Introducción

La prueba t y la prueba de ANOVA analiza el impacto de una variable independiente categórica en una variable dependiente numérica. El paso que vamos a dar en esta sección es analizar la relación bivariada entre dos variables de factor (o categóricas). Esta evaluación se realiza mediante la prueba de chi-cuadrado.

  • Chi-cuadrado:

    • Variable independiente (país) -> Variable dependiente (apoyo a la democracia).

    • Variable independiente (situación económica) -> Variable dependiente (satisfacción con la vida)

    • Variable independiente(nivel educativo) -> Variable dependiente (satisfacción con la democracia)

Tablas de contingencia

Se trata de tablas de doble entrada (como mínimo) para analizar los datos de variables categóricas. Una variable va en las filas y otra en las columnas. Se puede tener los totales por filas o por columnas, que se llaman “distribuciones marginales” y que coinciden con la distribución de la variable individual.

Se puede calcular porcentajes de 3 maneras:

  • Porcentajes por filas

  • Porcentajes por columnas

  • Porcentaje sobre el total

Se recomienda que la variable independiente sea colocada en las columnas y la variable dependiente en las filas. Si se calcula los porcentajes por columnas de esta manera, se podrá comparar las distribuciones condicionales de la variable dependiente por cada grupo de la variable independiente.

En este documento vamos a trabajar con el reporte comparado El Pulso de la Democracia, disponible aquí. Este reporte presenta los principales hallazgos del proyecto del Barómetro de las Américas, organizado por el Proyecto de Opinión Pública en América Latina (LAPOP, por sus siglas en inglés). En este documento se reportan los resultados de la última ronda disponible de 2023.

Pueden descargar los datos de manera libre aquí.](http://datasets.americasbarometer.org/database/login.php).) En este enlace, se pueden registrar o entrar como “Free User”. En el buscador, se puede ingresar el texto “2023”. Ahí se tendrá acceso a las bases de datos completas de la ronda 2021 y de todas las rondas de cada país en versión para STATA. Se descarga la base de datos en formato .dta. Una vez descargada y guardada en el directorio de trabajo, se tiene que leer la base de datos como un objeto dataframe en R. El cuestionario de esta base de datos puede ser visto en este enlace.

library(rio)
peru23 = import("bases/PER_2023_LAPOP_AmericasBarometer_v1.0_w.sav")

Desde la pag. 20 del reporte se hace una evaluación de la democracia en la práctica. En particular, se trabaja con la variable PN4. 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 Perú. El reporte se indica que los datos se recodifican en una variable dicotómica. En este documento vamos a trabajar con la variable original. Esta variable es una variable categórica, ordinal o de factor. 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ómica, 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áficas y socioeconómica como variables independientes.

Por ejemplo, se reporta que entre los hombres, el 42.3% están satisfechos con la democracia, mientras que entre las mujeres, este porcentaje disminuye a 36.9%.

Antes de proceder, tenemos que recodificar las variables, ponerlas en forma de factor y etiquetar.

library(tidyverse)
peru23 = peru23 %>%
  mutate(sexo = factor(q1tc_r, labels=c("Hombre", "Mujer")))
table(peru23$sexo)
## 
## Hombre  Mujer 
##    769    761

Lo mismo para la variable PN4 que se transforma en la variable “satis”.

peru23 = peru23 %>%
  mutate(satis = factor(pn4, labels= c("Muy satisfecho", "Satisfecho", 
                                       "Insatisfecho", "Muy insatisfecho")))
tabla1 = table(peru23$satis)
tabla1
## 
##   Muy satisfecho       Satisfecho     Insatisfecho Muy insatisfecho 
##               58              233              944              280

Para calcular la tabla de satisfacción con la democracia, independiente del género de la persona, se puede calcular los porcentajes de esta variable con el comando prop.table. Se multuplica por 100 para tener el formato de porcentaje.

tabla1 %>%
  prop.table()*100
## 
##   Muy satisfecho       Satisfecho     Insatisfecho Muy insatisfecho 
##         3.828383        15.379538        62.310231        18.481848

Ahora, se puede calcular la tabla de contingencia entre satisfacción y género. El comando table nos brinda las frecuencias absolutas del cruce entre ambas variables. La variable dependiente “satisfacción con la democracia” se ubica en las filas y la variable independiente “sexo” en las columnas. Se verifica que las 58 observaciones que están muy satisfechas con la democracia, se dividen en 27 hombres y 29 mujeres.

tabla2 = table(peru23$satis, peru23$sexo)
tabla2
##                   
##                    Hombre Mujer
##   Muy satisfecho       27    29
##   Satisfecho          132   101
##   Insatisfecho        456   485
##   Muy insatisfecho    148   132

Para calcular las frecuencias relativas, se tiene que usar el comando prop.table. Se agrega la especificación (2) para indicar que se quiere las proporciones sobre las columnas. Se sigue con el comando round para eliminar los decimales innecesarios y finalmente se usa addmargins para verificar la suma de proporciones sobre las columnas.

tabla3 = tabla2 %>%
  prop.table(2) %>%
  round(3)*100 
tabla3
##                   
##                    Hombre Mujer
##   Muy satisfecho      3.5   3.9
##   Satisfecho         17.3  13.5
##   Insatisfecho       59.8  64.9
##   Muy insatisfecho   19.4  17.7

En esta tabla se muestra las distribuciones condicionales de satisfacción con la democracia por cada grupo de género. Por ejemplo, el 3.5% de los hombres se encuentras muy satisfechos con la democracia, un porcentaje algo similar al 3.9% de las mujeres. El 17.3% de los hombres se encuentran satisfechos con la democracia, 4 puntos porcentuales por encima que las mujeres.

De esta manera, se pueden comparar los porcentajes por cada categoría de la variable dependiente entre grupos de la variable independiente y, además, se puede comparar con los porcentajes no condicionales de la variable satisfacción con la democracia.

peru23 = peru23 %>%
  mutate(protesta = factor(prot3, labels= c("Sí ha participado", 
                                            "No ha participado")))
tabla4 = table(peru23$protesta, peru23$sexo)
tabla4 = tabla4 %>%
  prop.table(2) %>%
  round(3)*100
tabla4
##                    
##                     Hombre Mujer
##   Sí ha participado   13.3  10.2
##   No ha participado   86.7  89.8
prueba2 = chisq.test(peru23$protesta, peru23$sexo)
prueba2
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  peru23$protesta and peru23$sexo
## X-squared = 3.0967, df = 1, p-value = 0.07845
peru23 = peru23 %>%
  mutate(urbano = factor(ur, labels= c("Urbano", "Rural")))
tabla5 = table(peru23$protesta, peru23$urbano)
tabla5 = tabla5 %>%
  prop.table(2) %>%
  round(3)*100
tabla5
##                    
##                     Urbano Rural
##   Sí ha participado   10.4  16.1
##   No ha participado   89.6  83.9
prueba3 = chisq.test(peru23$protesta, peru23$urbano)
prueba3
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  peru23$protesta and peru23$urbano
## X-squared = 8.1579, df = 1, p-value = 0.004287

Gráficos bivariados categóricos

Para crear un 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. Nótese que el dataframe guarda los porcentajes en otro formato.

tabla4 = as.data.frame(tabla3)
tabla4
##               Var1   Var2 Freq
## 1   Muy satisfecho Hombre  3.5
## 2       Satisfecho Hombre 17.3
## 3     Insatisfecho Hombre 59.8
## 4 Muy insatisfecho Hombre 19.4
## 5   Muy satisfecho  Mujer  3.9
## 6       Satisfecho  Mujer 13.5
## 7     Insatisfecho  Mujer 64.9
## 8 Muy insatisfecho  Mujer 17.7

En este caso, como tenemos 4 categorías para satisfacción con la democracia y otras 2 para sexo, un gráfico de barras separadas crearía 8 barras.

library(ggplot2)
ggplot(data=tabla4, aes(x=Var1, y=Freq, fill=Var2))+
  geom_bar(position = "dodge", stat="identity")+
  geom_text(aes(label=paste(Freq, "%", sep="")), 
            position = position_dodge(width = 0.9), 
            vjust=0, size = 3)+
  labs(x="Satisfacción con la democracia", y="Porcentaje", fill="Sexo")

Esta forma de graficar puede complicar la comparación en algunos casos. Por eso, en otros casos, se prefiere el tipo de barras apiladas.

ggplot(data=tabla4, aes(x=Var2, y=Freq, fill=Var1))+
  geom_bar(position="stack", stat="identity")+
  geom_text(aes(label=paste(Freq, "%", sep="")), 
            position = position_stack(), vjust=1, size = 3)+
  labs(x="Sexo", y="Porcentaje", fill="Satisfacción con la democracia")

Independencia y dependencia

Decimos que dos variables categóricas son estadísticamente independientes si las distribuciones condicionales (poblacionales) son idénticas por cada categoría de la variable independiente. Por ejemplo, la siguiente tabla, si mostrara los porcentajes poblacionales condicionales, estos son idénticos entre grupos de la variable independiente. Es decir, independientemente de ser hombre o mujer, las distribución de satisfacción por la democracia es la misma. Ser hombre o mujer no cambia nada las opiniones con respecto a la satisfacción con la democracia.

Satisfacción con la democracia Hombre Mujer
Muy satisfecho 3.5% 3.9%
Satisfecho 17.3% 13.5%
Insatisfecho 59.8% 64.9%
Muy insatisfecho 19.4% 17.7%

VI: fuma ———> VD: cáncer de pulmón

Fuma
Cáncer al pulmón Fumador No fumador
Si desarrolla cáncer 10 10
No desarrolla cáncer 90 90
Total 100% 100%

A medida que estos porcentajes difieren más entre sí, hay más probabilidades que ambas variables estén relacionadas. En realidad, a medida que estos porcentajes difieren más de la distribución no condicional de la variable satisfacción con la democracia también habría una mayor probabilidad de que estén relacionadas.

Prueba de independencia de chi-cuadrado

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ía haber en cada celda de la tabla si las variables fueran independientes). En ese sentido \(H_0: f_e = f_o\) o lo que es lo mismo que las variables son independientes.

Si no hubiera relación entre las variables, tendríamos los mismo porcentajes reproducidos en las distribuciones condicionales.

Col1 Hombres Mujeres
MS

2.1% de hombres -> #observaciones si no hay relación

cuánto es el 2.1% de 1617 = 34 -> #obs si NO hubiera relación

Pero, 19 es lo realmente observado

(19-34)^2

2.1% de mujeres -> #observaciones si no hay relación

cuánto es el 2.1% de 1421 = 29.8 -> #obs si NO hubiera relación

Pero, 12 es lo realmente observado

(12-29.8)^2

S 18.6% 18.6%
I 61.3% 61.3%
MI 18% 18%
100% 100%

Prueba estadística

El chi-cuadrado resume qué tan cerca están las frecuencias esperadas de las frecuencias observadas. Mientras más pequeña la distancia en cada celda, menos probabilidades de rechazar la hipótesis nula. Mientras la distancia más grande en cada celda ,más probabilidades de rechazar la hipótesis nula.

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

  • Si fo=fe en cada celda, entonces χ^2 = 0

  • Con el valor de \(\chi^2\) se calcula un p-value, que tiene que ser menor de 0.05 para rechazar la Ho.

  • Se requiere que haya al menos 5 observaciones en cada celda

En R se usa el comando chisq.test para calcular el estadístico y el p-value. Esta prueba es mejor guardarla en un objeto nuevo

prueba = chisq.test(peru23$satis, peru23$sexo)

La primera tabla presenta las frecuencias observadas, que es lo que realmente se recoge en campo. La segunda tabla presenta las frecuencias esperadas (si no hubiera relación). Se comprueba los cálculos que se hizo en la tabla anterior (las diferencias son debido a la aproximación decimal).

El estadístico \(\chi^2\) resume las diferencias entre las frecuencias observadas y esperadas en cada celda y las suma de acuerdo a la fórmula.

prueba
## 
##  Pearson's Chi-squared test
## 
## data:  peru23$satis and peru23$sexo
## X-squared = 5.835, df = 3, p-value = 0.1199

La prueba nos da como resultado un p-value = 0.12, por lo que NO se puede rechazar la hipótesis nula y se concluye que no sabemos si existe asociación/relación/dependencia entre las variables.

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 para Perú 2023.

Vamos a recodificar la variable educación. La variable original “edre” separa los niveles educativos en 7 niveles (del 0 al 6). Los analfabetos son un grupo muy pequeño y podrían causar problemas.

Primero, creamos una variable “educ”, como el factor de “edre”. Luego, se etiqueta.

peru23 = peru23 |>
  mutate(educ = factor(edre, labels=c("Analfabeto", "Primaria incompleta", 
                                      "Primaria completa","Secundaria incompleta",
                                      "Secundaria completa",
                                      "Universitaria o técnica incompleta", 
                                      "Universitaria o técnica completa")))
table(peru23$educ)
## 
##                         Analfabeto                Primaria incompleta 
##                                  8                                 80 
##                  Primaria completa              Secundaria incompleta 
##                                 90                                133 
##                Secundaria completa Universitaria o técnica incompleta 
##                                511                                270 
##   Universitaria o técnica completa 
##                                443

Vamos a crear otra variable de educación “educ2” que junte categorías para que no hayan 7 niveles educativos.

peru23 = peru23 |>
    mutate(educ2= case_when(
    edre == 0 ~ 1,
    edre == 1 ~ 1,
    edre == 2 ~ 1,
    edre == 3 ~ 2,
    edre == 4 ~ 2,
    edre == 5 ~ 3,
    edre == 6 ~ 4,
    ))
peru23 = peru23 |>
  mutate(educ2 = factor(educ2, labels=c("Hasta primaria ", "Hasta secundaria",
                                      "Universitaria o técnica incompleta", 
                                      "Universitaria o técnica completa")))
table(peru23$educ2)
## 
##                    Hasta primaria                    Hasta secundaria 
##                                178                                644 
## Universitaria o técnica incompleta   Universitaria o técnica completa 
##                                270                                443

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

tabla4 = table(peru23$satis, peru23$educ2)
tabla4
##                   
##                    Hasta primaria  Hasta secundaria
##   Muy satisfecho                23               25
##   Satisfecho                    20              112
##   Insatisfecho                  88              405
##   Muy insatisfecho              36               94
##                   
##                    Universitaria o técnica incompleta
##   Muy satisfecho                                    3
##   Satisfecho                                       38
##   Insatisfecho                                    180
##   Muy insatisfecho                                 49
##                   
##                    Universitaria o técnica completa
##   Muy satisfecho                                  7
##   Satisfecho                                     63
##   Insatisfecho                                  271
##   Muy insatisfecho                              101
tabla4 = tabla4 |>
  prop.table(2) |>
  round(3)*100
tabla4
##                   
##                    Hasta primaria  Hasta secundaria
##   Muy satisfecho              13.8              3.9
##   Satisfecho                  12.0             17.6
##   Insatisfecho                52.7             63.7
##   Muy insatisfecho            21.6             14.8
##                   
##                    Universitaria o técnica incompleta
##   Muy satisfecho                                  1.1
##   Satisfecho                                     14.1
##   Insatisfecho                                   66.7
##   Muy insatisfecho                               18.1
##                   
##                    Universitaria o técnica completa
##   Muy satisfecho                                1.6
##   Satisfecho                                   14.3
##   Insatisfecho                                 61.3
##   Muy insatisfecho                             22.9

Gráfico bivariado de satisfacción con la democracia según educación

tabla5 = as.data.frame(tabla4)
tabla5
##                Var1                               Var2 Freq
## 1    Muy satisfecho                    Hasta primaria  13.8
## 2        Satisfecho                    Hasta primaria  12.0
## 3      Insatisfecho                    Hasta primaria  52.7
## 4  Muy insatisfecho                    Hasta primaria  21.6
## 5    Muy satisfecho                   Hasta secundaria  3.9
## 6        Satisfecho                   Hasta secundaria 17.6
## 7      Insatisfecho                   Hasta secundaria 63.7
## 8  Muy insatisfecho                   Hasta secundaria 14.8
## 9    Muy satisfecho Universitaria o técnica incompleta  1.1
## 10       Satisfecho Universitaria o técnica incompleta 14.1
## 11     Insatisfecho Universitaria o técnica incompleta 66.7
## 12 Muy insatisfecho Universitaria o técnica incompleta 18.1
## 13   Muy satisfecho   Universitaria o técnica completa  1.6
## 14       Satisfecho   Universitaria o técnica completa 14.3
## 15     Insatisfecho   Universitaria o técnica completa 61.3
## 16 Muy insatisfecho   Universitaria o técnica completa 22.9
ggplot(data=tabla5, aes(x=Var2, y=Freq, fill=Var1))+
  geom_bar(position="stack", stat="identity")+
  geom_text(aes(label=paste(Freq, "%", sep="")), 
            position = position_stack(), vjust=1, size = 3)+
  labs(x="Nivel educativo", y="Porcentaje", 
       fill="Satisfacción con la democracia")

Prueba estadística entre satisfacción con la democracia según educación

Para comprobar la relación entre estas variables, también se puede usar la prueba de independencia de \(\chi^2\). Esta evaluación se guarda en un objeto “prueba2”.

prueba2 = chisq.test(peru23$satis, peru23$educ2)
prueba2
## 
##  Pearson's Chi-squared test
## 
## data:  peru23$satis and peru23$educ2
## X-squared = 71.87, df = 9, p-value = 6.539e-12
prueba2 = chisq.test(peru23$satis, peru23$educ2)
prueba2
## 
##  Pearson's Chi-squared test
## 
## data:  peru23$satis and peru23$educ2
## X-squared = 71.87, df = 9, p-value = 6.539e-12

Con el valor de estadístico se obtiene un p-value menor a 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 sí existe una relación de dependencia entre las variables. Esto quiere decir que en Perú en 2023 existen diferencias en la satisfacción con la democracia entre diferentes grupos por nivel educativo.

LS0tCnRpdGxlOiAiQ2xhc2UgNyIKYXV0aG9yOiAiQXJ0dXJvIE1hbGRvbmFkbyIKZGF0ZTogIjAxLzEwLzIwMjQiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIHRvY19kZXB0aDogMQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IGNvc21vCiAgICBoaWdobGlnaHQ6IHRleHRtYXRlCmVkaXRvcl9vcHRpb25zOgogIG1hcmtkb3duOgogICAgd3JhcDogc2VudGVuY2UKYmlibGlvZ3JhcGh5OiByZWZlcmVuY2VzLmJpYgotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyBJbnRyb2R1Y2Npw7NuCgpMYSBwcnVlYmEgdCB5IGxhIHBydWViYSBkZSBBTk9WQSBhbmFsaXphIGVsIGltcGFjdG8gZGUgdW5hIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgY2F0ZWfDs3JpY2EgZW4gdW5hIHZhcmlhYmxlIGRlcGVuZGllbnRlIG51bcOpcmljYS4KRWwgcGFzbyBxdWUgdmFtb3MgYSBkYXIgZW4gZXN0YSBzZWNjacOzbiBlcyBhbmFsaXphciBsYSAqKnJlbGFjacOzbiBiaXZhcmlhZGEgZW50cmUgZG9zIHZhcmlhYmxlcyBkZSBmYWN0b3IgKG8gY2F0ZWfDs3JpY2FzKSoqLgpFc3RhIGV2YWx1YWNpw7NuIHNlIHJlYWxpemEgbWVkaWFudGUgbGEgcHJ1ZWJhIGRlIGNoaS1jdWFkcmFkby4KCi0gICBDaGktY3VhZHJhZG86CgogICAgLSAgIFZhcmlhYmxlIGluZGVwZW5kaWVudGUgKHBhw61zKSAtXD4gVmFyaWFibGUgZGVwZW5kaWVudGUgKGFwb3lvIGEgbGEgZGVtb2NyYWNpYSkuCgogICAgLSAgIFZhcmlhYmxlIGluZGVwZW5kaWVudGUgKHNpdHVhY2nDs24gZWNvbsOzbWljYSkgLVw+IFZhcmlhYmxlIGRlcGVuZGllbnRlIChzYXRpc2ZhY2Npw7NuIGNvbiBsYSB2aWRhKQoKICAgIC0gICBWYXJpYWJsZSBpbmRlcGVuZGllbnRlKG5pdmVsIGVkdWNhdGl2bykgLVw+IFZhcmlhYmxlIGRlcGVuZGllbnRlIChzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhKQoKIyBUYWJsYXMgZGUgY29udGluZ2VuY2lhCgpTZSB0cmF0YSBkZSB0YWJsYXMgZGUgZG9ibGUgZW50cmFkYSAoY29tbyBtw61uaW1vKSBwYXJhIGFuYWxpemFyIGxvcyBkYXRvcyBkZSB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzLgpVbmEgdmFyaWFibGUgdmEgZW4gbGFzIGZpbGFzIHkgb3RyYSBlbiBsYXMgY29sdW1uYXMuClNlIHB1ZWRlIHRlbmVyIGxvcyB0b3RhbGVzIHBvciBmaWxhcyBvIHBvciBjb2x1bW5hcywgcXVlIHNlIGxsYW1hbiAiZGlzdHJpYnVjaW9uZXMgbWFyZ2luYWxlcyIgeSBxdWUgY29pbmNpZGVuIGNvbiBsYSBkaXN0cmlidWNpw7NuIGRlIGxhIHZhcmlhYmxlIGluZGl2aWR1YWwuCgpTZSBwdWVkZSBjYWxjdWxhciBwb3JjZW50YWplcyBkZSAzIG1hbmVyYXM6CgotICAgUG9yY2VudGFqZXMgcG9yIGZpbGFzCgotICAgUG9yY2VudGFqZXMgcG9yIGNvbHVtbmFzCgotICAgUG9yY2VudGFqZSBzb2JyZSBlbCB0b3RhbAoKU2UgcmVjb21pZW5kYSBxdWUgbGEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZSBzZWEgY29sb2NhZGEgZW4gbGFzIGNvbHVtbmFzIHkgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUgZW4gbGFzIGZpbGFzLgpTaSBzZSBjYWxjdWxhIGxvcyBwb3JjZW50YWplcyBwb3IgY29sdW1uYXMgZGUgZXN0YSBtYW5lcmEsIHNlIHBvZHLDoSBjb21wYXJhciBsYXMgZGlzdHJpYnVjaW9uZXMgY29uZGljaW9uYWxlcyBkZSBsYSB2YXJpYWJsZSBkZXBlbmRpZW50ZSBwb3IgY2FkYSBncnVwbyBkZSBsYSB2YXJpYWJsZSBpbmRlcGVuZGllbnRlLgoKRW4gZXN0ZSBkb2N1bWVudG8gdmFtb3MgYSB0cmFiYWphciBjb24gZWwgcmVwb3J0ZSBjb21wYXJhZG8gKkVsIFB1bHNvIGRlIGxhIERlbW9jcmFjaWEqLCBkaXNwb25pYmxlIFthcXXDrV0oaHR0cHM6Ly93d3cudmFuZGVyYmlsdC5lZHUvbGFwb3AvYWIyMDE4LzIwMTgtMTlfQW1lcmljYXNCYXJvbWV0ZXJfUmVnaW9uYWxfUmVwb3J0X1NwYW5pc2hfV18wMy4yNy4yMC5wZGYpLgpFc3RlIHJlcG9ydGUgcHJlc2VudGEgbG9zIHByaW5jaXBhbGVzIGhhbGxhemdvcyBkZWwgcHJveWVjdG8gZGVsIEJhcsOzbWV0cm8gZGUgbGFzIEFtw6lyaWNhcywgb3JnYW5pemFkbyBwb3IgZWwgUHJveWVjdG8gZGUgT3BpbmnDs24gUMO6YmxpY2EgZW4gQW3DqXJpY2EgTGF0aW5hIChbTEFQT1BdKGh0dHBzOi8vd3d3LnZhbmRlcmJpbHQuZWR1L2xhcG9wLyksIHBvciBzdXMgc2lnbGFzIGVuIGluZ2zDqXMpLgpFbiBlc3RlIGRvY3VtZW50byBzZSByZXBvcnRhbiBsb3MgcmVzdWx0YWRvcyBkZSBsYSDDumx0aW1hIHJvbmRhIGRpc3BvbmlibGUgZGUgMjAyMy4KClB1ZWRlbiBkZXNjYXJnYXIgbG9zIGRhdG9zIGRlIG1hbmVyYSBsaWJyZSBbYXF1w61dKCU1Qmh0dHA6Ly9kYXRhc2V0cy5hbWVyaWNhc2Jhcm9tZXRlci5vcmcvZGF0YWJhc2UvbG9naW4ucGhwKS5dKDxodHRwOi8vZGF0YXNldHMuYW1lcmljYXNiYXJvbWV0ZXIub3JnL2RhdGFiYXNlL2xvZ2luLnBocD4pLikgRW4gZXN0ZSBlbmxhY2UsIHNlIHB1ZWRlbiByZWdpc3RyYXIgbyBlbnRyYXIgY29tbyAiRnJlZSBVc2VyIi4KRW4gZWwgYnVzY2Fkb3IsIHNlIHB1ZWRlIGluZ3Jlc2FyIGVsIHRleHRvICIyMDIzIi4KQWjDrSBzZSB0ZW5kcsOhIGFjY2VzbyBhIGxhcyBiYXNlcyBkZSBkYXRvcyBjb21wbGV0YXMgZGUgbGEgcm9uZGEgMjAyMSB5IGRlIHRvZGFzIGxhcyByb25kYXMgZGUgY2FkYSBwYcOtcyBlbiB2ZXJzacOzbiBwYXJhIFNUQVRBLgpTZSBkZXNjYXJnYSBsYSBiYXNlIGRlIGRhdG9zIGVuIGZvcm1hdG8gLmR0YS4KVW5hIHZleiBkZXNjYXJnYWRhIHkgZ3VhcmRhZGEgZW4gZWwgZGlyZWN0b3JpbyBkZSB0cmFiYWpvLCBzZSB0aWVuZSBxdWUgbGVlciBsYSBiYXNlIGRlIGRhdG9zIGNvbW8gdW4gb2JqZXRvIGRhdGFmcmFtZSBlbiBSLgpFbCBjdWVzdGlvbmFyaW8gZGUgZXN0YSBiYXNlIGRlIGRhdG9zIHB1ZWRlIHNlciB2aXN0byBlbiBlc3RlIFtlbmxhY2VdKGh0dHBzOi8vd3d3LnZhbmRlcmJpbHQuZWR1L2xhcG9wL2FiMjAxOC9BQjIwMTgtdjEyLjAtU3BhLTE5MDEzMV9XLnBkZikuCgpgYGB7ciBiYXNlfQpsaWJyYXJ5KHJpbykKcGVydTIzID0gaW1wb3J0KCJiYXNlcy9QRVJfMjAyM19MQVBPUF9BbWVyaWNhc0Jhcm9tZXRlcl92MS4wX3cuc2F2IikKYGBgCgpEZXNkZSBsYSBwYWcuCjIwIGRlbCByZXBvcnRlIHNlIGhhY2UgdW5hIGV2YWx1YWNpw7NuIGRlIGxhIGRlbW9jcmFjaWEgZW4gbGEgcHLDoWN0aWNhLgpFbiBwYXJ0aWN1bGFyLCBzZSB0cmFiYWphIGNvbiBsYSB2YXJpYWJsZSBQTjQuCkVuIGdlbmVyYWwsIMK/dXN0ZWQgZGlyw61hIHF1ZSBlc3TDoSBtdXkgc2F0aXNmZWNobyhhKSwgc2F0aXNmZWNobyhhKSwgaW5zYXRpc2ZlY2hvKGEpIG8gbXV5IGluc2F0aXNmZWNobyhhKSBjb24gbGEgZm9ybWEgZW4gcXVlIGxhIGRlbW9jcmFjaWEgZnVuY2lvbmEgZW4gUGVyw7ouCkVsIHJlcG9ydGUgc2UgaW5kaWNhIHF1ZSBsb3MgZGF0b3Mgc2UgcmVjb2RpZmljYW4gZW4gdW5hIHZhcmlhYmxlIGRpY290w7NtaWNhLgpFbiBlc3RlIGRvY3VtZW50byB2YW1vcyBhIHRyYWJhamFyIGNvbiBsYSB2YXJpYWJsZSBvcmlnaW5hbC4KRXN0YSB2YXJpYWJsZSBlcyB1bmEgdmFyaWFibGUgY2F0ZWfDs3JpY2EsIG9yZGluYWwgbyBkZSBmYWN0b3IuCkVuIGVsIEdyw6FmaWNvIDEuMTQgZGVsIHJlcG9ydGUgc2UgcHJlc2VudGEgdW5hIGV2YWx1YWNpw7NuIGRlIGxhIHNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEgcG9yIHZhcmlhYmxlcyBkZW1vZ3LDoWZpY2FzIHkgc29jaW9lY29uw7NtaWNhLCBjb21vIG5pdmVsIGVkdWNhdGl2bywgcXVpbnRpbGVzIGRlIHJpcXVlemEsIGx1Z2FyIGRlIHJlc2lkZW5jaWEsIGfDqW5lcm8gbyBncnVwb3MgZGUgZWRhZC4KRXMgZGVjaXIsIHNlIHVzYSBsYSBzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhIGNvbW8gdmFyaWFibGUgZGVwZW5kaWVudGUgeSBhIGNhZGEgdmFyaWFibGUgZGVtb2dyw6FmaWNhcyB5IHNvY2lvZWNvbsOzbWljYSBjb21vIHZhcmlhYmxlcyBpbmRlcGVuZGllbnRlcy4KClBvciBlamVtcGxvLCBzZSByZXBvcnRhIHF1ZSBlbnRyZSBsb3MgaG9tYnJlcywgZWwgNDIuMyUgZXN0w6FuIHNhdGlzZmVjaG9zIGNvbiBsYSBkZW1vY3JhY2lhLCBtaWVudHJhcyBxdWUgZW50cmUgbGFzIG11amVyZXMsIGVzdGUgcG9yY2VudGFqZSBkaXNtaW51eWUgYSAzNi45JS4KCkFudGVzIGRlIHByb2NlZGVyLCB0ZW5lbW9zIHF1ZSByZWNvZGlmaWNhciBsYXMgdmFyaWFibGVzLCBwb25lcmxhcyBlbiBmb3JtYSBkZSBmYWN0b3IgeSBldGlxdWV0YXIuCgpgYGB7ciByZWNvMH0KbGlicmFyeSh0aWR5dmVyc2UpCnBlcnUyMyA9IHBlcnUyMyAlPiUKICBtdXRhdGUoc2V4byA9IGZhY3RvcihxMXRjX3IsIGxhYmVscz1jKCJIb21icmUiLCAiTXVqZXIiKSkpCmBgYAoKYGBge3IgcmVjbzF9CnRhYmxlKHBlcnUyMyRzZXhvKQpgYGAKCkxvIG1pc21vIHBhcmEgbGEgdmFyaWFibGUgUE40IHF1ZSBzZSB0cmFuc2Zvcm1hIGVuIGxhIHZhcmlhYmxlICJzYXRpcyIuCgpgYGB7ciByZWNvMn0KcGVydTIzID0gcGVydTIzICU+JQogIG11dGF0ZShzYXRpcyA9IGZhY3RvcihwbjQsIGxhYmVscz0gYygiTXV5IHNhdGlzZmVjaG8iLCAiU2F0aXNmZWNobyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSW5zYXRpc2ZlY2hvIiwgIk11eSBpbnNhdGlzZmVjaG8iKSkpCmBgYAoKYGBge3J9CnRhYmxhMSA9IHRhYmxlKHBlcnUyMyRzYXRpcykKdGFibGExCmBgYAoKUGFyYSBjYWxjdWxhciBsYSB0YWJsYSBkZSBzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhLCBpbmRlcGVuZGllbnRlIGRlbCBnw6luZXJvIGRlIGxhIHBlcnNvbmEsIHNlIHB1ZWRlIGNhbGN1bGFyIGxvcyBwb3JjZW50YWplcyBkZSBlc3RhIHZhcmlhYmxlIGNvbiBlbCBjb21hbmRvIGBwcm9wLnRhYmxlYC4KU2UgbXVsdHVwbGljYSBwb3IgMTAwIHBhcmEgdGVuZXIgZWwgZm9ybWF0byBkZSBwb3JjZW50YWplLgoKYGBge3Igc2F0aXNwb3JjfQp0YWJsYTEgJT4lCiAgcHJvcC50YWJsZSgpKjEwMApgYGAKCkFob3JhLCBzZSBwdWVkZSBjYWxjdWxhciBsYSB0YWJsYSBkZSBjb250aW5nZW5jaWEgZW50cmUgc2F0aXNmYWNjacOzbiB5IGfDqW5lcm8uCkVsIGNvbWFuZG8gYHRhYmxlYCBub3MgYnJpbmRhIGxhcyBmcmVjdWVuY2lhcyBhYnNvbHV0YXMgZGVsIGNydWNlIGVudHJlIGFtYmFzIHZhcmlhYmxlcy4KTGEgdmFyaWFibGUgZGVwZW5kaWVudGUgInNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEiIHNlIHViaWNhIGVuIGxhcyBmaWxhcyB5IGxhIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgInNleG8iIGVuIGxhcyBjb2x1bW5hcy4KU2UgdmVyaWZpY2EgcXVlIGxhcyA1OCBvYnNlcnZhY2lvbmVzIHF1ZSBlc3TDoW4gbXV5IHNhdGlzZmVjaGFzIGNvbiBsYSBkZW1vY3JhY2lhLCBzZSBkaXZpZGVuIGVuIDI3IGhvbWJyZXMgeSAyOSBtdWplcmVzLgoKYGBge3IgdGFibGF9CnRhYmxhMiA9IHRhYmxlKHBlcnUyMyRzYXRpcywgcGVydTIzJHNleG8pCnRhYmxhMgpgYGAKClBhcmEgY2FsY3VsYXIgbGFzIGZyZWN1ZW5jaWFzIHJlbGF0aXZhcywgc2UgdGllbmUgcXVlIHVzYXIgZWwgY29tYW5kbyBgcHJvcC50YWJsZWAuClNlIGFncmVnYSBsYSBlc3BlY2lmaWNhY2nDs24gYCgyKWAgcGFyYSBpbmRpY2FyIHF1ZSBzZSBxdWllcmUgbGFzIHByb3BvcmNpb25lcyBzb2JyZSBsYXMgY29sdW1uYXMuClNlIHNpZ3VlIGNvbiBlbCBjb21hbmRvIGByb3VuZGAgcGFyYSBlbGltaW5hciBsb3MgZGVjaW1hbGVzIGlubmVjZXNhcmlvcyB5IGZpbmFsbWVudGUgc2UgdXNhIGBhZGRtYXJnaW5zYCBwYXJhIHZlcmlmaWNhciBsYSBzdW1hIGRlIHByb3BvcmNpb25lcyBzb2JyZSBsYXMgY29sdW1uYXMuCgpgYGB7ciB0YWJsYTF9CnRhYmxhMyA9IHRhYmxhMiAlPiUKICBwcm9wLnRhYmxlKDIpICU+JQogIHJvdW5kKDMpKjEwMCAKdGFibGEzCmBgYAoKRW4gZXN0YSB0YWJsYSBzZSBtdWVzdHJhIGxhcyBkaXN0cmlidWNpb25lcyBjb25kaWNpb25hbGVzIGRlIHNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEgcG9yIGNhZGEgZ3J1cG8gZGUgZ8OpbmVyby4KUG9yIGVqZW1wbG8sIGVsIDMuNSUgZGUgbG9zIGhvbWJyZXMgc2UgZW5jdWVudHJhcyBtdXkgc2F0aXNmZWNob3MgY29uIGxhIGRlbW9jcmFjaWEsIHVuIHBvcmNlbnRhamUgYWxnbyBzaW1pbGFyIGFsIDMuOSUgZGUgbGFzIG11amVyZXMuCkVsIDE3LjMlIGRlIGxvcyBob21icmVzIHNlIGVuY3VlbnRyYW4gc2F0aXNmZWNob3MgY29uIGxhIGRlbW9jcmFjaWEsIDQgcHVudG9zIHBvcmNlbnR1YWxlcyBwb3IgZW5jaW1hIHF1ZSBsYXMgbXVqZXJlcy4KCkRlIGVzdGEgbWFuZXJhLCBzZSBwdWVkZW4gY29tcGFyYXIgbG9zIHBvcmNlbnRhamVzIHBvciBjYWRhIGNhdGVnb3LDrWEgZGUgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUgZW50cmUgZ3J1cG9zIGRlIGxhIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgeSwgYWRlbcOhcywgc2UgcHVlZGUgY29tcGFyYXIgY29uIGxvcyBwb3JjZW50YWplcyBubyBjb25kaWNpb25hbGVzIGRlIGxhIHZhcmlhYmxlIHNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEuCgpgYGB7cn0KcGVydTIzID0gcGVydTIzICU+JQogIG11dGF0ZShwcm90ZXN0YSA9IGZhY3Rvcihwcm90MywgbGFiZWxzPSBjKCJTw60gaGEgcGFydGljaXBhZG8iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm8gaGEgcGFydGljaXBhZG8iKSkpCmBgYAoKYGBge3J9CnRhYmxhNCA9IHRhYmxlKHBlcnUyMyRwcm90ZXN0YSwgcGVydTIzJHNleG8pCnRhYmxhNCA9IHRhYmxhNCAlPiUKICBwcm9wLnRhYmxlKDIpICU+JQogIHJvdW5kKDMpKjEwMAp0YWJsYTQKYGBgCgpgYGB7cn0KcHJ1ZWJhMiA9IGNoaXNxLnRlc3QocGVydTIzJHByb3Rlc3RhLCBwZXJ1MjMkc2V4bykKcHJ1ZWJhMgpgYGAKCmBgYHtyfQpwZXJ1MjMgPSBwZXJ1MjMgJT4lCiAgbXV0YXRlKHVyYmFubyA9IGZhY3Rvcih1ciwgbGFiZWxzPSBjKCJVcmJhbm8iLCAiUnVyYWwiKSkpCmBgYAoKYGBge3J9CnRhYmxhNSA9IHRhYmxlKHBlcnUyMyRwcm90ZXN0YSwgcGVydTIzJHVyYmFubykKdGFibGE1ID0gdGFibGE1ICU+JQogIHByb3AudGFibGUoMikgJT4lCiAgcm91bmQoMykqMTAwCnRhYmxhNQpgYGAKCmBgYHtyfQpwcnVlYmEzID0gY2hpc3EudGVzdChwZXJ1MjMkcHJvdGVzdGEsIHBlcnUyMyR1cmJhbm8pCnBydWViYTMKYGBgCgojIEdyw6FmaWNvcyBiaXZhcmlhZG9zIGNhdGVnw7NyaWNvcwoKUGFyYSBjcmVhciB1biBncsOhZmljbyBzZSB0aWVuZSBxdWUgZ3VhcmRhciBsYSB0YWJsYSBjb21vIHVuIGRhdGFmcmFtZS4KU2UgdXNhIGVsIGNvbWFuZG8gYGFzLmRhdGEuZnJhbWVgIHBhcmEgc2FsdmFyIGxvcyBwb3JjZW50YWplcyB5IHBvZGVyIHVzYXJsb3MgY29uIGVsIGNvbWFuZG8gYGdncGxvdGAuCk7Ds3Rlc2UgcXVlIGVsIGRhdGFmcmFtZSBndWFyZGEgbG9zIHBvcmNlbnRhamVzIGVuIG90cm8gZm9ybWF0by4KCmBgYHtyIHRhYmxhM30KdGFibGE0ID0gYXMuZGF0YS5mcmFtZSh0YWJsYTMpCnRhYmxhNApgYGAKCkVuIGVzdGUgY2FzbywgY29tbyB0ZW5lbW9zIDQgY2F0ZWdvcsOtYXMgcGFyYSBzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhIHkgb3RyYXMgMiBwYXJhIHNleG8sIHVuIGdyw6FmaWNvIGRlIGJhcnJhcyBzZXBhcmFkYXMgY3JlYXLDrWEgOCBiYXJyYXMuCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpnZ3Bsb3QoZGF0YT10YWJsYTQsIGFlcyh4PVZhcjEsIHk9RnJlcSwgZmlsbD1WYXIyKSkrCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiLCBzdGF0PSJpZGVudGl0eSIpKwogIGdlb21fdGV4dChhZXMobGFiZWw9cGFzdGUoRnJlcSwgIiUiLCBzZXA9IiIpKSwgCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCAKICAgICAgICAgICAgdmp1c3Q9MCwgc2l6ZSA9IDMpKwogIGxhYnMoeD0iU2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSIsIHk9IlBvcmNlbnRhamUiLCBmaWxsPSJTZXhvIikKYGBgCgpFc3RhIGZvcm1hIGRlIGdyYWZpY2FyIHB1ZWRlIGNvbXBsaWNhciBsYSBjb21wYXJhY2nDs24gZW4gYWxndW5vcyBjYXNvcy4KUG9yIGVzbywgZW4gb3Ryb3MgY2Fzb3MsIHNlIHByZWZpZXJlIGVsIHRpcG8gZGUgYmFycmFzIGFwaWxhZGFzLgoKYGBge3IgYmFycmFwaWxhZGFzZWR9CmdncGxvdChkYXRhPXRhYmxhNCwgYWVzKHg9VmFyMiwgeT1GcmVxLCBmaWxsPVZhcjEpKSsKICBnZW9tX2Jhcihwb3NpdGlvbj0ic3RhY2siLCBzdGF0PSJpZGVudGl0eSIpKwogIGdlb21fdGV4dChhZXMobGFiZWw9cGFzdGUoRnJlcSwgIiUiLCBzZXA9IiIpKSwgCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2soKSwgdmp1c3Q9MSwgc2l6ZSA9IDMpKwogIGxhYnMoeD0iU2V4byIsIHk9IlBvcmNlbnRhamUiLCBmaWxsPSJTYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhIikKYGBgCgojIEluZGVwZW5kZW5jaWEgeSBkZXBlbmRlbmNpYQoKRGVjaW1vcyBxdWUgZG9zIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMgc29uICoqKmVzdGFkw61zdGljYW1lbnRlIGluZGVwZW5kaWVudGVzKioqIHNpIGxhcyBkaXN0cmlidWNpb25lcyBjb25kaWNpb25hbGVzIChwb2JsYWNpb25hbGVzKSBzb24gaWTDqW50aWNhcyBwb3IgY2FkYSBjYXRlZ29yw61hIGRlIGxhIHZhcmlhYmxlIGluZGVwZW5kaWVudGUuClBvciBlamVtcGxvLCBsYSBzaWd1aWVudGUgdGFibGEsIHNpIG1vc3RyYXJhIGxvcyBwb3JjZW50YWplcyBwb2JsYWNpb25hbGVzIGNvbmRpY2lvbmFsZXMsIGVzdG9zIHNvbiBpZMOpbnRpY29zIGVudHJlIGdydXBvcyBkZSBsYSB2YXJpYWJsZSBpbmRlcGVuZGllbnRlLgpFcyBkZWNpciwgaW5kZXBlbmRpZW50ZW1lbnRlIGRlIHNlciBob21icmUgbyBtdWplciwgbGFzIGRpc3RyaWJ1Y2nDs24gZGUgc2F0aXNmYWNjacOzbiBwb3IgbGEgZGVtb2NyYWNpYSBlcyBsYSBtaXNtYS4KU2VyIGhvbWJyZSBvIG11amVyIG5vIGNhbWJpYSBuYWRhIGxhcyBvcGluaW9uZXMgY29uIHJlc3BlY3RvIGEgbGEgc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYS4KCnwgU2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSB8IEhvbWJyZSB8IE11amVyIHwKfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfDotLS0tLS06fDotLS0tLTp8CnwgTXV5IHNhdGlzZmVjaG8gICAgICAgICAgICAgICAgIHwgIDMuNSUgIHwgMy45JSAgfAp8IFNhdGlzZmVjaG8gICAgICAgICAgICAgICAgICAgICB8IDE3LjMlICB8IDEzLjUlIHwKfCBJbnNhdGlzZmVjaG8gICAgICAgICAgICAgICAgICAgfCA1OS44JSAgfCA2NC45JSB8CnwgTXV5IGluc2F0aXNmZWNobyAgICAgICAgICAgICAgIHwgMTkuNCUgIHwgMTcuNyUgfAoKVkk6IGZ1bWEgLS0tLS0tLS0tXD4gVkQ6IGPDoW5jZXIgZGUgcHVsbcOzbgoKfCAgICAgICAgICAgICAgICAgICAgICB8IEZ1bWEgICAgfCAgICAgICAgICAgIHwKfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tfC0tLS0tLS0tLS0tLXwKfCBDw6FuY2VyIGFsIHB1bG3Ds24gICAgIHwgRnVtYWRvciB8IE5vIGZ1bWFkb3IgfAp8IFNpIGRlc2Fycm9sbGEgY8OhbmNlciB8IDEwICAgICAgfCAxMCAgICAgICAgIHwKfCBObyBkZXNhcnJvbGxhIGPDoW5jZXIgfCA5MCAgICAgIHwgOTAgICAgICAgICB8CnwgVG90YWwgICAgICAgICAgICAgICAgfCAxMDAlICAgIHwgMTAwJSAgICAgICB8CgpBIG1lZGlkYSBxdWUgZXN0b3MgcG9yY2VudGFqZXMgZGlmaWVyZW4gbcOhcyBlbnRyZSBzw60sIGhheSBtw6FzIHByb2JhYmlsaWRhZGVzIHF1ZSBhbWJhcyB2YXJpYWJsZXMgZXN0w6luIHJlbGFjaW9uYWRhcy4KRW4gcmVhbGlkYWQsIGEgbWVkaWRhIHF1ZSBlc3RvcyBwb3JjZW50YWplcyBkaWZpZXJlbiBtw6FzIGRlIGxhIGRpc3RyaWJ1Y2nDs24gbm8gY29uZGljaW9uYWwgZGUgbGEgdmFyaWFibGUgc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSB0YW1iacOpbiBoYWJyw61hIHVuYSBtYXlvciBwcm9iYWJpbGlkYWQgZGUgcXVlIGVzdMOpbiByZWxhY2lvbmFkYXMuCgojIFBydWViYSBkZSBpbmRlcGVuZGVuY2lhIGRlIGNoaS1jdWFkcmFkbwoKU2UgYmFzYSBlbiBsYSBjb21wYXJhY2nDs24gZGUgbGFzIGZyZWN1ZW5jaWFzIG9ic2VydmFkYXMgKGxhcyBvYnNlcnZhY2lvbmVzIHF1ZSBzZSByZWNvZ2UgZW4gY2FtcG8pIHZlcnN1cyBsYXMgZnJlY3VlbmNpYXMgZXNwZXJhZGFzIChsYXMgb2JzZXJ2YWNpb25lcyBxdWUgZGViZXLDrWEgaGFiZXIgZW4gY2FkYSBjZWxkYSBkZSBsYSB0YWJsYSBzaSBsYXMgdmFyaWFibGVzIGZ1ZXJhbiBpbmRlcGVuZGllbnRlcykuCkVuIGVzZSBzZW50aWRvICRIXzA6IGZfZSA9IGZfbyQgbyBsbyBxdWUgZXMgbG8gbWlzbW8gcXVlIGxhcyB2YXJpYWJsZXMgc29uIGluZGVwZW5kaWVudGVzLgoKU2kgbm8gaHViaWVyYSByZWxhY2nDs24gZW50cmUgbGFzIHZhcmlhYmxlcywgdGVuZHLDrWFtb3MgbG9zIG1pc21vIHBvcmNlbnRhamVzIHJlcHJvZHVjaWRvcyBlbiBsYXMgZGlzdHJpYnVjaW9uZXMgY29uZGljaW9uYWxlcy4KCistLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgQ29sMSB8IEhvbWJyZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgTXVqZXJlcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8Cis9PT09PT0rPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0rCnwgTVMgICB8IDIuMSUgZGUgaG9tYnJlcyAtXD4gI29ic2VydmFjaW9uZXMgc2kgbm8gaGF5IHJlbGFjacOzbiAgICAgICAgICB8IDIuMSUgZGUgbXVqZXJlcyAtXD4gI29ic2VydmFjaW9uZXMgc2kgbm8gaGF5IHJlbGFjacOzbiAgICAgICAgICAgIHwKfCAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKfCAgICAgIHwgY3XDoW50byBlcyBlbCAyLjElIGRlIDE2MTcgPSAzNCAtXD4gI29icyBzaSBOTyBodWJpZXJhIHJlbGFjacOzbiB8IGN1w6FudG8gZXMgZWwgMi4xJSBkZSAxNDIxID0gMjkuOCAtXD4gI29icyBzaSBOTyBodWJpZXJhIHJlbGFjacOzbiB8CnwgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgICAgICB8IFBlcm8sIDE5IGVzIGxvIHJlYWxtZW50ZSBvYnNlcnZhZG8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUGVybywgMTIgZXMgbG8gcmVhbG1lbnRlIG9ic2VydmFkbyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwgICAgICB8ICgxOS0zNClcXjIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgKDEyLTI5LjgpXF4yICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CistLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgUyAgICB8IDE4LjYlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgMTguNiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CistLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgSSAgICB8IDYxLjMlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgNjEuMyUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CistLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgTUkgICB8IDE4JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgMTglICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CistLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgICAgICB8IDEwMCUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgMTAwJSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CistLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCgojIFBydWViYSBlc3RhZMOtc3RpY2EKCkVsIGNoaS1jdWFkcmFkbyByZXN1bWUgcXXDqSB0YW4gY2VyY2EgZXN0w6FuIGxhcyBmcmVjdWVuY2lhcyBlc3BlcmFkYXMgZGUgbGFzIGZyZWN1ZW5jaWFzIG9ic2VydmFkYXMuCk1pZW50cmFzIG3DoXMgcGVxdWXDsWEgbGEgZGlzdGFuY2lhIGVuIGNhZGEgY2VsZGEsIG1lbm9zIHByb2JhYmlsaWRhZGVzIGRlIHJlY2hhemFyIGxhIGhpcMOzdGVzaXMgbnVsYS4KTWllbnRyYXMgbGEgZGlzdGFuY2lhIG3DoXMgZ3JhbmRlIGVuIGNhZGEgY2VsZGEgLG3DoXMgcHJvYmFiaWxpZGFkZXMgZGUgcmVjaGF6YXIgbGEgaGlww7N0ZXNpcyBudWxhLgoKJCQKXGNoaV4yID0gXHN1bVxmcmFjeyhmX28tZl9lKV4yfXtmX2V9CiQkCgotICAgU2kgZm89ZmUgZW4gY2FkYSBjZWxkYSwgZW50b25jZXMgz4dcXjIgPSAwCgotICAgQ29uIGVsIHZhbG9yIGRlICRcY2hpXjIkIHNlIGNhbGN1bGEgdW4gcC12YWx1ZSwgcXVlIHRpZW5lIHF1ZSBzZXIgbWVub3IgZGUgMC4wNSBwYXJhIHJlY2hhemFyIGxhIEhvLgoKLSAgIFNlIHJlcXVpZXJlIHF1ZSBoYXlhIGFsIG1lbm9zIDUgb2JzZXJ2YWNpb25lcyBlbiBjYWRhIGNlbGRhCgpFbiBSIHNlIHVzYSBlbCBjb21hbmRvIGBjaGlzcS50ZXN0YCBwYXJhIGNhbGN1bGFyIGVsIGVzdGFkw61zdGljbyB5IGVsIHAtdmFsdWUuCkVzdGEgcHJ1ZWJhIGVzIG1lam9yIGd1YXJkYXJsYSBlbiB1biBvYmpldG8gbnVldm8KCmBgYHtyIHBydWViYX0KcHJ1ZWJhID0gY2hpc3EudGVzdChwZXJ1MjMkc2F0aXMsIHBlcnUyMyRzZXhvKQpgYGAKCkxhIHByaW1lcmEgdGFibGEgcHJlc2VudGEgbGFzIGZyZWN1ZW5jaWFzIG9ic2VydmFkYXMsIHF1ZSBlcyBsbyBxdWUgcmVhbG1lbnRlIHNlIHJlY29nZSBlbiBjYW1wby4KTGEgc2VndW5kYSB0YWJsYSBwcmVzZW50YSBsYXMgZnJlY3VlbmNpYXMgZXNwZXJhZGFzIChzaSBubyBodWJpZXJhIHJlbGFjacOzbikuClNlIGNvbXBydWViYSBsb3MgY8OhbGN1bG9zIHF1ZSBzZSBoaXpvIGVuIGxhIHRhYmxhIGFudGVyaW9yIChsYXMgZGlmZXJlbmNpYXMgc29uIGRlYmlkbyBhIGxhIGFwcm94aW1hY2nDs24gZGVjaW1hbCkuCgpFbCBlc3RhZMOtc3RpY28gJFxjaGleMiQgcmVzdW1lIGxhcyBkaWZlcmVuY2lhcyBlbnRyZSBsYXMgZnJlY3VlbmNpYXMgb2JzZXJ2YWRhcyB5IGVzcGVyYWRhcyBlbiBjYWRhIGNlbGRhIHkgbGFzIHN1bWEgZGUgYWN1ZXJkbyBhIGxhIGbDs3JtdWxhLgoKYGBge3IgY2hpfQpwcnVlYmEKYGBgCgpMYSBwcnVlYmEgbm9zIGRhIGNvbW8gcmVzdWx0YWRvIHVuIHAtdmFsdWUgPSAwLjEyLCBwb3IgbG8gcXVlIE5PIHNlIHB1ZWRlIHJlY2hhemFyIGxhIGhpcMOzdGVzaXMgbnVsYSB5IHNlIGNvbmNsdXllIHF1ZSBubyBzYWJlbW9zIHNpIGV4aXN0ZSBhc29jaWFjacOzbi9yZWxhY2nDs24vZGVwZW5kZW5jaWEgZW50cmUgbGFzIHZhcmlhYmxlcy4KCiMgVGFibGEgY3J1emFkYSBkZSBzYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhIHNlZ8O6biBuaXZlbCBlZHVjYXRpdm8KCkVsIEdyw6FmaWNvIDEuMTQgZGVsIHJlcG9ydGUgbXVlc3RyYSBsb3MgZGF0b3MgZGUgc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSAoc2Vnw7puIGxhIHZhcmlhYmxlIHJlY29kaWZpY2FkYSBkdW1teSkgcG9yIG5pdmVsZXMgZWR1Y2F0aXZvLgpDb21vIHNlZ3VuZG8gZWplbXBsbywgYXF1w60gdmFtb3MgYSByZXBsaWNhciBlc2EgcmVsYWNpw7NuIHVzYW5kbyBsYSB2YXJpYWJsZSBvcmlnaW5hbCBkZSB0aXBvIGZhY3RvciBwYXJhIFBlcsO6IDIwMjMuCgpWYW1vcyBhIHJlY29kaWZpY2FyIGxhIHZhcmlhYmxlIGVkdWNhY2nDs24uCkxhIHZhcmlhYmxlIG9yaWdpbmFsICJlZHJlIiBzZXBhcmEgbG9zIG5pdmVsZXMgZWR1Y2F0aXZvcyBlbiA3IG5pdmVsZXMgKGRlbCAwIGFsIDYpLgpMb3MgYW5hbGZhYmV0b3Mgc29uIHVuIGdydXBvIG11eSBwZXF1ZcOxbyB5IHBvZHLDrWFuIGNhdXNhciBwcm9ibGVtYXMuCgpQcmltZXJvLCBjcmVhbW9zIHVuYSB2YXJpYWJsZSAiZWR1YyIsIGNvbW8gZWwgZmFjdG9yIGRlICJlZHJlIi4KTHVlZ28sIHNlIGV0aXF1ZXRhLgoKYGBge3J9CnBlcnUyMyA9IHBlcnUyMyB8PgogIG11dGF0ZShlZHVjID0gZmFjdG9yKGVkcmUsIGxhYmVscz1jKCJBbmFsZmFiZXRvIiwgIlByaW1hcmlhIGluY29tcGxldGEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUHJpbWFyaWEgY29tcGxldGEiLCJTZWN1bmRhcmlhIGluY29tcGxldGEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZWN1bmRhcmlhIGNvbXBsZXRhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpYSBvIHTDqWNuaWNhIGluY29tcGxldGEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpYSBvIHTDqWNuaWNhIGNvbXBsZXRhIikpKQp0YWJsZShwZXJ1MjMkZWR1YykKYGBgCgpWYW1vcyBhIGNyZWFyIG90cmEgdmFyaWFibGUgZGUgZWR1Y2FjacOzbiAiZWR1YzIiIHF1ZSBqdW50ZSBjYXRlZ29yw61hcyBwYXJhIHF1ZSBubyBoYXlhbiA3IG5pdmVsZXMgZWR1Y2F0aXZvcy4KCmBgYHtyfQpwZXJ1MjMgPSBwZXJ1MjMgfD4KICAgIG11dGF0ZShlZHVjMj0gY2FzZV93aGVuKAogICAgZWRyZSA9PSAwIH4gMSwKICAgIGVkcmUgPT0gMSB+IDEsCiAgICBlZHJlID09IDIgfiAxLAogICAgZWRyZSA9PSAzIH4gMiwKICAgIGVkcmUgPT0gNCB+IDIsCiAgICBlZHJlID09IDUgfiAzLAogICAgZWRyZSA9PSA2IH4gNCwKICAgICkpCmBgYAoKYGBge3J9CnBlcnUyMyA9IHBlcnUyMyB8PgogIG11dGF0ZShlZHVjMiA9IGZhY3RvcihlZHVjMiwgbGFiZWxzPWMoIkhhc3RhIHByaW1hcmlhICIsICJIYXN0YSBzZWN1bmRhcmlhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpYSBvIHTDqWNuaWNhIGluY29tcGxldGEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5pdmVyc2l0YXJpYSBvIHTDqWNuaWNhIGNvbXBsZXRhIikpKQp0YWJsZShwZXJ1MjMkZWR1YzIpCmBgYAoKQ29uIGxhIHZhcmlhYmxlIHJlY29kaWZpY2FkYSBzZSBwdWVkZSBjYWxjdWxhciBsYSB0YWJsYSBjcnV6YWRhIGRlIHNhdGlzZmFjY2nDs24gY29uIGxhIGRlbW9jcmFjaWEgc2Vnw7puIG5pdmVsZXMgZWR1Y2F0aXZvcy4KCmBgYHtyIHRhYmxhIGVkfQp0YWJsYTQgPSB0YWJsZShwZXJ1MjMkc2F0aXMsIHBlcnUyMyRlZHVjMikKdGFibGE0CmBgYAoKYGBge3J9CnRhYmxhNCA9IHRhYmxhNCB8PgogIHByb3AudGFibGUoMikgfD4KICByb3VuZCgzKSoxMDAKdGFibGE0CmBgYAoKIyBHcsOhZmljbyBiaXZhcmlhZG8gZGUgc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSBzZWfDum4gZWR1Y2FjacOzbgoKYGBge3J9CnRhYmxhNSA9IGFzLmRhdGEuZnJhbWUodGFibGE0KQp0YWJsYTUKYGBgCgpgYGB7cn0KZ2dwbG90KGRhdGE9dGFibGE1LCBhZXMoeD1WYXIyLCB5PUZyZXEsIGZpbGw9VmFyMSkpKwogIGdlb21fYmFyKHBvc2l0aW9uPSJzdGFjayIsIHN0YXQ9ImlkZW50aXR5IikrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1wYXN0ZShGcmVxLCAiJSIsIHNlcD0iIikpLCAKICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjaygpLCB2anVzdD0xLCBzaXplID0gMykrCiAgbGFicyh4PSJOaXZlbCBlZHVjYXRpdm8iLCB5PSJQb3JjZW50YWplIiwgCiAgICAgICBmaWxsPSJTYXRpc2ZhY2Npw7NuIGNvbiBsYSBkZW1vY3JhY2lhIikKYGBgCgojIFBydWViYSBlc3RhZMOtc3RpY2EgZW50cmUgc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSBzZWfDum4gZWR1Y2FjacOzbgoKUGFyYSBjb21wcm9iYXIgbGEgcmVsYWNpw7NuIGVudHJlIGVzdGFzIHZhcmlhYmxlcywgdGFtYmnDqW4gc2UgcHVlZGUgdXNhciBsYSBwcnVlYmEgZGUgaW5kZXBlbmRlbmNpYSBkZSAkXGNoaV4yJC4KRXN0YSBldmFsdWFjacOzbiBzZSBndWFyZGEgZW4gdW4gb2JqZXRvICJwcnVlYmEyIi4KCmBgYHtyfQpwcnVlYmEyID0gY2hpc3EudGVzdChwZXJ1MjMkc2F0aXMsIHBlcnUyMyRlZHVjMikKcHJ1ZWJhMgpgYGAKCmBgYHtyIGNoaSBlZH0KcHJ1ZWJhMiA9IGNoaXNxLnRlc3QocGVydTIzJHNhdGlzLCBwZXJ1MjMkZWR1YzIpCnBydWViYTIKYGBgCgpDb24gZWwgdmFsb3IgZGUgZXN0YWTDrXN0aWNvIHNlIG9idGllbmUgdW4gcC12YWx1ZSBtZW5vciBhIDAuMDUsIGNvbiBsbyBxdWUgc2UgcmVjaGF6YSBsYSBoaXDDs3Rlc2lzIG51bGEgeSBzZSBhZmlybWEgcXVlIGxhcyBmcmVjdWVuY2lhcyBvYnNlcnZhZGFzIHNvbiBkaWZlcmVudGVzIGRlIGxhcyBlc3BlcmFkYXMsIGNvbiBsbyBxdWUgY29uY2x1aW1vcyBxdWUgc8OtIGV4aXN0ZSB1bmEgcmVsYWNpw7NuIGRlIGRlcGVuZGVuY2lhIGVudHJlIGxhcyB2YXJpYWJsZXMuCkVzdG8gcXVpZXJlIGRlY2lyIHF1ZSBlbiBQZXLDuiBlbiAyMDIzIGV4aXN0ZW4gZGlmZXJlbmNpYXMgZW4gbGEgc2F0aXNmYWNjacOzbiBjb24gbGEgZGVtb2NyYWNpYSBlbnRyZSBkaWZlcmVudGVzIGdydXBvcyBwb3Igbml2ZWwgZWR1Y2F0aXZvLgo=