#Import data
Countries<- read.csv("https://tkelleman.github.io/tkweb/Week5/countries_total.csv")
Income<-read.csv("https://tkelleman.github.io/tkweb/Week5/income_per_person.csv")
LifeExp<-read.csv("https://tkelleman.github.io/tkweb/Week5/life_expectancy_years.csv")
Population<-read.csv("https://tkelleman.github.io/tkweb/Week5/population_total.csv")
## A - Reshape data set: Income Per Person to make a longitudinal data such that the resulting data set has three columns: country, year, and income.
IncomeEdit <- Income %>%
gather(key = "Year", value = "Income", - geo, na.rm=TRUE)
names(IncomeEdit)[1] <- "Country"
## B - Do the same for Life Expectancy in Years so that the resulting data set has three columns: country, year, and life expectancy.
LifeExpEdit <- LifeExp %>%
gather(key = "Year", value = "LifeExpectancy", - geo, na.rm=TRUE)
names(LifeExpEdit)[1] <- "Country"
## C - Merge/join the above two longitudinal data sets to make a new data set, under name LifeExpIncom that has variables: country, year, lifeExp, and income.
LifeExpIncom <- merge(IncomeEdit, LifeExpEdit, by = c("Country", "Year"))
## D - Merge LifeExpIncom with country region so that the final data set has information about income, life expectancy, and country region.
LifeIncomCount <-merge(LifeExpIncom, Countries, by.x = "Country", by.y = "name", all.x = TRUE)
## E - Merge the previous resulting data set with population size so that the final data set has information about income, life expectancy, population size, and country region.
PopulationEdit <- Population %>%
gather(key = "Year", value = "Population", - geo, na.rm=TRUE)
names(PopulationEdit)[1] <- "Country"
FinalData <- merge(LifeIncomCount, PopulationEdit, by = c("Country", "Year"))
FinalData <- subset(FinalData, select = -c(alpha.2, alpha.3, country.code, iso_3166.2, sub.region, region.code, sub.region.code, intermediate.region.code, intermediate.region))
FinalData$Year<-gsub("X","", as.character(FinalData$Year))
#write.csv(FinalData, "FinalData.csv")
## 3 Create a subset of the above resulting longitudinal data set that contains only the data of the year 2000/font> - name it 2000data.
Y2000data<-filter(FinalData, Year==2000)
#Y2000data contains 187 observations of 6 variables
#FinalData contains 40,437 observations of 6 variables
Each of the four data sets CSV files (countries_total,
income_per_person, life_expectancy_years, and
population_total) were imported into R for data preparation.
Exact steps of the data preparation are documented in the comments in
the code above, press “show” button. income_per_person and
life_expectancy_years were reshaped from latitudinal to
longitudinal to only include the columns: “country”, “year”, and “life
expectancy” and merged into one data set. This data set was then merged
into a “FinalData” dataset that included countries_total and
population_total formatted to only include information about
income, life expectancy, population size, and country region.
Y2015data<-filter(FinalData, Year==2015)
#Y2015data<-formatC(Y2015data$Population, format = "d", big.mark = ",")
plot2015<-plot_ly(
data = Y2015data,
x=~Income,
y=~LifeExpectancy,
alpha = 0.8,
size = ~Population,
color = ~Country,
width = 2,
frame = ~Year,
text = ~paste("Country:", Country,
"<br>Life Expectancy:", LifeExpectancy,
"<br>Population:", Population),
hoverinfo = "text",
type = "scatter",
mode = "markers"
)%>%
layout(
title =list(text = "Interactive Plot of Life Expectancy by Income in 2015",
font = list(family = "Times New Roman",
size = 18,
color = "black"))
)
plot2015
Figure 1: Interactive Plot of Life Expectancy by Income in 2015
This interactive plot shows the relationship between life
expectancy and income in the year 2015 in the merged data set. The
population of each country is represented by the diameter of the points
plotted and the color of the point represents the country. As shown in
this figure, countries in the regions of Americas and Europe have a
higher life expectancy than most countries in the Africa region, with a
few outlier data points. As each point is selected, the country, life
expectancy, and population is displayed.
### Full Data Set
cols1 = c("#332288","#117733","#44AA99","#88CCEE","#DDCC77","#CC6677")
AllDataPlot<-ggplot(FinalData, aes(x=Income,
y=LifeExpectancy,
size = Population,
color = region)) +
geom_point(aes(size=Population, ids = Country),
show.legend = TRUE,
alpha = 0.8)+
scale_color_manual(values = cols1)+
labs(title = 'Plot of Life Expectency by Income at Year: {closest_state}',
x = 'Income',
y = 'Life Expectancy',
fill = 'Region')+
transition_states(Year) +
ease_aes('linear')
animate(AllDataPlot, renderer = gifski_renderer(), rewind = FALSE, nframes = 300, fps = 10)
Figure 2: Plot of Life Expectancy by Income for Years 1800-2018
This plot shows the relationship between life expectancy and
income all countries in the merged data set. The population of each
country is represented by the diameter of the points plotted and the
color of the point represents the region of the country. As shown in the
plot, all represented countries increase their life expectancy between
the given years but not all countries show an increase in income.
LS0tDQp0aXRsZTogIldlZWsgNiAtIEludGVyYWN0aXZlIFBsb3RzIHdpdGggUGxvdGx5KCkiDQphdXRob3I6ICJUaW0gS2VsbGVtYW4iDQpkYXRlOiAiMjAyNC0wMi0yOSINCg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgZmlnX3dpZHRoOiA4DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogdHJ1ZQ0KICAgIHRoZW1lOiByZWFkYWJsZQ0KICAgDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDUNCiAgICBmaWdfaGVpZ2h0OiA0DQotLS0NCg0KYGBgez1odG1sfQ0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KZGl2I1RPQyBsaSB7DQogICAgbGlzdC1zdHlsZTpub25lOw0KICAgIGJhY2tncm91bmQtY29sb3I6bGlnaHRncmF5Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCiAgICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCiAgICBjb2xvcjogIzc4MGMwYzsNCn0NCg0KLyogbW91c2Ugb3ZlciBsaW5rICovDQpkaXYjVE9DIGE6aG92ZXIgew0KICBjb2xvcjogcmVkOw0KfQ0KDQovKiB1bnZpc2l0ZWQgbGluayAqLw0KZGl2I1RPQyBhOmxpbmsgew0KICBjb2xvcjogYmx1ZTsNCn0NCg0KDQoNCmgxLnRpdGxlIHsNCiAgZm9udC1zaXplOiAyNHB4Ow0KICBjb2xvcjogRGFya2JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6IEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQogIGZvbnQtdmFyaWFudC1jYXBzOiBub3JtYWw7DQp9DQpoNC5hdXRob3IgeyANCiAgICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuZGF0ZSB7IA0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgxIHsNCiAgICBmb250LXNpemU6IDI0cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDIgew0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IA0KICAgIGZvbnQtc2l6ZTogMTVweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi8qIHVudmlzaXRlZCBsaW5rICovDQphOmxpbmsgew0KICBjb2xvcjogZ3JlZW47DQp9DQoNCi8qIHZpc2l0ZWQgbGluayAqLw0KYTp2aXNpdGVkIHsNCiAgY29sb3I6IGdyZWVuOw0KfQ0KDQovKiBtb3VzZSBvdmVyIGxpbmsgKi8NCmE6aG92ZXIgew0KICBjb2xvcjogcmVkOw0KfQ0KDQovKiBzZWxlY3RlZCBsaW5rICovDQphOmFjdGl2ZSB7DQogIGNvbG9yOiB5ZWxsb3c7DQp9DQo8L3N0eWxlPg0KYGBgDQotLS0NCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQpvcHRpb25zKHJlcG9zID0gbGlzdChDUkFOPSJodHRwOi8vY3Jhbi5yc3R1ZGlvLmNvbS8iKSkNCmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgiY293cGxvdCIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJjb3dwbG90IikNCiAgIGxpYnJhcnkoY293cGxvdCkNCn0NCmlmICghcmVxdWlyZSgibGF0ZXgyZXhwIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImxhdGV4MmV4cCIpDQogICBsaWJyYXJ5KGxhdGV4MmV4cCkNCn0NCmlmICghcmVxdWlyZSgicGxvdGx5IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogICBsaWJyYXJ5KHBsb3RseSkNCn0NCmlmICghcmVxdWlyZSgiZ2FwbWluZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImdhcG1pbmRlciIpDQogICBsaWJyYXJ5KGdhcG1pbmRlcikNCn0NCmlmICghcmVxdWlyZSgicG5nIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJwbmciKSAgICAgICAgICAgICAjIEluc3RhbGwgcG5nIHBhY2thZ2UNCiAgICBsaWJyYXJ5KCJwbmciKQ0KfQ0KaWYgKCFyZXF1aXJlKCJSQ3VybCIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiUkN1cmwiKSAgICAgICAgICAgIyBJbnN0YWxsIFJDdXJsIHBhY2thZ2UNCiAgICBsaWJyYXJ5KCJSQ3VybCIpDQp9DQppZiAoIXJlcXVpcmUoImNvbG91cnBpY2tlciIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiY29sb3VycGlja2VyIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImNvbG91cnBpY2tlciIpDQp9DQppZiAoIXJlcXVpcmUoImdpZnNraSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2lmc2tpIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdpZnNraSIpDQp9DQppZiAoIXJlcXVpcmUoIm1hZ2ljayIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygibWFnaWNrIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoIm1hZ2ljayIpDQp9DQppZiAoIXJlcXVpcmUoImdyRGV2aWNlcyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ3JEZXZpY2VzIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdyRGV2aWNlcyIpDQp9DQojIyMgZ2dwbG90IGFuZCBleHRlbnNpb25zDQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2dwbG90MiIpDQp9DQppZiAoIXJlcXVpcmUoImdnYW5pbWF0ZSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dhbmltYXRlIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdnYW5pbWF0ZSIpDQp9DQppZiAoIXJlcXVpcmUoImdncmlkZ2VzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3JpZGdlcyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnZ3JpZGdlcyIpDQp9DQppZiAoIXJlcXVpcmUoImdyYXBoaWNzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJncmFwaGljcyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJncmFwaGljcyIpDQp9DQppZiAoIXJlcXVpcmUoImRwbHlyIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJkcGx5ciIpDQp9DQoNCg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gVFJVRSwgICANCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BKQ0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRX0NCiNJbXBvcnQgZGF0YQ0KQ291bnRyaWVzPC0gcmVhZC5jc3YoImh0dHBzOi8vdGtlbGxlbWFuLmdpdGh1Yi5pby90a3dlYi9XZWVrNS9jb3VudHJpZXNfdG90YWwuY3N2IikNCkluY29tZTwtcmVhZC5jc3YoImh0dHBzOi8vdGtlbGxlbWFuLmdpdGh1Yi5pby90a3dlYi9XZWVrNS9pbmNvbWVfcGVyX3BlcnNvbi5jc3YiKQ0KTGlmZUV4cDwtcmVhZC5jc3YoImh0dHBzOi8vdGtlbGxlbWFuLmdpdGh1Yi5pby90a3dlYi9XZWVrNS9saWZlX2V4cGVjdGFuY3lfeWVhcnMuY3N2IikNClBvcHVsYXRpb248LXJlYWQuY3N2KCJodHRwczovL3RrZWxsZW1hbi5naXRodWIuaW8vdGt3ZWIvV2VlazUvcG9wdWxhdGlvbl90b3RhbC5jc3YiKQ0KDQojIyBBIC0gUmVzaGFwZSBkYXRhIHNldDogSW5jb21lIFBlciBQZXJzb24gdG8gbWFrZSBhIGxvbmdpdHVkaW5hbCBkYXRhIHN1Y2ggdGhhdCB0aGUgcmVzdWx0aW5nIGRhdGEgc2V0IGhhcyB0aHJlZSBjb2x1bW5zOiBjb3VudHJ5LCB5ZWFyLCBhbmQgaW5jb21lLg0KSW5jb21lRWRpdCA8LSBJbmNvbWUgJT4lDQogIGdhdGhlcihrZXkgPSAiWWVhciIsIHZhbHVlID0gIkluY29tZSIsIC0gZ2VvLCBuYS5ybT1UUlVFKQ0KbmFtZXMoSW5jb21lRWRpdClbMV0gPC0gIkNvdW50cnkiDQoNCiMjIEIgLSBEbyB0aGUgc2FtZSBmb3IgTGlmZSBFeHBlY3RhbmN5IGluIFllYXJzIHNvIHRoYXQgdGhlIHJlc3VsdGluZyBkYXRhIHNldCBoYXMgdGhyZWUgY29sdW1uczogY291bnRyeSwgeWVhciwgYW5kIGxpZmUgZXhwZWN0YW5jeS4NCkxpZmVFeHBFZGl0IDwtIExpZmVFeHAgJT4lDQogIGdhdGhlcihrZXkgPSAiWWVhciIsIHZhbHVlID0gIkxpZmVFeHBlY3RhbmN5IiwgLSBnZW8sIG5hLnJtPVRSVUUpDQpuYW1lcyhMaWZlRXhwRWRpdClbMV0gPC0gIkNvdW50cnkiDQoNCiMjIEMgLSAgTWVyZ2Uvam9pbiB0aGUgYWJvdmUgdHdvIGxvbmdpdHVkaW5hbCBkYXRhIHNldHMgdG8gbWFrZSBhIG5ldyBkYXRhIHNldCwgdW5kZXIgbmFtZSBMaWZlRXhwSW5jb20gdGhhdCBoYXMgdmFyaWFibGVzOiBjb3VudHJ5LCB5ZWFyLCBsaWZlRXhwLCBhbmQgaW5jb21lLg0KTGlmZUV4cEluY29tIDwtIG1lcmdlKEluY29tZUVkaXQsIExpZmVFeHBFZGl0LCBieSA9IGMoIkNvdW50cnkiLCAiWWVhciIpKQ0KDQojIyBEIC0gTWVyZ2UgTGlmZUV4cEluY29tIHdpdGggY291bnRyeSByZWdpb24gc28gdGhhdCB0aGUgZmluYWwgZGF0YSBzZXQgaGFzIGluZm9ybWF0aW9uIGFib3V0IGluY29tZSwgbGlmZSBleHBlY3RhbmN5LCBhbmQgY291bnRyeSByZWdpb24uDQpMaWZlSW5jb21Db3VudCA8LW1lcmdlKExpZmVFeHBJbmNvbSwgQ291bnRyaWVzLCBieS54ID0gIkNvdW50cnkiLCBieS55ID0gIm5hbWUiLCBhbGwueCA9IFRSVUUpDQoNCiMjIEUgLSAgTWVyZ2UgdGhlIHByZXZpb3VzIHJlc3VsdGluZyBkYXRhIHNldCB3aXRoIHBvcHVsYXRpb24gc2l6ZSBzbyB0aGF0IHRoZSBmaW5hbCBkYXRhIHNldCBoYXMgaW5mb3JtYXRpb24gYWJvdXQgaW5jb21lLCBsaWZlIGV4cGVjdGFuY3ksIHBvcHVsYXRpb24gc2l6ZSwgYW5kIGNvdW50cnkgcmVnaW9uLg0KUG9wdWxhdGlvbkVkaXQgPC0gUG9wdWxhdGlvbiAlPiUNCiAgZ2F0aGVyKGtleSA9ICJZZWFyIiwgdmFsdWUgPSAiUG9wdWxhdGlvbiIsIC0gZ2VvLCBuYS5ybT1UUlVFKQ0KbmFtZXMoUG9wdWxhdGlvbkVkaXQpWzFdIDwtICJDb3VudHJ5Ig0KDQpGaW5hbERhdGEgPC0gbWVyZ2UoTGlmZUluY29tQ291bnQsIFBvcHVsYXRpb25FZGl0LCBieSA9IGMoIkNvdW50cnkiLCAiWWVhciIpKQ0KRmluYWxEYXRhIDwtIHN1YnNldChGaW5hbERhdGEsIHNlbGVjdCA9IC1jKGFscGhhLjIsIGFscGhhLjMsIGNvdW50cnkuY29kZSwgaXNvXzMxNjYuMiwgc3ViLnJlZ2lvbiwgcmVnaW9uLmNvZGUsIHN1Yi5yZWdpb24uY29kZSwgaW50ZXJtZWRpYXRlLnJlZ2lvbi5jb2RlLCBpbnRlcm1lZGlhdGUucmVnaW9uKSkNCkZpbmFsRGF0YSRZZWFyPC1nc3ViKCJYIiwiIiwgYXMuY2hhcmFjdGVyKEZpbmFsRGF0YSRZZWFyKSkNCg0KI3dyaXRlLmNzdihGaW5hbERhdGEsICJGaW5hbERhdGEuY3N2IikNCg0KIyMgMyBDcmVhdGUgYSBzdWJzZXQgb2YgdGhlIGFib3ZlIHJlc3VsdGluZyBsb25naXR1ZGluYWwgZGF0YSBzZXQgdGhhdCBjb250YWlucyBvbmx5IHRoZSBkYXRhIG9mIHRoZSB5ZWFyIDIwMDAvZm9udD4gLSBuYW1lIGl0IDIwMDBkYXRhLg0KWTIwMDBkYXRhPC1maWx0ZXIoRmluYWxEYXRhLCBZZWFyPT0yMDAwKQ0KDQojWTIwMDBkYXRhIGNvbnRhaW5zIDE4NyBvYnNlcnZhdGlvbnMgb2YgNiB2YXJpYWJsZXMNCiNGaW5hbERhdGEgY29udGFpbnMgNDAsNDM3IG9ic2VydmF0aW9ucyBvZiA2IHZhcmlhYmxlcw0KDQpgYGANCjxicj4NCkVhY2ggb2YgdGhlIGZvdXIgZGF0YSBzZXRzIENTViBmaWxlcyAoX2NvdW50cmllc190b3RhbF8sIF9pbmNvbWVfcGVyX3BlcnNvbl8sIF9saWZlX2V4cGVjdGFuY3lfeWVhcnNfLCBhbmQgX3BvcHVsYXRpb25fdG90YWxfKSB3ZXJlIGltcG9ydGVkIGludG8gUiBmb3IgZGF0YSBwcmVwYXJhdGlvbi4gRXhhY3Qgc3RlcHMgb2YgdGhlIGRhdGEgcHJlcGFyYXRpb24gYXJlIGRvY3VtZW50ZWQgaW4gdGhlIGNvbW1lbnRzIGluIHRoZSBjb2RlIGFib3ZlLCBwcmVzcyDigJxzaG934oCdIGJ1dHRvbi4gX2luY29tZV9wZXJfcGVyc29uXyBhbmQgX2xpZmVfZXhwZWN0YW5jeV95ZWFyc18gd2VyZSByZXNoYXBlZCBmcm9tIGxhdGl0dWRpbmFsIHRvIGxvbmdpdHVkaW5hbCB0byBvbmx5IGluY2x1ZGUgdGhlIGNvbHVtbnM6IOKAnGNvdW50cnnigJ0sIOKAnHllYXLigJ0sIGFuZCDigJxsaWZlIGV4cGVjdGFuY3nigJ0gYW5kIG1lcmdlZCBpbnRvIG9uZSBkYXRhIHNldC4gVGhpcyBkYXRhIHNldCB3YXMgdGhlbiBtZXJnZWQgaW50byBhIOKAnEZpbmFsRGF0YeKAnSBkYXRhc2V0IHRoYXQgaW5jbHVkZWQgX2NvdW50cmllc190b3RhbF8gYW5kIF9wb3B1bGF0aW9uX3RvdGFsXyBmb3JtYXR0ZWQgdG8gb25seSBpbmNsdWRlIGluZm9ybWF0aW9uIGFib3V0IGluY29tZSwgbGlmZSBleHBlY3RhbmN5LCBwb3B1bGF0aW9uIHNpemUsIGFuZCBjb3VudHJ5IHJlZ2lvbi4NCmBgYHtyIGV2YWw9VFJVRX0NClkyMDE1ZGF0YTwtZmlsdGVyKEZpbmFsRGF0YSwgWWVhcj09MjAxNSkNCiNZMjAxNWRhdGE8LWZvcm1hdEMoWTIwMTVkYXRhJFBvcHVsYXRpb24sIGZvcm1hdCA9ICJkIiwgYmlnLm1hcmsgPSAiLCIpDQpwbG90MjAxNTwtcGxvdF9seSgNCiAgICAgIGRhdGEgPSBZMjAxNWRhdGEsDQogICAgICB4PX5JbmNvbWUsIA0KICAgICAgeT1+TGlmZUV4cGVjdGFuY3ksIA0KICAgICAgYWxwaGEgPSAwLjgsDQogICAgICBzaXplID0gflBvcHVsYXRpb24sIA0KICAgICAgY29sb3IgPSB+Q291bnRyeSwNCiAgICAgIHdpZHRoID0gMiwNCiAgICAgIGZyYW1lID0gflllYXIsDQogICAgICB0ZXh0ID0gfnBhc3RlKCJDb3VudHJ5OiIsIENvdW50cnksDQogICAgICAgICAgICAgICAgICAgICI8YnI+TGlmZSBFeHBlY3RhbmN5OiIsIExpZmVFeHBlY3RhbmN5LA0KICAgICAgICAgICAgICAgICAgICAiPGJyPlBvcHVsYXRpb246IiwgUG9wdWxhdGlvbiksDQogICAgICBob3ZlcmluZm8gPSAidGV4dCIsDQogICAgICB0eXBlID0gInNjYXR0ZXIiLA0KICAgICAgbW9kZSA9ICJtYXJrZXJzIg0KKSU+JQ0KbGF5b3V0KA0KICB0aXRsZSA9bGlzdCh0ZXh0ID0gIkludGVyYWN0aXZlIFBsb3Qgb2YgTGlmZSBFeHBlY3RhbmN5IGJ5IEluY29tZSBpbiAyMDE1IiwgDQogICAgICAgICAgICAgICAgICBmb250ID0gbGlzdChmYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDE4LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikpDQogICkNCnBsb3QyMDE1DQpgYGANCg0KPGJyPg0KRmlndXJlIDE6IEludGVyYWN0aXZlIFBsb3Qgb2YgTGlmZSBFeHBlY3RhbmN5IGJ5IEluY29tZSBpbiAyMDE1IDxicj4gPGJyPiAgVGhpcyBpbnRlcmFjdGl2ZSBwbG90IHNob3dzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBsaWZlIGV4cGVjdGFuY3kgYW5kIGluY29tZSBpbiB0aGUgeWVhciAyMDE1IGluIHRoZSBtZXJnZWQgZGF0YSBzZXQuIFRoZSBwb3B1bGF0aW9uIG9mIGVhY2ggY291bnRyeSBpcyByZXByZXNlbnRlZCBieSB0aGUgZGlhbWV0ZXIgb2YgdGhlIHBvaW50cyBwbG90dGVkIGFuZCB0aGUgY29sb3Igb2YgdGhlIHBvaW50IHJlcHJlc2VudHMgdGhlIGNvdW50cnkuIEFzIHNob3duIGluIHRoaXMgZmlndXJlLCBjb3VudHJpZXMgaW4gdGhlIHJlZ2lvbnMgb2YgQW1lcmljYXMgYW5kIEV1cm9wZSBoYXZlIGEgaGlnaGVyIGxpZmUgZXhwZWN0YW5jeSB0aGFuIG1vc3QgY291bnRyaWVzIGluIHRoZSBBZnJpY2EgcmVnaW9uLCB3aXRoIGEgZmV3IG91dGxpZXIgZGF0YSBwb2ludHMuIEFzIGVhY2ggcG9pbnQgaXMgc2VsZWN0ZWQsIHRoZSBjb3VudHJ5LCBsaWZlIGV4cGVjdGFuY3ksIGFuZCBwb3B1bGF0aW9uIGlzIGRpc3BsYXllZC4NCmBgYHtyIGV2YWw9VFJVRX0NCiMjIyBGdWxsIERhdGEgU2V0DQpjb2xzMSA9IGMoIiMzMzIyODgiLCIjMTE3NzMzIiwiIzQ0QUE5OSIsIiM4OENDRUUiLCIjRERDQzc3IiwiI0NDNjY3NyIpDQpBbGxEYXRhUGxvdDwtZ2dwbG90KEZpbmFsRGF0YSwgYWVzKHg9SW5jb21lLCANCiAgICAgICAgICAgICAgICAgICAgICB5PUxpZmVFeHBlY3RhbmN5LCANCiAgICAgICAgICAgICAgICAgICAgICBzaXplID0gUG9wdWxhdGlvbiwgDQogICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSByZWdpb24pKSArDQogIGdlb21fcG9pbnQoYWVzKHNpemU9UG9wdWxhdGlvbiwgaWRzID0gQ291bnRyeSksDQogICAgICAgICAgICBzaG93LmxlZ2VuZCA9IFRSVUUsDQogICAgICAgICAgICBhbHBoYSA9IDAuOCkrDQogICAgICAgICAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczEpKw0KICAgIGxhYnModGl0bGUgPSAnUGxvdCBvZiBMaWZlIEV4cGVjdGVuY3kgYnkgSW5jb21lIGF0IFllYXI6IHtjbG9zZXN0X3N0YXRlfScsDQogICAgICAgeCA9ICdJbmNvbWUnLA0KICAgICAgIHkgPSAnTGlmZSBFeHBlY3RhbmN5JywNCiAgICAgICBmaWxsID0gICdSZWdpb24nKSsNCiAgICB0cmFuc2l0aW9uX3N0YXRlcyhZZWFyKSArDQogICAgZWFzZV9hZXMoJ2xpbmVhcicpDQoNCmFuaW1hdGUoQWxsRGF0YVBsb3QsIHJlbmRlcmVyID0gZ2lmc2tpX3JlbmRlcmVyKCksIHJld2luZCA9IEZBTFNFLCBuZnJhbWVzID0gMzAwLCBmcHMgPSAxMCkNCmBgYA0KPGJyPg0KRmlndXJlIDI6IFBsb3Qgb2YgTGlmZSBFeHBlY3RhbmN5IGJ5IEluY29tZSBmb3IgWWVhcnMgMTgwMC0yMDE4IDxicj4gPGJyPiAgVGhpcyBwbG90IHNob3dzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBsaWZlIGV4cGVjdGFuY3kgYW5kIGluY29tZSBhbGwgY291bnRyaWVzIGluIHRoZSBtZXJnZWQgZGF0YSBzZXQuIFRoZSBwb3B1bGF0aW9uIG9mIGVhY2ggY291bnRyeSBpcyByZXByZXNlbnRlZCBieSB0aGUgZGlhbWV0ZXIgb2YgdGhlIHBvaW50cyBwbG90dGVkIGFuZCB0aGUgY29sb3Igb2YgdGhlIHBvaW50IHJlcHJlc2VudHMgdGhlIHJlZ2lvbiBvZiB0aGUgY291bnRyeS4gQXMgc2hvd24gaW4gdGhlIHBsb3QsIGFsbCByZXByZXNlbnRlZCBjb3VudHJpZXMgaW5jcmVhc2UgdGhlaXIgbGlmZSBleHBlY3RhbmN5IGJldHdlZW4gdGhlIGdpdmVuIHllYXJzIGJ1dCBub3QgYWxsIGNvdW50cmllcyBzaG93IGFuIGluY3JlYXNlIGluIGluY29tZS4gDQo=