1 Giải thích bộ dữ liệu

HousePrices: đây là bộ dữ liệu khảo sát 546 người về giá bán nhà ở thành phố Windsor, Canada, trong tháng 7, 8 và 9 năm 1987.

Bộ dữ liệu gồm 546 quan sát và 12 biến. Trong đó có 6 biến định tính và 6 biến định lượng.

6 biến định tính bao gồm:

  • driveway: nhà có khu vực riêng để đậu xe không?

  • recreation: nhà có phòng giải trí không?

  • fullbase: nhà có được trang bị tầng hầm hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …)

  • gasheat: nhà có sử dụng gas để đun nước nóng không?

  • aircon: nhà có máy điều hoà trung tâm không?

  • prefer: nhà có nằm trong khu trung tâm của thành phố không?

6 biến định lượng bao gồm

  • price: giá bán nhà

  • lotsize: diện tích căn nhà

  • bedrooms: số phòng ngủ của ngôi nhà

  • bathrooms: số phòng tắm của ngôi nhà

  • stories: số tầng của ngôi nhà không tính tầng hầm

  • garage: số gara trong nhà

data('HousePrices', package = 'AER') 
h <- HousePrices
datatable(h)

2 Chọn biến phụ thuộc

2.1 Biến định lượng

Đối với biến định lượng tôi chọn biến bedrooms (số phòng ngủ) làm biến phụ thuộc. Lý do tôi chọn biến này làm biến phụ thuộc là để phân tích các yếu tố ảnh hưởng đến số phòng ngủ trong cuộc khảo sát như giá, diện tích, vị trí của ngôi nhà,…

2.2 Biến định tính

Đối với biến định tính tôi chọn biến fullbase làm biến phụ thuộc. Đây là biến phản ánh trang bị tầng hầm của ngôi nhà có được hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …). Lý do tôi chọn biến này làm biến phụ thuộc là vì muốn phân tích các yếu tố ảnh hưởng đến việc trang bị của tầng hầm như diện tích ngôi nhà, giá nhà, …

3 Thống kê mô tả

3.1 Biến price

  • price: giá bán nhà
summary(h$price)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   25000   49125   62000   68122   82000  190000
sd(h$price)
## [1] 26702.67
  • Giá bán nhà dao động ở mức tử 25.000 USD đến 190.000 USD. Giá bán trung bình là 68.122 USD.

  • Có 25% số người trong cuộc khảo sát có giá bán thấp hơn 49.125 USD.

  • Có 50% số người trong cuộc khảo sát có giá bán thấp hơn 62.000 USD.

  • Có 75% số người trong cuộc khảo sát có giá bán thấp hơn 82.000 USD.

  • Giá bán có độ lệch chuẩn là 26702,67.

ID <- seq(1,546, length = length(h$price))
hID <- mutate(h,ID)
hID |> ggplot(aes( x = ID, y = price)) + geom_col( fill = 'lightpink') + xlab('ID') + ylab('Giá nhà')

BIỂU ĐỘ THỂ HIỆN GIÁ BÁN

3.2 Biến lotsize

  • lotsize: diện tích ngôi nhà
summary(h$lotsize)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1650    3600    4600    5150    6360   16200
sd(h$lotsize)
## [1] 2168.159
  • Diện tích ngôi nhà dao động trong khoảng từ 1.650 sqft đến 16.200 sqft. (sqft: feet vuông)

  • Diện tích trung bình là 5.150 sqft.

  • Có 25% số người trong cuộc khảo sát có diện tích nhà nhỏ hơn 3.600 sqft.

  • Có 50% số người trong cuộc khảo sát có diện tích nhà nhỏ hơn 4.600 sqft.

  • Có 75% số người trong cuộc khảo sát có diện tích nhà nhỏ hơn 6.360 sqft.

  • Diện tích ngôi nhà có độ lệch chuẩn là 2168,159.

hID |> ggplot( aes( x = ID, y = lotsize)) + geom_col( fill='lightpink') + xlab('ID') + ylab('Diện tích')

BIỂU ĐỒ THỂ HIỆN DIỆN TÍCH NHÀ

3.3 Biến Bedrooms

  • bedrooms: số phòng ngủ trong nhà
summary(h$bedrooms)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   2.000   3.000   2.965   3.000   6.000
var(h$bedrooms)
## [1] 0.543741
sd(h$bedrooms)
## [1] 0.7373879
  • Trong cuộc khảo sát, số phòng ngủ trong nhà dao động từ 1 đến 6 phòng.

  • Số phòng ngủ trung bình là gần 3 phòng.

  • Có 25% số người trong cuộc khảo sát có ít hơn 2 phòng ngủ trong nhà.

  • Có 75% số người trong cuộc khảo sát có ít hơn 3 phòng ngủ trong nhà.

  • Số phòng ngủ có phương sai là 0,5437 và độ lệch chuẩn là 0,7374.

table(h$bedrooms)
## 
##   1   2   3   4   5   6 
##   2 136 301  95  10   2
table(h$bedrooms)/sum(table(h$bedrooms))*100
## 
##          1          2          3          4          5          6 
##  0.3663004 24.9084249 55.1282051 17.3992674  1.8315018  0.3663004
h |> ggplot( aes( x = bedrooms, y= after_stat(count))) + geom_bar(fill='lightpink') + geom_text(aes(label= scales :: percent(after_stat(count/sum(count)),accuracy=.01)), stat = 'count', color= 'black', vjust= -.5) + theme_classic() + xlab('Số phòng ngủ') + ylab('Số người')

  • Nhà có 3 phòng ngủ chiếm tỷ lệ cao nhất 55,13%.

  • Nhà có 1 phòng ngủ và nhà có 6 phòng ngủ chiếm tỉ lệ thấp nhất 0,37%.

  • Nhà có 2 phòng ngủ chiếm tỷ lệ 24,91%.

  • Nhà có 4 phòng ngủ chiếm tỷ lệ 17,4%.

  • Nhà có 5 phòng ngủ chiếm tỷ lệ 1,83%.

3.4 Biến bathrooms

  • bathrooms: số phòng tắm trong nhà
summary(h$bathrooms)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   1.000   1.000   1.286   2.000   4.000
var(h$bathrooms)
## [1] 0.2521625
sd(h$bathrooms)
## [1] 0.5021579
  • Trong cuộc khảo sát, số phòng tắm trong nhà giao động từ 1 đến 4 phòng. Số phòng trung bình là 1.

  • Có 50% số người trong cuộc khảo sát có 1 phòng tắm trong nhà.

  • Có 75% số người trong cuộc khảo sát có ít hơn 2 phòng tắm trong nhà.

table(h$bathrooms)
## 
##   1   2   3   4 
## 402 133  10   1
table(h$bathrooms)/sum(table(h$bathrooms))*100
## 
##          1          2          3          4 
## 73.6263736 24.3589744  1.8315018  0.1831502
h |> ggplot( aes( x = bathrooms, y= after_stat(count))) + geom_bar(fill='lightpink') + geom_text(aes(label= scales :: percent(after_stat(count/sum(count)),accuracy=.01)), stat = 'count', color= 'black', vjust= -.5) + theme_classic() + xlab('Số phòng tắm') + ylab('Số người')

  • Nhà có 1 phòng tắm chiếm tỷ lệ cao nhất 73,63%

  • Nhà có 4 phòng tắm chiếm tỷ lệ thấp nhất 0,18%

  • Nhà có 2 phòng tắm chiếm tỷ lệ 24,36% và nhà có 3 phòng tắm chiếm tỷ lệ 1,83%

3.5 Biến stories

  • stories: Số tầng của ngôi nhà không tính tầng hầm
summary(h$stories)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   1.000   2.000   1.808   2.000   4.000
var(h$stories)
## [1] 0.7537756
sd(h$stories)
## [1] 0.8682025
  • Trong cuộc khảo sát, số tầng của ngôi nhà không tính tầng hầm dao động từ 1 đến 4 tầng.

  • Có 25% số người trong cuộc khảo sát có nhà ít hơn 1 tầng (không tính tầng hầm)

  • Có 75% số người trong cuộc khảo sát có nhà ít hơn 2 tầng (không tính tầng hầm)

table(h$stories)
## 
##   1   2   3   4 
## 227 238  40  41
table(h$stories)/sum(table(h$stories))*100
## 
##         1         2         3         4 
## 41.575092 43.589744  7.326007  7.509158
h |> ggplot( aes( x = stories, y= after_stat(count))) + geom_bar(fill='lightpink') + geom_text(aes(label= scales :: percent(after_stat(count/sum(count)),accuracy=.01)), stat = 'count', color= 'black', vjust= -.5) + theme_classic() + xlab('Số tầng') + ylab('Số người')

  • Nhà có 2 tầng (không tính tầng hầm) chiếm tỷ lệ cao nhất 43,59%

  • Nhà có 3 tầng (không tính tầng hầm) chiếm tỷ lệ thấp nhất 7,33%

  • Nhà có 1 tầng (không tính tầng hầm) chiếm tỷ lệ 41,58%

  • Nhà có 4 tầng (không tính tầng hầm) chiếm tỷ lệ 7,51%

3.6 Biến driveway

  • driveway: Khu vực riêng đậu xe riêng của ngôi nhà
table(h$driveway)
## 
##  no yes 
##  77 469
table(h$driveway)/sum(table(h$driveway))*100
## 
##       no      yes 
## 14.10256 85.89744
h |> ggplot(aes( x = driveway, y = after_stat(count))) +
  geom_bar(fill = 'lightpink') +
  geom_text(aes(label = scales::percent( after_stat(count/sum(count)))), stat = 'count', color = 'black', vjust = 1.5) +
  theme_classic() + 
  labs(x = 'driveway', y = 'Số người')

ld <- h %>% group_by(driveway) %>% summarise( n=n()) %>% mutate( percent =n/sum(n)) 
ld |> ggplot(aes(x='', y=percent, fill= driveway)) + geom_bar(stat='identity', width = 1) + geom_text(aes(label = paste0(round(percent*100), "%")), position = position_stack(vjust = 0.5))+
  coord_polar("y", start = 0) +
  scale_fill_manual(values = c("lightpink", "moccasin"), name = "driveway") +
    labs(title = "driveway") +
  theme_minimal()

  • Có 14% số người trong cuộc khảo sát không có khu vực riêng để đậu xe

  • Có 86% số người trong cuộc khảo sát có nhà có khu vực riêng để đậu xe.

3.7 Biến recreation

  • recreation: Nhà có phòng giải trí không?
table(h$recreation)
## 
##  no yes 
## 449  97
table(h$recreation)/sum(table(h$recreation))*100
## 
##       no      yes 
## 82.23443 17.76557
h |> ggplot(aes( x = recreation, y = after_stat(count))) +
  geom_bar(fill = 'lightpink') +
  geom_text(aes(label = scales::percent( after_stat(count/sum(count)))), stat = 'count', color = 'black', vjust = 1.5) +
  theme_classic() + 
  labs(x = 'Phòng giải trí', y = 'Số người')

gt <- h %>% group_by(recreation) %>% summarise( n=n()) %>% mutate( percent =n/sum(n)) 
gt |> ggplot(aes(x='', y=percent, fill= recreation)) + geom_bar(stat='identity', width = 1) + geom_text(aes(label = paste0(round(percent*100), "%")), position = position_stack(vjust = 0.5))+
  coord_polar("y", start = 0) +
  scale_fill_manual(values = c("lightpink", "moccasin"), name = "Phòng giải trí") +
    labs(title = "PHÒNG GIẢI TRÍ") +
  theme_minimal()

  • Có 18% số người trong cuộc khảo sát nhà có phòng giải trí và 82% số người trong cuộc khảo sát nhà không có phòng giải trí.

3.8 Biến fullbase

  • fullbase: nhà có được trang bị tầng hầm hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …)
table(h$fullbase)
## 
##  no yes 
## 355 191
table(h$fullbase)/sum(table(h$fullbase))*100
## 
##       no      yes 
## 65.01832 34.98168
h |> ggplot(aes( x = fullbase, y = after_stat(count))) +
  geom_bar(fill = 'lightpink') +
  geom_text(aes(label = scales::percent( after_stat(count/sum(count)))), stat = 'count', color = 'black', vjust = 1.5) +
  theme_classic() + 
  labs(x = 'fullbase', y = 'Số người')

thht <- h %>% group_by(fullbase) %>% summarise( n=n()) %>% mutate( percent =n/sum(n)) 
thht |> ggplot(aes(x='', y=percent, fill= fullbase)) + geom_bar(stat='identity', width = 1) + geom_text(aes(label = paste0(round(percent*100), "%")), position = position_stack(vjust = 0.5))+
  coord_polar("y", start = 0) +
  scale_fill_manual(values = c("lightpink", "moccasin"), name = "fullbase") +
    labs(title = "fullbase") +
  theme_minimal()

  • Có 35% số người trong cuộc khảo sát có ngôi nhà được trang bị tầng hầm hoàn thiện và 65% số người trong cuộc khảo sát có ngôi nhà không được trang bị tầng hầm hoàn thiện.

3.9 Biến gasheat

  • gasheat: nhà có sử dụng gas để đun nước nóng không?
table(h$gasheat)
## 
##  no yes 
## 521  25
table(h$gasheat)/sum(table(h$gasheat))*100
## 
##        no       yes 
## 95.421245  4.578755
h |> ggplot(aes( x = gasheat, y = after_stat(count))) +
  geom_bar(fill = 'lightpink') +
  geom_text(aes(label = scales::percent( after_stat(count/sum(count)))), stat = 'count', color = 'black', vjust = 1.5) +
  theme_classic() + 
  labs(x = 'gasheat', y = 'Số người')

gas <- h %>% group_by(gasheat) %>% summarise( n=n()) %>% mutate( percent =n/sum(n)) 
gas |> ggplot(aes(x='', y=percent, fill= gasheat)) + geom_bar(stat='identity', width = 1) + geom_text(aes(label = paste0(round(percent*100), "%")), position = position_stack(vjust = 0.5))+
  coord_polar("y", start = 0) +
  scale_fill_manual(values = c("lightpink", "moccasin"), name = "gasheat") +
    labs(title = "gasheat") +
  theme_minimal()

  • Có 95% số người trong cuộc khảo sát có sử dụng gas để đun nước nóng và 5% số người trong cuộc khảo sát không sử dụng gas để đun nước nóng.

3.10 Biến aircon

  • aircon: nhà có máy điều hoà trung tâm không?
table(h$aircon)
## 
##  no yes 
## 373 173
table(h$aircon)/sum(table(h$aircon))*100
## 
##       no      yes 
## 68.31502 31.68498
h |> ggplot(aes( x = aircon, y = after_stat(count))) +
  geom_bar(fill = 'lightpink') +
  geom_text(aes(label = scales::percent( after_stat(count/sum(count)))), stat = 'count', color = 'black', vjust = 1.5) +
  theme_classic() + 
  labs(x = 'aircon', y = 'Số người')

air <- h %>% group_by(aircon) %>% summarise( n=n()) %>% mutate( percent =n/sum(n)) 
air |> ggplot(aes(x='', y=percent, fill= aircon)) + geom_bar(stat='identity', width = 1) + geom_text(aes(label = paste0(round(percent*100), "%")), position = position_stack(vjust = 0.5))+
  coord_polar("y", start = 0) +
  scale_fill_manual(values = c("lightpink", "moccasin"), name = "aircon") +
    labs(title = "aircon") +
  theme_minimal()

  • Có 32% số người trong cuộc khảo sát có lắp máy điều hoà trung tâm trong nhà và 68% số người trong cuộc khảo sát không có lắp mấy điều hoà trung tâm trong nhà.

3.11 Biến garage

  • garage: số gara trong nhà
table(h$garage)
## 
##   0   1   2   3 
## 300 126 108  12
table(h$garage)/sum(table(h$garage))*100
## 
##         0         1         2         3 
## 54.945055 23.076923 19.780220  2.197802
h |> ggplot(aes( x = garage, y = after_stat(count))) +
  geom_bar(fill = 'lightpink') +
  geom_text(aes(label = scales::percent( after_stat(count/sum(count)))), stat = 'count', color = 'black', vjust = 1.5) +
  theme_classic() + 
  labs(x = 'garage', y = 'Số người')

  • Nhà không có gara chiếm tỷ lệ cao nhất 54,9%

  • Nhà có 3 gara chiếm tỷ lệ thấp nhất 2,2%

  • Nhà có 1 gara chiếm 23,1% và nhà có 2 gara chiếm 19,8%

3.12 Biến prefer

  • prefer: có nằm trong khu trung tâm của thành phố không?
table(h$prefer)
## 
##  no yes 
## 418 128
table(h$prefer)/sum(table(h$prefer))*100
## 
##       no      yes 
## 76.55678 23.44322
h |> ggplot(aes( x = prefer, y = after_stat(count))) +
  geom_bar(fill = 'lightpink') +
  geom_text(aes(label = scales::percent( after_stat(count/sum(count)))), stat = 'count', color = 'black', vjust = 1.5) +
  theme_classic() + 
  labs(x = 'prefer', y = 'Số người')

pre <- h %>% group_by(prefer) %>% summarise( n=n()) %>% mutate( percent =n/sum(n)) 
pre |> ggplot(aes(x='', y=percent, fill= prefer)) + geom_bar(stat='identity', width = 1) + geom_text(aes(label = paste0(round(percent*100), "%")), position = position_stack(vjust = 0.5))+
  coord_polar("y", start = 0) +
  scale_fill_manual(values = c("lightpink", "moccasin"), name = "prefer") +
    labs(title = "prefer") +
  theme_minimal()

  • Có 23% số người trong cuộc khảo sát có nhà nằm trong khu vực trung tâm thành phố và 77% số người trong cuộc khảo sát có nhà nằm ngoài trung tâm thành phố.

4 Mối quan hệ giữa các biến

4.1 Mối quan hệ giữa biến fullbase và prefer

  • fullbase: nhà có được trang bị tầng hầm hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …)

  • prefer: nhà có nằm trong khu vực trung tâm thành phố không?

4.1.1 Lập bảng tần số

a1 <- table(h$fullbase, h$prefer)
addmargins(a1)
##      
##        no yes Sum
##   no  297  58 355
##   yes 121  70 191
##   Sum 418 128 546
  • Có 297 người có nhà không nằm trong khu vực trung tâm thành phố và không có tầng hầm được trang bị hoàn thiện.

  • Có 121 người có nhà không nằm trong khu vực trung tâm thành phố nhưng có tầng hầm được trang bị hoàn thiện.

  • Có 58 người có nhà nằm trong khu vực trung tâm thành phố nhưng không có tầng hầm được trang bị hoàn thiện.

  • Có 70 người có nhà nằm trong khu vực trung tâm thành phố và có tầng hầm được trang bị hoàn thiện.

4.1.2 RelRisk, riskratio, oddsratio

RelRisk(a1)
## [1] 1.320615
riskratio(a1)
## $data
##        
##          no yes Total
##   no    297  58   355
##   yes   121  70   191
##   Total 418 128   546
## 
## $measure
##      risk ratio with 95% C.I.
##       estimate    lower    upper
##   no  1.000000       NA       NA
##   yes 2.243185 1.661303 3.028874
## 
## $p.value
##      two-sided
##         midp.exact fisher.exact   chi.square
##   no            NA           NA           NA
##   yes 1.724756e-07 1.669965e-07 9.151904e-08
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Tỷ lệ những người nhà không có tầng hầm được trang bị hoàn thiện không nằm trong khu vực trung thành phố nhiều hơn 32% so với tỷ lệ những người nhà có tầng hầm được trang bị hoàn thiện không nằm trong khu vực trung thành phố.

  • Tỷ lệ những người có nhà nằm trong khu vực trung tâm thành phố có tầng hầm được trang bị hoàn thiện bằng 2,24 lần tỷ lệ những người có nhà nằm trong khu vực trung tâm thành phố không có tầng được trang bị hoàn thiện.

oddsratio(a1)
## $data
##        
##          no yes Total
##   no    297  58   355
##   yes   121  70   191
##   Total 418 128   546
## 
## $measure
##      odds ratio with 95% C.I.
##       estimate    lower    upper
##   no   1.00000       NA       NA
##   yes  2.95422 1.967706 4.455468
## 
## $p.value
##      two-sided
##         midp.exact fisher.exact   chi.square
##   no            NA           NA           NA
##   yes 1.724756e-07 1.669965e-07 9.151904e-08
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"
  • Tỷ lệ những người có nhà nằm trong khu vực trung tâm thành phố trên những người không có nhà trong khu vực trung tâm thành phố của những ngôi nhà không có tầng hầm được trang bị hoàn thiện bằng 2,95 lần tỷ lệ những người có nhà nằm trong khu vực trung tâm thành phố trên những người có nhà không nằm trong khu vực trung tâm thành phố của những ngôi nhà có tầng hầm được trang bị hoàn thiện

4.1.3 Đồ thị

h |> count(fullbase, prefer) |>
  group_by(fullbase) |>
  mutate(pH = n/sum(n)) |>
  ggplot(aes(x = fullbase, y = n, fill = prefer)) +
  geom_col() +
  geom_text(aes(label = percent(pH, accuracy = .01)), position = position_stack(vjust = 0.5), size = 4) +
  ylab('prefer') +
  xlab('fullbase')

Đọc đồ thị, ta thấy:

  • Trong số những ngôi nhà không có tầng hầm được trang bị hoàn thiện thì có 83,66% không nằm trong khu vực trung tâm thành phố và 16,34% nằm trong khu vực trung tâm thành phố.

  • Trong số những ngôi nhà có tầng hầm được trang bị hoàn thiện thì có 63,35% không nằm trong khu vực trung tâm thành phố và 36,65% nằm trong khu vực trung tâm thành phố.

4.2 Mối quan hệ giữa biến fullbase và biến driveway

  • fullbase: nhà có được trang bị tầng hầm hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …)

  • driveway: khu vực đậu xe riêng của nhà

4.2.1 Lập bảng tần số

a2 <- table(h$fullbase, h$driveway)
addmargins(a2)
##      
##        no yes Sum
##   no   54 301 355
##   yes  23 168 191
##   Sum  77 469 546
  • Có 54 người trong cuộc khảo sát nhà không có khu vực đậu xe riêng và không có tầng hầm được trang bị hoàn thiện.

  • Có 301 người trong cuộc khảo sát nhà có khu vực đậu xe riêng nhưng không có tầng hầm được trang bị hoàn thiện.

  • Có 34 người trong cuộc khảo sát nhà không có khu vực đậu xe riêng nhưng có tầng hầm được trang bị hoàn thiện.

  • Có 168 người trong cuộc khảo sát nhà có khu vực đậu xe riêng và có tầng hầm được trang bị hoàn thiện.

4.2.2 RelRisk, riskratio, oddsratio

RelRisk(a2)
## [1] 1.263197
riskratio(a2)
## $data
##        
##         no yes Total
##   no    54 301   355
##   yes   23 168   191
##   Total 77 469   546
## 
## $measure
##      risk ratio with 95% C.I.
##       estimate     lower    upper
##   no   1.00000        NA       NA
##   yes  1.03738 0.9686805 1.110951
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact chi.square
##   no          NA           NA         NA
##   yes  0.3141123     0.367124  0.3102127
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Tỷ lệ người có nhà không có khu vực đậu xe riêng và không có tầng hầm được trang bị hoàn thiện nhiều hơn 26% so với tỷ lệ người có nhà không có khu vực đậu xe riêng nhưng có tầng hầm được trang bị hoàn thiện.

  • Tỷ lệ người có nhà có khu vực đậu xe riêng và có tầng hầm được trang bị hoàn thiện nhiều hơn 3,7% so với tỷ lệ người có nhà có khu vực đậu xe riêng nhưng không có tầng hầm được trang bị hoàn thiện.

oddsratio(a2)
## $data
##        
##         no yes Total
##   no    54 301   355
##   yes   23 168   191
##   Total 77 469   546
## 
## $measure
##      odds ratio with 95% C.I.
##       estimate     lower   upper
##   no  1.000000        NA      NA
##   yes 1.305199 0.7811282 2.24292
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact chi.square
##   no          NA           NA         NA
##   yes  0.3141123     0.367124  0.3102127
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"
  • Tỷ lệ những người có nhà có khu vực đậu xe riêng trên những người có nhà không có khu vực đậu xe riêng trong số những người có nhà không có tầng hầm được trang bị hoàn thiện nhiều hơn 30,5% so với tỷ lệ những người có nhà có khu vực đậu xe riêng trên những người có nhà không có khu vực đậu xe riêng trong số những người có nhà có tầng hầm được trang bị hoàn thiện.

4.2.3 Đồ thị

h |> count(fullbase, driveway) |>
  group_by(fullbase) |>
  mutate(pH = n/sum(n)) |>
  ggplot(aes(x = fullbase, y = n, fill = driveway)) +
  geom_col() +
  geom_text(aes(label = percent(pH, accuracy = .01)), position = position_stack(vjust = 0.5), size = 4) +
  ylab('driveway') +
  xlab('fullbase')

Nhìn đồ thị ta thấy:

  • Trong số những ngôi nhà không có tầng hầm được trang bị hoàn thiện thì có 84,79% là nhà có khu vực đậu xe riêng và 15,21% là nhà không có khu vực đậu xe riêng.

  • Trong số những ngôi nhà có tầng hầm được trang bị hoàn thiện thì có 87,96% là nhà có khu vực đậu xe riêng và 12,04% là nhà không có khu vực đậu xe riêng.

4.3 Mối quan hệ giữa biến fullbase và biến price

  • fullbase: nhà có được trang bị tầng hầm hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …)

  • price: giá bán nhà

4.3.1 Lập bảng tần số

a3 <- table(h$fullbase, h$gia)
addmargins(a3)
##      
##       thấp cao Sum
##   no   247 108 355
##   yes   98  93 191
##   Sum  345 201 546
  • Có 247 người trong cuộc khảo sát có nhà không có tầng hầm được trang bị hoàn thiện được bán với mức giá thấp.

  • Có 108 người trong cuộc khảo sát có nhà không có tầng hầm được trang bị hoàn thiện được bán với mức giá cao.

  • Có 98 người trong cuộc khảo sát có nhà có tầng hầm được trang bị hoàn thiện được bán với mức giá thấp.

  • Có 93 người trong cuộc khảo sát có nhà có tầng hầm được trang bị hoàn thiện được bán với mức giá cao.

4.3.2 RelRisk, riskratio, oddsratio

RelRisk(a3)
## [1] 1.356051
riskratio(a3)
## $data
##        
##         thấp cao Total
##   no     247 108   355
##   yes     98  93   191
##   Total  345 201   546
## 
## $measure
##      risk ratio with 95% C.I.
##       estimate    lower    upper
##   no  1.000000       NA       NA
##   yes 1.600494 1.291717 1.983083
## 
## $p.value
##      two-sided
##        midp.exact fisher.exact chi.square
##   no           NA           NA         NA
##   yes 2.91145e-05 3.944639e-05 2.4313e-05
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Tỷ lệ những người có nhà không có tầng hầm được trang bị hoàn thiện được bán với mức giá thấp nhiều hơn 35,6% so với tỷ lệ những người có nhà có tầng hầm được trang bị hoàn thiện được bán với mức giá thấp.

  • Tỷ lệ những người có nhà có tầng hầm được trang bị hoàn thiện được bán với mức giá cao nhiều hơn 60,05% so với tỷ lệ người có nhà không có tầng hầm được trang bị hoàn thiện được bán với mức giá cao.

oddsratio(a3)
## $data
##        
##         thấp cao Total
##   no     247 108   355
##   yes     98  93   191
##   Total  345 201   546
## 
## $measure
##      odds ratio with 95% C.I.
##       estimate    lower    upper
##   no  1.000000       NA       NA
##   yes 2.166523 1.507616 3.120285
## 
## $p.value
##      two-sided
##        midp.exact fisher.exact chi.square
##   no           NA           NA         NA
##   yes 2.91145e-05 3.944639e-05 2.4313e-05
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"
  • Tỷ lệ những nhà được bán với mức giá cao trên những nhà được bán với mức giá thấp trong số những nhà không có tầng hầm được trang bị hoàn thiện cao gấp 2,16 lần tỷ lệnhững nhà được bán với mức giá cao trên những nhà được bán với mức giá thấp trong số những nhà có tầng hầm được trang bị hoàn thiện. ### Đồ thị
h |> count(fullbase, gia) |>
  group_by(fullbase) |>
  mutate(pH = n/sum(n)) |>
  ggplot(aes(x = fullbase, y = n, fill = gia)) +
  geom_col() +
  geom_text(aes(label = percent(pH, accuracy = .01)), position = position_stack(vjust = 0.5), size = 4) +
  ylab('Giá bán nhà') +
  xlab('fullbase')

Nhìn đồ thị ta thấy:

  • Trong số những ngôi nhà không có tầng hầm được trang bị hoàn thiện thì có 30,42% là nhà được bán với mức giá cao và 69,58% là nhà được bán với mức giá thấp.

  • Trong số những ngôi nhà có tầng hầm được trang bị hoàn thiện thì có 48,69% là nhà được bán với mức giá cao và 51,31% là nhà được bán với mức giá thấp.

4.4 Mối quan hệ giữa biến fullbase và biến recreation

  • fullbase: nhà có được trang bị tầng hầm hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …)

  • recreation: nhà có phòng giải trí không?

4.4.1 Lập bảng tần số

a4 <- table(h$fullbase, h$recreation)
addmargins(a4)
##      
##        no yes Sum
##   no  329  26 355
##   yes 120  71 191
##   Sum 449  97 546
  • Có 329 người trong cuộc khảo sát có nhà không được trang bị tầng hầm hoàn thiện và không có phòng giải trí.

  • Có 26 người trong cuộc khảo sát có nhà không được trang bị tầng hầm hoàn thiện nhưng có phòng giải trí.

  • Có 120 người trong cuộc khảo sát có nhà được trang bị tầng hầm hoàn thiện nhưng không có phòng giải trí.

  • Có 71 người trong cuộc khảo sát có nhà được trang bị tầng hầm hoàn thiện và có phòng giải trí.

4.4.2 RelRisk, riskratio, oddsratio

RelRisk(a4)
## [1] 1.475094
riskratio(a4)
## $data
##        
##          no yes Total
##   no    329  26   355
##   yes   120  71   191
##   Total 449  97   546
## 
## $measure
##      risk ratio with 95% C.I.
##       estimate    lower    upper
##   no  1.000000       NA       NA
##   yes 5.075513 3.356849 7.674112
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact  chi.square
##   no          NA           NA          NA
##   yes          0 2.760878e-17 3.24569e-18
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Tỷ lệ những nhà không có tầng hầm được trang bị hoàn thiện và không có phòng giải trí nhiều hơn 47,5% tỷ lệ những nhà có tầng hầm được trang bị hoàn thiện nhưng không có phòng giải trí.

  • Tỷ lệ những nhà có tầng hầm được trang bị hoàn thiện và có phòng giải trí gấp 5 lần tỷ lệ những nhà không có tầng hầm được trang bị hoàn thiện nhưng có phòng giải trí.

oddsratio(a4)
## $data
##        
##          no yes Total
##   no    329  26   355
##   yes   120  71   191
##   Total 449  97   546
## 
## $measure
##      odds ratio with 95% C.I.
##       estimate    lower    upper
##   no  1.000000       NA       NA
##   yes 7.428772 4.574343 12.39923
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact  chi.square
##   no          NA           NA          NA
##   yes          0 2.760878e-17 3.24569e-18
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"
  • Tỷ lệ những nhà có phòng giải trí trên những nhà không có phòng giải trí trong số những nhà không có tầng hầm được trang bị hoàn thiện gấp 7,4 lần so với tỷ lệ những nhà có phòng giải trí trên những nhà không có phòng giải trí trong số những nhà có tầng hầm được trang bị hoàn thiện.

4.4.3 Đồ thị

h |> count(fullbase, recreation) |>
  group_by(fullbase) |>
  mutate(pH = n/sum(n)) |>
  ggplot(aes(x = fullbase, y = n, fill = recreation)) +
  geom_col() +
  geom_text(aes(label = percent(pH, accuracy = .01)), position = position_stack(vjust = 0.5), size = 4) +
  ylab('recreation') +
  xlab('fullbase')

Nhìn đồ thị ta thấy:

  • Trong số những nhà không có tầng hầm được trang bị hoàn thiện thì có 7,32% là có phòng giải trí và 92,68% là không có phòng giải trí.

  • Trong số những nhà có tầng hầm được trang bị hoàn thiện thì có 37,17% là có phòng giải trí và 62,83% là không có phòng giải trí.

4.5 Mối liên hệ giữa biến fullbase và lotsize

  • fullbase: nhà có được trang bị tầng hầm hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …)

  • lotsize: diện tích căn nhà

4.5.1 Lập bảng tần số

h$size <- cut(h$lotsize, breaks = c(0,5500,16300), labels = c('Small','Big') )
table(h$size)
## 
## Small   Big 
##   343   203

Tôi chia biến lotsize (diện tích căn nhà) thành 2 phần Big (lớn) và Small (nhỏ). Thì trong cuộc khảo sát có 343 có diện tích nhỏ và 203 căn nhà có diện tich lớn.

a5 <- table(h$fullbase, h$size)
addmargins(a5)
##      
##       Small Big Sum
##   no    234 121 355
##   yes   109  82 191
##   Sum   343 203 546
  • Có 234 người trong cuộc khảo sát có nhà có diện tích nhỏ và không có tầng hầm được trang bị hoàn thiện.

  • Có 121 người trong cuộc khảo sát có nhà có diện tích lớn nhưng không có tầng hầm được trang bị hoàn thiện.

  • Có 109 người trong cuộc khảo sát có nhà có diện tích nhỏ nhưng có tầng hầm được trang bị hoàn thiện.

  • Có 82 người trong cuộc khảo sát có nhà có diện tích lớn và có tầng hầm được trang bị hoàn thiện.

4.5.2 RelRisk, riskratio, oddsratio

RelRisk(a5)
## [1] 1.155033
riskratio(a5)
## $data
##        
##         Small Big Total
##   no      234 121   355
##   yes     109  82   191
##   Total   343 203   546
## 
## $measure
##      risk ratio with 95% C.I.
##       estimate    lower    upper
##   no  1.000000       NA       NA
##   yes 1.259573 1.012536 1.566882
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact chi.square
##   no          NA           NA         NA
##   yes 0.04280097   0.05104901  0.0413414
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Tỷ lệ những người có nhà có diện tích nhỏ không có tầng hầm được trang bị hoàn thiện nhiều hơn 15,5% so với tỷ lệ những người có nhà có diện tích nhỏ nhưng có tầng hầm được trang bị hoàn thiện.

  • Tỷ lệ những người có nhà có diện tích lớn có tầng hầm được trang bị hoàn thiện nhiều hơn 25,96% so với tỷ lệ những người có nhà có diện tích lớn nhưng không có tầng hầm được trang bị hoàn thiện.

oddsratio(a5)
## $data
##        
##         Small Big Total
##   no      234 121   355
##   yes     109  82   191
##   Total   343 203   546
## 
## $measure
##      odds ratio with 95% C.I.
##       estimate    lower    upper
##   no  1.000000       NA       NA
##   yes 1.453937 1.012248 2.087186
## 
## $p.value
##      two-sided
##       midp.exact fisher.exact chi.square
##   no          NA           NA         NA
##   yes 0.04280097   0.05104901  0.0413414
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"
  • Tỷ lệ những người có nhà diện tích lơn trên những nhà diện tích nhỏ trong số những ngôi nhà không có tầng hầm được trang bị hoàn thiện nhiều hơn 45,4% so với tỷ lệ những người có nhà diện tích lớn trên những nhà diện tích nhỏ trong số những ngôi nhà có tầng hầm được trang bị hoàn thiện.

4.5.3 Đồ thị

h |> count(fullbase, size) |>
  group_by(fullbase) |>
  mutate(pH = n/sum(n)) |>
  ggplot(aes(x = fullbase, y = n, fill = size)) +
  geom_col() +
  geom_text(aes(label = percent(pH, accuracy = .01)), position = position_stack(vjust = 0.5), size = 4) +
  ylab('size') +
  xlab('fullbase')

Nhìn đồ thị ta thấy:

  • Trong số những ngôi nhà không có tầng hầm được trang bị hoàn thiện thì có 34,08% là nhà có diện tich lớn và 65,92% là nhà có diện tich nhỏ.

  • Trong số những ngôi nhà có tầng hầm được trang bị hoàn thiện thì có 42,93% là nhà có diện tich lớn và 57,07% là nhà có diện tich nhỏ.

4.6 Mối liên hệ giữa biến bedrooms và size

  • bedrooms: số phòng ngủ

  • size: diện tích căn nhà

4.6.1 Lập bảng tần số

h$ngu <- cut( h$bedrooms, breaks = c(0,2,7), labels = c('ít', 'nhiều'))
table(h$ngu)
## 
##    ít nhiều 
##   138   408
  • Tôi chia biến bedrooms thành 2 phần ít và nhiều. Trong cuộc khảo sát có 138 người nhà có ít phòng ngủ và 408 người nhà có nhiều phòng ngủ.
a6 <- table(h$ngu, h$size)
addmargins(a6)
##        
##         Small Big Sum
##   ít      104  34 138
##   nhiều   239 169 408
##   Sum     343 203 546
  • Có 104 người trong cuộc khảo sát có diện tích nhà nhỏ có ít phòng ngủ.

  • Có 34 người trong cuộc khảo sát có diện tích nhà lớn có ít phòng ngủ.

  • Có 239 người trong cuộc khảo sát có diện tích nhà nhỏ có nhiều phòng ngủ .

  • Có 169 người trong cuộc khảo sát có diện tích nhà lớn có nhiều phòng ngủ.

4.6.2 RelRisk, riskratio, oddsratio

RelRisk(a6)
## [1] 1.28652
riskratio(a6)
## $data
##        
##         Small Big Total
##   ít      104  34   138
##   nhiều   239 169   408
##   Total   343 203   546
## 
## $measure
##        risk ratio with 95% C.I.
##         estimate   lower    upper
##   ít    1.000000      NA       NA
##   nhiều 1.681228 1.22843 2.300927
## 
## $p.value
##        two-sided
##           midp.exact fisher.exact   chi.square
##   ít              NA           NA           NA
##   nhiều 0.0003476904 0.0003624873 0.0004208389
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Tỷ lệ những người có nhà diện tích nhỏ có ít phòng ngủ nhiều hơn 28,65% so với tỷ lệ những người có nhà diện tích nhỏ có nhiều phòng ngủ.

  • Tỷ lệ những người có nhà diện tích lớn có nhiều phòng ngủ nhiều hơn 68,12% so với tỷ lệ những người có nhà diện tích lớn có ít phòng ngủ.

oddsratio(a6)
## $data
##        
##         Small Big Total
##   ít      104  34   138
##   nhiều   239 169   408
##   Total   343 203   546
## 
## $measure
##        odds ratio with 95% C.I.
##         estimate    lower    upper
##   ít    1.000000       NA       NA
##   nhiều 2.154556 1.406418 3.367406
## 
## $p.value
##        two-sided
##           midp.exact fisher.exact   chi.square
##   ít              NA           NA           NA
##   nhiều 0.0003476904 0.0003624873 0.0004208389
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"
  • Tỷ lệ những ngôi nhà diện tích lớn trên những ngôi nhà diện tích nhỏ trong số những ngôi nhà có ít phòng ngủ cao gấp 2,15 lần tỷ lệ những ngôi nhà diện tích lớn trên những ngôi nhà diện tích nhỏ trong số những ngôi nhà có nhiều phòng ngủ.

4.6.3 Đồ thị

h |> count(ngu, size) |>
  group_by(ngu) |>
  mutate(pH = n/sum(n)) |>
  ggplot(aes(x = ngu, y = n, fill = size)) +
  geom_col() +
  geom_text(aes(label = percent(pH, accuracy = .01)), position = position_stack(vjust = 0.5), size = 4) +
  ylab('Diện tích ngôi nhà') +
  xlab('Số phòng ngủ')

Nhìn đồ thị ta thấy:

  • Trong số những ngôi nhà có ít phòng ngủ thì có 24,64% là những ngôi nhà có diện tích lớn và 75,36% là những ngôi nhà có diện tích nhỏ.

  • Trong số những ngôi nhà có nhiều phòng ngủ thì có 41,42% là những ngôi nhà có diện tích lớn và 58,58% là những ngôi nhà có diện tích nhỏ.

4.7 Mối liên hệ giữa biến bedrooms và price

  • price: giá bán nhà

  • bedrooms: số phòng ngủ

4.7.1 Lập bảng tần số

h$gia <- cut( h$price, breaks = c(0,70000,191000), labels = c('thấp', 'cao'))
table(h$gia)
## 
## thấp  cao 
##  345  201
  • Tôi chia biến price (giá bán nhà) thành 2 phần cao và thấp. Trong cuộc khảo sát có 345 người bán nhà với mức giá thấp và 201 người bán nhà với mức giá cao.
a7 <- table(h$ngu, h$gia)
addmargins(a7)
##        
##         thấp cao Sum
##   ít     127  11 138
##   nhiều  218 190 408
##   Sum    345 201 546
  • Có 127 người trong cuộc khảo sát có ít phòng ngủ có mức giá bán thấp.

  • Có 111 người trong cuộc khảo sát có ít phòng ngủ có mức giá bán cao.

  • Có 218 người trong cuộc khảo sát có nhiều phòng ngủ có mức giá bán thấp.

  • Có 190 người trong cuộc khảo sát có nhiều phòng ngủ có mức giá bán cao.

4.7.2 RelRisk, riskratio, oddsratio

RelRisk(a7)
## [1] 1.722377
riskratio(a7)
## $data
##        
##         thấp cao Total
##   ít     127  11   138
##   nhiều  218 190   408
##   Total  345 201   546
## 
## $measure
##        risk ratio with 95% C.I.
##         estimate    lower    upper
##   ít    1.000000       NA       NA
##   nhiều 5.842246 3.282996 10.39655
## 
## $p.value
##        two-sided
##         midp.exact fisher.exact   chi.square
##   ít            NA           NA           NA
##   nhiều          0 2.243681e-18 4.408231e-16
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Tỷ lệ những nhà có ít phòng ngủ được bán với mức giá thấp nhiều hơn 72,24%% so với tỷ lệ những nhà có nhiều phòng ngủ được bán với mức giá thấp.

  • Tỷ lệ những nhà có nhiều phòng ngủ được bán với mức giá cao cao gấp 5,84 lần so với tỷ lệ những nhà có ít phòng ngủ được bán với mức giá cao.

oddsratio(a7)
## $data
##        
##         thấp cao Total
##   ít     127  11   138
##   nhiều  218 190   408
##   Total  345 201   546
## 
## $measure
##        odds ratio with 95% C.I.
##         estimate   lower    upper
##   ít    1.000000      NA       NA
##   nhiều 9.905394 5.41057 20.04372
## 
## $p.value
##        two-sided
##         midp.exact fisher.exact   chi.square
##   ít            NA           NA           NA
##   nhiều          0 2.243681e-18 4.408231e-16
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"
  • Tỷ lệ những ngôi nhà có giá bán cao trên những ngôi nhà có giá bán thấp trong số những ngôi nhà có ít phòng ngủ cao gấp 9,9 lần tỷ lệ những ngôi nhà có giá bán cao trên những ngôi nhà có giá bán thấp trong số những ngôi nhà có nhiều phòng ngủ.

4.7.3 Đồ thị

h |> count(ngu, gia) |>
  group_by(ngu) |>
  mutate(pH = n/sum(n)) |>
  ggplot(aes(x = ngu, y = n, fill = gia)) +
  geom_col() +
  geom_text(aes(label = percent(pH, accuracy = .01)), position = position_stack(vjust = 0.5), size = 4) +
  ylab('Giá bán nhà') +
  xlab('Số phòng ngủ')

Nhìn đồ thị ta thấy:

  • Trong số những ngôi nhà có ít phòng ngủ thì có 7,97% là nhà có mức giá bán cao, 92,03% là nhà có mức giá bán thấp.

  • Trong số những ngôi nhà có nhiều phòng ngủ thì có 46,57% là nhà có mức giá bán cao, 53,43% là nhà có mức giá bán thấp.

4.8 Mối liên hệ giữa biến bedrooms và biến prefer

  • prefer: nhà có nằm trong khu vực trung tâm thành phố không

  • bedrooms: số phòng ngủ

a8 <- table(h$ngu, h$prefer)
addmargins(a8)
##        
##          no yes Sum
##   ít    122  16 138
##   nhiều 296 112 408
##   Sum   418 128 546
  • Có 122 người trong cuộc khảo sát nhà có ít phòng ngủ không nằm trong khu vực trung tâm thành phố.

  • Có 296 người trong cuộc khảo sát nhà có nhiều phòng ngủ không nằm trong khu vực trung tâm thành phố.

  • Có 16 người trong cuộc khảo sát nhà có ít phòng ngủ không nằm trong khu vực trung tâm thành phố.

  • Có 112 người trong cuộc khảo sát nhà có nhiều phòng ngủ nằm trong khu vực trung tâm thành phố.

4.8.1 RelRisk, riskratio, oddsratio

RelRisk(a8)
## [1] 1.218566
riskratio(a8)
## $data
##        
##          no yes Total
##   ít    122  16   138
##   nhiều 296 112   408
##   Total 418 128   546
## 
## $measure
##        risk ratio with 95% C.I.
##         estimate    lower    upper
##   ít    1.000000       NA       NA
##   nhiều 2.367647 1.454887 3.853049
## 
## $p.value
##        two-sided
##          midp.exact fisher.exact   chi.square
##   ít             NA           NA           NA
##   nhiều 7.29951e-05 0.0001082007 0.0001441648
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Tỷ lệ nhà có ít phòng ngủ không nằm trong khu vực trung tâm thành phố nhiều hơn 21,86% so với tỷ lệ nhà có nhiều phòng ngủ nằm trong khu vực trung tâm thành phố.

  • Tỷ lệ nhà có nhiều phòng ngủ nằm trong khu vực trung tâm thành phố gấp 2,37 lần so với tỷ lệ nhà có ít phòng ngủ nằm trong khu vực trung tâm thành phố.

oddsratio(a8)
## $data
##        
##          no yes Total
##   ít    122  16   138
##   nhiều 296 112   408
##   Total 418 128   546
## 
## $measure
##        odds ratio with 95% C.I.
##         estimate    lower    upper
##   ít    1.000000       NA       NA
##   nhiều 2.859007 1.665527 5.210635
## 
## $p.value
##        two-sided
##          midp.exact fisher.exact   chi.square
##   ít             NA           NA           NA
##   nhiều 7.29951e-05 0.0001082007 0.0001441648
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"
  • Tỷ lệ những nhà không nằm trong khu vực trung tâm thành phố trên những nhà nằm trong khu vực trung tâm thành phố trong số những ngôi nhà được bán có ít phòng ngủ bằng 2,86 lần tỷ lệ những nhà không nằm trong khu vực trung tâm thành phố trên những nhà nằm trong khu vực trung tâm thành phố trong số những ngôi nhà được bán có nhiều phòng ngủ.

4.8.2 Đồ thị

h |> count(ngu, prefer) |>
  group_by(ngu) |>
  mutate(pH = n/sum(n)) |>
  ggplot(aes(x = ngu, y = n, fill = prefer)) +
  geom_col() +
  geom_text(aes(label = percent(pH, accuracy = .01)), position = position_stack(vjust = 0.5), size = 4) +
  ylab('Vị trí nhà') +
  xlab('Số phòng ngủ')

Nhìn đồ thị ta thấy:

  • Trong số những ngôi nhà có ít phòng ngủ thì có 11,59% là nhà nằm trong khu vực trung tâm thành phố và 88,41% là nhà không nằm trong khu vực trung tâm thành phố.

  • Trong số những ngôi nhà có nhiều phòng ngủ thì có 27,45% là nhà nằm trong khu vực trung tâm thành phố và 72,55% là nhà không nằm trong khu vực trung tâm thành phố.

4.9 Mối liên hệ giữa biến bedrooms và biến stories

  • stories: số tầng không tính tầng hầm

  • bedrooms: số phòng ngủ

4.9.1 Bảng tần số

h$tang <- cut(h$stories, breaks = c(0,1,4.1), labels = c('ít', 'nhiều'))
table(h$tang)
## 
##    ít nhiều 
##   227   319
  • Trong cuộc khảo sát có 227 người có nhà có ít tầng và 319 người có nhà có nhiều tầng.
a9 <- table(h$ngu, h$tang)
addmargins(a9)
##        
##          ít nhiều Sum
##   ít    117    21 138
##   nhiều 110   298 408
##   Sum   227   319 546
  • Có 117 người trong cuộc khảo sát có nhà có ít tầng có ít phòng ngủ.

  • Có 21 người trong cuộc khảo sát có nhà có nhiều tầng có ít phòng ngủ.

  • Có 110 người trong cuộc khảo sát có nhà có ít tầng có nhiều phòng ngủ.

  • Có 298 người trong cuộc khảo sát có nhà có nhiều tầng có nhiều phòng ngủ.

4.9.2 RelRisk, riskratio, oddsratio

RelRisk(a9)
## [1] 3.144664
riskratio(a9)
## $data
##        
##          ít nhiều Total
##   ít    117    21   138
##   nhiều 110   298   408
##   Total 227   319   546
## 
## $measure
##        risk ratio with 95% C.I.
##         estimate    lower    upper
##   ít     1.00000       NA       NA
##   nhiều  4.79972 3.223136 7.147483
## 
## $p.value
##        two-sided
##         midp.exact fisher.exact   chi.square
##   ít            NA           NA           NA
##   nhiều          0 1.419547e-33 1.003275e-32
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "Unconditional MLE & normal approximation (Wald) CI"
  • Tỷ lệ người có nhà ít tầng có ít phòng ngủ cao gấp 3,14 lần so với tỷ lệ người có nhà có ít tầng có nhiều phòng ngủ.

  • Tỷ lệ người có nhà có nhiều tầng có nhiều phòng ngủ cao gấp 4,8 lần so với tỷ lệ người có nhà có nhiều tầng có ít phòng ngủ.

oddsratio(a9)
## $data
##        
##          ít nhiều Total
##   ít    117    21   138
##   nhiều 110   298   408
##   Total 227   319   546
## 
## $measure
##        odds ratio with 95% C.I.
##         estimate    lower    upper
##   ít     1.00000       NA       NA
##   nhiều 14.92381 9.094548 25.57279
## 
## $p.value
##        two-sided
##         midp.exact fisher.exact   chi.square
##   ít            NA           NA           NA
##   nhiều          0 1.419547e-33 1.003275e-32
## 
## $correction
## [1] FALSE
## 
## attr(,"method")
## [1] "median-unbiased estimate & mid-p exact CI"
  • Tỷ lệ người có nhà có nhiều tầng trên người có nhà có ít tầng trong số những người có ít phòng ngủ bằng 14,7 lần tỷ lệ người có nhà có nhiều tầng trên người có nhà có ít tầng trong số những người có nhiều phòng ngủ.

4.9.3 Đồ thị

h |> count(ngu, tang) |>
  group_by(ngu) |>
  mutate(pH = n/sum(n)) |>
  ggplot(aes(x = ngu, y = n, fill = tang)) +
  geom_col() +
  geom_text(aes(label = percent(pH, accuracy = .01)), position = position_stack(vjust = 0.5), size = 4) +
  ylab('Số tầng') +
  xlab('Số phòng ngủ')

  • Trong số những ngôi nhà có ít phòng ngủ có 15,22% là nhà có nhiều tầng và 84,78% là nhà có ít tầng.

  • Trong số những ngôi nhà có nhiều phòng ngủ có 73,04% là nhà có nhiều tầng và 26,96% là nhà có ít tầng.

5 Kiểm định chi bình phương

5.1 Giữa 2 biến fullbase và biến prefer

  • fullbase: nhà có được trang bị tầng hầm hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …)

  • prefer: nhà có nằm trong khu vực trung tâm thành phố không?

Đặt giả thiết:

H0: Hai biến độc lập

H1: Hai biến không độc lập

chisq.test(a1)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  a1
## X-squared = 27.425, df = 1, p-value = 1.633e-07

Kết quả này cho chúng ta thấy rằng p-value < 0.05. đây cũng là bằng chứng để ta bác bỏ giả thuyết H0. Vậy 2 biến fullbase và prefer là hai biến không độc lập với nhau.

5.2 Giữa 2 biến fullbase và driveway

  • fullbase: nhà có được trang bị tầng hầm hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …)

  • driveway: nhà có khu vực đậu xe riêng không?

Đặt giả thiết:

H0: Hai biến độc lập

H1: Hai biến không độc lập

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

Kết quả này cho chúng ta thấy rằng p-value = 0,3757 > 0.05. Chấp nhận giả thiết H0. Vậy 2 biến fullbase và driveway là hai biến độc lập với nhau.

5.3 Giữa 2 biến fullbase và price

  • fullbase: nhà có được trang bị tầng hầm hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …)

  • price: giá bán nhà

Đặt giả thiết:

H0: Hai biến độc lập

H1: Hai biến không độc lập

chisq.test(a3)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  a3
## X-squared = 17.041, df = 1, p-value = 3.658e-05

Kết quả này cho chúng ta thấy rằng p-value < 0.05. Đây cũng là bằng chứng để ta bác bỏ giả thuyết H0. Vậy 2 biến fullbase và gia là hai biến không độc lập với nhau.

5.4 Giữa 2 biến fullbase và recreation

  • fullbase: nhà có được trang bị tầng hầm hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …)

  • recreation: nhà có phòng giải trí không?

Đặt giả thiết:

H0: Hai biến độc lập

H1: Hai biến không độc lập

chisq.test(a4)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  a4
## X-squared = 73.705, df = 1, p-value < 2.2e-16

Kết quả này cho chúng ta thấy rằng p-value < 0.05. Đây cũng là bằng chứng để ta bác bỏ giả thuyết H0. Vậy 2 biến fullbase và recreation là hai biến không độc lập với nhau.

5.5 Giữa 2 biến fullbase và lotsize

  • fullbase: nhà có được trang bị tầng hầm hoàn thiện hay không? ( tầng hầm hoàn thiện bao gồm các phòng như phòng tập thể dục, trò chơi điện tử, …)

  • lotsize: diện tích căn nhà

Đặt giả thiết:

H0: Hai biến độc lập

H1: Hai biến không độc lập

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

Kết quả này cho chúng ta thấy rằng p-value > 0.05. Đây cũng là bằng chứng để ta chấp nhận giả thuyết H0. Vậy 2 biến fullbase và lotsize là hai biến độc lập với nhau.

5.6 Giữa 2 biến ngu và size

  • ngu: số phòng ngủ

  • size: diện tích căn nhà

Đặt giả thiết:

H0: Hai biến độc lập

H1: Hai biến không độc lập

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

Kết quả này cho chúng ta thấy rằng p-value < 0.05. Đây cũng là bằng chứng để ta bác bỏ giả thuyết H0. Vậy 2 biến ngu và size là hai biến không độc lập với nhau.

5.7 Giữa 2 biến ngu và gia

  • gia: giá bán nhà

  • ngu: số phòng ngủ

Đặt giả thiết:

H0: Hai biến độc lập

H1: Hai biến không độc lập

chisq.test(a7)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  a7
## X-squared = 64.396, df = 1, p-value = 1.018e-15

Kết quả này cho chúng ta thấy rằng p-value < 0.05. Đây cũng là bằng chứng để ta bác bỏ giả thuyết H0. Vậy 2 biến ngu và gia là hai biến không độc lập với nhau.

5.8 Giữa 2 biến ngu và prefer

  • ngu: số phòng ngủ

  • prefer: nhà có nằm trong khu vực trung tâm thành phố không

Đặt giả thiết

H0: Hai biến độc lập

H1: Hai biến không độc lập

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

Kết quả này cho chúng ta thấy rằng p-value < 0.05. Đây cũng là bằng chứng để ta bác bỏ giả thuyết H0. Vậy 2 biến ngu và prefer là hai biến không độc lập với nhau.

5.9 Giữa 2 biến ngu và stories

  • ngu: số phòng ngủ

  • stories: số tầng của ngôi nhà không tính tầng hầm

Đặt giả thiết:

H0: Hai biến độc lập

H1: Hai biến không độc lập

chisq.test(a9)
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  a9
## X-squared = 139.57, df = 1, p-value < 2.2e-16

Kết quả này cho chúng ta thấy rằng p-value < 0.05. Đây cũng là bằng chứng để ta bác bỏ giả thuyết H0. Vậy 2 biến ngu và stories là hai biến không độc lập với nhau.

6 Bài toán ước lượng tỷ lệ

6.1 Ước lượng tỷ lệ cho biến price

t <- h[h$price > 70000,]
prop.test( length(t$price), length(h$price))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(t$price) out of length(h$price), null probability 0.5
## X-squared = 37.452, df = 1, p-value = 9.367e-10
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.3278412 0.4103067
## sample estimates:
##         p 
## 0.3681319

Với độ tin cậy 95% ta có tỷ lệ người bán nhà với giá trên 70000 USD trong cuộc khảo sát nằm trong khoảng từ 32,78% đến 41,03%.

6.2 Ước lượng tỷ lệ cho biến lotsize

t1 <- h[h$lotsize > 5500,]
prop.test( length(t1$lotsize), length(h$lotsize))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(t1$lotsize) out of length(h$lotsize), null probability 0.5
## X-squared = 35.386, df = 1, p-value = 2.704e-09
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.3313961 0.4140253
## sample estimates:
##         p 
## 0.3717949

Với độ tin cậy 95% ta có tỷ lệ người bán nhà có diện tích trên 5500 sqft trong cuộc khảo sát nằm trong khoảng từ 33,14% đến 41,4%.

6.3 Ước lượng tỷ lệ cho biến bedrooms

t2 <- h[h$bedrooms > 2,]
prop.test( length(t2$bedrooms), length(h$bedrooms))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(t2$bedrooms) out of length(h$bedrooms), null probability 0.5
## X-squared = 132.53, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.7082068 0.7827575
## sample estimates:
##         p 
## 0.7472527

Với độ tin cậy 95% ta có tỷ lệ người bán nhà có nhiều hơn 2 phòng ngủ trong cuộc khảo sát nằm trong khoảng từ 70,82% đến 78,28%.

6.4 Ước lượng tỷ lệ biến bathrooms

t3 <- h[h$bathrooms > 2,]
prop.test( length(t3$bathrooms), length(h$bathrooms))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(t3$bathrooms) out of length(h$bathrooms), null probability 0.5
## X-squared = 500.97, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.01062914 0.03686823
## sample estimates:
##          p 
## 0.02014652

Với độ tin cậy 95% ta có tỷ lệ người bán nhà có nhiều hơn 2 phòng tắm trong cuộc khảo sát nằm trong khoảng từ 1,1% đến 3,7%.

6.5 Ước lượng tỷ lệ biến stories

t4 <- h[h$stories > 1,]
prop.test( length(t4$stories), length(h$stories))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(t4$stories) out of length(h$stories), null probability 0.5
## X-squared = 15.167, df = 1, p-value = 9.843e-05
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.541539 0.625756
## sample estimates:
##         p 
## 0.5842491

Với độ tin cậy 95% ta có tỷ lệ người bán nhà có nhiều hơn 1 tầng trong cuộc khảo sát nằm trong khoảng từ 54,15% đến 62,58%.

6.6 Ước lượng tỷ lệ biến driveway

t5 <- h[h$driveway == 'no',]
prop.test( length(t5$driveway), length(h$driveway))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(t5$driveway) out of length(h$driveway), null probability 0.5
## X-squared = 280, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.1135030 0.1737204
## sample estimates:
##         p 
## 0.1410256

Với độ tin cậy 95% ta có tỷ lệ người bán nhà có khu vực đậu xe riêng trong cuộc khảo sát nằm trong khoảng từ 11,35% đến 17,37%.

6.7 Ước lượng tỷ lệ biến recreation

t6 <- h[h$recreation == 'yes',]
prop.test( length(t6$recreation), length(h$recreation))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(t6$recreation) out of length(h$recreation), null probability 0.5
## X-squared = 225.64, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.1470350 0.2129083
## sample estimates:
##         p 
## 0.1776557

Với độ tin cậy 95% ta có tỷ lệ người bán nhà có phòng giải trí trong cuộc khảo sát nằm trong khoảng từ 14,7% đến 21,3%.

6.8 Ước lượng tỷ lệ biến fullbase

t7 <- h[h$fullbase == 'yes',]
prop.test( length(t7$fullbase), length(h$fullbase))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(t7$fullbase) out of length(h$fullbase), null probability 0.5
## X-squared = 48.661, df = 1, p-value = 3.042e-12
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.3101042 0.3916759
## sample estimates:
##         p 
## 0.3498168

Với độ tin cậy 95% ta có tỷ lệ người bán nhà có tầng hầm được trang bị hoàn thiện trong cuộc khảo sát nằm trong khoảng từ 31,01% đến 39,2%.

6.9 Ước lượng tỷ lệ biến gasheat

t8 <- h[h$gasheat == 'yes',]
prop.test( length(t8$gasheat), length(h$gasheat))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(t8$gasheat) out of length(h$gasheat), null probability 0.5
## X-squared = 448.76, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.03045780 0.06778902
## sample estimates:
##          p 
## 0.04578755

Với độ tin cậy 95% ta có tỷ lệ người bán nhà có sử dụng gas để đun nước nóng trong cuộc khảo sát nằm trong khoảng từ 3,05% đến 6,8%.

6.10 Ước lượng tỷ lệ biến aircon

t9 <- h[h$aircon == 'yes',]
prop.test( length(t9$aircon), length(h$aircon))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(t9$aircon) out of length(h$aircon), null probability 0.5
## X-squared = 72.529, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.2783411 0.3579775
## sample estimates:
##         p 
## 0.3168498

Với độ tin cậy 95% ta có tỷ lệ người bán nhà có máy điều hoà trung tâm trong cuộc khảo sát nằm trong khoảng từ 27,83% đến 35,8%.

6.11 Ước lượng tỷ lệ biến garage

t10 <- h[h$garage > 2,]
prop.test( length(t10$garage), length(h$garage))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(t10$garage) out of length(h$garage), null probability 0.5
## X-squared = 497.14, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.01194850 0.03916523
## sample estimates:
##          p 
## 0.02197802

Với độ tin cậy 95% ta có tỷ lệ người bán nhà có điều hoà trung tâm trong nhà trong cuộc khảo sát nằm trong khoảng từ 1,2% đến 3,9%.

6.12 Ước lượng tỷ lệ biến prefer

t11 <- h[h$prefer =='yes',]
prop.test( length(t11$prefer), length(h$prefer))
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(t11$prefer) out of length(h$prefer), null probability 0.5
## X-squared = 152.97, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.1999671 0.2727033
## sample estimates:
##         p 
## 0.2344322

Với độ tin cậy 95% ta có tỷ lệ người bán nhà nằm trong khu vực trung tâm thành phố trong cuộc khảo sát nằm trong khoảng từ 20% đến 27,27%.

7 Hồi quy

7.1 Hồi quy cho biến fullbase

7.1.1 Hồi quy logit

MHlog <- glm( fullbase ~ prefer + recreation , family= binomial( link = 'logit'), data=h)
summary(MHlog)
## 
## Call:
## glm(formula = fullbase ~ prefer + recreation, family = binomial(link = "logit"), 
##     data = h)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)    -1.2299     0.1233  -9.977  < 2e-16 ***
## preferyes       0.9432     0.2231   4.228 2.35e-05 ***
## recreationyes   1.9247     0.2573   7.479 7.48e-14 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 706.89  on 545  degrees of freedom
## Residual deviance: 616.33  on 543  degrees of freedom
## AIC: 622.33
## 
## Number of Fisher Scoring iterations: 4
BrierScore(MHlog)
## [1] 0.1894667
confusionMatrix( table( predict(MHlog, type ='response') >= 0.5, MHlog$data$fullbase == 'yes'))
## Confusion Matrix and Statistics
## 
##        
##         FALSE TRUE
##   FALSE   329  120
##   TRUE     26   71
##                                           
##                Accuracy : 0.7326          
##                  95% CI : (0.6934, 0.7693)
##     No Information Rate : 0.6502          
##     P-Value [Acc > NIR] : 2.310e-05       
##                                           
##                   Kappa : 0.3368          
##                                           
##  Mcnemar's Test P-Value : 1.396e-14       
##                                           
##             Sensitivity : 0.9268          
##             Specificity : 0.3717          
##          Pos Pred Value : 0.7327          
##          Neg Pred Value : 0.7320          
##              Prevalence : 0.6502          
##          Detection Rate : 0.6026          
##    Detection Prevalence : 0.8223          
##       Balanced Accuracy : 0.6492          
##                                           
##        'Positive' Class : FALSE           
## 

Ta có mô hình hồi quy:

\(log(\frac{\pi}{1-\pi}) = -1,2299 + 0,9432prefer + 1,9247recreation\)

7.1.2 Hồi quy cloglog

MHcloglog <- glm( fullbase ~ prefer + recreation , family= binomial( link = 'cloglog'), data=h)
summary(MHcloglog)
## 
## Call:
## glm(formula = fullbase ~ prefer + recreation, family = binomial(link = "cloglog"), 
##     data = h)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)    -1.3450     0.1044 -12.880  < 2e-16 ***
## preferyes       0.7222     0.1597   4.523 6.11e-06 ***
## recreationyes   1.3768     0.1607   8.567  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 706.89  on 545  degrees of freedom
## Residual deviance: 614.99  on 543  degrees of freedom
## AIC: 620.99
## 
## Number of Fisher Scoring iterations: 5
BrierScore(MHcloglog)
## [1] 0.1890734
confusionMatrix( table( predict(MHcloglog, type ='response') >= 0.5, MHcloglog$data$fullbase == 'yes'))
## Confusion Matrix and Statistics
## 
##        
##         FALSE TRUE
##   FALSE   329  120
##   TRUE     26   71
##                                           
##                Accuracy : 0.7326          
##                  95% CI : (0.6934, 0.7693)
##     No Information Rate : 0.6502          
##     P-Value [Acc > NIR] : 2.310e-05       
##                                           
##                   Kappa : 0.3368          
##                                           
##  Mcnemar's Test P-Value : 1.396e-14       
##                                           
##             Sensitivity : 0.9268          
##             Specificity : 0.3717          
##          Pos Pred Value : 0.7327          
##          Neg Pred Value : 0.7320          
##              Prevalence : 0.6502          
##          Detection Rate : 0.6026          
##    Detection Prevalence : 0.8223          
##       Balanced Accuracy : 0.6492          
##                                           
##        'Positive' Class : FALSE           
## 

Ta có hàm hồi quy:

\(cloglog(\pi) = -1,345 + 0,7222prefer + 1,3768recreation\)

7.1.3 Hồi quy probit

MHprobit <- glm( fullbase ~ prefer  + recreation , family= binomial( link = 'probit'), data=h)
summary(MHprobit)
## 
## Call:
## glm(formula = fullbase ~ prefer + recreation, family = binomial(link = "probit"), 
##     data = h)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)   -0.75060    0.07171 -10.468  < 2e-16 ***
## preferyes      0.57257    0.13500   4.241 2.22e-05 ***
## recreationyes  1.18263    0.15334   7.712 1.24e-14 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 706.89  on 545  degrees of freedom
## Residual deviance: 616.18  on 543  degrees of freedom
## AIC: 622.18
## 
## Number of Fisher Scoring iterations: 4
BrierScore(MHprobit)
## [1] 0.1894331
confusionMatrix( table( predict(MHprobit, type ='response') >= 0.5, MHprobit$data$fullbase == 'yes'))
## Confusion Matrix and Statistics
## 
##        
##         FALSE TRUE
##   FALSE   329  120
##   TRUE     26   71
##                                           
##                Accuracy : 0.7326          
##                  95% CI : (0.6934, 0.7693)
##     No Information Rate : 0.6502          
##     P-Value [Acc > NIR] : 2.310e-05       
##                                           
##                   Kappa : 0.3368          
##                                           
##  Mcnemar's Test P-Value : 1.396e-14       
##                                           
##             Sensitivity : 0.9268          
##             Specificity : 0.3717          
##          Pos Pred Value : 0.7327          
##          Neg Pred Value : 0.7320          
##              Prevalence : 0.6502          
##          Detection Rate : 0.6026          
##    Detection Prevalence : 0.8223          
##       Balanced Accuracy : 0.6492          
##                                           
##        'Positive' Class : FALSE           
## 

Ta có hàm hồi quy:

\(probit(\pi) = -0,7506 + 0,57257prefer + 1,18263recreation\)

7.1.4 Lựa chọn mô hình phù hợp

AIC  <- c(622.33,620.99,622.18)
Brierscore <- c(0.1894667,0.1890734,0.1894331)
Deviance <- c( 616.33, 614.99, 616.18)
confusionMatrix <- c(0.7326 ,0.7326 ,0.7326 )  
MH <- c('logit','cloglog','probit')
BangKetQua <- data.frame(MH, confusionMatrix, Deviance, Brierscore, AIC)
BangKetQua
##        MH confusionMatrix Deviance Brierscore    AIC
## 1   logit          0.7326   616.33  0.1894667 622.33
## 2 cloglog          0.7326   614.99  0.1890734 620.99
## 3  probit          0.7326   616.18  0.1894331 622.18
  • Ta có mô hình hồi quy theo link function cloglog là tối ưu nhất. Vì với cùng độ chính xác là 73,26% thì mô hình cloglog có Diviance, Brierscore và AIC là thất nhất trong các mô hình.

7.1.5 Kiểm định sự phù hợp mô hình

anova(MHcloglog, test = 'Chisq')
## Analysis of Deviance Table
## 
## Model: binomial, link: cloglog
## 
## Response: fullbase
## 
## Terms added sequentially (first to last)
## 
## 
##            Df Deviance Resid. Df Resid. Dev  Pr(>Chi)    
## NULL                         545     706.89              
## prefer      1   27.565       544     679.32 1.519e-07 ***
## recreation  1   64.333       543     614.99 1.050e-15 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Giả thuyết H0: mô hình không phù hợp với dữ liệu điều tra

Ta có các p_value đều bé hơn 0,05, nên bác bỏ giả thuyết H0, mô hình trên là phù hợp.

7.1.6 Giải thích mô hình được chọn

Kết quả từ mô hình cloglog cho thấy biến fullbase chịu ảnh hưởng từ 2 biến độc lập là prefer và recreation. Trong đó:

  • preferyes: người có nhà nằm trong khu trung tâm của thành phố

  • recreationyes: nhà có phòng giải trí

Với giả thuyết các yếu tố khác không đổi, ta có tác động của từng biến lên biến fullbase:

  • Người có nhà nằm ở khu vực trung tâm thành phố có tỷ lệ tầng hầm được trang bị hoàn thiện cao hơn người có nhà không nằm người khu vực trung tâm thành phố.

  • Nhà có phòng giải trí có tỷ lệ tầng hầm được trang bị hoàn thiện cao hơn nhà không có phòng giải trí.

7.2 Hồi quy poisson

MHlog1 <- glm( bedrooms ~  price + stories , family= poisson( link = 'log'), data=h)
summary(MHlog1)
## 
## Call:
## glm(formula = bedrooms ~ price + stories, family = poisson(link = "log"), 
##     data = h)
## 
## Coefficients:
##              Estimate Std. Error z value Pr(>|z|)    
## (Intercept) 7.886e-01  7.250e-02  10.878  < 2e-16 ***
## price       2.085e-06  9.895e-07   2.107  0.03513 *  
## stories     8.312e-02  3.024e-02   2.748  0.00599 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for poisson family taken to be 1)
## 
##     Null deviance: 99.168  on 545  degrees of freedom
## Residual deviance: 78.755  on 543  degrees of freedom
## AIC: 1697.1
## 
## Number of Fisher Scoring iterations: 4

Ta thấy biến bedrooms chịu ảnh hưởng bởi 2 biến price và stories. Trong đó:

  • bedroom: số phòng ngủ trong nhà

  • price: giá bán nhà

  • stories: số tầng (không tính tầng hầm)

Ta có hàm hồi quy:

\(log(\frac{\mu(x)}{t}) = 0,7886 + 0,08312stories\) \(+ 2,085*10^{-6}price\)

Trong đó \(\frac{\mu(x)}{t}\) là tỉ lệ số phòng ngủ trung bình của những ngôi nhà có cùng số tầng và mức giá bán.

LS0tCnRpdGxlOiAidGx1YW5idGR0IgphdXRob3I6ICJOZ3V54buFbiBUaHXhu7UgVGhhbmggVHLDumMiCmRhdGU6ICIyMDIzLTA3LTE3IgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogNAogICAgbnVtYmVyX3NlY3Rpb25zOiBUUlVFCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGhpZ2hsaWdodDoga2F0ZQogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQoKYGBge3IgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KERUKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShkcGx5cikKbGlicmFyeShydmVzdCkKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShEZXNjVG9vbHMpCmxpYnJhcnkoZXBpdG9vbHMpCmxpYnJhcnkoY2FyZXQpCmBgYAoKIyBHaeG6o2kgdGjDrWNoIGLhu5kgZOG7ryBsaeG7h3UKCkhvdXNlUHJpY2VzOiDEkcOieSBsw6AgYuG7mSBk4buvIGxp4buHdSBraOG6o28gc8OhdCA1NDYgbmfGsOG7nWkgduG7gSBnacOhIGLDoW4gbmjDoCDhu58gdGjDoG5oIHBo4buRIFdpbmRzb3IsIENhbmFkYSwgdHJvbmcgdGjDoW5nIDcsIDggdsOgIDkgbsSDbSAxOTg3LgoKQuG7mSBk4buvIGxp4buHdSBn4buTbSA1NDYgcXVhbiBzw6F0IHbDoCAxMiBiaeG6v24uIFRyb25nIMSRw7MgY8OzIDYgYmnhur9uIMSR4buLbmggdMOtbmggdsOgIDYgYmnhur9uIMSR4buLbmggbMaw4bujbmcuCgo2IGJp4bq/biDEkeG7i25oIHTDrW5oIGJhbyBn4buTbToKCi0gICBkcml2ZXdheTogbmjDoCBjw7Mga2h1IHbhu7FjIHJpw6puZyDEkeG7gyDEkeG6rXUgeGUga2jDtG5nPwoKLSAgIHJlY3JlYXRpb246IG5ow6AgY8OzIHBow7JuZyBnaeG6o2kgdHLDrSBraMO0bmc/CgotICAgZnVsbGJhc2U6IG5ow6AgY8OzIMSRxrDhu6NjIHRyYW5nIGLhu4sgdOG6p25nIGjhuqdtIGhvw6BuIHRoaeG7h24gaGF5IGtow7RuZz8gKCB04bqnbmcgaOG6p20gaG/DoG4gdGhp4buHbiBiYW8gZ+G7k20gY8OhYyBwaMOybmcgbmjGsCBwaMOybmcgdOG6rXAgdGjhu4MgZOG7pWMsIHRyw7IgY2jGoWkgxJFp4buHbiB04butLCAuLi4pCgotICAgZ2FzaGVhdDogbmjDoCBjw7Mgc+G7rSBk4bulbmcgZ2FzIMSR4buDIMSRdW4gbsaw4bubYyBuw7NuZyBraMO0bmc/CgotICAgYWlyY29uOiBuaMOgIGPDsyBtw6F5IMSRaeG7gXUgaG/DoCB0cnVuZyB0w6JtIGtow7RuZz8KCi0gICBwcmVmZXI6IG5ow6AgY8OzIG7hurFtIHRyb25nIGtodSB0cnVuZyB0w6JtIGPhu6dhIHRow6BuaCBwaOG7kSBraMO0bmc/Cgo2IGJp4bq/biDEkeG7i25oIGzGsOG7o25nIGJhbyBn4buTbQoKLSAgIHByaWNlOiBnacOhIGLDoW4gbmjDoAoKLSAgIGxvdHNpemU6IGRp4buHbiB0w61jaCBjxINuIG5ow6AKCi0gICBiZWRyb29tczogc+G7kSBwaMOybmcgbmfhu6cgY+G7p2EgbmfDtGkgbmjDoAoKLSAgIGJhdGhyb29tczogc+G7kSBwaMOybmcgdOG6r20gY+G7p2EgbmfDtGkgbmjDoAoKLSAgIHN0b3JpZXM6IHPhu5EgdOG6p25nIGPhu6dhIG5nw7RpIG5ow6Aga2jDtG5nIHTDrW5oIHThuqduZyBo4bqnbQoKLSAgIGdhcmFnZTogc+G7kSBnYXJhIHRyb25nIG5ow6AKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmRhdGEoJ0hvdXNlUHJpY2VzJywgcGFja2FnZSA9ICdBRVInKSAKaCA8LSBIb3VzZVByaWNlcwpkYXRhdGFibGUoaCkKYGBgCgojIENo4buNbiBiaeG6v24gcGjhu6UgdGh14buZYwoKIyMgQmnhur9uIMSR4buLbmggbMaw4bujbmcKCsSQ4buRaSB24bubaSBiaeG6v24gxJHhu4tuaCBsxrDhu6NuZyB0w7RpIGNo4buNbiBiaeG6v24gYmVkcm9vbXMgKHPhu5EgcGjDsm5nIG5n4bunKSBsw6BtIGJp4bq/biBwaOG7pSB0aHXhu5ljLiBMw70gZG8gdMO0aSBjaOG7jW4gYmnhur9uIG7DoHkgbMOgbSBiaeG6v24gcGjhu6UgdGh14buZYyBsw6AgxJHhu4MgcGjDom4gdMOtY2ggY8OhYyB54bq/dSB04buRIOG6o25oIGjGsOG7n25nIMSR4bq/biBz4buRIHBow7JuZyBuZ+G7pyB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgbmjGsCBnacOhLCBkaeG7h24gdMOtY2gsIHbhu4sgdHLDrSBj4bunYSBuZ8O0aSBuaMOgLC4uLgoKIyMgQmnhur9uIMSR4buLbmggdMOtbmgKCsSQ4buRaSB24bubaSBiaeG6v24gxJHhu4tuaCB0w61uaCB0w7RpIGNo4buNbiBiaeG6v24gZnVsbGJhc2UgbMOgbSBiaeG6v24gcGjhu6UgdGh14buZYy4gxJDDonkgbMOgIGJp4bq/biBwaOG6o24gw6FuaCB0cmFuZyBi4buLIHThuqduZyBo4bqnbSBj4bunYSBuZ8O0aSBuaMOgIGPDsyDEkcaw4bujYyBob8OgbiB0aGnhu4duIGhheSBraMO0bmc/ICggdOG6p25nIGjhuqdtIGhvw6BuIHRoaeG7h24gYmFvIGfhu5NtIGPDoWMgcGjDsm5nIG5oxrAgcGjDsm5nIHThuq1wIHRo4buDIGThu6VjLCB0csOyIGNoxqFpIMSRaeG7h24gdOG7rSwgLi4uKS4gTMO9IGRvIHTDtGkgY2jhu41uIGJp4bq/biBuw6B5IGzDoG0gYmnhur9uIHBo4bulIHRodeG7mWMgbMOgIHbDrCBtdeG7kW4gcGjDom4gdMOtY2ggY8OhYyB54bq/dSB04buRIOG6o25oIGjGsOG7n25nIMSR4bq/biB2aeG7h2MgdHJhbmcgYuG7iyBj4bunYSB04bqnbmcgaOG6p20gbmjGsCBkaeG7h24gdMOtY2ggbmfDtGkgbmjDoCwgZ2nDoSBuaMOgLCAuLi4KCiMgVGjhu5FuZyBrw6ogbcO0IHThuqMKCiMjIEJp4bq/biBwcmljZQoKLSAgIHByaWNlOiBnacOhIGLDoW4gbmjDoAoKYGBge3J9CnN1bW1hcnkoaCRwcmljZSkKc2QoaCRwcmljZSkKYGBgCgotICAgR2nDoSBiw6FuIG5ow6AgZGFvIMSR4buZbmcg4bufIG3hu6ljIHThu60gMjUuMDAwIFVTRCDEkeG6v24gMTkwLjAwMCBVU0QuIEdpw6EgYsOhbiB0cnVuZyBiw6xuaCBsw6AgNjguMTIyIFVTRC4KCi0gICBDw7MgMjUlIHPhu5EgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBnacOhIGLDoW4gdGjhuqVwIGjGoW4gNDkuMTI1IFVTRC4KCi0gICBDw7MgNTAlIHPhu5EgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBnacOhIGLDoW4gdGjhuqVwIGjGoW4gNjIuMDAwIFVTRC4KCi0gICBDw7MgNzUlIHPhu5EgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBnacOhIGLDoW4gdGjhuqVwIGjGoW4gODIuMDAwIFVTRC4KCi0gICBHacOhIGLDoW4gY8OzIMSR4buZIGzhu4djaCBjaHXhuqluIGzDoCAyNjcwMiw2Ny4KCmBgYHtyfQpJRCA8LSBzZXEoMSw1NDYsIGxlbmd0aCA9IGxlbmd0aChoJHByaWNlKSkKaElEIDwtIG11dGF0ZShoLElEKQpoSUQgfD4gZ2dwbG90KGFlcyggeCA9IElELCB5ID0gcHJpY2UpKSArIGdlb21fY29sKCBmaWxsID0gJ2xpZ2h0cGluaycpICsgeGxhYignSUQnKSArIHlsYWIoJ0dpw6EgbmjDoCcpCmBgYAoKQknhu4JVIMSQ4buYIFRI4buCIEhJ4buGTiBHScOBIELDgU4KCiMjIEJp4bq/biBsb3RzaXplCgotICAgbG90c2l6ZTogZGnhu4duIHTDrWNoIG5nw7RpIG5ow6AKCmBgYHtyfQpzdW1tYXJ5KGgkbG90c2l6ZSkKc2QoaCRsb3RzaXplKQpgYGAKCi0gICBEaeG7h24gdMOtY2ggbmfDtGkgbmjDoCBkYW8gxJHhu5luZyB0cm9uZyBraG/huqNuZyB04burIDEuNjUwIHNxZnQgxJHhur9uIDE2LjIwMCBzcWZ0LiAoc3FmdDogZmVldCB2dcO0bmcpCgotICAgRGnhu4duIHTDrWNoIHRydW5nIGLDrG5oIGzDoCA1LjE1MCBzcWZ0LgoKLSAgIEPDsyAyNSUgc+G7kSBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgY8OzIGRp4buHbiB0w61jaCBuaMOgIG5o4buPIGjGoW4gMy42MDAgc3FmdC4KCi0gICBDw7MgNTAlIHPhu5EgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBkaeG7h24gdMOtY2ggbmjDoCBuaOG7jyBoxqFuIDQuNjAwIHNxZnQuCgotICAgQ8OzIDc1JSBz4buRIG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgZGnhu4duIHTDrWNoIG5ow6Agbmjhu48gaMahbiA2LjM2MCBzcWZ0LgoKLSAgIERp4buHbiB0w61jaCBuZ8O0aSBuaMOgIGPDsyDEkeG7mSBs4buHY2ggY2h14bqpbiBsw6AgMjE2OCwxNTkuCgpgYGB7cn0KaElEIHw+IGdncGxvdCggYWVzKCB4ID0gSUQsIHkgPSBsb3RzaXplKSkgKyBnZW9tX2NvbCggZmlsbD0nbGlnaHRwaW5rJykgKyB4bGFiKCdJRCcpICsgeWxhYignRGnhu4duIHTDrWNoJykKYGBgCgpCSeG7glUgxJDhu5IgVEjhu4IgSEnhu4ZOIERJ4buGTiBUw41DSCBOSMOACgojIyBCaeG6v24gQmVkcm9vbXMKCi0gICBiZWRyb29tczogc+G7kSBwaMOybmcgbmfhu6cgdHJvbmcgbmjDoAoKYGBge3J9CnN1bW1hcnkoaCRiZWRyb29tcykKdmFyKGgkYmVkcm9vbXMpCnNkKGgkYmVkcm9vbXMpCmBgYAoKLSAgIFRyb25nIGN14buZYyBraOG6o28gc8OhdCwgc+G7kSBwaMOybmcgbmfhu6cgdHJvbmcgbmjDoCBkYW8gxJHhu5luZyB04burIDEgxJHhur9uIDYgcGjDsm5nLgoKLSAgIFPhu5EgcGjDsm5nIG5n4bunIHRydW5nIGLDrG5oIGzDoCBn4bqnbiAzIHBow7JuZy4KCi0gICBDw7MgMjUlIHPhu5EgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyDDrXQgaMahbiAyIHBow7JuZyBuZ+G7pyB0cm9uZyBuaMOgLgoKLSAgIEPDsyA3NSUgc+G7kSBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgY8OzIMOtdCBoxqFuIDMgcGjDsm5nIG5n4bunIHRyb25nIG5ow6AuCgotICAgU+G7kSBwaMOybmcgbmfhu6cgY8OzIHBoxrDGoW5nIHNhaSBsw6AgMCw1NDM3IHbDoCDEkeG7mSBs4buHY2ggY2h14bqpbiBsw6AgMCw3Mzc0LgoKYGBge3J9CnRhYmxlKGgkYmVkcm9vbXMpCnRhYmxlKGgkYmVkcm9vbXMpL3N1bSh0YWJsZShoJGJlZHJvb21zKSkqMTAwCmggfD4gZ2dwbG90KCBhZXMoIHggPSBiZWRyb29tcywgeT0gYWZ0ZXJfc3RhdChjb3VudCkpKSArIGdlb21fYmFyKGZpbGw9J2xpZ2h0cGluaycpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbD0gc2NhbGVzIDo6IHBlcmNlbnQoYWZ0ZXJfc3RhdChjb3VudC9zdW0oY291bnQpKSxhY2N1cmFjeT0uMDEpKSwgc3RhdCA9ICdjb3VudCcsIGNvbG9yPSAnYmxhY2snLCB2anVzdD0gLS41KSArIHRoZW1lX2NsYXNzaWMoKSArIHhsYWIoJ1Phu5EgcGjDsm5nIG5n4bunJykgKyB5bGFiKCdT4buRIG5nxrDhu51pJykKYGBgCgotICAgTmjDoCBjw7MgMyBwaMOybmcgbmfhu6cgY2hp4bq/bSB04bu3IGzhu4cgY2FvIG5o4bqldCA1NSwxMyUuCgotICAgTmjDoCBjw7MgMSBwaMOybmcgbmfhu6cgdsOgIG5ow6AgY8OzIDYgcGjDsm5nIG5n4bunIGNoaeG6v20gdOG7iSBs4buHIHRo4bqlcCBuaOG6pXQgMCwzNyUuCgotICAgTmjDoCBjw7MgMiBwaMOybmcgbmfhu6cgY2hp4bq/bSB04bu3IGzhu4cgMjQsOTElLgoKLSAgIE5ow6AgY8OzIDQgcGjDsm5nIG5n4bunIGNoaeG6v20gdOG7tyBs4buHIDE3LDQlLgoKLSAgIE5ow6AgY8OzIDUgcGjDsm5nIG5n4bunIGNoaeG6v20gdOG7tyBs4buHIDEsODMlLgoKIyMgQmnhur9uIGJhdGhyb29tcwoKLSAgIGJhdGhyb29tczogc+G7kSBwaMOybmcgdOG6r20gdHJvbmcgbmjDoAoKYGBge3J9CnN1bW1hcnkoaCRiYXRocm9vbXMpCnZhcihoJGJhdGhyb29tcykKc2QoaCRiYXRocm9vbXMpCmBgYAoKLSAgIFRyb25nIGN14buZYyBraOG6o28gc8OhdCwgc+G7kSBwaMOybmcgdOG6r20gdHJvbmcgbmjDoCBnaWFvIMSR4buZbmcgdOG7qyAxIMSR4bq/biA0IHBow7JuZy4gU+G7kSBwaMOybmcgdHJ1bmcgYsOsbmggbMOgIDEuCgotICAgQ8OzIDUwJSBz4buRIG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgMSBwaMOybmcgdOG6r20gdHJvbmcgbmjDoC4KCi0gICBDw7MgNzUlIHPhu5EgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyDDrXQgaMahbiAyIHBow7JuZyB04bqvbSB0cm9uZyBuaMOgLgoKYGBge3J9CnRhYmxlKGgkYmF0aHJvb21zKQp0YWJsZShoJGJhdGhyb29tcykvc3VtKHRhYmxlKGgkYmF0aHJvb21zKSkqMTAwCmggfD4gZ2dwbG90KCBhZXMoIHggPSBiYXRocm9vbXMsIHk9IGFmdGVyX3N0YXQoY291bnQpKSkgKyBnZW9tX2JhcihmaWxsPSdsaWdodHBpbmsnKSArIGdlb21fdGV4dChhZXMobGFiZWw9IHNjYWxlcyA6OiBwZXJjZW50KGFmdGVyX3N0YXQoY291bnQvc3VtKGNvdW50KSksYWNjdXJhY3k9LjAxKSksIHN0YXQgPSAnY291bnQnLCBjb2xvcj0gJ2JsYWNrJywgdmp1c3Q9IC0uNSkgKyB0aGVtZV9jbGFzc2ljKCkgKyB4bGFiKCdT4buRIHBow7JuZyB04bqvbScpICsgeWxhYignU+G7kSBuZ8aw4budaScpCmBgYAoKLSAgIE5ow6AgY8OzIDEgcGjDsm5nIHThuq9tIGNoaeG6v20gdOG7tyBs4buHIGNhbyBuaOG6pXQgNzMsNjMlCgotICAgTmjDoCBjw7MgNCBwaMOybmcgdOG6r20gY2hp4bq/bSB04bu3IGzhu4cgdGjhuqVwIG5o4bqldCAwLDE4JQoKLSAgIE5ow6AgY8OzIDIgcGjDsm5nIHThuq9tIGNoaeG6v20gdOG7tyBs4buHIDI0LDM2JSB2w6AgbmjDoCBjw7MgMyBwaMOybmcgdOG6r20gY2hp4bq/bSB04bu3IGzhu4cgMSw4MyUKCiMjIEJp4bq/biBzdG9yaWVzCgotICAgc3RvcmllczogU+G7kSB04bqnbmcgY+G7p2EgbmfDtGkgbmjDoCBraMO0bmcgdMOtbmggdOG6p25nIGjhuqdtCgpgYGB7cn0Kc3VtbWFyeShoJHN0b3JpZXMpCnZhcihoJHN0b3JpZXMpCnNkKGgkc3RvcmllcykKYGBgCgotICAgVHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0LCBz4buRIHThuqduZyBj4bunYSBuZ8O0aSBuaMOgIGtow7RuZyB0w61uaCB04bqnbmcgaOG6p20gZGFvIMSR4buZbmcgdOG7qyAxIMSR4bq/biA0IHThuqduZy4KCi0gICBDw7MgMjUlIHPhu5EgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBuaMOgIMOtdCBoxqFuIDEgdOG6p25nIChraMO0bmcgdMOtbmggdOG6p25nIGjhuqdtKQoKLSAgIEPDsyA3NSUgc+G7kSBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgY8OzIG5ow6Agw610IGjGoW4gMiB04bqnbmcgKGtow7RuZyB0w61uaCB04bqnbmcgaOG6p20pCgpgYGB7cn0KdGFibGUoaCRzdG9yaWVzKQp0YWJsZShoJHN0b3JpZXMpL3N1bSh0YWJsZShoJHN0b3JpZXMpKSoxMDAKaCB8PiBnZ3Bsb3QoIGFlcyggeCA9IHN0b3JpZXMsIHk9IGFmdGVyX3N0YXQoY291bnQpKSkgKyBnZW9tX2JhcihmaWxsPSdsaWdodHBpbmsnKSArIGdlb21fdGV4dChhZXMobGFiZWw9IHNjYWxlcyA6OiBwZXJjZW50KGFmdGVyX3N0YXQoY291bnQvc3VtKGNvdW50KSksYWNjdXJhY3k9LjAxKSksIHN0YXQgPSAnY291bnQnLCBjb2xvcj0gJ2JsYWNrJywgdmp1c3Q9IC0uNSkgKyB0aGVtZV9jbGFzc2ljKCkgKyB4bGFiKCdT4buRIHThuqduZycpICsgeWxhYignU+G7kSBuZ8aw4budaScpCmBgYAoKLSAgIE5ow6AgY8OzIDIgdOG6p25nIChraMO0bmcgdMOtbmggdOG6p25nIGjhuqdtKSBjaGnhur9tIHThu7cgbOG7hyBjYW8gbmjhuqV0IDQzLDU5JQoKLSAgIE5ow6AgY8OzIDMgdOG6p25nIChraMO0bmcgdMOtbmggdOG6p25nIGjhuqdtKSBjaGnhur9tIHThu7cgbOG7hyB0aOG6pXAgbmjhuqV0IDcsMzMlCgotICAgTmjDoCBjw7MgMSB04bqnbmcgKGtow7RuZyB0w61uaCB04bqnbmcgaOG6p20pIGNoaeG6v20gdOG7tyBs4buHIDQxLDU4JQoKLSAgIE5ow6AgY8OzIDQgdOG6p25nIChraMO0bmcgdMOtbmggdOG6p25nIGjhuqdtKSBjaGnhur9tIHThu7cgbOG7hyA3LDUxJQoKIyMgQmnhur9uIGRyaXZld2F5CgotICAgZHJpdmV3YXk6IEtodSB24buxYyByacOqbmcgxJHhuq11IHhlIHJpw6puZyBj4bunYSBuZ8O0aSBuaMOgCgpgYGB7cn0KdGFibGUoaCRkcml2ZXdheSkKdGFibGUoaCRkcml2ZXdheSkvc3VtKHRhYmxlKGgkZHJpdmV3YXkpKSoxMDAKaCB8PiBnZ3Bsb3QoYWVzKCB4ID0gZHJpdmV3YXksIHkgPSBhZnRlcl9zdGF0KGNvdW50KSkpICsKICBnZW9tX2JhcihmaWxsID0gJ2xpZ2h0cGluaycpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KCBhZnRlcl9zdGF0KGNvdW50L3N1bShjb3VudCkpKSksIHN0YXQgPSAnY291bnQnLCBjb2xvciA9ICdibGFjaycsIHZqdXN0ID0gMS41KSArCiAgdGhlbWVfY2xhc3NpYygpICsgCiAgbGFicyh4ID0gJ2RyaXZld2F5JywgeSA9ICdT4buRIG5nxrDhu51pJykKCmxkIDwtIGggJT4lIGdyb3VwX2J5KGRyaXZld2F5KSAlPiUgc3VtbWFyaXNlKCBuPW4oKSkgJT4lIG11dGF0ZSggcGVyY2VudCA9bi9zdW0obikpIApsZCB8PiBnZ3Bsb3QoYWVzKHg9JycsIHk9cGVyY2VudCwgZmlsbD0gZHJpdmV3YXkpKSArIGdlb21fYmFyKHN0YXQ9J2lkZW50aXR5Jywgd2lkdGggPSAxKSArIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZTAocm91bmQocGVyY2VudCoxMDApLCAiJSIpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSkpKwogIGNvb3JkX3BvbGFyKCJ5Iiwgc3RhcnQgPSAwKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygibGlnaHRwaW5rIiwgIm1vY2Nhc2luIiksIG5hbWUgPSAiZHJpdmV3YXkiKSArCiAgICBsYWJzKHRpdGxlID0gImRyaXZld2F5IikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCi0gICBDw7MgMTQlIHPhu5EgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGtow7RuZyBjw7Mga2h1IHbhu7FjIHJpw6puZyDEkeG7gyDEkeG6rXUgeGUKCi0gICBDw7MgODYlIHPhu5EgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBuaMOgIGPDsyBraHUgduG7sWMgcmnDqm5nIMSR4buDIMSR4bqtdSB4ZS4KCiMjIEJp4bq/biByZWNyZWF0aW9uCgotICAgcmVjcmVhdGlvbjogTmjDoCBjw7MgcGjDsm5nIGdp4bqjaSB0csOtIGtow7RuZz8KCmBgYHtyfQp0YWJsZShoJHJlY3JlYXRpb24pCnRhYmxlKGgkcmVjcmVhdGlvbikvc3VtKHRhYmxlKGgkcmVjcmVhdGlvbikpKjEwMApoIHw+IGdncGxvdChhZXMoIHggPSByZWNyZWF0aW9uLCB5ID0gYWZ0ZXJfc3RhdChjb3VudCkpKSArCiAgZ2VvbV9iYXIoZmlsbCA9ICdsaWdodHBpbmsnKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudCggYWZ0ZXJfc3RhdChjb3VudC9zdW0oY291bnQpKSkpLCBzdGF0ID0gJ2NvdW50JywgY29sb3IgPSAnYmxhY2snLCB2anVzdCA9IDEuNSkgKwogIHRoZW1lX2NsYXNzaWMoKSArIAogIGxhYnMoeCA9ICdQaMOybmcgZ2nhuqNpIHRyw60nLCB5ID0gJ1Phu5EgbmfGsOG7nWknKQoKZ3QgPC0gaCAlPiUgZ3JvdXBfYnkocmVjcmVhdGlvbikgJT4lIHN1bW1hcmlzZSggbj1uKCkpICU+JSBtdXRhdGUoIHBlcmNlbnQgPW4vc3VtKG4pKSAKZ3QgfD4gZ2dwbG90KGFlcyh4PScnLCB5PXBlcmNlbnQsIGZpbGw9IHJlY3JlYXRpb24pKSArIGdlb21fYmFyKHN0YXQ9J2lkZW50aXR5Jywgd2lkdGggPSAxKSArIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZTAocm91bmQocGVyY2VudCoxMDApLCAiJSIpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSkpKwogIGNvb3JkX3BvbGFyKCJ5Iiwgc3RhcnQgPSAwKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygibGlnaHRwaW5rIiwgIm1vY2Nhc2luIiksIG5hbWUgPSAiUGjDsm5nIGdp4bqjaSB0csOtIikgKwogICAgbGFicyh0aXRsZSA9ICJQSMOSTkcgR0nhuqJJIFRSw40iKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKLSAgIEPDsyAxOCUgc+G7kSBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgbmjDoCBjw7MgcGjDsm5nIGdp4bqjaSB0csOtIHbDoCA4MiUgc+G7kSBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgbmjDoCBraMO0bmcgY8OzIHBow7JuZyBnaeG6o2kgdHLDrS4KCiMjIEJp4bq/biBmdWxsYmFzZQoKLSAgIGZ1bGxiYXNlOiBuaMOgIGPDsyDEkcaw4bujYyB0cmFuZyBi4buLIHThuqduZyBo4bqnbSBob8OgbiB0aGnhu4duIGhheSBraMO0bmc/ICggdOG6p25nIGjhuqdtIGhvw6BuIHRoaeG7h24gYmFvIGfhu5NtIGPDoWMgcGjDsm5nIG5oxrAgcGjDsm5nIHThuq1wIHRo4buDIGThu6VjLCB0csOyIGNoxqFpIMSRaeG7h24gdOG7rSwgLi4uKQoKYGBge3J9CnRhYmxlKGgkZnVsbGJhc2UpCnRhYmxlKGgkZnVsbGJhc2UpL3N1bSh0YWJsZShoJGZ1bGxiYXNlKSkqMTAwCmggfD4gZ2dwbG90KGFlcyggeCA9IGZ1bGxiYXNlLCB5ID0gYWZ0ZXJfc3RhdChjb3VudCkpKSArCiAgZ2VvbV9iYXIoZmlsbCA9ICdsaWdodHBpbmsnKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudCggYWZ0ZXJfc3RhdChjb3VudC9zdW0oY291bnQpKSkpLCBzdGF0ID0gJ2NvdW50JywgY29sb3IgPSAnYmxhY2snLCB2anVzdCA9IDEuNSkgKwogIHRoZW1lX2NsYXNzaWMoKSArIAogIGxhYnMoeCA9ICdmdWxsYmFzZScsIHkgPSAnU+G7kSBuZ8aw4budaScpCgp0aGh0IDwtIGggJT4lIGdyb3VwX2J5KGZ1bGxiYXNlKSAlPiUgc3VtbWFyaXNlKCBuPW4oKSkgJT4lIG11dGF0ZSggcGVyY2VudCA9bi9zdW0obikpIAp0aGh0IHw+IGdncGxvdChhZXMoeD0nJywgeT1wZXJjZW50LCBmaWxsPSBmdWxsYmFzZSkpICsgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLCB3aWR0aCA9IDEpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChwZXJjZW50KjEwMCksICIlIikpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSkrCiAgY29vcmRfcG9sYXIoInkiLCBzdGFydCA9IDApICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJsaWdodHBpbmsiLCAibW9jY2FzaW4iKSwgbmFtZSA9ICJmdWxsYmFzZSIpICsKICAgIGxhYnModGl0bGUgPSAiZnVsbGJhc2UiKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKLSAgIEPDsyAzNSUgc+G7kSBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgY8OzIG5nw7RpIG5ow6AgxJHGsOG7o2MgdHJhbmcgYuG7iyB04bqnbmcgaOG6p20gaG/DoG4gdGhp4buHbiB2w6AgNjUlIHPhu5EgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBuZ8O0aSBuaMOgIGtow7RuZyDEkcaw4bujYyB0cmFuZyBi4buLIHThuqduZyBo4bqnbSBob8OgbiB0aGnhu4duLgoKIyMgQmnhur9uIGdhc2hlYXQKCi0gICBnYXNoZWF0OiBuaMOgIGPDsyBz4butIGThu6VuZyBnYXMgxJHhu4MgxJF1biBuxrDhu5tjIG7Ds25nIGtow7RuZz8KCmBgYHtyfQp0YWJsZShoJGdhc2hlYXQpCnRhYmxlKGgkZ2FzaGVhdCkvc3VtKHRhYmxlKGgkZ2FzaGVhdCkpKjEwMApoIHw+IGdncGxvdChhZXMoIHggPSBnYXNoZWF0LCB5ID0gYWZ0ZXJfc3RhdChjb3VudCkpKSArCiAgZ2VvbV9iYXIoZmlsbCA9ICdsaWdodHBpbmsnKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudCggYWZ0ZXJfc3RhdChjb3VudC9zdW0oY291bnQpKSkpLCBzdGF0ID0gJ2NvdW50JywgY29sb3IgPSAnYmxhY2snLCB2anVzdCA9IDEuNSkgKwogIHRoZW1lX2NsYXNzaWMoKSArIAogIGxhYnMoeCA9ICdnYXNoZWF0JywgeSA9ICdT4buRIG5nxrDhu51pJykKCmdhcyA8LSBoICU+JSBncm91cF9ieShnYXNoZWF0KSAlPiUgc3VtbWFyaXNlKCBuPW4oKSkgJT4lIG11dGF0ZSggcGVyY2VudCA9bi9zdW0obikpIApnYXMgfD4gZ2dwbG90KGFlcyh4PScnLCB5PXBlcmNlbnQsIGZpbGw9IGdhc2hlYXQpKSArIGdlb21fYmFyKHN0YXQ9J2lkZW50aXR5Jywgd2lkdGggPSAxKSArIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZTAocm91bmQocGVyY2VudCoxMDApLCAiJSIpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSkpKwogIGNvb3JkX3BvbGFyKCJ5Iiwgc3RhcnQgPSAwKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygibGlnaHRwaW5rIiwgIm1vY2Nhc2luIiksIG5hbWUgPSAiZ2FzaGVhdCIpICsKICAgIGxhYnModGl0bGUgPSAiZ2FzaGVhdCIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgotICAgQ8OzIDk1JSBz4buRIG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7Mgc+G7rSBk4bulbmcgZ2FzIMSR4buDIMSRdW4gbsaw4bubYyBuw7NuZyB2w6AgNSUgc+G7kSBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQga2jDtG5nIHPhu60gZOG7pW5nIGdhcyDEkeG7gyDEkXVuIG7GsOG7m2MgbsOzbmcuCgojIyBCaeG6v24gYWlyY29uCgotICAgYWlyY29uOiBuaMOgIGPDsyBtw6F5IMSRaeG7gXUgaG/DoCB0cnVuZyB0w6JtIGtow7RuZz8KCmBgYHtyfQp0YWJsZShoJGFpcmNvbikKdGFibGUoaCRhaXJjb24pL3N1bSh0YWJsZShoJGFpcmNvbikpKjEwMApoIHw+IGdncGxvdChhZXMoIHggPSBhaXJjb24sIHkgPSBhZnRlcl9zdGF0KGNvdW50KSkpICsKICBnZW9tX2JhcihmaWxsID0gJ2xpZ2h0cGluaycpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KCBhZnRlcl9zdGF0KGNvdW50L3N1bShjb3VudCkpKSksIHN0YXQgPSAnY291bnQnLCBjb2xvciA9ICdibGFjaycsIHZqdXN0ID0gMS41KSArCiAgdGhlbWVfY2xhc3NpYygpICsgCiAgbGFicyh4ID0gJ2FpcmNvbicsIHkgPSAnU+G7kSBuZ8aw4budaScpCgphaXIgPC0gaCAlPiUgZ3JvdXBfYnkoYWlyY29uKSAlPiUgc3VtbWFyaXNlKCBuPW4oKSkgJT4lIG11dGF0ZSggcGVyY2VudCA9bi9zdW0obikpIAphaXIgfD4gZ2dwbG90KGFlcyh4PScnLCB5PXBlcmNlbnQsIGZpbGw9IGFpcmNvbikpICsgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLCB3aWR0aCA9IDEpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChwZXJjZW50KjEwMCksICIlIikpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSkrCiAgY29vcmRfcG9sYXIoInkiLCBzdGFydCA9IDApICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJsaWdodHBpbmsiLCAibW9jY2FzaW4iKSwgbmFtZSA9ICJhaXJjb24iKSArCiAgICBsYWJzKHRpdGxlID0gImFpcmNvbiIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgotICAgQ8OzIDMyJSBz4buRIG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgbOG6r3AgbcOheSDEkWnhu4F1IGhvw6AgdHJ1bmcgdMOibSB0cm9uZyBuaMOgIHbDoCA2OCUgc+G7kSBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQga2jDtG5nIGPDsyBs4bqvcCBt4bqleSDEkWnhu4F1IGhvw6AgdHJ1bmcgdMOibSB0cm9uZyBuaMOgLgoKIyMgQmnhur9uIGdhcmFnZQoKLSAgIGdhcmFnZTogc+G7kSBnYXJhIHRyb25nIG5ow6AKCmBgYHtyfQp0YWJsZShoJGdhcmFnZSkKdGFibGUoaCRnYXJhZ2UpL3N1bSh0YWJsZShoJGdhcmFnZSkpKjEwMApoIHw+IGdncGxvdChhZXMoIHggPSBnYXJhZ2UsIHkgPSBhZnRlcl9zdGF0KGNvdW50KSkpICsKICBnZW9tX2JhcihmaWxsID0gJ2xpZ2h0cGluaycpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KCBhZnRlcl9zdGF0KGNvdW50L3N1bShjb3VudCkpKSksIHN0YXQgPSAnY291bnQnLCBjb2xvciA9ICdibGFjaycsIHZqdXN0ID0gMS41KSArCiAgdGhlbWVfY2xhc3NpYygpICsgCiAgbGFicyh4ID0gJ2dhcmFnZScsIHkgPSAnU+G7kSBuZ8aw4budaScpCmBgYAoKLSAgIE5ow6Aga2jDtG5nIGPDsyBnYXJhIGNoaeG6v20gdOG7tyBs4buHIGNhbyBuaOG6pXQgNTQsOSUKCi0gICBOaMOgIGPDsyAzIGdhcmEgY2hp4bq/bSB04bu3IGzhu4cgdGjhuqVwIG5o4bqldCAyLDIlCgotICAgTmjDoCBjw7MgMSBnYXJhIGNoaeG6v20gMjMsMSUgdsOgIG5ow6AgY8OzIDIgZ2FyYSBjaGnhur9tIDE5LDglCgojIyBCaeG6v24gcHJlZmVyCgotICAgcHJlZmVyOiBjw7MgbuG6sW0gdHJvbmcga2h1IHRydW5nIHTDom0gY+G7p2EgdGjDoG5oIHBo4buRIGtow7RuZz8KCmBgYHtyfQp0YWJsZShoJHByZWZlcikKdGFibGUoaCRwcmVmZXIpL3N1bSh0YWJsZShoJHByZWZlcikpKjEwMApoIHw+IGdncGxvdChhZXMoIHggPSBwcmVmZXIsIHkgPSBhZnRlcl9zdGF0KGNvdW50KSkpICsKICBnZW9tX2JhcihmaWxsID0gJ2xpZ2h0cGluaycpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KCBhZnRlcl9zdGF0KGNvdW50L3N1bShjb3VudCkpKSksIHN0YXQgPSAnY291bnQnLCBjb2xvciA9ICdibGFjaycsIHZqdXN0ID0gMS41KSArCiAgdGhlbWVfY2xhc3NpYygpICsgCiAgbGFicyh4ID0gJ3ByZWZlcicsIHkgPSAnU+G7kSBuZ8aw4budaScpCgpwcmUgPC0gaCAlPiUgZ3JvdXBfYnkocHJlZmVyKSAlPiUgc3VtbWFyaXNlKCBuPW4oKSkgJT4lIG11dGF0ZSggcGVyY2VudCA9bi9zdW0obikpIApwcmUgfD4gZ2dwbG90KGFlcyh4PScnLCB5PXBlcmNlbnQsIGZpbGw9IHByZWZlcikpICsgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLCB3aWR0aCA9IDEpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChwZXJjZW50KjEwMCksICIlIikpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSkrCiAgY29vcmRfcG9sYXIoInkiLCBzdGFydCA9IDApICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJsaWdodHBpbmsiLCAibW9jY2FzaW4iKSwgbmFtZSA9ICJwcmVmZXIiKSArCiAgICBsYWJzKHRpdGxlID0gInByZWZlciIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgotICAgQ8OzIDIzJSBz4buRIG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgbmjDoCBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EgdsOgIDc3JSBz4buRIG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgbmjDoCBu4bqxbSBuZ2/DoGkgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EuCgojIE3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgY8OhYyBiaeG6v24KCiMjIE3hu5FpIHF1YW4gaOG7hyBnaeG7r2EgYmnhur9uIGZ1bGxiYXNlIHbDoCBwcmVmZXIKCi0gICBmdWxsYmFzZTogbmjDoCBjw7MgxJHGsOG7o2MgdHJhbmcgYuG7iyB04bqnbmcgaOG6p20gaG/DoG4gdGhp4buHbiBoYXkga2jDtG5nPyAoIHThuqduZyBo4bqnbSBob8OgbiB0aGnhu4duIGJhbyBn4buTbSBjw6FjIHBow7JuZyBuaMawIHBow7JuZyB04bqtcCB0aOG7gyBk4bulYywgdHLDsiBjaMahaSDEkWnhu4duIHThu60sIC4uLikKCi0gICBwcmVmZXI6IG5ow6AgY8OzIG7hurFtIHRyb25nIGtodSB24buxYyB0cnVuZyB0w6JtIHRow6BuaCBwaOG7kSBraMO0bmc/CgojIyMgTOG6rXAgYuG6o25nIHThuqduIHPhu5EKCmBgYHtyfQphMSA8LSB0YWJsZShoJGZ1bGxiYXNlLCBoJHByZWZlcikKYWRkbWFyZ2lucyhhMSkKYGBgCgotICAgQ8OzIDI5NyBuZ8aw4budaSBjw7MgbmjDoCBraMO0bmcgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRIHbDoCBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24uCgotICAgQ8OzIDEyMSBuZ8aw4budaSBjw7MgbmjDoCBraMO0bmcgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRIG5oxrBuZyBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbi4KCi0gICBDw7MgNTggbmfGsOG7nWkgY8OzIG5ow6AgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRIG5oxrBuZyBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24uCgotICAgQ8OzIDcwIG5nxrDhu51pIGPDsyBuaMOgIG7hurFtIHRyb25nIGtodSB24buxYyB0cnVuZyB0w6JtIHRow6BuaCBwaOG7kSB2w6AgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24uCgojIyMgUmVsUmlzaywgcmlza3JhdGlvLCBvZGRzcmF0aW8KCmBgYHtyfQpSZWxSaXNrKGExKQpyaXNrcmF0aW8oYTEpCmBgYAoKLSAgIFThu7cgbOG7hyBuaOG7r25nIG5nxrDhu51pIG5ow6Aga2jDtG5nIGPDsyB04bqnbmcgaOG6p20gxJHGsOG7o2MgdHJhbmcgYuG7iyBob8OgbiB0aGnhu4duIGtow7RuZyBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdGjDoG5oIHBo4buRIG5oaeG7gXUgaMahbiAzMiUgc28gduG7m2kgdOG7tyBs4buHIG5o4buvbmcgbmfGsOG7nWkgbmjDoCBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiBraMO0bmcgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHRow6BuaCBwaOG7kS4KCi0gICBU4bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjw7MgbmjDoCBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gYuG6sW5nIDIsMjQgbOG6p24gdOG7tyBs4buHIG5o4buvbmcgbmfGsOG7nWkgY8OzIG5ow6AgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRIGtow7RuZyBjw7MgdOG6p25nIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbi4KCmBgYHtyfQpvZGRzcmF0aW8oYTEpCmBgYAoKLSAgIFThu7cgbOG7hyBuaOG7r25nIG5nxrDhu51pIGPDsyBuaMOgIG7hurFtIHRyb25nIGtodSB24buxYyB0cnVuZyB0w6JtIHRow6BuaCBwaOG7kSB0csOqbiBuaOG7r25nIG5nxrDhu51pIGtow7RuZyBjw7MgbmjDoCB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EgY+G7p2Egbmjhu69uZyBuZ8O0aSBuaMOgIGtow7RuZyBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiBi4bqxbmcgMiw5NSBs4bqnbiB04bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjw7MgbmjDoCBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EgdHLDqm4gbmjhu69uZyBuZ8aw4budaSBjw7MgbmjDoCBraMO0bmcgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRIGPhu6dhIG5o4buvbmcgbmfDtGkgbmjDoCBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbgoKIyMjIMSQ4buTIHRo4buLCgpgYGB7cn0KaCB8PiBjb3VudChmdWxsYmFzZSwgcHJlZmVyKSB8PgogIGdyb3VwX2J5KGZ1bGxiYXNlKSB8PgogIG11dGF0ZShwSCA9IG4vc3VtKG4pKSB8PgogIGdncGxvdChhZXMoeCA9IGZ1bGxiYXNlLCB5ID0gbiwgZmlsbCA9IHByZWZlcikpICsKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChwSCwgYWNjdXJhY3kgPSAuMDEpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemUgPSA0KSArCiAgeWxhYigncHJlZmVyJykgKwogIHhsYWIoJ2Z1bGxiYXNlJykKYGBgCgrEkOG7jWMgxJHhu5MgdGjhu4ssIHRhIHRo4bqleToKCi0gICBUcm9uZyBz4buRIG5o4buvbmcgbmfDtGkgbmjDoCBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gdGjDrCBjw7MgODMsNjYlIGtow7RuZyBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EgdsOgIDE2LDM0JSBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EuCgotICAgVHJvbmcgc+G7kSBuaOG7r25nIG5nw7RpIG5ow6AgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gdGjDrCBjw7MgNjMsMzUlIGtow7RuZyBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EgdsOgIDM2LDY1JSBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EuCgojIyBN4buRaSBxdWFuIGjhu4cgZ2nhu69hIGJp4bq/biBmdWxsYmFzZSB2w6AgYmnhur9uIGRyaXZld2F5CgotICAgZnVsbGJhc2U6IG5ow6AgY8OzIMSRxrDhu6NjIHRyYW5nIGLhu4sgdOG6p25nIGjhuqdtIGhvw6BuIHRoaeG7h24gaGF5IGtow7RuZz8gKCB04bqnbmcgaOG6p20gaG/DoG4gdGhp4buHbiBiYW8gZ+G7k20gY8OhYyBwaMOybmcgbmjGsCBwaMOybmcgdOG6rXAgdGjhu4MgZOG7pWMsIHRyw7IgY2jGoWkgxJFp4buHbiB04butLCAuLi4pCgotICAgZHJpdmV3YXk6IGtodSB24buxYyDEkeG6rXUgeGUgcmnDqm5nIGPhu6dhIG5ow6AKCiMjIyBM4bqtcCBi4bqjbmcgdOG6p24gc+G7kQoKYGBge3J9CmEyIDwtIHRhYmxlKGgkZnVsbGJhc2UsIGgkZHJpdmV3YXkpCmFkZG1hcmdpbnMoYTIpCmBgYAoKLSAgIEPDsyA1NCBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgbmjDoCBraMO0bmcgY8OzIGtodSB24buxYyDEkeG6rXUgeGUgcmnDqm5nIHbDoCBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24uCgotICAgQ8OzIDMwMSBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgbmjDoCBjw7Mga2h1IHbhu7FjIMSR4bqtdSB4ZSByacOqbmcgbmjGsG5nIGtow7RuZyBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbi4KCi0gICBDw7MgMzQgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IG5ow6Aga2jDtG5nIGPDsyBraHUgduG7sWMgxJHhuq11IHhlIHJpw6puZyBuaMawbmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24uCgotICAgQ8OzIDE2OCBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgbmjDoCBjw7Mga2h1IHbhu7FjIMSR4bqtdSB4ZSByacOqbmcgdsOgIGPDsyB04bqnbmcgaOG6p20gxJHGsOG7o2MgdHJhbmcgYuG7iyBob8OgbiB0aGnhu4duLgoKIyMjIFJlbFJpc2ssIHJpc2tyYXRpbywgb2Rkc3JhdGlvCgpgYGB7cn0KUmVsUmlzayhhMikKcmlza3JhdGlvKGEyKQpgYGAKCi0gICBU4bu3IGzhu4cgbmfGsOG7nWkgY8OzIG5ow6Aga2jDtG5nIGPDsyBraHUgduG7sWMgxJHhuq11IHhlIHJpw6puZyB2w6Aga2jDtG5nIGPDsyB04bqnbmcgaOG6p20gxJHGsOG7o2MgdHJhbmcgYuG7iyBob8OgbiB0aGnhu4duIG5oaeG7gXUgaMahbiAyNiUgc28gduG7m2kgdOG7tyBs4buHIG5nxrDhu51pIGPDsyBuaMOgIGtow7RuZyBjw7Mga2h1IHbhu7FjIMSR4bqtdSB4ZSByacOqbmcgbmjGsG5nIGPDsyB04bqnbmcgaOG6p20gxJHGsOG7o2MgdHJhbmcgYuG7iyBob8OgbiB0aGnhu4duLgoKLSAgIFThu7cgbOG7hyBuZ8aw4budaSBjw7MgbmjDoCBjw7Mga2h1IHbhu7FjIMSR4bqtdSB4ZSByacOqbmcgdsOgIGPDsyB04bqnbmcgaOG6p20gxJHGsOG7o2MgdHJhbmcgYuG7iyBob8OgbiB0aGnhu4duIG5oaeG7gXUgaMahbiAzLDclIHNvIHbhu5tpIHThu7cgbOG7hyBuZ8aw4budaSBjw7MgbmjDoCBjw7Mga2h1IHbhu7FjIMSR4bqtdSB4ZSByacOqbmcgbmjGsG5nIGtow7RuZyBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbi4KCmBgYHtyfQpvZGRzcmF0aW8oYTIpCmBgYAoKLSAgIFThu7cgbOG7hyBuaOG7r25nIG5nxrDhu51pIGPDsyBuaMOgIGPDsyBraHUgduG7sWMgxJHhuq11IHhlIHJpw6puZyB0csOqbiBuaOG7r25nIG5nxrDhu51pIGPDsyBuaMOgIGtow7RuZyBjw7Mga2h1IHbhu7FjIMSR4bqtdSB4ZSByacOqbmcgdHJvbmcgc+G7kSBuaOG7r25nIG5nxrDhu51pIGPDsyBuaMOgIGtow7RuZyBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiBuaGnhu4F1IGjGoW4gMzAsNSUgc28gduG7m2kgdOG7tyBs4buHIG5o4buvbmcgbmfGsOG7nWkgY8OzIG5ow6AgY8OzIGtodSB24buxYyDEkeG6rXUgeGUgcmnDqm5nIHRyw6puIG5o4buvbmcgbmfGsOG7nWkgY8OzIG5ow6Aga2jDtG5nIGPDsyBraHUgduG7sWMgxJHhuq11IHhlIHJpw6puZyB0cm9uZyBz4buRIG5o4buvbmcgbmfGsOG7nWkgY8OzIG5ow6AgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24uCgojIyMgxJDhu5MgdGjhu4sKCmBgYHtyfQpoIHw+IGNvdW50KGZ1bGxiYXNlLCBkcml2ZXdheSkgfD4KICBncm91cF9ieShmdWxsYmFzZSkgfD4KICBtdXRhdGUocEggPSBuL3N1bShuKSkgfD4KICBnZ3Bsb3QoYWVzKHggPSBmdWxsYmFzZSwgeSA9IG4sIGZpbGwgPSBkcml2ZXdheSkpICsKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChwSCwgYWNjdXJhY3kgPSAuMDEpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemUgPSA0KSArCiAgeWxhYignZHJpdmV3YXknKSArCiAgeGxhYignZnVsbGJhc2UnKQpgYGAKCk5ow6xuIMSR4buTIHRo4buLIHRhIHRo4bqleToKCi0gICBUcm9uZyBz4buRIG5o4buvbmcgbmfDtGkgbmjDoCBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gdGjDrCBjw7MgODQsNzklIGzDoCBuaMOgIGPDsyBraHUgduG7sWMgxJHhuq11IHhlIHJpw6puZyB2w6AgMTUsMjElIGzDoCBuaMOgIGtow7RuZyBjw7Mga2h1IHbhu7FjIMSR4bqtdSB4ZSByacOqbmcuCgotICAgVHJvbmcgc+G7kSBuaOG7r25nIG5nw7RpIG5ow6AgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gdGjDrCBjw7MgODcsOTYlIGzDoCBuaMOgIGPDsyBraHUgduG7sWMgxJHhuq11IHhlIHJpw6puZyB2w6AgMTIsMDQlIGzDoCBuaMOgIGtow7RuZyBjw7Mga2h1IHbhu7FjIMSR4bqtdSB4ZSByacOqbmcuCgojIyBN4buRaSBxdWFuIGjhu4cgZ2nhu69hIGJp4bq/biBmdWxsYmFzZSB2w6AgYmnhur9uIHByaWNlCgotICAgZnVsbGJhc2U6IG5ow6AgY8OzIMSRxrDhu6NjIHRyYW5nIGLhu4sgdOG6p25nIGjhuqdtIGhvw6BuIHRoaeG7h24gaGF5IGtow7RuZz8gKCB04bqnbmcgaOG6p20gaG/DoG4gdGhp4buHbiBiYW8gZ+G7k20gY8OhYyBwaMOybmcgbmjGsCBwaMOybmcgdOG6rXAgdGjhu4MgZOG7pWMsIHRyw7IgY2jGoWkgxJFp4buHbiB04butLCAuLi4pCgotICAgcHJpY2U6IGdpw6EgYsOhbiBuaMOgCgojIyMgTOG6rXAgYuG6o25nIHThuqduIHPhu5EKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmgkZ2lhIDwtIGN1dCggaCRwcmljZSwgYnJlYWtzID0gYygwLDcwMDAwLDE5MTAwMCksIGxhYmVscyA9IGMoJ3Ro4bqlcCcsICdjYW8nKSkKdGFibGUoaCRnaWEpCmBgYAoKYGBge3J9CmEzIDwtIHRhYmxlKGgkZnVsbGJhc2UsIGgkZ2lhKQphZGRtYXJnaW5zKGEzKQpgYGAKCi0gICBDw7MgMjQ3IG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgbmjDoCBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gxJHGsOG7o2MgYsOhbiB24bubaSBt4bupYyBnacOhIHRo4bqlcC4KCi0gICBDw7MgMTA4IG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgbmjDoCBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gxJHGsOG7o2MgYsOhbiB24bubaSBt4bupYyBnacOhIGNhby4KCi0gICBDw7MgOTggbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBuaMOgIGPDsyB04bqnbmcgaOG6p20gxJHGsOG7o2MgdHJhbmcgYuG7iyBob8OgbiB0aGnhu4duIMSRxrDhu6NjIGLDoW4gduG7m2kgbeG7qWMgZ2nDoSB0aOG6pXAuCgotICAgQ8OzIDkzIG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgbmjDoCBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiDEkcaw4bujYyBiw6FuIHbhu5tpIG3hu6ljIGdpw6EgY2FvLgoKIyMjIFJlbFJpc2ssIHJpc2tyYXRpbywgb2Rkc3JhdGlvCgpgYGB7cn0KUmVsUmlzayhhMykKcmlza3JhdGlvKGEzKQpgYGAKCi0gICBU4bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjw7MgbmjDoCBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gxJHGsOG7o2MgYsOhbiB24bubaSBt4bupYyBnacOhIHRo4bqlcCBuaGnhu4F1IGjGoW4gMzUsNiUgc28gduG7m2kgdOG7tyBs4buHIG5o4buvbmcgbmfGsOG7nWkgY8OzIG5ow6AgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gxJHGsOG7o2MgYsOhbiB24bubaSBt4bupYyBnacOhIHRo4bqlcC4KCi0gICBU4bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjw7MgbmjDoCBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiDEkcaw4bujYyBiw6FuIHbhu5tpIG3hu6ljIGdpw6EgY2FvIG5oaeG7gXUgaMahbiA2MCwwNSUgc28gduG7m2kgdOG7tyBs4buHIG5nxrDhu51pIGPDsyBuaMOgIGtow7RuZyBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiDEkcaw4bujYyBiw6FuIHbhu5tpIG3hu6ljIGdpw6EgY2FvLgoKYGBge3J9Cm9kZHNyYXRpbyhhMykKYGBgCgotICAgVOG7tyBs4buHIG5o4buvbmcgbmjDoCDEkcaw4bujYyBiw6FuIHbhu5tpIG3hu6ljIGdpw6EgY2FvIHRyw6puIG5o4buvbmcgbmjDoCDEkcaw4bujYyBiw6FuIHbhu5tpIG3hu6ljIGdpw6EgdGjhuqVwIHRyb25nIHPhu5Egbmjhu69uZyBuaMOgIGtow7RuZyBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiBjYW8gZ+G6pXAgMiwxNiBs4bqnbiB04bu3IGzhu4duaOG7r25nIG5ow6AgxJHGsOG7o2MgYsOhbiB24bubaSBt4bupYyBnacOhIGNhbyB0csOqbiBuaOG7r25nIG5ow6AgxJHGsOG7o2MgYsOhbiB24bubaSBt4bupYyBnacOhIHRo4bqlcCB0cm9uZyBz4buRIG5o4buvbmcgbmjDoCBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbi4gXCMjIyDEkOG7kyB0aOG7iwoKYGBge3J9CmggfD4gY291bnQoZnVsbGJhc2UsIGdpYSkgfD4KICBncm91cF9ieShmdWxsYmFzZSkgfD4KICBtdXRhdGUocEggPSBuL3N1bShuKSkgfD4KICBnZ3Bsb3QoYWVzKHggPSBmdWxsYmFzZSwgeSA9IG4sIGZpbGwgPSBnaWEpKSArCiAgZ2VvbV9jb2woKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnQocEgsIGFjY3VyYWN5ID0gLjAxKSksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBzaXplID0gNCkgKwogIHlsYWIoJ0dpw6EgYsOhbiBuaMOgJykgKwogIHhsYWIoJ2Z1bGxiYXNlJykKYGBgCgpOaMOsbiDEkeG7kyB0aOG7iyB0YSB0aOG6pXk6CgotICAgVHJvbmcgc+G7kSBuaOG7r25nIG5nw7RpIG5ow6Aga2jDtG5nIGPDsyB04bqnbmcgaOG6p20gxJHGsOG7o2MgdHJhbmcgYuG7iyBob8OgbiB0aGnhu4duIHRow6wgY8OzIDMwLDQyJSBsw6AgbmjDoCDEkcaw4bujYyBiw6FuIHbhu5tpIG3hu6ljIGdpw6EgY2FvIHbDoCA2OSw1OCUgbMOgIG5ow6AgxJHGsOG7o2MgYsOhbiB24bubaSBt4bupYyBnacOhIHRo4bqlcC4KCi0gICBUcm9uZyBz4buRIG5o4buvbmcgbmfDtGkgbmjDoCBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiB0aMOsIGPDsyA0OCw2OSUgbMOgIG5ow6AgxJHGsOG7o2MgYsOhbiB24bubaSBt4bupYyBnacOhIGNhbyB2w6AgNTEsMzElIGzDoCBuaMOgIMSRxrDhu6NjIGLDoW4gduG7m2kgbeG7qWMgZ2nDoSB0aOG6pXAuCgojIyBN4buRaSBxdWFuIGjhu4cgZ2nhu69hIGJp4bq/biBmdWxsYmFzZSB2w6AgYmnhur9uIHJlY3JlYXRpb24KCi0gICBmdWxsYmFzZTogbmjDoCBjw7MgxJHGsOG7o2MgdHJhbmcgYuG7iyB04bqnbmcgaOG6p20gaG/DoG4gdGhp4buHbiBoYXkga2jDtG5nPyAoIHThuqduZyBo4bqnbSBob8OgbiB0aGnhu4duIGJhbyBn4buTbSBjw6FjIHBow7JuZyBuaMawIHBow7JuZyB04bqtcCB0aOG7gyBk4bulYywgdHLDsiBjaMahaSDEkWnhu4duIHThu60sIC4uLikKCi0gICByZWNyZWF0aW9uOiBuaMOgIGPDsyBwaMOybmcgZ2nhuqNpIHRyw60ga2jDtG5nPwoKIyMjIEzhuq1wIGLhuqNuZyB04bqnbiBz4buRCgpgYGB7cn0KYTQgPC0gdGFibGUoaCRmdWxsYmFzZSwgaCRyZWNyZWF0aW9uKQphZGRtYXJnaW5zKGE0KQpgYGAKCi0gICBDw7MgMzI5IG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgbmjDoCBraMO0bmcgxJHGsOG7o2MgdHJhbmcgYuG7iyB04bqnbmcgaOG6p20gaG/DoG4gdGhp4buHbiB2w6Aga2jDtG5nIGPDsyBwaMOybmcgZ2nhuqNpIHRyw60uCgotICAgQ8OzIDI2IG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgbmjDoCBraMO0bmcgxJHGsOG7o2MgdHJhbmcgYuG7iyB04bqnbmcgaOG6p20gaG/DoG4gdGhp4buHbiBuaMawbmcgY8OzIHBow7JuZyBnaeG6o2kgdHLDrS4KCi0gICBDw7MgMTIwIG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgbmjDoCDEkcaw4bujYyB0cmFuZyBi4buLIHThuqduZyBo4bqnbSBob8OgbiB0aGnhu4duIG5oxrBuZyBraMO0bmcgY8OzIHBow7JuZyBnaeG6o2kgdHLDrS4KCi0gICBDw7MgNzEgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBuaMOgIMSRxrDhu6NjIHRyYW5nIGLhu4sgdOG6p25nIGjhuqdtIGhvw6BuIHRoaeG7h24gdsOgIGPDsyBwaMOybmcgZ2nhuqNpIHRyw60uCgojIyMgUmVsUmlzaywgcmlza3JhdGlvLCBvZGRzcmF0aW8KCmBgYHtyfQpSZWxSaXNrKGE0KQpyaXNrcmF0aW8oYTQpCmBgYAoKLSAgIFThu7cgbOG7hyBuaOG7r25nIG5ow6Aga2jDtG5nIGPDsyB04bqnbmcgaOG6p20gxJHGsOG7o2MgdHJhbmcgYuG7iyBob8OgbiB0aGnhu4duIHbDoCBraMO0bmcgY8OzIHBow7JuZyBnaeG6o2kgdHLDrSBuaGnhu4F1IGjGoW4gNDcsNSUgdOG7tyBs4buHIG5o4buvbmcgbmjDoCBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiBuaMawbmcga2jDtG5nIGPDsyBwaMOybmcgZ2nhuqNpIHRyw60uCgotICAgVOG7tyBs4buHIG5o4buvbmcgbmjDoCBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiB2w6AgY8OzIHBow7JuZyBnaeG6o2kgdHLDrSBn4bqlcCA1IGzhuqduIHThu7cgbOG7hyBuaOG7r25nIG5ow6Aga2jDtG5nIGPDsyB04bqnbmcgaOG6p20gxJHGsOG7o2MgdHJhbmcgYuG7iyBob8OgbiB0aGnhu4duIG5oxrBuZyBjw7MgcGjDsm5nIGdp4bqjaSB0csOtLgoKYGBge3J9Cm9kZHNyYXRpbyhhNCkKYGBgCgotICAgVOG7tyBs4buHIG5o4buvbmcgbmjDoCBjw7MgcGjDsm5nIGdp4bqjaSB0csOtIHRyw6puIG5o4buvbmcgbmjDoCBraMO0bmcgY8OzIHBow7JuZyBnaeG6o2kgdHLDrSB0cm9uZyBz4buRIG5o4buvbmcgbmjDoCBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gZ+G6pXAgNyw0IGzhuqduIHNvIHbhu5tpIHThu7cgbOG7hyBuaOG7r25nIG5ow6AgY8OzIHBow7JuZyBnaeG6o2kgdHLDrSB0csOqbiBuaOG7r25nIG5ow6Aga2jDtG5nIGPDsyBwaMOybmcgZ2nhuqNpIHRyw60gdHJvbmcgc+G7kSBuaOG7r25nIG5ow6AgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24uCgojIyMgxJDhu5MgdGjhu4sKCmBgYHtyfQpoIHw+IGNvdW50KGZ1bGxiYXNlLCByZWNyZWF0aW9uKSB8PgogIGdyb3VwX2J5KGZ1bGxiYXNlKSB8PgogIG11dGF0ZShwSCA9IG4vc3VtKG4pKSB8PgogIGdncGxvdChhZXMoeCA9IGZ1bGxiYXNlLCB5ID0gbiwgZmlsbCA9IHJlY3JlYXRpb24pKSArCiAgZ2VvbV9jb2woKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnQocEgsIGFjY3VyYWN5ID0gLjAxKSksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBzaXplID0gNCkgKwogIHlsYWIoJ3JlY3JlYXRpb24nKSArCiAgeGxhYignZnVsbGJhc2UnKQpgYGAKCk5ow6xuIMSR4buTIHRo4buLIHRhIHRo4bqleToKCi0gICBUcm9uZyBz4buRIG5o4buvbmcgbmjDoCBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gdGjDrCBjw7MgNywzMiUgbMOgIGPDsyBwaMOybmcgZ2nhuqNpIHRyw60gdsOgIDkyLDY4JSBsw6Aga2jDtG5nIGPDsyBwaMOybmcgZ2nhuqNpIHRyw60uCgotICAgVHJvbmcgc+G7kSBuaOG7r25nIG5ow6AgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gdGjDrCBjw7MgMzcsMTclIGzDoCBjw7MgcGjDsm5nIGdp4bqjaSB0csOtIHbDoCA2Miw4MyUgbMOgIGtow7RuZyBjw7MgcGjDsm5nIGdp4bqjaSB0csOtLgoKIyMgTeG7kWkgbGnDqm4gaOG7hyBnaeG7r2EgYmnhur9uIGZ1bGxiYXNlIHbDoCBsb3RzaXplCgotICAgZnVsbGJhc2U6IG5ow6AgY8OzIMSRxrDhu6NjIHRyYW5nIGLhu4sgdOG6p25nIGjhuqdtIGhvw6BuIHRoaeG7h24gaGF5IGtow7RuZz8gKCB04bqnbmcgaOG6p20gaG/DoG4gdGhp4buHbiBiYW8gZ+G7k20gY8OhYyBwaMOybmcgbmjGsCBwaMOybmcgdOG6rXAgdGjhu4MgZOG7pWMsIHRyw7IgY2jGoWkgxJFp4buHbiB04butLCAuLi4pCgotICAgbG90c2l6ZTogZGnhu4duIHTDrWNoIGPEg24gbmjDoAoKIyMjIEzhuq1wIGLhuqNuZyB04bqnbiBz4buRCgpgYGB7cn0KaCRzaXplIDwtIGN1dChoJGxvdHNpemUsIGJyZWFrcyA9IGMoMCw1NTAwLDE2MzAwKSwgbGFiZWxzID0gYygnU21hbGwnLCdCaWcnKSApCnRhYmxlKGgkc2l6ZSkKYGBgCgpUw7RpIGNoaWEgYmnhur9uIGxvdHNpemUgKGRp4buHbiB0w61jaCBjxINuIG5ow6ApIHRow6BuaCAyIHBo4bqnbiBCaWcgKGzhu5tuKSB2w6AgU21hbGwgKG5o4buPKS4gVGjDrCB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgY8OzIDM0MyBjw7MgZGnhu4duIHTDrWNoIG5o4buPIHbDoCAyMDMgY8SDbiBuaMOgIGPDsyBkaeG7h24gdGljaCBs4bubbi4KCmBgYHtyfQphNSA8LSB0YWJsZShoJGZ1bGxiYXNlLCBoJHNpemUpCmFkZG1hcmdpbnMoYTUpCmBgYAoKLSAgIEPDsyAyMzQgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBuaMOgIGPDsyBkaeG7h24gdMOtY2ggbmjhu48gdsOgIGtow7RuZyBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbi4KCi0gICBDw7MgMTIxIG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgbmjDoCBjw7MgZGnhu4duIHTDrWNoIGzhu5tuIG5oxrBuZyBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24uCgotICAgQ8OzIDEwOSBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgY8OzIG5ow6AgY8OzIGRp4buHbiB0w61jaCBuaOG7jyBuaMawbmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24uCgotICAgQ8OzIDgyIG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgbmjDoCBjw7MgZGnhu4duIHTDrWNoIGzhu5tuIHbDoCBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbi4KCiMjIyBSZWxSaXNrLCByaXNrcmF0aW8sIG9kZHNyYXRpbwoKYGBge3J9ClJlbFJpc2soYTUpCnJpc2tyYXRpbyhhNSkKYGBgCgotICAgVOG7tyBs4buHIG5o4buvbmcgbmfGsOG7nWkgY8OzIG5ow6AgY8OzIGRp4buHbiB0w61jaCBuaOG7jyBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gbmhp4buBdSBoxqFuIDE1LDUlIHNvIHbhu5tpIHThu7cgbOG7hyBuaOG7r25nIG5nxrDhu51pIGPDsyBuaMOgIGPDsyBkaeG7h24gdMOtY2ggbmjhu48gbmjGsG5nIGPDsyB04bqnbmcgaOG6p20gxJHGsOG7o2MgdHJhbmcgYuG7iyBob8OgbiB0aGnhu4duLgoKLSAgIFThu7cgbOG7hyBuaOG7r25nIG5nxrDhu51pIGPDsyBuaMOgIGPDsyBkaeG7h24gdMOtY2ggbOG7m24gY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gbmhp4buBdSBoxqFuIDI1LDk2JSBzbyB24bubaSB04bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjw7MgbmjDoCBjw7MgZGnhu4duIHTDrWNoIGzhu5tuIG5oxrBuZyBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24uCgpgYGB7cn0Kb2Rkc3JhdGlvKGE1KQpgYGAKCi0gICBU4bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjw7MgbmjDoCBkaeG7h24gdMOtY2ggbMahbiB0csOqbiBuaOG7r25nIG5ow6AgZGnhu4duIHTDrWNoIG5o4buPIHRyb25nIHPhu5Egbmjhu69uZyBuZ8O0aSBuaMOgIGtow7RuZyBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiBuaGnhu4F1IGjGoW4gNDUsNCUgc28gduG7m2kgdOG7tyBs4buHIG5o4buvbmcgbmfGsOG7nWkgY8OzIG5ow6AgZGnhu4duIHTDrWNoIGzhu5tuIHRyw6puIG5o4buvbmcgbmjDoCBkaeG7h24gdMOtY2ggbmjhu48gdHJvbmcgc+G7kSBuaOG7r25nIG5nw7RpIG5ow6AgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24uCgojIyMgxJDhu5MgdGjhu4sKCmBgYHtyfQpoIHw+IGNvdW50KGZ1bGxiYXNlLCBzaXplKSB8PgogIGdyb3VwX2J5KGZ1bGxiYXNlKSB8PgogIG11dGF0ZShwSCA9IG4vc3VtKG4pKSB8PgogIGdncGxvdChhZXMoeCA9IGZ1bGxiYXNlLCB5ID0gbiwgZmlsbCA9IHNpemUpKSArCiAgZ2VvbV9jb2woKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnQocEgsIGFjY3VyYWN5ID0gLjAxKSksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBzaXplID0gNCkgKwogIHlsYWIoJ3NpemUnKSArCiAgeGxhYignZnVsbGJhc2UnKQpgYGAKCk5ow6xuIMSR4buTIHRo4buLIHRhIHRo4bqleToKCi0gICBUcm9uZyBz4buRIG5o4buvbmcgbmfDtGkgbmjDoCBraMO0bmcgY8OzIHThuqduZyBo4bqnbSDEkcaw4bujYyB0cmFuZyBi4buLIGhvw6BuIHRoaeG7h24gdGjDrCBjw7MgMzQsMDglIGzDoCBuaMOgIGPDsyBkaeG7h24gdGljaCBs4bubbiB2w6AgNjUsOTIlIGzDoCBuaMOgIGPDsyBkaeG7h24gdGljaCBuaOG7jy4KCi0gICBUcm9uZyBz4buRIG5o4buvbmcgbmfDtGkgbmjDoCBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiB0aMOsIGPDsyA0Miw5MyUgbMOgIG5ow6AgY8OzIGRp4buHbiB0aWNoIGzhu5tuIHbDoCA1NywwNyUgbMOgIG5ow6AgY8OzIGRp4buHbiB0aWNoIG5o4buPLgoKIyMgTeG7kWkgbGnDqm4gaOG7hyBnaeG7r2EgYmnhur9uIGJlZHJvb21zIHbDoCBzaXplCgotICAgYmVkcm9vbXM6IHPhu5EgcGjDsm5nIG5n4bunCgotICAgc2l6ZTogZGnhu4duIHTDrWNoIGPEg24gbmjDoAoKIyMjIEzhuq1wIGLhuqNuZyB04bqnbiBz4buRCgpgYGB7cn0KaCRuZ3UgPC0gY3V0KCBoJGJlZHJvb21zLCBicmVha3MgPSBjKDAsMiw3KSwgbGFiZWxzID0gYygnw610JywgJ25oaeG7gXUnKSkKdGFibGUoaCRuZ3UpCmBgYAoKLSAgIFTDtGkgY2hpYSBiaeG6v24gYmVkcm9vbXMgdGjDoG5oIDIgcGjhuqduIMOtdCB2w6Agbmhp4buBdS4gVHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyAxMzggbmfGsOG7nWkgbmjDoCBjw7Mgw610IHBow7JuZyBuZ+G7pyB2w6AgNDA4IG5nxrDhu51pIG5ow6AgY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunLgoKYGBge3J9CmE2IDwtIHRhYmxlKGgkbmd1LCBoJHNpemUpCmFkZG1hcmdpbnMoYTYpCmBgYAoKLSAgIEPDsyAxMDQgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBkaeG7h24gdMOtY2ggbmjDoCBuaOG7jyBjw7Mgw610IHBow7JuZyBuZ+G7py4KCi0gICBDw7MgMzQgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBkaeG7h24gdMOtY2ggbmjDoCBs4bubbiBjw7Mgw610IHBow7JuZyBuZ+G7py4KCi0gICBDw7MgMjM5IG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgZGnhu4duIHTDrWNoIG5ow6Agbmjhu48gY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunIC4KCi0gICBDw7MgMTY5IG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgZGnhu4duIHTDrWNoIG5ow6AgbOG7m24gY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunLgoKIyMjIFJlbFJpc2ssIHJpc2tyYXRpbywgb2Rkc3JhdGlvCgpgYGB7cn0KUmVsUmlzayhhNikKcmlza3JhdGlvKGE2KQpgYGAKCi0gICBU4bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjw7MgbmjDoCBkaeG7h24gdMOtY2ggbmjhu48gY8OzIMOtdCBwaMOybmcgbmfhu6cgbmhp4buBdSBoxqFuIDI4LDY1JSBzbyB24bubaSB04bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjw7MgbmjDoCBkaeG7h24gdMOtY2ggbmjhu48gY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunLgoKLSAgIFThu7cgbOG7hyBuaOG7r25nIG5nxrDhu51pIGPDsyBuaMOgIGRp4buHbiB0w61jaCBs4bubbiBjw7Mgbmhp4buBdSBwaMOybmcgbmfhu6cgbmhp4buBdSBoxqFuIDY4LDEyJSBzbyB24bubaSB04bu3IGzhu4cgbmjhu69uZyBuZ8aw4budaSBjw7MgbmjDoCBkaeG7h24gdMOtY2ggbOG7m24gY8OzIMOtdCBwaMOybmcgbmfhu6cuCgpgYGB7cn0Kb2Rkc3JhdGlvKGE2KQpgYGAKCi0gICBU4bu3IGzhu4cgbmjhu69uZyBuZ8O0aSBuaMOgIGRp4buHbiB0w61jaCBs4bubbiB0csOqbiBuaOG7r25nIG5nw7RpIG5ow6AgZGnhu4duIHTDrWNoIG5o4buPIHRyb25nIHPhu5Egbmjhu69uZyBuZ8O0aSBuaMOgIGPDsyDDrXQgcGjDsm5nIG5n4bunIGNhbyBn4bqlcCAyLDE1IGzhuqduIHThu7cgbOG7hyBuaOG7r25nIG5nw7RpIG5ow6AgZGnhu4duIHTDrWNoIGzhu5tuIHRyw6puIG5o4buvbmcgbmfDtGkgbmjDoCBkaeG7h24gdMOtY2ggbmjhu48gdHJvbmcgc+G7kSBuaOG7r25nIG5nw7RpIG5ow6AgY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunLgoKIyMjIMSQ4buTIHRo4buLCgpgYGB7cn0KaCB8PiBjb3VudChuZ3UsIHNpemUpIHw+CiAgZ3JvdXBfYnkobmd1KSB8PgogIG11dGF0ZShwSCA9IG4vc3VtKG4pKSB8PgogIGdncGxvdChhZXMoeCA9IG5ndSwgeSA9IG4sIGZpbGwgPSBzaXplKSkgKwogIGdlb21fY29sKCkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50KHBILCBhY2N1cmFjeSA9IC4wMSkpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgc2l6ZSA9IDQpICsKICB5bGFiKCdEaeG7h24gdMOtY2ggbmfDtGkgbmjDoCcpICsKICB4bGFiKCdT4buRIHBow7JuZyBuZ+G7pycpCmBgYAoKTmjDrG4gxJHhu5MgdGjhu4sgdGEgdGjhuqV5OgoKLSAgIFRyb25nIHPhu5Egbmjhu69uZyBuZ8O0aSBuaMOgIGPDsyDDrXQgcGjDsm5nIG5n4bunIHRow6wgY8OzIDI0LDY0JSBsw6Agbmjhu69uZyBuZ8O0aSBuaMOgIGPDsyBkaeG7h24gdMOtY2ggbOG7m24gdsOgIDc1LDM2JSBsw6Agbmjhu69uZyBuZ8O0aSBuaMOgIGPDsyBkaeG7h24gdMOtY2ggbmjhu48uCgotICAgVHJvbmcgc+G7kSBuaOG7r25nIG5nw7RpIG5ow6AgY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunIHRow6wgY8OzIDQxLDQyJSBsw6Agbmjhu69uZyBuZ8O0aSBuaMOgIGPDsyBkaeG7h24gdMOtY2ggbOG7m24gdsOgIDU4LDU4JSBsw6Agbmjhu69uZyBuZ8O0aSBuaMOgIGPDsyBkaeG7h24gdMOtY2ggbmjhu48uCgojIyBN4buRaSBsacOqbiBo4buHIGdp4buvYSBiaeG6v24gYmVkcm9vbXMgdsOgIHByaWNlCgotICAgcHJpY2U6IGdpw6EgYsOhbiBuaMOgCgotICAgYmVkcm9vbXM6IHPhu5EgcGjDsm5nIG5n4bunCgojIyMgTOG6rXAgYuG6o25nIHThuqduIHPhu5EKCmBgYHtyfQpoJGdpYSA8LSBjdXQoIGgkcHJpY2UsIGJyZWFrcyA9IGMoMCw3MDAwMCwxOTEwMDApLCBsYWJlbHMgPSBjKCd0aOG6pXAnLCAnY2FvJykpCnRhYmxlKGgkZ2lhKQpgYGAKCi0gICBUw7RpIGNoaWEgYmnhur9uIHByaWNlIChnacOhIGLDoW4gbmjDoCkgdGjDoG5oIDIgcGjhuqduIGNhbyB2w6AgdGjhuqVwLiBUcm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgY8OzIDM0NSBuZ8aw4budaSBiw6FuIG5ow6AgduG7m2kgbeG7qWMgZ2nDoSB0aOG6pXAgdsOgIDIwMSBuZ8aw4budaSBiw6FuIG5ow6AgduG7m2kgbeG7qWMgZ2nDoSBjYW8uCgpgYGB7cn0KYTcgPC0gdGFibGUoaCRuZ3UsIGgkZ2lhKQphZGRtYXJnaW5zKGE3KQpgYGAKCi0gICBDw7MgMTI3IG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7Mgw610IHBow7JuZyBuZ+G7pyBjw7MgbeG7qWMgZ2nDoSBiw6FuIHRo4bqlcC4KCi0gICBDw7MgMTExIG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7Mgw610IHBow7JuZyBuZ+G7pyBjw7MgbeG7qWMgZ2nDoSBiw6FuIGNhby4KCi0gICBDw7MgMjE4IG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7Mgbmhp4buBdSBwaMOybmcgbmfhu6cgY8OzIG3hu6ljIGdpw6EgYsOhbiB0aOG6pXAuCgotICAgQ8OzIDE5MCBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunIGPDsyBt4bupYyBnacOhIGLDoW4gY2FvLgoKIyMjIFJlbFJpc2ssIHJpc2tyYXRpbywgb2Rkc3JhdGlvCgpgYGB7cn0KUmVsUmlzayhhNykKcmlza3JhdGlvKGE3KQpgYGAKCi0gICBU4bu3IGzhu4cgbmjhu69uZyBuaMOgIGPDsyDDrXQgcGjDsm5nIG5n4bunIMSRxrDhu6NjIGLDoW4gduG7m2kgbeG7qWMgZ2nDoSB0aOG6pXAgbmhp4buBdSBoxqFuIDcyLDI0JSUgc28gduG7m2kgdOG7tyBs4buHIG5o4buvbmcgbmjDoCBjw7Mgbmhp4buBdSBwaMOybmcgbmfhu6cgxJHGsOG7o2MgYsOhbiB24bubaSBt4bupYyBnacOhIHRo4bqlcC4KCi0gICBU4bu3IGzhu4cgbmjhu69uZyBuaMOgIGPDsyBuaGnhu4F1IHBow7JuZyBuZ+G7pyDEkcaw4bujYyBiw6FuIHbhu5tpIG3hu6ljIGdpw6EgY2FvIGNhbyBn4bqlcCA1LDg0IGzhuqduIHNvIHbhu5tpIHThu7cgbOG7hyBuaOG7r25nIG5ow6AgY8OzIMOtdCBwaMOybmcgbmfhu6cgxJHGsOG7o2MgYsOhbiB24bubaSBt4bupYyBnacOhIGNhby4KCmBgYHtyfQpvZGRzcmF0aW8oYTcpCmBgYAoKLSAgIFThu7cgbOG7hyBuaOG7r25nIG5nw7RpIG5ow6AgY8OzIGdpw6EgYsOhbiBjYW8gdHLDqm4gbmjhu69uZyBuZ8O0aSBuaMOgIGPDsyBnacOhIGLDoW4gdGjhuqVwIHRyb25nIHPhu5Egbmjhu69uZyBuZ8O0aSBuaMOgIGPDsyDDrXQgcGjDsm5nIG5n4bunIGNhbyBn4bqlcCA5LDkgbOG6p24gdOG7tyBs4buHIG5o4buvbmcgbmfDtGkgbmjDoCBjw7MgZ2nDoSBiw6FuIGNhbyB0csOqbiBuaOG7r25nIG5nw7RpIG5ow6AgY8OzIGdpw6EgYsOhbiB0aOG6pXAgdHJvbmcgc+G7kSBuaOG7r25nIG5nw7RpIG5ow6AgY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunLgoKIyMjIMSQ4buTIHRo4buLCgpgYGB7cn0KaCB8PiBjb3VudChuZ3UsIGdpYSkgfD4KICBncm91cF9ieShuZ3UpIHw+CiAgbXV0YXRlKHBIID0gbi9zdW0obikpIHw+CiAgZ2dwbG90KGFlcyh4ID0gbmd1LCB5ID0gbiwgZmlsbCA9IGdpYSkpICsKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChwSCwgYWNjdXJhY3kgPSAuMDEpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemUgPSA0KSArCiAgeWxhYignR2nDoSBiw6FuIG5ow6AnKSArCiAgeGxhYignU+G7kSBwaMOybmcgbmfhu6cnKQpgYGAKCk5ow6xuIMSR4buTIHRo4buLIHRhIHRo4bqleToKCi0gICBUcm9uZyBz4buRIG5o4buvbmcgbmfDtGkgbmjDoCBjw7Mgw610IHBow7JuZyBuZ+G7pyB0aMOsIGPDsyA3LDk3JSBsw6AgbmjDoCBjw7MgbeG7qWMgZ2nDoSBiw6FuIGNhbywgOTIsMDMlIGzDoCBuaMOgIGPDsyBt4bupYyBnacOhIGLDoW4gdGjhuqVwLgoKLSAgIFRyb25nIHPhu5Egbmjhu69uZyBuZ8O0aSBuaMOgIGPDsyBuaGnhu4F1IHBow7JuZyBuZ+G7pyB0aMOsIGPDsyA0Niw1NyUgbMOgIG5ow6AgY8OzIG3hu6ljIGdpw6EgYsOhbiBjYW8sIDUzLDQzJSBsw6AgbmjDoCBjw7MgbeG7qWMgZ2nDoSBiw6FuIHRo4bqlcC4KCiMjIE3hu5FpIGxpw6puIGjhu4cgZ2nhu69hIGJp4bq/biBiZWRyb29tcyB2w6AgYmnhur9uIHByZWZlcgoKLSAgIHByZWZlcjogbmjDoCBjw7MgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRIGtow7RuZwoKLSAgIGJlZHJvb21zOiBz4buRIHBow7JuZyBuZ+G7pwoKYGBge3J9CmE4IDwtIHRhYmxlKGgkbmd1LCBoJHByZWZlcikKYWRkbWFyZ2lucyhhOCkKYGBgCgotICAgQ8OzIDEyMiBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgbmjDoCBjw7Mgw610IHBow7JuZyBuZ+G7pyBraMO0bmcgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRLgoKLSAgIEPDsyAyOTYgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IG5ow6AgY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunIGtow7RuZyBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EuCgotICAgQ8OzIDE2IG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBuaMOgIGPDsyDDrXQgcGjDsm5nIG5n4bunIGtow7RuZyBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EuCgotICAgQ8OzIDExMiBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgbmjDoCBjw7Mgbmhp4buBdSBwaMOybmcgbmfhu6cgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRLgoKIyMjIFJlbFJpc2ssIHJpc2tyYXRpbywgb2Rkc3JhdGlvCgpgYGB7cn0KUmVsUmlzayhhOCkKcmlza3JhdGlvKGE4KQpgYGAKCi0gICBU4bu3IGzhu4cgbmjDoCBjw7Mgw610IHBow7JuZyBuZ+G7pyBraMO0bmcgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRIG5oaeG7gXUgaMahbiAyMSw4NiUgc28gduG7m2kgdOG7tyBs4buHIG5ow6AgY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunIG7hurFtIHRyb25nIGtodSB24buxYyB0cnVuZyB0w6JtIHRow6BuaCBwaOG7kS4KCi0gICBU4bu3IGzhu4cgbmjDoCBjw7Mgbmhp4buBdSBwaMOybmcgbmfhu6cgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRIGfhuqVwIDIsMzcgbOG6p24gc28gduG7m2kgdOG7tyBs4buHIG5ow6AgY8OzIMOtdCBwaMOybmcgbmfhu6cgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRLgoKYGBge3J9Cm9kZHNyYXRpbyhhOCkKYGBgCgotICAgVOG7tyBs4buHIG5o4buvbmcgbmjDoCBraMO0bmcgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRIHRyw6puIG5o4buvbmcgbmjDoCBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EgdHJvbmcgc+G7kSBuaOG7r25nIG5nw7RpIG5ow6AgxJHGsOG7o2MgYsOhbiBjw7Mgw610IHBow7JuZyBuZ+G7pyBi4bqxbmcgMiw4NiBs4bqnbiB04bu3IGzhu4cgbmjhu69uZyBuaMOgIGtow7RuZyBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EgdHLDqm4gbmjhu69uZyBuaMOgIG7hurFtIHRyb25nIGtodSB24buxYyB0cnVuZyB0w6JtIHRow6BuaCBwaOG7kSB0cm9uZyBz4buRIG5o4buvbmcgbmfDtGkgbmjDoCDEkcaw4bujYyBiw6FuIGPDsyBuaGnhu4F1IHBow7JuZyBuZ+G7py4KCiMjIyDEkOG7kyB0aOG7iwoKYGBge3J9CmggfD4gY291bnQobmd1LCBwcmVmZXIpIHw+CiAgZ3JvdXBfYnkobmd1KSB8PgogIG11dGF0ZShwSCA9IG4vc3VtKG4pKSB8PgogIGdncGxvdChhZXMoeCA9IG5ndSwgeSA9IG4sIGZpbGwgPSBwcmVmZXIpKSArCiAgZ2VvbV9jb2woKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnQocEgsIGFjY3VyYWN5ID0gLjAxKSksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBzaXplID0gNCkgKwogIHlsYWIoJ1bhu4sgdHLDrSBuaMOgJykgKwogIHhsYWIoJ1Phu5EgcGjDsm5nIG5n4bunJykKYGBgCgpOaMOsbiDEkeG7kyB0aOG7iyB0YSB0aOG6pXk6CgotICAgVHJvbmcgc+G7kSBuaOG7r25nIG5nw7RpIG5ow6AgY8OzIMOtdCBwaMOybmcgbmfhu6cgdGjDrCBjw7MgMTEsNTklIGzDoCBuaMOgIG7hurFtIHRyb25nIGtodSB24buxYyB0cnVuZyB0w6JtIHRow6BuaCBwaOG7kSB2w6AgODgsNDElIGzDoCBuaMOgIGtow7RuZyBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EuCgotICAgVHJvbmcgc+G7kSBuaOG7r25nIG5nw7RpIG5ow6AgY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunIHRow6wgY8OzIDI3LDQ1JSBsw6AgbmjDoCBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EgdsOgIDcyLDU1JSBsw6AgbmjDoCBraMO0bmcgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRLgoKIyMgTeG7kWkgbGnDqm4gaOG7hyBnaeG7r2EgYmnhur9uIGJlZHJvb21zIHbDoCBiaeG6v24gc3RvcmllcwoKLSAgIHN0b3JpZXM6IHPhu5EgdOG6p25nIGtow7RuZyB0w61uaCB04bqnbmcgaOG6p20KCi0gICBiZWRyb29tczogc+G7kSBwaMOybmcgbmfhu6cKCiMjIyBC4bqjbmcgdOG6p24gc+G7kQoKYGBge3J9CmgkdGFuZyA8LSBjdXQoaCRzdG9yaWVzLCBicmVha3MgPSBjKDAsMSw0LjEpLCBsYWJlbHMgPSBjKCfDrXQnLCAnbmhp4buBdScpKQp0YWJsZShoJHRhbmcpCmBgYAoKLSAgIFRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgMjI3IG5nxrDhu51pIGPDsyBuaMOgIGPDsyDDrXQgdOG6p25nIHbDoCAzMTkgbmfGsOG7nWkgY8OzIG5ow6AgY8OzIG5oaeG7gXUgdOG6p25nLgoKYGBge3J9CmE5IDwtIHRhYmxlKGgkbmd1LCBoJHRhbmcpCmFkZG1hcmdpbnMoYTkpCmBgYAoKLSAgIEPDsyAxMTcgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBuaMOgIGPDsyDDrXQgdOG6p25nIGPDsyDDrXQgcGjDsm5nIG5n4bunLgoKLSAgIEPDsyAyMSBuZ8aw4budaSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgY8OzIG5ow6AgY8OzIG5oaeG7gXUgdOG6p25nIGPDsyDDrXQgcGjDsm5nIG5n4bunLgoKLSAgIEPDsyAxMTAgbmfGsOG7nWkgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IGPDsyBuaMOgIGPDsyDDrXQgdOG6p25nIGPDsyBuaGnhu4F1IHBow7JuZyBuZ+G7py4KCi0gICBDw7MgMjk4IG5nxrDhu51pIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBjw7MgbmjDoCBjw7Mgbmhp4buBdSB04bqnbmcgY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunLgoKIyMjIFJlbFJpc2ssIHJpc2tyYXRpbywgb2Rkc3JhdGlvCgpgYGB7cn0KUmVsUmlzayhhOSkKcmlza3JhdGlvKGE5KQpgYGAKCi0gICBU4bu3IGzhu4cgbmfGsOG7nWkgY8OzIG5ow6Agw610IHThuqduZyBjw7Mgw610IHBow7JuZyBuZ+G7pyBjYW8gZ+G6pXAgMywxNCBs4bqnbiBzbyB24bubaSB04bu3IGzhu4cgbmfGsOG7nWkgY8OzIG5ow6AgY8OzIMOtdCB04bqnbmcgY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunLgoKLSAgIFThu7cgbOG7hyBuZ8aw4budaSBjw7MgbmjDoCBjw7Mgbmhp4buBdSB04bqnbmcgY8OzIG5oaeG7gXUgcGjDsm5nIG5n4bunIGNhbyBn4bqlcCA0LDggbOG6p24gc28gduG7m2kgdOG7tyBs4buHIG5nxrDhu51pIGPDsyBuaMOgIGPDsyBuaGnhu4F1IHThuqduZyBjw7Mgw610IHBow7JuZyBuZ+G7py4KCmBgYHtyfQpvZGRzcmF0aW8oYTkpCmBgYAoKLSAgIFThu7cgbOG7hyBuZ8aw4budaSBjw7MgbmjDoCBjw7Mgbmhp4buBdSB04bqnbmcgdHLDqm4gbmfGsOG7nWkgY8OzIG5ow6AgY8OzIMOtdCB04bqnbmcgdHJvbmcgc+G7kSBuaOG7r25nIG5nxrDhu51pIGPDsyDDrXQgcGjDsm5nIG5n4bunIGLhurFuZyAxNCw3IGzhuqduIHThu7cgbOG7hyBuZ8aw4budaSBjw7MgbmjDoCBjw7Mgbmhp4buBdSB04bqnbmcgdHLDqm4gbmfGsOG7nWkgY8OzIG5ow6AgY8OzIMOtdCB04bqnbmcgdHJvbmcgc+G7kSBuaOG7r25nIG5nxrDhu51pIGPDsyBuaGnhu4F1IHBow7JuZyBuZ+G7py4KCiMjIyDEkOG7kyB0aOG7iwoKYGBge3J9CmggfD4gY291bnQobmd1LCB0YW5nKSB8PgogIGdyb3VwX2J5KG5ndSkgfD4KICBtdXRhdGUocEggPSBuL3N1bShuKSkgfD4KICBnZ3Bsb3QoYWVzKHggPSBuZ3UsIHkgPSBuLCBmaWxsID0gdGFuZykpICsKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudChwSCwgYWNjdXJhY3kgPSAuMDEpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemUgPSA0KSArCiAgeWxhYignU+G7kSB04bqnbmcnKSArCiAgeGxhYignU+G7kSBwaMOybmcgbmfhu6cnKQpgYGAKCi0gICBUcm9uZyBz4buRIG5o4buvbmcgbmfDtGkgbmjDoCBjw7Mgw610IHBow7JuZyBuZ+G7pyBjw7MgMTUsMjIlIGzDoCBuaMOgIGPDsyBuaGnhu4F1IHThuqduZyB2w6AgODQsNzglIGzDoCBuaMOgIGPDsyDDrXQgdOG6p25nLgoKLSAgIFRyb25nIHPhu5Egbmjhu69uZyBuZ8O0aSBuaMOgIGPDsyBuaGnhu4F1IHBow7JuZyBuZ+G7pyBjw7MgNzMsMDQlIGzDoCBuaMOgIGPDsyBuaGnhu4F1IHThuqduZyB2w6AgMjYsOTYlIGzDoCBuaMOgIGPDsyDDrXQgdOG6p25nLgoKIyBLaeG7g20gxJHhu4tuaCBjaGkgYsOsbmggcGjGsMahbmcKCiMjIEdp4buvYSAyIGJp4bq/biBmdWxsYmFzZSB2w6AgYmnhur9uIHByZWZlcgoKLSAgIGZ1bGxiYXNlOiBuaMOgIGPDsyDEkcaw4bujYyB0cmFuZyBi4buLIHThuqduZyBo4bqnbSBob8OgbiB0aGnhu4duIGhheSBraMO0bmc/ICggdOG6p25nIGjhuqdtIGhvw6BuIHRoaeG7h24gYmFvIGfhu5NtIGPDoWMgcGjDsm5nIG5oxrAgcGjDsm5nIHThuq1wIHRo4buDIGThu6VjLCB0csOyIGNoxqFpIMSRaeG7h24gdOG7rSwgLi4uKQoKLSAgIHByZWZlcjogbmjDoCBjw7MgbuG6sW0gdHJvbmcga2h1IHbhu7FjIHRydW5nIHTDom0gdGjDoG5oIHBo4buRIGtow7RuZz8KCsSQ4bq3dCBnaeG6oyB0aGnhur90OgoKSDA6IEhhaSBiaeG6v24gxJHhu5ljIGzhuq1wCgpIMTogSGFpIGJp4bq/biBraMO0bmcgxJHhu5ljIGzhuq1wCgpgYGB7cn0KY2hpc3EudGVzdChhMSkKYGBgCgpL4bq/dCBxdeG6oyBuw6B5IGNobyBjaMO6bmcgdGEgdGjhuqV5IHLhurFuZyBwLXZhbHVlIFw8IDAuMDUuIMSRw6J5IGPFqW5nIGzDoCBi4bqxbmcgY2jhu6luZyDEkeG7gyB0YSBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSDAuIFbhuq15IDIgYmnhur9uIGZ1bGxiYXNlIHbDoCBwcmVmZXIgbMOgIGhhaSBiaeG6v24ga2jDtG5nIMSR4buZYyBs4bqtcCB24bubaSBuaGF1LgoKIyMgR2nhu69hIDIgYmnhur9uIGZ1bGxiYXNlIHbDoCBkcml2ZXdheQoKLSAgIGZ1bGxiYXNlOiBuaMOgIGPDsyDEkcaw4bujYyB0cmFuZyBi4buLIHThuqduZyBo4bqnbSBob8OgbiB0aGnhu4duIGhheSBraMO0bmc/ICggdOG6p25nIGjhuqdtIGhvw6BuIHRoaeG7h24gYmFvIGfhu5NtIGPDoWMgcGjDsm5nIG5oxrAgcGjDsm5nIHThuq1wIHRo4buDIGThu6VjLCB0csOyIGNoxqFpIMSRaeG7h24gdOG7rSwgLi4uKQoKLSAgIGRyaXZld2F5OiBuaMOgIGPDsyBraHUgduG7sWMgxJHhuq11IHhlIHJpw6puZyBraMO0bmc/CgrEkOG6t3QgZ2nhuqMgdGhp4bq/dDoKCkgwOiBIYWkgYmnhur9uIMSR4buZYyBs4bqtcAoKSDE6IEhhaSBiaeG6v24ga2jDtG5nIMSR4buZYyBs4bqtcAoKYGBge3J9CmNoaXNxLnRlc3QoYTIpCmBgYAoKS+G6v3QgcXXhuqMgbsOgeSBjaG8gY2jDum5nIHRhIHRo4bqleSBy4bqxbmcgcC12YWx1ZSA9IDAsMzc1NyBcPiAwLjA1LiBDaOG6pXAgbmjhuq1uIGdp4bqjIHRoaeG6v3QgSDAuIFbhuq15IDIgYmnhur9uIGZ1bGxiYXNlIHbDoCBkcml2ZXdheSBsw6AgaGFpIGJp4bq/biDEkeG7mWMgbOG6rXAgduG7m2kgbmhhdS4KCiMjIEdp4buvYSAyIGJp4bq/biBmdWxsYmFzZSB2w6AgcHJpY2UKCi0gICBmdWxsYmFzZTogbmjDoCBjw7MgxJHGsOG7o2MgdHJhbmcgYuG7iyB04bqnbmcgaOG6p20gaG/DoG4gdGhp4buHbiBoYXkga2jDtG5nPyAoIHThuqduZyBo4bqnbSBob8OgbiB0aGnhu4duIGJhbyBn4buTbSBjw6FjIHBow7JuZyBuaMawIHBow7JuZyB04bqtcCB0aOG7gyBk4bulYywgdHLDsiBjaMahaSDEkWnhu4duIHThu60sIC4uLikKCi0gICBwcmljZTogZ2nDoSBiw6FuIG5ow6AKCsSQ4bq3dCBnaeG6oyB0aGnhur90OgoKSDA6IEhhaSBiaeG6v24gxJHhu5ljIGzhuq1wCgpIMTogSGFpIGJp4bq/biBraMO0bmcgxJHhu5ljIGzhuq1wCgpgYGB7cn0KY2hpc3EudGVzdChhMykKYGBgCgpL4bq/dCBxdeG6oyBuw6B5IGNobyBjaMO6bmcgdGEgdGjhuqV5IHLhurFuZyBwLXZhbHVlIFw8IDAuMDUuIMSQw6J5IGPFqW5nIGzDoCBi4bqxbmcgY2jhu6luZyDEkeG7gyB0YSBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSDAuIFbhuq15IDIgYmnhur9uIGZ1bGxiYXNlIHbDoCBnaWEgbMOgIGhhaSBiaeG6v24ga2jDtG5nIMSR4buZYyBs4bqtcCB24bubaSBuaGF1LgoKIyMgR2nhu69hIDIgYmnhur9uIGZ1bGxiYXNlIHbDoCByZWNyZWF0aW9uCgotICAgZnVsbGJhc2U6IG5ow6AgY8OzIMSRxrDhu6NjIHRyYW5nIGLhu4sgdOG6p25nIGjhuqdtIGhvw6BuIHRoaeG7h24gaGF5IGtow7RuZz8gKCB04bqnbmcgaOG6p20gaG/DoG4gdGhp4buHbiBiYW8gZ+G7k20gY8OhYyBwaMOybmcgbmjGsCBwaMOybmcgdOG6rXAgdGjhu4MgZOG7pWMsIHRyw7IgY2jGoWkgxJFp4buHbiB04butLCAuLi4pCgotICAgcmVjcmVhdGlvbjogbmjDoCBjw7MgcGjDsm5nIGdp4bqjaSB0csOtIGtow7RuZz8KCsSQ4bq3dCBnaeG6oyB0aGnhur90OgoKSDA6IEhhaSBiaeG6v24gxJHhu5ljIGzhuq1wCgpIMTogSGFpIGJp4bq/biBraMO0bmcgxJHhu5ljIGzhuq1wCgpgYGB7cn0KY2hpc3EudGVzdChhNCkKYGBgCgpL4bq/dCBxdeG6oyBuw6B5IGNobyBjaMO6bmcgdGEgdGjhuqV5IHLhurFuZyBwLXZhbHVlIFw8IDAuMDUuIMSQw6J5IGPFqW5nIGzDoCBi4bqxbmcgY2jhu6luZyDEkeG7gyB0YSBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSDAuIFbhuq15IDIgYmnhur9uIGZ1bGxiYXNlIHbDoCByZWNyZWF0aW9uIGzDoCBoYWkgYmnhur9uIGtow7RuZyDEkeG7mWMgbOG6rXAgduG7m2kgbmhhdS4KCiMjIEdp4buvYSAyIGJp4bq/biBmdWxsYmFzZSB2w6AgbG90c2l6ZQoKLSAgIGZ1bGxiYXNlOiBuaMOgIGPDsyDEkcaw4bujYyB0cmFuZyBi4buLIHThuqduZyBo4bqnbSBob8OgbiB0aGnhu4duIGhheSBraMO0bmc/ICggdOG6p25nIGjhuqdtIGhvw6BuIHRoaeG7h24gYmFvIGfhu5NtIGPDoWMgcGjDsm5nIG5oxrAgcGjDsm5nIHThuq1wIHRo4buDIGThu6VjLCB0csOyIGNoxqFpIMSRaeG7h24gdOG7rSwgLi4uKQoKLSAgIGxvdHNpemU6IGRp4buHbiB0w61jaCBjxINuIG5ow6AKCsSQ4bq3dCBnaeG6oyB0aGnhur90OgoKSDA6IEhhaSBiaeG6v24gxJHhu5ljIGzhuq1wCgpIMTogSGFpIGJp4bq/biBraMO0bmcgxJHhu5ljIGzhuq1wCgpgYGB7cn0KY2hpc3EudGVzdChhNSkKYGBgCgpL4bq/dCBxdeG6oyBuw6B5IGNobyBjaMO6bmcgdGEgdGjhuqV5IHLhurFuZyBwLXZhbHVlIFw+IDAuMDUuIMSQw6J5IGPFqW5nIGzDoCBi4bqxbmcgY2jhu6luZyDEkeG7gyB0YSBjaOG6pXAgbmjhuq1uIGdp4bqjIHRodXnhur90IEgwLiBW4bqteSAyIGJp4bq/biBmdWxsYmFzZSB2w6AgbG90c2l6ZSBsw6AgaGFpIGJp4bq/biDEkeG7mWMgbOG6rXAgduG7m2kgbmhhdS4KCiMjIEdp4buvYSAyIGJp4bq/biBuZ3UgdsOgIHNpemUKCi0gICBuZ3U6IHPhu5EgcGjDsm5nIG5n4bunCgotICAgc2l6ZTogZGnhu4duIHTDrWNoIGPEg24gbmjDoAoKxJDhurd0IGdp4bqjIHRoaeG6v3Q6CgpIMDogSGFpIGJp4bq/biDEkeG7mWMgbOG6rXAKCkgxOiBIYWkgYmnhur9uIGtow7RuZyDEkeG7mWMgbOG6rXAKCmBgYHtyfQpjaGlzcS50ZXN0KGE2KQpgYGAKCkvhur90IHF14bqjIG7DoHkgY2hvIGNow7puZyB0YSB0aOG6pXkgcuG6sW5nIHAtdmFsdWUgXDwgMC4wNS4gxJDDonkgY8WpbmcgbMOgIGLhurFuZyBjaOG7qW5nIMSR4buDIHRhIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBIMC4gVuG6rXkgMiBiaeG6v24gbmd1IHbDoCBzaXplIGzDoCBoYWkgYmnhur9uIGtow7RuZyDEkeG7mWMgbOG6rXAgduG7m2kgbmhhdS4KCiMjIEdp4buvYSAyIGJp4bq/biBuZ3UgdsOgIGdpYQoKLSAgIGdpYTogZ2nDoSBiw6FuIG5ow6AKCi0gICBuZ3U6IHPhu5EgcGjDsm5nIG5n4bunCgrEkOG6t3QgZ2nhuqMgdGhp4bq/dDoKCkgwOiBIYWkgYmnhur9uIMSR4buZYyBs4bqtcAoKSDE6IEhhaSBiaeG6v24ga2jDtG5nIMSR4buZYyBs4bqtcAoKYGBge3J9CmNoaXNxLnRlc3QoYTcpCmBgYAoKS+G6v3QgcXXhuqMgbsOgeSBjaG8gY2jDum5nIHRhIHRo4bqleSBy4bqxbmcgcC12YWx1ZSBcPCAwLjA1LiDEkMOieSBjxaluZyBsw6AgYuG6sW5nIGNo4bupbmcgxJHhu4MgdGEgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEgwLiBW4bqteSAyIGJp4bq/biBuZ3UgdsOgIGdpYSBsw6AgaGFpIGJp4bq/biBraMO0bmcgxJHhu5ljIGzhuq1wIHbhu5tpIG5oYXUuCgojIyBHaeG7r2EgMiBiaeG6v24gbmd1IHbDoCBwcmVmZXIKCi0gICBuZ3U6IHPhu5EgcGjDsm5nIG5n4bunCgotICAgcHJlZmVyOiBuaMOgIGPDsyBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5Ega2jDtG5nCgrEkOG6t3QgZ2nhuqMgdGhp4bq/dAoKSDA6IEhhaSBiaeG6v24gxJHhu5ljIGzhuq1wCgpIMTogSGFpIGJp4bq/biBraMO0bmcgxJHhu5ljIGzhuq1wCgpgYGB7cn0KY2hpc3EudGVzdChhOCkKYGBgCgpL4bq/dCBxdeG6oyBuw6B5IGNobyBjaMO6bmcgdGEgdGjhuqV5IHLhurFuZyBwLXZhbHVlIFw8IDAuMDUuIMSQw6J5IGPFqW5nIGzDoCBi4bqxbmcgY2jhu6luZyDEkeG7gyB0YSBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSDAuIFbhuq15IDIgYmnhur9uIG5ndSB2w6AgcHJlZmVyIGzDoCBoYWkgYmnhur9uIGtow7RuZyDEkeG7mWMgbOG6rXAgduG7m2kgbmhhdS4KCiMjIEdp4buvYSAyIGJp4bq/biBuZ3UgdsOgIHN0b3JpZXMKCi0gICBuZ3U6IHPhu5EgcGjDsm5nIG5n4bunCgotICAgc3Rvcmllczogc+G7kSB04bqnbmcgY+G7p2EgbmfDtGkgbmjDoCBraMO0bmcgdMOtbmggdOG6p25nIGjhuqdtCgrEkOG6t3QgZ2nhuqMgdGhp4bq/dDoKCkgwOiBIYWkgYmnhur9uIMSR4buZYyBs4bqtcAoKSDE6IEhhaSBiaeG6v24ga2jDtG5nIMSR4buZYyBs4bqtcAoKYGBge3J9CmNoaXNxLnRlc3QoYTkpCmBgYAoKS+G6v3QgcXXhuqMgbsOgeSBjaG8gY2jDum5nIHRhIHRo4bqleSBy4bqxbmcgcC12YWx1ZSBcPCAwLjA1LiDEkMOieSBjxaluZyBsw6AgYuG6sW5nIGNo4bupbmcgxJHhu4MgdGEgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEgwLiBW4bqteSAyIGJp4bq/biBuZ3UgdsOgIHN0b3JpZXMgbMOgIGhhaSBiaeG6v24ga2jDtG5nIMSR4buZYyBs4bqtcCB24bubaSBuaGF1LgoKIyBCw6BpIHRvw6FuIMaw4bubYyBsxrDhu6NuZyB04bu3IGzhu4cKCiMjIMav4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgY2hvIGJp4bq/biBwcmljZQoKYGBge3J9CnQgPC0gaFtoJHByaWNlID4gNzAwMDAsXQpwcm9wLnRlc3QoIGxlbmd0aCh0JHByaWNlKSwgbGVuZ3RoKGgkcHJpY2UpKQpgYGAKClbhu5tpIMSR4buZIHRpbiBj4bqteSA5NSUgdGEgY8OzIHThu7cgbOG7hyBuZ8aw4budaSBiw6FuIG5ow6AgduG7m2kgZ2nDoSB0csOqbiA3MDAwMCBVU0QgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IG7hurFtIHRyb25nIGtob+G6o25nIHThu6sgMzIsNzglIMSR4bq/biA0MSwwMyUuCgojIyDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIGNobyBiaeG6v24gbG90c2l6ZQoKYGBge3J9CnQxIDwtIGhbaCRsb3RzaXplID4gNTUwMCxdCnByb3AudGVzdCggbGVuZ3RoKHQxJGxvdHNpemUpLCBsZW5ndGgoaCRsb3RzaXplKSkKYGBgCgpW4bubaSDEkeG7mSB0aW4gY+G6rXkgOTUlIHRhIGPDsyB04bu3IGzhu4cgbmfGsOG7nWkgYsOhbiBuaMOgIGPDsyBkaeG7h24gdMOtY2ggdHLDqm4gNTUwMCBzcWZ0IHRyb25nIGN14buZYyBraOG6o28gc8OhdCBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDMzLDE0JSDEkeG6v24gNDEsNCUuCgojIyDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIGNobyBiaeG6v24gYmVkcm9vbXMKCmBgYHtyfQp0MiA8LSBoW2gkYmVkcm9vbXMgPiAyLF0KcHJvcC50ZXN0KCBsZW5ndGgodDIkYmVkcm9vbXMpLCBsZW5ndGgoaCRiZWRyb29tcykpCmBgYAoKVuG7m2kgxJHhu5kgdGluIGPhuq15IDk1JSB0YSBjw7MgdOG7tyBs4buHIG5nxrDhu51pIGLDoW4gbmjDoCBjw7Mgbmhp4buBdSBoxqFuIDIgcGjDsm5nIG5n4bunIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDcwLDgyJSDEkeG6v24gNzgsMjglLgoKIyMgxq/hu5tjIGzGsOG7o25nIHThu7cgbOG7hyBiaeG6v24gYmF0aHJvb21zCgpgYGB7cn0KdDMgPC0gaFtoJGJhdGhyb29tcyA+IDIsXQpwcm9wLnRlc3QoIGxlbmd0aCh0MyRiYXRocm9vbXMpLCBsZW5ndGgoaCRiYXRocm9vbXMpKQpgYGAKClbhu5tpIMSR4buZIHRpbiBj4bqteSA5NSUgdGEgY8OzIHThu7cgbOG7hyBuZ8aw4budaSBiw6FuIG5ow6AgY8OzIG5oaeG7gXUgaMahbiAyIHBow7JuZyB04bqvbSB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgbuG6sW0gdHJvbmcga2hv4bqjbmcgdOG7qyAxLDElIMSR4bq/biAzLDclLgoKIyMgxq/hu5tjIGzGsOG7o25nIHThu7cgbOG7hyBiaeG6v24gc3RvcmllcwoKYGBge3J9CnQ0IDwtIGhbaCRzdG9yaWVzID4gMSxdCnByb3AudGVzdCggbGVuZ3RoKHQ0JHN0b3JpZXMpLCBsZW5ndGgoaCRzdG9yaWVzKSkKYGBgCgpW4bubaSDEkeG7mSB0aW4gY+G6rXkgOTUlIHRhIGPDsyB04bu3IGzhu4cgbmfGsOG7nWkgYsOhbiBuaMOgIGPDsyBuaGnhu4F1IGjGoW4gMSB04bqnbmcgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IG7hurFtIHRyb25nIGtob+G6o25nIHThu6sgNTQsMTUlIMSR4bq/biA2Miw1OCUuCgojIyDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIGJp4bq/biBkcml2ZXdheQoKYGBge3J9CnQ1IDwtIGhbaCRkcml2ZXdheSA9PSAnbm8nLF0KcHJvcC50ZXN0KCBsZW5ndGgodDUkZHJpdmV3YXkpLCBsZW5ndGgoaCRkcml2ZXdheSkpCmBgYAoKVuG7m2kgxJHhu5kgdGluIGPhuq15IDk1JSB0YSBjw7MgdOG7tyBs4buHIG5nxrDhu51pIGLDoW4gbmjDoCBjw7Mga2h1IHbhu7FjIMSR4bqtdSB4ZSByacOqbmcgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IG7hurFtIHRyb25nIGtob+G6o25nIHThu6sgMTEsMzUlIMSR4bq/biAxNywzNyUuCgojIyDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIGJp4bq/biByZWNyZWF0aW9uCgpgYGB7cn0KdDYgPC0gaFtoJHJlY3JlYXRpb24gPT0gJ3llcycsXQpwcm9wLnRlc3QoIGxlbmd0aCh0NiRyZWNyZWF0aW9uKSwgbGVuZ3RoKGgkcmVjcmVhdGlvbikpCmBgYAoKVuG7m2kgxJHhu5kgdGluIGPhuq15IDk1JSB0YSBjw7MgdOG7tyBs4buHIG5nxrDhu51pIGLDoW4gbmjDoCBjw7MgcGjDsm5nIGdp4bqjaSB0csOtIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDE0LDclIMSR4bq/biAyMSwzJS4KCiMjIMav4bubYyBsxrDhu6NuZyB04bu3IGzhu4cgYmnhur9uIGZ1bGxiYXNlCgpgYGB7cn0KdDcgPC0gaFtoJGZ1bGxiYXNlID09ICd5ZXMnLF0KcHJvcC50ZXN0KCBsZW5ndGgodDckZnVsbGJhc2UpLCBsZW5ndGgoaCRmdWxsYmFzZSkpCmBgYAoKVuG7m2kgxJHhu5kgdGluIGPhuq15IDk1JSB0YSBjw7MgdOG7tyBs4buHIG5nxrDhu51pIGLDoW4gbmjDoCBjw7MgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiB0cm9uZyBjdeG7mWMga2jhuqNvIHPDoXQgbuG6sW0gdHJvbmcga2hv4bqjbmcgdOG7qyAzMSwwMSUgxJHhur9uIDM5LDIlLgoKIyMgxq/hu5tjIGzGsOG7o25nIHThu7cgbOG7hyBiaeG6v24gZ2FzaGVhdAoKYGBge3J9CnQ4IDwtIGhbaCRnYXNoZWF0ID09ICd5ZXMnLF0KcHJvcC50ZXN0KCBsZW5ndGgodDgkZ2FzaGVhdCksIGxlbmd0aChoJGdhc2hlYXQpKQpgYGAKClbhu5tpIMSR4buZIHRpbiBj4bqteSA5NSUgdGEgY8OzIHThu7cgbOG7hyBuZ8aw4budaSBiw6FuIG5ow6AgY8OzIHPhu60gZOG7pW5nIGdhcyDEkeG7gyDEkXVuIG7GsOG7m2MgbsOzbmcgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IG7hurFtIHRyb25nIGtob+G6o25nIHThu6sgMywwNSUgxJHhur9uIDYsOCUuCgojIyDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIGJp4bq/biBhaXJjb24KCmBgYHtyfQp0OSA8LSBoW2gkYWlyY29uID09ICd5ZXMnLF0KcHJvcC50ZXN0KCBsZW5ndGgodDkkYWlyY29uKSwgbGVuZ3RoKGgkYWlyY29uKSkKYGBgCgpW4bubaSDEkeG7mSB0aW4gY+G6rXkgOTUlIHRhIGPDsyB04bu3IGzhu4cgbmfGsOG7nWkgYsOhbiBuaMOgIGPDsyBtw6F5IMSRaeG7gXUgaG/DoCB0cnVuZyB0w6JtIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDI3LDgzJSDEkeG6v24gMzUsOCUuCgojIyDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIGJp4bq/biBnYXJhZ2UKCmBgYHtyfQp0MTAgPC0gaFtoJGdhcmFnZSA+IDIsXQpwcm9wLnRlc3QoIGxlbmd0aCh0MTAkZ2FyYWdlKSwgbGVuZ3RoKGgkZ2FyYWdlKSkKYGBgCgpW4bubaSDEkeG7mSB0aW4gY+G6rXkgOTUlIHRhIGPDsyB04bu3IGzhu4cgbmfGsOG7nWkgYsOhbiBuaMOgIGPDsyDEkWnhu4F1IGhvw6AgdHJ1bmcgdMOibSB0cm9uZyBuaMOgIHRyb25nIGN14buZYyBraOG6o28gc8OhdCBu4bqxbSB0cm9uZyBraG/huqNuZyB04burIDEsMiUgxJHhur9uIDMsOSUuCgojIyDGr+G7m2MgbMaw4bujbmcgdOG7tyBs4buHIGJp4bq/biBwcmVmZXIKCmBgYHtyfQp0MTEgPC0gaFtoJHByZWZlciA9PSd5ZXMnLF0KcHJvcC50ZXN0KCBsZW5ndGgodDExJHByZWZlciksIGxlbmd0aChoJHByZWZlcikpCmBgYAoKVuG7m2kgxJHhu5kgdGluIGPhuq15IDk1JSB0YSBjw7MgdOG7tyBs4buHIG5nxrDhu51pIGLDoW4gbmjDoCBu4bqxbSB0cm9uZyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EgdHJvbmcgY3Xhu5ljIGto4bqjbyBzw6F0IG7hurFtIHRyb25nIGtob+G6o25nIHThu6sgMjAlIMSR4bq/biAyNywyNyUuCgojIEjhu5NpIHF1eQoKIyMgSOG7k2kgcXV5IGNobyBiaeG6v24gZnVsbGJhc2UgCgojIyMgSOG7k2kgcXV5IGxvZ2l0CgpgYGB7cn0KTUhsb2cgPC0gZ2xtKCBmdWxsYmFzZSB+IHByZWZlciArIHJlY3JlYXRpb24gLCBmYW1pbHk9IGJpbm9taWFsKCBsaW5rID0gJ2xvZ2l0JyksIGRhdGE9aCkKc3VtbWFyeShNSGxvZykKQnJpZXJTY29yZShNSGxvZykKY29uZnVzaW9uTWF0cml4KCB0YWJsZSggcHJlZGljdChNSGxvZywgdHlwZSA9J3Jlc3BvbnNlJykgPj0gMC41LCBNSGxvZyRkYXRhJGZ1bGxiYXNlID09ICd5ZXMnKSkKYGBgCgpUYSBjw7MgbcO0IGjDrG5oIGjhu5NpIHF1eToKCiRsb2coXGZyYWN7XHBpfXsxLVxwaX0pID0gLTEsMjI5OSArIDAsOTQzMnByZWZlciArIDEsOTI0N3JlY3JlYXRpb24kCgoKCiMjIyBI4buTaSBxdXkgY2xvZ2xvZwoKYGBge3J9Ck1IY2xvZ2xvZyA8LSBnbG0oIGZ1bGxiYXNlIH4gcHJlZmVyICsgcmVjcmVhdGlvbiAsIGZhbWlseT0gYmlub21pYWwoIGxpbmsgPSAnY2xvZ2xvZycpLCBkYXRhPWgpCnN1bW1hcnkoTUhjbG9nbG9nKQpCcmllclNjb3JlKE1IY2xvZ2xvZykKY29uZnVzaW9uTWF0cml4KCB0YWJsZSggcHJlZGljdChNSGNsb2dsb2csIHR5cGUgPSdyZXNwb25zZScpID49IDAuNSwgTUhjbG9nbG9nJGRhdGEkZnVsbGJhc2UgPT0gJ3llcycpKQpgYGAKClRhIGPDsyBow6BtIGjhu5NpIHF1eToKCiRjbG9nbG9nKFxwaSkgPSAtMSwzNDUgKyAwLDcyMjJwcmVmZXIgKyAxLDM3NjhyZWNyZWF0aW9uJAoKCiMjIyBI4buTaSBxdXkgcHJvYml0CgpgYGB7cn0KTUhwcm9iaXQgPC0gZ2xtKCBmdWxsYmFzZSB+IHByZWZlciAgKyByZWNyZWF0aW9uICwgZmFtaWx5PSBiaW5vbWlhbCggbGluayA9ICdwcm9iaXQnKSwgZGF0YT1oKQpzdW1tYXJ5KE1IcHJvYml0KQpCcmllclNjb3JlKE1IcHJvYml0KQpjb25mdXNpb25NYXRyaXgoIHRhYmxlKCBwcmVkaWN0KE1IcHJvYml0LCB0eXBlID0ncmVzcG9uc2UnKSA+PSAwLjUsIE1IcHJvYml0JGRhdGEkZnVsbGJhc2UgPT0gJ3llcycpKQpgYGAKClRhIGPDsyBow6BtIGjhu5NpIHF1eToKCiRwcm9iaXQoXHBpKSA9IC0wLDc1MDYgKyAwLDU3MjU3cHJlZmVyICsgMSwxODI2M3JlY3JlYXRpb24kCgoKCiMjIyBM4buxYSBjaOG7jW4gbcO0IGjDrG5oIHBow7kgaOG7o3AKCmBgYHtyfQpBSUMgIDwtIGMoNjIyLjMzLDYyMC45OSw2MjIuMTgpCkJyaWVyc2NvcmUgPC0gYygwLjE4OTQ2NjcsMC4xODkwNzM0LDAuMTg5NDMzMSkKRGV2aWFuY2UgPC0gYyggNjE2LjMzLCA2MTQuOTksIDYxNi4xOCkKY29uZnVzaW9uTWF0cml4IDwtIGMoMC43MzI2ICwwLjczMjYgLDAuNzMyNiApICAKTUggPC0gYygnbG9naXQnLCdjbG9nbG9nJywncHJvYml0JykKQmFuZ0tldFF1YSA8LSBkYXRhLmZyYW1lKE1ILCBjb25mdXNpb25NYXRyaXgsIERldmlhbmNlLCBCcmllcnNjb3JlLCBBSUMpCkJhbmdLZXRRdWEKYGBgCgotICAgVGEgY8OzIG3DtCBow6xuaCBo4buTaSBxdXkgdGhlbyBsaW5rIGZ1bmN0aW9uIGNsb2dsb2cgbMOgIHThu5FpIMawdSBuaOG6pXQuIFbDrCB24bubaSBjw7luZyDEkeG7mSBjaMOtbmggeMOhYyBsw6AgNzMsMjYlIHRow6wgbcO0IGjDrG5oIGNsb2dsb2cgY8OzIERpdmlhbmNlLCBCcmllcnNjb3JlIHbDoCBBSUMgbMOgIHRo4bqldCBuaOG6pXQgdHJvbmcgY8OhYyBtw7QgaMOsbmguCgojIyMgS2nhu4NtIMSR4buLbmggc+G7sSBwaMO5IGjhu6NwIG3DtCBow6xuaApgYGB7cn0KYW5vdmEoTUhjbG9nbG9nLCB0ZXN0ID0gJ0NoaXNxJykKYGBgCgpHaeG6oyB0aHV54bq/dCBIMDogbcO0IGjDrG5oIGtow7RuZyBwaMO5IGjhu6NwIHbhu5tpIGThu68gbGnhu4d1IMSRaeG7gXUgdHJhCgpUYSBjw7MgY8OhYyBwX3ZhbHVlIMSR4buBdSBiw6kgaMahbiAwLDA1LCBuw6puIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBIMCwgbcO0IGjDrG5oIHRyw6puIGzDoCBwaMO5IGjhu6NwLgoKIyMjIEdp4bqjaSB0aMOtY2ggbcO0IGjDrG5oIMSRxrDhu6NjIGNo4buNbgoKS+G6v3QgcXXhuqMgdOG7qyBtw7QgaMOsbmggY2xvZ2xvZyBjaG8gdGjhuqV5IGJp4bq/biBmdWxsYmFzZSBjaOG7i3Ug4bqjbmggaMaw4bufbmcgdOG7qyAyIGJp4bq/biDEkeG7mWMgbOG6rXAgbMOgIHByZWZlciB2w6AgcmVjcmVhdGlvbi4gVHJvbmcgxJHDszoKCi0gICBwcmVmZXJ5ZXM6IG5nxrDhu51pIGPDsyBuaMOgIG7hurFtIHRyb25nIGtodSB0cnVuZyB0w6JtIGPhu6dhIHRow6BuaCBwaOG7kSAKCi0gICByZWNyZWF0aW9ueWVzOiBuaMOgIGPDsyBwaMOybmcgZ2nhuqNpIHRyw60gCgpW4bubaSBnaeG6oyB0aHV54bq/dCBjw6FjIHnhur91IHThu5Ega2jDoWMga2jDtG5nIMSR4buVaSwgdGEgY8OzIHTDoWMgxJHhu5luZyBj4bunYSB04burbmcgYmnhur9uIGzDqm4gYmnhur9uIGZ1bGxiYXNlOgoKLSAgIE5nxrDhu51pIGPDsyBuaMOgIG7hurFtIOG7nyBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EgY8OzIHThu7cgbOG7hyB04bqnbmcgaOG6p20gxJHGsOG7o2MgdHJhbmcgYuG7iyBob8OgbiB0aGnhu4duIGNhbyBoxqFuIG5nxrDhu51pIGPDsyBuaMOgIGtow7RuZyBu4bqxbSBuZ8aw4budaSBraHUgduG7sWMgdHJ1bmcgdMOibSB0aMOgbmggcGjhu5EuCgotICAgTmjDoCBjw7MgcGjDsm5nIGdp4bqjaSB0csOtIGPDsyB04bu3IGzhu4cgdOG6p25nIGjhuqdtIMSRxrDhu6NjIHRyYW5nIGLhu4sgaG/DoG4gdGhp4buHbiBjYW8gaMahbiBuaMOgIGtow7RuZyBjw7MgcGjDsm5nIGdp4bqjaSB0csOtLgoKIyMgSOG7k2kgcXV5IHBvaXNzb24KCmBgYHtyfQpNSGxvZzEgPC0gZ2xtKCBiZWRyb29tcyB+ICBwcmljZSArIHN0b3JpZXMgLCBmYW1pbHk9IHBvaXNzb24oIGxpbmsgPSAnbG9nJyksIGRhdGE9aCkKc3VtbWFyeShNSGxvZzEpCmBgYAoKVGEgdGjhuqV5IGJp4bq/biBiZWRyb29tcyBjaOG7i3Ug4bqjbmggaMaw4bufbmcgYuG7n2kgMiBiaeG6v24gcHJpY2UgdsOgIHN0b3JpZXMuIFRyb25nIMSRw7M6CgotICAgYmVkcm9vbTogc+G7kSBwaMOybmcgbmfhu6cgdHJvbmcgbmjDoAoKLSAgIHByaWNlOiBnacOhIGLDoW4gbmjDoAoKLSAgIHN0b3JpZXM6IHPhu5EgdOG6p25nIChraMO0bmcgdMOtbmggdOG6p25nIGjhuqdtKQoKVGEgY8OzIGjDoG0gaOG7k2kgcXV5OgoKJGxvZyhcZnJhY3tcbXUoeCl9e3R9KSA9IDAsNzg4NiArIDAsMDgzMTJzdG9yaWVzJCAkKyAyLDA4NSoxMF57LTZ9cHJpY2UkCgpUcm9uZyDEkcOzICRcZnJhY3tcbXUoeCl9e3R9JCBsw6AgdOG7iSBs4buHIHPhu5EgcGjDsm5nIG5n4bunIHRydW5nIGLDrG5oIGPhu6dhIG5o4buvbmcgbmfDtGkgbmjDoCBjw7MgY8O5bmcgc+G7kSB04bqnbmcgdsOgIG3hu6ljIGdpw6EgYsOhbi4gCgoKCgo=