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):
- Equity
- Income
- Investment securities
- Large time deposits
- Loans 30 days past due
- Loans 90 days past90
- Nonaccrual loans
- Other real estate owned
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