Problem 1.1 - Exploration and Logistic Regression

We will first get familiar with the data. Load the CSV file gerber.csv into R. What proportion of people in this dataset voted in this election ?

gerber <- read.csv("gerber.csv")
temp <- table(gerber$voting)
temp[2] / sum(temp)
        1 
0.3158996 

Problem 1.2 - Exploration and Logistic Regression

Which of the four “treatment groups” had the largest percentage of people who actually voted (voting = 1)?

mean(gerber$voting[gerber$civicduty == 1])
[1] 0.3145377
mean(gerber$voting[gerber$hawthorne == 1])
[1] 0.3223746
mean(gerber$voting[gerber$self == 1])
[1] 0.3451515
mean(gerber$voting[gerber$neighbors== 1])
[1] 0.3779482
print("Neighbors" , quote = FALSE)
[1] Neighbors
# 利用平均值計算投票的比例

Problem 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.

model1 <- glm(voting ~ civicduty + hawthorne + self + neighbors, data = gerber, family = "binomial")
summary(model1)

Call:
glm(formula = voting ~ civicduty + hawthorne + self + neighbors, 
    family = "binomial", data = gerber)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-0.9744  -0.8691  -0.8389   1.4586   1.5590  

Coefficients:
             Estimate Std. Error  z value Pr(>|z|)    
(Intercept) -0.863358   0.005006 -172.459  < 2e-16 ***
civicduty    0.084368   0.012100    6.972 3.12e-12 ***
hawthorne    0.120477   0.012037   10.009  < 2e-16 ***
self         0.222937   0.011867   18.786  < 2e-16 ***
neighbors    0.365092   0.011679   31.260  < 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
print("Civicduty , Hawthorne , Self , Neighbors ", quote = FALSE)
[1] Civicduty , Hawthorne , Self , Neighbors 

Problem 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.)

pred1 <- predict(model1 , type = "response")
temp <- table(gerber$voting , pred1 > 0.3)
(temp[2,2] + temp[1,1]) / sum(temp)
[1] 0.5419578
# 將 confusion matrix 存到 temp 中,再計算 accuracy 的數值

Problem 1.5 - Exploration and Logistic Regression

Using a threshold of 0.5, what is the accuracy of the logistic regression model?

temp <- table(gerber$voting , pred1 > 0.5)
temp[1] / sum(temp)
[1] 0.6841004
# 同上,更改門檻值即可

Problem 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?

library(ROCR)
ROCRpred <- prediction(pred1, gerber$voting)
as.numeric(performance(ROCRpred, "auc")@y.values)
[1] 0.5308461
print("Even though all of the variables are significant, this is a weak predictive model." , quote = FALSE)
[1] Even though all of the variables are significant, this is a weak predictive model.
# AUC 僅高出 0.5 一點點點

Problem 2.1 - Trees

We will now try out trees. Build a CART tree for voting using all data and the same four treatment variables we used before. Don’t set the option method=“class” - we are actually going to create a regression tree here. We are interested in building a tree to explore the fraction of people who vote, or the probability of voting. We’d like CART to split our groups if they have different probabilities of voting. If we used method=‘class’, CART would only split if one of the groups had a probability of voting above 50% and the other had a probability of voting less than 50% (since the predicted outcomes would be different). However, with regression trees, CART will split even if both groups have probability less than 50%.

Leave all the parameters at their default values. You can use the following command in R to build the tree:

CARTmodel = rpart(voting ~ civicduty + hawthorne + self + neighbors, data=gerber) Plot the tree. What happens, and if relevant, why?

library(rpart)
library(rpart.plot)
modelCART <- rpart(voting ~ civicduty + hawthorne + self + neighbors, data = gerber)
prp(modelCART)

Problem 2.2 - Trees

Now build the tree using the command:

CARTmodel2 = rpart(voting ~ civicduty + hawthorne + self + neighbors, data=gerber, cp=0.0) to force the complete tree to be built. Then plot the tree. What do you observe about the order of the splits?

modelCART2 <- rpart(voting ~ civicduty + hawthorne + self + neighbors, data = gerber, cp=0.0)
prp(modelCART2)

print("Neighbor is the first split, civic duty is the last." , quote = FALSE)
[1] Neighbor is the first split, civic duty is the last.
# CP 表示為表示精度的參數

Problem 2.3 - Trees

Using only the CART tree plot, determine what fraction (a number between 0 and 1) of “Civic Duty” people voted:

0.31
[1] 0.31
# 從上圖可以看出來

Problem 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?

modelCART3 <- rpart(voting ~ civicduty + hawthorne + self + neighbors + sex, data = gerber, cp=0.0)
prp(modelCART3)

print("Men" , quote = FALSE)
[1] Men

In the “Civic Duty” group, which gender is more likely to vote?

print("Men" , quote = FALSE)
[1] Men

Problem 3.1 - Interaction Terms

We know trees can handle “nonlinear” relationships, e.g. “in the ‘Civic Duty’ group and female”, but as we will see in the next few questions, it is possible to do the same for logistic regression. First, let’s explore what trees can tell us some more.

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.

modelCARTcontrol <- rpart(voting ~ control, data = gerber, cp = 0.0)
modelCARTcontrol_sex <- rpart(voting ~ control + sex, data = gerber, cp = 0.0)
prp(modelCARTcontrol, digits = 6)

abs(0.296638 - 0.34)
[1] 0.043362

Problem 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(modelCARTcontrol_sex, digits = 6)

0.334176 - 0.290456
[1] 0.04372
0.345818 - 0.302795
[1] 0.043023
print("They are affected about the same (change in probability within 0.001 of each other)." , quote = FALSE)
[1] They are affected about the same (change in probability within 0.001 of each other).

Problem 3.3 - Interaction Terms

Going back to logistic regression now, create a model using “sex” and “control”. Interpret the coefficient for “sex”:

modelControl_Sex <- glm(voting ~ control + sex, data = gerber, family = "binomial")
summary(modelControl_Sex)

Call:
glm(formula = voting ~ control + sex, family = "binomial", data = gerber)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-0.9220  -0.9012  -0.8290   1.4564   1.5717  

Coefficients:
             Estimate Std. Error z value Pr(>|z|)    
(Intercept) -0.635538   0.006511 -97.616  < 2e-16 ***
control     -0.200142   0.007364 -27.179  < 2e-16 ***
sex         -0.055791   0.007343  -7.597 3.02e-14 ***
---
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: 428443  on 344081  degrees of freedom
AIC: 428449

Number of Fisher Scoring iterations: 4
print("Coefficient is negative, reflecting that women are less likely to vote " , quote = FALSE)
[1] Coefficient is negative, reflecting that women are less likely to vote 
# 由於 Sex = 1 代表女性,且係數是負的,代表說女性的投票率是較低的

Problem 3.4 - Interaction Terms

The regression tree calculated the percentage voting exactly for every one of the four possibilities (Man, Not Control), (Man, Control), (Woman, Not Control), (Woman, Control). Logistic regression has attempted to do the same, although it wasn’t able to do as well because it can’t consider exactly the joint possibility of being a women and in the control group.

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”)

The four values in the results correspond to the four possibilities in the order they are stated above ( (Man, Not Control), (Man, Control), (Woman, Not Control), (Woman, Control) ). What is the absolute difference between the tree and the logistic regression for the (Woman, Control) case? Give an answer with five numbers after the decimal point.

Possibilities <- data.frame(sex = c(0,0,1,1) , control = c(0,1,0,1))
temp <- predict(modelControl_Sex, newdata = Possibilities, type = "response")
round(abs(0.2908065 - 0.290456),5)
[1] 0.00035
# 創建一個有這四種狀況的 data.frame

Problem 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:

LogModel2 = glm(voting ~ sex + control + sex:control, data=gerber, family=“binomial”)

How do you interpret the coefficient for the new variable in isolation? That is, how does it relate to the dependent variable?

model2 <- glm(voting ~ sex + control + sex:control, data = gerber, family = "binomial")
summary(model2)

Call:
glm(formula = voting ~ sex + control + sex:control, family = "binomial", 
    data = gerber)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-0.9213  -0.9019  -0.8284   1.4573   1.5724  

Coefficients:
             Estimate Std. Error z value Pr(>|z|)    
(Intercept) -0.637471   0.007603 -83.843  < 2e-16 ***
sex         -0.051888   0.010801  -4.804 1.55e-06 ***
control     -0.196553   0.010356 -18.980  < 2e-16 ***
sex:control -0.007259   0.014729  -0.493    0.622    
---
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: 428442  on 344080  degrees of freedom
AIC: 428450

Number of Fisher Scoring iterations: 4
print("If a person is a woman and in the control group, the chance that she voted goes down." , quote = FALSE)
[1] If a person is a woman and in the control group, the chance that she voted goes down.
# 因為交叉相乘項的係數是負的,代表說是女性且為 control group 的投票率會下降

Problem 3.6 - Interaction Terms

Run the same code as before to calculate the average for each group:

predict(LogModel2, newdata=Possibilities, type=“response”)

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(model2, newdata = Possibilities, type = "response")
        1         2         3         4 
0.3458183 0.3027947 0.3341757 0.2904558 
round(abs(0.2904558 - 0.290456),5)
[1] 0

Problem 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?

print("No" , quote = FALSE)
[1] No
# 加入過多的變數容易導致模型過度適配、失去一般性的問題
LS0tCnRpdGxlOiAiQVM0LTEiCmF1dGhvcjogIkFsbGVuIExpbiBNMDY0MTExMDM4IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIFByb2JsZW0gMS4xIC0gRXhwbG9yYXRpb24gYW5kIExvZ2lzdGljIFJlZ3Jlc3Npb24KCldlIHdpbGwgZmlyc3QgZ2V0IGZhbWlsaWFyIHdpdGggdGhlIGRhdGEuIExvYWQgdGhlIENTViBmaWxlIGdlcmJlci5jc3YgaW50byBSLiBXaGF0IHByb3BvcnRpb24gb2YgcGVvcGxlIGluIHRoaXMgZGF0YXNldCB2b3RlZCBpbiB0aGlzIGVsZWN0aW9uID8KCmBgYHtyfQoKZ2VyYmVyIDwtIHJlYWQuY3N2KCJnZXJiZXIuY3N2IikKdGVtcCA8LSB0YWJsZShnZXJiZXIkdm90aW5nKQp0ZW1wWzJdIC8gc3VtKHRlbXApCgpgYGAKCgojIFByb2JsZW0gMS4yIC0gRXhwbG9yYXRpb24gYW5kIExvZ2lzdGljIFJlZ3Jlc3Npb24KCldoaWNoIG9mIHRoZSBmb3VyICJ0cmVhdG1lbnQgZ3JvdXBzIiBoYWQgdGhlIGxhcmdlc3QgcGVyY2VudGFnZSBvZiBwZW9wbGUgd2hvIGFjdHVhbGx5IHZvdGVkICh2b3RpbmcgPSAxKT8KCmBgYHtyfQoKbWVhbihnZXJiZXIkdm90aW5nW2dlcmJlciRjaXZpY2R1dHkgPT0gMV0pCm1lYW4oZ2VyYmVyJHZvdGluZ1tnZXJiZXIkaGF3dGhvcm5lID09IDFdKQptZWFuKGdlcmJlciR2b3RpbmdbZ2VyYmVyJHNlbGYgPT0gMV0pCm1lYW4oZ2VyYmVyJHZvdGluZ1tnZXJiZXIkbmVpZ2hib3JzPT0gMV0pCgpwcmludCgiTmVpZ2hib3JzIiAsIHF1b3RlID0gRkFMU0UpCgojIOWIqeeUqOW5s+Wdh+WAvOioiOeul+aKleelqOeahOavlOS+iwoKYGBgCgoKIyBQcm9ibGVtIDEuMyAtIEV4cGxvcmF0aW9uIGFuZCBMb2dpc3RpYyBSZWdyZXNzaW9uCgpCdWlsZCBhIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwgZm9yIHZvdGluZyB1c2luZyB0aGUgZm91ciB0cmVhdG1lbnQgZ3JvdXAgdmFyaWFibGVzIGFzIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXMgKGNpdmljZHV0eSwgaGF3dGhvcm5lLCBzZWxmLCBhbmQgbmVpZ2hib3JzKS4gVXNlIGFsbCB0aGUgZGF0YSB0byBidWlsZCB0aGUgbW9kZWwgKERPIE5PVCBzcGxpdCB0aGUgZGF0YSBpbnRvIGEgdHJhaW5pbmcgc2V0IGFuZCB0ZXN0aW5nIHNldCkuIFdoaWNoIG9mIHRoZSBmb2xsb3dpbmcgY29lZmZpY2llbnRzIGFyZSBzaWduaWZpY2FudCBpbiB0aGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbD8gU2VsZWN0IGFsbCB0aGF0IGFwcGx5LgoKYGBge3J9Cgptb2RlbDEgPC0gZ2xtKHZvdGluZyB+IGNpdmljZHV0eSArIGhhd3Rob3JuZSArIHNlbGYgKyBuZWlnaGJvcnMsIGRhdGEgPSBnZXJiZXIsIGZhbWlseSA9ICJiaW5vbWlhbCIpCnN1bW1hcnkobW9kZWwxKQoKcHJpbnQoIkNpdmljZHV0eSAsIEhhd3Rob3JuZSAsIFNlbGYgLCBOZWlnaGJvcnMgIiwgcXVvdGUgPSBGQUxTRSkKCmBgYAoKCiMgUHJvYmxlbSAxLjQgLSBFeHBsb3JhdGlvbiBhbmQgTG9naXN0aWMgUmVncmVzc2lvbgoKVXNpbmcgYSB0aHJlc2hvbGQgb2YgMC4zLCB3aGF0IGlzIHRoZSBhY2N1cmFjeSBvZiB0aGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbD8gKFdoZW4gbWFraW5nIHByZWRpY3Rpb25zLCB5b3UgZG9uJ3QgbmVlZCB0byB1c2UgdGhlIG5ld2RhdGEgYXJndW1lbnQgc2luY2Ugd2UgZGlkbid0IHNwbGl0IG91ciBkYXRhLikKCmBgYHtyfQoKcHJlZDEgPC0gcHJlZGljdChtb2RlbDEgLCB0eXBlID0gInJlc3BvbnNlIikKdGVtcCA8LSB0YWJsZShnZXJiZXIkdm90aW5nICwgcHJlZDEgPiAwLjMpCgoodGVtcFsyLDJdICsgdGVtcFsxLDFdKSAvIHN1bSh0ZW1wKQoKIyDlsIcgY29uZnVzaW9uIG1hdHJpeCDlrZjliLAgdGVtcCDkuK3vvIzlho3oqIjnrpcgYWNjdXJhY3kg55qE5pW45YC8CgpgYGAKCgojIFByb2JsZW0gMS41IC0gRXhwbG9yYXRpb24gYW5kIExvZ2lzdGljIFJlZ3Jlc3Npb24KClVzaW5nIGEgdGhyZXNob2xkIG9mIDAuNSwgd2hhdCBpcyB0aGUgYWNjdXJhY3kgb2YgdGhlIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWw/CgpgYGB7cn0KCnRlbXAgPC0gdGFibGUoZ2VyYmVyJHZvdGluZyAsIHByZWQxID4gMC41KQoKdGVtcFsxXSAvIHN1bSh0ZW1wKQoKIyDlkIzkuIrvvIzmm7TmlLnploDmqrvlgLzljbPlj68KCmBgYAoKCiMgUHJvYmxlbSAxLjYgLSBFeHBsb3JhdGlvbiBhbmQgTG9naXN0aWMgUmVncmVzc2lvbgoKQ29tcGFyZSB5b3VyIHByZXZpb3VzIHR3byBhbnN3ZXJzIHRvIHRoZSBwZXJjZW50YWdlIG9mIHBlb3BsZSB3aG8gZGlkIG5vdCB2b3RlICh0aGUgYmFzZWxpbmUgYWNjdXJhY3kpIGFuZCBjb21wdXRlIHRoZSBBVUMgb2YgdGhlIG1vZGVsLiBXaGF0IGlzIGhhcHBlbmluZyBoZXJlPwoKYGBge3J9CgpsaWJyYXJ5KFJPQ1IpCgpST0NScHJlZCA8LSBwcmVkaWN0aW9uKHByZWQxLCBnZXJiZXIkdm90aW5nKQphcy5udW1lcmljKHBlcmZvcm1hbmNlKFJPQ1JwcmVkLCAiYXVjIilAeS52YWx1ZXMpCgpwcmludCgiRXZlbiB0aG91Z2ggYWxsIG9mIHRoZSB2YXJpYWJsZXMgYXJlIHNpZ25pZmljYW50LCB0aGlzIGlzIGEgd2VhayBwcmVkaWN0aXZlIG1vZGVsLiIgLCBxdW90ZSA9IEZBTFNFKQoKIyBBVUMg5YOF6auY5Ye6IDAuNSDkuIDpu57pu57pu54KCgpgYGAKCgojIFByb2JsZW0gMi4xIC0gVHJlZXMKCldlIHdpbGwgbm93IHRyeSBvdXQgdHJlZXMuIEJ1aWxkIGEgQ0FSVCB0cmVlIGZvciB2b3RpbmcgdXNpbmcgYWxsIGRhdGEgYW5kIHRoZSBzYW1lIGZvdXIgdHJlYXRtZW50IHZhcmlhYmxlcyB3ZSB1c2VkIGJlZm9yZS4gRG9uJ3Qgc2V0IHRoZSBvcHRpb24gbWV0aG9kPSJjbGFzcyIgLSB3ZSBhcmUgYWN0dWFsbHkgZ29pbmcgdG8gY3JlYXRlIGEgcmVncmVzc2lvbiB0cmVlIGhlcmUuIFdlIGFyZSBpbnRlcmVzdGVkIGluIGJ1aWxkaW5nIGEgdHJlZSB0byBleHBsb3JlIHRoZSBmcmFjdGlvbiBvZiBwZW9wbGUgd2hvIHZvdGUsIG9yIHRoZSBwcm9iYWJpbGl0eSBvZiB2b3RpbmcuIFdl4oCZZCBsaWtlIENBUlQgdG8gc3BsaXQgb3VyIGdyb3VwcyBpZiB0aGV5IGhhdmUgZGlmZmVyZW50IHByb2JhYmlsaXRpZXMgb2Ygdm90aW5nLiBJZiB3ZSB1c2VkIG1ldGhvZD3igJhjbGFzc+KAmSwgQ0FSVCB3b3VsZCBvbmx5IHNwbGl0IGlmIG9uZSBvZiB0aGUgZ3JvdXBzIGhhZCBhIHByb2JhYmlsaXR5IG9mIHZvdGluZyBhYm92ZSA1MCUgYW5kIHRoZSBvdGhlciBoYWQgYSBwcm9iYWJpbGl0eSBvZiB2b3RpbmcgbGVzcyB0aGFuIDUwJSAoc2luY2UgdGhlIHByZWRpY3RlZCBvdXRjb21lcyB3b3VsZCBiZSBkaWZmZXJlbnQpLiBIb3dldmVyLCB3aXRoIHJlZ3Jlc3Npb24gdHJlZXMsIENBUlQgd2lsbCBzcGxpdCBldmVuIGlmIGJvdGggZ3JvdXBzIGhhdmUgcHJvYmFiaWxpdHkgbGVzcyB0aGFuIDUwJS4KCkxlYXZlIGFsbCB0aGUgcGFyYW1ldGVycyBhdCB0aGVpciBkZWZhdWx0IHZhbHVlcy4gWW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBjb21tYW5kIGluIFIgdG8gYnVpbGQgdGhlIHRyZWU6CgpDQVJUbW9kZWwgPSBycGFydCh2b3RpbmcgfiBjaXZpY2R1dHkgKyBoYXd0aG9ybmUgKyBzZWxmICsgbmVpZ2hib3JzLCBkYXRhPWdlcmJlcikKUGxvdCB0aGUgdHJlZS4gV2hhdCBoYXBwZW5zLCBhbmQgaWYgcmVsZXZhbnQsIHdoeT8KCmBgYHtyfQoKbGlicmFyeShycGFydCkKbGlicmFyeShycGFydC5wbG90KQoKbW9kZWxDQVJUIDwtIHJwYXJ0KHZvdGluZyB+IGNpdmljZHV0eSArIGhhd3Rob3JuZSArIHNlbGYgKyBuZWlnaGJvcnMsIGRhdGEgPSBnZXJiZXIpCnBycChtb2RlbENBUlQpCgpgYGAKCiMgUHJvYmxlbSAyLjIgLSBUcmVlcwoKTm93IGJ1aWxkIHRoZSB0cmVlIHVzaW5nIHRoZSBjb21tYW5kOgoKQ0FSVG1vZGVsMiA9IHJwYXJ0KHZvdGluZyB+IGNpdmljZHV0eSArIGhhd3Rob3JuZSArIHNlbGYgKyBuZWlnaGJvcnMsIGRhdGE9Z2VyYmVyLCBjcD0wLjApCnRvIGZvcmNlIHRoZSBjb21wbGV0ZSB0cmVlIHRvIGJlIGJ1aWx0LiBUaGVuIHBsb3QgdGhlIHRyZWUuIFdoYXQgZG8geW91IG9ic2VydmUgYWJvdXQgdGhlIG9yZGVyIG9mIHRoZSBzcGxpdHM/CgoKYGBge3J9Cgptb2RlbENBUlQyIDwtIHJwYXJ0KHZvdGluZyB+IGNpdmljZHV0eSArIGhhd3Rob3JuZSArIHNlbGYgKyBuZWlnaGJvcnMsIGRhdGEgPSBnZXJiZXIsIGNwPTAuMCkKcHJwKG1vZGVsQ0FSVDIpCgpwcmludCgiTmVpZ2hib3IgaXMgdGhlIGZpcnN0IHNwbGl0LCBjaXZpYyBkdXR5IGlzIHRoZSBsYXN0LiIgLCBxdW90ZSA9IEZBTFNFKQoKIyBDUCDooajnpLrngrrooajnpLrnsr7luqbnmoTlj4PmlbgKCmBgYAoKCiMgUHJvYmxlbSAyLjMgLSBUcmVlcwoKVXNpbmcgb25seSB0aGUgQ0FSVCB0cmVlIHBsb3QsIGRldGVybWluZSB3aGF0IGZyYWN0aW9uIChhIG51bWJlciBiZXR3ZWVuIDAgYW5kIDEpIG9mICJDaXZpYyBEdXR5IiBwZW9wbGUgdm90ZWQ6CgpgYGB7cn0KCjAuMzEKCiMg5b6e5LiK5ZyW5Y+v5Lul55yL5Ye65L6GCgpgYGAKCgojIFByb2JsZW0gMi40IC0gVHJlZXMKCk1ha2UgYSBuZXcgdHJlZSB0aGF0IGluY2x1ZGVzIHRoZSAic2V4IiB2YXJpYWJsZSwgYWdhaW4gd2l0aCBjcCA9IDAuMC4gTm90aWNlIHRoYXQgc2V4IGFwcGVhcnMgYXMgYSBzcGxpdCB0aGF0IGlzIG9mIHNlY29uZGFyeSBpbXBvcnRhbmNlIHRvIHRoZSB0cmVhdG1lbnQgZ3JvdXAuCgpJbiB0aGUgY29udHJvbCBncm91cCwgd2hpY2ggZ2VuZGVyIGlzIG1vcmUgbGlrZWx5IHRvIHZvdGU/CgpgYGB7cn0KCm1vZGVsQ0FSVDMgPC0gcnBhcnQodm90aW5nIH4gY2l2aWNkdXR5ICsgaGF3dGhvcm5lICsgc2VsZiArIG5laWdoYm9ycyArIHNleCwgZGF0YSA9IGdlcmJlciwgY3A9MC4wKQpwcnAobW9kZWxDQVJUMykKCnByaW50KCJNZW4iICwgcXVvdGUgPSBGQUxTRSkKCgoKYGBgCgoKSW4gdGhlICJDaXZpYyBEdXR5IiBncm91cCwgd2hpY2ggZ2VuZGVyIGlzIG1vcmUgbGlrZWx5IHRvIHZvdGU/CgpgYGB7cn0KCnByaW50KCJNZW4iICwgcXVvdGUgPSBGQUxTRSkKCmBgYAoKCiMgUHJvYmxlbSAzLjEgLSBJbnRlcmFjdGlvbiBUZXJtcwoKV2Uga25vdyB0cmVlcyBjYW4gaGFuZGxlICJub25saW5lYXIiIHJlbGF0aW9uc2hpcHMsIGUuZy4gImluIHRoZSAnQ2l2aWMgRHV0eScgZ3JvdXAgYW5kIGZlbWFsZSIsIGJ1dCBhcyB3ZSB3aWxsIHNlZSBpbiB0aGUgbmV4dCBmZXcgcXVlc3Rpb25zLCBpdCBpcyBwb3NzaWJsZSB0byBkbyB0aGUgc2FtZSBmb3IgbG9naXN0aWMgcmVncmVzc2lvbi4gRmlyc3QsIGxldCdzIGV4cGxvcmUgd2hhdCB0cmVlcyBjYW4gdGVsbCB1cyBzb21lIG1vcmUuCgpMZXQncyBqdXN0IGZvY3VzIG9uIHRoZSAiQ29udHJvbCIgdHJlYXRtZW50IGdyb3VwLiBDcmVhdGUgYSByZWdyZXNzaW9uIHRyZWUgdXNpbmcganVzdCB0aGUgImNvbnRyb2wiIHZhcmlhYmxlLCB0aGVuIGNyZWF0ZSBhbm90aGVyIHRyZWUgd2l0aCB0aGUgImNvbnRyb2wiIGFuZCAic2V4IiB2YXJpYWJsZXMsIGJvdGggd2l0aCBjcD0wLjAuCgpJbiB0aGUgImNvbnRyb2wiIG9ubHkgdHJlZSwgd2hhdCBpcyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIGRpZmZlcmVuY2UgaW4gdGhlIHByZWRpY3RlZCBwcm9iYWJpbGl0eSBvZiB2b3RpbmcgYmV0d2VlbiBiZWluZyBpbiB0aGUgY29udHJvbCBncm91cCB2ZXJzdXMgYmVpbmcgaW4gYSBkaWZmZXJlbnQgZ3JvdXA/IFlvdSBjYW4gdXNlIHRoZSBhYnNvbHV0ZSB2YWx1ZSBmdW5jdGlvbiB0byBnZXQgYW5zd2VyLCBpLmUuIGFicyhDb250cm9sIFByZWRpY3Rpb24gLSBOb24tQ29udHJvbCBQcmVkaWN0aW9uKS4gQWRkIHRoZSBhcmd1bWVudCAiZGlnaXRzID0gNiIgdG8gdGhlIHBycCBjb21tYW5kIHRvIGdldCBhIG1vcmUgYWNjdXJhdGUgZXN0aW1hdGUuCgpgYGB7cn0KCm1vZGVsQ0FSVGNvbnRyb2wgPC0gcnBhcnQodm90aW5nIH4gY29udHJvbCwgZGF0YSA9IGdlcmJlciwgY3AgPSAwLjApCm1vZGVsQ0FSVGNvbnRyb2xfc2V4IDwtIHJwYXJ0KHZvdGluZyB+IGNvbnRyb2wgKyBzZXgsIGRhdGEgPSBnZXJiZXIsIGNwID0gMC4wKQoKcHJwKG1vZGVsQ0FSVGNvbnRyb2wsIGRpZ2l0cyA9IDYpCgphYnMoMC4yOTY2MzggLSAwLjM0KQoKYGBgCgoKIyBQcm9ibGVtIDMuMiAtIEludGVyYWN0aW9uIFRlcm1zCgpOb3csIHVzaW5nIHRoZSBzZWNvbmQgdHJlZSAod2l0aCBjb250cm9sIGFuZCBzZXgpLCBkZXRlcm1pbmUgd2hvIGlzIGFmZmVjdGVkIG1vcmUgYnkgTk9UIGJlaW5nIGluIHRoZSBjb250cm9sIGdyb3VwIChiZWluZyBpbiBhbnkgb2YgdGhlIGZvdXIgdHJlYXRtZW50IGdyb3Vwcyk6CgpgYGB7cn0KCnBycChtb2RlbENBUlRjb250cm9sX3NleCwgZGlnaXRzID0gNikKCjAuMzM0MTc2IC0gMC4yOTA0NTYKMC4zNDU4MTggLSAwLjMwMjc5NQoKcHJpbnQoIlRoZXkgYXJlIGFmZmVjdGVkIGFib3V0IHRoZSBzYW1lIChjaGFuZ2UgaW4gcHJvYmFiaWxpdHkgd2l0aGluIDAuMDAxIG9mIGVhY2ggb3RoZXIpLiIgLCBxdW90ZSA9IEZBTFNFKQoKYGBgCgoKIyBQcm9ibGVtIDMuMyAtIEludGVyYWN0aW9uIFRlcm1zCgpHb2luZyBiYWNrIHRvIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbm93LCBjcmVhdGUgYSBtb2RlbCB1c2luZyAic2V4IiBhbmQgImNvbnRyb2wiLiBJbnRlcnByZXQgdGhlIGNvZWZmaWNpZW50IGZvciAic2V4IjoKCmBgYHtyfQoKbW9kZWxDb250cm9sX1NleCA8LSBnbG0odm90aW5nIH4gY29udHJvbCArIHNleCwgZGF0YSA9IGdlcmJlciwgZmFtaWx5ID0gImJpbm9taWFsIikKc3VtbWFyeShtb2RlbENvbnRyb2xfU2V4KQoKcHJpbnQoIkNvZWZmaWNpZW50IGlzIG5lZ2F0aXZlLCByZWZsZWN0aW5nIHRoYXQgd29tZW4gYXJlIGxlc3MgbGlrZWx5IHRvIHZvdGUgIiAsIHF1b3RlID0gRkFMU0UpCgojIOeUseaWvCBTZXggPSAxIOS7o+ihqOWls+aAp++8jOS4lOS/guaVuOaYr+iyoOeahO+8jOS7o+ihqOiqquWls+aAp+eahOaKleelqOeOh+aYr+i8g+S9jueahAoKYGBgCgoKIyBQcm9ibGVtIDMuNCAtIEludGVyYWN0aW9uIFRlcm1zCgpUaGUgcmVncmVzc2lvbiB0cmVlIGNhbGN1bGF0ZWQgdGhlIHBlcmNlbnRhZ2Ugdm90aW5nIGV4YWN0bHkgZm9yIGV2ZXJ5IG9uZSBvZiB0aGUgZm91ciBwb3NzaWJpbGl0aWVzIChNYW4sIE5vdCBDb250cm9sKSwgKE1hbiwgQ29udHJvbCksIChXb21hbiwgTm90IENvbnRyb2wpLCAoV29tYW4sIENvbnRyb2wpLiBMb2dpc3RpYyByZWdyZXNzaW9uIGhhcyBhdHRlbXB0ZWQgdG8gZG8gdGhlIHNhbWUsIGFsdGhvdWdoIGl0IHdhc24ndCBhYmxlIHRvIGRvIGFzIHdlbGwgYmVjYXVzZSBpdCBjYW4ndCBjb25zaWRlciBleGFjdGx5IHRoZSBqb2ludCBwb3NzaWJpbGl0eSBvZiBiZWluZyBhIHdvbWVuIGFuZCBpbiB0aGUgY29udHJvbCBncm91cC4KCldlIGNhbiBxdWFudGlmeSB0aGlzIHByZWNpc2VseS4gQ3JlYXRlIHRoZSBmb2xsb3dpbmcgZGF0YWZyYW1lICh0aGlzIGNvbnRhaW5zIGFsbCBvZiB0aGUgcG9zc2libGUgdmFsdWVzIG9mIHNleCBhbmQgY29udHJvbCksIGFuZCBldmFsdWF0ZSB5b3VyIGxvZ2lzdGljIHJlZ3Jlc3Npb24gdXNpbmcgdGhlIHByZWRpY3QgZnVuY3Rpb24gKHdoZXJlICJMb2dNb2RlbFNleCIgaXMgdGhlIG5hbWUgb2YgeW91ciBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsIHRoYXQgdXNlcyBib3RoIGNvbnRyb2wgYW5kIHNleCk6CgpQb3NzaWJpbGl0aWVzID0gZGF0YS5mcmFtZShzZXg9YygwLDAsMSwxKSxjb250cm9sPWMoMCwxLDAsMSkpCnByZWRpY3QoTG9nTW9kZWxTZXgsIG5ld2RhdGE9UG9zc2liaWxpdGllcywgdHlwZT0icmVzcG9uc2UiKQoKVGhlIGZvdXIgdmFsdWVzIGluIHRoZSByZXN1bHRzIGNvcnJlc3BvbmQgdG8gdGhlIGZvdXIgcG9zc2liaWxpdGllcyBpbiB0aGUgb3JkZXIgdGhleSBhcmUgc3RhdGVkIGFib3ZlICggKE1hbiwgTm90IENvbnRyb2wpLCAoTWFuLCBDb250cm9sKSwgKFdvbWFuLCBOb3QgQ29udHJvbCksIChXb21hbiwgQ29udHJvbCkgKS4gV2hhdCBpcyB0aGUgYWJzb2x1dGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0cmVlIGFuZCB0aGUgbG9naXN0aWMgcmVncmVzc2lvbiBmb3IgdGhlIChXb21hbiwgQ29udHJvbCkgY2FzZT8gR2l2ZSBhbiBhbnN3ZXIgd2l0aCBmaXZlIG51bWJlcnMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuCgpgYGB7cn0KClBvc3NpYmlsaXRpZXMgPC0gZGF0YS5mcmFtZShzZXggPSBjKDAsMCwxLDEpICwgY29udHJvbCA9IGMoMCwxLDAsMSkpCnRlbXAgPC0gcHJlZGljdChtb2RlbENvbnRyb2xfU2V4LCBuZXdkYXRhID0gUG9zc2liaWxpdGllcywgdHlwZSA9ICJyZXNwb25zZSIpCgpyb3VuZChhYnMoMC4yOTA4MDY1IC0gMC4yOTA0NTYpLDUpCgojIOWJteW7uuS4gOWAi+aciemAmeWbm+eorueLgOazgeeahCBkYXRhLmZyYW1lCgoKYGBgCgoKIyBQcm9ibGVtIDMuNSAtIEludGVyYWN0aW9uIFRlcm1zCgpTbyB0aGUgZGlmZmVyZW5jZSBpcyBub3QgdG9vIGJpZyBmb3IgdGhpcyBkYXRhc2V0LCBidXQgaXQgaXMgdGhlcmUuIFdlJ3JlIGdvaW5nIHRvIGFkZCBhIG5ldyB0ZXJtIHRvIG91ciBsb2dpc3RpYyByZWdyZXNzaW9uIG5vdywgdGhhdCBpcyB0aGUgY29tYmluYXRpb24gb2YgdGhlICJzZXgiIGFuZCAiY29udHJvbCIgdmFyaWFibGVzIC0gc28gaWYgdGhpcyBuZXcgdmFyaWFibGUgaXMgMSwgdGhhdCBtZWFucyB0aGUgcGVyc29uIGlzIGEgd29tYW4gQU5EIGluIHRoZSBjb250cm9sIGdyb3VwLiBXZSBjYW4gZG8gdGhhdCB3aXRoIHRoZSBmb2xsb3dpbmcgY29tbWFuZDoKCkxvZ01vZGVsMiA9IGdsbSh2b3RpbmcgfiBzZXggKyBjb250cm9sICsgc2V4OmNvbnRyb2wsIGRhdGE9Z2VyYmVyLCBmYW1pbHk9ImJpbm9taWFsIikKCkhvdyBkbyB5b3UgaW50ZXJwcmV0IHRoZSBjb2VmZmljaWVudCBmb3IgdGhlIG5ldyB2YXJpYWJsZSBpbiBpc29sYXRpb24/IFRoYXQgaXMsIGhvdyBkb2VzIGl0IHJlbGF0ZSB0byB0aGUgZGVwZW5kZW50IHZhcmlhYmxlPwoKYGBge3J9Cgptb2RlbDIgPC0gZ2xtKHZvdGluZyB+IHNleCArIGNvbnRyb2wgKyBzZXg6Y29udHJvbCwgZGF0YSA9IGdlcmJlciwgZmFtaWx5ID0gImJpbm9taWFsIikKc3VtbWFyeShtb2RlbDIpCgpwcmludCgiSWYgYSBwZXJzb24gaXMgYSB3b21hbiBhbmQgaW4gdGhlIGNvbnRyb2wgZ3JvdXAsIHRoZSBjaGFuY2UgdGhhdCBzaGUgdm90ZWQgZ29lcyBkb3duLiIgLCBxdW90ZSA9IEZBTFNFKQoKIyDlm6DngrrkuqTlj4nnm7jkuZjpoIXnmoTkv4LmlbjmmK/osqDnmoTvvIzku6PooajoqqrmmK/lpbPmgKfkuJTngrogY29udHJvbCBncm91cCDnmoTmipXnpajnjofmnIPkuIvpmY0KCmBgYAoKCiMgUHJvYmxlbSAzLjYgLSBJbnRlcmFjdGlvbiBUZXJtcwoKUnVuIHRoZSBzYW1lIGNvZGUgYXMgYmVmb3JlIHRvIGNhbGN1bGF0ZSB0aGUgYXZlcmFnZSBmb3IgZWFjaCBncm91cDoKCnByZWRpY3QoTG9nTW9kZWwyLCBuZXdkYXRhPVBvc3NpYmlsaXRpZXMsIHR5cGU9InJlc3BvbnNlIikKCk5vdyB3aGF0IGlzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwgYW5kIHRoZSBDQVJUIG1vZGVsIGZvciB0aGUgKFdvbWFuLCBDb250cm9sKSBjYXNlPyBBZ2FpbiwgZ2l2ZSB5b3VyIGFuc3dlciB3aXRoIGZpdmUgbnVtYmVycyBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC4KCmBgYHtyfQoKcHJlZGljdChtb2RlbDIsIG5ld2RhdGEgPSBQb3NzaWJpbGl0aWVzLCB0eXBlID0gInJlc3BvbnNlIikKcm91bmQoYWJzKDAuMjkwNDU1OCAtIDAuMjkwNDU2KSw1KQoKYGBgCgoKIyBQcm9ibGVtIDMuNyAtIEludGVyYWN0aW9uIFRlcm1zCgpUaGlzIGV4YW1wbGUgaGFzIHNob3duIHRoYXQgdHJlZXMgY2FuIGNhcHR1cmUgbm9ubGluZWFyIHJlbGF0aW9uc2hpcHMgdGhhdCBsb2dpc3RpYyByZWdyZXNzaW9uIGNhbiBub3QsIGJ1dCB0aGF0IHdlIGNhbiBnZXQgYXJvdW5kIHRoaXMgc29tZXRpbWVzIGJ5IHVzaW5nIHZhcmlhYmxlcyB0aGF0IGFyZSB0aGUgY29tYmluYXRpb24gb2YgdHdvIHZhcmlhYmxlcy4gU2hvdWxkIHdlIGFsd2F5cyBpbmNsdWRlIGFsbCBwb3NzaWJsZSBpbnRlcmFjdGlvbiB0ZXJtcyBvZiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGVzIHdoZW4gYnVpbGRpbmcgYSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsPwoKYGBge3J9CgpwcmludCgiTm8iICwgcXVvdGUgPSBGQUxTRSkKCiMg5Yqg5YWl6YGO5aSa55qE6K6K5pW45a655piT5bCO6Ie05qih5Z6L6YGO5bqm6YGp6YWN44CB5aSx5Y675LiA6Iis5oCn55qE5ZWP6aGMCgpgYGAKCgoKCgo=