ggplot
a) Scatter Plot
library(ggplot2)
diabetes$Outcome = as.character(diabetes$Outcome)
ggplot(diabetes, aes(x = BMI, y = Glucose, color = Outcome)) + geom_point(size = 1.5) +
labs(title = 'BMI Vs Glucose (Using ggplot)',
x = 'BMI (Kg/m^2)',
y = 'Glucose (mmol/L)',
caption = 'Source: Iskulghar') +
scale_color_manual(values = c("0" = "maroon", "1" = "royalblue"))+
theme_minimal() +
theme(
legend.position = "top",
text = element_text(colour = 'darkslategray', size = 13),
)

The association between a suspected diabetes patient’s BMI and
glucose level is shown in a scatter plot. Based on the two attributes,
each dot represents the conclusion as either no diabetes (0) or diabetes
(1).
b) Box Plot
diabetes$Outcome = as.character(diabetes$Outcome)
ggplot(diabetes, aes(x = Outcome, y = Pregnancies, fill = Outcome)) +
geom_boxplot() +
labs(title = "Bloxplot using ggplot",
x = "Pregnancies",
y = "value",
caption = "Source: Iskulghar") +
theme(
legend.position = "top",
text = element_text(colour = 'black', size = 14))

ggplot(diabetes, aes(x = Outcome, y = Glucose, fill = Outcome)) +
geom_boxplot() +
labs(title = "Bloxplot using ggplot",
x = "Glucose",
y = "value",
caption = "Source: Iskulghar") +
theme(
legend.position = "top",
text = element_text(colour = 'black', size = 14))

ggplot(diabetes, aes(x = Outcome, y = BloodPressure, fill = Outcome)) +
geom_boxplot() +
labs(title = "Bloxplot using ggplot",
x = "BloodPressure",
y = "value",
caption = "Source: Iskulghar") +
theme(
legend.position = "top",
text = element_text(colour = 'black', size = 14))

ggplot(diabetes, aes(x = Outcome, y = SkinThickness, fill = Outcome)) +
geom_boxplot() +
labs(title = "Bloxplot using ggplot",
x = "SkinThickness",
y = "value",
caption = "Source: Iskulghar") +
theme(
legend.position = "top",
text = element_text(colour = 'black', size = 14))

ggplot(diabetes, aes(x = Outcome, y = Insulin, fill = Outcome)) +
geom_boxplot() +
labs(title = "Bloxplot using ggplot",
x = "Insulin",
y = "value",
caption = "Source: Iskulghar") +
theme(
legend.position = "top",
text = element_text(colour = 'black', size = 14))

ggplot(diabetes, aes(x = Outcome, y = BMI, fill = Outcome)) +
geom_boxplot() +
labs(title = "Bloxplot using ggplot",
x = "BMI",
y = "value",
caption = "Source: Iskulghar") +
theme(
legend.position = "top",
text = element_text(colour = 'black', size = 14))

ggplot(diabetes, aes(x = Outcome, y = DiabetesPedigreeFunction, fill = Outcome)) +
geom_boxplot() +
labs(title = "Bloxplot using ggplot",
x = "DiabetesPedigreeFunction",
y = "value",
caption = "Source: Iskulghar") +
theme(
legend.position = "top",
text = element_text(colour = 'black', size = 14))

ggplot(diabetes, aes(x = Outcome, y = Age, fill = Outcome)) +
geom_boxplot() +
labs(title = "Bloxplot using ggplot",
x = "Age",
y = "value",
caption = "Source: Iskulghar") +
theme(
legend.position = "top",
text = element_text(colour = 'black', size = 14))

The interquartile range, which includes a line representing the
median age, is used to illustrate the distribution of the all columns of
“diabetes” dataset. It also shows the maximum and minimum values within
that range. Any point that falls outside of the range are considered as
outliers.
Interactive violin plot
library(plotly)
plot_ly(data= diabetes, x = ~Outcome, y = ~Pregnancies, type = 'violin')
library(plotly)
plot_ly(data= diabetes, x = ~Outcome, y = ~Glucose, type = 'violin')
library(plotly)
plot_ly(data= diabetes, x = ~Outcome, y = ~BloodPressure, type = 'violin')
library(plotly)
plot_ly(data= diabetes, x = ~Outcome, y = ~Insulin, type = 'violin')
library(plotly)
plot_ly(data= diabetes, x = ~Outcome, y = ~BMI, type = 'violin')
library(plotly)
plot_ly(data= diabetes, x = ~Outcome, y = ~DiabetesPedigreeFunction, type = 'violin')
library(plotly)
plot_ly(data= diabetes, x = ~Outcome, y = ~BMI, type = 'violin')
library(plotly)
plot_ly(data = diabetes, x = ~Outcome, y = ~Pregnancies, type = 'box')
library(plotly)
plot_ly(data = diabetes, x = ~Outcome, y = ~Glucose, type = 'box')
library(plotly)
plot_ly(data = diabetes, x = ~Outcome, y = ~BloodPressure, type = 'box')
library(plotly)
plot_ly(data = diabetes, x = ~Outcome, y = ~Insulin, type = 'box')
library(plotly)
plot_ly(data = diabetes, x = ~Outcome, y = ~BMI, type = 'box')
library(plotly)
plot_ly(data = diabetes, x = ~Outcome, y = ~DiabetesPedigreeFunction, type = 'box')
library(plotly)
plot_ly(data = diabetes, x = ~Outcome, y = ~Age, type = 'box')
Correlation matrix
cor_matrix = cor(diabetes[ ,1:8])
print(cor_matrix)
Pregnancies Glucose BloodPressure SkinThickness Insulin BMI DiabetesPedigreeFunction
Pregnancies 1.00000000 0.12945867 0.14128198 -0.08167177 -0.07353461 0.01768309 -0.03352267
Glucose 0.12945867 1.00000000 0.15258959 0.05732789 0.33135711 0.22107107 0.13733730
BloodPressure 0.14128198 0.15258959 1.00000000 0.20737054 0.08893338 0.28180529 0.04126495
SkinThickness -0.08167177 0.05732789 0.20737054 1.00000000 0.43678257 0.39257320 0.18392757
Insulin -0.07353461 0.33135711 0.08893338 0.43678257 1.00000000 0.19785906 0.18507093
BMI 0.01768309 0.22107107 0.28180529 0.39257320 0.19785906 1.00000000 0.14064695
DiabetesPedigreeFunction -0.03352267 0.13733730 0.04126495 0.18392757 0.18507093 0.14064695 1.00000000
Age 0.54434123 0.26351432 0.23952795 -0.11397026 -0.04216295 0.03624187 0.03356131
Age
Pregnancies 0.54434123
Glucose 0.26351432
BloodPressure 0.23952795
SkinThickness -0.11397026
Insulin -0.04216295
BMI 0.03624187
DiabetesPedigreeFunction 0.03356131
Age 1.00000000
Correlation matrix plot
library(ggcorrplot)
ggcorrplot(cor_matrix,
type = "lower",
colors = c("blue", "white", "maroon"),
lab = TRUE)

Pair plot
library(GGally)
ggpairs(diabetes, aes(colour = Outcome))

PCA
library(stats)
diabetes_pca = prcomp(diabetes[ , -9], scale = TRUE, center = TRUE)
diabetes_pca
Standard deviations (1, .., p=8):
[1] 1.4471973 1.3157546 1.0147068 0.9356971 0.8731234 0.8262133 0.6479322 0.6359733
Rotation (n x k) = (8 x 8):
PC1 PC2 PC3 PC4 PC5 PC6 PC7 PC8
Pregnancies -0.1284321 0.5937858 -0.01308692 0.08069115 -0.4756057 0.193598168 -0.58879003 -0.117840984
Glucose -0.3930826 0.1740291 0.46792282 -0.40432871 0.4663280 0.094161756 -0.06015291 -0.450355256
BloodPressure -0.3600026 0.1838921 -0.53549442 0.05598649 0.3279531 -0.634115895 -0.19211793 0.011295538
SkinThickness -0.4398243 -0.3319653 -0.23767380 0.03797608 -0.4878621 0.009589438 0.28221253 -0.566283799
Insulin -0.4350262 -0.2507811 0.33670893 -0.34994376 -0.3469348 -0.270650609 -0.13200992 0.548621381
BMI -0.4519413 -0.1009598 -0.36186463 0.05364595 0.2532038 0.685372179 -0.03536644 0.341517637
DiabetesPedigreeFunction -0.2706114 -0.1220690 0.43318905 0.83368010 0.1198105 -0.085784088 -0.08609107 0.008258731
Age -0.1980271 0.6205885 0.07524755 0.07120060 -0.1092900 -0.033357170 0.71208542 0.211661979
pca_12 = data.frame(diabetes_pca$x[ , 1:2])
head(pca_12)
pca_12_out = cbind(pca_12, Outcome = diabetes$Outcome)
pca_12_out
Bar plot of PCAs
library(factoextra)
fviz_eig(diabetes_pca, addlabels = TRUE)

Contribution plot (Circular plot)
fviz_pca_var(diabetes_pca, col.var = "contrib")

Contribution plot as heatmap
library("corrplot")
var = get_pca_var(diabetes_pca)
corrplot(var$cos2)

Cluster plot
fviz_pca_ind(diabetes_pca,
geom.ind = "point",
col.ind = diabetes$Outcome,
addEllipses = TRUE)

SVM Model
library(lattice)
library(e1071)
library(caret)
train_ix = createDataPartition(diabetes$Outcome, p = 0.8, list = FALSE)
train_data = diabetes[train_ix, ]
test_data = diabetes[-train_ix, ]
train_data
test_data
diabetes$Outcome = as.factor(diabetes$Outcome)
svm_model = svm(Outcome ~ Pregnancies+Glucose+BloodPressure+SkinThickness+Insulin+BMI+DiabetesPedigreeFunction
+Age, data = train_data, kernel = "linear")
test_data[2, ]
predict(svm_model, newdata = test_data[2, -9])
5
1
Levels: 0 1
Confusion matrix
predictions = predict(svm_model, newdata = test_data)
confusion_mat = confusionMatrix(predictions, test_data$Outcome)
confusion_mat
Confusion Matrix and Statistics
Reference
Prediction 0 1
0 87 21
1 13 32
Accuracy : 0.7778
95% CI : (0.7036, 0.8409)
No Information Rate : 0.6536
P-Value [Acc > NIR] : 0.000586
Kappa : 0.4912
Mcnemar's Test P-Value : 0.229949
Sensitivity : 0.8700
Specificity : 0.6038
Pos Pred Value : 0.8056
Neg Pred Value : 0.7111
Prevalence : 0.6536
Detection Rate : 0.5686
Detection Prevalence : 0.7059
Balanced Accuracy : 0.7369
'Positive' Class : 0
com = as.data.frame(confusion_mat$table)
ggplot(com, aes(Prediction, Reference, fill = Freq)) +
geom_tile() +
geom_text(aes(label = Freq)) +
scale_fill_gradient(low="navy", high="aquamarine")

US Admission dataset
us_ad = read.csv('US Admission.csv')
us_ad
Removal of Serial.No column
us_ad_new = us_ad[ ,-1]
us_ad_new
Pair plot
library(GGally)
ggpairs(us_ad_new, cardinality_threshold = NULL )

Linear regression
x = us_ad_new$GRE.Score
y = us_ad_new$Chance.of.Admit
plot(x~y, xlab = "Chance of Admission", ylab = "GRE Score", main = "Linear Regression of GRE Score and Chance of Admission", pch = 20, col = 'blue')

x = us_ad_new$TOEFL.Score
y = us_ad_new$Chance.of.Admit
plot(x~y, xlab = "Chance of Admission", ylab = "TOEFL Score", main = "Linear Regression of TOEFL Score and Chance of Admission", pch = 20, col = 'red')

x = us_ad_new$University.Rating
y = us_ad_new$Chance.of.Admit
plot(x~y, xlab = "Chance of Admission", ylab = "University Rating", main = "Linear Regression of University Rating and Chance of Admission", pch = 20, col = 'purple')

x = us_ad_new$SOP
y = us_ad_new$Chance.of.Admit
plot(x~y, xlab = "Chance of Admission", ylab = "SOP", main = "Linear Regression of SOP and Chance of Admission", pch = 20, col = 'maroon')

x = us_ad_new$LOR
y = us_ad_new$Chance.of.Admit
plot(x~y, xlab = "Chance of Admission", ylab = "LOR", main = "Linear Regression of LOR and Chance of Admission", pch = 20, col = 'navy')

x = us_ad_new$CGPA
y = us_ad_new$Chance.of.Admit
plot(x~y, xlab = "Chance of Admission", ylab = "CGPA", main = "Linear Regression of CGPA and Chance of Admission", pch = 20, col = 'brown')

x = us_ad_new$Research
y = us_ad_new$Chance.of.Admit
plot(x~y, xlab = "Chance of Admission", ylab = "Research", main = "Linear Regression of Research and Chance of Admission", pch = 20, col = 'black')

Polynomial regression
library(ggplot2)
ggplot(us_ad_new, aes(x = GRE.Score, y = TOEFL.Score), color = Chance.of.Admit ) +
geom_point() +
geom_smooth(method = "lm", formula = y~poly(x, 2), level = 0.95) +
theme_minimal()

ggplot(us_ad_new, aes(x = GRE.Score, y =University.Rating), color = Chance.of.Admit ) +
geom_point() +
geom_smooth(method = "lm", formula = y~poly(x, 2), level = 0.95) +
theme_minimal()

ggplot(us_ad_new, aes(x = GRE.Score, y = SOP), color = Chance.of.Admit ) +
geom_point() +
geom_smooth(method = "lm", formula = y~poly(x, 2), level = 0.95) +
theme_minimal()

ggplot(us_ad_new, aes(x = GRE.Score, y = LOR), color = Chance.of.Admit ) +
geom_point() +
geom_smooth(method = "lm", formula = y~poly(x, 2), level = 0.95) +
theme_minimal()

ggplot(us_ad_new, aes(x = GRE.Score, y = CGPA), color = Chance.of.Admit ) +
geom_point() +
geom_smooth(method = "lm", formula = y~poly(x, 2), level = 0.95) +
theme_minimal()

ggplot(us_ad_new, aes(x = GRE.Score, y = Research), color = Chance.of.Admit ) +
geom_point() +
geom_smooth(method = "lm", formula = y~poly(x, 2), level = 0.95) +
theme_minimal()

Regression model
library(datasets)
data(us_ad_new)
Warning: data set ‘us_ad_new’ not found
lm_model = lm(Chance.of.Admit ~ GRE.Score+TOEFL.Score+University.Rating+SOP+LOR+CGPA+Research, data = us_ad_new)
summary(lm_model)
Call:
lm(formula = Chance.of.Admit ~ GRE.Score + TOEFL.Score + University.Rating +
SOP + LOR + CGPA + Research, data = us_ad_new)
Residuals:
Min 1Q Median 3Q Max
-0.26259 -0.02103 0.01005 0.03628 0.15928
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -1.2594325 0.1247307 -10.097 < 2e-16 ***
GRE.Score 0.0017374 0.0005979 2.906 0.00387 **
TOEFL.Score 0.0029196 0.0010895 2.680 0.00768 **
University.Rating 0.0057167 0.0047704 1.198 0.23150
SOP -0.0033052 0.0055616 -0.594 0.55267
LOR 0.0223531 0.0055415 4.034 6.6e-05 ***
CGPA 0.1189395 0.0122194 9.734 < 2e-16 ***
Research 0.0245251 0.0079598 3.081 0.00221 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.06378 on 392 degrees of freedom
Multiple R-squared: 0.8035, Adjusted R-squared: 0.8
F-statistic: 228.9 on 7 and 392 DF, p-value: < 2.2e-16
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIFN1c21pdGEgQmFydWENCiMjIFN0dWRlbnQsIFVuaXZlcnNpdHkgb2YgQ2hpdHRhZ29uZw0KDQoNCiMjIFRoZSAnZGlhYmV0ZXMnIGlzIGEgZGF0YXNldCB0aGF0IGRldGVybWluZXMgdGhlIG91dGNvbWUgb2YgdGhlIHN1c3BlY3RlZCBwYXRpZW50cyBiYXNlZCBvbiBzZXZlcmFsICdmZWF0dXJlcycgZWl0aGVyIGFzICdObyBkaWFiZXRlcyA9IDAnIG9yIGFzICdEaWFiZXRlcyA9IDEnLiANCg0KYGBge3J9DQpudW1lX2NvbHVtbiA9IHNhcHBseShkaWFiZXRlcywgaXMubnVtZXJpYykNCm51bWVfY29sdW1uX25hbWUgPSBuYW1lcyhudW1lX2NvbHVtbikNCm51bWVfY29sdW1uX25hbWUNCmBgYA0KDQojIyBUaGVyZSBhcmUgdG90YWwgOSBudW1lcmljYWwgY29sdW1ucyBhbmQgMCBjYXRlZ29yaWNhbCBjb2x1bW4gaW4gdGhlICdkaWFiZXRlcycgZGF0YXNldC5UaGUgdGFyZ2V0IHZhcmlhYmxlIG9mIHRoZSBkYXRhc2V0IGlzIHRoZSAnT3V0Y29tZScgY29sdW1uLg0KDQpgYGB7cn0NCmRpYWJldGVzID0gcmVhZC5jc3YoJ2RpYWJldGVzLmNzdicpDQpkaWFiZXRlcw0KYGBgDQojIEJhc2ljIFBsb3QNCg0KIyMgYSkgU2NhdHRlciBwbG90DQoNCmBgYHtyfQ0KcmVzdWx0X2NvbG9yID0gYXMubnVtZXJpYyhmYWN0b3IoZGlhYmV0ZXMkT3V0Y29tZSkpIA0KcGxvdChkaWFiZXRlcyRCTUksIGRpYWJldGVzJEdsdWNvc2UsIA0KICAgICBjb2wgPSByZXN1bHRfY29sb3IsDQogICAgIHBjaCA9IDIwLA0KICAgICB4bGFiID0gc3Vic3RpdHV0ZShwYXN0ZShib2xkKCJCTUkgKGtnL21eMikiKSkpLA0KICAgICB5bGFiID0gc3Vic3RpdHV0ZShwYXN0ZShib2xkKCJHbHVjb3NlIChtbW9sL0wpIikpKSwNCiAgICAgbWFpbiA9ICdCTUkgVnMgR2x1Y29zZScsDQogICAgIGNvbC5tYWluID0gJ2JsYWNrJywNCiAgICAgY2V4Lm1haW4gPSAxLjUNCiAgICApIA0KYGBgDQojIyBUaGUgc2NhdHRlciBwbG90IHJlcHJlc2VudHMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIEJNSSBhbmQgR2x1Y29zZSBsZXZlbCBvZiBzdXNwZWN0ZWQgZGlhYmV0ZXMgcGF0aWVudHMuIEVhY2ggZG90IGRlbW9uc3RyYXRlcyB0aGUgb3V0Y29tZSBhcyBubyBkaWFiZXRlcyAoMCkgYW5kIGRpYWJldGVzKDEpIGJhc2VkIG9uIHRoZSB0d28gZmVhdHVyZXMuDQoNCiMjIGIpIEhpc3RvZ3JhbSBQbG90DQoNCmBgYHtyfQ0KaGlzdChkaWFiZXRlcyRJbnN1bGluLA0KICAgICBtYWluID0gIkhpc3RvZ3JhbSBwbG90IG9mIEluc3VsaW4iLA0KICAgICBjb2wgPSAicGluayIsDQogICAgIHhsYWIgPSAiSW5zdWxpbiBMZXZlbCAoSVUvbUwpIikNCmBgYA0KIyMgVGhlIGhpc3RvZ3JhbSBpcyBhIGdyYXBoaWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGlzdHJpYnV0aW9uIG9mICdkaWFiZXRlcycgZGF0YXNldC4gSGVyZSwgdGhlIHgtYXhpcyByZXByZXNlbnRzIGluc3VsaW4gbGV2ZWwgcmFuZ2UgYW5kIHRoZSB5LWF4aXMgc2hvd3MgdGhlIGZyZXF1ZW5jeSBvZiBpbmRpdmlkdWFscyBmYWxsaW5nIHdpdGhpbiBlYWNoIHJhbmdlLg0KDQojIyBjKSBCb3ggUGxvdA0KYGBge3J9DQpib3hwbG90KGRpYWJldGVzJEFnZSwNCiAgICAgICAgbWFpbiA9ICdCb3ggcGxvdCcsDQogICAgICAgIGNvbCA9ICdhcXVhbWFyaW5lJywNCiAgICAgICAgeGxhYiA9IHN1YnN0aXR1dGUocGFzdGUoYm9sZCgnQWdlJykpKSwNCiAgICAgICAgeWxhYiA9IHN1YnN0aXR1dGUocGFzdGUoYm9sZCgnWWVhcnMnKSkpDQopDQpgYGANCiMjIFRoZSBib3hwbG90IGRpc3BsYXlzIGtleSBzdGF0aXN0aWNzIHN1Y2ggYXMgbWVkaWFuLCBxdWFydGlsZXMgYW5kIHBvdGVudGlhbCBvdXRsaWVycy4gVGhpcyBib3hwbG90IHJlcHJlc2VudHMgdGhlIGFnZSBkaXN0cmlidXRpb24gb2YgJ2RpYWJldGVzJyBkYXRhc2V0IHNob3dpbmcgdGhlaXIgbWF4aW11bSBhbmQgbWluaW11bSB2YWx1ZSB3aXRoaW4gYSBjZXJ0YWluIHJhbmdlLCB0aGUgaW50ZXJxdWFydGlsZSByYW5nZSB3aXRoICBhIGxpbmUgaW5zaWRlIGluZGljYXRpbmcgdGhlIG1lZGlhbiBhZ2UuIFRoZSBwb2ludHMgYmV5b25kIHRoZSBtYXhpbXVtIHJhbmdlIGFyZSBjb25zaWRlcmVkIGFzIG91dGxpZXJzLg0KDQojIGdncGxvdA0KDQojIyBhKSBTY2F0dGVyIFBsb3QNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KDQpkaWFiZXRlcyRPdXRjb21lID0gYXMuY2hhcmFjdGVyKGRpYWJldGVzJE91dGNvbWUpDQpnZ3Bsb3QoZGlhYmV0ZXMsIGFlcyh4ID0gQk1JLCB5ID0gR2x1Y29zZSwgY29sb3IgPSBPdXRjb21lKSkgKyBnZW9tX3BvaW50KHNpemUgPSAxLjUpICsgDQogIGxhYnModGl0bGUgPSAnQk1JIFZzIEdsdWNvc2UgKFVzaW5nIGdncGxvdCknLA0KICAgICAgIHggPSAnQk1JIChLZy9tXjIpJywNCiAgICAgICB5ID0gJ0dsdWNvc2UgKG1tb2wvTCknLA0KICAgICAgIGNhcHRpb24gPSAnU291cmNlOiBJc2t1bGdoYXInKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIwIiA9ICJtYXJvb24iLCAiMSIgPSAicm95YWxibHVlIikpKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwNCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICdkYXJrc2xhdGVncmF5Jywgc2l6ZSA9IDEzKSwgDQogICAgICAgICApDQpgYGANCiMjIFRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIGEgc3VzcGVjdGVkIGRpYWJldGVzIHBhdGllbnQncyBCTUkgYW5kIGdsdWNvc2UgbGV2ZWwgaXMgc2hvd24gaW4gYSBzY2F0dGVyIHBsb3QuIEJhc2VkIG9uIHRoZSB0d28gYXR0cmlidXRlcywgZWFjaCBkb3QgcmVwcmVzZW50cyB0aGUgY29uY2x1c2lvbiBhcyBlaXRoZXIgbm8gZGlhYmV0ZXMgKDApIG9yIGRpYWJldGVzICgxKS4NCg0KIyMgYikgQm94IFBsb3QNCmBgYHtyfQ0KZGlhYmV0ZXMkT3V0Y29tZSA9IGFzLmNoYXJhY3RlcihkaWFiZXRlcyRPdXRjb21lKQ0KZ2dwbG90KGRpYWJldGVzLCBhZXMoeCA9IE91dGNvbWUsIHkgPSBQcmVnbmFuY2llcywgZmlsbCA9IE91dGNvbWUpKSArDQpnZW9tX2JveHBsb3QoKSArDQoNCiAgbGFicyh0aXRsZSA9ICJCbG94cGxvdCB1c2luZyBnZ3Bsb3QiLA0KICAgICAgIHggPSAiUHJlZ25hbmNpZXMiLA0KICAgICAgIHkgPSAidmFsdWUiLA0KICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBJc2t1bGdoYXIiKSArDQogIA0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgDQogICAgdGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAnYmxhY2snLCBzaXplID0gMTQpKQ0KDQpnZ3Bsb3QoZGlhYmV0ZXMsIGFlcyh4ID0gT3V0Y29tZSwgeSA9IEdsdWNvc2UsIGZpbGwgPSBPdXRjb21lKSkgKw0KZ2VvbV9ib3hwbG90KCkgKw0KDQogIGxhYnModGl0bGUgPSAiQmxveHBsb3QgdXNpbmcgZ2dwbG90IiwNCiAgICAgICB4ID0gIkdsdWNvc2UiLA0KICAgICAgIHkgPSAidmFsdWUiLA0KICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBJc2t1bGdoYXIiKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCANCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICdibGFjaycsIHNpemUgPSAxNCkpDQoNCmdncGxvdChkaWFiZXRlcywgYWVzKHggPSBPdXRjb21lLCB5ID0gQmxvb2RQcmVzc3VyZSwgZmlsbCA9IE91dGNvbWUpKSArDQpnZW9tX2JveHBsb3QoKSArDQoNCiAgbGFicyh0aXRsZSA9ICJCbG94cGxvdCB1c2luZyBnZ3Bsb3QiLA0KICAgICAgIHggPSAiQmxvb2RQcmVzc3VyZSIsDQogICAgICAgeSA9ICJ2YWx1ZSIsDQogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IElza3VsZ2hhciIpICsNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIA0KICAgIHRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gJ2JsYWNrJywgc2l6ZSA9IDE0KSkNCg0KZ2dwbG90KGRpYWJldGVzLCBhZXMoeCA9IE91dGNvbWUsIHkgPSBTa2luVGhpY2tuZXNzLCBmaWxsID0gT3V0Y29tZSkpICsNCmdlb21fYm94cGxvdCgpICsNCg0KICBsYWJzKHRpdGxlID0gIkJsb3hwbG90IHVzaW5nIGdncGxvdCIsDQogICAgICAgeCA9ICJTa2luVGhpY2tuZXNzIiwNCiAgICAgICB5ID0gInZhbHVlIiwNCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogSXNrdWxnaGFyIikgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgDQogICAgdGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAnYmxhY2snLCBzaXplID0gMTQpKQ0KDQpnZ3Bsb3QoZGlhYmV0ZXMsIGFlcyh4ID0gT3V0Y29tZSwgeSA9IEluc3VsaW4sIGZpbGwgPSBPdXRjb21lKSkgKw0KZ2VvbV9ib3hwbG90KCkgKw0KDQogIGxhYnModGl0bGUgPSAiQmxveHBsb3QgdXNpbmcgZ2dwbG90IiwNCiAgICAgICB4ID0gIkluc3VsaW4iLA0KICAgICAgIHkgPSAidmFsdWUiLA0KICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBJc2t1bGdoYXIiKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCANCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICdibGFjaycsIHNpemUgPSAxNCkpDQoNCmdncGxvdChkaWFiZXRlcywgYWVzKHggPSBPdXRjb21lLCB5ID0gQk1JLCBmaWxsID0gT3V0Y29tZSkpICsNCmdlb21fYm94cGxvdCgpICsNCg0KICBsYWJzKHRpdGxlID0gIkJsb3hwbG90IHVzaW5nIGdncGxvdCIsDQogICAgICAgeCA9ICJCTUkiLA0KICAgICAgIHkgPSAidmFsdWUiLA0KICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBJc2t1bGdoYXIiKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCANCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICdibGFjaycsIHNpemUgPSAxNCkpDQoNCmdncGxvdChkaWFiZXRlcywgYWVzKHggPSBPdXRjb21lLCB5ID0gRGlhYmV0ZXNQZWRpZ3JlZUZ1bmN0aW9uLCBmaWxsID0gT3V0Y29tZSkpICsNCmdlb21fYm94cGxvdCgpICsNCg0KICBsYWJzKHRpdGxlID0gIkJsb3hwbG90IHVzaW5nIGdncGxvdCIsDQogICAgICAgeCA9ICJEaWFiZXRlc1BlZGlncmVlRnVuY3Rpb24iLA0KICAgICAgIHkgPSAidmFsdWUiLA0KICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBJc2t1bGdoYXIiKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCANCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICdibGFjaycsIHNpemUgPSAxNCkpDQoNCmdncGxvdChkaWFiZXRlcywgYWVzKHggPSBPdXRjb21lLCB5ID0gQWdlLCBmaWxsID0gT3V0Y29tZSkpICsNCmdlb21fYm94cGxvdCgpICsNCg0KICBsYWJzKHRpdGxlID0gIkJsb3hwbG90IHVzaW5nIGdncGxvdCIsDQogICAgICAgeCA9ICJBZ2UiLA0KICAgICAgIHkgPSAidmFsdWUiLA0KICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBJc2t1bGdoYXIiKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCANCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICdibGFjaycsIHNpemUgPSAxNCkpDQpgYGANCg0KIyMgVGhlIGludGVycXVhcnRpbGUgcmFuZ2UsIHdoaWNoIGluY2x1ZGVzIGEgbGluZSByZXByZXNlbnRpbmcgdGhlIG1lZGlhbiBhZ2UsIGlzIHVzZWQgdG8gaWxsdXN0cmF0ZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBhbGwgY29sdW1ucyBvZiAiZGlhYmV0ZXMiIGRhdGFzZXQuIEl0IGFsc28gc2hvd3MgdGhlIG1heGltdW0gYW5kIG1pbmltdW0gdmFsdWVzIHdpdGhpbiB0aGF0IHJhbmdlLiBBbnkgcG9pbnQgdGhhdCBmYWxscyBvdXRzaWRlIG9mIHRoZSByYW5nZSBhcmUgY29uc2lkZXJlZCBhcyBvdXRsaWVycy4NCg0KIyMgSW50ZXJhY3RpdmUgdmlvbGluIHBsb3QNCmBgYHtyfQ0KbGlicmFyeShwbG90bHkpDQpwbG90X2x5KGRhdGE9IGRpYWJldGVzLCB4ID0gfk91dGNvbWUsIHkgPSB+UHJlZ25hbmNpZXMsIHR5cGUgPSAndmlvbGluJykgDQpgYGANCmBgYHtyfQ0KbGlicmFyeShwbG90bHkpDQpwbG90X2x5KGRhdGE9IGRpYWJldGVzLCB4ID0gfk91dGNvbWUsIHkgPSB+R2x1Y29zZSwgdHlwZSA9ICd2aW9saW4nKSANCmBgYA0KYGBge3J9DQpsaWJyYXJ5KHBsb3RseSkNCnBsb3RfbHkoZGF0YT0gZGlhYmV0ZXMsIHggPSB+T3V0Y29tZSwgeSA9IH5CbG9vZFByZXNzdXJlLCB0eXBlID0gJ3Zpb2xpbicpIA0KYGBgDQpgYGB7cn0NCmxpYnJhcnkocGxvdGx5KQ0KcGxvdF9seShkYXRhPSBkaWFiZXRlcywgeCA9IH5PdXRjb21lLCB5ID0gfkluc3VsaW4sIHR5cGUgPSAndmlvbGluJykgDQpgYGANCmBgYHtyfQ0KbGlicmFyeShwbG90bHkpDQpwbG90X2x5KGRhdGE9IGRpYWJldGVzLCB4ID0gfk91dGNvbWUsIHkgPSB+Qk1JLCB0eXBlID0gJ3Zpb2xpbicpIA0KYGBgDQpgYGB7cn0NCmxpYnJhcnkocGxvdGx5KQ0KcGxvdF9seShkYXRhPSBkaWFiZXRlcywgeCA9IH5PdXRjb21lLCB5ID0gfkRpYWJldGVzUGVkaWdyZWVGdW5jdGlvbiwgdHlwZSA9ICd2aW9saW4nKSANCmBgYA0KYGBge3J9DQpsaWJyYXJ5KHBsb3RseSkNCnBsb3RfbHkoZGF0YT0gZGlhYmV0ZXMsIHggPSB+T3V0Y29tZSwgeSA9IH5CTUksIHR5cGUgPSAndmlvbGluJykNCmBgYA0KDQoNCmBgYHtyfQ0KbGlicmFyeShwbG90bHkpDQpwbG90X2x5KGRhdGEgPSBkaWFiZXRlcywgeCA9IH5PdXRjb21lLCB5ID0gflByZWduYW5jaWVzLCB0eXBlID0gJ2JveCcpDQpgYGANCmBgYHtyfQ0KbGlicmFyeShwbG90bHkpDQpwbG90X2x5KGRhdGEgPSBkaWFiZXRlcywgeCA9IH5PdXRjb21lLCB5ID0gfkdsdWNvc2UsIHR5cGUgPSAnYm94JykNCmBgYA0KYGBge3J9DQpsaWJyYXJ5KHBsb3RseSkNCnBsb3RfbHkoZGF0YSA9IGRpYWJldGVzLCB4ID0gfk91dGNvbWUsIHkgPSB+Qmxvb2RQcmVzc3VyZSwgdHlwZSA9ICdib3gnKQ0KYGBgDQpgYGB7cn0NCmxpYnJhcnkocGxvdGx5KQ0KcGxvdF9seShkYXRhID0gZGlhYmV0ZXMsIHggPSB+T3V0Y29tZSwgeSA9IH5JbnN1bGluLCB0eXBlID0gJ2JveCcpDQpgYGANCmBgYHtyfQ0KbGlicmFyeShwbG90bHkpDQpwbG90X2x5KGRhdGEgPSBkaWFiZXRlcywgeCA9IH5PdXRjb21lLCB5ID0gfkJNSSwgdHlwZSA9ICdib3gnKQ0KYGBgDQpgYGB7cn0NCmxpYnJhcnkocGxvdGx5KQ0KcGxvdF9seShkYXRhID0gZGlhYmV0ZXMsIHggPSB+T3V0Y29tZSwgeSA9IH5EaWFiZXRlc1BlZGlncmVlRnVuY3Rpb24sIHR5cGUgPSAnYm94JykNCmBgYA0KYGBge3J9DQpsaWJyYXJ5KHBsb3RseSkNCnBsb3RfbHkoZGF0YSA9IGRpYWJldGVzLCB4ID0gfk91dGNvbWUsIHkgPSB+QWdlLCB0eXBlID0gJ2JveCcpDQpgYGANCg0KIyMgQ29ycmVsYXRpb24gbWF0cml4DQpgYGB7cn0NCmNvcl9tYXRyaXggPSBjb3IoZGlhYmV0ZXNbICwxOjhdKQ0KcHJpbnQoY29yX21hdHJpeCkNCmBgYA0KIyMgQ29ycmVsYXRpb24gbWF0cml4IHBsb3QNCmBgYHtyfQ0KbGlicmFyeShnZ2NvcnJwbG90KQ0KZ2djb3JycGxvdChjb3JfbWF0cml4LCANCgkgICAgICAgICAgIHR5cGUgPSAibG93ZXIiLA0KCSAgICAgICAgICAgY29sb3JzID0gYygiYmx1ZSIsICJ3aGl0ZSIsICJtYXJvb24iKSwNCgkgICAgICAgICAgIGxhYiA9IFRSVUUpDQpgYGANCg0KIyMgUGFpciBwbG90DQpgYGB7cn0NCmxpYnJhcnkoR0dhbGx5KQ0KZ2dwYWlycyhkaWFiZXRlcywgYWVzKGNvbG91ciA9IE91dGNvbWUpKQ0KYGBgDQoNCiMjIFBDQQ0KYGBge3J9DQpsaWJyYXJ5KHN0YXRzKQ0KDQpkaWFiZXRlc19wY2EgPSBwcmNvbXAoZGlhYmV0ZXNbICwgLTldLCBzY2FsZSA9IFRSVUUsIGNlbnRlciA9IFRSVUUpDQpkaWFiZXRlc19wY2ENCmBgYA0KYGBge3J9DQpwY2FfMTIgPSBkYXRhLmZyYW1lKGRpYWJldGVzX3BjYSR4WyAsIDE6Ml0pDQpoZWFkKHBjYV8xMikNCmBgYA0KYGBge3J9DQpwY2FfMTJfb3V0ID0gY2JpbmQocGNhXzEyLCBPdXRjb21lID0gZGlhYmV0ZXMkT3V0Y29tZSkNCnBjYV8xMl9vdXQNCmBgYA0KIyMgQmFyIHBsb3Qgb2YgUENBcw0KYGBge3J9DQpsaWJyYXJ5KGZhY3RvZXh0cmEpDQpmdml6X2VpZyhkaWFiZXRlc19wY2EsIGFkZGxhYmVscyA9IFRSVUUpDQpgYGANCiMjIENvbnRyaWJ1dGlvbiBwbG90IChDaXJjdWxhciBwbG90KQ0KYGBge3J9DQpmdml6X3BjYV92YXIoZGlhYmV0ZXNfcGNhLCBjb2wudmFyID0gImNvbnRyaWIiKQ0KYGBgDQojIyBDb250cmlidXRpb24gcGxvdCBhcyBoZWF0bWFwDQpgYGB7cn0NCmxpYnJhcnkoImNvcnJwbG90IikNCnZhciA9IGdldF9wY2FfdmFyKGRpYWJldGVzX3BjYSkNCmNvcnJwbG90KHZhciRjb3MyKQ0KYGBgDQojIyBDbHVzdGVyIHBsb3QNCmBgYHtyfQ0KZnZpel9wY2FfaW5kKGRpYWJldGVzX3BjYSwNCiAgICAgICAgICAgICBnZW9tLmluZCA9ICJwb2ludCIsDQogICAgICAgICAgICAgY29sLmluZCA9IGRpYWJldGVzJE91dGNvbWUsDQogICAgICAgICAgICAgYWRkRWxsaXBzZXMgPSBUUlVFKQ0KYGBgDQojIyBTVk0gTW9kZWwNCmBgYHtyfQ0KbGlicmFyeShsYXR0aWNlKQ0KbGlicmFyeShlMTA3MSkNCmxpYnJhcnkoY2FyZXQpDQoNCnRyYWluX2l4ID0gY3JlYXRlRGF0YVBhcnRpdGlvbihkaWFiZXRlcyRPdXRjb21lLCBwID0gMC44LCBsaXN0ID0gRkFMU0UpDQp0cmFpbl9kYXRhID0gZGlhYmV0ZXNbdHJhaW5faXgsIF0NCnRlc3RfZGF0YSA9IGRpYWJldGVzWy10cmFpbl9peCwgXQ0KDQp0cmFpbl9kYXRhDQp0ZXN0X2RhdGENCg0KZGlhYmV0ZXMkT3V0Y29tZSA9IGFzLmZhY3RvcihkaWFiZXRlcyRPdXRjb21lKQ0Kc3ZtX21vZGVsID0gc3ZtKE91dGNvbWUgfiBQcmVnbmFuY2llcytHbHVjb3NlK0Jsb29kUHJlc3N1cmUrU2tpblRoaWNrbmVzcytJbnN1bGluK0JNSStEaWFiZXRlc1BlZGlncmVlRnVuY3Rpb24NCitBZ2UsIGRhdGEgPSB0cmFpbl9kYXRhLCBrZXJuZWwgPSAibGluZWFyIikNCmBgYA0KYGBge3J9DQp0ZXN0X2RhdGFbMiwgXQ0KYGBgDQoNCmBgYHtyfQ0KcHJlZGljdChzdm1fbW9kZWwsIG5ld2RhdGEgPSB0ZXN0X2RhdGFbMiwgLTldKQ0KYGBgDQojIyBDb25mdXNpb24gbWF0cml4DQoNCmBgYHtyfQ0KcHJlZGljdGlvbnMgPSBwcmVkaWN0KHN2bV9tb2RlbCwgbmV3ZGF0YSA9IHRlc3RfZGF0YSkNCmNvbmZ1c2lvbl9tYXQgPSBjb25mdXNpb25NYXRyaXgocHJlZGljdGlvbnMsIHRlc3RfZGF0YSRPdXRjb21lKQ0KY29uZnVzaW9uX21hdA0KY29tID0gYXMuZGF0YS5mcmFtZShjb25mdXNpb25fbWF0JHRhYmxlKQ0KDQpnZ3Bsb3QoY29tLCBhZXMoUHJlZGljdGlvbiwgUmVmZXJlbmNlLCBmaWxsID0gRnJlcSkpICsgDQogIGdlb21fdGlsZSgpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IEZyZXEpKSArIA0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdz0ibmF2eSIsIGhpZ2g9ImFxdWFtYXJpbmUiKQ0KYGBgDQojIyBVUyBBZG1pc3Npb24gZGF0YXNldA0KYGBge3J9DQp1c19hZCA9IHJlYWQuY3N2KCdVUyBBZG1pc3Npb24uY3N2JykNCnVzX2FkDQpgYGANCiMjIFJlbW92YWwgb2YgU2VyaWFsLk5vIGNvbHVtbg0KYGBge3J9DQp1c19hZF9uZXcgPSB1c19hZFsgLC0xXQ0KdXNfYWRfbmV3DQpgYGANCiMjIFBhaXIgcGxvdA0KYGBge3J9DQpsaWJyYXJ5KEdHYWxseSkNCmdncGFpcnModXNfYWRfbmV3LCBjYXJkaW5hbGl0eV90aHJlc2hvbGQgPSBOVUxMICkgDQpgYGANCiMjIExpbmVhciByZWdyZXNzaW9uDQpgYGB7cn0NCnggPSB1c19hZF9uZXckR1JFLlNjb3JlDQp5ID0gdXNfYWRfbmV3JENoYW5jZS5vZi5BZG1pdA0KDQpwbG90KHh+eSwgeGxhYiA9ICJDaGFuY2Ugb2YgQWRtaXNzaW9uIiwgeWxhYiA9ICJHUkUgU2NvcmUiLCBtYWluID0gIkxpbmVhciBSZWdyZXNzaW9uIG9mIEdSRSBTY29yZSBhbmQgQ2hhbmNlIG9mIEFkbWlzc2lvbiIsIHBjaCA9IDIwLCBjb2wgPSAnYmx1ZScpDQoNCnggPSB1c19hZF9uZXckVE9FRkwuU2NvcmUNCnkgPSB1c19hZF9uZXckQ2hhbmNlLm9mLkFkbWl0DQoNCnBsb3QoeH55LCB4bGFiID0gIkNoYW5jZSBvZiBBZG1pc3Npb24iLCB5bGFiID0gIlRPRUZMIFNjb3JlIiwgbWFpbiA9ICJMaW5lYXIgUmVncmVzc2lvbiBvZiBUT0VGTCBTY29yZSBhbmQgQ2hhbmNlIG9mIEFkbWlzc2lvbiIsIHBjaCA9IDIwLCBjb2wgPSAncmVkJykNCg0KeCA9IHVzX2FkX25ldyRVbml2ZXJzaXR5LlJhdGluZw0KeSA9IHVzX2FkX25ldyRDaGFuY2Uub2YuQWRtaXQNCg0KcGxvdCh4fnksIHhsYWIgPSAiQ2hhbmNlIG9mIEFkbWlzc2lvbiIsIHlsYWIgPSAiVW5pdmVyc2l0eSBSYXRpbmciLCBtYWluID0gIkxpbmVhciBSZWdyZXNzaW9uIG9mIFVuaXZlcnNpdHkgUmF0aW5nIGFuZCBDaGFuY2Ugb2YgQWRtaXNzaW9uIiwgcGNoID0gMjAsIGNvbCA9ICdwdXJwbGUnKQ0KDQp4ID0gdXNfYWRfbmV3JFNPUA0KeSA9IHVzX2FkX25ldyRDaGFuY2Uub2YuQWRtaXQNCg0KcGxvdCh4fnksIHhsYWIgPSAiQ2hhbmNlIG9mIEFkbWlzc2lvbiIsIHlsYWIgPSAiU09QIiwgbWFpbiA9ICJMaW5lYXIgUmVncmVzc2lvbiBvZiBTT1AgYW5kIENoYW5jZSBvZiBBZG1pc3Npb24iLCBwY2ggPSAyMCwgY29sID0gJ21hcm9vbicpDQoNCnggPSB1c19hZF9uZXckTE9SDQp5ID0gdXNfYWRfbmV3JENoYW5jZS5vZi5BZG1pdA0KDQpwbG90KHh+eSwgeGxhYiA9ICJDaGFuY2Ugb2YgQWRtaXNzaW9uIiwgeWxhYiA9ICJMT1IiLCBtYWluID0gIkxpbmVhciBSZWdyZXNzaW9uIG9mIExPUiBhbmQgQ2hhbmNlIG9mIEFkbWlzc2lvbiIsIHBjaCA9IDIwLCBjb2wgPSAnbmF2eScpDQoNCnggPSB1c19hZF9uZXckQ0dQQQ0KeSA9IHVzX2FkX25ldyRDaGFuY2Uub2YuQWRtaXQNCg0KcGxvdCh4fnksIHhsYWIgPSAiQ2hhbmNlIG9mIEFkbWlzc2lvbiIsIHlsYWIgPSAiQ0dQQSIsIG1haW4gPSAiTGluZWFyIFJlZ3Jlc3Npb24gb2YgQ0dQQSBhbmQgQ2hhbmNlIG9mIEFkbWlzc2lvbiIsIHBjaCA9IDIwLCBjb2wgPSAnYnJvd24nKQ0KDQp4ID0gdXNfYWRfbmV3JFJlc2VhcmNoDQp5ID0gdXNfYWRfbmV3JENoYW5jZS5vZi5BZG1pdA0KDQpwbG90KHh+eSwgeGxhYiA9ICJDaGFuY2Ugb2YgQWRtaXNzaW9uIiwgeWxhYiA9ICJSZXNlYXJjaCIsIG1haW4gPSAiTGluZWFyIFJlZ3Jlc3Npb24gb2YgUmVzZWFyY2ggYW5kIENoYW5jZSBvZiBBZG1pc3Npb24iLCBwY2ggPSAyMCwgY29sID0gJ2JsYWNrJykNCmBgYA0KIyMgUG9seW5vbWlhbCByZWdyZXNzaW9uDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmdncGxvdCh1c19hZF9uZXcsIGFlcyh4ID0gR1JFLlNjb3JlLCB5ID0gVE9FRkwuU2NvcmUpLCBjb2xvciA9IENoYW5jZS5vZi5BZG1pdCApICsgDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSB5fnBvbHkoeCwgMiksIGxldmVsID0gMC45NSkgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KZ2dwbG90KHVzX2FkX25ldywgYWVzKHggPSBHUkUuU2NvcmUsIHkgPVVuaXZlcnNpdHkuUmF0aW5nKSwgY29sb3IgPSBDaGFuY2Uub2YuQWRtaXQgKSArIA0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBmb3JtdWxhID0geX5wb2x5KHgsIDIpLCBsZXZlbCA9IDAuOTUpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmdncGxvdCh1c19hZF9uZXcsIGFlcyh4ID0gR1JFLlNjb3JlLCB5ID0gU09QKSwgY29sb3IgPSBDaGFuY2Uub2YuQWRtaXQgKSArIA0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBmb3JtdWxhID0geX5wb2x5KHgsIDIpLCBsZXZlbCA9IDAuOTUpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmdncGxvdCh1c19hZF9uZXcsIGFlcyh4ID0gR1JFLlNjb3JlLCB5ID0gTE9SKSwgY29sb3IgPSBDaGFuY2Uub2YuQWRtaXQgKSArIA0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBmb3JtdWxhID0geX5wb2x5KHgsIDIpLCBsZXZlbCA9IDAuOTUpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmdncGxvdCh1c19hZF9uZXcsIGFlcyh4ID0gR1JFLlNjb3JlLCB5ID0gQ0dQQSksIGNvbG9yID0gQ2hhbmNlLm9mLkFkbWl0ICkgKyANCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgZm9ybXVsYSA9IHl+cG9seSh4LCAyKSwgbGV2ZWwgPSAwLjk1KSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpnZ3Bsb3QodXNfYWRfbmV3LCBhZXMoeCA9IEdSRS5TY29yZSwgeSA9IFJlc2VhcmNoKSwgY29sb3IgPSBDaGFuY2Uub2YuQWRtaXQgKSArIA0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBmb3JtdWxhID0geX5wb2x5KHgsIDIpLCBsZXZlbCA9IDAuOTUpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCiMjIFJlZ3Jlc3Npb24gbW9kZWwNCmBgYHtyfQ0KbGlicmFyeShkYXRhc2V0cykNCmRhdGEodXNfYWRfbmV3KQ0KDQpsbV9tb2RlbCA9IGxtKENoYW5jZS5vZi5BZG1pdCB+IEdSRS5TY29yZStUT0VGTC5TY29yZStVbml2ZXJzaXR5LlJhdGluZytTT1ArTE9SK0NHUEErUmVzZWFyY2gsIGRhdGEgPSB1c19hZF9uZXcpDQpzdW1tYXJ5KGxtX21vZGVsKQ0KYGBgDQoNCg==