Call in the SAH segmentation datasset.
library(readxl)
SAH_imaging_database <- read_excel("~/Documents/Job/Research /Bulters research/SAH imaging /Data/SAH imaging database.xlsx",
sheet = "Complete dataset")
Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900Warning: NA inserted for an unsupported date prior to 1900
View(SAH_imaging_database)
data_imaging <- SAH_imaging_database
Error in exists(cacheKey, where = .rs.WorkingDataEnv, inherits = FALSE) :
invalid first argument
Error in assign(cacheKey, frame, .rs.CachedDataEnv) :
attempt to use zero-length variable name
Cohort characteristic calcuations.
Firstly, calculate the median and IQR from symptom onset to scan.
na.omit(data_imaging$Time_until_scan_min)
[1] 157 128 207 210 189 1165 113 163 769 340 147 13 1042 124 126 222 308 92 96 266 1200 117 148 347 934 96 652 513 144
[30] 90 637 208 276 294 533 129 155 998 330 337 149 125 244 1014 103 341 871 541 549 127 118 78 779 293 224 800 337 123
[59] 1256 225 482 1256 491 923 349 288 232 1351 1187 393 136 119 1320 261 385 728 113 175 371 117 119 671
attr(,"na.action")
[1] 39 42 52 55 59 60 62 68 70 71 74 75 76 77 80
attr(,"class")
[1] "omit"
summary(data_imaging$Time_until_scan_min)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
13.0 130.8 271.0 411.9 547.0 1351.0 15
271/60 #Mediam
[1] 4.516667
130/60 #1st quartile
[1] 2.166667
547/60 #3rd quartile
[1] 9.116667
Baseline characteristics table Unknown represents any missing data -
2 patients in the cohort did not have blood volumes collected.
library(gtsummary)
theme_gtsummary_compact()
Setting theme `Compact`
data_imaging %>% select("AGE", "SEX", "HTN", "ANEULOC", "SURGPROC", "Time_until_scan_min", "FISHGRDN", "SEBES", "Total blood", "SSV blood", "Non-SSV blood", "Total manual volume", "SSV Volume", "Ventricular volume", "Below SSV Volume", "WFNSGRDN") %>% tbl_summary()
| Characteristic |
N = 97 |
| AGE |
55 (50, 62) |
| SEX |
|
| Β Β Β Β Female |
75 (77%) |
| Β Β Β Β Male |
22 (23%) |
| HTN |
|
| Β Β Β Β N |
70 (72%) |
| Β Β Β Β Y |
27 (28%) |
| ANEULOC |
|
| Β Β Β Β Anterior Circulation |
80 (84%) |
| Β Β Β Β Posterior Circulation |
15 (16%) |
| Β Β Β Β Unknown |
2 |
| SURGPROC |
|
| Β Β Β Β Clipping |
22 (23%) |
| Β Β Β Β Coiling |
73 (75%) |
| Β Β Β Β Not Done |
2 (2.1%) |
| Time_until_scan_min |
271 (131, 547) |
| Β Β Β Β Unknown |
15 |
| FISHGRDN |
|
| Β Β Β Β 3 |
37 (38%) |
| Β Β Β Β 4 |
60 (62%) |
| SEBES |
|
| Β Β Β Β 0 |
63 (65%) |
| Β Β Β Β 1 |
15 (15%) |
| Β Β Β Β 2 |
9 (9.3%) |
| Β Β Β Β 3 |
7 (7.2%) |
| Β Β Β Β 4 |
3 (3.1%) |
| Total blood |
20 (9, 35) |
| SSV blood |
0.00 (0.00, 1.50) |
| Β Β Β Β Unknown |
2 |
| Non-SSV blood |
19 (9, 33) |
| Β Β Β Β Unknown |
2 |
| Total manual volume |
158 (90, 283) |
| SSV Volume |
37 (20, 75) |
| Ventricular volume |
39 (23, 62) |
| Below SSV Volume |
110 (59, 223) |
| WFNSGRDN |
|
| Β Β Β Β 1 |
44 (45%) |
| Β Β Β Β 2 |
16 (16%) |
| Β Β Β Β 3 |
5 (5.2%) |
| Β Β Β Β 4 |
27 (28%) |
| Β Β Β Β 5 |
5 (5.2%) |
Blood distributions to check for the normality and see if
transformations are required.
#Blood variables: Total Blood, SSV Blood and Non-SSV Blood
Total_blood <- SAH_imaging_database$`Total blood`
SSV_Blood <- SAH_imaging_database$`SSV blood`
Non_SSV_Blood <- SAH_imaging_database$`Non-SSV blood`
hist(Total_blood)

hist(SSV_Blood)

hist(Non_SSV_Blood)

library(moments)
d_total_blood <- density(Total_blood)# returns the density data
skewness(Total_blood, na.rm = TRUE) #Skewness
[1] 0.7766232
plot(d_total_blood, main = "Density plot Total Blood Volume (mls)", sub = "Skewness = 0.777") # plots the results

d_SSV_blood <- density(SSV_Blood, na.rm = TRUE)# returns the density data
skewness(SSV_Blood, na.rm = TRUE) #Skewness
[1] 3.526801
plot(d_SSV_blood, main = "Density plot SSV Blood Volume (mls)", sub = "Skewness = 3.53") # plots the results

d_Non_SSV_blood <- density(Non_SSV_Blood, na.rm = TRUE)# returns the density data
skewness(Non_SSV_Blood, na.rm = TRUE) #Skewness
[1] 0.7286446
plot(d_Non_SSV_blood, main = "Density plot Non-SSV Blood Volume (mls)", sub = "Skewness = 0.729") # plots the results

NA
NA
CSF distributions to check for skewness
#CSF variables: SEBES, Ventricular volume, SSV volume, Below SSV Volume
SEBES <- SAH_imaging_database$SEBES
Ventricle_CSF <- SAH_imaging_database$`Ventricular volume`
SSV_CSF <- SAH_imaging_database$`SSV Volume`
Below_SSV_CSF <- SAH_imaging_database$`Below SSV Volume`
Total_CSF <- SAH_imaging_database$`Total manual volume`
hist(SEBES)

hist(Ventricle_CSF)

hist(SSV_CSF)

hist(Below_SSV_CSF)

hist(Total_CSF)

library(moments)
d_SEBES <- density(SEBES)# returns the density data
skewness(SEBES, na.rm = TRUE) #Skewness
[1] 1.542407
plot(d_SEBES, main = "Density plot SEBES", sub = "Skewness = 1.542") # plots the results

d_Ventricle_CSF <- density(Ventricle_CSF, na.rm = TRUE)# returns the density data
skewness(Ventricle_CSF, na.rm = TRUE) #Skewness
[1] 1.590469
plot(d_Ventricle_CSF, main = "Density plot Ventricle CSF Volume (mls)", sub = "Skewness = 1.59") # plots the results

d_SSV_CSF <- density(SSV_CSF, na.rm = TRUE)# returns the density data
skewness(SSV_CSF, na.rm = TRUE) #Skewness
[1] 1.431467
plot(d_SSV_CSF, main = "Density plot SSV CSF Volume (mls)", sub = "Skewness = 1.43") # plots the results

d_Below_SSV_CSF <- density(Below_SSV_CSF, na.rm = TRUE)# returns the density data
skewness(Below_SSV_CSF, na.rm = TRUE) #Skewness
[1] 0.8290886
plot(d_Below_SSV_CSF, main = "Density plot Below SSV CSF Volume (mls)", sub = "Skewness = 0.829") # plots the results

d_Total_CSF <- density(Total_CSF, na.rm = TRUE)# returns the density data
skewness(Total_CSF, na.rm = TRUE) #Skewness
[1] 0.899855
plot(d_Total_CSF, main = "Density plot Total CSF Volume (mls)", sub = "Skewness = 0.9") # plots the results

Decision made not to transform the variables because they are
generally normally distributed, with the exception of SSV blood which is
not a clinically important variable anyway.
The next step is to identify through correlation matrices, how the
imaging variables are related..
#For visualisation ensure that the variables have the correct names
SAH_imaging_database$Age <- SAH_imaging_database$AGE
SAH_imaging_database$WFNS <- SAH_imaging_database$WFNSGRDN
SAH_imaging_database$Total_CSF <- SAH_imaging_database$`Total manual volume`
SAH_imaging_database$Ventricular_CSF <- SAH_imaging_database$`Ventricular volume`
SAH_imaging_database$SSV_CSF <- SAH_imaging_database$`SSV Volume`
data_imaging_correlation <- SAH_imaging_database[, c("Age", "WFNS",
"Total blood", "SSV_CSF", "Ventricular_CSF",
"Total_CSF")]
data_imaging_correlation <- na.omit(data_imaging_correlation)
remove.packages('Hmisc')
Removing package from β/Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/libraryβ
(as βlibβ is unspecified)
install.packages("Hmisc", repos="http://cran.rstudio.com/", dependencies=TRUE)
trying URL 'http://cran.rstudio.com/bin/macosx/big-sur-arm64/contrib/4.3/Hmisc_5.1-0.tgz'
Content type 'application/x-gzip' length 3515239 bytes (3.4 MB)
==================================================
downloaded 3.4 MB
The downloaded binary packages are in
/var/folders/5q/zxkgc5yn685ffrcr6m2_f_4h0000gn/T//RtmpVnEbxd/downloaded_packages
install.packages("checkmate")
trying URL 'https://cran.rstudio.com/bin/macosx/big-sur-arm64/contrib/4.3/checkmate_2.2.0.tgz'
Content type 'application/x-gzip' length 772034 bytes (753 KB)
==================================================
downloaded 753 KB
The downloaded binary packages are in
/var/folders/5q/zxkgc5yn685ffrcr6m2_f_4h0000gn/T//RtmpVnEbxd/downloaded_packages
library(Hmisc)
Registered S3 method overwritten by 'htmlwidgets':
method from
print.htmlwidget tools:rstudio
Registered S3 method overwritten by 'data.table':
method from
print.data.table
Attaching package: βHmiscβ
The following objects are masked from βpackage:baseβ:
format.pval, units
res2 <- rcorr(as.matrix(data_imaging_correlation), type = "spearman")
res2
Age WFNS Total blood SSV_CSF Ventricular_CSF Total_CSF
Age 1.00 0.06 0.01 0.24 0.39 0.34
WFNS 0.06 1.00 0.46 -0.37 -0.03 -0.14
Total blood 0.01 0.46 1.00 -0.26 -0.28 -0.19
SSV_CSF 0.24 -0.37 -0.26 1.00 0.45 0.78
Ventricular_CSF 0.39 -0.03 -0.28 0.45 1.00 0.78
Total_CSF 0.34 -0.14 -0.19 0.78 0.78 1.00
n= 97
P
Age WFNS Total blood SSV_CSF Ventricular_CSF Total_CSF
Age 0.5781 0.9249 0.0196 0.0000 0.0007
WFNS 0.5781 0.0000 0.0002 0.7396 0.1653
Total blood 0.9249 0.0000 0.0108 0.0051 0.0589
SSV_CSF 0.0196 0.0002 0.0108 0.0000 0.0000
Ventricular_CSF 0.0000 0.7396 0.0051 0.0000 0.0000
Total_CSF 0.0007 0.1653 0.0589 0.0000 0.0000
res2$r
Age WFNS Total blood SSV_CSF Ventricular_CSF Total_CSF
Age 1.000000000 0.05716434 0.009694334 0.2367181 0.38567391 0.3391306
WFNS 0.057164345 1.00000000 0.460972143 -0.3728866 -0.03418735 -0.1420047
Total blood 0.009694334 0.46097214 1.000000000 -0.2577188 -0.28217705 -0.1925100
SSV_CSF 0.236718130 -0.37288664 -0.257718809 1.0000000 0.44937408 0.7821244
Ventricular_CSF 0.385673908 -0.03418735 -0.282177046 0.4493741 1.00000000 0.7780086
Total_CSF 0.339130575 -0.14200467 -0.192509994 0.7821244 0.77800863 1.0000000
res2$P
Age WFNS Total blood SSV_CSF Ventricular_CSF Total_CSF
Age NA 5.781015e-01 9.249165e-01 1.957150e-02 9.569289e-05 0.0006787165
WFNS 5.781015e-01 NA 2.018435e-06 1.688910e-04 7.395581e-01 0.1652907303
Total blood 9.249165e-01 2.018435e-06 NA 1.081759e-02 5.106494e-03 0.0588736570
SSV_CSF 1.957150e-02 1.688910e-04 1.081759e-02 NA 3.889443e-06 0.0000000000
Ventricular_CSF 9.569289e-05 7.395581e-01 5.106494e-03 3.889443e-06 NA 0.0000000000
Total_CSF 6.787165e-04 1.652907e-01 5.887366e-02 0.000000e+00 0.000000e+00 NA
flattenCorrMatrix <- function(cormat, pmat) { #format correlation matrix
ut <- upper.tri(cormat)
data.frame(
row = rownames(cormat)[row(cormat)[ut]],
column = rownames(cormat)[col(cormat)[ut]],
cor =(cormat)[ut],
p = pmat[ut]
)
}
correlation_matrix <- flattenCorrMatrix(res2$r, res2$P)
write.csv(correlation_matrix, "Correlation_matrix.csv", row.names = F) #export table
library(corrplot) #visualise the correlation matrix
corrplot 0.92 loaded
res <- cor(data_imaging_correlation)
corrplot(res, type = "upper", order = "hclust",
tl.col = "black", tl.srt = 45)

corrplot(res2$r, type="upper", order="hclust", #insignificant correlations removed
p.mat = res2$P, sig.level = 0.01, insig = "blank")
Error in data.frame(..., check.names = FALSE) :
arguments imply differing number of rows: 21, 15

Univariate analysis of variables
summary(Univariate)
Call:
glm(formula = data_imaging$SAHOT180_dich ~ data_imaging$Total_CSF,
family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.381248 0.379002 -1.006 0.314
data_imaging$Total_CSF -0.001276 0.001626 -0.785 0.433
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 122.70 on 94 degrees of freedom
Residual deviance: 122.07 on 93 degrees of freedom
AIC: 126.07
Number of Fisher Scoring iterations: 4
Dominance plots
To prevent overfitting of further predictive models, a dominance
analysis was done by assessing each variableβs R2 when predicting mRS at
day 28 and day 180. The mRS at day 28 and day 180 were used because mRS
is used most widely in clinical practice to assess functional outcome.
Day 28 was selected to reflect short term and day 180 long-term outcome.
In addition, to demonstrate the difference between a general scale of
functional outcome for stroke and a patient reported SAH specific scale
of symptoms we undertook a dominance analysis of SAHOT on day 180.

Multivariate analysis
In order to investigate the additional benefit of blood and CSF
volume measurements in models over conventional clinical features alone
multivariate models were built using the previously reported SAHIT core
variables to predict mRS at day 28 and 180 and repeated adding total
blood volume, SSV CSF, ventricular CSF.
Core model= Age, Hypertension and Admission WFNS Neuroimaging model=
Core model + Total Blood volume, SSV CSF and Ventricular CSF
For unknown reasons the below code did not work and therefore, I
created the AUC graphs by adapting my previous analysed code.
legend("bottomright", title = "modified Rankin Scale",
legend = c("Neuroimaging Day 28", "Neuroimaging Day 180", "Clinical Day 28", "Clinical Day 180"), col = c("red", "black", "orange", "blue"),
lwd = 2, "Legend", cex=0.8)
Error in (function (s, units = "user", cex = NULL, font = NULL, vfont = NULL, :
plot.new has not been called yet

SSV dichotomisation from the literature
Choi et al.: SSV not normally distributed and subjects separated into
equal quartiles for measuring odds ratios in examining associations with
GCE as well as clinical outcomes. FINDINGS: compared to patients in the
highest quartile for SSV, the OR for poor outcome at discharge increased
in a dose dependent manner in the lower quartiles after adjusting for
age, sex, smoking hypertension and HH score
Yuan et al.: SSV taken as continuous variable and in sensitivity
analysis dichotomisation at <5.2ml was done. FINDINGS early SSV
defined as lowest SSV volume in first 72hrs but not admission SSV was
predictive of outcome
Create two new variables, SSV_quantiles and SSV_dich
levels(SSV_dich)
NULL
Currently have several CSF volumes including - total CSF, SSV CSF,
ventricular CSF and below SSV CSF. However, one volume that is missing,
is a non-SSV, non-ventricular CSF.
Create non_SSV_non_vent_CSF variable
summary(Univariate)
Call:
glm(formula = SAHOT180_dich ~ non_SSV_non_vent_CSF, family = binomial,
data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.658236 0.338537 -1.944 0.0519 .
non_SSV_non_vent_CSF 0.000288 0.002716 0.106 0.9155
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 122.70 on 94 degrees of freedom
Residual deviance: 122.69 on 93 degrees of freedom
(2 observations deleted due to missingness)
AIC: 126.69
Number of Fisher Scoring iterations: 4
Before multivariate analysis, letβs see if the new SSV cut-offs make
it a significant predictor of day 30 and 180 outcome in a univariate
analysis
summary(Univariate)
Call:
glm(formula = SAHOT180_dich ~ SSV_dich, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.7357 0.2536 -2.901 0.00372 **
SSV_dichlow 0.3992 0.4855 0.822 0.41093
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 122.70 on 94 degrees of freedom
Residual deviance: 122.03 on 93 degrees of freedom
(2 observations deleted due to missingness)
AIC: 126.03
Number of Fisher Scoring iterations: 4
Repeat regressions:
Before we make that major restructure we wanted to see the outcomes
of the regressions for
- WFNS, TBV and SSV to predict outcome (MRS and SAHOT at day 30 and
180)
- WFNS, TBV and ventricular volume to predict outcome
If the latter does not give a clear result then we wanted to try it
again but:
- add presence of an EVD as a covariate and an interaction between
ventricular volume and an EVD
- add an interaction between TBV and ventricular volume
# Regression 1: WFNS, TBV and SSV regression
Multivariate <- glm(as.factor(mRS28) ~ WFNS+Total_blood_volume+SSV_CSF, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(mRS28) ~ WFNS + Total_blood_volume +
SSV_CSF, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -3.010329 0.784551 -3.837 0.000125 ***
WFNS 0.856655 0.209192 4.095 4.22e-05 ***
Total_blood_volume 0.014721 0.015629 0.942 0.346263
SSV_CSF -0.004514 0.006311 -0.715 0.474383
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 124.387 on 96 degrees of freedom
Residual deviance: 89.964 on 93 degrees of freedom
AIC: 97.964
Number of Fisher Scoring iterations: 4
Multivariate <- glm(as.factor(mRS180) ~ WFNS+Total_blood_volume+SSV_CSF, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(mRS180) ~ WFNS + Total_blood_volume +
SSV_CSF, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -3.415511 0.984158 -3.470 0.00052 ***
WFNS 0.525937 0.238247 2.208 0.02728 *
Total_blood_volume 0.018970 0.016313 1.163 0.24489
SSV_CSF -0.004060 0.007936 -0.512 0.60894
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 86.870 on 96 degrees of freedom
Residual deviance: 74.307 on 93 degrees of freedom
AIC: 82.307
Number of Fisher Scoring iterations: 5
Multivariate <- glm(as.factor(SAHOT28_dich) ~ WFNS+Total_blood_volume+SSV_CSF, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(SAHOT28_dich) ~ WFNS + Total_blood_volume +
SSV_CSF, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.469845 0.589470 -0.797 0.4254
WFNS 0.213558 0.180917 1.180 0.2378
Total_blood_volume 0.024086 0.014551 1.655 0.0979 .
SSV_CSF -0.008032 0.005332 -1.506 0.1320
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 131.18 on 94 degrees of freedom
Residual deviance: 117.88 on 91 degrees of freedom
(2 observations deleted due to missingness)
AIC: 125.88
Number of Fisher Scoring iterations: 4
Multivariate <- glm(as.factor(SAHOT180_dich) ~ WFNS+Total_blood_volume+SSV_CSF, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(SAHOT180_dich) ~ WFNS + Total_blood_volume +
SSV_CSF, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.936754 0.645685 -1.451 0.1468
WFNS -0.014991 0.187351 -0.080 0.9362
Total_blood_volume 0.030589 0.014152 2.161 0.0307 *
SSV_CSF -0.009022 0.006394 -1.411 0.1582
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 122.70 on 94 degrees of freedom
Residual deviance: 112.25 on 91 degrees of freedom
(2 observations deleted due to missingness)
AIC: 120.25
Number of Fisher Scoring iterations: 4
# For mRS, WFNS is a significant predictor, for SAHOT, TBV is significant.Substitute in new SSV variables to see if this makes a difference.
#SSV_quantile first
Multivariate <- glm(as.factor(mRS28) ~ WFNS+Total_blood_volume+SSV_quantiles, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(mRS28) ~ WFNS + Total_blood_volume +
SSV_quantiles, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -3.44386 0.95249 -3.616 0.000300 ***
WFNS 0.91927 0.23636 3.889 0.000101 ***
Total_blood_volume 0.01880 0.01655 1.136 0.255768
SSV_quantiles2 -0.36984 0.78129 -0.473 0.635952
SSV_quantiles3 0.62358 0.78633 0.793 0.427768
SSV_quantiles4 -0.72274 0.81935 -0.882 0.377732
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 124.387 on 96 degrees of freedom
Residual deviance: 87.279 on 91 degrees of freedom
AIC: 99.279
Number of Fisher Scoring iterations: 5
Multivariate <- glm(as.factor(mRS180) ~ WFNS+Total_blood_volume+SSV_quantiles, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(mRS180) ~ WFNS + Total_blood_volume +
SSV_quantiles, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -4.62012 1.16642 -3.961 7.47e-05 ***
WFNS 0.70936 0.26454 2.681 0.00733 **
Total_blood_volume 0.01309 0.01801 0.727 0.46708
SSV_quantiles2 1.10257 0.85530 1.289 0.19736
SSV_quantiles3 1.23702 0.91902 1.346 0.17829
SSV_quantiles4 0.23181 1.00954 0.230 0.81838
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 86.870 on 96 degrees of freedom
Residual deviance: 71.709 on 91 degrees of freedom
AIC: 83.709
Number of Fisher Scoring iterations: 5
Multivariate <- glm(as.factor(SAHOT28_dich) ~ WFNS+Total_blood_volume+SSV_quantiles, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(SAHOT28_dich) ~ WFNS + Total_blood_volume +
SSV_quantiles, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.56706 0.74665 -0.759 0.448
WFNS 0.22010 0.20052 1.098 0.272
Total_blood_volume 0.02143 0.01498 1.431 0.152
SSV_quantiles2 0.35846 0.70441 0.509 0.611
SSV_quantiles3 -0.59282 0.66883 -0.886 0.375
SSV_quantiles4 -0.84778 0.68353 -1.240 0.215
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 131.18 on 94 degrees of freedom
Residual deviance: 116.03 on 89 degrees of freedom
(2 observations deleted due to missingness)
AIC: 128.03
Number of Fisher Scoring iterations: 4
Multivariate <- glm(as.factor(SAHOT180_dich) ~ WFNS+Total_blood_volume+SSV_quantiles, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(SAHOT180_dich) ~ WFNS + Total_blood_volume +
SSV_quantiles, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.1602876 0.7493937 -1.548 0.1215
WFNS -0.0006619 0.2018584 -0.003 0.9974
Total_blood_volume 0.0305582 0.0147357 2.074 0.0381 *
SSV_quantiles2 0.0063719 0.6535923 0.010 0.9922
SSV_quantiles3 -0.1591029 0.6770875 -0.235 0.8142
SSV_quantiles4 -1.0107826 0.7590549 -1.332 0.1830
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 122.70 on 94 degrees of freedom
Residual deviance: 111.88 on 89 degrees of freedom
(2 observations deleted due to missingness)
AIC: 123.88
Number of Fisher Scoring iterations: 4
#Makes no difference. How about SSV_dich
Multivariate <- glm(as.factor(mRS28) ~ WFNS+Total_blood_volume+SSV_dich, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(mRS28) ~ WFNS + Total_blood_volume +
SSV_dich, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -3.35505 0.64610 -5.193 2.07e-07 ***
WFNS 0.86463 0.22327 3.873 0.000108 ***
Total_blood_volume 0.01661 0.01556 1.067 0.285778
SSV_dichlow 0.16214 0.61914 0.262 0.793417
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 124.387 on 96 degrees of freedom
Residual deviance: 90.424 on 93 degrees of freedom
AIC: 98.424
Number of Fisher Scoring iterations: 4
Multivariate <- glm(as.factor(mRS180) ~ WFNS+Total_blood_volume+SSV_dich, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(mRS180) ~ WFNS + Total_blood_volume +
SSV_dich, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -3.74949 0.81003 -4.629 3.68e-06 ***
WFNS 0.69899 0.26084 2.680 0.00737 **
Total_blood_volume 0.01566 0.01677 0.934 0.35020
SSV_dichlow -0.90681 0.74110 -1.224 0.22111
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 86.870 on 96 degrees of freedom
Residual deviance: 72.985 on 93 degrees of freedom
AIC: 80.985
Number of Fisher Scoring iterations: 5
Multivariate <- glm(as.factor(SAHOT28_dich) ~ WFNS+Total_blood_volume+SSV_dich, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(SAHOT28_dich) ~ WFNS + Total_blood_volume +
SSV_dich, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.06198 0.44665 -2.378 0.0174 *
WFNS 0.20878 0.19555 1.068 0.2857
Total_blood_volume 0.02790 0.01457 1.915 0.0555 .
SSV_dichlow 0.37694 0.57273 0.658 0.5104
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 131.18 on 94 degrees of freedom
Residual deviance: 119.86 on 91 degrees of freedom
(2 observations deleted due to missingness)
AIC: 127.86
Number of Fisher Scoring iterations: 4
Multivariate <- glm(as.factor(SAHOT180_dich) ~ WFNS+Total_blood_volume+SSV_dich, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(SAHOT180_dich) ~ WFNS + Total_blood_volume +
SSV_dich, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.583066 0.483300 -3.276 0.00105 **
WFNS 0.008426 0.200301 0.042 0.96645
Total_blood_volume 0.033597 0.014236 2.360 0.01827 *
SSV_dichlow 0.308950 0.565281 0.547 0.58469
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 122.70 on 94 degrees of freedom
Residual deviance: 114.23 on 91 degrees of freedom
(2 observations deleted due to missingness)
AIC: 122.23
Number of Fisher Scoring iterations: 4
#Again no difference made.
# Regression 2: WFNS, TBV and ventricular volume to predict outcome
Multivariate <- glm(as.factor(mRS28) ~ WFNS+Total_blood_volume+Ventricular_CSF, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(mRS28) ~ WFNS + Total_blood_volume +
Ventricular_CSF, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -4.396700 0.877685 -5.009 5.46e-07 ***
WFNS 0.882108 0.213980 4.122 3.75e-05 ***
Total_blood_volume 0.026610 0.016492 1.614 0.1066
Ventricular_CSF 0.014472 0.006771 2.137 0.0326 *
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 124.39 on 96 degrees of freedom
Residual deviance: 85.55 on 93 degrees of freedom
AIC: 93.55
Number of Fisher Scoring iterations: 5
Multivariate <- glm(as.factor(mRS180) ~ WFNS+Total_blood_volume+Ventricular_CSF, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(mRS180) ~ WFNS + Total_blood_volume +
Ventricular_CSF, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -4.688721 1.031167 -4.547 5.44e-06 ***
WFNS 0.535981 0.241497 2.219 0.0265 *
Total_blood_volume 0.030422 0.017492 1.739 0.0820 .
Ventricular_CSF 0.012876 0.006733 1.912 0.0558 .
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 86.870 on 96 degrees of freedom
Residual deviance: 70.991 on 93 degrees of freedom
AIC: 78.991
Number of Fisher Scoring iterations: 5
Multivariate <- glm(as.factor(SAHOT28_dich) ~ WFNS+Total_blood_volume+Ventricular_CSF, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(SAHOT28_dich) ~ WFNS + Total_blood_volume +
Ventricular_CSF, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.309795 0.552306 -2.372 0.0177 *
WFNS 0.242631 0.177250 1.369 0.1710
Total_blood_volume 0.029947 0.015179 1.973 0.0485 *
Ventricular_CSF 0.004223 0.005557 0.760 0.4473
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 131.18 on 94 degrees of freedom
Residual deviance: 119.71 on 91 degrees of freedom
(2 observations deleted due to missingness)
AIC: 127.71
Number of Fisher Scoring iterations: 4
Multivariate <- glm(as.factor(SAHOT180_dich) ~ WFNS+Total_blood_volume+Ventricular_CSF, family = binomial, data = data_imaging)
summary(Multivariate)
Call:
glm(formula = as.factor(SAHOT180_dich) ~ WFNS + Total_blood_volume +
Ventricular_CSF, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.586e+00 5.821e-01 -2.725 0.00644 **
WFNS 5.660e-02 1.822e-01 0.311 0.75604
Total_blood_volume 3.239e-02 1.463e-02 2.213 0.02688 *
Ventricular_CSF 5.209e-05 5.813e-03 0.009 0.99285
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 122.70 on 94 degrees of freedom
Residual deviance: 114.53 on 91 degrees of freedom
(2 observations deleted due to missingness)
AIC: 122.53
Number of Fisher Scoring iterations: 4
# Ventricular CSF significant at 30 day mRS and almost significant for mRS 180. However, not significant for SAHOT.
The above regressions demonstrate several observations with the
dataset:
- WFNS is a highly significant predictor of functional outcome at 30
days and 180 days
- When using a more specific outcome tool for SAH (SAHOT), TBV is
shown to be a highly significant predictor
- Univariate analysis of SSV using cut offs, which isolate cases with
βlowβ SSV, makes it a significant variable at early timepoints
- Multivariate analyse shows that SSV is not an independent predictor
of outcome when TBV and WFNS are included. However, Ventricular volume
is an independent predictor of outcome using mRS
I think the above gives a clear result. Firstly, it shows that we
have been able to replicate previous findings in the literature, that at
early timepoints SSV predicts outcome. However, we have shown that this
affect is not maintained at later timepoints or when combined with other
significant predictors of outcome. Instead, imaging predictors of TBV,
and to a lesser extent ventricular CSF are more important.
The narrative of the paper is clearer to me now and I think should be
presented something like this:
- Basic demographics
- Regression 1 and Regression 2 from above
- Interaction plots
- Inclusion of βotherβ imaging variables to show they are less
relevant
For completeness, below I will include:
- add presence of an EVD as a covariate and an interaction between
ventricular volume and an EVD
- add an interaction between TBV and ventricular volume
summary(Multivariate)
Call:
glm(formula = as.factor(mRS180) ~ WFNS + Total_blood_volume +
Ventricular_CSF * EVD, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -5.17723 1.23504 -4.192 2.77e-05 ***
WFNS 0.35852 0.29083 1.233 0.2177
Total_blood_volume 0.02756 0.01767 1.560 0.1188
Ventricular_CSF 0.02031 0.01024 1.983 0.0474 *
EVDY 2.12353 1.11352 1.907 0.0565 .
Ventricular_CSF:EVDY -0.01595 0.01299 -1.227 0.2197
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 86.870 on 96 degrees of freedom
Residual deviance: 66.859 on 91 degrees of freedom
AIC: 78.859
Number of Fisher Scoring iterations: 6
Another thing we should check is whether the model fit is better if
we use just: -WFNS and blood vol -WFNS and CSF vol -Blood and CSF
vol
summary(Multivariate)
Call:
glm(formula = as.factor(mRS180) ~ WFNS + Total_blood_volume +
Total_CSF, family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -4.399267 1.094137 -4.021 5.8e-05 ***
WFNS 0.609560 0.242768 2.511 0.012 *
Total_blood_volume 0.022004 0.016296 1.350 0.177
Total_CSF 0.002316 0.002224 1.041 0.298
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 86.870 on 96 degrees of freedom
Residual deviance: 73.526 on 93 degrees of freedom
AIC: 81.526
Number of Fisher Scoring iterations: 5
SAHOT as linear to see if this changes significance of variables.
SAHOT is a 9 part scale 1 (Best outcome), 9 (death).
Repeat regressions Univariate SSV analyses:

As SAHOT as a linear 9 point scale,
Repeat regressions SAHOT at D28 and D180: 1) WFNS, TBV and SSV to
predict outcome (MRS and SAHOT at day 30 and 180) 2) WFNS, TBV and
ventricular volume to predict outcome
summary(Multivariate)
Call:
lm(formula = sahot180 ~ WFNS + Total_blood_volume + Ventricular_CSF,
data = data_imaging)
Residuals:
Min 1Q Median 3Q Max
-3.4973 -1.7656 -0.4125 1.5223 5.1628
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.2918313 0.5470922 4.189 6.47e-05 ***
WFNS 0.2250422 0.1820884 1.236 0.21968
Total_blood_volume 0.0416388 0.0143432 2.903 0.00464 **
Ventricular_CSF 0.0008862 0.0056270 0.157 0.87520
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
Residual standard error: 2.149 on 91 degrees of freedom
(2 observations deleted due to missingness)
Multiple R-squared: 0.1658, Adjusted R-squared: 0.1383
F-statistic: 6.028 on 3 and 91 DF, p-value: 0.0008604
Reasoning why a variable in a univariate analysis is not significant
but becomes significant in a multivariate analysis:
The case of two predictors that are truly orthogonal: there is
absolutely no collinearity among them. A remarkable change in
significance can still happen.
Designate the predictor variables π1 and π2 and let π name the
predictor. The regression of π against π1 will fail to be significant
when the variation in π around its mean is not appreciably reduced when
π1 is used as the independent variable. When that variation is strongly
associated with a second variable π2, however, the situation changes.
Recall that multiple regression of π against π1 and π2 is equivalent to
separately regress π and π1 against π2.
Regress the π residuals against the π1 residuals.
The residuals from the first step have removed the effect of π2. When
π2 is closely correlated with π, this can expose a relatively small
amount of variation that had previously been masked. If this variation
is associated with π1, we obtain a significant result.
Further info from: https://stats.stackexchange.com/questions/28474/how-can-adding-a-2nd-iv-make-the-1st-iv-significant
In the analyses done WFNS and ventricular volume are not colinear,
but blood volume and ventricular volume are colinear in a negative
direction. WFNS and ventricular volume, therefore represent the above
finding:
#Ventricular volume only
Univariate <- glm(as.factor(mRS180) ~ Ventricular_CSF, family =
binomial, data = data_imaging) summary(Univariate)
#Ventricular volume is not significant on its own
#WFNS and ventricular volume
Multivariate <- glm(as.factor(mRS180) ~ WFNS+Ventricular_CSF,
family = binomial, data = data_imaging) summary(Multivariate)
##AIC: 94.269 #WFNS significant, ventricular volume is almost
significant
#Blood and ventricular volume
Multivariate <- glm(as.factor(mRS180) ~
Total_blood_volume+Ventricular_CSF, family = binomial, data =
data_imaging) summary(Multivariate)
##AIC: 112.16 #Total blood very significant and ventricular volume
significant - probably due to collinarity
Shapley plots
Complex predictive models are not easy to interpret. By complex I
mean: random forest, xgboost, deep learning, etc.
Shapley values calculate the importance of a feature by comparing
what a model predicts with and without the feature. However, since the
order in which a model sees features can affect its predictions, this is
done in every possible order, so that the features are fairly
compared.
How to interpret the shap summary plot?
The y-axis indicates the variable name, in order of importance from
top to bottom. The value next to them is the mean SHAP value. On the
x-axis is the SHAP value. Indicates how much is the change in log-odds.
From this number we can extract the probability of success. Gradient
color indicates the original value for that variable. In booleans, it
will take two colors, but in number it can contain the whole spectrum.
Each point represents a row from the original dataset.
fit_xgb <- xgb.train(
params,
data = dtrain,
watchlist = list(valid = dvalid),
early_stopping_rounds = 20,
print_every_n = 100,
nrounds = 10000 # early stopping
)
Error in xgb.iter.update(bst$handle, dtrain, iteration - 1, obj) :
[15:53:06] src/objective/regression_obj.cu:43: Check failed: info.labels.Shape(0) == info.num_row_ (0 vs. 97) : Invalid shape of labels.
Stack trace:
[bt] (0) 1 xgboost.so 0x000000013580bd3c dmlc::LogMessageFatal::~LogMessageFatal() + 124
[bt] (1) 2 xgboost.so 0x0000000135836b10 xgboost::obj::(anonymous namespace)::CheckInitInputs(xgboost::MetaInfo const&) + 208
[bt] (2) 3 xgboost.so 0x00000001358368dc xgboost::obj::(anonymous namespace)::CheckRegInputs(xgboost::MetaInfo const&, xgboost::HostDeviceVector<float> const&) + 28
[bt] (3) 4 xgboost.so 0x0000000135835c3c xgboost::obj::RegLossObj<xgboost::obj::LinearSquareLoss>::GetGradient(xgboost::HostDeviceVector<float> const&, xgboost::MetaInfo const&, int, xgboost::HostDeviceVector<xgboost::detail::GradientPairInternal<float> >*) + 60
[bt] (4) 5 xgboost.so 0x00000001359610fc xgboost::Lea
Create a comparative AUC graph for the βfinalβ model that includes
WFNS, total blood volume and ventricular CSF volume in the prediction of
mRS 180
legend("bottomright", title = "modified Rankin Scale",
legend = c("WFNS+Blood", "WFNS+VentricularCSF", "Final model", "WFNS+SSV_CSF", "WFNS+TotalCSF"), col = c("red", "black", "orange", "blue", "forestgreen"),
lwd = 2, "Legend", cex=0.8)
Error in (function (s, units = "user", cex = NULL, font = NULL, vfont = NULL, :
plot.new has not been called yet
Stepwise regresssional analysis for the development of the
multivariate model.
Variables: age, WFNS, TBV, SSV, Ventricular CSF, total CSF
summary(step.model)
Call:
glm(formula = mRS180 ~ WFNS + Total_blood + Ventricular_CSF,
family = binomial, data = data_imaging)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -4.688721 1.031167 -4.547 5.44e-06 ***
WFNS 0.535981 0.241497 2.219 0.0265 *
Total_blood 0.030422 0.017492 1.739 0.0820 .
Ventricular_CSF 0.012876 0.006733 1.912 0.0558 .
---
Signif. codes: 0 β***β 0.001 β**β 0.01 β*β 0.05 β.β 0.1 β β 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 86.870 on 96 degrees of freedom
Residual deviance: 70.991 on 93 degrees of freedom
AIC: 78.991
Number of Fisher Scoring iterations: 5
LS0tCnRpdGxlOiAiU0FIIFNlZ21lbnRhdGlvbiBQcm9qZWN0IgphdXRob3I6ICJKYW1lcyBCb29rZXIiCmRhdGE6IDI2dGggQXByaWwgMjAyMwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgpDYWxsIGluIHRoZSBTQUggc2VnbWVudGF0aW9uIGRhdGFzc2V0LiAKCmBgYHtyfQpsaWJyYXJ5KHJlYWR4bCkKU0FIX2ltYWdpbmdfZGF0YWJhc2UgPC0gcmVhZF9leGNlbCgifi9Eb2N1bWVudHMvSm9iL1Jlc2VhcmNoIC9CdWx0ZXJzIHJlc2VhcmNoL1NBSCBpbWFnaW5nIC9EYXRhL1NBSCBpbWFnaW5nIGRhdGFiYXNlLnhsc3giLCAKICAgIHNoZWV0ID0gIkNvbXBsZXRlIGRhdGFzZXQiKQpWaWV3KFNBSF9pbWFnaW5nX2RhdGFiYXNlKQoKZGF0YV9pbWFnaW5nIDwtIFNBSF9pbWFnaW5nX2RhdGFiYXNlCmBgYAoKQ29ob3J0IGNoYXJhY3RlcmlzdGljIGNhbGN1YXRpb25zLiAKCkZpcnN0bHksIGNhbGN1bGF0ZSB0aGUgbWVkaWFuIGFuZCBJUVIgZnJvbSBzeW1wdG9tIG9uc2V0IHRvIHNjYW4uIAoKYGBge3J9Cm5hLm9taXQoZGF0YV9pbWFnaW5nJFRpbWVfdW50aWxfc2Nhbl9taW4pCnN1bW1hcnkoZGF0YV9pbWFnaW5nJFRpbWVfdW50aWxfc2Nhbl9taW4pCjI3MS82MCAjTWVkaWFtCjEzMC82MCAjMXN0IHF1YXJ0aWxlIAo1NDcvNjAgIzNyZCBxdWFydGlsZQpgYGAKQmFzZWxpbmUgY2hhcmFjdGVyaXN0aWNzIHRhYmxlIApVbmtub3duIHJlcHJlc2VudHMgYW55IG1pc3NpbmcgZGF0YSAtIDIgcGF0aWVudHMgaW4gdGhlIGNvaG9ydCBkaWQgbm90IGhhdmUgYmxvb2Qgdm9sdW1lcyBjb2xsZWN0ZWQuICAKCmBgYHtyfQpsaWJyYXJ5KGd0c3VtbWFyeSkKdGhlbWVfZ3RzdW1tYXJ5X2NvbXBhY3QoKQpkYXRhX2ltYWdpbmcgJT4lIHNlbGVjdCgiQUdFIiwgIlNFWCIsICJIVE4iLCAiQU5FVUxPQyIsICJTVVJHUFJPQyIsICJUaW1lX3VudGlsX3NjYW5fbWluIiwgIkZJU0hHUkROIiwgIlNFQkVTIiwgIlRvdGFsIGJsb29kIiwgIlNTViBibG9vZCIsICJOb24tU1NWIGJsb29kIiwgIlRvdGFsIG1hbnVhbCB2b2x1bWUiLCAiU1NWIFZvbHVtZSIsICJWZW50cmljdWxhciB2b2x1bWUiLCAiQmVsb3cgU1NWIFZvbHVtZSIsICJXRk5TR1JETiIpICU+JSB0Ymxfc3VtbWFyeSgpCmBgYAoKQmxvb2QgZGlzdHJpYnV0aW9ucyB0byBjaGVjayBmb3IgdGhlIG5vcm1hbGl0eSBhbmQgc2VlIGlmIHRyYW5zZm9ybWF0aW9ucyBhcmUgcmVxdWlyZWQuCgpgYGB7cn0KI0Jsb29kIHZhcmlhYmxlczogVG90YWwgQmxvb2QsIFNTViBCbG9vZCBhbmQgTm9uLVNTViBCbG9vZAoKVG90YWxfYmxvb2QgPC0gU0FIX2ltYWdpbmdfZGF0YWJhc2UkYFRvdGFsIGJsb29kYApTU1ZfQmxvb2QgPC0gU0FIX2ltYWdpbmdfZGF0YWJhc2UkYFNTViBibG9vZGAKTm9uX1NTVl9CbG9vZCA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZSRgTm9uLVNTViBibG9vZGAKCmhpc3QoVG90YWxfYmxvb2QpCmhpc3QoU1NWX0Jsb29kKQpoaXN0KE5vbl9TU1ZfQmxvb2QpCgpsaWJyYXJ5KG1vbWVudHMpCmRfdG90YWxfYmxvb2QgPC0gZGVuc2l0eShUb3RhbF9ibG9vZCkjIHJldHVybnMgdGhlIGRlbnNpdHkgZGF0YQpza2V3bmVzcyhUb3RhbF9ibG9vZCwgbmEucm0gPSBUUlVFKSAjU2tld25lc3MKcGxvdChkX3RvdGFsX2Jsb29kLCBtYWluID0gIkRlbnNpdHkgcGxvdCBUb3RhbCBCbG9vZCBWb2x1bWUgKG1scykiLCBzdWIgPSAiU2tld25lc3MgPSAwLjc3NyIpICMgcGxvdHMgdGhlIHJlc3VsdHMKCmRfU1NWX2Jsb29kIDwtIGRlbnNpdHkoU1NWX0Jsb29kLCBuYS5ybSA9IFRSVUUpIyByZXR1cm5zIHRoZSBkZW5zaXR5IGRhdGEKc2tld25lc3MoU1NWX0Jsb29kLCBuYS5ybSA9IFRSVUUpICNTa2V3bmVzcwpwbG90KGRfU1NWX2Jsb29kLCBtYWluID0gIkRlbnNpdHkgcGxvdCBTU1YgQmxvb2QgVm9sdW1lIChtbHMpIiwgc3ViID0gIlNrZXduZXNzID0gMy41MyIpICMgcGxvdHMgdGhlIHJlc3VsdHMKCmRfTm9uX1NTVl9ibG9vZCA8LSBkZW5zaXR5KE5vbl9TU1ZfQmxvb2QsIG5hLnJtID0gVFJVRSkjIHJldHVybnMgdGhlIGRlbnNpdHkgZGF0YQpza2V3bmVzcyhOb25fU1NWX0Jsb29kLCBuYS5ybSA9IFRSVUUpICNTa2V3bmVzcwpwbG90KGRfTm9uX1NTVl9ibG9vZCwgbWFpbiA9ICJEZW5zaXR5IHBsb3QgTm9uLVNTViBCbG9vZCBWb2x1bWUgKG1scykiLCBzdWIgPSAiU2tld25lc3MgPSAwLjcyOSIpICMgcGxvdHMgdGhlIHJlc3VsdHMKCgpgYGAKQ1NGIGRpc3RyaWJ1dGlvbnMgdG8gY2hlY2sgZm9yIHNrZXduZXNzIAoKYGBge3J9CgojQ1NGIHZhcmlhYmxlczogU0VCRVMsIFZlbnRyaWN1bGFyIHZvbHVtZSwgU1NWIHZvbHVtZSwgQmVsb3cgU1NWIFZvbHVtZQoKU0VCRVMgPC0gU0FIX2ltYWdpbmdfZGF0YWJhc2UkU0VCRVMKVmVudHJpY2xlX0NTRiA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZSRgVmVudHJpY3VsYXIgdm9sdW1lYApTU1ZfQ1NGIDwtIFNBSF9pbWFnaW5nX2RhdGFiYXNlJGBTU1YgVm9sdW1lYApCZWxvd19TU1ZfQ1NGIDwtIFNBSF9pbWFnaW5nX2RhdGFiYXNlJGBCZWxvdyBTU1YgVm9sdW1lYApUb3RhbF9DU0YgPC0gU0FIX2ltYWdpbmdfZGF0YWJhc2UkYFRvdGFsIG1hbnVhbCB2b2x1bWVgCgpoaXN0KFNFQkVTKQpoaXN0KFZlbnRyaWNsZV9DU0YpCmhpc3QoU1NWX0NTRikKaGlzdChCZWxvd19TU1ZfQ1NGKQpoaXN0KFRvdGFsX0NTRikKCmxpYnJhcnkobW9tZW50cykKZF9TRUJFUyA8LSBkZW5zaXR5KFNFQkVTKSMgcmV0dXJucyB0aGUgZGVuc2l0eSBkYXRhCnNrZXduZXNzKFNFQkVTLCBuYS5ybSA9IFRSVUUpICNTa2V3bmVzcwpwbG90KGRfU0VCRVMsIG1haW4gPSAiRGVuc2l0eSBwbG90IFNFQkVTIiwgc3ViID0gIlNrZXduZXNzID0gMS41NDIiKSAjIHBsb3RzIHRoZSByZXN1bHRzCgpkX1ZlbnRyaWNsZV9DU0YgPC0gZGVuc2l0eShWZW50cmljbGVfQ1NGLCBuYS5ybSA9IFRSVUUpIyByZXR1cm5zIHRoZSBkZW5zaXR5IGRhdGEKc2tld25lc3MoVmVudHJpY2xlX0NTRiwgbmEucm0gPSBUUlVFKSAjU2tld25lc3MKcGxvdChkX1ZlbnRyaWNsZV9DU0YsIG1haW4gPSAiRGVuc2l0eSBwbG90IFZlbnRyaWNsZSBDU0YgVm9sdW1lIChtbHMpIiwgc3ViID0gIlNrZXduZXNzID0gMS41OSIpICMgcGxvdHMgdGhlIHJlc3VsdHMKCmRfU1NWX0NTRiA8LSBkZW5zaXR5KFNTVl9DU0YsIG5hLnJtID0gVFJVRSkjIHJldHVybnMgdGhlIGRlbnNpdHkgZGF0YQpza2V3bmVzcyhTU1ZfQ1NGLCBuYS5ybSA9IFRSVUUpICNTa2V3bmVzcwpwbG90KGRfU1NWX0NTRiwgbWFpbiA9ICJEZW5zaXR5IHBsb3QgU1NWIENTRiBWb2x1bWUgKG1scykiLCBzdWIgPSAiU2tld25lc3MgPSAxLjQzIikgIyBwbG90cyB0aGUgcmVzdWx0cwoKZF9CZWxvd19TU1ZfQ1NGIDwtIGRlbnNpdHkoQmVsb3dfU1NWX0NTRiwgbmEucm0gPSBUUlVFKSMgcmV0dXJucyB0aGUgZGVuc2l0eSBkYXRhCnNrZXduZXNzKEJlbG93X1NTVl9DU0YsIG5hLnJtID0gVFJVRSkgI1NrZXduZXNzCnBsb3QoZF9CZWxvd19TU1ZfQ1NGLCBtYWluID0gIkRlbnNpdHkgcGxvdCBCZWxvdyBTU1YgQ1NGIFZvbHVtZSAobWxzKSIsIHN1YiA9ICJTa2V3bmVzcyA9IDAuODI5IikgIyBwbG90cyB0aGUgcmVzdWx0cwoKZF9Ub3RhbF9DU0YgPC0gZGVuc2l0eShUb3RhbF9DU0YsIG5hLnJtID0gVFJVRSkjIHJldHVybnMgdGhlIGRlbnNpdHkgZGF0YQpza2V3bmVzcyhUb3RhbF9DU0YsIG5hLnJtID0gVFJVRSkgI1NrZXduZXNzCnBsb3QoZF9Ub3RhbF9DU0YsIG1haW4gPSAiRGVuc2l0eSBwbG90IFRvdGFsIENTRiBWb2x1bWUgKG1scykiLCBzdWIgPSAiU2tld25lc3MgPSAwLjkiKSAjIHBsb3RzIHRoZSByZXN1bHRzCgpgYGAKCkRlY2lzaW9uIG1hZGUgbm90IHRvIHRyYW5zZm9ybSB0aGUgdmFyaWFibGVzIGJlY2F1c2UgdGhleSBhcmUgZ2VuZXJhbGx5IG5vcm1hbGx5IGRpc3RyaWJ1dGVkLCB3aXRoIHRoZSBleGNlcHRpb24gb2YgU1NWIGJsb29kIHdoaWNoIGlzIG5vdCBhIGNsaW5pY2FsbHkgaW1wb3J0YW50IHZhcmlhYmxlIGFueXdheS4gCgpUaGUgbmV4dCBzdGVwIGlzIHRvIGlkZW50aWZ5IHRocm91Z2ggY29ycmVsYXRpb24gbWF0cmljZXMsIGhvdyB0aGUgaW1hZ2luZyB2YXJpYWJsZXMgYXJlIHJlbGF0ZWQuLiAKCmBgYHtyfQoKI0ZvciB2aXN1YWxpc2F0aW9uIGVuc3VyZSB0aGF0IHRoZSB2YXJpYWJsZXMgaGF2ZSB0aGUgY29ycmVjdCBuYW1lcyAKClNBSF9pbWFnaW5nX2RhdGFiYXNlJEFnZSA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZSRBR0UKU0FIX2ltYWdpbmdfZGF0YWJhc2UkV0ZOUyA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZSRXRk5TR1JETgpTQUhfaW1hZ2luZ19kYXRhYmFzZSRUb3RhbF9DU0YgPC0gU0FIX2ltYWdpbmdfZGF0YWJhc2UkYFRvdGFsIG1hbnVhbCB2b2x1bWVgClNBSF9pbWFnaW5nX2RhdGFiYXNlJFZlbnRyaWN1bGFyX0NTRiA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZSRgVmVudHJpY3VsYXIgdm9sdW1lYApTQUhfaW1hZ2luZ19kYXRhYmFzZSRTU1ZfQ1NGIDwtIFNBSF9pbWFnaW5nX2RhdGFiYXNlJGBTU1YgVm9sdW1lYAoKZGF0YV9pbWFnaW5nX2NvcnJlbGF0aW9uIDwtIFNBSF9pbWFnaW5nX2RhdGFiYXNlWywgYygiQWdlIiwgIldGTlMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRvdGFsIGJsb29kIiwgIlNTVl9DU0YiLCAiVmVudHJpY3VsYXJfQ1NGIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUb3RhbF9DU0YiKV0KCmRhdGFfaW1hZ2luZ19jb3JyZWxhdGlvbiA8LSBuYS5vbWl0KGRhdGFfaW1hZ2luZ19jb3JyZWxhdGlvbikKCnJlbW92ZS5wYWNrYWdlcygnSG1pc2MnKQppbnN0YWxsLnBhY2thZ2VzKCJIbWlzYyIsIHJlcG9zPSJodHRwOi8vY3Jhbi5yc3R1ZGlvLmNvbS8iLCBkZXBlbmRlbmNpZXM9VFJVRSkKaW5zdGFsbC5wYWNrYWdlcygiY2hlY2ttYXRlIikKbGlicmFyeShIbWlzYykKCnJlczIgPC0gcmNvcnIoYXMubWF0cml4KGRhdGFfaW1hZ2luZ19jb3JyZWxhdGlvbiksIHR5cGUgPSAic3BlYXJtYW4iKQpyZXMyCgpyZXMyJHIKcmVzMiRQCgpmbGF0dGVuQ29yck1hdHJpeCA8LSBmdW5jdGlvbihjb3JtYXQsIHBtYXQpIHsgI2Zvcm1hdCBjb3JyZWxhdGlvbiBtYXRyaXggCiAgdXQgPC0gdXBwZXIudHJpKGNvcm1hdCkKICBkYXRhLmZyYW1lKAogICAgcm93ID0gcm93bmFtZXMoY29ybWF0KVtyb3coY29ybWF0KVt1dF1dLAogICAgY29sdW1uID0gcm93bmFtZXMoY29ybWF0KVtjb2woY29ybWF0KVt1dF1dLAogICAgY29yICA9KGNvcm1hdClbdXRdLAogICAgcCA9IHBtYXRbdXRdCiAgKQp9Cgpjb3JyZWxhdGlvbl9tYXRyaXggPC0gZmxhdHRlbkNvcnJNYXRyaXgocmVzMiRyLCByZXMyJFApCndyaXRlLmNzdihjb3JyZWxhdGlvbl9tYXRyaXgsICJDb3JyZWxhdGlvbl9tYXRyaXguY3N2Iiwgcm93Lm5hbWVzID0gRikgI2V4cG9ydCB0YWJsZSAKCgpsaWJyYXJ5KGNvcnJwbG90KSAjdmlzdWFsaXNlIHRoZSBjb3JyZWxhdGlvbiBtYXRyaXgKcmVzIDwtIGNvcihkYXRhX2ltYWdpbmdfY29ycmVsYXRpb24pCmNvcnJwbG90KHJlcywgdHlwZSA9ICJ1cHBlciIsIG9yZGVyID0gImhjbHVzdCIsIAogICAgICAgICB0bC5jb2wgPSAiYmxhY2siLCB0bC5zcnQgPSA0NSkKCgpjb3JycGxvdChyZXMyJHIsIHR5cGU9InVwcGVyIiwgb3JkZXI9ImhjbHVzdCIsICNpbnNpZ25pZmljYW50IGNvcnJlbGF0aW9ucyByZW1vdmVkCiAgICAgICAgIHAubWF0ID0gcmVzMiRQLCBzaWcubGV2ZWwgPSAwLjAxLCBpbnNpZyA9ICJibGFuayIpCgpgYGAKClVuaXZhcmlhdGUgYW5hbHlzaXMgb2YgdmFyaWFibGVzIAoKYGBge3J9CiNVbml2YXJpYXRlIGFuYWx5c2lzIGxvZ2lzdGljIHJlZ3Jlc3Npb24gCgpkYXRhX2ltYWdpbmcgPC0gU0FIX2ltYWdpbmdfZGF0YWJhc2UKCiMjbVJTIAoKbVJTNyA8LSBkYXRhX2ltYWdpbmckTVJTN19kaWNoCm1SU2RpcyA8LSBkYXRhX2ltYWdpbmckTVJTRElTX2RpY2gKbVJTMjggPC0gZGF0YV9pbWFnaW5nJE1SUzI4X2RpY2gKbVJTOTAgPC0gZGF0YV9pbWFnaW5nJE1SUzkwX2RpY2gKbVJTMTgwIDwtIGRhdGFfaW1hZ2luZyRNUlMxODBfZGljaAoKbGlicmFyeSh0aWR5dmVyc2UpCm1SUzI4IDwtIGFzLmZhY3RvcihyZWNvZGUobVJTMjgsICIwIj0iR29vZCBvdXRjb21lIiwgIjEiID0gIkJhZCBvdXRjb21lIikpCmNvbnRyYXN0cyhhcy5mYWN0b3IobVJTMjgpKQptUlMyOCA8LSBmYWN0b3IobVJTMjgsIGxldmVscyA9IGMoIkdvb2Qgb3V0Y29tZSIsICJCYWQgb3V0Y29tZSIpKQpjb250cmFzdHMoYXMuZmFjdG9yKG1SUzI4KSkKCgpVbml2YXJpYXRlIDwtIGdsbShtUlMxODAgfiBkYXRhX2ltYWdpbmckVG90YWxfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoVW5pdmFyaWF0ZSkKZXhwKGNiaW5kKGNvZWYoVW5pdmFyaWF0ZSksIGNvbmZpbnQoVW5pdmFyaWF0ZSkpKSAgCgojI0dPU0UgCmRhdGFfaW1hZ2luZyA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZQpkYXRhX2ltYWdpbmcgPC0gZGF0YV9pbWFnaW5nW2NvbXBsZXRlLmNhc2VzKGRhdGFfaW1hZ2luZyRHT1NFMjhfZGljaCksXQpTU1YgPC0gZGF0YV9pbWFnaW5nCmRhdGFfaW1hZ2luZyRTU1ZfZ2NlIDwtIHJlYyhTU1YsIHJlYyA9ICJtaW46MC44NT0xOyAwLjk6bWF4PTAiKSAjU3BsaXQgU1NWIGF0IDAuODUgbWwKU1NWX2djZSA8LSBkYXRhX2ltYWdpbmckU1NWX2djZQpTU1ZfZ2NlIDwtIGFzLmZhY3RvcihyZWNvZGUoU1NWX2djZSwgIjAiPSJObyIsICIxIiA9ICJZZXMiKSkKdGFibGUoU1NWX2djZSkKCkdPU0UyOF9kaWNoIDwtIGRhdGFfaW1hZ2luZyRHT1NFMjhfZGljaApHT1NFOTBfZGljaCA8LSBkYXRhX2ltYWdpbmckR09TRTkwX2RpY2gKR09TRTE4MF9kaWNoIDwtIGRhdGFfaW1hZ2luZyRHT1NFMTgwX2RpY2gKClVuaXZhcmlhdGUgPC0gZ2xtKGRhdGFfaW1hZ2luZyRHT1NFMTgwX2RpY2ggfiBkYXRhX2ltYWdpbmckYFRvdGFsIGJsb29kYCwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoVW5pdmFyaWF0ZSkKCiMjU0FIT1QgCmRhdGFfaW1hZ2luZyA8LSBkYXRhX2ltYWdpbmdbY29tcGxldGUuY2FzZXMoZGF0YV9pbWFnaW5nJFNBSE9UMjhfZGljaCksXQoKU0FIT1QyOF9kaWNoIDwtIGRhdGFfaW1hZ2luZyRTQUhPVDI4X2RpY2gKU0FIT1Q5MF9kaWNoIDwtIGRhdGFfaW1hZ2luZyRTQUhPVDkwX2RpY2gKU0FIT1QxODBfZGljaCA8LSBkYXRhX2ltYWdpbmckU0FIT1QxODBfZGljaAoKVW5pdmFyaWF0ZSA8LSBnbG0oZGF0YV9pbWFnaW5nJFNBSE9UMTgwX2RpY2ggfiBkYXRhX2ltYWdpbmckVG90YWxfQ1NGICwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoVW5pdmFyaWF0ZSkKCmBgYAoKRG9taW5hbmNlIHBsb3RzIAoKVG8gcHJldmVudCBvdmVyZml0dGluZyBvZiBmdXJ0aGVyIHByZWRpY3RpdmUgbW9kZWxzLCBhIGRvbWluYW5jZSBhbmFseXNpcyB3YXMgZG9uZSBieSBhc3Nlc3NpbmcgZWFjaCB2YXJpYWJsZeKAmXMgUjIgd2hlbiBwcmVkaWN0aW5nIG1SUyBhdCBkYXkgMjggYW5kIGRheSAxODAuIFRoZSBtUlMgYXQgZGF5IDI4IGFuZCBkYXkgMTgwIHdlcmUgdXNlZCBiZWNhdXNlIG1SUyBpcyB1c2VkIG1vc3Qgd2lkZWx5IGluIGNsaW5pY2FsIHByYWN0aWNlIHRvIGFzc2VzcyBmdW5jdGlvbmFsIG91dGNvbWUuIERheSAyOCB3YXMgc2VsZWN0ZWQgdG8gcmVmbGVjdCBzaG9ydCB0ZXJtIGFuZCBkYXkgMTgwIGxvbmctdGVybSBvdXRjb21lLiBJbiBhZGRpdGlvbiwgdG8gZGVtb25zdHJhdGUgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBhIGdlbmVyYWwgc2NhbGUgb2YgZnVuY3Rpb25hbCBvdXRjb21lIGZvciBzdHJva2UgYW5kIGEgcGF0aWVudCByZXBvcnRlZCBTQUggc3BlY2lmaWMgc2NhbGUgb2Ygc3ltcHRvbXMgd2UgdW5kZXJ0b29rIGEgZG9taW5hbmNlIGFuYWx5c2lzIG9mIFNBSE9UIG9uIGRheSAxODAuCgpgYGB7cn0KCiNSZWNvZGUgdmFyaWFibGVzCgpBZ2UgPC0gZGF0YV9pbWFnaW5nJEFHRQpIeXBlcnRlbnNpb24gPC0gZGF0YV9pbWFnaW5nJEhUTgpXRk5TIDwtIGRhdGFfaW1hZ2luZyRXRk5TR1JETgpUb3RhbF9ibG9vZF92b2x1bWUgPC0gZGF0YV9pbWFnaW5nJGBUb3RhbCBibG9vZGAKU1NWX0NTRiA8LSBkYXRhX2ltYWdpbmckYFNTViBWb2x1bWVgClZlbnRyaWN1bGFyX0NTRiA8LSBkYXRhX2ltYWdpbmckYFZlbnRyaWN1bGFyIHZvbHVtZWAKCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMyOCkgfiBBZ2UrV0ZOUysKICAgICAgICAgICAgICAgICAgICAgIFRvdGFsX2Jsb29kX3ZvbHVtZStTU1ZfQ1NGK1ZlbnRyaWN1bGFyX0NTRiwgCiAgICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQpjb2VmKE11bHRpdmFyaWF0ZSkKCmFub3ZhKE11bHRpdmFyaWF0ZSwgdGVzdCA9ICJDaGlzcSIpCgpsaWJyYXJ5KHBzY2wpCgpwUjIoTXVsdGl2YXJpYXRlKQoKYXYgPC0gYXZhaWxhYmxlLnBhY2thZ2VzKGZpbHRlcnM9bGlzdCgpKQphdlthdlssICJQYWNrYWdlIl0gPT0gZG9taW5hbmNlYW5hbHlzaXMsIF0KCmluc3RhbGwucGFja2FnZXMoJ2RvbWluYW5jZWFuYWx5c2lzJykKbGlicmFyeShkb21pbmFuY2VhbmFseXNpcykKCmRhLmdsbS5maXQoKSgibmFtZXMiKQoKZGFwcmVzPC1kb21pbmFuY2VBbmFseXNpcyhNdWx0aXZhcmlhdGUpCgpnZXRGaXRzKGRhcHJlcywicjIubSIpCgpkb21pbmFuY2VNYXRyaXgoZGFwcmVzLCB0eXBlPSJjb21wbGV0ZSIsZml0LmZ1bmN0aW9ucyA9ICJyMi5tIiwgb3JkZXJlZD1UUlVFKSAjY29tcGxldGUgZG9taW5hbmNlID0gMSwgY29tcGxldGUgZG9taW5hbmNlIG5vdCBlc3RhYmxpc2hlZCA9IDAuNQoKY29udHJpYnV0aW9uQnlMZXZlbChkYXByZXMsZml0LmZ1bmN0aW9ucz0icjIubSIpCgpsaWJyYXJ5KHJlc2hhcGUyKQoKcGxvdChkYXByZXMsIHdoaWNoLmdyYXBoID0iY29uZGl0aW9uYWwiLGZpdC5mdW5jdGlvbiA9ICJyMi5tIikgI0NvbmRpdGlvbmFsIGRvbWluYW5jZSBwbG90IAoKZG9taW5hbmNlTWF0cml4KGRhcHJlcywgdHlwZT0iY29uZGl0aW9uYWwiLGZpdC5mdW5jdGlvbnMgPSAicjIubSIsIG9yZGVyZWQ9VFJVRSkKCmF2ZXJhZ2VDb250cmlidXRpb24oZGFwcmVzLGZpdC5mdW5jdGlvbnMgPSAicjIubSIpCgpwbG90KGRhcHJlcywgd2hpY2guZ3JhcGggPSJnZW5lcmFsIixmaXQuZnVuY3Rpb24gPSAicjIubSIpICNHZW5lcmFsIGRvbWluYW5jZSBwbG90Cgpib290bW9kcHJlczEwMCA8LSBib290RG9taW5hbmNlQW5hbHlzaXMoTXVsdGl2YXJpYXRlLCBSPTEwMCkgIyBCb290c3RyYXAgYW5hbHlzaXMgZm9yIGRvbWluYW5jZSBhbmFseXNpcyAKc3VtbWFyeShib290bW9kcHJlczEwMCxmaXQuZnVuY3Rpb25zPSJyMi5tIikKCmJvb3RhdmVtb2RwcmVzMTAwPC1ib290QXZlcmFnZURvbWluYW5jZUFuYWx5c2lzKE11bHRpdmFyaWF0ZSxSPTEwMCkgIyBCb290c3RyYXAgYW5hbHlzaXMgZm9yIGdlbmVyYWwgZG9taW5hbmNlIGFuYWx5c2lzIApzdW1tYXJ5KGJvb3RhdmVtb2RwcmVzMTAwLGZpdC5mdW5jdGlvbnM9YygicjIubSIpKQoKYGBgCk11bHRpdmFyaWF0ZSBhbmFseXNpcyAKCkluIG9yZGVyIHRvIGludmVzdGlnYXRlIHRoZSBhZGRpdGlvbmFsIGJlbmVmaXQgb2YgYmxvb2QgYW5kIENTRiB2b2x1bWUgbWVhc3VyZW1lbnRzIGluIG1vZGVscyBvdmVyIGNvbnZlbnRpb25hbCBjbGluaWNhbCBmZWF0dXJlcyBhbG9uZSBtdWx0aXZhcmlhdGUgbW9kZWxzIHdlcmUgYnVpbHQgdXNpbmcgdGhlIHByZXZpb3VzbHkgcmVwb3J0ZWQgU0FISVQgY29yZSB2YXJpYWJsZXMgdG8gcHJlZGljdCBtUlMgYXQgZGF5IDI4IGFuZCAxODAgYW5kIHJlcGVhdGVkIGFkZGluZyB0b3RhbCBibG9vZCB2b2x1bWUsIFNTViBDU0YsIHZlbnRyaWN1bGFyIENTRi4KCkNvcmUgbW9kZWw9IEFnZSwgSHlwZXJ0ZW5zaW9uIGFuZCBBZG1pc3Npb24gV0ZOUyAKTmV1cm9pbWFnaW5nIG1vZGVsPSBDb3JlIG1vZGVsICsgVG90YWwgQmxvb2Qgdm9sdW1lLCBTU1YgQ1NGIGFuZCBWZW50cmljdWxhciBDU0YgCgpGb3IgdW5rbm93biByZWFzb25zIHRoZSBiZWxvdyBjb2RlIGRpZCBub3Qgd29yayBhbmQgdGhlcmVmb3JlLCBJIGNyZWF0ZWQgdGhlIEFVQyBncmFwaHMgYnkgYWRhcHRpbmcgbXkgcHJldmlvdXMgYW5hbHlzZWQgY29kZS4gCgpgYGB7cn0KI0NvcmUgbW9kZWwgCgphZ2UgPC0gZGF0YV9pbWFnaW5nJEFHRSAKSFROIDwtIGRhdGFfaW1hZ2luZyRIVE4KV0ZOUyA8LSBkYXRhX2ltYWdpbmckV0ZOU0dSRE4KCiMjIG1SUwoKCm1SUzI4IDwtIGFzLmZhY3RvcihyZWNvZGUobVJTMjgsICIwIj0iR29vZCBvdXRjb21lIiwgIjEiID0gIkJhZCBvdXRjb21lIikpCmNvbnRyYXN0cyhhcy5mYWN0b3IobVJTMjgpKQptUlMyOCA8LSBmYWN0b3IobVJTMjgsIGxldmVscyA9IGMoIkdvb2Qgb3V0Y29tZSIsICJCYWQgb3V0Y29tZSIpKQpjb250cmFzdHMoYXMuZmFjdG9yKG1SUzI4KSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0obVJTMTgwIH4gYWdlK0hUTitXRk5TLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCmNvZWYoTXVsdGl2YXJpYXRlKQoKIyMjIE1jRmFkZGVuJ3MgUHNldWRvIFIyIAoKbGwubnVsbCA8LSBNdWx0aXZhcmlhdGUkbnVsbC5kZXZpYW5jZS8tMgpsbC5wcm9wb3NlZCA8LSBNdWx0aXZhcmlhdGUkZGV2aWFuY2UvLTIKKGxsLm51bGwgLSBsbC5wcm9wb3NlZCkvbGwubnVsbAoxIC0gcGNoaXNxKDIqKGxsLnByb3Bvc2VkIC0gbGwubnVsbCksIGRmID0gbGVuZ3RoKE11bHRpdmFyaWF0ZSRjb2VmZmljaWVudHMpLTEpCgojIyBBVUMgCgpsaWJyYXJ5KFJPQ1IpCmxpYnJhcnkocFJPQykKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBhZ2UrSFROK1dGTlMsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCnJvYzEgPC0gcm9jKG1SUzE4MCwgTXVsdGl2YXJpYXRlJGZpdHRlZC52YWx1ZXMsIHBsb3QgPSBUUlVFKQpyb2MxCmNpKHJvYzEpCnBhcihwdHkgPSAicyIpCgpyb2MobVJTMjgsIE11bHRpdmFyaWF0ZSRmaXR0ZWQudmFsdWVzLCBwbG90ID0gVFJVRSwgbGVnYWN5LmF4ZXMgPSBUUlVFLCBwZXJjZW50ID0gVFJVRSwKICAgIHhsYWI9ICJGYWxzZSBQb3NpdGl2ZSBQZXJjZW50YWdlIiwgeWxhYiA9ICJUcnVlIFBvc2l0aXZlIFBlcmNlbnRhZ2UiLCBjb2wgPSAiYmxhY2siLCBsd2QgPSAyLCBwcmludC5hdWMgPSA2MCkKbGVnZW5kKCJib3R0b21yaWdodCIsIGxlZ2VuZCA9IGMoIm1SUyBkYXkgMTgwIiksIGNvbCA9IGMoImJsYWNrIiksIGx3ZCA9IDQpCgpjaShyb2MxKQoKIyBOZXVyb2ltYWdpbmcgbW9kZWwgCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKG1SUzE4MCB+IGFnZStIVE4rV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrU1NWX0NTRitWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKY29lZihNdWx0aXZhcmlhdGUpCgojIyMgTWNGYWRkZW4ncyBQc2V1ZG8gUjIgCgpsbC5udWxsIDwtIE11bHRpdmFyaWF0ZSRudWxsLmRldmlhbmNlLy0yCmxsLnByb3Bvc2VkIDwtIE11bHRpdmFyaWF0ZSRkZXZpYW5jZS8tMgoobGwubnVsbCAtIGxsLnByb3Bvc2VkKS9sbC5udWxsCjEgLSBwY2hpc3EoMioobGwucHJvcG9zZWQgLSBsbC5udWxsKSwgZGYgPSBsZW5ndGgoTXVsdGl2YXJpYXRlJGNvZWZmaWNpZW50cyktMSkKCiMjIEFVQyAKCmxpYnJhcnkoUk9DUikKbGlicmFyeShwUk9DKQoKCnBsb3QoeCA9IFdGTlMsIHkgPSBtUlMxODApCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBhZ2UrSFROK1dGTlMsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCnJvYzEgPC0gcm9jKG1SUzE4MCwgTXVsdGl2YXJpYXRlJGZpdHRlZC52YWx1ZXMsIHBsb3QgPSBUUlVFKQpyb2MxCmNpKHJvYzEpCnBhcihwdHkgPSAicyIpCgpyb2MobVJTMTgwLCBNdWx0aXZhcmlhdGUkZml0dGVkLnZhbHVlcywgcGxvdCA9IFRSVUUsIGxlZ2FjeS5heGVzID0gVFJVRSwgcGVyY2VudCA9IFRSVUUsCiAgICB4bGFiPSAiRmFsc2UgUG9zaXRpdmUgUGVyY2VudGFnZSIsIHlsYWIgPSAiVHJ1ZSBQb3NpdGl2ZSBQZXJjZW50YWdlIiwgY29sID0gImJsYWNrIiwgbHdkID0gMiwgcHJpbnQuYXVjID0gNjApCmxlZ2VuZCgiYm90dG9tcmlnaHQiLCBsZWdlbmQgPSBjKCJtUlMgZGF5IDE4MCIpLCBjb2wgPSBjKCJibGFjayIpLCBsd2QgPSA0KQoKY2kocm9jMSkKCiMgT3ZlcmxhcCBBVUMgCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMyOCkgfiBhZ2UrSFROK1dGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1NTVl9DU0YrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpyb2MobVJTMjgsIE11bHRpdmFyaWF0ZSRmaXR0ZWQudmFsdWVzLCBwbG90ID0gVFJVRSwgbGVnYWN5LmF4ZXMgPSBUUlVFLCBwZXJjZW50ID0gVFJVRSwKICAgIHhsYWI9ICJGYWxzZSBQb3NpdGl2ZSBQZXJjZW50YWdlIiwgeWxhYiA9ICJUcnVlIFBvc2l0aXZlIFBlcmNlbnRhZ2UiLCBjb2wgPSAiYmxhY2siLCBsd2QgPSAyLCBwcmludC5hdWMgPSA2MCkKcGFyKHB0eSA9ICJzIikKTXVsdGl2YXJpYXRlMiA8LSBnbG0oYXMuZmFjdG9yKG1SUzI4KSB+IGFnZStIVE4rV0ZOUywgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCk11bHRpdmFyaWF0ZTMgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gYWdlK0hUTitXRk5TLCBUb3RhbF9ibG9vZF92b2x1bWUrU1NWX0NTRitWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpNdWx0aXZhcmlhdGU0IDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IGFnZStIVE4rV0ZOUywgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCgpyb2MobVJTMjgsIE11bHRpdmFyaWF0ZSRmaXR0ZWQudmFsdWVzLCBwbG90ID0gVFJVRSwgbGVnYWN5LmF4ZXMgPSBUUlVFLCBwZXJjZW50ID0gVFJVRSwKICAgIHhsYWI9ICJGYWxzZSBQb3NpdGl2ZSBQZXJjZW50YWdlIiwgeWxhYiA9ICJUcnVlIFBvc2l0aXZlIFBlcmNlbnRhZ2UiLCBjb2wgPSAib3JhbmdlIiwgbHdkID0gMSwgcHJpbnQuYXVjID0gVFJVRSwgcHJpbnQuYXVjLnkgPSA3MCwgcHJpbnQuYXVjLnggPSA0MCkKcGxvdC5yb2MobVJTMjgsIE11bHRpdmFyaWF0ZTIkZml0dGVkLnZhbHVlcywgcGVyY2VudCA9IFRSVUUsIGNvbCA9ICJyZWQiLCBsd2QgPSAxLCBhZGQgPSBUUlVFLCBwcmludC5hdWMgPSBUUlVFLCBwcmludC5hdWMueSA9IDkwLCBwcmludC5hdWMueCA9IDQwKQpwbG90LnJvYyhtUlMxODAsIE11bHRpdmFyaWF0ZTMkZml0dGVkLnZhbHVlcywgcGVyY2VudCA9IFRSVUUsIGNvbCA9ICJibHVlIiwgbHdkID0gMSwgYWRkID0gVFJVRSwgcHJpbnQuYXVjID0gVFJVRSwgcHJpbnQuYXVjLnkgPSA2MCwgcHJpbnQuYXVjLnggPSA0MCkKcGxvdC5yb2MobVJTMTgwLCBNdWx0aXZhcmlhdGU0JGZpdHRlZC52YWx1ZXMsIHBlcmNlbnQgPSBUUlVFLCBjb2wgPSAiYmxhY2siLCBsd2QgPSAxLCBhZGQgPSBUUlVFLCBwcmludC5hdWMgPSBUUlVFLCBwcmludC5hdWMueSA9IDgwLCBwcmludC5hdWMueCA9IDQwKQoKbGVnZW5kKCJib3R0b21yaWdodCIsIHRpdGxlID0gIm1vZGlmaWVkIFJhbmtpbiBTY2FsZSIsIAogICAgICAgbGVnZW5kID0gYygiTmV1cm9pbWFnaW5nIERheSAyOCIsICJOZXVyb2ltYWdpbmcgRGF5IDE4MCIsICJDbGluaWNhbCBEYXkgMjgiLCAiQ2xpbmljYWwgRGF5IDE4MCIpLCBjb2wgPSBjKCJyZWQiLCAiYmxhY2siLCAib3JhbmdlIiwgImJsdWUiKSwgCiAgICAgICBsd2QgPSAyLCAiTGVnZW5kIiwgY2V4PTAuOCkKYGBgCgpgYGB7cn0KIyBFeHBsb3JlIHRoZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIGFnZSwgQ1NGIGFuZCBibG9vZCB2b2x1bWUgCmRhdGFfaW1hZ2luZyA8LSBTQUhfaW1hZ2luZ19kYXRhYmFzZQoKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBWZW50cmljdWxhcl9DU0YgKiBUb3RhbF9ibG9vZCAqIGFnZSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQpjb2VmKE11bHRpdmFyaWF0ZSkKCiNQbG90cwoKbGlicmFyeShzalBsb3QpCmxpYnJhcnkoc2ptaXNjKQpsaWJyYXJ5KGdncGxvdDIpCnRoZW1lX3NldCh0aGVtZV9zanBsb3QoKSkKCmludGVyYWN0aW9uX21vZGVsIDwtICBwbG90X21vZGVsKE11bHRpdmFyaWF0ZSwgdHlwZSA9ICJwcmVkIiwgCiAgICAgICAgICAgYXhpcy50aXRsZSA9IGMoIlZlbnRyaWN1bGFyIENTRiBWb2x1bWUgKG1scykiLCAiUHJvYmFiaWxpdHkgb2YgcG9vciBvdXRjb21lICglKSIpLCB0aXRsZSA9ICIiLCB0ZXJtcyA9IGMoIlZlbnRyaWN1bGFyX0NTRiIsICJUb3RhbF9ibG9vZCIsICJhZ2UgWzQwLDYwLDgwXSIpKQoKaW50ZXJhY3Rpb25fbW9kZWwgKyB4bGltKDAsMTAwKQoKIiIsIHRlcm1zID0gYygiVmVudHJpY3VsYXJfQ1NGIiwiVG90YWxfYmxvb2Rfdm9sdW1lIiwiYWdlIFs0MCw2MCw4MF0iKSkgCmBgYApTU1YgZGljaG90b21pc2F0aW9uIGZyb20gdGhlIGxpdGVyYXR1cmUgCgpDaG9pIGV0IGFsLjogU1NWIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZCBhbmQgc3ViamVjdHMgc2VwYXJhdGVkIGludG8gZXF1YWwgcXVhcnRpbGVzIGZvciBtZWFzdXJpbmcgb2RkcyByYXRpb3MgaW4gZXhhbWluaW5nIGFzc29jaWF0aW9ucyB3aXRoIEdDRSBhcyB3ZWxsIGFzIGNsaW5pY2FsIG91dGNvbWVzLiBGSU5ESU5HUzogY29tcGFyZWQgdG8gcGF0aWVudHMgaW4gdGhlIGhpZ2hlc3QgcXVhcnRpbGUgZm9yIFNTViwgdGhlIE9SIGZvciBwb29yIG91dGNvbWUgYXQgZGlzY2hhcmdlIGluY3JlYXNlZCBpbiBhIGRvc2UgZGVwZW5kZW50IG1hbm5lciBpbiB0aGUgbG93ZXIgcXVhcnRpbGVzIGFmdGVyIGFkanVzdGluZyBmb3IgYWdlLCBzZXgsIHNtb2tpbmcgaHlwZXJ0ZW5zaW9uIGFuZCBISCBzY29yZQoKWXVhbiBldCBhbC46IFNTViB0YWtlbiBhcyBjb250aW51b3VzIHZhcmlhYmxlIGFuZCBpbiBzZW5zaXRpdml0eSBhbmFseXNpcyBkaWNob3RvbWlzYXRpb24gYXQgPDUuMm1sIHdhcyBkb25lLiBGSU5ESU5HUyBlYXJseSBTU1YgZGVmaW5lZCBhcyBsb3dlc3QgU1NWIHZvbHVtZSBpbiBmaXJzdCA3MmhycyBidXQgbm90IGFkbWlzc2lvbiBTU1Ygd2FzIHByZWRpY3RpdmUgb2Ygb3V0Y29tZQoKQ3JlYXRlIHR3byBuZXcgdmFyaWFibGVzLCBTU1ZfcXVhbnRpbGVzIGFuZCBTU1ZfZGljaCAKYGBge3J9CiNJZGVudGlmeSB0aGUgcXVhcnRpbGVzIGZvciBTU1YgCgpxdWFudGlsZShTU1ZfQ1NGKQpoaXN0KFNTVl9DU0YpCm1pbihTU1ZfQ1NGKQptYXgoU1NWX0NTRikKCiMgMTw9MjAuMjUwNzgxLCAyPjIwLjI1MDc4MSwgMjw9MzcuMDk4ODQ5LCAzPjM3LjA5ODg0OSwgMzw9NzUuMTI4MzAzLCA0Pjc1LjEyODMwMwoKZGF0YV9pbWFnaW5nJFNTVl9xdWFudGlsZXMgPC0gY3V0KGRhdGFfaW1hZ2luZyRgU1NWIFZvbHVtZWAsCiAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzPWMoMy40ODEwNzMsIDIwLjI1MDc4MSwgMzcuMDk4ODQ5LCA3NS4xMjgzMDMsIDIzNi43Mzg0MjYpLAogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCcxJywgJzInLCAnMycsICc0JykpCgpkYXRhX2ltYWdpbmckU1NWX3F1YW50aWxlcwpTU1ZfcXVhbnRpbGVzIDwtIGRhdGFfaW1hZ2luZyRTU1ZfcXVhbnRpbGVzCmNsYXNzKFNTVl9xdWFudGlsZXMpClNTVl9xdWFudGlsZXMgPC0gcmVsZXZlbChTU1ZfcXVhbnRpbGVzLCByZWYgPSAiNCIpClNTVl9xdWFudGlsZXMKCmdncGxvdChkYXRhID0gZGF0YV9pbWFnaW5nLCBtYXBwaW5nID0gYWVzKHggPSBTU1ZfcXVhbnRpbGVzKSkgKwogIGdlb21fYmFyKCkKCiNTcGxpdCBieSBkaWNob3RvbWlzYXRpb24gb2YgNS4ybWwgaW50byBoaWdoIGFuZCBsb3cgCgpkYXRhX2ltYWdpbmckU1NWX2RpY2hbZGF0YV9pbWFnaW5nJGBTU1YgVm9sdW1lYCA8IDUuMl0gPC0gImxvdyIKZGF0YV9pbWFnaW5nJFNTVl9kaWNoW2RhdGFfaW1hZ2luZyRgU1NWIFZvbHVtZWAgPiA1LjJdIDwtICJoaWdoIgoKZGF0YV9pbWFnaW5nJFNTVl9kaWNoClNTVl9kaWNoIDwtIGRhdGFfaW1hZ2luZyRTU1ZfZGljaAoKI05vdCBhIHN1aXRhYmxlIGN1dC1vZmYgaW4gdGhlIGRhdGFzZXQsIGluc3RlYWQgZGljaG90b21pc2UgYXQgbG93ZXIgcXVhbnRpbGUgCgpkYXRhX2ltYWdpbmckU1NWX2RpY2hbZGF0YV9pbWFnaW5nJGBTU1YgVm9sdW1lYCA8IDIwLjI1MDc4MV0gPC0gImxvdyIKZGF0YV9pbWFnaW5nJFNTVl9kaWNoW2RhdGFfaW1hZ2luZyRgU1NWIFZvbHVtZWAgPiAyMC4yNTA3ODFdIDwtICJoaWdoIgoKZGF0YV9pbWFnaW5nJFNTVl9kaWNoCgoKZ2dwbG90KGRhdGEgPSBkYXRhX2ltYWdpbmcsIG1hcHBpbmcgPSBhZXMoeCA9IFNTVl9kaWNoKSkgKwogIGdlb21fYmFyKCkKCmBgYApDdXJyZW50bHkgaGF2ZSBzZXZlcmFsIENTRiB2b2x1bWVzIGluY2x1ZGluZyAtIHRvdGFsIENTRiwgU1NWIENTRiwgdmVudHJpY3VsYXIgQ1NGIGFuZCBiZWxvdyBTU1YgQ1NGLiBIb3dldmVyLCBvbmUgdm9sdW1lIHRoYXQgaXMgbWlzc2luZywgaXMgYSBub24tU1NWLCBub24tdmVudHJpY3VsYXIgQ1NGLiAKCkNyZWF0ZSBub25fU1NWX25vbl92ZW50X0NTRiB2YXJpYWJsZSAKCmBgYHtyfQoKbXV0YXRlKGRhdGFfaW1hZ2luZywgbm9uX1NTVl9ub25fdmVudCA9IEJlbG93X1NTVl9DU0YgLSBWZW50cmljdWxhcl9DU0YpCgpkYXRhX2ltYWdpbmckbm9uX1NTVl9ub25fdmVudF9DU0YgPC0gQmVsb3dfU1NWX0NTRiAtIFZlbnRyaWN1bGFyX0NTRgoKZGF0YV9pbWFnaW5nJG5vbl9TU1Zfbm9uX3ZlbnRfQ1NGCm5vbl9TU1Zfbm9uX3ZlbnRfQ1NGICA8LSBkYXRhX2ltYWdpbmckbm9uX1NTVl9ub25fdmVudF9DU0YKCm5vbl9TU1Zfbm9uX3ZlbnRfQ1NGICA8LSBub25fU1NWX25vbl92ZW50X0NTRiBbbm9uX1NTVl9ub25fdmVudF9DU0YgID49IDBdCgpoaXN0KG5vbl9TU1Zfbm9uX3ZlbnRfQ1NGKQoKI1VuaXZhcmF0ZSBub24tc3N2IG5vbi12ZW50cmljdWxhciBDU0YKClVuaXZhcmlhdGUgPC0gZ2xtKFNBSE9UMTgwX2RpY2ggfiBub25fU1NWX25vbl92ZW50X0NTRiwgZmFtaWx5ID0gYmlub21pYWwsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCgpgYGAKQmVmb3JlIG11bHRpdmFyaWF0ZSBhbmFseXNpcywgbGV0J3Mgc2VlIGlmIHRoZSBuZXcgU1NWIGN1dC1vZmZzIG1ha2UgaXQgYSBzaWduaWZpY2FudCBwcmVkaWN0b3Igb2YgZGF5IDMwIGFuZCAxODAgb3V0Y29tZSBpbiBhIHVuaXZhcmlhdGUgYW5hbHlzaXMgCgoKYGBge3J9CiNQcmVwYXJlIG91dGNvbWUgdmFyaWFibGVzIAptUlM3IDwtIGRhdGFfaW1hZ2luZyRNUlM3X2RpY2gKbVJTZGlzIDwtIGRhdGFfaW1hZ2luZyRNUlNESVNfZGljaAptUlMyOCA8LSBkYXRhX2ltYWdpbmckTVJTMjhfZGljaAptUlM5MCA8LSBkYXRhX2ltYWdpbmckTVJTOTBfZGljaAptUlMxODAgPC0gZGF0YV9pbWFnaW5nJE1SUzE4MF9kaWNoCgpsaWJyYXJ5KHRpZHl2ZXJzZSkKbVJTNyA8LSBhcy5mYWN0b3IocmVjb2RlKG1SUzcsICIwIj0iR29vZCBvdXRjb21lIiwgIjEiID0gIkJhZCBvdXRjb21lIikpCmNvbnRyYXN0cyhhcy5mYWN0b3IobVJTNykpCm1SUzcgPC0gZmFjdG9yKG1SUzcsIGxldmVscyA9IGMoIkdvb2Qgb3V0Y29tZSIsICJCYWQgb3V0Y29tZSIpKQpjb250cmFzdHMoYXMuZmFjdG9yKG1SUzcpKQoKU0FIT1QyOF9kaWNoIDwtIGRhdGFfaW1hZ2luZyRTQUhPVDI4X2RpY2gKU0FIT1Q5MF9kaWNoIDwtIGRhdGFfaW1hZ2luZyRTQUhPVDkwX2RpY2gKU0FIT1QxODBfZGljaCA8LSBkYXRhX2ltYWdpbmckU0FIT1QxODBfZGljaAoKI1NTVl9xdWFudGlsZSB0aGUgQ2hvaSBldCBhbC4gY3V0LW9mZgoKI0NoYW5nZSB0aGUgbGV2ZWxzIG9mIFNTViBxdWFudGlsZXMKClNTVl9xdWFudGlsZXMKU1NWX3F1YW50aWxlc19tb2QgPC0gZmFjdG9yKFNTVl9xdWFudGlsZXMsIGxldmVscyA9IGMoIjQiLCAiMyIsICIyIiwgIjEiKSkKU1NWX3F1YW50aWxlc19tb2QKClVuaXZhcmlhdGUgPC0gZ2xtKFNBSE9UMTgwX2RpY2ggfiBTU1ZfZGljaCwgZmFtaWx5ID0gYmlub21pYWwsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCmV4cChjYmluZChjb2VmKFVuaXZhcmlhdGUpLCBjb25maW50KFVuaXZhcmlhdGUpKSkgIAo/Z2xtCgpVbml2YXJpYXRlIDwtIGdsbShtUlMxODAgfiBkYXRhX2ltYWdpbmckU1NWX3F1YW50aWxlcywgZmFtaWx5ID0gYmlub21pYWwsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCmV4cChjYmluZChjb2VmKFVuaXZhcmlhdGUpLCBjb25maW50KFVuaXZhcmlhdGUpKSkgIAoKVW5pdmFyaWF0ZSA8LSBnbG0oU0FIT1QyOF9kaWNoIH4gZGF0YV9pbWFnaW5nJFNTVl9xdWFudGlsZXMsIGZhbWlseSA9IGJpbm9taWFsLCAgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShVbml2YXJpYXRlKQpleHAoY2JpbmQoY29lZihVbml2YXJpYXRlKSwgY29uZmludChVbml2YXJpYXRlKSkpICAKClVuaXZhcmlhdGUgPC0gZ2xtKFNBSE9UMTgwX2RpY2ggfiBkYXRhX2ltYWdpbmckU1NWX3F1YW50aWxlcywgZmFtaWx5ID0gYmlub21pYWwsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCmV4cChjYmluZChjb2VmKFVuaXZhcmlhdGUpLCBjb25maW50KFVuaXZhcmlhdGUpKSkgIAoKI1RoZSBhYm92ZSBhbmFseXNpcyByZXBsaWNhdGVzIHNob3dzIHRoYXQgYXQgdGhlIGVhcmxpZXIgdGltZXBvaW50IGxvdyBTU1YgcHJlZGljdHMgcG9vciBvdXRjb21lIHVzaW5nIG1SUyBhbmQgU0FIT1QuIEhvd2V2ZXIsIFNTViBkb2VzIG5vdCByZWFjaCBzaWduaWZpY2FuY2UgYXQgdGhlIDE4MCB0aW1lcG9pbnQuIAoKI1VzZSBkaWNob3RvbWlzYXRpb24gZnJvbSBZdWFuLCBsb3dlc3QgcXVhbnRpbGUgZGVmaW5lZCBhcyAnbG93JyAKClVuaXZhcmlhdGUgPC0gZ2xtKG1SUzI4IH4gZGF0YV9pbWFnaW5nJFNTVl9kaWNoLCBmYW1pbHkgPSBiaW5vbWlhbCwgIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoVW5pdmFyaWF0ZSkKZXhwKGNiaW5kKGNvZWYoVW5pdmFyaWF0ZSksIGNvbmZpbnQoVW5pdmFyaWF0ZSkpKSAgCgpVbml2YXJpYXRlIDwtIGdsbShtUlMxODAgfiBkYXRhX2ltYWdpbmckU1NWX2RpY2gsIGZhbWlseSA9IGJpbm9taWFsLCAgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShVbml2YXJpYXRlKQpleHAoY2JpbmQoY29lZihVbml2YXJpYXRlKSwgY29uZmludChVbml2YXJpYXRlKSkpICAKClVuaXZhcmlhdGUgPC0gZ2xtKFNBSE9UMjhfZGljaCB+IGRhdGFfaW1hZ2luZyRTU1ZfZGljaCwgZmFtaWx5ID0gYmlub21pYWwsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCmV4cChjYmluZChjb2VmKFVuaXZhcmlhdGUpLCBjb25maW50KFVuaXZhcmlhdGUpKSkgIAoKVW5pdmFyaWF0ZSA8LSBnbG0oU0FIT1QxODBfZGljaCB+IGRhdGFfaW1hZ2luZyRTU1ZfZGljaCwgZmFtaWx5ID0gYmlub21pYWwsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCmV4cChjYmluZChjb2VmKFVuaXZhcmlhdGUpLCBjb25maW50KFVuaXZhcmlhdGUpKSkKCiNUaGUgZWFybHkgbVJTIG91dGNvbWUgaXMgdGhlIG9ubHkgdGltZXBvaW50IGluIHdoaWNoIHRoZSAnbG93JyBTU1YgbGVhZHMgdG8gd29ya3Mgb3V0Y29tZS4gCgpgYGAKUmVwZWF0IHJlZ3Jlc3Npb25zOgoKQmVmb3JlIHdlIG1ha2UgdGhhdCBtYWpvciByZXN0cnVjdHVyZSB3ZSB3YW50ZWQgdG8gc2VlIHRoZSBvdXRjb21lcyBvZiB0aGUgcmVncmVzc2lvbnMgZm9yIAoKMSkgV0ZOUywgVEJWIGFuZCBTU1YgdG8gcHJlZGljdCBvdXRjb21lIChNUlMgYW5kIFNBSE9UIGF0IGRheSAzMCBhbmQgMTgwKQoyKSBXRk5TLCBUQlYgYW5kIHZlbnRyaWN1bGFyIHZvbHVtZSB0byBwcmVkaWN0IG91dGNvbWUKCklmIHRoZSBsYXR0ZXIgZG9lcyBub3QgZ2l2ZSBhIGNsZWFyIHJlc3VsdCB0aGVuIHdlIHdhbnRlZCB0byB0cnkgaXQgYWdhaW4gYnV0OgoKYSkgYWRkIHByZXNlbmNlIG9mIGFuIEVWRCBhcyBhIGNvdmFyaWF0ZSBhbmQgYW4gaW50ZXJhY3Rpb24gYmV0d2VlbiB2ZW50cmljdWxhciB2b2x1bWUgYW5kIGFuIEVWRApiKSBhZGQgYW4gaW50ZXJhY3Rpb24gYmV0d2VlbiBUQlYgYW5kIHZlbnRyaWN1bGFyIHZvbHVtZQpgYGB7cn0KCiMgUmVncmVzc2lvbiAxOiBXRk5TLCBUQlYgYW5kIFNTViByZWdyZXNzaW9uCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMyOCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStTU1ZfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrU1NWX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IoU0FIT1QyOF9kaWNoKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1NTVl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMTgwX2RpY2gpIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrU1NWX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKIyBGb3IgbVJTLCBXRk5TIGlzIGEgc2lnbmlmaWNhbnQgcHJlZGljdG9yLCBmb3IgU0FIT1QsIFRCViBpcyBzaWduaWZpY2FudC4gU3Vic3RpdHV0ZSBpbiBuZXcgU1NWIHZhcmlhYmxlcyB0byBzZWUgaWYgdGhpcyBtYWtlcyBhIGRpZmZlcmVuY2UuIAoKI1NTVl9xdWFudGlsZSBmaXJzdAoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMjgpIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrU1NWX3F1YW50aWxlcywgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1NTVl9xdWFudGlsZXMsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMjhfZGljaCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStTU1ZfcXVhbnRpbGVzLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihTQUhPVDE4MF9kaWNoKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1NTVl9xdWFudGlsZXMsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCiNNYWtlcyBubyBkaWZmZXJlbmNlLiBIb3cgYWJvdXQgU1NWX2RpY2gKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzI4KSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1NTVl9kaWNoLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrU1NWX2RpY2gsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMjhfZGljaCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStTU1ZfZGljaCwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IoU0FIT1QxODBfZGljaCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStTU1ZfZGljaCwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKI0FnYWluIG5vIGRpZmZlcmVuY2UgbWFkZS4gCgojIFJlZ3Jlc3Npb24gMjogV0ZOUywgVEJWIGFuZCB2ZW50cmljdWxhciB2b2x1bWUgdG8gcHJlZGljdCBvdXRjb21lCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMyOCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMjhfZGljaCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMTgwX2RpY2gpIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojIFZlbnRyaWN1bGFyIENTRiBzaWduaWZpY2FudCBhdCAzMCBkYXkgbVJTIGFuZCBhbG1vc3Qgc2lnbmlmaWNhbnQgZm9yIG1SUyAxODAuIEhvd2V2ZXIsIG5vdCBzaWduaWZpY2FudCBmb3IgU0FIT1QuIAoKYGBgClRoZSBhYm92ZSByZWdyZXNzaW9ucyBkZW1vbnN0cmF0ZSBzZXZlcmFsIG9ic2VydmF0aW9ucyB3aXRoIHRoZSBkYXRhc2V0OgoKKDEpIFdGTlMgaXMgYSBoaWdobHkgc2lnbmlmaWNhbnQgcHJlZGljdG9yIG9mIGZ1bmN0aW9uYWwgb3V0Y29tZSBhdCAzMCBkYXlzIGFuZCAxODAgZGF5cyAKKDIpIFdoZW4gdXNpbmcgYSBtb3JlIHNwZWNpZmljIG91dGNvbWUgdG9vbCBmb3IgU0FIIChTQUhPVCksIFRCViBpcyBzaG93biB0byBiZSBhIGhpZ2hseSBzaWduaWZpY2FudCBwcmVkaWN0b3IgCigzKSBVbml2YXJpYXRlIGFuYWx5c2lzIG9mIFNTViB1c2luZyBjdXQgb2Zmcywgd2hpY2ggaXNvbGF0ZSBjYXNlcyB3aXRoICdsb3cnIFNTViwgbWFrZXMgaXQgYSBzaWduaWZpY2FudCB2YXJpYWJsZSBhdCBlYXJseSB0aW1lcG9pbnRzCig0KSBNdWx0aXZhcmlhdGUgYW5hbHlzZSBzaG93cyB0aGF0IFNTViBpcyBub3QgYW4gaW5kZXBlbmRlbnQgcHJlZGljdG9yIG9mIG91dGNvbWUgd2hlbiBUQlYgYW5kIFdGTlMgYXJlIGluY2x1ZGVkLiBIb3dldmVyLCBWZW50cmljdWxhciB2b2x1bWUgaXMgYW4gaW5kZXBlbmRlbnQgcHJlZGljdG9yIG9mIG91dGNvbWUgdXNpbmcgbVJTIAoKSSB0aGluayB0aGUgYWJvdmUgZ2l2ZXMgYSBjbGVhciByZXN1bHQuIEZpcnN0bHksIGl0IHNob3dzIHRoYXQgd2UgaGF2ZSBiZWVuIGFibGUgdG8gcmVwbGljYXRlIHByZXZpb3VzIGZpbmRpbmdzIGluIHRoZSBsaXRlcmF0dXJlLCB0aGF0IGF0IGVhcmx5IHRpbWVwb2ludHMgU1NWIHByZWRpY3RzIG91dGNvbWUuIEhvd2V2ZXIsIHdlIGhhdmUgc2hvd24gdGhhdCB0aGlzIGFmZmVjdCBpcyBub3QgbWFpbnRhaW5lZCBhdCBsYXRlciB0aW1lcG9pbnRzIG9yIHdoZW4gY29tYmluZWQgd2l0aCBvdGhlciBzaWduaWZpY2FudCBwcmVkaWN0b3JzIG9mIG91dGNvbWUuIEluc3RlYWQsIGltYWdpbmcgcHJlZGljdG9ycyBvZiBUQlYsIGFuZCB0byBhIGxlc3NlciBleHRlbnQgdmVudHJpY3VsYXIgQ1NGIGFyZSBtb3JlIGltcG9ydGFudC4gCgpUaGUgbmFycmF0aXZlIG9mIHRoZSBwYXBlciBpcyBjbGVhcmVyIHRvIG1lIG5vdyBhbmQgSSB0aGluayBzaG91bGQgYmUgcHJlc2VudGVkIHNvbWV0aGluZyBsaWtlIHRoaXM6IAoKKDEpIEJhc2ljIGRlbW9ncmFwaGljcyAKKDIpIFJlZ3Jlc3Npb24gMSBhbmQgUmVncmVzc2lvbiAyIGZyb20gYWJvdmUgCigzKSBJbnRlcmFjdGlvbiBwbG90cyAKKDQpIEluY2x1c2lvbiBvZiAnb3RoZXInIGltYWdpbmcgdmFyaWFibGVzIHRvIHNob3cgdGhleSBhcmUgbGVzcyByZWxldmFudCAKCkZvciBjb21wbGV0ZW5lc3MsIGJlbG93IEkgd2lsbCBpbmNsdWRlOiAKCmEpIGFkZCBwcmVzZW5jZSBvZiBhbiBFVkQgYXMgYSBjb3ZhcmlhdGUgYW5kIGFuIGludGVyYWN0aW9uIGJldHdlZW4gdmVudHJpY3VsYXIgdm9sdW1lIGFuZCBhbiBFVkQKYikgYWRkIGFuIGludGVyYWN0aW9uIGJldHdlZW4gVEJWIGFuZCB2ZW50cmljdWxhciB2b2x1bWUKCmBgYHtyfQojIGFkZCBwcmVzZW5jZSBvZiBhbiBFVkQgYXMgYSBjb3ZhcmlhdGUgYW5kIGFuIGludGVyYWN0aW9uIGJldHdlZW4gdmVudHJpY3VsYXIgdm9sdW1lIGFuZCBhbiBFVkQKCmNvbG5hbWVzKGRhdGFfaW1hZ2luZykKRVZEIDwtIGRhdGFfaW1hZ2luZyRFVkRGTApFVkQKZ2dwbG90KGRhdGEgPSBkYXRhX2ltYWdpbmcsIG1hcHBpbmcgPSBhZXMoeCA9IEVWRCkpKwogIGdlb21fYmFyKCkKCiNJbmNsdWRlIEVWRCBhcyBjb3ZhcmlhdGUgCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMyOCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YrRVZELCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGK0VWRCwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IoU0FIT1QyOF9kaWNoKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1ZlbnRyaWN1bGFyX0NTRitFVkQsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMTgwX2RpY2gpIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGK0VWRCwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKI0VWRCBpbnNlcnRpb24gaXMgaGlnaGx5IHNpZ25pZmljYW50IG9mIGVhcmx5IG91dGNvbWUgdXNpbmcgbVJTIGFuZCBzbGlnaHRseSByZWR1Y2VzIHRoZSBzaWduaWZpY2FuY2Ugb2YgdmVudHJpY3VsYXIgdm9sdW1lcyAKCiNJbmNsdWRlIEVWRCBhcyBpbnRlcmFjdGlvbiBmb3IgVmVudHJpY3VsYXIgQ1NGIHZvbHVtZSAKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzI4KSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1ZlbnRyaWN1bGFyX0NTRipFVkQsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YqRVZELCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihTQUhPVDI4X2RpY2gpIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGKkVWRCwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IoU0FIT1QxODBfZGljaCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YqRVZELCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojV2hlbiBFVkQgaXMgYWRkZWQgYXMgYW4gaW50ZXJhY3Rpb24gdGVybSBmb3IgdmVudHJpY3VsYXIgdm9sdW1lLCB0aGVyZSBpcyBpbmNyZWFzZWQgc2lnbmlmaWNhbmNlIG9mIHRoZSB2YXJpYWJsZXMgYXQgMTgwIG1SUy4gCgojIGFkZCBhbiBpbnRlcmFjdGlvbiBiZXR3ZWVuIFRCViBhbmQgdmVudHJpY3VsYXIgdm9sdW1lCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMyOCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZSpWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZSpWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMjhfZGljaCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZSpWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKFNBSE9UMTgwX2RpY2gpIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUqVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCmBgYApBbm90aGVyIHRoaW5nIHdlIHNob3VsZCBjaGVjayBpcyB3aGV0aGVyIHRoZSBtb2RlbCBmaXQgaXMgYmV0dGVyIGlmIHdlIHVzZSBqdXN0OgotV0ZOUyBhbmQgYmxvb2Qgdm9sCi1XRk5TIGFuZCBDU0Ygdm9sCi1CbG9vZCBhbmQgQ1NGIHZvbAoKYGBge3J9CgoKI011bHRpdmFyYXRlIAoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1NTVl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCiNXRk5TLCBTU1YgYW5kIFRCVgojQUlDID0gODIuMwoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1RvdGFsX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCiMjQUlDOiA3OC45OTEKI1dGTlMsIGJsb29kIHZvbHVtZSAgdmVudHJpY3VsYXIgdm9sdW1lIHNpZ25pZmljYW50CgojV0ZOUyBhbmQgYmxvb2Qgdm9sdW1lIAoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojI0FJQzogODAuNTg2CiNXRk5TIHNpZ25pZmljYW50IGJsb29kIHZvbHVtZSBpc24ndAoKI1dGTlMgYW5kIHZlbnRyaWN1bGFyIHZvbHVtZQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojI0FJQzogODAuMDk5CiNXRk5TIHNpZ25pZmljYW50LCB2ZW50cmljdWxhciB2b2x1bWUgaXMgYWxtb3N0IHNpZ25pZmljYW50CgojV0ZOUyBhbmQgdG90YWwgQ1NGIHZvbHVtZQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojI0FJQzogODEuMzY5CiNXRk5TIHNpZ25pZmljYW50LCB2ZW50cmljdWxhciB2b2x1bWUgaXMgYWxtb3N0IHNpZ25pZmljYW50CgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gV0ZOUytTU1ZfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojI0FJQzogODEuNjY2CiNXRk5TIHNpZ25pZmljYW50LCB2ZW50cmljdWxhciB2b2x1bWUgaXMgYWxtb3N0IHNpZ25pZmljYW50CgoKI0Jsb29kIGFuZCB2ZW50cmljdWxhciB2b2x1bWUgCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gVG90YWxfYmxvb2Rfdm9sdW1lK1ZlbnRyaWN1bGFyX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKIyNBSUM6IDExMi4xNgojVG90YWwgYmxvb2QgdmVyeSBzaWduaWZpY2FudCBhbmQgdmVudHJpY3VsYXIgdm9sdW1lIHNpZ25pZmljYW50IAoKI1ZlbnRyaWN1bGFyIHZvbHVtZSBvbmx5IAoKVW5pdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCiNWZW50cmljdWxhciB2b2x1bWUgaXMgbm90IHNpZ25pZmljYW50IG9uIGl0cyBvd24KCiNXRk5TIG9ubHkgCgpVbml2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCgojI0FJQzogOTUuNTk0CiNXRk5TIGlzIGhpZ2hseSBzaWduaWZpY2FudCAKCiNUQlYgb25seSAKClVuaXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gVG90YWxfYmxvb2Rfdm9sdW1lLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShVbml2YXJpYXRlKQoKIyNBSUM6IDg0LjgyCiNUQlYgaXMgaGlnaGx5IHNpZ25pZmljYW50CgojV0ZOUywgYWdlIGFuZCBIVE4gCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gV0ZOUysgYWdlK0hUTiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFRvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCiNWZW50cmljdWxhciB2b2x1bWUgdnMgb3V0Y29tZSAKCmdncGxvdChkYXRhID0gZGF0YV9pbWFnaW5nLCBtYXBwaW5nID0gYWVzKHggPSBUb3RhbF9ibG9vZF92b2x1bWUsIHkgPSBkYXRhX2ltYWdpbmckTVJTMTgwKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKCkKCmdncGxvdChkYXRhID0gZGF0YV9pbWFnaW5nLCBtYXBwaW5nID0gYWVzKHggPSBWZW50cmljdWxhcl9DU0YsIHkgPSBkYXRhX2ltYWdpbmckTVJTMTgwKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKCkKCmdncGxvdChkYXRhID0gZGF0YV9pbWFnaW5nLCBtYXBwaW5nID0gYWVzKHggPSBkYXRhX2ltYWdpbmckYEJlbG93IFNTViBWb2x1bWVgLCB5ID0gZGF0YV9pbWFnaW5nJE1SUzE4MCkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aCgpCgpgYGAKU0FIT1QgYXMgbGluZWFyIHRvIHNlZSBpZiB0aGlzIGNoYW5nZXMgc2lnbmlmaWNhbmNlIG9mIHZhcmlhYmxlcy4gClNBSE9UIGlzIGEgOSBwYXJ0IHNjYWxlIDEgKEJlc3Qgb3V0Y29tZSksIDkgKGRlYXRoKS4KClJlcGVhdCByZWdyZXNzaW9ucyBVbml2YXJpYXRlIFNTViBhbmFseXNlczogCgpgYGB7cn0Kc2Fob3QyOCA8LSBkYXRhX2ltYWdpbmckU0FIT1QyOExPQ0YKc2Fob3Q5MCA8LSBkYXRhX2ltYWdpbmckU0FIT1Q5MExPQ0YKc2Fob3QxODAgPC0gZGF0YV9pbWFnaW5nJFNBSE9UMTgwTE9DRgoKc2Fob3QyOCAjMk5BcwpzYWhvdDkwICMyTkFzCnNhaG90MTgwICMyTkFzCgpzdHIoc2Fob3QyOCkKc3RyKHNhaG90MTgwKQoKI1Zpc3VhbGlzZSB0aGUgc3ByZWFkIG9mIFNBSE9UIAoKZ2dwbG90KGRhdGEgPSBkYXRhX2ltYWdpbmcsIG1hcHBpbmcgPSBhZXMoeCA9IHNhaG90MjgpKSsKICBnZW9tX2JhcigpCgpnZ3Bsb3QoZGF0YSA9IGRhdGFfaW1hZ2luZywgbWFwcGluZyA9IGFlcyh4ID0gc2Fob3QyOCwgeSA9IFdGTlMpKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgoKSsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMjUpCgpnZ3Bsb3QoZGF0YSA9IGRhdGFfaW1hZ2luZywgbWFwcGluZyA9IGFlcyh4ID0gc2Fob3QxODApKSsKICBnZW9tX2JhcigpCgpnZ3Bsb3QoZGF0YSA9IGRhdGFfaW1hZ2luZywgbWFwcGluZyA9IGFlcyh4ID0gc2Fob3QxODAsIHkgPSBXRk5TKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKCkrCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjI1KQoKI1NTVl9xdWFudGlsZSB0aGUgQ2hvaSBldCBhbC4gY3V0LW9mZgojIDE8PTIwLjI1MDc4MSwgMj4yMC4yNTA3ODEsIDI8PTM3LjA5ODg0OSwgMz4zNy4wOTg4NDksIDM8PTc1LjEyODMwMywgND43NS4xMjgzMDMgKHVuaXRzID0gbWxzKQoKVW5pdmFyaWF0ZSA8LSBsbShzYWhvdDI4IH4gZGF0YV9pbWFnaW5nJFNTVl9xdWFudGlsZXMsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCmV4cChjYmluZChjb2VmKFVuaXZhcmlhdGUpLCBjb25maW50KFVuaXZhcmlhdGUpKSkgIAoKVW5pdmFyaWF0ZSA8LSBsbShzYWhvdDE4MCB+IGRhdGFfaW1hZ2luZyRTU1ZfcXVhbnRpbGVzLCAgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShVbml2YXJpYXRlKQpleHAoY2JpbmQoY29lZihVbml2YXJpYXRlKSwgY29uZmludChVbml2YXJpYXRlKSkpICAKCiNUaGUgYWJvdmUgYW5hbHlzaXMgcmVwbGljYXRlcyBzaG93cyB0aGF0IGF0IHRoZSBlYXJsaWVyIHRpbWVwb2ludCBsb3cgU1NWIHByZWRpY3RzIHBvb3Igb3V0Y29tZSB1c2luZyBtUlMgYW5kIFNBSE9ULiBIb3dldmVyLCBTU1YgZG9lcyBub3QgcmVhY2ggc2lnbmlmaWNhbmNlIGF0IHRoZSAxODAgdGltZXBvaW50LgojVmVyeSBzaW1pbGFyIHJlc3VsdHMgaW4gY29tcGFyaXNvbiB0byB3aGVuIFNBSE9UIHdhcyB0cmVhdGVkIGFzIGEgZGljaG90b21pc2VkIHZhcmlhYmxlIAoKI1VzZSBkaWNob3RvbWlzYXRpb24gZnJvbSBZdWFuLCBsb3dlc3QgcXVhbnRpbGUgZGVmaW5lZCBhcyAnbG93JyAKClVuaXZhcmlhdGUgPC0gbG0oc2Fob3QyOCB+IGRhdGFfaW1hZ2luZyRTU1ZfZGljaCwgIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoVW5pdmFyaWF0ZSkKZXhwKGNiaW5kKGNvZWYoVW5pdmFyaWF0ZSksIGNvbmZpbnQoVW5pdmFyaWF0ZSkpKSAgCgpVbml2YXJpYXRlIDwtIGdsbShzYWhvdDE4MCB+IGRhdGFfaW1hZ2luZyRTU1ZfZGljaCwgIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoVW5pdmFyaWF0ZSkKZXhwKGNiaW5kKGNvZWYoVW5pdmFyaWF0ZSksIGNvbmZpbnQoVW5pdmFyaWF0ZSkpKQoKI0F0IG5laXRoZXIgdGltZXBvaW50IGxvdyBTU1YgaXMgc2lnbmlmaWNhbnQuLiAKCiNVc2UgbGluZWFyIFNBSE9UIGZvciB1bml2YXJhdGUgYW5hbHlzaXMgCgpVbml2YXJpYXRlIDwtIGdsbShzYWhvdDE4MCB+IGRhdGFfaW1hZ2luZyRgVG90YWwgbWFudWFsIHZvbHVtZWAsICBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KFVuaXZhcmlhdGUpCgpgYGAKQXMgU0FIT1QgYXMgYSBsaW5lYXIgOSBwb2ludCBzY2FsZSwKClJlcGVhdCByZWdyZXNzaW9ucyBTQUhPVCBhdCBEMjggYW5kIEQxODA6IAoxKSBXRk5TLCBUQlYgYW5kIFNTViB0byBwcmVkaWN0IG91dGNvbWUgKE1SUyBhbmQgU0FIT1QgYXQgZGF5IDMwIGFuZCAxODApCjIpIFdGTlMsIFRCViBhbmQgdmVudHJpY3VsYXIgdm9sdW1lIHRvIHByZWRpY3Qgb3V0Y29tZQoKYGBge3J9CgojUmVncmVzc2lvbiAxOiAKCk11bHRpdmFyaWF0ZSA8LSBsbShzYWhvdDI4IH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrU1NWX0NTRiwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpNdWx0aXZhcmlhdGUgPC0gbG0oc2Fob3QxODAgfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStTU1ZfQ1NGLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCiNmb3IgU0FIT1QsIFdGTlMgaXMgc2lnLiBEMjggYW5kIFRCViBpcyBzaWduaWZpY2FudCBhdCBsYXRlIHRpbXBvaW50CgojUmVncmVzc2lvbiAyOgoKTXVsdGl2YXJpYXRlIDwtIGxtKHNhaG90MjggfiBXRk5TK1RvdGFsX2Jsb29kX3ZvbHVtZStWZW50cmljdWxhcl9DU0YsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKTXVsdGl2YXJpYXRlIDwtIGxtKHNhaG90MTgwIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpzdW1tYXJ5KE11bHRpdmFyaWF0ZSkKCiNObyBjaGFuZ2Ugc3Vic3RpdHVpdGluZyB2ZW50cmljdWxhciBDU0Ygdm9sdW1lIC0gV0ZOUyBpcyBzaWcuIEQyOCBhbmQgVEJWIGlzIHNpZ25pZmljYW50IGF0IGxhdGUgdGltcG9pbnQKCmBgYApSZWFzb25pbmcgd2h5IGEgdmFyaWFibGUgaW4gYSB1bml2YXJpYXRlIGFuYWx5c2lzIGlzIG5vdCBzaWduaWZpY2FudCBidXQgYmVjb21lcyBzaWduaWZpY2FudCBpbiBhIG11bHRpdmFyaWF0ZSBhbmFseXNpczogCgpUaGUgY2FzZSBvZiB0d28gcHJlZGljdG9ycyB0aGF0IGFyZSB0cnVseSBvcnRob2dvbmFsOiB0aGVyZSBpcyBhYnNvbHV0ZWx5IG5vIGNvbGxpbmVhcml0eSBhbW9uZyB0aGVtLiBBIHJlbWFya2FibGUgY2hhbmdlIGluIHNpZ25pZmljYW5jZSBjYW4gc3RpbGwgaGFwcGVuLgoKRGVzaWduYXRlIHRoZSBwcmVkaWN0b3IgdmFyaWFibGVzIPCdkYsxIGFuZCDwnZGLMiBhbmQgbGV0IPCdkYwgbmFtZSB0aGUgcHJlZGljdG9yLiBUaGUgcmVncmVzc2lvbiBvZiDwnZGMCiBhZ2FpbnN0IPCdkYsxIHdpbGwgZmFpbCB0byBiZSBzaWduaWZpY2FudCB3aGVuIHRoZSB2YXJpYXRpb24gaW4g8J2RjCBhcm91bmQgaXRzIG1lYW4gaXMgbm90IGFwcHJlY2lhYmx5IHJlZHVjZWQgd2hlbiDwnZGLMQogaXMgdXNlZCBhcyB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGUuIFdoZW4gdGhhdCB2YXJpYXRpb24gaXMgc3Ryb25nbHkgYXNzb2NpYXRlZCB3aXRoIGEgc2Vjb25kIHZhcmlhYmxlIPCdkYsyLAogaG93ZXZlciwgdGhlIHNpdHVhdGlvbiBjaGFuZ2VzLiBSZWNhbGwgdGhhdCBtdWx0aXBsZSByZWdyZXNzaW9uIG9mIPCdkYwgYWdhaW5zdCDwnZGLMSBhbmQg8J2RizIgaXMgZXF1aXZhbGVudCB0bwogc2VwYXJhdGVseSByZWdyZXNzIPCdkYwgYW5kIPCdkYsxIGFnYWluc3Qg8J2RizIuCgpSZWdyZXNzIHRoZSDwnZGMIHJlc2lkdWFscyBhZ2FpbnN0IHRoZSDwnZGLMSByZXNpZHVhbHMuCgpUaGUgcmVzaWR1YWxzIGZyb20gdGhlIGZpcnN0IHN0ZXAgaGF2ZSByZW1vdmVkIHRoZSBlZmZlY3Qgb2Yg8J2RizIuIFdoZW4g8J2RizIgaXMgY2xvc2VseSBjb3JyZWxhdGVkIHdpdGgg8J2RjCwgdGhpcyBjYW4gZXhwb3NlIAphIHJlbGF0aXZlbHkgc21hbGwgYW1vdW50IG9mIHZhcmlhdGlvbiB0aGF0IGhhZCBwcmV2aW91c2x5IGJlZW4gbWFza2VkLiBJZiB0aGlzIHZhcmlhdGlvbiBpcyBhc3NvY2lhdGVkIHdpdGgg8J2RizEsIHdlIG9idGFpbiBhIHNpZ25pZmljYW50IHJlc3VsdC4KCkZ1cnRoZXIgaW5mbyBmcm9tOiBodHRwczovL3N0YXRzLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy8yODQ3NC9ob3ctY2FuLWFkZGluZy1hLTJuZC1pdi1tYWtlLXRoZS0xc3QtaXYtc2lnbmlmaWNhbnQKCkluIHRoZSBhbmFseXNlcyBkb25lIFdGTlMgYW5kIHZlbnRyaWN1bGFyIHZvbHVtZSBhcmUgbm90IGNvbGluZWFyLCBidXQgYmxvb2Qgdm9sdW1lIGFuZCB2ZW50cmljdWxhciB2b2x1bWUgYXJlIGNvbGluZWFyIGluIGEgbmVnYXRpdmUgZGlyZWN0aW9uLiAKV0ZOUyBhbmQgdmVudHJpY3VsYXIgdm9sdW1lLCB0aGVyZWZvcmUgcmVwcmVzZW50IHRoZSBhYm92ZSBmaW5kaW5nOiAKCiNWZW50cmljdWxhciB2b2x1bWUgb25seSAKClVuaXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShVbml2YXJpYXRlKQoKI1ZlbnRyaWN1bGFyIHZvbHVtZSBpcyBub3Qgc2lnbmlmaWNhbnQgb24gaXRzIG93bgoKI1dGTlMgYW5kIHZlbnRyaWN1bGFyIHZvbHVtZQoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojI0FJQzogOTQuMjY5CiNXRk5TIHNpZ25pZmljYW50LCB2ZW50cmljdWxhciB2b2x1bWUgaXMgYWxtb3N0IHNpZ25pZmljYW50CgojQmxvb2QgYW5kIHZlbnRyaWN1bGFyIHZvbHVtZSAKCk11bHRpdmFyaWF0ZSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgojI0FJQzogMTEyLjE2CiNUb3RhbCBibG9vZCB2ZXJ5IHNpZ25pZmljYW50IGFuZCB2ZW50cmljdWxhciB2b2x1bWUgc2lnbmlmaWNhbnQgLSBwcm9iYWJseSBkdWUgdG8gY29sbGluYXJpdHkgCgoKU2hhcGxleSBwbG90cyAKCkNvbXBsZXggcHJlZGljdGl2ZSBtb2RlbHMgYXJlIG5vdCBlYXN5IHRvIGludGVycHJldC4gQnkgY29tcGxleCBJIG1lYW46IHJhbmRvbSBmb3Jlc3QsIHhnYm9vc3QsIGRlZXAgbGVhcm5pbmcsIGV0Yy4KClNoYXBsZXkgdmFsdWVzIGNhbGN1bGF0ZSB0aGUgaW1wb3J0YW5jZSBvZiBhIGZlYXR1cmUgYnkgY29tcGFyaW5nIHdoYXQgYSBtb2RlbCBwcmVkaWN0cyB3aXRoIGFuZCB3aXRob3V0IHRoZSBmZWF0dXJlLiBIb3dldmVyLCBzaW5jZSB0aGUgb3JkZXIgaW4gd2hpY2ggYSBtb2RlbCBzZWVzIGZlYXR1cmVzIGNhbiBhZmZlY3QgaXRzIHByZWRpY3Rpb25zLCB0aGlzIGlzIGRvbmUgaW4gZXZlcnkgcG9zc2libGUgb3JkZXIsIHNvIHRoYXQgdGhlIGZlYXR1cmVzIGFyZSBmYWlybHkgY29tcGFyZWQuCgpIb3cgdG8gaW50ZXJwcmV0IHRoZSBzaGFwIHN1bW1hcnkgcGxvdD8KClRoZSB5LWF4aXMgaW5kaWNhdGVzIHRoZSB2YXJpYWJsZSBuYW1lLCBpbiBvcmRlciBvZiBpbXBvcnRhbmNlIGZyb20gdG9wIHRvIGJvdHRvbS4gVGhlIHZhbHVlIG5leHQgdG8gdGhlbSBpcyB0aGUgbWVhbiBTSEFQIHZhbHVlLgpPbiB0aGUgeC1heGlzIGlzIHRoZSBTSEFQIHZhbHVlLiBJbmRpY2F0ZXMgaG93IG11Y2ggaXMgdGhlIGNoYW5nZSBpbiBsb2ctb2Rkcy4gRnJvbSB0aGlzIG51bWJlciB3ZSBjYW4gZXh0cmFjdCB0aGUgcHJvYmFiaWxpdHkgb2Ygc3VjY2Vzcy4KR3JhZGllbnQgY29sb3IgaW5kaWNhdGVzIHRoZSBvcmlnaW5hbCB2YWx1ZSBmb3IgdGhhdCB2YXJpYWJsZS4gSW4gYm9vbGVhbnMsIGl0IHdpbGwgdGFrZSB0d28gY29sb3JzLCBidXQgaW4gbnVtYmVyIGl0IGNhbiBjb250YWluIHRoZSB3aG9sZSBzcGVjdHJ1bS4KRWFjaCBwb2ludCByZXByZXNlbnRzIGEgcm93IGZyb20gdGhlIG9yaWdpbmFsIGRhdGFzZXQuCgpgYGB7cn0KaW5zdGFsbC5wYWNrYWdlcygic2hhcHIiKSAjQ2FsbCBpbiBwYWNrYWdlcwppbnN0YWxsLnBhY2thZ2VzKCJ4Z2Jvb3N0IikKaW5zdGFsbC5wYWNrYWdlcygiU0hBUGZvcnhnYm9vc3QiKQoKbGlicmFyeShzaGFwcikKbGlicmFyeSh4Z2Jvb3N0KQpsaWJyYXJ5KFNIQVBmb3J4Z2Jvb3N0KQoKCj9zaGFwcgoKI0RlZmluZSB0aGUgcmVzcG9uc2UgYW5kIGZlYXR1cmVzIApjb2xuYW1lcyhkYXRhX2ltYWdpbmcpCgojUHJlcGFyZSBkYXRhIAoKZGF0YV9pbWFnaW5nX3N1YnNldCA8LSBkYXRhX2ltYWdpbmdbLCBjKCJBR0UiLCAiV0ZOU0dSRE4iLCAiVG90YWwgYmxvb2QiLCAiU1NWIFZvbHVtZSIsCiAgICAgICAiVmVudHJpY3VsYXIgdm9sdW1lIiwgIlRvdGFsIG1hbnVhbCB2b2x1bWUiLCAiTVJTMTgwX2RpY2giKV0KCnZpZXcoZGF0YV9pbWFnaW5nX3N1YnNldCkKCnkgPC0gIk1SUzE4MF9kaWNoIgp4IDwtIGMoIkFHRSIsICJXRk5TR1JETiIsICJUb3RhbCBibG9vZCIsICJTU1YgVm9sdW1lIiwKICAgICAgICJWZW50cmljdWxhciB2b2x1bWUiLCAiVG90YWwgbWFudWFsIHZvbHVtZSIpCgpkYXRhX2ltYWdpbmdfc3Vic2V0IDwtIG5hLm9taXQoZGF0YV9pbWFnaW5nX3N1YnNldCkKCiNGaXQgYSBtYW51YWxseSB0dW5lZCBYR0Jvb3N0IG1vZGVsIHRvIHRoZSBkYXRhLgoKZHRyYWluIDwtIHhnYi5ETWF0cml4KGRhdGEubWF0cml4KGRhdGFfaW1hZ2luZ19zdWJzZXQpKQpkdmFsaWQgPC0geGdiLkRNYXRyaXgoZGF0YS5tYXRyaXgoZGF0YV9pbWFnaW5nX3N1YnNldCkpCgpwYXJhbXMgPC0gbGlzdCgKICBvYmplY3RpdmUgPSAicmVnOnNxdWFyZWRlcnJvciIsCiAgbGVhcm5pbmdfcmF0ZSA9IDAuMDUsCiAgc3Vic2FtcGxlID0gMC45LAogIGNvbHNhbXBsZV9ieW5vZGUgPSAxLAogIHJlZ19sYW1iZGEgPSAyLAogIG1heF9kZXB0aCA9IDUKKQpmaXRfeGdiIDwtIHhnYi50cmFpbigKICBwYXJhbXMsCiAgZGF0YSA9IGR0cmFpbiwKICB3YXRjaGxpc3QgPSBsaXN0KHZhbGlkID0gZHZhbGlkKSwKICBlYXJseV9zdG9wcGluZ19yb3VuZHMgPSAyMCwKICBwcmludF9ldmVyeV9uID0gMTAwLAogIG5yb3VuZHMgPSAxMDAwMCAjIGVhcmx5IHN0b3BwaW5nCikKCmBgYApDcmVhdGUgYSBjb21wYXJhdGl2ZSBBVUMgZ3JhcGggZm9yIHRoZSAnZmluYWwnIG1vZGVsIHRoYXQgaW5jbHVkZXMgV0ZOUywgdG90YWwgYmxvb2Qgdm9sdW1lIGFuZCB2ZW50cmljdWxhciBDU0Ygdm9sdW1lIGluIHRoZSBwcmVkaWN0aW9uIG9mIG1SUyAxODAKYGBge3J9CiNGaW5hbCBtb2RlbCAKCldGTlMKVG90YWxfYmxvb2Rfdm9sdW1lClZlbnRyaWN1bGFyX0NTRgptUlMxODAKCiMjIG1SUwoKbVJTMTgwIDwtIGFzLmZhY3RvcihyZWNvZGUobVJTMTgwLCAiMCI9Ikdvb2Qgb3V0Y29tZSIsICIxIiA9ICJCYWQgb3V0Y29tZSIpKQpjb250cmFzdHMoYXMuZmFjdG9yKG1SUzI4KSkKbVJTMTgwIDwtIGZhY3RvcihtUlMxODAsIGxldmVscyA9IGMoIkdvb2Qgb3V0Y29tZSIsICJCYWQgb3V0Y29tZSIpKQpjb250cmFzdHMoYXMuZmFjdG9yKG1SUzE4MCkpCgpNdWx0aXZhcmlhdGUgPC0gZ2xtKG1SUzE4MCB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1ZlbnRyaWN1bGFyX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQpjb2VmKE11bHRpdmFyaWF0ZSkKCgojIyBDb21iaW5lZCBBVUMgCgpsaWJyYXJ5KFJPQ1IpCmxpYnJhcnkocFJPQykKCgpwbG90KHggPSBXRk5TLCB5ID0gbVJTMTgwKQpNdWx0aXZhcmlhdGUgPC0gZ2xtKGFzLmZhY3RvcihtUlMxODApIH4gV0ZOUytUb3RhbF9ibG9vZF92b2x1bWUrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShNdWx0aXZhcmlhdGUpCgpyb2MxIDwtIHJvYyhtUlMxODAsIE11bHRpdmFyaWF0ZSRmaXR0ZWQudmFsdWVzLCBwbG90ID0gVFJVRSkKcm9jMQpjaShyb2MxKQpwYXIocHR5ID0gInMiKQoKcm9jKG1SUzE4MCwgTXVsdGl2YXJpYXRlJGZpdHRlZC52YWx1ZXMsIHBsb3QgPSBUUlVFLCBsZWdhY3kuYXhlcyA9IFRSVUUsIHBlcmNlbnQgPSBUUlVFLAogICAgeGxhYj0gIkZhbHNlIFBvc2l0aXZlIFBlcmNlbnRhZ2UiLCB5bGFiID0gIlRydWUgUG9zaXRpdmUgUGVyY2VudGFnZSIsIGNvbCA9ICJibGFjayIsIGx3ZCA9IDIsIHByaW50LmF1YyA9IDYwKQpsZWdlbmQoImJvdHRvbXJpZ2h0IiwgbGVnZW5kID0gYygibVJTIGRheSAxODAiKSwgY29sID0gYygiYmxhY2siKSwgbHdkID0gNCkKCmNpKHJvYzEpCgojIE92ZXJsYXAgQVVDIAoKTXVsdGl2YXJpYXRlIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lK1ZlbnRyaWN1bGFyX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCnN1bW1hcnkoTXVsdGl2YXJpYXRlKQoKcm9jKG1SUzE4MCwgTXVsdGl2YXJpYXRlJGZpdHRlZC52YWx1ZXMsIHBsb3QgPSBUUlVFLCBsZWdhY3kuYXhlcyA9IFRSVUUsIHBlcmNlbnQgPSBUUlVFLAogICAgeGxhYj0gIkZhbHNlIFBvc2l0aXZlIFBlcmNlbnRhZ2UiLCB5bGFiID0gIlRydWUgUG9zaXRpdmUgUGVyY2VudGFnZSIsIGNvbCA9ICJibGFjayIsIGx3ZCA9IDIsIHByaW50LmF1YyA9IDYwKQpwYXIocHR5ID0gInMiKQpNdWx0aXZhcmlhdGUyIDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVG90YWxfYmxvb2Rfdm9sdW1lLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKTXVsdGl2YXJpYXRlMyA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBXRk5TK1NTVl9DU0YsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gZGF0YV9pbWFnaW5nKQpNdWx0aXZhcmlhdGU0IDwtIGdsbShhcy5mYWN0b3IobVJTMTgwKSB+IFdGTlMrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKTXVsdGl2YXJpYXRlNSA8LSBnbG0oYXMuZmFjdG9yKG1SUzE4MCkgfiBXRk5TK1RvdGFsX0NTRiwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBkYXRhX2ltYWdpbmcpCgoKcm9jKG1SUzE4MCwgTXVsdGl2YXJpYXRlJGZpdHRlZC52YWx1ZXMsIHBsb3QgPSBUUlVFLCBsZWdhY3kuYXhlcyA9IFRSVUUsIHBlcmNlbnQgPSBUUlVFLAogICAgeGxhYj0gIkZhbHNlIFBvc2l0aXZlIFBlcmNlbnRhZ2UiLCB5bGFiID0gIlRydWUgUG9zaXRpdmUgUGVyY2VudGFnZSIsIGNvbCA9ICJvcmFuZ2UiLCBsd2QgPSAxLCBwcmludC5hdWMgPSBUUlVFLCBwcmludC5hdWMueSA9IDcwLCBwcmludC5hdWMueCA9IDQwKQpwbG90LnJvYyhtUlMxODAsIE11bHRpdmFyaWF0ZTIkZml0dGVkLnZhbHVlcywgcGVyY2VudCA9IFRSVUUsIGNvbCA9ICJyZWQiLCBsd2QgPSAxLCBhZGQgPSBUUlVFLCBwcmludC5hdWMgPSBUUlVFLCBwcmludC5hdWMueSA9IDkwLCBwcmludC5hdWMueCA9IDQwKQpwbG90LnJvYyhtUlMxODAsIE11bHRpdmFyaWF0ZTMkZml0dGVkLnZhbHVlcywgcGVyY2VudCA9IFRSVUUsIGNvbCA9ICJibHVlIiwgbHdkID0gMSwgYWRkID0gVFJVRSwgcHJpbnQuYXVjID0gVFJVRSwgcHJpbnQuYXVjLnkgPSA2MCwgcHJpbnQuYXVjLnggPSA0MCkKcGxvdC5yb2MobVJTMTgwLCBNdWx0aXZhcmlhdGU0JGZpdHRlZC52YWx1ZXMsIHBlcmNlbnQgPSBUUlVFLCBjb2wgPSAiYmxhY2siLCBsd2QgPSAxLCBhZGQgPSBUUlVFLCBwcmludC5hdWMgPSBUUlVFLCBwcmludC5hdWMueSA9IDgwLCBwcmludC5hdWMueCA9IDQwKQpwbG90LnJvYyhtUlMxODAsIE11bHRpdmFyaWF0ZTUkZml0dGVkLnZhbHVlcywgcGVyY2VudCA9IFRSVUUsIGNvbCA9ICJmb3Jlc3RncmVlbiIsIGx3ZCA9IDEsIGFkZCA9IFRSVUUsIHByaW50LmF1YyA9IFRSVUUsIHByaW50LmF1Yy55ID0gODAsIHByaW50LmF1Yy54ID0gNDApCgpsZWdlbmQoImJvdHRvbXJpZ2h0IiwgdGl0bGUgPSAibW9kaWZpZWQgUmFua2luIFNjYWxlIiwgCiAgICAgICBsZWdlbmQgPSBjKCJXRk5TK0Jsb29kIiwgIldGTlMrVmVudHJpY3VsYXJDU0YiLCAiRmluYWwgbW9kZWwiLCAiV0ZOUytTU1ZfQ1NGIiwgIldGTlMrVG90YWxDU0YiKSwgY29sID0gYygicmVkIiwgImJsYWNrIiwgIm9yYW5nZSIsICJibHVlIiwgImZvcmVzdGdyZWVuIiksIAogICAgICAgbHdkID0gMiwgIkxlZ2VuZCIsIGNleD0wLjgpCmBgYApTdGVwd2lzZSByZWdyZXNzc2lvbmFsIGFuYWx5c2lzIGZvciB0aGUgZGV2ZWxvcG1lbnQgb2YgdGhlIG11bHRpdmFyaWF0ZSBtb2RlbC4gCgpWYXJpYWJsZXM6IGFnZSwgV0ZOUywgVEJWLCBTU1YsIFZlbnRyaWN1bGFyIENTRiwgdG90YWwgQ1NGIAoKYGBge3J9CgojUGFja2FnZXMgCgpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShjYXJldCkKbGlicmFyeShsZWFwcykKbGlicmFyeShNQVNTKQoKI0ZpdCBmdWxsIG1vZGVsIAoKZnVsbC5tb2RlbCA8LSAgZ2xtKG1SUzE4MCB+IGFnZStXRk5TK1RvdGFsX2Jsb29kK1NTVl9DU0YrVmVudHJpY3VsYXJfQ1NGLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IGRhdGFfaW1hZ2luZykKc3VtbWFyeShmdWxsLm1vZGVsKQoKI1N0ZXB3aXNlIG1vZGVsCgpzdGVwLm1vZGVsIDwtIHN0ZXBBSUMoZnVsbC5tb2RlbCwgZGlyZWN0aW9uID0gImJvdGgiLCB0cmFjZSA9IEZBTFNFKQpzdW1tYXJ5KHN0ZXAubW9kZWwpCmBgYAoK