1 Introduction

The data that will be used in this analysis was extracted from an online survey. The study population consists of undergraduate business students from two different regional northern universities. The purpose of this study is to identify the factors that influence students’ learning experience and impact on students’ learning outcomes. For this analysis, I am going to focus on six components of the survey. These include the student’s engagement in learning, the student’s learning style, writing and reading load, remedial experience, encouragement and support, and growth and development. For reference, these are questions 4, 5, 6, 8, 9, and 10 respectively.

1.1 Data Download

First, I am going to download the data from github, I am also removing the odd numbered rows, since all of those are blank, giving us a total of 332 observations and 121 variables.

survey0 = read.csv("https://raw.githubusercontent.com/AvaDeSt/atrisksurvey/refs/heads/main/at-risk-survey-data.csv", head = TRUE)

survey <- survey0[seq(2, nrow(survey0), by = 2), ]

Since R does not have a function to find the model of a given data set, I write the following function to find the model of a data set.

We will perform both principal component analysis (PCA) and exploratory factor analysis (EFA).

my.mode = function(dataset){
  freq.tbl = table(dataset)
  max.freq.id=which(freq.tbl==max(freq.tbl))
  mode=names(freq.tbl[max.freq.id])
  as.numeric(mode)
}

2 Handling Missing Values

2.1 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])
}

3 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.

3.1 Engagement in Learning Questionaire

##
M=cor(EIL)
corrplot.mixed(M, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)
The pairwise correlation plot reveals the potential relevance of PCA. The shape of an ellipse represents the correlation. The skinnier the ellipse, the higher the correlation. The direction reflects whether a correlation is positive or negative. The off-diagonal direction implies s positive correlation while the main diagonal direction implies a negative association.

The pairwise correlation plot reveals the potential relevance of PCA. The shape of an ellipse represents the correlation. The skinnier the ellipse, the higher the correlation. The direction reflects whether a correlation is positive or negative. The off-diagonal direction implies s positive correlation while the main diagonal direction implies a negative association.

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.
LCI alpha UCI
0.8377 0.878 0.911

3.2 Students Learning Style

##
M1=cor(SLS)
corrplot.mixed(M1, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)
The pairwise correlation plot reveals the potential relevance of PCA. The shape of an ellipse represents the correlation. The skinnier the ellipse, the higher the correlation. The direction reflects whether a correlation is positive or negative. The off-diagonal direction implies s positive correlation while the main diagonal direction implies a negative association.

The pairwise correlation plot reveals the potential relevance of PCA. The shape of an ellipse represents the correlation. The skinnier the ellipse, the higher the correlation. The direction reflects whether a correlation is positive or negative. The off-diagonal direction implies s positive correlation while the main diagonal direction implies a negative association.

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.
LCI alpha UCI
0.797 0.8474 0.8887

3.3 Writing and Reading Load

##
M2=cor(WRL)
corrplot.mixed(M2, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)
The pairwise correlation plot reveals the potential relevance of PCA. The shape of an ellipse represents the correlation. The skinnier the ellipse, the higher the correlation. The direction reflects whether a correlation is positive or negative. The off-diagonal direction implies s positive correlation while the main diagonal direction implies a negative association.

The pairwise correlation plot reveals the potential relevance of PCA. The shape of an ellipse represents the correlation. The skinnier the ellipse, the higher the correlation. The direction reflects whether a correlation is positive or negative. The off-diagonal direction implies s positive correlation while the main diagonal direction implies a negative association.

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
LCI alpha UCI
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.

3.4 Remidial Experience

##
M3=cor(RE)
corrplot.mixed(M3, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)
The pairwise correlation plot reveals the potential relevance of PCA. The shape of an ellipse represents the correlation. The skinnier the ellipse, the higher the correlation. The direction reflects whether a correlation is positive or negative. The off-diagonal direction implies s positive correlation while the main diagonal direction implies a negative association.

The pairwise correlation plot reveals the potential relevance of PCA. The shape of an ellipse represents the correlation. The skinnier the ellipse, the higher the correlation. The direction reflects whether a correlation is positive or negative. The off-diagonal direction implies s positive correlation while the main diagonal direction implies a negative association.

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.
LCI alpha UCI
0.7436 0.8072 0.8594

3.5 Encouregment and Support

##
M4=cor(EAS)
corrplot.mixed(M4, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)
The pairwise correlation plot reveals the potential relevance of PCA. The shape of an ellipse represents the correlation. The skinnier the ellipse, the higher the correlation. The direction reflects whether a correlation is positive or negative. The off-diagonal direction implies s positive correlation while the main diagonal direction implies a negative association.

The pairwise correlation plot reveals the potential relevance of PCA. The shape of an ellipse represents the correlation. The skinnier the ellipse, the higher the correlation. The direction reflects whether a correlation is positive or negative. The off-diagonal direction implies s positive correlation while the main diagonal direction implies a negative association.

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.
LCI alpha UCI
0.778 0.8331 0.8783

3.6 Growth and Development

##
M5=cor(GAD)
corrplot.mixed(M5, lower.col = "purple", upper = "ellipse", number.cex = .7, tl.cex = 0.7)
The pairwise correlation plot reveals the potential relevance of PCA. The shape of an ellipse represents the correlation. The skinnier the ellipse, the higher the correlation. The direction reflects whether a correlation is positive or negative. The off-diagonal direction implies s positive correlation while the main diagonal direction implies a negative association.

The pairwise correlation plot reveals the potential relevance of PCA. The shape of an ellipse represents the correlation. The skinnier the ellipse, the higher the correlation. The direction reflects whether a correlation is positive or negative. The off-diagonal direction implies s positive correlation while the main diagonal direction implies a negative association.

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.
LCI alpha UCI
0.9292 0.9468 0.9612

4 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…

4.1 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.
PC1 PC2
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.
PC1 PC2
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
)

4.2 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.
PC1 PC2
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.
PC1 PC2
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
)

4.3 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.
PC1 PC2
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.
PC1 PC2
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
)

4.4 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.
PC1 PC2
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.
PC1 PC2
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)

4.5 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.
PC1 PC2
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.
PC1 PC2
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
)

4.6 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.
PC1 PC2
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.
PC1 PC2
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
)

5 Project Questions

5.1 Question 1: What factors are associated with students’ plans to return or not return to the school?

This first question could be useful for universities to be able to better predict if a student will stay at their school once they are enrolled. Knowing this can also help universities calculate an estimate on the number of students that will end up leaving per class. This will help the university to know what to invest resources in, and how to help those students who are more likely to drop out. The response variable for this question would be question 14 on the survey, which asks students if they plan on returning to the university or not in order to graduate. The explanatory variables that would be primarily focused on for this analysis would be survey question 9 which looks at how supported the student feels by the university, question 11 ( this how help universities determine how much the resources they are currently providing are helping students), and question 12.

5.2 Question 2: Do national students have better learning outcomes than national ones?

My second question could be a good insight as to whether or not schools in america could improve in comparison to learning institutions outside the united states. If international students do have a better or worse learning outcomes than native students, it would be interesting to known which if components such as learning support contributed to it. If this question were to be studied, question 23 of the survey would be used since it is asking if the student is foreign or international. In order to measure learning outcomes, I would likely look at questions 15, and 16, which look at GPA and total credit hours. I would also look at question 12.3 and see how many students view being academically unprepared as a reason not to come back to school.

LS0tDQp0aXRsZTogIlJpc2sgU3VydmV5IEFuYWx5c2lzIGFuZCBRdWVzdGlvbnMiDQphdXRob3I6ICdBdmEgRGVTdGVmYW5vJw0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgZmlnX3dpZHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQogIHdvcmRfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGtlZXBfbWQ6IHllcw0KICBwZGZfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgZmlnX3dpZHRoOiAzDQogICAgZmlnX2hlaWdodDogMw0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQphbHdheXNfYWxsb3dfaHRtbDogdHJ1ZQ0KLS0tDQpgYGB7PWh0bWx9DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQpkaXYjVE9DIGxpIHsNCiAgICBsaXN0LXN0eWxlOm5vbmU7DQogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOw0KICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7DQogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOw0KfQ0KaDEudGl0bGUgew0KICBmb250LXNpemU6IDI0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgyIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQo8L3N0eWxlPg0KYGBgDQoNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICAgbGlicmFyeSh0aWR5dmVyc2UpDQp9DQppZiAoIXJlcXVpcmUoIkdQQXJvdGF0aW9uIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIkdQQXJvdGF0aW9uIikNCiAgIGxpYnJhcnkoR1BBcm90YXRpb24pDQp9DQppZiAoIXJlcXVpcmUoIm5GYWN0b3JzIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIm5GYWN0b3JzIikNCiAgIGxpYnJhcnkobkZhY3RvcnMpDQp9DQppZiAoIXJlcXVpcmUoInBhcmFtZXRlcnMiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGFyYW1ldGVycyIpDQogICBsaWJyYXJ5KHBhcmFtZXRlcnMpDQp9DQppZiAoIXJlcXVpcmUoImNvcnJwbG90IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImNvcnJwbG90IikNCiAgIGxpYnJhcnkoY29ycnBsb3QpDQp9DQppZiAoIXJlcXVpcmUoImdnY29ycnBsb3QiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2djb3JycGxvdCIpDQogICBsaWJyYXJ5KGdnY29ycnBsb3QpDQp9DQppZiAoIXJlcXVpcmUoImdnZm9ydGlmeSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJnZ2ZvcnRpZnkiKQ0KICAgbGlicmFyeShnZ2ZvcnRpZnkpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQogICBsaWJyYXJ5KGdncGxvdDIpDQp9DQppZiAoIXJlcXVpcmUoIkdHYWxseSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJHR2FsbHkiKQ0KICAgbGlicmFyeShHR2FsbHkpDQp9DQoNCmlmICghcmVxdWlyZSgiQ0NBIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIkNDQSIpDQogICBsaWJyYXJ5KENDQSkNCn0NCmlmICghcmVxdWlyZSgib2xzcnIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygib2xzcnIiKQ0KICAgbGlicmFyeShvbHNycikNCn0NCmlmICghcmVxdWlyZSgicHN5Y2giKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicHN5Y2giKQ0KICAgbGlicmFyeShwc3ljaCkNCn0NCmlmICghcmVxdWlyZSgiY29jcm9uIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImNvY3JvbiIpDQogICBsaWJyYXJ5KGNvY3JvbikNCn0NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgicGFuZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBhbmRlciIpDQogICBsaWJyYXJ5KHBhbmRlcikNCn0NCmlmICghcmVxdWlyZSgiZHBseXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKQ0KICAgbGlicmFyeShkcGx5cikNCn0NCiMjDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmdzID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy5hbGlnbj0nY2VudGVyJywgDQogICAgICAgICAgICAgICAgICAgICAgZmlnLnBvcyA9ICdodCcpDQpgYGANCg0KDQojIEludHJvZHVjdGlvbiANCg0KVGhlIGRhdGEgdGhhdCB3aWxsIGJlIHVzZWQgaW4gdGhpcyBhbmFseXNpcyB3YXMgZXh0cmFjdGVkIGZyb20gYW4gb25saW5lIHN1cnZleS4gVGhlIHN0dWR5IHBvcHVsYXRpb24gY29uc2lzdHMgb2YgdW5kZXJncmFkdWF0ZSBidXNpbmVzcyBzdHVkZW50cyBmcm9tIHR3byBkaWZmZXJlbnQgcmVnaW9uYWwgbm9ydGhlcm4gdW5pdmVyc2l0aWVzLiBUaGUgcHVycG9zZSBvZiB0aGlzIHN0dWR5IGlzIHRvIGlkZW50aWZ5IHRoZSBmYWN0b3JzIHRoYXQgaW5mbHVlbmNlIHN0dWRlbnRz4oCZIGxlYXJuaW5nIGV4cGVyaWVuY2UgYW5kIGltcGFjdCBvbiBzdHVkZW50c+KAmSBsZWFybmluZyBvdXRjb21lcy4gRm9yIHRoaXMgYW5hbHlzaXMsIEkgYW0gZ29pbmcgdG8gZm9jdXMgb24gc2l4IGNvbXBvbmVudHMgb2YgdGhlIHN1cnZleS4gVGhlc2UgaW5jbHVkZSB0aGUgc3R1ZGVudCdzIGVuZ2FnZW1lbnQgaW4gbGVhcm5pbmcsIHRoZSBzdHVkZW50J3MgbGVhcm5pbmcgc3R5bGUsIHdyaXRpbmcgYW5kIHJlYWRpbmcgbG9hZCwgcmVtZWRpYWwgZXhwZXJpZW5jZSwgZW5jb3VyYWdlbWVudCBhbmQgc3VwcG9ydCwgYW5kIGdyb3d0aCBhbmQgZGV2ZWxvcG1lbnQuIEZvciByZWZlcmVuY2UsIHRoZXNlIGFyZSBxdWVzdGlvbnMgNCwgNSwgNiwgOCwgOSwgYW5kIDEwIHJlc3BlY3RpdmVseS4NCg0KIyMgRGF0YSBEb3dubG9hZA0KDQpGaXJzdCwgSSBhbSBnb2luZyB0byBkb3dubG9hZCB0aGUgZGF0YSBmcm9tIGdpdGh1YiwgSSBhbSBhbHNvIHJlbW92aW5nIHRoZSBvZGQgbnVtYmVyZWQgcm93cywgc2luY2UgYWxsIG9mIHRob3NlIGFyZSBibGFuaywgZ2l2aW5nIHVzIGEgdG90YWwgb2YgMzMyIG9ic2VydmF0aW9ucyBhbmQgMTIxIHZhcmlhYmxlcy4NCg0KYGBge3J9DQpzdXJ2ZXkwID0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9BdmFEZVN0L2F0cmlza3N1cnZleS9yZWZzL2hlYWRzL21haW4vYXQtcmlzay1zdXJ2ZXktZGF0YS5jc3YiLCBoZWFkID0gVFJVRSkNCg0Kc3VydmV5IDwtIHN1cnZleTBbc2VxKDIsIG5yb3coc3VydmV5MCksIGJ5ID0gMiksIF0NCg0KYGBgDQoNCg0KU2luY2UgUiBkb2VzIG5vdCBoYXZlIGEgZnVuY3Rpb24gdG8gZmluZCB0aGUgbW9kZWwgb2YgYSBnaXZlbiBkYXRhIHNldCwgSSB3cml0ZSB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uIHRvIGZpbmQgdGhlIG1vZGVsIG9mIGEgZGF0YSBzZXQuDQoNCldlIHdpbGwgcGVyZm9ybSBib3RoIHByaW5jaXBhbCBjb21wb25lbnQgYW5hbHlzaXMgKFBDQSkgYW5kIGV4cGxvcmF0b3J5IGZhY3RvciBhbmFseXNpcyAoRUZBKS4NCg0KYGBge3J9DQpteS5tb2RlID0gZnVuY3Rpb24oZGF0YXNldCl7DQogIGZyZXEudGJsID0gdGFibGUoZGF0YXNldCkNCiAgbWF4LmZyZXEuaWQ9d2hpY2goZnJlcS50Ymw9PW1heChmcmVxLnRibCkpDQogIG1vZGU9bmFtZXMoZnJlcS50YmxbbWF4LmZyZXEuaWRdKQ0KICBhcy5udW1lcmljKG1vZGUpDQp9DQpgYGANCg0KIyBIYW5kbGluZyBNaXNzaW5nIFZhbHVlcw0KDQojIyBFbmdhZ2VtZW50IGluIExlYXJuaW5nIE1pc3NpbmcgVmFsdWVzDQoNCkZpcnN0IEkgd2lsbCBoYW5kbGUgdGhlIG1pc3NpbmcgdmFsdWVzIGZvciB0aGUgZW5nYWdlbWVudCBpbiBsZWFybmluZyBwb3J0aW9uLCB3aGljaCBpcyBxdWVzdGlvbnMgNC4xIC0gNC4yMS4gSSBjcmVhdGVkIGEgc2VwYXJhdGUgZGF0YSBzZXQgZm9yIGNhbGxlZCAiRUlMIiwgdGhlbiBJIGltcHV0ZWQgdGhlIG1pc3NpbmcgdmFsdWUgb2YgdGhpcyBkYXRhIHNldCBieSByZXBsYWNpbmcgdGhlIG1pc3NpbmcgdmFsdWUgaW4gZWFjaCBvZiB0aGUgMTIgaXRlbXMgd2l0aCB0aGUgbW9kZSBvZiB0aGUgY29ycmVzcG9uZGluZyBzdXJ2ZXkgaXRlbXMuIA0KDQpgYGB7cn0NCkVJTDwtIHN1cnZleVssIGMoInE0MSIsICJxNDIiLCAicTQzIiwgInE0NCIsICJxNDUiLCAicTQ2IiwgInE0NyIsICJxNDgiLCAicTQ5IiwgInE0MTAiLCAicTQxMSIsICJxNDEyIiwgInE0MTMiLCAicTQxNCIsICJxNDE1IiwgInE0MTYiLCAicTQxNyIsICJxNDE4IiwgInE0MTkiLCAicTQyMCIsICJxNDIxIildDQoNCg0KZm9yIChpIGluIDE6MjEpIHsNCiAgRUlMWyxpXVtpcy5uYShFSUxbLGldKV09bXkubW9kZShFSUxbLGldKQ0KfQ0KYGBgDQoNCkkgd2lsbCBkbyB0aGUgc2FtZSBmb3IgdGhlIG5leHQgZml2ZSBzdXJ2ZXkgY29tcG9uZW50cyBzaW5jZSBub25lIG9mIHRoZW0gY29udGFpbiB0b28gbWFueSBtaXNzaW5nIHZhbHVlcy4uLg0KDQpTdHVkZW50IGVuZ2FnZW1lbnQgaW4gbGVhcm5pbmcuLi4NCg0KYGBge3J9DQpTTFM8LSBzdXJ2ZXlbLCBjKCJxNTEiLCAicTUyIiwgInE1MyIsICJxNTQiLCAicTU1IiwgInE1NiIpXQ0KDQpmb3IgKGkgaW4gMTo2KSB7DQogIFNMU1ssaV1baXMubmEoU0xTWyxpXSldPW15Lm1vZGUoU0xTWyxpXSkNCn0NCmBgYA0KDQp3cml0aW5nIGFuZCByZWFkaW5nIGxvYWQuLi4NCg0KYGBge3J9DQpXUkw8LSBzdXJ2ZXlbLCBjKCJxNjEiLCAicTYyIiwgInE2MyIpXQ0KDQpmb3IgKGkgaW4gMTozKSB7DQogIFdSTFssaV1baXMubmEoV1JMWyxpXSldPW15Lm1vZGUoV1JMWyxpXSkNCn0NCmBgYA0KDQpSZW1lZGlhbCBleHBlcmllbmNlLi4uDQoNCmBgYHtyfQ0KUkU8LSBzdXJ2ZXlbLCBjKCJxODEiLCAicTgyIiwgInE4MyIsICJxODQiLCAicTg1IiwgInE4NiIsICJxODciLCAicTg4IiwgInE4OSIpXQ0KDQpmb3IgKGkgaW4gMTo5KSB7DQogIFJFWyxpXVtpcy5uYShSRVssaV0pXT1teS5tb2RlKFJFWyxpXSkNCn0NCmBgYA0KDQplbmNvdXJhZ2VtZW50IGFuZCBzdXBwb3J0Li4uDQoNCmBgYHtyfQ0KRUFTPC0gc3VydmV5WywgYygicTkxIiwgInE5MiIsICJxOTMiLCAicTk0IiwgInE5NSIsICJxOTYiLCAicTk3IildDQoNCmZvciAoaSBpbiAxOjcpIHsNCiAgRUFTWyxpXVtpcy5uYShFQVNbLGldKV09bXkubW9kZShFQVNbLGldKQ0KfQ0KYGBgDQoNCmdyb3d0aCBhbmQgZGV2ZWxvcG1lbnQNCg0KYGBge3J9DQpHQUQ8LSBzdXJ2ZXlbLCBjKCJxMTAxIiwgInExMDIiLCAicTEwMyIsICJxMTA0IiwgInExMDUiLCAicTEwNiIsICJxMTA3IiwgInExMDgiLCAicTEwOSIsICJxMTAxMCIsICJxMTAxMSIsICJxMTAxMiIsICJxMTAxMyIsICJxMTAxNCIsICJxMTAxNSIpXQ0KDQpmb3IgKGkgaW4gMToxNSkgew0KICBHQURbLGldW2lzLm5hKEdBRFssaV0pXT1teS5tb2RlKEdBRFssaV0pDQp9DQpgYGANCg0KIyBWYWxpZGl0eSBhbmQgUmVsaWFiaWxpdHkgQW5hbHlzZXMNCg0KTmV4dCwgSSBhbSBnb2luZyB0byByZXBvcnQgdGhlIG1lYXN1cmVzIG9mIHZhbGlkaXR5IGFuZCByZWxpYWJpbGl0eSBvbiBlYWNoIG9mIHRoZSBzaXggY29tcG9uZW50cy4gSSB3aWxsIGRvIHRoaXMgYnkgZmlyc3RzIGxvb2tpbmcgYXQgY29ycmVsYXRpb24gcGxvdHMgdG8gc2VlIHRoZSByZWxldmFuY2Ugb2YgdGhlIFBDQSBwcm9jZWR1cmUuIEkgd2lsbCB0aGVuIGNhbGN1bGF0ZSBDcm9uYmFjaCdzIGFscGhhIGFuZCA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbHMuIA0KDQojIyBFbmdhZ2VtZW50IGluIExlYXJuaW5nIFF1ZXN0aW9uYWlyZQ0KDQpgYGB7ciBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gNiwgZmlnLmNhcD0iVGhlIHBhaXJ3aXNlIGNvcnJlbGF0aW9uIHBsb3QgcmV2ZWFscyB0aGUgcG90ZW50aWFsIHJlbGV2YW5jZSBvZiBQQ0EuIFRoZSBzaGFwZSBvZiBhbiBlbGxpcHNlIHJlcHJlc2VudHMgdGhlIGNvcnJlbGF0aW9uLiBUaGUgc2tpbm5pZXIgdGhlIGVsbGlwc2UsIHRoZSBoaWdoZXIgdGhlIGNvcnJlbGF0aW9uLiBUaGUgZGlyZWN0aW9uIHJlZmxlY3RzIHdoZXRoZXIgYSBjb3JyZWxhdGlvbiBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4gVGhlIG9mZi1kaWFnb25hbCBkaXJlY3Rpb24gaW1wbGllcyBzIHBvc2l0aXZlIGNvcnJlbGF0aW9uIHdoaWxlIHRoZSBtYWluIGRpYWdvbmFsIGRpcmVjdGlvbiBpbXBsaWVzIGEgbmVnYXRpdmUgYXNzb2NpYXRpb24uIn0NCiMjDQpNPWNvcihFSUwpDQpjb3JycGxvdC5taXhlZChNLCBsb3dlci5jb2wgPSAicHVycGxlIiwgdXBwZXIgPSAiZWxsaXBzZSIsIG51bWJlci5jZXggPSAuNywgdGwuY2V4ID0gMC43KQ0KYGBgDQoNClRoZSBjaGFydCBzaG93cyB0aGUgbW9kZXJhdGUgYXNzb2NpYXRpb24gYmV0d2VlbiBpbmRpdmlkdWFsIHN1cnZleSBpdGVtcy4gVGhpcyBpbXBsaWVzIHRoYXQgdGhlIFBDQSBpcyByZWxldmFudCBpbiBhZ2dyZWdhdGluZyB0aGUgaW5mb3JtYXRpb24gaW4gdGhlIHN1cnZleSBpdGVtcy4NCg0KYGBge3J9DQpjcm9uYmFjaC5zYyA9IGFzLm51bWVyaWMoYWxwaGEoRUlMKSR0b3RhbFsxXSkNCkNJLnNjID0gY3JvbmJhY2guYWxwaGEuQ0koYWxwaGE9Y3JvbmJhY2guc2MsIG49MTA0LCBpdGVtcz02LCBjb25mLmxldmVsID0gMC45NSkNCkNJLmNvbXAgPSBjYmluZChMQ0kgPSBDSS5zY1sxXSwgYWxwaGEgPSBjcm9uYmFjaC5zYywgVUNJID1DSS5zY1syXSkNCnJvdy5uYW1lcyhDSS5jb21wKSA9ICIiDQpwYW5kZXIoQ0kuY29tcCwgY2FwdGlvbj0iQ29uZm9kZW5jZSBJbnRlcnZhbCBvZiBDcmFuYmFjaCBBbHBoYSIpDQpgYGANCkhlcmUsIENyb25iYWNoJ3MgYWxwaGEgaXMgMC44NzgsIHdpdGggYSBjb25maWRlbmNlIGludGVydmFsIG9mICgwLjgzOCwgMC45MTEpLCBzdWdnZXN0aW5nIHRoYXQgdGhlIGl0ZW1zIGluIHRoZSBlbmdhZ2VtZW50IGluIGxlYXJuaW5nIGNvbXBvbmVudCBoYXZlIHJlbGF0aXZlbHkgaGlnaCBpbnRlcm5hbCBjb25zaXN0ZW5jeS4gDQoNCg0KDQojIyBTdHVkZW50cyBMZWFybmluZyBTdHlsZQ0KDQoNCmBgYHtyIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA2LCBmaWcuY2FwPSJUaGUgcGFpcndpc2UgY29ycmVsYXRpb24gcGxvdCByZXZlYWxzIHRoZSBwb3RlbnRpYWwgcmVsZXZhbmNlIG9mIFBDQS4gVGhlIHNoYXBlIG9mIGFuIGVsbGlwc2UgcmVwcmVzZW50cyB0aGUgY29ycmVsYXRpb24uIFRoZSBza2lubmllciB0aGUgZWxsaXBzZSwgdGhlIGhpZ2hlciB0aGUgY29ycmVsYXRpb24uIFRoZSBkaXJlY3Rpb24gcmVmbGVjdHMgd2hldGhlciBhIGNvcnJlbGF0aW9uIGlzIHBvc2l0aXZlIG9yIG5lZ2F0aXZlLiBUaGUgb2ZmLWRpYWdvbmFsIGRpcmVjdGlvbiBpbXBsaWVzIHMgcG9zaXRpdmUgY29ycmVsYXRpb24gd2hpbGUgdGhlIG1haW4gZGlhZ29uYWwgZGlyZWN0aW9uIGltcGxpZXMgYSBuZWdhdGl2ZSBhc3NvY2lhdGlvbi4ifQ0KIyMNCk0xPWNvcihTTFMpDQpjb3JycGxvdC5taXhlZChNMSwgbG93ZXIuY29sID0gInB1cnBsZSIsIHVwcGVyID0gImVsbGlwc2UiLCBudW1iZXIuY2V4ID0gLjcsIHRsLmNleCA9IDAuNykNCg0KYGBgDQoNCmBgYHtyfQ0KY3JvbmJhY2guc2MgPSBhcy5udW1lcmljKGFscGhhKFNMUykkdG90YWxbMV0pDQpDSS5zYyA9IGNyb25iYWNoLmFscGhhLkNJKGFscGhhPWNyb25iYWNoLnNjLCBuPTEwNCwgaXRlbXM9NiwgY29uZi5sZXZlbCA9IDAuOTUpDQpDSS5jb21wID0gY2JpbmQoTENJID0gQ0kuc2NbMV0sIGFscGhhID0gY3JvbmJhY2guc2MsIFVDSSA9Q0kuc2NbMl0pDQpyb3cubmFtZXMoQ0kuY29tcCkgPSAiIg0KcGFuZGVyKENJLmNvbXAsIGNhcHRpb249IkNvbmZvZGVuY2UgSW50ZXJ2YWwgb2YgQ3JhbmJhY2ggQWxwaGEiKQ0KYGBgDQpIZXJlLCBDcm9uYmFjaCdzIGFscGhhIGlzIDAuODQ3NCwgd2l0aCBhIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgKDAuNzk3LCAwLjg4ODcpLCBzdWdnZXN0aW5nIHRoYXQgdGhlIGl0ZW1zIGluIHRoZSBlbmdhZ2VtZW50IGluIGxlYXJuaW5nIGNvbXBvbmVudCBoYXZlIHJlbGF0aXZlbHkgaGlnaCBpbnRlcm5hbCBjb25zaXN0ZW5jeS4NCg0KDQojIyBXcml0aW5nIGFuZCBSZWFkaW5nIExvYWQNCg0KDQpgYGB7ciBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gNiwgZmlnLmNhcD0iVGhlIHBhaXJ3aXNlIGNvcnJlbGF0aW9uIHBsb3QgcmV2ZWFscyB0aGUgcG90ZW50aWFsIHJlbGV2YW5jZSBvZiBQQ0EuIFRoZSBzaGFwZSBvZiBhbiBlbGxpcHNlIHJlcHJlc2VudHMgdGhlIGNvcnJlbGF0aW9uLiBUaGUgc2tpbm5pZXIgdGhlIGVsbGlwc2UsIHRoZSBoaWdoZXIgdGhlIGNvcnJlbGF0aW9uLiBUaGUgZGlyZWN0aW9uIHJlZmxlY3RzIHdoZXRoZXIgYSBjb3JyZWxhdGlvbiBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4gVGhlIG9mZi1kaWFnb25hbCBkaXJlY3Rpb24gaW1wbGllcyBzIHBvc2l0aXZlIGNvcnJlbGF0aW9uIHdoaWxlIHRoZSBtYWluIGRpYWdvbmFsIGRpcmVjdGlvbiBpbXBsaWVzIGEgbmVnYXRpdmUgYXNzb2NpYXRpb24uIn0NCiMjDQpNMj1jb3IoV1JMKQ0KY29ycnBsb3QubWl4ZWQoTTIsIGxvd2VyLmNvbCA9ICJwdXJwbGUiLCB1cHBlciA9ICJlbGxpcHNlIiwgbnVtYmVyLmNleCA9IC43LCB0bC5jZXggPSAwLjcpDQpgYGANCmBgYHtyfQ0KY3JvbmJhY2guc2MgPSBhcy5udW1lcmljKGFscGhhKFdSTCkkdG90YWxbMV0pDQpDSS5zYyA9IGNyb25iYWNoLmFscGhhLkNJKGFscGhhPWNyb25iYWNoLnNjLCBuPTEwNCwgaXRlbXM9NiwgY29uZi5sZXZlbCA9IDAuOTUpDQpDSS5jb21wID0gY2JpbmQoTENJID0gQ0kuc2NbMV0sIGFscGhhID0gY3JvbmJhY2guc2MsIFVDSSA9Q0kuc2NbMl0pDQpyb3cubmFtZXMoQ0kuY29tcCkgPSAiIg0KcGFuZGVyKENJLmNvbXAsIGNhcHRpb249IkNvbmZvZGVuY2UgSW50ZXJ2YWwgb2YgQ3JhbmJhY2ggQWxwaGEiKQ0KYGBgDQoNCkhlcmUsIENyb25iYWNoJ3MgYWxwaGEgaXMgMC40OTEsIHdpdGggYSBjb25maWRlbmNlIGludGVydmFsIG9mICgwLjMyMzQsIDAuNjI5MSksIHN1Z2dlc3RpbmcgdGhhdCB0aGUgaXRlbXMgaW4gdGhlIGVuZ2FnZW1lbnQgaW4gbGVhcm5pbmcgY29tcG9uZW50IGhhdmUgcmVsYXRpdmVseSBsb3cgaW50ZXJuYWwgY29uc2lzdGVuY3kuIFRoaXMgc3VnZ2VzdHMgdGhhdCB0aGUgcmVhZGluZyBhbmQgd3JpdGluZyBsb2FkIGNvbXBvbmVudCBvZiB0aGlzIHN1cnZleSBpcyBub3QgcmVsaWFibGUuDQoNCiMjIFJlbWlkaWFsIEV4cGVyaWVuY2UNCg0KDQpgYGB7ciBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gNiwgZmlnLmNhcD0iVGhlIHBhaXJ3aXNlIGNvcnJlbGF0aW9uIHBsb3QgcmV2ZWFscyB0aGUgcG90ZW50aWFsIHJlbGV2YW5jZSBvZiBQQ0EuIFRoZSBzaGFwZSBvZiBhbiBlbGxpcHNlIHJlcHJlc2VudHMgdGhlIGNvcnJlbGF0aW9uLiBUaGUgc2tpbm5pZXIgdGhlIGVsbGlwc2UsIHRoZSBoaWdoZXIgdGhlIGNvcnJlbGF0aW9uLiBUaGUgZGlyZWN0aW9uIHJlZmxlY3RzIHdoZXRoZXIgYSBjb3JyZWxhdGlvbiBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4gVGhlIG9mZi1kaWFnb25hbCBkaXJlY3Rpb24gaW1wbGllcyBzIHBvc2l0aXZlIGNvcnJlbGF0aW9uIHdoaWxlIHRoZSBtYWluIGRpYWdvbmFsIGRpcmVjdGlvbiBpbXBsaWVzIGEgbmVnYXRpdmUgYXNzb2NpYXRpb24uIn0NCiMjDQpNMz1jb3IoUkUpDQpjb3JycGxvdC5taXhlZChNMywgbG93ZXIuY29sID0gInB1cnBsZSIsIHVwcGVyID0gImVsbGlwc2UiLCBudW1iZXIuY2V4ID0gLjcsIHRsLmNleCA9IDAuNykNCmBgYA0KYGBge3J9DQpjcm9uYmFjaC5zYyA9IGFzLm51bWVyaWMoYWxwaGEoUkUpJHRvdGFsWzFdKQ0KQ0kuc2MgPSBjcm9uYmFjaC5hbHBoYS5DSShhbHBoYT1jcm9uYmFjaC5zYywgbj0xMDQsIGl0ZW1zPTYsIGNvbmYubGV2ZWwgPSAwLjk1KQ0KQ0kuY29tcCA9IGNiaW5kKExDSSA9IENJLnNjWzFdLCBhbHBoYSA9IGNyb25iYWNoLnNjLCBVQ0kgPUNJLnNjWzJdKQ0Kcm93Lm5hbWVzKENJLmNvbXApID0gIiINCnBhbmRlcihDSS5jb21wLCBjYXB0aW9uPSJDb25mb2RlbmNlIEludGVydmFsIG9mIENyYW5iYWNoIEFscGhhIikNCmBgYA0KSGVyZSwgQ3JvbmJhY2gncyBhbHBoYSBpcyAwLjgwNywgd2l0aCBhIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgKDAuNzQ0LCAwLjg1OSksIHN1Z2dlc3RpbmcgdGhhdCB0aGUgaXRlbXMgaW4gdGhlIGVuZ2FnZW1lbnQgaW4gbGVhcm5pbmcgY29tcG9uZW50IGhhdmUgcmVsYXRpdmVseSBoaWdoIGludGVybmFsIGNvbnNpc3RlbmN5Lg0KDQojIyBFbmNvdXJlZ21lbnQgYW5kIFN1cHBvcnQNCg0KDQpgYGB7ciBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gNiwgZmlnLmNhcD0iVGhlIHBhaXJ3aXNlIGNvcnJlbGF0aW9uIHBsb3QgcmV2ZWFscyB0aGUgcG90ZW50aWFsIHJlbGV2YW5jZSBvZiBQQ0EuIFRoZSBzaGFwZSBvZiBhbiBlbGxpcHNlIHJlcHJlc2VudHMgdGhlIGNvcnJlbGF0aW9uLiBUaGUgc2tpbm5pZXIgdGhlIGVsbGlwc2UsIHRoZSBoaWdoZXIgdGhlIGNvcnJlbGF0aW9uLiBUaGUgZGlyZWN0aW9uIHJlZmxlY3RzIHdoZXRoZXIgYSBjb3JyZWxhdGlvbiBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4gVGhlIG9mZi1kaWFnb25hbCBkaXJlY3Rpb24gaW1wbGllcyBzIHBvc2l0aXZlIGNvcnJlbGF0aW9uIHdoaWxlIHRoZSBtYWluIGRpYWdvbmFsIGRpcmVjdGlvbiBpbXBsaWVzIGEgbmVnYXRpdmUgYXNzb2NpYXRpb24uIn0NCiMjDQpNND1jb3IoRUFTKQ0KY29ycnBsb3QubWl4ZWQoTTQsIGxvd2VyLmNvbCA9ICJwdXJwbGUiLCB1cHBlciA9ICJlbGxpcHNlIiwgbnVtYmVyLmNleCA9IC43LCB0bC5jZXggPSAwLjcpDQpgYGANCmBgYHtyfQ0KY3JvbmJhY2guc2MgPSBhcy5udW1lcmljKGFscGhhKEVBUykkdG90YWxbMV0pDQpDSS5zYyA9IGNyb25iYWNoLmFscGhhLkNJKGFscGhhPWNyb25iYWNoLnNjLCBuPTEwNCwgaXRlbXM9NiwgY29uZi5sZXZlbCA9IDAuOTUpDQpDSS5jb21wID0gY2JpbmQoTENJID0gQ0kuc2NbMV0sIGFscGhhID0gY3JvbmJhY2guc2MsIFVDSSA9Q0kuc2NbMl0pDQpyb3cubmFtZXMoQ0kuY29tcCkgPSAiIg0KcGFuZGVyKENJLmNvbXAsIGNhcHRpb249IkNvbmZvZGVuY2UgSW50ZXJ2YWwgb2YgQ3JhbmJhY2ggQWxwaGEiKQ0KYGBgDQpIZXJlLCBDcm9uYmFjaCdzIGFscGhhIGlzIDAuODMzLCB3aXRoIGEgY29uZmlkZW5jZSBpbnRlcnZhbCBvZiAoMC43NzgsIDAuODc4KSwgc3VnZ2VzdGluZyB0aGF0IHRoZSBpdGVtcyBpbiB0aGUgZW5nYWdlbWVudCBpbiBsZWFybmluZyBjb21wb25lbnQgaGF2ZSByZWxhdGl2ZWx5IGhpZ2ggaW50ZXJuYWwgY29uc2lzdGVuY3kuDQoNCiMjIEdyb3d0aCBhbmQgRGV2ZWxvcG1lbnQgDQoNCg0KYGBge3IgZmlnLndpZHRoID0gNiwgZmlnLmhlaWdodCA9IDYsIGZpZy5jYXA9IlRoZSBwYWlyd2lzZSBjb3JyZWxhdGlvbiBwbG90IHJldmVhbHMgdGhlIHBvdGVudGlhbCByZWxldmFuY2Ugb2YgUENBLiBUaGUgc2hhcGUgb2YgYW4gZWxsaXBzZSByZXByZXNlbnRzIHRoZSBjb3JyZWxhdGlvbi4gVGhlIHNraW5uaWVyIHRoZSBlbGxpcHNlLCB0aGUgaGlnaGVyIHRoZSBjb3JyZWxhdGlvbi4gVGhlIGRpcmVjdGlvbiByZWZsZWN0cyB3aGV0aGVyIGEgY29ycmVsYXRpb24gaXMgcG9zaXRpdmUgb3IgbmVnYXRpdmUuIFRoZSBvZmYtZGlhZ29uYWwgZGlyZWN0aW9uIGltcGxpZXMgcyBwb3NpdGl2ZSBjb3JyZWxhdGlvbiB3aGlsZSB0aGUgbWFpbiBkaWFnb25hbCBkaXJlY3Rpb24gaW1wbGllcyBhIG5lZ2F0aXZlIGFzc29jaWF0aW9uLiJ9DQojIw0KTTU9Y29yKEdBRCkNCmNvcnJwbG90Lm1peGVkKE01LCBsb3dlci5jb2wgPSAicHVycGxlIiwgdXBwZXIgPSAiZWxsaXBzZSIsIG51bWJlci5jZXggPSAuNywgdGwuY2V4ID0gMC43KQ0KYGBgDQpgYGB7cn0NCmNyb25iYWNoLnNjID0gYXMubnVtZXJpYyhhbHBoYShHQUQpJHRvdGFsWzFdKQ0KQ0kuc2MgPSBjcm9uYmFjaC5hbHBoYS5DSShhbHBoYT1jcm9uYmFjaC5zYywgbj0xMDQsIGl0ZW1zPTYsIGNvbmYubGV2ZWwgPSAwLjk1KQ0KQ0kuY29tcCA9IGNiaW5kKExDSSA9IENJLnNjWzFdLCBhbHBoYSA9IGNyb25iYWNoLnNjLCBVQ0kgPUNJLnNjWzJdKQ0Kcm93Lm5hbWVzKENJLmNvbXApID0gIiINCnBhbmRlcihDSS5jb21wLCBjYXB0aW9uPSJDb25mb2RlbmNlIEludGVydmFsIG9mIENyYW5iYWNoIEFscGhhIikNCmBgYA0KSGVyZSwgQ3JvbmJhY2gncyBhbHBoYSBpcyAwLjk0Nywgd2l0aCBhIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgKDAuOTI5LCAwLjk2MSksIHN1Z2dlc3RpbmcgdGhhdCB0aGUgaXRlbXMgaW4gdGhlIGVuZ2FnZW1lbnQgaW4gbGVhcm5pbmcgY29tcG9uZW50IGhhdmUgcmVsYXRpdmVseSBoaWdoIGludGVybmFsIGNvbnNpc3RlbmN5Lg0KDQoNCiMgUENBIA0KDQpUaGlzIHNlY3Rpb24gcmVwb3J0IHRoZSByZXN1bHRzIG9mIHRoZSBwcmluY2lwbGUgY29tcG9uZW50IGFuYWx5c2lzLiBUaGUgc2lnbmlmaWNhbnQgUENzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGFuYWx5dGljIGRhdGEgc2V0IGZvciBmdXR1cmUgbW9kZWxpbmcuIEJ1dCBiZWZvcmUgdGhpcyBJIHdpbGwgZGVmaW5lIHRoZSBmb2xsb3dpbmcgdHdvIFIgZnVuY3Rpb25zIGFuZCB1c2UgdGhlbSBpbiB0aGUgUENBIGFuYWx5c2lzLiBUaGVuLCB0aGUgbXkubG9hZGluZ3MudmFyIGlzIHVzZWQgdG8gZXh0cmFjdCB0aGUgcHJvcG9ydGlvbiBvZiB2YXJpYW5jZSBhbmQgTXkuDQoNCmBgYHtyIH0NCk15LnBsb3RuU2NyZWUgPSBmdW5jdGlvbihtYXQsIGxlZ2VuZCA9IFRSVUUsIG1ldGhvZCA9ImZhY3RvcnMiLCBtYWluKXsNCiAgICAjIG1hdCA9IGRhdGEgbWF0cml4DQogICAgIyBtZXRob2QgPSBjKCJmYWN0b3JzIiwgImNvbXBvbmVudHMiKSwgZGVmYXVsdCBpcyAiZmFjdG9ycyIuDQogICAgIyBtYWluID0gdGl0bGUgb2YgdGhlIHBsb3QNCiAgICBldiA8LSBlaWdlbihjb3IobWF0KSkgICAgIyBnZXQgZWlnZW52YWx1ZXMNCiAgICBhcCA8LSBwYXJhbGxlbChzdWJqZWN0PW5yb3cobWF0KSx2YXI9bmNvbChtYXQpLCByZXA9NTAwMCxjZW50PS4wNSkNCiAgICBuU2NyZWUgPSBuU2NyZWUoeD1ldiR2YWx1ZXMsIGFwYXJhbGxlbD1hcCRlaWdlbiRxZXZwZWEsIG1vZGVsPW1ldGhvZCkgIA0KICAgICMjDQogICAgaWYgKCFpbmhlcml0cyhuU2NyZWUsICJuU2NyZWUiKSkgDQogICAgICAgIHN0b3AoIk1ldGhvZCBpcyBvbmx5IGZvciBuU2NyZWUgb2JqZWN0cyIpDQogICAgaWYgKG5TY3JlZSRNb2RlbCA9PSAiY29tcG9uZW50cyIpIA0KICAgICAgICBua2Fpc2VyID0gIkVpZ2VudmFsdWVzID4gbWVhbjogbiA9ICINCiAgICBpZiAoblNjcmVlJE1vZGVsID09ICJmYWN0b3JzIikgDQogICAgICBua2Fpc2VyID0gIkVpZ2VudmFsdWVzID4gemVybzogbiA9ICINCiAgICAjIGF4aXMgbGFiZWxzDQogICAgeGxhYiA9IG5TY3JlZSRNb2RlbA0KICAgIHlsYWIgPSAiRWlnZW52YWx1ZXMiDQogICAgIyMNCiAgICBwYXIoY29sID0gMSwgcGNoID0gMTgpDQogICAgcGFyKG1mcm93ID0gYygxLCAxKSkNCiAgICBlaWcgPC0gblNjcmVlJEFuYWx5c2lzJEVpZ2VudmFsdWVzDQogICAgayA8LSAxOmxlbmd0aChlaWcpDQogICAgcGxvdCgxOmxlbmd0aChlaWcpLCBlaWcsIHR5cGU9ImIiLCBtYWluID0gbWFpbiwgDQogICAgICAgIHhsYWIgPSB4bGFiLCB5bGFiID0geWxhYiwgeWxpbT1jKDAsIDEuMiptYXgoZWlnKSkpDQogICAgIw0KICAgIG5rIDwtIGxlbmd0aChlaWcpDQogICAgbm9jIDwtIG5TY3JlZSRDb21wb25lbnRzJG5vYw0KICAgIHZwLnAgPC0gbG0oZWlnW2Mobm9jICsgMSwgbmspXSB+IGtbYyhub2MgKyAxLCBuayldKQ0KICAgIHggPC0gc3VtKGMoMSwgMSkgKiBjb2VmKHZwLnApKQ0KICAgIHkgPC0gc3VtKGMoMSwgbmspICogY29lZih2cC5wKSkNCiAgICBwYXIoY29sID0gMTApDQogICAgbGluZXMoa1tjKDEsIG5rKV0sIGMoeCwgeSkpDQogICAgcGFyKGNvbCA9IDExLCBwY2ggPSAyMCkNCiAgICBsaW5lcygxOm5rLCBuU2NyZWUkQW5hbHlzaXMkUGFyLkFuYWx5c2lzLCB0eXBlID0gImIiKQ0KICAgIGlmIChsZWdlbmQgPT0gVFJVRSkgew0KICAgICAgICBsZWcudHh0IDwtIGMocGFzdGUobmthaXNlciwgblNjcmVlJENvbXBvbmVudHMkbmthaXNlciksIA0KICAgICAgICAgICAgICAgICAgIGMocGFzdGUoIlBhcmFsbGVsIEFuYWx5c2lzOiBuID0gIiwgblNjcmVlJENvbXBvbmVudHMkbnBhcmFsbGVsKSksIA0KICAgICAgICAgICAgICAgICAgIGMocGFzdGUoIk9wdGltYWwgQ29vcmRpbmF0ZXM6IG4gPSAiLCBuU2NyZWUkQ29tcG9uZW50cyRub2MpKSwgDQogICAgICAgICAgICAgICAgICAgYyhwYXN0ZSgiQWNjZWxlcmF0aW9uIEZhY3RvcjogbiA9ICIsIG5TY3JlZSRDb21wb25lbnRzJG5hZikpDQogICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICBsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gbGVnLnR4dCwgcGNoID0gYygxOCwgMjAsIE5BLCBOQSksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dC5jb2wgPSBjKDEsIDMsIDIsIDQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbCA9IGMoMSwgMywgMiwgNCksIGJ0eT0ibiIsIGNleD0wLjcpDQogICAgfQ0KICAgIG5hZiA8LSBuU2NyZWUkQ29tcG9uZW50cyRuYWYNCiAgICB0ZXh0KHggPSBub2MsIHkgPSBlaWdbbm9jXSwgbGFiZWwgPSAiIChPQykiLCBjZXggPSAwLjcsIA0KICAgICAgICBhZGogPSBjKDAsIDApLCBjb2wgPSAyKQ0KICAgIHRleHQoeCA9IG5hZiArIDEsIHkgPSBlaWdbbmFmICsgMV0sIGxhYmVsID0gIiAoQUYpIiwgDQogICAgICAgIGNleCA9IDAuNywgYWRqID0gYygwLCAwKSwgY29sID0gNCkNCn0NCmBgYA0KDQpgYGB7cn0NCk15LmxvYWRpbmdzLnZhciA8LSBmdW5jdGlvbihtYXQsIG5mY3QsIG1ldGhvZD0iZmEiKXsNCiAgICMgbWF0ID0gIGRhdGEgbWF0cml4DQogICAjIG5mY3QgPSBudW1iZXIgb2YgZmFjdG9ycyBvciBjb21wb25lbnRzDQogICAjIG1ldGhvZCA9IGMoImZhIiwgInBjYSIpLCBkZWZhdWx0ID0gaXMgImZhIi4NCiAgICBpZihtZXRob2QgPT0gImZhIil7IA0KICAgICBmMSA8LSBmYWN0YW5hbChtYXQsIGZhY3RvcnMgPSBuZmN0LCAgcm90YXRpb24gPSAidmFyaW1heCIpDQogICAgIHggPC0gbG9hZGluZ3MoZjEpDQogICAgIHZ4IDwtIGNvbFN1bXMoeF4yKQ0KICAgICB2YXJTUyA9IHJiaW5kKCdTUyBsb2FkaW5ncycgPSB2eCwNCiAgICAgICAgICAgICdQcm9wb3J0aW9uIFZhcicgPSB2eC9ucm93KHgpLA0KICAgICAgICAgICAnQ3VtdWxhdGl2ZSBWYXInID0gY3Vtc3VtKHZ4L25yb3coeCkpKQ0KICAgICB3ZWlnaHQgPSBmMSRsb2FkaW5nc1tdIA0KICAgfSBlbHNlIGlmIChtZXRob2QgPT0gInBjYSIpew0KICAgICBwY2EgPC0gcHJjb21wKG1hdCwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKQ0KICAgICB2YXJTUyA9IHN1bW1hcnkocGNhKSRpbXBvcnRhbmNlWywxOm5mY3RdDQogICAgIHdlaWdodCA9IHBjYSRyb3RhdGlvblssMTpuZmN0XQ0KICB9DQogICAgbGlzdChMb2FkaW5ncyA9IHdlaWdodCwgUHJvcC5WYXIgPSB2YXJTUykNCn0NCmBgYA0KDQpOb3csIHdlIGNhbiBwZXJmb3JtIFBDQSBhbmFseXNpcyBvbiBlYWNoIG9mIHRoZSBzaXggc3VydmV5IGNvbXBvbmVudHMuLi4NCg0KIyMgUENBIEZvciBFSUwgQ29tcG9uZW50IA0KDQpgYGB7ciBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gNn0NCk15LnBsb3RuU2NyZWUobWF0PUVJTCwgbGVnZW5kID0gVFJVRSwgbWV0aG9kID0iY29tcG9uZW50cyIsIA0KICAgICAgICAgICAgICBtYWluPSJEZXRlcm1pbmF0aW9uIG9mIE51bWJlciBvZiBDb21wb25lbnRzXG4gRUlMIChQb3NpdGl2ZSkiKQ0KYGBgDQoNCg0KRmlyc3QsIEkgYW0gZ29pbmcgdG8gZXh0cmFjdCB0aGUgZmFjdG9ycyBvZiB0aGUgZmlyc3QgdHdvIFBDQXMuIFRoZSBQQ0EgZmFjdG9yIGxvYWRpbmdzIGFuZCB0aGUgcHJvcG9ydGlvbiBvZiB2YXJpYW5jZSBleHBsYWluZWQgYnkgdGhlIHJldGFpbmVkIFBDQXMgYXJlIHN1bW1hcml6ZWQgaW4gdGhlIGZvbGxvd2luZyB0YWJsZXMuDQoNCmBgYHtyfQ0KTG9hZGluZ3MgPSBNeS5sb2FkaW5ncy52YXIobWF0PUVJTCwgbmZjdD0yLCBtZXRob2Q9InBjYSIpJExvYWRpbmdzDQojDQojIHBjYSBsb2FkaW5ncw0Ka2FibGUocm91bmQoTG9hZGluZ3MsMyksDQogIGNhcHRpb249IkZhY3RvciBvZiB0aGUgZmlyc3QgZmV3IFBDQXMgYW5kIHRoZSBjdW11bGF0aXZlIHByb3BvcnRpb24NCm9mIHZhcmlhdGlvbiBleHBsYWluZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgUENBcyBpbiB0aGUgRUlMIGNvbXBvbmVudC4iKQ0KYGBgDQoNCmBgYHtyfQ0KVmFyUHJvcCA9IE15LmxvYWRpbmdzLnZhcihtYXQ9RUlMLCBuZmN0PTIsIG1ldGhvZD0icGNhIikkUHJvcC5WYXINCiMgcGNhIGxvYWRpbmdzDQprYWJsZShyb3VuZChWYXJQcm9wLDMpLA0KICAgIGNhcHRpb249IkN1bXVsYXRpdmUgYW5kIHByb3BvcnRpb24gb2YgdmFyaWFuY2VzIGV4cGxhaW5lZCBieSBlYWNoIA0KICAgIHRoZSBwcmluY2lwYWwgY29tcG9uZW50IGluIEVJTC4iKQ0KYGBgDQoNClRoZSBTY3JlZSB0eXBlIG9mIHRlc3Qgc3VnZ2VzdHMgcmV0YWluaW5nIGEgc2luZ2xlIGZhY3Rvci4gVGhlIHByb3BvcnRpb24gb2YgdG90YWwgdmFyaWF0aW9uIGlzIGxvd2VyIHRoYW4gdGhhdCBvZiBQQ0EuSSB1c2VkIHRoZSBQQ0EgbWV0aG9kIGFuZCBleHRyYWN0IHRoZSBmaXJzdCB0d28gcHJpbmNpcGFsIGNvbXBvbmVudHMgZm9yIGZ1dHVyZSBhbmFseXNpcy4gVGhlIHRhYmxlIGFib3ZlIHNob3dzIHRoZSBmYWN0b3IgbG9hZGluZ3Mgb2YgdGhlIGZpcnN0IHR3byBwcmluY2lwYWwgY29tcG9uZW50cy4gV2UgY2FuIHNlZSB0aGF0IGVhY2ggb2YgdGhlIG9yaWdpbmFsIGl0ZW1zIGNvbnRyaWJ1dGVzIHRvIHRoZSB0d28gUENBcyBldmVubHkgaW4gdGVybXMgb2YgdGhlIG1hZ25pdHVkZS4gVGhlIGZpcnN0IFBDQSBjb3VudHMgYWJvdXQgMzAuNiUgb2YgdGhlIHRvdGFsIHZhcmlhdGlvbiBhbmQgdGhlIHNlY29uZCBQQ0EgY291bnRzIDguOSUgb2YgdGhlIHRvdGFsIHZhcmlhdGlvbiBUaGlzIHN1Z2dlc3RzIHRoYXQgd2Ugc2hvdWxkIHJldGFpbiBhIHNpbXBsZSBmYWN0b3IuDQoNCmBgYHtyfQ0KcGNhMSA8LSBwcmNvbXAoRUlMLCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IFRSVUUpDQplaWwuaWR4ID0gcGNhMSR4WywxXQ0KIyMNCmhpc3QoZWlsLmlkeCwNCm1haW49IkRpc3RyaWJ1dGlvbiBvZiBFbmdhZ2VtZW50IGluIExlYXJuaW5nIEluZGV4IiwNCmJyZWFrcyA9IHNlcShtaW4oZWlsLmlkeCksIG1heChlaWwuaWR4KSwgbGVuZ3RoPTkpLA0KeGxhYj0iRUlMIEluZGV4IiwNCnhsaW09cmFuZ2UoZWlsLmlkeCksDQpib3JkZXI9InJlZCIsDQpjb2w9ImxpZ2h0Ymx1ZSIsDQpmcmVxPUZBTFNFDQopDQpgYGANCg0KDQoNCg0KDQoNCiMjIFBDQSBGb3IgU0xTIENvbXBvbmVudCANCmBgYHtyfQ0KTXkucGxvdG5TY3JlZShtYXQ9U0xTLCBsZWdlbmQgPSBUUlVFLCBtZXRob2QgPSJjb21wb25lbnRzIiwgDQogICAgICAgICAgICAgIG1haW49IkRldGVybWluYXRpb24gb2YgTnVtYmVyIG9mIENvbXBvbmVudHNcbiBTTFMgKFBvc2l0aXZlKSIpDQpgYGANCg0KYGBge3J9DQpMb2FkaW5ncyA9IE15LmxvYWRpbmdzLnZhcihtYXQ9U0xTLCBuZmN0PTIsIG1ldGhvZD0icGNhIikkTG9hZGluZ3MNCiMNCiMgcGNhIGxvYWRpbmdzDQprYWJsZShyb3VuZChMb2FkaW5ncywzKSwNCiAgY2FwdGlvbj0iRmFjdG9yIG9mIHRoZSBmaXJzdCBmZXcgUENBcyBhbmQgdGhlIGN1bXVsYXRpdmUgcHJvcG9ydGlvbg0Kb2YgdmFyaWF0aW9uIGV4cGxhaW5lZCBieSB0aGUgY29ycmVzcG9uZGluZyBQQ0FzIGluIHRoZSBTTFMgY29tcG9uZW50LiIpDQpgYGANCg0KYGBge3J9DQpWYXJQcm9wID0gTXkubG9hZGluZ3MudmFyKG1hdD1TTFMsIG5mY3Q9MiwgbWV0aG9kPSJwY2EiKSRQcm9wLlZhcg0KIyBwY2EgbG9hZGluZ3MNCmthYmxlKHJvdW5kKFZhclByb3AsMyksDQogICAgY2FwdGlvbj0iQ3VtdWxhdGl2ZSBhbmQgcHJvcG9ydGlvbiBvZiB2YXJpYW5jZXMgZXhwbGFpbmVkIGJ5IGVhY2ggDQogICAgdGhlIHByaW5jaXBhbCBjb21wb25lbnQgaW4gU0xTLiIpDQpgYGANClRoZSB0YWJsZSBhYm92ZSBzaG93cyB0aGUgZmFjdG9yIGxvYWRpbmdzIG9mIHRoZSBmaXJzdCB0d28gcHJpbmNpcGFsIGNvbXBvbmVudHMuIFdlIGNhbiBzZWUgdGhhdCBlYWNoIG9mIHRoZSBvcmlnaW5hbCBpdGVtcyBjb250cmlidXRlcyB0byB0aGUgdHdvIFBDQXMgZXZlbmx5IGluIHRlcm1zIG9mIHRoZSBtYWduaXR1ZGUuIFRoZSBmaXJzdCBQQ0EgY291bnRzIGFib3V0IDU4LjIlIG9mIHRoZSB0b3RhbCB2YXJpYXRpb24gYW5kIHRoZSBzZWNvbmQgUENBIGNvdW50cyAxNC40JSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIFRoaXMgc3VnZ2VzdHMgdGhhdCB3ZSBzaG91bGQgcmV0YWluIGEgc2ltcGxlIGZhY3Rvci4NCg0KYGBge3J9DQpwY2EyIDwtIHByY29tcChTTFMsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gVFJVRSkNCnNscy5pZHggPSBwY2EyJHhbLDFdDQojIw0KaGlzdChzbHMuaWR4LA0KbWFpbj0iRGlzdHJpYnV0aW9uIG9mIFN0dWRlbnQgTGVhcm5pbmcgSW5kZXgiLA0KYnJlYWtzID0gc2VxKG1pbihzbHMuaWR4KSwgbWF4KHNscy5pZHgpLCBsZW5ndGg9OSksDQp4bGFiPSJTTFMgSW5kZXgiLA0KeGxpbT1yYW5nZShzbHMuaWR4KSwNCmJvcmRlcj0icmVkIiwNCmNvbD0ibGlnaHRibHVlIiwNCmZyZXE9RkFMU0UNCikNCmBgYA0KDQoNCg0KDQoNCg0KDQojIyBQQ0EgRm9yIFdSTCBDb21wb25lbnQgDQpgYGB7cn0NCk15LnBsb3RuU2NyZWUobWF0PVdSTCwgbGVnZW5kID0gVFJVRSwgbWV0aG9kID0iY29tcG9uZW50cyIsIA0KICAgICAgICAgICAgICBtYWluPSJEZXRlcm1pbmF0aW9uIG9mIE51bWJlciBvZiBDb21wb25lbnRzXG4gU0xTIChQb3NpdGl2ZSkiKQ0KYGBgDQoNCmBgYHtyfQ0KTG9hZGluZ3MgPSBNeS5sb2FkaW5ncy52YXIobWF0PVdSTCwgbmZjdD0yLCBtZXRob2Q9InBjYSIpJExvYWRpbmdzDQojDQojIHBjYSBsb2FkaW5ncw0Ka2FibGUocm91bmQoTG9hZGluZ3MsMyksDQogIGNhcHRpb249IkZhY3RvciBvZiB0aGUgZmlyc3QgZmV3IFBDQXMgYW5kIHRoZSBjdW11bGF0aXZlIHByb3BvcnRpb24NCm9mIHZhcmlhdGlvbiBleHBsYWluZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgUENBcyBpbiB0aGUgV1JMIGNvbXBvbmVudC4iKQ0KYGBgDQoNCmBgYHtyfQ0KVmFyUHJvcCA9IE15LmxvYWRpbmdzLnZhcihtYXQ9V1JMLCBuZmN0PTIsIG1ldGhvZD0icGNhIikkUHJvcC5WYXINCiMgcGNhIGxvYWRpbmdzDQprYWJsZShyb3VuZChWYXJQcm9wLDMpLA0KICAgIGNhcHRpb249IkN1bXVsYXRpdmUgYW5kIHByb3BvcnRpb24gb2YgdmFyaWFuY2VzIGV4cGxhaW5lZCBieSBlYWNoIA0KICAgIHRoZSBwcmluY2lwYWwgY29tcG9uZW50IGluIFdSTC4iKQ0KYGBgDQpUaGUgdGFibGUgYWJvdmUgc2hvd3MgdGhlIGZhY3RvciBsb2FkaW5ncyBvZiB0aGUgZmlyc3QgdHdvIHByaW5jaXBhbCBjb21wb25lbnRzLiBXZSBjYW4gc2VlIHRoYXQgZWFjaCBvZiB0aGUgb3JpZ2luYWwgaXRlbXMgY29udHJpYnV0ZXMgdG8gdGhlIHR3byBQQ0FzIGV2ZW5seSBpbiB0ZXJtcyBvZiB0aGUgbWFnbml0dWRlLiBUaGUgZmlyc3QgUENBIGNvdW50cyBhYm91dCA1MC43JSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIGFuZCB0aGUgc2Vjb25kIFBDQSBjb3VudHMgMzEuNCUlIG9mIHRoZSB0b3RhbCB2YXJpYXRpb24gVGhpcyBzdWdnZXN0cyB0aGF0IHdlIHNob3VsZCByZXRhaW4gYSBzaW1wbGUgZmFjdG9yLg0KDQpgYGB7cn0NCnBjYTMgPC0gcHJjb21wKFdSTCwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKQ0Kd3JsLmlkeCA9IHBjYTMkeFssMV0NCiMjDQpoaXN0KHdybC5pZHgsDQptYWluPSJEaXN0cmlidXRpb24gb2YgV3JpdGluZyBhbmQgUmVhZGluZyBMb2FkIEluZGV4IiwNCmJyZWFrcyA9IHNlcShtaW4od3JsLmlkeCksIG1heCh3cmwuaWR4KSwgbGVuZ3RoPTkpLA0KeGxhYj0iV1JMIEluZGV4IiwNCnhsaW09cmFuZ2Uod3JsLmlkeCksDQpib3JkZXI9InJlZCIsDQpjb2w9ImxpZ2h0Ymx1ZSIsDQpmcmVxPUZBTFNFDQopDQpgYGANCg0KDQoNCg0KDQoNCg0KDQoNCiMjIFBDQSBGb3IgUkUgQ29tcG9uZW50IA0KYGBge3J9DQpNeS5wbG90blNjcmVlKG1hdD1SRSwgbGVnZW5kID0gVFJVRSwgbWV0aG9kID0iY29tcG9uZW50cyIsIA0KICAgICAgICAgICAgICBtYWluPSJEZXRlcm1pbmF0aW9uIG9mIE51bWJlciBvZiBDb21wb25lbnRzXG4gUkUgKFBvc2l0aXZlKSIpDQpgYGANCg0KYGBge3J9DQpMb2FkaW5ncyA9IE15LmxvYWRpbmdzLnZhcihtYXQ9UkUsIG5mY3Q9MiwgbWV0aG9kPSJwY2EiKSRMb2FkaW5ncw0KIw0KIyBwY2EgbG9hZGluZ3MNCmthYmxlKHJvdW5kKExvYWRpbmdzLDMpLA0KICBjYXB0aW9uPSJGYWN0b3Igb2YgdGhlIGZpcnN0IGZldyBQQ0FzIGFuZCB0aGUgY3VtdWxhdGl2ZSBwcm9wb3J0aW9uDQpvZiB2YXJpYXRpb24gZXhwbGFpbmVkIGJ5IHRoZSBjb3JyZXNwb25kaW5nIFBDQXMgaW4gdGhlIFJFIGNvbXBvbmVudC4iKQ0KYGBgDQoNCmBgYHtyfQ0KVmFyUHJvcCA9IE15LmxvYWRpbmdzLnZhcihtYXQ9UkUsIG5mY3Q9MiwgbWV0aG9kPSJwY2EiKSRQcm9wLlZhcg0KIyBwY2EgbG9hZGluZ3MNCmthYmxlKHJvdW5kKFZhclByb3AsMyksDQogICAgY2FwdGlvbj0iQ3VtdWxhdGl2ZSBhbmQgcHJvcG9ydGlvbiBvZiB2YXJpYW5jZXMgZXhwbGFpbmVkIGJ5IGVhY2ggDQogICAgdGhlIHByaW5jaXBhbCBjb21wb25lbnQgaW4gUkUuIikNCmBgYA0KVGhlIHRhYmxlIGFib3ZlIHNob3dzIHRoZSBmYWN0b3IgbG9hZGluZ3Mgb2YgdGhlIGZpcnN0IHR3byBwcmluY2lwYWwgY29tcG9uZW50cy4gV2UgY2FuIHNlZSB0aGF0IGVhY2ggb2YgdGhlIG9yaWdpbmFsIGl0ZW1zIGNvbnRyaWJ1dGVzIHRvIHRoZSB0d28gUENBcyBldmVubHkgaW4gdGVybXMgb2YgdGhlIG1hZ25pdHVkZS4gVGhlIGZpcnN0IFBDQSBjb3VudHMgYWJvdXQgNDAuNCUgb2YgdGhlIHRvdGFsIHZhcmlhdGlvbiBhbmQgdGhlIHNlY29uZCBQQ0EgY291bnRzIDE1JSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIFRoaXMgc3VnZ2VzdHMgdGhhdCB3ZSBzaG91bGQgcmV0YWluIGEgc2ltcGxlIGZhY3Rvci4NCg0KYGBge3J9DQpwY2E0IDwtIHByY29tcChSRSwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKQ0KcmUuaWR4ID0gcGNhNCR4WywxXQ0KIyMNCmhpc3QocmUuaWR4LA0KbWFpbj0iRGlzdHJpYnV0aW9uIG9mIFJlbWlkaWFsIEV4cGVyaWVuY2UgSW5kZXgiLA0KYnJlYWtzID0gc2VxKG1pbihyZS5pZHgpLCBtYXgocmUuaWR4KSwgbGVuZ3RoPTkpLA0KeGxhYj0iUkUgSW5kZXgiLA0KeGxpbT1yYW5nZShyZS5pZHgpLA0KYm9yZGVyPSJyZWQiLA0KY29sPSJsaWdodGJsdWUiLA0KZnJlcT1GQUxTRQ0KKQ0KYGBgDQoNCkhlcmUsIHNpbmNlIHRoZSBSRSBpbmRleCBkaXN0cmlidXRpb24gaXMgc2NyZXdlZCB0byB0aGUgbGVmdC4gV2UgY2FuIHBlcmZvcm0gYSBib3ggY294IHRyYW5zZm9ybWF0aW9uIHRvIGZpeCB0aGlzLiANCg0KYGBge3J9DQpNMT1jb3IoY2JpbmQoZWlsLmlkeCwgRUlMLCBzbHMuaWR4LCBTTFMsIHdybC5pZHgsIFdSTCkpDQojY29ycnBsb3QoTSwgdHlwZSA9ICJ1cHBlciIsIG1ldGhvZCA9ICJlbGxpcHNlIiwgbWFpbj0iUGFpcndpc2UgQ29ycmVsYXRpb24gUGxvdDogU2VsZi1Db21wYXNzaW9uIFNjYWxlIikNCmNvcnJwbG90Lm1peGVkKE0xLCBsb3dlci5jb2wgPSAicHVycGxlIiwgdXBwZXIgPSAiZWxsaXBzZSIsIG51bWJlci5jZXggPSAuNywgdGwuY2V4ID0gMC43KQ0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQojIyBQQ0EgRm9yIEVBUyBDb21wb25lbnQgDQpgYGB7cn0NCk15LnBsb3RuU2NyZWUobWF0PUVBUywgbGVnZW5kID0gVFJVRSwgbWV0aG9kID0iY29tcG9uZW50cyIsIA0KICAgICAgICAgICAgICBtYWluPSJEZXRlcm1pbmF0aW9uIG9mIE51bWJlciBvZiBDb21wb25lbnRzXG4gU0xTIChQb3NpdGl2ZSkiKQ0KYGBgDQoNCmBgYHtyfQ0KTG9hZGluZ3MgPSBNeS5sb2FkaW5ncy52YXIobWF0PUVBUywgbmZjdD0yLCBtZXRob2Q9InBjYSIpJExvYWRpbmdzDQojDQojIHBjYSBsb2FkaW5ncw0Ka2FibGUocm91bmQoTG9hZGluZ3MsMyksDQogIGNhcHRpb249IkZhY3RvciBvZiB0aGUgZmlyc3QgZmV3IFBDQXMgYW5kIHRoZSBjdW11bGF0aXZlIHByb3BvcnRpb24NCm9mIHZhcmlhdGlvbiBleHBsYWluZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgUENBcyBpbiB0aGUgRUFTIGNvbXBvbmVudC4iKQ0KYGBgDQoNCmBgYHtyfQ0KVmFyUHJvcCA9IE15LmxvYWRpbmdzLnZhcihtYXQ9RUFTLCBuZmN0PTIsIG1ldGhvZD0icGNhIikkUHJvcC5WYXINCiMgcGNhIGxvYWRpbmdzDQprYWJsZShyb3VuZChWYXJQcm9wLDMpLA0KICAgIGNhcHRpb249IkN1bXVsYXRpdmUgYW5kIHByb3BvcnRpb24gb2YgdmFyaWFuY2VzIGV4cGxhaW5lZCBieSBlYWNoIA0KICAgIHRoZSBwcmluY2lwYWwgY29tcG9uZW50IGluIEVBUy4iKQ0KYGBgDQpUaGUgdGFibGUgYWJvdmUgc2hvd3MgdGhlIGZhY3RvciBsb2FkaW5ncyBvZiB0aGUgZmlyc3QgdHdvIHByaW5jaXBhbCBjb21wb25lbnRzLiBXZSBjYW4gc2VlIHRoYXQgZWFjaCBvZiB0aGUgb3JpZ2luYWwgaXRlbXMgY29udHJpYnV0ZXMgdG8gdGhlIHR3byBQQ0FzIGV2ZW5seSBpbiB0ZXJtcyBvZiB0aGUgbWFnbml0dWRlLiBUaGUgZmlyc3QgUENBIGNvdW50cyBhYm91dCA1MC41JSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIGFuZCB0aGUgc2Vjb25kIFBDQSBjb3VudHMgMTQuNCUgb2YgdGhlIHRvdGFsIHZhcmlhdGlvbiBUaGlzIHN1Z2dlc3RzIHRoYXQgd2Ugc2hvdWxkIHJldGFpbiBhIHNpbXBsZSBmYWN0b3IuDQoNCmBgYHtyfQ0KcGNhNSA8LSBwcmNvbXAoRUFTLCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IFRSVUUpDQplYXMuaWR4ID0gcGNhNSR4WywxXQ0KIyMNCmhpc3QoZWFzLmlkeCwNCm1haW49IkRpc3RyaWJ1dGlvbiBvZiBFbmNvdXJhZ21lbnQgYW5kIFN1cHBvcnQgSW5kZXgiLA0KYnJlYWtzID0gc2VxKG1pbihlYXMuaWR4KSwgbWF4KGVhcy5pZHgpLCBsZW5ndGg9OSksDQp4bGFiPSJFQVMgSW5kZXgiLA0KeGxpbT1yYW5nZShlYXMuaWR4KSwNCmJvcmRlcj0icmVkIiwNCmNvbD0ibGlnaHRibHVlIiwNCmZyZXE9RkFMU0UNCikNCmBgYA0KDQoNCg0KDQoNCg0KDQoNCg0KDQojIyBQQ0EgRm9yIEdBRCBDb21wb25lbnQgDQpgYGB7cn0NCk15LnBsb3RuU2NyZWUobWF0PUdBRCwgbGVnZW5kID0gVFJVRSwgbWV0aG9kID0iY29tcG9uZW50cyIsIA0KICAgICAgICAgICAgICBtYWluPSJEZXRlcm1pbmF0aW9uIG9mIE51bWJlciBvZiBDb21wb25lbnRzXG4gR0FEIChQb3NpdGl2ZSkiKQ0KYGBgDQoNCmBgYHtyfQ0KTG9hZGluZ3MgPSBNeS5sb2FkaW5ncy52YXIobWF0PUdBRCwgbmZjdD0yLCBtZXRob2Q9InBjYSIpJExvYWRpbmdzDQojDQojIHBjYSBsb2FkaW5ncw0Ka2FibGUocm91bmQoTG9hZGluZ3MsMyksDQogIGNhcHRpb249IkZhY3RvciBvZiB0aGUgZmlyc3QgZmV3IFBDQXMgYW5kIHRoZSBjdW11bGF0aXZlIHByb3BvcnRpb24NCm9mIHZhcmlhdGlvbiBleHBsYWluZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgUENBcyBpbiB0aGUgR0FEIGNvbXBvbmVudC4iKQ0KYGBgDQoNCmBgYHtyfQ0KVmFyUHJvcCA9IE15LmxvYWRpbmdzLnZhcihtYXQ9R0FELCBuZmN0PTIsIG1ldGhvZD0icGNhIikkUHJvcC5WYXINCiMgcGNhIGxvYWRpbmdzDQprYWJsZShyb3VuZChWYXJQcm9wLDMpLA0KICAgIGNhcHRpb249IkN1bXVsYXRpdmUgYW5kIHByb3BvcnRpb24gb2YgdmFyaWFuY2VzIGV4cGxhaW5lZCBieSBlYWNoIA0KICAgIHRoZSBwcmluY2lwYWwgY29tcG9uZW50IGluIEdBRC4iKQ0KYGBgDQpUaGUgdGFibGUgYWJvdmUgc2hvd3MgdGhlIGZhY3RvciBsb2FkaW5ncyBvZiB0aGUgZmlyc3QgdHdvIHByaW5jaXBhbCBjb21wb25lbnRzLiBXZSBjYW4gc2VlIHRoYXQgZWFjaCBvZiB0aGUgb3JpZ2luYWwgaXRlbXMgY29udHJpYnV0ZXMgdG8gdGhlIHR3byBQQ0FzIGV2ZW5seSBpbiB0ZXJtcyBvZiB0aGUgbWFnbml0dWRlLiBUaGUgZmlyc3QgUENBIGNvdW50cyBhYm91dCA1Ny43JSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIGFuZCB0aGUgc2Vjb25kIFBDQSBjb3VudHMgOC4zJSBvZiB0aGUgdG90YWwgdmFyaWF0aW9uIFRoaXMgc3VnZ2VzdHMgdGhhdCB3ZSBzaG91bGQgcmV0YWluIGEgc2ltcGxlIGZhY3Rvci4NCg0KYGBge3J9DQpwY2E2IDwtIHByY29tcChHQUQsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gVFJVRSkNCmdhZC5pZHggPSBwY2E2JHhbLDFdDQojIw0KaGlzdChnYWQuaWR4LA0KbWFpbj0iRGlzdHJpYnV0aW9uIG9mIEdyb3d0aCBhbmQgRGV2ZWxvcGVtZW50IEluZGV4IiwNCmJyZWFrcyA9IHNlcShtaW4oZ2FkLmlkeCksIG1heChnYWQuaWR4KSwgbGVuZ3RoPTkpLA0KeGxhYj0iR0FEIEluZGV4IiwNCnhsaW09cmFuZ2UoZ2FkLmlkeCksDQpib3JkZXI9InJlZCIsDQpjb2w9ImxpZ2h0Ymx1ZSIsDQpmcmVxPUZBTFNFDQopDQpgYGANCg0KIyBQcm9qZWN0IFF1ZXN0aW9ucyANCg0KIyMgUXVlc3Rpb24gMTogV2hhdCBmYWN0b3JzIGFyZSBhc3NvY2lhdGVkIHdpdGggc3R1ZGVudHPigJkgcGxhbnMgdG8gcmV0dXJuIG9yIG5vdCByZXR1cm4gdG8gdGhlIHNjaG9vbD8NCg0KVGhpcyBmaXJzdCBxdWVzdGlvbiBjb3VsZCBiZSB1c2VmdWwgZm9yIHVuaXZlcnNpdGllcyB0byBiZSBhYmxlIHRvIGJldHRlciBwcmVkaWN0IGlmIGEgc3R1ZGVudCB3aWxsIHN0YXkgYXQgdGhlaXIgc2Nob29sIG9uY2UgdGhleSBhcmUgZW5yb2xsZWQuIEtub3dpbmcgdGhpcyBjYW4gYWxzbyBoZWxwIHVuaXZlcnNpdGllcyBjYWxjdWxhdGUgYW4gZXN0aW1hdGUgb24gdGhlIG51bWJlciBvZiBzdHVkZW50cyB0aGF0IHdpbGwgZW5kIHVwIGxlYXZpbmcgcGVyIGNsYXNzLiBUaGlzIHdpbGwgaGVscCB0aGUgdW5pdmVyc2l0eSB0byBrbm93IHdoYXQgdG8gaW52ZXN0IHJlc291cmNlcyBpbiwgYW5kIGhvdyB0byBoZWxwIHRob3NlIHN0dWRlbnRzIHdobyBhcmUgbW9yZSBsaWtlbHkgdG8gZHJvcCBvdXQuIFRoZSByZXNwb25zZSB2YXJpYWJsZSBmb3IgdGhpcyBxdWVzdGlvbiB3b3VsZCBiZSBxdWVzdGlvbiAxNCBvbiB0aGUgc3VydmV5LCB3aGljaCBhc2tzIHN0dWRlbnRzIGlmIHRoZXkgcGxhbiBvbiByZXR1cm5pbmcgdG8gdGhlIHVuaXZlcnNpdHkgb3Igbm90IGluIG9yZGVyIHRvIGdyYWR1YXRlLiBUaGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzIHRoYXQgd291bGQgYmUgcHJpbWFyaWx5IGZvY3VzZWQgb24gZm9yIHRoaXMgYW5hbHlzaXMgd291bGQgYmUgc3VydmV5IHF1ZXN0aW9uIDkgd2hpY2ggbG9va3MgYXQgaG93IHN1cHBvcnRlZCB0aGUgc3R1ZGVudCBmZWVscyBieSB0aGUgdW5pdmVyc2l0eSwgcXVlc3Rpb24gMTEgKCB0aGlzIGhvdyBoZWxwIHVuaXZlcnNpdGllcyBkZXRlcm1pbmUgaG93IG11Y2ggdGhlIHJlc291cmNlcyB0aGV5IGFyZSBjdXJyZW50bHkgcHJvdmlkaW5nIGFyZSBoZWxwaW5nIHN0dWRlbnRzKSwgYW5kIHF1ZXN0aW9uIDEyLiANCg0KIyMgUXVlc3Rpb24gMjogRG8gbmF0aW9uYWwgc3R1ZGVudHMgaGF2ZSBiZXR0ZXIgbGVhcm5pbmcgb3V0Y29tZXMgdGhhbiBuYXRpb25hbCBvbmVzPw0KDQpNeSBzZWNvbmQgcXVlc3Rpb24gY291bGQgYmUgYSBnb29kIGluc2lnaHQgYXMgdG8gd2hldGhlciBvciBub3Qgc2Nob29scyBpbiBhbWVyaWNhIGNvdWxkIGltcHJvdmUgaW4gY29tcGFyaXNvbiB0byBsZWFybmluZyBpbnN0aXR1dGlvbnMgb3V0c2lkZSB0aGUgdW5pdGVkIHN0YXRlcy4gSWYgaW50ZXJuYXRpb25hbCBzdHVkZW50cyBkbyBoYXZlIGEgYmV0dGVyIG9yIHdvcnNlIGxlYXJuaW5nIG91dGNvbWVzIHRoYW4gbmF0aXZlIHN0dWRlbnRzLCBpdCB3b3VsZCBiZSBpbnRlcmVzdGluZyB0byBrbm93biB3aGljaCBpZiBjb21wb25lbnRzIHN1Y2ggYXMgbGVhcm5pbmcgc3VwcG9ydCBjb250cmlidXRlZCB0byBpdC4gSWYgdGhpcyBxdWVzdGlvbiB3ZXJlIHRvIGJlIHN0dWRpZWQsIHF1ZXN0aW9uIDIzIG9mIHRoZSBzdXJ2ZXkgd291bGQgYmUgdXNlZCBzaW5jZSBpdCBpcyBhc2tpbmcgaWYgdGhlIHN0dWRlbnQgaXMgZm9yZWlnbiBvciBpbnRlcm5hdGlvbmFsLiBJbiBvcmRlciB0byBtZWFzdXJlIGxlYXJuaW5nIG91dGNvbWVzLCBJIHdvdWxkIGxpa2VseSBsb29rIGF0IHF1ZXN0aW9ucyAxNSwgYW5kIDE2LCB3aGljaCBsb29rIGF0IEdQQSBhbmQgdG90YWwgY3JlZGl0IGhvdXJzLiBJIHdvdWxkIGFsc28gbG9vayBhdCBxdWVzdGlvbiAxMi4zIGFuZCBzZWUgaG93IG1hbnkgc3R1ZGVudHMgdmlldyBiZWluZyBhY2FkZW1pY2FsbHkgdW5wcmVwYXJlZCBhcyBhIHJlYXNvbiBub3QgdG8gY29tZSBiYWNrIHRvIHNjaG9vbC4NCg==