Data Processing:
The data is read in from the working directory using the read.csv function. Data processing and visualization packages are also loaded.
library(dplyr)
library(ggplot2)
storm_data <- read.csv("repdata%2Fdata%2FStormData.csv.bz2", as.is = TRUE)
Using the names function, the available database variables are viewed:
names(storm_data)
[1] "STATE__" "BGN_DATE" "BGN_TIME" "TIME_ZONE" "COUNTY" "COUNTYNAME" "STATE"
[8] "EVTYPE" "BGN_RANGE" "BGN_AZI" "BGN_LOCATI" "END_DATE" "END_TIME" "COUNTY_END"
[15] "COUNTYENDN" "END_RANGE" "END_AZI" "END_LOCATI" "LENGTH" "WIDTH" "F"
[22] "MAG" "FATALITIES" "INJURIES" "PROPDMG" "PROPDMGEXP" "CROPDMG" "CROPDMGEXP"
[29] "WFO" "STATEOFFIC" "ZONENAMES" "LATITUDE" "LONGITUDE" "LATITUDE_E" "LONGITUDE_"
[36] "REMARKS" "REFNUM"
The NOAA storm database documentation can be found here: ( http://www.nws.noaa.gov/directives/). After reviewing this documentation, the variables FATALITIES and INJURIES appear to be the only variables pertinent to the question of harm caused to individual health.
The variables PROPDMG, PROPDMEGXP, CROPDMG and CROPDMGEXP each relate to the economic consequences caused by storm events. PROPDMG and PROPDMGEXP give property damage totals with PROPDMGEXP providing a multiplier for the damage amount (code “H” for hundreds of dollars, “K” for thousands, “M” for millions, etc.). CROPDMG and CROPDMGEXP give similar damage estimates for agricultural losses.
Assessment of harm to population health
For ease of visualization, subsets of the data are created containing only event type and fatalities/injuries. We then take a cursory look at the data using the summary function.
death <- storm_data[,c(8,23)]
injury <- storm_data[,c(8,24)]
summary(death$FATALITIES)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.0000 0.0000 0.0000 0.0168 0.0000 583.0000
summary(injury$INJURIES)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.0000 0.0000 0.0000 0.1557 0.0000 1700.0000
Both the fatality and injury variables contain a large number of zero values. Those are removed here, and the resulting five most fatal/injurious event types are retained for plotting.
death <- death[death$FATALITIES > 0,]
injury <- injury[injury$INJURIES > 0,]
total_deaths <- aggregate(death$FATALITIES, by = list(death$EVTYPE), FUN = "sum")
total_deaths <- total_deaths[order(-total_deaths[,2]),]
total_deaths <- total_deaths[1:5,]
names(total_deaths) <- c("Event", "Total_Deaths")
rownames(total_deaths) <- NULL
total_injuries <- aggregate(injury$INJURIES, by = list(injury$EVTYPE), FUN = "sum")
total_injuries <- total_injuries[order(-total_injuries[,2]),]
total_injuries <- total_injuries[1:5,]
names(total_injuries) <- c("Event", "Total_Injuries")
rownames(total_injuries) <- NULL
ggplot2 is used to plot the data:
ggplot(total_deaths, aes(x=reorder(Event, -Total_Deaths), y=Total_Deaths, fill=Event)) +
labs(title = "The Five Deadliest Weather Event Types", x = "Weather Event", y = "Total Deaths") +
geom_bar(stat="identity") + ylim(0, 6500) + theme(legend.position = "none")

ggplot(total_injuries, aes(x=reorder(Event, -Total_Injuries), y=Total_Injuries, fill=Event)) +
labs(title = "Weather Event Types That Cause the Most Injuries") +
labs(x = "Weather Event", y = "Total Injuries") +
geom_bar(stat="identity") + ylim(0, 101000) + theme(legend.position = "none")

Assessment of Economic Consequnces
As noted above, the economic consequence data utilizes multipliers found in variables PROPDMGEXP and CROPDMGEXP to describe the total financial loss caused by a given event. Respectively, the two multiplier variables contain the following codes:
levels(as.factor(storm_data$PROPDMGEXP))
[1] "" "-" "?" "+" "0" "1" "2" "3" "4" "5" "6" "7" "8" "B" "h" "H" "K" "m" "M"
levels(as.factor(storm_data$CROPDMGEXP))
[1] "" "?" "0" "2" "B" "k" "K" "m" "M"
To ease assessment of the financial loss data, subsets of the data are again created containing only event type and property or econimic harm data. Zero values for damage are excluded since they are not pertinent to the question posed.
prop_damage <- storm_data[,c(8,25:26)]
prop_damage <- prop_damage[prop_damage$PROPDMG > 0,]
crop_damage <- storm_data[,c(8, 27:28)]
crop_damage <- crop_damage[crop_damage$CROPDMG > 0,]
The summary function shows how many times each multiplier is used in the remaining data. (The first entry in each list is a count of the number of times no multiplier was indicated.)
summary(as.factor(prop_damage$PROPDMGEXP))
- + 0 2 3 4 5 6 7 B h H K
76 1 5 209 1 1 4 18 3 2 40 1 6 227481
m M
7 11319
summary(as.factor(crop_damage$CROPDMGEXP))
0 B k K m M
3 12 7 21 20137 1 1918
A small number of the remaining multipliers have unknown meanings (i.e. they are not discussed in the dataset documentation). These values are: -, ?, +, 0 through 8, and blank spaces. Because these entries are present in only 0.0013% of the property damage data and 0.00068% of the crop damage data, those rows are excluded as possible data entry errors.
prop_damage <- prop_damage[(prop_damage$PROPDMGEXP == "B") | (prop_damage$PROPDMGEXP == "h") |
(prop_damage$PROPDMGEXP == "H") | (prop_damage$PROPDMGEXP == "K") |
(prop_damage$PROPDMGEXP == "m") | (prop_damage$PROPDMGEXP == "M"),]
crop_damage <- crop_damage[(crop_damage$CROPDMGEXP == "B") | (crop_damage$CROPDMGEXP == "k") |
(crop_damage$CROPDMGEXP == "K") | (crop_damage$CROPDMGEXP == "m") |
(crop_damage$CROPDMGEXP == "M"),]
The multipliers are now used to adjust the property and crop damage values.
prop_damage$PROPDMGEXP[prop_damage$PROPDMGEXP == "B"] <- 1000000000
prop_damage$PROPDMGEXP[prop_damage$PROPDMGEXP == "M"] <- 1000000
prop_damage$PROPDMGEXP[prop_damage$PROPDMGEXP == "m"] <- 1000000
prop_damage$PROPDMGEXP[prop_damage$PROPDMGEXP == "K"] <- 1000
prop_damage$PROPDMGEXP[prop_damage$PROPDMGEXP == "H"] <- 100
prop_damage$PROPDMGEXP[prop_damage$PROPDMGEXP == "h"] <- 100
crop_damage$CROPDMGEXP[crop_damage$CROPDMGEXP == "B"] <- 1000000000
crop_damage$CROPDMGEXP[crop_damage$CROPDMGEXP == "M"] <- 1000000
crop_damage$CROPDMGEXP[crop_damage$CROPDMGEXP == "m"] <- 1000000
crop_damage$CROPDMGEXP[crop_damage$CROPDMGEXP == "K"] <- 1000
crop_damage$CROPDMGEXP[crop_damage$CROPDMGEXP == "K"] <- 1000
prop_damage$ADJPROPDMG <- prop_damage$PROPDMG * as.numeric(prop_damage$PROPDMGEXP)
crop_damage$ADJCROPDMG <- crop_damage$CROPDMG * as.numeric(crop_damage$CROPDMGEXP)
NAs introduced by coercion
Finally, the most damaging storm events are identified:
prop_damage <- aggregate(prop_damage$ADJPROPDMG, by = list(prop_damage$EVTYPE), FUN = "sum")
prop_damage <- prop_damage[order(-prop_damage[,2]),]
names(prop_damage) <- c("Event", "Prop_Damage")
crop_damage <- aggregate(crop_damage$ADJCROPDMG, by = list(crop_damage$EVTYPE), FUN = "sum")
crop_damage <- crop_damage[order(-crop_damage[,2]),]
names(crop_damage) <- c("Event", "Crop_Damage")
total <- merge(prop_damage, crop_damage, by="Event")
total[is.na(total)] <- 0
total$Losses <- total$Prop_Damage + total$Crop_Damage
total <- total[order(-total[,4]),]
row.names(total) = NULL
total <- total[1:10,]
total$Losses <- total$Losses/1e+09
total
The economic loss information is also summarized visually here:
ggplot(data = total, aes(x=reorder(Event, -Losses), y=Losses)) + geom_bar(stat = "identity") +
geom_text(aes(label=round(Losses,2)), color="white", vjust= 1, size=3) +
labs(title = "Economic Losses Attributable to Weather Events") +
labs(x = "Event", y = "Losses in Billions of Dollars") +
theme(axis.text.x = element_text(angle = 90, size = 8))

LS0tDQp0aXRsZTogIlN0b3JtIFNldmVyaXR5IEFuYWx5c2lzIFVzaW5nIHRoZSBOT0FBIFN0b3JtIERhdGFiYXNlIg0KYXV0aG9yOiBieSBKb3NoIENob2F0ZQ0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiMjIFN5bm9wc2lzOg0KDQpUaGlzIHJlcG9ydCB1dGlsaXplcyB0aGUgVS5TLiBOYXRpb25hbCBPY2VhbmljIGFuZCBBdG1vc3BoZXJpYyBBZG1pbmlzdHJhdGlvbidzIChOT0FBKSBzdG9ybSBkYXRhYmFzZSB0byBhbnN3ZXIgdHdvIGJhc2ljIHF1ZXN0aW9uczoNCg0KKiBXaGF0IGtpbmRzIG9mIHN0b3JtIGV2ZW50cyBoYXZlIGJlZW4gdGhlIG1vc3QgaGFybWZ1bCB0byBwb3B1bGF0aW9uIGhlYWx0aD8NCiogV2hhdCBraW5kcyBvZiBzdG9ybSBldmVudHMgaGF2ZSBoYWQgdGhlIGdyZWF0ZXN0IGVjb25vbWljIGNvbnNlcXVlbmNlcz8NCg0KVGhlIGRhdGEgY29udGFpbnMgaW5mb3JtYXRpb24gb24gYSB3aWRlIHZhcmlldHkgb2Ygc2V2ZXJlIHN0b3JtcyBvY2N1cnJpbmcgYmV0d2VlbiAxOTUwIGFuZCAyMDExLiBFdmVyeXRoaW5nIGZyb20gaGVhdnkgcmFpbiwgc2xlZXQgb3IgaGlnaCBzdXJmIHRvIHRvcm5hZG9lcyBhbmQgdm9sY2FuaW5jIGFzaCBhcmUgaW5jbHVkZWQuIA0KDQojIyBEYXRhIFByb2Nlc3Npbmc6DQoNClRoZSBkYXRhIGlzIHJlYWQgaW4gZnJvbSB0aGUgd29ya2luZyBkaXJlY3RvcnkgdXNpbmcgdGhlIHJlYWQuY3N2IGZ1bmN0aW9uLiBEYXRhIHByb2Nlc3NpbmcgYW5kIHZpc3VhbGl6YXRpb24gcGFja2FnZXMgYXJlIGFsc28gbG9hZGVkLg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0Kc3Rvcm1fZGF0YSA8LSByZWFkLmNzdigicmVwZGF0YSUyRmRhdGElMkZTdG9ybURhdGEuY3N2LmJ6MiIsIGFzLmlzID0gVFJVRSkNCmBgYA0KDQpVc2luZyB0aGUgbmFtZXMgZnVuY3Rpb24sIHRoZSBhdmFpbGFibGUgZGF0YWJhc2UgdmFyaWFibGVzIGFyZSB2aWV3ZWQ6DQpgYGB7cn0NCm5hbWVzKHN0b3JtX2RhdGEpDQpgYGANCg0KVGhlIE5PQUEgc3Rvcm0gZGF0YWJhc2UgZG9jdW1lbnRhdGlvbiBjYW4gYmUgZm91bmQgaGVyZTogKCBodHRwOi8vd3d3Lm53cy5ub2FhLmdvdi9kaXJlY3RpdmVzLykuIEFmdGVyIHJldmlld2luZyB0aGlzIGRvY3VtZW50YXRpb24sIHRoZSB2YXJpYWJsZXMgRkFUQUxJVElFUyBhbmQgSU5KVVJJRVMgYXBwZWFyIHRvIGJlIHRoZSBvbmx5IHZhcmlhYmxlcyBwZXJ0aW5lbnQgdG8gdGhlIHF1ZXN0aW9uIG9mIGhhcm0gY2F1c2VkIHRvIGluZGl2aWR1YWwgaGVhbHRoLiANCg0KVGhlIHZhcmlhYmxlcyBQUk9QRE1HLCBQUk9QRE1FR1hQLCBDUk9QRE1HIGFuZCBDUk9QRE1HRVhQIGVhY2ggcmVsYXRlIHRvIHRoZSBlY29ub21pYyBjb25zZXF1ZW5jZXMgY2F1c2VkIGJ5IHN0b3JtIGV2ZW50cy4gUFJPUERNRyBhbmQgUFJPUERNR0VYUCBnaXZlIHByb3BlcnR5IGRhbWFnZSB0b3RhbHMgd2l0aCBQUk9QRE1HRVhQIHByb3ZpZGluZyBhIG11bHRpcGxpZXIgZm9yIHRoZSBkYW1hZ2UgYW1vdW50IChjb2RlICJIIiBmb3IgaHVuZHJlZHMgb2YgZG9sbGFycywgIksiIGZvciB0aG91c2FuZHMsICJNIiBmb3IgbWlsbGlvbnMsIGV0Yy4pLiBDUk9QRE1HIGFuZCBDUk9QRE1HRVhQIGdpdmUgc2ltaWxhciBkYW1hZ2UgZXN0aW1hdGVzIGZvciBhZ3JpY3VsdHVyYWwgbG9zc2VzLg0KDQojIyMgQXNzZXNzbWVudCBvZiBoYXJtIHRvIHBvcHVsYXRpb24gaGVhbHRoDQoNCkZvciBlYXNlIG9mIHZpc3VhbGl6YXRpb24sIHN1YnNldHMgb2YgdGhlIGRhdGEgYXJlIGNyZWF0ZWQgY29udGFpbmluZyBvbmx5IGV2ZW50IHR5cGUgYW5kIGZhdGFsaXRpZXMvaW5qdXJpZXMuIFdlIHRoZW4gdGFrZSBhIGN1cnNvcnkgbG9vayBhdCB0aGUgZGF0YSB1c2luZyB0aGUgc3VtbWFyeSBmdW5jdGlvbi4NCmBgYHtyfQ0KZGVhdGggPC0gc3Rvcm1fZGF0YVssYyg4LDIzKV0NCmluanVyeSA8LSBzdG9ybV9kYXRhWyxjKDgsMjQpXQ0Kc3VtbWFyeShkZWF0aCRGQVRBTElUSUVTKQ0Kc3VtbWFyeShpbmp1cnkkSU5KVVJJRVMpDQpgYGANCg0KQm90aCB0aGUgZmF0YWxpdHkgYW5kIGluanVyeSB2YXJpYWJsZXMgY29udGFpbiBhIGxhcmdlIG51bWJlciBvZiB6ZXJvIHZhbHVlcy4gVGhvc2UgYXJlIHJlbW92ZWQgaGVyZSwgYW5kIHRoZSByZXN1bHRpbmcgZml2ZSBtb3N0IGZhdGFsL2luanVyaW91cyBldmVudCB0eXBlcyBhcmUgcmV0YWluZWQgZm9yIHBsb3R0aW5nLg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQpkZWF0aCA8LSBkZWF0aFtkZWF0aCRGQVRBTElUSUVTID4gMCxdDQppbmp1cnkgPC0gaW5qdXJ5W2luanVyeSRJTkpVUklFUyA+IDAsXQ0KDQp0b3RhbF9kZWF0aHMgPC0gYWdncmVnYXRlKGRlYXRoJEZBVEFMSVRJRVMsIGJ5ID0gbGlzdChkZWF0aCRFVlRZUEUpLCBGVU4gPSAic3VtIikNCnRvdGFsX2RlYXRocyA8LSB0b3RhbF9kZWF0aHNbb3JkZXIoLXRvdGFsX2RlYXRoc1ssMl0pLF0NCnRvdGFsX2RlYXRocyA8LSB0b3RhbF9kZWF0aHNbMTo1LF0NCm5hbWVzKHRvdGFsX2RlYXRocykgPC0gYygiRXZlbnQiLCAiVG90YWxfRGVhdGhzIikNCnJvd25hbWVzKHRvdGFsX2RlYXRocykgPC0gTlVMTA0KDQp0b3RhbF9pbmp1cmllcyA8LSBhZ2dyZWdhdGUoaW5qdXJ5JElOSlVSSUVTLCBieSA9IGxpc3QoaW5qdXJ5JEVWVFlQRSksIEZVTiA9ICJzdW0iKQ0KdG90YWxfaW5qdXJpZXMgPC0gdG90YWxfaW5qdXJpZXNbb3JkZXIoLXRvdGFsX2luanVyaWVzWywyXSksXQ0KdG90YWxfaW5qdXJpZXMgPC0gdG90YWxfaW5qdXJpZXNbMTo1LF0NCm5hbWVzKHRvdGFsX2luanVyaWVzKSA8LSBjKCJFdmVudCIsICJUb3RhbF9Jbmp1cmllcyIpDQpyb3duYW1lcyh0b3RhbF9pbmp1cmllcykgPC0gTlVMTA0KYGBgDQoNCmdncGxvdDIgaXMgdXNlZCB0byBwbG90IHRoZSBkYXRhOg0KYGBge3J9DQpnZ3Bsb3QodG90YWxfZGVhdGhzLCBhZXMoeD1yZW9yZGVyKEV2ZW50LCAtVG90YWxfRGVhdGhzKSwgeT1Ub3RhbF9EZWF0aHMsIGZpbGw9RXZlbnQpKSArDQogIGxhYnModGl0bGUgPSAiVGhlIEZpdmUgRGVhZGxpZXN0IFdlYXRoZXIgRXZlbnQgVHlwZXMiLCB4ID0gIldlYXRoZXIgRXZlbnQiLCB5ID0gIlRvdGFsIERlYXRocyIpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArIHlsaW0oMCwgNjUwMCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpIA0KDQpnZ3Bsb3QodG90YWxfaW5qdXJpZXMsIGFlcyh4PXJlb3JkZXIoRXZlbnQsIC1Ub3RhbF9Jbmp1cmllcyksIHk9VG90YWxfSW5qdXJpZXMsIGZpbGw9RXZlbnQpKSArDQogIGxhYnModGl0bGUgPSAiV2VhdGhlciBFdmVudCBUeXBlcyBUaGF0IENhdXNlIHRoZSBNb3N0IEluanVyaWVzIikgKw0KICBsYWJzKHggPSAiV2VhdGhlciBFdmVudCIsIHkgPSAiVG90YWwgSW5qdXJpZXMiKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKyB5bGltKDAsIDEwMTAwMCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQpgYGANCg0KIyMjIEFzc2Vzc21lbnQgb2YgRWNvbm9taWMgQ29uc2VxdW5jZXMNCg0KQXMgbm90ZWQgYWJvdmUsIHRoZSBlY29ub21pYyBjb25zZXF1ZW5jZSBkYXRhIHV0aWxpemVzIG11bHRpcGxpZXJzIGZvdW5kIGluIHZhcmlhYmxlcyBQUk9QRE1HRVhQIGFuZCBDUk9QRE1HRVhQIHRvIGRlc2NyaWJlIHRoZSB0b3RhbCBmaW5hbmNpYWwgbG9zcyBjYXVzZWQgYnkgYSBnaXZlbiBldmVudC4gUmVzcGVjdGl2ZWx5LCB0aGUgdHdvIG11bHRpcGxpZXIgdmFyaWFibGVzIGNvbnRhaW4gdGhlIGZvbGxvd2luZyBjb2RlczoNCmBgYHtyfQ0KbGV2ZWxzKGFzLmZhY3RvcihzdG9ybV9kYXRhJFBST1BETUdFWFApKQ0KbGV2ZWxzKGFzLmZhY3RvcihzdG9ybV9kYXRhJENST1BETUdFWFApKQ0KYGBgDQoNClRvIGVhc2UgYXNzZXNzbWVudCBvZiB0aGUgZmluYW5jaWFsIGxvc3MgZGF0YSwgc3Vic2V0cyBvZiB0aGUgZGF0YSBhcmUgYWdhaW4gY3JlYXRlZCBjb250YWluaW5nIG9ubHkgZXZlbnQgdHlwZSBhbmQgcHJvcGVydHkgb3IgZWNvbmltaWMgaGFybSBkYXRhLiBaZXJvIHZhbHVlcyBmb3IgZGFtYWdlIGFyZSBleGNsdWRlZCBzaW5jZSB0aGV5IGFyZSBub3QgcGVydGluZW50IHRvIHRoZSBxdWVzdGlvbiBwb3NlZC4NCmBgYHtyfQ0KcHJvcF9kYW1hZ2UgPC0gc3Rvcm1fZGF0YVssYyg4LDI1OjI2KV0NCnByb3BfZGFtYWdlIDwtIHByb3BfZGFtYWdlW3Byb3BfZGFtYWdlJFBST1BETUcgPiAwLF0NCg0KY3JvcF9kYW1hZ2UgPC0gc3Rvcm1fZGF0YVssYyg4LCAyNzoyOCldDQpjcm9wX2RhbWFnZSA8LSBjcm9wX2RhbWFnZVtjcm9wX2RhbWFnZSRDUk9QRE1HID4gMCxdDQpgYGANCg0KVGhlIHN1bW1hcnkgZnVuY3Rpb24gc2hvd3MgaG93IG1hbnkgdGltZXMgZWFjaCBtdWx0aXBsaWVyIGlzIHVzZWQgaW4gdGhlIHJlbWFpbmluZyBkYXRhLiAoVGhlIGZpcnN0IGVudHJ5IGluIGVhY2ggbGlzdCBpcyBhIGNvdW50IG9mIHRoZSBudW1iZXIgb2YgdGltZXMgbm8gbXVsdGlwbGllciB3YXMgaW5kaWNhdGVkLikNCmBgYHtyfQ0Kc3VtbWFyeShhcy5mYWN0b3IocHJvcF9kYW1hZ2UkUFJPUERNR0VYUCkpDQpzdW1tYXJ5KGFzLmZhY3Rvcihjcm9wX2RhbWFnZSRDUk9QRE1HRVhQKSkNCmBgYA0KDQpBIHNtYWxsIG51bWJlciBvZiB0aGUgcmVtYWluaW5nIG11bHRpcGxpZXJzIGhhdmUgdW5rbm93biBtZWFuaW5ncyAoaS5lLiB0aGV5IGFyZSBub3QgZGlzY3Vzc2VkIGluIHRoZSBkYXRhc2V0IGRvY3VtZW50YXRpb24pLiBUaGVzZSB2YWx1ZXMgYXJlOiAtLCA/LCArLCAwIHRocm91Z2ggOCwgYW5kIGJsYW5rIHNwYWNlcy4gQmVjYXVzZSB0aGVzZSBlbnRyaWVzIGFyZSBwcmVzZW50IGluIG9ubHkgMC4wMDEzJSBvZiB0aGUgcHJvcGVydHkgZGFtYWdlIGRhdGEgYW5kIDAuMDAwNjglIG9mIHRoZSBjcm9wIGRhbWFnZSBkYXRhLCB0aG9zZSByb3dzIGFyZSBleGNsdWRlZCBhcyBwb3NzaWJsZSBkYXRhIGVudHJ5IGVycm9ycy4NCmBgYHtyfQ0KcHJvcF9kYW1hZ2UgPC0gcHJvcF9kYW1hZ2VbKHByb3BfZGFtYWdlJFBST1BETUdFWFAgPT0gIkIiKSB8IChwcm9wX2RhbWFnZSRQUk9QRE1HRVhQID09ICJoIikgfA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgKHByb3BfZGFtYWdlJFBST1BETUdFWFAgPT0gIkgiKSB8IChwcm9wX2RhbWFnZSRQUk9QRE1HRVhQID09ICJLIikgfA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgKHByb3BfZGFtYWdlJFBST1BETUdFWFAgPT0gIm0iKSB8IChwcm9wX2RhbWFnZSRQUk9QRE1HRVhQID09ICJNIiksXQ0KDQpjcm9wX2RhbWFnZSA8LSBjcm9wX2RhbWFnZVsoY3JvcF9kYW1hZ2UkQ1JPUERNR0VYUCA9PSAiQiIpIHwgKGNyb3BfZGFtYWdlJENST1BETUdFWFAgPT0gImsiKSB8DQogICAgICAgICAgICAgICAgICAgICAgICAgICAoY3JvcF9kYW1hZ2UkQ1JPUERNR0VYUCA9PSAiSyIpIHwgKGNyb3BfZGFtYWdlJENST1BETUdFWFAgPT0gIm0iKSB8DQogICAgICAgICAgICAgICAgICAgICAgICAgICAoY3JvcF9kYW1hZ2UkQ1JPUERNR0VYUCA9PSAiTSIpLF0NCmBgYA0KDQpUaGUgbXVsdGlwbGllcnMgYXJlIG5vdyB1c2VkIHRvIGFkanVzdCB0aGUgcHJvcGVydHkgYW5kIGNyb3AgZGFtYWdlIHZhbHVlcy4NCmBgYHtyfQ0KcHJvcF9kYW1hZ2UkUFJPUERNR0VYUFtwcm9wX2RhbWFnZSRQUk9QRE1HRVhQID09ICJCIl0gPC0gMTAwMDAwMDAwMA0KcHJvcF9kYW1hZ2UkUFJPUERNR0VYUFtwcm9wX2RhbWFnZSRQUk9QRE1HRVhQID09ICJNIl0gPC0gMTAwMDAwMA0KcHJvcF9kYW1hZ2UkUFJPUERNR0VYUFtwcm9wX2RhbWFnZSRQUk9QRE1HRVhQID09ICJtIl0gPC0gMTAwMDAwMA0KcHJvcF9kYW1hZ2UkUFJPUERNR0VYUFtwcm9wX2RhbWFnZSRQUk9QRE1HRVhQID09ICJLIl0gPC0gMTAwMA0KcHJvcF9kYW1hZ2UkUFJPUERNR0VYUFtwcm9wX2RhbWFnZSRQUk9QRE1HRVhQID09ICJIIl0gPC0gMTAwDQpwcm9wX2RhbWFnZSRQUk9QRE1HRVhQW3Byb3BfZGFtYWdlJFBST1BETUdFWFAgPT0gImgiXSA8LSAxMDANCg0KY3JvcF9kYW1hZ2UkQ1JPUERNR0VYUFtjcm9wX2RhbWFnZSRDUk9QRE1HRVhQID09ICJCIl0gPC0gMTAwMDAwMDAwMA0KY3JvcF9kYW1hZ2UkQ1JPUERNR0VYUFtjcm9wX2RhbWFnZSRDUk9QRE1HRVhQID09ICJNIl0gPC0gMTAwMDAwMA0KY3JvcF9kYW1hZ2UkQ1JPUERNR0VYUFtjcm9wX2RhbWFnZSRDUk9QRE1HRVhQID09ICJtIl0gPC0gMTAwMDAwMA0KY3JvcF9kYW1hZ2UkQ1JPUERNR0VYUFtjcm9wX2RhbWFnZSRDUk9QRE1HRVhQID09ICJLIl0gPC0gMTAwMA0KY3JvcF9kYW1hZ2UkQ1JPUERNR0VYUFtjcm9wX2RhbWFnZSRDUk9QRE1HRVhQID09ICJLIl0gPC0gMTAwMA0KDQpwcm9wX2RhbWFnZSRBREpQUk9QRE1HIDwtIHByb3BfZGFtYWdlJFBST1BETUcgKiBhcy5udW1lcmljKHByb3BfZGFtYWdlJFBST1BETUdFWFApDQpjcm9wX2RhbWFnZSRBREpDUk9QRE1HIDwtIGNyb3BfZGFtYWdlJENST1BETUcgKiBhcy5udW1lcmljKGNyb3BfZGFtYWdlJENST1BETUdFWFApDQpgYGANCg0KRmluYWxseSwgdGhlIG1vc3QgZGFtYWdpbmcgc3Rvcm0gZXZlbnRzIGFyZSBpZGVudGlmaWVkOg0KYGBge3J9DQpwcm9wX2RhbWFnZSA8LSBhZ2dyZWdhdGUocHJvcF9kYW1hZ2UkQURKUFJPUERNRywgYnkgPSBsaXN0KHByb3BfZGFtYWdlJEVWVFlQRSksIEZVTiA9ICJzdW0iKQ0KcHJvcF9kYW1hZ2UgPC0gcHJvcF9kYW1hZ2Vbb3JkZXIoLXByb3BfZGFtYWdlWywyXSksXQ0KbmFtZXMocHJvcF9kYW1hZ2UpIDwtIGMoIkV2ZW50IiwgIlByb3BfRGFtYWdlIikNCg0KY3JvcF9kYW1hZ2UgPC0gYWdncmVnYXRlKGNyb3BfZGFtYWdlJEFESkNST1BETUcsIGJ5ID0gbGlzdChjcm9wX2RhbWFnZSRFVlRZUEUpLCBGVU4gPSAic3VtIikNCmNyb3BfZGFtYWdlIDwtIGNyb3BfZGFtYWdlW29yZGVyKC1jcm9wX2RhbWFnZVssMl0pLF0NCm5hbWVzKGNyb3BfZGFtYWdlKSA8LSBjKCJFdmVudCIsICJDcm9wX0RhbWFnZSIpDQoNCnRvdGFsIDwtIG1lcmdlKHByb3BfZGFtYWdlLCBjcm9wX2RhbWFnZSwgYnk9IkV2ZW50IikNCnRvdGFsW2lzLm5hKHRvdGFsKV0gPC0gMA0KdG90YWwkTG9zc2VzIDwtIHRvdGFsJFByb3BfRGFtYWdlICsgdG90YWwkQ3JvcF9EYW1hZ2UNCnRvdGFsIDwtIHRvdGFsW29yZGVyKC10b3RhbFssNF0pLF0NCnJvdy5uYW1lcyh0b3RhbCkgPSBOVUxMDQp0b3RhbCA8LSB0b3RhbFsxOjEwLF0NCnRvdGFsJExvc3NlcyA8LSB0b3RhbCRMb3NzZXMvMWUrMDkNCnRvdGFsDQpgYGANCg0KVGhlIGVjb25vbWljIGxvc3MgaW5mb3JtYXRpb24gaXMgYWxzbyBzdW1tYXJpemVkIHZpc3VhbGx5IGhlcmU6DQpgYGB7cn0NCmdncGxvdChkYXRhID0gdG90YWwsIGFlcyh4PXJlb3JkZXIoRXZlbnQsIC1Mb3NzZXMpLCB5PUxvc3NlcykpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChMb3NzZXMsMikpLCBjb2xvcj0id2hpdGUiLCB2anVzdD0gMSwgc2l6ZT0zKSArDQogIGxhYnModGl0bGUgPSAiRWNvbm9taWMgTG9zc2VzIEF0dHJpYnV0YWJsZSB0byBXZWF0aGVyIEV2ZW50cyIpICsNCiAgbGFicyh4ID0gIkV2ZW50IiwgeSA9ICJMb3NzZXMgaW4gQmlsbGlvbnMgb2YgRG9sbGFycyIpICsgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHNpemUgPSA4KSkNCmBgYA0KDQojIyBSZXN1bHRzOg0KDQpDbGVhcmx5LCB0b3JuYWRvZXMgcG9zZSB0aGUgZ3JlYXRlc3QgcmlzayBvZiBpbmp1cnkgb3IgZGVhdGggb2YgYW55IHdlYXRoZXIgZXZlbnQgaW4gdGhlIFVuaXRlZCBTdGF0ZXMuIFRvcm5hZG9lcyBoYXZlIGNhdXNlZCBuZWFybHkgdGhyZWUgdGltZXMgYXMgbWFueSBkZWF0aHMgYW5kIHRlbnMgb2YgdGhvdXNhbmRzIG1vcmUgaW5qdXJpZXMuIE9uIHRoZSBvdGhlciBoYW5kLCB3aGlsZSB0b3JuYWRvZXMgaGF2ZSBoYWQgYSBzaWduaWZpY2FudCBlY29ub21pYyBpbXBhY3Qgb3ZlciB0aGUgeWVhcnMsIHRoZXkgZG8gbm90IGNhdXNlIHRoZSBtb3N0IGZpbmFuY2lhbCBkYW1hZ2UuIFJhdGhlciwgZmxvb2RpbmcgaGFzIGJlZW4gdGhlIG1vc3QgZWNvbm9taWNhbGx5IHNpZ25pZmljYW50IHdlYXRoZXIgZXZlbnQgaW4gdGhlIFUuUy4gYnkgYSBsYXJnZSBtYXJnaW4uDQoNCg==