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.

pais_rd <- rh22 %>% 
  group_by(pais) %>% 
  tally() %>% 
  ungroup 

pais_freelo <- freelo22 %>% 
  group_by(pais) %>% 
  tally() %>% 
  ungroup 

paises_kiwi <- full_join(pais_freelo, pais_rd, by = "pais") %>% 
    mutate(n.x = coalesce(n.x, 0),
         n.y = coalesce(n.y, 0),
         n = n.x + n.y)

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 7 de octubre y el 22 de noviembre de 2021.

En esta edición recibimos 361 respuestas de 12 países diferentes.

paises_kiwi %>%
  arrange(-n, pais) %>% 
  select(pais, n) %>% 
  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 302
Paraguay 14
México 10
Perú 10
Bolivia 7
España 5
Chile 4
Uruguay 4
El Salvador 2
Ecuador 1
Guatemala 1
Otro Europa 1
Note:
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2022

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

paises_kiwi <- paises_kiwi %>% 
  group_by(pais) %>% 
  summarise(total_freelo = sum(n.x),
            total_rd = sum(n.y)) %>% 
  ungroup() %>% 
  pivot_longer(cols = c("total_freelo", "total_rd"),
               names_to = "trabajo",
               values_to = "rtas")

kiwi %>% 
  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)

Como aclaración, cuando nos referimos a la identidad de género de las personas, utilizamos los términos 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----
rh22 <- rh22 %>% 
  mutate(genero = fct_collapse(genero,  "Hombre cis" = c("Hombre cis", "Varon")))

div <- rh22 %>% 
  select(genero) %>% 
  mutate(genero = factor(genero, 
                         levels = c("Mujer cis", "Hombre cis", "Mujer trans"))) %>% 
  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(lila, verde, amarillo)) +
  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 identidad de género",
       subtitle = "Relación de Dependencia",
       fill = "Identidad de Género", 
       caption = fuente)

# Gráfico de freelancers ----
freelo22 <- freelo22 %>% 
  mutate(genero = fct_collapse(genero, "Mujer cis" = c("Mujer cis", "Mujer")))

div <- freelo22 %>% 
  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(verde, lila)) +
  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 identidad de género",
       subtitle = "Freelancers",
       fill = "Identidad de 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.

# Corregir identidad de género
kiwi <- kiwi %>% 
    mutate(genero = fct_collapse(genero, "Mujer cis" = c("Mujer cis", "Mujer"),
                               "Hombre cis" = c("Hombre cis", "Varon")),
         genero = factor(genero, levels = c("Mujer cis", "Hombre cis")))

# Crear tabla
kiwi %>% 
  group_by(genero) %>% 
  tally(sort = T) %>% 
  mutate(Porcentaje = n/sum(n),
         Porcentaje = percent(Porcentaje, accuracy = 0.1)) %>% 
  janitor::adorn_totals() %>% 
  rename("Identidad de 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
Identidad de Género Cantidad Porcentaje
Mujer cis 261 71.7%
Hombre cis 101 27.7%
NA 2 0.5%
Total 364
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2022

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 <- rh22 %>% 
  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$501 y 4656 respectivamente, 
# podamos todo lo que esté fuera de ese rango

media_pais <- sueldos_dolar %>% 
  filter(pais %in% c("Argentina", "Paraguay", "México", "Perú", "Bolivia", "España"),
         between(sueldo_dolar,poda_p05,poda_p95)) %>% 
  group_by(pais) %>% 
  summarise(sueldop = list(mean_se(sueldo_dolar))) %>% 
  unnest(cols = c(sueldop)) 
 
sueldo_dolar_pais <- rh22 %>% 
  select(pais, sueldo_dolar) %>% 
  filter(between(sueldo_dolar, poda_p05, poda_p95),
         pais %in% c("Argentina", "Paraguay", "México", "Perú", "Bolivia", "España"))

# 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 5 o más respuestas"),
       x = NULL, y = NULL) + 
  estiloh

En España se encuentran los sueldos más altos de la muestra. Dentro de Latinoamérica, México es el país con mejores sueldos de la región seguido por Argentina. Obtuvimos muy pocas respuestas de Uruguay y Chile, que en las dos ediciones anteriores tenían los sueldos de la región, pero por la baja cantidad de respuestas, fueron excluidos del presente análisis.

Análisis de sueldos por puestos en Latinoamérica

# Crear un data frame sólo con países de Latinoamérica
rh22la <- rh22 %>% 
  filter(pais != "España")

# Gráficos de sueldo promedio por puesto
rh22la %>% 
  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) +
  geom_text(aes(label = comma(mediana_salarial, accuracy = 1,prefix = "USS ",
                              decimal.mark = ",", big.mark = ".")),
                color = "#FBFCFC",
                hjust = 1.2,
            fontface = "bold",
            size = 3) +
  estilov +
  labs(title = "Mediana salarial por puesto", 
       subtitle = "Sueldos de RRHH en U$S", 
       x = "", y = "", 
       caption = fuente) +
  eje_x_n

La posición de HRBP presenta una complejidad, que es que dependiendo la empresa el rol es similar al de un Manager, o en otros casos es un Analista Especializado o Senior. Por esa razón tiene una mediana salarial más alta que los Responsables. Es por eso que encontramos entre los HRBP encontramos un suledo mínimo similar al de los analistas y salarios máximos mayores que el de los directores.

gt(rh22la %>% 
     select(puesto, sueldo_dolar) %>% 
     filter(puesto != "Pasante",
            between(sueldo_dolar, poda_p05, poda_p95)) %>% 
     group_by(puesto) %>% 
     summarise(minimo = min(sueldo_dolar),
               mediana_salarial = median(sueldo_dolar),
               maximo = max(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 =  c("mediana_salarial", "minimo", "maximo"), decimals = 0,
               sep_mark = ".", dec_mark = ",") %>% 
  cols_label(puesto = "Posición",
             minimo = "Mínimo",
             mediana_salarial = "Mediana",
             maximo = "Máximo",
             cant = "Respuestas") 
Mediana salarial por puestos
Sueldos en U$D
Posición Mínimo Mediana Máximo Respuestas
Director $1.402 $3.491 $3.782 5
Gerente $1.024 $2.910 $4.422 42
Jefe $1.338 $2.037 $4.655 36
Responsable $512 $1.294 $4.073 53
HRBP $519 $1.750 $4.655 29
Analista $503 $1.216 $3.200 111
Administrativo $550 $616 $1.455 7
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2022

Anállisis por Funciones

Al igual que en ediciones anteriores, las funciones de RH más especializadas como Diseño Organizacional, Cultura y Bienestar y People Analytics cuentan con salarios más altos, mientras que funciones más transaccionales como Administración de Personal están dentro de los más bajos.

# Calcular la mediana salarial 
funcion_rh <- rh22la %>% 
  filter(puesto != "Pasante",
         between(sueldo_dolar, poda_p05, poda_p95)) %>% 
  group_by(funcion) %>% 
  summarise(mediana = median(sueldo_dolar),
            cant = n()) %>% 
  arrange(-mediana)

min_funcion <- round(min(funcion_rh$mediana))
max_funcion <- round(max(funcion_rh$mediana))

# Gráfico
ggplot(funcion_rh, aes(x = mediana, y = reorder(funcion, mediana))) +
  geom_point(color = azul, size = 3) +
  geom_segment(aes(x = 0, xend = mediana, 
                   y = funcion, yend = funcion),
               color = azul) +
  labs(title = "Mediana Salarial por Función en LATAM",
       subtitle = "Sueldos de RRHH en U$S",
       x = NULL, y = NULL,
       caption = fuente) +
  geom_text(aes(label = comma(mediana, accuracy = 1,prefix = "USS ",
                              decimal.mark = ",", big.mark = ".")),
                color = azul,
                hjust = -.2,
            fontface = "bold",
            size = 3) +
  estilov +
  eje_x_n +
  scale_x_continuous(limits = c(0, 3000)) 

Nuevamente es necesario aclarar que hay funciones donde no tenemos mucha cantidad de respuestas como Compliance donde sólo tenemos un solo caso, pero la diferencia entre las funciones con mayores sueldos, y con los menores sueldos es muy amplia (U$D 1851).

gt(rh22la %>% 
     filter(puesto != "Pasante",
            between(sueldo_dolar, poda_p05, poda_p95)) %>% 
     select(funcion, sueldo_dolar) %>% 
     group_by(funcion) %>% 
     summarise(minimo = min(sueldo_dolar),
               mediana_salarial = median(sueldo_dolar),
               maximo = max(sueldo_dolar),
               cant = n())
     ) %>% 
  tab_header(title = "Mediana salarial por Función", 
             subtitle = "Sueldos en U$D") %>% 
  tab_source_note(source_note = fuente) %>% 
   fmt_currency(columns =  c("mediana_salarial", "minimo", "maximo"), decimals = 0,
               sep_mark = ".", dec_mark = ",") %>% 
  cols_label(funcion = "Función",
             minimo = "Mínimo",
             mediana_salarial = "Mediana",
             maximo = "Máximo",
             cant = "Respuestas") 
Mediana salarial por Función
Sueldos en U$D
Función Mínimo Mediana Máximo Respuestas
Administración de personal $512 $1.109 $2.502 27
Capacitación y desarrollo $616 $1.696 $3.491 16
Compensaciones y beneficios $763 $1.397 $3.491 13
Compliance $768 $768 $768 1
Comunicación interna $1.216 $1.216 $1.216 1
Payroll / Liquidación de sueldos $943 $1.362 $2.037 19
Cultura y bienestar $815 $2.386 $3.491 3
Diseño organizacional $908 $2.619 $3.592 9
Generalista $512 $1.724 $4.655 116
Gestión de expatriados $1.110 $1.110 $1.110 1
HRIS / Administración de sistemas de RH $832 $1.519 $4.655 6
People analytics $1.145 $1.747 $2.724 15
Reclutamiento y selección $503 $1.235 $4.452 52
Relaciones laborales $1.024 $1.390 $1.978 4
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2022

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.

rh22la %>% 
  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 <- rh22la %>% 
  select(puesto, sueldo_dolar, origen_capital) %>% 
  filter(between(sueldo_dolar, poda_p05, poda_p95),
         puesto != "Pasante") %>% 
  group_by(puesto, origen_capital) %>% 
  summarise(mediana_salarial = round(median(sueldo_dolar)))

CGPfunctions::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 <- rh22la %>% 
  select(rubro) %>% 
  group_by(rubro) %>% 
  count(sort = TRUE) %>%
  filter(rubro != "Otros", n > 30) %>% 
  pull(var = rubro)


rh22la %>% 
  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:

rh22la %>% 
    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()) %>% 
  ungroup() %>% 
    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
Silvicultura, madera, celulosa, papel 3346 206 2
Industrias químicas 3200 1376 7
Bancos, banca online 2470 1058 6
Agricultura, plantaciones, otros sectores rurales 2409 967 4
Servicios financieros seguros 2124 921 14
Minería 2095 812 3
Petróleo y producción de gas, refinación de petróleo 2095 514 9
Industria siderúrgica 1858 1640 2
Transporte (incluyendo aviación civil, ferrocarriles por carretera) 1804 783 3
Terminales automotrices, fábricas autopartistas, y afines 1705 364 3
Servicios de salud 1680 639 26
Función pública 1678 700 7
Otros 1676 968 32
Servicios profesionales 1571 538 9
Textiles, vestido, cuero, calzado 1549 839 4
Comercio 1501 733 19
Servicios públicos (agua, gas, electricidad) 1484 NA 1
Tecnologías de información 1472 1031 64
Medios de comunicación, cultura, gráficos 1338 234 5
Construcción 1280 569 9
Industria metalúrgica, metalmecánica 1228 884 12
Ingeniería mecánica 1222 NA 1
Alimentación, bebidas 1212 778 18
Servicios de consultoría 1190 1200 18
Educación 1158 656 4
Hotelería, restauración, turismo 1035 NA 1
Transporte marítimo, puertos 512 NA 1

Análisis por países

En esta sección analizaremos la situación salarial de RRHH únicamente de cuatro países: Argentina, Paraguay, México y Perú únicamente, por la cantidad de respuestas. Del resto de los países tenemos menos de 8 respuestas, por lo que es imposible realizar un análisis serio.

Paraguay

Análisis por puesto

# Preproceso -----

# Filtrar los sueldos extremos
rh22la_clean <- rh22la %>% 
  filter(puesto != "Pasante",
         between(sueldo_dolar, poda_p05, poda_p95)) %>% 
  mutate(rubro = str_wrap(rubro, width = 30))

# Limpiar datos 2020
df2020 <-  profiling_num(kiwi20$sueldo_dolar)
p05_20 <- df2020[1,6]
p95_20 <- df2020[1,10]

rh20 <- kiwi20 %>% filter(between(sueldo_dolar, p05_20, p95_20)) %>% 
  mutate(anio = 2020) %>% 
  select(anio, pais, puesto, funcion = funcion_rh, sueldo_bruto) 


# Limpiar datos 2021
df2021 <- profiling_num(kiwi21$sueldo_dolar)
p05_21 <- df2021[1,6]
p95_21 <- df2021[1,10]

rh21 <- kiwi21 %>% filter(between(sueldo_dolar, p05_20, p95_20)) %>% 
  mutate(anio = 2021) %>% 
  select(anio, pais, puesto, funcion, sueldo_bruto) 



# Filtrar por Paraaguay ----
rh_py <- rh22la_clean %>% 
  filter(pais == "Paraguay") %>% 
  mutate(anio = 2022)

rh20py <- rh20 %>% 
  filter(pais == "Paraguay")

rh21py <- rh21 %>% 
  filter(pais == "Paraguay")

rh22py <- rh_py %>% 
    select(anio, pais, puesto, funcion, sueldo_bruto) 

# Para analizar evolución de salarios
# Evolucion
historico <- rbind(rh20py, rh21py, rh22py)

# Salario por puesto 

rh_py %>% 
  group_by(puesto) %>% 
  summarise(mediana = median(sueldo_bruto)) %>%
  ungroup() %>% 
  ggplot(aes(x = fct_rev(puesto), y = mediana)) +
  geom_col(fill = "#0038a8") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            vjust = 1.2,
            size = 3, 
            color = "white") +
  eje_y_n +
  estiloh +
  labs(title = "Mediana Salarial por Puesto",
       subtitle = "Datos de Paraguay - En Gs.",
       x = NULL, y = NULL,
       caption = fuente)

Análisis por función

rh_py %>% 
  group_by(funcion) %>% 
  summarise(mediana = median(sueldo_bruto)) %>%
  ungroup() %>% 
  ggplot(aes(y = reorder(funcion, mediana), x = mediana)) +
  geom_col(fill = "#0038a8") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            hjust = 1.2,
            size = 3, 
            color = "white") +
  eje_x_n +
  estilov +
  labs(title = "Mediana Salarial por Puesto",
       subtitle = "Datos de Paraguay - En Gs.",
       x = NULL, y = NULL,
       caption = fuente)

Análisis por rubro

rh_py %>% 
  group_by(rubro) %>% 
  summarise(mediana = median(sueldo_bruto)) %>%
  ungroup() %>% 
  ggplot(aes(y = reorder(rubro, mediana), x = mediana)) +
  geom_col(fill = "#0038a8") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            hjust = 1.2,
            size = 3, 
            color = "white") +
  eje_x_n +
  estilov +
  labs(title = "Mediana Salarial por Puesto",
       subtitle = "Datos de Paraguay - En Gs.",
       x = NULL, y = NULL,
       caption = fuente)

Evolución

La evolución de los salarios en moneda local puede ser contraintuitiva dada la baja cantidad de respuestas obtenidas por año.

historico %>% 
  group_by(anio) %>% 
  summarise(mediana = median(sueldo_bruto)) %>% 
  ungroup %>% 
  ggplot(aes(x = anio, y = mediana)) +
  geom_col(fill = "#0038a8") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            vjust = 1.2, color = "white") +
  eje_y_n +
  estiloh +
  labs(title = "Mediana Salarial por Año",
       subtitle = "Datos de Paraguay - En Gs.",
       x = NULL, y = NULL,
       caption = fuente)

México

Análisis por puesto

# Filtrar por México ----
rh_mx <- rh22la_clean %>% 
  filter(pais == "México") %>% 
  mutate(anio = 2022)


rh_mx <- rh22la %>% 
  filter(pais == "México") %>% 
  mutate(anio = 2022)

rh20mx <- rh20 %>% 
  filter(pais == "México")

rh21mx <- rh21 %>% 
  filter(pais == "México")

rh22mx <- rh_mx %>% 
    select(anio, pais, puesto, funcion, sueldo_bruto) 

# Para analizar evolución de salarios
# Evolucion
historico <- rbind(rh20mx, rh21mx, rh22mx)

# Salario por puesto 

rh_mx %>% 
  group_by(puesto) %>% 
  summarise(mediana = median(sueldo_bruto)) %>%
  ungroup() %>% 
  ggplot(aes(x = fct_rev(puesto), y = mediana)) +
  geom_col(fill = "#006847") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            vjust = 1.2,
            size = 3, 
            color = "white") +
  eje_y_n +
  estiloh +
  labs(title = "Mediana Salarial por Puesto",
       subtitle = "Datos de México - En MX$",
       x = NULL, y = NULL,
       caption = fuente)

Análisis por función

rh_mx %>% 
  group_by(funcion) %>% 
  summarise(mediana = median(sueldo_bruto)) %>%
  ungroup() %>% 
  ggplot(aes(y = reorder(funcion, mediana), x = mediana)) +
  geom_col(fill = "#006847") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            hjust = 1.2,
            size = 3, 
            color = "white") +
  eje_x_n +
  estilov +
  labs(title = "Mediana Salarial por Puesto",
       subtitle = "Datos de México - En MX$",
       x = NULL, y = NULL,
       caption = fuente)

Análisis por rubro

rh_mx %>% 
  group_by(rubro) %>% 
  summarise(mediana = median(sueldo_bruto)) %>%
  ungroup() %>% 
  ggplot(aes(y = reorder(rubro, mediana), x = mediana)) +
  geom_col(fill = "#006847") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            hjust = 1.2,
            size = 3, 
            color = "white") +
  eje_x_n +
  estilov +
  labs(title = "Mediana Salarial por Puesto",
       subtitle = "Datos de México - En MX$",
       x = NULL, y = NULL,
       caption = fuente)

Evolución

La evolución de los salarios en moneda local puede ser contraintuitiva dada la baja cantidad de respuestas obtenidas por año.

historico %>% 
  group_by(anio) %>% 
  summarise(mediana = median(sueldo_bruto)) %>% 
  ungroup %>% 
  ggplot(aes(x = anio, y = mediana)) +
  geom_col(fill = "#006847") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            vjust = 1.2, 
            color = "white") +
  eje_y_n +
  estiloh +
  labs(title = "Mediana Salarial por Año",
       subtitle = "Datos de México - En MX$",
       x = NULL, y = NULL,
       caption = fuente)

Perú

Análisis por puesto

# Filtrar por México ----
rh_pe <- rh22la_clean %>% 
  filter(pais == "Perú") %>% 
  mutate(anio = 2022)


rh20pe <- rh20 %>% 
  filter(pais == "Perú")

rh21pe <- rh21 %>% 
  filter(pais == "Perú")

rh22pe <- rh_pe %>% 
    select(anio, pais, puesto, funcion, sueldo_bruto) 

# Para analizar evolución de salarios
# Evolucion
historico <- rbind(rh20pe, rh21pe, rh22pe)

# Salario por puesto 

rh_pe %>% 
  group_by(puesto) %>% 
  summarise(mediana = median(sueldo_bruto)) %>%
  ungroup() %>% 
  ggplot(aes(x = fct_rev(puesto), y = mediana)) +
  geom_col(fill = "#D91023") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            vjust = 1.2,
            size = 3, 
            color = "white") +
  eje_y_n +
  estiloh +
  labs(title = "Mediana Salarial por Puesto",
       subtitle = "Datos de Perú - En S/",
       x = NULL, y = NULL,
       caption = fuente)

Análisis por función

rh_pe %>% 
  group_by(funcion) %>% 
  summarise(mediana = median(sueldo_bruto)) %>%
  ungroup() %>% 
  ggplot(aes(y = reorder(funcion, mediana), x = mediana)) +
  geom_col(fill = "#D91023") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            hjust = 1.2,
            size = 3, 
            color = "white") +
  eje_x_n +
  estilov +
  labs(title = "Mediana Salarial por Puesto",
       subtitle = "Datos de Perú - En S/",
       x = NULL, y = NULL,
       caption = fuente)

Análisis por rubro

rh_pe %>% 
  group_by(rubro) %>% 
  summarise(mediana = median(sueldo_bruto)) %>%
  ungroup() %>% 
  ggplot(aes(y = reorder(rubro, mediana), x = mediana)) +
  geom_col(fill = "#D91023") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            hjust = 1.2,
            size = 3, 
            color = "white") +
  eje_x_n +
  estilov +
  labs(title = "Mediana Salarial por Puesto",
       subtitle = "Datos de Perú - En S/",
       x = NULL, y = NULL,
       caption = fuente)

Evolución

La evolución de los salarios en moneda local puede ser contraintuitiva dada la baja cantidad de respuestas obtenidas por año.

historico %>% 
  group_by(anio) %>% 
  summarise(mediana = median(sueldo_bruto)) %>% 
  ungroup %>% 
  ggplot(aes(x = anio, y = mediana)) +
  geom_col(fill = "#D91023") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            vjust = 1.2, 
            color = "white") +
  eje_y_n +
  estiloh +
  labs(title = "Mediana Salarial por Año",
       subtitle = "Datos de Perú - En S/",
       x = NULL, y = NULL,
       caption = fuente)

Argentina

Análisis por puesto

# Filtrar por Argentina ----
rh_ar <- rh22la_clean %>% 
  filter(pais == "Argentina") %>% 
  mutate(anio = 2022)


rh20ar <- rh20 %>% 
  filter(pais == "Argentina")

rh21ar <- rh21 %>% 
  filter(pais == "Argentina")

rh22ar <- rh_ar %>% 
    select(anio, pais, puesto, funcion, sueldo_bruto) 

# Para analizar evolución de salarios
# Evolucion
historico <- rbind(rh20ar, rh21ar, rh22ar)

# Unificar nombres de funciones
historico <- historico %>% 
  mutate(funcion = fct_collapse(funcion, 
                                "Cultura y Clima" = c("Cultura y bienestar","Clima & Cultura"),
                                "Administración de Personal" = c("Administración de personal",
                                                                 "Administración de Personal"),
                                "Capacitación y Desarrollo" = c("Capacitación y desarrollo",
                                                                "Capacitación y desarrollo"),
                                "Compensaciones y Beneficios" = "Compensaciones y beneficios",
                                "Comunicación Interna" = c("Comunicación Interna", 
                                                           "Comunicación interna"),
                                "Diseño Organizacional" = c("Diseño Organizacional",
                                                            "Diseño organizacional"),
                                "Payroll" = c("Payroll",
                                              "Payroll / Liquidación de sueldos"),
                                "People Analytics" = c("People Analytics", 
                                                       "People analytics"),
                                "Reclutamiento" = c("Reclutamiento",
                                                    "Reclutamiento y selección"))) 

# Salario por puesto 

rh_ar %>% 
  group_by(puesto) %>% 
  summarise(mediana = median(sueldo_bruto)) %>%
  ungroup() %>% 
  ggplot(aes(x = fct_rev(puesto), y = mediana)) +
  geom_col(fill = "#75AADB") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            vjust = 1.2,
            size = 3, 
            color = "white") +
  eje_y_n +
  estiloh +
  labs(title = "Mediana Salarial por Puesto",
       subtitle = "Datos de Argentina - En AR$",
       x = NULL, y = NULL,
       caption = fuente)

Dado que el puesto de HRBP en algunas compañías es un analista senior, y en otras es un puesto gerencial, explicaría el por qué la mediana salarial es mayor que el caso de los Responsables, que es una figura que se usa mayormente en empresas con estructuras pequeñas.

Evolución

historico %>% 
  group_by(anio) %>% 
  summarise(mediana = median(sueldo_bruto)) %>% 
  ungroup %>% 
  ggplot(aes(x = anio, y = mediana)) +
  geom_col(fill = "#75AADB") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            vjust = 1.2, 
            color = "white") +
  eje_y_n +
  estiloh +
  labs(title = "Mediana Salarial por Año",
       subtitle = "Datos de Argentina - En AR$",
       x = NULL, y = NULL,
       caption = fuente)

historico_tabla <- historico %>% 
  group_by(anio) %>% 
  summarise(mediana = median(sueldo_bruto)) %>% 
  ungroup 

La mediana salarial del año 2022 en comparación al 2021 creció un 117% mientras que el año anterior el incremento ha sido de un 67%.

Análisis por función

Nuevamente encontramos que los salarios de las funciones más sofisticadas se encuentran dentro de los salarios más altos, mientras que en roles más operativos encontramos salarios más bajos.

rh_ar %>% 
  group_by(funcion) %>% 
  summarise(mediana = median(sueldo_bruto)) %>%
  ungroup() %>% 
  ggplot(aes(y = reorder(funcion, mediana), x = mediana)) +
  geom_col(fill = "#75AADB") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            hjust = 1.2,
            size = 3, 
            color = "white") +
  eje_x_n +
  estilov +
  labs(title = "Mediana Salarial por Puesto",
       subtitle = "Datos de Argentina - En AR$",
       x = NULL, y = NULL,
       caption = fuente)

A continuación podemos apreciar el incremento salarial en comparación con el año anterior de los roles en los cuales tenemos información.

historico %>% 
  filter(anio != 2020,
         !funcion %in% c("HRIS / Administración de sistemas de RH",
                         "Control de Gestión",
                         "Gestión de expatriados")) %>% 
  group_by(funcion, anio) %>%
  summarise(mediana = median(sueldo_bruto)) %>% 
  ungroup %>% 
  ggplot(aes(y = fct_rev(funcion), x = mediana, fill = factor(anio))) +
  geom_col(position = "dodge") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            position = position_dodge(0.9),
            hjust = 1.2,
            size = 2, 
            color = "white") +
  theme(legend.position = "top") +
  guides(fill = guide_legend(reverse=TRUE)) +
  scale_fill_manual(values = c(gris, "#75AADB")) +
  estilov +
  eje_x_n +
  labs(title = "Evolución Salarial por Función",
       subtitle = "En AR$",
       x = NULL, y = NULL,
       caption = fuente,
       fill = "Año")

Análisis por rubro

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

rh_ar %>% 
  group_by(rubro) %>% 
  summarise(mediana = median(sueldo_bruto)) %>%
  ungroup() %>% 
  ggplot(aes(y = reorder(rubro, mediana), x = mediana)) +
  geom_point(color = azul) +
  geom_segment(aes(x = 0, xend = mediana, y = rubro, yend = rubro), 
               color = "#75AADB") +
  geom_text(aes(label = comma(mediana, big.mark = ".", decimal.mark = ",")),
            hjust = -0.2,
            size = 2.8) +
  scale_x_continuous(limits = c(0, 700000), labels = comma_format(big.mark = ".", 
                                                                   decimal.mark = ";")) +
  estilov +
  labs(title = "Mediana Salarial por Puesto",
       subtitle = "Datos de Argentina - En AR$",
       x = NULL, y = NULL,
       caption = fuente)

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 = 40)


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 la línea en el centro de la caja. Los puntos violetas y verdes representan a las mujeres y los hombres respectivamente en cada uno de los puestos.

rh_ar %>% 
    filter(genero %in% c("Mujer cis", "Hombre cis"),
         puesto != "Director",
         rubro %in% c("Tecnologías de información",
                      "Servicios de consultoría",
                      "Servicios de salud",
                      "Alimentación, bebidas",
                      "Comercio",
                      "Servicios profesionales")) %>% 
  ggplot(aes(x = fct_rev(puesto), y = sueldo_bruto)) +
  geom_boxplot(width = 0.4, alpha = 0.3, fill = gris) +
  geom_point(aes(y = sueldo_bruto, color = genero), alpha = 0.4,
             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",
        legend.position = "top")

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_rh, 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_rh, 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.208 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.208 nos indica que los años de experiencia explican un 20.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_rh, 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 Administrativos. En el resto de los puestos los años de trayectoria influyen muy poco en los sueldos de cada uno de los puestos. En el caso de los Directores también vemos una relación muy fuerte pero negativa. En ambos casos lo podemos atribuir a la baja cantidad de respuestas que afecta la calidad de este análisis.

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.

rh_ar %>% 
  filter(genero %in% c("Hombre cis", "Mujer cis")) %>% 
ggplot(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) +
  theme(legend.position = "none")

Si bien hay outliers entre las mujeres con sueldos muy altos, los salarios de los hombres en general suelen ser más altos que el de las mujeres, por eso vemos que la caja de los hombres es más alta que el de las mujeres.

Análisis según género

Cuando analizamos la distribución salarial por puesto, apreciamos desigualdades que se repiten de años anteriores. Antes de profundizar, expliquemos brevemente cómo interpretar el gráfico que vemos a continuación que se llama boxplot.

En primer lugar, la parte inferior de cada caja indica el valor del primer cuartil, es decir el límite donde se encuentra el 25% de los datos. Por otra parte, la parte superior de cada caja indica el tercer cuartil, o sea, el 75% de los datos. Esto implica que dentro de la caja nos encontramos con la mitad de los datos. La cantidad de casos dentro de cada mitad es la misma para cada caja.

Un elemento muy importante dentro del gráfico es la línea que observamos dentro de cada caja que representa a la mediana que es el valor que divide a la mitad a los datos. Este es el valor que habitualmente utilizamos para comparar salarios porque representa el punto medio para cada grupo y además no es sensible a valores extremos como el promedio. La mediana es el valor que vamos a usar para comparar los sueldos entre hombres y mujeres.

Los puntos que observamos en algunos casos indican valores extremos que denominamos outliers. Estos valores son atípicos. Las líneas que salen de las cajas indican los límites a partir de los cuales se determina que un valor es atípico o no.

Por último, el tamaño de la caja también es importante porque nos da una idea de la distribución de los datos. Si la caja es chiquita quiere decir que los sueldos están en un rango de valores cercano. En cambio si la caja, o una de sus mitades, es larga, eso nos indica que los sueldos tienen un rango más amplio, o sea que los sueldos llegan a valores más altos o más bajos dependiendo el caso, y que se alejan más de la mediana.

rh_ar %>% 
  filter(genero %in% c("Hombre cis", "Mujer cis"),
         !puesto %in% c("Director", "Administrativo")) %>% 
ggplot(aes(x = fct_rev(puesto), y = sueldo_bruto, fill = genero)) +
  geom_boxplot() +
  estiloh +
  scale_fill_manual(values = c(verde, lila)) +
  eje_y_n +
  labs(title = "Distribución Salarial según Identidad de Género",
       subtitle = "En AR$",
       fill = "Identidad de Género",
       x = NULL, y = NULL,
       caption = fuente) +
  theme(legend.position = "top")

En el gráfico anterior podemos apreciar que las medianas de los sueldos es más alta para los hombres en los roles de Analista, Responsables, y Jefes. En cambio en las mujeres podemos apreciar que las HBRP y Gerentes tienen medianas salariales más altas.

Analizando el rol de Analista podemos ver que en el caso de los hombres, además de observar una mediana salarial más amplia que en el caso de las mujeres, el tamaño de la caja es más amplia, lo que nos indica que los sueldos de los analistas varones tienen un rango más amplio llegando a sueldos más altos que sus pares mujeres. Podemos apreciar varios outliers por encima de los AR$ 400.000 tanto para hombres y mujeres.

En el rol de Jefe apreciamos que las medianas están algo alejadas y el tamaño de la caja nos indica que los rangos de los sueldos de los hombres alcanza valores más altos que en el caso de las mujeres, mientras que la mitad superior de las mujeres está concentrado en un rango de valores muy cercanos. También podemos observar que hay algunos casos de mujeres con sueldos muy altos indicados como outliers (puntos) alrededor de los AR$ 600.000.

Esta es otra opción para visualizar los gaps salariales.

brecha <- rh_ar %>% 
  filter(genero %in% c("Mujer cis", "Hombre cis"), 
         puesto %in% c("Gerente","Jefe", "HRBP","Responsable", "Analista")) %>% 
  mutate(puesto = factor(puesto, levels = c("Analista",  
                                            "HRBP", "Responsable", "Jefe",
                                            "Gerente","Director"))) %>% 
  group_by(genero, puesto) %>% 
  summarise(media_salarial = median(sueldo_bruto, na.rm = TRUE)) %>% 
  ungroup()


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 = 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), size = 3,
            nudge_y = .2) +
  labs(title = "Brecha salarial por puestos de RRHH",
       subtitle = "Mediana en Argentina",
       x = "",
       y = NULL, 
       caption = fuente) +
  scale_x_continuous(labels = comma_format(big.mark = ".", decimal.mark = ",")) +
  scale_color_manual(values = colores)

Si observamos la mediana salarial para cada puesto vemos que de acuerdo a las respuestas recolectadas las mujeres en puesto de Gerente tienen un sueldo un 10% mayor que los hombres en el mismo rol. No hay diferencia salarial en el puesto de HRBP.

Finalmente vemos que la brecha salarial en favor de los hombres es de un 16% en el rol de Jefe, un 14% para Responsables y de un 13% para los Analistas.

En la tabla a continuación veremos algunos datos que resumen estos hallazgos. Excluimos a los directores y administrativos porque tenemos muy pocas respuestas.

gt(rh_ar %>% 
  filter(genero %in% c("Hombre cis", "Mujer cis"), 
         !puesto %in% c("Director", "Administrativo")) %>% 
  group_by(puesto, genero) %>% 
  summarise(Rtas = n(),
            Min = min(sueldo_bruto),
            Mediana = median(sueldo_bruto),
            Promedio = mean(sueldo_bruto),
            Max = max(sueldo_bruto)
            ) %>% 
  ungroup() %>% 
  pivot_longer(cols = c("Rtas", "Min", "Mediana", "Promedio", "Max"),
               names_to = "Metrica",
               values_to = "Valor") %>% 
  pivot_wider(id_cols = c(puesto,genero),
              names_from = Metrica,
              values_from = Valor),
  groupname_col = "puesto") %>% 
  fmt_currency(columns = c(Min, Mediana, Promedio, Max),
               currency = "ARS",
               decimals = 0,
               sep_mark = ".",
               dec_mark = ",") %>% 
  tab_header(title = "Resumen Salarial por Puesto y Género",
             subtitle = "En AR$") %>% 
  tab_spanner(label = "Métricas Salariales",
              columns = c(Min, Mediana, Promedio, Max)) %>% 
  tab_source_note(source_note = fuente) %>% 
  cols_label(puesto = "Puesto",
             genero = "Género") %>% 
  tab_options(row_group.background.color = "#A3E4D7",)
Resumen Salarial por Puesto y Género
En AR$
Género Rtas Métricas Salariales
Min Mediana Promedio Max
Gerente
Hombre cis 13 $176.000 $500.000 $494.077 $736.000
Mujer cis 23 $235.000 $550.000 $497.863 $760.000
Jefe
Hombre cis 9 $250.000 $400.000 $426.668 $800.000
Mujer cis 20 $230.000 $337.425 $377.125 $623.000
Responsable
Hombre cis 15 $157.300 $255.000 $290.911 $700.000
Mujer cis 31 $88.000 $220.000 $231.612 $504.630
HRBP
Hombre cis 1 $300.000 $300.000 $300.000 $300.000
Mujer cis 24 $143.000 $301.500 $334.785 $800.000
Analista
Hombre cis 21 $90.000 $230.000 $251.676 $550.000
Mujer cis 75 $99.000 $200.000 $225.132 $500.000
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2022

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:

kiwi %>% 
  select(pais, tipo_universidad) %>% 
  group_by(pais, tipo_universidad) %>% 
  summarise(cant = n()) %>% 
  transmute(tipo_universidad, porcentaje = cant/sum(cant)) %>% 
  ungroup() %>% 
  ggplot(aes(y = fct_rev(pais),
             x = porcentaje,
             fill = tipo_universidad)) +
           geom_col(position = "fill") + 
  scale_fill_manual(values = c(gris, verde, azul)) +
  geom_text(aes(label = percent(porcentaje, accuracy = 1)), 
            position = position_fill(0.5),
            color = "white",
            fontface = "bold",
            size = 3) +
  labs(title = "Distribución de respuestas por tipo de universidad por país",
       caption = fuente,
       x = "", y = "") +
  estilo +
  theme(legend.position = "none") +
  eje_x_p


educ <- kiwi %>% 
  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 <- kiwi %>% 
  select(nivel_formacion, carrera_grado, tipo_universidad, trabajo, 
         sueldo_bruto, puesto, funcion, pais, genero) %>% 
  filter(trabajo == "Relación de Dependencia") %>% 
  mutate(carrera_grado = factor(carrera_grado))


carreras <- carreras %>% 
  mutate(carrera_grado = fct_collapse(carrera_grado, 
                                      "Comunicación Social" = c("Comunicación", "Comunicación social", "Comunicación Social", "comunicacion social", "Comunicación Institucional", "Comunicación Social Institucional"),
         "Ingenierías" = c("Ingeniería Comercial","Ingenieria Electronica", "Ingeniería Industrial"),
         "Sistemas" = c("Análisis Sistemas", "Sistemas"),
         "Administración de Empresas" = c("Administración de Empresas",
                                          "Administración Industrial",
                                          "Administración y Recursos Humanos"),
         "Abogacía" = c("Abogacía", "Derecho, HR y Escribania"),
         "RRHH / RRLL / RRTT" = c("Relaciones Laborales y Abogacia",
                                  "RRHH / RRLL / RRTT",
                                  "RRTT + Abogado UBA")),
         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",
                                          "Ingenierías",
                                          "Otras")))



carreras %>% 
  group_by(carrera_grado) %>% 
  summarise(cant = n()) %>%
  ungroup() %>% 
ggplot(aes(x = cant, y = fct_rev(carrera_grado))) + 
  geom_col(position = "dodge", fill = azul) +
  geom_text(aes(label = cant),
            size = 3,
            color = "white",
            facefont = "bold",
            hjust = 1.2) +
  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 <- rh22la %>%
  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 


# 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",
                                                       "Maestría o superior 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",
                                      "Maestría en curso" = "Maestría o superior en curso",
                                      "Maestría completa" = "Maestría o superior completa")) 

ne_salario %>% 
  select(pais, nivel_formacion, genero, puesto) %>%
  filter(genero %in% c("Mujer cis", "Hombre cis"),
         !is.na(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, genero) %>%
  summarise(cant = n()) %>% 
  transmute(genero, porcentaje = cant/sum(cant)) %>% 
  ungroup() %>% 
  ggplot(aes (y= nivel_formacion, x = porcentaje, fill = genero)) + 
  geom_col(position = "fill") +
  geom_text(aes(label = percent(porcentaje, accuracy = 1)),
            position = position_fill(0.5),
            color = "white",
            size = 3,
            fontface = "bold")+
  scale_fill_manual(values = c(verde, lila)) +
  estilov +
  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, 
       x = NULL, y = NULL,
       fill = "Género") +
  eje_x_p +
      guides(fill = guide_legend(reverse=TRUE))  # Invierte el orden de los colores en la leyenda

En términos absolutos, las mujeres graduadas representan más 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") + 
  scale_fill_manual(values = colores) +
  facet_wrap(~genero, ncol = 2) +
  estiloh +
  eje_y_p +
  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") +
  eje_x_p +
  facet_wrap(~puesto, ncol = 3) + 
      guides(fill = guide_legend(reverse=TRUE))  # Invierte el orden de los colores en la leyenda

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 <- rh22la %>% 
  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)

rh22la %>% 
  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",
                                      "Maestría en curso" = "Maestría o superior en curso",
                                      "Maestría completa" = "Maestría o superior completa")) %>% 
    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 = ",",
                            prefix = "AR$ "),
            hjust = 1.2, 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.

rh22la %>% 
  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 o superior 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",
                                      "Maestría en curso" = "Maestría o superior en curso",
                                      "Maestría completa" = "Maestría o superior completa")) %>% 
    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) %>% 
  ungroup() %>% 
  ggplot(aes(x = nivel_formacion, y = y, fill = genero)) +
  geom_col(position = "dodge")+
  geom_errorbar(aes(ymin = ymin,ymax = ymax), position = "dodge")+
  coord_flip()+
  eje_y_n +
  estilov +
  scale_fill_manual(values = c(verde, lila, amarillo)) +
  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") +      
  guides(fill = guide_legend(reverse=TRUE))  # Invierte el orden de los colores en la leyenda

Diversidad en RRHH

Liderazgo y género en RRHH

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

div <- rh22la %>%
  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 <- rh22la %>% 
  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, 69 respuestas, 43 ocupan un puesto de liderazgo (62%).

Del total de hombres, 195 respuestas, 87 ocupan un puesto de liderazgo (45%).

Con un p-value igual a 0.884 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.

Diversidad en RRHH

En esta sección analizaremos qué tan diversa e inclusiva es la función de RRHH en general desde una perspectiva de identidad de género, orientación sexual y discapacidad.

# Cargar los datos 2020 y 2021
k20 <- googlesheets4::read_sheet("1833xEeRIy1DLke4eHKfEThjjgx01YGX9yQaU6vv15K0", 
                     skip = 5) %>% 
  janitor::clean_names()

k21 <- googlesheets4::read_sheet("1LDdXlIwrcsyuywbcS4gdc-1p6wBXfEfL2Y6sNBj-4GM",
                    skip = 5) %>% 
  janitor::clean_names()

# Seleccionar las columnas de ambos data frames.
k20 <- k20 %>% 
  select(identidad_genero = genero, 
         diversidad_sexual = te_identificas_como_lgbt_lesbiana_gay_bisexual_transexual_otra_minoria_sexual,
         rubro = rubro_de_la_empresa,
         origen_del_capital,
         puesto = en_que_puesto_trabajas,
         nivel_formacion = maximo_nivel_de_formacion,
         idioma = te_exigieron_saber_un_idioma_extranjero_ingles_portugues_etc_para_entrar_a_trabajar_en_tu_empresa,
         idioma_porcentaje = que_porcentaje_del_tiempo_usas_el_idioma_extranjero_en_tu_puesto_actual,
         discapacidad,
         trabajo) %>% 
  mutate(libertad_ser = 99, 
         sufrio_acoso = 99,
         management_femenino = 99,
         linea_segura = 99,
         machismo = 99,
         edicion = 2020) # Añado una columna con un valor = 1 porque esta pregunta no existía en la edición 2020 de la Encuesta

k21 <- k21 %>% 
  select(identidad_genero = identidad_de_genero,
         diversidad_sexual = te_identificas_como_lgbtiq_lesbiana_gay_bisexual_transexual_otra_minoria_sexual,
         rubro = rubro_de_la_empresa,
         origen_del_capital,
         puesto = en_que_puesto_trabajas,
         nivel_formacion = maximo_nivel_de_formacion,
         idioma = te_exigieron_saber_un_idioma_extranjero_ingles_portugues_etc_para_entrar_a_trabajar_en_tu_empresa,
         idioma_porcentaje = que_porcentaje_del_tiempo_usas_el_idioma_extranjero_en_tu_puesto_actual,
         discapacidad = tenes_alguna_discapacidad,
         trabajo,
         libertad_ser = en_tu_empresa_puedes_ser_como_realmente_eres_por_ej_expresar_abiertamente_tu_personalidad_tu_identidad_de_genero_orientacion_sexual_etc, 
         sufrio_acoso = sufriste_alguna_situacion_de_acoso_abuso_o_de_discriminacion_en_algun_trabajo,
         management_femenino = que_porcentaje_aproximado_del_management_de_tu_empresa_son_mujeres_entiendase_posiciones_de_jefatura_de_gerencia_o_de_direccion, 
         linea_segura = en_tu_organizacion_existe_una_linea_segura_o_politicas_definidas_para_actuar_frente_a_situaciones_de_acoso_o_discriminacion) %>% 
  mutate(machismo = 99,
         edicion = 2021)

k22 <- kiwi %>% 
  select(identidad_genero = genero,
         diversidad_sexual,
         rubro,
         origen_del_capital = origen_capital,
         puesto,
         nivel_formacion,
         idioma = idioma_exigencia,
         idioma_porcentaje,
         discapacidad,
         trabajo,
         libertad_ser, 
         sufrio_acoso,
         management_femenino = diversidad_management,
         linea_segura,
         machismo) %>% 
  mutate(edicion = 2022)

# Unir los datasets
div_rh <- rbind(k20, k21, k22)

# Como ya tengo unificados ambos datasets puedo borrar las versiones individuales para ahorrar memoria
rm(k20, k21, k22)

En la edición 2020, nos referíamos a la identidad de género de una manera diferente a la que lo hicimos en la edición del 2021, así que la siguiente parte consiste en consolidar los datos de ambas ediciones.

# Verificar las distintas formas de referirse al género
unique(div_rh$identidad_genero)
##  [1] "Masculino"                                                      
##  [2] "Femenino"                                                       
##  [3] "Prefiero no responder"                                          
##  [4] "Género diverso (género diverso / género fluido /otras minorías)"
##  [5] "No binario"                                                     
##  [6] "Mujer cis"                                                      
##  [7] "Hombre cis"                                                     
##  [8] "Hombre"                                                         
##  [9] "Hombre hetero. Que es cis?"                                     
## [10] "mujer"                                                          
## [11] "Mujer heterosexual"                                             
## [12] "Gay"                                                            
## [13] "Mujer"                                                          
## [14] "Hombre heterosexual"                                            
## [15] NA

En los datos encontramos 5 formas diferentes de referirse a los hombres cis, y 5 formas diferentes de referirse a las mujeres cis, así que el siguiente paso es unificar estos valores para simplificar el análisis y la interpretación de los resultados.

El sufijo cis hace referencia a las personas que se identifican con el mismo género asignado al nacer.

div_rh <- div_rh %>% 
    mutate(identidad_genero = 
             fct_collapse(identidad_genero,
                          "Hombre cis" = c("Masculino",
                                           "Hombre cis",
                                           "Hombre",
                                           "Hombre hetero. Que es cis?",
                                           "Hombre heterosexual",
                                           "Varon"),
                          "Mujer cis" = c("Femenino",
                                          "Mujer cis",
                                          "mujer",
                                          "Mujer heterosexual",
                                          "Mujer"),
                          "Género diverso" = c("Género diverso (género diverso / género fluido /otras minorías)",
                                               "No binario",
                                               "Gay")))

# Ver resultados del proceso anterior
unique(div_rh$identidad_genero)
## [1] Hombre cis            Mujer cis             Prefiero no responder
## [4] Género diverso        <NA>                 
## Levels: Mujer cis Género diverso Hombre cis Prefiero no responder
div_rh <- div_rh %>% 
  mutate(rubro = fct_collapse(rubro, "Agro" = c("Agricultura, plantaciones, otros sectores rurales", "Agricultura; plantaciones,otros sectores rurales"),
                              "Alimentos" = c("Alimentación, bebidas", "Alimentación; bebidas; tabaco"),
                              "Bancos y Finanzas" = c("Bancos, banca online", "Bancos; banca online;", "Servicios financieros seguros", "Servicios financieros; seguros"),
                              "Autopartista" = c("Fabricación de material de transporte", "Terminales automotrices, fábricas autopartistas, y afines"), 
                              "Hotelería" = "Hotelería, restauración, turismo",
                              "Metalurgia" = c("Industria metalúrgica, metalmecánica", "Producción de metales básicos"), 
                              "Medios" = c("Medios de comunicación, cultura, gráficos", "Medios de comunicación; cultura; gráficos"),
                              "Minería" = c("Minería", "Minería (carbón, otra minería)"),
                              "Oil & Gas" = c("Petróleo y producción de gas, refinación de petróleo", "Petróleo y producción de gas; refinación de petróleo"), 
                              "Consultoría" = "Servicios de consultoría",
                              "Correos" = c("Servicios de correos y de telecomunicaciones", "Medios de comunicación; cultura; gráficos"),
                              "Correos" = c("Servicios de correos y de telecomunicaciones", "Servicios de correos, y de telecomunicaciones"),
                              "Servicios Públicos" = c("Servicios públicos (agua, gas, electricidad)", "Servicios públicos (agua;gas; electricidad)"),
                              "Silvicultura" = "Silvicultura; madera; celulosa; papel",
                              "Tecnología" = c("Tecnologías de información", "Tecnologías de Información, Sistemas, y afines"), 
                              "Textil" = c("Textiles, vestido, cuero, calzado", "Textiles; vestido; cuero; calzado"),
                              "Transporte" = c("Transporte (incluyendo aviación civil, ferrocarriles por carretera)", "Transporte (incluyendo aviación civil; ferrocarriles por carretera)", "Transporte marítimo, puertos", "Transporte marítimo; puertos;"
                                               )))

# Añadimos a los freelancers como servicios de consultoría dentro de la columna Rubro
div_rh <- div_rh %>% 
  mutate(rubro = if_else(trabajo == "Freelance", "Consultoría Freelance", as.character(rubro)))

# Limpieza Puesto
# Descartamos posiciones no relacionadas con RRHH
div_rh <- div_rh %>% 
  filter(!puesto %in% c("Juzgado Civil y Comercial", "Programador",
                        "Cuidado", "Asesor", "Jefe de Proyecto",
                        "Desarrollador", "Programador", 
                        "-", "Inspección de calidad", "Jefe de Proyecto",
                        "Representante", "Técnico", "Asesoramiento", "-")) %>% 
  mutate(puesto = str_trim(puesto, side = "both")) # Elimina espacios vacíos antes y después de cada palabra

# Reemplazar los valores NA por Consultor Freelance
div_rh <- div_rh %>% 
  mutate(puesto = if_else(is.na(puesto), "Consultor Freelance", puesto))


# Unificación de Puestos
div_rh <- div_rh %>% 
  mutate(puesto = fct_collapse(puesto, "Gerente" = c("Gerente",
                                                     "Superintendente", 
                                                     "Director",
                                                     "Director ( escalafón municipal)"),
                         "HRBP" = c("HRBP",
                                    "Senior Consultoría", "specialist",
                                    "especialista",
                                    "Specialist",
                                    "Especialista de selección por un lado (única persona en estas tareas) y HRBP de 2 equipos por otro",
                                    "Especialista en selección IT", 
                                    "Recruiter"),
                        "Responsable" = c("Responsable",
                                          "Coordinación",
                                          "coordinación",
                                          "Coordinador de Payroll",
                                          "Encargado",
                                          "Coordinadora",
                                          "Supervisor",
                                          "Líder Ágil",
                                          "Líder de selección"),
                        "Administrativo" = c("Administrativo",
                                             "Asistente",
                                             "Asistente RRHH",
                                             "Aux", "Auxiliar",
                                             "consultor jr",
                                             "El cargo es Asistente de CH, pero leo adelante Comunicación Interna, RSE, Capacitacion",
                                             "Payroll Assistant"),
                        "Analista" = c("Analista", 
                                       "Analista semi senior",
                                       "Asesoramiento", 
                                       "Consultor", 
                                       "Capacitador", 
                                       "Consultor Ejecutivo",
                                       "consultor jr",
                                       "Generalista",
                                       "Profesional RRHH",
                                       "Reclutador",
                                       "Recruiter",
                                       "Recruiter IT",
                                       "Reclutadora", 
                                       "Selectora",
                                       "Senior",
                                       "Senior Recruiter",
                                       "Senior Consultoría",
                                       "Sourcer (Recruiter)",
                                       "Sourcer Specialist",
                                       "talent",
                                       "Talent Acquisition",
                                       "IT RECRUITER",
                                       "Auditor",
                                       "Tech Recruiter",
                                       "Analista de People Operations",
                                       "Specialist")))

Cuanta diversidad de identidades de género y orientaciones sexuales hay en RRHH

En este punto creo que es importante aclarar que entre una edición y otra de la Encuesta KIWI hicimos cambios en el diseño del formulario, y por ejemplo, las preguntas sobre orientación sexual sólo se las hicimos a las personas que trabajan en relación de dependencia, con lo cual no tenemos una continuidad en los datos sobre el total de las personas que participaron, especialmente de quienes trabajan de manera freelance.

En primer lugar, veamos cuántas personas trabajan en RRHH según su identidad de género:

gt(
div_rh %>% 
  group_by(edicion, identidad_genero) %>% 
  count(sort = TRUE) %>% 
  ungroup() %>% 
  pivot_wider(names_from = edicion, values_from = n) %>% 
  mutate(`2020` = coalesce(`2020`, 0),
         `2021` = coalesce(`2021`, 0),
         `2022` = coalesce(`2022`, 0),
         Total = `2020` + `2021` + `2022`,
         Porcentaje = round(Total/sum(Total),3))
) %>% 
  fmt_percent(columns = Porcentaje,
              decimals = 1) %>% 
  tab_header(title = "Identidad de Género por Edición") %>% 
  tab_source_note(source_note = fuente) %>% 
  cols_label(identidad_genero = "Identidad de Género")
Identidad de Género por Edición
Identidad de Género 2020 2021 2022 Total Porcentaje
Mujer cis 518 403 261 1182 69.5%
Hombre cis 232 170 101 503 29.6%
Prefiero no responder 2 6 0 8 0.5%
Género diverso 4 2 0 6 0.4%
NA 0 0 2 2 0.1%
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2022

Según la muestra que obtuvimos, menos del 1% de las personas que trabajan en RRHH son personas no binarias. Como para quede más claro veamóslo con un gráfico.

div_rh %>% 
  group_by(identidad_genero) %>% 
  count(sort = TRUE) %>% 
  ungroup() %>% 
  ggplot(aes(y = reorder(identidad_genero, n), x = n, 
             fill = identidad_genero)) +
  geom_col() +
  estilov +
  geom_text(aes(label = n, hjust = -0.2),
            size = 3.5,
            color = c(gris, gris, gris, "black", "black"))+
  scale_fill_manual(values = c(gris, verde, gris, verde, gris)) +
  scale_x_continuous(limits = c(0, 1300)) +
  labs(title = "Cantidad de respuestas según Identidad de Género",
       x = "", y = "",
       caption = fuente) +
  theme(legend.position = "none")

Por decirlo amablemente: Hay muchas oportunidades de mejora acá.

Y ahora veamos la cantidad de respuestas según la orientación sexual de las personas que participaron de la encuesta. Dado que en la edición 2021 esta era una sección voluntaria, la cantidad de respuestas va a ser distinta que en la tabla anterior. Además, fue algo que no le preguntamos a las personas que trabajan de manera independiente.

La pregunta que hicimos fue ¿Te identificás como LGBTIQ+ (lesbiana, gay, bisexual, transexual, otra minoría sexual)?. He aquí las respuestas:

gt(div_rh %>% 
  filter(!is.na(diversidad_sexual)) %>% 
  group_by(edicion, diversidad_sexual) %>% 
  count(sort = TRUE) %>% 
  ungroup() %>% 
  pivot_wider(names_from = edicion, 
              values_from = n) %>% 
  mutate(Total = `2020` + `2021`,
         Porcentaje = Total/sum(Total))
) %>% 
  fmt_percent(columns = Porcentaje,
              decimals = 1) %>% 
  tab_header(title = "Diversidad Sexual por Edición") %>% 
  tab_source_note(source_note = fuente) %>% 
  cols_label(diversidad_sexual = "Eres de algún\nColectivo LBGTQ+")
Diversidad Sexual por Edición
Eres de algún Colectivo LBGTQ+ 2020 2021 2022 Total Porcentaje
No 701 335 198 1036 91.4%
Si 41 33 16 74 6.5%
Prefiero no responder 14 9 3 23 2.0%
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2022

Al menos respecto de esta pregunta, tenemos una mayor representación de diversidades sexuales. Nuevamente, esta muestra no es representativa de todas las personas que trabajan en RRHH, pero esperamos que permita discutir el tema.

div_rh %>% 
  filter(!is.na(diversidad_sexual)) %>%
  group_by(identidad_genero, diversidad_sexual) %>% 
  tally() %>% 
  ungroup() %>% 
  ggplot(aes(y = identidad_genero, x = n, fill = diversidad_sexual )) +
  geom_col(position = "fill") +
  geom_text(aes(label = n), position = position_fill(vjust = 0.5), size = 2.5) +
  estilov +
  theme(legend.position = "top") +
  guides(fill = guide_legend(reverse = T)) +
  scale_x_continuous(labels = scales::percent_format(accuracy = 1))+
  labs(title = "Diversidad Sexual según Identidad de Género",
       subtitle = "Pregunta: ¿Te identificás como LGBTIQ+?", 
       fill = "Eres de algún Colectivo LGBTIQ+",
       x = NULL, y = NULL, caption = fuente) +
  scale_fill_manual(values = c(azul, gris, verde))

El tamaño de las barras reflejan la proporción de cada respuesta según la identidad de género de cada participante. Por ejemplo, en el caso de las personas que se identifican como Hombres cis, 46 personas se identifican como parte de la comunidad LGBTIQ+ (un 11.6%). 41 Mujeres cis (4.3%) pertenecen a este colectivo.

En qué rubros se da la mayor tasa de diversidad

Ahora analicemos los rubros. Dado que no tenemos muchas personas con diversas identidades de género, listaremos todos los rubros.

gt(div_rh %>% 
  filter(identidad_genero == "Género diverso") %>% 
  select(Rubro = rubro) %>% 
  group_by(Rubro) %>% 
  tally(sort = T, name = "Respuestas") %>% 
    janitor::adorn_totals()
)
Rubro Respuestas
Consultoría Freelance 3
Construcción 1
Correos 1
Servicios profesionales 1
Total 6

Ahora, repliquemos el análisis con la pregunta ¿Te identificás como LGBTIQ+ (lesbiana, gay, bisexual, transexual, otra minoría sexual)?.

gt(
div_rh %>% 
  filter(diversidad_sexual == "Si") %>% 
  select(Rubro = rubro) %>% 
  group_by(Rubro) %>% 
  tally(sort = T, name = "Respuestas")
)
Rubro Respuestas
Tecnología 14
Consultoría 11
Otros 10
Bancos y Finanzas 8
Consultoría Freelance 5
Servicios de salud 5
Alimentos 4
Construcción 4
Hotelería 4
Agro 3
Comercio 3
Metalurgia 3
Transporte 3
Correos 2
Oil & Gas 2
Servicios profesionales 2
Servicios Públicos 2
Autopartista 1
Educación 1
Función pública 1
Industrias químicas 1
Minería 1

Entre los primeros rubros (fuera de Otros) nos encontramos con actividades relacionadas con servicios. Recién en el 6° puesto nos encontramos con el primer rubro relacionado con la industria manufacturera (Alimentos).

Qué roles ejercen las personas diversas

Por último, veamos en qué roles se desempeñan las personas que pertenecen a algún colectivo de diversidad dentro de RRHH.

# Crear un flag para posiciones de manager (Gerente, Jefe o Responsable)
div_rh <- div_rh %>% 
  mutate(manager = if_else(puesto %in% c("Gerente", "Jefe", "Responsable"),
                           1, 0))

# Si el valor de la columna identidad_genero es igual a Género diverso o el valor de la columna diversidad_sexual es igual a Si, entonces el valor en la nueva columna llamada diversa es 1, de lo contrario poner 0.
div_rh <- div_rh %>% 
  mutate(diversa = if_else(identidad_genero == "Género diverso" | diversidad_sexual == "Si",
                           1, 0))

managers_porcentaje <- div_rh %>% 
  filter(diversa == 1) %>% 
  group_by(manager) %>% 
  count() %>% 
  ungroup() %>% 
  mutate(porcentaje = n/sum(n))

puestos_porcentaje <- div_rh %>% 
  filter(diversa == 1) %>% 
  group_by(puesto) %>% 
  count(sort = T) %>% 
  ungroup() %>% 
  mutate(porcentaje = n/sum(n))

# Visualización
ggplot(puestos_porcentaje, aes(x = n, y = reorder(puesto, n))) +
  geom_col(fill = verde) +
  geom_text(aes(label = n), 
            hjust = 1.3,
            size = 4) +
  estilov +
  labs(title = "Roles que ocupan las personas diversas",
       x = NULL, y = NULL,
       caption = fuente)

Algo interesante de este gráfico es que un 39% ocupan algún puesto jerárquico (definidos como Gerente, Jefe, o Responsable) lo cual nos parece algo positivo.

Sólo 6 personas, un 6%, trabajan por su cuenta como Consultor Freelance, el cual es un dato alentador mirándolo desde el punto de vista de la formalidad laboral y la estabilidad.

Estos son datos que están sesgados por la muestra de datos, pero la hipótesis inicial que teníamos era que el porcentaje de freelancers sería mayor en este caso.

Libertad en el trabajo

En las últimas ediciones de la Encuesta KIWI incluimos dos preguntas, una fue si En tu empresa puedes ser como realmente eres, por ej. expresar abiertamente tu personalizada, tu identidad de género, orientación sexual, etc.. y la otra fue ¿Sufriste alguna situación de acoso, abuso o de discriminación en algún trabajo?, con las cuales apuntábamos a analizar qué tan abiertos son los lugares de trabajo, y qué tan seguras y libres se sienten las personas con su lugar de trabajo.

En esta sección vamos a comparar los resultados de estas preguntas de acuerdo a si las personas pertenecen a algún colectivo de diversidad o no.

Estas eran preguntas voluntarias en las ediciones del 2021 y del 2022 así que no todas las personas la respondieron, y no estaban incluidas en la edición del 2020.

# Limpiar campos
libertad <- div_rh %>% 
  filter(libertad_ser %in% c("De acuerdo", "En desacuerdo", "Ni de acuerdo ni en desacuerdo", 
                             "Totalmente de acuerdo", "Totalmente en desacuerdo"),
         !is.na(diversa))

# Ordenar la jerarquía de las respuestas sobre libertad en el trabajo.
libertad <- libertad %>% 
  mutate(libertad_ser = factor(libertad_ser, levels = c("Totalmente de acuerdo", "De acuerdo", 
                                                        "Ni de acuerdo ni en desacuerdo",
                                                        "En desacuerdo", "Totalmente en desacuerdo"))) 

Comparemos las respuestas según si las personas pertenecen a algún colectivo de diversidad o no.

libertad_scores <- libertad %>%
  mutate(diversa = factor(diversa)) %>% 
  group_by(diversa, libertad_ser) %>% 
  summarise(respuestas = n()) %>% 
  mutate(porcentaje = respuestas/sum(respuestas)) 

ggplot(libertad_scores, aes(y = diversa, x = respuestas, fill = libertad_ser)) +
  geom_col(position = "fill") +
  scale_fill_manual(values = c(azul, lila, gris, rosa2, rosa1)) +
  geom_text(aes(label = scales::percent(porcentaje, accuracy = 1)), position = position_fill(vjust = 0.5), size = 3) +
  estilo +
  scale_x_continuous(labels = scales::percent_format(accuracy = 1)) +
  theme(legend.position = "top",
        legend.text = element_text(size = 5),
        legend.background = element_rect(colour = "#FCFCFC")) +
  guides(fill = guide_legend(reverse = TRUE)) +
  labs(title = "Niveles de libertad en el trabajo",
       subtitle = "0: Personas no diversas - 1: Personas diversas",
       x = NULL, y = NULL, caption = fuente,
       fill = "Libertad para\nser uno mismo")

No hay grandes diferencias entre los resultados de ambos grupos. En la opción Totalmente de acuerdo es donde encontramos la mayor diferencia (6%). Si agrupamos las respuestas Totalmente en desacuerdo y En desacuerdo, la diferencia total es de 9%.

Me parece muy positivo que 2 de cada 3 personas (el 65%) de colectivos de diversidad sientan que pueden ser como son en sus respectivos trabajos.

Ahora comparemos las respuestas a la pregunta ¿Sufriste alguna situación de acoso, abuso o de discriminación en algún trabajo?. Primero, analicemos los resultados según si la persona pertenece a algún colectivo de diversidad o no.

div_rh %>% 
  mutate(sufrio_acoso = 
           fct_collapse(sufrio_acoso,
                        "Si" = c("Si", 
                                 "agresión verbal.", 
                                 "Mobbing",
                                 "no en el actual",
                                 "Sí. Son sutiles pero están.",
                                  "No. Pero si muchos comentarios marchistas durante mi carrera. No ahora.",
                                 "Sí claro, abuso de autoridad",
                                 "Alguna vez sufrí maltrato psicológico",
                                 "Lo máximo fue \"sos lesbiana porque no te maquillas\""
                                              ))) %>% 
  filter(sufrio_acoso %in% c("Si", "No"), 
         !is.na(diversa)) %>% 
  group_by(diversa, sufrio_acoso) %>% 
  summarise(cantidad = n()) %>%
  mutate(porcentaje = cantidad/sum(cantidad)) %>% 
  ggplot(aes(x = factor(diversa), y = cantidad, fill = sufrio_acoso)) +
  geom_col(position = "dodge") +
  geom_text(aes(label = paste0(cantidad, " (", scales::percent(porcentaje, accuracy = 1), ")")),
            position = position_dodge(0.9), vjust = -0.3, size = 3) +
  estiloh +
  labs(title = "Personas que sufrieron acoso, abuso o discriminación\nsegún colectivo de diversidad",  subtitle = "0: Personas no diversas - 1: Personas diversas",
       x = NULL, y = NULL, caption = fuente,
       fill = "Sufrió acoso, abuso o discriminación") +
  theme(legend.position = "top") +
  scale_fill_manual(values = c(naranja, gris)) +
  scale_y_continuous(limits = c(0,450))

El 34% de las personas diversas, ya sea por su identidad de género o por su orientación sexual sufrieron alguna situación de acoso, abuso, o discriminación, frente a un 28% de las personas cis y heterosexuales.

Ahora desagreguemos el gráfico anterior según la identidad de género de las personas:

div_rh %>% 
  mutate(sufrio_acoso = fct_collapse(sufrio_acoso,
                                     "Si" = c("Si", "agresión verbal.", "Mobbing",
                                              "no en el actual"))) %>% 
  filter(sufrio_acoso %in% c("Si", "No")) %>% 
  group_by(identidad_genero, sufrio_acoso) %>% 
  summarise(cantidad = n()) %>%
  mutate(porcentaje = cantidad/sum(cantidad)) %>% 
  ggplot(aes(x = identidad_genero, y = cantidad, fill = sufrio_acoso)) +
  geom_col(position = "dodge") +
  geom_text(aes(label = paste0(cantidad, " (", scales::percent(porcentaje, accuracy = 1), ")")),
            position = position_dodge(0.9), vjust = -0.3, size = 3) +
  estiloh +
  labs(title = "Personas que sufrieron acoso, abuso o discriminación\nsegún su identidad de género",  subtitle = "0: Personas no diversas - 1: Personas diversas",
       x = NULL, y = NULL, caption = fuente,
       fill = "Sufrió acoso, abuso o discriminación") +
  theme(legend.position = "top") +
  scale_fill_manual(values = c(naranja, gris)) +
  scale_y_continuous(limits = c(0,320))

En este último gráfico podemos apreciar las distintas realidades de las personas. Un tercio de las mujeres cis sufrió al menos una vez alguna situación de acoso, abuso o discriminación versus un 15% de los hombres cis. Más allá de la cantidad de respuestas recibidas, las tendencias son claras.

Machismo

La siguiente pregunta, ¿Sentís que tu entorno laboral es machista?, la realizamos por primera vez en 2022, así que en primer lugar comparemos los resultados en función de si las personas son diversas o no.

# Creamos un dataframe específico para este análisis.
machismo <- div_rh %>% 
  filter(!is.na(diversa),
         machismo %in% c("No es un entorno machista",
                         "Si pero no es tanto",
                         "Si, es muy machista")) %>% 
  mutate(machismo = factor(machismo, 
                           levels = c("No es un entorno machista",
                                      "Si pero no es tanto",
                                      "Si, es muy machista")))

machismo_score <- machismo %>%
  mutate(diversa = factor(diversa)) %>% 
  group_by(diversa, machismo) %>% 
  summarise(respuestas = n()) %>% 
  mutate(porcentaje = respuestas/sum(respuestas)) 

ggplot(machismo_score, aes(y = diversa, x = respuestas, fill = machismo)) +
  geom_col(position = "fill") +
  scale_fill_manual(values = c(azul, rosa1, rosa2)) +
  geom_text(aes(label = scales::percent(porcentaje, accuracy = 1)), position = position_fill(vjust = 0.5), size = 3) +
  estilo +
  scale_x_continuous(labels = scales::percent_format(accuracy = 1)) +
  theme(legend.position = "top",
        legend.text = element_text(size = 5),
        legend.background = element_rect(colour = "#FCFCFC")) +
  guides(fill = guide_legend(reverse = TRUE)) +
  labs(title = "¿Sentís que tu entorno laboral es machista?",
       subtitle = "0: Personas no diversas - 1: Personas diversas",
       x = NULL, y = NULL, caption = fuente,
       fill = "Respuesta:")

Entre las personas diversas encontramos respuestas con mayor cantidad de respuestas en los extremos, 44% no sienten que su entorno sea machista, y un 25% sienten que es muy machista.

Entre las personas heteronormativas un 42% que su entorno no es tan machista.

Analizando las respuestas según la identidad de género, no sorprende que las mujeres tengan una percepción mayor que los hombres sobre si el entorno laboral es machista.

machismo_genero <- machismo %>%
  filter(identidad_genero != "Mujer trans") %>% 
  group_by(identidad_genero, machismo) %>% 
  summarise(respuestas = n()) %>% 
  mutate(porcentaje = respuestas/sum(respuestas)) 

ggplot(machismo_genero, aes(y = identidad_genero, x = respuestas, fill = machismo)) +
  geom_col(position = "fill") +
  scale_fill_manual(values = c(azul, rosa1, rosa2)) +
  geom_text(aes(label = scales::percent(porcentaje, accuracy = 1)), position = position_fill(vjust = 0.5), size = 3) +
  estilo +
  scale_x_continuous(labels = scales::percent_format(accuracy = 1)) +
  theme(legend.position = "top",
        legend.text = element_text(size = 5),
        legend.background = element_rect(colour = "#FCFCFC")) +
  guides(fill = guide_legend(reverse = TRUE)) +
  labs(title = "¿Sentís que tu entorno laboral es machista?",
       x = NULL, y = NULL, caption = fuente,
       fill = "Respuesta:")

Analicemos la situación por rubros:

machismo_rubro <- machismo %>%
  mutate(diversa = factor(diversa)) %>% 
  group_by(rubro, machismo) %>% 
  summarise(respuestas = n()) %>% 
  mutate(porcentaje = respuestas/sum(respuestas)) 

ggplot(machismo_rubro, aes(y = fct_rev(rubro), x = respuestas, fill = machismo)) +
  geom_col(position = "fill") +
  scale_fill_manual(values = c(azul, rosa1, rosa2)) +
  geom_text(aes(label = scales::percent(porcentaje, accuracy = 1)), position = position_fill(vjust = 0.5), size = 3) +
  estilo +
  scale_x_continuous(labels = scales::percent_format(accuracy = 1)) +
  theme(legend.position = "top",
        legend.text = element_text(size = 5),
        legend.background = element_rect(colour = "#FCFCFC")) +
  guides(fill = guide_legend(reverse = TRUE)) +
  labs(title = "¿Sentís que tu entorno laboral es machista?",
       x = NULL, y = NULL, caption = fuente,
       fill = "Respuesta:")

En la visualización anterior podemos ver que los rubros que hay menor percepción de machismo, son en Servicios profesionales, Medios, y Consultoría. En el otro extremo, por cantidad de respuestas, nos encontramos que los rubros Alimentos, Tecnología, y Servicios de Salud.

machismo_rubro %>% 
  select(-porcentaje) %>% 
  pivot_wider(names_from = machismo, values_from = respuestas) %>% 
  mutate(`No es un entorno machista` = coalesce(`No es un entorno machista`, 0),
         `Si pero no es tanto` = coalesce(`Si pero no es tanto`, 0),
         `Si, es muy machista` = coalesce(`Si, es muy machista`, 0),
         Total = `No es un entorno machista` + `Si pero no es tanto` + `Si, es muy machista`) %>% 
  rename(Rubro = rubro) %>% 
      arrange(-Total) %>% 
  kbl(caption = "Percepción de Machismo por Rubro") %>% 
  kable_styling(full_width = F, position = "center",
              bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>% 
  scroll_box(height = "500px")
Percepción de Machismo por Rubro
Rubro No es un entorno machista Si pero no es tanto Si, es muy machista Total
Tecnología 21 10 10 41
Otros 13 12 3 28
Servicios de salud 6 9 4 19
Comercio 7 7 3 17
Bancos y Finanzas 3 10 1 14
Alimentos 4 2 7 13
Consultoría 6 4 1 11
Metalurgia 3 4 3 10
Oil & Gas 1 7 2 10
Servicios profesionales 7 2 0 9
Construcción 1 3 3 7
Industrias químicas 2 4 1 7
Función pública 1 2 2 5
Agro 2 1 1 4
Minería 1 2 1 4
Textil 2 2 0 4
Medios 2 1 0 3
Transporte 0 2 1 3
Autopartista 0 1 1 2
Educación 0 1 0 1
Hotelería 0 1 0 1
Industria siderúrgica 0 1 0 1
Ingeniería mecánica 0 1 0 1
Silvicultura, madera, celulosa, papel 0 0 1 1

Discapacidad

disc_rh <- div_rh %>%
  filter(!is.na(discapacidad)) %>% 
  mutate(discapacidad = 
           fct_collapse(discapacidad, 
                        "Sin discapacidad" = 
                          c("No tengo ninguna discapacidad",
                            "creo no tener jajaja", 
                            "Visual???")),
    tiene_discapacidad = if_else(discapacidad %in% c("Sin discapacidad", "Prefiero no responder"), 0, 1))

Veamos cuántas personas con alguna discapacidad participaron de la edición actual:

kiwi <- kiwi %>% 
  mutate(discapacidad = 
           fct_collapse(discapacidad,
                        "Sin discapacidad" = 
                          c("No tengo ninguna discapacidad",
                            "creo no tener jajaja",
                            "Visual???")),
         tiene_discapacidad = factor(if_else(discapacidad == "Sin discapacidad", 0, 1)))

div <- kiwi %>% 
  filter(!is.na(discapacidad)) %>% 
  select(tiene_discapacidad) %>% 
  group_by(tiene_discapacidad) %>% 
  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=tiene_discapacidad)) +
  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, naranja)) +
  theme_void() +
  theme(legend.position = "top",
        panel.background = element_blank(),
        plot.title.position = "plot",
        text = element_text(family = "Roboto")) +
  labs(title = "Respuestas según discapacidad",
       subtitle = "1: Tiene alguna discapacidad - 0: Sin discapacidad",
       fill = "Discapacidad", 
       caption = fuente)

gt(kiwi %>% 
  filter(!is.na(discapacidad)) %>% 
  group_by(tiene_discapacidad) %>% 
  tally(name = "Respuestas") %>% 
  ungroup() %>% 
  mutate(Porcentaje = Respuestas/sum(Respuestas),
         tiene_discapacidad = factor(tiene_discapacidad,
                                      levels = c(0, 1),
                                      labels = c("No", "Si")))) %>% 
  cols_label(tiene_discapacidad = "Con Discapacidad") %>% 
  summary_rows(columns = c(Respuestas, Porcentaje),
    fns = list(Total = "sum")) %>% 
  fmt_percent(columns = Porcentaje,
              decimals = 1) %>% 
  tab_header(title = "Respuestas según discapacidad",
             subtitle = "Relación de Dependencia") %>% 
  tab_source_note(source_note = fuente)
Respuestas según discapacidad
Relación de Dependencia
Con Discapacidad Respuestas Porcentaje
No 210 97.2%
Si 6 2.8%
Total 216.00 1.00
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2022

En la actual edición contamos sólo con un 2.8% de colegas con alguna discapacidad trabajando en RRHH, las cuales son las siguientes:

kiwi %>% 
  filter(!is.na(discapacidad),
         tiene_discapacidad == 1) %>% 
  group_by(discapacidad) %>% 
  summarise(cant = n()) %>% 
  ungroup() %>% 
  ggplot(aes(x = cant, y = reorder(discapacidad, cant))) +
  geom_col(fill = naranja) +
  estilov +
  labs(title = "Tipos de Discapacidad",
       subtitle = "Relación de Dependencia",
       x = NULL, y = NULL,
       caption = fuente)

Veamos cómo fue la evolución de esta respuesta a lo largo de las ediciones de esta encuesta.

disc_rh %>% 
  filter(tiene_discapacidad == 1) %>% 
  group_by(edicion) %>% 
  summarise(cant = n()) %>% 
  ungroup() %>% 
  ggplot(aes(x = factor(edicion), y = cant)) +
  geom_col(fill = naranja) +
  geom_text(aes(label = cant),
            vjust = 1.2,
            size = 3) +
  estiloh +
  labs(title = "Respuestas de Personas con Discapacidad",
       subtitle = "Relación de Dependencia",
       x = NULL, y = NULL,
       caption = fuente)

Puestos

Si bien la mayor cantidad de personas con discapacidad históricamente se desempeñan en roles de Analista, es interesante apreciar que en total tenemos prácticamente la misma cantidad (18) en roles de liderazgo (Gerente, Jefe o Resposable).

Esto nos parece positivo porque es una muestra no sólo de diversidad, sino también de inclusión. Consideramos que no sólo es importante contratar personas con discapacidad, sino también darles las oportunidades de desarrollo que le daríamos a cualquier persona de la compañía.

gt(disc_rh %>% 
  filter(!is.na(discapacidad),
         !is.na(puesto),
         tiene_discapacidad == 1) %>% 
  group_by(edicion, puesto) %>% 
  summarise(cant = n()) %>% 
  ungroup() %>% 
    pivot_wider(names_from = edicion,
                values_from = cant) %>% 
  mutate(`2020` = coalesce(`2020`, 0),
         `2021` = coalesce(`2021`, 0),
         `2022` = coalesce(`2022`, 0),
         Total = `2020`+`2021`+`2022`)) %>% 
  cols_label(puesto = "Puesto") %>% 
  tab_header(title = "Puestos de Personas con Discapacidad") %>% 
  tab_source_note(source_note = fuente)
Puestos de Personas con Discapacidad
Puesto 2020 2021 2022 Total
Administrativo 3 0 0 3
Analista 9 8 3 20
Consultor Freelance 6 0 0 6
Responsable 4 3 1 8
Gerente 3 2 1 6
Jefe 2 2 0 4
HRBP 0 2 1 3
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2022

Contratación de personas con discapacidad

En esta edición incluimos la pregunta En lo que va del año, ¿han contratado en tu empresa a personas con discapacidad? para analizar si las empresas están activamente tomando acciones de inclusión.

kiwi %>% 
  filter(!is.na(contrata_discapacidad)) %>% 
  group_by(contrata_discapacidad) %>% 
  summarise(cant = n()) %>% 
  ungroup() %>% 
  ggplot(aes(x = contrata_discapacidad, y = cant, fill = contrata_discapacidad)) +
  geom_col() +
  geom_text(aes(label = cant),
            vjust = 1.2, 
            color = "white",
            size = 3) +
  scale_fill_manual(values = c(gris, gris, naranja)) +
  estiloh +
  labs(title = "Contrataron personas con discapacidad",
       x = NULL, y = NULL,
       caption = fuente) +
  theme(legend.position = "none")

contrata_disc <- kiwi %>% 
  filter(!is.na(contrata_discapacidad)) %>% 
  group_by(contrata_discapacidad) %>% 
  summarise(cant = n()) %>% 
  ungroup() %>% 
  mutate(porcentaje = cant/sum(cant))

En esta edición, 44 (un 20%) afirmaron que en sus empresas han contratado personas con discapacidad en sus organizaciones. Esto nos lleva a la siguientes preguntas: estas compañías, ¿son nacionales o multinacionales?, ¿Qué tamaño tienen las empresas?

kiwi %>% 
  filter(contrata_discapacidad == "Si") %>% 
  group_by(origen_capital) %>% 
  tally() %>% 
  ungroup() %>% 
  ggplot(aes(x = origen_capital, y = n)) +
  geom_col(fill = naranja) +
  geom_text(aes(label = n),
            vjust = 1.2,
            size = 3) +
  estiloh +
  labs(title = "Origen del Capital de Empresas\nque Contrataron Personas con Discapacidad",
       x = NULL, y = NULL,
       caption = fuente)

En base a las respuestas recibidas, las empresas nacionales han contratado más personas con discapacidad que las multinacionales.

kiwi %>% 
  filter(contrata_discapacidad == "Si") %>%
  mutate(dotacion = factor(dotacion,
                           levels = c("1 - 50",
                                      "51 - 100",
                                      "101 - 250",
                                      "251 - 500",
                                      "501 - 1.000",
                                      "1.001 - 2.500",
                                      "2.501 - 5.000",
                                      "5.001 - 10.000",
                                      "10.001 o más"))) %>% 
  group_by(dotacion) %>% 
  tally() %>% 
  ungroup() %>% 
  ggplot(aes(x = dotacion, y = n)) +
  geom_col(fill = naranja) +
  geom_text(aes(label = n),
            vjust = 1.1,
            size = 3) +
  scale_x_discrete(guide = guide_axis(n.dodge = 2)) +
  labs(title = "Empresas que Contrataron Personas con Discapacidad\nsegún Tamaño de la Empresa",
       x = "Dotación de la Empresa", y = NULL,
       caption = fuente) +
  estiloh

Si bien en total vemos que las empresas con más de 1.000 empleados son las que contratan más personas con discapacidad, no vemos un patrón claro en función de la dotación de la organización porque por ejemplo las empresas que tienen entre 101 y 250 empleados han contratado personas con discapacidad en la misma medidad que las organizaciones con 5.001 - 10.000 empleados.

Edad

La discriminación por edad, también conocida como edadismo es un problema que afecta a la empleabilidad de las personas de mayor edad. Es habitual encontrar avisos de empleo donde el límite de edad es de 40 años.

En la presente edición de la encuesta incluimos la pregunta “En lo que va del año, ¿han contratado en tu empresa a personas mayores de 50 años?” para analizar cuál es la tendencia en contratación de personas senior.

kiwi %>% 
  filter(!is.na(contrata_senior)) %>% 
  group_by(contrata_senior) %>% 
  tally() %>% 
  ungroup() %>% 
  ggplot(aes(x = contrata_senior, y = n, fill = contrata_senior)) +
  geom_col() +
  geom_text(aes(label = n),
            vjust = 1.2,
            size = 3, 
            color = "white") +
  estiloh +
  labs(title = "Empresas que han Contratado \nPersonas de Más de 50 Años",
       x = NULL, y = NULL,
       caption = fuente) +
  scale_fill_manual(values = c(gris, gris, rosa1)) +
  theme(legend.position = "none")

contrata_sr <- kiwi %>% 
  filter(!is.na(contrata_senior)) %>% 
  group_by(contrata_senior) %>% 
  summarise(cant = n()) %>% 
  ungroup() %>% 
  mutate(porcentaje = cant/sum(cant))

En esta edición, 88 (un 41%) afirmaron que en sus empresas han contratado personas de más de 50 años.

A continuación reiteraremos los análisis en función del origen del capital y del tamaño de las empresas.

kiwi %>% 
  filter(contrata_senior == "Si") %>% 
  group_by(origen_capital) %>% 
  tally() %>% 
  ungroup() %>% 
  ggplot(aes(x = origen_capital, y = n)) +
  geom_col(fill = rosa1) +
  geom_text(aes(label = n),
            vjust = 1.2,
            size = 3,
            color = "white") +
  estiloh +
  labs(title = "Origen del Capital de Empresas\nque Contrataron Personas de Más de 50 Años",
       x = NULL, y = NULL,
       caption = fuente)

En base a las respuestas recibidas, nuevamente apreciamos que las empresas nacionales han contratado más personas de más de 50 años que las multinacionales.

kiwi %>% 
  filter(contrata_senior == "Si") %>%
  mutate(dotacion = factor(dotacion,
                           levels = c("1 - 50",
                                      "51 - 100",
                                      "101 - 250",
                                      "251 - 500",
                                      "501 - 1.000",
                                      "1.001 - 2.500",
                                      "2.501 - 5.000",
                                      "5.001 - 10.000",
                                      "10.001 o más"))) %>% 
  group_by(dotacion) %>% 
  tally() %>% 
  ungroup() %>% 
  ggplot(aes(x = dotacion, y = n)) +
  geom_col(fill = rosa1) +
  geom_text(aes(label = n),
            vjust = 1.2,
            size = 3,
            color = "white") +
  scale_x_discrete(guide = guide_axis(n.dodge = 2)) +
  labs(title = "Empresas que Personas de Más de 50 Años\nsegún Tamaño de la Empresa",
       x = "Dotación de la Empresa", y = NULL,
       caption = fuente) +
  estiloh

A contrario de los que vimos en el análisis de discapacidad, las empresas más chicas tienden a contratar personas de más de 50 años que las empresas más grandes.

Lo que podemos apreciar en todos estos análisis es que la diversidad e inclusión depende más de la visión de una organización y su compromiso genuino, que el tamaño de la compañía, o el origen de su capital.

Nuevos Empleados

Otra forma de analizar la empleabilidad de las personas, podría ser comparando cuántas personas tienen menos de 2 años en su empresa actual por rango de edad.

# Respuestas por Edad
resp_edad <- rh22 %>% 
  group_by(edad) %>% 
  tally() %>% 
  ungroup()

# Nuevos Empleados
resp_ne <- rh22 %>% 
  filter(anios_empresa < 2) %>% 
  group_by(edad) %>% 
  tally(name = "nuevos") %>% 
  ungroup()

resp_edad <- left_join(resp_edad, resp_ne, by = "edad") %>% 
  mutate(nuevos = coalesce(nuevos, 0))


ggplot(resp_ne, aes(x = edad, y = nuevos)) +
  geom_col(fill = rosa1) +
  geom_text(aes(label = nuevos), 
            vjust = -0.5,
            size = 3) +
  scale_y_continuous(limits = c(0,65)) +
  estiloh +
  labs(title = "Personas con menos de 2 años de antigüedad\nen su actual empresa",
       x = NULL, y = NULL,
       caption = fuente)

En el gráfico anterior podemos apreciar que las personas con menos de dos años de antigüedad en sus empresas empieza a decrecer luego de los 30 años.

gt(
  resp_edad %>% 
    select(edad, nuevos, n) %>% 
    mutate(porcentaje = nuevos/n) 
) %>% 
  fmt_percent(columns = porcentaje,
              decimals = 1) %>% 
  tab_header(title = "Porcentaje de Nuevos Empleados según Edad",
             subtitle = "Nuevo Empleado = Antigüedad < 2 años") %>% 
  tab_source_note(source_note = fuente) %>% 
  cols_label(edad = "Edad",
             n = "Total",
             nuevos = "Empleados Nuevos",
             porcentaje = "Porcentaje") 
Porcentaje de Nuevos Empleados según Edad
Nuevo Empleado = Antigüedad < 2 años
Edad Empleados Nuevos Total Porcentaje
18 - 25 11 17 64.7%
25 - 30 58 93 62.4%
31 - 35 41 91 45.1%
36 - 40 28 59 47.5%
41 - 45 17 37 45.9%
46 - 50 5 17 29.4%
51 - 55 1 6 16.7%
55 - 60 0 1 0.0%
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2022

De la tabla anterior podemos ver que:

  • Casi dos tercios de las personas menores de 30 años está en sus empresas hace menos de dos años.
  • Casi la mitad de las personas mayores de 30 años y menores de 45 años que respondieron la encuesta tienen menos de dos años de experiencia en su empleo actual.
  • A partir de los 46 años el porcentaje de empleados nuevos decrece.

Hay una parte de esta movilidad en función de la edad que la podemos explicar por el afán de buscar mejores oportunidades laborales (o las primeras oportunidades en los más jóvenes) mientras uno tiene menores responsabilidades, y a medida que las personas crecemos nos interesa más la estabilidad o el retiro.

Algo interesante para analizar sería la tasa de desempleo por rangos de edad de profesionales de RRHH y cuánto tiempo estuvieron buscando trabajo o si las personas estuvieron desempleadas antes de su actual empleo o no, pero son datos con los que no contamos y que exceden este trabajo.

Finalmente veamos en qué puestos se desarrollan las personas con menos de dos años de antigüedad según su rango de edad

rh22 %>% 
  filter(anios_empresa < 2) %>% 
  group_by(edad, puesto) %>% 
  tally() %>% 
  ungroup %>% 
  ggplot(aes(x = fct_rev(puesto), y = n)) +
  geom_col(fill = rosa1) +
  facet_wrap(~edad, ncol = 2,scales = "free_y") +
  theme(axis.text.x = element_text(angle = 90)) +
  estiloh +
  labs(title = "Puestos de Trabajadores Nuevos por Edad",
       x = NULL, y = NULL,
       caption = fuente)

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 36
Chile 1
Otro Europa 1
Paraguay 1
Perú 1
Total 40
Fuente: Encuesta KIWI de Sueldos de RRHH para Latam 2022

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 6
Total 40

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 15
Maestría o superior completa 9
Diplomado de posgrado completo 7
Diplomado de posgrado en curso 2
Terciario completo 2
Universitario abandonado 2
Maestría o superior en curso 1
Terciario en curso 1
Universitario en curso 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 33
Contractor 4
Responsable inscripto 2
Asociado a cooperativa de trabajo 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 9
Transferencia 3
criptos estables 1
Cuenta en el exterior 1
Deel 1
dinero en mano 1
PayPal 1
Wise 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 16
Entre 2 y 5 años 14
Entre 5 y 10 años 1
Más de 10 años 9

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 24 0.6
No 16 0.4

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 22
Anual 2

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% 1
30% 2
40% 3
50% 2

Otros análisis

Relación entre satisfacción y sueldos

Para este análisis nos preguntamos si hay relación entre el nivel salarial y la satisfacción.

Para responder a esta pregunta, cruzamos los sueldos brutos de Argentina, contra los niveles de satisfacción con la actual empresa donde trabajan las personas que respondieron la encuesta.

Los pasos que seguimos fueron los siguientes:

A los sueldos brutos los segmentamos en 4 partes con igual cantidad de registros (cuartiles). Es decir, en el 1° cuartil tenemos el 25% de los datos, en el segundo cuartil tenemos el 50% de los datos, y en el 3° cuartil tenemos el 75% de los datos. En el primer cuartil están los sueldos más bajos, y el 4° los más altos. Los niveles de satisfacción van del 1 (Totalmente Insatisfecho), al 5, (Totalmente Satisfecho).

library(ggalluvial)

satisf <- rh22la %>% 
  filter(!is.na(satisfaccion),
         pais == "Argentina") %>% 
  select(sueldo_bruto, satisfaccion)


p25 <- profiling_num(satisf)[1,7]
p50 <- profiling_num(satisf)[1,8]
p75 <- profiling_num(satisf)[1,9]

satisf <- satisf %>% 
  mutate(cuartil = factor(case_when(
    sueldo_bruto  <   p25  ~ "1Q",
    sueldo_bruto > p25 & sueldo_bruto < p50 ~ "2Q",
    sueldo_bruto > p50 & sueldo_bruto < p75 ~ "3Q",
    TRUE   ~ "4Q")),
    satisfaccion = factor(satisfaccion, 
                             levels = c("1","2","3","4","5")), 
    cuenta = 1)


satisf <- satisf %>% 
  group_by(satisfaccion, cuartil) %>% 
  summarise(cant = n())



ggplot(as.data.frame(satisf), aes(y = cant, axis1 = cuartil, axis2 = satisfaccion)) +
  geom_alluvium(aes(fill = cuartil), width = 1/12,  alpha = 0.4) +
  geom_stratum(width = 1/12, fill = "#8882F7") +
  geom_label(stat = "stratum", aes(label = after_stat(stratum))) +
  scale_x_discrete(limits = c("Sueldo Bruto por Cuartil", "Nivel de Satisfacción"), expand = c(.05, .05)) +
  scale_fill_manual(values = c(verde, lila, rosa1, azul)) +
  theme_void() +
  labs(title = "Relación entre nivel salarial y satisfacción con la empresa",
       y = "", caption = fuente, fill = "Cuartil")

Burn out en RRHH

En esta edición de la Encuesta KIWI de Sueldos de RH Latam incluimos unas preguntas nuevas sobre burn out debido a cómo el tema de la salud mental ha cobrado relevancia desde el inicio de la pandemia y las compañías han desarrollado muchas actividades (con mayor o menor efectividad) desde entonces.

Es por eso que en esta edición incluimos 3 preguntas:

  • Del 1 al 10, ¿qué tan estresado o estresada te sentís?
  • En comparación con el año pasado, ¿cómo te sentís?
  • Motivo principal por el cual sentís estrés en el trabajo.

Esta sección fue publicada previamente en este link

burn <- kiwi %>%
  filter(!is.na(estres)) %>% 
  select(genero, puesto, rubro, estres,
         comparacion, motivo)

# Transformar en categórica la variable estrés
burn <- burn %>% 
  mutate(estres_cat = case_when(
    estres <= 2 ~ "Sin Estrés",
    estres <= 4 ~ "Estrés Bajo",
    estres <= 6 ~ "Estrés Moderado",
    estres <= 8 ~ "Estrés Alto",
    estres <= 10 ~ "Estrés Muy Alto"
  ),
  estres_cat = factor(estres_cat, 
                      levels = c("Sin Estrés", "Estrés Bajo", 
                                 "Estrés Moderado",
                                 "Estrés Alto", "Estrés Muy Alto")))

# Ordenar variable 'comparacion'
burn <- burn %>% 
  mutate(comparacion = 
           factor(comparacion,
                  levels = c("No me siento estresada o estresado",
                             "Con menos estrés",
                             "Mismo nivel de estrés",
                             "Con más estrés")))

# Calcular porcentajes de los resultados.
niveles <- burn %>% 
  group_by(estres_cat) %>% 
  summarise(cant = n()) %>% 
  ungroup() %>%
  mutate(Porcentaje = cant/sum(cant))

Para construir las categorías de los niveles de estrés asumimos que resultados:

  • 1 o 2 = Sin Estrés
  • 3 o 4 = Estrés Bajo
  • 5 o 6 = Estrés Moderado
  • 7 u 8 = Estrés Alto
  • 9 o 10 = Estrés Muy Alto

En base a 210 recibidas, el 60% sienten que su nivel de estrés es Alto o Muy Alto.

ggplot(niveles, aes(x = estres_cat, y = cant, fill = estres_cat)) +
  geom_col() +
  geom_text(aes(label = percent(Porcentaje, accuracy = 1)),
            vjust = 1.2,
            color = "white", 
            face = "bold",
            size = 4) +
  scale_fill_viridis_d(direction = -1)+
  estiloh +
  labs(title = "Niveles de estrés en RRHH",
       subtitle = paste0("En base a ", sum(niveles$cant), " respuestas recibidas"),
       caption = fuente,
       x = NULL, y = NULL, 
       fill = NULL) +
  theme(legend.position = "none")

Comparación de Estres

comparacion <- burn %>% 
  group_by(comparacion) %>% 
  summarise(cant = n()) %>% 
  ungroup() %>% 
  mutate(porcentaje = cant/sum(cant),
         comparacion = str_wrap(comparacion, width = 20))

La siguiente pregunta que realizamos es si la sensación de estrés es mayor, igual o menor al año pasado.

En base a las respuestas obtenidas, un 35% siente que su nivel de estrés es mayor en relación al año anterior, mientras que un 35% afirma que sus niveles de estrés son más bajos en relación al 2021.

ggplot(comparacion, aes(x = comparacion, 
                        y = cant, 
                        fill = comparacion)) +
  geom_col() +
    geom_text(aes(label = percent(porcentaje, accuracy = 1)),
            vjust = 1.2,
            color = "white", 
            face = "bold",
            size = 4) +
  scale_fill_viridis_d(direction = -1)+
  estiloh +
  labs(title = "Comparación de Niveles de Estrés vs. Año Anterior",
       subtitle = paste0("En base a ", sum(niveles$cant), " respuestas recibidas"),
       caption = fuente,
       x = NULL, y = NULL, 
       fill = NULL) +
  theme(legend.position = "none")

Causas de la sensación de estrés

En la siguiente nube de palabras podremos ver las causas mencionadas en la pregunta abierta sobre las causas de la sensación de estrés de las personas que trabajan en RRHH.

# Separar las palabras en filas individuales
causa <- burn %>% 
  filter(!is.na(motivo)) %>% 
  select(motivo) %>% 
  unnest_tokens(palabra, motivo)

# Lexicon de palabras vacías
vacias <- read_csv("https://raw.githubusercontent.com/7PartidasDigital/AnaText/master/datos/diccionarios/vacias.txt",
                               locale = default_locale())

# Eliminar palabras vacías
causa <- causa %>% 
  anti_join(vacias, by = "palabra")

# Contar la cantidad de veces que aparece cada palabra
 causa <- causa %>%
   count(palabra, sort = T, name = "freq")

# Crear la nube de palabras
nube <- wordcloud2(data = causa,
           size = 0.8,
           rotateRatio = 1,
           color = rep_len(c("#D4499C", "#3500B3", "#02D9C5", "#5463A8", "#DEF241"),                          nrow(causa)))
nube

Podemos apreciar que las 5 principales palabras son:

  1. trabajo: con 27 apariciones
  2. falta: con 20 apariciones
  3. carga: con 15 apariciones
  4. tareas: con 15 apariciones
  5. tiempo: con 11 apariciones

Esto nos daría a entender que una de las principales causas de estrés es la alta carga de trabajo con la que contamos y la falta de recursos que tenemos.

A continuación intentaremos analizar las relaciones de estos conceptos, para lo cual lo que haremos en primer lugar es agrupar las palabras de a pares, llamados bigramas en la jerga, y luego realizaremos un análisis de grafos para ver cómo se relacionan entre sí. Para saber más sobre análisis de grafos te invitamos a ver este video de un meetup de R4HR

# Creamos duplas de tokens
causa2 <- burn %>% 
  filter(!is.na(motivo)) %>% 
  select(motivo) %>% 
  unnest_tokens(bigrama, motivo,
                token = "ngrams",
                n = 2)

# Separamos los bigramas en dos columnas
causa2 <- causa2 %>% 
    separate(bigrama,
           c("palabra1", "palabra2"),
           sep = " ")

# Eliminamos palabras vacías
causa2 <- causa2 %>% 
   filter(!palabra1 %in% vacias$palabra,
         !palabra2 %in% vacias$palabra)

# Eliminamos filas con datos nulos
causa2 <- causa2 %>% 
  filter(!is.na(palabra1))

Si tienen curiosidad por ver cuáles son los bigramas más frecuentes les dejo este gráfico:

causa2 %>% 
  unite(bigrama, palabra1, palabra2, sep = " ") %>% 
  group_by(bigrama) %>% 
  tally(sort = TRUE) %>% 
  ungroup() %>% 
  filter(n > 1) %>% 
  ggplot(aes(x = n, y = reorder(bigrama, n))) +
  geom_col(fill = rosa2) +
  geom_text(aes(label = n), 
            hjust = 1.2, 
            size = 3) +
  estilov +
  labs(title = "Motivos de Estrés en RRHH",
    subtitle = "Bigramas más frecuentes",
       x = NULL, y = "Bigramas",
       caption = fuente)

Las cantidades de repeticiones son bajas porque sólo tenemos 160 comentarios para analizar. Sin embargo hay tópicos que podemos entender que la carga de trabajo (carga laboral, mucho trabajo, muchos temas, muchas cosas) es la principal causa de estrés dentro de RRHH.

Ahora analicemos las relaciones entre estos conceptos:

# Creamos un objeto grafo
grafo_causa2 <-  causa2 %>% 
  count(palabra1, palabra2, sort = T) 

grafo_causa2 <- grafo_causa2 %>% 
  graph_from_data_frame()

# Seleccionar 100 filas nada más 
ggraph(grafo_causa2, layout = "nicely") +
  geom_edge_link(aes(edge_alpha = n),
                 show.legend = FALSE,
                 arrow = arrow(type = "closed",
                               length = unit(3, "mm"))) +
  geom_node_point(color = rosa2, size = 3) +
  geom_node_text(aes(label = name), vjust = 1, hjust = 1) +
  theme_void()

Este gráfico inicial es un poco confuso dado que tenemos muchas relaciones con bigramas que se repiten una sola vez. Pero prestemos atención a las zonas donde hay mucha concentración de conceptos, y eso nos va a dar una idea de cómo se relacionan las palabras entre sí.

Busquen el término carga. Las palabras mucha y demasiada apuntan a carga (esto se llama un grafo dirigido) y luego carga apunta a laboral que tiene a su vez relaciones con agenda, presión y entorno, por ejemplo.

Si filtramos los bigramas que tienen más de una aparición nos encontramos con algo así

# Creamos un objeto grafo
grafo_causa2 <-  causa2 %>% 
  count(palabra1, palabra2, sort = T) %>% 
  filter(n > 1)

grafo_causa2 <- grafo_causa2 %>% 
  graph_from_data_frame()

# Seleccionar 100 filas nada más 
ggraph(grafo_causa2, layout = "nicely") +
  geom_edge_link(aes(edge_alpha = n),
                 show.legend = FALSE,
                 arrow = arrow(type = "closed",
                               length = unit(3, "mm"))) +
  geom_node_point(color = rosa2, size = 3) +
  geom_node_text(aes(label = name), vjust = 1, hjust = 1) +
  theme_void()

Vemos que los términos mucho, muchos, muchas, mucha si bien se refieren a lo mismo, a un exceso, al estar escrito de diferentes maneras genera 4 términos diferentes, así que intentaremos repetir el primer grafo con todos los conceptos, pero eliminando las palabras en plural y su género (en la medida de lo posible) para intentar generar mayor claridad.

Este proceso de limpieza nos permitió detectar que el término tiempo también tiene mucha relación con varios conceptos que contribuyen añ burn out en RRHH.

# Comenzamos limpieza de datos
burn2 <- burn %>% 
  mutate(motivo = str_replace(motivo, "alas", "a las"),
         motivo = str_replace(motivo, "años", "año"),
         motivo = str_replace(motivo, "[aá]reas", "área"),
         motivo = str_replace(motivo, "asignadas", "asignados"),
         motivo = str_replace(motivo, "aspectos", "aspecto"),
         motivo = str_replace(motivo, "beneficios", "beneficio"),
         motivo = str_replace(motivo, "buen[ao]s|buena", "bueno"),
         motivo = str_replace(motivo, "claras|claros", "claro"),
         motivo = str_replace(motivo, "clientes", "cliente"),
         motivo = str_replace(motivo, "deberían", "deben"),
         motivo = str_replace(motivo, "demasiadas", "demasiada"),
         motivo = str_replace(motivo, "decisiones", "decisión"),
         motivo = str_replace(motivo, "días", "día"),
         motivo = str_replace(motivo, "económica|economica", "económico"),
         motivo = str_replace(motivo, "exigencias", "exigencia"),
         motivo = str_replace(motivo, "externos", "externo"),
         motivo = str_replace(motivo, "extras", "extra"),
         motivo = str_replace(motivo, "estres", "estrés"),
         motivo = str_replace(motivo, "expectativas", "expectativa"),
         motivo = str_replace(motivo, "excesivas", "excesiva"),
         motivo = str_replace(motivo, "extern[ao]s", "externo"),
         motivo = str_replace(motivo, "globales", "global"),
         motivo = str_replace(motivo, "ha[bc]er[lm]e|hago|hace", "hacer"),
         motivo = str_replace(motivo, "horas", "hora"),
         motivo = str_replace(motivo, "intern[ao]s", "interno"),
         motivo = str_replace(motivo, "jef[ae]", "jefe"),
         motivo = str_replace(motivo, "jornadas", "jornada"),
         motivo = str_replace(motivo, "lasrg[ao]s|larga", "largo"),
         motivo = str_replace(motivo, "l[ií]deres", "lider"),
         motivo = str_replace(motivo, "laborales", "laboral"),
         motivo = str_replace(motivo, "locales", "local"),
         motivo = str_replace(motivo, "malos", "mal"),
         motivo = str_replace(motivo, "much[ao]", "mucho"),
         motivo = str_replace(motivo, "necesari[ao]|necesari[ao]s", "necesario"),
         motivo = str_replace(motivo, "nuev[ao]|nuev[ao]s", "nuevo"),
         motivo = str_replace(motivo, "poca|poc[ao]s", "poco"),
         motivo = str_replace(motivo, "presion|presiones", "presión"),
         motivo = str_replace(motivo, "problemas", "problema"),
         motivo = str_replace(motivo, "propia|propi[ao]s", "propio"),
         motivo = str_replace(motivo, "proyectos", "proyecto"),
         motivo = str_replace(motivo, "realizo|realizadas|realizada", "realizar"),
         motivo = str_replace(motivo, "reglas", "regla"),
         motivo = str_replace(motivo, "relaciones|relacion", "relación"),
         motivo = str_replace(motivo, "responsabilidades", "responsabilidad"),
         motivo = str_replace(motivo, "respuestas", "respuesta"),
         motivo = str_replace(motivo, "responsabilidades", "responsabilidad"),
         motivo = str_replace(motivo, "resultados", "resultado"),                motivo = str_replace(motivo, "situacion|situaciones", "situación"),
         motivo = str_replace(motivo, "soluciones", "solución"),
         motivo = str_replace(motivo, "tareas", "tarea"),
         motivo = str_replace(motivo, "temas", "tema"),
         motivo = str_replace(motivo, "tenemos|tengo", "tener"),
         motivo = str_replace(motivo, "tiempos", "tiempo"),
         motivo = str_replace(motivo, "tomado", "tomar"),
         motivo = str_replace(motivo, "toxico|tóxic[ao]|tóxic[ao]s", "tóxico"),
         motivo = str_replace(motivo, "trabajando", "trabajar"))

burn2 <- burn2 %>% 
  mutate(motivo = str_replace(motivo, "much[ao]s", "mucho"))

# Creamos duplas de tokens
causa3 <- burn2 %>% 
  filter(!is.na(motivo)) %>% 
  select(motivo) %>% 
  unnest_tokens(bigrama, motivo,
                token = "ngrams",
                n = 2)

# Separamos los bigramas en dos columnas
causa3 <- causa3 %>% 
    separate(bigrama,
           c("palabra1", "palabra2"),
           sep = " ")

# Eliminamos palabras vacías
causa3 <- causa3 %>% 
   filter(!palabra1 %in% vacias$palabra,
         !palabra2 %in% vacias$palabra)

# Eliminamos filas con datos nulos
causa3 <- causa3 %>% 
  filter(!is.na(palabra1))

# Creamos un objeto grafo
grafo_causa3 <-  causa3 %>% 
  count(palabra1, palabra2, sort = T) 

grafo_causa3 <- grafo_causa3 %>% 
  graph_from_data_frame()

# Seleccionar 100 filas nada más 
ggraph(grafo_causa3, layout = "nicely") +
  geom_edge_link(aes(edge_alpha = n),
                 show.legend = FALSE,
                 arrow = arrow(type = "closed",
                               length = unit(3, "mm"))) +
  geom_node_point(color = rosa2, size = 3) +
  geom_node_text(aes(label = name), vjust = 1, hjust = 1) +
  theme_void()

Resultados por género

Comparemos los scores promedios según el género.

burn %>% 
  filter(genero %in% c("Mujer cis", "Hombre cis")) %>% 
  group_by(genero) %>% 
  summarise(estres_prom = mean(estres)) %>% 
  ggplot(aes(x = genero, y = estres_prom, fill = genero)) +
  geom_col() +
  geom_text(aes(label = round(estres_prom,1)),
            vjust = 1.2, 
            color = "white") +
  estiloh +
  labs(title = "Promedio de Puntajes de Estrés por Género",
       x = NULL, y = NULL, 
       caption = fuente,
       fill = "Identidad de Género") +
  scale_fill_manual(values = colores) +
  theme(legend.position = "top")

estres_genero <- burn %>% 
  filter(genero %in% c("Mujer cis", "Hombre cis")) %>% 
  group_by(genero) %>% 
  summarise(estres_prom = mean(estres)) %>%
  ungroup()
burn %>% 
  filter(genero %in% c("Mujer cis", "Hombre cis")) %>% 
  ggplot(aes(x = genero, y = estres, color = genero)) +
  geom_violin()+
  geom_point(position = position_jitter(width = 0.15), alpha = 0.4, size = 4) +
  estiloh +
  labs(title = "Distribución de Puntajes de Estrés por Género",
       x = NULL, y = NULL, 
       caption = fuente,
       color = "Identidad de Género") +
  scale_color_manual(values = colores) +
  theme(legend.position = "top")

En promedio, el puntaje de estrés de las mujeres es -0.7 puntos más alto que en el caso de los varones. La mayor concentración de respuestas las tenemos entre los 5 y 7.5 puntos.

Comparación por rubros

Por último, veremos los resultados promedios por industria.

burn %>% 
  filter(rubro %in% c("Tecnologías de información", "Servicios de salud",
                      "Comercio", "Otros", "Alimentación, bebidas",
                      "Industria metalúrgica, metalmecánica",
                      "Petróleo y producción de gas, refinación de petróleo",
                      "Servicios de consultoría", "Servicios profesionales",
                      "Construcción", "Servicios financieros seguros")) %>% 
  mutate(rubro = str_wrap(rubro, width = 30)) %>% 
  group_by(rubro) %>% 
  summarise(estres_prom = mean(estres)) %>% 
  ungroup() %>% 
  ggplot(aes(x = estres_prom, y = reorder(rubro, estres_prom))) +
  geom_point(size = 4, color = azul) +
  geom_segment(aes(x = 0, xend = estres_prom, 
                   y = rubro, yend = rubro),
               color = azul) +
  estilov +
  labs(title = "Nivel Promedio de Estrés por Industria",
       caption = fuente, 
       x = NULL, y =NULL)

Conclusión

En líneas generales apreciamos que los niveles de estrés de las personas que trabajan en RRHH es alto, y que las principales razones se deben a la sobrecarga de trabajo y la cantidad de tareas que debemos atender desde el sector (y en ocasiones con menos recursos de los que deberíamos tener).

Un aspecto positivo es que en comparación con el 2021, mayormente los niveles de estrés son más bajos. Probablemente podamos atribuir ese resultado a la salida de las cuarentenas estrictas y al regreso a una vida más o menos similar a la que teníamos antes de la pandemia.

De todas maneras este es un tema que merece un estudio más a fondo hecho por personas más idóneas que nosotros. Si te sentís abrumada o abrumado, animate a pedir ayuda y a hablar con alguien de confianza. Lo peor del estrés es la sensación de soledad.

Comunidades

R4HR es una comunidad abierta y gratuita. ¿Qué quiere decir esto? Que es es un espacio donde cualquier persona puede participar de la comunidad, sepa de R o no sepa nada, y además no hay que pagar nada por formar parte. También es un espacio seguro en el que cuidamos que haya acoso, insultos o abusos.

Las comunidades son una gran forma de construir conocimiento, de aprender, de generar relaciones, para resolver consultas, y también, por qué no, de hacer buenos amigos. Así que en esta sección nos proponemos ver cuáles son las comunidades más frecuentadas por las personas que participaron de la Encuesta.

comunidad <- rh22 %>% 
  select(pais, provincia, comunidad, comunidades)

div <- comunidad %>% 
  select(comunidad) %>% 
  filter(!is.na(comunidad)) %>% 
  group_by(comunidad) %>% 
  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$comunidad, "\n Cant: ", div$n)

# Make the plot
ggplot(div, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=comunidad)) +
  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, azul)) +
  theme_void() +
  theme(legend.position = "top",
        panel.background = element_blank(),
        plot.title.position = "plot",
        text = element_text(family = "Roboto")) +
  labs(title = "Participás de Alguna Comunidad",
       fill = "Respuesta", 
       caption = fuente)

Del total de respuestas, 49% (131) participan de alguna comunidad. Estas son las comunidades mencionadas.

En la tabla a continuación ponemos todas las comunidades que nos nombraron. No ponemos la cantidad de respuestas que obtuvo cada una porque no es una competencia.

Tené en cuenta lo siguiente: Para crear una comunidad sólo hace falta tener ganas de hacerlo. Lo mejor de las comunidades es que hay mucha gente dispuesta a compartir.

comunidad <- comunidad %>% 
  filter(!is.na(comunidades), 
         comunidad == "Si") %>% 
  select(pais, comunidades)

comunidad <- comunidad %>% 
  mutate(comunidades = str_replace(comunidades, "whats app|Whatsapp|Wsapp|wsp|whatsapp", "WhatsApp"),
         comunidades = str_replace(comunidades, "Adrha|Adhra|ADHRA", "ADRHA"),
         comunidades = str_replace(comunidades, "Data 4 hr|Data4hr|DATA4HR", "Data 4HR"),
         comunidades = str_replace(comunidades, "Bench.Club|Benchclub|Bench", "Bench Club"),
         comunidades = str_replace(comunidades, "Aprhnoa", "APRHNOA"),
         comunidades = str_replace(comunidades, "Bench ClubClub", "Bench Club"),
         comunidades = str_replace(comunidades, "Aparh", "APARH"),
         comunidades = str_replace(comunidades, "slack tech recruiters arg|tech.recruiters.arg|Tech Recruiter", "Tech Recruiters Arg"),
         comunidades = str_replace(comunidades, "LinkdIn|Linkedin", "LinkedIn"),
         comunidades = str_replace(comunidades, "Uba", "UBA"),
         comunidades = str_replace(comunidades, "Interempresa Cordoba|Recursos Humanos Inter Empresas CBA", "RRHH Interempresas"),
         comunidades = str_replace(comunidades, "grupo", "Grupo"),
         comunidades = str_replace(comunidades, "Capital humano Talento femenino", "Capital Humano Talento Femenino"),
         comunidades = str_replace(comunidades, "Tendencia de Recursos Humanos Bolivia", "Tendencias en Recursos Humanos Bolivia"),
         comunidades = str_replace(comunidades, "PAS", "People Analytics Spain"),
         comunidades = str_replace(comunidades, "Grupos de Whatsapp", "Grupos de WhatsApp"),
         comunidades = str_replace(comunidades, "Grupos Whatsapp", "Grupos de WhatsApp")) 

# Reemplazo manual de comunidades
comunidad[2,2] <- "Grupos de WhatsApp, ADRHA"
comunidad[6,2] <- "Bench Club, ADRHA"
comunidad[7,2] <- "Grupos de WhatsApp"
comunidad[9,2] <- "Grupos en LinkedIn, Grupos de WhatsApp"
comunidad[12,2] <- "Grupos de WhatsApp"
comunidad[13,2] <- "Grupo de WhatsApp Córdoba"
comunidad[14,2] <- "Club de R para RH, Grupo de WhatsApp Córdoba"
comunidad[17,2] <- "Club de R para RH"
comunidad[21,2] <- "Grupos de WhatsApp, Grupo Local, LinkedIn"
comunidad[22,2] <- "Grupos de LinkedIn"
comunidad[25,2] <- "Grupos de WhatsApp, LinkedIn"
comunidad[28,2] <- "Instagram, Grupos de WhatsApp"
comunidad[29,2] <- "ADRHA, Comunidad HR"
comunidad[42,2] <- "ADRHA, LinkedIn"
comunidad[48,2] <- "Tendencias en Recursos Humanos Bolivia, ASOBOGH"
comunidad[53,2] <- "Comunidad HR, Grupos de diferentes Universidades"
comunidad[59,2] <- "Grupos de Whatsapp, LinkedIn"
comunidad[64,2] <- "Red de RRHH, Grupo de WhatsApp Mar del Plata"
comunidad[69,2] <- "Grupo de Colegas RRHH (Consultora MJG) Buenos Aires y Latinoamerica"
comunidad[70,2] <- "ADRHA, Grupos Regionales"
comunidad[73,2] <- "Club de R para RH, Data 4HR, RRHH Interempresas, Reclutadores CBA"
comunidad[80,2] <- "Compensaciones, Bench Club"
comunidad[83,2] <- "Total Rewards Compensaciones"

# Separamos las comunidades en columnas y luego pivoteamos para agruparlas
comunidad %>% 
  separate(col = comunidades, into = c("c1", "c2", "c3", "c4"), 
           sep = ",", fill = "right", remove = TRUE) %>% 
  mutate(across(c("c1", "c2", "c3", "c4"), str_trim)) %>% 
  pivot_longer(cols = c(c1:c4),
    names_to = "columna",
    values_to = "comunidad") %>% 
  filter(!is.na(comunidad)) %>% 
  filter(comunidad != "etc") %>% 
  group_by(pais, comunidad) %>% 
  tally() %>% 
  ungroup() %>% 
  select(-n) %>% 
  rename("País" = pais,
         "Comunidad" = comunidad) %>% 
  kable("html", escape=F) %>% 
  kable_styling(full_width = TRUE, 
                bootstrap_options = 
                  c("striped","hover","condensed" )) %>% 
  row_spec(0, bold=T, color="white", background = azul)
País Comunidad
Argentina ADRHA
Argentina AIHR
Argentina APRHNOA
Argentina Asociación de Recursos Humanos Misiones
Argentina Asociación de RRHH de Misiones
Argentina Asociación Misionera de RRHH
Argentina Bench Club
Argentina Capital Humano Talento Femenino
Argentina Chats
Argentina Club de Profesionales de Recursos Humanos RRHH
Argentina Club de R para RH
Argentina Club IFREI - IAE
Argentina Compañeros de posgrado
Argentina Compensaciones
Argentina Comunidad HR
Argentina Comunidad RH
Argentina Data 4HR
Argentina En red
Argentina En un Grupo de la carrera de RT de la UBA
Argentina Grupo de Colegas RRHH (Consultora MJG) Buenos Aires y Latinoamerica
Argentina Grupo de Gerentes de RRHH de Mundos E
Argentina Grupo de profesionales de RRHH de la UES21
Argentina Grupo de WhatsApp
Argentina Grupo de WhatsApp Córdoba
Argentina Grupo de WhatsApp de Compensaciones
Argentina Grupo de WhatsApp Mar del Plata
Argentina Grupo Local
Argentina Grupos de diferentes Universidades
Argentina Grupos de la facultad.
Argentina Grupos de LinkedIn
Argentina Grupos de Whatsapp
Argentina Grupos de WhatsApp
Argentina Grupos en LinkedIn
Argentina Grupos Regionales
Argentina Grupos WhatsApp
Argentina IDEA
Argentina Instagram
Argentina Invounf recruiting
Argentina ITBA People Analytics
Argentina LinkedIn
Argentina Profesionales de RRHH
Argentina Profesionales de RT
Argentina Reclutadores CBA
Argentina Red de profesionales RT
Argentina Red de RRHH
Argentina Rewards
Argentina RH Talent
Argentina RR.HH. ARGENTINA
Argentina RRHH Interempresas
Argentina Talento de Cessi
Argentina Tech Recruiters Arg
Argentina Total Rewards Compensaciones
Argentina UBA
Argentina Varias
Argentina Varias en Facebook
Bolivia ASOBOGH
Bolivia Tendencias en Recursos Humanos Bolivia
Chile Comunidades de People Analytics
Chile Red de RRHH
Ecuador People Analytics Ecuador
El Salvador ASOBOGH
España People Analytics Spain
México Grupos de redes sociales
México People Analytics en su mayoría
Paraguay APARH
Paraguay Asociación Paraguaya de Recursos Humanos
Paraguay Comunidad RH
Paraguay Mas de tres
Perú Local
LS0tDQp0aXRsZTogIjPCsCBFbmN1ZXN0YSBLSVdJIGRlIFN1ZWxkb3MgZGUgUkgiDQphdXRob3I6ICJSNEhSIENsdWIgZGUgUiBwYXJhIFJSSEgiDQpkYXRlOiAiMjAyMi0xMS0zMCINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdGhlbWU6IGNvc21vDQogICAgaGlnaGxpZ2h0OiBoYWRkb2NrDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgZmlnLnJldGluYSA9IDMsIG91dC53aWR0aCA9ICI4MCUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIikNCg0KIyBMaWJyZXLDrWFzIC0tLS0NCnBhY21hbjo6cF9sb2FkKHRpZHl2ZXJzZSwgZnVuTW9kZWxpbmcsIGd0LCBleHRyYWZvbnQsIHNjYWxlcywgDQogICAgICAgICAgICAgICBnZ2FsdCwga2FibGVFeHRyYSwgd29yZGNsb3VkLCBuZXR3b3JrRDMsIGdncG1pc2MsDQogICAgICAgICAgICAgICBkYXRhLnRhYmxlLCBnZ2Vjb25vZGlzdCwgd29yZGNsb3VkMiwgdGlkeXRleHQsDQogICAgICAgICAgICAgICBpZ3JhcGgsIGdncmFwaCwgZ3JpZCkNCg0KIyBDb25maWd1cmFjaW9uZXMgZ2VuZXJhbGVzIC0tLS0NCg0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpICAgIyBNb2RpZmljYSBsYSB2aXN1YWxpemFjacOzbiBkZSBsb3MgZWplcyBudW3DqXJpY28gYSB2YWxvcmVzIG5vbWluYWxlcw0KDQpsb2FkZm9udHMocXVpZXQgPSBUUlVFKSAjIFBlcm1pdGUgY2FyZ2FyIGVuIFIgb3Ryb3MgdGlwb3MgZGUgZnVlbnRlcy4NCg0KIyBFc3RpbG8gbGltcGlvIHNpbiBsw61uZWFzIGRlIGZvbmRvDQplc3RpbG8gPC0gdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjRkJGQ0ZDIiksDQogICAgICAgICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJSb2JvdG8iKSwNCiAgICAgICAgICAgICAgICBwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiKQ0KDQojIEVzdGlsbyBsaW1waW8gY29uIGzDrW5lYXMgZGUgcmVmZXJlbmNpYSB2ZXJ0aWNhbGVzIGVuIGdyaXMgY2xhcm8NCmVzdGlsb3YgPC0gdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZCRkNGQyIpLA0KICAgICAgICAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiI0FFQjZCRiIpLA0KICAgICAgICAgICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJSb2JvdG8iKSwNCiAgICAgICAgICAgICAgICAgcGxvdC50aXRsZS5wb3NpdGlvbiA9ICJwbG90IikNCg0KIyBFc3RpbG8gbGltcGlvIGNvbiBsw61uZWFzIGRlIHJlZmVyZW5jaWEgaG9yaXpvbnRhbGVzIGVuIGdyaXMgY2xhcm8NCmVzdGlsb2ggPC0gdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI0ZCRkNGQyIpLA0KICAgICAgICAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiI0FFQjZCRiIpLA0KICAgICAgICAgICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJSb2JvdG8iKSwNCiAgICAgICAgICAgICAgICAgcGxvdC50aXRsZS5wb3NpdGlvbiA9ICJwbG90IikNCg0KZ2VuZXJvIDwtIGMoIiM4NjI0RjUiLCAiIzFGQzNBQSIsICIjRkZEMTI5IiwgIiM3NTgzOEYiKSAjVmlvbGV0YSAtIFZlcmRlIC0gQW1hcmlsbG8gLSBHcmlzDQpnZW5lcm8zIDwtIGMoIiM4NjI0RjUiLCIjRkZEMTI5IiwgIiMxRkMzQUEiKQ0KDQpjb2xvcmVzIDwtICBjKCIjODYyNEY1IiwgIiMxRkMzQUEiKQ0KDQphenVsIDwtICIjMzQ0RDdFIg0KdmVyZGUgPC0gICIjMUZDM0FBIg0Kcm9zYTEgPC0gIiNCOTUxOTIiDQpyb3NhMiA8LSAiI0VFNTc3NyINCm5hcmFuamEgPC0gIiNGRjc2NEMiDQphbWFyaWxsbyA8LSAiI0ZGRDEyOSINCmdyaXMgPC0gIiM3NTgzOEYiDQpsaWxhIDwtICIjODYyNEY1Ig0Kcm9qbyA8LSAiIzk0MzEyNiINCg0KY29sNCA8LSBjKGF6dWwsIGxpbGEsIHJvc2ExLCByb3NhMikNCmNvbDUgPC0gYyhhenVsLCBsaWxhLCByb3NhMSwgcm9zYTIsIG5hcmFuamEpDQpjb2w2IDwtIGMoYXp1bCwgbGlsYSwgcm9zYTEsIHJvc2EyLCBuYXJhbmphLCBhbWFyaWxsbykNCg0KIyBDcmVvIHVuIG9iamV0byBjb24gdW4gdGV4dG8gcXVlIHNlIHZhIGEgcmVwZXRpciBtdWNobyBhIGxvIGxhcmdvIGRlbCBhbsOhbGlzaXMNCmZ1ZW50ZSA8LSAiRnVlbnRlOiBFbmN1ZXN0YSBLSVdJIGRlIFN1ZWxkb3MgZGUgUlJISCBwYXJhIExhdGFtIDIwMjIiDQoNCiMgQ3JlbyBvYmpldG9zIHBhcmEgZm9ybWF0ZWFyIGxhcyBldGlxdWV0YXMgbnVtw6lyaWNhcyBkZSBsb3MgZWplcyB4IGUgeQ0KZWplX3hfbiA8LSBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gY29tbWFfZm9ybWF0KGJpZy5tYXJrID0gIi4iLCBkZWNpbWFsLm1hcmsgPSAiLCIpKQ0KDQplamVfeV9uIDwtIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBjb21tYV9mb3JtYXQoYmlnLm1hcmsgPSAiLiIsIGRlY2ltYWwubWFyayA9ICIsIikpDQoNCmVqZV94X3AgPC0gc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpDQoNCmVqZV95X3AgPC0gc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpDQoNCg0KIyBEYXRvcyAtLS0tDQojIFJlbGFjacOzbiBkZSBkZXBlbmRlbmNpYQ0KcmgyMiA8LSByZWFkX2RlbGltKCJkYXRhL3JoXzIwMjIuY3N2IiwgZGVsaW0gPSAiOyIpDQoNCiMgRnJlZWxhbmNlcnMNCmZyZWVsbzIyIDwtIHJlYWRfZGVsaW0oImRhdGEvZnJlZWxhbmNlcnNfMjAyMi5jc3YiLCBkZWxpbSA9ICI7IikNCg0KIyBCYXNlIE9yaWdpbmFsDQpraXdpIDwtIHJlYWRfZGVsaW0oImRhdGEva2l3aV8yMDIyLmNzdiIsIGRlbGltID0gIjsiKSAlPiUgDQogIGphbml0b3I6OmNsZWFuX25hbWVzKCkNCg0KIyBFZGljaW9uZXMgYW50ZXJpb3Jlcw0KIyBFbmN1ZXN0YQ0Ka2l3aTIxIDwtIHJlYWQuY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcjRoci9raXdpMjAyMS9tYWluL2RhdGEvcmhfMjAyMS5jc3YiLA0KICAgICAgICAgICAgICAgICAgIHNlcCA9ICI7IiwNCiAgICAgICAgICAgICAgICAgICBlbmNvZGluZyA9ICJVVEYtOCIpIA0KDQpraXdpMjAgPC0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9yNGhyL2tpd2kyMDIxL21haW4vZGF0YS9yaF8yMDIwLmNzdiIsIA0KICAgICAgICAgICAgICAgICAgIHNlcCA9ICI7IiwNCiAgICAgICAgICAgICAgICAgICBlbmNvZGluZyA9ICJVVEYtOCIpDQoNCiMgTGltcGllemEgZGUgZGF0b3MgLS0tLS0NCg0KIyBBZ3J1cGFyIHB1ZXN0b3MNCnJoMjIgPC0gcmgyMiAlPiUgDQogIG11dGF0ZShwdWVzdG8gPSANCiAgICAgICAgICAgZmN0X2NvbGxhcHNlKHB1ZXN0bywgDQogICAgICAgICAgICAgICAgICAgICAgICAiQW5hbGlzdGEiID0gYygiQW5hbGlzdGEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBbmFsaXN0YSBkZSBQZW9wbGUgT3BlcmF0aW9ucyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ29uc3VsdG9yIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJVCBSRUNSVUlURVIiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTcGVjaWFsaXN0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQcm9mZXNpb25hbCBSUkhIIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVjcnVpdGVyIElUIiksDQogICAgICAgICAgICAgICAgICAgICAgICAiUmVzcG9uc2FibGUiID0gYygiUmVzcG9uc2FibGUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb29yZGluYWRvcmEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMw61kZXIgw4FnaWwiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdXBlcnZpc29yIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMw61kZXIgZGUgc2VsZWNjacOzbiIpKSwNCiAgICAgICAgIHB1ZXN0byA9IGZhY3RvcihwdWVzdG8sIGxldmVscyA9IGMoIkRpcmVjdG9yIiwgIkdlcmVudGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSmVmZSIsICJSZXNwb25zYWJsZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIUkJQIiwgIkFuYWxpc3RhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFkbWluaXN0cmF0aXZvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBhc2FudGUiKSkpDQoNCiMjIEFncnVwYXIgZnVuY2lvbmVzIC0tLS0NCnJoMjIgPC0gIHJoMjIgJT4lIA0KICBtdXRhdGUoZnVuY2lvbiA9IGZjdF9jb2xsYXBzZShmdW5jaW9uLCAiR2VuZXJhbGlzdGEiID0gYygiR2VuZXJhbGlzdGEiLCAiR2VuZXJhbGlzdGEgKyBSUkxMIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdlbmVyYWxpc3RhLCBubyBoYXkgdW4gZm9jbyBxdWUgc29icmVzYWxnYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHZXN0acOzbiBkZSB0b2RhIGVsIMOhcmVhIGRlIFJSSEgiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2VzdGnDs24gUlJISCIsICJKZWZlIGRlIFJSLkhIIEdlbmVyYWxpc3RhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1peCBkZSB2YXJpYXM6IGNhcGFjaXRhY2lvbiAvIGNvbXBlbnNhY2lvbiAvIHJybGwgLyBhZG0iLCAiU29uIHZhcmlhcyBmdW5jaW9uZXMiLCAiVGVuZ28gbWFzIGRlIHVuIGFyZWEuIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUb2RhcyBsYXMgYW50ZXJpb3JlcyIsICJUb2Rhcy4gU295IGplZmUiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlbGFjaW9uZXMgbGFib3JhbGVzIiA9IGMoIlJlbGFjaW9uZXMgbGFib3JhbGVzIiwgIlJlbGFjaW9uZXMgSW5kdXN0cmlhbGVzIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYXBhY2l0YWNpw7NuIHkgZGVzYXJyb2xsbyIgPSBjKCJDYXBhY2l0YWNpw7NuIHkgZGVzYXJyb2xsbyIsICJDYXBhY2l0YWNpw7NuIHkgU2VsZWNjacOzbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIklUIFRhbGVudCBBY3F1aXNpdGlvbiAmIEhSQlAgZGUgRGVzYXJyb2xsbyB5IFByb2R1Y3RvIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWNsdXRhbWllbnRvIHkgc2VsZWNjacOzbiIgPSBjKCJSZWNsdXRhbWllbnRvIHkgc2VsZWNjacOzbiIsICJSZWNsdXRhbWllbnRvIHkgU2VsZWNjacOzbiBtw6FzIGFkbWluaXN0cmFjacOzbiBkZSBwZXJzb25hbCIsICJSZWNsdXRhbWllbnRvLCBzZWxlY2Npb24sIGNsaW1hLGNvbXVuaWNhY2nDs24sIGJlbmVmaWNpb3MiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZXNwb25zYWJsZSBkZSBhdHJhY2Npw7NuIGRlIHRhbGVudG8gKyBjdWx0dXJhIG9yZ2FuaXphY2lvbmFsIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQZW9wbGUgYW5hbHl0aWNzIiA9IGMoIlBlb3BsZSBhbmFseXRpY3MiLCAiUHJveWVjdG9zIHkgUGVvcGxlIEFuYWx5dGljcyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlzZcOxbyBvcmdhbml6YWNpb25hbCIgPSBjKCJEaXNlw7FvIG9yZ2FuaXphY2lvbmFsIiwgIkxpZGVyIGRlIHByb3llY3RvcyBIUiIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ3VsdHVyYSB5IGJpZW5lc3RhciIgPSBjKCJDdWx0dXJhIHkgYmllbmVzdGFyIiwgIkN1bHR1cmEgT3JnYW5pemFjaW9uYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQZXJzb25hcyB5IGN1bHR1cmEiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBheXJvbGwgLyBMaXF1aWRhY2nDs24gZGUgc3VlbGRvcyIgPSBjKCJQYXlyb2xsIC8gTGlxdWlkYWNpw7NuIGRlIHN1ZWxkb3MiLCAiT3BlcmFjaW9uZXMgZGUgUlJISCIsICJDb250cm9sbGVyIikpKSANCg0KIyMgVW5pZmljYXIgdGlwbyBkZSBjb250cmF0bw0KcmgyMiA8LSByaDIyICU+JSANCiAgbXV0YXRlKHRpcG9fY29udHJhdGFjaW9uID0gZmN0X2NvbGxhcHNlKHRpcG9fY29udHJhdGFjaW9uLCAiSW5kZXRlcm1pbmFkbyIgPSBjKCJJbmRldGVybWluYWRvIiwgIlJFTEFDSU9OIERFIERFUEVOREVOQ0lBIikpKQ0KDQpgYGANCg0KIyBJbnRyb2R1Y2Npw7NuDQoNCltSNEhSIENsdWIgZGUgUiBwYXJhIFJSSEhdKGh0dHBzOi8vcjRoci5jbHViKSBlcyB1bmEgY29tdW5pZGFkIGRlIGFwcmVuZGl6YWplIGRlIHByb2dyYW1hY2nDs24gZGUgUiBwYXJhIHByb2Zlc2lvbmFsZXMgeSBlc3R1ZGlhbnRlcyBxdWUgdHJhYmFqZW4gbyBxdWllcmFuIHRyYWJhamFyIGVuIFJSSEguDQoNClNvbW9zIHVuYSBjb211bmlkYWQgcXVlIHVzYSBtYXlvcm1lbnRlIGRhdG9zIGRlIGVqZW1wbG8gcmVsYWNpb25hZG9zIGNvbiBSUkhILCB5IHF1ZSBnZW5lcmEgY29udGVuaWRvIGVuIGNhc3RlbGxhbm8gcGFyYSBlbGltaW5hciBsYXMgYmFycmVyYXMgZW4gZWwgYXByZW5kaXphamUgeSBmYWNpbGl0YXIgcXVlIG3DoXMgcGVyc29uYXMgYWRvcHRlbiBsYXMgaGVycmFtaWVudGFzIGRlIGFuw6FsaXNpcyBkZSBkYXRvcyBlbiBzdXMgdHJhYmFqb3MuDQoNClBhcmEgc2FiZXIgbcOhcyBkZSBub3NvdHJvcyB0ZSBpbnZpdGFtb3MgYSBsZWVyIFtlc3RlIHBvc3RdKGh0dHBzOi8vcjRoci5jbHViLzIwMjAvMDkvMjMvZWwtY2x1Yi1kZS1yLXBhcmEtcnJoaC8pLg0KDQpUYW1iacOpbiBwb2TDqXMgdmVyIHRvZG8gZWwgY29udGVuaWRvIHF1ZSBnZW5lcmFtb3MgZW4gbG9zIHNpZ3VpZW50ZXMgbGlua3M6DQoNCmByIGljb25zOjpmb250YXdlc29tZSgiZ29vZ2xlLWRyaXZlIilgIFtHb29nbGUgRHJpdmVdKGh0dHBzOi8vZHJpdmUuZ29vZ2xlLmNvbS9kcml2ZS9mb2xkZXJzLzFRY2szel90NlhMUlhiMnZiTi0wMDkzMURnZEpaMHlzZT91c3A9c2hhcmluZykNCg0KYHIgaWNvbnM6OmZvbnRhd2Vzb21lKCJ5b3V0dWJlIilgIFtZb3VUdWJlXShodHRwczovL3lvdXR1YmUuY29tL3BsYXlsaXN0P2xpc3Q9UExadVZ5dFVKcnhRbGNxdTZsLVAzb3U0dlYybVJKVTJLYSkNCg0KYHIgaWNvbnM6OmZvbnRhd2Vzb21lKCJnaXRodWIiKWAgW0dpdGh1Yl0oaHR0cHM6Ly9naXRodWIuY29tL3I0aHIvKQ0KDQpgciBpY29uczo6Zm9udGF3ZXNvbWUoImxpbmsiKWAgVGFtYmnDqW4gdGUgaW52aXRhbW9zIGEgc2VndWlybm9zIGVuIHRvZGFzIFtudWVzdHJhcyByZWRlcyBzb2NpYWxlc10oaHR0cHM6Ly9saW5rdHIuZWUvcjRocmNsdWIpLg0KDQpQdWVkZW4gYWNjZWRlciBhIGxvcyBkYXRvcyBjcnVkb3MgZGVzZGUgW2VzdGUgbGlua10oaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMUtlQi1zWFJNbURoemdFUFdMRFZOVUhncGdyb1ZOc0xPMlVXRTBSTExDVncvZWRpdD91c3A9c2hhcmluZykuDQoNCmBgYHtyfQ0KcGFpc19yZCA8LSByaDIyICU+JSANCiAgZ3JvdXBfYnkocGFpcykgJT4lIA0KICB0YWxseSgpICU+JSANCiAgdW5ncm91cCANCg0KcGFpc19mcmVlbG8gPC0gZnJlZWxvMjIgJT4lIA0KICBncm91cF9ieShwYWlzKSAlPiUgDQogIHRhbGx5KCkgJT4lIA0KICB1bmdyb3VwIA0KDQpwYWlzZXNfa2l3aSA8LSBmdWxsX2pvaW4ocGFpc19mcmVlbG8sIHBhaXNfcmQsIGJ5ID0gInBhaXMiKSAlPiUgDQogICAgbXV0YXRlKG4ueCA9IGNvYWxlc2NlKG4ueCwgMCksDQogICAgICAgICBuLnkgPSBjb2FsZXNjZShuLnksIDApLA0KICAgICAgICAgbiA9IG4ueCArIG4ueSkNCmBgYA0KDQojIE1vdGl2YWNpb25lcw0KDQpDb21vIGVuIFJSSEggdHJhYmFqYW1vcyBjb24gZGF0b3Mgc2Vuc2libGVzLCBlcyBjb21wbGVqbyBjb25zZWd1aXIgZGF0b3MgcGFyYSBwcmFjdGljYXIgY3VhbmRvIGVzdMOhcyBhcHJlbmRpZW5kbyBzb2JyZSBQZW9wbGUgQW5hbHl0aWNzLCBlc3BlY2lhbG1lbnRlIGxhIHBhcnRlIHByw6FjdGljYS4gUG9yIGVzbywgZSBpbnNwaXJhZG9zIGVuIGxhIEVuY3Vlc3RhIGRlIFtTeXNBcm15XShodHRwczovL3N5c2FybXkuY29tL2Jsb2cvcG9zdHMvcmVzdWx0YWRvcy1kZS1sYS1lbmN1ZXN0YS1kZS1zdWVsZG9zLTIwMjAtMi8pLCB1bmEgY29tdW5pZGFkIGRlIHRlY25vbG9nw61hLCBxdWUgZW50cmUgb3RyYXMgY29zYXMsIG9yZ2FuaXphIGV2ZW50b3MgY29tbyAqKk5lcmRlYXJsYSoqLg0KDQpQb3IgZXN0YSByYXrDs24gaGljaW1vcyBudWVzdHJhIHByb3BpYSBlbmN1ZXN0YSwgcmVsZXZhbmRvIGRhdG9zIGRlIHByb2Zlc2lvbmFsZXMgcXVlIHRyYWJhamFuIHRhbnRvIGJham8gcmVsYWNpw7NuIGRlIGRlcGVuZGVuY2lhIGNvbW8gZGUgbWFuZXJhIGZyZWVsYW5jZS4gRWwgcmVsZXZhbWllbnRvIGRlIGRhdG9zIGxvIGhpY2ltb3MgZW50cmUgZWwgNyBkZSBvY3R1YnJlIHkgZWwgMjIgZGUgbm92aWVtYnJlIGRlIDIwMjEuDQoNCkVuIGVzdGEgZWRpY2nDs24gcmVjaWJpbW9zIGByIG5yb3cocmgyMikgKyBucm93KGZyZWVsbzIyKWAgcmVzcHVlc3RhcyBkZSBgciBucm93KHBhaXNlc19raXdpKWAgcGHDrXNlcyBkaWZlcmVudGVzLg0KDQpgYGB7ciB0YWJsYV9ydGFzX3BhaXN9DQpwYWlzZXNfa2l3aSAlPiUNCiAgYXJyYW5nZSgtbiwgcGFpcykgJT4lIA0KICBzZWxlY3QocGFpcywgbikgJT4lIA0KICByZW5hbWUoIlBhw61zIiA9IHBhaXMsDQogICAgICAgICAiUmVzcHVlc3RhcyIgPSBuKSAlPiUgDQogIGtibChjYXB0aW9uID0gIlJlc3B1ZXN0YXMgcG9yIFBhw61zIiwgKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEYsIHBvc2l0aW9uID0gImNlbnRlciIsDQogICAgICAgICAgICAgICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIikpICU+JSANCiAgZm9vdG5vdGUoZ2VuZXJhbCA9IGZ1ZW50ZSkNCmBgYA0KDQpEZWwgdG90YWwgZGUgcmVzcHVlc3RhcyByZWNpYmlkYXMsIGByIG5yb3cocmgyMilgIHNvbiBkZSBwZXJzb25hcyBxdWUgdHJhYmFqYW4gZW4gcmVsYWNpw7NuIGRlIGRlcGVuZGVuY2lhIGVuIFJSSEgsIG1pZW50cmFzIHF1ZSBgciBucm93KGZyZWVsbzIyKWAgcGVyc29uYXMgdHJhYmFqYW4gZGUgbWFuZXJhIGZyZWVsYW5jZS4NCg0KYGBge3J9DQoNCnBhaXNlc19raXdpIDwtIHBhaXNlc19raXdpICU+JSANCiAgZ3JvdXBfYnkocGFpcykgJT4lIA0KICBzdW1tYXJpc2UodG90YWxfZnJlZWxvID0gc3VtKG4ueCksDQogICAgICAgICAgICB0b3RhbF9yZCA9IHN1bShuLnkpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIHBpdm90X2xvbmdlcihjb2xzID0gYygidG90YWxfZnJlZWxvIiwgInRvdGFsX3JkIiksDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJ0cmFiYWpvIiwNCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJydGFzIikNCg0Ka2l3aSAlPiUgDQogIHNlbGVjdCh0cmFiYWpvKSAlPiUgDQogIGdyb3VwX2J5KHRyYWJham8pICU+JSANCiAgY291bnQoKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSB0cmFiYWpvKSkgKw0KICBnZW9tX2NvbChmaWxsID0gYXp1bCkgKw0KICBlc3RpbG92ICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCAjIEluZGljYSBsYSBjYW50aWRhZCBkZSBkZWNpbWFsZXMNCiAgICAgICAgICAgIHNpemUgPSAzLCAgICAgICAjIENhbWJpYSBlbCB0YW1hw7FvIGRlIGxhIGxldHJhDQogICAgICAgICAgICBoanVzdCA9IDEuMiwgICAgIyBNdWV2ZSBsYSBldGlxdWV0YSBwYXJhIGxhIGl6cXVpZXJkYQ0KICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICAgZmFtaWx5ID0gIlJvYm90byIpICsNCiAgbGFicyh0aXRsZSA9ICJSZXNwdWVzdGFzIHBvciB0aXBvIGRlIHRyYWJhamFkb3IiLCANCiAgICAgICB4ID0gIiIsIHkgPSAiIiwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCmBgYA0KDQpDb21vIGFjbGFyYWNpw7NuLCBjdWFuZG8gbm9zIHJlZmVyaW1vcyBhIGxhICoqaWRlbnRpZGFkIGRlIGfDqW5lcm8qKiBkZSBsYXMgcGVyc29uYXMsIHV0aWxpemFtb3MgbG9zIHTDqXJtaW5vcyBNdWplciBjaXMvTXVqZXIgdHJhbnMqIHkgKkhvbWJyZSBjaXMvSG9tYnJlIHRyYW5zKiBwYXJhIHBvZGVyIHJlZmxlamFyIGNvbiBtYXlvciBwcmVjaXNpw7NuIGVsIGFiw6FuaWNvIGRlIGlkZW50aWRhZGVzIHkgcGVyY2VwY2lvbmVzLg0KDQo+IEVsIHTDqXJtaWlubyAqImNpcyIqIGhhY2UgcmVmZXJlbmNpYSBhIHF1ZSBsYSBwZXJzb25hIHNlIGlkZW50aWZpY2EgY29uIGVsIG1pc21vIGfDqW5lcm8gY29uIGVsIHF1ZSBuYWNpw7MuDQoNCkxlIGFncmFkZWNlbW9zIG11Y2hvIGEgW0l2YW5hIEZlbGRlYmVyZ10oaHR0cHM6Ly93d3cubGlua2VkaW4uY29tL2luL2l2YW5hLWZlbGRmZWJlci8pIGRlbCBbT2JzZXJ2YXRvcmlvIGRlIERhdG9zIGNvbiBQZXJzcGVjdGl2YSBkZSBHw6luZXJvXShodHRwczovL3d3dy5kYXRhZ2VuZXJvLm9yZy8pIHBvciBlbCBhc2Vzb3JhbWllbnRvIGVuIGVzdGUgYXBhcnRhZG8uDQoNCkRpY2hvIGVzdG8sIGxhcyByZXNwdWVzdGFzIHNlZ8O6biBsYSBpZGVudGlkYWQgZGUgZ8OpbmVybyBkZSBsYXMgcGVyc29uYXMgcXVlIHBhcnRpY2lwYXJvbiBlcyBsYSBzaWd1aWVudGU6DQoNCmBgYHtyIGZpZy5zaG93PSdob2xkJywgb3V0LndpZHRoPSI1MCUiLCBmaWcuYWxpZ249J2RlZmF1bHQnfQ0KDQojIEdyw6FmaWNvIHBhcmEgcmVsYWNpw7NuIGRlIGRlcGVuZGVuY2lhLS0tLQ0KcmgyMiA8LSByaDIyICU+JSANCiAgbXV0YXRlKGdlbmVybyA9IGZjdF9jb2xsYXBzZShnZW5lcm8sICAiSG9tYnJlIGNpcyIgPSBjKCJIb21icmUgY2lzIiwgIlZhcm9uIikpKQ0KDQpkaXYgPC0gcmgyMiAlPiUgDQogIHNlbGVjdChnZW5lcm8pICU+JSANCiAgbXV0YXRlKGdlbmVybyA9IGZhY3RvcihnZW5lcm8sIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk11amVyIGNpcyIsICJIb21icmUgY2lzIiwgIk11amVyIHRyYW5zIikpKSAlPiUgDQogIGdyb3VwX2J5KGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2UgKG4gPSBuKCkpICU+JSANCiAgbXV0YXRlKGZyZXEgPSBuL3N1bShuKSkgJT4lIA0KICBhcnJhbmdlKC1uKQ0KDQojIENvbXB1dGUgdGhlIGN1bXVsYXRpdmUgcGVyY2VudGFnZXMgKHRvcCBvZiBlYWNoIHJlY3RhbmdsZSkNCmRpdiR5bWF4IDwtIGN1bXN1bShkaXYkZnJlcSkNCg0KIyBDb21wdXRlIHRoZSBib3R0b20gb2YgZWFjaCByZWN0YW5nbGUNCmRpdiR5bWluIDwtIGMoMCwgaGVhZChkaXYkeW1heCwgbj0tMSkpDQoNCiMgQ29tcHV0ZSBsYWJlbCBwb3NpdGlvbg0KZGl2JGxhYmVsUG9zaXRpb24gPC0gKGRpdiR5bWF4ICsgZGl2JHltaW4pIC8gMg0KDQojIENvbXB1dGUgYSBnb29kIGxhYmVsDQpkaXYkbGFiZWwgPC0gcGFzdGUwKGRpdiRnZW5lcm8sICJcbiBDYW50OiAiLCBkaXYkbikNCg0KIyBNYWtlIHRoZSBwbG90DQpnZ3Bsb3QoZGl2LCBhZXMoeW1heD15bWF4LCB5bWluPXltaW4sIHhtYXg9NCwgeG1pbj0zLCBmaWxsPWdlbmVybykpICsNCiAgZ2VvbV9yZWN0KCkgKw0KICBjb29yZF9wb2xhcih0aGV0YT0ieSIpICsgIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gdW5kZXJzdGFuZCBob3cgdGhlIGNoYXJ0IGlzIGJ1aWx0IGluaXRpYWxseQ0KICB4bGltKGMoMiwgNCkpICsjIFRyeSB0byByZW1vdmUgdGhhdCB0byBzZWUgaG93IHRvIG1ha2UgYSBwaWUgY2hhcnQNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhsaWxhLCB2ZXJkZSwgYW1hcmlsbG8pKSArDQogIHRoZW1lX3ZvaWQoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJSb2JvdG8iKSkgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgc2Vnw7puIGlkZW50aWRhZCBkZSBnw6luZXJvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJSZWxhY2nDs24gZGUgRGVwZW5kZW5jaWEiLA0KICAgICAgIGZpbGwgPSAiSWRlbnRpZGFkIGRlIEfDqW5lcm8iLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KDQojIEdyw6FmaWNvIGRlIGZyZWVsYW5jZXJzIC0tLS0NCmZyZWVsbzIyIDwtIGZyZWVsbzIyICU+JSANCiAgbXV0YXRlKGdlbmVybyA9IGZjdF9jb2xsYXBzZShnZW5lcm8sICJNdWplciBjaXMiID0gYygiTXVqZXIgY2lzIiwgIk11amVyIikpKQ0KDQpkaXYgPC0gZnJlZWxvMjIgJT4lIA0KICBzZWxlY3QoZ2VuZXJvKSAlPiUgDQogIGdyb3VwX2J5KGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2UgKG4gPSBuKCkpICU+JSANCiAgbXV0YXRlKGZyZXEgPSBuL3N1bShuKSkgJT4lIA0KICBhcnJhbmdlKC1uKQ0KDQojIENvbXB1dGUgdGhlIGN1bXVsYXRpdmUgcGVyY2VudGFnZXMgKHRvcCBvZiBlYWNoIHJlY3RhbmdsZSkNCmRpdiR5bWF4IDwtIGN1bXN1bShkaXYkZnJlcSkNCg0KIyBDb21wdXRlIHRoZSBib3R0b20gb2YgZWFjaCByZWN0YW5nbGUNCmRpdiR5bWluIDwtIGMoMCwgaGVhZChkaXYkeW1heCwgbj0tMSkpDQoNCiMgQ29tcHV0ZSBsYWJlbCBwb3NpdGlvbg0KZGl2JGxhYmVsUG9zaXRpb24gPC0gKGRpdiR5bWF4ICsgZGl2JHltaW4pIC8gMg0KDQojIENvbXB1dGUgYSBnb29kIGxhYmVsDQpkaXYkbGFiZWwgPC0gcGFzdGUwKGRpdiRnZW5lcm8sICJcbiBDYW50OiAiLCBkaXYkbikNCg0KIyBNYWtlIHRoZSBwbG90DQpnZ3Bsb3QoZGl2LCBhZXMoeW1heD15bWF4LCB5bWluPXltaW4sIHhtYXg9NCwgeG1pbj0zLCBmaWxsPWdlbmVybykpICsNCiAgZ2VvbV9yZWN0KCkgKw0KICBjb29yZF9wb2xhcih0aGV0YT0ieSIpICsgIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gdW5kZXJzdGFuZCBob3cgdGhlIGNoYXJ0IGlzIGJ1aWx0IGluaXRpYWxseQ0KICB4bGltKGMoMiwgNCkpICsjIFRyeSB0byByZW1vdmUgdGhhdCB0byBzZWUgaG93IHRvIG1ha2UgYSBwaWUgY2hhcnQNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyh2ZXJkZSwgbGlsYSkpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIsDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIlJvYm90byIpKSArDQogIGxhYnModGl0bGUgPSAiQ2FudGlkYWQgZGUgcmVzcHVlc3RhcyBzZWfDum4gaWRlbnRpZGFkIGRlIGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkZyZWVsYW5jZXJzIiwNCiAgICAgICBmaWxsID0gIklkZW50aWRhZCBkZSBHw6luZXJvIiwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCg0KYGBgDQoNCkVuIHJlc3VtZW4sIG3DoXMgZGUgZG9zIHRlcmNpb3MgZGUgbGFzIHBlcnNvbmFzIHF1ZSBwYXJ0aWNpcGFyb24gZGUgZXN0YSBlbmN1ZXN0YSBzb24gbXVqZXJlcyBjaXMuIEFsZ28gcXVlIHJlZmxlamFuIGxvcyBkYXRvcyBlcyBxdWUgZW4gbGFzIMOhcmVhcyBkZSBSZWN1cnNvcyBIdW1hbm9zLCBsYSBkaXZlcnNpZGFkIGRlIGlkZW50aWRhZGVzIGRlIGfDqW5lcm8gZXMgcHLDoWN0aWNhbWVudGUgbnVsYS4NCg0KYGBge3IgZ2VuZXJvX3BhcnRpY2lwYW50ZXN9DQojIENvcnJlZ2lyIGlkZW50aWRhZCBkZSBnw6luZXJvDQpraXdpIDwtIGtpd2kgJT4lIA0KICAgIG11dGF0ZShnZW5lcm8gPSBmY3RfY29sbGFwc2UoZ2VuZXJvLCAiTXVqZXIgY2lzIiA9IGMoIk11amVyIGNpcyIsICJNdWplciIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIb21icmUgY2lzIiA9IGMoIkhvbWJyZSBjaXMiLCAiVmFyb24iKSksDQogICAgICAgICBnZW5lcm8gPSBmYWN0b3IoZ2VuZXJvLCBsZXZlbHMgPSBjKCJNdWplciBjaXMiLCAiSG9tYnJlIGNpcyIpKSkNCg0KIyBDcmVhciB0YWJsYQ0Ka2l3aSAlPiUgDQogIGdyb3VwX2J5KGdlbmVybykgJT4lIA0KICB0YWxseShzb3J0ID0gVCkgJT4lIA0KICBtdXRhdGUoUG9yY2VudGFqZSA9IG4vc3VtKG4pLA0KICAgICAgICAgUG9yY2VudGFqZSA9IHBlcmNlbnQoUG9yY2VudGFqZSwgYWNjdXJhY3kgPSAwLjEpKSAlPiUgDQogIGphbml0b3I6OmFkb3JuX3RvdGFscygpICU+JSANCiAgcmVuYW1lKCJJZGVudGlkYWQgZGUgR8OpbmVybyIgPSBnZW5lcm8sIA0KICAgICAgICAgIkNhbnRpZGFkIiA9IG4pICU+JSANCiAga2JsKGNhcHRpb24gPSAiVG90YWwgZGUgUGFydGljaXBhbnRlcyBzZWfDum5cbklkZW50aWRhZCBkZSBHw6luZXJvIikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGLCBwb3NpdGlvbiA9ICJjZW50ZXIiLA0KICAgICAgICAgICAgICAgIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiLCAicmVzcG9uc2l2ZSIpKSAlPiUgDQogIGZvb3Rub3RlKGdlbmVyYWwgPSBmdWVudGUsIGdlbmVyYWxfdGl0bGUgPSAiIikNCg0KYGBgDQoNCiMgQW7DoWxpc2lzIGRlIHJlbXVuZXJhY2lvbmVzDQojIyBSZW11bmVyYWNpb25lcyBwb3IgcGHDrXMNCg0KRW4gZXN0YSBzZWNjacOzbiBub3MgZGVkaWNhcmVtb3MgYSBjb21wYXJhciBsb3Mgc3VlbGRvcyBlbnRyZSBsb3MgcGHDrXNlcy4gRW4gcHJpbWVyIGx1Z2FyLCBoYXkgcXVlIHJlc2FsdGFyIHF1ZSBsb3MgcmVzdWx0YWRvcyBubyBzb24gcmVwcmVzZW50YXRpdm9zIGRlIGxvcyBtZXJjYWRvcyBkZSBsb3MgcGHDrXNlcywgc2lubyBxdWUgbG8gc29uIGRlIGxvcyBkYXRvcyByZWNvbGVjdGFkb3MuDQoNClBvciBvdHJhIHBhcnRlLCBsYSBiYWphIGNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgcmVjb2xlY3RhZGFzIGRlIG90cm9zIHBhw61zZXMgZnVlcmEgZGUgbGEgQXJnZW50aW5hLCBub3MgaGFjZSBpbXBvc2libGUsIGhhY2VyIHVuIGFuw6FsaXNpcyBjb21wYXJhZG8gcmVwcmVzZW50YXRpdm8gZGUgbG9zIHB1ZXN0b3MuIFNpbiBlbWJhcmdvLCBoYXkgYWxndW5vcyBkYXRvcyBpbnRyZXNhbnRlcyBwYXJhIGFuYWxpemFyLg0KDQpQcmltZXJvLCBhbmFsaWNlbW9zIGxvcyBzdWVsZG9zIGRlIGxvcyB0cmFiYWphZG9yZXMgZW4gcmVsYWNpw7NuIGRlIGRlcGVuZGVuY2lhLCBkZSBjdXlvcyBwYcOtc2VzIGhheWFtb3MgcmVjaWJpZG8gYWwgbWVub3MgNSByZXNwdWVzdGFzLg0KDQpgYGB7ciBzdWVsZG9fcGFpczF9DQpzdWVsZG9zX2RvbGFyIDwtIHJoMjIgJT4lIA0KICBzZWxlY3QocHVlc3RvLCBzdWVsZG9fZG9sYXIsIHBhaXMsIHRpcG9fY29udHJhdGFjaW9uKSAlPiUgDQogIGZpbHRlcihwdWVzdG8gIT0gIlBhc2FudGUiLCB0aXBvX2NvbnRyYXRhY2lvbiAhPSAiUGFzYW50ZSIpDQoNCiMgRWxpbWluYW1vcyBsb3Mgc3VlbGRvcyBxdWUgZXN0w6FuIGRlbnRybyBkZWwgcmFuZ28gZW50cmUgbG9zIHBlcmNlbnRpbGVzIDUgeSA5NQ0KbnVtZXJpY29zIDwtIHByb2ZpbGluZ19udW0oc3VlbGRvc19kb2xhcikNCnBvZGFfcDA1IDwtIG51bWVyaWNvc1sxLDZdDQpwb2RhX3A5NSA8LSBudW1lcmljb3NbMSwxMF0NCg0KIyBEYWRvIHF1ZSBsb3MgcGVyY2VudGlsZXMgNSB5IDk1IGVzdMOhbiBlbiBVJDUwMSB5IDQ2NTYgcmVzcGVjdGl2YW1lbnRlLCANCiMgcG9kYW1vcyB0b2RvIGxvIHF1ZSBlc3TDqSBmdWVyYSBkZSBlc2UgcmFuZ28NCg0KbWVkaWFfcGFpcyA8LSBzdWVsZG9zX2RvbGFyICU+JSANCiAgZmlsdGVyKHBhaXMgJWluJSBjKCJBcmdlbnRpbmEiLCAiUGFyYWd1YXkiLCAiTcOpeGljbyIsICJQZXLDuiIsICJCb2xpdmlhIiwgIkVzcGHDsWEiKSwNCiAgICAgICAgIGJldHdlZW4oc3VlbGRvX2RvbGFyLHBvZGFfcDA1LHBvZGFfcDk1KSkgJT4lIA0KICBncm91cF9ieShwYWlzKSAlPiUgDQogIHN1bW1hcmlzZShzdWVsZG9wID0gbGlzdChtZWFuX3NlKHN1ZWxkb19kb2xhcikpKSAlPiUgDQogIHVubmVzdChjb2xzID0gYyhzdWVsZG9wKSkgDQogDQpzdWVsZG9fZG9sYXJfcGFpcyA8LSByaDIyICU+JSANCiAgc2VsZWN0KHBhaXMsIHN1ZWxkb19kb2xhcikgJT4lIA0KICBmaWx0ZXIoYmV0d2VlbihzdWVsZG9fZG9sYXIsIHBvZGFfcDA1LCBwb2RhX3A5NSksDQogICAgICAgICBwYWlzICVpbiUgYygiQXJnZW50aW5hIiwgIlBhcmFndWF5IiwgIk3DqXhpY28iLCAiUGVyw7oiLCAiQm9saXZpYSIsICJFc3Bhw7FhIikpDQoNCiMgR3LDoWZpY28NCmdncGxvdChtZWRpYV9wYWlzLCBhZXMocmVvcmRlcihwYWlzLCAteSksIHkgPSAgeSkpKw0KICBnZW9tX2NvbChmaWxsID0gYXp1bCwgYWxwaGEgPSAwLjg1KSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSB5bWluLHltYXggPSB5bWF4KSwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICIjMzMzZTQ3IikrDQogIGdlb21fcG9pbnQoZGF0YSA9IHN1ZWxkb19kb2xhcl9wYWlzLCBhZXMoeCA9IHBhaXMsIHkgPSBzdWVsZG9fZG9sYXIpLCANCiAgICAgICAgICAgICBhbHBoYSA9IDAuMywgc2l6ZSA9IDIsIGNvbG9yID0gIiM3NTgzOEYiLA0KICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gMC4xNSkpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoeD15LCAwKSwgYmlnLm1hcmsgPSAiLiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiKSwNCiAgICAgICAgICAgICAgICB2anVzdCA9IDEuNSwgZm9udGZhY2UgPSAiYm9sZCIpLCANCiAgICAgICAgICAgIHNpemUgPSA0LCBjb2xvciA9ICJ3aGl0ZSIsDQogICAgICAgICAgICBmYW1pbHkgPSAiUm9ib3RvIikrDQogIGVqZV95X24gKw0KICBsYWJzKHRpdGxlID0gIlNhbGFyaW8gcHJvbWVkaW8gcG9yIHBhw61zIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJTdWVsZG9zIGRlIFJSSEggZW4gVSRTIiwNCiAgICAgICBjYXB0aW9uID0gcGFzdGUwKGZ1ZW50ZSwiXG5QYcOtc2VzIGNvbiA1IG8gbcOhcyByZXNwdWVzdGFzIiksDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMKSArIA0KICBlc3RpbG9oDQpgYGANCg0KRW4gKipFc3Bhw7FhKiogc2UgZW5jdWVudHJhbiBsb3Mgc3VlbGRvcyBtw6FzIGFsdG9zIGRlIGxhIG11ZXN0cmEuIERlbnRybyBkZSBMYXRpbm9hbcOpcmljYSwgKipNw6l4aWNvKiogZXMgZWwgcGHDrXMgY29uIG1lam9yZXMgc3VlbGRvcyBkZSBsYSByZWdpw7NuIHNlZ3VpZG8gcG9yIEFyZ2VudGluYS4gT2J0dXZpbW9zIG11eSBwb2NhcyByZXNwdWVzdGFzIGRlICoqVXJ1Z3VheSoqIHkgKipDaGlsZSoqLCBxdWUgZW4gbGFzIGRvcyBlZGljaW9uZXMgYW50ZXJpb3JlcyB0ZW7DrWFuIGxvcyBzdWVsZG9zIGRlIGxhIHJlZ2nDs24sIHBlcm8gcG9yIGxhIGJhamEgY2FudGlkYWQgZGUgcmVzcHVlc3RhcywgZnVlcm9uIGV4Y2x1aWRvcyBkZWwgcHJlc2VudGUgYW7DoWxpc2lzLg0KDQojIyBBbsOhbGlzaXMgZGUgc3VlbGRvcyBwb3IgcHVlc3RvcyBlbiBMYXRpbm9hbcOpcmljYQ0KDQpgYGB7ciBzdWVsZG9fcHVlc3RvfQ0KIyBDcmVhciB1biBkYXRhIGZyYW1lIHPDs2xvIGNvbiBwYcOtc2VzIGRlIExhdGlub2Ftw6lyaWNhDQpyaDIybGEgPC0gcmgyMiAlPiUgDQogIGZpbHRlcihwYWlzICE9ICJFc3Bhw7FhIikNCg0KIyBHcsOhZmljb3MgZGUgc3VlbGRvIHByb21lZGlvIHBvciBwdWVzdG8NCnJoMjJsYSAlPiUgDQogIHNlbGVjdChwdWVzdG8sIHN1ZWxkb19kb2xhcikgJT4lIA0KICBmaWx0ZXIocHVlc3RvICE9ICJQYXNhbnRlIiwNCiAgICAgICAgIGJldHdlZW4oc3VlbGRvX2RvbGFyLCBwb2RhX3AwNSwgcG9kYV9wOTUpKSAlPiUgDQogIGdyb3VwX2J5KHB1ZXN0bykgJT4lIA0KICBzdW1tYXJpc2UobWVkaWFuYV9zYWxhcmlhbCA9IG1lZGlhbihzdWVsZG9fZG9sYXIpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1lZGlhbmFfc2FsYXJpYWwsIHkgPSBmY3RfcmV2KHB1ZXN0bykpKSArDQogIGdlb21fY29sKGZpbGwgPSBhenVsKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShtZWRpYW5hX3NhbGFyaWFsLCBhY2N1cmFjeSA9IDEscHJlZml4ID0gIlVTUyAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiLCBiaWcubWFyayA9ICIuIikpLA0KICAgICAgICAgICAgICAgIGNvbG9yID0gIiNGQkZDRkMiLA0KICAgICAgICAgICAgICAgIGhqdXN0ID0gMS4yLA0KICAgICAgICAgICAgZm9udGZhY2UgPSAiYm9sZCIsDQogICAgICAgICAgICBzaXplID0gMykgKw0KICBlc3RpbG92ICsNCiAgbGFicyh0aXRsZSA9ICJNZWRpYW5hIHNhbGFyaWFsIHBvciBwdWVzdG8iLCANCiAgICAgICBzdWJ0aXRsZSA9ICJTdWVsZG9zIGRlIFJSSEggZW4gVSRTIiwgDQogICAgICAgeCA9ICIiLCB5ID0gIiIsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpICsNCiAgZWplX3hfbg0KDQpgYGANCg0KTGEgcG9zaWNpw7NuIGRlICoqSFJCUCoqIHByZXNlbnRhIHVuYSBjb21wbGVqaWRhZCwgcXVlIGVzIHF1ZSBkZXBlbmRpZW5kbyBsYSBlbXByZXNhIGVsIHJvbCBlcyBzaW1pbGFyIGFsIGRlIHVuIE1hbmFnZXIsIG8gZW4gb3Ryb3MgY2Fzb3MgZXMgdW4gQW5hbGlzdGEgRXNwZWNpYWxpemFkbyBvIFNlbmlvci4gUG9yIGVzYSByYXrDs24gdGllbmUgdW5hIG1lZGlhbmEgc2FsYXJpYWwgbcOhcyBhbHRhIHF1ZSBsb3MgKipSZXNwb25zYWJsZXMqKi4gRXMgcG9yIGVzbyBxdWUgZW5jb250cmFtb3MgZW50cmUgbG9zICoqSFJCUCoqIGVuY29udHJhbW9zIHVuIHN1bGVkbyBtw61uaW1vIHNpbWlsYXIgYWwgZGUgbG9zIGFuYWxpc3RhcyB5IHNhbGFyaW9zIG3DoXhpbW9zIG1heW9yZXMgcXVlIGVsIGRlIGxvcyBkaXJlY3RvcmVzLg0KDQpgYGB7ciBzdWVsZG9fcHVlc3RvX3RhYmxhfQ0KZ3QocmgyMmxhICU+JSANCiAgICAgc2VsZWN0KHB1ZXN0bywgc3VlbGRvX2RvbGFyKSAlPiUgDQogICAgIGZpbHRlcihwdWVzdG8gIT0gIlBhc2FudGUiLA0KICAgICAgICAgICAgYmV0d2VlbihzdWVsZG9fZG9sYXIsIHBvZGFfcDA1LCBwb2RhX3A5NSkpICU+JSANCiAgICAgZ3JvdXBfYnkocHVlc3RvKSAlPiUgDQogICAgIHN1bW1hcmlzZShtaW5pbW8gPSBtaW4oc3VlbGRvX2RvbGFyKSwNCiAgICAgICAgICAgICAgIG1lZGlhbmFfc2FsYXJpYWwgPSBtZWRpYW4oc3VlbGRvX2RvbGFyKSwNCiAgICAgICAgICAgICAgIG1heGltbyA9IG1heChzdWVsZG9fZG9sYXIpLA0KICAgICAgICAgICAgICAgY2FudCA9IG4oKSkNCiAgICAgKSAlPiUgDQogIHRhYl9oZWFkZXIodGl0bGUgPSAiTWVkaWFuYSBzYWxhcmlhbCBwb3IgcHVlc3RvcyIsIA0KICAgICAgICAgICAgIHN1YnRpdGxlID0gIlN1ZWxkb3MgZW4gVSREIikgJT4lIA0KICB0YWJfc291cmNlX25vdGUoc291cmNlX25vdGUgPSBmdWVudGUpICU+JSANCiAgIGZtdF9jdXJyZW5jeShjb2x1bW5zID0gIGMoIm1lZGlhbmFfc2FsYXJpYWwiLCAibWluaW1vIiwgIm1heGltbyIpLCBkZWNpbWFscyA9IDAsDQogICAgICAgICAgICAgICBzZXBfbWFyayA9ICIuIiwgZGVjX21hcmsgPSAiLCIpICU+JSANCiAgY29sc19sYWJlbChwdWVzdG8gPSAiUG9zaWNpw7NuIiwNCiAgICAgICAgICAgICBtaW5pbW8gPSAiTcOtbmltbyIsDQogICAgICAgICAgICAgbWVkaWFuYV9zYWxhcmlhbCA9ICJNZWRpYW5hIiwNCiAgICAgICAgICAgICBtYXhpbW8gPSAiTcOheGltbyIsDQogICAgICAgICAgICAgY2FudCA9ICJSZXNwdWVzdGFzIikgDQpgYGANCg0KIyMgQW7DoWxsaXNpcyBwb3IgRnVuY2lvbmVzDQoNCkFsIGlndWFsIHF1ZSBlbiBlZGljaW9uZXMgYW50ZXJpb3JlcywgbGFzIGZ1bmNpb25lcyBkZSBSSCBtw6FzIGVzcGVjaWFsaXphZGFzIGNvbW8gKipEaXNlw7FvIE9yZ2FuaXphY2lvbmFsKiosICoqQ3VsdHVyYSB5IEJpZW5lc3RhcioqIHkgKipQZW9wbGUgQW5hbHl0aWNzKiogY3VlbnRhbiBjb24gc2FsYXJpb3MgbcOhcyBhbHRvcywgbWllbnRyYXMgcXVlIGZ1bmNpb25lcyBtw6FzIHRyYW5zYWNjaW9uYWxlcyBjb21vICoqQWRtaW5pc3RyYWNpw7NuIGRlIFBlcnNvbmFsKiogZXN0w6FuIGRlbnRybyBkZSBsb3MgbcOhcyBiYWpvcy4gDQoNCg0KDQpgYGB7ciBmdW5jaW9uMX0NCiMgQ2FsY3VsYXIgbGEgbWVkaWFuYSBzYWxhcmlhbCANCmZ1bmNpb25fcmggPC0gcmgyMmxhICU+JSANCiAgZmlsdGVyKHB1ZXN0byAhPSAiUGFzYW50ZSIsDQogICAgICAgICBiZXR3ZWVuKHN1ZWxkb19kb2xhciwgcG9kYV9wMDUsIHBvZGFfcDk1KSkgJT4lIA0KICBncm91cF9ieShmdW5jaW9uKSAlPiUgDQogIHN1bW1hcmlzZShtZWRpYW5hID0gbWVkaWFuKHN1ZWxkb19kb2xhciksDQogICAgICAgICAgICBjYW50ID0gbigpKSAlPiUgDQogIGFycmFuZ2UoLW1lZGlhbmEpDQoNCm1pbl9mdW5jaW9uIDwtIHJvdW5kKG1pbihmdW5jaW9uX3JoJG1lZGlhbmEpKQ0KbWF4X2Z1bmNpb24gPC0gcm91bmQobWF4KGZ1bmNpb25fcmgkbWVkaWFuYSkpDQoNCiMgR3LDoWZpY28NCmdncGxvdChmdW5jaW9uX3JoLCBhZXMoeCA9IG1lZGlhbmEsIHkgPSByZW9yZGVyKGZ1bmNpb24sIG1lZGlhbmEpKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gYXp1bCwgc2l6ZSA9IDMpICsNCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMCwgeGVuZCA9IG1lZGlhbmEsIA0KICAgICAgICAgICAgICAgICAgIHkgPSBmdW5jaW9uLCB5ZW5kID0gZnVuY2lvbiksDQogICAgICAgICAgICAgICBjb2xvciA9IGF6dWwpICsNCiAgbGFicyh0aXRsZSA9ICJNZWRpYW5hIFNhbGFyaWFsIHBvciBGdW5jacOzbiBlbiBMQVRBTSIsDQogICAgICAgc3VidGl0bGUgPSAiU3VlbGRvcyBkZSBSUkhIIGVuIFUkUyIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGNvbW1hKG1lZGlhbmEsIGFjY3VyYWN5ID0gMSxwcmVmaXggPSAiVVNTICIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNpbWFsLm1hcmsgPSAiLCIsIGJpZy5tYXJrID0gIi4iKSksDQogICAgICAgICAgICAgICAgY29sb3IgPSBhenVsLA0KICAgICAgICAgICAgICAgIGhqdXN0ID0gLS4yLA0KICAgICAgICAgICAgZm9udGZhY2UgPSAiYm9sZCIsDQogICAgICAgICAgICBzaXplID0gMykgKw0KICBlc3RpbG92ICsNCiAgZWplX3hfbiArDQogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDMwMDApKSANCg0KYGBgDQoNCk51ZXZhbWVudGUgZXMgbmVjZXNhcmlvIGFjbGFyYXIgcXVlIGhheSBmdW5jaW9uZXMgZG9uZGUgbm8gdGVuZW1vcyBtdWNoYSBjYW50aWRhZCBkZSByZXNwdWVzdGFzIGNvbW8gKipDb21wbGlhbmNlKiogZG9uZGUgc8OzbG8gdGVuZW1vcyB1biBzb2xvIGNhc28sIHBlcm8gbGEgZGlmZXJlbmNpYSBlbnRyZSBsYXMgZnVuY2lvbmVzIGNvbiBtYXlvcmVzIHN1ZWxkb3MsIHkgY29uIGxvcyBtZW5vcmVzIHN1ZWxkb3MgZXMgbXV5IGFtcGxpYSAoVSREIGByIG1heF9mdW5jaW9uIC0gbWluX2Z1bmNpb25gKS4NCg0KYGBge3J9DQpndChyaDIybGEgJT4lIA0KICAgICBmaWx0ZXIocHVlc3RvICE9ICJQYXNhbnRlIiwNCiAgICAgICAgICAgIGJldHdlZW4oc3VlbGRvX2RvbGFyLCBwb2RhX3AwNSwgcG9kYV9wOTUpKSAlPiUgDQogICAgIHNlbGVjdChmdW5jaW9uLCBzdWVsZG9fZG9sYXIpICU+JSANCiAgICAgZ3JvdXBfYnkoZnVuY2lvbikgJT4lIA0KICAgICBzdW1tYXJpc2UobWluaW1vID0gbWluKHN1ZWxkb19kb2xhciksDQogICAgICAgICAgICAgICBtZWRpYW5hX3NhbGFyaWFsID0gbWVkaWFuKHN1ZWxkb19kb2xhciksDQogICAgICAgICAgICAgICBtYXhpbW8gPSBtYXgoc3VlbGRvX2RvbGFyKSwNCiAgICAgICAgICAgICAgIGNhbnQgPSBuKCkpDQogICAgICkgJT4lIA0KICB0YWJfaGVhZGVyKHRpdGxlID0gIk1lZGlhbmEgc2FsYXJpYWwgcG9yIEZ1bmNpw7NuIiwgDQogICAgICAgICAgICAgc3VidGl0bGUgPSAiU3VlbGRvcyBlbiBVJEQiKSAlPiUgDQogIHRhYl9zb3VyY2Vfbm90ZShzb3VyY2Vfbm90ZSA9IGZ1ZW50ZSkgJT4lIA0KICAgZm10X2N1cnJlbmN5KGNvbHVtbnMgPSAgYygibWVkaWFuYV9zYWxhcmlhbCIsICJtaW5pbW8iLCAibWF4aW1vIiksIGRlY2ltYWxzID0gMCwNCiAgICAgICAgICAgICAgIHNlcF9tYXJrID0gIi4iLCBkZWNfbWFyayA9ICIsIikgJT4lIA0KICBjb2xzX2xhYmVsKGZ1bmNpb24gPSAiRnVuY2nDs24iLA0KICAgICAgICAgICAgIG1pbmltbyA9ICJNw61uaW1vIiwNCiAgICAgICAgICAgICBtZWRpYW5hX3NhbGFyaWFsID0gIk1lZGlhbmEiLA0KICAgICAgICAgICAgIG1heGltbyA9ICJNw6F4aW1vIiwNCiAgICAgICAgICAgICBjYW50ID0gIlJlc3B1ZXN0YXMiKSANCmBgYA0KDQoNCiMjIFN1ZWxkb3Mgc2Vnw7puIGVsIG9yaWdlbiBkZWwgY2FwaXRhbA0KDQpTaSBkaXZpZGltb3MgbG9zIGdyw6FmaWNvcyBzZWfDum4gZWwgKk9yaWdlbiBkZWwgQ2FwaXRhbCosIHBvZGVtb3MgYXByZWNpYXIgcXVlIGVuIGzDrW5lYXMgZ2VuZXJhbGVzLCBsYSBtZWRpYW5hIHNhbGFyaWFsIGVuIGVtcHJlc2FzIG11bHRpbmFjaW9uZXMgZXMgbWF5b3IgcXVlIGVuIGxhcyBlbXByZXNhcyBuYWNpb25hbGVzLiBTb2xhbWVudGUgZW4gbGFzIHBvc2ljaW9uZXMgZGUgKipIUkJQKiogeSBkZSAqKkdlcmVudGUqKiBzZSBhcHJlY2lhIHVuYSBwYXJpZGFkIHNhbGFyaWFsIHJlc3BlY3RvIGRlbCBvcmlnZW4gZGVsIGNhcGl0YWwgZGUgbGEgb3JnYW5pemFjacOzbi4NCg0KYGBge3Igb3JpZ2VuX2NhcGl0YWx9DQpyaDIybGEgJT4lIA0KICBzZWxlY3Qob3JpZ2VuX2NhcGl0YWwsIHB1ZXN0bywgc3VlbGRvX2RvbGFyKSAlPiUgDQogIGZpbHRlcihwdWVzdG8gIT0gIlBhc2FudGUiLCANCiAgICAgICAgIGJldHdlZW4oc3VlbGRvX2RvbGFyLCBwb2RhX3AwNSwgcG9kYV9wOTUpKSAlPiUgDQogIGdyb3VwX2J5KHB1ZXN0bywgb3JpZ2VuX2NhcGl0YWwpICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbmFfc2FsYXJpYWwgPSBtZWRpYW4oc3VlbGRvX2RvbGFyKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtZWRpYW5hX3NhbGFyaWFsLCB5ID0gZmN0X3JldihwdWVzdG8pLCBmaWxsID0gb3JpZ2VuX2NhcGl0YWwpKSArDQogIGdlb21fY29sKCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQoeD1tZWRpYW5hX3NhbGFyaWFsLCAwKSwgaGp1c3QgPSAxLjIsIGZvbnRmYWNlID0gImJvbGQiKSxzaXplID0gMywgY29sb3IgPSAid2hpdGUiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGModmVyZGUsIGF6dWwpKSArDQogIGVzdGlsb3YgKw0KICBlamVfeF9uICsNCiAgZmFjZXRfd3JhcCh+b3JpZ2VuX2NhcGl0YWwpICsNCiAgbGFicyh0aXRsZSA9ICJNZWRpYW5hIHNhbGFyaWFsIHBvciBwdWVzdG8gc2Vnw7puIG9yaWdlbiBkZWwgY2FwaXRhbCIsIA0KICAgICAgIHN1YnRpdGxlID0gIlN1ZWxkb3MgZGUgUlJISCBlbiBVJFMiLCANCiAgICAgICB4ID0gIiIsIHkgPSAiIiwgZmlsbCA9ICIiLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKQ0KYGBgDQoNClZlYW1vcyBlc3RlIGdyw6FmaWNvIGRlIG90cmEgbWFuZXJhOg0KDQpgYGB7ciBvcmlnZW5fY2FwaXRhbF9zbG9wZX0NCg0Kc2xvcGVfZGYgPC0gcmgyMmxhICU+JSANCiAgc2VsZWN0KHB1ZXN0bywgc3VlbGRvX2RvbGFyLCBvcmlnZW5fY2FwaXRhbCkgJT4lIA0KICBmaWx0ZXIoYmV0d2VlbihzdWVsZG9fZG9sYXIsIHBvZGFfcDA1LCBwb2RhX3A5NSksDQogICAgICAgICBwdWVzdG8gIT0gIlBhc2FudGUiKSAlPiUgDQogIGdyb3VwX2J5KHB1ZXN0bywgb3JpZ2VuX2NhcGl0YWwpICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbmFfc2FsYXJpYWwgPSByb3VuZChtZWRpYW4oc3VlbGRvX2RvbGFyKSkpDQoNCkNHUGZ1bmN0aW9uczo6bmV3Z2dzbG9wZWdyYXBoKGRhdGFmcmFtZSA9IHNsb3BlX2RmLA0KICAgICAgICAgICAgICAgIFRpbWVzID0gb3JpZ2VuX2NhcGl0YWwsDQogICAgICAgICAgICAgICAgTWVhc3VyZW1lbnQgPSBtZWRpYW5hX3NhbGFyaWFsLA0KICAgICAgICAgICAgICAgIEdyb3VwaW5nID0gcHVlc3RvLA0KICAgICAgICAgICAgICAgIFRpdGxlID0gIkRpZmVyZW5jaWFzIGVudHJlIHN1ZWxkb3MgZGUgUlJISCBlbiBlbXByZXNhcyBuYWNpb25hbGVzIHkgbXVsdGluYWNpb25hbGVzIiwNCiAgICAgICAgICAgICAgICBTdWJUaXRsZSA9ICJNZWRpYW5hIFNhbGFyaWFsLiBTdWVsZG9zIGVuIFUkUyIsDQogICAgICAgICAgICAgICAgQ2FwdGlvbiA9IGZ1ZW50ZSwgV2lkZXJMYWJlbHMgPSBUDQogICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgKQ0KYGBgDQoNCiMjIEFuw6FsaXNpcyBwb3IgcnVicm8geSBvcmlnZW4gZGVsIGNhcGl0YWwNCg0KUGFyYSBlbCBhbsOhbGlzaXMgZGUgbG9zIHJ1YnJvcyBkZSBsYSBlbXByZXNhLCB2YW1vcyBhIGZpbHRyYXIgbG9zIDUgcnVicm9zIHF1ZSB0aWVuZW4gbcOhcyByZXNwdWVzdGFzLiBUYW1iacOpbiBlbGltaW5hcmVtb3MgZGVsIGFuw6FsaXNpcyBlbCBwdWVzdG8gZGUgRGlyZWN0b3IgcG9ycXVlIG5vIHNlIGVuY3VlbnRyYSBwcmVzZW50ZSBlbiB0b2RvcyBsb3MgcnVicm9zLg0KDQpgYGB7ciBydWJyb3MsIGZpZy5oZWlnaHQ9MTV9DQp0b3BfNV9ydWJyb3MgPC0gcmgyMmxhICU+JSANCiAgc2VsZWN0KHJ1YnJvKSAlPiUgDQogIGdyb3VwX2J5KHJ1YnJvKSAlPiUgDQogIGNvdW50KHNvcnQgPSBUUlVFKSAlPiUNCiAgZmlsdGVyKHJ1YnJvICE9ICJPdHJvcyIsIG4gPiAzMCkgJT4lIA0KICBwdWxsKHZhciA9IHJ1YnJvKQ0KDQoNCnJoMjJsYSAlPiUgDQogIHNlbGVjdChydWJybywgb3JpZ2VuX2NhcGl0YWwsIHB1ZXN0bywgc3VlbGRvX2RvbGFyKSAlPiUgDQogIGZpbHRlcihwdWVzdG8gIT0gIlBhc2FudGUiLCBwdWVzdG8gIT0gIkRpcmVjdG9yIiwNCiAgICAgICAgIGJldHdlZW4oc3VlbGRvX2RvbGFyLCBwb2RhX3AwNSwgcG9kYV9wOTUpLA0KICAgICAgICAgcnVicm8gJWluJSB0b3BfNV9ydWJyb3MpICU+JSANCiAgZ3JvdXBfYnkocnVicm8sIHB1ZXN0bywgb3JpZ2VuX2NhcGl0YWwpICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbmFfc2FsYXJpYWwgPSBtZWRpYW4oc3VlbGRvX2RvbGFyKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtZWRpYW5hX3NhbGFyaWFsLCB5ID0gZmN0X3JldihwdWVzdG8pLCANCiAgICAgICAgICAgICBmaWxsID0gb3JpZ2VuX2NhcGl0YWwpKSArDQogIGdlb21fY29sKCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQoeD1tZWRpYW5hX3NhbGFyaWFsLCAwKSwgDQogICAgICAgICAgICAgICAgaGp1c3QgPSAxLjIsIA0KICAgICAgICAgICAgICAgIGZvbnRmYWNlID0gImJvbGQiKSwNCiAgICAgICAgICAgIHNpemUgPSAzLCANCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKHZlcmRlLCBhenVsKSkgKw0KICBlc3RpbG8gKw0KICBlamVfeF9uICsNCiAgZmFjZXRfZ3JpZChydWJyb35vcmlnZW5fY2FwaXRhbCkgKw0KICBsYWJzKHRpdGxlID0gIk1lZGlhbmEgc2FsYXJpYWwgcG9yIHB1ZXN0byBzZWfDum4gb3JpZ2VuIGRlbCBjYXBpdGFsIiwgDQogICAgICAgc3VidGl0bGUgPSAiU3VlbGRvcyBkZSBSUkhIIGVuIFUkUyIsIA0KICAgICAgIHggPSAiIiwgeSA9ICIiLCBmaWxsID0gIiIsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQpgYGANCg0KUGFyYSB2ZXIgbGFzIG1lZGlhbmFzIHNhbGFyaWFsZXMgcG9yIHJ1YnJvcyBqdW50byBjb24gZWwgZGVzdsOtbyBlc3TDoW5kYXIsIHB1ZWRlbiB2ZXIgbGEgc2lndWllbnRlIHRhYmxhOg0KDQpgYGB7ciBydWJyb3MyfQ0KcmgyMmxhICU+JSANCiAgICBzZWxlY3QocnVicm8sIHN1ZWxkb19kb2xhcikgJT4lIA0KICAgIGZpbHRlcihiZXR3ZWVuKHN1ZWxkb19kb2xhciwgcG9kYV9wMDUsIHBvZGFfcDk1KSkgJT4lIA0KICAgIGdyb3VwX2J5KHJ1YnJvKSAlPiUgDQogICAgc3VtbWFyaXNlKG1lZGlhbmFfc2FsYXJpYWwgPSByb3VuZChtZWRpYW4oc3VlbGRvX2RvbGFyKSksDQogICAgICAgICAgICAgIGRlc3Zpb19zYWxhcmlhbCA9IHJvdW5kKHNkKHN1ZWxkb19kb2xhcikpLA0KICAgICAgICAgICAgICBSZXNwdWVzdGFzID0gbigpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogICAgYXJyYW5nZSgtbWVkaWFuYV9zYWxhcmlhbCkgJT4lIA0KICBrYmwoY2FwdGlvbiA9ICJNZWRpYW5hIHNhbGFyaWFsIHBvciBydWJyby4gRW4gVSRTIiwgDQogICAgICBjb2wubmFtZXMgPSBjKCJSdWJybyIsICJNZWRpYW5hIFNhbGFyaWFsIiwiRGVzdsOtbyIsICJSZXNwdWVzdGFzIikpICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRiwgcG9zaXRpb24gPSAiY2VudGVyIiwNCiAgICAgICAgICAgICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIikpICU+JSANCiAgc2Nyb2xsX2JveChoZWlnaHQgPSAiNTAwcHgiKQ0KDQpgYGANCg0KDQojIEFuw6FsaXNpcyBwb3IgcGHDrXNlcw0KDQpFbiBlc3RhIHNlY2Npw7NuIGFuYWxpemFyZW1vcyBsYSBzaXR1YWNpw7NuIHNhbGFyaWFsIGRlIFJSSEggw7puaWNhbWVudGUgZGUgY3VhdHJvIHBhw61zZXM6ICpBcmdlbnRpbmEsIFBhcmFndWF5LCBNw6l4aWNvIHkgUGVyw7oqIMO6bmljYW1lbnRlLCBwb3IgbGEgY2FudGlkYWQgZGUgcmVzcHVlc3Rhcy4gRGVsIHJlc3RvIGRlIGxvcyBwYcOtc2VzIHRlbmVtb3MgbWVub3MgZGUgOCByZXNwdWVzdGFzLCBwb3IgbG8gcXVlIGVzIGltcG9zaWJsZSByZWFsaXphciB1biBhbsOhbGlzaXMgc2VyaW8uDQoNCiMjIFBhcmFndWF5DQoNCiMjIyBBbsOhbGlzaXMgcG9yIHB1ZXN0bw0KDQpgYGB7ciBwYXJhZ3VheTF9DQojIFByZXByb2Nlc28gLS0tLS0NCg0KIyBGaWx0cmFyIGxvcyBzdWVsZG9zIGV4dHJlbW9zDQpyaDIybGFfY2xlYW4gPC0gcmgyMmxhICU+JSANCiAgZmlsdGVyKHB1ZXN0byAhPSAiUGFzYW50ZSIsDQogICAgICAgICBiZXR3ZWVuKHN1ZWxkb19kb2xhciwgcG9kYV9wMDUsIHBvZGFfcDk1KSkgJT4lIA0KICBtdXRhdGUocnVicm8gPSBzdHJfd3JhcChydWJybywgd2lkdGggPSAzMCkpDQoNCiMgTGltcGlhciBkYXRvcyAyMDIwDQpkZjIwMjAgPC0gIHByb2ZpbGluZ19udW0oa2l3aTIwJHN1ZWxkb19kb2xhcikNCnAwNV8yMCA8LSBkZjIwMjBbMSw2XQ0KcDk1XzIwIDwtIGRmMjAyMFsxLDEwXQ0KDQpyaDIwIDwtIGtpd2kyMCAlPiUgZmlsdGVyKGJldHdlZW4oc3VlbGRvX2RvbGFyLCBwMDVfMjAsIHA5NV8yMCkpICU+JSANCiAgbXV0YXRlKGFuaW8gPSAyMDIwKSAlPiUgDQogIHNlbGVjdChhbmlvLCBwYWlzLCBwdWVzdG8sIGZ1bmNpb24gPSBmdW5jaW9uX3JoLCBzdWVsZG9fYnJ1dG8pIA0KDQoNCiMgTGltcGlhciBkYXRvcyAyMDIxDQpkZjIwMjEgPC0gcHJvZmlsaW5nX251bShraXdpMjEkc3VlbGRvX2RvbGFyKQ0KcDA1XzIxIDwtIGRmMjAyMVsxLDZdDQpwOTVfMjEgPC0gZGYyMDIxWzEsMTBdDQoNCnJoMjEgPC0ga2l3aTIxICU+JSBmaWx0ZXIoYmV0d2VlbihzdWVsZG9fZG9sYXIsIHAwNV8yMCwgcDk1XzIwKSkgJT4lIA0KICBtdXRhdGUoYW5pbyA9IDIwMjEpICU+JSANCiAgc2VsZWN0KGFuaW8sIHBhaXMsIHB1ZXN0bywgZnVuY2lvbiwgc3VlbGRvX2JydXRvKSANCg0KDQoNCiMgRmlsdHJhciBwb3IgUGFyYWFndWF5IC0tLS0NCnJoX3B5IDwtIHJoMjJsYV9jbGVhbiAlPiUgDQogIGZpbHRlcihwYWlzID09ICJQYXJhZ3VheSIpICU+JSANCiAgbXV0YXRlKGFuaW8gPSAyMDIyKQ0KDQpyaDIwcHkgPC0gcmgyMCAlPiUgDQogIGZpbHRlcihwYWlzID09ICJQYXJhZ3VheSIpDQoNCnJoMjFweSA8LSByaDIxICU+JSANCiAgZmlsdGVyKHBhaXMgPT0gIlBhcmFndWF5IikNCg0KcmgyMnB5IDwtIHJoX3B5ICU+JSANCiAgICBzZWxlY3QoYW5pbywgcGFpcywgcHVlc3RvLCBmdW5jaW9uLCBzdWVsZG9fYnJ1dG8pIA0KDQojIFBhcmEgYW5hbGl6YXIgZXZvbHVjacOzbiBkZSBzYWxhcmlvcw0KIyBFdm9sdWNpb24NCmhpc3RvcmljbyA8LSByYmluZChyaDIwcHksIHJoMjFweSwgcmgyMnB5KQ0KDQojIFNhbGFyaW8gcG9yIHB1ZXN0byANCg0KcmhfcHkgJT4lIA0KICBncm91cF9ieShwdWVzdG8pICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbmEgPSBtZWRpYW4oc3VlbGRvX2JydXRvKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZjdF9yZXYocHVlc3RvKSwgeSA9IG1lZGlhbmEpKSArDQogIGdlb21fY29sKGZpbGwgPSAiIzAwMzhhOCIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGNvbW1hKG1lZGlhbmEsIGJpZy5tYXJrID0gIi4iLCBkZWNpbWFsLm1hcmsgPSAiLCIpKSwNCiAgICAgICAgICAgIHZqdXN0ID0gMS4yLA0KICAgICAgICAgICAgc2l6ZSA9IDMsIA0KICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiKSArDQogIGVqZV95X24gKw0KICBlc3RpbG9oICsNCiAgbGFicyh0aXRsZSA9ICJNZWRpYW5hIFNhbGFyaWFsIHBvciBQdWVzdG8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIFBhcmFndWF5IC0gRW4gR3MuIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCiAgDQpgYGANCg0KIyMjIEFuw6FsaXNpcyBwb3IgZnVuY2nDs24NCg0KYGBge3IgcGFyYWd1YXkyfQ0KcmhfcHkgJT4lIA0KICBncm91cF9ieShmdW5jaW9uKSAlPiUgDQogIHN1bW1hcmlzZShtZWRpYW5hID0gbWVkaWFuKHN1ZWxkb19icnV0bykpICU+JQ0KICB1bmdyb3VwKCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHkgPSByZW9yZGVyKGZ1bmNpb24sIG1lZGlhbmEpLCB4ID0gbWVkaWFuYSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICIjMDAzOGE4IikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEobWVkaWFuYSwgYmlnLm1hcmsgPSAiLiIsIGRlY2ltYWwubWFyayA9ICIsIikpLA0KICAgICAgICAgICAgaGp1c3QgPSAxLjIsDQogICAgICAgICAgICBzaXplID0gMywgDQogICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgZWplX3hfbiArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIk1lZGlhbmEgU2FsYXJpYWwgcG9yIFB1ZXN0byIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgUGFyYWd1YXkgLSBFbiBHcy4iLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KYGBgDQoNCiMjIyBBbsOhbGlzaXMgcG9yIHJ1YnJvDQoNCmBgYHtyIHBhcmFndWF5M30NCnJoX3B5ICU+JSANCiAgZ3JvdXBfYnkocnVicm8pICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbmEgPSBtZWRpYW4oc3VlbGRvX2JydXRvKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdncGxvdChhZXMoeSA9IHJlb3JkZXIocnVicm8sIG1lZGlhbmEpLCB4ID0gbWVkaWFuYSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICIjMDAzOGE4IikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEobWVkaWFuYSwgYmlnLm1hcmsgPSAiLiIsIGRlY2ltYWwubWFyayA9ICIsIikpLA0KICAgICAgICAgICAgaGp1c3QgPSAxLjIsDQogICAgICAgICAgICBzaXplID0gMywgDQogICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgZWplX3hfbiArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIk1lZGlhbmEgU2FsYXJpYWwgcG9yIFB1ZXN0byIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgUGFyYWd1YXkgLSBFbiBHcy4iLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KYGBgDQoNCiMjIyBFdm9sdWNpw7NuDQoNCkxhIGV2b2x1Y2nDs24gZGUgbG9zIHNhbGFyaW9zIGVuIG1vbmVkYSBsb2NhbCBwdWVkZSBzZXIgY29udHJhaW50dWl0aXZhIGRhZGEgbGEgYmFqYSBjYW50aWRhZCBkZSByZXNwdWVzdGFzIG9idGVuaWRhcyBwb3IgYcOxby4NCg0KYGBge3IgcGFyYWd1YXk0fQ0KaGlzdG9yaWNvICU+JSANCiAgZ3JvdXBfYnkoYW5pbykgJT4lIA0KICBzdW1tYXJpc2UobWVkaWFuYSA9IG1lZGlhbihzdWVsZG9fYnJ1dG8pKSAlPiUgDQogIHVuZ3JvdXAgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBhbmlvLCB5ID0gbWVkaWFuYSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICIjMDAzOGE4IikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEobWVkaWFuYSwgYmlnLm1hcmsgPSAiLiIsIGRlY2ltYWwubWFyayA9ICIsIikpLA0KICAgICAgICAgICAgdmp1c3QgPSAxLjIsIGNvbG9yID0gIndoaXRlIikgKw0KICBlamVfeV9uICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiTWVkaWFuYSBTYWxhcmlhbCBwb3IgQcOxbyIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgUGFyYWd1YXkgLSBFbiBHcy4iLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KDQpgYGANCg0KDQojIyBNw6l4aWNvDQoNCiMjIyBBbsOhbGlzaXMgcG9yIHB1ZXN0bw0KDQpgYGB7ciBtZXgxfQ0KIyBGaWx0cmFyIHBvciBNw6l4aWNvIC0tLS0NCnJoX214IDwtIHJoMjJsYV9jbGVhbiAlPiUgDQogIGZpbHRlcihwYWlzID09ICJNw6l4aWNvIikgJT4lIA0KICBtdXRhdGUoYW5pbyA9IDIwMjIpDQoNCg0KcmhfbXggPC0gcmgyMmxhICU+JSANCiAgZmlsdGVyKHBhaXMgPT0gIk3DqXhpY28iKSAlPiUgDQogIG11dGF0ZShhbmlvID0gMjAyMikNCg0KcmgyMG14IDwtIHJoMjAgJT4lIA0KICBmaWx0ZXIocGFpcyA9PSAiTcOpeGljbyIpDQoNCnJoMjFteCA8LSByaDIxICU+JSANCiAgZmlsdGVyKHBhaXMgPT0gIk3DqXhpY28iKQ0KDQpyaDIybXggPC0gcmhfbXggJT4lIA0KICAgIHNlbGVjdChhbmlvLCBwYWlzLCBwdWVzdG8sIGZ1bmNpb24sIHN1ZWxkb19icnV0bykgDQoNCiMgUGFyYSBhbmFsaXphciBldm9sdWNpw7NuIGRlIHNhbGFyaW9zDQojIEV2b2x1Y2lvbg0KaGlzdG9yaWNvIDwtIHJiaW5kKHJoMjBteCwgcmgyMW14LCByaDIybXgpDQoNCiMgU2FsYXJpbyBwb3IgcHVlc3RvIA0KDQpyaF9teCAlPiUgDQogIGdyb3VwX2J5KHB1ZXN0bykgJT4lIA0KICBzdW1tYXJpc2UobWVkaWFuYSA9IG1lZGlhbihzdWVsZG9fYnJ1dG8pKSAlPiUNCiAgdW5ncm91cCgpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmN0X3JldihwdWVzdG8pLCB5ID0gbWVkaWFuYSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICIjMDA2ODQ3IikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEobWVkaWFuYSwgYmlnLm1hcmsgPSAiLiIsIGRlY2ltYWwubWFyayA9ICIsIikpLA0KICAgICAgICAgICAgdmp1c3QgPSAxLjIsDQogICAgICAgICAgICBzaXplID0gMywgDQogICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgZWplX3lfbiArDQogIGVzdGlsb2ggKw0KICBsYWJzKHRpdGxlID0gIk1lZGlhbmEgU2FsYXJpYWwgcG9yIFB1ZXN0byIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgTcOpeGljbyAtIEVuIE1YJCIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQogIA0KYGBgDQoNCiMjIyBBbsOhbGlzaXMgcG9yIGZ1bmNpw7NuDQoNCmBgYHtyIG1leDJ9DQpyaF9teCAlPiUgDQogIGdyb3VwX2J5KGZ1bmNpb24pICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbmEgPSBtZWRpYW4oc3VlbGRvX2JydXRvKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdncGxvdChhZXMoeSA9IHJlb3JkZXIoZnVuY2lvbiwgbWVkaWFuYSksIHggPSBtZWRpYW5hKSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiMwMDY4NDciKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShtZWRpYW5hLCBiaWcubWFyayA9ICIuIiwgZGVjaW1hbC5tYXJrID0gIiwiKSksDQogICAgICAgICAgICBoanVzdCA9IDEuMiwNCiAgICAgICAgICAgIHNpemUgPSAzLCANCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIikgKw0KICBlamVfeF9uICsNCiAgZXN0aWxvdiArDQogIGxhYnModGl0bGUgPSAiTWVkaWFuYSBTYWxhcmlhbCBwb3IgUHVlc3RvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEYXRvcyBkZSBNw6l4aWNvIC0gRW4gTVgkIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCmBgYA0KDQojIyMgQW7DoWxpc2lzIHBvciBydWJybw0KDQpgYGB7ciBtZXgzfQ0KcmhfbXggJT4lIA0KICBncm91cF9ieShydWJybykgJT4lIA0KICBzdW1tYXJpc2UobWVkaWFuYSA9IG1lZGlhbihzdWVsZG9fYnJ1dG8pKSAlPiUNCiAgdW5ncm91cCgpICU+JSANCiAgZ2dwbG90KGFlcyh5ID0gcmVvcmRlcihydWJybywgbWVkaWFuYSksIHggPSBtZWRpYW5hKSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiMwMDY4NDciKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShtZWRpYW5hLCBiaWcubWFyayA9ICIuIiwgZGVjaW1hbC5tYXJrID0gIiwiKSksDQogICAgICAgICAgICBoanVzdCA9IDEuMiwNCiAgICAgICAgICAgIHNpemUgPSAzLCANCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIikgKw0KICBlamVfeF9uICsNCiAgZXN0aWxvdiArDQogIGxhYnModGl0bGUgPSAiTWVkaWFuYSBTYWxhcmlhbCBwb3IgUHVlc3RvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEYXRvcyBkZSBNw6l4aWNvIC0gRW4gTVgkIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCmBgYA0KDQojIyMgRXZvbHVjacOzbg0KDQpMYSBldm9sdWNpw7NuIGRlIGxvcyBzYWxhcmlvcyBlbiBtb25lZGEgbG9jYWwgcHVlZGUgc2VyIGNvbnRyYWludHVpdGl2YSBkYWRhIGxhIGJhamEgY2FudGlkYWQgZGUgcmVzcHVlc3RhcyBvYnRlbmlkYXMgcG9yIGHDsW8uDQoNCmBgYHtyIG1leDR9DQpoaXN0b3JpY28gJT4lIA0KICBncm91cF9ieShhbmlvKSAlPiUgDQogIHN1bW1hcmlzZShtZWRpYW5hID0gbWVkaWFuKHN1ZWxkb19icnV0bykpICU+JSANCiAgdW5ncm91cCAlPiUgDQogIGdncGxvdChhZXMoeCA9IGFuaW8sIHkgPSBtZWRpYW5hKSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiMwMDY4NDciKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShtZWRpYW5hLCBiaWcubWFyayA9ICIuIiwgZGVjaW1hbC5tYXJrID0gIiwiKSksDQogICAgICAgICAgICB2anVzdCA9IDEuMiwgDQogICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgZWplX3lfbiArDQogIGVzdGlsb2ggKw0KICBsYWJzKHRpdGxlID0gIk1lZGlhbmEgU2FsYXJpYWwgcG9yIEHDsW8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIE3DqXhpY28gLSBFbiBNWCQiLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KDQpgYGANCg0KDQojIyBQZXLDug0KDQojIyMgQW7DoWxpc2lzIHBvciBwdWVzdG8NCg0KYGBge3IgcGVydTF9DQojIEZpbHRyYXIgcG9yIE3DqXhpY28gLS0tLQ0KcmhfcGUgPC0gcmgyMmxhX2NsZWFuICU+JSANCiAgZmlsdGVyKHBhaXMgPT0gIlBlcsO6IikgJT4lIA0KICBtdXRhdGUoYW5pbyA9IDIwMjIpDQoNCg0KcmgyMHBlIDwtIHJoMjAgJT4lIA0KICBmaWx0ZXIocGFpcyA9PSAiUGVyw7oiKQ0KDQpyaDIxcGUgPC0gcmgyMSAlPiUgDQogIGZpbHRlcihwYWlzID09ICJQZXLDuiIpDQoNCnJoMjJwZSA8LSByaF9wZSAlPiUgDQogICAgc2VsZWN0KGFuaW8sIHBhaXMsIHB1ZXN0bywgZnVuY2lvbiwgc3VlbGRvX2JydXRvKSANCg0KIyBQYXJhIGFuYWxpemFyIGV2b2x1Y2nDs24gZGUgc2FsYXJpb3MNCiMgRXZvbHVjaW9uDQpoaXN0b3JpY28gPC0gcmJpbmQocmgyMHBlLCByaDIxcGUsIHJoMjJwZSkNCg0KIyBTYWxhcmlvIHBvciBwdWVzdG8gDQoNCnJoX3BlICU+JSANCiAgZ3JvdXBfYnkocHVlc3RvKSAlPiUgDQogIHN1bW1hcmlzZShtZWRpYW5hID0gbWVkaWFuKHN1ZWxkb19icnV0bykpICU+JQ0KICB1bmdyb3VwKCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBmY3RfcmV2KHB1ZXN0byksIHkgPSBtZWRpYW5hKSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiNEOTEwMjMiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShtZWRpYW5hLCBiaWcubWFyayA9ICIuIiwgZGVjaW1hbC5tYXJrID0gIiwiKSksDQogICAgICAgICAgICB2anVzdCA9IDEuMiwNCiAgICAgICAgICAgIHNpemUgPSAzLCANCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIikgKw0KICBlamVfeV9uICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiTWVkaWFuYSBTYWxhcmlhbCBwb3IgUHVlc3RvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEYXRvcyBkZSBQZXLDuiAtIEVuIFMvIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCiAgDQpgYGANCg0KIyMjIEFuw6FsaXNpcyBwb3IgZnVuY2nDs24NCg0KYGBge3IgcGVydTJ9DQpyaF9wZSAlPiUgDQogIGdyb3VwX2J5KGZ1bmNpb24pICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbmEgPSBtZWRpYW4oc3VlbGRvX2JydXRvKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdncGxvdChhZXMoeSA9IHJlb3JkZXIoZnVuY2lvbiwgbWVkaWFuYSksIHggPSBtZWRpYW5hKSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiNEOTEwMjMiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShtZWRpYW5hLCBiaWcubWFyayA9ICIuIiwgZGVjaW1hbC5tYXJrID0gIiwiKSksDQogICAgICAgICAgICBoanVzdCA9IDEuMiwNCiAgICAgICAgICAgIHNpemUgPSAzLCANCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIikgKw0KICBlamVfeF9uICsNCiAgZXN0aWxvdiArDQogIGxhYnModGl0bGUgPSAiTWVkaWFuYSBTYWxhcmlhbCBwb3IgUHVlc3RvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEYXRvcyBkZSBQZXLDuiAtIEVuIFMvIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCmBgYA0KDQojIyMgQW7DoWxpc2lzIHBvciBydWJybw0KDQpgYGB7ciBwZXJ1M30NCnJoX3BlICU+JSANCiAgZ3JvdXBfYnkocnVicm8pICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbmEgPSBtZWRpYW4oc3VlbGRvX2JydXRvKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdncGxvdChhZXMoeSA9IHJlb3JkZXIocnVicm8sIG1lZGlhbmEpLCB4ID0gbWVkaWFuYSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICIjRDkxMDIzIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEobWVkaWFuYSwgYmlnLm1hcmsgPSAiLiIsIGRlY2ltYWwubWFyayA9ICIsIikpLA0KICAgICAgICAgICAgaGp1c3QgPSAxLjIsDQogICAgICAgICAgICBzaXplID0gMywgDQogICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgZWplX3hfbiArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIk1lZGlhbmEgU2FsYXJpYWwgcG9yIFB1ZXN0byIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgUGVyw7ogLSBFbiBTLyIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQpgYGANCg0KIyMjIEV2b2x1Y2nDs24NCg0KTGEgZXZvbHVjacOzbiBkZSBsb3Mgc2FsYXJpb3MgZW4gbW9uZWRhIGxvY2FsIHB1ZWRlIHNlciBjb250cmFpbnR1aXRpdmEgZGFkYSBsYSBiYWphIGNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgb2J0ZW5pZGFzIHBvciBhw7FvLg0KDQpgYGB7ciBwZXJ1NH0NCmhpc3RvcmljbyAlPiUgDQogIGdyb3VwX2J5KGFuaW8pICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbmEgPSBtZWRpYW4oc3VlbGRvX2JydXRvKSkgJT4lIA0KICB1bmdyb3VwICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gYW5pbywgeSA9IG1lZGlhbmEpKSArDQogIGdlb21fY29sKGZpbGwgPSAiI0Q5MTAyMyIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGNvbW1hKG1lZGlhbmEsIGJpZy5tYXJrID0gIi4iLCBkZWNpbWFsLm1hcmsgPSAiLCIpKSwNCiAgICAgICAgICAgIHZqdXN0ID0gMS4yLCANCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIikgKw0KICBlamVfeV9uICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiTWVkaWFuYSBTYWxhcmlhbCBwb3IgQcOxbyIsDQogICAgICAgc3VidGl0bGUgPSAiRGF0b3MgZGUgUGVyw7ogLSBFbiBTLyIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQoNCmBgYA0KDQojIyBBcmdlbnRpbmENCg0KDQojIyMgQW7DoWxpc2lzIHBvciBwdWVzdG8NCg0KYGBge3IgYXJnZW50aW5hfQ0KIyBGaWx0cmFyIHBvciBBcmdlbnRpbmEgLS0tLQ0KcmhfYXIgPC0gcmgyMmxhX2NsZWFuICU+JSANCiAgZmlsdGVyKHBhaXMgPT0gIkFyZ2VudGluYSIpICU+JSANCiAgbXV0YXRlKGFuaW8gPSAyMDIyKQ0KDQoNCnJoMjBhciA8LSByaDIwICU+JSANCiAgZmlsdGVyKHBhaXMgPT0gIkFyZ2VudGluYSIpDQoNCnJoMjFhciA8LSByaDIxICU+JSANCiAgZmlsdGVyKHBhaXMgPT0gIkFyZ2VudGluYSIpDQoNCnJoMjJhciA8LSByaF9hciAlPiUgDQogICAgc2VsZWN0KGFuaW8sIHBhaXMsIHB1ZXN0bywgZnVuY2lvbiwgc3VlbGRvX2JydXRvKSANCg0KIyBQYXJhIGFuYWxpemFyIGV2b2x1Y2nDs24gZGUgc2FsYXJpb3MNCiMgRXZvbHVjaW9uDQpoaXN0b3JpY28gPC0gcmJpbmQocmgyMGFyLCByaDIxYXIsIHJoMjJhcikNCg0KIyBVbmlmaWNhciBub21icmVzIGRlIGZ1bmNpb25lcw0KaGlzdG9yaWNvIDwtIGhpc3RvcmljbyAlPiUgDQogIG11dGF0ZShmdW5jaW9uID0gZmN0X2NvbGxhcHNlKGZ1bmNpb24sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ3VsdHVyYSB5IENsaW1hIiA9IGMoIkN1bHR1cmEgeSBiaWVuZXN0YXIiLCJDbGltYSAmIEN1bHR1cmEiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFkbWluaXN0cmFjacOzbiBkZSBQZXJzb25hbCIgPSBjKCJBZG1pbmlzdHJhY2nDs24gZGUgcGVyc29uYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWRtaW5pc3RyYWNpw7NuIGRlIFBlcnNvbmFsIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYXBhY2l0YWNpw7NuIHkgRGVzYXJyb2xsbyIgPSBjKCJDYXBhY2l0YWNpw7NuIHkgZGVzYXJyb2xsbyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhcGFjaXRhY2nDs24geSBkZXNhcnJvbGxvIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb21wZW5zYWNpb25lcyB5IEJlbmVmaWNpb3MiID0gIkNvbXBlbnNhY2lvbmVzIHkgYmVuZWZpY2lvcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb211bmljYWNpw7NuIEludGVybmEiID0gYygiQ29tdW5pY2FjacOzbiBJbnRlcm5hIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb211bmljYWNpw7NuIGludGVybmEiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpc2XDsW8gT3JnYW5pemFjaW9uYWwiID0gYygiRGlzZcOxbyBPcmdhbml6YWNpb25hbCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlzZcOxbyBvcmdhbml6YWNpb25hbCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGF5cm9sbCIgPSBjKCJQYXlyb2xsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGF5cm9sbCAvIExpcXVpZGFjacOzbiBkZSBzdWVsZG9zIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQZW9wbGUgQW5hbHl0aWNzIiA9IGMoIlBlb3BsZSBBbmFseXRpY3MiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGVvcGxlIGFuYWx5dGljcyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVjbHV0YW1pZW50byIgPSBjKCJSZWNsdXRhbWllbnRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVjbHV0YW1pZW50byB5IHNlbGVjY2nDs24iKSkpIA0KDQojIFNhbGFyaW8gcG9yIHB1ZXN0byANCg0KcmhfYXIgJT4lIA0KICBncm91cF9ieShwdWVzdG8pICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbmEgPSBtZWRpYW4oc3VlbGRvX2JydXRvKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZjdF9yZXYocHVlc3RvKSwgeSA9IG1lZGlhbmEpKSArDQogIGdlb21fY29sKGZpbGwgPSAiIzc1QUFEQiIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGNvbW1hKG1lZGlhbmEsIGJpZy5tYXJrID0gIi4iLCBkZWNpbWFsLm1hcmsgPSAiLCIpKSwNCiAgICAgICAgICAgIHZqdXN0ID0gMS4yLA0KICAgICAgICAgICAgc2l6ZSA9IDMsIA0KICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiKSArDQogIGVqZV95X24gKw0KICBlc3RpbG9oICsNCiAgbGFicyh0aXRsZSA9ICJNZWRpYW5hIFNhbGFyaWFsIHBvciBQdWVzdG8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIEFyZ2VudGluYSAtIEVuIEFSJCIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQogIA0KYGBgDQoNCkRhZG8gcXVlIGVsIHB1ZXN0byBkZSAqKkhSQlAqKiBlbiBhbGd1bmFzIGNvbXBhw7HDrWFzIGVzIHVuIGFuYWxpc3RhIHNlbmlvciwgeSBlbiBvdHJhcyBlcyB1biBwdWVzdG8gZ2VyZW5jaWFsLCBleHBsaWNhcsOtYSBlbCBwb3IgcXXDqSBsYSBtZWRpYW5hIHNhbGFyaWFsIGVzIG1heW9yIHF1ZSBlbCBjYXNvIGRlIGxvcyAqKlJlc3BvbnNhYmxlcyoqLCBxdWUgZXMgdW5hIGZpZ3VyYSBxdWUgc2UgdXNhIG1heW9ybWVudGUgZW4gZW1wcmVzYXMgY29uIGVzdHJ1Y3R1cmFzIHBlcXVlw7Fhcy4NCg0KIyMjIEV2b2x1Y2nDs24NCg0KDQpgYGB7ciBhcmdlbnRpbmE0fQ0KaGlzdG9yaWNvICU+JSANCiAgZ3JvdXBfYnkoYW5pbykgJT4lIA0KICBzdW1tYXJpc2UobWVkaWFuYSA9IG1lZGlhbihzdWVsZG9fYnJ1dG8pKSAlPiUgDQogIHVuZ3JvdXAgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBhbmlvLCB5ID0gbWVkaWFuYSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICIjNzVBQURCIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEobWVkaWFuYSwgYmlnLm1hcmsgPSAiLiIsIGRlY2ltYWwubWFyayA9ICIsIikpLA0KICAgICAgICAgICAgdmp1c3QgPSAxLjIsIA0KICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiKSArDQogIGVqZV95X24gKw0KICBlc3RpbG9oICsNCiAgbGFicyh0aXRsZSA9ICJNZWRpYW5hIFNhbGFyaWFsIHBvciBBw7FvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEYXRvcyBkZSBBcmdlbnRpbmEgLSBFbiBBUiQiLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KDQpoaXN0b3JpY29fdGFibGEgPC0gaGlzdG9yaWNvICU+JSANCiAgZ3JvdXBfYnkoYW5pbykgJT4lIA0KICBzdW1tYXJpc2UobWVkaWFuYSA9IG1lZGlhbihzdWVsZG9fYnJ1dG8pKSAlPiUgDQogIHVuZ3JvdXAgDQogIA0KYGBgDQoNCkxhIG1lZGlhbmEgc2FsYXJpYWwgZGVsIGHDsW8gMjAyMiBlbiBjb21wYXJhY2nDs24gYWwgMjAyMSBjcmVjacOzIHVuIGByIHBlcmNlbnQoKHB1bGwoaGlzdG9yaWNvX3RhYmxhWzMsMl0pL3B1bGwoaGlzdG9yaWNvX3RhYmxhWzIsMl0pKS0xKWAgbWllbnRyYXMgcXVlIGVsIGHDsW8gYW50ZXJpb3IgZWwgaW5jcmVtZW50byBoYSBzaWRvIGRlIHVuIGByIHBlcmNlbnQoKHB1bGwoaGlzdG9yaWNvX3RhYmxhWzIsMl0pL3B1bGwoaGlzdG9yaWNvX3RhYmxhWzEsMl0pKS0xKWAuDQoNCiMjIyBBbsOhbGlzaXMgcG9yIGZ1bmNpw7NuDQoNCk51ZXZhbWVudGUgZW5jb250cmFtb3MgcXVlIGxvcyBzYWxhcmlvcyBkZSBsYXMgZnVuY2lvbmVzIG3DoXMgc29maXN0aWNhZGFzIHNlIGVuY3VlbnRyYW4gZGVudHJvIGRlIGxvcyBzYWxhcmlvcyBtw6FzIGFsdG9zLCBtaWVudHJhcyBxdWUgZW4gcm9sZXMgbcOhcyBvcGVyYXRpdm9zIGVuY29udHJhbW9zIHNhbGFyaW9zIG3DoXMgYmFqb3MuDQoNCmBgYHtyIGFyZ2VudGluYTF9DQpyaF9hciAlPiUgDQogIGdyb3VwX2J5KGZ1bmNpb24pICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhbmEgPSBtZWRpYW4oc3VlbGRvX2JydXRvKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdncGxvdChhZXMoeSA9IHJlb3JkZXIoZnVuY2lvbiwgbWVkaWFuYSksIHggPSBtZWRpYW5hKSkgKw0KICBnZW9tX2NvbChmaWxsID0gIiM3NUFBREIiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShtZWRpYW5hLCBiaWcubWFyayA9ICIuIiwgZGVjaW1hbC5tYXJrID0gIiwiKSksDQogICAgICAgICAgICBoanVzdCA9IDEuMiwNCiAgICAgICAgICAgIHNpemUgPSAzLCANCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIikgKw0KICBlamVfeF9uICsNCiAgZXN0aWxvdiArDQogIGxhYnModGl0bGUgPSAiTWVkaWFuYSBTYWxhcmlhbCBwb3IgUHVlc3RvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEYXRvcyBkZSBBcmdlbnRpbmEgLSBFbiBBUiQiLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KYGBgDQoNCkEgY29udGludWFjacOzbiBwb2RlbW9zIGFwcmVjaWFyIGVsIGluY3JlbWVudG8gc2FsYXJpYWwgZW4gY29tcGFyYWNpw7NuIGNvbiBlbCBhw7FvIGFudGVyaW9yIGRlIGxvcyByb2xlcyBlbiBsb3MgY3VhbGVzIHRlbmVtb3MgaW5mb3JtYWNpw7NuLg0KDQpgYGB7cn0NCmhpc3RvcmljbyAlPiUgDQogIGZpbHRlcihhbmlvICE9IDIwMjAsDQogICAgICAgICAhZnVuY2lvbiAlaW4lIGMoIkhSSVMgLyBBZG1pbmlzdHJhY2nDs24gZGUgc2lzdGVtYXMgZGUgUkgiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICJDb250cm9sIGRlIEdlc3Rpw7NuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAiR2VzdGnDs24gZGUgZXhwYXRyaWFkb3MiKSkgJT4lIA0KICBncm91cF9ieShmdW5jaW9uLCBhbmlvKSAlPiUNCiAgc3VtbWFyaXNlKG1lZGlhbmEgPSBtZWRpYW4oc3VlbGRvX2JydXRvKSkgJT4lIA0KICB1bmdyb3VwICU+JSANCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldihmdW5jaW9uKSwgeCA9IG1lZGlhbmEsIGZpbGwgPSBmYWN0b3IoYW5pbykpKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEobWVkaWFuYSwgYmlnLm1hcmsgPSAiLiIsIGRlY2ltYWwubWFyayA9ICIsIikpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLA0KICAgICAgICAgICAgaGp1c3QgPSAxLjIsDQogICAgICAgICAgICBzaXplID0gMiwgDQogICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZT1UUlVFKSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKGdyaXMsICIjNzVBQURCIikpICsNCiAgZXN0aWxvdiArDQogIGVqZV94X24gKw0KICBsYWJzKHRpdGxlID0gIkV2b2x1Y2nDs24gU2FsYXJpYWwgcG9yIEZ1bmNpw7NuIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJFbiBBUiQiLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlLA0KICAgICAgIGZpbGwgPSAiQcOxbyIpDQpgYGANCg0KDQojIyMgQW7DoWxpc2lzIHBvciBydWJybw0KDQpWZWFtb3MgY3XDoWxlcyBzb24gbG9zIHJ1YnJvcyBtZWpvciBwYWdvcyBlbiBBcmdlbnRpbmEuDQoNCg0KYGBge3IgYXJnZW50aW5hMiwgZmlnLmhlaWdodD05fQ0KcmhfYXIgJT4lIA0KICBncm91cF9ieShydWJybykgJT4lIA0KICBzdW1tYXJpc2UobWVkaWFuYSA9IG1lZGlhbihzdWVsZG9fYnJ1dG8pKSAlPiUNCiAgdW5ncm91cCgpICU+JSANCiAgZ2dwbG90KGFlcyh5ID0gcmVvcmRlcihydWJybywgbWVkaWFuYSksIHggPSBtZWRpYW5hKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gYXp1bCkgKw0KICBnZW9tX3NlZ21lbnQoYWVzKHggPSAwLCB4ZW5kID0gbWVkaWFuYSwgeSA9IHJ1YnJvLCB5ZW5kID0gcnVicm8pLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gIiM3NUFBREIiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb21tYShtZWRpYW5hLCBiaWcubWFyayA9ICIuIiwgZGVjaW1hbC5tYXJrID0gIiwiKSksDQogICAgICAgICAgICBoanVzdCA9IC0wLjIsDQogICAgICAgICAgICBzaXplID0gMi44KSArDQogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDcwMDAwMCksIGxhYmVscyA9IGNvbW1hX2Zvcm1hdChiaWcubWFyayA9ICIuIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbC5tYXJrID0gIjsiKSkgKw0KICBlc3RpbG92ICsNCiAgbGFicyh0aXRsZSA9ICJNZWRpYW5hIFNhbGFyaWFsIHBvciBQdWVzdG8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIEFyZ2VudGluYSAtIEVuIEFSJCIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQpgYGANCg0KQWhvcmEgY29tcGFyZW1vcyBsb3Mgc3VlbGRvcyBwb3IgcnVicm9zIHkgZ8OpbmVyb3MuIEFxdcOtIHBvZHJlbW9zIGFwcmVjaWFyIGxhcyBkaWZlcmVuY2lhcyBlbnRyZSBsb3Mgc3VlbGRvcyBwcm9tZWRpb3MgZGUgbG9zIGhvbWJyZXMgeSBtdWplcmVzIGVuIGNhZGEgcnVicm8uDQoNCmBgYHtyIGFyX3J1YnJvMn0NCnJ1YnJvX2FyIDwtIHJoX2FyICU+JSANCiAgc2VsZWN0KHJ1YnJvLCBzdWVsZG9fZnQpICU+JSANCiAgZ3JvdXBfYnkocnVicm8pICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhX3N1ZWxkbyA9IG1lYW4oc3VlbGRvX2Z0KSwNCiAgICAgICAgICAgIHJlc3B1ZXN0YXMgPSBuKCkpICU+JSANCiAgYXJyYW5nZSgtcmVzcHVlc3RhcykNCg0KdG9wX3J1YnJvcyA8LSBydWJyb19hciAlPiUgDQogIGZpbHRlcihydWJybyAhPSAiT3Ryb3MiLCByZXNwdWVzdGFzID4gMTApICU+JSANCiAgcHVsbChydWJybykNCg0KIyBEaXZpZGUgZWwgbGFyZ28gZGUgJ3J1YnJvcycgZW4gdmFyaWFzIGzDrW5lYXMNCnJoX2FyJHJ1YnJvIDwtIHN0cl93cmFwKHJoX2FyJHJ1YnJvLCB3aWR0aCA9IDQwKQ0KDQoNCnJoX2FyICU+JSANCiAgZmlsdGVyKHJ1YnJvICVpbiUgdG9wX3J1YnJvcykgJT4lIA0KICBzZWxlY3QocnVicm8sIHN1ZWxkb19mdCwgZ2VuZXJvKSAlPiUgDQogIGdyb3VwX2J5KHJ1YnJvLCBnZW5lcm8pICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhX3N1ZWxkbyA9IG1lYW4oc3VlbGRvX2Z0KSwNCiAgICAgICAgICAgIHJlc3B1ZXN0YXMgPSBuKCkpICU+JSANCiAgYXJyYW5nZSgtcmVzcHVlc3RhcykgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtZWRpYV9zdWVsZG8sIHkgPSByZW9yZGVyKHJ1YnJvLCBtZWRpYV9zdWVsZG8pLCBmaWxsID0gZ2VuZXJvKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGNvbW1hKHJvdW5kKG1lZGlhX3N1ZWxkbywgMCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaWcubWFyayA9ICIuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2ltYWwubWFyayA9ICIsIiksDQogICAgICAgICAgICAgICAgaGp1c3QgPSAxLjQsIHZqdXN0ID0gMC4zKSwNCiAgICAgICAgICAgIHNpemUgPSAzLCANCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwgDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gLjkpKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGdlbmVybykgKw0KICBsYWJzKHRpdGxlID0gIlByb21lZGlvIHNhbGFyaWFsIHBvciBydWJybyB5IGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIEFyZ2VudGluYSAtIGVuIEFSJCIsDQogICAgICAgeCA9ICIiLCB5ID0gIiIsIGZpbGwgPSAiR8OpbmVybyIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICBlamVfeF9uICsNCiAgZXN0aWxvdiArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIpICsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZT1UUlVFKSkgICMgSW52aWVydGUgZWwgb3JkZW4gZGUgbG9zIGNvbG9yZXMgZW4gbGEgbGV5ZW5kYQ0KDQoNCnJtKHJ1YnJvX2FyLCB0b3BfcnVicm9zKQ0KYGBgDQoNClBvciDDumx0aW1vLCBhbmFsaWNlbW9zIGxvcyBzdWVsZG9zIGRlIGxvcyA2IHJ1YnJvcyBjb24gbWF5b3IgY2FudGlkYWQgZGUgcmVzcHVlc3RhcywgeSB2aXN1YWxpY2Vtb3MgbGFzIGRpc3RyaWJ1Y2lvbmVzIGRlIGxvcyBzdWVsZG9zIHBvciBwdWVzdG8geSBnw6luZXJvLiBFbiBlc3RlIGdyw6FmaWNvIHBvZGVtb3MgdmVyIGxvcyBjdWFydGlsZXMgZGVsaW1pdGFuZG8gbGFzIHpvbmFzIHNvbWJyZWFkYXMsIHkgbGEgbWVkaWFuYSBjb24gbGEgbMOtbmVhIGVuIGVsIGNlbnRybyBkZSBsYSBjYWphLiBMb3MgcHVudG9zIHZpb2xldGFzIHkgdmVyZGVzIHJlcHJlc2VudGFuIGEgbGFzIG11amVyZXMgeSBsb3MgaG9tYnJlcyByZXNwZWN0aXZhbWVudGUgZW4gY2FkYSB1bm8gZGUgbG9zIHB1ZXN0b3MuDQoNCmBgYHtyIGFyX3J1YnJvczN9DQojfCBvdXQud2lkdGggPSAiOTAlIiwNCiN8IGZpZy5oZWlnaHQgPSA3DQoNCnJoX2FyICU+JSANCiAgICBmaWx0ZXIoZ2VuZXJvICVpbiUgYygiTXVqZXIgY2lzIiwgIkhvbWJyZSBjaXMiKSwNCiAgICAgICAgIHB1ZXN0byAhPSAiRGlyZWN0b3IiLA0KICAgICAgICAgcnVicm8gJWluJSBjKCJUZWNub2xvZ8OtYXMgZGUgaW5mb3JtYWNpw7NuIiwNCiAgICAgICAgICAgICAgICAgICAgICAiU2VydmljaW9zIGRlIGNvbnN1bHRvcsOtYSIsDQogICAgICAgICAgICAgICAgICAgICAgIlNlcnZpY2lvcyBkZSBzYWx1ZCIsDQogICAgICAgICAgICAgICAgICAgICAgIkFsaW1lbnRhY2nDs24sIGJlYmlkYXMiLA0KICAgICAgICAgICAgICAgICAgICAgICJDb21lcmNpbyIsDQogICAgICAgICAgICAgICAgICAgICAgIlNlcnZpY2lvcyBwcm9mZXNpb25hbGVzIikpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmN0X3JldihwdWVzdG8pLCB5ID0gc3VlbGRvX2JydXRvKSkgKw0KICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjQsIGFscGhhID0gMC4zLCBmaWxsID0gZ3JpcykgKw0KICBnZW9tX3BvaW50KGFlcyh5ID0gc3VlbGRvX2JydXRvLCBjb2xvciA9IGdlbmVybyksIGFscGhhID0gMC40LA0KICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gMC4yNSkpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGModmVyZGUsIGxpbGEpKSArDQogIGVqZV95X24gKw0KICBjb29yZF9mbGlwKCkgKw0KICBmYWNldF93cmFwKH5ydWJybywgbmNvbCA9IDIpICsNCiAgZXN0aWxvdiArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVjacOzbiBzYWxhcmlhbCBwb3IgcHVlc3RvIHkgcnVicm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRhdG9zIGRlIEFyZ2VudGluYSAtIGVuIEFSJCIsDQogICAgICAgeCA9ICIiLCB5ID0gIiIsIGNvbG9yID0gIkfDqW5lcm8iLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpICsNCiAgdGhlbWUocGxvdC50aXRsZS5wb3NpdGlvbiA9ICJwbG90IiwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQpgYGANCg0KDQojIyMgUmVsYWNpb25lcyBlbnRyZSBleHBlcmllbmNpYSB5IHN1ZWxkbyBicnV0bw0KDQpFbiBlc3RhIHNlY2Npw7NuIGRlbCBhbsOhbGlzaXMgYnVzY2Ftb3MgaWRlbnRpZmljYXIgY3XDoWxlcyBzb24gbG9zIGZhY3RvcmVzIHF1ZSBpbmZsdXllbiBlbiBsb3MgaW5ncmVzb3MgKGluZGVwZW5kaWVudGVtZW50ZSBkZSBsYSBwb3NpY2nDs24pLCBhc8OtIHF1ZSBlbXBlemFtb3MgYSBleHBsb3JhciBsb3MgZGF0b3MuDQoNCkxhIHByaW1lcmEgcHJlZ3VudGEgcXVlIG5vcyBoaWNpbW9zIGZ1ZSBzaSBsb3MgYcOxb3MgZGUgdHJheWVjdG9yaWEgaW5mbHV5ZW4gZW4gZWwgc3VlbGRvLiBOdWVzdHJhIGhpcMOzdGVzaXMgZXMgcXVlIGEgbWF5b3IgY2FudGlkYWQgZGUgYcOxb3MgZGUgZXhwZXJpZW5jaWEsIG1heW9yIGliYSBhIHNlciBlbCBpbmdyZXNvLg0KDQpMbyBxdWUgdmFtb3MgYSB2ZXIgZW4gZWwgc2lndWllbnRlIGdyw6FmaWNvIGRlIGRpc3BlcnNpw7NuLCBlcyBlbiBlbCBlamUgaG9yaXpvbnRhbCwgbG9zIGHDsW9zIGRlIGV4cGVyaWVuY2lhLCB5IGVuIGVsIGVqZSB2ZXJ0aWNhbCwgZWwgc3VlbGRvIGJydXRvIGV4cHJlc2FkbyBlbiBwZXNvcyBhcmdlbnRpbm9zLiBMdWVnbywgdmFtb3MgYSBncmFmaWNhciB1bmEgcmVjdGEsIHF1ZSBub3MgdmEgYSBpbmRpY2FyIGxhICpmdWVyemEqIGRlIGVzYSByZWxhY2nDs24uDQoNCmBgYHtyIHJlZ19saW5lYWxfMX0NCmxtX3JoIDwtIGxtKHN1ZWxkb19mdCB+IGFuaW9zX3JoLCBkYXRhID0gcmhfYXIpDQoNCmxtX2hyX3Jlc3VsdHMgPC0gc3VtbWFyeShsbV9yaCkNCg0KbG1fcmhfcjIgPC0gcm91bmQobG1faHJfcmVzdWx0c1tbInIuc3F1YXJlZCJdXSwzKQ0KDQpnZ3Bsb3QocmhfYXIsIGFlcyh4PWFuaW9zX3JoLCB5ID0gc3VlbGRvX2Z0KSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gIiMxRkMzQUEiLCBhbHBoYSA9IDAuNCwgc2l6ZSA9IDIpICsgDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiUm9ib3RvIikpICsNCiAgbGFicyh0aXRsZSA9ICJSZWxhY2nDs24gZW50cmUgc3VlbGRvIHkgYcOxb3MgZGUgZXhwZXJpZW5jaWEiLA0KICAgICAgIHggPSAiQcOxb3MgZGUgRXhwZXJpZW5jaWEiLA0KICAgICAgIHkgPSAiU3VlbGRvIGJydXRvIChBUiQpIiwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICBlamVfeV9uICsNCiAgZ2VvbV90ZXh0KGFlcyh4PS1JbmYsIHk9SW5mLCBoanVzdD0wLCB2anVzdD0xLCBsYWJlbD0gcGFzdGUwKCJSMiA9ICIsIGxtX3JoX3IyKSkpIA0KDQpgYGANCg0KRW4gZWwgZ3LDoWZpY28gcG9kZW1vcyBhcHJlY2lhciB1bmEgcmVjdGEgcXVlIHZhIGNyZWNpZW5kbyBlZmVjdGl2YW1lbnRlOiBhIG1lZGlkYSBxdWUgbm9zIG1vdmVtb3MgbcOhcyBoYWNpYSBsYSBkZXJlY2hhLCBsYSByZWN0YSB2YSBzdWJpZW5kby4gUGVybyBlbCAkUl4yJCA9IGByIGxtX3JoX3IyYCBub3MgaW5kaWNhIGN1w6FudG8gZXhwbGljYSBsb3MgYcOxb3MgZGUgZXhwZXJpZW5jaWEgc29icmUgZWwgc3VlbGRvIGJydXRvLCBvIGRpY2hvIGRlIG90cmEgbWFuZXJhLCBlbiBxdcOpIG1lZGlkYSBpbmZsdXllIGxhIHZhcmlhYmxlIHggKGHDsW9zIGRlIGV4cGVyaWVuY2lhKSwgc29icmUgbGEgdmFyaWFibGUgeSAoc3VlbGRvIGJydXRvKS4gVW5hIGRlZmluaWNpw7NuIG3DoXMgcHJlY2lzYSBkZSBlc3RlIHZhbG9yIGNvbm9jaWRvIGNvbW8gKipDb2VmaWNpZW50ZSBkZSBEZXRlcm1pbmFjacOzbioqIGVzIGxhIHByb3BvcmNpw7NuIGRlIGxhIHZhcmlhbnphIHRvdGFsIGRlIGxhIHZhcmlhYmxlIGV4cGxpY2FkYSBwb3IgbGEgcmVncmVzacOzbi4NCg0KRXN0ZSB2YWxvciBwdWVkZSBlc3RhciBlbnRyZSAwIHkgMSwgbWllbnRyYXMgbcOhcyBjZXJjYSBkZSAwIGVzdMOhIG1lbm9yIGVzIGxhIHJlbGFjacOzbiwgeSBtaWVudHJhcyBtw6FzIGNlcmNhIGRlIDEgZXN0w6kgZWwgcmVzdWx0YWRvLCBpbmRpY2EgcXVlIGxhIHJlZ3Jlc2nDs24gZXhwbGljYSBsYSB2YXJpYWJpbGlkYWQgZGUgbGEgdmFyaWFibGUgZGUgcmVzcHVlc3RhLiBFcyBwb3IgZXNvIHF1ZSBlc3RlICRSXjIkID0gYHIgbG1fcmhfcjJgIG5vcyBpbmRpY2EgcXVlIGxvcyBhw7FvcyBkZSBleHBlcmllbmNpYSBleHBsaWNhbiB1biAyMC44JSBkZSBsYSB2YXJpYWJpbGlkYWQgZGUgbG9zIHN1ZWxkb3MgZW4gUlJISC4NCg0KIyMjIyBSZWxhY2nDs24gZW50cmUgYcOxb3MgZGUgZXhwZXJpZW5jaWEgeSBzdWVsZG8gYnJ1dG8gcG9yIHB1ZXN0by4NCg0KRGFkbyBxdWUgZW4gZWwgZ3LDoWZpY28gYW50ZXJpb3IgdGVuZW1vcyBtZXpjbGFkb3MgbG9zIHN1ZWxkb3MgZGUgYWRtaW5pc3RyYXRpdm9zLCBhbmFsaXN0YXMsIGplZmVzIHkgZ2VyZW50ZXMsIGRlY2lkaW1vcyBhbmFsaXphciBsYSByZWxhY2nDs24gZW50cmUgbG9zIGHDsW9zIGRlIGV4cGVyaWVuY2lhIHkgZWwgc3VlbGRvIGJydXRvIHBvciBjYWRhIHVubyBkZSBsb3MgcHVlc3RvcyBwb3Igc2VwYXJhZG8uDQoNCmBgYHtyIHJlZ19saW5lYWxfMiwgb3V0LndpZHRoPSI5MCUifQ0KDQptaS5mb3JtdWxhIDwtIHkgfiB4DQoNCmdncGxvdChyaF9hciwgYWVzKHg9YW5pb3NfcmgsIHkgPSBzdWVsZG9fZnQpKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAiIzFGQzNBQSIsIGFscGhhID0gMC40LCBzaXplID0gMikgKyANCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgZm9ybXVsYSA9IG1pLmZvcm11bGEsIHNlID0gRkFMU0UpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiUm9ib3RvIikpICsNCiAgbGFicyh0aXRsZSA9ICJSZWxhY2nDs24gZW50cmUgc3VlbGRvIHkgYcOxb3MgZGUgZXhwZXJpZW5jaWEiLA0KICAgICAgIHggPSAiQcOxb3MgZGUgRXhwZXJpZW5jaWEiLA0KICAgICAgIHkgPSAiIiwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICBlamVfeV9uICsNCiAgc3RhdF9wb2x5X2VxKGZvcm11bGEgPSBtaS5mb3JtdWxhLCANCiAgICAgICAgICAgICAgIGFlcyhsYWJlbCA9IHBhc3RlKC4ucnIubGFiZWwuLiwgc2VwID0gIn5+fiIpKSwgDQogICAgICAgICAgICAgICBwYXJzZSA9IFRSVUUpICsNCiAgZmFjZXRfd3JhcCh+cHVlc3RvKQ0KDQpgYGANCg0KQ29tbyBwb2RlbW9zIGFwcmVjaWFyIGVuIGxvcyAkUl4yJCBkZSBjYWRhIGdyw6FmaWNvIGVuIGVsIMO6bmljbyBwdWVzdG8gZG9uZGUgZW5jb250cmFtb3MgdW5hIGZ1ZXJ0ZSByZWxhY2nDs24gZW50cmUgbG9zIGHDsW9zIGRlIGV4cGVyaWVuY2lhIHkgZWwgc3VlbGRvIGJydXRvIGVzIGVuIGxvcyAqKkFkbWluaXN0cmF0aXZvcyoqLiBFbiBlbCByZXN0byBkZSBsb3MgcHVlc3RvcyBsb3MgYcOxb3MgZGUgdHJheWVjdG9yaWEgaW5mbHV5ZW4gbXV5IHBvY28gZW4gbG9zIHN1ZWxkb3MgZGUgY2FkYSB1bm8gZGUgbG9zIHB1ZXN0b3MuIEVuIGVsIGNhc28gZGUgbG9zICoqRGlyZWN0b3JlcyoqIHRhbWJpw6luIHZlbW9zIHVuYSByZWxhY2nDs24gbXV5IGZ1ZXJ0ZSBwZXJvIG5lZ2F0aXZhLiBFbiBhbWJvcyBjYXNvcyBsbyBwb2RlbW9zIGF0cmlidWlyIGEgbGEgYmFqYSBjYW50aWRhZCBkZSByZXNwdWVzdGFzIHF1ZSBhZmVjdGEgbGEgY2FsaWRhZCBkZSBlc3RlIGFuw6FsaXNpcy4NCg0KQWhvcmEgYmllbiwgbGEgcHJlZ3VudGEgZXMsICrCv2N1w6FsIGVzIGxhIHZhcmlhYmxlIHF1ZSBtw6FzIGluZmx1eWUgZW4gZWwgc3VlbGRvIGVuIFJlY3Vyc29zIEh1bWFub3M/LiogVHJpc3RlbWVudGUsIGxhIHJlc3B1ZXN0YSBubyBzb3JwcmVuZGUuDQoNCmBgYHtyfQ0KcmhfYXIgJT4lIA0KICBmaWx0ZXIoZ2VuZXJvICVpbiUgYygiSG9tYnJlIGNpcyIsICJNdWplciBjaXMiKSkgJT4lIA0KZ2dwbG90KGFlcyh4ID0gZ2VuZXJvLCB5ID0gc3VlbGRvX2Z0LCBmaWxsID0gZ2VuZXJvKSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIGVqZV95X24gKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKHZlcmRlLCBsaWxhKSkgKw0KICBlc3RpbG9oICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIHNhbGFyaWFsIHBvciBnw6luZXJvIiwNCiAgICAgICB4ID0gIiIsIHkgPSAiIiwNCiAgICAgICBmaWxsID0gIkfDqW5lcm8iLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCmBgYA0KDQpTaSBiaWVuIGhheSAqb3V0bGllcnMqIGVudHJlIGxhcyBtdWplcmVzIGNvbiBzdWVsZG9zIG11eSBhbHRvcywgbG9zIHNhbGFyaW9zIGRlIGxvcyBob21icmVzIGVuIGdlbmVyYWwgc3VlbGVuIHNlciBtw6FzIGFsdG9zIHF1ZSBlbCBkZSBsYXMgbXVqZXJlcywgcG9yIGVzbyB2ZW1vcyBxdWUgbGEgY2FqYSBkZSBsb3MgaG9tYnJlcyBlcyBtw6FzIGFsdGEgcXVlIGVsIGRlIGxhcyBtdWplcmVzLg0KDQojIyBBbsOhbGlzaXMgc2Vnw7puIGfDqW5lcm8NCg0KQ3VhbmRvIGFuYWxpemFtb3MgbGEgZGlzdHJpYnVjacOzbiBzYWxhcmlhbCBwb3IgcHVlc3RvLCBhcHJlY2lhbW9zIGRlc2lndWFsZGFkZXMgcXVlIHNlIHJlcGl0ZW4gZGUgYcOxb3MgYW50ZXJpb3Jlcy4gQW50ZXMgZGUgcHJvZnVuZGl6YXIsIGV4cGxpcXVlbW9zIGJyZXZlbWVudGUgY8OzbW8gaW50ZXJwcmV0YXIgZWwgZ3LDoWZpY28gcXVlIHZlbW9zIGEgY29udGludWFjacOzbiBxdWUgc2UgbGxhbWEgKmJveHBsb3QqLg0KDQpFbiBwcmltZXIgbHVnYXIsIGxhIHBhcnRlIGluZmVyaW9yIGRlIGNhZGEgY2FqYSBpbmRpY2EgZWwgdmFsb3IgZGVsICoqcHJpbWVyIGN1YXJ0aWwqKiwgZXMgZGVjaXIgZWwgbMOtbWl0ZSBkb25kZSBzZSBlbmN1ZW50cmEgZWwgMjUlIGRlIGxvcyBkYXRvcy4gUG9yIG90cmEgcGFydGUsIGxhIHBhcnRlIHN1cGVyaW9yIGRlIGNhZGEgY2FqYSBpbmRpY2EgZWwgKip0ZXJjZXIgY3VhcnRpbCoqLCBvIHNlYSwgZWwgNzUlIGRlIGxvcyBkYXRvcy4gRXN0byBpbXBsaWNhIHF1ZSBkZW50cm8gZGUgbGEgY2FqYSBub3MgZW5jb250cmFtb3MgY29uIGxhIG1pdGFkIGRlIGxvcyBkYXRvcy4gTGEgY2FudGlkYWQgZGUgY2Fzb3MgZGVudHJvIGRlIGNhZGEgbWl0YWQgZXMgbGEgbWlzbWEgcGFyYSBjYWRhIGNhamEuDQoNClVuIGVsZW1lbnRvIG11eSBpbXBvcnRhbnRlIGRlbnRybyBkZWwgZ3LDoWZpY28gZXMgbGEgbMOtbmVhIHF1ZSBvYnNlcnZhbW9zIGRlbnRybyBkZSBjYWRhIGNhamEgcXVlIHJlcHJlc2VudGEgYSBsYSAqKm1lZGlhbmEqKiBxdWUgZXMgZWwgdmFsb3IgcXVlIGRpdmlkZSBhIGxhIG1pdGFkIGEgbG9zIGRhdG9zLiBFc3RlIGVzIGVsIHZhbG9yIHF1ZSBoYWJpdHVhbG1lbnRlIHV0aWxpemFtb3MgcGFyYSBjb21wYXJhciBzYWxhcmlvcyBwb3JxdWUgcmVwcmVzZW50YSBlbCBwdW50byBtZWRpbyBwYXJhIGNhZGEgZ3J1cG8geSBhZGVtw6FzIG5vIGVzIHNlbnNpYmxlIGEgdmFsb3JlcyBleHRyZW1vcyBjb21vIGVsIHByb21lZGlvLiAqKkxhIG1lZGlhbmEgZXMgZWwgdmFsb3IgcXVlIHZhbW9zIGEgdXNhciBwYXJhIGNvbXBhcmFyIGxvcyBzdWVsZG9zIGVudHJlIGhvbWJyZXMgeSBtdWplcmVzKiouDQoNCkxvcyBwdW50b3MgcXVlIG9ic2VydmFtb3MgZW4gYWxndW5vcyBjYXNvcyBpbmRpY2FuIHZhbG9yZXMgZXh0cmVtb3MgcXVlIGRlbm9taW5hbW9zICoqb3V0bGllcnMuKiogRXN0b3MgdmFsb3JlcyBzb24gYXTDrXBpY29zLiBMYXMgbMOtbmVhcyBxdWUgc2FsZW4gZGUgbGFzIGNhamFzIGluZGljYW4gbG9zIGzDrW1pdGVzIGEgcGFydGlyIGRlIGxvcyBjdWFsZXMgc2UgZGV0ZXJtaW5hIHF1ZSB1biB2YWxvciBlcyBhdMOtcGljbyBvIG5vLg0KDQpQb3Igw7psdGltbywgZWwgdGFtYcOxbyBkZSBsYSBjYWphIHRhbWJpw6luIGVzIGltcG9ydGFudGUgcG9ycXVlIG5vcyBkYSB1bmEgaWRlYSBkZSBsYSAqKmRpc3RyaWJ1Y2nDs24qKiBkZSBsb3MgZGF0b3MuIFNpIGxhIGNhamEgZXMgY2hpcXVpdGEgcXVpZXJlIGRlY2lyIHF1ZSBsb3Mgc3VlbGRvcyBlc3TDoW4gZW4gdW4gcmFuZ28gZGUgdmFsb3JlcyBjZXJjYW5vLiBFbiBjYW1iaW8gc2kgbGEgY2FqYSwgbyB1bmEgZGUgc3VzIG1pdGFkZXMsIGVzIGxhcmdhLCBlc28gbm9zIGluZGljYSBxdWUgbG9zIHN1ZWxkb3MgdGllbmVuIHVuIHJhbmdvIG3DoXMgYW1wbGlvLCBvIHNlYSBxdWUgbG9zIHN1ZWxkb3MgbGxlZ2FuIGEgdmFsb3JlcyBtw6FzIGFsdG9zIG8gbcOhcyBiYWpvcyBkZXBlbmRpZW5kbyBlbCBjYXNvLCB5IHF1ZSBzZSBhbGVqYW4gbcOhcyBkZSBsYSBtZWRpYW5hLg0KDQpgYGB7cn0NCnJoX2FyICU+JSANCiAgZmlsdGVyKGdlbmVybyAlaW4lIGMoIkhvbWJyZSBjaXMiLCAiTXVqZXIgY2lzIiksDQogICAgICAgICAhcHVlc3RvICVpbiUgYygiRGlyZWN0b3IiLCAiQWRtaW5pc3RyYXRpdm8iKSkgJT4lIA0KZ2dwbG90KGFlcyh4ID0gZmN0X3JldihwdWVzdG8pLCB5ID0gc3VlbGRvX2JydXRvLCBmaWxsID0gZ2VuZXJvKSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIGVzdGlsb2ggKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKHZlcmRlLCBsaWxhKSkgKw0KICBlamVfeV9uICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIFNhbGFyaWFsIHNlZ8O6biBJZGVudGlkYWQgZGUgR8OpbmVybyIsDQogICAgICAgc3VidGl0bGUgPSAiRW4gQVIkIiwNCiAgICAgICBmaWxsID0gIklkZW50aWRhZCBkZSBHw6luZXJvIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikNCmBgYA0KDQpFbiBlbCBncsOhZmljbyBhbnRlcmlvciBwb2RlbW9zIGFwcmVjaWFyIHF1ZSBsYXMgbWVkaWFuYXMgZGUgbG9zIHN1ZWxkb3MgZXMgbcOhcyBhbHRhIHBhcmEgbG9zIGhvbWJyZXMgZW4gbG9zIHJvbGVzIGRlICoqQW5hbGlzdGEqKiwgKipSZXNwb25zYWJsZXMqKiwgeSAqKkplZmVzKiouIEVuIGNhbWJpbyBlbiBsYXMgbXVqZXJlcyBwb2RlbW9zIGFwcmVjaWFyIHF1ZSBsYXMgKipIQlJQKiogeSAqKkdlcmVudGVzKiogdGllbmVuIG1lZGlhbmFzIHNhbGFyaWFsZXMgbcOhcyBhbHRhcy4NCg0KQW5hbGl6YW5kbyBlbCByb2wgZGUgKipBbmFsaXN0YSoqIHBvZGVtb3MgdmVyIHF1ZSBlbiBlbCBjYXNvIGRlIGxvcyBob21icmVzLCBhZGVtw6FzIGRlIG9ic2VydmFyIHVuYSBtZWRpYW5hIHNhbGFyaWFsIG3DoXMgYW1wbGlhIHF1ZSBlbiBlbCBjYXNvIGRlIGxhcyBtdWplcmVzLCBlbCB0YW1hw7FvIGRlIGxhIGNhamEgZXMgbcOhcyBhbXBsaWEsIGxvIHF1ZSBub3MgaW5kaWNhIHF1ZSBsb3Mgc3VlbGRvcyBkZSBsb3MgYW5hbGlzdGFzIHZhcm9uZXMgdGllbmVuIHVuIHJhbmdvIG3DoXMgYW1wbGlvIGxsZWdhbmRvIGEgc3VlbGRvcyBtw6FzIGFsdG9zIHF1ZSBzdXMgcGFyZXMgbXVqZXJlcy4gUG9kZW1vcyBhcHJlY2lhciB2YXJpb3Mgb3V0bGllcnMgcG9yIGVuY2ltYSBkZSBsb3MgYEFSJCA0MDAuMDAwYCB0YW50byBwYXJhIGhvbWJyZXMgeSBtdWplcmVzLg0KDQpFbiBlbCByb2wgZGUgKipKZWZlKiogYXByZWNpYW1vcyBxdWUgbGFzIG1lZGlhbmFzIGVzdMOhbiBhbGdvIGFsZWphZGFzIHkgZWwgdGFtYcOxbyBkZSBsYSBjYWphIG5vcyBpbmRpY2EgcXVlIGxvcyByYW5nb3MgZGUgbG9zIHN1ZWxkb3MgZGUgbG9zIGhvbWJyZXMgYWxjYW56YSB2YWxvcmVzIG3DoXMgYWx0b3MgcXVlIGVuIGVsIGNhc28gZGUgbGFzIG11amVyZXMsIG1pZW50cmFzIHF1ZSBsYSBtaXRhZCBzdXBlcmlvciBkZSBsYXMgbXVqZXJlcyBlc3TDoSBjb25jZW50cmFkbyBlbiB1biByYW5nbyBkZSB2YWxvcmVzIG11eSBjZXJjYW5vcy4gVGFtYmnDqW4gcG9kZW1vcyBvYnNlcnZhciBxdWUgaGF5IGFsZ3Vub3MgY2Fzb3MgZGUgbXVqZXJlcyBjb24gc3VlbGRvcyBtdXkgYWx0b3MgaW5kaWNhZG9zIGNvbW8gKm91dGxpZXJzKiAocHVudG9zKSBhbHJlZGVkb3IgZGUgbG9zIGBBUiQgNjAwLjAwMGAuDQoNCkVzdGEgZXMgb3RyYSBvcGNpw7NuIHBhcmEgdmlzdWFsaXphciBsb3MgZ2FwcyBzYWxhcmlhbGVzLg0KDQoNCmBgYHtyfQ0KYnJlY2hhIDwtIHJoX2FyICU+JSANCiAgZmlsdGVyKGdlbmVybyAlaW4lIGMoIk11amVyIGNpcyIsICJIb21icmUgY2lzIiksIA0KICAgICAgICAgcHVlc3RvICVpbiUgYygiR2VyZW50ZSIsIkplZmUiLCAiSFJCUCIsIlJlc3BvbnNhYmxlIiwgIkFuYWxpc3RhIikpICU+JSANCiAgbXV0YXRlKHB1ZXN0byA9IGZhY3RvcihwdWVzdG8sIGxldmVscyA9IGMoIkFuYWxpc3RhIiwgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSFJCUCIsICJSZXNwb25zYWJsZSIsICJKZWZlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdlcmVudGUiLCJEaXJlY3RvciIpKSkgJT4lIA0KICBncm91cF9ieShnZW5lcm8sIHB1ZXN0bykgJT4lIA0KICBzdW1tYXJpc2UobWVkaWFfc2FsYXJpYWwgPSBtZWRpYW4oc3VlbGRvX2JydXRvLCBuYS5ybSA9IFRSVUUpKSAlPiUgDQogIHVuZ3JvdXAoKQ0KDQoNCmJyZWNoYV9ncmFmIDwtIGJyZWNoYSAlPiUgDQogIHBpdm90X3dpZGVyKC4sIG5hbWVzX2Zyb20gPSBnZW5lcm8sIHZhbHVlc19mcm9tID0gbWVkaWFfc2FsYXJpYWwpICU+JSANCiAgbXV0YXRlKGJyZWNoYSA9IHBlcmNlbnQoKGBIb21icmUgY2lzYC1gTXVqZXIgY2lzYCkvYEhvbWJyZSBjaXNgLCAxKSwNCiAgICAgICAgIHggPSAoYEhvbWJyZSBjaXNgICsgYE11amVyIGNpc2ApLzIpDQoNCmdncGxvdChicmVjaGFfZ3JhZiwgDQogICAgICAgYWVzKHggPSBgTXVqZXIgY2lzYCwgeGVuZCA9IGBIb21icmUgY2lzYCwgeSA9IHB1ZXN0bywgDQogICAgICAgICAgIGdyb3VwID0gcHVlc3RvLCBsYWJlbCA9IGJyZWNoYSkpICsNCiAgZ2VvbV9kdW1iYmVsbChjb2xvciA9ICIjODA4MDgwIiwNCiAgICAgICAgICAgICAgICBzaXplX3ggPSAzLCBzaXplX3hlbmQgPSAzLA0KICAgICAgICAgICAgICAgIGNvbG91cl94ID0gY29sb3Jlc1sxXSwNCiAgICAgICAgICAgICAgICBjb2xvdXJfeGVuZCA9IGNvbG9yZXNbMl0pICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBicmVjaGFfZ3JhZiwgDQogICAgICAgICAgICBhZXMoeCwgcHVlc3RvLCBsYWJlbCA9IGJyZWNoYSksIHNpemUgPSAzLA0KICAgICAgICAgICAgbnVkZ2VfeSA9IC4yKSArDQogIGxhYnModGl0bGUgPSAiQnJlY2hhIHNhbGFyaWFsIHBvciBwdWVzdG9zIGRlIFJSSEgiLA0KICAgICAgIHN1YnRpdGxlID0gIk1lZGlhbmEgZW4gQXJnZW50aW5hIiwNCiAgICAgICB4ID0gIiIsDQogICAgICAgeSA9IE5VTEwsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IGNvbW1hX2Zvcm1hdChiaWcubWFyayA9ICIuIiwgZGVjaW1hbC5tYXJrID0gIiwiKSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JlcykNCmBgYA0KDQoNClNpIG9ic2VydmFtb3MgbGEgbWVkaWFuYSBzYWxhcmlhbCBwYXJhIGNhZGEgcHVlc3RvIHZlbW9zIHF1ZSBkZSBhY3VlcmRvIGEgbGFzIHJlc3B1ZXN0YXMgcmVjb2xlY3RhZGFzIGxhcyAqKm11amVyZXMqKiBlbiBwdWVzdG8gZGUgKipHZXJlbnRlKiogdGllbmVuIHVuIHN1ZWxkbyB1biAxMCUgbWF5b3IgcXVlIGxvcyBob21icmVzIGVuIGVsIG1pc21vIHJvbC4gTm8gaGF5IGRpZmVyZW5jaWEgc2FsYXJpYWwgZW4gZWwgcHVlc3RvIGRlIEhSQlAuDQoNCkZpbmFsbWVudGUgdmVtb3MgcXVlIGxhIGJyZWNoYSBzYWxhcmlhbCBlbiBmYXZvciBkZSBsb3MgaG9tYnJlcyBlcyBkZSB1biAxNiUgZW4gZWwgcm9sIGRlICoqSmVmZSoqLCB1biAxNCUgcGFyYSAqKlJlc3BvbnNhYmxlcyoqIHkgZGUgdW4gMTMlIHBhcmEgbG9zICoqQW5hbGlzdGFzKiouDQoNCkVuIGxhIHRhYmxhIGEgY29udGludWFjacOzbiB2ZXJlbW9zIGFsZ3Vub3MgZGF0b3MgcXVlIHJlc3VtZW4gZXN0b3MgaGFsbGF6Z29zLiBFeGNsdWltb3MgYSBsb3MgZGlyZWN0b3JlcyB5IGFkbWluaXN0cmF0aXZvcyBwb3JxdWUgdGVuZW1vcyBtdXkgcG9jYXMgcmVzcHVlc3Rhcy4NCg0KYGBge3IgdGFibGFfZ2VuZXJvX2FyfQ0KZ3QocmhfYXIgJT4lIA0KICBmaWx0ZXIoZ2VuZXJvICVpbiUgYygiSG9tYnJlIGNpcyIsICJNdWplciBjaXMiKSwgDQogICAgICAgICAhcHVlc3RvICVpbiUgYygiRGlyZWN0b3IiLCAiQWRtaW5pc3RyYXRpdm8iKSkgJT4lIA0KICBncm91cF9ieShwdWVzdG8sIGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2UoUnRhcyA9IG4oKSwNCiAgICAgICAgICAgIE1pbiA9IG1pbihzdWVsZG9fYnJ1dG8pLA0KICAgICAgICAgICAgTWVkaWFuYSA9IG1lZGlhbihzdWVsZG9fYnJ1dG8pLA0KICAgICAgICAgICAgUHJvbWVkaW8gPSBtZWFuKHN1ZWxkb19icnV0byksDQogICAgICAgICAgICBNYXggPSBtYXgoc3VlbGRvX2JydXRvKQ0KICAgICAgICAgICAgKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIHBpdm90X2xvbmdlcihjb2xzID0gYygiUnRhcyIsICJNaW4iLCAiTWVkaWFuYSIsICJQcm9tZWRpbyIsICJNYXgiKSwNCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIk1ldHJpY2EiLA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIlZhbG9yIikgJT4lIA0KICBwaXZvdF93aWRlcihpZF9jb2xzID0gYyhwdWVzdG8sZ2VuZXJvKSwNCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IE1ldHJpY2EsDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gVmFsb3IpLA0KICBncm91cG5hbWVfY29sID0gInB1ZXN0byIpICU+JSANCiAgZm10X2N1cnJlbmN5KGNvbHVtbnMgPSBjKE1pbiwgTWVkaWFuYSwgUHJvbWVkaW8sIE1heCksDQogICAgICAgICAgICAgICBjdXJyZW5jeSA9ICJBUlMiLA0KICAgICAgICAgICAgICAgZGVjaW1hbHMgPSAwLA0KICAgICAgICAgICAgICAgc2VwX21hcmsgPSAiLiIsDQogICAgICAgICAgICAgICBkZWNfbWFyayA9ICIsIikgJT4lIA0KICB0YWJfaGVhZGVyKHRpdGxlID0gIlJlc3VtZW4gU2FsYXJpYWwgcG9yIFB1ZXN0byB5IEfDqW5lcm8iLA0KICAgICAgICAgICAgIHN1YnRpdGxlID0gIkVuIEFSJCIpICU+JSANCiAgdGFiX3NwYW5uZXIobGFiZWwgPSAiTcOpdHJpY2FzIFNhbGFyaWFsZXMiLA0KICAgICAgICAgICAgICBjb2x1bW5zID0gYyhNaW4sIE1lZGlhbmEsIFByb21lZGlvLCBNYXgpKSAlPiUgDQogIHRhYl9zb3VyY2Vfbm90ZShzb3VyY2Vfbm90ZSA9IGZ1ZW50ZSkgJT4lIA0KICBjb2xzX2xhYmVsKHB1ZXN0byA9ICJQdWVzdG8iLA0KICAgICAgICAgICAgIGdlbmVybyA9ICJHw6luZXJvIikgJT4lIA0KICB0YWJfb3B0aW9ucyhyb3dfZ3JvdXAuYmFja2dyb3VuZC5jb2xvciA9ICIjQTNFNEQ3IiwpDQpgYGANCg0KDQojIEVkdWNhY2nDs24NCg0KRW4gZXN0YSBzZWNjacOzbiBxdWVyZW1vcyBpbmRhZ2FyIHNpIGhheSByZWxhY2nDs24gZW50cmUgbGEgZm9ybWFjacOzbiB5IGxhIHJlbXVuZXJhY2nDs24sIHkgc2kgaW1wYWN0YSB0YW1iacOpbiBlbCB0aXBvIGRlIHVuaXZlcnNpZGFkLCBww7pibGljYSBvIHByaXZhZGEsIGVuIGxhIHJlbXVuZXJhY2nDs24geSBwb3NpY2nDs24uIFByaW1lcm8gdmVhbW9zIGVudHJlIGxvcyBkaXN0aW50b3MgcGHDrXNlcyBjb21vIHNlIGRpc3RyaWJ1eWUgbGEgbXVlc3RyYSBlbnRyZSBwcm9mZXNpb25hbGVzIHByb3ZlbmllbnRlcyBkZSB1bml2ZXJzaWRhZGVzIHDDumJsaWNhcyB5IHByaXZhZGFzLg0KDQpEYWRvIHF1ZSB0ZW5lbW9zIHJlbGF0aXZhbWVudGUgcG9jYXMgcmVzcHVlc3RhcyBkZSBvdHJvcyBwYcOtc2VzIHF1ZSBubyBzZWFuIEFyZ2VudGluYSwgbm8gcG9kZW1vcyBzYWNhciBuaW5ndW5hIGNvbmNsdXNpw7NuIHNlcmlhLCBzw7NsbyBtZW5jaW9uYXIgcXVlIGVuIEFyZ2VudGluYSwgaGF5IHVuYSB2aXJ0dWFsIHBhcmlkYWQgZW50cmUgbG9zIGVzdHVkaWFudGVzIHkgZ3JhZHVhZG9zIGRlIHVuaXZlcnNpZGFkZXMgcMO6YmxpY2FzIHkgcHJpdmFkYXMuIFBvc3Rlcmlvcm1lbnRlIGFuYWxpemFyZW1vcyBsYSBzaXR1YWNpw7NuIHBvciByZWdpb25lcyBkZW50cm8gZGVsIHBhw61zLg0KDQpMYXMgcHJvcG9yY2lvbmVzIGRlIHJlc3B1ZXN0YXMgc2Vnw7puIGFsIHRpcG8gZGUgdW5pdmVyc2lkYWQgcXVlIGFzaXN0aWVyb24gbG9zIHBhcnRpY2lwYW50ZXMgZGUgbGEgZW5jdWVzdGEgZXMgbGEgc2lndWllbnRlOg0KDQpgYGB7ciB0aXBvX3VuaXZlcnNpZGFkLCBmaWcuc2hvdz0iaG9sZCIsIG91dC53aWR0aD0iNTAlIiwgZmlnLmFsaWduID0gImRlZmF1bHQifQ0Ka2l3aSAlPiUgDQogIHNlbGVjdChwYWlzLCB0aXBvX3VuaXZlcnNpZGFkKSAlPiUgDQogIGdyb3VwX2J5KHBhaXMsIHRpcG9fdW5pdmVyc2lkYWQpICU+JSANCiAgc3VtbWFyaXNlKGNhbnQgPSBuKCkpICU+JSANCiAgdHJhbnNtdXRlKHRpcG9fdW5pdmVyc2lkYWQsIHBvcmNlbnRhamUgPSBjYW50L3N1bShjYW50KSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHkgPSBmY3RfcmV2KHBhaXMpLA0KICAgICAgICAgICAgIHggPSBwb3JjZW50YWplLA0KICAgICAgICAgICAgIGZpbGwgPSB0aXBvX3VuaXZlcnNpZGFkKSkgKw0KICAgICAgICAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIikgKyANCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhncmlzLCB2ZXJkZSwgYXp1bCkpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnQocG9yY2VudGFqZSwgYWNjdXJhY3kgPSAxKSksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9maWxsKDAuNSksDQogICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsDQogICAgICAgICAgICBmb250ZmFjZSA9ICJib2xkIiwNCiAgICAgICAgICAgIHNpemUgPSAzKSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVjacOzbiBkZSByZXNwdWVzdGFzIHBvciB0aXBvIGRlIHVuaXZlcnNpZGFkIHBvciBwYcOtcyIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSwNCiAgICAgICB4ID0gIiIsIHkgPSAiIikgKw0KICBlc3RpbG8gKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgZWplX3hfcA0KDQoNCmVkdWMgPC0ga2l3aSAlPiUgDQogIHNlbGVjdCh0aXBvX3VuaXZlcnNpZGFkKSAlPiUgIA0KICBncm91cF9ieSh0aXBvX3VuaXZlcnNpZGFkKSAlPiUgDQogIHN1bW1hcmlzZSAobiA9IG4oKSkgJT4lIA0KICBtdXRhdGUoZnJlcSA9IG4vc3VtKG4pKSAlPiUgDQogIGFycmFuZ2UoLW4pDQoNCiMgQ29tcHV0ZSB0aGUgY3VtdWxhdGl2ZSBwZXJjZW50YWdlcyAodG9wIG9mIGVhY2ggcmVjdGFuZ2xlKQ0KZWR1YyR5bWF4IDwtIGN1bXN1bShlZHVjJGZyZXEpDQoNCiMgQ29tcHV0ZSB0aGUgYm90dG9tIG9mIGVhY2ggcmVjdGFuZ2xlDQplZHVjJHltaW4gPC0gYygwLCBoZWFkKGVkdWMkeW1heCwgbj0tMSkpDQoNCiMgQ29tcHV0ZSBsYWJlbCBwb3NpdGlvbg0KZWR1YyRsYWJlbFBvc2l0aW9uIDwtIChlZHVjJHltYXggKyBlZHVjJHltaW4pIC8gMg0KDQojIENvbXB1dGUgYSBnb29kIGxhYmVsDQplZHVjJGxhYmVsIDwtIHBhc3RlMChlZHVjJHRpcG9fdW5pdmVyc2lkYWQsICJcbiBDYW50OiAiLCBlZHVjJG4pDQoNCiMgTWFrZSB0aGUgcGxvdA0KZ2dwbG90KGVkdWMsIGFlcyh5bWF4PXltYXgsIHltaW49eW1pbiwgeG1heD00LCB4bWluPTMsIGZpbGw9dGlwb191bml2ZXJzaWRhZCkpICsNCiAgZ2VvbV9yZWN0KCkgKw0KICBjb29yZF9wb2xhcih0aGV0YT0ieSIpICsgIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gdW5kZXJzdGFuZCBob3cgdGhlIGNoYXJ0IGlzIGJ1aWx0IGluaXRpYWxseQ0KICB4bGltKGMoMiwgNCkpICsjIFRyeSB0byByZW1vdmUgdGhhdCB0byBzZWUgaG93IHRvIG1ha2UgYSBwaWUgY2hhcnQNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhncmlzLCB2ZXJkZSwgYXp1bCkpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiUm9ib3RvIikpICsNCiAgbGFicyh0aXRsZSA9ICJUaXBvIGRlIFVuaXZlcnNpZGFkIiwNCiAgICAgICBmaWxsID0gIlRpcG8gZGUgVW5pdmVyc2lkYWQiLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJsZWZ0IikNCmBgYA0KDQpMYXMgcHJpbmNpcGFsZXMgY2FycmVyYXMgZGUgbGFzIHBlcnNvbmFzIHF1ZSByZXNwb25kaWVyb24gc29uOg0KDQpgYGB7ciBjYXJyZXJhc30NCmNhcnJlcmFzIDwtIGtpd2kgJT4lIA0KICBzZWxlY3Qobml2ZWxfZm9ybWFjaW9uLCBjYXJyZXJhX2dyYWRvLCB0aXBvX3VuaXZlcnNpZGFkLCB0cmFiYWpvLCANCiAgICAgICAgIHN1ZWxkb19icnV0bywgcHVlc3RvLCBmdW5jaW9uLCBwYWlzLCBnZW5lcm8pICU+JSANCiAgZmlsdGVyKHRyYWJham8gPT0gIlJlbGFjacOzbiBkZSBEZXBlbmRlbmNpYSIpICU+JSANCiAgbXV0YXRlKGNhcnJlcmFfZ3JhZG8gPSBmYWN0b3IoY2FycmVyYV9ncmFkbykpDQoNCg0KY2FycmVyYXMgPC0gY2FycmVyYXMgJT4lIA0KICBtdXRhdGUoY2FycmVyYV9ncmFkbyA9IGZjdF9jb2xsYXBzZShjYXJyZXJhX2dyYWRvLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNvbXVuaWNhY2nDs24gU29jaWFsIiA9IGMoIkNvbXVuaWNhY2nDs24iLCAiQ29tdW5pY2FjacOzbiBzb2NpYWwiLCAiQ29tdW5pY2FjacOzbiBTb2NpYWwiLCAiY29tdW5pY2FjaW9uIHNvY2lhbCIsICJDb211bmljYWNpw7NuIEluc3RpdHVjaW9uYWwiLCAiQ29tdW5pY2FjacOzbiBTb2NpYWwgSW5zdGl0dWNpb25hbCIpLA0KICAgICAgICAgIkluZ2VuaWVyw61hcyIgPSBjKCJJbmdlbmllcsOtYSBDb21lcmNpYWwiLCJJbmdlbmllcmlhIEVsZWN0cm9uaWNhIiwgIkluZ2VuaWVyw61hIEluZHVzdHJpYWwiKSwNCiAgICAgICAgICJTaXN0ZW1hcyIgPSBjKCJBbsOhbGlzaXMgU2lzdGVtYXMiLCAiU2lzdGVtYXMiKSwNCiAgICAgICAgICJBZG1pbmlzdHJhY2nDs24gZGUgRW1wcmVzYXMiID0gYygiQWRtaW5pc3RyYWNpw7NuIGRlIEVtcHJlc2FzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBZG1pbmlzdHJhY2nDs24gSW5kdXN0cmlhbCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWRtaW5pc3RyYWNpw7NuIHkgUmVjdXJzb3MgSHVtYW5vcyIpLA0KICAgICAgICAgIkFib2dhY8OtYSIgPSBjKCJBYm9nYWPDrWEiLCAiRGVyZWNobywgSFIgeSBFc2NyaWJhbmlhIiksDQogICAgICAgICAiUlJISCAvIFJSTEwgLyBSUlRUIiA9IGMoIlJlbGFjaW9uZXMgTGFib3JhbGVzIHkgQWJvZ2FjaWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSUkhIIC8gUlJMTCAvIFJSVFQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSUlRUICsgQWJvZ2FkbyBVQkEiKSksDQogICAgICAgICBjYXJyZXJhX2dyYWRvID0gZmN0X2x1bXAoY2FycmVyYV9ncmFkbywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcCA9IDAuMDIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG90aGVyX2xldmVsID0gIk90cmFzIiksDQogICAgICAgICBjYXJyZXJhX2dyYWRvID0gZmFjdG9yKGNhcnJlcmFfZ3JhZG8sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiUlJISCAvIFJSTEwgLyBSUlRUIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHNpY29sb2fDrWEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBZG1pbmlzdHJhY2nDs24gZGUgRW1wcmVzYXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkluZ2VuaWVyw61hcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3RyYXMiKSkpDQoNCg0KDQpjYXJyZXJhcyAlPiUgDQogIGdyb3VwX2J5KGNhcnJlcmFfZ3JhZG8pICU+JSANCiAgc3VtbWFyaXNlKGNhbnQgPSBuKCkpICU+JQ0KICB1bmdyb3VwKCkgJT4lIA0KZ2dwbG90KGFlcyh4ID0gY2FudCwgeSA9IGZjdF9yZXYoY2FycmVyYV9ncmFkbykpKSArIA0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIsIGZpbGwgPSBhenVsKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjYW50KSwNCiAgICAgICAgICAgIHNpemUgPSAzLA0KICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICAgZmFjZWZvbnQgPSAiYm9sZCIsDQogICAgICAgICAgICBoanVzdCA9IDEuMikgKw0KICBsYWJzKHg9IiIseT0iIikgKw0KICBlc3RpbG92ICsNCiAgbGFicyh0aXRsZSA9ICJQcmluY2lwYWxlcyBjYXJyZXJhcyBlc3R1ZGlhZGFzIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJUcmFiYWphZG9yZXMgZW4gcmVsYWNpw7NuIGRlIGRlcGVuZGVuY2lhIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KDQpgYGANCg0KRGFkYSBsYSBjYW50aWRhZCBkZSByZXNwdWVzdGFzIHBvciBwYcOtcywgZWwgYW7DoWxpc2lzIHF1ZSBoYXJlbW9zIGRlc2RlIGFxdcOtIGVuIGFkZWxhbnRlIHPDs2xvIHNlcsOhIHBhcmEgKipBcmdlbnRpbmEqKi4NCg0KIyMgQW7DoWxpc2lzIGRlIGVkdWNhY2nDs24geSBwdWVzdG9zIHBhcmEgQXJnZW50aW5hDQoNCkx1ZWdvLCBwb2RlbW9zIGFuYWxpemFyIGVuIHF1w6kgdGlwbyBkZSB1bml2ZXJzaWRhZCBlc3R1ZGlhcm9uIGxhcyBwZXJzb25hcyBxdWUgcmVzcG9uZGllcm9uIGxhIGVuY3Vlc3RhLCBzZWfDum4gZWwgcHVlc3RvIGFjdHVhbCBxdWUgb2N1cGFuLg0KDQpgYGB7ciBwdWVzdG8tdW5pdmVyc2lkYWR9DQpyZWNvcnRlX2VkdWNhY2lvbiA8LSByaDIybGEgJT4lDQogIGZpbHRlcihwYWlzID09ICJBcmdlbnRpbmEiKSAlPiUgDQogIHNlbGVjdChuaXZlbF9mb3JtYWNpb24sIGNhcnJlcmFfZ3JhZG8sDQogICAgICAgICB0aXBvX3VuaXZlcnNpZGFkLCB0cmFiYWpvLCBzdWVsZG9fYnJ1dG8sIHB1ZXN0bywgZnVuY2lvbiwgcGFpcywgZ2VuZXJvKQ0KDQpnZ3Bsb3QocmVjb3J0ZV9lZHVjYWNpb24sIChhZXMoeCA9IHB1ZXN0bywgZmlsbCA9IHRpcG9fdW5pdmVyc2lkYWQpKSkgKyAjVGlwbyBkZSB1bml2ZXJzaWRhZCB5IGNhcmdvDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICB0aGVtZShwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiKSArIA0KICBsYWJzKHg9IiIseT0iIikgKw0KICAgIGVzdGlsb3YgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKGdyaXMsIHZlcmRlLCBhenVsKSkgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgc2Vnw7puIHB1ZXN0byB5IHVuaXZlcnNpZGFkIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJTw7NsbyByZXNwdWVzdGFzIGRlIEFyZ2VudGluYSIsDQogICAgICAgeCA9ICIiLCBmaWxsID0gIlRpcG8gZGUgVW5pdmVyc2lkYWQiLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpICsNCiAgICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlPVRSVUUpKSAgIyBJbnZpZXJ0ZSBlbCBvcmRlbiBkZSBsb3MgY29sb3JlcyBlbiBsYSBsZXllbmRhDQoNCmBgYA0KDQpSZWl0ZXJlbW9zIGVsIGFuw6FsaXNpcyBwZXJvIMO6bmljYW1lbnRlIHBhcmEgbGFzIGNhcnJlcmFzIHJlbGFjaW9uYWRhcyBjb24gUmVjdXJzb3MgSHVtYW5vcyB5IFJlbGFjaW9uZXMgZGVsIFRyYWJham8uDQoNCmBgYHtyIHJoLXBzaWNvfQ0KcmVjb3J0ZV9lZHVjYWNpb24gJT4lDQogIGZpbHRlcihjYXJyZXJhX2dyYWRvID09ICJSUkhIIC8gUlJMTCAvIFJSVFQiKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHB1ZXN0bywgZmlsbCA9IHRpcG9fdW5pdmVyc2lkYWQpKSArICNUaXBvIGRlIHVuaXZlcnNpZGFkIHkgY2FyZ28NCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIHRoZW1lKHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIpICsgDQogIGxhYnMoeD0iIix5PSIiKSArDQogICAgZXN0aWxvdiArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoZ3JpcywgdmVyZGUsIGF6dWwpKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiQ2FudGlkYWQgZGUgcmVzcHVlc3RhcyBzZWfDum4gcHVlc3RvIHkgdW5pdmVyc2lkYWQiLA0KICAgICAgIHN1YnRpdGxlID0gIlPDs2xvIHJlc3B1ZXN0YXMgZGUgQXJnZW50aW5hIC0gQ2FycmVyYXMgZGUgUkgiLA0KICAgICAgIHggPSAiIiwgZmlsbCA9ICJUaXBvIGRlIFVuaXZlcnNpZGFkIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogICAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZT1UUlVFKSkgICMgSW52aWVydGUgZWwgb3JkZW4gZGUgbG9zIGNvbG9yZXMgZW4gbGEgbGV5ZW5kYQ0KDQogIA0KDQpgYGANCg0KUG9kZW1vcyBhcHJlY2lhciBxdWUgYSBwYXJ0aXIgZGUgbG9zIHB1ZXN0b3MgZGUgamVmYXR1cmEsIGhheSBtYXlvciBwcmVzZW5jaWEgZGUgZ3JhZHVhZG9zIHByb3ZlbmllbnRlcyBkZSB1bml2ZXJzaWRhZGVzIHByaXZhZGFzLg0KDQpFbiBBcmdlbnRpbmEsIHBvZGVtb3MgdmVyIGxhIHNpZ3VpZW50ZSBkaXN0cmlidWNpw7NuIHBvciBnw6luZXJvIHkgbml2ZWwgZWR1Y2F0aXZvLg0KDQpgYGB7ciBuaXZlbC1lZC1nZW5lcm99DQoNCm5lX3NhbGFyaW8gPC0gcmVjb3J0ZV9lZHVjYWNpb24gDQoNCg0KIyBBZ3J1cGEgY2F0ZWdvcsOtYXMgZGUgZWR1Y2FjacOzbg0KbmVfc2FsYXJpbyA8LSBuZV9zYWxhcmlvICU+JSANCiAgICBtdXRhdGUobml2ZWxfZm9ybWFjaW9uID0gDQogICAgICAgICAgICAgZmN0X2NvbGxhcHNlKG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNlY3VuZGFyaW8gY29tcGxldG8iID0gYygiU2VjdW5kYXJpbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRlcmNpYXJpbyBlbiBjdXJzbyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUZXJjaWFyaW8gYWJhbmRvbmFkbyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuaXZlcnNpdGFyaW8gYWJhbmRvbmFkbyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpbyBjb21wbGV0byIgPSBjKCJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFlc3Ryw61hIGFiYW5kb25hZGEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWVzdHLDrWEgbyBzdXBlcmlvciBhYmFuZG9uYWRhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGFiYW5kb25hZG8iKSksDQogICAgICAgICBuaXZlbF9mb3JtYWNpb24gPSBmY3RfcmVjb2RlKG5pdmVsX2Zvcm1hY2lvbiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXBsb21hZG8gY29tcGxldG8iID0gIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXBsb21hZG8gZW4gY3Vyc28iID0gIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBlbiBjdXJzbyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWVzdHLDrWEgZW4gY3Vyc28iID0gIk1hZXN0csOtYSBvIHN1cGVyaW9yIGVuIGN1cnNvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hZXN0csOtYSBjb21wbGV0YSIgPSAiTWFlc3Ryw61hIG8gc3VwZXJpb3IgY29tcGxldGEiKSkgDQoNCm5lX3NhbGFyaW8gJT4lIA0KICBzZWxlY3QocGFpcywgbml2ZWxfZm9ybWFjaW9uLCBnZW5lcm8sIHB1ZXN0bykgJT4lDQogIGZpbHRlcihnZW5lcm8gJWluJSBjKCJNdWplciBjaXMiLCAiSG9tYnJlIGNpcyIpLA0KICAgICAgICAgIWlzLm5hKG5pdmVsX2Zvcm1hY2lvbikpICU+JQ0KICBtdXRhdGUobml2ZWxfZm9ybWFjaW9uID0gZmFjdG9yKG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJTZWN1bmRhcmlvIGNvbXBsZXRvIiwgIlRlcmNpYXJpbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpbyBlbiBjdXJzbyIsICJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXBsb21hZG8gZW4gY3Vyc28iLCJEaXBsb21hZG8gY29tcGxldG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hZXN0csOtYSBlbiBjdXJzbyIsIk1hZXN0csOtYSBjb21wbGV0YSIpKSkgJT4lIA0KICBncm91cF9ieShuaXZlbF9mb3JtYWNpb24sIGdlbmVybykgJT4lDQogIHN1bW1hcmlzZShjYW50ID0gbigpKSAlPiUgDQogIHRyYW5zbXV0ZShnZW5lcm8sIHBvcmNlbnRhamUgPSBjYW50L3N1bShjYW50KSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBnZ3Bsb3QoYWVzICh5PSBuaXZlbF9mb3JtYWNpb24sIHggPSBwb3JjZW50YWplLCBmaWxsID0gZ2VuZXJvKSkgKyANCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnQocG9yY2VudGFqZSwgYWNjdXJhY3kgPSAxKSksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ZpbGwoMC41KSwNCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwNCiAgICAgICAgICAgIHNpemUgPSAzLA0KICAgICAgICAgICAgZm9udGZhY2UgPSAiYm9sZCIpKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKHZlcmRlLCBsaWxhKSkgKw0KICBlc3RpbG92ICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgIHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIpICsNCiAgbGFicyh0aXRsZSA9ICJNw6F4aW1vIG5pdmVsIGVkdWNhdGl2byBhbGNhbnphZG8gcG9yIGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gcG9yIGZyZWN1ZW5jaWFzIGFic29sdXRhcyIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSwgDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgICAgIGZpbGwgPSAiR8OpbmVybyIpICsNCiAgZWplX3hfcCArDQogICAgICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlPVRSVUUpKSAgIyBJbnZpZXJ0ZSBlbCBvcmRlbiBkZSBsb3MgY29sb3JlcyBlbiBsYSBsZXllbmRhDQoNCg0KYGBgDQoNCkVuIHTDqXJtaW5vcyBhYnNvbHV0b3MsIGxhcyBtdWplcmVzIGdyYWR1YWRhcyByZXByZXNlbnRhbiBtw6FzIGRlbCA3NSUgZGUgbGEgbXVlc3RyYS4gQW5hbGljZW1vcyBlc3RvcyBkYXRvcyBlbiB0w6lybWlub3MgcmVsYXRpdm9zLiBQcsOhY3RpY2FtZW50ZSBlbCBwYXRyw7NuIGRlIG5pdmVsIGVkdWNhdGl2byBlbnRyZSBob21icmVzIHkgbXVqZXJlcyBlcyBpZMOpbnRpY28uDQoNCkRlIGFjdWVyZG8gYSBsYSBtdWVzdHJhIHJlY29sZWN0YWRhLCBsYXMgbXVqZXJlcyBzZSBmb3JtYW4gZW4gbWF5b3IgcHJvcG9yY2nDs24gcXVlIGxvcyBob21icmVzIGNpcy4NCg0KYGBge3Igbml2ZWwtZWQtZ2VuZXJvLXJlbH0NCm5lX2ZlbSA8LSBuZV9zYWxhcmlvICU+JSANCiAgZmlsdGVyKGdlbmVybyA9PSAiTXVqZXIgY2lzIikgJT4lIA0KICBncm91cF9ieShnZW5lcm8sIG5pdmVsX2Zvcm1hY2lvbikgJT4lIA0KICBtdXRhdGUobml2ZWxfZm9ybWFjaW9uID0gZmFjdG9yKG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJTZWN1bmRhcmlvIGNvbXBsZXRvIiwgIlRlcmNpYXJpbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpbyBlbiBjdXJzbyIsICJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXBsb21hZG8gZW4gY3Vyc28iLCJEaXBsb21hZG8gY29tcGxldG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hZXN0csOtYSBlbiBjdXJzbyIsIk1hZXN0csOtYSBjb21wbGV0YSIpKSkgJT4lIA0KICBncm91cF9ieShuaXZlbF9mb3JtYWNpb24pICU+JSANCiAgc3VtbWFyaXNlKG4gPSBuKCkpICU+JSANCiAgbXV0YXRlKGZyZWN1ZW5jaWEgPSByb3VuZChuL3N1bShuKSwyKSwNCiAgICAgICAgIGdlbmVybyA9ICJNdWplciBjaXMiKSANCg0KbmVfbWFzIDwtIG5lX3NhbGFyaW8gJT4lIA0KICBmaWx0ZXIoZ2VuZXJvID09ICJIb21icmUgY2lzIikgJT4lIA0KICBncm91cF9ieShnZW5lcm8sIG5pdmVsX2Zvcm1hY2lvbikgJT4lIA0KICBtdXRhdGUobml2ZWxfZm9ybWFjaW9uID0gZmFjdG9yKG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJTZWN1bmRhcmlvIGNvbXBsZXRvIiwgIlRlcmNpYXJpbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpbyBlbiBjdXJzbyIsICJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXBsb21hZG8gZW4gY3Vyc28iLCJEaXBsb21hZG8gY29tcGxldG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hZXN0csOtYSBlbiBjdXJzbyIsIk1hZXN0csOtYSBjb21wbGV0YSIpKSkgJT4lIA0KICBncm91cF9ieShuaXZlbF9mb3JtYWNpb24pICU+JSANCiAgc3VtbWFyaXNlKG4gPSBuKCkpICU+JSANCiAgbXV0YXRlKGZyZWN1ZW5jaWEgPSByb3VuZChuL3N1bShuKSwyKSwNCiAgICAgICAgIGdlbmVybyA9ICJIb21icmUgY2lzIikgDQoNCm5lX3RvdGFsIDwtIHJiaW5kKG5lX2ZlbSwgbmVfbWFzKQ0KDQpnZ3Bsb3QobmVfdG90YWwsIGFlcyh4ID0gbml2ZWxfZm9ybWFjaW9uLCB5ID0gZnJlY3VlbmNpYSwgZmlsbCA9IGdlbmVybykpICsNCiAgZ2VvbV9jb2woKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApLCANCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArIA0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcmVzKSArDQogIGZhY2V0X3dyYXAofmdlbmVybywgbmNvbCA9IDIpICsNCiAgZXN0aWxvaCArDQogIGVqZV95X3AgKw0KICBsYWJzKHRpdGxlID0gIlByb3BvcmNpw7NuIGRlIG5pdmVsIGVkdWNhdGl2byBtw6F4aW1vIHBvciBnw6luZXJvIiwNCiAgICAgICB4ID0gIiIsIHkgPSAiUHJvcG9yY2nDs24iLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KDQpgYGANCg0KQWhvcmEgdmVhbW9zIGNvbW8gc2UgZGlzdHJpYnV5ZW4gbG9zIHB1ZXN0b3Mgc2Vnw7puIGVsIGfDqW5lcm8geSBlbCBuaXZlbCBlZHVjYXRpdm8uDQoNCmBgYHtyIHB1ZXN0b3Mtbml2ZWwtZWQsIGZpZy5oZWlnaHQ9OH0NCm5lX3NhbGFyaW8gJT4lIA0KICBzZWxlY3QocGFpcywgbml2ZWxfZm9ybWFjaW9uLCBnZW5lcm8sIHB1ZXN0bykgJT4lDQogIGZpbHRlcihnZW5lcm8gJWluJSBjKCJNdWplciBjaXMiLCAiSG9tYnJlIGNpcyIpLA0KICAgICAgICAgcHVlc3RvICE9ICJQYXNhbnRlIiwgcHVlc3RvICE9ICJEaXJlY3RvciIpICU+JQ0KICBtdXRhdGUobml2ZWxfZm9ybWFjaW9uID0gZmFjdG9yKG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJTZWN1bmRhcmlvIGNvbXBsZXRvIiwgIlRlcmNpYXJpbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpbyBlbiBjdXJzbyIsICJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXBsb21hZG8gZW4gY3Vyc28iLCJEaXBsb21hZG8gY29tcGxldG8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWVzdHLDrWEgZW4gY3Vyc28iLCJNYWVzdHLDrWEgY29tcGxldGEiKSksDQogICAgICAgICBwdWVzdG8gPSBmYWN0b3IocHVlc3RvLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJEaXJlY3RvciIsICJHZXJlbnRlIiwgIkplZmUiLCAiUmVzcG9uc2FibGUiLCAiSFJCUCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQW5hbGlzdGEiLCAiQWRtaW5pc3RyYXRpdm8iKSkpICU+JSANCiAgZ3JvdXBfYnkobml2ZWxfZm9ybWFjaW9uKSAlPiUgDQogIGdncGxvdChhZXMgKHk9IG5pdmVsX2Zvcm1hY2lvbiwgZmlsbCA9IGdlbmVybykpICsgDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArDQogIGxhYnMoeD0iIix5PSIiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGModmVyZGUsIGxpbGEpKSArDQogIGVzdGlsbyArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgICBwbG90LnRpdGxlLnBvc2l0aW9uID0gInBsb3QiKSArDQogIGxhYnModGl0bGUgPSAiTml2ZWwgZWR1Y2F0aXZvIHBvciBwdWVzdG8geSBnw6luZXJvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEaXN0cmlidWNpw7NuIHBvciBmcmVjdWVuY2lhcyBhYnNvbHV0YXMiLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUsIA0KICAgICAgIGZpbGwgPSAiR8OpbmVybyIpICsNCiAgZWplX3hfcCArDQogIGZhY2V0X3dyYXAofnB1ZXN0bywgbmNvbCA9IDMpICsgDQogICAgICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlPVRSVUUpKSAgIyBJbnZpZXJ0ZSBlbCBvcmRlbiBkZSBsb3MgY29sb3JlcyBlbiBsYSBsZXllbmRhDQoNCg0KYGBgDQoNCg0KIyMgQW7DoWxpc2lzIGRlIHN1ZWxkb3MgeSBlZHVjYWNpw7NuIGVuIEFyZ2VudGluYQ0KDQpFbiBlc3RhIHNlY2Npw7NuIGFuYWxpemFyZW1vcyBsb3Mgc3VlbGRvcyBlbiBjb21wYXJhY2nDs24gY29uIGxvcyBkaXN0aW50b3Mgbml2ZWxlcyBlZHVjYXRpdm9zLg0KDQpBIGRpZmVyZW5jaWEgZGUgb3RyYXMgc2VjY2lvbmVzLCBlbiBlc3RlIGNhc28gY29tcGFyYXJlbW9zIGxhICptZWRpYSBzYWxhcmlhbCogcGFyYSBwb2RlciBvYnNlcnZhciBsb3MgZGVzdsOtb3MgZXN0w6FuZGFyIGVuIGxvcyBhbsOhbGlzaXMuIEVuIHByaW1lciBsdWdhciBhbmFsaWNlbW9zIGN1w6FsIGVzIGVsIHN1ZWxkbyBwcm9tZWRpbyBkZSBhY3VlcmRvIGEgbG9zIGRpc3RpbnRvcyBuaXZlbGVzIGVkdWNhdGl2b3MuDQoNClByaW1lcm8gdmVhbW9zIGN1w6FsIGVzIGVsIHN1ZWxkbyBwcm9tZWRpbyBlbiBwZXNvcyBhcmdlbnRpbm9zLCBzZWfDum4gZWwgbml2ZWwgZWR1Y2F0aXZvLg0KDQpgYGB7ciBzdWVsZG8tZWR1Y30NCmVzdHVkaW9zIDwtIHJoMjJsYSAlPiUgDQogIGZpbHRlcihwYWlzID09ICJBcmdlbnRpbmEiKSAlPiUgDQogIHNlbGVjdChnZW5lcm8sIG5pdmVsX2Zvcm1hY2lvbiwgc3VlbGRvX2JydXRvKQ0KICAgIA0KICANCmVzdF9hciAgPC0gcHJvZmlsaW5nX251bShlc3R1ZGlvcykNCmVzX3AwNSA8LSBlc3RfYXJbMSw2XQ0KZXNfcDk1IDwtIGVzdF9hclsxLDEwXQ0KDQpybShlc3RfYXIpDQoNCnJoMjJsYSAlPiUgDQogIGZpbHRlcihwYWlzID09ICJBcmdlbnRpbmEiLCANCiAgICAgICAgIGJldHdlZW4oc3VlbGRvX2JydXRvLCBlc19wMDUsIGVzX3A5NSkpICU+JSANCiAgICAgIG11dGF0ZShuaXZlbF9mb3JtYWNpb24gPSBmY3RfY29sbGFwc2Uobml2ZWxfZm9ybWFjaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZWN1bmRhcmlvIGNvbXBsZXRvIiA9IGMoIlNlY3VuZGFyaW8gY29tcGxldG8iLCAiVGVyY2lhcmlvIGVuIGN1cnNvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUZXJjaWFyaW8gYWJhbmRvbmFkbyIsICJVbml2ZXJzaXRhcmlvIGFiYW5kb25hZG8iKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpbyBjb21wbGV0byIgPSBjKCJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwgIk1hZXN0csOtYSBhYmFuZG9uYWRhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGFiYW5kb25hZG8iKSksDQogICAgICAgICBuaXZlbF9mb3JtYWNpb24gPSBmY3RfcmVjb2RlKG5pdmVsX2Zvcm1hY2lvbiwgIkRpcGxvbWFkbyBjb21wbGV0byIgPSAiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpcGxvbWFkbyBlbiBjdXJzbyIgPSAiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGVuIGN1cnNvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hZXN0csOtYSBlbiBjdXJzbyIgPSAiTWFlc3Ryw61hIG8gc3VwZXJpb3IgZW4gY3Vyc28iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFlc3Ryw61hIGNvbXBsZXRhIiA9ICJNYWVzdHLDrWEgbyBzdXBlcmlvciBjb21wbGV0YSIpKSAlPiUgDQogICAgbXV0YXRlKG5pdmVsX2Zvcm1hY2lvbiA9IGZhY3RvcihuaXZlbF9mb3JtYWNpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiU2VjdW5kYXJpbyBjb21wbGV0byIsICJUZXJjaWFyaW8gY29tcGxldG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuaXZlcnNpdGFyaW8gZW4gY3Vyc28iLCAiVW5pdmVyc2l0YXJpbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlwbG9tYWRvIGVuIGN1cnNvIiwgIkRpcGxvbWFkbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFlc3Ryw61hIGVuIGN1cnNvIiwiTWFlc3Ryw61hIGNvbXBsZXRhIikpKSAlPiUgDQogIGdyb3VwX2J5KG5pdmVsX2Zvcm1hY2lvbikgJT4lIA0KICBzdW1tYXJpc2Uoc3VlbGRvX3Byb21lZGlvID0gbWVhbihzdWVsZG9fYnJ1dG8pKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHN1ZWxkb19wcm9tZWRpbywgeSA9IG5pdmVsX2Zvcm1hY2lvbikpKw0KICBnZW9tX2NvbChmaWxsID0gYXp1bCkrDQpnZW9tX3RleHQoYWVzKGxhYmVsID0gY29tbWEocm91bmQoc3VlbGRvX3Byb21lZGlvLCAwKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaWcubWFyayA9ICIuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCA9ICJBUiQgIiksDQogICAgICAgICAgICBoanVzdCA9IDEuMiwgZm9udGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLA0KICAgICAgICAgICAgc2l6ZSA9IDMsIGNvbG9yID0gIndoaXRlIiwNCiAgICAgICAgICAgIGZhbWlseSA9ICJSb2JvdG8iKSArDQogIGVzdGlsb3YgKw0KICBlamVfeF9uICsNCiAgbGFicyh0aXRsZSA9ICJTdWVsZG8gcHJvbWVkaW8gcG9yIG5pdmVsIGRlIGZvcm1hY2nDs24iLA0KICAgICAgIHN1YnRpdGxlID0gIkVuIEFSJCIsDQogICAgICAgeD0iIiwgeT0iIiwgY2FwdGlvbiA9IGZ1ZW50ZSkNCg0KICANCg0KYGBgDQoNCkFob3JhIHZlYW1vcyBxdcOpIHBhc2Egc2kgaW5jbHVpbW9zIGVuIGVsIGFuw6FsaXNpcyBlbCBnw6luZXJvIHBhcmEgYW5hbGl6YXIgbG9zIHN1ZWxkb3MgcHJvbWVkaW9zIHkgc3VzIGRlc3bDrW9zIGVzdMOhbmRhci4NCg0KYGBge3Igc3VlbGRvLWVkdWMtZ2VuZXJvfQ0KcmgyMmxhICU+JSANCiAgZmlsdGVyKHBhaXMgPT0gIkFyZ2VudGluYSIsIA0KICAgICAgICAgYmV0d2VlbihzdWVsZG9fYnJ1dG8sIGVzX3AwNSwgZXNfcDk1KSkgJT4lIA0KICAgICAgbXV0YXRlKG5pdmVsX2Zvcm1hY2lvbiA9IA0KICAgICAgICAgICAgICAgZmN0X2NvbGxhcHNlKG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2VjdW5kYXJpbyBjb21wbGV0byIgPSBjKCJTZWN1bmRhcmlvIGNvbXBsZXRvIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVGVyY2lhcmlvIGVuIGN1cnNvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUZXJjaWFyaW8gYWJhbmRvbmFkbyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuaXZlcnNpdGFyaW8gYWJhbmRvbmFkbyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiA9IGMoIlVuaXZlcnNpdGFyaW8gY29tcGxldG8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWVzdHLDrWEgbyBzdXBlcmlvciBhYmFuZG9uYWRhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGFiYW5kb25hZG8iKSksDQogICAgICAgICBuaXZlbF9mb3JtYWNpb24gPSBmY3RfcmVjb2RlKG5pdmVsX2Zvcm1hY2lvbiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXBsb21hZG8gY29tcGxldG8iID0gIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBjb21wbGV0byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXBsb21hZG8gZW4gY3Vyc28iID0gIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBlbiBjdXJzbyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWVzdHLDrWEgZW4gY3Vyc28iID0gIk1hZXN0csOtYSBvIHN1cGVyaW9yIGVuIGN1cnNvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hZXN0csOtYSBjb21wbGV0YSIgPSAiTWFlc3Ryw61hIG8gc3VwZXJpb3IgY29tcGxldGEiKSkgJT4lIA0KICAgIG11dGF0ZShuaXZlbF9mb3JtYWNpb24gPSBmYWN0b3Iobml2ZWxfZm9ybWFjaW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlNlY3VuZGFyaW8gY29tcGxldG8iLCAiVGVyY2lhcmlvIGNvbXBsZXRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbml2ZXJzaXRhcmlvIGVuIGN1cnNvIiwgIlVuaXZlcnNpdGFyaW8gY29tcGxldG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpcGxvbWFkbyBlbiBjdXJzbyIsICJEaXBsb21hZG8gY29tcGxldG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hZXN0csOtYSBlbiBjdXJzbyIsIk1hZXN0csOtYSBjb21wbGV0YSIpKSkgJT4lIA0KICBncm91cF9ieShuaXZlbF9mb3JtYWNpb24sIGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2Uoc2FsYXJpb3MgPSBsaXN0KG1lYW5fc2Uoc3VlbGRvX2JydXRvKSkpICU+JSANCiAgdW5uZXN0KHNhbGFyaW9zKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG5pdmVsX2Zvcm1hY2lvbiwgeSA9IHksIGZpbGwgPSBnZW5lcm8pKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikrDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSB5bWluLHltYXggPSB5bWF4KSwgcG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgY29vcmRfZmxpcCgpKw0KICBlamVfeV9uICsNCiAgZXN0aWxvdiArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGModmVyZGUsIGxpbGEsIGFtYXJpbGxvKSkgKw0KICBsYWJzKHRpdGxlID0gIlN1ZWxkbyBwcm9tZWRpbyB5IGRlc3bDrW8gZXN0w6FuZGFyZCBwb3Igbml2ZWwgZGUgZm9ybWFjacOzbiB5IGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkVuIEFSJCIsIA0KICAgICAgIHggPSAiIiwgeSA9ICIiLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlLCANCiAgICAgICBmaWxsID0gIkfDqW5lcm8iKSArICAgICAgDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2U9VFJVRSkpICAjIEludmllcnRlIGVsIG9yZGVuIGRlIGxvcyBjb2xvcmVzIGVuIGxhIGxleWVuZGENCg0KYGBgDQoNCiMgRGl2ZXJzaWRhZCBlbiBSUkhIDQoNCiMjIExpZGVyYXpnbyB5IGfDqW5lcm8gZW4gUlJISA0KDQpBbmFsaWNlbW9zIGxhcyBwcm9wb3JjaW9uZXMgZGUgaG9tYnJlcyB5IGRlIG11amVyZXMgZW4gcHVlc3RvIGRlIGxpZGVyYXpnby4NCg0KYGBge3IgbGlkZXJhemdvLWdlbmVybywgcmVzdWx0cz0naGlkZSd9DQoNCmRpdiA8LSByaDIybGEgJT4lDQogIGZpbHRlcihwYWlzID09ICJBcmdlbnRpbmEiKSAlPiUgDQpzZWxlY3QoZ2VuZXJvKSAlPiUgDQogIG11dGF0ZShnZW5lcm8gPSBmYWN0b3IoZ2VuZXJvLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJNdWplciBjaXMiLCAiSG9tYnJlIGNpcyIpKSkgJT4lIA0KICBncm91cF9ieShnZW5lcm8pICU+JSANCiAgc3VtbWFyaXNlIChuID0gbigpKSAlPiUgDQogIG11dGF0ZShmcmVxID0gbi9zdW0obikpICU+JSANCiAgYXJyYW5nZSgtbikNCg0KbGlkZXJlcyA8LSByaDIybGEgJT4lIA0KICBmaWx0ZXIocGFpcyA9PSAiQXJnZW50aW5hIikgJT4lIA0KIHNlbGVjdChnZW5lcm8sIHB1ZXN0bykgDQoNCiMgUHJvcG9jacOzbiBkZSBsw61kZXJlcyBob21icmVzIHkgbXVqZXJlcw0KbGlkZXJlc19nZW5lcm8gPC0gbGlkZXJlcyAlPiUgDQogIGZpbHRlcihnZW5lcm8gJWluJSBjKCJNdWplciBjaXMiLCAiSG9tYnJlIGNpcyIpKSAlPiUgDQogIGdyb3VwX2J5KGdlbmVybykgJT4lDQogIG11dGF0ZShnZW50ZV9hX2NhcmdvID0gaWZfZWxzZShwdWVzdG8gJWluJSBjKCJSZXNwb25zYWJsZSIsICJKZWZlIiwgIkdlcmVudGUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlN1cGVydmlzb3IiLCAiRGlyZWN0b3IiKSwxLDApKSAlPiUNCiAgc3VtbWFyaXNlKGxpZGVyID0gc3VtKGdlbnRlX2FfY2FyZ28pKSAlPiUgDQogIGxlZnRfam9pbihkaXYpICU+JSANCiAgc2VsZWN0KGdlbmVybywgbGlkZXIsIG4pICU+JSANCiAgbXV0YXRlKHByb3BvcmNpb24gPSBwZXJjZW50KGxpZGVyL24pKQ0KDQojIFRlc3QgZGUgaGlww7N0ZXNpcyBwYXJhIHZhbGlkYXIgZGlmZXJlbmNpYXMgZGUgcmVzdWx0YWRvcw0KIyBIYXkgcXVlIHZlcmlmaWNhciBzaSBsYSBwcm9wb3JjacOzbiBkZSBsw61kZXJlcyBob21icmVzIGVzIG1heW9yIHF1ZSBsYSBwcm9wb3JjacOzbiBkZSBsw61kZXJlcyBtdWplcmVzDQojIENyZW8gdW4gZGF0YWZyYW1lIHBhcmEgYW5hbGl6YXIgcHJvcG9yY2lvbmVzIGRlIGhvbWJyZXMgeSBkZSBtdWplcmVzIGVuIHB1ZXN0b3MgZGUgbGlkZXJhemdvIHkgZGUgbm8tbGlkZXJhemdvDQp0ZXN0X2xpZGVyIDwtIGxpZGVyZXNfZ2VuZXJvICU+JSANCiAgbXV0YXRlKG5vX2xpZGVyID0gbiAtIGxpZGVyKSAlPiUgICAgICAgICMgQ29sdW1uYSBkZSBubyBsw61kZXJlcw0KICBzZWxlY3QoZ2VuZXJvLCBsaWRlciwgbm9fbGlkZXIpICU+JSAgICAgIyBzZWxlY2Npb25vIGNvbHVtbmFzIGRlIGludGVyw6lzDQogIHBpdm90X2xvbmdlcihjb2xzID0gYyhsaWRlciwgbm9fbGlkZXIpLCAjIEhhZ28gdW4gZGF0YXNldCBsYXJnbyBwYXJhIGFuYWxpemFyIGRlc3B1w6lzDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJlc19saWRlciIsIHZhbHVlc190byA9ICJjb250ZW8iKQ0KDQojIERlbCB0b3RhbCBkZSByZXNwdWVzdGFzIG1lIGludGVyZXNhIHPDs2xvIHZlciBjdcOhbGVzIHNvbiBsb3MgaG9tYnJlcyBjb24gcHVlc3RvIGRlIGxpZGVyYXpnbw0KdGVzdF9saWRlciRjYXQgPC0gYygwLDAsMSwwKQ0KDQojIEV4dHJhaWdvIGVsIG11IHBhcmEgZGVjaWRpciBzaSBsYSBkaWZlcmVuY2lhIGVzIHNpZ25pZmljYXRpdmEgeSBwYXNhcmxvIGEgbGEgZsOzcm11bGEgZGVsIHRlc3QuDQpwcm9wX211amVyX2xpZCA8LSBwdWxsKGxpZGVyZXNfZ2VuZXJvWzEsMl0vbGlkZXJlc19nZW5lcm9bMSwzXSkNCg0KIyBSZWFsaXpvIGVsIHRlc3QgZGUgaGlww7N0ZXNpcy4NCiMgSDAgPSBMYXMgcHJvcG9yY2lvbmVzIGRlIGzDrWRlcmVzIGhvbWJyZXMgeSBtdWplcmVzIHNvbiBpZ3VhbGVzDQojIEgxID0gTGEgcHJvcG9yY2nDs24gZGUgaG9tYnJlcyBsw61kZXJlcyBlcyBtYXlvciBxdWUgbGEgcHJvcG9yY2nDs24gZGUgbXVqZXJlcyBsw61kZXJlcy4NCnJlc3VsdGFkb3NfdGVzdCA8LSBicm9vbTo6dGlkeSh0LnRlc3QodGVzdF9saWRlciRjYXQsIG11ID0gcHJvcF9tdWplcl9saWQsIGFsdGVybmF0aXZlID0gImdyZWF0ZXIiKSkNCg0KdmFsb3JfdGVzdCA8LSBpZihyZXN1bHRhZG9zX3Rlc3RbMSwzXSA+IDAuMDUpIHsNCiAgcHJpbnQoImxhIGRpZmVyZW5jaWEgZXMgZXN0YWTDrXN0aWNhbWVudGUgc2lnbmlmaWNhdGl2YSwgeSBsYSBwcm9wb3JjacOzbiBkZSBob21icmVzIGVuIHB1ZXN0b3MgZGUgbGlkZXJhemdvIGVzIG1heW9yIHF1ZSBlbCBkZSBsYXMgbXVqZXJlcyIpDQogIH0gZWxzZSB7DQogICAgcHJpbnQoImxhIGRpZmVyZW5jaWEgbm8gZXMgZXN0YWTDrXN0aWNhbWVudGUgc2lnbmlmaWNhdGl2YSwgeSBsYSBwcm9wb3JjacOzbiBkZSBob21icmVzIG5vIGVzIGVzdGFkw61zdGljYW1lbnRlIG1heW9yIHF1ZSBlbCBkZSBsYXMgbXVqZXJlcyBlbiBwdWVzdG9zIGRlIGxpZGVyYXpnbyIpDQogIH0NCmBgYA0KDQpgYGB7ciBncmFmaWNvLXByb3AtbGlkLWdlbmVyb30NCiMgR3LDoWZpY28NCmxpZGVyZXNfZ2VuZXJvICU+JSANCiAgbXV0YXRlKHBvcmNfbGlkZXIgPSBsaWRlci9uLCANCiAgICAgICAgIHBvcmNfbm9fbGlkZXIgPSAxIC0gcG9yY19saWRlcikgJT4lIA0KICBwaXZvdF9sb25nZXIoY29scyA9IGMocG9yY19saWRlciwgcG9yY19ub19saWRlciksDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJlc19saWRlciIsIA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbG9yZXMiKSAlPiUgDQogIG11dGF0ZShlc19saWRlciA9IGZhY3Rvcihlc19saWRlciwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJwb3JjX25vX2xpZGVyIiwgInBvcmNfbGlkZXIiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJObyBMw61kZXIiLCAiTMOtZGVyIikpKSAlPiUgDQogIGdncGxvdChhZXMoeD0gZ2VuZXJvLCB5ID0gdmFsb3JlcywgZmlsbCA9IGVzX2xpZGVyKSkrDQogIGdlb21fY29sKHBvc2l0aW9uID0gImZpbGwiKSsNCiAgZXN0aWxvICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzc1ODM4RiIsICIjMzQ0RDdFIikpICsNCiAgbGFicyh0aXRsZSA9ICJQcm9wb3JjacOzbiBkZSBMw61kZXJlcyBzZWfDum4gZ8OpbmVybyIsDQogICAgICAgeCA9ICIiLCB5ID0gIiIsIGZpbGwgPSAiIiwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCg0KYGBgDQoNCkRlIGFjdWVyZG8gYSBsYXMgcmVzcHVlc3RhcyByZWNvbGVjdGFkYXMgKioyIGRlIGNhZGEgMyoqIHBhcnRpY2lwYW50ZXMgc29uIG11amVyZXMuDQoNClBhcmEgbG9zIHB1ZXN0b3MgZGUgbGlkZXJhemdvIGNvbnNpZGVyYW1vcyBsYXMgcGVyc29uYXMgZW4gbG9zIHB1ZXN0b3MgZGUgKkRpcmVjdG9yLCBHZXJlbnRlLCBKZWZlLCB5IFJlc3BvbnNhYmxlLioNCg0KRGVsIHRvdGFsIGRlICoqbXVqZXJlcyoqLCBgciBsaWRlcmVzX2dlbmVyb1sxLDNdYCByZXNwdWVzdGFzLCBgciBsaWRlcmVzX2dlbmVyb1sxLDJdYCBvY3VwYW4gdW4gcHVlc3RvIGRlIGxpZGVyYXpnbyAoYHIgbGlkZXJlc19nZW5lcm9bMSwgNF1gKS4NCg0KRGVsIHRvdGFsIGRlICoqaG9tYnJlcyoqLCBgciBsaWRlcmVzX2dlbmVyb1syLCAzXWAgcmVzcHVlc3RhcywgYHIgbGlkZXJlc19nZW5lcm9bMiwyXWAgb2N1cGFuIHVuIHB1ZXN0byBkZSBsaWRlcmF6Z28gKGByIGxpZGVyZXNfZ2VuZXJvWzIsIDRdYCkuDQoNCkNvbiB1biAqcC12YWx1ZSogaWd1YWwgYSBgciByb3VuZChyZXN1bHRhZG9zX3Rlc3RbMSwzXSwzKWAgcG9kZW1vcyBhZmlybWFyIHF1ZSAqKmByIHZhbG9yX3Rlc3RgKiouDQoNCg0KQSBwZXNhciBkZSBxdWUgZW4gUmVjdXJzb3MgSHVtYW5vcyBlbiBBcmdlbnRpbmEsIGxhcyBtdWplcmVzIGNpcyByZXByZXNlbnRhbiBsYSBtYXlvciBjYW50aWRhZCBkZSBlbXBsZWFkb3MgYmFqbyByZWxhY2nDs24gZGUgZGVwZW5kZW5jaWEsIHkgYWRlbcOhcyBzZSBmb3JtYW4gZW4gbWF5b3IgcHJvcG9yY2nDs24gcXVlIGxvcyB2YXJvbmVzIGVuIHBvc2dyYWRvcywgcHJvcG9yY2lvbmFsbWVudGUgZW4gY29tcGFyYWNpw7NuIGNvbiBsb3MgaG9tYnJlcyBjaXMsIGFjY2VkZW4gYSBtZW5vcyBwb3NpY2lvbmVzIGRlIGxpZGVyYXpnby4NCg0KIyMgRGl2ZXJzaWRhZCBlbiBSUkhIDQoNCkVuIGVzdGEgc2VjY2nDs24gYW5hbGl6YXJlbW9zIHF1w6kgdGFuIGRpdmVyc2EgZSBpbmNsdXNpdmEgZXMgbGEgZnVuY2nDs24gZGUgUlJISCBlbiBnZW5lcmFsIGRlc2RlIHVuYSBwZXJzcGVjdGl2YSBkZSBpZGVudGlkYWQgZGUgZ8OpbmVybywgb3JpZW50YWNpw7NuIHNleHVhbCB5IGRpc2NhcGFjaWRhZC4NCg0KYGBge3J9DQojIENhcmdhciBsb3MgZGF0b3MgMjAyMCB5IDIwMjENCmsyMCA8LSBnb29nbGVzaGVldHM0OjpyZWFkX3NoZWV0KCIxODMzeEVlUkl5MURMa2U0ZUhLZkVUaGpqZ3gwMVlHWDl5UWFVNnZ2MTVLMCIsIA0KICAgICAgICAgICAgICAgICAgICAgc2tpcCA9IDUpICU+JSANCiAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKQ0KDQprMjEgPC0gZ29vZ2xlc2hlZXRzNDo6cmVhZF9zaGVldCgiMUxEZFhsSXdyY3N5dXl3YmNTNGdkYy0xcDZ3QlhmRWZMMlk2c05Cai00R00iLA0KICAgICAgICAgICAgICAgICAgICBza2lwID0gNSkgJT4lIA0KICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpDQoNCiMgU2VsZWNjaW9uYXIgbGFzIGNvbHVtbmFzIGRlIGFtYm9zIGRhdGEgZnJhbWVzLg0KazIwIDwtIGsyMCAlPiUgDQogIHNlbGVjdChpZGVudGlkYWRfZ2VuZXJvID0gZ2VuZXJvLCANCiAgICAgICAgIGRpdmVyc2lkYWRfc2V4dWFsID0gdGVfaWRlbnRpZmljYXNfY29tb19sZ2J0X2xlc2JpYW5hX2dheV9iaXNleHVhbF90cmFuc2V4dWFsX290cmFfbWlub3JpYV9zZXh1YWwsDQogICAgICAgICBydWJybyA9IHJ1YnJvX2RlX2xhX2VtcHJlc2EsDQogICAgICAgICBvcmlnZW5fZGVsX2NhcGl0YWwsDQogICAgICAgICBwdWVzdG8gPSBlbl9xdWVfcHVlc3RvX3RyYWJhamFzLA0KICAgICAgICAgbml2ZWxfZm9ybWFjaW9uID0gbWF4aW1vX25pdmVsX2RlX2Zvcm1hY2lvbiwNCiAgICAgICAgIGlkaW9tYSA9IHRlX2V4aWdpZXJvbl9zYWJlcl91bl9pZGlvbWFfZXh0cmFuamVyb19pbmdsZXNfcG9ydHVndWVzX2V0Y19wYXJhX2VudHJhcl9hX3RyYWJhamFyX2VuX3R1X2VtcHJlc2EsDQogICAgICAgICBpZGlvbWFfcG9yY2VudGFqZSA9IHF1ZV9wb3JjZW50YWplX2RlbF90aWVtcG9fdXNhc19lbF9pZGlvbWFfZXh0cmFuamVyb19lbl90dV9wdWVzdG9fYWN0dWFsLA0KICAgICAgICAgZGlzY2FwYWNpZGFkLA0KICAgICAgICAgdHJhYmFqbykgJT4lIA0KICBtdXRhdGUobGliZXJ0YWRfc2VyID0gOTksIA0KICAgICAgICAgc3VmcmlvX2Fjb3NvID0gOTksDQogICAgICAgICBtYW5hZ2VtZW50X2ZlbWVuaW5vID0gOTksDQogICAgICAgICBsaW5lYV9zZWd1cmEgPSA5OSwNCiAgICAgICAgIG1hY2hpc21vID0gOTksDQogICAgICAgICBlZGljaW9uID0gMjAyMCkgIyBBw7FhZG8gdW5hIGNvbHVtbmEgY29uIHVuIHZhbG9yID0gMSBwb3JxdWUgZXN0YSBwcmVndW50YSBubyBleGlzdMOtYSBlbiBsYSBlZGljacOzbiAyMDIwIGRlIGxhIEVuY3Vlc3RhDQoNCmsyMSA8LSBrMjEgJT4lIA0KICBzZWxlY3QoaWRlbnRpZGFkX2dlbmVybyA9IGlkZW50aWRhZF9kZV9nZW5lcm8sDQogICAgICAgICBkaXZlcnNpZGFkX3NleHVhbCA9IHRlX2lkZW50aWZpY2FzX2NvbW9fbGdidGlxX2xlc2JpYW5hX2dheV9iaXNleHVhbF90cmFuc2V4dWFsX290cmFfbWlub3JpYV9zZXh1YWwsDQogICAgICAgICBydWJybyA9IHJ1YnJvX2RlX2xhX2VtcHJlc2EsDQogICAgICAgICBvcmlnZW5fZGVsX2NhcGl0YWwsDQogICAgICAgICBwdWVzdG8gPSBlbl9xdWVfcHVlc3RvX3RyYWJhamFzLA0KICAgICAgICAgbml2ZWxfZm9ybWFjaW9uID0gbWF4aW1vX25pdmVsX2RlX2Zvcm1hY2lvbiwNCiAgICAgICAgIGlkaW9tYSA9IHRlX2V4aWdpZXJvbl9zYWJlcl91bl9pZGlvbWFfZXh0cmFuamVyb19pbmdsZXNfcG9ydHVndWVzX2V0Y19wYXJhX2VudHJhcl9hX3RyYWJhamFyX2VuX3R1X2VtcHJlc2EsDQogICAgICAgICBpZGlvbWFfcG9yY2VudGFqZSA9IHF1ZV9wb3JjZW50YWplX2RlbF90aWVtcG9fdXNhc19lbF9pZGlvbWFfZXh0cmFuamVyb19lbl90dV9wdWVzdG9fYWN0dWFsLA0KICAgICAgICAgZGlzY2FwYWNpZGFkID0gdGVuZXNfYWxndW5hX2Rpc2NhcGFjaWRhZCwNCiAgICAgICAgIHRyYWJham8sDQogICAgICAgICBsaWJlcnRhZF9zZXIgPSBlbl90dV9lbXByZXNhX3B1ZWRlc19zZXJfY29tb19yZWFsbWVudGVfZXJlc19wb3JfZWpfZXhwcmVzYXJfYWJpZXJ0YW1lbnRlX3R1X3BlcnNvbmFsaWRhZF90dV9pZGVudGlkYWRfZGVfZ2VuZXJvX29yaWVudGFjaW9uX3NleHVhbF9ldGMsIA0KICAgICAgICAgc3VmcmlvX2Fjb3NvID0gc3VmcmlzdGVfYWxndW5hX3NpdHVhY2lvbl9kZV9hY29zb19hYnVzb19vX2RlX2Rpc2NyaW1pbmFjaW9uX2VuX2FsZ3VuX3RyYWJham8sDQogICAgICAgICBtYW5hZ2VtZW50X2ZlbWVuaW5vID0gcXVlX3BvcmNlbnRhamVfYXByb3hpbWFkb19kZWxfbWFuYWdlbWVudF9kZV90dV9lbXByZXNhX3Nvbl9tdWplcmVzX2VudGllbmRhc2VfcG9zaWNpb25lc19kZV9qZWZhdHVyYV9kZV9nZXJlbmNpYV9vX2RlX2RpcmVjY2lvbiwgDQogICAgICAgICBsaW5lYV9zZWd1cmEgPSBlbl90dV9vcmdhbml6YWNpb25fZXhpc3RlX3VuYV9saW5lYV9zZWd1cmFfb19wb2xpdGljYXNfZGVmaW5pZGFzX3BhcmFfYWN0dWFyX2ZyZW50ZV9hX3NpdHVhY2lvbmVzX2RlX2Fjb3NvX29fZGlzY3JpbWluYWNpb24pICU+JSANCiAgbXV0YXRlKG1hY2hpc21vID0gOTksDQogICAgICAgICBlZGljaW9uID0gMjAyMSkNCg0KazIyIDwtIGtpd2kgJT4lIA0KICBzZWxlY3QoaWRlbnRpZGFkX2dlbmVybyA9IGdlbmVybywNCiAgICAgICAgIGRpdmVyc2lkYWRfc2V4dWFsLA0KICAgICAgICAgcnVicm8sDQogICAgICAgICBvcmlnZW5fZGVsX2NhcGl0YWwgPSBvcmlnZW5fY2FwaXRhbCwNCiAgICAgICAgIHB1ZXN0bywNCiAgICAgICAgIG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgIGlkaW9tYSA9IGlkaW9tYV9leGlnZW5jaWEsDQogICAgICAgICBpZGlvbWFfcG9yY2VudGFqZSwNCiAgICAgICAgIGRpc2NhcGFjaWRhZCwNCiAgICAgICAgIHRyYWJham8sDQogICAgICAgICBsaWJlcnRhZF9zZXIsIA0KICAgICAgICAgc3VmcmlvX2Fjb3NvLA0KICAgICAgICAgbWFuYWdlbWVudF9mZW1lbmlubyA9IGRpdmVyc2lkYWRfbWFuYWdlbWVudCwNCiAgICAgICAgIGxpbmVhX3NlZ3VyYSwNCiAgICAgICAgIG1hY2hpc21vKSAlPiUgDQogIG11dGF0ZShlZGljaW9uID0gMjAyMikNCg0KIyBVbmlyIGxvcyBkYXRhc2V0cw0KZGl2X3JoIDwtIHJiaW5kKGsyMCwgazIxLCBrMjIpDQoNCiMgQ29tbyB5YSB0ZW5nbyB1bmlmaWNhZG9zIGFtYm9zIGRhdGFzZXRzIHB1ZWRvIGJvcnJhciBsYXMgdmVyc2lvbmVzIGluZGl2aWR1YWxlcyBwYXJhIGFob3JyYXIgbWVtb3JpYQ0Kcm0oazIwLCBrMjEsIGsyMikNCg0KYGBgDQoNCkVuIGxhIGVkaWNpw7NuIDIwMjAsIG5vcyByZWZlcsOtYW1vcyBhIGxhIGlkZW50aWRhZCBkZSBnw6luZXJvIGRlIHVuYSBtYW5lcmEgZGlmZXJlbnRlIGEgbGEgcXVlIGxvIGhpY2ltb3MgZW4gbGEgZWRpY2nDs24gZGVsIDIwMjEsIGFzw60gcXVlIGxhIHNpZ3VpZW50ZSBwYXJ0ZSBjb25zaXN0ZSBlbiBjb25zb2xpZGFyIGxvcyBkYXRvcyBkZSBhbWJhcyBlZGljaW9uZXMuDQoNCmBgYHtyIGRhdG9zX2dlbmVyb30NCg0KIyBWZXJpZmljYXIgbGFzIGRpc3RpbnRhcyBmb3JtYXMgZGUgcmVmZXJpcnNlIGFsIGfDqW5lcm8NCnVuaXF1ZShkaXZfcmgkaWRlbnRpZGFkX2dlbmVybykNCmBgYA0KDQpFbiBsb3MgZGF0b3MgZW5jb250cmFtb3MgNSBmb3JtYXMgZGlmZXJlbnRlcyBkZSByZWZlcmlyc2UgYSBsb3MgaG9tYnJlcyBjaXMsIHkgNSBmb3JtYXMgZGlmZXJlbnRlcyBkZSByZWZlcmlyc2UgYSBsYXMgbXVqZXJlcyBjaXMsIGFzw60gcXVlIGVsIHNpZ3VpZW50ZSBwYXNvIGVzIHVuaWZpY2FyIGVzdG9zIHZhbG9yZXMgcGFyYSBzaW1wbGlmaWNhciBlbCBhbsOhbGlzaXMgeSBsYSBpbnRlcnByZXRhY2nDs24gZGUgbG9zIHJlc3VsdGFkb3MuDQoNCj4gRWwgc3VmaWpvICpjaXMqIGhhY2UgcmVmZXJlbmNpYSBhIGxhcyBwZXJzb25hcyBxdWUgc2UgaWRlbnRpZmljYW4gY29uIGVsIG1pc21vIGfDqW5lcm8gYXNpZ25hZG8gYWwgbmFjZXIuDQoNCmBgYHtyfQ0KZGl2X3JoIDwtIGRpdl9yaCAlPiUgDQogICAgbXV0YXRlKGlkZW50aWRhZF9nZW5lcm8gPSANCiAgICAgICAgICAgICBmY3RfY29sbGFwc2UoaWRlbnRpZGFkX2dlbmVybywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkhvbWJyZSBjaXMiID0gYygiTWFzY3VsaW5vIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSG9tYnJlIGNpcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkhvbWJyZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkhvbWJyZSBoZXRlcm8uIFF1ZSBlcyBjaXM/IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSG9tYnJlIGhldGVyb3NleHVhbCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlZhcm9uIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICJNdWplciBjaXMiID0gYygiRmVtZW5pbm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk11amVyIGNpcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVqZXIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk11amVyIGhldGVyb3NleHVhbCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTXVqZXIiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkfDqW5lcm8gZGl2ZXJzbyIgPSBjKCJHw6luZXJvIGRpdmVyc28gKGfDqW5lcm8gZGl2ZXJzbyAvIGfDqW5lcm8gZmx1aWRvIC9vdHJhcyBtaW5vcsOtYXMpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vIGJpbmFyaW8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2F5IikpKQ0KDQojIFZlciByZXN1bHRhZG9zIGRlbCBwcm9jZXNvIGFudGVyaW9yDQp1bmlxdWUoZGl2X3JoJGlkZW50aWRhZF9nZW5lcm8pDQpgYGANCg0KYGBge3J9DQpkaXZfcmggPC0gZGl2X3JoICU+JSANCiAgbXV0YXRlKHJ1YnJvID0gZmN0X2NvbGxhcHNlKHJ1YnJvLCAiQWdybyIgPSBjKCJBZ3JpY3VsdHVyYSwgcGxhbnRhY2lvbmVzLCBvdHJvcyBzZWN0b3JlcyBydXJhbGVzIiwgIkFncmljdWx0dXJhOyBwbGFudGFjaW9uZXMsb3Ryb3Mgc2VjdG9yZXMgcnVyYWxlcyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFsaW1lbnRvcyIgPSBjKCJBbGltZW50YWNpw7NuLCBiZWJpZGFzIiwgIkFsaW1lbnRhY2nDs247IGJlYmlkYXM7IHRhYmFjbyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJhbmNvcyB5IEZpbmFuemFzIiA9IGMoIkJhbmNvcywgYmFuY2Egb25saW5lIiwgIkJhbmNvczsgYmFuY2Egb25saW5lOyIsICJTZXJ2aWNpb3MgZmluYW5jaWVyb3Mgc2VndXJvcyIsICJTZXJ2aWNpb3MgZmluYW5jaWVyb3M7IHNlZ3Vyb3MiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBdXRvcGFydGlzdGEiID0gYygiRmFicmljYWNpw7NuIGRlIG1hdGVyaWFsIGRlIHRyYW5zcG9ydGUiLCAiVGVybWluYWxlcyBhdXRvbW90cmljZXMsIGbDoWJyaWNhcyBhdXRvcGFydGlzdGFzLCB5IGFmaW5lcyIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIb3RlbGVyw61hIiA9ICJIb3RlbGVyw61hLCByZXN0YXVyYWNpw7NuLCB0dXJpc21vIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNZXRhbHVyZ2lhIiA9IGMoIkluZHVzdHJpYSBtZXRhbMO6cmdpY2EsIG1ldGFsbWVjw6FuaWNhIiwgIlByb2R1Y2Npw7NuIGRlIG1ldGFsZXMgYsOhc2ljb3MiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWVkaW9zIiA9IGMoIk1lZGlvcyBkZSBjb211bmljYWNpw7NuLCBjdWx0dXJhLCBncsOhZmljb3MiLCAiTWVkaW9zIGRlIGNvbXVuaWNhY2nDs247IGN1bHR1cmE7IGdyw6FmaWNvcyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1pbmVyw61hIiA9IGMoIk1pbmVyw61hIiwgIk1pbmVyw61hIChjYXJiw7NuLCBvdHJhIG1pbmVyw61hKSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk9pbCAmIEdhcyIgPSBjKCJQZXRyw7NsZW8geSBwcm9kdWNjacOzbiBkZSBnYXMsIHJlZmluYWNpw7NuIGRlIHBldHLDs2xlbyIsICJQZXRyw7NsZW8geSBwcm9kdWNjacOzbiBkZSBnYXM7IHJlZmluYWNpw7NuIGRlIHBldHLDs2xlbyIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb25zdWx0b3LDrWEiID0gIlNlcnZpY2lvcyBkZSBjb25zdWx0b3LDrWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNvcnJlb3MiID0gYygiU2VydmljaW9zIGRlIGNvcnJlb3MgeSBkZSB0ZWxlY29tdW5pY2FjaW9uZXMiLCAiTWVkaW9zIGRlIGNvbXVuaWNhY2nDs247IGN1bHR1cmE7IGdyw6FmaWNvcyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNvcnJlb3MiID0gYygiU2VydmljaW9zIGRlIGNvcnJlb3MgeSBkZSB0ZWxlY29tdW5pY2FjaW9uZXMiLCAiU2VydmljaW9zIGRlIGNvcnJlb3MsIHkgZGUgdGVsZWNvbXVuaWNhY2lvbmVzIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2VydmljaW9zIFDDumJsaWNvcyIgPSBjKCJTZXJ2aWNpb3MgcMO6YmxpY29zIChhZ3VhLCBnYXMsIGVsZWN0cmljaWRhZCkiLCAiU2VydmljaW9zIHDDumJsaWNvcyAoYWd1YTtnYXM7IGVsZWN0cmljaWRhZCkiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTaWx2aWN1bHR1cmEiID0gIlNpbHZpY3VsdHVyYTsgbWFkZXJhOyBjZWx1bG9zYTsgcGFwZWwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRlY25vbG9nw61hIiA9IGMoIlRlY25vbG9nw61hcyBkZSBpbmZvcm1hY2nDs24iLCAiVGVjbm9sb2fDrWFzIGRlIEluZm9ybWFjacOzbiwgU2lzdGVtYXMsIHkgYWZpbmVzIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRleHRpbCIgPSBjKCJUZXh0aWxlcywgdmVzdGlkbywgY3Vlcm8sIGNhbHphZG8iLCAiVGV4dGlsZXM7IHZlc3RpZG87IGN1ZXJvOyBjYWx6YWRvIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVHJhbnNwb3J0ZSIgPSBjKCJUcmFuc3BvcnRlIChpbmNsdXllbmRvIGF2aWFjacOzbiBjaXZpbCwgZmVycm9jYXJyaWxlcyBwb3IgY2FycmV0ZXJhKSIsICJUcmFuc3BvcnRlIChpbmNsdXllbmRvIGF2aWFjacOzbiBjaXZpbDsgZmVycm9jYXJyaWxlcyBwb3IgY2FycmV0ZXJhKSIsICJUcmFuc3BvcnRlIG1hcsOtdGltbywgcHVlcnRvcyIsICJUcmFuc3BvcnRlIG1hcsOtdGltbzsgcHVlcnRvczsiDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpKQ0KDQojIEHDsWFkaW1vcyBhIGxvcyBmcmVlbGFuY2VycyBjb21vIHNlcnZpY2lvcyBkZSBjb25zdWx0b3LDrWEgZGVudHJvIGRlIGxhIGNvbHVtbmEgUnVicm8NCmRpdl9yaCA8LSBkaXZfcmggJT4lIA0KICBtdXRhdGUocnVicm8gPSBpZl9lbHNlKHRyYWJham8gPT0gIkZyZWVsYW5jZSIsICJDb25zdWx0b3LDrWEgRnJlZWxhbmNlIiwgYXMuY2hhcmFjdGVyKHJ1YnJvKSkpDQoNCiMgTGltcGllemEgUHVlc3RvDQojIERlc2NhcnRhbW9zIHBvc2ljaW9uZXMgbm8gcmVsYWNpb25hZGFzIGNvbiBSUkhIDQpkaXZfcmggPC0gZGl2X3JoICU+JSANCiAgZmlsdGVyKCFwdWVzdG8gJWluJSBjKCJKdXpnYWRvIENpdmlsIHkgQ29tZXJjaWFsIiwgIlByb2dyYW1hZG9yIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJDdWlkYWRvIiwgIkFzZXNvciIsICJKZWZlIGRlIFByb3llY3RvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICJEZXNhcnJvbGxhZG9yIiwgIlByb2dyYW1hZG9yIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAiLSIsICJJbnNwZWNjacOzbiBkZSBjYWxpZGFkIiwgIkplZmUgZGUgUHJveWVjdG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgIlJlcHJlc2VudGFudGUiLCAiVMOpY25pY28iLCAiQXNlc29yYW1pZW50byIsICItIikpICU+JSANCiAgbXV0YXRlKHB1ZXN0byA9IHN0cl90cmltKHB1ZXN0bywgc2lkZSA9ICJib3RoIikpICMgRWxpbWluYSBlc3BhY2lvcyB2YWPDrW9zIGFudGVzIHkgZGVzcHXDqXMgZGUgY2FkYSBwYWxhYnJhDQoNCiMgUmVlbXBsYXphciBsb3MgdmFsb3JlcyBOQSBwb3IgQ29uc3VsdG9yIEZyZWVsYW5jZQ0KZGl2X3JoIDwtIGRpdl9yaCAlPiUgDQogIG11dGF0ZShwdWVzdG8gPSBpZl9lbHNlKGlzLm5hKHB1ZXN0byksICJDb25zdWx0b3IgRnJlZWxhbmNlIiwgcHVlc3RvKSkNCg0KDQojIFVuaWZpY2FjacOzbiBkZSBQdWVzdG9zDQpkaXZfcmggPC0gZGl2X3JoICU+JSANCiAgbXV0YXRlKHB1ZXN0byA9IGZjdF9jb2xsYXBzZShwdWVzdG8sICJHZXJlbnRlIiA9IGMoIkdlcmVudGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3VwZXJpbnRlbmRlbnRlIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXJlY3RvciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXJlY3RvciAoIGVzY2FsYWbDs24gbXVuaWNpcGFsKSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICJIUkJQIiA9IGMoIkhSQlAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNlbmlvciBDb25zdWx0b3LDrWEiLCAic3BlY2lhbGlzdCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXNwZWNpYWxpc3RhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTcGVjaWFsaXN0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFc3BlY2lhbGlzdGEgZGUgc2VsZWNjacOzbiBwb3IgdW4gbGFkbyAow7puaWNhIHBlcnNvbmEgZW4gZXN0YXMgdGFyZWFzKSB5IEhSQlAgZGUgMiBlcXVpcG9zIHBvciBvdHJvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFc3BlY2lhbGlzdGEgZW4gc2VsZWNjacOzbiBJVCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlY3J1aXRlciIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIlJlc3BvbnNhYmxlIiA9IGMoIlJlc3BvbnNhYmxlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb29yZGluYWNpw7NuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb29yZGluYWNpw7NuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb29yZGluYWRvciBkZSBQYXlyb2xsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbmNhcmdhZG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNvb3JkaW5hZG9yYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3VwZXJ2aXNvciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTMOtZGVyIMOBZ2lsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMw61kZXIgZGUgc2VsZWNjacOzbiIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIkFkbWluaXN0cmF0aXZvIiA9IGMoIkFkbWluaXN0cmF0aXZvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBc2lzdGVudGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFzaXN0ZW50ZSBSUkhIIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBdXgiLCAiQXV4aWxpYXIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbnN1bHRvciBqciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRWwgY2FyZ28gZXMgQXNpc3RlbnRlIGRlIENILCBwZXJvIGxlbyBhZGVsYW50ZSBDb211bmljYWNpw7NuIEludGVybmEsIFJTRSwgQ2FwYWNpdGFjaW9uIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQYXlyb2xsIEFzc2lzdGFudCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIkFuYWxpc3RhIiA9IGMoIkFuYWxpc3RhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQW5hbGlzdGEgc2VtaSBzZW5pb3IiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFzZXNvcmFtaWVudG8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb25zdWx0b3IiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYXBhY2l0YWRvciIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNvbnN1bHRvciBFamVjdXRpdm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbnN1bHRvciBqciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2VuZXJhbGlzdGEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlByb2Zlc2lvbmFsIFJSSEgiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlY2x1dGFkb3IiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlY3J1aXRlciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVjcnVpdGVyIElUIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWNsdXRhZG9yYSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNlbGVjdG9yYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2VuaW9yIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZW5pb3IgUmVjcnVpdGVyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZW5pb3IgQ29uc3VsdG9yw61hIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTb3VyY2VyIChSZWNydWl0ZXIpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTb3VyY2VyIFNwZWNpYWxpc3QiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhbGVudCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVGFsZW50IEFjcXVpc2l0aW9uIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJVCBSRUNSVUlURVIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkF1ZGl0b3IiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRlY2ggUmVjcnVpdGVyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBbmFsaXN0YSBkZSBQZW9wbGUgT3BlcmF0aW9ucyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3BlY2lhbGlzdCIpKSkNCiAgDQoNCmBgYA0KDQojIyMgQ3VhbnRhIGRpdmVyc2lkYWQgZGUgaWRlbnRpZGFkZXMgZGUgZ8OpbmVybyB5IG9yaWVudGFjaW9uZXMgc2V4dWFsZXMgaGF5IGVuIFJSSEgNCg0KRW4gZXN0ZSBwdW50byBjcmVvIHF1ZSBlcyBpbXBvcnRhbnRlIGFjbGFyYXIgcXVlIGVudHJlIHVuYSBlZGljacOzbiB5IG90cmEgZGUgbGEgRW5jdWVzdGEgS0lXSSBoaWNpbW9zIGNhbWJpb3MgZW4gZWwgZGlzZcOxbyBkZWwgZm9ybXVsYXJpbywgeSBwb3IgZWplbXBsbywgbGFzIHByZWd1bnRhcyBzb2JyZSBvcmllbnRhY2nDs24gc2V4dWFsIHPDs2xvIHNlIGxhcyBoaWNpbW9zIGEgbGFzIHBlcnNvbmFzIHF1ZSB0cmFiYWphbiBlbiByZWxhY2nDs24gZGUgZGVwZW5kZW5jaWEsIGNvbiBsbyBjdWFsIG5vIHRlbmVtb3MgdW5hIGNvbnRpbnVpZGFkIGVuIGxvcyBkYXRvcyBzb2JyZSBlbCB0b3RhbCBkZSBsYXMgcGVyc29uYXMgcXVlIHBhcnRpY2lwYXJvbiwgZXNwZWNpYWxtZW50ZSBkZSBxdWllbmVzIHRyYWJhamFuIGRlIG1hbmVyYSBmcmVlbGFuY2UuDQoNCkVuIHByaW1lciBsdWdhciwgdmVhbW9zIGN1w6FudGFzIHBlcnNvbmFzIHRyYWJhamFuIGVuIFJSSEggc2Vnw7puIHN1IGlkZW50aWRhZCBkZSBnw6luZXJvOg0KDQpgYGB7ciBkaXZlcnNpZGFkXzF9DQpndCgNCmRpdl9yaCAlPiUgDQogIGdyb3VwX2J5KGVkaWNpb24sIGlkZW50aWRhZF9nZW5lcm8pICU+JSANCiAgY291bnQoc29ydCA9IFRSVUUpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGVkaWNpb24sIHZhbHVlc19mcm9tID0gbikgJT4lIA0KICBtdXRhdGUoYDIwMjBgID0gY29hbGVzY2UoYDIwMjBgLCAwKSwNCiAgICAgICAgIGAyMDIxYCA9IGNvYWxlc2NlKGAyMDIxYCwgMCksDQogICAgICAgICBgMjAyMmAgPSBjb2FsZXNjZShgMjAyMmAsIDApLA0KICAgICAgICAgVG90YWwgPSBgMjAyMGAgKyBgMjAyMWAgKyBgMjAyMmAsDQogICAgICAgICBQb3JjZW50YWplID0gcm91bmQoVG90YWwvc3VtKFRvdGFsKSwzKSkNCikgJT4lIA0KICBmbXRfcGVyY2VudChjb2x1bW5zID0gUG9yY2VudGFqZSwNCiAgICAgICAgICAgICAgZGVjaW1hbHMgPSAxKSAlPiUgDQogIHRhYl9oZWFkZXIodGl0bGUgPSAiSWRlbnRpZGFkIGRlIEfDqW5lcm8gcG9yIEVkaWNpw7NuIikgJT4lIA0KICB0YWJfc291cmNlX25vdGUoc291cmNlX25vdGUgPSBmdWVudGUpICU+JSANCiAgY29sc19sYWJlbChpZGVudGlkYWRfZ2VuZXJvID0gIklkZW50aWRhZCBkZSBHw6luZXJvIikNCmBgYA0KDQpTZWfDum4gbGEgbXVlc3RyYSBxdWUgb2J0dXZpbW9zLCAqKm1lbm9zIGRlbCAxJSBkZSBsYXMgcGVyc29uYXMgcXVlIHRyYWJhamFuIGVuIFJSSEggc29uIHBlcnNvbmFzIG5vIGJpbmFyaWFzLioqIENvbW8gcGFyYSBxdWVkZSBtw6FzIGNsYXJvIHZlYW3Ds3NsbyBjb24gdW4gZ3LDoWZpY28uDQoNCmBgYHtyIGRpdmVyc2lkYWRfMn0NCmRpdl9yaCAlPiUgDQogIGdyb3VwX2J5KGlkZW50aWRhZF9nZW5lcm8pICU+JSANCiAgY291bnQoc29ydCA9IFRSVUUpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgZ2dwbG90KGFlcyh5ID0gcmVvcmRlcihpZGVudGlkYWRfZ2VuZXJvLCBuKSwgeCA9IG4sIA0KICAgICAgICAgICAgIGZpbGwgPSBpZGVudGlkYWRfZ2VuZXJvKSkgKw0KICBnZW9tX2NvbCgpICsNCiAgZXN0aWxvdiArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCBoanVzdCA9IC0wLjIpLA0KICAgICAgICAgICAgc2l6ZSA9IDMuNSwNCiAgICAgICAgICAgIGNvbG9yID0gYyhncmlzLCBncmlzLCBncmlzLCAiYmxhY2siLCAiYmxhY2siKSkrDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoZ3JpcywgdmVyZGUsIGdyaXMsIHZlcmRlLCBncmlzKSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAxMzAwKSkgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgc2Vnw7puIElkZW50aWRhZCBkZSBHw6luZXJvIiwNCiAgICAgICB4ID0gIiIsIHkgPSAiIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCiAgDQpgYGANClBvciBkZWNpcmxvIGFtYWJsZW1lbnRlOiBIYXkgbXVjaGFzIG9wb3J0dW5pZGFkZXMgZGUgbWVqb3JhIGFjw6EuDQoNClkgYWhvcmEgdmVhbW9zIGxhIGNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgc2Vnw7puIGxhIG9yaWVudGFjacOzbiBzZXh1YWwgZGUgbGFzIHBlcnNvbmFzIHF1ZSBwYXJ0aWNpcGFyb24gZGUgbGEgZW5jdWVzdGEuIERhZG8gcXVlIGVuIGxhIGVkaWNpw7NuIDIwMjEgZXN0YSBlcmEgdW5hIHNlY2Npw7NuIHZvbHVudGFyaWEsIGxhIGNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgdmEgYSBzZXIgZGlzdGludGEgcXVlIGVuIGxhIHRhYmxhIGFudGVyaW9yLiBBZGVtw6FzLCBmdWUgYWxnbyBxdWUgbm8gbGUgcHJlZ3VudGFtb3MgYSBsYXMgcGVyc29uYXMgcXVlIHRyYWJhamFuIGRlIG1hbmVyYSBpbmRlcGVuZGllbnRlLg0KDQpMYSBwcmVndW50YSBxdWUgaGljaW1vcyBmdWUgKirCv1RlIGlkZW50aWZpY8OhcyBjb21vIExHQlRJUSsgKGxlc2JpYW5hLCBnYXksIGJpc2V4dWFsLCB0cmFuc2V4dWFsLCBvdHJhIG1pbm9yw61hIHNleHVhbCk/LioqIEhlIGFxdcOtIGxhcyByZXNwdWVzdGFzOg0KDQpgYGB7ciBkaXZlcnNpZGFkX3NleHVhbH0NCg0KZ3QoZGl2X3JoICU+JSANCiAgZmlsdGVyKCFpcy5uYShkaXZlcnNpZGFkX3NleHVhbCkpICU+JSANCiAgZ3JvdXBfYnkoZWRpY2lvbiwgZGl2ZXJzaWRhZF9zZXh1YWwpICU+JSANCiAgY291bnQoc29ydCA9IFRSVUUpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGVkaWNpb24sIA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IG4pICU+JSANCiAgbXV0YXRlKFRvdGFsID0gYDIwMjBgICsgYDIwMjFgLA0KICAgICAgICAgUG9yY2VudGFqZSA9IFRvdGFsL3N1bShUb3RhbCkpDQopICU+JSANCiAgZm10X3BlcmNlbnQoY29sdW1ucyA9IFBvcmNlbnRhamUsDQogICAgICAgICAgICAgIGRlY2ltYWxzID0gMSkgJT4lIA0KICB0YWJfaGVhZGVyKHRpdGxlID0gIkRpdmVyc2lkYWQgU2V4dWFsIHBvciBFZGljacOzbiIpICU+JSANCiAgdGFiX3NvdXJjZV9ub3RlKHNvdXJjZV9ub3RlID0gZnVlbnRlKSAlPiUgDQogIGNvbHNfbGFiZWwoZGl2ZXJzaWRhZF9zZXh1YWwgPSAiRXJlcyBkZSBhbGfDum5cbkNvbGVjdGl2byBMQkdUUSsiKQ0KICANCmBgYA0KDQpBbCBtZW5vcyByZXNwZWN0byBkZSBlc3RhIHByZWd1bnRhLCB0ZW5lbW9zIHVuYSBtYXlvciByZXByZXNlbnRhY2nDs24gZGUgZGl2ZXJzaWRhZGVzIHNleHVhbGVzLiBOdWV2YW1lbnRlLCBlc3RhIG11ZXN0cmEgbm8gZXMgcmVwcmVzZW50YXRpdmEgZGUgdG9kYXMgbGFzIHBlcnNvbmFzIHF1ZSB0cmFiYWphbiBlbiBSUkhILCBwZXJvIGVzcGVyYW1vcyBxdWUgcGVybWl0YSBkaXNjdXRpciBlbCB0ZW1hLg0KDQpgYGB7ciBkaXZlcnNpZGFkX3NleHVhbF9wbG90fQ0KZGl2X3JoICU+JSANCiAgZmlsdGVyKCFpcy5uYShkaXZlcnNpZGFkX3NleHVhbCkpICU+JQ0KICBncm91cF9ieShpZGVudGlkYWRfZ2VuZXJvLCBkaXZlcnNpZGFkX3NleHVhbCkgJT4lIA0KICB0YWxseSgpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgZ2dwbG90KGFlcyh5ID0gaWRlbnRpZGFkX2dlbmVybywgeCA9IG4sIGZpbGwgPSBkaXZlcnNpZGFkX3NleHVhbCApKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gImZpbGwiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9maWxsKHZqdXN0ID0gMC41KSwgc2l6ZSA9IDIuNSkgKw0KICBlc3RpbG92ICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFQpKSArDQogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpKw0KICBsYWJzKHRpdGxlID0gIkRpdmVyc2lkYWQgU2V4dWFsIHNlZ8O6biBJZGVudGlkYWQgZGUgR8OpbmVybyIsDQogICAgICAgc3VidGl0bGUgPSAiUHJlZ3VudGE6IMK/VGUgaWRlbnRpZmljw6FzIGNvbW8gTEdCVElRKz8iLCANCiAgICAgICBmaWxsID0gIkVyZXMgZGUgYWxnw7puIENvbGVjdGl2byBMR0JUSVErIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsIGNhcHRpb24gPSBmdWVudGUpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhhenVsLCBncmlzLCB2ZXJkZSkpDQpgYGANCg0KRWwgdGFtYcOxbyBkZSBsYXMgYmFycmFzIHJlZmxlamFuIGxhIHByb3BvcmNpw7NuIGRlIGNhZGEgcmVzcHVlc3RhIHNlZ8O6biBsYSBpZGVudGlkYWQgZGUgZ8OpbmVybyBkZSBjYWRhIHBhcnRpY2lwYW50ZS4gUG9yIGVqZW1wbG8sIGVuIGVsIGNhc28gZGUgbGFzIHBlcnNvbmFzIHF1ZSBzZSBpZGVudGlmaWNhbiBjb21vICpIb21icmVzIGNpcyosIDQ2IHBlcnNvbmFzIHNlIGlkZW50aWZpY2FuIGNvbW8gcGFydGUgZGUgbGEgY29tdW5pZGFkIExHQlRJUSsgKHVuIDExLjYlKS4gNDEgKk11amVyZXMgY2lzKiAoNC4zJSkgcGVydGVuZWNlbiBhIGVzdGUgY29sZWN0aXZvLg0KDQojIyMgRW4gcXXDqSBydWJyb3Mgc2UgZGEgbGEgbWF5b3IgdGFzYSBkZSBkaXZlcnNpZGFkDQoNCkFob3JhIGFuYWxpY2Vtb3MgbG9zIHJ1YnJvcy4gRGFkbyBxdWUgbm8gdGVuZW1vcyBtdWNoYXMgcGVyc29uYXMgY29uIGRpdmVyc2FzIGlkZW50aWRhZGVzIGRlIGfDqW5lcm8sIGxpc3RhcmVtb3MgdG9kb3MgbG9zIHJ1YnJvcy4NCg0KYGBge3IgcnVicm9zMDF9DQpndChkaXZfcmggJT4lIA0KICBmaWx0ZXIoaWRlbnRpZGFkX2dlbmVybyA9PSAiR8OpbmVybyBkaXZlcnNvIikgJT4lIA0KICBzZWxlY3QoUnVicm8gPSBydWJybykgJT4lIA0KICBncm91cF9ieShSdWJybykgJT4lIA0KICB0YWxseShzb3J0ID0gVCwgbmFtZSA9ICJSZXNwdWVzdGFzIikgJT4lIA0KICAgIGphbml0b3I6OmFkb3JuX3RvdGFscygpDQopDQpgYGANCg0KQWhvcmEsIHJlcGxpcXVlbW9zIGVsIGFuw6FsaXNpcyBjb24gbGEgcHJlZ3VudGEgKirCv1RlIGlkZW50aWZpY8OhcyBjb21vIExHQlRJUSsgKGxlc2JpYW5hLCBnYXksIGJpc2V4dWFsLCB0cmFuc2V4dWFsLCBvdHJhIG1pbm9yw61hIHNleHVhbCk/LioqDQoNCmBgYHtyIHJ1YnJvc19jb2xlY3Rpdm99DQpndCgNCmRpdl9yaCAlPiUgDQogIGZpbHRlcihkaXZlcnNpZGFkX3NleHVhbCA9PSAiU2kiKSAlPiUgDQogIHNlbGVjdChSdWJybyA9IHJ1YnJvKSAlPiUgDQogIGdyb3VwX2J5KFJ1YnJvKSAlPiUgDQogIHRhbGx5KHNvcnQgPSBULCBuYW1lID0gIlJlc3B1ZXN0YXMiKQ0KKQ0KYGBgDQoNCkVudHJlIGxvcyBwcmltZXJvcyBydWJyb3MgKGZ1ZXJhIGRlICpPdHJvcyopIG5vcyBlbmNvbnRyYW1vcyBjb24gYWN0aXZpZGFkZXMgcmVsYWNpb25hZGFzIGNvbiBzZXJ2aWNpb3MuIFJlY2nDqW4gZW4gZWwgNsKwIHB1ZXN0byBub3MgZW5jb250cmFtb3MgY29uIGVsIHByaW1lciBydWJybyByZWxhY2lvbmFkbyBjb24gbGEgaW5kdXN0cmlhIG1hbnVmYWN0dXJlcmEgKCpBbGltZW50b3MqKS4NCg0KIyMjIFF1w6kgcm9sZXMgZWplcmNlbiBsYXMgcGVyc29uYXMgZGl2ZXJzYXMNCg0KUG9yIMO6bHRpbW8sIHZlYW1vcyBlbiBxdcOpIHJvbGVzIHNlIGRlc2VtcGXDsWFuIGxhcyBwZXJzb25hcyBxdWUgcGVydGVuZWNlbiBhIGFsZ8O6biBjb2xlY3Rpdm8gZGUgZGl2ZXJzaWRhZCBkZW50cm8gZGUgUlJISC4NCg0KYGBge3Igcm9sZXN9DQojIENyZWFyIHVuIGZsYWcgcGFyYSBwb3NpY2lvbmVzIGRlIG1hbmFnZXIgKEdlcmVudGUsIEplZmUgbyBSZXNwb25zYWJsZSkNCmRpdl9yaCA8LSBkaXZfcmggJT4lIA0KICBtdXRhdGUobWFuYWdlciA9IGlmX2Vsc2UocHVlc3RvICVpbiUgYygiR2VyZW50ZSIsICJKZWZlIiwgIlJlc3BvbnNhYmxlIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAwKSkNCg0KIyBTaSBlbCB2YWxvciBkZSBsYSBjb2x1bW5hIGlkZW50aWRhZF9nZW5lcm8gZXMgaWd1YWwgYSBHw6luZXJvIGRpdmVyc28gbyBlbCB2YWxvciBkZSBsYSBjb2x1bW5hIGRpdmVyc2lkYWRfc2V4dWFsIGVzIGlndWFsIGEgU2ksIGVudG9uY2VzIGVsIHZhbG9yIGVuIGxhIG51ZXZhIGNvbHVtbmEgbGxhbWFkYSBkaXZlcnNhIGVzIDEsIGRlIGxvIGNvbnRyYXJpbyBwb25lciAwLg0KZGl2X3JoIDwtIGRpdl9yaCAlPiUgDQogIG11dGF0ZShkaXZlcnNhID0gaWZfZWxzZShpZGVudGlkYWRfZ2VuZXJvID09ICJHw6luZXJvIGRpdmVyc28iIHwgZGl2ZXJzaWRhZF9zZXh1YWwgPT0gIlNpIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDApKQ0KDQptYW5hZ2Vyc19wb3JjZW50YWplIDwtIGRpdl9yaCAlPiUgDQogIGZpbHRlcihkaXZlcnNhID09IDEpICU+JSANCiAgZ3JvdXBfYnkobWFuYWdlcikgJT4lIA0KICBjb3VudCgpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgbXV0YXRlKHBvcmNlbnRhamUgPSBuL3N1bShuKSkNCg0KcHVlc3Rvc19wb3JjZW50YWplIDwtIGRpdl9yaCAlPiUgDQogIGZpbHRlcihkaXZlcnNhID09IDEpICU+JSANCiAgZ3JvdXBfYnkocHVlc3RvKSAlPiUgDQogIGNvdW50KHNvcnQgPSBUKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIG11dGF0ZShwb3JjZW50YWplID0gbi9zdW0obikpDQoNCiMgVmlzdWFsaXphY2nDs24NCmdncGxvdChwdWVzdG9zX3BvcmNlbnRhamUsIGFlcyh4ID0gbiwgeSA9IHJlb3JkZXIocHVlc3RvLCBuKSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9IHZlcmRlKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwgDQogICAgICAgICAgICBoanVzdCA9IDEuMywNCiAgICAgICAgICAgIHNpemUgPSA0KSArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIlJvbGVzIHF1ZSBvY3VwYW4gbGFzIHBlcnNvbmFzIGRpdmVyc2FzIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCmBgYA0KDQpBbGdvIGludGVyZXNhbnRlIGRlIGVzdGUgZ3LDoWZpY28gZXMgcXVlIHVuIGByIHNjYWxlczo6cGVyY2VudChwdWxsKG1hbmFnZXJzX3BvcmNlbnRhamVbMiwzXSkpYCBvY3VwYW4gYWxnw7puIHB1ZXN0byBqZXLDoXJxdWljbyAoZGVmaW5pZG9zIGNvbW8gYEdlcmVudGVgLCBgSmVmZWAsIG8gYFJlc3BvbnNhYmxlYCkgbG8gY3VhbCBub3MgcGFyZWNlIGFsZ28gcG9zaXRpdm8uDQoNClPDs2xvIDYgcGVyc29uYXMsIHVuIGByIHNjYWxlczo6cGVyY2VudChwdWxsKHB1ZXN0b3NfcG9yY2VudGFqZVs2LDNdKSlgLCB0cmFiYWphbiBwb3Igc3UgY3VlbnRhIGNvbW8gYENvbnN1bHRvciBGcmVlbGFuY2VgLCBlbCBjdWFsIGVzIHVuIGRhdG8gYWxlbnRhZG9yIG1pcsOhbmRvbG8gZGVzZGUgZWwgcHVudG8gZGUgdmlzdGEgZGUgbGEgZm9ybWFsaWRhZCBsYWJvcmFsIHkgbGEgZXN0YWJpbGlkYWQuDQoNCkVzdG9zIHNvbiBkYXRvcyBxdWUgZXN0w6FuIHNlc2dhZG9zIHBvciBsYSBtdWVzdHJhIGRlIGRhdG9zLCBwZXJvIGxhIGhpcMOzdGVzaXMgaW5pY2lhbCBxdWUgdGVuw61hbW9zIGVyYSBxdWUgZWwgcG9yY2VudGFqZSBkZSBmcmVlbGFuY2VycyBzZXLDrWEgbWF5b3IgZW4gZXN0ZSBjYXNvLg0KDQojIyMgTGliZXJ0YWQgZW4gZWwgdHJhYmFqbw0KDQpFbiBsYXMgw7psdGltYXMgZWRpY2lvbmVzIGRlIGxhIEVuY3Vlc3RhIEtJV0kgaW5jbHVpbW9zIGRvcyBwcmVndW50YXMsIHVuYSBmdWUgc2kgKipFbiB0dSBlbXByZXNhIHB1ZWRlcyBzZXIgY29tbyByZWFsbWVudGUgZXJlcywgcG9yIGVqLiBleHByZXNhciBhYmllcnRhbWVudGUgdHUgcGVyc29uYWxpemFkYSwgdHUgaWRlbnRpZGFkIGRlIGfDqW5lcm8sIG9yaWVudGFjacOzbiBzZXh1YWwsIGV0Yy4uKiogeSBsYSBvdHJhIGZ1ZSAqKsK/U3VmcmlzdGUgYWxndW5hIHNpdHVhY2nDs24gZGUgYWNvc28sIGFidXNvIG8gZGUgZGlzY3JpbWluYWNpw7NuIGVuIGFsZ8O6biB0cmFiYWpvPyoqLCBjb24gbGFzIGN1YWxlcyBhcHVudMOhYmFtb3MgYSBhbmFsaXphciBxdcOpIHRhbiBhYmllcnRvcyBzb24gbG9zIGx1Z2FyZXMgZGUgdHJhYmFqbywgeSBxdcOpIHRhbiBzZWd1cmFzIHkgbGlicmVzIHNlIHNpZW50ZW4gbGFzIHBlcnNvbmFzIGNvbiBzdSBsdWdhciBkZSB0cmFiYWpvLg0KDQpFbiBlc3RhIHNlY2Npw7NuIHZhbW9zIGEgY29tcGFyYXIgbG9zIHJlc3VsdGFkb3MgZGUgZXN0YXMgcHJlZ3VudGFzIGRlIGFjdWVyZG8gYSBzaSBsYXMgcGVyc29uYXMgcGVydGVuZWNlbiBhIGFsZ8O6biBjb2xlY3Rpdm8gZGUgZGl2ZXJzaWRhZCBvIG5vLg0KDQpFc3RhcyBlcmFuIHByZWd1bnRhcyB2b2x1bnRhcmlhcyBlbiBsYXMgZWRpY2lvbmVzIGRlbCAyMDIxIHkgZGVsIDIwMjIgYXPDrSBxdWUgbm8gdG9kYXMgbGFzIHBlcnNvbmFzIGxhIHJlc3BvbmRpZXJvbiwgeSBubyBlc3RhYmFuIGluY2x1aWRhcyBlbiBsYSBlZGljacOzbiBkZWwgMjAyMC4NCg0KYGBge3IgbGliZXJ0YWR9DQojIExpbXBpYXIgY2FtcG9zDQpsaWJlcnRhZCA8LSBkaXZfcmggJT4lIA0KICBmaWx0ZXIobGliZXJ0YWRfc2VyICVpbiUgYygiRGUgYWN1ZXJkbyIsICJFbiBkZXNhY3VlcmRvIiwgIk5pIGRlIGFjdWVyZG8gbmkgZW4gZGVzYWN1ZXJkbyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVG90YWxtZW50ZSBkZSBhY3VlcmRvIiwgIlRvdGFsbWVudGUgZW4gZGVzYWN1ZXJkbyIpLA0KICAgICAgICAgIWlzLm5hKGRpdmVyc2EpKQ0KDQojIE9yZGVuYXIgbGEgamVyYXJxdcOtYSBkZSBsYXMgcmVzcHVlc3RhcyBzb2JyZSBsaWJlcnRhZCBlbiBlbCB0cmFiYWpvLg0KbGliZXJ0YWQgPC0gbGliZXJ0YWQgJT4lIA0KICBtdXRhdGUobGliZXJ0YWRfc2VyID0gZmFjdG9yKGxpYmVydGFkX3NlciwgbGV2ZWxzID0gYygiVG90YWxtZW50ZSBkZSBhY3VlcmRvIiwgIkRlIGFjdWVyZG8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5pIGRlIGFjdWVyZG8gbmkgZW4gZGVzYWN1ZXJkbyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbiBkZXNhY3VlcmRvIiwgIlRvdGFsbWVudGUgZW4gZGVzYWN1ZXJkbyIpKSkgDQpgYGANCg0KQ29tcGFyZW1vcyBsYXMgcmVzcHVlc3RhcyBzZWfDum4gc2kgbGFzIHBlcnNvbmFzIHBlcnRlbmVjZW4gYSBhbGfDum4gY29sZWN0aXZvIGRlIGRpdmVyc2lkYWQgbyBuby4NCg0KYGBge3IgbGliZXJ0YWRfMX0NCmxpYmVydGFkX3Njb3JlcyA8LSBsaWJlcnRhZCAlPiUNCiAgbXV0YXRlKGRpdmVyc2EgPSBmYWN0b3IoZGl2ZXJzYSkpICU+JSANCiAgZ3JvdXBfYnkoZGl2ZXJzYSwgbGliZXJ0YWRfc2VyKSAlPiUgDQogIHN1bW1hcmlzZShyZXNwdWVzdGFzID0gbigpKSAlPiUgDQogIG11dGF0ZShwb3JjZW50YWplID0gcmVzcHVlc3Rhcy9zdW0ocmVzcHVlc3RhcykpIA0KDQpnZ3Bsb3QobGliZXJ0YWRfc2NvcmVzLCBhZXMoeSA9IGRpdmVyc2EsIHggPSByZXNwdWVzdGFzLCBmaWxsID0gbGliZXJ0YWRfc2VyKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKGF6dWwsIGxpbGEsIGdyaXMsIHJvc2EyLCByb3NhMSkpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudChwb3JjZW50YWplLCBhY2N1cmFjeSA9IDEpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9maWxsKHZqdXN0ID0gMC41KSwgc2l6ZSA9IDMpICsNCiAgZXN0aWxvICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDUpLA0KICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiI0ZDRkNGQyIpKSArDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkgKw0KICBsYWJzKHRpdGxlID0gIk5pdmVsZXMgZGUgbGliZXJ0YWQgZW4gZWwgdHJhYmFqbyIsDQogICAgICAgc3VidGl0bGUgPSAiMDogUGVyc29uYXMgbm8gZGl2ZXJzYXMgLSAxOiBQZXJzb25hcyBkaXZlcnNhcyIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLCBjYXB0aW9uID0gZnVlbnRlLA0KICAgICAgIGZpbGwgPSAiTGliZXJ0YWQgcGFyYVxuc2VyIHVubyBtaXNtbyIpDQoNCmBgYA0KDQpObyBoYXkgZ3JhbmRlcyBkaWZlcmVuY2lhcyBlbnRyZSBsb3MgcmVzdWx0YWRvcyBkZSBhbWJvcyBncnVwb3MuIEVuIGxhIG9wY2nDs24gKlRvdGFsbWVudGUgZGUgYWN1ZXJkbyogZXMgZG9uZGUgZW5jb250cmFtb3MgbGEgbWF5b3IgZGlmZXJlbmNpYSAoNiUpLiBTaSBhZ3J1cGFtb3MgbGFzIHJlc3B1ZXN0YXMgKlRvdGFsbWVudGUgZW4gZGVzYWN1ZXJkbyogeSAqRW4gZGVzYWN1ZXJkbyosIGxhIGRpZmVyZW5jaWEgdG90YWwgZXMgZGUgOSUuDQoNCioqTWUgcGFyZWNlIG11eSBwb3NpdGl2byBxdWUgMiBkZSBjYWRhIDMgcGVyc29uYXMgKGVsIDY1JSkgZGUgY29sZWN0aXZvcyBkZSBkaXZlcnNpZGFkIHNpZW50YW4gcXVlIHB1ZWRlbiBzZXIgY29tbyBzb24gZW4gc3VzIHJlc3BlY3Rpdm9zIHRyYWJham9zLioqDQoNCkFob3JhIGNvbXBhcmVtb3MgbGFzIHJlc3B1ZXN0YXMgYSBsYSBwcmVndW50YSAqKsK/U3VmcmlzdGUgYWxndW5hIHNpdHVhY2nDs24gZGUgYWNvc28sIGFidXNvIG8gZGUgZGlzY3JpbWluYWNpw7NuIGVuIGFsZ8O6biB0cmFiYWpvPy4qKiBQcmltZXJvLCBhbmFsaWNlbW9zIGxvcyByZXN1bHRhZG9zIHNlZ8O6biBzaSBsYSBwZXJzb25hIHBlcnRlbmVjZSBhIGFsZ8O6biBjb2xlY3Rpdm8gZGUgZGl2ZXJzaWRhZCBvIG5vLg0KDQpgYGB7ciBkaXNjcmltaW5hY2lvbn0NCmRpdl9yaCAlPiUgDQogIG11dGF0ZShzdWZyaW9fYWNvc28gPSANCiAgICAgICAgICAgZmN0X2NvbGxhcHNlKHN1ZnJpb19hY29zbywNCiAgICAgICAgICAgICAgICAgICAgICAgICJTaSIgPSBjKCJTaSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFncmVzacOzbiB2ZXJiYWwuIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTW9iYmluZyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm8gZW4gZWwgYWN0dWFsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTw60uIFNvbiBzdXRpbGVzIHBlcm8gZXN0w6FuLiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vLiBQZXJvIHNpIG11Y2hvcyBjb21lbnRhcmlvcyBtYXJjaGlzdGFzIGR1cmFudGUgbWkgY2FycmVyYS4gTm8gYWhvcmEuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTw60gY2xhcm8sIGFidXNvIGRlIGF1dG9yaWRhZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWxndW5hIHZleiBzdWZyw60gbWFsdHJhdG8gcHNpY29sw7NnaWNvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMbyBtw6F4aW1vIGZ1ZSBcInNvcyBsZXNiaWFuYSBwb3JxdWUgbm8gdGUgbWFxdWlsbGFzXCIiDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkpICU+JSANCiAgZmlsdGVyKHN1ZnJpb19hY29zbyAlaW4lIGMoIlNpIiwgIk5vIiksIA0KICAgICAgICAgIWlzLm5hKGRpdmVyc2EpKSAlPiUgDQogIGdyb3VwX2J5KGRpdmVyc2EsIHN1ZnJpb19hY29zbykgJT4lIA0KICBzdW1tYXJpc2UoY2FudGlkYWQgPSBuKCkpICU+JQ0KICBtdXRhdGUocG9yY2VudGFqZSA9IGNhbnRpZGFkL3N1bShjYW50aWRhZCkpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmFjdG9yKGRpdmVyc2EpLCB5ID0gY2FudGlkYWQsIGZpbGwgPSBzdWZyaW9fYWNvc28pKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKGNhbnRpZGFkLCAiICgiLCBzY2FsZXM6OnBlcmNlbnQocG9yY2VudGFqZSwgYWNjdXJhY3kgPSAxKSwgIikiKSksDQogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksIHZqdXN0ID0gLTAuMywgc2l6ZSA9IDMpICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiUGVyc29uYXMgcXVlIHN1ZnJpZXJvbiBhY29zbywgYWJ1c28gbyBkaXNjcmltaW5hY2nDs25cbnNlZ8O6biBjb2xlY3Rpdm8gZGUgZGl2ZXJzaWRhZCIsICBzdWJ0aXRsZSA9ICIwOiBQZXJzb25hcyBubyBkaXZlcnNhcyAtIDE6IFBlcnNvbmFzIGRpdmVyc2FzIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsIGNhcHRpb24gPSBmdWVudGUsDQogICAgICAgZmlsbCA9ICJTdWZyacOzIGFjb3NvLCBhYnVzbyBvIGRpc2NyaW1pbmFjacOzbiIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhuYXJhbmphLCBncmlzKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDQ1MCkpDQoNCmBgYA0KDQpFbCAzNCUgZGUgbGFzIHBlcnNvbmFzIGRpdmVyc2FzLCB5YSBzZWEgcG9yIHN1IGlkZW50aWRhZCBkZSBnw6luZXJvIG8gcG9yIHN1IG9yaWVudGFjacOzbiBzZXh1YWwgc3Vmcmllcm9uIGFsZ3VuYSBzaXR1YWNpw7NuIGRlIGFjb3NvLCBhYnVzbywgbyBkaXNjcmltaW5hY2nDs24sIGZyZW50ZSBhIHVuIDI4JSBkZSBsYXMgcGVyc29uYXMgY2lzIHkgaGV0ZXJvc2V4dWFsZXMuDQoNCkFob3JhIGRlc2FncmVndWVtb3MgZWwgZ3LDoWZpY28gYW50ZXJpb3Igc2Vnw7puIGxhIGlkZW50aWRhZCBkZSBnw6luZXJvIGRlIGxhcyBwZXJzb25hczoNCg0KYGBge3J9DQpkaXZfcmggJT4lIA0KICBtdXRhdGUoc3VmcmlvX2Fjb3NvID0gZmN0X2NvbGxhcHNlKHN1ZnJpb19hY29zbywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2kiID0gYygiU2kiLCAiYWdyZXNpw7NuIHZlcmJhbC4iLCAiTW9iYmluZyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5vIGVuIGVsIGFjdHVhbCIpKSkgJT4lIA0KICBmaWx0ZXIoc3VmcmlvX2Fjb3NvICVpbiUgYygiU2kiLCAiTm8iKSkgJT4lIA0KICBncm91cF9ieShpZGVudGlkYWRfZ2VuZXJvLCBzdWZyaW9fYWNvc28pICU+JSANCiAgc3VtbWFyaXNlKGNhbnRpZGFkID0gbigpKSAlPiUNCiAgbXV0YXRlKHBvcmNlbnRhamUgPSBjYW50aWRhZC9zdW0oY2FudGlkYWQpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGlkZW50aWRhZF9nZW5lcm8sIHkgPSBjYW50aWRhZCwgZmlsbCA9IHN1ZnJpb19hY29zbykpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZTAoY2FudGlkYWQsICIgKCIsIHNjYWxlczo6cGVyY2VudChwb3JjZW50YWplLCBhY2N1cmFjeSA9IDEpLCAiKSIpKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSwgdmp1c3QgPSAtMC4zLCBzaXplID0gMykgKw0KICBlc3RpbG9oICsNCiAgbGFicyh0aXRsZSA9ICJQZXJzb25hcyBxdWUgc3Vmcmllcm9uIGFjb3NvLCBhYnVzbyBvIGRpc2NyaW1pbmFjacOzblxuc2Vnw7puIHN1IGlkZW50aWRhZCBkZSBnw6luZXJvIiwgIHN1YnRpdGxlID0gIjA6IFBlcnNvbmFzIG5vIGRpdmVyc2FzIC0gMTogUGVyc29uYXMgZGl2ZXJzYXMiLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwgY2FwdGlvbiA9IGZ1ZW50ZSwNCiAgICAgICBmaWxsID0gIlN1ZnJpw7MgYWNvc28sIGFidXNvIG8gZGlzY3JpbWluYWNpw7NuIikgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKG5hcmFuamEsIGdyaXMpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsMzIwKSkNCmBgYA0KDQpFbiBlc3RlIMO6bHRpbW8gZ3LDoWZpY28gcG9kZW1vcyBhcHJlY2lhciBsYXMgZGlzdGludGFzIHJlYWxpZGFkZXMgZGUgbGFzIHBlcnNvbmFzLiAqKlVuIHRlcmNpbyBkZSBsYXMgbXVqZXJlcyBjaXMqKiAqKnN1ZnJpw7MgYWwgbWVub3MgdW5hIHZleiBhbGd1bmEgc2l0dWFjacOzbiBkZSBhY29zbywgYWJ1c28gbyBkaXNjcmltaW5hY2nDs24qKiB2ZXJzdXMgdW4gMTUlIGRlIGxvcyBob21icmVzIGNpcy4gTcOhcyBhbGzDoSBkZSBsYSBjYW50aWRhZCBkZSByZXNwdWVzdGFzIHJlY2liaWRhcywgbGFzIHRlbmRlbmNpYXMgc29uIGNsYXJhcy4NCg0KIyMjIE1hY2hpc21vDQoNCkxhIHNpZ3VpZW50ZSBwcmVndW50YSwgKirCv1NlbnTDrXMgcXVlIHR1IGVudG9ybm8gbGFib3JhbCBlcyBtYWNoaXN0YT8qKiwgbGEgcmVhbGl6YW1vcyBwb3IgcHJpbWVyYSB2ZXogZW4gMjAyMiwgYXPDrSBxdWUgZW4gcHJpbWVyIGx1Z2FyIGNvbXBhcmVtb3MgbG9zIHJlc3VsdGFkb3MgZW4gZnVuY2nDs24gZGUgc2kgbGFzIHBlcnNvbmFzIHNvbiBkaXZlcnNhcyBvIG5vLg0KDQpgYGB7ciBtYWNob18xfQ0KIyBDcmVhbW9zIHVuIGRhdGFmcmFtZSBlc3BlY8OtZmljbyBwYXJhIGVzdGUgYW7DoWxpc2lzLg0KbWFjaGlzbW8gPC0gZGl2X3JoICU+JSANCiAgZmlsdGVyKCFpcy5uYShkaXZlcnNhKSwNCiAgICAgICAgIG1hY2hpc21vICVpbiUgYygiTm8gZXMgdW4gZW50b3JubyBtYWNoaXN0YSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIlNpIHBlcm8gbm8gZXMgdGFudG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICJTaSwgZXMgbXV5IG1hY2hpc3RhIikpICU+JSANCiAgbXV0YXRlKG1hY2hpc21vID0gZmFjdG9yKG1hY2hpc21vLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk5vIGVzIHVuIGVudG9ybm8gbWFjaGlzdGEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2kgcGVybyBubyBlcyB0YW50byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTaSwgZXMgbXV5IG1hY2hpc3RhIikpKQ0KDQptYWNoaXNtb19zY29yZSA8LSBtYWNoaXNtbyAlPiUNCiAgbXV0YXRlKGRpdmVyc2EgPSBmYWN0b3IoZGl2ZXJzYSkpICU+JSANCiAgZ3JvdXBfYnkoZGl2ZXJzYSwgbWFjaGlzbW8pICU+JSANCiAgc3VtbWFyaXNlKHJlc3B1ZXN0YXMgPSBuKCkpICU+JSANCiAgbXV0YXRlKHBvcmNlbnRhamUgPSByZXNwdWVzdGFzL3N1bShyZXNwdWVzdGFzKSkgDQoNCmdncGxvdChtYWNoaXNtb19zY29yZSwgYWVzKHkgPSBkaXZlcnNhLCB4ID0gcmVzcHVlc3RhcywgZmlsbCA9IG1hY2hpc21vKSkgKw0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKGF6dWwsIHJvc2ExLCByb3NhMikpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudChwb3JjZW50YWplLCBhY2N1cmFjeSA9IDEpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9maWxsKHZqdXN0ID0gMC41KSwgc2l6ZSA9IDMpICsNCiAgZXN0aWxvICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDUpLA0KICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiI0ZDRkNGQyIpKSArDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkgKw0KICBsYWJzKHRpdGxlID0gIsK/U2VudMOtcyBxdWUgdHUgZW50b3JubyBsYWJvcmFsIGVzIG1hY2hpc3RhPyIsDQogICAgICAgc3VidGl0bGUgPSAiMDogUGVyc29uYXMgbm8gZGl2ZXJzYXMgLSAxOiBQZXJzb25hcyBkaXZlcnNhcyIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLCBjYXB0aW9uID0gZnVlbnRlLA0KICAgICAgIGZpbGwgPSAiUmVzcHVlc3RhOiIpDQpgYGANCkVudHJlIGxhcyBwZXJzb25hcyBkaXZlcnNhcyBlbmNvbnRyYW1vcyByZXNwdWVzdGFzIGNvbiBtYXlvciBjYW50aWRhZCBkZSByZXNwdWVzdGFzIGVuIGxvcyBleHRyZW1vcywgYHIgcGVyY2VudChwdWxsKG1hY2hpc21vX3Njb3JlWzQsNF0pKWAgbm8gc2llbnRlbiBxdWUgc3UgZW50b3JubyBzZWEgbWFjaGlzdGEsIHkgdW4gYHIgcGVyY2VudChwdWxsKG1hY2hpc21vX3Njb3JlWzYsNF0pKWAgc2llbnRlbiBxdWUgZXMgbXV5IG1hY2hpc3RhLg0KDQpFbnRyZSBsYXMgcGVyc29uYXMgaGV0ZXJvbm9ybWF0aXZhcyB1biBgciBwZXJjZW50KHB1bGwobWFjaGlzbW9fc2NvcmVbMiw0XSkpYCBxdWUgc3UgZW50b3JubyBubyBlcyB0YW4gbWFjaGlzdGEuDQoNCkFuYWxpemFuZG8gbGFzIHJlc3B1ZXN0YXMgc2Vnw7puIGxhIGlkZW50aWRhZCBkZSBnw6luZXJvLCBubyBzb3JwcmVuZGUgcXVlIGxhcyBtdWplcmVzIHRlbmdhbiB1bmEgcGVyY2VwY2nDs24gbWF5b3IgcXVlIGxvcyBob21icmVzIHNvYnJlIHNpIGVsIGVudG9ybm8gbGFib3JhbCBlcyBtYWNoaXN0YS4NCg0KYGBge3J9DQptYWNoaXNtb19nZW5lcm8gPC0gbWFjaGlzbW8gJT4lDQogIGZpbHRlcihpZGVudGlkYWRfZ2VuZXJvICE9ICJNdWplciB0cmFucyIpICU+JSANCiAgZ3JvdXBfYnkoaWRlbnRpZGFkX2dlbmVybywgbWFjaGlzbW8pICU+JSANCiAgc3VtbWFyaXNlKHJlc3B1ZXN0YXMgPSBuKCkpICU+JSANCiAgbXV0YXRlKHBvcmNlbnRhamUgPSByZXNwdWVzdGFzL3N1bShyZXNwdWVzdGFzKSkgDQoNCmdncGxvdChtYWNoaXNtb19nZW5lcm8sIGFlcyh5ID0gaWRlbnRpZGFkX2dlbmVybywgeCA9IHJlc3B1ZXN0YXMsIGZpbGwgPSBtYWNoaXNtbykpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhhenVsLCByb3NhMSwgcm9zYTIpKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQocG9yY2VudGFqZSwgYWNjdXJhY3kgPSAxKSksIHBvc2l0aW9uID0gcG9zaXRpb25fZmlsbCh2anVzdCA9IDAuNSksIHNpemUgPSAzKSArDQogIGVzdGlsbyArDQogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA1KSwNCiAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gIiNGQ0ZDRkMiKSkgKw0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSkpICsNCiAgbGFicyh0aXRsZSA9ICLCv1NlbnTDrXMgcXVlIHR1IGVudG9ybm8gbGFib3JhbCBlcyBtYWNoaXN0YT8iLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwgY2FwdGlvbiA9IGZ1ZW50ZSwNCiAgICAgICBmaWxsID0gIlJlc3B1ZXN0YToiKQ0KYGBgDQoNCg0KQW5hbGljZW1vcyBsYSBzaXR1YWNpw7NuIHBvciBydWJyb3M6DQoNCmBgYHtyIGZpZy5oZWlnaHQ9N30NCm1hY2hpc21vX3J1YnJvIDwtIG1hY2hpc21vICU+JQ0KICBtdXRhdGUoZGl2ZXJzYSA9IGZhY3RvcihkaXZlcnNhKSkgJT4lIA0KICBncm91cF9ieShydWJybywgbWFjaGlzbW8pICU+JSANCiAgc3VtbWFyaXNlKHJlc3B1ZXN0YXMgPSBuKCkpICU+JSANCiAgbXV0YXRlKHBvcmNlbnRhamUgPSByZXNwdWVzdGFzL3N1bShyZXNwdWVzdGFzKSkgDQoNCmdncGxvdChtYWNoaXNtb19ydWJybywgYWVzKHkgPSBmY3RfcmV2KHJ1YnJvKSwgeCA9IHJlc3B1ZXN0YXMsIGZpbGwgPSBtYWNoaXNtbykpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhhenVsLCByb3NhMSwgcm9zYTIpKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQocG9yY2VudGFqZSwgYWNjdXJhY3kgPSAxKSksIHBvc2l0aW9uID0gcG9zaXRpb25fZmlsbCh2anVzdCA9IDAuNSksIHNpemUgPSAzKSArDQogIGVzdGlsbyArDQogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA1KSwNCiAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gIiNGQ0ZDRkMiKSkgKw0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSkpICsNCiAgbGFicyh0aXRsZSA9ICLCv1NlbnTDrXMgcXVlIHR1IGVudG9ybm8gbGFib3JhbCBlcyBtYWNoaXN0YT8iLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwgY2FwdGlvbiA9IGZ1ZW50ZSwNCiAgICAgICBmaWxsID0gIlJlc3B1ZXN0YToiKQ0KYGBgDQpFbiBsYSB2aXN1YWxpemFjacOzbiBhbnRlcmlvciBwb2RlbW9zIHZlciBxdWUgbG9zIHJ1YnJvcyBxdWUgaGF5IG1lbm9yIHBlcmNlcGNpw7NuIGRlIG1hY2hpc21vLCBzb24gZW4gKlNlcnZpY2lvcyBwcm9mZXNpb25hbGVzKiwgKk1lZGlvcyosIHkgKkNvbnN1bHRvcsOtYSouIEVuIGVsIG90cm8gZXh0cmVtbywgcG9yIGNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMsIG5vcyBlbmNvbnRyYW1vcyBxdWUgbG9zIHJ1YnJvcyAqQWxpbWVudG9zKiwgKlRlY25vbG9nw61hKiwgeSAqU2VydmljaW9zIGRlIFNhbHVkKi4NCg0KYGBge3J9DQptYWNoaXNtb19ydWJybyAlPiUgDQogIHNlbGVjdCgtcG9yY2VudGFqZSkgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gbWFjaGlzbW8sIHZhbHVlc19mcm9tID0gcmVzcHVlc3RhcykgJT4lIA0KICBtdXRhdGUoYE5vIGVzIHVuIGVudG9ybm8gbWFjaGlzdGFgID0gY29hbGVzY2UoYE5vIGVzIHVuIGVudG9ybm8gbWFjaGlzdGFgLCAwKSwNCiAgICAgICAgIGBTaSBwZXJvIG5vIGVzIHRhbnRvYCA9IGNvYWxlc2NlKGBTaSBwZXJvIG5vIGVzIHRhbnRvYCwgMCksDQogICAgICAgICBgU2ksIGVzIG11eSBtYWNoaXN0YWAgPSBjb2FsZXNjZShgU2ksIGVzIG11eSBtYWNoaXN0YWAsIDApLA0KICAgICAgICAgVG90YWwgPSBgTm8gZXMgdW4gZW50b3JubyBtYWNoaXN0YWAgKyBgU2kgcGVybyBubyBlcyB0YW50b2AgKyBgU2ksIGVzIG11eSBtYWNoaXN0YWApICU+JSANCiAgcmVuYW1lKFJ1YnJvID0gcnVicm8pICU+JSANCiAgICAgIGFycmFuZ2UoLVRvdGFsKSAlPiUgDQogIGtibChjYXB0aW9uID0gIlBlcmNlcGNpw7NuIGRlIE1hY2hpc21vIHBvciBSdWJybyIpICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRiwgcG9zaXRpb24gPSAiY2VudGVyIiwNCiAgICAgICAgICAgICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIikpICU+JSANCiAgc2Nyb2xsX2JveChoZWlnaHQgPSAiNTAwcHgiKQ0KYGBgDQojIyBEaXNjYXBhY2lkYWQNCg0KYGBge3IgZGlzY2FwYWNpZGFkXzF9DQpkaXNjX3JoIDwtIGRpdl9yaCAlPiUNCiAgZmlsdGVyKCFpcy5uYShkaXNjYXBhY2lkYWQpKSAlPiUgDQogIG11dGF0ZShkaXNjYXBhY2lkYWQgPSANCiAgICAgICAgICAgZmN0X2NvbGxhcHNlKGRpc2NhcGFjaWRhZCwgDQogICAgICAgICAgICAgICAgICAgICAgICAiU2luIGRpc2NhcGFjaWRhZCIgPSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgYygiTm8gdGVuZ28gbmluZ3VuYSBkaXNjYXBhY2lkYWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjcmVvIG5vIHRlbmVyIGphamFqYSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJWaXN1YWw/Pz8iKSksDQogICAgdGllbmVfZGlzY2FwYWNpZGFkID0gaWZfZWxzZShkaXNjYXBhY2lkYWQgJWluJSBjKCJTaW4gZGlzY2FwYWNpZGFkIiwgIlByZWZpZXJvIG5vIHJlc3BvbmRlciIpLCAwLCAxKSkNCmBgYA0KDQpWZWFtb3MgY3XDoW50YXMgcGVyc29uYXMgY29uIGFsZ3VuYSBkaXNjYXBhY2lkYWQgcGFydGljaXBhcm9uIGRlIGxhIGVkaWNpw7NuIGFjdHVhbDoNCg0KYGBge3J9DQpraXdpIDwtIGtpd2kgJT4lIA0KICBtdXRhdGUoZGlzY2FwYWNpZGFkID0gDQogICAgICAgICAgIGZjdF9jb2xsYXBzZShkaXNjYXBhY2lkYWQsDQogICAgICAgICAgICAgICAgICAgICAgICAiU2luIGRpc2NhcGFjaWRhZCIgPSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgYygiTm8gdGVuZ28gbmluZ3VuYSBkaXNjYXBhY2lkYWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjcmVvIG5vIHRlbmVyIGphamFqYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlZpc3VhbD8/PyIpKSwNCiAgICAgICAgIHRpZW5lX2Rpc2NhcGFjaWRhZCA9IGZhY3RvcihpZl9lbHNlKGRpc2NhcGFjaWRhZCA9PSAiU2luIGRpc2NhcGFjaWRhZCIsIDAsIDEpKSkNCg0KZGl2IDwtIGtpd2kgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKGRpc2NhcGFjaWRhZCkpICU+JSANCiAgc2VsZWN0KHRpZW5lX2Rpc2NhcGFjaWRhZCkgJT4lIA0KICBncm91cF9ieSh0aWVuZV9kaXNjYXBhY2lkYWQpICU+JSANCiAgc3VtbWFyaXNlIChuID0gbigpKSAlPiUgDQogIG11dGF0ZShmcmVxID0gbi9zdW0obikpICU+JSANCiAgYXJyYW5nZSgtbikNCg0KIyBDb21wdXRlIHRoZSBjdW11bGF0aXZlIHBlcmNlbnRhZ2VzICh0b3Agb2YgZWFjaCByZWN0YW5nbGUpDQpkaXYkeW1heCA8LSBjdW1zdW0oZGl2JGZyZXEpDQoNCiMgQ29tcHV0ZSB0aGUgYm90dG9tIG9mIGVhY2ggcmVjdGFuZ2xlDQpkaXYkeW1pbiA8LSBjKDAsIGhlYWQoZGl2JHltYXgsIG49LTEpKQ0KDQojIENvbXB1dGUgbGFiZWwgcG9zaXRpb24NCmRpdiRsYWJlbFBvc2l0aW9uIDwtIChkaXYkeW1heCArIGRpdiR5bWluKSAvIDINCg0KIyBDb21wdXRlIGEgZ29vZCBsYWJlbA0KZGl2JGxhYmVsIDwtIHBhc3RlMChkaXYkZ2VuZXJvLCAiXG4gQ2FudDogIiwgZGl2JG4pDQoNCiMgTWFrZSB0aGUgcGxvdA0KZ2dwbG90KGRpdiwgYWVzKHltYXg9eW1heCwgeW1pbj15bWluLCB4bWF4PTQsIHhtaW49MywgZmlsbD10aWVuZV9kaXNjYXBhY2lkYWQpKSArDQogIGdlb21fcmVjdCgpICsNCiAgY29vcmRfcG9sYXIodGhldGE9InkiKSArICMgVHJ5IHRvIHJlbW92ZSB0aGF0IHRvIHVuZGVyc3RhbmQgaG93IHRoZSBjaGFydCBpcyBidWlsdCBpbml0aWFsbHkNCiAgeGxpbShjKDIsIDQpKSArIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gc2VlIGhvdyB0byBtYWtlIGEgcGllIGNoYXJ0DQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoZ3JpcywgbmFyYW5qYSkpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIsDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIlJvYm90byIpKSArDQogIGxhYnModGl0bGUgPSAiUmVzcHVlc3RhcyBzZWfDum4gZGlzY2FwYWNpZGFkIiwNCiAgICAgICBzdWJ0aXRsZSA9ICIxOiBUaWVuZSBhbGd1bmEgZGlzY2FwYWNpZGFkIC0gMDogU2luIGRpc2NhcGFjaWRhZCIsDQogICAgICAgZmlsbCA9ICJEaXNjYXBhY2lkYWQiLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KYGBgDQoNCmBgYHtyfQ0KZ3Qoa2l3aSAlPiUgDQogIGZpbHRlcighaXMubmEoZGlzY2FwYWNpZGFkKSkgJT4lIA0KICBncm91cF9ieSh0aWVuZV9kaXNjYXBhY2lkYWQpICU+JSANCiAgdGFsbHkobmFtZSA9ICJSZXNwdWVzdGFzIikgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBtdXRhdGUoUG9yY2VudGFqZSA9IFJlc3B1ZXN0YXMvc3VtKFJlc3B1ZXN0YXMpLA0KICAgICAgICAgdGllbmVfZGlzY2FwYWNpZGFkID0gZmFjdG9yKHRpZW5lX2Rpc2NhcGFjaWRhZCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygwLCAxKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiTm8iLCAiU2kiKSkpKSAlPiUgDQogIGNvbHNfbGFiZWwodGllbmVfZGlzY2FwYWNpZGFkID0gIkNvbiBEaXNjYXBhY2lkYWQiKSAlPiUgDQogIHN1bW1hcnlfcm93cyhjb2x1bW5zID0gYyhSZXNwdWVzdGFzLCBQb3JjZW50YWplKSwNCiAgICBmbnMgPSBsaXN0KFRvdGFsID0gInN1bSIpKSAlPiUgDQogIGZtdF9wZXJjZW50KGNvbHVtbnMgPSBQb3JjZW50YWplLA0KICAgICAgICAgICAgICBkZWNpbWFscyA9IDEpICU+JSANCiAgdGFiX2hlYWRlcih0aXRsZSA9ICJSZXNwdWVzdGFzIHNlZ8O6biBkaXNjYXBhY2lkYWQiLA0KICAgICAgICAgICAgIHN1YnRpdGxlID0gIlJlbGFjacOzbiBkZSBEZXBlbmRlbmNpYSIpICU+JSANCiAgdGFiX3NvdXJjZV9ub3RlKHNvdXJjZV9ub3RlID0gZnVlbnRlKQ0KDQpgYGANCkVuIGxhIGFjdHVhbCBlZGljacOzbiBjb250YW1vcyBzw7NsbyBjb24gdW4gMi44JSBkZSBjb2xlZ2FzIGNvbiBhbGd1bmEgZGlzY2FwYWNpZGFkIHRyYWJhamFuZG8gZW4gUlJISCwgbGFzIGN1YWxlcyBzb24gbGFzIHNpZ3VpZW50ZXM6DQoNCmBgYHtyfQ0Ka2l3aSAlPiUgDQogIGZpbHRlcighaXMubmEoZGlzY2FwYWNpZGFkKSwNCiAgICAgICAgIHRpZW5lX2Rpc2NhcGFjaWRhZCA9PSAxKSAlPiUgDQogIGdyb3VwX2J5KGRpc2NhcGFjaWRhZCkgJT4lIA0KICBzdW1tYXJpc2UoY2FudCA9IG4oKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBjYW50LCB5ID0gcmVvcmRlcihkaXNjYXBhY2lkYWQsIGNhbnQpKSkgKw0KICBnZW9tX2NvbChmaWxsID0gbmFyYW5qYSkgKw0KICBlc3RpbG92ICsNCiAgbGFicyh0aXRsZSA9ICJUaXBvcyBkZSBEaXNjYXBhY2lkYWQiLA0KICAgICAgIHN1YnRpdGxlID0gIlJlbGFjacOzbiBkZSBEZXBlbmRlbmNpYSIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQpgYGANCg0KDQpWZWFtb3MgY8OzbW8gZnVlIGxhIGV2b2x1Y2nDs24gZGUgZXN0YSByZXNwdWVzdGEgYSBsbyBsYXJnbyBkZSBsYXMgZWRpY2lvbmVzIGRlIGVzdGEgZW5jdWVzdGEuDQoNCmBgYHtyfQ0KZGlzY19yaCAlPiUgDQogIGZpbHRlcih0aWVuZV9kaXNjYXBhY2lkYWQgPT0gMSkgJT4lIA0KICBncm91cF9ieShlZGljaW9uKSAlPiUgDQogIHN1bW1hcmlzZShjYW50ID0gbigpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZhY3RvcihlZGljaW9uKSwgeSA9IGNhbnQpKSArDQogIGdlb21fY29sKGZpbGwgPSBuYXJhbmphKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjYW50KSwNCiAgICAgICAgICAgIHZqdXN0ID0gMS4yLA0KICAgICAgICAgICAgc2l6ZSA9IDMpICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiUmVzcHVlc3RhcyBkZSBQZXJzb25hcyBjb24gRGlzY2FwYWNpZGFkIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJSZWxhY2nDs24gZGUgRGVwZW5kZW5jaWEiLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KDQpgYGANCg0KIyMjIFB1ZXN0b3MNCg0KU2kgYmllbiBsYSBtYXlvciBjYW50aWRhZCBkZSBwZXJzb25hcyBjb24gZGlzY2FwYWNpZGFkIGhpc3TDs3JpY2FtZW50ZSBzZSBkZXNlbXBlw7FhbiBlbiByb2xlcyBkZSBBbmFsaXN0YSwgZXMgaW50ZXJlc2FudGUgYXByZWNpYXIgcXVlIGVuIHRvdGFsIHRlbmVtb3MgcHLDoWN0aWNhbWVudGUgbGEgbWlzbWEgY2FudGlkYWQgKDE4KSBlbiByb2xlcyBkZSBsaWRlcmF6Z28gKEdlcmVudGUsIEplZmUgbyBSZXNwb3NhYmxlKS4NCg0KRXN0byBub3MgcGFyZWNlIHBvc2l0aXZvIHBvcnF1ZSBlcyB1bmEgbXVlc3RyYSBubyBzw7NsbyBkZSBkaXZlcnNpZGFkLCBzaW5vIHRhbWJpw6luIGRlIGluY2x1c2nDs24uIENvbnNpZGVyYW1vcyBxdWUgbm8gc8OzbG8gZXMgaW1wb3J0YW50ZSBjb250cmF0YXIgcGVyc29uYXMgY29uIGRpc2NhcGFjaWRhZCwgc2lubyB0YW1iacOpbiBkYXJsZXMgbGFzIG9wb3J0dW5pZGFkZXMgZGUgZGVzYXJyb2xsbyBxdWUgbGUgZGFyw61hbW9zIGEgY3VhbHF1aWVyIHBlcnNvbmEgZGUgbGEgY29tcGHDscOtYS4NCg0KYGBge3IgZGlzY19wdWVzdG99DQpndChkaXNjX3JoICU+JSANCiAgZmlsdGVyKCFpcy5uYShkaXNjYXBhY2lkYWQpLA0KICAgICAgICAgIWlzLm5hKHB1ZXN0byksDQogICAgICAgICB0aWVuZV9kaXNjYXBhY2lkYWQgPT0gMSkgJT4lIA0KICBncm91cF9ieShlZGljaW9uLCBwdWVzdG8pICU+JSANCiAgc3VtbWFyaXNlKGNhbnQgPSBuKCkpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gZWRpY2lvbiwNCiAgICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IGNhbnQpICU+JSANCiAgbXV0YXRlKGAyMDIwYCA9IGNvYWxlc2NlKGAyMDIwYCwgMCksDQogICAgICAgICBgMjAyMWAgPSBjb2FsZXNjZShgMjAyMWAsIDApLA0KICAgICAgICAgYDIwMjJgID0gY29hbGVzY2UoYDIwMjJgLCAwKSwNCiAgICAgICAgIFRvdGFsID0gYDIwMjBgK2AyMDIxYCtgMjAyMmApKSAlPiUgDQogIGNvbHNfbGFiZWwocHVlc3RvID0gIlB1ZXN0byIpICU+JSANCiAgdGFiX2hlYWRlcih0aXRsZSA9ICJQdWVzdG9zIGRlIFBlcnNvbmFzIGNvbiBEaXNjYXBhY2lkYWQiKSAlPiUgDQogIHRhYl9zb3VyY2Vfbm90ZShzb3VyY2Vfbm90ZSA9IGZ1ZW50ZSkNCmBgYA0KDQojIyMgQ29udHJhdGFjacOzbiBkZSBwZXJzb25hcyBjb24gZGlzY2FwYWNpZGFkDQoNCkVuIGVzdGEgZWRpY2nDs24gaW5jbHVpbW9zIGxhIHByZWd1bnRhICoqRW4gbG8gcXVlIHZhIGRlbCBhw7FvLCDCv2hhbiBjb250cmF0YWRvIGVuIHR1IGVtcHJlc2EgYSBwZXJzb25hcyBjb24gZGlzY2FwYWNpZGFkPyoqIHBhcmEgYW5hbGl6YXIgc2kgbGFzIGVtcHJlc2FzIGVzdMOhbiBhY3RpdmFtZW50ZSB0b21hbmRvIGFjY2lvbmVzIGRlIGluY2x1c2nDs24uDQoNCg0KYGBge3J9DQpraXdpICU+JSANCiAgZmlsdGVyKCFpcy5uYShjb250cmF0YV9kaXNjYXBhY2lkYWQpKSAlPiUgDQogIGdyb3VwX2J5KGNvbnRyYXRhX2Rpc2NhcGFjaWRhZCkgJT4lIA0KICBzdW1tYXJpc2UoY2FudCA9IG4oKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBjb250cmF0YV9kaXNjYXBhY2lkYWQsIHkgPSBjYW50LCBmaWxsID0gY29udHJhdGFfZGlzY2FwYWNpZGFkKSkgKw0KICBnZW9tX2NvbCgpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGNhbnQpLA0KICAgICAgICAgICAgdmp1c3QgPSAxLjIsIA0KICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiLA0KICAgICAgICAgICAgc2l6ZSA9IDMpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhncmlzLCBncmlzLCBuYXJhbmphKSkgKw0KICBlc3RpbG9oICsNCiAgbGFicyh0aXRsZSA9ICJDb250cmF0YXJvbiBwZXJzb25hcyBjb24gZGlzY2FwYWNpZGFkIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCmNvbnRyYXRhX2Rpc2MgPC0ga2l3aSAlPiUgDQogIGZpbHRlcighaXMubmEoY29udHJhdGFfZGlzY2FwYWNpZGFkKSkgJT4lIA0KICBncm91cF9ieShjb250cmF0YV9kaXNjYXBhY2lkYWQpICU+JSANCiAgc3VtbWFyaXNlKGNhbnQgPSBuKCkpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgbXV0YXRlKHBvcmNlbnRhamUgPSBjYW50L3N1bShjYW50KSkNCmBgYA0KDQpFbiBlc3RhIGVkaWNpw7NuLCBgciBwdWxsKGNvbnRyYXRhX2Rpc2NbMywyXSlgICh1biBgciBwZXJjZW50KHB1bGwoY29udHJhdGFfZGlzY1szLDNdKSlgKSBhZmlybWFyb24gcXVlIGVuIHN1cyBlbXByZXNhcyBoYW4gY29udHJhdGFkbyBwZXJzb25hcyBjb24gZGlzY2FwYWNpZGFkIGVuIHN1cyBvcmdhbml6YWNpb25lcy4gRXN0byBub3MgbGxldmEgYSBsYSBzaWd1aWVudGVzIHByZWd1bnRhczogZXN0YXMgY29tcGHDscOtYXMsIMK/c29uIG5hY2lvbmFsZXMgbyBtdWx0aW5hY2lvbmFsZXM/LCDCv1F1w6kgdGFtYcOxbyB0aWVuZW4gbGFzIGVtcHJlc2FzPw0KDQpgYGB7cn0NCmtpd2kgJT4lIA0KICBmaWx0ZXIoY29udHJhdGFfZGlzY2FwYWNpZGFkID09ICJTaSIpICU+JSANCiAgZ3JvdXBfYnkob3JpZ2VuX2NhcGl0YWwpICU+JSANCiAgdGFsbHkoKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG9yaWdlbl9jYXBpdGFsLCB5ID0gbikpICsNCiAgZ2VvbV9jb2woZmlsbCA9IG5hcmFuamEpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLA0KICAgICAgICAgICAgdmp1c3QgPSAxLjIsDQogICAgICAgICAgICBzaXplID0gMykgKw0KICBlc3RpbG9oICsNCiAgbGFicyh0aXRsZSA9ICJPcmlnZW4gZGVsIENhcGl0YWwgZGUgRW1wcmVzYXNcbnF1ZSBDb250cmF0YXJvbiBQZXJzb25hcyBjb24gRGlzY2FwYWNpZGFkIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCmBgYA0KDQpFbiBiYXNlIGEgbGFzIHJlc3B1ZXN0YXMgcmVjaWJpZGFzLCBsYXMgZW1wcmVzYXMgbmFjaW9uYWxlcyBoYW4gY29udHJhdGFkbyBtw6FzIHBlcnNvbmFzIGNvbiBkaXNjYXBhY2lkYWQgcXVlIGxhcyBtdWx0aW5hY2lvbmFsZXMuDQoNCmBgYHtyfQ0Ka2l3aSAlPiUgDQogIGZpbHRlcihjb250cmF0YV9kaXNjYXBhY2lkYWQgPT0gIlNpIikgJT4lDQogIG11dGF0ZShkb3RhY2lvbiA9IGZhY3Rvcihkb3RhY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIjEgLSA1MCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI1MSAtIDEwMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMDEgLSAyNTAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMjUxIC0gNTAwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjUwMSAtIDEuMDAwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEuMDAxIC0gMi41MDAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMi41MDEgLSA1LjAwMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI1LjAwMSAtIDEwLjAwMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMC4wMDEgbyBtw6FzIikpKSAlPiUgDQogIGdyb3VwX2J5KGRvdGFjaW9uKSAlPiUgDQogIHRhbGx5KCkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkb3RhY2lvbiwgeSA9IG4pKSArDQogIGdlb21fY29sKGZpbGwgPSBuYXJhbmphKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwNCiAgICAgICAgICAgIHZqdXN0ID0gMS4xLA0KICAgICAgICAgICAgc2l6ZSA9IDMpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShndWlkZSA9IGd1aWRlX2F4aXMobi5kb2RnZSA9IDIpKSArDQogIGxhYnModGl0bGUgPSAiRW1wcmVzYXMgcXVlIENvbnRyYXRhcm9uIFBlcnNvbmFzIGNvbiBEaXNjYXBhY2lkYWRcbnNlZ8O6biBUYW1hw7FvIGRlIGxhIEVtcHJlc2EiLA0KICAgICAgIHggPSAiRG90YWNpw7NuIGRlIGxhIEVtcHJlc2EiLCB5ID0gTlVMTCwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIGVzdGlsb2gNCg0KYGBgDQpTaSBiaWVuIGVuIHRvdGFsIHZlbW9zIHF1ZSBsYXMgZW1wcmVzYXMgY29uIG3DoXMgZGUgMS4wMDAgZW1wbGVhZG9zIHNvbiBsYXMgcXVlIGNvbnRyYXRhbiBtw6FzIHBlcnNvbmFzIGNvbiBkaXNjYXBhY2lkYWQsIG5vIHZlbW9zIHVuIHBhdHLDs24gY2xhcm8gZW4gZnVuY2nDs24gZGUgbGEgZG90YWNpw7NuIGRlIGxhIG9yZ2FuaXphY2nDs24gcG9ycXVlIHBvciBlamVtcGxvIGxhcyBlbXByZXNhcyBxdWUgdGllbmVuIGVudHJlICoxMDEgeSAyNTAqIGVtcGxlYWRvcyBoYW4gY29udHJhdGFkbyBwZXJzb25hcyBjb24gZGlzY2FwYWNpZGFkIGVuIGxhIG1pc21hIG1lZGlkYWQgcXVlIGxhcyBvcmdhbml6YWNpb25lcyBjb24gKjUuMDAxIC0gMTAuMDAwKiBlbXBsZWFkb3MuIA0KDQojIyBFZGFkDQoNCkxhIGRpc2NyaW1pbmFjacOzbiBwb3IgZWRhZCwgdGFtYmnDqW4gY29ub2NpZGEgY29tbyAqKmVkYWRpc21vKiogZXMgdW4gcHJvYmxlbWEgcXVlIGFmZWN0YSBhIGxhIGVtcGxlYWJpbGlkYWQgZGUgbGFzIHBlcnNvbmFzIGRlIG1heW9yIGVkYWQuIEVzIGhhYml0dWFsIGVuY29udHJhciBhdmlzb3MgZGUgZW1wbGVvIGRvbmRlIGVsIGzDrW1pdGUgZGUgZWRhZCBlcyBkZSA0MCBhw7Fvcy4gDQoNCkVuIGxhIHByZXNlbnRlIGVkaWNpw7NuIGRlIGxhIGVuY3Vlc3RhIGluY2x1aW1vcyBsYSBwcmVndW50YSAqKiJFbiBsbyBxdWUgdmEgZGVsIGHDsW8sIMK/aGFuIGNvbnRyYXRhZG8gZW4gdHUgZW1wcmVzYSBhIHBlcnNvbmFzIG1heW9yZXMgZGUgNTAgYcOxb3M/IioqIHBhcmEgYW5hbGl6YXIgY3XDoWwgZXMgbGEgdGVuZGVuY2lhIGVuIGNvbnRyYXRhY2nDs24gZGUgcGVyc29uYXMgc2VuaW9yLg0KDQpgYGB7cn0NCmtpd2kgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKGNvbnRyYXRhX3NlbmlvcikpICU+JSANCiAgZ3JvdXBfYnkoY29udHJhdGFfc2VuaW9yKSAlPiUgDQogIHRhbGx5KCkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBjb250cmF0YV9zZW5pb3IsIHkgPSBuLCBmaWxsID0gY29udHJhdGFfc2VuaW9yKSkgKw0KICBnZW9tX2NvbCgpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLA0KICAgICAgICAgICAgdmp1c3QgPSAxLjIsDQogICAgICAgICAgICBzaXplID0gMywgDQogICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiRW1wcmVzYXMgcXVlIGhhbiBDb250cmF0YWRvIFxuUGVyc29uYXMgZGUgTcOhcyBkZSA1MCBBw7FvcyIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhncmlzLCBncmlzLCByb3NhMSkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQpjb250cmF0YV9zciA8LSBraXdpICU+JSANCiAgZmlsdGVyKCFpcy5uYShjb250cmF0YV9zZW5pb3IpKSAlPiUgDQogIGdyb3VwX2J5KGNvbnRyYXRhX3NlbmlvcikgJT4lIA0KICBzdW1tYXJpc2UoY2FudCA9IG4oKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBtdXRhdGUocG9yY2VudGFqZSA9IGNhbnQvc3VtKGNhbnQpKQ0KYGBgDQoNCkVuIGVzdGEgZWRpY2nDs24sIGByIHB1bGwoY29udHJhdGFfc3JbMywyXSlgICh1biBgciBwZXJjZW50KHB1bGwoY29udHJhdGFfc3JbMywzXSkpYCkgYWZpcm1hcm9uIHF1ZSBlbiBzdXMgZW1wcmVzYXMgaGFuIGNvbnRyYXRhZG8gcGVyc29uYXMgZGUgbcOhcyBkZSA1MCBhw7Fvcy4NCg0KQSBjb250aW51YWNpw7NuIHJlaXRlcmFyZW1vcyBsb3MgYW7DoWxpc2lzIGVuIGZ1bmNpw7NuIGRlbCBvcmlnZW4gZGVsIGNhcGl0YWwgeSBkZWwgdGFtYcOxbyBkZSBsYXMgZW1wcmVzYXMuDQoNCg0KYGBge3J9DQpraXdpICU+JSANCiAgZmlsdGVyKGNvbnRyYXRhX3NlbmlvciA9PSAiU2kiKSAlPiUgDQogIGdyb3VwX2J5KG9yaWdlbl9jYXBpdGFsKSAlPiUgDQogIHRhbGx5KCkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBvcmlnZW5fY2FwaXRhbCwgeSA9IG4pKSArDQogIGdlb21fY29sKGZpbGwgPSByb3NhMSkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksDQogICAgICAgICAgICB2anVzdCA9IDEuMiwNCiAgICAgICAgICAgIHNpemUgPSAzLA0KICAgICAgICAgICAgY29sb3IgPSAid2hpdGUiKSArDQogIGVzdGlsb2ggKw0KICBsYWJzKHRpdGxlID0gIk9yaWdlbiBkZWwgQ2FwaXRhbCBkZSBFbXByZXNhc1xucXVlIENvbnRyYXRhcm9uIFBlcnNvbmFzIGRlIE3DoXMgZGUgNTAgQcOxb3MiLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KYGBgDQoNCkVuIGJhc2UgYSBsYXMgcmVzcHVlc3RhcyByZWNpYmlkYXMsIG51ZXZhbWVudGUgYXByZWNpYW1vcyBxdWUgbGFzIGVtcHJlc2FzIG5hY2lvbmFsZXMgaGFuIGNvbnRyYXRhZG8gbcOhcyBwZXJzb25hcyBkZSBtw6FzIGRlIDUwIGHDsW9zIHF1ZSBsYXMgbXVsdGluYWNpb25hbGVzLg0KDQpgYGB7cn0NCmtpd2kgJT4lIA0KICBmaWx0ZXIoY29udHJhdGFfc2VuaW9yID09ICJTaSIpICU+JQ0KICBtdXRhdGUoZG90YWNpb24gPSBmYWN0b3IoZG90YWNpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCIxIC0gNTAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNTEgLSAxMDAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAxIC0gMjUwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjI1MSAtIDUwMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI1MDEgLSAxLjAwMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxLjAwMSAtIDIuNTAwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjIuNTAxIC0gNS4wMDAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNS4wMDEgLSAxMC4wMDAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAuMDAxIG8gbcOhcyIpKSkgJT4lIA0KICBncm91cF9ieShkb3RhY2lvbikgJT4lIA0KICB0YWxseSgpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZG90YWNpb24sIHkgPSBuKSkgKw0KICBnZW9tX2NvbChmaWxsID0gcm9zYTEpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLA0KICAgICAgICAgICAgdmp1c3QgPSAxLjIsDQogICAgICAgICAgICBzaXplID0gMywNCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGd1aWRlID0gZ3VpZGVfYXhpcyhuLmRvZGdlID0gMikpICsNCiAgbGFicyh0aXRsZSA9ICJFbXByZXNhcyBxdWUgUGVyc29uYXMgZGUgTcOhcyBkZSA1MCBBw7Fvc1xuc2Vnw7puIFRhbWHDsW8gZGUgbGEgRW1wcmVzYSIsDQogICAgICAgeCA9ICJEb3RhY2nDs24gZGUgbGEgRW1wcmVzYSIsIHkgPSBOVUxMLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpICsNCiAgZXN0aWxvaA0KDQpgYGANCg0KQSBjb250cmFyaW8gZGUgbG9zIHF1ZSB2aW1vcyBlbiBlbCBhbsOhbGlzaXMgZGUgZGlzY2FwYWNpZGFkLCBsYXMgZW1wcmVzYXMgbcOhcyBjaGljYXMgdGllbmRlbiBhIGNvbnRyYXRhciBwZXJzb25hcyBkZSBtw6FzIGRlIDUwIGHDsW9zIHF1ZSBsYXMgZW1wcmVzYXMgbcOhcyBncmFuZGVzLg0KDQpMbyBxdWUgcG9kZW1vcyBhcHJlY2lhciBlbiB0b2RvcyBlc3RvcyBhbsOhbGlzaXMgZXMgcXVlIGxhIGRpdmVyc2lkYWQgZSBpbmNsdXNpw7NuIGRlcGVuZGUgbcOhcyBkZSBsYSB2aXNpw7NuIGRlIHVuYSBvcmdhbml6YWNpw7NuIHkgc3UgY29tcHJvbWlzbyBnZW51aW5vLCBxdWUgZWwgdGFtYcOxbyBkZSBsYSBjb21wYcOxw61hLCBvIGVsIG9yaWdlbiBkZSBzdSBjYXBpdGFsLg0KDQojIyMgTnVldm9zIEVtcGxlYWRvcw0KDQpPdHJhIGZvcm1hIGRlIGFuYWxpemFyIGxhIGVtcGxlYWJpbGlkYWQgZGUgbGFzIHBlcnNvbmFzLCBwb2Ryw61hIHNlciBjb21wYXJhbmRvIGN1w6FudGFzIHBlcnNvbmFzIHRpZW5lbiAqKm1lbm9zIGRlIDIgYcOxb3MqKiBlbiBzdSBlbXByZXNhIGFjdHVhbCBwb3IgcmFuZ28gZGUgZWRhZC4NCg0KYGBge3J9DQojIFJlc3B1ZXN0YXMgcG9yIEVkYWQNCnJlc3BfZWRhZCA8LSByaDIyICU+JSANCiAgZ3JvdXBfYnkoZWRhZCkgJT4lIA0KICB0YWxseSgpICU+JSANCiAgdW5ncm91cCgpDQoNCiMgTnVldm9zIEVtcGxlYWRvcw0KcmVzcF9uZSA8LSByaDIyICU+JSANCiAgZmlsdGVyKGFuaW9zX2VtcHJlc2EgPCAyKSAlPiUgDQogIGdyb3VwX2J5KGVkYWQpICU+JSANCiAgdGFsbHkobmFtZSA9ICJudWV2b3MiKSAlPiUgDQogIHVuZ3JvdXAoKQ0KDQpyZXNwX2VkYWQgPC0gbGVmdF9qb2luKHJlc3BfZWRhZCwgcmVzcF9uZSwgYnkgPSAiZWRhZCIpICU+JSANCiAgbXV0YXRlKG51ZXZvcyA9IGNvYWxlc2NlKG51ZXZvcywgMCkpDQoNCg0KZ2dwbG90KHJlc3BfbmUsIGFlcyh4ID0gZWRhZCwgeSA9IG51ZXZvcykpICsNCiAgZ2VvbV9jb2woZmlsbCA9IHJvc2ExKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBudWV2b3MpLCANCiAgICAgICAgICAgIHZqdXN0ID0gLTAuNSwNCiAgICAgICAgICAgIHNpemUgPSAzKSArDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsNjUpKSArDQogIGVzdGlsb2ggKw0KICBsYWJzKHRpdGxlID0gIlBlcnNvbmFzIGNvbiBtZW5vcyBkZSAyIGHDsW9zIGRlIGFudGlnw7xlZGFkXG5lbiBzdSBhY3R1YWwgZW1wcmVzYSIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQpgYGANCkVuIGVsIGdyw6FmaWNvIGFudGVyaW9yIHBvZGVtb3MgYXByZWNpYXIgcXVlIGxhcyBwZXJzb25hcyBjb24gbWVub3MgZGUgZG9zIGHDsW9zIGRlIGFudGlnw7xlZGFkIGVuIHN1cyBlbXByZXNhcyBlbXBpZXphIGEgZGVjcmVjZXIgbHVlZ28gZGUgbG9zIDMwIGHDsW9zLg0KDQoNCmBgYHtyfQ0KZ3QoDQogIHJlc3BfZWRhZCAlPiUgDQogICAgc2VsZWN0KGVkYWQsIG51ZXZvcywgbikgJT4lIA0KICAgIG11dGF0ZShwb3JjZW50YWplID0gbnVldm9zL24pIA0KKSAlPiUgDQogIGZtdF9wZXJjZW50KGNvbHVtbnMgPSBwb3JjZW50YWplLA0KICAgICAgICAgICAgICBkZWNpbWFscyA9IDEpICU+JSANCiAgdGFiX2hlYWRlcih0aXRsZSA9ICJQb3JjZW50YWplIGRlIE51ZXZvcyBFbXBsZWFkb3Mgc2Vnw7puIEVkYWQiLA0KICAgICAgICAgICAgIHN1YnRpdGxlID0gIk51ZXZvIEVtcGxlYWRvID0gQW50aWfDvGVkYWQgPCAyIGHDsW9zIikgJT4lIA0KICB0YWJfc291cmNlX25vdGUoc291cmNlX25vdGUgPSBmdWVudGUpICU+JSANCiAgY29sc19sYWJlbChlZGFkID0gIkVkYWQiLA0KICAgICAgICAgICAgIG4gPSAiVG90YWwiLA0KICAgICAgICAgICAgIG51ZXZvcyA9ICJFbXBsZWFkb3MgTnVldm9zIiwNCiAgICAgICAgICAgICBwb3JjZW50YWplID0gIlBvcmNlbnRhamUiKSANCmBgYA0KDQpEZSBsYSB0YWJsYSBhbnRlcmlvciBwb2RlbW9zIHZlciBxdWU6DQoNCiogQ2FzaSBkb3MgdGVyY2lvcyBkZSBsYXMgcGVyc29uYXMgbWVub3JlcyBkZSAzMCBhw7FvcyBlc3TDoSBlbiBzdXMgZW1wcmVzYXMgaGFjZSBtZW5vcyBkZSBkb3MgYcOxb3MuDQoqIENhc2kgbGEgbWl0YWQgZGUgbGFzIHBlcnNvbmFzIG1heW9yZXMgZGUgMzAgYcOxb3MgeSBtZW5vcmVzIGRlIDQ1IGHDsW9zIHF1ZSByZXNwb25kaWVyb24gbGEgZW5jdWVzdGEgdGllbmVuIG1lbm9zIGRlIGRvcyBhw7FvcyBkZSBleHBlcmllbmNpYSBlbiBzdSBlbXBsZW8gYWN0dWFsLg0KKiBBIHBhcnRpciBkZSBsb3MgNDYgYcOxb3MgZWwgcG9yY2VudGFqZSBkZSBlbXBsZWFkb3MgbnVldm9zIGRlY3JlY2UuDQoNCkhheSB1bmEgcGFydGUgZGUgZXN0YSBtb3ZpbGlkYWQgZW4gZnVuY2nDs24gZGUgbGEgZWRhZCBxdWUgbGEgcG9kZW1vcyBleHBsaWNhciBwb3IgZWwgYWbDoW4gZGUgYnVzY2FyIG1lam9yZXMgb3BvcnR1bmlkYWRlcyBsYWJvcmFsZXMgKG8gbGFzIHByaW1lcmFzIG9wb3J0dW5pZGFkZXMgZW4gbG9zIG3DoXMgasOzdmVuZXMpIG1pZW50cmFzIHVubyB0aWVuZSBtZW5vcmVzIHJlc3BvbnNhYmlsaWRhZGVzLCB5IGEgbWVkaWRhIHF1ZSBsYXMgcGVyc29uYXMgY3JlY2Vtb3Mgbm9zIGludGVyZXNhIG3DoXMgbGEgZXN0YWJpbGlkYWQgbyBlbCByZXRpcm8uDQoNCkFsZ28gaW50ZXJlc2FudGUgcGFyYSBhbmFsaXphciBzZXLDrWEgbGEgdGFzYSBkZSBkZXNlbXBsZW8gcG9yIHJhbmdvcyBkZSBlZGFkIGRlIHByb2Zlc2lvbmFsZXMgZGUgUlJISCB5IGN1w6FudG8gdGllbXBvIGVzdHV2aWVyb24gYnVzY2FuZG8gdHJhYmFqbyBvIHNpIGxhcyBwZXJzb25hcyBlc3R1dmllcm9uIGRlc2VtcGxlYWRhcyBhbnRlcyBkZSBzdSBhY3R1YWwgZW1wbGVvIG8gbm8sIHBlcm8gc29uIGRhdG9zIGNvbiBsb3MgcXVlIG5vIGNvbnRhbW9zIHkgcXVlIGV4Y2VkZW4gZXN0ZSB0cmFiYWpvLg0KDQpGaW5hbG1lbnRlIHZlYW1vcyBlbiBxdcOpIHB1ZXN0b3Mgc2UgZGVzYXJyb2xsYW4gbGFzIHBlcnNvbmFzIGNvbiBtZW5vcyBkZSBkb3MgYcOxb3MgZGUgYW50aWfDvGVkYWQgc2Vnw7puIHN1IHJhbmdvIGRlIGVkYWQNCg0KYGBge3IgZmlnLmhlaWdodD03fQ0KcmgyMiAlPiUgDQogIGZpbHRlcihhbmlvc19lbXByZXNhIDwgMikgJT4lIA0KICBncm91cF9ieShlZGFkLCBwdWVzdG8pICU+JSANCiAgdGFsbHkoKSAlPiUgDQogIHVuZ3JvdXAgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBmY3RfcmV2KHB1ZXN0byksIHkgPSBuKSkgKw0KICBnZW9tX2NvbChmaWxsID0gcm9zYTEpICsNCiAgZmFjZXRfd3JhcCh+ZWRhZCwgbmNvbCA9IDIsc2NhbGVzID0gImZyZWVfeSIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiUHVlc3RvcyBkZSBUcmFiYWphZG9yZXMgTnVldm9zIHBvciBFZGFkIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCmBgYA0KDQoNCg0KIyBGcmVlbGFuY2Vycw0KDQpFbiBlc3RlIHJlbGV2YW1pZW50byBwYXJ0aWNpcGFuIGNvbGVnYXMgcXVlIHRyYWJhamFuIGVuIHJlbGFjacOzbiBkZSBkZXBlbmRlbmNpYSB5IHRhbWJpw6luIGRlIG1hbmVyYSBmcmVlbGFuY2UuIEVzdGUgZXMgZWwgYW7DoWxpc2lzIGRlc2Fycm9sbGFkbyBlbiBiYXNlIGEgbGFzIHJlc3B1ZXN0YXMgZGUgbGFzIHBlcnNvbmFzIHF1ZSB0cmFiYWphbiBkZSBtYW5lcmEgaW5kZXBlbmRpZW50ZSBvIGVuIHN1cyBwcm9waWFzIGVtcHJlc2FzLg0KDQojIyBSZXNwdWVzdGFzICBwb3IgcGHDrXMNCg0KRW4gZWwgY2FzbyBkZSBsYXMgcGVyc29uYXMgZnJlZWxhbmNlLCBsYSBtYXlvcsOtYSBkZSBsYXMgcmVzcHVlc3RhcyBvYnRlbmlkYXMgZnVlcm9uIGRlIEFyZ2VudGluYS4NClBvciBlc28gcmVpdGVyYW1vcywgcXVlIGxvcyByZXN1bHRhZG9zIG5vIHNvbiByZXByZXNlbnRhdGl2b3MgZGUgbG9zIHBhw61zZXMuIA0KDQoNCmBgYHtyICBlY2hvPUZBTFNFICB9DQoNCg0KcGFpc2VzIDwtIGZyZWVsbzIyICU+JSANCiAgc2VsZWN0KHBhaXMpICU+JSANCiAgbXV0YXRlKGN1ZW50YSA9IDEpICU+JSANCiAgZ3JvdXBfYnkocGFpcykgJT4lIA0KICBzdW1tYXJpc2UoQ3VlbnRhID0gc3VtKGN1ZW50YSkpICU+JSANCiAgYXJyYW5nZSgtQ3VlbnRhKSAlPiUgDQogIGphbml0b3I6OmFkb3JuX3RvdGFscygpDQoNCmd0KHBhaXNlcykgJT4lIA0KICB0YWJfaGVhZGVyKHRpdGxlID0gIkNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgcG9yIHBhw61zIiwNCiAgICAgICAgICAgICBzdWJ0aXRsZSA9ICJGcmVlbGFuY2UiKSAlPiUgDQogIHRhYl9zb3VyY2Vfbm90ZShzb3VyY2Vfbm90ZSA9IGZ1ZW50ZSkgJT4lIA0KICBjb2xzX2xhYmVsKHBhaXMgPSAiUGHDrXMiKQ0KDQpgYGANCg0KIyMgUmVzcHVlc3RhcyBwb3IgR8OpbmVybyANCg0KTGEgcGFydGljaXBhY2nDs24gc2Vnw7puIGVsIGfDqW5lcm8gZGUgbGFzIHBlcnNvbmFzIGZyZWVsYW5jZSwgIGVzIGxhIHNpZ3VpZW50ZToNCg0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFIH0NCg0KDQojIyBMaW1waWV6YSB2YXJpYWJsZSBnZW5lcm8gLS0tLQ0KZnJlZWxvMjIgPC0gZnJlZWxvMjIgJT4lIA0KICBtdXRhdGUoZ2VuZXJvID0gZmN0X2NvbGxhcHNlKGdlbmVybywgIk11amVyIGNpcyIgPSBjKCJNdWplciBjaXMiLCAiTXVqZXIiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSG9tYnJlIGNpcyIgPSAiSG9tYnJlIGNpcyIpLA0KICAgICAgICAgZ2VuZXJvID0gZmFjdG9yKGdlbmVybywgbGV2ZWxzID0gYygiTXVqZXIgY2lzIiwgIkhvbWJyZSBjaXMiKSkpDQoNCg0KZGl2IDwtIGZyZWVsbzIyICU+JSANCiAgc2VsZWN0KGdlbmVybykgJT4lIA0KICBmaWx0ZXIoZ2VuZXJvIT0iTkEiKSU+JSAgIyBzZSBzYWNhLCBwb3JxdWUgbm8gZXMgcmVwcmVzZW50YXRpdm8NCiAgZmlsdGVyKGdlbmVybyE9IlByZWZpZXJvIG5vIHJlc3BvbmRlciIpJT4lICAjIHNlIHNhY2EsIHBvcnF1ZSBubyBlcyByZXByZXNlbnRhdGl2bw0KICBncm91cF9ieShnZW5lcm8pICU+JSANCiAgc3VtbWFyaXNlIChuID0gbigpKSAlPiUgDQogIG11dGF0ZShmcmVxID0gbi9zdW0obikpICU+JSANCiAgYXJyYW5nZSgtbikNCg0KIyBDb21wdXRlIHRoZSBjdW11bGF0aXZlIHBlcmNlbnRhZ2VzICh0b3Agb2YgZWFjaCByZWN0YW5nbGUpDQpkaXYkeW1heCA8LSBjdW1zdW0oZGl2JGZyZXEpDQoNCiMgQ29tcHV0ZSB0aGUgYm90dG9tIG9mIGVhY2ggcmVjdGFuZ2xlDQpkaXYkeW1pbiA8LSBjKDAsIGhlYWQoZGl2JHltYXgsIG49LTEpKQ0KDQojIENvbXB1dGUgbGFiZWwgcG9zaXRpb24NCmRpdiRsYWJlbFBvc2l0aW9uIDwtIChkaXYkeW1heCArIGRpdiR5bWluKSAvIDINCg0KIyBDb21wdXRlIGEgZ29vZCBsYWJlbA0KZGl2JGxhYmVsIDwtIHBhc3RlMChkaXYkZ2VuZXJvLCAiXG4gQ2FudDogIiwgZGl2JG4pDQoNCiMgTWFrZSB0aGUgcGxvdA0KZ2dwbG90KGRpdiwgYWVzKHltYXg9eW1heCwgeW1pbj15bWluLCB4bWF4PTQsIHhtaW49MywgZmlsbD1nZW5lcm8pKSArDQogIGdlb21fcmVjdCgpICsNCiAgY29vcmRfcG9sYXIodGhldGE9InkiKSArICMgVHJ5IHRvIHJlbW92ZSB0aGF0IHRvIHVuZGVyc3RhbmQgaG93IHRoZSBjaGFydCBpcyBidWlsdCBpbml0aWFsbHkNCiAgeGxpbShjKDIsIDQpKSArIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gc2VlIGhvdyB0byBtYWtlIGEgcGllIGNoYXJ0DQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM4NjI0RjUiLCAgIiMxRkMzQUEiLCAiI0ZGRDEyOSIsIiM3NTgzOEYiKSkgKw0KICB0aGVtZV92b2lkKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJSb2JvdG8iKSkgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMgc2Vnw7puIGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkZyZWVsYW5jZSIsDQogICAgICAgZmlsbCA9ICJHw6luZXJvIiwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkNCg0KYGBgDQoNClBvZGVtb3Mgb2JzZXJ2YXIgcXVlIGxhIG1heW9yw61hIGRlIGxhcyByZXNwdWVzdGFzIGZ1ZXJvbiBkZSAgTXVqZXJlcyBjaXMsIG1hbnRlbmllbmRvIGxhIG1pc21hIHRlbmRlbmNpYSBxdWUgbGFzIHBlcnNvbmFzIGVuIHJlbGFjacOzbiBkZSBkZXBlbmRlbmNpYS4gDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQoNCmZyZWVsbzIyICU+JSANCiAgc2VsZWN0KGdlbmVybykgJT4lDQogIG11dGF0ZShjdWVudGEgPSAxKSAlPiUgDQogIGdyb3VwX2J5KGdlbmVybykgJT4lDQogIHN1bW1hcmlzZShDdWVudGEgPSBzdW0oY3VlbnRhKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGFycmFuZ2UoLUN1ZW50YSklPiUNCiAgamFuaXRvcjo6YWRvcm5fdG90YWxzKCkgJT4lIA0KICByZW5hbWUoIkfDqW5lcm8iPWdlbmVybykgJT4lIA0KICBrYWJsZSgiaHRtbCIsIGVzY2FwZT1GKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IFRSVUUsIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsImhvdmVyIiwiY29uZGVuc2VkIiApKSAlPiUgDQogIHJvd19zcGVjKDAsIGJvbGQ9VCwgY29sb3I9IndoaXRlIiwgYmFja2dyb3VuZCA9IGF6dWwpDQpgYGANCg0KIyMgUmVzcHVlc3RhcyBwb3IgRWR1Y2FjacOzbiANCg0KRW4gZXN0YSBzZWNjacOzbiBxdWVyZW1vcyBpbmRhZ2FyIHNpIGhheSByZWxhY2nDs24gZW50cmUgbGEgZm9ybWFjacOzbiB5IGxhIGV4cG9ydGFjaW9uIGRlIGxvcyBzZXJ2aWNpb3MsIHkgc2kgaW1wYWN0YSB0YW1iacOpbiBlbCB0aXBvIGRlIHVuaXZlcnNpZGFkLCBww7pibGljYSBvIHByaXZhZGEsIGVuIGRpY2hhcyBwcmVzdGFjacOzbmVzLiANClByaW1lcm8gdmVhbW9zICBjb21vIHNlIGRpc3RyaWJ1eWUgbGEgbXVlc3RyYSBlbnRyZSBwcm9mZXNpb25hbGVzIHByb3ZlbmllbnRlcyBkZSB1bml2ZXJzaWRhZGVzIHDDumJsaWNhcyB5IHByaXZhZGFzIGRlIGxvcyBkaWZlcmVudGVzIHBhaXNlczoNCg0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQojIE5vdGE6IFZlciBjb21vIGFncmVnYXIgbGEgdGFibGEgZGUgcmVmZXJlbmNpYXMgYWwgZ3JhZmljby0NCg0KZnJlZWxvMjIgJT4lIA0KICBzZWxlY3QocGFpcywgdGlwb191bml2ZXJzaWRhZCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHkgPSBwYWlzLCBmaWxsID0gdGlwb191bml2ZXJzaWRhZCkpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsgDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoZ3JpcywgdmVyZGUsIGF6dWwpKSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVjacOzbiBkZSByZXNwdWVzdGFzIHBvciB0aXBvIGRlIHVuaXZlcnNpZGFkIHBvciBwYcOtcyIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSwgDQogICAgICAgeCA9ICIiLCB5ID0gIiIpICsNCiAgZXN0aWxvICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsNCiAgZWplX3hfcA0KDQpgYGANCg0KDQpMaW1pdGFuZG9ub3MgYWwgcGHDrXMgY29uIG1heW9yIGNhbnRpZGFkIGRlIHJlc3B1ZXN0YXMsIEFyZ2VudGluYSwgZW4gbG9zICBzaWd1aWVudGVzIGdyYWZpY29zIHBvZGVtb3Mgb2JzZXJ2YXIgIHF1ZSAgbGEgZGlzdHJpYnVjacOzbiAgIHBvciB0aXBvIGRlIFVuaXZlcnNpZGFkIGVzICBtdXkgcGFyZWphICwgcXVlZGFuZG8gdW4gdmFsb3IgIG1pbmltbyB5IHBvY28gcmVwcmVzZW50YXRpdm8gIHBhcmEgcXVpZW5lbiBubyBmdWVyb24gYSBsYSBVbml2ZXJzaWRhZDogDQoNCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KZnJlZWxvMjIgJT4lIA0KICBzZWxlY3QocGFpcywgdGlwb191bml2ZXJzaWRhZCkgJT4lDQogIGZpbHRlciAocGFpcz09IkFyZ2VudGluYSIpJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB0aXBvX3VuaXZlcnNpZGFkKSkgKyANCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiLCBmaWxsID0gYXp1bCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDM2MCkpICsgDQogIGxhYnMoeD0iIix5PSIiKSArDQogIGVzdGlsb2ggKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gZGUgcmVzcHVlc3RhcyBwb3IgdGlwbyBkZSB1bml2ZXJzaWRhZCIsDQogICAgICAgc3VidGl0bGUgPSAiU29sbyBBcmdlbnRpbmEiLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQoNCg0KYGBgDQoNCmBgYHtyICBlY2hvPUZBTFNFICwgbWVzc2FnZT0gRkFMU0UsICB3YXJuaW5nID0gRkFMU0V9DQoNCg0KDQojIyBUaXBvIGRlIFVuaXZlcnNpZGFkICANCg0KZWR1YyA8LSBmcmVlbG8yMiAlPiUgDQogIHNlbGVjdCh0aXBvX3VuaXZlcnNpZGFkKSAlPiUgIA0KICBncm91cF9ieSh0aXBvX3VuaXZlcnNpZGFkKSAlPiUgDQogIHN1bW1hcmlzZSAobiA9IG4oKSkgJT4lIA0KICBtdXRhdGUoZnJlcSA9IG4vc3VtKG4pKSAlPiUgDQogIGFycmFuZ2UoLW4pDQoNCiMgQ29tcHV0ZSB0aGUgY3VtdWxhdGl2ZSBwZXJjZW50YWdlcyAodG9wIG9mIGVhY2ggcmVjdGFuZ2xlKQ0KZWR1YyR5bWF4IDwtIGN1bXN1bShlZHVjJGZyZXEpDQoNCiMgQ29tcHV0ZSB0aGUgYm90dG9tIG9mIGVhY2ggcmVjdGFuZ2xlDQplZHVjJHltaW4gPC0gYygwLCBoZWFkKGVkdWMkeW1heCwgbj0tMSkpDQoNCiMgQ29tcHV0ZSBsYWJlbCBwb3NpdGlvbg0KZWR1YyRsYWJlbFBvc2l0aW9uIDwtIChlZHVjJHltYXggKyBlZHVjJHltaW4pIC8gMg0KDQojIENvbXB1dGUgYSBnb29kIGxhYmVsDQplZHVjJGxhYmVsIDwtIHBhc3RlMChlZHVjJHRpcG9fdW5pdmVyc2lkYWQsICJcbiBDYW50OiAiLCBlZHVjJG4pDQoNCiMgTWFrZSB0aGUgcGxvdA0KZ2dwbG90KGVkdWMsIGFlcyh5bWF4PXltYXgsIHltaW49eW1pbiwgeG1heD00LCB4bWluPTMsIGZpbGw9dGlwb191bml2ZXJzaWRhZCkpICsNCiAgZ2VvbV9yZWN0KCkgKw0KICBjb29yZF9wb2xhcih0aGV0YT0ieSIpICsgIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gdW5kZXJzdGFuZCBob3cgdGhlIGNoYXJ0IGlzIGJ1aWx0IGluaXRpYWxseQ0KICB4bGltKGMoMiwgNCkpICsjIFRyeSB0byByZW1vdmUgdGhhdCB0byBzZWUgaG93IHRvIG1ha2UgYSBwaWUgY2hhcnQNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhncmlzLCB2ZXJkZSwgYXp1bCkpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiUm9ib3RvIikpICsNCiAgbGFicyh0aXRsZSA9ICJUaXBvIGRlIFVuaXZlcnNpZGFkIiwNCiAgICAgICBmaWxsID0gIlRpcG8gZGUgVW5pdmVyc2lkYWQiLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJsZWZ0IikNCmBgYA0KDQoNCg0KTm9zIGludGVyZXNhYmEgaW5kYWdhciBjdcOhbCBlcmEgZWwgbml2ZWwgZGUgZm9ybWFjacOzbiAgZGUgbG9zIGVuY3Vlc3RhZG9zLg0KDQpFbiBsYSBzaWd1aWVudGUgdGFibGEgcG9kZW1vcyB2ZXIgcXVlIGxhIG1heW9yw61hIHRpZW5lIGVzdHVkaW9zICBVbml2ZXJzaXRhcmlvcyBjb21wbGV0b3M6IA0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQpmcmVlbG8yMiAlPiUgDQogIHNlbGVjdChuaXZlbF9mb3JtYWNpb24pICU+JQ0KICBtdXRhdGUoY3VlbnRhID0gMSkgJT4lIA0KICBncm91cF9ieShuaXZlbF9mb3JtYWNpb24pICU+JQ0KICBzdW1tYXJpc2UoQ3VlbnRhID0gc3VtKGN1ZW50YSkpICU+JSANCiAgYXJyYW5nZSgtQ3VlbnRhKSU+JSANCiAgc2VsZWN0KG5pdmVsX2Zvcm1hY2lvbixDdWVudGEpICU+JSANCiAgcmVuYW1lKCJOaXZlbCBkZSBGb3JtYWNpw7NuIj1uaXZlbF9mb3JtYWNpb24pICU+JSANCiAga2FibGUoImh0bWwiLCBlc2NhcGU9RikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFLCBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJob3ZlciIsImNvbmRlbnNlZCIgKSkgJT4lIA0KICByb3dfc3BlYygwLCBib2xkPVQsIGNvbG9yPSJ3aGl0ZSIsIGJhY2tncm91bmQgPSBhenVsKQ0KYGBgDQoNCkN1YW5kbyAgYW5hbGl6YW1vcyBlZHVjYWNpw7NuLCBub3MgcmVzdWx0w7MgIGludGVyZXNhbnRlIGFuYWxpemFyIGxhIGRpc3RyaWJ1Y2nDs24gcG9yIGfDqW5lcm8geSBuaXZlbCBlZHVjYXRpdm8uDQoNCkVuIGVsIHNpZ3VpZW50ZSBncsOhZmljbyBwb2RlbW9zIG9ic2VydmFyIHF1ZSBsYXMgbXVqZXJlcyB0aWVuZW4gbWF5b3Igbml2ZWwgZGUgZm9ybWFjacOzbiBxdWUgbG9zIGhvbWJyZXM6DQoNCmBgYHtyICBlY2hvPUZBTFNFICwgbWVzc2FnZT0gRkFMU0UsICB3YXJuaW5nID0gRkFMU0V9DQpmcmVlbG8yMiAlPiUgDQogIHNlbGVjdChwYWlzLCBuaXZlbF9mb3JtYWNpb24sIGdlbmVybykgJT4lDQogIGZpbHRlcihnZW5lcm8gIT0gIlByZWZpZXJvIG5vIHJlc3BvbmRlciIpICU+JSAjIHNhY2FyIHBvcnF1ZSBubyBlcyByZXByZXNlbnRhdGl2bw0KICBmaWx0ZXIobml2ZWxfZm9ybWFjaW9uICE9ICJOQSIpICU+JSAgICAgICAgICAgIyBzYWNhciBwb3JxdWUgbm8gZXMgcmVwcmVzZW50YXRpdm8NCiAgbXV0YXRlKG5pdmVsX2Zvcm1hY2lvbiA9IGZhY3RvcihuaXZlbF9mb3JtYWNpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiVGVyY2lhcmlvIGVuIGN1cnNvIiwgIlRlcmNpYXJpbyBjb21wbGV0byIsICJVbml2ZXJzaXRhcmlvIGFiYW5kb25hZG8iLCAiVW5pdmVyc2l0YXJpbyBlbiBjdXJzbyIsICJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwgIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBlbiBjdXJzbyIsIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBjb21wbGV0byIsICJNYWVzdHLDrWEgbyBzdXBlcmlvciBlbiBjdXJzbyIsICJNYWVzdHLDrWEgbyBzdXBlcmlvciBjb21wbGV0YSIpKSkgJT4lIA0KICBncm91cF9ieShuaXZlbF9mb3JtYWNpb24pICU+JSANCiAgZ2dwbG90KGFlcyAoeT0gbml2ZWxfZm9ybWFjaW9uLCBmaWxsID0gZ2VuZXJvKSkgKyANCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyh4PSIiLHk9IiIpICsNCiAgZWplX3hfcCArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG9yZXMpICsNCiAgZXN0aWxvICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsNCiAgbGFicyh0aXRsZSA9ICJNw6F4aW1vIG5pdmVsIGVkdWNhdGl2byBhbGNhbnphZG8gcG9yIGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gcG9yIGZyZWN1ZW5jaWFzIGFic29sdXRhcyIsDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSwgDQogICAgICAgZmlsbCA9ICJHw6luZXJvIikNCg0KYGBgDQoNCg0KVmVhbW9zIGxvcyBtaXNtb3MgcmVzdWx0YWRvcywgZW4gdGVybWlub3MgcmVsYXRpdm9zOiANCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KI0VzdGEgYmllbiBsYSBwcm9wb3JjaW9uPz8gdmVyISEgDQoNCmZyX2ZlbSA8LSBmcmVlbG8yMiAlPiUgDQogIGZpbHRlcihnZW5lcm8gPT0gIk11amVyIGNpcyIpICU+JSANCiAgZ3JvdXBfYnkoZ2VuZXJvLCBuaXZlbF9mb3JtYWNpb24pICU+JSANCiAgbXV0YXRlKG5pdmVsX2Zvcm1hY2lvbiA9IGZhY3RvcihuaXZlbF9mb3JtYWNpb24sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiVGVyY2lhcmlvIGVuIGN1cnNvIiwgIlRlcmNpYXJpbyBjb21wbGV0byIsICJVbml2ZXJzaXRhcmlvIGFiYW5kb25hZG8iLCAiVW5pdmVyc2l0YXJpbyBlbiBjdXJzbyIsICJVbml2ZXJzaXRhcmlvIGNvbXBsZXRvIiwgIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBlbiBjdXJzbyIsIkRpcGxvbWFkbyBkZSBwb3NncmFkbyBjb21wbGV0byIsICJNYWVzdHLDrWEgbyBzdXBlcmlvciBlbiBjdXJzbyIsICJNYWVzdHLDrWEgbyBzdXBlcmlvciBjb21wbGV0YSIpKSkgJT4lIA0KICBncm91cF9ieShuaXZlbF9mb3JtYWNpb24pICU+JSANCiAgc3VtbWFyaXNlKG4gPSBuKCkpICU+JSANCiAgbXV0YXRlKGZyZWN1ZW5jaWEgPSByb3VuZChuL3N1bShuKSwyKSwNCiAgICAgICAgIGdlbmVybyA9ICJNdWplciBjaXMiKSANCg0KDQpmcl9tYXMgPC0gZnJlZWxvMjIgJT4lIA0KICBmaWx0ZXIoZ2VuZXJvID09ICJIb21icmUgY2lzIikgJT4lIA0KICBncm91cF9ieShnZW5lcm8sIG5pdmVsX2Zvcm1hY2lvbikgJT4lIA0KICBtdXRhdGUobml2ZWxfZm9ybWFjaW9uID0gZmFjdG9yKG5pdmVsX2Zvcm1hY2lvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJUZXJjaWFyaW8gZW4gY3Vyc28iLCAiVGVyY2lhcmlvIGNvbXBsZXRvIiwgIlVuaXZlcnNpdGFyaW8gYWJhbmRvbmFkbyIsICJVbml2ZXJzaXRhcmlvIGVuIGN1cnNvIiwgIlVuaXZlcnNpdGFyaW8gY29tcGxldG8iLCAiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGVuIGN1cnNvIiwiRGlwbG9tYWRvIGRlIHBvc2dyYWRvIGNvbXBsZXRvIiwgIk1hZXN0csOtYSBvIHN1cGVyaW9yIGVuIGN1cnNvIiwgIk1hZXN0csOtYSBvIHN1cGVyaW9yIGNvbXBsZXRhIikpKSAlPiUgDQogIGdyb3VwX2J5KG5pdmVsX2Zvcm1hY2lvbikgJT4lIA0KICBzdW1tYXJpc2UobiA9IG4oKSkgJT4lIA0KICBtdXRhdGUoZnJlY3VlbmNpYSA9IHJvdW5kKG4vc3VtKG4pLDIpLA0KICAgICAgICAgZ2VuZXJvID0gIkhvbWJyZSBjaXMiKSANCg0KZnJfdG90YWwgPC0gcmJpbmQoZnJfZmVtLCBmcl9tYXMgKQ0KDQpnZ3Bsb3QoZnJfdG90YWwsIGFlcyh4ID0gbml2ZWxfZm9ybWFjaW9uLCB5ID0gZnJlY3VlbmNpYSwgZmlsbCA9IGdlbmVybykpICsNCiAgZ2VvbV9jb2woKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApLCANCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArIA0KICBsYWJzKHg9IiIseT0iIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcmVzKSArDQogIGZhY2V0X3dyYXAofmdlbmVybywgbmNvbCA9IDIpICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiUHJvcG9yY2nDs24gZGUgbml2ZWwgZWR1Y2F0aXZvIG3DoXhpbW8gcG9yIGfDqW5lcm8iLA0KICAgICAgIHN1YnRpdGxlID0gIkZyZWVsYW5jZSIsDQogICAgICAgeCA9ICIiLCB5ID0gIlByb3BvcmNpw7NuIiwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICBlamVfeV9wDQoNCg0KYGBgDQoNCg0KUmVzcGVjdG8gYSBsYXMgIGNhcnJlcmFzLCB2ZW1vcyBxdWUgbGEgdGVuZGVuY2lhIGRlIGxhcyBtaXNtYXMgc2UgY29ycmVzcG9uZGVuIGNvbiBsb3MgcmVzdWx0YWRvcyBvYnRlbmlkb3MgZW4gbGFzIHBlcnNvbmFzIGVuIHJlbGFjacOzbiBkZSBkZXBlbmRlbmNpYTogDQoNCmBgYHtyICBlY2hvPUZBTFNFICwgbWVzc2FnZT0gRkFMU0UsICB3YXJuaW5nID0gRkFMU0V9DQoNCmNhcnJlcmFzZnIgPC0gZnJlZWxvMjIgJT4lIA0KICBzZWxlY3Qobml2ZWxfZm9ybWFjaW9uLCBjYXJyZXJhX2dyYWRvLCB0aXBvX3VuaXZlcnNpZGFkLCBwYWlzLCBnZW5lcm8pICU+JSANCiAgbXV0YXRlKGNhcnJlcmFfZ3JhZG8gPSBmYWN0b3IoY2FycmVyYV9ncmFkbykpDQoNCmNhcnJlcmFzZnIgPC0gY2FycmVyYXNmciAlPiUgDQogIG11dGF0ZShjYXJyZXJhX2dyYWRvID0gZmN0X2NvbGxhcHNlKGNhcnJlcmFfZ3JhZG8sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJSSEggLyBSUkxMIC8gUlJUVCIgPSBjKCJSUkhIIC8gUlJMTCAvIFJSVFQiLCAiWSBhaG9yYSBSZWxhY2lvbmVzIExhYm9yYWxlcyIpKSwNCiAgICAgICAgIGNhcnJlcmFfZ3JhZG8gPSBmY3RfY29sbGFwc2UoY2FycmVyYV9ncmFkbywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQc2ljb2xvZ8OtYSIgPSBjKCJQc2ljb2xvZ8OtYSIpKSwNCiAgICAgICAgIGNhcnJlcmFfZ3JhZG8gPSBmY3RfY29sbGFwc2UoY2FycmVyYV9ncmFkbywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBZG1pbmlzdHJhY2nDs24gZGUgRW1wcmVzYXMiID0gYygiQWRtaW5pc3RyYWNpw7NuIGRlIEVtcHJlc2FzIikpLA0KICANCiAgICAgICAgIGNhcnJlcmFfZ3JhZG8gPSBmY3RfbHVtcChjYXJyZXJhX2dyYWRvLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wID0gMC4wMiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJfbGV2ZWwgPSAiT3Ryb3MiKSwNCiAgICAgICAgICAgY2FycmVyYV9ncmFkbyA9IGZhY3RvcihjYXJyZXJhX2dyYWRvLCBsZXZlbHMgPSBjKCJSUkhIIC8gUlJMTCAvIFJSVFQiLCAiUHNpY29sb2fDrWEiLCAiQWRtaW5pc3RyYWNpw7NuIGRlIEVtcHJlc2FzIiwgIk90cm9zIikpKQ0KDQoNCmdncGxvdChjYXJyZXJhc2ZyLCBhZXMoeCA9IGNhcnJlcmFfZ3JhZG8pKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIiwgZmlsbCA9IGF6dWwpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzNjApKSArIA0KICBsYWJzKHg9IiIseT0iIikgKw0KICBlc3RpbG9oICsNCiAgbGFicyh0aXRsZSA9ICJQcmluY2lwYWxlcyBjYXJyZXJhcyBlc3R1ZGlhZGFzIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJGcmVlbGFuY2UiLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQpgYGANCg0KIyMgUmVzcHVlc3RhcyBwb3IgQ29uZGljacOzbiBmaXNjYWwNCg0KTGEgY29uZGlkaWNpw7NuIGZpc2NhbCBkZSAgbG9zIGVuY3Vlc3RhZG9zIGxhIHBvZGVtb3Mgb2JzZXJ2YXIgZW4gbGEgc2lndWllbnRlIHRhYmxhOg0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQoNCmZpc2NvZnIgPC0gZnJlZWxvMjIgJT4lIA0KICBzZWxlY3QocmVnaXN0cm9fZmlzY2FsLCBtZWRpb19wYWdvX2V4dGVyaW9yKSAlPiUgDQogIG11dGF0ZShyZWdpc3Ryb19maXNjYWwgPSBmYWN0b3IocmVnaXN0cm9fZmlzY2FsKSklPiUNCiAgbXV0YXRlKHJlZ2lzdHJvX2Zpc2NhbCA9IGZjdF9jb2xsYXBzZShyZWdpc3Ryb19maXNjYWwsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTW9ub3RyaWJ1dGlzdGEiID0gIk1vbm90cmlidXRpc3RhIiksDQogICAgICAgICByZWdpc3Ryb19maXNjYWwgPSBmY3RfY29sbGFwc2UocmVnaXN0cm9fZmlzY2FsLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ29udHJhY3RvciIgPSAiQ29udHJhY3RvciIpLA0KICAgICAgICAgcmVnaXN0cm9fZmlzY2FsID0gZmN0X2NvbGxhcHNlKHJlZ2lzdHJvX2Zpc2NhbCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlc3BvbnNhYmxlIGluc2NyaXB0byIgPSAiUmVzcG9uc2FibGUgaW5zY3JpcHRvIiksDQogICAgICAgICAgcmVnaXN0cm9fZmlzY2FsID0gZmN0X2NvbGxhcHNlKHJlZ2lzdHJvX2Zpc2NhbCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNBIiA9ICJTQSIpLA0KICAgICAgICAgcmVnaXN0cm9fZmlzY2FsID0gZmN0X2NvbGxhcHNlKHJlZ2lzdHJvX2Zpc2NhbCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk90cm9zIiA9IGMoIk5vIGVzdG95IHJlZ2lzdHJhZGEgcG9yIGVsIG1vbWVudG8iLCJTcGEiLCJ0ZW5nbyB1biBjb250cmF0byBtaXh0byByZWwgZGVwZW5kZW5jaWEgeSAgZnJlZWxhbmNlIikpLA0KICAgICAgICAgY2FycmVyYV9ncmFkbyA9IGZhY3RvcihyZWdpc3Ryb19maXNjYWwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk1vbm90cmlidXRpc3RhIiwgIkNvbnRyYWN0b3IiLCAiUmVzcG9uc2FibGUgaW5zY3JpcHRvIiwiU0EiLCAiT3Ryb3MiKSkpDQoNCg0KZmlzY29mciAlPiUgDQogIHNlbGVjdChyZWdpc3Ryb19maXNjYWwpICU+JQ0KICBtdXRhdGUoY3VlbnRhID0gMSkgJT4lIA0KICBncm91cF9ieShyZWdpc3Ryb19maXNjYWwpICU+JQ0KICBzdW1tYXJpc2UoQ3VlbnRhID0gc3VtKGN1ZW50YSkpICU+JSANCiAgYXJyYW5nZSgtQ3VlbnRhKSU+JSANCiAgcmVuYW1lKCJSZWdpc3RybyBGaXNjYWwiPXJlZ2lzdHJvX2Zpc2NhbCkgJT4lIA0KICBrYWJsZSgiaHRtbCIsIGVzY2FwZT1GKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IFRSVUUsIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsImhvdmVyIiwiY29uZGVuc2VkIiApKSAlPiUgDQogIHJvd19zcGVjKDAsIGJvbGQ9VCwgY29sb3I9IndoaXRlIiwgYmFja2dyb3VuZCA9IGF6dWwpDQoNCmBgYA0KDQojIyAgUmVzcHVlc3RhcyBwb3IgRXhwb3J0YWNpw7NuIGRlICBTZXJ2aWNpbw0KDQpDb21vIHZlbW9zIGEgY29udGludWFjacOzbiwgIGxhIG1heW9yw61hIG5vIGV4cG9ydGEgc3VzIHNlcnZpY2lvczogDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQpleHAgPC0gZnJlZWxvMjIgJT4lIA0KICBzZWxlY3QoZXhwb3J0YSkgJT4lIA0KIGZpbHRlcihleHBvcnRhIT0iTkEiKSAlPiUgDQogIGdyb3VwX2J5KGV4cG9ydGEpICU+JSANCiAgc3VtbWFyaXNlIChuID0gbigpKSAlPiUgDQogIG11dGF0ZShmcmVxID0gbi9zdW0obikpICU+JSANCiAgYXJyYW5nZSgtbikNCg0KIyBDb21wdXRlIHRoZSBjdW11bGF0aXZlIHBlcmNlbnRhZ2VzICh0b3Agb2YgZWFjaCByZWN0YW5nbGUpDQpleHAkeW1heCA8LSBjdW1zdW0oZXhwJGZyZXEpDQoNCiMgQ29tcHV0ZSB0aGUgYm90dG9tIG9mIGVhY2ggcmVjdGFuZ2xlDQpleHAkeW1pbiA8LSBjKDAsIGhlYWQoZXhwJHltYXgsIG49LTEpKQ0KDQojIENvbXB1dGUgbGFiZWwgcG9zaXRpb24NCmV4cCRsYWJlbFBvc2l0aW9uIDwtIChleHAkeW1heCArIGRpdiR5bWluKSAvIDINCg0KIyBDb21wdXRlIGEgZ29vZCBsYWJlbA0KZXhwJGxhYmVsIDwtIHBhc3RlMChleHAkZXhwb3J0YSwgIlxuIENhbnQ6ICIsIGRpdiRuKQ0KDQojIE1ha2UgdGhlIHBsb3QNCmdncGxvdChleHAsIGFlcyh5bWF4PXltYXgsIHltaW49eW1pbiwgeG1heD00LCB4bWluPTMsIGZpbGw9ZXhwb3J0YSkpICsNCiAgZ2VvbV9yZWN0KCkgKw0KICBjb29yZF9wb2xhcih0aGV0YT0ieSIpICsgIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gdW5kZXJzdGFuZCBob3cgdGhlIGNoYXJ0IGlzIGJ1aWx0IGluaXRpYWxseQ0KICB4bGltKGMoMiwgNCkpICsjIFRyeSB0byByZW1vdmUgdGhhdCB0byBzZWUgaG93IHRvIG1ha2UgYSBwaWUgY2hhcnQNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhncmlzLCBhenVsKSkgKw0KICB0aGVtZV92b2lkKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJSb2JvdG8iKSkgKw0KICBsYWJzKHRpdGxlID0gIkV4cG9ydGEgU2VydmljaW9zIiwNCiAgICAgICBmaWxsID0gIiIsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQpgYGANCg0KDQpGb2NhbGl6YW5kb25vcyBlbnRyZSBxdWllbmVzIGV4cG9ydGFuLCBwb2RlbW9zIHZlciBjdcOhbCBlcyBlbCBzZXJ2aWNpbyBwcmVzdGFkbzogDQoNCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KDQpzdl9mciA8LSBmcmVlbG8yMiAlPiUgDQogIGZpbHRlcihzZXJ2aWNpb19wcmluY2lwYWwgIT0gIk5BIiklPiUgDQogIGZpbHRlcihzZXJ2aWNpb19wcmluY2lwYWwgIT0gIlN0YXJ0IHVwIGRlbCBhcmVhIGRlIEhSIGlucG1lbnRhY2lvbiBkZSBwb2xpdGljYXMgeSBwcm9jZXNvcywgYnVzcXVlZGEgeSBzZWxlY2Npb24sIGFzZXNvcmFtaWVudG8gZW4gZ2VuZXJhbCBkZWwgYXJlYSIpJT4lIA0KICBzZWxlY3Qoc2VydmljaW9fcHJpbmNpcGFsLCBleHBvcnRhKSMgJT4lDQojICBmaWx0ZXIoZXhwb3J0YT09IlNpIikjJT4lDQojIG11dGF0ZShzZXJ2aWNpb19wcmluY2lwYWwgPSBmYWN0b3Ioc2VydmljaW9fcHJpbmNpcGFsLA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJQYXlyb2xsIC8gTGlxdWlkYWNpw7NuIGRlIHN1ZWxkb3MiLCAiRGlzZcOxbyBvcmdhbml6YWNpb25hbCIsICJDYXBhY2l0YWNpw7NuIiwgIkNvbXVuaWNhY2nDs24gaW50ZXJuYSIsIlBlb3BsZSBBbmFseXRpY3MiLCJIUiBHZW5lcmFsaXN0YSIpKSkNCg0KZ2dwbG90KHN2X2ZyLCAoYWVzKHkgPSBmY3RfcmV2KHNlcnZpY2lvX3ByaW5jaXBhbCksIGZpbGwgPSBleHBvcnRhKSkpICsgDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKHg9IiIseT0iIikgKw0KICBlc3RpbG92ICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhncmlzLCB2ZXJkZSkpICsNCiAgbGFicyh0aXRsZSA9ICJSZXNwdWVzdGFzIHNlZ8O6biBTZXJ2aWNpbyBFeHBvcnRhZG8iLA0KICAgICAgIHN1YnRpdGxlID0gIkZyZWVsYW5jZSIsDQogICAgICAgeCA9ICIiLCBmaWxsID0gIkV4cG9ydGEiLA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQpgYGANCg0KDQpFbiByZWxhY2nDs24gYSBsb3MgbWVkaW9zIGRlIHBhZ28gdXRpbGl6YWRvcyBwb3IgcXVpZW5lcyBleHBvcnRhbiwgc3VzIHJlc3B1ZXN0YXMgZnVlcm9uIGxhcyBzaWd1aWVudGVzOiANCg0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQoNCm1wX2ZyIDwtZnJlZWxvMjIlPiUNCiAgbXV0YXRlKG1lZGlvX3BhZ29fZXh0ZXJpb3IgPSBmY3RfY29sbGFwc2UobWVkaW9fcGFnb19leHRlcmlvciwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBheW9uZWVyIiA9IGMoIlBheW9uZWVyIikpLA0KICAgICAgICAgbWVkaW9fcGFnb19leHRlcmlvciA9IGZjdF9jb2xsYXBzZShtZWRpb19wYWdvX2V4dGVyaW9yLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVHJhbnNmZXJlbmNpYSIgPSBjKCJUcmFuc2ZlcmVuY2lhIGEgdHUgY3VlbnRhIikpLA0KICAgICAgICAgbWVkaW9fcGFnb19leHRlcmlvciA9IGZjdF9jb2xsYXBzZShtZWRpb19wYWdvX2V4dGVyaW9yLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGF5UGFsIiA9IGMoIlBheVBhbCIpKSwNCiAgICAgICAgIG1lZGlvX3BhZ29fZXh0ZXJpb3IgPSBmY3RfY29sbGFwc2UobWVkaW9fcGFnb19leHRlcmlvciwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCaXRjb2luIiA9IGMoIkJpdGNvaW4iKSksDQogICAgICAgICBtZWRpb19wYWdvX2V4dGVyaW9yID0gZmN0X2NvbGxhcHNlKG1lZGlvX3BhZ29fZXh0ZXJpb3IsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiV2VzdGVybiBVbmlvbiIgPSBjKCJXZXN0ZXJuIFVuaW9uIikpLA0KICAgICAgICAgbWVkaW9fcGFnb19leHRlcmlvciA9IGZjdF9jb2xsYXBzZShtZWRpb19wYWdvX2V4dGVyaW9yLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlByZXgiID0gYygiUHJleCIpKSwNCiAgICAgICAgIG1lZGlvX3BhZ29fZXh0ZXJpb3IgPSBmY3RfY29sbGFwc2UobWVkaW9fcGFnb19leHRlcmlvciwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOTyIgPSBjKCItIiwiMCIsIk4vQSIsIm5vIiwiTm8iLCJObyBhcGxpY2EiLCJObyBleHBvcnRpIHBvciBhaG9yYSIsIm5vIGV4cG9ydG8iLCJObyBleHBvcnRvIiAsIk5vIGV4cG9ydG8gc2VydmljaW9zIiwiTm8gZXhwb3J0by4iLCJObyB0cmFiYWpvIHBhcmEgYWZ1ZXJhIGHDum4iLCJYeHh4IikpLA0KICAgICAgICAgY2FycmVyYV9ncmFkbyA9IGZhY3RvcihtZWRpb19wYWdvX2V4dGVyaW9yLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJQYXlvbmVlciIsICJUcmFuc2ZlcmVuY2lhIiwgIlBheVBhbCIsICJCaXRjb2luIiwiV2VzdGVybiBVbmlvbiIsIlByZXgiLCJOTyIpKSkNCg0KDQoNCm1wX2ZyICU+JSANCiAgZmlsdGVyKG1lZGlvX3BhZ29fZXh0ZXJpb3IhPSJOTyIpJT4lIA0KICBtdXRhdGUoY3VlbnRhID0gMSkgJT4lIA0KICBncm91cF9ieShtZWRpb19wYWdvX2V4dGVyaW9yKSAlPiUNCiAgc3VtbWFyaXNlKEN1ZW50YSA9IHN1bShjdWVudGEpKSAlPiUgDQogIGFycmFuZ2UoLUN1ZW50YSklPiUgDQogIHNlbGVjdChtZWRpb19wYWdvX2V4dGVyaW9yLEN1ZW50YSkgJT4lIA0KICByZW5hbWUoIk1lZGlvcyBkZSBQYWdvIEV4dGVyaW9yIj1tZWRpb19wYWdvX2V4dGVyaW9yKSAlPiUgDQogIGthYmxlKCJodG1sIiwgZXNjYXBlPUYpICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiICkpICU+JSANCiAgcm93X3NwZWMoMCwgYm9sZD1ULCBjb2xvcj0id2hpdGUiLCBiYWNrZ3JvdW5kID0gYXp1bCkNCg0KYGBgDQoNCiMjIFJlc3B1ZXN0YXMgcG9yICBBbnRpZ8O8ZWRhZA0KDQpSZXNwZWN0byBhIGxvcyBhw7FvcyBkZSBleHBlcmllbmNpYSBjb21vIGZyZWVsYW5jZSwgcG9kZW1vcyBvYnNlcnZhciBxdWUgbGEgbWF5b3LDrWEgdGllbmUgbWVub3MgZGUgZG9zIGHDsW9zLg0KDQpVbiBpbnRlcnJvZ2FudGUgcXVlIG5vcyBzdXJnZSBlbiBzaSBsYSBpbnNlcmNpw7NuIGVuIGVzdGEgbW9kYWxpZGFkIGZ1ZSB1bmEgZGVjaXNpw7NuIGRlIGNhcnJlcmEgdm9sdW50YXJpYSBvIGltcHVsc2FkYSBwb3IgbGFzIGNvbnNlY3VlbmNpYXMgZGUgbGEgcGFuZGVtaWEuIENhcmVjZW1vcyBkZSBlbGVtZW50b3MgcGFyYSByZXNwb25kZXIgZXNhIHByZWd1bnRhLCBwb3IgZXNvIG5vcyBsaW1pdGFtb3MgYSAgcHJlc2VudGFyIGxhcyByZXNwdWVzdGFzIG9idGVuaWRhczogDQoNCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KYW50X2ZyPC0gZnJlZWxvMjIgJT4lIA0KICBtdXRhdGUocmFuZ29fYW50ID1jYXNlX3doZW4oDQogICAgYW5pb3NfZnJlZWxhbmNlIDwgMiB+ICJNZW5vcyBkZSAyIGHDsW9zIiwNCiAgICBhbmlvc19mcmVlbGFuY2UgPCA2IH4gIkVudHJlIDIgeSA1IGHDsW9zIiwNCiAgICBhbmlvc19mcmVlbGFuY2UgPCAxMSB+ICJFbnRyZSA1IHkgMTAgYcOxb3MiLA0KICAgIGFuaW9zX2ZyZWVsYW5jZSA9IFQgfiAiTcOhcyBkZSAxMCBhw7FvcyIpLA0KICAgIHJhbmdvX2FudCA9IGZjdF9yZWxldmVsKHJhbmdvX2FudCwgYygiTWVub3MgZGUgMiBhw7FvcyIsICJFbnRyZSAyIHkgNSBhw7FvcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVudHJlIDUgeSAxMCBhw7FvcyIsICJNw6FzIGRlIDEwIGHDsW9zIikpKQ0KIGFudF9mciAlPiUNCiAgc2VsZWN0KHJhbmdvX2FudCkgJT4lDQogIG11dGF0ZShjdWVudGEgPSAxKSAlPiUgDQogIGdyb3VwX2J5KHJhbmdvX2FudCkgJT4lDQogIHN1bW1hcmlzZShDdWVudGEgPSBzdW0oY3VlbnRhKSkgJT4lIA0KICBhcnJhbmdlKHJhbmdvX2FudCklPiUgDQogIHJlbmFtZSgiQcOxb3MgZGUgRXhwZXJpZW5jaWEiPXJhbmdvX2FudCkgJT4lIA0KICMgcmVuYW1lKCJFeHBvcnRhIj1leHBvcnRhKSAlPiUgDQogIGthYmxlKCJodG1sIiwgZXNjYXBlPUYpICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiICkpICU+JSANCiAgcm93X3NwZWMoMCwgYm9sZD1ULCBjb2xvcj0id2hpdGUiLCBiYWNrZ3JvdW5kID0gYXp1bCkNCg0KYGBgDQoNCiMjIFJlc3B1ZXN0YXMgcG9yICBCw7pzcXVlZGFzDQoNCk5vcyBpbnRlcmVzYSBzYWJlciBjdWFudG9zIHNlIGRlZGljYW4gYSByZWFsaXphciB0cmFiYWpvcyBkZSBzZWxlY2Npw7NuIGRlIHRhbGVudG9zLiANCg0KUG9kZW1vcyBvYnNlcnZhciBxdWUgdW4gNjYlIGRlIGxhcyBwZXJzb25hcyBlbmN1ZXN0YWRhcyBlbiBlc3RhIGNhdGVnb3JpYSBzZSBkZWRpY2FuIGEgbGEgdGFyZWEgZGUgYsO6c3F1ZWRhLiANCg0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQpmcmVlbG8yMiAlPiUgDQogIHNlbGVjdChzZXJ2aWNpb19idXNxdWVkYSkgJT4lDQogIG11dGF0ZShjdWVudGEgPSAxKSAlPiUgDQogIGdyb3VwX2J5KHNlcnZpY2lvX2J1c3F1ZWRhKSAlPiUNCiAgc3VtbWFyaXNlIChuID0gbigpKSAlPiUgDQogIG11dGF0ZShmcmVxID0gbi9zdW0obikpICU+JSANCiAgYXJyYW5nZSgtbiklPiUgDQpyZW5hbWUoIlNlcnYuIELDunNxdWVkYSI9c2VydmljaW9fYnVzcXVlZGEpICU+JQ0KICAga2FibGUoImh0bWwiLCBlc2NhcGU9RikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFLCBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJob3ZlciIsImNvbmRlbnNlZCIgKSkgJT4lIA0KICByb3dfc3BlYygwLCBib2xkPVQsIGNvbG9yPSJ3aGl0ZSIsIGJhY2tncm91bmQgPSBhenVsKQ0KDQpgYGANCg0KU2FiaWVuZG8gZWwgY3JlY2ltaWVudG8geSBhdWdlIGRlIGxhcyBiw7pzcXVlZGFzIGVuIGVsIHNlY3RvciBkZSBJVCwgdmVhbW9zIGN1w6FsIGVzIGxhIHBhcnRpY2lwYWNpw7NuIGRlIGxhcyBtaXNtYXMgZW50cmUgbGFzIHBlcnNvbmFzIHF1ZSBoYWNlbiByZWNydWl0aW5nLiANCg0KQ29tbyBzZSBvYnNlcnZhIGVuIGVsIHNpZ3VpZW50ZSBncsOhZmljbywgbGEgbWF5b3LDrWEgZGUgbGFzIGLDunNxdWVkYXMgc2UgY29uY2VudHJhbiBxdWUgZW4gZWwgc2VjdG9yIElULiANCg0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQoNCml0X2ZyPC0gZnJlZWxvMjIgJT4lIA0KICBzZWxlY3QoYnVzcXVlZGFfaXQsIHNlcnZpY2lvX2J1c3F1ZWRhKSAlPiUgDQogIGZpbHRlcihzZXJ2aWNpb19idXNxdWVkYT09IlNpIikgDQoNCg0KZ2dwbG90KGl0X2ZyLCAoYWVzKHggPSBidXNxdWVkYV9pdCwgZmlsbCA9IHNlcnZpY2lvX2J1c3F1ZWRhKSkpICsgDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKHg9IiIseT0iIikgKw0KICBlc3RpbG92ICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyh2ZXJkZSkpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJTZXJ2aWNpbyBkZSBCw7pzcXVlZGEiLA0KICAgICAgIHN1YnRpdGxlID0gIkZyZWVsYW5jZSIsDQogICAgICAgeCA9ICIiLCBmaWxsID0gIklUIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KYGBgDQoNCg0KIyMgUmVzcHVlc3RhIHBvciBnYXJhbnTDrWEgZGUgdHJhYmFqbw0KDQpMYXMgZ2FyYW50w61hcyBkZSByZXBvc2ljacOzbiBkZSB2YWNhbnRlcyBzZSByZWZpZXJlbiBhIGxhIHByb3RlY2Npw7NuIHF1ZSBzZSBicmluZGEgYSBjYWRhIGNsaWVudGUgZW4gZWwgY2FzbyBkZSBxdWUgbGEgcGVyc29uYSBjb250cmF0YWRhICAgc2UgbWFyY2hlIGRlIGxhIGVtcHJlc2EuDQoNClZlYW1vcyBlbnRyZSBsb3MgcXVlICBwcmVzdGFuICBlbCBzZXJ2aWNpbyBkZSByZWNydWl0aW5nLCBxdWllbmVzIG9mcmVjZW4gZ2FyYW50w61hIGRlIHBlcm1hbmVuY2lhIGRlbCBjYW5kaWRhdG8uIA0KDQoNCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KDQpndGlhIDwtIGZyZWVsbzIyICU+JSANCiMgIHNlbGVjdChnYXJhbnRpYSxzZXJ2aWNpb19idXNxdWVkYSkgJT4lIA0KICBmaWx0ZXIoc2VydmljaW9fYnVzcXVlZGE9PSJTaSIpICU+JSANCiAgbXV0YXRlKGdhcmFudGlhPWZjdF9jb2xsYXBzZShnYXJhbnRpYSwgIlNpIiA9IGMoIjEgbWVzIiwiMiBtZXNlcyIsICIzIG1lc2VzIikpLA0KICAgICAgICAgZ2FyYW50aWE9ZmN0X2NvbGxhcHNlKGdhcmFudGlhLCAiTm8iID0gYygiTm8gb2ZyZXpjbyBnYXJhbnTDrWEiKSksDQogICAgICAgICAgZ2FyYW50aWEgPSBmYWN0b3IoZ2FyYW50aWEsIGxldmVscyA9YygiU2kiLCJObyIgKSkpDQoNCg0KZ3RpYTIgPC0gZ3RpYSAlPiUgDQogIHNlbGVjdChnYXJhbnRpYSkgJT4lIA0KICBncm91cF9ieShnYXJhbnRpYSkgJT4lIA0KICBzdW1tYXJpc2UgKG4gPSBuKCkpICU+JSANCiAgbXV0YXRlKGZyZXEgPSBuL3N1bShuKSkgJT4lIA0KICBhcnJhbmdlKC1uKQ0KDQojIENvbXB1dGUgdGhlIGN1bXVsYXRpdmUgcGVyY2VudGFnZXMgKHRvcCBvZiBlYWNoIHJlY3RhbmdsZSkNCmd0aWEyJHltYXggPC0gY3Vtc3VtKGd0aWEyJGZyZXEpDQoNCiMgQ29tcHV0ZSB0aGUgYm90dG9tIG9mIGVhY2ggcmVjdGFuZ2xlDQpndGlhMiR5bWluIDwtIGMoMCwgaGVhZChndGlhMiR5bWF4LCBuPS0xKSkNCg0KIyBDb21wdXRlIGxhYmVsIHBvc2l0aW9uDQpndGlhMiRsYWJlbFBvc2l0aW9uIDwtIChndGlhMiR5bWF4ICsgZ3RpYTIkeW1pbikgLyAyDQoNCiMgQ29tcHV0ZSBhIGdvb2QgbGFiZWwNCmd0aWEyJGxhYmVsIDwtIHBhc3RlMChndGlhMiRnYXJhbnRpYSwgIlxuIENhbnQ6ICIsIGd0aWEyJG4pDQoNCiMgTWFrZSB0aGUgcGxvdA0KZ2dwbG90KGd0aWEyLCBhZXMoeW1heD15bWF4LCB5bWluPXltaW4sIHhtYXg9NCwgeG1pbj0zLCBmaWxsPWdhcmFudGlhKSkgKw0KICBnZW9tX3JlY3QoKSArDQogIGNvb3JkX3BvbGFyKHRoZXRhPSJ5IikgKyAjIFRyeSB0byByZW1vdmUgdGhhdCB0byB1bmRlcnN0YW5kIGhvdyB0aGUgY2hhcnQgaXMgYnVpbHQgaW5pdGlhbGx5DQogIHhsaW0oYygyLCA0KSkgKyMgVHJ5IHRvIHJlbW92ZSB0aGF0IHRvIHNlZSBob3cgdG8gbWFrZSBhIHBpZSBjaGFydA0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCB2ZXJkZSwgZ3JpcykpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiUm9ib3RvIikpICsNCiAgbGFicyh0aXRsZSA9ICJHYXJhbnTDrWEgZGUgUGVybWFuZW5jaWEiLA0KICAgICAgIGZpbGwgPSAiIiwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibGVmdCIpDQoNCg0KDQoNCmBgYA0KDQoNCg0KRW4gbGEgc2lndWllbnRlIHRhYmxhIHBvZGVtb3Mgb2JzZXJ2YXIgcXVlIGxvcyBwbGF6b3MgZGUgZ2FyYW50w61hIHN1ZWxlbiBpciBkZXNkZSB1biBtZXMgaGFzdGEgbG9zIHRyZXMgbWVzZXMuIFBlcm8gdW4gbsO6bWVybyBpbXBvcnRhbnRlLCBubyBvZnJlY2UgZ2FyYW50aWEgcG9yIGVsICBzZXJ2aWNpbyBjb250cmF0YWRvLg0KDQpgYGB7ciAgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQpndGlhMiA8LSBmcmVlbG8yMiAlPiUgDQojICBzZWxlY3QoZ2FyYW50aWEsc2VydmljaW9fYnVzcXVlZGEpICU+JSANCiAgZmlsdGVyKHNlcnZpY2lvX2J1c3F1ZWRhPT0iU2kiKSAlPiUgDQogIG11dGF0ZSggZ2FyYW50aWE9ZmN0X2NvbGxhcHNlKGdhcmFudGlhLCAiTm8iID0gYygiTm8gb2ZyZXpjbyBnYXJhbnTDrWEiKSksDQogICAgICAgICAgZ2FyYW50aWEgPSBmYWN0b3IoZ2FyYW50aWEsIGxldmVscyA9YygiU2kiLCJObyIgKSkpDQoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KDQoNCmBgYA0KDQojIyBSZXNwdWVzdGFzIHBvciBCYXNlIGRlIENvZWZpY2llbnRlDQoNCg0KT3RybyBwdW50byBwYXJhIGRlc3RhY2FyIGVzIGVsIHByZWNpbyBkZWwgc2VydmljaW8gZGUgcXVpZW5lcyBoYWNlbiByZWNydWl0aW5nLg0KDQpQb2RlbW9zIHZlciBxdWUgbGEgZ3JhbiBtYXlvcsOtYSAgY29icmEgICBwb3IgZGljaG8gc2VydmljaW8sIHVuIHBvcmNlbnRhamUgZGUgIHJlbXVuZXJhY2nDs24gbWVuc3VhbCBkZWwgaW5ncmVzYW50ZSwgZGVqYW5kbyBwYXJhIG11eSBwb2NvcyBjYXNvcyBlbCBpbmdyZXNvIGFudWFsIGRlbCBtaXNtby4NCg0KDQpVbmEgcHJlZ3VudGEgYWJpZXJ0YSBxdWUgbm9zIHF1ZWRhLCBlcyBjdcOhbGVzIHNvbiBsYXMgcG9zaWNpb25lcyBtZWpvcmVzIHBhZ2FzIHBhcmEgbG9zIHJlY3J1aXRlcnMuIFNpbiBlbWJhcmdvLCBkaWNobyBhbsOhbGlzaXMgZXNjYXBhIGRlIGxvcyBvYmpldGl2b3MgZGUgbGEgcHJlc2VudGUgZW5jdWVzdGEuICANCg0KYGBge3IgIGVjaG89RkFMU0UgLCBtZXNzYWdlPSBGQUxTRSwgIHdhcm5pbmcgPSBGQUxTRX0NCg0KY29lZl9mcjwtIGZyZWVsbzIyICU+JSANCiAgbXV0YXRlKGJhc2VfY29lZmljaWVudGU9ZmN0X2NvbGxhcHNlKGJhc2VfY29lZmljaWVudGUsICJNZW5zdWFsIiA9ICJSZW11bmVyYWNpw7NuIG1lbnN1YWwgZGVsIGluZ3Jlc2FudGUiKSwNCiAgICAgICAgIGJhc2VfY29lZmljaWVudGU9ZmN0X2NvbGxhcHNlKGJhc2VfY29lZmljaWVudGUsICJBbnVhbCIgPSAiUmVtdW5lcmFjacOzbiBhbnVhbCBkZWwgaW5ncmVzYW50ZSIpLA0KICAgICAgICAgIGJhc2VfY29lZmljaWVudGUgPSBmYWN0b3IoYmFzZV9jb2VmaWNpZW50ZSwgbGV2ZWxzID1jKCJNZW5zdWFsIiwiQW51YWwiICkpKQ0KDQoNCiBjb2VmX2ZyICU+JQ0KICBzZWxlY3Qoc2VydmljaW9fYnVzcXVlZGEsYmFzZV9jb2VmaWNpZW50ZSkgJT4lDQogIGZpbHRlcihzZXJ2aWNpb19idXNxdWVkYT09IlNpIikgJT4lIA0KICBtdXRhdGUoY3VlbnRhID0gMSkgJT4lIA0KICBncm91cF9ieShiYXNlX2NvZWZpY2llbnRlKSAlPiUNCiAgc3VtbWFyaXNlKEN1ZW50YSA9IHN1bShjdWVudGEpKSAlPiUgDQogIGFycmFuZ2UoLUN1ZW50YSklPiUgDQogIHJlbmFtZSgiUmVtdW5lcmFjacOzbiBkZWwgSW5ncmVzYW50ZSI9YmFzZV9jb2VmaWNpZW50ZSkgJT4lIA0KICBrYWJsZSgiaHRtbCIsIGVzY2FwZT1GKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IFRSVUUsIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsImhvdmVyIiwiY29uZGVuc2VkIiApKSAlPiUgDQogIHJvd19zcGVjKDAsIGJvbGQ9VCwgY29sb3I9IndoaXRlIiwgYmFja2dyb3VuZCA9IGF6dWwpDQoNCg0KYGBgDQoNCkxhIG1heW9yw61hIGNvYnJhIHVuIHBvcmNlbnRhamUgIHF1ZSB2YSBkZWwgIDIwJSBhbCAzMCUgZGUgIGxhcyByZW11bmVyYWNpb25lcyBtZW5zdWFsZXMgZGUgbG9zIGluZ3Jlc2FudGVzLCBjb21vIHBvZGVtb3MgdmVyIGVuIGVsIHNpZ3VpZW50ZSBjdWFkcm86DQoNCg0KYGBge3IgZWNobz1GQUxTRSAsIG1lc3NhZ2U9IEZBTFNFLCAgd2FybmluZyA9IEZBTFNFfQ0KDQojIyBhcm1vIGxhcyBjYXRlZ29yaWFzDQoNCiNmcmVlbG8yMSRjb2VmaWNpZW50ZSAjY29uc3VsdG8gY2F0ZWdvcmlhcw0KDQpuX2NvZWY8LSBmcmVlbG8yMiAlPiUgDQogIHNlbGVjdChzZXJ2aWNpb19idXNxdWVkYSxjb2VmaWNpZW50ZSxiYXNlX2NvZWZpY2llbnRlKSAlPiUgDQogIGZpbHRlcihzZXJ2aWNpb19idXNxdWVkYT09IlNpIikgJT4lIA0KICBmaWx0ZXIoYmFzZV9jb2VmaWNpZW50ZT09IlJlbXVuZXJhY2nDs24gbWVuc3VhbCBkZWwgaW5ncmVzYW50ZSIpICU+JSANCiAgZmlsdGVyKGNvZWZpY2llbnRlPjEwKSU+JSAgI0ZpbHRybyBlbnRyZSAwLTEwMCAoZGVjaWRvIGVsaW1pbmFyIDEuMiwxLjUsMi4wIHkgb3Ryb3MsIHBvcnF1ZSBubyBlcyBjbGFyYSBzdSBjYXRlZ29yaXphY2lvbikNCiAgZmlsdGVyKGNvZWZpY2llbnRlPDEwMSkgJT4lIA0KICBtdXRhdGUoY29lZmljaWVudGUgPWNhc2Vfd2hlbigNCiAgICAgIGNvZWZpY2llbnRlIDwgMTEgfiAiMTAlIiwNCiAgICBjb2VmaWNpZW50ZSA8IDIxIH4gIjIwJSIsDQogICAgY29lZmljaWVudGUgPCAzMSB+ICIzMCUiLA0KICAgICAgICBjb2VmaWNpZW50ZSA8IDQxIH4gIjQwJSIsDQogICAgY29lZmljaWVudGUgPCA1MSB+ICI1MCUiLA0KICAgIGNvZWZpY2llbnRlIDwgNjEgfiAiNjAlIiwNCiAgICBjb2VmaWNpZW50ZSA8IDcxIH4gIjcwJSIsDQogICAgY29lZmljaWVudGUgPCA4MSB+ICI4MCUiLA0KICAgIGNvZWZpY2llbnRlIDwgOTEgfiAiOTAlIiwNCiAgICBjb2VmaWNpZW50ZSA8MTAxIH4gIjEwMCUiLA0KICAgIGNvZWZpY2llbnRlID0gVCB+ICJPdHJvcyIpLA0KICAgIGNvZWZpY2llbnRlID0gZmN0X3JlbGV2ZWwoY29lZmljaWVudGUsIGMoIjEwJSIsIjIwJSIsIjMwJSIsIjQwJSIsIjUwJSIsIjYwJSIsIjcwJSIsIjgwJSIsIjkwJSIsIjEwMCUiLCJPdHJvcyIpKSkNCiAgDQojIGFncnVwbyBsYXMgY2F0ZWdvcmlhcyBlbiB1bmEgdGFibGEuDQoNCiBuX2NvZWY8LSBuX2NvZWYgJT4lDQogIHNlbGVjdChjb2VmaWNpZW50ZSkgJT4lDQogIG11dGF0ZShjdWVudGEgPSAxKSAlPiUgDQogIGdyb3VwX2J5KGNvZWZpY2llbnRlKSAlPiUNCiAgc3VtbWFyaXNlKEN1ZW50YSA9IHN1bShjdWVudGEpKSAlPiUgDQogICNhcnJhbmdlKC1DdWVudGEpJT4lIA0KICByZW5hbWUoIlBvcmNlbnRhamUiPWNvZWZpY2llbnRlKQ0KIA0KIG5fY29lZiRUSVAgPC0gYygiJSBTb2JyZSBsYSBSZW11bmVyYWNpw7NuIE1lbnN1YWwiKSAjIGFsIHBhc2FyIGVsIGN1cnNvciBzZSB2ZQ0KIA0KICNUYWJsYQ0KDQpuX2NvZWYgJT4lIA0KICBtdXRhdGUoQ3VlbnRhPXRleHRfc3BlYyhDdWVudGEsICJodG1sIiwgdG9vbHRpcD1USVApKSAlPiUgDQogICAgc2VsZWN0KFBvcmNlbnRhamUsQ3VlbnRhKSAlPiUgDQogIGthYmxlKCJodG1sIiwgZXNjYXBlPUYpICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiICkpICU+JSANCiAgcm93X3NwZWMoMCwgYm9sZD1ULCBjb2xvcj0id2hpdGUiLCBiYWNrZ3JvdW5kID0gYXp1bCkNCg0KDQpgYGANCg0KIyBPdHJvcyBhbsOhbGlzaXMNCg0KIyMgUmVsYWNpw7NuIGVudHJlIHNhdGlzZmFjY2nDs24geSBzdWVsZG9zDQpQYXJhIGVzdGUgYW7DoWxpc2lzIG5vcyBwcmVndW50YW1vcyBzaSBoYXkgcmVsYWNpw7NuIGVudHJlIGVsIG5pdmVsIHNhbGFyaWFsIHkgbGEgc2F0aXNmYWNjacOzbi4NCg0KUGFyYSByZXNwb25kZXIgYSBlc3RhIHByZWd1bnRhLCBjcnV6YW1vcyBsb3Mgc3VlbGRvcyBicnV0b3MgZGUgQXJnZW50aW5hLCBjb250cmEgbG9zIG5pdmVsZXMgZGUgc2F0aXNmYWNjacOzbiBjb24gbGEgYWN0dWFsIGVtcHJlc2EgZG9uZGUgdHJhYmFqYW4gbGFzIHBlcnNvbmFzIHF1ZSByZXNwb25kaWVyb24gbGEgZW5jdWVzdGEuDQoNCkxvcyBwYXNvcyBxdWUgc2VndWltb3MgZnVlcm9uIGxvcyBzaWd1aWVudGVzOg0KDQpBIGxvcyBzdWVsZG9zIGJydXRvcyBsb3Mgc2VnbWVudGFtb3MgZW4gNCBwYXJ0ZXMgY29uIGlndWFsIGNhbnRpZGFkIGRlIHJlZ2lzdHJvcyAoY3VhcnRpbGVzKS4gRXMgZGVjaXIsIGVuIGVsIDHCsCBjdWFydGlsIHRlbmVtb3MgZWwgMjUlIGRlIGxvcyBkYXRvcywgZW4gZWwgc2VndW5kbyBjdWFydGlsIHRlbmVtb3MgZWwgNTAlIGRlIGxvcyBkYXRvcywgeSBlbiBlbCAzwrAgY3VhcnRpbCB0ZW5lbW9zIGVsIDc1JSBkZSBsb3MgZGF0b3MuDQpFbiBlbCBwcmltZXIgY3VhcnRpbCBlc3TDoW4gbG9zIHN1ZWxkb3MgbcOhcyBiYWpvcywgeSBlbCA0wrAgbG9zIG3DoXMgYWx0b3MuDQpMb3Mgbml2ZWxlcyBkZSBzYXRpc2ZhY2Npw7NuIHZhbiBkZWwgMSAoVG90YWxtZW50ZSBJbnNhdGlzZmVjaG8pLCBhbCA1LCAoVG90YWxtZW50ZSBTYXRpc2ZlY2hvKS4NCg0KYGBge3J9DQpsaWJyYXJ5KGdnYWxsdXZpYWwpDQoNCnNhdGlzZiA8LSByaDIybGEgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKHNhdGlzZmFjY2lvbiksDQogICAgICAgICBwYWlzID09ICJBcmdlbnRpbmEiKSAlPiUgDQogIHNlbGVjdChzdWVsZG9fYnJ1dG8sIHNhdGlzZmFjY2lvbikNCg0KDQpwMjUgPC0gcHJvZmlsaW5nX251bShzYXRpc2YpWzEsN10NCnA1MCA8LSBwcm9maWxpbmdfbnVtKHNhdGlzZilbMSw4XQ0KcDc1IDwtIHByb2ZpbGluZ19udW0oc2F0aXNmKVsxLDldDQoNCnNhdGlzZiA8LSBzYXRpc2YgJT4lIA0KICBtdXRhdGUoY3VhcnRpbCA9IGZhY3RvcihjYXNlX3doZW4oDQogICAgc3VlbGRvX2JydXRvICA8ICAgcDI1ICB+ICIxUSIsDQogICAgc3VlbGRvX2JydXRvID4gcDI1ICYgc3VlbGRvX2JydXRvIDwgcDUwIH4gIjJRIiwNCiAgICBzdWVsZG9fYnJ1dG8gPiBwNTAgJiBzdWVsZG9fYnJ1dG8gPCBwNzUgfiAiM1EiLA0KICAgIFRSVUUgICB+ICI0USIpKSwNCiAgICBzYXRpc2ZhY2Npb24gPSBmYWN0b3Ioc2F0aXNmYWNjaW9uLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiMSIsIjIiLCIzIiwiNCIsIjUiKSksIA0KICAgIGN1ZW50YSA9IDEpDQoNCg0Kc2F0aXNmIDwtIHNhdGlzZiAlPiUgDQogIGdyb3VwX2J5KHNhdGlzZmFjY2lvbiwgY3VhcnRpbCkgJT4lIA0KICBzdW1tYXJpc2UoY2FudCA9IG4oKSkNCg0KDQoNCmdncGxvdChhcy5kYXRhLmZyYW1lKHNhdGlzZiksIGFlcyh5ID0gY2FudCwgYXhpczEgPSBjdWFydGlsLCBheGlzMiA9IHNhdGlzZmFjY2lvbikpICsNCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IGN1YXJ0aWwpLCB3aWR0aCA9IDEvMTIsICBhbHBoYSA9IDAuNCkgKw0KICBnZW9tX3N0cmF0dW0od2lkdGggPSAxLzEyLCBmaWxsID0gIiM4ODgyRjciKSArDQogIGdlb21fbGFiZWwoc3RhdCA9ICJzdHJhdHVtIiwgYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChzdHJhdHVtKSkpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJTdWVsZG8gQnJ1dG8gcG9yIEN1YXJ0aWwiLCAiTml2ZWwgZGUgU2F0aXNmYWNjacOzbiIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKHZlcmRlLCBsaWxhLCByb3NhMSwgYXp1bCkpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgbGFicyh0aXRsZSA9ICJSZWxhY2nDs24gZW50cmUgbml2ZWwgc2FsYXJpYWwgeSBzYXRpc2ZhY2Npw7NuIGNvbiBsYSBlbXByZXNhIiwNCiAgICAgICB5ID0gIiIsIGNhcHRpb24gPSBmdWVudGUsIGZpbGwgPSAiQ3VhcnRpbCIpDQpgYGANCg0KDQojIyBCdXJuIG91dCBlbiBSUkhIDQoNCkVuIGVzdGEgZWRpY2nDs24gZGUgbGEgRW5jdWVzdGEgS0lXSSBkZSBTdWVsZG9zIGRlIFJIIExhdGFtIGluY2x1aW1vcyB1bmFzIHByZWd1bnRhcyBudWV2YXMgc29icmUgKipidXJuIG91dCoqIGRlYmlkbyBhIGPDs21vIGVsIHRlbWEgZGUgbGEgc2FsdWQgbWVudGFsIGhhIGNvYnJhZG8gcmVsZXZhbmNpYSBkZXNkZSBlbCBpbmljaW8gZGUgbGEgcGFuZGVtaWEgeSBsYXMgY29tcGHDscOtYXMgaGFuIGRlc2Fycm9sbGFkbyBtdWNoYXMgYWN0aXZpZGFkZXMgKGNvbiBtYXlvciBvIG1lbm9yIGVmZWN0aXZpZGFkKSBkZXNkZSBlbnRvbmNlcy4NCg0KRXMgcG9yIGVzbyBxdWUgZW4gZXN0YSBlZGljacOzbiBpbmNsdWltb3MgMyBwcmVndW50YXM6DQoNCiogRGVsIDEgYWwgMTAsIMK/cXXDqSB0YW4gZXN0cmVzYWRvIG8gZXN0cmVzYWRhIHRlIHNlbnTDrXM/DQoqIEVuIGNvbXBhcmFjacOzbiBjb24gZWwgYcOxbyBwYXNhZG8sIMK/Y8OzbW8gdGUgc2VudMOtcz8NCiogTW90aXZvIHByaW5jaXBhbCBwb3IgZWwgY3VhbCBzZW50w61zIGVzdHLDqXMgZW4gZWwgdHJhYmFqby4NCg0KPiBFc3RhIHNlY2Npw7NuIGZ1ZSBwdWJsaWNhZGEgcHJldmlhbWVudGUgZW4gW2VzdGUgbGlua10oaHR0cHM6Ly9jaGVjaG9pZC5xdWFydG8ucHViL2J1cm5fb3V0LyMvYnVybi1vdXQtZW4tcnJoaCkNCg0KYGBge3IgZXN0cmVzfQ0KYnVybiA8LSBraXdpICU+JQ0KICBmaWx0ZXIoIWlzLm5hKGVzdHJlcykpICU+JSANCiAgc2VsZWN0KGdlbmVybywgcHVlc3RvLCBydWJybywgZXN0cmVzLA0KICAgICAgICAgY29tcGFyYWNpb24sIG1vdGl2bykNCg0KIyBUcmFuc2Zvcm1hciBlbiBjYXRlZ8OzcmljYSBsYSB2YXJpYWJsZSBlc3Ryw6lzDQpidXJuIDwtIGJ1cm4gJT4lIA0KICBtdXRhdGUoZXN0cmVzX2NhdCA9IGNhc2Vfd2hlbigNCiAgICBlc3RyZXMgPD0gMiB+ICJTaW4gRXN0csOpcyIsDQogICAgZXN0cmVzIDw9IDQgfiAiRXN0csOpcyBCYWpvIiwNCiAgICBlc3RyZXMgPD0gNiB+ICJFc3Ryw6lzIE1vZGVyYWRvIiwNCiAgICBlc3RyZXMgPD0gOCB+ICJFc3Ryw6lzIEFsdG8iLA0KICAgIGVzdHJlcyA8PSAxMCB+ICJFc3Ryw6lzIE11eSBBbHRvIg0KICApLA0KICBlc3RyZXNfY2F0ID0gZmFjdG9yKGVzdHJlc19jYXQsIA0KICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlNpbiBFc3Ryw6lzIiwgIkVzdHLDqXMgQmFqbyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVzdHLDqXMgTW9kZXJhZG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVzdHLDqXMgQWx0byIsICJFc3Ryw6lzIE11eSBBbHRvIikpKQ0KDQojIE9yZGVuYXIgdmFyaWFibGUgJ2NvbXBhcmFjaW9uJw0KYnVybiA8LSBidXJuICU+JSANCiAgbXV0YXRlKGNvbXBhcmFjaW9uID0gDQogICAgICAgICAgIGZhY3Rvcihjb21wYXJhY2lvbiwNCiAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk5vIG1lIHNpZW50byBlc3RyZXNhZGEgbyBlc3RyZXNhZG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ29uIG1lbm9zIGVzdHLDqXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWlzbW8gbml2ZWwgZGUgZXN0csOpcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb24gbcOhcyBlc3Ryw6lzIikpKQ0KDQojIENhbGN1bGFyIHBvcmNlbnRhamVzIGRlIGxvcyByZXN1bHRhZG9zLg0Kbml2ZWxlcyA8LSBidXJuICU+JSANCiAgZ3JvdXBfYnkoZXN0cmVzX2NhdCkgJT4lIA0KICBzdW1tYXJpc2UoY2FudCA9IG4oKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShQb3JjZW50YWplID0gY2FudC9zdW0oY2FudCkpDQpgYGANCg0KUGFyYSBjb25zdHJ1aXIgbGFzIGNhdGVnb3LDrWFzIGRlIGxvcyBuaXZlbGVzIGRlIGVzdHLDqXMgYXN1bWltb3MgcXVlIHJlc3VsdGFkb3M6DQoNCi0gICAxIG8gMiA9ICpTaW4gRXN0csOpcyoNCi0gICAzIG8gNCA9ICpFc3Ryw6lzIEJham8qDQotICAgNSBvIDYgPSAqRXN0csOpcyBNb2RlcmFkbyoNCi0gICA3IHUgOCA9ICpFc3Ryw6lzIEFsdG8qDQotICAgOSBvIDEwID0gKkVzdHLDqXMgTXV5IEFsdG8qDQoNCkVuIGJhc2UgYSBgciBzdW0obml2ZWxlcyRjYW50KWAgcmVjaWJpZGFzLCBlbCBgciBzY2FsZXM6OnBlcmNlbnQocHVsbChuaXZlbGVzWzQsM10pICsgcHVsbChuaXZlbGVzWzUsM10pLCBhY2N1cmFjeSA9IDEpYCBzaWVudGVuIHF1ZSBzdSBuaXZlbCBkZSBlc3Ryw6lzIGVzICoqQWx0byoqIG8gKipNdXkgQWx0byoqLg0KDQpgYGB7cn0NCmdncGxvdChuaXZlbGVzLCBhZXMoeCA9IGVzdHJlc19jYXQsIHkgPSBjYW50LCBmaWxsID0gZXN0cmVzX2NhdCkpICsNCiAgZ2VvbV9jb2woKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50KFBvcmNlbnRhamUsIGFjY3VyYWN5ID0gMSkpLA0KICAgICAgICAgICAgdmp1c3QgPSAxLjIsDQogICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIsIA0KICAgICAgICAgICAgZmFjZSA9ICJib2xkIiwNCiAgICAgICAgICAgIHNpemUgPSA0KSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKGRpcmVjdGlvbiA9IC0xKSsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiTml2ZWxlcyBkZSBlc3Ryw6lzIGVuIFJSSEgiLA0KICAgICAgIHN1YnRpdGxlID0gcGFzdGUwKCJFbiBiYXNlIGEgIiwgc3VtKG5pdmVsZXMkY2FudCksICIgcmVzcHVlc3RhcyByZWNpYmlkYXMiKSwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwgDQogICAgICAgZmlsbCA9IE5VTEwpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KYGBgDQoNCiMjIyBDb21wYXJhY2nDs24gZGUgRXN0cmVzDQoNCmBgYHtyIGNvbXBhcmFjaW9ufQ0KY29tcGFyYWNpb24gPC0gYnVybiAlPiUgDQogIGdyb3VwX2J5KGNvbXBhcmFjaW9uKSAlPiUgDQogIHN1bW1hcmlzZShjYW50ID0gbigpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIG11dGF0ZShwb3JjZW50YWplID0gY2FudC9zdW0oY2FudCksDQogICAgICAgICBjb21wYXJhY2lvbiA9IHN0cl93cmFwKGNvbXBhcmFjaW9uLCB3aWR0aCA9IDIwKSkNCmBgYA0KDQpMYSBzaWd1aWVudGUgcHJlZ3VudGEgcXVlIHJlYWxpemFtb3MgZXMgc2kgbGEgc2Vuc2FjacOzbiBkZSBlc3Ryw6lzIGVzIG1heW9yLCBpZ3VhbCBvIG1lbm9yIGFsIGHDsW8gcGFzYWRvLg0KDQpFbiBiYXNlIGEgbGFzIHJlc3B1ZXN0YXMgb2J0ZW5pZGFzLCB1biBgciBzY2FsZXM6OnBlcmNlbnQocHVsbChjb21wYXJhY2lvbls0LDNdKSwgYWNjdXJhY3kgPSAxKWAgc2llbnRlIHF1ZSBzdSBuaXZlbCBkZSBlc3Ryw6lzIGVzIG1heW9yIGVuIHJlbGFjacOzbiBhbCBhw7FvIGFudGVyaW9yLCBtaWVudHJhcyBxdWUgdW4gYHIgc2NhbGVzOjpwZXJjZW50KHB1bGwoY29tcGFyYWNpb25bMiwzXSksIGFjY3VyYWN5ID0gMSlgIGFmaXJtYSBxdWUgc3VzIG5pdmVsZXMgZGUgZXN0csOpcyBzb24gKiptw6FzIGJham9zKiogZW4gcmVsYWNpw7NuIGFsIDIwMjEuDQoNCmBgYHtyfQ0KZ2dwbG90KGNvbXBhcmFjaW9uLCBhZXMoeCA9IGNvbXBhcmFjaW9uLCANCiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBjYW50LCANCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSBjb21wYXJhY2lvbikpICsNCiAgZ2VvbV9jb2woKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnQocG9yY2VudGFqZSwgYWNjdXJhY3kgPSAxKSksDQogICAgICAgICAgICB2anVzdCA9IDEuMiwNCiAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwgDQogICAgICAgICAgICBmYWNlID0gImJvbGQiLA0KICAgICAgICAgICAgc2l6ZSA9IDQpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2QoZGlyZWN0aW9uID0gLTEpKw0KICBlc3RpbG9oICsNCiAgbGFicyh0aXRsZSA9ICJDb21wYXJhY2nDs24gZGUgTml2ZWxlcyBkZSBFc3Ryw6lzIHZzLiBBw7FvIEFudGVyaW9yIiwNCiAgICAgICBzdWJ0aXRsZSA9IHBhc3RlMCgiRW4gYmFzZSBhICIsIHN1bShuaXZlbGVzJGNhbnQpLCAiIHJlc3B1ZXN0YXMgcmVjaWJpZGFzIiksDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsIA0KICAgICAgIGZpbGwgPSBOVUxMKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCmBgYA0KDQojIyMgQ2F1c2FzIGRlIGxhIHNlbnNhY2nDs24gZGUgZXN0csOpcw0KDQpFbiBsYSBzaWd1aWVudGUgbnViZSBkZSBwYWxhYnJhcyBwb2RyZW1vcyB2ZXIgbGFzIGNhdXNhcyBtZW5jaW9uYWRhcyBlbiBsYSBwcmVndW50YSBhYmllcnRhIHNvYnJlIGxhcyBjYXVzYXMgZGUgbGEgc2Vuc2FjacOzbiBkZSBlc3Ryw6lzIGRlIGxhcyBwZXJzb25hcyBxdWUgdHJhYmFqYW4gZW4gUlJISC4NCg0KYGBge3J9DQojIFNlcGFyYXIgbGFzIHBhbGFicmFzIGVuIGZpbGFzIGluZGl2aWR1YWxlcw0KY2F1c2EgPC0gYnVybiAlPiUgDQogIGZpbHRlcighaXMubmEobW90aXZvKSkgJT4lIA0KICBzZWxlY3QobW90aXZvKSAlPiUgDQogIHVubmVzdF90b2tlbnMocGFsYWJyYSwgbW90aXZvKQ0KDQojIExleGljb24gZGUgcGFsYWJyYXMgdmFjw61hcw0KdmFjaWFzIDwtIHJlYWRfY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vN1BhcnRpZGFzRGlnaXRhbC9BbmFUZXh0L21hc3Rlci9kYXRvcy9kaWNjaW9uYXJpb3MvdmFjaWFzLnR4dCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlID0gZGVmYXVsdF9sb2NhbGUoKSkNCg0KIyBFbGltaW5hciBwYWxhYnJhcyB2YWPDrWFzDQpjYXVzYSA8LSBjYXVzYSAlPiUgDQogIGFudGlfam9pbih2YWNpYXMsIGJ5ID0gInBhbGFicmEiKQ0KDQojIENvbnRhciBsYSBjYW50aWRhZCBkZSB2ZWNlcyBxdWUgYXBhcmVjZSBjYWRhIHBhbGFicmENCiBjYXVzYSA8LSBjYXVzYSAlPiUNCiAgIGNvdW50KHBhbGFicmEsIHNvcnQgPSBULCBuYW1lID0gImZyZXEiKQ0KDQojIENyZWFyIGxhIG51YmUgZGUgcGFsYWJyYXMNCm51YmUgPC0gd29yZGNsb3VkMihkYXRhID0gY2F1c2EsDQogICAgICAgICAgIHNpemUgPSAwLjgsDQogICAgICAgICAgIHJvdGF0ZVJhdGlvID0gMSwNCiAgICAgICAgICAgY29sb3IgPSByZXBfbGVuKGMoIiNENDQ5OUMiLCAiIzM1MDBCMyIsICIjMDJEOUM1IiwgIiM1NDYzQTgiLCAiI0RFRjI0MSIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgbnJvdyhjYXVzYSkpKQ0KbnViZQ0KYGBgDQoNClBvZGVtb3MgYXByZWNpYXIgcXVlIGxhcyA1IHByaW5jaXBhbGVzIHBhbGFicmFzIHNvbjogDQoNCjEuICpgciBwdWxsKGNhdXNhWzEsMV0pYCo6IGNvbiBgciBwdWxsKGNhdXNhWzEsMl0pYCBhcGFyaWNpb25lcw0KMi4gKmByIHB1bGwoY2F1c2FbMiwxXSlgKjogY29uIGByIHB1bGwoY2F1c2FbMiwyXSlgIGFwYXJpY2lvbmVzDQozLiAqYHIgcHVsbChjYXVzYVszLDFdKWAqOiBjb24gYHIgcHVsbChjYXVzYVszLDJdKWAgYXBhcmljaW9uZXMNCjQuICpgciBwdWxsKGNhdXNhWzQsMV0pYCo6IGNvbiBgciBwdWxsKGNhdXNhWzQsMl0pYCBhcGFyaWNpb25lcw0KNS4gKmByIHB1bGwoY2F1c2FbNSwxXSlgKjogY29uIGByIHB1bGwoY2F1c2FbNSwyXSlgIGFwYXJpY2lvbmVzDQoNCkVzdG8gbm9zIGRhcsOtYSBhIGVudGVuZGVyIHF1ZSB1bmEgZGUgbGFzIHByaW5jaXBhbGVzIGNhdXNhcyBkZSBlc3Ryw6lzIGVzIGxhIGFsdGEgY2FyZ2EgZGUgdHJhYmFqbyBjb24gbGEgcXVlIGNvbnRhbW9zIHkgbGEgZmFsdGEgZGUgcmVjdXJzb3MgcXVlIHRlbmVtb3MuDQoNCkEgY29udGludWFjacOzbiBpbnRlbnRhcmVtb3MgYW5hbGl6YXIgbGFzIHJlbGFjaW9uZXMgZGUgZXN0b3MgY29uY2VwdG9zLCBwYXJhIGxvIGN1YWwgbG8gcXVlIGhhcmVtb3MgZW4gcHJpbWVyIGx1Z2FyIGVzIGFncnVwYXIgbGFzIHBhbGFicmFzIGRlIGEgcGFyZXMsIGxsYW1hZG9zICpiaWdyYW1hcyogZW4gbGEgamVyZ2EsIHkgbHVlZ28gcmVhbGl6YXJlbW9zIHVuIGFuw6FsaXNpcyBkZSBncmFmb3MgcGFyYSB2ZXIgY8OzbW8gc2UgcmVsYWNpb25hbiBlbnRyZSBzw60uIFBhcmEgc2FiZXIgbcOhcyBzb2JyZSBhbsOhbGlzaXMgZGUgZ3JhZm9zIHRlIGludml0YW1vcyBhIFt2ZXIgZXN0ZSB2aWRlbyBkZSB1biBtZWV0dXAgZGUgUjRIUl0oKQ0KYGBge3IgYmlncmFtYXN9DQojIENyZWFtb3MgZHVwbGFzIGRlIHRva2Vucw0KY2F1c2EyIDwtIGJ1cm4gJT4lIA0KICBmaWx0ZXIoIWlzLm5hKG1vdGl2bykpICU+JSANCiAgc2VsZWN0KG1vdGl2bykgJT4lIA0KICB1bm5lc3RfdG9rZW5zKGJpZ3JhbWEsIG1vdGl2bywNCiAgICAgICAgICAgICAgICB0b2tlbiA9ICJuZ3JhbXMiLA0KICAgICAgICAgICAgICAgIG4gPSAyKQ0KDQojIFNlcGFyYW1vcyBsb3MgYmlncmFtYXMgZW4gZG9zIGNvbHVtbmFzDQpjYXVzYTIgPC0gY2F1c2EyICU+JSANCiAgICBzZXBhcmF0ZShiaWdyYW1hLA0KICAgICAgICAgICBjKCJwYWxhYnJhMSIsICJwYWxhYnJhMiIpLA0KICAgICAgICAgICBzZXAgPSAiICIpDQoNCiMgRWxpbWluYW1vcyBwYWxhYnJhcyB2YWPDrWFzDQpjYXVzYTIgPC0gY2F1c2EyICU+JSANCiAgIGZpbHRlcighcGFsYWJyYTEgJWluJSB2YWNpYXMkcGFsYWJyYSwNCiAgICAgICAgICFwYWxhYnJhMiAlaW4lIHZhY2lhcyRwYWxhYnJhKQ0KDQojIEVsaW1pbmFtb3MgZmlsYXMgY29uIGRhdG9zIG51bG9zDQpjYXVzYTIgPC0gY2F1c2EyICU+JSANCiAgZmlsdGVyKCFpcy5uYShwYWxhYnJhMSkpDQoNCmBgYA0KDQpTaSB0aWVuZW4gY3VyaW9zaWRhZCBwb3IgdmVyIGN1w6FsZXMgc29uIGxvcyAqYmlncmFtYXMqIG3DoXMgZnJlY3VlbnRlcyBsZXMgZGVqbyBlc3RlIGdyw6FmaWNvOg0KDQpgYGB7cn0NCmNhdXNhMiAlPiUgDQogIHVuaXRlKGJpZ3JhbWEsIHBhbGFicmExLCBwYWxhYnJhMiwgc2VwID0gIiAiKSAlPiUgDQogIGdyb3VwX2J5KGJpZ3JhbWEpICU+JSANCiAgdGFsbHkoc29ydCA9IFRSVUUpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgZmlsdGVyKG4gPiAxKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKGJpZ3JhbWEsIG4pKSkgKw0KICBnZW9tX2NvbChmaWxsID0gcm9zYTIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCANCiAgICAgICAgICAgIGhqdXN0ID0gMS4yLCANCiAgICAgICAgICAgIHNpemUgPSAzKSArDQogIGVzdGlsb3YgKw0KICBsYWJzKHRpdGxlID0gIk1vdGl2b3MgZGUgRXN0csOpcyBlbiBSUkhIIiwNCiAgICBzdWJ0aXRsZSA9ICJCaWdyYW1hcyBtw6FzIGZyZWN1ZW50ZXMiLA0KICAgICAgIHggPSBOVUxMLCB5ID0gIkJpZ3JhbWFzIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlKQ0KYGBgDQpMYXMgY2FudGlkYWRlcyBkZSByZXBldGljaW9uZXMgc29uIGJhamFzIHBvcnF1ZSBzw7NsbyB0ZW5lbW9zIDE2MCBjb21lbnRhcmlvcyBwYXJhIGFuYWxpemFyLiBTaW4gZW1iYXJnbyBoYXkgdMOzcGljb3MgcXVlIHBvZGVtb3MgZW50ZW5kZXIgcXVlIGxhIGNhcmdhIGRlIHRyYWJham8gKGBjYXJnYSBsYWJvcmFsYCwgYG11Y2hvIHRyYWJham9gLCBgbXVjaG9zIHRlbWFzYCwgYG11Y2hhcyBjb3Nhc2ApIGVzIGxhIHByaW5jaXBhbCBjYXVzYSBkZSBlc3Ryw6lzIGRlbnRybyBkZSBSUkhILg0KDQpBaG9yYSBhbmFsaWNlbW9zIGxhcyByZWxhY2lvbmVzIGVudHJlIGVzdG9zIGNvbmNlcHRvczoNCg0KYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEwfQ0KIyBDcmVhbW9zIHVuIG9iamV0byBncmFmbw0KZ3JhZm9fY2F1c2EyIDwtICBjYXVzYTIgJT4lIA0KICBjb3VudChwYWxhYnJhMSwgcGFsYWJyYTIsIHNvcnQgPSBUKSANCg0KZ3JhZm9fY2F1c2EyIDwtIGdyYWZvX2NhdXNhMiAlPiUgDQogIGdyYXBoX2Zyb21fZGF0YV9mcmFtZSgpDQoNCiMgU2VsZWNjaW9uYXIgMTAwIGZpbGFzIG5hZGEgbcOhcyANCmdncmFwaChncmFmb19jYXVzYTIsIGxheW91dCA9ICJuaWNlbHkiKSArDQogIGdlb21fZWRnZV9saW5rKGFlcyhlZGdlX2FscGhhID0gbiksDQogICAgICAgICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UsDQogICAgICAgICAgICAgICAgIGFycm93ID0gYXJyb3codHlwZSA9ICJjbG9zZWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IHVuaXQoMywgIm1tIikpKSArDQogIGdlb21fbm9kZV9wb2ludChjb2xvciA9IHJvc2EyLCBzaXplID0gMykgKw0KICBnZW9tX25vZGVfdGV4dChhZXMobGFiZWwgPSBuYW1lKSwgdmp1c3QgPSAxLCBoanVzdCA9IDEpICsNCiAgdGhlbWVfdm9pZCgpDQogIA0KYGBgDQoNCkVzdGUgZ3LDoWZpY28gaW5pY2lhbCBlcyB1biBwb2NvIGNvbmZ1c28gZGFkbyBxdWUgdGVuZW1vcyBtdWNoYXMgcmVsYWNpb25lcyBjb24gYmlncmFtYXMgcXVlIHNlIHJlcGl0ZW4gdW5hIHNvbGEgdmV6LiBQZXJvIHByZXN0ZW1vcyBhdGVuY2nDs24gYSBsYXMgem9uYXMgZG9uZGUgaGF5IG11Y2hhIGNvbmNlbnRyYWNpw7NuIGRlIGNvbmNlcHRvcywgeSBlc28gbm9zIHZhIGEgZGFyIHVuYSBpZGVhIGRlIGPDs21vIHNlIHJlbGFjaW9uYW4gbGFzIHBhbGFicmFzIGVudHJlIHPDrS4gDQoNCkJ1c3F1ZW4gZWwgdMOpcm1pbm8gYGNhcmdhYC4gTGFzIHBhbGFicmFzIGBtdWNoYWAgeSBgZGVtYXNpYWRhYCBhcHVudGFuIGEgYGNhcmdhYCAoZXN0byBzZSBsbGFtYSB1biAqZ3JhZm8gZGlyaWdpZG8qKSB5IGx1ZWdvIGBjYXJnYWAgYXB1bnRhIGEgYGxhYm9yYWxgIHF1ZSB0aWVuZSBhIHN1IHZleiByZWxhY2lvbmVzIGNvbiBgYWdlbmRhYCwgYHByZXNpw7NuYCB5IGBlbnRvcm5vYCwgcG9yIGVqZW1wbG8uDQoNClNpIGZpbHRyYW1vcyBsb3MgYmlncmFtYXMgcXVlIHRpZW5lbiBtw6FzIGRlIHVuYSBhcGFyaWNpw7NuIG5vcyBlbmNvbnRyYW1vcyBjb24gYWxnbyBhc8OtDQoNCmBgYHtyfQ0KIyBDcmVhbW9zIHVuIG9iamV0byBncmFmbw0KZ3JhZm9fY2F1c2EyIDwtICBjYXVzYTIgJT4lIA0KICBjb3VudChwYWxhYnJhMSwgcGFsYWJyYTIsIHNvcnQgPSBUKSAlPiUgDQogIGZpbHRlcihuID4gMSkNCg0KZ3JhZm9fY2F1c2EyIDwtIGdyYWZvX2NhdXNhMiAlPiUgDQogIGdyYXBoX2Zyb21fZGF0YV9mcmFtZSgpDQoNCiMgU2VsZWNjaW9uYXIgMTAwIGZpbGFzIG5hZGEgbcOhcyANCmdncmFwaChncmFmb19jYXVzYTIsIGxheW91dCA9ICJuaWNlbHkiKSArDQogIGdlb21fZWRnZV9saW5rKGFlcyhlZGdlX2FscGhhID0gbiksDQogICAgICAgICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UsDQogICAgICAgICAgICAgICAgIGFycm93ID0gYXJyb3codHlwZSA9ICJjbG9zZWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IHVuaXQoMywgIm1tIikpKSArDQogIGdlb21fbm9kZV9wb2ludChjb2xvciA9IHJvc2EyLCBzaXplID0gMykgKw0KICBnZW9tX25vZGVfdGV4dChhZXMobGFiZWwgPSBuYW1lKSwgdmp1c3QgPSAxLCBoanVzdCA9IDEpICsNCiAgdGhlbWVfdm9pZCgpDQpgYGANClZlbW9zIHF1ZSBsb3MgdMOpcm1pbm9zIGBtdWNob2AsIGBtdWNob3NgLCBgbXVjaGFzYCwgYG11Y2hhYCBzaSBiaWVuIHNlIHJlZmllcmVuIGEgbG8gbWlzbW8sIGEgdW4gZXhjZXNvLCBhbCBlc3RhciBlc2NyaXRvIGRlIGRpZmVyZW50ZXMgbWFuZXJhcyBnZW5lcmEgNCB0w6lybWlub3MgZGlmZXJlbnRlcywgYXPDrSBxdWUgaW50ZW50YXJlbW9zIHJlcGV0aXIgZWwgcHJpbWVyIGdyYWZvIGNvbiB0b2RvcyBsb3MgY29uY2VwdG9zLCBwZXJvIGVsaW1pbmFuZG8gbGFzIHBhbGFicmFzIGVuIHBsdXJhbCB5IHN1IGfDqW5lcm8gKGVuIGxhIG1lZGlkYSBkZSBsbyBwb3NpYmxlKSBwYXJhIGludGVudGFyIGdlbmVyYXIgbWF5b3IgY2xhcmlkYWQuDQoNCkVzdGUgcHJvY2VzbyBkZSBsaW1waWV6YSBub3MgcGVybWl0acOzIGRldGVjdGFyIHF1ZSBlbCB0w6lybWlubyBgdGllbXBvYCB0YW1iacOpbiB0aWVuZSBtdWNoYSByZWxhY2nDs24gY29uIHZhcmlvcyBjb25jZXB0b3MgcXVlIGNvbnRyaWJ1eWVuIGHDsSBidXJuIG91dCBlbiBSUkhILg0KDQpgYGB7ciBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTF9DQojIENvbWVuemFtb3MgbGltcGllemEgZGUgZGF0b3MNCmJ1cm4yIDwtIGJ1cm4gJT4lIA0KICBtdXRhdGUobW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAiYWxhcyIsICJhIGxhcyIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAiYcOxb3MiLCAiYcOxbyIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAiW2HDoV1yZWFzIiwgIsOhcmVhIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJhc2lnbmFkYXMiLCAiYXNpZ25hZG9zIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJhc3BlY3RvcyIsICJhc3BlY3RvIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJiZW5lZmljaW9zIiwgImJlbmVmaWNpbyIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAiYnVlblthb11zfGJ1ZW5hIiwgImJ1ZW5vIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJjbGFyYXN8Y2xhcm9zIiwgImNsYXJvIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJjbGllbnRlcyIsICJjbGllbnRlIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJkZWJlcsOtYW4iLCAiZGViZW4iKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgImRlbWFzaWFkYXMiLCAiZGVtYXNpYWRhIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJkZWNpc2lvbmVzIiwgImRlY2lzacOzbiIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAiZMOtYXMiLCAiZMOtYSIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAiZWNvbsOzbWljYXxlY29ub21pY2EiLCAiZWNvbsOzbWljbyIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAiZXhpZ2VuY2lhcyIsICJleGlnZW5jaWEiKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgImV4dGVybm9zIiwgImV4dGVybm8iKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgImV4dHJhcyIsICJleHRyYSIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAiZXN0cmVzIiwgImVzdHLDqXMiKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgImV4cGVjdGF0aXZhcyIsICJleHBlY3RhdGl2YSIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAiZXhjZXNpdmFzIiwgImV4Y2VzaXZhIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJleHRlcm5bYW9dcyIsICJleHRlcm5vIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJnbG9iYWxlcyIsICJnbG9iYWwiKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgImhhW2JjXWVyW2xtXWV8aGFnb3xoYWNlIiwgImhhY2VyIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJob3JhcyIsICJob3JhIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJpbnRlcm5bYW9dcyIsICJpbnRlcm5vIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJqZWZbYWVdIiwgImplZmUiKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgImpvcm5hZGFzIiwgImpvcm5hZGEiKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgImxhc3JnW2FvXXN8bGFyZ2EiLCAibGFyZ28iKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgImxbacOtXWRlcmVzIiwgImxpZGVyIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJsYWJvcmFsZXMiLCAibGFib3JhbCIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAibG9jYWxlcyIsICJsb2NhbCIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAibWFsb3MiLCAibWFsIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJtdWNoW2FvXSIsICJtdWNobyIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAibmVjZXNhcmlbYW9dfG5lY2VzYXJpW2FvXXMiLCAibmVjZXNhcmlvIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJudWV2W2FvXXxudWV2W2FvXXMiLCAibnVldm8iKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgInBvY2F8cG9jW2FvXXMiLCAicG9jbyIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAicHJlc2lvbnxwcmVzaW9uZXMiLCAicHJlc2nDs24iKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgInByb2JsZW1hcyIsICJwcm9ibGVtYSIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAicHJvcGlhfHByb3BpW2FvXXMiLCAicHJvcGlvIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJwcm95ZWN0b3MiLCAicHJveWVjdG8iKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgInJlYWxpem98cmVhbGl6YWRhc3xyZWFsaXphZGEiLCAicmVhbGl6YXIiKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgInJlZ2xhcyIsICJyZWdsYSIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAicmVsYWNpb25lc3xyZWxhY2lvbiIsICJyZWxhY2nDs24iKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgInJlc3BvbnNhYmlsaWRhZGVzIiwgInJlc3BvbnNhYmlsaWRhZCIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAicmVzcHVlc3RhcyIsICJyZXNwdWVzdGEiKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgInJlc3BvbnNhYmlsaWRhZGVzIiwgInJlc3BvbnNhYmlsaWRhZCIpLA0KICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAicmVzdWx0YWRvcyIsICJyZXN1bHRhZG8iKSwgICAgICAgICAgICAgICAgbW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAic2l0dWFjaW9ufHNpdHVhY2lvbmVzIiwgInNpdHVhY2nDs24iKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgInNvbHVjaW9uZXMiLCAic29sdWNpw7NuIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJ0YXJlYXMiLCAidGFyZWEiKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgInRlbWFzIiwgInRlbWEiKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgInRlbmVtb3N8dGVuZ28iLCAidGVuZXIiKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgInRpZW1wb3MiLCAidGllbXBvIiksDQogICAgICAgICBtb3Rpdm8gPSBzdHJfcmVwbGFjZShtb3Rpdm8sICJ0b21hZG8iLCAidG9tYXIiKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgInRveGljb3x0w7N4aWNbYW9dfHTDs3hpY1thb11zIiwgInTDs3hpY28iKSwNCiAgICAgICAgIG1vdGl2byA9IHN0cl9yZXBsYWNlKG1vdGl2bywgInRyYWJhamFuZG8iLCAidHJhYmFqYXIiKSkNCg0KYnVybjIgPC0gYnVybjIgJT4lIA0KICBtdXRhdGUobW90aXZvID0gc3RyX3JlcGxhY2UobW90aXZvLCAibXVjaFthb11zIiwgIm11Y2hvIikpDQoNCiMgQ3JlYW1vcyBkdXBsYXMgZGUgdG9rZW5zDQpjYXVzYTMgPC0gYnVybjIgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKG1vdGl2bykpICU+JSANCiAgc2VsZWN0KG1vdGl2bykgJT4lIA0KICB1bm5lc3RfdG9rZW5zKGJpZ3JhbWEsIG1vdGl2bywNCiAgICAgICAgICAgICAgICB0b2tlbiA9ICJuZ3JhbXMiLA0KICAgICAgICAgICAgICAgIG4gPSAyKQ0KDQojIFNlcGFyYW1vcyBsb3MgYmlncmFtYXMgZW4gZG9zIGNvbHVtbmFzDQpjYXVzYTMgPC0gY2F1c2EzICU+JSANCiAgICBzZXBhcmF0ZShiaWdyYW1hLA0KICAgICAgICAgICBjKCJwYWxhYnJhMSIsICJwYWxhYnJhMiIpLA0KICAgICAgICAgICBzZXAgPSAiICIpDQoNCiMgRWxpbWluYW1vcyBwYWxhYnJhcyB2YWPDrWFzDQpjYXVzYTMgPC0gY2F1c2EzICU+JSANCiAgIGZpbHRlcighcGFsYWJyYTEgJWluJSB2YWNpYXMkcGFsYWJyYSwNCiAgICAgICAgICFwYWxhYnJhMiAlaW4lIHZhY2lhcyRwYWxhYnJhKQ0KDQojIEVsaW1pbmFtb3MgZmlsYXMgY29uIGRhdG9zIG51bG9zDQpjYXVzYTMgPC0gY2F1c2EzICU+JSANCiAgZmlsdGVyKCFpcy5uYShwYWxhYnJhMSkpDQoNCiMgQ3JlYW1vcyB1biBvYmpldG8gZ3JhZm8NCmdyYWZvX2NhdXNhMyA8LSAgY2F1c2EzICU+JSANCiAgY291bnQocGFsYWJyYTEsIHBhbGFicmEyLCBzb3J0ID0gVCkgDQoNCmdyYWZvX2NhdXNhMyA8LSBncmFmb19jYXVzYTMgJT4lIA0KICBncmFwaF9mcm9tX2RhdGFfZnJhbWUoKQ0KDQojIFNlbGVjY2lvbmFyIDEwMCBmaWxhcyBuYWRhIG3DoXMgDQpnZ3JhcGgoZ3JhZm9fY2F1c2EzLCBsYXlvdXQgPSAibmljZWx5IikgKw0KICBnZW9tX2VkZ2VfbGluayhhZXMoZWRnZV9hbHBoYSA9IG4pLA0KICAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICBhcnJvdyA9IGFycm93KHR5cGUgPSAiY2xvc2VkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSB1bml0KDMsICJtbSIpKSkgKw0KICBnZW9tX25vZGVfcG9pbnQoY29sb3IgPSByb3NhMiwgc2l6ZSA9IDMpICsNCiAgZ2VvbV9ub2RlX3RleHQoYWVzKGxhYmVsID0gbmFtZSksIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSArDQogIHRoZW1lX3ZvaWQoKQ0KYGBgDQoNCg0KIyMjIFJlc3VsdGFkb3MgcG9yIGfDqW5lcm8NCg0KQ29tcGFyZW1vcyBsb3Mgc2NvcmVzIHByb21lZGlvcyBzZWfDum4gZWwgZ8OpbmVyby4NCg0KYGBge3J9DQpidXJuICU+JSANCiAgZmlsdGVyKGdlbmVybyAlaW4lIGMoIk11amVyIGNpcyIsICJIb21icmUgY2lzIikpICU+JSANCiAgZ3JvdXBfYnkoZ2VuZXJvKSAlPiUgDQogIHN1bW1hcmlzZShlc3RyZXNfcHJvbSA9IG1lYW4oZXN0cmVzKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBnZW5lcm8sIHkgPSBlc3RyZXNfcHJvbSwgZmlsbCA9IGdlbmVybykpICsNCiAgZ2VvbV9jb2woKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChlc3RyZXNfcHJvbSwxKSksDQogICAgICAgICAgICB2anVzdCA9IDEuMiwgDQogICAgICAgICAgICBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgZXN0aWxvaCArDQogIGxhYnModGl0bGUgPSAiUHJvbWVkaW8gZGUgUHVudGFqZXMgZGUgRXN0csOpcyBwb3IgR8OpbmVybyIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLCANCiAgICAgICBjYXB0aW9uID0gZnVlbnRlLA0KICAgICAgIGZpbGwgPSAiSWRlbnRpZGFkIGRlIEfDqW5lcm8iKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG9yZXMpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQoNCmVzdHJlc19nZW5lcm8gPC0gYnVybiAlPiUgDQogIGZpbHRlcihnZW5lcm8gJWluJSBjKCJNdWplciBjaXMiLCAiSG9tYnJlIGNpcyIpKSAlPiUgDQogIGdyb3VwX2J5KGdlbmVybykgJT4lIA0KICBzdW1tYXJpc2UoZXN0cmVzX3Byb20gPSBtZWFuKGVzdHJlcykpICU+JQ0KICB1bmdyb3VwKCkNCmBgYA0KDQpgYGB7cn0NCmJ1cm4gJT4lIA0KICBmaWx0ZXIoZ2VuZXJvICVpbiUgYygiTXVqZXIgY2lzIiwgIkhvbWJyZSBjaXMiKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBnZW5lcm8sIHkgPSBlc3RyZXMsIGNvbG9yID0gZ2VuZXJvKSkgKw0KICBnZW9tX3Zpb2xpbigpKw0KICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gMC4xNSksIGFscGhhID0gMC40LCBzaXplID0gNCkgKw0KICBlc3RpbG9oICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGRlIFB1bnRhamVzIGRlIEVzdHLDqXMgcG9yIEfDqW5lcm8iLA0KICAgICAgIHggPSBOVUxMLCB5ID0gTlVMTCwgDQogICAgICAgY2FwdGlvbiA9IGZ1ZW50ZSwNCiAgICAgICBjb2xvciA9ICJJZGVudGlkYWQgZGUgR8OpbmVybyIpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9yZXMpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQpgYGANCg0KRW4gcHJvbWVkaW8sIGVsIHB1bnRhamUgZGUgZXN0csOpcyBkZSBsYXMgbXVqZXJlcyBlcyBgciByb3VuZChwdWxsKGVzdHJlc19nZW5lcm9bMiwyXSkgLSBwdWxsKGVzdHJlc19nZW5lcm9bMSwyXSksMSlgIHB1bnRvcyBtw6FzIGFsdG8gcXVlIGVuIGVsIGNhc28gZGUgbG9zIHZhcm9uZXMuIExhIG1heW9yIGNvbmNlbnRyYWNpw7NuIGRlIHJlc3B1ZXN0YXMgbGFzIHRlbmVtb3MgZW50cmUgbG9zIDUgeSA3LjUgcHVudG9zLg0KDQojIyMgQ29tcGFyYWNpw7NuIHBvciBydWJyb3MNCg0KUG9yIMO6bHRpbW8sIHZlcmVtb3MgbG9zIHJlc3VsdGFkb3MgcHJvbWVkaW9zIHBvciBpbmR1c3RyaWEuIA0KDQpgYGB7cn0NCmJ1cm4gJT4lIA0KICBmaWx0ZXIocnVicm8gJWluJSBjKCJUZWNub2xvZ8OtYXMgZGUgaW5mb3JtYWNpw7NuIiwgIlNlcnZpY2lvcyBkZSBzYWx1ZCIsDQogICAgICAgICAgICAgICAgICAgICAgIkNvbWVyY2lvIiwgIk90cm9zIiwgIkFsaW1lbnRhY2nDs24sIGJlYmlkYXMiLA0KICAgICAgICAgICAgICAgICAgICAgICJJbmR1c3RyaWEgbWV0YWzDunJnaWNhLCBtZXRhbG1lY8OhbmljYSIsDQogICAgICAgICAgICAgICAgICAgICAgIlBldHLDs2xlbyB5IHByb2R1Y2Npw7NuIGRlIGdhcywgcmVmaW5hY2nDs24gZGUgcGV0csOzbGVvIiwNCiAgICAgICAgICAgICAgICAgICAgICAiU2VydmljaW9zIGRlIGNvbnN1bHRvcsOtYSIsICJTZXJ2aWNpb3MgcHJvZmVzaW9uYWxlcyIsDQogICAgICAgICAgICAgICAgICAgICAgIkNvbnN0cnVjY2nDs24iLCAiU2VydmljaW9zIGZpbmFuY2llcm9zIHNlZ3Vyb3MiKSkgJT4lIA0KICBtdXRhdGUocnVicm8gPSBzdHJfd3JhcChydWJybywgd2lkdGggPSAzMCkpICU+JSANCiAgZ3JvdXBfYnkocnVicm8pICU+JSANCiAgc3VtbWFyaXNlKGVzdHJlc19wcm9tID0gbWVhbihlc3RyZXMpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGVzdHJlc19wcm9tLCB5ID0gcmVvcmRlcihydWJybywgZXN0cmVzX3Byb20pKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSA0LCBjb2xvciA9IGF6dWwpICsNCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMCwgeGVuZCA9IGVzdHJlc19wcm9tLCANCiAgICAgICAgICAgICAgICAgICB5ID0gcnVicm8sIHllbmQgPSBydWJybyksDQogICAgICAgICAgICAgICBjb2xvciA9IGF6dWwpICsNCiAgZXN0aWxvdiArDQogIGxhYnModGl0bGUgPSAiTml2ZWwgUHJvbWVkaW8gZGUgRXN0csOpcyBwb3IgSW5kdXN0cmlhIiwNCiAgICAgICBjYXB0aW9uID0gZnVlbnRlLCANCiAgICAgICB4ID0gTlVMTCwgeSA9TlVMTCkNCiAgDQpgYGANCg0KDQojIyMgQ29uY2x1c2nDs24NCg0KRW4gbMOtbmVhcyBnZW5lcmFsZXMgYXByZWNpYW1vcyBxdWUgbG9zIG5pdmVsZXMgZGUgZXN0csOpcyBkZSBsYXMgcGVyc29uYXMgcXVlIHRyYWJhamFuIGVuIFJSSEggZXMgYWx0bywgeSBxdWUgbGFzIHByaW5jaXBhbGVzIHJhem9uZXMgc2UgZGViZW4gYSBsYSBzb2JyZWNhcmdhIGRlIHRyYWJham8geSBsYSBjYW50aWRhZCBkZSB0YXJlYXMgcXVlIGRlYmVtb3MgYXRlbmRlciBkZXNkZSBlbCBzZWN0b3IgKHkgZW4gb2Nhc2lvbmVzIGNvbiBtZW5vcyByZWN1cnNvcyBkZSBsb3MgcXVlIGRlYmVyw61hbW9zIHRlbmVyKS4NCg0KVW4gYXNwZWN0byBwb3NpdGl2byBlcyBxdWUgZW4gY29tcGFyYWNpw7NuIGNvbiBlbCAyMDIxLCBtYXlvcm1lbnRlIGxvcyBuaXZlbGVzIGRlIGVzdHLDqXMgc29uIG3DoXMgYmFqb3MuIFByb2JhYmxlbWVudGUgcG9kYW1vcyBhdHJpYnVpciBlc2UgcmVzdWx0YWRvIGEgbGEgc2FsaWRhIGRlIGxhcyBjdWFyZW50ZW5hcyBlc3RyaWN0YXMgeSBhbCByZWdyZXNvIGEgdW5hIHZpZGEgbcOhcyBvIG1lbm9zIHNpbWlsYXIgYSBsYSBxdWUgdGVuw61hbW9zIGFudGVzIGRlIGxhIHBhbmRlbWlhLg0KDQpEZSB0b2RhcyBtYW5lcmFzIGVzdGUgZXMgdW4gdGVtYSBxdWUgbWVyZWNlIHVuIGVzdHVkaW8gbcOhcyBhIGZvbmRvIGhlY2hvIHBvciBwZXJzb25hcyBtw6FzIGlkw7NuZWFzIHF1ZSBub3NvdHJvcy4gU2kgdGUgc2VudMOtcyBhYnJ1bWFkYSBvIGFicnVtYWRvLCBhbmltYXRlIGEgcGVkaXIgYXl1ZGEgeSBhIGhhYmxhciBjb24gYWxndWllbiBkZSBjb25maWFuemEuIExvIHBlb3IgZGVsIGVzdHLDqXMgZXMgbGEgc2Vuc2FjacOzbiBkZSBzb2xlZGFkLg0KDQojIyBDb211bmlkYWRlcw0KDQpSNEhSIGVzIHVuYSBjb211bmlkYWQgYWJpZXJ0YSB5IGdyYXR1aXRhLiDCv1F1w6kgcXVpZXJlIGRlY2lyIGVzdG8/IFF1ZSBlcyBlcyB1biBlc3BhY2lvIGRvbmRlIGN1YWxxdWllciBwZXJzb25hIHB1ZWRlIHBhcnRpY2lwYXIgZGUgbGEgY29tdW5pZGFkLCBzZXBhIGRlIFIgbyBubyBzZXBhIG5hZGEsIHkgYWRlbcOhcyBubyBoYXkgcXVlIHBhZ2FyIG5hZGEgcG9yIGZvcm1hciBwYXJ0ZS4gVGFtYmnDqW4gZXMgdW4gZXNwYWNpbyBzZWd1cm8gZW4gZWwgcXVlIGN1aWRhbW9zIHF1ZSBoYXlhIGFjb3NvLCBpbnN1bHRvcyBvIGFidXNvcy4NCg0KTGFzIGNvbXVuaWRhZGVzIHNvbiB1bmEgZ3JhbiBmb3JtYSBkZSBjb25zdHJ1aXIgY29ub2NpbWllbnRvLCBkZSBhcHJlbmRlciwgZGUgZ2VuZXJhciByZWxhY2lvbmVzLCBwYXJhIHJlc29sdmVyIGNvbnN1bHRhcywgeSB0YW1iacOpbiwgcG9yIHF1w6kgbm8sIGRlIGhhY2VyIGJ1ZW5vcyBhbWlnb3MuIEFzw60gcXVlIGVuIGVzdGEgc2VjY2nDs24gbm9zIHByb3BvbmVtb3MgdmVyIGN1w6FsZXMgc29uIGxhcyBjb211bmlkYWRlcyBtw6FzIGZyZWN1ZW50YWRhcyBwb3IgbGFzIHBlcnNvbmFzIHF1ZSBwYXJ0aWNpcGFyb24gZGUgbGEgRW5jdWVzdGEuDQoNCmBgYHtyIGNvbXVuaWRhZH0NCmNvbXVuaWRhZCA8LSByaDIyICU+JSANCiAgc2VsZWN0KHBhaXMsIHByb3ZpbmNpYSwgY29tdW5pZGFkLCBjb211bmlkYWRlcykNCg0KZGl2IDwtIGNvbXVuaWRhZCAlPiUgDQogIHNlbGVjdChjb211bmlkYWQpICU+JSANCiAgZmlsdGVyKCFpcy5uYShjb211bmlkYWQpKSAlPiUgDQogIGdyb3VwX2J5KGNvbXVuaWRhZCkgJT4lIA0KICBzdW1tYXJpc2UgKG4gPSBuKCkpICU+JSANCiAgbXV0YXRlKGZyZXEgPSBuL3N1bShuKSkgJT4lIA0KICBhcnJhbmdlKC1uKQ0KDQojIENvbXB1dGUgdGhlIGN1bXVsYXRpdmUgcGVyY2VudGFnZXMgKHRvcCBvZiBlYWNoIHJlY3RhbmdsZSkNCmRpdiR5bWF4IDwtIGN1bXN1bShkaXYkZnJlcSkNCg0KIyBDb21wdXRlIHRoZSBib3R0b20gb2YgZWFjaCByZWN0YW5nbGUNCmRpdiR5bWluIDwtIGMoMCwgaGVhZChkaXYkeW1heCwgbj0tMSkpDQoNCiMgQ29tcHV0ZSBsYWJlbCBwb3NpdGlvbg0KZGl2JGxhYmVsUG9zaXRpb24gPC0gKGRpdiR5bWF4ICsgZGl2JHltaW4pIC8gMg0KDQojIENvbXB1dGUgYSBnb29kIGxhYmVsDQpkaXYkbGFiZWwgPC0gcGFzdGUwKGRpdiRjb211bmlkYWQsICJcbiBDYW50OiAiLCBkaXYkbikNCg0KIyBNYWtlIHRoZSBwbG90DQpnZ3Bsb3QoZGl2LCBhZXMoeW1heD15bWF4LCB5bWluPXltaW4sIHhtYXg9NCwgeG1pbj0zLCBmaWxsPWNvbXVuaWRhZCkpICsNCiAgZ2VvbV9yZWN0KCkgKw0KICBjb29yZF9wb2xhcih0aGV0YT0ieSIpICsgIyBUcnkgdG8gcmVtb3ZlIHRoYXQgdG8gdW5kZXJzdGFuZCBob3cgdGhlIGNoYXJ0IGlzIGJ1aWx0IGluaXRpYWxseQ0KICB4bGltKGMoMiwgNCkpICsjIFRyeSB0byByZW1vdmUgdGhhdCB0byBzZWUgaG93IHRvIG1ha2UgYSBwaWUgY2hhcnQNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhncmlzLCBhenVsKSkgKw0KICB0aGVtZV92b2lkKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwNCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGxvdC50aXRsZS5wb3NpdGlvbiA9ICJwbG90IiwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiUm9ib3RvIikpICsNCiAgbGFicyh0aXRsZSA9ICJQYXJ0aWNpcMOhcyBkZSBBbGd1bmEgQ29tdW5pZGFkIiwNCiAgICAgICBmaWxsID0gIlJlc3B1ZXN0YSIsIA0KICAgICAgIGNhcHRpb24gPSBmdWVudGUpDQpgYGANCg0KRGVsIHRvdGFsIGRlIHJlc3B1ZXN0YXMsIGByIHBlcmNlbnQocHVsbChkaXZbMiwzXSkpYCAoYHIgcHVsbChkaXZbMiwyXSlgKSBwYXJ0aWNpcGFuIGRlIGFsZ3VuYSBjb211bmlkYWQuIEVzdGFzIHNvbiBsYXMgY29tdW5pZGFkZXMgbWVuY2lvbmFkYXMuDQoNCkVuIGxhIHRhYmxhIGEgY29udGludWFjacOzbiBwb25lbW9zIHRvZGFzIGxhcyBjb211bmlkYWRlcyBxdWUgbm9zIG5vbWJyYXJvbi4gTm8gcG9uZW1vcyBsYSBjYW50aWRhZCBkZSByZXNwdWVzdGFzIHF1ZSBvYnR1dm8gY2FkYSB1bmEgcG9ycXVlIG5vIGVzIHVuYSBjb21wZXRlbmNpYS4gDQoNCj4gVGVuw6kgZW4gY3VlbnRhIGxvIHNpZ3VpZW50ZTogUGFyYSBjcmVhciB1bmEgY29tdW5pZGFkIHPDs2xvIGhhY2UgZmFsdGEgdGVuZXIgZ2FuYXMgZGUgaGFjZXJsby4gTG8gbWVqb3IgZGUgbGFzIGNvbXVuaWRhZGVzIGVzIHF1ZSBoYXkgbXVjaGEgZ2VudGUgZGlzcHVlc3RhIGEgY29tcGFydGlyLg0KDQpgYGB7ciBjb211bmlkYWRlc30NCmNvbXVuaWRhZCA8LSBjb211bmlkYWQgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKGNvbXVuaWRhZGVzKSwgDQogICAgICAgICBjb211bmlkYWQgPT0gIlNpIikgJT4lIA0KICBzZWxlY3QocGFpcywgY29tdW5pZGFkZXMpDQoNCmNvbXVuaWRhZCA8LSBjb211bmlkYWQgJT4lIA0KICBtdXRhdGUoY29tdW5pZGFkZXMgPSBzdHJfcmVwbGFjZShjb211bmlkYWRlcywgIndoYXRzIGFwcHxXaGF0c2FwcHxXc2FwcHx3c3B8d2hhdHNhcHAiLCAiV2hhdHNBcHAiKSwNCiAgICAgICAgIGNvbXVuaWRhZGVzID0gc3RyX3JlcGxhY2UoY29tdW5pZGFkZXMsICJBZHJoYXxBZGhyYXxBREhSQSIsICJBRFJIQSIpLA0KICAgICAgICAgY29tdW5pZGFkZXMgPSBzdHJfcmVwbGFjZShjb211bmlkYWRlcywgIkRhdGEgNCBocnxEYXRhNGhyfERBVEE0SFIiLCAiRGF0YSA0SFIiKSwNCiAgICAgICAgIGNvbXVuaWRhZGVzID0gc3RyX3JlcGxhY2UoY29tdW5pZGFkZXMsICJCZW5jaC5DbHVifEJlbmNoY2x1YnxCZW5jaCIsICJCZW5jaCBDbHViIiksDQogICAgICAgICBjb211bmlkYWRlcyA9IHN0cl9yZXBsYWNlKGNvbXVuaWRhZGVzLCAiQXByaG5vYSIsICJBUFJITk9BIiksDQogICAgICAgICBjb211bmlkYWRlcyA9IHN0cl9yZXBsYWNlKGNvbXVuaWRhZGVzLCAiQmVuY2ggQ2x1YkNsdWIiLCAiQmVuY2ggQ2x1YiIpLA0KICAgICAgICAgY29tdW5pZGFkZXMgPSBzdHJfcmVwbGFjZShjb211bmlkYWRlcywgIkFwYXJoIiwgIkFQQVJIIiksDQogICAgICAgICBjb211bmlkYWRlcyA9IHN0cl9yZXBsYWNlKGNvbXVuaWRhZGVzLCAic2xhY2sgdGVjaCByZWNydWl0ZXJzIGFyZ3x0ZWNoLnJlY3J1aXRlcnMuYXJnfFRlY2ggUmVjcnVpdGVyIiwgIlRlY2ggUmVjcnVpdGVycyBBcmciKSwNCiAgICAgICAgIGNvbXVuaWRhZGVzID0gc3RyX3JlcGxhY2UoY29tdW5pZGFkZXMsICJMaW5rZElufExpbmtlZGluIiwgIkxpbmtlZEluIiksDQogICAgICAgICBjb211bmlkYWRlcyA9IHN0cl9yZXBsYWNlKGNvbXVuaWRhZGVzLCAiVWJhIiwgIlVCQSIpLA0KICAgICAgICAgY29tdW5pZGFkZXMgPSBzdHJfcmVwbGFjZShjb211bmlkYWRlcywgIkludGVyZW1wcmVzYSBDb3Jkb2JhfFJlY3Vyc29zIEh1bWFub3MgSW50ZXIgRW1wcmVzYXMgQ0JBIiwgIlJSSEggSW50ZXJlbXByZXNhcyIpLA0KICAgICAgICAgY29tdW5pZGFkZXMgPSBzdHJfcmVwbGFjZShjb211bmlkYWRlcywgImdydXBvIiwgIkdydXBvIiksDQogICAgICAgICBjb211bmlkYWRlcyA9IHN0cl9yZXBsYWNlKGNvbXVuaWRhZGVzLCAiQ2FwaXRhbCBodW1hbm8gVGFsZW50byBmZW1lbmlubyIsICJDYXBpdGFsIEh1bWFubyBUYWxlbnRvIEZlbWVuaW5vIiksDQogICAgICAgICBjb211bmlkYWRlcyA9IHN0cl9yZXBsYWNlKGNvbXVuaWRhZGVzLCAiVGVuZGVuY2lhIGRlIFJlY3Vyc29zIEh1bWFub3MgQm9saXZpYSIsICJUZW5kZW5jaWFzIGVuIFJlY3Vyc29zIEh1bWFub3MgQm9saXZpYSIpLA0KICAgICAgICAgY29tdW5pZGFkZXMgPSBzdHJfcmVwbGFjZShjb211bmlkYWRlcywgIlBBUyIsICJQZW9wbGUgQW5hbHl0aWNzIFNwYWluIiksDQogICAgICAgICBjb211bmlkYWRlcyA9IHN0cl9yZXBsYWNlKGNvbXVuaWRhZGVzLCAiR3J1cG9zIGRlIFdoYXRzYXBwIiwgIkdydXBvcyBkZSBXaGF0c0FwcCIpLA0KICAgICAgICAgY29tdW5pZGFkZXMgPSBzdHJfcmVwbGFjZShjb211bmlkYWRlcywgIkdydXBvcyBXaGF0c2FwcCIsICJHcnVwb3MgZGUgV2hhdHNBcHAiKSkgDQoNCiMgUmVlbXBsYXpvIG1hbnVhbCBkZSBjb211bmlkYWRlcw0KY29tdW5pZGFkWzIsMl0gPC0gIkdydXBvcyBkZSBXaGF0c0FwcCwgQURSSEEiDQpjb211bmlkYWRbNiwyXSA8LSAiQmVuY2ggQ2x1YiwgQURSSEEiDQpjb211bmlkYWRbNywyXSA8LSAiR3J1cG9zIGRlIFdoYXRzQXBwIg0KY29tdW5pZGFkWzksMl0gPC0gIkdydXBvcyBlbiBMaW5rZWRJbiwgR3J1cG9zIGRlIFdoYXRzQXBwIg0KY29tdW5pZGFkWzEyLDJdIDwtICJHcnVwb3MgZGUgV2hhdHNBcHAiDQpjb211bmlkYWRbMTMsMl0gPC0gIkdydXBvIGRlIFdoYXRzQXBwIEPDs3Jkb2JhIg0KY29tdW5pZGFkWzE0LDJdIDwtICJDbHViIGRlIFIgcGFyYSBSSCwgR3J1cG8gZGUgV2hhdHNBcHAgQ8OzcmRvYmEiDQpjb211bmlkYWRbMTcsMl0gPC0gIkNsdWIgZGUgUiBwYXJhIFJIIg0KY29tdW5pZGFkWzIxLDJdIDwtICJHcnVwb3MgZGUgV2hhdHNBcHAsIEdydXBvIExvY2FsLCBMaW5rZWRJbiINCmNvbXVuaWRhZFsyMiwyXSA8LSAiR3J1cG9zIGRlIExpbmtlZEluIg0KY29tdW5pZGFkWzI1LDJdIDwtICJHcnVwb3MgZGUgV2hhdHNBcHAsIExpbmtlZEluIg0KY29tdW5pZGFkWzI4LDJdIDwtICJJbnN0YWdyYW0sIEdydXBvcyBkZSBXaGF0c0FwcCINCmNvbXVuaWRhZFsyOSwyXSA8LSAiQURSSEEsIENvbXVuaWRhZCBIUiINCmNvbXVuaWRhZFs0MiwyXSA8LSAiQURSSEEsIExpbmtlZEluIg0KY29tdW5pZGFkWzQ4LDJdIDwtICJUZW5kZW5jaWFzIGVuIFJlY3Vyc29zIEh1bWFub3MgQm9saXZpYSwgQVNPQk9HSCINCmNvbXVuaWRhZFs1MywyXSA8LSAiQ29tdW5pZGFkIEhSLCBHcnVwb3MgZGUgZGlmZXJlbnRlcyBVbml2ZXJzaWRhZGVzIg0KY29tdW5pZGFkWzU5LDJdIDwtICJHcnVwb3MgZGUgV2hhdHNhcHAsIExpbmtlZEluIg0KY29tdW5pZGFkWzY0LDJdIDwtICJSZWQgZGUgUlJISCwgR3J1cG8gZGUgV2hhdHNBcHAgTWFyIGRlbCBQbGF0YSINCmNvbXVuaWRhZFs2OSwyXSA8LSAiR3J1cG8gZGUgQ29sZWdhcyBSUkhIIChDb25zdWx0b3JhIE1KRykgQnVlbm9zIEFpcmVzIHkgTGF0aW5vYW1lcmljYSINCmNvbXVuaWRhZFs3MCwyXSA8LSAiQURSSEEsIEdydXBvcyBSZWdpb25hbGVzIg0KY29tdW5pZGFkWzczLDJdIDwtICJDbHViIGRlIFIgcGFyYSBSSCwgRGF0YSA0SFIsIFJSSEggSW50ZXJlbXByZXNhcywgUmVjbHV0YWRvcmVzIENCQSINCmNvbXVuaWRhZFs4MCwyXSA8LSAiQ29tcGVuc2FjaW9uZXMsIEJlbmNoIENsdWIiDQpjb211bmlkYWRbODMsMl0gPC0gIlRvdGFsIFJld2FyZHMgQ29tcGVuc2FjaW9uZXMiDQoNCiMgU2VwYXJhbW9zIGxhcyBjb211bmlkYWRlcyBlbiBjb2x1bW5hcyB5IGx1ZWdvIHBpdm90ZWFtb3MgcGFyYSBhZ3J1cGFybGFzDQpjb211bmlkYWQgJT4lIA0KICBzZXBhcmF0ZShjb2wgPSBjb211bmlkYWRlcywgaW50byA9IGMoImMxIiwgImMyIiwgImMzIiwgImM0IiksIA0KICAgICAgICAgICBzZXAgPSAiLCIsIGZpbGwgPSAicmlnaHQiLCByZW1vdmUgPSBUUlVFKSAlPiUgDQogIG11dGF0ZShhY3Jvc3MoYygiYzEiLCAiYzIiLCAiYzMiLCAiYzQiKSwgc3RyX3RyaW0pKSAlPiUgDQogIHBpdm90X2xvbmdlcihjb2xzID0gYyhjMTpjNCksDQogICAgbmFtZXNfdG8gPSAiY29sdW1uYSIsDQogICAgdmFsdWVzX3RvID0gImNvbXVuaWRhZCIpICU+JSANCiAgZmlsdGVyKCFpcy5uYShjb211bmlkYWQpKSAlPiUgDQogIGZpbHRlcihjb211bmlkYWQgIT0gImV0YyIpICU+JSANCiAgZ3JvdXBfYnkocGFpcywgY29tdW5pZGFkKSAlPiUgDQogIHRhbGx5KCkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBzZWxlY3QoLW4pICU+JSANCiAgcmVuYW1lKCJQYcOtcyIgPSBwYWlzLA0KICAgICAgICAgIkNvbXVuaWRhZCIgPSBjb211bmlkYWQpICU+JSANCiAga2FibGUoImh0bWwiLCBlc2NhcGU9RikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUUlVFLCANCiAgICAgICAgICAgICAgICBib290c3RyYXBfb3B0aW9ucyA9IA0KICAgICAgICAgICAgICAgICAgYygic3RyaXBlZCIsImhvdmVyIiwiY29uZGVuc2VkIiApKSAlPiUgDQogIHJvd19zcGVjKDAsIGJvbGQ9VCwgY29sb3I9IndoaXRlIiwgYmFja2dyb3VuZCA9IGF6dWwpDQpgYGANCg0K