A00834241 | Regina Rodríguez Chávez A00833617 | Yessica Acosta
Blancheth A01275763 | Eli Gabriel Hernández Medina A00833172 | Genaro
Rodríguez Alcántara
It is necessary to load the database to begin the analysis.
Exploratory Data Analysis
It is important to start analyzing the structure of the database, as
well as the type of data held in each variable, in order to fully
understand the data we are working with.
#dataset
#str(dataset)
Analyzing the structure of the database, we can realize that the chas
variable is a binary variable of factor type, which is in an integer
type, therefore it is necessary to transform the data.
dataset$chas <- as.factor(dataset$chas)
sum(is.na(dataset))
## [1] 0
Since no null data were found, it is important to have an idea of the
main values of each variable through a descriptive statistical
analysis.
summary(dataset)
## medv cmedv crim zn
## Min. : 5.00 Min. : 5.00 Min. : 0.00632 Min. : 0.00
## 1st Qu.:17.02 1st Qu.:17.02 1st Qu.: 0.08205 1st Qu.: 0.00
## Median :21.20 Median :21.20 Median : 0.25651 Median : 0.00
## Mean :22.53 Mean :22.53 Mean : 3.61352 Mean : 11.36
## 3rd Qu.:25.00 3rd Qu.:25.00 3rd Qu.: 3.67708 3rd Qu.: 12.50
## Max. :50.00 Max. :50.00 Max. :88.97620 Max. :100.00
## indus chas nox rm age
## Min. : 0.46 0:471 Min. :0.3850 Min. :3.561 Min. : 2.90
## 1st Qu.: 5.19 1: 35 1st Qu.:0.4490 1st Qu.:5.886 1st Qu.: 45.02
## Median : 9.69 Median :0.5380 Median :6.208 Median : 77.50
## Mean :11.14 Mean :0.5547 Mean :6.285 Mean : 68.57
## 3rd Qu.:18.10 3rd Qu.:0.6240 3rd Qu.:6.623 3rd Qu.: 94.08
## Max. :27.74 Max. :0.8710 Max. :8.780 Max. :100.00
## dis rad tax ptratio
## Min. : 1.130 Min. : 1.000 Min. :187.0 Min. :12.60
## 1st Qu.: 2.100 1st Qu.: 4.000 1st Qu.:279.0 1st Qu.:17.40
## Median : 3.207 Median : 5.000 Median :330.0 Median :19.05
## Mean : 3.795 Mean : 9.549 Mean :408.2 Mean :18.46
## 3rd Qu.: 5.188 3rd Qu.:24.000 3rd Qu.:666.0 3rd Qu.:20.20
## Max. :12.127 Max. :24.000 Max. :711.0 Max. :22.00
## b lstat
## Min. : 0.32 Min. : 1.73
## 1st Qu.:375.38 1st Qu.: 6.95
## Median :391.44 Median :11.36
## Mean :356.67 Mean :12.65
## 3rd Qu.:396.23 3rd Qu.:16.95
## Max. :396.90 Max. :37.97
statistics_dt = summary(dataset)
mean_value <- statistics_dt[2, ]
median_value <- statistics_dt[3, ]
standard_deviation <- statistics_dt[4, ]
minimum_value <- statistics_dt[5, ]
maximum_value <- statistics_dt[6, ]
# Print the descriptive statistics
cat("Mean:", mean_value, "\n")
## Mean: 1st Qu.:17.02 1st Qu.:17.02 1st Qu.: 0.08205 1st Qu.: 0.00 1st Qu.: 5.19 1: 35 1st Qu.:0.4490 1st Qu.:5.886 1st Qu.: 45.02 1st Qu.: 2.100 1st Qu.: 4.000 1st Qu.:279.0 1st Qu.:17.40 1st Qu.:375.38 1st Qu.: 6.95
cat("Median:", median_value, "\n")
## Median: Median :21.20 Median :21.20 Median : 0.25651 Median : 0.00 Median : 9.69 NA Median :0.5380 Median :6.208 Median : 77.50 Median : 3.207 Median : 5.000 Median :330.0 Median :19.05 Median :391.44 Median :11.36
cat("Standard Deviation:", standard_deviation, "\n")
## Standard Deviation: Mean :22.53 Mean :22.53 Mean : 3.61352 Mean : 11.36 Mean :11.14 NA Mean :0.5547 Mean :6.285 Mean : 68.57 Mean : 3.795 Mean : 9.549 Mean :408.2 Mean :18.46 Mean :356.67 Mean :12.65
cat("Minimum:", minimum_value, "\n")
## Minimum: 3rd Qu.:25.00 3rd Qu.:25.00 3rd Qu.: 3.67708 3rd Qu.: 12.50 3rd Qu.:18.10 NA 3rd Qu.:0.6240 3rd Qu.:6.623 3rd Qu.: 94.08 3rd Qu.: 5.188 3rd Qu.:24.000 3rd Qu.:666.0 3rd Qu.:20.20 3rd Qu.:396.23 3rd Qu.:16.95
cat("Maximum:", maximum_value, "\n")
## Maximum: Max. :50.00 Max. :50.00 Max. :88.97620 Max. :100.00 Max. :27.74 NA Max. :0.8710 Max. :8.780 Max. :100.00 Max. :12.127 Max. :24.000 Max. :711.0 Max. :22.00 Max. :396.90 Max. :37.97
The results of the descriptive statistics reveal valuable information
about the variables in my data set. Regarding the target variable “medv”
(average value of homes), it is observed that its values range between
5.00 and 50.00, with a median of 21.20 and a slightly higher mean of
22.53. This suggests a relatively wide dispersion of house prices. When
examining other variables, such as “crim” (crime rate) and “nox”
(concentration of nitrogen oxides), wide variations in their values are
found, indicating significant differences in levels of crime and air
quality in the studied areas. Additionally, the variable “chas” is
mostly categorical, with most records having a value of 0.
On the other hand, statistics highlight key characteristics of the
predictor variables. For example, “rm” (average number of rooms per
dwelling) has values that vary between 3,561 and 8,780, with a median of
6,208, suggesting variability in the size of dwellings. The variable
“tax” shows wide variation, with values ranging between 187.0 and 711.0.
Furthermore, “lstat” (percentage of population of lower status) presents
values that vary from 1.73 to 37.97, indicating the diversity in the
socioeconomic conditions of the studied areas. These summary statistics
provide an overview of the distribution and variability of the
variables, which is essential for better understanding the data set and
planning subsequent analyses.
Since no abnormality was found in the data, a graphical analysis is
carried out.
Data Visualization
- Build at least 2 pair-wised graphs between the dependent variable
and independent variables
ggplot(data = dataset, aes(x = crim, y = medv)) +
geom_point(color = "blue", alpha = 0.6) +
labs(x = "Crime Rate (crim)", y = "Median Value (medv)") +
ggtitle("Scatter Plot: Median Value vs. Crime Rate") +
theme_minimal()

ggplot(data = dataset, aes(x = zn, y = medv)) +
geom_point(color = "red", alpha = 0.6) +
labs(x = "Proportion of Residential Land Zoned (zn)", y = "Median Value (medv)") +
ggtitle("Scatter Plot: Median Value vs. Proportion of Residential Land Zoned") +
theme_minimal()

ggplot(data = dataset, aes(x = indus, y = medv)) +
geom_point(color = "green", alpha = 0.6) +
labs(x = "Industrial Zone Proportion (indus)", y = "Median Value (medv)") +
ggtitle("Scatter Plot: Median Value vs. Industrial Zone Proportion") +
theme_minimal()

ggplot(data = dataset, aes(x = nox, y = medv)) +
geom_point(color = "blue", alpha = 0.6) +
labs(x = "Nitrogen Oxides Concentration (nox)", y = "Median Value (medv)") +
ggtitle("Scatter Plot: Median Value vs. Nitrogen Oxides Concentration") +
theme_minimal()

ggplot(data = dataset, aes(x = rm, y = medv)) +
geom_point(color = "red", alpha = 0.6) +
labs(x = "Average Number of Rooms (rm)", y = "Median Value (medv)") +
ggtitle("Scatter Plot: Median Value vs. Average Number of Rooms") +
theme_minimal()

ggplot(data = dataset, aes(x = age, y = medv)) +
geom_line(color = "green", alpha = 0.6) +
labs(x = "Proportion of Owner-Occupied Units Built Before 1940 (age)", y = "Median Value (medv)") +
ggtitle("Scatter Plot: Median Value vs. Proportion of Owner-Occupied Units Built Before 1940") +
theme_minimal()

ggplot(data = dataset, aes(x = dis, y = medv)) +
geom_line(color = "purple", alpha = 0.6) +
labs(x = "Weighted Distances to Employment Centers (dis)", y = "Median Value (medv)") +
ggtitle("Scatter Plot: Median Value vs. Weighted Distances to Employment Centers") +
theme_minimal()

ggplot(data = dataset, aes(x = factor(rad), y = medv)) +
geom_boxplot(fill = "skyblue") +
labs(x = "Accessibility to Radial Highways (rad)", y = "Median Value (medv)") +
ggtitle("Boxplot: Median Value vs. Accessibility to Radial Highways") +
theme_minimal()

ggplot(data = dataset, aes(x = factor(tax), y = medv)) +
geom_boxplot(fill = "lightgreen") +
labs(x = "Property Tax Rate (tax)", y = "Median Value (medv)") +
ggtitle("Boxplot: Median Value vs. Property Tax Rate") +
theme_minimal()

ggplot(data = dataset, aes(x = ptratio, y = medv)) +
geom_point(color = "blue", fill = "lightblue") +
labs(x = "Pupil-Teacher Ratio (ptratio)", y = "Median Value (medv)") +
ggtitle("Density Plot: Median Value vs. Pupil-Teacher Ratio") +
theme_minimal()

ggplot(data = dataset, aes(x = b, y = medv)) +
geom_point(color = "purple", alpha = 0.6) +
labs(x = "Proportion of Residents of African American Descent (b)", y = "Median Value (medv)") +
ggtitle("Scatter Plot: Median Value vs. Proportion of Residents of African American Descent (b)") +
theme_minimal()

ggplot(data = dataset, aes(x = lstat, y = medv)) +
geom_point(color = "orange", alpha = 0.6) +
labs(x = "Percentage of Lower Status Population (lstat)", y = "Median Value (medv)") +
ggtitle("Scatter Plot: Median Value vs. Percentage of Lower Status Population (lstat)") +
theme_minimal()
The previous graphs give us an idea of the correlation relationships
between each independent variable and the dependent variable. This does
not mean that they have a direct causal relationship, but they are a
sign that they have the potential to be statistically significant, so
some variables would be interesting to include in linear regression
analyses, for example, zn,nox, rm or ISTAT.
- Display a histogram of dependent variable
hist(dataset$medv)

hist(dataset$crim)

hist(dataset$zn)

hist(dataset$indus)

hist(dataset$nox)

hist(dataset$rm)

hist(dataset$dis)

hist(dataset$rad)

hist(dataset$tax)

hist(dataset$ptratio)

hist(dataset$b)

hist(dataset$lstat)

Thanks to the histograms, we can see the distribution of the data for
each variable, where we see that there are several such as: crim, zn,
indus, chas, nox, dix, rad, tax, ptratio, b and lstat that do not follow
a normal distribution, therefore it will be interesting to apply
quadratic or logarithmic transformations to these variables in our
subsequent linear regression analyses.
- Display a correlation plot
To better understand the correlation relationships between the
variables, a diagram and a correlation matrix will be made. It is very
important to analyze this to avoid multiculinality problems.
dataset_excl_chas <- dataset[, !colnames(dataset) %in% c("chas")]
cor_matrix <- cor(dataset_excl_chas)
corrplot(cor_matrix, type = "upper", order = "hclust", addCoef.col = "black")

cor_matrix
## medv cmedv crim zn indus nox
## medv 1.0000000 0.9984759 -0.3883046 0.3604453 -0.4837252 -0.4273208
## cmedv 0.9984759 1.0000000 -0.3895824 0.3603862 -0.4847544 -0.4293002
## crim -0.3883046 -0.3895824 1.0000000 -0.2004692 0.4065834 0.4209717
## zn 0.3604453 0.3603862 -0.2004692 1.0000000 -0.5338282 -0.5166037
## indus -0.4837252 -0.4847544 0.4065834 -0.5338282 1.0000000 0.7636514
## nox -0.4273208 -0.4293002 0.4209717 -0.5166037 0.7636514 1.0000000
## rm 0.6953599 0.6963038 -0.2192467 0.3119906 -0.3916759 -0.3021882
## age -0.3769546 -0.3779989 0.3527343 -0.5695373 0.6447785 0.7314701
## dis 0.2499287 0.2493148 -0.3796701 0.6644082 -0.7080270 -0.7692301
## rad -0.3816262 -0.3847656 0.6255051 -0.3119478 0.5951293 0.6114406
## tax -0.4685359 -0.4719788 0.5827643 -0.3145633 0.7207602 0.6680232
## ptratio -0.5077867 -0.5056546 0.2899456 -0.3916785 0.3832476 0.1889327
## b 0.3334608 0.3348608 -0.3850639 0.1755203 -0.3569765 -0.3800506
## lstat -0.7376627 -0.7408360 0.4556215 -0.4129946 0.6037997 0.5908789
## rm age dis rad tax ptratio
## medv 0.6953599 -0.3769546 0.2499287 -0.3816262 -0.4685359 -0.5077867
## cmedv 0.6963038 -0.3779989 0.2493148 -0.3847656 -0.4719788 -0.5056546
## crim -0.2192467 0.3527343 -0.3796701 0.6255051 0.5827643 0.2899456
## zn 0.3119906 -0.5695373 0.6644082 -0.3119478 -0.3145633 -0.3916785
## indus -0.3916759 0.6447785 -0.7080270 0.5951293 0.7207602 0.3832476
## nox -0.3021882 0.7314701 -0.7692301 0.6114406 0.6680232 0.1889327
## rm 1.0000000 -0.2402649 0.2052462 -0.2098467 -0.2920478 -0.3555015
## age -0.2402649 1.0000000 -0.7478805 0.4560225 0.5064556 0.2615150
## dis 0.2052462 -0.7478805 1.0000000 -0.4945879 -0.5344316 -0.2324705
## rad -0.2098467 0.4560225 -0.4945879 1.0000000 0.9102282 0.4647412
## tax -0.2920478 0.5064556 -0.5344316 0.9102282 1.0000000 0.4608530
## ptratio -0.3555015 0.2615150 -0.2324705 0.4647412 0.4608530 1.0000000
## b 0.1280686 -0.2735340 0.2915117 -0.4444128 -0.4418080 -0.1773833
## lstat -0.6138083 0.6023385 -0.4969958 0.4886763 0.5439934 0.3740443
## b lstat
## medv 0.3334608 -0.7376627
## cmedv 0.3348608 -0.7408360
## crim -0.3850639 0.4556215
## zn 0.1755203 -0.4129946
## indus -0.3569765 0.6037997
## nox -0.3800506 0.5908789
## rm 0.1280686 -0.6138083
## age -0.2735340 0.6023385
## dis 0.2915117 -0.4969958
## rad -0.4444128 0.4886763
## tax -0.4418080 0.5439934
## ptratio -0.1773833 0.3740443
## b 1.0000000 -0.3660869
## lstat -0.3660869 1.0000000
The correlation analysis between the independent variables and the
dependent variable “medv” shows several interesting results. A strong
positive correlation is observed between “medv” and “cmedv,” indicating
that both variables are highly related. Furthermore, “rm” (number of
rooms) also presents a significant positive correlation with “medv,”
suggesting that as the number of rooms increases, the median home value
tends to increase.
On the other hand, there is a notable negative correlation between
“medv” and “lstat” (percentage of population with low socioeconomic
status), indicating that as the percentage of population with low
socioeconomic status decreases, the median value of the housing tends to
increase. It is important to mention that multicollinearity is also
observed between some independent variables, such as “nox” and “indus,”
which suggests that these variables are correlated with each other.
Regression Analysis
With the exploratory analysis of the data, the variables that are
believed to have the best potential to model the situation will be
chosen…
Likewise, for models 2 and 3, transformations will be used through
the conclusions found in the histograms and other insights found in the
exploratory analysis of the data.
MODEL 1
dmodel1<-lm(medv ~ rm+nox+lstat+crim+tax+indus,data=dataset)
summary(dmodel1)
##
## Call:
## lm(formula = medv ~ rm + nox + lstat + crim + tax + indus, data = dataset)
##
## Residuals:
## Min 1Q Median 3Q Max
## -16.782 -3.553 -1.137 1.765 30.464
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -2.481981 3.299447 -0.752 0.45226
## rm 5.213899 0.444913 11.719 < 2e-16 ***
## nox 3.850583 3.474274 1.108 0.26826
## lstat -0.560857 0.053869 -10.412 < 2e-16 ***
## crim -0.059567 0.035764 -1.666 0.09643 .
## tax -0.006609 0.002392 -2.763 0.00593 **
## indus 0.010882 0.063367 0.172 0.86372
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 5.459 on 499 degrees of freedom
## Multiple R-squared: 0.6519, Adjusted R-squared: 0.6477
## F-statistic: 155.8 on 6 and 499 DF, p-value: < 2.2e-16
The model has a moderate ability to explain variations in house
prices, with an adjusted R-squared of approximately 0.648.
Among the independent variables, “rm” (average number of rooms per
household) and “lstat” (percentage of population with low status) are
statistically significant. A one-unit increase in the average number of
rooms is associated with an increase of about 5,214 units in the housing
price, while a one-unit increase in the percentage of the population
with low status is associated with a decrease of about 0.561 units in
the price of housing.
The variables “tax” (property tax), “nox” (concentration of nitrogen
oxides), “crim” (crime rate) and “indus” (proportion of acres of
non-retail businesses per city) are not statistically significant in
this model.
The model as a whole has a statistically significant F value,
indicating that at least one of the independent variables is relevant in
predicting house prices.
The intercept is not statistically significant in this context.
In summary, the model suggests that the average number of rooms and
the percentage of the population with low status are important factors
in predicting housing prices, while other variables do not have a
significant impact on the model. The model as a whole is capable of
explaining a considerable part of the variability in house prices.
Although the model shows a relatively good fit, it is necessary to
perform diagnostic tests to detect problems such as multiculinality,
heterocerasticity or normality of residuals.
Diagnostic tests MODEL 1
# Multicollinearity
vif(dmodel1)
## rm nox lstat crim tax indus
## 1.656208 2.746972 2.507990 1.603871 2.753383 3.202960
Since no value exceeds the threshold of 10, multiculionality is not
observed, that is, there is no correlation between the independent
variables.
# Heteroscedasticity
bptest(dmodel1)
##
## studentized Breusch-Pagan test
##
## data: dmodel1
## BP = 33.193, df = 6, p-value = 9.628e-06
The p-value is extremely low (much less than 0.05), indicating that
there is very strong evidence against the homoscedasticity hypothesis.
Therefore, there is evidence of heterocerasticity.
# Normality of Residuals
qqnorm(dmodel1$residuals)
qqline(dmodel1$residuals)

shapiro.test(dmodel1$residuals)
##
## Shapiro-Wilk normality test
##
## data: dmodel1$residuals
## W = 0.87497, p-value < 2.2e-16
The Shapiro-Wilk normality test yields a p value very close to zero
(< 2.2e-16), less than p=0.05. which indicates that we must reject
the null hypothesis that the residuals of model dmodel1 follow a normal
distribution, concluding that the residuals do not They are normally
distributed.
MODEL 2
dmodel2<-lm(log(medv) ~ rm+nox+lstat+crim+tax+indus,data=dataset)
summary(dmodel2)
##
## Call:
## lm(formula = log(medv) ~ rm + nox + lstat + crim + tax + indus,
## data = dataset)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.74079 -0.13175 -0.01677 0.10572 0.93981
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.626e+00 1.305e-01 20.118 < 2e-16 ***
## rm 1.432e-01 1.760e-02 8.136 3.26e-15 ***
## nox 5.965e-02 1.374e-01 0.434 0.664477
## lstat -3.031e-02 2.131e-03 -14.223 < 2e-16 ***
## crim -8.308e-03 1.415e-03 -5.872 7.87e-09 ***
## tax -3.153e-04 9.461e-05 -3.332 0.000926 ***
## indus 1.576e-03 2.507e-03 0.629 0.529846
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.216 on 499 degrees of freedom
## Multiple R-squared: 0.7242, Adjusted R-squared: 0.7209
## F-statistic: 218.4 on 6 and 499 DF, p-value: < 2.2e-16
The model achieves a moderate ability to explain variations in the
logarithm of house prices, with an adjusted R-squared of approximately
0.721.
Of the independent variables, “rm” (average number of rooms per home)
and “lstat” (percentage of population with low status) are statistically
significant. A one-unit increase in the average number of bedrooms is
associated with an increase in the log house price by approximately
0.315 units, while a one-unit increase in the percentage of the
population with low status is associated with a decrease in the log of
the house price by approximately 0.047 units.
The variables “nox” (concentration of nitrogen oxides), “crim” (crime
rate), “tax” (property tax), and “indus” (proportion of non-retail
business acres per city) are not statistically significant in this
model.
The model as a whole has a statistically significant F value,
indicating that at least one of the independent variables is relevant in
predicting the logarithm of house prices.
The intercept is not statistically significant in this context.
In summary, the second model suggests that the average number of
rooms and the percentage of population with low status are important
factors in predicting the logarithm of house prices, while other
variables do not have a significant impact on the model. The model as a
whole is able to explain a considerable part of the variability in the
logarithm of house prices.
Diagnostic tests MODEL 2
# Multicollinearity
vif(dmodel2)
## rm nox lstat crim tax indus
## 1.656208 2.746972 2.507990 1.603871 2.753383 3.202960
Since no value exceeds the threshold of 10, multiculionality is not
observed, that is, there is no correlation between the independent
variables.
# Heteroscedasticity
bptest(dmodel2)
##
## studentized Breusch-Pagan test
##
## data: dmodel2
## BP = 48.152, df = 6, p-value = 1.102e-08
The studentized Breusch-Pagan test yields an extremely low p-value
(1.518e-07), which leads us to strongly reject the null hypothesis of
homoscedasticity in the dmodel2 model. With such a low p value, we can
strongly conclude that heteroskedasticity exists in the model residuals.
The significance level is much lower than 0.05, which reinforces this
conclusion.
# Normality of Residuals
qqnorm(dmodel2$residuals)
qqline(dmodel2$residuals)

shapiro.test(dmodel2$residuals)
##
## Shapiro-Wilk normality test
##
## data: dmodel2$residuals
## W = 0.94569, p-value = 1.164e-12
The Shapiro-Wilk normality test shows an extremely low p-value
(1.164e-12), less than P=0.05. indicating that the residuals from the
dmodel2 model do not follow a normal distribution. Therefore, we can
strongly reject the null hypothesis that the residuals are normally
distributed. This result suggests that the model does not meet the
assumption of normality of errors.
MODEL 3
dmodel3<-lm(log(medv) ~ +I(cmedv^2)+nox+rm+nox+lstat+crim,data=dataset)
summary(dmodel3)
##
## Call:
## lm(formula = log(medv) ~ +I(cmedv^2) + nox + rm + nox + lstat +
## crim, data = dataset)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.66621 -0.06049 0.00662 0.07079 0.49828
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.332e+00 8.588e-02 38.796 < 2e-16 ***
## I(cmedv^2) 4.820e-04 1.724e-05 27.954 < 2e-16 ***
## nox -1.851e-01 6.669e-02 -2.776 0.00571 **
## rm -3.294e-02 1.267e-02 -2.599 0.00962 **
## lstat -1.880e-02 1.396e-03 -13.459 < 2e-16 ***
## crim -9.702e-03 8.128e-04 -11.937 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1363 on 500 degrees of freedom
## Multiple R-squared: 0.8899, Adjusted R-squared: 0.8888
## F-statistic: 807.9 on 5 and 500 DF, p-value: < 2.2e-16
The model has a high capacity to explain variations in the logarithm
of house prices, with an adjusted R-squared of approximately 0.8898.
Of the independent variables, “I(cmedv^2)” (a quadratic
transformation of the average house price), “nox” (concentration of
nitrogen oxides), “rm” (average number of rooms per house), “lstat”
(percentage of population with low status) and “crim” (crime rate) are
statistically significant.
The coefficient of “I(cmedv^2)” is positive, suggesting a positive
quadratic relationship between the transformed variable and the
logarithm of house prices.
The intercept is statistically significant and has a positive value,
indicating a base value in the logarithm of house prices.
Overall, the model as a whole is highly significant, with a
statistically significant F value.
The model has a good fit to the data, with a low residual standard
error of approximately 0.1363.
Diagnostic tests MODEL 3
# Multicollinearity
vif(dmodel3)
## I(cmedv^2) nox rm lstat crim
## 2.206569 1.622443 2.154363 2.701969 1.328018
Since no value exceeds the threshold of 10, multiculionality is not
observed, that is, there is no correlation between the independent
variables.
# Heteroscedasticity
bptest(dmodel3)
##
## studentized Breusch-Pagan test
##
## data: dmodel3
## BP = 107.81, df = 5, p-value < 2.2e-16
The Breusch-Pagan test yields a p-value very close to zero (p-value
< 2.2e-16), less to p=0.05. Indicating strong evidence against the
null hypothesis of homoscedasticity. Therefore, we can conclude that
there is heteroscedasticity in the dmodel3 model, which suggests that
the error variance is not constant in all observations and that there
could be dispersion problems in the model.
# Normality of Residuals
qqnorm(dmodel3$residuals)
qqline(dmodel3$residuals)

shapiro.test(dmodel3$residuals)
##
## Shapiro-Wilk normality test
##
## data: dmodel3$residuals
## W = 0.93175, p-value = 1.972e-14
The Shapiro-Wilk normality test yields an extremely low p-value
(p-value = 1.972e-14), indicating strong evidence against the null
hypothesis that the residuals follow a normal distribution. Therefore,
we can conclude that the residuals do not follow a normal distribution,
suggesting that the assumption of normality of the errors in the model
may not be adequately met. It is important to keep this non-normality in
mind when interpreting model results and considering possible
adjustments or transformations of the data if necessary.
AIC(dmodel1)
## [1] 3162.478
AIC(dmodel2)
## [1] -106.17
AIC(dmodel3)
## [1] -572.6356
Model Selection
The models presented problems of normality and heterocerasticity,
which is why it is important to continue making data transformations and
apply other regularization methods to achieve a more precise and
reliable model for predictions. On the other hand, because most of the
variables are statistically significant, have a higher r-squared value,
do not present multiculinality and have a lower AIC value, model 3 is
chosen as the best option to fit our needs. data. It is also important
to mention that heterocerasticity is a problem inherent to the nature of
the data, since data from one point in time from various US states are
being studied, therefore the variances will differ when studying many
groups of data with characteristics different.
Model interpretation
The model has a high capacity to explain variations in the logarithm
of house prices, with an adjusted R-squared of approximately 0.8898.
Of the independent variables, “I(cmedv^2)” (a quadratic
transformation of the average house price), “nox” (concentration of
nitrogen oxides), “rm” (average number of rooms per house), “lstat”
(percentage of population with low status) and “crim” (crime rate) are
statistically significant.
The coefficient of “I(cmedv^2)” is positive, suggesting a positive
quadratic relationship between the transformed variable and the
logarithm of house prices.
The intercept is statistically significant and has a positive value,
indicating a base value in the logarithm of house prices.
Overall, the model as a whole is highly significant, with a
statistically significant F value.
The model has a good fit to the data, with a low residual standard
error of approximately 0.1363.
# LASSO regression via glmnet package can only take numerical observations. Then, the dataset is transformed to model.matrix() format.
# Independent variables
x<-model.matrix(log(medv) ~ rm+nox+lstat+crim,dataset)[,-1] ### OLS model specification
# x<-model.matrix(Weekly_Sales~.,train.data)[,-1] ### matrix of independent variables X's
y<-dataset$medv ### dependent variable
# In estimating LASSO regression it is important to define the lambda that minimizes the prediction error rate.
# Cross-validation ensures that every data / observation from the original dataset (datains) has a chance of appearing in train and test datasets.
# Find the best lambda using cross-validation.
set.seed(123)
cv.lasso<-cv.glmnet(x,y,alpha=1) # alpha = 1 for LASSO
# Display the best lambda value
cv.lasso$lambda.min ### lambda: a numeric value defining the amount of shrinkage. Why min? the higher the value of ?? , the more penalization there is
## [1] 0.1494561
# Fit the final model on the training data
lassomodel<-glmnet(x,y,alpha=1,lambda=cv.lasso$lambda.min)
# Display regression coefficients
coef(lassomodel)
## 5 x 1 sparse Matrix of class "dgCMatrix"
## s0
## (Intercept) -1.74433078
## rm 5.06940392
## nox .
## lstat -0.57351659
## crim -0.09007037
# Make predictions on the test data
x.test<-model.matrix(log(medv) ~ rm+nox+lstat+crim,dataset)[,-1] ### OLS model specification
# x.test<-model.matrix(Weekly_Sales~.,test.data)[,-1]
lassopredictions <- lassomodel %>% predict(x.test) %>% as.vector()
### visualizing lasso regression results
lbs_fun <- function(fit, offset_x=1, ...) {
L <- length(fit$lambda)
x <- log(fit$lambda[L])+ offset_x
y <- fit$beta[, L]
labs <- names(y)
text(x, y, labels=labs, ...)
}
lasso<-glmnet(scale(x),y,alpha=1)
plot(lasso,xvar="lambda",label=T)
lbs_fun(lasso)
abline(v=cv.lasso$lambda.min,col="red",lty=2)
abline(v=cv.lasso$lambda.1se,col="blue",lty=2)

summary(lassomodel)
## Length Class Mode
## a0 1 -none- numeric
## beta 4 dgCMatrix S4
## df 1 -none- numeric
## dim 2 -none- numeric
## lambda 1 -none- numeric
## dev.ratio 1 -none- numeric
## nulldev 1 -none- numeric
## npasses 1 -none- numeric
## jerr 1 -none- numeric
## offset 1 -none- logical
## call 5 -none- call
## nobs 1 -none- numeric
- Intercept: The intercept value is approximately -1.744. This
represents the estimated value of the dependent variable (medv) when all
independent variables are equal to zero.
- Coefficients of the independent variables: The model has identified
three significant variables in predicting the dependent variable (medv).
These are “rm” (number of rooms), “lstat” (percentage of low-status
population), and “crim” (crime rate). The magnitude of these
coefficients indicates their impact on the dependent variable. For
example, a one unit increase in “rm” results in an increase of
approximately 5.07 units in medv, holding the other variables
constant.
- Variable “nox” (nitrogen oxide): The coefficient for “nox” is marked
“.”. This means that the model has considered that this variable does
not have a significant impact on the dependent variable after L1
regularization.
- Model dimension: The model has estimated four non-null coefficients
(df) and a constant term, which means that it considers four independent
variables as relevant for the prediction of medv.
Serial Autocorrelation
Since we are working with a database that collects information on the
value of homes at a specific point in time, they are cross-sectional
data and therefore do not have serial autocorrelation.
Results Discussion
In summary, the linear regression models that were developed to
predict property median value (medv) presented significant challenges
related to normality of residuals and heteroskedasticity. These issues
suggest that the underlying assumptions of classical linear regression
may not be fully met in this data set. As a result, data transformations
were applied and regularization methods, such as the Lasso model, were
explored to address these limitations and improve prediction
accuracy.
In particular, the Lasso model showed a penalty coefficient (lambda)
of 0.149, indicating that the model penalizes the predictor variables to
some extent. This suggests that some of the features may not contribute
significantly to the medv prediction and could be removed to simplify
the model without significant loss of accuracy. In addition, it was
observed that the variables “rm” (number of rooms), “nox” (concentration
of nitrogen oxide in the air) and “lstat” (percentage of low-status
population) had significant coefficients in the Lasso model, which
indicating its importance in predicting the median value of the
properties.
Despite the challenges of normality and heteroscedasticity, multiple
linear regression Model 3 was selected as the best option due to its
higher R-squared, statistical significance of the predictor variables,
lack of multicollinearity, and lower AIC value. This suggests that,
although the data present certain problems, Model 3 provides a solid
approximation to predict the median value of the properties as a
function of the variables considered.
It was very interesting to see how the data transformations helped to
reduce the problems of heterocerasticity and normality of the residuals
that were found in the first model proposed.
Regarding the insights found, the great impact that the crime rate
has on homes is highlighted, since this variable was statistically
significant, with a high and negative coefficient, so an increase in
crime leads to a considerable loss in the value of the property. the
homes, which is why it is important to guarantee the security of the
neighborhoods and thus be able to increase the value of the homes. On
the other hand, air quality, as thought, turned out to have a negative
significance, which highlights the tendency of people to live in quiet
places, with excellent air and a very good quality of life. However,
something interesting was seeing that the number of rooms turned out to
have a negative relationship with the value of the homes, something very
peculiar and that could be related to the fact that perhaps people value
other more important factors more than the number of rooms.
Regarding the importance of diagnostics in improving the results of
linear regression and predictive analysis, they played a fundamental
role. Tests for normality and heteroscedasticity identified problems in
the data that led to the application of transformations and
regularization methods, such as the Lasso model. These diagnostics
helped fine-tune the models and improve their ability to make accurate
predictions. Furthermore, the variable selection process in the Lasso
model highlighted the importance of certain characteristics, which can
be valuable in decision making to optimize the design of future real
estate projects in the studied regions.
LS0tCnRpdGxlOiAiQXNzaWdubWVudCAyLiBEaWFnbm9zdGljIFRlc3RzIGZvciBSZWdyZXNzaW9uIEFuYWx5c2lzIgphdXRob3I6ICJHYWJyaWVsIE1lZGluYSAtIEEwMTI3NTc2MyIKZGF0ZTogIjIwMjMtMDgtMjIiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCkVxdWlwbzoKCkEwMDgzNDI0MSB8IFJlZ2luYSBSb2Ryw61ndWV6IENow6F2ZXoKQTAwODMzNjE3IHwgWWVzc2ljYSBBY29zdGEgQmxhbmNoZXRoCkEwMTI3NTc2MyB8IEVsaSBHYWJyaWVsIEhlcm7DoW5kZXogTWVkaW5hCkEwMDgzMzE3MiB8IEdlbmFybyBSb2Ryw61ndWV6IEFsY8OhbnRhcmEKClRoZSBmaXJzdCBzdGVwIGlzIGxvYWQgdGhlIGxpYnJhcmllcwpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGZvcmVpZ24pCmxpYnJhcnkoZHBseXIpICAgICAgICAjIGRhdGEgbWFuaXB1bGF0aW9uIApsaWJyYXJ5KGZvcmNhdHMpICAgICAgIyB0byB3b3JrIHdpdGggY2F0ZWdvcmljYWwgdmFyaWFibGVzCmxpYnJhcnkoZ2dwbG90MikgICAgICAjIGRhdGEgdmlzdWFsaXphdGlvbiAKbGlicmFyeShyZWFkcikgICAgICAgICMgcmVhZCBzcGVjaWZpYyBjc3YgZmlsZXMKbGlicmFyeShqYW5pdG9yKSAgICAgICMgZGF0YSBleHBsb3JhdGlvbiBhbmQgY2xlYW5pbmcgCmxpYnJhcnkoSG1pc2MpICAgICAgICAjIHNldmVyYWwgdXNlZnVsIGZ1bmN0aW9ucyBmb3IgZGF0YSBhbmFseXNpcyAKbGlicmFyeShwc3ljaCkgICAgICAgICMgZnVuY3Rpb25zIGZvciBtdWx0aXZhcmlhdGUgYW5hbHlzaXMgCmxpYnJhcnkobmFuaWFyKSAgICAgICAjIHN1bW1hcmllcyBhbmQgdmlzdWFsaXphdGlvbiBvZiBtaXNzaW5nIHZhbHVlcyBOQSdzCmxpYnJhcnkoZGxvb2tyKSAgICAgICAjIHN1bW1hcmllcyBhbmQgdmlzdWFsaXphdGlvbiBvZiBtaXNzaW5nIHZhbHVlcyBOQSdzCmxpYnJhcnkoY29ycnBsb3QpICAgICAjIGNvcnJlbGF0aW9uIHBsb3RzCmxpYnJhcnkoanRvb2xzKSAgICAgICAjIHByZXNlbnRhdGlvbiBvZiByZWdyZXNzaW9uIGFuYWx5c2lzIApsaWJyYXJ5KGxtdGVzdCkgICAgICAgIyBkaWFnbm9zdGljIGNoZWNrcyAtIGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2lzIApsaWJyYXJ5KGNhcikgICAgICAgICAgIyBkaWFnbm9zdGljIGNoZWNrcyAtIGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2lzCmxpYnJhcnkob2xzcnIpICAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMgCmxpYnJhcnkobmFuaWFyKSAgICAgICAjIGlkZW50aWZ5aW5nIG1pc3NpbmcgdmFsdWVzCiNsaWJyYXJ5KGZ1bk1vZGVsaW5nKSAgIyBjcmVhdGUgZnJlcXVlbmN5IHRhYmxlcwpsaWJyYXJ5KHN0YXJnYXplcikgICAgIyBjcmVhdGUgcHVibGljYXRpb24gcXVhbGl0eSB0YWJsZXMKbGlicmFyeShlZmZlY3RzKSAgICAgICMgZGlzcGxheXMgZm9yIGxpbmVhciBhbmQgb3RoZXIgcmVncmVzc2lvbiBtb2RlbHMKbGlicmFyeSh0aWR5dmVyc2UpICAgICMgY29sbGVjdGlvbiBvZiBSIHBhY2thZ2VzIGRlc2lnbmVkIGZvciBkYXRhIHNjaWVuYwpsaWJyYXJ5KGNhcmV0KSAgICAgICAgIyBDbGFzc2lmaWNhdGlvbiBhbmQgUmVncmVzc2lvbiBUcmFpbmluZyAKbGlicmFyeShnbG1uZXQpICAKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGNhcikKbGlicmFyeShsbXRlc3QpCgoKYGBgCgoKSXQgaXMgbmVjZXNzYXJ5IHRvIGxvYWQgdGhlIGRhdGFiYXNlIHRvIGJlZ2luIHRoZSBhbmFseXNpcy4KCmBgYHtyIGNhcnN9CiNmaWxlLmNob29zZSgpCmRhdGFzZXQgPC0gcmVhZC5jc3YoIi9Vc2Vycy9nYWJyaWVsbWVkaW5hL0Rvd25sb2Fkcy9SZWFsX2VzdGF0ZV9kYXRhICgxKS5jc3YiKQoKYGBgCgojIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMKCgpJdCBpcyBpbXBvcnRhbnQgdG8gc3RhcnQgYW5hbHl6aW5nIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGRhdGFiYXNlLCBhcyB3ZWxsIGFzIHRoZSB0eXBlIG9mIGRhdGEgaGVsZCBpbiBlYWNoIHZhcmlhYmxlLCBpbiBvcmRlciB0byBmdWxseSB1bmRlcnN0YW5kIHRoZSBkYXRhIHdlIGFyZSB3b3JraW5nIHdpdGguCgpgYGB7cn0KI2RhdGFzZXQKYGBgCmBgYHtyfQojc3RyKGRhdGFzZXQpCmBgYAoKQW5hbHl6aW5nIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGRhdGFiYXNlLCB3ZSBjYW4gcmVhbGl6ZSB0aGF0IHRoZSBjaGFzIHZhcmlhYmxlIGlzIGEgYmluYXJ5IHZhcmlhYmxlIG9mIGZhY3RvciB0eXBlLCB3aGljaCBpcyBpbiBhbiBpbnRlZ2VyIHR5cGUsIHRoZXJlZm9yZSBpdCBpcyBuZWNlc3NhcnkgdG8gdHJhbnNmb3JtIHRoZSBkYXRhLgoKYGBge3J9CmRhdGFzZXQkY2hhcyA8LSBhcy5mYWN0b3IoZGF0YXNldCRjaGFzKQpgYGAKCmBgYHtyfQpzdW0oaXMubmEoZGF0YXNldCkpIApgYGAKClNpbmNlIG5vIG51bGwgZGF0YSB3ZXJlIGZvdW5kLCBpdCBpcyBpbXBvcnRhbnQgdG8gaGF2ZSBhbiBpZGVhIG9mIHRoZSBtYWluIHZhbHVlcyBvZiBlYWNoIHZhcmlhYmxlIHRocm91Z2ggYSBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNhbCBhbmFseXNpcy4KCmBgYHtyfQpzdW1tYXJ5KGRhdGFzZXQpCmBgYAoKYGBge3J9CnN0YXRpc3RpY3NfZHQgPSBzdW1tYXJ5KGRhdGFzZXQpCgoKbWVhbl92YWx1ZSA8LSBzdGF0aXN0aWNzX2R0WzIsIF0KbWVkaWFuX3ZhbHVlIDwtIHN0YXRpc3RpY3NfZHRbMywgXQpzdGFuZGFyZF9kZXZpYXRpb24gPC0gc3RhdGlzdGljc19kdFs0LCBdCm1pbmltdW1fdmFsdWUgPC0gc3RhdGlzdGljc19kdFs1LCBdCm1heGltdW1fdmFsdWUgPC0gc3RhdGlzdGljc19kdFs2LCBdCgojIFByaW50IHRoZSBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzCmNhdCgiTWVhbjoiLCBtZWFuX3ZhbHVlLCAiXG4iKQpjYXQoIk1lZGlhbjoiLCBtZWRpYW5fdmFsdWUsICJcbiIpCmNhdCgiU3RhbmRhcmQgRGV2aWF0aW9uOiIsIHN0YW5kYXJkX2RldmlhdGlvbiwgIlxuIikKY2F0KCJNaW5pbXVtOiIsIG1pbmltdW1fdmFsdWUsICJcbiIpCmNhdCgiTWF4aW11bToiLCBtYXhpbXVtX3ZhbHVlLCAiXG4iKQoKYGBgClRoZSByZXN1bHRzIG9mIHRoZSBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIHJldmVhbCB2YWx1YWJsZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdmFyaWFibGVzIGluIG15IGRhdGEgc2V0LiBSZWdhcmRpbmcgdGhlIHRhcmdldCB2YXJpYWJsZSAibWVkdiIgKGF2ZXJhZ2UgdmFsdWUgb2YgaG9tZXMpLCBpdCBpcyBvYnNlcnZlZCB0aGF0IGl0cyB2YWx1ZXMgcmFuZ2UgYmV0d2VlbiA1LjAwIGFuZCA1MC4wMCwgd2l0aCBhIG1lZGlhbiBvZiAyMS4yMCBhbmQgYSBzbGlnaHRseSBoaWdoZXIgbWVhbiBvZiAyMi41My4gVGhpcyBzdWdnZXN0cyBhIHJlbGF0aXZlbHkgd2lkZSBkaXNwZXJzaW9uIG9mIGhvdXNlIHByaWNlcy4gV2hlbiBleGFtaW5pbmcgb3RoZXIgdmFyaWFibGVzLCBzdWNoIGFzICJjcmltIiAoY3JpbWUgcmF0ZSkgYW5kICJub3giIChjb25jZW50cmF0aW9uIG9mIG5pdHJvZ2VuIG94aWRlcyksIHdpZGUgdmFyaWF0aW9ucyBpbiB0aGVpciB2YWx1ZXMgYXJlIGZvdW5kLCBpbmRpY2F0aW5nIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGluIGxldmVscyBvZiBjcmltZSBhbmQgYWlyIHF1YWxpdHkgaW4gdGhlIHN0dWRpZWQgYXJlYXMuIEFkZGl0aW9uYWxseSwgdGhlIHZhcmlhYmxlICJjaGFzIiBpcyBtb3N0bHkgY2F0ZWdvcmljYWwsIHdpdGggbW9zdCByZWNvcmRzIGhhdmluZyBhIHZhbHVlIG9mIDAuCgpPbiB0aGUgb3RoZXIgaGFuZCwgc3RhdGlzdGljcyBoaWdobGlnaHQga2V5IGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgcHJlZGljdG9yIHZhcmlhYmxlcy4gRm9yIGV4YW1wbGUsICJybSIgKGF2ZXJhZ2UgbnVtYmVyIG9mIHJvb21zIHBlciBkd2VsbGluZykgaGFzIHZhbHVlcyB0aGF0IHZhcnkgYmV0d2VlbiAzLDU2MSBhbmQgOCw3ODAsIHdpdGggYSBtZWRpYW4gb2YgNiwyMDgsIHN1Z2dlc3RpbmcgdmFyaWFiaWxpdHkgaW4gdGhlIHNpemUgb2YgZHdlbGxpbmdzLiBUaGUgdmFyaWFibGUgInRheCIgc2hvd3Mgd2lkZSB2YXJpYXRpb24sIHdpdGggdmFsdWVzIHJhbmdpbmcgYmV0d2VlbiAxODcuMCBhbmQgNzExLjAuIEZ1cnRoZXJtb3JlLCAibHN0YXQiIChwZXJjZW50YWdlIG9mIHBvcHVsYXRpb24gb2YgbG93ZXIgc3RhdHVzKSBwcmVzZW50cyB2YWx1ZXMgdGhhdCB2YXJ5IGZyb20gMS43MyB0byAzNy45NywgaW5kaWNhdGluZyB0aGUgZGl2ZXJzaXR5IGluIHRoZSBzb2Npb2Vjb25vbWljIGNvbmRpdGlvbnMgb2YgdGhlIHN0dWRpZWQgYXJlYXMuIFRoZXNlIHN1bW1hcnkgc3RhdGlzdGljcyBwcm92aWRlIGFuIG92ZXJ2aWV3IG9mIHRoZSBkaXN0cmlidXRpb24gYW5kIHZhcmlhYmlsaXR5IG9mIHRoZSB2YXJpYWJsZXMsIHdoaWNoIGlzIGVzc2VudGlhbCBmb3IgYmV0dGVyIHVuZGVyc3RhbmRpbmcgdGhlIGRhdGEgc2V0IGFuZCBwbGFubmluZyBzdWJzZXF1ZW50IGFuYWx5c2VzLgoKU2luY2Ugbm8gYWJub3JtYWxpdHkgd2FzIGZvdW5kIGluIHRoZSBkYXRhLCBhIGdyYXBoaWNhbCBhbmFseXNpcyBpcyBjYXJyaWVkIG91dC4KCiMgIERhdGEgVmlzdWFsaXphdGlvbgoKIyMjIyMgLSBCdWlsZCBhdCBsZWFzdCAyIHBhaXItd2lzZWQgZ3JhcGhzIGJldHdlZW4gdGhlIGRlcGVuZGVudCB2YXJpYWJsZSBhbmQgaW5kZXBlbmRlbnQgdmFyaWFibGVzCgpgYGB7cn0KCmdncGxvdChkYXRhID0gZGF0YXNldCwgYWVzKHggPSBjcmltLCB5ID0gbWVkdikpICsKICBnZW9tX3BvaW50KGNvbG9yID0gImJsdWUiLCBhbHBoYSA9IDAuNikgKwogIGxhYnMoeCA9ICJDcmltZSBSYXRlIChjcmltKSIsIHkgPSAiTWVkaWFuIFZhbHVlIChtZWR2KSIpICsKICBnZ3RpdGxlKCJTY2F0dGVyIFBsb3Q6IE1lZGlhbiBWYWx1ZSB2cy4gQ3JpbWUgUmF0ZSIpICsKICB0aGVtZV9taW5pbWFsKCkKCgpnZ3Bsb3QoZGF0YSA9IGRhdGFzZXQsIGFlcyh4ID0gem4sIHkgPSBtZWR2KSkgKwogIGdlb21fcG9pbnQoY29sb3IgPSAicmVkIiwgYWxwaGEgPSAwLjYpICsKICBsYWJzKHggPSAiUHJvcG9ydGlvbiBvZiBSZXNpZGVudGlhbCBMYW5kIFpvbmVkICh6bikiLCB5ID0gIk1lZGlhbiBWYWx1ZSAobWVkdikiKSArCiAgZ2d0aXRsZSgiU2NhdHRlciBQbG90OiBNZWRpYW4gVmFsdWUgdnMuIFByb3BvcnRpb24gb2YgUmVzaWRlbnRpYWwgTGFuZCBab25lZCIpICsKICB0aGVtZV9taW5pbWFsKCkKCgpnZ3Bsb3QoZGF0YSA9IGRhdGFzZXQsIGFlcyh4ID0gaW5kdXMsIHkgPSBtZWR2KSkgKwogIGdlb21fcG9pbnQoY29sb3IgPSAiZ3JlZW4iLCBhbHBoYSA9IDAuNikgKwogIGxhYnMoeCA9ICJJbmR1c3RyaWFsIFpvbmUgUHJvcG9ydGlvbiAoaW5kdXMpIiwgeSA9ICJNZWRpYW4gVmFsdWUgKG1lZHYpIikgKwogIGdndGl0bGUoIlNjYXR0ZXIgUGxvdDogTWVkaWFuIFZhbHVlIHZzLiBJbmR1c3RyaWFsIFpvbmUgUHJvcG9ydGlvbiIpICsKICB0aGVtZV9taW5pbWFsKCkKCgpnZ3Bsb3QoZGF0YSA9IGRhdGFzZXQsIGFlcyh4ID0gbm94LCB5ID0gbWVkdikpICsKICBnZW9tX3BvaW50KGNvbG9yID0gImJsdWUiLCBhbHBoYSA9IDAuNikgKwogIGxhYnMoeCA9ICJOaXRyb2dlbiBPeGlkZXMgQ29uY2VudHJhdGlvbiAobm94KSIsIHkgPSAiTWVkaWFuIFZhbHVlIChtZWR2KSIpICsKICBnZ3RpdGxlKCJTY2F0dGVyIFBsb3Q6IE1lZGlhbiBWYWx1ZSB2cy4gTml0cm9nZW4gT3hpZGVzIENvbmNlbnRyYXRpb24iKSArCiAgdGhlbWVfbWluaW1hbCgpCgoKZ2dwbG90KGRhdGEgPSBkYXRhc2V0LCBhZXMoeCA9IHJtLCB5ID0gbWVkdikpICsKICBnZW9tX3BvaW50KGNvbG9yID0gInJlZCIsIGFscGhhID0gMC42KSArCiAgbGFicyh4ID0gIkF2ZXJhZ2UgTnVtYmVyIG9mIFJvb21zIChybSkiLCB5ID0gIk1lZGlhbiBWYWx1ZSAobWVkdikiKSArCiAgZ2d0aXRsZSgiU2NhdHRlciBQbG90OiBNZWRpYW4gVmFsdWUgdnMuIEF2ZXJhZ2UgTnVtYmVyIG9mIFJvb21zIikgKwogIHRoZW1lX21pbmltYWwoKQoKCmdncGxvdChkYXRhID0gZGF0YXNldCwgYWVzKHggPSBhZ2UsIHkgPSBtZWR2KSkgKwogIGdlb21fbGluZShjb2xvciA9ICJncmVlbiIsIGFscGhhID0gMC42KSArCiAgbGFicyh4ID0gIlByb3BvcnRpb24gb2YgT3duZXItT2NjdXBpZWQgVW5pdHMgQnVpbHQgQmVmb3JlIDE5NDAgKGFnZSkiLCB5ID0gIk1lZGlhbiBWYWx1ZSAobWVkdikiKSArCiAgZ2d0aXRsZSgiU2NhdHRlciBQbG90OiBNZWRpYW4gVmFsdWUgdnMuIFByb3BvcnRpb24gb2YgT3duZXItT2NjdXBpZWQgVW5pdHMgQnVpbHQgQmVmb3JlIDE5NDAiKSArCiAgdGhlbWVfbWluaW1hbCgpCgoKZ2dwbG90KGRhdGEgPSBkYXRhc2V0LCBhZXMoeCA9IGRpcywgeSA9IG1lZHYpKSArCiAgZ2VvbV9saW5lKGNvbG9yID0gInB1cnBsZSIsIGFscGhhID0gMC42KSArCiAgbGFicyh4ID0gIldlaWdodGVkIERpc3RhbmNlcyB0byBFbXBsb3ltZW50IENlbnRlcnMgKGRpcykiLCB5ID0gIk1lZGlhbiBWYWx1ZSAobWVkdikiKSArCiAgZ2d0aXRsZSgiU2NhdHRlciBQbG90OiBNZWRpYW4gVmFsdWUgdnMuIFdlaWdodGVkIERpc3RhbmNlcyB0byBFbXBsb3ltZW50IENlbnRlcnMiKSArCiAgdGhlbWVfbWluaW1hbCgpCgoKZ2dwbG90KGRhdGEgPSBkYXRhc2V0LCBhZXMoeCA9IGZhY3RvcihyYWQpLCB5ID0gbWVkdikpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICJza3libHVlIikgKwogIGxhYnMoeCA9ICJBY2Nlc3NpYmlsaXR5IHRvIFJhZGlhbCBIaWdod2F5cyAocmFkKSIsIHkgPSAiTWVkaWFuIFZhbHVlIChtZWR2KSIpICsKICBnZ3RpdGxlKCJCb3hwbG90OiBNZWRpYW4gVmFsdWUgdnMuIEFjY2Vzc2liaWxpdHkgdG8gUmFkaWFsIEhpZ2h3YXlzIikgKwogIHRoZW1lX21pbmltYWwoKQoKCmdncGxvdChkYXRhID0gZGF0YXNldCwgYWVzKHggPSBmYWN0b3IodGF4KSwgeSA9IG1lZHYpKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAibGlnaHRncmVlbiIpICsKICBsYWJzKHggPSAiUHJvcGVydHkgVGF4IFJhdGUgKHRheCkiLCB5ID0gIk1lZGlhbiBWYWx1ZSAobWVkdikiKSArCiAgZ2d0aXRsZSgiQm94cGxvdDogTWVkaWFuIFZhbHVlIHZzLiBQcm9wZXJ0eSBUYXggUmF0ZSIpICsKICB0aGVtZV9taW5pbWFsKCkKCmdncGxvdChkYXRhID0gZGF0YXNldCwgYWVzKHggPSBwdHJhdGlvLCB5ID0gbWVkdikpICsKICBnZW9tX3BvaW50KGNvbG9yID0gImJsdWUiLCBmaWxsID0gImxpZ2h0Ymx1ZSIpICsKICBsYWJzKHggPSAiUHVwaWwtVGVhY2hlciBSYXRpbyAocHRyYXRpbykiLCB5ID0gIk1lZGlhbiBWYWx1ZSAobWVkdikiKSArCiAgZ2d0aXRsZSgiRGVuc2l0eSBQbG90OiBNZWRpYW4gVmFsdWUgdnMuIFB1cGlsLVRlYWNoZXIgUmF0aW8iKSArCiAgdGhlbWVfbWluaW1hbCgpCgpnZ3Bsb3QoZGF0YSA9IGRhdGFzZXQsIGFlcyh4ID0gYiwgeSA9IG1lZHYpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJwdXJwbGUiLCBhbHBoYSA9IDAuNikgKwogIGxhYnMoeCA9ICJQcm9wb3J0aW9uIG9mIFJlc2lkZW50cyBvZiBBZnJpY2FuIEFtZXJpY2FuIERlc2NlbnQgKGIpIiwgeSA9ICJNZWRpYW4gVmFsdWUgKG1lZHYpIikgKwogIGdndGl0bGUoIlNjYXR0ZXIgUGxvdDogTWVkaWFuIFZhbHVlIHZzLiBQcm9wb3J0aW9uIG9mIFJlc2lkZW50cyBvZiBBZnJpY2FuIEFtZXJpY2FuIERlc2NlbnQgKGIpIikgKwogIHRoZW1lX21pbmltYWwoKQoKZ2dwbG90KGRhdGEgPSBkYXRhc2V0LCBhZXMoeCA9IGxzdGF0LCB5ID0gbWVkdikpICsKICBnZW9tX3BvaW50KGNvbG9yID0gIm9yYW5nZSIsIGFscGhhID0gMC42KSArCiAgbGFicyh4ID0gIlBlcmNlbnRhZ2Ugb2YgTG93ZXIgU3RhdHVzIFBvcHVsYXRpb24gKGxzdGF0KSIsIHkgPSAiTWVkaWFuIFZhbHVlIChtZWR2KSIpICsKICBnZ3RpdGxlKCJTY2F0dGVyIFBsb3Q6IE1lZGlhbiBWYWx1ZSB2cy4gUGVyY2VudGFnZSBvZiBMb3dlciBTdGF0dXMgUG9wdWxhdGlvbiAobHN0YXQpIikgKwogIHRoZW1lX21pbmltYWwoKQoKYGBgClRoZSBwcmV2aW91cyBncmFwaHMgZ2l2ZSB1cyBhbiBpZGVhIG9mIHRoZSBjb3JyZWxhdGlvbiByZWxhdGlvbnNoaXBzIGJldHdlZW4gZWFjaCBpbmRlcGVuZGVudCB2YXJpYWJsZSBhbmQgdGhlIGRlcGVuZGVudCB2YXJpYWJsZS4gVGhpcyBkb2VzIG5vdCBtZWFuIHRoYXQgdGhleSBoYXZlIGEgZGlyZWN0IGNhdXNhbCByZWxhdGlvbnNoaXAsIGJ1dCB0aGV5IGFyZSBhIHNpZ24gdGhhdCB0aGV5IGhhdmUgdGhlIHBvdGVudGlhbCB0byBiZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LCBzbyBzb21lIHZhcmlhYmxlcyB3b3VsZCBiZSBpbnRlcmVzdGluZyB0byBpbmNsdWRlIGluIGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2VzLCBmb3IgZXhhbXBsZSwgem4sbm94LCBybSBvciBJU1RBVC4KCiMjIyMjIC0gRGlzcGxheSBhIGhpc3RvZ3JhbSBvZiBkZXBlbmRlbnQgdmFyaWFibGUKCmBgYHtyfQpoaXN0KGRhdGFzZXQkbWVkdikKaGlzdChkYXRhc2V0JGNyaW0pCmhpc3QoZGF0YXNldCR6bikKaGlzdChkYXRhc2V0JGluZHVzKQpoaXN0KGRhdGFzZXQkbm94KQpoaXN0KGRhdGFzZXQkcm0pCmhpc3QoZGF0YXNldCRkaXMpCmhpc3QoZGF0YXNldCRyYWQpCmhpc3QoZGF0YXNldCR0YXgpCmhpc3QoZGF0YXNldCRwdHJhdGlvKQpoaXN0KGRhdGFzZXQkYikKaGlzdChkYXRhc2V0JGxzdGF0KQpgYGAKClRoYW5rcyB0byB0aGUgaGlzdG9ncmFtcywgd2UgY2FuIHNlZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBkYXRhIGZvciBlYWNoIHZhcmlhYmxlLCB3aGVyZSB3ZSBzZWUgdGhhdCB0aGVyZSBhcmUgc2V2ZXJhbCBzdWNoIGFzOiBjcmltLCB6biwgaW5kdXMsIGNoYXMsIG5veCwgZGl4LCByYWQsIHRheCwgcHRyYXRpbywgYiBhbmQgbHN0YXQgdGhhdCBkbyBub3QgZm9sbG93IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgdGhlcmVmb3JlIGl0IHdpbGwgYmUgaW50ZXJlc3RpbmcgdG8gYXBwbHkgcXVhZHJhdGljIG9yIGxvZ2FyaXRobWljIHRyYW5zZm9ybWF0aW9ucyB0byB0aGVzZSB2YXJpYWJsZXMgaW4gb3VyIHN1YnNlcXVlbnQgbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzZXMuCgojIyMjIyAtIERpc3BsYXkgYSBjb3JyZWxhdGlvbiBwbG90ICAKClRvIGJldHRlciB1bmRlcnN0YW5kIHRoZSBjb3JyZWxhdGlvbiByZWxhdGlvbnNoaXBzIGJldHdlZW4gdGhlIHZhcmlhYmxlcywgYSBkaWFncmFtIGFuZCBhIGNvcnJlbGF0aW9uIG1hdHJpeCB3aWxsIGJlIG1hZGUuIEl0IGlzIHZlcnkgaW1wb3J0YW50IHRvIGFuYWx5emUgdGhpcyB0byBhdm9pZCBtdWx0aWN1bGluYWxpdHkgcHJvYmxlbXMuCgoKYGBge3J9CgpkYXRhc2V0X2V4Y2xfY2hhcyA8LSBkYXRhc2V0WywgIWNvbG5hbWVzKGRhdGFzZXQpICVpbiUgYygiY2hhcyIpXQoKY29yX21hdHJpeCA8LSBjb3IoZGF0YXNldF9leGNsX2NoYXMpCmNvcnJwbG90KGNvcl9tYXRyaXgsIHR5cGUgPSAidXBwZXIiLCBvcmRlciA9ICJoY2x1c3QiLCBhZGRDb2VmLmNvbCA9ICJibGFjayIpCgoKYGBgCgpgYGB7cn0KY29yX21hdHJpeApgYGAKClRoZSBjb3JyZWxhdGlvbiBhbmFseXNpcyBiZXR3ZWVuIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXMgYW5kIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgIm1lZHYiIHNob3dzIHNldmVyYWwgaW50ZXJlc3RpbmcgcmVzdWx0cy4gQSBzdHJvbmcgcG9zaXRpdmUgY29ycmVsYXRpb24gaXMgb2JzZXJ2ZWQgYmV0d2VlbiAibWVkdiIgYW5kICJjbWVkdiwiIGluZGljYXRpbmcgdGhhdCBib3RoIHZhcmlhYmxlcyBhcmUgaGlnaGx5IHJlbGF0ZWQuIEZ1cnRoZXJtb3JlLCAicm0iIChudW1iZXIgb2Ygcm9vbXMpIGFsc28gcHJlc2VudHMgYSBzaWduaWZpY2FudCBwb3NpdGl2ZSBjb3JyZWxhdGlvbiB3aXRoICJtZWR2LCIgc3VnZ2VzdGluZyB0aGF0IGFzIHRoZSBudW1iZXIgb2Ygcm9vbXMgaW5jcmVhc2VzLCB0aGUgbWVkaWFuIGhvbWUgdmFsdWUgdGVuZHMgdG8gaW5jcmVhc2UuCgpPbiB0aGUgb3RoZXIgaGFuZCwgdGhlcmUgaXMgYSBub3RhYmxlIG5lZ2F0aXZlIGNvcnJlbGF0aW9uIGJldHdlZW4gIm1lZHYiIGFuZCAibHN0YXQiIChwZXJjZW50YWdlIG9mIHBvcHVsYXRpb24gd2l0aCBsb3cgc29jaW9lY29ub21pYyBzdGF0dXMpLCBpbmRpY2F0aW5nIHRoYXQgYXMgdGhlIHBlcmNlbnRhZ2Ugb2YgcG9wdWxhdGlvbiB3aXRoIGxvdyBzb2Npb2Vjb25vbWljIHN0YXR1cyBkZWNyZWFzZXMsIHRoZSBtZWRpYW4gdmFsdWUgb2YgdGhlIGhvdXNpbmcgdGVuZHMgdG8gaW5jcmVhc2UuIEl0IGlzIGltcG9ydGFudCB0byBtZW50aW9uIHRoYXQgbXVsdGljb2xsaW5lYXJpdHkgaXMgYWxzbyBvYnNlcnZlZCBiZXR3ZWVuIHNvbWUgaW5kZXBlbmRlbnQgdmFyaWFibGVzLCBzdWNoIGFzICJub3giIGFuZCAiaW5kdXMsIiB3aGljaCBzdWdnZXN0cyB0aGF0IHRoZXNlIHZhcmlhYmxlcyBhcmUgY29ycmVsYXRlZCB3aXRoIGVhY2ggb3RoZXIuCgoKIyBIeXBvdGhlc2VzIFN0YXRlbWVudAoKLSAtIC0gSHlwb3RoZXNpcyBvbiB0aGUgbnVtYmVyIG9mIHJvb21zIChybSk6IEl0IGlzIGJlbGlldmVkIHRoYXQgYSBncmVhdGVyIG51bWJlciBvZiByb29tcyBpbiBob21lcyB0ZW5kcyB0byBpbmNyZWFzZSB0aGUgbWVkaWFuIHByb3BlcnR5IHZhbHVlIChtZWR2KS4gVGhpcyBiZWxpZWYgaXMgYmFzZWQgb24gdGhlIGxvZ2ljIHRoYXQgbW9yZSBzcGFjaW91cyBob21lcyB0ZW5kIHRvIGhhdmUgYSBoaWdoZXIgdmFsdWUgaW4gdGhlIHJlYWwgZXN0YXRlIG1hcmtldCBkdWUgdG8gdGhlaXIgYWJpbGl0eSB0byBtZWV0IHRoZSBuZWVkcyBvZiBsYXJnZXIgZmFtaWxpZXMgb3IgcHJvdmlkZSBhZGRpdGlvbmFsIGNvbWZvcnQuCgotIC0gLSBBaXIgcXVhbGl0eSBoeXBvdGhlc2lzIChub3gpOiBJdCBpcyBhcmd1ZWQgdGhhdCBhbiBpbmNyZWFzZSBpbiB0aGUgY29uY2VudHJhdGlvbiBvZiBuaXRyb2dlbiBveGlkZSBpbiB0aGUgYWlyIChub3gpIGlzIGFzc29jaWF0ZWQgd2l0aCBhIGRlY3JlYXNlIGluIHRoZSBtZWRpYW4gaG9tZSB2YWx1ZSAobWVkdikuIFRoaXMgaHlwb3RoZXNpcyBpcyBqdXN0aWZpZWQgaW4gdGhlIGNvbnRleHQgb2YgaGVhbHRoIGFuZCB3ZWxsLWJlaW5nLCBhcyBpbmNyZWFzZWQgYWlyIHBvbGx1dGlvbiBjYW4gbWFrZSBhIGxvY2F0aW9uIGxlc3MgYXR0cmFjdGl2ZSBmb3IgaG91c2luZy4KCi0gLSAtIENyaW1lIHJhdGUgaHlwb3RoZXNpcyAoY3JpbSk6IEl0IGlzIGFyZ3VlZCB0aGF0IGFuIGluY3JlYXNlIGluIHRoZSBjcmltZSByYXRlIGluIGFuIGFyZWEgKGNyaW0pIGhhcyBhIG5lZ2F0aXZlIGltcGFjdCBvbiB0aGUgbWVkaWFuIGhvbWUgdmFsdWUgKG1lZHYpLiBUaGlzIGJlbGllZiBpcyBiYXNlZCBvbiB0aGUgcGVyY2VwdGlvbiB0aGF0IGFyZWFzIHdpdGggaGlnaCBjcmltZSByYXRlcyBtYXkgYmUgbGVzcyBzYWZlIGFuZCB0aGVyZWZvcmUgbGVzcyBkZXNpcmFibGUgdG8gbGl2ZSBpbiwgd2hpY2ggY291bGQgZGVjcmVhc2UgdGhlIGRlbWFuZCBmb3IgaG91c2luZyBhbmQsIGNvbnNlcXVlbnRseSwgaXRzIHZhbHVlcy4KCgojIFJlZ3Jlc3Npb24gQW5hbHlzaXMKCldpdGggdGhlIGV4cGxvcmF0b3J5IGFuYWx5c2lzIG9mIHRoZSBkYXRhLCB0aGUgdmFyaWFibGVzIHRoYXQgYXJlIGJlbGlldmVkIHRvIGhhdmUgdGhlIGJlc3QgcG90ZW50aWFsIHRvIG1vZGVsIHRoZSBzaXR1YXRpb24gd2lsbCBiZSBjaG9zZW4uLi4KCkxpa2V3aXNlLCBmb3IgbW9kZWxzIDIgYW5kIDMsIHRyYW5zZm9ybWF0aW9ucyB3aWxsIGJlIHVzZWQgdGhyb3VnaCB0aGUgY29uY2x1c2lvbnMgZm91bmQgaW4gdGhlIGhpc3RvZ3JhbXMgYW5kIG90aGVyIGluc2lnaHRzIGZvdW5kIGluIHRoZSBleHBsb3JhdG9yeSBhbmFseXNpcyBvZiB0aGUgZGF0YS4KCiMjIyMjIE1PREVMIDEKCmBgYHtyfQpkbW9kZWwxPC1sbShtZWR2IH4gcm0rbm94K2xzdGF0K2NyaW0rdGF4K2luZHVzLGRhdGE9ZGF0YXNldCkKc3VtbWFyeShkbW9kZWwxKQpgYGAKClRoZSBtb2RlbCBoYXMgYSBtb2RlcmF0ZSBhYmlsaXR5IHRvIGV4cGxhaW4gdmFyaWF0aW9ucyBpbiBob3VzZSBwcmljZXMsIHdpdGggYW4gYWRqdXN0ZWQgUi1zcXVhcmVkIG9mIGFwcHJveGltYXRlbHkgMC42NDguCgpBbW9uZyB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzLCAicm0iIChhdmVyYWdlIG51bWJlciBvZiByb29tcyBwZXIgaG91c2Vob2xkKSBhbmQgImxzdGF0IiAocGVyY2VudGFnZSBvZiBwb3B1bGF0aW9uIHdpdGggbG93IHN0YXR1cykgYXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuIEEgb25lLXVuaXQgaW5jcmVhc2UgaW4gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIHJvb21zIGlzIGFzc29jaWF0ZWQgd2l0aCBhbiBpbmNyZWFzZSBvZiBhYm91dCA1LDIxNCB1bml0cyBpbiB0aGUgaG91c2luZyBwcmljZSwgd2hpbGUgYSBvbmUtdW5pdCBpbmNyZWFzZSBpbiB0aGUgcGVyY2VudGFnZSBvZiB0aGUgcG9wdWxhdGlvbiB3aXRoIGxvdyBzdGF0dXMgaXMgYXNzb2NpYXRlZCB3aXRoIGEgZGVjcmVhc2Ugb2YgYWJvdXQgMC41NjEgdW5pdHMgaW4gdGhlIHByaWNlIG9mIGhvdXNpbmcuCgpUaGUgdmFyaWFibGVzICJ0YXgiIChwcm9wZXJ0eSB0YXgpLCAibm94IiAoY29uY2VudHJhdGlvbiBvZiBuaXRyb2dlbiBveGlkZXMpLCAiY3JpbSIgKGNyaW1lIHJhdGUpIGFuZCAiaW5kdXMiIChwcm9wb3J0aW9uIG9mIGFjcmVzIG9mIG5vbi1yZXRhaWwgYnVzaW5lc3NlcyBwZXIgY2l0eSkgYXJlIG5vdCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGluIHRoaXMgbW9kZWwuCgpUaGUgbW9kZWwgYXMgYSB3aG9sZSBoYXMgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IEYgdmFsdWUsIGluZGljYXRpbmcgdGhhdCBhdCBsZWFzdCBvbmUgb2YgdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlcyBpcyByZWxldmFudCBpbiBwcmVkaWN0aW5nIGhvdXNlIHByaWNlcy4KClRoZSBpbnRlcmNlcHQgaXMgbm90IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgaW4gdGhpcyBjb250ZXh0LgoKSW4gc3VtbWFyeSwgdGhlIG1vZGVsIHN1Z2dlc3RzIHRoYXQgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIHJvb21zIGFuZCB0aGUgcGVyY2VudGFnZSBvZiB0aGUgcG9wdWxhdGlvbiB3aXRoIGxvdyBzdGF0dXMgYXJlIGltcG9ydGFudCBmYWN0b3JzIGluIHByZWRpY3RpbmcgaG91c2luZyBwcmljZXMsIHdoaWxlIG90aGVyIHZhcmlhYmxlcyBkbyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbW9kZWwuIFRoZSBtb2RlbCBhcyBhIHdob2xlIGlzIGNhcGFibGUgb2YgZXhwbGFpbmluZyBhIGNvbnNpZGVyYWJsZSBwYXJ0IG9mIHRoZSB2YXJpYWJpbGl0eSBpbiBob3VzZSBwcmljZXMuCgpBbHRob3VnaCB0aGUgbW9kZWwgc2hvd3MgYSByZWxhdGl2ZWx5IGdvb2QgZml0LCBpdCBpcyBuZWNlc3NhcnkgdG8gcGVyZm9ybSBkaWFnbm9zdGljIHRlc3RzIHRvIGRldGVjdCBwcm9ibGVtcyBzdWNoIGFzIG11bHRpY3VsaW5hbGl0eSwgaGV0ZXJvY2VyYXN0aWNpdHkgb3Igbm9ybWFsaXR5IG9mIHJlc2lkdWFscy4KCiMjIyMjIERpYWdub3N0aWMgdGVzdHMgTU9ERUwgMQoKYGBge3J9CgojIE11bHRpY29sbGluZWFyaXR5Cgp2aWYoZG1vZGVsMSkKYGBgCgpTaW5jZSBubyB2YWx1ZSBleGNlZWRzIHRoZSB0aHJlc2hvbGQgb2YgMTAsIG11bHRpY3VsaW9uYWxpdHkgaXMgbm90IG9ic2VydmVkLCB0aGF0IGlzLCB0aGVyZSBpcyBubyBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXMuCgpgYGB7cn0KIyBIZXRlcm9zY2VkYXN0aWNpdHkKCmJwdGVzdChkbW9kZWwxKQpgYGAKVGhlIHAtdmFsdWUgaXMgZXh0cmVtZWx5IGxvdyAobXVjaCBsZXNzIHRoYW4gMC4wNSksIGluZGljYXRpbmcgdGhhdCB0aGVyZSBpcyB2ZXJ5IHN0cm9uZyBldmlkZW5jZSBhZ2FpbnN0IHRoZSBob21vc2NlZGFzdGljaXR5IGh5cG90aGVzaXMuIFRoZXJlZm9yZSwgdGhlcmUgaXMgZXZpZGVuY2Ugb2YgaGV0ZXJvY2VyYXN0aWNpdHkuCgpgYGB7cn0KIyBOb3JtYWxpdHkgb2YgUmVzaWR1YWxzCnFxbm9ybShkbW9kZWwxJHJlc2lkdWFscykKcXFsaW5lKGRtb2RlbDEkcmVzaWR1YWxzKQpzaGFwaXJvLnRlc3QoZG1vZGVsMSRyZXNpZHVhbHMpCmBgYAoKVGhlIFNoYXBpcm8tV2lsayBub3JtYWxpdHkgdGVzdCB5aWVsZHMgYSBwIHZhbHVlIHZlcnkgY2xvc2UgdG8gemVybyAoPCAyLjJlLTE2KSwgbGVzcyB0aGFuIHA9MC4wNS4gd2hpY2ggaW5kaWNhdGVzIHRoYXQgd2UgbXVzdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHRoZSByZXNpZHVhbHMgb2YgbW9kZWwgZG1vZGVsMSBmb2xsb3cgYSBub3JtYWwgZGlzdHJpYnV0aW9uLCBjb25jbHVkaW5nIHRoYXQgdGhlIHJlc2lkdWFscyBkbyBub3QgVGhleSBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuCgoKIyMjIyMgTU9ERUwgMgoKYGBge3J9CmRtb2RlbDI8LWxtKGxvZyhtZWR2KSB+IHJtK25veCtsc3RhdCtjcmltK3RheCtpbmR1cyxkYXRhPWRhdGFzZXQpCnN1bW1hcnkoZG1vZGVsMikKCmBgYAoKVGhlIG1vZGVsIGFjaGlldmVzIGEgbW9kZXJhdGUgYWJpbGl0eSB0byBleHBsYWluIHZhcmlhdGlvbnMgaW4gdGhlIGxvZ2FyaXRobSBvZiBob3VzZSBwcmljZXMsIHdpdGggYW4gYWRqdXN0ZWQgUi1zcXVhcmVkIG9mIGFwcHJveGltYXRlbHkgMC43MjEuCgpPZiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzLCAicm0iIChhdmVyYWdlIG51bWJlciBvZiByb29tcyBwZXIgaG9tZSkgYW5kICJsc3RhdCIgKHBlcmNlbnRhZ2Ugb2YgcG9wdWxhdGlvbiB3aXRoIGxvdyBzdGF0dXMpIGFyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LiBBIG9uZS11bml0IGluY3JlYXNlIGluIHRoZSBhdmVyYWdlIG51bWJlciBvZiBiZWRyb29tcyBpcyBhc3NvY2lhdGVkIHdpdGggYW4gaW5jcmVhc2UgaW4gdGhlIGxvZyBob3VzZSBwcmljZSBieSBhcHByb3hpbWF0ZWx5IDAuMzE1IHVuaXRzLCB3aGlsZSBhIG9uZS11bml0IGluY3JlYXNlIGluIHRoZSBwZXJjZW50YWdlIG9mIHRoZSBwb3B1bGF0aW9uIHdpdGggbG93IHN0YXR1cyBpcyBhc3NvY2lhdGVkIHdpdGggYSBkZWNyZWFzZSBpbiB0aGUgbG9nIG9mIHRoZSBob3VzZSBwcmljZSBieSBhcHByb3hpbWF0ZWx5IDAuMDQ3IHVuaXRzLgoKVGhlIHZhcmlhYmxlcyAibm94IiAoY29uY2VudHJhdGlvbiBvZiBuaXRyb2dlbiBveGlkZXMpLCAiY3JpbSIgKGNyaW1lIHJhdGUpLCAidGF4IiAocHJvcGVydHkgdGF4KSwgYW5kICJpbmR1cyIgKHByb3BvcnRpb24gb2Ygbm9uLXJldGFpbCBidXNpbmVzcyBhY3JlcyBwZXIgY2l0eSkgYXJlIG5vdCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGluIHRoaXMgbW9kZWwuCgpUaGUgbW9kZWwgYXMgYSB3aG9sZSBoYXMgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IEYgdmFsdWUsIGluZGljYXRpbmcgdGhhdCBhdCBsZWFzdCBvbmUgb2YgdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlcyBpcyByZWxldmFudCBpbiBwcmVkaWN0aW5nIHRoZSBsb2dhcml0aG0gb2YgaG91c2UgcHJpY2VzLgoKVGhlIGludGVyY2VwdCBpcyBub3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBpbiB0aGlzIGNvbnRleHQuCgpJbiBzdW1tYXJ5LCB0aGUgc2Vjb25kIG1vZGVsIHN1Z2dlc3RzIHRoYXQgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIHJvb21zIGFuZCB0aGUgcGVyY2VudGFnZSBvZiBwb3B1bGF0aW9uIHdpdGggbG93IHN0YXR1cyBhcmUgaW1wb3J0YW50IGZhY3RvcnMgaW4gcHJlZGljdGluZyB0aGUgbG9nYXJpdGhtIG9mIGhvdXNlIHByaWNlcywgd2hpbGUgb3RoZXIgdmFyaWFibGVzIGRvIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBtb2RlbC4gVGhlIG1vZGVsIGFzIGEgd2hvbGUgaXMgYWJsZSB0byBleHBsYWluIGEgY29uc2lkZXJhYmxlIHBhcnQgb2YgdGhlIHZhcmlhYmlsaXR5IGluIHRoZSBsb2dhcml0aG0gb2YgaG91c2UgcHJpY2VzLgoKIyMjIyMgRGlhZ25vc3RpYyB0ZXN0cyBNT0RFTCAyCgpgYGB7cn0KIyBNdWx0aWNvbGxpbmVhcml0eQoKdmlmKGRtb2RlbDIpCmBgYAoKU2luY2Ugbm8gdmFsdWUgZXhjZWVkcyB0aGUgdGhyZXNob2xkIG9mIDEwLCBtdWx0aWN1bGlvbmFsaXR5IGlzIG5vdCBvYnNlcnZlZCwgdGhhdCBpcywgdGhlcmUgaXMgbm8gY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzLgoKYGBge3J9CiMgSGV0ZXJvc2NlZGFzdGljaXR5CgpicHRlc3QoZG1vZGVsMikKYGBgClRoZSBzdHVkZW50aXplZCBCcmV1c2NoLVBhZ2FuIHRlc3QgeWllbGRzIGFuIGV4dHJlbWVseSBsb3cgcC12YWx1ZSAoMS41MThlLTA3KSwgd2hpY2ggbGVhZHMgdXMgdG8gc3Ryb25nbHkgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgb2YgaG9tb3NjZWRhc3RpY2l0eSBpbiB0aGUgZG1vZGVsMiBtb2RlbC4gV2l0aCBzdWNoIGEgbG93IHAgdmFsdWUsIHdlIGNhbiBzdHJvbmdseSBjb25jbHVkZSB0aGF0IGhldGVyb3NrZWRhc3RpY2l0eSBleGlzdHMgaW4gdGhlIG1vZGVsIHJlc2lkdWFscy4gVGhlIHNpZ25pZmljYW5jZSBsZXZlbCBpcyBtdWNoIGxvd2VyIHRoYW4gMC4wNSwgd2hpY2ggcmVpbmZvcmNlcyB0aGlzIGNvbmNsdXNpb24uCgoKYGBge3J9CiMgTm9ybWFsaXR5IG9mIFJlc2lkdWFscwpxcW5vcm0oZG1vZGVsMiRyZXNpZHVhbHMpCnFxbGluZShkbW9kZWwyJHJlc2lkdWFscykKc2hhcGlyby50ZXN0KGRtb2RlbDIkcmVzaWR1YWxzKQpgYGAKCgpUaGUgU2hhcGlyby1XaWxrIG5vcm1hbGl0eSB0ZXN0IHNob3dzIGFuIGV4dHJlbWVseSBsb3cgcC12YWx1ZSAoMS4xNjRlLTEyKSwgbGVzcyB0aGFuIFA9MC4wNS4gaW5kaWNhdGluZyB0aGF0IHRoZSByZXNpZHVhbHMgZnJvbSB0aGUgZG1vZGVsMiBtb2RlbCBkbyBub3QgZm9sbG93IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gVGhlcmVmb3JlLCB3ZSBjYW4gc3Ryb25nbHkgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGUgcmVzaWR1YWxzIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZC4gVGhpcyByZXN1bHQgc3VnZ2VzdHMgdGhhdCB0aGUgbW9kZWwgZG9lcyBub3QgbWVldCB0aGUgYXNzdW1wdGlvbiBvZiBub3JtYWxpdHkgb2YgZXJyb3JzLgoKIyMjIyMgTU9ERUwgMwoKYGBge3J9CmRtb2RlbDM8LWxtKGxvZyhtZWR2KSB+ICtJKGNtZWR2XjIpK25veCtybStub3grbHN0YXQrY3JpbSxkYXRhPWRhdGFzZXQpCnN1bW1hcnkoZG1vZGVsMykgCmBgYApUaGUgbW9kZWwgaGFzIGEgaGlnaCBjYXBhY2l0eSB0byBleHBsYWluIHZhcmlhdGlvbnMgaW4gdGhlIGxvZ2FyaXRobSBvZiBob3VzZSBwcmljZXMsIHdpdGggYW4gYWRqdXN0ZWQgUi1zcXVhcmVkIG9mIGFwcHJveGltYXRlbHkgMC44ODk4LgoKT2YgdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlcywgIkkoY21lZHZeMikiIChhIHF1YWRyYXRpYyB0cmFuc2Zvcm1hdGlvbiBvZiB0aGUgYXZlcmFnZSBob3VzZSBwcmljZSksICJub3giIChjb25jZW50cmF0aW9uIG9mIG5pdHJvZ2VuIG94aWRlcyksICJybSIgKGF2ZXJhZ2UgbnVtYmVyIG9mIHJvb21zIHBlciBob3VzZSksICJsc3RhdCAiIChwZXJjZW50YWdlIG9mIHBvcHVsYXRpb24gd2l0aCBsb3cgc3RhdHVzKSBhbmQgImNyaW0iIChjcmltZSByYXRlKSBhcmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4KClRoZSBjb2VmZmljaWVudCBvZiAiSShjbWVkdl4yKSIgaXMgcG9zaXRpdmUsIHN1Z2dlc3RpbmcgYSBwb3NpdGl2ZSBxdWFkcmF0aWMgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHRyYW5zZm9ybWVkIHZhcmlhYmxlIGFuZCB0aGUgbG9nYXJpdGhtIG9mIGhvdXNlIHByaWNlcy4KClRoZSBpbnRlcmNlcHQgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBhbmQgaGFzIGEgcG9zaXRpdmUgdmFsdWUsIGluZGljYXRpbmcgYSBiYXNlIHZhbHVlIGluIHRoZSBsb2dhcml0aG0gb2YgaG91c2UgcHJpY2VzLgoKT3ZlcmFsbCwgdGhlIG1vZGVsIGFzIGEgd2hvbGUgaXMgaGlnaGx5IHNpZ25pZmljYW50LCB3aXRoIGEgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBGIHZhbHVlLgoKVGhlIG1vZGVsIGhhcyBhIGdvb2QgZml0IHRvIHRoZSBkYXRhLCB3aXRoIGEgbG93IHJlc2lkdWFsIHN0YW5kYXJkIGVycm9yIG9mIGFwcHJveGltYXRlbHkgMC4xMzYzLgoKIyMjIyMgRGlhZ25vc3RpYyB0ZXN0cyBNT0RFTCAzCgpgYGB7cn0KIyBNdWx0aWNvbGxpbmVhcml0eQoKdmlmKGRtb2RlbDMpCmBgYApTaW5jZSBubyB2YWx1ZSBleGNlZWRzIHRoZSB0aHJlc2hvbGQgb2YgMTAsIG11bHRpY3VsaW9uYWxpdHkgaXMgbm90IG9ic2VydmVkLCB0aGF0IGlzLCB0aGVyZSBpcyBubyBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXMuCgoKYGBge3J9CiMgSGV0ZXJvc2NlZGFzdGljaXR5CgpicHRlc3QoZG1vZGVsMykKYGBgCgpUaGUgQnJldXNjaC1QYWdhbiB0ZXN0IHlpZWxkcyBhIHAtdmFsdWUgdmVyeSBjbG9zZSB0byB6ZXJvIChwLXZhbHVlIDwgMi4yZS0xNiksIGxlc3MgdG8gcD0wLjA1LiBJbmRpY2F0aW5nIHN0cm9uZyBldmlkZW5jZSBhZ2FpbnN0IHRoZSBudWxsIGh5cG90aGVzaXMgb2YgaG9tb3NjZWRhc3RpY2l0eS4gVGhlcmVmb3JlLCB3ZSBjYW4gY29uY2x1ZGUgdGhhdCB0aGVyZSBpcyBoZXRlcm9zY2VkYXN0aWNpdHkgaW4gdGhlIGRtb2RlbDMgbW9kZWwsIHdoaWNoIHN1Z2dlc3RzIHRoYXQgdGhlIGVycm9yIHZhcmlhbmNlIGlzIG5vdCBjb25zdGFudCBpbiBhbGwgb2JzZXJ2YXRpb25zIGFuZCB0aGF0IHRoZXJlIGNvdWxkIGJlIGRpc3BlcnNpb24gcHJvYmxlbXMgaW4gdGhlIG1vZGVsLgoKCmBgYHtyfQojIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMKcXFub3JtKGRtb2RlbDMkcmVzaWR1YWxzKQpxcWxpbmUoZG1vZGVsMyRyZXNpZHVhbHMpCnNoYXBpcm8udGVzdChkbW9kZWwzJHJlc2lkdWFscykKYGBgCgpUaGUgU2hhcGlyby1XaWxrIG5vcm1hbGl0eSB0ZXN0IHlpZWxkcyBhbiBleHRyZW1lbHkgbG93IHAtdmFsdWUgKHAtdmFsdWUgPSAxLjk3MmUtMTQpLCBpbmRpY2F0aW5nIHN0cm9uZyBldmlkZW5jZSBhZ2FpbnN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGUgcmVzaWR1YWxzIGZvbGxvdyBhIG5vcm1hbCBkaXN0cmlidXRpb24uIFRoZXJlZm9yZSwgd2UgY2FuIGNvbmNsdWRlIHRoYXQgdGhlIHJlc2lkdWFscyBkbyBub3QgZm9sbG93IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgc3VnZ2VzdGluZyB0aGF0IHRoZSBhc3N1bXB0aW9uIG9mIG5vcm1hbGl0eSBvZiB0aGUgZXJyb3JzIGluIHRoZSBtb2RlbCBtYXkgbm90IGJlIGFkZXF1YXRlbHkgbWV0LiBJdCBpcyBpbXBvcnRhbnQgdG8ga2VlcCB0aGlzIG5vbi1ub3JtYWxpdHkgaW4gbWluZCB3aGVuIGludGVycHJldGluZyBtb2RlbCByZXN1bHRzIGFuZCBjb25zaWRlcmluZyBwb3NzaWJsZSBhZGp1c3RtZW50cyBvciB0cmFuc2Zvcm1hdGlvbnMgb2YgdGhlIGRhdGEgaWYgbmVjZXNzYXJ5LgoKYGBge3J9CkFJQyhkbW9kZWwxKQpBSUMoZG1vZGVsMikKQUlDKGRtb2RlbDMpCmBgYAoKIyMjIyMgTW9kZWwgU2VsZWN0aW9uCgpUaGUgbW9kZWxzIHByZXNlbnRlZCBwcm9ibGVtcyBvZiBub3JtYWxpdHkgYW5kIGhldGVyb2NlcmFzdGljaXR5LCB3aGljaCBpcyB3aHkgaXQgaXMgaW1wb3J0YW50IHRvIGNvbnRpbnVlIG1ha2luZyBkYXRhIHRyYW5zZm9ybWF0aW9ucyBhbmQgYXBwbHkgb3RoZXIgcmVndWxhcml6YXRpb24gbWV0aG9kcyB0byBhY2hpZXZlIGEgbW9yZSBwcmVjaXNlIGFuZCByZWxpYWJsZSBtb2RlbCBmb3IgcHJlZGljdGlvbnMuIE9uIHRoZSBvdGhlciBoYW5kLCBiZWNhdXNlIG1vc3Qgb2YgdGhlIHZhcmlhYmxlcyBhcmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgaGF2ZSBhIGhpZ2hlciByLXNxdWFyZWQgdmFsdWUsIGRvIG5vdCBwcmVzZW50IG11bHRpY3VsaW5hbGl0eSBhbmQgaGF2ZSBhIGxvd2VyIEFJQyB2YWx1ZSwgbW9kZWwgMyBpcyBjaG9zZW4gYXMgdGhlIGJlc3Qgb3B0aW9uIHRvIGZpdCBvdXIgbmVlZHMuIGRhdGEuIEl0IGlzIGFsc28gaW1wb3J0YW50IHRvIG1lbnRpb24gdGhhdCBoZXRlcm9jZXJhc3RpY2l0eSBpcyBhIHByb2JsZW0gaW5oZXJlbnQgdG8gdGhlIG5hdHVyZSBvZiB0aGUgZGF0YSwgc2luY2UgZGF0YSBmcm9tIG9uZSBwb2ludCBpbiB0aW1lIGZyb20gdmFyaW91cyBVUyBzdGF0ZXMgYXJlIGJlaW5nIHN0dWRpZWQsIHRoZXJlZm9yZSB0aGUgdmFyaWFuY2VzIHdpbGwgZGlmZmVyIHdoZW4gc3R1ZHlpbmcgbWFueSBncm91cHMgb2YgZGF0YSB3aXRoIGNoYXJhY3RlcmlzdGljcyBkaWZmZXJlbnQuCgojIyMgTW9kZWwgaW50ZXJwcmV0YXRpb24KClRoZSBtb2RlbCBoYXMgYSBoaWdoIGNhcGFjaXR5IHRvIGV4cGxhaW4gdmFyaWF0aW9ucyBpbiB0aGUgbG9nYXJpdGhtIG9mIGhvdXNlIHByaWNlcywgd2l0aCBhbiBhZGp1c3RlZCBSLXNxdWFyZWQgb2YgYXBwcm94aW1hdGVseSAwLjg4OTguCgpPZiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzLCAiSShjbWVkdl4yKSIgKGEgcXVhZHJhdGljIHRyYW5zZm9ybWF0aW9uIG9mIHRoZSBhdmVyYWdlIGhvdXNlIHByaWNlKSwgIm5veCIgKGNvbmNlbnRyYXRpb24gb2Ygbml0cm9nZW4gb3hpZGVzKSwgInJtIiAoYXZlcmFnZSBudW1iZXIgb2Ygcm9vbXMgcGVyIGhvdXNlKSwgImxzdGF0ICIgKHBlcmNlbnRhZ2Ugb2YgcG9wdWxhdGlvbiB3aXRoIGxvdyBzdGF0dXMpIGFuZCAiY3JpbSIgKGNyaW1lIHJhdGUpIGFyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LgoKVGhlIGNvZWZmaWNpZW50IG9mICJJKGNtZWR2XjIpIiBpcyBwb3NpdGl2ZSwgc3VnZ2VzdGluZyBhIHBvc2l0aXZlIHF1YWRyYXRpYyByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdHJhbnNmb3JtZWQgdmFyaWFibGUgYW5kIHRoZSBsb2dhcml0aG0gb2YgaG91c2UgcHJpY2VzLgoKVGhlIGludGVyY2VwdCBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGFuZCBoYXMgYSBwb3NpdGl2ZSB2YWx1ZSwgaW5kaWNhdGluZyBhIGJhc2UgdmFsdWUgaW4gdGhlIGxvZ2FyaXRobSBvZiBob3VzZSBwcmljZXMuCgpPdmVyYWxsLCB0aGUgbW9kZWwgYXMgYSB3aG9sZSBpcyBoaWdobHkgc2lnbmlmaWNhbnQsIHdpdGggYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IEYgdmFsdWUuCgpUaGUgbW9kZWwgaGFzIGEgZ29vZCBmaXQgdG8gdGhlIGRhdGEsIHdpdGggYSBsb3cgcmVzaWR1YWwgc3RhbmRhcmQgZXJyb3Igb2YgYXBwcm94aW1hdGVseSAwLjEzNjMuCgotIENvZWZmaWNpZW50IGludGVycHJldGF0aW9uczoKCi0gLSAtIEludGVjZXB0ICgzLjMzMmUrMDApOiBJZiBhbGwgcHJlZGljdG9yIHZhcmlhYmxlcyBhcmUgemVybywgdGhlIGxvZ2FyaXRobSBvZiB0aGUgYXZlcmFnZSBob21lIHZhbHVlIGlzIGVzdGltYXRlZCBhdCAzLjMzMi4KLSAtIC0gSShjbWVkdl4yKSAoNC44MjBlLTA0KTogRm9yIGV2ZXJ5IG9uZS11bml0IGluY3JlYXNlIGluIHRoZSBzcXVhcmUgb2YgY21lZHYsIHRoZSBsb2dhcml0aG0gb2YgbWVkdiBpbmNyZWFzZXMgYnkgYXBwcm94aW1hdGVseSAwLjAwMDQ4Mi4gSXQgaXMgaGlnaGx5IHNpZ25pZmljYW50IHdpdGggYSBwIHZhbHVlIDwgMmUtMTYuCi0gLSAtIG5veCAoLTEuODUxZS0wMSk6IEZvciBldmVyeSBvbmUgdW5pdCBpbmNyZWFzZSBpbiBub3gsIHRoZSBsb2dhcml0aG0gb2YgbWVkdiBkZWNyZWFzZXMgYnkgYXBwcm94aW1hdGVseSAwLjE4NTEuIEl0IGlzIHNpZ25pZmljYW50IHdpdGggYSBwIHZhbHVlIG9mIDAuMDA1NzEuCi0gLSAtIHJtICgtMy4yOTRlLTAyKTogRm9yIGV2ZXJ5IG9uZS1yb29tIGluY3JlYXNlIGluIHJtLCB0aGUgbG9nYXJpdGhtIG9mIG1lZHYgZGVjcmVhc2VzIGJ5IGFwcHJveGltYXRlbHkgMC4wMzI5NC4gSXQgaXMgc2lnbmlmaWNhbnQgd2l0aCBhIHAgdmFsdWUgb2YgMC4wMDk2Mi4KLSAtIC0gbHN0YXQgKC0xLjg4MGUtMDIpOiBGb3IgZXZlcnkgb25lLXVuaXQgaW5jcmVhc2UgaW4gbHN0YXQsIHRoZSBsb2dhcml0aG0gb2YgbWVkdiBkZWNyZWFzZXMgYnkgYXBwcm94aW1hdGVseSAwLjAxODguIEl0IGlzIGhpZ2hseSBzaWduaWZpY2FudCB3aXRoIGEgcCB2YWx1ZSA8IDJlLTE2LgotIC0gLSBjcmltICgtOS43MDJlLTAzKTogRm9yIGV2ZXJ5IG9uZSB1bml0IGluY3JlYXNlIGluIHRoZSBjcmltZSByYXRlLCB0aGUgbG9nIG9mIG1lZHYgZGVjcmVhc2VzIGJ5IGFwcHJveGltYXRlbHkgMC4wMDk3MDIuIEl0IGlzIGhpZ2hseSBzaWduaWZpY2FudCB3aXRoIGEgcCB2YWx1ZSA8IDJlLTE2LgoKCmBgYHtyfQojIExBU1NPIHJlZ3Jlc3Npb24gdmlhIGdsbW5ldCBwYWNrYWdlIGNhbiBvbmx5IHRha2UgbnVtZXJpY2FsIG9ic2VydmF0aW9ucy4gVGhlbiwgdGhlIGRhdGFzZXQgaXMgdHJhbnNmb3JtZWQgdG8gbW9kZWwubWF0cml4KCkgZm9ybWF0LiAKIyBJbmRlcGVuZGVudCB2YXJpYWJsZXMKeDwtbW9kZWwubWF0cml4KGxvZyhtZWR2KSB+IHJtK25veCtsc3RhdCtjcmltLGRhdGFzZXQpWywtMV0gIyMjIE9MUyBtb2RlbCBzcGVjaWZpY2F0aW9uCiMgeDwtbW9kZWwubWF0cml4KFdlZWtseV9TYWxlc34uLHRyYWluLmRhdGEpWywtMV0gIyMjIG1hdHJpeCBvZiBpbmRlcGVuZGVudCB2YXJpYWJsZXMgWCdzCnk8LWRhdGFzZXQkbWVkdiAjIyMgZGVwZW5kZW50IHZhcmlhYmxlIAoKIyBJbiBlc3RpbWF0aW5nIExBU1NPIHJlZ3Jlc3Npb24gaXQgaXMgaW1wb3J0YW50IHRvIGRlZmluZSB0aGUgbGFtYmRhIHRoYXQgbWluaW1pemVzIHRoZSBwcmVkaWN0aW9uIGVycm9yIHJhdGUuIAojIENyb3NzLXZhbGlkYXRpb24gZW5zdXJlcyB0aGF0IGV2ZXJ5IGRhdGEgLyBvYnNlcnZhdGlvbiBmcm9tIHRoZSBvcmlnaW5hbCBkYXRhc2V0IChkYXRhaW5zKSBoYXMgYSBjaGFuY2Ugb2YgYXBwZWFyaW5nIGluIHRyYWluIGFuZCB0ZXN0IGRhdGFzZXRzLgojIEZpbmQgdGhlIGJlc3QgbGFtYmRhIHVzaW5nIGNyb3NzLXZhbGlkYXRpb24uCnNldC5zZWVkKDEyMykgCmN2Lmxhc3NvPC1jdi5nbG1uZXQoeCx5LGFscGhhPTEpICMgYWxwaGEgPSAxIGZvciBMQVNTTwoKIyBEaXNwbGF5IHRoZSBiZXN0IGxhbWJkYSB2YWx1ZQpjdi5sYXNzbyRsYW1iZGEubWluICAgICAgICAgICAgICAgICAgICAgICMjIyBsYW1iZGE6IGEgbnVtZXJpYyB2YWx1ZSBkZWZpbmluZyB0aGUgYW1vdW50IG9mIHNocmlua2FnZS4gV2h5IG1pbj8gdGhlIGhpZ2hlciB0aGUgdmFsdWUgb2YgPz8gLCB0aGUgbW9yZSBwZW5hbGl6YXRpb24gdGhlcmUgaXMKCiMgRml0IHRoZSBmaW5hbCBtb2RlbCBvbiB0aGUgdHJhaW5pbmcgZGF0YQpsYXNzb21vZGVsPC1nbG1uZXQoeCx5LGFscGhhPTEsbGFtYmRhPWN2Lmxhc3NvJGxhbWJkYS5taW4pCgojIERpc3BsYXkgcmVncmVzc2lvbiBjb2VmZmljaWVudHMKY29lZihsYXNzb21vZGVsKQoKIyBNYWtlIHByZWRpY3Rpb25zIG9uIHRoZSB0ZXN0IGRhdGEKeC50ZXN0PC1tb2RlbC5tYXRyaXgobG9nKG1lZHYpIH4gcm0rbm94K2xzdGF0K2NyaW0sZGF0YXNldClbLC0xXSAjIyMgT0xTIG1vZGVsIHNwZWNpZmljYXRpb24KIyB4LnRlc3Q8LW1vZGVsLm1hdHJpeChXZWVrbHlfU2FsZXN+Lix0ZXN0LmRhdGEpWywtMV0KbGFzc29wcmVkaWN0aW9ucyA8LSBsYXNzb21vZGVsICU+JSBwcmVkaWN0KHgudGVzdCkgJT4lIGFzLnZlY3RvcigpCgoKIyMjIHZpc3VhbGl6aW5nIGxhc3NvIHJlZ3Jlc3Npb24gcmVzdWx0cyAKbGJzX2Z1biA8LSBmdW5jdGlvbihmaXQsIG9mZnNldF94PTEsIC4uLikgewogIEwgPC0gbGVuZ3RoKGZpdCRsYW1iZGEpCiAgeCA8LSBsb2coZml0JGxhbWJkYVtMXSkrIG9mZnNldF94CiAgeSA8LSBmaXQkYmV0YVssIExdCiAgbGFicyA8LSBuYW1lcyh5KQogIHRleHQoeCwgeSwgbGFiZWxzPWxhYnMsIC4uLikKfQoKbGFzc288LWdsbW5ldChzY2FsZSh4KSx5LGFscGhhPTEpCgpwbG90KGxhc3NvLHh2YXI9ImxhbWJkYSIsbGFiZWw9VCkKbGJzX2Z1bihsYXNzbykKYWJsaW5lKHY9Y3YubGFzc28kbGFtYmRhLm1pbixjb2w9InJlZCIsbHR5PTIpCmFibGluZSh2PWN2Lmxhc3NvJGxhbWJkYS4xc2UsY29sPSJibHVlIixsdHk9MikKCnN1bW1hcnkobGFzc29tb2RlbCkKCmBgYAotIC0gLSBJbnRlcmNlcHQ6IFRoZSBpbnRlcmNlcHQgdmFsdWUgaXMgYXBwcm94aW1hdGVseSAtMS43NDQuIFRoaXMgcmVwcmVzZW50cyB0aGUgZXN0aW1hdGVkIHZhbHVlIG9mIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgKG1lZHYpIHdoZW4gYWxsIGluZGVwZW5kZW50IHZhcmlhYmxlcyBhcmUgZXF1YWwgdG8gemVyby4KCi0gLSAtIENvZWZmaWNpZW50cyBvZiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzOiBUaGUgbW9kZWwgaGFzIGlkZW50aWZpZWQgdGhyZWUgc2lnbmlmaWNhbnQgdmFyaWFibGVzIGluIHByZWRpY3RpbmcgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSAobWVkdikuIFRoZXNlIGFyZSAicm0iIChudW1iZXIgb2Ygcm9vbXMpLCAibHN0YXQiIChwZXJjZW50YWdlIG9mIGxvdy1zdGF0dXMgcG9wdWxhdGlvbiksIGFuZCAiY3JpbSIgKGNyaW1lIHJhdGUpLiBUaGUgbWFnbml0dWRlIG9mIHRoZXNlIGNvZWZmaWNpZW50cyBpbmRpY2F0ZXMgdGhlaXIgaW1wYWN0IG9uIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUuIEZvciBleGFtcGxlLCBhIG9uZSB1bml0IGluY3JlYXNlIGluICJybSIgcmVzdWx0cyBpbiBhbiBpbmNyZWFzZSBvZiBhcHByb3hpbWF0ZWx5IDUuMDcgdW5pdHMgaW4gbWVkdiwgaG9sZGluZyB0aGUgb3RoZXIgdmFyaWFibGVzIGNvbnN0YW50LgoKLSAtIC0gVmFyaWFibGUgIm5veCIgKG5pdHJvZ2VuIG94aWRlKTogVGhlIGNvZWZmaWNpZW50IGZvciAibm94IiBpcyBtYXJrZWQgIi4iLiBUaGlzIG1lYW5zIHRoYXQgdGhlIG1vZGVsIGhhcyBjb25zaWRlcmVkIHRoYXQgdGhpcyB2YXJpYWJsZSBkb2VzIG5vdCBoYXZlIGEgc2lnbmlmaWNhbnQgaW1wYWN0IG9uIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgYWZ0ZXIgTDEgcmVndWxhcml6YXRpb24uCgotIC0gLSBNb2RlbCBkaW1lbnNpb246IFRoZSBtb2RlbCBoYXMgZXN0aW1hdGVkIGZvdXIgbm9uLW51bGwgY29lZmZpY2llbnRzIChkZikgYW5kIGEgY29uc3RhbnQgdGVybSwgd2hpY2ggbWVhbnMgdGhhdCBpdCBjb25zaWRlcnMgZm91ciBpbmRlcGVuZGVudCB2YXJpYWJsZXMgYXMgcmVsZXZhbnQgZm9yIHRoZSBwcmVkaWN0aW9uIG9mIG1lZHYuCgojIyMjIyBTZXJpYWwgQXV0b2NvcnJlbGF0aW9uCgpTaW5jZSB3ZSBhcmUgd29ya2luZyB3aXRoIGEgZGF0YWJhc2UgdGhhdCBjb2xsZWN0cyBpbmZvcm1hdGlvbiBvbiB0aGUgdmFsdWUgb2YgaG9tZXMgYXQgYSBzcGVjaWZpYyBwb2ludCBpbiB0aW1lLCB0aGV5IGFyZSBjcm9zcy1zZWN0aW9uYWwgZGF0YSBhbmQgdGhlcmVmb3JlIGRvIG5vdCBoYXZlIHNlcmlhbCBhdXRvY29ycmVsYXRpb24uCgoKIyBSZXN1bHRzIERpc2N1c3Npb24KCkluIHN1bW1hcnksIHRoZSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbHMgdGhhdCB3ZXJlIGRldmVsb3BlZCB0byBwcmVkaWN0IHByb3BlcnR5IG1lZGlhbiB2YWx1ZSAobWVkdikgcHJlc2VudGVkIHNpZ25pZmljYW50IGNoYWxsZW5nZXMgcmVsYXRlZCB0byBub3JtYWxpdHkgb2YgcmVzaWR1YWxzIGFuZCBoZXRlcm9za2VkYXN0aWNpdHkuIFRoZXNlIGlzc3VlcyBzdWdnZXN0IHRoYXQgdGhlIHVuZGVybHlpbmcgYXNzdW1wdGlvbnMgb2YgY2xhc3NpY2FsIGxpbmVhciByZWdyZXNzaW9uIG1heSBub3QgYmUgZnVsbHkgbWV0IGluIHRoaXMgZGF0YSBzZXQuIEFzIGEgcmVzdWx0LCBkYXRhIHRyYW5zZm9ybWF0aW9ucyB3ZXJlIGFwcGxpZWQgYW5kIHJlZ3VsYXJpemF0aW9uIG1ldGhvZHMsIHN1Y2ggYXMgdGhlIExhc3NvIG1vZGVsLCB3ZXJlIGV4cGxvcmVkIHRvIGFkZHJlc3MgdGhlc2UgbGltaXRhdGlvbnMgYW5kIGltcHJvdmUgcHJlZGljdGlvbiBhY2N1cmFjeS4KCkluIHBhcnRpY3VsYXIsIHRoZSBMYXNzbyBtb2RlbCBzaG93ZWQgYSBwZW5hbHR5IGNvZWZmaWNpZW50IChsYW1iZGEpIG9mIDAuMTQ5LCBpbmRpY2F0aW5nIHRoYXQgdGhlIG1vZGVsIHBlbmFsaXplcyB0aGUgcHJlZGljdG9yIHZhcmlhYmxlcyB0byBzb21lIGV4dGVudC4gVGhpcyBzdWdnZXN0cyB0aGF0IHNvbWUgb2YgdGhlIGZlYXR1cmVzIG1heSBub3QgY29udHJpYnV0ZSBzaWduaWZpY2FudGx5IHRvIHRoZSBtZWR2IHByZWRpY3Rpb24gYW5kIGNvdWxkIGJlIHJlbW92ZWQgdG8gc2ltcGxpZnkgdGhlIG1vZGVsIHdpdGhvdXQgc2lnbmlmaWNhbnQgbG9zcyBvZiBhY2N1cmFjeS4gSW4gYWRkaXRpb24sIGl0IHdhcyBvYnNlcnZlZCB0aGF0IHRoZSB2YXJpYWJsZXMgInJtIiAobnVtYmVyIG9mIHJvb21zKSwgIm5veCIgKGNvbmNlbnRyYXRpb24gb2Ygbml0cm9nZW4gb3hpZGUgaW4gdGhlIGFpcikgYW5kICJsc3RhdCIgKHBlcmNlbnRhZ2Ugb2YgbG93LXN0YXR1cyBwb3B1bGF0aW9uKSBoYWQgc2lnbmlmaWNhbnQgY29lZmZpY2llbnRzIGluIHRoZSBMYXNzbyBtb2RlbCwgd2hpY2ggaW5kaWNhdGluZyBpdHMgaW1wb3J0YW5jZSBpbiBwcmVkaWN0aW5nIHRoZSBtZWRpYW4gdmFsdWUgb2YgdGhlIHByb3BlcnRpZXMuCgpEZXNwaXRlIHRoZSBjaGFsbGVuZ2VzIG9mIG5vcm1hbGl0eSBhbmQgaGV0ZXJvc2NlZGFzdGljaXR5LCBtdWx0aXBsZSBsaW5lYXIgcmVncmVzc2lvbiBNb2RlbCAzIHdhcyBzZWxlY3RlZCBhcyB0aGUgYmVzdCBvcHRpb24gZHVlIHRvIGl0cyBoaWdoZXIgUi1zcXVhcmVkLCBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2Ugb2YgdGhlIHByZWRpY3RvciB2YXJpYWJsZXMsIGxhY2sgb2YgbXVsdGljb2xsaW5lYXJpdHksIGFuZCBsb3dlciBBSUMgdmFsdWUuIFRoaXMgc3VnZ2VzdHMgdGhhdCwgYWx0aG91Z2ggdGhlIGRhdGEgcHJlc2VudCBjZXJ0YWluIHByb2JsZW1zLCBNb2RlbCAzIHByb3ZpZGVzIGEgc29saWQgYXBwcm94aW1hdGlvbiB0byBwcmVkaWN0IHRoZSBtZWRpYW4gdmFsdWUgb2YgdGhlIHByb3BlcnRpZXMgYXMgYSBmdW5jdGlvbiBvZiB0aGUgdmFyaWFibGVzIGNvbnNpZGVyZWQuCgpJdCB3YXMgdmVyeSBpbnRlcmVzdGluZyB0byBzZWUgaG93IHRoZSBkYXRhIHRyYW5zZm9ybWF0aW9ucyBoZWxwZWQgdG8gcmVkdWNlIHRoZSBwcm9ibGVtcyBvZiBoZXRlcm9jZXJhc3RpY2l0eSBhbmQgbm9ybWFsaXR5IG9mIHRoZSByZXNpZHVhbHMgdGhhdCB3ZXJlIGZvdW5kIGluIHRoZSBmaXJzdCBtb2RlbCBwcm9wb3NlZC4KClJlZ2FyZGluZyB0aGUgaW5zaWdodHMgZm91bmQsIHRoZSBncmVhdCBpbXBhY3QgdGhhdCB0aGUgY3JpbWUgcmF0ZSBoYXMgb24gaG9tZXMgaXMgaGlnaGxpZ2h0ZWQsIHNpbmNlIHRoaXMgdmFyaWFibGUgd2FzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIHdpdGggYSBoaWdoIGFuZCBuZWdhdGl2ZSBjb2VmZmljaWVudCwgc28gYW4gaW5jcmVhc2UgaW4gY3JpbWUgbGVhZHMgdG8gYSBjb25zaWRlcmFibGUgbG9zcyBpbiB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5LiB0aGUgaG9tZXMsIHdoaWNoIGlzIHdoeSBpdCBpcyBpbXBvcnRhbnQgdG8gZ3VhcmFudGVlIHRoZSBzZWN1cml0eSBvZiB0aGUgbmVpZ2hib3Job29kcyBhbmQgdGh1cyBiZSBhYmxlIHRvIGluY3JlYXNlIHRoZSB2YWx1ZSBvZiB0aGUgaG9tZXMuIE9uIHRoZSBvdGhlciBoYW5kLCBhaXIgcXVhbGl0eSwgYXMgdGhvdWdodCwgdHVybmVkIG91dCB0byBoYXZlIGEgbmVnYXRpdmUgc2lnbmlmaWNhbmNlLCB3aGljaCBoaWdobGlnaHRzIHRoZSB0ZW5kZW5jeSBvZiBwZW9wbGUgdG8gbGl2ZSBpbiBxdWlldCBwbGFjZXMsIHdpdGggZXhjZWxsZW50IGFpciBhbmQgYSB2ZXJ5IGdvb2QgcXVhbGl0eSBvZiBsaWZlLiBIb3dldmVyLCBzb21ldGhpbmcgaW50ZXJlc3Rpbmcgd2FzIHNlZWluZyB0aGF0IHRoZSBudW1iZXIgb2Ygcm9vbXMgdHVybmVkIG91dCB0byBoYXZlIGEgbmVnYXRpdmUgcmVsYXRpb25zaGlwIHdpdGggdGhlIHZhbHVlIG9mIHRoZSBob21lcywgc29tZXRoaW5nIHZlcnkgcGVjdWxpYXIgYW5kIHRoYXQgY291bGQgYmUgcmVsYXRlZCB0byB0aGUgZmFjdCB0aGF0IHBlcmhhcHMgcGVvcGxlIHZhbHVlIG90aGVyIG1vcmUgaW1wb3J0YW50IGZhY3RvcnMgbW9yZSB0aGFuIHRoZSBudW1iZXIgb2Ygcm9vbXMuCgpSZWdhcmRpbmcgdGhlIGltcG9ydGFuY2Ugb2YgZGlhZ25vc3RpY3MgaW4gaW1wcm92aW5nIHRoZSByZXN1bHRzIG9mIGxpbmVhciByZWdyZXNzaW9uIGFuZCBwcmVkaWN0aXZlIGFuYWx5c2lzLCB0aGV5IHBsYXllZCBhIGZ1bmRhbWVudGFsIHJvbGUuIFRlc3RzIGZvciBub3JtYWxpdHkgYW5kIGhldGVyb3NjZWRhc3RpY2l0eSBpZGVudGlmaWVkIHByb2JsZW1zIGluIHRoZSBkYXRhIHRoYXQgbGVkIHRvIHRoZSBhcHBsaWNhdGlvbiBvZiB0cmFuc2Zvcm1hdGlvbnMgYW5kIHJlZ3VsYXJpemF0aW9uIG1ldGhvZHMsIHN1Y2ggYXMgdGhlIExhc3NvIG1vZGVsLiBUaGVzZSBkaWFnbm9zdGljcyBoZWxwZWQgZmluZS10dW5lIHRoZSBtb2RlbHMgYW5kIGltcHJvdmUgdGhlaXIgYWJpbGl0eSB0byBtYWtlIGFjY3VyYXRlIHByZWRpY3Rpb25zLiBGdXJ0aGVybW9yZSwgdGhlIHZhcmlhYmxlIHNlbGVjdGlvbiBwcm9jZXNzIGluIHRoZSBMYXNzbyBtb2RlbCBoaWdobGlnaHRlZCB0aGUgaW1wb3J0YW5jZSBvZiBjZXJ0YWluIGNoYXJhY3RlcmlzdGljcywgd2hpY2ggY2FuIGJlIHZhbHVhYmxlIGluIGRlY2lzaW9uIG1ha2luZyB0byBvcHRpbWl6ZSB0aGUgZGVzaWduIG9mIGZ1dHVyZSByZWFsIGVzdGF0ZSBwcm9qZWN0cyBpbiB0aGUgc3R1ZGllZCByZWdpb25zLgoK