library(tidyselect)
## Warning: package 'tidyselect' was built under R version 3.6.3
library(epitools)
## Warning: package 'epitools' was built under R version 3.6.3
library(DescTools)
## Warning: package 'DescTools' was built under R version 3.6.3
library(dplyr)
## Warning: package 'dplyr' was built under R version 3.6.3
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 3.6.3
library(caTools)
## Warning: package 'caTools' was built under R version 3.6.3
library(caret)
## Warning: package 'caret' was built under R version 3.6.3
## Loading required package: lattice
## 
## Attaching package: 'caret'
## The following objects are masked from 'package:DescTools':
## 
##     MAE, RMSE
library(fBasics)
## Warning: package 'fBasics' was built under R version 3.6.3
## Loading required package: timeDate
## Loading required package: timeSeries
library(lmtest)
## Warning: package 'lmtest' was built under R version 3.6.3
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 3.6.3
## 
## Attaching package: 'zoo'
## The following object is masked from 'package:timeSeries':
## 
##     time<-
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric

link tiểu luận (file pdf): https://drive.google.com/file/d/1eEctJgI8AECuvg9d6sEaSg4XabMQQL74/view?usp=sharing

File dữ liệu: https://drive.google.com/file/d/1WlDsnbdNxnN-Z__55tVxU5yg15LetA_3/view?usp=sharing

1 Dữ liệu nghiên cứu

Bài tiểu luận sử dụng bộ dữ liệu về khách hàng dùng thẻ tín dụng, được lấy ở Kaggle, được chia sẻ bới Sakshi Goyal (2021). Xuất phát từ bài toán: một người quản lý tại ngân hàng cảm thấy băn khoăn với việc ngày càng nhiều khách hàng rời bỏ dịch vụ thẻ tín dụng của họ. Người quản lý này muốn tìm hiểu về lý do của việc rời bỏ này từ đó dự đoán được ai sẽ là người rời bỏ để chủ động đến gặp khách hàng nhằm cung cấp dịch vụ tốt hơn và khiến khách hàng thay đổi theo hướng ngược lại.

Bộ dữ liệu có 20 biến quan sát gồm 10.127 quan sát.

da<-file.choose()
mac<-read.csv(da, header = T)
mac$Attrition_Flag<- as.factor(mac$Attrition_Flag)
mac$Gender<-as.factor(mac$Gender)
mac$Education_Level<-as.factor(mac$Education_Level)
mac$Dependent_count<-as.factor(mac$Dependent_count)
mac$Marital_Status<-as.factor(mac$Marital_Status)
mac$Income_Category<-as.factor(mac$Income_Category)
mac$Card_Category<-as.factor(mac$Card_Category)
str(mac)
## 'data.frame':    10127 obs. of  20 variables:
##  $ CLIENTNUM               : int  768805383 818770008 713982108 769911858 709106358 713061558 810347208 818906208 710930508 719661558 ...
##  $ Attrition_Flag          : Factor w/ 2 levels "Attrited Customer",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ Customer_Age            : int  45 49 51 40 40 44 51 32 37 48 ...
##  $ Gender                  : Factor w/ 2 levels "F","M": 2 1 2 1 2 2 2 2 2 2 ...
##  $ Dependent_count         : Factor w/ 6 levels "0","1","2","3",..: 4 6 4 5 4 3 5 1 4 3 ...
##  $ Education_Level         : Factor w/ 7 levels "College","Doctorate",..: 4 3 3 4 6 3 7 4 6 3 ...
##  $ Marital_Status          : Factor w/ 4 levels "Divorced","Married",..: 2 3 2 4 2 2 2 4 3 3 ...
##  $ Income_Category         : Factor w/ 6 levels "$120K +","$40K - $60K",..: 3 5 4 5 3 2 1 3 3 4 ...
##  $ Card_Category           : Factor w/ 4 levels "Blue","Gold",..: 1 1 1 1 1 1 2 4 1 1 ...
##  $ Months_on_book          : int  39 44 36 34 21 36 46 27 36 36 ...
##  $ Total_Relationship_Count: int  5 6 4 3 5 3 6 2 5 6 ...
##  $ Months_Inactive_12_mon  : int  1 1 1 4 1 1 1 2 2 3 ...
##  $ Contacts_Count_12_mon   : int  3 2 0 1 0 2 3 2 0 3 ...
##  $ Credit_Limit            : num  12691 8256 3418 3313 4716 ...
##  $ Total_Revolving_Bal     : int  777 864 0 2517 0 1247 2264 1396 2517 1677 ...
##  $ Total_Amt_Chng_Q4_Q1    : num  1.33 1.54 2.59 1.4 2.17 ...
##  $ Total_Trans_Amt         : int  1144 1291 1887 1171 816 1088 1330 1538 1350 1441 ...
##  $ Total_Trans_Ct          : int  42 33 20 20 28 24 31 36 24 32 ...
##  $ Total_Ct_Chng_Q4_Q1     : num  1.62 3.71 2.33 2.33 2.5 ...
##  $ Avg_Utilization_Ratio   : num  0.061 0.105 0 0.76 0 0.311 0.066 0.048 0.113 0.144 ...
  • CLIENTNUM: mã khách hàng
  • Attrition_Flag: trạng thái hoạt động của thẻ tín dụng. Existing customer: khách hàng vẫn còn sử dụng thẻ tín dụng; Attrited customer: khách hàng đã rời bỏ thẻ tín dụng.
  • Customer_age: tuổi của khách hàng (tính theo năm).
  • Gender: giới tính của khách hàng (M: Nam, F: nữ).
  • Dependent_Count: Số người phụ thuộc trong gia đình.
  • Education_Level: trình độ học vấn (Graduate: Đại học, High school: tốt nghiệp THPT ,Uneducated: không đi học ,College: cao đẳng, Post-graduate: sau đại học, Doctorate: tiến sĩ , Unknown: khác )
  • Marital_Status: tình trạng hôn nhân (Single: độc thân, Divorced: ly hôn, Married: Kết hôn)
  • Income_Category: thu nhập hàng năm (Less than $40K, $40k-$60k, $60K-$80K, $80k-$120k, $120k +, Unknown)
  • Card_Category: Loại thẻ tín dụng ( Blue, Silver, Gold, Platium).
  • Months_on_book: thời gian quan hệ với ngân hàng (Period of relationship with bank)
  • Total_Relationship_Count: tổng số sản phẩm mà khách hàng nắm giữ.
  • Months_Inactive_12_mon: số tháng không sử dụng thẻ trong 12 tháng qua.
  • Contacts_Count_12_mon: số lần liên hệ giữa khách hàng và ngân hàng trong 12 tháng qua.
  • Credit_Limit: hạn mức tín dụng
  • Total_Revolving_Bal: tổng tín dụng quay vòng
  • Total_Amt_Chng_Q4_Q1: thay đổi tổng mức chi tiêu thẻ tín dụng (Q4 so với Q1)
  • Total_Trans_Amt: tổng mức chi tiêu thẻ tín dụng (12 tháng qua)
  • Total_Trans_Ct: tổng số lượng giao dịch (12 tháng qua)
  • Total_Ct_Chnq_Q4_Q1: thay đổi tổng số giao dịch (Q4 so với Q1)
  • AVg_Utilization_Ratio: tỷ lệ chi tiêu thẻ trung bình (Số tiền đã sử dụng/ Hạn mức tín dụng)

2 Thống kê mô tả

2.1 Thống kê mô tả 1 biến

2.1.1 Biến Attrition_FLag

table(mac$Attrition_Flag)
## 
## Attrited Customer Existing Customer 
##              1627              8500
table(mac$Attrition_Flag)/sum(table(mac$Attrition_Flag))
## 
## Attrited Customer Existing Customer 
##         0.1606596         0.8393404

Có 1627 khách hàng rời bỏ (Không còn sử dụng thẻ tín dụng của ngân hàng) chiếm tỷ lệ 16,06596% tổng số khách hàng.

ggplot(mac,aes(Attrition_Flag))+
  geom_bar(color = "blue", fill = "green")+
   geom_text(aes(label = scales :: percent(after_stat(count/sum(count)))), stat=  'count', color = 'black', vjust = -.5)+
  ylab("Number of Customer")+ xlab("Attrition Flag")

2.1.2 Biến Gender

table(mac$Gender)
## 
##    F    M 
## 5358 4769

Có 5358 khách hàng nữ và 4769 khách hàng nam.

ggplot(mac,aes(Gender))+
  geom_bar(color = "blue", fill = "green")+
   geom_text(aes(label = scales :: percent(after_stat(count/sum(count)))), stat=  'count', color = 'black', vjust = -.5)+
  ylab("Number of Customer")+ xlab("Gender")

2.1.3 Biến Education_Level

table(mac$Education_Level)
## 
##       College     Doctorate      Graduate   High School Post-Graduate 
##          1013           451          3128          2013           516 
##    Uneducated       Unknown 
##          1487          1519

Phân loại số khách hàng theo trình độ học vấn như sau:

  • 1013 khách hàng tốt nghiệp cao đẳng
  • 451 khách hàng tốt nghiệp tiến sĩ
  • 3128 khách hàng tốt nghiệp đại học
  • 2013 khách hàng tốt nghiệp THPT
  • 516 khách hàng tốt nghiệp sau đại học
  • 1487 khách hàng không đi học
  • 1519 khách hàng có trình độ học vấn khác
ggplot(mac,aes(Education_Level))+
  geom_bar(color = "blue", fill = "green")+
   geom_text(aes(label = scales :: percent(after_stat(count/sum(count)))), stat=  'count', color = 'black', vjust = -.5)+
  ylab("Number of Customer")+ xlab("Education_Level")

2.1.4 Biến Marital_Status

table(mac$Marital_Status)
## 
## Divorced  Married   Single  Unknown 
##      748     4687     3943      749
  • 748 khách hàng đã ly hôn
  • 4687 khách hàng đã kết hôn
  • 3943 khách hàng còn độc thân
  • 749 khách hàng có tình trạng hôn nhân khác.
ggplot(mac,aes(x = Marital_Status, y = after_stat(count)))+
  geom_bar(color = "blue", fill = "green")+
  geom_text(aes(label = scales :: percent(after_stat(count/sum(count)))), stat=  'count', color = 'black', vjust = -.5)+
  ylab("Number of Customer")+ xlab("Marital_Status")

2.1.5 Biến Income_Category

table(mac$Income_Category)
## 
##        $120K +    $40K - $60K    $60K - $80K   $80K - $120K Less than $40K 
##            727           1790           1402           1535           3561 
##        Unknown 
##           1112
  • 727 khách hàng có thu nhập trên $120k
  • 1535 khách hàng có thu nhập từ $80k - $120k
  • 1402 khách hàng có thu nhập từ $60k - $80k
  • 1790 khách hàng có thu nhập từ $40k - $60k
  • 3561 khách hàng có thu nhập ít hơn $40k
  • 1112 khách hàng mức thu nhập khác
ggplot(mac, aes(x = "", fill = Income_Category)) +
  geom_bar(color = "blue", width = 1, stat = "count") +
  coord_polar("y", start = 0) +
  ylab("Number of Customers") +
  xlab("Income Category")

2.1.6 Biến Card_Category

summary(mac$Card_Category)
##     Blue     Gold Platinum   Silver 
##     9436      116       20      555
  • 9436 khách hàng sử dụng thẻ Blue
  • 116 khách hàng sử dụng thẻ Gold
  • 20 khách hàng sử dụng thẻ Platinum
  • 555 khách hàng sử dụng thẻ Silver
ggplot(mac,aes(Card_Category))+
  geom_bar(color = "blue", fill = "green")+
   geom_text(aes(label = scales :: percent(after_stat(count/sum(count)))), stat=  'count', color = 'black', vjust = -.5)+
  ylab("Number of Customer")+ xlab("Card Category")

2.1.7 Một số biến định lượng còn lại

Thống kê mô tả

mac1<-data.frame(mac$Total_Ct_Chng_Q4_Q1, mac$Avg_Utilization_Ratio, mac$Total_Relationship_Count, mac$Total_Trans_Amt, mac$Credit_Limit, mac$Contacts_Count_12_mon, mac$Months_Inactive_12_mon)

summary(mac1)
##  mac.Total_Ct_Chng_Q4_Q1 mac.Avg_Utilization_Ratio mac.Total_Relationship_Count
##  Min.   :0.0000          Min.   :0.0000            Min.   :1.000               
##  1st Qu.:0.5820          1st Qu.:0.0230            1st Qu.:3.000               
##  Median :0.7020          Median :0.1760            Median :4.000               
##  Mean   :0.7122          Mean   :0.2749            Mean   :3.813               
##  3rd Qu.:0.8180          3rd Qu.:0.5030            3rd Qu.:5.000               
##  Max.   :3.7140          Max.   :0.9990            Max.   :6.000               
##  mac.Total_Trans_Amt mac.Credit_Limit mac.Contacts_Count_12_mon
##  Min.   :  510       Min.   : 1438    Min.   :0.000            
##  1st Qu.: 2156       1st Qu.: 2555    1st Qu.:2.000            
##  Median : 3899       Median : 4549    Median :2.000            
##  Mean   : 4404       Mean   : 8632    Mean   :2.455            
##  3rd Qu.: 4741       3rd Qu.:11068    3rd Qu.:3.000            
##  Max.   :18484       Max.   :34516    Max.   :6.000            
##  mac.Months_Inactive_12_mon
##  Min.   :0.000             
##  1st Qu.:2.000             
##  Median :2.000             
##  Mean   :2.341             
##  3rd Qu.:3.000             
##  Max.   :6.000

Từ kết quả thống kê mô tả cho thấy:

  • Thay đổi số lượng giao dịch thẻ tín dụng quý 4 so với quý 1 (Total_Ct_Chng_Q4_Q1): nhỏ nhất là 0; giá trị lớn nhất là 3,714; giá trị trung bình là 0,7122; 25% dữ liệu nhỏ hơn 0,582 (giá trị tứ phân vị thứ nhất); 50% dữ liệu nhỏ hơn 0,702 (giá trị trung vị); 75% dữ liệu nhỏ hơn 0,818 (giá trị tứ phân vị thứ ba)

  • Tỷ lệ chi tiêu thẻ trung bình (Avg_Utilization_Ratio): giá trị nhỏ nhất của dữ liệu 0; giá trị lớn nhất là 0.999; giá trị trung bình là 0,2749; 25% dữ liệu nhỏ hơn 0,023 (giá trị tứ phân vị thứ nhất); 50% dữ liệu nhỏ hơn 0,176 (giá trị trung vị); 75% dữ liệu nhỏ hơn 0,503 (giá trị tứ phân vị thứ ba)

  • Tổng số sản phẩm dịch vụ ngân hàng mà khách hàng nắm giữ (Total_Relationship_Count): giá trị nhỏ nhất của dữ liệu 1; giá trị lớn nhất là 6; giá trị trung bình là 3,813; 25% dữ liệu nhỏ hơn 3(giá trị tứ phân vị thứ nhất); 50% dữ liệu nhỏ hơn 4 (giá trị trung vị); 75% dữ liệu nhỏ hơn 5 (giá trị tứ phân vị thứ ba)

  • Tổng mức chi tiêu thẻ tín dụng (Total_Trans_Amt): giá trị nhỏ nhất của dữ liệu 510; giá trị lớn nhất là 18.484; giá trị trung bình là 4.404; 25% dữ liệu nhỏ hơn 2.156 (giá trị tứ phân vị thứ nhất); 50% dữ liệu nhỏ hơn 3.899 (giá trị trung vị); 75% dữ liệu nhỏ hơn 4.741 (giá trị tứ phân vị thứ ba)

  • Hạn mức thẻ tín dụng (Credit_Limit):giá trị nhỏ nhất của dữ liệu 1.438; giá trị lớn nhất là 34.516; giá trị trung bình là 8.632; 25% dữ liệu nhỏ hơn 2.555 (giá trị tứ phân vị thứ nhất); 50% dữ liệu nhỏ hơn 4.549 (giá trị trung vị); 75% dữ liệu nhỏ hơn 11.068 (giá trị tứ phân vị thứ ba)

  • Số lần liên hệ của ngân hàng với khách hàng (Contacts_Count_12_mon): giá trị nhỏ nhất của dữ liệu 0; giá trị lớn nhất là 6; giá trị trung bình là 2,455; 25% dữ liệu nhỏ hơn 2 (giá trị tứ phân vị thứ nhất); 50% dữ liệu nhỏ hơn 2 (giá trị trung vị); 75% dữ liệu nhỏ hơn 3 (giá trị tứ phân vị thứ ba)

  • Số tháng không hoạt động thẻ tín dụng (Months_Inactive_12_mon): giá trị nhỏ nhất của dữ liệu 0; giá trị lớn nhất là 6; giá trị trung bình là 2,3415; 25% dữ liệu nhỏ hơn 2 (giá trị tứ phân vị thứ nhất); 50% dữ liệu nhỏ hơn 2 (giá trị trung vị); 75% dữ liệu nhỏ hơn 3 (giá trị tứ phân vị thứ ba)

Biểu đồ Histogram

hist(mac$Total_Amt_Chng_Q4_Q1)

Thay đổi số lượng giao dịch thẻ tín dụng quý 4 so với quý 1 (Total_Ct_Chng_Q4_Q1) nằm trong phạm vi 0,5 đến 1 xuất hiện nhiều nhất.

hist(mac$Avg_Utilization_Ratio)

Tỷ lệ chi tiêu thẻ trung bình (Avg_Utilization_Ratio) phân bố đều ở phạm vi giá trị từ 0.1 đến 1 và phạm vi giá trị từ 0 đến 0,5 xuất hiện nhiều nhất.

hist(mac$Total_Trans_Amt)

Tổng mức chi tiêu thẻ tín dụng (Total_Trans_Amt) ở phạm vi từ 1000 đến 5000 là nhiều nhất.

hist(mac$Credit_Limit)

Đa số khách hàng có hạn mức thẻ tín dụng (Credit_Limit) ở khoảng bé hơn 5000

2.2 Thống kê mô tả 2 biến

2.2.1 Phân tích việc khách hàng rời bỏ theo giới tính

2.2.1.1 Lập bảng tần suất

rm<-table(mac$Gender,mac$Attrition_Flag)
rm
##    
##     Attrited Customer Existing Customer
##   F               930              4428
##   M               697              4072
  • 930 khách hàng nữ không còn sử dụng thẻ tín dụng và 4428 khách hàng nữ vẫn còn sử dụng thẻ tín dụng
  • 697 khách hàng nam không còn sử dụng thẻ tín dụng và 4072 khách hàng nam vẫn còn sử dụng thẻ tín dụng
ggplot(mac, aes(Gender, fill = Attrition_Flag)) + geom_bar(position = 'dodge')

2.2.1.2 Rủi ro tương đối

Relative risk

RelRisk(rm)
## [1] 1.187613

Tỷ lệ khách hàng nữ không còn sử dụng thẻ tín dụng bằng 118,76% tỷ lệ khách hàng nam không còn sử dụng thẻ tín dụng.

Risk ratio

epitab(rm,method='riskratio',rev='c')
## $tab
##    
##     Existing Customer        p0 Attrited Customer        p1 riskratio     lower
##   F              4428 0.8264278               930 0.1735722 1.0000000        NA
##   M              4072 0.8538478               697 0.1461522 0.8420254 0.7694698
##    
##         upper      p.value
##   F        NA           NA
##   M 0.9214226 0.0001824515
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Tỷ lệ khách hàng nam không còn sử dụng thẻ tín dụng bằng 84,2% tỷ lệ khách hàng nữ không còn sử dụng thẻ tín dụng.

2.2.1.3 Odd ratio

epitab(rm, method = 'oddsratio', rev='c') 
## $tab
##    
##     Existing Customer        p0 Attrited Customer        p1 oddsratio     lower
##   F              4428 0.5209412               930 0.5716042 1.0000000        NA
##   M              4072 0.4790588               697 0.4283958 0.8149851 0.7322716
##    
##         upper      p.value
##   F        NA           NA
##   M 0.9070415 0.0001824515
## 
## $measure
## [1] "wald"
## 
## $conf.level
## [1] 0.95
## 
## $pvalue
## [1] "fisher.exact"

Tỷ lệ rời bỏ so với tỷ lệ còn sử dụng thẻ tín dụng của khách hàng nữ bằng 81,499% tỷ lệ rời bỏ so với tỷ lệ còn sử dụng thẻ tín dụng của khách hàng nam.

2.2.2 Phân tích việc khách hàng rời bỏ theo trình độ học vấn

2.2.2.1 Bảng tần suất

rm1<-table(mac$Education_Level,mac$Attrition_Flag)
rm1
##                
##                 Attrited Customer Existing Customer
##   College                     154               859
##   Doctorate                    95               356
##   Graduate                    487              2641
##   High School                 306              1707
##   Post-Graduate                92               424
##   Uneducated                  237              1250
##   Unknown                     256              1263
  • Trong số khách hàng tốt nghiệp cao đẳng có 154 khách hàng không còn sử dụng thẻ tín dụng( rời bỏ ) trong khi 859 khách hàng vẫn còn sử dụng.
  • Trong số khách hàng tốt nghiệp tiến sĩ có 95 khách hàng không còn sử dụng thẻ tín dụng( rời bỏ ) trong khi 356 khách hàng vẫn còn sử dụng.
  • Trong số khách hàng tốt nghiệp đại học có 487 khách hàng không còn sử dụng thẻ tín dụng( rời bỏ ) trong khi 2641 khách hàng vẫn còn sử dụng.
  • Trong số khách hàng tốt nghiệp THPT có 306 khách hàng không còn sử dụng thẻ tín dụng( rời bỏ ) trong khi 1707 khách hàng vẫn còn sử dụng.
  • Trong số khách hàng tốt nghiệp sau đại học có 92 khách hàng không còn sử dụng thẻ tín dụng( rời bỏ ) trong khi 424 khách hàng vẫn còn sử dụng.
  • Trong số khách hàng không đi học có 237 khách hàng không còn sử dụng thẻ tín dụng( rời bỏ ) trong khi 1250 khách hàng vẫn còn sử dụng.
  • Trong số khách hàng có trình độ học vấn khác có 256 khách hàng không còn sử dụng thẻ tín dụng( rời bỏ ) trong khi 1263 khách hàng vẫn còn sử dụng.
ggplot(mac, aes(Education_Level, fill = Attrition_Flag)) + geom_bar(position = 'dodge') 

Nhìn vào biểu đồ ta thấy khách hàng có trình độ học vấn đại học có tỷ lệ rời bỏ sử dụng thẻ tín dụng cao nhất.

2.2.3 Phân tích việc khách hàng rời bỏ theo độ tuổi

ggplot(mac, aes(x = Customer_Age, fill = Attrition_Flag)) + theme_bw()+ geom_histogram(binwidth = 8)+ labs(y = "Customer count", x = "Age", title = "Bankchuners rates by age")

Nhìn vào hình ta thấy đa số khách hàng rời bỏ thẻ tín dụng ở độ tuổi 40-60.

2.2.4 Phân tích việc khách hàng rời bỏ theo tổng mức chi tiêu thẻ tín dụng

ggplot(mac, aes(x = Total_Trans_Amt, fill = Attrition_Flag)) + theme_bw()+ geom_histogram(binwidth = 8)+ labs(y = "Customer count", x = "Transaction", title = "Bankchuners rates by transaction")

Nhìn vào đồ thị ta thấy đa số khách hàng rời bỏ giảm dần theo tổng mức chi tiêu thẻ tín dụng. Khách hàng có tổng mức chi tiêu thẻ tín dụng nằm ở khoảng dưới 5000 có tỷ lệ rời bỏ thẻ tín dụng cao nhất.

2.2.5 Phân tích việc khách hàng rời bỏ theo giới tính và loại thẻ tín dụng

2.2.5.1 Bảng tần suất

rm2<-ftable(mac$Dependent_count, mac$Gender ,mac$Attrition_Flag)
rm2
##      Attrited Customer Existing Customer
##                                         
## 0 F                 77               407
##   M                 58               362
## 1 F                169               827
##   M                100               742
## 2 F                228              1160
##   M                189              1078
## 3 F                272              1144
##   M                210              1106
## 4 F                154               695
##   M                106               619
## 5 F                 30               195
##   M                 34               165
  • Đối với khách hàng có 0 người phụ thuộc

    • 77 khách hàng nữ rời bỏ, 407 người vẫn còn sử dụng thẻ
    • 58 khách hàng nam rời bỏ, 362 người vẫn còn sử dụng thẻ
  • Đối với khách hàng có 1 người phụ thuộc

    • 169 khách hàng nữ rời bỏ, 827 người vẫn còn sử dụng thẻ
    • 100 khách hàng nam rời bỏ, 742 người vẫn còn sử dụng thẻ
  • Đối với khách hàng có 2 người phụ thuộc

    • 228 khách hàng nữ rời bỏ, 1160 người vẫn còn sử dụng thẻ
    • 189 khách hàng nam rời bỏ, 1078 người vẫn còn sử dụng thẻ
  • Đối với khách hàng có 3 người phụ thuộc

    • 272 khách hàng nữ rời bỏ, 1144 người vẫn còn sử dụng thẻ
    • 210 khách hàng nam rời bỏ, 1106 người vẫn còn sử dụng thẻ
  • Đối với khách hàng có 4 người phụ thuộc

    • 154 khách hàng nữ rời bỏ, 695 người vẫn còn sử dụng thẻ
    • 106 khách hàng nam rời bỏ, 619 người vẫn còn sử dụng thẻ
  • Đối với khách hàng có 5 người phụ thuộc

    • 30 khách hàng nữ rời bỏ, 195 người vẫn còn sử dụng thẻ
    • 34 khách hàng nam rời bỏ, 165 người vẫn còn sử dụng thẻ
ggplot(mac, aes(x = Gender, fill = Attrition_Flag)) +
  theme_bw()+
  facet_wrap(~ Dependent_count)+
  geom_bar()+
  labs(y = "Customer count",
       title = "Bankchuners rates by Gender and Dependent_count")

Nhìn vào hình vẽ ta thấy: khách hàng có 3 người phụ thuộc có tỷ lệ rời bỏ cao nhất trong khi khách hàng có 5 người phụ thuộc có tỷ lệ rời bỏ thấp nhất. Và tỷ lệ rời bỏ của khách hàng nữ đều cao hơn khách hàng nam (ngoại trừ khách hàng có 5 người phụ thuộc).

3 Thống kê suy diễn cho dữ liệu định tính

3.1 Kiểm định tính độc lập cho 2 biến định tính

Kiểm định tính độc lập cho 2 biến Attrition_Flag và Gender

chisq.test(table(mac$Attrition_Flag,mac$Gender))
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table(mac$Attrition_Flag, mac$Gender)
## X-squared = 13.866, df = 1, p-value = 0.0001964

Với p_value < 5%, bác bỏ giả thuyết H0 do đó kết luận việc khách hàng rời bỏ có liên quan tới giới tính của khách hàng.

Kiểm định tính độc lập cho 2 biến Attrition_Flag và Income_Category

chisq.test(table(mac$Attrition_Flag,mac$Income_Category))
## 
##  Pearson's Chi-squared test
## 
## data:  table(mac$Attrition_Flag, mac$Income_Category)
## X-squared = 12.832, df = 5, p-value = 0.025

Qua kết quả kiểm định cho thấy việc khách hàng rời bỏ có liên quan tới mức thu nhập của khách hàng (p_value<5%).

Kiểm định tính độc lập cho 2 biến Attrition_Flag và Education_Level

chisq.test(table(mac$Attrition_Flag,mac$Education_Level))
## 
##  Pearson's Chi-squared test
## 
## data:  table(mac$Attrition_Flag, mac$Education_Level)
## X-squared = 12.511, df = 6, p-value = 0.05149

Với mức ý nghĩa 5% chưa đủ cơ sở kết luận việc khách hàng rời bỏ có liên quan tới trình độ học vấn

Kiểm định tính độc lập cho 2 biến Attrition_Flag và Card_Category

chisq.test(table(mac$Attrition_Flag,mac$Card_Category))
## Warning in chisq.test(table(mac$Attrition_Flag, mac$Card_Category)): Chi-squared
## approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  table(mac$Attrition_Flag, mac$Card_Category)
## X-squared = 2.2342, df = 3, p-value = 0.5252

Qua kết quả kiểm định cho thấy chưa đủ cơ sở kết luận việc khách hàng rời bỏ có liên quan tới loại thẻ tín dụng

3.2 Khoảng ước lượng cho tỷ lệ

  • Bài toán 1: Ước lượng tỷ lệ khách hàng nam rời bỏ thẻ tín dụng đồng thời kiểm định xem tỷ lệ khách hàng nam rời bỏ thẻ tín dụng có phải là 40% không?
rm<- mac[mac$Attrition_Flag =="Attrited Customer",]
rm1<- rm[rm$Gender == "M",]
prop.test(length(rm1$Gender), length(rm$Gender), p = 0.4)
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(rm1$Gender) out of length(rm$Gender), null probability 0.4
## X-squared = 5.3485, df = 1, p-value = 0.02074
## alternative hypothesis: true p is not equal to 0.4
## 95 percent confidence interval:
##  0.4042428 0.4528905
## sample estimates:
##         p 
## 0.4283958

Với khoảng tin cậy 95% uớc lượng tỷ lệ khách hàng nam rời bỏ thẻ tín dụng nằm trong khoảng từ 0,4042 đến 0,45289

p-value < 5%, bác bỏ giả thuyết H0. Do đó tỷ lệ khách hàng nam rời bỏ thẻ tín dụng không bằng 40% với mức ý nghĩa 5%.

  • Bài toán 2: Ước lượng tỷ lệ khách hàng nữ rời bỏ thẻ tín dụng đồng thời kiểm định xem tỷ lệ khách hàng nữ rời bỏ thẻ tín dụng có phải là 60% không?
rf<- mac[mac$Attrition_Flag =="Attrited Customer",]
rf1<- rm[rm$Gender == "F",]
prop.test(length(rm1$Gender), length(rm$Gender), p = 0.6)
## 
##  1-sample proportions test with continuity correction
## 
## data:  length(rm1$Gender) out of length(rm$Gender), null probability 0.6
## X-squared = 198.92, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.6
## 95 percent confidence interval:
##  0.4042428 0.4528905
## sample estimates:
##         p 
## 0.4283958

Với khoảng tin cậy 95% uớc lượng tỷ lệ khách hàng nữ rời bỏ thẻ tín dụng nằm trong khoảng từ 0,5471 đến 0,5957

p-value < 5%, bác bỏ giả thuyết H0. Do đó tỷ lệ khách hàng nữ rời bỏ thẻ tín dụng không bằng 60% với mức ý nghĩa 5%.

  • Bài toán 3: Ước lượng sự chênh lệch về tỷ lệ rời bỏ thẻ tín dụng giữa khách hàng nam và nữ. Đồng thời thực hiện bài toán kiển định sự chênh lệch này
a <- c(nrow(rm), nrow(rf))
b <- c(nrow(rm1), nrow(rf1))

prop.test(b,a)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  b out of a
## X-squared = 66.163, df = 1, p-value = 4.15e-16
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  -0.1778277 -0.1085890
## sample estimates:
##    prop 1    prop 2 
## 0.4283958 0.5716042

P_value < 5%, bác bỏ giả thuyết H0, do đó có sự chênh lệnh giữa tỷ lệ khách hàng nam và nữ rời bỏ thẻ tín dụng.

Khoảng tin cậy 95% cho chênh lệch tỷ lệ nằm trong khoảng từ -0,1778277 đến -0,108589.

4 Ma trận hệ số tương quan

# Chọn các biến số liên tục trong mô hình
continuous_vars <- mac[, sapply(mac, is.numeric)]

# Tính ma trận tương quan
cor_matrix <- cor(continuous_vars)
cor_matrix
##                              CLIENTNUM Customer_Age Months_on_book
## CLIENTNUM                 1.0000000000  0.007612651    0.134587831
## Customer_Age              0.0076126512  1.000000000    0.788912359
## Months_on_book            0.1345878309  0.788912359    1.000000000
## Total_Relationship_Count  0.0069069051 -0.010931069   -0.009203080
## Months_Inactive_12_mon    0.0057285276  0.054360999    0.074163514
## Contacts_Count_12_mon     0.0056944278 -0.018451855   -0.010774479
## Credit_Limit              0.0057076227  0.002476227    0.007507009
## Total_Revolving_Bal       0.0008245041  0.014779895    0.008622804
## Total_Amt_Chng_Q4_Q1      0.0173693399 -0.062042092   -0.048959320
## Total_Trans_Amt          -0.0196917088 -0.046446491   -0.038590629
## Total_Trans_Ct           -0.0029610131 -0.067096864   -0.049819084
## Total_Ct_Chng_Q4_Q1       0.0076955755 -0.012142548   -0.014071671
## Avg_Utilization_Ratio     0.0002659600  0.007114222   -0.007540837
##                          Total_Relationship_Count Months_Inactive_12_mon
## CLIENTNUM                             0.006906905            0.005728528
## Customer_Age                         -0.010931069            0.054360999
## Months_on_book                       -0.009203080            0.074163514
## Total_Relationship_Count              1.000000000           -0.003675377
## Months_Inactive_12_mon               -0.003675377            1.000000000
## Contacts_Count_12_mon                 0.055203163            0.029492910
## Credit_Limit                         -0.071385817           -0.020393791
## Total_Revolving_Bal                   0.013725849           -0.042209609
## Total_Amt_Chng_Q4_Q1                  0.050118644           -0.032246712
## Total_Trans_Amt                      -0.347228880           -0.036982425
## Total_Trans_Ct                       -0.241890850           -0.042787039
## Total_Ct_Chng_Q4_Q1                   0.040831148           -0.038989338
## Avg_Utilization_Ratio                 0.067662878           -0.007502633
##                          Contacts_Count_12_mon Credit_Limit Total_Revolving_Bal
## CLIENTNUM                          0.005694428  0.005707623        0.0008245041
## Customer_Age                      -0.018451855  0.002476227        0.0147798946
## Months_on_book                    -0.010774479  0.007507009        0.0086228045
## Total_Relationship_Count           0.055203163 -0.071385817        0.0137258489
## Months_Inactive_12_mon             0.029492910 -0.020393791       -0.0422096088
## Contacts_Count_12_mon              1.000000000  0.020817012       -0.0539127312
## Credit_Limit                       0.020817012  1.000000000        0.0424926073
## Total_Revolving_Bal               -0.053912731  0.042492607        1.0000000000
## Total_Amt_Chng_Q4_Q1              -0.024445115  0.012812536        0.0581736645
## Total_Trans_Amt                   -0.112773929  0.171730150        0.0643704770
## Total_Trans_Ct                    -0.152212605  0.075926912        0.0560604930
## Total_Ct_Chng_Q4_Q1               -0.094996916 -0.002019850        0.0898610078
## Avg_Utilization_Ratio             -0.055471285 -0.482965071        0.6240219910
##                          Total_Amt_Chng_Q4_Q1 Total_Trans_Amt Total_Trans_Ct
## CLIENTNUM                         0.017369340     -0.01969171   -0.002961013
## Customer_Age                     -0.062042092     -0.04644649   -0.067096864
## Months_on_book                   -0.048959320     -0.03859063   -0.049819084
## Total_Relationship_Count          0.050118644     -0.34722888   -0.241890850
## Months_Inactive_12_mon           -0.032246712     -0.03698243   -0.042787039
## Contacts_Count_12_mon            -0.024445115     -0.11277393   -0.152212605
## Credit_Limit                      0.012812536      0.17173015    0.075926912
## Total_Revolving_Bal               0.058173664      0.06437048    0.056060493
## Total_Amt_Chng_Q4_Q1              1.000000000      0.03967759    0.005468567
## Total_Trans_Amt                   0.039677592      1.00000000    0.807192035
## Total_Trans_Ct                    0.005468567      0.80719203    1.000000000
## Total_Ct_Chng_Q4_Q1               0.384189256      0.08558098    0.112324440
## Avg_Utilization_Ratio             0.035234835     -0.08303425    0.002838112
##                          Total_Ct_Chng_Q4_Q1 Avg_Utilization_Ratio
## CLIENTNUM                        0.007695575           0.000265960
## Customer_Age                    -0.012142548           0.007114222
## Months_on_book                  -0.014071671          -0.007540837
## Total_Relationship_Count         0.040831148           0.067662878
## Months_Inactive_12_mon          -0.038989338          -0.007502633
## Contacts_Count_12_mon           -0.094996916          -0.055471285
## Credit_Limit                    -0.002019850          -0.482965071
## Total_Revolving_Bal              0.089861008           0.624021991
## Total_Amt_Chng_Q4_Q1             0.384189256           0.035234835
## Total_Trans_Amt                  0.085580976          -0.083034246
## Total_Trans_Ct                   0.112324440           0.002838112
## Total_Ct_Chng_Q4_Q1              1.000000000           0.074143210
## Avg_Utilization_Ratio            0.074143210           1.000000000

Qua trận hệ số tương quan giữa các biến ta thấy có mối tương quan mạnh giữa các cặp biến(Customer_Age, Months_on_book); (Total_Revovling_bal, Avg_utilization_Ratio) và (Total_trans_amt, total_trans_ct)

5 Ước lượng mô hình hồi quy

5.1 Mô hình hồi quy logit

5.1.1 Mô hình 1

Mô hình có biến phụ thuộc: attrition_flag và các biến độc lập bao gồm 3 biến định tính: gender, Income_category, dependent_count; tất cả các biến định lượng trong bộ data.

mac1 <- mac %>% select(-c(CLIENTNUM, Marital_Status, Education_Level, Card_Category))

set.seed(42)  
split <- sample.split(mac1$Attrition_Flag, SplitRatio = 0.8)
train_data1 <- subset(mac1, split == TRUE)
test_data1 <- subset(mac1, split == FALSE)
levels(mac1$Attrition_Flag)
## [1] "Attrited Customer" "Existing Customer"
mac1$Attrition_Flag <- factor(mac1$Attrition_Flag, levels = c("Existing Customer", "Attrited Customer"))
mh1 <- glm(Attrition_Flag ~., family = binomial(link = 'logit'), data = train_data1)

summary(mh1)
## 
## Call:
## glm(formula = Attrition_Flag ~ ., family = binomial(link = "logit"), 
##     data = train_data1)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -3.4003   0.0701   0.1742   0.3657   2.9931  
## 
## Coefficients:
##                                 Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                   -6.397e+00  5.059e-01 -12.645  < 2e-16 ***
## Customer_Age                   7.215e-03  8.554e-03   0.843  0.39900    
## GenderM                        8.420e-01  1.605e-01   5.246 1.56e-07 ***
## Dependent_count1              -3.012e-02  1.750e-01  -0.172  0.86335    
## Dependent_count2              -2.926e-01  1.666e-01  -1.756  0.07907 .  
## Dependent_count3              -4.155e-01  1.669e-01  -2.490  0.01278 *  
## Dependent_count4              -4.840e-01  1.814e-01  -2.668  0.00763 ** 
## Dependent_count5              -5.996e-01  2.607e-01  -2.300  0.02143 *  
## Income_Category$40K - $60K     4.919e-01  2.213e-01   2.223  0.02622 *  
## Income_Category$60K - $80K     4.236e-01  2.000e-01   2.118  0.03420 *  
## Income_Category$80K - $120K    8.661e-03  1.870e-01   0.046  0.96306    
## Income_CategoryLess than $40K  3.832e-01  2.399e-01   1.597  0.11026    
## Income_CategoryUnknown         4.867e-01  2.585e-01   1.883  0.05970 .  
## Months_on_book                 9.480e-03  8.496e-03   1.116  0.26449    
## Total_Relationship_Count       4.611e-01  3.060e-02  15.066  < 2e-16 ***
## Months_Inactive_12_mon        -5.290e-01  4.234e-02 -12.494  < 2e-16 ***
## Contacts_Count_12_mon         -5.015e-01  4.086e-02 -12.274  < 2e-16 ***
## Credit_Limit                   7.885e-06  6.671e-06   1.182  0.23720    
## Total_Revolving_Bal            9.364e-04  7.952e-05  11.776  < 2e-16 ***
## Total_Amt_Chng_Q4_Q1           4.898e-01  2.061e-01   2.376  0.01750 *  
## Total_Trans_Amt               -4.712e-04  2.522e-05 -18.680  < 2e-16 ***
## Total_Trans_Ct                 1.156e-01  4.082e-03  28.314  < 2e-16 ***
## Total_Ct_Chng_Q4_Q1            2.805e+00  2.090e-01  13.417  < 2e-16 ***
## Avg_Utilization_Ratio          1.710e-01  2.717e-01   0.630  0.52892    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 7143.2  on 8101  degrees of freedom
## Residual deviance: 3800.6  on 8078  degrees of freedom
## AIC: 3848.6
## 
## Number of Fisher Scoring iterations: 6
# Kiểm định sự phù hợp của mô hình bằng cách tính giá trị Prob(LR statistic)
lr_test <- anova(mh1, test = "Chisq")

# Lấy giá trị Prob(LR statistic)
p_value <- lr_test$Pr[2] 
p_value
## [1] 0.1732732

Kiểm định sự phù hơp của mô hình

Giả thuyết H0: mô hình không phù hợp Với P-value = Prob(LR) = 0, 1733 > 5% nên chưa đủ cơ sở bác bỏ giả thuyết H0 nên mô hình không phù hợp với dữ liệu.

Hệ số tương quan giữa customer_age và months_on_book là 0,7889 khá lớn nên CUstomer_Age không thực sự ảnh hướng đến xác suất rời bỏ thẻ tín dụng của khách hàng nên loại biến này.

5.1.2 Mô hình 2

Các biến trong mô hình 2 là các biến trong mô hình 1 đã loại bỏ đi biến Customer_age

mac2<- mac1 %>% select(-Customer_Age)
set.seed(42)  
split <- sample.split(mac2$Attrition_Flag, SplitRatio = 0.8)
train_data2 <- subset(mac2, split == TRUE)
test_data2 <- subset(mac2, split == FALSE)
mh2 <- glm(Attrition_Flag ~., family = binomial(link = 'logit'), data = train_data2)

summary(mh2)
## 
## Call:
## glm(formula = Attrition_Flag ~ ., family = binomial(link = "logit"), 
##     data = train_data2)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -2.9923  -0.3651  -0.1742  -0.0703   3.4053  
## 
## Coefficients:
##                                 Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                    6.228e+00  4.642e-01  13.416  < 2e-16 ***
## GenderM                       -8.360e-01  1.603e-01  -5.215 1.84e-07 ***
## Dependent_count1               2.811e-02  1.750e-01   0.161  0.87240    
## Dependent_count2               2.933e-01  1.667e-01   1.760  0.07842 .  
## Dependent_count3               4.186e-01  1.669e-01   2.508  0.01213 *  
## Dependent_count4               4.858e-01  1.814e-01   2.677  0.00742 ** 
## Dependent_count5               6.026e-01  2.606e-01   2.312  0.02077 *  
## Income_Category$40K - $60K    -4.767e-01  2.206e-01  -2.161  0.03068 *  
## Income_Category$60K - $80K    -4.132e-01  1.997e-01  -2.069  0.03854 *  
## Income_Category$80K - $120K   -4.094e-04  1.868e-01  -0.002  0.99825    
## Income_CategoryLess than $40K -3.679e-01  2.393e-01  -1.537  0.12420    
## Income_CategoryUnknown        -4.746e-01  2.581e-01  -1.839  0.06593 .  
## Months_on_book                -1.514e-02  5.210e-03  -2.905  0.00367 ** 
## Total_Relationship_Count      -4.607e-01  3.059e-02 -15.059  < 2e-16 ***
## Months_Inactive_12_mon         5.304e-01  4.230e-02  12.537  < 2e-16 ***
## Contacts_Count_12_mon          5.027e-01  4.084e-02  12.308  < 2e-16 ***
## Credit_Limit                  -7.925e-06  6.671e-06  -1.188  0.23488    
## Total_Revolving_Bal           -9.350e-04  7.950e-05 -11.761  < 2e-16 ***
## Total_Amt_Chng_Q4_Q1          -4.794e-01  2.058e-01  -2.330  0.01980 *  
## Total_Trans_Amt                4.699e-04  2.516e-05  18.676  < 2e-16 ***
## Total_Trans_Ct                -1.153e-01  4.067e-03 -28.357  < 2e-16 ***
## Total_Ct_Chng_Q4_Q1           -2.809e+00  2.089e-01 -13.446  < 2e-16 ***
## Avg_Utilization_Ratio         -1.765e-01  2.716e-01  -0.650  0.51581    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 7143.2  on 8101  degrees of freedom
## Residual deviance: 3801.3  on 8079  degrees of freedom
## AIC: 3847.3
## 
## Number of Fisher Scoring iterations: 6
# Kiểm định sự phù hợp của mô hình bằng cách tính giá trị Prob(LR statistic)
lr_test <- anova(mh2, test = "Chisq")

# Lấy giá trị Prob(LR statistic)
p_value <- lr_test$Pr[2] 
p_value
## [1] 0.0001217857

Kiểm định sự phù hơp của mô hình

Giả thuyết H0: mô hình không phù hợp Với P-value = Prob(LR) = 0, 0001 < 5% bác bỏ giả thuyết H0 nên mô hình phù hợp với dữ liệu.

Hệ số tương quan giữa total_revolving_bal và Avg_Utilization_Ratio là 0,624 khá lớn nên tiếp tục loại bỏ biến Avg_Utilization_Ratio và chạy mô hình 3

5.1.3 Mô hình 3

mac3<- mac2 %>% select(-Avg_Utilization_Ratio)
set.seed(42)  
split <- sample.split(mac3$Attrition_Flag, SplitRatio = 0.8)
train_data3 <- subset(mac3, split == TRUE)
test_data3 <- subset(mac3, split == FALSE)
mh3 <- glm(Attrition_Flag ~., family = binomial(link = 'logit'), data = train_data3)

summary(mh3)
## 
## Call:
## glm(formula = Attrition_Flag ~ ., family = binomial(link = "logit"), 
##     data = train_data3)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -3.0105  -0.3642  -0.1736  -0.0698   3.4210  
## 
## Coefficients:
##                                 Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                    6.213e+00  4.637e-01  13.400  < 2e-16 ***
## GenderM                       -8.349e-01  1.603e-01  -5.210 1.89e-07 ***
## Dependent_count1               2.786e-02  1.749e-01   0.159  0.87345    
## Dependent_count2               2.934e-01  1.667e-01   1.761  0.07832 .  
## Dependent_count3               4.189e-01  1.668e-01   2.511  0.01205 *  
## Dependent_count4               4.863e-01  1.814e-01   2.681  0.00735 ** 
## Dependent_count5               6.060e-01  2.605e-01   2.326  0.02001 *  
## Income_Category$40K - $60K    -4.783e-01  2.208e-01  -2.166  0.03029 *  
## Income_Category$60K - $80K    -4.094e-01  1.998e-01  -2.049  0.04048 *  
## Income_Category$80K - $120K    9.564e-04  1.870e-01   0.005  0.99592    
## Income_CategoryLess than $40K -3.752e-01  2.392e-01  -1.569  0.11666    
## Income_CategoryUnknown        -4.729e-01  2.582e-01  -1.831  0.06704 .  
## Months_on_book                -1.509e-02  5.208e-03  -2.897  0.00377 ** 
## Total_Relationship_Count      -4.608e-01  3.059e-02 -15.062  < 2e-16 ***
## Months_Inactive_12_mon         5.297e-01  4.228e-02  12.529  < 2e-16 ***
## Contacts_Count_12_mon          5.030e-01  4.084e-02  12.315  < 2e-16 ***
## Credit_Limit                  -5.960e-06  5.943e-06  -1.003  0.31590    
## Total_Revolving_Bal           -9.744e-04  5.170e-05 -18.846  < 2e-16 ***
## Total_Amt_Chng_Q4_Q1          -4.829e-01  2.057e-01  -2.347  0.01891 *  
## Total_Trans_Amt                4.712e-04  2.510e-05  18.773  < 2e-16 ***
## Total_Trans_Ct                -1.154e-01  4.064e-03 -28.405  < 2e-16 ***
## Total_Ct_Chng_Q4_Q1           -2.808e+00  2.089e-01 -13.446  < 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: 7143.2  on 8101  degrees of freedom
## Residual deviance: 3801.7  on 8080  degrees of freedom
## AIC: 3845.7
## 
## Number of Fisher Scoring iterations: 6
# Kiểm định sự phù hợp của mô hình bằng cách tính giá trị Prob(LR statistic)
lr_test <- anova(mh3, test = "Chisq")

# Lấy giá trị Prob(LR statistic)
p_value <- lr_test$Pr[2] 
p_value
## [1] 0.0001217857

Kiểm định sự phù hơp của mô hình

Giả thuyết H0: mô hình không phù hợp Với P-value = Prob(LR) = 0, 0001 < 5% bác bỏ giả thuyết H0 nên mô hình phù hợp với dữ liệu.

Hệ số tương quan giữa total_trans_amt và total_trans_ct là 0,8072 khá lớn , tiếp tục loại bỏ biến total_trans_amt và chạy mô hình 4.

5.1.4 Mô hình 4

mac4<- mac3 %>% select(- Total_Trans_Amt)
set.seed(42)  
split <- sample.split(mac4$Attrition_Flag, SplitRatio = 0.8)
train_data4 <- subset(mac4, split == TRUE)
test_data4<- subset(mac4, split == FALSE)
mh4 <- glm(Attrition_Flag ~., family = binomial(link = 'logit'), data = train_data4)

summary(mh4)
## 
## Call:
## glm(formula = Attrition_Flag ~ ., family = binomial(link = "logit"), 
##     data = train_data4)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -2.7394  -0.4106  -0.2092  -0.0907   3.7786  
## 
## Coefficients:
##                                 Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                    5.106e+00  4.412e-01  11.574  < 2e-16 ***
## GenderM                       -7.003e-01  1.552e-01  -4.511 6.46e-06 ***
## Dependent_count1               4.091e-02  1.685e-01   0.243  0.80818    
## Dependent_count2               2.544e-01  1.604e-01   1.587  0.11262    
## Dependent_count3               3.794e-01  1.598e-01   2.374  0.01758 *  
## Dependent_count4               4.458e-01  1.738e-01   2.565  0.01033 *  
## Dependent_count5               5.352e-01  2.485e-01   2.154  0.03123 *  
## Income_Category$40K - $60K    -3.268e-01  2.145e-01  -1.523  0.12764    
## Income_Category$60K - $80K    -3.174e-01  1.944e-01  -1.633  0.10254    
## Income_Category$80K - $120K    4.488e-04  1.819e-01   0.002  0.99803    
## Income_CategoryLess than $40K -2.466e-01  2.332e-01  -1.058  0.29021    
## Income_CategoryUnknown        -4.280e-01  2.494e-01  -1.716  0.08612 .  
## Months_on_book                -1.501e-02  5.024e-03  -2.987  0.00281 ** 
## Total_Relationship_Count      -5.364e-01  2.956e-02 -18.144  < 2e-16 ***
## Months_Inactive_12_mon         4.844e-01  4.037e-02  11.997  < 2e-16 ***
## Contacts_Count_12_mon          4.584e-01  3.847e-02  11.916  < 2e-16 ***
## Credit_Limit                   4.468e-06  5.718e-06   0.781  0.43454    
## Total_Revolving_Bal           -9.282e-04  4.987e-05 -18.612  < 2e-16 ***
## Total_Amt_Chng_Q4_Q1          -1.277e-01  1.913e-01  -0.668  0.50427    
## Total_Trans_Ct                -6.476e-02  2.371e-03 -27.312  < 2e-16 ***
## Total_Ct_Chng_Q4_Q1           -2.705e+00  2.036e-01 -13.284  < 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: 7143.2  on 8101  degrees of freedom
## Residual deviance: 4135.8  on 8081  degrees of freedom
## AIC: 4177.8
## 
## Number of Fisher Scoring iterations: 6
# Kiểm định sự phù hợp của mô hình bằng cách tính giá trị Prob(LR statistic)
lr_test <- anova(mh4, test = "Chisq")

# Lấy giá trị Prob(LR statistic)
p_value <- lr_test$Pr[2] 
p_value
## [1] 0.0001217857

Kiểm định sự phù hơp của mô hình

Giả thuyết H0: mô hình không phù hợp Với P-value = Prob(LR) = 0, 0001 < 5% bác bỏ giả thuyết H0 nên mô hình phù hợp với dữ liệu.

5.1.5 Lựa chọn mô hình phù hợp

Sau khi thực hiện kiểm định sự phù hợp cuả 4 mô hình ta thấy: MH2, MH3 và MH4 đều phù hợp với dữ liệu do đó dùng 4 tiêu chí sau để tiếp tục lựa chọn ra mô hình phù hợp nhất

5.1.5.1 Tiêu chỉ AIC

AIC(MH2) = 3847,3

AIC(MH3) = 3845,7

AIC(MH4) = 4135,8

Mô hình 3 có AIC nhỏ nhất nên ta chọn MH3.

5.1.5.2 Deviance

Deviance(MH2) = 3801,3

Deviance(MH3) = 3801,7

Deviance(MH4) = 4177,8

Mô hình 2 deviance nhỏ nhất nên ta chọn MH2

5.1.5.3 Brier Score

BrierScore(mh2)
## [1] 0.06976853
BrierScore(mh3)
## [1] 0.0697465
BrierScore(mh4)
## [1] 0.07395472

Dựa vào tiêu chí Brier score ta thấy MH3 có giá trị nhỏ nhất nên ta chọn MH3

5.1.5.4 Ma trận nhầm lẫn

Mô hình 2

# Đánh giá mô hình trên tập kiểm tra
predictions <- predict(mh2, newdata = test_data2, type = "response")
predicted_classes <- ifelse(predictions > 0.5, "1", "0")  # Chỉnh ngưỡng phân loại
predictions1<-factor(predicted_classes, levels = c("0","1"))
actual<- factor(test_data2$Attrition_Flag, labels = c("0","1"))
confusionMatrix(table(predictions1, actual))
## Confusion Matrix and Statistics
## 
##             actual
## predictions1    0    1
##            0 1630  148
##            1   70  177
##                                          
##                Accuracy : 0.8923         
##                  95% CI : (0.878, 0.9055)
##     No Information Rate : 0.8395         
##     P-Value [Acc > NIR] : 6.132e-12      
##                                          
##                   Kappa : 0.5576         
##                                          
##  Mcnemar's Test P-Value : 1.837e-07      
##                                          
##             Sensitivity : 0.9588         
##             Specificity : 0.5446         
##          Pos Pred Value : 0.9168         
##          Neg Pred Value : 0.7166         
##              Prevalence : 0.8395         
##          Detection Rate : 0.8049         
##    Detection Prevalence : 0.8780         
##       Balanced Accuracy : 0.7517         
##                                          
##        'Positive' Class : 0              
## 

MH2 có độ chính xác toàn thể là 89,23%, độ nhạy là 95,88% và độ hiệu quả là 54,46%

Mô hình 3

# Đánh giá mô hình trên tập kiểm tra
predictions <- predict(mh3, newdata = test_data3, type = "response")
predicted_classes <- ifelse(predictions > 0.5, "1", "0")  # Chỉnh ngưỡng phân loại
predictions1<-factor(predicted_classes, levels = c("0","1"))
actual<- factor(test_data3$Attrition_Flag, labels = c("0","1"))
confusionMatrix(table(predictions1, actual))
## Confusion Matrix and Statistics
## 
##             actual
## predictions1    0    1
##            0 1630  146
##            1   70  179
##                                           
##                Accuracy : 0.8933          
##                  95% CI : (0.8791, 0.9064)
##     No Information Rate : 0.8395          
##     P-Value [Acc > NIR] : 2.386e-12       
##                                           
##                   Kappa : 0.5628          
##                                           
##  Mcnemar's Test P-Value : 3.341e-07       
##                                           
##             Sensitivity : 0.9588          
##             Specificity : 0.5508          
##          Pos Pred Value : 0.9178          
##          Neg Pred Value : 0.7189          
##              Prevalence : 0.8395          
##          Detection Rate : 0.8049          
##    Detection Prevalence : 0.8770          
##       Balanced Accuracy : 0.7548          
##                                           
##        'Positive' Class : 0               
## 

MH3 có độ chính xác toàn thể là 89,33%, độ nhạy là 95,88% và độ hiệu quả là 55,08%

MH3 có độ nhạy bằng và độ chính xác, độ hiệu quả cao hơn so với MH2 do đó chọn mô hình 3

Kết luận: Dựa vào 4 tiêu chuẩn trên ta thấy MH3 là mô hình được chọn nhiều nhất (3 tiêu chí) do đó để ước lượng mô hình logit ta chọn MH3.

5.2 Mô hình hồi quy probit

probit <- glm(Attrition_Flag ~., family = binomial(link = 'probit'), data = train_data3)

summary(probit)
## 
## Call:
## glm(formula = Attrition_Flag ~ ., family = binomial(link = "probit"), 
##     data = train_data3)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -3.1301  -0.3847  -0.1483  -0.0326   3.7118  
## 
## Coefficients:
##                                 Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                    3.325e+00  2.486e-01  13.378  < 2e-16 ***
## GenderM                       -4.463e-01  8.626e-02  -5.174 2.29e-07 ***
## Dependent_count1               7.479e-03  9.415e-02   0.079  0.93669    
## Dependent_count2               1.400e-01  8.982e-02   1.559  0.11900    
## Dependent_count3               2.054e-01  8.977e-02   2.288  0.02216 *  
## Dependent_count4               2.397e-01  9.773e-02   2.453  0.01418 *  
## Dependent_count5               3.062e-01  1.395e-01   2.194  0.02821 *  
## Income_Category$40K - $60K    -2.318e-01  1.189e-01  -1.949  0.05127 .  
## Income_Category$60K - $80K    -2.151e-01  1.078e-01  -1.995  0.04601 *  
## Income_Category$80K - $120K   -1.084e-02  1.014e-01  -0.107  0.91486    
## Income_CategoryLess than $40K -1.938e-01  1.294e-01  -1.498  0.13418    
## Income_CategoryUnknown        -2.595e-01  1.394e-01  -1.862  0.06254 .  
## Months_on_book                -8.416e-03  2.816e-03  -2.989  0.00280 ** 
## Total_Relationship_Count      -2.379e-01  1.627e-02 -14.626  < 2e-16 ***
## Months_Inactive_12_mon         2.906e-01  2.265e-02  12.827  < 2e-16 ***
## Contacts_Count_12_mon          2.770e-01  2.170e-02  12.762  < 2e-16 ***
## Credit_Limit                  -2.495e-06  3.193e-06  -0.782  0.43448    
## Total_Revolving_Bal           -5.059e-04  2.757e-05 -18.352  < 2e-16 ***
## Total_Amt_Chng_Q4_Q1          -2.943e-01  1.099e-01  -2.677  0.00743 ** 
## Total_Trans_Amt                2.638e-04  1.316e-05  20.043  < 2e-16 ***
## Total_Trans_Ct                -6.377e-02  2.090e-03 -30.516  < 2e-16 ***
## Total_Ct_Chng_Q4_Q1           -1.511e+00  1.109e-01 -13.633  < 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: 7143.2  on 8101  degrees of freedom
## Residual deviance: 3821.3  on 8080  degrees of freedom
## AIC: 3865.3
## 
## Number of Fisher Scoring iterations: 7
# Kiểm định sự phù hợp của mô hình bằng cách tính giá trị Prob(LR statistic)
lr_test <- anova(probit, test = "Chisq")

# Lấy giá trị Prob(LR statistic)
p_value <- lr_test$Pr[2] 
p_value
## [1] 0.0001217857

Kiểm định sự phù hơp của mô hình

Giả thuyết H0: mô hình không phù hợp Với P-value = Prob(LR) = 0, 0001 < 5% bác bỏ giả thuyết H0 nên mô hình phù hợp với dữ liệu.

5.3 Mô hình cloglog

cloglog <- glm(Attrition_Flag ~., family = binomial(link = 'cloglog'), data = train_data3)
## Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
summary(cloglog)
## 
## Call:
## glm(formula = Attrition_Flag ~ ., family = binomial(link = "cloglog"), 
##     data = train_data3)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -4.8586  -0.3951  -0.2255  -0.1141   3.1972  
## 
## Coefficients:
##                                 Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                    4.313e+00  3.468e-01  12.439  < 2e-16 ***
## GenderM                       -6.090e-01  1.229e-01  -4.955 7.24e-07 ***
## Dependent_count1              -4.832e-03  1.339e-01  -0.036 0.971204    
## Dependent_count2               2.273e-01  1.271e-01   1.789 0.073615 .  
## Dependent_count3               2.592e-01  1.266e-01   2.048 0.040565 *  
## Dependent_count4               3.553e-01  1.367e-01   2.600 0.009327 ** 
## Dependent_count5               3.964e-01  1.972e-01   2.010 0.044399 *  
## Income_Category$40K - $60K    -5.755e-01  1.702e-01  -3.381 0.000721 ***
## Income_Category$60K - $80K    -5.031e-01  1.545e-01  -3.257 0.001126 ** 
## Income_Category$80K - $120K   -1.515e-01  1.445e-01  -1.049 0.294371    
## Income_CategoryLess than $40K -4.879e-01  1.836e-01  -2.657 0.007892 ** 
## Income_CategoryUnknown        -5.351e-01  1.970e-01  -2.716 0.006599 ** 
## Months_on_book                -1.225e-02  3.986e-03  -3.074 0.002115 ** 
## Total_Relationship_Count      -3.632e-01  2.254e-02 -16.117  < 2e-16 ***
## Months_Inactive_12_mon         3.927e-01  3.240e-02  12.122  < 2e-16 ***
## Contacts_Count_12_mon          3.753e-01  3.008e-02  12.476  < 2e-16 ***
## Credit_Limit                  -1.480e-05  4.711e-06  -3.142 0.001678 ** 
## Total_Revolving_Bal           -7.402e-04  3.880e-05 -19.076  < 2e-16 ***
## Total_Amt_Chng_Q4_Q1          -2.347e-01  1.561e-01  -1.504 0.132688    
## Total_Trans_Amt                3.414e-04  1.950e-05  17.505  < 2e-16 ***
## Total_Trans_Ct                -8.356e-02  3.013e-03 -27.737  < 2e-16 ***
## Total_Ct_Chng_Q4_Q1           -2.158e+00  1.600e-01 -13.489  < 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: 7143.2  on 8101  degrees of freedom
## Residual deviance: 3866.9  on 8080  degrees of freedom
## AIC: 3910.9
## 
## Number of Fisher Scoring iterations: 7
# Kiểm định sự phù hợp của mô hình bằng cách tính giá trị Prob(LR statistic)
lr_test <- anova(cloglog, test = "Chisq")

# Lấy giá trị Prob(LR statistic)
p_value <- lr_test$Pr[2] 
p_value
## [1] 0.0001217857

Kiểm định sự phù hơp của mô hình

Giả thuyết H0: mô hình không phù hợp Với P-value = Prob(LR) = 0, 0001 < 5% bác bỏ giả thuyết H0 nên mô hình phù hợp với dữ liệu.

5.4 Lựa chọn giữa mô hình logit, probit và cloglog

Sau khi thực hiện kiểm định sự phù hợp cuả mô hình logit, probit và cloglog ta thấy cả 3 mô hình đều phù hợp với dữ liệu, do đó sử dụng 4 tiêu chí sau để tìm ra mô hình phù hợp.

5.4.1 AIC

AIC(logit) = 3845,7

AIC(probit) = 3865,3

AIC(cloglog) = 3910,9

Mô hình logit có AIC nhỏ nhất nên ta chọn mô hình này.

5.4.2 Deviance

Deviance(logit) = 3801,7

Deviance(progit) = 3821,3

Deviance(cloglog) = 3866,9

Mô hình logit có deviance nhỏ nhất nên ta chọn mô hình này

5.4.3 Brier Score

BrierScore(mh3) #mô hình logit
## [1] 0.0697465
BrierScore(probit)
## [1] 0.07025875
BrierScore(cloglog)
## [1] 0.07028891

Mô hình logit có chỉ số Brier nhỏ nhất nên ta chọn mô hình này.

5.4.4 Ma trận nhầm lẫn

5.4.4.1 Mô hình logit

predictions <- predict(mh3, newdata = test_data3, type = "response")
predicted_classes <- ifelse(predictions > 0.5, "1", "0")  # Chỉnh ngưỡng phân loại
predictions1<-factor(predicted_classes, levels = c("0","1"))
actual<- factor(test_data3$Attrition_Flag, labels = c("0","1"))
confusionMatrix(table(predictions1, actual))
## Confusion Matrix and Statistics
## 
##             actual
## predictions1    0    1
##            0 1630  146
##            1   70  179
##                                           
##                Accuracy : 0.8933          
##                  95% CI : (0.8791, 0.9064)
##     No Information Rate : 0.8395          
##     P-Value [Acc > NIR] : 2.386e-12       
##                                           
##                   Kappa : 0.5628          
##                                           
##  Mcnemar's Test P-Value : 3.341e-07       
##                                           
##             Sensitivity : 0.9588          
##             Specificity : 0.5508          
##          Pos Pred Value : 0.9178          
##          Neg Pred Value : 0.7189          
##              Prevalence : 0.8395          
##          Detection Rate : 0.8049          
##    Detection Prevalence : 0.8770          
##       Balanced Accuracy : 0.7548          
##                                           
##        'Positive' Class : 0               
## 

Mô hình logit có độ chính xác toàn thể là 89,33%, độ nhạy là 95,88% và độ hiệu quả là 55,08%

5.4.4.2 Mô hình probit

predictions <- predict(probit, newdata = test_data3, type = "response")
predicted_classes <- ifelse(predictions > 0.5, "1", "0")  # Chỉnh ngưỡng phân loại
predictions1<-factor(predicted_classes, levels = c("0","1"))
actual<- factor(test_data3$Attrition_Flag, labels = c("0","1"))
confusionMatrix(table(predictions1, actual))
## Confusion Matrix and Statistics
## 
##             actual
## predictions1    0    1
##            0 1634  147
##            1   66  178
##                                           
##                Accuracy : 0.8948          
##                  95% CI : (0.8806, 0.9078)
##     No Information Rate : 0.8395          
##     P-Value [Acc > NIR] : 5.575e-13       
##                                           
##                   Kappa : 0.5659          
##                                           
##  Mcnemar's Test P-Value : 4.217e-08       
##                                           
##             Sensitivity : 0.9612          
##             Specificity : 0.5477          
##          Pos Pred Value : 0.9175          
##          Neg Pred Value : 0.7295          
##              Prevalence : 0.8395          
##          Detection Rate : 0.8069          
##    Detection Prevalence : 0.8795          
##       Balanced Accuracy : 0.7544          
##                                           
##        'Positive' Class : 0               
## 

Mô hình probit có độ chính xác toàn thể là 89,48, độ nhạy là 96,12% và độ hiệu quả là 54,77%

5.4.4.3 Mô hình cloglog

predictions <- predict(cloglog, newdata = test_data3, type = "response")
predicted_classes <- ifelse(predictions > 0.5, "1", "0")  # Chỉnh ngưỡng phân loại
head(predicted_classes,4)
##   1   2   4  13 
## "0" "0" "0" "0"
predictions1<-factor(predicted_classes, levels = c("0","1"))
actual<- factor(test_data3$Attrition_Flag, labels = c("0","1"))
confusionMatrix(table(predictions1, actual))
## Confusion Matrix and Statistics
## 
##             actual
## predictions1    0    1
##            0 1649  165
##            1   51  160
##                                           
##                Accuracy : 0.8933          
##                  95% CI : (0.8791, 0.9064)
##     No Information Rate : 0.8395          
##     P-Value [Acc > NIR] : 2.386e-12       
##                                           
##                   Kappa : 0.5387          
##                                           
##  Mcnemar's Test P-Value : 1.487e-14       
##                                           
##             Sensitivity : 0.9700          
##             Specificity : 0.4923          
##          Pos Pred Value : 0.9090          
##          Neg Pred Value : 0.7583          
##              Prevalence : 0.8395          
##          Detection Rate : 0.8143          
##    Detection Prevalence : 0.8958          
##       Balanced Accuracy : 0.7312          
##                                           
##        'Positive' Class : 0               
## 

Mô hình cloglog có độ chính xác toàn thể là 89,33%, độ nhạy là 97% và độ hiệu quả là 49,23%.

Độ chính xác toàn thể của mô hình probit cao nhất; độ nhạy của mô hình cloglog cao nhất và độ hiệu quả của mô hình cao nhất. Vì mục tiêu của bài tiểu luận là không bỏ sót các khách hàng có nguy cơ rời bỏ sử dụng dịch vụ thẻ tín dụng của ngân hàng. Do đó độ hiệu quả là tiêu chí quan trọng nhất để đánh giá trong trường hợp này, vì vậy mô hình lựa chọn là mô hình logit.

Kết luận: Dựa vào 4 tiêu chuẩn ta thấy mô hình logit là mô hình được lựa chọn nhiều nhất do đó MH logit được lựa chọn để phân tích các yếu tố ảnh hưởng đến quyết định rời bỏ thẻ tín dụng của khách hàng.

5.5 Kết quả của mô hình logit

summary(mh3)
## 
## Call:
## glm(formula = Attrition_Flag ~ ., family = binomial(link = "logit"), 
##     data = train_data3)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -3.0105  -0.3642  -0.1736  -0.0698   3.4210  
## 
## Coefficients:
##                                 Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                    6.213e+00  4.637e-01  13.400  < 2e-16 ***
## GenderM                       -8.349e-01  1.603e-01  -5.210 1.89e-07 ***
## Dependent_count1               2.786e-02  1.749e-01   0.159  0.87345    
## Dependent_count2               2.934e-01  1.667e-01   1.761  0.07832 .  
## Dependent_count3               4.189e-01  1.668e-01   2.511  0.01205 *  
## Dependent_count4               4.863e-01  1.814e-01   2.681  0.00735 ** 
## Dependent_count5               6.060e-01  2.605e-01   2.326  0.02001 *  
## Income_Category$40K - $60K    -4.783e-01  2.208e-01  -2.166  0.03029 *  
## Income_Category$60K - $80K    -4.094e-01  1.998e-01  -2.049  0.04048 *  
## Income_Category$80K - $120K    9.564e-04  1.870e-01   0.005  0.99592    
## Income_CategoryLess than $40K -3.752e-01  2.392e-01  -1.569  0.11666    
## Income_CategoryUnknown        -4.729e-01  2.582e-01  -1.831  0.06704 .  
## Months_on_book                -1.509e-02  5.208e-03  -2.897  0.00377 ** 
## Total_Relationship_Count      -4.608e-01  3.059e-02 -15.062  < 2e-16 ***
## Months_Inactive_12_mon         5.297e-01  4.228e-02  12.529  < 2e-16 ***
## Contacts_Count_12_mon          5.030e-01  4.084e-02  12.315  < 2e-16 ***
## Credit_Limit                  -5.960e-06  5.943e-06  -1.003  0.31590    
## Total_Revolving_Bal           -9.744e-04  5.170e-05 -18.846  < 2e-16 ***
## Total_Amt_Chng_Q4_Q1          -4.829e-01  2.057e-01  -2.347  0.01891 *  
## Total_Trans_Amt                4.712e-04  2.510e-05  18.773  < 2e-16 ***
## Total_Trans_Ct                -1.154e-01  4.064e-03 -28.405  < 2e-16 ***
## Total_Ct_Chng_Q4_Q1           -2.808e+00  2.089e-01 -13.446  < 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: 7143.2  on 8101  degrees of freedom
## Residual deviance: 3801.7  on 8080  degrees of freedom
## AIC: 3845.7
## 
## Number of Fisher Scoring iterations: 6

5.5.1 Giải thích kết quả

Kết quả phân tích hồi quy Logit cho thấy, 21 biến đưa vào mô hình hồi quy để phân tích nhưng kết quả phân tích chỉ có 17 biến độc lập có ý nghĩa thống kê bao gồm:

  • Giới tính (Gender)
  • Số người phụ thuộc :2 (Dependent_count2)
  • Số người phụ thuộc :3 (Dependent_count3)
  • Số người phụ thuộc :4 (Dependent_count4)
  • Số người phụ thuộc :5 (Dependent_count5)
  • Thu nhập từ $40k - $60K (Income_Category$40k - $60K)
  • Thu nhập từ $60k - $80K (Income_Category$60k - $80K)
  • Thu nhập khác (Income_CategoryUnknown)
  • Thời gian quan hệ với ngân hàng (Period of relationship with bank)( months_on_book)
  • Tổng số sản phẩm mà khách hàng nắm giữ ( total_Relationship_Count)
  • Số tháng không sử dụng thẻ trong 12 tháng qua ( months_Inactive_12_mon)
  • số lần liên hệ giữa khách hàng và ngân hàng trong 12 tháng qua( contacts_Count_12_mon)
  • tổng tín dụng quay vòng( Total_Revolving_Bal)
  • thay đổi tổng mức chi tiêu thẻ tín dụng (Q4 so với Q1) (total_Amt_Chng_Q4_Q1)
  • tổng mức chi tiêu thẻ tín dụng (12 tháng qua)(total_Trans_Amt)
  • tổng số lượng giao dịch (12 tháng qua)( total_Trans_Ct)
  • thay đổi tổng số giao dịch (Q4 so với Q1) (Total_Ct_Chng_Q4_Q1)

Với giả thuyết các yếu tố khác không đổi, ảnh hưởng của từng biến đến được diễn giải như sau:

  • Biến giới tính trong mô hình có ý nghĩa thống kê về tỷ lệ rời bỏ thẻ tín dụng của khách hàng, ở mức ý nghĩa 1% thì khách hàng nam sẽ có xác suất rời bỏ cao hơn 30,26 % so với khách hàng nữ.

  • Số người phụ thuộc của khách hàng khác nhau sẽ có tác động đáng kể đến quyết định rời bỏ thẻ tín dụng của khách hàng. Ở mức ý nghĩa 10% thì khách hàng có 2 người phụ thuộc có xác suất rời bỏ cao hơn 57,28% so với khách hàng không có người phụ thuộc.Ở mức ý nghĩa 5% Khách hàng có 3 người phụ thuộc có xác suất rời bỏ cao hơn 60,32% so với ở mức thu nhập khách hàng không có người phụ thuộc.Ở mức ý nghĩa 1% Khách hàng có 4 người phụ thuộc có xác suất rời bỏ cao hơn 61,92% so với ở mức thu nhập khách hàng không có người phụ thuộc. Ở mức ý nghĩa 5% Khách hàng có 5 người phụ thuộc có xác suất rời bỏ cao hơn 64,7% so với ở mức thu nhập khách hàng không có người phụ thuộc.

  • Thu nhập của khách hàng ở các mức khác nhau sẽ có tác động đáng kể đến quyết định rời bỏ thẻ tín dụng của khách hàng. Ở mức ý nghĩa 5% thì khách hàng có thu nhập từ $40-$60 có xác suất rời bỏ cao hơn 61,73% so với ở mức thu nhập lớn hơn $120 . Trong khi đó khách hàng có mức thu nhập từ $60-$80 có xác suất cao hơn 60,09% so với khách hàng có mức thu nhập lớn hơn $120. Với mức ý nghĩa 10% thì khách hàng có thu nhập khác có xác suất rời bỏ cao hơn 61,61% so với ở mức thu nhập lớn hơn $120.

  • Ở mức ý nghĩa 1%, thời gian quan hệ với ngân hàng (Period of relationship with bank)( months_on_book), tổng số sản phẩm mà khách hàng nắm giữ ( total_Relationship_Count),tổng tín dụng quay vòng( Total_Revolving_Bal), thay đổi tổng mức chi tiêu thẻ tín dụng (Q4 so với Q1) (total_Amt_Chng_Q4_Q1), tổng số lượng giao dịch (12 tháng qua)( total_Trans_Ct), thay đổi tổng số giao dịch (Q4 so với Q1) (Total_Ct_Chng_Q4_Q1) có tác động tiêu cực lên khả năng rởi bỏ thẻ tín dụng của khách hàng. Trong khi các yếu tố: số lần liên hệ của ngân hàng với khách hàng (Contacts_Count_12_mon) , số tháng không hoạt động thẻ tín dụng (Months_Inactive_12_mon) và tổng mức chi tiêu thẻ tín dụng (12 tháng qua)(total_Trans_Amt) lại có tác động tích cực lên khả năng rởi bỏ thẻ tín dụng của khách hàng.

5.5.2 Khoảng ước lượng cho hệ số hồi quy

confint.default(mh3)
##                                       2.5 %        97.5 %
## (Intercept)                    5.304385e+00  7.121915e+00
## GenderM                       -1.148941e+00 -5.207695e-01
## Dependent_count1              -3.149909e-01  3.707141e-01
## Dependent_count2              -3.323691e-02  6.200321e-01
## Dependent_count3               9.188186e-02  7.459095e-01
## Dependent_count4               1.307356e-01  8.418483e-01
## Dependent_count5               9.537716e-02  1.116529e+00
## Income_Category$40K - $60K    -9.111017e-01 -4.555335e-02
## Income_Category$60K - $80K    -8.010750e-01 -1.775864e-02
## Income_Category$80K - $120K   -3.655805e-01  3.674932e-01
## Income_CategoryLess than $40K -8.439416e-01  9.351513e-02
## Income_CategoryUnknown        -9.789782e-01  3.320185e-02
## Months_on_book                -2.529605e-02 -4.879611e-03
## Total_Relationship_Count      -5.207558e-01 -4.008349e-01
## Months_Inactive_12_mon         4.468573e-01  6.125929e-01
## Contacts_Count_12_mon          4.229297e-01  5.830270e-01
## Credit_Limit                  -1.760825e-05  5.687684e-06
## Total_Revolving_Bal           -1.075700e-03 -8.730376e-04
## Total_Amt_Chng_Q4_Q1          -8.861509e-01 -7.967858e-02
## Total_Trans_Amt                4.220410e-04  5.204387e-04
## Total_Trans_Ct                -1.234149e-01 -1.074827e-01
## Total_Ct_Chng_Q4_Q1           -3.217643e+00 -2.398942e+00

5.5.3 Dự báo

predictions <- predict(mh3, newdata = test_data3, type = "response")
head(round(predictions,4),10)
##      1      2      4     13     16     17     21     24     25     29 
## 0.0030 0.0000 0.0120 0.0044 0.0108 0.0423 0.0125 0.8876 0.7622 0.2890
LS0tDQp0aXRsZTogIlBIw4JOIFTDjUNIIEPDgUMgWeG6vlUgVOG7kCDhuqJOSCBIxq/hu55ORyDEkOG6vk4gS0jhuqIgTsSCTkcgUuG7nEkgQuG7jiBUSOG6uiBUw41OIEThu6RORyBD4bumQSBLSMOBQ0ggSMOATkciDQphdXRob3I6ICJUcuG6p24gVGjhu4sgVGh1IEPhuqltIg0KZGF0ZTogJyAxMi8wNi8yMDIzJw0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBubw0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQotLS0NCg0KDQpgYGB7cn0NCg0KbGlicmFyeSh0aWR5c2VsZWN0KQ0KbGlicmFyeShlcGl0b29scykNCmxpYnJhcnkoRGVzY1Rvb2xzKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoY2FUb29scykNCmxpYnJhcnkoY2FyZXQpDQpsaWJyYXJ5KGZCYXNpY3MpDQpsaWJyYXJ5KGxtdGVzdCkNCmBgYA0KDQpsaW5rIHRp4buDdSBsdeG6rW4gKGZpbGUgcGRmKTogPGh0dHBzOi8vZHJpdmUuZ29vZ2xlLmNvbS9maWxlL2QvMWVFY3RKZ0k4QUVDdXZnOWQ2c0VhU2c0WGFiTVFRTDc0L3ZpZXc/dXNwPXNoYXJpbmc+DQoNCkZpbGUgZOG7ryBsaeG7h3U6IDxodHRwczovL2RyaXZlLmdvb2dsZS5jb20vZmlsZS9kLzFXbERzbmJkTnhuTi1aX181NXRWeFU1eWcxNUxldEFfMy92aWV3P3VzcD1zaGFyaW5nPg0KDQoNCiMgROG7ryBsaeG7h3UgbmdoacOqbiBj4bupdQ0KDQoNCjxkaXYgYWxpZ249Imp1c3RpZnkiPkLDoGkgdGnhu4N1IGx14bqtbiBz4butIGThu6VuZyBi4buZIGThu68gbGnhu4d1IHbhu4Ega2jDoWNoIGjDoG5nIGTDuW5nIHRo4bq7IHTDrW4gZOG7pW5nLCDEkcaw4bujYyBs4bqleSDhu58gS2FnZ2xlLCDEkcaw4bujYyBjaGlhIHPhursgYuG7m2kgU2Frc2hpIEdveWFsICgyMDIxKS4gWHXhuqV0IHBow6F0IHThu6sgYsOgaSB0b8OhbjogbeG7mXQgbmfGsOG7nWkgcXXhuqNuIGzDvSB04bqhaSBuZ8OibiBow6BuZyBj4bqjbSB0aOG6pXkgYsSDbiBraG/Eg24gduG7m2kgdmnhu4djIG5nw6B5IGPDoG5nIG5oaeG7gXUga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gZOG7i2NoIHbhu6UgdGjhursgdMOtbiBk4bulbmcgY+G7p2EgaOG7jS4gTmfGsOG7nWkgcXXhuqNuIGzDvSBuw6B5IG114buRbiB0w6xtIGhp4buDdSB24buBIGzDvSBkbyBj4bunYSB2aeG7h2MgcuG7nWkgYuG7jyBuw6B5IHThu6sgxJHDsyBk4buxIMSRb8OhbiDEkcaw4bujYyBhaSBz4bq9IGzDoCBuZ8aw4budaSBy4budaSBi4buPIMSR4buDIGNo4bunIMSR4buZbmcgxJHhur9uIGfhurdwIGtow6FjaCBow6BuZyBuaOG6sW0gY3VuZyBj4bqlcCBk4buLY2ggduG7pSB04buRdCBoxqFuIHbDoCBraGnhur9uIGtow6FjaCBow6BuZyB0aGF5IMSR4buVaSB0aGVvIGjGsOG7m25nIG5nxrDhu6NjIGzhuqFpLjwvZGl2Pg0KDQpC4buZIGThu68gbGnhu4d1IGPDsyAyMCBiaeG6v24gcXVhbiBzw6F0IGfhu5NtIDEwLjEyNyBxdWFuIHPDoXQuDQoNCg0KYGBge3J9DQoNCmRhPC1maWxlLmNob29zZSgpDQptYWM8LXJlYWQuY3N2KGRhLCBoZWFkZXIgPSBUKQ0KbWFjJEF0dHJpdGlvbl9GbGFnPC0gYXMuZmFjdG9yKG1hYyRBdHRyaXRpb25fRmxhZykNCm1hYyRHZW5kZXI8LWFzLmZhY3RvcihtYWMkR2VuZGVyKQ0KbWFjJEVkdWNhdGlvbl9MZXZlbDwtYXMuZmFjdG9yKG1hYyRFZHVjYXRpb25fTGV2ZWwpDQptYWMkRGVwZW5kZW50X2NvdW50PC1hcy5mYWN0b3IobWFjJERlcGVuZGVudF9jb3VudCkNCm1hYyRNYXJpdGFsX1N0YXR1czwtYXMuZmFjdG9yKG1hYyRNYXJpdGFsX1N0YXR1cykNCm1hYyRJbmNvbWVfQ2F0ZWdvcnk8LWFzLmZhY3RvcihtYWMkSW5jb21lX0NhdGVnb3J5KQ0KbWFjJENhcmRfQ2F0ZWdvcnk8LWFzLmZhY3RvcihtYWMkQ2FyZF9DYXRlZ29yeSkNCnN0cihtYWMpDQpgYGANCiogQ0xJRU5UTlVNOiBtw6Mga2jDoWNoIGjDoG5nDQoqIEF0dHJpdGlvbl9GbGFnOiB0cuG6oW5nIHRow6FpIGhv4bqhdCDEkeG7mW5nIGPhu6dhIHRo4bq7IHTDrW4gZOG7pW5nLiBFeGlzdGluZyBjdXN0b21lcjoga2jDoWNoIGjDoG5nIHbhuqtuIGPDsm4gc+G7rSBk4bulbmcgdGjhursgdMOtbiBk4bulbmc7IEF0dHJpdGVkIGN1c3RvbWVyOiBraMOhY2ggaMOgbmcgxJHDoyBy4budaSBi4buPIHRo4bq7IHTDrW4gZOG7pW5nLg0KKiBDdXN0b21lcl9hZ2U6IHR14buVaSBj4bunYSBraMOhY2ggaMOgbmcgKHTDrW5oIHRoZW8gbsSDbSkuDQoqIEdlbmRlcjogZ2nhu5tpIHTDrW5oIGPhu6dhIGtow6FjaCBow6BuZyAoTTogTmFtLCBGOiBu4buvKS4NCiogRGVwZW5kZW50X0NvdW50OiBT4buRIG5nxrDhu51pIHBo4bulIHRodeG7mWMgdHJvbmcgZ2lhIMSRw6xuaC4NCiogRWR1Y2F0aW9uX0xldmVsOiB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gKEdyYWR1YXRlOiDEkOG6oWkgaOG7jWMsIEhpZ2ggc2Nob29sOiB04buRdCBuZ2hp4buHcCBUSFBUICxVbmVkdWNhdGVkOiBraMO0bmcgxJFpIGjhu41jICxDb2xsZWdlOiBjYW8gxJHhurNuZywgUG9zdC1ncmFkdWF0ZTogc2F1IMSR4bqhaSBo4buNYywgRG9jdG9yYXRlOiB0aeG6v24gc8SpICwgVW5rbm93bjoga2jDoWMgKQ0KKiBNYXJpdGFsX1N0YXR1czogdMOsbmggdHLhuqFuZyBow7RuIG5ow6JuIChTaW5nbGU6IMSR4buZYyB0aMOibiwgRGl2b3JjZWQ6IGx5IGjDtG4sIE1hcnJpZWQ6IEvhur90IGjDtG4pDQoqIEluY29tZV9DYXRlZ29yeTogdGh1IG5o4bqtcCBow6BuZyBuxINtIChMZXNzIHRoYW4gJDQwSywgJDQway0kNjBrLCAkNjBLLSQ4MEssICQ4MGstJDEyMGssICQxMjBrICssIFVua25vd24pDQoqIENhcmRfQ2F0ZWdvcnk6IExv4bqhaSB0aOG6uyB0w61uIGThu6VuZyAoIEJsdWUsIFNpbHZlciwgR29sZCwgUGxhdGl1bSkuDQoqIE1vbnRoc19vbl9ib29rOiB0aOG7nWkgZ2lhbiBxdWFuIGjhu4cgduG7m2kgbmfDom4gaMOgbmcgKFBlcmlvZCBvZiByZWxhdGlvbnNoaXAgd2l0aCBiYW5rKQ0KKiBUb3RhbF9SZWxhdGlvbnNoaXBfQ291bnQ6IHThu5VuZyBz4buRIHPhuqNuIHBo4bqpbSBtw6Aga2jDoWNoIGjDoG5nIG7huq9tIGdp4buvLg0KKiBNb250aHNfSW5hY3RpdmVfMTJfbW9uOiBz4buRIHRow6FuZyBraMO0bmcgc+G7rSBk4bulbmcgdGjhursgdHJvbmcgMTIgdGjDoW5nIHF1YS4NCiogQ29udGFjdHNfQ291bnRfMTJfbW9uOiBz4buRIGzhuqduIGxpw6puIGjhu4cgZ2nhu69hIGtow6FjaCBow6BuZyB2w6AgbmfDom4gaMOgbmcgdHJvbmcgMTIgdGjDoW5nIHF1YS4NCiogQ3JlZGl0X0xpbWl0OiBo4bqhbiBt4bupYyB0w61uIGThu6VuZw0KKiBUb3RhbF9SZXZvbHZpbmdfQmFsOiB04buVbmcgdMOtbiBk4bulbmcgcXVheSB2w7JuZw0KKiBUb3RhbF9BbXRfQ2huZ19RNF9RMTogdGhheSDEkeG7lWkgdOG7lW5nIG3hu6ljIGNoaSB0acOqdSB0aOG6uyB0w61uIGThu6VuZyAoUTQgc28gduG7m2kgUTEpDQoqIFRvdGFsX1RyYW5zX0FtdDogdOG7lW5nIG3hu6ljIGNoaSB0acOqdSB0aOG6uyB0w61uIGThu6VuZyAoMTIgdGjDoW5nIHF1YSkNCiogVG90YWxfVHJhbnNfQ3Q6IHThu5VuZyBz4buRIGzGsOG7o25nIGdpYW8gZOG7i2NoICgxMiB0aMOhbmcgcXVhKQ0KKiBUb3RhbF9DdF9DaG5xX1E0X1ExOiB0aGF5IMSR4buVaSB04buVbmcgc+G7kSBnaWFvIGThu4tjaCAoUTQgc28gduG7m2kgUTEpDQoqIEFWZ19VdGlsaXphdGlvbl9SYXRpbzogdOG7tyBs4buHIGNoaSB0acOqdSB0aOG6uyB0cnVuZyBiw6xuaCAoU+G7kSB0aeG7gW4gxJHDoyBz4butIGThu6VuZy8gSOG6oW4gbeG7qWMgdMOtbiBk4bulbmcpDQoNCg0KDQojIFRo4buRbmcga8OqIG3DtCB04bqjIA0KDQojIyBUaOG7kW5nIGvDqiBtw7QgdOG6oyAxIGJp4bq/bg0KDQojIyMgQmnhur9uIEF0dHJpdGlvbl9GTGFnDQoNCmBgYHtyfQ0KdGFibGUobWFjJEF0dHJpdGlvbl9GbGFnKQ0KYGBgDQoNCmBgYHtyfQ0KdGFibGUobWFjJEF0dHJpdGlvbl9GbGFnKS9zdW0odGFibGUobWFjJEF0dHJpdGlvbl9GbGFnKSkNCmBgYA0KQ8OzIDE2Mjcga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gKEtow7RuZyBjw7JuIHPhu60gZOG7pW5nIHRo4bq7IHTDrW4gZOG7pW5nIGPhu6dhIG5nw6JuIGjDoG5nKSBjaGnhur9tIHThu7cgbOG7hyAxNiwwNjU5NiUgdOG7lW5nIHPhu5Ega2jDoWNoIGjDoG5nLg0KDQpgYGB7cn0NCmdncGxvdChtYWMsYWVzKEF0dHJpdGlvbl9GbGFnKSkrDQogIGdlb21fYmFyKGNvbG9yID0gImJsdWUiLCBmaWxsID0gImdyZWVuIikrDQogICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzIDo6IHBlcmNlbnQoYWZ0ZXJfc3RhdChjb3VudC9zdW0oY291bnQpKSkpLCBzdGF0PSAgJ2NvdW50JywgY29sb3IgPSAnYmxhY2snLCB2anVzdCA9IC0uNSkrDQogIHlsYWIoIk51bWJlciBvZiBDdXN0b21lciIpKyB4bGFiKCJBdHRyaXRpb24gRmxhZyIpDQpgYGANCg0KIyMjIEJp4bq/biBHZW5kZXINCg0KYGBge3J9DQp0YWJsZShtYWMkR2VuZGVyKQ0KYGBgDQpDw7MgNTM1OCBraMOhY2ggaMOgbmcgbuG7ryB2w6AgNDc2OSBraMOhY2ggaMOgbmcgbmFtLg0KYGBge3J9DQpnZ3Bsb3QobWFjLGFlcyhHZW5kZXIpKSsNCiAgZ2VvbV9iYXIoY29sb3IgPSAiYmx1ZSIsIGZpbGwgPSAiZ3JlZW4iKSsNCiAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXMgOjogcGVyY2VudChhZnRlcl9zdGF0KGNvdW50L3N1bShjb3VudCkpKSksIHN0YXQ9ICAnY291bnQnLCBjb2xvciA9ICdibGFjaycsIHZqdXN0ID0gLS41KSsNCiAgeWxhYigiTnVtYmVyIG9mIEN1c3RvbWVyIikrIHhsYWIoIkdlbmRlciIpDQpgYGANCg0KIyMjIEJp4bq/biBFZHVjYXRpb25fTGV2ZWwNCg0KYGBge3J9DQp0YWJsZShtYWMkRWR1Y2F0aW9uX0xldmVsKQ0KYGBgDQpQaMOibiBsb+G6oWkgc+G7kSBraMOhY2ggaMOgbmcgdGhlbyB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gbmjGsCBzYXU6DQoNCiogMTAxMyBraMOhY2ggaMOgbmcgdOG7kXQgbmdoaeG7h3AgY2FvIMSR4bqzbmcNCiogNDUxIGtow6FjaCBow6BuZyB04buRdCBuZ2hp4buHcCB0aeG6v24gc8SpDQoqIDMxMjgga2jDoWNoIGjDoG5nIHThu5F0IG5naGnhu4dwIMSR4bqhaSBo4buNYw0KKiAyMDEzIGtow6FjaCBow6BuZyB04buRdCBuZ2hp4buHcCBUSFBUDQoqIDUxNiBraMOhY2ggaMOgbmcgdOG7kXQgbmdoaeG7h3Agc2F1IMSR4bqhaSBo4buNYw0KKiAxNDg3IGtow6FjaCBow6BuZyBraMO0bmcgxJFpIGjhu41jDQoqIDE1MTkga2jDoWNoIGjDoG5nIGPDsyB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4ga2jDoWMNCg0KYGBge3J9DQpnZ3Bsb3QobWFjLGFlcyhFZHVjYXRpb25fTGV2ZWwpKSsNCiAgZ2VvbV9iYXIoY29sb3IgPSAiYmx1ZSIsIGZpbGwgPSAiZ3JlZW4iKSsNCiAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXMgOjogcGVyY2VudChhZnRlcl9zdGF0KGNvdW50L3N1bShjb3VudCkpKSksIHN0YXQ9ICAnY291bnQnLCBjb2xvciA9ICdibGFjaycsIHZqdXN0ID0gLS41KSsNCiAgeWxhYigiTnVtYmVyIG9mIEN1c3RvbWVyIikrIHhsYWIoIkVkdWNhdGlvbl9MZXZlbCIpDQpgYGANCg0KIyMjIEJp4bq/biBNYXJpdGFsX1N0YXR1cw0KDQpgYGB7cn0NCnRhYmxlKG1hYyRNYXJpdGFsX1N0YXR1cykNCmBgYA0KDQoqIDc0OCBraMOhY2ggaMOgbmcgxJHDoyBseSBow7RuDQoqIDQ2ODcga2jDoWNoIGjDoG5nIMSRw6Mga+G6v3QgaMO0bg0KKiAzOTQzIGtow6FjaCBow6BuZyBjw7JuIMSR4buZYyB0aMOibg0KKiA3NDkga2jDoWNoIGjDoG5nIGPDsyB0w6xuaCB0cuG6oW5nIGjDtG4gbmjDom4ga2jDoWMuDQoNCmBgYHtyfQ0KZ2dwbG90KG1hYyxhZXMoeCA9IE1hcml0YWxfU3RhdHVzLCB5ID0gYWZ0ZXJfc3RhdChjb3VudCkpKSsNCiAgZ2VvbV9iYXIoY29sb3IgPSAiYmx1ZSIsIGZpbGwgPSAiZ3JlZW4iKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlcyA6OiBwZXJjZW50KGFmdGVyX3N0YXQoY291bnQvc3VtKGNvdW50KSkpKSwgc3RhdD0gICdjb3VudCcsIGNvbG9yID0gJ2JsYWNrJywgdmp1c3QgPSAtLjUpKw0KICB5bGFiKCJOdW1iZXIgb2YgQ3VzdG9tZXIiKSsgeGxhYigiTWFyaXRhbF9TdGF0dXMiKQ0KYGBgDQoNCiMjIyBCaeG6v24gSW5jb21lX0NhdGVnb3J5DQoNCmBgYHtyfQ0KdGFibGUobWFjJEluY29tZV9DYXRlZ29yeSkNCmBgYA0KKiA3Mjcga2jDoWNoIGjDoG5nIGPDsyB0aHUgbmjhuq1wIHRyw6puICQxMjBrDQoqIDE1MzUga2jDoWNoIGjDoG5nIGPDsyB0aHUgbmjhuq1wIHThu6sgJDgwayAtICQxMjBrDQoqIDE0MDIga2jDoWNoIGjDoG5nIGPDsyB0aHUgbmjhuq1wIHThu6sgJDYwayAtICQ4MGsNCiogMTc5MCBraMOhY2ggaMOgbmcgY8OzIHRodSBuaOG6rXAgdOG7qyAkNDBrIC0gJDYwaw0KKiAzNTYxIGtow6FjaCBow6BuZyBjw7MgdGh1IG5o4bqtcCDDrXQgaMahbiAkNDBrDQoqIDExMTIga2jDoWNoIGjDoG5nIG3hu6ljIHRodSBuaOG6rXAga2jDoWMNCg0KYGBge3J9DQoNCg0KDQpnZ3Bsb3QobWFjLCBhZXMoeCA9ICIiLCBmaWxsID0gSW5jb21lX0NhdGVnb3J5KSkgKw0KICBnZW9tX2Jhcihjb2xvciA9ICJibHVlIiwgd2lkdGggPSAxLCBzdGF0ID0gImNvdW50IikgKw0KICBjb29yZF9wb2xhcigieSIsIHN0YXJ0ID0gMCkgKw0KICB5bGFiKCJOdW1iZXIgb2YgQ3VzdG9tZXJzIikgKw0KICB4bGFiKCJJbmNvbWUgQ2F0ZWdvcnkiKQ0KDQpgYGANCg0KIyMjIEJp4bq/biBDYXJkX0NhdGVnb3J5DQoNCmBgYHtyfQ0Kc3VtbWFyeShtYWMkQ2FyZF9DYXRlZ29yeSkNCmBgYA0KKiA5NDM2IGtow6FjaCBow6BuZyBz4butIGThu6VuZyB0aOG6uyBCbHVlDQoqIDExNiBraMOhY2ggaMOgbmcgc+G7rSBk4bulbmcgdGjhursgR29sZA0KKiAyMCBraMOhY2ggaMOgbmcgc+G7rSBk4bulbmcgdGjhursgUGxhdGludW0NCiogNTU1IGtow6FjaCBow6BuZyBz4butIGThu6VuZyB0aOG6uyBTaWx2ZXINCg0KYGBge3J9DQpnZ3Bsb3QobWFjLGFlcyhDYXJkX0NhdGVnb3J5KSkrDQogIGdlb21fYmFyKGNvbG9yID0gImJsdWUiLCBmaWxsID0gImdyZWVuIikrDQogICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzIDo6IHBlcmNlbnQoYWZ0ZXJfc3RhdChjb3VudC9zdW0oY291bnQpKSkpLCBzdGF0PSAgJ2NvdW50JywgY29sb3IgPSAnYmxhY2snLCB2anVzdCA9IC0uNSkrDQogIHlsYWIoIk51bWJlciBvZiBDdXN0b21lciIpKyB4bGFiKCJDYXJkIENhdGVnb3J5IikNCmBgYA0KDQojIyMgTeG7mXQgc+G7kSBiaeG6v24gxJHhu4tuaCBsxrDhu6NuZyBjw7JuIGzhuqFpDQoNCioqVGjhu5FuZyBrw6ogbcO0IHThuqMqKg0KYGBge3J9DQptYWMxPC1kYXRhLmZyYW1lKG1hYyRUb3RhbF9DdF9DaG5nX1E0X1ExLCBtYWMkQXZnX1V0aWxpemF0aW9uX1JhdGlvLCBtYWMkVG90YWxfUmVsYXRpb25zaGlwX0NvdW50LCBtYWMkVG90YWxfVHJhbnNfQW10LCBtYWMkQ3JlZGl0X0xpbWl0LCBtYWMkQ29udGFjdHNfQ291bnRfMTJfbW9uLCBtYWMkTW9udGhzX0luYWN0aXZlXzEyX21vbikNCg0Kc3VtbWFyeShtYWMxKQ0KDQoNCmBgYA0KVOG7qyBr4bq/dCBxdeG6oyB0aOG7kW5nIGvDqiBtw7QgdOG6oyBjaG8gdGjhuqV5Og0KDQoqIFRoYXkgxJHhu5VpIHPhu5EgbMaw4bujbmcgZ2lhbyBk4buLY2ggdGjhursgdMOtbiBk4bulbmcgcXXDvSA0IHNvIHbhu5tpIHF1w70gMSAoVG90YWxfQ3RfQ2huZ19RNF9RMSk6DQogbmjhu48gbmjhuqV0IGzDoCAwOyBnacOhIHRy4buLIGzhu5tuIG5o4bqldCBsw6AgMyw3MTQ7IGdpw6EgdHLhu4sgdHJ1bmcgYsOsbmggbMOgIDAsNzEyMjsgMjUlIGThu68gbGnhu4d1IG5o4buPIGjGoW4gMCw1ODIgKGdpw6EgdHLhu4sgdOG7qSBwaMOibiB24buLIHRo4bupIG5o4bqldCk7IDUwJSBk4buvIGxp4buHdSBuaOG7jyBoxqFuIDAsNzAyIChnacOhIHRy4buLIHRydW5nIHbhu4spOyA3NSUgZOG7ryBsaeG7h3Ugbmjhu48gaMahbiAwLDgxOCAoZ2nDoSB0cuG7iyB04bupIHBow6JuIHbhu4sgdGjhu6kgYmEpDQoNCiogVOG7tyBs4buHIGNoaSB0acOqdSB0aOG6uyB0cnVuZyBiw6xuaCAoQXZnX1V0aWxpemF0aW9uX1JhdGlvKTogZ2nDoSB0cuG7iyBuaOG7jyBuaOG6pXQgY+G7p2EgZOG7ryBsaeG7h3UgMDsgZ2nDoSB0cuG7iyBs4bubbiBuaOG6pXQgbMOgIDAuOTk5OyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGzDoCAwLDI3NDk7IDI1JSBk4buvIGxp4buHdSBuaOG7jyBoxqFuIDAsMDIzIChnacOhIHRy4buLIHThu6kgcGjDom4gduG7iyB0aOG7qSBuaOG6pXQpOyA1MCUgZOG7ryBsaeG7h3Ugbmjhu48gaMahbiAwLDE3NiAoZ2nDoSB0cuG7iyB0cnVuZyB24buLKTsgNzUlIGThu68gbGnhu4d1IG5o4buPIGjGoW4gMCw1MDMgKGdpw6EgdHLhu4sgdOG7qSBwaMOibiB24buLIHRo4bupIGJhKQ0KDQoqIFThu5VuZyBz4buRIHPhuqNuIHBo4bqpbSBk4buLY2ggduG7pSBuZ8OibiBow6BuZyBtw6Aga2jDoWNoIGjDoG5nIG7huq9tIGdp4buvIChUb3RhbF9SZWxhdGlvbnNoaXBfQ291bnQpOiBnacOhIHRy4buLIG5o4buPIG5o4bqldCBj4bunYSBk4buvIGxp4buHdSAxOyBnacOhIHRy4buLIGzhu5tuIG5o4bqldCBsw6AgNjsgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBsw6AgMyw4MTM7IDI1JSBk4buvIGxp4buHdSBuaOG7jyBoxqFuIDMoZ2nDoSB0cuG7iyB04bupIHBow6JuIHbhu4sgdGjhu6kgbmjhuqV0KTsgNTAlIGThu68gbGnhu4d1IG5o4buPIGjGoW4gNCAoZ2nDoSB0cuG7iyB0cnVuZyB24buLKTsgNzUlIGThu68gbGnhu4d1IG5o4buPIGjGoW4gNSAoZ2nDoSB0cuG7iyB04bupIHBow6JuIHbhu4sgdGjhu6kgYmEpDQoNCiogVOG7lW5nIG3hu6ljIGNoaSB0acOqdSB0aOG6uyB0w61uIGThu6VuZyAoVG90YWxfVHJhbnNfQW10KTogIGdpw6EgdHLhu4sgbmjhu48gbmjhuqV0IGPhu6dhIGThu68gbGnhu4d1IDUxMDsgZ2nDoSB0cuG7iyBs4bubbiBuaOG6pXQgbMOgIDE4LjQ4NDsgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBsw6AgNC40MDQ7IDI1JSBk4buvIGxp4buHdSBuaOG7jyBoxqFuIDIuMTU2IChnacOhIHRy4buLIHThu6kgcGjDom4gduG7iyB0aOG7qSBuaOG6pXQpOyA1MCUgZOG7ryBsaeG7h3Ugbmjhu48gaMahbiAzLjg5OSAoZ2nDoSB0cuG7iyB0cnVuZyB24buLKTsgNzUlIGThu68gbGnhu4d1IG5o4buPIGjGoW4gNC43NDEgKGdpw6EgdHLhu4sgdOG7qSBwaMOibiB24buLIHRo4bupIGJhKQ0KDQoqIEjhuqFuIG3hu6ljIHRo4bq7IHTDrW4gZOG7pW5nIChDcmVkaXRfTGltaXQpOmdpw6EgdHLhu4sgbmjhu48gbmjhuqV0IGPhu6dhIGThu68gbGnhu4d1IDEuNDM4OyBnacOhIHRy4buLIGzhu5tuIG5o4bqldCBsw6AgMzQuNTE2OyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGzDoCA4LjYzMjsgMjUlIGThu68gbGnhu4d1IG5o4buPIGjGoW4gMi41NTUgKGdpw6EgdHLhu4sgdOG7qSBwaMOibiB24buLIHRo4bupIG5o4bqldCk7IDUwJSBk4buvIGxp4buHdSBuaOG7jyBoxqFuIDQuNTQ5IChnacOhIHRy4buLIHRydW5nIHbhu4spOyA3NSUgZOG7ryBsaeG7h3Ugbmjhu48gaMahbiAxMS4wNjggKGdpw6EgdHLhu4sgdOG7qSBwaMOibiB24buLIHRo4bupIGJhKQ0KDQoqIFPhu5EgbOG6p24gbGnDqm4gaOG7hyBj4bunYSBuZ8OibiBow6BuZyB24bubaSBraMOhY2ggaMOgbmcgKENvbnRhY3RzX0NvdW50XzEyX21vbik6IGdpw6EgdHLhu4sgbmjhu48gbmjhuqV0IGPhu6dhIGThu68gbGnhu4d1IDA7IGdpw6EgdHLhu4sgbOG7m24gbmjhuqV0IGzDoCA2OyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGzDoCAyLDQ1NTsgMjUlIGThu68gbGnhu4d1IG5o4buPIGjGoW4gMiAoZ2nDoSB0cuG7iyB04bupIHBow6JuIHbhu4sgdGjhu6kgbmjhuqV0KTsgNTAlIGThu68gbGnhu4d1IG5o4buPIGjGoW4gMiAoZ2nDoSB0cuG7iyB0cnVuZyB24buLKTsgNzUlIGThu68gbGnhu4d1IG5o4buPIGjGoW4gMyAoZ2nDoSB0cuG7iyB04bupIHBow6JuIHbhu4sgdGjhu6kgYmEpDQoNCiogU+G7kSB0aMOhbmcga2jDtG5nIGhv4bqhdCDEkeG7mW5nIHRo4bq7IHTDrW4gZOG7pW5nIChNb250aHNfSW5hY3RpdmVfMTJfbW9uKTogIGdpw6EgdHLhu4sgbmjhu48gbmjhuqV0IGPhu6dhIGThu68gbGnhu4d1IDA7IGdpw6EgdHLhu4sgbOG7m24gbmjhuqV0IGzDoCA2OyBnacOhIHRy4buLIHRydW5nIGLDrG5oIGzDoCAyLDM0MTU7IDI1JSBk4buvIGxp4buHdSBuaOG7jyBoxqFuIDIgKGdpw6EgdHLhu4sgdOG7qSBwaMOibiB24buLIHRo4bupIG5o4bqldCk7IDUwJSBk4buvIGxp4buHdSBuaOG7jyBoxqFuIDIgKGdpw6EgdHLhu4sgdHJ1bmcgduG7iyk7IDc1JSBk4buvIGxp4buHdSBuaOG7jyBoxqFuIDMgKGdpw6EgdHLhu4sgdOG7qSBwaMOibiB24buLIHRo4bupIGJhKQ0KDQoqKkJp4buDdSDEkeG7kyBIaXN0b2dyYW0qKg0KDQpgYGB7cn0NCmhpc3QobWFjJFRvdGFsX0FtdF9DaG5nX1E0X1ExKQ0KYGBgDQoNClRoYXkgxJHhu5VpIHPhu5EgbMaw4bujbmcgZ2lhbyBk4buLY2ggdGjhursgdMOtbiBk4bulbmcgcXXDvSA0IHNvIHbhu5tpIHF1w70gMSAoVG90YWxfQ3RfQ2huZ19RNF9RMSkgbuG6sW0gdHJvbmcgcGjhuqFtIHZpIDAsNSDEkeG6v24gMSB4deG6pXQgaGnhu4duIG5oaeG7gXUgbmjhuqV0Lg0KDQpgYGB7cn0NCmhpc3QobWFjJEF2Z19VdGlsaXphdGlvbl9SYXRpbykNCmBgYA0KIA0KIFThu7cgbOG7hyBjaGkgdGnDqnUgdGjhursgdHJ1bmcgYsOsbmggKEF2Z19VdGlsaXphdGlvbl9SYXRpbykgcGjDom4gYuG7kSDEkeG7gXUg4bufIHBo4bqhbSB2aSBnacOhIHRy4buLIHThu6sNCjAuMSDEkeG6v24gMSB2w6AgcGjhuqFtIHZpICBnacOhIHRy4buLIHThu6sgMCDEkeG6v24gMCw1IHh14bqldCBoaeG7h24gbmhp4buBdSBuaOG6pXQuDQoNCmBgYHtyfQ0KaGlzdChtYWMkVG90YWxfVHJhbnNfQW10KQ0KYGBgDQoNClThu5VuZyBt4bupYyBjaGkgdGnDqnUgdGjhursgdMOtbiBk4bulbmcgKFRvdGFsX1RyYW5zX0FtdCkg4bufIHBo4bqhbSB2aSB04burIDEwMDAgxJHhur9uIDUwMDAgbMOgIG5oaeG7gXUgbmjhuqV0Lg0KDQpgYGB7cn0NCmhpc3QobWFjJENyZWRpdF9MaW1pdCkNCmBgYA0KDQrEkGEgc+G7kSBraMOhY2ggaMOgbmcgY8OzIGjhuqFuIG3hu6ljIHRo4bq7IHTDrW4gZOG7pW5nIChDcmVkaXRfTGltaXQpIOG7nyBraG/huqNuZyBiw6kgaMahbiA1MDAwDQoNCiMjIFRo4buRbmcga8OqIG3DtCB04bqjIDIgYmnhur9uDQoNCiMjIyBQaMOibiB0w61jaCB2aeG7h2Mga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gdGhlbyBnaeG7m2kgdMOtbmgNCg0KIyMjIyBM4bqtcCBi4bqjbmcgdOG6p24gc3XhuqV0DQoNCmBgYHtyfQ0Kcm08LXRhYmxlKG1hYyRHZW5kZXIsbWFjJEF0dHJpdGlvbl9GbGFnKQ0Kcm0NCmBgYA0KKiA5MzAga2jDoWNoIGjDoG5nIG7hu68ga2jDtG5nIGPDsm4gc+G7rSBk4bulbmcgdGjhursgdMOtbiBk4bulbmcgdsOgIDQ0Mjgga2jDoWNoIGjDoG5nIG7hu68gduG6q24gY8OybiBz4butIGThu6VuZyB0aOG6uyB0w61uIGThu6VuZw0KKiA2OTcga2jDoWNoIGjDoG5nIG5hbSBraMO0bmcgY8OybiBz4butIGThu6VuZyB0aOG6uyB0w61uIGThu6VuZyB2w6AgNDA3MiBraMOhY2ggaMOgbmcgbmFtIHbhuqtuIGPDsm4gc+G7rSBk4bulbmcgdGjhursgdMOtbiBk4bulbmcNCg0KDQpgYGB7cn0NCmdncGxvdChtYWMsIGFlcyhHZW5kZXIsIGZpbGwgPSBBdHRyaXRpb25fRmxhZykpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAnZG9kZ2UnKQ0KYGBgDQoNCiMjIyMgUuG7p2kgcm8gdMawxqFuZyDEkeG7kWkNCg0KKipSZWxhdGl2ZSByaXNrKioNCg0KYGBge3J9DQpSZWxSaXNrKHJtKQ0KYGBgDQpU4bu3IGzhu4cga2jDoWNoIGjDoG5nIG7hu68ga2jDtG5nIGPDsm4gc+G7rSBk4bulbmcgdGjhursgdMOtbiBk4bulbmcgYuG6sW5nIDExOCw3NiUgdOG7tyBs4buHIGtow6FjaCBow6BuZyBuYW0ga2jDtG5nIGPDsm4gc+G7rSBk4bulbmcgdGjhursgdMOtbiBk4bulbmcuDQoNCioqUmlzayByYXRpbyoqDQoNCmBgYHtyfQ0KZXBpdGFiKHJtLG1ldGhvZD0ncmlza3JhdGlvJyxyZXY9J2MnKQ0KYGBgDQpU4bu3IGzhu4cga2jDoWNoIGjDoG5nIG5hbSBraMO0bmcgY8OybiBz4butIGThu6VuZyB0aOG6uyB0w61uIGThu6VuZyBi4bqxbmcgODQsMiUgdOG7tyBs4buHIGtow6FjaCBow6BuZyBu4buvIGtow7RuZyBjw7JuIHPhu60gZOG7pW5nIHRo4bq7IHTDrW4gZOG7pW5nLg0KDQojIyMjIE9kZCByYXRpbw0KDQpgYGB7cn0NCmVwaXRhYihybSwgbWV0aG9kID0gJ29kZHNyYXRpbycsIHJldj0nYycpIA0KYGBgDQpU4bu3IGzhu4cgcuG7nWkgYuG7jyBzbyB24bubaSB04bu3IGzhu4cgY8OybiBz4butIGThu6VuZyB0aOG6uyB0w61uIGThu6VuZyBj4bunYSBraMOhY2ggaMOgbmcgbuG7ryBi4bqxbmcgODEsNDk5JSB04bu3IGzhu4cgcuG7nWkgYuG7jyBzbyB24bubaSB04bu3IGzhu4cgY8OybiBz4butIGThu6VuZyB0aOG6uyB0w61uIGThu6VuZyBj4bunYSBraMOhY2ggaMOgbmcgbmFtLg0KDQojIyMgUGjDom4gdMOtY2ggdmnhu4djIGtow6FjaCBow6BuZyBy4budaSBi4buPIHRoZW8gdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuDQoNCiMjIyMgQuG6o25nIHThuqduIHN14bqldCANCg0KYGBge3J9DQpybTE8LXRhYmxlKG1hYyRFZHVjYXRpb25fTGV2ZWwsbWFjJEF0dHJpdGlvbl9GbGFnKQ0Kcm0xDQpgYGANCiogVHJvbmcgc+G7kSBraMOhY2ggaMOgbmcgdOG7kXQgbmdoaeG7h3AgY2FvIMSR4bqzbmcgY8OzIDE1NCBraMOhY2ggaMOgbmcga2jDtG5nIGPDsm4gc+G7rSBk4bulbmcgdGjhursgdMOtbiBk4bulbmcoIHLhu51pIGLhu48gKSB0cm9uZyBraGkgODU5IGtow6FjaCBow6BuZyB24bqrbiBjw7JuIHPhu60gZOG7pW5nLg0KKiBUcm9uZyBz4buRIGtow6FjaCBow6BuZyB04buRdCBuZ2hp4buHcCB0aeG6v24gc8SpICBjw7MgOTUga2jDoWNoIGjDoG5nIGtow7RuZyBjw7JuIHPhu60gZOG7pW5nIHRo4bq7IHTDrW4gZOG7pW5nKCBy4budaSBi4buPICkgdHJvbmcga2hpIDM1NiBraMOhY2ggaMOgbmcgduG6q24gY8OybiBz4butIGThu6VuZy4NCiogVHJvbmcgc+G7kSBraMOhY2ggaMOgbmcgdOG7kXQgbmdoaeG7h3AgxJHhuqFpIGjhu41jIGPDsyA0ODcga2jDoWNoIGjDoG5nIGtow7RuZyBjw7JuIHPhu60gZOG7pW5nIHRo4bq7IHTDrW4gZOG7pW5nKCBy4budaSBi4buPICkgdHJvbmcga2hpIDI2NDEga2jDoWNoIGjDoG5nIHbhuqtuIGPDsm4gc+G7rSBk4bulbmcuDQoqIFRyb25nIHPhu5Ega2jDoWNoIGjDoG5nIHThu5F0IG5naGnhu4dwIFRIUFQgY8OzIDMwNiBraMOhY2ggaMOgbmcga2jDtG5nIGPDsm4gc+G7rSBk4bulbmcgdGjhursgdMOtbiBk4bulbmcoIHLhu51pIGLhu48gKSB0cm9uZyBraGkgMTcwNyBraMOhY2ggaMOgbmcgduG6q24gY8OybiBz4butIGThu6VuZy4NCiogVHJvbmcgc+G7kSBraMOhY2ggaMOgbmcgdOG7kXQgbmdoaeG7h3Agc2F1IMSR4bqhaSBo4buNYyBjw7MgOTIga2jDoWNoIGjDoG5nIGtow7RuZyBjw7JuIHPhu60gZOG7pW5nIHRo4bq7IHTDrW4gZOG7pW5nKCBy4budaSBi4buPICkgdHJvbmcga2hpIDQyNCBraMOhY2ggaMOgbmcgduG6q24gY8OybiBz4butIGThu6VuZy4NCiogVHJvbmcgc+G7kSBraMOhY2ggaMOgbmcga2jDtG5nIMSRaSBo4buNYyBjw7MgMjM3IGtow6FjaCBow6BuZyBraMO0bmcgY8OybiBz4butIGThu6VuZyB0aOG6uyB0w61uIGThu6VuZyggcuG7nWkgYuG7jyApIHRyb25nIGtoaSAxMjUwIGtow6FjaCBow6BuZyB24bqrbiBjw7JuIHPhu60gZOG7pW5nLg0KKiBUcm9uZyBz4buRIGtow6FjaCBow6BuZyBjw7MgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuIGtow6FjIGPDsyAyNTYga2jDoWNoIGjDoG5nIGtow7RuZyBjw7JuIHPhu60gZOG7pW5nIHRo4bq7IHTDrW4gZOG7pW5nKCBy4budaSBi4buPICkgdHJvbmcga2hpIDEyNjMga2jDoWNoIGjDoG5nIHbhuqtuIGPDsm4gc+G7rSBk4bulbmcuDQoNCg0KYGBge3J9DQpnZ3Bsb3QobWFjLCBhZXMoRWR1Y2F0aW9uX0xldmVsLCBmaWxsID0gQXR0cml0aW9uX0ZsYWcpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gJ2RvZGdlJykgDQoNCmBgYA0KDQpOaMOsbiB2w6BvIGJp4buDdSDEkeG7kyB0YSB0aOG6pXkga2jDoWNoIGjDoG5nIGPDsyB0csOsbmggxJHhu5kgaOG7jWMgduG6pW4gxJHhuqFpIGjhu41jIGPDsyB04bu3IGzhu4cgcuG7nWkgYuG7jyBz4butIGThu6VuZyB0aOG6uyB0w61uIGThu6VuZyBjYW8gbmjhuqV0Lg0KDQojIyMgUGjDom4gdMOtY2ggdmnhu4djIGtow6FjaCBow6BuZyBy4budaSBi4buPIHRoZW8gxJHhu5kgdHXhu5VpDQoNCmBgYHtyfQ0KZ2dwbG90KG1hYywgYWVzKHggPSBDdXN0b21lcl9BZ2UsIGZpbGwgPSBBdHRyaXRpb25fRmxhZykpICsgdGhlbWVfYncoKSsgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSA4KSsgbGFicyh5ID0gIkN1c3RvbWVyIGNvdW50IiwgeCA9ICJBZ2UiLCB0aXRsZSA9ICJCYW5rY2h1bmVycyByYXRlcyBieSBhZ2UiKQ0KYGBgDQoNCk5ow6xuIHbDoG8gaMOsbmggdGEgdGjhuqV5IMSRYSBz4buRIGtow6FjaCBow6BuZyBy4budaSBi4buPIHRo4bq7IHTDrW4gZOG7pW5nIOG7nyDEkeG7mSB0deG7lWkgNDAtNjAuDQoNCiMjIyBQaMOibiB0w61jaCB2aeG7h2Mga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gdGhlbyB04buVbmcgbeG7qWMgY2hpIHRpw6p1IHRo4bq7IHTDrW4gZOG7pW5nDQoNCmBgYHtyfQ0KZ2dwbG90KG1hYywgYWVzKHggPSBUb3RhbF9UcmFuc19BbXQsIGZpbGwgPSBBdHRyaXRpb25fRmxhZykpICsgdGhlbWVfYncoKSsgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSA4KSsgbGFicyh5ID0gIkN1c3RvbWVyIGNvdW50IiwgeCA9ICJUcmFuc2FjdGlvbiIsIHRpdGxlID0gIkJhbmtjaHVuZXJzIHJhdGVzIGJ5IHRyYW5zYWN0aW9uIikNCmBgYA0KDQpOaMOsbiB2w6BvIMSR4buTIHRo4buLIHRhIHRo4bqleSDEkWEgc+G7kSBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBnaeG6o20gZOG6p24gdGhlbyB04buVbmcgbeG7qWMgY2hpIHRpw6p1IHRo4bq7IHTDrW4gZOG7pW5nLiBLaMOhY2ggaMOgbmcgY8OzIHThu5VuZyBt4bupYyBjaGkgdGnDqnUgdGjhursgdMOtbiBk4bulbmcgbuG6sW0g4bufIGtob+G6o25nIGTGsOG7m2kgNTAwMCBjw7MgdOG7tyBs4buHIHLhu51pIGLhu48gdGjhursgdMOtbiBk4bulbmcgY2FvIG5o4bqldC4NCg0KDQojIyMgUGjDom4gdMOtY2ggdmnhu4djIGtow6FjaCBow6BuZyBy4budaSBi4buPIHRoZW8gZ2nhu5tpIHTDrW5oIHbDoCBsb+G6oWkgdGjhursgdMOtbiBk4bulbmcNCg0KIyMjIyBC4bqjbmcgdOG6p24gc3XhuqV0DQoNCmBgYHtyfQ0Kcm0yPC1mdGFibGUobWFjJERlcGVuZGVudF9jb3VudCwgbWFjJEdlbmRlciAsbWFjJEF0dHJpdGlvbl9GbGFnKQ0Kcm0yDQpgYGANCiogxJDhu5FpIHbhu5tpIGtow6FjaCBow6BuZyBjw7MgMCBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIA0KDQogICAgKyA3NyBraMOhY2ggaMOgbmcgbuG7ryBy4budaSBi4buPLCA0MDcgbmfGsOG7nWkgduG6q24gY8OybiBz4butIGThu6VuZyB0aOG6uw0KICAgICsgNTgga2jDoWNoIGjDoG5nIG5hbSBy4budaSBi4buPLCAzNjIgbmfGsOG7nWkgduG6q24gY8OybiBz4butIGThu6VuZyB0aOG6uw0KICAgDQoqIMSQ4buRaSB24bubaSBraMOhY2ggaMOgbmcgY8OzIDEgbmfGsOG7nWkgcGjhu6UgdGh14buZYyANCg0KICAgICsgMTY5IGtow6FjaCBow6BuZyBu4buvIHLhu51pIGLhu48sIDgyNyBuZ8aw4budaSB24bqrbiBjw7JuIHPhu60gZOG7pW5nIHRo4bq7DQogICAgKyAxMDAga2jDoWNoIGjDoG5nIG5hbSBy4budaSBi4buPLCA3NDIgbmfGsOG7nWkgduG6q24gY8OybiBz4butIGThu6VuZyB0aOG6uw0KDQoqIMSQ4buRaSB24bubaSBraMOhY2ggaMOgbmcgY8OzIDIgbmfGsOG7nWkgcGjhu6UgdGh14buZYyANCg0KICAgICsgMjI4IGtow6FjaCBow6BuZyBu4buvIHLhu51pIGLhu48sIDExNjAgbmfGsOG7nWkgduG6q24gY8OybiBz4butIGThu6VuZyB0aOG6uw0KICAgICsgMTg5IGtow6FjaCBow6BuZyBuYW0gcuG7nWkgYuG7jywgMTA3OCBuZ8aw4budaSB24bqrbiBjw7JuIHPhu60gZOG7pW5nIHRo4bq7DQoNCiogxJDhu5FpIHbhu5tpIGtow6FjaCBow6BuZyBjw7MgMyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIA0KDQogICAgKyAyNzIga2jDoWNoIGjDoG5nIG7hu68gcuG7nWkgYuG7jywgMTE0NCBuZ8aw4budaSB24bqrbiBjw7JuIHPhu60gZOG7pW5nIHRo4bq7DQogICAgKyAyMTAga2jDoWNoIGjDoG5nIG5hbSBy4budaSBi4buPLCAxMTA2IG5nxrDhu51pIHbhuqtuIGPDsm4gc+G7rSBk4bulbmcgdGjhursNCg0KKiDEkOG7kWkgduG7m2kga2jDoWNoIGjDoG5nIGPDsyA0IG5nxrDhu51pIHBo4bulIHRodeG7mWMgDQoNCiAgICArIDE1NCBraMOhY2ggaMOgbmcgbuG7ryBy4budaSBi4buPLCA2OTUgbmfGsOG7nWkgduG6q24gY8OybiBz4butIGThu6VuZyB0aOG6uw0KICAgICsgMTA2IGtow6FjaCBow6BuZyBuYW0gcuG7nWkgYuG7jywgNjE5IG5nxrDhu51pIHbhuqtuIGPDsm4gc+G7rSBk4bulbmcgdGjhursNCiAgICANCiogxJDhu5FpIHbhu5tpIGtow6FjaCBow6BuZyBjw7MgNSBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIA0KDQogICAgKyAzMCBraMOhY2ggaMOgbmcgbuG7ryBy4budaSBi4buPLCAxOTUgbmfGsOG7nWkgduG6q24gY8OybiBz4butIGThu6VuZyB0aOG6uw0KICAgICsgMzQga2jDoWNoIGjDoG5nIG5hbSBy4budaSBi4buPLCAxNjUgbmfGsOG7nWkgduG6q24gY8OybiBz4butIGThu6VuZyB0aOG6uw0KDQoNCmBgYHtyfQ0KZ2dwbG90KG1hYywgYWVzKHggPSBHZW5kZXIsIGZpbGwgPSBBdHRyaXRpb25fRmxhZykpICsNCiAgdGhlbWVfYncoKSsNCiAgZmFjZXRfd3JhcCh+IERlcGVuZGVudF9jb3VudCkrDQogIGdlb21fYmFyKCkrDQogIGxhYnMoeSA9ICJDdXN0b21lciBjb3VudCIsDQogICAgICAgdGl0bGUgPSAiQmFua2NodW5lcnMgcmF0ZXMgYnkgR2VuZGVyIGFuZCBEZXBlbmRlbnRfY291bnQiKQ0KYGBgDQoNCk5ow6xuIHbDoG8gaMOsbmggduG6vSB0YSB0aOG6pXk6IGtow6FjaCBow6BuZyBjw7MgMyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIGPDsyB04bu3IGzhu4cgcuG7nWkgYuG7jyBjYW8gbmjhuqV0IHRyb25nIGtoaSBraMOhY2ggaMOgbmcgY8OzIDUgbmfGsOG7nWkgcGjhu6UgdGh14buZYyBjw7MgdOG7tyBs4buHIHLhu51pIGLhu48gdGjhuqVwIG5o4bqldC4gVsOgIHThu7cgbOG7hyBy4budaSBi4buPIGPhu6dhIGtow6FjaCBow6BuZyBu4buvIMSR4buBdSBjYW8gaMahbiBraMOhY2ggaMOgbmcgbmFtIChuZ2/huqFpIHRy4burIGtow6FjaCBow6BuZyBjw7MgNSBuZ8aw4budaSBwaOG7pSB0aHXhu5ljKS4NCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQojIFRo4buRbmcga8OqIHN1eSBkaeG7hW4gY2hvIGThu68gbGnhu4d1IMSR4buLbmggdMOtbmgNCg0KIyMgS2nhu4NtIMSR4buLbmggdMOtbmggxJHhu5ljIGzhuq1wIGNobyAyIGJp4bq/biDEkeG7i25oIHTDrW5oDQoNCioqS2nhu4NtIMSR4buLbmggdMOtbmggxJHhu5ljIGzhuq1wIGNobyAyIGJp4bq/biBBdHRyaXRpb25fRmxhZyB2w6AgR2VuZGVyKioNCg0KYGBge3J9DQpjaGlzcS50ZXN0KHRhYmxlKG1hYyRBdHRyaXRpb25fRmxhZyxtYWMkR2VuZGVyKSkNCmBgYA0KDQpW4bubaSBwX3ZhbHVlIDwgNSUsIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBIMCBkbyDEkcOzIGvhur90IGx14bqtbiB2aeG7h2Mga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gY8OzIGxpw6puIHF1YW4gdOG7m2kgZ2nhu5tpIHTDrW5oIGPhu6dhIGtow6FjaCBow6BuZy4NCg0KKipLaeG7g20gxJHhu4tuaCB0w61uaCDEkeG7mWMgbOG6rXAgY2hvIDIgYmnhur9uIEF0dHJpdGlvbl9GbGFnIHbDoCBJbmNvbWVfQ2F0ZWdvcnkqKg0KDQpgYGB7cn0NCmNoaXNxLnRlc3QodGFibGUobWFjJEF0dHJpdGlvbl9GbGFnLG1hYyRJbmNvbWVfQ2F0ZWdvcnkpKQ0KYGBgDQoNClF1YSBr4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaCBjaG8gdGjhuqV5IHZp4buHYyBraMOhY2ggaMOgbmcgcuG7nWkgYuG7jyBjw7MgbGnDqm4gcXVhbiB04bubaSBt4bupYyB0aHUgbmjhuq1wIGPhu6dhIGtow6FjaCBow6BuZyAocF92YWx1ZTw1JSkuDQoNCioqS2nhu4NtIMSR4buLbmggdMOtbmggxJHhu5ljIGzhuq1wIGNobyAyIGJp4bq/biBBdHRyaXRpb25fRmxhZyB2w6AgRWR1Y2F0aW9uX0xldmVsKioNCg0KYGBge3J9DQpjaGlzcS50ZXN0KHRhYmxlKG1hYyRBdHRyaXRpb25fRmxhZyxtYWMkRWR1Y2F0aW9uX0xldmVsKSkNCmBgYA0KVuG7m2kgbeG7qWMgw70gbmdoxKlhIDUlIGNoxrBhIMSR4bunIGPGoSBz4bufIGvhur90IGx14bqtbiB2aeG7h2Mga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gY8OzIGxpw6puIHF1YW4gdOG7m2kgdHLDrG5oIMSR4buZIGjhu41jIHbhuqVuDQoNCg0KKipLaeG7g20gxJHhu4tuaCB0w61uaCDEkeG7mWMgbOG6rXAgY2hvIDIgYmnhur9uIEF0dHJpdGlvbl9GbGFnIHbDoCBDYXJkX0NhdGVnb3J5KioNCg0KYGBge3J9DQpjaGlzcS50ZXN0KHRhYmxlKG1hYyRBdHRyaXRpb25fRmxhZyxtYWMkQ2FyZF9DYXRlZ29yeSkpDQpgYGANClF1YSBr4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaCBjaG8gdGjhuqV5IGNoxrBhIMSR4bunIGPGoSBz4bufIGvhur90IGx14bqtbiB2aeG7h2Mga2jDoWNoIGjDoG5nIHLhu51pIGLhu48gY8OzIGxpw6puIHF1YW4gdOG7m2kgbG/huqFpIHRo4bq7IHTDrW4gZOG7pW5nDQoNCiMjIEtob+G6o25nIMaw4bubYyBsxrDhu6NuZyBjaG8gdOG7tyBs4buHDQoNCiogQsOgaSB0b8OhbiAxOiAgxq/hu5tjIGzGsOG7o25nIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgbmFtIHLhu51pIGLhu48gdGjhursgdMOtbiBk4bulbmcgxJHhu5NuZyB0aOG7nWkga2nhu4NtIMSR4buLbmggeGVtIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgbmFtIHLhu51pIGLhu48gdGjhursgdMOtbiBk4bulbmcgY8OzIHBo4bqjaSBsw6AgNDAlIGtow7RuZz8NCg0KYGBge3J9DQoNCnJtPC0gbWFjW21hYyRBdHRyaXRpb25fRmxhZyA9PSJBdHRyaXRlZCBDdXN0b21lciIsXQ0Kcm0xPC0gcm1bcm0kR2VuZGVyID09ICJNIixdDQpwcm9wLnRlc3QobGVuZ3RoKHJtMSRHZW5kZXIpLCBsZW5ndGgocm0kR2VuZGVyKSwgcCA9IDAuNCkNCmBgYA0KVuG7m2kga2hv4bqjbmcgdGluIGPhuq15IDk1JSB14bubYyBsxrDhu6NuZyB04bu3IGzhu4cga2jDoWNoIGjDoG5nIG5hbSBy4budaSBi4buPIHRo4bq7IHTDrW4gZOG7pW5nIG7hurFtIHRyb25nIGtob+G6o25nIHThu6sgMCw0MDQyIMSR4bq/biAwLDQ1Mjg5DQoNCnAtdmFsdWUgPCA1JSwgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEgwLiBEbyDEkcOzICB04bu3IGzhu4cga2jDoWNoIGjDoG5nIG5hbSBy4budaSBi4buPIHRo4bq7IHTDrW4gZOG7pW5nIGtow7RuZyBi4bqxbmcgNDAlIHbhu5tpIG3hu6ljIMO9IG5naMSpYSA1JS4NCg0KDQoqIELDoGkgdG/DoW4gMjogxq/hu5tjIGzGsOG7o25nIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgbuG7ryBy4budaSBi4buPIHRo4bq7IHTDrW4gZOG7pW5nIMSR4buTbmcgdGjhu51pIGtp4buDbSDEkeG7i25oIHhlbSB04bu3IGzhu4cga2jDoWNoIGjDoG5nIG7hu68gcuG7nWkgYuG7jyB0aOG6uyB0w61uIGThu6VuZyBjw7MgcGjhuqNpIGzDoCA2MCUga2jDtG5nPw0KDQpgYGB7cn0NCnJmPC0gbWFjW21hYyRBdHRyaXRpb25fRmxhZyA9PSJBdHRyaXRlZCBDdXN0b21lciIsXQ0KcmYxPC0gcm1bcm0kR2VuZGVyID09ICJGIixdDQpwcm9wLnRlc3QobGVuZ3RoKHJtMSRHZW5kZXIpLCBsZW5ndGgocm0kR2VuZGVyKSwgcCA9IDAuNikNCmBgYA0KDQpW4bubaSBraG/huqNuZyB0aW4gY+G6rXkgOTUlIHXhu5tjIGzGsOG7o25nIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgbuG7ryBy4budaSBi4buPIHRo4bq7IHTDrW4gZOG7pW5nIG7hurFtIHRyb25nIGtob+G6o25nIHThu6sgMCw1NDcxIMSR4bq/biAwLDU5NTcNCg0KcC12YWx1ZSA8IDUlLCBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSDAuIERvIMSRw7MgIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgbuG7ryBy4budaSBi4buPIHRo4bq7IHTDrW4gZOG7pW5nIGtow7RuZyBi4bqxbmcgNjAlIHbhu5tpIG3hu6ljIMO9IG5naMSpYSA1JS4NCg0KDQoqIELDoGkgdG/DoW4gMzogxq/hu5tjIGzGsOG7o25nIHPhu7EgY2jDqm5oIGzhu4djaCB24buBIHThu7cgbOG7hyBy4budaSBi4buPIHRo4bq7IHTDrW4gZOG7pW5nIGdp4buvYSBraMOhY2ggaMOgbmcgbmFtIHbDoCBu4buvLiDEkOG7k25nIHRo4budaSB0aOG7sWMgaGnhu4duIGLDoGkgdG/DoW4ga2nhu4NuIMSR4buLbmggc+G7sSBjaMOqbmggbOG7h2NoIG7DoHkNCg0KYGBge3J9DQoNCmEgPC0gYyhucm93KHJtKSwgbnJvdyhyZikpDQpiIDwtIGMobnJvdyhybTEpLCBucm93KHJmMSkpDQoNCnByb3AudGVzdChiLGEpDQpgYGANClBfdmFsdWUgPCA1JSwgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEgwLCBkbyDEkcOzIGPDsyBz4buxIGNow6puaCBs4buHbmggZ2nhu69hIHThu7cgbOG7hyBraMOhY2ggaMOgbmcgbmFtIHbDoCBu4buvIHLhu51pIGLhu48gdGjhursgdMOtbiBk4bulbmcuDQoNCktob+G6o25nIHRpbiBj4bqteSA5NSUgY2hvIGNow6puaCBs4buHY2ggdOG7tyBs4buHIG7hurFtIHRyb25nIGtob+G6o25nIHThu6sgLTAsMTc3ODI3NyDEkeG6v24gLTAsMTA4NTg5Lg0KDQoNCg0KDQoNCg0KDQojIE1hIHRy4bqtbiBo4buHIHPhu5EgdMawxqFuZyBxdWFuDQoNCmBgYHtyfQ0KDQoNCiMgQ2jhu41uIGPDoWMgYmnhur9uIHPhu5EgbGnDqm4gdOG7pWMgdHJvbmcgbcO0IGjDrG5oDQpjb250aW51b3VzX3ZhcnMgPC0gbWFjWywgc2FwcGx5KG1hYywgaXMubnVtZXJpYyldDQoNCiMgVMOtbmggbWEgdHLhuq1uIHTGsMahbmcgcXVhbg0KY29yX21hdHJpeCA8LSBjb3IoY29udGludW91c192YXJzKQ0KY29yX21hdHJpeA0KDQpgYGANCg0KUXVhIHRy4bqtbiBo4buHIHPhu5EgdMawxqFuZyBxdWFuIGdp4buvYSBjw6FjIGJp4bq/biB0YSB0aOG6pXkgY8OzIG3hu5FpIHTGsMahbmcgcXVhbiBt4bqhbmggZ2nhu69hIGPDoWMgY+G6t3AgYmnhur9uKEN1c3RvbWVyX0FnZSwgTW9udGhzX29uX2Jvb2spOyAoVG90YWxfUmV2b3ZsaW5nX2JhbCwgQXZnX3V0aWxpemF0aW9uX1JhdGlvKSB2w6AgKFRvdGFsX3RyYW5zX2FtdCwgdG90YWxfdHJhbnNfY3QpDQoNCiMgxq/hu5tjIGzGsOG7o25nIG3DtCBow6xuaCBo4buTaSBxdXkNCg0KIyMgTcO0IGjDrG5oIGjhu5NpIHF1eSBsb2dpdA0KDQojIyMgTcO0IGjDrG5oIDENCg0KTcO0IGjDrG5oIGPDsyBiaeG6v24gcGjhu6UgdGh14buZYzogYXR0cml0aW9uX2ZsYWcgdsOgIGPDoWMgYmnhur9uIMSR4buZYyBs4bqtcCBiYW8gZ+G7k20gMyBiaeG6v24gxJHhu4tuaCB0w61uaDogZ2VuZGVyLCBJbmNvbWVfY2F0ZWdvcnksIGRlcGVuZGVudF9jb3VudDsgdOG6pXQgY+G6oyBjw6FjIGJp4bq/biDEkeG7i25oIGzGsOG7o25nIHRyb25nIGLhu5kgZGF0YS4NCmBgYHtyfQ0KbWFjMSA8LSBtYWMgJT4lIHNlbGVjdCgtYyhDTElFTlROVU0sIE1hcml0YWxfU3RhdHVzLCBFZHVjYXRpb25fTGV2ZWwsIENhcmRfQ2F0ZWdvcnkpKQ0KDQpzZXQuc2VlZCg0MikgIA0Kc3BsaXQgPC0gc2FtcGxlLnNwbGl0KG1hYzEkQXR0cml0aW9uX0ZsYWcsIFNwbGl0UmF0aW8gPSAwLjgpDQp0cmFpbl9kYXRhMSA8LSBzdWJzZXQobWFjMSwgc3BsaXQgPT0gVFJVRSkNCnRlc3RfZGF0YTEgPC0gc3Vic2V0KG1hYzEsIHNwbGl0ID09IEZBTFNFKQ0KbGV2ZWxzKG1hYzEkQXR0cml0aW9uX0ZsYWcpDQptYWMxJEF0dHJpdGlvbl9GbGFnIDwtIGZhY3RvcihtYWMxJEF0dHJpdGlvbl9GbGFnLCBsZXZlbHMgPSBjKCJFeGlzdGluZyBDdXN0b21lciIsICJBdHRyaXRlZCBDdXN0b21lciIpKQ0KYGBgDQoNCmBgYHtyfQ0KDQptaDEgPC0gZ2xtKEF0dHJpdGlvbl9GbGFnIH4uLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gJ2xvZ2l0JyksIGRhdGEgPSB0cmFpbl9kYXRhMSkNCg0Kc3VtbWFyeShtaDEpDQoNCiMgS2nhu4NtIMSR4buLbmggc+G7sSBwaMO5IGjhu6NwIGPhu6dhIG3DtCBow6xuaCBi4bqxbmcgY8OhY2ggdMOtbmggZ2nDoSB0cuG7iyBQcm9iKExSIHN0YXRpc3RpYykNCmxyX3Rlc3QgPC0gYW5vdmEobWgxLCB0ZXN0ID0gIkNoaXNxIikNCg0KIyBM4bqleSBnacOhIHRy4buLIFByb2IoTFIgc3RhdGlzdGljKQ0KcF92YWx1ZSA8LSBscl90ZXN0JFByWzJdIA0KcF92YWx1ZQ0KDQpgYGANCg0KKipLaeG7g20gxJHhu4tuaCBz4buxIHBow7kgaMahcCBj4bunYSBtw7QgaMOsbmgqKg0KDQpHaeG6oyB0aHV54bq/dCBIMDogbcO0IGjDrG5oIGtow7RuZyBwaMO5IGjhu6NwDQpW4bubaSBQLXZhbHVlID0gIFByb2IoTFIpID0gMCwgMTczMyA+IDUlIG7Dqm4gY2jGsGEgxJHhu6cgY8ahIHPhu58gYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEgwIG7Dqm4gbcO0IGjDrG5oIGtow7RuZyBwaMO5IGjhu6NwIHbhu5tpIGThu68gbGnhu4d1Lg0KDQpI4buHIHPhu5EgdMawxqFuZyBxdWFuIGdp4buvYSBjdXN0b21lcl9hZ2UgdsOgIG1vbnRoc19vbl9ib29rIGzDoCAwLDc4ODkga2jDoSBs4bubbiBuw6puIENVc3RvbWVyX0FnZSBraMO0bmcgdGjhu7FjIHPhu7Eg4bqjbmggaMaw4bubbmcgxJHhur9uIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gdGjhursgdMOtbiBk4bulbmcgY+G7p2Ega2jDoWNoIGjDoG5nIG7Dqm4gbG/huqFpIGJp4bq/biBuw6B5Lg0KDQoNCiMjIyBNw7QgaMOsbmggMg0KIA0KQ8OhYyBiaeG6v24gdHJvbmcgbcO0IGjDrG5oIDIgbMOgIGPDoWMgYmnhur9uIHRyb25nIG3DtCBow6xuaCAxIMSRw6MgbG/huqFpIGLhu48gxJFpIGJp4bq/biBDdXN0b21lcl9hZ2UNCg0KYGBge3J9DQptYWMyPC0gbWFjMSAlPiUgc2VsZWN0KC1DdXN0b21lcl9BZ2UpDQpzZXQuc2VlZCg0MikgIA0Kc3BsaXQgPC0gc2FtcGxlLnNwbGl0KG1hYzIkQXR0cml0aW9uX0ZsYWcsIFNwbGl0UmF0aW8gPSAwLjgpDQp0cmFpbl9kYXRhMiA8LSBzdWJzZXQobWFjMiwgc3BsaXQgPT0gVFJVRSkNCnRlc3RfZGF0YTIgPC0gc3Vic2V0KG1hYzIsIHNwbGl0ID09IEZBTFNFKQ0KDQpgYGANCg0KYGBge3J9DQoNCm1oMiA8LSBnbG0oQXR0cml0aW9uX0ZsYWcgfi4sIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSwgZGF0YSA9IHRyYWluX2RhdGEyKQ0KDQpzdW1tYXJ5KG1oMikNCiMgS2nhu4NtIMSR4buLbmggc+G7sSBwaMO5IGjhu6NwIGPhu6dhIG3DtCBow6xuaCBi4bqxbmcgY8OhY2ggdMOtbmggZ2nDoSB0cuG7iyBQcm9iKExSIHN0YXRpc3RpYykNCmxyX3Rlc3QgPC0gYW5vdmEobWgyLCB0ZXN0ID0gIkNoaXNxIikNCg0KIyBM4bqleSBnacOhIHRy4buLIFByb2IoTFIgc3RhdGlzdGljKQ0KcF92YWx1ZSA8LSBscl90ZXN0JFByWzJdIA0KcF92YWx1ZQ0KDQpgYGANCioqS2nhu4NtIMSR4buLbmggc+G7sSBwaMO5IGjGoXAgY+G7p2EgbcO0IGjDrG5oKioNCg0KR2nhuqMgdGh1eeG6v3QgSDA6IG3DtCBow6xuaCBraMO0bmcgcGjDuSBo4bujcA0KVuG7m2kgUC12YWx1ZSA9ICBQcm9iKExSKSA9IDAsIDAwMDEgPCA1JSBiw6FjIGLhu48gZ2nhuqMgdGh1eeG6v3QgSDAgbsOqbiBtw7QgaMOsbmggcGjDuSBo4bujcCB24bubaSBk4buvIGxp4buHdS4NCg0KSOG7hyBz4buRIHTGsMahbmcgcXVhbiBnaeG7r2EgdG90YWxfcmV2b2x2aW5nX2JhbCB2w6AgQXZnX1V0aWxpemF0aW9uX1JhdGlvIGzDoCAwLDYyNCBraMOhIGzhu5tuIG7Dqm4gdGnhur9wIHThu6VjIGxv4bqhaSBi4buPIGJp4bq/biBBdmdfVXRpbGl6YXRpb25fUmF0aW8gdsOgIGNo4bqheSBtw7QgaMOsbmggMw0KDQojIyMgTcO0IGjDrG5oIDMNCg0KYGBge3J9DQptYWMzPC0gbWFjMiAlPiUgc2VsZWN0KC1BdmdfVXRpbGl6YXRpb25fUmF0aW8pDQpzZXQuc2VlZCg0MikgIA0Kc3BsaXQgPC0gc2FtcGxlLnNwbGl0KG1hYzMkQXR0cml0aW9uX0ZsYWcsIFNwbGl0UmF0aW8gPSAwLjgpDQp0cmFpbl9kYXRhMyA8LSBzdWJzZXQobWFjMywgc3BsaXQgPT0gVFJVRSkNCnRlc3RfZGF0YTMgPC0gc3Vic2V0KG1hYzMsIHNwbGl0ID09IEZBTFNFKQ0KDQpgYGANCg0KYGBge3J9DQoNCm1oMyA8LSBnbG0oQXR0cml0aW9uX0ZsYWcgfi4sIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAnbG9naXQnKSwgZGF0YSA9IHRyYWluX2RhdGEzKQ0KDQpzdW1tYXJ5KG1oMykNCiMgS2nhu4NtIMSR4buLbmggc+G7sSBwaMO5IGjhu6NwIGPhu6dhIG3DtCBow6xuaCBi4bqxbmcgY8OhY2ggdMOtbmggZ2nDoSB0cuG7iyBQcm9iKExSIHN0YXRpc3RpYykNCmxyX3Rlc3QgPC0gYW5vdmEobWgzLCB0ZXN0ID0gIkNoaXNxIikNCg0KIyBM4bqleSBnacOhIHRy4buLIFByb2IoTFIgc3RhdGlzdGljKQ0KcF92YWx1ZSA8LSBscl90ZXN0JFByWzJdIA0KcF92YWx1ZQ0KDQoNCmBgYA0KDQoqKktp4buDbSDEkeG7i25oIHPhu7EgcGjDuSBoxqFwIGPhu6dhIG3DtCBow6xuaCoqDQoNCkdp4bqjIHRodXnhur90IEgwOiBtw7QgaMOsbmgga2jDtG5nIHBow7kgaOG7o3ANClbhu5tpIFAtdmFsdWUgPSAgUHJvYihMUikgPSAwLCAwMDAxIDwgNSUgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEgwIG7Dqm4gbcO0IGjDrG5oIHBow7kgaOG7o3AgduG7m2kgZOG7ryBsaeG7h3UuDQoNCkjhu4cgc+G7kSB0xrDGoW5nIHF1YW4gZ2nhu69hIHRvdGFsX3RyYW5zX2FtdCB2w6AgdG90YWxfdHJhbnNfY3QgbMOgIDAsODA3MiBraMOhIGzhu5tuICwgdGnhur9wIHThu6VjIGxv4bqhaSBi4buPIGJp4bq/biB0b3RhbF90cmFuc19hbXQgdsOgIGNo4bqheSBtw7QgaMOsbmggNC4NCg0KDQoNCiMjIyBNw7QgaMOsbmggNA0KDQpgYGB7cn0NCm1hYzQ8LSBtYWMzICU+JSBzZWxlY3QoLSBUb3RhbF9UcmFuc19BbXQpDQpzZXQuc2VlZCg0MikgIA0Kc3BsaXQgPC0gc2FtcGxlLnNwbGl0KG1hYzQkQXR0cml0aW9uX0ZsYWcsIFNwbGl0UmF0aW8gPSAwLjgpDQp0cmFpbl9kYXRhNCA8LSBzdWJzZXQobWFjNCwgc3BsaXQgPT0gVFJVRSkNCnRlc3RfZGF0YTQ8LSBzdWJzZXQobWFjNCwgc3BsaXQgPT0gRkFMU0UpDQoNCmBgYA0KDQpgYGB7cn0NCg0KbWg0IDwtIGdsbShBdHRyaXRpb25fRmxhZyB+LiwgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdsb2dpdCcpLCBkYXRhID0gdHJhaW5fZGF0YTQpDQoNCnN1bW1hcnkobWg0KQ0KIyBLaeG7g20gxJHhu4tuaCBz4buxIHBow7kgaOG7o3AgY+G7p2EgbcO0IGjDrG5oIGLhurFuZyBjw6FjaCB0w61uaCBnacOhIHRy4buLIFByb2IoTFIgc3RhdGlzdGljKQ0KbHJfdGVzdCA8LSBhbm92YShtaDQsIHRlc3QgPSAiQ2hpc3EiKQ0KDQojIEzhuqV5IGdpw6EgdHLhu4sgUHJvYihMUiBzdGF0aXN0aWMpDQpwX3ZhbHVlIDwtIGxyX3Rlc3QkUHJbMl0gDQpwX3ZhbHVlDQoNCmBgYA0KKipLaeG7g20gxJHhu4tuaCBz4buxIHBow7kgaMahcCBj4bunYSBtw7QgaMOsbmgqKg0KDQpHaeG6oyB0aHV54bq/dCBIMDogbcO0IGjDrG5oIGtow7RuZyBwaMO5IGjhu6NwDQpW4bubaSBQLXZhbHVlID0gIFByb2IoTFIpID0gMCwgMDAwMSA8IDUlIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBIMCBuw6puIG3DtCBow6xuaCBwaMO5IGjhu6NwIHbhu5tpIGThu68gbGnhu4d1Lg0KDQoNCg0KDQojIyMgTOG7sWEgY2jhu41uIG3DtCBow6xuaCBwaMO5IGjhu6NwDQoNClNhdSBraGkgdGjhu7FjIGhp4buHbiBraeG7g20gxJHhu4tuaCBz4buxIHBow7kgaOG7o3AgY3XhuqMgNCBtw7QgaMOsbmggdGEgdGjhuqV5OiBNSDIsIE1IMyB2w6AgTUg0IMSR4buBdSBwaMO5IGjhu6NwIHbhu5tpIGThu68gbGnhu4d1IGRvIMSRw7MgZMO5bmcgNCB0acOqdSBjaMOtIHNhdSDEkeG7gyB0aeG6v3AgdOG7pWMgbOG7sWEgY2jhu41uIHJhIG3DtCBow6xuaCBwaMO5IGjhu6NwIG5o4bqldA0KDQojIyMjIFRpw6p1IGNo4buJIEFJQw0KDQpBSUMoTUgyKSA9IDM4NDcsMw0KDQpBSUMoTUgzKSA9IDM4NDUsNw0KDQpBSUMoTUg0KSA9IDQxMzUsOA0KDQpNw7QgaMOsbmggMyBjw7MgQUlDIG5o4buPIG5o4bqldCBuw6puIHRhIGNo4buNbiBNSDMuDQoNCiMjIyMgRGV2aWFuY2UNCg0KRGV2aWFuY2UoTUgyKSA9IDM4MDEsMw0KDQpEZXZpYW5jZShNSDMpID0gMzgwMSw3DQoNCkRldmlhbmNlKE1INCkgPSA0MTc3LDgNCg0KTcO0IGjDrG5oIDIgZGV2aWFuY2Ugbmjhu48gbmjhuqV0IG7Dqm4gdGEgY2jhu41uIE1IMg0KDQojIyMjIEJyaWVyIFNjb3JlDQoNCmBgYHtyfQ0KQnJpZXJTY29yZShtaDIpDQpCcmllclNjb3JlKG1oMykNCkJyaWVyU2NvcmUobWg0KQ0KYGBgDQpE4buxYSB2w6BvIHRpw6p1IGNow60gQnJpZXIgc2NvcmUgdGEgdGjhuqV5IE1IMyBjw7MgZ2nDoSB0cuG7iyBuaOG7jyBuaOG6pXQgbsOqbiB0YSBjaOG7jW4gTUgzDQoNCg0KDQoNCiMjIyMgTWEgdHLhuq1uIG5o4bqnbSBs4bqrbg0KDQoqKk3DtCBow6xuaCAyKioNCg0KYGBge3J9DQoNCiMgxJDDoW5oIGdpw6EgbcO0IGjDrG5oIHRyw6puIHThuq1wIGtp4buDbSB0cmENCnByZWRpY3Rpb25zIDwtIHByZWRpY3QobWgyLCBuZXdkYXRhID0gdGVzdF9kYXRhMiwgdHlwZSA9ICJyZXNwb25zZSIpDQpwcmVkaWN0ZWRfY2xhc3NlcyA8LSBpZmVsc2UocHJlZGljdGlvbnMgPiAwLjUsICIxIiwgIjAiKSAgIyBDaOG7iW5oIG5nxrDhu6FuZyBwaMOibiBsb+G6oWkNCnByZWRpY3Rpb25zMTwtZmFjdG9yKHByZWRpY3RlZF9jbGFzc2VzLCBsZXZlbHMgPSBjKCIwIiwiMSIpKQ0KYWN0dWFsPC0gZmFjdG9yKHRlc3RfZGF0YTIkQXR0cml0aW9uX0ZsYWcsIGxhYmVscyA9IGMoIjAiLCIxIikpDQpjb25mdXNpb25NYXRyaXgodGFibGUocHJlZGljdGlvbnMxLCBhY3R1YWwpKQ0KDQoNCmBgYA0KDQpNSDIgY8OzIMSR4buZIGNow61uaCB4w6FjIHRvw6BuIHRo4buDIGzDoCA4OSwyMyUsIMSR4buZIG5o4bqheSBsw6AgOTUsODglIHbDoCDEkeG7mSBoaeG7h3UgcXXhuqMgbMOgIDU0LDQ2JQ0KDQoqKk3DtCBow6xuaCAzKioNCmBgYHtyfQ0KDQojIMSQw6FuaCBnacOhIG3DtCBow6xuaCB0csOqbiB04bqtcCBraeG7g20gdHJhDQpwcmVkaWN0aW9ucyA8LSBwcmVkaWN0KG1oMywgbmV3ZGF0YSA9IHRlc3RfZGF0YTMsIHR5cGUgPSAicmVzcG9uc2UiKQ0KcHJlZGljdGVkX2NsYXNzZXMgPC0gaWZlbHNlKHByZWRpY3Rpb25zID4gMC41LCAiMSIsICIwIikgICMgQ2jhu4luaCBuZ8aw4buhbmcgcGjDom4gbG/huqFpDQpwcmVkaWN0aW9uczE8LWZhY3RvcihwcmVkaWN0ZWRfY2xhc3NlcywgbGV2ZWxzID0gYygiMCIsIjEiKSkNCmFjdHVhbDwtIGZhY3Rvcih0ZXN0X2RhdGEzJEF0dHJpdGlvbl9GbGFnLCBsYWJlbHMgPSBjKCIwIiwiMSIpKQ0KY29uZnVzaW9uTWF0cml4KHRhYmxlKHByZWRpY3Rpb25zMSwgYWN0dWFsKSkNCg0KYGBgDQoNCk1IMyBjw7MgxJHhu5kgY2jDrW5oIHjDoWMgdG/DoG4gdGjhu4MgbMOgIDg5LDMzJSwgxJHhu5kgbmjhuqF5IGzDoCA5NSw4OCUgdsOgIMSR4buZIGhp4buHdSBxdeG6oyBsw6AgNTUsMDglDQoNCk1IMyBjw7MgxJHhu5kgbmjhuqF5IGLhurFuZyB2w6AgxJHhu5kgY2jDrW5oIHjDoWMsIMSR4buZIGhp4buHdSBxdeG6oyBjYW8gaMahbiBzbyB24bubaSBNSDIgZG8gxJHDsyBjaOG7jW4gbcO0IGjDrG5oIDMNCg0KKipL4bq/dCBsdeG6rW4qKjogROG7sWEgdsOgbyA0IHRpw6p1IGNodeG6qW4gdHLDqm4gdGEgdGjhuqV5IE1IMyBsw6AgbcO0IGjDrG5oIMSRxrDhu6NjIGNo4buNbiBuaGnhu4F1IG5o4bqldCAoMyB0acOqdSBjaMOtKSBkbyDEkcOzIMSR4buDIMaw4bubYyBsxrDhu6NuZyBtw7QgaMOsbmggbG9naXQgdGEgY2jhu41uIE1IMy4NCg0KDQoNCiMjIE3DtCBow6xuaCBo4buTaSBxdXkgcHJvYml0DQoNCmBgYHtyfQ0KDQpwcm9iaXQgPC0gZ2xtKEF0dHJpdGlvbl9GbGFnIH4uLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gJ3Byb2JpdCcpLCBkYXRhID0gdHJhaW5fZGF0YTMpDQoNCnN1bW1hcnkocHJvYml0KQ0KIyBLaeG7g20gxJHhu4tuaCBz4buxIHBow7kgaOG7o3AgY+G7p2EgbcO0IGjDrG5oIGLhurFuZyBjw6FjaCB0w61uaCBnacOhIHRy4buLIFByb2IoTFIgc3RhdGlzdGljKQ0KbHJfdGVzdCA8LSBhbm92YShwcm9iaXQsIHRlc3QgPSAiQ2hpc3EiKQ0KDQojIEzhuqV5IGdpw6EgdHLhu4sgUHJvYihMUiBzdGF0aXN0aWMpDQpwX3ZhbHVlIDwtIGxyX3Rlc3QkUHJbMl0gDQpwX3ZhbHVlDQoNCmBgYA0KDQoqKktp4buDbSDEkeG7i25oIHPhu7EgcGjDuSBoxqFwIGPhu6dhIG3DtCBow6xuaCoqDQoNCkdp4bqjIHRodXnhur90IEgwOiBtw7QgaMOsbmgga2jDtG5nIHBow7kgaOG7o3ANClbhu5tpIFAtdmFsdWUgPSAgUHJvYihMUikgPSAwLCAwMDAxIDwgNSUgYsOhYyBi4buPIGdp4bqjIHRodXnhur90IEgwIG7Dqm4gbcO0IGjDrG5oIHBow7kgaOG7o3AgduG7m2kgZOG7ryBsaeG7h3UuDQoNCg0KDQoNCiMjIE3DtCBow6xuaCBjbG9nbG9nDQoNCmBgYHtyfQ0KDQpjbG9nbG9nIDwtIGdsbShBdHRyaXRpb25fRmxhZyB+LiwgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICdjbG9nbG9nJyksIGRhdGEgPSB0cmFpbl9kYXRhMykNCg0Kc3VtbWFyeShjbG9nbG9nKQ0KIyBLaeG7g20gxJHhu4tuaCBz4buxIHBow7kgaOG7o3AgY+G7p2EgbcO0IGjDrG5oIGLhurFuZyBjw6FjaCB0w61uaCBnacOhIHRy4buLIFByb2IoTFIgc3RhdGlzdGljKQ0KbHJfdGVzdCA8LSBhbm92YShjbG9nbG9nLCB0ZXN0ID0gIkNoaXNxIikNCg0KIyBM4bqleSBnacOhIHRy4buLIFByb2IoTFIgc3RhdGlzdGljKQ0KcF92YWx1ZSA8LSBscl90ZXN0JFByWzJdIA0KcF92YWx1ZQ0KDQpgYGANCg0KKipLaeG7g20gxJHhu4tuaCBz4buxIHBow7kgaMahcCBj4bunYSBtw7QgaMOsbmgqKg0KDQpHaeG6oyB0aHV54bq/dCBIMDogbcO0IGjDrG5oIGtow7RuZyBwaMO5IGjhu6NwDQpW4bubaSBQLXZhbHVlID0gIFByb2IoTFIpID0gMCwgMDAwMSA8IDUlIGLDoWMgYuG7jyBnaeG6oyB0aHV54bq/dCBIMCBuw6puIG3DtCBow6xuaCBwaMO5IGjhu6NwIHbhu5tpIGThu68gbGnhu4d1Lg0KDQojIyBM4buxYSBjaOG7jW4gZ2nhu69hIG3DtCBow6xuaCBsb2dpdCwgcHJvYml0IHbDoCBjbG9nbG9nDQoNClNhdSBraGkgdGjhu7FjIGhp4buHbiBraeG7g20gxJHhu4tuaCBz4buxIHBow7kgaOG7o3AgY3XhuqMgbcO0IGjDrG5oIGxvZ2l0LCBwcm9iaXQgdsOgIGNsb2dsb2cgdGEgdGjhuqV5IGPhuqMgMyBtw7QgaMOsbmggxJHhu4F1IHBow7kgaOG7o3AgduG7m2kgZOG7ryBsaeG7h3UsIGRvIMSRw7Mgc+G7rSBk4bulbmcgNCB0acOqdSBjaMOtIHNhdSDEkeG7gyB0w6xtIHJhIG3DtCBow6xuaCBwaMO5IGjhu6NwLg0KDQojIyMgQUlDDQoNCkFJQyhsb2dpdCkgPSAzODQ1LDcNCg0KQUlDKHByb2JpdCkgPSAzODY1LDMNCg0KQUlDKGNsb2dsb2cpID0gMzkxMCw5DQoNCk3DtCBow6xuaCBsb2dpdCBjw7MgQUlDIG5o4buPIG5o4bqldCBuw6puIHRhIGNo4buNbiBtw7QgaMOsbmggbsOgeS4NCg0KIyMjIERldmlhbmNlDQoNCkRldmlhbmNlKGxvZ2l0KSA9IDM4MDEsNw0KDQpEZXZpYW5jZShwcm9naXQpID0gMzgyMSwzDQoNCkRldmlhbmNlKGNsb2dsb2cpID0gMzg2Niw5DQoNCk3DtCBow6xuaCBsb2dpdCBjw7MgZGV2aWFuY2Ugbmjhu48gbmjhuqV0IG7Dqm4gdGEgY2jhu41uIG3DtCBow6xuaCBuw6B5DQoNCiMjIyBCcmllciBTY29yZQ0KDQpgYGB7cn0NCkJyaWVyU2NvcmUobWgzKSAjbcO0IGjDrG5oIGxvZ2l0DQpCcmllclNjb3JlKHByb2JpdCkNCkJyaWVyU2NvcmUoY2xvZ2xvZykNCg0KYGBgDQpNw7QgaMOsbmggbG9naXQgY8OzIGNo4buJIHPhu5EgQnJpZXIgbmjhu48gbmjhuqV0IG7Dqm4gdGEgY2jhu41uIG3DtCBow6xuaCBuw6B5Lg0KDQojIyMgTWEgdHLhuq1uIG5o4bqnbSBs4bqrbg0KDQojIyMjIE3DtCBow6xuaCBsb2dpdA0KDQpgYGB7Un0NCnByZWRpY3Rpb25zIDwtIHByZWRpY3QobWgzLCBuZXdkYXRhID0gdGVzdF9kYXRhMywgdHlwZSA9ICJyZXNwb25zZSIpDQpwcmVkaWN0ZWRfY2xhc3NlcyA8LSBpZmVsc2UocHJlZGljdGlvbnMgPiAwLjUsICIxIiwgIjAiKSAgIyBDaOG7iW5oIG5nxrDhu6FuZyBwaMOibiBsb+G6oWkNCnByZWRpY3Rpb25zMTwtZmFjdG9yKHByZWRpY3RlZF9jbGFzc2VzLCBsZXZlbHMgPSBjKCIwIiwiMSIpKQ0KYWN0dWFsPC0gZmFjdG9yKHRlc3RfZGF0YTMkQXR0cml0aW9uX0ZsYWcsIGxhYmVscyA9IGMoIjAiLCIxIikpDQpjb25mdXNpb25NYXRyaXgodGFibGUocHJlZGljdGlvbnMxLCBhY3R1YWwpKQ0KDQpgYGANCg0KTcO0IGjDrG5oIGxvZ2l0IGPDsyDEkeG7mSBjaMOtbmggeMOhYyB0b8OgbiB0aOG7gyBsw6AgODksMzMlLCDEkeG7mSBuaOG6oXkgbMOgIDk1LDg4JSB2w6AgxJHhu5kgaGnhu4d1IHF14bqjIGzDoCA1NSwwOCUNCg0KIyMjIyBNw7QgaMOsbmggcHJvYml0DQoNCmBgYHtSfQ0KcHJlZGljdGlvbnMgPC0gcHJlZGljdChwcm9iaXQsIG5ld2RhdGEgPSB0ZXN0X2RhdGEzLCB0eXBlID0gInJlc3BvbnNlIikNCnByZWRpY3RlZF9jbGFzc2VzIDwtIGlmZWxzZShwcmVkaWN0aW9ucyA+IDAuNSwgIjEiLCAiMCIpICAjIENo4buJbmggbmfGsOG7oW5nIHBow6JuIGxv4bqhaQ0KcHJlZGljdGlvbnMxPC1mYWN0b3IocHJlZGljdGVkX2NsYXNzZXMsIGxldmVscyA9IGMoIjAiLCIxIikpDQphY3R1YWw8LSBmYWN0b3IodGVzdF9kYXRhMyRBdHRyaXRpb25fRmxhZywgbGFiZWxzID0gYygiMCIsIjEiKSkNCmNvbmZ1c2lvbk1hdHJpeCh0YWJsZShwcmVkaWN0aW9uczEsIGFjdHVhbCkpDQoNCmBgYA0KDQpNw7QgaMOsbmggcHJvYml0IGPDsyDEkeG7mSBjaMOtbmggeMOhYyB0b8OgbiB0aOG7gyBsw6AgODksNDgsIMSR4buZIG5o4bqheSBsw6AgOTYsMTIlIHbDoCDEkeG7mSBoaeG7h3UgcXXhuqMgbMOgIDU0LDc3JQ0KDQojIyMjIE3DtCBow6xuaCBjbG9nbG9nDQoNCmBgYHtSfQ0KcHJlZGljdGlvbnMgPC0gcHJlZGljdChjbG9nbG9nLCBuZXdkYXRhID0gdGVzdF9kYXRhMywgdHlwZSA9ICJyZXNwb25zZSIpDQpwcmVkaWN0ZWRfY2xhc3NlcyA8LSBpZmVsc2UocHJlZGljdGlvbnMgPiAwLjUsICIxIiwgIjAiKSAgIyBDaOG7iW5oIG5nxrDhu6FuZyBwaMOibiBsb+G6oWkNCmhlYWQocHJlZGljdGVkX2NsYXNzZXMsNCkNCnByZWRpY3Rpb25zMTwtZmFjdG9yKHByZWRpY3RlZF9jbGFzc2VzLCBsZXZlbHMgPSBjKCIwIiwiMSIpKQ0KYWN0dWFsPC0gZmFjdG9yKHRlc3RfZGF0YTMkQXR0cml0aW9uX0ZsYWcsIGxhYmVscyA9IGMoIjAiLCIxIikpDQpjb25mdXNpb25NYXRyaXgodGFibGUocHJlZGljdGlvbnMxLCBhY3R1YWwpKQ0KDQpgYGANCg0KTcO0IGjDrG5oIGNsb2dsb2cgY8OzIMSR4buZIGNow61uaCB4w6FjIHRvw6BuIHRo4buDIGzDoCA4OSwzMyUsIMSR4buZIG5o4bqheSBsw6AgOTclIHbDoCDEkeG7mSBoaeG7h3UgcXXhuqMgbMOgIDQ5LDIzJS4NCg0KxJDhu5kgY2jDrW5oIHjDoWMgdG/DoG4gdGjhu4MgY+G7p2EgbcO0IGjDrG5oIHByb2JpdCBjYW8gbmjhuqV0OyDEkeG7mSBuaOG6oXkgY+G7p2EgbcO0IGjDrG5oIGNsb2dsb2cgY2FvIG5o4bqldCB2w6AgxJHhu5kgaGnhu4d1IHF14bqjIGPhu6dhIG3DtCBow6xuaCBjYW8gbmjhuqV0LiBWw6wgbeG7pWMgdGnDqnUgY+G7p2EgYsOgaSB0aeG7g3UgbHXhuq1uIGzDoCBraMO0bmcgYuG7jyBzw7N0IGPDoWMga2jDoWNoIGjDoG5nIGPDsyBuZ3V5IGPGoSBy4budaSBi4buPIHPhu60gZOG7pW5nIGThu4tjaCB24bulIHRo4bq7IHTDrW4gZOG7pW5nIGPhu6dhIG5nw6JuIGjDoG5nLiBEbyDEkcOzIMSR4buZIGhp4buHdSBxdeG6oyBsw6AgdGnDqnUgY2jDrSBxdWFuIHRy4buNbmcgbmjhuqV0IMSR4buDIMSRw6FuaCBnacOhIHRyb25nIHRyxrDhu51uZyBo4bujcCBuw6B5LCB2w6wgduG6rXkgbcO0IGjDrG5oIGzhu7FhIGNo4buNbiBsw6AgbcO0IGjDrG5oIGxvZ2l0Lg0KDQoqKkvhur90IGx14bqtbioqOiBE4buxYSB2w6BvIDQgdGnDqnUgY2h14bqpbiB0YSB0aOG6pXkgbcO0IGjDrG5oIGxvZ2l0IGzDoCBtw7QgaMOsbmggxJHGsOG7o2MgbOG7sWEgY2jhu41uIG5oaeG7gXUgbmjhuqV0IGRvIMSRw7MgTUggbG9naXQgxJHGsOG7o2MgbOG7sWEgY2jhu41uIMSR4buDIHBow6JuIHTDrWNoIGPDoWMgeeG6v3UgdOG7kSDhuqNuaCBoxrDhu59uZyDEkeG6v24gcXV54bq/dCDEkeG7i25oIHLhu51pIGLhu48gdGjhursgdMOtbiBk4bulbmcgY+G7p2Ega2jDoWNoIGjDoG5nLg0KDQojIyBL4bq/dCBxdeG6oyBj4bunYSBtw7QgaMOsbmggbG9naXQNCg0KYGBge3J9DQoNCnN1bW1hcnkobWgzKQ0KDQpgYGANCg0KIyMjIEdp4bqjaSB0aMOtY2gga+G6v3QgcXXhuqMNCg0KS+G6v3QgcXXhuqMgcGjDom4gdMOtY2ggaOG7k2kgcXV5IExvZ2l0IGNobyB0aOG6pXksIDIxIGJp4bq/biDEkcawYSB2w6BvIG3DtCBow6xuaCBo4buTaSBxdXkgxJHhu4MgcGjDom4gdMOtY2ggbmjGsG5nIGvhur90IHF14bqjIHBow6JuIHTDrWNoIGNo4buJIGPDsyAxNyBiaeG6v24gxJHhu5ljIGzhuq1wIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ogYmFvIGfhu5NtOiANCg0KKiBHaeG7m2kgdMOtbmggKEdlbmRlcikNCiogU+G7kSBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIDoyIChEZXBlbmRlbnRfY291bnQyKQ0KKiBT4buRIG5nxrDhu51pIHBo4bulIHRodeG7mWMgOjMgKERlcGVuZGVudF9jb3VudDMpDQoqIFPhu5EgbmfGsOG7nWkgcGjhu6UgdGh14buZYyA6NCAoRGVwZW5kZW50X2NvdW50NCkNCiogU+G7kSBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIDo1IChEZXBlbmRlbnRfY291bnQ1KQ0KKiBUaHUgbmjhuq1wIHThu6sgJDQwayAtICQ2MEsgKEluY29tZV9DYXRlZ29yeSQ0MGsgLSAkNjBLKQ0KKiBUaHUgbmjhuq1wICB04burICQ2MGsgLSAkODBLIChJbmNvbWVfQ2F0ZWdvcnkkNjBrIC0gJDgwSykNCiogVGh1IG5o4bqtcCBraMOhYyAoSW5jb21lX0NhdGVnb3J5VW5rbm93bikNCiogVGjhu51pIGdpYW4gcXVhbiBo4buHIHbhu5tpIG5nw6JuIGjDoG5nIChQZXJpb2Qgb2YgcmVsYXRpb25zaGlwIHdpdGggYmFuaykoIG1vbnRoc19vbl9ib29rKQ0KKiBU4buVbmcgc+G7kSBz4bqjbiBwaOG6qW0gbcOgIGtow6FjaCBow6BuZyBu4bqvbSBnaeG7ryAoIHRvdGFsX1JlbGF0aW9uc2hpcF9Db3VudCkNCiogU+G7kSB0aMOhbmcga2jDtG5nIHPhu60gZOG7pW5nIHRo4bq7IHRyb25nIDEyIHRow6FuZyBxdWEgKCBtb250aHNfSW5hY3RpdmVfMTJfbW9uKQ0KKiBz4buRIGzhuqduIGxpw6puIGjhu4cgZ2nhu69hIGtow6FjaCBow6BuZyB2w6AgbmfDom4gaMOgbmcgdHJvbmcgMTIgdGjDoW5nIHF1YSggY29udGFjdHNfQ291bnRfMTJfbW9uKQ0KKiB04buVbmcgdMOtbiBk4bulbmcgcXVheSB2w7JuZyggVG90YWxfUmV2b2x2aW5nX0JhbCkNCiogdGhheSDEkeG7lWkgdOG7lW5nIG3hu6ljIGNoaSB0acOqdSB0aOG6uyB0w61uIGThu6VuZyAoUTQgc28gduG7m2kgUTEpICh0b3RhbF9BbXRfQ2huZ19RNF9RMSkgDQoqIHThu5VuZyBt4bupYyBjaGkgdGnDqnUgdGjhursgdMOtbiBk4bulbmcgKDEyIHRow6FuZyBxdWEpKHRvdGFsX1RyYW5zX0FtdCkgDQoqIHThu5VuZyBz4buRIGzGsOG7o25nIGdpYW8gZOG7i2NoICgxMiB0aMOhbmcgcXVhKSggdG90YWxfVHJhbnNfQ3QpDQoqIHRoYXkgxJHhu5VpIHThu5VuZyBz4buRIGdpYW8gZOG7i2NoIChRNCBzbyB24bubaSBRMSkgKFRvdGFsX0N0X0NobmdfUTRfUTEpDQoNClbhu5tpIGdp4bqjIHRodXnhur90IGPDoWMgeeG6v3UgdOG7kSBraMOhYyBraMO0bmcgxJHhu5VpLCDhuqNuaCBoxrDhu59uZyBj4bunYSB04burbmcgYmnhur9uIMSR4bq/biDEkcaw4bujYyBkaeG7hW4gZ2nhuqNpIG5oxrAgc2F1Og0KDQoqIEJp4bq/biBnaeG7m2kgdMOtbmggdHJvbmcgbcO0IGjDrG5oIGPDsyDDvSBuZ2jEqWEgdGjhu5FuZyBrw6ogduG7gSB04bu3IGzhu4cgcuG7nWkgYuG7jyB0aOG6uyB0w61uIGThu6VuZyBj4bunYSBraMOhY2ggaMOgbmcsIOG7nyBt4bupYyDDvSBuZ2jEqWEgMSUgdGjDrCBraMOhY2ggaMOgbmcgbmFtIHPhur0gY8OzIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gY2FvIGjGoW4gMzAsMjYgJSBzbyB24bubaSBraMOhY2ggaMOgbmcgbuG7ry4NCg0KKiBT4buRIG5nxrDhu51pIHBo4bulIHRodeG7mWMgY+G7p2Ega2jDoWNoIGjDoG5nIGtow6FjIG5oYXUgc+G6vSBjw7MgdMOhYyDEkeG7mW5nIMSRw6FuZyBr4buDIMSR4bq/biBxdXnhur90IMSR4buLbmggcuG7nWkgYuG7jyB0aOG6uyB0w61uIGThu6VuZyBj4bunYSBraMOhY2ggaMOgbmcuIOG7niBt4bupYyDDvSBuZ2jEqWEgMTAlIHRow6wga2jDoWNoIGjDoG5nIGPDsyAyIG5nxrDhu51pIHBo4bulIHRodeG7mWMgY8OzIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gY2FvIGjGoW4gNTcsMjglIHNvIHbhu5tpIGtow6FjaCBow6BuZyBraMO0bmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMu4bueIG3hu6ljIMO9IG5naMSpYSA1JSBLaMOhY2ggaMOgbmcgY8OzIDMgbmfGsOG7nWkgcGjhu6UgdGh14buZYyBjw7MgeMOhYyBzdeG6pXQgcuG7nWkgYuG7jyBjYW8gaMahbiA2MCwzMiUgc28gduG7m2kg4bufIG3hu6ljIHRodSBuaOG6rXAga2jDoWNoIGjDoG5nIGtow7RuZyBjw7MgbmfGsOG7nWkgcGjhu6UgdGh14buZYy7hu54gbeG7qWMgw70gbmdoxKlhIDElIEtow6FjaCBow6BuZyBjw7MgNCBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIGPDsyB4w6FjIHN14bqldCBy4budaSBi4buPIGNhbyBoxqFuIDYxLDkyJSBzbyB24bubaSDhu58gbeG7qWMgdGh1IG5o4bqtcCBraMOhY2ggaMOgbmcga2jDtG5nIGPDsyBuZ8aw4budaSBwaOG7pSB0aHXhu5ljLiDhu54gbeG7qWMgw70gbmdoxKlhIDUlIEtow6FjaCBow6BuZyBjw7MgNSBuZ8aw4budaSBwaOG7pSB0aHXhu5ljIGPDsyB4w6FjIHN14bqldCBy4budaSBi4buPIGNhbyBoxqFuIDY0LDclIHNvIHbhu5tpIOG7nyBt4bupYyB0aHUgbmjhuq1wIGtow6FjaCBow6BuZyBraMO0bmcgY8OzIG5nxrDhu51pIHBo4bulIHRodeG7mWMuDQoNCiogVGh1IG5o4bqtcCBj4bunYSBraMOhY2ggaMOgbmcg4bufIGPDoWMgbeG7qWMga2jDoWMgbmhhdSBz4bq9IGPDsyB0w6FjIMSR4buZbmcgxJHDoW5nIGvhu4MgxJHhur9uIHF1eeG6v3QgxJHhu4tuaCBy4budaSBi4buPIHRo4bq7IHTDrW4gZOG7pW5nIGPhu6dhIGtow6FjaCBow6BuZy4g4bueIG3hu6ljIMO9IG5naMSpYSA1JSB0aMOsIGtow6FjaCBow6BuZyBjw7MgdGh1IG5o4bqtcCB04burICQ0MC0kNjAgY8OzIHjDoWMgc3XhuqV0IHLhu51pIGLhu48gY2FvIGjGoW4gNjEsNzMlIHNvIHbhu5tpIOG7nyBt4bupYyB0aHUgbmjhuq1wIGzhu5tuIGjGoW4gJDEyMCAuIFRyb25nIGtoaSDEkcOzIGtow6FjaCBow6BuZyBjw7MgbeG7qWMgdGh1IG5o4bqtcCB04burICQ2MC0kODAgY8OzIHjDoWMgc3XhuqV0IGNhbyBoxqFuIDYwLDA5JSBzbyB24bubaSBraMOhY2ggaMOgbmcgY8OzIG3hu6ljIHRodSBuaOG6rXAgbOG7m24gaMahbiAkMTIwLiBW4bubaSBt4bupYyDDvSBuZ2jEqWEgMTAlIHRow6wga2jDoWNoIGjDoG5nIGPDsyB0aHUgbmjhuq1wIGtow6FjIGPDsyB4w6FjIHN14bqldCBy4budaSBi4buPIGNhbyBoxqFuIDYxLDYxJSBzbyB24bubaSDhu58gbeG7qWMgdGh1IG5o4bqtcCBs4bubbiBoxqFuICQxMjAuDQoNCiog4bueIG3hu6ljIMO9IG5naMSpYSAxJSwgdGjhu51pIGdpYW4gcXVhbiBo4buHIHbhu5tpIG5nw6JuIGjDoG5nIChQZXJpb2Qgb2YgcmVsYXRpb25zaGlwIHdpdGggYmFuaykoIG1vbnRoc19vbl9ib29rKSwgdOG7lW5nIHPhu5Egc+G6o24gcGjhuqltIG3DoCBraMOhY2ggaMOgbmcgbuG6r20gZ2nhu68gKCB0b3RhbF9SZWxhdGlvbnNoaXBfQ291bnQpLHThu5VuZyB0w61uIGThu6VuZyBxdWF5IHbDsm5nKCBUb3RhbF9SZXZvbHZpbmdfQmFsKSwgdGhheSDEkeG7lWkgdOG7lW5nIG3hu6ljIGNoaSB0acOqdSB0aOG6uyB0w61uIGThu6VuZyAoUTQgc28gduG7m2kgUTEpICh0b3RhbF9BbXRfQ2huZ19RNF9RMSksIHThu5VuZyBz4buRIGzGsOG7o25nIGdpYW8gZOG7i2NoICgxMiB0aMOhbmcgcXVhKSggdG90YWxfVHJhbnNfQ3QpLCB0aGF5IMSR4buVaSB04buVbmcgc+G7kSBnaWFvIGThu4tjaCAoUTQgc28gduG7m2kgUTEpIChUb3RhbF9DdF9DaG5nX1E0X1ExKSBjw7MgdMOhYyDEkeG7mW5nIHRpw6p1IGPhu7FjIGzDqm4ga2jhuqMgbsSDbmcgcuG7n2kgYuG7jyB0aOG6uyB0w61uIGThu6VuZyBj4bunYSBraMOhY2ggaMOgbmcuIFRyb25nIGtoaSBjw6FjIHnhur91IHThu5E6IHPhu5EgbOG6p24gbGnDqm4gaOG7hyBj4bunYSBuZ8OibiBow6BuZyB24bubaSBraMOhY2ggaMOgbmcgKENvbnRhY3RzX0NvdW50XzEyX21vbikgLCBz4buRIHRow6FuZyBraMO0bmcgaG/huqF0IMSR4buZbmcgdGjhursgdMOtbiBk4bulbmcgKE1vbnRoc19JbmFjdGl2ZV8xMl9tb24pIHbDoCB04buVbmcgbeG7qWMgY2hpIHRpw6p1IHRo4bq7IHTDrW4gZOG7pW5nICgxMiB0aMOhbmcgcXVhKSh0b3RhbF9UcmFuc19BbXQpIGzhuqFpIGPDsyB0w6FjIMSR4buZbmcgdMOtY2ggY+G7sWMgbMOqbiBraOG6oyBuxINuZyBy4bufaSBi4buPIHRo4bq7IHTDrW4gZOG7pW5nIGPhu6dhIGtow6FjaCBow6BuZy4NCg0KIyMjIEtob+G6o25nIMaw4bubYyBsxrDhu6NuZyBjaG8gaOG7hyBz4buRIGjhu5NpIHF1eQ0KDQpgYGB7cn0NCg0KY29uZmludC5kZWZhdWx0KG1oMykNCmBgYA0KDQojIyMgROG7sSBiw6FvDQoNCmBgYHtyfQ0KcHJlZGljdGlvbnMgPC0gcHJlZGljdChtaDMsIG5ld2RhdGEgPSB0ZXN0X2RhdGEzLCB0eXBlID0gInJlc3BvbnNlIikNCmhlYWQocm91bmQocHJlZGljdGlvbnMsNCksMTApDQoNCmBgYA0KDQoNCg==