Population Pyramids


R Codes for Collecting Data and Visualization
#==================================================================================
# Scrapping population data with inputs are:
# 1. Given year,
# 2. Country code selected from https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
#==================================================================================
# Clear workspace:
rm(list = ls())
# Load some packages for scrapping data and data manipulation:
library(rvest)
library(magrittr)
library(tidyverse)
# A function for collecting population data:
get_population <- function(countryCode_selected, year_selected) {
base_url <- "https://www.census.gov/data-tools/demo/idb/region.php?N=%20Results%20&T=10&A=separate&RT=0&Y="
link <- paste0(paste0(paste0(base_url, year_selected), "&R=-1&C="), countryCode_selected)
link %>%
read_html() -> html_content
html_content %>%
html_table(fill = TRUE) %>%
.[[1]] -> pop_df
names(pop_df) <- str_replace_all(names(pop_df), " ", "_")
country_name <- html_content %>%
html_nodes('.query_source a') %>%
html_text()
if (length(country_name) == 2) {
country_name <- country_name[2]
}
final_df <- pop_df %>%
select(-Year, -Age, -contains("Percent"), -Sex_Ratio) %>%
mutate_all(function(x) {str_replace_all(x, "[^0-9]", "") %>% as.numeric()}) %>%
mutate(Year = pop_df$Year, Country = country_name[1], Age = pop_df$Age) %>%
select(Year, Country, Age, everything()) %>%
mutate(Percent_Both_Sexes = Both_Sexes_Population / Both_Sexes_Population[1],
Percent_Male = Male_Population / Male_Population[1],
Percent_Female = Female_Population / Female_Population[1],
Sex_Ratio = Male_Population / Female_Population,
Age = case_when(Age == "0-4" ~ "00-04", Age == "5-9" ~ "05-09", TRUE ~ Age))
return(final_df)
}
# Function for getting population data for Vietnam by given year:
pop_data_ByYear <- function(year_selected) {
get_population("VM", year_selected) %>%
slice(-c(1, 20:22)) %>%
select(Year, Age, Male_Population, Female_Population) %>%
mutate(Female_Population = -1*Female_Population) %>%
gather(Gender, Value, -Age, -Year) %>%
return()
}
# Use the function for getting data:
lapply(c(2018, 2005, 2000, 1995), pop_data_ByYear) -> total_list
total_df <- do.call("rbind", total_list)
#=========================
# Data Visualization
#=========================
library(extrafont)
# Colors and font selected:
my_colors <- c("#2E74C0", "#CB454A")
my_font <- "Roboto Condensed"
#---------------------------------
# Version 1: Using geom_col()
#---------------------------------
total_df %>%
ggplot(aes(Age, Value, fill = Gender)) +
geom_col(position = "stack", width = 0.85) +
scale_y_continuous(expand = c(0, 0.5)) +
facet_wrap(~ Year) +
coord_flip() +
scale_y_continuous(breaks = seq(-5000000, 5000000, 1000000),
limits = c(-5000000, 5000000),
labels = c(paste0(seq(5, 0, -1), "M"), paste0(1:5, "M"))) +
theme_minimal() +
scale_fill_manual(values = my_colors, name = "", labels = c("Female", "Male")) +
# guides(fill = guide_legend(reverse = TRUE)) +
theme(panel.grid.major.x = element_line(linetype = "dotted", size = 0.2, color = "grey40")) +
theme(panel.grid.major.y = element_blank()) +
theme(panel.grid.minor.y = element_blank()) +
theme(panel.grid.minor.x = element_blank()) +
theme(legend.position = "top") +
theme(axis.text.y = element_text(size = 10, family = my_font)) +
theme(axis.text.x = element_text(size = 10, family = my_font)) +
theme(plot.title = element_text(family = my_font, size = 28)) +
theme(plot.subtitle = element_text(family = my_font, size = 13, color = "gray40")) +
theme(plot.caption = element_text(family = my_font, size = 12, colour = "grey40", face = "italic")) +
theme(plot.margin = unit(c(1.2, 1.2, 1.2, 1.2), "cm")) +
theme(legend.text = element_text(size = 12, face = "bold", color = "grey30", family = my_font)) +
theme(strip.text = element_text(color = "grey20", size = 13, face = "bold", family = my_font)) +
labs(x = NULL, y = NULL,
title = "Population Pyramids of Vietnam: 1995 - 2018",
subtitle = "The age-sex structure of a country's population and may provide insights about political and social stability,\nas well as economic development. Countries with young populations need to invest more in schools,\nwhile countries with older populations need to invest more in the health sector.",
caption = "Data Source: https://www.census.gov")
#-----------------------------------------
# Version 2: Using geom_linerange()
#-----------------------------------------
total_df %>%
ggplot(aes(x = Age, color = Gender))+
geom_linerange(data = total_df %>% filter(Gender == "Male_Population"),
aes(ymin = -0.3, ymax = -0.3 + Value), size = 3.5, alpha = 1) +
geom_linerange(data = total_df %>% filter(Gender != "Male_Population"),
aes(ymin = 0.3, ymax = 0.3 + Value), size = 3.5, alpha = 1) +
geom_label(aes(x = Age, y = 0, label = Age), inherit.aes = TRUE, family = my_font,
size = 3.5, label.padding = unit(0, "lines"), label.size = 0,
label.r = unit(0.0, "lines"), fill = "#f5f5f2", alpha = 1, color = "gray20") +
theme_minimal() +
coord_flip() +
facet_wrap( ~ Year) +
scale_y_continuous(breaks = seq(-5000000, 5000000, 1000000),
limits = c(-5000000, 5000000),
labels = c(paste0(seq(5, 0, -1), "M"), paste0(1:5, "M"))) +
scale_color_manual(name = "", values = c(Female_Population = "#3E606F", Male_Population = "#8C3F4D"),
labels = c("Male", "Female")) +
theme(panel.grid.major.y = element_blank()) +
theme(plot.title = element_text(face = "bold", size = 28, family = my_font, margin = margin(b = 10), hjust = 0, color = "grey20")) +
theme(plot.subtitle = element_text(size = 14, margin = margin(b = 20), hjust = 0, family = my_font, color = "grey30")) +
theme(plot.caption = element_text(size = 13, color = "grey50", family = my_font)) +
theme(axis.text.y = element_blank()) +
theme(axis.text.x = element_text(size = 12, color = "grey20", family = my_font, face = "bold")) +
theme(plot.background = element_rect(fill = "#EFF2F4", color = NA)) +
theme(panel.grid.major.x = element_line(linetype = "dotted", size = 0.2, color = "grey40")) +
theme(plot.margin = unit(c(1.2, 1.2, 1.2, 1.2), "cm")) +
theme(legend.position = "top") +
theme(legend.text = element_text(size = 13, face = "bold", color = "grey30", family = my_font)) +
theme(legend.text.align = 1) +
theme(strip.text = element_text(color = "grey20", size = 14, face = "bold", family = my_font)) +
# theme(strip.text = element_text(color = "grey20", size = 14, face = "bold", hjust = 0.026) +
labs(x = NULL, y = NULL,
title = "Population Pyramids of Vietnam: 1995 - 2018",
subtitle = "The age-sex structure of a country's population and may provide insights about political and social stability,\nas well as economic development. Countries with young populations need to invest more in schools,\nwhile countries with older populations need to invest more in the health sector.",
caption = "Data Source: https://www.census.gov")
LS0tDQp0aXRsZTogIlBvcHVsYXRpb24gU3RydWN0dXJlIG9mIFZpZXRuYW06IDE5OTUgLSAyMDE4Ig0KYXV0aG9yOiAiTmd1eWVuIENoaSBEdW5nIg0Kc3VidGl0bGU6ICJEYWlseSBHcmFwaCBTZXJpZXMiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgIyBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBoaWdobGlnaHQ6IHplbmJ1cm4NCiAgICB0aGVtZTogZmxhdGx5DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQotLS0NCg0KYGBge3Igc2V0dXAsaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIGZpZy5yZXRpbmE9MikNCmBgYA0KDQojIFBvcHVsYXRpb24gUHlyYW1pZHMNCg0KIVtdKEM6XFxVc2Vyc1xcWmJvb2tcXERlc2t0b3BcXHBpY1xccGlkMS5qcGcpDQoNCiFbXShDOlxcVXNlcnNcXFpib29rXFxEZXNrdG9wXFxwaWNcXHBpZDIuanBnKQ0KDQojIFIgQ29kZXMgZm9yIENvbGxlY3RpbmcgRGF0YSBhbmQgVmlzdWFsaXphdGlvbg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCg0KIz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCiMgICBTY3JhcHBpbmcgcG9wdWxhdGlvbiBkYXRhIHdpdGggaW5wdXRzIGFyZTogDQojICAgMS4gR2l2ZW4geWVhciwgDQojICAgMi4gQ291bnRyeSBjb2RlIHNlbGVjdGVkIGZyb20gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPXzMxNjYtMV9hbHBoYS0yDQojPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KDQojIENsZWFyIHdvcmtzcGFjZTogDQpybShsaXN0ID0gbHMoKSkNCg0KIyBMb2FkIHNvbWUgcGFja2FnZXMgZm9yIHNjcmFwcGluZyBkYXRhIGFuZCBkYXRhIG1hbmlwdWxhdGlvbjogDQpsaWJyYXJ5KHJ2ZXN0KQ0KbGlicmFyeShtYWdyaXR0cikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KDQojIEEgZnVuY3Rpb24gZm9yIGNvbGxlY3RpbmcgcG9wdWxhdGlvbiBkYXRhOiANCg0KZ2V0X3BvcHVsYXRpb24gPC0gZnVuY3Rpb24oY291bnRyeUNvZGVfc2VsZWN0ZWQsIHllYXJfc2VsZWN0ZWQpIHsNCiAgDQogIGJhc2VfdXJsIDwtICJodHRwczovL3d3dy5jZW5zdXMuZ292L2RhdGEtdG9vbHMvZGVtby9pZGIvcmVnaW9uLnBocD9OPSUyMFJlc3VsdHMlMjAmVD0xMCZBPXNlcGFyYXRlJlJUPTAmWT0iDQogIGxpbmsgPC0gcGFzdGUwKHBhc3RlMChwYXN0ZTAoYmFzZV91cmwsIHllYXJfc2VsZWN0ZWQpLCAiJlI9LTEmQz0iKSwgY291bnRyeUNvZGVfc2VsZWN0ZWQpDQogIA0KICBsaW5rICU+JSANCiAgICByZWFkX2h0bWwoKSAtPiBodG1sX2NvbnRlbnQgIA0KICANCiAgaHRtbF9jb250ZW50ICU+JSANCiAgICBodG1sX3RhYmxlKGZpbGwgPSBUUlVFKSAlPiUgDQogICAgLltbMV1dIC0+IHBvcF9kZg0KICANCiAgbmFtZXMocG9wX2RmKSA8LSBzdHJfcmVwbGFjZV9hbGwobmFtZXMocG9wX2RmKSwgIiAiLCAiXyIpDQogIA0KICBjb3VudHJ5X25hbWUgPC0gaHRtbF9jb250ZW50ICU+JSANCiAgICBodG1sX25vZGVzKCcucXVlcnlfc291cmNlIGEnKSAlPiUgDQogICAgaHRtbF90ZXh0KCkgDQogIA0KICBpZiAobGVuZ3RoKGNvdW50cnlfbmFtZSkgPT0gMikgew0KICAgIGNvdW50cnlfbmFtZSA8LSBjb3VudHJ5X25hbWVbMl0NCiAgfQ0KICANCiAgDQogIGZpbmFsX2RmIDwtIHBvcF9kZiAlPiUgDQogICAgc2VsZWN0KC1ZZWFyLCAtQWdlLCAtY29udGFpbnMoIlBlcmNlbnQiKSwgLVNleF9SYXRpbykgJT4lIA0KICAgIG11dGF0ZV9hbGwoZnVuY3Rpb24oeCkge3N0cl9yZXBsYWNlX2FsbCh4LCAiW14wLTldIiwgIiIpICU+JSBhcy5udW1lcmljKCl9KSAlPiUgDQogICAgbXV0YXRlKFllYXIgPSBwb3BfZGYkWWVhciwgQ291bnRyeSA9IGNvdW50cnlfbmFtZVsxXSwgQWdlID0gcG9wX2RmJEFnZSkgJT4lIA0KICAgIHNlbGVjdChZZWFyLCBDb3VudHJ5LCBBZ2UsIGV2ZXJ5dGhpbmcoKSkgJT4lIA0KICAgIG11dGF0ZShQZXJjZW50X0JvdGhfU2V4ZXMgPSBCb3RoX1NleGVzX1BvcHVsYXRpb24gLyBCb3RoX1NleGVzX1BvcHVsYXRpb25bMV0sIA0KICAgICAgICAgICBQZXJjZW50X01hbGUgPSBNYWxlX1BvcHVsYXRpb24gLyBNYWxlX1BvcHVsYXRpb25bMV0sIA0KICAgICAgICAgICBQZXJjZW50X0ZlbWFsZSA9IEZlbWFsZV9Qb3B1bGF0aW9uIC8gRmVtYWxlX1BvcHVsYXRpb25bMV0sIA0KICAgICAgICAgICBTZXhfUmF0aW8gPSBNYWxlX1BvcHVsYXRpb24gLyBGZW1hbGVfUG9wdWxhdGlvbiwgDQogICAgICAgICAgIEFnZSA9IGNhc2Vfd2hlbihBZ2UgPT0gIjAtNCIgfiAiMDAtMDQiLCBBZ2UgPT0gIjUtOSIgfiAiMDUtMDkiLCBUUlVFIH4gQWdlKSkNCiAgDQogIHJldHVybihmaW5hbF9kZikNCiAgDQp9DQoNCg0KIyBGdW5jdGlvbiBmb3IgZ2V0dGluZyBwb3B1bGF0aW9uIGRhdGEgZm9yIFZpZXRuYW0gYnkgZ2l2ZW4geWVhcjogDQoNCnBvcF9kYXRhX0J5WWVhciA8LSBmdW5jdGlvbih5ZWFyX3NlbGVjdGVkKSB7DQogIGdldF9wb3B1bGF0aW9uKCJWTSIsIHllYXJfc2VsZWN0ZWQpICU+JSANCiAgICBzbGljZSgtYygxLCAyMDoyMikpICU+JSANCiAgICBzZWxlY3QoWWVhciwgQWdlLCBNYWxlX1BvcHVsYXRpb24sIEZlbWFsZV9Qb3B1bGF0aW9uKSAlPiUgDQogICAgbXV0YXRlKEZlbWFsZV9Qb3B1bGF0aW9uID0gLTEqRmVtYWxlX1BvcHVsYXRpb24pICU+JSANCiAgICBnYXRoZXIoR2VuZGVyLCBWYWx1ZSwgLUFnZSwgLVllYXIpICU+JSANCiAgICByZXR1cm4oKQ0KfQ0KDQoNCiMgVXNlIHRoZSBmdW5jdGlvbiBmb3IgZ2V0dGluZyBkYXRhOiANCmxhcHBseShjKDIwMTgsIDIwMDUsIDIwMDAsIDE5OTUpLCBwb3BfZGF0YV9CeVllYXIpIC0+IHRvdGFsX2xpc3QNCnRvdGFsX2RmIDwtIGRvLmNhbGwoInJiaW5kIiwgdG90YWxfbGlzdCkNCg0KIz09PT09PT09PT09PT09PT09PT09PT09PT0NCiMgIERhdGEgVmlzdWFsaXphdGlvbg0KIz09PT09PT09PT09PT09PT09PT09PT09PT0NCg0KbGlicmFyeShleHRyYWZvbnQpDQoNCiMgQ29sb3JzIGFuZCBmb250IHNlbGVjdGVkOiANCm15X2NvbG9ycyA8LSBjKCIjMkU3NEMwIiwgIiNDQjQ1NEEiKQ0KbXlfZm9udCA8LSAiUm9ib3RvIENvbmRlbnNlZCINCg0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojICAgVmVyc2lvbiAxOiBVc2luZyBnZW9tX2NvbCgpDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCnRvdGFsX2RmICU+JSANCiAgZ2dwbG90KGFlcyhBZ2UsIFZhbHVlLCBmaWxsID0gR2VuZGVyKSkgKyANCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAic3RhY2siLCB3aWR0aCA9IDAuODUpICsgDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDAuNSkpICsgDQogIGZhY2V0X3dyYXAofiBZZWFyKSArIA0KICBjb29yZF9mbGlwKCkgKyANCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtNTAwMDAwMCwgNTAwMDAwMCwgMTAwMDAwMCksIA0KICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygtNTAwMDAwMCwgNTAwMDAwMCksIA0KICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYyhwYXN0ZTAoc2VxKDUsIDAsIC0xKSwgIk0iKSwgcGFzdGUwKDE6NSwgIk0iKSkpICsgDQogIHRoZW1lX21pbmltYWwoKSArIA0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBteV9jb2xvcnMsIG5hbWUgPSAiIiwgbGFiZWxzID0gYygiRmVtYWxlIiwgIk1hbGUiKSkgKyANCiAgIyBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSkpICsgDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfbGluZShsaW5ldHlwZSA9ICJkb3R0ZWQiLCBzaXplID0gMC4yLCBjb2xvciA9ICJncmV5NDAiKSkgKyANCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArIA0KICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIHRoZW1lKHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsgDQogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgZmFtaWx5ID0gbXlfZm9udCkpICsgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgZmFtaWx5ID0gbXlfZm9udCkpICsgDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gbXlfZm9udCwgc2l6ZSA9IDI4KSkgKyANCiAgdGhlbWUocGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSBteV9mb250LCBzaXplID0gMTMsIGNvbG9yID0gImdyYXk0MCIpKSArIA0KICB0aGVtZShwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gbXlfZm9udCwgc2l6ZSA9IDEyLCBjb2xvdXIgPSAiZ3JleTQwIiwgZmFjZSA9ICJpdGFsaWMiKSkgKyANCiAgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMS4yLCAxLjIsIDEuMiwgMS4yKSwgImNtIikpICsgDQogIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiwgY29sb3IgPSAiZ3JleTMwIiwgZmFtaWx5ID0gbXlfZm9udCkpICsgDQogIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgc2l6ZSA9IDEzLCBmYWNlID0gImJvbGQiLCBmYW1pbHkgPSBteV9mb250KSkgKyAgDQogIGxhYnMoeCA9IE5VTEwsIHkgPSBOVUxMLCANCiAgICAgICB0aXRsZSA9ICJQb3B1bGF0aW9uIFB5cmFtaWRzIG9mIFZpZXRuYW06IDE5OTUgLSAyMDE4IiwNCiAgICAgICBzdWJ0aXRsZSA9ICJUaGUgYWdlLXNleCBzdHJ1Y3R1cmUgb2YgYSBjb3VudHJ5J3MgcG9wdWxhdGlvbiBhbmQgbWF5IHByb3ZpZGUgaW5zaWdodHMgYWJvdXQgcG9saXRpY2FsIGFuZCBzb2NpYWwgc3RhYmlsaXR5LFxuYXMgd2VsbCBhcyBlY29ub21pYyBkZXZlbG9wbWVudC4gQ291bnRyaWVzIHdpdGggeW91bmcgcG9wdWxhdGlvbnMgbmVlZCB0byBpbnZlc3QgbW9yZSBpbiBzY2hvb2xzLFxud2hpbGUgY291bnRyaWVzIHdpdGggb2xkZXIgcG9wdWxhdGlvbnMgbmVlZCB0byBpbnZlc3QgbW9yZSBpbiB0aGUgaGVhbHRoIHNlY3Rvci4iLA0KICAgICAgIGNhcHRpb24gPSAiRGF0YSBTb3VyY2U6IGh0dHBzOi8vd3d3LmNlbnN1cy5nb3YiKQ0KDQoNCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAgIFZlcnNpb24gMjogVXNpbmcgZ2VvbV9saW5lcmFuZ2UoKQ0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCnRvdGFsX2RmICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gQWdlLCBjb2xvciA9IEdlbmRlcikpKw0KICBnZW9tX2xpbmVyYW5nZShkYXRhID0gdG90YWxfZGYgJT4lIGZpbHRlcihHZW5kZXIgPT0gIk1hbGVfUG9wdWxhdGlvbiIpLA0KICAgICAgICAgICAgICAgICBhZXMoeW1pbiA9IC0wLjMsIHltYXggPSAtMC4zICsgVmFsdWUpLCBzaXplID0gMy41LCBhbHBoYSA9IDEpICsNCiAgZ2VvbV9saW5lcmFuZ2UoZGF0YSA9IHRvdGFsX2RmICU+JSBmaWx0ZXIoR2VuZGVyICE9ICJNYWxlX1BvcHVsYXRpb24iKSwgDQogICAgICAgICAgICAgICAgIGFlcyh5bWluID0gMC4zLCB5bWF4ID0gMC4zICsgVmFsdWUpLCBzaXplID0gMy41LCBhbHBoYSA9IDEpICsgDQogIGdlb21fbGFiZWwoYWVzKHggPSBBZ2UsIHkgPSAwLCBsYWJlbCA9IEFnZSksIGluaGVyaXQuYWVzID0gVFJVRSwgZmFtaWx5ID0gbXlfZm9udCwgDQogICAgICAgICAgICAgc2l6ZSA9IDMuNSwgbGFiZWwucGFkZGluZyA9IHVuaXQoMCwgImxpbmVzIiksIGxhYmVsLnNpemUgPSAwLCANCiAgICAgICAgICAgICBsYWJlbC5yID0gdW5pdCgwLjAsICJsaW5lcyIpLCBmaWxsID0gIiNmNWY1ZjIiLCBhbHBoYSA9IDEsIGNvbG9yID0gImdyYXkyMCIpICsgDQogIHRoZW1lX21pbmltYWwoKSArIA0KICBjb29yZF9mbGlwKCkgKyANCiAgZmFjZXRfd3JhcCggfiBZZWFyKSArIA0KICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKC01MDAwMDAwLCA1MDAwMDAwLCAxMDAwMDAwKSwgDQogICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKC01MDAwMDAwLCA1MDAwMDAwKSwgDQogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKHBhc3RlMChzZXEoNSwgMCwgLTEpLCAiTSIpLCBwYXN0ZTAoMTo1LCAiTSIpKSkgKyANCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiIiwgdmFsdWVzID0gYyhGZW1hbGVfUG9wdWxhdGlvbiA9ICIjM0U2MDZGIiwgTWFsZV9Qb3B1bGF0aW9uID0gIiM4QzNGNEQiKSwgDQogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJNYWxlIiwgIkZlbWFsZSIpKSArIA0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDI4LCBmYW1pbHkgPSBteV9mb250LCBtYXJnaW4gPSBtYXJnaW4oYiA9IDEwKSwgaGp1c3QgPSAwLCBjb2xvciA9ICJncmV5MjAiKSkgKyANCiAgdGhlbWUocGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIG1hcmdpbiA9IG1hcmdpbihiID0gMjApLCBoanVzdCA9IDAsIGZhbWlseSA9IG15X2ZvbnQsIGNvbG9yID0gImdyZXkzMCIpKSArIA0KICB0aGVtZShwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEzLCBjb2xvciA9ICJncmV5NTAiLCBmYW1pbHkgPSBteV9mb250KSkgKyANCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgY29sb3IgPSAiZ3JleTIwIiwgZmFtaWx5ID0gbXlfZm9udCwgZmFjZSA9ICJib2xkIikpICsgDQogIHRoZW1lKHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNFRkYyRjQiLCBjb2xvciA9IE5BKSkgKyANCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9saW5lKGxpbmV0eXBlID0gImRvdHRlZCIsIHNpemUgPSAwLjIsIGNvbG9yID0gImdyZXk0MCIpKSArIA0KICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLjIsIDEuMiwgMS4yLCAxLjIpLCAiY20iKSkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsgDQogIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMywgZmFjZSA9ICJib2xkIiwgY29sb3IgPSAiZ3JleTMwIiwgZmFtaWx5ID0gbXlfZm9udCkpICsgDQogIHRoZW1lKGxlZ2VuZC50ZXh0LmFsaWduID0gMSkgKyANCiAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCBzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIsIGZhbWlseSA9IG15X2ZvbnQpKSArIA0KICAjIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuMDI2KSArIA0KICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwgDQogICAgICAgdGl0bGUgPSAiUG9wdWxhdGlvbiBQeXJhbWlkcyBvZiBWaWV0bmFtOiAxOTk1IC0gMjAxOCIsDQogICAgICAgc3VidGl0bGUgPSAiVGhlIGFnZS1zZXggc3RydWN0dXJlIG9mIGEgY291bnRyeSdzIHBvcHVsYXRpb24gYW5kIG1heSBwcm92aWRlIGluc2lnaHRzIGFib3V0IHBvbGl0aWNhbCBhbmQgc29jaWFsIHN0YWJpbGl0eSxcbmFzIHdlbGwgYXMgZWNvbm9taWMgZGV2ZWxvcG1lbnQuIENvdW50cmllcyB3aXRoIHlvdW5nIHBvcHVsYXRpb25zIG5lZWQgdG8gaW52ZXN0IG1vcmUgaW4gc2Nob29scyxcbndoaWxlIGNvdW50cmllcyB3aXRoIG9sZGVyIHBvcHVsYXRpb25zIG5lZWQgdG8gaW52ZXN0IG1vcmUgaW4gdGhlIGhlYWx0aCBzZWN0b3IuIiwNCiAgICAgICBjYXB0aW9uID0gIkRhdGEgU291cmNlOiBodHRwczovL3d3dy5jZW5zdXMuZ292IikNCiAgDQoNCg0KYGBgDQoNCg==