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

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

  1. PassengerID: A unique identifier
  2. Survived: The survival status of the passenger (0 = No, 1 = Yes)
  3. Pclass: The passenger’s ticket class (1st, 2nd, or 3rd)
  4. Name: The passenger’s name
  5. Sex: The passenger’s sex
  6. Age: The passenger’s age in years
  7. sibSp: Number of siblings/spouse aboard
  8. Parch: Number of parents/children aboard
  9. Ticket: Passenger’s ticket number
  10. Fare: Passenger’s boarding fare in USD
  11. Cabin: The passenger’s cabin
  12. 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)

3 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

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

5 Predictive Logistic Regression

5.1 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
  Survived Pclass Age Sex SibSp Parch Fare
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

5.2 Multiple Logistic Regression

5.2.1 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)))
(Intercept) Age Pclass2 Pclass3 Sexmale
32.41 0.9697 0.2259 0.07259 0.1157

5.2.2 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)))
(Intercept) Age
0.8075 0.9943

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

5.3 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

5.4 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==