This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

library(dplyr)
library(rpart)
library(randomForest)
library(ROCR)
library(rpart.plot)
library(dummies)
library(caret)
library(ggplot2)
library(pROC)
library(DT)
str(telcod)
'data.frame':   7043 obs. of  21 variables:
 $ customerID      : Factor w/ 7043 levels "0002-ORFBO","0003-MKNFE",..: 5376 3963 2565 5536 6512 6552 1003 4771 5605 4535 ...
 $ gender          : Factor w/ 2 levels "Female","Male": 1 2 2 2 1 1 2 1 1 2 ...
 $ SeniorCitizen   : int  0 0 0 0 0 0 0 0 0 0 ...
 $ Partner         : Factor w/ 2 levels "No","Yes": 2 1 1 1 1 1 1 1 2 1 ...
 $ Dependents      : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 2 1 1 2 ...
 $ tenure          : int  1 34 2 45 2 8 22 10 28 62 ...
 $ PhoneService    : Factor w/ 2 levels "No","Yes": 1 2 2 1 2 2 2 1 2 2 ...
 $ MultipleLines   : Factor w/ 3 levels "No","No phone service",..: 2 1 1 2 1 3 3 2 3 1 ...
 $ InternetService : Factor w/ 3 levels "DSL","Fiber optic",..: 1 1 1 1 2 2 2 1 2 1 ...
 $ OnlineSecurity  : Factor w/ 3 levels "No","No internet service",..: 1 3 3 3 1 1 1 3 1 3 ...
 $ OnlineBackup    : Factor w/ 3 levels "No","No internet service",..: 3 1 3 1 1 1 3 1 1 3 ...
 $ DeviceProtection: Factor w/ 3 levels "No","No internet service",..: 1 3 1 3 1 3 1 1 3 1 ...
 $ TechSupport     : Factor w/ 3 levels "No","No internet service",..: 1 1 1 3 1 1 1 1 3 1 ...
 $ StreamingTV     : Factor w/ 3 levels "No","No internet service",..: 1 1 1 1 1 3 3 1 3 1 ...
 $ StreamingMovies : Factor w/ 3 levels "No","No internet service",..: 1 1 1 1 1 3 1 1 3 1 ...
 $ Contract        : Factor w/ 3 levels "Month-to-month",..: 1 2 1 2 1 1 1 1 1 2 ...
 $ PaperlessBilling: Factor w/ 2 levels "No","Yes": 2 1 2 1 2 2 2 1 2 1 ...
 $ PaymentMethod   : Factor w/ 4 levels "Bank transfer (automatic)",..: 3 4 4 1 3 3 2 4 3 1 ...
 $ MonthlyCharges  : num  29.9 57 53.9 42.3 70.7 ...
 $ TotalCharges    : num  29.9 1889.5 108.2 1840.8 151.7 ...
 $ Churn           : Factor w/ 2 levels "No","Yes": 1 1 2 1 2 2 1 1 2 1 ...
sum(is.na(telcod_copy))
[1] 11
# Create a Training Control Object that stores information about how we want to develop(train) the models
# We will use 10 fold cross validation to train and evaluate model
TrainingParameters <- trainControl(method = "cv", number =10)
# train model

#############c5.0##################
DecTreeModel <- train(Churn ~ ., data = trainData,
                      method = "C5.0",
                      trControl= TrainingParameters,
                      na.action = na.omit
                     )
DTcm
Confusion Matrix and Statistics

          Reference
Prediction   No  Yes
       No  1397  275
       Yes  151  285
                                          
               Accuracy : 0.7979          
                 95% CI : (0.7801, 0.8149)
    No Information Rate : 0.7343          
    P-Value [Acc > NIR] : 6.398e-12       
                                          
                  Kappa : 0.4427          
 Mcnemar's Test P-Value : 2.532e-09       
                                          
            Sensitivity : 0.9025          
            Specificity : 0.5089          
         Pos Pred Value : 0.8355          
         Neg Pred Value : 0.6537          
             Prevalence : 0.7343          
         Detection Rate : 0.6627          
   Detection Prevalence : 0.7932          
      Balanced Accuracy : 0.7057          
                                          
       'Positive' Class : No              
                                          

##############Ensemble#################
library(ggplot2)
library(kernlab)
library(caret)
library(plyr)
library(dplyr)
library(C50)
library(kernlab)
library(e1071)
library(caretEnsemble)

econtrol <- trainControl(method="cv", number=10, summaryFunction = twoClassSummary, savePredictions=TRUE, classProbs=TRUE)
econtrol

Corrmodels <- caretList(Churn ~., data=trainData,
                     methodList=c("svmPoly", "nnet", "C5.0", "naive_bayes"),
                     trControl = econtrol
)

Corresults <- resamples(Corrmodels)
dotplot(Corresults)
?resamples
mcr <-modelCor(Corresults)
mcr
splom(mcr)
smallmodels <- c(Corrmodels$C5.0, Corrmodels$nnet)
?caretEnsemble
ensmodel <- caretEnsemble(smallmodels,
                          metric = "Accuracy",
                          trControl = trainControl(method="cv", number = 10, classProbs = TRUE)
)
enstackpredictions <-predict(ensmodel,testData, na.action = na.omit)
cmPIMA <-confusionMatrix(enstackpredictions, testData$Churn, mode="everything")
cmPIMA
cmPIMA

#Predict
enstackpredictions <-predict(enstackmodel, testData, na.action = na.omit)

# Create confusion matrix
cmPIMA <-confusionMatrix(enstackpredictions, testData$Churn)
cmPIMA

cm_rf
Confusion Matrix and Statistics

          Reference
Prediction   No  Yes
       No  1467  352
       Yes   81  208
                                          
               Accuracy : 0.7946          
                 95% CI : (0.7767, 0.8117)
    No Information Rate : 0.7343          
    P-Value [Acc > NIR] : 7.528e-11       
                                          
                  Kappa : 0.3774          
 Mcnemar's Test P-Value : < 2.2e-16       
                                          
            Sensitivity : 0.9477          
            Specificity : 0.3714          
         Pos Pred Value : 0.8065          
         Neg Pred Value : 0.7197          
             Prevalence : 0.7343          
         Detection Rate : 0.6959          
   Detection Prevalence : 0.8629          
      Balanced Accuracy : 0.6596          
                                          
       'Positive' Class : No              
                                          
cmSVMup
Confusion Matrix and Statistics

          Reference
Prediction   No  Yes
       No  1102  130
       Yes  446  430
                                          
               Accuracy : 0.7268          
                 95% CI : (0.7072, 0.7457)
    No Information Rate : 0.7343          
    P-Value [Acc > NIR] : 0.7925          
                                          
                  Kappa : 0.4065          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.7119          
            Specificity : 0.7679          
         Pos Pred Value : 0.8945          
         Neg Pred Value : 0.4909          
             Prevalence : 0.7343          
         Detection Rate : 0.5228          
   Detection Prevalence : 0.5844          
      Balanced Accuracy : 0.7399          
                                          
       'Positive' Class : No              
                                          
GBTreeModel <- train(Churn ~ ., data = trainData,
                      method = "gbm",
                      trControl= TrainingParameters,
                      na.action = na.omit
                     )

GBcm
Confusion Matrix and Statistics

          Reference
Prediction   No  Yes
       No  1414  287
       Yes  134  273
                                          
               Accuracy : 0.8003          
                 95% CI : (0.7826, 0.8172)
    No Information Rate : 0.7343          
    P-Value [Acc > NIR] : 1.009e-12       
                                          
                  Kappa : 0.4392          
 Mcnemar's Test P-Value : 1.282e-13       
                                          
            Sensitivity : 0.9134          
            Specificity : 0.4875          
         Pos Pred Value : 0.8313          
         Neg Pred Value : 0.6708          
             Prevalence : 0.7343          
         Detection Rate : 0.6708          
   Detection Prevalence : 0.8069          
      Balanced Accuracy : 0.7005          
                                          
       'Positive' Class : No              
                                          
CMList
[[1]]
Confusion Matrix and Statistics

          Reference
Prediction   No  Yes
       No  1397  275
       Yes  151  285
                                          
               Accuracy : 0.7979          
                 95% CI : (0.7801, 0.8149)
    No Information Rate : 0.7343          
    P-Value [Acc > NIR] : 6.398e-12       
                                          
                  Kappa : 0.4427          
 Mcnemar's Test P-Value : 2.532e-09       
                                          
            Sensitivity : 0.9025          
            Specificity : 0.5089          
         Pos Pred Value : 0.8355          
         Neg Pred Value : 0.6537          
             Prevalence : 0.7343          
         Detection Rate : 0.6627          
   Detection Prevalence : 0.7932          
      Balanced Accuracy : 0.7057          
                                          
       'Positive' Class : No              
                                          

[[2]]
Confusion Matrix and Statistics

          Reference
Prediction  No Yes
       No  908  68
       Yes 640 492
                                          
               Accuracy : 0.6641          
                 95% CI : (0.6435, 0.6843)
    No Information Rate : 0.7343          
    P-Value [Acc > NIR] : 1               
                                          
                  Kappa : 0.3508          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.5866          
            Specificity : 0.8786          
         Pos Pred Value : 0.9303          
         Neg Pred Value : 0.4346          
             Prevalence : 0.7343          
         Detection Rate : 0.4307          
   Detection Prevalence : 0.4630          
      Balanced Accuracy : 0.7326          
                                          
       'Positive' Class : No              
                                          

[[3]]
Confusion Matrix and Statistics

          Reference
Prediction   No  Yes
       No  1362  241
       Yes  186  319
                                          
               Accuracy : 0.7974          
                 95% CI : (0.7796, 0.8144)
    No Information Rate : 0.7343          
    P-Value [Acc > NIR] : 9.178e-12       
                                          
                  Kappa : 0.464           
 Mcnemar's Test P-Value : 0.008969        
                                          
            Sensitivity : 0.8798          
            Specificity : 0.5696          
         Pos Pred Value : 0.8497          
         Neg Pred Value : 0.6317          
             Prevalence : 0.7343          
         Detection Rate : 0.6461          
   Detection Prevalence : 0.7604          
      Balanced Accuracy : 0.7247          
                                          
       'Positive' Class : No              
                                          

[[4]]
Confusion Matrix and Statistics

          Reference
Prediction   No  Yes
       No  1467  352
       Yes   81  208
                                          
               Accuracy : 0.7946          
                 95% CI : (0.7767, 0.8117)
    No Information Rate : 0.7343          
    P-Value [Acc > NIR] : 7.528e-11       
                                          
                  Kappa : 0.3774          
 Mcnemar's Test P-Value : < 2.2e-16       
                                          
            Sensitivity : 0.9477          
            Specificity : 0.3714          
         Pos Pred Value : 0.8065          
         Neg Pred Value : 0.7197          
             Prevalence : 0.7343          
         Detection Rate : 0.6959          
   Detection Prevalence : 0.8629          
      Balanced Accuracy : 0.6596          
                                          
       'Positive' Class : No              
                                          

[[5]]
Confusion Matrix and Statistics

          Reference
Prediction   No  Yes
       No  1102  130
       Yes  446  430
                                          
               Accuracy : 0.7268          
                 95% CI : (0.7072, 0.7457)
    No Information Rate : 0.7343          
    P-Value [Acc > NIR] : 0.7925          
                                          
                  Kappa : 0.4065          
 Mcnemar's Test P-Value : <2e-16          
                                          
            Sensitivity : 0.7119          
            Specificity : 0.7679          
         Pos Pred Value : 0.8945          
         Neg Pred Value : 0.4909          
             Prevalence : 0.7343          
         Detection Rate : 0.5228          
   Detection Prevalence : 0.5844          
      Balanced Accuracy : 0.7399          
                                          
       'Positive' Class : No              
                                          

[[6]]
Confusion Matrix and Statistics

          Reference
Prediction   No  Yes
       No  1414  287
       Yes  134  273
                                          
               Accuracy : 0.8003          
                 95% CI : (0.7826, 0.8172)
    No Information Rate : 0.7343          
    P-Value [Acc > NIR] : 1.009e-12       
                                          
                  Kappa : 0.4392          
 Mcnemar's Test P-Value : 1.282e-13       
                                          
            Sensitivity : 0.9134          
            Specificity : 0.4875          
         Pos Pred Value : 0.8313          
         Neg Pred Value : 0.6708          
             Prevalence : 0.7343          
         Detection Rate : 0.6708          
   Detection Prevalence : 0.8069          
      Balanced Accuracy : 0.7005          
                                          
       'Positive' Class : No              
                                          

[[7]]
Confusion Matrix and Statistics

          Reference
Prediction   No  Yes
       No  1395  294
       Yes  153  266
                                          
               Accuracy : 0.788           
                 95% CI : (0.7699, 0.8052)
    No Information Rate : 0.7343          
    P-Value [Acc > NIR] : 6.868e-09       
                                          
                  Kappa : 0.409           
 Mcnemar's Test P-Value : 3.549e-11       
                                          
            Sensitivity : 0.9012          
            Specificity : 0.4750          
         Pos Pred Value : 0.8259          
         Neg Pred Value : 0.6348          
             Prevalence : 0.7343          
         Detection Rate : 0.6618          
   Detection Prevalence : 0.8012          
      Balanced Accuracy : 0.6881          
                                          
       'Positive' Class : No              
                                          

[[8]]
Confusion Matrix and Statistics

          Reference
Prediction   No  Yes
       No  1419  290
       Yes  129  270
                                          
               Accuracy : 0.8012          
                 95% CI : (0.7835, 0.8181)
    No Information Rate : 0.7343          
    P-Value [Acc > NIR] : 4.720e-13       
                                          
                  Kappa : 0.4391          
 Mcnemar's Test P-Value : 5.431e-15       
                                          
            Sensitivity : 0.9167          
            Specificity : 0.4821          
         Pos Pred Value : 0.8303          
         Neg Pred Value : 0.6767          
             Prevalence : 0.7343          
         Detection Rate : 0.6731          
   Detection Prevalence : 0.8107          
      Balanced Accuracy : 0.6994          
                                          
       'Positive' Class : No              
                                          
##In this project we aimed to build a model to predict whether the customer will churn.  According to our problem statement, NAÏVE BAYES yields SPECIFICITY of 87%, better than any other model and hence we select it as a final model.

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgd29yZF9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNClRoaXMgaXMgYW4gW1IgTWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pIE5vdGVib29rLiBXaGVuIHlvdSBleGVjdXRlIGNvZGUgd2l0aGluIHRoZSBub3RlYm9vaywgdGhlIHJlc3VsdHMgYXBwZWFyIGJlbmVhdGggdGhlIGNvZGUuIA0KDQpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ3RybCtTaGlmdCtFbnRlciouIA0KDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHJwYXJ0KQ0KbGlicmFyeShyYW5kb21Gb3Jlc3QpDQpsaWJyYXJ5KFJPQ1IpDQpsaWJyYXJ5KHJwYXJ0LnBsb3QpDQpsaWJyYXJ5KGR1bW1pZXMpDQpsaWJyYXJ5KGNhcmV0KQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShwUk9DKQ0KbGlicmFyeShEVCkNCmBgYA0KDQpgYGB7cn0NCiNMb2FkIHRoZSBkYXRhIHNldA0KdGVsY29kIDwtcmVhZC5jc3YoIkU6L01TL0RBVEEgTUlOSU5HL0Fzc2lnbm1lbnQ0L1dBX0ZuLVVzZUNfLVRlbGNvLUN1c3RvbWVyLUNodXJuLmNzdiIpDQpzdHIodGVsY29kKQ0KYGBgDQoNCmBgYHtyfQ0KI2NvcHkgdGhlIGRhdGEgd2l0aG91dCB0aGUgY2xhc3MgdmFyaWFibGUsQ2h1cm4gDQp0ZWxjb2RfY29weSA8LSB0ZWxjb2RbLC0xXQ0KI2ZpbmQgdGhlIGVudHJpZXMgaW4gb3VyIGRhdGEgc2V0IHdoaWNoIGFyZSBlbXB0eSBvciBoYXZlIE5BIHZhbHVlcw0Kc3VtKGlzLm5hKHRlbGNvZF9jb3B5KSkNCmBgYA0KYGBge3J9DQojVGhlIG51bWJlciBvZiBOQSdzIGFzIGNvbXBhcmVkIHRvIHRoZSB3aG9sZSBkYXRhc2V0IGlzIHJlbGF0aXZlbHkgbGVzcyBhbmQgaGVuY2Ugd2Ugd291bGQgZHJvcCB0aGVzZSAxMSB2YWx1ZXMuDQojZGF0YSBjbGVhbmluZw0KdGVsY28gPC0gdGVsY29kX2NvcHlbY29tcGxldGUuY2FzZXModGVsY29kX2NvcHkpLF0NCmBgYA0KYGBge3J9DQojRGl2aWRlIHRoZSBkYXRhIHNldCBpbnRvIHRyYWluIGFuZCB0ZXN0DQp0cmFpbmluZ0RhdGEgPC0gY3JlYXRlRGF0YVBhcnRpdGlvbih5ID0gdGVsY28kQ2h1cm4sIHAgPSAwLjcsIGxpc3QgPSBGQUxTRSkNCnRyYWluRGF0YSA8LSB0ZWxjb1t0cmFpbmluZ0RhdGEsIF0NCiMgRXZlcnl0aGluZyBlbHNlIG5vdCBpbiB0cmFpbmluZyBpcyB0ZXN0IGRhdGEuIE5vdGUgdGhlIC0gKG1pbnVzKXNpZ24NCnRlc3REYXRhIDwtIHRlbGNvWy10cmFpbmluZ0RhdGEsIF0NCg0KYGBgDQpgYGB7cn0NCiMgQ3JlYXRlIGEgVHJhaW5pbmcgQ29udHJvbCBPYmplY3QgdGhhdCBzdG9yZXMgaW5mb3JtYXRpb24gYWJvdXQgaG93IHdlIHdhbnQgdG8gZGV2ZWxvcCh0cmFpbikgdGhlIG1vZGVscw0KIyBXZSB3aWxsIHVzZSAxMCBmb2xkIGNyb3NzIHZhbGlkYXRpb24gdG8gdHJhaW4gYW5kIGV2YWx1YXRlIG1vZGVsDQpUcmFpbmluZ1BhcmFtZXRlcnMgPC0gdHJhaW5Db250cm9sKG1ldGhvZCA9ICJjdiIsIG51bWJlciA9MTApDQojIHRyYWluIG1vZGVsDQoNCiMjIyMjIyMjIyMjIyNjNS4wIyMjIyMjIyMjIyMjIyMjIyMjDQpEZWNUcmVlTW9kZWwgPC0gdHJhaW4oQ2h1cm4gfiAuLCBkYXRhID0gdHJhaW5EYXRhLA0KICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJDNS4wIiwNCiAgICAgICAgICAgICAgICAgICAgICB0ckNvbnRyb2w9IFRyYWluaW5nUGFyYW1ldGVycywNCiAgICAgICAgICAgICAgICAgICAgICBuYS5hY3Rpb24gPSBuYS5vbWl0DQogICAgICAgICAgICAgICAgICAgICApDQpgYGANCmBgYHtyfQ0KRGVjVHJlZU1vZGVsJHJlc3VsdHMNCiMgUGxvdCBwZXJmb3JtYW5jZQ0KcGxvdC50cmFpbihEZWNUcmVlTW9kZWwpDQpnZ3Bsb3QoRGVjVHJlZU1vZGVsKQ0KI2Jlc3QgbW1vZGVsIGlzIHN0b3JlZCBpbiBmaW5hbE1vZGVsIA0KcGxvdChEZWNUcmVlTW9kZWwkZmluYWxNb2RlbCR0cmVlKQ0Kc3VtbWFyeShEZWNUcmVlTW9kZWwpDQpgYGANCmBgYHtyfQ0KI2NyZWF0ZSBwcmVkaWN0aW9ucw0KRFRQcmVkaWN0aW9ucyA8LXByZWRpY3QoRGVjVHJlZU1vZGVsLCB0ZXN0RGF0YSwgbmEuYWN0aW9uID0gbmEucGFzcykNCiMgU2VlIHByZWRpY3Rpb25zDQpEVFByZWRpY3Rpb25zDQojIENyZWF0ZSBjb25mdXNpb24gbWF0cml4DQo/Y29uZnVzaW9uTWF0cml4DQpEVGNtPC1jb25mdXNpb25NYXRyaXgoRFRQcmVkaWN0aW9ucywgdGVzdERhdGEkQ2h1cm4pDQpEVGNtJG92ZXJhbGwNCkRUY20kYnlDbGFzcw0KRFRjbQ0KYGBgDQpgYGB7cn0NCiMjIyMjIyMjIyMjI05haXZlIEJheWVzIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIENyZWF0ZSBuZXcgbW9kZWwgdXNpbmcgbmFpdmVfYmF5ZXMgYWxnb3JpdGhtLHdpdGggc2FtZSBkYXRhc2V0IGFuZCB0cmFpbmluZyBwYXJhbWV0ZXJzDQpsaWJyYXJ5KGtsYVIpDQpOYWl2ZVRyZWVNb2RlbCA8LSB0cmFpbihDaHVybiB+IC4sIGRhdGEgPSB0cmFpbkRhdGEsDQogICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gIm5iIiwNCiAgICAgICAgICAgICAgICAgICAgICB0ckNvbnRyb2w9IFRyYWluaW5nUGFyYW1ldGVycw0KICAgICAgICAgICAgICAgICAgICAgKQ0KI0xldHMgdGFrZSBhIGxvb2sgYXQgcmVzdWx0cw0KTmFpdmVUcmVlTW9kZWwNCnBsb3QudHJhaW4oTmFpdmVUcmVlTW9kZWwpDQpOQlByZWRpY3Rpb25zIDwtcHJlZGljdChOYWl2ZVRyZWVNb2RlbCwgdGVzdERhdGEpDQpwbG90KHZhckltcChOYWl2ZVRyZWVNb2RlbCkpDQojIFByaW50IGNvbmZ1c2lvbiBtYXRyaXggYW5kIHJlc3VsdHMNCm5haXZlY20gPC1jb25mdXNpb25NYXRyaXgoTkJQcmVkaWN0aW9ucywgdGVzdERhdGEkQ2h1cm4pDQpuYWl2ZWNtJG92ZXJhbGwNCm5haXZlY20kYnlDbGFzcw0KbmFpdmVjbQ0KYGBgDQpgYGB7cn0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjU1ZNLVBPTFkjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCiMgdHJhaW4gbW9kZWwgd2l0aCBTVk0NCmxpYnJhcnkocGx5cikNCmxpYnJhcnkoY2FyZXQpDQpsaWJyYXJ5KG1sYmVuY2gpDQpsaWJyYXJ5KGZvcmVpZ24pDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KHJlc2hhcGUpDQpsaWJyYXJ5KGUxMDcxKQ0KbGlicmFyeShrbGFSKQ0KDQpQb2x5U1ZNb2RlbCA8LSB0cmFpbihDaHVybiB+IC4sIGRhdGEgPSB0cmFpbkRhdGEsDQogICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSAic3ZtUG9seSIsI3BvbHlub21pYWwga2VybmVsDQogICAgICAgICAgICAgICAgICAgICB0ckNvbnRyb2w9IFRyYWluaW5nUGFyYW1ldGVycw0KICAgICAgICAgICAgICAgICAgICAgKQ0KZ2dwbG90KFBvbHlTVk1vZGVsKQ0KU1ZNUHJlZGljdGlvbnMgPC1wcmVkaWN0KFBvbHlTVk1vZGVsLCB0ZXN0RGF0YSkNCiMgU2VlIHByZWRpY3Rpb25zDQpTVk1QcmVkaWN0aW9ucw0KIyBDcmVhdGUgY29uZnVzaW9uIG1hdHJpeA0KY21TVk0gPC1jb25mdXNpb25NYXRyaXgoU1ZNUHJlZGljdGlvbnMsIHRlc3REYXRhJENodXJuKQ0KY21TVk0kb3ZlcmFsbA0KY21TVk0kYnlDbGFzcw0KY21TVk0NCmBgYA0KYGBge3J9DQojIHRyYWluIG1vZGVsIHdpdGggUENBDQpEZWNUcmVlTW9kZWwyIDwtIHRyYWluKENodXJuIH4gLiwgZGF0YSA9IHRyYWluRGF0YSwgDQogICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gIkM1LjAiLA0KICAgICAgICAgICAgICAgICAgICAgIHRyQ29udHJvbD0gVHJhaW5pbmdQYXJhbWV0ZXJzLA0KICAgICAgICAgICAgICAgICAgICAgIHByZVByb2Nlc3MgPSBjKCJjb3JyIiwgIm56diIsICJwY2EiKSwNCiAgICAgICAgICAgICAgICAgICAgICBuYS5hY3Rpb24gPSBuYS5vbWl0DQopDQpwbG90KERlY1RyZWVNb2RlbDIpDQojcHJlZGljdA0KRFRQcmVkaWN0aW9uczIgPC1wcmVkaWN0KERlY1RyZWVNb2RlbDIsIHRlc3REYXRhLCBuYS5hY3Rpb24gPSBuYS5wYXNzKQ0KIyBTZWUgcHJlZGljdGlvbnMNCnBsb3QoRFRQcmVkaWN0aW9uczIpDQojIENyZWF0ZSBjb25mdXNpb24gbWF0cml4DQpjbTIgPC1jb25mdXNpb25NYXRyaXgoRFRQcmVkaWN0aW9uczIsIHRlc3REYXRhJENodXJuKQ0KY20yDQpjbTIkb3ZlcmFsbA0KY20yJGJ5Q2xhc3MNCmBgYA0KYGBge3J9DQojIyMjIyMjIyMjIyMjI0Vuc2VtYmxlIyMjIyMjIyMjIyMjIyMjIyMNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoa2VybmxhYikNCmxpYnJhcnkoY2FyZXQpDQpsaWJyYXJ5KHBseXIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShDNTApDQpsaWJyYXJ5KGtlcm5sYWIpDQpsaWJyYXJ5KGUxMDcxKQ0KbGlicmFyeShjYXJldEVuc2VtYmxlKQ0KDQplY29udHJvbCA8LSB0cmFpbkNvbnRyb2wobWV0aG9kPSJjdiIsIG51bWJlcj0xMCwgc3VtbWFyeUZ1bmN0aW9uID0gdHdvQ2xhc3NTdW1tYXJ5LCBzYXZlUHJlZGljdGlvbnM9VFJVRSwgY2xhc3NQcm9icz1UUlVFKQ0KZWNvbnRyb2wNCg0KQ29ycm1vZGVscyA8LSBjYXJldExpc3QoQ2h1cm4gfi4sIGRhdGE9dHJhaW5EYXRhLA0KICAgICAgICAgICAgICAgICAgICAgbWV0aG9kTGlzdD1jKCJzdm1Qb2x5IiwgIm5uZXQiLCAiQzUuMCIsICJuYWl2ZV9iYXllcyIpLA0KICAgICAgICAgICAgICAgICAgICAgdHJDb250cm9sID0gZWNvbnRyb2wNCikNCg0KQ29ycmVzdWx0cyA8LSByZXNhbXBsZXMoQ29ycm1vZGVscykNCmRvdHBsb3QoQ29ycmVzdWx0cykNCj9yZXNhbXBsZXMNCm1jciA8LW1vZGVsQ29yKENvcnJlc3VsdHMpDQptY3INCnNwbG9tKG1jcikNCnNtYWxsbW9kZWxzIDwtIGMoQ29ycm1vZGVscyRDNS4wLCBDb3JybW9kZWxzJG5uZXQpDQo/Y2FyZXRFbnNlbWJsZQ0KZW5zbW9kZWwgPC0gY2FyZXRFbnNlbWJsZShzbWFsbG1vZGVscywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0cmljID0gIkFjY3VyYWN5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgdHJDb250cm9sID0gdHJhaW5Db250cm9sKG1ldGhvZD0iY3YiLCBudW1iZXIgPSAxMCwgY2xhc3NQcm9icyA9IFRSVUUpDQopDQplbnN0YWNrcHJlZGljdGlvbnMgPC1wcmVkaWN0KGVuc21vZGVsLHRlc3REYXRhLCBuYS5hY3Rpb24gPSBuYS5vbWl0KQ0KY21QSU1BIDwtY29uZnVzaW9uTWF0cml4KGVuc3RhY2twcmVkaWN0aW9ucywgdGVzdERhdGEkQ2h1cm4sIG1vZGU9ImV2ZXJ5dGhpbmciKQ0KY21QSU1BDQpjbVBJTUENCg0KI1ByZWRpY3QNCmVuc3RhY2twcmVkaWN0aW9ucyA8LXByZWRpY3QoZW5zdGFja21vZGVsLCB0ZXN0RGF0YSwgbmEuYWN0aW9uID0gbmEub21pdCkNCg0KIyBDcmVhdGUgY29uZnVzaW9uIG1hdHJpeA0KY21QSU1BIDwtY29uZnVzaW9uTWF0cml4KGVuc3RhY2twcmVkaWN0aW9ucywgdGVzdERhdGEkQ2h1cm4pDQpjbVBJTUENCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoInJwYXJ0LnBsb3QiKQ0KDQp0cmVlID0gcnBhcnQoQ2h1cm4gfi4sIGRhdGEgPSB0cmFpbkRhdGEsIG1ldGhvZD0iY2xhc3MiKQ0KcnBhcnQucGxvdCh0cmVlKQ0KYGBgDQpgYGB7cn0NCnRjX3JmIDwtIHRyYWluQ29udHJvbChtZXRob2QgPSAicmVwZWF0ZWRjdiIscmVwZWF0cyA9IDIsbnVtYmVyID0gMywgc2VhcmNoID0gInJhbmRvbSIpDQpyZl90cmFpbiA8LSB0cmFpbihDaHVybiB+IC4sIGRhdGEgPSB0cmFpbkRhdGEsIG1ldGhvZCA9ICJyZiIsIHRyYWluQ29udHJvbCA9IHRjX3JmKSAjI1RpbWUgY29uc3VtaW5nDQpwbG90KHZhckltcChyZl90cmFpbiwgc2NhbGUgPSBGKSkNCmBgYA0KYGBge3J9DQpwcmVkaWN0X3JmdHJhaW4gPC0gcHJlZGljdChyZl90cmFpbiwgdGVzdERhdGEpDQpjbV9yZiA8LSBjb25mdXNpb25NYXRyaXgocHJlZGljdF9yZnRyYWluLCB0ZXN0RGF0YSRDaHVybikNCmNtX3JmDQpgYGANCmBgYHtyfQ0KI0luY3JlYXNlIHRoZSBwZXJmb3JtYW5jZSBvZiB0aGUgU1ZNIGJ5IGluY3JlYXNpbmcgdGhlIHNhbXBsZXMgLSB1cFNhbXBsaW5nDQpUcmFpbmluZ1BhcmFtZXRlcnNVcCA8LSB0cmFpbkNvbnRyb2wobWV0aG9kID0gImN2IiwgbnVtYmVyID0gMTAsc2FtcGxpbmcgPSAidXAiKQ0KDQojIHRyYWluIG1vZGVsIHdpdGggU1ZNICB1cCBTYW1wbGluZw0KU1ZNb2RlbHVwIDwtIHRyYWluKENodXJuIH4gLiwgZGF0YSA9IHRyYWluRGF0YSwNCiAgICAgICAgICAgICAgICAgbWV0aG9kID0gInN2bVBvbHkiLA0KICAgICAgICAgICAgICAgICB0ckNvbnRyb2w9IFRyYWluaW5nUGFyYW1ldGVyc1VwLA0KICAgICAgICAgICAgICAgICBwcmVQcm9jZXNzID0gYygiY2VudGVyIiwic2NhbGUiKSwNCiAgICAgICAgICAgICAgICAgdHVuZUdyaWQgPSBkYXRhLmZyYW1lKGRlZ3JlZSA9IGMoMTo0KSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlID0gMSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEMgPSAxICNtYXJnaW4gbGluZSh0cmFpbmluZyBhY2N1cmFjeSBjaGFuZ2VzIGJhc2VkIG9uIHRoZSBjIHZhbHVlKQ0KICAgICAgICAgICAgICAgICApLA0KICAgICAgICAgICAgICAgICBuYS5hY3Rpb24gPSBuYS5vbWl0DQogICAgICAgICAgICAgICAgIA0KKQ0KDQpwbG90KFNWTW9kZWx1cCkNCiNjcmVhdGUgcHJlZGljdGlvbnMNClNWTVByZWRpY3Rpb25zdXAgPC1wcmVkaWN0KFNWTW9kZWx1cCwgdGVzdERhdGEpDQojIFNlZSBwcmVkaWN0aW9ucw0KcGxvdChTVk1QcmVkaWN0aW9uc3VwKQ0KIyBDcmVhdGUgY29uZnVzaW9uIG1hdHJpeA0KY21TVk11cCA8LWNvbmZ1c2lvbk1hdHJpeChTVk1QcmVkaWN0aW9uc3VwLCB0ZXN0RGF0YSRDaHVybikNCmNtU1ZNdXAkb3ZlcmFsbA0KY21TVk11cCRieUNsYXNzDQpjbVNWTXVwDQoNCmBgYA0KYGBge3J9DQpHQlRyZWVNb2RlbCA8LSB0cmFpbihDaHVybiB+IC4sIGRhdGEgPSB0cmFpbkRhdGEsDQogICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gImdibSIsDQogICAgICAgICAgICAgICAgICAgICAgdHJDb250cm9sPSBUcmFpbmluZ1BhcmFtZXRlcnMsDQogICAgICAgICAgICAgICAgICAgICAgbmEuYWN0aW9uID0gbmEub21pdA0KICAgICAgICAgICAgICAgICAgICAgKQ0KYGBgDQpgYGB7cn0NCkdCVHJlZU1vZGVsJHJlc3VsdHMNCiMgUGxvdCBwZXJmb3JtYW5jZQ0KcGxvdC50cmFpbihHQlRyZWVNb2RlbCkNCmdncGxvdChHQlRyZWVNb2RlbCkNCiNiZXN0IG1tb2RlbCBpcyBzdG9yZWQgaW4gZmluYWxNb2RlbCANCnBsb3QoR0JUcmVlTW9kZWwkZmluYWxNb2RlbCR0cmVlKQ0Kc3VtbWFyeShHQlRyZWVNb2RlbCkNCmBgYA0KYGBge3J9DQojY3JlYXRlIHByZWRpY3Rpb25zDQpsaWJyYXJ5KCJST0NSIikNCkdCRFRQcmVkaWN0aW9ucyA8LXByZWRpY3QoR0JUcmVlTW9kZWwsIHRlc3REYXRhLCBuYS5hY3Rpb24gPSBuYS5wYXNzKQ0KIyBDcmVhdGUgY29uZnVzaW9uIG1hdHJpeA0KP2NvbmZ1c2lvbk1hdHJpeA0KR0JjbTwtY29uZnVzaW9uTWF0cml4KEdCRFRQcmVkaWN0aW9ucywgdGVzdERhdGEkQ2h1cm4pDQpHQmNtJG92ZXJhbGwNCkdCY20kYnlDbGFzcw0KR0JjbQ0KYGBgDQpgYGB7cn0NCkNNTGlzdCA8LSBsaXN0KERUY20sbmFpdmVjbSxjbVBJTUEsY21fcmYsY21TVk11cCxHQmNtLGNtMixjbVNWTSkNCkNNTGlzdA0KYGBgDQpgYGB7cn0NCiMjSW4gdGhpcyBwcm9qZWN0IHdlIGFpbWVkIHRvIGJ1aWxkIGEgbW9kZWwgdG8gcHJlZGljdCB3aGV0aGVyIHRoZSBjdXN0b21lciB3aWxsIGNodXJuLiAgQWNjb3JkaW5nIHRvIG91ciBwcm9ibGVtIHN0YXRlbWVudCwgTkHPVkUgQkFZRVMgeWllbGRzIFNQRUNJRklDSVRZIG9mIDg3JSwgYmV0dGVyIHRoYW4gYW55IG90aGVyIG1vZGVsIGFuZCBoZW5jZSB3ZSBzZWxlY3QgaXQgYXMgYSBmaW5hbCBtb2RlbC4NCmBgYA0KDQoNCkFkZCBhIG5ldyBjaHVuayBieSBjbGlja2luZyB0aGUgKkluc2VydCBDaHVuayogYnV0dG9uIG9uIHRoZSB0b29sYmFyIG9yIGJ5IHByZXNzaW5nICpDdHJsK0FsdCtJKi4NCg0KV2hlbiB5b3Ugc2F2ZSB0aGUgbm90ZWJvb2ssIGFuIEhUTUwgZmlsZSBjb250YWluaW5nIHRoZSBjb2RlIGFuZCBvdXRwdXQgd2lsbCBiZSBzYXZlZCBhbG9uZ3NpZGUgaXQgKGNsaWNrIHRoZSAqUHJldmlldyogYnV0dG9uIG9yIHByZXNzICpDdHJsK1NoaWZ0K0sqIHRvIHByZXZpZXcgdGhlIEhUTUwgZmlsZSkuDQoNClRoZSBwcmV2aWV3IHNob3dzIHlvdSBhIHJlbmRlcmVkIEhUTUwgY29weSBvZiB0aGUgY29udGVudHMgb2YgdGhlIGVkaXRvci4gQ29uc2VxdWVudGx5LCB1bmxpa2UgKktuaXQqLCAqUHJldmlldyogZG9lcyBub3QgcnVuIGFueSBSIGNvZGUgY2h1bmtzLiBJbnN0ZWFkLCB0aGUgb3V0cHV0IG9mIHRoZSBjaHVuayB3aGVuIGl0IHdhcyBsYXN0IHJ1biBpbiB0aGUgZWRpdG9yIGlzIGRpc3BsYXllZC4NCg==