Overview

Every quarter banks make detailed, public reports of their balance sheets called Call Reports. Bank regulators use this data and a simple logit model to find which banks are at risk of failure and should be monitored closely. This project replicates the type of screening model used by estimating the relationship between Call Report variables and eventual bank failure in historical data. It then applies the model to recent data to find which banks currently seem most risky.

Data Collection

Procedure and Details The data set callreport20071231 was prepared from the December 2007 Call Reports. The Call Reports are available from the Federal Financial Institutions Examination Council website.

Merge in a list bank failures downloaded from the Federal Depository Insurance Corporation using the “CERT” identifier as the merge key.

Replicate the regulators’ screening model by estimating a logit regression using the failure indicator as the dependent variable. The explanatory variables are the following, all as proportions of total assets (rcon2170):

We will use the logit regression in our model.

We will calculate the predicted probability within two years for each bank using the 2007 data. We will also create a table of all the banks that failed in that two year period with the model’s failure probability for each. Create a table of the ten banks with the highest predicted failure probability that did not fail.

Error: attempt to use zero-length variable name

After downloading the list of failed banks from site, lets load into our R environment. Briefly, there are 551 observations and 7 variables. Now let’s preview our list of failed banks data set.

'data.frame':   555 obs. of  7 variables:
 $ Bank.Name            : chr  "Washington Federal Bank for Savings" "The Farmers and Merchants State Bank of Argonia" "Fayette County Bank" "Guaranty Bank, (d/b/a BestBank in Georgia & Michigan)" ...
 $ City                 : chr  "Chicago" "Argonia" "Saint Elmo" "Milwaukee" ...
 $ ST                   : chr  "IL" "KS" "IL" "WI" ...
 $ CERT                 : int  30570 17719 1802 30003 58302 35495 19328 34951 91 11297 ...
 $ Acquiring.Institution: chr  "Royal Savings Bank" "Conway Bank" "United Fidelity Bank, fsb" "First-Citizens Bank & Trust Company" ...
 $ Closing.Date         : chr  "15-Dec-17" "13-Oct-17" "26-May-17" "5-May-17" ...
 $ Updated.Date         : chr  "21-Feb-18" "21-Feb-18" "26-Jul-17" "22-Mar-18" ...

EDA

Check for na values, if so, hot-code to ‘0’.

[1] FALSE

AL AR AZ CA CO CT FL GA HI IA ID IL IN KS KY LA MA MD MI MN MO MS NC NE NH NJ NM NV NY OH OK OR PA PR SC SD TN 
 7  4 16 41 10  2 75 93  1  2  2 69  3 10  2  4  1 10 14 23 16  2  7  3  1  7  3 12  5  8  7  6 10  4 10  1  7 
TX UT VA WA WI WV WY 
12  8  5 19 11  1  1 

Since our Closing.Date varibable is currently a character, we would need to convert it into a Date type for conditional subsetting later when we create an indicator variable for whether the bank failed in 2008 or 2009.

As you can see, there were 165 failed banks and 386 banks survived between 2008-2009.


  0   1 
390 165 

Training Set

The 2007 Call Reports contains 7,788 observations and 11 variables.

'data.frame':   7788 obs. of  11 variables:
 $ idrssd: int  37 242 279 354 457 505 1155 1351 1454 1557 ...
 $ name  : chr  "BANK OF HANCOCK COUNTY" "First Community  Bank, Xenia-Flora" "MINEOLA COMMUNITY BANK S. S. B." "Bison State Bank" ...
 $ cert  : int  10057 3850 28868 14083 10202 6959 17639 9392 19184 15328 ...
 $ equity: num  0.199 0.124 0.156 0.123 0.103 ...
 $ income: num  0.01072 0.01706 0.00524 -0.00549 0.0161 ...
 $ invsec: num  0.3275 0.2807 0.1855 0.3516 0.0392 ...
 $ ltdep : num  0.1784 0.0853 0.1753 0.0392 0.0709 ...
 $ past30: num  0.001263 0.000496 0.000873 0.000654 0 ...
 $ past90: num  0.00128 0 0 0 0 ...
 $ nonacc: num  0.003537 0 0 0.000523 0.018188 ...
 $ oreo  : num  0.000379 0 0.003193 0 0.004352 ...

Next, we will create a training set by merging in a list bank failures from previously using the “CERT” identifier as the merge key.

'data.frame':   461 obs. of  18 variables:
 $ CERT                 : int  91 151 182 416 513 916 1006 1056 1252 1361 ...
 $ Bank.Name            : chr  "Allied Bank" "Habersham Bank" "The Peoples Bank" "First Capital Bank" ...
 $ City                 : chr  "Mulberry" "Clarkesville" "Winder" "Kingfisher" ...
 $ ST                   : chr  "AR" "GA" "GA" "OK" ...
 $ Acquiring.Institution: chr  "Today's Bank" "SCBT National Association" "Community & Southern Bank" "F & M Bank" ...
 $ Closing.Date         : Date, format: "2016-09-23" "2011-02-18" "2010-09-17" "2012-06-08" ...
 $ Updated.Date         : chr  "25-Sep-17" "23-Feb-18" "6-Oct-17" "5-Feb-15" ...
 $ failed               : int  0 0 0 0 0 0 1 0 0 0 ...
 $ idrssd               : int  28349 270335 454434 3953 124773 215130 84345 836151 868376 236452 ...
 $ name                 : chr  "ALLIED BANK" "Habersham Bank" "The Peoples Bank" "First Capital Bank" ...
 $ equity               : num  0.103 0.0993 0.1082 0.0811 0.116 ...
 $ income               : num  0.01436 0.00769 0.01143 0.01371 0.00372 ...
 $ invsec               : num  1.92e-01 1.75e-01 3.24e-01 3.59e-05 2.45e-02 ...
 $ ltdep                : num  0.2736 0.2265 0.2165 0.0956 0.3177 ...
 $ past30               : num  0.000733 0.007509 0.005402 0 0.008801 ...
 $ past90               : num  0 0 0 0 0.00026 ...
 $ nonacc               : num  0 0.034912 0.000277 0.006642 0 ...
 $ oreo                 : num  0.00398 0.0224 0.00374 0 0.00161 ...

Let’s begin training our logit regression model by using the 9 independent variables and failed binary indicator column as our dependent variable.


Call:
glm(formula = failed ~ equity + income + invsec + ltdep + past30 + 
    past90 + nonacc + oreo, family = binomial(link = "logit"), 
    data = train_df)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-1.8814  -0.7940  -0.6498   1.0406   2.3296  

Coefficients:
            Estimate Std. Error z value Pr(>|z|)   
(Intercept)  -0.7878     0.4336  -1.817  0.06922 . 
equity       -5.3128     2.8581  -1.859  0.06304 . 
income      -12.3401     8.2757  -1.491  0.13593   
invsec        1.9679     1.0387   1.895  0.05815 . 
ltdep        -1.4543     1.0661  -1.364  0.17254   
past30       27.9293     9.2588   3.016  0.00256 **
past90       13.6011    20.4702   0.664  0.50641   
nonacc       18.4779     6.4590   2.861  0.00423 **
oreo         18.9908    12.3116   1.543  0.12295   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 566.07  on 460  degrees of freedom
Residual deviance: 503.86  on 452  degrees of freedom
AIC: 521.86

Number of Fisher Scoring iterations: 4

Below is a preview of the predicted probabilities of our training model.

Table of all the banks that failed in 2008-2009 with their predicted probabilities of failure:

Table of all the banks with the Highest Predicted Failure Probabilities that did not fail (2008-2009), but eventually did:

Test Data

Using our previous model, we can now test unseen data in our 2015 Call Reports and determine the current banks predicted probablities of failing.

'data.frame':   6328 obs. of  11 variables:
 $ idrssd: int  37 242 279 354 457 505 1155 1351 1454 1557 ...
 $ name  : chr  "Bank of Hancock County" "First Community  Bank, Xenia-Flora" "MINEOLA COMMUNITY BANK S. S. B." "Bison State Bank" ...
 $ cert  : int  10057 3850 28868 14083 10202 6959 17639 9392 19184 15328 ...
 $ equity: num  0.2316 0.1303 0.1376 0.1089 0.0938 ...
 $ income: num  0.00849 0.01181 0.00263 -0.00371 0.01442 ...
 $ invsec: num  0.5755 0.2901 0.0363 0.6191 0.006 ...
 $ ltdep : num  0.1037 0.1066 0.2099 0.0446 0.0881 ...
 $ past30: num  0.000701 0.003032 0.002454 0 0 ...
 $ past90: num  0 0 0 0 0 ...
 $ nonacc: num  0 0.000398 0.000171 0 0 ...
 $ oreo  : num  0.000584 0 0 0 0.001408 ...

Top 10 banks with highest predicted failure rate using current Call Report data (09302015).

As you can see from our predicted probabilities table, Banamex is has a probability rate of 99.95% of failure. Citigroup, the parent company for Citibank and Banamex USA, has confirmed that it will close Banamex USA as of June 2015.

Beach Community Bank, State Central Bank, and Boulevard Bank are still currently in operation, while Builders Bank technically closed its doors on April of 2017 with a failure rate of 86.17%.

AMERICAN PATRIOT BANK has since merged with APEX BANK on Sep 23, 2016.

Conclusion

We replicate the type of screening model used by estimating the relationship between Call Report variables and eventual bank failure in historical data. It then applies the model to recent data to find which banks currently seem most risky and act accordingly.

EOF

LS0tDQp0aXRsZTogIkJhbmsgRmFpbHVyZSBTY3JlZW5pbmcgTW9kZWwiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KLS0tDQoNCiMjIyBPdmVydmlldw0KRXZlcnkgcXVhcnRlciBiYW5rcyBtYWtlIGRldGFpbGVkLCBwdWJsaWMgcmVwb3J0cyBvZiB0aGVpciBiYWxhbmNlIHNoZWV0cyBjYWxsZWQgQ2FsbCBSZXBvcnRzLiBCYW5rIHJlZ3VsYXRvcnMgdXNlIHRoaXMgZGF0YSBhbmQgYSBzaW1wbGUgbG9naXQgbW9kZWwgdG8gZmluZCB3aGljaCBiYW5rcyBhcmUgYXQgcmlzayBvZiBmYWlsdXJlIGFuZCBzaG91bGQgYmUgbW9uaXRvcmVkIGNsb3NlbHkuIFRoaXMgcHJvamVjdCByZXBsaWNhdGVzIHRoZSB0eXBlIG9mIHNjcmVlbmluZyBtb2RlbCB1c2VkIGJ5IGVzdGltYXRpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIENhbGwgUmVwb3J0IHZhcmlhYmxlcyBhbmQgZXZlbnR1YWwgYmFuayBmYWlsdXJlIGluIGhpc3RvcmljYWwgZGF0YS4gSXQgdGhlbiBhcHBsaWVzIHRoZSBtb2RlbCB0byByZWNlbnQgZGF0YSB0byBmaW5kIHdoaWNoIGJhbmtzIGN1cnJlbnRseSBzZWVtIG1vc3Qgcmlza3kuDQoNCiMjIyBEYXRhIENvbGxlY3Rpb24NCg0KUHJvY2VkdXJlIGFuZCBEZXRhaWxzDQpUaGUgZGF0YSBzZXQgY2FsbHJlcG9ydDIwMDcxMjMxIHdhcyBwcmVwYXJlZCBmcm9tIHRoZSBEZWNlbWJlciAyMDA3IENhbGwgUmVwb3J0cy4gVGhlIENhbGwgUmVwb3J0cyBhcmUgYXZhaWxhYmxlIGZyb20gdGhlIFtGZWRlcmFsIEZpbmFuY2lhbCBJbnN0aXR1dGlvbnMgRXhhbWluYXRpb24gQ291bmNpbF0oaHR0cHM6Ly93d3cuZmZpZWMuZ292Lykgd2Vic2l0ZS4NCg0KTWVyZ2UgaW4gYSBsaXN0IGJhbmsgZmFpbHVyZXMgZG93bmxvYWRlZCBmcm9tIHRoZSBbRmVkZXJhbCBEZXBvc2l0b3J5IEluc3VyYW5jZSBDb3Jwb3JhdGlvbl0oaHR0cDovL3d3dy5mZGljLmdvdi9iYW5rL2luZGl2aWR1YWwvZmFpbGVkL2JhbmtsaXN0Lmh0bWwpIHVzaW5nIHRoZSAiQ0VSVCIgaWRlbnRpZmllciBhcyB0aGUgbWVyZ2Uga2V5LiANCg0KUmVwbGljYXRlIHRoZSByZWd1bGF0b3JzJyBzY3JlZW5pbmcgbW9kZWwgYnkgZXN0aW1hdGluZyBhIGxvZ2l0IHJlZ3Jlc3Npb24gdXNpbmcgdGhlIGZhaWx1cmUgaW5kaWNhdG9yIGFzIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUuIFRoZSBleHBsYW5hdG9yeSB2YXJpYWJsZXMgYXJlIHRoZSBmb2xsb3dpbmcsIGFsbCBhcyBwcm9wb3J0aW9ucyBvZiB0b3RhbCBhc3NldHMgKHJjb24yMTcwKToNCg0KKiBFcXVpdHkgDQoqIEluY29tZSANCiogSW52ZXN0bWVudCBzZWN1cml0aWVzIA0KKiBMYXJnZSB0aW1lIGRlcG9zaXRzDQoqIExvYW5zIDMwIGRheXMgcGFzdCBkdWUgDQoqIExvYW5zIDkwIGRheXMgcGFzdDkwIA0KKiBOb25hY2NydWFsIGxvYW5zIA0KKiBPdGhlciByZWFsIGVzdGF0ZSBvd25lZA0KDQpXZSB3aWxsIHVzZSB0aGUgbG9naXQgcmVncmVzc2lvbiBpbiBvdXIgbW9kZWwuDQoNCldlIHdpbGwgY2FsY3VsYXRlIHRoZSBwcmVkaWN0ZWQgcHJvYmFiaWxpdHkgd2l0aGluIHR3byB5ZWFycyBmb3IgZWFjaCBiYW5rIHVzaW5nIHRoZSAyMDA3IGRhdGEuIFdlIHdpbGwgYWxzbyBjcmVhdGUgYSB0YWJsZSBvZiBhbGwgdGhlIGJhbmtzIHRoYXQgZmFpbGVkIGluIHRoYXQgdHdvIHllYXIgcGVyaW9kIHdpdGggdGhlIG1vZGVsJ3MgZmFpbHVyZSBwcm9iYWJpbGl0eSBmb3IgZWFjaC4gQ3JlYXRlIGEgdGFibGUgb2YgdGhlIHRlbiBiYW5rcyB3aXRoIHRoZSBoaWdoZXN0IHByZWRpY3RlZCBmYWlsdXJlIHByb2JhYmlsaXR5IHRoYXQgZGlkIG5vdCBmYWlsLiANCg0KYGBge3IgZWNobz1GQUxTRX0NCnNldHdkKCJDOlxcVXNlcnNcXEtFVklOXFxEb3dubG9hZHNcXF9DU1UgRWFzdCBCYXlcXEJhbmsgRmFpbHVyZSBwcm9qZWN0IikNCmBgYA0KDQpBZnRlciBkb3dubG9hZGluZyB0aGUgbGlzdCBvZiBmYWlsZWQgYmFua3MgZnJvbSBzaXRlLCBsZXRzIGxvYWQgaW50byBvdXIgUiBlbnZpcm9ubWVudC4gQnJpZWZseSwgdGhlcmUgYXJlIDU1MSBvYnNlcnZhdGlvbnMgYW5kIDcgdmFyaWFibGVzLiBOb3cgbGV0J3MgcHJldmlldyBvdXIgbGlzdCBvZiBmYWlsZWQgYmFua3MgZGF0YSBzZXQuDQoNCmBgYHtyIGVjaG89RkFMU0V9DQpiYW5rbGlzdCA8LSByZWFkLmNzdigiaHR0cHM6Ly93d3cuZmRpYy5nb3YvYmFuay9pbmRpdmlkdWFsL2ZhaWxlZC9iYW5rbGlzdC5jc3YiLCBzZXAgPSAiLCIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwgaGVhZGVyID0gVFJVRSkNCnN0cihiYW5rbGlzdCkNCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KaGVhZChiYW5rbGlzdCkNCmBgYA0KDQojIyBFREENCg0KQ2hlY2sgZm9yIG5hIHZhbHVlcywgaWYgc28sIGhvdC1jb2RlIHRvICcwJy4NCg0KYGBge3IgZWNobz1GQUxTRX0NCmFueShpcy5uYShiYW5rbGlzdCkpDQpiYW5rbGlzdFtpcy5uYShiYW5rbGlzdCldIDwtIDANCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KI2h0dHBzOi8vd3d3Lmdhc2xhbXBtZWRpYS5jb20vZG93bmxvYWQtemlwLWNvZGUtbGF0aXR1ZGUtbG9uZ2l0dWRlLWNpdHktc3RhdGUtY291bnR5LWNzdi8NCmxvbmdfbGF0IDwtIHJlYWQuY3N2KCJodHRwOi8vbm90ZWJvb2suZ2FzbGFtcG1lZGlhLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAxMy8wOC96aXBfY29kZXNfc3RhdGVzLmNzdiIsIHNlcCA9ICIsIikNCg0KI2hlYWQobG9uZ19sYXQsMikNCg0KYGBgDQoNCg0KYGBge3IgZWNobz1GQUxTRX0NCiNiYW5rbGlzdCRTVCA8LSBhcy5udW1lcmljKGJhbmtsaXN0JFNUKQ0KdGFibGUoYmFua2xpc3QkU1QpDQpgYGANCg0KYGBge3IgZWNobz1GQUxTRX0NCiNsaWJyYXJ5KGdncGxvdDIpDQojZ2dwbG90KGJhbmtsaXN0JFNULCBhZXMoeCA9IExldmVsKSkgKyBnZW9tX2JhcigpDQoNCmBgYA0KDQoNCiANCiANCg0KU2luY2Ugb3VyICoqQ2xvc2luZy5EYXRlKiogdmFyaWJhYmxlIGlzIGN1cnJlbnRseSBhIGNoYXJhY3Rlciwgd2Ugd291bGQgbmVlZCB0byBjb252ZXJ0IGl0IGludG8gYSBEYXRlIHR5cGUgZm9yIGNvbmRpdGlvbmFsIHN1YnNldHRpbmcgbGF0ZXIgd2hlbiB3ZSBjcmVhdGUgYW4gaW5kaWNhdG9yIHZhcmlhYmxlIGZvciB3aGV0aGVyIHRoZSBiYW5rIGZhaWxlZCBpbiAyMDA4IG9yIDIwMDkuDQoNCmBgYHtyIGVjaG89RkFMU0V9DQojIENvbnZlcnQgdG8gRGF0ZQ0KYmFua2xpc3QkQ2xvc2luZy5EYXRlIDwtIGFzLkRhdGUoYmFua2xpc3QkQ2xvc2luZy5EYXRlLCBmb3JtYXQ9IiVkLSViLSV5IikgDQoNCiMgQ3JlYXRlIGJpbmFyeSBpbmRpY2F0b3IgKDE9ZmFpbGVkKQ0KYmFua2xpc3QkZmFpbGVkIDwtIGFzLm51bWVyaWMoYmFua2xpc3QkQ2xvc2luZy5EYXRlID49ICIyMDA4LTAxLTAxIiAmIGJhbmtsaXN0JENsb3NpbmcuRGF0ZSA8PSAiMjAwOS0xMi0zMSIpDQpgYGANCg0KQXMgeW91IGNhbiBzZWUsIHRoZXJlIHdlcmUgMTY1IGZhaWxlZCBiYW5rcyBhbmQgMzg2IGJhbmtzIHN1cnZpdmVkIGJldHdlZW4gMjAwOC0yMDA5Lg0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KdGFibGUoYmFua2xpc3QkZmFpbGVkKSAgDQpgYGANCg0KIyMgVHJhaW5pbmcgU2V0DQoNClRoZSAyMDA3IENhbGwgUmVwb3J0cyBjb250YWlucyA3LDc4OCBvYnNlcnZhdGlvbnMgYW5kIDExIHZhcmlhYmxlcy4NCiANCg0KYGBge3IgZWNobz1GQUxTRX0NCiMgRm9yIHRyYWluaW5nIHNldA0KIyBodHRwczovL2Nkci5mZmllYy5nb3YvcHVibGljL1BXUy9Eb3dubG9hZEJ1bGtEYXRhLmFzcHgNCmNhbGwyMDA3MTIzMSA8LSByZWFkLmNzdigiY2FsbDIwMDcxMjMxLmNzdiIsIHNlcCA9ICIsIiwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLCBoZWFkZXIgPSBUUlVFKQ0KDQpzdHIoY2FsbDIwMDcxMjMxKSANCg0KYGBgDQoNCk5leHQsIHdlIHdpbGwgY3JlYXRlIGEgdHJhaW5pbmcgc2V0IGJ5IG1lcmdpbmcgaW4gYSBsaXN0IGJhbmsgZmFpbHVyZXMgZnJvbSBwcmV2aW91c2x5IHVzaW5nIHRoZSAiQ0VSVCIgaWRlbnRpZmllciBhcyB0aGUgbWVyZ2Uga2V5Lg0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KIyBSZW5hbWUgY2VydCBjb2x1bW4gdG8gbWF0Y2ggd2l0aCBDRVJUDQpsaWJyYXJ5KGRhdGEudGFibGUpDQpzZXRuYW1lcyhjYWxsMjAwNzEyMzEsICJjZXJ0IiwgIkNFUlQiKQ0KDQojIHJlcGxhY2UgTkEncyB3aXRoIDAgbnVtZXJpYw0KY2FsbDIwMDcxMjMxW2lzLm5hKGNhbGwyMDA3MTIzMSldIDwtIDANCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KIyBNZXJnZSBiYW5rbGlzdCBhbmQgMjAwNyBDYWxsIFJlcG9ydHMNCnRyYWluX2RmIDwtIG1lcmdlKGJhbmtsaXN0LCBjYWxsMjAwNzEyMzEsIGJ5PWMoIkNFUlQiICkpDQoNCnRyYWluX2RmJGZhaWxlZCA8LSBhcy5pbnRlZ2VyKHRyYWluX2RmJGZhaWxlZCkNCnN0cih0cmFpbl9kZikNCmBgYA0KDQpMZXQncyBiZWdpbiB0cmFpbmluZyBvdXIgbG9naXQgcmVncmVzc2lvbiBtb2RlbCBieSB1c2luZyB0aGUgOSBpbmRlcGVuZGVudCB2YXJpYWJsZXMgYW5kICpmYWlsZWQqIGJpbmFyeSBpbmRpY2F0b3IgY29sdW1uIGFzIG91ciBkZXBlbmRlbnQgdmFyaWFibGUuDQoNCmBgYHtyIGVjaG89RkFMU0V9DQptb2RlbCA8LSBnbG0oZmFpbGVkIH4gZXF1aXR5ICsgaW5jb21lICsgaW52c2VjICsgbHRkZXAgKyBwYXN0MzAgKyBwYXN0OTAgKyBub25hY2MgKyBvcmVvLCANCiAgICAgICAgICAgICBkYXRhPXRyYWluX2RmLCAgZmFtaWx5ID0gYmlub21pYWwobGluaz0ibG9naXQiKSkgDQoNCnN1bW1hcnkobW9kZWwpDQpgYGANCg0KQmVsb3cgaXMgYSBwcmV2aWV3IG9mIHRoZSBwcmVkaWN0ZWQgcHJvYmFiaWxpdGllcyBvZiBvdXIgdHJhaW5pbmcgbW9kZWwuDQoNCmBgYHtyIGVjaG89RkFMU0V9DQpwcmVkX2dsbSA8LSBwcmVkaWN0KG1vZGVsLCB0cmFpbl9kZix0eXBlPSJyZXNwb25zZSIpDQpgYGANCg0KVGFibGUgb2YgYWxsIHRoZSBiYW5rcyB0aGF0IGZhaWxlZCBpbiAyMDA4LTIwMDkgd2l0aCB0aGVpciBwcmVkaWN0ZWQgcHJvYmFiaWxpdGllcyBvZiBmYWlsdXJlOg0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KY2IgPC0gY2JpbmQodHJhaW5fZGYsIHByZWRfZ2xtKQ0Kc29ydGVkLmRmIDwtIGNiW29yZGVyKC1wcmVkX2dsbSksXQ0KDQojIFNhdmUgdG8gY3N2IGZpbGUgW29wdGlvbmFsXQ0Kd3JpdGUudGFibGUoc29ydGVkLmRmLCAidGVzdDAxLmNzdiIsIHNlcCA9ICIsIiwgcm93Lm5hbWVzID0gRkFMU0UpDQoNCiMgc29ydCBieSBmYWlsZWQgPT0gMQ0Kc29ydGVkLmRmMiA8LSBzb3J0ZWQuZGZbIHdoaWNoKHNvcnRlZC5kZiRmYWlsZWQ9PTEpLF0NCg0KIyBzZWxlY3Qgb25seSAzIGltcG9ydGFudCBjb2x1bW5zDQpsaWJyYXJ5KGRwbHlyKQ0Kc29ydGVkLmRmMyA8LSBzZWxlY3Qoc29ydGVkLmRmMiwgQ0VSVCwgQmFuay5OYW1lLCBwcmVkX2dsbSkgDQoNCnNvcnRlZC5kZjMNCmBgYA0KDQpUYWJsZSBvZiBhbGwgdGhlIGJhbmtzIHdpdGggdGhlIEhpZ2hlc3QgUHJlZGljdGVkIEZhaWx1cmUgUHJvYmFiaWxpdGllcyB0aGF0IGRpZCBub3QgZmFpbCAoMjAwOC0yMDA5KSwgYnV0IGV2ZW50dWFsbHkgZGlkOg0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KY2IgPC0gY2JpbmQodHJhaW5fZGYsIHByZWRfZ2xtKQ0Kc29ydGVkLmRmIDwtIGNiW29yZGVyKC1wcmVkX2dsbSksXQ0KDQojIFNhdmUgdG8gY3N2IGZpbGUgW29wdGlvbmFsXQ0Kd3JpdGUudGFibGUoc29ydGVkLmRmLCAidGVzdDAyLmNzdiIsIHNlcCA9ICIsIiwgcm93Lm5hbWVzID0gRkFMU0UpDQoNCiMgc29ydCBieSBmYWlsZWQgPT0gMA0Kc29ydGVkLmRmNCA8LSBzb3J0ZWQuZGZbIHdoaWNoKHNvcnRlZC5kZiRmYWlsZWQ9PTApLF0NCg0KIyBzZWxlY3Qgb25seSAzIGltcG9ydGFudCBjb2x1bW5zDQpsaWJyYXJ5KGRwbHlyKQ0Kc29ydGVkLmRmNSA8LSBzZWxlY3Qoc29ydGVkLmRmNCwgQ0VSVCwgQmFuay5OYW1lLCBwcmVkX2dsbSkgDQoNCnNvcnRlZC5kZjUNCmBgYA0KDQojIyBUZXN0IERhdGENCg0KVXNpbmcgb3VyIHByZXZpb3VzIG1vZGVsLCB3ZSBjYW4gbm93IHRlc3QgdW5zZWVuIGRhdGEgaW4gb3VyIDIwMTUgQ2FsbCBSZXBvcnRzIGFuZCBkZXRlcm1pbmUgdGhlIGN1cnJlbnQgYmFua3MgcHJlZGljdGVkIHByb2JhYmxpdGllcyBvZiBmYWlsaW5nLg0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KY2FsbDA5MzAyMDE1IDwtIHJlYWQuY3N2KCJjYWxsMDkzMDIwMTUuY3N2Iiwgc2VwID0gIiwiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UsIGhlYWRlciA9IFRSVUUpDQpzdHIoY2FsbDA5MzAyMDE1KSANCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KbGlicmFyeShkYXRhLnRhYmxlKQ0Kc2V0bmFtZXMoY2FsbDA5MzAyMDE1LCAiY2VydCIsICJDRVJUIikNCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KY2FsbDA5MzAyMDE1W2lzLm5hKGNhbGwwOTMwMjAxNSldIDwtIDANCg0KdGVzdF9kZiA8LSBtZXJnZShiYW5rbGlzdCwgY2FsbDA5MzAyMDE1LCBieT1jKCJDRVJUIiApKQ0KdGVzdF9kZiA8LSB0ZXN0X2RmIDwtIGNhbGwwOTMwMjAxNVs0OjExXQ0KdGVzdF9kZiANCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KcHJlZF9nbG0gPC0gcHJlZGljdChtb2RlbCwgY2FsbDA5MzAyMDE1LHR5cGU9InJlc3BvbnNlIikNCmBgYA0KDQpUb3AgMTAgYmFua3Mgd2l0aCBoaWdoZXN0IHByZWRpY3RlZCBmYWlsdXJlIHJhdGUgdXNpbmcgY3VycmVudCBDYWxsIFJlcG9ydCBkYXRhICgwOTMwMjAxNSkuDQoNCmBgYHtyIGVjaG89RkFMU0V9DQpjYiA8LSBjYmluZChjYWxsMDkzMDIwMTUsIHByZWRfZ2xtKQ0Kc29ydGVkLmRmIDwtIGNiW29yZGVyKC1wcmVkX2dsbSksXQ0KDQpzb3J0ZWQuZGY5IDwtIHNlbGVjdChzb3J0ZWQuZGYsIG5hbWUsIHByZWRfZ2xtKQ0KDQojIFNhdmUgdG8gY3N2IGZpbGUgW29wdGlvbmFsXQ0Kd3JpdGUudGFibGUoc29ydGVkLmRmLCAidGVzdDAzLmNzdiIsIHNlcCA9ICIsIiwgcm93Lm5hbWVzID0gRkFMU0UpDQoNCnNvcnRlZC5kZjkNCg0KYGBgDQoNCmBgYHtyIGVjaG89RkFMU0V9DQojY2INCmBgYA0KDQpBcyB5b3UgY2FuIHNlZSBmcm9tIG91ciBwcmVkaWN0ZWQgcHJvYmFiaWxpdGllcyB0YWJsZSwgQmFuYW1leCBpcyBoYXMgYSBwcm9iYWJpbGl0eSByYXRlIG9mIDk5Ljk1JSBvZiBmYWlsdXJlLiBDaXRpZ3JvdXAsIHRoZSBwYXJlbnQgY29tcGFueSBmb3IgQ2l0aWJhbmsgYW5kIEJhbmFtZXggVVNBLCBoYXMgY29uZmlybWVkIHRoYXQgaXQgd2lsbCBjbG9zZSBCYW5hbWV4IFVTQSBhcyBvZiBKdW5lIDIwMTUuDQoNCkJlYWNoIENvbW11bml0eSBCYW5rLCBTdGF0ZSBDZW50cmFsIEJhbmssIGFuZCBCb3VsZXZhcmQgQmFuayBhcmUgc3RpbGwgY3VycmVudGx5IGluIG9wZXJhdGlvbiwgd2hpbGUgQnVpbGRlcnMgQmFuayB0ZWNobmljYWxseSBjbG9zZWQgaXRzIGRvb3JzIG9uIEFwcmlsIG9mIDIwMTcgd2l0aCBhIGZhaWx1cmUgcmF0ZSBvZiA4Ni4xNyUuDQoNCkFNRVJJQ0FOIFBBVFJJT1QgQkFOSyBoYXMgc2luY2UgbWVyZ2VkIHdpdGggQVBFWCBCQU5LIG9uIFNlcCAyMywgMjAxNi4NCg0KIyMgQ29uY2x1c2lvbg0KDQpXZSByZXBsaWNhdGUgdGhlIHR5cGUgb2Ygc2NyZWVuaW5nIG1vZGVsIHVzZWQgYnkgZXN0aW1hdGluZyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gQ2FsbCBSZXBvcnQgdmFyaWFibGVzIGFuZCBldmVudHVhbCBiYW5rIGZhaWx1cmUgaW4gaGlzdG9yaWNhbCBkYXRhLiBJdCB0aGVuIGFwcGxpZXMgdGhlIG1vZGVsIHRvIHJlY2VudCBkYXRhIHRvIGZpbmQgd2hpY2ggYmFua3MgY3VycmVudGx5IHNlZW0gbW9zdCByaXNreSBhbmQgYWN0IGFjY29yZGluZ2x5Lg0KDQojIyMjIEVPRg0K