Trabajo elaborado para la asignatura “Programación y manejo de datos en la era del Big Data” de la Universitat de València durante el curso 2021-2022. El repo del trabajo está aquí.

La página web de la asignatura y los trabajos de mis compañeros pueden verse aquí.


Introducción



El Índice de Libertad Económica es elaborado anualmente por la Fundación Heritage y The Wall Street Journal. Su objetivo declarado es medir el nivel de economía de mercado que un país admite. El ranking puntúa datos entre 0 y 100, donde 0 significa «ausencia de libertad económica» y 100 significa «libertad económica total».

Más allá de sus objetivos, está pensado para ayudar a los lectores a realizar un seguimiento de más de dos décadas del avance en la libertad económica, la prosperidad y las oportunidades, y promover estas ideas en sus hogares, escuelas y comunidades. El índice cubre 12 libertades, desde los derechos de propiedad hasta la libertad financiera, en 186 países. En concreto, vamos estudiar el índice para el año 2019, anterior a la pandemia mundial de covid-19.

Proceso de datos

Descargamos los datos aqui. A continuación, situamos los datos en la carpeta datos y realizamos las siguientes modificaciones:

df <- read.csv("./datos/economic_freedom_index2019_data.csv")

#- ponemos las variables en forma numérica

df <- df %>% arrange(desc(X2019.Score)) %>% 
    filter(!X2019.Score == 'N/A')

#seleccionamos las variables que nos interesan

df <- df %>% 
  rename(Score_2019 = "X2019.Score",
         GDP_capita = "GDP.per.Capita..PPP.") %>%
  select(Country, Region, World.Rank, Region.Rank, Score_2019, Property.Rights, Judical.Effectiveness, Government.Integrity, Business.Freedom, Labor.Freedom, Monetary.Freedom, Trade.Freedom, Financial.Freedom, GDP_capita) 

#renombramos paises

df$Country <- recode(df$Country,
                     "Hong Kong SAR" = "Hong Kong",
                     "Czech Republic" = "Czech Rep.",
                     "Korea, South" = "Korea",
                     "Brunei Darussalam" = "Brunei",
                     "Slovak Republic" = "Slovakia",
                     "Cabo Verde" = "Cape Verde",
                     "Kyrgyz Republic" = "Kyrgyzstan",
                     "Bosnia and Herzegovina" = "Bosnia and Herz.",
                     "Dominican Republic" = "Dominican Rep.",
                     "Lao P.D.R." = "Lao PDR",
                     "Solomon Islands" = "Solomon Is.",
                     "São Tomé and Príncipe" = "São Tomé and Principe",
                     "Burma" = "Myanmar",
                     "Macau" = "Macao",
                     "Taiwan" = "Taiwan",
                     "Saint Vincent and the Grenadines" = "St. Vin. and Gren.",
                     "Congo, Democratic Republic of the Congo" = "Dem. Rep. Congo",
                     "Korea, North" = "Dem. Rep. Korea",
                     "Central African Republic" = "Central African Rep.",
                     "Equatorial Guinea" = "Eq. Guinea",
                     "Congo, Republic of" = "Congo",
                     "Eswatini" = "Swaziland")

df$GDP_capita <- recode(df$GDP_capita,
                              "$1,700 (2015 est.)" = "$1,700")

#Eliminamos el simbolo del dólar 

df <- df %>% mutate(GDP_capita = str_replace(GDP_capita, "\\$", "" ))

#Eliminamos las comas para pasarlo a numerico y las remplazamos por puntos

df <- df %>% mutate(GDP_capita = str_replace(GDP_capita, ",", "" ))

df <- transform(df, Score_2019 = as.numeric(Score_2019),
                Property.Rights = as.numeric(Property.Rights),
                Judical.Effectiveness = as.numeric(Judical.Effectiveness),
                Labor.Freedom = as.numeric(Labor.Freedom),
                Financial.Freedom = as.numeric(Financial.Freedom),
                GDP_capita = as.numeric(GDP_capita))

#.eliminamos los países que no tienen puntuacion

df <- df %>% arrange(desc(Score_2019)) %>% 
    filter(!Score_2019 == 'N/A')

#añadimos el siguiente comentario

df <- df %>%
  mutate(Grado_libertad = case_when( 
    Score_2019 > 80 ~ "Libre",
    Score_2019 > 70 & Score_2019 < 80   ~ "Generalmente libre",
    Score_2019 > 60 & Score_2019 < 70   ~ "Moderadamente libre" , 
    Score_2019 > 50 & Score_2019 < 60   ~ "Generalmente autoritario",
    Score_2019 < 50 ~ "Autoritario"))

df <- df %>%
   select(Country, Region, World.Rank, Region.Rank, Score_2019, Grado_libertad, Property.Rights, Judical.Effectiveness, Government.Integrity, Business.Freedom, Labor.Freedom, Monetary.Freedom, Trade.Freedom, Financial.Freedom, GDP_capita)

En esta tabla se puede observar y buscar cualquier elemento del data frame:

DT::datatable(df)

Análisis de las puntuaciones por países

Vamos a analizar los 20 países con mayor y menor puntuación puntuación en el índice.

En primer lugar, el top 20 son países desarrollados, con unas instituciones democrátricas consolidadas que favorecen el crecimiento económico. En segundo lugar, el top 20 con menor puntuación son países cuyas instituciones son realmente poco beneficiosas para el crecimiento. La gran mayoría son países totalitarios que presentan una elevada corrupción.

Top 20 mayor puntuación

# top 20
df_20 <- df %>%
  group_by(Country) %>%
  ungroup() %>%
  slice_max(Score_2019, n = 20)

#Convertirmos a factor la columna Razón
df_20$Country <- factor(df_20$Country,levels = df_20$Country)

p1 <- ggplot(df_20, aes(y = fct_rev(Country),
                  x = Score_2019)) +
  geom_col(fill = "#2A759F") +
  geom_text(aes(label = Score_2019), hjust = -0.15,size = 3.25) +
  scale_x_continuous(breaks = seq(0, 100, 30), limits = c(0, 100)) +
  labs(title = "Índice de libertad económica",
       subtitle = "Top 20, año 2019",
       y = "Puntuación", x = "País") +
  theme_classic()
p1

Wordcloud

df_1 <- df %>%
  select(Country, Score_2019)

df_1$Country <- recode(df_1$Country, 
                     "United States"="USA",
        "Hong Kong" = "HK",
        "United Kingdom" = "UK",
        "United Arab Emirates" = "EAU")

wordcloud2(data = df_1, shape = "circle", size = 0.3)

Otra forma de visualizar los datos

df_5 <- df %>%
  group_by(Country) %>%
  ungroup() %>%
  slice_max(Score_2019, n = 5)

p2 <- treemap(df_5,
            index = "Country",
            vSize ="Score_2019",
            type = "index",
            palette = "Set2",
            (col2rgb(bg.labels = c("white"), silent = TRUE)),
            align.labels= list(c("center", "center"),
                               c("right", "bottom")),
            title = "Top 5 con mayor índice de libertad económica")
p2
#> $tm
#>       Country vSize vColor stdErr vColorValue level        x0        y0
#> 1   Australia  80.9      1   80.9          NA     1 0.4208060 0.0000000
#> 2   Hong Kong  90.2      1   90.2          NA     1 0.0000000 0.4977728
#> 3 New Zealand  84.4      1   84.4          NA     1 0.4208060 0.3272654
#> 4   Singapore  89.4      1   89.4          NA     1 0.0000000 0.0000000
#> 5 Switzerland  81.9      1   81.9          NA     1 0.7147565 0.3272654
#>           w         h   color
#> 1 0.5791940 0.3272654 #66C2A5
#> 2 0.4208060 0.5022272 #FC8D62
#> 3 0.2939505 0.6727346 #8DA0CB
#> 4 0.4208060 0.4977728 #E78AC3
#> 5 0.2852435 0.6727346 #A6D854
#> 
#> $type
#> [1] "index"
#> 
#> $vSize
#> [1] "Score_2019"
#> 
#> $vColor
#> [1] NA
#> 
#> $stdErr
#> [1] "Score_2019"
#> 
#> $algorithm
#> [1] "pivotSize"
#> 
#> $vpCoorX
#> [1] 0.02812148 0.97187852
#> 
#> $vpCoorY
#> [1] 0.02239057 0.89798858
#> 
#> $aspRatio
#> [1] 1.716375
#> 
#> $range
#> [1] NA
#> 
#> $mapping
#> [1] NA NA NA
#> 
#> $draw
#> [1] TRUE

Tabla

df_20 <- df %>%
  slice_max(Score_2019, n = 20) %>%
  select(Country, Region, World.Rank, Region.Rank, Score_2019, Grado_libertad) %>%
  rename("País" = Country, "Región" = Region, "Ranking" = World.Rank, "Ranking regional" = Region.Rank, "Puntuación" = Score_2019, "Grado de libertad" = Grado_libertad)

gt_20 <- gt(df_20) %>% 
  tab_header(title = md("**Top 20 países con mayor libertad económica**"),
             subtitle = "en 2019")

gt_20
Top 20 países con mayor libertad económica
en 2019
País Región Ranking Ranking regional Puntuación Grado de libertad
Hong Kong Asia-Pacific 1 1 90.2 Libre
Singapore Asia-Pacific 2 2 89.4 Libre
New Zealand Asia-Pacific 3 3 84.4 Libre
Switzerland Europe 4 1 81.9 Libre
Australia Asia-Pacific 5 4 80.9 Libre
Ireland Europe 6 2 80.5 Libre
United Kingdom Europe 7 3 78.9 Generalmente libre
Canada Americas 8 1 77.7 Generalmente libre
United Arab Emirates Middle East and North Africa 9 1 77.6 Generalmente libre
Taiwan Asia-Pacific 10 5 77.3 Generalmente libre
Iceland Europe 11 4 77.1 Generalmente libre
Netherlands Europe 13 5 76.8 Generalmente libre
United States Americas 12 2 76.8 Generalmente libre
Denmark Europe 14 6 76.7 Generalmente libre
Estonia Europe 15 7 76.6 Generalmente libre
Georgia Europe 16 8 75.9 Generalmente libre
Luxembourg Europe 17 9 75.9 Generalmente libre
Chile Americas 18 3 75.4 Generalmente libre
Sweden Europe 19 10 75.2 Generalmente libre
Finland Europe 20 11 74.9 Generalmente libre

Top 20 menor puntuación

# top 20
df_min <- df %>%
  group_by(Country) %>%
  ungroup() %>%
  slice_min(Score_2019, n = 20)

#Convertirmos a factor la columna Razón
df_min$Country <- factor(df_min$Country,levels = df_min$Country)

p3 <- ggplot(df_min, aes(y = fct_rev(Country),
                  x = Score_2019)) +
  geom_col(fill = "#2A759F") +
  geom_text(aes(label = Score_2019), hjust = -0.15,size = 3.25) +
  scale_x_continuous(breaks = seq(0, 100, 30), limits = c(0, 100)) +
  labs(title = "Índice de libertad económica",
       subtitle = "Top 20 con menor puntuación, año 2019",
       y = "Puntuación", x = "País") +
  theme_classic()
p3

Otra forma de visualizar los datos

df_min_5 <- df %>%
  group_by(Country) %>%
  ungroup() %>%
  slice_min(Score_2019, n = 5)

p4 <- treemap(df_min_5,
            index = "Country",
            vSize ="Score_2019",
            type = "index",
            palette = "Set2",
            (col2rgb(bg.labels = c("white"), silent = TRUE)),
            align.labels= list(c("center", "center"),
                               c("right", "bottom")),
            title = "Top 5 con menor índice de libertad económica")
p4
#> $tm
#>         Country vSize vColor stdErr vColorValue level        x0        y0
#> 1         Congo  39.7      1   39.7          NA     1 0.0000000 0.4949109
#> 2          Cuba  27.8      1   27.8          NA     1 0.5687410 0.5335570
#> 3       Eritrea  38.9      1   38.9          NA     1 0.0000000 0.0000000
#> 4 Korea, North    5.9      1    5.9          NA     1 0.9199865 0.0000000
#> 5     Venezuela  25.9      1   25.9          NA     1 0.5687410 0.0000000
#>            w         h   color
#> 1 0.56874096 0.5050891 #66C2A5
#> 2 0.43125904 0.4664430 #FC8D62
#> 3 0.56874096 0.4949109 #8DA0CB
#> 4 0.08001347 0.5335570 #E78AC3
#> 5 0.35124557 0.5335570 #A6D854
#> 
#> $type
#> [1] "index"
#> 
#> $vSize
#> [1] "Score_2019"
#> 
#> $vColor
#> [1] NA
#> 
#> $stdErr
#> [1] "Score_2019"
#> 
#> $algorithm
#> [1] "pivotSize"
#> 
#> $vpCoorX
#> [1] 0.02812148 0.97187852
#> 
#> $vpCoorY
#> [1] 0.02239057 0.89798858
#> 
#> $aspRatio
#> [1] 1.716375
#> 
#> $range
#> [1] NA
#> 
#> $mapping
#> [1] NA NA NA
#> 
#> $draw
#> [1] TRUE

Tabla

df_min <- df %>%
  slice_min(Score_2019, n = 20) %>%
  select(Country, Region, World.Rank, Region.Rank, Score_2019, Grado_libertad) %>%
  rename("País" = Country, "Región" = Region, "Ranking" = World.Rank, "Ranking regional" = Region.Rank, "Puntuación" = Score_2019, "Grado de libertad" = Grado_libertad)

gt_min <- gt(df_min) %>% 
  tab_header(title = md("**Top 20 países con menor libertad económica**"),
             subtitle = "en 2019")

gt_min
Top 20 países con menor libertad económica
en 2019
País Región Ranking Ranking regional Puntuación Grado de libertad
Korea, North Asia-Pacific 180 43 5.9 Autoritario
Venezuela Americas 179 32 25.9 Autoritario
Cuba Americas 178 31 27.8 Autoritario
Eritrea Sub-Saharan Africa 177 47 38.9 Autoritario
Congo Sub-Saharan Africa 176 46 39.7 Autoritario
Zimbabwe Sub-Saharan Africa 175 45 40.4 Autoritario
Eq. Guinea Sub-Saharan Africa 174 44 41.0 Autoritario
Bolivia Americas 173 30 42.3 Autoritario
Timor-Leste Asia-Pacific 172 42 44.2 Autoritario
Algeria Middle East and North Africa 171 14 46.2 Autoritario
Ecuador Americas 170 29 46.9 Autoritario
Djibouti Sub-Saharan Africa 169 43 47.1 Autoritario
Kiribati Asia-Pacific 168 41 47.3 Autoritario
Sierra Leone Sub-Saharan Africa 167 42 47.5 Autoritario
Sudan Sub-Saharan Africa 166 41 47.7 Autoritario
Suriname Americas 165 28 48.1 Autoritario
Turkmenistan Asia-Pacific 164 40 48.4 Autoritario
Mozambique Sub-Saharan Africa 163 40 48.6 Autoritario
Burundi Sub-Saharan Africa 162 39 48.9 Autoritario
Central African Rep. Sub-Saharan Africa 161 38 49.1 Autoritario

Análisis de los diferentes componentes del índice

Vamos a llevar a cabo un análisis de algunos de los componentes que considero que son importantes a la hora de explicar el grado de libertad de los países.

Derechos de propiedad

Gráfico

df_comp <- df %>%
  select(!GDP_capita)

df_prop <- df_comp %>%
  select(Country, Region, World.Rank, Region.Rank, Property.Rights)

df_prop1 <- df_prop %>%
  slice_max(Property.Rights, n = 10) %>%
  select(Country, Region, World.Rank, Region.Rank, Property.Rights)

df_prop2 <- df_prop %>%
  slice_min(Property.Rights, n = 5) %>%
  arrange(desc(Property.Rights)) %>%
  select(Country, Region, World.Rank, Region.Rank, Property.Rights)

#Convertirmos a factor la columna Razón
df_prop1$Country <- factor(df_prop1$Country,levels = df_prop1$Country)

ggplot(df_prop1, aes(y = fct_rev(Country), 
                     x = Property.Rights)) +
  geom_col(fill = "#2A759F", position = position_stack(reverse = TRUE)) +
  geom_text(aes(label = Property.Rights), hjust = -0.15, size = 3.25) +
  scale_x_continuous(breaks = seq(0, 100, 30), limits = c(0, 100)) +
  labs(title = "Top 10 paises con mejores derechos de propiedad",
       subtitle = "en 2019",
       x = "Puntuación derechos de propiedad",
       y = "Países") +
  theme(axis.text.x = element_text(angle = 30)) +
  theme_classic()

Tabla

df_prop1 <- df_prop %>%
  slice_max(Property.Rights, n = 10) %>%
  select(Country, Region, World.Rank, Region.Rank, Property.Rights) %>%
  rename("País" = Country, "Región" = Region, "Ranking mundial" = World.Rank, "Ranking regional" = Region.Rank, "Derechos de propiedad" = Property.Rights)


knitr::kable(df_prop1, 
             align = "c", 
             caption = "Top 10 paises con mejores derechos de propiedad",
             digits = 2) %>%
  kableExtra::kable_styling(fixed_thead = list(enabled = T, 
                                               background = "white")) %>%
  column_spec(1, background = "white")
Top 10 paises con mejores derechos de propiedad
País Región Ranking mundial Ranking regional Derechos de propiedad
Singapore Asia-Pacific 2 2 97.4
New Zealand Asia-Pacific 3 3 95.0
Hong Kong Asia-Pacific 1 1 93.3
United Kingdom Europe 7 3 92.3
Finland Europe 20 11 89.6
Sweden Europe 19 10 89.5
Netherlands Europe 13 5 88.0
Iceland Europe 11 4 87.4
Canada Americas 8 1 87.0
Denmark Europe 14 6 86.2

Efectividad judicial

Gráfico

df_jud <- df_comp %>%
  select(Country, Region, World.Rank, Region.Rank, Judical.Effectiveness)

df_jud1 <- df_jud %>%
  slice_max(Judical.Effectiveness, n = 10) %>%
  select(Country, Region, World.Rank, Region.Rank, Judical.Effectiveness)

#Convertirmos a factor la columna Razón
df_jud1$Country<-factor(df_jud1$Country, levels = df_jud1$Country)

my_10 <- c('#9e0142','#d53e4f','#f46d43','#fdae61','#fee08b','#e6f598','#abdda4','#66c2a5','#3288bd','#5e4fa2')

ggplot(df_jud1, aes(y = fct_rev(Country), x = Judical.Effectiveness)) +
  geom_col(fill = my_10) +
  geom_text(aes(label = Judical.Effectiveness), hjust = -0.15, size = 3.25) +
  scale_fill_manual(values = my_10) +
  scale_x_continuous(breaks = seq(0, 100, 30), limits = c(0, 100)) +
  labs(title = "Top 10 paises con mejor efectividad judicial",
       subtitle = "en 2019",
       x = "Puntuación en efectividad judicial",
       y = "Países") +
  theme_classic() +
  theme(axis.text.x = element_text(angle =30))

Tabla

df_jud1 <- df_jud %>%
  slice_max(Judical.Effectiveness, n = 10) %>%
  select(Country, Region, World.Rank, Region.Rank, Judical.Effectiveness) %>%
  rename("País" = Country, "Región" = Region, "Ranking mundial" = World.Rank, "Ranking regional" = Region.Rank, "Efectividad judicial" = Judical.Effectiveness)


knitr::kable(df_jud1, 
             align = "c", 
             caption = "Top 10 paises con mayor efectividad judicial",
             digits = 2) %>%
  kableExtra::kable_styling(fixed_thead = list(enabled = T, 
                                               background = "white")) %>%
  column_spec(1, background = "white")
Top 10 paises con mayor efectividad judicial
País Región Ranking mundial Ranking regional Efectividad judicial
Singapore Asia-Pacific 2 2 92.4
United Arab Emirates Middle East and North Africa 9 1 87.1
Australia Asia-Pacific 5 4 86.5
United Kingdom Europe 7 3 85.9
Sweden Europe 19 10 84.0
New Zealand Asia-Pacific 3 3 83.5
Rwanda Sub-Saharan Africa 32 2 83.2
Switzerland Europe 4 1 82.0
Finland Europe 20 11 81.2
Norway Europe 26 15 81.2

Libertad laboral

Entran en juego paises africanos como Namibia o Nigeria. También Estados Unidos, de los pocos países occidentales en mantener su tradicional flexibilidad laboral, asunto muy criticado por los países europeos, que han impuesto una mayor rigidez (salarios mínimos, mayores indemnizaciones por despido, etc) desde los años 70 y que explicaron el período de histéresis cuyos efectos incluso aún perduran. Es por ello que solo vemos a un país europeo en el top 10.

Gráfico

df_lab <- df_comp %>%
  select(Country, Region, World.Rank, Region.Rank, Labor.Freedom)

df_lab1 <- df_lab %>%
  slice_max(Labor.Freedom, n = 10) %>%
  select(Country, Region, World.Rank, Region.Rank, Labor.Freedom)

#Convertirmos a factor la columna Razón
df_lab1$Country<-factor(df_lab1$Country, levels = df_lab1$Country)

ggplot(df_lab1, aes(y = fct_rev(Country), x = Labor.Freedom)) +
  geom_col(fill = "#2A759F") +
  geom_text(aes(label = Labor.Freedom), hjust = -0.15, size = 3.25) +
  scale_x_continuous(breaks = seq(0, 100, 20), limits = c(0, 100)) +
  labs(title = "Top 10 paises con mayor libertad laboral",
       subtitle = "en 2019",
       x = "Puntuación en libertad laboral",
       y = "Países") +
  theme_classic() +
  theme(axis.text.x = element_text(angle =30))

Tabla

df_lab1 <- df_lab %>%
  slice_max(Labor.Freedom, n = 10) %>%
  select(Country, Region, World.Rank, Region.Rank, Labor.Freedom) %>%
  rename("País" = Country, "Región" = Region, "Ranking mundial" = World.Rank, "Ranking regional" = Region.Rank, "Libertad laboral" = Labor.Freedom)


knitr::kable(df_lab1, 
             align = "c", 
             caption = "Top 10 paises con mayor libertad laboral",
             digits = 2) %>%
  kableExtra::kable_styling(fixed_thead = list(enabled = T, 
                                               background = "white")) %>%
  column_spec(1, background = "white")
Top 10 paises con mayor libertad laboral
País Región Ranking mundial Ranking regional Libertad laboral
Singapore Asia-Pacific 2 2 91.0
Brunei Asia-Pacific 63 14 90.8
United States Americas 12 2 89.4
Hong Kong Asia-Pacific 1 1 89.2
New Zealand Asia-Pacific 3 3 86.7
Denmark Europe 14 6 86.4
Kazakhstan Asia-Pacific 59 12 86.2
Namibia Sub-Saharan Africa 99 10 85.1
Australia Asia-Pacific 5 4 84.1
Nigeria Sub-Saharan Africa 111 14 83.3

Libertad financiera

Según la economía keynesiana, una mayor libertad financiera, y por tanto, una menor desregularización puede llevar consigo la mayor probabilidad de crisis financieras. Con la era liberal de los años 80, comenzó un proceso liberalizador de las finanzas, cuyo foco principal fue Estados Unidos y Reino Unido. Muchos economistas afirman que este proceso conllevo a la crisis financiera de 2007. Este hecho hizo que a posteriori la regularización se implementara en mayor medida.

Gráfico

df_fin <- df_comp %>%
  select(Country, Region, World.Rank, Region.Rank, Financial.Freedom)

df_fin1 <- df_fin %>%
  slice_max(Financial.Freedom, n = 10) %>%
  select(Country, Region, World.Rank, Region.Rank, Financial.Freedom)

#Convertirmos a factor la columna Razón
df_fin1$Country<-factor(df_fin1$Country, levels = df_fin1$Country)

ggplot(df_fin1, aes(y = fct_rev(Country), x = Financial.Freedom)) +
  geom_col(fill = "#2A759F") +
  geom_text(aes(label = Financial.Freedom), hjust = -0.15, size = 3.25) +
  scale_x_continuous(breaks = seq(0, 100, 20), limits = c(0, 100)) +
  labs(title = "Top 10 paises con mayor libertad financiera",
       subtitle = "en 2019",
       x = "Puntuación en libertad financiera",
       y = "Países") +
  theme(axis.text.x = element_text(angle =30)) + 
  theme_classic()

Tabla

df_fin1 <- df_fin %>%
  slice_max(Financial.Freedom, n = 10) %>%
  select(Country, Region, World.Rank, Region.Rank, Financial.Freedom) %>%
  rename("País" = Country, "Región" = Region, "Ranking mundial" = World.Rank, "Ranking regional" = Region.Rank, "Libertad financiera" = Financial.Freedom)


knitr::kable(df_fin1, 
             align = "c", 
             caption = "Top 10 paises con mayor libertad financiera",
             digits = 2) %>%
  kableExtra::kable_styling(fixed_thead = list(enabled = T, 
                                               background = "white")) %>%
  column_spec(1, background = "white")
Top 10 paises con mayor libertad financiera
País Región Ranking mundial Ranking regional Libertad financiera
Hong Kong Asia-Pacific 1 1 90
Switzerland Europe 4 1 90
Australia Asia-Pacific 5 4 90
Singapore Asia-Pacific 2 2 80
New Zealand Asia-Pacific 3 3 80
United Kingdom Europe 7 3 80
Canada Americas 8 1 80
Netherlands Europe 13 5 80
United States Americas 12 2 80
Denmark Europe 14 6 80
Luxembourg Europe 17 9 80
Sweden Europe 19 10 80
Finland Europe 20 11 80
Czech Rep.  Europe 23 13 80
Bahrain Middle East and North Africa 54 5 80

Análisis de los paises por regiones

Vemos que la región con mayor libertad económica, y por tanto, con mayor media en este índice es Europa.

La Fundación Heritage informa que el 20% superior en el índice tiene el doble del ingreso per cápita que aquellos en el segundo quintil, y cinco veces el del 20% inferior.

Gráfico

# Cogemos el top 5 de cada región

df_max <- df %>%
  group_by(Region) %>%
  slice_max(Score_2019, n = 5) %>%
  select(Country, Region, Region.Rank, Score_2019, Grado_libertad)

df_max$Country<-factor(df_max$Country, levels = df_max$Country)

my_colors <- c('#e41a1c','#377eb8','#4daf4a','#984ea3','#ff7f00')

h <- ggplot(df_max, aes(y = fct_rev(Country), 
                         x = Score_2019,
                         fill = Region)) + 
  geom_col() +
  scale_fill_manual(values = my_colors) +
  scale_x_continuous(breaks = seq(0, 100, 20), limits = c(0, 100)) +
  labs(title = "Índice de libertad económica por regiones",
       subtitle = "Top 5 por region",
       y = "País",
       x = "Puntuación en 2019") +
  theme_classic()

h

Tabla

df_max <- df %>%
  group_by(Region) %>%
  slice_max(Score_2019, n = 5) %>%
  select(Country, Region, Region.Rank, Score_2019, Grado_libertad) %>%
  rename("País" = Country, "Región" = Region, "Ranking regional" = Region.Rank, "Puntuación" = Score_2019, "Grado de libertad" = Grado_libertad)

gt_max<- gt(df_max) %>% 
  tab_header(title = md("**Top 5 por regiones**"),
             subtitle = "en 2019") 

gt_max
Top 5 por regiones
en 2019
País Ranking regional Puntuación Grado de libertad
Americas
Canada 1 77.7 Generalmente libre
United States 2 76.8 Generalmente libre
Chile 3 75.4 Generalmente libre
Saint Lucia 4 68.7 Moderadamente libre
Jamaica 5 68.6 Moderadamente libre
Uruguay 6 68.6 Moderadamente libre
Asia-Pacific
Hong Kong 1 90.2 Libre
Singapore 2 89.4 Libre
New Zealand 3 84.4 Libre
Australia 4 80.9 Libre
Taiwan 5 77.3 Generalmente libre
Europe
Switzerland 1 81.9 Libre
Ireland 2 80.5 Libre
United Kingdom 3 78.9 Generalmente libre
Iceland 4 77.1 Generalmente libre
Netherlands 5 76.8 Generalmente libre
Middle East and North Africa
United Arab Emirates 1 77.6 Generalmente libre
Israel 2 72.8 Generalmente libre
Qatar 3 72.6 Generalmente libre
Jordan 4 66.5 Moderadamente libre
Bahrain 5 66.4 Moderadamente libre
Sub-Saharan Africa
Mauritius 1 73.0 Generalmente libre
Rwanda 2 71.1 Generalmente libre
Botswana 3 69.5 Moderadamente libre
Cape Verde 4 63.1 Moderadamente libre
Côte d'Ivoire 5 62.4 Moderadamente libre

Box-plot

my_palette <- c('#1b9e77','#d95f02','#7570b3','#e7298a','#66a61e')

df_regiones <- df %>%
  group_by(Region) %>%
  select(Country, Region, Region.Rank, Score_2019, Grado_libertad)


p5 <- ggplot(df_regiones, aes(x = Region,
                              y = Score_2019,
                              fill = Region)) +
  geom_boxplot() +
  geom_jitter(width = 0.15, alpha = 0.2, color = "tomato") +
  scale_fill_manual(values = my_palette) +
  scale_y_continuous(breaks = seq(0, 100, 20), limits = c(0, 100)) +
  coord_flip() +
  labs(title = "Puntuación por regiones",
       subtitle = "en 2019",
       x = "Región",
       y = "Puntuación") +
  theme_classic() +
  theme(legend.position = "none",
       panel.background = element_rect(fill = NA)) 

p5

Mapa

world <- ne_countries(scale = "medium", returnclass = "sf")
world <- world %>% filter(subregion != "Antarctica") %>% filter(admin != "Greenland")
world <- world %>% select(name, iso_a3, geometry)

df_join <- left_join (df, world, by = c("Country" = "name"))

df_world <- df_join %>%
  mutate(Score_2019_5 = ntile(Score_2019, 5)) %>%
  select(Country, Region, World.Rank, Region.Rank, Score_2019, Score_2019_5, geometry)

gg <- ggplot(df_world, aes(fill = Score_2019, geometry = geometry)) +
  geom_sf() +
  scale_fill_gradient("Puntuación", high = "#993404", low = "#ffffd4", breaks = seq(20,100, 20), limits = c(20,100)) + 
  labs(title = "Índice de libertad económica",
       subtitle = "en 2019",
       caption = "Los paises en blanco no tienen datos")  + 
  theme(panel.background = element_rect(fill = NA),
        legend.text = element_text(face = "italic"),
        legend.title = element_text(face = "italic"),
        legend.position = "bottom", 
        legend.direction = "horizontal",
        axis.ticks = element_line(linetype = "blank"),
        axis.text = element_text(colour = "white"))

gg

Media regional

df_reg <- df %>%
  group_by(Region) %>%
  summarise(Media = mean(Score_2019)) %>%
  arrange(desc(Media)) %>%
  select(Region, Media)

gt_reg <- gt(df_reg) %>% 
  tab_header(title = md("**Puntuación media regional en el índice de libertad económica**"),
             subtitle = "en 2019") 

gt_reg
Puntuación media regional en el índice de libertad económica
en 2019
Region Media
Europe 68.62727
Middle East and North Africa 61.25714
Asia-Pacific 60.63488
Americas 59.60000
Sub-Saharan Africa 54.18298

Puntuación y PIB per cápita

La Fundación Heritage informa que el 20% superior en el índice tiene el doble del ingreso per cápita que aquellos en el segundo quintil, y cinco veces el del 20% inferior, por lo tanto hay una correlación positiva entre libertad económica y desarrollo. Queremos comprobar esto.

Se puede observar que los países con mayor libertad económica tienen un mayor PIB per cápita en términos medios, excepto para el caso de la región de Oriente Medio y Norte de África, que poseen más PIB per cápita que los países europeos, por el negocio del petróleo.

Gráfico

df <- df

f <- ggplot(df, aes(GDP_capita,
               Score_2019,
               alpha = 0.5)) +
  geom_point(aes(color = Country)) +
  geom_smooth(formula = y ~ x, method = "lm") +
  labs(title = "Relación PIB per cápita y libertad económica",
       subtitle = "en 2019",
       x = "PIB per cápita",
       y = "Libertad económica") + 
  theme_classic() +
  theme(legend.position = "none",
        panel.background = element_rect(fill = NA))

f

#con ggplotly no sale el gráfico

Media PIB per cápita por regiones

df_gdp <- df %>%
  group_by(Region) %>%
  summarise(media_GDP_capita = mean(GDP_capita)) %>%
  arrange(desc(media_GDP_capita))

df_gdp$Region <- factor(df_gdp$Region, levels = df_gdp$Region)

my_colors <- c('#e41a1c','#377eb8','#4daf4a','#984ea3','#ff7f00')

g <- ggplot(df_gdp, aes(y = fct_rev(Region),
                   x = media_GDP_capita,
                   fill = Region)) +
  geom_col(show.legend = FALSE) +
  scale_fill_manual(values = my_colors) +
  scale_x_continuous(breaks = seq(0, 45000, 5000), limits = c(0, 45000)) +
  geom_text(aes(label = round(media_GDP_capita, digits = 0)), hjust = -0.10, size = 3.25) +
  labs(title = "PIB per cápita medio por regiones",
       subtitle = "en 2019",
       y = "Región",
       x = "PIB per cápita medio") + 
  theme(panel.background = element_rect(fill = NA)) +
  theme_classic()
g

Media de la puntuación por regiones

df_puntuacion <- df %>%
  group_by(Region) %>%
  summarise(media_score_2019 = mean(Score_2019)) %>%
  arrange(desc(media_score_2019))
  
df_puntuacion$Region <- factor(df_puntuacion$Region ,levels = df_puntuacion$Region)

ggplot(df_puntuacion, aes(x = media_score_2019,
                          y = fct_rev(Region),
                          fill = Region)) +
  geom_col(show.legend = FALSE) +
  geom_text(aes(label = round(media_score_2019, digits = 2)), hjust = -0.10, size = 3.25) +
  scale_fill_manual(values = my_colors) +
  coord_cartesian(xlim = c(40, 70)) +
  labs(title = "Puntuación media por regiones",
       subtitle = "en 2019",
       y = "Región",
       x = "Puntuación media") + 
  theme_classic() +
  theme(panel.background = element_rect(fill = NA))

df_join <- left_join(df_puntuacion, df_gdp, by = "Region") %>%
  arrange(desc(media_score_2019))

Tabla

df_gdp <- df %>%
  group_by(Region) %>%
  summarise(media_GDP_capita = mean(GDP_capita))

df_puntuacion <- df %>%
  group_by(Region) %>%
  summarise(media_score_2019 = mean(Score_2019))

df_join <- left_join(df_puntuacion, df_gdp, by = "Region") %>%
  arrange(desc(media_score_2019)) %>%
  rename("Región" = Region,
  "Puntuación media" = media_score_2019,
  "PIB per cápita medio" = media_GDP_capita)

knitr::kable(df_join, 
             align = "c", 
             caption = "Puntuación y PIB per cápita medios por regiones",
             digits = 2) %>%
  kableExtra::kable_styling(fixed_thead = list(enabled = T, 
                                               background = "white")) %>%
  column_spec(1, background = "white")
Puntuación y PIB per cápita medios por regiones
Región Puntuación media PIB per cápita medio
Europe 68.63 34783.84
Middle East and North Africa 61.26 38826.79
Asia-Pacific 60.63 20202.26
Americas 59.60 16897.56
Sub-Saharan Africa 54.18 5698.36

Bibliografía

Kaggle

Tutoriales de la asignatura

The Heritage Foundation (2019): World Economic Freedom Index

https://rpubs.com

https://colorbrewer2.org



Información de mi R-sesión:

- Session info ---------------------------------------------------------------
 setting  value                       
 version  R version 4.1.1 (2021-08-10)
 os       Windows 10 x64              
 system   x86_64, mingw32             
 ui       RTerm                       
 language (EN)                        
 collate  Spanish_Spain.1252          
 ctype    Spanish_Spain.1252          
 tz       Europe/Paris                
 date     2022-01-09                  

- Packages -------------------------------------------------------------------
 package           * version    date       lib source                        
 assertthat          0.2.1      2019-03-21 [1] CRAN (R 4.1.1)                
 backports           1.2.1      2020-12-09 [1] CRAN (R 4.1.1)                
 broom               0.7.9      2021-07-27 [1] CRAN (R 4.1.1)                
 bslib               0.3.0      2021-09-02 [1] CRAN (R 4.1.1)                
 cellranger          1.1.0      2016-07-27 [1] CRAN (R 4.1.1)                
 checkmate           2.0.0      2020-02-06 [1] CRAN (R 4.1.1)                
 class               7.3-19     2021-05-03 [2] CRAN (R 4.1.1)                
 classInt            0.4-3      2020-04-07 [1] CRAN (R 4.1.1)                
 cli                 3.0.1      2021-07-17 [1] CRAN (R 4.1.1)                
 clipr               0.7.1      2020-10-08 [1] CRAN (R 4.1.1)                
 colorspace          2.0-2      2021-06-24 [1] CRAN (R 4.1.1)                
 commonmark          1.7        2018-12-01 [1] CRAN (R 4.1.1)                
 crayon              1.4.2      2021-10-29 [1] CRAN (R 4.1.1)                
 crosstalk           1.1.1      2021-01-12 [1] CRAN (R 4.1.1)                
 curl                4.3.2      2021-06-23 [1] CRAN (R 4.1.1)                
 data.table          1.14.0     2021-02-21 [1] CRAN (R 4.1.1)                
 DBI                 1.1.1      2021-01-15 [1] CRAN (R 4.1.1)                
 dbplyr              2.1.1      2021-04-06 [1] CRAN (R 4.1.1)                
 desc                1.3.0      2021-03-05 [1] CRAN (R 4.1.1)                
 details             0.2.1      2020-01-12 [1] CRAN (R 4.1.1)                
 digest              0.6.27     2020-10-24 [1] CRAN (R 4.1.1)                
 dplyr             * 1.0.7      2021-06-18 [1] CRAN (R 4.1.1)                
 DT                  0.19       2021-09-02 [1] CRAN (R 4.1.1)                
 e1071               1.7-8      2021-07-28 [1] CRAN (R 4.1.1)                
 ellipsis            0.3.2      2021-04-29 [1] CRAN (R 4.1.1)                
 evaluate            0.14       2019-05-28 [1] CRAN (R 4.1.1)                
 fansi               0.5.0      2021-05-25 [1] CRAN (R 4.1.1)                
 farver              2.1.0      2021-02-28 [1] CRAN (R 4.1.1)                
 fastmap             1.1.0      2021-01-25 [1] CRAN (R 4.1.1)                
 forcats           * 0.5.1      2021-01-27 [1] CRAN (R 4.1.1)                
 foreign             0.8-81     2020-12-22 [2] CRAN (R 4.1.1)                
 formatR             1.11       2021-06-01 [1] CRAN (R 4.1.1)                
 fs                  1.5.0      2020-07-31 [1] CRAN (R 4.1.1)                
 generics            0.1.1      2021-10-25 [1] CRAN (R 4.1.1)                
 gganimate         * 1.0.7      2020-10-15 [1] CRAN (R 4.1.1)                
 ggfittext           0.9.1      2021-01-30 [1] CRAN (R 4.1.2)                
 ggplot2           * 3.3.5      2021-06-25 [1] CRAN (R 4.1.1)                
 ggThemeAssist     * 0.1.5      2016-08-13 [1] CRAN (R 4.1.1)                
 gifski              1.4.3-1    2021-05-02 [1] CRAN (R 4.1.1)                
 glue                1.4.2      2020-08-27 [1] CRAN (R 4.1.1)                
 gridBase            0.4-7      2014-02-24 [1] CRAN (R 4.1.1)                
 gridExtra           2.3        2017-09-09 [1] CRAN (R 4.1.1)                
 gt                * 0.3.1      2021-08-07 [1] CRAN (R 4.1.1)                
 gtable              0.3.0      2019-03-25 [1] CRAN (R 4.1.1)                
 haven               2.4.3      2021-08-04 [1] CRAN (R 4.1.1)                
 here                1.0.1      2020-12-13 [1] CRAN (R 4.1.1)                
 highr               0.9        2021-04-16 [1] CRAN (R 4.1.1)                
 hms                 1.1.0      2021-05-17 [1] CRAN (R 4.1.1)                
 htmltools           0.5.2      2021-08-25 [1] CRAN (R 4.1.1)                
 htmlwidgets         1.5.4      2021-09-08 [1] CRAN (R 4.1.1)                
 httpuv              1.6.3      2021-09-09 [1] CRAN (R 4.1.1)                
 httr                1.4.2      2020-07-20 [1] CRAN (R 4.1.1)                
 igraph              1.2.7      2021-10-15 [1] CRAN (R 4.1.1)                
 jquerylib           0.1.4      2021-04-26 [1] CRAN (R 4.1.1)                
 jsonlite            1.7.2      2020-12-09 [1] CRAN (R 4.1.1)                
 kableExtra        * 1.3.4      2021-02-20 [1] CRAN (R 4.1.1)                
 KernSmooth          2.23-20    2021-05-03 [2] CRAN (R 4.1.1)                
 klippy            * 0.0.0.9500 2021-11-17 [1] Github (rlesur/klippy@378c247)
 knitr             * 1.34       2021-09-09 [1] CRAN (R 4.1.1)                
 labeling            0.4.2      2020-10-20 [1] CRAN (R 4.1.1)                
 later               1.3.0      2021-08-18 [1] CRAN (R 4.1.1)                
 lattice             0.20-44    2021-05-02 [2] CRAN (R 4.1.1)                
 lazyeval            0.2.2      2019-03-15 [1] CRAN (R 4.1.1)                
 lifecycle           1.0.1      2021-09-24 [1] CRAN (R 4.1.1)                
 lubridate           1.7.10     2021-02-26 [1] CRAN (R 4.1.1)                
 magrittr            2.0.1      2020-11-17 [1] CRAN (R 4.1.1)                
 Matrix              1.3-4      2021-06-01 [2] CRAN (R 4.1.1)                
 mgcv                1.8-36     2021-06-01 [2] CRAN (R 4.1.1)                
 mime                0.11       2021-06-23 [1] CRAN (R 4.1.1)                
 miniUI              0.1.1.1    2018-05-18 [1] CRAN (R 4.1.1)                
 modelr              0.1.8      2020-05-19 [1] CRAN (R 4.1.1)                
 munsell             0.5.0      2018-06-12 [1] CRAN (R 4.1.1)                
 nlme                3.1-152    2021-02-04 [2] CRAN (R 4.1.1)                
 openxlsx            4.2.4      2021-06-16 [1] CRAN (R 4.1.1)                
 pillar              1.6.4      2021-10-18 [1] CRAN (R 4.1.1)                
 pkgconfig           2.0.3      2019-09-22 [1] CRAN (R 4.1.1)                
 plotly            * 4.9.4.1    2021-06-18 [1] CRAN (R 4.1.1)                
 png                 0.1-7      2013-12-03 [1] CRAN (R 4.1.1)                
 prettyunits         1.1.1      2020-01-24 [1] CRAN (R 4.1.1)                
 progress            1.2.2      2019-05-16 [1] CRAN (R 4.1.1)                
 promises            1.2.0.1    2021-02-11 [1] CRAN (R 4.1.1)                
 proxy               0.4-26     2021-06-07 [1] CRAN (R 4.1.1)                
 purrr             * 0.3.4      2020-04-17 [1] CRAN (R 4.1.1)                
 R6                  2.5.1      2021-08-19 [1] CRAN (R 4.1.1)                
 RColorBrewer        1.1-2      2014-12-07 [1] CRAN (R 4.1.1)                
 Rcpp                1.0.7      2021-07-07 [1] CRAN (R 4.1.1)                
 readr             * 2.0.1      2021-08-10 [1] CRAN (R 4.1.1)                
 readxl              1.3.1      2019-03-13 [1] CRAN (R 4.1.1)                
 reprex              2.0.1      2021-08-05 [1] CRAN (R 4.1.1)                
 rgeos               0.5-8      2021-09-22 [1] CRAN (R 4.1.1)                
 rio               * 0.5.27     2021-06-21 [1] CRAN (R 4.1.1)                
 rlang               0.4.11     2021-04-30 [1] CRAN (R 4.1.1)                
 rmarkdown           2.11       2021-09-14 [1] CRAN (R 4.1.1)                
 rnaturalearth     * 0.1.0      2017-03-21 [1] CRAN (R 4.1.1)                
 rnaturalearthdata   0.1.0      2017-02-21 [1] CRAN (R 4.1.1)                
 rprojroot           2.0.2      2020-11-15 [1] CRAN (R 4.1.1)                
 rstudioapi          0.13       2020-11-12 [1] CRAN (R 4.1.1)                
 rvest               1.0.1      2021-07-26 [1] CRAN (R 4.1.1)                
 sass                0.4.0      2021-05-12 [1] CRAN (R 4.1.1)                
 scales              1.1.1      2020-05-11 [1] CRAN (R 4.1.1)                
 sessioninfo         1.1.1      2018-11-05 [1] CRAN (R 4.1.1)                
 sf                * 1.0-2      2021-07-26 [1] CRAN (R 4.1.1)                
 shiny               1.7.0      2021-09-22 [1] CRAN (R 4.1.1)                
 sp                  1.4-5      2021-01-10 [1] CRAN (R 4.1.1)                
 stringi             1.7.5      2021-10-04 [1] CRAN (R 4.1.1)                
 stringr           * 1.4.0      2019-02-10 [1] CRAN (R 4.1.1)                
 svglite             2.0.0      2021-02-20 [1] CRAN (R 4.1.1)                
 systemfonts         1.0.3      2021-10-13 [1] CRAN (R 4.1.1)                
 tibble            * 3.1.4      2021-08-25 [1] CRAN (R 4.1.1)                
 tidyr             * 1.1.3      2021-03-03 [1] CRAN (R 4.1.1)                
 tidyselect          1.1.1      2021-04-30 [1] CRAN (R 4.1.1)                
 tidyverse         * 1.3.1      2021-04-15 [1] CRAN (R 4.1.1)                
 treemap           * 2.4-3      2021-08-22 [1] CRAN (R 4.1.1)                
 treemapify        * 2.5.5      2021-01-08 [1] CRAN (R 4.1.2)                
 tweenr              1.0.2      2021-03-23 [1] CRAN (R 4.1.1)                
 tzdb                0.1.2      2021-07-20 [1] CRAN (R 4.1.1)                
 units               0.7-2      2021-06-08 [1] CRAN (R 4.1.1)                
 utf8                1.2.2      2021-07-24 [1] CRAN (R 4.1.1)                
 vctrs               0.3.8      2021-04-29 [1] CRAN (R 4.1.1)                
 viridis           * 0.6.2      2021-10-13 [1] CRAN (R 4.1.1)                
 viridisLite       * 0.4.0      2021-04-13 [1] CRAN (R 4.1.1)                
 webshot             0.5.2      2019-11-22 [1] CRAN (R 4.1.1)                
 withr               2.4.2      2021-04-18 [1] CRAN (R 4.1.1)                
 wordcloud2        * 0.2.1      2018-01-03 [1] CRAN (R 4.1.2)                
 xfun                0.25       2021-08-06 [1] CRAN (R 4.1.1)                
 xml2                1.3.2      2020-04-23 [1] CRAN (R 4.1.1)                
 xtable              1.8-4      2019-04-21 [1] CRAN (R 4.1.1)                
 yaml                2.2.1      2020-02-01 [1] CRAN (R 4.1.1)                
 zip                 2.2.0      2021-05-31 [1] CRAN (R 4.1.1)                

[1] C:/Users/MAYTE/Documents/R/win-library/4.1
[2] C:/Program Files/R/R-4.1.1/library






LS0tDQp0aXRsZTogIsONbmRpY2UgZGUgbGliZXJ0YWQgZWNvbsOzbWljYSINCnN1YnRpdGxlOiAicGFyYSBlbCBhw7FvIDIwMTkiDQphdXRob3I6ICJEYW1pw6FuIFDDqXJleiBTb2xlciAocGVzb2RhQGFsdW1uaS51di5lcykiDQpkYXRlOiAiRGljaWVtYnJlIGRlIDIwMjEgKGFjdHVhbGl6YWRvIGVsIGByIGZvcm1hdChTeXMudGltZSgpLCAnJWQtJW0tJVknKWApIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNzczogIi4vYXNzZXRzL2Nzc19pbmRleC5jc3MiDQogICAgdGhlbWU6IHBhcGVyDQogICAgaGlnaGxpZ2h0OiB0ZXh0bWF0ZSANCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDMgDQogICAgdG9jX2Zsb2F0OiANCiAgICAgIGNvbGxhcHNlZDogdHJ1ZQ0KICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQ0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQ0KICAgIGRmX3ByaW50OiBrYWJsZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUNCi0tLQ0KDQpgYGB7ciBwYWNrYWdlcy1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHN0cmluZ3IpDQpsaWJyYXJ5KGtsaXBweSkgIy1yZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHJpbykNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeShzZikNCmxpYnJhcnkocm5hdHVyYWxlYXJ0aCkNCmxpYnJhcnkoZ3QpICNpbnN0YWxsLnBhY2thZ2VzKCJndCIpDQpsaWJyYXJ5KHdvcmRjbG91ZDIpICNpbnN0YWxsLnBhY2thZ2VzKCJ3b3JkY2xvdWQyIikNCmxpYnJhcnkoZ2dUaGVtZUFzc2lzdCkNCmxpYnJhcnkodHJlZW1hcCkNCmxpYnJhcnkodHJlZW1hcGlmeSkgI2luc3RhbGwucGFja2FnZXMo4oCcdHJlZW1hcGlmeeKAnSkNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoa2FibGVFeHRyYSkNCmxpYnJhcnkodmlyaWRpc0xpdGUpDQpsaWJyYXJ5KHZpcmlkaXMpDQoNCmBgYA0KDQpgYGB7ciBjaHVuay1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIA0KICAgICAgICAgICAgICAgICAgICAgICNyZXN1bHRzID0gImhvbGQiLA0KICAgICAgICAgICAgICAgICAgICAgIGNhY2hlID0gRkFMU0UsIGNhY2hlLnBhdGggPSAiL2NhY2hlcy8iLCBjb21tZW50ID0gIiM+IiwNCiAgICAgICAgICAgICAgICAgICAgICAjZmlnLndpZHRoID0gNywgI2ZpZy5oZWlnaHQ9IDcsICAgDQogICAgICAgICAgICAgICAgICAgICAgI291dC53aWR0aCA9IDcsIG91dC5oZWlnaHQgPSA3LA0KICAgICAgICAgICAgICAgICAgICAgIGNvbGxhcHNlID0gVFJVRSwgIGZpZy5zaG93ID0gImhvbGQiLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy5hc3AgPSAwLjYyOCwgb3V0LndpZHRoID0gIjc1JSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGRldiA9ICJwbmciLCBkZXYuYXJncyA9IGxpc3QodHlwZSA9ICJjYWlyby1wbmciKSkNCmBgYA0KDQoNCmBgYHtyIG9wdGlvbnMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAjLSBwYXJhIHF1aXRhciBsYSBub3RhY2nDs24gY2llbnTDrWZpY2ENCm9wdGlvbnMoInlhbWwuZXZhbC5leHByIiA9IFRSVUUpIA0KYGBgDQoNCg0KYGBge3Iga2xpcHB5LCBlY2hvID0gRkFMU0V9DQprbGlwcHk6OmtsaXBweShwb3NpdGlvbiA9IGMoInRvcCIsICJyaWdodCIpKSAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpgYGANCg0KDQo8aHIgY2xhc3M9ImxpbmVhLWJsYWNrIj4NCg0KVHJhYmFqbyBlbGFib3JhZG8gcGFyYSBsYSBhc2lnbmF0dXJhICJQcm9ncmFtYWNpw7NuIHkgbWFuZWpvIGRlIGRhdG9zIGVuIGxhIGVyYSBkZWwgQmlnIERhdGEiIGRlIGxhIFVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSBkdXJhbnRlIGVsIGN1cnNvIDIwMjEtMjAyMi4gRWwgcmVwbyBkZWwgdHJhYmFqbyBlc3TDoSBbYXF1w61dKGh0dHBzOi8vZ2l0aHViLmNvbS9kYW1pYW5wczE0L3RyYWJham9fQmlnRGF0YSl7dGFyZ2V0PSJfYmxhbmsifS4gDQoNCkxhIHDDoWdpbmEgd2ViIGRlIGxhIGFzaWduYXR1cmEgeSBsb3MgdHJhYmFqb3MgZGUgbWlzIGNvbXBhw7Flcm9zIHB1ZWRlbiB2ZXJzZSBbYXF1w61dKGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIxLTIyLXdlYi8wNy10cmFiYWpvcy5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9Lg0KDQoNCjxociBjbGFzcz0ibGluZWEtcmVkIj4NCg0KIyBJbnRyb2R1Y2Npw7NuDQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWFnZW5lcyIsICJpbWFnZW4yLmpwZyIpKQ0KDQpgYGANCg0KPGJyPjxicj4NCg0KRWwgw41uZGljZSBkZSBMaWJlcnRhZCBFY29uw7NtaWNhIGVzIGVsYWJvcmFkbyBhbnVhbG1lbnRlIHBvciBsYSBGdW5kYWNpw7NuIEhlcml0YWdlIHkgVGhlIFdhbGwgU3RyZWV0IEpvdXJuYWwuIFN1IG9iamV0aXZvIGRlY2xhcmFkbyBlcyBtZWRpciBlbCBuaXZlbCBkZSBlY29ub23DrWEgZGUgbWVyY2FkbyBxdWUgdW4gcGHDrXMgYWRtaXRlLiBFbCByYW5raW5nIHB1bnTDumEgZGF0b3MgZW50cmUgMCB5IDEwMCwgZG9uZGUgMCBzaWduaWZpY2EgwqthdXNlbmNpYSBkZSBsaWJlcnRhZCBlY29uw7NtaWNhwrsgeSAxMDAgc2lnbmlmaWNhIMKrbGliZXJ0YWQgZWNvbsOzbWljYSB0b3RhbMK7Lg0KDQpNw6FzIGFsbMOhIGRlIHN1cyBvYmpldGl2b3MsIGVzdMOhIHBlbnNhZG8gcGFyYSBheXVkYXIgYSBsb3MgbGVjdG9yZXMgYSByZWFsaXphciB1biBzZWd1aW1pZW50byBkZSBtw6FzIGRlIGRvcyBkw6ljYWRhcyBkZWwgYXZhbmNlIGVuIGxhIGxpYmVydGFkIGVjb27Ds21pY2EsIGxhIHByb3NwZXJpZGFkIHkgbGFzIG9wb3J0dW5pZGFkZXMsIHkgcHJvbW92ZXIgZXN0YXMgaWRlYXMgZW4gc3VzIGhvZ2FyZXMsIGVzY3VlbGFzIHkgY29tdW5pZGFkZXMuIEVsIMOtbmRpY2UgY3VicmUgMTIgbGliZXJ0YWRlcywgZGVzZGUgbG9zIGRlcmVjaG9zIGRlIHByb3BpZWRhZCBoYXN0YSBsYSBsaWJlcnRhZCBmaW5hbmNpZXJhLCBlbiAxODYgcGHDrXNlcy4gRW4gY29uY3JldG8sIHZhbW9zIGVzdHVkaWFyIGVsIMOtbmRpY2UgcGFyYSBlbCBhw7FvIDIwMTksIGFudGVyaW9yIGEgbGEgcGFuZGVtaWEgbXVuZGlhbCBkZSBjb3ZpZC0xOS4NCg0KIyBQcm9jZXNvIGRlIGRhdG9zDQoNCkRlc2NhcmdhbW9zIGxvcyBkYXRvcyBbYXF1aV0oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9sZXdpc2R1bmNhbjkzL3RoZS1lY29ub21pYy1mcmVlZG9tLWluZGV4P3NlbGVjdD1lY29ub21pY19mcmVlZG9tX2luZGV4MjAxOV9kYXRhLmNzdikuIEEgY29udGludWFjacOzbiwgc2l0dWFtb3MgbG9zIGRhdG9zIGVuIGxhIGNhcnBldGEgZGF0b3MgeSByZWFsaXphbW9zIGxhcyBzaWd1aWVudGVzIG1vZGlmaWNhY2lvbmVzOg0KDQpgYGB7ciwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9DQpkZiA8LSByZWFkLmNzdigiLi9kYXRvcy9lY29ub21pY19mcmVlZG9tX2luZGV4MjAxOV9kYXRhLmNzdiIpDQoNCiMtIHBvbmVtb3MgbGFzIHZhcmlhYmxlcyBlbiBmb3JtYSBudW3DqXJpY2ENCg0KZGYgPC0gZGYgJT4lIGFycmFuZ2UoZGVzYyhYMjAxOS5TY29yZSkpICU+JSANCiAgICBmaWx0ZXIoIVgyMDE5LlNjb3JlID09ICdOL0EnKQ0KDQojc2VsZWNjaW9uYW1vcyBsYXMgdmFyaWFibGVzIHF1ZSBub3MgaW50ZXJlc2FuDQoNCmRmIDwtIGRmICU+JSANCiAgcmVuYW1lKFNjb3JlXzIwMTkgPSAiWDIwMTkuU2NvcmUiLA0KICAgICAgICAgR0RQX2NhcGl0YSA9ICJHRFAucGVyLkNhcGl0YS4uUFBQLiIpICU+JQ0KICBzZWxlY3QoQ291bnRyeSwgUmVnaW9uLCBXb3JsZC5SYW5rLCBSZWdpb24uUmFuaywgU2NvcmVfMjAxOSwgUHJvcGVydHkuUmlnaHRzLCBKdWRpY2FsLkVmZmVjdGl2ZW5lc3MsIEdvdmVybm1lbnQuSW50ZWdyaXR5LCBCdXNpbmVzcy5GcmVlZG9tLCBMYWJvci5GcmVlZG9tLCBNb25ldGFyeS5GcmVlZG9tLCBUcmFkZS5GcmVlZG9tLCBGaW5hbmNpYWwuRnJlZWRvbSwgR0RQX2NhcGl0YSkgDQoNCiNyZW5vbWJyYW1vcyBwYWlzZXMNCg0KZGYkQ291bnRyeSA8LSByZWNvZGUoZGYkQ291bnRyeSwNCiAgICAgICAgICAgICAgICAgICAgICJIb25nIEtvbmcgU0FSIiA9ICJIb25nIEtvbmciLA0KICAgICAgICAgICAgICAgICAgICAgIkN6ZWNoIFJlcHVibGljIiA9ICJDemVjaCBSZXAuIiwNCiAgICAgICAgICAgICAgICAgICAgICJLb3JlYSwgU291dGgiID0gIktvcmVhIiwNCiAgICAgICAgICAgICAgICAgICAgICJCcnVuZWkgRGFydXNzYWxhbSIgPSAiQnJ1bmVpIiwNCiAgICAgICAgICAgICAgICAgICAgICJTbG92YWsgUmVwdWJsaWMiID0gIlNsb3Zha2lhIiwNCiAgICAgICAgICAgICAgICAgICAgICJDYWJvIFZlcmRlIiA9ICJDYXBlIFZlcmRlIiwNCiAgICAgICAgICAgICAgICAgICAgICJLeXJneXogUmVwdWJsaWMiID0gIkt5cmd5enN0YW4iLA0KICAgICAgICAgICAgICAgICAgICAgIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiID0gIkJvc25pYSBhbmQgSGVyei4iLA0KICAgICAgICAgICAgICAgICAgICAgIkRvbWluaWNhbiBSZXB1YmxpYyIgPSAiRG9taW5pY2FuIFJlcC4iLA0KICAgICAgICAgICAgICAgICAgICAgIkxhbyBQLkQuUi4iID0gIkxhbyBQRFIiLA0KICAgICAgICAgICAgICAgICAgICAgIlNvbG9tb24gSXNsYW5kcyIgPSAiU29sb21vbiBJcy4iLA0KICAgICAgICAgICAgICAgICAgICAgIlPDo28gVG9tw6kgYW5kIFByw61uY2lwZSIgPSAiU8OjbyBUb23DqSBhbmQgUHJpbmNpcGUiLA0KICAgICAgICAgICAgICAgICAgICAgIkJ1cm1hIiA9ICJNeWFubWFyIiwNCiAgICAgICAgICAgICAgICAgICAgICJNYWNhdSIgPSAiTWFjYW8iLA0KICAgICAgICAgICAgICAgICAgICAgIlRhaXdhbiIgPSAiVGFpd2FuIiwNCiAgICAgICAgICAgICAgICAgICAgICJTYWludCBWaW5jZW50IGFuZCB0aGUgR3JlbmFkaW5lcyIgPSAiU3QuIFZpbi4gYW5kIEdyZW4uIiwNCiAgICAgICAgICAgICAgICAgICAgICJDb25nbywgRGVtb2NyYXRpYyBSZXB1YmxpYyBvZiB0aGUgQ29uZ28iID0gIkRlbS4gUmVwLiBDb25nbyIsDQogICAgICAgICAgICAgICAgICAgICAiS29yZWEsIE5vcnRoIiA9ICJEZW0uIFJlcC4gS29yZWEiLA0KICAgICAgICAgICAgICAgICAgICAgIkNlbnRyYWwgQWZyaWNhbiBSZXB1YmxpYyIgPSAiQ2VudHJhbCBBZnJpY2FuIFJlcC4iLA0KICAgICAgICAgICAgICAgICAgICAgIkVxdWF0b3JpYWwgR3VpbmVhIiA9ICJFcS4gR3VpbmVhIiwNCiAgICAgICAgICAgICAgICAgICAgICJDb25nbywgUmVwdWJsaWMgb2YiID0gIkNvbmdvIiwNCiAgICAgICAgICAgICAgICAgICAgICJFc3dhdGluaSIgPSAiU3dhemlsYW5kIikNCg0KZGYkR0RQX2NhcGl0YSA8LSByZWNvZGUoZGYkR0RQX2NhcGl0YSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIkMSw3MDAgKDIwMTUgZXN0LikiID0gIiQxLDcwMCIpDQoNCiNFbGltaW5hbW9zIGVsIHNpbWJvbG8gZGVsIGTDs2xhciANCg0KZGYgPC0gZGYgJT4lIG11dGF0ZShHRFBfY2FwaXRhID0gc3RyX3JlcGxhY2UoR0RQX2NhcGl0YSwgIlxcJCIsICIiICkpDQoNCiNFbGltaW5hbW9zIGxhcyBjb21hcyBwYXJhIHBhc2FybG8gYSBudW1lcmljbyB5IGxhcyByZW1wbGF6YW1vcyBwb3IgcHVudG9zDQoNCmRmIDwtIGRmICU+JSBtdXRhdGUoR0RQX2NhcGl0YSA9IHN0cl9yZXBsYWNlKEdEUF9jYXBpdGEsICIsIiwgIiIgKSkNCg0KZGYgPC0gdHJhbnNmb3JtKGRmLCBTY29yZV8yMDE5ID0gYXMubnVtZXJpYyhTY29yZV8yMDE5KSwNCiAgICAgICAgICAgICAgICBQcm9wZXJ0eS5SaWdodHMgPSBhcy5udW1lcmljKFByb3BlcnR5LlJpZ2h0cyksDQogICAgICAgICAgICAgICAgSnVkaWNhbC5FZmZlY3RpdmVuZXNzID0gYXMubnVtZXJpYyhKdWRpY2FsLkVmZmVjdGl2ZW5lc3MpLA0KICAgICAgICAgICAgICAgIExhYm9yLkZyZWVkb20gPSBhcy5udW1lcmljKExhYm9yLkZyZWVkb20pLA0KICAgICAgICAgICAgICAgIEZpbmFuY2lhbC5GcmVlZG9tID0gYXMubnVtZXJpYyhGaW5hbmNpYWwuRnJlZWRvbSksDQogICAgICAgICAgICAgICAgR0RQX2NhcGl0YSA9IGFzLm51bWVyaWMoR0RQX2NhcGl0YSkpDQoNCiMuZWxpbWluYW1vcyBsb3MgcGHDrXNlcyBxdWUgbm8gdGllbmVuIHB1bnR1YWNpb24NCg0KZGYgPC0gZGYgJT4lIGFycmFuZ2UoZGVzYyhTY29yZV8yMDE5KSkgJT4lIA0KICAgIGZpbHRlcighU2NvcmVfMjAxOSA9PSAnTi9BJykNCg0KI2HDsWFkaW1vcyBlbCBzaWd1aWVudGUgY29tZW50YXJpbw0KDQpkZiA8LSBkZiAlPiUNCiAgbXV0YXRlKEdyYWRvX2xpYmVydGFkID0gY2FzZV93aGVuKCANCiAgICBTY29yZV8yMDE5ID4gODAgfiAiTGlicmUiLA0KICAgIFNjb3JlXzIwMTkgPiA3MCAmIFNjb3JlXzIwMTkgPCA4MCAgIH4gIkdlbmVyYWxtZW50ZSBsaWJyZSIsDQogICAgU2NvcmVfMjAxOSA+IDYwICYgU2NvcmVfMjAxOSA8IDcwICAgfiAiTW9kZXJhZGFtZW50ZSBsaWJyZSIgLCANCiAgICBTY29yZV8yMDE5ID4gNTAgJiBTY29yZV8yMDE5IDwgNjAgICB+ICJHZW5lcmFsbWVudGUgYXV0b3JpdGFyaW8iLA0KICAgIFNjb3JlXzIwMTkgPCA1MCB+ICJBdXRvcml0YXJpbyIpKQ0KDQpkZiA8LSBkZiAlPiUNCiAgIHNlbGVjdChDb3VudHJ5LCBSZWdpb24sIFdvcmxkLlJhbmssIFJlZ2lvbi5SYW5rLCBTY29yZV8yMDE5LCBHcmFkb19saWJlcnRhZCwgUHJvcGVydHkuUmlnaHRzLCBKdWRpY2FsLkVmZmVjdGl2ZW5lc3MsIEdvdmVybm1lbnQuSW50ZWdyaXR5LCBCdXNpbmVzcy5GcmVlZG9tLCBMYWJvci5GcmVlZG9tLCBNb25ldGFyeS5GcmVlZG9tLCBUcmFkZS5GcmVlZG9tLCBGaW5hbmNpYWwuRnJlZWRvbSwgR0RQX2NhcGl0YSkNCg0KYGBgDQoNCkVuIGVzdGEgdGFibGEgc2UgcHVlZGUgb2JzZXJ2YXIgeSBidXNjYXIgY3VhbHF1aWVyIGVsZW1lbnRvIGRlbCBkYXRhIGZyYW1lOg0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQpEVDo6ZGF0YXRhYmxlKGRmKQ0KYGBgDQoNCiMgQW7DoWxpc2lzIGRlIGxhcyBwdW50dWFjaW9uZXMgcG9yIHBhw61zZXMgey50YWJzZXQgLnRhYnNldC1waWxsc30gDQoNClZhbW9zIGEgYW5hbGl6YXIgbG9zIDIwIHBhw61zZXMgY29uIG1heW9yIHkgbWVub3IgcHVudHVhY2nDs24gcHVudHVhY2nDs24gZW4gZWwgw61uZGljZS4NCg0KRW4gcHJpbWVyIGx1Z2FyLCBlbCB0b3AgMjAgc29uIHBhw61zZXMgZGVzYXJyb2xsYWRvcywgY29uIHVuYXMgaW5zdGl0dWNpb25lcyBkZW1vY3LDoXRyaWNhcyBjb25zb2xpZGFkYXMgcXVlIGZhdm9yZWNlbiBlbCBjcmVjaW1pZW50byBlY29uw7NtaWNvLiANCkVuIHNlZ3VuZG8gbHVnYXIsIGVsIHRvcCAyMCBjb24gbWVub3IgcHVudHVhY2nDs24gc29uIHBhw61zZXMgY3V5YXMgaW5zdGl0dWNpb25lcyBzb24gcmVhbG1lbnRlIHBvY28gYmVuZWZpY2lvc2FzIHBhcmEgZWwgY3JlY2ltaWVudG8uIExhIGdyYW4gbWF5b3LDrWEgc29uIHBhw61zZXMgdG90YWxpdGFyaW9zIHF1ZSBwcmVzZW50YW4gdW5hIGVsZXZhZGEgY29ycnVwY2nDs24uDQoNCiMjIFRvcCAyMCBtYXlvciBwdW50dWFjacOzbg0KDQpgYGB7ciwgZXZhbCA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRX0NCiMgdG9wIDIwDQpkZl8yMCA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkoQ291bnRyeSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgc2xpY2VfbWF4KFNjb3JlXzIwMTksIG4gPSAyMCkNCg0KI0NvbnZlcnRpcm1vcyBhIGZhY3RvciBsYSBjb2x1bW5hIFJhesOzbg0KZGZfMjAkQ291bnRyeSA8LSBmYWN0b3IoZGZfMjAkQ291bnRyeSxsZXZlbHMgPSBkZl8yMCRDb3VudHJ5KQ0KDQpwMSA8LSBnZ3Bsb3QoZGZfMjAsIGFlcyh5ID0gZmN0X3JldihDb3VudHJ5KSwNCiAgICAgICAgICAgICAgICAgIHggPSBTY29yZV8yMDE5KSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiMyQTc1OUYiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBTY29yZV8yMDE5KSwgaGp1c3QgPSAtMC4xNSxzaXplID0gMy4yNSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMzApLCBsaW1pdHMgPSBjKDAsIDEwMCkpICsNCiAgbGFicyh0aXRsZSA9ICLDjW5kaWNlIGRlIGxpYmVydGFkIGVjb27Ds21pY2EiLA0KICAgICAgIHN1YnRpdGxlID0gIlRvcCAyMCwgYcOxbyAyMDE5IiwNCiAgICAgICB5ID0gIlB1bnR1YWNpw7NuIiwgeCA9ICJQYcOtcyIpICsNCiAgdGhlbWVfY2xhc3NpYygpDQpwMQ0KDQpgYGANCg0KIyMgV29yZGNsb3VkDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gMiwgZmlnLndpZHRoID0gNSAsZHBpID0gMTUwLGZpZy5hbGlnbiA9ICJjZW50ZXIiLCBldmFsPSBUUlVFfQ0KDQpkZl8xIDwtIGRmICU+JQ0KICBzZWxlY3QoQ291bnRyeSwgU2NvcmVfMjAxOSkNCg0KZGZfMSRDb3VudHJ5IDwtIHJlY29kZShkZl8xJENvdW50cnksIA0KICAgICAgICAgICAgICAgICAgICAgIlVuaXRlZCBTdGF0ZXMiPSJVU0EiLA0KICAgICAgICAiSG9uZyBLb25nIiA9ICJISyIsDQogICAgICAgICJVbml0ZWQgS2luZ2RvbSIgPSAiVUsiLA0KICAgICAgICAiVW5pdGVkIEFyYWIgRW1pcmF0ZXMiID0gIkVBVSIpDQoNCndvcmRjbG91ZDIoZGF0YSA9IGRmXzEsIHNoYXBlID0gImNpcmNsZSIsIHNpemUgPSAwLjMpDQoNCmBgYA0KDQojIyBPdHJhIGZvcm1hIGRlIHZpc3VhbGl6YXIgbG9zIGRhdG9zDQoNCmBgYHtyLCBldmFsID0gVFJVRX0NCg0KZGZfNSA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkoQ291bnRyeSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgc2xpY2VfbWF4KFNjb3JlXzIwMTksIG4gPSA1KQ0KDQpwMiA8LSB0cmVlbWFwKGRmXzUsDQogICAgICAgICAgICBpbmRleCA9ICJDb3VudHJ5IiwNCiAgICAgICAgICAgIHZTaXplID0iU2NvcmVfMjAxOSIsDQogICAgICAgICAgICB0eXBlID0gImluZGV4IiwNCiAgICAgICAgICAgIHBhbGV0dGUgPSAiU2V0MiIsDQogICAgICAgICAgICAoY29sMnJnYihiZy5sYWJlbHMgPSBjKCJ3aGl0ZSIpLCBzaWxlbnQgPSBUUlVFKSksDQogICAgICAgICAgICBhbGlnbi5sYWJlbHM9IGxpc3QoYygiY2VudGVyIiwgImNlbnRlciIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoInJpZ2h0IiwgImJvdHRvbSIpKSwNCiAgICAgICAgICAgIHRpdGxlID0gIlRvcCA1IGNvbiBtYXlvciDDrW5kaWNlIGRlIGxpYmVydGFkIGVjb27Ds21pY2EiKQ0KcDINCg0KDQpgYGANCg0KIyMgVGFibGENCg0KYGBge3IsIGV2YWwgPSBUUlVFfQ0KZGZfMjAgPC0gZGYgJT4lDQogIHNsaWNlX21heChTY29yZV8yMDE5LCBuID0gMjApICU+JQ0KICBzZWxlY3QoQ291bnRyeSwgUmVnaW9uLCBXb3JsZC5SYW5rLCBSZWdpb24uUmFuaywgU2NvcmVfMjAxOSwgR3JhZG9fbGliZXJ0YWQpICU+JQ0KICByZW5hbWUoIlBhw61zIiA9IENvdW50cnksICJSZWdpw7NuIiA9IFJlZ2lvbiwgIlJhbmtpbmciID0gV29ybGQuUmFuaywgIlJhbmtpbmcgcmVnaW9uYWwiID0gUmVnaW9uLlJhbmssICJQdW50dWFjacOzbiIgPSBTY29yZV8yMDE5LCAiR3JhZG8gZGUgbGliZXJ0YWQiID0gR3JhZG9fbGliZXJ0YWQpDQoNCmd0XzIwIDwtIGd0KGRmXzIwKSAlPiUgDQogIHRhYl9oZWFkZXIodGl0bGUgPSBtZCgiKipUb3AgMjAgcGHDrXNlcyBjb24gbWF5b3IgbGliZXJ0YWQgZWNvbsOzbWljYSoqIiksDQogICAgICAgICAgICAgc3VidGl0bGUgPSAiZW4gMjAxOSIpDQoNCmd0XzIwDQoNCmBgYA0KDQojIyBUb3AgMjAgbWVub3IgcHVudHVhY2nDs24NCg0KYGBge3IsIGV2YWwgPSBUUlVFLCB3YXJuaW5nID0gRkFMU0V9DQojIHRvcCAyMA0KZGZfbWluIDwtIGRmICU+JQ0KICBncm91cF9ieShDb3VudHJ5KSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBzbGljZV9taW4oU2NvcmVfMjAxOSwgbiA9IDIwKQ0KDQojQ29udmVydGlybW9zIGEgZmFjdG9yIGxhIGNvbHVtbmEgUmF6w7NuDQpkZl9taW4kQ291bnRyeSA8LSBmYWN0b3IoZGZfbWluJENvdW50cnksbGV2ZWxzID0gZGZfbWluJENvdW50cnkpDQoNCnAzIDwtIGdncGxvdChkZl9taW4sIGFlcyh5ID0gZmN0X3JldihDb3VudHJ5KSwNCiAgICAgICAgICAgICAgICAgIHggPSBTY29yZV8yMDE5KSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiMyQTc1OUYiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBTY29yZV8yMDE5KSwgaGp1c3QgPSAtMC4xNSxzaXplID0gMy4yNSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMzApLCBsaW1pdHMgPSBjKDAsIDEwMCkpICsNCiAgbGFicyh0aXRsZSA9ICLDjW5kaWNlIGRlIGxpYmVydGFkIGVjb27Ds21pY2EiLA0KICAgICAgIHN1YnRpdGxlID0gIlRvcCAyMCBjb24gbWVub3IgcHVudHVhY2nDs24sIGHDsW8gMjAxOSIsDQogICAgICAgeSA9ICJQdW50dWFjacOzbiIsIHggPSAiUGHDrXMiKSArDQogIHRoZW1lX2NsYXNzaWMoKQ0KcDMNCg0KYGBgDQoNCiMjIE90cmEgZm9ybWEgZGUgdmlzdWFsaXphciBsb3MgZGF0b3MNCg0KYGBge3IsIGV2YWwgPSBUUlVFfQ0KDQpkZl9taW5fNSA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkoQ291bnRyeSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgc2xpY2VfbWluKFNjb3JlXzIwMTksIG4gPSA1KQ0KDQpwNCA8LSB0cmVlbWFwKGRmX21pbl81LA0KICAgICAgICAgICAgaW5kZXggPSAiQ291bnRyeSIsDQogICAgICAgICAgICB2U2l6ZSA9IlNjb3JlXzIwMTkiLA0KICAgICAgICAgICAgdHlwZSA9ICJpbmRleCIsDQogICAgICAgICAgICBwYWxldHRlID0gIlNldDIiLA0KICAgICAgICAgICAgKGNvbDJyZ2IoYmcubGFiZWxzID0gYygid2hpdGUiKSwgc2lsZW50ID0gVFJVRSkpLA0KICAgICAgICAgICAgYWxpZ24ubGFiZWxzPSBsaXN0KGMoImNlbnRlciIsICJjZW50ZXIiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJyaWdodCIsICJib3R0b20iKSksDQogICAgICAgICAgICB0aXRsZSA9ICJUb3AgNSBjb24gbWVub3Igw61uZGljZSBkZSBsaWJlcnRhZCBlY29uw7NtaWNhIikNCnA0DQoNCmBgYA0KDQojIyBUYWJsYQ0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQpkZl9taW4gPC0gZGYgJT4lDQogIHNsaWNlX21pbihTY29yZV8yMDE5LCBuID0gMjApICU+JQ0KICBzZWxlY3QoQ291bnRyeSwgUmVnaW9uLCBXb3JsZC5SYW5rLCBSZWdpb24uUmFuaywgU2NvcmVfMjAxOSwgR3JhZG9fbGliZXJ0YWQpICU+JQ0KICByZW5hbWUoIlBhw61zIiA9IENvdW50cnksICJSZWdpw7NuIiA9IFJlZ2lvbiwgIlJhbmtpbmciID0gV29ybGQuUmFuaywgIlJhbmtpbmcgcmVnaW9uYWwiID0gUmVnaW9uLlJhbmssICJQdW50dWFjacOzbiIgPSBTY29yZV8yMDE5LCAiR3JhZG8gZGUgbGliZXJ0YWQiID0gR3JhZG9fbGliZXJ0YWQpDQoNCmd0X21pbiA8LSBndChkZl9taW4pICU+JSANCiAgdGFiX2hlYWRlcih0aXRsZSA9IG1kKCIqKlRvcCAyMCBwYcOtc2VzIGNvbiBtZW5vciBsaWJlcnRhZCBlY29uw7NtaWNhKioiKSwNCiAgICAgICAgICAgICBzdWJ0aXRsZSA9ICJlbiAyMDE5IikNCg0KZ3RfbWluDQoNCmBgYA0KDQojIEFuw6FsaXNpcyBkZSBsb3MgZGlmZXJlbnRlcyBjb21wb25lbnRlcyBkZWwgw61uZGljZSANCg0KVmFtb3MgYSBsbGV2YXIgYSBjYWJvIHVuIGFuw6FsaXNpcyBkZSBhbGd1bm9zIGRlIGxvcyBjb21wb25lbnRlcyBxdWUgY29uc2lkZXJvIHF1ZSBzb24gaW1wb3J0YW50ZXMgYSBsYSBob3JhIGRlIGV4cGxpY2FyIGVsIGdyYWRvIGRlIGxpYmVydGFkIGRlIGxvcyBwYcOtc2VzLg0KDQojIyBEZXJlY2hvcyBkZSBwcm9waWVkYWQgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIEdyw6FmaWNvDQoNCmBgYHtyLCBldmFsID0gVFJVRX0NCg0KZGZfY29tcCA8LSBkZiAlPiUNCiAgc2VsZWN0KCFHRFBfY2FwaXRhKQ0KDQpkZl9wcm9wIDwtIGRmX2NvbXAgJT4lDQogIHNlbGVjdChDb3VudHJ5LCBSZWdpb24sIFdvcmxkLlJhbmssIFJlZ2lvbi5SYW5rLCBQcm9wZXJ0eS5SaWdodHMpDQoNCmRmX3Byb3AxIDwtIGRmX3Byb3AgJT4lDQogIHNsaWNlX21heChQcm9wZXJ0eS5SaWdodHMsIG4gPSAxMCkgJT4lDQogIHNlbGVjdChDb3VudHJ5LCBSZWdpb24sIFdvcmxkLlJhbmssIFJlZ2lvbi5SYW5rLCBQcm9wZXJ0eS5SaWdodHMpDQoNCmRmX3Byb3AyIDwtIGRmX3Byb3AgJT4lDQogIHNsaWNlX21pbihQcm9wZXJ0eS5SaWdodHMsIG4gPSA1KSAlPiUNCiAgYXJyYW5nZShkZXNjKFByb3BlcnR5LlJpZ2h0cykpICU+JQ0KICBzZWxlY3QoQ291bnRyeSwgUmVnaW9uLCBXb3JsZC5SYW5rLCBSZWdpb24uUmFuaywgUHJvcGVydHkuUmlnaHRzKQ0KDQojQ29udmVydGlybW9zIGEgZmFjdG9yIGxhIGNvbHVtbmEgUmF6w7NuDQpkZl9wcm9wMSRDb3VudHJ5IDwtIGZhY3RvcihkZl9wcm9wMSRDb3VudHJ5LGxldmVscyA9IGRmX3Byb3AxJENvdW50cnkpDQoNCmdncGxvdChkZl9wcm9wMSwgYWVzKHkgPSBmY3RfcmV2KENvdW50cnkpLCANCiAgICAgICAgICAgICAgICAgICAgIHggPSBQcm9wZXJ0eS5SaWdodHMpKSArDQogIGdlb21fY29sKGZpbGwgPSAiIzJBNzU5RiIsIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2socmV2ZXJzZSA9IFRSVUUpKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBQcm9wZXJ0eS5SaWdodHMpLCBoanVzdCA9IC0wLjE1LCBzaXplID0gMy4yNSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMzApLCBsaW1pdHMgPSBjKDAsIDEwMCkpICsNCiAgbGFicyh0aXRsZSA9ICJUb3AgMTAgcGFpc2VzIGNvbiBtZWpvcmVzIGRlcmVjaG9zIGRlIHByb3BpZWRhZCIsDQogICAgICAgc3VidGl0bGUgPSAiZW4gMjAxOSIsDQogICAgICAgeCA9ICJQdW50dWFjacOzbiBkZXJlY2hvcyBkZSBwcm9waWVkYWQiLA0KICAgICAgIHkgPSAiUGHDrXNlcyIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCkpICsNCiAgdGhlbWVfY2xhc3NpYygpDQoNCmBgYA0KDQojIyMgVGFibGENCg0KYGBge3IsIGV2YWwgPSBUUlVFfQ0KDQpkZl9wcm9wMSA8LSBkZl9wcm9wICU+JQ0KICBzbGljZV9tYXgoUHJvcGVydHkuUmlnaHRzLCBuID0gMTApICU+JQ0KICBzZWxlY3QoQ291bnRyeSwgUmVnaW9uLCBXb3JsZC5SYW5rLCBSZWdpb24uUmFuaywgUHJvcGVydHkuUmlnaHRzKSAlPiUNCiAgcmVuYW1lKCJQYcOtcyIgPSBDb3VudHJ5LCAiUmVnacOzbiIgPSBSZWdpb24sICJSYW5raW5nIG11bmRpYWwiID0gV29ybGQuUmFuaywgIlJhbmtpbmcgcmVnaW9uYWwiID0gUmVnaW9uLlJhbmssICJEZXJlY2hvcyBkZSBwcm9waWVkYWQiID0gUHJvcGVydHkuUmlnaHRzKQ0KDQoNCmtuaXRyOjprYWJsZShkZl9wcm9wMSwgDQogICAgICAgICAgICAgYWxpZ24gPSAiYyIsIA0KICAgICAgICAgICAgIGNhcHRpb24gPSAiVG9wIDEwIHBhaXNlcyBjb24gbWVqb3JlcyBkZXJlY2hvcyBkZSBwcm9waWVkYWQiLA0KICAgICAgICAgICAgIGRpZ2l0cyA9IDIpICU+JQ0KICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZpeGVkX3RoZWFkID0gbGlzdChlbmFibGVkID0gVCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmQgPSAid2hpdGUiKSkgJT4lDQogIGNvbHVtbl9zcGVjKDEsIGJhY2tncm91bmQgPSAid2hpdGUiKQ0KDQpgYGANCg0KIyMgRWZlY3RpdmlkYWQganVkaWNpYWwgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIEdyw6FmaWNvDQoNCmBgYHtyLCBldmFsID0gVFJVRX0NCg0KZGZfanVkIDwtIGRmX2NvbXAgJT4lDQogIHNlbGVjdChDb3VudHJ5LCBSZWdpb24sIFdvcmxkLlJhbmssIFJlZ2lvbi5SYW5rLCBKdWRpY2FsLkVmZmVjdGl2ZW5lc3MpDQoNCmRmX2p1ZDEgPC0gZGZfanVkICU+JQ0KICBzbGljZV9tYXgoSnVkaWNhbC5FZmZlY3RpdmVuZXNzLCBuID0gMTApICU+JQ0KICBzZWxlY3QoQ291bnRyeSwgUmVnaW9uLCBXb3JsZC5SYW5rLCBSZWdpb24uUmFuaywgSnVkaWNhbC5FZmZlY3RpdmVuZXNzKQ0KDQojQ29udmVydGlybW9zIGEgZmFjdG9yIGxhIGNvbHVtbmEgUmF6w7NuDQpkZl9qdWQxJENvdW50cnk8LWZhY3RvcihkZl9qdWQxJENvdW50cnksIGxldmVscyA9IGRmX2p1ZDEkQ291bnRyeSkNCg0KbXlfMTAgPC0gYygnIzllMDE0MicsJyNkNTNlNGYnLCcjZjQ2ZDQzJywnI2ZkYWU2MScsJyNmZWUwOGInLCcjZTZmNTk4JywnI2FiZGRhNCcsJyM2NmMyYTUnLCcjMzI4OGJkJywnIzVlNGZhMicpDQoNCmdncGxvdChkZl9qdWQxLCBhZXMoeSA9IGZjdF9yZXYoQ291bnRyeSksIHggPSBKdWRpY2FsLkVmZmVjdGl2ZW5lc3MpKSArDQogIGdlb21fY29sKGZpbGwgPSBteV8xMCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gSnVkaWNhbC5FZmZlY3RpdmVuZXNzKSwgaGp1c3QgPSAtMC4xNSwgc2l6ZSA9IDMuMjUpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbXlfMTApICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAxMDAsIDMwKSwgbGltaXRzID0gYygwLCAxMDApKSArDQogIGxhYnModGl0bGUgPSAiVG9wIDEwIHBhaXNlcyBjb24gbWVqb3IgZWZlY3RpdmlkYWQganVkaWNpYWwiLA0KICAgICAgIHN1YnRpdGxlID0gImVuIDIwMTkiLA0KICAgICAgIHggPSAiUHVudHVhY2nDs24gZW4gZWZlY3RpdmlkYWQganVkaWNpYWwiLA0KICAgICAgIHkgPSAiUGHDrXNlcyIpICsNCiAgdGhlbWVfY2xhc3NpYygpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPTMwKSkNCg0KYGBgDQoNCiMjIyBUYWJsYQ0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQoNCmRmX2p1ZDEgPC0gZGZfanVkICU+JQ0KICBzbGljZV9tYXgoSnVkaWNhbC5FZmZlY3RpdmVuZXNzLCBuID0gMTApICU+JQ0KICBzZWxlY3QoQ291bnRyeSwgUmVnaW9uLCBXb3JsZC5SYW5rLCBSZWdpb24uUmFuaywgSnVkaWNhbC5FZmZlY3RpdmVuZXNzKSAlPiUNCiAgcmVuYW1lKCJQYcOtcyIgPSBDb3VudHJ5LCAiUmVnacOzbiIgPSBSZWdpb24sICJSYW5raW5nIG11bmRpYWwiID0gV29ybGQuUmFuaywgIlJhbmtpbmcgcmVnaW9uYWwiID0gUmVnaW9uLlJhbmssICJFZmVjdGl2aWRhZCBqdWRpY2lhbCIgPSBKdWRpY2FsLkVmZmVjdGl2ZW5lc3MpDQoNCg0Ka25pdHI6OmthYmxlKGRmX2p1ZDEsIA0KICAgICAgICAgICAgIGFsaWduID0gImMiLCANCiAgICAgICAgICAgICBjYXB0aW9uID0gIlRvcCAxMCBwYWlzZXMgY29uIG1heW9yIGVmZWN0aXZpZGFkIGp1ZGljaWFsIiwNCiAgICAgICAgICAgICBkaWdpdHMgPSAyKSAlPiUNCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmaXhlZF90aGVhZCA9IGxpc3QoZW5hYmxlZCA9IFQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kID0gIndoaXRlIikpICU+JQ0KICBjb2x1bW5fc3BlYygxLCBiYWNrZ3JvdW5kID0gIndoaXRlIikNCg0KYGBgDQoNCiMjIExpYmVydGFkIGxhYm9yYWwgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KRW50cmFuIGVuIGp1ZWdvIHBhaXNlcyBhZnJpY2Fub3MgY29tbyBOYW1pYmlhIG8gTmlnZXJpYS4NClRhbWJpw6luIEVzdGFkb3MgVW5pZG9zLCBkZSBsb3MgcG9jb3MgcGHDrXNlcyBvY2NpZGVudGFsZXMgZW4gbWFudGVuZXIgc3UgdHJhZGljaW9uYWwgZmxleGliaWxpZGFkIGxhYm9yYWwsIGFzdW50byBtdXkgY3JpdGljYWRvIHBvciBsb3MgcGHDrXNlcyBldXJvcGVvcywgcXVlIGhhbiBpbXB1ZXN0byB1bmEgbWF5b3IgcmlnaWRleiAoc2FsYXJpb3MgbcOtbmltb3MsIG1heW9yZXMgaW5kZW1uaXphY2lvbmVzIHBvciBkZXNwaWRvLCBldGMpIGRlc2RlIGxvcyBhw7FvcyA3MCB5IHF1ZSBleHBsaWNhcm9uIGVsIHBlcsOtb2RvIGRlIGhpc3TDqXJlc2lzIGN1eW9zIGVmZWN0b3MgaW5jbHVzbyBhw7puIHBlcmR1cmFuLiBFcyBwb3IgZWxsbyBxdWUgc29sbyB2ZW1vcyBhIHVuIHBhw61zIGV1cm9wZW8gZW4gZWwgdG9wIDEwLg0KDQojIyMgR3LDoWZpY28NCg0KYGBge3IsIGV2YWwgPSBUUlVFfQ0KDQpkZl9sYWIgPC0gZGZfY29tcCAlPiUNCiAgc2VsZWN0KENvdW50cnksIFJlZ2lvbiwgV29ybGQuUmFuaywgUmVnaW9uLlJhbmssIExhYm9yLkZyZWVkb20pDQoNCmRmX2xhYjEgPC0gZGZfbGFiICU+JQ0KICBzbGljZV9tYXgoTGFib3IuRnJlZWRvbSwgbiA9IDEwKSAlPiUNCiAgc2VsZWN0KENvdW50cnksIFJlZ2lvbiwgV29ybGQuUmFuaywgUmVnaW9uLlJhbmssIExhYm9yLkZyZWVkb20pDQoNCiNDb252ZXJ0aXJtb3MgYSBmYWN0b3IgbGEgY29sdW1uYSBSYXrDs24NCmRmX2xhYjEkQ291bnRyeTwtZmFjdG9yKGRmX2xhYjEkQ291bnRyeSwgbGV2ZWxzID0gZGZfbGFiMSRDb3VudHJ5KQ0KDQpnZ3Bsb3QoZGZfbGFiMSwgYWVzKHkgPSBmY3RfcmV2KENvdW50cnkpLCB4ID0gTGFib3IuRnJlZWRvbSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICIjMkE3NTlGIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gTGFib3IuRnJlZWRvbSksIGhqdXN0ID0gLTAuMTUsIHNpemUgPSAzLjI1KSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAyMCksIGxpbWl0cyA9IGMoMCwgMTAwKSkgKw0KICBsYWJzKHRpdGxlID0gIlRvcCAxMCBwYWlzZXMgY29uIG1heW9yIGxpYmVydGFkIGxhYm9yYWwiLA0KICAgICAgIHN1YnRpdGxlID0gImVuIDIwMTkiLA0KICAgICAgIHggPSAiUHVudHVhY2nDs24gZW4gbGliZXJ0YWQgbGFib3JhbCIsDQogICAgICAgeSA9ICJQYcOtc2VzIikgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9MzApKQ0KDQpgYGANCg0KIyMjIFRhYmxhDQoNCmBgYHtyLCBldmFsID0gVFJVRX0NCg0KZGZfbGFiMSA8LSBkZl9sYWIgJT4lDQogIHNsaWNlX21heChMYWJvci5GcmVlZG9tLCBuID0gMTApICU+JQ0KICBzZWxlY3QoQ291bnRyeSwgUmVnaW9uLCBXb3JsZC5SYW5rLCBSZWdpb24uUmFuaywgTGFib3IuRnJlZWRvbSkgJT4lDQogIHJlbmFtZSgiUGHDrXMiID0gQ291bnRyeSwgIlJlZ2nDs24iID0gUmVnaW9uLCAiUmFua2luZyBtdW5kaWFsIiA9IFdvcmxkLlJhbmssICJSYW5raW5nIHJlZ2lvbmFsIiA9IFJlZ2lvbi5SYW5rLCAiTGliZXJ0YWQgbGFib3JhbCIgPSBMYWJvci5GcmVlZG9tKQ0KDQoNCmtuaXRyOjprYWJsZShkZl9sYWIxLCANCiAgICAgICAgICAgICBhbGlnbiA9ICJjIiwgDQogICAgICAgICAgICAgY2FwdGlvbiA9ICJUb3AgMTAgcGFpc2VzIGNvbiBtYXlvciBsaWJlcnRhZCBsYWJvcmFsIiwNCiAgICAgICAgICAgICBkaWdpdHMgPSAyKSAlPiUNCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmaXhlZF90aGVhZCA9IGxpc3QoZW5hYmxlZCA9IFQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kID0gIndoaXRlIikpICU+JQ0KICBjb2x1bW5fc3BlYygxLCBiYWNrZ3JvdW5kID0gIndoaXRlIikNCg0KYGBgDQoNCiMjIExpYmVydGFkIGZpbmFuY2llcmEgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KU2Vnw7puIGxhIGVjb25vbcOtYSBrZXluZXNpYW5hLCB1bmEgbWF5b3IgbGliZXJ0YWQgZmluYW5jaWVyYSwgeSBwb3IgdGFudG8sIHVuYSBtZW5vciBkZXNyZWd1bGFyaXphY2nDs24gcHVlZGUgbGxldmFyIGNvbnNpZ28gbGEgbWF5b3IgcHJvYmFiaWxpZGFkIGRlIGNyaXNpcyBmaW5hbmNpZXJhcy4NCkNvbiBsYSBlcmEgbGliZXJhbCBkZSBsb3MgYcOxb3MgODAsIGNvbWVuesOzIHVuIHByb2Nlc28gbGliZXJhbGl6YWRvciBkZSBsYXMgZmluYW56YXMsIGN1eW8gZm9jbyBwcmluY2lwYWwgZnVlIEVzdGFkb3MgVW5pZG9zIHkgUmVpbm8gVW5pZG8uIE11Y2hvcyBlY29ub21pc3RhcyBhZmlybWFuIHF1ZSBlc3RlIHByb2Nlc28gY29ubGxldm8gYSBsYSBjcmlzaXMgZmluYW5jaWVyYSBkZSAyMDA3LiBFc3RlIGhlY2hvIGhpem8gcXVlIGEgcG9zdGVyaW9yaSBsYSByZWd1bGFyaXphY2nDs24gc2UgaW1wbGVtZW50YXJhIGVuIG1heW9yIG1lZGlkYS4NCg0KIyMjIEdyw6FmaWNvDQoNCmBgYHtyLCBldmFsID0gVFJVRX0NCg0KZGZfZmluIDwtIGRmX2NvbXAgJT4lDQogIHNlbGVjdChDb3VudHJ5LCBSZWdpb24sIFdvcmxkLlJhbmssIFJlZ2lvbi5SYW5rLCBGaW5hbmNpYWwuRnJlZWRvbSkNCg0KZGZfZmluMSA8LSBkZl9maW4gJT4lDQogIHNsaWNlX21heChGaW5hbmNpYWwuRnJlZWRvbSwgbiA9IDEwKSAlPiUNCiAgc2VsZWN0KENvdW50cnksIFJlZ2lvbiwgV29ybGQuUmFuaywgUmVnaW9uLlJhbmssIEZpbmFuY2lhbC5GcmVlZG9tKQ0KDQojQ29udmVydGlybW9zIGEgZmFjdG9yIGxhIGNvbHVtbmEgUmF6w7NuDQpkZl9maW4xJENvdW50cnk8LWZhY3RvcihkZl9maW4xJENvdW50cnksIGxldmVscyA9IGRmX2ZpbjEkQ291bnRyeSkNCg0KZ2dwbG90KGRmX2ZpbjEsIGFlcyh5ID0gZmN0X3JldihDb3VudHJ5KSwgeCA9IEZpbmFuY2lhbC5GcmVlZG9tKSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiMyQTc1OUYiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBGaW5hbmNpYWwuRnJlZWRvbSksIGhqdXN0ID0gLTAuMTUsIHNpemUgPSAzLjI1KSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAyMCksIGxpbWl0cyA9IGMoMCwgMTAwKSkgKw0KICBsYWJzKHRpdGxlID0gIlRvcCAxMCBwYWlzZXMgY29uIG1heW9yIGxpYmVydGFkIGZpbmFuY2llcmEiLA0KICAgICAgIHN1YnRpdGxlID0gImVuIDIwMTkiLA0KICAgICAgIHggPSAiUHVudHVhY2nDs24gZW4gbGliZXJ0YWQgZmluYW5jaWVyYSIsDQogICAgICAgeSA9ICJQYcOtc2VzIikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9MzApKSArIA0KICB0aGVtZV9jbGFzc2ljKCkNCg0KYGBgDQoNCiMjIyBUYWJsYQ0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQoNCmRmX2ZpbjEgPC0gZGZfZmluICU+JQ0KICBzbGljZV9tYXgoRmluYW5jaWFsLkZyZWVkb20sIG4gPSAxMCkgJT4lDQogIHNlbGVjdChDb3VudHJ5LCBSZWdpb24sIFdvcmxkLlJhbmssIFJlZ2lvbi5SYW5rLCBGaW5hbmNpYWwuRnJlZWRvbSkgJT4lDQogIHJlbmFtZSgiUGHDrXMiID0gQ291bnRyeSwgIlJlZ2nDs24iID0gUmVnaW9uLCAiUmFua2luZyBtdW5kaWFsIiA9IFdvcmxkLlJhbmssICJSYW5raW5nIHJlZ2lvbmFsIiA9IFJlZ2lvbi5SYW5rLCAiTGliZXJ0YWQgZmluYW5jaWVyYSIgPSBGaW5hbmNpYWwuRnJlZWRvbSkNCg0KDQprbml0cjo6a2FibGUoZGZfZmluMSwgDQogICAgICAgICAgICAgYWxpZ24gPSAiYyIsIA0KICAgICAgICAgICAgIGNhcHRpb24gPSAiVG9wIDEwIHBhaXNlcyBjb24gbWF5b3IgbGliZXJ0YWQgZmluYW5jaWVyYSIsDQogICAgICAgICAgICAgZGlnaXRzID0gMikgJT4lDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZml4ZWRfdGhlYWQgPSBsaXN0KGVuYWJsZWQgPSBULCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZCA9ICJ3aGl0ZSIpKSAlPiUNCiAgY29sdW1uX3NwZWMoMSwgYmFja2dyb3VuZCA9ICJ3aGl0ZSIpDQoNCmBgYA0KDQojIEFuw6FsaXNpcyBkZSBsb3MgcGFpc2VzIHBvciByZWdpb25lcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfSANCg0KVmVtb3MgcXVlIGxhIHJlZ2nDs24gY29uIG1heW9yIGxpYmVydGFkIGVjb27Ds21pY2EsIHkgcG9yIHRhbnRvLCBjb24gbWF5b3IgbWVkaWEgZW4gZXN0ZSDDrW5kaWNlIGVzIEV1cm9wYS4NCg0KTGEgRnVuZGFjacOzbiBIZXJpdGFnZSBpbmZvcm1hIHF1ZSBlbCAyMCUgc3VwZXJpb3IgZW4gZWwgw61uZGljZSB0aWVuZSBlbCBkb2JsZSBkZWwgaW5ncmVzbyBwZXIgY8OhcGl0YSBxdWUgYXF1ZWxsb3MgZW4gZWwgc2VndW5kbyBxdWludGlsLCB5IGNpbmNvIHZlY2VzIGVsIGRlbCAyMCUgaW5mZXJpb3IuDQoNCiMjIEdyw6FmaWNvDQoNCmBgYHtyLCBldmFsID0gVFJVRX0NCg0KIyBDb2dlbW9zIGVsIHRvcCA1IGRlIGNhZGEgcmVnacOzbg0KDQpkZl9tYXggPC0gZGYgJT4lDQogIGdyb3VwX2J5KFJlZ2lvbikgJT4lDQogIHNsaWNlX21heChTY29yZV8yMDE5LCBuID0gNSkgJT4lDQogIHNlbGVjdChDb3VudHJ5LCBSZWdpb24sIFJlZ2lvbi5SYW5rLCBTY29yZV8yMDE5LCBHcmFkb19saWJlcnRhZCkNCg0KZGZfbWF4JENvdW50cnk8LWZhY3RvcihkZl9tYXgkQ291bnRyeSwgbGV2ZWxzID0gZGZfbWF4JENvdW50cnkpDQoNCm15X2NvbG9ycyA8LSBjKCcjZTQxYTFjJywnIzM3N2ViOCcsJyM0ZGFmNGEnLCcjOTg0ZWEzJywnI2ZmN2YwMCcpDQoNCmggPC0gZ2dwbG90KGRmX21heCwgYWVzKHkgPSBmY3RfcmV2KENvdW50cnkpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gU2NvcmVfMjAxOSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gUmVnaW9uKSkgKyANCiAgZ2VvbV9jb2woKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG15X2NvbG9ycykgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMjApLCBsaW1pdHMgPSBjKDAsIDEwMCkpICsNCiAgbGFicyh0aXRsZSA9ICLDjW5kaWNlIGRlIGxpYmVydGFkIGVjb27Ds21pY2EgcG9yIHJlZ2lvbmVzIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJUb3AgNSBwb3IgcmVnaW9uIiwNCiAgICAgICB5ID0gIlBhw61zIiwNCiAgICAgICB4ID0gIlB1bnR1YWNpw7NuIGVuIDIwMTkiKSArDQogIHRoZW1lX2NsYXNzaWMoKQ0KDQpoDQoNCmBgYA0KDQojIyBUYWJsYQ0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQpkZl9tYXggPC0gZGYgJT4lDQogIGdyb3VwX2J5KFJlZ2lvbikgJT4lDQogIHNsaWNlX21heChTY29yZV8yMDE5LCBuID0gNSkgJT4lDQogIHNlbGVjdChDb3VudHJ5LCBSZWdpb24sIFJlZ2lvbi5SYW5rLCBTY29yZV8yMDE5LCBHcmFkb19saWJlcnRhZCkgJT4lDQogIHJlbmFtZSgiUGHDrXMiID0gQ291bnRyeSwgIlJlZ2nDs24iID0gUmVnaW9uLCAiUmFua2luZyByZWdpb25hbCIgPSBSZWdpb24uUmFuaywgIlB1bnR1YWNpw7NuIiA9IFNjb3JlXzIwMTksICJHcmFkbyBkZSBsaWJlcnRhZCIgPSBHcmFkb19saWJlcnRhZCkNCg0KZ3RfbWF4PC0gZ3QoZGZfbWF4KSAlPiUgDQogIHRhYl9oZWFkZXIodGl0bGUgPSBtZCgiKipUb3AgNSBwb3IgcmVnaW9uZXMqKiIpLA0KICAgICAgICAgICAgIHN1YnRpdGxlID0gImVuIDIwMTkiKSANCg0KZ3RfbWF4DQoNCmBgYA0KDQojIyBCb3gtcGxvdA0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQoNCm15X3BhbGV0dGUgPC0gYygnIzFiOWU3NycsJyNkOTVmMDInLCcjNzU3MGIzJywnI2U3Mjk4YScsJyM2NmE2MWUnKQ0KDQpkZl9yZWdpb25lcyA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkoUmVnaW9uKSAlPiUNCiAgc2VsZWN0KENvdW50cnksIFJlZ2lvbiwgUmVnaW9uLlJhbmssIFNjb3JlXzIwMTksIEdyYWRvX2xpYmVydGFkKQ0KDQoNCnA1IDwtIGdncGxvdChkZl9yZWdpb25lcywgYWVzKHggPSBSZWdpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gU2NvcmVfMjAxOSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSBSZWdpb24pKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjE1LCBhbHBoYSA9IDAuMiwgY29sb3IgPSAidG9tYXRvIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBteV9wYWxldHRlKSArDQogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAyMCksIGxpbWl0cyA9IGMoMCwgMTAwKSkgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIlB1bnR1YWNpw7NuIHBvciByZWdpb25lcyIsDQogICAgICAgc3VidGl0bGUgPSAiZW4gMjAxOSIsDQogICAgICAgeCA9ICJSZWdpw7NuIiwNCiAgICAgICB5ID0gIlB1bnR1YWNpw7NuIikgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEpKSANCg0KcDUNCg0KYGBgDQoNCg0KIyMgTWFwYQ0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQp3b3JsZCA8LSBuZV9jb3VudHJpZXMoc2NhbGUgPSAibWVkaXVtIiwgcmV0dXJuY2xhc3MgPSAic2YiKQ0Kd29ybGQgPC0gd29ybGQgJT4lIGZpbHRlcihzdWJyZWdpb24gIT0gIkFudGFyY3RpY2EiKSAlPiUgZmlsdGVyKGFkbWluICE9ICJHcmVlbmxhbmQiKQ0Kd29ybGQgPC0gd29ybGQgJT4lIHNlbGVjdChuYW1lLCBpc29fYTMsIGdlb21ldHJ5KQ0KDQpkZl9qb2luIDwtIGxlZnRfam9pbiAoZGYsIHdvcmxkLCBieSA9IGMoIkNvdW50cnkiID0gIm5hbWUiKSkNCg0KZGZfd29ybGQgPC0gZGZfam9pbiAlPiUNCiAgbXV0YXRlKFNjb3JlXzIwMTlfNSA9IG50aWxlKFNjb3JlXzIwMTksIDUpKSAlPiUNCiAgc2VsZWN0KENvdW50cnksIFJlZ2lvbiwgV29ybGQuUmFuaywgUmVnaW9uLlJhbmssIFNjb3JlXzIwMTksIFNjb3JlXzIwMTlfNSwgZ2VvbWV0cnkpDQoNCmdnIDwtIGdncGxvdChkZl93b3JsZCwgYWVzKGZpbGwgPSBTY29yZV8yMDE5LCBnZW9tZXRyeSA9IGdlb21ldHJ5KSkgKw0KICBnZW9tX3NmKCkgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KCJQdW50dWFjacOzbiIsIGhpZ2ggPSAiIzk5MzQwNCIsIGxvdyA9ICIjZmZmZmQ0IiwgYnJlYWtzID0gc2VxKDIwLDEwMCwgMjApLCBsaW1pdHMgPSBjKDIwLDEwMCkpICsgDQogIGxhYnModGl0bGUgPSAiw41uZGljZSBkZSBsaWJlcnRhZCBlY29uw7NtaWNhIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJlbiAyMDE5IiwNCiAgICAgICBjYXB0aW9uID0gIkxvcyBwYWlzZXMgZW4gYmxhbmNvIG5vIHRpZW5lbiBkYXRvcyIpICArIA0KICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiaXRhbGljIiksDQogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gIml0YWxpYyIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIsDQogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUobGluZXR5cGUgPSAiYmxhbmsiKSwNCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJ3aGl0ZSIpKQ0KDQpnZw0KDQpgYGANCg0KIyMgTWVkaWEgcmVnaW9uYWwNCg0KYGBge3IsIGV2YWwgPSBUUlVFfQ0KDQpkZl9yZWcgPC0gZGYgJT4lDQogIGdyb3VwX2J5KFJlZ2lvbikgJT4lDQogIHN1bW1hcmlzZShNZWRpYSA9IG1lYW4oU2NvcmVfMjAxOSkpICU+JQ0KICBhcnJhbmdlKGRlc2MoTWVkaWEpKSAlPiUNCiAgc2VsZWN0KFJlZ2lvbiwgTWVkaWEpDQoNCmd0X3JlZyA8LSBndChkZl9yZWcpICU+JSANCiAgdGFiX2hlYWRlcih0aXRsZSA9IG1kKCIqKlB1bnR1YWNpw7NuIG1lZGlhIHJlZ2lvbmFsIGVuIGVsIMOtbmRpY2UgZGUgbGliZXJ0YWQgZWNvbsOzbWljYSoqIiksDQogICAgICAgICAgICAgc3VidGl0bGUgPSAiZW4gMjAxOSIpIA0KDQpndF9yZWcNCg0KYGBgDQoNCg0KIyBQdW50dWFjacOzbiB5IFBJQiBwZXIgY8OhcGl0YSAgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KTGEgRnVuZGFjacOzbiBIZXJpdGFnZSBpbmZvcm1hIHF1ZSBlbCAyMCUgc3VwZXJpb3IgZW4gZWwgw61uZGljZSB0aWVuZSBlbCBkb2JsZSBkZWwgaW5ncmVzbyBwZXIgY8OhcGl0YSBxdWUgYXF1ZWxsb3MgZW4gZWwgc2VndW5kbyBxdWludGlsLCB5IGNpbmNvIHZlY2VzIGVsIGRlbCAyMCUgaW5mZXJpb3IsIHBvciBsbyB0YW50byBoYXkgdW5hIGNvcnJlbGFjacOzbiBwb3NpdGl2YSBlbnRyZSBsaWJlcnRhZCBlY29uw7NtaWNhIHkgZGVzYXJyb2xsby4gUXVlcmVtb3MgY29tcHJvYmFyIGVzdG8uDQoNClNlIHB1ZWRlIG9ic2VydmFyIHF1ZSBsb3MgcGHDrXNlcyBjb24gbWF5b3IgbGliZXJ0YWQgZWNvbsOzbWljYSB0aWVuZW4gdW4gbWF5b3IgUElCIHBlciBjw6FwaXRhIGVuIHTDqXJtaW5vcyBtZWRpb3MsIGV4Y2VwdG8gcGFyYSBlbCBjYXNvIGRlIGxhIHJlZ2nDs24gZGUgT3JpZW50ZSBNZWRpbyB5IE5vcnRlIGRlIMOBZnJpY2EsIHF1ZSBwb3NlZW4gbcOhcyBQSUIgcGVyIGPDoXBpdGEgcXVlIGxvcyBwYcOtc2VzIGV1cm9wZW9zLCBwb3IgZWwgbmVnb2NpbyBkZWwgcGV0csOzbGVvLg0KDQojIyBHcsOhZmljbw0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQoNCmRmIDwtIGRmDQoNCmYgPC0gZ2dwbG90KGRmLCBhZXMoR0RQX2NhcGl0YSwNCiAgICAgICAgICAgICAgIFNjb3JlXzIwMTksDQogICAgICAgICAgICAgICBhbHBoYSA9IDAuNSkpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBDb3VudHJ5KSkgKw0KICBnZW9tX3Ntb290aChmb3JtdWxhID0geSB+IHgsIG1ldGhvZCA9ICJsbSIpICsNCiAgbGFicyh0aXRsZSA9ICJSZWxhY2nDs24gUElCIHBlciBjw6FwaXRhIHkgbGliZXJ0YWQgZWNvbsOzbWljYSIsDQogICAgICAgc3VidGl0bGUgPSAiZW4gMjAxOSIsDQogICAgICAgeCA9ICJQSUIgcGVyIGPDoXBpdGEiLA0KICAgICAgIHkgPSAiTGliZXJ0YWQgZWNvbsOzbWljYSIpICsgDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEpKQ0KDQpmDQoNCiNjb24gZ2dwbG90bHkgbm8gc2FsZSBlbCBncsOhZmljbw0KDQpgYGANCg0KIyMgTWVkaWEgUElCIHBlciBjw6FwaXRhIHBvciByZWdpb25lcw0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQoNCmRmX2dkcCA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkoUmVnaW9uKSAlPiUNCiAgc3VtbWFyaXNlKG1lZGlhX0dEUF9jYXBpdGEgPSBtZWFuKEdEUF9jYXBpdGEpKSAlPiUNCiAgYXJyYW5nZShkZXNjKG1lZGlhX0dEUF9jYXBpdGEpKQ0KDQpkZl9nZHAkUmVnaW9uIDwtIGZhY3RvcihkZl9nZHAkUmVnaW9uLCBsZXZlbHMgPSBkZl9nZHAkUmVnaW9uKQ0KDQpteV9jb2xvcnMgPC0gYygnI2U0MWExYycsJyMzNzdlYjgnLCcjNGRhZjRhJywnIzk4NGVhMycsJyNmZjdmMDAnKQ0KDQpnIDwtIGdncGxvdChkZl9nZHAsIGFlcyh5ID0gZmN0X3JldihSZWdpb24pLA0KICAgICAgICAgICAgICAgICAgIHggPSBtZWRpYV9HRFBfY2FwaXRhLA0KICAgICAgICAgICAgICAgICAgIGZpbGwgPSBSZWdpb24pKSArDQogIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbXlfY29sb3JzKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNDUwMDAsIDUwMDApLCBsaW1pdHMgPSBjKDAsIDQ1MDAwKSkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobWVkaWFfR0RQX2NhcGl0YSwgZGlnaXRzID0gMCkpLCBoanVzdCA9IC0wLjEwLCBzaXplID0gMy4yNSkgKw0KICBsYWJzKHRpdGxlID0gIlBJQiBwZXIgY8OhcGl0YSBtZWRpbyBwb3IgcmVnaW9uZXMiLA0KICAgICAgIHN1YnRpdGxlID0gImVuIDIwMTkiLA0KICAgICAgIHkgPSAiUmVnacOzbiIsDQogICAgICAgeCA9ICJQSUIgcGVyIGPDoXBpdGEgbWVkaW8iKSArIA0KICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSkpICsNCiAgdGhlbWVfY2xhc3NpYygpDQpnDQoNCmBgYA0KDQojIyBNZWRpYSBkZSBsYSBwdW50dWFjacOzbiBwb3IgcmVnaW9uZXMNCg0KYGBge3IsIGV2YWwgPSBUUlVFfQ0KDQpkZl9wdW50dWFjaW9uIDwtIGRmICU+JQ0KICBncm91cF9ieShSZWdpb24pICU+JQ0KICBzdW1tYXJpc2UobWVkaWFfc2NvcmVfMjAxOSA9IG1lYW4oU2NvcmVfMjAxOSkpICU+JQ0KICBhcnJhbmdlKGRlc2MobWVkaWFfc2NvcmVfMjAxOSkpDQogIA0KZGZfcHVudHVhY2lvbiRSZWdpb24gPC0gZmFjdG9yKGRmX3B1bnR1YWNpb24kUmVnaW9uICxsZXZlbHMgPSBkZl9wdW50dWFjaW9uJFJlZ2lvbikNCg0KZ2dwbG90KGRmX3B1bnR1YWNpb24sIGFlcyh4ID0gbWVkaWFfc2NvcmVfMjAxOSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IGZjdF9yZXYoUmVnaW9uKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IFJlZ2lvbikpICsNCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQobWVkaWFfc2NvcmVfMjAxOSwgZGlnaXRzID0gMikpLCBoanVzdCA9IC0wLjEwLCBzaXplID0gMy4yNSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBteV9jb2xvcnMpICsNCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDQwLCA3MCkpICsNCiAgbGFicyh0aXRsZSA9ICJQdW50dWFjacOzbiBtZWRpYSBwb3IgcmVnaW9uZXMiLA0KICAgICAgIHN1YnRpdGxlID0gImVuIDIwMTkiLA0KICAgICAgIHkgPSAiUmVnacOzbiIsDQogICAgICAgeCA9ICJQdW50dWFjacOzbiBtZWRpYSIpICsgDQogIHRoZW1lX2NsYXNzaWMoKSArDQogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BKSkNCg0KZGZfam9pbiA8LSBsZWZ0X2pvaW4oZGZfcHVudHVhY2lvbiwgZGZfZ2RwLCBieSA9ICJSZWdpb24iKSAlPiUNCiAgYXJyYW5nZShkZXNjKG1lZGlhX3Njb3JlXzIwMTkpKQ0KDQpgYGANCg0KIyMgVGFibGENCg0KYGBge3IsIGV2YWwgPSBUUlVFfQ0KDQpkZl9nZHAgPC0gZGYgJT4lDQogIGdyb3VwX2J5KFJlZ2lvbikgJT4lDQogIHN1bW1hcmlzZShtZWRpYV9HRFBfY2FwaXRhID0gbWVhbihHRFBfY2FwaXRhKSkNCg0KZGZfcHVudHVhY2lvbiA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkoUmVnaW9uKSAlPiUNCiAgc3VtbWFyaXNlKG1lZGlhX3Njb3JlXzIwMTkgPSBtZWFuKFNjb3JlXzIwMTkpKQ0KDQpkZl9qb2luIDwtIGxlZnRfam9pbihkZl9wdW50dWFjaW9uLCBkZl9nZHAsIGJ5ID0gIlJlZ2lvbiIpICU+JQ0KICBhcnJhbmdlKGRlc2MobWVkaWFfc2NvcmVfMjAxOSkpICU+JQ0KICByZW5hbWUoIlJlZ2nDs24iID0gUmVnaW9uLA0KICAiUHVudHVhY2nDs24gbWVkaWEiID0gbWVkaWFfc2NvcmVfMjAxOSwNCiAgIlBJQiBwZXIgY8OhcGl0YSBtZWRpbyIgPSBtZWRpYV9HRFBfY2FwaXRhKQ0KDQprbml0cjo6a2FibGUoZGZfam9pbiwgDQogICAgICAgICAgICAgYWxpZ24gPSAiYyIsIA0KICAgICAgICAgICAgIGNhcHRpb24gPSAiUHVudHVhY2nDs24geSBQSUIgcGVyIGPDoXBpdGEgbWVkaW9zIHBvciByZWdpb25lcyIsDQogICAgICAgICAgICAgZGlnaXRzID0gMikgJT4lDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZml4ZWRfdGhlYWQgPSBsaXN0KGVuYWJsZWQgPSBULCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZCA9ICJ3aGl0ZSIpKSAlPiUNCiAgY29sdW1uX3NwZWMoMSwgYmFja2dyb3VuZCA9ICJ3aGl0ZSIpDQoNCmBgYA0KDQojIEJpYmxpb2dyYWbDrWENCg0KW0thZ2dsZV0oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9sZXdpc2R1bmNhbjkzL3RoZS1lY29ub21pYy1mcmVlZG9tLWluZGV4P3NlbGVjdD1lY29ub21pY19mcmVlZG9tX2luZGV4MjAxOV9kYXRhLmNzdikNCg0KW1R1dG9yaWFsZXMgZGUgbGEgYXNpZ25hdHVyYV0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjEtMjItd2ViLzA0LXR1dG9yaWFsZXMuaHRtbCkNCg0KW1RoZSBIZXJpdGFnZSBGb3VuZGF0aW9uICgyMDE5KTogV29ybGQgRWNvbm9taWMgRnJlZWRvbSBJbmRleF0oaHR0cHM6Ly93d3cuaGVyaXRhZ2Uub3JnL2luZGV4LykNCg0KaHR0cHM6Ly9ycHVicy5jb20NCg0KaHR0cHM6Ly9jb2xvcmJyZXdlcjIub3JnDQoNCjxicj48YnI+DQoNCmBgYHtyLCBlY2hvID0gRkFMU0V9DQpzZXNzaW9uaW5mbzo6c2Vzc2lvbl9pbmZvKCkgJT4lIGRldGFpbHM6OmRldGFpbHMoc3VtbWFyeSA9ICdJbmZvcm1hY2nDs24gZGUgbWkgUi1zZXNpw7NuOicpIA0KYGBgDQoNCg0KPGJyPjxicj4NCg0KPGRpdiBjbGFzcz0idG9jaWZ5LWV4dGVuZC1wYWdlIiBkYXRhLXVuaXF1ZT0idG9jaWZ5LWV4dGVuZC1wYWdlIiBzdHlsZT0iaGVpZ2h0OiAwOyI+PC9kaXY+DQo8YnI+PGJyPg0KDQo8ZGl2IGNsYXNzPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIGRhdGEtdW5pcXVlPSJ0b2NpZnktZXh0ZW5kLXBhZ2UiIHN0eWxlPSJoZWlnaHQ6IDA7Ij48L2Rpdj4NCg==