Introducción

Las secciones anteriores correspondientes a la prueba t y a la prueba de ANOVA tratan sobre la relación de una variable numérica con una variable categórica, de tal manera que el objetivo es comparar y extrapolar las medias de la variable numérica por grupos de la variable categórica.

En esta sección veremos las relaciones bivariadas entre dos variables categóricas (o de factor en la terminología de R). Esta evaluación se hace mediante tablas cruzadas (o de contingencia) y se evalúa mediante la prueba de chi-cuadrado.

Sobre la base de datos

Los datos que vamos a usar deben citarse de la siguiente manera: Fuente: Barómetro de las Américas por el Proyecto de Opinión Pública de América Latina (LAPOP), wwww.LapopSurveys.org. Pueden descargar los datos de manera libre aquí.

En este documento se carga nuevamente una base de datos recortada, originalmente en formato SPSS (.sav). Se recomiendo limpiar el Environment antes de iniciar esta sección.

Esta base de datos se encuentra alojada en el repositorio “materials_edu” de la cuenta de LAPOP en GitHub. Mediante la librería rio y el comando import se puede importar esta base de datos desde este repositorio. Además, se seleccionan los datos de países con códigos menores o iguales a 35, es decir, se elimina las observaciones de Estados Unidos y Canadá.

library(rio) 
lapop18 <- import("https://raw.github.com/lapop-central/materials_edu/main/LAPOP_AB_Merge_2018_v1.0.sav")
lapop18 <- subset(lapop18, pais<=35)

También cargamos la base de datos de la ronda 2021.

lapop21 = import("lapop21.RData") 
lapop21 <- subset(lapop21, pais<=35)

Los votos son contados correctamente

El reporte El Pulso de la Democracia de la ronda 2021 del Barómetro de las Américas reporta los resultados de la variable COUNTFAIR1. Los votos son contados correcta y justamente. ¿Diría usted que sucede siempre, algunas veces o nunca? Se reporta el porcentaje de cada categoría por país.

Este gráfico está reportando el cruce entre una variable categórica (o de factor en el lenguaje de R) llamada “countfair” que tiene tres categorías (nunca, algunas veces y siempre) con otra variable categórica llamada “pais” que tiene 15 categorías (cada país mostrado).

Esta variable es importada por R como una de tipo numérica. Para poder trabajarla en esta sección se tiene que declararla como una variable de tipo factor usando el comando as.factor y luego se etiqueta con el comando levels.

library(haven)
lapop21$countfair1r = as.factor(lapop21$countfair1)
levels(lapop21$countfair1r) <- c("Siempre", "Algunas veces", "Nunca")
table(lapop21$countfair1r)
## 
##       Siempre Algunas veces         Nunca 
##          3477          5235          1698

Tabla cruzada de si los votos se cuentan justamente por país

Antes de replicar el gráfico, es útil ver estos resultados en forma de tabla cruzada. Esta table se puede crear con el comando table. Sin embargo, en esta tabla tenemos las frecuencias absolutas. Además, nos muestra que esta pregunta no se realizó en algunos países.

table(lapop21$pais, lapop21$countfair1r)
##     
##      Siempre Algunas veces Nunca
##   1        0             0     0
##   2        0             0     0
##   3        0             0     0
##   4        0             0     0
##   5      186           351   173
##   6      354           272    51
##   7      215           445   120
##   8      130           362   226
##   9      158           435   143
##   10     169           408   112
##   11     177           430    97
##   12     169           315   168
##   13     428           201    39
##   14     525           111    20
##   15     346           257   116
##   17     216           350   120
##   21     170           406    99
##   22       0             0     0
##   23     122           464    97
##   24     112           428   117

Para poder reproducir las frecuencias relativas tenemos que usar el comando prop.table. Este comando nos brinda por defecto los porcentajes sobre el total. Lo que queremos calcular en este caso son los porcentajes por cada fila, es decir, por cada país.

prop.table(table(lapop21$pais, lapop21$countfair1r))
##     
##          Siempre Algunas veces       Nunca
##   1  0.000000000   0.000000000 0.000000000
##   2  0.000000000   0.000000000 0.000000000
##   3  0.000000000   0.000000000 0.000000000
##   4  0.000000000   0.000000000 0.000000000
##   5  0.017867435   0.033717579 0.016618636
##   6  0.034005764   0.026128722 0.004899135
##   7  0.020653218   0.042747358 0.011527378
##   8  0.012487992   0.034774256 0.021709894
##   9  0.015177714   0.041786744 0.013736792
##   10 0.016234390   0.039193084 0.010758886
##   11 0.017002882   0.041306436 0.009317963
##   12 0.016234390   0.030259366 0.016138329
##   13 0.041114313   0.019308357 0.003746398
##   14 0.050432277   0.010662824 0.001921230
##   15 0.033237272   0.024687800 0.011143132
##   17 0.020749280   0.033621518 0.011527378
##   21 0.016330451   0.039000961 0.009510086
##   22 0.000000000   0.000000000 0.000000000
##   23 0.011719500   0.044572526 0.009317963
##   24 0.010758886   0.041114313 0.011239193

Para poder especificar que se calculen los porcentajes por fila se añade la especificación , 1 en prop.table. También se anida todo el código en el comando addmargins que nos comprueba la suma de porcentajes horizontales. Estos son los mismos porcentajes que se presentarán en el gráfico de barras de más abajo. Estos porcentajes no son iguales a los mostrados en la figura 2.5 debido a que estos cálculos no incluyen el efecto de diseño.

addmargins(prop.table(table(lapop21$pais, lapop21$countfair1r), 1)*100, 2)
##     
##         Siempre Algunas veces      Nunca        Sum
##   1                                                
##   2                                                
##   3                                                
##   4                                                
##   5   26.197183     49.436620  24.366197 100.000000
##   6   52.289513     40.177253   7.533235 100.000000
##   7   27.564103     57.051282  15.384615 100.000000
##   8   18.105850     50.417827  31.476323 100.000000
##   9   21.467391     59.103261  19.429348 100.000000
##   10  24.528302     59.216255  16.255443 100.000000
##   11  25.142045     61.079545  13.778409 100.000000
##   12  25.920245     48.312883  25.766871 100.000000
##   13  64.071856     30.089820   5.838323 100.000000
##   14  80.030488     16.920732   3.048780 100.000000
##   15  48.122392     35.744089  16.133519 100.000000
##   17  31.486880     51.020408  17.492711 100.000000
##   21  25.185185     60.148148  14.666667 100.000000
##   22                                               
##   23  17.862372     67.935578  14.202050 100.000000
##   24  17.047184     65.144597  17.808219 100.000000

Gráfico de barras de si los votos se cuentan justamente por país

De la misma manera que vimos en el módulo de variables ordinales, que se puede revisar aquí, para replicar el gráfico comparativo por país se requiere crear la tabla de contingencia entre la variable “countfair” y “pais”. Esta tabla cruzada se guarda en un objeto “count_pais”. Se debe notar que el dataframe que se crea crea una fila por cada valor de “countfair” en cada país. De esta manera tenemos 3 opciones x 20 países = 60 filas.

count_pais = as.data.frame(round(prop.table(table(lapop21$pais, lapop21$countfair1r), 1), 3)*100)
count_pais

En esta tabla se calculan los datos por cada valor de la variable “pais”, incluso cuando no se tiene datos de la variable “countfair”, debido a que la pregunta no se realizó en ese país. Por este motivo se tienen que eliminar las filas de los países en los que no se recogió esta información. Esto se hace con la especificación [-c(filas),]. Luego se crea un vector con los nombres de los países. Esta lista se repite 3 veces (15 países restantes x 3 opciones). Este vector se agrega al dataframe en una columna “pais”.

count_pais = count_pais[-c(1:4,18,21:24,38,41:44,58),]
pais = c("Nicaragua","Costa Rica", "Panamá", "Colombia", "Ecuador", "Bolivia", "Perú",
        "Paraguay", "Chile", "Uruguay", "Brasil", "Argentina", "Rep. Dom.","Jamaica", "Guyana", "Nicaragua","Costa Rica", "Panamá", "Colombia", "Ecuador", "Bolivia", "Perú",
        "Paraguay", "Chile", "Uruguay", "Brasil", "Argentina", "Rep. Dom.","Jamaica", "Guyana","Nicaragua","Costa Rica", "Panamá", "Colombia", "Ecuador", "Bolivia", "Perú",
        "Paraguay", "Chile", "Uruguay", "Brasil", "Argentina", "Rep. Dom.","Jamaica", "Guyana")
count_pais$pais = pais
count_pais

Con este dataframe “count_pais” ya tenemos los elementos para replicar el gráfico de barras apiladas. En la especificación aesse define que en el eje X se grafiquen los porcentajes, en el eje Y los países y cada barra se divida por la columna Var2.

ggplot(data=count_pais, aes(x=Freq, y=pais, fill=Var2))+
  geom_bar(stat="identity", width=0.3)+
  geom_text(aes(label=paste(Freq, "%", sep="")), color="white", 
            position=position_stack(vjust=0.5), size=2)+
  labs(x="Porcentaje", y="País", fill="Los votos se cuentan justamente",
       caption="Barómetro de las Américas por LAPOP, 2021")

Evaluación de la democracia en la práctica

Desde la página 20 del reporte El Pulso de la Democracia de la ronda 2018/19 se hace una evaluación de la democracia en la práctica. En particular, esta sección del reporte usa la variable “pn4”. Esta variable está fraseada de la siguiente manera: “En general, ¿usted diría que está muy satisfecho(a), satisfecho(a), insatisfecho(a) o muy insatisfecho(a) con la forma en que la democracia funciona en (país)?”

En el reporte se indica que esta variable se recodifica como una variable dicotómica para poder trabajar con porcentajes. En esta sección vamos a trabajar con la variable original, que es una variable categórica (o de factor) ordinal.

En el Gráfico 1.14 del reporte se presenta una evaluación de la satisfacción con la democracia por variables demográficas y socioeconómicas, como nivel educativo, quintiles de riqueza, lugar de residencia, género o grupos de edad. Es decir, se usa la satisfacción con la democracia como variable dependiente y a cada variable demográfica o socioeconómica como variable independiente.

Por ejemplo, se reporta que entre los hombres, el 42.3% están satisfechos con la democracia (usando la variable recodificada como dummy), mientras que entre las mujeres, este porcentaje disminuye a 36.9%. Aquí vamos a analizar estas mismas variables, pero usando la variable “pn4” en su forma original (como categórica ordinal). Antes de proceder, tenemos que recodificar las variables en forma de factor y etiquetarlas.

lapop18$genero <- as.factor(lapop18$q1)
levels(lapop18$genero) <- c("Hombre", "Mujer")
table(lapop18$genero)
## 
## Hombre  Mujer 
##  13943  14084

Se hace lo mismo para la variable “pn4” que se transforma en una nueva variable “satis”.

lapop18$satis <- as.factor(lapop18$pn4)
levels(lapop18$satis) <- c("Muy satisfecho", "Satisfecho", "Insatisfecho", "Muy insatisfecho")
table(lapop18$satis)
## 
##   Muy satisfecho       Satisfecho     Insatisfecho Muy insatisfecho 
##             1727             8916            12455             3855

Tabla cruzada de satisfacción con la democracia según género

Con las nuevas variables de factor, lo primero es calcular la tabla cruzada o de contingencia. El comando table sirve para presentar las frecuencias de una o del cruce de dos variables. Por convención, la variable dependiente “satisfacción con la democracia” se ubica en las filas y la variable independiente “género” en las columnas.

table(lapop18$satis, lapop18$genero)
##                   
##                    Hombre Mujer
##   Muy satisfecho      919   803
##   Satisfecho         4821  4091
##   Insatisfecho       5994  6457
##   Muy insatisfecho   1874  1979

Para calcular las frecuencias relativas, se tiene que anidar el comando table dentro del comando prop.table. Si se anida solamente, este comando calcula las proporciones sobre el total de observaciones.

prop.table(table(lapop18$satis, lapop18$genero))
##                   
##                        Hombre      Mujer
##   Muy satisfecho   0.03411538 0.02980919
##   Satisfecho       0.17896652 0.15186725
##   Insatisfecho     0.22251095 0.23969857
##   Muy insatisfecho 0.06956715 0.07346499

Estas proporciones no son de mucha utilidad para la comparación que queremos hacer. Lo que requerimos son las distribuciones condicionales de “satisfacción con la democracia” por cada grupo de género. Es decir, calcular los porcentajes por cada columna. Para que prop.table calcule estas proporciones, se tiene que agregar la especificación (…, 2). Se multiplica por 100 para pasar de proporciones a porcentajes. También se puede anidar todo dentro del comando addmargins para verificar la suma de proporciones sobre las columnas, con la especificación (…, 1).

addmargins(prop.table(table(lapop18$satis, lapop18$genero), 2)*100, 1)
##                   
##                        Hombre      Mujer
##   Muy satisfecho     6.753380   6.024006
##   Satisfecho        35.427690  30.690173
##   Insatisfecho      44.047619  48.439610
##   Muy insatisfecho  13.771311  14.846212
##   Sum              100.000000 100.000000

En la tabla se muestra que el 6.8% de los hombres se encuentra muy satisfecho con la democracia, un porcentaje muy similar al de las mujeres. El 44% de los hombres se encuentra insatisfecho con la democracia. En esta categoría, las mujeres tienen un porcentaje mayor (48.4%).

De esta manera, se puede comparar los porcentajes de la variable dependiente “satisfacción con la democracia” por cada categoría de la variable independiente “género”.

Gráficos de satisfacción con la democracia según género

En la sección sobre Descriptivos de variables ordinales se presentó un adelanto de lo que estamos viendo en esta sección. Se crearon tablas cruzadas y gráficos de dos variables. Aquí volveremos a visitar esos temas, usando el tidyverse.

Para hacer el gráfico, lo primero que se tiene que crear es un nuevo dataframe con los datos del cruce de variables. Se usa el comando as.data.frame para transformar la tabla bivariada en un nuevo dataframe llamado “tabla”. Usando este comando, los resultados se ordenan por nuevas columnas (Var1, Var2 y Freq) de forma que pueden usarse para crear un gráfico.

tabla <- as.data.frame(prop.table(table(lapop18$satis, lapop18$genero), 2)*100)
tabla

Usaremos la librería ggplot2 y el comando ggplot para crear un gráfico de barras, usando el dataframe “tabla” que contiene los porcentajes de satisfacción con la democracia para hombres y mujeres. El comando requiere una estética donde se especifica que en el eje X se incluirá la “Var1”, que corresponde a las categorías de satisfacción con la democracia. En el eje Y se incluye la “Freq”, que corresponde a los porcentajes. Se incluye también la especificación fill para indicar que se dividirá en grupos Hombre/Mujer por cada categoría de “Var1” y ymax para especificar el límite superior del eje Y.

Luego de definir las variables en los ejes, se indica que se quiere un gráfico de barras con el comando geom_bar y con la especificación position="dodge" se indica que se quiere un gráfico con barras separadas por cada combinación de categorías de las variables. Se agrega la especificación stat="identity" para indicar que el comando trabaje con los datos de la tabla.

Con el comando geom_text se incluye los porcentajes de cada barra, que se encuentra en la columna “Freq”. Estos porcentajes se redondean con round a 1 decimal y se añade el símbolo “%” con paste. También se incluye la especificación position=position_dodge(…) que ubica estos porcentajes arriba de cada columna. La opción por defecto dentro de esta especificación es width=NULL, pero de esta manera los porcentajes quedarían mal ubicados, por esto se define width=0.9 para centrar los porcentajes.

Por defecto la leyenda incluye el nombre de la columna con los datos de género, que es “Var2”. Para cambiar este nombre, se usa el comando labs(fill="Género") para nombrar adecuadamente la leyenda. Finalmente, se etiqueta el eje Y y X con ylab y xlab.

library(ggplot2)
ggplot(data=tabla, aes(x=Var1, y=Freq, fill=Var2, ymax=60))+
  geom_bar(position="dodge", stat="identity")+
  geom_text(aes(label=paste(round(Freq, 1), "%", sep="")),
            position=position_dodge(width=0.9), vjust=-0.25)+
  labs(fill="Género")+
  ylab("Porcentaje")+
  xlab("Satisfacción con la democracia")

Otra forma de mostrar estos datos es mediante barras apiladas. Es decir, por cada categoría de género se muestra la distribución de satisfacción con la democracia. Para esto, usamos el mismo comando ggplot pero ahora se cambia el orden de las variables en la estética. Ahora la variable “Var2” (con las categorías de género) se ubica en el eje X y cada barra se divide de acuerdo a los valores de Var1.

El tipo de barra cambia en el comando geom_bar a position="stack". De la misma manera, las etiquetas de datos tienen que considerar que la posición de cada sector, con position=position_stack().

ggplot(data=tabla, aes(x=Var2, y=Freq, fill=Var1, ymax=100))+
  geom_bar(position="stack", stat="identity")+
  geom_text(aes(label=paste(round(Freq, 1), "%", sep="")),
            position=position_stack(), vjust=2)+
  labs(fill="Satisfacción con la democracia")+
  ylab("Porcentaje")+
  xlab("Género")

Tabla cruzada de satisfacción con la democracia según nivel educativo

El Gráfico 1.14 del reporte muestra los datos de satisfacción con la democracia (según la variable recodificada dummy) por niveles educativo. Como segundo ejemplo, aquí vamos a replicar esa relación usando la variable original de tipo factor.

Lo primero es recodificar la variable educación. La variable original “ed” está recogida como una variable numérica (años de estudio). Esta variable tiene valores que van desde 0 a 18. Se recodifica de tal manera que aquellos con cero años de educación se les asigna el valor de 0 “Ninguna”, aquellos entre 1 y 6 años de educación se les asigna el valor 1 “Primaria”, aquellos entre 7 y 11 años de educación se les asigna el valor de 2 “Secundaria” y entre 12 y 18 años de educación el valor de 3 “Superior”.

library(car)
lapop18$educ <- car::recode(lapop18$ed, "0=0; 1:6=1; 7:11=2; 12:18=3")
lapop18$educ <- as.factor(lapop18$educ)
levels(lapop18$educ) <- c("Ninguna", "Primaria", "Secundaria", "Superior")
table(lapop18$educ)
## 
##    Ninguna   Primaria Secundaria   Superior 
##        643       6156      10176      10595

Con la variable recodificada se puede calcular la tabla cruzada de satisfacción con la democracia según niveles educativos.

addmargins(prop.table(table(lapop18$satis, lapop18$educ), 2)*100, 1)
##                   
##                       Ninguna   Primaria Secundaria   Superior
##   Muy satisfecho    13.818182   9.874826   6.002645   4.324428
##   Satisfecho        38.363636  34.961752  33.045071  31.760523
##   Insatisfecho      34.363636  42.576495  46.596805  48.596963
##   Muy insatisfecho  13.454545  12.586926  14.355479  15.318086
##   Sum              100.000000 100.000000 100.000000 100.000000

Para crear el gráfico se tiene que guardar la tabla como un dataframe. Se usa el comando as.data.frame para salvar los porcentajes y poder usarlos con el comando ggplot.

tabla2 <- as.data.frame(prop.table(table(lapop18$satis, lapop18$educ), 2)*100)
tabla2

En este caso, como tenemos 4 categorías para satisfacción con la democracia y otras 4 para niveles educativo, un gráfico de barras separadas crearía 16 barras, lo que complicaría la comparación. Por eso, en este caso, se prefiere el tipo de barras apiladas.

library(ggplot2)
ggplot(data=tabla2, aes(x=Var2, y=Freq, fill=Var1, ymax=100))+
  geom_bar(position="stack", stat="identity")+
  geom_text(aes(label=paste(round(Freq, 1), "%", sep="")),
            position=position_stack(), vjust=2)+
  labs(fill="Satisfacción con la democracia")+
  ylab("Porcentaje")+
  xlab("Nivel educativo")

En el Gráfico 1.14 se observa que se tiene un mayor porcentaje de satisfacción con la democracia entre los menos educados. Esta relación también puede observarse en este gráfico. Los sectores “muy satisfechos” (en rosado) y “satisfechos” (en verde) disminuyen a medida que se pasa de ninguna a primaria, secundaria y superior.

En todos los ejemplos que se han mostrado, se pueden observar diferencias porcentuales en una variable por categorías de otra variable. Estos porcentajes se pueden comparar directamente, pero para formalizar si existe una relación estadística entre ambas variables se tiene que correr una prueba de significancia.

Prueba de independencia de chi-cuadrado

Se dice que dos variables categóricas con estadísticamente independientes si las distribuciones condicionales (poblacionales) son idénticas por cada categoría de la variable independiente En la relación bivariada anterior, esto significa que ser hombre o mujer no cambia las opiniones con respecto a la satisfacción con la democracia. A medida que estas distribuciones condicionales difieren más entre sí, se dice que ambas variables están más relacionadas o son más dependientes.

Esta evaluación se hace mediante la prueba de independencia de chi-cuadrado o de \(\chi^2\). Esta prueba se basa en la comparación de las frecuencias observadas (las observaciones que se recoge en campo) versus las frecuencias esperadas (las observaciones que deberían haber en cada celda si las variables fueran independientes). El estadístico de la prueba resume qué tan cerca están las frecuencias esperadas de las frecuencias observadas.

\[ \chi^2 = \sum\frac{(f_o-f_e)^2}{f_e} \]

Mientras más pequeña la distancia en cada celda, menos probabilidad de rechazar la hipótesis nula. Mientras la distancia sea más grande en cada celda, mas probabilidades de rechazar la hipótesis nula.

\[ H0: f_o = f_e \]

Con el valor de \(\chi^2\) y con los grados de libertad (filas-1*columnas-1), se calcula un p-value en la distribución de chi-cuadrado. Si este p-value es menor de 0.05, se rechaza la H0. Esta prueba requiere que haya al menos 5 observaciones en cada celda.

Los votos se cuentan justamente por país

En R se usa el comando chisq.test para calcular el estadístico y el p-value asociado. Esta prueba se puede guardar en un nuevo objeto “prueba1”.

prueba1 <- chisq.test(lapop21$countfair1r, lapop21$pais)
prueba1
## 
##  Pearson's Chi-squared test
## 
## data:  lapop21$countfair1r and lapop21$pais
## X-squared = 1691.6, df = 28, p-value < 2.2e-16

El p-value obtenido es menor de 0.05, por lo que se rechaza la H0, con lo que decimos que las frecuencias observadas parecen ser diferentes de las frecuencias esperadas que hubieran en cada celda si no hubiera relación, por lo que decimos que hay una relación entre las variables o que hay una dependencia entre ambas.

Es importante notar que “prueba” es un objeto de tipo lista. Este tipo de objeto puede almacenar otra información de diferente tipo. Por ejemplo, “prueba” guarda las tablas de frecuencias observadas (mismo resultado que con el comando table) y de frecuencias esperadas. En este objeto también se guarda el valor de los residuales, los residuos estandarizados y el valor del p-value.

prueba1$observed
##                    lapop21$pais
## lapop21$countfair1r   5   6   7   8   9  10  11  12  13  14  15  17  21  23  24
##       Siempre       186 354 215 130 158 169 177 169 428 525 346 216 170 122 112
##       Algunas veces 351 272 445 362 435 408 430 315 201 111 257 350 406 464 428
##       Nunca         173  51 120 226 143 112  97 168  39  20 116 120  99  97 117
prueba1$expected
##                    lapop21$pais
## lapop21$countfair1r        5        6        7        8        9       10
##       Siempre       237.1441 226.1219 260.5245 239.8161 245.8282 230.1300
##       Algunas veces 357.0461 340.4510 392.2478 361.0692 370.1210 346.4856
##       Nunca         115.8098 110.4271 127.2277 117.1147 120.0507 112.3844
##                    lapop21$pais
## lapop21$countfair1r       11       12       13       14       15       17
##       Siempre       235.1401 217.7718 223.1159 219.1078 240.1501 229.1280
##       Algunas veces 354.0288 327.8790 335.9251 329.8905 361.5720 344.9769
##       Nunca         114.8311 106.3493 108.9591 107.0017 117.2778 111.8951
##                    lapop21$pais
## lapop21$countfair1r       21       23       24
##       Siempre       225.4539 228.1259 219.4418
##       Algunas veces 339.4452 343.4683 330.3934
##       Nunca         110.1009 111.4058 107.1648

Para evaluar la fuerza de la relación, se usa la librería vcd que cuenta con el comando assocstats que nos ofrece una serie de medidas de asociación adecuadas para el cruce entre una variable ordinal como “countfair1” y una variable nominal como “pais”.

El comando assocstats no puede calcular las medidas de asociación si se tiene celdas en la tabla cruzada con valores de cero. Como se tiene algunos países donde no se hizo la pregunta “countfair1” entonces se tiene que indicar que no se use las observaciones de esos países. Para esto creamos una nueva variable de país, donde las observaciones de estos países se ponen como NAs.

lapop21$pais_r = lapop21$pais
lapop21$pais_r[lapop21$pais==1] = NA
lapop21$pais_r[lapop21$pais==2] = NA
lapop21$pais_r[lapop21$pais==3] = NA
lapop21$pais_r[lapop21$pais==4] = NA
lapop21$pais_r[lapop21$pais==22] = NA

Con esta nueva variable se puede crear la tabla cruzada entre “countfair1” y “pais” y calcular las medidas de asociación.

library(vcd)
tabla3 <- table(lapop21$countfair1r, lapop21$pais_r)
assocstats(tabla3)
##                     X^2 df P(> X^2)
## Likelihood Ratio 1639.2 28        0
## Pearson          1691.6 28        0
## 
## Phi-Coefficient   : NA 
## Contingency Coeff.: 0.374 
## Cramer's V        : 0.285

El comando assocstats nos brinda el coeficiente de contingencia y la V de Cramer como medidas. Estas medidas varían entre 0 y 1. Mientras más cercano a cero, se asume que la relación es más débil. Por el contrario, mientras más cercano a 1, se asume que la relación es más fuerte.

Por convención se asume que se tiene relaciones débiles con valores entre 0 y 0.3, relaciones moderadas con valores entre 0.3 y 0.6 y relaciones fuertes con valores mayores a 0.6. En este caso, podemos indicar que la relación entre si los votos se cuentan justamente y país es débil.

Satisfacción con la democracia según educación

Para comprobar la relación entre la satisfacción con la democracia y el género, también se puede usar la prueba de independencia de \(\chi^2\). Esta evaluación se guarda en un objeto “prueba2”.

prueba2 <- chisq.test(lapop18$satis, lapop18$educ)
prueba2
## 
##  Pearson's Chi-squared test
## 
## data:  lapop18$satis and lapop18$educ
## X-squared = 312.2, df = 9, p-value < 2.2e-16

Nuevamente se obtiene un p-value menor de 0.05, con lo que se rechaza la hipótesis nula y se afirma que las frecuencias observadas son diferentes de las esperadas, con lo que concluimos que existiría una relación de dependencia entre las variables.

Para evaluar la fuerza de la relación se usa la librería oii que cuenta con el comando association.measures que nos brinda una serie de medidas de asociación adecuadas para el tipo de variables que se están relacionando, que son ambas de tipo ordinal.

library(oii)
association.measures(lapop18$satis, lapop18$educ)
## Chi-square-based measures of association:
##    Phi:                      0.108 
##    Contingency coefficient:  0.108 
##    Cramer's V:               0.063 
## 
## Ordinal measures of association:
##    Total number of pairs:   352092916 
##    Concordant pairs:        84356625   ( 23.96 %)
##    Discordant pairs:        68163337   ( 19.36 %)
##    Tied on first variable:  80445182   ( 22.85 %)
##    Tied on second variable: 77098765   ( 21.9 %)
##    Tied on both variables:  42029007   ( 11.94 %)
## 
##    Goodman-Kruskal Gamma: 0.106 
##    Somers' d (col dep.):  0.071 
##    Kendall's tau-b:       0.070 
##    Stuart's tau-c:        0.061

En este caso se observan las medidas de asociación para variables ordinales. Este comando reporta 4 se estas medidas, todas ellas varían entre -1 a +1. En nuestro ejemplo, todas tiene signo positivo, lo que indica una relación directa entre ambas variables. Esto parecería ir contra lo que se reporta en el Gráfico 1.14 del reporte donde se observa claramente que la satisfacción con la democracia disminuye a niveles educativos más altos, lo que se expresaría en un signo negativo.

Esta aparente contradicción es debido a la forma como se ha codificado la satisfacción con la democracia (variable “satis” que se crea desde “pn4”). La variable original tiene valores entre 1 a 4, donde 1 significa “muy satisfecho” y 4 “muy insatisfecho”. Es decir, esta variable tiene una codificación donde valores altos indican “menos” de la variable. Es por ese motivo que la prueba de asociación resulta con un signo positivo, que en este caso indicaría que un valor mayor de la variable de educación significa “más” de la variable satisfacción con la democracia (que en realidad es menos).

Para evitar esta confusión se debió cambiar la monotonía de la variable satisfacción con la democracia para que valores más altos indiquen una mayor satisfacción y, con esto, se obtenga un signo negativo en las medidas de asociación. En esta sección se ha procedido de esa manera para llamar la atención a que la codificación tiene consecuencias en los resultados y puede llevar a confusión si no se presta atención.

Finalmente, el valor de las medidas de asociación son menores a 0.3, con lo que se indica que la relación entre las variables es débil.

Resumen

En esta sección hemos trabajado con relaciones bivariadas entre variables categóricas. Se ha calculado las tablas cruzadas y los gráficos de barras para mostrar los resultados descriptivos. Luego, se ha trabajado con la prueba de independencia de chi-cuadrado para inferir si existe una relación de dependencia entre las variables en la población y finalmente se evalúa la fuerza de la asociación entre las variables, diferenciando cuando se trata de variables nominales u ordinales.

Cálculos incluyendo el efecto de diseño

En la sección sobre descriptivos de variables ordinales se procedió a calcular los porcentajes de si los votos se cuentan justamente por país incorporando el efecto de diseño. Con estos datos, se procedió a replicar exactamente el gráfico 2.5.

Para calcular la prueba chi cuadrado, incluyendo el factor de expansión, se puede usar la librería survey y el comando svychisq.

library(survey)
diseno18<-svydesign(ids = ~upm, strata = ~estratopri, weights = ~weight1500, nest=TRUE, data=lapop18)

Se calcula la tabla de contingencia con el comando svytable. En este caso cruzando satisfacción con la democracia por género. Este comando se anida dentro de prop.table para presentar las frecuencias relativas y no las absolutas. A su vez, todo esto se vuelve a anidar dentro del comando addmargins para presentar las frecuencias relativas como porcentajes. De la misma manera que más arriba, esta tabla se puede guardar en un objeto para luego graficar estos resultados.

addmargins(prop.table(svytable(~satis+genero, design=diseno18),2)*100,1)
##                   genero
## satis                  Hombre      Mujer
##   Muy satisfecho     6.777875   6.025175
##   Satisfecho        35.341585  30.695022
##   Insatisfecho      44.119892  48.450745
##   Muy insatisfecho  13.760648  14.829058
##   Sum              100.000000 100.000000

La prueba de independencia de Chi-cuadrado incorporando el efecto de diseño se calcula usando el comando svychisq. Se incluya la variable dependiente, la independiente y el objeto con el diseño muestral.

prueba3 =svychisq(~satis+genero,diseno18)
prueba3
## 
##  Pearson's X^2: Rao & Scott adjustment
## 
## data:  svychisq(~satis + genero, diseno18)
## F = 28.172, ndf = 2.9969, ddf = 3985.8861, p-value < 2.2e-16

Los resultados muestran un p-value menor a 0.05, por lo que se puede rechazar la H0 de igualdad de frecuencias esperadas con observadas, por lo que se concluye que existe una relación de dependencia estadística entre ambas variables.

Se puede calcular los valores observados y esperados. Como se puede ver, los valores esperados difieren de los resultados sin el efecto de diseño.

prueba3$observed
##                   genero
## satis                 Hombre     Mujer
##   Muy satisfecho    960.0493  836.1461
##   Satisfecho       5005.9443 4259.7143
##   Insatisfecho     6249.3440 6723.7720
##   Muy insatisfecho 1949.1214 2057.9086
prueba3$expected
##                   genero
## satis                 Hombre     Mujer
##   Muy satisfecho    907.2868  888.9086
##   Satisfecho       4680.2311 4585.4274
##   Insatisfecho     6552.9267 6420.1893
##   Muy insatisfecho 2024.0144 1983.0156

En este caso no se cuenta con un comando para poder calcular las medidas de asociación incorporando el efecto de diseño. Se pueden tomar las medidas de asociación no ponderados como valores referenciales.

LS0tCnRpdGxlOiAiVGFibGFzIGNydXphZGFzIGNvbiBlbCBCYXLDs21ldHJvIGRlIGxhcyBBbcOpcmljYXMiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIHRvY19kZXB0aDogMQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IGZsYXRseQogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBzZWxmX2NvbnRhaW5lZDogbm8KICAgIGtlZXBfbWQ6IHllcwplZGl0b3Jfb3B0aW9uczogCiAgbWFya2Rvd246IAogICAgd3JhcDogc2VudGVuY2UKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSwgY2FjaGU9VFJVRSkKYGBgCgpgYGB7Y3NzIGNvbG9yLCBlY2hvPUZBTFNFfQouY29sdW1ucyB7ZGlzcGxheTogZmxleDt9CmgxIHtjb2xvcjogIzMzNjZDQzt9CmBgYAoKIyBJbnRyb2R1Y2Npw7NuCgpMYXMgc2VjY2lvbmVzIGFudGVyaW9yZXMgY29ycmVzcG9uZGllbnRlcyBhIGxhIFtwcnVlYmEgdF0oaHR0cHM6Ly9hcnR1cm9tYWxkb25hZG8uZ2l0aHViLmlvL0Jhcm9tZXRyb0VkdV9XZWIvcHJ1ZWJhdC5odG1sKSB5IGEgbGEgcHJ1ZWJhIGRlIFtBTk9WQV0oaHR0cHM6Ly9hcnR1cm9tYWxkb25hZG8uZ2l0aHViLmlvL0Jhcm9tZXRyb0VkdV9XZWIvYW5vdmEuaHRtbCkgdHJhdGFuIHNvYnJlIGxhIHJlbGFjacOzbiBkZSB1bmEgdmFyaWFibGUgbnVtw6lyaWNhIGNvbiB1bmEgdmFyaWFibGUgY2F0ZWfDs3JpY2EsIGRlIHRhbCBtYW5lcmEgcXVlIGVsIG9iamV0aXZvIGVzIGNvbXBhcmFyIHkgZXh0cmFwb2xhciBsYXMgbWVkaWFzIGRlIGxhIHZhcmlhYmxlIG51bcOpcmljYSBwb3IgZ3J1cG9zIGRlIGxhIHZhcmlhYmxlIGNhdGVnw7NyaWNhLgoKRW4gZXN0YSBzZWNjacOzbiB2ZXJlbW9zIGxhcyByZWxhY2lvbmVzIGJpdmFyaWFkYXMgZW50cmUgZG9zIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMgKG8gZGUgZmFjdG9yIGVuIGxhIHRlcm1pbm9sb2fDrWEgZGUgUikuCkVzdGEgZXZhbHVhY2nDs24gc2UgaGFjZSBtZWRpYW50ZSB0YWJsYXMgY3J1emFkYXMgKG8gZGUgY29udGluZ2VuY2lhKSB5IHNlIGV2YWzDumEgbWVkaWFudGUgbGEgcHJ1ZWJhIGRlIGNoaS1jdWFkcmFkby4KCiMgU29icmUgbGEgYmFzZSBkZSBkYXRvcwoKTG9zIGRhdG9zIHF1ZSB2YW1vcyBhIHVzYXIgZGViZW4gY2l0YXJzZSBkZSBsYSBzaWd1aWVudGUgbWFuZXJhOiBGdWVudGU6IEJhcsOzbWV0cm8gZGUgbGFzIEFtw6lyaWNhcyBwb3IgZWwgUHJveWVjdG8gZGUgT3BpbmnDs24gUMO6YmxpY2EgZGUgQW3DqXJpY2EgTGF0aW5hIChMQVBPUCksIHd3d3cuTGFwb3BTdXJ2ZXlzLm9yZy4KUHVlZGVuIGRlc2NhcmdhciBsb3MgZGF0b3MgZGUgbWFuZXJhIGxpYnJlIFthcXXDrV0oaHR0cDovL2RhdGFzZXRzLmFtZXJpY2FzYmFyb21ldGVyLm9yZy9kYXRhYmFzZS9sb2dpbi5waHApLgoKRW4gZXN0ZSBkb2N1bWVudG8gc2UgY2FyZ2EgbnVldmFtZW50ZSB1bmEgYmFzZSBkZSBkYXRvcyByZWNvcnRhZGEsIG9yaWdpbmFsbWVudGUgZW4gZm9ybWF0byBTUFNTICguc2F2KS4KU2UgcmVjb21pZW5kbyBsaW1waWFyIGVsIEVudmlyb25tZW50IGFudGVzIGRlIGluaWNpYXIgZXN0YSBzZWNjacOzbi4KCkVzdGEgYmFzZSBkZSBkYXRvcyBzZSBlbmN1ZW50cmEgYWxvamFkYSBlbiBlbCByZXBvc2l0b3JpbyAibWF0ZXJpYWxzX2VkdSIgZGUgbGEgY3VlbnRhIGRlIExBUE9QIGVuIEdpdEh1Yi4KTWVkaWFudGUgbGEgbGlicmVyw61hIHJpbyB5IGVsIGNvbWFuZG8gaW1wb3J0IHNlIHB1ZWRlIGltcG9ydGFyIGVzdGEgYmFzZSBkZSBkYXRvcyBkZXNkZSBlc3RlIHJlcG9zaXRvcmlvLgpBZGVtw6FzLCBzZSBzZWxlY2Npb25hbiBsb3MgZGF0b3MgZGUgcGHDrXNlcyBjb24gY8OzZGlnb3MgbWVub3JlcyBvIGlndWFsZXMgYSAzNSwgZXMgZGVjaXIsIHNlIGVsaW1pbmEgbGFzIG9ic2VydmFjaW9uZXMgZGUgRXN0YWRvcyBVbmlkb3MgeSBDYW5hZMOhLgoKYGBge3IgYmFzZX0KbGlicmFyeShyaW8pIApsYXBvcDE4IDwtIGltcG9ydCgiaHR0cHM6Ly9yYXcuZ2l0aHViLmNvbS9sYXBvcC1jZW50cmFsL21hdGVyaWFsc19lZHUvbWFpbi9MQVBPUF9BQl9NZXJnZV8yMDE4X3YxLjAuc2F2IikKbGFwb3AxOCA8LSBzdWJzZXQobGFwb3AxOCwgcGFpczw9MzUpCmBgYAoKVGFtYmnDqW4gY2FyZ2Ftb3MgbGEgYmFzZSBkZSBkYXRvcyBkZSBsYSByb25kYSAyMDIxLgoKYGBge3IgYmFzZTIxfQpsYXBvcDIxID0gaW1wb3J0KCJsYXBvcDIxLlJEYXRhIikgCmxhcG9wMjEgPC0gc3Vic2V0KGxhcG9wMjEsIHBhaXM8PTM1KQpgYGAKCiMgTG9zIHZvdG9zIHNvbiBjb250YWRvcyBjb3JyZWN0YW1lbnRlCgpFbCByZXBvcnRlICpFbCBQdWxzbyBkZSBsYSBEZW1vY3JhY2lhKiBkZSBsYSByb25kYSAyMDIxIGRlbCBCYXLDs21ldHJvIGRlIGxhcyBBbcOpcmljYXMgcmVwb3J0YSBsb3MgcmVzdWx0YWRvcyBkZSBsYSB2YXJpYWJsZSAqKkNPVU5URkFJUjEuKiogTG9zIHZvdG9zIHNvbiBjb250YWRvcyBjb3JyZWN0YSB5IGp1c3RhbWVudGUuCsK/RGlyw61hIHVzdGVkIHF1ZSBzdWNlZGUgc2llbXByZSwgYWxndW5hcyB2ZWNlcyBvIG51bmNhPwpTZSByZXBvcnRhIGVsIHBvcmNlbnRhamUgZGUgY2FkYSBjYXRlZ29yw61hIHBvciBwYcOtcy4KCkVzdGUgZ3LDoWZpY28gZXN0w6EgcmVwb3J0YW5kbyBlbCBjcnVjZSBlbnRyZSB1bmEgdmFyaWFibGUgY2F0ZWfDs3JpY2EgKG8gZGUgZmFjdG9yIGVuIGVsIGxlbmd1YWplIGRlIFIpIGxsYW1hZGEgImNvdW50ZmFpciIgcXVlIHRpZW5lIHRyZXMgY2F0ZWdvcsOtYXMgKG51bmNhLCBhbGd1bmFzIHZlY2VzIHkgc2llbXByZSkgY29uIG90cmEgdmFyaWFibGUgY2F0ZWfDs3JpY2EgbGxhbWFkYSAicGFpcyIgcXVlIHRpZW5lIDE1IGNhdGVnb3LDrWFzIChjYWRhIHBhw61zIG1vc3RyYWRvKS4KCiFbXShGaWd1cmUyLjUucG5nKXt3aWR0aD0iNjI1In0KCkVzdGEgdmFyaWFibGUgZXMgaW1wb3J0YWRhIHBvciBSIGNvbW8gdW5hIGRlIHRpcG8gbnVtw6lyaWNhLgpQYXJhIHBvZGVyIHRyYWJhamFybGEgZW4gZXN0YSBzZWNjacOzbiBzZSB0aWVuZSBxdWUgZGVjbGFyYXJsYSBjb21vIHVuYSB2YXJpYWJsZSBkZSB0aXBvIGZhY3RvciB1c2FuZG8gZWwgY29tYW5kbyBgYXMuZmFjdG9yYCB5IGx1ZWdvIHNlIGV0aXF1ZXRhIGNvbiBlbCBjb21hbmRvIGBsZXZlbHNgLgoKYGBge3IgZmFjdG9yIHZvdG9zfQpsaWJyYXJ5KGhhdmVuKQpsYXBvcDIxJGNvdW50ZmFpcjFyID0gYXMuZmFjdG9yKGxhcG9wMjEkY291bnRmYWlyMSkKbGV2ZWxzKGxhcG9wMjEkY291bnRmYWlyMXIpIDwtIGMoIlNpZW1wcmUiLCAiQWxndW5hcyB2ZWNlcyIsICJOdW5jYSIpCnRhYmxlKGxhcG9wMjEkY291bnRmYWlyMXIpCmBgYAoKIyMgVGFibGEgY3J1emFkYSBkZSBzaSBsb3Mgdm90b3Mgc2UgY3VlbnRhbiBqdXN0YW1lbnRlIHBvciBwYcOtcwoKQW50ZXMgZGUgcmVwbGljYXIgZWwgZ3LDoWZpY28sIGVzIMO6dGlsIHZlciBlc3RvcyByZXN1bHRhZG9zIGVuIGZvcm1hIGRlIHRhYmxhIGNydXphZGEuCkVzdGEgdGFibGUgc2UgcHVlZGUgY3JlYXIgY29uIGVsIGNvbWFuZG8gYHRhYmxlYC4KU2luIGVtYmFyZ28sIGVuIGVzdGEgdGFibGEgdGVuZW1vcyBsYXMgZnJlY3VlbmNpYXMgYWJzb2x1dGFzLgpBZGVtw6FzLCBub3MgbXVlc3RyYSBxdWUgZXN0YSBwcmVndW50YSBubyBzZSByZWFsaXrDsyBlbiBhbGd1bm9zIHBhw61zZXMuCgpgYGB7ciBwYWlzIHggdm90b3MgMX0KdGFibGUobGFwb3AyMSRwYWlzLCBsYXBvcDIxJGNvdW50ZmFpcjFyKQpgYGAKClBhcmEgcG9kZXIgcmVwcm9kdWNpciBsYXMgZnJlY3VlbmNpYXMgcmVsYXRpdmFzIHRlbmVtb3MgcXVlIHVzYXIgZWwgY29tYW5kbyBgcHJvcC50YWJsZWAuCkVzdGUgY29tYW5kbyBub3MgYnJpbmRhIHBvciBkZWZlY3RvIGxvcyBwb3JjZW50YWplcyBzb2JyZSBlbCB0b3RhbC4KTG8gcXVlIHF1ZXJlbW9zIGNhbGN1bGFyIGVuIGVzdGUgY2FzbyBzb24gbG9zIHBvcmNlbnRhamVzIHBvciBjYWRhIGZpbGEsIGVzIGRlY2lyLCBwb3IgY2FkYSBwYcOtcy4KCmBgYHtyIHBhaXMgeCB2b3RvcyAyfQpwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMjEkcGFpcywgbGFwb3AyMSRjb3VudGZhaXIxcikpCmBgYAoKUGFyYSBwb2RlciBlc3BlY2lmaWNhciBxdWUgc2UgY2FsY3VsZW4gbG9zIHBvcmNlbnRhamVzIHBvciBmaWxhIHNlIGHDsWFkZSBsYSBlc3BlY2lmaWNhY2nDs24gYCwgMWAgZW4gYHByb3AudGFibGVgLgpUYW1iacOpbiBzZSBhbmlkYSB0b2RvIGVsIGPDs2RpZ28gZW4gZWwgY29tYW5kbyBgYWRkbWFyZ2luc2AgcXVlIG5vcyBjb21wcnVlYmEgbGEgc3VtYSBkZSBwb3JjZW50YWplcyBob3Jpem9udGFsZXMuCkVzdG9zIHNvbiBsb3MgbWlzbW9zIHBvcmNlbnRhamVzIHF1ZSBzZSBwcmVzZW50YXLDoW4gZW4gZWwgZ3LDoWZpY28gZGUgYmFycmFzIGRlIG3DoXMgYWJham8uCkVzdG9zIHBvcmNlbnRhamVzIG5vIHNvbiBpZ3VhbGVzIGEgbG9zIG1vc3RyYWRvcyBlbiBsYSBmaWd1cmEgMi41IGRlYmlkbyBhIHF1ZSBlc3RvcyBjw6FsY3Vsb3Mgbm8gaW5jbHV5ZW4gZWwgZWZlY3RvIGRlIGRpc2XDsW8uCgpgYGB7ciBwYWlzIHggdm90b3MgMjF9CmFkZG1hcmdpbnMocHJvcC50YWJsZSh0YWJsZShsYXBvcDIxJHBhaXMsIGxhcG9wMjEkY291bnRmYWlyMXIpLCAxKSoxMDAsIDIpCmBgYAoKIyMgR3LDoWZpY28gZGUgYmFycmFzIGRlIHNpIGxvcyB2b3RvcyBzZSBjdWVudGFuIGp1c3RhbWVudGUgcG9yIHBhw61zCgpEZSBsYSBtaXNtYSBtYW5lcmEgcXVlIHZpbW9zIGVuIGVsIG3Ds2R1bG8gZGUgdmFyaWFibGVzIG9yZGluYWxlcywgcXVlIHNlIHB1ZWRlIHJldmlzYXIgW2FxdcOtXShodHRwczovL2FydHVyb21hbGRvbmFkby5naXRodWIuaW8vQmFyb21ldHJvRWR1X1dlYi9EZXNjcmlwdGl2b3MyLmh0bWwpLCBwYXJhIHJlcGxpY2FyIGVsIGdyw6FmaWNvIGNvbXBhcmF0aXZvIHBvciBwYcOtcyBzZSByZXF1aWVyZSBjcmVhciBsYSB0YWJsYSBkZSBjb250aW5nZW5jaWEgZW50cmUgbGEgdmFyaWFibGUgImNvdW50ZmFpciIgeSAicGFpcyIuCkVzdGEgdGFibGEgY3J1emFkYSBzZSBndWFyZGEgZW4gdW4gb2JqZXRvICJjb3VudF9wYWlzIi4KU2UgZGViZSBub3RhciBxdWUgZWwgZGF0YWZyYW1lIHF1ZSBzZSBjcmVhIGNyZWEgdW5hIGZpbGEgcG9yIGNhZGEgdmFsb3IgZGUgImNvdW50ZmFpciIgZW4gY2FkYSBwYcOtcy4KRGUgZXN0YSBtYW5lcmEgdGVuZW1vcyAzIG9wY2lvbmVzIHggMjAgcGHDrXNlcyA9IDYwIGZpbGFzLgoKYGBge3IgdGFibGEgdm90b3MgcG9yIHBhaXMgMjF9CmNvdW50X3BhaXMgPSBhcy5kYXRhLmZyYW1lKHJvdW5kKHByb3AudGFibGUodGFibGUobGFwb3AyMSRwYWlzLCBsYXBvcDIxJGNvdW50ZmFpcjFyKSwgMSksIDMpKjEwMCkKY291bnRfcGFpcwpgYGAKCkVuIGVzdGEgdGFibGEgc2UgY2FsY3VsYW4gbG9zIGRhdG9zIHBvciBjYWRhIHZhbG9yIGRlIGxhIHZhcmlhYmxlICJwYWlzIiwgaW5jbHVzbyBjdWFuZG8gbm8gc2UgdGllbmUgZGF0b3MgZGUgbGEgdmFyaWFibGUgImNvdW50ZmFpciIsIGRlYmlkbyBhIHF1ZSBsYSBwcmVndW50YSBubyBzZSByZWFsaXrDsyBlbiBlc2UgcGHDrXMuClBvciBlc3RlIG1vdGl2byBzZSB0aWVuZW4gcXVlIGVsaW1pbmFyIGxhcyBmaWxhcyBkZSBsb3MgcGHDrXNlcyBlbiBsb3MgcXVlIG5vIHNlIHJlY29nacOzIGVzdGEgaW5mb3JtYWNpw7NuLgpFc3RvIHNlIGhhY2UgY29uIGxhIGVzcGVjaWZpY2FjacOzbsKgYFstYyhmaWxhcyksXWAuCkx1ZWdvIHNlIGNyZWEgdW4gdmVjdG9yIGNvbiBsb3Mgbm9tYnJlcyBkZSBsb3MgcGHDrXNlcy4KRXN0YSBsaXN0YSBzZSByZXBpdGUgMyB2ZWNlcyAoMTUgcGHDrXNlcyByZXN0YW50ZXMgeCAzIG9wY2lvbmVzKS4KRXN0ZSB2ZWN0b3Igc2UgYWdyZWdhIGFsIGRhdGFmcmFtZSBlbiB1bmEgY29sdW1uYSAicGFpcyIuCgpgYGB7ciBmaXggdGFibGEgMjF9CmNvdW50X3BhaXMgPSBjb3VudF9wYWlzWy1jKDE6NCwxOCwyMToyNCwzOCw0MTo0NCw1OCksXQpwYWlzID0gYygiTmljYXJhZ3VhIiwiQ29zdGEgUmljYSIsICJQYW5hbcOhIiwgIkNvbG9tYmlhIiwgIkVjdWFkb3IiLCAiQm9saXZpYSIsICJQZXLDuiIsCiAgICAgICAgIlBhcmFndWF5IiwgIkNoaWxlIiwgIlVydWd1YXkiLCAiQnJhc2lsIiwgIkFyZ2VudGluYSIsICJSZXAuIERvbS4iLCJKYW1haWNhIiwgIkd1eWFuYSIsICJOaWNhcmFndWEiLCJDb3N0YSBSaWNhIiwgIlBhbmFtw6EiLCAiQ29sb21iaWEiLCAiRWN1YWRvciIsICJCb2xpdmlhIiwgIlBlcsO6IiwKICAgICAgICAiUGFyYWd1YXkiLCAiQ2hpbGUiLCAiVXJ1Z3VheSIsICJCcmFzaWwiLCAiQXJnZW50aW5hIiwgIlJlcC4gRG9tLiIsIkphbWFpY2EiLCAiR3V5YW5hIiwiTmljYXJhZ3VhIiwiQ29zdGEgUmljYSIsICJQYW5hbcOhIiwgIkNvbG9tYmlhIiwgIkVjdWFkb3IiLCAiQm9saXZpYSIsICJQZXLDuiIsCiAgICAgICAgIlBhcmFndWF5IiwgIkNoaWxlIiwgIlVydWd1YXkiLCAiQnJhc2lsIiwgIkFyZ2VudGluYSIsICJSZXAuIERvbS4iLCJKYW1haWNhIiwgIkd1eWFuYSIpCmNvdW50X3BhaXMkcGFpcyA9IHBhaXMKY291bnRfcGFpcwpgYGAKCkNvbiBlc3RlIGRhdGFmcmFtZSAiY291bnRfcGFpcyIgeWEgdGVuZW1vcyBsb3MgZWxlbWVudG9zIHBhcmEgcmVwbGljYXIgZWwgZ3LDoWZpY28gZGUgYmFycmFzIGFwaWxhZGFzLgpFbiBsYSBlc3BlY2lmaWNhY2nDs27CoGBhZXNgc2UgZGVmaW5lIHF1ZSBlbiBlbCBlamUgWCBzZSBncmFmaXF1ZW4gbG9zIHBvcmNlbnRhamVzLCBlbiBlbCBlamUgWSBsb3MgcGHDrXNlcyB5IGNhZGEgYmFycmEgc2UgZGl2aWRhIHBvciBsYSBjb2x1bW5hIFZhcjIuCgpgYGB7ciBmaWd1cmEgMi41fQpnZ3Bsb3QoZGF0YT1jb3VudF9wYWlzLCBhZXMoeD1GcmVxLCB5PXBhaXMsIGZpbGw9VmFyMikpKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iiwgd2lkdGg9MC4zKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXBhc3RlKEZyZXEsICIlIiwgc2VwPSIiKSksIGNvbG9yPSJ3aGl0ZSIsIAogICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9zdGFjayh2anVzdD0wLjUpLCBzaXplPTIpKwogIGxhYnMoeD0iUG9yY2VudGFqZSIsIHk9IlBhw61zIiwgZmlsbD0iTG9zIHZvdG9zIHNlIGN1ZW50YW4ganVzdGFtZW50ZSIsCiAgICAgICBjYXB0aW9uPSJCYXLDs21ldHJvIGRlIGxhcyBBbcOpcmljYXMgcG9yIExBUE9QLCAyMDIxIikKYGBgCgojIEV2YWx1YWNpw7NuIGRlIGxhIGRlbW9jcmFjaWEgZW4gbGEgcHLDoWN0aWNhCgpEZXNkZSBsYSBww6FnaW5hIDIwIGRlbCByZXBvcnRlICpFbCBQdWxzbyBkZSBsYSBEZW1vY3JhY2lhKiBkZSBsYSByb25kYSAyMDE4LzE5IHNlIGhhY2UgdW5hIGV2YWx1YWNpw7NuIGRlIGxhIGRlbW9jcmFjaWEgZW4gbGEgcHLDoWN0aWNhLgpFbiBwYXJ0aWN1bGFyLCBlc3RhIHNlY2Npw7NuIGRlbCByZXBvcnRlIHVzYSBsYSB2YXJpYWJsZSAicG40Ii4KRXN0YSB2YXJpYWJsZSBlc3TDoSBmcmFzZWFkYSBkZSBsYSBzaWd1aWVudGUgbWFuZXJhOiAiRW4gZ2VuZXJhbCwgwr91c3RlZCBkaXLDrWEgcXVlIGVzdMOhIG11eSBzYXRpc2ZlY2hvKGEpLCBzYXRpc2ZlY2hvKGEpLCBpbnNhdGlzZmVjaG8oYSkgbyBtdXkgaW5zYXRpc2ZlY2hvKGEpIGNvbiBsYSBmb3JtYSBlbiBxdWUgbGEgZGVtb2NyYWNpYSBmdW5jaW9uYSBlbiAocGHDrXMpPyIKCkVuIGVsIHJlcG9ydGUgc2UgaW5kaWNhIHF1ZSBlc3RhIHZhcmlhYmxlIHNlIHJlY29kaWZpY2EgY29tbyB1bmEgdmFyaWFibGUgZGljb3TDs21pY2EgcGFyYSBwb2RlciB0cmFiYWphciBjb24gcG9yY2VudGFqZXMuCkVuIGVzdGEgc2VjY2nDs24gdmFtb3MgYSB0cmFiYWphciBjb24gbGEgdmFyaWFibGUgb3JpZ2luYWwsIHF1ZSBlcyB1bmEgdmFyaWFibGUgY2F0ZWfDs3JpY2EgKG8gZGUgZmFjdG9yKSBvcmRpbmFsLgoKRW4gZWwgR3LDoWZpY28gMS4xNCBkZWwgcmVwb3J0ZSBzZSBwcmVzZW50YSB1bmEgZXZhbHVhY2nDs24gZGUgbGEgc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSBwb3IgdmFyaWFibGVzIGRlbW9ncsOhZmljYXMgeSBzb2Npb2Vjb27Ds21pY2FzLCBjb21vIG5pdmVsIGVkdWNhdGl2bywgcXVpbnRpbGVzIGRlIHJpcXVlemEsIGx1Z2FyIGRlIHJlc2lkZW5jaWEsIGfDqW5lcm8gbyBncnVwb3MgZGUgZWRhZC4KRXMgZGVjaXIsIHNlIHVzYSBsYSBzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhIGNvbW8gdmFyaWFibGUgZGVwZW5kaWVudGUgeSBhIGNhZGEgdmFyaWFibGUgZGVtb2dyw6FmaWNhIG8gc29jaW9lY29uw7NtaWNhIGNvbW8gdmFyaWFibGUgaW5kZXBlbmRpZW50ZS4KCiFbXShHcmFmMS4xNC5wbmcpe3dpZHRoPSIzODQifQoKUG9yIGVqZW1wbG8sIHNlIHJlcG9ydGEgcXVlIGVudHJlIGxvcyBob21icmVzLCBlbCA0Mi4zJSBlc3TDoW4gc2F0aXNmZWNob3MgY29uIGxhIGRlbW9jcmFjaWEgKHVzYW5kbyBsYSB2YXJpYWJsZSByZWNvZGlmaWNhZGEgY29tbyBkdW1teSksIG1pZW50cmFzIHF1ZSBlbnRyZSBsYXMgbXVqZXJlcywgZXN0ZSBwb3JjZW50YWplIGRpc21pbnV5ZSBhIDM2LjklLgpBcXXDrSB2YW1vcyBhIGFuYWxpemFyIGVzdGFzIG1pc21hcyB2YXJpYWJsZXMsIHBlcm8gdXNhbmRvIGxhIHZhcmlhYmxlICJwbjQiIGVuIHN1IGZvcm1hIG9yaWdpbmFsIChjb21vIGNhdGVnw7NyaWNhIG9yZGluYWwpLgpBbnRlcyBkZSBwcm9jZWRlciwgdGVuZW1vcyBxdWUgcmVjb2RpZmljYXIgbGFzIHZhcmlhYmxlcyBlbiBmb3JtYSBkZSBmYWN0b3IgeSBldGlxdWV0YXJsYXMuCgpgYGB7ciBnZW5lcm99CmxhcG9wMTgkZ2VuZXJvIDwtIGFzLmZhY3RvcihsYXBvcDE4JHExKQpsZXZlbHMobGFwb3AxOCRnZW5lcm8pIDwtIGMoIkhvbWJyZSIsICJNdWplciIpCnRhYmxlKGxhcG9wMTgkZ2VuZXJvKQpgYGAKClNlIGhhY2UgbG8gbWlzbW8gcGFyYSBsYSB2YXJpYWJsZSAicG40IiBxdWUgc2UgdHJhbnNmb3JtYSBlbiB1bmEgbnVldmEgdmFyaWFibGUgInNhdGlzIi4KCmBgYHtyIHNhdGlzfQpsYXBvcDE4JHNhdGlzIDwtIGFzLmZhY3RvcihsYXBvcDE4JHBuNCkKbGV2ZWxzKGxhcG9wMTgkc2F0aXMpIDwtIGMoIk11eSBzYXRpc2ZlY2hvIiwgIlNhdGlzZmVjaG8iLCAiSW5zYXRpc2ZlY2hvIiwgIk11eSBpbnNhdGlzZmVjaG8iKQp0YWJsZShsYXBvcDE4JHNhdGlzKQpgYGAKCiMjIFRhYmxhIGNydXphZGEgZGUgc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSBzZWfDum4gZ8OpbmVybwoKQ29uIGxhcyBudWV2YXMgdmFyaWFibGVzIGRlIGZhY3RvciwgbG8gcHJpbWVybyBlcyBjYWxjdWxhciBsYSB0YWJsYSBjcnV6YWRhIG8gZGUgY29udGluZ2VuY2lhLgpFbCBjb21hbmRvIGB0YWJsZWAgc2lydmUgcGFyYSBwcmVzZW50YXIgbGFzIGZyZWN1ZW5jaWFzIGRlIHVuYSBvIGRlbCBjcnVjZSBkZSBkb3MgdmFyaWFibGVzLgpQb3IgY29udmVuY2nDs24sIGxhIHZhcmlhYmxlIGRlcGVuZGllbnRlICJzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhIiBzZSB1YmljYSBlbiBsYXMgZmlsYXMgeSBsYSB2YXJpYWJsZSBpbmRlcGVuZGllbnRlICJnw6luZXJvIiBlbiBsYXMgY29sdW1uYXMuCgpgYGB7ciB0YWJsYX0KdGFibGUobGFwb3AxOCRzYXRpcywgbGFwb3AxOCRnZW5lcm8pCmBgYAoKUGFyYSBjYWxjdWxhciBsYXMgZnJlY3VlbmNpYXMgcmVsYXRpdmFzLCBzZSB0aWVuZSBxdWUgYW5pZGFyIGVsIGNvbWFuZG8gYHRhYmxlYCBkZW50cm8gZGVsIGNvbWFuZG8gYHByb3AudGFibGVgLgpTaSBzZSBhbmlkYSBzb2xhbWVudGUsIGVzdGUgY29tYW5kbyBjYWxjdWxhIGxhcyBwcm9wb3JjaW9uZXMgc29icmUgZWwgdG90YWwgZGUgb2JzZXJ2YWNpb25lcy4KCmBgYHtyIHRhYmxhMn0KcHJvcC50YWJsZSh0YWJsZShsYXBvcDE4JHNhdGlzLCBsYXBvcDE4JGdlbmVybykpCmBgYAoKRXN0YXMgcHJvcG9yY2lvbmVzIG5vIHNvbiBkZSBtdWNoYSB1dGlsaWRhZCBwYXJhIGxhIGNvbXBhcmFjacOzbiBxdWUgcXVlcmVtb3MgaGFjZXIuCkxvIHF1ZSByZXF1ZXJpbW9zIHNvbiBsYXMgZGlzdHJpYnVjaW9uZXMgY29uZGljaW9uYWxlcyBkZSAic2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSIgcG9yIGNhZGEgZ3J1cG8gZGUgZ8OpbmVyby4KRXMgZGVjaXIsIGNhbGN1bGFyIGxvcyBwb3JjZW50YWplcyBwb3IgY2FkYSBjb2x1bW5hLgpQYXJhIHF1ZSBgcHJvcC50YWJsZWAgY2FsY3VsZSBlc3RhcyBwcm9wb3JjaW9uZXMsIHNlIHRpZW5lIHF1ZSBhZ3JlZ2FyIGxhIGVzcGVjaWZpY2FjacOzbiBgKOKApiwgMilgLgpTZSBtdWx0aXBsaWNhIHBvciAxMDAgcGFyYSBwYXNhciBkZSBwcm9wb3JjaW9uZXMgYSBwb3JjZW50YWplcy4KVGFtYmnDqW4gc2UgcHVlZGUgYW5pZGFyIHRvZG8gZGVudHJvIGRlbCBjb21hbmRvIGBhZGRtYXJnaW5zYCBwYXJhIHZlcmlmaWNhciBsYSBzdW1hIGRlIHByb3BvcmNpb25lcyBzb2JyZSBsYXMgY29sdW1uYXMsIGNvbiBsYSBlc3BlY2lmaWNhY2nDs24gYCjigKYsIDEpYC4KCmBgYHtyIHRhYmxhczN9CmFkZG1hcmdpbnMocHJvcC50YWJsZSh0YWJsZShsYXBvcDE4JHNhdGlzLCBsYXBvcDE4JGdlbmVybyksIDIpKjEwMCwgMSkKYGBgCgpFbiBsYSB0YWJsYSBzZSBtdWVzdHJhIHF1ZSBlbCA2LjglIGRlIGxvcyBob21icmVzIHNlIGVuY3VlbnRyYSBtdXkgc2F0aXNmZWNobyBjb24gbGEgZGVtb2NyYWNpYSwgdW4gcG9yY2VudGFqZSBtdXkgc2ltaWxhciBhbCBkZSBsYXMgbXVqZXJlcy4KRWwgNDQlIGRlIGxvcyBob21icmVzIHNlIGVuY3VlbnRyYSBpbnNhdGlzZmVjaG8gY29uIGxhIGRlbW9jcmFjaWEuCkVuIGVzdGEgY2F0ZWdvcsOtYSwgbGFzIG11amVyZXMgdGllbmVuIHVuIHBvcmNlbnRhamUgbWF5b3IgKDQ4LjQlKS4KCkRlIGVzdGEgbWFuZXJhLCBzZSBwdWVkZSBjb21wYXJhciBsb3MgcG9yY2VudGFqZXMgZGUgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUgInNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEiIHBvciBjYWRhIGNhdGVnb3LDrWEgZGUgbGEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZSAiZ8OpbmVybyIuCgojIyBHcsOhZmljb3MgZGUgc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSBzZWfDum4gZ8OpbmVybwoKRW4gbGEgc2VjY2nDs24gc29icmUgW0Rlc2NyaXB0aXZvcyBkZSB2YXJpYWJsZXMgb3JkaW5hbGVzXShodHRwczovL2FydHVyb21hbGRvbmFkby5naXRodWIuaW8vQmFyb21ldHJvRWR1X1dlYi9EZXNjcmlwdGl2b3MyLmh0bWwpIHNlIHByZXNlbnTDsyB1biBhZGVsYW50byBkZSBsbyBxdWUgZXN0YW1vcyB2aWVuZG8gZW4gZXN0YSBzZWNjacOzbi4KU2UgY3JlYXJvbiB0YWJsYXMgY3J1emFkYXMgeSBncsOhZmljb3MgZGUgZG9zIHZhcmlhYmxlcy4KQXF1w60gdm9sdmVyZW1vcyBhIHZpc2l0YXIgZXNvcyB0ZW1hcywgdXNhbmRvIGVsIHRpZHl2ZXJzZS4KClBhcmEgaGFjZXIgZWwgZ3LDoWZpY28sIGxvIHByaW1lcm8gcXVlIHNlIHRpZW5lIHF1ZSBjcmVhciBlcyB1biBudWV2byBkYXRhZnJhbWUgY29uIGxvcyBkYXRvcyBkZWwgY3J1Y2UgZGUgdmFyaWFibGVzLgpTZSB1c2EgZWwgY29tYW5kbyBgYXMuZGF0YS5mcmFtZWAgcGFyYSB0cmFuc2Zvcm1hciBsYSB0YWJsYSBiaXZhcmlhZGEgZW4gdW4gbnVldm8gZGF0YWZyYW1lIGxsYW1hZG8gInRhYmxhIi4KVXNhbmRvIGVzdGUgY29tYW5kbywgbG9zIHJlc3VsdGFkb3Mgc2Ugb3JkZW5hbiBwb3IgbnVldmFzIGNvbHVtbmFzIChWYXIxLCBWYXIyIHkgRnJlcSkgZGUgZm9ybWEgcXVlIHB1ZWRlbiB1c2Fyc2UgcGFyYSBjcmVhciB1biBncsOhZmljby4KCmBgYHtyIHRhYmxhNH0KdGFibGEgPC0gYXMuZGF0YS5mcmFtZShwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMTgkc2F0aXMsIGxhcG9wMTgkZ2VuZXJvKSwgMikqMTAwKQp0YWJsYQpgYGAKClVzYXJlbW9zIGxhIGxpYnJlcsOtYSBgZ2dwbG90MmAgeSBlbCBjb21hbmRvIGBnZ3Bsb3RgIHBhcmEgY3JlYXIgdW4gZ3LDoWZpY28gZGUgYmFycmFzLCB1c2FuZG8gZWwgZGF0YWZyYW1lICJ0YWJsYSIgcXVlIGNvbnRpZW5lIGxvcyBwb3JjZW50YWplcyBkZSBzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhIHBhcmEgaG9tYnJlcyB5IG11amVyZXMuCkVsIGNvbWFuZG8gcmVxdWllcmUgdW5hIGVzdMOpdGljYSBkb25kZSBzZSBlc3BlY2lmaWNhIHF1ZSBlbiBlbCBlamUgWCBzZSBpbmNsdWlyw6EgbGEgIlZhcjEiLCBxdWUgY29ycmVzcG9uZGUgYSBsYXMgY2F0ZWdvcsOtYXMgZGUgc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYS4KRW4gZWwgZWplIFkgc2UgaW5jbHV5ZSBsYSAiRnJlcSIsIHF1ZSBjb3JyZXNwb25kZSBhIGxvcyBwb3JjZW50YWplcy4KU2UgaW5jbHV5ZSB0YW1iacOpbiBsYSBlc3BlY2lmaWNhY2nDs24gYGZpbGxgIHBhcmEgaW5kaWNhciBxdWUgc2UgZGl2aWRpcsOhIGVuIGdydXBvcyBIb21icmUvTXVqZXIgcG9yIGNhZGEgY2F0ZWdvcsOtYSBkZSAiVmFyMSIgeSBgeW1heGAgcGFyYSBlc3BlY2lmaWNhciBlbCBsw61taXRlIHN1cGVyaW9yIGRlbCBlamUgWS4KCkx1ZWdvIGRlIGRlZmluaXIgbGFzIHZhcmlhYmxlcyBlbiBsb3MgZWplcywgc2UgaW5kaWNhIHF1ZSBzZSBxdWllcmUgdW4gZ3LDoWZpY28gZGUgYmFycmFzIGNvbiBlbCBjb21hbmRvIGBnZW9tX2JhcmAgeSBjb24gbGEgZXNwZWNpZmljYWNpw7NuIGBwb3NpdGlvbj0iZG9kZ2UiYCBzZSBpbmRpY2EgcXVlIHNlIHF1aWVyZSB1biBncsOhZmljbyBjb24gYmFycmFzIHNlcGFyYWRhcyBwb3IgY2FkYSBjb21iaW5hY2nDs24gZGUgY2F0ZWdvcsOtYXMgZGUgbGFzIHZhcmlhYmxlcy4KU2UgYWdyZWdhIGxhIGVzcGVjaWZpY2FjacOzbiBgc3RhdD0iaWRlbnRpdHkiYCBwYXJhIGluZGljYXIgcXVlIGVsIGNvbWFuZG8gdHJhYmFqZSBjb24gbG9zIGRhdG9zIGRlIGxhIHRhYmxhLgoKQ29uIGVsIGNvbWFuZG8gYGdlb21fdGV4dGAgc2UgaW5jbHV5ZSBsb3MgcG9yY2VudGFqZXMgZGUgY2FkYSBiYXJyYSwgcXVlIHNlIGVuY3VlbnRyYSBlbiBsYSBjb2x1bW5hICJGcmVxIi4KRXN0b3MgcG9yY2VudGFqZXMgc2UgcmVkb25kZWFuIGNvbiBgcm91bmRgIGEgMSBkZWNpbWFsIHkgc2UgYcOxYWRlIGVsIHPDrW1ib2xvICIlIiBjb24gYHBhc3RlYC4KVGFtYmnDqW4gc2UgaW5jbHV5ZSBsYSBlc3BlY2lmaWNhY2nDs24gYHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKOKApilgIHF1ZSB1YmljYSBlc3RvcyBwb3JjZW50YWplcyBhcnJpYmEgZGUgY2FkYSBjb2x1bW5hLgpMYSBvcGNpw7NuIHBvciBkZWZlY3RvIGRlbnRybyBkZSBlc3RhIGVzcGVjaWZpY2FjacOzbiBlcyBgd2lkdGg9TlVMTGAsIHBlcm8gZGUgZXN0YSBtYW5lcmEgbG9zIHBvcmNlbnRhamVzIHF1ZWRhcsOtYW4gbWFsIHViaWNhZG9zLCBwb3IgZXN0byBzZSBkZWZpbmUgYHdpZHRoPTAuOWAgcGFyYSBjZW50cmFyIGxvcyBwb3JjZW50YWplcy4KClBvciBkZWZlY3RvIGxhIGxleWVuZGEgaW5jbHV5ZSBlbCBub21icmUgZGUgbGEgY29sdW1uYSBjb24gbG9zIGRhdG9zIGRlIGfDqW5lcm8sIHF1ZSBlcyAiVmFyMiIuClBhcmEgY2FtYmlhciBlc3RlIG5vbWJyZSwgc2UgdXNhIGVsIGNvbWFuZG8gYGxhYnMoZmlsbD0iR8OpbmVybyIpYCBwYXJhIG5vbWJyYXIgYWRlY3VhZGFtZW50ZSBsYSBsZXllbmRhLgpGaW5hbG1lbnRlLCBzZSBldGlxdWV0YSBlbCBlamUgWSB5IFggY29uIGB5bGFiYCB5IGB4bGFiLmAKCmBgYHtyIGdyYWZiYXJ9CmxpYnJhcnkoZ2dwbG90MikKZ2dwbG90KGRhdGE9dGFibGEsIGFlcyh4PVZhcjEsIHk9RnJlcSwgZmlsbD1WYXIyLCB5bWF4PTYwKSkrCiAgZ2VvbV9iYXIocG9zaXRpb249ImRvZGdlIiwgc3RhdD0iaWRlbnRpdHkiKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXBhc3RlKHJvdW5kKEZyZXEsIDEpLCAiJSIsIHNlcD0iIikpLAogICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjkpLCB2anVzdD0tMC4yNSkrCiAgbGFicyhmaWxsPSJHw6luZXJvIikrCiAgeWxhYigiUG9yY2VudGFqZSIpKwogIHhsYWIoIlNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEiKQpgYGAKCk90cmEgZm9ybWEgZGUgbW9zdHJhciBlc3RvcyBkYXRvcyBlcyBtZWRpYW50ZSBiYXJyYXMgYXBpbGFkYXMuCkVzIGRlY2lyLCBwb3IgY2FkYSBjYXRlZ29yw61hIGRlIGfDqW5lcm8gc2UgbXVlc3RyYSBsYSBkaXN0cmlidWNpw7NuIGRlIHNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEuClBhcmEgZXN0bywgdXNhbW9zIGVsIG1pc21vIGNvbWFuZG8gYGdncGxvdGAgcGVybyBhaG9yYSBzZSBjYW1iaWEgZWwgb3JkZW4gZGUgbGFzIHZhcmlhYmxlcyBlbiBsYSBlc3TDqXRpY2EuCkFob3JhIGxhIHZhcmlhYmxlICJWYXIyIiAoY29uIGxhcyBjYXRlZ29yw61hcyBkZSBnw6luZXJvKSBzZSB1YmljYSBlbiBlbCBlamUgWCB5IGNhZGEgYmFycmEgc2UgZGl2aWRlIGRlIGFjdWVyZG8gYSBsb3MgdmFsb3JlcyBkZSBWYXIxLgoKRWwgdGlwbyBkZSBiYXJyYSBjYW1iaWEgZW4gZWwgY29tYW5kbyBgZ2VvbV9iYXJgIGEgYHBvc2l0aW9uPSJzdGFjayJgLgpEZSBsYSBtaXNtYSBtYW5lcmEsIGxhcyBldGlxdWV0YXMgZGUgZGF0b3MgdGllbmVuIHF1ZSBjb25zaWRlcmFyIHF1ZSBsYSBwb3NpY2nDs24gZGUgY2FkYSBzZWN0b3IsIGNvbiBgcG9zaXRpb249cG9zaXRpb25fc3RhY2soKWAuCgpgYGB7ciBncmFmYmFyYXBpbGF9CmdncGxvdChkYXRhPXRhYmxhLCBhZXMoeD1WYXIyLCB5PUZyZXEsIGZpbGw9VmFyMSwgeW1heD0xMDApKSsKICBnZW9tX2Jhcihwb3NpdGlvbj0ic3RhY2siLCBzdGF0PSJpZGVudGl0eSIpKwogIGdlb21fdGV4dChhZXMobGFiZWw9cGFzdGUocm91bmQoRnJlcSwgMSksICIlIiwgc2VwPSIiKSksCiAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX3N0YWNrKCksIHZqdXN0PTIpKwogIGxhYnMoZmlsbD0iU2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSIpKwogIHlsYWIoIlBvcmNlbnRhamUiKSsKICB4bGFiKCJHw6luZXJvIikKYGBgCgojIyBUYWJsYSBjcnV6YWRhIGRlIHNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEgc2Vnw7puIG5pdmVsIGVkdWNhdGl2bwoKRWwgR3LDoWZpY28gMS4xNCBkZWwgcmVwb3J0ZSBtdWVzdHJhIGxvcyBkYXRvcyBkZSBzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhIChzZWfDum4gbGEgdmFyaWFibGUgcmVjb2RpZmljYWRhIGR1bW15KSBwb3Igbml2ZWxlcyBlZHVjYXRpdm8uCkNvbW8gc2VndW5kbyBlamVtcGxvLCBhcXXDrSB2YW1vcyBhIHJlcGxpY2FyIGVzYSByZWxhY2nDs24gdXNhbmRvIGxhIHZhcmlhYmxlIG9yaWdpbmFsIGRlIHRpcG8gZmFjdG9yLgoKTG8gcHJpbWVybyBlcyByZWNvZGlmaWNhciBsYSB2YXJpYWJsZSBlZHVjYWNpw7NuLgpMYSB2YXJpYWJsZSBvcmlnaW5hbCAiZWQiIGVzdMOhIHJlY29naWRhIGNvbW8gdW5hIHZhcmlhYmxlIG51bcOpcmljYSAoYcOxb3MgZGUgZXN0dWRpbykuCkVzdGEgdmFyaWFibGUgdGllbmUgdmFsb3JlcyBxdWUgdmFuIGRlc2RlIDAgYSAxOC4KU2UgcmVjb2RpZmljYSBkZSB0YWwgbWFuZXJhIHF1ZSBhcXVlbGxvcyBjb24gY2VybyBhw7FvcyBkZSBlZHVjYWNpw7NuIHNlIGxlcyBhc2lnbmEgZWwgdmFsb3IgZGUgMCAiTmluZ3VuYSIsIGFxdWVsbG9zIGVudHJlIDEgeSA2IGHDsW9zIGRlIGVkdWNhY2nDs24gc2UgbGVzIGFzaWduYSBlbCB2YWxvciAxICJQcmltYXJpYSIsIGFxdWVsbG9zIGVudHJlIDcgeSAxMSBhw7FvcyBkZSBlZHVjYWNpw7NuIHNlIGxlcyBhc2lnbmEgZWwgdmFsb3IgZGUgMiAiU2VjdW5kYXJpYSIgeSBlbnRyZSAxMiB5IDE4IGHDsW9zIGRlIGVkdWNhY2nDs24gZWwgdmFsb3IgZGUgMyAiU3VwZXJpb3IiLgoKYGBge3IgcmVjb2VkfQpsaWJyYXJ5KGNhcikKbGFwb3AxOCRlZHVjIDwtIGNhcjo6cmVjb2RlKGxhcG9wMTgkZWQsICIwPTA7IDE6Nj0xOyA3OjExPTI7IDEyOjE4PTMiKQpsYXBvcDE4JGVkdWMgPC0gYXMuZmFjdG9yKGxhcG9wMTgkZWR1YykKbGV2ZWxzKGxhcG9wMTgkZWR1YykgPC0gYygiTmluZ3VuYSIsICJQcmltYXJpYSIsICJTZWN1bmRhcmlhIiwgIlN1cGVyaW9yIikKdGFibGUobGFwb3AxOCRlZHVjKQpgYGAKCkNvbiBsYSB2YXJpYWJsZSByZWNvZGlmaWNhZGEgc2UgcHVlZGUgY2FsY3VsYXIgbGEgdGFibGEgY3J1emFkYSBkZSBzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhIHNlZ8O6biBuaXZlbGVzIGVkdWNhdGl2b3MuCgpgYGB7ciB0YWJsYWVkfQphZGRtYXJnaW5zKHByb3AudGFibGUodGFibGUobGFwb3AxOCRzYXRpcywgbGFwb3AxOCRlZHVjKSwgMikqMTAwLCAxKQpgYGAKClBhcmEgY3JlYXIgZWwgZ3LDoWZpY28gc2UgdGllbmUgcXVlIGd1YXJkYXIgbGEgdGFibGEgY29tbyB1biBkYXRhZnJhbWUuClNlIHVzYSBlbCBjb21hbmRvIGBhcy5kYXRhLmZyYW1lYCBwYXJhIHNhbHZhciBsb3MgcG9yY2VudGFqZXMgeSBwb2RlciB1c2FybG9zIGNvbiBlbCBjb21hbmRvIGBnZ3Bsb3RgLgoKYGBge3IgdGFibGE1fQp0YWJsYTIgPC0gYXMuZGF0YS5mcmFtZShwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMTgkc2F0aXMsIGxhcG9wMTgkZWR1YyksIDIpKjEwMCkKdGFibGEyCmBgYAoKRW4gZXN0ZSBjYXNvLCBjb21vIHRlbmVtb3MgNCBjYXRlZ29yw61hcyBwYXJhIHNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEgeSBvdHJhcyA0IHBhcmEgbml2ZWxlcyBlZHVjYXRpdm8sIHVuIGdyw6FmaWNvIGRlIGJhcnJhcyBzZXBhcmFkYXMgY3JlYXLDrWEgMTYgYmFycmFzLCBsbyBxdWUgY29tcGxpY2Fyw61hIGxhIGNvbXBhcmFjacOzbi4KUG9yIGVzbywgZW4gZXN0ZSBjYXNvLCBzZSBwcmVmaWVyZSBlbCB0aXBvIGRlIGJhcnJhcyBhcGlsYWRhcy4KCmBgYHtyIGJhcnJhcGlsYWRhc2VkfQpsaWJyYXJ5KGdncGxvdDIpCmdncGxvdChkYXRhPXRhYmxhMiwgYWVzKHg9VmFyMiwgeT1GcmVxLCBmaWxsPVZhcjEsIHltYXg9MTAwKSkrCiAgZ2VvbV9iYXIocG9zaXRpb249InN0YWNrIiwgc3RhdD0iaWRlbnRpdHkiKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXBhc3RlKHJvdW5kKEZyZXEsIDEpLCAiJSIsIHNlcD0iIikpLAogICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9zdGFjaygpLCB2anVzdD0yKSsKICBsYWJzKGZpbGw9IlNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEiKSsKICB5bGFiKCJQb3JjZW50YWplIikrCiAgeGxhYigiTml2ZWwgZWR1Y2F0aXZvIikKYGBgCgpFbiBlbCBHcsOhZmljbyAxLjE0IHNlIG9ic2VydmEgcXVlIHNlIHRpZW5lIHVuIG1heW9yIHBvcmNlbnRhamUgZGUgc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSBlbnRyZSBsb3MgbWVub3MgZWR1Y2Fkb3MuCkVzdGEgcmVsYWNpw7NuIHRhbWJpw6luIHB1ZWRlIG9ic2VydmFyc2UgZW4gZXN0ZSBncsOhZmljby4KTG9zIHNlY3RvcmVzICJtdXkgc2F0aXNmZWNob3MiIChlbiByb3NhZG8pIHkgInNhdGlzZmVjaG9zIiAoZW4gdmVyZGUpIGRpc21pbnV5ZW4gYSBtZWRpZGEgcXVlIHNlIHBhc2EgZGUgbmluZ3VuYSBhIHByaW1hcmlhLCBzZWN1bmRhcmlhIHkgc3VwZXJpb3IuCgpFbiB0b2RvcyBsb3MgZWplbXBsb3MgcXVlIHNlIGhhbiBtb3N0cmFkbywgc2UgcHVlZGVuIG9ic2VydmFyIGRpZmVyZW5jaWFzIHBvcmNlbnR1YWxlcyBlbiB1bmEgdmFyaWFibGUgcG9yIGNhdGVnb3LDrWFzIGRlIG90cmEgdmFyaWFibGUuCkVzdG9zIHBvcmNlbnRhamVzIHNlIHB1ZWRlbiBjb21wYXJhciBkaXJlY3RhbWVudGUsIHBlcm8gcGFyYSBmb3JtYWxpemFyIHNpIGV4aXN0ZSB1bmEgcmVsYWNpw7NuIGVzdGFkw61zdGljYSBlbnRyZSBhbWJhcyB2YXJpYWJsZXMgc2UgdGllbmUgcXVlIGNvcnJlciB1bmEgcHJ1ZWJhIGRlIHNpZ25pZmljYW5jaWEuCgojIFBydWViYSBkZSBpbmRlcGVuZGVuY2lhIGRlIGNoaS1jdWFkcmFkbwoKU2UgZGljZSBxdWUgZG9zIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMgY29uIGVzdGFkw61zdGljYW1lbnRlIGluZGVwZW5kaWVudGVzIHNpIGxhcyBkaXN0cmlidWNpb25lcyBjb25kaWNpb25hbGVzIChwb2JsYWNpb25hbGVzKSBzb24gaWTDqW50aWNhcyBwb3IgY2FkYSBjYXRlZ29yw61hIGRlIGxhIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgRW4gbGEgcmVsYWNpw7NuIGJpdmFyaWFkYSBhbnRlcmlvciwgZXN0byBzaWduaWZpY2EgcXVlIHNlciBob21icmUgbyBtdWplciBubyBjYW1iaWEgbGFzIG9waW5pb25lcyBjb24gcmVzcGVjdG8gYSBsYSBzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhLgpBIG1lZGlkYSBxdWUgZXN0YXMgZGlzdHJpYnVjaW9uZXMgY29uZGljaW9uYWxlcyBkaWZpZXJlbiBtw6FzIGVudHJlIHPDrSwgc2UgZGljZSBxdWUgYW1iYXMgdmFyaWFibGVzIGVzdMOhbiBtw6FzIHJlbGFjaW9uYWRhcyBvIHNvbiBtw6FzIGRlcGVuZGllbnRlcy4KCkVzdGEgZXZhbHVhY2nDs24gc2UgaGFjZSBtZWRpYW50ZSBsYSBwcnVlYmEgZGUgaW5kZXBlbmRlbmNpYSBkZSBjaGktY3VhZHJhZG8gbyBkZSAkXGNoaV4yJC4KRXN0YSBwcnVlYmEgc2UgYmFzYSBlbiBsYSBjb21wYXJhY2nDs24gZGUgbGFzIGZyZWN1ZW5jaWFzIG9ic2VydmFkYXMgKGxhcyBvYnNlcnZhY2lvbmVzIHF1ZSBzZSByZWNvZ2UgZW4gY2FtcG8pIHZlcnN1cyBsYXMgZnJlY3VlbmNpYXMgZXNwZXJhZGFzIChsYXMgb2JzZXJ2YWNpb25lcyBxdWUgZGViZXLDrWFuIGhhYmVyIGVuIGNhZGEgY2VsZGEgc2kgbGFzIHZhcmlhYmxlcyBmdWVyYW4gaW5kZXBlbmRpZW50ZXMpLgpFbCBlc3RhZMOtc3RpY28gZGUgbGEgcHJ1ZWJhIHJlc3VtZSBxdcOpIHRhbiBjZXJjYSBlc3TDoW4gbGFzIGZyZWN1ZW5jaWFzIGVzcGVyYWRhcyBkZSBsYXMgZnJlY3VlbmNpYXMgb2JzZXJ2YWRhcy4KCiQkClxjaGleMiA9IFxzdW1cZnJhY3soZl9vLWZfZSleMn17Zl9lfQokJAoKTWllbnRyYXMgbcOhcyBwZXF1ZcOxYSBsYSBkaXN0YW5jaWEgZW4gY2FkYSBjZWxkYSwgbWVub3MgcHJvYmFiaWxpZGFkIGRlIHJlY2hhemFyIGxhIGhpcMOzdGVzaXMgbnVsYS4KTWllbnRyYXMgbGEgZGlzdGFuY2lhIHNlYSBtw6FzIGdyYW5kZSBlbiBjYWRhIGNlbGRhLCBtYXMgcHJvYmFiaWxpZGFkZXMgZGUgcmVjaGF6YXIgbGEgaGlww7N0ZXNpcyBudWxhLgoKJCQKSDA6IGZfbyA9IGZfZQokJAoKQ29uIGVsIHZhbG9yIGRlICRcY2hpXjIkIHkgY29uIGxvcyBncmFkb3MgZGUgbGliZXJ0YWQgKGZpbGFzLTFcKmNvbHVtbmFzLTEpLCBzZSBjYWxjdWxhIHVuIHAtdmFsdWUgZW4gbGEgZGlzdHJpYnVjacOzbiBkZSBjaGktY3VhZHJhZG8uClNpIGVzdGUgcC12YWx1ZSBlcyBtZW5vciBkZSAwLjA1LCBzZSByZWNoYXphIGxhIEgwLgpFc3RhIHBydWViYSByZXF1aWVyZSBxdWUgaGF5YSBhbCBtZW5vcyA1IG9ic2VydmFjaW9uZXMgZW4gY2FkYSBjZWxkYS4KCiMjIExvcyB2b3RvcyBzZSBjdWVudGFuIGp1c3RhbWVudGUgcG9yIHBhw61zCgpFbiBSIHNlIHVzYSBlbCBjb21hbmRvIGBjaGlzcS50ZXN0YCBwYXJhIGNhbGN1bGFyIGVsIGVzdGFkw61zdGljbyB5IGVsIHAtdmFsdWUgYXNvY2lhZG8uCkVzdGEgcHJ1ZWJhIHNlIHB1ZWRlIGd1YXJkYXIgZW4gdW4gbnVldm8gb2JqZXRvICJwcnVlYmExIi4KCmBgYHtyIHBydWViYSAxfQpwcnVlYmExIDwtIGNoaXNxLnRlc3QobGFwb3AyMSRjb3VudGZhaXIxciwgbGFwb3AyMSRwYWlzKQpwcnVlYmExCmBgYAoKRWwgcC12YWx1ZSBvYnRlbmlkbyBlcyBtZW5vciBkZSAwLjA1LCBwb3IgbG8gcXVlIHNlIHJlY2hhemEgbGEgSDAsIGNvbiBsbyBxdWUgZGVjaW1vcyBxdWUgbGFzIGZyZWN1ZW5jaWFzIG9ic2VydmFkYXMgcGFyZWNlbiBzZXIgZGlmZXJlbnRlcyBkZSBsYXMgZnJlY3VlbmNpYXMgZXNwZXJhZGFzIHF1ZSBodWJpZXJhbiBlbiBjYWRhIGNlbGRhIHNpIG5vIGh1YmllcmEgcmVsYWNpw7NuLCBwb3IgbG8gcXVlIGRlY2ltb3MgcXVlIGhheSB1bmEgcmVsYWNpw7NuIGVudHJlIGxhcyB2YXJpYWJsZXMgbyBxdWUgaGF5IHVuYSBkZXBlbmRlbmNpYSBlbnRyZSBhbWJhcy4KCkVzIGltcG9ydGFudGUgbm90YXIgcXVlICJwcnVlYmEiIGVzIHVuIG9iamV0byBkZSB0aXBvICpsaXN0YSouCkVzdGUgdGlwbyBkZSBvYmpldG8gcHVlZGUgYWxtYWNlbmFyIG90cmEgaW5mb3JtYWNpw7NuIGRlIGRpZmVyZW50ZSB0aXBvLgpQb3IgZWplbXBsbywgInBydWViYSIgZ3VhcmRhIGxhcyB0YWJsYXMgZGUgZnJlY3VlbmNpYXMgb2JzZXJ2YWRhcyAobWlzbW8gcmVzdWx0YWRvIHF1ZSBjb24gZWwgY29tYW5kbyBgdGFibGVgKSB5IGRlIGZyZWN1ZW5jaWFzIGVzcGVyYWRhcy4KRW4gZXN0ZSBvYmpldG8gdGFtYmnDqW4gc2UgZ3VhcmRhIGVsIHZhbG9yIGRlIGxvcyByZXNpZHVhbGVzLCBsb3MgcmVzaWR1b3MgZXN0YW5kYXJpemFkb3MgeSBlbCB2YWxvciBkZWwgcC12YWx1ZS4KCmBgYHtyIG9ic2V4cH0KcHJ1ZWJhMSRvYnNlcnZlZApwcnVlYmExJGV4cGVjdGVkCmBgYAoKUGFyYSBldmFsdWFyIGxhIGZ1ZXJ6YSBkZSBsYSByZWxhY2nDs24sIHNlIHVzYSBsYSBsaWJyZXLDrWEgYHZjZGAgcXVlIGN1ZW50YSBjb24gZWwgY29tYW5kbyBgYXNzb2NzdGF0c2AgcXVlIG5vcyBvZnJlY2UgdW5hIHNlcmllIGRlIG1lZGlkYXMgZGUgYXNvY2lhY2nDs24gYWRlY3VhZGFzIHBhcmEgZWwgY3J1Y2UgZW50cmUgdW5hIHZhcmlhYmxlIG9yZGluYWwgY29tbyAiY291bnRmYWlyMSIgeSB1bmEgdmFyaWFibGUgbm9taW5hbCBjb21vICJwYWlzIi4KCkVsIGNvbWFuZG8gYGFzc29jc3RhdHNgIG5vIHB1ZWRlIGNhbGN1bGFyIGxhcyBtZWRpZGFzIGRlIGFzb2NpYWNpw7NuIHNpIHNlIHRpZW5lIGNlbGRhcyBlbiBsYSB0YWJsYSBjcnV6YWRhIGNvbiB2YWxvcmVzIGRlIGNlcm8uCkNvbW8gc2UgdGllbmUgYWxndW5vcyBwYcOtc2VzIGRvbmRlIG5vIHNlIGhpem8gbGEgcHJlZ3VudGEgImNvdW50ZmFpcjEiIGVudG9uY2VzIHNlIHRpZW5lIHF1ZSBpbmRpY2FyIHF1ZSBubyBzZSB1c2UgbGFzIG9ic2VydmFjaW9uZXMgZGUgZXNvcyBwYcOtc2VzLgpQYXJhIGVzdG8gY3JlYW1vcyB1bmEgbnVldmEgdmFyaWFibGUgZGUgcGHDrXMsIGRvbmRlIGxhcyBvYnNlcnZhY2lvbmVzIGRlIGVzdG9zIHBhw61zZXMgc2UgcG9uZW4gY29tbyBOQXMuCgpgYGB7ciBudWV2byBwYWlzfQpsYXBvcDIxJHBhaXNfciA9IGxhcG9wMjEkcGFpcwpsYXBvcDIxJHBhaXNfcltsYXBvcDIxJHBhaXM9PTFdID0gTkEKbGFwb3AyMSRwYWlzX3JbbGFwb3AyMSRwYWlzPT0yXSA9IE5BCmxhcG9wMjEkcGFpc19yW2xhcG9wMjEkcGFpcz09M10gPSBOQQpsYXBvcDIxJHBhaXNfcltsYXBvcDIxJHBhaXM9PTRdID0gTkEKbGFwb3AyMSRwYWlzX3JbbGFwb3AyMSRwYWlzPT0yMl0gPSBOQQpgYGAKCkNvbiBlc3RhIG51ZXZhIHZhcmlhYmxlIHNlIHB1ZWRlIGNyZWFyIGxhIHRhYmxhIGNydXphZGEgZW50cmUgImNvdW50ZmFpcjEiIHkgInBhaXMiIHkgY2FsY3VsYXIgbGFzIG1lZGlkYXMgZGUgYXNvY2lhY2nDs24uCgpgYGB7ciBhc29jIG5vbWluYWx9CmxpYnJhcnkodmNkKQp0YWJsYTMgPC0gdGFibGUobGFwb3AyMSRjb3VudGZhaXIxciwgbGFwb3AyMSRwYWlzX3IpCmFzc29jc3RhdHModGFibGEzKQpgYGAKCkVsIGNvbWFuZG8gYGFzc29jc3RhdHNgIG5vcyBicmluZGEgZWwgY29lZmljaWVudGUgZGUgY29udGluZ2VuY2lhIHkgbGEgViBkZSBDcmFtZXIgY29tbyBtZWRpZGFzLgpFc3RhcyBtZWRpZGFzIHZhcsOtYW4gZW50cmUgMCB5IDEuCk1pZW50cmFzIG3DoXMgY2VyY2FubyBhIGNlcm8sIHNlIGFzdW1lIHF1ZSBsYSByZWxhY2nDs24gZXMgbcOhcyBkw6liaWwuClBvciBlbCBjb250cmFyaW8sIG1pZW50cmFzIG3DoXMgY2VyY2FubyBhIDEsIHNlIGFzdW1lIHF1ZSBsYSByZWxhY2nDs24gZXMgbcOhcyBmdWVydGUuCgpQb3IgY29udmVuY2nDs24gc2UgYXN1bWUgcXVlIHNlIHRpZW5lIHJlbGFjaW9uZXMgZMOpYmlsZXMgY29uIHZhbG9yZXMgZW50cmUgMCB5IDAuMywgcmVsYWNpb25lcyBtb2RlcmFkYXMgY29uIHZhbG9yZXMgZW50cmUgMC4zIHkgMC42IHkgcmVsYWNpb25lcyBmdWVydGVzIGNvbiB2YWxvcmVzIG1heW9yZXMgYSAwLjYuCkVuIGVzdGUgY2FzbywgcG9kZW1vcyBpbmRpY2FyIHF1ZSBsYSByZWxhY2nDs24gZW50cmUgc2kgbG9zIHZvdG9zIHNlIGN1ZW50YW4ganVzdGFtZW50ZSB5IHBhw61zIGVzIGTDqWJpbC4KCiMjIFNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEgc2Vnw7puIGVkdWNhY2nDs24KClBhcmEgY29tcHJvYmFyIGxhIHJlbGFjacOzbiBlbnRyZSBsYSBzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhIHkgZWwgZ8OpbmVybywgdGFtYmnDqW4gc2UgcHVlZGUgdXNhciBsYSBwcnVlYmEgZGUgaW5kZXBlbmRlbmNpYSBkZSAkXGNoaV4yJC4KRXN0YSBldmFsdWFjacOzbiBzZSBndWFyZGEgZW4gdW4gb2JqZXRvICJwcnVlYmEyIi4KCmBgYHtyIHBydWViYX0KcHJ1ZWJhMiA8LSBjaGlzcS50ZXN0KGxhcG9wMTgkc2F0aXMsIGxhcG9wMTgkZWR1YykKcHJ1ZWJhMgpgYGAKCk51ZXZhbWVudGUgc2Ugb2J0aWVuZSB1biBwLXZhbHVlIG1lbm9yIGRlIDAuMDUsIGNvbiBsbyBxdWUgc2UgcmVjaGF6YSBsYSBoaXDDs3Rlc2lzIG51bGEgeSBzZSBhZmlybWEgcXVlIGxhcyBmcmVjdWVuY2lhcyBvYnNlcnZhZGFzIHNvbiBkaWZlcmVudGVzIGRlIGxhcyBlc3BlcmFkYXMsIGNvbiBsbyBxdWUgY29uY2x1aW1vcyBxdWUgZXhpc3RpcsOtYSB1bmEgcmVsYWNpw7NuIGRlIGRlcGVuZGVuY2lhIGVudHJlIGxhcyB2YXJpYWJsZXMuCgpQYXJhIGV2YWx1YXIgbGEgZnVlcnphIGRlIGxhIHJlbGFjacOzbiBzZSB1c2EgbGEgbGlicmVyw61hIGBvaWlgIHF1ZSBjdWVudGEgY29uIGVsIGNvbWFuZG8gYGFzc29jaWF0aW9uLm1lYXN1cmVzYCBxdWUgbm9zIGJyaW5kYSB1bmEgc2VyaWUgZGUgbWVkaWRhcyBkZSBhc29jaWFjacOzbiBhZGVjdWFkYXMgcGFyYSBlbCB0aXBvIGRlIHZhcmlhYmxlcyBxdWUgc2UgZXN0w6FuIHJlbGFjaW9uYW5kbywgcXVlIHNvbiBhbWJhcyBkZSB0aXBvIG9yZGluYWwuCgpgYGB7ciBvcmRpbmFsfQpsaWJyYXJ5KG9paSkKYXNzb2NpYXRpb24ubWVhc3VyZXMobGFwb3AxOCRzYXRpcywgbGFwb3AxOCRlZHVjKQpgYGAKCkVuIGVzdGUgY2FzbyBzZSBvYnNlcnZhbiBsYXMgbWVkaWRhcyBkZSBhc29jaWFjacOzbiBwYXJhIHZhcmlhYmxlcyBvcmRpbmFsZXMuCkVzdGUgY29tYW5kbyByZXBvcnRhIDQgc2UgZXN0YXMgbWVkaWRhcywgdG9kYXMgZWxsYXMgdmFyw61hbiBlbnRyZSAtMSBhICsxLgpFbiBudWVzdHJvIGVqZW1wbG8sIHRvZGFzIHRpZW5lIHNpZ25vIHBvc2l0aXZvLCBsbyBxdWUgaW5kaWNhIHVuYSByZWxhY2nDs24gZGlyZWN0YSBlbnRyZSBhbWJhcyB2YXJpYWJsZXMuCkVzdG8gcGFyZWNlcsOtYSBpciBjb250cmEgbG8gcXVlIHNlIHJlcG9ydGEgZW4gZWwgR3LDoWZpY28gMS4xNCBkZWwgcmVwb3J0ZSBkb25kZSBzZSBvYnNlcnZhIGNsYXJhbWVudGUgcXVlIGxhIHNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEgZGlzbWludXllIGEgbml2ZWxlcyBlZHVjYXRpdm9zIG3DoXMgYWx0b3MsIGxvIHF1ZSBzZSBleHByZXNhcsOtYSBlbiB1biBzaWdubyBuZWdhdGl2by4KCkVzdGEgYXBhcmVudGUgY29udHJhZGljY2nDs24gZXMgZGViaWRvIGEgbGEgZm9ybWEgY29tbyBzZSBoYSBjb2RpZmljYWRvIGxhIHNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEgKHZhcmlhYmxlICJzYXRpcyIgcXVlIHNlIGNyZWEgZGVzZGUgInBuNCIpLgpMYSB2YXJpYWJsZSBvcmlnaW5hbCB0aWVuZSB2YWxvcmVzIGVudHJlIDEgYSA0LCBkb25kZSAxIHNpZ25pZmljYSAibXV5IHNhdGlzZmVjaG8iIHkgNCAibXV5IGluc2F0aXNmZWNobyIuCkVzIGRlY2lyLCBlc3RhIHZhcmlhYmxlIHRpZW5lIHVuYSBjb2RpZmljYWNpw7NuIGRvbmRlIHZhbG9yZXMgYWx0b3MgaW5kaWNhbiAibWVub3MiIGRlIGxhIHZhcmlhYmxlLgpFcyBwb3IgZXNlIG1vdGl2byBxdWUgbGEgcHJ1ZWJhIGRlIGFzb2NpYWNpw7NuIHJlc3VsdGEgY29uIHVuIHNpZ25vIHBvc2l0aXZvLCBxdWUgZW4gZXN0ZSBjYXNvIGluZGljYXLDrWEgcXVlIHVuIHZhbG9yIG1heW9yIGRlIGxhIHZhcmlhYmxlIGRlIGVkdWNhY2nDs24gc2lnbmlmaWNhICJtw6FzIiBkZSBsYSB2YXJpYWJsZSBzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhIChxdWUgZW4gcmVhbGlkYWQgZXMgbWVub3MpLgoKUGFyYSBldml0YXIgZXN0YSBjb25mdXNpw7NuIHNlIGRlYmnDsyBjYW1iaWFyIGxhIG1vbm90b27DrWEgZGUgbGEgdmFyaWFibGUgc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSBwYXJhIHF1ZSB2YWxvcmVzIG3DoXMgYWx0b3MgaW5kaXF1ZW4gdW5hIG1heW9yIHNhdGlzZmFjY2nDs24geSwgY29uIGVzdG8sIHNlIG9idGVuZ2EgdW4gc2lnbm8gbmVnYXRpdm8gZW4gbGFzIG1lZGlkYXMgZGUgYXNvY2lhY2nDs24uCkVuIGVzdGEgc2VjY2nDs24gc2UgaGEgcHJvY2VkaWRvIGRlIGVzYSBtYW5lcmEgcGFyYSBsbGFtYXIgbGEgYXRlbmNpw7NuIGEgcXVlIGxhIGNvZGlmaWNhY2nDs24gdGllbmUgY29uc2VjdWVuY2lhcyBlbiBsb3MgcmVzdWx0YWRvcyB5IHB1ZWRlIGxsZXZhciBhIGNvbmZ1c2nDs24gc2kgbm8gc2UgcHJlc3RhIGF0ZW5jacOzbi4KCkZpbmFsbWVudGUsIGVsIHZhbG9yIGRlIGxhcyBtZWRpZGFzIGRlIGFzb2NpYWNpw7NuIHNvbiBtZW5vcmVzIGEgMC4zLCBjb24gbG8gcXVlIHNlIGluZGljYSBxdWUgbGEgcmVsYWNpw7NuIGVudHJlIGxhcyB2YXJpYWJsZXMgZXMgZMOpYmlsLgoKIyBSZXN1bWVuCgpFbiBlc3RhIHNlY2Npw7NuIGhlbW9zIHRyYWJhamFkbyBjb24gcmVsYWNpb25lcyBiaXZhcmlhZGFzIGVudHJlIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMuClNlIGhhIGNhbGN1bGFkbyBsYXMgdGFibGFzIGNydXphZGFzIHkgbG9zIGdyw6FmaWNvcyBkZSBiYXJyYXMgcGFyYSBtb3N0cmFyIGxvcyByZXN1bHRhZG9zIGRlc2NyaXB0aXZvcy4KTHVlZ28sIHNlIGhhIHRyYWJhamFkbyBjb24gbGEgcHJ1ZWJhIGRlIGluZGVwZW5kZW5jaWEgZGUgY2hpLWN1YWRyYWRvIHBhcmEgaW5mZXJpciBzaSBleGlzdGUgdW5hIHJlbGFjacOzbiBkZSBkZXBlbmRlbmNpYSBlbnRyZSBsYXMgdmFyaWFibGVzIGVuIGxhIHBvYmxhY2nDs24geSBmaW5hbG1lbnRlIHNlIGV2YWzDumEgbGEgZnVlcnphIGRlIGxhIGFzb2NpYWNpw7NuIGVudHJlIGxhcyB2YXJpYWJsZXMsIGRpZmVyZW5jaWFuZG8gY3VhbmRvIHNlIHRyYXRhIGRlIHZhcmlhYmxlcyBub21pbmFsZXMgdSBvcmRpbmFsZXMuCgojIEPDoWxjdWxvcyBpbmNsdXllbmRvIGVsIGVmZWN0byBkZSBkaXNlw7FvCgpFbiBsYSBzZWNjacOzbiBzb2JyZSBbZGVzY3JpcHRpdm9zIGRlIHZhcmlhYmxlcyBvcmRpbmFsZXNdKGh0dHBzOi8vYXJ0dXJvbWFsZG9uYWRvLmdpdGh1Yi5pby9CYXJvbWV0cm9FZHVfV2ViL0Rlc2NyaXB0aXZvczIuaHRtbCkgc2UgcHJvY2VkacOzIGEgY2FsY3VsYXIgbG9zIHBvcmNlbnRhamVzIGRlIHNpIGxvcyB2b3RvcyBzZSBjdWVudGFuIGp1c3RhbWVudGUgcG9yIHBhw61zIGluY29ycG9yYW5kbyBlbCBlZmVjdG8gZGUgZGlzZcOxby4KQ29uIGVzdG9zIGRhdG9zLCBzZSBwcm9jZWRpw7MgYSByZXBsaWNhciBleGFjdGFtZW50ZSBlbCBncsOhZmljbyAyLjUuCgpQYXJhIGNhbGN1bGFyIGxhIHBydWViYSBjaGkgY3VhZHJhZG8sIGluY2x1eWVuZG8gZWwgZmFjdG9yIGRlIGV4cGFuc2nDs24sIHNlIHB1ZWRlIHVzYXIgbGEgbGlicmVyw61hIGBzdXJ2ZXlgIHkgZWwgY29tYW5kbyBgc3Z5Y2hpc3FgLgoKYGBge3IgZGlzZW5vfQpsaWJyYXJ5KHN1cnZleSkKZGlzZW5vMTg8LXN2eWRlc2lnbihpZHMgPSB+dXBtLCBzdHJhdGEgPSB+ZXN0cmF0b3ByaSwgd2VpZ2h0cyA9IH53ZWlnaHQxNTAwLCBuZXN0PVRSVUUsIGRhdGE9bGFwb3AxOCkKYGBgCgpTZSBjYWxjdWxhIGxhIHRhYmxhIGRlIGNvbnRpbmdlbmNpYSBjb24gZWwgY29tYW5kbyBgc3Z5dGFibGVgLgpFbiBlc3RlIGNhc28gY3J1emFuZG8gc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSBwb3IgZ8OpbmVyby4KRXN0ZSBjb21hbmRvIHNlIGFuaWRhIGRlbnRybyBkZSBgcHJvcC50YWJsZWAgcGFyYSBwcmVzZW50YXIgbGFzIGZyZWN1ZW5jaWFzIHJlbGF0aXZhcyB5IG5vIGxhcyBhYnNvbHV0YXMuCkEgc3UgdmV6LCB0b2RvIGVzdG8gc2UgdnVlbHZlIGEgYW5pZGFyIGRlbnRybyBkZWwgY29tYW5kbyBgYWRkbWFyZ2luc2AgcGFyYSBwcmVzZW50YXIgbGFzIGZyZWN1ZW5jaWFzIHJlbGF0aXZhcyBjb21vIHBvcmNlbnRhamVzLgpEZSBsYSBtaXNtYSBtYW5lcmEgcXVlIG3DoXMgYXJyaWJhLCBlc3RhIHRhYmxhIHNlIHB1ZWRlIGd1YXJkYXIgZW4gdW4gb2JqZXRvIHBhcmEgbHVlZ28gZ3JhZmljYXIgZXN0b3MgcmVzdWx0YWRvcy4KCmBgYHtyIHRhYmxhd30KYWRkbWFyZ2lucyhwcm9wLnRhYmxlKHN2eXRhYmxlKH5zYXRpcytnZW5lcm8sIGRlc2lnbj1kaXNlbm8xOCksMikqMTAwLDEpCmBgYAoKTGEgcHJ1ZWJhIGRlIGluZGVwZW5kZW5jaWEgZGUgQ2hpLWN1YWRyYWRvIGluY29ycG9yYW5kbyBlbCBlZmVjdG8gZGUgZGlzZcOxbyBzZSBjYWxjdWxhIHVzYW5kbyBlbCBjb21hbmRvIGBzdnljaGlzcWAuClNlIGluY2x1eWEgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUsIGxhIGluZGVwZW5kaWVudGUgeSBlbCBvYmpldG8gY29uIGVsIGRpc2XDsW8gbXVlc3RyYWwuCgpgYGB7ciBjaGl3fQpwcnVlYmEzID1zdnljaGlzcSh+c2F0aXMrZ2VuZXJvLGRpc2VubzE4KQpwcnVlYmEzCmBgYAoKTG9zIHJlc3VsdGFkb3MgbXVlc3RyYW4gdW4gcC12YWx1ZSBtZW5vciBhIDAuMDUsIHBvciBsbyBxdWUgc2UgcHVlZGUgcmVjaGF6YXIgbGEgSDAgZGUgaWd1YWxkYWQgZGUgZnJlY3VlbmNpYXMgZXNwZXJhZGFzIGNvbiBvYnNlcnZhZGFzLCBwb3IgbG8gcXVlIHNlIGNvbmNsdXllIHF1ZSBleGlzdGUgdW5hIHJlbGFjacOzbiBkZSBkZXBlbmRlbmNpYSBlc3RhZMOtc3RpY2EgZW50cmUgYW1iYXMgdmFyaWFibGVzLgoKU2UgcHVlZGUgY2FsY3VsYXIgbG9zIHZhbG9yZXMgb2JzZXJ2YWRvcyB5IGVzcGVyYWRvcy4KQ29tbyBzZSBwdWVkZSB2ZXIsIGxvcyB2YWxvcmVzIGVzcGVyYWRvcyBkaWZpZXJlbiBkZSBsb3MgcmVzdWx0YWRvcyBzaW4gZWwgZWZlY3RvIGRlIGRpc2XDsW8uCgpgYGB7ciBvYnN2cmV4cHd9CnBydWViYTMkb2JzZXJ2ZWQKcHJ1ZWJhMyRleHBlY3RlZApgYGAKCkVuIGVzdGUgY2FzbyBubyBzZSBjdWVudGEgY29uIHVuIGNvbWFuZG8gcGFyYSBwb2RlciBjYWxjdWxhciBsYXMgbWVkaWRhcyBkZSBhc29jaWFjacOzbiBpbmNvcnBvcmFuZG8gZWwgZWZlY3RvIGRlIGRpc2XDsW8uClNlIHB1ZWRlbiB0b21hciBsYXMgbWVkaWRhcyBkZSBhc29jaWFjacOzbiBubyBwb25kZXJhZG9zIGNvbW8gdmFsb3JlcyByZWZlcmVuY2lhbGVzLgo=