1 Introduction
For Assignment 2, we are tasked with finding a data set and selecting
one explanatory variable to correlate with the response variable. We
will be using the least squares method and 95% bootstrap confidence
intervals if applicable.
2 Description of my Data Set
The data set I chose was Railroad Accidents in the U.S. in 2010. The
data was collected via safetydata.fra.dot.gov. This data set has a
handful of response variables, so I’m going to see which explanatory
variables correlate best with number of people killed, number of people
injured, number of locomotives derailed, and number of cars derailed. My
guess is that speed, equipment damage, and number equipment damage will
correlate the strongest with these response variables.Before even
digging into the data, it looks like the set does have enough
information to answer these questions.
2.1 Variables
- Railroad (categorical) - name of railroad
- Month (categorical)
- Day (categorical) - days of the week labeled 1 through 7
- State (categorical)
- County (categorical)
- Track type (categorical)
- Track Management (categorical)
- Accident Type (categorical)
- Accident Cause (categorical)
- Equipment damage (numerical) - amount of money spent on damages
- Track Damage (numerical)- amount of money spent on track repair
- killed (numerical) - number of people killed from accident
- injured (numerical) - number of people injured from accident
- RREquip (categorical) - type of train
- Speed (numerical) - mph the train was going at during impact
- Locomotives derailed (numerical) - the number of locomotives
derailed
- Cars Derailed (numerical) - the number of cars derailed
3 Pairwise Scatterplot
library(psych)
# Keep only numeric columns
numData <- myData[, sapply(myData, is.numeric)]
# Optional: check the structure
str(numData)
tibble [2,621 × 10] (S3: tbl_df/tbl/data.frame)
$ Acident : num [1:2621] 1 2 3 4 5 6 7 8 9 10 ...
$ Month : num [1:2621] 1 1 1 1 1 1 1 1 1 1 ...
$ Day : num [1:2621] 1 2 2 2 2 2 2 3 3 3 ...
$ EqpDamg : num [1:2621] 8485 1500000 103833 15000 9964 ...
$ TrkDamg : num [1:2621] 333700 0 17615 50000 750 ...
$ Killed : num [1:2621] 0 0 0 0 0 0 0 0 0 0 ...
$ Injured : num [1:2621] 0 0 0 0 0 0 0 0 0 0 ...
$ Speed : num [1:2621] 24 0 10 4 45 2 4 9 3 10 ...
$ LocosDer: num [1:2621] 0 0 0 5 0 0 0 0 0 0 ...
$ CarsDer : num [1:2621] 13 0 6 0 0 1 3 6 0 0 ...
# Pairwise scatterplot
pairs.panels(
numData,
pch = 21,
main = "Pair-wise Scatter Plot of numerical variables",
cex.main = 1.1
)

3.1 Finding a Strong Correlation
I wanted to see which variables had the strongest correlation to make
the next step easier. As you can see, I had to pivot from my original
plan of finding a variable that correlates with number of people killed
and number of people injured. This is because that both of these numbers
were both very little throughout all of the accidents, with the results
typically being 0 or 1. I had to change my regression model to find two
other variables that had a correlation. My new explanatory variable is
cars derailed and my new response variable is equipment damage. The
correlation coefficient for these two variables is 0.66.
# Get only numeric columns
numeric_data <- myData[sapply(myData, is.numeric)]
# Correlation matrix
cor_matrix <- cor(numeric_data, use = "complete.obs")
cor_matrix
Acident Month Day EqpDamg TrkDamg
Acident 1.000000000 0.996205159 0.026732926 -0.007057778 -0.003522700
Month 0.996205159 1.000000000 -0.056019706 -0.005761464 -0.004673623
Day 0.026732926 -0.056019706 1.000000000 -0.011989520 0.015826863
EqpDamg -0.007057778 -0.005761464 -0.011989520 1.000000000 0.476854734
TrkDamg -0.003522700 -0.004673623 0.015826863 0.476854734 1.000000000
Killed -0.023449754 -0.023510018 0.004927620 0.023794277 0.004064826
Injured -0.008792426 -0.006753119 -0.026061616 0.117567797 -0.010711459
Speed -0.017698831 -0.016700409 -0.002005197 0.239990735 0.162821086
LocosDer -0.022181280 -0.022486719 0.011468588 0.085812854 0.046443288
CarsDer -0.006447788 -0.005438397 -0.011992079 0.658219030 0.453507160
Killed Injured Speed LocosDer CarsDer
Acident -0.023449754 -0.008792426 -0.017698831 -0.022181280 -0.006447788
Month -0.023510018 -0.006753119 -0.016700409 -0.022486719 -0.005438397
Day 0.004927620 -0.026061616 -0.002005197 0.011468588 -0.011992079
EqpDamg 0.023794277 0.117567797 0.239990735 0.085812854 0.658219030
TrkDamg 0.004064826 -0.010711459 0.162821086 0.046443288 0.453507160
Killed 1.000000000 0.055314747 0.247128656 0.016628834 -0.048867444
Injured 0.055314747 1.000000000 0.214750720 0.072628280 -0.024335555
Speed 0.247128656 0.214750720 1.000000000 0.007642235 0.126906896
LocosDer 0.016628834 0.072628280 0.007642235 1.000000000 -0.018006320
CarsDer -0.048867444 -0.024335555 0.126906896 -0.018006320 1.000000000
4 Results and Conclusions
4.1 Least Squares Regression Model
There is a positive linear association between cars derailed and
equipment damage.
Cars_derailed <- myData$CarsDer
Equipment_Damage <- myData$EqpDamg
plot(Cars_derailed, Equipment_Damage, pch = 21, col ="red",
main = "Relationship between Cars Derailed and Equipment Damage")

4.2 Plotting the Residuals
The Residuals vs Fitted plot shows there is not a constant variance
in the residuals. The QQ-Plot violates the normality assumption as well.
The Scale Location plot shows the same assumption violation that the
Residuals vs Fitted plot showed. There are three outliers: accident
observation numbers 77, 273, and 981.
parametric.model <- lm(Cars_derailed ~ Equipment_Damage)
par(mfrow = c(2,2))
plot(parametric.model)

par(mar = c(4, 4, 2, 1))
plot(Cars_derailed, Equipment_Damage)

4.3 Bootstrap Regression
Since the normality assumptions were not met, we will be using
bootstrap confidence intervals to determine the slope. We will be using
a 95% confidence interval.
boot.beta <- boot(data = myData, statistic = boot_fn, R = 1000)
boot.beta
ORDINARY NONPARAMETRIC BOOTSTRAP
Call:
boot(data = myData, statistic = boot_fn, R = 1000)
Bootstrap Statistics :
original bias std. error
t1* -16757.54 0 0
t2* 30025.80 0 0
vec.id <- 1:length(Equipment_Damage)
boot.id <- sample(vec.id, length(Equipment_Damage), replace = TRUE)
boot.Equipment_Damage <- Equipment_Damage[boot.id]
boot.Cars_derailed <- Cars_derailed[boot.id]
B <- 1000
boot.beta0 <- NULL
boot.beta1 <- NULL
vec.id <- 1:length(Equipment_Damage)
for(i in 1:B){
boot.id <- sample(vec.id, length(Equipment_Damage), replace = TRUE)
boot.Equipment_Damage <- Equipment_Damage[boot.id]
boot.Cars_derailed <- Cars_derailed[boot.id]
boot.reg <- lm(Equipment_Damage[boot.id] ~ Cars_derailed[boot.id])
boot.beta0[i] <- coef(boot.reg)[1]
boot.beta1[i] <- coef(boot.reg)[2]}
boot.beta0.ci <- quantile(boot.beta0, c(0.025, 0.975), type = 2)
boot.beta1.ci <- quantile(boot.beta1, c(0.025, 0.975), type = 2)
boot.coef <- data.frame(rbind(boot.beta0.ci, boot.beta1.ci))
names(boot.coef) <- c("2.5%", "97.5%")
pander(boot.coef, caption="Bootstrap Confidence Intervals of Regression Coefficients")
Bootstrap Confidence Intervals of Regression Coefficients Using
bootstrap re sampling with 1,000 replications, we obtained the following
95% confidence intervals for the regression coefficients:
boot.beta0.ci |
-27647 |
-5178 |
boot.beta1.ci |
25254 |
34519 |
Intercept (boot.beta0.ci): The 95% bootstrap confidence interval
ranges from –27,327 to –6,691. This suggests that when the number of
cars derailed is zero, the expected equipment damage is significantly
below zero. The negative intercept indicates that the model’s prediction
at very low values of cars derailed may not be meaningful outside the
observed data range.
Slope (boot.beta1.ci): The 95% bootstrap confidence interval ranges
from 25,819 to 34,771. This indicates a strong positive relationship:
for each additional car derailed, equipment damage is estimated to
increase by between $25,800 and 34,800. Because the interval does not
include zero, the effect of cars derailed on equipment damage is
statistically significant.
4.4 P-Values
We ran inferential statistics to find the estimate and t-value of our
slope and intercept.
library(pander)
parametric.model <- lm(Equipment_Damage ~ Cars_derailed, data = myData)
reg.table <- coef(summary(parametric.model))
response_var <- all.vars(formula(parametric.model))[1]
predictors <- all.vars(formula(parametric.model))[-1]
caption_text <- paste0(
"Inferential statistics for predicting ", response_var,
" (y) from ", paste(predictors, collapse = ", "), " (x)"
)
pander(reg.table, caption = caption_text)
Inferential statistics for predicting Equipment_Damage (y) from
Cars_derailed (x)
(Intercept) |
-16758 |
4143 |
-4.045 |
5.386e-05 |
Cars_derailed |
30026 |
671 |
44.74 |
0 |
Our slope and intercept are highly significant. For each additional
car derailed, equipment damage increases by $30,026.
6 Conclusion
We should be using the bootstrap method because the residual
assumptions are not met. We can see that there is not constant variance
within the residuals. It also appears that none of the variables had a
strong correlation, with the only two variables with even a moderate
correlation being Equipment Damage and Cars Derailed.
LS0tDQp0aXRsZTogIlNUQTMyMSBBc3NpZ25tZW50IDIiDQphdXRob3I6ICJMdWtlIFZvbG0iDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6ICAgICAgICAgICAjIG91dHB1dCBkb2N1bWVudCBmb3JtYXQNCiAgICB0b2M6IHllcyAgICAgICAgICAgICAgICMgYWRkIHRhYmxlIGNvbnRlbnRzDQogICAgdG9jX2Zsb2F0OiB5ZXMgICAgICAgICAjIHRvY19wcm9wZXJ0eTogZmxvYXRpbmcNCiAgICB0b2NfZGVwdGg6IDQgICAgICAgICAgICMgZGVwdGggb2YgVE9DIGhlYWRpbmdzDQogICAgZmlnX3dpZHRoOiA2ICAgICAgICAgICAjIGdsb2JhbCBmaWd1cmUgd2lkdGgNCiAgICBmaWdfaGVpZ2h0OiA0ICAgICAgICAgICMgZ2xvYmFsIGZpZ3VyZSBoZWlnaHQNCiAgICBmaWdfY2FwdGlvbjogeWVzICAgICAgICMgYWRkIGZpZ3VyZSBjYXB0aW9uDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubyAgICMgbnVtYmVyaW5nIHNlY3Rpb24gaGVhZGluZ3MNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMgICAgICMgVE9DIHN1YmhlYWRpbmcgY29sbGFwc2luZw0KICAgIGNvZGVfZm9sZGluZzogaGlkZSAgICAgIyBmb2xkaW5nL3Nob3dpbmcgY29kZSANCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMgICAgICMgYWxsb3cgdG8gZG93bmxvYWQgY29tcGxldGUgUk1hcmtkb3duIHNvdXJjZSBjb2RlDQogICAgc21vb3RoX3Njcm9sbDogeWVzICAgICAjIHNjcm9sbGluZyB0ZXh0IG9mIHRoZSBkb2N1bWVudA0KICAgIHRoZW1lOiBsdW1lbiAgICAgICAgICAgIyB2aXN1YWwgdGhlbWUgZm9yIEhUTUwgZG9jdW1lbnQgb25seQ0KICAgIGhpZ2hsaWdodDogdGFuZ28gICAgICAgIyBjb2RlIHN5bnRheCBoaWdobGlnaHRpbmcgc3R5bGVzDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgd29yZF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogJzQnDQotLS0NCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0NCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgxIHsgLyogSGVhZGVyIDEgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDIwcHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMiB7IC8qIEhlYWRlciAyIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE2cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTRweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogQWRkIGRvdHMgYWZ0ZXIgbnVtYmVyZWQgaGVhZGVycyAqLw0KLmhlYWRlci1zZWN0aW9uLW51bWJlcjo6YWZ0ZXIgew0KICBjb250ZW50OiAiLiI7DQp9DQpgYGANCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0Kc2V0d2QoIkM6L1VzZXJzL3ZvbG0xL09uZURyaXZlL0RvY3VtZW50cyIpDQpsaWJyYXJ5KHJlYWR4bCkNCm15RGF0YSA8LSByZWFkX2V4Y2VsKCJ0cmFpbl9hY2NfMjAxMCAoMSkueGxzIikNCm15ZGF0YSA8LSBteURhdGFbLCAtMV0NCmlmICghcmVxdWlyZSgia25pdHIiKSkgeyAgICAgICAgICAgICAgICAgICAgICAjIHVzZSBjb25kaXRpb25hbCBzdGF0ZW1lbnQgdG8gZGV0ZWN0DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpICAgICAgICAgICAgICAgICAgIyB3aGV0aGVyIGEgcGFja2FnZSB3YXMgaW5zdGFsbGVkIGluDQogICBsaWJyYXJ5KGtuaXRyKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB5b3VyIG1hY2hpbmUuIElmIG5vdCwgaW5zdGFsbCBpdCBhbmQNCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGxvYWQgaXQgdG8gdGhlIHdvcmtpbmcgZGlyZWN0b3J5Lg0KIw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAgICAgICMgaW5jbHVkZSBjb2RlIGNodW5rIGluIHRoZSBvdXRwdXQgZmlsZQ0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICAgICAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGhlIG91dHB1dCBmaWxlLiANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVFJVRSwgICAgICAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsICAgICAgICAjIHN1cHByZXNzIG1lc3NhZ2VzIA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQSAgICAgICAgICAgICMgcmVtb3ZlIHRoZSBkZWZhdWx0IGxlYWRpbmcgaGFzaCB0YWdzIGluIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICApICAgDQpgYGANCg0KDQoNCiMgMSBJbnRyb2R1Y3Rpb24NCg0KICBGb3IgQXNzaWdubWVudCAyLCB3ZSBhcmUgdGFza2VkIHdpdGggZmluZGluZyBhIGRhdGEgc2V0IGFuZCBzZWxlY3Rpbmcgb25lIGV4cGxhbmF0b3J5IHZhcmlhYmxlIHRvIGNvcnJlbGF0ZSB3aXRoIHRoZSByZXNwb25zZSB2YXJpYWJsZS4gV2Ugd2lsbCBiZSB1c2luZyB0aGUgbGVhc3Qgc3F1YXJlcyBtZXRob2QgYW5kIDk1JSBib290c3RyYXAgY29uZmlkZW5jZSBpbnRlcnZhbHMgaWYgYXBwbGljYWJsZS4NCg0KIyAyIERlc2NyaXB0aW9uIG9mIG15IERhdGEgU2V0DQogIA0KICBUaGUgZGF0YSBzZXQgSSBjaG9zZSB3YXMgUmFpbHJvYWQgQWNjaWRlbnRzIGluIHRoZSBVLlMuIGluIDIwMTAuIFRoZSBkYXRhIHdhcyBjb2xsZWN0ZWQgdmlhIHNhZmV0eWRhdGEuZnJhLmRvdC5nb3YuIFRoaXMgZGF0YSBzZXQgaGFzIGEgaGFuZGZ1bCBvZiByZXNwb25zZSB2YXJpYWJsZXMsIHNvIEknbSBnb2luZyB0byBzZWUgd2hpY2ggZXhwbGFuYXRvcnkgdmFyaWFibGVzIGNvcnJlbGF0ZSBiZXN0IHdpdGggbnVtYmVyIG9mIHBlb3BsZSBraWxsZWQsIG51bWJlciBvZiBwZW9wbGUgaW5qdXJlZCwgbnVtYmVyIG9mIGxvY29tb3RpdmVzIGRlcmFpbGVkLCBhbmQgbnVtYmVyIG9mIGNhcnMgZGVyYWlsZWQuIE15IGd1ZXNzIGlzIHRoYXQgc3BlZWQsIGVxdWlwbWVudCBkYW1hZ2UsIGFuZCBudW1iZXIgZXF1aXBtZW50IGRhbWFnZSB3aWxsIGNvcnJlbGF0ZSB0aGUgc3Ryb25nZXN0IHdpdGggdGhlc2UgcmVzcG9uc2UgdmFyaWFibGVzLkJlZm9yZSBldmVuIGRpZ2dpbmcgaW50byB0aGUgZGF0YSwgaXQgbG9va3MgbGlrZSB0aGUgc2V0IGRvZXMgaGF2ZSBlbm91Z2ggaW5mb3JtYXRpb24gdG8gYW5zd2VyIHRoZXNlIHF1ZXN0aW9ucy4NCg0KIyMgMi4xIFZhcmlhYmxlcw0KDQogICogUmFpbHJvYWQgKGNhdGVnb3JpY2FsKSAtIG5hbWUgb2YgcmFpbHJvYWQNCiAgKiBNb250aCAoY2F0ZWdvcmljYWwpDQogICogRGF5IChjYXRlZ29yaWNhbCkgLSBkYXlzIG9mIHRoZSB3ZWVrIGxhYmVsZWQgMSB0aHJvdWdoIDcNCiAgKiBTdGF0ZSAoY2F0ZWdvcmljYWwpDQogICogQ291bnR5IChjYXRlZ29yaWNhbCkNCiAgKiBUcmFjayB0eXBlIChjYXRlZ29yaWNhbCkNCiAgKiBUcmFjayBNYW5hZ2VtZW50IChjYXRlZ29yaWNhbCkNCiAgKiBBY2NpZGVudCBUeXBlIChjYXRlZ29yaWNhbCkNCiAgKiBBY2NpZGVudCBDYXVzZSAoY2F0ZWdvcmljYWwpDQogICogRXF1aXBtZW50IGRhbWFnZSAobnVtZXJpY2FsKSAtIGFtb3VudCBvZiBtb25leSBzcGVudCBvbiBkYW1hZ2VzDQogICogVHJhY2sgRGFtYWdlIChudW1lcmljYWwpLSBhbW91bnQgb2YgbW9uZXkgc3BlbnQgb24gdHJhY2sgcmVwYWlyDQogICoga2lsbGVkIChudW1lcmljYWwpIC0gbnVtYmVyIG9mIHBlb3BsZSBraWxsZWQgZnJvbSBhY2NpZGVudA0KICAqIGluanVyZWQgKG51bWVyaWNhbCkgLSBudW1iZXIgb2YgcGVvcGxlIGluanVyZWQgZnJvbSBhY2NpZGVudA0KICAqIFJSRXF1aXAgKGNhdGVnb3JpY2FsKSAtIHR5cGUgb2YgdHJhaW4NCiAgKiBTcGVlZCAobnVtZXJpY2FsKSAtIG1waCB0aGUgdHJhaW4gd2FzIGdvaW5nIGF0IGR1cmluZyBpbXBhY3QNCiAgKiBMb2NvbW90aXZlcyBkZXJhaWxlZCAobnVtZXJpY2FsKSAtIHRoZSBudW1iZXIgb2YgbG9jb21vdGl2ZXMgZGVyYWlsZWQNCiAgKiBDYXJzIERlcmFpbGVkIChudW1lcmljYWwpIC0gdGhlIG51bWJlciBvZiBjYXJzIGRlcmFpbGVkDQoNCmBgYHtyIHNlY29uZCBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShib290KQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocGFuZGVyKQ0Kc2V0LnNlZWQoMTIzKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KDQpsaWJyYXJ5KGtuaXRyKQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5ncyA9IEZBTFNFLCAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVFJVRSApICAgICAgIA0KbGlicmFyeShyZWFkeGwpDQpteURhdGEgPC0gcmVhZF9leGNlbCgidHJhaW5fYWNjXzIwMTAgKDEpLnhscyIpDQpteWRhdGEgPC0gbXlEYXRhWywgLTFdDQoNCmBgYA0KDQojIDMgUGFpcndpc2UgU2NhdHRlcnBsb3QNCg0KYGBge3IgcGFpcndpc2UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMn0NCmxpYnJhcnkocHN5Y2gpDQoNCiMgS2VlcCBvbmx5IG51bWVyaWMgY29sdW1ucw0KbnVtRGF0YSA8LSBteURhdGFbLCBzYXBwbHkobXlEYXRhLCBpcy5udW1lcmljKV0NCg0KIyBPcHRpb25hbDogY2hlY2sgdGhlIHN0cnVjdHVyZQ0Kc3RyKG51bURhdGEpDQoNCiMgUGFpcndpc2Ugc2NhdHRlcnBsb3QNCnBhaXJzLnBhbmVscygNCiAgbnVtRGF0YSwNCiAgcGNoID0gMjEsDQogIG1haW4gPSAiUGFpci13aXNlIFNjYXR0ZXIgUGxvdCBvZiBudW1lcmljYWwgdmFyaWFibGVzIiwNCiAgY2V4Lm1haW4gPSAxLjENCikNCmBgYA0KDQojIyAzLjEgRmluZGluZyBhIFN0cm9uZyBDb3JyZWxhdGlvbg0KDQogIEkgd2FudGVkIHRvIHNlZSB3aGljaCB2YXJpYWJsZXMgaGFkIHRoZSBzdHJvbmdlc3QgY29ycmVsYXRpb24gdG8gbWFrZSB0aGUgbmV4dCBzdGVwIGVhc2llci4gQXMgeW91IGNhbiBzZWUsIEkgaGFkIHRvIHBpdm90IGZyb20gbXkgb3JpZ2luYWwgcGxhbiBvZiBmaW5kaW5nIGEgdmFyaWFibGUgdGhhdCBjb3JyZWxhdGVzIHdpdGggbnVtYmVyIG9mIHBlb3BsZSBraWxsZWQgYW5kIG51bWJlciBvZiBwZW9wbGUgaW5qdXJlZC4gVGhpcyBpcyBiZWNhdXNlIHRoYXQgYm90aCBvZiB0aGVzZSBudW1iZXJzIHdlcmUgYm90aCB2ZXJ5IGxpdHRsZSB0aHJvdWdob3V0IGFsbCBvZiB0aGUgYWNjaWRlbnRzLCB3aXRoIHRoZSByZXN1bHRzIHR5cGljYWxseSBiZWluZyAwIG9yIDEuIEkgaGFkIHRvIGNoYW5nZSBteSByZWdyZXNzaW9uIG1vZGVsIHRvIGZpbmQgdHdvIG90aGVyIHZhcmlhYmxlcyB0aGF0IGhhZCBhIGNvcnJlbGF0aW9uLiBNeSBuZXcgZXhwbGFuYXRvcnkgdmFyaWFibGUgaXMgY2FycyBkZXJhaWxlZCBhbmQgbXkgbmV3IHJlc3BvbnNlIHZhcmlhYmxlIGlzIGVxdWlwbWVudCBkYW1hZ2UuIFRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBmb3IgdGhlc2UgdHdvIHZhcmlhYmxlcyBpcyAwLjY2Lg0KDQpgYGB7cn0NCiMgR2V0IG9ubHkgbnVtZXJpYyBjb2x1bW5zDQpudW1lcmljX2RhdGEgPC0gbXlEYXRhW3NhcHBseShteURhdGEsIGlzLm51bWVyaWMpXQ0KDQojIENvcnJlbGF0aW9uIG1hdHJpeA0KY29yX21hdHJpeCA8LSBjb3IobnVtZXJpY19kYXRhLCB1c2UgPSAiY29tcGxldGUub2JzIikNCg0KY29yX21hdHJpeA0KYGBgDQoNCg0KIyA0IFJlc3VsdHMgYW5kIENvbmNsdXNpb25zDQoNCiMjIDQuMSBMZWFzdCBTcXVhcmVzIFJlZ3Jlc3Npb24gTW9kZWwNCg0KICBUaGVyZSBpcyBhIHBvc2l0aXZlIGxpbmVhciBhc3NvY2lhdGlvbiBiZXR3ZWVuIGNhcnMgZGVyYWlsZWQgYW5kIGVxdWlwbWVudCBkYW1hZ2UuDQogIA0KYGBge3J9DQpDYXJzX2RlcmFpbGVkIDwtIG15RGF0YSRDYXJzRGVyDQpFcXVpcG1lbnRfRGFtYWdlIDwtIG15RGF0YSRFcXBEYW1nDQpwbG90KENhcnNfZGVyYWlsZWQsIEVxdWlwbWVudF9EYW1hZ2UsIHBjaCA9IDIxLCBjb2wgPSJyZWQiLA0KICAgICBtYWluID0gIlJlbGF0aW9uc2hpcCBiZXR3ZWVuIENhcnMgRGVyYWlsZWQgYW5kIEVxdWlwbWVudCBEYW1hZ2UiKQ0KYGBgDQoNCiMjIDQuMiBQbG90dGluZyB0aGUgUmVzaWR1YWxzDQoNCiAgVGhlIFJlc2lkdWFscyB2cyBGaXR0ZWQgcGxvdCBzaG93cyB0aGVyZSBpcyBub3QgYSBjb25zdGFudCB2YXJpYW5jZSBpbiB0aGUgcmVzaWR1YWxzLiBUaGUgUVEtUGxvdCB2aW9sYXRlcyB0aGUgbm9ybWFsaXR5IGFzc3VtcHRpb24gYXMgd2VsbC4gVGhlIFNjYWxlIExvY2F0aW9uIHBsb3Qgc2hvd3MgdGhlIHNhbWUgYXNzdW1wdGlvbiB2aW9sYXRpb24gdGhhdCB0aGUgUmVzaWR1YWxzIHZzIEZpdHRlZCBwbG90IHNob3dlZC4gVGhlcmUgYXJlIHRocmVlIG91dGxpZXJzOiBhY2NpZGVudCBvYnNlcnZhdGlvbiBudW1iZXJzIDc3LCAyNzMsIGFuZCA5ODEuIA0KICANCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02fQ0KcGFyYW1ldHJpYy5tb2RlbCA8LSBsbShDYXJzX2RlcmFpbGVkIH4gRXF1aXBtZW50X0RhbWFnZSkNCnBhcihtZnJvdyA9IGMoMiwyKSkNCnBsb3QocGFyYW1ldHJpYy5tb2RlbCkNCnBhcihtYXIgPSBjKDQsIDQsIDIsIDEpKQ0KcGxvdChDYXJzX2RlcmFpbGVkLCBFcXVpcG1lbnRfRGFtYWdlKQ0KYGBgDQoNCg0KYGBge3IgYm9vdHN0cmFwIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShib290KQ0KYm9vdF9mbiA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzKSB7DQogIGQgPC0gZGF0YVtpbmRpY2VzLCBdICAgICAgICAgICAgICANCiAgZml0IDwtIGxtKEVxdWlwbWVudF9EYW1hZ2UgfiBDYXJzX2RlcmFpbGVkLCBkYXRhID0gZCkgICANCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAgICAgICAgICAgICANCn0NCmBgYA0KDQojIyA0LjMgQm9vdHN0cmFwIFJlZ3Jlc3Npb24NCg0KICBTaW5jZSB0aGUgbm9ybWFsaXR5IGFzc3VtcHRpb25zIHdlcmUgbm90IG1ldCwgd2Ugd2lsbCBiZSB1c2luZyBib290c3RyYXAgY29uZmlkZW5jZSBpbnRlcnZhbHMgdG8gZGV0ZXJtaW5lIHRoZSBzbG9wZS4gV2Ugd2lsbCBiZSB1c2luZyBhIDk1JSBjb25maWRlbmNlIGludGVydmFsLg0KICANCmBgYHtyfQ0KYm9vdC5iZXRhIDwtIGJvb3QoZGF0YSA9IG15RGF0YSwgc3RhdGlzdGljID0gYm9vdF9mbiwgUiA9IDEwMDApDQoNCg0KYm9vdC5iZXRhDQoNCnZlYy5pZCA8LSAxOmxlbmd0aChFcXVpcG1lbnRfRGFtYWdlKQ0KYm9vdC5pZCA8LSBzYW1wbGUodmVjLmlkLCBsZW5ndGgoRXF1aXBtZW50X0RhbWFnZSksIHJlcGxhY2UgPSBUUlVFKQ0KYm9vdC5FcXVpcG1lbnRfRGFtYWdlIDwtIEVxdWlwbWVudF9EYW1hZ2VbYm9vdC5pZF0NCmJvb3QuQ2Fyc19kZXJhaWxlZCA8LSBDYXJzX2RlcmFpbGVkW2Jvb3QuaWRdDQoNCkIgPC0gMTAwMA0KYm9vdC5iZXRhMCA8LSBOVUxMDQpib290LmJldGExIDwtIE5VTEwNCnZlYy5pZCA8LSAxOmxlbmd0aChFcXVpcG1lbnRfRGFtYWdlKQ0KZm9yKGkgaW4gMTpCKXsNCiAgYm9vdC5pZCA8LSBzYW1wbGUodmVjLmlkLCBsZW5ndGgoRXF1aXBtZW50X0RhbWFnZSksIHJlcGxhY2UgPSBUUlVFKQ0KYm9vdC5FcXVpcG1lbnRfRGFtYWdlIDwtIEVxdWlwbWVudF9EYW1hZ2VbYm9vdC5pZF0NCmJvb3QuQ2Fyc19kZXJhaWxlZCA8LSBDYXJzX2RlcmFpbGVkW2Jvb3QuaWRdDQpib290LnJlZyA8LSBsbShFcXVpcG1lbnRfRGFtYWdlW2Jvb3QuaWRdIH4gQ2Fyc19kZXJhaWxlZFtib290LmlkXSkNCmJvb3QuYmV0YTBbaV0gPC0gY29lZihib290LnJlZylbMV0NCmJvb3QuYmV0YTFbaV0gPC0gY29lZihib290LnJlZylbMl19DQpib290LmJldGEwLmNpIDwtIHF1YW50aWxlKGJvb3QuYmV0YTAsIGMoMC4wMjUsIDAuOTc1KSwgdHlwZSA9IDIpDQpib290LmJldGExLmNpIDwtIHF1YW50aWxlKGJvb3QuYmV0YTEsIGMoMC4wMjUsIDAuOTc1KSwgdHlwZSA9IDIpDQpib290LmNvZWYgPC0gZGF0YS5mcmFtZShyYmluZChib290LmJldGEwLmNpLCBib290LmJldGExLmNpKSkNCm5hbWVzKGJvb3QuY29lZikgPC0gYygiMi41JSIsICI5Ny41JSIpDQpwYW5kZXIoYm9vdC5jb2VmLCBjYXB0aW9uPSJCb290c3RyYXAgQ29uZmlkZW5jZSBJbnRlcnZhbHMgb2YgUmVncmVzc2lvbiBDb2VmZmljaWVudHMiKQ0KYGBgDQpVc2luZyBib290c3RyYXAgcmUgc2FtcGxpbmcgd2l0aCAxLDAwMCByZXBsaWNhdGlvbnMsIHdlIG9idGFpbmVkIHRoZSBmb2xsb3dpbmcgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGZvciB0aGUgcmVncmVzc2lvbiBjb2VmZmljaWVudHM6DQoNCkludGVyY2VwdCAoYm9vdC5iZXRhMC5jaSk6IFRoZSA5NSUgYm9vdHN0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWwgcmFuZ2VzIGZyb20g4oCTMjcsMzI3IHRvIOKAkzYsNjkxLiBUaGlzIHN1Z2dlc3RzIHRoYXQgd2hlbiB0aGUgbnVtYmVyIG9mIGNhcnMgZGVyYWlsZWQgaXMgemVybywgdGhlIGV4cGVjdGVkIGVxdWlwbWVudCBkYW1hZ2UgaXMgc2lnbmlmaWNhbnRseSBiZWxvdyB6ZXJvLiBUaGUgbmVnYXRpdmUgaW50ZXJjZXB0IGluZGljYXRlcyB0aGF0IHRoZSBtb2RlbOKAmXMgcHJlZGljdGlvbiBhdCB2ZXJ5IGxvdyB2YWx1ZXMgb2YgY2FycyBkZXJhaWxlZCBtYXkgbm90IGJlIG1lYW5pbmdmdWwgb3V0c2lkZSB0aGUgb2JzZXJ2ZWQgZGF0YSByYW5nZS4NCg0KU2xvcGUgKGJvb3QuYmV0YTEuY2kpOiBUaGUgOTUlIGJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFsIHJhbmdlcyBmcm9tIDI1LDgxOSB0byAzNCw3NzEuIFRoaXMgaW5kaWNhdGVzIGEgc3Ryb25nIHBvc2l0aXZlIHJlbGF0aW9uc2hpcDogZm9yIGVhY2ggYWRkaXRpb25hbCBjYXIgZGVyYWlsZWQsIGVxdWlwbWVudCBkYW1hZ2UgaXMgZXN0aW1hdGVkIHRvIGluY3JlYXNlIGJ5IGJldHdlZW4gJDI1LDgwMCBhbmQgMzQsODAwLiBCZWNhdXNlIHRoZSBpbnRlcnZhbCBkb2VzIG5vdCBpbmNsdWRlIHplcm8sIHRoZSBlZmZlY3Qgb2YgY2FycyBkZXJhaWxlZCBvbiBlcXVpcG1lbnQgZGFtYWdlIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuDQoNCiMjIDQuNCBQLVZhbHVlcw0KDQpXZSByYW4gaW5mZXJlbnRpYWwgc3RhdGlzdGljcyB0byBmaW5kIHRoZSBlc3RpbWF0ZSBhbmQgdC12YWx1ZSBvZiBvdXIgc2xvcGUgYW5kIGludGVyY2VwdC4NCg0KYGBge3J9DQpsaWJyYXJ5KHBhbmRlcikNCg0KcGFyYW1ldHJpYy5tb2RlbCA8LSBsbShFcXVpcG1lbnRfRGFtYWdlIH4gQ2Fyc19kZXJhaWxlZCwgZGF0YSA9IG15RGF0YSkNCnJlZy50YWJsZSA8LSBjb2VmKHN1bW1hcnkocGFyYW1ldHJpYy5tb2RlbCkpDQoNCnJlc3BvbnNlX3ZhciA8LSBhbGwudmFycyhmb3JtdWxhKHBhcmFtZXRyaWMubW9kZWwpKVsxXQ0KcHJlZGljdG9ycyA8LSBhbGwudmFycyhmb3JtdWxhKHBhcmFtZXRyaWMubW9kZWwpKVstMV0NCg0KY2FwdGlvbl90ZXh0IDwtIHBhc3RlMCgNCiAgIkluZmVyZW50aWFsIHN0YXRpc3RpY3MgZm9yIHByZWRpY3RpbmcgIiwgcmVzcG9uc2VfdmFyLA0KICAiICh5KSBmcm9tICIsIHBhc3RlKHByZWRpY3RvcnMsIGNvbGxhcHNlID0gIiwgIiksICIgKHgpIg0KKQ0KDQpwYW5kZXIocmVnLnRhYmxlLCBjYXB0aW9uID0gY2FwdGlvbl90ZXh0KQ0KYGBgDQoNCk91ciBzbG9wZSBhbmQgaW50ZXJjZXB0IGFyZSBoaWdobHkgc2lnbmlmaWNhbnQuIEZvciBlYWNoIGFkZGl0aW9uYWwgY2FyIGRlcmFpbGVkLCBlcXVpcG1lbnQgZGFtYWdlIGluY3JlYXNlcyBieSAkMzAsMDI2Lg0KDQojIDYgQ29uY2x1c2lvbg0KDQogIFdlIHNob3VsZCBiZSB1c2luZyB0aGUgYm9vdHN0cmFwIG1ldGhvZCBiZWNhdXNlIHRoZSByZXNpZHVhbCBhc3N1bXB0aW9ucyBhcmUgbm90IG1ldC4gV2UgY2FuIHNlZSB0aGF0IHRoZXJlIGlzIG5vdCBjb25zdGFudCB2YXJpYW5jZSB3aXRoaW4gdGhlIHJlc2lkdWFscy4gSXQgYWxzbyBhcHBlYXJzIHRoYXQgbm9uZSBvZiB0aGUgdmFyaWFibGVzIGhhZCBhIHN0cm9uZyBjb3JyZWxhdGlvbiwgd2l0aCB0aGUgb25seSB0d28gdmFyaWFibGVzIHdpdGggZXZlbiBhIG1vZGVyYXRlIGNvcnJlbGF0aW9uIGJlaW5nIEVxdWlwbWVudCBEYW1hZ2UgYW5kIENhcnMgRGVyYWlsZWQu