In this set of problems, we will first go through some of the data that are collected by the World Bank. We will do some cleaning on the data before we start analyzing it. Then, we will try to do a simple web scraping exercise where we will analyze the data as well.
The dataset presented in this problem set is a truncated version of one you can find on the World Bank Gender Statistics website.
For the purpose of data cleansing and manipulation, we will use the tidyverse package. Once we upload the data we are going to see that there are multiple indicators of gender, countries and years in the data. In this case we are just interested in analyzing the data for one indicator that is the Adolescent Fertility Rate, in the data the indicator code for this variable is called SP.ADO.TFRT. This indicator measures the annual number of births to women 15 to 19 years of age per 1,000 women in that age group. It represents the risk of childbearing among adolescent women 15 to 19 years of age. It is also referred to as the age-specific fertility rate for women aged 15-19. Once we have completed this problem set we will have more information of how this rate has evolved over time and how it varies across different groups of countries.
# Preliminaries
rm(list=ls())
library("utils")
library("tidyverse")
# Set working directory
setwd("C:/Users/Tarek/Documents/MITx 14.310x - Data Analysis for Social Scientists")
# Read the data
gender_data <- as_tibble(read.csv("DataSets/Week3/Gender_StatsData.csv"))
# The first few observations
head(gender_data, 20)
NA
Teenage Fertility Rate
teenage_fr <- gender_data %>% filter(Indicator.Code == "SP.ADO.TFRT")
factor(teenage_fr$Country.Code)
[1] ARB CSS CEB EAR EAS EAP TEA EMU ECS ECA TEC EUU FCS HPC HIC IBD IBT IDB IDX IDA LTE
[22] LCN LAC TLA LDC LMY LIC LMC MEA MNA TMN MIC NAC OED OSS PSS PST PRE SST SAS TSA SSF
[43] SSA TSS UMC WLD AFG ALB DZA ASM AND AGO ATG ARG ARM ABW AUS AUT AZE BHS BHR BGD BRB
[64] BLR BEL BLZ BEN BMU BTN BOL BIH BWA BRA VGB BRN BGR BFA BDI CPV KHM CMR CAN CYM CAF
[85] TCD CHI CHL CHN COL COM COD COG CRI CIV HRV CUB CUW CYP CZE DNK DJI DMA DOM ECU EGY
[106] SLV GNQ ERI EST SWZ ETH FRO FJI FIN FRA PYF GAB GMB GEO DEU GHA GIB GRC GRL GRD GUM
[127] GTM GIN GNB GUY HTI HND HKG HUN ISL IND IDN IRN IRQ IRL IMN ISR ITA JAM JPN JOR KAZ
[148] KEN KIR PRK KOR XKX KWT KGZ LAO LVA LBN LSO LBR LBY LIE LTU LUX MAC MKD MDG MWI MYS
[169] MDV MLI MLT MHL MRT MUS MEX FSM MDA MCO MNG MNE MAR MOZ MMR NAM NRU NPL NLD NCL NZL
[190] NIC NER NGA MNP NOR OMN PAK PLW PAN PNG PRY PER PHL POL PRT PRI QAT ROU RUS RWA WSM
[211] SMR STP SAU SEN SRB SYC SLE SGP SXM SVK SVN SLB SOM ZAF SSD ESP LKA KNA LCA MAF VCT
[232] SDN SUR SWE CHE SYR TJK TZA THA TLS TGO TON TTO TUN TUR TKM TCA TUV UGA UKR ARE GBR
[253] USA URY UZB VUT VEN VNM VIR PSE YEM ZMB ZWE
263 Levels: ABW AFG AGO ALB AND ARB ARE ARG ARM ASM ATG AUS AUT AZE BDI BEL BEN ... ZWE
Summary Statistics
round(mean(teenage_fr$X2000, na.rm = TRUE), 2)
[1] 63.15
round(sd(teenage_fr$X2000, na.rm = TRUE), 2)
[1] 46.92
Now, we are interested in plotting the evolution of the Adolescent Fertility Rate from 1960 to 2015. In addition, we are interested in having different information in the same plot. First, we want to plot the sample mean of all the data set, but also we want to add more information such as the rate for low, middle and high income countries (an indicator for country code is stored in the variable “Country.Code”).
Inspect this variable to get a sense of what it contains. Note that it includes indicators for both countries, regions, and income group. Since we are only interested in the trends by income group, we want to filter the data to contain only the fertility rate for high, middle, and low income countries as well as the world average.
Trends By Income Group
byincomelevel <- filter(teenage_fr, Country.Code %in% c("LIC", "HIC", "MIC", "WLD"))
byincomelevel
Notice, there are still two problems with the resulting data:
It contains additional variables that we don’t need or are meaningless at this level of aggregation.
It is not organized in a very intuitive way. A more natural way to organize this data, and prepare it for plotting, is to have each observation represent either a year or a country group-year, and each of the columns represent either the fertility rate for a given group, or if the data is at the country-group year level, then just the fertility rate.
Data by Group Year Using gather()
plotdata_bygroupyear <- gather(byincomelevel, "Year", "FertilityRate", X1960:X2015) %>% select(Year, Country.Name, Country.Code, FertilityRate)
# plotdata_bygroupyear <- mutate(plotdata_bygroupyear, Year=as.numeric(str_sub(Year,-4)))
plotdata_bygroupyear <- mutate(plotdata_bygroupyear, Year=as.numeric(str_replace(Year, "X", "")))
head(plotdata_bygroupyear)
Suppose you take a look at the data and change your mind. You decided you prefer to look at the data at the year level and have the fertility rates for each income-group as separate variables.
Data by Group Year Using spread()
plotdata_byyear<-select(plotdata_bygroupyear, Country.Code, Year, FertilityRate) %>% spread(Country.Code, FertilityRate)
plotdata_byyear
Let’s plot the fertility rate over time, separately for each income level.
p <- ggplot(plotdata_bygroupyear, aes(x = Year, y = FertilityRate, group = Country.Code, col = Country.Code))
p + geom_line() +
labs(x = "Year", y = "Fertility Rate", title = 'Fertility Rate by Country-Income-Level over Time') +
scale_x_continuous(minor_breaks = seq(1960, 2015, 5), breaks = seq(1960, 2015, 10)) +
theme(plot.title = element_text(hjust = 0.5))

Now, we are not going to consider the trends of the different categories over the years. Instead, we are going to compare how the distribution of the Adolescent Fertility Rate is different between 1960 and 2000.
#Generating histdata_twoyears
histdata_twoyears <- select(teenage_fr, Country.Name, Country.Code, Indicator.Name, Indicator.Code, X1960,X2000)
histdata_twoyears <- gather(teenage_fr, Year, FertilityRate, X1960, X2000) %>%
select(Year, Country.Name, Country.Code, FertilityRate)
histdata_twoyears <- filter(histdata_twoyears,!is.na(FertilityRate))
ggplot(histdata_twoyears, aes(x=FertilityRate)) +
geom_histogram(data = subset(histdata_twoyears, Year=="X1960"), bins = 20, color="darkred", fill="red", alpha=0.2) +
geom_histogram(data=subset(histdata_twoyears, Year=="X2000"), bins = 20, color="darkblue", fill="blue", alpha=0.2) +
labs(title = "Fertility Rates' Distribution in 1960 and 2000", x = "Fertility Rate", y = "Number of Adolescents")

Kernels
ggplot(histdata_twoyears, aes(x=FertilityRate, group=Year, color=Year, alpha=0.2)) + geom_histogram(aes(y=..density..)) + geom_density(data=subset(histdata_twoyears, Year=="X1960"), color="darkred", fill="red", alpha=0.2, bw=5, kernel = "optcosine") + geom_density(data=subset(histdata_twoyears, Year=="X2000"), color="darkblue", fill="blue", alpha=0.2, bw=5, kernel = "optcosine")

Cummulative Distribution Function
ggplot(histdata_twoyears, aes(x = FertilityRate)) +
stat_ecdf(aes(color = Year,linetype = Year),
geom = "step", size = 1.5) +
scale_color_manual(values = c("#00AFBB", "#E7B800"))+
labs(x ="Fertility Rate", y = "Cummulative Distribution Function", title = "Empirical Cummulative Distribution Function in 1960 and 2000") +
theme(plot.title = element_text(hjust = 0.5))

CDF Plots
The CDFs below are calculated by integrating calculated marginal pdfs. You can find the derivatives of the below CDFs to find the corresponding pdf for each random variable. CDF is defined as the probability of X less than or equal to x. From this definition, and if the random variables are continuous, then one may find the derivative of the pdf.
x <- seq(0,1,0.001)
y <- seq(0,1,0.001)
cdfx <- 6/5 * (x^2/2 + x/3)
cdfy <- 6/5 * (x/2 + x^3/3)
plot(x, cdfx, type = "l", col="blue", xlab=" ", ylab = "Cumulative Probability", xlim=c(0,1), main="CDF plot")
lines(y, cdfy, lty=2, col="red", lwd=2)
legend("bottomright", ncol=1, legend = c("X", "Y"), lty=c(1,2), col=c("blue", "red"))

Resources
LS0tDQp0aXRsZTogIlRlZW5hZ2UgRmVydGlsaXR5IFJhdGUiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpJbiB0aGlzIHNldCBvZiBwcm9ibGVtcywgd2Ugd2lsbCBmaXJzdCBnbyB0aHJvdWdoIHNvbWUgb2YgdGhlIGRhdGEgdGhhdCBhcmUgY29sbGVjdGVkIGJ5IHRoZSBXb3JsZCBCYW5rLiBXZSB3aWxsIGRvIHNvbWUgY2xlYW5pbmcgb24gdGhlIGRhdGEgYmVmb3JlIHdlIHN0YXJ0IGFuYWx5emluZyBpdC4gVGhlbiwgd2Ugd2lsbCB0cnkgdG8gZG8gYSBzaW1wbGUgd2ViIHNjcmFwaW5nIGV4ZXJjaXNlIHdoZXJlIHdlIHdpbGwgYW5hbHl6ZSB0aGUgZGF0YSBhcyB3ZWxsLg0KDQoNClRoZSBkYXRhc2V0IHByZXNlbnRlZCBpbiB0aGlzIHByb2JsZW0gc2V0IGlzIGEgdHJ1bmNhdGVkIHZlcnNpb24gb2Ygb25lIHlvdSBjYW4gZmluZCBvbiB0aGUgV29ybGQgQmFuayBHZW5kZXIgU3RhdGlzdGljcyB3ZWJzaXRlLg0KDQpGb3IgdGhlIHB1cnBvc2Ugb2YgZGF0YSBjbGVhbnNpbmcgYW5kIG1hbmlwdWxhdGlvbiwgd2Ugd2lsbCB1c2UgdGhlIHRpZHl2ZXJzZSBwYWNrYWdlLiBPbmNlIHdlIHVwbG9hZCB0aGUgZGF0YSB3ZSBhcmUgZ29pbmcgdG8gc2VlIHRoYXQgdGhlcmUgYXJlIG11bHRpcGxlIGluZGljYXRvcnMgb2YgZ2VuZGVyLCBjb3VudHJpZXMgYW5kIHllYXJzIGluIHRoZSBkYXRhLiBJbiB0aGlzIGNhc2Ugd2UgYXJlIGp1c3QgaW50ZXJlc3RlZCBpbiBhbmFseXppbmcgdGhlIGRhdGEgZm9yIG9uZSBpbmRpY2F0b3IgdGhhdCBpcyB0aGUgQWRvbGVzY2VudCBGZXJ0aWxpdHkgUmF0ZSwgaW4gdGhlIGRhdGEgdGhlIGluZGljYXRvciBjb2RlIGZvciB0aGlzIHZhcmlhYmxlIGlzIGNhbGxlZCBTUC5BRE8uVEZSVC4gVGhpcyBpbmRpY2F0b3IgbWVhc3VyZXMgdGhlIGFubnVhbCBudW1iZXIgb2YgYmlydGhzIHRvIHdvbWVuIDE1IHRvIDE5IHllYXJzIG9mIGFnZSBwZXIgMSwwMDAgd29tZW4gaW4gdGhhdCBhZ2UgZ3JvdXAuIEl0IHJlcHJlc2VudHMgdGhlIHJpc2sgb2YgY2hpbGRiZWFyaW5nIGFtb25nIGFkb2xlc2NlbnQgd29tZW4gMTUgdG8gMTkgeWVhcnMgb2YgYWdlLiBJdCBpcyBhbHNvIHJlZmVycmVkIHRvIGFzIHRoZSBhZ2Utc3BlY2lmaWMgZmVydGlsaXR5IHJhdGUgZm9yIHdvbWVuIGFnZWQgMTUtMTkuIE9uY2Ugd2UgaGF2ZSBjb21wbGV0ZWQgdGhpcyBwcm9ibGVtIHNldCB3ZSB3aWxsIGhhdmUgbW9yZSBpbmZvcm1hdGlvbiBvZiBob3cgdGhpcyByYXRlIGhhcyBldm9sdmVkIG92ZXIgdGltZSBhbmQgaG93IGl0IHZhcmllcyBhY3Jvc3MgZGlmZmVyZW50IGdyb3VwcyBvZiBjb3VudHJpZXMuDQoNCmBgYHtyfQ0KIyBQcmVsaW1pbmFyaWVzDQpybShsaXN0PWxzKCkpDQpsaWJyYXJ5KCJ1dGlscyIpDQpsaWJyYXJ5KCJ0aWR5dmVyc2UiKQ0KDQojIFNldCB3b3JraW5nIGRpcmVjdG9yeQ0Kc2V0d2QoIkM6L1VzZXJzL1RhcmVrL0RvY3VtZW50cy9NSVR4IDE0LjMxMHggLSBEYXRhIEFuYWx5c2lzIGZvciBTb2NpYWwgU2NpZW50aXN0cyIpDQoNCiMgUmVhZCB0aGUgZGF0YQ0KZ2VuZGVyX2RhdGEgPC0gYXNfdGliYmxlKHJlYWQuY3N2KCJEYXRhU2V0cy9XZWVrMy9HZW5kZXJfU3RhdHNEYXRhLmNzdiIpKQ0KDQojIFRoZSBmaXJzdCBmZXcgb2JzZXJ2YXRpb25zDQpoZWFkKGdlbmRlcl9kYXRhLCAyMCkNCg0KYGBgDQojIyMgVGVlbmFnZSBGZXJ0aWxpdHkgUmF0ZQ0KYGBge3J9DQp0ZWVuYWdlX2ZyIDwtIGdlbmRlcl9kYXRhICU+JSBmaWx0ZXIoSW5kaWNhdG9yLkNvZGUgPT0gIlNQLkFETy5URlJUIikNCmZhY3Rvcih0ZWVuYWdlX2ZyJENvdW50cnkuQ29kZSkNCmBgYA0KIyMjIFN1bW1hcnkgU3RhdGlzdGljcw0KYGBge3J9DQpyb3VuZChtZWFuKHRlZW5hZ2VfZnIkWDIwMDAsIG5hLnJtID0gVFJVRSksIDIpDQpyb3VuZChzZCh0ZWVuYWdlX2ZyJFgyMDAwLCBuYS5ybSA9IFRSVUUpLCAyKQ0KYGBgDQpOb3csIHdlIGFyZSBpbnRlcmVzdGVkIGluIHBsb3R0aW5nIHRoZSBldm9sdXRpb24gb2YgdGhlIEFkb2xlc2NlbnQgRmVydGlsaXR5IFJhdGUgZnJvbSAxOTYwIHRvIDIwMTUuIEluIGFkZGl0aW9uLCB3ZSBhcmUgaW50ZXJlc3RlZCBpbiBoYXZpbmcgZGlmZmVyZW50IGluZm9ybWF0aW9uIGluIHRoZSBzYW1lIHBsb3QuIEZpcnN0LCB3ZSB3YW50IHRvIHBsb3QgdGhlIHNhbXBsZSBtZWFuIG9mIGFsbCB0aGUgZGF0YSBzZXQsIGJ1dCBhbHNvIHdlIHdhbnQgdG8gYWRkIG1vcmUgaW5mb3JtYXRpb24gc3VjaCBhcyB0aGUgcmF0ZSBmb3IgbG93LCBtaWRkbGUgYW5kIGhpZ2ggaW5jb21lIGNvdW50cmllcyAoYW4gaW5kaWNhdG9yIGZvciBjb3VudHJ5IGNvZGUgaXMgc3RvcmVkIGluIHRoZSB2YXJpYWJsZSAiQ291bnRyeS5Db2RlIikuDQoNCkluc3BlY3QgdGhpcyB2YXJpYWJsZSB0byBnZXQgYSBzZW5zZSBvZiB3aGF0IGl0IGNvbnRhaW5zLiBOb3RlIHRoYXQgaXQgaW5jbHVkZXMgaW5kaWNhdG9ycyBmb3IgYm90aCBjb3VudHJpZXMsIHJlZ2lvbnMsIGFuZCBpbmNvbWUgZ3JvdXAuICBTaW5jZSB3ZSBhcmUgb25seSBpbnRlcmVzdGVkIGluIHRoZSB0cmVuZHMgYnkgaW5jb21lIGdyb3VwLCB3ZSB3YW50IHRvIGZpbHRlciB0aGUgZGF0YSB0byBjb250YWluIG9ubHkgdGhlIGZlcnRpbGl0eSByYXRlIGZvciBoaWdoLCBtaWRkbGUsIGFuZCBsb3cgaW5jb21lIGNvdW50cmllcyBhcyB3ZWxsIGFzIHRoZSB3b3JsZCBhdmVyYWdlLg0KDQojIyMgVHJlbmRzIEJ5IEluY29tZSBHcm91cA0KYGBge3J9DQpieWluY29tZWxldmVsIDwtIGZpbHRlcih0ZWVuYWdlX2ZyLCBDb3VudHJ5LkNvZGUgJWluJSBjKCJMSUMiLCAiSElDIiwgIk1JQyIsICJXTEQiKSkNCmJ5aW5jb21lbGV2ZWwNCmBgYA0KTm90aWNlLCB0aGVyZSBhcmUgc3RpbGwgdHdvIHByb2JsZW1zIHdpdGggdGhlIHJlc3VsdGluZyBkYXRhOg0KDQoxLiAgICAgSXQgY29udGFpbnMgYWRkaXRpb25hbCB2YXJpYWJsZXMgdGhhdCB3ZSBkb27igJl0IG5lZWQgb3IgYXJlIG1lYW5pbmdsZXNzIGF0IHRoaXMgbGV2ZWwgb2YgYWdncmVnYXRpb24uDQoNCjIuICAgICBJdCBpcyBub3Qgb3JnYW5pemVkIGluIGEgdmVyeSBpbnR1aXRpdmUgd2F5LiAgQSBtb3JlIG5hdHVyYWwgd2F5IHRvIG9yZ2FuaXplIHRoaXMgZGF0YSwgYW5kIHByZXBhcmUgaXQgZm9yIHBsb3R0aW5nLCBpcyB0byBoYXZlIGVhY2ggb2JzZXJ2YXRpb24gcmVwcmVzZW50IGVpdGhlciBhIHllYXIgb3IgYSBjb3VudHJ5IGdyb3VwLXllYXIsIGFuZCBlYWNoIG9mIHRoZSBjb2x1bW5zIHJlcHJlc2VudCBlaXRoZXIgdGhlIGZlcnRpbGl0eSByYXRlIGZvciBhIGdpdmVuIGdyb3VwLCBvciBpZiB0aGUgZGF0YSBpcyBhdCB0aGUgY291bnRyeS1ncm91cCB5ZWFyIGxldmVsLCB0aGVuIGp1c3QgdGhlIGZlcnRpbGl0eSByYXRlLg0KDQoNCiMjIyBEYXRhIGJ5IEdyb3VwIFllYXIgVXNpbmcgYGdhdGhlcigpYA0KYGBge3J9DQpwbG90ZGF0YV9ieWdyb3VweWVhciA8LSBnYXRoZXIoYnlpbmNvbWVsZXZlbCwgIlllYXIiLCAiRmVydGlsaXR5UmF0ZSIsIFgxOTYwOlgyMDE1KSAlPiUgc2VsZWN0KFllYXIsIENvdW50cnkuTmFtZSwgQ291bnRyeS5Db2RlLCBGZXJ0aWxpdHlSYXRlKSAgDQojIFJlbW92ZSBYIGZyb20gdGhlIHllYXJzIA0KIyBwbG90ZGF0YV9ieWdyb3VweWVhciA8LSBtdXRhdGUocGxvdGRhdGFfYnlncm91cHllYXIsIFllYXI9YXMubnVtZXJpYyhzdHJfc3ViKFllYXIsLTQpKSkgDQojIE9SDQojIHBsb3RkYXRhX2J5Z3JvdXB5ZWFyIDwtIG11dGF0ZShwbG90ZGF0YV9ieWdyb3VweWVhciwgWWVhcj1hcy5udW1lcmljKHN0cl9zdWIoWWVhciwgMiwgNSkpKQ0KIyBPUg0KcGxvdGRhdGFfYnlncm91cHllYXIgPC0gbXV0YXRlKHBsb3RkYXRhX2J5Z3JvdXB5ZWFyLCBZZWFyPWFzLm51bWVyaWMoc3RyX3JlcGxhY2UoWWVhciwgIlgiLCAiIikpKQ0KaGVhZChwbG90ZGF0YV9ieWdyb3VweWVhcikNCmBgYA0KDQpTdXBwb3NlIHlvdSB0YWtlIGEgbG9vayBhdCB0aGUgZGF0YSBhbmQgY2hhbmdlIHlvdXIgbWluZC4gWW91IGRlY2lkZWQgeW91IHByZWZlciB0byBsb29rIGF0IHRoZSBkYXRhIGF0IHRoZSB5ZWFyIGxldmVsIGFuZCBoYXZlIHRoZSBmZXJ0aWxpdHkgcmF0ZXMgZm9yIGVhY2ggaW5jb21lLWdyb3VwIGFzIHNlcGFyYXRlIHZhcmlhYmxlcy4NCg0KIyMjIERhdGEgYnkgR3JvdXAgWWVhciBVc2luZyBgc3ByZWFkKClgDQpgYGB7cn0NCnBsb3RkYXRhX2J5eWVhcjwtIHNlbGVjdChwbG90ZGF0YV9ieWdyb3VweWVhciwgQ291bnRyeS5Db2RlLCBZZWFyLCBGZXJ0aWxpdHlSYXRlKSAlPiUgc3ByZWFkKENvdW50cnkuQ29kZSwgRmVydGlsaXR5UmF0ZSkNCnBsb3RkYXRhX2J5eWVhcg0KYGBgDQpMZXTigJlzIHBsb3QgdGhlIGZlcnRpbGl0eSByYXRlIG92ZXIgdGltZSwgc2VwYXJhdGVseSBmb3IgZWFjaCBpbmNvbWUgbGV2ZWwuDQoNCmBgYHtyfQ0KcCA8LSBnZ3Bsb3QocGxvdGRhdGFfYnlncm91cHllYXIsIGFlcyh4ID0gWWVhciwgeSA9IEZlcnRpbGl0eVJhdGUsIGdyb3VwID0gQ291bnRyeS5Db2RlLCBjb2wgPSBDb3VudHJ5LkNvZGUpKQ0KcCArIGdlb21fbGluZSgpICsgDQogICAgbGFicyh4ID0gIlllYXIiLCB5ID0gIkZlcnRpbGl0eSBSYXRlIiwgdGl0bGUgPSAnRmVydGlsaXR5IFJhdGUgYnkgQ291bnRyeS1JbmNvbWUtTGV2ZWwgb3ZlciBUaW1lJykgKw0KICAgIHNjYWxlX3hfY29udGludW91cyhtaW5vcl9icmVha3MgPSBzZXEoMTk2MCwgMjAxNSwgNSksIGJyZWFrcyA9IHNlcSgxOTYwLCAyMDE1LCAxMCkpICsNCiAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkNCmBgYA0KTm93LCB3ZSBhcmUgbm90IGdvaW5nIHRvIGNvbnNpZGVyIHRoZSB0cmVuZHMgb2YgdGhlIGRpZmZlcmVudCBjYXRlZ29yaWVzIG92ZXIgdGhlIHllYXJzLiBJbnN0ZWFkLCB3ZSBhcmUgZ29pbmcgdG8gY29tcGFyZSBob3cgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgQWRvbGVzY2VudCBGZXJ0aWxpdHkgUmF0ZSBpcyBkaWZmZXJlbnQgYmV0d2VlbiAxOTYwIGFuZCAyMDAwLiANCg0KYGBge3J9DQojR2VuZXJhdGluZyBoaXN0ZGF0YV90d295ZWFycw0KaGlzdGRhdGFfdHdveWVhcnMgPC0gc2VsZWN0KHRlZW5hZ2VfZnIsIENvdW50cnkuTmFtZSwgQ291bnRyeS5Db2RlLCBJbmRpY2F0b3IuTmFtZSwgSW5kaWNhdG9yLkNvZGUsIFgxOTYwLFgyMDAwKQ0KDQpoaXN0ZGF0YV90d295ZWFycyA8LSBnYXRoZXIodGVlbmFnZV9mciwgWWVhciwgRmVydGlsaXR5UmF0ZSwgWDE5NjAsIFgyMDAwKSAlPiUNCiAgc2VsZWN0KFllYXIsIENvdW50cnkuTmFtZSwgQ291bnRyeS5Db2RlLCBGZXJ0aWxpdHlSYXRlKQ0KDQpoaXN0ZGF0YV90d295ZWFycyA8LSBmaWx0ZXIoaGlzdGRhdGFfdHdveWVhcnMsIWlzLm5hKEZlcnRpbGl0eVJhdGUpKQ0KDQpnZ3Bsb3QoaGlzdGRhdGFfdHdveWVhcnMsIGFlcyh4PUZlcnRpbGl0eVJhdGUpKSArIA0KICBnZW9tX2hpc3RvZ3JhbShkYXRhID0gc3Vic2V0KGhpc3RkYXRhX3R3b3llYXJzLCBZZWFyPT0iWDE5NjAiKSwgYmlucyA9IDIwLCBjb2xvcj0iZGFya3JlZCIsIGZpbGw9InJlZCIsIGFscGhhPTAuMikgKyANCiAgZ2VvbV9oaXN0b2dyYW0oZGF0YT1zdWJzZXQoaGlzdGRhdGFfdHdveWVhcnMsIFllYXI9PSJYMjAwMCIpLCBiaW5zID0gMjAsIGNvbG9yPSJkYXJrYmx1ZSIsIGZpbGw9ImJsdWUiLCBhbHBoYT0wLjIpICsgDQogIGxhYnModGl0bGUgPSAiRmVydGlsaXR5IFJhdGVzJyBEaXN0cmlidXRpb24gaW4gMTk2MCBhbmQgMjAwMCIsIHggPSAiRmVydGlsaXR5IFJhdGUiLCB5ID0gIk51bWJlciBvZiBBZG9sZXNjZW50cyIpDQpgYGANCiMjIyBLZXJuZWxzDQpgYGB7cn0NCmdncGxvdChoaXN0ZGF0YV90d295ZWFycywgYWVzKHg9RmVydGlsaXR5UmF0ZSwgZ3JvdXA9WWVhciwgY29sb3I9WWVhciwgYWxwaGE9MC4yKSkgKyAgICAgICAgZ2VvbV9oaXN0b2dyYW0oYWVzKHk9Li5kZW5zaXR5Li4pKSArIGdlb21fZGVuc2l0eShkYXRhPXN1YnNldChoaXN0ZGF0YV90d295ZWFycywgWWVhcj09IlgxOTYwIiksIGNvbG9yPSJkYXJrcmVkIiwgZmlsbD0icmVkIiwgYWxwaGE9MC4yLCBidz01KSArIGdlb21fZGVuc2l0eShkYXRhID0gc3Vic2V0KGhpc3RkYXRhX3R3b3llYXJzLCBZZWFyPT0iWDIwMDAiKSwgY29sb3I9ImRhcmtibHVlIiwgZmlsbD0iYmx1ZSIsIGFscGhhPTAuMiwgYnc9NSkNCmBgYA0KIyMjIEN1bW11bGF0aXZlIERpc3RyaWJ1dGlvbiBGdW5jdGlvbg0KYGBge3J9DQpnZ3Bsb3QoaGlzdGRhdGFfdHdveWVhcnMsIGFlcyh4ID0gRmVydGlsaXR5UmF0ZSkpICsNCiAgc3RhdF9lY2RmKGFlcyhjb2xvciA9IFllYXIsbGluZXR5cGUgPSBZZWFyKSwgDQogICAgICAgICAgICAgIGdlb20gPSAic3RlcCIsIHNpemUgPSAxLjUpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIpKSsNCiAgbGFicyh4ID0iRmVydGlsaXR5IFJhdGUiLCB5ID0gIkN1bW11bGF0aXZlIERpc3RyaWJ1dGlvbiBGdW5jdGlvbiIsIHRpdGxlID0gIkVtcGlyaWNhbCBDdW1tdWxhdGl2ZSBEaXN0cmlidXRpb24gRnVuY3Rpb24gaW4gMTk2MCBhbmQgMjAwMCIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpDQpgYGANCiMjIyBDREYgUGxvdHMgDQoNClRoZSBDREZzIGJlbG93IGFyZSBjYWxjdWxhdGVkIGJ5IGludGVncmF0aW5nIGNhbGN1bGF0ZWQgbWFyZ2luYWwgcGRmcy4gWW91IGNhbiBmaW5kIHRoZSBkZXJpdmF0aXZlcyBvZiB0aGUgYmVsb3cgQ0RGcyB0byBmaW5kIHRoZSBjb3JyZXNwb25kaW5nIHBkZiBmb3IgZWFjaCByYW5kb20gdmFyaWFibGUuIENERiBpcyBkZWZpbmVkIGFzIHRoZSBwcm9iYWJpbGl0eSBvZiBYIGxlc3MgdGhhbiBvciBlcXVhbCB0byB4LiBGcm9tIHRoaXMgZGVmaW5pdGlvbiwgYW5kIGlmIHRoZSByYW5kb20gdmFyaWFibGVzIGFyZSBjb250aW51b3VzLCB0aGVuIG9uZSBtYXkgZmluZCB0aGUgZGVyaXZhdGl2ZSBvZiB0aGUgcGRmLg0KYGBge3J9DQp4IDwtIHNlcSgwLDEsMC4wMDEpDQp5IDwtIHNlcSgwLDEsMC4wMDEpDQpjZGZ4IDwtIDYvNSAqICh4XjIvMiArIHgvMykNCmNkZnkgPC0gNi81ICogKHgvMiArIHheMy8zKQ0KcGxvdCh4LCBjZGZ4LCB0eXBlID0gImwiLCBjb2w9ImJsdWUiLCB4bGFiPSIgIiwgeWxhYiA9ICJDdW11bGF0aXZlIFByb2JhYmlsaXR5IiwgeGxpbT1jKDAsMSksIG1haW49IkNERiBwbG90IikNCmxpbmVzKHksIGNkZnksIGx0eT0yLCBjb2w9InJlZCIsIGx3ZD0yKQ0KbGVnZW5kKCJib3R0b21yaWdodCIsIG5jb2w9MSwgbGVnZW5kID0gYygiWCIsICJZIiksIGx0eT1jKDEsMiksIGNvbD1jKCJibHVlIiwgInJlZCIpKQ0KYGBgDQoqKlJlc291cmNlcyoqDQoNCi0gW1dvcmxkIEJhbmsgR2VuZGVyIHN0YXRpc3RpY3NdKGh0dHBzOi8vZGF0YWNhdGFsb2cud29ybGRiYW5rLm9yZy9kYXRhc2V0L2dlbmRlci1zdGF0aXN0aWNzKQ0KLSBbRUNERiBpbiBnZ3Bsb3RdKGh0dHBzOi8vd3d3LmRhdGFub3ZpYS5jb20vZW4vbGVzc29ucy9nZ3Bsb3QtZWNkZi8pDQotIFt0aWR5cl0oaHR0cHM6Ly91Yy1yLmdpdGh1Yi5pby90aWR5cikNCi0gW0p1cHl0ZXIgYW5kIFIgTWFya2Rvd10oaHR0cHM6Ly93d3cuZGF0YWNhbXAuY29tL2NvbW11bml0eS9ibG9nL2p1cHl0ZXItbm90ZWJvb2stciNtYXJrZG93bikNCi0gW0Z1cnRoZXIgcGxvdGluZyB1c2luZyBnZ3Bsb3RdKGh0dHBzOi8vcnB1YnMuY29tL2V1Y2xpZC8zNDM2NDQpDQotIFtBZGRpdGlvbmFsIFJlc291cmNlc10oaHR0cHM6Ly9jb3Vyc2VzLmVkeC5vcmcvY291cnNlcy9jb3Vyc2UtdjE6TUlUeCsxNC4zMTB4KzFUMjAxOC9lNmQ1ZDg0OTQ1ZmI0YWNhYWQyNWEzMTBlMmJkYjRjOS8pDQoNCg0KDQo=