Introducción

R4HR Club de R para RRHH es una comunidad de aprendizaje de programación de R para profesionales y estudiantes que trabajen o quieran trabajar en RRHH.

Somos una comunidad que usa mayormente datos de ejemplo relacionados con RRHH, y que genera contenido en castellano para eliminar las barreras en el aprendizaje y facilitar que más personas adopten las herramientas de análisis de datos en sus trabajos.

Para saber más de nosotros te invitamos a leer este post.

También podés ver todo el contenido que generamos en los siguientes links:

Google Drive

YouTube

Github

También te invitamos a seguirnos en todas nuestras redes sociales.

Pueden acceder a los datos crudos desde este link.

# Carga de librerías 
# Instalar pacman install.packages("pacman")

pacman::p_load(tidyverse, funModeling, gt, googlesheets4,gt, CGPfunctions,
               extrafont, scales, ggalt, kableExtra, wordcloud, networkD3,
               data.table, ggeconodist, ggpmisc)



# Carga de Datos ----
# Datos --------

## 2021 ----

# Encuesta
kiwi21 <- read.csv("https://raw.githubusercontent.com/r4hr/kiwi2021/main/data/rh_2021.csv",
                   sep = ";",
                   encoding = "UTF-8") 

kiwi20 <- read.csv("https://raw.githubusercontent.com/r4hr/kiwi2021/main/data/rh_2020.csv", 
                   sep = ";",
                   encoding = "UTF-8")

freelo21 <- read.csv("https://raw.githubusercontent.com/r4hr/kiwi2021/main/data/freelancers_2021.csv",
                     sep = ";",
                     encoding = "UTF-8")

kiwi21_original <- read_sheet("1nhpqDWuJoWhiVj0rIaV51-SdfnSxTpbV3Vcd3iYmyTw")

# Configuraciones generales ----

options(scipen = 999)   # Modifica la visualización de los ejes numérico a valores nominales

loadfonts(quiet = TRUE) # Permite cargar en R otros tipos de fuentes.

# Estilo limpio sin líneas de fondo
estilo <- theme(panel.grid = element_blank(),
                plot.background = element_rect(fill = "#FBFCFC"),
                panel.background = element_blank(),
                text = element_text(family = "Roboto"))

# Estilo limpio con líneas de referencia verticales en gris claro
estilov <- theme(panel.grid = element_blank(),
                 plot.background = element_rect(fill = "#FBFCFC"),
                 panel.background = element_blank(),
                 panel.grid.major.x = element_line(color = "#AEB6BF"),
                 text = element_text(family = "Roboto"))

# Estilo limpio con líneas de referencia horizontales en gris claro
estiloh <- theme(panel.grid = element_blank(),
                 plot.background = element_rect(fill = "#FBFCFC"),
                 panel.background = element_blank(),
                 panel.grid.major.y = element_line(color = "#AEB6BF"),
                 text = element_text(family = "Roboto"))

genero <- c("#1FC3AA", "#8624F5", "#FFD129", "#75838F") # Verde - Violeta - Amarillo - Gris
genero3 <- c("#8624F5","#FFD129", "#1FC3AA")

colores <-  c("#8624F5", "#1FC3AA")

azul <- "#344D7E"
verde <-  "#1FC3AA"
rosa1 <- "#B95192"
rosa2 <- "#EE5777"
naranja <- "#FF764C"
amarillo <- "#FFA600"
gris <- "#75838F"
lila <- "#8624F5"
rojo <- "#943126"

col4 <- c(azul, lila, rosa1, rosa2)
col5 <- c(azul, lila, rosa1, rosa2, naranja)
col6 <- c(azul, lila, rosa1, rosa2, naranja, amarillo)

# Creo un objeto con un texto que se va a repetir mucho a lo largo del análisis
fuente <- "Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2021"

# Creo objetos para formatear las etiquetas numéricas de los ejes x e y
eje_x_n <- scale_x_continuous(labels = comma_format(big.mark = ".", decimal.mark = ","))

eje_y_n <- scale_y_continuous(labels = comma_format(big.mark = ".", decimal.mark = ","))


# Cantidad de respuestas 

rtas21 <- nrow(kiwi21_original)

rtas21_perc <- percent(1- (rtas21 / 762))

rtas_pais <- kiwi21_original %>% 
  select(pais = `País en el que trabajas`) %>% 
  distinct(pais) %>% 
  count() %>% 
  pull()


# Reorganizar puestos jerárquicamente
kiwi21 <- kiwi21 %>% 
  mutate(puesto = factor(puesto, 
                         levels = c("Director", "Gerente", "Jefe", 
                                    "Responsable", "HRBP", "Analista",
                                    "Administrativo", "Pasante")))

Motivaciones

Como en RRHH trabajamos con datos sensibles, es complejo conseguir datos para practicar cuando estás aprendiendo sobre People Analytics, especialmente la parte práctica. Por eso, e inspirados en la Encuesta de SysArmy, una comunidad de tecnología, que entre otras cosas, organiza eventos como Nerdearla.

Por esta razón hicimos nuestra propia encuesta, relevando datos de profesionales que trabajan tanto bajo relación de dependencia como de manera freelance. El relevamiento de datos lo hicimos entre el 22 de octubre y el 22 de noviembre de 2021.

En esta edición recibimos en total 586 respuestas (un 23% menos que en 2020), de 16 países diferentes.

kiwi21 %>% 
  group_by(pais) %>% 
  tally(sort = T) %>% 
  rename("País" = pais,
         "Respuestas" = n) %>% 
  kbl(caption = "Respuestas por País", ) %>% 
  kable_styling(full_width = F, position = "center",
                bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>% 
  footnote(general = fuente)
Respuestas por País
País Respuestas
Argentina 426
Perú 19
Bolivia 16
Costa Rica 15
Uruguay 14
Chile 10
México 7
Paraguay 6
Ecuador 5
Colombia 3
España 2
Guatemala 2
El Salvador 1
Estados Unidos 1
Panamá 1
Venezuela 1
Note:
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2021

Del total de respuestas recibidas, 536 son de personas que trabajan en relación de dependencia en RRHH, mientras que 50 personas trabajan de manera freelance.

kiwi21_original %>% 
  select(Trabajo) %>% 
  group_by(Trabajo) %>% 
  count() %>% 
  ggplot(aes(x = n, y = Trabajo)) +
  geom_col(fill = azul) +
  estilov +
  geom_text(aes(label = n), # Indica la cantidad de decimales
            size = 3,       # Cambia el tamaño de la letra
            hjust = 1.2,    # Mueve la etiqueta para la izquierda
            color = "white",
            family = "Roboto") +
  labs(title = "Respuestas por tipo de trabajador", 
       x = "", y = "", 
       caption = fuente)

En esta edición decidimos realizar los análisis de género en términos de Identidad de Género para intentar abarcar con nuestro análisis la diversidad en términos de identidad de género. Es por esta razón que, a diferencia de la primera edición donde los análisis los hicimos en términos de Mujer/Hombre este año lo hicimos en términos de Mujer cis/Mujer trans y Hombre cis/Hombre trans para poder reflejar con mayor precisión el abánico de identidades y percepciones.

El térmiino “cis” hace referencia a que la persona se identifica con el mismo género con el que nació.

Le agradecemos mucho a Ivana Feldeberg del Observatorio de Datos con Perspectiva de Género por el asesoramiento en este apartado.

Dicho esto, las respuestas según la identidad de género de las personas que participaron es la siguiente:

# Gráfico para relación de dependencia----
div <- kiwi21 %>% 
  select(genero) %>% 
  mutate(genero = factor(genero, 
                         levels = c("Mujer cis", "Hombre cis", 
                                    "Prefiero no responder", "Gay"))) %>% 
  group_by(genero) %>% 
  summarise (n = n()) %>% 
  mutate(freq = n/sum(n)) %>% 
  arrange(-n)

# Compute the cumulative percentages (top of each rectangle)
div$ymax <- cumsum(div$freq)

# Compute the bottom of each rectangle
div$ymin <- c(0, head(div$ymax, n=-1))

# Compute label position
div$labelPosition <- (div$ymax + div$ymin) / 2

# Compute a good label
div$label <- paste0(div$genero, "\n Cant: ", div$n)

# Make the plot
ggplot(div, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=genero)) +
  geom_rect() +
  coord_polar(theta="y") + # Try to remove that to understand how the chart is built initially
  xlim(c(2, 4)) +# Try to remove that to see how to make a pie chart
  scale_fill_manual(values = c("#8624F5",  "#1FC3AA", "#FFD129","#75838F")) +
  theme_void() +
  theme(legend.position = "top",
        panel.background = element_blank(),
        plot.title.position = "plot",
        text = element_text(family = "Roboto")) +
  labs(title = "Cantidad de respuestas según género",
       subtitle = "Relación de Dependencia",
       fill = "Género", 
       caption = fuente)

# Gráfico de freelancers ----
freelo21 <- freelo21 %>% 
  mutate(genero = fct_collapse(genero, "Mujer cis" = c("Mujer cis", "Mujer"),
                               "Hombre cis" = c("Hombre cis")),
         genero = factor(genero, levels = c("Mujer cis", "Hombre cis",
                                             "Prefiero no responder", "No binario")))

div <- freelo21 %>% 
  select(genero) %>% 
  group_by(genero) %>% 
  summarise (n = n()) %>% 
  mutate(freq = n/sum(n)) %>% 
  arrange(-n)

# Compute the cumulative percentages (top of each rectangle)
div$ymax <- cumsum(div$freq)

# Compute the bottom of each rectangle
div$ymin <- c(0, head(div$ymax, n=-1))

# Compute label position
div$labelPosition <- (div$ymax + div$ymin) / 2

# Compute a good label
div$label <- paste0(div$genero, "\n Cant: ", div$n)

# Make the plot
ggplot(div, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=genero)) +
  geom_rect() +
  coord_polar(theta="y") + # Try to remove that to understand how the chart is built initially
  xlim(c(2, 4)) +# Try to remove that to see how to make a pie chart
  scale_fill_manual(values = c("#8624F5",  "#1FC3AA", "#FFD129","#75838F")) +
  theme_void() +
  theme(legend.position = "top",
        panel.background = element_blank(),
        plot.title.position = "plot",
        text = element_text(family = "Roboto")) +
  labs(title = "Cantidad de respuestas según género",
       subtitle = "Freelancers",
       fill = "Género", 
       caption = fuente)

En resumen, más de dos tercios de las personas que participaron de esta encuesta son mujeres cis. Algo que reflejan los datos es que en las áreas de Recursos Humanos, la diversidad de identidades de género es prácticamente nula.

kiwi21_original %>% 
    mutate(genero = fct_collapse(`Identidad de Género`, "Mujer cis" = c("Mujer cis", "Mujer", "mujer",
                                                       "Mujer heterosexual"),
                               "Hombre cis" = c("Hombre cis", "Hombre", 
                                                "Hombre hetero. Que es cis?",
                                                "Hombre heterosexual")),
         genero = factor(genero, levels = c("Mujer cis", "Hombre cis",
                                            "Gay", "Prefiero no responder", "No binario"))) %>% 
  group_by(genero) %>% 
  tally(sort = T) %>% 
  mutate(Porcentaje = n/sum(n),
         Porcentaje = percent(Porcentaje, accuracy = 0.1)) %>% 
  rename("Género" = genero, 
         "Cantidad" = n) %>% 
  kbl(caption = "Total de Participantes según\nIdentidad de Género") %>% 
  kable_styling(full_width = F, position = "center",
                bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>% 
  footnote(general = fuente, general_title = "")
Total de Participantes según Identidad de Género
Género Cantidad Porcentaje
Mujer cis 407 69.5%
Hombre cis 171 29.2%
Prefiero no responder 6 1.0%
Gay 1 0.2%
No binario 1 0.2%
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2021

Análisis de remuneraciones

Remuneraciones por país

En esta sección nos dedicaremos a comparar los sueldos entre los países. En primer lugar, hay que resaltar que los resultados no son representativos de los mercados de los países, sino que lo son de los datos recolectados.

Por otra parte, la baja cantidad de respuestas recolectadas de otros países fuera de la Argentina, nos hace imposible, hacer un análisis comparado representativo de los puestos. Sin embargo, hay algunos datos intresantes para analizar.

Primero, analicemos los sueldos de los trabajadores en relación de dependencia, de cuyos países hayamos recibido al menos 5 respuestas.

sueldos_dolar <- kiwi21 %>% 
  select(puesto, sueldo_dolar, pais, tipo_contratacion) %>% 
  filter(puesto != "Pasante", tipo_contratacion != "Pasante")

# Eliminamos los sueldos que están dentro del rango entre los percentiles 5 y 95
numericos <- profiling_num(sueldos_dolar)
poda_p05 <- numericos[1,6]
poda_p95 <- numericos[1,10]

# Dado que los percentiles 5 y 95 están en U$422 y 3300 respectivamente, 
# podamos todo lo que esté fuera de ese rango

media_pais <- sueldos_dolar %>% 
  filter(pais %in% c("Argentina", "Perú", "Bolivia", "Costa Rica", "Uruguay", 
                     "Chile", "México", "Paraguay", "Ecuador"),
         between(sueldo_dolar,poda_p05,poda_p95)) %>% 
  group_by(pais) %>% 
  summarise(sueldop = list(mean_se(sueldo_dolar))) %>% 
  unnest(cols = c(sueldop)) 
 
sueldo_dolar_pais <- kiwi21 %>% 
  select(pais, sueldo_dolar) %>% 
  filter(between(sueldo_dolar, poda_p05, poda_p95),
         pais %in% c("Argentina", "Perú", "Bolivia", "Costa Rica", "Uruguay", 
                     "Chile", "México", "Paraguay", "Ecuador"))

# Gráfico
ggplot(media_pais, aes(reorder(pais, -y), y =  y))+
  geom_col(fill = azul, alpha = 0.85) +
  geom_errorbar(aes(ymin = ymin,ymax = ymax), position = "dodge", color = "#333e47")+
  geom_point(data = sueldo_dolar_pais, aes(x = pais, y = sueldo_dolar), 
             alpha = 0.3, size = 2, color = "#75838F",
             position = position_jitter(width = 0.15))+
  geom_text(aes(label = comma(round(x=y, 0), big.mark = ".", 
                              decimal.mark = ","),
                vjust = 1.5, fontface = "bold"), 
            size = 4, color = "white",
            family = "Roboto")+
  eje_y_n +
  labs(title = "Salario promedio por país",
       subtitle = "Sueldos de RRHH en U$S",
       caption = paste0(fuente,"\nPaíses con más de 5 respuestas"),
       x = "", y = "") + 
  estiloh

A pesar de la baja cantidad de respuestas, se repite la tendencia del 2020 en donde Uruguay y Chile tienen en promedio los sueldos más altos de la región.

Análisis de sueldos por puestos en Latinoamérica

kiwi21 %>% 
  select(puesto, sueldo_dolar) %>% 
  filter(puesto != "Pasante",
         between(sueldo_dolar, poda_p05, poda_p95)) %>% 
  group_by(puesto) %>% 
  summarise(mediana_salarial = median(sueldo_dolar)) %>% 
  ggplot(aes(x = mediana_salarial, y = fct_rev(puesto))) +
  geom_col(fill = azul) +
  estilov +
  labs(title = "Mediana salarial por puesto", 
       subtitle = "Sueldos de RRHH en U$S", 
       x = "", y = "", 
       caption = fuente) +
  eje_x_n

La razón por la cual la mediana salarial de las personas en puesto de Dirección es menor a la de las personas en puestos de Gerente se explica por el tamaño de la muestra y las respuestas recibidas. En la tabla a continuación incorpora la cantidad de respuestas recibidas para cada uno de estas posiciones.

gt(kiwi21 %>% 
     select(puesto, sueldo_dolar) %>% 
     filter(puesto != "Pasante") %>% 
     group_by(puesto) %>% 
     summarise(mediana_salarial = median(sueldo_dolar), 
               cant = n())
     ) %>% 
  tab_header(title = "Mediana salarial por puestos", 
             subtitle = "Sueldos en U$D") %>% 
  tab_source_note(source_note = fuente) %>% 
   fmt_currency(columns =  "mediana_salarial", decimals = 0,
               sep_mark = ".", dec_mark = ",") %>% 
  cols_label(puesto = "Posición",
             mediana_salarial = "Mediana Sueldo",
             cant = "Respuestas") 
Mediana salarial por puestos
Sueldos en U$D
Posición Mediana Sueldo Respuestas
Director $1.591 6
Gerente $2.773 46
Jefe $1.879 54
Responsable $1.359 96
HRBP $1.221 56
Analista $977 236
Administrativo $658 25
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2021

Sueldos según el origen del capital

Si dividimos los gráficos según el Origen del Capital, podemos apreciar que en líneas generales, la mediana salarial en empresas multinaciones es mayor que en las empresas nacionales. Solamente en las posiciones de HRBP y de Gerente se aprecia una paridad salarial respecto del origen del capital de la organización.

kiwi21 %>% 
  select(origen_capital, puesto, sueldo_dolar) %>% 
  filter(puesto != "Pasante", 
         between(sueldo_dolar, poda_p05, poda_p95)) %>% 
  group_by(puesto, origen_capital) %>% 
  summarise(mediana_salarial = median(sueldo_dolar)) %>% 
  ggplot(aes(x = mediana_salarial, y = fct_rev(puesto), fill = origen_capital)) +
  geom_col() +
  geom_text(aes(label = round(x=mediana_salarial, 0), hjust = 1.2, fontface = "bold"),size = 3, color = "white") +
  scale_fill_manual(values = c(verde, azul)) +
  estilov +
  eje_x_n +
  facet_wrap(~origen_capital) +
  labs(title = "Mediana salarial por puesto según origen del capital", 
       subtitle = "Sueldos de RRHH en U$S", 
       x = "", y = "", fill = "", 
       caption = fuente) +
  theme(legend.position = "top")

Veamos este gráfico de otra manera:

slope_df <- kiwi21 %>% 
  select(puesto, sueldo_dolar, origen_capital) %>% 
  filter(between(sueldo_dolar, poda_p05, poda_p95)) %>% 
  group_by(puesto, origen_capital) %>% 
  summarise(mediana_salarial = round(median(sueldo_dolar)))

newggslopegraph(dataframe = slope_df,
                Times = origen_capital,
                Measurement = mediana_salarial,
                Grouping = puesto,
                Title = "Diferencias entre sueldos de RRHH en empresas nacionales y multinacionales",
                SubTitle = "Mediana Salarial. Sueldos en U$S",
                Caption = fuente, WiderLabels = T
                
                )

Análisis por rubro y origen del capital

Para el análisis de los rubros de la empresa, vamos a filtrar los 5 rubros que tienen más respuestas. También eliminaremos del análisis el puesto de Director porque no se encuentra presente en todos los rubros.

top_5_rubros <- kiwi21 %>% 
  select(rubro) %>% 
  group_by(rubro) %>% 
  count(sort = TRUE) %>%
  filter(rubro != "Otros", n > 30) %>% 
  pull(var = rubro)


kiwi21 %>% 
  select(rubro, origen_capital, puesto, sueldo_dolar) %>% 
  filter(puesto != "Pasante", puesto != "Director",
         between(sueldo_dolar, poda_p05, poda_p95),
         rubro %in% top_5_rubros) %>% 
  group_by(rubro, puesto, origen_capital) %>% 
  summarise(mediana_salarial = median(sueldo_dolar)) %>% 
  ggplot(aes(x = mediana_salarial, y = fct_rev(puesto), 
             fill = origen_capital)) +
  geom_col() +
  geom_text(aes(label = round(x=mediana_salarial, 0), 
                hjust = 1.2, 
                fontface = "bold"),
            size = 3, 
            color = "white") +
  scale_fill_manual(values = c(verde, azul)) +
  estilo +
  eje_x_n +
  facet_grid(rubro~origen_capital) +
  labs(title = "Mediana salarial por puesto según origen del capital", 
       subtitle = "Sueldos de RRHH en U$S", 
       x = "", y = "", fill = "", 
       caption = fuente) +
  theme(legend.position = "top")

Para ver las medianas salariales por rubros junto con el desvío estándar, pueden ver la siguiente tabla:

  kiwi21 %>% 
    select(rubro, sueldo_dolar) %>% 
    filter(between(sueldo_dolar, poda_p05, poda_p95)) %>% 
    group_by(rubro) %>% 
    summarise(mediana_salarial = round(median(sueldo_dolar)),
              desvio_salarial = round(sd(sueldo_dolar)),
              Respuestas = n()) %>% 
    arrange(-mediana_salarial) %>% 
  kbl(caption = "Mediana salarial por rubro. En U$S", 
      col.names = c("Rubro", "Mediana Salarial","Desvío", "Respuestas")) %>% 
  kable_styling(full_width = F, position = "center",
              bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>% 
  scroll_box(height = "500px")
Mediana salarial por rubro. En U$S
Rubro Mediana Salarial Desvío Respuestas
Servicios financieros seguros 1785 784 15
Transporte marítimo, puertos 1706 831 2
Petróleo y producción de gas, refinación de petróleo 1691 646 15
Tabaco 1597 266 2
Bancos, banca online 1578 242 6
Servicios de correos y de telecomunicaciones 1498 673 11
Servicios públicos (agua, gas, electricidad) 1494 345 4
Hotelería, restauración, turismo 1409 664 5
Agricultura, plantaciones, otros sectores rurales 1376 636 8
Transporte (incluyendo aviación civil, ferrocarriles por carretera) 1371 748 14
Terminales automotrices, fábricas autopartistas, y afines 1334 409 6
Medios de comunicación, cultura, gráficos 1221 391 5
Industrias químicas 1174 307 6
Servicios de salud 1165 542 32
Tecnologías de información 1163 639 93
Minería 1146 826 7
Alimentación, bebidas 1118 535 34
Servicios de consultoría 1092 618 39
Construcción 1091 905 11
Otros 1071 557 67
Servicios profesionales 1057 481 18
Función pública 1005 448 13
Comercio 939 695 31
Producción de metales básicos 905 NA 1
Industria metalúrgica, metalmecánica 890 872 12
Educación 874 697 9
Textiles, vestido, cuero, calzado 798 306 3

Sueldos por países

Si bien la mayor cantidad de respuestas la recibimos de personas trabajando en Argentina, en esta edición decidimos incluir a todos los países de los que obtuvimos al menos 10 respuestas (Argentina, Perú, Bolivia, Costa Rica, Uruguay y Chile). Si bien la cantidad de respuestas no nos permiten realizar análisis muy profundos queremos agradecer a las personas que respondieron realizando aunque más no sea un breve análisis.

Como primeros pasos, vamos a filtrar los datos correspondientes a cada país, y luego filtramos los sueldos que estén entre los percentiles 5 y 95, para eliminar valores espurios o extremos que ensucien el análisis.

También eliminamos el puesto de Director del análisis y las respuestas con Género diverso por la baja cantidad de respuestas.

Otra conversión que hicimos fue pasar los sueldos de las personas que trabajan part-time a una equivalencia full-time multiplicando por 1.5 el sueldo completado en la encuesta.

En esta instancia, también simplificamos los nombres de algunos rubros para mejorar las visualizaciones de los resultados.

Perú

kiwi21 <- kiwi21 %>% 
  filter(between(sueldo_dolar, poda_p05, poda_p95),
         puesto != "Director", puesto != "Pasante",
         genero %in% c("Mujer cis", "Hombre cis"),
         anios_experiencia < 50) %>% 
  mutate(rubro = fct_recode(rubro, "Servicios financieros" = "Servicios financieros; seguros",
                             "Transporte" = "Transporte (incluyendo aviación civil; ferrocarriles por carretera)",
                            "Ind. Automotriz y Autopartistas" = "Terminales automotrices, fábricas autopartistas, y afines",
                            "Tecnología" = "Tecnologías de Información, Sistemas, y afines",
                            "Ind. Petrolera" = "Petróleo y producción de gas; refinación de petróleo"),
         multiplicador = if_else(tipo_contratacion == "Part time", 1.5, 1),
         sueldo_ft = sueldo_bruto * multiplicador)

# Análisis Perú
rh_pe <- kiwi21 %>% 
  filter(pais == "Perú")

Análisis salarial por género y puestos

En el siguiente gráfico podemos ver la distribución de los sueldos por género. En este tipo de gráficos, llamados boxplots podemos ver:

  • Primer cuartil: La parte inferior de la caja.
  • Mediana: La línea gruesa dentro de cada rectángulo.
  • Tercer cuartil: La parte superior de la caja
  • Outliers: son los valores extremos identificados con puntos.

A este gráfico lo combinamos con un scatterplot para poder ver la cantidad de registros.

ggplot(rh_pe, aes(x = genero, y = sueldo_bruto, fill = genero)) +
  geom_boxplot(alpha = 0.6) +
  geom_point(position = position_jitter(width = 0.08), size = 2) +
  scale_fill_manual(values = genero) +
  estiloh + 
  eje_y_n +
  labs(title = "Distribución de sueldos por género",
       subtitle = "Datos de Perú - En S/",
       x = "", y = "Soles S/",
       fill = "Género",
       caption = fuente)

En el siguiente gráfico podemos ver los sueldos promedios para cada posición y género. En algunas posiciones y género sólo tenemos una sola respuesta, por eso las barras de error no aparecen.

rh_pe %>% 
  group_by(puesto, genero) %>% 
  summarise(sueldop = list(mean_se(sueldo_bruto))) %>% 
  unnest(cols = c(sueldop)) %>% 
  ggplot(aes(x = fct_rev(puesto), y = y, fill = genero)) +
  geom_col(position = "dodge") +
  geom_errorbar(aes(ymin = ymin,ymax = ymax), position = "dodge", color = "#333e47") +
  geom_text(aes(label = comma(round(x=y, 0), big.mark = ".",
                             decimal.mark = ","),
               vjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
           size = 4, color = "white",
           family = "Roboto") +
  eje_y_n +
  scale_fill_manual(values = genero) +
  labs(title = "Salario promedio por puesto y género",
       subtitle = "Datos de Perú en S/",
       caption = paste0(fuente),
       fill = "Género",
       x = "", y = "Soles S/") + 
  estiloh

Análisis por funciones

rh_pe %>% 
  group_by(funcion) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, 
             y = reorder(funcion, sueldo_promedio))) +
  geom_col(fill = azul) +
  geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
            size = 3, color = "white",
            family = "Roboto") +
  eje_x_n +
  estilov +
  labs(title = "Sueldo promedio por función",
       subtitle = "Datos de Perú en S/",
       x = "Soles S/",
       y = "",
       caption = fuente) +
  theme(plot.title.position = "plot")

Análisis por rubros

Veamos cuáles son los rubros mejor pagos en Perú

rh_pe %>% 
  group_by(rubro) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, 
             y = reorder(rubro, sueldo_promedio))) +
  geom_col(fill = azul) +
  geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
            size = 3, color = "white",
            family = "Roboto") +
  eje_x_n +
  estilov +
  labs(title = "Sueldo promedio por rubro",
       subtitle = "Datos de Perú en S/",
       x = "Soles S/",
       y = "",
       caption = fuente) +
  theme(plot.title.position = "plot")

Bolivia

# Análisis Bolivia
rh_bo <- kiwi21 %>% 
  filter(pais == "Bolivia")

Análisis salarial por género y puestos

En el siguiente gráfico podemos ver la distribución de los sueldos por género. En este tipo de gráficos, llamados boxplots podemos ver:

  • Primer cuartil: La parte inferior de la caja.
  • Mediana: La línea gruesa dentro de cada rectángulo.
  • Tercer cuartil: La parte superior de la caja
  • Outliers: son los valores extremos identificados con puntos.

A este gráfico lo combinamos con un scatterplot para poder ver la cantidad de registros.

ggplot(rh_bo, aes(x = genero, y = sueldo_bruto, fill = genero)) +
  geom_boxplot(alpha = 0.6) +
  geom_point(position = position_jitter(width = 0.08), size = 2) +
  scale_fill_manual(values = genero) +
  estiloh + 
  eje_y_n +
  labs(title = "Distribución de sueldos por género",
       subtitle = "Datos de Bolivia - En Bs.",
       x = "", y = "Boliviano Bs",
       fill = "Género",
       caption = fuente)

En el siguiente gráfico podemos ver los sueldos promedios para cada posición y género. En algunas posiciones y género sólo tenemos una sola respuesta, por eso las barras de error no aparecen.

rh_bo %>% 
  group_by(puesto, genero) %>% 
  summarise(sueldop = list(mean_se(sueldo_bruto))) %>% 
  unnest(cols = c(sueldop)) %>% 
  ggplot(aes(x = fct_rev(puesto), y = y, fill = genero)) +
  geom_col(position = "dodge") +
  geom_errorbar(aes(ymin = ymin,ymax = ymax), position = "dodge", color = "#333e47") +
  geom_text(aes(label = comma(round(x=y, 0), big.mark = ".",
                             decimal.mark = ","),
               vjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
           size = 4, color = "white",
           family = "Roboto") +
  eje_y_n +
  scale_fill_manual(values = genero) +
  labs(title = "Salario promedio por puesto y género",
       subtitle = "Datos de Bolivia Bs.",
       caption = paste0(fuente),
       fill = "Género",
       x = "", y = "Bolivianos Bs") + 
  estiloh

Análisis por funciones

rh_bo %>% 
  group_by(funcion) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, 
             y = reorder(funcion, sueldo_promedio))) +
  geom_col(fill = azul) +
  geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
            size = 3, color = "white",
            family = "Roboto") +
  eje_x_n +
  estilov +
  labs(title = "Sueldo promedio por función",
       subtitle = "Datos de Bolivia en Bs.",
       x = "Bolivia Bs.",
       y = "",
       caption = fuente) +
  theme(plot.title.position = "plot")

Análisis por rubros

Veamos cuáles son los rubros mejor pagos en Bolivia.

rh_bo %>% 
  group_by(rubro) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, 
             y = reorder(rubro, sueldo_promedio))) +
  geom_col(fill = azul) +
  geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
            size = 3, color = "white",
            family = "Roboto") +
  eje_x_n +
  estilov +
  labs(title = "Sueldo promedio por rubro",
       subtitle = "Datos de Bolivia en Bs.",
       x = "Bolivianos Bs",
       y = "",
       caption = fuente) +
  theme(plot.title.position = "plot")

Costa Rica

# Análisis Costa Rica
rh_cr <- kiwi21 %>% 
  filter(pais == "Costa Rica")

Análisis salarial por género y puestos

En el siguiente gráfico podemos ver la distribución de los sueldos por género. En este tipo de gráficos, llamados boxplots podemos ver:

  • Primer cuartil: La parte inferior de la caja.
  • Mediana: La línea gruesa dentro de cada rectángulo.
  • Tercer cuartil: La parte superior de la caja
  • Outliers: son los valores extremos identificados con puntos.

A este gráfico lo combinamos con un scatterplot para poder ver la cantidad de registros.

ggplot(rh_cr, aes(x = genero, y = sueldo_bruto, fill = genero)) +
  geom_boxplot(alpha = 0.6) +
  geom_point(position = position_jitter(width = 0.08), size = 2) +
  scale_fill_manual(values = genero) +
  estiloh + 
  eje_y_n +
  labs(title = "Distribución de sueldos por género",
       subtitle = "Datos de Costa Rica - en CRC",
       x = "", y = "Colones ¢",
       fill = "Género",
       caption = fuente)

En el siguiente gráfico podemos ver los sueldos promedios para cada posición y género. En algunas posiciones y género sólo tenemos una sola respuesta, por eso las barras de error no aparecen.

rh_cr %>% 
  group_by(puesto, genero) %>% 
  summarise(sueldop = list(mean_se(sueldo_bruto))) %>% 
  unnest(cols = c(sueldop)) %>% 
  ggplot(aes(x = fct_rev(puesto), y = y, fill = genero)) +
  geom_col(position = "dodge") +
  geom_errorbar(aes(ymin = ymin,ymax = ymax), position = "dodge", color = "#333e47") +
  geom_text(aes(label = comma(round(x=y, 0), big.mark = ".",
                             decimal.mark = ","),
               vjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
           size = 4, color = "white",
           family = "Roboto") +
  eje_y_n +
  scale_fill_manual(values = genero) +
  labs(title = "Salario promedio por puesto y género",
       subtitle = "Datos de Costa Rica en CRC",
       caption = paste0(fuente),
       fill = "Género",
       x = "", y = "Colones ¢") + 
  estiloh

Análisis por funciones

rh_cr %>% 
  group_by(funcion) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, 
             y = reorder(funcion, sueldo_promedio))) +
  geom_col(fill = azul) +
  geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
            size = 3, color = "white",
            family = "Roboto") +
  eje_x_n +
  estilov +
  labs(title = "Sueldo promedio por función",
       subtitle = "Datos de Costa Rica en CRC",
       x = "Colones ¢",
       y = "",
       caption = fuente) +
  theme(plot.title.position = "plot")

Análisis por rubros

Veamos cuáles son los rubros mejor pagos en Costa Rica.

rh_cr %>% 
  group_by(rubro) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, 
             y = reorder(rubro, sueldo_promedio))) +
  geom_col(fill = azul) +
  geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
            size = 3, color = "white",
            family = "Roboto") +
  eje_x_n +
  estilov +
  labs(title = "Sueldo promedio por rubro",
       subtitle = "Datos de Costa Rica en CRC",
       x = "Colones ¢",
       y = "",
       caption = fuente) +
  theme(plot.title.position = "plot")

Uruguay

# Análisis Uruguay
rh_uy <- kiwi21 %>% 
  filter(pais == "Uruguay")

Análisis salarial por género y puestos

En el siguiente gráfico podemos ver la distribución de los sueldos por género. En este tipo de gráficos, llamados boxplots podemos ver:

  • Primer cuartil: La parte inferior de la caja.
  • Mediana: La línea gruesa dentro de cada rectángulo.
  • Tercer cuartil: La parte superior de la caja
  • Outliers: son los valores extremos identificados con puntos.

A este gráfico lo combinamos con un scatterplot para poder ver la cantidad de registros.

ggplot(rh_uy, aes(x = genero, y = sueldo_bruto, fill = genero)) +
  geom_boxplot(alpha = 0.6) +
  geom_point(position = position_jitter(width = 0.08), size = 2) +
  scale_fill_manual(values = genero) +
  estiloh + 
  eje_y_n +
  labs(title = "Distribución de sueldos por género",
       subtitle = "Datos de Uruguay - en UYU",
       x = "", y = "Pesos $",
       fill = "Género",
       caption = fuente)

En el siguiente gráfico podemos ver los sueldos promedios para cada posición y género. En algunas posiciones y género sólo tenemos una sola respuesta, por eso las barras de error no aparecen.

rh_uy %>% 
  group_by(puesto, genero) %>% 
  summarise(sueldop = list(mean_se(sueldo_bruto))) %>% 
  unnest(cols = c(sueldop)) %>% 
  ggplot(aes(x = fct_rev(puesto), y = y, fill = genero)) +
  geom_col(position = "dodge") +
  geom_errorbar(aes(ymin = ymin,ymax = ymax), position = "dodge", color = "#333e47") +
  geom_text(aes(label = comma(round(x=y, 0), big.mark = ".",
                             decimal.mark = ","),
               vjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
           size = 4, color = "white",
           family = "Roboto") +
  eje_y_n +
  scale_fill_manual(values = genero) +
  labs(title = "Salario promedio por puesto y género",
       subtitle = "Datos de Uruguay en UYU",
       caption = paste0(fuente),
       fill = "Género",
       x = "", y = "Pesos $") + 
  estiloh

Análisis por funciones

rh_uy %>% 
  group_by(funcion) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, 
             y = reorder(funcion, sueldo_promedio))) +
  geom_col(fill = azul) +
  geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
            size = 3, color = "white",
            family = "Roboto") +
  eje_x_n +
  estilov +
  labs(title = "Sueldo promedio por función",
       subtitle = "Datos de Uruguay en UYU",
       x = "Pesos $",
       y = "",
       caption = fuente) +
  theme(plot.title.position = "plot")

Análisis por rubros

Veamos cuáles son los rubros mejor pagos en Uruguay.

rh_uy %>% 
  group_by(rubro) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, 
             y = reorder(rubro, sueldo_promedio))) +
  geom_col(fill = azul) +
  geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
            size = 3, color = "white",
            family = "Roboto") +
  eje_x_n +
  estilov +
  labs(title = "Sueldo promedio por rubro",
       subtitle = "Datos de Uruguay en UYU",
       x = "Pesos $",
       y = "",
       caption = fuente) +
  theme(plot.title.position = "plot")

Chile

# Análisis Chile
rh_cl <- kiwi21 %>% 
  filter(pais == "Chile")

Análisis salarial por género y puestos

En el siguiente gráfico podemos ver la distribución de los sueldos por género. En este tipo de gráficos, llamados boxplots podemos ver:

  • Primer cuartil: La parte inferior de la caja.
  • Mediana: La línea gruesa dentro de cada rectángulo.
  • Tercer cuartil: La parte superior de la caja
  • Outliers: son los valores extremos identificados con puntos.

A este gráfico lo combinamos con un scatterplot para poder ver la cantidad de registros.

ggplot(rh_cl, aes(x = genero, y = sueldo_bruto, fill = genero)) +
  geom_boxplot(alpha = 0.6) +
  geom_point(position = position_jitter(width = 0.08), size = 2) +
  scale_fill_manual(values = genero) +
  estiloh + 
  eje_y_n +
  labs(title = "Distribución de sueldos por género",
       subtitle = "Datos de Chile - en CLP",
       x = "", y = "Pesos $",
       fill = "Género",
       caption = fuente)

En el siguiente gráfico podemos ver los sueldos promedios para cada posición y género. En algunas posiciones y género sólo tenemos una sola respuesta, por eso las barras de error no aparecen.

rh_cl %>% 
  group_by(puesto, genero) %>% 
  summarise(sueldop = list(mean_se(sueldo_bruto))) %>% 
  unnest(cols = c(sueldop)) %>% 
  ggplot(aes(x = fct_rev(puesto), y = y, fill = genero)) +
  geom_col(position = "dodge") +
  geom_errorbar(aes(ymin = ymin,ymax = ymax), position = "dodge", color = "#333e47") +
  geom_text(aes(label = comma(round(x=y, 0), big.mark = ".",
                             decimal.mark = ","),
               vjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
           size = 4, color = "white",
           family = "Roboto") +
  eje_y_n +
  scale_fill_manual(values = genero) +
  labs(title = "Salario promedio por puesto y género",
       subtitle = "Datos de Chile en CLP",
       caption = paste0(fuente),
       fill = "Género",
       x = "", y = "Pesos $") + 
  estiloh

Análisis por funciones

rh_cl %>% 
  group_by(funcion) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, 
             y = reorder(funcion, sueldo_promedio))) +
  geom_col(fill = azul) +
  geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
            size = 3, color = "white",
            family = "Roboto") +
  eje_x_n +
  estilov +
  labs(title = "Sueldo promedio por función",
       subtitle = "Datos de Chile en CLP",
       x = "Pesos $",
       y = "",
       caption = fuente) +
  theme(plot.title.position = "plot")

Análisis por rubros

Veamos cuáles son los rubros mejor pagos en Chile.

rh_cl %>% 
  group_by(rubro) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, 
             y = reorder(rubro, sueldo_promedio))) +
  geom_col(fill = azul) +
  geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
            size = 2, color = "white",
            family = "Roboto") +
  eje_x_n +
  estilov +
  labs(title = "Sueldo promedio por rubro",
       subtitle = "Datos de Chile en CLP",
       x = "Pesos $",
       y = "",
       caption = fuente) +
  theme(plot.title.position = "plot")

Argentina

En el caso de Argentina, como contamos con un caudal de respuestas mucho más amplio, vamos a realizar un análisis más detallado.

# Análisis Argentina
rh_ar <- kiwi21 %>% 
  filter(pais == "Argentina")

Análisis salarial por género y puestos

En el siguiente gráfico podemos ver la distribución de los sueldos por género. En este tipo de gráficos, llamados boxplots podemos ver:

  • Primer cuartil: La parte inferior de la caja.
  • Mediana: La línea gruesa dentro de cada rectángulo.
  • Tercer cuartil: La parte superior de la caja
  • Outliers: son los valores extremos identificados con puntos.

A este gráfico lo combinamos con un scatterplot para poder ver la cantidad de registros.

ggplot(rh_ar, aes(x = genero, y = sueldo_bruto, fill = genero)) +
  geom_boxplot(alpha = 0.7) +
  geom_point(position = position_jitter(width = 0.08), size = 2, alpha = 0.35) +
  scale_fill_manual(values = genero) +
  estiloh + 
  eje_y_n +
  labs(title = "Distribución de sueldos por género",
       subtitle = "Datos de Argentina - en ARS",
       x = "", y = "Pesos $",
       fill = "Género",
       caption = fuente)

En el siguiente gráfico podemos ver los sueldos promedios para cada posición y género.

rh_ar %>% 
  group_by(puesto, genero) %>% 
  summarise(sueldop = list(mean_se(sueldo_bruto))) %>% 
  unnest(cols = c(sueldop)) %>% 
  ggplot(aes(x = fct_rev(puesto), y = y, fill = genero)) +
  geom_col(position = "dodge") +
  geom_errorbar(aes(ymin = ymin,ymax = ymax), position = "dodge", color = "#333e47") +
  geom_text(aes(label = comma(round(x=y, 0), big.mark = ".",
                             decimal.mark = ","),
               vjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
           size = 2, color = "white",
           family = "Roboto") +
  eje_y_n +
  scale_fill_manual(values = genero) +
  labs(title = "Salario promedio por puesto y género",
       subtitle = "Datos de Argentina en ARS",
       caption = paste0(fuente),
       fill = "Género",
       x = "", y = "Pesos $") + 
  estiloh

Es interesante, de alguna manera combinar la información de los gráficos anteriores para analizar la distribución de los sueldos para cada posición:

ggplot(rh_ar, aes(x = fct_rev(puesto), y = sueldo_ft, fill = genero)) +
  geom_boxplot() +
  scale_fill_manual(values = genero) +
  eje_y_n +
  estiloh +
  labs(title = "Distribución de sueldos por género",
       subtitle = "Datos de Argentina - en ARS",
       x = "", y = "", fill = "Género",
       caption = fuente) +
  theme(panel.grid.minor.y = element_line(color = "#AEB6BF"),
        plot.title.position = "plot")

Con estos datos podemos realizar una visualización de los gaps salariales entre hombres y mujeres.

gap_salarial <- rh_ar %>% 
  select(genero, puesto, sueldo_ft)

brecha <- gap_salarial %>% 
  group_by(genero, puesto) %>% 
  summarise(media_salarial = mean(sueldo_ft))


brecha_graf <- brecha %>% 
  pivot_wider(., names_from = genero, values_from = media_salarial) %>% 
  mutate(brecha = percent((`Hombre cis`-`Mujer cis`)/`Hombre cis`, 1),
         x = (`Hombre cis` + `Mujer cis`)/2)

ggplot(brecha_graf, 
       aes(x = `Mujer cis`, xend = `Hombre cis`, y = fct_rev(puesto), 
           group = puesto, label = brecha)) +
  geom_dumbbell(color = "#808080",
                size_x = 3, size_xend = 3,
                colour_x = colores[1],
                colour_xend = colores[2]) +
  geom_text(data = brecha_graf, 
            aes(x, puesto, label = brecha), nudge_y = .2) +
  labs(title = "Brecha salarial por puestos de RRHH",
       subtitle = "Sueldos promedios en Argentina en ARS",
       x = "",
       y = NULL, 
       caption = fuente) +
  eje_x_n +
  scale_color_manual(values = colores) +
  theme_minimal()+
  theme(plot.background = element_rect(fill = "#fbfcfc"),
        text = element_text(family = "Roboto"),
        plot.title.position = "plot")

rm(brecha, gap_salarial)

Si comparamos los resultados con la edición del 2020 (sección Sueldos Argentina -> Distribución de sueldos por puesto) podemos apreciar las siguientes diferencias.

En 2020, la mayoría de las medianas tenían valores similares en la mayoría de las posiciones de mayor jerarquía y había una paridad casi absoluta en el caso de los HRBP. En esta edición, salvo para el caso de los responsables, la mediana salarial aumentó para los hombres cis, y en el caso de las mujeres cis, la única posición jerárquica que tiene una mediana salarial más alta, es en el puesto de Responsable.

El puesto de Analista es el único caso donde la mediana salarial es más alta para las mujeres que para los varones, el gap salarial es un 5% más alto para las mujeres que para los hombres, y la distribución salarial es equitativa (aunque hay varias mujeres cis con valores altos).

Respecto al gráfico de gaps salariales, en esta edición comparada con la de 2020 podemos apreciar que:

  • Para el puesto de Gerente, la brecha salarial se mantiene igual.
  • Para el puesto de Jefe, la brecha salarial aumentó 4% (de un 12% en 2020 a un 16% en 2021).
  • Para el puesto de Responsable la brecha se redujo de un 17% en 2020, a un 6% en la edición 2021.
  • El mayor cambio en el análisis de gaps se apreció en la posición de HRBP donde el gap pasó de un 3% en 2020 a un 29% en 2021.
  • El puesto de Analista es el único en donde el gap salarial es favorable para las mujeres cis, pasando de un gap de 17% en 2020, a un 5% a favor de las mujeres.
  • Para el puesto de Administrativo el gap salarial pasó de un 8% en 2020 a un 19% en 2021.

Dado que la encuesta es anónima, es imposible trackear los cambios, promociones y aumentos en las mismas personas y empresas. Sería interesante buscar otros análisis de mercado para ver si esta tendencia se replica en otras investigaciones. Es sabido que la pandemia tuvo un impacto mayor en la carga cognitiva de las mujeres, dado que sumado a sus responsabilidades laborales, las mujeres típicamente se hacen cargo de las tareas domésticas y de la educación de los hijos e hijas, lo cual también implica un mayor acompañamiento también en las clases que fueron virtuales y de las tareas para el hogar. Para determinar el impacto de la carga cognitiva y de trabajo de las tareas domésticas sería importante hacer un análisis ad-hoc.

A continuación, y a modo de resumen, dejamos una comparación del gap salarial del 2020 vs. 2021.

Puesto <- c("Gerente", "Jefe", "Responsable", "HRBP", "Analista", "Administrativo")
`Gap 2020` <- c(0.13, 0.12, 0.17, 0.03, 0.17, 0.08)
`Gap 2021` <- c(0.13, 0.16, 0.06, 0.29, -0.05, 0.19)

gaps <- data.frame(Puesto, `Gap 2020`, `Gap 2021`)

gaps <- gaps %>% 
  mutate(Diferencia = Gap.2021 - Gap.2020)

gt(
  gaps
) %>% 
  tab_header(
    title = "Gap Salarial por puesto en RRHH en Argentina por año",
    subtitle = "Comparación Hombres cis vs Mujeres cis"
  ) %>% 
  fmt_percent(columns = c("Gap.2020", "Gap.2021", "Diferencia"),
              decimals = 0) %>% 
  cols_label(
    Gap.2020 = "Gap 2020",
    Gap.2021 = "Gap 2021"
  ) %>% 
  tab_source_note(source_note = paste0(fuente, " y 2020"))
Gap Salarial por puesto en RRHH en Argentina por año
Comparación Hombres cis vs Mujeres cis
Puesto Gap 2020 Gap 2021 Diferencia
Gerente 13% 13% 0%
Jefe 12% 16% 4%
Responsable 17% 6% −11%
HRBP 3% 29% 26%
Analista 17% −5% −22%
Administrativo 8% 19% 11%
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2021 y 2020

Análisis por funciones

rh_ar %>% 
  group_by(funcion) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, 
             y = reorder(funcion, sueldo_promedio))) +
  geom_col(fill = azul) +
  geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
            size = 3, color = "white",
            family = "Roboto") +
  eje_x_n +
  estilov +
  labs(title = "Sueldo promedio por función",
       subtitle = "Datos de Argentina en ARS",
       x = "Pesos $",
       y = "",
       caption = fuente) +
  theme(plot.title.position = "plot")

Análisis por rubros

Veamos cuáles son los rubros mejor pagos en Argentina.

rh_ar %>% 
  group_by(rubro) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, 
             y = reorder(rubro, sueldo_promedio))) +
  geom_col(fill = azul) +
  geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1.5, fontface = "bold"),
            position = position_dodge(0.9),
            size = 2, color = "white",
            family = "Roboto") +
  eje_x_n +
  estilov +
  labs(title = "Sueldo promedio por rubro",
       subtitle = "Datos de Argentina en ARS",
       x = "Pesos $",
       y = "",
       caption = fuente) +
  theme(plot.title.position = "plot")

Ahora comparemos los sueldos por rubros y géneros. Aquí podremos apreciar las diferencias entre los sueldos promedios de los hombres y mujeres en cada rubro.

rubro_ar <- rh_ar %>% 
  select(rubro, sueldo_ft) %>% 
  group_by(rubro) %>% 
  summarise(media_sueldo = mean(sueldo_ft),
            respuestas = n()) %>% 
  arrange(-respuestas)

top_rubros <- rubro_ar %>% 
  filter(rubro != "Otros", respuestas > 10) %>% 
  pull(rubro)

# Divide el largo de 'rubros' en varias líneas
rh_ar$rubro <- str_wrap(rh_ar$rubro, width = 30)


rh_ar %>% 
  filter(rubro %in% top_rubros) %>% 
  select(rubro, sueldo_ft, genero) %>% 
  group_by(rubro, genero) %>% 
  summarise(media_sueldo = mean(sueldo_ft),
            respuestas = n()) %>% 
  arrange(-respuestas) %>% 
  ggplot(aes(x = media_sueldo, y = reorder(rubro, media_sueldo), fill = genero)) +
  geom_col(position = "dodge") +
  geom_text(aes(label = comma(round(media_sueldo, 0),
                              big.mark = ".",
                              decimal.mark = ","),
                hjust = 1.4, vjust = 0.3),
            size = 3, 
            color = "white", 
            position = position_dodge(width = .9)) +
  scale_fill_manual(values = genero) +
  labs(title = "Promedio salarial por rubro y género",
       subtitle = "Datos de Argentina - en AR$",
       x = "", y = "", fill = "Género",
       caption = fuente) +
  eje_x_n +
  estilov +
  theme(axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        plot.title.position = "plot") +
  guides(fill = guide_legend(reverse=TRUE))  # Invierte el orden de los colores en la leyenda

rm(rubro_ar, top_rubros)

Por último, analicemos los sueldos de los 6 rubros con mayor cantidad de respuestas, y visualicemos las distribuciones de los sueldos por puesto y género. En este gráfico podemos ver los cuartiles delimitando las zonas sombreadas, y la mediana con el punto gris. Los puntos violetas y verdes representan a las mujeres y los hombres respectivamente en cada uno de los puestos.

rh_ar %>% 
  filter(genero != "Género Diverso",
         puesto != "Director",
         rubro %in% c("Tecnologías de información", "Servicios de consultoría", 
                      "Alimentación, bebidas", "Comercio",
                      "Servicios de salud", "Servicios profesionales"))  %>% 
  ggplot(aes(x = fct_rev(puesto), y = sueldo_bruto)) +
  geom_econodist(width = 0.5) +
  geom_point(aes(y = sueldo_bruto, color = genero), alpha = 0.3,
             position = position_jitter(width = 0.25)) +
  scale_color_manual(values = c(verde, lila)) +
  eje_y_n +
  coord_flip() +
  facet_wrap(~rubro, ncol = 2) +
  estilov +
  labs(title = "Distribución salarial por puesto y rubro",
       subtitle = "Datos de Argentina - en AR$",
       x = "", y = "", color = "Género",
       caption = fuente) +
  theme(plot.title.position = "plot")

Relaciones entre experiencia y sueldo bruto

En esta sección del análisis buscamos identificar cuáles son los factores que influyen en los ingresos (independientemente de la posición), así que empezamos a explorar los datos.

La primera pregunta que nos hicimos fue si los años de trayectoria influyen en el sueldo. Nuestra hipótesis es que a mayor cantidad de años de experiencia, mayor iba a ser el ingreso.

Lo que vamos a ver en el siguiente gráfico de dispersión, es en el eje horizontal, los años de experiencia, y en el eje vertical, el sueldo bruto expresado en pesos argentinos. Luego, vamos a graficar una recta, que nos va a indicar la fuerza de esa relación.

lm_rh <- lm(sueldo_ft ~ anios_experiencia, data = rh_ar)

lm_hr_results <- summary(lm_rh)

lm_rh_r2 <- round(lm_hr_results[["r.squared"]],3)

ggplot(rh_ar, aes(x=anios_experiencia, y = sueldo_ft)) +
  geom_point(color = "#1FC3AA", alpha = 0.4, size = 2) + 
  geom_smooth(method = "lm") +
  theme_minimal() +
  theme(text = element_text(family = "Roboto")) +
  labs(title = "Relación entre sueldo y años de experiencia",
       x = "Años de Experiencia",
       y = "Sueldo bruto (AR$)", 
       caption = fuente) +
  eje_y_n +
  geom_text(aes(x=-Inf, y=Inf, hjust=0, vjust=1, label= paste0("R2 = ", lm_rh_r2))) 

En el gráfico podemos apreciar una recta que va creciendo efectivamente: a medida que nos movemos más hacia la derecha, la recta va subiendo. Pero el \(R^2\) = 0.318 nos indica cuánto explica los años de experiencia sobre el sueldo bruto, o dicho de otra manera, en qué medida influye la variable x (años de experiencia), sobre la variable y (sueldo bruto). Una definición más precisa de este valor conocido como Coeficiente de Determinación es la proporción de la varianza total de la variable explicada por la regresión.

Este valor puede estar entre 0 y 1, mientras más cerca de 0 está menor es la relación, y mientras más cerca de 1 esté el resultado, indica que la regresión explica la variabilidad de la variable de respuesta. Es por eso que este \(R^2\) = 0.318 nos indica que los años de experiencia explican un 31.8% de la variabilidad de los sueldos en RRHH.

Relación entre años de experiencia y sueldo bruto por puesto.

Dado que en el gráfico anterior tenemos mezclados los sueldos de administrativos, analistas, jefes y gerentes, decidimos analizar la relación entre los años de experiencia y el sueldo bruto por cada uno de los puestos por separado.

mi.formula <- y ~ x

ggplot(rh_ar, aes(x=anios_experiencia, y = sueldo_ft)) +
  geom_point(color = "#1FC3AA", alpha = 0.4, size = 2) + 
  geom_smooth(method = "lm", formula = mi.formula, se = FALSE) +
  theme_minimal() +
  theme(text = element_text(family = "Roboto")) +
  labs(title = "Relación entre sueldo y años de experiencia",
       x = "Años de Experiencia",
       y = "", 
       caption = fuente) +
  eje_y_n +
  stat_poly_eq(formula = mi.formula, 
               aes(label = paste(..rr.label.., sep = "~~~")), 
               parse = TRUE) +
  facet_wrap(~puesto)

Como podemos apreciar en los \(R^2\) de cada gráfico en el único puesto donde encontramos una fuerte relación entre los años de experiencia y el sueldo bruto es en los HRBP. En el resto de los puestos los años de trayectoria influyen muy poco en los sueldos de cada uno de los puestos.

Ahora bien, la pregunta es, ¿cuál es la variable que más influye en el sueldo en Recursos Humanos?. Tristemente, la respuesta no sorprende.

ggplot(rh_ar, aes(x = genero, y = sueldo_ft, fill = genero)) +
  geom_boxplot() +
  eje_y_n +
  scale_fill_manual(values = c(verde, lila)) +
  estiloh +
  labs(title = "Distribución salarial por género",
       x = "", y = "",
       fill = "Género", 
       caption = fuente)

Educación

En esta sección queremos indagar si hay relación entre la formación y la remuneración, y si impacta también el tipo de universidad, pública o privada, en la remuneración y posición. Primero veamos entre los distintos países como se distribuye la muestra entre profesionales provenientes de universidades públicas y privadas.

Dado que tenemos relativamente pocas respuestas de otros países que no sean Argentina, no podemos sacar ninguna conclusión seria, sólo mencionar que en Argentina, hay una virtual paridad entre los estudiantes y graduados de universidades públicas y privadas. Posteriormente analizaremos la situación por regiones dentro del país.

Las proporciones de respuestas según al tipo de universidad que asistieron los participantes de la encuesta es la siguiente:

kiwi21 %>% 
  select(pais, tipo_universidad) %>% 
  ggplot(aes(y = fct_rev(pais), 
             fill = tipo_universidad)) +
           geom_bar(position = "fill") + 
  scale_fill_manual(values = c(gris, verde, azul)) +
  labs(title = "Distribución de respuestas por tipo de universidad por país",
       caption = fuente, 
       x = "", y = "") +
  estilo +
  theme(legend.position = "none")


educ <- kiwi21 %>% 
  select(tipo_universidad) %>%  
  group_by(tipo_universidad) %>% 
  summarise (n = n()) %>% 
  mutate(freq = n/sum(n)) %>% 
  arrange(-n)

# Compute the cumulative percentages (top of each rectangle)
educ$ymax <- cumsum(educ$freq)

# Compute the bottom of each rectangle
educ$ymin <- c(0, head(educ$ymax, n=-1))

# Compute label position
educ$labelPosition <- (educ$ymax + educ$ymin) / 2

# Compute a good label
educ$label <- paste0(educ$tipo_universidad, "\n Cant: ", educ$n)

# Make the plot
ggplot(educ, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=tipo_universidad)) +
  geom_rect() +
  coord_polar(theta="y") + # Try to remove that to understand how the chart is built initially
  xlim(c(2, 4)) +# Try to remove that to see how to make a pie chart
  scale_fill_manual(values = c(gris, verde, azul)) +
  theme_void() +
  theme(legend.position = "right",
        panel.background = element_blank(),
        text = element_text(family = "Roboto")) +
  labs(title = "Tipo de Universidad",
       fill = "Tipo de Universidad", 
       caption = fuente) +
  theme(legend.position = "left")

Las principales carreras de las personas que respondieron son:

carreras <- kiwi21 %>% 
  select(nivel_formacion, carrera_grado, tipo_universidad, trabajo, 
         sueldo_bruto, puesto, funcion, pais, genero) %>% 
  mutate(carrera_grado = factor(carrera_grado))


carreras <- carreras %>% 
  mutate(carrera_grado = fct_collapse(carrera_grado, 
                                      "Comunicación Social" = c("Ciencias de la Comunicación", "Comunicación", "Comunicación social",
                                                                "Comunicación Social",
                                                                "Soy Licenciada en Ciencias Comunicación y Diplomada en RRHH")), 
         carrera_grado = fct_collapse(carrera_grado, "Ingenierías" = c("Ingeniera Comercial", "INGENIERA COMERCIAL",
                                                                       "Ing. Gestión Empresarial", "Ingeniería",
                                                                       "Ingenieria comercial", "Ingeniería Comercial",
                                                                       "Ingeniería de Sistemas", "Ingeniería Industrial")),
         carrera_grado = fct_collapse(carrera_grado, "Relaciones Públicas" = c("Lic. en Relacione Publicas",
                                                                               "Lic. en Relaciones Públicas",
                                                                               "Relaciones Públicas e Institucionales")),
         carrera_grado = fct_collapse(carrera_grado, 
                                      "Psicología" = c("Psicología", "Psicología Social")),
         carrera_grado = fct_lump(carrera_grado, 
                                  prop = 0.02, 
                                  other_level = "Otras"),
         carrera_grado = factor(carrera_grado,
                               levels = c("RRHH / RRLL / RRTT", "Psicología", "Administración de Empresas", 
                                         "Contador Público", "Ingenierías","Comunicación Social", "Otras")))



ggplot(carreras, aes(y = fct_rev(carrera_grado))) + 
  geom_bar(position = "dodge", fill = azul) +
  theme(plot.title.position = "plot") + 
  labs(x="",y="") +
  estilov +
  labs(title = "Principales carreras estudiadas",
       subtitle = "Trabajadores en relación de dependencia",
       caption = fuente)

Dada la cantidad de respuestas por país, el análisis que haremos desde aquí en adelante sólo será para Argentina.

Análisis de educación y puestos para Argentina

Luego, podemos analizar en qué tipo de universidad estudiaron las personas que respondieron la encuesta, según el puesto actual que ocupan.

recorte_educacion <- rh_ar %>%
  filter(pais == "Argentina") %>% 
  select(nivel_formacion, carrera_grado,
         tipo_universidad, trabajo, sueldo_bruto, puesto, funcion, pais, genero)

ggplot(recorte_educacion, (aes(x = puesto, fill = tipo_universidad))) + #Tipo de universidad y cargo
  geom_bar(position = "dodge") +
  theme(plot.title.position = "plot") + 
  labs(x="",y="") +
    estilov +
  scale_fill_manual(values = c(gris, verde, azul)) +
  coord_flip() +
  labs(title = "Cantidad de respuestas según puesto y universidad",
       subtitle = "Sólo respuestas de Argentina",
       x = "", fill = "Tipo de Universidad",
       caption = fuente) +
    guides(fill = guide_legend(reverse=TRUE))  # Invierte el orden de los colores en la leyenda

Reiteremos el análisis pero únicamente para las carreras relacionadas con Recursos Humanos y Relaciones del Trabajo.

recorte_educacion %>%
  filter(carrera_grado == "RRHH / RRLL / RRTT") %>% 
  ggplot(aes(x = puesto, fill = tipo_universidad)) + #Tipo de universidad y cargo
  geom_bar(position = "dodge") +
  theme(plot.title.position = "plot") + 
  labs(x="",y="") +
    estilov +
  scale_fill_manual(values = c(gris, verde, azul)) +
  coord_flip() +
  labs(title = "Cantidad de respuestas según puesto y universidad",
       subtitle = "Sólo respuestas de Argentina - Carreras de RH",
       x = "", fill = "Tipo de Universidad",
       caption = fuente) +
    guides(fill = guide_legend(reverse=TRUE))  # Invierte el orden de los colores en la leyenda

Podemos apreciar que a partir de los puestos de jefatura, hay mayor presencia de graduados provenientes de universidades privadas.

En Argentina, podemos ver la siguiente distribución por género y nivel educativo.

ne_salario <- recorte_educacion 

# Elimina recorte_educacion
rm(recorte_educacion)

# Agrupa categorías de educación
ne_salario <- ne_salario %>% 
    mutate(nivel_formacion = fct_collapse(nivel_formacion,
                                        "Secundario completo" = c("Secundario completo", "Terciario en curso",
                                                                  "Terciario abandonado", "Universitario abandonado"),
                                        "Universitario completo" = c("Universitario completo", "Maestría abandonada", 
                                                                     "Diplomado de posgrado abandonado")),
         nivel_formacion = fct_recode(nivel_formacion, "Diplomado completo" = "Diplomado de posgrado completo",
                                      "Diplomado en curso" = "Diplomado de posgrado en curso")) 

ne_salario %>% 
  select(pais, nivel_formacion, genero, puesto) %>%
  filter(genero %in% c("Mujer cis", "Hombre cis")) %>%
  mutate(nivel_formacion = factor(nivel_formacion,
                                  levels = c("Secundario completo", "Terciario completo",
                                             "Universitario en curso", "Universitario completo",
                                             "Diplomado en curso","Diplomado completo",
                                             "Maestría en curso","Maestría completa"))) %>% 
  group_by(nivel_formacion) %>% 
  ggplot(aes (y= nivel_formacion, fill = genero)) + 
  geom_bar(position = "fill") +
  labs(x="",y="") +
  scale_fill_manual(values = c(verde, lila)) +
  estilo +
  theme(legend.position = "top",
        plot.title.position = "plot") +
  labs(title = "Máximo nivel educativo alcanzado por género",
       subtitle = "Distribución por frecuencias absolutas",
       caption = fuente, 
       fill = "Género")

En términos absolutos, las mujeres graduadas representan cerca del 75% de la muestra. Analicemos estos datos en términos relativos. Prácticamente el patrón de nivel educativo entre hombres y mujeres es idéntico.

De acuerdo a la muestra recolectada, las mujeres se forman en mayor proporción que los hombres cis.

ne_fem <- ne_salario %>% 
  filter(genero == "Mujer cis") %>% 
  group_by(genero, nivel_formacion) %>% 
  mutate(nivel_formacion = factor(nivel_formacion,
                                  levels = c("Secundario completo", "Terciario completo",
                                             "Universitario en curso", "Universitario completo",
                                             "Diplomado en curso","Diplomado completo",
                                             "Maestría en curso","Maestría completa"))) %>% 
  group_by(nivel_formacion) %>% 
  summarise(n = n()) %>% 
  mutate(frecuencia = round(n/sum(n),2),
         genero = "Mujer cis") 

ne_mas <- ne_salario %>% 
  filter(genero == "Hombre cis") %>% 
  group_by(genero, nivel_formacion) %>% 
  mutate(nivel_formacion = factor(nivel_formacion,
                                  levels = c("Secundario completo", "Terciario completo",
                                             "Universitario en curso", "Universitario completo",
                                             "Diplomado en curso","Diplomado completo",
                                             "Maestría en curso","Maestría completa"))) %>% 
  group_by(nivel_formacion) %>% 
  summarise(n = n()) %>% 
  mutate(frecuencia = round(n/sum(n),2),
         genero = "Hombre cis") 

ne_total <- rbind(ne_fem, ne_mas)

ggplot(ne_total, aes(x = nivel_formacion, y = frecuencia, fill = genero)) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 90), 
        legend.position = "none") + 
  labs(x="",y="") +
  scale_fill_manual(values = colores) +
  facet_wrap(~genero, ncol = 2) +
  estiloh +
  labs(title = "Proporción de nivel educativo máximo por género",
       x = "", y = "Proporción", 
       caption = fuente)

Ahora veamos como se distribuyen los puestos según el género y el nivel educativo.

ne_salario %>% 
  select(pais, nivel_formacion, genero, puesto) %>%
  filter(genero %in% c("Mujer cis", "Hombre cis"),
         puesto != "Pasante", puesto != "Director") %>%
  mutate(nivel_formacion = factor(nivel_formacion,
                                  levels = c("Secundario completo", "Terciario completo",
                                             "Universitario en curso", "Universitario completo",
                                             "Diplomado en curso","Diplomado completo", 
                                             "Maestría en curso","Maestría completa")),
         puesto = factor(puesto, 
                         levels = c("Director", "Gerente", "Jefe", "Responsable", "HRBP",
                                    "Analista", "Administrativo"))) %>% 
  group_by(nivel_formacion) %>% 
  ggplot(aes (y= nivel_formacion, fill = genero)) + 
  geom_bar(position = "fill") +
  labs(x="",y="") +
  scale_fill_manual(values = c(verde, lila)) +
  estilo +
  theme(legend.position = "top",
        plot.title.position = "plot") +
  labs(title = "Nivel educativo por puesto y género",
       subtitle = "Distribución por frecuencias absolutas",
       caption = fuente, 
       fill = "Género") +
  facet_wrap(~puesto, ncol = 3)

Algunas datos llamativos del gráfico anterior:

  • En las posiciones de Gerente y de Jefe hay paridad entre los géneros respecto de la formación en posgrados completos.
  • En posiciones de menor jerarquía se observan mujeres cis con posgrados completos o en curso en mayor proporción que hombres cis.
  • En el caso del puesto de Analista encontramos mujeres con posgrados completos, incluso con maestrías y diplomados completos. Hay pocas observaciones de varones cis con Diplomado completo en esta posición. Lo cual nos da la pauta que contar con un título de posgrado en el caso de los hombres ayuda a posicionarse en posiciones de mayor jerarquía en mayor proporción que las mujeres.

Analicemos las proporciones de hombres y de mujeres en puesto de liderazgo.

div <- rh_ar %>%
  filter(pais == "Argentina") %>% 
select(genero) %>% 
  mutate(genero = factor(genero, 
                         levels = c("Mujer cis", "Hombre cis"))) %>% 
  group_by(genero) %>% 
  summarise (n = n()) %>% 
  mutate(freq = n/sum(n)) %>% 
  arrange(-n)

lideres <- rh_ar %>% 
  filter(pais == "Argentina") %>% 
 select(genero, puesto) 

# Propoción de líderes hombres y mujeres
lideres_genero <- lideres %>% 
  filter(genero %in% c("Mujer cis", "Hombre cis")) %>% 
  group_by(genero) %>%
  mutate(gente_a_cargo = if_else(puesto %in% c("Responsable", "Jefe", "Gerente", 
                                               "Supervisor", "Director"),1,0)) %>%
  summarise(lider = sum(gente_a_cargo)) %>% 
  left_join(div) %>% 
  select(genero, lider, n) %>% 
  mutate(proporcion = percent(lider/n))

# Test de hipótesis para validar diferencias de resultados
# Hay que verificar si la proporción de líderes hombres es mayor que la proporción de líderes mujeres
# Creo un dataframe para analizar proporciones de hombres y de mujeres en puestos de liderazgo y de no-liderazgo
test_lider <- lideres_genero %>% 
  mutate(no_lider = n - lider) %>%        # Columna de no líderes
  select(genero, lider, no_lider) %>%     # selecciono columnas de interés
  pivot_longer(cols = c(lider, no_lider), # Hago un dataset largo para analizar después
               names_to = "es_lider", values_to = "conteo")

# Del total de respuestas me interesa sólo ver cuáles son los hombres con puesto de liderazgo
test_lider$cat <- c(0,0,1,0)

# Extraigo el mu para decidir si la diferencia es significativa y pasarlo a la fórmula del test.
prop_mujer_lid <- pull(lideres_genero[1,2]/lideres_genero[1,3])

# Realizo el test de hipótesis.
# H0 = Las proporciones de líderes hombres y mujeres son iguales
# H1 = La proporción de hombres líderes es mayor que la proporción de mujeres líderes.
resultados_test <- broom::tidy(t.test(test_lider$cat, mu = prop_mujer_lid, alternative = "greater"))

valor_test <- if(resultados_test[1,3] > 0.05) {
  print("la diferencia es estadísticamente significativa, y la proporción de hombres en puestos de liderazgo es mayor que el de las mujeres")
  } else {
    print("la diferencia no es estadísticamente significativa, y la proporción de hombres no es estadísticamente mayor que el de las mujeres en puestos de liderazgo")
  }
# Gráfico
lideres_genero %>% 
  mutate(porc_lider = lider/n, 
         porc_no_lider = 1 - porc_lider) %>% 
  pivot_longer(cols = c(porc_lider, porc_no_lider),
               names_to = "es_lider", 
               values_to = "valores") %>% 
  mutate(es_lider = factor(es_lider, 
                           levels = c("porc_no_lider", "porc_lider"), 
                           labels = c("No Líder", "Líder"))) %>% 
  ggplot(aes(x= genero, y = valores, fill = es_lider))+
  geom_col(position = "fill")+
  estilo +
  scale_fill_manual(values = c("#75838F", "#344D7E")) +
  labs(title = "Proporción de Líderes según género",
       x = "", y = "", fill = "", 
       caption = fuente)

De acuerdo a las respuestas recolectadas 2 de cada 3 participantes son mujeres.

Para los puestos de liderazgo consideramos las personas en los puestos de Director, Gerente, Jefe, y Responsable.

Del total de mujeres, 109 respuestas, 52 ocupan un puesto de liderazgo (48%).

Del total de hombres, 274 respuestas, 88 ocupan un puesto de liderazgo (32%).

Con un p-value igual a 0.785 podemos afirmar que la diferencia es estadísticamente significativa, y la proporción de hombres en puestos de liderazgo es mayor que el de las mujeres.

A pesar de que en Recursos Humanos en Argentina, las mujeres cis representan la mayor cantidad de empleados bajo relación de dependencia, y además se forman en mayor proporción que los varones en posgrados, proporcionalmente en comparación con los hombres cis, acceden a menos posiciones de liderazgo.

Análisis de sueldos y educación en Argentina

En esta sección analizaremos los sueldos en comparación con los distintos niveles educativos.

A diferencia de otras secciones, en este caso compararemos la media salarial para poder observar los desvíos estándar en los análisis. En primer lugar analicemos cuál es el sueldo promedio de acuerdo a los distintos niveles educativos.

Primero veamos cuál es el sueldo promedio en pesos argentinos, según el nivel educativo.

estudios <- rh_ar %>% 
  filter(pais == "Argentina") %>% 
  select(genero, nivel_formacion, sueldo_bruto)
    
  
est_ar  <- profiling_num(estudios)
es_p05 <- est_ar[1,6]
es_p95 <- est_ar[1,10]

rm(est_ar)

rh_ar %>% 
  filter(pais == "Argentina", 
         between(sueldo_bruto, es_p05, es_p95)) %>% 
      mutate(nivel_formacion = fct_collapse(nivel_formacion,
                                        "Secundario completo" = c("Secundario completo", "Terciario en curso",
                                                                  "Terciario abandonado", "Universitario abandonado"),
                                        "Universitario completo" = c("Universitario completo", "Maestría abandonada", 
                                                                     "Diplomado de posgrado abandonado")),
         nivel_formacion = fct_recode(nivel_formacion, "Diplomado completo" = "Diplomado de posgrado completo",
                                      "Diplomado en curso" = "Diplomado de posgrado en curso")) %>% 
    mutate(nivel_formacion = factor(nivel_formacion,
                                  levels = c("Secundario completo", "Terciario completo",
                                             "Universitario en curso", "Universitario completo",
                                             "Diplomado en curso", "Diplomado completo",
                                             "Maestría en curso","Maestría completa"))) %>% 
  group_by(nivel_formacion) %>% 
  summarise(sueldo_promedio = mean(sueldo_bruto)) %>% 
  ggplot(aes(x = sueldo_promedio, y = nivel_formacion))+
  geom_col(fill = azul)+
geom_text(aes(label = comma(round(sueldo_promedio, 0), 
                              big.mark = ".",
                             decimal.mark = ","),
            hjust = 1., fontface = "bold"),
            position = position_dodge(0.9),
            size = 3, color = "white",
            family = "Roboto") +
  estilov +
  eje_x_n +
  labs(title = "Sueldo promedio por nivel de formación",
       subtitle = "En AR$",
       x="", y="", caption = fuente)

Ahora veamos qué pasa si incluimos en el análisis el género para analizar los sueldos promedios y sus desvíos estándar.

rh_ar %>% 
  filter(pais == "Argentina", 
         between(sueldo_bruto, es_p05, es_p95)) %>% 
      mutate(nivel_formacion = fct_collapse(nivel_formacion,
                                        "Secundario completo" = c("Secundario completo", "Terciario en curso",
                                                                  "Terciario abandonado", "Universitario abandonado"),
                                        "Universitario completo" = c("Universitario completo", "Maestría abandonada", 
                                                                     "Diplomado de posgrado abandonado")),
         nivel_formacion = fct_recode(nivel_formacion, "Diplomado completo" = "Diplomado de posgrado completo",
                                      "Diplomado en curso" = "Diplomado de posgrado en curso")) %>% 
    mutate(nivel_formacion = factor(nivel_formacion,
                                  levels = c("Secundario completo", "Terciario completo",
                                             "Universitario en curso", "Universitario completo",
                                             "Diplomado en curso", "Diplomado completo",
                                             "Maestría en curso","Maestría completa"))) %>% 
  group_by(nivel_formacion, genero) %>% 
  summarise(salarios = list(mean_se(sueldo_bruto))) %>% 
  unnest(salarios) %>% 
  ggplot(aes(x = nivel_formacion, y = y, fill = genero)) +
  geom_col(position = "dodge")+
  geom_errorbar(aes(ymin = ymin,ymax = ymax), position = "dodge")+
  coord_flip()+
  theme(legend.position = "top",
        plot.title.position = "plot") +
  eje_y_n +
  estilov +
  scale_fill_manual(values = c(verde, lila)) +
  labs(title = "Sueldo promedio y desvío estándard por nivel de formación y género",
       subtitle = "En AR$", 
       x = "", y = "", 
       caption = fuente, 
       fill = "Género")

Freelancers

En este relevamiento participan colegas que trabajan en relación de dependencia y también de manera freelance. Este es el análisis desarrollado en base a las respuestas de las personas que trabajan de manera independiente o en sus propias empresas.

Respuestas por país

En el caso de las personas freelance, la mayoría de las respuestas obtenidas fueron de Argentina. Por eso reiteramos, que los resultados no son representativos de los países.

Cantidad de respuestas por país
Freelance
País Cuenta
Argentina 40
Perú 3
Bolivia 2
Chile 1
Colombia 1
Estados Unidos 1
México 1
Uruguay 1
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2021

Respuestas por Género

La participación según el género de las personas freelance, es la siguiente:

Podemos observar que la mayoría de las respuestas fueron de Mujeres cis, manteniendo la misma tendencia que las personas en relación de dependencia.

Género Cuenta
Mujer cis 34
Hombre cis 14

Respuestas por Educación

En esta sección queremos indagar si hay relación entre la formación y la exportacion de los servicios, y si impacta también el tipo de universidad, pública o privada, en dichas prestaciónes. Primero veamos como se distribuye la muestra entre profesionales provenientes de universidades públicas y privadas de los diferentes paises:

Limitandonos al país con mayor cantidad de respuestas, Argentina, en los siguientes graficos podemos observar que la distribución por tipo de Universidad es muy pareja , quedando un valor minimo y poco representativo para quienen no fueron a la Universidad:

Nos interesaba indagar cuál era el nivel de formación de los encuestados.

En la siguiente tabla podemos ver que la mayoría tiene estudios Universitarios completos:

Nivel de Formación Cuenta
Universitario completo 16
Diplomado de posgrado completo 9
Maestría completa 8
Universitario en curso 8
Diplomado de posgrado en curso 4
Terciario completo 4
Terciario abandonado 1

Cuando analizamos educación, nos resultó interesante analizar la distribución por género y nivel educativo.

En el siguiente gráfico podemos observar que las mujeres tienen mayor nivel de formación que los hombres:

Veamos los mismos resultados, en terminos relativos:

Respecto a las carreras, vemos que la tendencia de las mismas se corresponden con los resultados obtenidos en las personas en relación de dependencia:

Respuestas por Condición fiscal

La condidición fiscal de los encuestados la podemos observar en la siguiente tabla:

Registro Fiscal Cuenta
Monotributista 36
Contractor 7
Otros 3
Responsable inscripto 3
SA 1

Respuestas por Exportación de Servicio

como vemos a continuación, la mayoría no exporta sus servicios:

Focalizandonos entre quienes exportan, podemos ver cuál es el servicio prestado:

En relación a los medios de pago utilizados por quienes exportan, sus respuestas fueron las siguientes:

Medios de Pago Exterior Cuenta
Payoneer 12
Transferencia 12
PayPal 7
Bitcoin 1
Prex 1
Western Union 1

Respuestas por Antigüedad

Respecto a los años de experiencia como freelance, podemos observar que la mayoría tiene menos de dos años.

Un interrogante que nos surge en si la inserción en esta modalidad fue una decisión de carrera voluntaria o impulsada por las consecuencias de la pandemia. Carecemos de elementos para responder esa pregunta, por eso nos limitamos a presentar las respuestas obtenidas:

Años de Experiencia Cuenta
Menos de 2 años 26
Entre 2 y 5 años 18
Entre 5 y 10 años 4
Más de 10 años 2

Respuestas por Búsquedas

Nos interesa saber cuantos se dedican a realizar trabajos de selección de talentos.

Podemos observar que un 66% de las personas encuestadas en esta categoria se dedican a la tarea de búsqueda.

Serv. Búsqueda n freq
Si 33 0.66
No 17 0.34

Sabiendo el crecimiento y auge de las búsquedas en el sector de IT, veamos cuál es la participación de las mismas entre las personas que hacen recruiting.

Como se observa en el siguiente gráfico, la mayoría de las búsquedas se concentran que en el sector IT.

Respuesta por garantía de trabajo

Las garantías de reposición de vacantes se refieren a la protección que se brinda a cada cliente en el caso de que la persona contratada se marche de la empresa.

Veamos entre los que prestan el servicio de recruiting, quienes ofrecen garantía de permanencia del candidato.

En la siguiente tabla podemos observar que los plazos de garantía suelen ir desde un mes hasta los tres meses. Pero un número importante, no ofrece garantia por el servicio contratado.

Respuestas por Base de Coeficiente

Otro punto para destacar es el precio del servicio de quienes hacen recruiting.

Podemos ver que la gran mayoría cobra por dicho servicio, un porcentaje de remuneración mensual del ingresante, dejando para muy pocos casos el ingreso anual del mismo.

Una pregunta abierta que nos queda, es cuáles son las posiciones mejores pagas para los recruiters. Sin embargo, dicho análisis escapa de los objetivos de la presente encuesta.

Remuneración del Ingresante Cuenta
Mensual 30
Anual 3

La mayoría cobra un porcentaje que va del 20% al 30% de las remuneraciones mensuales de los ingresantes, como podemos ver en el siguiente cuadro:

Porcentaje Cuenta
20% 5
30% 4
40% 2
50% 2
70% 1
80% 1
100% 2
LS0tDQp0aXRsZTogIjLCsCBFbmN1ZXN0YSBLSVdJIGRlIFN1ZWxkb3MgZGUgUlJISCBwYXJhIExhdGFtIDIwMjEiDQphdXRob3I6ICJSNEhSIENsdWIgZGUgUiBwYXJhIFJSSEgiDQpkYXRlOiAiMjkvMTEvMjAyMSINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdGhlbWU6IGNvc21vDQogICAgaGlnaGxpZ2h0OiBoYWRkb2NrDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgZmlnLnJldGluYSA9IDMsIG91dC53aWR0aCA9ICI4MCUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIikNCmBgYA0KDQojIEludHJvZHVjY2nDs24NCg0KW1I0SFIgQ2x1YiBkZSBSIHBhcmEgUlJISF0oaHR0cHM6Ly9yNGhyLmNsdWIpIGVzIHVuYSBjb211bmlkYWQgZGUgYXByZW5kaXphamUgZGUgcHJvZ3JhbWFjacOzbiBkZSBSIHBhcmEgcHJvZmVzaW9uYWxlcyB5IGVzdHVkaWFudGVzIHF1ZSB0cmFiYWplbiBvIHF1aWVyYW4gdHJhYmFqYXIgZW4gUlJISC4NCg0KU29tb3MgdW5hIGNvbXVuaWRhZCBxdWUgdXNhIG1heW9ybWVudGUgZGF0b3MgZGUgZWplbXBsbyByZWxhY2lvbmFkb3MgY29uIFJSSEgsIHkgcXVlIGdlbmVyYSBjb250ZW5pZG8gZW4gY2FzdGVsbGFubyBwYXJhIGVsaW1pbmFyIGxhcyBiYXJyZXJhcyBlbiBlbCBhcHJlbmRpemFqZSB5IGZhY2lsaXRhciBxdWUgbcOhcyBwZXJzb25hcyBhZG9wdGVuIGxhcyBoZXJyYW1pZW50YXMgZGUgYW7DoWxpc2lzIGRlIGRhdG9zIGVuIHN1cyB0cmFiYWpvcy4NCg0KUGFyYSBzYWJlciBtw6FzIGRlIG5vc290cm9zIHRlIGludml0YW1vcyBhIGxlZXIgW2VzdGUgcG9zdF0oaHR0cHM6Ly9yNGhyLmNsdWIvMjAyMC8wOS8yMy9lbC1jbHViLWRlLXItcGFyYS1ycmhoLykuDQoNClRhbWJpw6luIHBvZMOpcyB2ZXIgdG9kbyBlbCBjb250ZW5pZG8gcXVlIGdlbmVyYW1vcyBlbiBsb3Mgc2lndWllbnRlcyBsaW5rczoNCg0KYHIgaWNvbnM6OmZvbnRhd2Vzb21lKCJnb29nbGUtZHJpdmUiKWAgW0dvb2dsZSBEcml2ZV0oaHR0cHM6Ly9kcml2ZS5nb29nbGUuY29tL2RyaXZlL2ZvbGRlcnMvMVFjazN6X3Q2WExSWGIydmJOLTAwOTMxRGdkSloweXNlP3VzcD1zaGFyaW5nKQ0KDQpgciBpY29uczo6Zm9udGF3ZXNvbWUoInlvdXR1YmUiKWAgW1lvdVR1YmVdKGh0dHBzOi8veW91dHViZS5jb20vcGxheWxpc3Q/bGlzdD1QTFp1Vnl0VUpyeFFsY3F1NmwtUDNvdTR2VjJtUkpVMkthKQ0KDQpgciBpY29uczo6Zm9udGF3ZXNvbWUoImdpdGh1YiIpYCBbR2l0aHViXShodHRwczovL2dpdGh1Yi5jb20vcjRoci8pDQoNCmByIGljb25zOjpmb250YXdlc29tZSgibGluayIpYCBUYW1iacOpbiB0ZSBpbnZpdGFtb3MgYSBzZWd1aXJub3MgZW4gdG9kYXMgW251ZXN0cmFzIHJlZGVzIHNvY2lhbGVzXShodHRwczovL2xpbmt0ci5lZS9yNGhyY2x1YikuDQoNClB1ZWRlbiBhY2NlZGVyIGEgbG9zIGRhdG9zIGNydWRvcyBkZXNkZSBbZXN0ZSBsaW5rXShodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xTERkWGxJd3Jjc3l1eXdiY1M0Z2RjLTFwNndCWGZFZkwyWTZzTkJqLTRHTS9lZGl0P3VzcD1zaGFyaW5nKS4NCg0KYGBge3IgcHJlcHJvY2Vzb30NCiMgQ2FyZ2EgZGUgbGlicmVyw61hcyANCiMgSW5zdGFsYXIgcGFjbWFuIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQoNCnBhY21hbjo6cF9sb2FkKHRpZHl2ZXJzZSwgZnVuTW9kZWxpbmcsIGd0LCBnb29nbGVzaGVldHM0LGd0LCBDR1BmdW5jdGlvbnMsDQogICAgICAgICAgICAgICBleHRyYWZvbnQsIHNjYWxlcywgZ2dhbHQsIGthYmxlRXh0cmEsIHdvcmRjbG91ZCwgbmV0d29ya0QzLA0KICAgICAgICAgICAgICAgZGF0YS50YWJsZSwgZ2dlY29ub2Rpc3QsIGdncG1pc2MpDQoNCg0KDQojIENhcmdhIGRlIERhdG9zIC0tLS0NCiMgRGF0b3MgLS0tLS0tLS0NCg0KIyMgMjAyMSAtLS0tDQoNCiMgRW5jdWVzdGENCmtpd2kyMSA8LSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3I0aHIva2l3aTIwMjEvbWFpbi9kYXRhL3JoXzIwMjEuY3N2IiwNCiAgICAgICAgICAgICAgICAgICBzZXAgPSAiOyIsDQogICAgICAgICAgICAgICAgICAgZW5jb2RpbmcgPSAiVVRGLTgiKSANCg0Ka2l3aTIwIDwtIHJlYWQuY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcjRoci9raXdpMjAyMS9tYWluL2RhdGEvcmhfMjAyMC5jc3YiLCANCiAgICAgICAgICAgICAgICAgICBzZXAgPSAiOyIsDQogICAgICAgICAgICAgICAgICAgZW5jb2RpbmcgPSAiVVRGLTgiKQ0KDQpmcmVlbG8yMSA8LSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3I0aHIva2l3aTIwMjEvbWFpbi9kYXRhL2ZyZWVsYW5jZXJzXzIwMjEuY3N2IiwNCiAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICI7IiwNCiAgICAgICAgICAgICAgICAgICAgIGVuY29kaW5nID0gIlVURi04IikNCg0Ka2l3aTIxX29yaWdpbmFsIDwtIHJlYWRfc2hlZXQoIjFuaHBxRFd1Sm9XaGlWajBySWFWNTEtU2RmblN4VHBiVjNWY2QzaVlteVR3IikNCg0KIyBDb25maWd1cmFjaW9uZXMgZ2VuZXJhbGVzIC0tLS0NCg0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpICAgIyBNb2RpZmljYSBsYSB2aXN1YWxpemFjacOzbiBkZSBsb3MgZWplcyBudW3DqXJpY28gYSB2YWxvcmVzIG5vbWluYWxlcw0KDQpsb2FkZm9udHMocXVpZXQgPSBUUlVFKSAjIFBlcm1pdGUgY2FyZ2FyIGVuIFIgb3Ryb3MgdGlwb3MgZGUgZnVlbnRlcy4NCg0KIyBFc3RpbG8gbGltcGlvIHNpbiBsw61uZWFzIGRlIGZvbmRvDQplc3RpbG8gPC0gdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkJGQ0ZDIiksDQogICAgICAgICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJSb2JvdG8iKSkNCg0KIyBFc3RpbG8gbGltcGlvIGNvbiBsw61uZWFzIGRlIHJlZmVyZW5jaWEgdmVydGljYWxlcyBlbiBncmlzIGNsYXJvDQplc3RpbG92IDwtIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNGQkZDRkMiKSwNCiAgICAgICAgICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gIiNBRUI2QkYiKSwNCiAgICAgICAgICAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiUm9ib3RvIikpDQoNCiMgRXN0aWxvIGxpbXBpbyBjb24gbMOtbmVhcyBkZSByZWZlcmVuY2lhIGhvcml6b250YWxlcyBlbiBncmlzIGNsYXJvDQplc3RpbG9oIDwtIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNGQkZDRkMiKSwNCiAgICAgICAgICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9saW5lKGNvbG9yID0gIiNBRUI2QkYiKSwNCiAgICAgICAgICAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiUm9ib3RvIikpDQoNCmdlbmVybyA8LSBjKCIjMUZDM0FBIiwgIiM4NjI0RjUiLCAiI0ZGRDEyOSIsICIjNzU4MzhGIikgIyBWZXJkZSAtIFZpb2xldGEgLSBBbWFyaWxsbyAtIEdyaXMNCmdlbmVybzMgPC0gYygiIzg2MjRGNSIsIiNGRkQxMjkiLCAiIzFGQzNBQSIpDQoNCmNvbG9yZXMgPC0gIGMoIiM4NjI0RjUiLCAiIzFGQzNBQSIpDQoNCmF6dWwgPC0gIiMzNDREN0UiDQp2ZXJkZSA8LSAgIiMxRkMzQUEiDQpyb3NhMSA8LSAiI0I5NTE5MiINCnJvc2EyIDwtICIjRUU1Nzc3Ig0KbmFyYW5qYSA8LSAiI0ZGNzY0QyINCmFtYXJpbGxvIDwtICIjRkZBNjAwIg0KZ3JpcyA8LSAiIzc1ODM4RiINCmxpbGEgPC0gIiM4NjI0RjUiDQpyb2pvIDwtICIjOTQzMTI2Ig0KDQpjb2w0IDwtIGMoYXp1bCwgbGlsYSwgcm9zYTEsIHJvc2EyKQ0KY29sNSA8LSBjKGF6dWwsIGxpbGEsIHJvc2ExLCByb3NhMiwgbmFyYW5qYSkNCmNvbDYgPC0gYyhhenVsLCBsaWxhLCByb3NhMSwgcm9zYTIsIG5hcmFuamEsIGFtYXJpbGxvKQ0KDQojIENyZW8gdW4gb2JqZXRvIGNvbiB1biB0ZXh0byBxdWUgc2UgdmEgYSByZXBldGlyIG11Y2hvIGEgbG8gbGFyZ28gZGVsIGFuw6FsaXNpcw0KZnVlbnRlIDwtICJGdWVudGU6IEVuY3Vlc3RhIEtJV0kgZGUgU3VlbGRvcyBkZSBSUkhIIHBhcmEgTGF0YW0gMjAyMSINCg0KIyBDcmVvIG9iamV0b3MgcGFyYSBmb3JtYXRlYXIgbGFzIGV0aXF1ZXRhcyBudW3DqXJpY2FzIGRlIGxvcyBlamVzIHggZSB5DQplamVfeF9uIDwtIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBjb21tYV9mb3JtYXQoYmlnLm1hcmsgPSAiLiIsIGRlY2ltYWwubWFyayA9ICIsIikpDQoNCmVqZV95X24gPC0gc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGNvbW1hX2Zvcm1hdChiaWcubWFyayA9ICIuIiwgZGVjaW1hbC5tYXJrID0gIiwiKSkNCg0KDQojIENhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgDQoNCnJ0YXMyMSA8LSBucm93KGtpd2kyMV9vcmlnaW5hbCkNCg0KcnRhczIxX3BlcmMgPC0gcGVyY2VudCgxLSAocnRhczIxIC8gNzYyKSkNCg0KcnRhc19wYWlzIDwtIGtpd2kyMV9vcmlnaW5hbCAlPiUgDQogIHNlbGVjdChwYWlzID0gYFBhw61zIGVuIGVsIHF1ZSB0cmFiYWphc2ApICU+JSANCiAgZGlzdGluY3QocGFpcykgJT4lIA0KICBjb3VudCgpICU+JSANCiAgcHVsbCgpDQoNCg0KIyBSZW9yZ2FuaXphciBwdWVzdG9zIGplcsOhcnF1aWNhbWVudGUNCmtpd2kyMSA8LSBraXdpMjEgJT4lIA0KICBtdXRhdGUocHVlc3RvID0gZmFjdG9yKHB1ZXN0bywgDQogICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiRGlyZWN0b3IiLCAiR2VyZW50ZSIsICJKZWZlIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVzcG9uc2FibGUiLCAiSFJCUCIsICJBbmFsaXN0YSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWRtaW5pc3RyYXRpdm8iLCAiUGFzYW50ZSIpKSkNCmBgYA0KDQojIE1vdGl2YWNpb25lcw0KDQpDb21vIGVuIFJSSEggdHJhYmFqYW1vcyBjb24gZGF0b3Mgc2Vuc2libGVzLCBlcyBjb21wbGVqbyBjb25zZWd1aXIgZGF0b3MgcGFyYSBwcmFjdGljYXIgY3VhbmRvIGVzdMOhcyBhcHJlbmRpZW5kbyBzb2JyZSBQZW9wbGUgQW5hbHl0aWNzLCBlc3BlY2lhbG1lbnRlIGxhIHBhcnRlIHByw6FjdGljYS4gUG9yIGVzbywgZSBpbnNwaXJhZG9zIGVuIGxhIEVuY3Vlc3RhIGRlIFtTeXNBcm15XShodHRwczovL3N5c2FybXkuY29tL2Jsb2cvcG9zdHMvcmVzdWx0YWRvcy1kZS1sYS1lbmN1ZXN0YS1kZS1zdWVsZG9zLTIwMjAtMi8pLCB1bmEgY29tdW5pZGFkIGRlIHRlY25vbG9nw61hLCBxdWUgZW50cmUgb3RyYXMgY29zYXMsIG9yZ2FuaXphIGV2ZW50b3MgY29tbyAqKk5lcmRlYXJsYSoqLg0KDQpQb3IgZXN0YSByYXrDs24gaGljaW1vcyBudWVzdHJhIHByb3BpYSBlbmN1ZXN0YSwgcmVsZXZhbmRvIGRhdG9zIGRlIHByb2Zlc2lvbmFsZXMgcXVlIHRyYWJhamFuIHRhbnRvIGJham8gcmVsYWNpw7NuIGRlIGRlcGVuZGVuY2lhIGNvbW8gZGUgbWFuZXJhIGZyZWVsYW5jZS4gRWwgcmVsZXZhbWllbnRvIGRlIGRhdG9zIGxvIGhpY2ltb3MgZW50cmUgZWwgMjIgZGUgb2N0dWJyZSB5IGVsIDIyIGRlIG5vdmllbWJyZSBkZSAyMDIxLg0KDQpFbiBlc3RhIGVkaWNpw7NuIHJlY2liaW1vcyBlbiB0b3RhbCBgciBydGFzMjFgIHJlc3B1ZXN0YXMgKHVuIGByIHJ0YXMyMV9wZXJjYCBtZW5vcyBxdWUgZW4gMjAyMCksIGRlIGByIHJ0YXNfcGFpc2AgcGHDrXNlcyBkaWZlcmVudGVzLg0KDQpgYGB7ciBydGFzX3BhaXNfdGFibGF9DQpraXdpMjEgJT4lIA0KICBncm91cF9ieShwYWlzKSAlPiUgDQogIHRhbGx5KHNvcnQgPSBUKSAlPiUgDQogIHJlbmFtZSgiUGHDrXMiID0gcGFpcywNCiAgICAgICAgICJSZXNwdWVzdGFzIiA9IG4pICU+JSANCiAga2JsKGNhcHRpb24gPSAiUmVzcHVlc3RhcyBwb3IgUGHDrXMiLCApICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRiwgcG9zaXRpb24gPSAiY2VudGVyIiwNCiAgICAgICAgICAgICAgICBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIiwgInJlc3BvbnNpdmUiKSkgJT4lIA0KICBmb290bm90ZShnZW5lcmFsID0gZnVlbnRlKQ0KYGBgDQoNCkRlbCB0b3RhbCBkZSByZXNwdWVzdGFzIHJlY2liaWRhcywgYHIgbnJvdyhraXdpMjFfb3JpZ2luYWwpIC0gbnJvdyhmcmVlbG8yMSlgIHNvbiBkZSBwZXJzb25hcyBxdWUgdHJhYmFqYW4gZW4gcmVsYWNpw7NuIGRlIGRlcGVuZGVuY2lhIGVuIFJSSEgsIG1pZW50cmFzIHF1ZSBgciBucm93KGZyZWVsbzIxKWAgcGVyc29uYXMgdHJhYmFqYW4gZGUgbWFuZXJhIGZyZWVsYW5jZS4NCg0KYGBge3J9DQpraXdpMjFfb3JpZ2luYWwgJT4lIA0KICBzZWxlY3QoVHJhYmFqbykgJT4lIA0KICBncm91cF9ieShUcmFiYWpvKSAlPiUgDQogIGNvdW50KCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gVHJhYmFqbykpICsNCiAgZ2VvbV9jb2woZmlsbCA9IGF6dWwpICsNCiAgZXN0aWxvdiArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwgIyBJbmRpY2EgbGEgY2FudGlkYWQgZGUgZGVjaW1hbGVzDQogICAgICAgICAgICBzaXplID0gMywgICAgICAgIyBDYW1iaWEgZWwgdGFtYcOxbyBkZSBsYSBsZXRyYQ0KICAgICAgICAgICAgaGp1c3QgPSAxLjIsICAgICMgTXVldmUgbGEgZXRpcXVldGEgcGFyYSBsYSBpenF1aWVyZGENCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwNCiAgICAgICAgICAgIGZhbWlseSA9ICJSb2JvdG8iKSArDQogIGxhYnModGl0bGUgPSAiUmVzcHVlc3RhcyBwb3IgdGlwbyBkZSB0cmFiYWphZG9yIiwgDQogICAgICAgeCA9ICIiLCB5ID0gIiIsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQpgYGANCg0KRW4gZXN0YSBlZGljacOzbiBkZWNpZGltb3MgcmVhbGl6YXIgbG9zIGFuw6FsaXNpcyBkZSBnw6luZXJvIGVuIHTDqXJtaW5vcyBkZSAqKklkZW50aWRhZCBkZSBHw6luZXJvKiogcGFyYSBpbnRlbnRhciBhYmFyY2FyIGNvbiBudWVzdHJvIGFuw6FsaXNpcyBsYSBkaXZlcnNpZGFkIGVuIHTDqXJtaW5vcyBkZSBpZGVudGlkYWQgZGUgZ8OpbmVyby4gRXMgcG9yIGVzdGEgcmF6w7NuIHF1ZSwgYSBkaWZlcmVuY2lhIGRlIGxhIHByaW1lcmEgZWRpY2nDs24gZG9uZGUgbG9zIGFuw6FsaXNpcyBsb3MgaGljaW1vcyBlbiB0w6lybWlub3MgZGUgKk11amVyL0hvbWJyZSogZXN0ZSBhw7FvIGxvIGhpY2ltb3MgZW4gdMOpcm1pbm9zIGRlICpNdWplciBjaXMvTXVqZXIgdHJhbnMqIHkgKkhvbWJyZSBjaXMvSG9tYnJlIHRyYW5zKiBwYXJhIHBvZGVyIHJlZmxlamFyIGNvbiBtYXlvciBwcmVjaXNpw7NuIGVsIGFiw6FuaWNvIGRlIGlkZW50aWRhZGVzIHkgcGVyY2VwY2lvbmVzLg0KDQo+IEVsIHTDqXJtaWlubyAqImNpcyIqIGhhY2UgcmVmZXJlbmNpYSBhIHF1ZSBsYSBwZXJzb25hIHNlIGlkZW50aWZpY2EgY29uIGVsIG1pc21vIGfDqW5lcm8gY29uIGVsIHF1ZSBuYWNpw7MuDQoNCkxlIGFncmFkZWNlbW9zIG11Y2hvIGEgW0l2YW5hIEZlbGRlYmVyZ10oaHR0cHM6Ly93d3cubGlua2VkaW4uY29tL2luL2l2YW5hLWZlbGRmZWJlci8pIGRlbCBbT2JzZXJ2YXRvcmlvIGRlIERhdG9zIGNvbiBQZXJzcGVjdGl2YSBkZSBHw6luZXJvXShodHRwczovL3d3dy5kYXRhZ2VuZXJvLm9yZy8pIHBvciBlbCBhc2Vzb3JhbWllbnRvIGVuIGVzdGUgYXBhcnRhZG8uDQoNCkRpY2hvIGVzdG8sIGxhcyByZXNwdWVzdGFzIHNlZ8O6biBsYSBpZGVudGlkYWQgZGUgZ8OpbmVybyBkZSBsYXMgcGVyc29uYXMgcXVlIHBhcnRpY2lwYXJvbiBlcyBsYSBzaWd1aWVudGU6DQoNCmBgYHtyIGZpZy5zaG93PSdob2xkJywgb3V0LndpZHRoPSI1MCUiLCBmaWcuYWxpZ249J2RlZmF1bHQnfQ0KDQojIEdyw6FmaWNvIHBhcmEgcmVsYWNpw7NuIGRlIGRlcGVuZGVuY2lhLS0tLQ0KZGl2IDwtIGtpd2kyMSAlPiUgDQogIHNlbGVjdChnZW5lcm8pICU+JSANCiAgbXV0YXRlKGdlbmVybyA9IGZhY3RvcihnZW5lcm8sIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk11amVyIGNpcyIsICJIb21icmUgY2lzIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHJlZmllcm8gbm8gcmVzcG9uZGVyIiwgIkdheSIpKSkgJT4lIA0KICBncm91cF9ieShnZW5lcm8pICU+JSANCiAgc3VtbWFyaXNlIChuID0gbigpKSAlPiUgDQogIG11dGF0ZShmcmVxID0gbi9zdW0obikpICU+JSANCiAgYXJyYW5nZSgtbikNCg0KIyBDb21wdXRlIHRoZSBjdW11bGF0aXZlIHBlcmNlbnRhZ2VzICh0b3Agb2YgZWFjaCByZWN0YW5nbGUpDQpkaXYkeW1heCA8LSBjdW1zdW0oZGl2JGZyZXEpDQoNCiMgQ29tcHV0ZSB0aGUgYm90dG9tIG9mIGVhY2ggcmVjdGFuZ2xlDQpkaXYkeW1pbiA8LSBjKDAsIGhlYWQoZGl2JHltYXgsIG49LTEpKQ0KDQojIENvbXB1dGUgbGFiZWwgcG9zaXRpb24NCmRpdiRsYWJlbFBvc2l0aW9uIDwtIChkaXYkeW1heCArIGRpdiR5bWluKSAvIDINCg0KIyBDb21wdXRlIGEgZ29vZCBsYWJlbA0KZGl2JGxhYmVsIDwtIHBhc3RlMChkaXYkZ2VuZXJvLCAiXG4gQ2FudDogIiwgZGl2JG4pDQoNCiMgTWFrZSB0aGUgcGxvdA0KZ2dwbG90KGRpdiwgYWVzKHltYXg9eW1heCwgeW1pbj15bWluLCB4bWF4PTQsIHhtaW49MywgZmlsbD1nZW5lcm8pKSArDQogIGdlb21fcmVjdCgpICsNCiAgY29vcmRfcG9sYXIodGhldGE9InkiKSArICMgVHJ5IHRvIHJlbW92ZSB0aGF0IHRvIHVuZGVyc3RhbmQgaG93IHRoZSBjaGFydCBpcyBidWlsdCBpbml0aWFsbHkNCiAgeGxpbShjKDIsIDQpKSArIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gc2VlIGhvdyB0byBtYWtlIGEgcGllIGNoYXJ0DQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM4NjI0RjUiLCAgIiMxRkMzQUEiLCAiI0ZGRDEyOSIsIiM3NTgzOEYiKSkgKw0KICB0aGVtZV92b2lkKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwNCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGxvdC50aXRsZS5wb3NpdGlvbiA9ICJwbG90IiwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiUm9ib3RvIikpICsNCiAgbGFicyh0aXRsZSA9ICJDYW50aWRhZCBkZSByZXNwdWVzdGFzIHNlZ8O6biBnw6luZXJvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJSZWxhY2nDs24gZGUgRGVwZW5kZW5jaWEiLA0KICAgICAgIGZpbGwgPSAiR8OpbmVybyIsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQoNCiMgR3LDoWZpY28gZGUgZnJlZWxhbmNlcnMgLS0tLQ0KZnJlZWxvMjEgPC0gZnJlZWxvMjEgJT4lIA0KICBtdXRhdGUoZ2VuZXJvID0gZmN0X2NvbGxhcHNlKGdlbmVybywgIk11amVyIGNpcyIgPSBjKCJNdWplciBjaXMiLCAiTXVqZXIiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSG9tYnJlIGNpcyIgPSBjKCJIb21icmUgY2lzIikpLA0KICAgICAgICAgZ2VuZXJvID0gZmFjdG9yKGdlbmVybywgbGV2ZWxzID0gYygiTXVqZXIgY2lzIiwgIkhvbWJyZSBjaXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlByZWZpZXJvIG5vIHJlc3BvbmRlciIsICJObyBiaW5hcmlvIikpKQ0KDQpkaXYgPC0gZnJlZWxvMjEgJT4lIA0KICBzZWxlY3QoZ2VuZXJvKSAlPiUgDQogIGdyb3VwX2J5KGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2UgKG4gPSBuKCkpICU+JSANCiAgbXV0YXRlKGZyZXEgPSBuL3N1bShuKSkgJT4lIA0KICBhcnJhbmdlKC1uKQ0KDQojIENvbXB1dGUgdGhlIGN1bXVsYXRpdmUgcGVyY2VudGFnZXMgKHRvcCBvZiBlYWNoIHJlY3RhbmdsZSkNCmRpdiR5bWF4IDwtIGN1bXN1bShkaXYkZnJlcSkNCg0KIyBDb21wdXRlIHRoZSBib3R0b20gb2YgZWFjaCByZWN0YW5nbGUNCmRpdiR5bWluIDwtIGMoMCwgaGVhZChkaXYkeW1heCwgbj0tMSkpDQoNCiMgQ29tcHV0ZSBsYWJlbCBwb3NpdGlvbg0KZGl2JGxhYmVsUG9zaXRpb24gPC0gKGRpdiR5bWF4ICsgZGl2JHltaW4pIC8gMg0KDQojIENvbXB1dGUgYSBnb29kIGxhYmVsDQpkaXYkbGFiZWwgPC0gcGFzdGUwKGRpdiRnZW5lcm8sICJcbiBDYW50OiAiLCBkaXYkbikNCg0KIyBNYWtlIHRoZSBwbG90DQpnZ3Bsb3QoZGl2LCBhZXMoeW1heD15bWF4LCB5bWluPXltaW4sIHhtYXg9NCwgeG1pbj0zLCBmaWxsPWdlbmVybykpICsNCiAgZ2VvbV9yZWN0KCkgKw0KICBjb29yZF9wb2xhcih0aGV0YT0ieSIpICsgIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gdW5kZXJzdGFuZCBob3cgdGhlIGNoYXJ0IGlzIGJ1aWx0IGluaXRpYWxseQ0KICB4bGltKGMoMiwgNCkpICsjIFRyeSB0byByZW1vdmUgdGhhdCB0byBzZWUgaG93IHRvIG1ha2UgYSBwaWUgY2hhcnQNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzg2MjRGNSIsICAiIzFGQzNBQSIsICIjRkZEMTI5IiwiIzc1ODM4RiIpKSArDQogIHRoZW1lX3ZvaWQoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJSb2JvdG8iKSkgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgc2Vnw7puIGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkZyZWVsYW5jZXJzIiwNCiAgICAgICBmaWxsID0gIkfDqW5lcm8iLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KDQpgYGANCg0KRW4gcmVzdW1lbiwgbcOhcyBkZSBkb3MgdGVyY2lvcyBkZSBsYXMgcGVyc29uYXMgcXVlIHBhcnRpY2lwYXJvbiBkZSBlc3RhIGVuY3Vlc3RhIHNvbiBtdWplcmVzIGNpcy4gQWxnbyBxdWUgcmVmbGVqYW4gbG9zIGRhdG9zIGVzIHF1ZSBlbiBsYXMgw6FyZWFzIGRlIFJlY3Vyc29zIEh1bWFub3MsIGxhIGRpdmVyc2lkYWQgZGUgaWRlbnRpZGFkZXMgZGUgZ8OpbmVybyBlcyBwcsOhY3RpY2FtZW50ZSBudWxhLg0KDQpgYGB7ciBnZW5lcm9fcGFydGljaXBhbnRlc30NCmtpd2kyMV9vcmlnaW5hbCAlPiUgDQogICAgbXV0YXRlKGdlbmVybyA9IGZjdF9jb2xsYXBzZShgSWRlbnRpZGFkIGRlIEfDqW5lcm9gLCAiTXVqZXIgY2lzIiA9IGMoIk11amVyIGNpcyIsICJNdWplciIsICJtdWplciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk11amVyIGhldGVyb3NleHVhbCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIb21icmUgY2lzIiA9IGMoIkhvbWJyZSBjaXMiLCAiSG9tYnJlIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSG9tYnJlIGhldGVyby4gUXVlIGVzIGNpcz8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkhvbWJyZSBoZXRlcm9zZXh1YWwiKSksDQogICAgICAgICBnZW5lcm8gPSBmYWN0b3IoZ2VuZXJvLCBsZXZlbHMgPSBjKCJNdWplciBjaXMiLCAiSG9tYnJlIGNpcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHYXkiLCAiUHJlZmllcm8gbm8gcmVzcG9uZGVyIiwgIk5vIGJpbmFyaW8iKSkpICU+JSANCiAgZ3JvdXBfYnkoZ2VuZXJvKSAlPiUgDQogIHRhbGx5KHNvcnQgPSBUKSAlPiUgDQogIG11dGF0ZShQb3JjZW50YWplID0gbi9zdW0obiksDQogICAgICAgICBQb3JjZW50YWplID0gcGVyY2VudChQb3JjZW50YWplLCBhY2N1cmFjeSA9IDAuMSkpICU+JSANCiAgcmVuYW1lKCJHw6luZXJvIiA9IGdlbmVybywgDQogICAgICAgICAiQ2FudGlkYWQiID0gbikgJT4lIA0KICBrYmwoY2FwdGlvbiA9ICJUb3RhbCBkZSBQYXJ0aWNpcGFudGVzIHNlZ8O6blxuSWRlbnRpZGFkIGRlIEfDqW5lcm8iKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEYsIHBvc2l0aW9uID0gImNlbnRlciIsDQogICAgICAgICAgICAgICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIikpICU+JSANCiAgZm9vdG5vdGUoZ2VuZXJhbCA9IGZ1ZW50ZSwgZ2VuZXJhbF90aXRsZSA9ICIiKQ0KICANCg0KDQpgYGANCg0KDQojIEFuw6FsaXNpcyBkZSByZW11bmVyYWNpb25lcw0KIyMgUmVtdW5lcmFjaW9uZXMgcG9yIHBhw61zDQoNCkVuIGVzdGEgc2VjY2nDs24gbm9zIGRlZGljYXJlbW9zIGEgY29tcGFyYXIgbG9zIHN1ZWxkb3MgZW50cmUgbG9zIHBhw61zZXMuIEVuIHByaW1lciBsdWdhciwgaGF5IHF1ZSByZXNhbHRhciBxdWUgbG9zIHJlc3VsdGFkb3Mgbm8gc29uIHJlcHJlc2VudGF0aXZvcyBkZSBsb3MgbWVyY2Fkb3MgZGUgbG9zIHBhw61zZXMsIHNpbm8gcXVlIGxvIHNvbiBkZSBsb3MgZGF0b3MgcmVjb2xlY3RhZG9zLg0KDQpQb3Igb3RyYSBwYXJ0ZSwgbGEgYmFqYSBjYW50aWRhZCBkZSByZXNwdWVzdGFzIHJlY29sZWN0YWRhcyBkZSBvdHJvcyBwYcOtc2VzIGZ1ZXJhIGRlIGxhIEFyZ2VudGluYSwgbm9zIGhhY2UgaW1wb3NpYmxlLCBoYWNlciB1biBhbsOhbGlzaXMgY29tcGFyYWRvIHJlcHJlc2VudGF0aXZvIGRlIGxvcyBwdWVzdG9zLiBTaW4gZW1iYXJnbywgaGF5IGFsZ3Vub3MgZGF0b3MgaW50cmVzYW50ZXMgcGFyYSBhbmFsaXphci4NCg0KUHJpbWVybywgYW5hbGljZW1vcyBsb3Mgc3VlbGRvcyBkZSBsb3MgdHJhYmFqYWRvcmVzIGVuIHJlbGFjacOzbiBkZSBkZXBlbmRlbmNpYSwgZGUgY3V5b3MgcGHDrXNlcyBoYXlhbW9zIHJlY2liaWRvIGFsIG1lbm9zIDUgcmVzcHVlc3Rhcy4NCg0KYGBge3Igc3VlbGRvX3BhaXMxfQ0Kc3VlbGRvc19kb2xhciA8LSBraXdpMjEgJT4lIA0KICBzZWxlY3QocHVlc3RvLCBzdWVsZG9fZG9sYXIsIHBhaXMsIHRpcG9fY29udHJhdGFjaW9uKSAlPiUgDQogIGZpbHRlcihwdWVzdG8gIT0gIlBhc2FudGUiLCB0aXBvX2NvbnRyYXRhY2lvbiAhPSAiUGFzYW50ZSIpDQoNCiMgRWxpbWluYW1vcyBsb3Mgc3VlbGRvcyBxdWUgZXN0w6FuIGRlbnRybyBkZWwgcmFuZ28gZW50cmUgbG9zIHBlcmNlbnRpbGVzIDUgeSA5NQ0KbnVtZXJpY29zIDwtIHByb2ZpbGluZ19udW0oc3VlbGRvc19kb2xhcikNCnBvZGFfcDA1IDwtIG51bWVyaWNvc1sxLDZdDQpwb2RhX3A5NSA8LSBudW1lcmljb3NbMSwxMF0NCg0KIyBEYWRvIHF1ZSBsb3MgcGVyY2VudGlsZXMgNSB5IDk1IGVzdMOhbiBlbiBVJDQyMiB5IDMzMDAgcmVzcGVjdGl2YW1lbnRlLCANCiMgcG9kYW1vcyB0b2RvIGxvIHF1ZSBlc3TDqSBmdWVyYSBkZSBlc2UgcmFuZ28NCg0KbWVkaWFfcGFpcyA8LSBzdWVsZG9zX2RvbGFyICU+JSANCiAgZmlsdGVyKHBhaXMgJWluJSBjKCJBcmdlbnRpbmEiLCAiUGVyw7oiLCAiQm9saXZpYSIsICJDb3N0YSBSaWNhIiwgIlVydWd1YXkiLCANCiAgICAgICAgICAgICAgICAgICAgICJDaGlsZSIsICJNw6l4aWNvIiwgIlBhcmFndWF5IiwgIkVjdWFkb3IiKSwNCiAgICAgICAgIGJldHdlZW4oc3VlbGRvX2RvbGFyLHBvZGFfcDA1LHBvZGFfcDk1KSkgJT4lIA0KICBncm91cF9ieShwYWlzKSAlPiUgDQogIHN1bW1hcmlzZShzdWVsZG9wID0gbGlzdChtZWFuX3NlKHN1ZWxkb19kb2xhcikpKSAlPiUgDQogIHVubmVzdChjb2xzID0gYyhzdWVsZG9wKSkgDQogDQpzdWVsZG9fZG9sYXJfcGFpcyA8LSBraXdpMjEgJT4lIA0KICBzZWxlY3QocGFpcywgc3VlbGRvX2RvbGFyKSAlPiUgDQogIGZpbHRlcihiZXR3ZWVuKHN1ZWxkb19kb2xhciwgcG9kYV9wMDUsIHBvZGFfcDk1KSwNCiAgICAgICAgIHBhaXMgJWluJSBjKCJBcmdlbnRpbmEiLCAiUGVyw7oiLCAiQm9saXZpYSIsICJDb3N0YSBSaWNhIiwgIlVydWd1YXkiLCANCiAgICAgICAgICAgICAgICAgICAgICJDaGlsZSIsICJNw6l4aWNvIiwgIlBhcmFndWF5IiwgIkVjdWFkb3IiKSkNCg0KIyBHcsOhZmljbw0KZ2dwbG90KG1lZGlhX3BhaXMsIGFlcyhyZW9yZGVyKHBhaXMsIC15KSwgeSA9ICB5KSkrDQogIGdlb21fY29sKGZpbGwgPSBhenVsLCBhbHBoYSA9IDAuODUpICsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHltaW4seW1heCA9IHltYXgpLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gIiMzMzNlNDciKSsNCiAgZ2VvbV9wb2ludChkYXRhID0gc3VlbGRvX2RvbGFyX3BhaXMsIGFlcyh4ID0gcGFpcywgeSA9IHN1ZWxkb19kb2xhciksIA0KICAgICAgICAgICAgIGFscGhhID0gMC4zLCBzaXplID0gMiwgY29sb3IgPSAiIzc1ODM4RiIsDQogICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjE1KSkrDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShyb3VuZCh4PXksIDApLCBiaWcubWFyayA9ICIuIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNpbWFsLm1hcmsgPSAiLCIpLA0KICAgICAgICAgICAgICAgIHZqdXN0ID0gMS41LCBmb250ZmFjZSA9ICJib2xkIiksIA0KICAgICAgICAgICAgc2l6ZSA9IDQsIGNvbG9yID0gIndoaXRlIiwNCiAgICAgICAgICAgIGZhbWlseSA9ICJSb2JvdG8iKSsNCiAgZWplX3lfbiArDQogIGxhYnModGl0bGUgPSAiU2FsYXJpbyBwcm9tZWRpbyBwb3IgcGHDrXMiLA0KICAgICAgIHN1YnRpdGxlID0gIlN1ZWxkb3MgZGUgUlJISCBlbiBVJFMiLA0KICAgICAgIGNhcHRpb24gPSBwYXN0ZTAoZnVlbnRlLCJcblBhw61zZXMgY29uIG3DoXMgZGUgNSByZXNwdWVzdGFzIiksDQogICAgICAgeCA9ICIiLCB5ID0gIiIpICsgDQogIGVzdGlsb2gNCmBgYA0KDQpBIHBlc2FyIGRlIGxhIGJhamEgY2FudGlkYWQgZGUgcmVzcHVlc3Rhcywgc2UgcmVwaXRlIGxhIHRlbmRlbmNpYSBkZWwgMjAyMCBlbiBkb25kZSAqKlVydWd1YXkqKiB5ICoqQ2hpbGUqKiB0aWVuZW4gZW4gcHJvbWVkaW8gbG9zIHN1ZWxkb3MgbcOhcyBhbHRvcyBkZSBsYSByZWdpw7NuLg0KDQojIyBBbsOhbGlzaXMgZGUgc3VlbGRvcyBwb3IgcHVlc3RvcyBlbiBMYXRpbm9hbcOpcmljYQ0KDQpgYGB7ciBzdWVsZG9fcHVlc3RvfQ0Ka2l3aTIxICU+JSANCiAgc2VsZWN0KHB1ZXN0bywgc3VlbGRvX2RvbGFyKSAlPiUgDQogIGZpbHRlcihwdWVzdG8gIT0gIlBhc2FudGUiLA0KICAgICAgICAgYmV0d2VlbihzdWVsZG9fZG9sYXIsIHBvZGFfcDA1LCBwb2RhX3A5NSkpICU+JSANCiAgZ3JvdXBfYnkocHVlc3RvKSAlPiUgDQogIHN1bW1hcmlzZShtZWRpYW5hX3NhbGFyaWFsID0gbWVkaWFuKHN1ZWxkb19kb2xhcikpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVkaWFuYV9zYWxhcmlhbCwgeSA9IGZjdF9yZXYocHVlc3RvKSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9IGF6dWwpICsNCiAgZXN0aWxvdiArDQogIGxhYnModGl0bGUgPSAiTWVkaWFuYSBzYWxhcmlhbCBwb3IgcHVlc3RvIiwgDQogICAgICAgc3VidGl0bGUgPSAiU3VlbGRvcyBkZSBSUkhIIGVuIFUkUyIsIA0KICAgICAgIHggPSAiIiwgeSA9ICIiLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIGVqZV94X24NCmBgYA0KDQpMYSByYXrDs24gcG9yIGxhIGN1YWwgbGEgbWVkaWFuYSBzYWxhcmlhbCBkZSBsYXMgcGVyc29uYXMgZW4gcHVlc3RvIGRlICoqRGlyZWNjacOzbioqIGVzIG1lbm9yIGEgbGEgZGUgbGFzIHBlcnNvbmFzIGVuIHB1ZXN0b3MgZGUgKipHZXJlbnRlKiogc2UgZXhwbGljYSBwb3IgZWwgdGFtYcOxbyBkZSBsYSBtdWVzdHJhIHkgbGFzIHJlc3B1ZXN0YXMgcmVjaWJpZGFzLiBFbiBsYSB0YWJsYSBhIGNvbnRpbnVhY2nDs24gaW5jb3Jwb3JhIGxhIGNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgcmVjaWJpZGFzIHBhcmEgY2FkYSB1bm8gZGUgZXN0YXMgcG9zaWNpb25lcy4NCg0KYGBge3Igc3VlbGRvX3B1ZXN0b190YWJsYX0NCmd0KGtpd2kyMSAlPiUgDQogICAgIHNlbGVjdChwdWVzdG8sIHN1ZWxkb19kb2xhcikgJT4lIA0KICAgICBmaWx0ZXIocHVlc3RvICE9ICJQYXNhbnRlIikgJT4lIA0KICAgICBncm91cF9ieShwdWVzdG8pICU+JSANCiAgICAgc3VtbWFyaXNlKG1lZGlhbmFfc2FsYXJpYWwgPSBtZWRpYW4oc3VlbGRvX2RvbGFyKSwgDQogICAgICAgICAgICAgICBjYW50ID0gbigpKQ0KICAgICApICU+JSANCiAgdGFiX2hlYWRlcih0aXRsZSA9ICJNZWRpYW5hIHNhbGFyaWFsIHBvciBwdWVzdG9zIiwgDQogICAgICAgICAgICAgc3VidGl0bGUgPSAiU3VlbGRvcyBlbiBVJEQiKSAlPiUgDQogIHRhYl9zb3VyY2Vfbm90ZShzb3VyY2Vfbm90ZSA9IGZ1ZW50ZSkgJT4lIA0KICAgZm10X2N1cnJlbmN5KGNvbHVtbnMgPSAgIm1lZGlhbmFfc2FsYXJpYWwiLCBkZWNpbWFscyA9IDAsDQogICAgICAgICAgICAgICBzZXBfbWFyayA9ICIuIiwgZGVjX21hcmsgPSAiLCIpICU+JSANCiAgY29sc19sYWJlbChwdWVzdG8gPSAiUG9zaWNpw7NuIiwNCiAgICAgICAgICAgICBtZWRpYW5hX3NhbGFyaWFsID0gIk1lZGlhbmEgU3VlbGRvIiwNCiAgICAgICAgICAgICBjYW50ID0gIlJlc3B1ZXN0YXMiKSANCmBgYA0KDQojIyBTdWVsZG9zIHNlZ8O6biBlbCBvcmlnZW4gZGVsIGNhcGl0YWwNCg0KU2kgZGl2aWRpbW9zIGxvcyBncsOhZmljb3Mgc2Vnw7puIGVsICpPcmlnZW4gZGVsIENhcGl0YWwqLCBwb2RlbW9zIGFwcmVjaWFyIHF1ZSBlbiBsw61uZWFzIGdlbmVyYWxlcywgbGEgbWVkaWFuYSBzYWxhcmlhbCBlbiBlbXByZXNhcyBtdWx0aW5hY2lvbmVzIGVzIG1heW9yIHF1ZSBlbiBsYXMgZW1wcmVzYXMgbmFjaW9uYWxlcy4gU29sYW1lbnRlIGVuIGxhcyBwb3NpY2lvbmVzIGRlICoqSFJCUCoqIHkgZGUgKipHZXJlbnRlKiogc2UgYXByZWNpYSB1bmEgcGFyaWRhZCBzYWxhcmlhbCByZXNwZWN0byBkZWwgb3JpZ2VuIGRlbCBjYXBpdGFsIGRlIGxhIG9yZ2FuaXphY2nDs24uDQoNCmBgYHtyIG9yaWdlbl9jYXBpdGFsfQ0Ka2l3aTIxICU+JSANCiAgc2VsZWN0KG9yaWdlbl9jYXBpdGFsLCBwdWVzdG8sIHN1ZWxkb19kb2xhcikgJT4lIA0KICBmaWx0ZXIocHVlc3RvICE9ICJQYXNhbnRlIiwgDQogICAgICAgICBiZXR3ZWVuKHN1ZWxkb19kb2xhciwgcG9kYV9wMDUsIHBvZGFfcDk1KSkgJT4lIA0KICBncm91cF9ieShwdWVzdG8sIG9yaWdlbl9jYXBpdGFsKSAlPiUgDQogIHN1bW1hcmlzZShtZWRpYW5hX3NhbGFyaWFsID0gbWVkaWFuKHN1ZWxkb19kb2xhcikpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVkaWFuYV9zYWxhcmlhbCwgeSA9IGZjdF9yZXYocHVlc3RvKSwgZmlsbCA9IG9yaWdlbl9jYXBpdGFsKSkgKw0KICBnZW9tX2NvbCgpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKHg9bWVkaWFuYV9zYWxhcmlhbCwgMCksIGhqdXN0ID0gMS4yLCBmb250ZmFjZSA9ICJib2xkIiksc2l6ZSA9IDMsIGNvbG9yID0gIndoaXRlIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKHZlcmRlLCBhenVsKSkgKw0KICBlc3RpbG92ICsNCiAgZWplX3hfbiArDQogIGZhY2V0X3dyYXAofm9yaWdlbl9jYXBpdGFsKSArDQogIGxhYnModGl0bGUgPSAiTWVkaWFuYSBzYWxhcmlhbCBwb3IgcHVlc3RvIHNlZ8O6biBvcmlnZW4gZGVsIGNhcGl0YWwiLCANCiAgICAgICBzdWJ0aXRsZSA9ICJTdWVsZG9zIGRlIFJSSEggZW4gVSRTIiwgDQogICAgICAgeCA9ICIiLCB5ID0gIiIsIGZpbGwgPSAiIiwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikNCmBgYA0KDQpWZWFtb3MgZXN0ZSBncsOhZmljbyBkZSBvdHJhIG1hbmVyYToNCg0KYGBge3Igb3JpZ2VuX2NhcGl0YWxfc2xvcGV9DQoNCnNsb3BlX2RmIDwtIGtpd2kyMSAlPiUgDQogIHNlbGVjdChwdWVzdG8sIHN1ZWxkb19kb2xhciwgb3JpZ2VuX2NhcGl0YWwpICU+JSANCiAgZmlsdGVyKGJldHdlZW4oc3VlbGRvX2RvbGFyLCBwb2RhX3AwNSwgcG9kYV9wOTUpKSAlPiUgDQogIGdyb3VwX2J5KHB1ZXN0bywgb3JpZ2VuX2NhcGl0YWwpICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbmFfc2FsYXJpYWwgPSByb3VuZChtZWRpYW4oc3VlbGRvX2RvbGFyKSkpDQoNCm5ld2dnc2xvcGVncmFwaChkYXRhZnJhbWUgPSBzbG9wZV9kZiwNCiAgICAgICAgICAgICAgICBUaW1lcyA9IG9yaWdlbl9jYXBpdGFsLA0KICAgICAgICAgICAgICAgIE1lYXN1cmVtZW50ID0gbWVkaWFuYV9zYWxhcmlhbCwNCiAgICAgICAgICAgICAgICBHcm91cGluZyA9IHB1ZXN0bywNCiAgICAgICAgICAgICAgICBUaXRsZSA9ICJEaWZlcmVuY2lhcyBlbnRyZSBzdWVsZG9zIGRlIFJSSEggZW4gZW1wcmVzYXMgbmFjaW9uYWxlcyB5IG11bHRpbmFjaW9uYWxlcyIsDQogICAgICAgICAgICAgICAgU3ViVGl0bGUgPSAiTWVkaWFuYSBTYWxhcmlhbC4gU3VlbGRvcyBlbiBVJFMiLA0KICAgICAgICAgICAgICAgIENhcHRpb24gPSBmdWVudGUsIFdpZGVyTGFiZWxzID0gVA0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICkNCmBgYA0KDQojIyBBbsOhbGlzaXMgcG9yIHJ1YnJvIHkgb3JpZ2VuIGRlbCBjYXBpdGFsDQoNClBhcmEgZWwgYW7DoWxpc2lzIGRlIGxvcyBydWJyb3MgZGUgbGEgZW1wcmVzYSwgdmFtb3MgYSBmaWx0cmFyIGxvcyA1IHJ1YnJvcyBxdWUgdGllbmVuIG3DoXMgcmVzcHVlc3Rhcy4gVGFtYmnDqW4gZWxpbWluYXJlbW9zIGRlbCBhbsOhbGlzaXMgZWwgcHVlc3RvIGRlIERpcmVjdG9yIHBvcnF1ZSBubyBzZSBlbmN1ZW50cmEgcHJlc2VudGUgZW4gdG9kb3MgbG9zIHJ1YnJvcy4NCg0KYGBge3IgcnVicm9zLCBmaWcuaGVpZ2h0PTE1fQ0KdG9wXzVfcnVicm9zIDwtIGtpd2kyMSAlPiUgDQogIHNlbGVjdChydWJybykgJT4lIA0KICBncm91cF9ieShydWJybykgJT4lIA0KICBjb3VudChzb3J0ID0gVFJVRSkgJT4lDQogIGZpbHRlcihydWJybyAhPSAiT3Ryb3MiLCBuID4gMzApICU+JSANCiAgcHVsbCh2YXIgPSBydWJybykNCg0KDQpraXdpMjEgJT4lIA0KICBzZWxlY3QocnVicm8sIG9yaWdlbl9jYXBpdGFsLCBwdWVzdG8sIHN1ZWxkb19kb2xhcikgJT4lIA0KICBmaWx0ZXIocHVlc3RvICE9ICJQYXNhbnRlIiwgcHVlc3RvICE9ICJEaXJlY3RvciIsDQogICAgICAgICBiZXR3ZWVuKHN1ZWxkb19kb2xhciwgcG9kYV9wMDUsIHBvZGFfcDk1KSwNCiAgICAgICAgIHJ1YnJvICVpbiUgdG9wXzVfcnVicm9zKSAlPiUgDQogIGdyb3VwX2J5KHJ1YnJvLCBwdWVzdG8sIG9yaWdlbl9jYXBpdGFsKSAlPiUgDQogIHN1bW1hcmlzZShtZWRpYW5hX3NhbGFyaWFsID0gbWVkaWFuKHN1ZWxkb19kb2xhcikpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVkaWFuYV9zYWxhcmlhbCwgeSA9IGZjdF9yZXYocHVlc3RvKSwgDQogICAgICAgICAgICAgZmlsbCA9IG9yaWdlbl9jYXBpdGFsKSkgKw0KICBnZW9tX2NvbCgpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKHg9bWVkaWFuYV9zYWxhcmlhbCwgMCksIA0KICAgICAgICAgICAgICAgIGhqdXN0ID0gMS4yLCANCiAgICAgICAgICAgICAgICBmb250ZmFjZSA9ICJib2xkIiksDQogICAgICAgICAgICBzaXplID0gMywgDQogICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyh2ZXJkZSwgYXp1bCkpICsNCiAgZXN0aWxvICsNCiAgZWplX3hfbiArDQogIGZhY2V0X2dyaWQocnVicm9+b3JpZ2VuX2NhcGl0YWwpICsNCiAgbGFicyh0aXRsZSA9ICJNZWRpYW5hIHNhbGFyaWFsIHBvciBwdWVzdG8gc2Vnw7puIG9yaWdlbiBkZWwgY2FwaXRhbCIsIA0KICAgICAgIHN1YnRpdGxlID0gIlN1ZWxkb3MgZGUgUlJISCBlbiBVJFMiLCANCiAgICAgICB4ID0gIiIsIHkgPSAiIiwgZmlsbCA9ICIiLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKQ0KYGBgDQoNClBhcmEgdmVyIGxhcyBtZWRpYW5hcyBzYWxhcmlhbGVzIHBvciBydWJyb3MganVudG8gY29uIGVsIGRlc3bDrW8gZXN0w6FuZGFyLCBwdWVkZW4gdmVyIGxhIHNpZ3VpZW50ZSB0YWJsYToNCg0KYGBge3IgcnVicm9zMn0NCiAga2l3aTIxICU+JSANCiAgICBzZWxlY3QocnVicm8sIHN1ZWxkb19kb2xhcikgJT4lIA0KICAgIGZpbHRlcihiZXR3ZWVuKHN1ZWxkb19kb2xhciwgcG9kYV9wMDUsIHBvZGFfcDk1KSkgJT4lIA0KICAgIGdyb3VwX2J5KHJ1YnJvKSAlPiUgDQogICAgc3VtbWFyaXNlKG1lZGlhbmFfc2FsYXJpYWwgPSByb3VuZChtZWRpYW4oc3VlbGRvX2RvbGFyKSksDQogICAgICAgICAgICAgIGRlc3Zpb19zYWxhcmlhbCA9IHJvdW5kKHNkKHN1ZWxkb19kb2xhcikpLA0KICAgICAgICAgICAgICBSZXNwdWVzdGFzID0gbigpKSAlPiUgDQogICAgYXJyYW5nZSgtbWVkaWFuYV9zYWxhcmlhbCkgJT4lIA0KICBrYmwoY2FwdGlvbiA9ICJNZWRpYW5hIHNhbGFyaWFsIHBvciBydWJyby4gRW4gVSRTIiwgDQogICAgICBjb2wubmFtZXMgPSBjKCJSdWJybyIsICJNZWRpYW5hIFNhbGFyaWFsIiwiRGVzdsOtbyIsICJSZXNwdWVzdGFzIikpICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRiwgcG9zaXRpb24gPSAiY2VudGVyIiwNCiAgICAgICAgICAgICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIikpICU+JSANCiAgc2Nyb2xsX2JveChoZWlnaHQgPSAiNTAwcHgiKQ0KICANCg0KYGBgDQoNCiMgU3VlbGRvcyBwb3IgcGHDrXNlcw0KDQpTaSBiaWVuIGxhIG1heW9yIGNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgbGEgcmVjaWJpbW9zIGRlIHBlcnNvbmFzIHRyYWJhamFuZG8gZW4gQXJnZW50aW5hLCBlbiBlc3RhIGVkaWNpw7NuIGRlY2lkaW1vcyBpbmNsdWlyIGEgdG9kb3MgbG9zIHBhw61zZXMgZGUgbG9zIHF1ZSBvYnR1dmltb3MgYWwgbWVub3MgMTAgcmVzcHVlc3RhcyAoQXJnZW50aW5hLCBQZXLDuiwgQm9saXZpYSwgQ29zdGEgUmljYSwgVXJ1Z3VheSB5IENoaWxlKS4gU2kgYmllbiBsYSBjYW50aWRhZCBkZSByZXNwdWVzdGFzIG5vICBub3MgcGVybWl0ZW4gcmVhbGl6YXIgYW7DoWxpc2lzIG11eSBwcm9mdW5kb3MgcXVlcmVtb3MgYWdyYWRlY2VyIGEgbGFzIHBlcnNvbmFzIHF1ZSByZXNwb25kaWVyb24gcmVhbGl6YW5kbyBhdW5xdWUgbcOhcyBubyBzZWEgdW4gYnJldmUgYW7DoWxpc2lzLg0KDQpDb21vIHByaW1lcm9zIHBhc29zLCB2YW1vcyBhIGZpbHRyYXIgbG9zIGRhdG9zIGNvcnJlc3BvbmRpZW50ZXMgYSBjYWRhIHBhw61zLCB5IGx1ZWdvIGZpbHRyYW1vcyBsb3Mgc3VlbGRvcyBxdWUgZXN0w6luIGVudHJlIGxvcyBwZXJjZW50aWxlcyA1IHkgOTUsIHBhcmEgZWxpbWluYXIgdmFsb3JlcyBlc3B1cmlvcyBvIGV4dHJlbW9zIHF1ZSBlbnN1Y2llbiBlbCBhbsOhbGlzaXMuDQoNClRhbWJpw6luIGVsaW1pbmFtb3MgZWwgcHVlc3RvIGRlIERpcmVjdG9yIGRlbCBhbsOhbGlzaXMgeSBsYXMgcmVzcHVlc3RhcyBjb24gR8OpbmVybyBkaXZlcnNvIHBvciBsYSBiYWphIGNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMuDQoNCk90cmEgY29udmVyc2nDs24gcXVlIGhpY2ltb3MgZnVlIHBhc2FyIGxvcyBzdWVsZG9zIGRlIGxhcyBwZXJzb25hcyBxdWUgdHJhYmFqYW4gcGFydC10aW1lIGEgdW5hIGVxdWl2YWxlbmNpYSBmdWxsLXRpbWUgbXVsdGlwbGljYW5kbyBwb3IgMS41IGVsIHN1ZWxkbyBjb21wbGV0YWRvIGVuIGxhIGVuY3Vlc3RhLg0KDQpFbiBlc3RhIGluc3RhbmNpYSwgdGFtYmnDqW4gc2ltcGxpZmljYW1vcyBsb3Mgbm9tYnJlcyBkZSBhbGd1bm9zIHJ1YnJvcyBwYXJhIG1lam9yYXIgbGFzIHZpc3VhbGl6YWNpb25lcyBkZSBsb3MgcmVzdWx0YWRvcy4NCg0KIyMgUGVyw7oNCg0KYGBge3IgcGVydTF9DQpraXdpMjEgPC0ga2l3aTIxICU+JSANCiAgZmlsdGVyKGJldHdlZW4oc3VlbGRvX2RvbGFyLCBwb2RhX3AwNSwgcG9kYV9wOTUpLA0KICAgICAgICAgcHVlc3RvICE9ICJEaXJlY3RvciIsIHB1ZXN0byAhPSAiUGFzYW50ZSIsDQogICAgICAgICBnZW5lcm8gJWluJSBjKCJNdWplciBjaXMiLCAiSG9tYnJlIGNpcyIpLA0KICAgICAgICAgYW5pb3NfZXhwZXJpZW5jaWEgPCA1MCkgJT4lIA0KICBtdXRhdGUocnVicm8gPSBmY3RfcmVjb2RlKHJ1YnJvLCAiU2VydmljaW9zIGZpbmFuY2llcm9zIiA9ICJTZXJ2aWNpb3MgZmluYW5jaWVyb3M7IHNlZ3Vyb3MiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVHJhbnNwb3J0ZSIgPSAiVHJhbnNwb3J0ZSAoaW5jbHV5ZW5kbyBhdmlhY2nDs24gY2l2aWw7IGZlcnJvY2FycmlsZXMgcG9yIGNhcnJldGVyYSkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbmQuIEF1dG9tb3RyaXogeSBBdXRvcGFydGlzdGFzIiA9ICJUZXJtaW5hbGVzIGF1dG9tb3RyaWNlcywgZsOhYnJpY2FzIGF1dG9wYXJ0aXN0YXMsIHkgYWZpbmVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVGVjbm9sb2fDrWEiID0gIlRlY25vbG9nw61hcyBkZSBJbmZvcm1hY2nDs24sIFNpc3RlbWFzLCB5IGFmaW5lcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkluZC4gUGV0cm9sZXJhIiA9ICJQZXRyw7NsZW8geSBwcm9kdWNjacOzbiBkZSBnYXM7IHJlZmluYWNpw7NuIGRlIHBldHLDs2xlbyIpLA0KICAgICAgICAgbXVsdGlwbGljYWRvciA9IGlmX2Vsc2UodGlwb19jb250cmF0YWNpb24gPT0gIlBhcnQgdGltZSIsIDEuNSwgMSksDQogICAgICAgICBzdWVsZG9fZnQgPSBzdWVsZG9fYnJ1dG8gKiBtdWx0aXBsaWNhZG9yKQ0KDQojIEFuw6FsaXNpcyBQZXLDug0KcmhfcGUgPC0ga2l3aTIxICU+JSANCiAgZmlsdGVyKHBhaXMgPT0gIlBlcsO6IikNCg0KDQoNCmBgYA0KDQojIyMgQW7DoWxpc2lzIHNhbGFyaWFsIHBvciBnw6luZXJvIHkgcHVlc3Rvcw0KDQpFbiBlbCBzaWd1aWVudGUgZ3LDoWZpY28gcG9kZW1vcyB2ZXIgbGEgZGlzdHJpYnVjacOzbiBkZSBsb3Mgc3VlbGRvcyBwb3IgZ8OpbmVyby4gRW4gZXN0ZSB0aXBvIGRlIGdyw6FmaWNvcywgbGxhbWFkb3MgYm94cGxvdHMgcG9kZW1vcyB2ZXI6DQoNCiogKipQcmltZXIgY3VhcnRpbCoqOiBMYSBwYXJ0ZSBpbmZlcmlvciBkZSBsYSBjYWphLg0KKiAqKk1lZGlhbmEqKjogTGEgbMOtbmVhIGdydWVzYSBkZW50cm8gZGUgY2FkYSByZWN0w6FuZ3Vsby4NCiogKipUZXJjZXIgY3VhcnRpbCoqOiBMYSBwYXJ0ZSBzdXBlcmlvciBkZSBsYSBjYWphDQoqICoqT3V0bGllcnMqKjogc29uIGxvcyB2YWxvcmVzIGV4dHJlbW9zIGlkZW50aWZpY2Fkb3MgY29uIHB1bnRvcy4NCg0KQSBlc3RlIGdyw6FmaWNvIGxvIGNvbWJpbmFtb3MgY29uIHVuIHNjYXR0ZXJwbG90IHBhcmEgcG9kZXIgdmVyIGxhIGNhbnRpZGFkIGRlIHJlZ2lzdHJvcy4NCg0KYGBge3IgcGVydTJ9DQpnZ3Bsb3QocmhfcGUsIGFlcyh4ID0gZ2VuZXJvLCB5ID0gc3VlbGRvX2JydXRvLCBmaWxsID0gZ2VuZXJvKSkgKw0KICBnZW9tX2JveHBsb3QoYWxwaGEgPSAwLjYpICsNCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDAuMDgpLCBzaXplID0gMikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBnZW5lcm8pICsNCiAgZXN0aWxvaCArIA0KICBlamVfeV9uICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGRlIHN1ZWxkb3MgcG9yIGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIFBlcsO6IC0gRW4gUy8iLA0KICAgICAgIHggPSAiIiwgeSA9ICJTb2xlcyBTLyIsDQogICAgICAgZmlsbCA9ICJHw6luZXJvIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KDQpgYGANCg0KRW4gZWwgc2lndWllbnRlIGdyw6FmaWNvIHBvZGVtb3MgdmVyIGxvcyBzdWVsZG9zIHByb21lZGlvcyBwYXJhIGNhZGEgcG9zaWNpw7NuIHkgZ8OpbmVyby4gRW4gYWxndW5hcyBwb3NpY2lvbmVzIHkgZ8OpbmVybyBzw7NsbyB0ZW5lbW9zIHVuYSBzb2xhIHJlc3B1ZXN0YSwgcG9yIGVzbyBsYXMgYmFycmFzIGRlIGVycm9yIG5vIGFwYXJlY2VuLg0KDQpgYGB7ciBwZXJ1M30NCg0KcmhfcGUgJT4lIA0KICBncm91cF9ieShwdWVzdG8sIGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2Uoc3VlbGRvcCA9IGxpc3QobWVhbl9zZShzdWVsZG9fYnJ1dG8pKSkgJT4lIA0KICB1bm5lc3QoY29scyA9IGMoc3VlbGRvcCkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmN0X3JldihwdWVzdG8pLCB5ID0geSwgZmlsbCA9IGdlbmVybykpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSB5bWluLHltYXggPSB5bWF4KSwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICIjMzMzZTQ3IikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoeD15LCAwKSwgYmlnLm1hcmsgPSAiLiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2ltYWwubWFyayA9ICIsIiksDQogICAgICAgICAgICAgICB2anVzdCA9IDEuNSwgZm9udGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLA0KICAgICAgICAgICBzaXplID0gNCwgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICBmYW1pbHkgPSAiUm9ib3RvIikgKw0KICBlamVfeV9uICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZ2VuZXJvKSArDQogIGxhYnModGl0bGUgPSAiU2FsYXJpbyBwcm9tZWRpbyBwb3IgcHVlc3RvIHkgZ8OpbmVybyIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgUGVyw7ogZW4gUy8iLA0KICAgICAgIGNhcHRpb24gPSBwYXN0ZTAoZnVlbnRlKSwNCiAgICAgICBmaWxsID0gIkfDqW5lcm8iLA0KICAgICAgIHggPSAiIiwgeSA9ICJTb2xlcyBTLyIpICsgDQogIGVzdGlsb2gNCmBgYA0KDQojIyMgQW7DoWxpc2lzIHBvciBmdW5jaW9uZXMNCg0KYGBge3IgcGVydV9yb2x9DQpyaF9wZSAlPiUgDQogIGdyb3VwX2J5KGZ1bmNpb24pICU+JSANCiAgc3VtbWFyaXNlKHN1ZWxkb19wcm9tZWRpbyA9IG1lYW4oc3VlbGRvX2JydXRvKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBzdWVsZG9fcHJvbWVkaW8sIA0KICAgICAgICAgICAgIHkgPSByZW9yZGVyKGZ1bmNpb24sIHN1ZWxkb19wcm9tZWRpbykpKSArDQogIGdlb21fY29sKGZpbGwgPSBhenVsKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShyb3VuZChzdWVsZG9fcHJvbWVkaW8sIDApLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpZy5tYXJrID0gIi4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNpbWFsLm1hcmsgPSAiLCIpLA0KICAgICAgICAgICAgaGp1c3QgPSAxLjUsIGZvbnRmYWNlID0gImJvbGQiKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSwNCiAgICAgICAgICAgIHNpemUgPSAzLCBjb2xvciA9ICJ3aGl0ZSIsDQogICAgICAgICAgICBmYW1pbHkgPSAiUm9ib3RvIikgKw0KICBlamVfeF9uICsNCiAgZXN0aWxvdiArDQogIGxhYnModGl0bGUgPSAiU3VlbGRvIHByb21lZGlvIHBvciBmdW5jacOzbiIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgUGVyw7ogZW4gUy8iLA0KICAgICAgIHggPSAiU29sZXMgUy8iLA0KICAgICAgIHkgPSAiIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIpDQpgYGANCg0KDQojIyMgQW7DoWxpc2lzIHBvciBydWJyb3MNCg0KVmVhbW9zIGN1w6FsZXMgc29uIGxvcyBydWJyb3MgbWVqb3IgcGFnb3MgZW4gUGVyw7oNCg0KYGBge3IgcGVydV9ydWJyb30NCnJoX3BlICU+JSANCiAgZ3JvdXBfYnkocnVicm8pICU+JSANCiAgc3VtbWFyaXNlKHN1ZWxkb19wcm9tZWRpbyA9IG1lYW4oc3VlbGRvX2JydXRvKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBzdWVsZG9fcHJvbWVkaW8sIA0KICAgICAgICAgICAgIHkgPSByZW9yZGVyKHJ1YnJvLCBzdWVsZG9fcHJvbWVkaW8pKSkgKw0KICBnZW9tX2NvbChmaWxsID0gYXp1bCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoc3VlbGRvX3Byb21lZGlvLCAwKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaWcubWFyayA9ICIuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiKSwNCiAgICAgICAgICAgIGhqdXN0ID0gMS41LCBmb250ZmFjZSA9ICJib2xkIiksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksDQogICAgICAgICAgICBzaXplID0gMywgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICAgZmFtaWx5ID0gIlJvYm90byIpICsNCiAgZWplX3hfbiArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIlN1ZWxkbyBwcm9tZWRpbyBwb3IgcnVicm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIFBlcsO6IGVuIFMvIiwNCiAgICAgICB4ID0gIlNvbGVzIFMvIiwNCiAgICAgICB5ID0gIiIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICB0aGVtZShwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiKQ0KYGBgDQoNCiMjIEJvbGl2aWENCg0KYGBge3IgYm9sMX0NCg0KIyBBbsOhbGlzaXMgQm9saXZpYQ0KcmhfYm8gPC0ga2l3aTIxICU+JSANCiAgZmlsdGVyKHBhaXMgPT0gIkJvbGl2aWEiKQ0KDQpgYGANCg0KIyMjIEFuw6FsaXNpcyBzYWxhcmlhbCBwb3IgZ8OpbmVybyB5IHB1ZXN0b3MNCg0KRW4gZWwgc2lndWllbnRlIGdyw6FmaWNvIHBvZGVtb3MgdmVyIGxhIGRpc3RyaWJ1Y2nDs24gZGUgbG9zIHN1ZWxkb3MgcG9yIGfDqW5lcm8uIEVuIGVzdGUgdGlwbyBkZSBncsOhZmljb3MsIGxsYW1hZG9zIGJveHBsb3RzIHBvZGVtb3MgdmVyOg0KDQoqICoqUHJpbWVyIGN1YXJ0aWwqKjogTGEgcGFydGUgaW5mZXJpb3IgZGUgbGEgY2FqYS4NCiogKipNZWRpYW5hKio6IExhIGzDrW5lYSBncnVlc2EgZGVudHJvIGRlIGNhZGEgcmVjdMOhbmd1bG8uDQoqICoqVGVyY2VyIGN1YXJ0aWwqKjogTGEgcGFydGUgc3VwZXJpb3IgZGUgbGEgY2FqYQ0KKiAqKk91dGxpZXJzKio6IHNvbiBsb3MgdmFsb3JlcyBleHRyZW1vcyBpZGVudGlmaWNhZG9zIGNvbiBwdW50b3MuDQoNCkEgZXN0ZSBncsOhZmljbyBsbyBjb21iaW5hbW9zIGNvbiB1biBzY2F0dGVycGxvdCBwYXJhIHBvZGVyIHZlciBsYSBjYW50aWRhZCBkZSByZWdpc3Ryb3MuDQoNCmBgYHtyIGJvbDJ9DQpnZ3Bsb3QocmhfYm8sIGFlcyh4ID0gZ2VuZXJvLCB5ID0gc3VlbGRvX2JydXRvLCBmaWxsID0gZ2VuZXJvKSkgKw0KICBnZW9tX2JveHBsb3QoYWxwaGEgPSAwLjYpICsNCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDAuMDgpLCBzaXplID0gMikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBnZW5lcm8pICsNCiAgZXN0aWxvaCArIA0KICBlamVfeV9uICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGRlIHN1ZWxkb3MgcG9yIGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIEJvbGl2aWEgLSBFbiBCcy4iLA0KICAgICAgIHggPSAiIiwgeSA9ICJCb2xpdmlhbm8gQnMiLA0KICAgICAgIGZpbGwgPSAiR8OpbmVybyIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCg0KYGBgDQoNCkVuIGVsIHNpZ3VpZW50ZSBncsOhZmljbyBwb2RlbW9zIHZlciBsb3Mgc3VlbGRvcyBwcm9tZWRpb3MgcGFyYSBjYWRhIHBvc2ljacOzbiB5IGfDqW5lcm8uIEVuIGFsZ3VuYXMgcG9zaWNpb25lcyB5IGfDqW5lcm8gc8OzbG8gdGVuZW1vcyB1bmEgc29sYSByZXNwdWVzdGEsIHBvciBlc28gbGFzIGJhcnJhcyBkZSBlcnJvciBubyBhcGFyZWNlbi4NCg0KYGBge3IgYm9sM30NCg0KcmhfYm8gJT4lIA0KICBncm91cF9ieShwdWVzdG8sIGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2Uoc3VlbGRvcCA9IGxpc3QobWVhbl9zZShzdWVsZG9fYnJ1dG8pKSkgJT4lIA0KICB1bm5lc3QoY29scyA9IGMoc3VlbGRvcCkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmN0X3JldihwdWVzdG8pLCB5ID0geSwgZmlsbCA9IGdlbmVybykpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSB5bWluLHltYXggPSB5bWF4KSwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICIjMzMzZTQ3IikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoeD15LCAwKSwgYmlnLm1hcmsgPSAiLiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2ltYWwubWFyayA9ICIsIiksDQogICAgICAgICAgICAgICB2anVzdCA9IDEuNSwgZm9udGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLA0KICAgICAgICAgICBzaXplID0gNCwgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICBmYW1pbHkgPSAiUm9ib3RvIikgKw0KICBlamVfeV9uICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZ2VuZXJvKSArDQogIGxhYnModGl0bGUgPSAiU2FsYXJpbyBwcm9tZWRpbyBwb3IgcHVlc3RvIHkgZ8OpbmVybyIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgQm9saXZpYSBCcy4iLA0KICAgICAgIGNhcHRpb24gPSBwYXN0ZTAoZnVlbnRlKSwNCiAgICAgICBmaWxsID0gIkfDqW5lcm8iLA0KICAgICAgIHggPSAiIiwgeSA9ICJCb2xpdmlhbm9zIEJzIikgKyANCiAgZXN0aWxvaA0KYGBgDQoNCiMjIyBBbsOhbGlzaXMgcG9yIGZ1bmNpb25lcw0KDQpgYGB7ciBib2xfcm9sfQ0KcmhfYm8gJT4lIA0KICBncm91cF9ieShmdW5jaW9uKSAlPiUgDQogIHN1bW1hcmlzZShzdWVsZG9fcHJvbWVkaW8gPSBtZWFuKHN1ZWxkb19icnV0bykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gc3VlbGRvX3Byb21lZGlvLCANCiAgICAgICAgICAgICB5ID0gcmVvcmRlcihmdW5jaW9uLCBzdWVsZG9fcHJvbWVkaW8pKSkgKw0KICBnZW9tX2NvbChmaWxsID0gYXp1bCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoc3VlbGRvX3Byb21lZGlvLCAwKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaWcubWFyayA9ICIuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiKSwNCiAgICAgICAgICAgIGhqdXN0ID0gMS41LCBmb250ZmFjZSA9ICJib2xkIiksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksDQogICAgICAgICAgICBzaXplID0gMywgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICAgZmFtaWx5ID0gIlJvYm90byIpICsNCiAgZWplX3hfbiArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIlN1ZWxkbyBwcm9tZWRpbyBwb3IgZnVuY2nDs24iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIEJvbGl2aWEgZW4gQnMuIiwNCiAgICAgICB4ID0gIkJvbGl2aWEgQnMuIiwNCiAgICAgICB5ID0gIiIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICB0aGVtZShwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiKQ0KYGBgDQoNCg0KIyMjIEFuw6FsaXNpcyBwb3IgcnVicm9zDQoNClZlYW1vcyBjdcOhbGVzIHNvbiBsb3MgcnVicm9zIG1lam9yIHBhZ29zIGVuIEJvbGl2aWEuDQoNCmBgYHtyIGJvbF9ydWJyb30NCnJoX2JvICU+JSANCiAgZ3JvdXBfYnkocnVicm8pICU+JSANCiAgc3VtbWFyaXNlKHN1ZWxkb19wcm9tZWRpbyA9IG1lYW4oc3VlbGRvX2JydXRvKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBzdWVsZG9fcHJvbWVkaW8sIA0KICAgICAgICAgICAgIHkgPSByZW9yZGVyKHJ1YnJvLCBzdWVsZG9fcHJvbWVkaW8pKSkgKw0KICBnZW9tX2NvbChmaWxsID0gYXp1bCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoc3VlbGRvX3Byb21lZGlvLCAwKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaWcubWFyayA9ICIuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiKSwNCiAgICAgICAgICAgIGhqdXN0ID0gMS41LCBmb250ZmFjZSA9ICJib2xkIiksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksDQogICAgICAgICAgICBzaXplID0gMywgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICAgZmFtaWx5ID0gIlJvYm90byIpICsNCiAgZWplX3hfbiArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIlN1ZWxkbyBwcm9tZWRpbyBwb3IgcnVicm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIEJvbGl2aWEgZW4gQnMuIiwNCiAgICAgICB4ID0gIkJvbGl2aWFub3MgQnMiLA0KICAgICAgIHkgPSAiIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIpDQpgYGANCg0KDQojIyBDb3N0YSBSaWNhDQoNCmBgYHtyIGNyMX0NCiMgQW7DoWxpc2lzIENvc3RhIFJpY2ENCnJoX2NyIDwtIGtpd2kyMSAlPiUgDQogIGZpbHRlcihwYWlzID09ICJDb3N0YSBSaWNhIikNCg0KYGBgDQoNCiMjIyBBbsOhbGlzaXMgc2FsYXJpYWwgcG9yIGfDqW5lcm8geSBwdWVzdG9zDQoNCkVuIGVsIHNpZ3VpZW50ZSBncsOhZmljbyBwb2RlbW9zIHZlciBsYSBkaXN0cmlidWNpw7NuIGRlIGxvcyBzdWVsZG9zIHBvciBnw6luZXJvLiBFbiBlc3RlIHRpcG8gZGUgZ3LDoWZpY29zLCBsbGFtYWRvcyBib3hwbG90cyBwb2RlbW9zIHZlcjoNCg0KKiAqKlByaW1lciBjdWFydGlsKio6IExhIHBhcnRlIGluZmVyaW9yIGRlIGxhIGNhamEuDQoqICoqTWVkaWFuYSoqOiBMYSBsw61uZWEgZ3J1ZXNhIGRlbnRybyBkZSBjYWRhIHJlY3TDoW5ndWxvLg0KKiAqKlRlcmNlciBjdWFydGlsKio6IExhIHBhcnRlIHN1cGVyaW9yIGRlIGxhIGNhamENCiogKipPdXRsaWVycyoqOiBzb24gbG9zIHZhbG9yZXMgZXh0cmVtb3MgaWRlbnRpZmljYWRvcyBjb24gcHVudG9zLg0KDQpBIGVzdGUgZ3LDoWZpY28gbG8gY29tYmluYW1vcyBjb24gdW4gc2NhdHRlcnBsb3QgcGFyYSBwb2RlciB2ZXIgbGEgY2FudGlkYWQgZGUgcmVnaXN0cm9zLg0KDQpgYGB7ciBjcjJ9DQpnZ3Bsb3QocmhfY3IsIGFlcyh4ID0gZ2VuZXJvLCB5ID0gc3VlbGRvX2JydXRvLCBmaWxsID0gZ2VuZXJvKSkgKw0KICBnZW9tX2JveHBsb3QoYWxwaGEgPSAwLjYpICsNCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDAuMDgpLCBzaXplID0gMikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBnZW5lcm8pICsNCiAgZXN0aWxvaCArIA0KICBlamVfeV9uICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGRlIHN1ZWxkb3MgcG9yIGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIENvc3RhIFJpY2EgLSBlbiBDUkMiLA0KICAgICAgIHggPSAiIiwgeSA9ICJDb2xvbmVzIMKiIiwNCiAgICAgICBmaWxsID0gIkfDqW5lcm8iLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQoNCmBgYA0KDQpFbiBlbCBzaWd1aWVudGUgZ3LDoWZpY28gcG9kZW1vcyB2ZXIgbG9zIHN1ZWxkb3MgcHJvbWVkaW9zIHBhcmEgY2FkYSBwb3NpY2nDs24geSBnw6luZXJvLiBFbiBhbGd1bmFzIHBvc2ljaW9uZXMgeSBnw6luZXJvIHPDs2xvIHRlbmVtb3MgdW5hIHNvbGEgcmVzcHVlc3RhLCBwb3IgZXNvIGxhcyBiYXJyYXMgZGUgZXJyb3Igbm8gYXBhcmVjZW4uDQoNCmBgYHtyIGNyM30NCnJoX2NyICU+JSANCiAgZ3JvdXBfYnkocHVlc3RvLCBnZW5lcm8pICU+JSANCiAgc3VtbWFyaXNlKHN1ZWxkb3AgPSBsaXN0KG1lYW5fc2Uoc3VlbGRvX2JydXRvKSkpICU+JSANCiAgdW5uZXN0KGNvbHMgPSBjKHN1ZWxkb3ApKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZjdF9yZXYocHVlc3RvKSwgeSA9IHksIGZpbGwgPSBnZW5lcm8pKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0geW1pbix5bWF4ID0geW1heCksIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiIzMzM2U0NyIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGNvbW1hKHJvdW5kKHg9eSwgMCksIGJpZy5tYXJrID0gIi4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNpbWFsLm1hcmsgPSAiLCIpLA0KICAgICAgICAgICAgICAgdmp1c3QgPSAxLjUsIGZvbnRmYWNlID0gImJvbGQiKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSwNCiAgICAgICAgICAgc2l6ZSA9IDQsIGNvbG9yID0gIndoaXRlIiwNCiAgICAgICAgICAgZmFtaWx5ID0gIlJvYm90byIpICsNCiAgZWplX3lfbiArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGdlbmVybykgKw0KICBsYWJzKHRpdGxlID0gIlNhbGFyaW8gcHJvbWVkaW8gcG9yIHB1ZXN0byB5IGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIENvc3RhIFJpY2EgZW4gQ1JDIiwNCiAgICAgICBjYXB0aW9uID0gcGFzdGUwKGZ1ZW50ZSksDQogICAgICAgZmlsbCA9ICJHw6luZXJvIiwNCiAgICAgICB4ID0gIiIsIHkgPSAiQ29sb25lcyDCoiIpICsgDQogIGVzdGlsb2gNCmBgYA0KDQojIyMgQW7DoWxpc2lzIHBvciBmdW5jaW9uZXMNCg0KYGBge3IgY3Jfcm9sfQ0KcmhfY3IgJT4lIA0KICBncm91cF9ieShmdW5jaW9uKSAlPiUgDQogIHN1bW1hcmlzZShzdWVsZG9fcHJvbWVkaW8gPSBtZWFuKHN1ZWxkb19icnV0bykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gc3VlbGRvX3Byb21lZGlvLCANCiAgICAgICAgICAgICB5ID0gcmVvcmRlcihmdW5jaW9uLCBzdWVsZG9fcHJvbWVkaW8pKSkgKw0KICBnZW9tX2NvbChmaWxsID0gYXp1bCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoc3VlbGRvX3Byb21lZGlvLCAwKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaWcubWFyayA9ICIuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiKSwNCiAgICAgICAgICAgIGhqdXN0ID0gMS41LCBmb250ZmFjZSA9ICJib2xkIiksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksDQogICAgICAgICAgICBzaXplID0gMywgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICAgZmFtaWx5ID0gIlJvYm90byIpICsNCiAgZWplX3hfbiArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIlN1ZWxkbyBwcm9tZWRpbyBwb3IgZnVuY2nDs24iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIENvc3RhIFJpY2EgZW4gQ1JDIiwNCiAgICAgICB4ID0gIkNvbG9uZXMgwqIiLA0KICAgICAgIHkgPSAiIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIpDQpgYGANCg0KDQojIyMgQW7DoWxpc2lzIHBvciBydWJyb3MNCg0KVmVhbW9zIGN1w6FsZXMgc29uIGxvcyBydWJyb3MgbWVqb3IgcGFnb3MgZW4gQ29zdGEgUmljYS4NCg0KYGBge3IgY3JfcnVicm99DQpyaF9jciAlPiUgDQogIGdyb3VwX2J5KHJ1YnJvKSAlPiUgDQogIHN1bW1hcmlzZShzdWVsZG9fcHJvbWVkaW8gPSBtZWFuKHN1ZWxkb19icnV0bykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gc3VlbGRvX3Byb21lZGlvLCANCiAgICAgICAgICAgICB5ID0gcmVvcmRlcihydWJybywgc3VlbGRvX3Byb21lZGlvKSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9IGF6dWwpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGNvbW1hKHJvdW5kKHN1ZWxkb19wcm9tZWRpbywgMCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmlnLm1hcmsgPSAiLiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2ltYWwubWFyayA9ICIsIiksDQogICAgICAgICAgICBoanVzdCA9IDEuNSwgZm9udGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLA0KICAgICAgICAgICAgc2l6ZSA9IDMsIGNvbG9yID0gIndoaXRlIiwNCiAgICAgICAgICAgIGZhbWlseSA9ICJSb2JvdG8iKSArDQogIGVqZV94X24gKw0KICBlc3RpbG92ICsNCiAgbGFicyh0aXRsZSA9ICJTdWVsZG8gcHJvbWVkaW8gcG9yIHJ1YnJvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEYXRvcyBkZSBDb3N0YSBSaWNhIGVuIENSQyIsDQogICAgICAgeCA9ICJDb2xvbmVzIMKiIiwNCiAgICAgICB5ID0gIiIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICB0aGVtZShwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiKQ0KYGBgDQoNCg0KIyMgVXJ1Z3VheQ0KDQpgYGB7ciB1eTF9DQojIEFuw6FsaXNpcyBVcnVndWF5DQpyaF91eSA8LSBraXdpMjEgJT4lIA0KICBmaWx0ZXIocGFpcyA9PSAiVXJ1Z3VheSIpDQoNCg0KDQpgYGANCg0KIyMjIEFuw6FsaXNpcyBzYWxhcmlhbCBwb3IgZ8OpbmVybyB5IHB1ZXN0b3MNCg0KRW4gZWwgc2lndWllbnRlIGdyw6FmaWNvIHBvZGVtb3MgdmVyIGxhIGRpc3RyaWJ1Y2nDs24gZGUgbG9zIHN1ZWxkb3MgcG9yIGfDqW5lcm8uIEVuIGVzdGUgdGlwbyBkZSBncsOhZmljb3MsIGxsYW1hZG9zIGJveHBsb3RzIHBvZGVtb3MgdmVyOg0KDQoqICoqUHJpbWVyIGN1YXJ0aWwqKjogTGEgcGFydGUgaW5mZXJpb3IgZGUgbGEgY2FqYS4NCiogKipNZWRpYW5hKio6IExhIGzDrW5lYSBncnVlc2EgZGVudHJvIGRlIGNhZGEgcmVjdMOhbmd1bG8uDQoqICoqVGVyY2VyIGN1YXJ0aWwqKjogTGEgcGFydGUgc3VwZXJpb3IgZGUgbGEgY2FqYQ0KKiAqKk91dGxpZXJzKio6IHNvbiBsb3MgdmFsb3JlcyBleHRyZW1vcyBpZGVudGlmaWNhZG9zIGNvbiBwdW50b3MuDQoNCkEgZXN0ZSBncsOhZmljbyBsbyBjb21iaW5hbW9zIGNvbiB1biBzY2F0dGVycGxvdCBwYXJhIHBvZGVyIHZlciBsYSBjYW50aWRhZCBkZSByZWdpc3Ryb3MuDQoNCmBgYHtyIHV5Mn0NCmdncGxvdChyaF91eSwgYWVzKHggPSBnZW5lcm8sIHkgPSBzdWVsZG9fYnJ1dG8sIGZpbGwgPSBnZW5lcm8pKSArDQogIGdlb21fYm94cGxvdChhbHBoYSA9IDAuNikgKw0KICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gMC4wOCksIHNpemUgPSAyKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGdlbmVybykgKw0KICBlc3RpbG9oICsgDQogIGVqZV95X24gKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gZGUgc3VlbGRvcyBwb3IgZ8OpbmVybyIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgVXJ1Z3VheSAtIGVuIFVZVSIsDQogICAgICAgeCA9ICIiLCB5ID0gIlBlc29zICQiLA0KICAgICAgIGZpbGwgPSAiR8OpbmVybyIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCg0KYGBgDQoNCkVuIGVsIHNpZ3VpZW50ZSBncsOhZmljbyBwb2RlbW9zIHZlciBsb3Mgc3VlbGRvcyBwcm9tZWRpb3MgcGFyYSBjYWRhIHBvc2ljacOzbiB5IGfDqW5lcm8uIEVuIGFsZ3VuYXMgcG9zaWNpb25lcyB5IGfDqW5lcm8gc8OzbG8gdGVuZW1vcyB1bmEgc29sYSByZXNwdWVzdGEsIHBvciBlc28gbGFzIGJhcnJhcyBkZSBlcnJvciBubyBhcGFyZWNlbi4NCg0KYGBge3IgdXkzfQ0KcmhfdXkgJT4lIA0KICBncm91cF9ieShwdWVzdG8sIGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2Uoc3VlbGRvcCA9IGxpc3QobWVhbl9zZShzdWVsZG9fYnJ1dG8pKSkgJT4lIA0KICB1bm5lc3QoY29scyA9IGMoc3VlbGRvcCkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmN0X3JldihwdWVzdG8pLCB5ID0geSwgZmlsbCA9IGdlbmVybykpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSB5bWluLHltYXggPSB5bWF4KSwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICIjMzMzZTQ3IikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoeD15LCAwKSwgYmlnLm1hcmsgPSAiLiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2ltYWwubWFyayA9ICIsIiksDQogICAgICAgICAgICAgICB2anVzdCA9IDEuNSwgZm9udGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLA0KICAgICAgICAgICBzaXplID0gNCwgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICBmYW1pbHkgPSAiUm9ib3RvIikgKw0KICBlamVfeV9uICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZ2VuZXJvKSArDQogIGxhYnModGl0bGUgPSAiU2FsYXJpbyBwcm9tZWRpbyBwb3IgcHVlc3RvIHkgZ8OpbmVybyIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgVXJ1Z3VheSBlbiBVWVUiLA0KICAgICAgIGNhcHRpb24gPSBwYXN0ZTAoZnVlbnRlKSwNCiAgICAgICBmaWxsID0gIkfDqW5lcm8iLA0KICAgICAgIHggPSAiIiwgeSA9ICJQZXNvcyAkIikgKyANCiAgZXN0aWxvaA0KYGBgDQoNCiMjIyBBbsOhbGlzaXMgcG9yIGZ1bmNpb25lcw0KDQpgYGB7ciB1eV9yb2x9DQpyaF91eSAlPiUgDQogIGdyb3VwX2J5KGZ1bmNpb24pICU+JSANCiAgc3VtbWFyaXNlKHN1ZWxkb19wcm9tZWRpbyA9IG1lYW4oc3VlbGRvX2JydXRvKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBzdWVsZG9fcHJvbWVkaW8sIA0KICAgICAgICAgICAgIHkgPSByZW9yZGVyKGZ1bmNpb24sIHN1ZWxkb19wcm9tZWRpbykpKSArDQogIGdlb21fY29sKGZpbGwgPSBhenVsKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShyb3VuZChzdWVsZG9fcHJvbWVkaW8sIDApLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpZy5tYXJrID0gIi4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNpbWFsLm1hcmsgPSAiLCIpLA0KICAgICAgICAgICAgaGp1c3QgPSAxLjUsIGZvbnRmYWNlID0gImJvbGQiKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSwNCiAgICAgICAgICAgIHNpemUgPSAzLCBjb2xvciA9ICJ3aGl0ZSIsDQogICAgICAgICAgICBmYW1pbHkgPSAiUm9ib3RvIikgKw0KICBlamVfeF9uICsNCiAgZXN0aWxvdiArDQogIGxhYnModGl0bGUgPSAiU3VlbGRvIHByb21lZGlvIHBvciBmdW5jacOzbiIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgVXJ1Z3VheSBlbiBVWVUiLA0KICAgICAgIHggPSAiUGVzb3MgJCIsDQogICAgICAgeSA9ICIiLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpICsNCiAgdGhlbWUocGxvdC50aXRsZS5wb3NpdGlvbiA9ICJwbG90IikNCmBgYA0KDQoNCiMjIyBBbsOhbGlzaXMgcG9yIHJ1YnJvcw0KDQpWZWFtb3MgY3XDoWxlcyBzb24gbG9zIHJ1YnJvcyBtZWpvciBwYWdvcyBlbiBVcnVndWF5Lg0KDQpgYGB7ciB1eV9ydWJyb30NCnJoX3V5ICU+JSANCiAgZ3JvdXBfYnkocnVicm8pICU+JSANCiAgc3VtbWFyaXNlKHN1ZWxkb19wcm9tZWRpbyA9IG1lYW4oc3VlbGRvX2JydXRvKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBzdWVsZG9fcHJvbWVkaW8sIA0KICAgICAgICAgICAgIHkgPSByZW9yZGVyKHJ1YnJvLCBzdWVsZG9fcHJvbWVkaW8pKSkgKw0KICBnZW9tX2NvbChmaWxsID0gYXp1bCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoc3VlbGRvX3Byb21lZGlvLCAwKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaWcubWFyayA9ICIuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiKSwNCiAgICAgICAgICAgIGhqdXN0ID0gMS41LCBmb250ZmFjZSA9ICJib2xkIiksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksDQogICAgICAgICAgICBzaXplID0gMywgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICAgZmFtaWx5ID0gIlJvYm90byIpICsNCiAgZWplX3hfbiArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIlN1ZWxkbyBwcm9tZWRpbyBwb3IgcnVicm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIFVydWd1YXkgZW4gVVlVIiwNCiAgICAgICB4ID0gIlBlc29zICQiLA0KICAgICAgIHkgPSAiIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIpDQpgYGANCg0KDQojIyBDaGlsZQ0KDQpgYGB7ciBjbDF9DQojIEFuw6FsaXNpcyBDaGlsZQ0KcmhfY2wgPC0ga2l3aTIxICU+JSANCiAgZmlsdGVyKHBhaXMgPT0gIkNoaWxlIikNCg0KDQoNCmBgYA0KDQojIyMgQW7DoWxpc2lzIHNhbGFyaWFsIHBvciBnw6luZXJvIHkgcHVlc3Rvcw0KDQpFbiBlbCBzaWd1aWVudGUgZ3LDoWZpY28gcG9kZW1vcyB2ZXIgbGEgZGlzdHJpYnVjacOzbiBkZSBsb3Mgc3VlbGRvcyBwb3IgZ8OpbmVyby4gRW4gZXN0ZSB0aXBvIGRlIGdyw6FmaWNvcywgbGxhbWFkb3MgYm94cGxvdHMgcG9kZW1vcyB2ZXI6DQoNCiogKipQcmltZXIgY3VhcnRpbCoqOiBMYSBwYXJ0ZSBpbmZlcmlvciBkZSBsYSBjYWphLg0KKiAqKk1lZGlhbmEqKjogTGEgbMOtbmVhIGdydWVzYSBkZW50cm8gZGUgY2FkYSByZWN0w6FuZ3Vsby4NCiogKipUZXJjZXIgY3VhcnRpbCoqOiBMYSBwYXJ0ZSBzdXBlcmlvciBkZSBsYSBjYWphDQoqICoqT3V0bGllcnMqKjogc29uIGxvcyB2YWxvcmVzIGV4dHJlbW9zIGlkZW50aWZpY2Fkb3MgY29uIHB1bnRvcy4NCg0KQSBlc3RlIGdyw6FmaWNvIGxvIGNvbWJpbmFtb3MgY29uIHVuIHNjYXR0ZXJwbG90IHBhcmEgcG9kZXIgdmVyIGxhIGNhbnRpZGFkIGRlIHJlZ2lzdHJvcy4NCg0KYGBge3IgY2wyfQ0KZ2dwbG90KHJoX2NsLCBhZXMoeCA9IGdlbmVybywgeSA9IHN1ZWxkb19icnV0bywgZmlsbCA9IGdlbmVybykpICsNCiAgZ2VvbV9ib3hwbG90KGFscGhhID0gMC42KSArDQogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjA4KSwgc2l6ZSA9IDIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZ2VuZXJvKSArDQogIGVzdGlsb2ggKyANCiAgZWplX3lfbiArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVjacOzbiBkZSBzdWVsZG9zIHBvciBnw6luZXJvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEYXRvcyBkZSBDaGlsZSAtIGVuIENMUCIsDQogICAgICAgeCA9ICIiLCB5ID0gIlBlc29zICQiLA0KICAgICAgIGZpbGwgPSAiR8OpbmVybyIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCg0KYGBgDQoNCkVuIGVsIHNpZ3VpZW50ZSBncsOhZmljbyBwb2RlbW9zIHZlciBsb3Mgc3VlbGRvcyBwcm9tZWRpb3MgcGFyYSBjYWRhIHBvc2ljacOzbiB5IGfDqW5lcm8uIEVuIGFsZ3VuYXMgcG9zaWNpb25lcyB5IGfDqW5lcm8gc8OzbG8gdGVuZW1vcyB1bmEgc29sYSByZXNwdWVzdGEsIHBvciBlc28gbGFzIGJhcnJhcyBkZSBlcnJvciBubyBhcGFyZWNlbi4NCg0KYGBge3IgY2wzfQ0KcmhfY2wgJT4lIA0KICBncm91cF9ieShwdWVzdG8sIGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2Uoc3VlbGRvcCA9IGxpc3QobWVhbl9zZShzdWVsZG9fYnJ1dG8pKSkgJT4lIA0KICB1bm5lc3QoY29scyA9IGMoc3VlbGRvcCkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmN0X3JldihwdWVzdG8pLCB5ID0geSwgZmlsbCA9IGdlbmVybykpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSB5bWluLHltYXggPSB5bWF4KSwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICIjMzMzZTQ3IikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoeD15LCAwKSwgYmlnLm1hcmsgPSAiLiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2ltYWwubWFyayA9ICIsIiksDQogICAgICAgICAgICAgICB2anVzdCA9IDEuNSwgZm9udGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLA0KICAgICAgICAgICBzaXplID0gNCwgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICBmYW1pbHkgPSAiUm9ib3RvIikgKw0KICBlamVfeV9uICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZ2VuZXJvKSArDQogIGxhYnModGl0bGUgPSAiU2FsYXJpbyBwcm9tZWRpbyBwb3IgcHVlc3RvIHkgZ8OpbmVybyIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgQ2hpbGUgZW4gQ0xQIiwNCiAgICAgICBjYXB0aW9uID0gcGFzdGUwKGZ1ZW50ZSksDQogICAgICAgZmlsbCA9ICJHw6luZXJvIiwNCiAgICAgICB4ID0gIiIsIHkgPSAiUGVzb3MgJCIpICsgDQogIGVzdGlsb2gNCmBgYA0KDQojIyMgQW7DoWxpc2lzIHBvciBmdW5jaW9uZXMNCg0KYGBge3IgY2xfcm9sfQ0KcmhfY2wgJT4lIA0KICBncm91cF9ieShmdW5jaW9uKSAlPiUgDQogIHN1bW1hcmlzZShzdWVsZG9fcHJvbWVkaW8gPSBtZWFuKHN1ZWxkb19icnV0bykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gc3VlbGRvX3Byb21lZGlvLCANCiAgICAgICAgICAgICB5ID0gcmVvcmRlcihmdW5jaW9uLCBzdWVsZG9fcHJvbWVkaW8pKSkgKw0KICBnZW9tX2NvbChmaWxsID0gYXp1bCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoc3VlbGRvX3Byb21lZGlvLCAwKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaWcubWFyayA9ICIuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiKSwNCiAgICAgICAgICAgIGhqdXN0ID0gMS41LCBmb250ZmFjZSA9ICJib2xkIiksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksDQogICAgICAgICAgICBzaXplID0gMywgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICAgZmFtaWx5ID0gIlJvYm90byIpICsNCiAgZWplX3hfbiArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIlN1ZWxkbyBwcm9tZWRpbyBwb3IgZnVuY2nDs24iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIENoaWxlIGVuIENMUCIsDQogICAgICAgeCA9ICJQZXNvcyAkIiwNCiAgICAgICB5ID0gIiIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICB0aGVtZShwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiKQ0KYGBgDQoNCg0KIyMjIEFuw6FsaXNpcyBwb3IgcnVicm9zDQoNClZlYW1vcyBjdcOhbGVzIHNvbiBsb3MgcnVicm9zIG1lam9yIHBhZ29zIGVuIENoaWxlLg0KDQpgYGB7ciBjbF9ydWJyb30NCnJoX2NsICU+JSANCiAgZ3JvdXBfYnkocnVicm8pICU+JSANCiAgc3VtbWFyaXNlKHN1ZWxkb19wcm9tZWRpbyA9IG1lYW4oc3VlbGRvX2JydXRvKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBzdWVsZG9fcHJvbWVkaW8sIA0KICAgICAgICAgICAgIHkgPSByZW9yZGVyKHJ1YnJvLCBzdWVsZG9fcHJvbWVkaW8pKSkgKw0KICBnZW9tX2NvbChmaWxsID0gYXp1bCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoc3VlbGRvX3Byb21lZGlvLCAwKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaWcubWFyayA9ICIuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiKSwNCiAgICAgICAgICAgIGhqdXN0ID0gMS41LCBmb250ZmFjZSA9ICJib2xkIiksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksDQogICAgICAgICAgICBzaXplID0gMiwgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICAgZmFtaWx5ID0gIlJvYm90byIpICsNCiAgZWplX3hfbiArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIlN1ZWxkbyBwcm9tZWRpbyBwb3IgcnVicm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIENoaWxlIGVuIENMUCIsDQogICAgICAgeCA9ICJQZXNvcyAkIiwNCiAgICAgICB5ID0gIiIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICB0aGVtZShwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiKQ0KYGBgDQoNCg0KDQojIyBBcmdlbnRpbmENCg0KRW4gZWwgY2FzbyBkZSBBcmdlbnRpbmEsIGNvbW8gY29udGFtb3MgY29uIHVuIGNhdWRhbCBkZSByZXNwdWVzdGFzIG11Y2hvIG3DoXMgYW1wbGlvLCB2YW1vcyBhIHJlYWxpemFyIHVuIGFuw6FsaXNpcyBtw6FzIGRldGFsbGFkby4NCg0KDQpgYGB7ciBhcjF9DQojIEFuw6FsaXNpcyBBcmdlbnRpbmENCnJoX2FyIDwtIGtpd2kyMSAlPiUgDQogIGZpbHRlcihwYWlzID09ICJBcmdlbnRpbmEiKQ0KDQpgYGANCg0KIyMjIEFuw6FsaXNpcyBzYWxhcmlhbCBwb3IgZ8OpbmVybyB5IHB1ZXN0b3MNCg0KRW4gZWwgc2lndWllbnRlIGdyw6FmaWNvIHBvZGVtb3MgdmVyIGxhIGRpc3RyaWJ1Y2nDs24gZGUgbG9zIHN1ZWxkb3MgcG9yIGfDqW5lcm8uIEVuIGVzdGUgdGlwbyBkZSBncsOhZmljb3MsIGxsYW1hZG9zIGJveHBsb3RzIHBvZGVtb3MgdmVyOg0KDQoqICoqUHJpbWVyIGN1YXJ0aWwqKjogTGEgcGFydGUgaW5mZXJpb3IgZGUgbGEgY2FqYS4NCiogKipNZWRpYW5hKio6IExhIGzDrW5lYSBncnVlc2EgZGVudHJvIGRlIGNhZGEgcmVjdMOhbmd1bG8uDQoqICoqVGVyY2VyIGN1YXJ0aWwqKjogTGEgcGFydGUgc3VwZXJpb3IgZGUgbGEgY2FqYQ0KKiAqKk91dGxpZXJzKio6IHNvbiBsb3MgdmFsb3JlcyBleHRyZW1vcyBpZGVudGlmaWNhZG9zIGNvbiBwdW50b3MuDQoNCkEgZXN0ZSBncsOhZmljbyBsbyBjb21iaW5hbW9zIGNvbiB1biBzY2F0dGVycGxvdCBwYXJhIHBvZGVyIHZlciBsYSBjYW50aWRhZCBkZSByZWdpc3Ryb3MuDQoNCmBgYHtyIGFyMn0NCmdncGxvdChyaF9hciwgYWVzKHggPSBnZW5lcm8sIHkgPSBzdWVsZG9fYnJ1dG8sIGZpbGwgPSBnZW5lcm8pKSArDQogIGdlb21fYm94cGxvdChhbHBoYSA9IDAuNykgKw0KICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gMC4wOCksIHNpemUgPSAyLCBhbHBoYSA9IDAuMzUpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZ2VuZXJvKSArDQogIGVzdGlsb2ggKyANCiAgZWplX3lfbiArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVjacOzbiBkZSBzdWVsZG9zIHBvciBnw6luZXJvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEYXRvcyBkZSBBcmdlbnRpbmEgLSBlbiBBUlMiLA0KICAgICAgIHggPSAiIiwgeSA9ICJQZXNvcyAkIiwNCiAgICAgICBmaWxsID0gIkfDqW5lcm8iLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQoNCmBgYA0KDQpFbiBlbCBzaWd1aWVudGUgZ3LDoWZpY28gcG9kZW1vcyB2ZXIgbG9zIHN1ZWxkb3MgcHJvbWVkaW9zIHBhcmEgY2FkYSBwb3NpY2nDs24geSBnw6luZXJvLiANCg0KYGBge3IgYXIzfQ0KcmhfYXIgJT4lIA0KICBncm91cF9ieShwdWVzdG8sIGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2Uoc3VlbGRvcCA9IGxpc3QobWVhbl9zZShzdWVsZG9fYnJ1dG8pKSkgJT4lIA0KICB1bm5lc3QoY29scyA9IGMoc3VlbGRvcCkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmN0X3JldihwdWVzdG8pLCB5ID0geSwgZmlsbCA9IGdlbmVybykpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSB5bWluLHltYXggPSB5bWF4KSwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICIjMzMzZTQ3IikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoeD15LCAwKSwgYmlnLm1hcmsgPSAiLiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2ltYWwubWFyayA9ICIsIiksDQogICAgICAgICAgICAgICB2anVzdCA9IDEuNSwgZm9udGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLA0KICAgICAgICAgICBzaXplID0gMiwgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICBmYW1pbHkgPSAiUm9ib3RvIikgKw0KICBlamVfeV9uICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZ2VuZXJvKSArDQogIGxhYnModGl0bGUgPSAiU2FsYXJpbyBwcm9tZWRpbyBwb3IgcHVlc3RvIHkgZ8OpbmVybyIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgQXJnZW50aW5hIGVuIEFSUyIsDQogICAgICAgY2FwdGlvbiA9IHBhc3RlMChmdWVudGUpLA0KICAgICAgIGZpbGwgPSAiR8OpbmVybyIsDQogICAgICAgeCA9ICIiLCB5ID0gIlBlc29zICQiKSArIA0KICBlc3RpbG9oDQpgYGANCg0KDQpFcyBpbnRlcmVzYW50ZSwgZGUgYWxndW5hIG1hbmVyYSBjb21iaW5hciBsYSBpbmZvcm1hY2nDs24gZGUgbG9zIGdyw6FmaWNvcyBhbnRlcmlvcmVzIHBhcmEgYW5hbGl6YXIgbGEgZGlzdHJpYnVjacOzbiBkZSBsb3Mgc3VlbGRvcyBwYXJhIGNhZGEgcG9zaWNpw7NuOg0KDQpgYGB7ciBhcjR9DQpnZ3Bsb3QocmhfYXIsIGFlcyh4ID0gZmN0X3JldihwdWVzdG8pLCB5ID0gc3VlbGRvX2Z0LCBmaWxsID0gZ2VuZXJvKSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGdlbmVybykgKw0KICBlamVfeV9uICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVjacOzbiBkZSBzdWVsZG9zIHBvciBnw6luZXJvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEYXRvcyBkZSBBcmdlbnRpbmEgLSBlbiBBUlMiLA0KICAgICAgIHggPSAiIiwgeSA9ICIiLCBmaWxsID0gIkfDqW5lcm8iLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9saW5lKGNvbG9yID0gIiNBRUI2QkYiKSwNCiAgICAgICAgcGxvdC50aXRsZS5wb3NpdGlvbiA9ICJwbG90IikNCmBgYA0KDQoNCkNvbiBlc3RvcyBkYXRvcyBwb2RlbW9zIHJlYWxpemFyIHVuYSB2aXN1YWxpemFjacOzbiBkZSBsb3MgZ2FwcyBzYWxhcmlhbGVzIGVudHJlIGhvbWJyZXMgeSBtdWplcmVzLg0KDQpgYGB7ciBicmVjaGFfMjF9DQpnYXBfc2FsYXJpYWwgPC0gcmhfYXIgJT4lIA0KICBzZWxlY3QoZ2VuZXJvLCBwdWVzdG8sIHN1ZWxkb19mdCkNCg0KYnJlY2hhIDwtIGdhcF9zYWxhcmlhbCAlPiUgDQogIGdyb3VwX2J5KGdlbmVybywgcHVlc3RvKSAlPiUgDQogIHN1bW1hcmlzZShtZWRpYV9zYWxhcmlhbCA9IG1lYW4oc3VlbGRvX2Z0KSkNCg0KDQpicmVjaGFfZ3JhZiA8LSBicmVjaGEgJT4lIA0KICBwaXZvdF93aWRlciguLCBuYW1lc19mcm9tID0gZ2VuZXJvLCB2YWx1ZXNfZnJvbSA9IG1lZGlhX3NhbGFyaWFsKSAlPiUgDQogIG11dGF0ZShicmVjaGEgPSBwZXJjZW50KChgSG9tYnJlIGNpc2AtYE11amVyIGNpc2ApL2BIb21icmUgY2lzYCwgMSksDQogICAgICAgICB4ID0gKGBIb21icmUgY2lzYCArIGBNdWplciBjaXNgKS8yKQ0KDQpnZ3Bsb3QoYnJlY2hhX2dyYWYsIA0KICAgICAgIGFlcyh4ID0gYE11amVyIGNpc2AsIHhlbmQgPSBgSG9tYnJlIGNpc2AsIHkgPSBmY3RfcmV2KHB1ZXN0byksIA0KICAgICAgICAgICBncm91cCA9IHB1ZXN0bywgbGFiZWwgPSBicmVjaGEpKSArDQogIGdlb21fZHVtYmJlbGwoY29sb3IgPSAiIzgwODA4MCIsDQogICAgICAgICAgICAgICAgc2l6ZV94ID0gMywgc2l6ZV94ZW5kID0gMywNCiAgICAgICAgICAgICAgICBjb2xvdXJfeCA9IGNvbG9yZXNbMV0sDQogICAgICAgICAgICAgICAgY29sb3VyX3hlbmQgPSBjb2xvcmVzWzJdKSArDQogIGdlb21fdGV4dChkYXRhID0gYnJlY2hhX2dyYWYsIA0KICAgICAgICAgICAgYWVzKHgsIHB1ZXN0bywgbGFiZWwgPSBicmVjaGEpLCBudWRnZV95ID0gLjIpICsNCiAgbGFicyh0aXRsZSA9ICJCcmVjaGEgc2FsYXJpYWwgcG9yIHB1ZXN0b3MgZGUgUlJISCIsDQogICAgICAgc3VidGl0bGUgPSAiU3VlbGRvcyBwcm9tZWRpb3MgZW4gQXJnZW50aW5hIGVuIEFSUyIsDQogICAgICAgeCA9ICIiLA0KICAgICAgIHkgPSBOVUxMLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIGVqZV94X24gKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JlcykgKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNmYmZjZmMiKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiUm9ib3RvIiksDQogICAgICAgIHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIpDQoNCnJtKGJyZWNoYSwgZ2FwX3NhbGFyaWFsKQ0KDQpgYGANCg0KU2kgY29tcGFyYW1vcyBsb3MgcmVzdWx0YWRvcyBjb24gbGEgW2VkaWNpw7NuIGRlbCAyMDIwXShodHRwczovL3JwdWJzLmNvbS9EYXRhNEhSL2VuY3Vlc3RhLWtpd2ktMjAyMCkgKHNlY2Npw7NuICpTdWVsZG9zIEFyZ2VudGluYSAtPiBEaXN0cmlidWNpw7NuIGRlIHN1ZWxkb3MgcG9yIHB1ZXN0byopIHBvZGVtb3MgYXByZWNpYXIgbGFzIHNpZ3VpZW50ZXMgZGlmZXJlbmNpYXMuIA0KDQpFbiAyMDIwLCBsYSBtYXlvcsOtYSBkZSBsYXMgbWVkaWFuYXMgdGVuw61hbiB2YWxvcmVzIHNpbWlsYXJlcyBlbiBsYSBtYXlvcsOtYSBkZSBsYXMgcG9zaWNpb25lcyBkZSBtYXlvciBqZXJhcnF1w61hIHkgaGFiw61hIHVuYSBwYXJpZGFkIGNhc2kgYWJzb2x1dGEgZW4gZWwgY2FzbyBkZSBsb3MgKipIUkJQKiouIEVuIGVzdGEgZWRpY2nDs24sIHNhbHZvIHBhcmEgZWwgY2FzbyBkZSBsb3MgcmVzcG9uc2FibGVzLCBsYSBtZWRpYW5hIHNhbGFyaWFsIGF1bWVudMOzIHBhcmEgbG9zIGhvbWJyZXMgY2lzLCB5IGVuIGVsIGNhc28gZGUgbGFzIG11amVyZXMgY2lzLCBsYSDDum5pY2EgcG9zaWNpw7NuIGplcsOhcnF1aWNhIHF1ZSB0aWVuZSB1bmEgbWVkaWFuYSBzYWxhcmlhbCBtw6FzIGFsdGEsIGVzIGVuIGVsIHB1ZXN0byBkZSAqKlJlc3BvbnNhYmxlKiouDQoNCkVsIHB1ZXN0byBkZSAqKkFuYWxpc3RhKiogZXMgZWwgw7puaWNvIGNhc28gZG9uZGUgbGEgbWVkaWFuYSBzYWxhcmlhbCBlcyBtw6FzIGFsdGEgcGFyYSBsYXMgbXVqZXJlcyBxdWUgcGFyYSBsb3MgdmFyb25lcywgZWwgZ2FwIHNhbGFyaWFsIGVzIHVuIDUlIG3DoXMgYWx0byBwYXJhIGxhcyBtdWplcmVzIHF1ZSBwYXJhIGxvcyBob21icmVzLCB5IGxhIGRpc3RyaWJ1Y2nDs24gc2FsYXJpYWwgZXMgZXF1aXRhdGl2YSAoYXVucXVlIGhheSB2YXJpYXMgbXVqZXJlcyBjaXMgY29uIHZhbG9yZXMgYWx0b3MpLg0KDQpSZXNwZWN0byBhbCBncsOhZmljbyBkZSBnYXBzIHNhbGFyaWFsZXMsIGVuIGVzdGEgZWRpY2nDs24gY29tcGFyYWRhIGNvbiBsYSBkZSAyMDIwIHBvZGVtb3MgYXByZWNpYXIgcXVlOg0KDQoqIFBhcmEgZWwgcHVlc3RvIGRlICoqR2VyZW50ZSoqLCBsYSBicmVjaGEgc2FsYXJpYWwgc2UgbWFudGllbmUgaWd1YWwuDQoqIFBhcmEgZWwgcHVlc3RvIGRlICoqSmVmZSoqLCBsYSBicmVjaGEgc2FsYXJpYWwgYXVtZW50w7MgNCUgKGRlIHVuIDEyJSBlbiAyMDIwIGEgdW4gMTYlIGVuIDIwMjEpLg0KKiBQYXJhIGVsIHB1ZXN0byBkZSAqKlJlc3BvbnNhYmxlKiogbGEgYnJlY2hhIHNlIHJlZHVqbyBkZSB1biAxNyUgZW4gMjAyMCwgYSB1biA2JSBlbiBsYSBlZGljacOzbiAyMDIxLg0KKiBFbCBtYXlvciBjYW1iaW8gZW4gZWwgYW7DoWxpc2lzIGRlIGdhcHMgc2UgYXByZWNpw7MgZW4gbGEgcG9zaWNpw7NuIGRlICoqSFJCUCoqIGRvbmRlIGVsIGdhcCBwYXPDsyBkZSB1biAzJSBlbiAyMDIwIGEgdW4gMjklIGVuIDIwMjEuDQoqIEVsIHB1ZXN0byBkZSAqKkFuYWxpc3RhKiogZXMgZWwgw7puaWNvIGVuIGRvbmRlIGVsIGdhcCBzYWxhcmlhbCBlcyBmYXZvcmFibGUgcGFyYSBsYXMgbXVqZXJlcyBjaXMsIHBhc2FuZG8gZGUgdW4gZ2FwIGRlIDE3JSBlbiAyMDIwLCBhIHVuIDUlIGEgZmF2b3IgZGUgbGFzIG11amVyZXMuDQoqIFBhcmEgZWwgcHVlc3RvIGRlICoqQWRtaW5pc3RyYXRpdm8qKiBlbCBnYXAgc2FsYXJpYWwgcGFzw7MgZGUgdW4gOCUgZW4gMjAyMCBhIHVuIDE5JSBlbiAyMDIxLg0KDQpEYWRvIHF1ZSBsYSBlbmN1ZXN0YSBlcyBhbsOzbmltYSwgZXMgaW1wb3NpYmxlIHRyYWNrZWFyIGxvcyBjYW1iaW9zLCBwcm9tb2Npb25lcyB5IGF1bWVudG9zIGVuIGxhcyBtaXNtYXMgcGVyc29uYXMgeSBlbXByZXNhcy4gU2Vyw61hIGludGVyZXNhbnRlIGJ1c2NhciBvdHJvcyBhbsOhbGlzaXMgZGUgbWVyY2FkbyBwYXJhIHZlciBzaSBlc3RhIHRlbmRlbmNpYSBzZSByZXBsaWNhIGVuIG90cmFzIGludmVzdGlnYWNpb25lcy4gRXMgc2FiaWRvIHF1ZSBsYSBwYW5kZW1pYSB0dXZvIHVuIGltcGFjdG8gbWF5b3IgZW4gbGEgY2FyZ2EgY29nbml0aXZhIGRlIGxhcyBtdWplcmVzLCBkYWRvIHF1ZSBzdW1hZG8gYSBzdXMgcmVzcG9uc2FiaWxpZGFkZXMgbGFib3JhbGVzLCBsYXMgbXVqZXJlcyB0w61waWNhbWVudGUgc2UgaGFjZW4gY2FyZ28gZGUgbGFzIHRhcmVhcyBkb23DqXN0aWNhcyB5IGRlIGxhIGVkdWNhY2nDs24gZGUgbG9zIGhpam9zIGUgaGlqYXMsIGxvIGN1YWwgdGFtYmnDqW4gaW1wbGljYSB1biBtYXlvciBhY29tcGHDsWFtaWVudG8gdGFtYmnDqW4gZW4gbGFzIGNsYXNlcyBxdWUgZnVlcm9uIHZpcnR1YWxlcyB5IGRlIGxhcyB0YXJlYXMgcGFyYSBlbCBob2dhci4gUGFyYSBkZXRlcm1pbmFyIGVsIGltcGFjdG8gZGUgbGEgY2FyZ2EgY29nbml0aXZhIHkgZGUgdHJhYmFqbyBkZSBsYXMgdGFyZWFzIGRvbcOpc3RpY2FzIHNlcsOtYSBpbXBvcnRhbnRlIGhhY2VyIHVuIGFuw6FsaXNpcyBhZC1ob2MuDQoNCkEgY29udGludWFjacOzbiwgeSBhIG1vZG8gZGUgcmVzdW1lbiwgZGVqYW1vcyB1bmEgY29tcGFyYWNpw7NuIGRlbCBnYXAgc2FsYXJpYWwgZGVsIDIwMjAgdnMuIDIwMjEuDQoNCmBgYHtyfQ0KUHVlc3RvIDwtIGMoIkdlcmVudGUiLCAiSmVmZSIsICJSZXNwb25zYWJsZSIsICJIUkJQIiwgIkFuYWxpc3RhIiwgIkFkbWluaXN0cmF0aXZvIikNCmBHYXAgMjAyMGAgPC0gYygwLjEzLCAwLjEyLCAwLjE3LCAwLjAzLCAwLjE3LCAwLjA4KQ0KYEdhcCAyMDIxYCA8LSBjKDAuMTMsIDAuMTYsIDAuMDYsIDAuMjksIC0wLjA1LCAwLjE5KQ0KDQpnYXBzIDwtIGRhdGEuZnJhbWUoUHVlc3RvLCBgR2FwIDIwMjBgLCBgR2FwIDIwMjFgKQ0KDQpnYXBzIDwtIGdhcHMgJT4lIA0KICBtdXRhdGUoRGlmZXJlbmNpYSA9IEdhcC4yMDIxIC0gR2FwLjIwMjApDQoNCmd0KA0KICBnYXBzDQopICU+JSANCiAgdGFiX2hlYWRlcigNCiAgICB0aXRsZSA9ICJHYXAgU2FsYXJpYWwgcG9yIHB1ZXN0byBlbiBSUkhIIGVuIEFyZ2VudGluYSBwb3IgYcOxbyIsDQogICAgc3VidGl0bGUgPSAiQ29tcGFyYWNpw7NuIEhvbWJyZXMgY2lzIHZzIE11amVyZXMgY2lzIg0KICApICU+JSANCiAgZm10X3BlcmNlbnQoY29sdW1ucyA9IGMoIkdhcC4yMDIwIiwgIkdhcC4yMDIxIiwgIkRpZmVyZW5jaWEiKSwNCiAgICAgICAgICAgICAgZGVjaW1hbHMgPSAwKSAlPiUgDQogIGNvbHNfbGFiZWwoDQogICAgR2FwLjIwMjAgPSAiR2FwIDIwMjAiLA0KICAgIEdhcC4yMDIxID0gIkdhcCAyMDIxIg0KICApICU+JSANCiAgdGFiX3NvdXJjZV9ub3RlKHNvdXJjZV9ub3RlID0gcGFzdGUwKGZ1ZW50ZSwgIiB5IDIwMjAiKSkNCmBgYA0KDQoNCiMjIyBBbsOhbGlzaXMgcG9yIGZ1bmNpb25lcw0KDQpgYGB7ciBhcl9yb2x9DQpyaF9hciAlPiUgDQogIGdyb3VwX2J5KGZ1bmNpb24pICU+JSANCiAgc3VtbWFyaXNlKHN1ZWxkb19wcm9tZWRpbyA9IG1lYW4oc3VlbGRvX2JydXRvKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBzdWVsZG9fcHJvbWVkaW8sIA0KICAgICAgICAgICAgIHkgPSByZW9yZGVyKGZ1bmNpb24sIHN1ZWxkb19wcm9tZWRpbykpKSArDQogIGdlb21fY29sKGZpbGwgPSBhenVsKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShyb3VuZChzdWVsZG9fcHJvbWVkaW8sIDApLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpZy5tYXJrID0gIi4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNpbWFsLm1hcmsgPSAiLCIpLA0KICAgICAgICAgICAgaGp1c3QgPSAxLjUsIGZvbnRmYWNlID0gImJvbGQiKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSwNCiAgICAgICAgICAgIHNpemUgPSAzLCBjb2xvciA9ICJ3aGl0ZSIsDQogICAgICAgICAgICBmYW1pbHkgPSAiUm9ib3RvIikgKw0KICBlamVfeF9uICsNCiAgZXN0aWxvdiArDQogIGxhYnModGl0bGUgPSAiU3VlbGRvIHByb21lZGlvIHBvciBmdW5jacOzbiIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgQXJnZW50aW5hIGVuIEFSUyIsDQogICAgICAgeCA9ICJQZXNvcyAkIiwNCiAgICAgICB5ID0gIiIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICB0aGVtZShwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiKQ0KYGBgDQoNCg0KIyMjIEFuw6FsaXNpcyBwb3IgcnVicm9zDQoNClZlYW1vcyBjdcOhbGVzIHNvbiBsb3MgcnVicm9zIG1lam9yIHBhZ29zIGVuIEFyZ2VudGluYS4NCg0KYGBge3IgYXJfcnVicm99DQpyaF9hciAlPiUgDQogIGdyb3VwX2J5KHJ1YnJvKSAlPiUgDQogIHN1bW1hcmlzZShzdWVsZG9fcHJvbWVkaW8gPSBtZWFuKHN1ZWxkb19icnV0bykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gc3VlbGRvX3Byb21lZGlvLCANCiAgICAgICAgICAgICB5ID0gcmVvcmRlcihydWJybywgc3VlbGRvX3Byb21lZGlvKSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9IGF6dWwpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGNvbW1hKHJvdW5kKHN1ZWxkb19wcm9tZWRpbywgMCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmlnLm1hcmsgPSAiLiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2ltYWwubWFyayA9ICIsIiksDQogICAgICAgICAgICBoanVzdCA9IDEuNSwgZm9udGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLA0KICAgICAgICAgICAgc2l6ZSA9IDIsIGNvbG9yID0gIndoaXRlIiwNCiAgICAgICAgICAgIGZhbWlseSA9ICJSb2JvdG8iKSArDQogIGVqZV94X24gKw0KICBlc3RpbG92ICsNCiAgbGFicyh0aXRsZSA9ICJTdWVsZG8gcHJvbWVkaW8gcG9yIHJ1YnJvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEYXRvcyBkZSBBcmdlbnRpbmEgZW4gQVJTIiwNCiAgICAgICB4ID0gIlBlc29zICQiLA0KICAgICAgIHkgPSAiIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIpDQpgYGANCg0KDQpBaG9yYSBjb21wYXJlbW9zIGxvcyBzdWVsZG9zIHBvciBydWJyb3MgeSBnw6luZXJvcy4gQXF1w60gcG9kcmVtb3MgYXByZWNpYXIgbGFzIGRpZmVyZW5jaWFzIGVudHJlIGxvcyBzdWVsZG9zIHByb21lZGlvcyBkZSBsb3MgaG9tYnJlcyB5IG11amVyZXMgZW4gY2FkYSBydWJyby4NCg0KYGBge3IgYXJfcnVicm8yfQ0KcnVicm9fYXIgPC0gcmhfYXIgJT4lIA0KICBzZWxlY3QocnVicm8sIHN1ZWxkb19mdCkgJT4lIA0KICBncm91cF9ieShydWJybykgJT4lIA0KICBzdW1tYXJpc2UobWVkaWFfc3VlbGRvID0gbWVhbihzdWVsZG9fZnQpLA0KICAgICAgICAgICAgcmVzcHVlc3RhcyA9IG4oKSkgJT4lIA0KICBhcnJhbmdlKC1yZXNwdWVzdGFzKQ0KDQp0b3BfcnVicm9zIDwtIHJ1YnJvX2FyICU+JSANCiAgZmlsdGVyKHJ1YnJvICE9ICJPdHJvcyIsIHJlc3B1ZXN0YXMgPiAxMCkgJT4lIA0KICBwdWxsKHJ1YnJvKQ0KDQojIERpdmlkZSBlbCBsYXJnbyBkZSAncnVicm9zJyBlbiB2YXJpYXMgbMOtbmVhcw0KcmhfYXIkcnVicm8gPC0gc3RyX3dyYXAocmhfYXIkcnVicm8sIHdpZHRoID0gMzApDQoNCg0KcmhfYXIgJT4lIA0KICBmaWx0ZXIocnVicm8gJWluJSB0b3BfcnVicm9zKSAlPiUgDQogIHNlbGVjdChydWJybywgc3VlbGRvX2Z0LCBnZW5lcm8pICU+JSANCiAgZ3JvdXBfYnkocnVicm8sIGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2UobWVkaWFfc3VlbGRvID0gbWVhbihzdWVsZG9fZnQpLA0KICAgICAgICAgICAgcmVzcHVlc3RhcyA9IG4oKSkgJT4lIA0KICBhcnJhbmdlKC1yZXNwdWVzdGFzKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1lZGlhX3N1ZWxkbywgeSA9IHJlb3JkZXIocnVicm8sIG1lZGlhX3N1ZWxkbyksIGZpbGwgPSBnZW5lcm8pKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQobWVkaWFfc3VlbGRvLCAwKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpZy5tYXJrID0gIi4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiKSwNCiAgICAgICAgICAgICAgICBoanVzdCA9IDEuNCwgdmp1c3QgPSAwLjMpLA0KICAgICAgICAgICAgc2l6ZSA9IDMsIA0KICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLCANCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAuOSkpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZ2VuZXJvKSArDQogIGxhYnModGl0bGUgPSAiUHJvbWVkaW8gc2FsYXJpYWwgcG9yIHJ1YnJvIHkgZ8OpbmVybyIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgQXJnZW50aW5hIC0gZW4gQVIkIiwNCiAgICAgICB4ID0gIiIsIHkgPSAiIiwgZmlsbCA9ICJHw6luZXJvIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIGVqZV94X24gKw0KICBlc3RpbG92ICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGxvdC50aXRsZS5wb3NpdGlvbiA9ICJwbG90IikgKw0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlPVRSVUUpKSAgIyBJbnZpZXJ0ZSBlbCBvcmRlbiBkZSBsb3MgY29sb3JlcyBlbiBsYSBsZXllbmRhDQoNCg0Kcm0ocnVicm9fYXIsIHRvcF9ydWJyb3MpDQpgYGANCg0KUG9yIMO6bHRpbW8sIGFuYWxpY2Vtb3MgbG9zIHN1ZWxkb3MgZGUgbG9zIDYgcnVicm9zIGNvbiBtYXlvciBjYW50aWRhZCBkZSByZXNwdWVzdGFzLCB5IHZpc3VhbGljZW1vcyBsYXMgZGlzdHJpYnVjaW9uZXMgZGUgbG9zIHN1ZWxkb3MgcG9yIHB1ZXN0byB5IGfDqW5lcm8uIEVuIGVzdGUgZ3LDoWZpY28gcG9kZW1vcyB2ZXIgbG9zIGN1YXJ0aWxlcyBkZWxpbWl0YW5kbyBsYXMgem9uYXMgc29tYnJlYWRhcywgeSBsYSBtZWRpYW5hIGNvbiBlbCBwdW50byBncmlzLiBMb3MgcHVudG9zIHZpb2xldGFzIHkgdmVyZGVzIHJlcHJlc2VudGFuIGEgbGFzIG11amVyZXMgeSBsb3MgaG9tYnJlcyByZXNwZWN0aXZhbWVudGUgZW4gY2FkYSB1bm8gZGUgbG9zIHB1ZXN0b3MuDQoNCmBgYHtyIGFyX3J1YnJvczN9DQojfCBvdXQud2lkdGggPSAiOTAlIiwNCiN8IGZpZy5oZWlnaHQgPSA3DQoNCnJoX2FyICU+JSANCiAgZmlsdGVyKGdlbmVybyAhPSAiR8OpbmVybyBEaXZlcnNvIiwNCiAgICAgICAgIHB1ZXN0byAhPSAiRGlyZWN0b3IiLA0KICAgICAgICAgcnVicm8gJWluJSBjKCJUZWNub2xvZ8OtYXMgZGUgaW5mb3JtYWNpw7NuIiwgIlNlcnZpY2lvcyBkZSBjb25zdWx0b3LDrWEiLCANCiAgICAgICAgICAgICAgICAgICAgICAiQWxpbWVudGFjacOzbiwgYmViaWRhcyIsICJDb21lcmNpbyIsDQogICAgICAgICAgICAgICAgICAgICAgIlNlcnZpY2lvcyBkZSBzYWx1ZCIsICJTZXJ2aWNpb3MgcHJvZmVzaW9uYWxlcyIpKSAgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBmY3RfcmV2KHB1ZXN0byksIHkgPSBzdWVsZG9fYnJ1dG8pKSArDQogIGdlb21fZWNvbm9kaXN0KHdpZHRoID0gMC41KSArDQogIGdlb21fcG9pbnQoYWVzKHkgPSBzdWVsZG9fYnJ1dG8sIGNvbG9yID0gZ2VuZXJvKSwgYWxwaGEgPSAwLjMsDQogICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjI1KSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyh2ZXJkZSwgbGlsYSkpICsNCiAgZWplX3lfbiArDQogIGNvb3JkX2ZsaXAoKSArDQogIGZhY2V0X3dyYXAofnJ1YnJvLCBuY29sID0gMikgKw0KICBlc3RpbG92ICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIHNhbGFyaWFsIHBvciBwdWVzdG8geSBydWJybyIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgQXJnZW50aW5hIC0gZW4gQVIkIiwNCiAgICAgICB4ID0gIiIsIHkgPSAiIiwgY29sb3IgPSAiR8OpbmVybyIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICB0aGVtZShwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiKQ0KYGBgDQoNCiMjIyBSZWxhY2lvbmVzIGVudHJlIGV4cGVyaWVuY2lhIHkgc3VlbGRvIGJydXRvDQoNCkVuIGVzdGEgc2VjY2nDs24gZGVsIGFuw6FsaXNpcyBidXNjYW1vcyBpZGVudGlmaWNhciBjdcOhbGVzIHNvbiBsb3MgZmFjdG9yZXMgcXVlIGluZmx1eWVuIGVuIGxvcyBpbmdyZXNvcyAoaW5kZXBlbmRpZW50ZW1lbnRlIGRlIGxhIHBvc2ljacOzbiksIGFzw60gcXVlIGVtcGV6YW1vcyBhIGV4cGxvcmFyIGxvcyBkYXRvcy4NCg0KTGEgcHJpbWVyYSBwcmVndW50YSBxdWUgbm9zIGhpY2ltb3MgZnVlIHNpIGxvcyBhw7FvcyBkZSB0cmF5ZWN0b3JpYSBpbmZsdXllbiBlbiBlbCBzdWVsZG8uIE51ZXN0cmEgaGlww7N0ZXNpcyBlcyBxdWUgYSBtYXlvciBjYW50aWRhZCBkZSBhw7FvcyBkZSBleHBlcmllbmNpYSwgbWF5b3IgaWJhIGEgc2VyIGVsIGluZ3Jlc28uDQoNCkxvIHF1ZSB2YW1vcyBhIHZlciBlbiBlbCBzaWd1aWVudGUgZ3LDoWZpY28gZGUgZGlzcGVyc2nDs24sIGVzIGVuIGVsIGVqZSBob3Jpem9udGFsLCBsb3MgYcOxb3MgZGUgZXhwZXJpZW5jaWEsIHkgZW4gZWwgZWplIHZlcnRpY2FsLCBlbCBzdWVsZG8gYnJ1dG8gZXhwcmVzYWRvIGVuIHBlc29zIGFyZ2VudGlub3MuIEx1ZWdvLCB2YW1vcyBhIGdyYWZpY2FyIHVuYSByZWN0YSwgcXVlIG5vcyB2YSBhIGluZGljYXIgbGEgKmZ1ZXJ6YSogZGUgZXNhIHJlbGFjacOzbi4NCg0KDQpgYGB7ciByZWdfbGluZWFsXzF9DQpsbV9yaCA8LSBsbShzdWVsZG9fZnQgfiBhbmlvc19leHBlcmllbmNpYSwgZGF0YSA9IHJoX2FyKQ0KDQpsbV9ocl9yZXN1bHRzIDwtIHN1bW1hcnkobG1fcmgpDQoNCmxtX3JoX3IyIDwtIHJvdW5kKGxtX2hyX3Jlc3VsdHNbWyJyLnNxdWFyZWQiXV0sMykNCg0KZ2dwbG90KHJoX2FyLCBhZXMoeD1hbmlvc19leHBlcmllbmNpYSwgeSA9IHN1ZWxkb19mdCkpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICIjMUZDM0FBIiwgYWxwaGEgPSAwLjQsIHNpemUgPSAyKSArIA0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIlJvYm90byIpKSArDQogIGxhYnModGl0bGUgPSAiUmVsYWNpw7NuIGVudHJlIHN1ZWxkbyB5IGHDsW9zIGRlIGV4cGVyaWVuY2lhIiwNCiAgICAgICB4ID0gIkHDsW9zIGRlIEV4cGVyaWVuY2lhIiwNCiAgICAgICB5ID0gIlN1ZWxkbyBicnV0byAoQVIkKSIsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpICsNCiAgZWplX3lfbiArDQogIGdlb21fdGV4dChhZXMoeD0tSW5mLCB5PUluZiwgaGp1c3Q9MCwgdmp1c3Q9MSwgbGFiZWw9IHBhc3RlMCgiUjIgPSAiLCBsbV9yaF9yMikpKSANCg0KYGBgDQoNCkVuIGVsIGdyw6FmaWNvIHBvZGVtb3MgYXByZWNpYXIgdW5hIHJlY3RhIHF1ZSB2YSBjcmVjaWVuZG8gZWZlY3RpdmFtZW50ZTogYSBtZWRpZGEgcXVlIG5vcyBtb3ZlbW9zIG3DoXMgaGFjaWEgbGEgZGVyZWNoYSwgbGEgcmVjdGEgdmEgc3ViaWVuZG8uIFBlcm8gZWwgJFJeMiQgPSBgciBsbV9yaF9yMmAgbm9zIGluZGljYSBjdcOhbnRvIGV4cGxpY2EgbG9zIGHDsW9zIGRlIGV4cGVyaWVuY2lhIHNvYnJlIGVsIHN1ZWxkbyBicnV0bywgbyBkaWNobyBkZSBvdHJhIG1hbmVyYSwgZW4gcXXDqSBtZWRpZGEgaW5mbHV5ZSBsYSB2YXJpYWJsZSB4IChhw7FvcyBkZSBleHBlcmllbmNpYSksIHNvYnJlIGxhIHZhcmlhYmxlIHkgKHN1ZWxkbyBicnV0bykuIFVuYSBkZWZpbmljacOzbiBtw6FzIHByZWNpc2EgZGUgZXN0ZSB2YWxvciBjb25vY2lkbyBjb21vICoqQ29lZmljaWVudGUgZGUgRGV0ZXJtaW5hY2nDs24qKiBlcyBsYSBwcm9wb3JjacOzbiBkZSBsYSB2YXJpYW56YSB0b3RhbCBkZSBsYSB2YXJpYWJsZSBleHBsaWNhZGEgcG9yIGxhIHJlZ3Jlc2nDs24uDQoNCkVzdGUgdmFsb3IgcHVlZGUgZXN0YXIgZW50cmUgMCB5IDEsIG1pZW50cmFzIG3DoXMgY2VyY2EgZGUgMCBlc3TDoSBtZW5vciBlcyBsYSByZWxhY2nDs24sIHkgbWllbnRyYXMgbcOhcyBjZXJjYSBkZSAxIGVzdMOpIGVsIHJlc3VsdGFkbywgaW5kaWNhIHF1ZSBsYSByZWdyZXNpw7NuIGV4cGxpY2EgbGEgdmFyaWFiaWxpZGFkIGRlIGxhIHZhcmlhYmxlIGRlIHJlc3B1ZXN0YS4gRXMgcG9yIGVzbyBxdWUgZXN0ZSAkUl4yJCA9IGByIGxtX3JoX3IyYCBub3MgaW5kaWNhIHF1ZSBsb3MgYcOxb3MgZGUgZXhwZXJpZW5jaWEgZXhwbGljYW4gdW4gMzEuOCUgZGUgbGEgdmFyaWFiaWxpZGFkIGRlIGxvcyBzdWVsZG9zIGVuIFJSSEguDQoNCiMjIyMgUmVsYWNpw7NuIGVudHJlIGHDsW9zIGRlIGV4cGVyaWVuY2lhIHkgc3VlbGRvIGJydXRvIHBvciBwdWVzdG8uDQoNCkRhZG8gcXVlIGVuIGVsIGdyw6FmaWNvIGFudGVyaW9yIHRlbmVtb3MgbWV6Y2xhZG9zIGxvcyBzdWVsZG9zIGRlIGFkbWluaXN0cmF0aXZvcywgYW5hbGlzdGFzLCBqZWZlcyB5IGdlcmVudGVzLCBkZWNpZGltb3MgYW5hbGl6YXIgbGEgcmVsYWNpw7NuIGVudHJlIGxvcyBhw7FvcyBkZSBleHBlcmllbmNpYSB5IGVsIHN1ZWxkbyBicnV0byBwb3IgY2FkYSB1bm8gZGUgbG9zIHB1ZXN0b3MgcG9yIHNlcGFyYWRvLg0KDQpgYGB7ciByZWdfbGluZWFsXzIsIG91dC53aWR0aD0iOTAlIn0NCg0KbWkuZm9ybXVsYSA8LSB5IH4geA0KDQpnZ3Bsb3QocmhfYXIsIGFlcyh4PWFuaW9zX2V4cGVyaWVuY2lhLCB5ID0gc3VlbGRvX2Z0KSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gIiMxRkMzQUEiLCBhbHBoYSA9IDAuNCwgc2l6ZSA9IDIpICsgDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSBtaS5mb3JtdWxhLCBzZSA9IEZBTFNFKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIlJvYm90byIpKSArDQogIGxhYnModGl0bGUgPSAiUmVsYWNpw7NuIGVudHJlIHN1ZWxkbyB5IGHDsW9zIGRlIGV4cGVyaWVuY2lhIiwNCiAgICAgICB4ID0gIkHDsW9zIGRlIEV4cGVyaWVuY2lhIiwNCiAgICAgICB5ID0gIiIsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpICsNCiAgZWplX3lfbiArDQogIHN0YXRfcG9seV9lcShmb3JtdWxhID0gbWkuZm9ybXVsYSwgDQogICAgICAgICAgICAgICBhZXMobGFiZWwgPSBwYXN0ZSguLnJyLmxhYmVsLi4sIHNlcCA9ICJ+fn4iKSksIA0KICAgICAgICAgICAgICAgcGFyc2UgPSBUUlVFKSArDQogIGZhY2V0X3dyYXAofnB1ZXN0bykNCg0KYGBgDQoNCkNvbW8gcG9kZW1vcyBhcHJlY2lhciBlbiBsb3MgJFJeMiQgZGUgY2FkYSBncsOhZmljbyBlbiBlbCDDum5pY28gcHVlc3RvIGRvbmRlIGVuY29udHJhbW9zIHVuYSBmdWVydGUgcmVsYWNpw7NuIGVudHJlIGxvcyBhw7FvcyBkZSBleHBlcmllbmNpYSB5IGVsIHN1ZWxkbyBicnV0byBlcyBlbiBsb3MgKipIUkJQKiouIEVuIGVsIHJlc3RvIGRlIGxvcyBwdWVzdG9zIGxvcyBhw7FvcyBkZSB0cmF5ZWN0b3JpYSBpbmZsdXllbiBtdXkgcG9jbyBlbiBsb3Mgc3VlbGRvcyBkZSBjYWRhIHVubyBkZSBsb3MgcHVlc3Rvcy4NCg0KQWhvcmEgYmllbiwgbGEgcHJlZ3VudGEgZXMsICrCv2N1w6FsIGVzIGxhIHZhcmlhYmxlIHF1ZSBtw6FzIGluZmx1eWUgZW4gZWwgc3VlbGRvIGVuIFJlY3Vyc29zIEh1bWFub3M/LiogVHJpc3RlbWVudGUsIGxhIHJlc3B1ZXN0YSBubyBzb3JwcmVuZGUuDQoNCmBgYHtyfQ0KZ2dwbG90KHJoX2FyLCBhZXMoeCA9IGdlbmVybywgeSA9IHN1ZWxkb19mdCwgZmlsbCA9IGdlbmVybykpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBlamVfeV9uICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyh2ZXJkZSwgbGlsYSkpICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVjacOzbiBzYWxhcmlhbCBwb3IgZ8OpbmVybyIsDQogICAgICAgeCA9ICIiLCB5ID0gIiIsDQogICAgICAgZmlsbCA9ICJHw6luZXJvIiwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCmBgYA0KDQojIEVkdWNhY2nDs24NCg0KRW4gZXN0YSBzZWNjacOzbiBxdWVyZW1vcyBpbmRhZ2FyIHNpIGhheSByZWxhY2nDs24gZW50cmUgbGEgZm9ybWFjacOzbiB5IGxhIHJlbXVuZXJhY2nDs24sIHkgc2kgaW1wYWN0YSB0YW1iacOpbiBlbCB0aXBvIGRlIHVuaXZlcnNpZGFkLCBww7pibGljYSBvIHByaXZhZGEsIGVuIGxhIHJlbXVuZXJhY2nDs24geSBwb3NpY2nDs24uIFByaW1lcm8gdmVhbW9zIGVudHJlIGxvcyBkaXN0aW50b3MgcGHDrXNlcyBjb21vIHNlIGRpc3RyaWJ1eWUgbGEgbXVlc3RyYSBlbnRyZSBwcm9mZXNpb25hbGVzIHByb3ZlbmllbnRlcyBkZSB1bml2ZXJzaWRhZGVzIHDDumJsaWNhcyB5IHByaXZhZGFzLg0KDQpEYWRvIHF1ZSB0ZW5lbW9zIHJlbGF0aXZhbWVudGUgcG9jYXMgcmVzcHVlc3RhcyBkZSBvdHJvcyBwYcOtc2VzIHF1ZSBubyBzZWFuIEFyZ2VudGluYSwgbm8gcG9kZW1vcyBzYWNhciBuaW5ndW5hIGNvbmNsdXNpw7NuIHNlcmlhLCBzw7NsbyBtZW5jaW9uYXIgcXVlIGVuIEFyZ2VudGluYSwgaGF5IHVuYSB2aXJ0dWFsIHBhcmlkYWQgZW50cmUgbG9zIGVzdHVkaWFudGVzIHkgZ3JhZHVhZG9zIGRlIHVuaXZlcnNpZGFkZXMgcMO6YmxpY2FzIHkgcHJpdmFkYXMuIFBvc3Rlcmlvcm1lbnRlIGFuYWxpemFyZW1vcyBsYSBzaXR1YWNpw7NuIHBvciByZWdpb25lcyBkZW50cm8gZGVsIHBhw61zLg0KDQpMYXMgcHJvcG9yY2lvbmVzIGRlIHJlc3B1ZXN0YXMgc2Vnw7puIGFsIHRpcG8gZGUgdW5pdmVyc2lkYWQgcXVlIGFzaXN0aWVyb24gbG9zIHBhcnRpY2lwYW50ZXMgZGUgbGEgZW5jdWVzdGEgZXMgbGEgc2lndWllbnRlOg0KDQpgYGB7ciB0aXBvX3VuaXZlcnNpZGFkLCBmaWcuc2hvdz0iaG9sZCIsIG91dC53aWR0aD0iNTAlIiwgZmlnLmFsaWduID0gImRlZmF1bHQifQ0Ka2l3aTIxICU+JSANCiAgc2VsZWN0KHBhaXMsIHRpcG9fdW5pdmVyc2lkYWQpICU+JSANCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldihwYWlzKSwgDQogICAgICAgICAgICAgZmlsbCA9IHRpcG9fdW5pdmVyc2lkYWQpKSArDQogICAgICAgICAgIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArIA0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKGdyaXMsIHZlcmRlLCBhenVsKSkgKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gZGUgcmVzcHVlc3RhcyBwb3IgdGlwbyBkZSB1bml2ZXJzaWRhZCBwb3IgcGHDrXMiLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUsIA0KICAgICAgIHggPSAiIiwgeSA9ICIiKSArDQogIGVzdGlsbyArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KDQplZHVjIDwtIGtpd2kyMSAlPiUgDQogIHNlbGVjdCh0aXBvX3VuaXZlcnNpZGFkKSAlPiUgIA0KICBncm91cF9ieSh0aXBvX3VuaXZlcnNpZGFkKSAlPiUgDQogIHN1bW1hcmlzZSAobiA9IG4oKSkgJT4lIA0KICBtdXRhdGUoZnJlcSA9IG4vc3VtKG4pKSAlPiUgDQogIGFycmFuZ2UoLW4pDQoNCiMgQ29tcHV0ZSB0aGUgY3VtdWxhdGl2ZSBwZXJjZW50YWdlcyAodG9wIG9mIGVhY2ggcmVjdGFuZ2xlKQ0KZWR1YyR5bWF4IDwtIGN1bXN1bShlZHVjJGZyZXEpDQoNCiMgQ29tcHV0ZSB0aGUgYm90dG9tIG9mIGVhY2ggcmVjdGFuZ2xlDQplZHVjJHltaW4gPC0gYygwLCBoZWFkKGVkdWMkeW1heCwgbj0tMSkpDQoNCiMgQ29tcHV0ZSBsYWJlbCBwb3NpdGlvbg0KZWR1YyRsYWJlbFBvc2l0aW9uIDwtIChlZHVjJHltYXggKyBlZHVjJHltaW4pIC8gMg0KDQojIENvbXB1dGUgYSBnb29kIGxhYmVsDQplZHVjJGxhYmVsIDwtIHBhc3RlMChlZHVjJHRpcG9fdW5pdmVyc2lkYWQsICJcbiBDYW50OiAiLCBlZHVjJG4pDQoNCiMgTWFrZSB0aGUgcGxvdA0KZ2dwbG90KGVkdWMsIGFlcyh5bWF4PXltYXgsIHltaW49eW1pbiwgeG1heD00LCB4bWluPTMsIGZpbGw9dGlwb191bml2ZXJzaWRhZCkpICsNCiAgZ2VvbV9yZWN0KCkgKw0KICBjb29yZF9wb2xhcih0aGV0YT0ieSIpICsgIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gdW5kZXJzdGFuZCBob3cgdGhlIGNoYXJ0IGlzIGJ1aWx0IGluaXRpYWxseQ0KICB4bGltKGMoMiwgNCkpICsjIFRyeSB0byByZW1vdmUgdGhhdCB0byBzZWUgaG93IHRvIG1ha2UgYSBwaWUgY2hhcnQNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhncmlzLCB2ZXJkZSwgYXp1bCkpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiUm9ib3RvIikpICsNCiAgbGFicyh0aXRsZSA9ICJUaXBvIGRlIFVuaXZlcnNpZGFkIiwNCiAgICAgICBmaWxsID0gIlRpcG8gZGUgVW5pdmVyc2lkYWQiLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJsZWZ0IikNCmBgYA0KDQpMYXMgcHJpbmNpcGFsZXMgY2FycmVyYXMgZGUgbGFzIHBlcnNvbmFzIHF1ZSByZXNwb25kaWVyb24gc29uOg0KDQpgYGB7ciBjYXJyZXJhc30NCmNhcnJlcmFzIDwtIGtpd2kyMSAlPiUgDQogIHNlbGVjdChuaXZlbF9mb3JtYWNpb24sIGNhcnJlcmFfZ3JhZG8sIHRpcG9fdW5pdmVyc2lkYWQsIHRyYWJham8sIA0KICAgICAgICAgc3VlbGRvX2JydXRvLCBwdWVzdG8sIGZ1bmNpb24sIHBhaXMsIGdlbmVybykgJT4lIA0KICBtdXRhdGUoY2FycmVyYV9ncmFkbyA9IGZhY3RvcihjYXJyZXJhX2dyYWRvKSkNCg0KDQpjYXJyZXJhcyA8LSBjYXJyZXJhcyAlPiUgDQogIG11dGF0ZShjYXJyZXJhX2dyYWRvID0gZmN0X2NvbGxhcHNlKGNhcnJlcmFfZ3JhZG8sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ29tdW5pY2FjacOzbiBTb2NpYWwiID0gYygiQ2llbmNpYXMgZGUgbGEgQ29tdW5pY2FjacOzbiIsICJDb211bmljYWNpw7NuIiwgIkNvbXVuaWNhY2nDs24gc29jaWFsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ29tdW5pY2FjacOzbiBTb2NpYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTb3kgTGljZW5jaWFkYSBlbiBDaWVuY2lhcyBDb211bmljYWNpw7NuIHkgRGlwbG9tYWRhIGVuIFJSSEgiKSksIA0KICAgICAgICAgY2FycmVyYV9ncmFkbyA9IGZjdF9jb2xsYXBzZShjYXJyZXJhX2dyYWRvLCAiSW5nZW5pZXLDrWFzIiA9IGMoIkluZ2VuaWVyYSBDb21lcmNpYWwiLCAiSU5HRU5JRVJBIENPTUVSQ0lBTCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbmcuIEdlc3Rpw7NuIEVtcHJlc2FyaWFsIiwgIkluZ2VuaWVyw61hIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkluZ2VuaWVyaWEgY29tZXJjaWFsIiwgIkluZ2VuaWVyw61hIENvbWVyY2lhbCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbmdlbmllcsOtYSBkZSBTaXN0ZW1hcyIsICJJbmdlbmllcsOtYSBJbmR1c3RyaWFsIikpLA0KICAgICAgICAgY2FycmVyYV9ncmFkbyA9IGZjdF9jb2xsYXBzZShjYXJyZXJhX2dyYWRvLCAiUmVsYWNpb25lcyBQw7pibGljYXMiID0gYygiTGljLiBlbiBSZWxhY2lvbmUgUHVibGljYXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMaWMuIGVuIFJlbGFjaW9uZXMgUMO6YmxpY2FzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVsYWNpb25lcyBQw7pibGljYXMgZSBJbnN0aXR1Y2lvbmFsZXMiKSksDQogICAgICAgICBjYXJyZXJhX2dyYWRvID0gZmN0X2NvbGxhcHNlKGNhcnJlcmFfZ3JhZG8sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHNpY29sb2fDrWEiID0gYygiUHNpY29sb2fDrWEiLCAiUHNpY29sb2fDrWEgU29jaWFsIikpLA0KICAgICAgICAgY2FycmVyYV9ncmFkbyA9IGZjdF9sdW1wKGNhcnJlcmFfZ3JhZG8sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3AgPSAwLjAyLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdGhlcl9sZXZlbCA9ICJPdHJhcyIpLA0KICAgICAgICAgY2FycmVyYV9ncmFkbyA9IGZhY3RvcihjYXJyZXJhX2dyYWRvLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlJSSEggLyBSUkxMIC8gUlJUVCIsICJQc2ljb2xvZ8OtYSIsICJBZG1pbmlzdHJhY2nDs24gZGUgRW1wcmVzYXMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNvbnRhZG9yIFDDumJsaWNvIiwgIkluZ2VuaWVyw61hcyIsIkNvbXVuaWNhY2nDs24gU29jaWFsIiwgIk90cmFzIikpKQ0KDQoNCg0KZ2dwbG90KGNhcnJlcmFzLCBhZXMoeSA9IGZjdF9yZXYoY2FycmVyYV9ncmFkbykpKSArIA0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIsIGZpbGwgPSBhenVsKSArDQogIHRoZW1lKHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIpICsgDQogIGxhYnMoeD0iIix5PSIiKSArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIlByaW5jaXBhbGVzIGNhcnJlcmFzIGVzdHVkaWFkYXMiLA0KICAgICAgIHN1YnRpdGxlID0gIlRyYWJhamFkb3JlcyBlbiByZWxhY2nDs24gZGUgZGVwZW5kZW5jaWEiLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQoNCmBgYA0KDQpEYWRhIGxhIGNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgcG9yIHBhw61zLCBlbCBhbsOhbGlzaXMgcXVlIGhhcmVtb3MgZGVzZGUgYXF1w60gZW4gYWRlbGFudGUgc8OzbG8gc2Vyw6EgcGFyYSAqKkFyZ2VudGluYSoqLg0KDQojIyBBbsOhbGlzaXMgZGUgZWR1Y2FjacOzbiB5IHB1ZXN0b3MgcGFyYSBBcmdlbnRpbmENCg0KTHVlZ28sIHBvZGVtb3MgYW5hbGl6YXIgZW4gcXXDqSB0aXBvIGRlIHVuaXZlcnNpZGFkIGVzdHVkaWFyb24gbGFzIHBlcnNvbmFzIHF1ZSByZXNwb25kaWVyb24gbGEgZW5jdWVzdGEsIHNlZ8O6biBlbCBwdWVzdG8gYWN0dWFsIHF1ZSBvY3VwYW4uDQoNCmBgYHtyIHB1ZXN0by11bml2ZXJzaWRhZH0NCnJlY29ydGVfZWR1Y2FjaW9uIDwtIHJoX2FyICU+JQ0KICBmaWx0ZXIocGFpcyA9PSAiQXJnZW50aW5hIikgJT4lIA0KICBzZWxlY3Qobml2ZWxfZm9ybWFjaW9uLCBjYXJyZXJhX2dyYWRvLA0KICAgICAgICAgdGlwb191bml2ZXJzaWRhZCwgdHJhYmFqbywgc3VlbGRvX2JydXRvLCBwdWVzdG8sIGZ1bmNpb24sIHBhaXMsIGdlbmVybykNCg0KZ2dwbG90KHJlY29ydGVfZWR1Y2FjaW9uLCAoYWVzKHggPSBwdWVzdG8sIGZpbGwgPSB0aXBvX3VuaXZlcnNpZGFkKSkpICsgI1RpcG8gZGUgdW5pdmVyc2lkYWQgeSBjYXJnbw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgdGhlbWUocGxvdC50aXRsZS5wb3NpdGlvbiA9ICJwbG90IikgKyANCiAgbGFicyh4PSIiLHk9IiIpICsNCiAgICBlc3RpbG92ICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhncmlzLCB2ZXJkZSwgYXp1bCkpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJDYW50aWRhZCBkZSByZXNwdWVzdGFzIHNlZ8O6biBwdWVzdG8geSB1bml2ZXJzaWRhZCIsDQogICAgICAgc3VidGl0bGUgPSAiU8OzbG8gcmVzcHVlc3RhcyBkZSBBcmdlbnRpbmEiLA0KICAgICAgIHggPSAiIiwgZmlsbCA9ICJUaXBvIGRlIFVuaXZlcnNpZGFkIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogICAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZT1UUlVFKSkgICMgSW52aWVydGUgZWwgb3JkZW4gZGUgbG9zIGNvbG9yZXMgZW4gbGEgbGV5ZW5kYQ0KDQpgYGANCg0KUmVpdGVyZW1vcyBlbCBhbsOhbGlzaXMgcGVybyDDum5pY2FtZW50ZSBwYXJhIGxhcyBjYXJyZXJhcyByZWxhY2lvbmFkYXMgY29uIFJlY3Vyc29zIEh1bWFub3MgeSBSZWxhY2lvbmVzIGRlbCBUcmFiYWpvLg0KDQpgYGB7ciByaC1wc2ljb30NCnJlY29ydGVfZWR1Y2FjaW9uICU+JQ0KICBmaWx0ZXIoY2FycmVyYV9ncmFkbyA9PSAiUlJISCAvIFJSTEwgLyBSUlRUIikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBwdWVzdG8sIGZpbGwgPSB0aXBvX3VuaXZlcnNpZGFkKSkgKyAjVGlwbyBkZSB1bml2ZXJzaWRhZCB5IGNhcmdvDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICB0aGVtZShwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiKSArIA0KICBsYWJzKHg9IiIseT0iIikgKw0KICAgIGVzdGlsb3YgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKGdyaXMsIHZlcmRlLCBhenVsKSkgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgc2Vnw7puIHB1ZXN0byB5IHVuaXZlcnNpZGFkIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJTw7NsbyByZXNwdWVzdGFzIGRlIEFyZ2VudGluYSAtIENhcnJlcmFzIGRlIFJIIiwNCiAgICAgICB4ID0gIiIsIGZpbGwgPSAiVGlwbyBkZSBVbml2ZXJzaWRhZCIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICAgIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2U9VFJVRSkpICAjIEludmllcnRlIGVsIG9yZGVuIGRlIGxvcyBjb2xvcmVzIGVuIGxhIGxleWVuZGENCg0KICANCg0KYGBgDQoNClBvZGVtb3MgYXByZWNpYXIgcXVlIGEgcGFydGlyIGRlIGxvcyBwdWVzdG9zIGRlIGplZmF0dXJhLCBoYXkgbWF5b3IgcHJlc2VuY2lhIGRlIGdyYWR1YWRvcyBwcm92ZW5pZW50ZXMgZGUgdW5pdmVyc2lkYWRlcyBwcml2YWRhcy4NCg0KRW4gQXJnZW50aW5hLCBwb2RlbW9zIHZlciBsYSBzaWd1aWVudGUgZGlzdHJpYnVjacOzbiBwb3IgZ8OpbmVybyB5IG5pdmVsIGVkdWNhdGl2by4NCg0KYGBge3Igbml2ZWwtZWQtZ2VuZXJvfQ0KDQpuZV9zYWxhcmlvIDwtIHJlY29ydGVfZWR1Y2FjaW9uIA0KDQojIEVsaW1pbmEgcmVjb3J0ZV9lZHVjYWNpb24NCnJtKHJlY29ydGVfZWR1Y2FjaW9uKQ0KDQojIEFncnVwYSBjYXRlZ29yw61hcyBkZSBlZHVjYWNpw7NuDQpuZV9zYWxhcmlvIDwtIG5lX3NhbGFyaW8gJT4lIA0KICAgIG11dGF0ZShuaXZlbF9mb3JtYWNpb24gPSBmY3RfY29sbGFwc2Uobml2ZWxfZm9ybWFjaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZWN1bmRhcmlvIGNvbXBsZXRvIiA9IGMoIlNlY3VuZGFyaW8gY29tcGxldG8iLCAiVGVyY2lhcmlvIGVuIGN1cnNvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUZXJjaWFyaW8gYWJhbmRvbmFkbyIsICJVbml2ZXJzaXRhcmlvIGFiYW5kb25hZG8iKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpbyBjb21wbGV0byIgPSBjKCJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwgIk1hZXN0csOtYSBhYmFuZG9uYWRhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGFiYW5kb25hZG8iKSksDQogICAgICAgICBuaXZlbF9mb3JtYWNpb24gPSBmY3RfcmVjb2RlKG5pdmVsX2Zvcm1hY2lvbiwgIkRpcGxvbWFkbyBjb21wbGV0byIgPSAiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpcGxvbWFkbyBlbiBjdXJzbyIgPSAiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGVuIGN1cnNvIikpIA0KDQpuZV9zYWxhcmlvICU+JSANCiAgc2VsZWN0KHBhaXMsIG5pdmVsX2Zvcm1hY2lvbiwgZ2VuZXJvLCBwdWVzdG8pICU+JQ0KICBmaWx0ZXIoZ2VuZXJvICVpbiUgYygiTXVqZXIgY2lzIiwgIkhvbWJyZSBjaXMiKSkgJT4lDQogIG11dGF0ZShuaXZlbF9mb3JtYWNpb24gPSBmYWN0b3Iobml2ZWxfZm9ybWFjaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlNlY3VuZGFyaW8gY29tcGxldG8iLCAiVGVyY2lhcmlvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbml2ZXJzaXRhcmlvIGVuIGN1cnNvIiwgIlVuaXZlcnNpdGFyaW8gY29tcGxldG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpcGxvbWFkbyBlbiBjdXJzbyIsIkRpcGxvbWFkbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFlc3Ryw61hIGVuIGN1cnNvIiwiTWFlc3Ryw61hIGNvbXBsZXRhIikpKSAlPiUgDQogIGdyb3VwX2J5KG5pdmVsX2Zvcm1hY2lvbikgJT4lIA0KICBnZ3Bsb3QoYWVzICh5PSBuaXZlbF9mb3JtYWNpb24sIGZpbGwgPSBnZW5lcm8pKSArIA0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKw0KICBsYWJzKHg9IiIseT0iIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKHZlcmRlLCBsaWxhKSkgKw0KICBlc3RpbG8gKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwNCiAgICAgICAgcGxvdC50aXRsZS5wb3NpdGlvbiA9ICJwbG90IikgKw0KICBsYWJzKHRpdGxlID0gIk3DoXhpbW8gbml2ZWwgZWR1Y2F0aXZvIGFsY2FuemFkbyBwb3IgZ8OpbmVybyIsDQogICAgICAgc3VidGl0bGUgPSAiRGlzdHJpYnVjacOzbiBwb3IgZnJlY3VlbmNpYXMgYWJzb2x1dGFzIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlLCANCiAgICAgICBmaWxsID0gIkfDqW5lcm8iKQ0KDQpgYGANCg0KRW4gdMOpcm1pbm9zIGFic29sdXRvcywgbGFzIG11amVyZXMgZ3JhZHVhZGFzIHJlcHJlc2VudGFuIGNlcmNhIGRlbCA3NSUgZGUgbGEgbXVlc3RyYS4gQW5hbGljZW1vcyBlc3RvcyBkYXRvcyBlbiB0w6lybWlub3MgcmVsYXRpdm9zLiBQcsOhY3RpY2FtZW50ZSBlbCBwYXRyw7NuIGRlIG5pdmVsIGVkdWNhdGl2byBlbnRyZSBob21icmVzIHkgbXVqZXJlcyBlcyBpZMOpbnRpY28uDQoNCkRlIGFjdWVyZG8gYSBsYSBtdWVzdHJhIHJlY29sZWN0YWRhLCBsYXMgbXVqZXJlcyBzZSBmb3JtYW4gZW4gbWF5b3IgcHJvcG9yY2nDs24gcXVlIGxvcyBob21icmVzIGNpcy4NCg0KYGBge3Igbml2ZWwtZWQtZ2VuZXJvLXJlbH0NCm5lX2ZlbSA8LSBuZV9zYWxhcmlvICU+JSANCiAgZmlsdGVyKGdlbmVybyA9PSAiTXVqZXIgY2lzIikgJT4lIA0KICBncm91cF9ieShnZW5lcm8sIG5pdmVsX2Zvcm1hY2lvbikgJT4lIA0KICBtdXRhdGUobml2ZWxfZm9ybWFjaW9uID0gZmFjdG9yKG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJTZWN1bmRhcmlvIGNvbXBsZXRvIiwgIlRlcmNpYXJpbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpbyBlbiBjdXJzbyIsICJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXBsb21hZG8gZW4gY3Vyc28iLCJEaXBsb21hZG8gY29tcGxldG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hZXN0csOtYSBlbiBjdXJzbyIsIk1hZXN0csOtYSBjb21wbGV0YSIpKSkgJT4lIA0KICBncm91cF9ieShuaXZlbF9mb3JtYWNpb24pICU+JSANCiAgc3VtbWFyaXNlKG4gPSBuKCkpICU+JSANCiAgbXV0YXRlKGZyZWN1ZW5jaWEgPSByb3VuZChuL3N1bShuKSwyKSwNCiAgICAgICAgIGdlbmVybyA9ICJNdWplciBjaXMiKSANCg0KbmVfbWFzIDwtIG5lX3NhbGFyaW8gJT4lIA0KICBmaWx0ZXIoZ2VuZXJvID09ICJIb21icmUgY2lzIikgJT4lIA0KICBncm91cF9ieShnZW5lcm8sIG5pdmVsX2Zvcm1hY2lvbikgJT4lIA0KICBtdXRhdGUobml2ZWxfZm9ybWFjaW9uID0gZmFjdG9yKG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJTZWN1bmRhcmlvIGNvbXBsZXRvIiwgIlRlcmNpYXJpbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpbyBlbiBjdXJzbyIsICJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXBsb21hZG8gZW4gY3Vyc28iLCJEaXBsb21hZG8gY29tcGxldG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hZXN0csOtYSBlbiBjdXJzbyIsIk1hZXN0csOtYSBjb21wbGV0YSIpKSkgJT4lIA0KICBncm91cF9ieShuaXZlbF9mb3JtYWNpb24pICU+JSANCiAgc3VtbWFyaXNlKG4gPSBuKCkpICU+JSANCiAgbXV0YXRlKGZyZWN1ZW5jaWEgPSByb3VuZChuL3N1bShuKSwyKSwNCiAgICAgICAgIGdlbmVybyA9ICJIb21icmUgY2lzIikgDQoNCm5lX3RvdGFsIDwtIHJiaW5kKG5lX2ZlbSwgbmVfbWFzKQ0KDQpnZ3Bsb3QobmVfdG90YWwsIGFlcyh4ID0gbml2ZWxfZm9ybWFjaW9uLCB5ID0gZnJlY3VlbmNpYSwgZmlsbCA9IGdlbmVybykpICsNCiAgZ2VvbV9jb2woKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApLCANCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArIA0KICBsYWJzKHg9IiIseT0iIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcmVzKSArDQogIGZhY2V0X3dyYXAofmdlbmVybywgbmNvbCA9IDIpICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiUHJvcG9yY2nDs24gZGUgbml2ZWwgZWR1Y2F0aXZvIG3DoXhpbW8gcG9yIGfDqW5lcm8iLA0KICAgICAgIHggPSAiIiwgeSA9ICJQcm9wb3JjacOzbiIsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQoNCmBgYA0KDQpBaG9yYSB2ZWFtb3MgY29tbyBzZSBkaXN0cmlidXllbiBsb3MgcHVlc3RvcyBzZWfDum4gZWwgZ8OpbmVybyB5IGVsIG5pdmVsIGVkdWNhdGl2by4NCg0KYGBge3IgcHVlc3Rvcy1uaXZlbC1lZCwgZmlnLmhlaWdodD04fQ0KbmVfc2FsYXJpbyAlPiUgDQogIHNlbGVjdChwYWlzLCBuaXZlbF9mb3JtYWNpb24sIGdlbmVybywgcHVlc3RvKSAlPiUNCiAgZmlsdGVyKGdlbmVybyAlaW4lIGMoIk11amVyIGNpcyIsICJIb21icmUgY2lzIiksDQogICAgICAgICBwdWVzdG8gIT0gIlBhc2FudGUiLCBwdWVzdG8gIT0gIkRpcmVjdG9yIikgJT4lDQogIG11dGF0ZShuaXZlbF9mb3JtYWNpb24gPSBmYWN0b3Iobml2ZWxfZm9ybWFjaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlNlY3VuZGFyaW8gY29tcGxldG8iLCAiVGVyY2lhcmlvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbml2ZXJzaXRhcmlvIGVuIGN1cnNvIiwgIlVuaXZlcnNpdGFyaW8gY29tcGxldG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpcGxvbWFkbyBlbiBjdXJzbyIsIkRpcGxvbWFkbyBjb21wbGV0byIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hZXN0csOtYSBlbiBjdXJzbyIsIk1hZXN0csOtYSBjb21wbGV0YSIpKSwNCiAgICAgICAgIHB1ZXN0byA9IGZhY3RvcihwdWVzdG8sIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIkRpcmVjdG9yIiwgIkdlcmVudGUiLCAiSmVmZSIsICJSZXNwb25zYWJsZSIsICJIUkJQIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBbmFsaXN0YSIsICJBZG1pbmlzdHJhdGl2byIpKSkgJT4lIA0KICBncm91cF9ieShuaXZlbF9mb3JtYWNpb24pICU+JSANCiAgZ2dwbG90KGFlcyAoeT0gbml2ZWxfZm9ybWFjaW9uLCBmaWxsID0gZ2VuZXJvKSkgKyANCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyh4PSIiLHk9IiIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyh2ZXJkZSwgbGlsYSkpICsNCiAgZXN0aWxvICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgIHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIpICsNCiAgbGFicyh0aXRsZSA9ICJOaXZlbCBlZHVjYXRpdm8gcG9yIHB1ZXN0byB5IGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gcG9yIGZyZWN1ZW5jaWFzIGFic29sdXRhcyIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSwgDQogICAgICAgZmlsbCA9ICJHw6luZXJvIikgKw0KICBmYWNldF93cmFwKH5wdWVzdG8sIG5jb2wgPSAzKQ0KDQpgYGANCg0KQWxndW5hcyBkYXRvcyBsbGFtYXRpdm9zIGRlbCBncsOhZmljbyBhbnRlcmlvcjoNCg0KLSBFbiBsYXMgcG9zaWNpb25lcyBkZSAqKkdlcmVudGUqKiB5IGRlICoqSmVmZSoqIGhheSBwYXJpZGFkIGVudHJlIGxvcyBnw6luZXJvcyByZXNwZWN0byBkZSBsYSBmb3JtYWNpw7NuIGVuIHBvc2dyYWRvcyBjb21wbGV0b3MuDQotIEVuIHBvc2ljaW9uZXMgZGUgbWVub3IgamVyYXJxdcOtYSBzZSBvYnNlcnZhbiBtdWplcmVzIGNpcyBjb24gcG9zZ3JhZG9zIGNvbXBsZXRvcyBvIGVuIGN1cnNvIGVuIG1heW9yIHByb3BvcmNpw7NuIHF1ZSBob21icmVzIGNpcy4NCi0gRW4gZWwgY2FzbyBkZWwgcHVlc3RvIGRlICoqQW5hbGlzdGEqKiBlbmNvbnRyYW1vcyBtdWplcmVzIGNvbiBwb3NncmFkb3MgY29tcGxldG9zLCBpbmNsdXNvIGNvbiBtYWVzdHLDrWFzIHkgZGlwbG9tYWRvcyBjb21wbGV0b3MuIEhheSBwb2NhcyBvYnNlcnZhY2lvbmVzIGRlIHZhcm9uZXMgY2lzIGNvbiBEaXBsb21hZG8gY29tcGxldG8gZW4gZXN0YSBwb3NpY2nDs24uIExvIGN1YWwgbm9zIGRhIGxhIHBhdXRhIHF1ZSBjb250YXIgY29uIHVuIHTDrXR1bG8gZGUgcG9zZ3JhZG8gZW4gZWwgY2FzbyBkZSBsb3MgaG9tYnJlcyBheXVkYSBhIHBvc2ljaW9uYXJzZSBlbiBwb3NpY2lvbmVzIGRlIG1heW9yIGplcmFycXXDrWEgZW4gbWF5b3IgcHJvcG9yY2nDs24gcXVlIGxhcyBtdWplcmVzLg0KDQpBbmFsaWNlbW9zIGxhcyBwcm9wb3JjaW9uZXMgZGUgaG9tYnJlcyB5IGRlIG11amVyZXMgZW4gcHVlc3RvIGRlIGxpZGVyYXpnby4NCg0KYGBge3IgbGlkZXJhemdvLWdlbmVybywgcmVzdWx0cz0naGlkZSd9DQoNCmRpdiA8LSByaF9hciAlPiUNCiAgZmlsdGVyKHBhaXMgPT0gIkFyZ2VudGluYSIpICU+JSANCnNlbGVjdChnZW5lcm8pICU+JSANCiAgbXV0YXRlKGdlbmVybyA9IGZhY3RvcihnZW5lcm8sIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk11amVyIGNpcyIsICJIb21icmUgY2lzIikpKSAlPiUgDQogIGdyb3VwX2J5KGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2UgKG4gPSBuKCkpICU+JSANCiAgbXV0YXRlKGZyZXEgPSBuL3N1bShuKSkgJT4lIA0KICBhcnJhbmdlKC1uKQ0KDQpsaWRlcmVzIDwtIHJoX2FyICU+JSANCiAgZmlsdGVyKHBhaXMgPT0gIkFyZ2VudGluYSIpICU+JSANCiBzZWxlY3QoZ2VuZXJvLCBwdWVzdG8pIA0KDQojIFByb3BvY2nDs24gZGUgbMOtZGVyZXMgaG9tYnJlcyB5IG11amVyZXMNCmxpZGVyZXNfZ2VuZXJvIDwtIGxpZGVyZXMgJT4lIA0KICBmaWx0ZXIoZ2VuZXJvICVpbiUgYygiTXVqZXIgY2lzIiwgIkhvbWJyZSBjaXMiKSkgJT4lIA0KICBncm91cF9ieShnZW5lcm8pICU+JQ0KICBtdXRhdGUoZ2VudGVfYV9jYXJnbyA9IGlmX2Vsc2UocHVlc3RvICVpbiUgYygiUmVzcG9uc2FibGUiLCAiSmVmZSIsICJHZXJlbnRlIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdXBlcnZpc29yIiwgIkRpcmVjdG9yIiksMSwwKSkgJT4lDQogIHN1bW1hcmlzZShsaWRlciA9IHN1bShnZW50ZV9hX2NhcmdvKSkgJT4lIA0KICBsZWZ0X2pvaW4oZGl2KSAlPiUgDQogIHNlbGVjdChnZW5lcm8sIGxpZGVyLCBuKSAlPiUgDQogIG11dGF0ZShwcm9wb3JjaW9uID0gcGVyY2VudChsaWRlci9uKSkNCg0KIyBUZXN0IGRlIGhpcMOzdGVzaXMgcGFyYSB2YWxpZGFyIGRpZmVyZW5jaWFzIGRlIHJlc3VsdGFkb3MNCiMgSGF5IHF1ZSB2ZXJpZmljYXIgc2kgbGEgcHJvcG9yY2nDs24gZGUgbMOtZGVyZXMgaG9tYnJlcyBlcyBtYXlvciBxdWUgbGEgcHJvcG9yY2nDs24gZGUgbMOtZGVyZXMgbXVqZXJlcw0KIyBDcmVvIHVuIGRhdGFmcmFtZSBwYXJhIGFuYWxpemFyIHByb3BvcmNpb25lcyBkZSBob21icmVzIHkgZGUgbXVqZXJlcyBlbiBwdWVzdG9zIGRlIGxpZGVyYXpnbyB5IGRlIG5vLWxpZGVyYXpnbw0KdGVzdF9saWRlciA8LSBsaWRlcmVzX2dlbmVybyAlPiUgDQogIG11dGF0ZShub19saWRlciA9IG4gLSBsaWRlcikgJT4lICAgICAgICAjIENvbHVtbmEgZGUgbm8gbMOtZGVyZXMNCiAgc2VsZWN0KGdlbmVybywgbGlkZXIsIG5vX2xpZGVyKSAlPiUgICAgICMgc2VsZWNjaW9ubyBjb2x1bW5hcyBkZSBpbnRlcsOpcw0KICBwaXZvdF9sb25nZXIoY29scyA9IGMobGlkZXIsIG5vX2xpZGVyKSwgIyBIYWdvIHVuIGRhdGFzZXQgbGFyZ28gcGFyYSBhbmFsaXphciBkZXNwdcOpcw0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiZXNfbGlkZXIiLCB2YWx1ZXNfdG8gPSAiY29udGVvIikNCg0KIyBEZWwgdG90YWwgZGUgcmVzcHVlc3RhcyBtZSBpbnRlcmVzYSBzw7NsbyB2ZXIgY3XDoWxlcyBzb24gbG9zIGhvbWJyZXMgY29uIHB1ZXN0byBkZSBsaWRlcmF6Z28NCnRlc3RfbGlkZXIkY2F0IDwtIGMoMCwwLDEsMCkNCg0KIyBFeHRyYWlnbyBlbCBtdSBwYXJhIGRlY2lkaXIgc2kgbGEgZGlmZXJlbmNpYSBlcyBzaWduaWZpY2F0aXZhIHkgcGFzYXJsbyBhIGxhIGbDs3JtdWxhIGRlbCB0ZXN0Lg0KcHJvcF9tdWplcl9saWQgPC0gcHVsbChsaWRlcmVzX2dlbmVyb1sxLDJdL2xpZGVyZXNfZ2VuZXJvWzEsM10pDQoNCiMgUmVhbGl6byBlbCB0ZXN0IGRlIGhpcMOzdGVzaXMuDQojIEgwID0gTGFzIHByb3BvcmNpb25lcyBkZSBsw61kZXJlcyBob21icmVzIHkgbXVqZXJlcyBzb24gaWd1YWxlcw0KIyBIMSA9IExhIHByb3BvcmNpw7NuIGRlIGhvbWJyZXMgbMOtZGVyZXMgZXMgbWF5b3IgcXVlIGxhIHByb3BvcmNpw7NuIGRlIG11amVyZXMgbMOtZGVyZXMuDQpyZXN1bHRhZG9zX3Rlc3QgPC0gYnJvb206OnRpZHkodC50ZXN0KHRlc3RfbGlkZXIkY2F0LCBtdSA9IHByb3BfbXVqZXJfbGlkLCBhbHRlcm5hdGl2ZSA9ICJncmVhdGVyIikpDQoNCnZhbG9yX3Rlc3QgPC0gaWYocmVzdWx0YWRvc190ZXN0WzEsM10gPiAwLjA1KSB7DQogIHByaW50KCJsYSBkaWZlcmVuY2lhIGVzIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmEsIHkgbGEgcHJvcG9yY2nDs24gZGUgaG9tYnJlcyBlbiBwdWVzdG9zIGRlIGxpZGVyYXpnbyBlcyBtYXlvciBxdWUgZWwgZGUgbGFzIG11amVyZXMiKQ0KICB9IGVsc2Ugew0KICAgIHByaW50KCJsYSBkaWZlcmVuY2lhIG5vIGVzIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmEsIHkgbGEgcHJvcG9yY2nDs24gZGUgaG9tYnJlcyBubyBlcyBlc3RhZMOtc3RpY2FtZW50ZSBtYXlvciBxdWUgZWwgZGUgbGFzIG11amVyZXMgZW4gcHVlc3RvcyBkZSBsaWRlcmF6Z28iKQ0KICB9DQpgYGANCg0KYGBge3IgZ3JhZmljby1wcm9wLWxpZC1nZW5lcm99DQojIEdyw6FmaWNvDQpsaWRlcmVzX2dlbmVybyAlPiUgDQogIG11dGF0ZShwb3JjX2xpZGVyID0gbGlkZXIvbiwgDQogICAgICAgICBwb3JjX25vX2xpZGVyID0gMSAtIHBvcmNfbGlkZXIpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKHBvcmNfbGlkZXIsIHBvcmNfbm9fbGlkZXIpLA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiZXNfbGlkZXIiLCANCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ2YWxvcmVzIikgJT4lIA0KICBtdXRhdGUoZXNfbGlkZXIgPSBmYWN0b3IoZXNfbGlkZXIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygicG9yY19ub19saWRlciIsICJwb3JjX2xpZGVyIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiTm8gTMOtZGVyIiwgIkzDrWRlciIpKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHg9IGdlbmVybywgeSA9IHZhbG9yZXMsIGZpbGwgPSBlc19saWRlcikpKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIikrDQogIGVzdGlsbyArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM3NTgzOEYiLCAiIzM0NEQ3RSIpKSArDQogIGxhYnModGl0bGUgPSAiUHJvcG9yY2nDs24gZGUgTMOtZGVyZXMgc2Vnw7puIGfDqW5lcm8iLA0KICAgICAgIHggPSAiIiwgeSA9ICIiLCBmaWxsID0gIiIsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQoNCmBgYA0KDQpEZSBhY3VlcmRvIGEgbGFzIHJlc3B1ZXN0YXMgcmVjb2xlY3RhZGFzICoqMiBkZSBjYWRhIDMqKiBwYXJ0aWNpcGFudGVzIHNvbiBtdWplcmVzLg0KDQpQYXJhIGxvcyBwdWVzdG9zIGRlIGxpZGVyYXpnbyBjb25zaWRlcmFtb3MgbGFzIHBlcnNvbmFzIGVuIGxvcyBwdWVzdG9zIGRlICpEaXJlY3RvciwgR2VyZW50ZSwgSmVmZSwgeSBSZXNwb25zYWJsZS4qDQoNCkRlbCB0b3RhbCBkZSAqKm11amVyZXMqKiwgYHIgbGlkZXJlc19nZW5lcm9bMSwzXWAgcmVzcHVlc3RhcywgYHIgbGlkZXJlc19nZW5lcm9bMSwyXWAgb2N1cGFuIHVuIHB1ZXN0byBkZSBsaWRlcmF6Z28gKGByIGxpZGVyZXNfZ2VuZXJvWzEsIDRdYCkuDQoNCkRlbCB0b3RhbCBkZSAqKmhvbWJyZXMqKiwgYHIgbGlkZXJlc19nZW5lcm9bMiwgM11gIHJlc3B1ZXN0YXMsIGByIGxpZGVyZXNfZ2VuZXJvWzIsMl1gIG9jdXBhbiB1biBwdWVzdG8gZGUgbGlkZXJhemdvIChgciBsaWRlcmVzX2dlbmVyb1syLCA0XWApLg0KDQpDb24gdW4gKnAtdmFsdWUqIGlndWFsIGEgYHIgcm91bmQocmVzdWx0YWRvc190ZXN0WzEsM10sMylgIHBvZGVtb3MgYWZpcm1hciBxdWUgKipgciB2YWxvcl90ZXN0YCoqLg0KDQoNCkEgcGVzYXIgZGUgcXVlIGVuIFJlY3Vyc29zIEh1bWFub3MgZW4gQXJnZW50aW5hLCBsYXMgbXVqZXJlcyBjaXMgcmVwcmVzZW50YW4gbGEgbWF5b3IgY2FudGlkYWQgZGUgZW1wbGVhZG9zIGJham8gcmVsYWNpw7NuIGRlIGRlcGVuZGVuY2lhLCB5IGFkZW3DoXMgc2UgZm9ybWFuIGVuIG1heW9yIHByb3BvcmNpw7NuIHF1ZSBsb3MgdmFyb25lcyBlbiBwb3NncmFkb3MsIHByb3BvcmNpb25hbG1lbnRlIGVuIGNvbXBhcmFjacOzbiBjb24gbG9zIGhvbWJyZXMgY2lzLCBhY2NlZGVuIGEgbWVub3MgcG9zaWNpb25lcyBkZSBsaWRlcmF6Z28uDQoNCg0KDQojIyBBbsOhbGlzaXMgZGUgc3VlbGRvcyB5IGVkdWNhY2nDs24gZW4gQXJnZW50aW5hDQoNCkVuIGVzdGEgc2VjY2nDs24gYW5hbGl6YXJlbW9zIGxvcyBzdWVsZG9zIGVuIGNvbXBhcmFjacOzbiBjb24gbG9zIGRpc3RpbnRvcyBuaXZlbGVzIGVkdWNhdGl2b3MuDQoNCkEgZGlmZXJlbmNpYSBkZSBvdHJhcyBzZWNjaW9uZXMsIGVuIGVzdGUgY2FzbyBjb21wYXJhcmVtb3MgbGEgKm1lZGlhIHNhbGFyaWFsKiBwYXJhIHBvZGVyIG9ic2VydmFyIGxvcyBkZXN2w61vcyBlc3TDoW5kYXIgZW4gbG9zIGFuw6FsaXNpcy4gRW4gcHJpbWVyIGx1Z2FyIGFuYWxpY2Vtb3MgY3XDoWwgZXMgZWwgc3VlbGRvIHByb21lZGlvIGRlIGFjdWVyZG8gYSBsb3MgZGlzdGludG9zIG5pdmVsZXMgZWR1Y2F0aXZvcy4NCg0KUHJpbWVybyB2ZWFtb3MgY3XDoWwgZXMgZWwgc3VlbGRvIHByb21lZGlvIGVuIHBlc29zIGFyZ2VudGlub3MsIHNlZ8O6biBlbCBuaXZlbCBlZHVjYXRpdm8uDQoNCmBgYHtyIHN1ZWxkby1lZHVjfQ0KZXN0dWRpb3MgPC0gcmhfYXIgJT4lIA0KICBmaWx0ZXIocGFpcyA9PSAiQXJnZW50aW5hIikgJT4lIA0KICBzZWxlY3QoZ2VuZXJvLCBuaXZlbF9mb3JtYWNpb24sIHN1ZWxkb19icnV0bykNCiAgICANCiAgDQplc3RfYXIgIDwtIHByb2ZpbGluZ19udW0oZXN0dWRpb3MpDQplc19wMDUgPC0gZXN0X2FyWzEsNl0NCmVzX3A5NSA8LSBlc3RfYXJbMSwxMF0NCg0Kcm0oZXN0X2FyKQ0KDQpyaF9hciAlPiUgDQogIGZpbHRlcihwYWlzID09ICJBcmdlbnRpbmEiLCANCiAgICAgICAgIGJldHdlZW4oc3VlbGRvX2JydXRvLCBlc19wMDUsIGVzX3A5NSkpICU+JSANCiAgICAgIG11dGF0ZShuaXZlbF9mb3JtYWNpb24gPSBmY3RfY29sbGFwc2Uobml2ZWxfZm9ybWFjaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZWN1bmRhcmlvIGNvbXBsZXRvIiA9IGMoIlNlY3VuZGFyaW8gY29tcGxldG8iLCAiVGVyY2lhcmlvIGVuIGN1cnNvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUZXJjaWFyaW8gYWJhbmRvbmFkbyIsICJVbml2ZXJzaXRhcmlvIGFiYW5kb25hZG8iKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpbyBjb21wbGV0byIgPSBjKCJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwgIk1hZXN0csOtYSBhYmFuZG9uYWRhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGFiYW5kb25hZG8iKSksDQogICAgICAgICBuaXZlbF9mb3JtYWNpb24gPSBmY3RfcmVjb2RlKG5pdmVsX2Zvcm1hY2lvbiwgIkRpcGxvbWFkbyBjb21wbGV0byIgPSAiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpcGxvbWFkbyBlbiBjdXJzbyIgPSAiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGVuIGN1cnNvIikpICU+JSANCiAgICBtdXRhdGUobml2ZWxfZm9ybWFjaW9uID0gZmFjdG9yKG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJTZWN1bmRhcmlvIGNvbXBsZXRvIiwgIlRlcmNpYXJpbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpbyBlbiBjdXJzbyIsICJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXBsb21hZG8gZW4gY3Vyc28iLCAiRGlwbG9tYWRvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWVzdHLDrWEgZW4gY3Vyc28iLCJNYWVzdHLDrWEgY29tcGxldGEiKSkpICU+JSANCiAgZ3JvdXBfYnkobml2ZWxfZm9ybWFjaW9uKSAlPiUgDQogIHN1bW1hcmlzZShzdWVsZG9fcHJvbWVkaW8gPSBtZWFuKHN1ZWxkb19icnV0bykpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gc3VlbGRvX3Byb21lZGlvLCB5ID0gbml2ZWxfZm9ybWFjaW9uKSkrDQogIGdlb21fY29sKGZpbGwgPSBhenVsKSsNCmdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShyb3VuZChzdWVsZG9fcHJvbWVkaW8sIDApLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpZy5tYXJrID0gIi4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNpbWFsLm1hcmsgPSAiLCIpLA0KICAgICAgICAgICAgaGp1c3QgPSAxLiwgZm9udGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLA0KICAgICAgICAgICAgc2l6ZSA9IDMsIGNvbG9yID0gIndoaXRlIiwNCiAgICAgICAgICAgIGZhbWlseSA9ICJSb2JvdG8iKSArDQogIGVzdGlsb3YgKw0KICBlamVfeF9uICsNCiAgbGFicyh0aXRsZSA9ICJTdWVsZG8gcHJvbWVkaW8gcG9yIG5pdmVsIGRlIGZvcm1hY2nDs24iLA0KICAgICAgIHN1YnRpdGxlID0gIkVuIEFSJCIsDQogICAgICAgeD0iIiwgeT0iIiwgY2FwdGlvbiA9IGZ1ZW50ZSkNCg0KICANCg0KYGBgDQoNCkFob3JhIHZlYW1vcyBxdcOpIHBhc2Egc2kgaW5jbHVpbW9zIGVuIGVsIGFuw6FsaXNpcyBlbCBnw6luZXJvIHBhcmEgYW5hbGl6YXIgbG9zIHN1ZWxkb3MgcHJvbWVkaW9zIHkgc3VzIGRlc3bDrW9zIGVzdMOhbmRhci4NCg0KYGBge3Igc3VlbGRvLWVkdWMtZ2VuZXJvfQ0KcmhfYXIgJT4lIA0KICBmaWx0ZXIocGFpcyA9PSAiQXJnZW50aW5hIiwgDQogICAgICAgICBiZXR3ZWVuKHN1ZWxkb19icnV0bywgZXNfcDA1LCBlc19wOTUpKSAlPiUgDQogICAgICBtdXRhdGUobml2ZWxfZm9ybWFjaW9uID0gZmN0X2NvbGxhcHNlKG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2VjdW5kYXJpbyBjb21wbGV0byIgPSBjKCJTZWN1bmRhcmlvIGNvbXBsZXRvIiwgIlRlcmNpYXJpbyBlbiBjdXJzbyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVGVyY2lhcmlvIGFiYW5kb25hZG8iLCAiVW5pdmVyc2l0YXJpbyBhYmFuZG9uYWRvIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuaXZlcnNpdGFyaW8gY29tcGxldG8iID0gYygiVW5pdmVyc2l0YXJpbyBjb21wbGV0byIsICJNYWVzdHLDrWEgYWJhbmRvbmFkYSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBhYmFuZG9uYWRvIikpLA0KICAgICAgICAgbml2ZWxfZm9ybWFjaW9uID0gZmN0X3JlY29kZShuaXZlbF9mb3JtYWNpb24sICJEaXBsb21hZG8gY29tcGxldG8iID0gIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXBsb21hZG8gZW4gY3Vyc28iID0gIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBlbiBjdXJzbyIpKSAlPiUgDQogICAgbXV0YXRlKG5pdmVsX2Zvcm1hY2lvbiA9IGZhY3RvcihuaXZlbF9mb3JtYWNpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiU2VjdW5kYXJpbyBjb21wbGV0byIsICJUZXJjaWFyaW8gY29tcGxldG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuaXZlcnNpdGFyaW8gZW4gY3Vyc28iLCAiVW5pdmVyc2l0YXJpbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlwbG9tYWRvIGVuIGN1cnNvIiwgIkRpcGxvbWFkbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFlc3Ryw61hIGVuIGN1cnNvIiwiTWFlc3Ryw61hIGNvbXBsZXRhIikpKSAlPiUgDQogIGdyb3VwX2J5KG5pdmVsX2Zvcm1hY2lvbiwgZ2VuZXJvKSAlPiUgDQogIHN1bW1hcmlzZShzYWxhcmlvcyA9IGxpc3QobWVhbl9zZShzdWVsZG9fYnJ1dG8pKSkgJT4lIA0KICB1bm5lc3Qoc2FsYXJpb3MpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbml2ZWxfZm9ybWFjaW9uLCB5ID0geSwgZmlsbCA9IGdlbmVybykpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHltaW4seW1heCA9IHltYXgpLCBwb3NpdGlvbiA9ICJkb2RnZSIpKw0KICBjb29yZF9mbGlwKCkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgICBwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiKSArDQogIGVqZV95X24gKw0KICBlc3RpbG92ICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyh2ZXJkZSwgbGlsYSkpICsNCiAgbGFicyh0aXRsZSA9ICJTdWVsZG8gcHJvbWVkaW8geSBkZXN2w61vIGVzdMOhbmRhcmQgcG9yIG5pdmVsIGRlIGZvcm1hY2nDs24geSBnw6luZXJvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJFbiBBUiQiLCANCiAgICAgICB4ID0gIiIsIHkgPSAiIiwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSwgDQogICAgICAgZmlsbCA9ICJHw6luZXJvIikNCmBgYA0KDQoNCiMgRnJlZWxhbmNlcnMNCg0KRW4gZXN0ZSByZWxldmFtaWVudG8gcGFydGljaXBhbiBjb2xlZ2FzIHF1ZSB0cmFiYWphbiBlbiByZWxhY2nDs24gZGUgZGVwZW5kZW5jaWEgeSB0YW1iacOpbiBkZSBtYW5lcmEgZnJlZWxhbmNlLiBFc3RlIGVzIGVsIGFuw6FsaXNpcyBkZXNhcnJvbGxhZG8gZW4gYmFzZSBhIGxhcyByZXNwdWVzdGFzIGRlIGxhcyBwZXJzb25hcyBxdWUgdHJhYmFqYW4gZGUgbWFuZXJhIGluZGVwZW5kaWVudGUgbyBlbiBzdXMgcHJvcGlhcyBlbXByZXNhcy4NCg0KIyMgUmVzcHVlc3RhcyAgcG9yIHBhw61zDQoNCkVuIGVsIGNhc28gZGUgbGFzIHBlcnNvbmFzIGZyZWVsYW5jZSwgbGEgbWF5b3LDrWEgZGUgbGFzIHJlc3B1ZXN0YXMgb2J0ZW5pZGFzIGZ1ZXJvbiBkZSBBcmdlbnRpbmEuDQpQb3IgZXNvIHJlaXRlcmFtb3MsIHF1ZSBsb3MgcmVzdWx0YWRvcyBubyBzb24gcmVwcmVzZW50YXRpdm9zIGRlIGxvcyBwYcOtc2VzLiANCg0KDQpgYGB7ciAgZWNobz1GQUxTRSAgfQ0KDQoNCnBhaXNlcyA8LSBmcmVlbG8yMSAlPiUgDQogIHNlbGVjdChwYWlzKSAlPiUgDQogIG11dGF0ZShjdWVudGEgPSAxKSAlPiUgDQogIGdyb3VwX2J5KHBhaXMpICU+JSANCiAgc3VtbWFyaXNlKEN1ZW50YSA9IHN1bShjdWVudGEpKSAlPiUgDQogIGFycmFuZ2UoLUN1ZW50YSkNCg0KZ3QocGFpc2VzKSAlPiUgDQogIHRhYl9oZWFkZXIodGl0bGUgPSAiQ2FudGlkYWQgZGUgcmVzcHVlc3RhcyBwb3IgcGHDrXMiLA0KICAgICAgICAgICAgIHN1YnRpdGxlID0gIkZyZWVsYW5jZSIpICU+JSANCiAgdGFiX3NvdXJjZV9ub3RlKHNvdXJjZV9ub3RlID0gZnVlbnRlKSAlPiUgDQogIGNvbHNfbGFiZWwocGFpcyA9ICJQYcOtcyIpDQoNCmBgYA0KDQojIyBSZXNwdWVzdGFzIHBvciBHw6luZXJvIA0KDQpMYSBwYXJ0aWNpcGFjacOzbiBzZWfDum4gZWwgZ8OpbmVybyBkZSBsYXMgcGVyc29uYXMgZnJlZWxhbmNlLCAgZXMgbGEgc2lndWllbnRlOg0KDQoNCmBgYHtyICBlY2hvPUZBTFNFICwgbWVzc2FnZT0gRkFMU0UsICB3YXJuaW5nID0gRkFMU0UgfQ0KDQoNCiMjIExpbXBpZXphIHZhcmlhYmxlIGdlbmVybyAtLS0tDQpmcmVlbG8yMSA8LSBmcmVlbG8yMSAlPiUgDQogIG11dGF0ZShnZW5lcm8gPSBmY3RfY29sbGFwc2UoZ2VuZXJvLCAiTXVqZXIgY2lzIiA9IGMoIk11amVyIGNpcyIsICJNdWplciIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIb21icmUgY2lzIiA9ICJIb21icmUgY2lzIiksDQogICAgICAgICBnZW5lcm8gPSBmYWN0b3IoZ2VuZXJvLCBsZXZlbHMgPSBjKCJNdWplciBjaXMiLCAiSG9tYnJlIGNpcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHJlZmllcm8gbm8gcmVzcG9uZGVyIikpKQ0KDQoNCmRpdiA8LSBmcmVlbG8yMSAlPiUgDQogIHNlbGVjdChnZW5lcm8pICU+JSANCiAgZmlsdGVyKGdlbmVybyE9Ik5BIiklPiUgICMgc2Ugc2FjYSwgcG9ycXVlIG5vIGVzIHJlcHJlc2VudGF0aXZvDQogIGZpbHRlcihnZW5lcm8hPSJQcmVmaWVybyBubyByZXNwb25kZXIiKSU+JSAgIyBzZSBzYWNhLCBwb3JxdWUgbm8gZXMgcmVwcmVzZW50YXRpdm8NCiAgZ3JvdXBfYnkoZ2VuZXJvKSAlPiUgDQogIHN1bW1hcmlzZSAobiA9IG4oKSkgJT4lIA0KICBtdXRhdGUoZnJlcSA9IG4vc3VtKG4pKSAlPiUgDQogIGFycmFuZ2UoLW4pDQoNCiMgQ29tcHV0ZSB0aGUgY3VtdWxhdGl2ZSBwZXJjZW50YWdlcyAodG9wIG9mIGVhY2ggcmVjdGFuZ2xlKQ0KZGl2JHltYXggPC0gY3Vtc3VtKGRpdiRmcmVxKQ0KDQojIENvbXB1dGUgdGhlIGJvdHRvbSBvZiBlYWNoIHJlY3RhbmdsZQ0KZGl2JHltaW4gPC0gYygwLCBoZWFkKGRpdiR5bWF4LCBuPS0xKSkNCg0KIyBDb21wdXRlIGxhYmVsIHBvc2l0aW9uDQpkaXYkbGFiZWxQb3NpdGlvbiA8LSAoZGl2JHltYXggKyBkaXYkeW1pbikgLyAyDQoNCiMgQ29tcHV0ZSBhIGdvb2QgbGFiZWwNCmRpdiRsYWJlbCA8LSBwYXN0ZTAoZGl2JGdlbmVybywgIlxuIENhbnQ6ICIsIGRpdiRuKQ0KDQojIE1ha2UgdGhlIHBsb3QNCmdncGxvdChkaXYsIGFlcyh5bWF4PXltYXgsIHltaW49eW1pbiwgeG1heD00LCB4bWluPTMsIGZpbGw9Z2VuZXJvKSkgKw0KICBnZW9tX3JlY3QoKSArDQogIGNvb3JkX3BvbGFyKHRoZXRhPSJ5IikgKyAjIFRyeSB0byByZW1vdmUgdGhhdCB0byB1bmRlcnN0YW5kIGhvdyB0aGUgY2hhcnQgaXMgYnVpbHQgaW5pdGlhbGx5DQogIHhsaW0oYygyLCA0KSkgKyMgVHJ5IHRvIHJlbW92ZSB0aGF0IHRvIHNlZSBob3cgdG8gbWFrZSBhIHBpZSBjaGFydA0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjODYyNEY1IiwgICIjMUZDM0FBIiwgIiNGRkQxMjkiLCIjNzU4MzhGIikpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiUm9ib3RvIikpICsNCiAgbGFicyh0aXRsZSA9ICJDYW50aWRhZCBkZSByZXNwdWVzdGFzIHNlZ8O6biBnw6luZXJvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJGcmVlbGFuY2UiLA0KICAgICAgIGZpbGwgPSAiR8OpbmVybyIsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQoNCmBgYA0KDQpQb2RlbW9zIG9ic2VydmFyIHF1ZSBsYSBtYXlvcsOtYSBkZSBsYXMgcmVzcHVlc3RhcyBmdWVyb24gZGUgIE11amVyZXMgY2lzLCBtYW50ZW5pZW5kbyBsYSBtaXNtYSB0ZW5kZW5jaWEgcXVlIGxhcyBwZXJzb25hcyBlbiByZWxhY2nDs24gZGUgZGVwZW5kZW5jaWEuIA0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KDQpmcmVlbG8yMSAlPiUgDQogIHNlbGVjdChnZW5lcm8pICU+JQ0KICBtdXRhdGUoY3VlbnRhID0gMSkgJT4lIA0KICBncm91cF9ieShnZW5lcm8pICU+JQ0KICBzdW1tYXJpc2UoQ3VlbnRhID0gc3VtKGN1ZW50YSkpICU+JQ0KICBmaWx0ZXIoQ3VlbnRhPjIpJT4lDQogIGFycmFuZ2UoLUN1ZW50YSklPiUNCiAgcmVuYW1lKCJHw6luZXJvIj1nZW5lcm8pICU+JSANCiAga2FibGUoImh0bWwiLCBlc2NhcGU9RikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFLCBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJob3ZlciIsImNvbmRlbnNlZCIgKSkgJT4lIA0KICByb3dfc3BlYygwLCBib2xkPVQsIGNvbG9yPSJ3aGl0ZSIsIGJhY2tncm91bmQgPSBhenVsKQ0KYGBgDQoNCiMjIFJlc3B1ZXN0YXMgcG9yIEVkdWNhY2nDs24gDQoNCkVuIGVzdGEgc2VjY2nDs24gcXVlcmVtb3MgaW5kYWdhciBzaSBoYXkgcmVsYWNpw7NuIGVudHJlIGxhIGZvcm1hY2nDs24geSBsYSBleHBvcnRhY2lvbiBkZSBsb3Mgc2VydmljaW9zLCB5IHNpIGltcGFjdGEgdGFtYmnDqW4gZWwgdGlwbyBkZSB1bml2ZXJzaWRhZCwgcMO6YmxpY2EgbyBwcml2YWRhLCBlbiBkaWNoYXMgcHJlc3RhY2nDs25lcy4gDQpQcmltZXJvIHZlYW1vcyAgY29tbyBzZSBkaXN0cmlidXllIGxhIG11ZXN0cmEgZW50cmUgcHJvZmVzaW9uYWxlcyBwcm92ZW5pZW50ZXMgZGUgdW5pdmVyc2lkYWRlcyBww7pibGljYXMgeSBwcml2YWRhcyBkZSBsb3MgZGlmZXJlbnRlcyBwYWlzZXM6DQoNCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KIyBOb3RhOiBWZXIgY29tbyBhZ3JlZ2FyIGxhIHRhYmxhIGRlIHJlZmVyZW5jaWFzIGFsIGdyYWZpY28tDQoNCmZyZWVsbzIxICU+JSANCiAgc2VsZWN0KHBhaXMsIHRpcG9fdW5pdmVyc2lkYWQpICU+JSANCiAgZ2dwbG90KGFlcyh5ID0gcGFpcywgZmlsbCA9IHRpcG9fdW5pdmVyc2lkYWQpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArIA0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKGdyaXMsIHZlcmRlLCBhenVsKSkgKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gZGUgcmVzcHVlc3RhcyBwb3IgdGlwbyBkZSB1bml2ZXJzaWRhZCBwb3IgcGHDrXMiLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUsIA0KICAgICAgIHggPSAiIiwgeSA9ICIiKSArDQogIGVzdGlsbyArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KYGBgDQoNCg0KTGltaXRhbmRvbm9zIGFsIHBhw61zIGNvbiBtYXlvciBjYW50aWRhZCBkZSByZXNwdWVzdGFzLCBBcmdlbnRpbmEsIGVuIGxvcyAgc2lndWllbnRlcyBncmFmaWNvcyBwb2RlbW9zIG9ic2VydmFyICBxdWUgIGxhIGRpc3RyaWJ1Y2nDs24gICBwb3IgdGlwbyBkZSBVbml2ZXJzaWRhZCBlcyAgbXV5IHBhcmVqYSAsIHF1ZWRhbmRvIHVuIHZhbG9yICBtaW5pbW8geSBwb2NvIHJlcHJlc2VudGF0aXZvICBwYXJhIHF1aWVuZW4gbm8gZnVlcm9uIGEgbGEgVW5pdmVyc2lkYWQ6IA0KDQoNCmBgYHtyICBlY2hvPUZBTFNFICwgbWVzc2FnZT0gRkFMU0UsICB3YXJuaW5nID0gRkFMU0V9DQoNCmZyZWVsbzIxICU+JSANCiAgc2VsZWN0KHBhaXMsIHRpcG9fdW5pdmVyc2lkYWQpICU+JQ0KICBmaWx0ZXIgKHBhaXM9PSJBcmdlbnRpbmEiKSU+JSANCiAgZ2dwbG90KGFlcyh4ID0gdGlwb191bml2ZXJzaWRhZCkpICsgDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIiwgZmlsbCA9IGF6dWwpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzNjApKSArIA0KICBsYWJzKHg9IiIseT0iIikgKw0KICBlc3RpbG9oICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGRlIHJlc3B1ZXN0YXMgcG9yIHRpcG8gZGUgdW5pdmVyc2lkYWQiLA0KICAgICAgIHN1YnRpdGxlID0gIlNvbG8gQXJnZW50aW5hIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KDQoNCmBgYA0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQoNCg0KIyMgVGlwbyBkZSBVbml2ZXJzaWRhZCAgDQoNCmVkdWMgPC0gZnJlZWxvMjEgJT4lIA0KICBzZWxlY3QodGlwb191bml2ZXJzaWRhZCkgJT4lICANCiAgZ3JvdXBfYnkodGlwb191bml2ZXJzaWRhZCkgJT4lIA0KICBzdW1tYXJpc2UgKG4gPSBuKCkpICU+JSANCiAgbXV0YXRlKGZyZXEgPSBuL3N1bShuKSkgJT4lIA0KICBhcnJhbmdlKC1uKQ0KDQojIENvbXB1dGUgdGhlIGN1bXVsYXRpdmUgcGVyY2VudGFnZXMgKHRvcCBvZiBlYWNoIHJlY3RhbmdsZSkNCmVkdWMkeW1heCA8LSBjdW1zdW0oZWR1YyRmcmVxKQ0KDQojIENvbXB1dGUgdGhlIGJvdHRvbSBvZiBlYWNoIHJlY3RhbmdsZQ0KZWR1YyR5bWluIDwtIGMoMCwgaGVhZChlZHVjJHltYXgsIG49LTEpKQ0KDQojIENvbXB1dGUgbGFiZWwgcG9zaXRpb24NCmVkdWMkbGFiZWxQb3NpdGlvbiA8LSAoZWR1YyR5bWF4ICsgZWR1YyR5bWluKSAvIDINCg0KIyBDb21wdXRlIGEgZ29vZCBsYWJlbA0KZWR1YyRsYWJlbCA8LSBwYXN0ZTAoZWR1YyR0aXBvX3VuaXZlcnNpZGFkLCAiXG4gQ2FudDogIiwgZWR1YyRuKQ0KDQojIE1ha2UgdGhlIHBsb3QNCmdncGxvdChlZHVjLCBhZXMoeW1heD15bWF4LCB5bWluPXltaW4sIHhtYXg9NCwgeG1pbj0zLCBmaWxsPXRpcG9fdW5pdmVyc2lkYWQpKSArDQogIGdlb21fcmVjdCgpICsNCiAgY29vcmRfcG9sYXIodGhldGE9InkiKSArICMgVHJ5IHRvIHJlbW92ZSB0aGF0IHRvIHVuZGVyc3RhbmQgaG93IHRoZSBjaGFydCBpcyBidWlsdCBpbml0aWFsbHkNCiAgeGxpbShjKDIsIDQpKSArIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gc2VlIGhvdyB0byBtYWtlIGEgcGllIGNoYXJ0DQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoZ3JpcywgdmVyZGUsIGF6dWwpKSArDQogIHRoZW1lX3ZvaWQoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsDQogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIlJvYm90byIpKSArDQogIGxhYnModGl0bGUgPSAiVGlwbyBkZSBVbml2ZXJzaWRhZCIsDQogICAgICAgZmlsbCA9ICJUaXBvIGRlIFVuaXZlcnNpZGFkIiwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibGVmdCIpDQpgYGANCg0KDQoNCk5vcyBpbnRlcmVzYWJhIGluZGFnYXIgY3XDoWwgZXJhIGVsIG5pdmVsIGRlIGZvcm1hY2nDs24gIGRlIGxvcyBlbmN1ZXN0YWRvcy4NCg0KRW4gbGEgc2lndWllbnRlIHRhYmxhIHBvZGVtb3MgdmVyIHF1ZSBsYSBtYXlvcsOtYSB0aWVuZSBlc3R1ZGlvcyAgVW5pdmVyc2l0YXJpb3MgY29tcGxldG9zOiANCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KZnJlZWxvMjEgJT4lIA0KICBzZWxlY3Qobml2ZWxfZm9ybWFjaW9uKSAlPiUNCiAgbXV0YXRlKGN1ZW50YSA9IDEpICU+JSANCiAgZ3JvdXBfYnkobml2ZWxfZm9ybWFjaW9uKSAlPiUNCiAgc3VtbWFyaXNlKEN1ZW50YSA9IHN1bShjdWVudGEpKSAlPiUgDQogIGFycmFuZ2UoLUN1ZW50YSklPiUgDQogIHNlbGVjdChuaXZlbF9mb3JtYWNpb24sQ3VlbnRhKSAlPiUgDQogIHJlbmFtZSgiTml2ZWwgZGUgRm9ybWFjacOzbiI9bml2ZWxfZm9ybWFjaW9uKSAlPiUgDQogIGthYmxlKCJodG1sIiwgZXNjYXBlPUYpICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiICkpICU+JSANCiAgcm93X3NwZWMoMCwgYm9sZD1ULCBjb2xvcj0id2hpdGUiLCBiYWNrZ3JvdW5kID0gYXp1bCkNCmBgYA0KDQpDdWFuZG8gIGFuYWxpemFtb3MgZWR1Y2FjacOzbiwgbm9zIHJlc3VsdMOzICBpbnRlcmVzYW50ZSBhbmFsaXphciBsYSBkaXN0cmlidWNpw7NuIHBvciBnw6luZXJvIHkgbml2ZWwgZWR1Y2F0aXZvLg0KDQpFbiBlbCBzaWd1aWVudGUgZ3LDoWZpY28gcG9kZW1vcyBvYnNlcnZhciBxdWUgbGFzIG11amVyZXMgdGllbmVuIG1heW9yIG5pdmVsIGRlIGZvcm1hY2nDs24gcXVlIGxvcyBob21icmVzOg0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KZnJlZWxvMjEgJT4lIA0KICBzZWxlY3QocGFpcywgbml2ZWxfZm9ybWFjaW9uLCBnZW5lcm8pICU+JQ0KICBmaWx0ZXIoZ2VuZXJvICE9ICJQcmVmaWVybyBubyByZXNwb25kZXIiKSAlPiUgIyBzYWNhciBwb3JxdWUgbm8gZXMgcmVwcmVzZW50YXRpdm8NCiAgZmlsdGVyKG5pdmVsX2Zvcm1hY2lvbiAhPSAiTkEiKSAlPiUgICAgICAgICAgICMgc2FjYXIgcG9ycXVlIG5vIGVzIHJlcHJlc2VudGF0aXZvDQogIG11dGF0ZShuaXZlbF9mb3JtYWNpb24gPSBmYWN0b3Iobml2ZWxfZm9ybWFjaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlRlcmNpYXJpbyBjb21wbGV0byIsIlRlcmNpYXJpbyBhYmFuZG9uYWRvIiwgIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBlbiBjdXJzbyIsIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBjb21wbGV0byIsIlVuaXZlcnNpdGFyaW8gZW4gY3Vyc28iLCAiVW5pdmVyc2l0YXJpbyBjb21wbGV0byIsICJNYWVzdHLDrWEgY29tcGxldGEiKSkpICU+JSANCiAgZ3JvdXBfYnkobml2ZWxfZm9ybWFjaW9uKSAlPiUgDQogIGdncGxvdChhZXMgKHk9IG5pdmVsX2Zvcm1hY2lvbiwgZmlsbCA9IGdlbmVybykpICsgDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArIA0KICBsYWJzKHg9IiIseT0iIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcmVzKSArDQogIGVzdGlsbyArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArDQogIGxhYnModGl0bGUgPSAiTcOheGltbyBuaXZlbCBlZHVjYXRpdm8gYWxjYW56YWRvIHBvciBnw6luZXJvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEaXN0cmlidWNpw7NuIHBvciBmcmVjdWVuY2lhcyBhYnNvbHV0YXMiLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUsIA0KICAgICAgIGZpbGwgPSAiR8OpbmVybyIpDQoNCmBgYA0KDQoNClZlYW1vcyBsb3MgbWlzbW9zIHJlc3VsdGFkb3MsIGVuIHRlcm1pbm9zIHJlbGF0aXZvczogDQoNCmBgYHtyICBlY2hvPUZBTFNFICwgbWVzc2FnZT0gRkFMU0UsICB3YXJuaW5nID0gRkFMU0V9DQoNCiNFc3RhIGJpZW4gbGEgcHJvcG9yY2lvbj8/IHZlciEhIA0KDQoNCg0KZnJfZmVtIDwtIGZyZWVsbzIxICU+JSANCiAgZmlsdGVyKGdlbmVybyA9PSAiTXVqZXIgY2lzIikgJT4lIA0KICBncm91cF9ieShnZW5lcm8sIG5pdmVsX2Zvcm1hY2lvbikgJT4lIA0KICBtdXRhdGUobml2ZWxfZm9ybWFjaW9uID0gZmFjdG9yKG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJUZXJjaWFyaW8gY29tcGxldG8iLCJUZXJjaWFyaW8gYWJhbmRvbmFkbyIsICJEaXBsb21hZG8gZGUgcG9zZ3JhZG8gZW4gY3Vyc28iLCJEaXBsb21hZG8gZGUgcG9zZ3JhZG8gY29tcGxldG8iLCJVbml2ZXJzaXRhcmlvIGVuIGN1cnNvIiwgIlVuaXZlcnNpdGFyaW8gY29tcGxldG8iLCAiTWFlc3Ryw61hIGNvbXBsZXRhIikpKSAlPiUgDQogIGdyb3VwX2J5KG5pdmVsX2Zvcm1hY2lvbikgJT4lIA0KICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lIA0KICBtdXRhdGUoZnJlY3VlbmNpYSA9IHJvdW5kKG4vc3VtKG4pLDIpLA0KICAgICAgICAgZ2VuZXJvID0gIk11amVyIGNpcyIpIA0KDQoNCmZyX21hcyA8LSBmcmVlbG8yMSAlPiUgDQogIGZpbHRlcihnZW5lcm8gPT0gIkhvbWJyZSBjaXMiKSAlPiUgDQogIGdyb3VwX2J5KGdlbmVybywgbml2ZWxfZm9ybWFjaW9uKSAlPiUgDQogIG11dGF0ZShuaXZlbF9mb3JtYWNpb24gPSBmYWN0b3Iobml2ZWxfZm9ybWFjaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlRlcmNpYXJpbyBjb21wbGV0byIsIlRlcmNpYXJpbyBhYmFuZG9uYWRvIiwgIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBlbiBjdXJzbyIsIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBjb21wbGV0byIsIlVuaXZlcnNpdGFyaW8gZW4gY3Vyc28iLCAiVW5pdmVyc2l0YXJpbyBjb21wbGV0byIsICJNYWVzdHLDrWEgY29tcGxldGEiKSkpICU+JSANCiAgZ3JvdXBfYnkobml2ZWxfZm9ybWFjaW9uKSAlPiUgDQogIHN1bW1hcmlzZShuID0gbigpKSAlPiUgDQogIG11dGF0ZShmcmVjdWVuY2lhID0gcm91bmQobi9zdW0obiksMiksDQogICAgICAgICBnZW5lcm8gPSAiSG9tYnJlIGNpcyIpIA0KDQpmcl90b3RhbCA8LSByYmluZChmcl9mZW0sIGZyX21hcyApDQoNCmdncGxvdChmcl90b3RhbCwgYWVzKHggPSBuaXZlbF9mb3JtYWNpb24sIHkgPSBmcmVjdWVuY2lhLCBmaWxsID0gZ2VuZXJvKSkgKw0KICBnZW9tX2NvbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCksIA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgDQogIGxhYnMoeD0iIix5PSIiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG9yZXMpICsNCiAgZmFjZXRfd3JhcCh+Z2VuZXJvLCBuY29sID0gMikgKw0KICBlc3RpbG9oICsNCiAgbGFicyh0aXRsZSA9ICJQcm9wb3JjacOzbiBkZSBuaXZlbCBlZHVjYXRpdm8gbcOheGltbyBwb3IgZ8OpbmVybyIsDQogICAgICAgc3VidGl0bGUgPSAiRnJlZWxhbmNlIiwNCiAgICAgICB4ID0gIiIsIHkgPSAiUHJvcG9yY2nDs24iLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KDQoNCmBgYA0KDQoNClJlc3BlY3RvIGEgbGFzICBjYXJyZXJhcywgdmVtb3MgcXVlIGxhIHRlbmRlbmNpYSBkZSBsYXMgbWlzbWFzIHNlIGNvcnJlc3BvbmRlbiBjb24gbG9zIHJlc3VsdGFkb3Mgb2J0ZW5pZG9zIGVuIGxhcyBwZXJzb25hcyBlbiByZWxhY2nDs24gZGUgZGVwZW5kZW5jaWE6IA0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQpjYXJyZXJhc2ZyIDwtIGZyZWVsbzIxICU+JSANCiAgc2VsZWN0KG5pdmVsX2Zvcm1hY2lvbiwgY2FycmVyYV9ncmFkbywgdGlwb191bml2ZXJzaWRhZCwgcGFpcywgZ2VuZXJvKSAlPiUgDQogIG11dGF0ZShjYXJyZXJhX2dyYWRvID0gZmFjdG9yKGNhcnJlcmFfZ3JhZG8pKQ0KDQpjYXJyZXJhc2ZyIDwtIGNhcnJlcmFzZnIgJT4lIA0KICBtdXRhdGUoY2FycmVyYV9ncmFkbyA9IGZjdF9jb2xsYXBzZShjYXJyZXJhX2dyYWRvLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSUkhIIC8gUlJMTCAvIFJSVFQiID0gYygiUlJISCAvIFJSTEwgLyBSUlRUIiwgIlkgYWhvcmEgUmVsYWNpb25lcyBMYWJvcmFsZXMiKSksDQogICAgICAgICBjYXJyZXJhX2dyYWRvID0gZmN0X2NvbGxhcHNlKGNhcnJlcmFfZ3JhZG8sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHNpY29sb2fDrWEiID0gYygiUHNpY29sb2fDrWEiKSksDQogICAgICAgICBjYXJyZXJhX2dyYWRvID0gZmN0X2NvbGxhcHNlKGNhcnJlcmFfZ3JhZG8sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWRtaW5pc3RyYWNpw7NuIGRlIEVtcHJlc2FzIiA9IGMoIkFkbWluaXN0cmFjacOzbiBkZSBFbXByZXNhcyIpKSwNCiAgDQogICAgICAgICBjYXJyZXJhX2dyYWRvID0gZmN0X2x1bXAoY2FycmVyYV9ncmFkbywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcCA9IDAuMDIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG90aGVyX2xldmVsID0gIk90cm9zIiksDQogICAgICAgICAgIGNhcnJlcmFfZ3JhZG8gPSBmYWN0b3IoY2FycmVyYV9ncmFkbywgbGV2ZWxzID0gYygiUlJISCAvIFJSTEwgLyBSUlRUIiwgIlBzaWNvbG9nw61hIiwgIkFkbWluaXN0cmFjacOzbiBkZSBFbXByZXNhcyIsICJPdHJvcyIpKSkNCg0KDQpnZ3Bsb3QoY2FycmVyYXNmciwgYWVzKHggPSBjYXJyZXJhX2dyYWRvKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIsIGZpbGwgPSBhenVsKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzYwKSkgKyANCiAgbGFicyh4PSIiLHk9IiIpICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiUHJpbmNpcGFsZXMgY2FycmVyYXMgZXN0dWRpYWRhcyIsDQogICAgICAgc3VidGl0bGUgPSAiRnJlZWxhbmNlIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KYGBgDQoNCiMjIFJlc3B1ZXN0YXMgcG9yIENvbmRpY2nDs24gZmlzY2FsDQoNCkxhIGNvbmRpZGljacOzbiBmaXNjYWwgZGUgIGxvcyBlbmN1ZXN0YWRvcyBsYSBwb2RlbW9zIG9ic2VydmFyIGVuIGxhIHNpZ3VpZW50ZSB0YWJsYToNCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KDQpmaXNjb2ZyIDwtIGZyZWVsbzIxICU+JSANCiAgc2VsZWN0KHRyYWJham8sIHJlZ2lzdHJvX2Zpc2NhbCwgbWVkaW9fcGFnb19leHRlcmlvcikgJT4lIA0KICBtdXRhdGUocmVnaXN0cm9fZmlzY2FsID0gZmFjdG9yKHJlZ2lzdHJvX2Zpc2NhbCkpJT4lDQogIG11dGF0ZShyZWdpc3Ryb19maXNjYWwgPSBmY3RfY29sbGFwc2UocmVnaXN0cm9fZmlzY2FsLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1vbm90cmlidXRpc3RhIiA9ICJNb25vdHJpYnV0aXN0YSIpLA0KICAgICAgICAgcmVnaXN0cm9fZmlzY2FsID0gZmN0X2NvbGxhcHNlKHJlZ2lzdHJvX2Zpc2NhbCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNvbnRyYWN0b3IiID0gIkNvbnRyYWN0b3IiKSwNCiAgICAgICAgIHJlZ2lzdHJvX2Zpc2NhbCA9IGZjdF9jb2xsYXBzZShyZWdpc3Ryb19maXNjYWwsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZXNwb25zYWJsZSBpbnNjcmlwdG8iID0gIlJlc3BvbnNhYmxlIGluc2NyaXB0byIpLA0KICAgICAgICAgIHJlZ2lzdHJvX2Zpc2NhbCA9IGZjdF9jb2xsYXBzZShyZWdpc3Ryb19maXNjYWwsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTQSIgPSAiU0EiKSwNCiAgICAgICAgIHJlZ2lzdHJvX2Zpc2NhbCA9IGZjdF9jb2xsYXBzZShyZWdpc3Ryb19maXNjYWwsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPdHJvcyIgPSBjKCJObyBlc3RveSByZWdpc3RyYWRhIHBvciBlbCBtb21lbnRvIiwiU3BhIiwidGVuZ28gdW4gY29udHJhdG8gbWl4dG8gcmVsIGRlcGVuZGVuY2lhIHkgIGZyZWVsYW5jZSIpKSwNCiAgICAgICAgIGNhcnJlcmFfZ3JhZG8gPSBmYWN0b3IocmVnaXN0cm9fZmlzY2FsLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJNb25vdHJpYnV0aXN0YSIsICJDb250cmFjdG9yIiwgIlJlc3BvbnNhYmxlIGluc2NyaXB0byIsIlNBIiwgIk90cm9zIikpKQ0KDQoNCmZpc2NvZnIgJT4lIA0KICBzZWxlY3QocmVnaXN0cm9fZmlzY2FsKSAlPiUNCiAgbXV0YXRlKGN1ZW50YSA9IDEpICU+JSANCiAgZ3JvdXBfYnkocmVnaXN0cm9fZmlzY2FsKSAlPiUNCiAgc3VtbWFyaXNlKEN1ZW50YSA9IHN1bShjdWVudGEpKSAlPiUgDQogIGFycmFuZ2UoLUN1ZW50YSklPiUgDQogIHJlbmFtZSgiUmVnaXN0cm8gRmlzY2FsIj1yZWdpc3Ryb19maXNjYWwpICU+JSANCiAga2FibGUoImh0bWwiLCBlc2NhcGU9RikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFLCBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJob3ZlciIsImNvbmRlbnNlZCIgKSkgJT4lIA0KICByb3dfc3BlYygwLCBib2xkPVQsIGNvbG9yPSJ3aGl0ZSIsIGJhY2tncm91bmQgPSBhenVsKQ0KDQpgYGANCg0KIyMgIFJlc3B1ZXN0YXMgcG9yIEV4cG9ydGFjacOzbiBkZSAgU2VydmljaW8NCg0KY29tbyB2ZW1vcyBhIGNvbnRpbnVhY2nDs24sICBsYSBtYXlvcsOtYSBubyBleHBvcnRhIHN1cyBzZXJ2aWNpb3M6IA0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KZXhwIDwtIGZyZWVsbzIxICU+JSANCiAgc2VsZWN0KGV4cG9ydGEpICU+JSANCiBmaWx0ZXIoZXhwb3J0YSE9Ik5BIikgJT4lIA0KICBncm91cF9ieShleHBvcnRhKSAlPiUgDQogIHN1bW1hcmlzZSAobiA9IG4oKSkgJT4lIA0KICBtdXRhdGUoZnJlcSA9IG4vc3VtKG4pKSAlPiUgDQogIGFycmFuZ2UoLW4pDQoNCiMgQ29tcHV0ZSB0aGUgY3VtdWxhdGl2ZSBwZXJjZW50YWdlcyAodG9wIG9mIGVhY2ggcmVjdGFuZ2xlKQ0KZXhwJHltYXggPC0gY3Vtc3VtKGV4cCRmcmVxKQ0KDQojIENvbXB1dGUgdGhlIGJvdHRvbSBvZiBlYWNoIHJlY3RhbmdsZQ0KZXhwJHltaW4gPC0gYygwLCBoZWFkKGV4cCR5bWF4LCBuPS0xKSkNCg0KIyBDb21wdXRlIGxhYmVsIHBvc2l0aW9uDQpleHAkbGFiZWxQb3NpdGlvbiA8LSAoZXhwJHltYXggKyBkaXYkeW1pbikgLyAyDQoNCiMgQ29tcHV0ZSBhIGdvb2QgbGFiZWwNCmV4cCRsYWJlbCA8LSBwYXN0ZTAoZXhwJGV4cG9ydGEsICJcbiBDYW50OiAiLCBkaXYkbikNCg0KIyBNYWtlIHRoZSBwbG90DQpnZ3Bsb3QoZXhwLCBhZXMoeW1heD15bWF4LCB5bWluPXltaW4sIHhtYXg9NCwgeG1pbj0zLCBmaWxsPWV4cG9ydGEpKSArDQogIGdlb21fcmVjdCgpICsNCiAgY29vcmRfcG9sYXIodGhldGE9InkiKSArICMgVHJ5IHRvIHJlbW92ZSB0aGF0IHRvIHVuZGVyc3RhbmQgaG93IHRoZSBjaGFydCBpcyBidWlsdCBpbml0aWFsbHkNCiAgeGxpbShjKDIsIDQpKSArIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gc2VlIGhvdyB0byBtYWtlIGEgcGllIGNoYXJ0DQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM4NjI0RjUiLCAgIiMxRkMzQUEiLCAiI0ZGRDEyOSIsIiM3NTgzOEYiKSkgKw0KICB0aGVtZV92b2lkKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJSb2JvdG8iKSkgKw0KICBsYWJzKHRpdGxlID0gIkV4cG9ydGEgU2VydmljaW9zIiwNCiAgICAgICBmaWxsID0gIiIsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQpgYGANCg0KDQpGb2NhbGl6YW5kb25vcyBlbnRyZSBxdWllbmVzIGV4cG9ydGFuLCBwb2RlbW9zIHZlciBjdcOhbCBlcyBlbCBzZXJ2aWNpbyBwcmVzdGFkbzogDQoNCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KDQpzdl9mciA8LSBmcmVlbG8yMSAlPiUgDQogIGZpbHRlcihzZXJ2aWNpb19wcmluY2lwYWwgIT0gIk5BIiklPiUgDQogIGZpbHRlcihzZXJ2aWNpb19wcmluY2lwYWwgIT0gIlN0YXJ0IHVwIGRlbCBhcmVhIGRlIEhSIGlucG1lbnRhY2lvbiBkZSBwb2xpdGljYXMgeSBwcm9jZXNvcywgYnVzcXVlZGEgeSBzZWxlY2Npb24sIGFzZXNvcmFtaWVudG8gZW4gZ2VuZXJhbCBkZWwgYXJlYSIpJT4lIA0KICBzZWxlY3Qoc2VydmljaW9fcHJpbmNpcGFsLCBleHBvcnRhKSAlPiUNCiAgZmlsdGVyKGV4cG9ydGE9PSJTaSIpJT4lDQptdXRhdGUoc2VydmljaW9fcHJpbmNpcGFsID0gZmFjdG9yKHNlcnZpY2lvX3ByaW5jaXBhbCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlBheXJvbGwgLyBMaXF1aWRhY2nDs24gZGUgc3VlbGRvcyIsICJEaXNlw7FvIG9yZ2FuaXphY2lvbmFsIiwgIkNhcGFjaXRhY2nDs24iLCAiQ29tdW5pY2FjacOzbiBpbnRlcm5hIiwiUGVvcGxlIEFuYWx5dGljcyIsIkhSIEdlbmVyYWxpc3RhIikpKQ0KDQpnZ3Bsb3Qoc3ZfZnIsIChhZXMoeCA9IHNlcnZpY2lvX3ByaW5jaXBhbCwgZmlsbCA9IGV4cG9ydGEpKSkgKyANCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArIA0KICBsYWJzKHg9IiIseT0iIikgKw0KICBlc3RpbG92ICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyh2ZXJkZSkpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJSZXNwdWVzdGFzIHNlZ8O6biBTZXJ2aWNpbyBFeHBvcnRhZG8iLA0KICAgICAgIHN1YnRpdGxlID0gIkZyZWVsYW5jZSIsDQogICAgICAgeCA9ICIiLCBmaWxsID0gIkV4cG9ydGEiLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQpgYGANCg0KDQpFbiByZWxhY2nDs24gYSBsb3MgbWVkaW9zIGRlIHBhZ28gdXRpbGl6YWRvcyBwb3IgcXVpZW5lcyBleHBvcnRhbiwgc3VzIHJlc3B1ZXN0YXMgZnVlcm9uIGxhcyBzaWd1aWVudGVzOiANCg0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQoNCm1wX2ZyIDwtZnJlZWxvMjElPiUNCiAgbXV0YXRlKG1lZGlvX3BhZ29fZXh0ZXJpb3IgPSBmY3RfY29sbGFwc2UobWVkaW9fcGFnb19leHRlcmlvciwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBheW9uZWVyIiA9IGMoIlBheW9uZWVyIikpLA0KICAgICAgICAgbWVkaW9fcGFnb19leHRlcmlvciA9IGZjdF9jb2xsYXBzZShtZWRpb19wYWdvX2V4dGVyaW9yLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVHJhbnNmZXJlbmNpYSIgPSBjKCJUcmFuc2ZlcmVuY2lhIGEgdHUgY3VlbnRhIikpLA0KICAgICAgICAgbWVkaW9fcGFnb19leHRlcmlvciA9IGZjdF9jb2xsYXBzZShtZWRpb19wYWdvX2V4dGVyaW9yLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGF5UGFsIiA9IGMoIlBheVBhbCIpKSwNCiAgICAgICAgIG1lZGlvX3BhZ29fZXh0ZXJpb3IgPSBmY3RfY29sbGFwc2UobWVkaW9fcGFnb19leHRlcmlvciwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCaXRjb2luIiA9IGMoIkJpdGNvaW4iKSksDQogICAgICAgICBtZWRpb19wYWdvX2V4dGVyaW9yID0gZmN0X2NvbGxhcHNlKG1lZGlvX3BhZ29fZXh0ZXJpb3IsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiV2VzdGVybiBVbmlvbiIgPSBjKCJXZXN0ZXJuIFVuaW9uIikpLA0KICAgICAgICAgbWVkaW9fcGFnb19leHRlcmlvciA9IGZjdF9jb2xsYXBzZShtZWRpb19wYWdvX2V4dGVyaW9yLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlByZXgiID0gYygiUHJleCIpKSwNCiAgICAgICAgIG1lZGlvX3BhZ29fZXh0ZXJpb3IgPSBmY3RfY29sbGFwc2UobWVkaW9fcGFnb19leHRlcmlvciwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOTyIgPSBjKCItIiwiMCIsIk4vQSIsIm5vIiwiTm8iLCJObyBhcGxpY2EiLCJObyBleHBvcnRpIHBvciBhaG9yYSIsIm5vIGV4cG9ydG8iLCJObyBleHBvcnRvIiAsIk5vIGV4cG9ydG8gc2VydmljaW9zIiwiTm8gZXhwb3J0by4iLCJObyB0cmFiYWpvIHBhcmEgYWZ1ZXJhIGHDum4iLCJYeHh4IikpLA0KICAgICAgICAgY2FycmVyYV9ncmFkbyA9IGZhY3RvcihtZWRpb19wYWdvX2V4dGVyaW9yLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJQYXlvbmVlciIsICJUcmFuc2ZlcmVuY2lhIiwgIlBheVBhbCIsICJCaXRjb2luIiwiV2VzdGVybiBVbmlvbiIsIlByZXgiLCJOTyIpKSkNCg0KDQoNCm1wX2ZyICU+JSANCiAgZmlsdGVyKG1lZGlvX3BhZ29fZXh0ZXJpb3IhPSJOTyIpJT4lIA0KICBtdXRhdGUoY3VlbnRhID0gMSkgJT4lIA0KICBncm91cF9ieShtZWRpb19wYWdvX2V4dGVyaW9yKSAlPiUNCiAgc3VtbWFyaXNlKEN1ZW50YSA9IHN1bShjdWVudGEpKSAlPiUgDQogIGFycmFuZ2UoLUN1ZW50YSklPiUgDQogIHNlbGVjdChtZWRpb19wYWdvX2V4dGVyaW9yLEN1ZW50YSkgJT4lIA0KICByZW5hbWUoIk1lZGlvcyBkZSBQYWdvIEV4dGVyaW9yIj1tZWRpb19wYWdvX2V4dGVyaW9yKSAlPiUgDQogIGthYmxlKCJodG1sIiwgZXNjYXBlPUYpICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiICkpICU+JSANCiAgcm93X3NwZWMoMCwgYm9sZD1ULCBjb2xvcj0id2hpdGUiLCBiYWNrZ3JvdW5kID0gYXp1bCkNCg0KYGBgDQoNCiMjIFJlc3B1ZXN0YXMgcG9yICBBbnRpZ8O8ZWRhZA0KDQpSZXNwZWN0byBhIGxvcyBhw7FvcyBkZSBleHBlcmllbmNpYSBjb21vIGZyZWVsYW5jZSwgcG9kZW1vcyBvYnNlcnZhciBxdWUgbGEgbWF5b3LDrWEgdGllbmUgbWVub3MgZGUgZG9zIGHDsW9zLg0KDQpVbiBpbnRlcnJvZ2FudGUgcXVlIG5vcyBzdXJnZSBlbiBzaSBsYSBpbnNlcmNpw7NuIGVuIGVzdGEgbW9kYWxpZGFkIGZ1ZSB1bmEgZGVjaXNpw7NuIGRlIGNhcnJlcmEgdm9sdW50YXJpYSBvIGltcHVsc2FkYSBwb3IgbGFzIGNvbnNlY3VlbmNpYXMgZGUgbGEgcGFuZGVtaWEuIENhcmVjZW1vcyBkZSBlbGVtZW50b3MgcGFyYSByZXNwb25kZXIgZXNhIHByZWd1bnRhLCBwb3IgZXNvIG5vcyBsaW1pdGFtb3MgYSAgcHJlc2VudGFyIGxhcyByZXNwdWVzdGFzIG9idGVuaWRhczogDQoNCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KYW50X2ZyPC0gZnJlZWxvMjEgJT4lIA0KICBtdXRhdGUocmFuZ29fYW50ID1jYXNlX3doZW4oDQogICAgYW5pb3NfZnJlZWxhbmNlIDwgMiB+ICJNZW5vcyBkZSAyIGHDsW9zIiwNCiAgICBhbmlvc19mcmVlbGFuY2UgPCA2IH4gIkVudHJlIDIgeSA1IGHDsW9zIiwNCiAgICBhbmlvc19mcmVlbGFuY2UgPCAxMSB+ICJFbnRyZSA1IHkgMTAgYcOxb3MiLA0KICAgIGFuaW9zX2ZyZWVsYW5jZSA9IFQgfiAiTcOhcyBkZSAxMCBhw7FvcyIpLA0KICAgIHJhbmdvX2FudCA9IGZjdF9yZWxldmVsKHJhbmdvX2FudCwgYygiTWVub3MgZGUgMiBhw7FvcyIsICJFbnRyZSAyIHkgNSBhw7FvcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVudHJlIDUgeSAxMCBhw7FvcyIsICJNw6FzIGRlIDEwIGHDsW9zIikpKQ0KIGFudF9mciAlPiUNCiAgc2VsZWN0KHJhbmdvX2FudCkgJT4lDQogIG11dGF0ZShjdWVudGEgPSAxKSAlPiUgDQogIGdyb3VwX2J5KHJhbmdvX2FudCkgJT4lDQogIHN1bW1hcmlzZShDdWVudGEgPSBzdW0oY3VlbnRhKSkgJT4lIA0KICBhcnJhbmdlKC1DdWVudGEpJT4lIA0KICByZW5hbWUoIkHDsW9zIGRlIEV4cGVyaWVuY2lhIj1yYW5nb19hbnQpICU+JSANCiAjIHJlbmFtZSgiRXhwb3J0YSI9ZXhwb3J0YSkgJT4lIA0KICBrYWJsZSgiaHRtbCIsIGVzY2FwZT1GKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IFRSVUUsIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsImhvdmVyIiwiY29uZGVuc2VkIiApKSAlPiUgDQogIHJvd19zcGVjKDAsIGJvbGQ9VCwgY29sb3I9IndoaXRlIiwgYmFja2dyb3VuZCA9IGF6dWwpDQoNCmBgYA0KDQojIyBSZXNwdWVzdGFzIHBvciAgQsO6c3F1ZWRhcw0KDQpOb3MgaW50ZXJlc2Egc2FiZXIgY3VhbnRvcyBzZSBkZWRpY2FuIGEgcmVhbGl6YXIgdHJhYmFqb3MgZGUgc2VsZWNjacOzbiBkZSB0YWxlbnRvcy4gDQoNClBvZGVtb3Mgb2JzZXJ2YXIgcXVlIHVuIDY2JSBkZSBsYXMgcGVyc29uYXMgZW5jdWVzdGFkYXMgZW4gZXN0YSBjYXRlZ29yaWEgc2UgZGVkaWNhbiBhIGxhIHRhcmVhIGRlIGLDunNxdWVkYS4gDQoNCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KZnJlZWxvMjEgJT4lIA0KICBzZWxlY3Qoc2VydmljaW9fYnVzcXVlZGEpICU+JQ0KICBtdXRhdGUoY3VlbnRhID0gMSkgJT4lIA0KICBncm91cF9ieShzZXJ2aWNpb19idXNxdWVkYSkgJT4lDQogIHN1bW1hcmlzZSAobiA9IG4oKSkgJT4lIA0KICBtdXRhdGUoZnJlcSA9IG4vc3VtKG4pKSAlPiUgDQogIGFycmFuZ2UoLW4pJT4lIA0KcmVuYW1lKCJTZXJ2LiBCw7pzcXVlZGEiPXNlcnZpY2lvX2J1c3F1ZWRhKSAlPiUNCiAgIGthYmxlKCJodG1sIiwgZXNjYXBlPUYpICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiICkpICU+JSANCiAgcm93X3NwZWMoMCwgYm9sZD1ULCBjb2xvcj0id2hpdGUiLCBiYWNrZ3JvdW5kID0gYXp1bCkNCg0KYGBgDQoNClNhYmllbmRvIGVsIGNyZWNpbWllbnRvIHkgYXVnZSBkZSBsYXMgYsO6c3F1ZWRhcyBlbiBlbCBzZWN0b3IgZGUgSVQsIHZlYW1vcyBjdcOhbCBlcyBsYSBwYXJ0aWNpcGFjacOzbiBkZSBsYXMgbWlzbWFzIGVudHJlIGxhcyBwZXJzb25hcyBxdWUgaGFjZW4gcmVjcnVpdGluZy4gDQoNCkNvbW8gc2Ugb2JzZXJ2YSBlbiBlbCBzaWd1aWVudGUgZ3LDoWZpY28sIGxhIG1heW9yw61hIGRlIGxhcyBiw7pzcXVlZGFzIHNlIGNvbmNlbnRyYW4gcXVlIGVuIGVsIHNlY3RvciBJVC4gDQoNCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KDQppdF9mcjwtIGZyZWVsbzIxICU+JSANCiAgc2VsZWN0KGJ1c3F1ZWRhX2l0LCBzZXJ2aWNpb19idXNxdWVkYSkgJT4lIA0KICBmaWx0ZXIoc2VydmljaW9fYnVzcXVlZGE9PSJTaSIpIA0KDQoNCmdncGxvdChpdF9mciwgKGFlcyh4ID0gYnVzcXVlZGFfaXQsIGZpbGwgPSBzZXJ2aWNpb19idXNxdWVkYSkpKSArIA0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsgDQogIGxhYnMoeD0iIix5PSIiKSArDQogIGVzdGlsb3YgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKHZlcmRlKSkgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIlNlcnZpY2lvIGRlIELDunNxdWVkYSIsDQogICAgICAgc3VidGl0bGUgPSAiRnJlZWxhbmNlIiwNCiAgICAgICB4ID0gIiIsIGZpbGwgPSAiSVQiLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQpgYGANCg0KDQojIyBSZXNwdWVzdGEgcG9yIGdhcmFudMOtYSBkZSB0cmFiYWpvDQoNCkxhcyBnYXJhbnTDrWFzIGRlIHJlcG9zaWNpw7NuIGRlIHZhY2FudGVzIHNlIHJlZmllcmVuIGEgbGEgcHJvdGVjY2nDs24gcXVlIHNlIGJyaW5kYSBhIGNhZGEgY2xpZW50ZSBlbiBlbCBjYXNvIGRlIHF1ZSBsYSBwZXJzb25hIGNvbnRyYXRhZGEgICBzZSBtYXJjaGUgZGUgbGEgZW1wcmVzYS4NCg0KVmVhbW9zIGVudHJlIGxvcyBxdWUgIHByZXN0YW4gIGVsIHNlcnZpY2lvIGRlIHJlY3J1aXRpbmcsIHF1aWVuZXMgb2ZyZWNlbiBnYXJhbnTDrWEgZGUgcGVybWFuZW5jaWEgZGVsIGNhbmRpZGF0by4gDQoNCg0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQoNCmd0aWEgPC0gZnJlZWxvMjEgJT4lIA0KIyAgc2VsZWN0KGdhcmFudGlhLHNlcnZpY2lvX2J1c3F1ZWRhKSAlPiUgDQogIGZpbHRlcihzZXJ2aWNpb19idXNxdWVkYT09IlNpIikgJT4lIA0KICBtdXRhdGUoZ2FyYW50aWE9ZmN0X2NvbGxhcHNlKGdhcmFudGlhLCAiU2kiID0gYygiMSBtZXMiLCIyIG1lc2VzIiwgIjMgbWVzZXMiKSksDQogICAgICAgICBnYXJhbnRpYT1mY3RfY29sbGFwc2UoZ2FyYW50aWEsICJObyIgPSBjKCJObyBvZnJlemNvIGdhcmFudMOtYSIpKSwNCiAgICAgICAgICBnYXJhbnRpYSA9IGZhY3RvcihnYXJhbnRpYSwgbGV2ZWxzID1jKCJTaSIsIk5vIiApKSkNCg0KDQpndGlhMiA8LSBndGlhICU+JSANCiAgc2VsZWN0KGdhcmFudGlhKSAlPiUgDQogIGdyb3VwX2J5KGdhcmFudGlhKSAlPiUgDQogIHN1bW1hcmlzZSAobiA9IG4oKSkgJT4lIA0KICBtdXRhdGUoZnJlcSA9IG4vc3VtKG4pKSAlPiUgDQogIGFycmFuZ2UoLW4pDQoNCiMgQ29tcHV0ZSB0aGUgY3VtdWxhdGl2ZSBwZXJjZW50YWdlcyAodG9wIG9mIGVhY2ggcmVjdGFuZ2xlKQ0KZ3RpYTIkeW1heCA8LSBjdW1zdW0oZ3RpYTIkZnJlcSkNCg0KIyBDb21wdXRlIHRoZSBib3R0b20gb2YgZWFjaCByZWN0YW5nbGUNCmd0aWEyJHltaW4gPC0gYygwLCBoZWFkKGd0aWEyJHltYXgsIG49LTEpKQ0KDQojIENvbXB1dGUgbGFiZWwgcG9zaXRpb24NCmd0aWEyJGxhYmVsUG9zaXRpb24gPC0gKGd0aWEyJHltYXggKyBndGlhMiR5bWluKSAvIDINCg0KIyBDb21wdXRlIGEgZ29vZCBsYWJlbA0KZ3RpYTIkbGFiZWwgPC0gcGFzdGUwKGd0aWEyJGdhcmFudGlhLCAiXG4gQ2FudDogIiwgZ3RpYTIkbikNCg0KIyBNYWtlIHRoZSBwbG90DQpnZ3Bsb3QoZ3RpYTIsIGFlcyh5bWF4PXltYXgsIHltaW49eW1pbiwgeG1heD00LCB4bWluPTMsIGZpbGw9Z2FyYW50aWEpKSArDQogIGdlb21fcmVjdCgpICsNCiAgY29vcmRfcG9sYXIodGhldGE9InkiKSArICMgVHJ5IHRvIHJlbW92ZSB0aGF0IHRvIHVuZGVyc3RhbmQgaG93IHRoZSBjaGFydCBpcyBidWlsdCBpbml0aWFsbHkNCiAgeGxpbShjKDIsIDQpKSArIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gc2VlIGhvdyB0byBtYWtlIGEgcGllIGNoYXJ0DQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIHZlcmRlLCBhenVsKSkgKw0KICB0aGVtZV92b2lkKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJSb2JvdG8iKSkgKw0KICBsYWJzKHRpdGxlID0gIkdhcmFudMOtYSBkZSBQZXJtYW5lbmNpYSIsDQogICAgICAgZmlsbCA9ICIiLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJsZWZ0IikNCg0KDQoNCg0KYGBgDQoNCg0KDQpFbiBsYSBzaWd1aWVudGUgdGFibGEgcG9kZW1vcyBvYnNlcnZhciBxdWUgbG9zIHBsYXpvcyBkZSBnYXJhbnTDrWEgc3VlbGVuIGlyIGRlc2RlIHVuIG1lcyBoYXN0YSBsb3MgdHJlcyBtZXNlcy4gUGVybyB1biBuw7ptZXJvIGltcG9ydGFudGUsIG5vIG9mcmVjZSBnYXJhbnRpYSBwb3IgZWwgIHNlcnZpY2lvIGNvbnRyYXRhZG8uDQoNCmBgYHtyICBlY2hvPUZBTFNFICwgbWVzc2FnZT0gRkFMU0UsICB3YXJuaW5nID0gRkFMU0V9DQoNCmd0aWEyIDwtIGZyZWVsbzIxICU+JSANCiMgIHNlbGVjdChnYXJhbnRpYSxzZXJ2aWNpb19idXNxdWVkYSkgJT4lIA0KICBmaWx0ZXIoc2VydmljaW9fYnVzcXVlZGE9PSJTaSIpICU+JSANCiAgbXV0YXRlKCBnYXJhbnRpYT1mY3RfY29sbGFwc2UoZ2FyYW50aWEsICJObyIgPSBjKCJObyBvZnJlemNvIGdhcmFudMOtYSIpKSwNCiAgICAgICAgICBnYXJhbnRpYSA9IGZhY3RvcihnYXJhbnRpYSwgbGV2ZWxzID1jKCJTaSIsIk5vIiApKSkNCg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQoNCg0KYGBgDQoNCiMjIFJlc3B1ZXN0YXMgcG9yIEJhc2UgZGUgQ29lZmljaWVudGUNCg0KDQpPdHJvIHB1bnRvIHBhcmEgZGVzdGFjYXIgZXMgZWwgcHJlY2lvIGRlbCBzZXJ2aWNpbyBkZSBxdWllbmVzIGhhY2VuIHJlY3J1aXRpbmcuDQoNClBvZGVtb3MgdmVyIHF1ZSBsYSBncmFuIG1heW9yw61hICBjb2JyYSAgIHBvciBkaWNobyBzZXJ2aWNpbywgdW4gcG9yY2VudGFqZSBkZSAgcmVtdW5lcmFjacOzbiBtZW5zdWFsIGRlbCBpbmdyZXNhbnRlLCBkZWphbmRvIHBhcmEgbXV5IHBvY29zIGNhc29zIGVsIGluZ3Jlc28gYW51YWwgZGVsIG1pc21vLg0KDQoNClVuYSBwcmVndW50YSBhYmllcnRhIHF1ZSBub3MgcXVlZGEsIGVzIGN1w6FsZXMgc29uIGxhcyBwb3NpY2lvbmVzIG1lam9yZXMgcGFnYXMgcGFyYSBsb3MgcmVjcnVpdGVycy4gU2luIGVtYmFyZ28sIGRpY2hvIGFuw6FsaXNpcyBlc2NhcGEgZGUgbG9zIG9iamV0aXZvcyBkZSBsYSBwcmVzZW50ZSBlbmN1ZXN0YS4gIA0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQpjb2VmX2ZyPC0gZnJlZWxvMjEgJT4lIA0KICBtdXRhdGUoYmFzZV9jb2VmaWNpZW50ZT1mY3RfY29sbGFwc2UoYmFzZV9jb2VmaWNpZW50ZSwgIk1lbnN1YWwiID0gIlJlbXVuZXJhY2nDs24gbWVuc3VhbCBkZWwgaW5ncmVzYW50ZSIpLA0KICAgICAgICAgYmFzZV9jb2VmaWNpZW50ZT1mY3RfY29sbGFwc2UoYmFzZV9jb2VmaWNpZW50ZSwgIkFudWFsIiA9ICJSZW11bmVyYWNpw7NuIGFudWFsIGRlbCBpbmdyZXNhbnRlIiksDQogICAgICAgICAgYmFzZV9jb2VmaWNpZW50ZSA9IGZhY3RvcihiYXNlX2NvZWZpY2llbnRlLCBsZXZlbHMgPWMoIk1lbnN1YWwiLCJBbnVhbCIgKSkpDQoNCg0KIGNvZWZfZnIgJT4lDQogIHNlbGVjdChzZXJ2aWNpb19idXNxdWVkYSxiYXNlX2NvZWZpY2llbnRlKSAlPiUNCiAgZmlsdGVyKHNlcnZpY2lvX2J1c3F1ZWRhPT0iU2kiKSAlPiUgDQogIG11dGF0ZShjdWVudGEgPSAxKSAlPiUgDQogIGdyb3VwX2J5KGJhc2VfY29lZmljaWVudGUpICU+JQ0KICBzdW1tYXJpc2UoQ3VlbnRhID0gc3VtKGN1ZW50YSkpICU+JSANCiAgYXJyYW5nZSgtQ3VlbnRhKSU+JSANCiAgcmVuYW1lKCJSZW11bmVyYWNpw7NuIGRlbCBJbmdyZXNhbnRlIj1iYXNlX2NvZWZpY2llbnRlKSAlPiUgDQogIGthYmxlKCJodG1sIiwgZXNjYXBlPUYpICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiICkpICU+JSANCiAgcm93X3NwZWMoMCwgYm9sZD1ULCBjb2xvcj0id2hpdGUiLCBiYWNrZ3JvdW5kID0gYXp1bCkNCg0KDQpgYGANCg0KTGEgbWF5b3LDrWEgY29icmEgdW4gcG9yY2VudGFqZSAgcXVlIHZhIGRlbCAgMjAlIGFsIDMwJSBkZSAgbGFzIHJlbXVuZXJhY2lvbmVzIG1lbnN1YWxlcyBkZSBsb3MgaW5ncmVzYW50ZXMsIGNvbW8gcG9kZW1vcyB2ZXIgZW4gZWwgc2lndWllbnRlIGN1YWRybzoNCg0KDQpgYGB7ciBlY2hvPUZBTFNFICwgbWVzc2FnZT0gRkFMU0UsICB3YXJuaW5nID0gRkFMU0V9DQoNCiMjIGFybW8gbGFzIGNhdGVnb3JpYXMNCg0KI2ZyZWVsbzIxJGNvZWZpY2llbnRlICNjb25zdWx0byBjYXRlZ29yaWFzDQoNCm5fY29lZjwtIGZyZWVsbzIxICU+JSANCiAgc2VsZWN0KHNlcnZpY2lvX2J1c3F1ZWRhLGNvZWZpY2llbnRlLGJhc2VfY29lZmljaWVudGUpICU+JSANCiAgZmlsdGVyKHNlcnZpY2lvX2J1c3F1ZWRhPT0iU2kiKSAlPiUgDQogIGZpbHRlcihiYXNlX2NvZWZpY2llbnRlPT0iUmVtdW5lcmFjacOzbiBtZW5zdWFsIGRlbCBpbmdyZXNhbnRlIikgJT4lIA0KICBmaWx0ZXIoY29lZmljaWVudGU+MTApJT4lICAjRmlsdHJvIGVudHJlIDAtMTAwIChkZWNpZG8gZWxpbWluYXIgMS4yLDEuNSwyLjAgeSBvdHJvcywgcG9ycXVlIG5vIGVzIGNsYXJhIHN1IGNhdGVnb3JpemFjaW9uKQ0KICBmaWx0ZXIoY29lZmljaWVudGU8MTAxKSAlPiUgDQogIG11dGF0ZShjb2VmaWNpZW50ZSA9Y2FzZV93aGVuKA0KICAgICAgY29lZmljaWVudGUgPCAxMSB+ICIxMCUiLA0KICAgIGNvZWZpY2llbnRlIDwgMjEgfiAiMjAlIiwNCiAgICBjb2VmaWNpZW50ZSA8IDMxIH4gIjMwJSIsDQogICAgICAgIGNvZWZpY2llbnRlIDwgNDEgfiAiNDAlIiwNCiAgICBjb2VmaWNpZW50ZSA8IDUxIH4gIjUwJSIsDQogICAgY29lZmljaWVudGUgPCA2MSB+ICI2MCUiLA0KICAgIGNvZWZpY2llbnRlIDwgNzEgfiAiNzAlIiwNCiAgICBjb2VmaWNpZW50ZSA8IDgxIH4gIjgwJSIsDQogICAgY29lZmljaWVudGUgPCA5MSB+ICI5MCUiLA0KICAgIGNvZWZpY2llbnRlIDwxMDEgfiAiMTAwJSIsDQogICAgY29lZmljaWVudGUgPSBUIH4gIk90cm9zIiksDQogICAgY29lZmljaWVudGUgPSBmY3RfcmVsZXZlbChjb2VmaWNpZW50ZSwgYygiMTAlIiwiMjAlIiwiMzAlIiwiNDAlIiwiNTAlIiwiNjAlIiwiNzAlIiwiODAlIiwiOTAlIiwiMTAwJSIsIk90cm9zIikpKQ0KICANCiMgYWdydXBvIGxhcyBjYXRlZ29yaWFzIGVuIHVuYSB0YWJsYS4NCg0KIG5fY29lZjwtIG5fY29lZiAlPiUNCiAgc2VsZWN0KGNvZWZpY2llbnRlKSAlPiUNCiAgbXV0YXRlKGN1ZW50YSA9IDEpICU+JSANCiAgZ3JvdXBfYnkoY29lZmljaWVudGUpICU+JQ0KICBzdW1tYXJpc2UoQ3VlbnRhID0gc3VtKGN1ZW50YSkpICU+JSANCiAgI2FycmFuZ2UoLUN1ZW50YSklPiUgDQogIHJlbmFtZSgiUG9yY2VudGFqZSI9Y29lZmljaWVudGUpDQogDQogbl9jb2VmJFRJUCA8LSBjKCIlIFNvYnJlIGxhIFJlbXVuZXJhY2nDs24gTWVuc3VhbCIpICMgYWwgcGFzYXIgZWwgY3Vyc29yIHNlIHZlDQogDQogI1RhYmxhDQoNCm5fY29lZiAlPiUgDQogIG11dGF0ZShDdWVudGE9dGV4dF9zcGVjKEN1ZW50YSwgImh0bWwiLCB0b29sdGlwPVRJUCkpICU+JSANCiAgICBzZWxlY3QoUG9yY2VudGFqZSxDdWVudGEpICU+JSANCiAga2FibGUoImh0bWwiLCBlc2NhcGU9RikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFLCBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJob3ZlciIsImNvbmRlbnNlZCIgKSkgJT4lIA0KICByb3dfc3BlYygwLCBib2xkPVQsIGNvbG9yPSJ3aGl0ZSIsIGJhY2tncm91bmQgPSBhenVsKQ0KDQoNCmBgYA0KDQoNCg0K