1.
1.1 Exploration and Logistic Regression
What proportion of people in this dataset voted in this election?
options(digits=6, scipen=12)
Gerber = read.csv("data/gerber.csv")
table(Gerber$voting)/nrow(Gerber)
0 1
0.6841 0.3159
1.2 Exploration and Logistic Regression
Which of the four “treatment groups” had the largest percentage of people who actually voted (voting = 1)?
tapply(Gerber$voting, Gerber$civicduty, mean)
0 1
0.316070 0.314538
tapply(Gerber$voting, Gerber$hawthorne, mean)
0 1
0.315091 0.322375
tapply(Gerber$voting, Gerber$self, mean)
0 1
0.312245 0.345151
tapply(Gerber$voting, Gerber$neighbors, mean)
0 1
0.308151 0.377948
1.3 Exploration and Logistic Regression
Build a logistic regression model for voting using the four treatment group variables as the independent variables (civicduty, hawthorne, self, and neighbors). Use all the data to build the model (DO NOT split the data into a training set and testing set). Which of the following coefficients are significant in the logistic regression model? Select all that apply.
model = glm(voting ~ civicduty+hawthorne+self+ neighbors,Gerber,family="binomial")
summary(model)
Call:
glm(formula = voting ~ civicduty + hawthorne + self + neighbors,
family = "binomial", data = Gerber)
Deviance Residuals:
Min 1Q Median 3Q Max
-0.974 -0.869 -0.839 1.459 1.559
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.86336 0.00501 -172.46 < 2e-16 ***
civicduty 0.08437 0.01210 6.97 0.0000000000031 ***
hawthorne 0.12048 0.01204 10.01 < 2e-16 ***
self 0.22294 0.01187 18.79 < 2e-16 ***
neighbors 0.36509 0.01168 31.26 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 429238 on 344083 degrees of freedom
Residual deviance: 428090 on 344079 degrees of freedom
AIC: 428100
Number of Fisher Scoring iterations: 4
- Civic Duty
- Hawthorne Effect
- Self
- Neighbors
1.4 Exploration and Logistic Regression
Using a threshold of 0.3, what is the accuracy of the logistic regression model? (When making predictions, you don’t need to use the newdata argument since we didn’t split our data.)
model = glm(voting ~ civicduty+hawthorne+self+ neighbors,Gerber,family="binomial")
Pred = predict(model,type="response")
table(Gerber$voting,Pred>0.3)
FALSE TRUE
0 134513 100875
1 56730 51966
(134513+51966)/nrow(Gerber)
[1] 0.541958
1.5 Exploration and Logistic Regression
Using a threshold of 0.5, what is the accuracy of the logistic regression model?
table(Gerber$voting,Pred>0.5)
FALSE
0 235388
1 108696
235388/nrow(Gerber)
[1] 0.6841
1.6 Exploration and Logistic Regression
Compare your previous two answers to the percentage of people who did not vote (the baseline accuracy) and compute the AUC of the model. What is happening here?
table(Gerber$voting)
0 1
235388 108696
235388/nrow(Gerber)
[1] 0.6841
library(ROCR)
package 愼㸱愼㸵ROCR愼㸱愼㸶 was built under R version 3.4.4Loading required package: gplots
package 愼㸱愼㸵gplots愼㸱愼㸶 was built under R version 3.4.4
Attaching package: 愼㸱愼㸵gplots愼㸱愼㸶
The following object is masked from 愼㸱愼㸵package:stats愼㸱愼㸶:
lowess
ROCRpredTest = prediction(Pred,Gerber$voting)
auc = as.numeric(performance(ROCRpredTest, "auc")@y.values)
auc
[1] 0.530846
- Even though all of the variables are significant, this is a weak predictive model.
2
2.1 Trees
Leave all the parameters at their default values. You can use the following command in R to build the tree.Plot the tree. What happens, and if relevant, why?
library(rpart)
package 愼㸱愼㸵rpart愼㸱愼㸶 was built under R version 3.4.4
CARTmodel = rpart(voting ~ civicduty + hawthorne + self + neighbors, data=Gerber)
library(rpart.plot)
package 愼㸱愼㸵rpart.plot愼㸱愼㸶 was built under R version 3.4.4
prp(CARTmodel)

- No variables are used (the tree is only a root node) - none of the variables make a big enough effect to be split on.
2.2 Trees
….to force the complete tree to be built. Then plot the tree. What do you observe about the order of the splits?
CARTmodel2 = rpart(voting ~ civicduty + hawthorne + self + neighbors, data=Gerber, cp=0.0)
prp(CARTmodel2)

- Neighbor is the first split, civic duty is the last.
2.3 Trees
Using only the CART tree plot, determine what fraction (a number between 0 and 1) of “Civic Duty” people voted:
2.4 Trees
Make a new tree that includes the “sex” variable, again with cp = 0.0. Notice that sex appears as a split that is of secondary importance to the treatment group.
In the control group, which gender is more likely to vote?
CARTmodel3 = rpart(voting ~ civicduty + hawthorne + self + neighbors + sex, data=Gerber, cp=0.0)
prp(CARTmodel3)

Control = subset(Gerber,control==1)
tapply(Control$voting,Control$sex,mean)
0 1
0.302795 0.290456
In the “Civic Duty” group, which gender is more likely to vote?
### 3
#### 3.1 - Interaction Terms
Let’s just focus on the “Control” treatment group. Create a regression tree using just the “control” variable, then create another tree with the “control” and “sex” variables, both with cp=0.0.
In the “control” only tree, what is the absolute value of the difference in the predicted probability of voting between being in the control group versus being in a different group? You can use the absolute value function to get answer, i.e. abs(Control Prediction - Non-Control Prediction). Add the argument “digits = 6” to the prp command to get a more accurate estimate.
Controlmodel = rpart(voting ~ control, data=Gerber, cp=0.0)
Controlmodel2 = rpart(voting ~ control+sex, data=Gerber, cp=0.0)
prp(Controlmodel,digits = 6)

abs(0.34-0.296638)
[1] 0.043362
3.2 - Interaction Terms
Now, using the second tree (with control and sex), determine who is affected more by NOT being in the control group (being in any of the four treatment groups):
prp(Controlmodel2,digits = 6)

- They are affected about the same (change in probability within 0.001 of each other).
3.3 - Interaction Terms
Going back to logistic regression now, create a model using “sex” and “control”. Interpret the coefficient for “sex”:
LogModelSex = glm(voting ~ control+sex, data=Gerber,family = "binomial")
- Coefficient is negative, reflecting that women are less likely to vote
3.4 - Interaction Terms
We can quantify this precisely. Create the following dataframe (this contains all of the possible values of sex and control), and evaluate your logistic regression using the predict function (where “LogModelSex” is the name of your logistic regression model that uses both control and sex):
Possibilities = data.frame(sex=c(0,0,1,1),control=c(0,1,0,1))
predict(LogModelSex, newdata=Possibilities, type="response")
1 2 3 4
0.346256 0.302446 0.333738 0.290806
#( (Man, Not Control), (Man, Control), (Woman, Not Control), (Woman, Control) )
abs(0.290456-0.290806 )
[1] 0.00035
3.5 - Interaction Terms
So the difference is not too big for this dataset, but it is there. We’re going to add a new term to our logistic regression now, that is the combination of the “sex” and “control” variables - so if this new variable is 1, that means the person is a woman AND in the control group. We can do that with the following command
How do you interpret the coefficient for the new variable in isolation? That is, how does it relate to the dependent variable?
LogModel2 = glm(voting ~ sex + control + sex:control, data=Gerber, family="binomial")
- If a person is a woman and in the control group, the chance that she voted goes down.
3.6 - Interaction Terms
Now what is the difference between the logistic regression model and the CART model for the (Woman, Control) case? Again, give your answer with five numbers after the decimal point.
predict(LogModel2, newdata=Possibilities, type="response")
1 2 3 4
0.345818 0.302795 0.334176 0.290456
abs(0.290456-0.290456)
[1] 0
3.7 - Interaction Terms
This example has shown that trees can capture nonlinear relationships that logistic regression can not, but that we can get around this sometimes by using variables that are the combination of two variables. Should we always include all possible interaction terms of the independent variables when building a logistic regression model?
LS0tDQp0aXRsZTogIkFTNC0xIFVuZGVyc3RhbmRpbmcgV2h5IFBlb3BsZSBWb3RlIg0KYXV0aG9yOiAiR3JvdXA0Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KDQojIyMgMS4gDQoNCiMjIyMgMS4xIEV4cGxvcmF0aW9uIGFuZCBMb2dpc3RpYyBSZWdyZXNzaW9uDQoNCldoYXQgcHJvcG9ydGlvbiBvZiBwZW9wbGUgaW4gdGhpcyBkYXRhc2V0IHZvdGVkIGluIHRoaXMgZWxlY3Rpb24/DQpgYGB7cn0NCm9wdGlvbnMoZGlnaXRzPTYsIHNjaXBlbj0xMikNCkdlcmJlciA9IHJlYWQuY3N2KCJkYXRhL2dlcmJlci5jc3YiKQ0KdGFibGUoR2VyYmVyJHZvdGluZykvbnJvdyhHZXJiZXIpDQoNCmBgYA0KDQojIyMjIDEuMiBFeHBsb3JhdGlvbiBhbmQgTG9naXN0aWMgUmVncmVzc2lvbg0KDQpXaGljaCBvZiB0aGUgZm91ciAidHJlYXRtZW50IGdyb3VwcyIgaGFkIHRoZSBsYXJnZXN0IHBlcmNlbnRhZ2Ugb2YgcGVvcGxlIHdobyBhY3R1YWxseSB2b3RlZCAodm90aW5nID0gMSk/DQpgYGB7cn0NCnRhcHBseShHZXJiZXIkdm90aW5nLCBHZXJiZXIkY2l2aWNkdXR5LCBtZWFuKQ0KdGFwcGx5KEdlcmJlciR2b3RpbmcsIEdlcmJlciRoYXd0aG9ybmUsIG1lYW4pDQp0YXBwbHkoR2VyYmVyJHZvdGluZywgR2VyYmVyJHNlbGYsIG1lYW4pDQp0YXBwbHkoR2VyYmVyJHZvdGluZywgR2VyYmVyJG5laWdoYm9ycywgbWVhbikNCg0KYGBgDQogKyBOZWlnaGJvcnMNCg0KIyMjIyAxLjMgRXhwbG9yYXRpb24gYW5kIExvZ2lzdGljIFJlZ3Jlc3Npb24NCg0KQnVpbGQgYSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsIGZvciB2b3RpbmcgdXNpbmcgdGhlIGZvdXIgdHJlYXRtZW50IGdyb3VwIHZhcmlhYmxlcyBhcyB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzIChjaXZpY2R1dHksIGhhd3Rob3JuZSwgc2VsZiwgYW5kIG5laWdoYm9ycykuIFVzZSBhbGwgdGhlIGRhdGEgdG8gYnVpbGQgdGhlIG1vZGVsIChETyBOT1Qgc3BsaXQgdGhlIGRhdGEgaW50byBhIHRyYWluaW5nIHNldCBhbmQgdGVzdGluZyBzZXQpLiBXaGljaCBvZiB0aGUgZm9sbG93aW5nIGNvZWZmaWNpZW50cyBhcmUgc2lnbmlmaWNhbnQgaW4gdGhlIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWw/IFNlbGVjdCBhbGwgdGhhdCBhcHBseS4NCmBgYHtyfQ0KbW9kZWwgPSBnbG0odm90aW5nIH4gY2l2aWNkdXR5K2hhd3Rob3JuZStzZWxmKyBuZWlnaGJvcnMsR2VyYmVyLGZhbWlseT0iYmlub21pYWwiKQ0Kc3VtbWFyeShtb2RlbCkNCg0KYGBgDQogKyBDaXZpYyBEdXR5DQogKyBIYXd0aG9ybmUgRWZmZWN0DQogKyBTZWxmDQogKyBOZWlnaGJvcnMNCg0KIyMjIyAxLjQgRXhwbG9yYXRpb24gYW5kIExvZ2lzdGljIFJlZ3Jlc3Npb24NCg0KVXNpbmcgYSB0aHJlc2hvbGQgb2YgMC4zLCB3aGF0IGlzIHRoZSBhY2N1cmFjeSBvZiB0aGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbD8gKFdoZW4gbWFraW5nIHByZWRpY3Rpb25zLCB5b3UgZG9uJ3QgbmVlZCB0byB1c2UgdGhlIG5ld2RhdGEgYXJndW1lbnQgc2luY2Ugd2UgZGlkbid0IHNwbGl0IG91ciBkYXRhLikNCmBgYHtyfQ0KbW9kZWwgPSBnbG0odm90aW5nIH4gY2l2aWNkdXR5K2hhd3Rob3JuZStzZWxmKyBuZWlnaGJvcnMsR2VyYmVyLGZhbWlseT0iYmlub21pYWwiKQ0KUHJlZCA9IHByZWRpY3QobW9kZWwsdHlwZT0icmVzcG9uc2UiKQ0KdGFibGUoR2VyYmVyJHZvdGluZyxQcmVkPjAuMykNCigxMzQ1MTMrNTE5NjYpL25yb3coR2VyYmVyKQ0KYGBgDQojIyMjIDEuNSBFeHBsb3JhdGlvbiBhbmQgTG9naXN0aWMgUmVncmVzc2lvbg0KDQpVc2luZyBhIHRocmVzaG9sZCBvZiAwLjUsIHdoYXQgaXMgdGhlIGFjY3VyYWN5IG9mIHRoZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsPw0KDQpgYGB7cn0NCnRhYmxlKEdlcmJlciR2b3RpbmcsUHJlZD4wLjUpDQoyMzUzODgvbnJvdyhHZXJiZXIpDQpgYGANCg0KIyMjIyAxLjYgRXhwbG9yYXRpb24gYW5kIExvZ2lzdGljIFJlZ3Jlc3Npb24NCg0KQ29tcGFyZSB5b3VyIHByZXZpb3VzIHR3byBhbnN3ZXJzIHRvIHRoZSBwZXJjZW50YWdlIG9mIHBlb3BsZSB3aG8gZGlkIG5vdCB2b3RlICh0aGUgYmFzZWxpbmUgYWNjdXJhY3kpIGFuZCBjb21wdXRlIHRoZSBBVUMgb2YgdGhlIG1vZGVsLiBXaGF0IGlzIGhhcHBlbmluZyBoZXJlPw0KYGBge3J9DQp0YWJsZShHZXJiZXIkdm90aW5nKQ0KMjM1Mzg4L25yb3coR2VyYmVyKQ0KbGlicmFyeShST0NSKQ0KUk9DUnByZWRUZXN0ID0gcHJlZGljdGlvbihQcmVkLEdlcmJlciR2b3RpbmcpDQphdWMgPSBhcy5udW1lcmljKHBlcmZvcm1hbmNlKFJPQ1JwcmVkVGVzdCwgImF1YyIpQHkudmFsdWVzKQ0KYXVjDQoNCmBgYA0KICsgRXZlbiB0aG91Z2ggYWxsIG9mIHRoZSB2YXJpYWJsZXMgYXJlIHNpZ25pZmljYW50LCB0aGlzIGlzIGEgd2VhayBwcmVkaWN0aXZlIG1vZGVsLiANCiANCiMjIyAyDQoNCiMjIyMgMi4xIFRyZWVzDQoNCkxlYXZlIGFsbCB0aGUgcGFyYW1ldGVycyBhdCB0aGVpciBkZWZhdWx0IHZhbHVlcy4gWW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBjb21tYW5kIGluIFIgdG8gYnVpbGQgdGhlIHRyZWUuUGxvdCB0aGUgdHJlZS4gV2hhdCBoYXBwZW5zLCBhbmQgaWYgcmVsZXZhbnQsIHdoeT8NCmBgYHtyfQ0KbGlicmFyeShycGFydCkNCkNBUlRtb2RlbCA9IHJwYXJ0KHZvdGluZyB+IGNpdmljZHV0eSArIGhhd3Rob3JuZSArIHNlbGYgKyBuZWlnaGJvcnMsIGRhdGE9R2VyYmVyKQ0KbGlicmFyeShycGFydC5wbG90KQ0KcHJwKENBUlRtb2RlbCkNCg0KYGBgDQogKyBObyB2YXJpYWJsZXMgYXJlIHVzZWQgKHRoZSB0cmVlIGlzIG9ubHkgYSByb290IG5vZGUpIC0gbm9uZSBvZiB0aGUgdmFyaWFibGVzIG1ha2UgYSBiaWcgZW5vdWdoIGVmZmVjdCB0byBiZSBzcGxpdCBvbi4NCiANCiMjIyMgMi4yIFRyZWVzDQoNCi4uLi50byBmb3JjZSB0aGUgY29tcGxldGUgdHJlZSB0byBiZSBidWlsdC4gVGhlbiBwbG90IHRoZSB0cmVlLiBXaGF0IGRvIHlvdSBvYnNlcnZlIGFib3V0IHRoZSBvcmRlciBvZiB0aGUgc3BsaXRzPw0KDQpgYGB7cn0NCkNBUlRtb2RlbDIgPSBycGFydCh2b3RpbmcgfiBjaXZpY2R1dHkgKyBoYXd0aG9ybmUgKyBzZWxmICsgbmVpZ2hib3JzLCBkYXRhPUdlcmJlciwgY3A9MC4wKQ0KcHJwKENBUlRtb2RlbDIpDQoNCmBgYA0KICsgTmVpZ2hib3IgaXMgdGhlIGZpcnN0IHNwbGl0LCBjaXZpYyBkdXR5IGlzIHRoZSBsYXN0Lg0KIA0KIyMjIyAyLjMgVHJlZXMNCg0KVXNpbmcgb25seSB0aGUgQ0FSVCB0cmVlIHBsb3QsIGRldGVybWluZSB3aGF0IGZyYWN0aW9uIChhIG51bWJlciBiZXR3ZWVuIDAgYW5kIDEpIG9mICJDaXZpYyBEdXR5IiBwZW9wbGUgdm90ZWQ6DQoNCisgMC4zMQ0KDQojIyMjIDIuNCBUcmVlcw0KIA0KTWFrZSBhIG5ldyB0cmVlIHRoYXQgaW5jbHVkZXMgdGhlICJzZXgiIHZhcmlhYmxlLCBhZ2FpbiB3aXRoIGNwID0gMC4wLiBOb3RpY2UgdGhhdCBzZXggYXBwZWFycyBhcyBhIHNwbGl0IHRoYXQgaXMgb2Ygc2Vjb25kYXJ5IGltcG9ydGFuY2UgdG8gdGhlIHRyZWF0bWVudCBncm91cC4NCg0KSW4gdGhlIGNvbnRyb2wgZ3JvdXAsIHdoaWNoIGdlbmRlciBpcyBtb3JlIGxpa2VseSB0byB2b3RlPw0KDQpgYGB7cn0NCkNBUlRtb2RlbDMgPSBycGFydCh2b3RpbmcgfiBjaXZpY2R1dHkgKyBoYXd0aG9ybmUgKyBzZWxmICsgbmVpZ2hib3JzICsgc2V4LCBkYXRhPUdlcmJlciwgY3A9MC4wKQ0KcHJwKENBUlRtb2RlbDMpDQpDb250cm9sID0gc3Vic2V0KEdlcmJlcixjb250cm9sPT0xKQ0KdGFwcGx5KENvbnRyb2wkdm90aW5nLENvbnRyb2wkc2V4LG1lYW4pDQpgYGANCiArIE1lbg0KIA0KSW4gdGhlICJDaXZpYyBEdXR5IiBncm91cCwgd2hpY2ggZ2VuZGVyIGlzIG1vcmUgbGlrZWx5IHRvIHZvdGU/DQoNCiArIE1lbg0KIA0KICMjIyAzDQogDQogIyMjIyAzLjEgLSBJbnRlcmFjdGlvbiBUZXJtcw0KDQpMZXQncyBqdXN0IGZvY3VzIG9uIHRoZSAiQ29udHJvbCIgdHJlYXRtZW50IGdyb3VwLiBDcmVhdGUgYSByZWdyZXNzaW9uIHRyZWUgdXNpbmcganVzdCB0aGUgImNvbnRyb2wiIHZhcmlhYmxlLCB0aGVuIGNyZWF0ZSBhbm90aGVyIHRyZWUgd2l0aCB0aGUgImNvbnRyb2wiIGFuZCAic2V4IiB2YXJpYWJsZXMsIGJvdGggd2l0aCBjcD0wLjAuDQoNCkluIHRoZSAiY29udHJvbCIgb25seSB0cmVlLCB3aGF0IGlzIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGUgZGlmZmVyZW5jZSBpbiB0aGUgcHJlZGljdGVkIHByb2JhYmlsaXR5IG9mIHZvdGluZyBiZXR3ZWVuIGJlaW5nIGluIHRoZSBjb250cm9sIGdyb3VwIHZlcnN1cyBiZWluZyBpbiBhIGRpZmZlcmVudCBncm91cD8gWW91IGNhbiB1c2UgdGhlIGFic29sdXRlIHZhbHVlIGZ1bmN0aW9uIHRvIGdldCBhbnN3ZXIsIGkuZS4gYWJzKENvbnRyb2wgUHJlZGljdGlvbiAtIE5vbi1Db250cm9sIFByZWRpY3Rpb24pLiBBZGQgdGhlIGFyZ3VtZW50ICJkaWdpdHMgPSA2IiB0byB0aGUgcHJwIGNvbW1hbmQgdG8gZ2V0IGEgbW9yZSBhY2N1cmF0ZSBlc3RpbWF0ZS4NCg0KYGBge3J9DQpDb250cm9sbW9kZWwgPSBycGFydCh2b3RpbmcgfiBjb250cm9sLCBkYXRhPUdlcmJlciwgY3A9MC4wKQ0KQ29udHJvbG1vZGVsMiA9IHJwYXJ0KHZvdGluZyB+IGNvbnRyb2wrc2V4LCBkYXRhPUdlcmJlciwgY3A9MC4wKQ0KcHJwKENvbnRyb2xtb2RlbCxkaWdpdHMgPSA2KQ0KYWJzKDAuMzQtMC4yOTY2MzgpDQpgYGANCg0KIyMjIyAzLjIgLSBJbnRlcmFjdGlvbiBUZXJtcw0KDQpOb3csIHVzaW5nIHRoZSBzZWNvbmQgdHJlZSAod2l0aCBjb250cm9sIGFuZCBzZXgpLCBkZXRlcm1pbmUgd2hvIGlzIGFmZmVjdGVkIG1vcmUgYnkgTk9UIGJlaW5nIGluIHRoZSBjb250cm9sIGdyb3VwIChiZWluZyBpbiBhbnkgb2YgdGhlIGZvdXIgdHJlYXRtZW50IGdyb3Vwcyk6DQoNCmBgYHtyfQ0KcHJwKENvbnRyb2xtb2RlbDIsZGlnaXRzID0gNikNCg0KYGBgDQogKyBUaGV5IGFyZSBhZmZlY3RlZCBhYm91dCB0aGUgc2FtZSAoY2hhbmdlIGluIHByb2JhYmlsaXR5IHdpdGhpbiAwLjAwMSBvZiBlYWNoIG90aGVyKS4gDQoNCiMjIyMgMy4zIC0gSW50ZXJhY3Rpb24gVGVybXMNCg0KR29pbmcgYmFjayB0byBsb2dpc3RpYyByZWdyZXNzaW9uIG5vdywgY3JlYXRlIGEgbW9kZWwgdXNpbmcgInNleCIgYW5kICJjb250cm9sIi4gSW50ZXJwcmV0IHRoZSBjb2VmZmljaWVudCBmb3IgInNleCI6DQpgYGB7cn0NCkxvZ01vZGVsU2V4ID0gZ2xtKHZvdGluZyB+IGNvbnRyb2wrc2V4LCBkYXRhPUdlcmJlcixmYW1pbHkgPSAiYmlub21pYWwiKQ0KDQpgYGANCiArIENvZWZmaWNpZW50IGlzIG5lZ2F0aXZlLCByZWZsZWN0aW5nIHRoYXQgd29tZW4gYXJlIGxlc3MgbGlrZWx5IHRvIHZvdGUNCiANCiMjIyMgMy40IC0gSW50ZXJhY3Rpb24gVGVybXMNCg0KV2UgY2FuIHF1YW50aWZ5IHRoaXMgcHJlY2lzZWx5LiBDcmVhdGUgdGhlIGZvbGxvd2luZyBkYXRhZnJhbWUgKHRoaXMgY29udGFpbnMgYWxsIG9mIHRoZSBwb3NzaWJsZSB2YWx1ZXMgb2Ygc2V4IGFuZCBjb250cm9sKSwgYW5kIGV2YWx1YXRlIHlvdXIgbG9naXN0aWMgcmVncmVzc2lvbiB1c2luZyB0aGUgcHJlZGljdCBmdW5jdGlvbiAod2hlcmUgIkxvZ01vZGVsU2V4IiBpcyB0aGUgbmFtZSBvZiB5b3VyIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwgdGhhdCB1c2VzIGJvdGggY29udHJvbCBhbmQgc2V4KToNCg0KYGBge3J9DQpQb3NzaWJpbGl0aWVzID0gZGF0YS5mcmFtZShzZXg9YygwLDAsMSwxKSxjb250cm9sPWMoMCwxLDAsMSkpDQpwcmVkaWN0KExvZ01vZGVsU2V4LCBuZXdkYXRhPVBvc3NpYmlsaXRpZXMsIHR5cGU9InJlc3BvbnNlIikNCiMoIChNYW4sIE5vdCBDb250cm9sKSwgKE1hbiwgQ29udHJvbCksIChXb21hbiwgTm90IENvbnRyb2wpLCAoV29tYW4sIENvbnRyb2wpICkNCmFicygwLjI5MDQ1Ni0wLjI5MDgwNiApDQoNCmBgYA0KDQojIyMjIDMuNSAtIEludGVyYWN0aW9uIFRlcm1zDQoNClNvIHRoZSBkaWZmZXJlbmNlIGlzIG5vdCB0b28gYmlnIGZvciB0aGlzIGRhdGFzZXQsIGJ1dCBpdCBpcyB0aGVyZS4gV2UncmUgZ29pbmcgdG8gYWRkIGEgbmV3IHRlcm0gdG8gb3VyIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbm93LCB0aGF0IGlzIHRoZSBjb21iaW5hdGlvbiBvZiB0aGUgInNleCIgYW5kICJjb250cm9sIiB2YXJpYWJsZXMgLSBzbyBpZiB0aGlzIG5ldyB2YXJpYWJsZSBpcyAxLCB0aGF0IG1lYW5zIHRoZSBwZXJzb24gaXMgYSB3b21hbiBBTkQgaW4gdGhlIGNvbnRyb2wgZ3JvdXAuIFdlIGNhbiBkbyB0aGF0IHdpdGggdGhlIGZvbGxvd2luZyBjb21tYW5kDQoNCkhvdyBkbyB5b3UgaW50ZXJwcmV0IHRoZSBjb2VmZmljaWVudCBmb3IgdGhlIG5ldyB2YXJpYWJsZSBpbiBpc29sYXRpb24/IFRoYXQgaXMsIGhvdyBkb2VzIGl0IHJlbGF0ZSB0byB0aGUgZGVwZW5kZW50IHZhcmlhYmxlPw0KYGBge3J9DQpMb2dNb2RlbDIgPSBnbG0odm90aW5nIH4gc2V4ICsgY29udHJvbCArIHNleDpjb250cm9sLCBkYXRhPUdlcmJlciwgZmFtaWx5PSJiaW5vbWlhbCIpDQpgYGANCiArIElmIGEgcGVyc29uIGlzIGEgd29tYW4gYW5kIGluIHRoZSBjb250cm9sIGdyb3VwLCB0aGUgY2hhbmNlIHRoYXQgc2hlIHZvdGVkIGdvZXMgZG93bi4NCiANCiMjIyMgMy42IC0gSW50ZXJhY3Rpb24gVGVybXMNCg0KTm93IHdoYXQgaXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCBhbmQgdGhlIENBUlQgbW9kZWwgZm9yIHRoZSAoV29tYW4sIENvbnRyb2wpIGNhc2U/IEFnYWluLCBnaXZlIHlvdXIgYW5zd2VyIHdpdGggZml2ZSBudW1iZXJzIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50Lg0KDQpgYGB7cn0NCnByZWRpY3QoTG9nTW9kZWwyLCBuZXdkYXRhPVBvc3NpYmlsaXRpZXMsIHR5cGU9InJlc3BvbnNlIikNCmFicygwLjI5MDQ1Ni0wLjI5MDQ1NikNCg0KYGBgDQoNCiMjIyMgMy43IC0gSW50ZXJhY3Rpb24gVGVybXMNCg0KVGhpcyBleGFtcGxlIGhhcyBzaG93biB0aGF0IHRyZWVzIGNhbiBjYXB0dXJlIG5vbmxpbmVhciByZWxhdGlvbnNoaXBzIHRoYXQgbG9naXN0aWMgcmVncmVzc2lvbiBjYW4gbm90LCBidXQgdGhhdCB3ZSBjYW4gZ2V0IGFyb3VuZCB0aGlzIHNvbWV0aW1lcyBieSB1c2luZyB2YXJpYWJsZXMgdGhhdCBhcmUgdGhlIGNvbWJpbmF0aW9uIG9mIHR3byB2YXJpYWJsZXMuIFNob3VsZCB3ZSBhbHdheXMgaW5jbHVkZSBhbGwgcG9zc2libGUgaW50ZXJhY3Rpb24gdGVybXMgb2YgdGhlIGluZGVwZW5kZW50IHZhcmlhYmxlcyB3aGVuIGJ1aWxkaW5nIGEgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbD8NCg0KICsgTk8NCiA=