Introduction
The RMS Titanic was a British luxury passenger liner that sank during
its maiden voyage en route to New York City from Southampton, England,
killing about 1,500 passengers and ship personnel. It is one of the most
famous tragedies in modern history, it inspired numerous stories,
several films, and a musical and has been the subject of much
scholarship and scientific speculation.
This report will continue the scientific exploration of the Titanic.
The estimated 2,224 passengers all have their own stories of escape or
death in the wreck. It is believed, however, that studying the
underlying information about these passengers can provide insight on why
certain people survived.
Data Source
The data set used in this report is sourced from Kaggle.com. It was
orignially created for a machine learning competition hosted by Kaggle.
The link for this data set is https://www.kaggle.com/c/titanic. The data is originally
split into seperate train and testing data sets for purposes of the
competition. The train data is used in this report for more observations
and the complete set of variables.
The data was uploaded to a GitHub repository for perpetual online
access. This report will source the data from this repository (URL, https://raw.githubusercontent.com/ncbrechbill/STA321/refs/heads/main/STA321/titanic.csv)
This data contains 891 observations on 12 variables. Any observations
of N/A in variables of interest will be removed. The variables are:
- PassengerID: A unique identifier
- Survived: The survival status of the passenger (0 =
No, 1 = Yes)
- Pclass: The passenger’s ticket class (1st, 2nd, or
3rd)
- Name: The passenger’s name
- Sex: The passenger’s sex
- Age: The passenger’s age in years
- sibSp: Number of siblings/spouse aboard
- Parch: Number of parents/children aboard
- Ticket: Passenger’s ticket number
- Fare: Passenger’s boarding fare in USD
- Cabin: The passenger’s cabin
- Embarked: Location which passenger embarked (C =
Cherbourg, Q = Queenstown, S = Southampton)
url = "https://raw.githubusercontent.com/ncbrechbill/STA321/refs/heads/main/STA321/titanic.csv"
titanic <- read.csv(url)
data <- na.omit(dplyr::select(titanic, Survived, Pclass, Age, Sex, SibSp, Parch, Fare))
data$Survived <- as.factor(data$Survived)
data$Pclass <- as.factor(data$Pclass)
Research Question
This report builds a logistic regression model to predict the
survival of the Titanic passengers using demographic information of a
sample of survivors
Exploratory Data
Analysis
All observations with missing values in any of the variables were
removed. This leaves 714 observations. Scatter plots were built to
display potential issues with predictor variables. The scatter plots are
displayed below.
pairs.panels(data[,-9],
method = "pearson", # correlation method
hist.col = "#00AFBB",
density = TRUE, # show density plots
ellipses = TRUE # show correlation ellipses
)

We can see that there are more deaths than survivals, more high class
passengers than middle or low, and more men than women. Age is slightly
skewed right, but no transformation will be applied. SibSP, Parch, and
Fare are highly skewed. PassengerID, Name, Ticket, Cabin, and Embarked
were not included by irrelevance.
Predictive Logistic
Regression
Split: Training and
Testing Data
The data is randomly split into two unique subsets. 60% of the data
is a training subset on which the model will be constructed. The
remaining 40% will be used for testing the model and providing
performance indications. The randomization seed will be set for
reproducibility of the samples.
set.seed(123)
train <- createDataPartition(data$Survived, p=0.6, list=FALSE)
training <- data[train,]
testing <- data[-train,]
pander(head(training), caption = "First 5 entries of the training data subset")
First 5 entries of the training data subset
| 3 |
1 |
3 |
26 |
female |
0 |
0 |
7.925 |
| 4 |
1 |
1 |
35 |
female |
1 |
0 |
53.1 |
| 5 |
0 |
3 |
35 |
male |
0 |
0 |
8.05 |
| 8 |
0 |
3 |
2 |
male |
3 |
1 |
21.07 |
| 10 |
1 |
2 |
14 |
female |
1 |
0 |
30.07 |
| 11 |
1 |
3 |
4 |
female |
1 |
1 |
16.7 |
Multiple Logistic
Regression
Candidate Model
#1
The first candidate model is built upon the variables age, class, and
sex. 10-fold cross validation will be used in this models training. The
coefficients will be displayed with an exponential transformation.
ctrl <- trainControl(method = "cv", number = 10, savePredictions = TRUE)
model <- train(Survived ~ Age + Pclass + Sex,
data=training,
method="glm",
family="binomial",
trControl=ctrl,
tuneLength = 10)
pander(exp(coef(model$finalModel)))
| 32.41 |
0.9697 |
0.2259 |
0.07259 |
0.1157 |
Candidate Model
#2
The second candidate model is built upon the variable age. This is
because age is a continuous variable that will have more predictive
power than the categorical variables. The coefficients are again
displayed with exponential transformation.
model.reduced <- train(Survived ~ Age,
data=training,
method="glm",
family="binomial",
trControl=ctrl,
tuneLength = 10)
pander(exp(coef(model.reduced$finalModel)))
We use a likelihood ratio test to determine if using the larger
candidate model is demonstrably improved upon the simpler, smaller
model. P <0.001, and we thus gain evidence in favor of the larger
model.
model.glm <- glm(Survived ~ Age + Sex + Pclass,
data=training,
family="binomial")
model.reduced.glm <- glm(Survived ~ Age,
data=training,
family="binomial")
anova(model.glm, model.reduced.glm, test="Chisq")
Analysis of Deviance Table
Model 1: Survived ~ Age + Sex + Pclass
Model 2: Survived ~ Age
Resid. Df Resid. Dev Df Deviance Pr(>Chi)
1 424 409.31
2 427 578.62 -3 -169.3 < 2.2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Variable
Importance
We assess the importance of each variable in the multiple logistic
regression model.
varImp(model)
glm variable importance
Overall
Sexmale 100.00
Pclass3 80.04
Pclass2 19.41
Age 0.00
Classification
Rate
Using the testing data subset, we can assess the accuracy of the
model. This model had an accuracy of 81.05%. The model resulted in an
equal amount of false-survivals and false-deaths. The sensitivity was
84.02% and specificity was 76.72%.
pred = predict(model, newdata=testing)
accuracy <- table(pred, testing[,"Survived"])
confusionMatrix(data=pred, testing$Survived)
Confusion Matrix and Statistics
Reference
Prediction 0 1
0 142 27
1 27 89
Accuracy : 0.8105
95% CI : (0.7601, 0.8543)
No Information Rate : 0.593
P-Value [Acc > NIR] : 3.435e-15
Kappa : 0.6075
Mcnemar's Test P-Value : 1
Sensitivity : 0.8402
Specificity : 0.7672
Pos Pred Value : 0.8402
Neg Pred Value : 0.7672
Prevalence : 0.5930
Detection Rate : 0.4982
Detection Prevalence : 0.5930
Balanced Accuracy : 0.8037
'Positive' Class : 0
LS0tDQp0aXRsZTogIlByZWRpY3RpdmUgTG9naXN0aWMgQW5hbHlzaXMgb2YgUk1TIFRpdGFuaWMgU3Vydml2b3JzIg0KYXV0aG9yOiAiTm9haCBCcmVjaGJpbGwiDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ193aWR0aDogNg0KICAgIGZpZ19oZWlnaHQ6IDYNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQovKiBDYXNjYWRpbmcgU3R5bGUgU2hlZXRzIChDU1MpIGlzIGEgc3R5bGVzaGVldCBsYW5ndWFnZSB1c2VkIHRvIGRlc2NyaWJlIHRoZSBwcmVzZW50YXRpb24gb2YgYSBkb2N1bWVudCB3cml0dGVuIGluIEhUTUwgb3IgWE1MLiBpdCBpcyBhIHNpbXBsZSBtZWNoYW5pc20gZm9yIGFkZGluZyBzdHlsZSAoZS5nLiwgZm9udHMsIGNvbG9ycywgc3BhY2luZykgdG8gV2ViIGRvY3VtZW50cy4gKi8NCg0KaDEudGl0bGUgeyAgLyogVGl0bGUgLSBmb250IHNwZWNpZmljYXRpb25zIG9mIHRoZSByZXBvcnQgdGl0bGUgKi8NCiAgZm9udC1zaXplOiAyNHB4Ow0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciBhdXRob3JzICAqLw0KICBmb250LXNpemU6IDIwcHg7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gZm9udCBzcGVjaWZpY2F0aW9ucyBmb3IgdGhlIGRhdGUgICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDEgeyAvKiBIZWFkZXIgMSAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGxldmVsIDEgc2VjdGlvbiB0aXRsZSAgKi8NCiAgICBmb250LXNpemU6IDIycHg7DQogICAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCmgyIHsgLyogSGVhZGVyIDIgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciBsZXZlbCAyIHNlY3Rpb24gdGl0bGUgKi8NCiAgICBmb250LXNpemU6IDIwcHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBmb250IHNwZWNpZmljYXRpb25zIG9mIGxldmVsIDMgc2VjdGlvbiB0aXRsZSAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBmb250IHNwZWNpZmljYXRpb25zIG9mIGxldmVsIDQgc2VjdGlvbiB0aXRsZSAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCi5oaWdobGlnaHRtZSB7IGJhY2tncm91bmQtY29sb3I6eWVsbG93OyB9DQoNCnAgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQpgYGANCg0KYGBge3IgcGFja2FnZXMsIGluY2x1ZGU9RkFMU0V9DQpsb2FkX3BhY2thZ2VzIDwtIGZ1bmN0aW9uKHBrZ19saXN0KSB7DQogIGZvciAocGtnIGluIHBrZ19saXN0KSB7DQogICAgaWYgKCFyZXF1aXJlKHBrZywgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKSkgew0KICAgICAgaW5zdGFsbC5wYWNrYWdlcyhwa2csIGRlcGVuZGVuY2llcyA9IFRSVUUpDQogICAgICBsaWJyYXJ5KHBrZywgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKQ0KICAgIH0NCiAgfQ0KfQ0KDQpwYWNrYWdlcyA8LSBjKCJ0aWR5dmVyc2UiLCAiR0dhbGx5IiwgInBhbmRlciIsICJwc3ljaCIsICJNQVNTIiwgImNhcmV0IikNCmxvYWRfcGFja2FnZXMocGFja2FnZXMpDQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICANCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLCAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy5hbGlnbiA9ICJjZW50ZXIiDQogICAgICAgICAgICAgICAgICAgICAgKSAgIA0KYGBgDQoNCiMgSW50cm9kdWN0aW9uDQoNClRoZSBSTVMgVGl0YW5pYyB3YXMgYSBCcml0aXNoIGx1eHVyeSBwYXNzZW5nZXIgbGluZXIgdGhhdCBzYW5rIGR1cmluZyBpdHMgbWFpZGVuIHZveWFnZSBlbiByb3V0ZSB0byBOZXcgWW9yayBDaXR5IGZyb20gU291dGhhbXB0b24sIEVuZ2xhbmQsIGtpbGxpbmcgYWJvdXQgMSw1MDAgcGFzc2VuZ2VycyBhbmQgc2hpcCBwZXJzb25uZWwuIEl0IGlzIG9uZSBvZiB0aGUgbW9zdCBmYW1vdXMgdHJhZ2VkaWVzIGluIG1vZGVybiBoaXN0b3J5LCBpdCBpbnNwaXJlZCBudW1lcm91cyBzdG9yaWVzLCBzZXZlcmFsIGZpbG1zLCBhbmQgYSBtdXNpY2FsIGFuZCBoYXMgYmVlbiB0aGUgc3ViamVjdCBvZiBtdWNoIHNjaG9sYXJzaGlwIGFuZCBzY2llbnRpZmljIHNwZWN1bGF0aW9uLg0KDQpUaGlzIHJlcG9ydCB3aWxsIGNvbnRpbnVlIHRoZSBzY2llbnRpZmljIGV4cGxvcmF0aW9uIG9mIHRoZSBUaXRhbmljLiBUaGUgZXN0aW1hdGVkIDIsMjI0IHBhc3NlbmdlcnMgYWxsIGhhdmUgdGhlaXIgb3duIHN0b3JpZXMgb2YgZXNjYXBlIG9yIGRlYXRoIGluIHRoZSB3cmVjay4gSXQgaXMgYmVsaWV2ZWQsIGhvd2V2ZXIsIHRoYXQgc3R1ZHlpbmcgdGhlIHVuZGVybHlpbmcgaW5mb3JtYXRpb24gYWJvdXQgdGhlc2UgcGFzc2VuZ2VycyBjYW4gcHJvdmlkZSBpbnNpZ2h0IG9uIHdoeSBjZXJ0YWluIHBlb3BsZSBzdXJ2aXZlZC4NCg0KIyBEYXRhIFNvdXJjZQ0KDQpUaGUgZGF0YSBzZXQgdXNlZCBpbiB0aGlzIHJlcG9ydCBpcyBzb3VyY2VkIGZyb20gS2FnZ2xlLmNvbS4gSXQgd2FzIG9yaWduaWFsbHkgY3JlYXRlZCBmb3IgYSBtYWNoaW5lIGxlYXJuaW5nIGNvbXBldGl0aW9uIGhvc3RlZCBieSBLYWdnbGUuIFRoZSBsaW5rIGZvciB0aGlzIGRhdGEgc2V0IGlzIDxodHRwczovL3d3dy5rYWdnbGUuY29tL2MvdGl0YW5pYz4uIFRoZSBkYXRhIGlzIG9yaWdpbmFsbHkgc3BsaXQgaW50byBzZXBlcmF0ZSB0cmFpbiBhbmQgdGVzdGluZyBkYXRhIHNldHMgZm9yIHB1cnBvc2VzIG9mIHRoZSBjb21wZXRpdGlvbi4gVGhlIHRyYWluIGRhdGEgaXMgdXNlZCBpbiB0aGlzIHJlcG9ydCBmb3IgbW9yZSBvYnNlcnZhdGlvbnMgYW5kIHRoZSBjb21wbGV0ZSBzZXQgb2YgdmFyaWFibGVzLg0KDQpUaGUgZGF0YSB3YXMgdXBsb2FkZWQgdG8gYSBHaXRIdWIgcmVwb3NpdG9yeSBmb3IgcGVycGV0dWFsIG9ubGluZSBhY2Nlc3MuIFRoaXMgcmVwb3J0IHdpbGwgc291cmNlIHRoZSBkYXRhIGZyb20gdGhpcyByZXBvc2l0b3J5IChVUkwsIDxodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vbmNicmVjaGJpbGwvU1RBMzIxL3JlZnMvaGVhZHMvbWFpbi9TVEEzMjEvdGl0YW5pYy5jc3Y+KQ0KDQpUaGlzIGRhdGEgY29udGFpbnMgODkxIG9ic2VydmF0aW9ucyBvbiAxMiB2YXJpYWJsZXMuIEFueSBvYnNlcnZhdGlvbnMgb2YgTi9BIGluIHZhcmlhYmxlcyBvZiBpbnRlcmVzdCB3aWxsIGJlIHJlbW92ZWQuIFRoZSB2YXJpYWJsZXMgYXJlOg0KDQoxLiAgKipQYXNzZW5nZXJJRCoqOiBBIHVuaXF1ZSBpZGVudGlmaWVyDQoyLiAgKipTdXJ2aXZlZCoqOiBUaGUgc3Vydml2YWwgc3RhdHVzIG9mIHRoZSBwYXNzZW5nZXIgKDAgPSBObywgMSA9IFllcykNCjMuICAqKlBjbGFzcyoqOiBUaGUgcGFzc2VuZ2VyJ3MgdGlja2V0IGNsYXNzICgxc3QsIDJuZCwgb3IgM3JkKQ0KNC4gICoqTmFtZSoqOiBUaGUgcGFzc2VuZ2VyJ3MgbmFtZQ0KNS4gICoqU2V4Kio6IFRoZSBwYXNzZW5nZXIncyBzZXgNCjYuICAqKkFnZSoqOiBUaGUgcGFzc2VuZ2VyJ3MgYWdlIGluIHllYXJzDQo3LiAgKipzaWJTcCoqOiBOdW1iZXIgb2Ygc2libGluZ3Mvc3BvdXNlIGFib2FyZA0KOC4gICoqUGFyY2gqKjogTnVtYmVyIG9mIHBhcmVudHMvY2hpbGRyZW4gYWJvYXJkDQo5LiAgKipUaWNrZXQqKjogUGFzc2VuZ2VyJ3MgdGlja2V0IG51bWJlcg0KMTAuICoqRmFyZSoqOiBQYXNzZW5nZXIncyBib2FyZGluZyBmYXJlIGluIFVTRA0KMTEuICoqQ2FiaW4qKjogVGhlIHBhc3NlbmdlcidzIGNhYmluDQoxMi4gKipFbWJhcmtlZCoqOiBMb2NhdGlvbiB3aGljaCBwYXNzZW5nZXIgZW1iYXJrZWQgKEMgPSBDaGVyYm91cmcsIFEgPSBRdWVlbnN0b3duLCBTID0gU291dGhhbXB0b24pDQoNCmBgYHtyIGRhdGEgbG9hZGluZ30NCnVybCA9ICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vbmNicmVjaGJpbGwvU1RBMzIxL3JlZnMvaGVhZHMvbWFpbi9TVEEzMjEvdGl0YW5pYy5jc3YiDQp0aXRhbmljIDwtIHJlYWQuY3N2KHVybCkNCmRhdGEgPC0gbmEub21pdChkcGx5cjo6c2VsZWN0KHRpdGFuaWMsIFN1cnZpdmVkLCBQY2xhc3MsIEFnZSwgU2V4LCBTaWJTcCwgUGFyY2gsIEZhcmUpKQ0KZGF0YSRTdXJ2aXZlZCA8LSBhcy5mYWN0b3IoZGF0YSRTdXJ2aXZlZCkNCmRhdGEkUGNsYXNzIDwtIGFzLmZhY3RvcihkYXRhJFBjbGFzcykNCmBgYA0KDQojIFJlc2VhcmNoIFF1ZXN0aW9uDQoNClRoaXMgcmVwb3J0IGJ1aWxkcyBhIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwgdG8gcHJlZGljdCB0aGUgc3Vydml2YWwgb2YgdGhlIFRpdGFuaWMgcGFzc2VuZ2VycyB1c2luZyBkZW1vZ3JhcGhpYyBpbmZvcm1hdGlvbiBvZiBhIHNhbXBsZSBvZiBzdXJ2aXZvcnMNCg0KIyBFeHBsb3JhdG9yeSBEYXRhIEFuYWx5c2lzDQoNCkFsbCBvYnNlcnZhdGlvbnMgd2l0aCBtaXNzaW5nIHZhbHVlcyBpbiBhbnkgb2YgdGhlIHZhcmlhYmxlcyB3ZXJlIHJlbW92ZWQuIFRoaXMgbGVhdmVzIDcxNCBvYnNlcnZhdGlvbnMuIFNjYXR0ZXIgcGxvdHMgd2VyZSBidWlsdCB0byBkaXNwbGF5IHBvdGVudGlhbCBpc3N1ZXMgd2l0aCBwcmVkaWN0b3IgdmFyaWFibGVzLiBUaGUgc2NhdHRlciBwbG90cyBhcmUgZGlzcGxheWVkIGJlbG93Lg0KDQpgYGB7cn0NCnBhaXJzLnBhbmVscyhkYXRhWywtOV0sIA0KICAgICAgICAgICAgIG1ldGhvZCA9ICJwZWFyc29uIiwgIyBjb3JyZWxhdGlvbiBtZXRob2QNCiAgICAgICAgICAgICBoaXN0LmNvbCA9ICIjMDBBRkJCIiwNCiAgICAgICAgICAgICBkZW5zaXR5ID0gVFJVRSwgICMgc2hvdyBkZW5zaXR5IHBsb3RzDQogICAgICAgICAgICAgZWxsaXBzZXMgPSBUUlVFICMgc2hvdyBjb3JyZWxhdGlvbiBlbGxpcHNlcw0KICAgICAgICAgICAgICkNCmBgYA0KDQpXZSBjYW4gc2VlIHRoYXQgdGhlcmUgYXJlIG1vcmUgZGVhdGhzIHRoYW4gc3Vydml2YWxzLCBtb3JlIGhpZ2ggY2xhc3MgcGFzc2VuZ2VycyB0aGFuIG1pZGRsZSBvciBsb3csIGFuZCBtb3JlIG1lbiB0aGFuIHdvbWVuLiBBZ2UgaXMgc2xpZ2h0bHkgc2tld2VkIHJpZ2h0LCBidXQgbm8gdHJhbnNmb3JtYXRpb24gd2lsbCBiZSBhcHBsaWVkLiBTaWJTUCwgUGFyY2gsIGFuZCBGYXJlIGFyZSBoaWdobHkgc2tld2VkLiBQYXNzZW5nZXJJRCwgTmFtZSwgVGlja2V0LCBDYWJpbiwgYW5kIEVtYmFya2VkIHdlcmUgbm90IGluY2x1ZGVkIGJ5IGlycmVsZXZhbmNlLg0KDQojIFByZWRpY3RpdmUgTG9naXN0aWMgUmVncmVzc2lvbg0KDQojIyBTcGxpdDogVHJhaW5pbmcgYW5kIFRlc3RpbmcgRGF0YQ0KDQpUaGUgZGF0YSBpcyByYW5kb21seSBzcGxpdCBpbnRvIHR3byB1bmlxdWUgc3Vic2V0cy4gNjAlIG9mIHRoZSBkYXRhIGlzIGEgdHJhaW5pbmcgc3Vic2V0IG9uIHdoaWNoIHRoZSBtb2RlbCB3aWxsIGJlIGNvbnN0cnVjdGVkLiBUaGUgcmVtYWluaW5nIDQwJSB3aWxsIGJlIHVzZWQgZm9yIHRlc3RpbmcgdGhlIG1vZGVsIGFuZCBwcm92aWRpbmcgcGVyZm9ybWFuY2UgaW5kaWNhdGlvbnMuIFRoZSByYW5kb21pemF0aW9uIHNlZWQgd2lsbCBiZSBzZXQgZm9yIHJlcHJvZHVjaWJpbGl0eSBvZiB0aGUgc2FtcGxlcy4NCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpDQp0cmFpbiA8LSBjcmVhdGVEYXRhUGFydGl0aW9uKGRhdGEkU3Vydml2ZWQsIHA9MC42LCBsaXN0PUZBTFNFKQ0KdHJhaW5pbmcgPC0gZGF0YVt0cmFpbixdDQp0ZXN0aW5nIDwtIGRhdGFbLXRyYWluLF0NCnBhbmRlcihoZWFkKHRyYWluaW5nKSwgY2FwdGlvbiA9ICJGaXJzdCA1IGVudHJpZXMgb2YgdGhlIHRyYWluaW5nIGRhdGEgc3Vic2V0IikNCmBgYA0KDQojIyBNdWx0aXBsZSBMb2dpc3RpYyBSZWdyZXNzaW9uDQoNCiMjIyBDYW5kaWRhdGUgTW9kZWwgIzENCg0KVGhlIGZpcnN0IGNhbmRpZGF0ZSBtb2RlbCBpcyBidWlsdCB1cG9uIHRoZSB2YXJpYWJsZXMgYWdlLCBjbGFzcywgYW5kIHNleC4gMTAtZm9sZCBjcm9zcyB2YWxpZGF0aW9uIHdpbGwgYmUgdXNlZCBpbiB0aGlzIG1vZGVscyB0cmFpbmluZy4gVGhlIGNvZWZmaWNpZW50cyB3aWxsIGJlIGRpc3BsYXllZCB3aXRoIGFuIGV4cG9uZW50aWFsIHRyYW5zZm9ybWF0aW9uLg0KDQpgYGB7cn0NCmN0cmwgPC0gdHJhaW5Db250cm9sKG1ldGhvZCA9ICJjdiIsIG51bWJlciA9IDEwLCBzYXZlUHJlZGljdGlvbnMgPSBUUlVFKQ0KbW9kZWwgPC0gdHJhaW4oU3Vydml2ZWQgfiBBZ2UgKyBQY2xhc3MgKyBTZXgsDQogICAgICAgICAgICAgICBkYXRhPXRyYWluaW5nLA0KICAgICAgICAgICAgICAgbWV0aG9kPSJnbG0iLA0KICAgICAgICAgICAgICAgZmFtaWx5PSJiaW5vbWlhbCIsDQogICAgICAgICAgICAgICB0ckNvbnRyb2w9Y3RybCwNCiAgICAgICAgICAgICAgIHR1bmVMZW5ndGggPSAxMCkNCnBhbmRlcihleHAoY29lZihtb2RlbCRmaW5hbE1vZGVsKSkpDQpgYGANCg0KIyMjIENhbmRpZGF0ZSBNb2RlbCAjMiANCg0KVGhlIHNlY29uZCBjYW5kaWRhdGUgbW9kZWwgaXMgYnVpbHQgdXBvbiB0aGUgdmFyaWFibGUgYWdlLiBUaGlzIGlzIGJlY2F1c2UgYWdlIGlzIGEgY29udGludW91cyB2YXJpYWJsZSB0aGF0IHdpbGwgaGF2ZSBtb3JlIHByZWRpY3RpdmUgcG93ZXIgdGhhbiB0aGUgY2F0ZWdvcmljYWwgdmFyaWFibGVzLiBUaGUgY29lZmZpY2llbnRzIGFyZSBhZ2FpbiBkaXNwbGF5ZWQgd2l0aCBleHBvbmVudGlhbCB0cmFuc2Zvcm1hdGlvbi4NCg0KYGBge3J9DQptb2RlbC5yZWR1Y2VkIDwtIHRyYWluKFN1cnZpdmVkIH4gQWdlLA0KICAgICAgICAgICAgICAgICAgICAgICBkYXRhPXRyYWluaW5nLA0KICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImdsbSIsDQogICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT0iYmlub21pYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICB0ckNvbnRyb2w9Y3RybCwNCiAgICAgICAgICAgICAgICAgICAgICAgdHVuZUxlbmd0aCA9IDEwKQ0KcGFuZGVyKGV4cChjb2VmKG1vZGVsLnJlZHVjZWQkZmluYWxNb2RlbCkpKQ0KYGBgDQoNCldlIHVzZSBhIGxpa2VsaWhvb2QgcmF0aW8gdGVzdCB0byBkZXRlcm1pbmUgaWYgdXNpbmcgdGhlIGxhcmdlciBjYW5kaWRhdGUgbW9kZWwgaXMgZGVtb25zdHJhYmx5IGltcHJvdmVkIHVwb24gdGhlIHNpbXBsZXIsIHNtYWxsZXIgbW9kZWwuIFAgXDwwLjAwMSwgYW5kIHdlIHRodXMgZ2FpbiBldmlkZW5jZSBpbiBmYXZvciBvZiB0aGUgbGFyZ2VyIG1vZGVsLg0KDQpgYGB7cn0NCm1vZGVsLmdsbSA8LSBnbG0oU3Vydml2ZWQgfiBBZ2UgKyBTZXggKyBQY2xhc3MsDQogICAgICAgICAgICAgICBkYXRhPXRyYWluaW5nLA0KICAgICAgICAgICAgICAgZmFtaWx5PSJiaW5vbWlhbCIpDQptb2RlbC5yZWR1Y2VkLmdsbSA8LSBnbG0oU3Vydml2ZWQgfiBBZ2UsDQogICAgICAgICAgICAgICAgICAgICBkYXRhPXRyYWluaW5nLA0KICAgICAgICAgICAgICAgICAgICAgZmFtaWx5PSJiaW5vbWlhbCIpDQphbm92YShtb2RlbC5nbG0sIG1vZGVsLnJlZHVjZWQuZ2xtLCB0ZXN0PSJDaGlzcSIpDQpgYGANCg0KIyMgVmFyaWFibGUgSW1wb3J0YW5jZQ0KDQpXZSBhc3Nlc3MgdGhlIGltcG9ydGFuY2Ugb2YgZWFjaCB2YXJpYWJsZSBpbiB0aGUgbXVsdGlwbGUgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbC4NCg0KYGBge3J9DQp2YXJJbXAobW9kZWwpDQpgYGANCg0KIyMgQ2xhc3NpZmljYXRpb24gUmF0ZQ0KDQpVc2luZyB0aGUgdGVzdGluZyBkYXRhIHN1YnNldCwgd2UgY2FuIGFzc2VzcyB0aGUgYWNjdXJhY3kgb2YgdGhlIG1vZGVsLiBUaGlzIG1vZGVsIGhhZCBhbiBhY2N1cmFjeSBvZiA4MS4wNSUuIFRoZSBtb2RlbCByZXN1bHRlZCBpbiBhbiBlcXVhbCBhbW91bnQgb2YgZmFsc2Utc3Vydml2YWxzIGFuZCBmYWxzZS1kZWF0aHMuIFRoZSBzZW5zaXRpdml0eSB3YXMgODQuMDIlIGFuZCBzcGVjaWZpY2l0eSB3YXMgNzYuNzIlLg0KDQpgYGB7cn0NCnByZWQgPSBwcmVkaWN0KG1vZGVsLCBuZXdkYXRhPXRlc3RpbmcpDQphY2N1cmFjeSA8LSB0YWJsZShwcmVkLCB0ZXN0aW5nWywiU3Vydml2ZWQiXSkNCmNvbmZ1c2lvbk1hdHJpeChkYXRhPXByZWQsIHRlc3RpbmckU3Vydml2ZWQpDQpgYGANCg==