Handling Missing
Values
Engagement in
Learning Missing Values
First I will handle the missing values for the engagement in learning
portion, which is questions 4.1 - 4.21. I created a separate data set
for called “EIL”, then I imputed the missing value of this data set by
replacing the missing value in each of the 12 items with the mode of the
corresponding survey items.
EIL<- survey[, c("q41", "q42", "q43", "q44", "q45", "q46", "q47", "q48", "q49", "q410", "q411", "q412", "q413", "q414", "q415", "q416", "q417", "q418", "q419", "q420", "q421")]
for (i in 1:21) {
EIL[,i][is.na(EIL[,i])]=my.mode(EIL[,i])
}
I will do the same for the next five survey components since none of
them contain too many missing values…
Student engagement in learning…
SLS<- survey[, c("q51", "q52", "q53", "q54", "q55", "q56")]
for (i in 1:6) {
SLS[,i][is.na(SLS[,i])]=my.mode(SLS[,i])
}
writing and reading load…
WRL<- survey[, c("q61", "q62", "q63")]
for (i in 1:3) {
WRL[,i][is.na(WRL[,i])]=my.mode(WRL[,i])
}
Remedial experience…
RE<- survey[, c("q81", "q82", "q83", "q84", "q85", "q86", "q87", "q88", "q89")]
for (i in 1:9) {
RE[,i][is.na(RE[,i])]=my.mode(RE[,i])
}
encouragement and support…
EAS<- survey[, c("q91", "q92", "q93", "q94", "q95", "q96", "q97")]
for (i in 1:7) {
EAS[,i][is.na(EAS[,i])]=my.mode(EAS[,i])
}
growth and development
GAD<- survey[, c("q101", "q102", "q103", "q104", "q105", "q106", "q107", "q108", "q109", "q1010", "q1011", "q1012", "q1013", "q1014", "q1015")]
for (i in 1:15) {
GAD[,i][is.na(GAD[,i])]=my.mode(GAD[,i])
}
Validity and
Reliability Analyses
Next, I am going to report the measures of validity and reliability
on each of the six components. I will do this by firsts looking at
correlation plots to see the relevance of the PCA procedure. I will then
calculate Cronbach’s alpha and 95% confidence intervals.
Engagement in
Learning Questionaire
##
M=cor(EIL)
corrplot.mixed(M, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)
The chart shows the moderate association between individual survey
items. This implies that the PCA is relevant in aggregating the
information in the survey items.
cronbach.sc = as.numeric(alpha(EIL)$total[1])
CI.sc = cronbach.alpha.CI(alpha=cronbach.sc, n=104, items=6, conf.level = 0.95)
CI.comp = cbind(LCI = CI.sc[1], alpha = cronbach.sc, UCI =CI.sc[2])
row.names(CI.comp) = ""
pander(CI.comp, caption="Confodence Interval of Cranbach Alpha")
Confodence Interval of Cranbach Alpha Here, Cronbach’s alpha is
0.878, with a confidence interval of (0.838, 0.911), suggesting that the
items in the engagement in learning component have relatively high
internal consistency.
0.8377 |
0.878 |
0.911 |
Students Learning
Style
##
M1=cor(SLS)
corrplot.mixed(M1, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)
cronbach.sc = as.numeric(alpha(SLS)$total[1])
CI.sc = cronbach.alpha.CI(alpha=cronbach.sc, n=104, items=6, conf.level = 0.95)
CI.comp = cbind(LCI = CI.sc[1], alpha = cronbach.sc, UCI =CI.sc[2])
row.names(CI.comp) = ""
pander(CI.comp, caption="Confodence Interval of Cranbach Alpha")
Confodence Interval of Cranbach Alpha Here, Cronbach’s alpha is
0.8474, with a confidence interval of (0.797, 0.8887), suggesting that
the items in the engagement in learning component have relatively high
internal consistency.
0.797 |
0.8474 |
0.8887 |
Writing and Reading
Load
##
M2=cor(WRL)
corrplot.mixed(M2, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)
cronbach.sc = as.numeric(alpha(WRL)$total[1])
CI.sc = cronbach.alpha.CI(alpha=cronbach.sc, n=104, items=6, conf.level = 0.95)
CI.comp = cbind(LCI = CI.sc[1], alpha = cronbach.sc, UCI =CI.sc[2])
row.names(CI.comp) = ""
pander(CI.comp, caption="Confodence Interval of Cranbach Alpha")
Confodence Interval of Cranbach Alpha
0.3234 |
0.4913 |
0.6291 |
Here, Cronbach’s alpha is 0.491, with a confidence interval of
(0.3234, 0.6291), suggesting that the items in the engagement in
learning component have relatively low internal consistency. This
suggests that the reading and writing load component of this survey is
not reliable.
Remidial
Experience
##
M3=cor(RE)
corrplot.mixed(M3, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)
cronbach.sc = as.numeric(alpha(RE)$total[1])
CI.sc = cronbach.alpha.CI(alpha=cronbach.sc, n=104, items=6, conf.level = 0.95)
CI.comp = cbind(LCI = CI.sc[1], alpha = cronbach.sc, UCI =CI.sc[2])
row.names(CI.comp) = ""
pander(CI.comp, caption="Confodence Interval of Cranbach Alpha")
Confodence Interval of Cranbach Alpha Here, Cronbach’s alpha is
0.807, with a confidence interval of (0.744, 0.859), suggesting that the
items in the engagement in learning component have relatively high
internal consistency.
0.7436 |
0.8072 |
0.8594 |
Encouregment and
Support
##
M4=cor(EAS)
corrplot.mixed(M4, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)
cronbach.sc = as.numeric(alpha(EAS)$total[1])
CI.sc = cronbach.alpha.CI(alpha=cronbach.sc, n=104, items=6, conf.level = 0.95)
CI.comp = cbind(LCI = CI.sc[1], alpha = cronbach.sc, UCI =CI.sc[2])
row.names(CI.comp) = ""
pander(CI.comp, caption="Confodence Interval of Cranbach Alpha")
Confodence Interval of Cranbach Alpha Here, Cronbach’s alpha is
0.833, with a confidence interval of (0.778, 0.878), suggesting that the
items in the engagement in learning component have relatively high
internal consistency.
0.778 |
0.8331 |
0.8783 |
Growth and
Development
##
M5=cor(GAD)
corrplot.mixed(M5, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)
cronbach.sc = as.numeric(alpha(GAD)$total[1])
CI.sc = cronbach.alpha.CI(alpha=cronbach.sc, n=104, items=6, conf.level = 0.95)
CI.comp = cbind(LCI = CI.sc[1], alpha = cronbach.sc, UCI =CI.sc[2])
row.names(CI.comp) = ""
pander(CI.comp, caption="Confodence Interval of Cranbach Alpha")
Confodence Interval of Cranbach Alpha Here, Cronbach’s alpha is
0.947, with a confidence interval of (0.929, 0.961), suggesting that the
items in the engagement in learning component have relatively high
internal consistency.
0.9292 |
0.9468 |
0.9612 |
PCA
This section report the results of the principle component analysis.
The significant PCs will be added to the analytic data set for future
modeling. But before this I will define the following two R functions
and use them in the PCA analysis. Then, the my.loadings.var is used to
extract the proportion of variance and My.
My.plotnScree = function(mat, legend = TRUE, method ="factors", main){
# mat = data matrix
# method = c("factors", "components"), default is "factors".
# main = title of the plot
ev <- eigen(cor(mat)) # get eigenvalues
ap <- parallel(subject=nrow(mat),var=ncol(mat), rep=5000,cent=.05)
nScree = nScree(x=ev$values, aparallel=ap$eigen$qevpea, model=method)
##
if (!inherits(nScree, "nScree"))
stop("Method is only for nScree objects")
if (nScree$Model == "components")
nkaiser = "Eigenvalues > mean: n = "
if (nScree$Model == "factors")
nkaiser = "Eigenvalues > zero: n = "
# axis labels
xlab = nScree$Model
ylab = "Eigenvalues"
##
par(col = 1, pch = 18)
par(mfrow = c(1, 1))
eig <- nScree$Analysis$Eigenvalues
k <- 1:length(eig)
plot(1:length(eig), eig, type="b", main = main,
xlab = xlab, ylab = ylab, ylim=c(0, 1.2*max(eig)))
#
nk <- length(eig)
noc <- nScree$Components$noc
vp.p <- lm(eig[c(noc + 1, nk)] ~ k[c(noc + 1, nk)])
x <- sum(c(1, 1) * coef(vp.p))
y <- sum(c(1, nk) * coef(vp.p))
par(col = 10)
lines(k[c(1, nk)], c(x, y))
par(col = 11, pch = 20)
lines(1:nk, nScree$Analysis$Par.Analysis, type = "b")
if (legend == TRUE) {
leg.txt <- c(paste(nkaiser, nScree$Components$nkaiser),
c(paste("Parallel Analysis: n = ", nScree$Components$nparallel)),
c(paste("Optimal Coordinates: n = ", nScree$Components$noc)),
c(paste("Acceleration Factor: n = ", nScree$Components$naf))
)
legend("topright", legend = leg.txt, pch = c(18, 20, NA, NA),
text.col = c(1, 3, 2, 4),
col = c(1, 3, 2, 4), bty="n", cex=0.7)
}
naf <- nScree$Components$naf
text(x = noc, y = eig[noc], label = " (OC)", cex = 0.7,
adj = c(0, 0), col = 2)
text(x = naf + 1, y = eig[naf + 1], label = " (AF)",
cex = 0.7, adj = c(0, 0), col = 4)
}
My.loadings.var <- function(mat, nfct, method="fa"){
# mat = data matrix
# nfct = number of factors or components
# method = c("fa", "pca"), default = is "fa".
if(method == "fa"){
f1 <- factanal(mat, factors = nfct, rotation = "varimax")
x <- loadings(f1)
vx <- colSums(x^2)
varSS = rbind('SS loadings' = vx,
'Proportion Var' = vx/nrow(x),
'Cumulative Var' = cumsum(vx/nrow(x)))
weight = f1$loadings[]
} else if (method == "pca"){
pca <- prcomp(mat, center = TRUE, scale = TRUE)
varSS = summary(pca)$importance[,1:nfct]
weight = pca$rotation[,1:nfct]
}
list(Loadings = weight, Prop.Var = varSS)
}
Now, we can perform PCA analysis on each of the six survey
components…
PCA For EIL
Component
My.plotnScree(mat=EIL, legend = TRUE, method ="components",
main="Determination of Number of Components\n EIL (Positive)")

First, I am going to extract the factors of the first two PCAs. The
PCA factor loadings and the proportion of variance explained by the
retained PCAs are summarized in the following tables.
Loadings = My.loadings.var(mat=EIL, nfct=2, method="pca")$Loadings
#
# pca loadings
kable(round(Loadings,3),
caption="Factor of the first few PCAs and the cumulative proportion
of variation explained by the corresponding PCAs in the EIL component.")
Factor of the first few PCAs and the cumulative proportion of
variation explained by the corresponding PCAs in the EIL
component.
q41 |
0.196 |
0.116 |
q42 |
0.253 |
0.192 |
q43 |
0.211 |
0.184 |
q44 |
0.231 |
0.209 |
q45 |
0.093 |
-0.391 |
q46 |
0.223 |
0.193 |
q47 |
0.239 |
0.108 |
q48 |
0.150 |
-0.246 |
q49 |
0.210 |
-0.319 |
q410 |
0.174 |
0.154 |
q411 |
0.232 |
0.226 |
q412 |
0.266 |
0.105 |
q413 |
0.270 |
-0.027 |
q414 |
0.272 |
-0.189 |
q415 |
0.266 |
0.174 |
q416 |
0.220 |
0.094 |
q417 |
0.237 |
-0.300 |
q418 |
0.257 |
-0.070 |
q419 |
0.185 |
-0.273 |
q420 |
0.199 |
-0.257 |
q421 |
0.035 |
-0.335 |
VarProp = My.loadings.var(mat=EIL, nfct=2, method="pca")$Prop.Var
# pca loadings
kable(round(VarProp,3),
caption="Cumulative and proportion of variances explained by each
the principal component in EIL.")
Cumulative and proportion of variances explained by each the
principal component in EIL.
Standard deviation |
2.533 |
1.366 |
Proportion of Variance |
0.306 |
0.089 |
Cumulative Proportion |
0.306 |
0.394 |
The Scree type of test suggests retaining a single factor. The
proportion of total variation is lower than that of PCA.I used the PCA
method and extract the first two principal components for future
analysis. The table above shows the factor loadings of the first two
principal components. We can see that each of the original items
contributes to the two PCAs evenly in terms of the magnitude. The first
PCA counts about 30.6% of the total variation and the second PCA counts
8.9% of the total variation This suggests that we should retain a simple
factor.
pca1 <- prcomp(EIL, center = TRUE, scale = TRUE)
eil.idx = pca1$x[,1]
##
hist(eil.idx,
main="Distribution of Engagement in Learning Index",
breaks = seq(min(eil.idx), max(eil.idx), length=9),
xlab="EIL Index",
xlim=range(eil.idx),
border="red",
col="lightblue",
freq=FALSE
)

PCA For SLS
Component
My.plotnScree(mat=SLS, legend = TRUE, method ="components",
main="Determination of Number of Components\n SLS (Positive)")

Loadings = My.loadings.var(mat=SLS, nfct=2, method="pca")$Loadings
#
# pca loadings
kable(round(Loadings,3),
caption="Factor of the first few PCAs and the cumulative proportion
of variation explained by the corresponding PCAs in the SLS component.")
Factor of the first few PCAs and the cumulative proportion of
variation explained by the corresponding PCAs in the SLS
component.
q51 |
0.272 |
-0.881 |
q52 |
0.424 |
-0.147 |
q53 |
0.455 |
-0.014 |
q54 |
0.413 |
0.362 |
q55 |
0.455 |
0.229 |
q56 |
0.403 |
0.135 |
VarProp = My.loadings.var(mat=SLS, nfct=2, method="pca")$Prop.Var
# pca loadings
kable(round(VarProp,3),
caption="Cumulative and proportion of variances explained by each
the principal component in SLS.")
Cumulative and proportion of variances explained by each the
principal component in SLS.
Standard deviation |
1.868 |
0.929 |
Proportion of Variance |
0.582 |
0.144 |
Cumulative Proportion |
0.582 |
0.726 |
The table above shows the factor loadings of the first two principal
components. We can see that each of the original items contributes to
the two PCAs evenly in terms of the magnitude. The first PCA counts
about 58.2% of the total variation and the second PCA counts 14.4% of
the total variation This suggests that we should retain a simple
factor.
pca2 <- prcomp(SLS, center = TRUE, scale = TRUE)
sls.idx = pca2$x[,1]
##
hist(sls.idx,
main="Distribution of Student Learning Index",
breaks = seq(min(sls.idx), max(sls.idx), length=9),
xlab="SLS Index",
xlim=range(sls.idx),
border="red",
col="lightblue",
freq=FALSE
)

PCA For WRL
Component
My.plotnScree(mat=WRL, legend = TRUE, method ="components",
main="Determination of Number of Components\n SLS (Positive)")

Loadings = My.loadings.var(mat=WRL, nfct=2, method="pca")$Loadings
#
# pca loadings
kable(round(Loadings,3),
caption="Factor of the first few PCAs and the cumulative proportion
of variation explained by the corresponding PCAs in the WRL component.")
Factor of the first few PCAs and the cumulative proportion of
variation explained by the corresponding PCAs in the WRL
component.
q61 |
-0.676 |
0.174 |
q62 |
-0.326 |
-0.942 |
q63 |
-0.661 |
0.287 |
VarProp = My.loadings.var(mat=WRL, nfct=2, method="pca")$Prop.Var
# pca loadings
kable(round(VarProp,3),
caption="Cumulative and proportion of variances explained by each
the principal component in WRL.")
Cumulative and proportion of variances explained by each the
principal component in WRL.
Standard deviation |
1.233 |
0.970 |
Proportion of Variance |
0.507 |
0.314 |
Cumulative Proportion |
0.507 |
0.821 |
The table above shows the factor loadings of the first two principal
components. We can see that each of the original items contributes to
the two PCAs evenly in terms of the magnitude. The first PCA counts
about 50.7% of the total variation and the second PCA counts 31.4%% of
the total variation This suggests that we should retain a simple
factor.
pca3 <- prcomp(WRL, center = TRUE, scale = TRUE)
wrl.idx = pca3$x[,1]
##
hist(wrl.idx,
main="Distribution of Writing and Reading Load Index",
breaks = seq(min(wrl.idx), max(wrl.idx), length=9),
xlab="WRL Index",
xlim=range(wrl.idx),
border="red",
col="lightblue",
freq=FALSE
)

PCA For RE
Component
My.plotnScree(mat=RE, legend = TRUE, method ="components",
main="Determination of Number of Components\n RE (Positive)")

Loadings = My.loadings.var(mat=RE, nfct=2, method="pca")$Loadings
#
# pca loadings
kable(round(Loadings,3),
caption="Factor of the first few PCAs and the cumulative proportion
of variation explained by the corresponding PCAs in the RE component.")
Factor of the first few PCAs and the cumulative proportion of
variation explained by the corresponding PCAs in the RE
component.
q81 |
0.214 |
-0.449 |
q82 |
0.321 |
0.076 |
q83 |
0.420 |
0.288 |
q84 |
0.412 |
0.344 |
q85 |
0.359 |
0.422 |
q86 |
0.351 |
-0.060 |
q87 |
0.287 |
-0.323 |
q88 |
0.275 |
-0.376 |
q89 |
0.309 |
-0.405 |
VarProp = My.loadings.var(mat=RE, nfct=2, method="pca")$Prop.Var
# pca loadings
kable(round(VarProp,3),
caption="Cumulative and proportion of variances explained by each
the principal component in RE.")
Cumulative and proportion of variances explained by each the
principal component in RE.
Standard deviation |
1.907 |
1.162 |
Proportion of Variance |
0.404 |
0.150 |
Cumulative Proportion |
0.404 |
0.554 |
The table above shows the factor loadings of the first two principal
components. We can see that each of the original items contributes to
the two PCAs evenly in terms of the magnitude. The first PCA counts
about 40.4% of the total variation and the second PCA counts 15% of the
total variation This suggests that we should retain a simple factor.
pca4 <- prcomp(RE, center = TRUE, scale = TRUE)
re.idx = pca4$x[,1]
##
hist(re.idx,
main="Distribution of Remidial Experience Index",
breaks = seq(min(re.idx), max(re.idx), length=9),
xlab="RE Index",
xlim=range(re.idx),
border="red",
col="lightblue",
freq=FALSE
)

Here, since the RE index distribution is screwed to the left. We can
perform a box cox transformation to fix this.
M1=cor(cbind(eil.idx, EIL, sls.idx, SLS, wrl.idx, WRL))
#corrplot(M, type = "upper", method = "ellipse", main="Pairwise Correlation Plot: Self-Compassion Scale")
corrplot.mixed(M1, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)

PCA For EAS
Component
My.plotnScree(mat=EAS, legend = TRUE, method ="components",
main="Determination of Number of Components\n SLS (Positive)")

Loadings = My.loadings.var(mat=EAS, nfct=2, method="pca")$Loadings
#
# pca loadings
kable(round(Loadings,3),
caption="Factor of the first few PCAs and the cumulative proportion
of variation explained by the corresponding PCAs in the EAS component.")
Factor of the first few PCAs and the cumulative proportion of
variation explained by the corresponding PCAs in the EAS
component.
q91 |
-0.289 |
0.546 |
q92 |
-0.414 |
0.079 |
q93 |
-0.416 |
-0.117 |
q94 |
-0.430 |
-0.331 |
q95 |
-0.435 |
-0.238 |
q96 |
-0.371 |
-0.179 |
q97 |
-0.245 |
0.695 |
VarProp = My.loadings.var(mat=EAS, nfct=2, method="pca")$Prop.Var
# pca loadings
kable(round(VarProp,3),
caption="Cumulative and proportion of variances explained by each
the principal component in EAS.")
Cumulative and proportion of variances explained by each the
principal component in EAS.
Standard deviation |
1.880 |
1.002 |
Proportion of Variance |
0.505 |
0.144 |
Cumulative Proportion |
0.505 |
0.648 |
The table above shows the factor loadings of the first two principal
components. We can see that each of the original items contributes to
the two PCAs evenly in terms of the magnitude. The first PCA counts
about 50.5% of the total variation and the second PCA counts 14.4% of
the total variation This suggests that we should retain a simple
factor.
pca5 <- prcomp(EAS, center = TRUE, scale = TRUE)
eas.idx = pca5$x[,1]
##
hist(eas.idx,
main="Distribution of Encouragment and Support Index",
breaks = seq(min(eas.idx), max(eas.idx), length=9),
xlab="EAS Index",
xlim=range(eas.idx),
border="red",
col="lightblue",
freq=FALSE
)

PCA For GAD
Component
My.plotnScree(mat=GAD, legend = TRUE, method ="components",
main="Determination of Number of Components\n GAD (Positive)")

Loadings = My.loadings.var(mat=GAD, nfct=2, method="pca")$Loadings
#
# pca loadings
kable(round(Loadings,3),
caption="Factor of the first few PCAs and the cumulative proportion
of variation explained by the corresponding PCAs in the GAD component.")
Factor of the first few PCAs and the cumulative proportion of
variation explained by the corresponding PCAs in the GAD
component.
q101 |
-0.246 |
0.327 |
q102 |
-0.246 |
0.282 |
q103 |
-0.267 |
0.231 |
q104 |
-0.278 |
0.138 |
q105 |
-0.275 |
0.289 |
q106 |
-0.229 |
0.284 |
q107 |
-0.234 |
0.244 |
q108 |
-0.262 |
-0.017 |
q109 |
-0.253 |
0.031 |
q1010 |
-0.268 |
-0.285 |
q1011 |
-0.264 |
-0.389 |
q1012 |
-0.277 |
-0.334 |
q1013 |
-0.254 |
-0.251 |
q1014 |
-0.262 |
-0.241 |
q1015 |
-0.252 |
-0.225 |
VarProp = My.loadings.var(mat=GAD, nfct=2, method="pca")$Prop.Var
# pca loadings
kable(round(VarProp,3),
caption="Cumulative and proportion of variances explained by each
the principal component in GAD.")
Cumulative and proportion of variances explained by each the
principal component in GAD.
Standard deviation |
2.943 |
1.117 |
Proportion of Variance |
0.577 |
0.083 |
Cumulative Proportion |
0.577 |
0.661 |
The table above shows the factor loadings of the first two principal
components. We can see that each of the original items contributes to
the two PCAs evenly in terms of the magnitude. The first PCA counts
about 57.7% of the total variation and the second PCA counts 8.3% of the
total variation This suggests that we should retain a simple factor.
pca6 <- prcomp(GAD, center = TRUE, scale = TRUE)
gad.idx = pca6$x[,1]
##
hist(gad.idx,
main="Distribution of Growth and Developement Index",
breaks = seq(min(gad.idx), max(gad.idx), length=9),
xlab="GAD Index",
xlim=range(gad.idx),
border="red",
col="lightblue",
freq=FALSE
)

LS0tDQp0aXRsZTogIlJpc2sgU3VydmV5IEFuYWx5c2lzIGFuZCBRdWVzdGlvbnMiDQphdXRob3I6ICdBdmEgRGVTdGVmYW5vJw0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgZmlnX3dpZHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQogIHdvcmRfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGtlZXBfbWQ6IHllcw0KICBwZGZfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgZmlnX3dpZHRoOiAzDQogICAgZmlnX2hlaWdodDogMw0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQphbHdheXNfYWxsb3dfaHRtbDogdHJ1ZQ0KLS0tDQpgYGB7PWh0bWx9DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQpkaXYjVE9DIGxpIHsNCiAgICBsaXN0LXN0eWxlOm5vbmU7DQogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOw0KICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7DQogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOw0KfQ0KaDEudGl0bGUgew0KICBmb250LXNpemU6IDI0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgyIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQo8L3N0eWxlPg0KYGBgDQoNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICAgbGlicmFyeSh0aWR5dmVyc2UpDQp9DQppZiAoIXJlcXVpcmUoIkdQQXJvdGF0aW9uIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIkdQQXJvdGF0aW9uIikNCiAgIGxpYnJhcnkoR1BBcm90YXRpb24pDQp9DQppZiAoIXJlcXVpcmUoIm5GYWN0b3JzIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIm5GYWN0b3JzIikNCiAgIGxpYnJhcnkobkZhY3RvcnMpDQp9DQppZiAoIXJlcXVpcmUoInBhcmFtZXRlcnMiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGFyYW1ldGVycyIpDQogICBsaWJyYXJ5KHBhcmFtZXRlcnMpDQp9DQppZiAoIXJlcXVpcmUoImNvcnJwbG90IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImNvcnJwbG90IikNCiAgIGxpYnJhcnkoY29ycnBsb3QpDQp9DQppZiAoIXJlcXVpcmUoImdnY29ycnBsb3QiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2djb3JycGxvdCIpDQogICBsaWJyYXJ5KGdnY29ycnBsb3QpDQp9DQppZiAoIXJlcXVpcmUoImdnZm9ydGlmeSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJnZ2ZvcnRpZnkiKQ0KICAgbGlicmFyeShnZ2ZvcnRpZnkpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQogICBsaWJyYXJ5KGdncGxvdDIpDQp9DQppZiAoIXJlcXVpcmUoIkdHYWxseSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJHR2FsbHkiKQ0KICAgbGlicmFyeShHR2FsbHkpDQp9DQoNCmlmICghcmVxdWlyZSgiQ0NBIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIkNDQSIpDQogICBsaWJyYXJ5KENDQSkNCn0NCmlmICghcmVxdWlyZSgib2xzcnIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygib2xzcnIiKQ0KICAgbGlicmFyeShvbHNycikNCn0NCmlmICghcmVxdWlyZSgicHN5Y2giKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicHN5Y2giKQ0KICAgbGlicmFyeShwc3ljaCkNCn0NCmlmICghcmVxdWlyZSgiY29jcm9uIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImNvY3JvbiIpDQogICBsaWJyYXJ5KGNvY3JvbikNCn0NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgicGFuZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBhbmRlciIpDQogICBsaWJyYXJ5KHBhbmRlcikNCn0NCmlmICghcmVxdWlyZSgiZHBseXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKQ0KICAgbGlicmFyeShkcGx5cikNCn0NCiMjDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmdzID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy5hbGlnbj0nY2VudGVyJywgDQogICAgICAgICAgICAgICAgICAgICAgZmlnLnBvcyA9ICdodCcpDQpgYGANCg0KDQojIEludHJvZHVjdGlvbiANCg0KVGhlIGRhdGEgdGhhdCB3aWxsIGJlIHVzZWQgaW4gdGhpcyBhbmFseXNpcyB3YXMgZXh0cmFjdGVkIGZyb20gYW4gb25saW5lIHN1cnZleS4gVGhlIHN0dWR5IHBvcHVsYXRpb24gY29uc2lzdHMgb2YgdW5kZXJncmFkdWF0ZSBidXNpbmVzcyBzdHVkZW50cyBmcm9tIHR3byBkaWZmZXJlbnQgcmVnaW9uYWwgbm9ydGhlcm4gdW5pdmVyc2l0aWVzLiBUaGUgcHVycG9zZSBvZiB0aGlzIHN0dWR5IGlzIHRvIGlkZW50aWZ5IHRoZSBmYWN0b3JzIHRoYXQgaW5mbHVlbmNlIHN0dWRlbnRz4oCZIGxlYXJuaW5nIGV4cGVyaWVuY2UgYW5kIGltcGFjdCBvbiBzdHVkZW50c+KAmSBsZWFybmluZyBvdXRjb21lcy4gRm9yIHRoaXMgYW5hbHlzaXMsIEkgYW0gZ29pbmcgdG8gZm9jdXMgb24gc2l4IGNvbXBvbmVudHMgb2YgdGhlIHN1cnZleS4gVGhlc2UgaW5jbHVkZSB0aGUgc3R1ZGVudCdzIGVuZ2FnZW1lbnQgaW4gbGVhcm5pbmcsIHRoZSBzdHVkZW50J3MgbGVhcm5pbmcgc3R5bGUsIHdyaXRpbmcgYW5kIHJlYWRpbmcgbG9hZCwgcmVtZWRpYWwgZXhwZXJpZW5jZSwgZW5jb3VyYWdlbWVudCBhbmQgc3VwcG9ydCwgYW5kIGdyb3d0aCBhbmQgZGV2ZWxvcG1lbnQuIEZvciByZWZlcmVuY2UsIHRoZXNlIGFyZSBxdWVzdGlvbnMgNCwgNSwgNiwgOCwgOSwgYW5kIDEwIHJlc3BlY3RpdmVseS4NCg0KIyMgRGF0YSBEb3dubG9hZA0KDQpGaXJzdCwgSSBhbSBnb2luZyB0byBkb3dubG9hZCB0aGUgZGF0YSBmcm9tIGdpdGh1YiwgSSBhbSBhbHNvIHJlbW92aW5nIHRoZSBvZGQgbnVtYmVyZWQgcm93cywgc2luY2UgYWxsIG9mIHRob3NlIGFyZSBibGFuaywgZ2l2aW5nIHVzIGEgdG90YWwgb2YgMzMyIG9ic2VydmF0aW9ucyBhbmQgMTIxIHZhcmlhYmxlcy4NCg0KYGBge3J9DQpzdXJ2ZXkwID0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9BdmFEZVN0L2F0cmlza3N1cnZleS9yZWZzL2hlYWRzL21haW4vYXQtcmlzay1zdXJ2ZXktZGF0YS5jc3YiLCBoZWFkID0gVFJVRSkNCg0Kc3VydmV5IDwtIHN1cnZleTBbc2VxKDIsIG5yb3coc3VydmV5MCksIGJ5ID0gMiksIF0NCg0KYGBgDQoNCg0KU2luY2UgUiBkb2VzIG5vdCBoYXZlIGEgZnVuY3Rpb24gdG8gZmluZCB0aGUgbW9kZWwgb2YgYSBnaXZlbiBkYXRhIHNldCwgSSB3cml0ZSB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uIHRvIGZpbmQgdGhlIG1vZGVsIG9mIGEgZGF0YSBzZXQuDQoNCldlIHdpbGwgcGVyZm9ybSBib3RoIHByaW5jaXBhbCBjb21wb25lbnQgYW5hbHlzaXMgKFBDQSkgYW5kIGV4cGxvcmF0b3J5IGZhY3RvciBhbmFseXNpcyAoRUZBKS4NCg0KYGBge3J9DQpteS5tb2RlID0gZnVuY3Rpb24oZGF0YXNldCl7DQogIGZyZXEudGJsID0gdGFibGUoZGF0YXNldCkNCiAgbWF4LmZyZXEuaWQ9d2hpY2goZnJlcS50Ymw9PW1heChmcmVxLnRibCkpDQogIG1vZGU9bmFtZXMoZnJlcS50YmxbbWF4LmZyZXEuaWRdKQ0KICBhcy5udW1lcmljKG1vZGUpDQp9DQpgYGANCg0KIyBIYW5kbGluZyBNaXNzaW5nIFZhbHVlcw0KDQojIyBFbmdhZ2VtZW50IGluIExlYXJuaW5nIE1pc3NpbmcgVmFsdWVzDQoNCkZpcnN0IEkgd2lsbCBoYW5kbGUgdGhlIG1pc3NpbmcgdmFsdWVzIGZvciB0aGUgZW5nYWdlbWVudCBpbiBsZWFybmluZyBwb3J0aW9uLCB3aGljaCBpcyBxdWVzdGlvbnMgNC4xIC0gNC4yMS4gSSBjcmVhdGVkIGEgc2VwYXJhdGUgZGF0YSBzZXQgZm9yIGNhbGxlZCAiRUlMIiwgdGhlbiBJIGltcHV0ZWQgdGhlIG1pc3NpbmcgdmFsdWUgb2YgdGhpcyBkYXRhIHNldCBieSByZXBsYWNpbmcgdGhlIG1pc3NpbmcgdmFsdWUgaW4gZWFjaCBvZiB0aGUgMTIgaXRlbXMgd2l0aCB0aGUgbW9kZSBvZiB0aGUgY29ycmVzcG9uZGluZyBzdXJ2ZXkgaXRlbXMuIA0KDQpgYGB7cn0NCkVJTDwtIHN1cnZleVssIGMoInE0MSIsICJxNDIiLCAicTQzIiwgInE0NCIsICJxNDUiLCAicTQ2IiwgInE0NyIsICJxNDgiLCAicTQ5IiwgInE0MTAiLCAicTQxMSIsICJxNDEyIiwgInE0MTMiLCAicTQxNCIsICJxNDE1IiwgInE0MTYiLCAicTQxNyIsICJxNDE4IiwgInE0MTkiLCAicTQyMCIsICJxNDIxIildDQoNCg0KZm9yIChpIGluIDE6MjEpIHsNCiAgRUlMWyxpXVtpcy5uYShFSUxbLGldKV09bXkubW9kZShFSUxbLGldKQ0KfQ0KYGBgDQoNCkkgd2lsbCBkbyB0aGUgc2FtZSBmb3IgdGhlIG5leHQgZml2ZSBzdXJ2ZXkgY29tcG9uZW50cyBzaW5jZSBub25lIG9mIHRoZW0gY29udGFpbiB0b28gbWFueSBtaXNzaW5nIHZhbHVlcy4uLg0KDQpTdHVkZW50IGVuZ2FnZW1lbnQgaW4gbGVhcm5pbmcuLi4NCg0KYGBge3J9DQpTTFM8LSBzdXJ2ZXlbLCBjKCJxNTEiLCAicTUyIiwgInE1MyIsICJxNTQiLCAicTU1IiwgInE1NiIpXQ0KDQpmb3IgKGkgaW4gMTo2KSB7DQogIFNMU1ssaV1baXMubmEoU0xTWyxpXSldPW15Lm1vZGUoU0xTWyxpXSkNCn0NCmBgYA0KDQp3cml0aW5nIGFuZCByZWFkaW5nIGxvYWQuLi4NCg0KYGBge3J9DQpXUkw8LSBzdXJ2ZXlbLCBjKCJxNjEiLCAicTYyIiwgInE2MyIpXQ0KDQpmb3IgKGkgaW4gMTozKSB7DQogIFdSTFssaV1baXMubmEoV1JMWyxpXSldPW15Lm1vZGUoV1JMWyxpXSkNCn0NCmBgYA0KDQpSZW1lZGlhbCBleHBlcmllbmNlLi4uDQoNCmBgYHtyfQ0KUkU8LSBzdXJ2ZXlbLCBjKCJxODEiLCAicTgyIiwgInE4MyIsICJxODQiLCAicTg1IiwgInE4NiIsICJxODciLCAicTg4IiwgInE4OSIpXQ0KDQpmb3IgKGkgaW4gMTo5KSB7DQogIFJFWyxpXVtpcy5uYShSRVssaV0pXT1teS5tb2RlKFJFWyxpXSkNCn0NCmBgYA0KDQplbmNvdXJhZ2VtZW50IGFuZCBzdXBwb3J0Li4uDQoNCmBgYHtyfQ0KRUFTPC0gc3VydmV5WywgYygicTkxIiwgInE5MiIsICJxOTMiLCAicTk0IiwgInE5NSIsICJxOTYiLCAicTk3IildDQoNCmZvciAoaSBpbiAxOjcpIHsNCiAgRUFTWyxpXVtpcy5uYShFQVNbLGldKV09bXkubW9kZShFQVNbLGldKQ0KfQ0KYGBgDQoNCmdyb3d0aCBhbmQgZGV2ZWxvcG1lbnQNCg0KYGBge3J9DQpHQUQ8LSBzdXJ2ZXlbLCBjKCJxMTAxIiwgInExMDIiLCAicTEwMyIsICJxMTA0IiwgInExMDUiLCAicTEwNiIsICJxMTA3IiwgInExMDgiLCAicTEwOSIsICJxMTAxMCIsICJxMTAxMSIsICJxMTAxMiIsICJxMTAxMyIsICJxMTAxNCIsICJxMTAxNSIpXQ0KDQpmb3IgKGkgaW4gMToxNSkgew0KICBHQURbLGldW2lzLm5hKEdBRFssaV0pXT1teS5tb2RlKEdBRFssaV0pDQp9DQpgYGANCg0KIyBWYWxpZGl0eSBhbmQgUmVsaWFiaWxpdHkgQW5hbHlzZXMNCg0KTmV4dCwgSSBhbSBnb2luZyB0byByZXBvcnQgdGhlIG1lYXN1cmVzIG9mIHZhbGlkaXR5IGFuZCByZWxpYWJpbGl0eSBvbiBlYWNoIG9mIHRoZSBzaXggY29tcG9uZW50cy4gSSB3aWxsIGRvIHRoaXMgYnkgZmlyc3RzIGxvb2tpbmcgYXQgY29ycmVsYXRpb24gcGxvdHMgdG8gc2VlIHRoZSByZWxldmFuY2Ugb2YgdGhlIFBDQSBwcm9jZWR1cmUuIEkgd2lsbCB0aGVuIGNhbGN1bGF0ZSBDcm9uYmFjaCdzIGFscGhhIGFuZCA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbHMuIA0KDQojIyBFbmdhZ2VtZW50IGluIExlYXJuaW5nIFF1ZXN0aW9uYWlyZQ0KDQpgYGB7ciBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gNiwgZmlnLmNhcD0iVGhlIHBhaXJ3aXNlIGNvcnJlbGF0aW9uIHBsb3QgcmV2ZWFscyB0aGUgcG90ZW50aWFsIHJlbGV2YW5jZSBvZiBQQ0EuIFRoZSBzaGFwZSBvZiBhbiBlbGxpcHNlIHJlcHJlc2VudHMgdGhlIGNvcnJlbGF0aW9uLiBUaGUgc2tpbm5pZXIgdGhlIGVsbGlwc2UsIHRoZSBoaWdoZXIgdGhlIGNvcnJlbGF0aW9uLiBUaGUgZGlyZWN0aW9uIHJlZmxlY3RzIHdoZXRoZXIgYSBjb3JyZWxhdGlvbiBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4gVGhlIG9mZi1kaWFnb25hbCBkaXJlY3Rpb24gaW1wbGllcyBzIHBvc2l0aXZlIGNvcnJlbGF0aW9uIHdoaWxlIHRoZSBtYWluIGRpYWdvbmFsIGRpcmVjdGlvbiBpbXBsaWVzIGEgbmVnYXRpdmUgYXNzb2NpYXRpb24uIn0NCiMjDQpNPWNvcihFSUwpDQpjb3JycGxvdC5taXhlZChNLCBsb3dlci5jb2wgPSAicHVycGxlIiwgdXBwZXIgPSAiZWxsaXBzZSIsIG51bWJlci5jZXggPSAuNywgdGwuY2V4ID0gMC43KQ0KYGBgDQoNClRoZSBjaGFydCBzaG93cyB0aGUgbW9kZXJhdGUgYXNzb2NpYXRpb24gYmV0d2VlbiBpbmRpdmlkdWFsIHN1cnZleSBpdGVtcy4gVGhpcyBpbXBsaWVzIHRoYXQgdGhlIFBDQSBpcyByZWxldmFudCBpbiBhZ2dyZWdhdGluZyB0aGUgaW5mb3JtYXRpb24gaW4gdGhlIHN1cnZleSBpdGVtcy4NCg0KYGBge3J9DQpjcm9uYmFjaC5zYyA9IGFzLm51bWVyaWMoYWxwaGEoRUlMKSR0b3RhbFsxXSkNCkNJLnNjID0gY3JvbmJhY2guYWxwaGEuQ0koYWxwaGE9Y3JvbmJhY2guc2MsIG49MTA0LCBpdGVtcz02LCBjb25mLmxldmVsID0gMC45NSkNCkNJLmNvbXAgPSBjYmluZChMQ0kgPSBDSS5zY1sxXSwgYWxwaGEgPSBjcm9uYmFjaC5zYywgVUNJID1DSS5zY1syXSkNCnJvdy5uYW1lcyhDSS5jb21wKSA9ICIiDQpwYW5kZXIoQ0kuY29tcCwgY2FwdGlvbj0iQ29uZm9kZW5jZSBJbnRlcnZhbCBvZiBDcmFuYmFjaCBBbHBoYSIpDQpgYGANCkhlcmUsIENyb25iYWNoJ3MgYWxwaGEgaXMgMC44NzgsIHdpdGggYSBjb25maWRlbmNlIGludGVydmFsIG9mICgwLjgzOCwgMC45MTEpLCBzdWdnZXN0aW5nIHRoYXQgdGhlIGl0ZW1zIGluIHRoZSBlbmdhZ2VtZW50IGluIGxlYXJuaW5nIGNvbXBvbmVudCBoYXZlIHJlbGF0aXZlbHkgaGlnaCBpbnRlcm5hbCBjb25zaXN0ZW5jeS4gDQoNCg0KDQojIyBTdHVkZW50cyBMZWFybmluZyBTdHlsZQ0KDQoNCmBgYHtyIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA2LCBmaWcuY2FwPSJUaGUgcGFpcndpc2UgY29ycmVsYXRpb24gcGxvdCByZXZlYWxzIHRoZSBwb3RlbnRpYWwgcmVsZXZhbmNlIG9mIFBDQS4gVGhlIHNoYXBlIG9mIGFuIGVsbGlwc2UgcmVwcmVzZW50cyB0aGUgY29ycmVsYXRpb24uIFRoZSBza2lubmllciB0aGUgZWxsaXBzZSwgdGhlIGhpZ2hlciB0aGUgY29ycmVsYXRpb24uIFRoZSBkaXJlY3Rpb24gcmVmbGVjdHMgd2hldGhlciBhIGNvcnJlbGF0aW9uIGlzIHBvc2l0aXZlIG9yIG5lZ2F0aXZlLiBUaGUgb2ZmLWRpYWdvbmFsIGRpcmVjdGlvbiBpbXBsaWVzIHMgcG9zaXRpdmUgY29ycmVsYXRpb24gd2hpbGUgdGhlIG1haW4gZGlhZ29uYWwgZGlyZWN0aW9uIGltcGxpZXMgYSBuZWdhdGl2ZSBhc3NvY2lhdGlvbi4ifQ0KIyMNCk0xPWNvcihTTFMpDQpjb3JycGxvdC5taXhlZChNMSwgbG93ZXIuY29sID0gInB1cnBsZSIsIHVwcGVyID0gImVsbGlwc2UiLCBudW1iZXIuY2V4ID0gLjcsIHRsLmNleCA9IDAuNykNCg0KYGBgDQoNCmBgYHtyfQ0KY3JvbmJhY2guc2MgPSBhcy5udW1lcmljKGFscGhhKFNMUykkdG90YWxbMV0pDQpDSS5zYyA9IGNyb25iYWNoLmFscGhhLkNJKGFscGhhPWNyb25iYWNoLnNjLCBuPTEwNCwgaXRlbXM9NiwgY29uZi5sZXZlbCA9IDAuOTUpDQpDSS5jb21wID0gY2JpbmQoTENJID0gQ0kuc2NbMV0sIGFscGhhID0gY3JvbmJhY2guc2MsIFVDSSA9Q0kuc2NbMl0pDQpyb3cubmFtZXMoQ0kuY29tcCkgPSAiIg0KcGFuZGVyKENJLmNvbXAsIGNhcHRpb249IkNvbmZvZGVuY2UgSW50ZXJ2YWwgb2YgQ3JhbmJhY2ggQWxwaGEiKQ0KYGBgDQpIZXJlLCBDcm9uYmFjaCdzIGFscGhhIGlzIDAuODQ3NCwgd2l0aCBhIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgKDAuNzk3LCAwLjg4ODcpLCBzdWdnZXN0aW5nIHRoYXQgdGhlIGl0ZW1zIGluIHRoZSBlbmdhZ2VtZW50IGluIGxlYXJuaW5nIGNvbXBvbmVudCBoYXZlIHJlbGF0aXZlbHkgaGlnaCBpbnRlcm5hbCBjb25zaXN0ZW5jeS4NCg0KDQojIyBXcml0aW5nIGFuZCBSZWFkaW5nIExvYWQNCg0KDQpgYGB7ciBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gNiwgZmlnLmNhcD0iVGhlIHBhaXJ3aXNlIGNvcnJlbGF0aW9uIHBsb3QgcmV2ZWFscyB0aGUgcG90ZW50aWFsIHJlbGV2YW5jZSBvZiBQQ0EuIFRoZSBzaGFwZSBvZiBhbiBlbGxpcHNlIHJlcHJlc2VudHMgdGhlIGNvcnJlbGF0aW9uLiBUaGUgc2tpbm5pZXIgdGhlIGVsbGlwc2UsIHRoZSBoaWdoZXIgdGhlIGNvcnJlbGF0aW9uLiBUaGUgZGlyZWN0aW9uIHJlZmxlY3RzIHdoZXRoZXIgYSBjb3JyZWxhdGlvbiBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4gVGhlIG9mZi1kaWFnb25hbCBkaXJlY3Rpb24gaW1wbGllcyBzIHBvc2l0aXZlIGNvcnJlbGF0aW9uIHdoaWxlIHRoZSBtYWluIGRpYWdvbmFsIGRpcmVjdGlvbiBpbXBsaWVzIGEgbmVnYXRpdmUgYXNzb2NpYXRpb24uIn0NCiMjDQpNMj1jb3IoV1JMKQ0KY29ycnBsb3QubWl4ZWQoTTIsIGxvd2VyLmNvbCA9ICJwdXJwbGUiLCB1cHBlciA9ICJlbGxpcHNlIiwgbnVtYmVyLmNleCA9IC43LCB0bC5jZXggPSAwLjcpDQpgYGANCmBgYHtyfQ0KY3JvbmJhY2guc2MgPSBhcy5udW1lcmljKGFscGhhKFdSTCkkdG90YWxbMV0pDQpDSS5zYyA9IGNyb25iYWNoLmFscGhhLkNJKGFscGhhPWNyb25iYWNoLnNjLCBuPTEwNCwgaXRlbXM9NiwgY29uZi5sZXZlbCA9IDAuOTUpDQpDSS5jb21wID0gY2JpbmQoTENJID0gQ0kuc2NbMV0sIGFscGhhID0gY3JvbmJhY2guc2MsIFVDSSA9Q0kuc2NbMl0pDQpyb3cubmFtZXMoQ0kuY29tcCkgPSAiIg0KcGFuZGVyKENJLmNvbXAsIGNhcHRpb249IkNvbmZvZGVuY2UgSW50ZXJ2YWwgb2YgQ3JhbmJhY2ggQWxwaGEiKQ0KYGBgDQoNCkhlcmUsIENyb25iYWNoJ3MgYWxwaGEgaXMgMC40OTEsIHdpdGggYSBjb25maWRlbmNlIGludGVydmFsIG9mICgwLjMyMzQsIDAuNjI5MSksIHN1Z2dlc3RpbmcgdGhhdCB0aGUgaXRlbXMgaW4gdGhlIGVuZ2FnZW1lbnQgaW4gbGVhcm5pbmcgY29tcG9uZW50IGhhdmUgcmVsYXRpdmVseSBsb3cgaW50ZXJuYWwgY29uc2lzdGVuY3kuIFRoaXMgc3VnZ2VzdHMgdGhhdCB0aGUgcmVhZGluZyBhbmQgd3JpdGluZyBsb2FkIGNvbXBvbmVudCBvZiB0aGlzIHN1cnZleSBpcyBub3QgcmVsaWFibGUuDQoNCiMjIFJlbWlkaWFsIEV4cGVyaWVuY2UNCg0KDQpgYGB7ciBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gNiwgZmlnLmNhcD0iVGhlIHBhaXJ3aXNlIGNvcnJlbGF0aW9uIHBsb3QgcmV2ZWFscyB0aGUgcG90ZW50aWFsIHJlbGV2YW5jZSBvZiBQQ0EuIFRoZSBzaGFwZSBvZiBhbiBlbGxpcHNlIHJlcHJlc2VudHMgdGhlIGNvcnJlbGF0aW9uLiBUaGUgc2tpbm5pZXIgdGhlIGVsbGlwc2UsIHRoZSBoaWdoZXIgdGhlIGNvcnJlbGF0aW9uLiBUaGUgZGlyZWN0aW9uIHJlZmxlY3RzIHdoZXRoZXIgYSBjb3JyZWxhdGlvbiBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4gVGhlIG9mZi1kaWFnb25hbCBkaXJlY3Rpb24gaW1wbGllcyBzIHBvc2l0aXZlIGNvcnJlbGF0aW9uIHdoaWxlIHRoZSBtYWluIGRpYWdvbmFsIGRpcmVjdGlvbiBpbXBsaWVzIGEgbmVnYXRpdmUgYXNzb2NpYXRpb24uIn0NCiMjDQpNMz1jb3IoUkUpDQpjb3JycGxvdC5taXhlZChNMywgbG93ZXIuY29sID0gInB1cnBsZSIsIHVwcGVyID0gImVsbGlwc2UiLCBudW1iZXIuY2V4ID0gLjcsIHRsLmNleCA9IDAuNykNCmBgYA0KYGBge3J9DQpjcm9uYmFjaC5zYyA9IGFzLm51bWVyaWMoYWxwaGEoUkUpJHRvdGFsWzFdKQ0KQ0kuc2MgPSBjcm9uYmFjaC5hbHBoYS5DSShhbHBoYT1jcm9uYmFjaC5zYywgbj0xMDQsIGl0ZW1zPTYsIGNvbmYubGV2ZWwgPSAwLjk1KQ0KQ0kuY29tcCA9IGNiaW5kKExDSSA9IENJLnNjWzFdLCBhbHBoYSA9IGNyb25iYWNoLnNjLCBVQ0kgPUNJLnNjWzJdKQ0Kcm93Lm5hbWVzKENJLmNvbXApID0gIiINCnBhbmRlcihDSS5jb21wLCBjYXB0aW9uPSJDb25mb2RlbmNlIEludGVydmFsIG9mIENyYW5iYWNoIEFscGhhIikNCmBgYA0KSGVyZSwgQ3JvbmJhY2gncyBhbHBoYSBpcyAwLjgwNywgd2l0aCBhIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgKDAuNzQ0LCAwLjg1OSksIHN1Z2dlc3RpbmcgdGhhdCB0aGUgaXRlbXMgaW4gdGhlIGVuZ2FnZW1lbnQgaW4gbGVhcm5pbmcgY29tcG9uZW50IGhhdmUgcmVsYXRpdmVseSBoaWdoIGludGVybmFsIGNvbnNpc3RlbmN5Lg0KDQojIyBFbmNvdXJlZ21lbnQgYW5kIFN1cHBvcnQNCg0KDQpgYGB7ciBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gNiwgZmlnLmNhcD0iVGhlIHBhaXJ3aXNlIGNvcnJlbGF0aW9uIHBsb3QgcmV2ZWFscyB0aGUgcG90ZW50aWFsIHJlbGV2YW5jZSBvZiBQQ0EuIFRoZSBzaGFwZSBvZiBhbiBlbGxpcHNlIHJlcHJlc2VudHMgdGhlIGNvcnJlbGF0aW9uLiBUaGUgc2tpbm5pZXIgdGhlIGVsbGlwc2UsIHRoZSBoaWdoZXIgdGhlIGNvcnJlbGF0aW9uLiBUaGUgZGlyZWN0aW9uIHJlZmxlY3RzIHdoZXRoZXIgYSBjb3JyZWxhdGlvbiBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4gVGhlIG9mZi1kaWFnb25hbCBkaXJlY3Rpb24gaW1wbGllcyBzIHBvc2l0aXZlIGNvcnJlbGF0aW9uIHdoaWxlIHRoZSBtYWluIGRpYWdvbmFsIGRpcmVjdGlvbiBpbXBsaWVzIGEgbmVnYXRpdmUgYXNzb2NpYXRpb24uIn0NCiMjDQpNND1jb3IoRUFTKQ0KY29ycnBsb3QubWl4ZWQoTTQsIGxvd2VyLmNvbCA9ICJwdXJwbGUiLCB1cHBlciA9ICJlbGxpcHNlIiwgbnVtYmVyLmNleCA9IC43LCB0bC5jZXggPSAwLjcpDQpgYGANCmBgYHtyfQ0KY3JvbmJhY2guc2MgPSBhcy5udW1lcmljKGFscGhhKEVBUykkdG90YWxbMV0pDQpDSS5zYyA9IGNyb25iYWNoLmFscGhhLkNJKGFscGhhPWNyb25iYWNoLnNjLCBuPTEwNCwgaXRlbXM9NiwgY29uZi5sZXZlbCA9IDAuOTUpDQpDSS5jb21wID0gY2JpbmQoTENJID0gQ0kuc2NbMV0sIGFscGhhID0gY3JvbmJhY2guc2MsIFVDSSA9Q0kuc2NbMl0pDQpyb3cubmFtZXMoQ0kuY29tcCkgPSAiIg0KcGFuZGVyKENJLmNvbXAsIGNhcHRpb249IkNvbmZvZGVuY2UgSW50ZXJ2YWwgb2YgQ3JhbmJhY2ggQWxwaGEiKQ0KYGBgDQpIZXJlLCBDcm9uYmFjaCdzIGFscGhhIGlzIDAuODMzLCB3aXRoIGEgY29uZmlkZW5jZSBpbnRlcnZhbCBvZiAoMC43NzgsIDAuODc4KSwgc3VnZ2VzdGluZyB0aGF0IHRoZSBpdGVtcyBpbiB0aGUgZW5nYWdlbWVudCBpbiBsZWFybmluZyBjb21wb25lbnQgaGF2ZSByZWxhdGl2ZWx5IGhpZ2ggaW50ZXJuYWwgY29uc2lzdGVuY3kuDQoNCiMjIEdyb3d0aCBhbmQgRGV2ZWxvcG1lbnQgDQoNCg0KYGBge3IgZmlnLndpZHRoID0gNiwgZmlnLmhlaWdodCA9IDYsIGZpZy5jYXA9IlRoZSBwYWlyd2lzZSBjb3JyZWxhdGlvbiBwbG90IHJldmVhbHMgdGhlIHBvdGVudGlhbCByZWxldmFuY2Ugb2YgUENBLiBUaGUgc2hhcGUgb2YgYW4gZWxsaXBzZSByZXByZXNlbnRzIHRoZSBjb3JyZWxhdGlvbi4gVGhlIHNraW5uaWVyIHRoZSBlbGxpcHNlLCB0aGUgaGlnaGVyIHRoZSBjb3JyZWxhdGlvbi4gVGhlIGRpcmVjdGlvbiByZWZsZWN0cyB3aGV0aGVyIGEgY29ycmVsYXRpb24gaXMgcG9zaXRpdmUgb3IgbmVnYXRpdmUuIFRoZSBvZmYtZGlhZ29uYWwgZGlyZWN0aW9uIGltcGxpZXMgcyBwb3NpdGl2ZSBjb3JyZWxhdGlvbiB3aGlsZSB0aGUgbWFpbiBkaWFnb25hbCBkaXJlY3Rpb24gaW1wbGllcyBhIG5lZ2F0aXZlIGFzc29jaWF0aW9uLiJ9DQojIw0KTTU9Y29yKEdBRCkNCmNvcnJwbG90Lm1peGVkKE01LCBsb3dlci5jb2wgPSAicHVycGxlIiwgdXBwZXIgPSAiZWxsaXBzZSIsIG51bWJlci5jZXggPSAuNywgdGwuY2V4ID0gMC43KQ0KYGBgDQpgYGB7cn0NCmNyb25iYWNoLnNjID0gYXMubnVtZXJpYyhhbHBoYShHQUQpJHRvdGFsWzFdKQ0KQ0kuc2MgPSBjcm9uYmFjaC5hbHBoYS5DSShhbHBoYT1jcm9uYmFjaC5zYywgbj0xMDQsIGl0ZW1zPTYsIGNvbmYubGV2ZWwgPSAwLjk1KQ0KQ0kuY29tcCA9IGNiaW5kKExDSSA9IENJLnNjWzFdLCBhbHBoYSA9IGNyb25iYWNoLnNjLCBVQ0kgPUNJLnNjWzJdKQ0Kcm93Lm5hbWVzKENJLmNvbXApID0gIiINCnBhbmRlcihDSS5jb21wLCBjYXB0aW9uPSJDb25mb2RlbmNlIEludGVydmFsIG9mIENyYW5iYWNoIEFscGhhIikNCmBgYA0KSGVyZSwgQ3JvbmJhY2gncyBhbHBoYSBpcyAwLjk0Nywgd2l0aCBhIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgKDAuOTI5LCAwLjk2MSksIHN1Z2dlc3RpbmcgdGhhdCB0aGUgaXRlbXMgaW4gdGhlIGVuZ2FnZW1lbnQgaW4gbGVhcm5pbmcgY29tcG9uZW50IGhhdmUgcmVsYXRpdmVseSBoaWdoIGludGVybmFsIGNvbnNpc3RlbmN5Lg0KDQoNCiMgUENBIA0KDQpUaGlzIHNlY3Rpb24gcmVwb3J0IHRoZSByZXN1bHRzIG9mIHRoZSBwcmluY2lwbGUgY29tcG9uZW50IGFuYWx5c2lzLiBUaGUgc2lnbmlmaWNhbnQgUENzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGFuYWx5dGljIGRhdGEgc2V0IGZvciBmdXR1cmUgbW9kZWxpbmcuIEJ1dCBiZWZvcmUgdGhpcyBJIHdpbGwgZGVmaW5lIHRoZSBmb2xsb3dpbmcgdHdvIFIgZnVuY3Rpb25zIGFuZCB1c2UgdGhlbSBpbiB0aGUgUENBIGFuYWx5c2lzLiBUaGVuLCB0aGUgbXkubG9hZGluZ3MudmFyIGlzIHVzZWQgdG8gZXh0cmFjdCB0aGUgcHJvcG9ydGlvbiBvZiB2YXJpYW5jZSBhbmQgTXkuDQoNCmBgYHtyIH0NCk15LnBsb3RuU2NyZWUgPSBmdW5jdGlvbihtYXQsIGxlZ2VuZCA9IFRSVUUsIG1ldGhvZCA9ImZhY3RvcnMiLCBtYWluKXsNCiAgICAjIG1hdCA9IGRhdGEgbWF0cml4DQogICAgIyBtZXRob2QgPSBjKCJmYWN0b3JzIiwgImNvbXBvbmVudHMiKSwgZGVmYXVsdCBpcyAiZmFjdG9ycyIuDQogICAgIyBtYWluID0gdGl0bGUgb2YgdGhlIHBsb3QNCiAgICBldiA8LSBlaWdlbihjb3IobWF0KSkgICAgIyBnZXQgZWlnZW52YWx1ZXMNCiAgICBhcCA8LSBwYXJhbGxlbChzdWJqZWN0PW5yb3cobWF0KSx2YXI9bmNvbChtYXQpLCByZXA9NTAwMCxjZW50PS4wNSkNCiAgICBuU2NyZWUgPSBuU2NyZWUoeD1ldiR2YWx1ZXMsIGFwYXJhbGxlbD1hcCRlaWdlbiRxZXZwZWEsIG1vZGVsPW1ldGhvZCkgIA0KICAgICMjDQogICAgaWYgKCFpbmhlcml0cyhuU2NyZWUsICJuU2NyZWUiKSkgDQogICAgICAgIHN0b3AoIk1ldGhvZCBpcyBvbmx5IGZvciBuU2NyZWUgb2JqZWN0cyIpDQogICAgaWYgKG5TY3JlZSRNb2RlbCA9PSAiY29tcG9uZW50cyIpIA0KICAgICAgICBua2Fpc2VyID0gIkVpZ2VudmFsdWVzID4gbWVhbjogbiA9ICINCiAgICBpZiAoblNjcmVlJE1vZGVsID09ICJmYWN0b3JzIikgDQogICAgICBua2Fpc2VyID0gIkVpZ2VudmFsdWVzID4gemVybzogbiA9ICINCiAgICAjIGF4aXMgbGFiZWxzDQogICAgeGxhYiA9IG5TY3JlZSRNb2RlbA0KICAgIHlsYWIgPSAiRWlnZW52YWx1ZXMiDQogICAgIyMNCiAgICBwYXIoY29sID0gMSwgcGNoID0gMTgpDQogICAgcGFyKG1mcm93ID0gYygxLCAxKSkNCiAgICBlaWcgPC0gblNjcmVlJEFuYWx5c2lzJEVpZ2VudmFsdWVzDQogICAgayA8LSAxOmxlbmd0aChlaWcpDQogICAgcGxvdCgxOmxlbmd0aChlaWcpLCBlaWcsIHR5cGU9ImIiLCBtYWluID0gbWFpbiwgDQogICAgICAgIHhsYWIgPSB4bGFiLCB5bGFiID0geWxhYiwgeWxpbT1jKDAsIDEuMiptYXgoZWlnKSkpDQogICAgIw0KICAgIG5rIDwtIGxlbmd0aChlaWcpDQogICAgbm9jIDwtIG5TY3JlZSRDb21wb25lbnRzJG5vYw0KICAgIHZwLnAgPC0gbG0oZWlnW2Mobm9jICsgMSwgbmspXSB+IGtbYyhub2MgKyAxLCBuayldKQ0KICAgIHggPC0gc3VtKGMoMSwgMSkgKiBjb2VmKHZwLnApKQ0KICAgIHkgPC0gc3VtKGMoMSwgbmspICogY29lZih2cC5wKSkNCiAgICBwYXIoY29sID0gMTApDQogICAgbGluZXMoa1tjKDEsIG5rKV0sIGMoeCwgeSkpDQogICAgcGFyKGNvbCA9IDExLCBwY2ggPSAyMCkNCiAgICBsaW5lcygxOm5rLCBuU2NyZWUkQW5hbHlzaXMkUGFyLkFuYWx5c2lzLCB0eXBlID0gImIiKQ0KICAgIGlmIChsZWdlbmQgPT0gVFJVRSkgew0KICAgICAgICBsZWcudHh0IDwtIGMocGFzdGUobmthaXNlciwgblNjcmVlJENvbXBvbmVudHMkbmthaXNlciksIA0KICAgICAgICAgICAgICAgICAgIGMocGFzdGUoIlBhcmFsbGVsIEFuYWx5c2lzOiBuID0gIiwgblNjcmVlJENvbXBvbmVudHMkbnBhcmFsbGVsKSksIA0KICAgICAgICAgICAgICAgICAgIGMocGFzdGUoIk9wdGltYWwgQ29vcmRpbmF0ZXM6IG4gPSAiLCBuU2NyZWUkQ29tcG9uZW50cyRub2MpKSwgDQogICAgICAgICAgICAgICAgICAgYyhwYXN0ZSgiQWNjZWxlcmF0aW9uIEZhY3RvcjogbiA9ICIsIG5TY3JlZSRDb21wb25lbnRzJG5hZikpDQogICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICBsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gbGVnLnR4dCwgcGNoID0gYygxOCwgMjAsIE5BLCBOQSksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dC5jb2wgPSBjKDEsIDMsIDIsIDQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbCA9IGMoMSwgMywgMiwgNCksIGJ0eT0ibiIsIGNleD0wLjcpDQogICAgfQ0KICAgIG5hZiA8LSBuU2NyZWUkQ29tcG9uZW50cyRuYWYNCiAgICB0ZXh0KHggPSBub2MsIHkgPSBlaWdbbm9jXSwgbGFiZWwgPSAiIChPQykiLCBjZXggPSAwLjcsIA0KICAgICAgICBhZGogPSBjKDAsIDApLCBjb2wgPSAyKQ0KICAgIHRleHQoeCA9IG5hZiArIDEsIHkgPSBlaWdbbmFmICsgMV0sIGxhYmVsID0gIiAoQUYpIiwgDQogICAgICAgIGNleCA9IDAuNywgYWRqID0gYygwLCAwKSwgY29sID0gNCkNCn0NCmBgYA0KDQpgYGB7cn0NCk15LmxvYWRpbmdzLnZhciA8LSBmdW5jdGlvbihtYXQsIG5mY3QsIG1ldGhvZD0iZmEiKXsNCiAgICMgbWF0ID0gIGRhdGEgbWF0cml4DQogICAjIG5mY3QgPSBudW1iZXIgb2YgZmFjdG9ycyBvciBjb21wb25lbnRzDQogICAjIG1ldGhvZCA9IGMoImZhIiwgInBjYSIpLCBkZWZhdWx0ID0gaXMgImZhIi4NCiAgICBpZihtZXRob2QgPT0gImZhIil7IA0KICAgICBmMSA8LSBmYWN0YW5hbChtYXQsIGZhY3RvcnMgPSBuZmN0LCAgcm90YXRpb24gPSAidmFyaW1heCIpDQogICAgIHggPC0gbG9hZGluZ3MoZjEpDQogICAgIHZ4IDwtIGNvbFN1bXMoeF4yKQ0KICAgICB2YXJTUyA9IHJiaW5kKCdTUyBsb2FkaW5ncycgPSB2eCwNCiAgICAgICAgICAgICdQcm9wb3J0aW9uIFZhcicgPSB2eC9ucm93KHgpLA0KICAgICAgICAgICAnQ3VtdWxhdGl2ZSBWYXInID0gY3Vtc3VtKHZ4L25yb3coeCkpKQ0KICAgICB3ZWlnaHQgPSBmMSRsb2FkaW5nc1tdIA0KICAgfSBlbHNlIGlmIChtZXRob2QgPT0gInBjYSIpew0KICAgICBwY2EgPC0gcHJjb21wKG1hdCwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKQ0KICAgICB2YXJTUyA9IHN1bW1hcnkocGNhKSRpbXBvcnRhbmNlWywxOm5mY3RdDQogICAgIHdlaWdodCA9IHBjYSRyb3RhdGlvblssMTpuZmN0XQ0KICB9DQogICAgbGlzdChMb2FkaW5ncyA9IHdlaWdodCwgUHJvcC5WYXIgPSB2YXJTUykNCn0NCmBgYA0KDQpOb3csIHdlIGNhbiBwZXJmb3JtIFBDQSBhbmFseXNpcyBvbiBlYWNoIG9mIHRoZSBzaXggc3VydmV5IGNvbXBvbmVudHMuLi4NCg0KIyMgUENBIEZvciBFSUwgQ29tcG9uZW50IA0KDQpgYGB7ciBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gNn0NCk15LnBsb3RuU2NyZWUobWF0PUVJTCwgbGVnZW5kID0gVFJVRSwgbWV0aG9kID0iY29tcG9uZW50cyIsIA0KICAgICAgICAgICAgICBtYWluPSJEZXRlcm1pbmF0aW9uIG9mIE51bWJlciBvZiBDb21wb25lbnRzXG4gRUlMIChQb3NpdGl2ZSkiKQ0KYGBgDQoNCg0KRmlyc3QsIEkgYW0gZ29pbmcgdG8gZXh0cmFjdCB0aGUgZmFjdG9ycyBvZiB0aGUgZmlyc3QgdHdvIFBDQXMuIFRoZSBQQ0EgZmFjdG9yIGxvYWRpbmdzIGFuZCB0aGUgcHJvcG9ydGlvbiBvZiB2YXJpYW5jZSBleHBsYWluZWQgYnkgdGhlIHJldGFpbmVkIFBDQXMgYXJlIHN1bW1hcml6ZWQgaW4gdGhlIGZvbGxvd2luZyB0YWJsZXMuDQoNCmBgYHtyfQ0KTG9hZGluZ3MgPSBNeS5sb2FkaW5ncy52YXIobWF0PUVJTCwgbmZjdD0yLCBtZXRob2Q9InBjYSIpJExvYWRpbmdzDQojDQojIHBjYSBsb2FkaW5ncw0Ka2FibGUocm91bmQoTG9hZGluZ3MsMyksDQogIGNhcHRpb249IkZhY3RvciBvZiB0aGUgZmlyc3QgZmV3IFBDQXMgYW5kIHRoZSBjdW11bGF0aXZlIHByb3BvcnRpb24NCm9mIHZhcmlhdGlvbiBleHBsYWluZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgUENBcyBpbiB0aGUgRUlMIGNvbXBvbmVudC4iKQ0KYGBgDQoNCmBgYHtyfQ0KVmFyUHJvcCA9IE15LmxvYWRpbmdzLnZhcihtYXQ9RUlMLCBuZmN0PTIsIG1ldGhvZD0icGNhIikkUHJvcC5WYXINCiMgcGNhIGxvYWRpbmdzDQprYWJsZShyb3VuZChWYXJQcm9wLDMpLA0KICAgIGNhcHRpb249IkN1bXVsYXRpdmUgYW5kIHByb3BvcnRpb24gb2YgdmFyaWFuY2VzIGV4cGxhaW5lZCBieSBlYWNoIA0KICAgIHRoZSBwcmluY2lwYWwgY29tcG9uZW50IGluIEVJTC4iKQ0KYGBgDQoNClRoZSBTY3JlZSB0eXBlIG9mIHRlc3Qgc3VnZ2VzdHMgcmV0YWluaW5nIGEgc2luZ2xlIGZhY3Rvci4gVGhlIHByb3BvcnRpb24gb2YgdG90YWwgdmFyaWF0aW9uIGlzIGxvd2VyIHRoYW4gdGhhdCBvZiBQQ0EuSSB1c2VkIHRoZSBQQ0EgbWV0aG9kIGFuZCBleHRyYWN0IHRoZSBmaXJzdCB0d28gcHJpbmNpcGFsIGNvbXBvbmVudHMgZm9yIGZ1dHVyZSBhbmFseXNpcy4gVGhlIHRhYmxlIGFib3ZlIHNob3dzIHRoZSBmYWN0b3IgbG9hZGluZ3Mgb2YgdGhlIGZpcnN0IHR3byBwcmluY2lwYWwgY29tcG9uZW50cy4gV2UgY2FuIHNlZSB0aGF0IGVhY2ggb2YgdGhlIG9yaWdpbmFsIGl0ZW1zIGNvbnRyaWJ1dGVzIHRvIHRoZSB0d28gUENBcyBldmVubHkgaW4gdGVybXMgb2YgdGhlIG1hZ25pdHVkZS4gVGhlIGZpcnN0IFBDQSBjb3VudHMgYWJvdXQgMzAuNiUgb2YgdGhlIHRvdGFsIHZhcmlhdGlvbiBhbmQgdGhlIHNlY29uZCBQQ0EgY291bnRzIDguOSUgb2YgdGhlIHRvdGFsIHZhcmlhdGlvbiBUaGlzIHN1Z2dlc3RzIHRoYXQgd2Ugc2hvdWxkIHJldGFpbiBhIHNpbXBsZSBmYWN0b3IuDQoNCmBgYHtyfQ0KcGNhMSA8LSBwcmNvbXAoRUlMLCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IFRSVUUpDQplaWwuaWR4ID0gcGNhMSR4WywxXQ0KIyMNCmhpc3QoZWlsLmlkeCwNCm1haW49IkRpc3RyaWJ1dGlvbiBvZiBFbmdhZ2VtZW50IGluIExlYXJuaW5nIEluZGV4IiwNCmJyZWFrcyA9IHNlcShtaW4oZWlsLmlkeCksIG1heChlaWwuaWR4KSwgbGVuZ3RoPTkpLA0KeGxhYj0iRUlMIEluZGV4IiwNCnhsaW09cmFuZ2UoZWlsLmlkeCksDQpib3JkZXI9InJlZCIsDQpjb2w9ImxpZ2h0Ymx1ZSIsDQpmcmVxPUZBTFNFDQopDQpgYGANCg0KDQoNCg0KDQoNCiMjIFBDQSBGb3IgU0xTIENvbXBvbmVudCANCmBgYHtyfQ0KTXkucGxvdG5TY3JlZShtYXQ9U0xTLCBsZWdlbmQgPSBUUlVFLCBtZXRob2QgPSJjb21wb25lbnRzIiwgDQogICAgICAgICAgICAgIG1haW49IkRldGVybWluYXRpb24gb2YgTnVtYmVyIG9mIENvbXBvbmVudHNcbiBTTFMgKFBvc2l0aXZlKSIpDQpgYGANCg0KYGBge3J9DQpMb2FkaW5ncyA9IE15LmxvYWRpbmdzLnZhcihtYXQ9U0xTLCBuZmN0PTIsIG1ldGhvZD0icGNhIikkTG9hZGluZ3MNCiMNCiMgcGNhIGxvYWRpbmdzDQprYWJsZShyb3VuZChMb2FkaW5ncywzKSwNCiAgY2FwdGlvbj0iRmFjdG9yIG9mIHRoZSBmaXJzdCBmZXcgUENBcyBhbmQgdGhlIGN1bXVsYXRpdmUgcHJvcG9ydGlvbg0Kb2YgdmFyaWF0aW9uIGV4cGxhaW5lZCBieSB0aGUgY29ycmVzcG9uZGluZyBQQ0FzIGluIHRoZSBTTFMgY29tcG9uZW50LiIpDQpgYGANCg0KYGBge3J9DQpWYXJQcm9wID0gTXkubG9hZGluZ3MudmFyKG1hdD1TTFMsIG5mY3Q9MiwgbWV0aG9kPSJwY2EiKSRQcm9wLlZhcg0KIyBwY2EgbG9hZGluZ3MNCmthYmxlKHJvdW5kKFZhclByb3AsMyksDQogICAgY2FwdGlvbj0iQ3VtdWxhdGl2ZSBhbmQgcHJvcG9ydGlvbiBvZiB2YXJpYW5jZXMgZXhwbGFpbmVkIGJ5IGVhY2ggDQogICAgdGhlIHByaW5jaXBhbCBjb21wb25lbnQgaW4gU0xTLiIpDQpgYGANClRoZSB0YWJsZSBhYm92ZSBzaG93cyB0aGUgZmFjdG9yIGxvYWRpbmdzIG9mIHRoZSBmaXJzdCB0d28gcHJpbmNpcGFsIGNvbXBvbmVudHMuIFdlIGNhbiBzZWUgdGhhdCBlYWNoIG9mIHRoZSBvcmlnaW5hbCBpdGVtcyBjb250cmlidXRlcyB0byB0aGUgdHdvIFBDQXMgZXZlbmx5IGluIHRlcm1zIG9mIHRoZSBtYWduaXR1ZGUuIFRoZSBmaXJzdCBQQ0EgY291bnRzIGFib3V0IDU4LjIlIG9mIHRoZSB0b3RhbCB2YXJpYXRpb24gYW5kIHRoZSBzZWNvbmQgUENBIGNvdW50cyAxNC40JSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIFRoaXMgc3VnZ2VzdHMgdGhhdCB3ZSBzaG91bGQgcmV0YWluIGEgc2ltcGxlIGZhY3Rvci4NCg0KYGBge3J9DQpwY2EyIDwtIHByY29tcChTTFMsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gVFJVRSkNCnNscy5pZHggPSBwY2EyJHhbLDFdDQojIw0KaGlzdChzbHMuaWR4LA0KbWFpbj0iRGlzdHJpYnV0aW9uIG9mIFN0dWRlbnQgTGVhcm5pbmcgSW5kZXgiLA0KYnJlYWtzID0gc2VxKG1pbihzbHMuaWR4KSwgbWF4KHNscy5pZHgpLCBsZW5ndGg9OSksDQp4bGFiPSJTTFMgSW5kZXgiLA0KeGxpbT1yYW5nZShzbHMuaWR4KSwNCmJvcmRlcj0icmVkIiwNCmNvbD0ibGlnaHRibHVlIiwNCmZyZXE9RkFMU0UNCikNCmBgYA0KDQoNCg0KDQoNCg0KDQojIyBQQ0EgRm9yIFdSTCBDb21wb25lbnQgDQpgYGB7cn0NCk15LnBsb3RuU2NyZWUobWF0PVdSTCwgbGVnZW5kID0gVFJVRSwgbWV0aG9kID0iY29tcG9uZW50cyIsIA0KICAgICAgICAgICAgICBtYWluPSJEZXRlcm1pbmF0aW9uIG9mIE51bWJlciBvZiBDb21wb25lbnRzXG4gU0xTIChQb3NpdGl2ZSkiKQ0KYGBgDQoNCmBgYHtyfQ0KTG9hZGluZ3MgPSBNeS5sb2FkaW5ncy52YXIobWF0PVdSTCwgbmZjdD0yLCBtZXRob2Q9InBjYSIpJExvYWRpbmdzDQojDQojIHBjYSBsb2FkaW5ncw0Ka2FibGUocm91bmQoTG9hZGluZ3MsMyksDQogIGNhcHRpb249IkZhY3RvciBvZiB0aGUgZmlyc3QgZmV3IFBDQXMgYW5kIHRoZSBjdW11bGF0aXZlIHByb3BvcnRpb24NCm9mIHZhcmlhdGlvbiBleHBsYWluZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgUENBcyBpbiB0aGUgV1JMIGNvbXBvbmVudC4iKQ0KYGBgDQoNCmBgYHtyfQ0KVmFyUHJvcCA9IE15LmxvYWRpbmdzLnZhcihtYXQ9V1JMLCBuZmN0PTIsIG1ldGhvZD0icGNhIikkUHJvcC5WYXINCiMgcGNhIGxvYWRpbmdzDQprYWJsZShyb3VuZChWYXJQcm9wLDMpLA0KICAgIGNhcHRpb249IkN1bXVsYXRpdmUgYW5kIHByb3BvcnRpb24gb2YgdmFyaWFuY2VzIGV4cGxhaW5lZCBieSBlYWNoIA0KICAgIHRoZSBwcmluY2lwYWwgY29tcG9uZW50IGluIFdSTC4iKQ0KYGBgDQpUaGUgdGFibGUgYWJvdmUgc2hvd3MgdGhlIGZhY3RvciBsb2FkaW5ncyBvZiB0aGUgZmlyc3QgdHdvIHByaW5jaXBhbCBjb21wb25lbnRzLiBXZSBjYW4gc2VlIHRoYXQgZWFjaCBvZiB0aGUgb3JpZ2luYWwgaXRlbXMgY29udHJpYnV0ZXMgdG8gdGhlIHR3byBQQ0FzIGV2ZW5seSBpbiB0ZXJtcyBvZiB0aGUgbWFnbml0dWRlLiBUaGUgZmlyc3QgUENBIGNvdW50cyBhYm91dCA1MC43JSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIGFuZCB0aGUgc2Vjb25kIFBDQSBjb3VudHMgMzEuNCUlIG9mIHRoZSB0b3RhbCB2YXJpYXRpb24gVGhpcyBzdWdnZXN0cyB0aGF0IHdlIHNob3VsZCByZXRhaW4gYSBzaW1wbGUgZmFjdG9yLg0KDQpgYGB7cn0NCnBjYTMgPC0gcHJjb21wKFdSTCwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKQ0Kd3JsLmlkeCA9IHBjYTMkeFssMV0NCiMjDQpoaXN0KHdybC5pZHgsDQptYWluPSJEaXN0cmlidXRpb24gb2YgV3JpdGluZyBhbmQgUmVhZGluZyBMb2FkIEluZGV4IiwNCmJyZWFrcyA9IHNlcShtaW4od3JsLmlkeCksIG1heCh3cmwuaWR4KSwgbGVuZ3RoPTkpLA0KeGxhYj0iV1JMIEluZGV4IiwNCnhsaW09cmFuZ2Uod3JsLmlkeCksDQpib3JkZXI9InJlZCIsDQpjb2w9ImxpZ2h0Ymx1ZSIsDQpmcmVxPUZBTFNFDQopDQpgYGANCg0KDQoNCg0KDQoNCg0KDQoNCiMjIFBDQSBGb3IgUkUgQ29tcG9uZW50IA0KYGBge3J9DQpNeS5wbG90blNjcmVlKG1hdD1SRSwgbGVnZW5kID0gVFJVRSwgbWV0aG9kID0iY29tcG9uZW50cyIsIA0KICAgICAgICAgICAgICBtYWluPSJEZXRlcm1pbmF0aW9uIG9mIE51bWJlciBvZiBDb21wb25lbnRzXG4gUkUgKFBvc2l0aXZlKSIpDQpgYGANCg0KYGBge3J9DQpMb2FkaW5ncyA9IE15LmxvYWRpbmdzLnZhcihtYXQ9UkUsIG5mY3Q9MiwgbWV0aG9kPSJwY2EiKSRMb2FkaW5ncw0KIw0KIyBwY2EgbG9hZGluZ3MNCmthYmxlKHJvdW5kKExvYWRpbmdzLDMpLA0KICBjYXB0aW9uPSJGYWN0b3Igb2YgdGhlIGZpcnN0IGZldyBQQ0FzIGFuZCB0aGUgY3VtdWxhdGl2ZSBwcm9wb3J0aW9uDQpvZiB2YXJpYXRpb24gZXhwbGFpbmVkIGJ5IHRoZSBjb3JyZXNwb25kaW5nIFBDQXMgaW4gdGhlIFJFIGNvbXBvbmVudC4iKQ0KYGBgDQoNCmBgYHtyfQ0KVmFyUHJvcCA9IE15LmxvYWRpbmdzLnZhcihtYXQ9UkUsIG5mY3Q9MiwgbWV0aG9kPSJwY2EiKSRQcm9wLlZhcg0KIyBwY2EgbG9hZGluZ3MNCmthYmxlKHJvdW5kKFZhclByb3AsMyksDQogICAgY2FwdGlvbj0iQ3VtdWxhdGl2ZSBhbmQgcHJvcG9ydGlvbiBvZiB2YXJpYW5jZXMgZXhwbGFpbmVkIGJ5IGVhY2ggDQogICAgdGhlIHByaW5jaXBhbCBjb21wb25lbnQgaW4gUkUuIikNCmBgYA0KVGhlIHRhYmxlIGFib3ZlIHNob3dzIHRoZSBmYWN0b3IgbG9hZGluZ3Mgb2YgdGhlIGZpcnN0IHR3byBwcmluY2lwYWwgY29tcG9uZW50cy4gV2UgY2FuIHNlZSB0aGF0IGVhY2ggb2YgdGhlIG9yaWdpbmFsIGl0ZW1zIGNvbnRyaWJ1dGVzIHRvIHRoZSB0d28gUENBcyBldmVubHkgaW4gdGVybXMgb2YgdGhlIG1hZ25pdHVkZS4gVGhlIGZpcnN0IFBDQSBjb3VudHMgYWJvdXQgNDAuNCUgb2YgdGhlIHRvdGFsIHZhcmlhdGlvbiBhbmQgdGhlIHNlY29uZCBQQ0EgY291bnRzIDE1JSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIFRoaXMgc3VnZ2VzdHMgdGhhdCB3ZSBzaG91bGQgcmV0YWluIGEgc2ltcGxlIGZhY3Rvci4NCg0KYGBge3J9DQpwY2E0IDwtIHByY29tcChSRSwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKQ0KcmUuaWR4ID0gcGNhNCR4WywxXQ0KIyMNCmhpc3QocmUuaWR4LA0KbWFpbj0iRGlzdHJpYnV0aW9uIG9mIFJlbWlkaWFsIEV4cGVyaWVuY2UgSW5kZXgiLA0KYnJlYWtzID0gc2VxKG1pbihyZS5pZHgpLCBtYXgocmUuaWR4KSwgbGVuZ3RoPTkpLA0KeGxhYj0iUkUgSW5kZXgiLA0KeGxpbT1yYW5nZShyZS5pZHgpLA0KYm9yZGVyPSJyZWQiLA0KY29sPSJsaWdodGJsdWUiLA0KZnJlcT1GQUxTRQ0KKQ0KYGBgDQoNCkhlcmUsIHNpbmNlIHRoZSBSRSBpbmRleCBkaXN0cmlidXRpb24gaXMgc2NyZXdlZCB0byB0aGUgbGVmdC4gV2UgY2FuIHBlcmZvcm0gYSBib3ggY294IHRyYW5zZm9ybWF0aW9uIHRvIGZpeCB0aGlzLiANCg0KYGBge3J9DQpNMT1jb3IoY2JpbmQoZWlsLmlkeCwgRUlMLCBzbHMuaWR4LCBTTFMsIHdybC5pZHgsIFdSTCkpDQojY29ycnBsb3QoTSwgdHlwZSA9ICJ1cHBlciIsIG1ldGhvZCA9ICJlbGxpcHNlIiwgbWFpbj0iUGFpcndpc2UgQ29ycmVsYXRpb24gUGxvdDogU2VsZi1Db21wYXNzaW9uIFNjYWxlIikNCmNvcnJwbG90Lm1peGVkKE0xLCBsb3dlci5jb2wgPSAicHVycGxlIiwgdXBwZXIgPSAiZWxsaXBzZSIsIG51bWJlci5jZXggPSAuNywgdGwuY2V4ID0gMC43KQ0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQojIyBQQ0EgRm9yIEVBUyBDb21wb25lbnQgDQpgYGB7cn0NCk15LnBsb3RuU2NyZWUobWF0PUVBUywgbGVnZW5kID0gVFJVRSwgbWV0aG9kID0iY29tcG9uZW50cyIsIA0KICAgICAgICAgICAgICBtYWluPSJEZXRlcm1pbmF0aW9uIG9mIE51bWJlciBvZiBDb21wb25lbnRzXG4gU0xTIChQb3NpdGl2ZSkiKQ0KYGBgDQoNCmBgYHtyfQ0KTG9hZGluZ3MgPSBNeS5sb2FkaW5ncy52YXIobWF0PUVBUywgbmZjdD0yLCBtZXRob2Q9InBjYSIpJExvYWRpbmdzDQojDQojIHBjYSBsb2FkaW5ncw0Ka2FibGUocm91bmQoTG9hZGluZ3MsMyksDQogIGNhcHRpb249IkZhY3RvciBvZiB0aGUgZmlyc3QgZmV3IFBDQXMgYW5kIHRoZSBjdW11bGF0aXZlIHByb3BvcnRpb24NCm9mIHZhcmlhdGlvbiBleHBsYWluZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgUENBcyBpbiB0aGUgRUFTIGNvbXBvbmVudC4iKQ0KYGBgDQoNCmBgYHtyfQ0KVmFyUHJvcCA9IE15LmxvYWRpbmdzLnZhcihtYXQ9RUFTLCBuZmN0PTIsIG1ldGhvZD0icGNhIikkUHJvcC5WYXINCiMgcGNhIGxvYWRpbmdzDQprYWJsZShyb3VuZChWYXJQcm9wLDMpLA0KICAgIGNhcHRpb249IkN1bXVsYXRpdmUgYW5kIHByb3BvcnRpb24gb2YgdmFyaWFuY2VzIGV4cGxhaW5lZCBieSBlYWNoIA0KICAgIHRoZSBwcmluY2lwYWwgY29tcG9uZW50IGluIEVBUy4iKQ0KYGBgDQpUaGUgdGFibGUgYWJvdmUgc2hvd3MgdGhlIGZhY3RvciBsb2FkaW5ncyBvZiB0aGUgZmlyc3QgdHdvIHByaW5jaXBhbCBjb21wb25lbnRzLiBXZSBjYW4gc2VlIHRoYXQgZWFjaCBvZiB0aGUgb3JpZ2luYWwgaXRlbXMgY29udHJpYnV0ZXMgdG8gdGhlIHR3byBQQ0FzIGV2ZW5seSBpbiB0ZXJtcyBvZiB0aGUgbWFnbml0dWRlLiBUaGUgZmlyc3QgUENBIGNvdW50cyBhYm91dCA1MC41JSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIGFuZCB0aGUgc2Vjb25kIFBDQSBjb3VudHMgMTQuNCUgb2YgdGhlIHRvdGFsIHZhcmlhdGlvbiBUaGlzIHN1Z2dlc3RzIHRoYXQgd2Ugc2hvdWxkIHJldGFpbiBhIHNpbXBsZSBmYWN0b3IuDQoNCmBgYHtyfQ0KcGNhNSA8LSBwcmNvbXAoRUFTLCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IFRSVUUpDQplYXMuaWR4ID0gcGNhNSR4WywxXQ0KIyMNCmhpc3QoZWFzLmlkeCwNCm1haW49IkRpc3RyaWJ1dGlvbiBvZiBFbmNvdXJhZ21lbnQgYW5kIFN1cHBvcnQgSW5kZXgiLA0KYnJlYWtzID0gc2VxKG1pbihlYXMuaWR4KSwgbWF4KGVhcy5pZHgpLCBsZW5ndGg9OSksDQp4bGFiPSJFQVMgSW5kZXgiLA0KeGxpbT1yYW5nZShlYXMuaWR4KSwNCmJvcmRlcj0icmVkIiwNCmNvbD0ibGlnaHRibHVlIiwNCmZyZXE9RkFMU0UNCikNCmBgYA0KDQoNCg0KDQoNCg0KDQoNCg0KDQojIyBQQ0EgRm9yIEdBRCBDb21wb25lbnQgDQpgYGB7cn0NCk15LnBsb3RuU2NyZWUobWF0PUdBRCwgbGVnZW5kID0gVFJVRSwgbWV0aG9kID0iY29tcG9uZW50cyIsIA0KICAgICAgICAgICAgICBtYWluPSJEZXRlcm1pbmF0aW9uIG9mIE51bWJlciBvZiBDb21wb25lbnRzXG4gR0FEIChQb3NpdGl2ZSkiKQ0KYGBgDQoNCmBgYHtyfQ0KTG9hZGluZ3MgPSBNeS5sb2FkaW5ncy52YXIobWF0PUdBRCwgbmZjdD0yLCBtZXRob2Q9InBjYSIpJExvYWRpbmdzDQojDQojIHBjYSBsb2FkaW5ncw0Ka2FibGUocm91bmQoTG9hZGluZ3MsMyksDQogIGNhcHRpb249IkZhY3RvciBvZiB0aGUgZmlyc3QgZmV3IFBDQXMgYW5kIHRoZSBjdW11bGF0aXZlIHByb3BvcnRpb24NCm9mIHZhcmlhdGlvbiBleHBsYWluZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgUENBcyBpbiB0aGUgR0FEIGNvbXBvbmVudC4iKQ0KYGBgDQoNCmBgYHtyfQ0KVmFyUHJvcCA9IE15LmxvYWRpbmdzLnZhcihtYXQ9R0FELCBuZmN0PTIsIG1ldGhvZD0icGNhIikkUHJvcC5WYXINCiMgcGNhIGxvYWRpbmdzDQprYWJsZShyb3VuZChWYXJQcm9wLDMpLA0KICAgIGNhcHRpb249IkN1bXVsYXRpdmUgYW5kIHByb3BvcnRpb24gb2YgdmFyaWFuY2VzIGV4cGxhaW5lZCBieSBlYWNoIA0KICAgIHRoZSBwcmluY2lwYWwgY29tcG9uZW50IGluIEdBRC4iKQ0KYGBgDQpUaGUgdGFibGUgYWJvdmUgc2hvd3MgdGhlIGZhY3RvciBsb2FkaW5ncyBvZiB0aGUgZmlyc3QgdHdvIHByaW5jaXBhbCBjb21wb25lbnRzLiBXZSBjYW4gc2VlIHRoYXQgZWFjaCBvZiB0aGUgb3JpZ2luYWwgaXRlbXMgY29udHJpYnV0ZXMgdG8gdGhlIHR3byBQQ0FzIGV2ZW5seSBpbiB0ZXJtcyBvZiB0aGUgbWFnbml0dWRlLiBUaGUgZmlyc3QgUENBIGNvdW50cyBhYm91dCA1Ny43JSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIGFuZCB0aGUgc2Vjb25kIFBDQSBjb3VudHMgOC4zJSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIFRoaXMgc3VnZ2VzdHMgdGhhdCB3ZSBzaG91bGQgcmV0YWluIGEgc2ltcGxlIGZhY3Rvci4NCg0KYGBge3J9DQpwY2E2IDwtIHByY29tcChHQUQsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gVFJVRSkNCmdhZC5pZHggPSBwY2E2JHhbLDFdDQojIw0KaGlzdChnYWQuaWR4LA0KbWFpbj0iRGlzdHJpYnV0aW9uIG9mIEdyb3d0aCBhbmQgRGV2ZWxvcGVtZW50IEluZGV4IiwNCmJyZWFrcyA9IHNlcShtaW4oZ2FkLmlkeCksIG1heChnYWQuaWR4KSwgbGVuZ3RoPTkpLA0KeGxhYj0iR0FEIEluZGV4IiwNCnhsaW09cmFuZ2UoZ2FkLmlkeCksDQpib3JkZXI9InJlZCIsDQpjb2w9ImxpZ2h0Ymx1ZSIsDQpmcmVxPUZBTFNFDQopDQpgYGANCg0KIyBQcm9qZWN0IFF1ZXN0aW9ucyANCg0KIyMgUXVlc3Rpb24gMTogV2hhdCBmYWN0b3JzIGFyZSBhc3NvY2lhdGVkIHdpdGggc3R1ZGVudHPigJkgcGxhbnMgdG8gcmV0dXJuIG9yIG5vdCByZXR1cm4gdG8gdGhlIHNjaG9vbD8NCg0KVGhpcyBmaXJzdCBxdWVzdGlvbiBjb3VsZCBiZSB1c2VmdWwgZm9yIHVuaXZlcnNpdGllcyB0byBiZSBhYmxlIHRvIGJldHRlciBwcmVkaWN0IGlmIGEgc3R1ZGVudCB3aWxsIHN0YXkgYXQgdGhlaXIgc2Nob29sIG9uY2UgdGhleSBhcmUgZW5yb2xsZWQuIEtub3dpbmcgdGhpcyBjYW4gYWxzbyBoZWxwIHVuaXZlcnNpdGllcyBjYWxjdWxhdGUgYW4gZXN0aW1hdGUgb24gdGhlIG51bWJlciBvZiBzdHVkZW50cyB0aGF0IHdpbGwgZW5kIHVwIGxlYXZpbmcgcGVyIGNsYXNzLiBUaGlzIHdpbGwgaGVscCB0aGUgdW5pdmVyc2l0eSB0byBrbm93IHdoYXQgdG8gaW52ZXN0IHJlc291cmNlcyBpbiwgYW5kIGhvdyB0byBoZWxwIHRob3NlIHN0dWRlbnRzIHdobyBhcmUgbW9yZSBsaWtlbHkgdG8gZHJvcCBvdXQuIFRoZSByZXNwb25zZSB2YXJpYWJsZSBmb3IgdGhpcyBxdWVzdGlvbiB3b3VsZCBiZSBxdWVzdGlvbiAxNCBvbiB0aGUgc3VydmV5LCB3aGljaCBhc2tzIHN0dWRlbnRzIGlmIHRoZXkgcGxhbiBvbiByZXR1cm5pbmcgdG8gdGhlIHVuaXZlcnNpdHkgb3Igbm90IGluIG9yZGVyIHRvIGdyYWR1YXRlLiBUaGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzIHRoYXQgd291bGQgYmUgcHJpbWFyaWx5IGZvY3VzZWQgb24gZm9yIHRoaXMgYW5hbHlzaXMgd291bGQgYmUgc3VydmV5IHF1ZXN0aW9uIDkgd2hpY2ggbG9va3MgYXQgaG93IHN1cHBvcnRlZCB0aGUgc3R1ZGVudCBmZWVscyBieSB0aGUgdW5pdmVyc2l0eSwgcXVlc3Rpb24gMTEgKCB0aGlzIGhvdyBoZWxwIHVuaXZlcnNpdGllcyBkZXRlcm1pbmUgaG93IG11Y2ggdGhlIHJlc291cmNlcyB0aGV5IGFyZSBjdXJyZW50bHkgcHJvdmlkaW5nIGFyZSBoZWxwaW5nIHN0dWRlbnRzKSwgYW5kIHF1ZXN0aW9uIDEyLiANCg0KIyMgUXVlc3Rpb24gMjogRG8gbmF0aW9uYWwgc3R1ZGVudHMgaGF2ZSBiZXR0ZXIgbGVhcm5pbmcgb3V0Y29tZXMgdGhhbiBuYXRpb25hbCBvbmVzPw0KDQpNeSBzZWNvbmQgcXVlc3Rpb24gY291bGQgYmUgYSBnb29kIGluc2lnaHQgYXMgdG8gd2hldGhlciBvciBub3Qgc2Nob29scyBpbiBhbWVyaWNhIGNvdWxkIGltcHJvdmUgaW4gY29tcGFyaXNvbiB0byBsZWFybmluZyBpbnN0aXR1dGlvbnMgb3V0c2lkZSB0aGUgdW5pdGVkIHN0YXRlcy4gSWYgaW50ZXJuYXRpb25hbCBzdHVkZW50cyBkbyBoYXZlIGEgYmV0dGVyIG9yIHdvcnNlIGxlYXJuaW5nIG91dGNvbWVzIHRoYW4gbmF0aXZlIHN0dWRlbnRzLCBpdCB3b3VsZCBiZSBpbnRlcmVzdGluZyB0byBrbm93biB3aGljaCBpZiBjb21wb25lbnRzIHN1Y2ggYXMgbGVhcm5pbmcgc3VwcG9ydCBjb250cmlidXRlZCB0byBpdC4gSWYgdGhpcyBxdWVzdGlvbiB3ZXJlIHRvIGJlIHN0dWRpZWQsIHF1ZXN0aW9uIDIzIG9mIHRoZSBzdXJ2ZXkgd291bGQgYmUgdXNlZCBzaW5jZSBpdCBpcyBhc2tpbmcgaWYgdGhlIHN0dWRlbnQgaXMgZm9yZWlnbiBvciBpbnRlcm5hdGlvbmFsLiBJbiBvcmRlciB0byBtZWFzdXJlIGxlYXJuaW5nIG91dGNvbWVzLCBJIHdvdWxkIGxpa2VseSBsb29rIGF0IHF1ZXN0aW9ucyAxNSwgYW5kIDE2LCB3aGljaCBsb29rIGF0IEdQQSBhbmQgdG90YWwgY3JlZGl0IGhvdXJzLiBJIHdvdWxkIGFsc28gbG9vayBhdCBxdWVzdGlvbiAxMi4zIGFuZCBzZWUgaG93IG1hbnkgc3R1ZGVudHMgdmlldyBiZWluZyBhY2FkZW1pY2FsbHkgdW5wcmVwYXJlZCBhcyBhIHJlYXNvbiBub3QgdG8gY29tZSBiYWNrIHRvIHNjaG9vbC4NCg==