library(tidyverse)
## Warning: package 'purrr' was built under R version 4.3.1
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.2     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library (readxl)
## Warning: package 'readxl' was built under R version 4.3.1
library (ggplot2)
library (DescTools)
## Warning: package 'DescTools' was built under R version 4.3.3
library(epitools)
## Warning: package 'epitools' was built under R version 4.3.1
library(caret)
## Warning: package 'caret' was built under R version 4.3.3
## Loading required package: lattice
## 
## Attaching package: 'caret'
## 
## The following objects are masked from 'package:DescTools':
## 
##     MAE, RMSE
## 
## The following object is masked from 'package:purrr':
## 
##     lift
library(DT)
## Warning: package 'DT' was built under R version 4.3.1

1 Dữ liệu nghiên cứu

Dữ liệu được thu thập bằng cách khảo sát dân số hiện tại tháng 3 năm 1988 của Cục điều tra dân số Hoa Kỳ. Tổng cộng có 28155 quan sát trên 7 biến.

data <- read_excel("C:/Users/Admin/Downloads/CPS1988.xlsx")
str(data)
## tibble [28,155 × 8] (S3: tbl_df/tbl/data.frame)
##  $ rownames  : num [1:28155] 1 2 3 4 5 6 7 8 9 10 ...
##  $ wage      : num [1:28155] 355 123 370 755 594 ...
##  $ education : num [1:28155] 7 12 9 11 12 16 8 12 12 14 ...
##  $ experience: num [1:28155] 45 1 9 46 36 22 51 34 0 18 ...
##  $ ethnicity : chr [1:28155] "cauc" "cauc" "cauc" "cauc" ...
##  $ smsa      : chr [1:28155] "yes" "yes" "yes" "yes" ...
##  $ region    : chr [1:28155] "northeast" "northeast" "northeast" "northeast" ...
##  $ parttime  : chr [1:28155] "no" "yes" "no" "no" ...
datatable(data)
## Warning in instance$preRenderHook(instance): It seems your data is too big for
## client-side DataTables. You may consider server-side processing:
## https://rstudio.github.io/DT/server.html

Bộ dữ liệu gồm có 7 biến, trong đó có 4 biến định tính và 3 biến định lượng

  • Biến Wage: Tiền lương của người quan sát (tính bằng đô la mỗi tuần).

  • Biến education: Số năm đi học.

  • Biến experience: Số năm kinh nghiệm làm việc.

  • Biến ethnicity: Chủng tộc, gồm 2 giá trị “cauc”và “afam”.

  • Biến smsa: Cá nhân đó có cư trú trong Khu vực Thống kê Đô thị Tiêu chuẩn (SMSA) không?, gồm 2 giá trị: “Yes” và “No”.

  • Biến region: Vùng đất, gồm 4 giá trị “northeast”, “midwest”, “south”, “west”.

  • Biến parttime: Cá nhân có làm việc bán thời gian không?, gồm 2 giá trị “Yes” và “No”.

2 Thống kê mô tả

2.1 Thống kê mô tả cho biến định tính

d <- data[,c("smsa","parttime","ethnicity","region")]

Biến smsa - Cá nhân có nơi cư trú trong khu vực đô thị tiêu chuẩn không

table(d$smsa)
## 
##    no   yes 
##  7223 20932
prop.table(table(d$smsa))
## 
##        no       yes 
## 0.2565441 0.7434559
ggplot(data,aes(smsa))+
  geom_bar(color = "blue", fill = "green")+
   geom_text(aes(label = scales :: percent(after_stat(count/sum(count)))), stat=  'count', color = 'black', vjust = -.5)+
  ylab("count")+ xlab("smsa") + labs(title = 'Đồ thị về nơi cư trú tiêu chuẩn của 28155 người được khảo sát')

Trong tổng số 28155 người tham gia khảo sát thì:

  • Có 7223 số người không có cư trú trong khu vực thống kê đô thị đạt tiêu chuẩn, chiếm 26%.

  • Có 20932 số người có cư trú trong khu vực thống kê đô thị đạt tiêu chuẩn, chiếm 74%.

Biến parttime - Cá nhân có làm việc bán thời gian không

table(d$parttime)
## 
##    no   yes 
## 25631  2524
prop.table(table(d$parttime))
## 
##        no       yes 
## 0.9103534 0.0896466
ggplot(data,aes(parttime))+
  geom_bar(color = "blue", fill = "green")+
   geom_text(aes(label = scales :: percent(after_stat(count/sum(count)))), stat=  'count', color = 'black', vjust = -.5)+
  ylab("count")+ xlab("parttime") + labs(title = 'Đồ thị về việc làm bán thời gian của 28155 người được khảo sát')

Trong tổng số 28155 người tham gia khảo sát thì có 25631 số người không có công việc bán thời gian, chiếm 91%. Có 2524 số người có công việc bán thời gian, chiếm 9%.

Biến ethnicity - Chủng tộc

table(d$ethnicity)
## 
##  afam  cauc 
##  2232 25923
prop.table(table(d$ethnicity))
## 
##       afam       cauc 
## 0.07927544 0.92072456
ggplot(data,aes(ethnicity))+
  geom_bar(color = "blue", fill = "green")+
   geom_text(aes(label = scales :: percent(after_stat(count/sum(count)))), stat=  'count', color = 'black', vjust = -.5)+
  ylab("count")+ xlab("ethnicity") + labs(title = 'Đồ thị về chủng tộc của 28155 người được khảo sát')

Trong tổng số 28155 người tham gia khảo sát thì có 2232 số người thuộc chủng tộc afam, chiếm 8%. Có 25923 số người thuộc chủng tộc cauc, chiếm 92%.

Biến region - Vùng đất

table(d$region)
## 
##   midwest northeast     south      west 
##      6863      6441      8760      6091
prop.table(table(d$region))
## 
##   midwest northeast     south      west 
## 0.2437578 0.2287693 0.3111348 0.2163381
ggplot(data,aes(region))+
  geom_bar(color = "blue", fill = "green")+
   geom_text(aes(label = scales :: percent(after_stat(count/sum(count)))), stat=  'count', color = 'black', vjust = -.5)+
  ylab("count")+ xlab("region") + labs(title = 'Đồ thị về vùng đất của 28155 người được khảo sát')

Trong tổng số 28155 người tham gia khảo sát thì:

  • Có 6863 số người sống ở phía Trung Tây, chiếm 24.4%,

  • Có 6441 số người sống ở phía Đông Bắc, chiếm 22.9%,

  • Có 8760 số người sống ở phía Nam, chiếm 31.1%,

  • Có 6091 số người sống ở phía Tây, chiếm 21.6%.

2.2 Thống kê mô tả cho biến định lượng

d <- data[,c("wage","education","experience")]

Biến Wage - Tiền lương

summary(data$wage)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##    50.05   308.64   522.32   603.73   783.48 18777.20

Trong 28155 người được khảo sát cho biết tiền lương:

  • Thấp nhất là 50.05

  • Cao nhất là 18777.20

  • Trung bình là 603.73

  • 50% người trong nhóm khỏa sát có tiền lương thấp hơn 522.32

  • 25% người trong nhóm khảo sát có tiền lương thấp hơn 308.64

  • 75% người trong nhóm khảo sát có tiền lương thấp hơn 783.48

sd(data$wage)
## [1] 453.5474

Độ lệch chuẩn của tiền lương là 453.5474, cho biết mức độ phân tán của tiền lương của từng người được khảo sát so với giá trị trung bình là 453.5474.

wage1 <- cut(data$wage, breaks =  c(0,200,400,600,800,1000,1200,1400,1600,18777), labels = c('0 - 200', '201 - 400','401 - 600','601 - 800','801 - 1000','1001 - 1200','1201 - 1400','1401 - 1600','>1600'))

d <- mutate(data, wage1)

d %>% na.omit() %>% ggplot(aes(x = wage1, y = after_stat(count))) + geom_bar(fill = 'skyblue') + geom_text(aes(label= scales::percent(after_stat(count/sum(count)), accuracy= 0.01)), stat = 'count', color = 'darkblue', vjust = -0.5)

Từ đồ thị trên ta thấy, những người được khảo sát có tiền lương chủ yếu từ 201 đến 600, trong đó nhóm từ 1401 đến 1600, chiếm tỷ lệ thấp nhất 1.66%.

Biến education - Trình độ học vấn

summary(data$education)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.00   12.00   12.00   13.07   15.00   18.00

Trong 28155 người được khảo sát cho biết trình độ học vấn:

  • Thấp nhất là 0

  • Cao nhất là 18

  • Trung bình là 13.07

  • 50% người trong nhóm khỏa sát có trình độ học vấn thấp hơn 12

  • 25% người trong nhóm khảo sát có trình độ học vấn hơn 12

  • 75% người trong nhóm khảo sát có trình độ học vấn hơn 15

sd(data$education)
## [1] 2.899682

Độ lệch chuẩn của trình độ học vấn là 2.899682, cho biết mức độ phân tán của trình độ học vấn của từng người được khảo sát so với giá trị trung bình là 2.899682.

table(data$education)
## 
##     0     1     2     3     4     5     6     7     8     9    10    11    12 
##    79    22    65   102    90   104   330   204   663   650  1022  1083 10549 
##    13    14    15    16    17    18 
##  2052  2967  1154  3873   815  2331
prop.table(table(data$education))
## 
##            0            1            2            3            4            5 
## 0.0028058959 0.0007813887 0.0023086486 0.0036228023 0.0031965903 0.0036938377 
##            6            7            8            9           10           11 
## 0.0117208311 0.0072456047 0.0235482152 0.0230864855 0.0362990588 0.0384656367 
##           12           13           14           15           16           17 
## 0.3746759013 0.0728822589 0.1053809270 0.0409873912 0.1375599361 0.0289469011 
##           18 
## 0.0827916889
education1 <- cut(data$education, breaks =  c(0,5,9,12,17), labels = c('0 - 5', '6 - 9','10 - 12','>12'))

d <- mutate(data, education1)

d %>% na.omit() %>% ggplot(aes(x = education1, y = after_stat(count))) + geom_bar(fill = 'skyblue') + geom_text(aes(label= scales::percent(after_stat(count/sum(count)), accuracy= 0.01)), stat = 'count', color = 'darkblue', vjust = -0.5)

Từ đồ thị trên ta thấy, những người được khảo sát có trình độ học vấn chủ yếu từ 10 đến 12 năm chiếm 49.15%, số người có trình độ học vấn từ 0 đến 5 năm chiếm tỷ lệ thấp nhất 1.49%

Biến experience - Kinh nghiệm

summary(data$experience)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    -4.0     8.0    16.0    18.2    27.0    63.0

Trong 28155 người được khảo sát cho biết số năm kinh nghiệm:

  • Thấp nhất là -4

  • Cao nhất là 63

  • Trung bình là 18.2

  • 50% người trong nhóm khỏa sát có số năm kinh nghiệm thấp hơn 16

  • 25% người trong nhóm khảo sát có số năm kinh nghiệm hơn 8

  • 75% người trong nhóm khảo sát có số năm kinh nghiệm hơn 27

sd(data$experience)
## [1] 13.07923

Độ lệch chuẩn của số năm kinh nghiệm là 13.07923, cho biết mức độ phân tán của số năm kinh nghiệm của từng người được khảo sát so với giá trị trung bình là 13.07923.

experience1 <- cut(data$experience, breaks =  c(-4,10,25,45,62), labels = c('-4 - 10', '11 - 25','26 - 45','46 - 63'))

d <- mutate(data, experience1)

d %>% na.omit() %>% ggplot(aes(x = experience1, y = after_stat(count))) + geom_bar(fill = 'skyblue') + geom_text(aes(label= scales::percent(after_stat(count/sum(count)), accuracy= 0.01)), stat = 'count', color = 'darkblue', vjust = -0.5)

Từ đồ thị trên ta thấy, những người được khảo sát có số năm kinh nghiệm chủ yếu từ 11 đến 25 năm chiếm 39.24%, số người có trình độ học vấn từ 46 đến 63 năm chiếm tỷ lệ thấp nhất 3.25%

3 Relative Risk/Risk Ratio

3.1 Rủi ro tương đối giữa biến parttime (có công việc bán thời gian) và biến smsa (khu vực cư trú tiêu chuẩn)

risk1 <- table(data$smsa,data$parttime) 
addmargins(risk1)
##      
##          no   yes   Sum
##   no   6591   632  7223
##   yes 19040  1892 20932
##   Sum 25631  2524 28155
RelRisk(risk1)
## [1] 1.003177

Tỷ lệ người có công việc bán thời gian không có nơi cư trú tiêu chuẩn bằng 100,32% tỷ lệ người có công việc bán thời gian nhưng có nơi cư trú tiêu chuẩn.

riskratio(risk1)
## $data
##        
##            no  yes Total
##   no     6591  632  7223
##   yes   19040 1892 20932
##   Total 25631 2524 28155
## 
## $measure
##      risk ratio with 95% C.I.
##       estimate     lower   upper
##   no  1.000000        NA      NA
##   yes 1.033025 0.9479131 1.12578
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact chi.square
##   no          NA           NA         NA
##   yes  0.4595492    0.4736688  0.4585465
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Tỷ lệ người có công việc bán thời gian có nơi cư trú tiêu chuẩn bằng 1.033 lần tỷ lệ người có công việc bán thời gian nhưng không có nơi cư trú tiêu chuẩn.

3.2 Rủi ro tương đối giữa biến parttime (có công việc bán thời gian) và biến ethnicity (chủng tộc)

risk2 <- table(data$ethnicity,data$parttime) 
addmargins(risk2)
##       
##           no   yes   Sum
##   afam  1988   244  2232
##   cauc 23643  2280 25923
##   Sum  25631  2524 28155
RelRisk(risk2)
## [1] 0.9765733

Tỷ lệ số người có công việc bán thời gian thuộc chủng tộc người Mỹ gốc Phi bằng 97.66% tỷ lệ số người có công việc bán thời gian thuộc chủng tộc người gốc Âu.

riskratio(risk2)
## $data
##        
##            no  yes Total
##   afam   1988  244  2232
##   cauc  23643 2280 25923
##   Total 25631 2524 28155
## 
## $measure
##       risk ratio with 95% C.I.
##         estimate     lower     upper
##   afam 1.0000000        NA        NA
##   cauc 0.8045517 0.7102013 0.9114366
## 
## $p.value
##       two-sided
##          midp.exact fisher.exact   chi.square
##   afam           NA           NA           NA
##   cauc 0.0009550463   0.00101711 0.0006975761
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"

Tỷ lệ số người có công việc bán thời gian thuộc chủng tộc người gốc Âu bằng 0.8 lần tỷ lệ số người có công việc bán thời gian thuộc chủng tộc người Mỹ gốc Phi.

4 Tỷ lệ chênh (Odd Ratio)

4.1 Tỷ lệ chênh giữa biến parttime (có công việc bán thời gian) và biến smsa (khu vực cư trú tiêu chuẩn)

odd1 <- table(data$smsa,data$parttime)
odd1
##      
##          no   yes
##   no   6591   632
##   yes 19040  1892
oddsratio(odd1)
## $data
##        
##            no  yes Total
##   no     6591  632  7223
##   yes   19040 1892 20932
##   Total 25631 2524 28155
## 
## $measure
##      odds ratio with 95% C.I.
##       estimate     lower    upper
##   no  1.000000        NA       NA
##   yes 1.036141 0.9434217 1.139305
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact chi.square
##   no          NA           NA         NA
##   yes  0.4595492    0.4736688  0.4585465
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Tỷ lệ người có công việc bán thời gian/người không có công việc bán thời gian mà có nơi cư trú tiêu chuẩn bằng 1.36 lần so với Tỷ lệ người có công việc bán thời gian/người không có công việc bán thời gian mà không có nơi cư trú tiêu chuẩn

4.2 Tỷ lệ chênh giữa biến parttime (có công việc bán thời gian) và biến ethnicity (chủng tộc)

odd2 <- table(data$ethnicity,data$parttime)
odd2
##       
##           no   yes
##   afam  1988   244
##   cauc 23643  2280
oddsratio(odd2)
## $data
##        
##            no  yes Total
##   afam   1988  244  2232
##   cauc  23643 2280 25923
##   Total 25631 2524 28155
## 
## $measure
##       odds ratio with 95% C.I.
##         estimate     lower     upper
##   afam 1.0000000        NA        NA
##   cauc 0.7852903 0.6842119 0.9049881
## 
## $p.value
##       two-sided
##          midp.exact fisher.exact   chi.square
##   afam           NA           NA           NA
##   cauc 0.0009550463   0.00101711 0.0006975761
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"

Tỷ lệ người có công việc bán thời gian/người không có công việc bán thời gian thuộc người gốc Âu bằng 0.79 lần so với Tỷ lệ người có công việc bán thời gian/người không có công việc bán thời gian thuộc người Mỹ gốc Phi

5 Thống kê suy diễn cho biến định tính

5.1 Kiểm tra tính độc lập của 2 biến khu vực cư trú tiêu chuẩn và công việc bán thời gian

Giả thuyết:

  • H0: khu vực cư trú tiêu chuẩn và công việc bán thời gian độc lập

  • H1: khu vực cư trú tiêu chuẩn và công việc bán thời gian không độc lập nhau

chisq.test(odd1)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  odd1
## X-squared = 0.5146, df = 1, p-value = 0.4732

Qua kết quả kiểm định ta thấy giá trị p_value = 0.4732 > 0.05 (mức ý nghĩa thông thường), nên chấp nhận giả thuyết H0. Vậy với mức ý nghĩa 5%, khu vực cư trú tiêu chuẩn và công việc bán thời gian độc lập nhau.

5.2 Kiểm tra tính độc lập của 2 biến chủng tộc và công việc bán thời gian

Giả thuyết:

  • H0: chủng tộc và công việc bán thời gian gian độc lập

  • H1: chủng tộc và công việc bán thời gian không độc lập nhau

chisq.test(odd2)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  odd2
## X-squared = 11.235, df = 1, p-value = 0.0008025

Qua kết quả kiểm định ta thấy giá trị p_value = 0.0008025 < 0.05 (mức ý nghĩa thông thường), nên bác bỏ giả thuyết H0. Vậy với mức ý nghĩa 5%, chủng tộc và công việc bán thời gian gian không độc lập.

6 Khoảng ước lượng cho tỷ lệ

6.1 Công thức ước lượng:

Để làm bài toán ước lượng tỷ lệ bằng R, ta thực hiện câu lệnh sau:

B1. install.packages(“DescTools”): cài đặt gói DescTools.

B2. library(DecsTools): gọi gói DescTools.

B3. BinomCI(k, n, conf.level = NULL, method = “wald”): câu lệnh ước lượng tỷ lệ một tổng thể; trong đó, k: số phần tử có tính chất A, n: số phần tử mẫu, conf.level = NULL: độ tin cậy mặc định là 95%, method = wald: phương pháp wald.

6.2 Để ước lượng tỷ lệ những người có số năm đi học dưới 12 năm ta làm như sau:

m <- data$education
m2 <- m[m < 12]
k <- length(m2[m2 < 3])
n <- length(m2)
BinomCI(k, n, conf.level = 0.95, method = "wald")
##             est     lwr.ci     upr.ci
## [1,] 0.03760761 0.03199525 0.04321998

Ta được khoảng ước lượng tỷ lệ những người có số năm đi học dưới 12 năm với độ tin cậy 95% là: 0.03199525 <= p <= 0.04321998

6.3 Ước lượng tỷ lệ người sống ở khu vực cư trú tiêu chuẩn có công việc bán thời gian đồng thời kiểm định xem tỷ lệ (%) người sống ở khu vực cư trú tiêu chuẩn có công việc bán thời gian có bằng 40% không?

#Tập hợp dữ liệu chỉ bao gồm những người có công việc bán thời gian
rm<- data[data$parttime == "yes",]
#Tập hợp con những người có công việc bán thời gian sống ở khu vực cư trú tiêu chuẩn
rm1<-rm[rm$smsa == "yes",]
#kiểm tra tỷ lệ
prop.test(length(rm1$smsa), length(rm$smsa), p = 0.4)
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(rm1$smsa) out of length(rm$smsa), null probability 0.4
## X-squared = 1283.9, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.4
## 95 percent confidence interval:
##  0.7321290 0.7663111
## sample estimates:
##         p 
## 0.7496038

Với khoảng tin cậy 95% ước lượng tỷ lệ người sống ở khu vực cư trú tiêu chuẩn có công việc bán thời gian nằm trong khoảng từ 0.7321290 đến 0.7663111

p-value = 2.2e-16 < 0.05,nên bác bỏ giả thuyết H0. Do đó tỷ lệ (%) người sống ở khu vực cư trú tiêu chuẩn có công việc bán thời gian không bằng 40% với mức ý nghĩa 5%

6.4 Ước lượng tỷ lệ người sống ở khu vực cư trú tiêu chuẩn không công việc bán thời gian đồng thời kiểm định xem tỷ lệ (%) người sống ở khu vực cư trú tiêu chuẩn không có công việc bán thời gian có bằng 40% không?

rm<- data[data$parttime == "no",]
rm1<-rm[rm$smsa == "yes",]
prop.test(length(rm1$smsa), length(rm$smsa), p = 0.4)
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(rm1$smsa) out of length(rm$smsa), null probability 0.4
## X-squared = 12552, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.4
## 95 percent confidence interval:
##  0.7374440 0.7481838
## sample estimates:
##         p 
## 0.7428505

Với khoảng tin cậy 95% ước lượng tỷ lệ người sống ở khu vực cư trú tiêu chuẩn không có công việc bán thời gian nằm trong khoảng từ 0.7374440 đến 0.7481838

p-value = 2.2e-16 < 0.05,nên bác bỏ giả thuyết H0. Do đó tỷ lệ (%) người sống ở khu vực cư trú tiêu chuẩn không có công việc bán thời gian không bằng 40% với mức ý nghĩa 5%.

LS0tDQp0aXRsZTogIkLDgEkgVOG6rFAgMSINCmF1dGhvcjogIk5HVVnhu4ROIEPhuqhNIE5HVVnDik4iDQpkYXRlOiAiMjAyNC0wNi0wMSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICB0b2NfZGVwaHQ6IDMNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogIHdvcmRfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeSAocmVhZHhsKQ0KbGlicmFyeSAoZ2dwbG90MikNCmxpYnJhcnkgKERlc2NUb29scykNCmxpYnJhcnkoZXBpdG9vbHMpDQpsaWJyYXJ5KGNhcmV0KQ0KbGlicmFyeShEVCkNCmBgYA0KDQojIEThu68gbGnhu4d1IG5naGnDqm4gY+G7qXUNCg0KROG7ryBsaeG7h3UgxJHGsOG7o2MgdGh1IHRo4bqtcCBi4bqxbmcgY8OhY2gga2jhuqNvIHPDoXQgZMOibiBz4buRIGhp4buHbiB04bqhaSB0aMOhbmcgMyBuxINtIDE5ODggY+G7p2EgQ+G7pWMgxJFp4buBdSB0cmEgZMOibiBz4buRIEhvYSBL4buzLiBU4buVbmcgY+G7mW5nIGPDsyAyODE1NSBxdWFuIHPDoXQgdHLDqm4gNyBiaeG6v24uDQoNCmBgYHtyfQ0KZGF0YSA8LSByZWFkX2V4Y2VsKCJDOi9Vc2Vycy9BZG1pbi9Eb3dubG9hZHMvQ1BTMTk4OC54bHN4IikNCnN0cihkYXRhKQ0KZGF0YXRhYmxlKGRhdGEpDQpgYGANCg0KQuG7mSBk4buvIGxp4buHdSBn4buTbSBjw7MgNyBiaeG6v24sIHRyb25nIMSRw7MgY8OzIDQgYmnhur9uIMSR4buLbmggdMOtbmggdsOgIDMgYmnhur9uIMSR4buLbmggbMaw4bujbmcNCg0KLSBCaeG6v24gV2FnZTogVGnhu4FuIGzGsMahbmcgY+G7p2EgbmfGsOG7nWkgcXVhbiBzw6F0ICh0w61uaCBi4bqxbmcgxJHDtCBsYSBt4buXaSB0deG6p24pLg0KDQotIEJp4bq/biBlZHVjYXRpb246IFPhu5EgbsSDbSDEkWkgaOG7jWMuDQoNCi0gQmnhur9uIGV4cGVyaWVuY2U6IFPhu5EgbsSDbSBraW5oIG5naGnhu4dtIGzDoG0gdmnhu4djLg0KDQotIEJp4bq/biBldGhuaWNpdHk6IENo4bunbmcgdOG7mWMsIGfhu5NtIDIgZ2nDoSB0cuG7iyAiY2F1YyJ2w6AgImFmYW0iLg0KDQotIEJp4bq/biBzbXNhOiBDw6EgbmjDom4gxJHDsyBjw7MgY8awIHRyw7ogdHJvbmcgS2h1IHbhu7FjIFRo4buRbmcga8OqIMSQw7QgdGjhu4sgVGnDqnUgY2h14bqpbiAoU01TQSkga2jDtG5nPywgZ+G7k20gMiBnacOhIHRy4buLOiAiWWVzIiB2w6AgIk5vIi4NCg0KLSBCaeG6v24gcmVnaW9uOiBWw7luZyDEkeG6pXQsIGfhu5NtIDQgZ2nDoSB0cuG7iyAibm9ydGhlYXN0IiwgIm1pZHdlc3QiLCAic291dGgiLCAid2VzdCIuDQoNCi0gQmnhur9uIHBhcnR0aW1lOiBDw6EgbmjDom4gY8OzIGzDoG0gdmnhu4djIGLDoW4gdGjhu51pIGdpYW4ga2jDtG5nPywgZ+G7k20gMiBnacOhIHRy4buLICJZZXMiIHbDoCAiTm8iLg0KDQojIFRo4buRbmcga8OqIG3DtCB04bqjIA0KDQojIyBUaOG7kW5nIGvDqiBtw7QgdOG6oyBjaG8gYmnhur9uIMSR4buLbmggdMOtbmgNCg0KYGBge3J9DQpkIDwtIGRhdGFbLGMoInNtc2EiLCJwYXJ0dGltZSIsImV0aG5pY2l0eSIsInJlZ2lvbiIpXQ0KYGBgDQoNCioqKkJp4bq/biBzbXNhIC0gQ8OhIG5ow6JuIGPDsyBuxqFpIGPGsCB0csO6IHRyb25nIGtodSB24buxYyDEkcO0IHRo4buLIHRpw6p1IGNodeG6qW4ga2jDtG5nKioqDQpgYGB7cn0NCnRhYmxlKGQkc21zYSkNCnByb3AudGFibGUodGFibGUoZCRzbXNhKSkNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChkYXRhLGFlcyhzbXNhKSkrDQogIGdlb21fYmFyKGNvbG9yID0gImJsdWUiLCBmaWxsID0gImdyZWVuIikrDQogICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzIDo6IHBlcmNlbnQoYWZ0ZXJfc3RhdChjb3VudC9zdW0oY291bnQpKSkpLCBzdGF0PSAgJ2NvdW50JywgY29sb3IgPSAnYmxhY2snLCB2anVzdCA9IC0uNSkrDQogIHlsYWIoImNvdW50IikrIHhsYWIoInNtc2EiKSArIGxhYnModGl0bGUgPSAnxJDhu5MgdGjhu4sgduG7gSBuxqFpIGPGsCB0csO6IHRpw6p1IGNodeG6qW4gY+G7p2EgMjgxNTUgbmfGsOG7nWkgxJHGsOG7o2Mga2jhuqNvIHPDoXQnKQ0KYGBgDQoNClRyb25nIHThu5VuZyBz4buRIDI4MTU1IG5nxrDhu51pIHRoYW0gZ2lhIGto4bqjbyBzw6F0IHRow6w6DQoNCiAgLSBDw7MgNzIyMyBz4buRIG5nxrDhu51pIGtow7RuZyBjw7MgY8awIHRyw7ogdHJvbmcga2h1IHbhu7FjIHRo4buRbmcga8OqIMSRw7QgdGjhu4sgxJHhuqF0IHRpw6p1IGNodeG6qW4sIGNoaeG6v20gMjYlLg0KICANCiAgLSBDw7MgMjA5MzIgc+G7kSBuZ8aw4budaSBjw7MgY8awIHRyw7ogdHJvbmcga2h1IHbhu7FjIHRo4buRbmcga8OqIMSRw7QgdGjhu4sgxJHhuqF0IHRpw6p1IGNodeG6qW4sIGNoaeG6v20gNzQlLg0KICANCioqKkJp4bq/biBwYXJ0dGltZSAtIEPDoSBuaMOibiBjw7MgbMOgbSB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbiBraMO0bmcqKioNCg0KYGBge3J9DQp0YWJsZShkJHBhcnR0aW1lKQ0KcHJvcC50YWJsZSh0YWJsZShkJHBhcnR0aW1lKSkNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChkYXRhLGFlcyhwYXJ0dGltZSkpKw0KICBnZW9tX2Jhcihjb2xvciA9ICJibHVlIiwgZmlsbCA9ICJncmVlbiIpKw0KICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlcyA6OiBwZXJjZW50KGFmdGVyX3N0YXQoY291bnQvc3VtKGNvdW50KSkpKSwgc3RhdD0gICdjb3VudCcsIGNvbG9yID0gJ2JsYWNrJywgdmp1c3QgPSAtLjUpKw0KICB5bGFiKCJjb3VudCIpKyB4bGFiKCJwYXJ0dGltZSIpICsgbGFicyh0aXRsZSA9ICfEkOG7kyB0aOG7iyB24buBIHZp4buHYyBsw6BtIGLDoW4gdGjhu51pIGdpYW4gY+G7p2EgMjgxNTUgbmfGsOG7nWkgxJHGsOG7o2Mga2jhuqNvIHPDoXQnKQ0KYGBgDQoNClRyb25nIHThu5VuZyBz4buRIDI4MTU1IG5nxrDhu51pIHRoYW0gZ2lhIGto4bqjbyBzw6F0IHRow6wgY8OzIDI1NjMxIHPhu5EgbmfGsOG7nWkga2jDtG5nIGPDsyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbiwgY2hp4bq/bSA5MSUuIEPDsyAyNTI0IHPhu5EgbmfGsOG7nWkgY8OzIGPDtG5nIHZp4buHYyBiw6FuIHRo4budaSBnaWFuLCBjaGnhur9tIDklLg0KDQoqKipCaeG6v24gZXRobmljaXR5IC0gQ2jhu6duZyB04buZYyoqKg0KYGBge3J9DQp0YWJsZShkJGV0aG5pY2l0eSkNCnByb3AudGFibGUodGFibGUoZCRldGhuaWNpdHkpKQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEsYWVzKGV0aG5pY2l0eSkpKw0KICBnZW9tX2Jhcihjb2xvciA9ICJibHVlIiwgZmlsbCA9ICJncmVlbiIpKw0KICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlcyA6OiBwZXJjZW50KGFmdGVyX3N0YXQoY291bnQvc3VtKGNvdW50KSkpKSwgc3RhdD0gICdjb3VudCcsIGNvbG9yID0gJ2JsYWNrJywgdmp1c3QgPSAtLjUpKw0KICB5bGFiKCJjb3VudCIpKyB4bGFiKCJldGhuaWNpdHkiKSArIGxhYnModGl0bGUgPSAnxJDhu5MgdGjhu4sgduG7gSBjaOG7p25nIHThu5ljIGPhu6dhIDI4MTU1IG5nxrDhu51pIMSRxrDhu6NjIGto4bqjbyBzw6F0JykNCmBgYA0KDQpUcm9uZyB04buVbmcgc+G7kSAyODE1NSBuZ8aw4budaSB0aGFtIGdpYSBraOG6o28gc8OhdCB0aMOsIGPDsyAyMjMyIHPhu5EgbmfGsOG7nWkgdGh14buZYyBjaOG7p25nIHThu5ljIGFmYW0sIGNoaeG6v20gOCUuIEPDsyAyNTkyMyBz4buRIG5nxrDhu51pIHRodeG7mWMgY2jhu6duZyB04buZYyBjYXVjLCBjaGnhur9tIDkyJS4NCg0KKioqQmnhur9uIHJlZ2lvbiAtIFbDuW5nIMSR4bqldCoqKg0KYGBge3J9DQp0YWJsZShkJHJlZ2lvbikNCnByb3AudGFibGUodGFibGUoZCRyZWdpb24pKQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEsYWVzKHJlZ2lvbikpKw0KICBnZW9tX2Jhcihjb2xvciA9ICJibHVlIiwgZmlsbCA9ICJncmVlbiIpKw0KICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlcyA6OiBwZXJjZW50KGFmdGVyX3N0YXQoY291bnQvc3VtKGNvdW50KSkpKSwgc3RhdD0gICdjb3VudCcsIGNvbG9yID0gJ2JsYWNrJywgdmp1c3QgPSAtLjUpKw0KICB5bGFiKCJjb3VudCIpKyB4bGFiKCJyZWdpb24iKSArIGxhYnModGl0bGUgPSAnxJDhu5MgdGjhu4sgduG7gSB2w7luZyDEkeG6pXQgY+G7p2EgMjgxNTUgbmfGsOG7nWkgxJHGsOG7o2Mga2jhuqNvIHPDoXQnKQ0KYGBgDQoNClRyb25nIHThu5VuZyBz4buRIDI4MTU1IG5nxrDhu51pIHRoYW0gZ2lhIGto4bqjbyBzw6F0IHRow6w6DQoNCiAgLSBDw7MgNjg2MyBz4buRIG5nxrDhu51pIHPhu5FuZyDhu58gcGjDrWEgVHJ1bmcgVMOieSwgY2hp4bq/bSAyNC40JSwNCiAgDQogIC0gQ8OzIDY0NDEgc+G7kSBuZ8aw4budaSBz4buRbmcg4bufIHBow61hIMSQw7RuZyBC4bqvYywgY2hp4bq/bSAyMi45JSwgDQogIA0KICAtIEPDsyA4NzYwIHPhu5EgbmfGsOG7nWkgc+G7kW5nIOG7nyBwaMOtYSBOYW0sIGNoaeG6v20gMzEuMSUsIA0KICANCiAgLSBDw7MgNjA5MSBz4buRIG5nxrDhu51pIHPhu5FuZyDhu58gcGjDrWEgVMOieSwgY2hp4bq/bSAyMS42JS4NCiAgDQojIyBUaOG7kW5nIGvDqiBtw7QgdOG6oyBjaG8gYmnhur9uIMSR4buLbmggbMaw4bujbmcNCg0KYGBge3J9DQpkIDwtIGRhdGFbLGMoIndhZ2UiLCJlZHVjYXRpb24iLCJleHBlcmllbmNlIildDQpgYGANCg0KKioqQmnhur9uIFdhZ2UgLSBUaeG7gW4gbMawxqFuZyoqKg0KDQpgYGB7cn0NCnN1bW1hcnkoZGF0YSR3YWdlKQ0KYGBgDQoNClRyb25nIDI4MTU1IG5nxrDhu51pIMSRxrDhu6NjIGto4bqjbyBzw6F0IGNobyBiaeG6v3QgdGnhu4FuIGzGsMahbmc6DQoNCiAgLSBUaOG6pXAgbmjhuqV0IGzDoCA1MC4wNQ0KICANCiAgLSBDYW8gbmjhuqV0IGzDoCAxODc3Ny4yMA0KICANCiAgLSBUcnVuZyBiw6xuaCBsw6AgNjAzLjczDQogIA0KICAtIDUwJSBuZ8aw4budaSB0cm9uZyBuaMOzbSBraOG7j2Egc8OhdCBjw7MgdGnhu4FuIGzGsMahbmcgdGjhuqVwIGjGoW4gNTIyLjMyDQogIA0KICAtIDI1JSBuZ8aw4budaSB0cm9uZyBuaMOzbSBraOG6o28gc8OhdCBjw7MgdGnhu4FuIGzGsMahbmcgdGjhuqVwIGjGoW4gMzA4LjY0DQogIA0KICAtIDc1JSBuZ8aw4budaSB0cm9uZyBuaMOzbSBraOG6o28gc8OhdCBjw7MgdGnhu4FuIGzGsMahbmcgdGjhuqVwIGjGoW4gNzgzLjQ4IA0KDQpgYGB7cn0NCnNkKGRhdGEkd2FnZSkNCmBgYA0KDQrEkOG7mSBs4buHY2ggY2h14bqpbiBj4bunYSB0aeG7gW4gbMawxqFuZyBsw6AgNDUzLjU0NzQsIGNobyBiaeG6v3QgbeG7qWMgxJHhu5kgcGjDom4gdMOhbiBj4bunYSB0aeG7gW4gbMawxqFuZyBj4bunYSB04burbmcgbmfGsOG7nWkgxJHGsOG7o2Mga2jhuqNvIHPDoXQgc28gduG7m2kgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBsw6AgNDUzLjU0NzQuDQoNCmBgYHtyfQ0Kd2FnZTEgPC0gY3V0KGRhdGEkd2FnZSwgYnJlYWtzID0gIGMoMCwyMDAsNDAwLDYwMCw4MDAsMTAwMCwxMjAwLDE0MDAsMTYwMCwxODc3NyksIGxhYmVscyA9IGMoJzAgLSAyMDAnLCAnMjAxIC0gNDAwJywnNDAxIC0gNjAwJywnNjAxIC0gODAwJywnODAxIC0gMTAwMCcsJzEwMDEgLSAxMjAwJywnMTIwMSAtIDE0MDAnLCcxNDAxIC0gMTYwMCcsJz4xNjAwJykpDQoNCmQgPC0gbXV0YXRlKGRhdGEsIHdhZ2UxKQ0KDQpkICU+JSBuYS5vbWl0KCkgJT4lIGdncGxvdChhZXMoeCA9IHdhZ2UxLCB5ID0gYWZ0ZXJfc3RhdChjb3VudCkpKSArIGdlb21fYmFyKGZpbGwgPSAnc2t5Ymx1ZScpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbD0gc2NhbGVzOjpwZXJjZW50KGFmdGVyX3N0YXQoY291bnQvc3VtKGNvdW50KSksIGFjY3VyYWN5PSAwLjAxKSksIHN0YXQgPSAnY291bnQnLCBjb2xvciA9ICdkYXJrYmx1ZScsIHZqdXN0ID0gLTAuNSkNCmBgYA0KDQpU4burIMSR4buTIHRo4buLIHRyw6puIHRhIHRo4bqleSwgbmjhu69uZyBuZ8aw4budaSDEkcaw4bujYyBraOG6o28gc8OhdCBjw7MgdGnhu4FuIGzGsMahbmcgY2jhu6cgeeG6v3UgdOG7qyAyMDEgxJHhur9uIDYwMCwgdHJvbmcgxJHDsyBuaMOzbSB04burIDE0MDEgxJHhur9uIDE2MDAsIGNoaeG6v20gdOG7tyBs4buHIHRo4bqlcCBuaOG6pXQgMS42NiUuDQoNCioqKkJp4bq/biBlZHVjYXRpb24gLSBUcsOsbmggxJHhu5kgaOG7jWMgduG6pW4qKioNCg0KYGBge3J9DQpzdW1tYXJ5KGRhdGEkZWR1Y2F0aW9uKQ0KYGBgDQoNClRyb25nIDI4MTU1IG5nxrDhu51pIMSRxrDhu6NjIGto4bqjbyBzw6F0IGNobyBiaeG6v3QgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuOg0KDQogIC0gVGjhuqVwIG5o4bqldCBsw6AgMA0KICANCiAgLSBDYW8gbmjhuqV0IGzDoCAxOA0KICANCiAgLSBUcnVuZyBiw6xuaCBsw6AgMTMuMDcNCiAgDQogIC0gNTAlIG5nxrDhu51pIHRyb25nIG5ow7NtIGto4buPYSBzw6F0IGPDsyB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gdGjhuqVwIGjGoW4gMTINCiAgDQogIC0gMjUlIG5nxrDhu51pIHRyb25nIG5ow7NtIGto4bqjbyBzw6F0IGPDsyB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gaMahbiAxMg0KICANCiAgLSA3NSUgbmfGsOG7nWkgdHJvbmcgbmjDs20ga2jhuqNvIHPDoXQgY8OzIHRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiBoxqFuIDE1IA0KDQpgYGB7cn0NCnNkKGRhdGEkZWR1Y2F0aW9uKQ0KYGBgDQoNCsSQ4buZIGzhu4djaCBjaHXhuqluIGPhu6dhIHRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiBsw6AgMi44OTk2ODIsIGNobyBiaeG6v3QgbeG7qWMgxJHhu5kgcGjDom4gdMOhbiBj4bunYSB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gY+G7p2EgdOG7q25nIG5nxrDhu51pIMSRxrDhu6NjIGto4bqjbyBzw6F0IHNvIHbhu5tpIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggbMOgIDIuODk5NjgyLg0KDQpgYGB7cn0NCnRhYmxlKGRhdGEkZWR1Y2F0aW9uKQ0KYGBgDQoNCmBgYHtyfQ0KcHJvcC50YWJsZSh0YWJsZShkYXRhJGVkdWNhdGlvbikpDQpgYGANCg0KYGBge3J9DQplZHVjYXRpb24xIDwtIGN1dChkYXRhJGVkdWNhdGlvbiwgYnJlYWtzID0gIGMoMCw1LDksMTIsMTcpLCBsYWJlbHMgPSBjKCcwIC0gNScsICc2IC0gOScsJzEwIC0gMTInLCc+MTInKSkNCg0KZCA8LSBtdXRhdGUoZGF0YSwgZWR1Y2F0aW9uMSkNCg0KZCAlPiUgbmEub21pdCgpICU+JSBnZ3Bsb3QoYWVzKHggPSBlZHVjYXRpb24xLCB5ID0gYWZ0ZXJfc3RhdChjb3VudCkpKSArIGdlb21fYmFyKGZpbGwgPSAnc2t5Ymx1ZScpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbD0gc2NhbGVzOjpwZXJjZW50KGFmdGVyX3N0YXQoY291bnQvc3VtKGNvdW50KSksIGFjY3VyYWN5PSAwLjAxKSksIHN0YXQgPSAnY291bnQnLCBjb2xvciA9ICdkYXJrYmx1ZScsIHZqdXN0ID0gLTAuNSkNCmBgYA0KDQpU4burIMSR4buTIHRo4buLIHRyw6puIHRhIHRo4bqleSwgbmjhu69uZyBuZ8aw4budaSDEkcaw4bujYyBraOG6o28gc8OhdCBjw7MgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIGNo4bunIHnhur91IHThu6sgMTAgxJHhur9uIDEyIG7Eg20gY2hp4bq/bSA0OS4xNSUsIHPhu5EgbmfGsOG7nWkgY8OzIHRyw6xuaCDEkeG7mSBo4buNYyB24bqlbiB04burIDAgxJHhur9uIDUgbsSDbSBjaGnhur9tIHThu7cgbOG7hyB0aOG6pXAgbmjhuqV0IDEuNDklDQoNCioqKkJp4bq/biBleHBlcmllbmNlIC0gS2luaCBuZ2hp4buHbSoqKg0KDQpgYGB7cn0NCnN1bW1hcnkoZGF0YSRleHBlcmllbmNlKQ0KYGBgDQpUcm9uZyAyODE1NSBuZ8aw4budaSDEkcaw4bujYyBraOG6o28gc8OhdCBjaG8gYmnhur90IHPhu5EgbsSDbSBraW5oIG5naGnhu4dtOg0KDQogIC0gVGjhuqVwIG5o4bqldCBsw6AgLTQNCiAgDQogIC0gQ2FvIG5o4bqldCBsw6AgNjMNCiAgDQogIC0gVHJ1bmcgYsOsbmggbMOgIDE4LjINCiAgDQogIC0gNTAlIG5nxrDhu51pIHRyb25nIG5ow7NtIGto4buPYSBzw6F0IGPDsyBz4buRIG7Eg20ga2luaCBuZ2hp4buHbSB0aOG6pXAgaMahbiAxNg0KICANCiAgLSAyNSUgbmfGsOG7nWkgdHJvbmcgbmjDs20ga2jhuqNvIHPDoXQgY8OzIHPhu5EgbsSDbSBraW5oIG5naGnhu4dtIGjGoW4gOA0KICANCiAgLSA3NSUgbmfGsOG7nWkgdHJvbmcgbmjDs20ga2jhuqNvIHPDoXQgY8OzIHPhu5EgbsSDbSBraW5oIG5naGnhu4dtIGjGoW4gMjcNCg0KYGBge3J9DQpzZChkYXRhJGV4cGVyaWVuY2UpDQpgYGANCsSQ4buZIGzhu4djaCBjaHXhuqluIGPhu6dhIHPhu5EgbsSDbSBraW5oIG5naGnhu4dtIGzDoCAxMy4wNzkyMywgY2hvIGJp4bq/dCBt4bupYyDEkeG7mSBwaMOibiB0w6FuIGPhu6dhIHPhu5EgbsSDbSBraW5oIG5naGnhu4dtIGPhu6dhIHThu6tuZyBuZ8aw4budaSDEkcaw4bujYyBraOG6o28gc8OhdCBzbyB24bubaSBnacOhIHRy4buLIHRydW5nIGLDrG5oIGzDoCAxMy4wNzkyMy4NCg0KYGBge3J9DQpleHBlcmllbmNlMSA8LSBjdXQoZGF0YSRleHBlcmllbmNlLCBicmVha3MgPSAgYygtNCwxMCwyNSw0NSw2MiksIGxhYmVscyA9IGMoJy00IC0gMTAnLCAnMTEgLSAyNScsJzI2IC0gNDUnLCc0NiAtIDYzJykpDQoNCmQgPC0gbXV0YXRlKGRhdGEsIGV4cGVyaWVuY2UxKQ0KDQpkICU+JSBuYS5vbWl0KCkgJT4lIGdncGxvdChhZXMoeCA9IGV4cGVyaWVuY2UxLCB5ID0gYWZ0ZXJfc3RhdChjb3VudCkpKSArIGdlb21fYmFyKGZpbGwgPSAnc2t5Ymx1ZScpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbD0gc2NhbGVzOjpwZXJjZW50KGFmdGVyX3N0YXQoY291bnQvc3VtKGNvdW50KSksIGFjY3VyYWN5PSAwLjAxKSksIHN0YXQgPSAnY291bnQnLCBjb2xvciA9ICdkYXJrYmx1ZScsIHZqdXN0ID0gLTAuNSkNCmBgYA0KDQpU4burIMSR4buTIHRo4buLIHRyw6puIHRhIHRo4bqleSwgbmjhu69uZyBuZ8aw4budaSDEkcaw4bujYyBraOG6o28gc8OhdCBjw7Mgc+G7kSBuxINtIGtpbmggbmdoaeG7h20gY2jhu6cgeeG6v3UgdOG7qyAxMSDEkeG6v24gMjUgbsSDbSBjaGnhur9tIDM5LjI0JSwgc+G7kSBuZ8aw4budaSBjw7MgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIHThu6sgNDYgxJHhur9uIDYzIG7Eg20gY2hp4bq/bSB04bu3IGzhu4cgdGjhuqVwIG5o4bqldCAzLjI1JQ0KDQojIFJlbGF0aXZlIFJpc2svUmlzayBSYXRpbw0KDQojIyBS4bunaSBybyB0xrDGoW5nIMSR4buRaSBnaeG7r2EgYmnhur9uIHBhcnR0aW1lIChjw7MgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4pIHbDoCBiaeG6v24gc21zYSAoa2h1IHbhu7FjIGPGsCB0csO6IHRpw6p1IGNodeG6qW4pICANCg0KYGBge3J9DQpyaXNrMSA8LSB0YWJsZShkYXRhJHNtc2EsZGF0YSRwYXJ0dGltZSkgDQphZGRtYXJnaW5zKHJpc2sxKQ0KYGBgDQoNCmBgYHtyfQ0KUmVsUmlzayhyaXNrMSkNCmBgYA0KVOG7tyBs4buHIG5nxrDhu51pIGPDsyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbiBraMO0bmcgY8OzIG7GoWkgY8awIHRyw7ogdGnDqnUgY2h14bqpbiBi4bqxbmcgMTAwLDMyJSB04bu3IGzhu4cgbmfGsOG7nWkgY8OzIGPDtG5nIHZp4buHYyBiw6FuIHRo4budaSBnaWFuIG5oxrBuZyBjw7MgbsahaSBjxrAgdHLDuiB0acOqdSBjaHXhuqluLg0KDQpgYGB7cn0NCnJpc2tyYXRpbyhyaXNrMSkNCmBgYA0KVOG7tyBs4buHIG5nxrDhu51pIGPDsyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbiBjw7MgbsahaSBjxrAgdHLDuiB0acOqdSBjaHXhuqluIGLhurFuZyAxLjAzMyBs4bqnbiB04bu3IGzhu4cgbmfGsOG7nWkgY8OzIGPDtG5nIHZp4buHYyBiw6FuIHRo4budaSBnaWFuIG5oxrBuZyBraMO0bmcgY8OzIG7GoWkgY8awIHRyw7ogdGnDqnUgY2h14bqpbi4NCg0KIyMgUuG7p2kgcm8gdMawxqFuZyDEkeG7kWkgZ2nhu69hIGJp4bq/biBwYXJ0dGltZSAoY8OzIGPDtG5nIHZp4buHYyBiw6FuIHRo4budaSBnaWFuKSB2w6AgYmnhur9uIGV0aG5pY2l0eSAoY2jhu6duZyB04buZYykgIA0KDQpgYGB7cn0NCnJpc2syIDwtIHRhYmxlKGRhdGEkZXRobmljaXR5LGRhdGEkcGFydHRpbWUpIA0KYWRkbWFyZ2lucyhyaXNrMikNCmBgYA0KDQpgYGB7cn0NClJlbFJpc2socmlzazIpDQpgYGANClThu7cgbOG7hyBz4buRIG5nxrDhu51pIGPDsyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbiB0aHXhu5ljIGNo4bunbmcgdOG7mWMgbmfGsOG7nWkgTeG7uSBn4buRYyBQaGkgYuG6sW5nIDk3LjY2JSB04bu3IGzhu4cgc+G7kSBuZ8aw4budaSBjw7MgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4gdGh14buZYyBjaOG7p25nIHThu5ljIG5nxrDhu51pIGfhu5FjIMOCdS4gDQoNCmBgYHtyfQ0Kcmlza3JhdGlvKHJpc2syKQ0KYGBgDQpU4bu3IGzhu4cgc+G7kSBuZ8aw4budaSBjw7MgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4gdGh14buZYyBjaOG7p25nIHThu5ljIG5nxrDhu51pIGfhu5FjIMOCdSAgYuG6sW5nIDAuOCBs4bqnbiB04bu3IGzhu4cgc+G7kSBuZ8aw4budaSBjw7MgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4gdGh14buZYyBjaOG7p25nIHThu5ljIG5nxrDhu51pIE3hu7kgZ+G7kWMgUGhpLiANCg0KDQojIFThu7cgbOG7hyBjaMOqbmggKE9kZCBSYXRpbykNCg0KIyMgVOG7tyBs4buHIGNow6puaCBnaeG7r2EgYmnhur9uIHBhcnR0aW1lIChjw7MgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4pIHbDoCBiaeG6v24gc21zYSAoa2h1IHbhu7FjIGPGsCB0csO6IHRpw6p1IGNodeG6qW4pIA0KDQpgYGB7cn0NCm9kZDEgPC0gdGFibGUoZGF0YSRzbXNhLGRhdGEkcGFydHRpbWUpDQpvZGQxDQpgYGANCg0KYGBge3J9DQpvZGRzcmF0aW8ob2RkMSkNCmBgYA0KVOG7tyBs4buHIG5nxrDhu51pIGPDsyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbi9uZ8aw4budaSBraMO0bmcgY8OzIGPDtG5nIHZp4buHYyBiw6FuIHRo4budaSBnaWFuIG3DoCBjw7MgbsahaSBjxrAgdHLDuiB0acOqdSBjaHXhuqluIGLhurFuZyAxLjM2IGzhuqduIHNvIHbhu5tpIFThu7cgbOG7hyBuZ8aw4budaSBjw7MgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4vbmfGsOG7nWkga2jDtG5nIGPDsyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbiBtw6Aga2jDtG5nIGPDsyBuxqFpIGPGsCB0csO6IHRpw6p1IGNodeG6qW4NCg0KIyMgVOG7tyBs4buHIGNow6puaCBnaeG7r2EgYmnhur9uIHBhcnR0aW1lIChjw7MgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4pIHbDoCBiaeG6v24gZXRobmljaXR5IChjaOG7p25nIHThu5ljKQ0KDQpgYGB7cn0NCm9kZDIgPC0gdGFibGUoZGF0YSRldGhuaWNpdHksZGF0YSRwYXJ0dGltZSkNCm9kZDINCmBgYA0KDQpgYGB7cn0NCm9kZHNyYXRpbyhvZGQyKQ0KYGBgDQpU4bu3IGzhu4cgbmfGsOG7nWkgY8OzIGPDtG5nIHZp4buHYyBiw6FuIHRo4budaSBnaWFuL25nxrDhu51pIGtow7RuZyBjw7MgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4gdGh14buZYyBuZ8aw4budaSBn4buRYyDDgnUgYuG6sW5nIDAuNzkgbOG6p24gc28gduG7m2kgVOG7tyBs4buHIG5nxrDhu51pIGPDsyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbi9uZ8aw4budaSBraMO0bmcgY8OzIGPDtG5nIHZp4buHYyBiw6FuIHRo4budaSBnaWFuIHRodeG7mWMgbmfGsOG7nWkgTeG7uSBn4buRYyBQaGkNCg0KIyBUaOG7kW5nIGvDqiBzdXkgZGnhu4VuIGNobyBiaeG6v24gxJHhu4tuaCB0w61uaA0KDQojIyBLaeG7g20gdHJhIHTDrW5oIMSR4buZYyBs4bqtcCBj4bunYSAyIGJp4bq/biBraHUgduG7sWMgY8awIHRyw7ogdGnDqnUgY2h14bqpbiB2w6AgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4NCg0KR2nhuqMgdGh1eeG6v3Q6DQoNCiAtIEgwOiBraHUgduG7sWMgY8awIHRyw7ogdGnDqnUgY2h14bqpbiB2w6AgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4gxJHhu5ljIGzhuq1wDQogDQogLSBIMToga2h1IHbhu7FjIGPGsCB0csO6IHRpw6p1IGNodeG6qW4gdsOgIGPDtG5nIHZp4buHYyBiw6FuIHRo4budaSBnaWFuIGtow7RuZyDEkeG7mWMgbOG6rXAgbmhhdQ0KIA0KYGBge3J9DQpjaGlzcS50ZXN0KG9kZDEpDQpgYGANClF1YSBr4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaCB0YSB0aOG6pXkgZ2nDoSB0cuG7iyBwX3ZhbHVlID0gMC40NzMyID4gMC4wNSAobeG7qWMgw70gbmdoxKlhIHRow7RuZyB0aMaw4budbmcpLCBuw6puIGNo4bqlcCBuaOG6rW4gZ2nhuqMgdGh1eeG6v3QgSDAuIFbhuq15IHbhu5tpIG3hu6ljIMO9IG5naMSpYSA1JSwga2h1IHbhu7FjIGPGsCB0csO6IHRpw6p1IGNodeG6qW4gdsOgIGPDtG5nIHZp4buHYyBiw6FuIHRo4budaSBnaWFuIMSR4buZYyBs4bqtcCBuaGF1Lg0KDQojIyBLaeG7g20gdHJhIHTDrW5oIMSR4buZYyBs4bqtcCBj4bunYSAyIGJp4bq/biBjaOG7p25nIHThu5ljIHbDoCBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbg0KDQpHaeG6oyB0aHV54bq/dDoNCg0KIC0gSDA6IGNo4bunbmcgdOG7mWMgdsOgIGPDtG5nIHZp4buHYyBiw6FuIHRo4budaSBnaWFuIGdpYW4gxJHhu5ljIGzhuq1wDQogDQogLSBIMTogY2jhu6duZyB04buZYyB2w6AgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4ga2jDtG5nIMSR4buZYyBs4bqtcCBuaGF1DQoNCmBgYHtyfQ0KY2hpc3EudGVzdChvZGQyKQ0KYGBgDQoNClF1YSBr4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaCB0YSB0aOG6pXkgZ2nDoSB0cuG7iyBwX3ZhbHVlID0gMC4wMDA4MDI1IDwgMC4wNSAobeG7qWMgw70gbmdoxKlhIHRow7RuZyB0aMaw4budbmcpLCBuw6puIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBIMC4gVuG6rXkgduG7m2kgbeG7qWMgw70gbmdoxKlhIDUlLCBjaOG7p25nIHThu5ljIHbDoCBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbiBnaWFuIGtow7RuZyDEkeG7mWMgbOG6rXAuDQoNCiMgS2hv4bqjbmcgxrDhu5tjIGzGsOG7o25nIGNobyB04bu3IGzhu4cNCg0KIyMgQ8O0bmcgdGjhu6ljIMaw4bubYyBsxrDhu6NuZzoNCg0KxJDhu4MgbMOgbSBiw6BpIHRvw6FuIMaw4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgYuG6sW5nIFIsIHRhIHRo4buxYyBoaeG7h24gY8OidSBs4buHbmggc2F1Og0KDQpCMS4gaW5zdGFsbC5wYWNrYWdlcyjigJxEZXNjVG9vbHPigJ0pOiBjw6BpIMSR4bq3dCBnw7NpIERlc2NUb29scy4NCg0KQjIuIGxpYnJhcnkoRGVjc1Rvb2xzKTogZ+G7jWkgZ8OzaSBEZXNjVG9vbHMuDQoNCkIzLiBCaW5vbUNJKGssIG4sIGNvbmYubGV2ZWwgPSBOVUxMLCBtZXRob2QgPSDigJx3YWxk4oCdKTogY8OidSBs4buHbmggxrDhu5tjIGzGsOG7o25nIHThu7cgbOG7hyBt4buZdCB04buVbmcgdGjhu4M7IHRyb25nIMSRw7MsIGs6IHPhu5EgcGjhuqduIHThu60gY8OzIHTDrW5oIGNo4bqldCBBLCBuOiBz4buRIHBo4bqnbiB04butIG3huqt1LCBjb25mLmxldmVsID0gTlVMTDogxJHhu5kgdGluIGPhuq15IG3hurdjIMSR4buLbmggbMOgIDk1JSwgbWV0aG9kID0gd2FsZDogcGjGsMahbmcgcGjDoXAgd2FsZC4NCg0KIyMgxJDhu4MgxrDhu5tjIGzGsOG7o25nIHThu7cgbOG7hyBuaOG7r25nIG5nxrDhu51pIGPDsyBz4buRIG7Eg20gxJFpIGjhu41jIGTGsOG7m2kgMTIgbsSDbSB0YSBsw6BtIG5oxrAgc2F1Og0KDQpgYGB7cn0NCm0gPC0gZGF0YSRlZHVjYXRpb24NCm0yIDwtIG1bbSA8IDEyXQ0KayA8LSBsZW5ndGgobTJbbTIgPCAzXSkNCm4gPC0gbGVuZ3RoKG0yKQ0KQmlub21DSShrLCBuLCBjb25mLmxldmVsID0gMC45NSwgbWV0aG9kID0gIndhbGQiKQ0KYGBgDQpUYSDEkcaw4bujYyBraG/huqNuZyDGsOG7m2MgbMaw4bujbmcgdOG7tyBs4buHIG5o4buvbmcgbmfGsOG7nWkgY8OzIHPhu5EgbsSDbSDEkWkgaOG7jWMgZMaw4bubaSAxMiBuxINtIHbhu5tpIMSR4buZIHRpbiBj4bqteSA5NSUgbMOgOiAwLjAzMTk5NTI1IDw9IHAgPD0gMC4wNDMyMTk5OA0KDQojIyDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIG5nxrDhu51pIHPhu5FuZyDhu58ga2h1IHbhu7FjIGPGsCB0csO6IHRpw6p1IGNodeG6qW4gY8OzIGPDtG5nIHZp4buHYyBiw6FuIHRo4budaSBnaWFuIMSR4buTbmcgdGjhu51pIGtp4buDbSDEkeG7i25oIHhlbSB04bu3IGzhu4cgKCUpIG5nxrDhu51pIHPhu5FuZyDhu58ga2h1IHbhu7FjIGPGsCB0csO6IHRpw6p1IGNodeG6qW4gY8OzIGPDtG5nIHZp4buHYyBiw6FuIHRo4budaSBnaWFuIGPDsyBi4bqxbmcgNDAlIGtow7RuZz8NCmBgYHtyfQ0KI1Thuq1wIGjhu6NwIGThu68gbGnhu4d1IGNo4buJIGJhbyBn4buTbSBuaOG7r25nIG5nxrDhu51pIGPDsyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbg0Kcm08LSBkYXRhW2RhdGEkcGFydHRpbWUgPT0gInllcyIsXQ0KI1Thuq1wIGjhu6NwIGNvbiBuaOG7r25nIG5nxrDhu51pIGPDsyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbiBz4buRbmcg4bufIGtodSB24buxYyBjxrAgdHLDuiB0acOqdSBjaHXhuqluDQpybTE8LXJtW3JtJHNtc2EgPT0gInllcyIsXQ0KI2tp4buDbSB0cmEgdOG7tyBs4buHDQpwcm9wLnRlc3QobGVuZ3RoKHJtMSRzbXNhKSwgbGVuZ3RoKHJtJHNtc2EpLCBwID0gMC40KQ0KYGBgDQpW4bubaSBraG/huqNuZyB0aW4gY+G6rXkgOTUlIMaw4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgbmfGsOG7nWkgc+G7kW5nIOG7nyBraHUgduG7sWMgY8awIHRyw7ogdGnDqnUgY2h14bqpbiBjw7MgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4gbuG6sW0gdHJvbmcga2hv4bqjbmcgdOG7qyAwLjczMjEyOTAgxJHhur9uIDAuNzY2MzExMQ0KDQpwLXZhbHVlID0gMi4yZS0xNiA8IDAuMDUsbsOqbiBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSDAuIERvIMSRw7MgdOG7tyBs4buHICglKSBuZ8aw4budaSBz4buRbmcg4bufIGtodSB24buxYyBjxrAgdHLDuiB0acOqdSBjaHXhuqluIGPDsyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbiBraMO0bmcgYuG6sW5nIDQwJSB24bubaSBt4bupYyDDvSBuZ2jEqWEgNSUNCg0KIyMgxq/hu5tjIGzGsOG7o25nIHThu7cgbOG7hyBuZ8aw4budaSBz4buRbmcg4bufIGtodSB24buxYyBjxrAgdHLDuiB0acOqdSBjaHXhuqluIGtow7RuZyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbiDEkeG7k25nIHRo4budaSBraeG7g20gxJHhu4tuaCB4ZW0gdOG7tyBs4buHICglKSBuZ8aw4budaSBz4buRbmcg4bufIGtodSB24buxYyBjxrAgdHLDuiB0acOqdSBjaHXhuqluIGtow7RuZyBjw7MgY8O0bmcgdmnhu4djIGLDoW4gdGjhu51pIGdpYW4gY8OzIGLhurFuZyA0MCUga2jDtG5nPw0KICANCmBgYHtyfQ0Kcm08LSBkYXRhW2RhdGEkcGFydHRpbWUgPT0gIm5vIixdDQpybTE8LXJtW3JtJHNtc2EgPT0gInllcyIsXQ0KcHJvcC50ZXN0KGxlbmd0aChybTEkc21zYSksIGxlbmd0aChybSRzbXNhKSwgcCA9IDAuNCkNCmBgYA0KVuG7m2kga2hv4bqjbmcgdGluIGPhuq15IDk1JSDGsOG7m2MgbMaw4bujbmcgdOG7tyBs4buHIG5nxrDhu51pIHPhu5FuZyDhu58ga2h1IHbhu7FjIGPGsCB0csO6IHRpw6p1IGNodeG6qW4ga2jDtG5nIGPDsyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbiBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDAuNzM3NDQ0MCDEkeG6v24gMC43NDgxODM4DQoNCnAtdmFsdWUgPSAyLjJlLTE2IDwgMC4wNSxuw6puIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBIMC4gRG8gxJHDsyB04bu3IGzhu4cgKCUpIG5nxrDhu51pIHPhu5FuZyDhu58ga2h1IHbhu7FjIGPGsCB0csO6IHRpw6p1IGNodeG6qW4ga2jDtG5nIGPDsyBjw7RuZyB2aeG7h2MgYsOhbiB0aOG7nWkgZ2lhbiBraMO0bmcgYuG6sW5nIDQwJSB24bubaSBt4bupYyDDvSBuZ2jEqWEgNSUuICANCg0K