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 2020-2021. El repo del trabajo está aquí. La página web de la asignatura y los trabajos de mis compañeros pueden verse aquí.

1. Introducción

Si preguntaramos a cualquier persona “entendida” en economía sobre como poder determinar el nivel de desarrollo de los países, nos remitiría casi con total seguridad al PIB de cada uno de éstos. Podemos definir el PIB per capita como la relación entre el valor total de todos los bienes y servicios finales generados durante un año por la economía de una nación o estado y el número de sus habitantes en ese año1. Este instrumento ha sido, durante décadas, el más utilizado por los economistas para estudiar la evolución económica de los países.

¿Pero es capaz de medir el PIB per cápita, por si solo, el grado de desarrollo de un país y el bienestar de sus habitantes? Hoy en día existe un consenso entre los principales economistas (Joseph Stiglitz, Amartya Sen, Jean-Paul Fitoss, etc.) sobre la poca fiabilidad del PIB como indicador único para medir el progreso económico y social de una nación.

El Índice para una Vida Mejor (en inglés, Better Life Index, o BLI) es un índice económico-social creado por la OCDE en 2011. Este índice permite a las personas comparar el nivel de desarrollo de los países que integran la OCDE a través de 11 criterios considerados como esenciales para el bienestar de la población.

Esta iniciativa se apoya en el informe de la Comisión Stiglitz-Sen-Fitoussi sobre la medición del rendimiento económico y del progreso social. Si alguien está interesado en saber las principales recomendaciones del informe puede verlas aquí.

El Índice, como hemos dicho anteriormente, comprende los 34 países miembros de la Organización para la Cooperación y el Desarrollo Económicos (OCDE) –la cual reúne a la mayoría de las economías desarrolladas del mundo y varias economías emergentes–, y algunos más.

En este trabajo vamos a reducir el círculo de países que integran este índice, a los países europeos que son miembros de la OCDE para que las gráficas sea más simples y podamos observar mejor los datos. Compararemos el nivel de ingresos de los ciudadanos de los países con otros indicadores (educación, nivel de empleo,satisfacción ante la vida,…etc.) de este índice para ver si existe una relación econónomica entre ellos, es decir, si aquellos países más ricos, tienen mayores niveles de bienestar social y económico.

2. Datos

Obtener los datos es una tarea relativamente sencilla. Accediendo a la página web del proyecto betterlifeindex, se puede descargar fácilmente los datos, entrando en la sección descarga los datos del índice.

#Cargo los paquetes
library(tidyverse)
library(klippy)  
library(knitr)
library(tibble)
library(ggthemes)
library(ggplot2)
library(dplyr)
library(patchwork)
library(ggrepel)
library(sf)
library(ggspatial)
library(rnaturalearth)
library(rnaturalearthdata)
library(pjpv2020.01)
library(plotly)
library(gganimate)
library (gifski)
library(gt)
library(kableExtra)
library(DT)
library(rio)
library(leaflet) 
library(leafem)
library(formattable)
library(lubridate)
library(echarts4r)

#Cargo los datos previamente descargados de la página de la OCDE
df <- rio::import("./datos/calidadvida2.xlsx")

#Fijo los nombres de las columnas
names(df)[1] <- "Paises"
names(df)[2] <- "Vivienda_sin_instalaciones_basicas"
names(df)[3] <- "Gasto_en_vivienda"
names(df)[4] <- "Habitaciones_por_persona"
names(df)[5] <- "Ingreso_familiar_disponible"
names(df)[6] <- "Patrimonio_familia"
names(df)[7] <- "Inseguridad_en_empleo"
names(df)[8] <- "Tasa_empleo"
names(df)[9] <- "Tasa_empleo_LP"
names(df)[10] <- "Ingresos_personales"
names(df)[11] <- "Calidad_apoyo_social"
names(df)[12] <- "Nivel_educacion"
names(df)[13] <- "Habilidades_de_estudiantes"
names(df)[14] <- "Años_de_educación"
names(df)[15] <- "Contaminacion_aire"
names(df)[16] <- "Calidad_agua"
names(df)[17] <- "Participacion_regulaciones"
names(df)[18] <- "Participacion_electoral"
names(df)[19] <- "Esperanza_vida"
names(df)[20] <- "Salud"
names(df)[21] <- "Satisfaccion_vida"
names(df)[22] <- "Seguridad_caminar_solos_noche"
names(df)[23] <- "Tasa_homicidios"
names(df)[24] <- "Empleados_trabajan_muchas"
names(df)[25] <- "Tiempo_ocio"

#Elimino los países que no son de la OCDE y la primera columna porque ya no los necesito.
df1 <- df %>% slice(2:39)

#Compruebo la estructura de datos de mi tabla para ver si son datos númericos y puedo trabajar con ellos
str(df1)
#> 'data.frame':    38 obs. of  25 variables:
#>  $ Paises                            : chr  "Australia" "Austria" "Belgium" "Canada" ...
#>  $ Vivienda_sin_instalaciones_basicas: chr  ".." "0.9" "1.9" "0.2" ...
#>  $ Gasto_en_vivienda                 : chr  "20" "21" "21" "22" ...
#>  $ Habitaciones_por_persona          : chr  ".." "1.6" "2.2000000000000002" "2.6" ...
#>  $ Ingreso_familiar_disponible       : chr  "32759" "33541" "30364" "30854" ...
#>  $ Patrimonio_familia                : chr  "427064" "308325" "386006" "423849" ...
#>  $ Inseguridad_en_empleo             : chr  "5.4" "3.5" "3.7" "6" ...
#>  $ Tasa_empleo                       : chr  "73" "72" "63" "73" ...
#>  $ Tasa_empleo_LP                    : chr  "1.31" "1.84" "3.54" "0.77" ...
#>  $ Ingresos_personales               : chr  "49126" "50349" "49675" "47622" ...
#>  $ Calidad_apoyo_social              : chr  "95" "92" "91" "93" ...
#>  $ Nivel_educacion                   : chr  "81" "85" "77" "91" ...
#>  $ Habilidades_de_estudiantes        : chr  "502" "492" "503" "523" ...
#>  $ Años_de_educación                 : chr  "21" "17" "19.3" "17.3" ...
#>  $ Contaminacion_aire                : chr  "5" "16" "15" "7" ...
#>  $ Calidad_agua                      : chr  "93" "92" "84" "91" ...
#>  $ Participacion_regulaciones        : chr  "2.7" "1.3" "2" "2.9" ...
#>  $ Participacion_electoral           : chr  "91" "80" "89" "68" ...
#>  $ Esperanza_vida                    : chr  "82.5" "81.7" "81.5" "81.900000000000006" ...
#>  $ Salud                             : chr  "85" "70" "74" "88" ...
#>  $ Satisfaccion_vida                 : chr  "7.3" "7.1" "6.9" "7.4" ...
#>  $ Seguridad_caminar_solos_noche     : chr  "63.5" "80.599999999999994" "70.099999999999994" "82.2" ...
#>  $ Tasa_homicidios                   : chr  "1.1000000000000001" "0.5" "1" "1.3" ...
#>  $ Empleados_trabajan_muchas         : chr  "13.04" "6.66" "4.75" "3.69" ...
#>  $ Tiempo_ocio                       : chr  "14.35" "14.55" "15.7" "14.56" ...

#Transformo los datos (a datos numéricos) para poder trabajar con ellos.
#Da warnings porque la tabla no contiene algunos datos para algunos países. Quiere decir que donde
#haya datos, pondrá NA´s.
df2 <- df1 %>% mutate(Vivienda_sin_instalaciones_basicas = as.numeric(Vivienda_sin_instalaciones_basicas))
df3 <- df2 %>% mutate(Gasto_en_vivienda = as.numeric(Gasto_en_vivienda))
df4 <- df3 %>% mutate(Habitaciones_por_persona = as.numeric(Habitaciones_por_persona))
df5 <- df4 %>% mutate(Ingreso_familiar_disponible = as.numeric(Ingreso_familiar_disponible))
df6 <- df5 %>% mutate(Patrimonio_familia = as.numeric(Patrimonio_familia))
df7 <- df6 %>% mutate(Inseguridad_en_empleo = as.numeric(Inseguridad_en_empleo))
df8 <- df7 %>% mutate(Tasa_empleo = as.numeric(Tasa_empleo))
df9 <- df8 %>% mutate(Nivel_educacion = as.numeric(Nivel_educacion))
df10 <- df9 %>% mutate(Habilidades_de_estudiantes = as.numeric(Habilidades_de_estudiantes))
df11 <- df10 %>% mutate(Años_de_educación = as.numeric(Años_de_educación))
df12 <- df11 %>% mutate(Contaminacion_aire = as.numeric(Contaminacion_aire))
df13 <- df12 %>% mutate(Calidad_agua = as.numeric(Calidad_agua))
df14 <- df13 %>% mutate(Participacion_regulaciones = as.numeric(Participacion_regulaciones))
df15 <- df14 %>% mutate(Participacion_electoral = as.numeric(Participacion_electoral))
df16 <- df15 %>% mutate(Esperanza_vida = as.numeric(Esperanza_vida))
df17 <- df16 %>% mutate(Salud = as.numeric(Salud))
df18 <- df17 %>% mutate(Satisfaccion_vida = as.numeric(Satisfaccion_vida))
df19 <- df18 %>% mutate(Seguridad_caminar_solos_noche = as.numeric(Seguridad_caminar_solos_noche))
df20 <- df19 %>% mutate(Tasa_homicidios = as.numeric(Tasa_homicidios))
df21 <- df20 %>% mutate(Empleados_trabajan_muchas = as.numeric(Empleados_trabajan_muchas))
df22 <- df21 %>% mutate(Tiempo_ocio = as.numeric(Tiempo_ocio))
df23 <- df22 %>% mutate(Tasa_empleo_LP = as.numeric(Tasa_empleo_LP))
df24 <- df23 %>% mutate(Ingresos_personales = as.numeric(Ingresos_personales))
df25 <- df24 %>% mutate(Calidad_apoyo_social = as.numeric(Calidad_apoyo_social))

#Compruebo que todo haya salido bien.
str(df25)
#> 'data.frame':    38 obs. of  25 variables:
#>  $ Paises                            : chr  "Australia" "Austria" "Belgium" "Canada" ...
#>  $ Vivienda_sin_instalaciones_basicas: num  NA 0.9 1.9 0.2 9.4 23.9 0.7 0.5 7 0.5 ...
#>  $ Gasto_en_vivienda                 : num  20 21 21 22 18 17 24 23 17 23 ...
#>  $ Habitaciones_por_persona          : num  NA 1.6 2.2 2.6 1.2 1.2 1.4 1.9 1.6 1.9 ...
#>  $ Ingreso_familiar_disponible       : num  32759 33541 30364 30854 NA ...
#>  $ Patrimonio_familia                : num  427064 308325 386006 423849 100967 ...
#>  $ Inseguridad_en_empleo             : num  5.4 3.5 3.7 6 8.7 NA 3.1 4.2 3.8 3.9 ...
#>  $ Tasa_empleo                       : num  73 72 63 73 63 67 74 74 74 70 ...
#>  $ Tasa_empleo_LP                    : num  1.31 1.84 3.54 0.77 NA 0.79 1.04 1.31 1.92 2.13 ...
#>  $ Ingresos_personales               : num  49126 50349 49675 47622 25879 ...
#>  $ Calidad_apoyo_social              : num  95 92 91 93 85 89 91 95 92 95 ...
#>  $ Nivel_educacion                   : num  81 85 77 91 65 54 94 81 89 88 ...
#>  $ Habilidades_de_estudiantes        : num  502 492 503 523 443 410 491 504 524 523 ...
#>  $ Años_de_educación                 : num  21 17 19.3 17.3 17.5 14.1 17.9 19.5 17.7 19.8 ...
#>  $ Contaminacion_aire                : num  5 16 15 7 16 10 20 9 8 6 ...
#>  $ Calidad_agua                      : num  93 92 84 91 71 75 87 95 84 95 ...
#>  $ Participacion_regulaciones        : num  2.7 1.3 2 2.9 1.3 1.4 1.6 2 2.7 2.2 ...
#>  $ Participacion_electoral           : num  91 80 89 68 47 53 61 86 64 67 ...
#>  $ Esperanza_vida                    : num  82.5 81.7 81.5 81.9 79.9 76.2 79.1 80.9 77.8 81.5 ...
#>  $ Salud                             : num  85 70 74 88 57 NA 60 71 53 70 ...
#>  $ Satisfaccion_vida                 : num  7.3 7.1 6.9 7.4 6.5 6.3 6.7 7.6 5.7 7.6 ...
#>  $ Seguridad_caminar_solos_noche     : num  63.5 80.6 70.1 82.2 47.9 44.4 72.3 83.5 69 85.1 ...
#>  $ Tasa_homicidios                   : num  1.1 0.5 1 1.3 4.2 24.5 0.5 0.6 3.1 1.3 ...
#>  $ Empleados_trabajan_muchas         : num  13.04 6.66 4.75 3.69 9.72 ...
#>  $ Tiempo_ocio                       : num  14.3 14.6 15.7 14.6 NA ...

#Elimino todos los países que no esten en la UE a excepción de UK y la media de la ODCE que me servirá para comparar.
df_<- df25 %>% filter(Paises %in% c("Austria","Belgium","Bulgaria","Croatia",
                                  "Czech Republic","Denmark","Estonia","Finland","France",
                                  "Germany","Greece","Hungary","Ireland","Italy","Latvia",
                                  "Lithuania","Luxembourg","Netherlands","Poland",
                                  "Portugal","Slovak Republic","Slovenia","Spain",
                                  "Sweden","United Kingdom","Switzerland","OECD - Total"))

#Guardo lo hecho para no tener que volverlo a hacer en cada chuck.
export(df_, "./datos/calidadvida_definitivo.csv")   # comma-separated values

2.1. Procesando los datos

El procesamiento de los datos como tal ha quedado reflejado en el anterior apartado pero me gustaría hacer un breve resumen del mismo aquí:

  1. Exportar el archivo descargado de la web.
  2. Definir el nombre de las columnas.
  3. Selecciono los países pertenecientes a la OCDE como primer filtro.
  4. Comprueblo la estructura de los datos para ver si puedo trabajarlos.
  5. Al ver que no son númericos, los tengo que transformar.
  6. Filtro uno a uno los países objeto del estudio.
  7. Para no hacer todo este proceso a menudo, decido importar los datos finales en un archivo que iré cargando en adelante.

Tras todo este largo proceso, mi tabla maestra de datos queda finalizada. En este caso he optado por hacerla interactiva por si alguna persona está interesada en descargar los datos.

3. Estructura de datos del informe.

El Índice para una Vida Mejor analiza 11 variables que la OCDE ha considerado fundamentales para las condiciones de vida de las personas. A su vez dentro de estas variables se analizan distintos indicadores que sirven para evaluar dicha variable en cada uno de los países objeto de este índice.

La estructura de los datos analizados, de forma esquemática, es la siguiente:

  1. Vivienda:
  • Gasto en Vivienda
  • Vivienda con instalaciones básicas
  • Habitaciones por persona
  1. Ingresos
  • Patrimonio familiar netos
  • Ingresos familiar disponible
  1. Empleo
  • Ingresos personales
  • Seguridad en el empleo
  • Tasa de empleo a LP
  • Tasa de empleo
  1. Comunidad
  • Calidad de apoyo social
  1. Educación
  • Años de educación
  • Competencias de los estudiantes
  • Nivel de educación.
  1. Medio Ambiente
  • Calidad del agua
  • Contaminación del aire
  1. Compromiso cívico
  • Participación electoral
  • Participación de los interesados en la elaboración de regulaciones
  1. Salud
  • Esperanza de vida
  • Salud, según las personas
  1. Satisfación ante la vida
  2. Seguridad
  • Tasa de homicidios
  • Sentimiento de seguridad al caminar solos por la noche
  1. Balance vida-trabajo
  • Tiempo destinado al ocio
  • Empleados que trabajan muchas horas

4. Índice para una vida mejor.

Pasamos a analizar ahora alguna de las variables representadas en el esquema anterior para los países europeos.

La estructura del análisis será simple y repetida para cada variable analizada. Estudiaremos un indicador (ver esquema anterior) en cada una de ellas y lo relacionaremos con los ingresos personales de cada una de los países. Posteriormente construiremos una tabla, un gráfico,un mapa y el chunk con el lenguaje utilizado.

El objetivo prioritario de este trabajo es comprobar si estas variables están relacionadas directamente con los ingresos. Es decir, los países más ricos siempre tendrán valores más altos en las variables analizadas (gasto en vivienda, bienestar, empleo, …, etc.).

4.1. Vivienda: Gasto en Vivienda

4.1.1. Tabla datos.

La vivienda es un bien de primera necesidad y un derecho fundamental en la mayoría de las sociedades desarrolladas de nuestro entorno. Es una obviedad decir que si el gasto en vivienda es demasiado grande, en función de los ingresos, los individuos que integran una sociedad vivirán peor porque no podrán destinar esos ingresos a otras actividades que le reportarían mayor felicidad.

Si observamos la tabla, los ciudadanos de países como Reino Unido, República Checa, Italia o Grecia, gastan demasiado porcentaje de sus ingresos en vivienda.

Por el otro lado, los ciudadanos de Suecia, Holanda, Estonia y Eslovenia están en una posición mejor, en este indicador, que sus vecinos europeos.

Por lo que respecta a los españoles, podemos decir que nos encontramos muy cerca de la media de la OCDE en lo que respecta al porcentaje de renta que dedicamos a la vivienda.

Paises Gasto_en_vivienda Ingresos_personales
United Kingdom 26 43732
Czech Republic 24 25372
Denmark 23 51466
Finland 23 42964
Greece 23 26064
Italy 23 36658
Latvia 23 23683
Slovak Republic 23 24328
Poland 22 27046
Switzerland 22 62283
Austria 21 50349
Belgium 21 49675
France 21 43755
Luxembourg 21 63062
Portugal 21 25367
Spain 21 38507
Germany 20 47585
Ireland 20 47653
OECD - Total 20 43241
Hungary 19 22576
Lithuania 19 24287
Netherlands 19 52877
Sweden 19 42393
Slovenia 18 34933
Estonia 17 24336

4.1.2. Gráfica.

En el análisis gráfico hemos relacionado los ingresos de los ciudadanos de cada país con el porcentaje que gastan en vivienda, con el objetivo de estudiar si hay algún tipo de relación.

Como podemos comprobar visualmente, no la hay.

4.1.3. Mapa.

Si transferimos los datos de la tabla creada en el primer apartado a un mapa, queda de la siguiente manera:

4.1.4. Chunks.

En este apartado se muestran los trozos de código R (chunk) utilizados para hacer la tabla, el gráfico y el mapa. Separándolo de los demás, hace que la lectura del trabajo sea más fácil y amena.


#Así he hecho la tabla

df_ <- rio::import("./datos/calidadvida_definitivo.csv")

dfviv1 <- df_ %>% select(Paises,Gasto_en_vivienda,Ingresos_personales) %>% arrange(desc(Ingresos_personales)) 

dfviv1 <- na.omit(dfviv1)

knitr::kable(dfviv1, format = "html") %>% 
  kableExtra::kable_styling(bootstrap_options = c("striped", "hover"))

#Así he hecho el gráfico

df_ <- rio::import("./datos/calidadvida_definitivo.csv") 

dfviv1 <- df_ %>% select(Paises,Gasto_en_vivienda,Ingresos_personales) 

dfviv1 <- na.omit(dfviv1)

ggplot(dfviv1, aes(Ingresos_personales, Gasto_en_vivienda, label = Paises)) + 
  geom_point() + 
  geom_point(data = filter(dfviv1, Paises == "Spain"), colour = "pink", size = 6)+ 
  geom_point(data = filter(dfviv1, Paises == "OECD - Total"), colour = "violet", size = 6)+
  labs(title = "Relación entre ingresos y gasto en vivienda" ,
       y = "Ingresos personales (en dólares)",
       x = "Gasto en vivienda (en porcentaje)",
       caption = "Fuente OCDE")+
  geom_smooth()+ geom_label_repel()+ theme_minimal()

#Así he hecho el mapa

mapadata_UE<- map_data("world") %>% filter(region %in% c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
                                                         "Czech Republic","Denmark","Estonia","Finland","France",
                                                         "Germany","Greece","Hungary","Ireland","Italy","Latvia",
                                                         "Lithuania","Luxembourg","Malta","Netherlands","Poland",
                                                         "Portugal","Romania","Slovakia","Slovenia","Spain",
                                                         "Sweden","UK","Switzerland","Bosnia and Herzegovina","Serbia","Ukraine","Belarus","Albania","Montenegro","Kosovo","Macedonia","Moldova"))

mapadata_UE_ <- mapadata_UE %>% mutate(region = case_when(
  region == "UK" ~ "United Kingdom",
  TRUE  ~  region ))

mapdata_UE_ <- full_join (mapadata_UE_,dfviv1, by = c("region"="Paises"))

mapaplot <- ggplot(mapdata_UE_, aes(x = long, y = lat, group=group, fill = Gasto_en_vivienda) ) +
  geom_polygon(color ="#ffffff") +
  scale_fill_gradient(low = "#313200",high = "#f7ff00") +
  labs(fill="Gasto_en_vivienda",
       x=NULL,
       y=NULL,
       title="Gasto en vivienda (en porcentaje) en Europa",
       caption="Fuente: OCDE") +
  theme( plot.background = element_rect( fill = "#ffffff"),
         panel.background = element_rect( fill = "cornsilk2", colour = "lavenderblush", size = 0.1 ),
         panel.grid  = element_line( colour ="grey"),
         axis.ticks = element_blank(),
         axis.text = element_blank(),
         plot.title = element_text(hjust = 0.5),
         panel.border = element_rect(fill = NA,colour = "black"),
         legend.background = element_rect( fill = "cornsilk2", colour = "black" ),
         plot.margin = margin(t = 5, r = 5, b = 5,10) )

mapaplot + scale_fill_viridis_c(direction = -1)

4.2.Ingresos:Ing. familiares netos

4.2.1. Tabla datos.

Quizá para muchos individuos el indicador más importante del bienestar de una sociedad son el nivel de ingresos de sus ciudadanos. Pues bien, en este apartado vamos a ver que ciudadanos europeos son los más “afortunados”.

Luxemburgo, Suiza y Alemania lideran este ranking. No hay sorpresas.

Los países del este de Europa (últimos en entrar en la UE) y Grecia están a la cola.

España se encuentra en la mitad de la tabla pero muy distanciado de la media de los países que pertenecen a la OCDE.

Paises Ingreso_familiar_disponible
Luxembourg 39264
Switzerland 37466
Germany 34294
OECD - Total 33604
Austria 33541
France 31304
Sweden 31287
Belgium 30364
Finland 29943
Denmark 29606
Netherlands 29333
United Kingdom 28715
Italy 26588
Ireland 25310
Spain 23999
Lithuania 21660
Czech Republic 21453
Portugal 21203
Slovenia 20820
Slovak Republic 20474
Poland 19814
Estonia 19697
Greece 17700
Latvia 16275

4.2.2. Gráfica.

Aquí muestro la tabla del primer apartado en un gráfico de barras.

4.2.3. Mapa.

Si transferimos los datos de la tabla creada en el primer apartado a un mapa. Podemos observar que los países centroeuropeos y losdel norte de europa son los más afortunados.

4.2.4. Chunks.

En este apartado se muestran los trozos de código R (chunk) utilizados para hacer la tabla, el gráfico y el mapa. Separándolo de los demás, hace que la lectura del trabajo sea más fácil y amena.


#Así he hecho la tabla

df_ <- rio::import("./datos/calidadvida_definitivo.csv")

df_ing <- df_  %>% select(Paises,Ingreso_familiar_disponible)%>% arrange(desc(Ingreso_familiar_disponible))

df_ing <- na.omit(df_ing)

df_ing %>% gt()

#Así he hecho el gráfico

df_ <- rio::import("./datos/calidadvida_definitivo.csv")

df_ing <- df_  %>% select(Paises,Ingreso_familiar_disponible,Patrimonio_familia)

df_ing <- na.omit(df_ing)

graficoA <- ggplot(df_ing, aes(forcats::fct_reorder(Paises, Ingreso_familiar_disponible), Ingreso_familiar_disponible)) +
  geom_col(aes(fill = Ingreso_familiar_disponible))+ coord_flip()+ 
  theme(axis.text.x = element_text(angle=90, vjust=0.6), panel.background = NULL)+
  labs(title = "Ingresos familiares disponibles (en dólares)", subtitle = "Por países", caption="Fuente: OCDE") + 
  labs(x = NULL, y = NULL)+ transition_reveal(Ingreso_familiar_disponible)

graficoA + theme(legend.position = "none")

#Así he hecho el mapa

mapadata_UE<- map_data("world") %>% filter(region %in% c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
                                                         "Czech Republic","Denmark","Estonia","Finland","France",
                                                         "Germany","Greece","Hungary","Ireland","Italy","Latvia",
                                                         "Lithuania","Luxembourg","Malta","Netherlands","Poland",
                                                         "Portugal","Romania","Slovakia","Slovenia","Spain",
                                                         "Sweden","UK","Switzerland","Bosnia and Herzegovina","Serbia","Ukraine","Belarus","Albania","Montenegro","Kosovo","Macedonia","Moldova"))

mapadata_UE_ <- mapadata_UE %>% mutate(region = case_when(
  region == "UK" ~ "United Kingdom",
  TRUE  ~  region ))

mapdata_UE_ <- full_join (mapadata_UE_,df_ing, by = c("region"="Paises"))


mapaplot2 <- ggplot(mapdata_UE_, aes(x = long, y = lat, group=group, fill = Ingreso_familiar_disponible) ) +
  geom_polygon(color ="#ffffff") +
  scale_fill_gradient(low = "#313200",high = "#f7ff00") +
  labs(fill="Ingreso_familiar_disponible",
       x=NULL,
       y=NULL,
       title="Ingresos familiares netos (en dólares) en la UE",
       caption="Fuente: OCDE") +
  theme( plot.background = element_rect( fill = "#ffffff"),
         panel.background = element_rect( fill = "cornsilk2", colour = "lavenderblush", size = 0.1 ),
         panel.grid  = element_line( colour ="grey"),
         axis.ticks = element_blank(),
         axis.text = element_blank(),
         plot.title = element_text(hjust = 0.5),
         panel.border = element_rect(fill = NA,colour = "black"),
         legend.background = element_rect( fill = "cornsilk2", colour = "black" ),
         plot.margin = margin(t = 5, r = 5, b = 5,10) )

mapaplot2 + scale_fill_viridis_c(direction = -1)

4.3. Empleo: Tasa de empleo

4.3.1. Tabla datos.

“El trabajo es salud”

¿Quién no ha escuchado alguna vez este dicho? Está claro que el trabajo, es salud, no solo física, sino mental. Además proporciona ingresos fundamentales para vivir y si ofrece una buena remuneración, el acceso a la educación, salud, ocio… etc, es más fácil.

Suiza, Suecia, Holanda, Alemania y Reino Unido son los países europeos con tasas de empleo más altas.

A la cola, los países mediterráneos del sur de Europa, entre ellos España.

Paises Tasa_empleo Ingresos_personales
Switzerland 80 62283
Sweden 77 42393
Netherlands 76 52877
Germany 75 47585
United Kingdom 75 43732
Czech Republic 74 25372
Denmark 74 51466
Estonia 74 24336
Austria 72 50349
Finland 70 42964
Latvia 70 23683
Lithuania 70 24287
Slovenia 69 34933
Hungary 68 22576
Portugal 68 25367
OECD - Total 68 43241
Ireland 67 47653
Luxembourg 66 63062
Poland 66 27046
Slovak Republic 66 24328
France 65 43755
Belgium 63 49675
Spain 62 38507
Italy 58 36658
Greece 53 26064

4.3.2. Gráfica.

En el análisis gráfico hemos relacionado los ingresos de los ciudadanos de cada país con la tasa de empleo, con el objetivo de estudiar si hay algún tipo de relación. No está muy clara.

Lo que si que vemos clara es la relación existente entre la inseguridad en el empleo y la tasa de empleo. A menor tasa de empleo, mayor inseguridad (miedo a perder el empleo).

4.3.3. Mapa.

Si transferimos los datos de la tabla creada en el primer apartado a un mapa, podemos apreciar lo comentado en el primer apartado: conforme vas avanzando hacia al sur de Europa, el nivel de empleo es menor.

4.3.4. Chunks.

En este apartado se muestran los trozos de código R (chunk) utilizados para hacer la tabla, el gráfico y el mapa. Separándolo de los demás, hace que la lectura del trabajo sea más fácil y amena.


#Así he hecho la tabla

df_ <- rio::import("./datos/calidadvida_definitivo.csv")

df_empleo <- df_  %>% select(Paises,Tasa_empleo,Ingresos_personales)%>% arrange(desc(Tasa_empleo))

df_empleo <- na.omit(df_empleo)

kable(df_empleo) %>%
  kableExtra::kable_styling(fixed_thead = list(enabled = T, background = "lightblue"))

#Así he hecho el primer gráfico 

df_ <- rio::import("./datos/calidadvida_definitivo.csv")

df_empleo <- df_  %>% select(Paises,Inseguridad_en_empleo,Tasa_empleo,Tasa_empleo_LP, Ingresos_personales)

df_empleo <- na.omit(df_empleo)

ggplot(df_empleo, aes(Tasa_empleo, Inseguridad_en_empleo, label = Paises)) + 
  geom_point() + 
  geom_point(data = filter(df_empleo, Paises == "Spain"), colour = "pink", size = 6)+ 
  geom_point(data = filter(df_empleo, Paises == "OECD - Total"), colour = "violet", size = 6)+
  labs(title = "Relación entre inseguridad de empleo y tasa empleo" ,
       y = "Inseguridad en el empleo",
       x = "Tasa de empleo",
       caption = "Fuente OCDE")+
  geom_smooth()+ geom_label_repel()+ theme_minimal()

#Así he hecho el segundo gráfico 

df_ <- rio::import("./datos/calidadvida_definitivo.csv")

df_empleo <- df_  %>% select(Paises,Inseguridad_en_empleo,Tasa_empleo,Tasa_empleo_LP, Ingresos_personales)

df_empleo <- na.omit(df_empleo)
p <- ggplot(df_empleo, aes(Ingresos_personales, Tasa_empleo)) + 
  geom_point(aes(color = Paises)) + geom_point(data = filter(df_empleo, Paises == "Spain"), colour = "pink", size = 6)+ 
  geom_point(data = filter(df_empleo, Paises == "OECD - Total"), colour = "violet", size = 6)+ 
  labs(title = "Relación entre ingresos personales y tasa de empleo" ,
       y = "Tasa de empleo",
       x = "Ingresos personales (en dólares)")+
  geom_smooth()+ theme_minimal()

p+annotate(geom = "curve", x = 38507, y = 62, xend = 40000, yend = 65, 
             curvature = .3, arrow = arrow(length = unit(2, "mm"))) +
    annotate(geom = "text", x = 39000, y = 66, label = "Spain", hjust = "left")+
    annotate(geom = "curve", x = 43241, y = 68, xend = 44000, yend = 71, 
             curvature = .3, arrow = arrow(length = unit(2, "mm"))) +
    annotate(geom = "text", x = 43000, y = 72, label = "OCDE", hjust = "left")    
    
#Así he hecho el mapa

mapadata_UE<- map_data("world") %>% filter(region %in% c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
                                                         "Czech Republic","Denmark","Estonia","Finland","France",
                                                         "Germany","Greece","Hungary","Ireland","Italy","Latvia",
                                                         "Lithuania","Luxembourg","Malta","Netherlands","Poland",
                                                         "Portugal","Romania","Slovakia","Slovenia","Spain",
                                                         "Sweden","UK","Switzerland","Bosnia and Herzegovina","Serbia","Ukraine","Belarus","Albania","Montenegro","Kosovo","Macedonia","Moldova"))

mapadata_UE_ <- mapadata_UE %>% mutate(region = case_when(
  region == "UK" ~ "United Kingdom",
  TRUE  ~  region ))

mapdata_UE_ <- full_join (mapadata_UE_,df_empleo, by = c("region"="Paises"))

mapaplot <- ggplot(mapdata_UE_, aes(x = long, y = lat, group=group, fill = Tasa_empleo) ) +
  geom_polygon(color ="#ffffff") +
  scale_fill_gradient(low = "#313200",high = "#f7ff00") +
  labs(fill="Tasa_empleo",
       x=NULL,
       y=NULL,
       title="Tasa de empleo (en porcentaje) en la UE",
       caption="Fuente: OCDE") +
  theme( plot.background = element_rect( fill = "#ffffff"),
         panel.background = element_rect( fill = "cornsilk2", colour = "lavenderblush", size = 0.1 ),
         panel.grid  = element_line( colour ="grey"),
         axis.ticks = element_blank(),
         axis.text = element_blank(),
         plot.title = element_text(hjust = 0.5),
         panel.border = element_rect(fill = NA,colour = "black"),
         legend.background = element_rect( fill = "cornsilk2", colour = "black" ),
         plot.margin = margin(t = 5, r = 5, b = 5,10) )

mapaplot + scale_fill_viridis_c(direction = -1)

4.4. Comunidad: Apoyo social

4.4.1. Tabla datos.

Un apoyo social y familiar es fundamental para el desarrollo tanto personal como profesional de los individuos. Las sociedades más individualistas, son sociedades con un menor bienestar social y económico.

De nuevo vemos a los países del norte de Europa liderando esta clasificación. Clasificación donde España se encuentra en una buena situación comparado con otros países europeos.

Me llama la atención la posición de Grecia en este ranking. Por su carácter mediterráneo (más familiar) nunca hubiese sospechado que se encontrase en última posición.

Paises Calidad_apoyo_social Ingresos_personales
Denmark 95 51466
Finland 95 42964
Ireland 95 47653
United Kingdom 94 43732
Luxembourg 93 63062
Spain 93 38507
Switzerland 93 62283
Austria 92 50349
Estonia 92 24336
Italy 92 36658
Slovenia 92 34933
Belgium 91 49675
Czech Republic 91 25372
Netherlands 91 52877
Slovak Republic 91 24328
Sweden 91 42393
France 90 43755
Germany 90 47585
OECD - Total 89 43241
Lithuania 88 24287
Portugal 88 25367
Hungary 86 22576
Latvia 86 23683
Poland 86 27046
Greece 80 26064

4.4.2. Gráfica.

En el análisis gráfico hemos relacionado los ingresos de los ciudadanos de cada país con la tasa de empleo, con el objetivo de estudiar si hay algún tipo de relación. Parece clara: a mayor apoyo social mayores ingresos.

4.4.3. Mapa.

Si transferimos los datos de la tabla creada en el primer apartado a un mapa, queda de la siguiente manera:

4.4.4. Chunks.

En este apartado se muestran los trozos de código R (chunk) utilizados para hacer la tabla, el gráfico y el mapa. Separándolo de los demás, hace que la lectura del trabajo sea más fácil y amena.


#Así he hecho la tabla

df_ <- rio::import("./datos/calidadvida_definitivo.csv")

df_social <- df_  %>% select(Paises,Calidad_apoyo_social, Ingresos_personales)

df_social <- na.omit(df_social)

df_social %>% gt()

#Así he hecho el primer gráfico 

ggplot(df_social, aes(forcats::fct_reorder(Paises, Calidad_apoyo_social), Calidad_apoyo_social)) +
  geom_col(aes(fill = Calidad_apoyo_social))+ coord_flip()+ 
  theme(axis.text.x = element_text(angle=90, vjust=0.6), panel.background = NULL)+
  labs(title = "Calidad de apoyo social (en porcentaje)", subtitle = "Por países",caption = "Fuente OCDE") + 
  labs(x = NULL, y = NULL)+ theme(legend.position = "none")

#Así he hecho el segundo gráfico

df_ <- rio::import("./datos/calidadvida_definitivo.csv")

df_social <- df_  %>% select(Paises,Calidad_apoyo_social, Ingresos_personales) %>% arrange(desc(Calidad_apoyo_social))

df_social <- na.omit(df_social)

ggplot(df_social, aes(Calidad_apoyo_social, Ingresos_personales)) + 
  geom_point(aes(color = Paises)) + geom_point(data = filter(df_social, Paises == "Spain"), colour = "pink", size = 6)+ geom_smooth()+ theme_calc()+
  labs(title = "Calidad de apoyo social VS Ingresos",caption = "Fuente OCDE")+ 
  labs(x ="Calidad apoyo social (en porcentaje)", y = "Ingresos personales (en dólares)") 

p + annotate(geom = "curve", x = 38507, y = 92, xend = 40000, yend = 94, 
                      curvature = .3, arrow = arrow(length = unit(2, "mm"))) +
           annotate(geom = "text", x = 39000, y = 94, label = "España", hjust = "left")

#Así he hecho el mapa

mapadata_UE<- map_data("world") %>% filter(region %in% c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
                                                         "Czech Republic","Denmark","Estonia","Finland","France",
                                                         "Germany","Greece","Hungary","Ireland","Italy","Latvia",
                                                         "Lithuania","Luxembourg","Malta","Netherlands","Poland",
                                                         "Portugal","Romania","Slovakia","Slovenia","Spain",
                                                         "Sweden","UK","Switzerland","Bosnia and Herzegovina","Serbia","Ukraine","Belarus","Albania","Montenegro","Kosovo","Macedonia","Moldova"))

mapadata_UE_ <- mapadata_UE %>% mutate(region = case_when(
  region == "UK" ~ "United Kingdom",
  TRUE  ~  region ))

mapdata_UE_ <- full_join (mapadata_UE_,df_social, by = c("region"="Paises"))


mapaplot2 <- ggplot(mapdata_UE_, aes(x = long, y = lat, group=group, fill = Ingresos_personales) ) +
  geom_polygon(color ="#ffffff") +
  scale_fill_gradient(low = "#313200",high = "#f7ff00") +
  labs(fill="Calidad_apoyo_social",
       x=NULL,
       y=NULL,
       title="Calidad de Apoyo Social (en porcentaje)",
       caption="Fuente: OCDE") +
  theme( plot.background = element_rect( fill = "#ffffff"),
         panel.background = element_rect( fill = "cornsilk2", colour = "lavenderblush", size = 0.1 ),
         panel.grid  = element_line( colour ="grey"),
         axis.ticks = element_blank(),
         axis.text = element_blank(),
         plot.title = element_text(hjust = 0.5),
         panel.border = element_rect(fill = NA,colour = "black"),
         legend.background = element_rect( fill = "cornsilk2", colour = "black" ),
         plot.margin = margin(t = 5, r = 5, b = 5,10) )

mapaplot2 + scale_fill_viridis_c(direction = -1)

4.5. Educación: Nivel de educación

4.5.1. Tabla datos.

Una sociedad educada, es una sociedad desarrollada. El nivel de educación es fundamental en el desarrollo a LP de un país.

Los países que lideran este indicador son los países del Este de Europa, seguidos de los norte-europeos.

A la cola, como en otros indicadores, los países mediterráneos del sur de Europa (España, Italia y Grecia).

Paises Ingresos_personales Nivel_educacion Años_de_educación Habilidades_de_estudiantes
Czech Republic 25372 94 17.9 491
Lithuania 24287 93 18.4 475
Poland 27046 92 17.6 504
Slovak Republic 24328 91 15.8 463
Estonia 24336 89 17.7 524
Finland 42964 88 19.8 523
Latvia 23683 88 18.0 487
Slovenia 34933 88 18.3 509
Switzerland 62283 88 17.5 506
Germany 47585 87 18.1 508
Austria 50349 85 17.0 492
Hungary 22576 84 16.4 474
Sweden 42393 83 19.3 496
Ireland 47653 82 18.1 509
Denmark 51466 81 19.5 504
United Kingdom 43732 81 17.5 500
France 43755 78 16.5 496
Netherlands 52877 78 18.7 508
OECD - Total 43241 78 17.2 486
Belgium 49675 77 19.3 503
Luxembourg 63062 77 15.1 483
Greece 26064 73 19.0 458
Italy 36658 61 16.6 485
Spain 38507 59 17.9 491
Portugal 25367 48 16.9 497

4.5.2. Gráfica.

La gráfica nos indica que no hay una relación directa, por lo menos a CP, entre nivel de educación e ingresos. Aunque diversos estudios indican que si ese nivel de educación alto se mantiene en el LP, el nivel de desarrollo de esa sociedad crecerá.

4.5.3. Mapa.

Vemos claramente la diferencia en niveles de educación entre el sur y el norte-este de Europa.

4.5.4. Chunks.

En este apartado se muestran los trozos de código R (chunk) utilizados para hacer la tabla, el gráfico y el mapa. Separándolo de los demás, hace que la lectura del trabajo sea más fácil y amena.


#Así he hecho la tabla

df <- rio::import("./datos/calidadvida_definitivo.csv")

df_educa <- df  %>% select(Paises, Ingresos_personales,Nivel_educacion, Años_de_educación, Habilidades_de_estudiantes) %>% arrange(desc(Nivel_educacion))

df_educa <- na.omit(df_educa)

knitr::kable(df_educa)

#Así he hecho el gráfico 

df <- rio::import("./datos/calidadvida_definitivo.csv")

df_educa <- df  %>% select(Paises, Ingresos_personales,Nivel_educacion, Años_de_educación, Habilidades_de_estudiantes)

df_educa <- na.omit(df_educa)

ggplot(df_educa, aes(Ingresos_personales, Nivel_educacion, label = Paises)) + 
  geom_point() + 
  geom_point(data = filter(df_educa, Paises == "Spain"), colour = "pink", size = 6)+ 
  geom_point(data = filter(df_educa, Paises == "OECD - Total"), colour = "violet", size = 6)+
  labs(title = "Relación entre ingresos y nivel de educación" ,
       y = "Ingresos personales (en dólares)",
       x = "Nivel de educación (sobre base 100)",
       caption = "Fuente OCDE")+
  geom_smooth()+ geom_label_repel()+ theme_economist()

#Así he hecho el mapa

mapadata_UE<- map_data("world") %>% filter(region %in% c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
                                                         "Czech Republic","Denmark","Estonia","Finland","France",
                                                         "Germany","Greece","Hungary","Ireland","Italy","Latvia",
                                                         "Lithuania","Luxembourg","Malta","Netherlands","Poland",
                                                         "Portugal","Romania","Slovakia","Slovenia","Spain",
                                                         "Sweden","UK","Switzerland","Bosnia and Herzegovina","Serbia","Ukraine","Belarus","Albania","Montenegro","Kosovo","Macedonia","Moldova"))

mapadata_UE_ <- mapadata_UE %>% mutate(region = case_when(
  region == "UK" ~ "United Kingdom",
  TRUE  ~  region ))

mapdata_UE_ <- full_join (mapadata_UE_,df_educa, by = c("region"="Paises"))

mapaplot <- ggplot(mapdata_UE_, aes(x = long, y = lat, group=group, fill = Nivel_educacion) ) +
  geom_polygon(color ="#ffffff") +
  scale_fill_gradient(low = "#313200",high = "#f7ff00") +
  labs(fill="Nivel_educacion",
       x=NULL,
       y=NULL,
       title="Nivel de educación (sobre base 100)",
       caption="Fuente: OCDE") +
  theme( plot.background = element_rect( fill = "#ffffff"),
         panel.background = element_rect( fill = "cornsilk2", colour = "lavenderblush", size = 0.1 ),
         panel.grid  = element_line( colour ="grey"),
         axis.ticks = element_blank(),
         axis.text = element_blank(),
         plot.title = element_text(hjust = 0.5),
         panel.border = element_rect(fill = NA,colour = "black"),
         legend.background = element_rect( fill = "cornsilk2", colour = "black" ),
         plot.margin = margin(t = 5, r = 5, b = 5,10) )

mapaplot + scale_fill_viridis_c(direction = -1)

4.6. Satisfacción ante la vida

4.6.1. Tabla datos.

Para mí, el indicador más importante (con los ingresos). Es el indicador que mejor refleja el estado de bienestar social de los integrantes de una sociedad y el que sirve de contrapeso entre indicadores de desarrollo de una sociedad (trabajo-tiempo de ocio).

Los países del norte de Europa y Suiza vuelven a liderar. Esta vez España está en buena posición, cercano a la media de la OCDE.

A la cola, los países del Este de Europa, Grecia y Portugal (éstos dos últimos más golpeados en la última crisis económica-financiera).

Paises Ingresos_personales Satisfaccion_vida
Denmark 51466 7.6
Finland 42964 7.6
Switzerland 62283 7.5
Netherlands 52877 7.4
Sweden 42393 7.3
Austria 50349 7.1
Germany 47585 7.0
Ireland 47653 7.0
Belgium 49675 6.9
Luxembourg 63062 6.9
United Kingdom 43732 6.8
Czech Republic 25372 6.7
France 43755 6.5
OECD - Total 43241 6.5
Spain 38507 6.3
Slovak Republic 24328 6.2
Poland 27046 6.1
Italy 36658 6.0
Latvia 23683 5.9
Lithuania 24287 5.9
Slovenia 34933 5.9
Estonia 24336 5.7
Hungary 22576 5.6
Greece 26064 5.4
Portugal 25367 5.4

4.6.2. Gráfica.

Parece que el dicho que “el dinero no da la felicidad” lo vamos a desmentir en este apartado.

Si relacionamos, ingresos con satisfación de vida, nos sale que a mayor ingresos, mayor satisfación de vida para los ciudadanos.

4.6.3. Mapa.

Si transferimos los datos de la tabla creada en el primer apartado a un mapa, queda de la siguiente manera:

4.6.4. Chunks.

En este apartado se muestran los trozos de código R (chunk) utilizados para hacer la tabla, el gráfico y el mapa. Separándolo de los demás, hace que la lectura del trabajo sea más fácil y amena.


#Así he hecho la tabla

df <- rio::import("./datos/calidadvida_definitivo.csv")

df_satisfaccion <- df  %>% select(Paises, Ingresos_personales,Satisfaccion_vida) %>% arrange(desc(Satisfaccion_vida))

df_satisfaccion <- na.omit(df_satisfaccion)

df_satisfaccion %>% gt()

#Así he hecho el gráfico 

ggplot(df_satisfaccion, aes(Ingresos_personales, Satisfaccion_vida, label = Paises)) + 
  geom_point() + 
  geom_point(data = filter(df_satisfaccion, Paises == "Spain"), colour = "pink", size = 6)+ 
  geom_point(data = filter(df_satisfaccion, Paises == "OECD - Total"), colour = "violet", size = 6)+
  labs(title = "Relación entre ingresos y nivel de educación" ,
       y = "Ingresos personales (en dólares)",
       x = "satisfacción ante la vida (nota de 1 a 10)",
       caption = "Fuente OCDE")+
  geom_smooth()+ geom_label_repel()+ theme_calc()

#Así he hecho el mapa

mapadata_UE<- map_data("world") %>% filter(region %in% c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
                                                         "Czech Republic","Denmark","Estonia","Finland","France",
                                                         "Germany","Greece","Hungary","Ireland","Italy","Latvia",
                                                         "Lithuania","Luxembourg","Malta","Netherlands","Poland",
                                                         "Portugal","Romania","Slovakia","Slovenia","Spain",
                                                         "Sweden","UK","Switzerland","Bosnia and Herzegovina","Serbia","Ukraine","Belarus","Albania","Montenegro","Kosovo","Macedonia","Moldova"))

mapadata_UE_ <- mapadata_UE %>% mutate(region = case_when(
  region == "UK" ~ "United Kingdom",
  TRUE  ~  region ))

mapdata_UE_ <- full_join (mapadata_UE_,df_satisfaccion, by = c("region"="Paises"))

mapaplot <- ggplot(mapdata_UE_, aes(x = long, y = lat, group=group, fill = Satisfaccion_vida) ) +
  geom_polygon(color ="#ffffff") +
  scale_fill_gradient(low = "#313200",high = "#f7ff00") +
  labs(fill="Satisfaccion_vida",
       x=NULL,
       y=NULL,
       title="Satisfacción ante la vida (nota del 1 al 10)",
       caption="Fuente: OCDE") +
  theme( plot.background = element_rect( fill = "#ffffff"),
         panel.background = element_rect( fill = "cornsilk2", colour = "lavenderblush", size = 0.1 ),
         panel.grid  = element_line( colour ="grey"),
         axis.ticks = element_blank(),
         axis.text = element_blank(),
         plot.title = element_text(hjust = 0.5),
         panel.border = element_rect(fill = NA,colour = "black"),
         legend.background = element_rect( fill = "cornsilk2", colour = "black" ),
         plot.margin = margin(t = 5, r = 5, b = 5,10) )

mapaplot + scale_fill_viridis_c(direction = -1)

4.7. Balance vida-trabajo

4.7.1. Tabla datos.

Como contrapeso al nivel de ingresos de los países se encuentra el balance que tienen sus ciudadanos entre ocio y trabajo.

Aquí, los países del sur de Europa salen ganando. Son los que mejor equilibrio entre trabajo y ocio tienen.

En la cola los países del Este de Europa, Austria y Reino Unido.

Paises Tiempo_ocio Empleados_trabajan_muchas Ingresos_personales
Italy 16.47 4.11 36658
France 16.36 7.67 43755
Spain 15.93 4.01 38507
Denmark 15.87 2.34 51466
Belgium 15.70 4.75 49675
Germany 15.62 4.26 47585
Sweden 15.18 1.07 42393
Finland 15.17 3.81 42964
OECD - Total 14.98 11.01 43241
United Kingdom 14.92 12.15 43732
Estonia 14.90 2.42 24336
Slovenia 14.75 4.39 34933
Austria 14.55 6.66 50349
Poland 14.42 5.95 27046
Latvia 13.83 1.27 23683

4.7.2. Gráfica.

No hay una relación clara entre tiempo de ocio e ingresos.

4.7.3. Mapa.

Si transferimos los datos de la tabla creada en el primer apartado a un mapa, podemos observar una cosa curiosa: invertimos prácticamente el mapa que hemos obtenido en otros indicadores como educación o empleo.

4.7.4. Chunks.

En este apartado se muestran los trozos de código R (chunk) utilizados para hacer la tabla, el gráfico y el mapa. Separándolo de los demás, hace que la lectura del trabajo sea más fácil y amena.


#Así he hecho la tabla 

df_ <- rio::import("./datos/calidadvida_definitivo.csv")

df_vida_trabajo <- df_  %>% select(Paises,Tiempo_ocio,Empleados_trabajan_muchas,Ingresos_personales)%>% arrange(desc(Tiempo_ocio))

df_vida_trabajo <- na.omit(df_vida_trabajo)

kable(df_vida_trabajo) %>%
  kableExtra::kable_styling(fixed_thead = list(enabled = T, background = "lightblue"))

#Así he hecho el gráfico 

ggplot(df_vida_trabajo, aes(Ingresos_personales, Tiempo_ocio, label = Paises)) + 
  geom_point() + 
  geom_point(data = filter(df_vida_trabajo, Paises == "Spain"), colour = "pink", size = 6)+ 
  geom_point(data = filter(df_vida_trabajo, Paises == "OECD - Total"), colour = "violet", size = 6)+
  labs(title = "Relación entre ingresos y nivel de educación" ,
       y = "Ingresos personales (en dólares)",
       x = "Tiempo de ocio (porcentaje)",
       caption = "Fuente OCDE")+
  geom_smooth()+ geom_label_repel()+ theme_clean()

#Así he hecho el mapa

mapadata_UE<- map_data("world") %>% filter(region %in% c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
                                                         "Czech Republic","Denmark","Estonia","Finland","France",
                                                         "Germany","Greece","Hungary","Ireland","Italy","Latvia",
                                                         "Lithuania","Luxembourg","Malta","Netherlands","Poland",
                                                         "Portugal","Romania","Slovakia","Slovenia","Spain",
                                                         "Sweden","UK","Switzerland","Bosnia and Herzegovina","Serbia","Ukraine","Belarus","Albania","Montenegro","Kosovo","Macedonia","Moldova"))

mapadata_UE_ <- mapadata_UE %>% mutate(region = case_when(
  region == "UK" ~ "United Kingdom",
  TRUE  ~  region ))

mapdata_UE_ <- full_join (mapadata_UE_,df_vida_trabajo, by = c("region"="Paises"))

mapaplot <- ggplot(mapdata_UE_, aes(x = long, y = lat, group=group, fill = Tiempo_ocio) ) +
  geom_polygon(color ="#ffffff") +
  scale_fill_gradient(low = "#313200",high = "#f7ff00") +
  labs(fill="Tiempo_ocio",
       x=NULL,
       y=NULL,
       title="Tiempo de ocio",
       caption="Fuente: OCDE") +
  theme( plot.background = element_rect( fill = "#ffffff"),
         panel.background = element_rect( fill = "cornsilk2", colour = "lavenderblush", size = 0.1 ),
         panel.grid  = element_line( colour ="grey"),
         axis.ticks = element_blank(),
         axis.text = element_blank(),
         plot.title = element_text(hjust = 0.5),
         panel.border = element_rect(fill = NA,colour = "black"),
         legend.background = element_rect( fill = "cornsilk2", colour = "black" ),
         plot.margin = margin(t = 5, r = 5, b = 5,10) )

mapaplot + scale_fill_viridis_c(direction = -1)

5. Conlusión.

“La verdadera felicidad social consiste en la armonía y en el uso pacífico de las satisfacciones de cada individuo.” — Marlene Dietrich.

A menudo pensamos que una sociedad rica, es una sociedad feliz. Nada más lejos de la realidad. Ejemplos como el de Japón o Corea del Sur (no analizados en el presente trabajo) son un buen ejemplo de ello. Datos ofrecidos por este informe de la OCDE demuestran que sus habitantes, pese a tener un buen nivel económico, están menos satisfechos con su vida que otros países con menores ingresos. Factores influyentes en esta percepción que tiene sus habitantes, pueden ser los malos datos que muestran, ambas economías, en el balance entre vida y trabajo.

A nivel europeo, objeto de este estudio, los países que salen ganadores, si se me permite esta licencia, son claramente los países nórdicos. Ocupan los primeros puestos en casi todas las variables, incluso en las que no están directamente relacionadas con los ingresos (educación, apoyo social o satisfacción ante la vida), por encima de países que tienen mayores ingresos per cápita (Luxemburgo, Suiza, Allemania).

Pese a lo que se podía esperar, nuestro país no sale mal parado del todo en este estudio porque pese los malos datos en algunos indicadores como educación, empleo o ingresos, se encuentra en la media de la OCDE en el más importante, en mi opinión: satisfacción ante la vida de sus ciudadanos. Destacan también en apoyo social y balance entre el tiempo de ocio y trabajo.

El punto más positivo de este Índice es que cada persona, en función del valor que le da a cada uno de las 11 variables, puede ver en que país encajaría mejor. La felicidad es enormemente subjetiva. Lo que puede hacer feliz a una sociedad, puede no hacérselo a otra. Esto para mí es una de las claves por lo que es injusto medir el desarrollo de un país solo por la tasa de crecimiento del PIB per cápita.

6. Bibliografía.

Página web del Índice para una Vida Mejor

Tutoriales de profesar de Universidad de Valencia, D.Pedro J. Pérez

Vídeo explicativo de Rafa González Gouveia sobre como animar las gráficas

Datos del dataframe y geometrias dados en clase por D.Pedro J. Pérez.

Me ha inspirado mi anterior trabajo en grupo: “La incidencia del Covid-19 en la Comunidad Valenciana”

Aquí aprendí como quitar valores nulos de las filas

current session info


- Session info ---------------------------------------------------------------
 setting  value                       
 version  R version 4.0.2 (2020-06-22)
 os       Windows 10 x64              
 system   x86_64, mingw32             
 ui       RTerm                       
 language (EN)                        
 collate  Spanish_Spain.1252          
 ctype    Spanish_Spain.1252          
 tz       Europe/Paris                
 date     2021-01-17                  

- Packages -------------------------------------------------------------------
 package           * version    date       lib
 assertthat          0.2.1      2019-03-21 [1]
 backports           1.1.9      2020-08-24 [1]
 base64enc           0.1-3      2015-07-28 [1]
 blob                1.2.1      2020-01-20 [1]
 broom               0.7.0      2020-07-09 [1]
 cellranger          1.1.0      2016-07-27 [1]
 checkmate           2.0.0      2020-02-06 [1]
 class               7.3-17     2020-04-26 [2]
 classInt            0.4-3      2020-04-07 [1]
 cli                 2.2.0      2020-11-20 [1]
 clipr               0.7.1      2020-10-08 [1]
 codetools           0.2-16     2018-12-24 [2]
 colorspace          1.4-1      2019-03-18 [1]
 crayon              1.3.4      2017-09-16 [1]
 crosstalk           1.1.0.1    2020-03-13 [1]
 curl                4.3        2019-12-02 [1]
 data.table          1.13.0     2020-07-24 [1]
 DBI                 1.1.0      2019-12-15 [1]
 dbplyr              1.4.4      2020-05-27 [1]
 desc                1.2.0      2018-05-01 [1]
 details             0.2.1      2020-01-12 [1]
 digest              0.6.27     2020-10-24 [1]
 dplyr             * 1.0.2      2020-08-18 [1]
 DT                * 0.15       2020-08-05 [1]
 e1071               1.7-3      2019-11-26 [1]
 echarts4r         * 0.3.3      2020-10-16 [1]
 ellipsis            0.3.1      2020-05-15 [1]
 evaluate            0.14       2019-05-28 [1]
 fansi               0.4.1      2020-01-08 [1]
 farver              2.0.3      2020-01-16 [1]
 fastmap             1.0.1      2019-10-08 [1]
 forcats           * 0.5.0      2020-03-01 [1]
 foreign             0.8-80     2020-05-24 [2]
 formattable       * 0.2.0.1    2016-08-05 [1]
 fs                  1.5.0      2020-07-31 [1]
 generics            0.1.0      2020-10-31 [1]
 gganimate         * 1.0.7      2020-10-15 [1]
 ggplot2           * 3.3.2      2020-06-19 [1]
 ggrepel           * 0.9.0      2020-12-16 [1]
 ggspatial         * 1.1.4      2020-07-12 [1]
 ggthemes          * 4.2.0      2019-05-13 [1]
 gifski            * 0.8.6      2018-09-28 [1]
 glue                1.4.2      2020-08-27 [1]
 gt                * 0.2.2      2020-08-05 [1]
 gtable              0.3.0      2019-03-25 [1]
 haven               2.3.1      2020-06-01 [1]
 here                0.1        2017-05-28 [1]
 highr               0.8        2019-03-20 [1]
 hms                 0.5.3      2020-01-08 [1]
 htmltools           0.5.0      2020-06-16 [1]
 htmlwidgets         1.5.1      2019-10-08 [1]
 httpuv              1.5.4      2020-06-06 [1]
 httr                1.4.2      2020-07-20 [1]
 jsonlite            1.7.1      2020-09-07 [1]
 kableExtra        * 1.3.1      2020-10-22 [1]
 KernSmooth          2.23-17    2020-04-26 [2]
 klippy            * 0.0.0.9500 2020-11-20 [1]
 knitr             * 1.29       2020-06-23 [1]
 labeling            0.3        2014-08-23 [1]
 later               1.1.0.1    2020-06-05 [1]
 lattice             0.20-41    2020-04-02 [2]
 lazyeval            0.2.2      2019-03-15 [1]
 leafem            * 0.1.3      2020-07-26 [1]
 leaflet           * 2.0.3      2019-11-16 [1]
 lifecycle           0.2.0      2020-03-06 [1]
 lubridate         * 1.7.9.2    2020-11-13 [1]
 magrittr            2.0.1      2020-11-17 [1]
 maps                3.3.0      2018-04-03 [1]
 Matrix              1.2-18     2019-11-27 [2]
 mgcv                1.8-31     2019-11-09 [2]
 mime                0.9        2020-02-04 [1]
 modelr              0.1.8      2020-05-19 [1]
 munsell             0.5.0      2018-06-12 [1]
 nlme                3.1-148    2020-05-24 [2]
 openxlsx            4.2.2      2020-09-17 [1]
 patchwork         * 1.1.1      2020-12-17 [1]
 pillar              1.4.7      2020-11-20 [1]
 pjpv2020.01       * 0.0.0.9000 2020-11-20 [1]
 pkgconfig           2.0.3      2019-09-22 [1]
 plotly            * 4.9.2.2    2020-12-19 [1]
 plyr                1.8.6      2020-03-03 [1]
 png                 0.1-7      2013-12-03 [1]
 prettyunits         1.1.1      2020-01-24 [1]
 progress            1.2.2      2019-05-16 [1]
 promises            1.1.1      2020-06-09 [1]
 purrr             * 0.3.4      2020-04-17 [1]
 R6                  2.5.0      2020-10-28 [1]
 raster              3.4-5      2020-11-14 [1]
 Rcpp                1.0.5      2020-07-06 [1]
 readr             * 1.4.0      2020-10-05 [1]
 readxl              1.3.1      2019-03-13 [1]
 reprex              0.3.0      2019-05-16 [1]
 rio               * 0.5.16     2018-11-26 [1]
 rlang               0.4.9      2020-11-26 [1]
 rmarkdown           2.3        2020-06-18 [1]
 rnaturalearth     * 0.1.0      2017-03-21 [1]
 rnaturalearthdata * 0.1.0      2017-02-21 [1]
 rprojroot           1.3-2      2018-01-03 [1]
 rstudioapi          0.11       2020-02-07 [1]
 rvest               0.3.6      2020-07-25 [1]
 sass                0.2.0      2020-03-18 [1]
 scales              1.1.1      2020-05-11 [1]
 sessioninfo         1.1.1      2018-11-05 [1]
 sf                * 0.9-6      2020-09-13 [1]
 shiny               1.5.0      2020-06-23 [1]
 sp                  1.4-2      2020-05-20 [1]
 stringi             1.5.3      2020-09-09 [1]
 stringr           * 1.4.0      2019-02-10 [1]
 tibble            * 3.0.4      2020-10-12 [1]
 tidyr             * 1.1.2      2020-08-27 [1]
 tidyselect          1.1.0      2020-05-11 [1]
 tidyverse         * 1.3.0      2019-11-21 [1]
 tweenr              1.0.1      2018-12-14 [1]
 units               0.6-7      2020-06-13 [1]
 vctrs               0.3.5      2020-11-17 [1]
 vembedr           * 0.1.4      2020-10-10 [1]
 viridisLite         0.3.0      2018-02-01 [1]
 webshot             0.5.2      2019-11-22 [1]
 withr               2.2.0      2020-04-20 [1]
 xfun                0.17       2020-09-09 [1]
 xml2                1.3.2      2020-04-23 [1]
 xtable              1.8-4      2019-04-21 [1]
 yaml                2.2.1      2020-02-01 [1]
 zip                 2.1.1      2020-08-27 [1]
 source                               
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.0)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 Github (rlesur/klippy@378c247)       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.0)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.0)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 Github (perezp44/pjpv2020.01@91df4e6)
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.3)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       
 CRAN (R 4.0.2)                       

[1] C:/Users/carlo/Documents/R/win-library/4.0
[2] C:/Program Files/R/R-4.0.2/library



  1. definición sacada de la wikipedia.↩︎

LS0tDQp0aXRsZTogPEZPTlQgQ09MT1I9Ik9yYW5nZSI+Ik9FQ0QgKipCZXR0ZXIgTGlmZSoqIEluZGV4IjwvRk9OVD4NCnN1YnRpdGxlOiAiSnVhbiBDYXJsb3MgR2FyY8OtYSBHdWFyZGXDsW8gKGdhcmd1YXIyQGFsdW1uaS51di5lcykiICAjLSBwb25nbyB0w7ogbm9tYnJlIGFow60gcGFyYSBxIGFwYXJlemNhIG3DoXMgZ3JhbmRlIHEgZWwgZGUgbGEgVVYNCmF1dGhvcjogIlVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSINCmRhdGU6ICJEaWNpZW1icmUgZGUgMjAyMCAoYWN0dWFsaXphZG8gZWwgYHIgZm9ybWF0KFN5cy50aW1lKCksICclZC0lbS0lWScpYCkiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgI2NzczogIi4vYXNzZXRzL215X2Nzc19maWxlLmNzcyINCiAgICB0aGVtZTogcGFwZXINCiAgICBoaWdobGlnaHQ6IHRleHRtYXRlIA0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogMyANCiAgICB0b2NfZmxvYXQ6IA0KICAgICAgY29sbGFwc2VkOiB0cnVlDQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlDQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlDQogICAgZGZfcHJpbnQ6IGthYmxlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQ0KLS0tDQoNCmBgYHtyIHBhY2thZ2VzLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoa2xpcHB5KSAgIy0gcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoInJsZXN1ci9rbGlwcHkiKQ0KbGlicmFyeShrbml0cikNCmBgYA0KDQpgYGB7ciBjaHVuay1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIA0KICAgICAgICAgICAgICAgICAgICAgICNyZXN1bHRzID0gImhvbGQiLA0KICAgICAgICAgICAgICAgICAgICAgIGNhY2hlID0gRkFMU0UsIGNhY2hlLnBhdGggPSAiL2NhY2hlcy8iLCBjb21tZW50ID0gIiM+IiwNCiAgICAgICAgICAgICAgICAgICAgICAjZmlnLndpZHRoID0gNywgI2ZpZy5oZWlnaHQ9IDcsICAgDQogICAgICAgICAgICAgICAgICAgICAgI291dC53aWR0aCA9IDcsIG91dC5oZWlnaHQgPSA3LA0KICAgICAgICAgICAgICAgICAgICAgIGNvbGxhcHNlID0gVFJVRSwgIGZpZy5zaG93ID0gImhvbGQiLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy5hc3AgPSA3LzksIG91dC53aWR0aCA9ICI2MCUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIikNCmtuaXRyOjpvcHRzX2NodW5rJHNldChkZXYgPSAicG5nIiwgZGV2LmFyZ3MgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpDQpgYGANCg0KYGBge3Igb3B0aW9ucy1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpICMtIHBhcmEgcXVpdGFyIGxhIG5vdGFjacOzbiBjaWVudMOtZmljYQ0Kb3B0aW9ucygieWFtbC5ldmFsLmV4cHIiID0gVFJVRSkgDQpgYGANCg0KYGBge3Iga2xpcHB5LCBlY2hvID0gRkFMU0V9DQprbGlwcHk6OmtsaXBweShwb3NpdGlvbiA9IGMoInRvcCIsICJyaWdodCIpKSAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpgYGANCg0KPGhyIGNsYXNzPSJsaW5lYS1ibGFjayI+DQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPg0KDQpUcmFiYWpvIGVsYWJvcmFkbyBwYXJhIGxhIGFzaWduYXR1cmEgIlByb2dyYW1hY2nDs24geSBtYW5lam8gZGUgZGF0b3MgZW4gbGEgZXJhIGRlbCBCaWcgRGF0YSIgZGUgbGEgVW5pdmVyc2l0YXQgZGUgVmFsw6huY2lhIGR1cmFudGUgZWwgY3Vyc28gMjAyMC0yMDIxLiBFbCByZXBvIGRlbCB0cmFiYWpvIGVzdMOhIFthcXXDrV0oaHR0cHM6Ly9naXRodWIuY29tL2Nhcmxvc21hbmlzZXMvdHJhYmFqb19CaWdEYXRhKXt0YXJnZXQ9Il9ibGFuayJ9LiBMYSBww6FnaW5hIHdlYiBkZSBsYSBhc2lnbmF0dXJhIHkgbG9zIHRyYWJham9zIGRlIG1pcyBjb21wYcOxZXJvcyBwdWVkZW4gdmVyc2UgW2FxdcOtXShodHRwczovL3BlcmV6cDQ0LmdpdGh1Yi5pby9pbnRyby1kcy0yMC0yMS13ZWIvMDctdHJhYmFqb3MuaHRtbCl7dGFyZ2V0PSJfYmxhbmsifS4NCjxkaXYvPg0KPCEtLSBFbCBww6FycmFmbyBkZSBhcnJpYmEgaGFzIGRlIGRlamFybG8gY2FzaSBpZ3VhbCwgDQogICAgICAgIHNvbG8gSEFTIGRlIFNVU1RJVFVJUiBsYXMgMiB2ZWNlcyBxdWUgYXBhcmVjZSAicGVyZXpwNDQiIHBvciB0dSB1c3VhcmlvIGRlIEdpdGh1Yi0tPg0KDQo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+DQoNCiMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+MS4gSW50cm9kdWNjacOzbiA8L0ZPTlQ+DQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPg0KDQpTaSBwcmVndW50YXJhbW9zIGEgY3VhbHF1aWVyIHBlcnNvbmEgImVudGVuZGlkYSIgZW4gZWNvbm9tw61hIHNvYnJlIGNvbW8gcG9kZXIgZGV0ZXJtaW5hciBlbCBuaXZlbCBkZSBkZXNhcnJvbGxvIGRlIGxvcyBwYcOtc2VzLCBub3MgcmVtaXRpcsOtYSBjYXNpIGNvbiB0b3RhbCBzZWd1cmlkYWQgYWwgUElCIGRlIGNhZGEgdW5vIGRlIMOpc3Rvcy4gUG9kZW1vcyBkZWZpbmlyIGVsIFBJQiBwZXIgY2FwaXRhIGNvbW8gKmxhIHJlbGFjacOzbiBlbnRyZSBlbCB2YWxvciB0b3RhbCBkZSB0b2RvcyBsb3MgYmllbmVzIHkgc2VydmljaW9zIGZpbmFsZXMgZ2VuZXJhZG9zIGR1cmFudGUgdW4gYcOxbyBwb3IgbGEgZWNvbm9tw61hIGRlIHVuYSBuYWNpw7NuIG8gZXN0YWRvIHkgZWwgbsO6bWVybyBkZSBzdXMgaGFiaXRhbnRlcyBlbiBlc2UgYcOxbypeW2RlZmluaWNpw7NuIHNhY2FkYSBkZSBsYSB3aWtpcGVkaWEuXS4gRXN0ZSBpbnN0cnVtZW50byBoYSBzaWRvLCBkdXJhbnRlIGTDqWNhZGFzLCBlbCBtw6FzIHV0aWxpemFkbyBwb3IgbG9zIGVjb25vbWlzdGFzIHBhcmEgZXN0dWRpYXIgbGEgZXZvbHVjacOzbiBlY29uw7NtaWNhIGRlIGxvcyBwYcOtc2VzLg0KDQrCv1Blcm8gZXMgY2FwYXogZGUgbWVkaXIgZWwgUElCIHBlciBjw6FwaXRhLCBwb3Igc2kgc29sbywgZWwgZ3JhZG8gZGUgZGVzYXJyb2xsbyBkZSB1biBwYcOtcyB5IGVsIGJpZW5lc3RhciBkZSBzdXMgaGFiaXRhbnRlcz8gSG95IGVuIGTDrWEgZXhpc3RlIHVuIGNvbnNlbnNvIGVudHJlIGxvcyBwcmluY2lwYWxlcyBlY29ub21pc3RhcyAoSm9zZXBoIFN0aWdsaXR6LCBBbWFydHlhIFNlbiwgSmVhbi1QYXVsIEZpdG9zcywgZXRjLikgc29icmUgbGEgcG9jYSBmaWFiaWxpZGFkIGRlbCBQSUIgY29tbyBpbmRpY2Fkb3Igw7puaWNvIHBhcmEgbWVkaXIgZWwgcHJvZ3Jlc28gZWNvbsOzbWljbyB5IHNvY2lhbCBkZSB1bmEgbmFjacOzbi4gDQoNCioqRWwgw41uZGljZSBwYXJhIHVuYSBWaWRhIE1lam9yKiogKGVuIGluZ2zDqXMsIEJldHRlciBMaWZlIEluZGV4LCBvIEJMSSkgZXMgdW4gw61uZGljZSBlY29uw7NtaWNvLXNvY2lhbCBjcmVhZG8gcG9yIGxhIE9DREUgZW4gMjAxMS4gRXN0ZSDDrW5kaWNlIHBlcm1pdGUgYSBsYXMgcGVyc29uYXMgY29tcGFyYXIgZWwgbml2ZWwgZGUgZGVzYXJyb2xsbyBkZSBsb3MgcGHDrXNlcyBxdWUgaW50ZWdyYW4gbGEgT0NERSBhIHRyYXbDqXMgZGUgMTEgY3JpdGVyaW9zIGNvbnNpZGVyYWRvcyBjb21vIGVzZW5jaWFsZXMgcGFyYSBlbCBiaWVuZXN0YXIgZGUgbGEgcG9ibGFjacOzbi4NCg0KRXN0YSBpbmljaWF0aXZhIHNlIGFwb3lhIGVuIGVsIGluZm9ybWUgZGUgbGEgQ29taXNpw7NuIFN0aWdsaXR6LVNlbi1GaXRvdXNzaSBzb2JyZSBsYSBtZWRpY2nDs24gZGVsIHJlbmRpbWllbnRvIGVjb27Ds21pY28geSBkZWwgcHJvZ3Jlc28gc29jaWFsLiBTaSBhbGd1aWVuIGVzdMOhIGludGVyZXNhZG8gZW4gc2FiZXIgbGFzIHByaW5jaXBhbGVzIHJlY29tZW5kYWNpb25lcyBkZWwgaW5mb3JtZSBwdWVkZSB2ZXJsYXMgDQogW2FxdcOtXShodHRwczovL3d3dy5kaWFyaW9saWJyZS5jb20vb3Bpbmlvbi9tZWRpci1udWVzdHJhcy12aWRhcy1sYXMtbGltaXRhY2lvbmVzLWRlbC1waWItY29tby1pbmRpY2Fkb3ItZGUtcHJvZ3Jlc28tTEpETDc2OTIxMSkuDQogDQpFbCDDjW5kaWNlLCBjb21vIGhlbW9zIGRpY2hvIGFudGVyaW9ybWVudGUsIGNvbXByZW5kZSBsb3MgMzQgcGHDrXNlcyBtaWVtYnJvcyBkZSBsYSBPcmdhbml6YWNpw7NuIHBhcmEgbGEgQ29vcGVyYWNpw7NuIHkgZWwgRGVzYXJyb2xsbyBFY29uw7NtaWNvcyAoT0NERSkg4oCTbGEgY3VhbCByZcO6bmUgYSBsYSBtYXlvcsOtYSBkZSBsYXMgZWNvbm9tw61hcyBkZXNhcnJvbGxhZGFzIGRlbCBtdW5kbyB5IHZhcmlhcyBlY29ub23DrWFzIGVtZXJnZW50ZXPigJMsIHkgYWxndW5vcyBtw6FzLg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KbGlicmFyeSgidmVtYmVkciIpDQplbWJlZF91cmwoImh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZEZwN2k3QUxNX0kiKQ0KYGBgDQoNCkVuIGVzdGUgdHJhYmFqbyB2YW1vcyBhIHJlZHVjaXIgZWwgY8OtcmN1bG8gZGUgcGHDrXNlcyBxdWUgaW50ZWdyYW4gZXN0ZSDDrW5kaWNlLCBhIGxvcyBwYcOtc2VzIGV1cm9wZW9zIHF1ZSBzb24gbWllbWJyb3MgZGUgbGEgT0NERSBwYXJhIHF1ZSBsYXMgZ3LDoWZpY2FzIHNlYSBtw6FzIHNpbXBsZXMgeSBwb2RhbW9zIG9ic2VydmFyIG1lam9yIGxvcyBkYXRvcy4gQ29tcGFyYXJlbW9zIGVsIG5pdmVsIGRlIGluZ3Jlc29zIGRlIGxvcyBjaXVkYWRhbm9zIGRlIGxvcyBwYcOtc2VzIGNvbiBvdHJvcyBpbmRpY2Fkb3JlcyAoZWR1Y2FjacOzbiwgbml2ZWwgZGUgZW1wbGVvLHNhdGlzZmFjY2nDs24gYW50ZSBsYSB2aWRhLC4uLmV0Yy4pIGRlIGVzdGUgw61uZGljZSBwYXJhIHZlciBzaSBleGlzdGUgdW5hIHJlbGFjacOzbiBlY29uw7Nub21pY2EgZW50cmUgZWxsb3MsIGVzIGRlY2lyLCBzaSBhcXVlbGxvcyBwYcOtc2VzIG3DoXMgcmljb3MsIHRpZW5lbiBtYXlvcmVzIG5pdmVsZXMgZGUgYmllbmVzdGFyIHNvY2lhbCB5IGVjb27Ds21pY28uPGRpdi8+DQoNCiMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+Mi4gRGF0b3MgPC9GT05UPg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZTo6aGVyZSgiaW1hZ2VuZXMiLCAiYmV0dGVybGlmZWluZGV4LmpwZyIpICApDQpgYGANCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+T2J0ZW5lciBsb3MgZGF0b3MgZXMgdW5hIHRhcmVhIHJlbGF0aXZhbWVudGUgc2VuY2lsbGEuIEFjY2VkaWVuZG8gYSBsYSBww6FnaW5hIHdlYiBkZWwgcHJveWVjdG8gW2JldHRlcmxpZmVpbmRleF0oaHR0cDovL3d3dy5vZWNkYmV0dGVybGlmZWluZGV4Lm9yZy9lcy8jLzExMTExMTExMTExKSwgc2UgcHVlZGUgZGVzY2FyZ2FyIGbDoWNpbG1lbnRlIGxvcyBkYXRvcywgZW50cmFuZG8gZW4gbGEgc2VjY2nDs24gW2Rlc2NhcmdhIGxvcyBkYXRvcyBkZWwgw61uZGljZS5dKGh0dHBzOi8vc3RhdHMub2VjZC5vcmcvSW5kZXguYXNweD9EYXRhU2V0Q29kZT1CTEkpDQoNCjxkaXYvPg0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQojQ2FyZ28gbG9zIHBhcXVldGVzDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoa2xpcHB5KSAgDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeSh0aWJibGUpDQpsaWJyYXJ5KGdndGhlbWVzKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocGF0Y2h3b3JrKQ0KbGlicmFyeShnZ3JlcGVsKQ0KbGlicmFyeShzZikNCmxpYnJhcnkoZ2dzcGF0aWFsKQ0KbGlicmFyeShybmF0dXJhbGVhcnRoKQ0KbGlicmFyeShybmF0dXJhbGVhcnRoZGF0YSkNCmxpYnJhcnkocGpwdjIwMjAuMDEpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeSAoZ2lmc2tpKQ0KbGlicmFyeShndCkNCmxpYnJhcnkoa2FibGVFeHRyYSkNCmxpYnJhcnkoRFQpDQpsaWJyYXJ5KHJpbykNCmxpYnJhcnkobGVhZmxldCkgDQpsaWJyYXJ5KGxlYWZlbSkNCmxpYnJhcnkoZm9ybWF0dGFibGUpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoZWNoYXJ0czRyKQ0KDQojQ2FyZ28gbG9zIGRhdG9zIHByZXZpYW1lbnRlIGRlc2NhcmdhZG9zIGRlIGxhIHDDoWdpbmEgZGUgbGEgT0NERQ0KZGYgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvY2FsaWRhZHZpZGEyLnhsc3giKQ0KDQojRmlqbyBsb3Mgbm9tYnJlcyBkZSBsYXMgY29sdW1uYXMNCm5hbWVzKGRmKVsxXSA8LSAiUGFpc2VzIg0KbmFtZXMoZGYpWzJdIDwtICJWaXZpZW5kYV9zaW5faW5zdGFsYWNpb25lc19iYXNpY2FzIg0KbmFtZXMoZGYpWzNdIDwtICJHYXN0b19lbl92aXZpZW5kYSINCm5hbWVzKGRmKVs0XSA8LSAiSGFiaXRhY2lvbmVzX3Bvcl9wZXJzb25hIg0KbmFtZXMoZGYpWzVdIDwtICJJbmdyZXNvX2ZhbWlsaWFyX2Rpc3BvbmlibGUiDQpuYW1lcyhkZilbNl0gPC0gIlBhdHJpbW9uaW9fZmFtaWxpYSINCm5hbWVzKGRmKVs3XSA8LSAiSW5zZWd1cmlkYWRfZW5fZW1wbGVvIg0KbmFtZXMoZGYpWzhdIDwtICJUYXNhX2VtcGxlbyINCm5hbWVzKGRmKVs5XSA8LSAiVGFzYV9lbXBsZW9fTFAiDQpuYW1lcyhkZilbMTBdIDwtICJJbmdyZXNvc19wZXJzb25hbGVzIg0KbmFtZXMoZGYpWzExXSA8LSAiQ2FsaWRhZF9hcG95b19zb2NpYWwiDQpuYW1lcyhkZilbMTJdIDwtICJOaXZlbF9lZHVjYWNpb24iDQpuYW1lcyhkZilbMTNdIDwtICJIYWJpbGlkYWRlc19kZV9lc3R1ZGlhbnRlcyINCm5hbWVzKGRmKVsxNF0gPC0gIkHDsW9zX2RlX2VkdWNhY2nDs24iDQpuYW1lcyhkZilbMTVdIDwtICJDb250YW1pbmFjaW9uX2FpcmUiDQpuYW1lcyhkZilbMTZdIDwtICJDYWxpZGFkX2FndWEiDQpuYW1lcyhkZilbMTddIDwtICJQYXJ0aWNpcGFjaW9uX3JlZ3VsYWNpb25lcyINCm5hbWVzKGRmKVsxOF0gPC0gIlBhcnRpY2lwYWNpb25fZWxlY3RvcmFsIg0KbmFtZXMoZGYpWzE5XSA8LSAiRXNwZXJhbnphX3ZpZGEiDQpuYW1lcyhkZilbMjBdIDwtICJTYWx1ZCINCm5hbWVzKGRmKVsyMV0gPC0gIlNhdGlzZmFjY2lvbl92aWRhIg0KbmFtZXMoZGYpWzIyXSA8LSAiU2VndXJpZGFkX2NhbWluYXJfc29sb3Nfbm9jaGUiDQpuYW1lcyhkZilbMjNdIDwtICJUYXNhX2hvbWljaWRpb3MiDQpuYW1lcyhkZilbMjRdIDwtICJFbXBsZWFkb3NfdHJhYmFqYW5fbXVjaGFzIg0KbmFtZXMoZGYpWzI1XSA8LSAiVGllbXBvX29jaW8iDQoNCiNFbGltaW5vIGxvcyBwYcOtc2VzIHF1ZSBubyBzb24gZGUgbGEgT0NERSB5IGxhIHByaW1lcmEgY29sdW1uYSBwb3JxdWUgeWEgbm8gbG9zIG5lY2VzaXRvLg0KZGYxIDwtIGRmICU+JSBzbGljZSgyOjM5KQ0KDQojQ29tcHJ1ZWJvIGxhIGVzdHJ1Y3R1cmEgZGUgZGF0b3MgZGUgbWkgdGFibGEgcGFyYSB2ZXIgc2kgc29uIGRhdG9zIG7Dum1lcmljb3MgeSBwdWVkbyB0cmFiYWphciBjb24gZWxsb3MNCnN0cihkZjEpDQoNCiNUcmFuc2Zvcm1vIGxvcyBkYXRvcyAoYSBkYXRvcyBudW3DqXJpY29zKSBwYXJhIHBvZGVyIHRyYWJhamFyIGNvbiBlbGxvcy4NCiNEYSB3YXJuaW5ncyBwb3JxdWUgbGEgdGFibGEgbm8gY29udGllbmUgYWxndW5vcyBkYXRvcyBwYXJhIGFsZ3Vub3MgcGHDrXNlcy4gUXVpZXJlIGRlY2lyIHF1ZSBkb25kZQ0KI2hheWEgZGF0b3MsIHBvbmRyw6EgTkHCtHMuDQpkZjIgPC0gZGYxICU+JSBtdXRhdGUoVml2aWVuZGFfc2luX2luc3RhbGFjaW9uZXNfYmFzaWNhcyA9IGFzLm51bWVyaWMoVml2aWVuZGFfc2luX2luc3RhbGFjaW9uZXNfYmFzaWNhcykpDQpkZjMgPC0gZGYyICU+JSBtdXRhdGUoR2FzdG9fZW5fdml2aWVuZGEgPSBhcy5udW1lcmljKEdhc3RvX2VuX3ZpdmllbmRhKSkNCmRmNCA8LSBkZjMgJT4lIG11dGF0ZShIYWJpdGFjaW9uZXNfcG9yX3BlcnNvbmEgPSBhcy5udW1lcmljKEhhYml0YWNpb25lc19wb3JfcGVyc29uYSkpDQpkZjUgPC0gZGY0ICU+JSBtdXRhdGUoSW5ncmVzb19mYW1pbGlhcl9kaXNwb25pYmxlID0gYXMubnVtZXJpYyhJbmdyZXNvX2ZhbWlsaWFyX2Rpc3BvbmlibGUpKQ0KZGY2IDwtIGRmNSAlPiUgbXV0YXRlKFBhdHJpbW9uaW9fZmFtaWxpYSA9IGFzLm51bWVyaWMoUGF0cmltb25pb19mYW1pbGlhKSkNCmRmNyA8LSBkZjYgJT4lIG11dGF0ZShJbnNlZ3VyaWRhZF9lbl9lbXBsZW8gPSBhcy5udW1lcmljKEluc2VndXJpZGFkX2VuX2VtcGxlbykpDQpkZjggPC0gZGY3ICU+JSBtdXRhdGUoVGFzYV9lbXBsZW8gPSBhcy5udW1lcmljKFRhc2FfZW1wbGVvKSkNCmRmOSA8LSBkZjggJT4lIG11dGF0ZShOaXZlbF9lZHVjYWNpb24gPSBhcy5udW1lcmljKE5pdmVsX2VkdWNhY2lvbikpDQpkZjEwIDwtIGRmOSAlPiUgbXV0YXRlKEhhYmlsaWRhZGVzX2RlX2VzdHVkaWFudGVzID0gYXMubnVtZXJpYyhIYWJpbGlkYWRlc19kZV9lc3R1ZGlhbnRlcykpDQpkZjExIDwtIGRmMTAgJT4lIG11dGF0ZShBw7Fvc19kZV9lZHVjYWNpw7NuID0gYXMubnVtZXJpYyhBw7Fvc19kZV9lZHVjYWNpw7NuKSkNCmRmMTIgPC0gZGYxMSAlPiUgbXV0YXRlKENvbnRhbWluYWNpb25fYWlyZSA9IGFzLm51bWVyaWMoQ29udGFtaW5hY2lvbl9haXJlKSkNCmRmMTMgPC0gZGYxMiAlPiUgbXV0YXRlKENhbGlkYWRfYWd1YSA9IGFzLm51bWVyaWMoQ2FsaWRhZF9hZ3VhKSkNCmRmMTQgPC0gZGYxMyAlPiUgbXV0YXRlKFBhcnRpY2lwYWNpb25fcmVndWxhY2lvbmVzID0gYXMubnVtZXJpYyhQYXJ0aWNpcGFjaW9uX3JlZ3VsYWNpb25lcykpDQpkZjE1IDwtIGRmMTQgJT4lIG11dGF0ZShQYXJ0aWNpcGFjaW9uX2VsZWN0b3JhbCA9IGFzLm51bWVyaWMoUGFydGljaXBhY2lvbl9lbGVjdG9yYWwpKQ0KZGYxNiA8LSBkZjE1ICU+JSBtdXRhdGUoRXNwZXJhbnphX3ZpZGEgPSBhcy5udW1lcmljKEVzcGVyYW56YV92aWRhKSkNCmRmMTcgPC0gZGYxNiAlPiUgbXV0YXRlKFNhbHVkID0gYXMubnVtZXJpYyhTYWx1ZCkpDQpkZjE4IDwtIGRmMTcgJT4lIG11dGF0ZShTYXRpc2ZhY2Npb25fdmlkYSA9IGFzLm51bWVyaWMoU2F0aXNmYWNjaW9uX3ZpZGEpKQ0KZGYxOSA8LSBkZjE4ICU+JSBtdXRhdGUoU2VndXJpZGFkX2NhbWluYXJfc29sb3Nfbm9jaGUgPSBhcy5udW1lcmljKFNlZ3VyaWRhZF9jYW1pbmFyX3NvbG9zX25vY2hlKSkNCmRmMjAgPC0gZGYxOSAlPiUgbXV0YXRlKFRhc2FfaG9taWNpZGlvcyA9IGFzLm51bWVyaWMoVGFzYV9ob21pY2lkaW9zKSkNCmRmMjEgPC0gZGYyMCAlPiUgbXV0YXRlKEVtcGxlYWRvc190cmFiYWphbl9tdWNoYXMgPSBhcy5udW1lcmljKEVtcGxlYWRvc190cmFiYWphbl9tdWNoYXMpKQ0KZGYyMiA8LSBkZjIxICU+JSBtdXRhdGUoVGllbXBvX29jaW8gPSBhcy5udW1lcmljKFRpZW1wb19vY2lvKSkNCmRmMjMgPC0gZGYyMiAlPiUgbXV0YXRlKFRhc2FfZW1wbGVvX0xQID0gYXMubnVtZXJpYyhUYXNhX2VtcGxlb19MUCkpDQpkZjI0IDwtIGRmMjMgJT4lIG11dGF0ZShJbmdyZXNvc19wZXJzb25hbGVzID0gYXMubnVtZXJpYyhJbmdyZXNvc19wZXJzb25hbGVzKSkNCmRmMjUgPC0gZGYyNCAlPiUgbXV0YXRlKENhbGlkYWRfYXBveW9fc29jaWFsID0gYXMubnVtZXJpYyhDYWxpZGFkX2Fwb3lvX3NvY2lhbCkpDQoNCiNDb21wcnVlYm8gcXVlIHRvZG8gaGF5YSBzYWxpZG8gYmllbi4NCnN0cihkZjI1KQ0KDQojRWxpbWlubyB0b2RvcyBsb3MgcGHDrXNlcyBxdWUgbm8gZXN0ZW4gZW4gbGEgVUUgYSBleGNlcGNpw7NuIGRlIFVLIHkgbGEgbWVkaWEgZGUgbGEgT0RDRSBxdWUgbWUgc2Vydmlyw6EgcGFyYSBjb21wYXJhci4NCmRmXzwtIGRmMjUgJT4lIGZpbHRlcihQYWlzZXMgJWluJSBjKCJBdXN0cmlhIiwiQmVsZ2l1bSIsIkJ1bGdhcmlhIiwiQ3JvYXRpYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkN6ZWNoIFJlcHVibGljIiwiRGVubWFyayIsIkVzdG9uaWEiLCJGaW5sYW5kIiwiRnJhbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2VybWFueSIsIkdyZWVjZSIsIkh1bmdhcnkiLCJJcmVsYW5kIiwiSXRhbHkiLCJMYXR2aWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMaXRodWFuaWEiLCJMdXhlbWJvdXJnIiwiTmV0aGVybGFuZHMiLCJQb2xhbmQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3J0dWdhbCIsIlNsb3ZhayBSZXB1YmxpYyIsIlNsb3ZlbmlhIiwiU3BhaW4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTd2VkZW4iLCJVbml0ZWQgS2luZ2RvbSIsIlN3aXR6ZXJsYW5kIiwiT0VDRCAtIFRvdGFsIikpDQoNCiNHdWFyZG8gbG8gaGVjaG8gcGFyYSBubyB0ZW5lciBxdWUgdm9sdmVybG8gYSBoYWNlciBlbiBjYWRhIGNodWNrLg0KZXhwb3J0KGRmXywgIi4vZGF0b3MvY2FsaWRhZHZpZGFfZGVmaW5pdGl2by5jc3YiKSAgICMgY29tbWEtc2VwYXJhdGVkIHZhbHVlcw0KDQpgYGANCg0KIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gMi4xLiBQcm9jZXNhbmRvIGxvcyBkYXRvcyA8L0ZPTlQ+DQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPg0KDQpFbCBwcm9jZXNhbWllbnRvIGRlIGxvcyBkYXRvcyBjb21vIHRhbCBoYSBxdWVkYWRvIHJlZmxlamFkbyBlbiBlbCBhbnRlcmlvciBhcGFydGFkbyBwZXJvIG1lIGd1c3RhcsOtYSBoYWNlciB1biBicmV2ZSByZXN1bWVuIGRlbCBtaXNtbyBhcXXDrToNCg0KPHN0eWxlPg0KZGl2LmJsdWUgeyBiYWNrZ3JvdW5kLWNvbG9yOiNlNmYwZmY7IGJvcmRlci1yYWRpdXM6IDVweDsgcGFkZGluZzogMjBweDt9DQo8L3N0eWxlPg0KPGRpdiBjbGFzcyA9ICJibHVlIj4NCg0KMS4gRXhwb3J0YXIgZWwgYXJjaGl2byBkZXNjYXJnYWRvIGRlIGxhIHdlYi4NCjIuIERlZmluaXIgZWwgbm9tYnJlIGRlIGxhcyBjb2x1bW5hcy4NCjMuIFNlbGVjY2lvbm8gbG9zIHBhw61zZXMgcGVydGVuZWNpZW50ZXMgYSBsYSBPQ0RFIGNvbW8gcHJpbWVyIGZpbHRyby4NCjQuIENvbXBydWVibG8gbGEgZXN0cnVjdHVyYSBkZSBsb3MgZGF0b3MgcGFyYSB2ZXIgc2kgcHVlZG8gdHJhYmFqYXJsb3MuDQo1LiBBbCB2ZXIgcXVlIG5vIHNvbiBuw7ptZXJpY29zLCBsb3MgdGVuZ28gcXVlIHRyYW5zZm9ybWFyLg0KNi4gRmlsdHJvIHVubyBhIHVubyBsb3MgcGHDrXNlcyBvYmpldG8gZGVsIGVzdHVkaW8uDQo3LiBQYXJhIG5vIGhhY2VyIHRvZG8gZXN0ZSBwcm9jZXNvIGEgbWVudWRvLCBkZWNpZG8gaW1wb3J0YXIgbG9zIGRhdG9zIGZpbmFsZXMgZW4gdW4gYXJjaGl2byBxdWUgaXLDqSBjYXJnYW5kbyBlbiBhZGVsYW50ZS4NCg0KVHJhcyB0b2RvIGVzdGUgbGFyZ28gcHJvY2VzbywgbWkgdGFibGEgbWFlc3RyYSBkZSBkYXRvcyBxdWVkYSBmaW5hbGl6YWRhLiBFbiBlc3RlIGNhc28gaGUgb3B0YWRvIHBvciBoYWNlcmxhIGludGVyYWN0aXZhIHBvciBzaSBhbGd1bmEgcGVyc29uYSBlc3TDoSBpbnRlcmVzYWRhIGVuIGRlc2NhcmdhciBsb3MgZGF0b3MuDQoNCjwvZGl2Pg0KYGBge3IsIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQpkZiA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQpkZl90YWJsYV9pbnRlcmFjdGl2YSA8LSBkZl8gDQoNCmRmX3RhYmxhX2ludGVyYWN0aXZhICU+JSBEVDo6ZGF0YXRhYmxlKGV4dGVuc2lvbnMgPSAnQnV0dG9ucycsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KGRvbSA9ICdCbGZydGlwJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2NvcHknLCAnY3N2JywgJ2V4Y2VsJywgJ3BkZicsICdwcmludCcpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gNSwgYXV0b1dpZHRoID0gVFJVRSApKSAlPiUgZm9ybWF0U3R5bGUgKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1NhdGlzZmFjY2lvbl92aWRhJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3IgPSAnI0Y1OTk4NScsICkgDQpgYGANCg0KDQojIDxGT05UIENPTE9SPSJPcmFuZ2UiPiAzLiBFc3RydWN0dXJhIGRlIGRhdG9zIGRlbCBpbmZvcm1lLiA8L0ZPTlQ+DQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPg0KDQoqKkVsIMONbmRpY2UgcGFyYSB1bmEgVmlkYSBNZWpvcioqIGFuYWxpemEgKjExIHZhcmlhYmxlcyogcXVlIGxhIE9DREUgaGEgY29uc2lkZXJhZG8gZnVuZGFtZW50YWxlcyBwYXJhIGxhcyBjb25kaWNpb25lcyBkZSB2aWRhIGRlIGxhcyBwZXJzb25hcy4gQSBzdSB2ZXogZGVudHJvIGRlIGVzdGFzIHZhcmlhYmxlcyBzZSBhbmFsaXphbiBkaXN0aW50b3MgKmluZGljYWRvcmVzKiBxdWUgc2lydmVuIHBhcmEgZXZhbHVhciBkaWNoYSB2YXJpYWJsZSBlbiBjYWRhIHVubyBkZSBsb3MgcGHDrXNlcyBvYmpldG8gZGUgZXN0ZSDDrW5kaWNlLg0KDQpMYSBlc3RydWN0dXJhIGRlIGxvcyBkYXRvcyBhbmFsaXphZG9zLCBkZSBmb3JtYSBlc3F1ZW3DoXRpY2EsIGVzIGxhIHNpZ3VpZW50ZToNCg0KMS4gVml2aWVuZGE6DQotIEdhc3RvIGVuIFZpdmllbmRhDQotIFZpdmllbmRhIGNvbiBpbnN0YWxhY2lvbmVzIGLDoXNpY2FzDQotIEhhYml0YWNpb25lcyBwb3IgcGVyc29uYQ0KMi4gSW5ncmVzb3MNCi0gUGF0cmltb25pbyBmYW1pbGlhciBuZXRvcw0KLSBJbmdyZXNvcyBmYW1pbGlhciBkaXNwb25pYmxlDQozLiBFbXBsZW8NCi0gSW5ncmVzb3MgcGVyc29uYWxlcw0KLSBTZWd1cmlkYWQgZW4gZWwgZW1wbGVvDQotIFRhc2EgZGUgZW1wbGVvIGEgTFANCi0gVGFzYSBkZSBlbXBsZW8NCjQuIENvbXVuaWRhZA0KLSBDYWxpZGFkIGRlIGFwb3lvIHNvY2lhbA0KNS4gRWR1Y2FjacOzbg0KLSBBw7FvcyBkZSBlZHVjYWNpw7NuDQotIENvbXBldGVuY2lhcyBkZSBsb3MgZXN0dWRpYW50ZXMNCi0gTml2ZWwgZGUgZWR1Y2FjacOzbi4NCjYuIE1lZGlvIEFtYmllbnRlDQotIENhbGlkYWQgZGVsIGFndWENCi0gQ29udGFtaW5hY2nDs24gZGVsIGFpcmUNCjcuIENvbXByb21pc28gY8Otdmljbw0KLSBQYXJ0aWNpcGFjacOzbiBlbGVjdG9yYWwNCi0gUGFydGljaXBhY2nDs24gZGUgbG9zIGludGVyZXNhZG9zIGVuIGxhIGVsYWJvcmFjacOzbiBkZSByZWd1bGFjaW9uZXMNCjguIFNhbHVkDQotIEVzcGVyYW56YSBkZSB2aWRhDQotIFNhbHVkLCBzZWfDum4gbGFzIHBlcnNvbmFzDQo5LiBTYXRpc2ZhY2nDs24gYW50ZSBsYSB2aWRhDQoxMC4gU2VndXJpZGFkDQotIFRhc2EgZGUgaG9taWNpZGlvcyANCi0gU2VudGltaWVudG8gZGUgc2VndXJpZGFkIGFsIGNhbWluYXIgc29sb3MgcG9yIGxhIG5vY2hlDQoxMS4gQmFsYW5jZSB2aWRhLXRyYWJham8NCi0gVGllbXBvIGRlc3RpbmFkbyBhbCBvY2lvDQotIEVtcGxlYWRvcyBxdWUgdHJhYmFqYW4gbXVjaGFzIGhvcmFzDQoNCjxkaXYvPg0KDQojIDxGT05UIENPTE9SPSJPcmFuZ2UiPiA0LiDDjW5kaWNlIHBhcmEgdW5hIHZpZGEgbWVqb3IuIDwvRk9OVD4NCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+DQoNClBhc2Ftb3MgYSBhbmFsaXphciBhaG9yYSBhbGd1bmEgZGUgbGFzIHZhcmlhYmxlcyByZXByZXNlbnRhZGFzIGVuIGVsIGVzcXVlbWEgYW50ZXJpb3IgcGFyYSBsb3MgcGHDrXNlcyBldXJvcGVvcy4NCg0KTGEgZXN0cnVjdHVyYSBkZWwgYW7DoWxpc2lzIHNlcsOhIHNpbXBsZSB5IHJlcGV0aWRhIHBhcmEgY2FkYSB2YXJpYWJsZSBhbmFsaXphZGEuIEVzdHVkaWFyZW1vcyB1biBpbmRpY2Fkb3IgKHZlciBlc3F1ZW1hIGFudGVyaW9yKSBlbiBjYWRhIHVuYSBkZSBlbGxhcyB5IGxvIHJlbGFjaW9uYXJlbW9zIGNvbiBsb3MgaW5ncmVzb3MgcGVyc29uYWxlcyBkZSBjYWRhIHVuYSBkZSBsb3MgcGHDrXNlcy4gUG9zdGVyaW9ybWVudGUgY29uc3RydWlyZW1vcyB1bmEgdGFibGEsIHVuIGdyw6FmaWNvLHVuIG1hcGEgeSBlbCBjaHVuayBjb24gZWwgbGVuZ3VhamUgdXRpbGl6YWRvLg0KDQpFbCBvYmpldGl2byBwcmlvcml0YXJpbyBkZSBlc3RlIHRyYWJham8gZXMgY29tcHJvYmFyIHNpIGVzdGFzIHZhcmlhYmxlcyBlc3TDoW4gcmVsYWNpb25hZGFzIGRpcmVjdGFtZW50ZSBjb24gbG9zIGluZ3Jlc29zLiBFcyBkZWNpciwgbG9zIHBhw61zZXMgbcOhcyByaWNvcyBzaWVtcHJlIHRlbmRyw6FuIHZhbG9yZXMgbcOhcyBhbHRvcyBlbiBsYXMgdmFyaWFibGVzIGFuYWxpemFkYXMgKGdhc3RvIGVuIHZpdmllbmRhLCBiaWVuZXN0YXIsIGVtcGxlbywgLi4uLCBldGMuKS4NCg0KPGRpdi8+DQoNCg0KIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuMS4gVml2aWVuZGE6IEdhc3RvIGVuIFZpdmllbmRhIDwvRk9OVD4gey50YWJzZXR9DQoNCiMjIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC4xLjEuIFRhYmxhIGRhdG9zLiA8L0ZPTlQ+DQoNCkxhIHZpdmllbmRhIGVzIHVuIGJpZW4gZGUgcHJpbWVyYSBuZWNlc2lkYWQgeSB1biBkZXJlY2hvIGZ1bmRhbWVudGFsIGVuIGxhIG1heW9yw61hIGRlIGxhcyBzb2NpZWRhZGVzIGRlc2Fycm9sbGFkYXMgZGUgbnVlc3RybyBlbnRvcm5vLiBFcyB1bmEgb2J2aWVkYWQgZGVjaXIgcXVlIHNpIGVsIGdhc3RvIGVuIHZpdmllbmRhIGVzIGRlbWFzaWFkbyBncmFuZGUsIGVuIGZ1bmNpw7NuIGRlIGxvcyBpbmdyZXNvcywgbG9zIGluZGl2aWR1b3MgcXVlIGludGVncmFuIHVuYSBzb2NpZWRhZCB2aXZpcsOhbiBwZW9yIHBvcnF1ZSBubyBwb2Ryw6FuIGRlc3RpbmFyIGVzb3MgaW5ncmVzb3MgYSBvdHJhcyBhY3RpdmlkYWRlcyBxdWUgbGUgcmVwb3J0YXLDrWFuIG1heW9yIGZlbGljaWRhZC4NCg0KU2kgb2JzZXJ2YW1vcyBsYSB0YWJsYSwgbG9zIGNpdWRhZGFub3MgZGUgcGHDrXNlcyBjb21vIFJlaW5vIFVuaWRvLCBSZXDDumJsaWNhIENoZWNhLCBJdGFsaWEgbyBHcmVjaWEsIGdhc3RhbiBkZW1hc2lhZG8gcG9yY2VudGFqZSBkZSBzdXMgaW5ncmVzb3MgZW4gdml2aWVuZGEuIA0KDQpQb3IgZWwgb3RybyBsYWRvLCBsb3MgY2l1ZGFkYW5vcyBkZSBTdWVjaWEsIEhvbGFuZGEsIEVzdG9uaWEgeSBFc2xvdmVuaWEgZXN0w6FuIGVuIHVuYSBwb3NpY2nDs24gbWVqb3IsIGVuIGVzdGUgaW5kaWNhZG9yLCBxdWUgc3VzIHZlY2lub3MgZXVyb3Blb3MuDQoNClBvciBsbyBxdWUgcmVzcGVjdGEgYSBsb3MgZXNwYcOxb2xlcywgcG9kZW1vcyBkZWNpciBxdWUgbm9zIGVuY29udHJhbW9zIG11eSBjZXJjYSBkZSBsYSBtZWRpYSBkZSBsYSBPQ0RFIGVuIGxvIHF1ZSByZXNwZWN0YSBhbCBwb3JjZW50YWplIGRlIHJlbnRhIHF1ZSBkZWRpY2Ftb3MgYSBsYSB2aXZpZW5kYS4NCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCmRmXyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmdml2MSA8LSBkZl8gJT4lIHNlbGVjdChQYWlzZXMsR2FzdG9fZW5fdml2aWVuZGEsSW5ncmVzb3NfcGVyc29uYWxlcykgJT4lIGFycmFuZ2UoZGVzYyhHYXN0b19lbl92aXZpZW5kYSkpIA0KDQpkZnZpdjEgPC0gbmEub21pdChkZnZpdjEpDQoNCmtuaXRyOjprYWJsZShkZnZpdjEsIGZvcm1hdCA9ICJodG1sIikgJT4lIA0KICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpKQ0KDQpgYGANCg0KDQoNCg0KDQojIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuMS4yLiBHcsOhZmljYS4gPC9GT05UPg0KDQpFbiBlbCBhbsOhbGlzaXMgZ3LDoWZpY28gaGVtb3MgcmVsYWNpb25hZG8gbG9zIGluZ3Jlc29zIGRlIGxvcyBjaXVkYWRhbm9zIGRlIGNhZGEgcGHDrXMgY29uIGVsIHBvcmNlbnRhamUgcXVlIGdhc3RhbiBlbiB2aXZpZW5kYSwgY29uIGVsIG9iamV0aXZvIGRlIGVzdHVkaWFyIHNpIGhheSBhbGfDum4gdGlwbyBkZSByZWxhY2nDs24uIA0KDQpDb21vIHBvZGVtb3MgY29tcHJvYmFyIHZpc3VhbG1lbnRlLCBubyBsYSBoYXkuIA0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KZGZfIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2NhbGlkYWR2aWRhX2RlZmluaXRpdm8uY3N2IikgI2V4cG9ydG8gbG9zIGRhdG9zDQoNCmRmdml2MSA8LSBkZl8gJT4lIHNlbGVjdChQYWlzZXMsR2FzdG9fZW5fdml2aWVuZGEsSW5ncmVzb3NfcGVyc29uYWxlcykgI0dhc3RvIGVuIHZpdmllbmRhDQoNCmRmdml2MSA8LSBuYS5vbWl0KGRmdml2MSkjZWxpbWlubyBhIGxvcyBwYWlzZXMgcXVlIG5vIHRlbmdhbiBkYXRvcw0KDQpnZ3Bsb3QoZGZ2aXYxLCBhZXMoSW5ncmVzb3NfcGVyc29uYWxlcywgR2FzdG9fZW5fdml2aWVuZGEsIGxhYmVsID0gUGFpc2VzKSkgKyANCiAgZ2VvbV9wb2ludCgpICsgDQogIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihkZnZpdjEsIFBhaXNlcyA9PSAiU3BhaW4iKSwgY29sb3VyID0gInBpbmsiLCBzaXplID0gNikrIA0KICBnZW9tX3BvaW50KGRhdGEgPSBmaWx0ZXIoZGZ2aXYxLCBQYWlzZXMgPT0gIk9FQ0QgLSBUb3RhbCIpLCBjb2xvdXIgPSAidmlvbGV0Iiwgc2l6ZSA9IDYpKw0KICBsYWJzKHRpdGxlID0gIlJlbGFjacOzbiBlbnRyZSBpbmdyZXNvcyB5IGdhc3RvIGVuIHZpdmllbmRhIiAsDQogICAgICAgeSA9ICJJbmdyZXNvcyBwZXJzb25hbGVzIChlbiBkw7NsYXJlcykiLA0KICAgICAgIHggPSAiR2FzdG8gZW4gdml2aWVuZGEgKGVuIHBvcmNlbnRhamUpIiwNCiAgICAgICBjYXB0aW9uID0gIkZ1ZW50ZSBPQ0RFIikrDQogIGdlb21fc21vb3RoKCkrIGdlb21fbGFiZWxfcmVwZWwoKSsgdGhlbWVfbWluaW1hbCgpDQpgYGAgDQoNCiAgICAgICAgICAgICAgICAgDQojIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuMS4zLiBNYXBhLiA8L0ZPTlQ+DQoNClNpIHRyYW5zZmVyaW1vcyBsb3MgZGF0b3MgZGUgbGEgdGFibGEgY3JlYWRhIGVuIGVsIHByaW1lciBhcGFydGFkbyBhIHVuIG1hcGEsIHF1ZWRhIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6DQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQptYXBhZGF0YV9VRTwtIG1hcF9kYXRhKCJ3b3JsZCIpICU+JSBmaWx0ZXIocmVnaW9uICVpbiUgYygiQXVzdHJpYSIsIkJlbGdpdW0iLCJCdWxnYXJpYSIsIkNyb2F0aWEiLCJDeXBydXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkN6ZWNoIFJlcHVibGljIiwiRGVubWFyayIsIkVzdG9uaWEiLCJGaW5sYW5kIiwiRnJhbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHZXJtYW55IiwiR3JlZWNlIiwiSHVuZ2FyeSIsIklyZWxhbmQiLCJJdGFseSIsIkxhdHZpYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGl0aHVhbmlhIiwiTHV4ZW1ib3VyZyIsIk1hbHRhIiwiTmV0aGVybGFuZHMiLCJQb2xhbmQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcnR1Z2FsIiwiUm9tYW5pYSIsIlNsb3Zha2lhIiwiU2xvdmVuaWEiLCJTcGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3dlZGVuIiwiVUsiLCJTd2l0emVybGFuZCIsIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiLCJTZXJiaWEiLCJVa3JhaW5lIiwiQmVsYXJ1cyIsIkFsYmFuaWEiLCJNb250ZW5lZ3JvIiwiS29zb3ZvIiwiTWFjZWRvbmlhIiwiTW9sZG92YSIpKQ0KDQptYXBhZGF0YV9VRV8gPC0gbWFwYWRhdGFfVUUgJT4lIG11dGF0ZShyZWdpb24gPSBjYXNlX3doZW4oDQogIHJlZ2lvbiA9PSAiVUsiIH4gIlVuaXRlZCBLaW5nZG9tIiwNCiAgVFJVRSAgfiAgcmVnaW9uICkpDQoNCm1hcGRhdGFfVUVfIDwtIGZ1bGxfam9pbiAobWFwYWRhdGFfVUVfLGRmdml2MSwgYnkgPSBjKCJyZWdpb24iPSJQYWlzZXMiKSkNCg0KbWFwYXBsb3QgPC0gZ2dwbG90KG1hcGRhdGFfVUVfLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gR2FzdG9fZW5fdml2aWVuZGEpICkgKw0KICBnZW9tX3BvbHlnb24oY29sb3IgPSIjZmZmZmZmIikgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjMzEzMjAwIixoaWdoID0gIiNmN2ZmMDAiKSArDQogIGxhYnMoZmlsbD0iR2FzdG9fZW5fdml2aWVuZGEiLA0KICAgICAgIHg9TlVMTCwNCiAgICAgICB5PU5VTEwsDQogICAgICAgdGl0bGU9Ikdhc3RvIGVuIHZpdmllbmRhIChlbiBwb3JjZW50YWplKSBlbiBFdXJvcGEiLA0KICAgICAgIGNhcHRpb249IkZ1ZW50ZTogT0NERSIpICsNCiAgdGhlbWUoIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICIjZmZmZmZmIiksDQogICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gImNvcm5zaWxrMiIsIGNvbG91ciA9ICJsYXZlbmRlcmJsdXNoIiwgc2l6ZSA9IDAuMSApLA0KICAgICAgICAgcGFuZWwuZ3JpZCAgPSBlbGVtZW50X2xpbmUoIGNvbG91ciA9ImdyZXkiKSwNCiAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsY29sb3VyID0gImJsYWNrIiksDQogICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICJjb3Juc2lsazIiLCBjb2xvdXIgPSAiYmxhY2siICksDQogICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gNSwgciA9IDUsIGIgPSA1LDEwKSApDQoNCm1hcGFwbG90ICsgc2NhbGVfZmlsbF92aXJpZGlzX2MoZGlyZWN0aW9uID0gLTEpDQoNCg0KYGBgIA0KDQojIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuMS40LiBDaHVua3MuIDwvRk9OVD4NCg0KRW4gZXN0ZSBhcGFydGFkbyBzZSBtdWVzdHJhbiBsb3MgdHJvem9zIGRlIGPDs2RpZ28gUiAoY2h1bmspIHV0aWxpemFkb3MgcGFyYSBoYWNlciBsYSB0YWJsYSwgZWwgZ3LDoWZpY28geSBlbCBtYXBhLiBTZXBhcsOhbmRvbG8gZGUgbG9zIGRlbcOhcywgaGFjZSBxdWUgbGEgbGVjdHVyYSBkZWwgdHJhYmFqbyBzZWEgbcOhcyBmw6FjaWwgeSBhbWVuYS4NCg0KYGBge3IsIGVjaG8gPSBUUlVFLCBldmFsID0gRkFMU0V9DQoNCiNBc8OtIGhlIGhlY2hvIGxhIHRhYmxhDQoNCmRmXyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmdml2MSA8LSBkZl8gJT4lIHNlbGVjdChQYWlzZXMsR2FzdG9fZW5fdml2aWVuZGEsSW5ncmVzb3NfcGVyc29uYWxlcykgJT4lIGFycmFuZ2UoZGVzYyhJbmdyZXNvc19wZXJzb25hbGVzKSkgDQoNCmRmdml2MSA8LSBuYS5vbWl0KGRmdml2MSkNCg0Ka25pdHI6OmthYmxlKGRmdml2MSwgZm9ybWF0ID0gImh0bWwiKSAlPiUgDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIikpDQoNCiNBc8OtIGhlIGhlY2hvIGVsIGdyw6FmaWNvDQoNCmRmXyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpIA0KDQpkZnZpdjEgPC0gZGZfICU+JSBzZWxlY3QoUGFpc2VzLEdhc3RvX2VuX3ZpdmllbmRhLEluZ3Jlc29zX3BlcnNvbmFsZXMpIA0KDQpkZnZpdjEgPC0gbmEub21pdChkZnZpdjEpDQoNCmdncGxvdChkZnZpdjEsIGFlcyhJbmdyZXNvc19wZXJzb25hbGVzLCBHYXN0b19lbl92aXZpZW5kYSwgbGFiZWwgPSBQYWlzZXMpKSArIA0KICBnZW9tX3BvaW50KCkgKyANCiAgZ2VvbV9wb2ludChkYXRhID0gZmlsdGVyKGRmdml2MSwgUGFpc2VzID09ICJTcGFpbiIpLCBjb2xvdXIgPSAicGluayIsIHNpemUgPSA2KSsgDQogIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihkZnZpdjEsIFBhaXNlcyA9PSAiT0VDRCAtIFRvdGFsIiksIGNvbG91ciA9ICJ2aW9sZXQiLCBzaXplID0gNikrDQogIGxhYnModGl0bGUgPSAiUmVsYWNpw7NuIGVudHJlIGluZ3Jlc29zIHkgZ2FzdG8gZW4gdml2aWVuZGEiICwNCiAgICAgICB5ID0gIkluZ3Jlc29zIHBlcnNvbmFsZXMgKGVuIGTDs2xhcmVzKSIsDQogICAgICAgeCA9ICJHYXN0byBlbiB2aXZpZW5kYSAoZW4gcG9yY2VudGFqZSkiLA0KICAgICAgIGNhcHRpb24gPSAiRnVlbnRlIE9DREUiKSsNCiAgZ2VvbV9zbW9vdGgoKSsgZ2VvbV9sYWJlbF9yZXBlbCgpKyB0aGVtZV9taW5pbWFsKCkNCg0KI0Fzw60gaGUgaGVjaG8gZWwgbWFwYQ0KDQptYXBhZGF0YV9VRTwtIG1hcF9kYXRhKCJ3b3JsZCIpICU+JSBmaWx0ZXIocmVnaW9uICVpbiUgYygiQXVzdHJpYSIsIkJlbGdpdW0iLCJCdWxnYXJpYSIsIkNyb2F0aWEiLCJDeXBydXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkN6ZWNoIFJlcHVibGljIiwiRGVubWFyayIsIkVzdG9uaWEiLCJGaW5sYW5kIiwiRnJhbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHZXJtYW55IiwiR3JlZWNlIiwiSHVuZ2FyeSIsIklyZWxhbmQiLCJJdGFseSIsIkxhdHZpYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGl0aHVhbmlhIiwiTHV4ZW1ib3VyZyIsIk1hbHRhIiwiTmV0aGVybGFuZHMiLCJQb2xhbmQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcnR1Z2FsIiwiUm9tYW5pYSIsIlNsb3Zha2lhIiwiU2xvdmVuaWEiLCJTcGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3dlZGVuIiwiVUsiLCJTd2l0emVybGFuZCIsIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiLCJTZXJiaWEiLCJVa3JhaW5lIiwiQmVsYXJ1cyIsIkFsYmFuaWEiLCJNb250ZW5lZ3JvIiwiS29zb3ZvIiwiTWFjZWRvbmlhIiwiTW9sZG92YSIpKQ0KDQptYXBhZGF0YV9VRV8gPC0gbWFwYWRhdGFfVUUgJT4lIG11dGF0ZShyZWdpb24gPSBjYXNlX3doZW4oDQogIHJlZ2lvbiA9PSAiVUsiIH4gIlVuaXRlZCBLaW5nZG9tIiwNCiAgVFJVRSAgfiAgcmVnaW9uICkpDQoNCm1hcGRhdGFfVUVfIDwtIGZ1bGxfam9pbiAobWFwYWRhdGFfVUVfLGRmdml2MSwgYnkgPSBjKCJyZWdpb24iPSJQYWlzZXMiKSkNCg0KbWFwYXBsb3QgPC0gZ2dwbG90KG1hcGRhdGFfVUVfLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gR2FzdG9fZW5fdml2aWVuZGEpICkgKw0KICBnZW9tX3BvbHlnb24oY29sb3IgPSIjZmZmZmZmIikgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjMzEzMjAwIixoaWdoID0gIiNmN2ZmMDAiKSArDQogIGxhYnMoZmlsbD0iR2FzdG9fZW5fdml2aWVuZGEiLA0KICAgICAgIHg9TlVMTCwNCiAgICAgICB5PU5VTEwsDQogICAgICAgdGl0bGU9Ikdhc3RvIGVuIHZpdmllbmRhIChlbiBwb3JjZW50YWplKSBlbiBFdXJvcGEiLA0KICAgICAgIGNhcHRpb249IkZ1ZW50ZTogT0NERSIpICsNCiAgdGhlbWUoIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICIjZmZmZmZmIiksDQogICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gImNvcm5zaWxrMiIsIGNvbG91ciA9ICJsYXZlbmRlcmJsdXNoIiwgc2l6ZSA9IDAuMSApLA0KICAgICAgICAgcGFuZWwuZ3JpZCAgPSBlbGVtZW50X2xpbmUoIGNvbG91ciA9ImdyZXkiKSwNCiAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsY29sb3VyID0gImJsYWNrIiksDQogICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICJjb3Juc2lsazIiLCBjb2xvdXIgPSAiYmxhY2siICksDQogICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gNSwgciA9IDUsIGIgPSA1LDEwKSApDQoNCm1hcGFwbG90ICsgc2NhbGVfZmlsbF92aXJpZGlzX2MoZGlyZWN0aW9uID0gLTEpDQoNCmBgYA0KDQojIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC4yLkluZ3Jlc29zOkluZy4gZmFtaWxpYXJlcyBuZXRvcyA8L0ZPTlQ+IHsudGFic2V0fQ0KDQojIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuMi4xLiBUYWJsYSBkYXRvcy4gPC9GT05UPg0KDQpRdWl6w6EgcGFyYSBtdWNob3MgaW5kaXZpZHVvcyBlbCBpbmRpY2Fkb3IgbcOhcyBpbXBvcnRhbnRlIGRlbCBiaWVuZXN0YXIgZGUgdW5hIHNvY2llZGFkIHNvbiBlbCBuaXZlbCBkZSBpbmdyZXNvcyBkZSBzdXMgY2l1ZGFkYW5vcy4gUHVlcyBiaWVuLCBlbiBlc3RlIGFwYXJ0YWRvIHZhbW9zIGEgdmVyIHF1ZSBjaXVkYWRhbm9zIGV1cm9wZW9zIHNvbiBsb3MgbcOhcyAqImFmb3J0dW5hZG9zIiouDQoNCkx1eGVtYnVyZ28sIFN1aXphIHkgQWxlbWFuaWEgbGlkZXJhbiBlc3RlIHJhbmtpbmcuIE5vIGhheSBzb3JwcmVzYXMuDQoNCkxvcyBwYcOtc2VzIGRlbCBlc3RlIGRlIEV1cm9wYSAow7psdGltb3MgZW4gZW50cmFyIGVuIGxhIFVFKSB5IEdyZWNpYSBlc3TDoW4gYSBsYSBjb2xhLg0KDQpFc3Bhw7FhIHNlIGVuY3VlbnRyYSBlbiBsYSBtaXRhZCBkZSBsYSB0YWJsYSBwZXJvIG11eSBkaXN0YW5jaWFkbyBkZSBsYSBtZWRpYSBkZSBsb3MgcGHDrXNlcyBxdWUgcGVydGVuZWNlbiBhIGxhIE9DREUuIA0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KZGZfIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2NhbGlkYWR2aWRhX2RlZmluaXRpdm8uY3N2IikNCg0KZGZfaW5nIDwtIGRmXyAgJT4lIHNlbGVjdChQYWlzZXMsSW5ncmVzb19mYW1pbGlhcl9kaXNwb25pYmxlKSU+JSBhcnJhbmdlKGRlc2MoSW5ncmVzb19mYW1pbGlhcl9kaXNwb25pYmxlKSkNCg0KZGZfaW5nIDwtIG5hLm9taXQoZGZfaW5nKQ0KDQpkZl9pbmcgJT4lIGd0KCkNCg0KYGBgDQoNCg0KIyMjIDxGT05UIENPTE9SPSJPcmFuZ2UiPiA0LjIuMi4gR3LDoWZpY2EuIDwvRk9OVD4NCg0KQXF1w60gbXVlc3RybyBsYSB0YWJsYSBkZWwgcHJpbWVyIGFwYXJ0YWRvIGVuIHVuIGdyw6FmaWNvIGRlIGJhcnJhcy4NCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCmRmXyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmX2luZyA8LSBkZl8gICU+JSBzZWxlY3QoUGFpc2VzLEluZ3Jlc29fZmFtaWxpYXJfZGlzcG9uaWJsZSxQYXRyaW1vbmlvX2ZhbWlsaWEpDQoNCmRmX2luZyA8LSBuYS5vbWl0KGRmX2luZykjZWxpbWlubyBhIGxvcyBwYWlzZXMgcXVlIG5vIHRlbmdhbiBkYXRvcw0KDQpncmFmaWNvQSA8LSBnZ3Bsb3QoZGZfaW5nLCBhZXMoZm9yY2F0czo6ZmN0X3Jlb3JkZXIoUGFpc2VzLCBJbmdyZXNvX2ZhbWlsaWFyX2Rpc3BvbmlibGUpLCBJbmdyZXNvX2ZhbWlsaWFyX2Rpc3BvbmlibGUpKSArDQogIGdlb21fY29sKGFlcyhmaWxsID0gSW5ncmVzb19mYW1pbGlhcl9kaXNwb25pYmxlKSkrIGNvb3JkX2ZsaXAoKSsgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTkwLCB2anVzdD0wLjYpLCBwYW5lbC5iYWNrZ3JvdW5kID0gTlVMTCkrDQogIGxhYnModGl0bGUgPSAiSW5ncmVzb3MgZmFtaWxpYXJlcyBkaXNwb25pYmxlcyAoZW4gZMOzbGFyZXMpIiwgc3VidGl0bGUgPSAiUG9yIHBhw61zZXMiLCBjYXB0aW9uPSJGdWVudGU6IE9DREUiKSArIA0KICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCkrIHRyYW5zaXRpb25fcmV2ZWFsKEluZ3Jlc29fZmFtaWxpYXJfZGlzcG9uaWJsZSkNCg0KZ3JhZmljb0EgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQpgYGAgDQoNCiAgICAgICAgICAgICAgICAgDQojIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuMi4zLiBNYXBhLiA8L0ZPTlQ+DQoNClNpIHRyYW5zZmVyaW1vcyBsb3MgZGF0b3MgZGUgbGEgdGFibGEgY3JlYWRhIGVuIGVsIHByaW1lciBhcGFydGFkbyBhIHVuIG1hcGEuIFBvZGVtb3Mgb2JzZXJ2YXIgcXVlIGxvcyBwYcOtc2VzIGNlbnRyb2V1cm9wZW9zIHkgbG9zZGVsIG5vcnRlIGRlIGV1cm9wYSBzb24gbG9zIG3DoXMgYWZvcnR1bmFkb3MuDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQptYXBhZGF0YV9VRTwtIG1hcF9kYXRhKCJ3b3JsZCIpICU+JSBmaWx0ZXIocmVnaW9uICVpbiUgYygiQXVzdHJpYSIsIkJlbGdpdW0iLCJCdWxnYXJpYSIsIkNyb2F0aWEiLCJDeXBydXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkN6ZWNoIFJlcHVibGljIiwiRGVubWFyayIsIkVzdG9uaWEiLCJGaW5sYW5kIiwiRnJhbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHZXJtYW55IiwiR3JlZWNlIiwiSHVuZ2FyeSIsIklyZWxhbmQiLCJJdGFseSIsIkxhdHZpYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGl0aHVhbmlhIiwiTHV4ZW1ib3VyZyIsIk1hbHRhIiwiTmV0aGVybGFuZHMiLCJQb2xhbmQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcnR1Z2FsIiwiUm9tYW5pYSIsIlNsb3Zha2lhIiwiU2xvdmVuaWEiLCJTcGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3dlZGVuIiwiVUsiLCJTd2l0emVybGFuZCIsIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiLCJTZXJiaWEiLCJVa3JhaW5lIiwiQmVsYXJ1cyIsIkFsYmFuaWEiLCJNb250ZW5lZ3JvIiwiS29zb3ZvIiwiTWFjZWRvbmlhIiwiTW9sZG92YSIpKQ0KDQptYXBhZGF0YV9VRV8gPC0gbWFwYWRhdGFfVUUgJT4lIG11dGF0ZShyZWdpb24gPSBjYXNlX3doZW4oDQogIHJlZ2lvbiA9PSAiVUsiIH4gIlVuaXRlZCBLaW5nZG9tIiwNCiAgVFJVRSAgfiAgcmVnaW9uICkpDQoNCm1hcGRhdGFfVUVfIDwtIGZ1bGxfam9pbiAobWFwYWRhdGFfVUVfLGRmX2luZywgYnkgPSBjKCJyZWdpb24iPSJQYWlzZXMiKSkNCg0KDQptYXBhcGxvdDIgPC0gZ2dwbG90KG1hcGRhdGFfVUVfLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gSW5ncmVzb19mYW1pbGlhcl9kaXNwb25pYmxlKSApICsNCiAgZ2VvbV9wb2x5Z29uKGNvbG9yID0iI2ZmZmZmZiIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiIzMxMzIwMCIsaGlnaCA9ICIjZjdmZjAwIikgKw0KICBsYWJzKGZpbGw9IkluZ3Jlc29fZmFtaWxpYXJfZGlzcG9uaWJsZSIsDQogICAgICAgeD1OVUxMLA0KICAgICAgIHk9TlVMTCwNCiAgICAgICB0aXRsZT0iSW5ncmVzb3MgZmFtaWxpYXJlcyBuZXRvcyAoZW4gZMOzbGFyZXMpIGVuIGxhIFVFIiwNCiAgICAgICBjYXB0aW9uPSJGdWVudGU6IE9DREUiKSArDQogIHRoZW1lKCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICJjb3Juc2lsazIiLCBjb2xvdXIgPSAibGF2ZW5kZXJibHVzaCIsIHNpemUgPSAwLjEgKSwNCiAgICAgICAgIHBhbmVsLmdyaWQgID0gZWxlbWVudF9saW5lKCBjb2xvdXIgPSJncmV5IiksDQogICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLGNvbG91ciA9ICJibGFjayIpLA0KICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImJsYWNrIiApLA0KICAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSA1LCBiID0gNSwxMCkgKQ0KDQptYXBhcGxvdDIgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhkaXJlY3Rpb24gPSAtMSkNCg0KYGBgIA0KDQojIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuMi40LiBDaHVua3MuIDwvRk9OVD4NCg0KRW4gZXN0ZSBhcGFydGFkbyBzZSBtdWVzdHJhbiBsb3MgdHJvem9zIGRlIGPDs2RpZ28gUiAoY2h1bmspIHV0aWxpemFkb3MgcGFyYSBoYWNlciBsYSB0YWJsYSwgZWwgZ3LDoWZpY28geSBlbCBtYXBhLiBTZXBhcsOhbmRvbG8gZGUgbG9zIGRlbcOhcywgaGFjZSBxdWUgbGEgbGVjdHVyYSBkZWwgdHJhYmFqbyBzZWEgbcOhcyBmw6FjaWwgeSBhbWVuYS4NCg0KYGBge3IsIGVjaG8gPSBUUlVFLCBldmFsID0gRkFMU0V9DQoNCiNBc8OtIGhlIGhlY2hvIGxhIHRhYmxhDQoNCmRmXyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmX2luZyA8LSBkZl8gICU+JSBzZWxlY3QoUGFpc2VzLEluZ3Jlc29fZmFtaWxpYXJfZGlzcG9uaWJsZSklPiUgYXJyYW5nZShkZXNjKEluZ3Jlc29fZmFtaWxpYXJfZGlzcG9uaWJsZSkpDQoNCmRmX2luZyA8LSBuYS5vbWl0KGRmX2luZykNCg0KZGZfaW5nICU+JSBndCgpDQoNCiNBc8OtIGhlIGhlY2hvIGVsIGdyw6FmaWNvDQoNCmRmXyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmX2luZyA8LSBkZl8gICU+JSBzZWxlY3QoUGFpc2VzLEluZ3Jlc29fZmFtaWxpYXJfZGlzcG9uaWJsZSxQYXRyaW1vbmlvX2ZhbWlsaWEpDQoNCmRmX2luZyA8LSBuYS5vbWl0KGRmX2luZykNCg0KZ3JhZmljb0EgPC0gZ2dwbG90KGRmX2luZywgYWVzKGZvcmNhdHM6OmZjdF9yZW9yZGVyKFBhaXNlcywgSW5ncmVzb19mYW1pbGlhcl9kaXNwb25pYmxlKSwgSW5ncmVzb19mYW1pbGlhcl9kaXNwb25pYmxlKSkgKw0KICBnZW9tX2NvbChhZXMoZmlsbCA9IEluZ3Jlc29fZmFtaWxpYXJfZGlzcG9uaWJsZSkpKyBjb29yZF9mbGlwKCkrIA0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT05MCwgdmp1c3Q9MC42KSwgcGFuZWwuYmFja2dyb3VuZCA9IE5VTEwpKw0KICBsYWJzKHRpdGxlID0gIkluZ3Jlc29zIGZhbWlsaWFyZXMgZGlzcG9uaWJsZXMgKGVuIGTDs2xhcmVzKSIsIHN1YnRpdGxlID0gIlBvciBwYcOtc2VzIiwgY2FwdGlvbj0iRnVlbnRlOiBPQ0RFIikgKyANCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwpKyB0cmFuc2l0aW9uX3JldmVhbChJbmdyZXNvX2ZhbWlsaWFyX2Rpc3BvbmlibGUpDQoNCmdyYWZpY29BICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQojQXPDrSBoZSBoZWNobyBlbCBtYXBhDQoNCm1hcGFkYXRhX1VFPC0gbWFwX2RhdGEoIndvcmxkIikgJT4lIGZpbHRlcihyZWdpb24gJWluJSBjKCJBdXN0cmlhIiwiQmVsZ2l1bSIsIkJ1bGdhcmlhIiwiQ3JvYXRpYSIsIkN5cHJ1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ3plY2ggUmVwdWJsaWMiLCJEZW5tYXJrIiwiRXN0b25pYSIsIkZpbmxhbmQiLCJGcmFuY2UiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdlcm1hbnkiLCJHcmVlY2UiLCJIdW5nYXJ5IiwiSXJlbGFuZCIsIkl0YWx5IiwiTGF0dmlhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMaXRodWFuaWEiLCJMdXhlbWJvdXJnIiwiTWFsdGEiLCJOZXRoZXJsYW5kcyIsIlBvbGFuZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG9ydHVnYWwiLCJSb21hbmlhIiwiU2xvdmFraWEiLCJTbG92ZW5pYSIsIlNwYWluIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTd2VkZW4iLCJVSyIsIlN3aXR6ZXJsYW5kIiwiQm9zbmlhIGFuZCBIZXJ6ZWdvdmluYSIsIlNlcmJpYSIsIlVrcmFpbmUiLCJCZWxhcnVzIiwiQWxiYW5pYSIsIk1vbnRlbmVncm8iLCJLb3Nvdm8iLCJNYWNlZG9uaWEiLCJNb2xkb3ZhIikpDQoNCm1hcGFkYXRhX1VFXyA8LSBtYXBhZGF0YV9VRSAlPiUgbXV0YXRlKHJlZ2lvbiA9IGNhc2Vfd2hlbigNCiAgcmVnaW9uID09ICJVSyIgfiAiVW5pdGVkIEtpbmdkb20iLA0KICBUUlVFICB+ICByZWdpb24gKSkNCg0KbWFwZGF0YV9VRV8gPC0gZnVsbF9qb2luIChtYXBhZGF0YV9VRV8sZGZfaW5nLCBieSA9IGMoInJlZ2lvbiI9IlBhaXNlcyIpKQ0KDQoNCm1hcGFwbG90MiA8LSBnZ3Bsb3QobWFwZGF0YV9VRV8sIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXA9Z3JvdXAsIGZpbGwgPSBJbmdyZXNvX2ZhbWlsaWFyX2Rpc3BvbmlibGUpICkgKw0KICBnZW9tX3BvbHlnb24oY29sb3IgPSIjZmZmZmZmIikgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjMzEzMjAwIixoaWdoID0gIiNmN2ZmMDAiKSArDQogIGxhYnMoZmlsbD0iSW5ncmVzb19mYW1pbGlhcl9kaXNwb25pYmxlIiwNCiAgICAgICB4PU5VTEwsDQogICAgICAgeT1OVUxMLA0KICAgICAgIHRpdGxlPSJJbmdyZXNvcyBmYW1pbGlhcmVzIG5ldG9zIChlbiBkw7NsYXJlcykgZW4gbGEgVUUiLA0KICAgICAgIGNhcHRpb249IkZ1ZW50ZTogT0NERSIpICsNCiAgdGhlbWUoIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICIjZmZmZmZmIiksDQogICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gImNvcm5zaWxrMiIsIGNvbG91ciA9ICJsYXZlbmRlcmJsdXNoIiwgc2l6ZSA9IDAuMSApLA0KICAgICAgICAgcGFuZWwuZ3JpZCAgPSBlbGVtZW50X2xpbmUoIGNvbG91ciA9ImdyZXkiKSwNCiAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsY29sb3VyID0gImJsYWNrIiksDQogICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICJjb3Juc2lsazIiLCBjb2xvdXIgPSAiYmxhY2siICksDQogICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gNSwgciA9IDUsIGIgPSA1LDEwKSApDQoNCm1hcGFwbG90MiArIHNjYWxlX2ZpbGxfdmlyaWRpc19jKGRpcmVjdGlvbiA9IC0xKQ0KDQoNCmBgYA0KDQojIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC4zLiBFbXBsZW86IFRhc2EgZGUgZW1wbGVvIDwvRk9OVD4gey50YWJzZXR9DQoNCiMjIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC4zLjEuIFRhYmxhIGRhdG9zLiA8L0ZPTlQ+DQoNCj4g4oCcRWwgdHJhYmFqbyBlcyBzYWx1ZOKAnSANCg0Kwr9RdWnDqW4gbm8gaGEgZXNjdWNoYWRvIGFsZ3VuYSB2ZXogZXN0ZSBkaWNobz8gRXN0w6EgY2xhcm8gcXVlIGVsIHRyYWJham8sIGVzIHNhbHVkLCBubyBzb2xvIGbDrXNpY2EsIHNpbm8gbWVudGFsLiBBZGVtw6FzIHByb3BvcmNpb25hIGluZ3Jlc29zIGZ1bmRhbWVudGFsZXMgcGFyYSB2aXZpciB5IHNpICBvZnJlY2UgdW5hIGJ1ZW5hIHJlbXVuZXJhY2nDs24sIGVsIGFjY2VzbyBhIGxhIGVkdWNhY2nDs24sIHNhbHVkLCBvY2lvLi4uIGV0YywgZXMgbcOhcyBmw6FjaWwuDQoNClN1aXphLCBTdWVjaWEsIEhvbGFuZGEsIEFsZW1hbmlhIHkgUmVpbm8gVW5pZG8gc29uIGxvcyBwYcOtc2VzIGV1cm9wZW9zIGNvbiB0YXNhcyBkZSBlbXBsZW8gbcOhcyBhbHRhcy4NCg0KQSBsYSBjb2xhLCBsb3MgcGHDrXNlcyBtZWRpdGVycsOhbmVvcyBkZWwgc3VyIGRlIEV1cm9wYSwgZW50cmUgZWxsb3MgKipFc3Bhw7FhKiouDQoNCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KZGZfIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2NhbGlkYWR2aWRhX2RlZmluaXRpdm8uY3N2IikNCg0KZGZfZW1wbGVvIDwtIGRmXyAgJT4lIHNlbGVjdChQYWlzZXMsVGFzYV9lbXBsZW8sSW5ncmVzb3NfcGVyc29uYWxlcyklPiUgYXJyYW5nZShkZXNjKFRhc2FfZW1wbGVvKSkNCg0KZGZfZW1wbGVvIDwtIG5hLm9taXQoZGZfZW1wbGVvKQ0KDQprYWJsZShkZl9lbXBsZW8pICU+JQ0KICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZpeGVkX3RoZWFkID0gbGlzdChlbmFibGVkID0gVCwgYmFja2dyb3VuZCA9ICJsaWdodGJsdWUiKSkNCmBgYA0KDQoNCiMjIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC4zLjIuIEdyw6FmaWNhLiA8L0ZPTlQ+DQoNCkVuIGVsIGFuw6FsaXNpcyBncsOhZmljbyBoZW1vcyByZWxhY2lvbmFkbyBsb3MgaW5ncmVzb3MgZGUgbG9zIGNpdWRhZGFub3MgZGUgY2FkYSBwYcOtcyBjb24gbGEgdGFzYSBkZSBlbXBsZW8sIGNvbiBlbCBvYmpldGl2byBkZSBlc3R1ZGlhciBzaSBoYXkgYWxnw7puIHRpcG8gZGUgcmVsYWNpw7NuLiBObyBlc3TDoSBtdXkgY2xhcmEuDQoNCkxvIHF1ZSBzaSBxdWUgdmVtb3MgY2xhcmEgZXMgbGEgcmVsYWNpw7NuIGV4aXN0ZW50ZSBlbnRyZSBsYSBpbnNlZ3VyaWRhZCBlbiBlbCBlbXBsZW8geSBsYSB0YXNhIGRlIGVtcGxlby4gQSBtZW5vciB0YXNhIGRlIGVtcGxlbywgbWF5b3IgaW5zZWd1cmlkYWQgKG1pZWRvIGEgcGVyZGVyIGVsIGVtcGxlbykuDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQpkZl8gPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvY2FsaWRhZHZpZGFfZGVmaW5pdGl2by5jc3YiKQ0KDQpkZl9lbXBsZW8gPC0gZGZfICAlPiUgc2VsZWN0KFBhaXNlcyxJbnNlZ3VyaWRhZF9lbl9lbXBsZW8sVGFzYV9lbXBsZW8sVGFzYV9lbXBsZW9fTFAsIEluZ3Jlc29zX3BlcnNvbmFsZXMpDQoNCmRmX2VtcGxlbyA8LSBuYS5vbWl0KGRmX2VtcGxlbykNCg0KZ2dwbG90KGRmX2VtcGxlbywgYWVzKFRhc2FfZW1wbGVvLCBJbnNlZ3VyaWRhZF9lbl9lbXBsZW8sIGxhYmVsID0gUGFpc2VzKSkgKyANCiAgZ2VvbV9wb2ludCgpICsgDQogIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihkZl9lbXBsZW8sIFBhaXNlcyA9PSAiU3BhaW4iKSwgY29sb3VyID0gInBpbmsiLCBzaXplID0gNikrIA0KICBnZW9tX3BvaW50KGRhdGEgPSBmaWx0ZXIoZGZfZW1wbGVvLCBQYWlzZXMgPT0gIk9FQ0QgLSBUb3RhbCIpLCBjb2xvdXIgPSAidmlvbGV0Iiwgc2l6ZSA9IDYpKw0KICBsYWJzKHRpdGxlID0gIlJlbGFjacOzbiBlbnRyZSBpbnNlZ3VyaWRhZCBkZSBlbXBsZW8geSB0YXNhIGVtcGxlbyIgLA0KICAgICAgIHkgPSAiSW5zZWd1cmlkYWQgZW4gZWwgZW1wbGVvIiwNCiAgICAgICB4ID0gIlRhc2EgZGUgZW1wbGVvIiwNCiAgICAgICBjYXB0aW9uID0gIkZ1ZW50ZSBPQ0RFIikrDQogIGdlb21fc21vb3RoKCkrIGdlb21fbGFiZWxfcmVwZWwoKSsgdGhlbWVfbWluaW1hbCgpDQoNCmBgYCANCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCmRmXyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmX2VtcGxlbyA8LSBkZl8gICU+JSBzZWxlY3QoUGFpc2VzLEluc2VndXJpZGFkX2VuX2VtcGxlbyxUYXNhX2VtcGxlbyxUYXNhX2VtcGxlb19MUCwgSW5ncmVzb3NfcGVyc29uYWxlcykNCg0KZGZfZW1wbGVvIDwtIG5hLm9taXQoZGZfZW1wbGVvKQ0KDQpwIDwtIGdncGxvdChkZl9lbXBsZW8sIGFlcyhJbmdyZXNvc19wZXJzb25hbGVzLFRhc2FfZW1wbGVvKSkgKyANCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBQYWlzZXMpKSArIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihkZl9lbXBsZW8sIFBhaXNlcyA9PSAiU3BhaW4iKSwgY29sb3VyID0gInBpbmsiLCBzaXplID0gNikrIA0KICBnZW9tX3BvaW50KGRhdGEgPSBmaWx0ZXIoZGZfZW1wbGVvLCBQYWlzZXMgPT0gIk9FQ0QgLSBUb3RhbCIpLCBjb2xvdXIgPSAidmlvbGV0Iiwgc2l6ZSA9IDYpKyANCiAgbGFicyh0aXRsZSA9ICJSZWxhY2nDs24gZW50cmUgaW5ncmVzb3MgcGVyc29uYWxlcyB5IHRhc2EgZGUgZW1wbGVvIiAsDQogICAgICAgeSA9ICJUYXNhIGRlIGVtcGxlbyIsDQogICAgICAgeCA9ICJJbmdyZXNvcyBwZXJzb25hbGVzIChlbiBkw7NsYXJlcykiLA0KICAgICAgIGNhcHRpb24gPSAiRnVlbnRlIE9DREUiKSsNCiAgZ2VvbV9zbW9vdGgoKSsgdGhlbWVfbWluaW1hbCgpDQoNCnArYW5ub3RhdGUoZ2VvbSA9ICJjdXJ2ZSIsIHggPSAzODUwNywgeSA9IDYyLCB4ZW5kID0gNDAwMDAsIHllbmQgPSA2NSwgDQogICAgICAgICAgICAgY3VydmF0dXJlID0gLjMsIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgyLCAibW0iKSkpICsNCiAgICBhbm5vdGF0ZShnZW9tID0gInRleHQiLCB4ID0gMzkwMDAsIHkgPSA2NiwgbGFiZWwgPSAiU3BhaW4iLCBoanVzdCA9ICJsZWZ0IikrDQogICAgYW5ub3RhdGUoZ2VvbSA9ICJjdXJ2ZSIsIHggPSA0MzI0MSwgeSA9IDY4LCB4ZW5kID0gNDQwMDAsIHllbmQgPSA3MSwgDQogICAgICAgICAgICAgY3VydmF0dXJlID0gLjMsIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgyLCAibW0iKSkpICsNCiAgICBhbm5vdGF0ZShnZW9tID0gInRleHQiLCB4ID0gNDMwMDAsIHkgPSA3MiwgbGFiZWwgPSAiT0NERSIsIGhqdXN0ID0gImxlZnQiKSAgICANCiAgICANCmBgYCANCg0KIyMjIDxGT05UIENPTE9SPSJPcmFuZ2UiPiA0LjMuMy4gTWFwYS4gPC9GT05UPg0KDQpTaSB0cmFuc2Zlcmltb3MgbG9zIGRhdG9zIGRlIGxhIHRhYmxhIGNyZWFkYSBlbiBlbCBwcmltZXIgYXBhcnRhZG8gYSB1biBtYXBhLCBwb2RlbW9zIGFwcmVjaWFyIGxvIGNvbWVudGFkbyBlbiBlbCBwcmltZXIgYXBhcnRhZG86IGNvbmZvcm1lIHZhcyBhdmFuemFuZG8gaGFjaWEgYWwgc3VyIGRlIEV1cm9wYSwgZWwgbml2ZWwgZGUgZW1wbGVvIGVzIG1lbm9yLg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KDQptYXBhZGF0YV9VRTwtIG1hcF9kYXRhKCJ3b3JsZCIpICU+JSBmaWx0ZXIocmVnaW9uICVpbiUgYygiQXVzdHJpYSIsIkJlbGdpdW0iLCJCdWxnYXJpYSIsIkNyb2F0aWEiLCJDeXBydXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkN6ZWNoIFJlcHVibGljIiwiRGVubWFyayIsIkVzdG9uaWEiLCJGaW5sYW5kIiwiRnJhbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHZXJtYW55IiwiR3JlZWNlIiwiSHVuZ2FyeSIsIklyZWxhbmQiLCJJdGFseSIsIkxhdHZpYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGl0aHVhbmlhIiwiTHV4ZW1ib3VyZyIsIk1hbHRhIiwiTmV0aGVybGFuZHMiLCJQb2xhbmQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcnR1Z2FsIiwiUm9tYW5pYSIsIlNsb3Zha2lhIiwiU2xvdmVuaWEiLCJTcGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3dlZGVuIiwiVUsiLCJTd2l0emVybGFuZCIsIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiLCJTZXJiaWEiLCJVa3JhaW5lIiwiQmVsYXJ1cyIsIkFsYmFuaWEiLCJNb250ZW5lZ3JvIiwiS29zb3ZvIiwiTWFjZWRvbmlhIiwiTW9sZG92YSIpKQ0KDQptYXBhZGF0YV9VRV8gPC0gbWFwYWRhdGFfVUUgJT4lIG11dGF0ZShyZWdpb24gPSBjYXNlX3doZW4oDQogIHJlZ2lvbiA9PSAiVUsiIH4gIlVuaXRlZCBLaW5nZG9tIiwNCiAgVFJVRSAgfiAgcmVnaW9uICkpDQoNCm1hcGRhdGFfVUVfIDwtIGZ1bGxfam9pbiAobWFwYWRhdGFfVUVfLGRmX2VtcGxlbywgYnkgPSBjKCJyZWdpb24iPSJQYWlzZXMiKSkNCg0KbWFwYXBsb3QgPC0gZ2dwbG90KG1hcGRhdGFfVUVfLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gVGFzYV9lbXBsZW8pICkgKw0KICBnZW9tX3BvbHlnb24oY29sb3IgPSIjZmZmZmZmIikgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjMzEzMjAwIixoaWdoID0gIiNmN2ZmMDAiKSArDQogIGxhYnMoZmlsbD0iVGFzYV9lbXBsZW8iLA0KICAgICAgIHg9TlVMTCwNCiAgICAgICB5PU5VTEwsDQogICAgICAgdGl0bGU9IlRhc2EgZGUgZW1wbGVvIChlbiBwb3JjZW50YWplKSBlbiBsYSBVRSIsDQogICAgICAgY2FwdGlvbj0iRnVlbnRlOiBPQ0RFIikgKw0KICB0aGVtZSggcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gIiNmZmZmZmYiKSwNCiAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImxhdmVuZGVyYmx1c2giLCBzaXplID0gMC4xICksDQogICAgICAgICBwYW5lbC5ncmlkICA9IGVsZW1lbnRfbGluZSggY29sb3VyID0iZ3JleSIpLA0KICAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSxjb2xvdXIgPSAiYmxhY2siKSwNCiAgICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gImNvcm5zaWxrMiIsIGNvbG91ciA9ICJibGFjayIgKSwNCiAgICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSA1LCByID0gNSwgYiA9IDUsMTApICkNCg0KbWFwYXBsb3QgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhkaXJlY3Rpb24gPSAtMSkNCg0KYGBgIA0KDQojIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuMy40LiBDaHVua3MuIDwvRk9OVD4NCg0KRW4gZXN0ZSBhcGFydGFkbyBzZSBtdWVzdHJhbiBsb3MgdHJvem9zIGRlIGPDs2RpZ28gUiAoY2h1bmspIHV0aWxpemFkb3MgcGFyYSBoYWNlciBsYSB0YWJsYSwgZWwgZ3LDoWZpY28geSBlbCBtYXBhLiBTZXBhcsOhbmRvbG8gZGUgbG9zIGRlbcOhcywgaGFjZSBxdWUgbGEgbGVjdHVyYSBkZWwgdHJhYmFqbyBzZWEgbcOhcyBmw6FjaWwgeSBhbWVuYS4NCg0KYGBge3IsIGVjaG8gPSBUUlVFLCBldmFsID0gRkFMU0V9DQoNCiNBc8OtIGhlIGhlY2hvIGxhIHRhYmxhDQoNCmRmXyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmX2VtcGxlbyA8LSBkZl8gICU+JSBzZWxlY3QoUGFpc2VzLFRhc2FfZW1wbGVvLEluZ3Jlc29zX3BlcnNvbmFsZXMpJT4lIGFycmFuZ2UoZGVzYyhUYXNhX2VtcGxlbykpDQoNCmRmX2VtcGxlbyA8LSBuYS5vbWl0KGRmX2VtcGxlbykNCg0Ka2FibGUoZGZfZW1wbGVvKSAlPiUNCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmaXhlZF90aGVhZCA9IGxpc3QoZW5hYmxlZCA9IFQsIGJhY2tncm91bmQgPSAibGlnaHRibHVlIikpDQoNCiNBc8OtIGhlIGhlY2hvIGVsIHByaW1lciBncsOhZmljbyANCg0KZGZfIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2NhbGlkYWR2aWRhX2RlZmluaXRpdm8uY3N2IikNCg0KZGZfZW1wbGVvIDwtIGRmXyAgJT4lIHNlbGVjdChQYWlzZXMsSW5zZWd1cmlkYWRfZW5fZW1wbGVvLFRhc2FfZW1wbGVvLFRhc2FfZW1wbGVvX0xQLCBJbmdyZXNvc19wZXJzb25hbGVzKQ0KDQpkZl9lbXBsZW8gPC0gbmEub21pdChkZl9lbXBsZW8pDQoNCmdncGxvdChkZl9lbXBsZW8sIGFlcyhUYXNhX2VtcGxlbywgSW5zZWd1cmlkYWRfZW5fZW1wbGVvLCBsYWJlbCA9IFBhaXNlcykpICsgDQogIGdlb21fcG9pbnQoKSArIA0KICBnZW9tX3BvaW50KGRhdGEgPSBmaWx0ZXIoZGZfZW1wbGVvLCBQYWlzZXMgPT0gIlNwYWluIiksIGNvbG91ciA9ICJwaW5rIiwgc2l6ZSA9IDYpKyANCiAgZ2VvbV9wb2ludChkYXRhID0gZmlsdGVyKGRmX2VtcGxlbywgUGFpc2VzID09ICJPRUNEIC0gVG90YWwiKSwgY29sb3VyID0gInZpb2xldCIsIHNpemUgPSA2KSsNCiAgbGFicyh0aXRsZSA9ICJSZWxhY2nDs24gZW50cmUgaW5zZWd1cmlkYWQgZGUgZW1wbGVvIHkgdGFzYSBlbXBsZW8iICwNCiAgICAgICB5ID0gIkluc2VndXJpZGFkIGVuIGVsIGVtcGxlbyIsDQogICAgICAgeCA9ICJUYXNhIGRlIGVtcGxlbyIsDQogICAgICAgY2FwdGlvbiA9ICJGdWVudGUgT0NERSIpKw0KICBnZW9tX3Ntb290aCgpKyBnZW9tX2xhYmVsX3JlcGVsKCkrIHRoZW1lX21pbmltYWwoKQ0KDQojQXPDrSBoZSBoZWNobyBlbCBzZWd1bmRvIGdyw6FmaWNvIA0KDQpkZl8gPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvY2FsaWRhZHZpZGFfZGVmaW5pdGl2by5jc3YiKQ0KDQpkZl9lbXBsZW8gPC0gZGZfICAlPiUgc2VsZWN0KFBhaXNlcyxJbnNlZ3VyaWRhZF9lbl9lbXBsZW8sVGFzYV9lbXBsZW8sVGFzYV9lbXBsZW9fTFAsIEluZ3Jlc29zX3BlcnNvbmFsZXMpDQoNCmRmX2VtcGxlbyA8LSBuYS5vbWl0KGRmX2VtcGxlbykNCnAgPC0gZ2dwbG90KGRmX2VtcGxlbywgYWVzKEluZ3Jlc29zX3BlcnNvbmFsZXMsIFRhc2FfZW1wbGVvKSkgKyANCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBQYWlzZXMpKSArIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihkZl9lbXBsZW8sIFBhaXNlcyA9PSAiU3BhaW4iKSwgY29sb3VyID0gInBpbmsiLCBzaXplID0gNikrIA0KICBnZW9tX3BvaW50KGRhdGEgPSBmaWx0ZXIoZGZfZW1wbGVvLCBQYWlzZXMgPT0gIk9FQ0QgLSBUb3RhbCIpLCBjb2xvdXIgPSAidmlvbGV0Iiwgc2l6ZSA9IDYpKyANCiAgbGFicyh0aXRsZSA9ICJSZWxhY2nDs24gZW50cmUgaW5ncmVzb3MgcGVyc29uYWxlcyB5IHRhc2EgZGUgZW1wbGVvIiAsDQogICAgICAgeSA9ICJUYXNhIGRlIGVtcGxlbyIsDQogICAgICAgeCA9ICJJbmdyZXNvcyBwZXJzb25hbGVzIChlbiBkw7NsYXJlcykiKSsNCiAgZ2VvbV9zbW9vdGgoKSsgdGhlbWVfbWluaW1hbCgpDQoNCnArYW5ub3RhdGUoZ2VvbSA9ICJjdXJ2ZSIsIHggPSAzODUwNywgeSA9IDYyLCB4ZW5kID0gNDAwMDAsIHllbmQgPSA2NSwgDQogICAgICAgICAgICAgY3VydmF0dXJlID0gLjMsIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgyLCAibW0iKSkpICsNCiAgICBhbm5vdGF0ZShnZW9tID0gInRleHQiLCB4ID0gMzkwMDAsIHkgPSA2NiwgbGFiZWwgPSAiU3BhaW4iLCBoanVzdCA9ICJsZWZ0IikrDQogICAgYW5ub3RhdGUoZ2VvbSA9ICJjdXJ2ZSIsIHggPSA0MzI0MSwgeSA9IDY4LCB4ZW5kID0gNDQwMDAsIHllbmQgPSA3MSwgDQogICAgICAgICAgICAgY3VydmF0dXJlID0gLjMsIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgyLCAibW0iKSkpICsNCiAgICBhbm5vdGF0ZShnZW9tID0gInRleHQiLCB4ID0gNDMwMDAsIHkgPSA3MiwgbGFiZWwgPSAiT0NERSIsIGhqdXN0ID0gImxlZnQiKSAgICANCiAgICANCiNBc8OtIGhlIGhlY2hvIGVsIG1hcGENCg0KbWFwYWRhdGFfVUU8LSBtYXBfZGF0YSgid29ybGQiKSAlPiUgZmlsdGVyKHJlZ2lvbiAlaW4lIGMoIkF1c3RyaWEiLCJCZWxnaXVtIiwiQnVsZ2FyaWEiLCJDcm9hdGlhIiwiQ3lwcnVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDemVjaCBSZXB1YmxpYyIsIkRlbm1hcmsiLCJFc3RvbmlhIiwiRmlubGFuZCIsIkZyYW5jZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2VybWFueSIsIkdyZWVjZSIsIkh1bmdhcnkiLCJJcmVsYW5kIiwiSXRhbHkiLCJMYXR2aWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxpdGh1YW5pYSIsIkx1eGVtYm91cmciLCJNYWx0YSIsIk5ldGhlcmxhbmRzIiwiUG9sYW5kIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3J0dWdhbCIsIlJvbWFuaWEiLCJTbG92YWtpYSIsIlNsb3ZlbmlhIiwiU3BhaW4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlN3ZWRlbiIsIlVLIiwiU3dpdHplcmxhbmQiLCJCb3NuaWEgYW5kIEhlcnplZ292aW5hIiwiU2VyYmlhIiwiVWtyYWluZSIsIkJlbGFydXMiLCJBbGJhbmlhIiwiTW9udGVuZWdybyIsIktvc292byIsIk1hY2Vkb25pYSIsIk1vbGRvdmEiKSkNCg0KbWFwYWRhdGFfVUVfIDwtIG1hcGFkYXRhX1VFICU+JSBtdXRhdGUocmVnaW9uID0gY2FzZV93aGVuKA0KICByZWdpb24gPT0gIlVLIiB+ICJVbml0ZWQgS2luZ2RvbSIsDQogIFRSVUUgIH4gIHJlZ2lvbiApKQ0KDQptYXBkYXRhX1VFXyA8LSBmdWxsX2pvaW4gKG1hcGFkYXRhX1VFXyxkZl9lbXBsZW8sIGJ5ID0gYygicmVnaW9uIj0iUGFpc2VzIikpDQoNCm1hcGFwbG90IDwtIGdncGxvdChtYXBkYXRhX1VFXywgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cD1ncm91cCwgZmlsbCA9IFRhc2FfZW1wbGVvKSApICsNCiAgZ2VvbV9wb2x5Z29uKGNvbG9yID0iI2ZmZmZmZiIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiIzMxMzIwMCIsaGlnaCA9ICIjZjdmZjAwIikgKw0KICBsYWJzKGZpbGw9IlRhc2FfZW1wbGVvIiwNCiAgICAgICB4PU5VTEwsDQogICAgICAgeT1OVUxMLA0KICAgICAgIHRpdGxlPSJUYXNhIGRlIGVtcGxlbyAoZW4gcG9yY2VudGFqZSkgZW4gbGEgVUUiLA0KICAgICAgIGNhcHRpb249IkZ1ZW50ZTogT0NERSIpICsNCiAgdGhlbWUoIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICIjZmZmZmZmIiksDQogICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gImNvcm5zaWxrMiIsIGNvbG91ciA9ICJsYXZlbmRlcmJsdXNoIiwgc2l6ZSA9IDAuMSApLA0KICAgICAgICAgcGFuZWwuZ3JpZCAgPSBlbGVtZW50X2xpbmUoIGNvbG91ciA9ImdyZXkiKSwNCiAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsY29sb3VyID0gImJsYWNrIiksDQogICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICJjb3Juc2lsazIiLCBjb2xvdXIgPSAiYmxhY2siICksDQogICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gNSwgciA9IDUsIGIgPSA1LDEwKSApDQoNCm1hcGFwbG90ICsgc2NhbGVfZmlsbF92aXJpZGlzX2MoZGlyZWN0aW9uID0gLTEpDQoNCmBgYA0KDQojIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC40LiBDb211bmlkYWQ6IEFwb3lvIHNvY2lhbCA8L0ZPTlQ+IHsudGFic2V0fQ0KDQojIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuNC4xLiBUYWJsYSBkYXRvcy4gPC9GT05UPg0KDQpVbiBhcG95byBzb2NpYWwgeSBmYW1pbGlhciBlcyBmdW5kYW1lbnRhbCBwYXJhIGVsIGRlc2Fycm9sbG8gdGFudG8gcGVyc29uYWwgY29tbyBwcm9mZXNpb25hbCBkZSBsb3MgaW5kaXZpZHVvcy4gTGFzIHNvY2llZGFkZXMgbcOhcyBpbmRpdmlkdWFsaXN0YXMsIHNvbiBzb2NpZWRhZGVzIGNvbiB1biBtZW5vciBiaWVuZXN0YXIgc29jaWFsIHkgZWNvbsOzbWljby4NCg0KRGUgbnVldm8gdmVtb3MgYSBsb3MgcGHDrXNlcyBkZWwgbm9ydGUgZGUgRXVyb3BhIGxpZGVyYW5kbyBlc3RhIGNsYXNpZmljYWNpw7NuLiBDbGFzaWZpY2FjacOzbiBkb25kZSBFc3Bhw7FhIHNlIGVuY3VlbnRyYSBlbiB1bmEgYnVlbmEgc2l0dWFjacOzbiBjb21wYXJhZG8gY29uIG90cm9zIHBhw61zZXMgZXVyb3Blb3MuDQoNCk1lIGxsYW1hIGxhIGF0ZW5jacOzbiBsYSBwb3NpY2nDs24gZGUgR3JlY2lhIGVuIGVzdGUgcmFua2luZy4gUG9yIHN1IGNhcsOhY3RlciBtZWRpdGVycsOhbmVvIChtw6FzIGZhbWlsaWFyKSBudW5jYSBodWJpZXNlIHNvc3BlY2hhZG8gcXVlIHNlIGVuY29udHJhc2UgZW4gw7psdGltYSBwb3NpY2nDs24uDQoNCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCg0KZGZfIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2NhbGlkYWR2aWRhX2RlZmluaXRpdm8uY3N2IikNCg0KZGZfc29jaWFsIDwtIGRmXyAgJT4lIHNlbGVjdChQYWlzZXMsQ2FsaWRhZF9hcG95b19zb2NpYWwsIEluZ3Jlc29zX3BlcnNvbmFsZXMpICU+JSBhcnJhbmdlKGRlc2MoQ2FsaWRhZF9hcG95b19zb2NpYWwpKSANCg0KZGZfc29jaWFsIDwtIG5hLm9taXQoZGZfc29jaWFsKQ0KDQpkZl9zb2NpYWwgJT4lIGd0KCkNCg0KYGBgDQoNCg0KIyMjIDxGT05UIENPTE9SPSJPcmFuZ2UiPiA0LjQuMi4gR3LDoWZpY2EuIDwvRk9OVD4NCg0KRW4gZWwgYW7DoWxpc2lzIGdyw6FmaWNvIGhlbW9zIHJlbGFjaW9uYWRvIGxvcyBpbmdyZXNvcyBkZSBsb3MgY2l1ZGFkYW5vcyBkZSBjYWRhIHBhw61zIGNvbiBsYSB0YXNhIGRlIGVtcGxlbywgY29uIGVsIG9iamV0aXZvIGRlIGVzdHVkaWFyIHNpIGhheSBhbGfDum4gdGlwbyBkZSByZWxhY2nDs24uIFBhcmVjZSBjbGFyYTogYSBtYXlvciBhcG95byBzb2NpYWwgbWF5b3JlcyBpbmdyZXNvcy4NCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCg0KZ2dwbG90KGRmX3NvY2lhbCwgYWVzKGZvcmNhdHM6OmZjdF9yZW9yZGVyKFBhaXNlcywgQ2FsaWRhZF9hcG95b19zb2NpYWwpLCBDYWxpZGFkX2Fwb3lvX3NvY2lhbCkpICsNCiAgZ2VvbV9jb2woYWVzKGZpbGwgPSBDYWxpZGFkX2Fwb3lvX3NvY2lhbCkpKyBjb29yZF9mbGlwKCkrIA0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT05MCwgdmp1c3Q9MC42KSwgcGFuZWwuYmFja2dyb3VuZCA9IE5VTEwpKw0KICBsYWJzKHRpdGxlID0gIkNhbGlkYWQgZGUgYXBveW8gc29jaWFsIChlbiBwb3JjZW50YWplKSIsIHN1YnRpdGxlID0gIlBvciBwYcOtc2VzIixjYXB0aW9uID0gIkZ1ZW50ZSBPQ0RFIikgKyANCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwpKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCmBgYCANCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCg0KZGZfIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2NhbGlkYWR2aWRhX2RlZmluaXRpdm8uY3N2IikNCg0KZGZfc29jaWFsIDwtIGRmXyAgJT4lIHNlbGVjdChQYWlzZXMsQ2FsaWRhZF9hcG95b19zb2NpYWwsIEluZ3Jlc29zX3BlcnNvbmFsZXMpICU+JSBhcnJhbmdlKGRlc2MoQ2FsaWRhZF9hcG95b19zb2NpYWwpKQ0KDQpkZl9zb2NpYWwgPC0gbmEub21pdChkZl9zb2NpYWwpDQoNCmdncGxvdChkZl9zb2NpYWwsIGFlcyhDYWxpZGFkX2Fwb3lvX3NvY2lhbCwgSW5ncmVzb3NfcGVyc29uYWxlcykpICsgDQogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gUGFpc2VzKSkgKyBnZW9tX3BvaW50KGRhdGEgPSBmaWx0ZXIoZGZfc29jaWFsLCBQYWlzZXMgPT0gIlNwYWluIiksIGNvbG91ciA9ICJwaW5rIiwgc2l6ZSA9IDYpKyBnZW9tX3Ntb290aCgpKyB0aGVtZV9jYWxjKCkrDQogIGxhYnModGl0bGUgPSAiQ2FsaWRhZCBkZSBhcG95byBzb2NpYWwgVlMgSW5ncmVzb3MiLGNhcHRpb24gPSAiRnVlbnRlIE9DREUiKSsgDQogIGxhYnMoeCA9IkNhbGlkYWQgYXBveW8gc29jaWFsIChlbiBwb3JjZW50YWplKSIsIHkgPSAiSW5ncmVzb3MgcGVyc29uYWxlcyAoZW4gZMOzbGFyZXMpIikgDQoNCmBgYCANCg0KIyMjIDxGT05UIENPTE9SPSJPcmFuZ2UiPiA0LjQuMy4gTWFwYS4gPC9GT05UPg0KDQpTaSB0cmFuc2Zlcmltb3MgbG9zIGRhdG9zIGRlIGxhIHRhYmxhIGNyZWFkYSBlbiBlbCBwcmltZXIgYXBhcnRhZG8gYSB1biBtYXBhLCBxdWVkYSBkZSBsYSBzaWd1aWVudGUgbWFuZXJhOg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KDQptYXBhZGF0YV9VRTwtIG1hcF9kYXRhKCJ3b3JsZCIpICU+JSBmaWx0ZXIocmVnaW9uICVpbiUgYygiQXVzdHJpYSIsIkJlbGdpdW0iLCJCdWxnYXJpYSIsIkNyb2F0aWEiLCJDeXBydXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkN6ZWNoIFJlcHVibGljIiwiRGVubWFyayIsIkVzdG9uaWEiLCJGaW5sYW5kIiwiRnJhbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHZXJtYW55IiwiR3JlZWNlIiwiSHVuZ2FyeSIsIklyZWxhbmQiLCJJdGFseSIsIkxhdHZpYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGl0aHVhbmlhIiwiTHV4ZW1ib3VyZyIsIk1hbHRhIiwiTmV0aGVybGFuZHMiLCJQb2xhbmQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcnR1Z2FsIiwiUm9tYW5pYSIsIlNsb3Zha2lhIiwiU2xvdmVuaWEiLCJTcGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3dlZGVuIiwiVUsiLCJTd2l0emVybGFuZCIsIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiLCJTZXJiaWEiLCJVa3JhaW5lIiwiQmVsYXJ1cyIsIkFsYmFuaWEiLCJNb250ZW5lZ3JvIiwiS29zb3ZvIiwiTWFjZWRvbmlhIiwiTW9sZG92YSIpKQ0KDQptYXBhZGF0YV9VRV8gPC0gbWFwYWRhdGFfVUUgJT4lIG11dGF0ZShyZWdpb24gPSBjYXNlX3doZW4oDQogIHJlZ2lvbiA9PSAiVUsiIH4gIlVuaXRlZCBLaW5nZG9tIiwNCiAgVFJVRSAgfiAgcmVnaW9uICkpDQoNCm1hcGRhdGFfVUVfIDwtIGZ1bGxfam9pbiAobWFwYWRhdGFfVUVfLGRmX3NvY2lhbCwgYnkgPSBjKCJyZWdpb24iPSJQYWlzZXMiKSkNCg0KDQptYXBhcGxvdDIgPC0gZ2dwbG90KG1hcGRhdGFfVUVfLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gSW5ncmVzb3NfcGVyc29uYWxlcykgKSArDQogIGdlb21fcG9seWdvbihjb2xvciA9IiNmZmZmZmYiKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIiMzMTMyMDAiLGhpZ2ggPSAiI2Y3ZmYwMCIpICsNCiAgbGFicyhmaWxsPSJDYWxpZGFkX2Fwb3lvX3NvY2lhbCIsDQogICAgICAgeD1OVUxMLA0KICAgICAgIHk9TlVMTCwNCiAgICAgICB0aXRsZT0iQ2FsaWRhZCBkZSBBcG95byBTb2NpYWwgKGVuIHBvcmNlbnRhamUpIiwNCiAgICAgICBjYXB0aW9uPSJGdWVudGU6IE9DREUiKSArDQogIHRoZW1lKCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICJjb3Juc2lsazIiLCBjb2xvdXIgPSAibGF2ZW5kZXJibHVzaCIsIHNpemUgPSAwLjEgKSwNCiAgICAgICAgIHBhbmVsLmdyaWQgID0gZWxlbWVudF9saW5lKCBjb2xvdXIgPSJncmV5IiksDQogICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLGNvbG91ciA9ICJibGFjayIpLA0KICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImJsYWNrIiApLA0KICAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSA1LCBiID0gNSwxMCkgKQ0KDQptYXBhcGxvdDIgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhkaXJlY3Rpb24gPSAtMSkNCg0KYGBgIA0KDQojIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuNC40LiBDaHVua3MuIDwvRk9OVD4NCg0KRW4gZXN0ZSBhcGFydGFkbyBzZSBtdWVzdHJhbiBsb3MgdHJvem9zIGRlIGPDs2RpZ28gUiAoY2h1bmspIHV0aWxpemFkb3MgcGFyYSBoYWNlciBsYSB0YWJsYSwgZWwgZ3LDoWZpY28geSBlbCBtYXBhLiBTZXBhcsOhbmRvbG8gZGUgbG9zIGRlbcOhcywgaGFjZSBxdWUgbGEgbGVjdHVyYSBkZWwgdHJhYmFqbyBzZWEgbcOhcyBmw6FjaWwgeSBhbWVuYS4NCg0KYGBge3IsIGVjaG8gPSBUUlVFLCBldmFsID0gRkFMU0V9DQoNCiNBc8OtIGhlIGhlY2hvIGxhIHRhYmxhDQoNCmRmXyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmX3NvY2lhbCA8LSBkZl8gICU+JSBzZWxlY3QoUGFpc2VzLENhbGlkYWRfYXBveW9fc29jaWFsLCBJbmdyZXNvc19wZXJzb25hbGVzKQ0KDQpkZl9zb2NpYWwgPC0gbmEub21pdChkZl9zb2NpYWwpDQoNCmRmX3NvY2lhbCAlPiUgZ3QoKQ0KDQojQXPDrSBoZSBoZWNobyBlbCBwcmltZXIgZ3LDoWZpY28gDQoNCmdncGxvdChkZl9zb2NpYWwsIGFlcyhmb3JjYXRzOjpmY3RfcmVvcmRlcihQYWlzZXMsIENhbGlkYWRfYXBveW9fc29jaWFsKSwgQ2FsaWRhZF9hcG95b19zb2NpYWwpKSArDQogIGdlb21fY29sKGFlcyhmaWxsID0gQ2FsaWRhZF9hcG95b19zb2NpYWwpKSsgY29vcmRfZmxpcCgpKyANCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9OTAsIHZqdXN0PTAuNiksIHBhbmVsLmJhY2tncm91bmQgPSBOVUxMKSsNCiAgbGFicyh0aXRsZSA9ICJDYWxpZGFkIGRlIGFwb3lvIHNvY2lhbCAoZW4gcG9yY2VudGFqZSkiLCBzdWJ0aXRsZSA9ICJQb3IgcGHDrXNlcyIsY2FwdGlvbiA9ICJGdWVudGUgT0NERSIpICsgDQogIGxhYnMoeCA9IE5VTEwsIHkgPSBOVUxMKSsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQojQXPDrSBoZSBoZWNobyBlbCBzZWd1bmRvIGdyw6FmaWNvDQoNCmRmXyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmX3NvY2lhbCA8LSBkZl8gICU+JSBzZWxlY3QoUGFpc2VzLENhbGlkYWRfYXBveW9fc29jaWFsLCBJbmdyZXNvc19wZXJzb25hbGVzKSAlPiUgYXJyYW5nZShkZXNjKENhbGlkYWRfYXBveW9fc29jaWFsKSkNCg0KZGZfc29jaWFsIDwtIG5hLm9taXQoZGZfc29jaWFsKQ0KDQpnZ3Bsb3QoZGZfc29jaWFsLCBhZXMoQ2FsaWRhZF9hcG95b19zb2NpYWwsIEluZ3Jlc29zX3BlcnNvbmFsZXMpKSArIA0KICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFBhaXNlcykpICsgZ2VvbV9wb2ludChkYXRhID0gZmlsdGVyKGRmX3NvY2lhbCwgUGFpc2VzID09ICJTcGFpbiIpLCBjb2xvdXIgPSAicGluayIsIHNpemUgPSA2KSsgZ2VvbV9zbW9vdGgoKSsgdGhlbWVfY2FsYygpKw0KICBsYWJzKHRpdGxlID0gIkNhbGlkYWQgZGUgYXBveW8gc29jaWFsIFZTIEluZ3Jlc29zIixjYXB0aW9uID0gIkZ1ZW50ZSBPQ0RFIikrIA0KICBsYWJzKHggPSJDYWxpZGFkIGFwb3lvIHNvY2lhbCAoZW4gcG9yY2VudGFqZSkiLCB5ID0gIkluZ3Jlc29zIHBlcnNvbmFsZXMgKGVuIGTDs2xhcmVzKSIpIA0KDQpwICsgYW5ub3RhdGUoZ2VvbSA9ICJjdXJ2ZSIsIHggPSAzODUwNywgeSA9IDkyLCB4ZW5kID0gNDAwMDAsIHllbmQgPSA5NCwgDQogICAgICAgICAgICAgICAgICAgICAgY3VydmF0dXJlID0gLjMsIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgyLCAibW0iKSkpICsNCiAgICAgICAgICAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeCA9IDM5MDAwLCB5ID0gOTQsIGxhYmVsID0gIkVzcGHDsWEiLCBoanVzdCA9ICJsZWZ0IikNCg0KI0Fzw60gaGUgaGVjaG8gZWwgbWFwYQ0KDQptYXBhZGF0YV9VRTwtIG1hcF9kYXRhKCJ3b3JsZCIpICU+JSBmaWx0ZXIocmVnaW9uICVpbiUgYygiQXVzdHJpYSIsIkJlbGdpdW0iLCJCdWxnYXJpYSIsIkNyb2F0aWEiLCJDeXBydXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkN6ZWNoIFJlcHVibGljIiwiRGVubWFyayIsIkVzdG9uaWEiLCJGaW5sYW5kIiwiRnJhbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHZXJtYW55IiwiR3JlZWNlIiwiSHVuZ2FyeSIsIklyZWxhbmQiLCJJdGFseSIsIkxhdHZpYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGl0aHVhbmlhIiwiTHV4ZW1ib3VyZyIsIk1hbHRhIiwiTmV0aGVybGFuZHMiLCJQb2xhbmQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcnR1Z2FsIiwiUm9tYW5pYSIsIlNsb3Zha2lhIiwiU2xvdmVuaWEiLCJTcGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3dlZGVuIiwiVUsiLCJTd2l0emVybGFuZCIsIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiLCJTZXJiaWEiLCJVa3JhaW5lIiwiQmVsYXJ1cyIsIkFsYmFuaWEiLCJNb250ZW5lZ3JvIiwiS29zb3ZvIiwiTWFjZWRvbmlhIiwiTW9sZG92YSIpKQ0KDQptYXBhZGF0YV9VRV8gPC0gbWFwYWRhdGFfVUUgJT4lIG11dGF0ZShyZWdpb24gPSBjYXNlX3doZW4oDQogIHJlZ2lvbiA9PSAiVUsiIH4gIlVuaXRlZCBLaW5nZG9tIiwNCiAgVFJVRSAgfiAgcmVnaW9uICkpDQoNCm1hcGRhdGFfVUVfIDwtIGZ1bGxfam9pbiAobWFwYWRhdGFfVUVfLGRmX3NvY2lhbCwgYnkgPSBjKCJyZWdpb24iPSJQYWlzZXMiKSkNCg0KDQptYXBhcGxvdDIgPC0gZ2dwbG90KG1hcGRhdGFfVUVfLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gSW5ncmVzb3NfcGVyc29uYWxlcykgKSArDQogIGdlb21fcG9seWdvbihjb2xvciA9IiNmZmZmZmYiKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIiMzMTMyMDAiLGhpZ2ggPSAiI2Y3ZmYwMCIpICsNCiAgbGFicyhmaWxsPSJDYWxpZGFkX2Fwb3lvX3NvY2lhbCIsDQogICAgICAgeD1OVUxMLA0KICAgICAgIHk9TlVMTCwNCiAgICAgICB0aXRsZT0iQ2FsaWRhZCBkZSBBcG95byBTb2NpYWwgKGVuIHBvcmNlbnRhamUpIiwNCiAgICAgICBjYXB0aW9uPSJGdWVudGU6IE9DREUiKSArDQogIHRoZW1lKCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICJjb3Juc2lsazIiLCBjb2xvdXIgPSAibGF2ZW5kZXJibHVzaCIsIHNpemUgPSAwLjEgKSwNCiAgICAgICAgIHBhbmVsLmdyaWQgID0gZWxlbWVudF9saW5lKCBjb2xvdXIgPSJncmV5IiksDQogICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLGNvbG91ciA9ICJibGFjayIpLA0KICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImJsYWNrIiApLA0KICAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSA1LCBiID0gNSwxMCkgKQ0KDQptYXBhcGxvdDIgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhkaXJlY3Rpb24gPSAtMSkNCmBgYA0KDQojIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC41LiBFZHVjYWNpw7NuOiBOaXZlbCBkZSBlZHVjYWNpw7NuIDwvRk9OVD4gey50YWJzZXR9DQoNCiMjIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC41LjEuIFRhYmxhIGRhdG9zLiA8L0ZPTlQ+DQoNClVuYSBzb2NpZWRhZCBlZHVjYWRhLCBlcyB1bmEgc29jaWVkYWQgZGVzYXJyb2xsYWRhLiBFbCBuaXZlbCBkZSBlZHVjYWNpw7NuIGVzIGZ1bmRhbWVudGFsIGVuIGVsIGRlc2Fycm9sbG8gYSBMUCBkZSB1biBwYcOtcy4gDQoNCkxvcyBwYcOtc2VzIHF1ZSBsaWRlcmFuIGVzdGUgaW5kaWNhZG9yIHNvbiBsb3MgcGHDrXNlcyBkZWwgRXN0ZSBkZSBFdXJvcGEsIHNlZ3VpZG9zIGRlIGxvcyBub3J0ZS1ldXJvcGVvcy4NCg0KQSBsYSBjb2xhLCBjb21vIGVuIG90cm9zIGluZGljYWRvcmVzLCBsb3MgcGHDrXNlcyBtZWRpdGVycsOhbmVvcyBkZWwgc3VyIGRlIEV1cm9wYSAoRXNwYcOxYSwgSXRhbGlhIHkgR3JlY2lhKS4NCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KDQpkZiA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmX2VkdWNhIDwtIGRmICAlPiUgc2VsZWN0KFBhaXNlcywgSW5ncmVzb3NfcGVyc29uYWxlcyxOaXZlbF9lZHVjYWNpb24sIEHDsW9zX2RlX2VkdWNhY2nDs24sIEhhYmlsaWRhZGVzX2RlX2VzdHVkaWFudGVzKSAlPiUgYXJyYW5nZShkZXNjKE5pdmVsX2VkdWNhY2lvbikpDQoNCmRmX2VkdWNhIDwtIG5hLm9taXQoZGZfZWR1Y2EpDQoNCmtuaXRyOjprYWJsZShkZl9lZHVjYSwgZm9ybWF0ID0gImh0bWwiKSAlPiUgDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIikpDQoNCmBgYA0KDQoNCiMjIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC41LjIuIEdyw6FmaWNhLiA8L0ZPTlQ+DQoNCkxhIGdyw6FmaWNhIG5vcyBpbmRpY2EgcXVlIG5vIGhheSB1bmEgcmVsYWNpw7NuIGRpcmVjdGEsIHBvciBsbyBtZW5vcyBhIENQLCBlbnRyZSBuaXZlbCBkZSBlZHVjYWNpw7NuIGUgaW5ncmVzb3MuIEF1bnF1ZSBkaXZlcnNvcyBlc3R1ZGlvcyBpbmRpY2FuIHF1ZSBzaSBlc2Ugbml2ZWwgZGUgZWR1Y2FjacOzbiBhbHRvIHNlIG1hbnRpZW5lIGVuIGVsIExQLCBlbCBuaXZlbCBkZSBkZXNhcnJvbGxvIGRlIGVzYSBzb2NpZWRhZCBjcmVjZXLDoS4NCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCg0KZGYgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvY2FsaWRhZHZpZGFfZGVmaW5pdGl2by5jc3YiKQ0KDQpkZl9lZHVjYSA8LSBkZiAgJT4lIHNlbGVjdChQYWlzZXMsIEluZ3Jlc29zX3BlcnNvbmFsZXMsTml2ZWxfZWR1Y2FjaW9uLCBBw7Fvc19kZV9lZHVjYWNpw7NuLCBIYWJpbGlkYWRlc19kZV9lc3R1ZGlhbnRlcykNCg0KZGZfZWR1Y2EgPC0gbmEub21pdChkZl9lZHVjYSkNCg0KZ2dwbG90KGRmX2VkdWNhLCBhZXMoSW5ncmVzb3NfcGVyc29uYWxlcywgTml2ZWxfZWR1Y2FjaW9uLCBsYWJlbCA9IFBhaXNlcykpICsgDQogIGdlb21fcG9pbnQoKSArIA0KICBnZW9tX3BvaW50KGRhdGEgPSBmaWx0ZXIoZGZfZWR1Y2EsIFBhaXNlcyA9PSAiU3BhaW4iKSwgY29sb3VyID0gInBpbmsiLCBzaXplID0gNikrIA0KICBnZW9tX3BvaW50KGRhdGEgPSBmaWx0ZXIoZGZfZWR1Y2EsIFBhaXNlcyA9PSAiT0VDRCAtIFRvdGFsIiksIGNvbG91ciA9ICJ2aW9sZXQiLCBzaXplID0gNikrDQogIGxhYnModGl0bGUgPSAiUmVsYWNpw7NuIGVudHJlIGluZ3Jlc29zIHkgbml2ZWwgZGUgZWR1Y2FjacOzbiIgLA0KICAgICAgIHkgPSAiSW5ncmVzb3MgcGVyc29uYWxlcyAoZW4gZMOzbGFyZXMpIiwNCiAgICAgICB4ID0gIk5pdmVsIGRlIGVkdWNhY2nDs24gKHNvYnJlIGJhc2UgMTAwKSIsDQogICAgICAgY2FwdGlvbiA9ICJGdWVudGUgT0NERSIpKw0KICBnZW9tX3Ntb290aCgpKyBnZW9tX2xhYmVsX3JlcGVsKCkrIHRoZW1lX2Vjb25vbWlzdCgpDQoNCg0KYGBgIA0KDQojIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuNS4zLiBNYXBhLiA8L0ZPTlQ+DQoNClZlbW9zIGNsYXJhbWVudGUgbGEgZGlmZXJlbmNpYSBlbiBuaXZlbGVzIGRlIGVkdWNhY2nDs24gZW50cmUgZWwgc3VyIHkgZWwgbm9ydGUtZXN0ZSBkZSBFdXJvcGEuDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQoNCm1hcGFkYXRhX1VFPC0gbWFwX2RhdGEoIndvcmxkIikgJT4lIGZpbHRlcihyZWdpb24gJWluJSBjKCJBdXN0cmlhIiwiQmVsZ2l1bSIsIkJ1bGdhcmlhIiwiQ3JvYXRpYSIsIkN5cHJ1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ3plY2ggUmVwdWJsaWMiLCJEZW5tYXJrIiwiRXN0b25pYSIsIkZpbmxhbmQiLCJGcmFuY2UiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdlcm1hbnkiLCJHcmVlY2UiLCJIdW5nYXJ5IiwiSXJlbGFuZCIsIkl0YWx5IiwiTGF0dmlhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMaXRodWFuaWEiLCJMdXhlbWJvdXJnIiwiTWFsdGEiLCJOZXRoZXJsYW5kcyIsIlBvbGFuZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG9ydHVnYWwiLCJSb21hbmlhIiwiU2xvdmFraWEiLCJTbG92ZW5pYSIsIlNwYWluIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTd2VkZW4iLCJVSyIsIlN3aXR6ZXJsYW5kIiwiQm9zbmlhIGFuZCBIZXJ6ZWdvdmluYSIsIlNlcmJpYSIsIlVrcmFpbmUiLCJCZWxhcnVzIiwiQWxiYW5pYSIsIk1vbnRlbmVncm8iLCJLb3Nvdm8iLCJNYWNlZG9uaWEiLCJNb2xkb3ZhIikpDQoNCm1hcGFkYXRhX1VFXyA8LSBtYXBhZGF0YV9VRSAlPiUgbXV0YXRlKHJlZ2lvbiA9IGNhc2Vfd2hlbigNCiAgcmVnaW9uID09ICJVSyIgfiAiVW5pdGVkIEtpbmdkb20iLA0KICBUUlVFICB+ICByZWdpb24gKSkNCg0KbWFwZGF0YV9VRV8gPC0gZnVsbF9qb2luIChtYXBhZGF0YV9VRV8sZGZfZWR1Y2EsIGJ5ID0gYygicmVnaW9uIj0iUGFpc2VzIikpDQoNCm1hcGFwbG90IDwtIGdncGxvdChtYXBkYXRhX1VFXywgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cD1ncm91cCwgZmlsbCA9IE5pdmVsX2VkdWNhY2lvbikgKSArDQogIGdlb21fcG9seWdvbihjb2xvciA9IiNmZmZmZmYiKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIiMzMTMyMDAiLGhpZ2ggPSAiI2Y3ZmYwMCIpICsNCiAgbGFicyhmaWxsPSJOaXZlbF9lZHVjYWNpb24iLA0KICAgICAgIHg9TlVMTCwNCiAgICAgICB5PU5VTEwsDQogICAgICAgdGl0bGU9Ik5pdmVsIGRlIGVkdWNhY2nDs24gKHNvYnJlIGJhc2UgMTAwKSIsDQogICAgICAgY2FwdGlvbj0iRnVlbnRlOiBPQ0RFIikgKw0KICB0aGVtZSggcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gIiNmZmZmZmYiKSwNCiAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImxhdmVuZGVyYmx1c2giLCBzaXplID0gMC4xICksDQogICAgICAgICBwYW5lbC5ncmlkICA9IGVsZW1lbnRfbGluZSggY29sb3VyID0iZ3JleSIpLA0KICAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSxjb2xvdXIgPSAiYmxhY2siKSwNCiAgICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gImNvcm5zaWxrMiIsIGNvbG91ciA9ICJibGFjayIgKSwNCiAgICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSA1LCByID0gNSwgYiA9IDUsMTApICkNCg0KbWFwYXBsb3QgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhkaXJlY3Rpb24gPSAtMSkNCg0KYGBgIA0KDQojIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuNS40LiBDaHVua3MuIDwvRk9OVD4NCg0KRW4gZXN0ZSBhcGFydGFkbyBzZSBtdWVzdHJhbiBsb3MgdHJvem9zIGRlIGPDs2RpZ28gUiAoY2h1bmspIHV0aWxpemFkb3MgcGFyYSBoYWNlciBsYSB0YWJsYSwgZWwgZ3LDoWZpY28geSBlbCBtYXBhLiBTZXBhcsOhbmRvbG8gZGUgbG9zIGRlbcOhcywgaGFjZSBxdWUgbGEgbGVjdHVyYSBkZWwgdHJhYmFqbyBzZWEgbcOhcyBmw6FjaWwgeSBhbWVuYS4NCg0KYGBge3IsIGVjaG8gPSBUUlVFLCBldmFsID0gRkFMU0V9DQoNCiNBc8OtIGhlIGhlY2hvIGxhIHRhYmxhDQoNCmRmIDwtIHJpbzo6aW1wb3J0KCIuL2RhdG9zL2NhbGlkYWR2aWRhX2RlZmluaXRpdm8uY3N2IikNCg0KZGZfZWR1Y2EgPC0gZGYgICU+JSBzZWxlY3QoUGFpc2VzLCBJbmdyZXNvc19wZXJzb25hbGVzLE5pdmVsX2VkdWNhY2lvbiwgQcOxb3NfZGVfZWR1Y2FjacOzbiwgSGFiaWxpZGFkZXNfZGVfZXN0dWRpYW50ZXMpICU+JSBhcnJhbmdlKGRlc2MoTml2ZWxfZWR1Y2FjaW9uKSkNCg0KZGZfZWR1Y2EgPC0gbmEub21pdChkZl9lZHVjYSkNCg0Ka25pdHI6OmthYmxlKGRmX2VkdWNhKQ0KDQojQXPDrSBoZSBoZWNobyBlbCBncsOhZmljbyANCg0KZGYgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvY2FsaWRhZHZpZGFfZGVmaW5pdGl2by5jc3YiKQ0KDQpkZl9lZHVjYSA8LSBkZiAgJT4lIHNlbGVjdChQYWlzZXMsIEluZ3Jlc29zX3BlcnNvbmFsZXMsTml2ZWxfZWR1Y2FjaW9uLCBBw7Fvc19kZV9lZHVjYWNpw7NuLCBIYWJpbGlkYWRlc19kZV9lc3R1ZGlhbnRlcykNCg0KZGZfZWR1Y2EgPC0gbmEub21pdChkZl9lZHVjYSkNCg0KZ2dwbG90KGRmX2VkdWNhLCBhZXMoSW5ncmVzb3NfcGVyc29uYWxlcywgTml2ZWxfZWR1Y2FjaW9uLCBsYWJlbCA9IFBhaXNlcykpICsgDQogIGdlb21fcG9pbnQoKSArIA0KICBnZW9tX3BvaW50KGRhdGEgPSBmaWx0ZXIoZGZfZWR1Y2EsIFBhaXNlcyA9PSAiU3BhaW4iKSwgY29sb3VyID0gInBpbmsiLCBzaXplID0gNikrIA0KICBnZW9tX3BvaW50KGRhdGEgPSBmaWx0ZXIoZGZfZWR1Y2EsIFBhaXNlcyA9PSAiT0VDRCAtIFRvdGFsIiksIGNvbG91ciA9ICJ2aW9sZXQiLCBzaXplID0gNikrDQogIGxhYnModGl0bGUgPSAiUmVsYWNpw7NuIGVudHJlIGluZ3Jlc29zIHkgbml2ZWwgZGUgZWR1Y2FjacOzbiIgLA0KICAgICAgIHkgPSAiSW5ncmVzb3MgcGVyc29uYWxlcyAoZW4gZMOzbGFyZXMpIiwNCiAgICAgICB4ID0gIk5pdmVsIGRlIGVkdWNhY2nDs24gKHNvYnJlIGJhc2UgMTAwKSIsDQogICAgICAgY2FwdGlvbiA9ICJGdWVudGUgT0NERSIpKw0KICBnZW9tX3Ntb290aCgpKyBnZW9tX2xhYmVsX3JlcGVsKCkrIHRoZW1lX2Vjb25vbWlzdCgpDQoNCiNBc8OtIGhlIGhlY2hvIGVsIG1hcGENCg0KbWFwYWRhdGFfVUU8LSBtYXBfZGF0YSgid29ybGQiKSAlPiUgZmlsdGVyKHJlZ2lvbiAlaW4lIGMoIkF1c3RyaWEiLCJCZWxnaXVtIiwiQnVsZ2FyaWEiLCJDcm9hdGlhIiwiQ3lwcnVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDemVjaCBSZXB1YmxpYyIsIkRlbm1hcmsiLCJFc3RvbmlhIiwiRmlubGFuZCIsIkZyYW5jZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2VybWFueSIsIkdyZWVjZSIsIkh1bmdhcnkiLCJJcmVsYW5kIiwiSXRhbHkiLCJMYXR2aWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxpdGh1YW5pYSIsIkx1eGVtYm91cmciLCJNYWx0YSIsIk5ldGhlcmxhbmRzIiwiUG9sYW5kIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3J0dWdhbCIsIlJvbWFuaWEiLCJTbG92YWtpYSIsIlNsb3ZlbmlhIiwiU3BhaW4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlN3ZWRlbiIsIlVLIiwiU3dpdHplcmxhbmQiLCJCb3NuaWEgYW5kIEhlcnplZ292aW5hIiwiU2VyYmlhIiwiVWtyYWluZSIsIkJlbGFydXMiLCJBbGJhbmlhIiwiTW9udGVuZWdybyIsIktvc292byIsIk1hY2Vkb25pYSIsIk1vbGRvdmEiKSkNCg0KbWFwYWRhdGFfVUVfIDwtIG1hcGFkYXRhX1VFICU+JSBtdXRhdGUocmVnaW9uID0gY2FzZV93aGVuKA0KICByZWdpb24gPT0gIlVLIiB+ICJVbml0ZWQgS2luZ2RvbSIsDQogIFRSVUUgIH4gIHJlZ2lvbiApKQ0KDQptYXBkYXRhX1VFXyA8LSBmdWxsX2pvaW4gKG1hcGFkYXRhX1VFXyxkZl9lZHVjYSwgYnkgPSBjKCJyZWdpb24iPSJQYWlzZXMiKSkNCg0KbWFwYXBsb3QgPC0gZ2dwbG90KG1hcGRhdGFfVUVfLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gTml2ZWxfZWR1Y2FjaW9uKSApICsNCiAgZ2VvbV9wb2x5Z29uKGNvbG9yID0iI2ZmZmZmZiIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiIzMxMzIwMCIsaGlnaCA9ICIjZjdmZjAwIikgKw0KICBsYWJzKGZpbGw9Ik5pdmVsX2VkdWNhY2lvbiIsDQogICAgICAgeD1OVUxMLA0KICAgICAgIHk9TlVMTCwNCiAgICAgICB0aXRsZT0iTml2ZWwgZGUgZWR1Y2FjacOzbiAoc29icmUgYmFzZSAxMDApIiwNCiAgICAgICBjYXB0aW9uPSJGdWVudGU6IE9DREUiKSArDQogIHRoZW1lKCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICJjb3Juc2lsazIiLCBjb2xvdXIgPSAibGF2ZW5kZXJibHVzaCIsIHNpemUgPSAwLjEgKSwNCiAgICAgICAgIHBhbmVsLmdyaWQgID0gZWxlbWVudF9saW5lKCBjb2xvdXIgPSJncmV5IiksDQogICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLGNvbG91ciA9ICJibGFjayIpLA0KICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImJsYWNrIiApLA0KICAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSA1LCBiID0gNSwxMCkgKQ0KDQptYXBhcGxvdCArIHNjYWxlX2ZpbGxfdmlyaWRpc19jKGRpcmVjdGlvbiA9IC0xKQ0KYGBgDQoNCg0KIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuNi4gU2F0aXNmYWNjacOzbiBhbnRlIGxhIHZpZGEgPC9GT05UPiB7LnRhYnNldH0NCg0KIyMjIDxGT05UIENPTE9SPSJPcmFuZ2UiPiA0LjYuMS4gVGFibGEgZGF0b3MuIDwvRk9OVD4NCg0KUGFyYSBtw60sIGVsIGluZGljYWRvciBtw6FzIGltcG9ydGFudGUgKGNvbiBsb3MgaW5ncmVzb3MpLiBFcyBlbCBpbmRpY2Fkb3IgcXVlIG1lam9yIHJlZmxlamEgZWwgZXN0YWRvIGRlIGJpZW5lc3RhciBzb2NpYWwgZGUgbG9zIGludGVncmFudGVzIGRlIHVuYSBzb2NpZWRhZCB5IGVsIHF1ZSBzaXJ2ZSBkZSBjb250cmFwZXNvIGVudHJlIGluZGljYWRvcmVzIGRlIGRlc2Fycm9sbG8gZGUgdW5hIHNvY2llZGFkICAodHJhYmFqby10aWVtcG8gZGUgb2NpbykuDQoNCkxvcyBwYcOtc2VzIGRlbCBub3J0ZSBkZSBFdXJvcGEgeSBTdWl6YSB2dWVsdmVuIGEgbGlkZXJhci4gRXN0YSB2ZXogRXNwYcOxYSBlc3TDoSBlbiBidWVuYSBwb3NpY2nDs24sIGNlcmNhbm8gYSBsYSBtZWRpYSBkZSBsYSBPQ0RFLg0KDQpBIGxhIGNvbGEsIGxvcyBwYcOtc2VzIGRlbCBFc3RlIGRlIEV1cm9wYSwgR3JlY2lhIHkgUG9ydHVnYWwgKMOpc3RvcyBkb3Mgw7psdGltb3MgbcOhcyBnb2xwZWFkb3MgZW4gbGEgw7psdGltYSBjcmlzaXMgZWNvbsOzbWljYS1maW5hbmNpZXJhKS4NCg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KDQpkZiA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmX3NhdGlzZmFjY2lvbiA8LSBkZiAgJT4lIHNlbGVjdChQYWlzZXMsIEluZ3Jlc29zX3BlcnNvbmFsZXMsU2F0aXNmYWNjaW9uX3ZpZGEpJT4lIGFycmFuZ2UoZGVzYyhTYXRpc2ZhY2Npb25fdmlkYSkpDQoNCmRmX3NhdGlzZmFjY2lvbiA8LSBuYS5vbWl0KGRmX3NhdGlzZmFjY2lvbikNCg0KZGZfc2F0aXNmYWNjaW9uICU+JSBndCgpDQoNCmBgYA0KDQoNCiMjIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC42LjIuIEdyw6FmaWNhLiA8L0ZPTlQ+DQoNClBhcmVjZSBxdWUgZWwgZGljaG8gcXVlICoiZWwgZGluZXJvIG5vIGRhIGxhIGZlbGljaWRhZCIqIGxvIHZhbW9zIGEgZGVzbWVudGlyIGVuIGVzdGUgYXBhcnRhZG8uDQoNClNpIHJlbGFjaW9uYW1vcywgaW5ncmVzb3MgY29uIHNhdGlzZmFjacOzbiBkZSB2aWRhLCBub3Mgc2FsZSBxdWUgYSBtYXlvciBpbmdyZXNvcywgbWF5b3Igc2F0aXNmYWNpw7NuIGRlIHZpZGEgcGFyYSBsb3MgY2l1ZGFkYW5vcy4NCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCg0KZ2dwbG90KGRmX3NhdGlzZmFjY2lvbiwgYWVzKEluZ3Jlc29zX3BlcnNvbmFsZXMsIFNhdGlzZmFjY2lvbl92aWRhLCBsYWJlbCA9IFBhaXNlcykpICsgDQogIGdlb21fcG9pbnQoKSArIA0KICBnZW9tX3BvaW50KGRhdGEgPSBmaWx0ZXIoZGZfc2F0aXNmYWNjaW9uLCBQYWlzZXMgPT0gIlNwYWluIiksIGNvbG91ciA9ICJwaW5rIiwgc2l6ZSA9IDYpKyANCiAgZ2VvbV9wb2ludChkYXRhID0gZmlsdGVyKGRmX3NhdGlzZmFjY2lvbiwgUGFpc2VzID09ICJPRUNEIC0gVG90YWwiKSwgY29sb3VyID0gInZpb2xldCIsIHNpemUgPSA2KSsNCiAgbGFicyh0aXRsZSA9ICJSZWxhY2nDs24gZW50cmUgaW5ncmVzb3MgeSBzYXRpc2ZhY2Npw7NuIGFudGUgbGEgdmlkYSIgLA0KICAgICAgIHkgPSAiSW5ncmVzb3MgcGVyc29uYWxlcyAoZW4gZMOzbGFyZXMpIiwNCiAgICAgICB4ID0gInNhdGlzZmFjY2nDs24gYW50ZSBsYSB2aWRhIChub3RhIGRlIDEgYSAxMCkiLA0KICAgICAgIGNhcHRpb24gPSAiRnVlbnRlIE9DREUiKSsNCiAgZ2VvbV9zbW9vdGgoKSsgZ2VvbV9sYWJlbF9yZXBlbCgpKyB0aGVtZV9jYWxjKCkNCg0KYGBgIA0KDQojIyMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+IDQuNi4zLiBNYXBhLiA8L0ZPTlQ+DQoNClNpIHRyYW5zZmVyaW1vcyBsb3MgZGF0b3MgZGUgbGEgdGFibGEgY3JlYWRhIGVuIGVsIHByaW1lciBhcGFydGFkbyBhIHVuIG1hcGEsIHF1ZWRhIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6DQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQoNCm1hcGFkYXRhX1VFPC0gbWFwX2RhdGEoIndvcmxkIikgJT4lIGZpbHRlcihyZWdpb24gJWluJSBjKCJBdXN0cmlhIiwiQmVsZ2l1bSIsIkJ1bGdhcmlhIiwiQ3JvYXRpYSIsIkN5cHJ1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ3plY2ggUmVwdWJsaWMiLCJEZW5tYXJrIiwiRXN0b25pYSIsIkZpbmxhbmQiLCJGcmFuY2UiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdlcm1hbnkiLCJHcmVlY2UiLCJIdW5nYXJ5IiwiSXJlbGFuZCIsIkl0YWx5IiwiTGF0dmlhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMaXRodWFuaWEiLCJMdXhlbWJvdXJnIiwiTWFsdGEiLCJOZXRoZXJsYW5kcyIsIlBvbGFuZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUG9ydHVnYWwiLCJSb21hbmlhIiwiU2xvdmFraWEiLCJTbG92ZW5pYSIsIlNwYWluIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTd2VkZW4iLCJVSyIsIlN3aXR6ZXJsYW5kIiwiQm9zbmlhIGFuZCBIZXJ6ZWdvdmluYSIsIlNlcmJpYSIsIlVrcmFpbmUiLCJCZWxhcnVzIiwiQWxiYW5pYSIsIk1vbnRlbmVncm8iLCJLb3Nvdm8iLCJNYWNlZG9uaWEiLCJNb2xkb3ZhIikpDQoNCm1hcGFkYXRhX1VFXyA8LSBtYXBhZGF0YV9VRSAlPiUgbXV0YXRlKHJlZ2lvbiA9IGNhc2Vfd2hlbigNCiAgcmVnaW9uID09ICJVSyIgfiAiVW5pdGVkIEtpbmdkb20iLA0KICBUUlVFICB+ICByZWdpb24gKSkNCg0KbWFwZGF0YV9VRV8gPC0gZnVsbF9qb2luIChtYXBhZGF0YV9VRV8sZGZfc2F0aXNmYWNjaW9uLCBieSA9IGMoInJlZ2lvbiI9IlBhaXNlcyIpKQ0KDQptYXBhcGxvdCA8LSBnZ3Bsb3QobWFwZGF0YV9VRV8sIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXA9Z3JvdXAsIGZpbGwgPSBTYXRpc2ZhY2Npb25fdmlkYSkgKSArDQogIGdlb21fcG9seWdvbihjb2xvciA9IiNmZmZmZmYiKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIiMzMTMyMDAiLGhpZ2ggPSAiI2Y3ZmYwMCIpICsNCiAgbGFicyhmaWxsPSJTYXRpc2ZhY2Npb25fdmlkYSIsDQogICAgICAgeD1OVUxMLA0KICAgICAgIHk9TlVMTCwNCiAgICAgICB0aXRsZT0iU2F0aXNmYWNjacOzbiBhbnRlIGxhIHZpZGEgKG5vdGEgZGVsIDEgYWwgMTApIiwNCiAgICAgICBjYXB0aW9uPSJGdWVudGU6IE9DREUiKSArDQogIHRoZW1lKCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICJjb3Juc2lsazIiLCBjb2xvdXIgPSAibGF2ZW5kZXJibHVzaCIsIHNpemUgPSAwLjEgKSwNCiAgICAgICAgIHBhbmVsLmdyaWQgID0gZWxlbWVudF9saW5lKCBjb2xvdXIgPSJncmV5IiksDQogICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLGNvbG91ciA9ICJibGFjayIpLA0KICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImJsYWNrIiApLA0KICAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSA1LCBiID0gNSwxMCkgKQ0KDQptYXBhcGxvdCArIHNjYWxlX2ZpbGxfdmlyaWRpc19jKGRpcmVjdGlvbiA9IC0xKQ0KDQpgYGAgDQoNCiMjIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC42LjQuIENodW5rcy4gPC9GT05UPg0KDQpFbiBlc3RlIGFwYXJ0YWRvIHNlIG11ZXN0cmFuIGxvcyB0cm96b3MgZGUgY8OzZGlnbyBSIChjaHVuaykgdXRpbGl6YWRvcyBwYXJhIGhhY2VyIGxhIHRhYmxhLCBlbCBncsOhZmljbyB5IGVsIG1hcGEuIFNlcGFyw6FuZG9sbyBkZSBsb3MgZGVtw6FzLCBoYWNlIHF1ZSBsYSBsZWN0dXJhIGRlbCB0cmFiYWpvIHNlYSBtw6FzIGbDoWNpbCB5IGFtZW5hLg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIGV2YWwgPSBGQUxTRX0NCg0KI0Fzw60gaGUgaGVjaG8gbGEgdGFibGENCg0KZGYgPC0gcmlvOjppbXBvcnQoIi4vZGF0b3MvY2FsaWRhZHZpZGFfZGVmaW5pdGl2by5jc3YiKQ0KDQpkZl9zYXRpc2ZhY2Npb24gPC0gZGYgICU+JSBzZWxlY3QoUGFpc2VzLCBJbmdyZXNvc19wZXJzb25hbGVzLFNhdGlzZmFjY2lvbl92aWRhKSAlPiUgYXJyYW5nZShkZXNjKFNhdGlzZmFjY2lvbl92aWRhKSkNCg0KZGZfc2F0aXNmYWNjaW9uIDwtIG5hLm9taXQoZGZfc2F0aXNmYWNjaW9uKQ0KDQpkZl9zYXRpc2ZhY2Npb24gJT4lIGd0KCkNCg0KI0Fzw60gaGUgaGVjaG8gZWwgZ3LDoWZpY28gDQoNCmdncGxvdChkZl9zYXRpc2ZhY2Npb24sIGFlcyhJbmdyZXNvc19wZXJzb25hbGVzLCBTYXRpc2ZhY2Npb25fdmlkYSwgbGFiZWwgPSBQYWlzZXMpKSArIA0KICBnZW9tX3BvaW50KCkgKyANCiAgZ2VvbV9wb2ludChkYXRhID0gZmlsdGVyKGRmX3NhdGlzZmFjY2lvbiwgUGFpc2VzID09ICJTcGFpbiIpLCBjb2xvdXIgPSAicGluayIsIHNpemUgPSA2KSsgDQogIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihkZl9zYXRpc2ZhY2Npb24sIFBhaXNlcyA9PSAiT0VDRCAtIFRvdGFsIiksIGNvbG91ciA9ICJ2aW9sZXQiLCBzaXplID0gNikrDQogIGxhYnModGl0bGUgPSAiUmVsYWNpw7NuIGVudHJlIGluZ3Jlc29zIHkgbml2ZWwgZGUgZWR1Y2FjacOzbiIgLA0KICAgICAgIHkgPSAiSW5ncmVzb3MgcGVyc29uYWxlcyAoZW4gZMOzbGFyZXMpIiwNCiAgICAgICB4ID0gInNhdGlzZmFjY2nDs24gYW50ZSBsYSB2aWRhIChub3RhIGRlIDEgYSAxMCkiLA0KICAgICAgIGNhcHRpb24gPSAiRnVlbnRlIE9DREUiKSsNCiAgZ2VvbV9zbW9vdGgoKSsgZ2VvbV9sYWJlbF9yZXBlbCgpKyB0aGVtZV9jYWxjKCkNCg0KI0Fzw60gaGUgaGVjaG8gZWwgbWFwYQ0KDQptYXBhZGF0YV9VRTwtIG1hcF9kYXRhKCJ3b3JsZCIpICU+JSBmaWx0ZXIocmVnaW9uICVpbiUgYygiQXVzdHJpYSIsIkJlbGdpdW0iLCJCdWxnYXJpYSIsIkNyb2F0aWEiLCJDeXBydXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkN6ZWNoIFJlcHVibGljIiwiRGVubWFyayIsIkVzdG9uaWEiLCJGaW5sYW5kIiwiRnJhbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHZXJtYW55IiwiR3JlZWNlIiwiSHVuZ2FyeSIsIklyZWxhbmQiLCJJdGFseSIsIkxhdHZpYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGl0aHVhbmlhIiwiTHV4ZW1ib3VyZyIsIk1hbHRhIiwiTmV0aGVybGFuZHMiLCJQb2xhbmQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcnR1Z2FsIiwiUm9tYW5pYSIsIlNsb3Zha2lhIiwiU2xvdmVuaWEiLCJTcGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3dlZGVuIiwiVUsiLCJTd2l0emVybGFuZCIsIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiLCJTZXJiaWEiLCJVa3JhaW5lIiwiQmVsYXJ1cyIsIkFsYmFuaWEiLCJNb250ZW5lZ3JvIiwiS29zb3ZvIiwiTWFjZWRvbmlhIiwiTW9sZG92YSIpKQ0KDQptYXBhZGF0YV9VRV8gPC0gbWFwYWRhdGFfVUUgJT4lIG11dGF0ZShyZWdpb24gPSBjYXNlX3doZW4oDQogIHJlZ2lvbiA9PSAiVUsiIH4gIlVuaXRlZCBLaW5nZG9tIiwNCiAgVFJVRSAgfiAgcmVnaW9uICkpDQoNCm1hcGRhdGFfVUVfIDwtIGZ1bGxfam9pbiAobWFwYWRhdGFfVUVfLGRmX3NhdGlzZmFjY2lvbiwgYnkgPSBjKCJyZWdpb24iPSJQYWlzZXMiKSkNCg0KbWFwYXBsb3QgPC0gZ2dwbG90KG1hcGRhdGFfVUVfLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gU2F0aXNmYWNjaW9uX3ZpZGEpICkgKw0KICBnZW9tX3BvbHlnb24oY29sb3IgPSIjZmZmZmZmIikgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjMzEzMjAwIixoaWdoID0gIiNmN2ZmMDAiKSArDQogIGxhYnMoZmlsbD0iU2F0aXNmYWNjaW9uX3ZpZGEiLA0KICAgICAgIHg9TlVMTCwNCiAgICAgICB5PU5VTEwsDQogICAgICAgdGl0bGU9IlNhdGlzZmFjY2nDs24gYW50ZSBsYSB2aWRhIChub3RhIGRlbCAxIGFsIDEwKSIsDQogICAgICAgY2FwdGlvbj0iRnVlbnRlOiBPQ0RFIikgKw0KICB0aGVtZSggcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gIiNmZmZmZmYiKSwNCiAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImxhdmVuZGVyYmx1c2giLCBzaXplID0gMC4xICksDQogICAgICAgICBwYW5lbC5ncmlkICA9IGVsZW1lbnRfbGluZSggY29sb3VyID0iZ3JleSIpLA0KICAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLA0KICAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSxjb2xvdXIgPSAiYmxhY2siKSwNCiAgICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KCBmaWxsID0gImNvcm5zaWxrMiIsIGNvbG91ciA9ICJibGFjayIgKSwNCiAgICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSA1LCByID0gNSwgYiA9IDUsMTApICkNCg0KbWFwYXBsb3QgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhkaXJlY3Rpb24gPSAtMSkNCg0KYGBgDQoNCiMjIDxGT05UIENPTE9SPSJPcmFuZ2UiPiA0LjcuIEJhbGFuY2UgdmlkYS10cmFiYWpvIDwvRk9OVD4gey50YWJzZXR9DQoNCiMjIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC43LjEuIFRhYmxhIGRhdG9zLiA8L0ZPTlQ+DQoNCkNvbW8gY29udHJhcGVzbyBhbCBuaXZlbCBkZSBpbmdyZXNvcyBkZSBsb3MgcGHDrXNlcyBzZSBlbmN1ZW50cmEgZWwgYmFsYW5jZSBxdWUgdGllbmVuIHN1cyBjaXVkYWRhbm9zIGVudHJlIG9jaW8geSB0cmFiYWpvLg0KDQpBcXXDrSwgbG9zIHBhw61zZXMgZGVsIHN1ciBkZSBFdXJvcGEgc2FsZW4gZ2FuYW5kby4gU29uIGxvcyBxdWUgbWVqb3IgZXF1aWxpYnJpbyBlbnRyZSB0cmFiYWpvIHkgb2NpbyB0aWVuZW4uDQoNCkVuIGxhIGNvbGEgbG9zIHBhw61zZXMgZGVsIEVzdGUgZGUgRXVyb3BhLCBBdXN0cmlhIHkgUmVpbm8gVW5pZG8uDQoNCg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0NCmRmXyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmX3ZpZGFfdHJhYmFqbyA8LSBkZl8gICU+JSBzZWxlY3QoUGFpc2VzLFRpZW1wb19vY2lvLEVtcGxlYWRvc190cmFiYWphbl9tdWNoYXMsSW5ncmVzb3NfcGVyc29uYWxlcyklPiUgYXJyYW5nZShkZXNjKFRpZW1wb19vY2lvKSkNCg0KZGZfdmlkYV90cmFiYWpvIDwtIG5hLm9taXQoZGZfdmlkYV90cmFiYWpvKQ0KDQprYWJsZShkZl92aWRhX3RyYWJham8pICU+JQ0KICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZpeGVkX3RoZWFkID0gbGlzdChlbmFibGVkID0gVCwgYmFja2dyb3VuZCA9ICJsaWdodGJsdWUiKSkNCmBgYA0KDQoNCiMjIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC43LjIuIEdyw6FmaWNhLiA8L0ZPTlQ+DQoNCk5vIGhheSB1bmEgcmVsYWNpw7NuIGNsYXJhIGVudHJlIHRpZW1wbyBkZSBvY2lvIGUgaW5ncmVzb3MuDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQoNCmdncGxvdChkZl92aWRhX3RyYWJham8sIGFlcyhJbmdyZXNvc19wZXJzb25hbGVzLCBUaWVtcG9fb2NpbywgbGFiZWwgPSBQYWlzZXMpKSArIA0KICBnZW9tX3BvaW50KCkgKyANCiAgZ2VvbV9wb2ludChkYXRhID0gZmlsdGVyKGRmX3ZpZGFfdHJhYmFqbywgUGFpc2VzID09ICJTcGFpbiIpLCBjb2xvdXIgPSAicGluayIsIHNpemUgPSA2KSsgDQogIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihkZl92aWRhX3RyYWJham8sIFBhaXNlcyA9PSAiT0VDRCAtIFRvdGFsIiksIGNvbG91ciA9ICJ2aW9sZXQiLCBzaXplID0gNikrDQogIGxhYnModGl0bGUgPSAiUmVsYWNpw7NuIGVudHJlIGluZ3Jlc29zIHkgdGllbXBvIGRlIG9jaW8iICwNCiAgICAgICB5ID0gIkluZ3Jlc29zIHBlcnNvbmFsZXMgKGVuIGTDs2xhcmVzKSIsDQogICAgICAgeCA9ICJUaWVtcG8gZGUgb2NpbyAocG9yY2VudGFqZSkiLA0KICAgICAgIGNhcHRpb24gPSAiRnVlbnRlIE9DREUiKSsNCiAgZ2VvbV9zbW9vdGgoKSsgZ2VvbV9sYWJlbF9yZXBlbCgpKyB0aGVtZV9jbGVhbigpDQoNCmBgYCANCg0KIyMjIDxGT05UIENPTE9SPSJPcmFuZ2UiPiA0LjcuMy4gTWFwYS4gPC9GT05UPg0KDQpTaSB0cmFuc2Zlcmltb3MgbG9zIGRhdG9zIGRlIGxhIHRhYmxhIGNyZWFkYSBlbiBlbCBwcmltZXIgYXBhcnRhZG8gYSB1biBtYXBhLCBwb2RlbW9zIG9ic2VydmFyIHVuYSBjb3NhIGN1cmlvc2E6IGludmVydGltb3MgcHLDoWN0aWNhbWVudGUgZWwgbWFwYSBxdWUgaGVtb3Mgb2J0ZW5pZG8gZW4gb3Ryb3MgaW5kaWNhZG9yZXMgY29tbyBlZHVjYWNpw7NuIG8gZW1wbGVvLg0KDQpgYGB7ciBldmFsID0gVFJVRSwgZWNobyA9IEZBTFNFfQ0KDQptYXBhZGF0YV9VRTwtIG1hcF9kYXRhKCJ3b3JsZCIpICU+JSBmaWx0ZXIocmVnaW9uICVpbiUgYygiQXVzdHJpYSIsIkJlbGdpdW0iLCJCdWxnYXJpYSIsIkNyb2F0aWEiLCJDeXBydXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkN6ZWNoIFJlcHVibGljIiwiRGVubWFyayIsIkVzdG9uaWEiLCJGaW5sYW5kIiwiRnJhbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHZXJtYW55IiwiR3JlZWNlIiwiSHVuZ2FyeSIsIklyZWxhbmQiLCJJdGFseSIsIkxhdHZpYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGl0aHVhbmlhIiwiTHV4ZW1ib3VyZyIsIk1hbHRhIiwiTmV0aGVybGFuZHMiLCJQb2xhbmQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcnR1Z2FsIiwiUm9tYW5pYSIsIlNsb3Zha2lhIiwiU2xvdmVuaWEiLCJTcGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3dlZGVuIiwiVUsiLCJTd2l0emVybGFuZCIsIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiLCJTZXJiaWEiLCJVa3JhaW5lIiwiQmVsYXJ1cyIsIkFsYmFuaWEiLCJNb250ZW5lZ3JvIiwiS29zb3ZvIiwiTWFjZWRvbmlhIiwiTW9sZG92YSIpKQ0KDQptYXBhZGF0YV9VRV8gPC0gbWFwYWRhdGFfVUUgJT4lIG11dGF0ZShyZWdpb24gPSBjYXNlX3doZW4oDQogIHJlZ2lvbiA9PSAiVUsiIH4gIlVuaXRlZCBLaW5nZG9tIiwNCiAgVFJVRSAgfiAgcmVnaW9uICkpDQoNCm1hcGRhdGFfVUVfIDwtIGZ1bGxfam9pbiAobWFwYWRhdGFfVUVfLGRmX3ZpZGFfdHJhYmFqbywgYnkgPSBjKCJyZWdpb24iPSJQYWlzZXMiKSkNCg0KbWFwYXBsb3QgPC0gZ2dwbG90KG1hcGRhdGFfVUVfLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gVGllbXBvX29jaW8pICkgKw0KICBnZW9tX3BvbHlnb24oY29sb3IgPSIjZmZmZmZmIikgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjMzEzMjAwIixoaWdoID0gIiNmN2ZmMDAiKSArDQogIGxhYnMoZmlsbD0iVGllbXBvX29jaW8iLA0KICAgICAgIHg9TlVMTCwNCiAgICAgICB5PU5VTEwsDQogICAgICAgdGl0bGU9IlRpZW1wbyBkZSBvY2lvIChwb3JjZW50YWplIHNvYnJlIGhvcmFzIHRvdGFsZXMpIiwNCiAgICAgICBjYXB0aW9uPSJGdWVudGU6IE9DREUiKSArDQogIHRoZW1lKCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICJjb3Juc2lsazIiLCBjb2xvdXIgPSAibGF2ZW5kZXJibHVzaCIsIHNpemUgPSAwLjEgKSwNCiAgICAgICAgIHBhbmVsLmdyaWQgID0gZWxlbWVudF9saW5lKCBjb2xvdXIgPSJncmV5IiksDQogICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLGNvbG91ciA9ICJibGFjayIpLA0KICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImJsYWNrIiApLA0KICAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSA1LCBiID0gNSwxMCkgKQ0KDQptYXBhcGxvdCArIHNjYWxlX2ZpbGxfdmlyaWRpc19jKGRpcmVjdGlvbiA9IC0xKQ0KDQpgYGAgDQoNCiMjIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj4gNC43LjQuIENodW5rcy4gPC9GT05UPg0KDQpFbiBlc3RlIGFwYXJ0YWRvIHNlIG11ZXN0cmFuIGxvcyB0cm96b3MgZGUgY8OzZGlnbyBSIChjaHVuaykgdXRpbGl6YWRvcyBwYXJhIGhhY2VyIGxhIHRhYmxhLCBlbCBncsOhZmljbyB5IGVsIG1hcGEuIFNlcGFyw6FuZG9sbyBkZSBsb3MgZGVtw6FzLCBoYWNlIHF1ZSBsYSBsZWN0dXJhIGRlbCB0cmFiYWpvIHNlYSBtw6FzIGbDoWNpbCB5IGFtZW5hLg0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIGV2YWwgPSBGQUxTRX0NCg0KI0Fzw60gaGUgaGVjaG8gbGEgdGFibGEgDQoNCmRmXyA8LSByaW86OmltcG9ydCgiLi9kYXRvcy9jYWxpZGFkdmlkYV9kZWZpbml0aXZvLmNzdiIpDQoNCmRmX3ZpZGFfdHJhYmFqbyA8LSBkZl8gICU+JSBzZWxlY3QoUGFpc2VzLFRpZW1wb19vY2lvLEVtcGxlYWRvc190cmFiYWphbl9tdWNoYXMsSW5ncmVzb3NfcGVyc29uYWxlcyklPiUgYXJyYW5nZShkZXNjKFRpZW1wb19vY2lvKSkNCg0KZGZfdmlkYV90cmFiYWpvIDwtIG5hLm9taXQoZGZfdmlkYV90cmFiYWpvKQ0KDQprYWJsZShkZl92aWRhX3RyYWJham8pICU+JQ0KICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZpeGVkX3RoZWFkID0gbGlzdChlbmFibGVkID0gVCwgYmFja2dyb3VuZCA9ICJsaWdodGJsdWUiKSkNCg0KI0Fzw60gaGUgaGVjaG8gZWwgZ3LDoWZpY28gDQoNCmdncGxvdChkZl92aWRhX3RyYWJham8sIGFlcyhJbmdyZXNvc19wZXJzb25hbGVzLCBUaWVtcG9fb2NpbywgbGFiZWwgPSBQYWlzZXMpKSArIA0KICBnZW9tX3BvaW50KCkgKyANCiAgZ2VvbV9wb2ludChkYXRhID0gZmlsdGVyKGRmX3ZpZGFfdHJhYmFqbywgUGFpc2VzID09ICJTcGFpbiIpLCBjb2xvdXIgPSAicGluayIsIHNpemUgPSA2KSsgDQogIGdlb21fcG9pbnQoZGF0YSA9IGZpbHRlcihkZl92aWRhX3RyYWJham8sIFBhaXNlcyA9PSAiT0VDRCAtIFRvdGFsIiksIGNvbG91ciA9ICJ2aW9sZXQiLCBzaXplID0gNikrDQogIGxhYnModGl0bGUgPSAiUmVsYWNpw7NuIGVudHJlIGluZ3Jlc29zIHkgbml2ZWwgZGUgZWR1Y2FjacOzbiIgLA0KICAgICAgIHkgPSAiSW5ncmVzb3MgcGVyc29uYWxlcyAoZW4gZMOzbGFyZXMpIiwNCiAgICAgICB4ID0gIlRpZW1wbyBkZSBvY2lvIChwb3JjZW50YWplKSIsDQogICAgICAgY2FwdGlvbiA9ICJGdWVudGUgT0NERSIpKw0KICBnZW9tX3Ntb290aCgpKyBnZW9tX2xhYmVsX3JlcGVsKCkrIHRoZW1lX2NsZWFuKCkNCg0KI0Fzw60gaGUgaGVjaG8gZWwgbWFwYQ0KDQptYXBhZGF0YV9VRTwtIG1hcF9kYXRhKCJ3b3JsZCIpICU+JSBmaWx0ZXIocmVnaW9uICVpbiUgYygiQXVzdHJpYSIsIkJlbGdpdW0iLCJCdWxnYXJpYSIsIkNyb2F0aWEiLCJDeXBydXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkN6ZWNoIFJlcHVibGljIiwiRGVubWFyayIsIkVzdG9uaWEiLCJGaW5sYW5kIiwiRnJhbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHZXJtYW55IiwiR3JlZWNlIiwiSHVuZ2FyeSIsIklyZWxhbmQiLCJJdGFseSIsIkxhdHZpYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGl0aHVhbmlhIiwiTHV4ZW1ib3VyZyIsIk1hbHRhIiwiTmV0aGVybGFuZHMiLCJQb2xhbmQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvcnR1Z2FsIiwiUm9tYW5pYSIsIlNsb3Zha2lhIiwiU2xvdmVuaWEiLCJTcGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3dlZGVuIiwiVUsiLCJTd2l0emVybGFuZCIsIkJvc25pYSBhbmQgSGVyemVnb3ZpbmEiLCJTZXJiaWEiLCJVa3JhaW5lIiwiQmVsYXJ1cyIsIkFsYmFuaWEiLCJNb250ZW5lZ3JvIiwiS29zb3ZvIiwiTWFjZWRvbmlhIiwiTW9sZG92YSIpKQ0KDQptYXBhZGF0YV9VRV8gPC0gbWFwYWRhdGFfVUUgJT4lIG11dGF0ZShyZWdpb24gPSBjYXNlX3doZW4oDQogIHJlZ2lvbiA9PSAiVUsiIH4gIlVuaXRlZCBLaW5nZG9tIiwNCiAgVFJVRSAgfiAgcmVnaW9uICkpDQoNCm1hcGRhdGFfVUVfIDwtIGZ1bGxfam9pbiAobWFwYWRhdGFfVUVfLGRmX3ZpZGFfdHJhYmFqbywgYnkgPSBjKCJyZWdpb24iPSJQYWlzZXMiKSkNCg0KbWFwYXBsb3QgPC0gZ2dwbG90KG1hcGRhdGFfVUVfLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gVGllbXBvX29jaW8pICkgKw0KICBnZW9tX3BvbHlnb24oY29sb3IgPSIjZmZmZmZmIikgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjMzEzMjAwIixoaWdoID0gIiNmN2ZmMDAiKSArDQogIGxhYnMoZmlsbD0iVGllbXBvX29jaW8iLA0KICAgICAgIHg9TlVMTCwNCiAgICAgICB5PU5VTEwsDQogICAgICAgdGl0bGU9IlRpZW1wbyBkZSBvY2lvIiwNCiAgICAgICBjYXB0aW9uPSJGdWVudGU6IE9DREUiKSArDQogIHRoZW1lKCBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiI2ZmZmZmZiIpLA0KICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCggZmlsbCA9ICJjb3Juc2lsazIiLCBjb2xvdXIgPSAibGF2ZW5kZXJibHVzaCIsIHNpemUgPSAwLjEgKSwNCiAgICAgICAgIHBhbmVsLmdyaWQgID0gZWxlbWVudF9saW5lKCBjb2xvdXIgPSJncmV5IiksDQogICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksDQogICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLGNvbG91ciA9ICJibGFjayIpLA0KICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIGZpbGwgPSAiY29ybnNpbGsyIiwgY29sb3VyID0gImJsYWNrIiApLA0KICAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDUsIHIgPSA1LCBiID0gNSwxMCkgKQ0KDQptYXBhcGxvdCArIHNjYWxlX2ZpbGxfdmlyaWRpc19jKGRpcmVjdGlvbiA9IC0xKQ0KDQpgYGANCg0KIyA8Rk9OVCBDT0xPUj0iT3JhbmdlIj41LiBDb25sdXNpw7NuLiA8L0ZPTlQ+DQoNCj4g4oCcTGEgdmVyZGFkZXJhIGZlbGljaWRhZCBzb2NpYWwgY29uc2lzdGUgZW4gbGEgYXJtb27DrWEgeSBlbiBlbCB1c28gcGFjw61maWNvIGRlIGxhcyBzYXRpc2ZhY2Npb25lcyBkZSBjYWRhIGluZGl2aWR1by7igJ0g4oCUIE1hcmxlbmUgRGlldHJpY2guDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmU6OmhlcmUoImltYWdlbmVzIiwgImhvbWJyZV9mZWxpei5qcGciKSAgKQ0KDQpgYGANCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+DQoNCkEgbWVudWRvIHBlbnNhbW9zIHF1ZSB1bmEgc29jaWVkYWQgcmljYSwgZXMgdW5hIHNvY2llZGFkIGZlbGl6LiBOYWRhIG3DoXMgbGVqb3MgZGUgbGEgcmVhbGlkYWQuIEVqZW1wbG9zIGNvbW8gZWwgZGUgSmFww7NuIG8gQ29yZWEgZGVsIFN1ciAobm8gYW5hbGl6YWRvcyBlbiBlbCBwcmVzZW50ZSB0cmFiYWpvKSBzb24gdW4gYnVlbiBlamVtcGxvIGRlIGVsbG8uIERhdG9zIG9mcmVjaWRvcyBwb3IgZXN0ZSBpbmZvcm1lIGRlIGxhIE9DREUgZGVtdWVzdHJhbiBxdWUgc3VzIGhhYml0YW50ZXMsIHBlc2UgYSB0ZW5lciB1biBidWVuIG5pdmVsIGVjb27Ds21pY28sIGVzdMOhbiBtZW5vcyBzYXRpc2ZlY2hvcyBjb24gc3UgdmlkYSBxdWUgb3Ryb3MgcGHDrXNlcyBjb24gbWVub3JlcyBpbmdyZXNvcy4gRmFjdG9yZXMgaW5mbHV5ZW50ZXMgZW4gZXN0YSBwZXJjZXBjacOzbiBxdWUgdGllbmUgIHN1cyBoYWJpdGFudGVzLCBwdWVkZW4gc2VyIGxvcyBtYWxvcyBkYXRvcyBxdWUgbXVlc3RyYW4sIGFtYmFzIGVjb25vbcOtYXMsIGVuIGVsIGJhbGFuY2UgZW50cmUgdmlkYSB5IHRyYWJham8uDQoNCkEgbml2ZWwgZXVyb3Blbywgb2JqZXRvIGRlIGVzdGUgZXN0dWRpbywgbG9zIHBhw61zZXMgcXVlIHNhbGVuIGdhbmFkb3Jlcywgc2kgc2UgbWUgcGVybWl0ZSBlc3RhIGxpY2VuY2lhLCBzb24gY2xhcmFtZW50ZSBsb3MgcGHDrXNlcyBuw7NyZGljb3MuIE9jdXBhbiBsb3MgcHJpbWVyb3MgcHVlc3RvcyBlbiBjYXNpIHRvZGFzIGxhcyB2YXJpYWJsZXMsIGluY2x1c28gZW4gbGFzIHF1ZSBubyBlc3TDoW4gZGlyZWN0YW1lbnRlIHJlbGFjaW9uYWRhcyBjb24gbG9zIGluZ3Jlc29zIChlZHVjYWNpw7NuLCBhcG95byBzb2NpYWwgbyBzYXRpc2ZhY2Npw7NuIGFudGUgbGEgdmlkYSksIHBvciBlbmNpbWEgZGUgcGHDrXNlcyBxdWUgdGllbmVuIG1heW9yZXMgaW5ncmVzb3MgcGVyIGPDoXBpdGEgKEx1eGVtYnVyZ28sIFN1aXphLCBBbGxlbWFuaWEpLg0KDQpQZXNlIGEgbG8gcXVlIHNlIHBvZMOtYSBlc3BlcmFyLCBudWVzdHJvIHBhw61zIG5vIHNhbGUgbWFsIHBhcmFkbyBkZWwgdG9kbyBlbiBlc3RlIGVzdHVkaW8gcG9ycXVlIHBlc2UgbG9zIG1hbG9zIGRhdG9zIGVuIGFsZ3Vub3MgaW5kaWNhZG9yZXMgY29tbyBlZHVjYWNpw7NuLCBlbXBsZW8gbyBpbmdyZXNvcywgc2UgZW5jdWVudHJhIGVuIGxhIG1lZGlhIGRlIGxhIE9DREUgZW4gZWwgbcOhcyBpbXBvcnRhbnRlLCBlbiBtaSBvcGluacOzbjogc2F0aXNmYWNjacOzbiBhbnRlIGxhIHZpZGEgZGUgc3VzIGNpdWRhZGFub3MuIERlc3RhY2FuIHRhbWJpw6luIGVuIGFwb3lvIHNvY2lhbCB5IGJhbGFuY2UgZW50cmUgZWwgdGllbXBvIGRlIG9jaW8geSB0cmFiYWpvLg0KDQpFbCBwdW50byBtw6FzIHBvc2l0aXZvIGRlIGVzdGUgw41uZGljZSBlcyBxdWUgY2FkYSBwZXJzb25hLCBlbiBmdW5jacOzbiBkZWwgdmFsb3IgcXVlIGxlIGRhIGEgY2FkYSB1bm8gZGUgbGFzIDExIHZhcmlhYmxlcywgcHVlZGUgdmVyIGVuIHF1ZSBwYcOtcyBlbmNhamFyw61hIG1lam9yLiBMYSBmZWxpY2lkYWQgZXMgZW5vcm1lbWVudGUgc3ViamV0aXZhLiBMbyBxdWUgcHVlZGUgaGFjZXIgZmVsaXogYSB1bmEgc29jaWVkYWQsIHB1ZWRlIG5vIGhhY8OpcnNlbG8gYSBvdHJhLiBFc3RvIHBhcmEgbcOtIGVzIHVuYSBkZSBsYXMgY2xhdmVzIHBvciBsbyBxdWUgZXMgaW5qdXN0byBtZWRpciBlbCBkZXNhcnJvbGxvIGRlIHVuIHBhw61zIHNvbG8gcG9yIGxhIHRhc2EgZGUgY3JlY2ltaWVudG8gZGVsIFBJQiBwZXIgY8OhcGl0YS4NCg0KPGRpdi8+DQoNCiMgPEZPTlQgQ09MT1I9Ik9yYW5nZSI+Ni4gQmlibGlvZ3JhZsOtYS4gPC9GT05UPg0KDQpbUMOhZ2luYSB3ZWIgZGVsIMONbmRpY2UgcGFyYSB1bmEgVmlkYSBNZWpvcl0oaHR0cDovL3d3dy5vZWNkYmV0dGVybGlmZWluZGV4Lm9yZy9lcy8jLzExMTExMTExMTExKQ0KDQpUdXRvcmlhbGVzIGRlIHByb2Zlc2FyIGRlIFVuaXZlcnNpZGFkIGRlIFZhbGVuY2lhLCBbRC5QZWRybyBKLiBQw6lyZXogXShodHRwczovL3BlcmV6cDQ0LmdpdGh1Yi5pby9pbnRyby1kcy0yMC0yMS13ZWIvaW5kZXguaHRtbCkgDQoNCltWw61kZW8gZXhwbGljYXRpdm8gZGUgUmFmYSBHb256w6FsZXogR291dmVpYSBzb2JyZSBjb21vIGFuaW1hciBsYXMgZ3LDoWZpY2FzXShodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PXBuU010YzFQSF93KQ0KDQpEYXRvcyBkZWwgZGF0YWZyYW1lIHkgZ2VvbWV0cmlhcyBkYWRvcyBlbiBjbGFzZSBwb3IgRC5QZWRybyBKLiBQw6lyZXouDQoNCltNZSBoYSBpbnNwaXJhZG8gbWkgYW50ZXJpb3IgdHJhYmFqbyBlbiBncnVwbzogIkxhIGluY2lkZW5jaWEgZGVsIENvdmlkLTE5IGVuIGxhIENvbXVuaWRhZCBWYWxlbmNpYW5hIl0oaHR0cHM6Ly9taWd1ZXJjaW9zLmdpdGh1Yi5pby90cmFiYWpvX0JpZ0RhdGFfZXF1aXBvLykgDQoNCltBcXXDrSBhcHJlbmTDrSBjb21vIHF1aXRhciB2YWxvcmVzIG51bG9zIGRlIGxhcyBmaWxhc10oaHR0cHM6Ly93d3cuZGllZ29jYWx2by5lcy9lbGltaW5hci1uYS1vLXZhbG9yZXMtbnVsb3MtZW4tci8pDQoNCmBgYHtyIGV2YWwgPSBUUlVFLCBlY2hvID0gRkFMU0V9DQpzZXNzaW9uaW5mbzo6c2Vzc2lvbl9pbmZvKCkgJT4lIGRldGFpbHM6OmRldGFpbHMoc3VtbWFyeSA9ICdjdXJyZW50IHNlc3Npb24gaW5mbycpDQpgYGANCg==