setwd("C:/Users/YEN NHI/Documents/MPNN")
rm(list=ls()) # clear environment
library(fBasics)
## Warning: package 'fBasics' was built under R version 4.2.3
library(ggplot2)
library(xlsx)
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.2.3
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# Đọc file dữ liệu
dl <- read.xlsx("mtcl.xlsx",1)
vcb = dl$VCB
vni = dl$VNI
bid = dl$BID
shb = dl$SHB
hdb = dl$HDB
acb = dl$ACB

1 Chương1. Giới thiệu

1.1 Lý do chọn đề tài

1.2 Mục tiêu nghiên cứu

Mô phỏng giá các cổ phiếu nhóm ngành ngân hàng trong danh mục đầu tư, từ đó đưa ra kết quả mô phỏng của tỷ suất sinh lời và giá trị danh mục đầu tư của danh mục.

1.3 Đối tượng nghiên cứu

Bài nghiên cứu này mô phỏng giá các cổ phiếu được niêm yết trên sàn giao dịch cũng như tỷ suất sinh lời và giá trị danh mục đầu tư.

1.4 Kết cấu bài nghiên cứu

Chương một: Giới thiệu tổng quan nghiên cứu. Chương này giới thiệu tổng quan nghiên cứu, bao gồm: đặt vấn đề nghiên cứu, mục tiêu nghiên cứu, đối tượng nghiên cứu, phạm vi và phương pháp nghiên cứu và kết cấu bài nghiên cứu.

Chương hai: Cơ sở lý thuyết nghiên cứu. Chương này bao gồm: các khái niệm, các lý thuyết xung quanh mô phỏng Monte Carlo và thị trường chứng khoán.

Chương ba: Phương pháp nghiên cứu và dữ liệu nghiên cứu – Mô tả phương pháp nghiên cứu và nguồn dữ liệu sử dụng, xây dựng mô hình nghiên cứu, giải thích các biến có trong mô hình.

Chương bốn: Phân tích dữ liệu và kết quả nghiên cứu.

Chương năm: Kết luận. Chương này bao gồm kết luận chung của bài nghiên cứu.

2 Chương 2. Cơ sở lý thuyết

2.1 Mô phỏng

Khi mô hình toán học quá phức tạp, được mô tả bởi rất nhiều phương trình và nhiều biến, ví dụ mô tả vụ nổ bom hạt nhân, thì nghiệm của mô hình là nghiệm mô phỏng, gần đúng (theo nghĩa xấp xỉ) với nghiệm thực của mô hình.

2.2 Mô phỏng ngẫu nhiên

Khi mô hình toán học giả định được vận hành theo các quy luật ngẫu nhiên, thì các phương pháp mô phỏng chúng đươc gọi là mô phỏng ngẫu nhiên.

2.3 Chuyển động Brown

Quá trình ngẫu nhiên {B(t): t \(\geq\) 0} được gọi là chuyển động Brown, nếu:

  1. B(0) = 0 hầu chắc chắn.
  2. {B(t): t \(\geq\) 0} là quá trình dừng, có số gia độc lập
  3. Với mỗi t \(\geq\) 0, B(t)~N(0,\(\sigma^2\)t).

Nếu \(\sigma\) = 1, thì {B(t): t \(\geq\) 0} là chuyển động Brown chính tắc. {B(t): t \(\geq\) 0} còn được gọi là quá trình Winner.

  • Số gia:

3 Chương 3. Phương pháp nghiên cứu và dữ liệu nghiên cứu

3.1 Biến đầu ra

VNi (Chỉ số VN-Index)

3.2 Biến đầu vào

  • 5 biến đầu vào của bài nghiên cứu tương ứng với giá 5 mã cố phiếu nhóm ngành ngân hàng được niêm yết trên sàn HOSE.
  1. VCB: Mã cổ phiếu của NHTMCP Ngoại thương Việt Nam.
  2. BID: Mã cổ phiếu của NHTMCP Đầu tư và Phát triền Việt Nam.
  3. SHB: Mã cổ phiếu của NHTMCP Sài Gòn - Hà Nội.
  4. HDB: Mã cổ phiếu của NHTMCP Phát triển TP Hồ Chí Minh.
  5. ACB: Mã cổ phiếu của NHTMCP Á Châu.

3.3 Mô hình nghiên cứu

\[ VNI = \beta_0 + \beta_1VCB + \beta_2BID + \beta_3SHB + \beta_4HDB + \beta_5ACB \]

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

Dữ liệu nghiên cứu được thu thập từ các trang web investing.com và cophieu68.vn, dữ liệu bao gồm 890 quan sát bắt đầu từ ngày 9/1/2020 đến ngày 1/8/2023 với 5 mã cổ phiếu trong nhóm ngành Ngân hàng như: VCB, BID, SHB, HDB, ACB.

4 Chương 4. Mô phỏng và kết quả nghiên cứu

4.1 Thống kê mô tả và xác định phân phối

4.1.1 Biến VCB

summary(vcb)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   43925   69114   76413   76600   82400  106500
sd(vcb)
## [1] 11028.78
hist(vcb)

Dựa trên kết quả thống kê trên, ta thấy giá cổ phiếu Vietcombank có giá trị trung bình là 76600 đồng, giá trị trung vị là 76413 đồng. Biến VCB dao động từ giá trị nhỏ nhất là 43925 đồng đến giá trị lớn nhất là 106500 đồng, với độ lệch chuẩn là 11028,78 đồng.

shapiro.test(vcb)
## 
##  Shapiro-Wilk normality test
## 
## data:  vcb
## W = 0.98504, p-value = 6.905e-08
ks.test(vcb, y=pexp)
## Warning in ks.test.default(vcb, y = pexp): ties should not be present for the
## Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  vcb
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided
ks.test(vcb, y = 'punif')
## Warning in ks.test.default(vcb, y = "punif"): ties should not be present for
## the Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  vcb
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided
ks.test(vcb, y = 'plnorm')
## Warning in ks.test.default(vcb, y = "plnorm"): ties should not be present for
## the Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  vcb
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided

Sau khi kiểm định các phân phối gồm: phân phối chuẩn, phân phối mũ, phân phối đều và phân phối loga chuẩn cho biến VCB, ta thấy P_value < 0,05, nên ta bác bỏ \(H_0\), tức là biến VCB không tuân theo các quy luật phân phối trên.

4.1.2 Biến BID

summary(bid)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   23970   31908   35150   36375   40236   49000
sd(bid)
## [1] 5448.574
hist(bid)

Dựa trên kết quả thống kê trên, ta thấy giá cổ phiếu BIDV có giá trị trung bình là 36375 đồng, giá trị trung vị là 35150 đồng. Biến BID dao động từ giá trị nhỏ nhất là 23970 đồng đến giá trị lớn nhất là 49000 đồng, với độ lệch chuẩn là 5448,574 đồng.

shapiro.test(bid)
## 
##  Shapiro-Wilk normality test
## 
## data:  bid
## W = 0.94711, p-value < 2.2e-16
ks.test(bid, y=pexp)
## Warning in ks.test.default(bid, y = pexp): ties should not be present for the
## Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  bid
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided
ks.test(bid, y = 'punif')
## Warning in ks.test.default(bid, y = "punif"): ties should not be present for
## the Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  bid
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided
ks.test(bid, y = 'plnorm')
## Warning in ks.test.default(bid, y = "plnorm"): ties should not be present for
## the Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  bid
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided

Sau khi kiểm định các phân phối gồm: phân phối chuẩn, phân phối mũ, phân phối đều và phân phối loga chuẩn cho biến BID, ta thấy P_value < 0,05, nên ta bác bỏ \(H_0\), tức là biến BID không tuân theo các quy luật phân phối trên.

4.1.3 Biến SHB

summary(shb)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    3893   10295   11765   13212   17520   22859
sd(shb)
## [1] 4243.949
hist(shb)

Dựa trên kết quả thống kê trên, ta thấy giá cổ phiếu SHB có giá trị trung bình là 13212 đồng, giá trị trung vị là 11765 đồng. Biến SHB dao động từ giá trị nhỏ nhất là 3893 đồng đến giá trị lớn nhất là 22859 đồng, với độ lệch chuẩn là 4243,949 đồng.

shapiro.test(shb)
## 
##  Shapiro-Wilk normality test
## 
## data:  shb
## W = 0.90939, p-value < 2.2e-16
ks.test(shb, y=pexp)
## Warning in ks.test.default(shb, y = pexp): ties should not be present for the
## Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  shb
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided
ks.test(shb, y = 'punif')
## Warning in ks.test.default(shb, y = "punif"): ties should not be present for
## the Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  shb
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided
ks.test(shb, y = 'plnorm')
## Warning in ks.test.default(shb, y = "plnorm"): ties should not be present for
## the Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  shb
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided

Sau khi kiểm định các phân phối gồm: phân phối chuẩn, phân phối mũ, phân phối đều và phân phối loga chuẩn cho biến SHB, ta thấy P_value < 0,05, nên ta bác bỏ \(H_0\), tức là biến SHB không tuân theo các quy luật phân phối trên.

4.1.4 Biến HDB

summary(hdb)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    6691   13728   18350   17190   20480   26800
sd(hdb)
## [1] 4589.172
hist(hdb)

Dựa trên kết quả thống kê trên, ta thấy giá cổ phiếu HDB có giá trị trung bình là 17190 đồng, giá trị trung vị là 18350 đồng. Biến HDB dao động từ giá trị nhỏ nhất là 6691 đồng đến giá trị lớn nhất là 26800 đồng, với độ lệch chuẩn là 4589,172 đồng.

shapiro.test(hdb)
## 
##  Shapiro-Wilk normality test
## 
## data:  hdb
## W = 0.95324, p-value = 3.351e-16
ks.test(hdb, y=pexp)
## Warning in ks.test.default(hdb, y = pexp): ties should not be present for the
## Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  hdb
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided
ks.test(hdb, y = 'punif')
## Warning in ks.test.default(hdb, y = "punif"): ties should not be present for
## the Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  hdb
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided
ks.test(hdb, y = 'plnorm')
## Warning in ks.test.default(hdb, y = "plnorm"): ties should not be present for
## the Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  hdb
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided

Sau khi kiểm định các phân phối gồm: phân phối chuẩn, phân phối mũ, phân phối đều và phân phối loga chuẩn cho biến HDB, ta thấy P_value < 0,05, nên ta bác bỏ \(H_0\), tức là biến HDB không tuân theo các quy luật phân phối trên.

4.1.5 Biến ACB

summary(acb)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    8763   17408   22900   21100   25350   30360
sd(acb)
## [1] 5675.872
hist(acb)

Dựa trên kết quả thống kê trên, ta thấy giá cổ phiếu HDB có giá trị trung bình là 21100 đồng, giá trị trung vị là 22900 đồng. Biến ACB dao động từ giá trị nhỏ nhất là 8763 đồng đến giá trị lớn nhất là 30360 đồng, với độ lệch chuẩn là 5675.872 đồng.

shapiro.test(acb)
## 
##  Shapiro-Wilk normality test
## 
## data:  acb
## W = 0.88974, p-value < 2.2e-16
ks.test(acb, y=pexp)
## Warning in ks.test.default(acb, y = pexp): ties should not be present for the
## Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  acb
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided
ks.test(acb, y = 'punif')
## Warning in ks.test.default(acb, y = "punif"): ties should not be present for
## the Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  acb
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided
ks.test(acb, y = 'plnorm')
## Warning in ks.test.default(acb, y = "plnorm"): ties should not be present for
## the Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  acb
## D = 1, p-value < 2.2e-16
## alternative hypothesis: two-sided

Sau khi kiểm định các phân phối gồm: phân phối chuẩn, phân phối mũ, phân phối đều và phân phối loga chuẩn cho biến ACB, ta thấy P_value < 0,05, nên ta bác bỏ \(H_0\), tức là biến ACB không tuân theo các quy luật phân phối trên.

4.2 Mô phỏng dữ liệu

set.seed(121)
r_vcb = (dl$VCB - lag(dl$VCB, n=1))/lag(dl$VCB,n=1)
r_vcb <- na.omit(r_vcb)
gbm.f = function(n,S0,mu,sigma){
  t = 1
  t.s = seq(0,t,length = n)
  dt = t/n
  Bt = sqrt(t)*cumsum(rnorm((n),0,1))
  St = S0*exp((mu-sigma^2/2)*t.s + sigma*Bt)
  St # Kết quả của GBM
}
n <- 10000
S0 <- vcb[1]
mu <- (1/(n*(1/n)))*sum(r_vcb) #tính lợi nhuận kỳ vọng giá
sigma <- sqrt((sum((r_vcb - mu)^2))*(1/(n-1)*(1/n))) #tính độ biến động giá
VCB <- gbm.f(n,S0,mu,sigma)
plot(VCB, type = 'l', col = 'blue', main = "Giá cổ phiếu VCB", ylab = "đồng", xlab = "Ngày")

set.seed(121)
r_bid = (dl$BID - lag(dl$BID))/lag(dl$BID)
r_bid <- na.omit(r_bid)
gbm.f = function(n,S0,mu,sigma){
  t = 1
  t.s = seq(0,t,length = n)
  dt = t/n
  Bt = sqrt(t)*cumsum(rnorm((n),0,1))
  St = S0*exp((mu-sigma^2/2)*t.s + sigma*Bt)
  St # Kết quả của GBM
}
n <- 10000
S0 <- bid[1]
mu <- (1/(n*(1/n)))*sum(r_bid) #tính lợi nhuận kỳ vọng giá
sigma <- sqrt((sum((r_bid - mu)^2))*(1/(n-1)*(1/n))) #tính độ biến động giá
BID <- gbm.f(n,S0,mu,sigma)
plot(BID, type = 'l', col = 'blue', main = "Giá cổ phiếu BID", ylab = "đồng", xlab = "Ngày")

set.seed(121)
r_shb = (dl$SHB - lag(dl$SHB))/lag(dl$SHB)
r_shb <- na.omit(r_shb)
gbm.f = function(n,S0,mu,sigma){
  t = 1
  t.s = seq(0,t,length = n)
  dt = t/n
  Bt = sqrt(t)*cumsum(rnorm((n),0,1))
  St = S0*exp((mu-sigma^2/2)*t.s + sigma*Bt)
  St # Kết quả của GBM
}
n <- 10000
S0 <- shb[1]
mu <- (1/(n*(1/n)))*sum(r_shb) #tính lợi nhuận kỳ vọng giá
sigma <- sqrt((sum((r_shb - mu)^2))*(1/(n-1)*(1/n))) #tính độ biến động giá
SHB <- gbm.f(n,S0,mu,sigma)
plot(SHB, type = 'l', col = 'blue', main = "Giá cổ phiếu SHB", ylab = "đồng", xlab = "Ngày")

set.seed(121)
r_hdb = (dl$HDB - lag(dl$HDB))/lag(dl$HDB)
r_hdb <- na.omit(r_hdb)
gbm.f = function(n,S0,mu,sigma){
  t = 1
  t.s = seq(0,t,length = n)
  dt = t/n
  Bt = sqrt(t)*cumsum(rnorm((n),0,1))
  St = S0*exp((mu-sigma^2/2)*t.s + sigma*Bt)
  St # Kết quả của GBM
}
n <- 10000
S0 <- hdb[1]
mu <- (1/(n*(1/n)))*sum(r_hdb) #tính lợi nhuận kỳ vọng giá
sigma <- sqrt((sum((r_hdb - mu)^2))*(1/(n-1)*(1/n))) #tính độ biến động giá
HDB <- gbm.f(n,S0,mu,sigma)
plot(HDB, type = 'l', col = 'blue', main = "Giá cổ phiếu HDB", ylab = "đồng", xlab = "Ngày")

set.seed(121)
r_acb = (dl$ACB - lag(dl$ACB))/lag(dl$ACB)
r_acb <- na.omit(r_acb)
gbm.f = function(n,S0,mu,sigma){
  t = 1
  t.s = seq(0,t,length = n)
  dt = t/n
  Bt = sqrt(t)*cumsum(rnorm((n),0,1))
  St = S0*exp((mu-sigma^2/2)*t.s + sigma*Bt)
  St # Kết quả của GBM
}
n <- 10000
S0 <- acb[1]
mu <- (1/(n*(1/n)))*sum(r_acb) #tính lợi nhuận kỳ vọng giá
sigma <- sqrt((sum((r_acb - mu)^2))*(1/(n-1)*(1/n))) #tính độ biến động giá
ACB <- gbm.f(n,S0,mu,sigma)
plot(ACB, type = 'l', col = 'blue', main = "Giá cổ phiếu ACB", ylab = "đồng", xlab = "Ngày")

4.3 Mô hình theo dữ liệu đã mô phỏng

mh <- lm(dl$VNI ~ dl$VCB + dl$BID + dl$SHB + dl$ACB + dl$HDB, data = dl)
summary(mh)
## 
## Call:
## lm(formula = dl$VNI ~ dl$VCB + dl$BID + dl$SHB + dl$ACB + dl$HDB, 
##     data = dl)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -163.764  -38.842   -8.628   41.325  143.207 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  4.540e+02  1.644e+01  27.620  < 2e-16 ***
## dl$VCB      -2.645e-03  4.545e-04  -5.818 8.34e-09 ***
## dl$BID       2.314e-03  7.546e-04   3.066  0.00223 ** 
## dl$SHB       1.188e-02  8.260e-04  14.384  < 2e-16 ***
## dl$ACB      -1.188e-02  1.392e-03  -8.531  < 2e-16 ***
## dl$HDB       5.230e-02  1.829e-03  28.586  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 58.22 on 883 degrees of freedom
## Multiple R-squared:  0.9252, Adjusted R-squared:  0.9248 
## F-statistic:  2186 on 5 and 883 DF,  p-value: < 2.2e-16
vni <- 4.540e+02 - 2.645e-03*VCB +2.314e-03*BID +1.188e-02*SHB + 5.23e-02*HDB - 1.188e-02*ACB
plot(vni, type = 'l', col = 'blue', main = "Chỉ số VN-Index", ylab = "điểm", xlab = "Ngày")

vni1 = (vni - lag(vni))
phientanggia <- vni1[vni1 > 0]
phiengiamgia <- vni1[vni1 < 0]
length(phientanggia)
## [1] 5185
length(phiengiamgia)
## [1] 4816
vni <- cut(vni, breaks = c(min(vni), mean(vni),max(vni)), labels = c('thap','cao'))
table(vni)/sum(table(vni))
## vni
##     thap      cao 
## 0.450445 0.549555

Thông qua bảng tần suất và biểu đồ về chỉ số VN-Index, được mô phỏng bởi 5 mã cổ phiếu Ngân hàng, ta thấy chỉ số VN-Index có ngày vượt mốc qua 1400 điểm và thấp nhất xấp xỉ 800 điểm, có thể thấy từ biểu đồ thì chỉ số VNI có xu hướng biến động lớn, nhưng các phiên có chỉ số trên 1000 điểm là hơn 6000 ngày. Trong đó, xác suất VNI thấp là 0,450445 và xác suất VNI cao là 0,549555. Chỉ số VNI sau mô phỏng có 5185 phiên tăng giá và 4816 phiên giảm giá.

5 Chương 5. Kết luận

LS0tDQp0aXRsZTogIlRp4buDdSBsdeG6rW4gTcO0IHBo4buPbmcgTmfhuqt1IE5oacOqbiINCmF1dGhvcjogIk5ndXnhu4VuIFRo4buLIFnhur9uIE5oaSINCmRhdGU6ICIyMDIzLTA4LTA1Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IGZhbHNlDQogICAgICBkZl9wcmludDogcGFnZWQNCi0tLQ0KDQpgYGB7cn0NCnNldHdkKCJDOi9Vc2Vycy9ZRU4gTkhJL0RvY3VtZW50cy9NUE5OIikNCnJtKGxpc3Q9bHMoKSkgIyBjbGVhciBlbnZpcm9ubWVudA0KbGlicmFyeShmQmFzaWNzKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeSh4bHN4KQ0KbGlicmFyeShkcGx5cikNCiMgxJDhu41jIGZpbGUgZOG7ryBsaeG7h3UNCmRsIDwtIHJlYWQueGxzeCgibXRjbC54bHN4IiwxKQ0KdmNiID0gZGwkVkNCDQp2bmkgPSBkbCRWTkkNCmJpZCA9IGRsJEJJRA0Kc2hiID0gZGwkU0hCDQpoZGIgPSBkbCRIREINCmFjYiA9IGRsJEFDQg0KYGBgDQoNCiMgQ2jGsMahbmcxLiBHaeG7m2kgdGhp4buHdQ0KDQojIyBMw70gZG8gY2jhu41uIMSR4buBIHTDoGkNCg0KIyMgTeG7pWMgdGnDqnUgbmdoacOqbiBj4bupdQ0KDQpNw7QgcGjhu49uZyBnacOhIGPDoWMgY+G7lSBwaGnhur91IG5ow7NtIG5nw6BuaCBuZ8OibiBow6BuZyB0cm9uZyBkYW5oIG3hu6VjIMSR4bqndSB0xrAsIHThu6sgxJHDsyDEkcawYSByYSBr4bq/dCBxdeG6oyBtw7QgcGjhu49uZyBj4bunYSB04bu3IHN14bqldCBzaW5oIGzhu51pIHbDoCBnacOhIHRy4buLIGRhbmggbeG7pWMgxJHhuqd1IHTGsCBj4bunYSBkYW5oIG3hu6VjLg0KDQojIyDEkOG7kWkgdMaw4bujbmcgbmdoacOqbiBj4bupdQ0KDQpCw6BpIG5naGnDqm4gY+G7qXUgbsOgeSBtw7QgcGjhu49uZyBnacOhIGPDoWMgY+G7lSBwaGnhur91IMSRxrDhu6NjIG5pw6ptIHnhur90IHRyw6puIHPDoG4gZ2lhbyBk4buLY2ggY8WpbmcgbmjGsCB04bu3IHN14bqldCBzaW5oIGzhu51pIHbDoCBnacOhIHRy4buLIGRhbmggbeG7pWMgxJHhuqd1IHTGsC4NCg0KIyMgS+G6v3QgY+G6pXUgYsOgaSBuZ2hpw6puIGPhu6l1DQoNCioqQ2jGsMahbmcgbeG7mXQ6KiogR2nhu5tpIHRoaeG7h3UgdOG7lW5nIHF1YW4gbmdoacOqbiBj4bupdS4gQ2jGsMahbmcgbsOgeSBnaeG7m2kgdGhp4buHdSB04buVbmcgDQpxdWFuIG5naGnDqm4gY+G7qXUsIGJhbyBn4buTbTogxJHhurd0IHbhuqVuIMSR4buBIG5naGnDqm4gY+G7qXUsIG3hu6VjIHRpw6p1IG5naGnDqm4gY+G7qXUsIMSR4buRaSB0xrDhu6NuZyANCm5naGnDqm4gY+G7qXUsIHBo4bqhbSB2aSB2w6AgcGjGsMahbmcgcGjDoXAgbmdoacOqbiBj4bupdSB2w6Aga+G6v3QgY+G6pXUgYsOgaSBuZ2hpw6puIGPhu6l1LiANCg0KKipDaMawxqFuZyBoYWk6KiogQ8ahIHPhu58gbMO9IHRodXnhur90IG5naGnDqm4gY+G7qXUuIENoxrDGoW5nIG7DoHkgYmFvIGfhu5NtOiBjw6FjIGtow6FpIG5p4buHbSwgDQpjw6FjIGzDvSB0aHV54bq/dCB4dW5nIHF1YW5oIG3DtCBwaOG7j25nIE1vbnRlIENhcmxvIHbDoCB0aOG7iyB0csaw4budbmcgY2jhu6luZyBraG/DoW4uDQoNCioqQ2jGsMahbmcgYmE6KiogUGjGsMahbmcgcGjDoXAgbmdoacOqbiBj4bupdSB2w6AgZOG7ryBsaeG7h3UgbmdoacOqbiBj4bupdSDigJMgTcO0IHThuqMgcGjGsMahbmcgDQpwaMOhcCBuZ2hpw6puIGPhu6l1IHbDoCBuZ3Xhu5NuIGThu68gbGnhu4d1IHPhu60gZOG7pW5nLCB4w6J5IGThu7FuZyBtw7QgaMOsbmggbmdoacOqbiBj4bupdSwgZ2nhuqNpIHRow61jaCBjw6FjIGJp4bq/biBjw7MgdHJvbmcgbcO0IGjDrG5oLiANCg0KKipDaMawxqFuZyBi4buRbjoqKiBQaMOibiB0w61jaCBk4buvIGxp4buHdSB2w6Aga+G6v3QgcXXhuqMgbmdoacOqbiBj4bupdS4gDQoNCioqQ2jGsMahbmcgbsSDbToqKiBL4bq/dCBsdeG6rW4uIENoxrDGoW5nIG7DoHkgYmFvIGfhu5NtIGvhur90IGx14bqtbiBjaHVuZyBj4bunYSBiw6BpIG5naGnDqm4gY+G7qXUuDQoNCiMgQ2jGsMahbmcgMi4gQ8ahIHPhu58gbMO9IHRodXnhur90DQoNCiMjIE3DtCBwaOG7j25nDQoNCktoaSBtw7QgaMOsbmggdG/DoW4gaOG7jWMgcXXDoSBwaOG7qWMgdOG6oXAsIMSRxrDhu6NjIG3DtCB04bqjIGLhu59pIHLhuqV0IG5oaeG7gXUgcGjGsMahbmcgdHLDrG5oIHbDoCBuaGnhu4F1IGJp4bq/biwgdsOtIGThu6UgbcO0IHThuqMgduG7pSBu4buVIGJvbSBo4bqhdCBuaMOibiwgdGjDrCBuZ2hp4buHbSBj4bunYSBtw7QgaMOsbmggbMOgIG5naGnhu4dtIG3DtCBwaOG7j25nLCBn4bqnbiDEkcO6bmcgKHRoZW8gbmdoxKlhIHjhuqVwIHjhu4kpIHbhu5tpIG5naGnhu4dtIHRo4buxYyBj4bunYSBtw7QgaMOsbmguDQoNCiMjIE3DtCBwaOG7j25nIG5n4bqrdSBuaGnDqm4NCg0KS2hpIG3DtCBow6xuaCB0b8OhbiBo4buNYyBnaeG6oyDEkeG7i25oIMSRxrDhu6NjIHbhuq1uIGjDoG5oIHRoZW8gY8OhYyBxdXkgbHXhuq10IG5n4bqrdSBuaGnDqm4sIHRow6wgY8OhYyBwaMawxqFuZyBwaMOhcCBtw7QgcGjhu49uZyBjaMO6bmcgxJHGsMahYyBn4buNaSBsw6AgbcO0IHBo4buPbmcgbmfhuqt1IG5oacOqbi4NCg0KIyMgQ2h1eeG7g24gxJHhu5luZyBCcm93bg0KDQpRdcOhIHRyw6xuaCBuZ+G6q3Ugbmhpw6puIHtCKHQpOiB0ICRcZ2VxJCAwfSDEkcaw4bujYyBn4buNaSBsw6AgY2h1eeG7g24gxJHhu5luZyBCcm93biwgbuG6v3U6DQoNCjEuIEIoMCkgPSAwIGjhuqd1IGNo4bqvYyBjaOG6r24uDQoyLiB7Qih0KTogdCAkXGdlcSQgMH0gbMOgIHF1w6EgdHLDrG5oIGThu6tuZywgY8OzIHPhu5EgZ2lhIMSR4buZYyBs4bqtcA0KMy4gVuG7m2kgbeG7l2kgdCAkXGdlcSQgMCwgQih0KX5OKDAsJFxzaWdtYV4yJHQpLg0KDQpO4bq/dSAkXHNpZ21hJCA9IDEsIHRow6wge0IodCk6IHQgJFxnZXEkIDB9IGzDoCBjaHV54buDbiDEkeG7mW5nIEJyb3duIGNow61uaCB04bqvYy4ge0IodCk6IHQgJFxnZXEkIDB9IGPDsm4gxJHGsOG7o2MgZ+G7jWkgbMOgIHF1w6EgdHLDrG5oIFdpbm5lci4NCg0KKiBT4buRIGdpYTogDQoNCiMgQ2jGsMahbmcgMy4gUGjGsMahbmcgcGjDoXAgbmdoacOqbiBj4bupdSB2w6AgZOG7ryBsaeG7h3UgbmdoacOqbiBj4bupdQ0KDQojIyBCaeG6v24gxJHhuqd1IHJhDQoNClZOaSAoQ2jhu4kgc+G7kSBWTi1JbmRleCkNCg0KIyMgQmnhur9uIMSR4bqndSB2w6BvDQoNCi0gNSBiaeG6v24gxJHhuqd1IHbDoG8gY+G7p2EgYsOgaSBuZ2hpw6puIGPhu6l1IHTGsMahbmcg4bupbmcgduG7m2kgZ2nDoSA1IG3DoyBj4buRIHBoaeG6v3UgbmjDs20gbmfDoG5oIG5nw6JuIGjDoG5nIMSRxrDhu6NjIG5pw6ptIHnhur90IHRyw6puIHPDoG4gSE9TRS4NCg0KMS4gVkNCOiBNw6MgY+G7lSBwaGnhur91IGPhu6dhIE5IVE1DUCBOZ2/huqFpIHRoxrDGoW5nIFZp4buHdCBOYW0uDQoyLiBCSUQ6IE3DoyBj4buVIHBoaeG6v3UgY+G7p2EgTkhUTUNQIMSQ4bqndSB0xrAgdsOgIFBow6F0IHRyaeG7gW4gVmnhu4d0IE5hbS4NCjMuIFNIQjogTcOjIGPhu5UgcGhp4bq/dSBj4bunYSBOSFRNQ1AgU8OgaSBHw7JuIC0gSMOgIE7hu5lpLg0KNC4gSERCOiBNw6MgY+G7lSBwaGnhur91IGPhu6dhIE5IVE1DUCBQaMOhdCB0cmnhu4NuIFRQIEjhu5MgQ2jDrSBNaW5oLg0KNS4gQUNCOiBNw6MgY+G7lSBwaGnhur91IGPhu6dhIE5IVE1DUCDDgSBDaMOidS4NCg0KIyMgTcO0IGjDrG5oIG5naGnDqm4gY+G7qXUNCg0KJCQgVk5JID0gXGJldGFfMCArIFxiZXRhXzFWQ0IgKyBcYmV0YV8yQklEICsgXGJldGFfM1NIQiArIFxiZXRhXzRIREIgKyBcYmV0YV81QUNCICQkDQoNCiMjIEThu68gbGnhu4d1IG5naGnDqm4gY+G7qXUNCg0KROG7ryBsaeG7h3UgbmdoacOqbiBj4bupdSDEkcaw4bujYyB0aHUgdGjhuq1wIHThu6sgY8OhYyB0cmFuZyB3ZWIgaW52ZXN0aW5nLmNvbSB2w6AgY29waGlldTY4LnZuLCBk4buvIGxp4buHdSBiYW8gZ+G7k20gODkwIHF1YW4gc8OhdCBi4bqvdCDEkeG6p3UgdOG7qyBuZ8OgeSA5LzEvMjAyMCDEkeG6v24gbmfDoHkgMS84LzIwMjMgduG7m2kgNSBtw6MgY+G7lSBwaGnhur91IHRyb25nIG5ow7NtIG5nw6BuaCBOZ8OibiBow6BuZyBuaMawOiBWQ0IsIEJJRCwgU0hCLCBIREIsIEFDQi4NCg0KIyBDaMawxqFuZyA0LiBNw7QgcGjhu49uZyB2w6Aga+G6v3QgcXXhuqMgbmdoacOqbiBj4bupdQ0KDQojIyBUaOG7kW5nIGvDqiBtw7QgdOG6oyB2w6AgeMOhYyDEkeG7i25oIHBow6JuIHBo4buRaQ0KDQojIyMgQmnhur9uIFZDQg0KDQpgYGB7cn0NCnN1bW1hcnkodmNiKQ0Kc2QodmNiKQ0KaGlzdCh2Y2IpDQpgYGANCg0KROG7sWEgdHLDqm4ga+G6v3QgcXXhuqMgdGjhu5FuZyBrw6ogdHLDqm4sIHRhIHRo4bqleSBnacOhIGPhu5UgcGhp4bq/dSBWaWV0Y29tYmFuayBjw7MgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBsw6AgNzY2MDAgxJHhu5NuZywgZ2nDoSB0cuG7iyB0cnVuZyB24buLIGzDoCA3NjQxMyDEkeG7k25nLiBCaeG6v24gVkNCIGRhbyDEkeG7mW5nIHThu6sgZ2nDoSB0cuG7iyBuaOG7jyBuaOG6pXQgbMOgIDQzOTI1IMSR4buTbmcgxJHhur9uIGdpw6EgdHLhu4sgbOG7m24gbmjhuqV0IGzDoCAxMDY1MDAgxJHhu5NuZywgduG7m2kgxJHhu5kgbOG7h2NoIGNodeG6qW4gbMOgIDExMDI4LDc4IMSR4buTbmcuDQoNCmBgYHtyfQ0Kc2hhcGlyby50ZXN0KHZjYikNCmtzLnRlc3QodmNiLCB5PXBleHApDQprcy50ZXN0KHZjYiwgeSA9ICdwdW5pZicpDQprcy50ZXN0KHZjYiwgeSA9ICdwbG5vcm0nKQ0KYGBgDQpTYXUga2hpIGtp4buDbSDEkeG7i25oIGPDoWMgcGjDom4gcGjhu5FpIGfhu5NtOiBwaMOibiBwaOG7kWkgY2h14bqpbiwgcGjDom4gcGjhu5FpIG3FqSwgcGjDom4gcGjhu5FpIMSR4buBdSB2w6AgcGjDom4gcGjhu5FpIGxvZ2EgY2h14bqpbiBjaG8gYmnhur9uIFZDQiwgdGEgdGjhuqV5IFBfdmFsdWUgPCAwLDA1LCBuw6puIHRhIGLDoWMgYuG7jyAkSF8wJCwgdOG7qWMgbMOgIGJp4bq/biBWQ0Iga2jDtG5nIHR1w6JuIHRoZW8gY8OhYyBxdXkgbHXhuq10IHBow6JuIHBo4buRaSB0csOqbi4NCg0KIyMjIEJp4bq/biBCSUQNCg0KYGBge3J9DQpzdW1tYXJ5KGJpZCkNCnNkKGJpZCkNCmhpc3QoYmlkKQ0KYGBgDQoNCkThu7FhIHRyw6puIGvhur90IHF14bqjIHRo4buRbmcga8OqIHRyw6puLCB0YSB0aOG6pXkgZ2nDoSBj4buVIHBoaeG6v3UgQklEViBjw7MgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBsw6AgMzYzNzUgxJHhu5NuZywgZ2nDoSB0cuG7iyB0cnVuZyB24buLIGzDoCAzNTE1MCDEkeG7k25nLiBCaeG6v24gQklEIGRhbyDEkeG7mW5nIHThu6sgZ2nDoSB0cuG7iyBuaOG7jyBuaOG6pXQgbMOgIDIzOTcwIMSR4buTbmcgxJHhur9uIGdpw6EgdHLhu4sgbOG7m24gbmjhuqV0IGzDoCA0OTAwMCDEkeG7k25nLCB24bubaSDEkeG7mSBs4buHY2ggY2h14bqpbiBsw6AgNTQ0OCw1NzQgxJHhu5NuZy4NCg0KYGBge3J9DQpzaGFwaXJvLnRlc3QoYmlkKQ0Ka3MudGVzdChiaWQsIHk9cGV4cCkNCmtzLnRlc3QoYmlkLCB5ID0gJ3B1bmlmJykNCmtzLnRlc3QoYmlkLCB5ID0gJ3Bsbm9ybScpDQpgYGANCg0KU2F1IGtoaSBraeG7g20gxJHhu4tuaCBjw6FjIHBow6JuIHBo4buRaSBn4buTbTogcGjDom4gcGjhu5FpIGNodeG6qW4sIHBow6JuIHBo4buRaSBtxaksIHBow6JuIHBo4buRaSDEkeG7gXUgdsOgIHBow6JuIHBo4buRaSBsb2dhIGNodeG6qW4gY2hvIGJp4bq/biBCSUQsIHRhIHRo4bqleSBQX3ZhbHVlIDwgMCwwNSwgbsOqbiB0YSBiw6FjIGLhu48gJEhfMCQsIHThu6ljIGzDoCBiaeG6v24gQklEIGtow7RuZyB0dcOibiB0aGVvIGPDoWMgcXV5IGx14bqtdCBwaMOibiBwaOG7kWkgdHLDqm4uDQoNCiMjIyBCaeG6v24gU0hCDQoNCmBgYHtyfQ0Kc3VtbWFyeShzaGIpDQpzZChzaGIpDQpoaXN0KHNoYikNCmBgYA0KDQpE4buxYSB0csOqbiBr4bq/dCBxdeG6oyB0aOG7kW5nIGvDqiB0csOqbiwgdGEgdGjhuqV5IGdpw6EgY+G7lSBwaGnhur91IFNIQiBjw7MgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBsw6AgMTMyMTIgxJHhu5NuZywgZ2nDoSB0cuG7iyB0cnVuZyB24buLIGzDoCAxMTc2NSDEkeG7k25nLiBCaeG6v24gU0hCIGRhbyDEkeG7mW5nIHThu6sgZ2nDoSB0cuG7iyBuaOG7jyBuaOG6pXQgbMOgIDM4OTMgxJHhu5NuZyDEkeG6v24gZ2nDoSB0cuG7iyBs4bubbiBuaOG6pXQgbMOgIDIyODU5IMSR4buTbmcsIHbhu5tpIMSR4buZIGzhu4djaCBjaHXhuqluIGzDoCA0MjQzLDk0OSDEkeG7k25nLg0KDQpgYGB7cn0NCnNoYXBpcm8udGVzdChzaGIpDQprcy50ZXN0KHNoYiwgeT1wZXhwKQ0Ka3MudGVzdChzaGIsIHkgPSAncHVuaWYnKQ0Ka3MudGVzdChzaGIsIHkgPSAncGxub3JtJykNCmBgYA0KDQpTYXUga2hpIGtp4buDbSDEkeG7i25oIGPDoWMgcGjDom4gcGjhu5FpIGfhu5NtOiBwaMOibiBwaOG7kWkgY2h14bqpbiwgcGjDom4gcGjhu5FpIG3FqSwgcGjDom4gcGjhu5FpIMSR4buBdSB2w6AgcGjDom4gcGjhu5FpIGxvZ2EgY2h14bqpbiBjaG8gYmnhur9uIFNIQiwgdGEgdGjhuqV5IFBfdmFsdWUgPCAwLDA1LCBuw6puIHRhIGLDoWMgYuG7jyAkSF8wJCwgdOG7qWMgbMOgIGJp4bq/biBTSEIga2jDtG5nIHR1w6JuIHRoZW8gY8OhYyBxdXkgbHXhuq10IHBow6JuIHBo4buRaSB0csOqbi4NCg0KIyMjIEJp4bq/biBIREINCg0KYGBge3J9DQpzdW1tYXJ5KGhkYikNCnNkKGhkYikNCmhpc3QoaGRiKQ0KYGBgDQoNCkThu7FhIHRyw6puIGvhur90IHF14bqjIHRo4buRbmcga8OqIHRyw6puLCB0YSB0aOG6pXkgZ2nDoSBj4buVIHBoaeG6v3UgSERCIGPDsyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGzDoCAxNzE5MCDEkeG7k25nLCBnacOhIHRy4buLIHRydW5nIHbhu4sgbMOgIDE4MzUwIMSR4buTbmcuIEJp4bq/biBIREIgZGFvIMSR4buZbmcgdOG7qyBnacOhIHRy4buLIG5o4buPIG5o4bqldCBsw6AgNjY5MSDEkeG7k25nIMSR4bq/biBnacOhIHRy4buLIGzhu5tuIG5o4bqldCBsw6AgMjY4MDAgxJHhu5NuZywgduG7m2kgxJHhu5kgbOG7h2NoIGNodeG6qW4gbMOgIDQ1ODksMTcyIMSR4buTbmcuDQoNCmBgYHtyfQ0Kc2hhcGlyby50ZXN0KGhkYikNCmtzLnRlc3QoaGRiLCB5PXBleHApDQprcy50ZXN0KGhkYiwgeSA9ICdwdW5pZicpDQprcy50ZXN0KGhkYiwgeSA9ICdwbG5vcm0nKQ0KYGBgDQoNClNhdSBraGkga2nhu4NtIMSR4buLbmggY8OhYyBwaMOibiBwaOG7kWkgZ+G7k206IHBow6JuIHBo4buRaSBjaHXhuqluLCBwaMOibiBwaOG7kWkgbcWpLCBwaMOibiBwaOG7kWkgxJHhu4F1IHbDoCBwaMOibiBwaOG7kWkgbG9nYSBjaHXhuqluIGNobyBiaeG6v24gSERCLCB0YSB0aOG6pXkgUF92YWx1ZSA8IDAsMDUsIG7Dqm4gdGEgYsOhYyBi4buPICRIXzAkLCB04bupYyBsw6AgYmnhur9uIEhEQiBraMO0bmcgdHXDom4gdGhlbyBjw6FjIHF1eSBsdeG6rXQgcGjDom4gcGjhu5FpIHRyw6puLg0KDQojIyMgQmnhur9uIEFDQg0KDQpgYGB7cn0NCnN1bW1hcnkoYWNiKQ0Kc2QoYWNiKQ0KaGlzdChhY2IpDQpgYGANCg0KROG7sWEgdHLDqm4ga+G6v3QgcXXhuqMgdGjhu5FuZyBrw6ogdHLDqm4sIHRhIHRo4bqleSBnacOhIGPhu5UgcGhp4bq/dSBIREIgY8OzIGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggbMOgIDIxMTAwIMSR4buTbmcsIGdpw6EgdHLhu4sgdHJ1bmcgduG7iyBsw6AgMjI5MDAgxJHhu5NuZy4gQmnhur9uIEFDQiBkYW8gxJHhu5luZyB04burIGdpw6EgdHLhu4sgbmjhu48gbmjhuqV0IGzDoCA4NzYzIMSR4buTbmcgxJHhur9uIGdpw6EgdHLhu4sgbOG7m24gbmjhuqV0IGzDoCAzMDM2MCDEkeG7k25nLCB24bubaSDEkeG7mSBs4buHY2ggY2h14bqpbiBsw6AgNTY3NS44NzIgxJHhu5NuZy4NCg0KYGBge3J9DQpzaGFwaXJvLnRlc3QoYWNiKQ0Ka3MudGVzdChhY2IsIHk9cGV4cCkNCmtzLnRlc3QoYWNiLCB5ID0gJ3B1bmlmJykNCmtzLnRlc3QoYWNiLCB5ID0gJ3Bsbm9ybScpDQpgYGANCg0KU2F1IGtoaSBraeG7g20gxJHhu4tuaCBjw6FjIHBow6JuIHBo4buRaSBn4buTbTogcGjDom4gcGjhu5FpIGNodeG6qW4sIHBow6JuIHBo4buRaSBtxaksIHBow6JuIHBo4buRaSDEkeG7gXUgdsOgIHBow6JuIHBo4buRaSBsb2dhIGNodeG6qW4gY2hvIGJp4bq/biBBQ0IsIHRhIHRo4bqleSBQX3ZhbHVlIDwgMCwwNSwgbsOqbiB0YSBiw6FjIGLhu48gJEhfMCQsIHThu6ljIGzDoCBiaeG6v24gQUNCIGtow7RuZyB0dcOibiB0aGVvIGPDoWMgcXV5IGx14bqtdCBwaMOibiBwaOG7kWkgdHLDqm4uDQoNCiMjIE3DtCBwaOG7j25nIGThu68gbGnhu4d1DQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIxKQ0Kcl92Y2IgPSAoZGwkVkNCIC0gbGFnKGRsJFZDQiwgbj0xKSkvbGFnKGRsJFZDQixuPTEpDQpyX3ZjYiA8LSBuYS5vbWl0KHJfdmNiKQ0KZ2JtLmYgPSBmdW5jdGlvbihuLFMwLG11LHNpZ21hKXsNCiAgdCA9IDENCiAgdC5zID0gc2VxKDAsdCxsZW5ndGggPSBuKQ0KICBkdCA9IHQvbg0KICBCdCA9IHNxcnQodCkqY3Vtc3VtKHJub3JtKChuKSwwLDEpKQ0KICBTdCA9IFMwKmV4cCgobXUtc2lnbWFeMi8yKSp0LnMgKyBzaWdtYSpCdCkNCiAgU3QgIyBL4bq/dCBxdeG6oyBj4bunYSBHQk0NCn0NCm4gPC0gMTAwMDANClMwIDwtIHZjYlsxXQ0KbXUgPC0gKDEvKG4qKDEvbikpKSpzdW0ocl92Y2IpICN0w61uaCBs4bujaSBuaHXhuq1uIGvhu7MgduG7jW5nIGdpw6ENCnNpZ21hIDwtIHNxcnQoKHN1bSgocl92Y2IgLSBtdSleMikpKigxLyhuLTEpKigxL24pKSkgI3TDrW5oIMSR4buZIGJp4bq/biDEkeG7mW5nIGdpw6ENClZDQiA8LSBnYm0uZihuLFMwLG11LHNpZ21hKQ0KcGxvdChWQ0IsIHR5cGUgPSAnbCcsIGNvbCA9ICdibHVlJywgbWFpbiA9ICJHacOhIGPhu5UgcGhp4bq/dSBWQ0IiLCB5bGFiID0gIsSR4buTbmciLCB4bGFiID0gIk5nw6B5IikNCmBgYA0KDQpgYGB7cn0NCnNldC5zZWVkKDEyMSkNCnJfYmlkID0gKGRsJEJJRCAtIGxhZyhkbCRCSUQpKS9sYWcoZGwkQklEKQ0Kcl9iaWQgPC0gbmEub21pdChyX2JpZCkNCmdibS5mID0gZnVuY3Rpb24obixTMCxtdSxzaWdtYSl7DQogIHQgPSAxDQogIHQucyA9IHNlcSgwLHQsbGVuZ3RoID0gbikNCiAgZHQgPSB0L24NCiAgQnQgPSBzcXJ0KHQpKmN1bXN1bShybm9ybSgobiksMCwxKSkNCiAgU3QgPSBTMCpleHAoKG11LXNpZ21hXjIvMikqdC5zICsgc2lnbWEqQnQpDQogIFN0ICMgS+G6v3QgcXXhuqMgY+G7p2EgR0JNDQp9DQpuIDwtIDEwMDAwDQpTMCA8LSBiaWRbMV0NCm11IDwtICgxLyhuKigxL24pKSkqc3VtKHJfYmlkKSAjdMOtbmggbOG7o2kgbmh14bqtbiBr4buzIHbhu41uZyBnacOhDQpzaWdtYSA8LSBzcXJ0KChzdW0oKHJfYmlkIC0gbXUpXjIpKSooMS8obi0xKSooMS9uKSkpICN0w61uaCDEkeG7mSBiaeG6v24gxJHhu5luZyBnacOhDQpCSUQgPC0gZ2JtLmYobixTMCxtdSxzaWdtYSkNCnBsb3QoQklELCB0eXBlID0gJ2wnLCBjb2wgPSAnYmx1ZScsIG1haW4gPSAiR2nDoSBj4buVIHBoaeG6v3UgQklEIiwgeWxhYiA9ICLEkeG7k25nIiwgeGxhYiA9ICJOZ8OgeSIpDQpgYGANCg0KYGBge3J9DQpzZXQuc2VlZCgxMjEpDQpyX3NoYiA9IChkbCRTSEIgLSBsYWcoZGwkU0hCKSkvbGFnKGRsJFNIQikNCnJfc2hiIDwtIG5hLm9taXQocl9zaGIpDQpnYm0uZiA9IGZ1bmN0aW9uKG4sUzAsbXUsc2lnbWEpew0KICB0ID0gMQ0KICB0LnMgPSBzZXEoMCx0LGxlbmd0aCA9IG4pDQogIGR0ID0gdC9uDQogIEJ0ID0gc3FydCh0KSpjdW1zdW0ocm5vcm0oKG4pLDAsMSkpDQogIFN0ID0gUzAqZXhwKChtdS1zaWdtYV4yLzIpKnQucyArIHNpZ21hKkJ0KQ0KICBTdCAjIEvhur90IHF14bqjIGPhu6dhIEdCTQ0KfQ0KbiA8LSAxMDAwMA0KUzAgPC0gc2hiWzFdDQptdSA8LSAoMS8obiooMS9uKSkpKnN1bShyX3NoYikgI3TDrW5oIGzhu6NpIG5odeG6rW4ga+G7syB24buNbmcgZ2nDoQ0Kc2lnbWEgPC0gc3FydCgoc3VtKChyX3NoYiAtIG11KV4yKSkqKDEvKG4tMSkqKDEvbikpKSAjdMOtbmggxJHhu5kgYmnhur9uIMSR4buZbmcgZ2nDoQ0KU0hCIDwtIGdibS5mKG4sUzAsbXUsc2lnbWEpDQpwbG90KFNIQiwgdHlwZSA9ICdsJywgY29sID0gJ2JsdWUnLCBtYWluID0gIkdpw6EgY+G7lSBwaGnhur91IFNIQiIsIHlsYWIgPSAixJHhu5NuZyIsIHhsYWIgPSAiTmfDoHkiKQ0KYGBgDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIxKQ0Kcl9oZGIgPSAoZGwkSERCIC0gbGFnKGRsJEhEQikpL2xhZyhkbCRIREIpDQpyX2hkYiA8LSBuYS5vbWl0KHJfaGRiKQ0KZ2JtLmYgPSBmdW5jdGlvbihuLFMwLG11LHNpZ21hKXsNCiAgdCA9IDENCiAgdC5zID0gc2VxKDAsdCxsZW5ndGggPSBuKQ0KICBkdCA9IHQvbg0KICBCdCA9IHNxcnQodCkqY3Vtc3VtKHJub3JtKChuKSwwLDEpKQ0KICBTdCA9IFMwKmV4cCgobXUtc2lnbWFeMi8yKSp0LnMgKyBzaWdtYSpCdCkNCiAgU3QgIyBL4bq/dCBxdeG6oyBj4bunYSBHQk0NCn0NCm4gPC0gMTAwMDANClMwIDwtIGhkYlsxXQ0KbXUgPC0gKDEvKG4qKDEvbikpKSpzdW0ocl9oZGIpICN0w61uaCBs4bujaSBuaHXhuq1uIGvhu7MgduG7jW5nIGdpw6ENCnNpZ21hIDwtIHNxcnQoKHN1bSgocl9oZGIgLSBtdSleMikpKigxLyhuLTEpKigxL24pKSkgI3TDrW5oIMSR4buZIGJp4bq/biDEkeG7mW5nIGdpw6ENCkhEQiA8LSBnYm0uZihuLFMwLG11LHNpZ21hKQ0KcGxvdChIREIsIHR5cGUgPSAnbCcsIGNvbCA9ICdibHVlJywgbWFpbiA9ICJHacOhIGPhu5UgcGhp4bq/dSBIREIiLCB5bGFiID0gIsSR4buTbmciLCB4bGFiID0gIk5nw6B5IikNCmBgYA0KDQpgYGB7cn0NCnNldC5zZWVkKDEyMSkNCnJfYWNiID0gKGRsJEFDQiAtIGxhZyhkbCRBQ0IpKS9sYWcoZGwkQUNCKQ0Kcl9hY2IgPC0gbmEub21pdChyX2FjYikNCmdibS5mID0gZnVuY3Rpb24obixTMCxtdSxzaWdtYSl7DQogIHQgPSAxDQogIHQucyA9IHNlcSgwLHQsbGVuZ3RoID0gbikNCiAgZHQgPSB0L24NCiAgQnQgPSBzcXJ0KHQpKmN1bXN1bShybm9ybSgobiksMCwxKSkNCiAgU3QgPSBTMCpleHAoKG11LXNpZ21hXjIvMikqdC5zICsgc2lnbWEqQnQpDQogIFN0ICMgS+G6v3QgcXXhuqMgY+G7p2EgR0JNDQp9DQpuIDwtIDEwMDAwDQpTMCA8LSBhY2JbMV0NCm11IDwtICgxLyhuKigxL24pKSkqc3VtKHJfYWNiKSAjdMOtbmggbOG7o2kgbmh14bqtbiBr4buzIHbhu41uZyBnacOhDQpzaWdtYSA8LSBzcXJ0KChzdW0oKHJfYWNiIC0gbXUpXjIpKSooMS8obi0xKSooMS9uKSkpICN0w61uaCDEkeG7mSBiaeG6v24gxJHhu5luZyBnacOhDQpBQ0IgPC0gZ2JtLmYobixTMCxtdSxzaWdtYSkNCnBsb3QoQUNCLCB0eXBlID0gJ2wnLCBjb2wgPSAnYmx1ZScsIG1haW4gPSAiR2nDoSBj4buVIHBoaeG6v3UgQUNCIiwgeWxhYiA9ICLEkeG7k25nIiwgeGxhYiA9ICJOZ8OgeSIpDQpgYGANCg0KIyMgTcO0IGjDrG5oIHRoZW8gZOG7ryBsaeG7h3UgxJHDoyBtw7QgcGjhu49uZw0KDQpgYGB7cn0NCm1oIDwtIGxtKGRsJFZOSSB+IGRsJFZDQiArIGRsJEJJRCArIGRsJFNIQiArIGRsJEFDQiArIGRsJEhEQiwgZGF0YSA9IGRsKQ0Kc3VtbWFyeShtaCkNCnZuaSA8LSA0LjU0MGUrMDIgLSAyLjY0NWUtMDMqVkNCICsyLjMxNGUtMDMqQklEICsxLjE4OGUtMDIqU0hCICsgNS4yM2UtMDIqSERCIC0gMS4xODhlLTAyKkFDQg0KcGxvdCh2bmksIHR5cGUgPSAnbCcsIGNvbCA9ICdibHVlJywgbWFpbiA9ICJDaOG7iSBz4buRIFZOLUluZGV4IiwgeWxhYiA9ICLEkWnhu4NtIiwgeGxhYiA9ICJOZ8OgeSIpDQp2bmkxID0gKHZuaSAtIGxhZyh2bmkpKQ0KcGhpZW50YW5nZ2lhIDwtIHZuaTFbdm5pMSA+IDBdDQpwaGllbmdpYW1naWEgPC0gdm5pMVt2bmkxIDwgMF0NCmxlbmd0aChwaGllbnRhbmdnaWEpDQpsZW5ndGgocGhpZW5naWFtZ2lhKQ0Kdm5pIDwtIGN1dCh2bmksIGJyZWFrcyA9IGMobWluKHZuaSksIG1lYW4odm5pKSxtYXgodm5pKSksIGxhYmVscyA9IGMoJ3RoYXAnLCdjYW8nKSkNCnRhYmxlKHZuaSkvc3VtKHRhYmxlKHZuaSkpDQpgYGANCg0KVGjDtG5nIHF1YSBi4bqjbmcgdOG6p24gc3XhuqV0IHbDoCBiaeG7g3UgxJHhu5MgduG7gSBjaOG7iSBz4buRIFZOLUluZGV4LCDEkcaw4bujYyBtw7QgcGjhu49uZyBi4bufaSA1IG3DoyBj4buVIHBoaeG6v3UgTmfDom4gaMOgbmcsIHRhIHRo4bqleSBjaOG7iSBz4buRIFZOLUluZGV4IGPDsyBuZ8OgeSB2xrDhu6N0IG3hu5FjIHF1YSAxNDAwIMSRaeG7g20gdsOgIHRo4bqlcCBuaOG6pXQgeOG6pXAgeOG7iSA4MDAgxJFp4buDbSwgY8OzIHRo4buDIHRo4bqleSB04burIGJp4buDdSDEkeG7kyB0aMOsIGNo4buJIHPhu5EgVk5JIGPDsyB4dSBoxrDhu5tuZyBiaeG6v24gxJHhu5luZyBs4bubbiwgbmjGsG5nIGPDoWMgcGhpw6puIGPDsyBjaOG7iSBz4buRIHRyw6puIDEwMDAgxJFp4buDbSBsw6AgaMahbiA2MDAwIG5nw6B5LiBUcm9uZyDEkcOzLCB4w6FjIHN14bqldCBWTkkgdGjhuqVwIGzDoCAwLDQ1MDQ0NSB2w6AgeMOhYyBzdeG6pXQgVk5JIGNhbyBsw6AgMCw1NDk1NTUuIENo4buJIHPhu5EgVk5JIHNhdSBtw7QgcGjhu49uZyBjw7MgNTE4NSBwaGnDqm4gdMSDbmcgZ2nDoSB2w6AgNDgxNiBwaGnDqm4gZ2nhuqNtIGdpw6EuDQoNCiMgQ2jGsMahbmcgNS4gS+G6v3QgbHXhuq1uDQo=