packages

Be sure to run

pacman::p_load(tidyverse, gapminder, palmerpenguins, janitor, gtsummary, visdat)

Recapitulation

EDA

dim(penguins)
[1] 344   8
summary(penguins)
visdat::vis_dat(penguins)

Data visualizations

Points

bill_length_mm vs bill_depth_mm

penguins %>% 
  ggplot(aes(x = bill_length_mm, 
             y = bill_depth_mm)) +
  geom_point() +
  aes(color = sex)
penguins %>% # my date
  drop_na() %>%  # i will dropn the NA values
  ggplot(aes(x = bill_length_mm, 
             y = bill_depth_mm)) +
  geom_point() + 
  aes(color = sex)
Facetting

One variable continuous

make an histogram with body_mass_g

Two variables continuous

Explore correlations

Two variables continuous vs nominal

body_mass_g by species

Data wrangling

Filter

Asia and 1952

Select

Mutate

1 United States Dollar equals 0.84 Euro

Group

Summarise

gapminder %>% 
  mutate(gpd_in_euros = gdpPercap * 0.84) %>% 
  group_by(continent, year) %>% 
  summarise(meanGdpperCapEur = mean(gpd_in_euros))
`summarise()` regrouping output by 'continent' (override with `.groups` argument)
gapminder %>% 
  mutate(gpd_in_euros = gdpPercap * 0.84) %>% 
  group_by(continent, year) %>% 
  summarise(meanGdpperCapEur = mean(gpd_in_euros)) %>% 
  ggplot(aes(x = year, 
             y = meanGdpperCapEur, 
             color = continent)) + 
  geom_line() +  
  scale_y_log10()
`summarise()` regrouping output by 'continent' (override with `.groups` argument)

Characteristic Adelie, N = 1461 Chinstrap, N = 681 Gentoo, N = 1191
body_mass_g 3,700 (3,362, 4,000) 3,700 (3,488, 3,950) 5,050 (4,700, 5,500)
bill_length_mm 38.8 (36.7, 40.8) 49.5 (46.3, 51.1) 47.4 (45.3, 49.6)
island
Biscoe 44 (30%) 0 (0%) 119 (100%)
Dream 55 (38%) 68 (100%) 0 (0%)
Torgersen 47 (32%) 0 (0%) 0 (0%)

1 Statistics presented: Median (IQR); n (%)

Pivot

unicef <- read_csv("https://bit.ly/unicef-wide")

Longer

Wider

gapminder %>% 
  group_by(continent, year) %>% 
  summarise(LifeExpMean = mean(lifeExp))
`summarise()` regrouping output by 'continent' (override with `.groups` argument)
gapminder %>% 
  group_by(continent, year) %>% 
  summarise(LifeExpMean = mean(lifeExp)) %>% 
  pivot_wider(names_from = year, 
              values_from = LifeExpMean )
`summarise()` regrouping output by 'continent' (override with `.groups` argument)

Join dataset

countries_list <- read_csv("https://datahub.io/JohnSnowLabs/country-and-continent-codes-list/r/country-and-continent-codes-list-csv.csv")

── Column specification ─────────────────────────────────────────────────────────────────
cols(
  Continent_Name = col_character(),
  Continent_Code = col_character(),
  Country_Name = col_character(),
  Two_Letter_Country_Code = col_character(),
  Three_Letter_Country_Code = col_character(),
  Country_Number = col_double()
)
names(unicef)
 [1] "country_name"              "u5mr_1950"                 "u5mr_1951"                
 [4] "u5mr_1952"                 "u5mr_1953"                 "u5mr_1954"                
 [7] "u5mr_1955"                 "u5mr_1956"                 "u5mr_1957"                
[10] "u5mr_1958"                 "u5mr_1959"                 "u5mr_1960"                
[13] "u5mr_1961"                 "u5mr_1962"                 "u5mr_1963"                
[16] "u5mr_1964"                 "u5mr_1965"                 "u5mr_1966"                
[19] "u5mr_1967"                 "u5mr_1968"                 "u5mr_1969"                
[22] "u5mr_1970"                 "u5mr_1971"                 "u5mr_1972"                
[25] "u5mr_1973"                 "u5mr_1974"                 "u5mr_1975"                
[28] "u5mr_1976"                 "u5mr_1977"                 "u5mr_1978"                
[31] "u5mr_1979"                 "u5mr_1980"                 "u5mr_1981"                
[34] "u5mr_1982"                 "u5mr_1983"                 "u5mr_1984"                
[37] "u5mr_1985"                 "u5mr_1986"                 "u5mr_1987"                
[40] "u5mr_1988"                 "u5mr_1989"                 "u5mr_1990"                
[43] "u5mr_1991"                 "u5mr_1992"                 "u5mr_1993"                
[46] "u5mr_1994"                 "u5mr_1995"                 "u5mr_1996"                
[49] "u5mr_1997"                 "u5mr_1998"                 "u5mr_1999"                
[52] "u5mr_2000"                 "u5mr_2001"                 "u5mr_2002"                
[55] "u5mr_2003"                 "u5mr_2004"                 "u5mr_2005"                
[58] "u5mr_2006"                 "u5mr_2007"                 "u5mr_2008"                
[61] "u5mr_2009"                 "u5mr_2010"                 "u5mr_2011"                
[64] "u5mr_2012"                 "u5mr_2013"                 "u5mr_2014"                
[67] "u5mr_2015"                 "Code"                      "Continent_Name"           
[70] "Continent_Code"            "Country_Name"              "Three_Letter_Country_Code"
[73] "Country_Number"           

calculate the mortality rate by continent and year

What is the trend in the mortality rate by continent?

unicef %>% 
  # first reformat from wide to long
  pivot_longer(u5mr_1950:u5mr_2015, 
               names_to = "year", 
               values_to = "value") %>% 
  # select only relevant columns 
  select(continent_name, year, value) %>% 
  # separate the year column 
  separate(year, into = c("delete", "year"), 
           sep = "_") %>% 
  # now delete the delete column 
  select(-delete) %>% 
  # group and summarize
  group_by(continent_name, year) %>% 
  summarise(meanMrtRate5y = mean(value)) %>% 
  ggplot(aes(x = year, 
             y = meanMrtRate5y, 
             color = continent_name)) + 
  geom_point()
`summarise()` regrouping output by 'continent_name' (override with `.groups` argument)

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCiMgcGFja2FnZXMKCgpCZSBzdXJlIHRvIHJ1biAKCnBhY21hbjo6cF9sb2FkKHRpZHl2ZXJzZSwgCiAgICAgICAgICAgICAgIGdhcG1pbmRlciwgCiAgICAgICAgICAgICAgIHBhbG1lcnBlbmd1aW5zLCAKICAgICAgICAgICAgICAgamFuaXRvciwgCiAgICAgICAgICAgICAgIGd0c3VtbWFyeSwgCiAgICAgICAgICAgICAgIHZpc2RhdCkKICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgIApgYGB7cn0KcGFjbWFuOjpwX2xvYWQodGlkeXZlcnNlLCAKICAgICAgICAgICAgICAgZ2FwbWluZGVyLCAKICAgICAgICAgICAgICAgcGFsbWVycGVuZ3VpbnMsIAogICAgICAgICAgICAgICBqYW5pdG9yLCAKICAgICAgICAgICAgICAgZ3RzdW1tYXJ5LCAKICAgICAgICAgICAgICAgdmlzZGF0KQpgYGAKCgojIFJlY2FwaXR1bGF0aW9uCgojIEVEQQoKYGBge3J9CmhlYWQocGVuZ3VpbnMpCmBgYAoKYGBge3J9CmRpbShwZW5ndWlucykKYGBgCmBgYHtyfQpzdW1tYXJ5KHBlbmd1aW5zKQpgYGAKYGBge3J9CnZpc2RhdDo6dmlzX2RhdChwZW5ndWlucykKYGBgCgojIyMgRGF0YSB2aXN1YWxpemF0aW9ucwoKIyMjIyBQb2ludHMKYmlsbF9sZW5ndGhfbW0KdnMgCmJpbGxfZGVwdGhfbW0KCmBgYHtyfQpwZW5ndWlucyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gYmlsbF9sZW5ndGhfbW0sIAogICAgICAgICAgICAgeSA9IGJpbGxfZGVwdGhfbW0pKSArCiAgZ2VvbV9wb2ludCgpCmBgYAoKYGBge3J9CnBlbmd1aW5zICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBiaWxsX2xlbmd0aF9tbSwgCiAgICAgICAgICAgICB5ID0gYmlsbF9kZXB0aF9tbSkpICsKICBnZW9tX3BvaW50KCkgKwogIGFlcyhjb2xvciA9IHNleCkKYGBgCgpgYGB7cn0KcGVuZ3VpbnMgJT4lICMgbXkgZGF0ZQogIGRyb3BfbmEoKSAlPiUgICMgaSB3aWxsIGRyb3BuIHRoZSBOQSB2YWx1ZXMKICBnZ3Bsb3QoYWVzKHggPSBiaWxsX2xlbmd0aF9tbSwgCiAgICAgICAgICAgICB5ID0gYmlsbF9kZXB0aF9tbSkpICsKICBnZW9tX3BvaW50KCkgKyAKICBhZXMoY29sb3IgPSBzZXgpCmBgYAoKIyMjIyMgRmFjZXR0aW5nCgpgYGB7cn0KcGVuZ3VpbnMgJT4lICMgbXkgZGF0ZQogIGRyb3BfbmEoKSAlPiUgICMgaSB3aWxsIGRyb3BuIHRoZSBOQSB2YWx1ZXMKICBnZ3Bsb3QoYWVzKHggPSBiaWxsX2xlbmd0aF9tbSwgCiAgICAgICAgICAgICB5ID0gYmlsbF9kZXB0aF9tbSkpICsKICBnZW9tX3BvaW50KCkgKyAKICBhZXMoY29sb3IgPSBzZXgpICsKICBmYWNldF93cmFwKH5zcGVjaWVzKQpgYGAKYGBge3J9CnBlbmd1aW5zICU+JSAjIG15IGRhdGUKICBkcm9wX25hKCkgJT4lICAjIGkgd2lsbCBkcm9wIHRoZSBOQSB2YWx1ZXMKICBnZ3Bsb3QoYWVzKHggPSBiaWxsX2xlbmd0aF9tbSwgCiAgICAgICAgICAgICB5ID0gYmlsbF9kZXB0aF9tbSkpICsKICBnZW9tX3BvaW50KCkgKyAKICBhZXMoY29sb3IgPSBzZXgpICsKICBmYWNldF9ncmlkKGlzbGFuZCB+IHNwZWNpZXMpCmBgYAoKIyMjIE9uZSB2YXJpYWJsZSBjb250aW51b3VzCm1ha2UgYW4gaGlzdG9ncmFtIHdpdGggYm9keV9tYXNzX2cKCgpgYGB7cn0KcGVuZ3VpbnMgJT4lCiAgZHJvcF9uYSgpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBib2R5X21hc3NfZykpICsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTIpICsKICBmYWNldF9ncmlkKHNwZWNpZXMgfiBzZXgpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCmBgYHtyfQpwYWNtYW46OnBfbG9hZChnZ3RoZW1lcykKYGBgCgpgYGB7cn0KcGVuZ3VpbnMgJT4lCiAgZHJvcF9uYSgpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBib2R5X21hc3NfZykpICsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTIpICsKICBmYWNldF9ncmlkKHNwZWNpZXMgfiBzZXgpICsKICBnZ3B1YnI6OnRoZW1lX3B1YmNsZWFuKCkKYGBgCgoKIyMjIFR3byB2YXJpYWJsZXMgY29udGludW91cwoKYGBge3J9CnBlbmd1aW5zICU+JQogIGRyb3BfbmEoKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBib2R5X21hc3NfZywKICAgICAgICAgICAgIHkgPSBiaWxsX2RlcHRoX21tKSkgKwogIGdlb21fcG9pbnQoKSArCiAgYWVzKGNvbG9yID0gc2V4KSArCiAgZmFjZXRfZ3JpZChzZXggfiBzcGVjaWVzKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKAogICAgdGl0bGUgPSAiQmlsbCB2cyBXZWlnaHQiLCAKICAgIHkgPSAiQmlsIERlcHRoIG1tIiwgCiAgICB4ID0gIkJvZHkgbWFzcyBnIiwgCiAgICBjb2xvciA9ICJTZXgiCiAgKQpgYGAKIyMjIyBFeHBsb3JlIGNvcnJlbGF0aW9ucwoKYGBge3J9CnBlbmd1aW5zICU+JQogIGRyb3BfbmEoKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBib2R5X21hc3NfZywKICAgICAgICAgICAgIHkgPSBiaWxsX2RlcHRoX21tKSkgKwogIGdlb21fcG9pbnQoKSArCiAgYWVzKGNvbG9yID0gc2V4KSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKAogICAgdGl0bGUgPSAiQmlsbCB2cyBXZWlnaHQiLCAKICAgIHkgPSAiQmlsIERlcHRoIG1tIiwgCiAgICB4ID0gIkJvZHkgbWFzcyBnIiwgCiAgICBjb2xvciA9ICJTZXgiCiAgKSArIAogIGdlb21fc21vb3RoKCkKYGBgCiMjIyBUd28gdmFyaWFibGVzIGNvbnRpbnVvdXMgdnMgbm9taW5hbAoKYm9keV9tYXNzX2cgYnkgc3BlY2llcwoKYGBge3J9CnBlbmd1aW5zICU+JSAKICBkcm9wX25hKCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsCiAgICAgICAgICAgICB5ID0gYm9keV9tYXNzX2cpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGFlcyhjb2xvciA9IHNleCkKYGBgCiMjIyBUcmVuZHMKCmBgYHtyfQpnYXBtaW5kZXIKYGBgCmBgYHtyfQpnYXBtaW5kZXIgPC0gZ2FwbWluZGVyOjpnYXBtaW5kZXIKYGBgCgojIERhdGEgd3JhbmdsaW5nCgojIyBGaWx0ZXIKCmBgYHtyfQpnYXBtaW5kZXIgJT4lIAogIGZpbHRlcihjb3VudHJ5ID09ICJHZXJtYW55IiAgKSAKYGBgCmBgYHtyfQpnYXBtaW5kZXIgJT4lIAogIGZpbHRlcihjb250aW5lbnQgPT0gIkV1cm9wZSIgJiB5ZWFyID09IDIwMDcpCmBgYAoKQXNpYSBhbmQgMTk1MgpgYGB7cn0KZ2FwbWluZGVyICU+JSAKICBmaWx0ZXIoY29udGluZW50PT0iQXNpYSIgJiB5ZWFyID09ICIxOTUyIikKYGBgCmBgYHtyfQpnYXBtaW5kZXIgJT4lIAogIGZpbHRlcihjb250aW5lbnQgJWluJSBjKCJBc2lhIiwgIkV1cm9wZSIpICYgeWVhciAlaW4lIGMoMTk1MiwgMjAwMikgKSAKYGBgCgoKYGBge3J9CnNlbGVjdGVkX2NvdW50cmllcyA8LSBjKCJCYWhyYWluIiwgIkFsYmFuaWEiKQpgYGAKCgoKIyMgU2VsZWN0CmBgYHtyfQpnYXBtaW5kZXIgJT4lIAogIHNlbGVjdChjb250aW5lbnQsIAogICAgICAgICBsaWZlRXhwKQpgYGAKYGBge3J9CmdhcG1pbmRlciAlPiUKICBmaWx0ZXIoY291bnRyeSAlaW4lIHNlbGVjdGVkX2NvdW50cmllcykKYGBgCgoKCiMjIE11dGF0ZQoKMSBVbml0ZWQgU3RhdGVzIERvbGxhciBlcXVhbHMgMC44NCBFdXJvCgpgYGB7cn0KZ2FwbWluZGVyICU+JSAKICBtdXRhdGUoZ3BkX2luX2V1cm9zID0gZ2RwUGVyY2FwICogMC44NCkKYGBgCgoKCiMjIEdyb3VwCgpgYGB7cn0KZ2FwbWluZGVyICU+JSAKICBncm91cF9ieShjb250aW5lbnQsIHllYXIpCmBgYAoKCiMjIFN1bW1hcmlzZQpgYGB7cn0KZ2FwbWluZGVyICU+JSAKICBtdXRhdGUoZ3BkX2luX2V1cm9zID0gZ2RwUGVyY2FwICogMC44NCkgJT4lIAogIGdyb3VwX2J5KGNvbnRpbmVudCwgeWVhcikgJT4lIAogIHN1bW1hcmlzZShtZWFuR2RwcGVyQ2FwRXVyID0gbWVhbihncGRfaW5fZXVyb3MpKQpgYGAKYGBge3J9CmdhcG1pbmRlciAlPiUgCiAgbXV0YXRlKGdwZF9pbl9ldXJvcyA9IGdkcFBlcmNhcCAqIDAuODQpICU+JSAKICBncm91cF9ieShjb250aW5lbnQsIHllYXIpICU+JSAKICBzdW1tYXJpc2UobWVhbkdkcHBlckNhcEV1ciA9IG1lYW4oZ3BkX2luX2V1cm9zKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHllYXIsIAogICAgICAgICAgICAgeSA9IG1lYW5HZHBwZXJDYXBFdXIsIAogICAgICAgICAgICAgY29sb3IgPSBjb250aW5lbnQpKSArIAogIGdlb21fbGluZSgpICsgIAogIHNjYWxlX3lfbG9nMTAoKQogCmBgYAoKYGBge3J9CnBlbmd1aW5zICU+JSAKICBkcm9wX25hKCkgJT4lIAogIHNlbGVjdChib2R5X21hc3NfZywgYmlsbF9sZW5ndGhfbW0sIHNwZWNpZXMsIGlzbGFuZCkgJT4lIAogIGd0c3VtbWFyeTo6dGJsX3N1bW1hcnkoYnkgPSBzcGVjaWVzKSAlPiUgCiAgZ3RzdW1tYXJ5Ojpib2xkX2xhYmVscygpCmBgYAoKCgoKCgojIyBQaXZvdAoKCgpgYGB7cn0KdW5pY2VmIDwtIHJlYWRfY3N2KCJodHRwczovL2JpdC5seS91bmljZWYtd2lkZSIpCmBgYAoKCmBgYHtyfQpoZWFkKHVuaWNlZikKYGBgCgpgYGB7cn0KdW5pY2VmIDwtIHVuaWNlZiAlPiUgCiAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKQpgYGAKCgoKIyMjIExvbmdlcgoKYGBge3J9CnVuaWNlZiAlPiUgCiAgcGl2b3RfbG9uZ2VyKHU1bXJfMTk1MDp1NW1yXzIwMTUsIAogICAgICAgICAgICAgICBuYW1lc190byA9ICJ5ZWFyIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ2YWx1ZSIpCmBgYApgYGB7cn0KdW5pY2VmX2xvbmcgPC0gdW5pY2VmICU+JSAKICBwaXZvdF9sb25nZXIodTVtcl8xOTUwOnU1bXJfMjAxNSwgCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInllYXIiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlIikKYGBgCgpgYGB7cn0KdW5pY2VmX2xvbmcKYGBgCgpgYGB7cn0KdW5pY2VmX2xvbmcgPC0gdW5pY2VmX2xvbmcgJT4lCiAgc2VwYXJhdGUoeWVhciwKICAgICAgICAgICBpbnRvID0gYygiZXRjIiwgInllYXIiKSwKICAgICAgICAgICBzZXAgPSAiXyIpICU+JSAKICBzZWxlY3QoLWV0YykKYGBgCgoKYGBge3J9CmhlYWQodW5pY2VmX2xvbmcpCmBgYAoKIyMjIFdpZGVyCmBgYHtyfQpnYXBtaW5kZXIgJT4lIAogIGdyb3VwX2J5KGNvbnRpbmVudCwgeWVhcikgJT4lIAogIHN1bW1hcmlzZShMaWZlRXhwTWVhbiA9IG1lYW4obGlmZUV4cCkpCmBgYApgYGB7cn0KZ2FwbWluZGVyICU+JSAKICBncm91cF9ieShjb250aW5lbnQsIHllYXIpICU+JSAKICBzdW1tYXJpc2UoTGlmZUV4cE1lYW4gPSBtZWFuKGxpZmVFeHApKSAlPiUgCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHllYXIsIAogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gTGlmZUV4cE1lYW4gKQpgYGAKCiMjIEpvaW4gZGF0YXNldAoKYGBge3J9CnVuaWNlZgpgYGAKCgpgYGB7cn0KY291bnRyaWVzX3Nob3J0IDwtIHJlYWRfY3N2KCJodHRwczovL3BrZ3N0b3JlLmRhdGFodWIuaW8vY29yZS9jb3VudHJ5LWxpc3QvZGF0YV9jc3YvZGF0YS9kN2M5ZDdjZmI0MmNiNjlmNDQyMmRlYzIyMmRiYmFhOC9kYXRhX2Nzdi5jc3YiKQoKCmNvdW50cmllc19saXN0IDwtIHJlYWRfY3N2KCJodHRwczovL2RhdGFodWIuaW8vSm9oblNub3dMYWJzL2NvdW50cnktYW5kLWNvbnRpbmVudC1jb2Rlcy1saXN0L3IvY291bnRyeS1hbmQtY29udGluZW50LWNvZGVzLWxpc3QtY3N2LmNzdiIpCmBgYApgYGB7cn0KaGVhZChjb3VudHJpZXNfc2hvcnQpCmBgYAoKCmBgYHtyfQpjb3VudHJpZXNfbGlzdApgYGAKCgoKYGBge3J9CnVuaWNlZgpgYGAKCmBgYHtyfQpsZWZ0X2pvaW4odW5pY2VmLCAKICAgICAgICAgIGNvdW50cmllc19zaG9ydCwgCiAgICAgICAgICBieSA9IGMoImNvdW50cnlfbmFtZSIgPSAiTmFtZSIpKQpgYGAKYGBge3J9CnVuaWNlZiA8LSBsZWZ0X2pvaW4odW5pY2VmLCAKICAgICAgICAgIGNvdW50cmllc19zaG9ydCwgCiAgICAgICAgICBieSA9IGMoImNvdW50cnlfbmFtZSIgPSAiTmFtZSIpKQpgYGAKCmBgYHtyfQpsZWZ0X2pvaW4odW5pY2VmLCAKICAgICAgICAgIGNvdW50cmllc19saXN0LCAKICAgICAgICAgIGJ5ID0gYygiQ29kZSIgPSAiVHdvX0xldHRlcl9Db3VudHJ5X0NvZGUiKSkKYGBgCgpgYGB7cn0KdW5pY2VmIDwtIGxlZnRfam9pbih1bmljZWYsIAogICAgICAgICAgY291bnRyaWVzX2xpc3QsIAogICAgICAgICAgYnkgPSBjKCJDb2RlIiA9ICJUd29fTGV0dGVyX0NvdW50cnlfQ29kZSIpKQpgYGAKCgpgYGB7cn0KbmFtZXModW5pY2VmKQpgYGAKY2FsY3VsYXRlIHRoZSBtb3J0YWxpdHkgcmF0ZSBieSBjb250aW5lbnQgYW5kIHllYXIKCmBgYHtyfQp1bmljZWYKYGBgCgoKV2hhdCBpcyB0aGUgdHJlbmQgaW4gdGhlIG1vcnRhbGl0eSByYXRlIGJ5IGNvbnRpbmVudD8KCmBgYHtyfQp1bmljZWYgJT4lIAogICMgZmlyc3QgcmVmb3JtYXQgZnJvbSB3aWRlIHRvIGxvbmcKICBwaXZvdF9sb25nZXIodTVtcl8xOTUwOnU1bXJfMjAxNSwgCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInllYXIiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlIikgJT4lIAogICMgc2VsZWN0IG9ubHkgcmVsZXZhbnQgY29sdW1ucyAKICBzZWxlY3QoY29udGluZW50X25hbWUsIHllYXIsIHZhbHVlKSAlPiUgCiAgIyBzZXBhcmF0ZSB0aGUgeWVhciBjb2x1bW4gCiAgc2VwYXJhdGUoeWVhciwgaW50byA9IGMoImRlbGV0ZSIsICJ5ZWFyIiksIAogICAgICAgICAgIHNlcCA9ICJfIikgJT4lIAogICMgbm93IGRlbGV0ZSB0aGUgZGVsZXRlIGNvbHVtbiAKICBzZWxlY3QoLWRlbGV0ZSkgJT4lIAogICMgZ3JvdXAgYW5kIHN1bW1hcml6ZQogIGdyb3VwX2J5KGNvbnRpbmVudF9uYW1lLCB5ZWFyKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5NcnRSYXRlNXkgPSBtZWFuKHZhbHVlKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHllYXIsIAogICAgICAgICAgICAgeSA9IG1lYW5NcnRSYXRlNXksIAogICAgICAgICAgICAgY29sb3IgPSBjb250aW5lbnRfbmFtZSkpICsgCiAgZ2VvbV9wb2ludCgpCmBgYAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK