- (Data: “asphalt”) The data (n = 31) deals with pavement durability which contains measurements on the following variables: y= change in rut depth
x1= viscosity of rut depth
x2= % of asphalt in the surface course
x3= % of asphalt in the base course
x4= % of fines in the surface course
x5= % of voids in the surface course
x6= run indicator
x6 is a run indicator which separates the data into two different experimental runs:
Fit the full regression model with six predictors to the data set and use the ANOVA table to assess its overall fit.
Exhibit the fitted equation for y when the run indicator is 1 and when it is -1.
Use All Possible Subsets regression to select the best model based on their R2 values. Perform all diagnostic tests and check the adequacy of this model.
library(readr)
library(dplyr)
library(tidyverse)
library(car)
We have imported the necessary packages into R which will come handy in our further assignment.
#import the data
asphalt <- read.csv("asphalt.csv")
asphalt
Here we have imported the data into R and have a glimpse at our asphalt dataset.
1.a) Regression Model
asphaltmodel <- lm(y~visc+surf+base+fines+voids+run, asphalt)
summary(asphaltmodel)
Call:
lm(formula = y ~ visc + surf + base + fines + voids + run, data = asphalt)
Residuals:
Min 1Q Median 3Q Max
-5.6781 -1.8309 0.1751 1.4858 11.1262
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -62.970450 36.118989 -1.743 0.0941 .
visc 0.003071 0.008161 0.376 0.7100
surf 7.498028 3.967155 1.890 0.0709 .
base 6.225817 4.812723 1.294 0.2081
fines 0.522211 1.174673 0.445 0.6606
voids -0.241275 1.684963 -0.143 0.8873
run -5.386297 0.985384 -5.466 1.28e-05 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 3.94 on 24 degrees of freedom
Multiple R-squared: 0.7274, Adjusted R-squared: 0.6592
F-statistic: 10.67 on 6 and 24 DF, p-value: 8.588e-06
Above we have fitted the regression model with all the six predictors available in the dataset by using Lm() Function and named it as asphaltmodel. Here, we can see that the R2 value is 0.7274, Adjusted R-square is 0.6592. To check the overall fit, we will use Anova function
anova(asphaltmodel)
Analysis of Variance Table
Response: y
Df Sum Sq Mean Sq F value Pr(>F)
visc 1 424.93 424.93 27.3767 2.310e-05 ***
surf 1 16.13 16.13 1.0393 0.3182
base 1 28.40 28.40 1.8295 0.1888
fines 1 19.73 19.73 1.2711 0.2707
voids 1 41.05 41.05 2.6450 0.1169
run 1 463.77 463.77 29.8792 1.283e-05 ***
Residuals 24 372.51 15.52
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
After performing the Anova test, we found out that P value for visc and run variables are 0.001 which is less than 0.005. Values for all the other variables are greater then 0.005.
1.b) Fitting Equation.
prun <- filter(asphalt, run == "1")
prunmodel <- lm(y~visc+surf+base+fines+voids, prun)
summary(prunmodel)
Call:
lm(formula = y ~ visc + surf + base + fines + voids, data = prun)
Residuals:
Min 1Q Median 3Q Max
-0.61544 -0.11773 -0.05099 0.13625 0.46611
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -4.0419695 4.7947737 -0.843 0.421
visc -0.0024706 0.0008347 -2.960 0.016 *
surf 0.1755011 0.5703476 0.308 0.765
base 0.3505746 0.8900850 0.394 0.703
fines 0.1902141 0.2179108 0.873 0.405
voids 0.2962432 0.2299413 1.288 0.230
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.3703 on 9 degrees of freedom
Multiple R-squared: 0.6382, Adjusted R-squared: 0.4372
F-statistic: 3.175 on 5 and 9 DF, p-value: 0.06313
nrun <- filter(asphalt, run == "-1")
nrunmodel <- lm(y~visc+surf+base+fines+voids, nrun)
summary(nrunmodel)
Call:
lm(formula = y ~ visc + surf + base + fines + voids, data = nrun)
Residuals:
Min 1Q Median 3Q Max
-4.5155 -2.1402 -0.3626 1.8615 5.5877
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -147.0491 69.9536 -2.102 0.0619 .
visc -1.7729 0.6298 -2.815 0.0183 *
surf 19.5080 7.5535 2.583 0.0273 *
base 10.4327 5.9136 1.764 0.1082
fines 0.1704 1.4195 0.120 0.9068
voids 3.6021 2.8706 1.255 0.2381
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 3.504 on 10 degrees of freedom
Multiple R-squared: 0.7356, Adjusted R-squared: 0.6035
F-statistic: 5.565 on 5 and 10 DF, p-value: 0.01044
In the above step, we have subset our data into 2 category based on run variables, where values are 1 and -1. We need to find the fitted equation for Y variable with both the run values.
For that, we created prun data frame for run = 1 and nrun dataframe for run = -1. The fitted quation for prun is Y^ = -4.04 -0.02X1+ 0.17X2+ 0.35X3+ 0.19X4+ 0.29X5.
We can also see that the P-value is smaller then 0.05, therefore we can say that the model is significant and we can reject H0. Multiple R square is 0.638 and Adjusted R- square is observed as 0.437.
For *run = -1, we created a model based on dataset nrun. The fitted equation for nrun is Y^ = -147.04 -1.77X1 +19.50X2 +10.43X3 +0.17X4 +3.60X5**.
1.c) Use All Possible Subsets regression to select the best model based on their R2 values.
library(leaps)
package 㤼㸱leaps㤼㸲 was built under R version 4.0.4
r<-leaps::regsubsets(y~visc+surf+base+fines+voids+run, data=asphalt)
summary(r)
Subset selection object
Call: regsubsets.formula(y ~ visc + surf + base + fines + voids + run,
data = asphalt)
6 Variables (and intercept)
Forced in Forced out
visc FALSE FALSE
surf FALSE FALSE
base FALSE FALSE
fines FALSE FALSE
voids FALSE FALSE
run FALSE FALSE
1 subsets of each size up to 6
Selection Algorithm: exhaustive
visc surf base fines voids run
1 ( 1 ) " " " " " " " " " " "*"
2 ( 1 ) " " "*" " " " " " " "*"
3 ( 1 ) " " "*" "*" " " " " "*"
4 ( 1 ) " " "*" "*" "*" " " "*"
5 ( 1 ) "*" "*" "*" "*" " " "*"
6 ( 1 ) "*" "*" "*" "*" "*" "*"
par(mfrow=c(1,1))
plot(r, scale="adjr2")

Here, to check select the best possible regression model bases on R2, we have used leaps functions. Through the above graph, we can see that the best model based on R2 are surf, base and run.
1.c) All the diagnostic test to check the adequacy values.
To check the model adequacy, we are evaluating the assumptions of the model.
par(mfrow = c(2,2))
plot(asphaltmodel)

In the above plot we can see 4 Diagnostic plots known as Residuals plot, QQ plots, Scale-location plot and leverage plots.
In the 1st graph we can see that on X axis has predicted value known as Y^(y hat) and on y axis there are residuals and errors. Here we can the line is not flat and the points are looking as a bunch of clouds which means that linearity assumption is violated here.
In the next Graph (QQ plot), here y axis is ordered, observed and Standardized residuals and on X axis it has ordered theoretical residuals. In the graph we can see that residuals are truly normally distributed as in the beginning some were falling out of line but after that all the points are falling on a roughly straight line.
The next two shows that the regression is non-linear, non-constant variance.
To test further, if any assumptions are violated or not. We will perform some tests.
durbinWatsonTest(asphaltmodel)
lag Autocorrelation D-W Statistic p-value
1 -0.08199506 2.09818 0.968
Alternative hypothesis: rho != 0
H0: Errors are uncorrelated H1: Errors are correlated
From the Durbin Waston test, we found out that p value is 0.984. This indictes negative/ No autocorrelation in the model. P value is grater then 0.05.
shapiro.test(asphaltmodel$residuals)
Shapiro-Wilk normality test
data: asphaltmodel$residuals
W = 0.93011, p-value = 0.04416
H0: Errors are normally distributed H1: Errors are not normally distributed
From the Shapiro-wilk normality test, after observing the P value of 0.015. We can say that the normality is violated here as p vale is greater then 0.05.
ncvTest(asphaltmodel)
Non-constant Variance Score Test
Variance formula: ~ fitted.values
Chisquare = 12.3959, Df = 1, p = 0.00043028
H0: Errors have a constant variance H1: Errors have a non-constant variance
Here, we can see that p value is less then 0.05. therefore, we can say that the constant variance assumptions is violated here.
2. (Data: “byssinosis”)
The data were collected from a group of workers in the cotton industry to assess the prevalence of the lung disease byssinosis among these workers. This disease is caused by long term exposure to particles of cotton, hemp, flax and jute working in this type of environment. It can result in asthma-like symptom which can lead to death among sufferers. The response variable y is binary and refer to number of workers suffering (response = yes) and not suffering (response = no) and the predictors are:
xl=dustiness of the workplace (1 = high, 2 = medium, 3 = low) x2=race ( 1 = European, 2 = other) x3=sex ( 1 = male, 2 = female) x4=smoking history (1 = smoker, 2 = nonsmoker) x5=length of employment in the cotton industry (1 = less than 10 years, 2 = between 10 and 20 years,3 = more than 20 years)
Notice that all five predictors are qualitative variables and the responses are entered in the event/trial format.
- Fit a logistic regression model to the data set and discuss which of the predictors have a significant effect on the presence of byssinosis.
- Discuss the adequacy of the logistic regression model.
- (Needs to be done manually or by hand) From the final model you have selected in part (a), determine the probability that a person will suffer from byssinosis if given:
- xl = 2, x2 = 2, x3 = 1, x4 = 2, x5 = 3,
- xl = 1, x2 = 2, x3 = 2, x4 = 1, x5 = 3
- xl = 2, x2 = 1, x3 = 1, x4 = 2, x5 = 2,
- xl = 3, x2 = 1, x3 = 2, x4 = 2, x5 = 1.
#Q2
byssinosis <- read.csv("byssinosis.csv")
byssinosis
Here, we imported the byssinosis dataset that will be used in our Q2.
(a) Fit a logistic regression model to the data set and discuss which of the predictors have a significant effect on the presence of byssinosis.
#2.a)
glmmodel <- glm(cbind(BysYes,BysNo)~Dust+Race+Sex+Smoke+Employ,
family=binomial,byssinosis)
summary.glm(glmmodel)
Call:
glm(formula = cbind(BysYes, BysNo) ~ Dust + Race + Sex + Smoke +
Employ, family = binomial, data = byssinosis)
Deviance Residuals:
Min 1Q Median 3Q Max
-3.4126 -0.7573 -0.2421 0.3688 1.9804
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.4852 0.6060 -0.801 0.42331
Dust -1.3751 0.1155 -11.901 < 2e-16 ***
Race 0.2463 0.2061 1.195 0.23203
Sex -0.2590 0.2116 -1.224 0.22095
Smoke -0.6292 0.1931 -3.259 0.00112 **
Employ 0.3856 0.1069 3.607 0.00031 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 322.527 on 64 degrees of freedom
Residual deviance: 69.509 on 59 degrees of freedom
AIC: 188.19
Number of Fisher Scoring iterations: 5
Here, we have used glm function to fit a logistic regression model and cbind function to bind the columns of Y variable, Family = binomial is used. In the above glm function, we can see that predictors Race, Smoke and Employ has significant impact on the presence of Byssinosis as their P-value is smaller then 0.05. Rest predictors has insignifacnt impat as they have higher P-value then 0.05
2.b) Discuss the adequacy of the logistic regression model.
pchisq(69.509, 59, lower.tail = FALSE)
[1] 0.1645647
To check the adequacy of the logistic regression model, we have used pchisq function by using the residual deviance and it’s **Degree of freedom*.
H0: the model fits the data well vs. H1: the model does not fit the data well The chi-square test statistic of 69.509 with 59 degree of freedom gives a p-value of 0.1645, indicating that the null hypothesis is plausible, and we can conclude that logistic model is adequate.
2.c) determine the probability that a person will suffer from byssinosis if given:
i. xl = 2, x2 = 2, x3 = 1, x4 = 2, x5 = 3
1/(1+exp((-1.37*2)+(0.24*2)+(-0.25*1)+(-0.62*2)+(0.38*3)))
[1] 0.9315024
The probability that a person will suffer from byssinosis if xl = 2, x2 = 2, x3 = 1, x4 = 2, x5 = 3 is 0.9315
ii. xl = 1, x2 = 2, x3 = 2, x4 = 1, x5 = 3
1/(1+exp((-1.37*1)+(0.24*2)+(-0.25*2)+(-0.62*1)+(0.38*3)))
[1] 0.7047457
The probability that a person will suffer from byssinosis if xl = 1, x2 = 2, x3 = 2, x4 = 1, x5 = 3 is 0.7047
iii. xl = 2, x2 = 1, x3 = 1, x4 = 2, x5 = 2
1/(1+exp((-1.37*2)+(0.24*1)+(-0.25*1)+(-0.62*2)+(0.38*2)))
[1] 0.9619478
The probability that a person will suffer from byssinosis if xl = 2, x2 = 1, x3 = 1, x4 = 2, x5 = 2 is 0.9619
iv. xl = 3, x2 = 1, x3 = 2, x4 = 2, x5 = 1.
1/(1+exp((-1.37*3)+(0.24*1)+(-0.25*2)+(-0.62*2)+(0.38*1)))
[1] 0.994675
The probability that a person will suffer from byssinosis if xl = 3, x2 = 1, x3 = 2, x4 = 2, x5 = 1 is 0.9946
LS0tDQp0aXRsZTogIk1BVEgxMzEyIFJlZ3Jlc3Npb24gQW5hbHlzaXMgU2VtZXN0ZXIgMSwgMjAyMSINCmF1dGhvcjogIlN1bm55IEt1bWFyIFZhaXNobm92KHMzODIyMjk1KSINClN0dWRlbnQgbm8uOiBTMzgyMjI5NQ0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQpzdWJ0aXRsZTogQXNzaWdubWVudDMNCi0tLQ0KMS4gKERhdGE6ICJhc3BoYWx0ICIpDQpUaGUgZGF0YSAobiA9IDMxKSBkZWFscyB3aXRoIHBhdmVtZW50IGR1cmFiaWxpdHkgd2hpY2ggY29udGFpbnMgbWVhc3VyZW1lbnRzIG9uIHRoZSBmb2xsb3dpbmcgdmFyaWFibGVzOg0KeT0gY2hhbmdlIGluIHJ1dCBkZXB0aA0KDQp4MT0gdmlzY29zaXR5IG9mIHJ1dCBkZXB0aA0KDQp4Mj0gJSBvZiBhc3BoYWx0IGluIHRoZSBzdXJmYWNlIGNvdXJzZQ0KDQp4Mz0gJSBvZiBhc3BoYWx0IGluIHRoZSBiYXNlIGNvdXJzZQ0KDQp4ND0gJSBvZiBmaW5lcyBpbiB0aGUgc3VyZmFjZSBjb3Vyc2UNCg0KeDU9ICUgb2Ygdm9pZHMgaW4gdGhlIHN1cmZhY2UgY291cnNlDQoNCng2PSBydW4gaW5kaWNhdG9yDQoNCng2IGlzIGEgcnVuIGluZGljYXRvciB3aGljaCBzZXBhcmF0ZXMgdGhlIGRhdGEgaW50byB0d28gZGlmZmVyZW50IGV4cGVyaW1lbnRhbCBydW5zOg0KDQooYSkgRml0IHRoZSBmdWxsIHJlZ3Jlc3Npb24gbW9kZWwgd2l0aCBzaXggcHJlZGljdG9ycyB0byB0aGUgZGF0YSBzZXQgYW5kIHVzZSB0aGUgQU5PVkEgdGFibGUgdG8gYXNzZXNzIGl0cyBvdmVyYWxsIGZpdC4NCg0KKGIpIEV4aGliaXQgdGhlIGZpdHRlZCBlcXVhdGlvbiBmb3IgeSB3aGVuIHRoZSBydW4gaW5kaWNhdG9yIGlzIDEgYW5kIHdoZW4gaXQgaXMgLTEuDQoNCihjKSBVc2UgQWxsIFBvc3NpYmxlIFN1YnNldHMgcmVncmVzc2lvbiB0byBzZWxlY3QgdGhlIGJlc3QgbW9kZWwgYmFzZWQgb24gdGhlaXIgUjIgdmFsdWVzLiBQZXJmb3JtIGFsbCBkaWFnbm9zdGljIHRlc3RzIGFuZCBjaGVjayB0aGUgYWRlcXVhY3kgb2YgdGhpcyBtb2RlbC4NCg0KIA0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5ncyA9IEZBTFNFfQ0KDQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShjYXIpDQpgYGANCg0KV2UgaGF2ZSBpbXBvcnRlZCB0aGUgbmVjZXNzYXJ5IHBhY2thZ2VzIGludG8gUiB3aGljaCB3aWxsIGNvbWUgaGFuZHkgaW4gb3VyIGZ1cnRoZXIgYXNzaWdubWVudC4NCg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmdzID0gRkFMU0V9DQojaW1wb3J0IHRoZSBkYXRhDQphc3BoYWx0IDwtIHJlYWQuY3N2KCJhc3BoYWx0LmNzdiIpDQphc3BoYWx0DQpgYGANCkhlcmUgd2UgaGF2ZSBpbXBvcnRlZCB0aGUgZGF0YSBpbnRvIFIgYW5kIGhhdmUgYSBnbGltcHNlIGF0IG91ciAqKmFzcGhhbHQqKiBkYXRhc2V0Lg0KDQojIDEuYSkgUmVncmVzc2lvbiBNb2RlbA0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmdzID0gRkFMU0V9DQoNCmFzcGhhbHRtb2RlbCA8LSBsbSh5fnZpc2Mrc3VyZitiYXNlK2ZpbmVzK3ZvaWRzK3J1biwgYXNwaGFsdCkNCnN1bW1hcnkoYXNwaGFsdG1vZGVsKQ0KYGBgDQpBYm92ZSB3ZSBoYXZlIGZpdHRlZCB0aGUgcmVncmVzc2lvbiBtb2RlbCB3aXRoIGFsbCB0aGUgc2l4IHByZWRpY3RvcnMgYXZhaWxhYmxlIGluIHRoZSBkYXRhc2V0IGJ5IHVzaW5nICoqTG0oKSoqIEZ1bmN0aW9uIGFuZCBuYW1lZCBpdCBhcyAqKmFzcGhhbHRtb2RlbCoqLiANCkhlcmUsIHdlIGNhbiBzZWUgdGhhdCB0aGUgUjIgdmFsdWUgaXMgKiowLjcyNzQqKiwgQWRqdXN0ZWQgUi1zcXVhcmUgaXMgKiowLjY1OTIqKi4gDQpUbyBjaGVjayB0aGUgb3ZlcmFsbCBmaXQsIHdlIHdpbGwgdXNlICoqQW5vdmEqKiBmdW5jdGlvbg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmdzID0gRkFMU0V9DQphbm92YShhc3BoYWx0bW9kZWwpDQoNCmBgYA0KQWZ0ZXIgcGVyZm9ybWluZyB0aGUgQW5vdmEgdGVzdCwgd2UgZm91bmQgb3V0IHRoYXQgUCB2YWx1ZSBmb3IgKip2aXNjKiogYW5kICoqcnVuKiogdmFyaWFibGVzIGFyZSAwLjAwMSB3aGljaCBpcyBsZXNzIHRoYW4gMC4wMDUuIFZhbHVlcyBmb3IgYWxsIHRoZSBvdGhlciB2YXJpYWJsZXMgYXJlIGdyZWF0ZXIgdGhlbiAwLjAwNS4gDQoNCiMgMS5iKSBGaXR0aW5nIEVxdWF0aW9uLg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmdzID0gRkFMU0V9DQoNCg0KcHJ1biA8LSBmaWx0ZXIoYXNwaGFsdCwgcnVuID09ICIxIikNCnBydW5tb2RlbCA8LSBsbSh5fnZpc2Mrc3VyZitiYXNlK2ZpbmVzK3ZvaWRzLCBwcnVuKQ0Kc3VtbWFyeShwcnVubW9kZWwpDQoNCm5ydW4gPC0gZmlsdGVyKGFzcGhhbHQsIHJ1biA9PSAiLTEiKQ0KbnJ1bm1vZGVsIDwtIGxtKHl+dmlzYytzdXJmK2Jhc2UrZmluZXMrdm9pZHMsIG5ydW4pDQpzdW1tYXJ5KG5ydW5tb2RlbCkNCg0KYGBgDQpJbiB0aGUgYWJvdmUgc3RlcCwgd2UgaGF2ZSBzdWJzZXQgb3VyIGRhdGEgaW50byAyIGNhdGVnb3J5IGJhc2VkIG9uICoqcnVuKiogdmFyaWFibGVzLCB3aGVyZSB2YWx1ZXMgYXJlICoqMSoqIGFuZCAqKi0xKiouDQpXZSBuZWVkIHRvIGZpbmQgdGhlIGZpdHRlZCBlcXVhdGlvbiBmb3IgKipZKiogdmFyaWFibGUgd2l0aCBib3RoIHRoZSAqKnJ1bioqIHZhbHVlcy4NCg0KRm9yIHRoYXQsIHdlIGNyZWF0ZWQgKipwcnVuKiogZGF0YSBmcmFtZSBmb3IgKipydW4gPSAxKiogYW5kICoqbnJ1bioqIGRhdGFmcmFtZSBmb3IgKipydW4gPSAtMSoqLg0KVGhlIGZpdHRlZCBxdWF0aW9uIGZvciAqKnBydW4qKiBpcyAqKlleID0gLTQuMDQgLTAuMDJYMSsgMC4xN1gyKyAwLjM1WDMrIDAuMTlYNCsgMC4yOVg1KiouICANCldlIGNhbiBhbHNvIHNlZSB0aGF0IHRoZSBQLXZhbHVlIGlzIHNtYWxsZXIgdGhlbiAwLjA1LCB0aGVyZWZvcmUgd2UgY2FuIHNheSB0aGF0IHRoZSBtb2RlbCBpcyBzaWduaWZpY2FudCBhbmQgd2UgY2FuIHJlamVjdCBIMC4gTXVsdGlwbGUgUiBzcXVhcmUgaXMgMC42MzggYW5kIEFkanVzdGVkIFItIHNxdWFyZSBpcyBvYnNlcnZlZCBhcyAwLjQzNy4NCg0KRm9yICpydW4gPSAtMSoqLCB3ZSBjcmVhdGVkIGEgbW9kZWwgYmFzZWQgb24gZGF0YXNldCAqKm5ydW4qKi4NClRoZSBmaXR0ZWQgZXF1YXRpb24gZm9yICoqbnJ1bioqIGlzICoqWV4gPSAtMTQ3LjA0IC0xLjc3WDEgKzE5LjUwWDIgKzEwLjQzWDMgKzAuMTdYNCArMy42MFg1KiouDQoNCiMgMS5jKSBVc2UgQWxsIFBvc3NpYmxlIFN1YnNldHMgcmVncmVzc2lvbiB0byBzZWxlY3QgdGhlIGJlc3QgbW9kZWwgYmFzZWQgb24gdGhlaXIgUjIgdmFsdWVzLg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmdzID0gRkFMU0V9DQpsaWJyYXJ5KGxlYXBzKQ0KcjwtbGVhcHM6OnJlZ3N1YnNldHMoeX52aXNjK3N1cmYrYmFzZStmaW5lcyt2b2lkcytydW4sIGRhdGE9YXNwaGFsdCkNCnN1bW1hcnkocikNCg0KcGFyKG1mcm93PWMoMSwxKSkNCnBsb3Qociwgc2NhbGU9ImFkanIyIikgDQpgYGAgDQpIZXJlLCB0byBjaGVjayBzZWxlY3QgdGhlIGJlc3QgcG9zc2libGUgcmVncmVzc2lvbiBtb2RlbCBiYXNlcyBvbiBSMiwgd2UgaGF2ZSB1c2VkICoqbGVhcHMqKiBmdW5jdGlvbnMuDQpUaHJvdWdoIHRoZSBhYm92ZSBncmFwaCwgd2UgY2FuIHNlZSB0aGF0IHRoZSBiZXN0IG1vZGVsIGJhc2VkIG9uIFIyIGFyZSAgKipzdXJmKiosICoqYmFzZSoqIGFuZCAqKnJ1bioqLiANCg0KIyAxLmMpIEFsbCB0aGUgZGlhZ25vc3RpYyB0ZXN0IHRvIGNoZWNrIHRoZSBhZGVxdWFjeSB2YWx1ZXMuDQpUbyBjaGVjayB0aGUgbW9kZWwgYWRlcXVhY3ksIHdlIGFyZSBldmFsdWF0aW5nIHRoZSBhc3N1bXB0aW9ucyBvZiB0aGUgbW9kZWwuDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZ3MgPSBGQUxTRX0NCg0KcGFyKG1mcm93ID0gYygyLDIpKQ0KcGxvdChhc3BoYWx0bW9kZWwpDQpgYGAgDQpJbiB0aGUgYWJvdmUgcGxvdCB3ZSBjYW4gc2VlIDQgRGlhZ25vc3RpYyBwbG90cyBrbm93biBhcyBSZXNpZHVhbHMgcGxvdCwgUVEgcGxvdHMsIFNjYWxlLWxvY2F0aW9uIHBsb3QgYW5kIGxldmVyYWdlIHBsb3RzLg0KDQpJbiB0aGUgMXN0IGdyYXBoIHdlIGNhbiBzZWUgdGhhdCBvbiBYIGF4aXMgaGFzIHByZWRpY3RlZCB2YWx1ZSBrbm93biBhcyBZXih5IGhhdCkgYW5kIG9uIHkgYXhpcyB0aGVyZSBhcmUgcmVzaWR1YWxzIGFuZCBlcnJvcnMuIEhlcmUgd2UgY2FuIHRoZSBsaW5lIGlzIG5vdCBmbGF0IGFuZCB0aGUgcG9pbnRzIGFyZSBsb29raW5nIGFzIGEgYnVuY2ggb2YgY2xvdWRzIHdoaWNoIG1lYW5zIHRoYXQgbGluZWFyaXR5IGFzc3VtcHRpb24gaXMgdmlvbGF0ZWQgaGVyZS4NCg0KSW4gdGhlIG5leHQgR3JhcGggKFFRIHBsb3QpLCBoZXJlIHkgYXhpcyBpcyBvcmRlcmVkLCBvYnNlcnZlZCBhbmQgU3RhbmRhcmRpemVkIHJlc2lkdWFscyBhbmQgb24gWCBheGlzIGl0IGhhcyBvcmRlcmVkIHRoZW9yZXRpY2FsIHJlc2lkdWFscy4gSW4gdGhlIGdyYXBoIHdlIGNhbiBzZWUgdGhhdCByZXNpZHVhbHMgYXJlIHRydWx5IG5vcm1hbGx5IGRpc3RyaWJ1dGVkIGFzIGluIHRoZSBiZWdpbm5pbmcgc29tZSB3ZXJlIGZhbGxpbmcgb3V0IG9mIGxpbmUgYnV0IGFmdGVyIHRoYXQgYWxsIHRoZSBwb2ludHMgYXJlIGZhbGxpbmcgb24gYSByb3VnaGx5IHN0cmFpZ2h0IGxpbmUuIA0KDQpUaGUgbmV4dCB0d28gc2hvd3MgdGhhdCB0aGUgcmVncmVzc2lvbiBpcyBub24tbGluZWFyLCBub24tY29uc3RhbnQgdmFyaWFuY2UuDQoNClRvIHRlc3QgZnVydGhlciwgaWYgYW55IGFzc3VtcHRpb25zIGFyZSB2aW9sYXRlZCBvciBub3QuIFdlIHdpbGwgcGVyZm9ybSBzb21lIHRlc3RzLg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmdzID0gRkFMU0V9DQpkdXJiaW5XYXRzb25UZXN0KGFzcGhhbHRtb2RlbCkNCmBgYA0KSDA6IEVycm9ycyBhcmUgdW5jb3JyZWxhdGVkDQpIMTogRXJyb3JzIGFyZSBjb3JyZWxhdGVkIA0KDQpGcm9tIHRoZSBEdXJiaW4gV2FzdG9uIHRlc3QsIHdlIGZvdW5kIG91dCB0aGF0IHAgdmFsdWUgaXMgMC45ODQuIFRoaXMgaW5kaWN0ZXMgbmVnYXRpdmUvIE5vIGF1dG9jb3JyZWxhdGlvbiBpbiB0aGUgbW9kZWwuIFAgdmFsdWUgaXMgZ3JhdGVyIHRoZW4gMC4wNS4gDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZ3MgPSBGQUxTRX0NCnNoYXBpcm8udGVzdChhc3BoYWx0bW9kZWwkcmVzaWR1YWxzKQ0KYGBgDQpIMDogRXJyb3JzIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZCANCkgxOiBFcnJvcnMgYXJlIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZCANCg0KRnJvbSB0aGUgU2hhcGlyby13aWxrIG5vcm1hbGl0eSB0ZXN0LCBhZnRlciBvYnNlcnZpbmcgdGhlIFAgdmFsdWUgb2YgMC4wMTUuIFdlIGNhbiBzYXkgdGhhdCB0aGUgbm9ybWFsaXR5IGlzIHZpb2xhdGVkIGhlcmUgYXMgcCB2YWxlIGlzIGdyZWF0ZXIgdGhlbiAwLjA1Lg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmdzID0gRkFMU0V9DQpuY3ZUZXN0KGFzcGhhbHRtb2RlbCkNCg0KYGBgDQpIMDogRXJyb3JzIGhhdmUgYSBjb25zdGFudCB2YXJpYW5jZSANCkgxOiBFcnJvcnMgaGF2ZSBhIG5vbi1jb25zdGFudCB2YXJpYW5jZQ0KDQpIZXJlLCB3ZSBjYW4gc2VlIHRoYXQgcCB2YWx1ZSBpcyBsZXNzIHRoZW4gMC4wNS4gdGhlcmVmb3JlLCB3ZSBjYW4gc2F5IHRoYXQgdGhlIGNvbnN0YW50IHZhcmlhbmNlIGFzc3VtcHRpb25zIGlzIHZpb2xhdGVkIGhlcmUuDQogIA0KIyAyLiAoRGF0YTogImJ5c3Npbm9zaXMiKQ0KVGhlIGRhdGEgd2VyZSBjb2xsZWN0ZWQgZnJvbSBhIGdyb3VwIG9mIHdvcmtlcnMgaW4gdGhlIGNvdHRvbiBpbmR1c3RyeSB0byBhc3Nlc3MgdGhlIHByZXZhbGVuY2Ugb2YgdGhlIGx1bmcgZGlzZWFzZSBieXNzaW5vc2lzIGFtb25nIHRoZXNlIHdvcmtlcnMuIFRoaXMgZGlzZWFzZSBpcyBjYXVzZWQgYnkgbG9uZyB0ZXJtIGV4cG9zdXJlIHRvIHBhcnRpY2xlcyBvZiBjb3R0b24sIGhlbXAsIGZsYXggYW5kIGp1dGUgd29ya2luZyBpbiB0aGlzIHR5cGUgb2YgZW52aXJvbm1lbnQuIEl0IGNhbiByZXN1bHQgaW4gYXN0aG1hLWxpa2Ugc3ltcHRvbSB3aGljaCBjYW4gbGVhZCB0byBkZWF0aCBhbW9uZyBzdWZmZXJlcnMuIFRoZSByZXNwb25zZSB2YXJpYWJsZSB5IGlzIGJpbmFyeSBhbmQgcmVmZXIgdG8gbnVtYmVyIG9mIHdvcmtlcnMgc3VmZmVyaW5nIChyZXNwb25zZSA9IHllcykgYW5kIG5vdCBzdWZmZXJpbmcgKHJlc3BvbnNlID0gbm8pIGFuZCB0aGUgcHJlZGljdG9ycyBhcmU6DQoNCnhsPWR1c3RpbmVzcyBvZiB0aGUgd29ya3BsYWNlICgxID0gaGlnaCwgMiA9IG1lZGl1bSwgMyA9IGxvdykNCngyPXJhY2UgKCAxID0gRXVyb3BlYW4sIDIgPSBvdGhlcikNCngzPXNleCAoIDEgPSBtYWxlLCAyID0gZmVtYWxlKQ0KeDQ9c21va2luZyBoaXN0b3J5ICgxID0gc21va2VyLCAyID0gbm9uc21va2VyKQ0KeDU9bGVuZ3RoIG9mIGVtcGxveW1lbnQgaW4gdGhlIGNvdHRvbiBpbmR1c3RyeQ0KKDEgPSBsZXNzIHRoYW4gMTAgeWVhcnMsIDIgPSBiZXR3ZWVuIDEwIGFuZCAyMCB5ZWFycywzID0gbW9yZSB0aGFuIDIwIHllYXJzKQ0KDQpOb3RpY2UgdGhhdCBhbGwgZml2ZSBwcmVkaWN0b3JzIGFyZSBxdWFsaXRhdGl2ZSB2YXJpYWJsZXMgYW5kIHRoZSByZXNwb25zZXMgYXJlIGVudGVyZWQgaW4gdGhlIGV2ZW50L3RyaWFsIGZvcm1hdC4NCg0KKGEpIEZpdCBhIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwgdG8gdGhlIGRhdGEgc2V0IGFuZCBkaXNjdXNzIHdoaWNoIG9mIHRoZSBwcmVkaWN0b3JzIGhhdmUgYSBzaWduaWZpY2FudCBlZmZlY3Qgb24gdGhlIHByZXNlbmNlIG9mIGJ5c3Npbm9zaXMuDQooYikgRGlzY3VzcyB0aGUgYWRlcXVhY3kgb2YgdGhlIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwuDQooYykgKE5lZWRzIHRvIGJlIGRvbmUgbWFudWFsbHkgb3IgYnkgaGFuZCkgRnJvbSB0aGUgZmluYWwgbW9kZWwgeW91IGhhdmUgc2VsZWN0ZWQgaW4gcGFydCAoYSksIGRldGVybWluZSB0aGUgcHJvYmFiaWxpdHkgdGhhdCBhIHBlcnNvbiB3aWxsIHN1ZmZlciBmcm9tIGJ5c3Npbm9zaXMgaWYgZ2l2ZW46DQppLiB4bCA9IDIsIHgyID0gMiwgeDMgPSAxLCB4NCA9IDIsIHg1ID0gMywNCmlpLiB4bCA9IDEsIHgyID0gMiwgeDMgPSAyLCB4NCA9IDEsIHg1ID0gMyANCmlpaS4geGwgPSAyLCB4MiA9IDEsIHgzID0gMSwgeDQgPSAyLCB4NSA9IDIsIA0KIGl2LiB4bCA9IDMsIHgyID0gMSwgeDMgPSAyLCB4NCA9IDIsIHg1ID0gMS4NCg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmdzID0gRkFMU0V9DQojUTINCmJ5c3Npbm9zaXMgPC0gcmVhZC5jc3YoImJ5c3Npbm9zaXMuY3N2IikNCmJ5c3Npbm9zaXMNCmBgYA0KSGVyZSwgd2UgaW1wb3J0ZWQgdGhlICoqYnlzc2lub3NpcyoqIGRhdGFzZXQgdGhhdCB3aWxsIGJlIHVzZWQgaW4gb3VyIFEyLg0KDQojIChhKSBGaXQgYSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsIHRvIHRoZSBkYXRhIHNldCBhbmQgZGlzY3VzcyB3aGljaCBvZiB0aGUgcHJlZGljdG9ycyBoYXZlIGEgc2lnbmlmaWNhbnQgZWZmZWN0IG9uIHRoZSBwcmVzZW5jZSBvZiBieXNzaW5vc2lzLg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmdzID0gRkFMU0V9DQojMi5hKQ0KZ2xtbW9kZWwgPC0gZ2xtKGNiaW5kKEJ5c1llcyxCeXNObyl+RHVzdCtSYWNlK1NleCtTbW9rZStFbXBsb3ksDQogICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5PWJpbm9taWFsLGJ5c3Npbm9zaXMpDQpzdW1tYXJ5LmdsbShnbG1tb2RlbCkNCmBgYA0KSGVyZSwgd2UgaGF2ZSB1c2VkICoqZ2xtKiogZnVuY3Rpb24gdG8gZml0IGEgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCBhbmQgKipjYmluZCoqIGZ1bmN0aW9uIHRvIGJpbmQgdGhlIGNvbHVtbnMgb2YgKipZKiogdmFyaWFibGUsICoqRmFtaWx5ID0gYmlub21pYWwqKiBpcyB1c2VkLg0KSW4gdGhlIGFib3ZlICoqZ2xtKiogZnVuY3Rpb24sIHdlIGNhbiBzZWUgdGhhdCBwcmVkaWN0b3JzICoqUmFjZSoqLCAqKlNtb2tlKiogYW5kICoqRW1wbG95KiogaGFzIHNpZ25pZmljYW50IGltcGFjdCBvbiB0aGUgcHJlc2VuY2Ugb2YgQnlzc2lub3NpcyBhcyB0aGVpciAqKlAtdmFsdWUqKiBpcyBzbWFsbGVyIHRoZW4gMC4wNS4gUmVzdCBwcmVkaWN0b3JzIGhhcyBpbnNpZ25pZmFjbnQgaW1wYXQgYXMgdGhleSBoYXZlIGhpZ2hlciAqKlAtdmFsdWUqKiB0aGVuIDAuMDUNCg0KIyAyLmIpIERpc2N1c3MgdGhlIGFkZXF1YWN5IG9mIHRoZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsLg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmdzID0gRkFMU0V9DQpwY2hpc3EoNjkuNTA5LCA1OSwgbG93ZXIudGFpbCA9IEZBTFNFKQ0KYGBgDQpUbyBjaGVjayB0aGUgYWRlcXVhY3kgb2YgdGhlIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwsIHdlIGhhdmUgdXNlZCAqKnBjaGlzcSoqIGZ1bmN0aW9uIGJ5IHVzaW5nIHRoZSAqKnJlc2lkdWFsIGRldmlhbmNlKiogYW5kIGl0J3MgKipEZWdyZWUgb2YgZnJlZWRvbSouDQoNCkgwOiB0aGUgbW9kZWwgZml0cyB0aGUgZGF0YSB3ZWxsDQp2cy4gDQpIMTogdGhlIG1vZGVsIGRvZXMgbm90IGZpdCB0aGUgZGF0YSB3ZWxsDQpUaGUgY2hpLXNxdWFyZSB0ZXN0IHN0YXRpc3RpYyBvZiA2OS41MDkgd2l0aCA1OSBkZWdyZWUgb2YgZnJlZWRvbSBnaXZlcyBhIHAtdmFsdWUgb2YgMC4xNjQ1LCBpbmRpY2F0aW5nIHRoYXQgdGhlIG51bGwgaHlwb3RoZXNpcyBpcyBwbGF1c2libGUsIGFuZCB3ZSBjYW4gY29uY2x1ZGUgdGhhdCBsb2dpc3RpYyBtb2RlbCBpcyAqKmFkZXF1YXRlLioqDQoNCiMgMi5jKSBkZXRlcm1pbmUgdGhlIHByb2JhYmlsaXR5IHRoYXQgYSBwZXJzb24gd2lsbCBzdWZmZXIgZnJvbSBieXNzaW5vc2lzIGlmIGdpdmVuOg0KIyMgaS4geGwgPSAyLCB4MiA9IDIsIHgzID0gMSwgeDQgPSAyLCB4NSA9IDMNCg0KYGBge3IsIGVjaG8gPSBUUlVFLCB3YXJuaW5ncyA9IEZBTFNFfQ0KMS8oMStleHAoKC0xLjM3KjIpKygwLjI0KjIpKygtMC4yNSoxKSsoLTAuNjIqMikrKDAuMzgqMykpKQ0KYGBgDQpUaGUgcHJvYmFiaWxpdHkgdGhhdCBhIHBlcnNvbiB3aWxsIHN1ZmZlciBmcm9tIGJ5c3Npbm9zaXMgaWYgeGwgPSAyLCB4MiA9IDIsIHgzID0gMSwgeDQgPSAyLCB4NSA9IDMNCmlzICoqMC45MzE1KioNCg0KIyMgaWkuIHhsID0gMSwgeDIgPSAyLCB4MyA9IDIsIHg0ID0gMSwgeDUgPSAzDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgd2FybmluZ3MgPSBGQUxTRX0NCjEvKDErZXhwKCgtMS4zNyoxKSsoMC4yNCoyKSsoLTAuMjUqMikrKC0wLjYyKjEpKygwLjM4KjMpKSkNCmBgYA0KVGhlIHByb2JhYmlsaXR5IHRoYXQgYSBwZXJzb24gd2lsbCBzdWZmZXIgZnJvbSBieXNzaW5vc2lzIGlmICB4bCA9IDEsIHgyID0gMiwgeDMgPSAyLCB4NCA9IDEsIA0KeDUgPSAzIGlzICoqMC43MDQ3KioNCg0KIyMgaWlpLiB4bCA9IDIsIHgyID0gMSwgeDMgPSAxLCB4NCA9IDIsIHg1ID0gMg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmdzID0gRkFMU0V9DQoxLygxK2V4cCgoLTEuMzcqMikrKDAuMjQqMSkrKC0wLjI1KjEpKygtMC42MioyKSsoMC4zOCoyKSkpDQpgYGANClRoZSBwcm9iYWJpbGl0eSB0aGF0IGEgcGVyc29uIHdpbGwgc3VmZmVyIGZyb20gYnlzc2lub3NpcyBpZiAgeGwgPSAyLCB4MiA9IDEsIHgzID0gMSwgeDQgPSAyLCANCng1ID0gMiBpcyAqKjAuOTYxOSoqDQoNCg0KIyMgaXYuIHhsID0gMywgeDIgPSAxLCB4MyA9IDIsIHg0ID0gMiwgeDUgPSAxLg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIHdhcm5pbmdzID0gRkFMU0V9DQoxLygxK2V4cCgoLTEuMzcqMykrKDAuMjQqMSkrKC0wLjI1KjIpKygtMC42MioyKSsoMC4zOCoxKSkpDQpgYGANCg0KVGhlIHByb2JhYmlsaXR5IHRoYXQgYSBwZXJzb24gd2lsbCBzdWZmZXIgZnJvbSBieXNzaW5vc2lzIGlmIHhsID0gMywgeDIgPSAxLCB4MyA9IDIsIHg0ID0gMiwgeDUgPSAxIGlzICoqMC45OTQ2Kio=