Efectivos en las Comisarias del Perú
Pregunta: ¿los policías en el Perú están distribuidos
equitativamente entre las comisarías del Perú?
¿Cómo cree que es esta distribución de datos?
Para responder a esta pregunta se usa la base de datos de comisarías
del Perú de 2017. Esta base de datos está disponible en la sección Microdatos del
INEI.
library(rio)
comi17 = import("bases/comi2017.sav")
Esta base de datos incluye la pregunta sobre el número total de
efectivos en cada comisaría. Esta variable se importa en R como una
variable numérica, y efectivamente es el tipo de variable correcto.
class(comi17$INF110_TOT)
## [1] "numeric"
Como esta es una variable numérica, se puede describir mediante la
media y la mediana.
¿Qué nos indican estos resultados?
library(tidyverse)
comi17 %>%
summarise(Mínimo = min(INF110_TOT),
Mediana = median(INF110_TOT),
Promedio = mean(INF110_TOT),
Máximo = max(INF110_TOT))
## Mínimo Mediana Promedio Máximo
## 1 3 19 31.61538 259
Se puede graficar la distribución del número de efectivos por
comisarias mediante un histograma. ¿Qué nos indica el gráfico?
library(ggplot2)
ggplot(comi17, aes(x=INF110_TOT))+
geom_histogram()+
xlab("Número de efectivos") +
ylab("Frecuencia")+
theme_light()
## `stat_bin()` using `bins = 30`.
## Pick better value with
## `binwidth`.
Se puede incluir el dato de la media y la mediana en este gráfico.
¿Cómo se interpreta la posición relativa de ambas medidas?
ggplot(comi17, aes(x=INF110_TOT))+
geom_histogram()+
geom_vline(xintercept = 19, color = "red")+
geom_vline(xintercept = 31.6, color = "green")+
xlab("Número de efectivos") +
ylab("Frecuencia")+
theme_light()
## `stat_bin()` using `bins = 30`.
## Pick better value with
## `binwidth`.
Ahora se quiere ver si existen diferencias en el número promedio de
efectivos policiales en las comisarías del Perú entre departamentos o
entre regiones. A pesar que en formulario se recoge el dato de
Departamento, Provincia y Distrito, en la base de datos no se cuenta con
esa información. Lo que se tiene es una variable llamada “ubigeo”. Esta
variable está estandarizada de tal manera que los dos primeros dígitos
corresponden al departamento, los segundos dos dígitos a las provincias
y los últimos dos dígitos al distrito. Por lo tanto, para saber en qué
departamento está la comisaría se requiere separar los primeros dos
dígitos y guardarlos en una nueva variable.
comi17 = comi17 %>%
mutate(dpto = str_sub(UBIGEO, 1, 2))
Copiamos el código usado para el voto 2016 y lo adaptamos a las
necesidades de esta base de datos. La variable “dpto” es una variable de
tipo “character” y sabemos que va desde el “01” al “25”, representando
cada “número” un departamento del Perú, que hemos asociado a Costa = 1,
Sierra = 2 o Selva = 3.
Entonces lo que tenemos que hallar es el código ubigeo de cada
departamento y reemplazarlo por el nombre del departamento en el código
original. La clasificación la guardamos en otra variable “region”.
comi17 = comi17 %>%
mutate(region = case_when(
dpto=="01"~3,
dpto=="02"~2,
dpto=="03"~2,
dpto=="04"~2,
dpto=="05"~2,
dpto=="06"~2,
dpto=="08"~2,
dpto=="07"~1,
dpto=="09"~2,
dpto=="10"~3,
dpto=="11"~1,
dpto=="12"~2,
dpto=="13"~1,
dpto=="14"~1,
dpto=="15"~1,
dpto=="16"~3,
dpto=="17"~3,
dpto=="18"~1,
dpto=="19"~2,
dpto=="20"~1,
dpto=="21"~2,
dpto=="22"~3,
dpto=="23"~1,
dpto=="24"~1,
dpto=="25"~3
))
Esta variable “region” es de tipo numérico, pero los códigos (1, 2 y
3) no son números, sino códigos para Costa, Sierra y Selva, por lo que
tenemos que crear otra variable, “region2” que sea de tipo “factor” con
las etiquetas correspondientes.
library(forcats)
comi17 = comi17 %>%
mutate(region2 = factor(region, labels=c("Costa", "Sierra", "Selva")))
Podemos usar esta variable para calcular los descriptivos del número
de efectivos por región. ¿Qué conclusión saca de la tabla?
tabla1 = comi17 %>%
group_by(region2) %>%
summarise(Mínimo = min(INF110_TOT),
Mediana = median(INF110_TOT),
Promedio = mean(INF110_TOT),
Desv = sd(INF110_TOT),
Máximo = max(INF110_TOT))
tabla1
## # A tibble: 3 × 6
## region2 Mínimo Mediana Promedio Desv Máximo
## <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Costa 4 28 44.3 38.3 259
## 2 Sierra 3 16 24.2 24.8 190
## 3 Selva 4 16 24.0 26.5 165
Esta tabla sirve para comparar los datos descriptivos por grupos de
otra variable. Algo similar se puede hacer con el gráfico de cajas, pero
comparando medianas y rangos intercuartiles.
ggplot(comi17, aes(y=INF110_TOT, x=region2))+
geom_boxplot()+
ylab("Número de efectivos")+
xlab("Región")+
theme_get()
Servicios básicos en las comisarías del Perú
Pregunta: ¿Las comisarías del Perú cuentan con servicios
básicos?
Para responder estas preguntas, la Encuesta Nacional de Comisarías de
2017 tiene otro módulo sobre infraestructura. Cargamos esa base de
datos.
library(rio)
comi17_2 = import("bases/comi2017_2.sav")
Esta base incluye la pregunta INF216 sobre luz eléctrica, la pregunta
INF225 sobre agua potable, la pregunta INF230 sobre desagüe y la
pregunta INF264_E sobre el servicio de internet.
En primer lugar verificamos cómo se importan las variables. Vemos que
se importan como variables numéricas. La variable sobre luz tiene
opciones Si = 1 y No = 2. Esta variable es en realidad una de tipo
factor.
class(comi17_2$INF216)
## [1] "numeric"
table(comi17_2$INF216)
##
## 1 2
## 1485 9
Se procede a crear otra variable “luz”, como la factorización de
INF216 con etiquetas Sí y No.
library(tidyverse)
comi17_2 = comi17_2 %>%
mutate(luz = factor(INF216, labels=c("Sí", "No")))
Esta variable incluye algunas comisarías donde no se tiene el dato,
por lo que cuando se calcula la tabla, se filtra solo las respuestas Sí
y No. Se guarda los resultados en un objeto “tabla2”.
tabla2 = comi17_2 %>%
filter(luz == "Sí" | luz == "No") %>%
count(Luz = luz, name="Frecuencia")
tabla2
## Luz Frecuencia
## 1 Sí 1485
## 2 No 9
Se añade a este mismo objeto los porcentajes. ¿Qué conclusiones saca
de estos resultados?
tabla2 = tabla2 %>%
mutate(Porcentaje = (Frecuencia / sum(Frecuencia)*100 ))
tabla2
## Luz Frecuencia Porcentaje
## 1 Sí 1485 99.3975904
## 2 No 9 0.6024096
Se hace el mismo procedimiento con la variable sobre agua potable. En
este caso, la variable tiene cinco valores.
class(comi17_2$INF225)
## [1] "numeric"
table(comi17_2$INF225)
##
## 1 3 4 5 6
## 1424 28 30 12 1
comi17_2 = comi17_2 %>%
mutate(agua = factor(INF225, labels=c("Red pública dentro del local",
"Camión cisterna",
"Pozo",
"Río, acequia o manantial",
"Otro")))
table(comi17_2$agua)
##
## Red pública dentro del local Camión cisterna
## 1424 28
## Pozo Río, acequia o manantial
## 30 12
## Otro
## 1
Se calcula la tabla de distribución de frecuencias, con el cálculo de
los porcentajes en el mismo código. ¿Qué conclusiones saca de estos
resultados?
tabla3 = comi17_2 %>%
count(Agua = agua, name="Frecuencia") %>%
mutate(Porcentaje = (Frecuencia / sum(Frecuencia)*100 ))
tabla3
## Agua Frecuencia Porcentaje
## 1 Red pública dentro del local 1424 95.25083612
## 2 Camión cisterna 28 1.87290970
## 3 Pozo 30 2.00668896
## 4 Río, acequia o manantial 12 0.80267559
## 5 Otro 1 0.06688963
¿Qué conclusiones saca de estos resultados?
Finalmente, se hace lo mismo para la pregunta sobre internet.
class(comi17_2$INF264_E)
## [1] "numeric"
table(comi17_2$INF264_E)
##
## 1 2 3 4
## 127 950 132 286
comi17_2 = comi17_2 %>%
mutate(internet = factor(INF264_E, labels=c("Sí, pago pendiente",
"Sí, pago al día",
"Sí, no sabe del pago",
"No cuenta con el servicio")))
table(comi17_2$internet)
##
## Sí, pago pendiente Sí, pago al día Sí, no sabe del pago
## 127 950 132
## No cuenta con el servicio
## 286
¿Qué conclusiones saca sobre estos resultados?
tabla5 = comi17_2 %>%
count(Internet = internet, name="Frecuencia") %>%
mutate(Porcentaje = (Frecuencia / sum(Frecuencia)*100 ))
tabla5
## Internet Frecuencia Porcentaje
## 1 Sí, pago pendiente 127 8.494983
## 2 Sí, pago al día 950 63.545151
## 3 Sí, no sabe del pago 132 8.829431
## 4 No cuenta con el servicio 286 19.130435
Este tipo de variables, de tipo factor, se puede visualizar con
gráficos de barras.
graf1 = ggplot(tabla5, aes(x=Internet, y=Porcentaje))+
geom_bar(stat="identity")+
geom_text(aes(label=paste(round(Porcentaje, 1))), vjust=-1, size=3)+
labs(x="Internet", y="Porcentaje")+
theme_classic()
graf1
Tarea
Calcule las tablas de distribución de frecuencias de luz y de
internet por regiones. Grafique.
Pruebas de significancia
Es una de las técnicas más usadas para el análisis en ciencias
sociales. Sirve, por ejemplo, para comparar entre grupos:
Comparar la media de ingresos de hombres y mujeres
Comparar la proporción de personas que votarán a candidato X en
Lima y en Regiones
Comparar los ingresos de profesores en la gestión pública y en la
gestión privada
La idea es comparar las estimaciones puntuales entre ambos grupos y
también poder extrapolar estas diferencias a la población.
Vamos a comenzar por comparaciones entre solo 2 grupos (por el
momento), que corresponde a una variable binaria o dicotómica, como sexo
(hombres/mujeres), ámbito (urbano/rural), gestión educativa
(pública/privada).
Para mostrar un ejemplo, vamos a usar el trabajo de (Galarza, Kogan, and Yamada 2012) que evalúa la
discriminación en el mercado laborar entre hombres y mujeres. Estos
autores enviaron CVs con exactas cualificaciones a ofertas reales de
trabajo, variando solo el nombre del aplicante, con nombres de hombres y
mujeres. La variable de respuesta es la tasa de respuesta a estos CVs,
es decir, de cuántos CVs enviados se recibió una llamada para una
entrevista.
En cualquier prueba de significancia se tiene que presentar una
hipótesis nula, que generalmente es la hipótesis de no diferencias o de
no efectos. Este trabajo parte de una idea que existe una discriminación
de género en el mercado laboral, por lo que la hipótesis nula indicaría
lo contrario. En el caso de este trabajo se tendría:
H0: Tasa de respuesta a CVs de hombres = Tasa de respuesta a CVs de
mujeres
o lo que es lo mismo
H0: Tasa de respuesta a CVs de hombres - Tasa de respuesta a CVs de
mujeres = 0
En ese trabajo se presenta el siguiente cuadro de resultados:
En la muestra total de 2,228 CVs enviados, mitad de CVs con nombres
de hombres y la otra mitad con nombres de mujeres, todos con las mismas
cualificaciones, se tiene que la tasa de respuesta para los CVs de
hombres es 13.4% y para los CVs de mujeres es 11.1%.
De acuerdo a las estimaciones puntuales, efectivamente, los hombres
tienen una mayor tasa de respuesta a sus CVs que las mujeres, a iguales
cualificaciones. Esta conclusión, sin embargo, es solo para las 2,228
observaciones de la muestra. ¿Cómo extrapolar esta conclusión a la
población? ¿Toda diferencia puntual se validaría en la población?
Comparación de intervalos de confianza por grupos
Una primera forma “informal” para extrapolar las diferencias en las
estimaciones puntuales de la muestra a la población es construyendo los
intervalos de confianza para la media o para la proporción por cada uno
de los subgrupos.
En este caso, por ejemplo, significaría construir el IC de la tasa de
respuesta para hombre y mujeres.
Pregunta: ¿Se pueden construir los IC de cada grupo con los datos de
la tabla?
Cada IC sería una extrapolación del parámetro, es decir, el rango de
valores de la tasa de respuesta a los CVs de hombres para todo el
mercado laboral al 95% de confianza. Lo mismo para la tasa de respuesta
de las mujeres.
Una vez construidos los IC, se analiza si estos intervalos se cruzan
o no se cruzan. La regla de decisión “informal” es:
Si los IC de ambos grupos se cruzan, entonces no se puede afirmar
que el parámetro de un grupo sea mayor o menos que el parámetro del otro
grupo.
Si los IC de ambos grupos NO se cruzan, entonces se puede
afirmar, al 95% de confianza, que el parámetro de un grupo es
mayor/menor al parámetro del otro grupo.
Ejemplo 1 para una variable numérica: ENL
Pregunta: ¿existen diferencia en la cantidad de libros que leen
hombres y mujeres? ¿y entre diferentes niveles socioeconómicos?
La hipótesis cero sería:
Ho: Promedio de libros que lee un hombre = Promedio de libros que lee
una mujer.
library(rio)
enl = import("/Users/Arturo/Library/CloudStorage/GoogleDrive-arturo.maldonado@pucp.pe/My Drive/A Cursos/Estadistica_1/Data/ENL2022/ENL2022.sav")
library(tidyverse)
enl = enl %>%
mutate(sexo = factor(P209, labels=c("Hombre", "Mujer")))
enl = enl %>%
mutate(nse1 = factor(nse, labels=c("Rural", "Bajo", "Medio", "Alto")))
library(tidyverse)
enl = enl %>%
mutate(libros = P412_1 + P412_2)
enl %>%
summarize(mean(P412_1, na.rm=T),
mean(P412_2, na.rm=T),
mean(libros, na.rm=T))
## mean(P412_1, na.rm = T) mean(P412_2, na.rm = T) mean(libros, na.rm = T)
## 1 2.468012 1.376829 3.844841
tabla1 = enl %>%
group_by(sexo) %>%
summarize(media = mean(libros, na.rm=T),
mediana = median(libros, na.rm=T),
desviacion = sd(libros, na.rm=T))
tabla1
## # A tibble: 2 × 4
## sexo media mediana desviacion
## <fct> <dbl> <dbl> <dbl>
## 1 Hombre 3.93 3 5.65
## 2 Mujer 3.78 3 4.86
ggplot(enl, aes(y= libros, x= sexo))+
geom_boxplot()+
scale_y_continuous(limits = c(0, 20))+
ylab("Total libros leídos")+
xlab("Sexo")+
theme_get()
## Warning: Removed 25176 rows containing
## non-finite outside the scale
## range (`stat_boxplot()`).
El cálculo del intervalo de confianza de una media es:
\[
IC = \bar{X} \pm 1.96 * \frac{s} {\sqrt{n}}
\]
Para una comparación usando los intervalos de confianza, se puede
usar el comando ciMean
de la librería lsr
.
Este comando regresa el límite inferior y el límite superior del
intervalo de confianza. Por lo tanto, para guardar solo el mínimo se
tiene que especificar lsr::ciMean(P1_6, na.rm=T)[1]
y para
el máximo cambiaría a [2]
.
library(lsr)
tabla2 = enl %>%
summarise(media = mean(libros, na.rm=T),
desv = sd(libros, na.rm = T),
liminf = ciMean(libros, na.rm=T)[1],
limsup = ciMean(libros, na.rm=T)[2]
)
tabla2
## media desv liminf limsup
## 1 3.844841 5.22275 3.770435 3.919248
tabla2xsexo = enl %>%
group_by(sexo) %>%
summarise(media = mean(libros, na.rm=T),
desv = sd(libros, na.rm = T),
liminf = ciMean(libros, na.rm=T)[1],
limsup = ciMean(libros, na.rm=T)[2]
)
tabla2xsexo
## # A tibble: 2 × 5
## sexo media desv liminf limsup
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 Hombre 3.93 5.65 3.80 4.05
## 2 Mujer 3.78 4.86 3.69 3.87
El IC al 95% de confianza, el promedio de libros que lee un
hombre está en el siguiente intervalo \[3.80
- 4.05\]
El IC al 95% de confianza el libros que lee una mujer está en el
siguiente intervalo \[3.69 -
3.87\]
Como ambos intervalos SÍ se traslapan, entonces NO se puede afirmar
que esas diferencias se pueden extrapolar la población. NO se puede
afirmar que existan diferencias entre hombres y mujeres en el número de
libros que leen (sería un “empate técnico”).
Ejemplo 2 para una variable numérica: ENDO
Pregunta: ¿a cuántos alumnos en promedio atiende un profesor
peruano? ¿Existen diferencias de género?
Usando el ejemplo de la ENDO 2020, la hipótesis que se puede evaluar
es si los profesores atienden a diferente número de alumnos de acuerdo a
su sexo. Como vimos antes, las comparaciones puntuales sugieren
diferencias, donde los docentes hombres atienden a más alumnos que las
docentes mujeres.
La hipótesis cero sería:
Ho: Promedio de alumnos que acompaña un docente hombre = Promedio de
alumnos que acompaña una docente mujer.
library(rio)
endo2020 = import("bases/ENDO_REMOTO_2020.dta")
La variable P1_1 (sexo del docente) está definida originalmente como
una variable numérica (esto se puede comprobar con el código
str(endo2020$P1_1)
. Esta variable, sin embargo es de tipo
factor.
Se puede crear una nueva variable “sexo” con la variable transformada
y etiquetada.
library(dplyr)
library(tidyverse)
endo2020 = endo2020 %>%
mutate(sexo = factor(P1_1, labels=c("Hombre", "Mujer")))
endo2020 %>%
summarize(Media = mean(P1_6, na.rm = T),
Desv.Std = sd(P1_6, na.rm = T))
## Media Desv.Std
## 1 39.98644 50.76707
alumxsexo = endo2020 %>%
group_by(sexo) %>%
summarize(Media = mean(P1_6, na.rm = T),
Desv.Std = sd(P1_6, na.rm = T))
alumxsexo
## # A tibble: 3 × 3
## sexo Media Desv.Std
## <fct> <dbl> <dbl>
## 1 Hombre 52.2 60.4
## 2 Mujer 34.1 44.2
## 3 <NA> NaN NA
Se encuentra que los docentes hombres acompañan a 52 alumnos en
promedio, en comparación con las docentes mujeres que acompañan a 34
alumnos en promedio, es decir 18 alumnos menos en promedio.
Recordemos que el cálculo del intervalo de confianza de una media
es:
\[
IC = \bar{X} \pm 1.96 * \frac{s} {\sqrt{n}}
\]
Para una comparación usando los intervalos de confianza, se puede
usar el comando ciMean
de la librería lsr
.
Este comando regresa el límite inferior y el límite superior del
intervalo de confianza. Por lo tanto, para guardar solo el mínimo se
tiene que especificar lsr::ciMean(P1_6, na.rm=T)[1]
y para
el máximo cambiaría a [2]
.
library(lsr)
endo2020 %>%
summarise(media = mean(P1_6, na.rm=T),
desv = sd(P1_6, na.rm = T),
liminf = ciMean(P1_6, na.rm=T)[1],
limsup = ciMean(P1_6, na.rm=T)[2]
)
## media desv liminf limsup
## 1 39.98644 50.76707 39.26358 40.7093
alumxsexo = endo2020 %>%
group_by(sexo) %>%
summarise(media = mean(P1_6, na.rm=T),
desv = sd(P1_6, na.rm = T),
liminf = ciMean(P1_6, na.rm=T)[1],
limsup = ciMean(P1_6, na.rm=T)[2]
)
alumxsexo
## # A tibble: 3 × 5
## sexo media desv liminf limsup
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 Hombre 52.2 60.4 50.7 53.8
## 2 Mujer 34.1 44.2 33.3 34.8
## 3 <NA> NaN NA NA NA
El IC al 95% de confianza, el promedio de alumnos que acompañan
los docentes hombre está en el siguiente intervalo \[50.7 - 53.8\]
El IC al 95% de confianza el promedio de alumnos que acompañan
las docentes mujeres está en el siguiente intervalo \[33.3 - 34.8\]
Como ambos intervalos NO se traslapan (el mayor valor del segundo IC,
34.8 , es menor al mejor valor del primer IC, 50.7), entonces se puede
afirmar que esas diferencias se pueden extrapolar la población.
Si los IC se traslapan, entonces, no se puede afirmar que existan
diferencias en el número de alumnos que acompañan docentes hombres o
mujeres (sería un “empate técnico”).
Gráfico de IC para comparar medias
Se puede graficar ambos intervalos de confianza. Para hacer esto,
usaremos la tabla que guarda los datos de los intervalos de
confianza.
Esta tabla, sin embargo, tiene una fila de resultados para los
valores perdidos. Esta fila no tiene datos por graficar, por lo que
tenemos que eliminarla.
Los dataframes se organizan en filas y columnas. La table
“ci_alumxsexo” tiene 3 filas y 3 columnas. La tercera fila es la que no
tiene datos que graficar. Para eliminar se tiene que especificar la
tabla y con los brackets [filas, columnas]
definir los
datos a eliminar [-3, ]
. Se elimina con el signo “-” y como
no hay datos luego de la “,”, se indica que no se cambia ninguna
columna.
alumxsexo = alumxsexo[-3,]
alumxsexo
## # A tibble: 2 × 5
## sexo media desv liminf limsup
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 Hombre 52.2 60.4 50.7 53.8
## 2 Mujer 34.1 44.2 33.3 34.8
Esta tabla se puede usar para crear un gráfico que compare ambos IC
con la librería ggplot2
y con la geometría
geom_errorbar
. Se agrega geom_text
para
incluir el “texto” con los valores promedio de ambos grupos.
library(ggplot2)
graf1 = ggplot(alumxsexo, aes(x=sexo, y=media))+
geom_bar(stat="identity")+
geom_errorbar(aes(ymin=liminf, ymax=limsup), width=0.2)+
geom_text(aes(label=round(media, 1)), vjust=-1, size=4)+
xlab("Sexo del docente") + ylab("Promedio de alumnos")+
ylim(0, 60)
graf1
En este gráfico queda más claro que ambos IC no se traslapan por lo
que se puede decir que sí existen diferencias entre docentes hombre y
mujeres en el número de alumnos que acompañan en el Perú.
Este tipo de gráfico es bastante usual en los reportes estadísticos.
Por ejemplo, se pueden ver este tipo de gráficos en los reportes de El
Pulso de la Democracia del proyecto LAPOP. En el último reporte para
Perú se presenta el siguiente gráfico que muestra los niveles de
satisfacción con la democracia entre grupos de satisfacción con los
servicios públicos. Estos gráficos son construidos de la misma manera
que se ha construido el gráfico de arriba.
¿Por qué?. .. Aquí viene la interpretación del politólogo .
OJO: no se debe confundir este gráfico con un gráfico de cajas.
TAREA: Analizar si existen diferencias en el número de alumnos entre
docentes con diferentes condiciones laborales (P1_7).
Ejemplo 3 para una variable numérica: LAPOP
library(rio)
lapop = import("bases/PER_2023_LAPOP_AmericasBarometer_v1.0_w.sav")
Ejemplo para variable numérica con índice aditivo
El cuestionario de LAPOP incluye dos preguntas sobre las fuerzas del
orden. B12. ¿Hasta qué punto tiene usted confianza en las Fuerzas
Armadas? y B18. ¿Hasta qué punto tiene usted confianza en la policía
nacional?
Ambas preguntas están medidas en una escala de 1 a 7, donde 1
significa “Nada” y 7 significa “Mucho”. Una persona que tenga
desconfianza de las fuerzas del orden en general, seguramente reportará
puntajes bajos en ambas preguntas. Por el contrario, una persona que
tenga alta confianza en las fuerzas del orden en general, puede reportar
puntajes altos en ambas preguntas.
Se pueden combinar ambas preguntas para generar un índice aditivo de
confianza general en las fuerzas del orden, como la suma de ambas. Como
cada pregunta puede ser respondida entre 1 y 7, la suma puede variar
entre 2 y 14. Un puntaje de 2 expresará la más baja confianza en las
fuerzas del orden. Un puntaje de 14, la más alta confianza en las
fuerzas del orden. Cualquier puntaje intermedio, expresará una confianza
intermedia.
Como NO es intuitivo tener un índice que varíe entre 2 y 14, se puede
restar dos a la suma para que el índice varíe entre 0 y 12. Como esta
variación tampoco es intuitiva, se puede dividir todo entre 12 para que
el índice varíe entre 0 y 1.
Persona con mucha desconfianza en las fuerzas del orden |
1 |
1 |
2 |
0 |
0 |
0 |
Persona con mucha confianza en las fuerzas del orden |
7 |
7 |
14 |
12 |
1 |
100 |
Persona con confianza media en las fuerzas del orden |
4 |
5 |
9 |
7 |
0.58 |
58 |
Persona con confianza media en las fuerzas del orden |
6 |
4 |
10 |
8 |
0.66 |
66 |
De esta manera cada persona tiene un puntaje que puede variar entre 0
y 1, dependiendo de las respuestas que dio a cada una de las preguntas
individuales.
Esto se puede calcular en R.
library(tidyverse)
lapop = lapop %>%
mutate(indice = (b12+b18-2)/12*100)
Podemos asumir que este índice es una variable cuantitativa, por lo
que podemos calcular la media y el intervalo de confianza de la
media.
library(lsr)
lapop %>%
summarise(media = mean(indice, na.rm=T),
liminf = ciMean(indice, na.rm=T)[1],
limsup = ciMean(indice, na.rm=T)[2]
)
## media liminf limsup
## 1 47.81916 46.42952 49.2088
Mejor aún, podemos calcular el índice de confianza en las fuerzas del
orden por año de la encuesta.
indicexwave = lapop %>%
group_by(wave) %>%
summarise(media = mean(indice, na.rm=T),
liminf = ciMean(indice, na.rm=T)[1],
limsup = ciMean(indice, na.rm=T)[2]
)
indicexwave
## # A tibble: 1 × 4
## wave media liminf limsup
## <dbl> <dbl> <dbl> <dbl>
## 1 2023 47.8 46.4 49.2
Con lo que podemos comparar el índice de apoyo a las fuerzas del
orden por año para sacar conclusiones acerca de diferencias.
library(ggplot2)
graf3 = ggplot(indicexwave, aes(x=wave, y=media))+
geom_bar(stat="identity")+
geom_errorbar(aes(ymin=liminf, ymax=limsup), width=0.2)+
geom_text(aes(label=paste(round(media, 1))), vjust=-1, size=4)+
xlab("Año de encuestas") + ylab("Índice de confianza en las fuerzas del orden")+
ylim(0, 60)
graf3
Ejemplo 1 para una variable categórica: ENDO
Siguiendo con el ejemplo de la ENDO 2020, la hipótesis que se puede
evaluar es si existen diferencias en si los docentes han recibido apoyo
psicológico o emocional por sexo (P1_13).
La hipótesis cero sería: La proporción de docentes que han recibido
apoyo psicológico entre docentes hombres = Proporción de docentes que
han recibido apoyo psicológico entre docentes mujeres.
Lo primero es transformar la variable P1_13 que es importada como
numérica, como una variable de factor y con sus etiquetas.
endo2020 = endo2020 %>%
mutate(apoyo = factor(P1_13, labels=c("Sí", "No")))
Ahora tenemos que producir la tabla de distribución de frecuencias.
Si calculamos las frecuencias con count
directamente, esta
tabla incluiría una fila de los NAs y luego calculará los porcentajes
incluyendo a este grupo. Es por esto que antes de calcular las
frecuencias, tenemos que filtrar para que solo cuente los “Sí” y “No”.
Luego de las frecuencias, incluimos el porcentaje con
mutate
.
tabla = endo2020 %>%
filter(apoyo =="Sí" | apoyo == "No") %>%
count(Apoyo = apoyo, name="N") %>%
mutate(total = sum(N),
Porcentaje = N / total * 100)
tabla
## Apoyo N total Porcentaje
## 1 Sí 9476 18930 50.05811
## 2 No 9454 18930 49.94189
Por ejemplo, para hallar el IC de la proporción de aquellos docentes
que reportaron haber recibido apoyo psicológico, podemos usar el comando
prop.test
. Este comando requiere el n de la opción “Sí” de
la tabla y el total de casos. Por defecto nos calcula el IC al 95% de
confianza.
prop.test(9476,18930)
##
## 1-sample proportions test with continuity correction
##
## data: 9476 out of 18930, null probability 0.5
## X-squared = 0.023296, df = 1, p-value = 0.8787
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
## 0.4934326 0.5077293
## sample estimates:
## p
## 0.5005811
Se estima que el la proporción de docentes que recibieron apoyo
psicológico está entre 49.3% y 50.8%.
Luego, para responder a la pregunta de si esta proporción varía entre
docentes hombres y mujeres, tenemos que crear otra tabla con las
frecuencias y porcentajes por cada grupo de la variable “sexo”. Para
esto, al código anterior le agregamos el comando
group_by
.
tabla2 = endo2020 %>%
filter(apoyo =="Sí" | apoyo == "No") %>%
group_by(sexo) %>%
count(Apoyo = apoyo, name="N") %>%
mutate(total = sum(N),
Por = N / total * 100,
err = sqrt(Por*(100-Por)/N),
liminf = Por - 1.96*err,
limsup = Por + 1.96*err)
tabla2
## # A tibble: 4 × 8
## # Groups: sexo [2]
## sexo Apoyo N total Por err liminf limsup
## <fct> <fct> <int> <int> <dbl> <dbl> <dbl> <dbl>
## 1 Hombre Sí 2777 6163 45.1 0.944 43.2 46.9
## 2 Hombre No 3386 6163 54.9 0.855 53.3 56.6
## 3 Mujer Sí 6699 12767 52.5 0.610 51.3 53.7
## 4 Mujer No 6068 12767 47.5 0.641 46.3 48.8
El mismo comando prop.test
permite hacer la prueba para
la diferencia de proporciones. Para esto, los valores tanto de hombres,
como de mujeres, se concatenan con la especificación c(…)
,
tanto para el n de “Sí” de cada grupo, como para el total de casos de
cada grupo.
prop.test(c(2777, 6699), c(6163,12767))
##
## 2-sample test for equality of proportions with continuity correction
##
## data: c(2777, 6699) out of c(6163, 12767)
## X-squared = 91.044, df = 1, p-value < 2.2e-16
## alternative hypothesis: two.sided
## 95 percent confidence interval:
## -0.08938432 -0.05885549
## sample estimates:
## prop 1 prop 2
## 0.4505922 0.5247121
Según los resultados, se encuentra que el 52.5% de docentes mujeres
recibieron apoyo psicológico versus el 45.1% de docentes hombres. Este
comando no nos brinda directamente los límites inferior y superior de
los IC de cada grupo, pero nos brinda el IC de la diferencia de
proporciones al 95% de confianza. Este IC de la diferencia de
proporciones varía entre -8.9% y -5.9%.
Como este IC va solo entre valores negativos; es decir, como el IC no
incluye al cero, se puede concluir que la diferencia de proporciones no
puede ser cero, por lo tanto, que existe una diferencia estadísticamente
significativa en las proporciones entre ambos grupos.
La tabla 2 se puede usar para graficar. Como nos interesa comparar
los porcentajes de docentes que reportaron haber recibido atención
psicológica por sexo, se puede eliminar las filas de aquellos que no
recibieron atención psicológica en la tabla 2.
tabla2 = tabla2[-c(2,4),]
Luego, con esta tabla podemos seguir el mismo procedimiento que con
el cálculo de las barras de error para la media, pero esta vez para los
porcentajes.
library(ggplot2)
graf2 = ggplot(tabla2, aes(x=sexo, y=Por))+
geom_bar(stat="identity")+
geom_errorbar(aes(ymin=liminf, ymax=limsup), width=0.2)+
geom_text(aes(label=paste(round(Por, 1))), vjust=-1, size=4)+
xlab("Sexo del docente") + ylab("Porcentaje que recibió atención psicológica")+
ylim(0, 60)
graf2
De este gráfico se puede concluir que existen diferencias
estadísticamente significativas en el porcentaje de docentes que
buscaron atención psicológica entre hombres y mujeres, debido a que los
intervalos de confianza no se traslapan.
De manera más específica, se puede afirmar que las docentes peruanas
reciben más atención psicológica que los docentes hombres.
Ejemplo 2 para una variable categórica: LAPOP
En la página 21 del reporte Cultura política de la democracia en
Perú y en las Américas 2021: Tomándole el pulso a la democracia se
presenta el gráfico que muestra el porcentaje de apoyo a la democracia
en Perú (línea magenta) a lo largo del tiempo, en comparación con
América Latina (línea morada).
El apoyo a la democracia, variable “ING4”, está medida en una escala
del 1 al 7, donde 1 significa “muy en desacuerdo” y 7 significa “muy de
acuerdo”. Esta variable se tiene que recodificar. De acuerdo al reporte
“Las respuestas van de 1 (muy en desacuerdo) a 7 (muy de acuerdo). Para
este análisis, se codificaron las respuestas en el extremo”de acuerdo”
de la escala (valores que van de 5 a 7) como apoyo a la democracia.”
(p.7).
Para recodificar la variable se usa el siguiente código. El resultado
es una variable dicotómica (0=No, 1=Sí), que es una variable categórica,
aunque incluye un grupo que no tiene respuesta en esta variable y está
como NAs.
library(dplyr)
lapop = lapop %>%
mutate(ing4rec= case_when(
ing4 >= 1 & ing4 <= 4 ~ 0,
ing4 >= 5 & ing4 <= 7 ~ 1,
))
Se verifica la recodificación.
lapop %>%
count(ing4, name="Frecuencia")
## ing4 Frecuencia
## 1 1 113
## 2 2 109
## 3 3 191
## 4 4 335
## 5 5 337
## 6 6 200
## 7 7 236
## 8 NA 14
Lo que queremos es encontrar el intervalo de confianza de la
proporción (o porcentaje) de aquellos que responden “Sí” (las 7754
personas con un 1). Ojo que la tabla muestra a 393 personas con NAs.
lapop %>%
count(ing4rec, name="Frecuencia")
## ing4rec Frecuencia
## 1 0 748
## 2 1 773
## 3 NA 14
Y queremos calcular el porcentaje de aquellos que responden “Sí” por
año de la encuesta. La variable que registra el año de la encuesta es
“wave”. Esta variable se carga como una numérica (por este motivo, en el
gráfico anterior el eje X del gráfico aparece como una variable
continua) y se tiene que transformar a una de factor llamada
“ronda”.
lapop = lapop %>%
mutate(ronda = factor(wave))
Se calcula el apoyo a la democracia por años. Para el cálculo de esta
tabla queremos excluir a aquellos que no tienen respuesta en la variable
apoyo a la democracia (los 393 NAs anteriores). Esto lo podemos hacer
con el comando filter
, donde especificamos que solo
queremos calcular los porcentajes de aquellos que respondieron No (o 0
en la variable) y aquellos que respondieron Sí (o 1 en la variable).
En cada grupo se quiere calcular el intervalo de confianza de la
proporción. Recuerden que la fórmula que se tiene que usar es la de
intervalos de confianza de la proporción.
Dentro del comando mutate
calculamos el total en cada
grupo (total), la proporción (Por), el error estándar (err que es igual
a la raíz cuadrada del porcentaje por 100-porcentaje entre N) y el
límite inferior y superior del intervalo de confianza.
tabla3 = lapop %>%
filter(ing4rec ==0 | ing4rec == 1) %>%
group_by(ronda) %>%
count(Apoyo = ing4rec, name="N") %>%
mutate(total = sum(N),
Por = N / total * 100,
err = sqrt(Por*(100-Por)/N),
liminf = Por - 1.96*err,
limsup = Por + 1.96*err)
tabla3
## # A tibble: 2 × 8
## # Groups: ronda [1]
## ronda Apoyo N total Por err liminf limsup
## <fct> <dbl> <int> <int> <dbl> <dbl> <dbl> <dbl>
## 1 2023 0 748 1521 49.2 1.83 45.6 52.8
## 2 2023 1 773 1521 50.8 1.80 47.3 54.3
La tabla muestra los datos de los que no apoyan a la democracia
(filas donde Apoyo=0) y de los que sí apoyan a la democracia (filas
donde Apoyo=1) por cada ronda.
Como solo se quiere graficar a los que sí apoyan a la democracia, se
deben eliminar todas las filas impares.
tabla3 = tabla3[-c(1,3,5,7,9,11,13,15),]
tabla3
## # A tibble: 1 × 8
## # Groups: ronda [1]
## ronda Apoyo N total Por err liminf limsup
## <fct> <dbl> <int> <int> <dbl> <dbl> <dbl> <dbl>
## 1 2023 1 773 1521 50.8 1.80 47.3 54.3
Ahora, tenemos los datos para graficar.
graf4 = ggplot(tabla3, aes(x=ronda, y=Por))+
geom_bar(stat="identity")+
geom_errorbar(aes(ymin=liminf, ymax=limsup), width=0.2)+
geom_text(aes(label=paste(round(Por, 1))), vjust=-1, size=4)+
xlab("Ronda") + ylab("Porcentaje que apoya a la democracia")+
ylim(0, 70)
graf4
Nota final
La comparación de IC, ya sea calculando los valores para cada grupo o
ya sea de manera gráfica, es una primera manera de analizar si las
diferencias entre grupos se pueden extrapolar a la población.
Pero esta es una manera “informal” de hacer esta comparación. Para
formalizar esta comparación existe una prueba estadística llamada prueba
t de diferencias de medias o la prueba de proporciones, que se verán en
la siguiente sesión.
Bibliografía
Galarza, Francisco, Liuba Kogan, and Gustavo Yamada. 2012.
“Detectando Discriminación Sexual y Racial En El Mercado Laboral
de Lima.” In Chapters of
Books, 1:103–35. Fondo Editorial, Universidad
del Pacífico.
LS0tCnRpdGxlOiAiQ2xhc2UgNDogRWplbXBsb3MgZSBJbnRlcnZhbG9zIGRlIENvbmZpYW56YSIKYXV0aG9yOiAiQXJ0dXJvIE1hbGRvbmFkbyIKZGF0ZTogIjEwLTE3LzA5LzIwMjQiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIHRvY19kZXB0aDogMQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IGNvc21vCiAgICBoaWdobGlnaHQ6IHRleHRtYXRlCmVkaXRvcl9vcHRpb25zOgogIG1hcmtkb3duOgogICAgd3JhcDogc2VudGVuY2UKYmlibGlvZ3JhcGh5OiByZWZlcmVuY2VzLmJpYgotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyBFZmVjdGl2b3MgZW4gbGFzIENvbWlzYXJpYXMgZGVsIFBlcsO6CgoqUHJlZ3VudGE6IMK/bG9zIHBvbGljw61hcyBlbiBlbCBQZXLDuiBlc3TDoW4gZGlzdHJpYnVpZG9zIGVxdWl0YXRpdmFtZW50ZSBlbnRyZSBsYXMgY29taXNhcsOtYXMgZGVsIFBlcsO6PyoKCirCv0PDs21vIGNyZWUgcXVlIGVzIGVzdGEgZGlzdHJpYnVjacOzbiBkZSBkYXRvcz8qCgpQYXJhIHJlc3BvbmRlciBhIGVzdGEgcHJlZ3VudGEgc2UgdXNhIGxhIGJhc2UgZGUgZGF0b3MgZGUgY29taXNhcsOtYXMgZGVsIFBlcsO6IGRlIDIwMTcuCkVzdGEgYmFzZSBkZSBkYXRvcyBlc3TDoSBkaXNwb25pYmxlIGVuIGxhIHNlY2Npw7NuIFtNaWNyb2RhdG9zXShodHRwczovL3Byb3llY3Rvcy5pbmVpLmdvYi5wZS9taWNyb2RhdG9zLykgZGVsIElORUkuCgpgYGB7cn0KbGlicmFyeShyaW8pIApjb21pMTcgPSBpbXBvcnQoImJhc2VzL2NvbWkyMDE3LnNhdiIpCmBgYAoKRXN0YSBiYXNlIGRlIGRhdG9zIGluY2x1eWUgbGEgcHJlZ3VudGEgc29icmUgZWwgbsO6bWVybyB0b3RhbCBkZSBlZmVjdGl2b3MgZW4gY2FkYSBjb21pc2Fyw61hLgpFc3RhIHZhcmlhYmxlIHNlIGltcG9ydGEgZW4gUiBjb21vIHVuYSB2YXJpYWJsZSBudW3DqXJpY2EsIHkgZWZlY3RpdmFtZW50ZSBlcyBlbCB0aXBvIGRlIHZhcmlhYmxlIGNvcnJlY3RvLgoKYGBge3J9CmNsYXNzKGNvbWkxNyRJTkYxMTBfVE9UKQpgYGAKCkNvbW8gZXN0YSBlcyB1bmEgdmFyaWFibGUgbnVtw6lyaWNhLCBzZSBwdWVkZSBkZXNjcmliaXIgbWVkaWFudGUgbGEgbWVkaWEgeSBsYSBtZWRpYW5hLgoKwr9RdcOpIG5vcyBpbmRpY2FuIGVzdG9zIHJlc3VsdGFkb3M/CgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmNvbWkxNyAlPiUKICBzdW1tYXJpc2UoTcOtbmltbyA9IG1pbihJTkYxMTBfVE9UKSwgCiAgICAgICAgICAgIE1lZGlhbmEgPSBtZWRpYW4oSU5GMTEwX1RPVCksIAogICAgICAgICAgICBQcm9tZWRpbyA9IG1lYW4oSU5GMTEwX1RPVCksCiAgICAgICAgICAgIE3DoXhpbW8gPSBtYXgoSU5GMTEwX1RPVCkpCmBgYAoKU2UgcHVlZGUgZ3JhZmljYXIgbGEgZGlzdHJpYnVjacOzbiBkZWwgbsO6bWVybyBkZSBlZmVjdGl2b3MgcG9yIGNvbWlzYXJpYXMgbWVkaWFudGUgdW4gaGlzdG9ncmFtYS4Kwr9RdcOpIG5vcyBpbmRpY2EgZWwgZ3LDoWZpY28/CgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpnZ3Bsb3QoY29taTE3LCBhZXMoeD1JTkYxMTBfVE9UKSkrCiAgZ2VvbV9oaXN0b2dyYW0oKSsKICB4bGFiKCJOw7ptZXJvIGRlIGVmZWN0aXZvcyIpICsKICB5bGFiKCJGcmVjdWVuY2lhIikrCiAgdGhlbWVfbGlnaHQoKQpgYGAKClNlIHB1ZWRlIGluY2x1aXIgZWwgZGF0byBkZSBsYSBtZWRpYSB5IGxhIG1lZGlhbmEgZW4gZXN0ZSBncsOhZmljby4Kwr9Dw7NtbyBzZSBpbnRlcnByZXRhIGxhIHBvc2ljacOzbiByZWxhdGl2YSBkZSBhbWJhcyBtZWRpZGFzPwoKYGBge3J9CmdncGxvdChjb21pMTcsIGFlcyh4PUlORjExMF9UT1QpKSsKICBnZW9tX2hpc3RvZ3JhbSgpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDE5LCBjb2xvciA9ICJyZWQiKSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAzMS42LCBjb2xvciA9ICJncmVlbiIpKwogIHhsYWIoIk7Dum1lcm8gZGUgZWZlY3Rpdm9zIikgKwogIHlsYWIoIkZyZWN1ZW5jaWEiKSsKICB0aGVtZV9saWdodCgpCmBgYAoKQWhvcmEgc2UgcXVpZXJlIHZlciBzaSBleGlzdGVuIGRpZmVyZW5jaWFzIGVuIGVsIG7Dum1lcm8gcHJvbWVkaW8gZGUgZWZlY3Rpdm9zIHBvbGljaWFsZXMgZW4gbGFzIGNvbWlzYXLDrWFzIGRlbCBQZXLDuiBlbnRyZSBkZXBhcnRhbWVudG9zIG8gZW50cmUgcmVnaW9uZXMuCkEgcGVzYXIgcXVlIGVuIGZvcm11bGFyaW8gc2UgcmVjb2dlIGVsIGRhdG8gZGUgRGVwYXJ0YW1lbnRvLCBQcm92aW5jaWEgeSBEaXN0cml0bywgZW4gbGEgYmFzZSBkZSBkYXRvcyBubyBzZSBjdWVudGEgY29uIGVzYSBpbmZvcm1hY2nDs24uCkxvIHF1ZSBzZSB0aWVuZSBlcyB1bmEgdmFyaWFibGUgbGxhbWFkYSAidWJpZ2VvIi4KRXN0YSB2YXJpYWJsZSBlc3TDoSBlc3RhbmRhcml6YWRhIGRlIHRhbCBtYW5lcmEgcXVlIGxvcyBkb3MgcHJpbWVyb3MgZMOtZ2l0b3MgY29ycmVzcG9uZGVuIGFsIGRlcGFydGFtZW50bywgbG9zIHNlZ3VuZG9zIGRvcyBkw61naXRvcyBhIGxhcyBwcm92aW5jaWFzIHkgbG9zIMO6bHRpbW9zIGRvcyBkw61naXRvcyBhbCBkaXN0cml0by4KUG9yIGxvIHRhbnRvLCBwYXJhIHNhYmVyIGVuIHF1w6kgZGVwYXJ0YW1lbnRvIGVzdMOhIGxhIGNvbWlzYXLDrWEgc2UgcmVxdWllcmUgc2VwYXJhciBsb3MgcHJpbWVyb3MgZG9zIGTDrWdpdG9zIHkgZ3VhcmRhcmxvcyBlbiB1bmEgbnVldmEgdmFyaWFibGUuCgpgYGB7cn0KY29taTE3ID0gY29taTE3ICU+JQogIG11dGF0ZShkcHRvID0gc3RyX3N1YihVQklHRU8sIDEsIDIpKQpgYGAKCkNvcGlhbW9zIGVsIGPDs2RpZ28gdXNhZG8gcGFyYSBlbCB2b3RvIDIwMTYgeSBsbyBhZGFwdGFtb3MgYSBsYXMgbmVjZXNpZGFkZXMgZGUgZXN0YSBiYXNlIGRlIGRhdG9zLgpMYSB2YXJpYWJsZSAiZHB0byIgZXMgdW5hIHZhcmlhYmxlIGRlIHRpcG8gImNoYXJhY3RlciIgeSBzYWJlbW9zIHF1ZSB2YSBkZXNkZSBlbCAiMDEiIGFsICIyNSIsIHJlcHJlc2VudGFuZG8gY2FkYSAibsO6bWVybyIgdW4gZGVwYXJ0YW1lbnRvIGRlbCBQZXLDuiwgcXVlIGhlbW9zIGFzb2NpYWRvIGEgQ29zdGEgPSAxLCBTaWVycmEgPSAyIG8gU2VsdmEgPSAzLgoKRW50b25jZXMgbG8gcXVlIHRlbmVtb3MgcXVlIGhhbGxhciBlcyBlbCBjw7NkaWdvIHViaWdlbyBkZSBjYWRhIGRlcGFydGFtZW50byB5IHJlZW1wbGF6YXJsbyBwb3IgZWwgbm9tYnJlIGRlbCBkZXBhcnRhbWVudG8gZW4gZWwgY8OzZGlnbyBvcmlnaW5hbC4KTGEgY2xhc2lmaWNhY2nDs24gbGEgZ3VhcmRhbW9zIGVuIG90cmEgdmFyaWFibGUgInJlZ2lvbiIuCgpgYGB7cn0KY29taTE3ID0gY29taTE3ICU+JQogIG11dGF0ZShyZWdpb24gPSBjYXNlX3doZW4oCiAgICBkcHRvPT0iMDEifjMsCiAgICBkcHRvPT0iMDIifjIsCiAgICBkcHRvPT0iMDMifjIsCiAgICBkcHRvPT0iMDQifjIsCiAgICBkcHRvPT0iMDUifjIsCiAgICBkcHRvPT0iMDYifjIsCiAgICBkcHRvPT0iMDgifjIsCiAgICBkcHRvPT0iMDcifjEsCiAgICBkcHRvPT0iMDkifjIsCiAgICBkcHRvPT0iMTAifjMsCiAgICBkcHRvPT0iMTEifjEsCiAgICBkcHRvPT0iMTIifjIsCiAgICBkcHRvPT0iMTMifjEsCiAgICBkcHRvPT0iMTQifjEsCiAgICBkcHRvPT0iMTUifjEsCiAgICBkcHRvPT0iMTYifjMsCiAgICBkcHRvPT0iMTcifjMsCiAgICBkcHRvPT0iMTgifjEsCiAgICBkcHRvPT0iMTkifjIsCiAgICBkcHRvPT0iMjAifjEsCiAgICBkcHRvPT0iMjEifjIsCiAgICBkcHRvPT0iMjIifjMsCiAgICBkcHRvPT0iMjMifjEsCiAgICBkcHRvPT0iMjQifjEsCiAgICBkcHRvPT0iMjUifjMKICApKSAKYGBgCgpFc3RhIHZhcmlhYmxlICJyZWdpb24iIGVzIGRlIHRpcG8gbnVtw6lyaWNvLCBwZXJvIGxvcyBjw7NkaWdvcyAoMSwgMiB5IDMpIG5vIHNvbiBuw7ptZXJvcywgc2lubyBjw7NkaWdvcyBwYXJhIENvc3RhLCBTaWVycmEgeSBTZWx2YSwgcG9yIGxvIHF1ZSB0ZW5lbW9zIHF1ZSBjcmVhciBvdHJhIHZhcmlhYmxlLCAicmVnaW9uMiIgcXVlIHNlYSBkZSB0aXBvICJmYWN0b3IiIGNvbiBsYXMgZXRpcXVldGFzIGNvcnJlc3BvbmRpZW50ZXMuCgpgYGB7cn0KbGlicmFyeShmb3JjYXRzKQpjb21pMTcgPSBjb21pMTcgJT4lCiAgbXV0YXRlKHJlZ2lvbjIgPSBmYWN0b3IocmVnaW9uLCBsYWJlbHM9YygiQ29zdGEiLCAiU2llcnJhIiwgIlNlbHZhIikpKQpgYGAKClBvZGVtb3MgdXNhciBlc3RhIHZhcmlhYmxlIHBhcmEgY2FsY3VsYXIgbG9zIGRlc2NyaXB0aXZvcyBkZWwgbsO6bWVybyBkZSBlZmVjdGl2b3MgcG9yIHJlZ2nDs24uCsK/UXXDqSBjb25jbHVzacOzbiBzYWNhIGRlIGxhIHRhYmxhPwoKYGBge3J9CnRhYmxhMSA9IGNvbWkxNyAlPiUKICBncm91cF9ieShyZWdpb24yKSAlPiUKICBzdW1tYXJpc2UoTcOtbmltbyA9IG1pbihJTkYxMTBfVE9UKSwgCiAgICAgICAgICAgIE1lZGlhbmEgPSBtZWRpYW4oSU5GMTEwX1RPVCksIAogICAgICAgICAgICBQcm9tZWRpbyA9IG1lYW4oSU5GMTEwX1RPVCksCiAgICAgICAgICAgIERlc3YgPSBzZChJTkYxMTBfVE9UKSwKICAgICAgICAgICAgTcOheGltbyA9IG1heChJTkYxMTBfVE9UKSkKdGFibGExCmBgYAoKRXN0YSB0YWJsYSBzaXJ2ZSBwYXJhIGNvbXBhcmFyIGxvcyBkYXRvcyBkZXNjcmlwdGl2b3MgcG9yIGdydXBvcyBkZSBvdHJhIHZhcmlhYmxlLgpBbGdvIHNpbWlsYXIgc2UgcHVlZGUgaGFjZXIgY29uIGVsIGdyw6FmaWNvIGRlIGNhamFzLCBwZXJvIGNvbXBhcmFuZG8gbWVkaWFuYXMgeSByYW5nb3MgaW50ZXJjdWFydGlsZXMuCgpgYGB7cn0KZ2dwbG90KGNvbWkxNywgYWVzKHk9SU5GMTEwX1RPVCwgeD1yZWdpb24yKSkrCiAgZ2VvbV9ib3hwbG90KCkrCiAgeWxhYigiTsO6bWVybyBkZSBlZmVjdGl2b3MiKSsKICB4bGFiKCJSZWdpw7NuIikrCiAgdGhlbWVfZ2V0KCkKYGBgCgojIFNlcnZpY2lvcyBiw6FzaWNvcyBlbiBsYXMgY29taXNhcsOtYXMgZGVsIFBlcsO6CgoqUHJlZ3VudGE6IMK/TGFzIGNvbWlzYXLDrWFzIGRlbCBQZXLDuiBjdWVudGFuIGNvbiBzZXJ2aWNpb3MgYsOhc2ljb3M/KgoKUGFyYSByZXNwb25kZXIgZXN0YXMgcHJlZ3VudGFzLCBsYSBFbmN1ZXN0YSBOYWNpb25hbCBkZSBDb21pc2Fyw61hcyBkZSAyMDE3IHRpZW5lIG90cm8gbcOzZHVsbyBzb2JyZSBpbmZyYWVzdHJ1Y3R1cmEuCkNhcmdhbW9zIGVzYSBiYXNlIGRlIGRhdG9zLgoKYGBge3J9CmxpYnJhcnkocmlvKQpjb21pMTdfMiA9IGltcG9ydCgiYmFzZXMvY29taTIwMTdfMi5zYXYiKQpgYGAKCkVzdGEgYmFzZSBpbmNsdXllIGxhIHByZWd1bnRhIElORjIxNiBzb2JyZSBsdXogZWzDqWN0cmljYSwgbGEgcHJlZ3VudGEgSU5GMjI1IHNvYnJlIGFndWEgcG90YWJsZSwgbGEgcHJlZ3VudGEgSU5GMjMwIHNvYnJlIGRlc2Fnw7xlIHkgbGEgcHJlZ3VudGEgSU5GMjY0X0Ugc29icmUgZWwgc2VydmljaW8gZGUgaW50ZXJuZXQuCgpFbiBwcmltZXIgbHVnYXIgdmVyaWZpY2Ftb3MgY8OzbW8gc2UgaW1wb3J0YW4gbGFzIHZhcmlhYmxlcy4KVmVtb3MgcXVlIHNlIGltcG9ydGFuIGNvbW8gdmFyaWFibGVzIG51bcOpcmljYXMuCkxhIHZhcmlhYmxlIHNvYnJlIGx1eiB0aWVuZSBvcGNpb25lcyBTaSA9IDEgeSBObyA9IDIuCkVzdGEgdmFyaWFibGUgZXMgZW4gcmVhbGlkYWQgdW5hIGRlIHRpcG8gZmFjdG9yLgoKYGBge3J9CmNsYXNzKGNvbWkxN18yJElORjIxNikKdGFibGUoY29taTE3XzIkSU5GMjE2KQpgYGAKClNlIHByb2NlZGUgYSBjcmVhciBvdHJhIHZhcmlhYmxlICJsdXoiLCBjb21vIGxhIGZhY3Rvcml6YWNpw7NuIGRlIElORjIxNiBjb24gZXRpcXVldGFzIFPDrSB5IE5vLgoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpjb21pMTdfMiA9IGNvbWkxN18yICU+JQogIG11dGF0ZShsdXogPSBmYWN0b3IoSU5GMjE2LCBsYWJlbHM9YygiU8OtIiwgIk5vIikpKQpgYGAKCkVzdGEgdmFyaWFibGUgaW5jbHV5ZSBhbGd1bmFzIGNvbWlzYXLDrWFzIGRvbmRlIG5vIHNlIHRpZW5lIGVsIGRhdG8sIHBvciBsbyBxdWUgY3VhbmRvIHNlIGNhbGN1bGEgbGEgdGFibGEsIHNlIGZpbHRyYSBzb2xvIGxhcyByZXNwdWVzdGFzIFPDrSB5IE5vLgpTZSBndWFyZGEgbG9zIHJlc3VsdGFkb3MgZW4gdW4gb2JqZXRvICJ0YWJsYTIiLgoKYGBge3J9CnRhYmxhMiA9IGNvbWkxN18yICU+JQogIGZpbHRlcihsdXogPT0gIlPDrSIgfCBsdXogPT0gIk5vIikgJT4lCiAgY291bnQoTHV6ID0gbHV6LCBuYW1lPSJGcmVjdWVuY2lhIikKdGFibGEyCmBgYAoKU2UgYcOxYWRlIGEgZXN0ZSBtaXNtbyBvYmpldG8gbG9zIHBvcmNlbnRhamVzLgrCv1F1w6kgY29uY2x1c2lvbmVzIHNhY2EgZGUgZXN0b3MgcmVzdWx0YWRvcz8KCmBgYHtyfQp0YWJsYTIgPSB0YWJsYTIgJT4lCiAgbXV0YXRlKFBvcmNlbnRhamUgPSAoRnJlY3VlbmNpYSAvIHN1bShGcmVjdWVuY2lhKSoxMDAgKSkKdGFibGEyCmBgYAoKU2UgaGFjZSBlbCBtaXNtbyBwcm9jZWRpbWllbnRvIGNvbiBsYSB2YXJpYWJsZSBzb2JyZSBhZ3VhIHBvdGFibGUuCkVuIGVzdGUgY2FzbywgbGEgdmFyaWFibGUgdGllbmUgY2luY28gdmFsb3Jlcy4KCmBgYHtyfQpjbGFzcyhjb21pMTdfMiRJTkYyMjUpCnRhYmxlKGNvbWkxN18yJElORjIyNSkKYGBgCgpgYGB7cn0KY29taTE3XzIgPSBjb21pMTdfMiAlPiUKICBtdXRhdGUoYWd1YSA9IGZhY3RvcihJTkYyMjUsIGxhYmVscz1jKCJSZWQgcMO6YmxpY2EgZGVudHJvIGRlbCBsb2NhbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbWnDs24gY2lzdGVybmEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBvem8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlLDrW8sIGFjZXF1aWEgbyBtYW5hbnRpYWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk90cm8iKSkpCnRhYmxlKGNvbWkxN18yJGFndWEpCmBgYAoKU2UgY2FsY3VsYSBsYSB0YWJsYSBkZSBkaXN0cmlidWNpw7NuIGRlIGZyZWN1ZW5jaWFzLCBjb24gZWwgY8OhbGN1bG8gZGUgbG9zIHBvcmNlbnRhamVzIGVuIGVsIG1pc21vIGPDs2RpZ28uCsK/UXXDqSBjb25jbHVzaW9uZXMgc2FjYSBkZSBlc3RvcyByZXN1bHRhZG9zPwoKYGBge3J9CnRhYmxhMyA9IGNvbWkxN18yICU+JQogIGNvdW50KEFndWEgPSBhZ3VhLCBuYW1lPSJGcmVjdWVuY2lhIikgJT4lCiAgbXV0YXRlKFBvcmNlbnRhamUgPSAoRnJlY3VlbmNpYSAvIHN1bShGcmVjdWVuY2lhKSoxMDAgKSkKdGFibGEzCmBgYAoKwr9RdcOpIGNvbmNsdXNpb25lcyBzYWNhIGRlIGVzdG9zIHJlc3VsdGFkb3M/CgpGaW5hbG1lbnRlLCBzZSBoYWNlIGxvIG1pc21vIHBhcmEgbGEgcHJlZ3VudGEgc29icmUgaW50ZXJuZXQuCgpgYGB7cn0KY2xhc3MoY29taTE3XzIkSU5GMjY0X0UpCnRhYmxlKGNvbWkxN18yJElORjI2NF9FKQpgYGAKCmBgYHtyfQpjb21pMTdfMiA9IGNvbWkxN18yICU+JQogIG11dGF0ZShpbnRlcm5ldCA9IGZhY3RvcihJTkYyNjRfRSwgbGFiZWxzPWMoIlPDrSwgcGFnbyBwZW5kaWVudGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTw60sIHBhZ28gYWwgZMOtYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU8OtLCBubyBzYWJlIGRlbCBwYWdvIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJObyBjdWVudGEgY29uIGVsIHNlcnZpY2lvIikpKQp0YWJsZShjb21pMTdfMiRpbnRlcm5ldCkKYGBgCgrCv1F1w6kgY29uY2x1c2lvbmVzIHNhY2Egc29icmUgZXN0b3MgcmVzdWx0YWRvcz8KCmBgYHtyfQp0YWJsYTUgPSBjb21pMTdfMiAlPiUKICBjb3VudChJbnRlcm5ldCA9IGludGVybmV0LCBuYW1lPSJGcmVjdWVuY2lhIikgJT4lCiAgbXV0YXRlKFBvcmNlbnRhamUgPSAoRnJlY3VlbmNpYSAvIHN1bShGcmVjdWVuY2lhKSoxMDAgKSkKdGFibGE1CmBgYAoKRXN0ZSB0aXBvIGRlIHZhcmlhYmxlcywgZGUgdGlwbyBmYWN0b3IsIHNlIHB1ZWRlIHZpc3VhbGl6YXIgY29uIGdyw6FmaWNvcyBkZSBiYXJyYXMuCgpgYGB7cn0KZ3JhZjEgPSBnZ3Bsb3QodGFibGE1LCBhZXMoeD1JbnRlcm5ldCwgeT1Qb3JjZW50YWplKSkrCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSsKICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1wYXN0ZShyb3VuZChQb3JjZW50YWplLCAxKSkpLCB2anVzdD0tMSwgc2l6ZT0zKSsKICBsYWJzKHg9IkludGVybmV0IiwgeT0iUG9yY2VudGFqZSIpKwogIHRoZW1lX2NsYXNzaWMoKQpncmFmMQpgYGAKCiMjIFRhcmVhCgpDYWxjdWxlIGxhcyB0YWJsYXMgZGUgZGlzdHJpYnVjacOzbiBkZSBmcmVjdWVuY2lhcyBkZSBsdXogeSBkZSBpbnRlcm5ldCBwb3IgcmVnaW9uZXMuCkdyYWZpcXVlLgoKIyBQcnVlYmFzIGRlIHNpZ25pZmljYW5jaWEKCkVzIHVuYSBkZSBsYXMgdMOpY25pY2FzIG3DoXMgdXNhZGFzIHBhcmEgZWwgYW7DoWxpc2lzIGVuIGNpZW5jaWFzIHNvY2lhbGVzLgpTaXJ2ZSwgcG9yIGVqZW1wbG8sIHBhcmEgY29tcGFyYXIgZW50cmUgZ3J1cG9zOgoKLSAgIENvbXBhcmFyIGxhIG1lZGlhIGRlIGluZ3Jlc29zIGRlIGhvbWJyZXMgeSBtdWplcmVzCgotICAgQ29tcGFyYXIgbGEgcHJvcG9yY2nDs24gZGUgcGVyc29uYXMgcXVlIHZvdGFyw6FuIGEgY2FuZGlkYXRvIFggZW4gTGltYSB5IGVuIFJlZ2lvbmVzCgotICAgQ29tcGFyYXIgbG9zIGluZ3Jlc29zIGRlIHByb2Zlc29yZXMgZW4gbGEgZ2VzdGnDs24gcMO6YmxpY2EgeSBlbiBsYSBnZXN0acOzbiBwcml2YWRhCgpMYSBpZGVhIGVzIGNvbXBhcmFyIGxhcyBlc3RpbWFjaW9uZXMgcHVudHVhbGVzIGVudHJlIGFtYm9zIGdydXBvcyB5IHRhbWJpw6luIHBvZGVyIGV4dHJhcG9sYXIgZXN0YXMgZGlmZXJlbmNpYXMgYSBsYSBwb2JsYWNpw7NuLgoKVmFtb3MgYSBjb21lbnphciBwb3IgY29tcGFyYWNpb25lcyBlbnRyZSBzb2xvIDIgZ3J1cG9zIChwb3IgZWwgbW9tZW50byksIHF1ZSBjb3JyZXNwb25kZSBhIHVuYSB2YXJpYWJsZSBiaW5hcmlhIG8gZGljb3TDs21pY2EsIGNvbW8gc2V4byAoaG9tYnJlcy9tdWplcmVzKSwgw6FtYml0byAodXJiYW5vL3J1cmFsKSwgZ2VzdGnDs24gZWR1Y2F0aXZhIChww7pibGljYS9wcml2YWRhKS4KClBhcmEgbW9zdHJhciB1biBlamVtcGxvLCB2YW1vcyBhIHVzYXIgZWwgdHJhYmFqbyBkZSBbQGdhbGFyemFEZXRlY3RhbmRvRGlzY3JpbWluYWNpb25TZXh1YWwyMDEyXSBxdWUgZXZhbMO6YSBsYSBkaXNjcmltaW5hY2nDs24gZW4gZWwgbWVyY2FkbyBsYWJvcmFyIGVudHJlIGhvbWJyZXMgeSBtdWplcmVzLgpFc3RvcyBhdXRvcmVzIGVudmlhcm9uIENWcyBjb24gZXhhY3RhcyBjdWFsaWZpY2FjaW9uZXMgYSBvZmVydGFzIHJlYWxlcyBkZSB0cmFiYWpvLCB2YXJpYW5kbyBzb2xvIGVsIG5vbWJyZSBkZWwgYXBsaWNhbnRlLCBjb24gbm9tYnJlcyBkZSBob21icmVzIHkgbXVqZXJlcy4KTGEgdmFyaWFibGUgZGUgcmVzcHVlc3RhIGVzIGxhIHRhc2EgZGUgcmVzcHVlc3RhIGEgZXN0b3MgQ1ZzLCBlcyBkZWNpciwgZGUgY3XDoW50b3MgQ1ZzIGVudmlhZG9zIHNlIHJlY2liacOzIHVuYSBsbGFtYWRhIHBhcmEgdW5hIGVudHJldmlzdGEuCgpFbiBjdWFscXVpZXIgcHJ1ZWJhIGRlIHNpZ25pZmljYW5jaWEgc2UgdGllbmUgcXVlIHByZXNlbnRhciB1bmEgaGlww7N0ZXNpcyBudWxhLCBxdWUgZ2VuZXJhbG1lbnRlIGVzIGxhIGhpcMOzdGVzaXMgZGUgbm8gZGlmZXJlbmNpYXMgbyBkZSBubyBlZmVjdG9zLgpFc3RlIHRyYWJham8gcGFydGUgZGUgdW5hIGlkZWEgcXVlIGV4aXN0ZSB1bmEgZGlzY3JpbWluYWNpw7NuIGRlIGfDqW5lcm8gZW4gZWwgbWVyY2FkbyBsYWJvcmFsLCBwb3IgbG8gcXVlIGxhIGhpcMOzdGVzaXMgbnVsYSBpbmRpY2Fyw61hIGxvIGNvbnRyYXJpby4KRW4gZWwgY2FzbyBkZSBlc3RlIHRyYWJham8gc2UgdGVuZHLDrWE6CgpIMDogVGFzYSBkZSByZXNwdWVzdGEgYSBDVnMgZGUgaG9tYnJlcyA9IFRhc2EgZGUgcmVzcHVlc3RhIGEgQ1ZzIGRlIG11amVyZXMKCm8gbG8gcXVlIGVzIGxvIG1pc21vCgpIMDogVGFzYSBkZSByZXNwdWVzdGEgYSBDVnMgZGUgaG9tYnJlcyAtIFRhc2EgZGUgcmVzcHVlc3RhIGEgQ1ZzIGRlIG11amVyZXMgPSAwCgpFbiBlc2UgdHJhYmFqbyBzZSBwcmVzZW50YSBlbCBzaWd1aWVudGUgY3VhZHJvIGRlIHJlc3VsdGFkb3M6CgohW10oR2FsYXJ6YS5wbmcpe3dpZHRoPSI0MzUifQoKRW4gbGEgbXVlc3RyYSB0b3RhbCBkZSAyLDIyOCBDVnMgZW52aWFkb3MsIG1pdGFkIGRlIENWcyBjb24gbm9tYnJlcyBkZSBob21icmVzIHkgbGEgb3RyYSBtaXRhZCBjb24gbm9tYnJlcyBkZSBtdWplcmVzLCB0b2RvcyBjb24gbGFzIG1pc21hcyBjdWFsaWZpY2FjaW9uZXMsIHNlIHRpZW5lIHF1ZSBsYSB0YXNhIGRlIHJlc3B1ZXN0YSBwYXJhIGxvcyBDVnMgZGUgaG9tYnJlcyBlcyAxMy40JSB5IHBhcmEgbG9zIENWcyBkZSBtdWplcmVzIGVzIDExLjElLgoKRGUgYWN1ZXJkbyBhIGxhcyBlc3RpbWFjaW9uZXMgcHVudHVhbGVzLCBlZmVjdGl2YW1lbnRlLCBsb3MgaG9tYnJlcyB0aWVuZW4gdW5hIG1heW9yIHRhc2EgZGUgcmVzcHVlc3RhIGEgc3VzIENWcyBxdWUgbGFzIG11amVyZXMsIGEgaWd1YWxlcyBjdWFsaWZpY2FjaW9uZXMuCkVzdGEgY29uY2x1c2nDs24sIHNpbiBlbWJhcmdvLCBlcyBzb2xvIHBhcmEgbGFzIDIsMjI4IG9ic2VydmFjaW9uZXMgZGUgbGEgbXVlc3RyYS4Kwr9Dw7NtbyBleHRyYXBvbGFyIGVzdGEgY29uY2x1c2nDs24gYSBsYSBwb2JsYWNpw7NuPwrCv1RvZGEgZGlmZXJlbmNpYSBwdW50dWFsIHNlIHZhbGlkYXLDrWEgZW4gbGEgcG9ibGFjacOzbj8KCiMgQ29tcGFyYWNpw7NuIGRlIGludGVydmFsb3MgZGUgY29uZmlhbnphIHBvciBncnVwb3MKClVuYSBwcmltZXJhIGZvcm1hICJpbmZvcm1hbCIgcGFyYSBleHRyYXBvbGFyIGxhcyBkaWZlcmVuY2lhcyBlbiBsYXMgZXN0aW1hY2lvbmVzIHB1bnR1YWxlcyBkZSBsYSBtdWVzdHJhIGEgbGEgcG9ibGFjacOzbiBlcyBjb25zdHJ1eWVuZG8gbG9zIGludGVydmFsb3MgZGUgY29uZmlhbnphIHBhcmEgbGEgbWVkaWEgbyBwYXJhIGxhIHByb3BvcmNpw7NuIHBvciBjYWRhIHVubyBkZSBsb3Mgc3ViZ3J1cG9zLgoKRW4gZXN0ZSBjYXNvLCBwb3IgZWplbXBsbywgc2lnbmlmaWNhcsOtYSBjb25zdHJ1aXIgZWwgSUMgZGUgbGEgdGFzYSBkZSByZXNwdWVzdGEgcGFyYSBob21icmUgeSBtdWplcmVzLgoKUHJlZ3VudGE6IMK/U2UgcHVlZGVuIGNvbnN0cnVpciBsb3MgSUMgZGUgY2FkYSBncnVwbyBjb24gbG9zIGRhdG9zIGRlIGxhIHRhYmxhPwoKQ2FkYSBJQyBzZXLDrWEgdW5hIGV4dHJhcG9sYWNpw7NuIGRlbCBwYXLDoW1ldHJvLCBlcyBkZWNpciwgZWwgcmFuZ28gZGUgdmFsb3JlcyBkZSBsYSB0YXNhIGRlIHJlc3B1ZXN0YSBhIGxvcyBDVnMgZGUgaG9tYnJlcyBwYXJhIHRvZG8gZWwgbWVyY2FkbyBsYWJvcmFsIGFsIDk1JSBkZSBjb25maWFuemEuCkxvIG1pc21vIHBhcmEgbGEgdGFzYSBkZSByZXNwdWVzdGEgZGUgbGFzIG11amVyZXMuCgpVbmEgdmV6IGNvbnN0cnVpZG9zIGxvcyBJQywgc2UgYW5hbGl6YSBzaSBlc3RvcyBpbnRlcnZhbG9zIHNlIGNydXphbiBvIG5vIHNlIGNydXphbi4KTGEgcmVnbGEgZGUgZGVjaXNpw7NuICJpbmZvcm1hbCIgZXM6CgotICAgU2kgbG9zIElDIGRlIGFtYm9zIGdydXBvcyBzZSBjcnV6YW4sIGVudG9uY2VzIG5vIHNlIHB1ZWRlIGFmaXJtYXIgcXVlIGVsIHBhcsOhbWV0cm8gZGUgdW4gZ3J1cG8gc2VhIG1heW9yIG8gbWVub3MgcXVlIGVsIHBhcsOhbWV0cm8gZGVsIG90cm8gZ3J1cG8uCgotICAgU2kgbG9zIElDIGRlIGFtYm9zIGdydXBvcyBOTyBzZSBjcnV6YW4sIGVudG9uY2VzIHNlIHB1ZWRlIGFmaXJtYXIsIGFsIDk1JSBkZSBjb25maWFuemEsIHF1ZSBlbCBwYXLDoW1ldHJvIGRlIHVuIGdydXBvIGVzIG1heW9yL21lbm9yIGFsIHBhcsOhbWV0cm8gZGVsIG90cm8gZ3J1cG8uCgojIEVqZW1wbG8gMSBwYXJhIHVuYSB2YXJpYWJsZSBudW3DqXJpY2E6IEVOTAoKKlByZWd1bnRhOiDCv2V4aXN0ZW4gZGlmZXJlbmNpYSBlbiBsYSBjYW50aWRhZCBkZSBsaWJyb3MgcXVlIGxlZW4gaG9tYnJlcyB5IG11amVyZXM/KiDCv3kgZW50cmUgZGlmZXJlbnRlcyBuaXZlbGVzIHNvY2lvZWNvbsOzbWljb3M/CgpMYSBoaXDDs3Rlc2lzIGNlcm8gc2Vyw61hOgoKSG86IFByb21lZGlvIGRlIGxpYnJvcyBxdWUgbGVlIHVuIGhvbWJyZSA9IFByb21lZGlvIGRlIGxpYnJvcyBxdWUgbGVlIHVuYSBtdWplci4KCmBgYHtyfQpsaWJyYXJ5KHJpbykKZW5sID0gaW1wb3J0KCIvVXNlcnMvQXJ0dXJvL0xpYnJhcnkvQ2xvdWRTdG9yYWdlL0dvb2dsZURyaXZlLWFydHVyby5tYWxkb25hZG9AcHVjcC5wZS9NeSBEcml2ZS9BIEN1cnNvcy9Fc3RhZGlzdGljYV8xL0RhdGEvRU5MMjAyMi9FTkwyMDIyLnNhdiIpCmBgYAoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQplbmwgPSBlbmwgJT4lCiAgbXV0YXRlKHNleG8gPSBmYWN0b3IoUDIwOSwgbGFiZWxzPWMoIkhvbWJyZSIsICJNdWplciIpKSkKYGBgCgpgYGB7cn0KZW5sID0gZW5sICU+JQogIG11dGF0ZShuc2UxID0gZmFjdG9yKG5zZSwgbGFiZWxzPWMoIlJ1cmFsIiwgIkJham8iLCAiTWVkaW8iLCAiQWx0byIpKSkKYGBgCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmVubCA9IGVubCAlPiUKICBtdXRhdGUobGlicm9zID0gUDQxMl8xICsgUDQxMl8yKQpgYGAKCmBgYHtyfQplbmwgJT4lCiAgc3VtbWFyaXplKG1lYW4oUDQxMl8xLCBuYS5ybT1UKSwgCiAgICAgICAgICAgIG1lYW4oUDQxMl8yLCBuYS5ybT1UKSwgCiAgICAgICAgICAgIG1lYW4obGlicm9zLCBuYS5ybT1UKSkKYGBgCgpgYGB7cn0KdGFibGExID0gZW5sICU+JQogIGdyb3VwX2J5KHNleG8pICU+JQogIHN1bW1hcml6ZShtZWRpYSA9IG1lYW4obGlicm9zLCBuYS5ybT1UKSwgCiAgICAgICAgICAgIG1lZGlhbmEgPSBtZWRpYW4obGlicm9zLCBuYS5ybT1UKSwKICAgICAgICAgICAgZGVzdmlhY2lvbiA9IHNkKGxpYnJvcywgbmEucm09VCkpCnRhYmxhMQpgYGAKCmBgYHtyfQpnZ3Bsb3QoZW5sLCBhZXMoeT0gbGlicm9zLCB4PSBzZXhvKSkrCiAgZ2VvbV9ib3hwbG90KCkrCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMjApKSsKICB5bGFiKCJUb3RhbCBsaWJyb3MgbGXDrWRvcyIpKwogIHhsYWIoIlNleG8iKSsKICB0aGVtZV9nZXQoKQpgYGAKCkVsIGPDoWxjdWxvIGRlbCBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGRlIHVuYSBtZWRpYSBlczoKCiQkCklDID0gIFxiYXJ7WH0gXHBtIDEuOTYgKiBcZnJhY3tzfSB7XHNxcnR7bn19CiQkCgpQYXJhIHVuYSBjb21wYXJhY2nDs24gdXNhbmRvIGxvcyBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YSwgc2UgcHVlZGUgdXNhciBlbCBjb21hbmRvIGBjaU1lYW5gIGRlIGxhIGxpYnJlcsOtYSBgbHNyYC4KRXN0ZSBjb21hbmRvIHJlZ3Jlc2EgZWwgbMOtbWl0ZSBpbmZlcmlvciB5IGVsIGzDrW1pdGUgc3VwZXJpb3IgZGVsIGludGVydmFsbyBkZSBjb25maWFuemEuClBvciBsbyB0YW50bywgcGFyYSBndWFyZGFyIHNvbG8gZWwgbcOtbmltbyBzZSB0aWVuZSBxdWUgZXNwZWNpZmljYXIgYGxzcjo6Y2lNZWFuKFAxXzYsIG5hLnJtPVQpWzFdYCB5IHBhcmEgZWwgbcOheGltbyBjYW1iaWFyw61hIGEgYFsyXWAuCgpgYGB7cn0KbGlicmFyeShsc3IpCnRhYmxhMiA9IGVubCAlPiUKICBzdW1tYXJpc2UobWVkaWEgPSBtZWFuKGxpYnJvcywgbmEucm09VCksCiAgICAgICAgICAgIGRlc3YgPSBzZChsaWJyb3MsIG5hLnJtID0gVCksCiAgICAgICAgICAgIGxpbWluZiA9IGNpTWVhbihsaWJyb3MsIG5hLnJtPVQpWzFdLAogICAgICAgICAgICBsaW1zdXAgPSBjaU1lYW4obGlicm9zLCBuYS5ybT1UKVsyXQogICAgICAgICAgICApCnRhYmxhMgpgYGAKCmBgYHtyfQp0YWJsYTJ4c2V4byA9IGVubCAlPiUKICBncm91cF9ieShzZXhvKSAlPiUKICBzdW1tYXJpc2UobWVkaWEgPSBtZWFuKGxpYnJvcywgbmEucm09VCksCiAgICAgICAgICAgIGRlc3YgPSBzZChsaWJyb3MsIG5hLnJtID0gVCksCiAgICAgICAgICAgIGxpbWluZiA9IGNpTWVhbihsaWJyb3MsIG5hLnJtPVQpWzFdLAogICAgICAgICAgICBsaW1zdXAgPSBjaU1lYW4obGlicm9zLCBuYS5ybT1UKVsyXQogICAgICAgICAgICApCnRhYmxhMnhzZXhvCmBgYAoKLSAgIEVsIElDIGFsIDk1JSBkZSBjb25maWFuemEsIGVsIHByb21lZGlvIGRlIGxpYnJvcyBxdWUgbGVlIHVuIGhvbWJyZSBlc3TDoSBlbiBlbCBzaWd1aWVudGUgaW50ZXJ2YWxvICQkMy44MCAtIDQuMDUkJAoKLSAgIEVsIElDIGFsIDk1JSBkZSBjb25maWFuemEgZWwgbGlicm9zIHF1ZSBsZWUgdW5hIG11amVyIGVzdMOhIGVuIGVsIHNpZ3VpZW50ZSBpbnRlcnZhbG8gJCQzLjY5IC0gMy44NyQkCgpDb21vIGFtYm9zIGludGVydmFsb3MgU8ONIHNlIHRyYXNsYXBhbiwgZW50b25jZXMgTk8gc2UgcHVlZGUgYWZpcm1hciBxdWUgZXNhcyBkaWZlcmVuY2lhcyBzZSBwdWVkZW4gZXh0cmFwb2xhciBsYSBwb2JsYWNpw7NuLgpOTyBzZSBwdWVkZSBhZmlybWFyIHF1ZSBleGlzdGFuIGRpZmVyZW5jaWFzIGVudHJlIGhvbWJyZXMgeSBtdWplcmVzIGVuIGVsIG7Dum1lcm8gZGUgbGlicm9zIHF1ZSBsZWVuIChzZXLDrWEgdW4gImVtcGF0ZSB0w6ljbmljbyIpLgoKIyMgR3LDoWZpY28gZGUgSUMgcGFyYSBjb21wYXJhciBtZWRpYXMKCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmdyYWYgPSBnZ3Bsb3QodGFibGEyeHNleG8sIGFlcyh4PXNleG8sIHk9bWVkaWEpKSsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49bGltaW5mLCB5bWF4PWxpbXN1cCksIHdpZHRoPTAuMikrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChtZWRpYSwgMSkpLCB2anVzdD0tMSwgc2l6ZT00KSsKICB4bGFiKCJTZXhvIikgKyB5bGFiKCJQcm9tZWRpbyBkZSBsaWJyb3MgcXVlIGxlZSIpKwogIHlsaW0oMCwgNSkKZ3JhZgpgYGAKCiMgRWplbXBsbyAyIHBhcmEgdW5hIHZhcmlhYmxlIG51bcOpcmljYTogRU5ETwoKKlByZWd1bnRhOiDCv2EgY3XDoW50b3MgYWx1bW5vcyBlbiBwcm9tZWRpbyBhdGllbmRlIHVuIHByb2Zlc29yIHBlcnVhbm8/IMK/RXhpc3RlbiBkaWZlcmVuY2lhcyBkZSBnw6luZXJvPyoKClVzYW5kbyBlbCBlamVtcGxvIGRlIGxhIEVORE8gMjAyMCwgbGEgaGlww7N0ZXNpcyBxdWUgc2UgcHVlZGUgZXZhbHVhciBlcyBzaSBsb3MgcHJvZmVzb3JlcyBhdGllbmRlbiBhIGRpZmVyZW50ZSBuw7ptZXJvIGRlIGFsdW1ub3MgZGUgYWN1ZXJkbyBhIHN1IHNleG8uCkNvbW8gdmltb3MgYW50ZXMsIGxhcyBjb21wYXJhY2lvbmVzIHB1bnR1YWxlcyBzdWdpZXJlbiBkaWZlcmVuY2lhcywgZG9uZGUgbG9zIGRvY2VudGVzIGhvbWJyZXMgYXRpZW5kZW4gYSBtw6FzIGFsdW1ub3MgcXVlIGxhcyBkb2NlbnRlcyBtdWplcmVzLgoKTGEgaGlww7N0ZXNpcyBjZXJvIHNlcsOtYToKCkhvOiBQcm9tZWRpbyBkZSBhbHVtbm9zIHF1ZSBhY29tcGHDsWEgdW4gZG9jZW50ZSBob21icmUgPSBQcm9tZWRpbyBkZSBhbHVtbm9zIHF1ZSBhY29tcGHDsWEgdW5hIGRvY2VudGUgbXVqZXIuCgpgYGB7ciBlbmRvLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHJpbykKZW5kbzIwMjAgPSBpbXBvcnQoImJhc2VzL0VORE9fUkVNT1RPXzIwMjAuZHRhIikKYGBgCgpMYSB2YXJpYWJsZSBQMV8xIChzZXhvIGRlbCBkb2NlbnRlKSBlc3TDoSBkZWZpbmlkYSBvcmlnaW5hbG1lbnRlIGNvbW8gdW5hIHZhcmlhYmxlIG51bcOpcmljYSAoZXN0byBzZSBwdWVkZSBjb21wcm9iYXIgY29uIGVsIGPDs2RpZ28gYHN0cihlbmRvMjAyMCRQMV8xKWAuCkVzdGEgdmFyaWFibGUsIHNpbiBlbWJhcmdvIGVzIGRlIHRpcG8gZmFjdG9yLgoKU2UgcHVlZGUgY3JlYXIgdW5hIG51ZXZhIHZhcmlhYmxlICJzZXhvIiBjb24gbGEgdmFyaWFibGUgdHJhbnNmb3JtYWRhIHkgZXRpcXVldGFkYS4KCmBgYHtyIG1lZGlhcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dmVyc2UpCmVuZG8yMDIwID0gZW5kbzIwMjAgJT4lCiAgbXV0YXRlKHNleG8gPSBmYWN0b3IoUDFfMSwgbGFiZWxzPWMoIkhvbWJyZSIsICJNdWplciIpKSkKYGBgCgpgYGB7cn0KZW5kbzIwMjAgJT4lCiAgc3VtbWFyaXplKE1lZGlhID0gbWVhbihQMV82LCBuYS5ybSA9IFQpLCAKICAgICAgICAgICAgRGVzdi5TdGQgPSBzZChQMV82LCBuYS5ybSA9IFQpKQpgYGAKCmBgYHtyfQphbHVteHNleG8gPSBlbmRvMjAyMCAlPiUKICBncm91cF9ieShzZXhvKSAlPiUKICBzdW1tYXJpemUoTWVkaWEgPSBtZWFuKFAxXzYsIG5hLnJtID0gVCksIAogICAgICAgICAgICBEZXN2LlN0ZCA9IHNkKFAxXzYsIG5hLnJtID0gVCkpCmFsdW14c2V4bwpgYGAKClNlIGVuY3VlbnRyYSBxdWUgbG9zIGRvY2VudGVzIGhvbWJyZXMgYWNvbXBhw7FhbiBhIDUyIGFsdW1ub3MgZW4gcHJvbWVkaW8sIGVuIGNvbXBhcmFjacOzbiBjb24gbGFzIGRvY2VudGVzIG11amVyZXMgcXVlIGFjb21wYcOxYW4gYSAzNCBhbHVtbm9zIGVuIHByb21lZGlvLCBlcyBkZWNpciAxOCBhbHVtbm9zIG1lbm9zIGVuIHByb21lZGlvLgoKUmVjb3JkZW1vcyBxdWUgZWwgY8OhbGN1bG8gZGVsIGludGVydmFsbyBkZSBjb25maWFuemEgZGUgdW5hIG1lZGlhIGVzOgoKJCQKSUMgPSAgXGJhcntYfSBccG0gMS45NiAqIFxmcmFje3N9IHtcc3FydHtufX0KJCQKClBhcmEgdW5hIGNvbXBhcmFjacOzbiB1c2FuZG8gbG9zIGludGVydmFsb3MgZGUgY29uZmlhbnphLCBzZSBwdWVkZSB1c2FyIGVsIGNvbWFuZG8gYGNpTWVhbmAgZGUgbGEgbGlicmVyw61hIGBsc3JgLgpFc3RlIGNvbWFuZG8gcmVncmVzYSBlbCBsw61taXRlIGluZmVyaW9yIHkgZWwgbMOtbWl0ZSBzdXBlcmlvciBkZWwgaW50ZXJ2YWxvIGRlIGNvbmZpYW56YS4KUG9yIGxvIHRhbnRvLCBwYXJhIGd1YXJkYXIgc29sbyBlbCBtw61uaW1vIHNlIHRpZW5lIHF1ZSBlc3BlY2lmaWNhciBgbHNyOjpjaU1lYW4oUDFfNiwgbmEucm09VClbMV1gIHkgcGFyYSBlbCBtw6F4aW1vIGNhbWJpYXLDrWEgYSBgWzJdYC4KCmBgYHtyfQpsaWJyYXJ5KGxzcikKZW5kbzIwMjAgJT4lCiAgc3VtbWFyaXNlKG1lZGlhID0gbWVhbihQMV82LCBuYS5ybT1UKSwKICAgICAgICAgICAgZGVzdiA9IHNkKFAxXzYsIG5hLnJtID0gVCksCiAgICAgICAgICAgIGxpbWluZiA9IGNpTWVhbihQMV82LCBuYS5ybT1UKVsxXSwKICAgICAgICAgICAgbGltc3VwID0gY2lNZWFuKFAxXzYsIG5hLnJtPVQpWzJdCiAgICAgICAgICAgICkKYGBgCgpgYGB7cn0KYWx1bXhzZXhvID0gZW5kbzIwMjAgJT4lCiAgZ3JvdXBfYnkoc2V4bykgJT4lCiAgc3VtbWFyaXNlKG1lZGlhID0gbWVhbihQMV82LCBuYS5ybT1UKSwKICAgICAgICAgICAgZGVzdiA9IHNkKFAxXzYsIG5hLnJtID0gVCksCiAgICAgICAgICAgIGxpbWluZiA9IGNpTWVhbihQMV82LCBuYS5ybT1UKVsxXSwKICAgICAgICAgICAgbGltc3VwID0gY2lNZWFuKFAxXzYsIG5hLnJtPVQpWzJdCiAgICAgICAgICAgICkKYWx1bXhzZXhvCmBgYAoKLSAgIEVsIElDIGFsIDk1JSBkZSBjb25maWFuemEsIGVsIHByb21lZGlvIGRlIGFsdW1ub3MgcXVlIGFjb21wYcOxYW4gbG9zIGRvY2VudGVzIGhvbWJyZSBlc3TDoSBlbiBlbCBzaWd1aWVudGUgaW50ZXJ2YWxvICQkNTAuNyAtIDUzLjgkJAoKLSAgIEVsIElDIGFsIDk1JSBkZSBjb25maWFuemEgZWwgcHJvbWVkaW8gZGUgYWx1bW5vcyBxdWUgYWNvbXBhw7FhbiBsYXMgZG9jZW50ZXMgbXVqZXJlcyBlc3TDoSBlbiBlbCBzaWd1aWVudGUgaW50ZXJ2YWxvICQkMzMuMyAtIDM0LjgkJAoKQ29tbyBhbWJvcyBpbnRlcnZhbG9zIE5PIHNlIHRyYXNsYXBhbiAoZWwgbWF5b3IgdmFsb3IgZGVsIHNlZ3VuZG8gSUMsIDM0LjggLCBlcyBtZW5vciBhbCBtZWpvciB2YWxvciBkZWwgcHJpbWVyIElDLCA1MC43KSwgZW50b25jZXMgc2UgcHVlZGUgYWZpcm1hciBxdWUgZXNhcyBkaWZlcmVuY2lhcyBzZSBwdWVkZW4gZXh0cmFwb2xhciBsYSBwb2JsYWNpw7NuLgoKU2kgbG9zIElDIHNlIHRyYXNsYXBhbiwgZW50b25jZXMsIG5vIHNlIHB1ZWRlIGFmaXJtYXIgcXVlIGV4aXN0YW4gZGlmZXJlbmNpYXMgZW4gZWwgbsO6bWVybyBkZSBhbHVtbm9zIHF1ZSBhY29tcGHDsWFuIGRvY2VudGVzIGhvbWJyZXMgbyBtdWplcmVzIChzZXLDrWEgdW4gImVtcGF0ZSB0w6ljbmljbyIpLgoKIyMgR3LDoWZpY28gZGUgSUMgcGFyYSBjb21wYXJhciBtZWRpYXMKClNlIHB1ZWRlIGdyYWZpY2FyIGFtYm9zIGludGVydmFsb3MgZGUgY29uZmlhbnphLgpQYXJhIGhhY2VyIGVzdG8sIHVzYXJlbW9zIGxhIHRhYmxhIHF1ZSBndWFyZGEgbG9zIGRhdG9zIGRlIGxvcyBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YS4KCkVzdGEgdGFibGEsIHNpbiBlbWJhcmdvLCB0aWVuZSB1bmEgZmlsYSBkZSByZXN1bHRhZG9zIHBhcmEgbG9zIHZhbG9yZXMgcGVyZGlkb3MuCkVzdGEgZmlsYSBubyB0aWVuZSBkYXRvcyBwb3IgZ3JhZmljYXIsIHBvciBsbyBxdWUgdGVuZW1vcyBxdWUgZWxpbWluYXJsYS4KCkxvcyBkYXRhZnJhbWVzIHNlIG9yZ2FuaXphbiBlbiBmaWxhcyB5IGNvbHVtbmFzLgpMYSB0YWJsZSAiY2lfYWx1bXhzZXhvIiB0aWVuZSAzIGZpbGFzIHkgMyBjb2x1bW5hcy4KTGEgdGVyY2VyYSBmaWxhIGVzIGxhIHF1ZSBubyB0aWVuZSBkYXRvcyBxdWUgZ3JhZmljYXIuClBhcmEgZWxpbWluYXIgc2UgdGllbmUgcXVlIGVzcGVjaWZpY2FyIGxhIHRhYmxhIHkgY29uIGxvcyBicmFja2V0cyBgW2ZpbGFzLCBjb2x1bW5hc11gIGRlZmluaXIgbG9zIGRhdG9zIGEgZWxpbWluYXIgYFstMywgXWAuClNlIGVsaW1pbmEgY29uIGVsIHNpZ25vICItIiB5IGNvbW8gbm8gaGF5IGRhdG9zIGx1ZWdvIGRlIGxhICIsIiwgc2UgaW5kaWNhIHF1ZSBubyBzZSBjYW1iaWEgbmluZ3VuYSBjb2x1bW5hLgoKYGBge3IgY2kgeCBzZXhvfQphbHVteHNleG8gPSBhbHVteHNleG9bLTMsXQphbHVteHNleG8KYGBgCgpFc3RhIHRhYmxhIHNlIHB1ZWRlIHVzYXIgcGFyYSBjcmVhciB1biBncsOhZmljbyBxdWUgY29tcGFyZSBhbWJvcyBJQyBjb24gbGEgbGlicmVyw61hIGBnZ3Bsb3QyYCB5IGNvbiBsYSBnZW9tZXRyw61hIGBnZW9tX2Vycm9yYmFyYC4KU2UgYWdyZWdhIGBnZW9tX3RleHRgIHBhcmEgaW5jbHVpciBlbCAidGV4dG8iIGNvbiBsb3MgdmFsb3JlcyBwcm9tZWRpbyBkZSBhbWJvcyBncnVwb3MuCgpgYGB7ciBncmFmaWNvMX0KbGlicmFyeShnZ3Bsb3QyKQpncmFmMSA9IGdncGxvdChhbHVteHNleG8sIGFlcyh4PXNleG8sIHk9bWVkaWEpKSsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49bGltaW5mLCB5bWF4PWxpbXN1cCksIHdpZHRoPTAuMikrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1yb3VuZChtZWRpYSwgMSkpLCB2anVzdD0tMSwgc2l6ZT00KSsKICB4bGFiKCJTZXhvIGRlbCBkb2NlbnRlIikgKyB5bGFiKCJQcm9tZWRpbyBkZSBhbHVtbm9zIikrCiAgeWxpbSgwLCA2MCkKZ3JhZjEKYGBgCgpFbiBlc3RlIGdyw6FmaWNvIHF1ZWRhIG3DoXMgY2xhcm8gcXVlIGFtYm9zIElDIG5vIHNlIHRyYXNsYXBhbiBwb3IgbG8gcXVlIHNlIHB1ZWRlIGRlY2lyIHF1ZSBzw60gZXhpc3RlbiBkaWZlcmVuY2lhcyBlbnRyZSBkb2NlbnRlcyBob21icmUgeSBtdWplcmVzIGVuIGVsIG7Dum1lcm8gZGUgYWx1bW5vcyBxdWUgYWNvbXBhw7FhbiBlbiBlbCBQZXLDui4KCkVzdGUgdGlwbyBkZSBncsOhZmljbyBlcyBiYXN0YW50ZSB1c3VhbCBlbiBsb3MgcmVwb3J0ZXMgZXN0YWTDrXN0aWNvcy4KUG9yIGVqZW1wbG8sIHNlIHB1ZWRlbiB2ZXIgZXN0ZSB0aXBvIGRlIGdyw6FmaWNvcyBlbiBsb3MgcmVwb3J0ZXMgZGUgW0VsIFB1bHNvIGRlIGxhIERlbW9jcmFjaWFdKGh0dHBzOi8vd3d3LnZhbmRlcmJpbHQuZWR1L2xhcG9wL2FiMjAyMS8yMDIxX0xBUE9QX0FtZXJpY2FzQmFyb21ldGVyXzIwMjFfUHVsc2Vfb2ZfRGVtb2NyYWN5X1NQQS5wZGYpIGRlbCBwcm95ZWN0byBMQVBPUC4KRW4gZWwgw7psdGltbyByZXBvcnRlIHBhcmEgUGVyw7ogc2UgcHJlc2VudGEgZWwgc2lndWllbnRlIGdyw6FmaWNvIHF1ZSBtdWVzdHJhIGxvcyBuaXZlbGVzIGRlIHNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEgZW50cmUgZ3J1cG9zIGRlIHNhdGlzZmFjY2nDs24gY29uIGxvcyBzZXJ2aWNpb3MgcMO6YmxpY29zLgpFc3RvcyBncsOhZmljb3Mgc29uIGNvbnN0cnVpZG9zIGRlIGxhIG1pc21hIG1hbmVyYSBxdWUgc2UgaGEgY29uc3RydWlkbyBlbCBncsOhZmljbyBkZSBhcnJpYmEuCgohW10oZ3JhZjYuNi5wbmcpe3dpZHRoPSI2MzUifQoKwr9Qb3IgcXXDqT8uCi4uCkFxdcOtIHZpZW5lIGxhIGludGVycHJldGFjacOzbiBkZWwgcG9saXTDs2xvZ28gLgoKT0pPOiBubyBzZSBkZWJlIGNvbmZ1bmRpciBlc3RlIGdyw6FmaWNvIGNvbiB1biBncsOhZmljbyBkZSBjYWphcy4KClRBUkVBOiBBbmFsaXphciBzaSBleGlzdGVuIGRpZmVyZW5jaWFzIGVuIGVsIG7Dum1lcm8gZGUgYWx1bW5vcyBlbnRyZSBkb2NlbnRlcyBjb24gZGlmZXJlbnRlcyBjb25kaWNpb25lcyBsYWJvcmFsZXMgKFAxXzcpLgoKIyBFamVtcGxvIDMgcGFyYSB1bmEgdmFyaWFibGUgbnVtw6lyaWNhOiBMQVBPUAoKYGBge3J9CmxpYnJhcnkocmlvKQpsYXBvcCA9IGltcG9ydCgiYmFzZXMvUEVSXzIwMjNfTEFQT1BfQW1lcmljYXNCYXJvbWV0ZXJfdjEuMF93LnNhdiIpCmBgYAoKIyMgRWplbXBsbyBwYXJhIHZhcmlhYmxlIG51bcOpcmljYSBjb24gw61uZGljZSBhZGl0aXZvCgpFbCBjdWVzdGlvbmFyaW8gZGUgTEFQT1AgaW5jbHV5ZSBkb3MgcHJlZ3VudGFzIHNvYnJlIGxhcyBmdWVyemFzIGRlbCBvcmRlbi4KQjEyLgrCv0hhc3RhIHF1w6kgcHVudG8gdGllbmUgdXN0ZWQgY29uZmlhbnphIGVuIGxhcyBGdWVyemFzIEFybWFkYXM/CnkgQjE4LgrCv0hhc3RhIHF1w6kgcHVudG8gdGllbmUgdXN0ZWQgY29uZmlhbnphIGVuIGxhIHBvbGljw61hIG5hY2lvbmFsPwoKQW1iYXMgcHJlZ3VudGFzIGVzdMOhbiBtZWRpZGFzIGVuIHVuYSBlc2NhbGEgZGUgMSBhIDcsIGRvbmRlIDEgc2lnbmlmaWNhICJOYWRhIiB5IDcgc2lnbmlmaWNhICJNdWNobyIuClVuYSBwZXJzb25hIHF1ZSB0ZW5nYSBkZXNjb25maWFuemEgZGUgbGFzIGZ1ZXJ6YXMgZGVsIG9yZGVuIGVuIGdlbmVyYWwsIHNlZ3VyYW1lbnRlIHJlcG9ydGFyw6EgcHVudGFqZXMgYmFqb3MgZW4gYW1iYXMgcHJlZ3VudGFzLgpQb3IgZWwgY29udHJhcmlvLCB1bmEgcGVyc29uYSBxdWUgdGVuZ2EgYWx0YSBjb25maWFuemEgZW4gbGFzIGZ1ZXJ6YXMgZGVsIG9yZGVuIGVuIGdlbmVyYWwsIHB1ZWRlIHJlcG9ydGFyIHB1bnRhamVzIGFsdG9zIGVuIGFtYmFzIHByZWd1bnRhcy4KClNlIHB1ZWRlbiBjb21iaW5hciBhbWJhcyBwcmVndW50YXMgcGFyYSBnZW5lcmFyIHVuIMOtbmRpY2UgYWRpdGl2byBkZSBjb25maWFuemEgZ2VuZXJhbCBlbiBsYXMgZnVlcnphcyBkZWwgb3JkZW4sIGNvbW8gbGEgc3VtYSBkZSBhbWJhcy4KQ29tbyBjYWRhIHByZWd1bnRhIHB1ZWRlIHNlciByZXNwb25kaWRhIGVudHJlIDEgeSA3LCBsYSBzdW1hIHB1ZWRlIHZhcmlhciBlbnRyZSAyIHkgMTQuClVuIHB1bnRhamUgZGUgMiBleHByZXNhcsOhIGxhIG3DoXMgYmFqYSBjb25maWFuemEgZW4gbGFzIGZ1ZXJ6YXMgZGVsIG9yZGVuLgpVbiBwdW50YWplIGRlIDE0LCBsYSBtw6FzIGFsdGEgY29uZmlhbnphIGVuIGxhcyBmdWVyemFzIGRlbCBvcmRlbi4KQ3VhbHF1aWVyIHB1bnRhamUgaW50ZXJtZWRpbywgZXhwcmVzYXLDoSB1bmEgY29uZmlhbnphIGludGVybWVkaWEuCgpDb21vIE5PIGVzIGludHVpdGl2byB0ZW5lciB1biDDrW5kaWNlIHF1ZSB2YXLDrWUgZW50cmUgMiB5IDE0LCBzZSBwdWVkZSByZXN0YXIgZG9zIGEgbGEgc3VtYSBwYXJhIHF1ZSBlbCDDrW5kaWNlIHZhcsOtZSBlbnRyZSAwIHkgMTIuCkNvbW8gZXN0YSB2YXJpYWNpw7NuIHRhbXBvY28gZXMgaW50dWl0aXZhLCBzZSBwdWVkZSBkaXZpZGlyIHRvZG8gZW50cmUgMTIgcGFyYSBxdWUgZWwgw61uZGljZSB2YXLDrWUgZW50cmUgMCB5IDEuCgp8ICAgfCBDb25maWFuemEgZW4gRkZBQSB8IENvbmZpYW56YSBlbiBwb2xpY8OtYSB8IENvbmZpYW56YSBnZW5lcmFsIHwgQ29uZmlhbnphIGdlbmVyYWwgLSAyIHwgKENvbmZpYW56YSBnZW5lcmFsIC0gMikgLyAxMiB8IChDb25maWFuemEgZ2VuZXJhbCAtIDIpIC8gMTJcKjEwMCB8CnwtLS0tLS0tLS0tLXw6LS0tLS0tLS0tOnw6LS0tLS0tLS0tOnw6LS0tLS0tLS0tOnw6LS0tLS0tLS0tOnw6LS0tLS0tLS0tOnw6LS0tLS0tLS0tOnwKfCBQZXJzb25hIGNvbiBtdWNoYSBkZXNjb25maWFuemEgZW4gbGFzIGZ1ZXJ6YXMgZGVsIG9yZGVuIHwgMSB8IDEgfCAyIHwgMCB8IDAgfCAwIHwKfCBQZXJzb25hIGNvbiBtdWNoYSBjb25maWFuemEgZW4gbGFzIGZ1ZXJ6YXMgZGVsIG9yZGVuIHwgNyB8IDcgfCAxNCB8IDEyIHwgMSB8IDEwMCB8CnwgUGVyc29uYSBjb24gY29uZmlhbnphIG1lZGlhIGVuIGxhcyBmdWVyemFzIGRlbCBvcmRlbiB8IDQgfCA1IHwgOSB8IDcgfCAwLjU4IHwgNTggfAp8IFBlcnNvbmEgY29uIGNvbmZpYW56YSBtZWRpYSBlbiBsYXMgZnVlcnphcyBkZWwgb3JkZW4gfCA2IHwgNCB8IDEwIHwgOCB8IDAuNjYgfCA2NiB8CgpEZSBlc3RhIG1hbmVyYSBjYWRhIHBlcnNvbmEgdGllbmUgdW4gcHVudGFqZSBxdWUgcHVlZGUgdmFyaWFyIGVudHJlIDAgeSAxLCBkZXBlbmRpZW5kbyBkZSBsYXMgcmVzcHVlc3RhcyBxdWUgZGlvIGEgY2FkYSB1bmEgZGUgbGFzIHByZWd1bnRhcyBpbmRpdmlkdWFsZXMuCgpFc3RvIHNlIHB1ZWRlIGNhbGN1bGFyIGVuIFIuCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxhcG9wID0gbGFwb3AgJT4lCiAgbXV0YXRlKGluZGljZSA9IChiMTIrYjE4LTIpLzEyKjEwMCkKYGBgCgpQb2RlbW9zIGFzdW1pciBxdWUgZXN0ZSDDrW5kaWNlIGVzIHVuYSB2YXJpYWJsZSBjdWFudGl0YXRpdmEsIHBvciBsbyBxdWUgcG9kZW1vcyBjYWxjdWxhciBsYSBtZWRpYSB5IGVsIGludGVydmFsbyBkZSBjb25maWFuemEgZGUgbGEgbWVkaWEuCgpgYGB7cn0KbGlicmFyeShsc3IpCmxhcG9wICU+JQogIHN1bW1hcmlzZShtZWRpYSA9IG1lYW4oaW5kaWNlLCBuYS5ybT1UKSwKICAgICAgICAgICAgbGltaW5mID0gY2lNZWFuKGluZGljZSwgbmEucm09VClbMV0sCiAgICAgICAgICAgIGxpbXN1cCA9IGNpTWVhbihpbmRpY2UsIG5hLnJtPVQpWzJdCiAgICAgICAgICAgICkKYGBgCgpNZWpvciBhw7puLCBwb2RlbW9zIGNhbGN1bGFyIGVsIMOtbmRpY2UgZGUgY29uZmlhbnphIGVuIGxhcyBmdWVyemFzIGRlbCBvcmRlbiBwb3IgYcOxbyBkZSBsYSBlbmN1ZXN0YS4KCmBgYHtyfQppbmRpY2V4d2F2ZSA9IGxhcG9wICU+JQogIGdyb3VwX2J5KHdhdmUpICU+JQogIHN1bW1hcmlzZShtZWRpYSA9IG1lYW4oaW5kaWNlLCBuYS5ybT1UKSwKICAgICAgICAgICAgbGltaW5mID0gY2lNZWFuKGluZGljZSwgbmEucm09VClbMV0sCiAgICAgICAgICAgIGxpbXN1cCA9IGNpTWVhbihpbmRpY2UsIG5hLnJtPVQpWzJdCiAgICAgICAgICAgICkKaW5kaWNleHdhdmUKYGBgCgpDb24gbG8gcXVlIHBvZGVtb3MgY29tcGFyYXIgZWwgw61uZGljZSBkZSBhcG95byBhIGxhcyBmdWVyemFzIGRlbCBvcmRlbiBwb3IgYcOxbyBwYXJhIHNhY2FyIGNvbmNsdXNpb25lcyBhY2VyY2EgZGUgZGlmZXJlbmNpYXMuCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpncmFmMyA9IGdncGxvdChpbmRpY2V4d2F2ZSwgYWVzKHg9d2F2ZSwgeT1tZWRpYSkpKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikrCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1saW1pbmYsIHltYXg9bGltc3VwKSwgd2lkdGg9MC4yKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXBhc3RlKHJvdW5kKG1lZGlhLCAxKSkpLCB2anVzdD0tMSwgc2l6ZT00KSsKICB4bGFiKCJBw7FvIGRlIGVuY3Vlc3RhcyIpICsgeWxhYigiw41uZGljZSBkZSBjb25maWFuemEgZW4gbGFzIGZ1ZXJ6YXMgZGVsIG9yZGVuIikrCiAgeWxpbSgwLCA2MCkKZ3JhZjMKYGBgCgojIEVqZW1wbG8gMSBwYXJhIHVuYSB2YXJpYWJsZSBjYXRlZ8OzcmljYTogRU5ETwoKU2lndWllbmRvIGNvbiBlbCBlamVtcGxvIGRlIGxhIEVORE8gMjAyMCwgbGEgaGlww7N0ZXNpcyBxdWUgc2UgcHVlZGUgZXZhbHVhciBlcyBzaSBleGlzdGVuIGRpZmVyZW5jaWFzIGVuIHNpIGxvcyBkb2NlbnRlcyBoYW4gcmVjaWJpZG8gYXBveW8gcHNpY29sw7NnaWNvIG8gZW1vY2lvbmFsIHBvciBzZXhvIChQMV8xMykuCgpMYSBoaXDDs3Rlc2lzIGNlcm8gc2Vyw61hOiBMYSBwcm9wb3JjacOzbiBkZSBkb2NlbnRlcyBxdWUgaGFuIHJlY2liaWRvIGFwb3lvIHBzaWNvbMOzZ2ljbyBlbnRyZSBkb2NlbnRlcyBob21icmVzID0gUHJvcG9yY2nDs24gZGUgZG9jZW50ZXMgcXVlIGhhbiByZWNpYmlkbyBhcG95byBwc2ljb2zDs2dpY28gZW50cmUgZG9jZW50ZXMgbXVqZXJlcy4KCkxvIHByaW1lcm8gZXMgdHJhbnNmb3JtYXIgbGEgdmFyaWFibGUgUDFfMTMgcXVlIGVzIGltcG9ydGFkYSBjb21vIG51bcOpcmljYSwgY29tbyB1bmEgdmFyaWFibGUgZGUgZmFjdG9yIHkgY29uIHN1cyBldGlxdWV0YXMuCgpgYGB7cn0KZW5kbzIwMjAgPSBlbmRvMjAyMCAlPiUKICBtdXRhdGUoYXBveW8gPSBmYWN0b3IoUDFfMTMsIGxhYmVscz1jKCJTw60iLCAiTm8iKSkpCmBgYAoKQWhvcmEgdGVuZW1vcyBxdWUgcHJvZHVjaXIgbGEgdGFibGEgZGUgZGlzdHJpYnVjacOzbiBkZSBmcmVjdWVuY2lhcy4KU2kgY2FsY3VsYW1vcyBsYXMgZnJlY3VlbmNpYXMgY29uIGBjb3VudGAgZGlyZWN0YW1lbnRlLCBlc3RhIHRhYmxhIGluY2x1aXLDrWEgdW5hIGZpbGEgZGUgbG9zIE5BcyB5IGx1ZWdvIGNhbGN1bGFyw6EgbG9zIHBvcmNlbnRhamVzIGluY2x1eWVuZG8gYSBlc3RlIGdydXBvLgpFcyBwb3IgZXN0byBxdWUgYW50ZXMgZGUgY2FsY3VsYXIgbGFzIGZyZWN1ZW5jaWFzLCB0ZW5lbW9zIHF1ZSBmaWx0cmFyIHBhcmEgcXVlIHNvbG8gY3VlbnRlIGxvcyAiU8OtIiB5ICJObyIuCkx1ZWdvIGRlIGxhcyBmcmVjdWVuY2lhcywgaW5jbHVpbW9zIGVsIHBvcmNlbnRhamUgY29uIGBtdXRhdGVgLgoKYGBge3J9CnRhYmxhID0gZW5kbzIwMjAgJT4lCiAgZmlsdGVyKGFwb3lvID09IlPDrSIgfCBhcG95byA9PSAiTm8iKSAlPiUKICBjb3VudChBcG95byA9IGFwb3lvLCBuYW1lPSJOIikgJT4lCiAgbXV0YXRlKHRvdGFsID0gc3VtKE4pLCAKICAgICAgICAgUG9yY2VudGFqZSA9IE4gLyB0b3RhbCAqIDEwMCkKdGFibGEKYGBgCgpQb3IgZWplbXBsbywgcGFyYSBoYWxsYXIgZWwgSUMgZGUgbGEgcHJvcG9yY2nDs24gZGUgYXF1ZWxsb3MgZG9jZW50ZXMgcXVlIHJlcG9ydGFyb24gaGFiZXIgcmVjaWJpZG8gYXBveW8gcHNpY29sw7NnaWNvLCBwb2RlbW9zIHVzYXIgZWwgY29tYW5kbyBgcHJvcC50ZXN0YC4KRXN0ZSBjb21hbmRvIHJlcXVpZXJlIGVsIG4gZGUgbGEgb3BjacOzbiAiU8OtIiBkZSBsYSB0YWJsYSB5IGVsIHRvdGFsIGRlIGNhc29zLgpQb3IgZGVmZWN0byBub3MgY2FsY3VsYSBlbCBJQyBhbCA5NSUgZGUgY29uZmlhbnphLgoKYGBge3J9CnByb3AudGVzdCg5NDc2LDE4OTMwKQpgYGAKClNlIGVzdGltYSBxdWUgZWwgbGEgcHJvcG9yY2nDs24gZGUgZG9jZW50ZXMgcXVlIHJlY2liaWVyb24gYXBveW8gcHNpY29sw7NnaWNvIGVzdMOhIGVudHJlIDQ5LjMlIHkgNTAuOCUuCgpMdWVnbywgcGFyYSByZXNwb25kZXIgYSBsYSBwcmVndW50YSBkZSBzaSBlc3RhIHByb3BvcmNpw7NuIHZhcsOtYSBlbnRyZSBkb2NlbnRlcyBob21icmVzIHkgbXVqZXJlcywgdGVuZW1vcyBxdWUgY3JlYXIgb3RyYSB0YWJsYSBjb24gbGFzIGZyZWN1ZW5jaWFzIHkgcG9yY2VudGFqZXMgcG9yIGNhZGEgZ3J1cG8gZGUgbGEgdmFyaWFibGUgInNleG8iLgpQYXJhIGVzdG8sIGFsIGPDs2RpZ28gYW50ZXJpb3IgbGUgYWdyZWdhbW9zIGVsIGNvbWFuZG8gYGdyb3VwX2J5YC4KCmBgYHtyfQp0YWJsYTIgPSBlbmRvMjAyMCAlPiUKICBmaWx0ZXIoYXBveW8gPT0iU8OtIiB8IGFwb3lvID09ICJObyIpICU+JQogIGdyb3VwX2J5KHNleG8pICU+JQogIGNvdW50KEFwb3lvID0gYXBveW8sIG5hbWU9Ik4iKSAlPiUKICBtdXRhdGUodG90YWwgPSBzdW0oTiksIAogICAgICAgICBQb3IgPSBOIC8gdG90YWwgKiAxMDAsCiAgICAgICAgIGVyciA9IHNxcnQoUG9yKigxMDAtUG9yKS9OKSwgCiAgICAgICAgIGxpbWluZiA9IFBvciAtIDEuOTYqZXJyLCAKICAgICAgICAgbGltc3VwID0gUG9yICsgMS45NiplcnIpCnRhYmxhMgpgYGAKCkVsIG1pc21vIGNvbWFuZG8gYHByb3AudGVzdGAgcGVybWl0ZSBoYWNlciBsYSBwcnVlYmEgcGFyYSBsYSBkaWZlcmVuY2lhIGRlIHByb3BvcmNpb25lcy4KUGFyYSBlc3RvLCBsb3MgdmFsb3JlcyB0YW50byBkZSBob21icmVzLCBjb21vIGRlIG11amVyZXMsIHNlIGNvbmNhdGVuYW4gY29uIGxhIGVzcGVjaWZpY2FjacOzbiBgYyjigKYpYCwgdGFudG8gcGFyYSBlbCBuIGRlICJTw60iIGRlIGNhZGEgZ3J1cG8sIGNvbW8gcGFyYSBlbCB0b3RhbCBkZSBjYXNvcyBkZSBjYWRhIGdydXBvLgoKYGBge3J9CnByb3AudGVzdChjKDI3NzcsIDY2OTkpLCBjKDYxNjMsMTI3NjcpKQpgYGAKClNlZ8O6biBsb3MgcmVzdWx0YWRvcywgc2UgZW5jdWVudHJhIHF1ZSBlbCA1Mi41JSBkZSBkb2NlbnRlcyBtdWplcmVzIHJlY2liaWVyb24gYXBveW8gcHNpY29sw7NnaWNvIHZlcnN1cyBlbCA0NS4xJSBkZSBkb2NlbnRlcyBob21icmVzLgpFc3RlIGNvbWFuZG8gbm8gbm9zIGJyaW5kYSBkaXJlY3RhbWVudGUgbG9zIGzDrW1pdGVzIGluZmVyaW9yIHkgc3VwZXJpb3IgZGUgbG9zIElDIGRlIGNhZGEgZ3J1cG8sIHBlcm8gbm9zIGJyaW5kYSBlbCBJQyBkZSBsYSBkaWZlcmVuY2lhIGRlIHByb3BvcmNpb25lcyBhbCA5NSUgZGUgY29uZmlhbnphLgpFc3RlIElDIGRlIGxhIGRpZmVyZW5jaWEgZGUgcHJvcG9yY2lvbmVzIHZhcsOtYSBlbnRyZSAtOC45JSB5IC01LjklLgoKQ29tbyBlc3RlIElDIHZhIHNvbG8gZW50cmUgdmFsb3JlcyBuZWdhdGl2b3M7IGVzIGRlY2lyLCBjb21vIGVsIElDIG5vIGluY2x1eWUgYWwgY2Vybywgc2UgcHVlZGUgY29uY2x1aXIgcXVlIGxhIGRpZmVyZW5jaWEgZGUgcHJvcG9yY2lvbmVzIG5vIHB1ZWRlIHNlciBjZXJvLCBwb3IgbG8gdGFudG8sIHF1ZSBleGlzdGUgdW5hIGRpZmVyZW5jaWEgZXN0YWTDrXN0aWNhbWVudGUgc2lnbmlmaWNhdGl2YSBlbiBsYXMgcHJvcG9yY2lvbmVzIGVudHJlIGFtYm9zIGdydXBvcy4KCkxhIHRhYmxhIDIgc2UgcHVlZGUgdXNhciBwYXJhIGdyYWZpY2FyLgpDb21vIG5vcyBpbnRlcmVzYSBjb21wYXJhciBsb3MgcG9yY2VudGFqZXMgZGUgZG9jZW50ZXMgcXVlIHJlcG9ydGFyb24gaGFiZXIgcmVjaWJpZG8gYXRlbmNpw7NuIHBzaWNvbMOzZ2ljYSBwb3Igc2V4bywgc2UgcHVlZGUgZWxpbWluYXIgbGFzIGZpbGFzIGRlIGFxdWVsbG9zIHF1ZSBubyByZWNpYmllcm9uIGF0ZW5jacOzbiBwc2ljb2zDs2dpY2EgZW4gbGEgdGFibGEgMi4KCmBgYHtyfQp0YWJsYTIgPSB0YWJsYTJbLWMoMiw0KSxdCmBgYAoKTHVlZ28sIGNvbiBlc3RhIHRhYmxhIHBvZGVtb3Mgc2VndWlyIGVsIG1pc21vIHByb2NlZGltaWVudG8gcXVlIGNvbiBlbCBjw6FsY3VsbyBkZSBsYXMgYmFycmFzIGRlIGVycm9yIHBhcmEgbGEgbWVkaWEsIHBlcm8gZXN0YSB2ZXogcGFyYSBsb3MgcG9yY2VudGFqZXMuCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpncmFmMiA9IGdncGxvdCh0YWJsYTIsIGFlcyh4PXNleG8sIHk9UG9yKSkrCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPWxpbWluZiwgeW1heD1saW1zdXApLCB3aWR0aD0wLjIpKwogIGdlb21fdGV4dChhZXMobGFiZWw9cGFzdGUocm91bmQoUG9yLCAxKSkpLCB2anVzdD0tMSwgc2l6ZT00KSsKICB4bGFiKCJTZXhvIGRlbCBkb2NlbnRlIikgKyB5bGFiKCJQb3JjZW50YWplIHF1ZSByZWNpYmnDsyBhdGVuY2nDs24gcHNpY29sw7NnaWNhIikrCiAgeWxpbSgwLCA2MCkKZ3JhZjIKYGBgCgpEZSBlc3RlIGdyw6FmaWNvIHNlIHB1ZWRlIGNvbmNsdWlyIHF1ZSBleGlzdGVuIGRpZmVyZW5jaWFzIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmFzIGVuIGVsIHBvcmNlbnRhamUgZGUgZG9jZW50ZXMgcXVlIGJ1c2Nhcm9uIGF0ZW5jacOzbiBwc2ljb2zDs2dpY2EgZW50cmUgaG9tYnJlcyB5IG11amVyZXMsIGRlYmlkbyBhIHF1ZSBsb3MgaW50ZXJ2YWxvcyBkZSBjb25maWFuemEgbm8gc2UgdHJhc2xhcGFuLgoKRGUgbWFuZXJhIG3DoXMgZXNwZWPDrWZpY2EsIHNlIHB1ZWRlIGFmaXJtYXIgcXVlIGxhcyBkb2NlbnRlcyBwZXJ1YW5hcyByZWNpYmVuIG3DoXMgYXRlbmNpw7NuIHBzaWNvbMOzZ2ljYSBxdWUgbG9zIGRvY2VudGVzIGhvbWJyZXMuCgojIEVqZW1wbG8gMiBwYXJhIHVuYSB2YXJpYWJsZSBjYXRlZ8OzcmljYTogTEFQT1AKCkVuIGxhIHDDoWdpbmEgMjEgZGVsIHJlcG9ydGUgKkN1bHR1cmEgcG9sw610aWNhIGRlIGxhIGRlbW9jcmFjaWEgZW4gUGVyw7ogeSBlbiBsYXMgQW3DqXJpY2FzIDIwMjE6IFRvbcOhbmRvbGUgZWwgcHVsc28gYSBsYSBkZW1vY3JhY2lhKiBzZSBwcmVzZW50YSBlbCBncsOhZmljbyBxdWUgbXVlc3RyYSBlbCBwb3JjZW50YWplIGRlIGFwb3lvIGEgbGEgZGVtb2NyYWNpYSBlbiBQZXLDuiAobMOtbmVhIG1hZ2VudGEpIGEgbG8gbGFyZ28gZGVsIHRpZW1wbywgZW4gY29tcGFyYWNpw7NuIGNvbiBBbcOpcmljYSBMYXRpbmEgKGzDrW5lYSBtb3JhZGEpLgoKRWwgYXBveW8gYSBsYSBkZW1vY3JhY2lhLCB2YXJpYWJsZSAiSU5HNCIsIGVzdMOhIG1lZGlkYSBlbiB1bmEgZXNjYWxhIGRlbCAxIGFsIDcsIGRvbmRlIDEgc2lnbmlmaWNhICJtdXkgZW4gZGVzYWN1ZXJkbyIgeSA3IHNpZ25pZmljYSAibXV5IGRlIGFjdWVyZG8iLgpFc3RhIHZhcmlhYmxlIHNlIHRpZW5lIHF1ZSByZWNvZGlmaWNhci4KRGUgYWN1ZXJkbyBhbCByZXBvcnRlICJMYXMgcmVzcHVlc3RhcyB2YW4gZGUgMSAobXV5IGVuIGRlc2FjdWVyZG8pIGEgNyAobXV5IGRlIGFjdWVyZG8pLiBQYXJhIGVzdGUgYW7DoWxpc2lzLCBzZSBjb2RpZmljYXJvbiBsYXMgcmVzcHVlc3RhcyBlbiBlbCBleHRyZW1vImRlIGFjdWVyZG8iIGRlIGxhIGVzY2FsYSAodmFsb3JlcyBxdWUgdmFuIGRlIDUgYSA3KSBjb21vIGFwb3lvIGEgbGEgZGVtb2NyYWNpYS4iIChwLjcpLgoKIVtdKGFwb3lvX3BlcnUucG5nKQoKUGFyYSByZWNvZGlmaWNhciBsYSB2YXJpYWJsZSBzZSB1c2EgZWwgc2lndWllbnRlIGPDs2RpZ28uCkVsIHJlc3VsdGFkbyBlcyB1bmEgdmFyaWFibGUgZGljb3TDs21pY2EgKDA9Tm8sIDE9U8OtKSwgcXVlIGVzIHVuYSB2YXJpYWJsZSBjYXRlZ8OzcmljYSwgYXVucXVlIGluY2x1eWUgdW4gZ3J1cG8gcXVlIG5vIHRpZW5lIHJlc3B1ZXN0YSBlbiBlc3RhIHZhcmlhYmxlIHkgZXN0w6EgY29tbyBOQXMuCgpgYGB7cn0KbGlicmFyeShkcGx5cikKbGFwb3AgPSBsYXBvcCAlPiUKICBtdXRhdGUoaW5nNHJlYz0gY2FzZV93aGVuKAogICAgaW5nNCA+PSAxICYgaW5nNCA8PSA0IH4gMCwKICAgIGluZzQgPj0gNSAmIGluZzQgPD0gNyB+IDEsCiAgICApKQpgYGAKClNlIHZlcmlmaWNhIGxhIHJlY29kaWZpY2FjacOzbi4KCmBgYHtyfQpsYXBvcCAlPiUKICBjb3VudChpbmc0LCBuYW1lPSJGcmVjdWVuY2lhIikKYGBgCgpMbyBxdWUgcXVlcmVtb3MgZXMgZW5jb250cmFyIGVsIGludGVydmFsbyBkZSBjb25maWFuemEgZGUgbGEgcHJvcG9yY2nDs24gKG8gcG9yY2VudGFqZSkgZGUgYXF1ZWxsb3MgcXVlIHJlc3BvbmRlbiAiU8OtIiAobGFzIDc3NTQgcGVyc29uYXMgY29uIHVuIDEpLgpPam8gcXVlIGxhIHRhYmxhIG11ZXN0cmEgYSAzOTMgcGVyc29uYXMgY29uIE5Bcy4KCmBgYHtyfQpsYXBvcCAlPiUKICBjb3VudChpbmc0cmVjLCBuYW1lPSJGcmVjdWVuY2lhIikKYGBgCgpZIHF1ZXJlbW9zIGNhbGN1bGFyIGVsIHBvcmNlbnRhamUgZGUgYXF1ZWxsb3MgcXVlIHJlc3BvbmRlbiAiU8OtIiBwb3IgYcOxbyBkZSBsYSBlbmN1ZXN0YS4KTGEgdmFyaWFibGUgcXVlIHJlZ2lzdHJhIGVsIGHDsW8gZGUgbGEgZW5jdWVzdGEgZXMgIndhdmUiLgpFc3RhIHZhcmlhYmxlIHNlIGNhcmdhIGNvbW8gdW5hIG51bcOpcmljYSAocG9yIGVzdGUgbW90aXZvLCBlbiBlbCBncsOhZmljbyBhbnRlcmlvciBlbCBlamUgWCBkZWwgZ3LDoWZpY28gYXBhcmVjZSBjb21vIHVuYSB2YXJpYWJsZSBjb250aW51YSkgeSBzZSB0aWVuZSBxdWUgdHJhbnNmb3JtYXIgYSB1bmEgZGUgZmFjdG9yIGxsYW1hZGEgInJvbmRhIi4KCmBgYHtyfQpsYXBvcCA9IGxhcG9wICU+JQogIG11dGF0ZShyb25kYSA9IGZhY3Rvcih3YXZlKSkKYGBgCgpTZSBjYWxjdWxhIGVsIGFwb3lvIGEgbGEgZGVtb2NyYWNpYSBwb3IgYcOxb3MuClBhcmEgZWwgY8OhbGN1bG8gZGUgZXN0YSB0YWJsYSBxdWVyZW1vcyBleGNsdWlyIGEgYXF1ZWxsb3MgcXVlIG5vIHRpZW5lbiByZXNwdWVzdGEgZW4gbGEgdmFyaWFibGUgYXBveW8gYSBsYSBkZW1vY3JhY2lhIChsb3MgMzkzIE5BcyBhbnRlcmlvcmVzKS4KRXN0byBsbyBwb2RlbW9zIGhhY2VyIGNvbiBlbCBjb21hbmRvIGBmaWx0ZXJgLCBkb25kZSBlc3BlY2lmaWNhbW9zIHF1ZSBzb2xvIHF1ZXJlbW9zIGNhbGN1bGFyIGxvcyBwb3JjZW50YWplcyBkZSBhcXVlbGxvcyBxdWUgcmVzcG9uZGllcm9uIE5vIChvIDAgZW4gbGEgdmFyaWFibGUpIHkgYXF1ZWxsb3MgcXVlIHJlc3BvbmRpZXJvbiBTw60gKG8gMSBlbiBsYSB2YXJpYWJsZSkuCgpFbiBjYWRhIGdydXBvIHNlIHF1aWVyZSBjYWxjdWxhciBlbCBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGRlIGxhIHByb3BvcmNpw7NuLgpSZWN1ZXJkZW4gcXVlIGxhIGbDs3JtdWxhIHF1ZSBzZSB0aWVuZSBxdWUgdXNhciBlcyBsYSBkZSBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YSBkZSBsYSBwcm9wb3JjacOzbi4KCkRlbnRybyBkZWwgY29tYW5kbyBgbXV0YXRlYCBjYWxjdWxhbW9zIGVsIHRvdGFsIGVuIGNhZGEgZ3J1cG8gKHRvdGFsKSwgbGEgcHJvcG9yY2nDs24gKFBvciksIGVsIGVycm9yIGVzdMOhbmRhciAoZXJyIHF1ZSBlcyBpZ3VhbCBhIGxhIHJhw616IGN1YWRyYWRhIGRlbCBwb3JjZW50YWplIHBvciAxMDAtcG9yY2VudGFqZSBlbnRyZSBOKSB5IGVsIGzDrW1pdGUgaW5mZXJpb3IgeSBzdXBlcmlvciBkZWwgaW50ZXJ2YWxvIGRlIGNvbmZpYW56YS4KCmBgYHtyfQp0YWJsYTMgPSBsYXBvcCAlPiUKICBmaWx0ZXIoaW5nNHJlYyA9PTAgfCBpbmc0cmVjID09IDEpICU+JQogIGdyb3VwX2J5KHJvbmRhKSAlPiUKICBjb3VudChBcG95byA9IGluZzRyZWMsIG5hbWU9Ik4iKSAlPiUKICBtdXRhdGUodG90YWwgPSBzdW0oTiksIAogICAgICAgICBQb3IgPSBOIC8gdG90YWwgKiAxMDAsIAogICAgICAgICBlcnIgPSBzcXJ0KFBvciooMTAwLVBvcikvTiksIAogICAgICAgICBsaW1pbmYgPSBQb3IgLSAxLjk2KmVyciwgCiAgICAgICAgIGxpbXN1cCA9IFBvciArIDEuOTYqZXJyKQp0YWJsYTMKYGBgCgpMYSB0YWJsYSBtdWVzdHJhIGxvcyBkYXRvcyBkZSBsb3MgcXVlIG5vIGFwb3lhbiBhIGxhIGRlbW9jcmFjaWEgKGZpbGFzIGRvbmRlIEFwb3lvPTApIHkgZGUgbG9zIHF1ZSBzw60gYXBveWFuIGEgbGEgZGVtb2NyYWNpYSAoZmlsYXMgZG9uZGUgQXBveW89MSkgcG9yIGNhZGEgcm9uZGEuCgpDb21vIHNvbG8gc2UgcXVpZXJlIGdyYWZpY2FyIGEgbG9zIHF1ZSBzw60gYXBveWFuIGEgbGEgZGVtb2NyYWNpYSwgc2UgZGViZW4gZWxpbWluYXIgdG9kYXMgbGFzIGZpbGFzIGltcGFyZXMuCgpgYGB7cn0KdGFibGEzID0gdGFibGEzWy1jKDEsMyw1LDcsOSwxMSwxMywxNSksXQp0YWJsYTMKYGBgCgpBaG9yYSwgdGVuZW1vcyBsb3MgZGF0b3MgcGFyYSBncmFmaWNhci4KCmBgYHtyfQpncmFmNCA9IGdncGxvdCh0YWJsYTMsIGFlcyh4PXJvbmRhLCB5PVBvcikpKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikrCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1saW1pbmYsIHltYXg9bGltc3VwKSwgd2lkdGg9MC4yKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXBhc3RlKHJvdW5kKFBvciwgMSkpKSwgdmp1c3Q9LTEsIHNpemU9NCkrCiAgeGxhYigiUm9uZGEiKSArIHlsYWIoIlBvcmNlbnRhamUgcXVlIGFwb3lhIGEgbGEgZGVtb2NyYWNpYSIpKwogIHlsaW0oMCwgNzApCmdyYWY0CmBgYAoKIyBOb3RhIGZpbmFsCgpMYSBjb21wYXJhY2nDs24gZGUgSUMsIHlhIHNlYSBjYWxjdWxhbmRvIGxvcyB2YWxvcmVzIHBhcmEgY2FkYSBncnVwbyBvIHlhIHNlYSBkZSBtYW5lcmEgZ3LDoWZpY2EsIGVzIHVuYSBwcmltZXJhIG1hbmVyYSBkZSBhbmFsaXphciBzaSBsYXMgZGlmZXJlbmNpYXMgZW50cmUgZ3J1cG9zIHNlIHB1ZWRlbiBleHRyYXBvbGFyIGEgbGEgcG9ibGFjacOzbi4KClBlcm8gZXN0YSBlcyB1bmEgbWFuZXJhICJpbmZvcm1hbCIgZGUgaGFjZXIgZXN0YSBjb21wYXJhY2nDs24uClBhcmEgZm9ybWFsaXphciBlc3RhIGNvbXBhcmFjacOzbiBleGlzdGUgdW5hIHBydWViYSBlc3RhZMOtc3RpY2EgbGxhbWFkYSBwcnVlYmEgdCBkZSBkaWZlcmVuY2lhcyBkZSBtZWRpYXMgbyBsYSBwcnVlYmEgZGUgcHJvcG9yY2lvbmVzLCBxdWUgc2UgdmVyw6FuIGVuIGxhIHNpZ3VpZW50ZSBzZXNpw7NuLgoKIyBCaWJsaW9ncmFmw61hCg==