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)
## 'data.frame': 506 obs. of 15 variables:
## $ medv : num 24 21.6 34.7 33.4 36.2 28.7 22.9 27.1 16.5 18.9 ...
## $ cmedv : num 24 21.6 34.7 33.4 36.2 28.7 22.9 22.1 16.5 18.9 ...
## $ crim : num 0.00632 0.02731 0.02729 0.03237 0.06905 ...
## $ zn : num 18 0 0 0 0 0 12.5 12.5 12.5 12.5 ...
## $ indus : num 2.31 7.07 7.07 2.18 2.18 2.18 7.87 7.87 7.87 7.87 ...
## $ chas : int 0 0 0 0 0 0 0 0 0 0 ...
## $ nox : num 0.538 0.469 0.469 0.458 0.458 0.458 0.524 0.524 0.524 0.524 ...
## $ rm : num 6.58 6.42 7.18 7 7.15 ...
## $ age : num 65.2 78.9 61.1 45.8 54.2 58.7 66.6 96.1 100 85.9 ...
## $ dis : num 4.09 4.97 4.97 6.06 6.06 ...
## $ rad : int 1 2 2 3 3 3 5 5 5 5 ...
## $ tax : int 296 242 242 222 222 222 311 311 311 311 ...
## $ ptratio: num 15.3 17.8 17.8 18.7 18.7 18.7 15.2 15.2 15.2 15.2 ...
## $ b : num 397 397 393 395 397 ...
## $ lstat : num 4.98 9.14 4.03 2.94 5.33 ...
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 Breusch-Pagan test shows an extremely low p value (9.628e-06),
less than P=0.05, which indicates that we must reject the null
hypothesis of homoscedasticity in model dmodel1, concluding that there
is evidence of heteroskedasticity in the model.
# 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), 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 tah 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
El test de Breusch-Pagan arroja un valor p muy cercano a cero
(p-value < 2.2e-16), lo que indica una fuerte evidencia en contra de
la hipótesis nula de homocedasticidad. Por lo tanto, podemos concluir
que existe heterocedasticidad en el modelo dmodel3, lo que sugiere que
la varianza de los errores no es constante en todas las observaciones y
que podría haber problemas de dispersión en el modelo.
# 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.
Conclusions
In summary, thanks to the exploratory analysis of the data, we had a
clear idea of the data we had and the transformations necessary to
achieve a robust model. Model 3 stands out as a model with a very good
fit to the data, thanks to good values of AIC and R squared, and it was
also a model that had many variables with statistical significance and
that helped us corroborate our hypotheses. However, despite reducing
heterocerasticity with data transformations and with the lasso model, it
is important to continue applying other transformation techniques to
avoid this problem, although as already mentioned, it is important to
highlight that heterocerasticity is a natural problem of The data we are
working with are cross-sectional data from several US states at a given
point in time, so the variances will hardly be homogeneous. 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.
Likewise, the value of homes is a variable that depends on many other
independent variables of those studied here, it will be interesting to
complement this analysis with the economic projections of the areas in
the future, the stores that are around, the distances to the cities,
etc.
Regarding the application of linear regression in the context of
predictive analytics, this approach appears to be a valuable tool.
Linear regression models provide an understanding of how various
characteristics affect property values and are therefore essential for
making informed real estate decisions. Furthermore, the identification
of significant variables, such as air quality (nox) and crime rate
(crim), can provide crucial information for the planning and development
of future real estate projects. This predictive analytics capability can
significantly improve efficiency and effectiveness in property
investment and management, supporting the continued importance of linear
regression in analysis and decision making in the real estate
market.
LS0tCnRpdGxlOiAiQXNzaWdubWVudCAxLiBSZWdyZXNzaW9uIEFuYWx5c2lzIgphdXRob3I6ICJHYWJyaWVsIE1lZGluYSAtIEEwMTI3NTc2MyIKZGF0ZTogIjIwMjMtMDgtMjIiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCkVxdWlwbzoKCkEwMDgzNDI0MSB8IFJlZ2luYSBSb2Ryw61ndWV6IENow6F2ZXoKQTAwODMzNjE3IHwgWWVzc2ljYSBBY29zdGEgQmxhbmNoZXRoCkEwMTI3NTc2MyB8IEVsaSBHYWJyaWVsIEhlcm7DoW5kZXogTWVkaW5hCkEwMDgzMzE3MiB8IEdlbmFybyBSb2Ryw61ndWV6IEFsY8OhbnRhcmEKClRoZSBmaXJzdCBzdGVwIGlzIGxvYWQgdGhlIGxpYnJhcmllcwoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShmb3JlaWduKQpsaWJyYXJ5KGRwbHlyKSAgICAgICAgIyBkYXRhIG1hbmlwdWxhdGlvbiAKbGlicmFyeShmb3JjYXRzKSAgICAgICMgdG8gd29yayB3aXRoIGNhdGVnb3JpY2FsIHZhcmlhYmxlcwpsaWJyYXJ5KGdncGxvdDIpICAgICAgIyBkYXRhIHZpc3VhbGl6YXRpb24gCmxpYnJhcnkocmVhZHIpICAgICAgICAjIHJlYWQgc3BlY2lmaWMgY3N2IGZpbGVzCmxpYnJhcnkoamFuaXRvcikgICAgICAjIGRhdGEgZXhwbG9yYXRpb24gYW5kIGNsZWFuaW5nIApsaWJyYXJ5KEhtaXNjKSAgICAgICAgIyBzZXZlcmFsIHVzZWZ1bCBmdW5jdGlvbnMgZm9yIGRhdGEgYW5hbHlzaXMgCmxpYnJhcnkocHN5Y2gpICAgICAgICAjIGZ1bmN0aW9ucyBmb3IgbXVsdGl2YXJpYXRlIGFuYWx5c2lzIApsaWJyYXJ5KG5hbmlhcikgICAgICAgIyBzdW1tYXJpZXMgYW5kIHZpc3VhbGl6YXRpb24gb2YgbWlzc2luZyB2YWx1ZXMgTkEncwpsaWJyYXJ5KGRsb29rcikgICAgICAgIyBzdW1tYXJpZXMgYW5kIHZpc3VhbGl6YXRpb24gb2YgbWlzc2luZyB2YWx1ZXMgTkEncwpsaWJyYXJ5KGNvcnJwbG90KSAgICAgIyBjb3JyZWxhdGlvbiBwbG90cwpsaWJyYXJ5KGp0b29scykgICAgICAgIyBwcmVzZW50YXRpb24gb2YgcmVncmVzc2lvbiBhbmFseXNpcyAKbGlicmFyeShsbXRlc3QpICAgICAgICMgZGlhZ25vc3RpYyBjaGVja3MgLSBsaW5lYXIgcmVncmVzc2lvbiBhbmFseXNpcyAKbGlicmFyeShjYXIpICAgICAgICAgICMgZGlhZ25vc3RpYyBjaGVja3MgLSBsaW5lYXIgcmVncmVzc2lvbiBhbmFseXNpcwpsaWJyYXJ5KG9sc3JyKSAgICAgICAgIyBkaWFnbm9zdGljIGNoZWNrcyAtIGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2lzIApsaWJyYXJ5KG5hbmlhcikgICAgICAgIyBpZGVudGlmeWluZyBtaXNzaW5nIHZhbHVlcwojbGlicmFyeShmdW5Nb2RlbGluZykgICMgY3JlYXRlIGZyZXF1ZW5jeSB0YWJsZXMKbGlicmFyeShzdGFyZ2F6ZXIpICAgICMgY3JlYXRlIHB1YmxpY2F0aW9uIHF1YWxpdHkgdGFibGVzCmxpYnJhcnkoZWZmZWN0cykgICAgICAjIGRpc3BsYXlzIGZvciBsaW5lYXIgYW5kIG90aGVyIHJlZ3Jlc3Npb24gbW9kZWxzCmxpYnJhcnkodGlkeXZlcnNlKSAgICAjIGNvbGxlY3Rpb24gb2YgUiBwYWNrYWdlcyBkZXNpZ25lZCBmb3IgZGF0YSBzY2llbmMKbGlicmFyeShjYXJldCkgICAgICAgICMgQ2xhc3NpZmljYXRpb24gYW5kIFJlZ3Jlc3Npb24gVHJhaW5pbmcgCmxpYnJhcnkoZ2xtbmV0KSAgCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShjYXIpCmxpYnJhcnkobG10ZXN0KQoKCmBgYAoKCkl0IGlzIG5lY2Vzc2FyeSB0byBsb2FkIHRoZSBkYXRhYmFzZSB0byBiZWdpbiB0aGUgYW5hbHlzaXMuCgpgYGB7ciBjYXJzfQojZmlsZS5jaG9vc2UoKQpkYXRhc2V0IDwtIHJlYWQuY3N2KCIvVXNlcnMvZ2FicmllbG1lZGluYS9Eb3dubG9hZHMvUmVhbF9lc3RhdGVfZGF0YSAoMSkuY3N2IikKCmBgYAoKIyBFeHBsb3JhdG9yeSBEYXRhIEFuYWx5c2lzCgoKSXQgaXMgaW1wb3J0YW50IHRvIHN0YXJ0IGFuYWx5emluZyB0aGUgc3RydWN0dXJlIG9mIHRoZSBkYXRhYmFzZSwgYXMgd2VsbCBhcyB0aGUgdHlwZSBvZiBkYXRhIGhlbGQgaW4gZWFjaCB2YXJpYWJsZSwgaW4gb3JkZXIgdG8gZnVsbHkgdW5kZXJzdGFuZCB0aGUgZGF0YSB3ZSBhcmUgd29ya2luZyB3aXRoLgoKYGBge3J9CiNkYXRhc2V0CgpgYGAKYGBge3J9CnN0cihkYXRhc2V0KQpgYGAKCkFuYWx5emluZyB0aGUgc3RydWN0dXJlIG9mIHRoZSBkYXRhYmFzZSwgd2UgY2FuIHJlYWxpemUgdGhhdCB0aGUgY2hhcyB2YXJpYWJsZSBpcyBhIGJpbmFyeSB2YXJpYWJsZSBvZiBmYWN0b3IgdHlwZSwgd2hpY2ggaXMgaW4gYW4gaW50ZWdlciB0eXBlLCB0aGVyZWZvcmUgaXQgaXMgbmVjZXNzYXJ5IHRvIHRyYW5zZm9ybSB0aGUgZGF0YS4KCmBgYHtyfQpkYXRhc2V0JGNoYXMgPC0gYXMuZmFjdG9yKGRhdGFzZXQkY2hhcykKYGBgCgpgYGB7cn0Kc3VtKGlzLm5hKGRhdGFzZXQpKSAKYGBgCgpTaW5jZSBubyBudWxsIGRhdGEgd2VyZSBmb3VuZCwgaXQgaXMgaW1wb3J0YW50IHRvIGhhdmUgYW4gaWRlYSBvZiB0aGUgbWFpbiB2YWx1ZXMgb2YgZWFjaCB2YXJpYWJsZSB0aHJvdWdoIGEgZGVzY3JpcHRpdmUgc3RhdGlzdGljYWwgYW5hbHlzaXMuCgpgYGB7cn0Kc3VtbWFyeShkYXRhc2V0KQpgYGAKCmBgYHtyfQpzdGF0aXN0aWNzX2R0ID0gc3VtbWFyeShkYXRhc2V0KQoKCm1lYW5fdmFsdWUgPC0gc3RhdGlzdGljc19kdFsyLCBdCm1lZGlhbl92YWx1ZSA8LSBzdGF0aXN0aWNzX2R0WzMsIF0Kc3RhbmRhcmRfZGV2aWF0aW9uIDwtIHN0YXRpc3RpY3NfZHRbNCwgXQptaW5pbXVtX3ZhbHVlIDwtIHN0YXRpc3RpY3NfZHRbNSwgXQptYXhpbXVtX3ZhbHVlIDwtIHN0YXRpc3RpY3NfZHRbNiwgXQoKIyBQcmludCB0aGUgZGVzY3JpcHRpdmUgc3RhdGlzdGljcwpjYXQoIk1lYW46IiwgbWVhbl92YWx1ZSwgIlxuIikKY2F0KCJNZWRpYW46IiwgbWVkaWFuX3ZhbHVlLCAiXG4iKQpjYXQoIlN0YW5kYXJkIERldmlhdGlvbjoiLCBzdGFuZGFyZF9kZXZpYXRpb24sICJcbiIpCmNhdCgiTWluaW11bToiLCBtaW5pbXVtX3ZhbHVlLCAiXG4iKQpjYXQoIk1heGltdW06IiwgbWF4aW11bV92YWx1ZSwgIlxuIikKCmBgYApUaGUgcmVzdWx0cyBvZiB0aGUgZGVzY3JpcHRpdmUgc3RhdGlzdGljcyByZXZlYWwgdmFsdWFibGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHZhcmlhYmxlcyBpbiBteSBkYXRhIHNldC4gUmVnYXJkaW5nIHRoZSB0YXJnZXQgdmFyaWFibGUgIm1lZHYiIChhdmVyYWdlIHZhbHVlIG9mIGhvbWVzKSwgaXQgaXMgb2JzZXJ2ZWQgdGhhdCBpdHMgdmFsdWVzIHJhbmdlIGJldHdlZW4gNS4wMCBhbmQgNTAuMDAsIHdpdGggYSBtZWRpYW4gb2YgMjEuMjAgYW5kIGEgc2xpZ2h0bHkgaGlnaGVyIG1lYW4gb2YgMjIuNTMuIFRoaXMgc3VnZ2VzdHMgYSByZWxhdGl2ZWx5IHdpZGUgZGlzcGVyc2lvbiBvZiBob3VzZSBwcmljZXMuIFdoZW4gZXhhbWluaW5nIG90aGVyIHZhcmlhYmxlcywgc3VjaCBhcyAiY3JpbSIgKGNyaW1lIHJhdGUpIGFuZCAibm94IiAoY29uY2VudHJhdGlvbiBvZiBuaXRyb2dlbiBveGlkZXMpLCB3aWRlIHZhcmlhdGlvbnMgaW4gdGhlaXIgdmFsdWVzIGFyZSBmb3VuZCwgaW5kaWNhdGluZyBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBpbiBsZXZlbHMgb2YgY3JpbWUgYW5kIGFpciBxdWFsaXR5IGluIHRoZSBzdHVkaWVkIGFyZWFzLiBBZGRpdGlvbmFsbHksIHRoZSB2YXJpYWJsZSAiY2hhcyIgaXMgbW9zdGx5IGNhdGVnb3JpY2FsLCB3aXRoIG1vc3QgcmVjb3JkcyBoYXZpbmcgYSB2YWx1ZSBvZiAwLgoKT24gdGhlIG90aGVyIGhhbmQsIHN0YXRpc3RpY3MgaGlnaGxpZ2h0IGtleSBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIHByZWRpY3RvciB2YXJpYWJsZXMuIEZvciBleGFtcGxlLCAicm0iIChhdmVyYWdlIG51bWJlciBvZiByb29tcyBwZXIgZHdlbGxpbmcpIGhhcyB2YWx1ZXMgdGhhdCB2YXJ5IGJldHdlZW4gMyw1NjEgYW5kIDgsNzgwLCB3aXRoIGEgbWVkaWFuIG9mIDYsMjA4LCBzdWdnZXN0aW5nIHZhcmlhYmlsaXR5IGluIHRoZSBzaXplIG9mIGR3ZWxsaW5ncy4gVGhlIHZhcmlhYmxlICJ0YXgiIHNob3dzIHdpZGUgdmFyaWF0aW9uLCB3aXRoIHZhbHVlcyByYW5naW5nIGJldHdlZW4gMTg3LjAgYW5kIDcxMS4wLiBGdXJ0aGVybW9yZSwgImxzdGF0IiAocGVyY2VudGFnZSBvZiBwb3B1bGF0aW9uIG9mIGxvd2VyIHN0YXR1cykgcHJlc2VudHMgdmFsdWVzIHRoYXQgdmFyeSBmcm9tIDEuNzMgdG8gMzcuOTcsIGluZGljYXRpbmcgdGhlIGRpdmVyc2l0eSBpbiB0aGUgc29jaW9lY29ub21pYyBjb25kaXRpb25zIG9mIHRoZSBzdHVkaWVkIGFyZWFzLiBUaGVzZSBzdW1tYXJ5IHN0YXRpc3RpY3MgcHJvdmlkZSBhbiBvdmVydmlldyBvZiB0aGUgZGlzdHJpYnV0aW9uIGFuZCB2YXJpYWJpbGl0eSBvZiB0aGUgdmFyaWFibGVzLCB3aGljaCBpcyBlc3NlbnRpYWwgZm9yIGJldHRlciB1bmRlcnN0YW5kaW5nIHRoZSBkYXRhIHNldCBhbmQgcGxhbm5pbmcgc3Vic2VxdWVudCBhbmFseXNlcy4KClNpbmNlIG5vIGFibm9ybWFsaXR5IHdhcyBmb3VuZCBpbiB0aGUgZGF0YSwgYSBncmFwaGljYWwgYW5hbHlzaXMgaXMgY2FycmllZCBvdXQuCgojICBEYXRhIFZpc3VhbGl6YXRpb24KCiMjIyMjIC0gQnVpbGQgYXQgbGVhc3QgMiBwYWlyLXdpc2VkIGdyYXBocyBiZXR3ZWVuIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgYW5kIGluZGVwZW5kZW50IHZhcmlhYmxlcwoKYGBge3J9CgpnZ3Bsb3QoZGF0YSA9IGRhdGFzZXQsIGFlcyh4ID0gY3JpbSwgeSA9IG1lZHYpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJibHVlIiwgYWxwaGEgPSAwLjYpICsKICBsYWJzKHggPSAiQ3JpbWUgUmF0ZSAoY3JpbSkiLCB5ID0gIk1lZGlhbiBWYWx1ZSAobWVkdikiKSArCiAgZ2d0aXRsZSgiU2NhdHRlciBQbG90OiBNZWRpYW4gVmFsdWUgdnMuIENyaW1lIFJhdGUiKSArCiAgdGhlbWVfbWluaW1hbCgpCgoKZ2dwbG90KGRhdGEgPSBkYXRhc2V0LCBhZXMoeCA9IHpuLCB5ID0gbWVkdikpICsKICBnZW9tX3BvaW50KGNvbG9yID0gInJlZCIsIGFscGhhID0gMC42KSArCiAgbGFicyh4ID0gIlByb3BvcnRpb24gb2YgUmVzaWRlbnRpYWwgTGFuZCBab25lZCAoem4pIiwgeSA9ICJNZWRpYW4gVmFsdWUgKG1lZHYpIikgKwogIGdndGl0bGUoIlNjYXR0ZXIgUGxvdDogTWVkaWFuIFZhbHVlIHZzLiBQcm9wb3J0aW9uIG9mIFJlc2lkZW50aWFsIExhbmQgWm9uZWQiKSArCiAgdGhlbWVfbWluaW1hbCgpCgoKZ2dwbG90KGRhdGEgPSBkYXRhc2V0LCBhZXMoeCA9IGluZHVzLCB5ID0gbWVkdikpICsKICBnZW9tX3BvaW50KGNvbG9yID0gImdyZWVuIiwgYWxwaGEgPSAwLjYpICsKICBsYWJzKHggPSAiSW5kdXN0cmlhbCBab25lIFByb3BvcnRpb24gKGluZHVzKSIsIHkgPSAiTWVkaWFuIFZhbHVlIChtZWR2KSIpICsKICBnZ3RpdGxlKCJTY2F0dGVyIFBsb3Q6IE1lZGlhbiBWYWx1ZSB2cy4gSW5kdXN0cmlhbCBab25lIFByb3BvcnRpb24iKSArCiAgdGhlbWVfbWluaW1hbCgpCgoKZ2dwbG90KGRhdGEgPSBkYXRhc2V0LCBhZXMoeCA9IG5veCwgeSA9IG1lZHYpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJibHVlIiwgYWxwaGEgPSAwLjYpICsKICBsYWJzKHggPSAiTml0cm9nZW4gT3hpZGVzIENvbmNlbnRyYXRpb24gKG5veCkiLCB5ID0gIk1lZGlhbiBWYWx1ZSAobWVkdikiKSArCiAgZ2d0aXRsZSgiU2NhdHRlciBQbG90OiBNZWRpYW4gVmFsdWUgdnMuIE5pdHJvZ2VuIE94aWRlcyBDb25jZW50cmF0aW9uIikgKwogIHRoZW1lX21pbmltYWwoKQoKCmdncGxvdChkYXRhID0gZGF0YXNldCwgYWVzKHggPSBybSwgeSA9IG1lZHYpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJyZWQiLCBhbHBoYSA9IDAuNikgKwogIGxhYnMoeCA9ICJBdmVyYWdlIE51bWJlciBvZiBSb29tcyAocm0pIiwgeSA9ICJNZWRpYW4gVmFsdWUgKG1lZHYpIikgKwogIGdndGl0bGUoIlNjYXR0ZXIgUGxvdDogTWVkaWFuIFZhbHVlIHZzLiBBdmVyYWdlIE51bWJlciBvZiBSb29tcyIpICsKICB0aGVtZV9taW5pbWFsKCkKCgpnZ3Bsb3QoZGF0YSA9IGRhdGFzZXQsIGFlcyh4ID0gYWdlLCB5ID0gbWVkdikpICsKICBnZW9tX2xpbmUoY29sb3IgPSAiZ3JlZW4iLCBhbHBoYSA9IDAuNikgKwogIGxhYnMoeCA9ICJQcm9wb3J0aW9uIG9mIE93bmVyLU9jY3VwaWVkIFVuaXRzIEJ1aWx0IEJlZm9yZSAxOTQwIChhZ2UpIiwgeSA9ICJNZWRpYW4gVmFsdWUgKG1lZHYpIikgKwogIGdndGl0bGUoIlNjYXR0ZXIgUGxvdDogTWVkaWFuIFZhbHVlIHZzLiBQcm9wb3J0aW9uIG9mIE93bmVyLU9jY3VwaWVkIFVuaXRzIEJ1aWx0IEJlZm9yZSAxOTQwIikgKwogIHRoZW1lX21pbmltYWwoKQoKCmdncGxvdChkYXRhID0gZGF0YXNldCwgYWVzKHggPSBkaXMsIHkgPSBtZWR2KSkgKwogIGdlb21fbGluZShjb2xvciA9ICJwdXJwbGUiLCBhbHBoYSA9IDAuNikgKwogIGxhYnMoeCA9ICJXZWlnaHRlZCBEaXN0YW5jZXMgdG8gRW1wbG95bWVudCBDZW50ZXJzIChkaXMpIiwgeSA9ICJNZWRpYW4gVmFsdWUgKG1lZHYpIikgKwogIGdndGl0bGUoIlNjYXR0ZXIgUGxvdDogTWVkaWFuIFZhbHVlIHZzLiBXZWlnaHRlZCBEaXN0YW5jZXMgdG8gRW1wbG95bWVudCBDZW50ZXJzIikgKwogIHRoZW1lX21pbmltYWwoKQoKCmdncGxvdChkYXRhID0gZGF0YXNldCwgYWVzKHggPSBmYWN0b3IocmFkKSwgeSA9IG1lZHYpKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAic2t5Ymx1ZSIpICsKICBsYWJzKHggPSAiQWNjZXNzaWJpbGl0eSB0byBSYWRpYWwgSGlnaHdheXMgKHJhZCkiLCB5ID0gIk1lZGlhbiBWYWx1ZSAobWVkdikiKSArCiAgZ2d0aXRsZSgiQm94cGxvdDogTWVkaWFuIFZhbHVlIHZzLiBBY2Nlc3NpYmlsaXR5IHRvIFJhZGlhbCBIaWdod2F5cyIpICsKICB0aGVtZV9taW5pbWFsKCkKCgpnZ3Bsb3QoZGF0YSA9IGRhdGFzZXQsIGFlcyh4ID0gZmFjdG9yKHRheCksIHkgPSBtZWR2KSkgKwogIGdlb21fYm94cGxvdChmaWxsID0gImxpZ2h0Z3JlZW4iKSArCiAgbGFicyh4ID0gIlByb3BlcnR5IFRheCBSYXRlICh0YXgpIiwgeSA9ICJNZWRpYW4gVmFsdWUgKG1lZHYpIikgKwogIGdndGl0bGUoIkJveHBsb3Q6IE1lZGlhbiBWYWx1ZSB2cy4gUHJvcGVydHkgVGF4IFJhdGUiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpnZ3Bsb3QoZGF0YSA9IGRhdGFzZXQsIGFlcyh4ID0gcHRyYXRpbywgeSA9IG1lZHYpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJibHVlIiwgZmlsbCA9ICJsaWdodGJsdWUiKSArCiAgbGFicyh4ID0gIlB1cGlsLVRlYWNoZXIgUmF0aW8gKHB0cmF0aW8pIiwgeSA9ICJNZWRpYW4gVmFsdWUgKG1lZHYpIikgKwogIGdndGl0bGUoIkRlbnNpdHkgUGxvdDogTWVkaWFuIFZhbHVlIHZzLiBQdXBpbC1UZWFjaGVyIFJhdGlvIikgKwogIHRoZW1lX21pbmltYWwoKQoKZ2dwbG90KGRhdGEgPSBkYXRhc2V0LCBhZXMoeCA9IGIsIHkgPSBtZWR2KSkgKwogIGdlb21fcG9pbnQoY29sb3IgPSAicHVycGxlIiwgYWxwaGEgPSAwLjYpICsKICBsYWJzKHggPSAiUHJvcG9ydGlvbiBvZiBSZXNpZGVudHMgb2YgQWZyaWNhbiBBbWVyaWNhbiBEZXNjZW50IChiKSIsIHkgPSAiTWVkaWFuIFZhbHVlIChtZWR2KSIpICsKICBnZ3RpdGxlKCJTY2F0dGVyIFBsb3Q6IE1lZGlhbiBWYWx1ZSB2cy4gUHJvcG9ydGlvbiBvZiBSZXNpZGVudHMgb2YgQWZyaWNhbiBBbWVyaWNhbiBEZXNjZW50IChiKSIpICsKICB0aGVtZV9taW5pbWFsKCkKCmdncGxvdChkYXRhID0gZGF0YXNldCwgYWVzKHggPSBsc3RhdCwgeSA9IG1lZHYpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJvcmFuZ2UiLCBhbHBoYSA9IDAuNikgKwogIGxhYnMoeCA9ICJQZXJjZW50YWdlIG9mIExvd2VyIFN0YXR1cyBQb3B1bGF0aW9uIChsc3RhdCkiLCB5ID0gIk1lZGlhbiBWYWx1ZSAobWVkdikiKSArCiAgZ2d0aXRsZSgiU2NhdHRlciBQbG90OiBNZWRpYW4gVmFsdWUgdnMuIFBlcmNlbnRhZ2Ugb2YgTG93ZXIgU3RhdHVzIFBvcHVsYXRpb24gKGxzdGF0KSIpICsKICB0aGVtZV9taW5pbWFsKCkKCmBgYApUaGUgcHJldmlvdXMgZ3JhcGhzIGdpdmUgdXMgYW4gaWRlYSBvZiB0aGUgY29ycmVsYXRpb24gcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGVhY2ggaW5kZXBlbmRlbnQgdmFyaWFibGUgYW5kIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUuIFRoaXMgZG9lcyBub3QgbWVhbiB0aGF0IHRoZXkgaGF2ZSBhIGRpcmVjdCBjYXVzYWwgcmVsYXRpb25zaGlwLCBidXQgdGhleSBhcmUgYSBzaWduIHRoYXQgdGhleSBoYXZlIHRoZSBwb3RlbnRpYWwgdG8gYmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgc28gc29tZSB2YXJpYWJsZXMgd291bGQgYmUgaW50ZXJlc3RpbmcgdG8gaW5jbHVkZSBpbiBsaW5lYXIgcmVncmVzc2lvbiBhbmFseXNlcywgZm9yIGV4YW1wbGUsIHpuLG5veCwgcm0gb3IgSVNUQVQuCgojIyMjIyAtIERpc3BsYXkgYSBoaXN0b2dyYW0gb2YgZGVwZW5kZW50IHZhcmlhYmxlCgpgYGB7cn0KaGlzdChkYXRhc2V0JG1lZHYpCmhpc3QoZGF0YXNldCRjcmltKQpoaXN0KGRhdGFzZXQkem4pCmhpc3QoZGF0YXNldCRpbmR1cykKaGlzdChkYXRhc2V0JG5veCkKaGlzdChkYXRhc2V0JHJtKQpoaXN0KGRhdGFzZXQkZGlzKQpoaXN0KGRhdGFzZXQkcmFkKQpoaXN0KGRhdGFzZXQkdGF4KQpoaXN0KGRhdGFzZXQkcHRyYXRpbykKaGlzdChkYXRhc2V0JGIpCmhpc3QoZGF0YXNldCRsc3RhdCkKYGBgCgpUaGFua3MgdG8gdGhlIGhpc3RvZ3JhbXMsIHdlIGNhbiBzZWUgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGF0YSBmb3IgZWFjaCB2YXJpYWJsZSwgd2hlcmUgd2Ugc2VlIHRoYXQgdGhlcmUgYXJlIHNldmVyYWwgc3VjaCBhczogY3JpbSwgem4sIGluZHVzLCBjaGFzLCBub3gsIGRpeCwgcmFkLCB0YXgsIHB0cmF0aW8sIGIgYW5kIGxzdGF0IHRoYXQgZG8gbm90IGZvbGxvdyBhIG5vcm1hbCBkaXN0cmlidXRpb24sIHRoZXJlZm9yZSBpdCB3aWxsIGJlIGludGVyZXN0aW5nIHRvIGFwcGx5IHF1YWRyYXRpYyBvciBsb2dhcml0aG1pYyB0cmFuc2Zvcm1hdGlvbnMgdG8gdGhlc2UgdmFyaWFibGVzIGluIG91ciBzdWJzZXF1ZW50IGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2VzLgoKIyMjIyMgLSBEaXNwbGF5IGEgY29ycmVsYXRpb24gcGxvdCAgCgpUbyBiZXR0ZXIgdW5kZXJzdGFuZCB0aGUgY29ycmVsYXRpb24gcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSB2YXJpYWJsZXMsIGEgZGlhZ3JhbSBhbmQgYSBjb3JyZWxhdGlvbiBtYXRyaXggd2lsbCBiZSBtYWRlLiBJdCBpcyB2ZXJ5IGltcG9ydGFudCB0byBhbmFseXplIHRoaXMgdG8gYXZvaWQgbXVsdGljdWxpbmFsaXR5IHByb2JsZW1zLgoKCmBgYHtyfQoKZGF0YXNldF9leGNsX2NoYXMgPC0gZGF0YXNldFssICFjb2xuYW1lcyhkYXRhc2V0KSAlaW4lIGMoImNoYXMiKV0KCmNvcl9tYXRyaXggPC0gY29yKGRhdGFzZXRfZXhjbF9jaGFzKQpjb3JycGxvdChjb3JfbWF0cml4LCB0eXBlID0gInVwcGVyIiwgb3JkZXIgPSAiaGNsdXN0IiwgYWRkQ29lZi5jb2wgPSAiYmxhY2siKQoKCmBgYAoKYGBge3J9CmNvcl9tYXRyaXgKYGBgCgpUaGUgY29ycmVsYXRpb24gYW5hbHlzaXMgYmV0d2VlbiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzIGFuZCB0aGUgZGVwZW5kZW50IHZhcmlhYmxlICJtZWR2IiBzaG93cyBzZXZlcmFsIGludGVyZXN0aW5nIHJlc3VsdHMuIEEgc3Ryb25nIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGlzIG9ic2VydmVkIGJldHdlZW4gIm1lZHYiIGFuZCAiY21lZHYsIiBpbmRpY2F0aW5nIHRoYXQgYm90aCB2YXJpYWJsZXMgYXJlIGhpZ2hseSByZWxhdGVkLiBGdXJ0aGVybW9yZSwgInJtIiAobnVtYmVyIG9mIHJvb21zKSBhbHNvIHByZXNlbnRzIGEgc2lnbmlmaWNhbnQgcG9zaXRpdmUgY29ycmVsYXRpb24gd2l0aCAibWVkdiwiIHN1Z2dlc3RpbmcgdGhhdCBhcyB0aGUgbnVtYmVyIG9mIHJvb21zIGluY3JlYXNlcywgdGhlIG1lZGlhbiBob21lIHZhbHVlIHRlbmRzIHRvIGluY3JlYXNlLgoKT24gdGhlIG90aGVyIGhhbmQsIHRoZXJlIGlzIGEgbm90YWJsZSBuZWdhdGl2ZSBjb3JyZWxhdGlvbiBiZXR3ZWVuICJtZWR2IiBhbmQgImxzdGF0IiAocGVyY2VudGFnZSBvZiBwb3B1bGF0aW9uIHdpdGggbG93IHNvY2lvZWNvbm9taWMgc3RhdHVzKSwgaW5kaWNhdGluZyB0aGF0IGFzIHRoZSBwZXJjZW50YWdlIG9mIHBvcHVsYXRpb24gd2l0aCBsb3cgc29jaW9lY29ub21pYyBzdGF0dXMgZGVjcmVhc2VzLCB0aGUgbWVkaWFuIHZhbHVlIG9mIHRoZSBob3VzaW5nIHRlbmRzIHRvIGluY3JlYXNlLiBJdCBpcyBpbXBvcnRhbnQgdG8gbWVudGlvbiB0aGF0IG11bHRpY29sbGluZWFyaXR5IGlzIGFsc28gb2JzZXJ2ZWQgYmV0d2VlbiBzb21lIGluZGVwZW5kZW50IHZhcmlhYmxlcywgc3VjaCBhcyAibm94IiBhbmQgImluZHVzLCIgd2hpY2ggc3VnZ2VzdHMgdGhhdCB0aGVzZSB2YXJpYWJsZXMgYXJlIGNvcnJlbGF0ZWQgd2l0aCBlYWNoIG90aGVyLgoKCiMgSHlwb3RoZXNlcyBTdGF0ZW1lbnQKCi0gLSAtIEh5cG90aGVzaXMgb24gdGhlIG51bWJlciBvZiByb29tcyAocm0pOiBJdCBpcyBiZWxpZXZlZCB0aGF0IGEgZ3JlYXRlciBudW1iZXIgb2Ygcm9vbXMgaW4gaG9tZXMgdGVuZHMgdG8gaW5jcmVhc2UgdGhlIG1lZGlhbiBwcm9wZXJ0eSB2YWx1ZSAobWVkdikuIFRoaXMgYmVsaWVmIGlzIGJhc2VkIG9uIHRoZSBsb2dpYyB0aGF0IG1vcmUgc3BhY2lvdXMgaG9tZXMgdGVuZCB0byBoYXZlIGEgaGlnaGVyIHZhbHVlIGluIHRoZSByZWFsIGVzdGF0ZSBtYXJrZXQgZHVlIHRvIHRoZWlyIGFiaWxpdHkgdG8gbWVldCB0aGUgbmVlZHMgb2YgbGFyZ2VyIGZhbWlsaWVzIG9yIHByb3ZpZGUgYWRkaXRpb25hbCBjb21mb3J0LgoKLSAtIC0gQWlyIHF1YWxpdHkgaHlwb3RoZXNpcyAobm94KTogSXQgaXMgYXJndWVkIHRoYXQgYW4gaW5jcmVhc2UgaW4gdGhlIGNvbmNlbnRyYXRpb24gb2Ygbml0cm9nZW4gb3hpZGUgaW4gdGhlIGFpciAobm94KSBpcyBhc3NvY2lhdGVkIHdpdGggYSBkZWNyZWFzZSBpbiB0aGUgbWVkaWFuIGhvbWUgdmFsdWUgKG1lZHYpLiBUaGlzIGh5cG90aGVzaXMgaXMganVzdGlmaWVkIGluIHRoZSBjb250ZXh0IG9mIGhlYWx0aCBhbmQgd2VsbC1iZWluZywgYXMgaW5jcmVhc2VkIGFpciBwb2xsdXRpb24gY2FuIG1ha2UgYSBsb2NhdGlvbiBsZXNzIGF0dHJhY3RpdmUgZm9yIGhvdXNpbmcuCgotIC0gLSBDcmltZSByYXRlIGh5cG90aGVzaXMgKGNyaW0pOiBJdCBpcyBhcmd1ZWQgdGhhdCBhbiBpbmNyZWFzZSBpbiB0aGUgY3JpbWUgcmF0ZSBpbiBhbiBhcmVhIChjcmltKSBoYXMgYSBuZWdhdGl2ZSBpbXBhY3Qgb24gdGhlIG1lZGlhbiBob21lIHZhbHVlIChtZWR2KS4gVGhpcyBiZWxpZWYgaXMgYmFzZWQgb24gdGhlIHBlcmNlcHRpb24gdGhhdCBhcmVhcyB3aXRoIGhpZ2ggY3JpbWUgcmF0ZXMgbWF5IGJlIGxlc3Mgc2FmZSBhbmQgdGhlcmVmb3JlIGxlc3MgZGVzaXJhYmxlIHRvIGxpdmUgaW4sIHdoaWNoIGNvdWxkIGRlY3JlYXNlIHRoZSBkZW1hbmQgZm9yIGhvdXNpbmcgYW5kLCBjb25zZXF1ZW50bHksIGl0cyB2YWx1ZXMuCgoKIyBSZWdyZXNzaW9uIEFuYWx5c2lzCgpXaXRoIHRoZSBleHBsb3JhdG9yeSBhbmFseXNpcyBvZiB0aGUgZGF0YSwgdGhlIHZhcmlhYmxlcyB0aGF0IGFyZSBiZWxpZXZlZCB0byBoYXZlIHRoZSBiZXN0IHBvdGVudGlhbCB0byBtb2RlbCB0aGUgc2l0dWF0aW9uIHdpbGwgYmUgY2hvc2VuLi4uCgpMaWtld2lzZSwgZm9yIG1vZGVscyAyIGFuZCAzLCB0cmFuc2Zvcm1hdGlvbnMgd2lsbCBiZSB1c2VkIHRocm91Z2ggdGhlIGNvbmNsdXNpb25zIGZvdW5kIGluIHRoZSBoaXN0b2dyYW1zIGFuZCBvdGhlciBpbnNpZ2h0cyBmb3VuZCBpbiB0aGUgZXhwbG9yYXRvcnkgYW5hbHlzaXMgb2YgdGhlIGRhdGEuCgojIyMjIE1PREVMIDEKCmBgYHtyfQpkbW9kZWwxPC1sbShtZWR2IH4gcm0rbm94K2xzdGF0K2NyaW0rdGF4K2luZHVzLGRhdGE9ZGF0YXNldCkKc3VtbWFyeShkbW9kZWwxKQpgYGAKClRoZSBtb2RlbCBoYXMgYSBtb2RlcmF0ZSBhYmlsaXR5IHRvIGV4cGxhaW4gdmFyaWF0aW9ucyBpbiBob3VzZSBwcmljZXMsIHdpdGggYW4gYWRqdXN0ZWQgUi1zcXVhcmVkIG9mIGFwcHJveGltYXRlbHkgMC42NDguCgpBbW9uZyB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzLCAicm0iIChhdmVyYWdlIG51bWJlciBvZiByb29tcyBwZXIgaG91c2Vob2xkKSBhbmQgImxzdGF0IiAocGVyY2VudGFnZSBvZiBwb3B1bGF0aW9uIHdpdGggbG93IHN0YXR1cykgYXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuIEEgb25lLXVuaXQgaW5jcmVhc2UgaW4gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIHJvb21zIGlzIGFzc29jaWF0ZWQgd2l0aCBhbiBpbmNyZWFzZSBvZiBhYm91dCA1LDIxNCB1bml0cyBpbiB0aGUgaG91c2luZyBwcmljZSwgd2hpbGUgYSBvbmUtdW5pdCBpbmNyZWFzZSBpbiB0aGUgcGVyY2VudGFnZSBvZiB0aGUgcG9wdWxhdGlvbiB3aXRoIGxvdyBzdGF0dXMgaXMgYXNzb2NpYXRlZCB3aXRoIGEgZGVjcmVhc2Ugb2YgYWJvdXQgMC41NjEgdW5pdHMgaW4gdGhlIHByaWNlIG9mIGhvdXNpbmcuCgpUaGUgdmFyaWFibGVzICJ0YXgiIChwcm9wZXJ0eSB0YXgpLCAibm94IiAoY29uY2VudHJhdGlvbiBvZiBuaXRyb2dlbiBveGlkZXMpLCAiY3JpbSIgKGNyaW1lIHJhdGUpIGFuZCAiaW5kdXMiIChwcm9wb3J0aW9uIG9mIGFjcmVzIG9mIG5vbi1yZXRhaWwgYnVzaW5lc3NlcyBwZXIgY2l0eSkgYXJlIG5vdCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGluIHRoaXMgbW9kZWwuCgpUaGUgbW9kZWwgYXMgYSB3aG9sZSBoYXMgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IEYgdmFsdWUsIGluZGljYXRpbmcgdGhhdCBhdCBsZWFzdCBvbmUgb2YgdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlcyBpcyByZWxldmFudCBpbiBwcmVkaWN0aW5nIGhvdXNlIHByaWNlcy4KClRoZSBpbnRlcmNlcHQgaXMgbm90IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgaW4gdGhpcyBjb250ZXh0LgoKSW4gc3VtbWFyeSwgdGhlIG1vZGVsIHN1Z2dlc3RzIHRoYXQgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIHJvb21zIGFuZCB0aGUgcGVyY2VudGFnZSBvZiB0aGUgcG9wdWxhdGlvbiB3aXRoIGxvdyBzdGF0dXMgYXJlIGltcG9ydGFudCBmYWN0b3JzIGluIHByZWRpY3RpbmcgaG91c2luZyBwcmljZXMsIHdoaWxlIG90aGVyIHZhcmlhYmxlcyBkbyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbW9kZWwuIFRoZSBtb2RlbCBhcyBhIHdob2xlIGlzIGNhcGFibGUgb2YgZXhwbGFpbmluZyBhIGNvbnNpZGVyYWJsZSBwYXJ0IG9mIHRoZSB2YXJpYWJpbGl0eSBpbiBob3VzZSBwcmljZXMuCgpBbHRob3VnaCB0aGUgbW9kZWwgc2hvd3MgYSByZWxhdGl2ZWx5IGdvb2QgZml0LCBpdCBpcyBuZWNlc3NhcnkgdG8gcGVyZm9ybSBkaWFnbm9zdGljIHRlc3RzIHRvIGRldGVjdCBwcm9ibGVtcyBzdWNoIGFzIG11bHRpY3VsaW5hbGl0eSwgaGV0ZXJvY2VyYXN0aWNpdHkgb3Igbm9ybWFsaXR5IG9mIHJlc2lkdWFscy4KCiMjIyMgRGlhZ25vc3RpYyB0ZXN0cyBNT0RFTCAxCgpgYGB7cn0KCiMgTXVsdGljb2xsaW5lYXJpdHkKCnZpZihkbW9kZWwxKQpgYGAKClNpbmNlIG5vIHZhbHVlIGV4Y2VlZHMgdGhlIHRocmVzaG9sZCBvZiAxMCwgbXVsdGljdWxpb25hbGl0eSBpcyBub3Qgb2JzZXJ2ZWQsIHRoYXQgaXMsIHRoZXJlIGlzIG5vIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlcy4KCmBgYHtyfQojIEhldGVyb3NjZWRhc3RpY2l0eQoKYnB0ZXN0KGRtb2RlbDEpCmBgYAoKVGhlIEJyZXVzY2gtUGFnYW4gdGVzdCBzaG93cyBhbiBleHRyZW1lbHkgbG93IHAgdmFsdWUgKDkuNjI4ZS0wNiksIGxlc3MgdGhhbiBQPTAuMDUsIHdoaWNoIGluZGljYXRlcyB0aGF0IHdlIG11c3QgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgb2YgaG9tb3NjZWRhc3RpY2l0eSBpbiBtb2RlbCBkbW9kZWwxLCBjb25jbHVkaW5nIHRoYXQgdGhlcmUgaXMgZXZpZGVuY2Ugb2YgaGV0ZXJvc2tlZGFzdGljaXR5IGluIHRoZSBtb2RlbC4KCmBgYHtyfQojIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMKcXFub3JtKGRtb2RlbDEkcmVzaWR1YWxzKQpxcWxpbmUoZG1vZGVsMSRyZXNpZHVhbHMpCnNoYXBpcm8udGVzdChkbW9kZWwxJHJlc2lkdWFscykKYGBgCgpUaGUgU2hhcGlyby1XaWxrIG5vcm1hbGl0eSB0ZXN0IHlpZWxkcyBhIHAgdmFsdWUgdmVyeSBjbG9zZSB0byB6ZXJvICg8IDIuMmUtMTYpLCB3aGljaCBpbmRpY2F0ZXMgdGhhdCB3ZSBtdXN0IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgdGhlIHJlc2lkdWFscyBvZiBtb2RlbCBkbW9kZWwxIGZvbGxvdyBhIG5vcm1hbCBkaXN0cmlidXRpb24sIGNvbmNsdWRpbmcgdGhhdCB0aGUgcmVzaWR1YWxzIGRvIG5vdCBUaGV5IGFyZSBub3JtYWxseSBkaXN0cmlidXRlZC4KCgojIyMjIE1PREVMIDIKCmBgYHtyfQpkbW9kZWwyPC1sbShsb2cobWVkdikgfiBybStub3grbHN0YXQrY3JpbSt0YXgraW5kdXMsZGF0YT1kYXRhc2V0KQpzdW1tYXJ5KGRtb2RlbDIpCgpgYGAKClRoZSBtb2RlbCBhY2hpZXZlcyBhIG1vZGVyYXRlIGFiaWxpdHkgdG8gZXhwbGFpbiB2YXJpYXRpb25zIGluIHRoZSBsb2dhcml0aG0gb2YgaG91c2UgcHJpY2VzLCB3aXRoIGFuIGFkanVzdGVkIFItc3F1YXJlZCBvZiBhcHByb3hpbWF0ZWx5IDAuNzIxLgoKT2YgdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlcywgInJtIiAoYXZlcmFnZSBudW1iZXIgb2Ygcm9vbXMgcGVyIGhvbWUpIGFuZCAibHN0YXQiIChwZXJjZW50YWdlIG9mIHBvcHVsYXRpb24gd2l0aCBsb3cgc3RhdHVzKSBhcmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gQSBvbmUtdW5pdCBpbmNyZWFzZSBpbiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgYmVkcm9vbXMgaXMgYXNzb2NpYXRlZCB3aXRoIGFuIGluY3JlYXNlIGluIHRoZSBsb2cgaG91c2UgcHJpY2UgYnkgYXBwcm94aW1hdGVseSAwLjMxNSB1bml0cywgd2hpbGUgYSBvbmUtdW5pdCBpbmNyZWFzZSBpbiB0aGUgcGVyY2VudGFnZSBvZiB0aGUgcG9wdWxhdGlvbiB3aXRoIGxvdyBzdGF0dXMgaXMgYXNzb2NpYXRlZCB3aXRoIGEgZGVjcmVhc2UgaW4gdGhlIGxvZyBvZiB0aGUgaG91c2UgcHJpY2UgYnkgYXBwcm94aW1hdGVseSAwLjA0NyB1bml0cy4KClRoZSB2YXJpYWJsZXMgIm5veCIgKGNvbmNlbnRyYXRpb24gb2Ygbml0cm9nZW4gb3hpZGVzKSwgImNyaW0iIChjcmltZSByYXRlKSwgInRheCIgKHByb3BlcnR5IHRheCksIGFuZCAiaW5kdXMiIChwcm9wb3J0aW9uIG9mIG5vbi1yZXRhaWwgYnVzaW5lc3MgYWNyZXMgcGVyIGNpdHkpIGFyZSBub3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBpbiB0aGlzIG1vZGVsLgoKVGhlIG1vZGVsIGFzIGEgd2hvbGUgaGFzIGEgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBGIHZhbHVlLCBpbmRpY2F0aW5nIHRoYXQgYXQgbGVhc3Qgb25lIG9mIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXMgaXMgcmVsZXZhbnQgaW4gcHJlZGljdGluZyB0aGUgbG9nYXJpdGhtIG9mIGhvdXNlIHByaWNlcy4KClRoZSBpbnRlcmNlcHQgaXMgbm90IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgaW4gdGhpcyBjb250ZXh0LgoKSW4gc3VtbWFyeSwgdGhlIHNlY29uZCBtb2RlbCBzdWdnZXN0cyB0aGF0IHRoZSBhdmVyYWdlIG51bWJlciBvZiByb29tcyBhbmQgdGhlIHBlcmNlbnRhZ2Ugb2YgcG9wdWxhdGlvbiB3aXRoIGxvdyBzdGF0dXMgYXJlIGltcG9ydGFudCBmYWN0b3JzIGluIHByZWRpY3RpbmcgdGhlIGxvZ2FyaXRobSBvZiBob3VzZSBwcmljZXMsIHdoaWxlIG90aGVyIHZhcmlhYmxlcyBkbyBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgbW9kZWwuIFRoZSBtb2RlbCBhcyBhIHdob2xlIGlzIGFibGUgdG8gZXhwbGFpbiBhIGNvbnNpZGVyYWJsZSBwYXJ0IG9mIHRoZSB2YXJpYWJpbGl0eSBpbiB0aGUgbG9nYXJpdGhtIG9mIGhvdXNlIHByaWNlcy4KCiMjIyMgRGlhZ25vc3RpYyB0ZXN0cyBNT0RFTCAyCgpgYGB7cn0KIyBNdWx0aWNvbGxpbmVhcml0eQoKdmlmKGRtb2RlbDIpCmBgYAoKU2luY2Ugbm8gdmFsdWUgZXhjZWVkcyB0aGUgdGhyZXNob2xkIG9mIDEwLCBtdWx0aWN1bGlvbmFsaXR5IGlzIG5vdCBvYnNlcnZlZCwgdGhhdCBpcywgdGhlcmUgaXMgbm8gY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzLgoKYGBge3J9CiMgSGV0ZXJvc2NlZGFzdGljaXR5CgpicHRlc3QoZG1vZGVsMikKYGBgClRoZSBzdHVkZW50aXplZCBCcmV1c2NoLVBhZ2FuIHRlc3QgeWllbGRzIGFuIGV4dHJlbWVseSBsb3cgcC12YWx1ZSAoMS41MThlLTA3KSwgd2hpY2ggbGVhZHMgdXMgdG8gc3Ryb25nbHkgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgb2YgaG9tb3NjZWRhc3RpY2l0eSBpbiB0aGUgZG1vZGVsMiBtb2RlbC4gV2l0aCBzdWNoIGEgbG93IHAgdmFsdWUsIHdlIGNhbiBzdHJvbmdseSBjb25jbHVkZSB0aGF0IGhldGVyb3NrZWRhc3RpY2l0eSBleGlzdHMgaW4gdGhlIG1vZGVsIHJlc2lkdWFscy4gVGhlIHNpZ25pZmljYW5jZSBsZXZlbCBpcyBtdWNoIGxvd2VyIHRoYW4gMC4wNSwgd2hpY2ggcmVpbmZvcmNlcyB0aGlzIGNvbmNsdXNpb24uCgoKYGBge3J9CiMgTm9ybWFsaXR5IG9mIFJlc2lkdWFscwpxcW5vcm0oZG1vZGVsMiRyZXNpZHVhbHMpCnFxbGluZShkbW9kZWwyJHJlc2lkdWFscykKc2hhcGlyby50ZXN0KGRtb2RlbDIkcmVzaWR1YWxzKQpgYGAKCgpUaGUgU2hhcGlyby1XaWxrIG5vcm1hbGl0eSB0ZXN0IHNob3dzIGFuIGV4dHJlbWVseSBsb3cgcC12YWx1ZSAoMS4xNjRlLTEyKSwgbGVzcyB0YWggcD0wLjA1LiBJbmRpY2F0aW5nIHRoYXQgdGhlIHJlc2lkdWFscyBmcm9tIHRoZSBkbW9kZWwyIG1vZGVsIGRvIG5vdCBmb2xsb3cgYSBub3JtYWwgZGlzdHJpYnV0aW9uLiBUaGVyZWZvcmUsIHdlIGNhbiBzdHJvbmdseSByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHRoZSByZXNpZHVhbHMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiBUaGlzIHJlc3VsdCBzdWdnZXN0cyB0aGF0IHRoZSBtb2RlbCBkb2VzIG5vdCBtZWV0IHRoZSBhc3N1bXB0aW9uIG9mIG5vcm1hbGl0eSBvZiBlcnJvcnMuCgoKIyMjIyBNT0RFTCAzCgpgYGB7cn0KZG1vZGVsMzwtbG0obG9nKG1lZHYpIH4gK0koY21lZHZeMikrbm94K3JtK25veCtsc3RhdCtjcmltLGRhdGE9ZGF0YXNldCkKc3VtbWFyeShkbW9kZWwzKSAKYGBgClRoZSBtb2RlbCBoYXMgYSBoaWdoIGNhcGFjaXR5IHRvIGV4cGxhaW4gdmFyaWF0aW9ucyBpbiB0aGUgbG9nYXJpdGhtIG9mIGhvdXNlIHByaWNlcywgd2l0aCBhbiBhZGp1c3RlZCBSLXNxdWFyZWQgb2YgYXBwcm94aW1hdGVseSAwLjg4OTguCgpPZiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzLCAiSShjbWVkdl4yKSIgKGEgcXVhZHJhdGljIHRyYW5zZm9ybWF0aW9uIG9mIHRoZSBhdmVyYWdlIGhvdXNlIHByaWNlKSwgIm5veCIgKGNvbmNlbnRyYXRpb24gb2Ygbml0cm9nZW4gb3hpZGVzKSwgInJtIiAoYXZlcmFnZSBudW1iZXIgb2Ygcm9vbXMgcGVyIGhvdXNlKSwgImxzdGF0ICIgKHBlcmNlbnRhZ2Ugb2YgcG9wdWxhdGlvbiB3aXRoIGxvdyBzdGF0dXMpIGFuZCAiY3JpbSIgKGNyaW1lIHJhdGUpIGFyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LgoKVGhlIGNvZWZmaWNpZW50IG9mICJJKGNtZWR2XjIpIiBpcyBwb3NpdGl2ZSwgc3VnZ2VzdGluZyBhIHBvc2l0aXZlIHF1YWRyYXRpYyByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdHJhbnNmb3JtZWQgdmFyaWFibGUgYW5kIHRoZSBsb2dhcml0aG0gb2YgaG91c2UgcHJpY2VzLgoKVGhlIGludGVyY2VwdCBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGFuZCBoYXMgYSBwb3NpdGl2ZSB2YWx1ZSwgaW5kaWNhdGluZyBhIGJhc2UgdmFsdWUgaW4gdGhlIGxvZ2FyaXRobSBvZiBob3VzZSBwcmljZXMuCgpPdmVyYWxsLCB0aGUgbW9kZWwgYXMgYSB3aG9sZSBpcyBoaWdobHkgc2lnbmlmaWNhbnQsIHdpdGggYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IEYgdmFsdWUuCgpUaGUgbW9kZWwgaGFzIGEgZ29vZCBmaXQgdG8gdGhlIGRhdGEsIHdpdGggYSBsb3cgcmVzaWR1YWwgc3RhbmRhcmQgZXJyb3Igb2YgYXBwcm94aW1hdGVseSAwLjEzNjMuCgojIyMjIERpYWdub3N0aWMgdGVzdHMgTU9ERUwgMwoKYGBge3J9CiMgTXVsdGljb2xsaW5lYXJpdHkKCnZpZihkbW9kZWwzKQpgYGAKU2luY2Ugbm8gdmFsdWUgZXhjZWVkcyB0aGUgdGhyZXNob2xkIG9mIDEwLCBtdWx0aWN1bGlvbmFsaXR5IGlzIG5vdCBvYnNlcnZlZCwgdGhhdCBpcywgdGhlcmUgaXMgbm8gY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzLgoKCmBgYHtyfQojIEhldGVyb3NjZWRhc3RpY2l0eQoKYnB0ZXN0KGRtb2RlbDMpCmBgYAoKRWwgdGVzdCBkZSBCcmV1c2NoLVBhZ2FuIGFycm9qYSB1biB2YWxvciBwIG11eSBjZXJjYW5vIGEgY2VybyAocC12YWx1ZSA8IDIuMmUtMTYpLCBsbyBxdWUgaW5kaWNhIHVuYSBmdWVydGUgZXZpZGVuY2lhIGVuIGNvbnRyYSBkZSBsYSBoaXDDs3Rlc2lzIG51bGEgZGUgaG9tb2NlZGFzdGljaWRhZC4gUG9yIGxvIHRhbnRvLCBwb2RlbW9zIGNvbmNsdWlyIHF1ZSBleGlzdGUgaGV0ZXJvY2VkYXN0aWNpZGFkIGVuIGVsIG1vZGVsbyBkbW9kZWwzLCBsbyBxdWUgc3VnaWVyZSBxdWUgbGEgdmFyaWFuemEgZGUgbG9zIGVycm9yZXMgbm8gZXMgY29uc3RhbnRlIGVuIHRvZGFzIGxhcyBvYnNlcnZhY2lvbmVzIHkgcXVlIHBvZHLDrWEgaGFiZXIgcHJvYmxlbWFzIGRlIGRpc3BlcnNpw7NuIGVuIGVsIG1vZGVsby4KCgpgYGB7cn0KIyBOb3JtYWxpdHkgb2YgUmVzaWR1YWxzCnFxbm9ybShkbW9kZWwzJHJlc2lkdWFscykKcXFsaW5lKGRtb2RlbDMkcmVzaWR1YWxzKQpzaGFwaXJvLnRlc3QoZG1vZGVsMyRyZXNpZHVhbHMpCmBgYAoKVGhlIFNoYXBpcm8tV2lsayBub3JtYWxpdHkgdGVzdCB5aWVsZHMgYW4gZXh0cmVtZWx5IGxvdyBwLXZhbHVlIChwLXZhbHVlID0gMS45NzJlLTE0KSwgaW5kaWNhdGluZyBzdHJvbmcgZXZpZGVuY2UgYWdhaW5zdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgdGhlIHJlc2lkdWFscyBmb2xsb3cgYSBub3JtYWwgZGlzdHJpYnV0aW9uLiBUaGVyZWZvcmUsIHdlIGNhbiBjb25jbHVkZSB0aGF0IHRoZSByZXNpZHVhbHMgZG8gbm90IGZvbGxvdyBhIG5vcm1hbCBkaXN0cmlidXRpb24sIHN1Z2dlc3RpbmcgdGhhdCB0aGUgYXNzdW1wdGlvbiBvZiBub3JtYWxpdHkgb2YgdGhlIGVycm9ycyBpbiB0aGUgbW9kZWwgbWF5IG5vdCBiZSBhZGVxdWF0ZWx5IG1ldC4gSXQgaXMgaW1wb3J0YW50IHRvIGtlZXAgdGhpcyBub24tbm9ybWFsaXR5IGluIG1pbmQgd2hlbiBpbnRlcnByZXRpbmcgbW9kZWwgcmVzdWx0cyBhbmQgY29uc2lkZXJpbmcgcG9zc2libGUgYWRqdXN0bWVudHMgb3IgdHJhbnNmb3JtYXRpb25zIG9mIHRoZSBkYXRhIGlmIG5lY2Vzc2FyeS4KCmBgYHtyfQpBSUMoZG1vZGVsMSkKQUlDKGRtb2RlbDIpCkFJQyhkbW9kZWwzKQpgYGAKCiMjIyMjIE1vZGVsIFNlbGVjdGlvbgoKVGhlIG1vZGVscyBwcmVzZW50ZWQgcHJvYmxlbXMgb2Ygbm9ybWFsaXR5IGFuZCBoZXRlcm9jZXJhc3RpY2l0eSwgd2hpY2ggaXMgd2h5IGl0IGlzIGltcG9ydGFudCB0byBjb250aW51ZSBtYWtpbmcgZGF0YSB0cmFuc2Zvcm1hdGlvbnMgYW5kIGFwcGx5IG90aGVyIHJlZ3VsYXJpemF0aW9uIG1ldGhvZHMgdG8gYWNoaWV2ZSBhIG1vcmUgcHJlY2lzZSBhbmQgcmVsaWFibGUgbW9kZWwgZm9yIHByZWRpY3Rpb25zLiBPbiB0aGUgb3RoZXIgaGFuZCwgYmVjYXVzZSBtb3N0IG9mIHRoZSB2YXJpYWJsZXMgYXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIGhhdmUgYSBoaWdoZXIgci1zcXVhcmVkIHZhbHVlLCBkbyBub3QgcHJlc2VudCBtdWx0aWN1bGluYWxpdHkgYW5kIGhhdmUgYSBsb3dlciBBSUMgdmFsdWUsIG1vZGVsIDMgaXMgY2hvc2VuIGFzIHRoZSBiZXN0IG9wdGlvbiB0byBmaXQgb3VyIG5lZWRzLiBkYXRhLiBJdCBpcyBhbHNvIGltcG9ydGFudCB0byBtZW50aW9uIHRoYXQgaGV0ZXJvY2VyYXN0aWNpdHkgaXMgYSBwcm9ibGVtIGluaGVyZW50IHRvIHRoZSBuYXR1cmUgb2YgdGhlIGRhdGEsIHNpbmNlIGRhdGEgZnJvbSBvbmUgcG9pbnQgaW4gdGltZSBmcm9tIHZhcmlvdXMgVVMgc3RhdGVzIGFyZSBiZWluZyBzdHVkaWVkLCB0aGVyZWZvcmUgdGhlIHZhcmlhbmNlcyB3aWxsIGRpZmZlciB3aGVuIHN0dWR5aW5nIG1hbnkgZ3JvdXBzIG9mIGRhdGEgd2l0aCBjaGFyYWN0ZXJpc3RpY3MgZGlmZmVyZW50LgoKIyMjIE1vZGVsIGludGVycHJldGF0aW9uCgpUaGUgbW9kZWwgaGFzIGEgaGlnaCBjYXBhY2l0eSB0byBleHBsYWluIHZhcmlhdGlvbnMgaW4gdGhlIGxvZ2FyaXRobSBvZiBob3VzZSBwcmljZXMsIHdpdGggYW4gYWRqdXN0ZWQgUi1zcXVhcmVkIG9mIGFwcHJveGltYXRlbHkgMC44ODk4LgoKT2YgdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlcywgIkkoY21lZHZeMikiIChhIHF1YWRyYXRpYyB0cmFuc2Zvcm1hdGlvbiBvZiB0aGUgYXZlcmFnZSBob3VzZSBwcmljZSksICJub3giIChjb25jZW50cmF0aW9uIG9mIG5pdHJvZ2VuIG94aWRlcyksICJybSIgKGF2ZXJhZ2UgbnVtYmVyIG9mIHJvb21zIHBlciBob3VzZSksICJsc3RhdCAiIChwZXJjZW50YWdlIG9mIHBvcHVsYXRpb24gd2l0aCBsb3cgc3RhdHVzKSBhbmQgImNyaW0iIChjcmltZSByYXRlKSBhcmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4KClRoZSBjb2VmZmljaWVudCBvZiAiSShjbWVkdl4yKSIgaXMgcG9zaXRpdmUsIHN1Z2dlc3RpbmcgYSBwb3NpdGl2ZSBxdWFkcmF0aWMgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHRyYW5zZm9ybWVkIHZhcmlhYmxlIGFuZCB0aGUgbG9nYXJpdGhtIG9mIGhvdXNlIHByaWNlcy4KClRoZSBpbnRlcmNlcHQgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBhbmQgaGFzIGEgcG9zaXRpdmUgdmFsdWUsIGluZGljYXRpbmcgYSBiYXNlIHZhbHVlIGluIHRoZSBsb2dhcml0aG0gb2YgaG91c2UgcHJpY2VzLgoKT3ZlcmFsbCwgdGhlIG1vZGVsIGFzIGEgd2hvbGUgaXMgaGlnaGx5IHNpZ25pZmljYW50LCB3aXRoIGEgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBGIHZhbHVlLgoKVGhlIG1vZGVsIGhhcyBhIGdvb2QgZml0IHRvIHRoZSBkYXRhLCB3aXRoIGEgbG93IHJlc2lkdWFsIHN0YW5kYXJkIGVycm9yIG9mIGFwcHJveGltYXRlbHkgMC4xMzYzLgoKLSBDb2VmZmljaWVudCBpbnRlcnByZXRhdGlvbnM6CgotIC0gLSBJbnRlY2VwdCAoMy4zMzJlKzAwKTogSWYgYWxsIHByZWRpY3RvciB2YXJpYWJsZXMgYXJlIHplcm8sIHRoZSBsb2dhcml0aG0gb2YgdGhlIGF2ZXJhZ2UgaG9tZSB2YWx1ZSBpcyBlc3RpbWF0ZWQgYXQgMy4zMzIuCi0gLSAtIEkoY21lZHZeMikgKDQuODIwZS0wNCk6IEZvciBldmVyeSBvbmUtdW5pdCBpbmNyZWFzZSBpbiB0aGUgc3F1YXJlIG9mIGNtZWR2LCB0aGUgbG9nYXJpdGhtIG9mIG1lZHYgaW5jcmVhc2VzIGJ5IGFwcHJveGltYXRlbHkgMC4wMDA0ODIuIEl0IGlzIGhpZ2hseSBzaWduaWZpY2FudCB3aXRoIGEgcCB2YWx1ZSA8IDJlLTE2LgotIC0gLSBub3ggKC0xLjg1MWUtMDEpOiBGb3IgZXZlcnkgb25lIHVuaXQgaW5jcmVhc2UgaW4gbm94LCB0aGUgbG9nYXJpdGhtIG9mIG1lZHYgZGVjcmVhc2VzIGJ5IGFwcHJveGltYXRlbHkgMC4xODUxLiBJdCBpcyBzaWduaWZpY2FudCB3aXRoIGEgcCB2YWx1ZSBvZiAwLjAwNTcxLgotIC0gLSBybSAoLTMuMjk0ZS0wMik6IEZvciBldmVyeSBvbmUtcm9vbSBpbmNyZWFzZSBpbiBybSwgdGhlIGxvZ2FyaXRobSBvZiBtZWR2IGRlY3JlYXNlcyBieSBhcHByb3hpbWF0ZWx5IDAuMDMyOTQuIEl0IGlzIHNpZ25pZmljYW50IHdpdGggYSBwIHZhbHVlIG9mIDAuMDA5NjIuCi0gLSAtIGxzdGF0ICgtMS44ODBlLTAyKTogRm9yIGV2ZXJ5IG9uZS11bml0IGluY3JlYXNlIGluIGxzdGF0LCB0aGUgbG9nYXJpdGhtIG9mIG1lZHYgZGVjcmVhc2VzIGJ5IGFwcHJveGltYXRlbHkgMC4wMTg4LiBJdCBpcyBoaWdobHkgc2lnbmlmaWNhbnQgd2l0aCBhIHAgdmFsdWUgPCAyZS0xNi4KLSAtIC0gY3JpbSAoLTkuNzAyZS0wMyk6IEZvciBldmVyeSBvbmUgdW5pdCBpbmNyZWFzZSBpbiB0aGUgY3JpbWUgcmF0ZSwgdGhlIGxvZyBvZiBtZWR2IGRlY3JlYXNlcyBieSBhcHByb3hpbWF0ZWx5IDAuMDA5NzAyLiBJdCBpcyBoaWdobHkgc2lnbmlmaWNhbnQgd2l0aCBhIHAgdmFsdWUgPCAyZS0xNi4KCgpgYGB7cn0KIyBMQVNTTyByZWdyZXNzaW9uIHZpYSBnbG1uZXQgcGFja2FnZSBjYW4gb25seSB0YWtlIG51bWVyaWNhbCBvYnNlcnZhdGlvbnMuIFRoZW4sIHRoZSBkYXRhc2V0IGlzIHRyYW5zZm9ybWVkIHRvIG1vZGVsLm1hdHJpeCgpIGZvcm1hdC4gCiMgSW5kZXBlbmRlbnQgdmFyaWFibGVzCng8LW1vZGVsLm1hdHJpeChsb2cobWVkdikgfiBybStub3grbHN0YXQrY3JpbSxkYXRhc2V0KVssLTFdICMjIyBPTFMgbW9kZWwgc3BlY2lmaWNhdGlvbgojIHg8LW1vZGVsLm1hdHJpeChXZWVrbHlfU2FsZXN+Lix0cmFpbi5kYXRhKVssLTFdICMjIyBtYXRyaXggb2YgaW5kZXBlbmRlbnQgdmFyaWFibGVzIFgncwp5PC1kYXRhc2V0JG1lZHYgIyMjIGRlcGVuZGVudCB2YXJpYWJsZSAKCiMgSW4gZXN0aW1hdGluZyBMQVNTTyByZWdyZXNzaW9uIGl0IGlzIGltcG9ydGFudCB0byBkZWZpbmUgdGhlIGxhbWJkYSB0aGF0IG1pbmltaXplcyB0aGUgcHJlZGljdGlvbiBlcnJvciByYXRlLiAKIyBDcm9zcy12YWxpZGF0aW9uIGVuc3VyZXMgdGhhdCBldmVyeSBkYXRhIC8gb2JzZXJ2YXRpb24gZnJvbSB0aGUgb3JpZ2luYWwgZGF0YXNldCAoZGF0YWlucykgaGFzIGEgY2hhbmNlIG9mIGFwcGVhcmluZyBpbiB0cmFpbiBhbmQgdGVzdCBkYXRhc2V0cy4KIyBGaW5kIHRoZSBiZXN0IGxhbWJkYSB1c2luZyBjcm9zcy12YWxpZGF0aW9uLgpzZXQuc2VlZCgxMjMpIApjdi5sYXNzbzwtY3YuZ2xtbmV0KHgseSxhbHBoYT0xKSAjIGFscGhhID0gMSBmb3IgTEFTU08KCiMgRGlzcGxheSB0aGUgYmVzdCBsYW1iZGEgdmFsdWUKY3YubGFzc28kbGFtYmRhLm1pbiAgICAgICAgICAgICAgICAgICAgICAjIyMgbGFtYmRhOiBhIG51bWVyaWMgdmFsdWUgZGVmaW5pbmcgdGhlIGFtb3VudCBvZiBzaHJpbmthZ2UuIFdoeSBtaW4/IHRoZSBoaWdoZXIgdGhlIHZhbHVlIG9mID8/ICwgdGhlIG1vcmUgcGVuYWxpemF0aW9uIHRoZXJlIGlzCgojIEZpdCB0aGUgZmluYWwgbW9kZWwgb24gdGhlIHRyYWluaW5nIGRhdGEKbGFzc29tb2RlbDwtZ2xtbmV0KHgseSxhbHBoYT0xLGxhbWJkYT1jdi5sYXNzbyRsYW1iZGEubWluKQoKIyBEaXNwbGF5IHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzCmNvZWYobGFzc29tb2RlbCkKCiMgTWFrZSBwcmVkaWN0aW9ucyBvbiB0aGUgdGVzdCBkYXRhCngudGVzdDwtbW9kZWwubWF0cml4KGxvZyhtZWR2KSB+IHJtK25veCtsc3RhdCtjcmltLGRhdGFzZXQpWywtMV0gIyMjIE9MUyBtb2RlbCBzcGVjaWZpY2F0aW9uCiMgeC50ZXN0PC1tb2RlbC5tYXRyaXgoV2Vla2x5X1NhbGVzfi4sdGVzdC5kYXRhKVssLTFdCmxhc3NvcHJlZGljdGlvbnMgPC0gbGFzc29tb2RlbCAlPiUgcHJlZGljdCh4LnRlc3QpICU+JSBhcy52ZWN0b3IoKQoKCiMjIyB2aXN1YWxpemluZyBsYXNzbyByZWdyZXNzaW9uIHJlc3VsdHMgCmxic19mdW4gPC0gZnVuY3Rpb24oZml0LCBvZmZzZXRfeD0xLCAuLi4pIHsKICBMIDwtIGxlbmd0aChmaXQkbGFtYmRhKQogIHggPC0gbG9nKGZpdCRsYW1iZGFbTF0pKyBvZmZzZXRfeAogIHkgPC0gZml0JGJldGFbLCBMXQogIGxhYnMgPC0gbmFtZXMoeSkKICB0ZXh0KHgsIHksIGxhYmVscz1sYWJzLCAuLi4pCn0KCmxhc3NvPC1nbG1uZXQoc2NhbGUoeCkseSxhbHBoYT0xKQoKcGxvdChsYXNzbyx4dmFyPSJsYW1iZGEiLGxhYmVsPVQpCmxic19mdW4obGFzc28pCmFibGluZSh2PWN2Lmxhc3NvJGxhbWJkYS5taW4sY29sPSJyZWQiLGx0eT0yKQphYmxpbmUodj1jdi5sYXNzbyRsYW1iZGEuMXNlLGNvbD0iYmx1ZSIsbHR5PTIpCgpzdW1tYXJ5KGxhc3NvbW9kZWwpCgpgYGAKCi0gLSAtIEludGVyY2VwdDogVGhlIGludGVyY2VwdCB2YWx1ZSBpcyBhcHByb3hpbWF0ZWx5IC0xLjc0NC4gVGhpcyByZXByZXNlbnRzIHRoZSBlc3RpbWF0ZWQgdmFsdWUgb2YgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSAobWVkdikgd2hlbiBhbGwgaW5kZXBlbmRlbnQgdmFyaWFibGVzIGFyZSBlcXVhbCB0byB6ZXJvLgoKLSAtIC0gQ29lZmZpY2llbnRzIG9mIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXM6IFRoZSBtb2RlbCBoYXMgaWRlbnRpZmllZCB0aHJlZSBzaWduaWZpY2FudCB2YXJpYWJsZXMgaW4gcHJlZGljdGluZyB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIChtZWR2KS4gVGhlc2UgYXJlICJybSIgKG51bWJlciBvZiByb29tcyksICJsc3RhdCIgKHBlcmNlbnRhZ2Ugb2YgbG93LXN0YXR1cyBwb3B1bGF0aW9uKSwgYW5kICJjcmltIiAoY3JpbWUgcmF0ZSkuIFRoZSBtYWduaXR1ZGUgb2YgdGhlc2UgY29lZmZpY2llbnRzIGluZGljYXRlcyB0aGVpciBpbXBhY3Qgb24gdGhlIGRlcGVuZGVudCB2YXJpYWJsZS4gRm9yIGV4YW1wbGUsIGEgb25lIHVuaXQgaW5jcmVhc2UgaW4gInJtIiByZXN1bHRzIGluIGFuIGluY3JlYXNlIG9mIGFwcHJveGltYXRlbHkgNS4wNyB1bml0cyBpbiBtZWR2LCBob2xkaW5nIHRoZSBvdGhlciB2YXJpYWJsZXMgY29uc3RhbnQuCgotIC0gLSBWYXJpYWJsZSAibm94IiAobml0cm9nZW4gb3hpZGUpOiBUaGUgY29lZmZpY2llbnQgZm9yICJub3giIGlzIG1hcmtlZCAiLiIuIFRoaXMgbWVhbnMgdGhhdCB0aGUgbW9kZWwgaGFzIGNvbnNpZGVyZWQgdGhhdCB0aGlzIHZhcmlhYmxlIGRvZXMgbm90IGhhdmUgYSBzaWduaWZpY2FudCBpbXBhY3Qgb24gdGhlIGRlcGVuZGVudCB2YXJpYWJsZSBhZnRlciBMMSByZWd1bGFyaXphdGlvbi4KCi0gLSAtIE1vZGVsIGRpbWVuc2lvbjogVGhlIG1vZGVsIGhhcyBlc3RpbWF0ZWQgZm91ciBub24tbnVsbCBjb2VmZmljaWVudHMgKGRmKSBhbmQgYSBjb25zdGFudCB0ZXJtLCB3aGljaCBtZWFucyB0aGF0IGl0IGNvbnNpZGVycyBmb3VyIGluZGVwZW5kZW50IHZhcmlhYmxlcyBhcyByZWxldmFudCBmb3IgdGhlIHByZWRpY3Rpb24gb2YgbWVkdi4KCgojIyMjIyBTZXJpYWwgQXV0b2NvcnJlbGF0aW9uCgpTaW5jZSB3ZSBhcmUgd29ya2luZyB3aXRoIGEgZGF0YWJhc2UgdGhhdCBjb2xsZWN0cyBpbmZvcm1hdGlvbiBvbiB0aGUgdmFsdWUgb2YgaG9tZXMgYXQgYSBzcGVjaWZpYyBwb2ludCBpbiB0aW1lLCB0aGV5IGFyZSBjcm9zcy1zZWN0aW9uYWwgZGF0YSBhbmQgdGhlcmVmb3JlIGRvIG5vdCBoYXZlIHNlcmlhbCBhdXRvY29ycmVsYXRpb24uCgojIENvbmNsdXNpb25zCgpJbiBzdW1tYXJ5LCB0aGFua3MgdG8gdGhlIGV4cGxvcmF0b3J5IGFuYWx5c2lzIG9mIHRoZSBkYXRhLCB3ZSBoYWQgYSBjbGVhciBpZGVhIG9mIHRoZSBkYXRhIHdlIGhhZCBhbmQgdGhlIHRyYW5zZm9ybWF0aW9ucyBuZWNlc3NhcnkgdG8gYWNoaWV2ZSBhIHJvYnVzdCBtb2RlbC4gTW9kZWwgMyBzdGFuZHMgb3V0IGFzIGEgbW9kZWwgd2l0aCBhIHZlcnkgZ29vZCBmaXQgdG8gdGhlIGRhdGEsIHRoYW5rcyB0byBnb29kIHZhbHVlcyBvZiBBSUMgYW5kIFIgc3F1YXJlZCwgYW5kIGl0IHdhcyBhbHNvIGEgbW9kZWwgdGhhdCBoYWQgbWFueSB2YXJpYWJsZXMgd2l0aCBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2UgYW5kIHRoYXQgaGVscGVkIHVzIGNvcnJvYm9yYXRlIG91ciBoeXBvdGhlc2VzLiBIb3dldmVyLCBkZXNwaXRlIHJlZHVjaW5nIGhldGVyb2NlcmFzdGljaXR5IHdpdGggZGF0YSB0cmFuc2Zvcm1hdGlvbnMgYW5kIHdpdGggdGhlIGxhc3NvIG1vZGVsLCBpdCBpcyBpbXBvcnRhbnQgdG8gY29udGludWUgYXBwbHlpbmcgb3RoZXIgdHJhbnNmb3JtYXRpb24gdGVjaG5pcXVlcyB0byBhdm9pZCB0aGlzIHByb2JsZW0sIGFsdGhvdWdoIGFzIGFscmVhZHkgbWVudGlvbmVkLCBpdCBpcyBpbXBvcnRhbnQgdG8gaGlnaGxpZ2h0IHRoYXQgaGV0ZXJvY2VyYXN0aWNpdHkgaXMgYSBuYXR1cmFsIHByb2JsZW0gb2YgVGhlIGRhdGEgd2UgYXJlIHdvcmtpbmcgd2l0aCBhcmUgY3Jvc3Mtc2VjdGlvbmFsIGRhdGEgZnJvbSBzZXZlcmFsIFVTIHN0YXRlcyBhdCBhIGdpdmVuIHBvaW50IGluIHRpbWUsIHNvIHRoZSB2YXJpYW5jZXMgd2lsbCBoYXJkbHkgYmUgaG9tb2dlbmVvdXMuClJlZ2FyZGluZyB0aGUgaW5zaWdodHMgZm91bmQsIHRoZSBncmVhdCBpbXBhY3QgdGhhdCB0aGUgY3JpbWUgcmF0ZSBoYXMgb24gaG9tZXMgaXMgaGlnaGxpZ2h0ZWQsIHNpbmNlIHRoaXMgdmFyaWFibGUgd2FzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIHdpdGggYSBoaWdoIGFuZCBuZWdhdGl2ZSBjb2VmZmljaWVudCwgc28gYW4gaW5jcmVhc2UgaW4gY3JpbWUgbGVhZHMgdG8gYSBjb25zaWRlcmFibGUgbG9zcyBpbiB0aGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5LiB0aGUgaG9tZXMsIHdoaWNoIGlzIHdoeSBpdCBpcyBpbXBvcnRhbnQgdG8gZ3VhcmFudGVlIHRoZSBzZWN1cml0eSBvZiB0aGUgbmVpZ2hib3Job29kcyBhbmQgdGh1cyBiZSBhYmxlIHRvIGluY3JlYXNlIHRoZSB2YWx1ZSBvZiB0aGUgaG9tZXMuIE9uIHRoZSBvdGhlciBoYW5kLCBhaXIgcXVhbGl0eSwgYXMgdGhvdWdodCwgdHVybmVkIG91dCB0byBoYXZlIGEgbmVnYXRpdmUgc2lnbmlmaWNhbmNlLCB3aGljaCBoaWdobGlnaHRzIHRoZSB0ZW5kZW5jeSBvZiBwZW9wbGUgdG8gbGl2ZSBpbiBxdWlldCBwbGFjZXMsIHdpdGggZXhjZWxsZW50IGFpciBhbmQgYSB2ZXJ5IGdvb2QgcXVhbGl0eSBvZiBsaWZlLiBIb3dldmVyLCBzb21ldGhpbmcgaW50ZXJlc3Rpbmcgd2FzIHNlZWluZyB0aGF0IHRoZSBudW1iZXIgb2Ygcm9vbXMgdHVybmVkIG91dCB0byBoYXZlIGEgbmVnYXRpdmUgcmVsYXRpb25zaGlwIHdpdGggdGhlIHZhbHVlIG9mIHRoZSBob21lcywgc29tZXRoaW5nIHZlcnkgcGVjdWxpYXIgYW5kIHRoYXQgY291bGQgYmUgcmVsYXRlZCB0byB0aGUgZmFjdCB0aGF0IHBlcmhhcHMgcGVvcGxlIHZhbHVlIG90aGVyIG1vcmUgaW1wb3J0YW50IGZhY3RvcnMgbW9yZSB0aGFuIHRoZSBudW1iZXIgb2Ygcm9vbXMuCgpMaWtld2lzZSwgdGhlIHZhbHVlIG9mIGhvbWVzIGlzIGEgdmFyaWFibGUgdGhhdCBkZXBlbmRzIG9uIG1hbnkgb3RoZXIgaW5kZXBlbmRlbnQgdmFyaWFibGVzIG9mIHRob3NlIHN0dWRpZWQgaGVyZSwgaXQgd2lsbCBiZSBpbnRlcmVzdGluZyB0byBjb21wbGVtZW50IHRoaXMgYW5hbHlzaXMgd2l0aCB0aGUgZWNvbm9taWMgcHJvamVjdGlvbnMgb2YgdGhlIGFyZWFzIGluIHRoZSBmdXR1cmUsIHRoZSBzdG9yZXMgdGhhdCBhcmUgYXJvdW5kLCB0aGUgZGlzdGFuY2VzIHRvIHRoZSBjaXRpZXMsIGV0Yy4KClJlZ2FyZGluZyB0aGUgYXBwbGljYXRpb24gb2YgbGluZWFyIHJlZ3Jlc3Npb24gaW4gdGhlIGNvbnRleHQgb2YgcHJlZGljdGl2ZSBhbmFseXRpY3MsIHRoaXMgYXBwcm9hY2ggYXBwZWFycyB0byBiZSBhIHZhbHVhYmxlIHRvb2wuIExpbmVhciByZWdyZXNzaW9uIG1vZGVscyBwcm92aWRlIGFuIHVuZGVyc3RhbmRpbmcgb2YgaG93IHZhcmlvdXMgY2hhcmFjdGVyaXN0aWNzIGFmZmVjdCBwcm9wZXJ0eSB2YWx1ZXMgYW5kIGFyZSB0aGVyZWZvcmUgZXNzZW50aWFsIGZvciBtYWtpbmcgaW5mb3JtZWQgcmVhbCBlc3RhdGUgZGVjaXNpb25zLiBGdXJ0aGVybW9yZSwgdGhlIGlkZW50aWZpY2F0aW9uIG9mIHNpZ25pZmljYW50IHZhcmlhYmxlcywgc3VjaCBhcyBhaXIgcXVhbGl0eSAobm94KSBhbmQgY3JpbWUgcmF0ZSAoY3JpbSksIGNhbiBwcm92aWRlIGNydWNpYWwgaW5mb3JtYXRpb24gZm9yIHRoZSBwbGFubmluZyBhbmQgZGV2ZWxvcG1lbnQgb2YgZnV0dXJlIHJlYWwgZXN0YXRlIHByb2plY3RzLiBUaGlzIHByZWRpY3RpdmUgYW5hbHl0aWNzIGNhcGFiaWxpdHkgY2FuIHNpZ25pZmljYW50bHkgaW1wcm92ZSBlZmZpY2llbmN5IGFuZCBlZmZlY3RpdmVuZXNzIGluIHByb3BlcnR5IGludmVzdG1lbnQgYW5kIG1hbmFnZW1lbnQsIHN1cHBvcnRpbmcgdGhlIGNvbnRpbnVlZCBpbXBvcnRhbmNlIG9mIGxpbmVhciByZWdyZXNzaW9uIGluIGFuYWx5c2lzIGFuZCBkZWNpc2lvbiBtYWtpbmcgaW4gdGhlIHJlYWwgZXN0YXRlIG1hcmtldC4=