1 Data Summary

income <- read.csv("https://ecoleman451.github.io/website/Data%20Visualization/Datasets/income_per_person.csv")

life <- read.csv("https://ecoleman451.github.io/website/Data%20Visualization/Datasets/life_expectancy_years.csv")

# Reshape data set such that there are only three columns (Geo, Year, & Income)
new_income <- pivot_longer(income, cols = -geo, names_to = "year", values_to = "income")

new_life <- pivot_longer(life, cols = -geo, names_to = "year", values_to = "life.expectancy")

## Create new data set
LifeExpIncom <- merge(new_life, new_income, by = c("geo", "year"))

## Read in More Data
country <- read.csv("https://ecoleman451.github.io/website/Data%20Visualization/Datasets/countries_total.csv")

pop <- read.csv("https://ecoleman451.github.io/website/Data%20Visualization/Datasets/population_total.csv")

new_pop <- pivot_longer(pop, cols = -geo, names_to = "year", values_to = "population")

## Merge LifeExpIncom with Country
merged <- merge(LifeExpIncom, country, by.x = "geo", by.y = "name", all.x = TRUE)

## Merge Population with Merged Data
fin_data <- merge(new_pop, merged, by = c("geo", "year"), all.x = TRUE)

## Get Data for Year 2000
final_data <- subset(fin_data, year =="X2000")

We first read in two datasets called “income” and “life,” which represent income and life expectancy values over many years. “Income” has 193 observations with 220 total variables, while “Life” has 187 observations and 220 total variables. Next, we reshape both datasets to have only three columns: Geo, Year, and Income or Life Expectancy. We then merge these reshaped sets into a dataset called “LifeExpIncome,” which now contains Geo, Year, Income, and Life Expectancy (40953 observations and 4 variables). Next, we read in two more datasets: “country” (240 observations and 11 variables) and “pop” (195 observations and 220 variables), representing country and population data, respectively. We reshape “pop” to align with “LifeExpIncome” and “Country,” which already have Year transformed into a single column. After this, we merge “LifeExpIncome” with “Country” and then merge this newly combined set with the reshaped “pop” set, creating a dataset called “fin_data” (42705 observations and 15 variables). Finally, we subset the data to focus only on data from the year 2000, resulting in our “final_data” set (195 observations and 15 variables):

2 GGPlot

The scatter plot below shows the relationship between income, life expectancy, and population size across different regions in the year 2000. Each point represents a country, with the size of the points corresponding to the population size of that specific region. The countries are color-coded for better visualization.

scatter_pop <- ggplot(final_data, aes(x = life.expectancy, y = income, color = region, size = population)) +
  geom_point() +
  labs(title = "Life Expectancy vs. Income per Region (2000)",
       x = "Life Expectancy",
       y = "Income",
       size = "Population",
       color = "Region")
scatter_pop

From the plot, we observe a slightly positive correlation between income and life expectancy. It indicates that countries with higher incomes are likely to have longer life expectancies. Additionally, countries in the Americas and Asia tend to have larger populations, as indicated by the larger point sizes. This also suggests that countries with higher populations might have longer life expectancies. European countries appear to have the longest life expectancies, with most of their points on the far right side of the graph, although their populations are not as large as those of other regions. Next, we subset the data to focus on the year 2015, resulting in our “final_data” set (195 observations and 15 variables). Now, let’s examine the overall summary statistics for the dataset “fin_data,” which includes data from all years, not just 2015.

## Get Data for Year 2015
final_data <- subset(fin_data, year =="X2015")

3 Plotly

The plot below shows the relationship between income, life expectancy, and population size across different regions over several years. Each point represents a country, with the size of the points corresponding to the population size of that specific country. The countries are color-coded by region for better visualization. To make the plot more visually appealing, we’ve applied a transformation to the population size using a logarithmic function. This transformation compresses the range of population sizes, reducing the size of the points and making the plot clearer and easier to interpret. Additionally, the x-axis uses a logarithmic scale to better visualize the wide range of income values. The plot is animated to show how these relationships change over time, providing a dynamic view of global trends in income, life expectancy, and population:

pal.IBM <- c("#332288", "#117733", "#0072B2","#D55E00", "#882255")
pal.IBM <- setNames(pal.IBM, c("Asia", "Europe", "Africa", "Americas", "Oceania"))

# Ensure no NA values in the region column
final_data <- final_data %>%
  filter(!is.na(region))  # Remove rows with NA in the region column

# Filter data to remove NA values and convert year to numeric
final_data$year <- as.numeric(gsub("X", "", final_data$year))
final_data <- final_data %>%
  filter(!is.na(life.expectancy) & !is.na(income) & !is.na(population))

fig <- final_data %>%
  plot_ly(
    x = ~income, 
    y = ~life.expectancy, 
    size = ~(2*log(population)-11)^2,
    color = ~region, 
    colors = pal.IBM,   # custom colors
    frame = ~year,      # the time variable to
    text = ~paste("Country:", geo,
                  "<br>Region:", region,
                  "<br>Year:", year,
                  "<br>Life Expectancy:", life.expectancy,
                  "<br>Population:", population,
                  "<br>Income per Person:", income),
    hoverinfo = "text",
    type = 'scatter',
    mode = 'markers'
  )
fig <- fig %>% layout(
    xaxis = list(
      type = "log"
    ),
    title = "Income vs. Life Expectancy Over Time",
    xaxis = list(title = "Income per Person (Log Scale)"),
    yaxis = list(title = "Life Expectancy")
  )

fig

The x-axis represents the income levels for each country, with higher incomes positioned further to the right. The y-axis represents life expectancy, with higher life expectancies positioned higher on the axis. From the plot, we can observe that some countries dominate the scatter plot due to their larger population sizes and higher incomes. This visualization allows us to analyze whether countries with higher incomes generally have longer life expectancies. Additionally, we can examine whether there is a correlation between population size and income levels, helping to identify trends and patterns in the data.

In the animated plot, each frame corresponds to a different year, showing how the relationship between income, life expectancy, and population size evolves over time. The size of each point is determined by the population of the country, with larger points indicating larger populations. The color of the points indicates the region to which the country belongs, allowing us to see regional trends and differences more clearly. By observing the animation, we can identify how economic and health outcomes have changed across different regions and time periods, providing insights into global development patterns.

LS0tDQp0aXRsZTogIkdHUGxvdCAmIFBsb3RseSINCmF1dGhvcjogIkVkd2FyZCBDb2xlbWFuIg0KZGF0ZTogIjAyLTIyLTIwMjQiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBmaWdfd2lkdGg6IDYNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHRydWUNCiAgICB0aGVtZTogcmVhZGFibGUNCiAgICBmaWdfaGVpZ2h0OiA0DQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KZGl2I1RPQyBsaSB7DQogICAgbGlzdC1zdHlsZTpub25lOw0KICAgIGJhY2tncm91bmQtY29sb3I6bGlnaHRncmF5Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCiAgICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCiAgICBjb2xvcjogIzc4MGMwYzsNCn0NCg0KLyogbW91c2Ugb3ZlciBsaW5rICovDQpkaXYjVE9DIGE6aG92ZXIgew0KICBjb2xvcjogcmVkOw0KfQ0KDQovKiB1bnZpc2l0ZWQgbGluayAqLw0KZGl2I1RPQyBhOmxpbmsgew0KICBjb2xvcjogYmx1ZTsNCn0NCg0KaDEudGl0bGUgew0KICBmb250LXNpemU6IDI0cHg7DQogIGNvbG9yOiBEYXJrYmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCiAgZm9udC12YXJpYW50LWNhcHM6IG5vcm1hbDsNCn0NCmg0LmF1dGhvciB7IA0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuZGF0ZSB7IA0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgew0KICBmb250LXNpemU6IDIycHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogZGFya3JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDIgeyANCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IG5hdnk7DQogIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgDQogIGZvbnQtc2l6ZTogMTVweDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBuYXZ5Ow0KICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IA0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogZGFya3JlZDsNCiAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogdW52aXNpdGVkIGxpbmsgKi8NCmE6bGluayB7DQogIGNvbG9yOiBncmVlbjsNCn0NCg0KLyogdmlzaXRlZCBsaW5rICovDQphOnZpc2l0ZWQgew0KICBjb2xvcjogZ3JlZW47DQp9DQoNCi8qIG1vdXNlIG92ZXIgbGluayAqLw0KYTpob3ZlciB7DQogIGNvbG9yOiByZWQ7DQp9DQoNCi8qIHNlbGVjdGVkIGxpbmsgKi8NCmE6YWN0aXZlIHsNCiAgY29sb3I6IHllbGxvdzsNCn0NCg0KPC9zdHlsZT4NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0UsIGNvbW1lbnQ9TkF9DQpvcHRpb25zKHJlcG9zID0gbGlzdChDUkFOPSJodHRwOi8vY3Jhbi5yc3R1ZGlvLmNvbS8iKSkNCmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgiY293cGxvdCIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJjb3dwbG90IikNCiAgIGxpYnJhcnkoY293cGxvdCkNCn0NCmlmICghcmVxdWlyZSgibGF0ZXgyZXhwIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImxhdGV4MmV4cCIpDQogICBsaWJyYXJ5KGxhdGV4MmV4cCkNCn0NCmlmICghcmVxdWlyZSgicGxvdGx5IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogICBsaWJyYXJ5KHBsb3RseSkNCn0NCmlmICghcmVxdWlyZSgiZ2FwbWluZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImdhcG1pbmRlciIpDQogICBsaWJyYXJ5KGdhcG1pbmRlcikNCn0NCmlmICghcmVxdWlyZSgicG5nIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJwbmciKSAgICANCiAgICBsaWJyYXJ5KCJwbmciKQ0KfQ0KaWYgKCFyZXF1aXJlKCJSQ3VybCIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiUkN1cmwiKSAgICANCiAgICBsaWJyYXJ5KCJSQ3VybCIpDQp9DQppZiAoIXJlcXVpcmUoImNvbG91cnBpY2tlciIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiY29sb3VycGlja2VyIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImNvbG91cnBpY2tlciIpDQp9DQppZiAoIXJlcXVpcmUoImdnYW5pbWF0ZSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dhbmltYXRlIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdnYW5pbWF0ZSIpDQp9DQppZiAoIXJlcXVpcmUoImdpZnNraSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2lmc2tpIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdpZnNraSIpDQp9DQppZiAoIXJlcXVpcmUoIm1hZ2ljayIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygibWFnaWNrIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoIm1hZ2ljayIpDQp9DQppZiAoIXJlcXVpcmUoImdyRGV2aWNlcyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ3JEZXZpY2VzIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdyRGV2aWNlcyIpDQp9DQppZiAoIXJlcXVpcmUoImpwZWciKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImpwZWciKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgianBlZyIpDQp9DQppZiAoIXJlcXVpcmUoImdncmlkZ2VzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3JpZGdlcyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnZ3JpZGdlcyIpDQp9DQppZiAoIXJlcXVpcmUoInBseXIiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoInBseXIiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgicGx5ciIpDQp9DQppZiAoIXJlcXVpcmUoImdnaXJhcGgiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdnaXJhcGgiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2dpcmFwaCIpDQp9DQppZiAoIXJlcXVpcmUoImhpZ2hjaGFydGVyIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJoaWdoY2hhcnRlciIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJoaWdoY2hhcnRlciIpDQp9DQppZiAoIXJlcXVpcmUoImZvcmVjYXN0IikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJmb3JlY2FzdCIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJmb3JlY2FzdCIpDQp9DQppZiAoIXJlcXVpcmUoImxlYWZsZXQiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImxlYWZsZXQiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgibGVhZmxldCIpDQp9DQppZiAoIXJlcXVpcmUoInNmIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJzZiIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJzZiIpDQp9DQppZiAoIXJlcXVpcmUoIlN0YXQyRGF0YSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJTdGF0MkRhdGEiKQ0KICAgbGlicmFyeShTdGF0MkRhdGEpDQp9DQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCiAgZWNobyA9IFRSVUUsICAgICAgIA0KICB3YXJuaW5nID0gRkFMU0UsICAgDQogIHJlc3VsdCA9IFRSVUUsICAgDQogIG1lc3NhZ2UgPSBGQUxTRSwNCiAgY29tbWVudCA9IE5BDQopDQoNCmxpYnJhcnkoY29sb3JzcGFjZSkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ2dmb3JjZSkNCmxpYnJhcnkoZ2dyaWRnZXMpDQpsaWJyYXJ5KHRyZWVtYXBpZnkpDQpsaWJyYXJ5KGZvcmNhdHMpDQpsaWJyYXJ5KHN0YXRlYmlucykNCmxpYnJhcnkoc2YpDQpsaWJyYXJ5KGNvd3Bsb3QpDQoNCm9wdGlvbnMoZGlnaXRzID0gMykNCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCiAgZWNobyA9IFRSVUUsDQogIG1lc3NhZ2UgPSBGQUxTRSwNCiAgd2FybmluZyA9IEZBTFNFLA0KICBjYWNoZSA9IEZBTFNFLA0KICBmaWcuYWxpZ24gPSAnY2VudGVyJywNCiAgZmlnLndpZHRoID0gNiwNCiAgZmlnLmFzcCA9IDAuNjE4LA0KICBmaWcuc2hvdyA9ICJob2xkIg0KKQ0Kb3B0aW9ucyhkcGx5ci5wcmludF9taW4gPSA2LCBkcGx5ci5wcmludF9tYXggPSA2KQ0KYGBgDQoNCiMgRGF0YSBTdW1tYXJ5DQpgYGB7cn0NCmluY29tZSA8LSByZWFkLmNzdigiaHR0cHM6Ly9lY29sZW1hbjQ1MS5naXRodWIuaW8vd2Vic2l0ZS9EYXRhJTIwVmlzdWFsaXphdGlvbi9EYXRhc2V0cy9pbmNvbWVfcGVyX3BlcnNvbi5jc3YiKQ0KDQpsaWZlIDwtIHJlYWQuY3N2KCJodHRwczovL2Vjb2xlbWFuNDUxLmdpdGh1Yi5pby93ZWJzaXRlL0RhdGElMjBWaXN1YWxpemF0aW9uL0RhdGFzZXRzL2xpZmVfZXhwZWN0YW5jeV95ZWFycy5jc3YiKQ0KDQojIFJlc2hhcGUgZGF0YSBzZXQgc3VjaCB0aGF0IHRoZXJlIGFyZSBvbmx5IHRocmVlIGNvbHVtbnMgKEdlbywgWWVhciwgJiBJbmNvbWUpDQpuZXdfaW5jb21lIDwtIHBpdm90X2xvbmdlcihpbmNvbWUsIGNvbHMgPSAtZ2VvLCBuYW1lc190byA9ICJ5ZWFyIiwgdmFsdWVzX3RvID0gImluY29tZSIpDQoNCm5ld19saWZlIDwtIHBpdm90X2xvbmdlcihsaWZlLCBjb2xzID0gLWdlbywgbmFtZXNfdG8gPSAieWVhciIsIHZhbHVlc190byA9ICJsaWZlLmV4cGVjdGFuY3kiKQ0KDQojIyBDcmVhdGUgbmV3IGRhdGEgc2V0DQpMaWZlRXhwSW5jb20gPC0gbWVyZ2UobmV3X2xpZmUsIG5ld19pbmNvbWUsIGJ5ID0gYygiZ2VvIiwgInllYXIiKSkNCg0KIyMgUmVhZCBpbiBNb3JlIERhdGENCmNvdW50cnkgPC0gcmVhZC5jc3YoImh0dHBzOi8vZWNvbGVtYW40NTEuZ2l0aHViLmlvL3dlYnNpdGUvRGF0YSUyMFZpc3VhbGl6YXRpb24vRGF0YXNldHMvY291bnRyaWVzX3RvdGFsLmNzdiIpDQoNCnBvcCA8LSByZWFkLmNzdigiaHR0cHM6Ly9lY29sZW1hbjQ1MS5naXRodWIuaW8vd2Vic2l0ZS9EYXRhJTIwVmlzdWFsaXphdGlvbi9EYXRhc2V0cy9wb3B1bGF0aW9uX3RvdGFsLmNzdiIpDQoNCm5ld19wb3AgPC0gcGl2b3RfbG9uZ2VyKHBvcCwgY29scyA9IC1nZW8sIG5hbWVzX3RvID0gInllYXIiLCB2YWx1ZXNfdG8gPSAicG9wdWxhdGlvbiIpDQoNCiMjIE1lcmdlIExpZmVFeHBJbmNvbSB3aXRoIENvdW50cnkNCm1lcmdlZCA8LSBtZXJnZShMaWZlRXhwSW5jb20sIGNvdW50cnksIGJ5LnggPSAiZ2VvIiwgYnkueSA9ICJuYW1lIiwgYWxsLnggPSBUUlVFKQ0KDQojIyBNZXJnZSBQb3B1bGF0aW9uIHdpdGggTWVyZ2VkIERhdGENCmZpbl9kYXRhIDwtIG1lcmdlKG5ld19wb3AsIG1lcmdlZCwgYnkgPSBjKCJnZW8iLCAieWVhciIpLCBhbGwueCA9IFRSVUUpDQoNCiMjIEdldCBEYXRhIGZvciBZZWFyIDIwMDANCmZpbmFsX2RhdGEgPC0gc3Vic2V0KGZpbl9kYXRhLCB5ZWFyID09IlgyMDAwIikNCmBgYA0KICBXZSBmaXJzdCByZWFkIGluIHR3byBkYXRhc2V0cyBjYWxsZWQgImluY29tZSIgYW5kICJsaWZlLCIgd2hpY2ggcmVwcmVzZW50IGluY29tZSBhbmQgbGlmZSBleHBlY3RhbmN5IHZhbHVlcyBvdmVyIG1hbnkgeWVhcnMuICJJbmNvbWUiIGhhcyAxOTMgb2JzZXJ2YXRpb25zIHdpdGggMjIwIHRvdGFsIHZhcmlhYmxlcywgd2hpbGUgIkxpZmUiIGhhcyAxODcgb2JzZXJ2YXRpb25zIGFuZCAyMjAgdG90YWwgdmFyaWFibGVzLiBOZXh0LCB3ZSByZXNoYXBlIGJvdGggZGF0YXNldHMgdG8gaGF2ZSBvbmx5IHRocmVlIGNvbHVtbnM6IEdlbywgWWVhciwgYW5kIEluY29tZSBvciBMaWZlIEV4cGVjdGFuY3kuIFdlIHRoZW4gbWVyZ2UgdGhlc2UgcmVzaGFwZWQgc2V0cyBpbnRvIGEgZGF0YXNldCBjYWxsZWQgIkxpZmVFeHBJbmNvbWUsIiB3aGljaCBub3cgY29udGFpbnMgR2VvLCBZZWFyLCBJbmNvbWUsIGFuZCBMaWZlIEV4cGVjdGFuY3kgKDQwOTUzIG9ic2VydmF0aW9ucyBhbmQgNCB2YXJpYWJsZXMpLiANCk5leHQsIHdlIHJlYWQgaW4gdHdvIG1vcmUgZGF0YXNldHM6ICJjb3VudHJ5IiAoMjQwIG9ic2VydmF0aW9ucyBhbmQgMTEgdmFyaWFibGVzKSBhbmQgInBvcCIgKDE5NSBvYnNlcnZhdGlvbnMgYW5kIDIyMCB2YXJpYWJsZXMpLCByZXByZXNlbnRpbmcgY291bnRyeSBhbmQgcG9wdWxhdGlvbiBkYXRhLCByZXNwZWN0aXZlbHkuIFdlIHJlc2hhcGUgInBvcCIgdG8gYWxpZ24gd2l0aCAiTGlmZUV4cEluY29tZSIgYW5kICJDb3VudHJ5LCIgd2hpY2ggYWxyZWFkeSBoYXZlIFllYXIgdHJhbnNmb3JtZWQgaW50byBhIHNpbmdsZSBjb2x1bW4uIEFmdGVyIHRoaXMsIHdlIG1lcmdlICJMaWZlRXhwSW5jb21lIiB3aXRoICJDb3VudHJ5IiBhbmQgdGhlbiBtZXJnZSB0aGlzIG5ld2x5IGNvbWJpbmVkIHNldCB3aXRoIHRoZSByZXNoYXBlZCAicG9wIiBzZXQsIGNyZWF0aW5nIGEgZGF0YXNldCBjYWxsZWQgImZpbl9kYXRhIiAoNDI3MDUgb2JzZXJ2YXRpb25zIGFuZCAxNSB2YXJpYWJsZXMpLiBGaW5hbGx5LCB3ZSBzdWJzZXQgdGhlIGRhdGEgdG8gZm9jdXMgb25seSBvbiBkYXRhIGZyb20gdGhlIHllYXIgMjAwMCwgcmVzdWx0aW5nIGluIG91ciAiZmluYWxfZGF0YSIgc2V0ICgxOTUgb2JzZXJ2YXRpb25zIGFuZCAxNSB2YXJpYWJsZXMpOg0KDQojIEdHUGxvdA0KICBUaGUgc2NhdHRlciBwbG90IGJlbG93IHNob3dzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmNvbWUsIGxpZmUgZXhwZWN0YW5jeSwgYW5kIHBvcHVsYXRpb24gc2l6ZSBhY3Jvc3MgZGlmZmVyZW50IHJlZ2lvbnMgaW4gdGhlIHllYXIgMjAwMC4gRWFjaCBwb2ludCByZXByZXNlbnRzIGEgY291bnRyeSwgd2l0aCB0aGUgc2l6ZSBvZiB0aGUgcG9pbnRzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHBvcHVsYXRpb24gc2l6ZSBvZiB0aGF0IHNwZWNpZmljIHJlZ2lvbi4gVGhlIGNvdW50cmllcyBhcmUgY29sb3ItY29kZWQgZm9yIGJldHRlciB2aXN1YWxpemF0aW9uLg0KYGBge3J9DQpzY2F0dGVyX3BvcCA8LSBnZ3Bsb3QoZmluYWxfZGF0YSwgYWVzKHggPSBsaWZlLmV4cGVjdGFuY3ksIHkgPSBpbmNvbWUsIGNvbG9yID0gcmVnaW9uLCBzaXplID0gcG9wdWxhdGlvbikpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgbGFicyh0aXRsZSA9ICJMaWZlIEV4cGVjdGFuY3kgdnMuIEluY29tZSBwZXIgUmVnaW9uICgyMDAwKSIsDQogICAgICAgeCA9ICJMaWZlIEV4cGVjdGFuY3kiLA0KICAgICAgIHkgPSAiSW5jb21lIiwNCiAgICAgICBzaXplID0gIlBvcHVsYXRpb24iLA0KICAgICAgIGNvbG9yID0gIlJlZ2lvbiIpDQpzY2F0dGVyX3BvcA0KYGBgDQogIEZyb20gdGhlIHBsb3QsIHdlIG9ic2VydmUgYSBzbGlnaHRseSBwb3NpdGl2ZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIGluY29tZSBhbmQgbGlmZSBleHBlY3RhbmN5LiBJdCBpbmRpY2F0ZXMgdGhhdCBjb3VudHJpZXMgd2l0aCBoaWdoZXIgaW5jb21lcyBhcmUgbGlrZWx5IHRvIGhhdmUgbG9uZ2VyIGxpZmUgZXhwZWN0YW5jaWVzLiBBZGRpdGlvbmFsbHksIGNvdW50cmllcyBpbiB0aGUgQW1lcmljYXMgYW5kIEFzaWEgdGVuZCB0byBoYXZlIGxhcmdlciBwb3B1bGF0aW9ucywgYXMgaW5kaWNhdGVkIGJ5IHRoZSBsYXJnZXIgcG9pbnQgc2l6ZXMuIFRoaXMgYWxzbyBzdWdnZXN0cyB0aGF0IGNvdW50cmllcyB3aXRoIGhpZ2hlciBwb3B1bGF0aW9ucyBtaWdodCBoYXZlIGxvbmdlciBsaWZlIGV4cGVjdGFuY2llcy4gRXVyb3BlYW4gY291bnRyaWVzIGFwcGVhciB0byBoYXZlIHRoZSBsb25nZXN0IGxpZmUgZXhwZWN0YW5jaWVzLCB3aXRoIG1vc3Qgb2YgdGhlaXIgcG9pbnRzIG9uIHRoZSBmYXIgcmlnaHQgc2lkZSBvZiB0aGUgZ3JhcGgsIGFsdGhvdWdoIHRoZWlyIHBvcHVsYXRpb25zIGFyZSBub3QgYXMgbGFyZ2UgYXMgdGhvc2Ugb2Ygb3RoZXIgcmVnaW9ucy4NCglOZXh0LCB3ZSBzdWJzZXQgdGhlIGRhdGEgdG8gZm9jdXMgb24gdGhlIHllYXIgMjAxNSwgcmVzdWx0aW5nIGluIG91ciAiZmluYWxfZGF0YSIgc2V0ICgxOTUgb2JzZXJ2YXRpb25zIGFuZCAxNSB2YXJpYWJsZXMpLiBOb3csIGxldOKAmXMgZXhhbWluZSB0aGUgb3ZlcmFsbCBzdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHRoZSBkYXRhc2V0ICJmaW5fZGF0YSwiIHdoaWNoIGluY2x1ZGVzIGRhdGEgZnJvbSBhbGwgeWVhcnMsIG5vdCBqdXN0IDIwMTUuDQpgYGB7ciwgY29tbWVudD1OQX0NCiMjIEdldCBEYXRhIGZvciBZZWFyIDIwMTUNCmZpbmFsX2RhdGEgPC0gc3Vic2V0KGZpbl9kYXRhLCB5ZWFyID09IlgyMDE1IikNCmBgYA0KDQojIFBsb3RseQ0KICBUaGUgcGxvdCBiZWxvdyBzaG93cyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gaW5jb21lLCBsaWZlIGV4cGVjdGFuY3ksIGFuZCBwb3B1bGF0aW9uIHNpemUgYWNyb3NzIGRpZmZlcmVudCByZWdpb25zIG92ZXIgc2V2ZXJhbCB5ZWFycy4gRWFjaCBwb2ludCByZXByZXNlbnRzIGEgY291bnRyeSwgd2l0aCB0aGUgc2l6ZSBvZiB0aGUgcG9pbnRzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHBvcHVsYXRpb24gc2l6ZSBvZiB0aGF0IHNwZWNpZmljIGNvdW50cnkuIFRoZSBjb3VudHJpZXMgYXJlIGNvbG9yLWNvZGVkIGJ5IHJlZ2lvbiBmb3IgYmV0dGVyIHZpc3VhbGl6YXRpb24uIFRvIG1ha2UgdGhlIHBsb3QgbW9yZSB2aXN1YWxseSBhcHBlYWxpbmcsIHdlJ3ZlIGFwcGxpZWQgYSB0cmFuc2Zvcm1hdGlvbiB0byB0aGUgcG9wdWxhdGlvbiBzaXplIHVzaW5nIGEgbG9nYXJpdGhtaWMgZnVuY3Rpb24uIFRoaXMgdHJhbnNmb3JtYXRpb24gY29tcHJlc3NlcyB0aGUgcmFuZ2Ugb2YgcG9wdWxhdGlvbiBzaXplcywgcmVkdWNpbmcgdGhlIHNpemUgb2YgdGhlIHBvaW50cyBhbmQgbWFraW5nIHRoZSBwbG90IGNsZWFyZXIgYW5kIGVhc2llciB0byBpbnRlcnByZXQuIEFkZGl0aW9uYWxseSwgdGhlIHgtYXhpcyB1c2VzIGEgbG9nYXJpdGhtaWMgc2NhbGUgdG8gYmV0dGVyIHZpc3VhbGl6ZSB0aGUgd2lkZSByYW5nZSBvZiBpbmNvbWUgdmFsdWVzLiBUaGUgcGxvdCBpcyBhbmltYXRlZCB0byBzaG93IGhvdyB0aGVzZSByZWxhdGlvbnNoaXBzIGNoYW5nZSBvdmVyIHRpbWUsIHByb3ZpZGluZyBhIGR5bmFtaWMgdmlldyBvZiBnbG9iYWwgdHJlbmRzIGluIGluY29tZSwgbGlmZSBleHBlY3RhbmN5LCBhbmQgcG9wdWxhdGlvbjoNCmBgYHtyLCBjb21tZW50PU5BfQ0KcGFsLklCTSA8LSBjKCIjMzMyMjg4IiwgIiMxMTc3MzMiLCAiIzAwNzJCMiIsIiNENTVFMDAiLCAiIzg4MjI1NSIpDQpwYWwuSUJNIDwtIHNldE5hbWVzKHBhbC5JQk0sIGMoIkFzaWEiLCAiRXVyb3BlIiwgIkFmcmljYSIsICJBbWVyaWNhcyIsICJPY2VhbmlhIikpDQoNCiMgRW5zdXJlIG5vIE5BIHZhbHVlcyBpbiB0aGUgcmVnaW9uIGNvbHVtbg0KZmluYWxfZGF0YSA8LSBmaW5hbF9kYXRhICU+JQ0KICBmaWx0ZXIoIWlzLm5hKHJlZ2lvbikpICAjIFJlbW92ZSByb3dzIHdpdGggTkEgaW4gdGhlIHJlZ2lvbiBjb2x1bW4NCg0KIyBGaWx0ZXIgZGF0YSB0byByZW1vdmUgTkEgdmFsdWVzIGFuZCBjb252ZXJ0IHllYXIgdG8gbnVtZXJpYw0KZmluYWxfZGF0YSR5ZWFyIDwtIGFzLm51bWVyaWMoZ3N1YigiWCIsICIiLCBmaW5hbF9kYXRhJHllYXIpKQ0KZmluYWxfZGF0YSA8LSBmaW5hbF9kYXRhICU+JQ0KICBmaWx0ZXIoIWlzLm5hKGxpZmUuZXhwZWN0YW5jeSkgJiAhaXMubmEoaW5jb21lKSAmICFpcy5uYShwb3B1bGF0aW9uKSkNCg0KZmlnIDwtIGZpbmFsX2RhdGEgJT4lDQogIHBsb3RfbHkoDQogICAgeCA9IH5pbmNvbWUsIA0KICAgIHkgPSB+bGlmZS5leHBlY3RhbmN5LCANCiAgICBzaXplID0gfigyKmxvZyhwb3B1bGF0aW9uKS0xMSleMiwNCiAgICBjb2xvciA9IH5yZWdpb24sIA0KICAgIGNvbG9ycyA9IHBhbC5JQk0sICAgIyBjdXN0b20gY29sb3JzDQogICAgZnJhbWUgPSB+eWVhciwgICAgICAjIHRoZSB0aW1lIHZhcmlhYmxlIHRvDQogICAgdGV4dCA9IH5wYXN0ZSgiQ291bnRyeToiLCBnZW8sDQogICAgICAgICAgICAgICAgICAiPGJyPlJlZ2lvbjoiLCByZWdpb24sDQogICAgICAgICAgICAgICAgICAiPGJyPlllYXI6IiwgeWVhciwNCiAgICAgICAgICAgICAgICAgICI8YnI+TGlmZSBFeHBlY3RhbmN5OiIsIGxpZmUuZXhwZWN0YW5jeSwNCiAgICAgICAgICAgICAgICAgICI8YnI+UG9wdWxhdGlvbjoiLCBwb3B1bGF0aW9uLA0KICAgICAgICAgICAgICAgICAgIjxicj5JbmNvbWUgcGVyIFBlcnNvbjoiLCBpbmNvbWUpLA0KICAgIGhvdmVyaW5mbyA9ICJ0ZXh0IiwNCiAgICB0eXBlID0gJ3NjYXR0ZXInLA0KICAgIG1vZGUgPSAnbWFya2VycycNCiAgKQ0KZmlnIDwtIGZpZyAlPiUgbGF5b3V0KA0KICAgIHhheGlzID0gbGlzdCgNCiAgICAgIHR5cGUgPSAibG9nIg0KICAgICksDQogICAgdGl0bGUgPSAiSW5jb21lIHZzLiBMaWZlIEV4cGVjdGFuY3kgT3ZlciBUaW1lIiwNCiAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiSW5jb21lIHBlciBQZXJzb24gKExvZyBTY2FsZSkiKSwNCiAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiTGlmZSBFeHBlY3RhbmN5IikNCiAgKQ0KDQpmaWcNCmBgYA0KDQpUaGUgeC1heGlzIHJlcHJlc2VudHMgdGhlIGluY29tZSBsZXZlbHMgZm9yIGVhY2ggY291bnRyeSwgd2l0aCBoaWdoZXIgaW5jb21lcyBwb3NpdGlvbmVkIGZ1cnRoZXIgdG8gdGhlIHJpZ2h0LiBUaGUgeS1heGlzIHJlcHJlc2VudHMgbGlmZSBleHBlY3RhbmN5LCB3aXRoIGhpZ2hlciBsaWZlIGV4cGVjdGFuY2llcyBwb3NpdGlvbmVkIGhpZ2hlciBvbiB0aGUgYXhpcy4gRnJvbSB0aGUgcGxvdCwgd2UgY2FuIG9ic2VydmUgdGhhdCBzb21lIGNvdW50cmllcyBkb21pbmF0ZSB0aGUgc2NhdHRlciBwbG90IGR1ZSB0byB0aGVpciBsYXJnZXIgcG9wdWxhdGlvbiBzaXplcyBhbmQgaGlnaGVyIGluY29tZXMuIFRoaXMgdmlzdWFsaXphdGlvbiBhbGxvd3MgdXMgdG8gYW5hbHl6ZSB3aGV0aGVyIGNvdW50cmllcyB3aXRoIGhpZ2hlciBpbmNvbWVzIGdlbmVyYWxseSBoYXZlIGxvbmdlciBsaWZlIGV4cGVjdGFuY2llcy4gQWRkaXRpb25hbGx5LCB3ZSBjYW4gZXhhbWluZSB3aGV0aGVyIHRoZXJlIGlzIGEgY29ycmVsYXRpb24gYmV0d2VlbiBwb3B1bGF0aW9uIHNpemUgYW5kIGluY29tZSBsZXZlbHMsIGhlbHBpbmcgdG8gaWRlbnRpZnkgdHJlbmRzIGFuZCBwYXR0ZXJucyBpbiB0aGUgZGF0YS4NCg0KSW4gdGhlIGFuaW1hdGVkIHBsb3QsIGVhY2ggZnJhbWUgY29ycmVzcG9uZHMgdG8gYSBkaWZmZXJlbnQgeWVhciwgc2hvd2luZyBob3cgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGluY29tZSwgbGlmZSBleHBlY3RhbmN5LCBhbmQgcG9wdWxhdGlvbiBzaXplIGV2b2x2ZXMgb3ZlciB0aW1lLiBUaGUgc2l6ZSBvZiBlYWNoIHBvaW50IGlzIGRldGVybWluZWQgYnkgdGhlIHBvcHVsYXRpb24gb2YgdGhlIGNvdW50cnksIHdpdGggbGFyZ2VyIHBvaW50cyBpbmRpY2F0aW5nIGxhcmdlciBwb3B1bGF0aW9ucy4gVGhlIGNvbG9yIG9mIHRoZSBwb2ludHMgaW5kaWNhdGVzIHRoZSByZWdpb24gdG8gd2hpY2ggdGhlIGNvdW50cnkgYmVsb25ncywgYWxsb3dpbmcgdXMgdG8gc2VlIHJlZ2lvbmFsIHRyZW5kcyBhbmQgZGlmZmVyZW5jZXMgbW9yZSBjbGVhcmx5LiBCeSBvYnNlcnZpbmcgdGhlIGFuaW1hdGlvbiwgd2UgY2FuIGlkZW50aWZ5IGhvdyBlY29ub21pYyBhbmQgaGVhbHRoIG91dGNvbWVzIGhhdmUgY2hhbmdlZCBhY3Jvc3MgZGlmZmVyZW50IHJlZ2lvbnMgYW5kIHRpbWUgcGVyaW9kcywgcHJvdmlkaW5nIGluc2lnaHRzIGludG8gZ2xvYmFsIGRldmVsb3BtZW50IHBhdHRlcm5zLg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K