Introducción
Esta es la primera entrega de la serie de análisis “El vocabulario del poder” realizado por el área de Participación Ciudadana del Laboratorio de Redes y Tecnologías Sociales (Lab TecnoSocial). El objetivo de este primer análisis es develar las palabras clave de las programas de gobierno que conforman la visión de mundo y propuesta de los partidos.
Realizaremos un análisis de contenido de los textos de los programas de gobierno. Si bien nada supera aún a una lectura atenta, contextualizada y reflexiva de los programas de gobierno, el análisis de contenido nos permitirá crear un resumen del vocabulario básico de las propuestas de los aspirantes a gobernantes, y una rápida comparación entre ellos.
Dado que siempre se puede usar la retórica en los debates políticos entre candidatos, se hace difícil saber qué es lo que realmente proponen los partidos. Nuestro método aquí es más estandarizado y cuantitativo, pero por lo mismo más objetivo, lo que nos permite ver cuestiones a veces ocultas entre tanto espectáculo. ¿Qué imagen de Bolivia tienen los candidatos? ¿Sus propuestas son realmente diferentes entre sí, más allá de sus estilos mediáticos personales?
Cabe aclarar que aquí nos limitaremos a detallar nuestros procedimientos, ejemplificar la lectura de los mismos y hacer notar algunas tendencias generales. La lectura detallada de los gráficos y los datos, sin embargo, corresponde a los ciudadanos. Más que un trabajo de interpretación, este es un trabajo de extracción (mining). También ponemos a disposición la descarga de los conjuntos de datos usados.
Preparación de los datos
Partimos de los programas de gobierno públicados por el Organo Electoral Plurinacional. A partir de allí preparamos los datos para su posterior análisis:
# Cargamos los 9 programas de gobierno en PDF, los transformamos a texto plano y luego los pasamos a una tabla de datos
library(tidyverse)
library(pdftools)
programas_pdf <- list.files(path = "./PDFs2020", pattern = "pdf$", full.names = TRUE)
programas_texto <- map(programas_pdf, pdf_text)
partidos <- c("ADN", "CC", "CREEMOS", "FPV", "JUNTOS", "Libre21", "MAS-IPSP", "PAN-BOL")
programas_df <- tibble(partido = partidos, programa = programas_texto)
programas_df
Descarga esta base de datos en formato CSV
# Tokenizamos por palabras, removemos las palabras vacías generales y específicas al corpus, y corregimos algunas cuestiones con tildes
library(tidytext)
library(stopwords)
library(stringr)
vac <- c("bolivia", "país", "creemos.org", "a.d.n", "f.p.v","boliviano", "bolivianos", "boliviana", "a", "b", "c", "d")
vacias_especificas <- tibble(palabra = vac)
programas_palabras <- programas_df %>%
unnest %>%
unnest_tokens(palabra, programa, strip_numeric = TRUE) %>%
anti_join(tibble(palabra = stopwords("spanish"))) %>%
anti_join(vacias_especificas) %>%
mutate(palabra = str_replace_all(palabra, "democratica", "democrática"))
Análisis de datos
1. Extensión de los programas de gobierno
Una primera comparación sencilla pero ilustrativa que haremos será sobre la extensión de los programas de gobierno. Se espera que un programa de gobierno para todo un país sea lo suficientemente complejo y por tanto tenga una buena extensión.
programas_df$pag <- c(9, 56, 60, 92, 52, 48, 58, 42)
programas_df %>%
ggplot(aes(reorder(partido, pag), pag)) +
geom_col() +
coord_flip() +
geom_label(aes(label = pag)) +
labs(title = "Número de páginas de los programas de gobierno", x = NULL, y = "Número") +
theme_minimal()
median(programas_df$pag)
[1] 54
Vemos que la media de los programas de gobierno es 54 páginas. Llama la atención la extensión tan mínima de ADN y la mayor ampulosidad del programa del FPV, del cual se ha detectado plagio.
2. Frecuencia de palabras
Naturalmente, la cantidad de páginas no nos dicen mucho sobre el contenido en sí. Ahora vamos a extraer la frecuencia de las palabras más utilizadas.
# Hacemos un conteo de la frecuencia de palabras más usadas por cada partido en sus programas
freq <- programas_palabras %>%
count(partido, palabra, sort = TRUE) %>%
arrange(partido)
freq
Descarga esta base de datos de 30.910 x 3 en formato CSV
# Recortamos las 10 palabras más usadas
top <- freq %>%
group_by(partido) %>%
top_n(10) %>%
arrange(partido)
top
Descarga esta base de datos de 80 x 3 en formato CSV
La anterior tabla ya nos da la información que queremos, pero necesitamos una visualización que nos ayude a comparar las palabras más frecuentes de los distintos programas. Una opción popular aquí es el uso de nubes de palabras, que si bien tienen una forma atractiva, en realidad no resumen bien la información, pues en ellas (a) no se puede distinguir la magnitud de la frecuencia de palabras de una palabra frente a las otras y (b) es difícil comparar varias nubes de palabras de diferentes casos.
En su lugar usaremos un diagrama de barras que es más preciso y comparable.
# Gráficamos
ggplot(top, aes(x = reorder_within(palabra, n, partido), y = n, fill = partido)) +
geom_col(show.legend = F) +
facet_wrap(~partido, scales = "free_y", ncol = 2) +
coord_flip() +
scale_x_reordered() +
labs(y = NULL,
x = NULL,
title = "Las 10 palabras más frecuentes de los \n programas de gobierno") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5))
Aquí una palabra común utilizada de forma muy frecuente en todos los programas de gobierno es la de desarrollo
, excepto por ADN quienes utilizan en su lugar la palabra progreso
.
3. Comparación de frecuencias
Ahora bien, ¿cuán parecidos son los partidos políticos entre sí? Ya vimos que una de las palabras comunes es desarrollo, ¿qué hay de las demás palabras? Podemos comparar las frecuencias de uso de las palabras entre los partidos.
# Antes de comparar primero cálculamos las proporciones de palabras dentro de cada programa
prop1 <- freq %>%
group_by(partido) %>%
mutate(proporcion = n / sum(n)) %>%
select(-n) %>%
spread(partido, proporcion)
prop2 <- prop1 %>%
gather(partido, proporcion, c(2, 3, 4, 5, 6, 7, 9))
# Ahora realizamos un gráfico de comparación de frecuencias
library(scales)
ggplot(prop2, aes(x = proporcion, y = `MAS-IPSP`, color = abs(`MAS-IPSP` - proporcion)), show.legend = FALSE) +
geom_abline(color = "gray40", lty = 2) +
geom_jitter(alpha = 0.1, size = 2.5, width = 0.3, height = 0.3) +
geom_text(aes(label = palabra), check_overlap = TRUE, vjust = 1.5) +
scale_x_log10(labels = percent_format()) +
scale_y_log10(labels = percent_format()) +
scale_color_gradient(limits = c(0, 0.001), low = "darkslategray4", high = "gray75") +
facet_wrap(~partido, ncol = 2) +
theme_linedraw() +
theme(legend.position="none", plot.title = element_text(hjust = 0.5)) +
labs(title = "COMPARACIÓN DE FRECUENCIAS DE PALABRAS ENTRE PROGRAMAS DE GOBIERNO", y = "MAS-IPSP", x = NULL)
NA
La forma de leer este gráfico es la siguiente:
- Las palabras que se encuentran en el sector diagonal superior en todos los paneles pertenecen al programa del MAS-IPSP, mientras las que se encuentran en la parte diagonal inferior pertenecen al programa de cada partido que está en el título del panel.
- Las palabras que están más cerca de la linea diagonal tienen una similar frecuencia en el par de textos comparados; aquí el color de la palabra tiene significado: entre más cercano a la linea su frecuencia es similar entre los dos programas comparados, y la palabra se pone verde; mientras si es más particular a cada programa entonces la palabra está alejada de la linea y se pone más gris.
- Por último, la linea diagonal asciende desde las palabras menos frecuentes hacía las más frecuentes.
Entonces las palabras más comunes en cada par de programas son las palabras verdes que se encuentran en el extremo superior de la diagonal, mientras las menos comunes entre sí son las palabras grises en el extremo inferior de la diagonal, existiendo muchos valores intermedios.
Para mayor claridad, demos un ejemplo. Leamos el tercer panel que es la comparación entre los programas del MAS-IPSP y CREEMOS. Las palabras desarrollo
, acceso
, bien
y gas
son palabras comunes en frecuencia en ambos programas. Mientras que económicas
es más una palabra particular al programas del MAS y legales
a de CREEMOS. De esta forma se pueden leer las demás comparaciones.
4. Correlaciones de palabras entre programas
El anterior gráfico nos mostraba el detalle de las palabras comparadas. Ahora veamos un resumen con una medida de correlación.
# Creamos una matriz de correlación y luego la visualizamos
library(widyr)
freq_cor <- freq %>%
pairwise_cor(partido, palabra, n, sort = TRUE)
freq_cor2 <- spread(freq_cor, item2, correlation) %>%
rename(rowname = item1) %>%
column_to_rownames()
rplot(freq_cor2, shape = 20, print_cor = T, colors = c("red", "green"), legend = F) +
labs(title = "Correlaciones de palabras entre programas de gobierno") +
theme(plot.title = element_text(hjust = 0.5))
La forma de leer este gráfico es la siguiente. El coeficiente indica cuán parecidas son las palabras usadas entre dos programas de 0 a 1, siendo 1 la máxima correlación positiva. Se puede empezar de la fila superior e ir de izquierda a derecha comparando la fila seleccionado con los otros partidos y encontrando la correlación más alta. Por ejemplo, PAN-BOL tiene la correlación más alta con FPV, un .7.
5. Términos particulares
Ahora veremos los términos más particulares de cada documento en comparación con los otros documentos. Usaremos el estadístico de tf-idf, que mide precisamente eso: La frecuencia de un término ajustado según la particularidad con la que se usa.
# Calculamos el total de las palabras en cada documento para luego ajustar la frecuencia
total_palabras <- freq%>%
group_by(partido) %>%
summarize(total = sum(n))
freq <- left_join(freq, total_palabras)
# Cálculamos el tf-idf de cada termino
freq <- freq %>%
bind_tf_idf(palabra, partido, n)
freq_part <- freq %>%
arrange(partido, desc(tf_idf)) %>%
mutate(palabra = factor(palabra, levels = rev(unique(palabra))))
freq_part
# Recortamos las 10 palabras particulares más usadas
top_part <- freq_part %>%
group_by(partido) %>%
slice(1:10) %>%
arrange(partido)
top_part
# Visualizamos las 10 palabras más particulares
top_part %>%
ggplot(aes(x = reorder_within(palabra, tf_idf, partido), y = tf_idf, fill = partido)) +
geom_col(show.legend = FALSE) +
facet_wrap(~partido, ncol = 2, scales = "free") +
coord_flip() +
scale_x_reordered() +
labs(y = "tf-idf",
x = NULL,
title = "Las 10 palabras más particulares de los \n programas de gobierno") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5))
Este gráfico nos da la perspectiva más particular de los conceptos usados en los programas de gobierno. Ahora sí aparecen algunos terminos diferenciadores.
Conclusiones
En temas político-electorales suele existir un debate acalarado para intentar diferenciar un partido de otro. Se juegan muchas perspectivas, intereses y emociones, cuestiones más subjetivas. Aquí intentamos brindar una información más objetiva sobre los programas de gobierno, que en teoría deberían ser la base de los debates políticos y la decisión informada por parte de los ciudadanos.
En general, encontramos que hay mucho parecido entre los conceptos de todos los partidos en carrera y algunas diferencias. No obstante, las conclusiones finales las tiene el ciudadano, a partir de una observación atenta de los gráficos que le presentamos.
Por supuesto, que no sólo se debe juzgar a un partido y sus candidatos por los programas de gobierno. Es por eso que en las siguientes entregas del “Vocabulario del poder”, analizaremos los discursos en Twitter de los candidatos y luego los discursos en medios de comunicación.
LS0tCnRpdGxlOiAiRWwgdm9jYWJ1bGFyaW8gZGVsIHBvZGVyIEkiCnN1YnRpdGxlOiAiQW7DoWxpc2lzIGRlIGNvbnRlbmlkbyBkZSBsb3MgcHJvZ3JhbWFzIGRlIGdvYmllcm5vIGRlIDIwMjAiCmF1dGhvcjogIsOBcmVhIGRlIFBhcnRpY2lwYWNpw7NuIENpdWRhZGFuYSAtIExhYiBUZWNub1NvY2lhbCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0aGVtZTogZmxhdGx5CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCgojIyBJbnRyb2R1Y2Npw7NuCgpFc3RhIGVzIGxhIHByaW1lcmEgZW50cmVnYSBkZSBsYSBzZXJpZSBkZSBhbsOhbGlzaXMgIkVsIHZvY2FidWxhcmlvIGRlbCBwb2RlciIgcmVhbGl6YWRvIHBvciBlbCDDoXJlYSBkZSBQYXJ0aWNpcGFjacOzbiBDaXVkYWRhbmEgZGVsIExhYm9yYXRvcmlvIGRlIFJlZGVzIHkgVGVjbm9sb2fDrWFzIFNvY2lhbGVzIChbTGFiIFRlY25vU29jaWFsXShodHRwOi8vbGFidGVjbm9zb2NpYWwub3JnLykpLiBFbCBvYmpldGl2byBkZSBlc3RlIHByaW1lciBhbsOhbGlzaXMgZXMgZGV2ZWxhciBsYXMgcGFsYWJyYXMgY2xhdmUgZGUgbGFzIHByb2dyYW1hcyBkZSBnb2JpZXJubyBxdWUgY29uZm9ybWFuIGxhIHZpc2nDs24gZGUgbXVuZG8geSBwcm9wdWVzdGEgZGUgbG9zIHBhcnRpZG9zLiAKClJlYWxpemFyZW1vcyB1biBhbsOhbGlzaXMgZGUgY29udGVuaWRvIGRlIGxvcyB0ZXh0b3MgZGUgbG9zIHByb2dyYW1hcyBkZSBnb2JpZXJuby4gU2kgYmllbiBuYWRhIHN1cGVyYSBhw7puIGEgdW5hIGxlY3R1cmEgYXRlbnRhLCBjb250ZXh0dWFsaXphZGEgeSByZWZsZXhpdmEgZGUgbG9zIHByb2dyYW1hcyBkZSBnb2JpZXJubywgZWwgYW7DoWxpc2lzIGRlIGNvbnRlbmlkbyBub3MgcGVybWl0aXLDoSBjcmVhciB1biByZXN1bWVuIGRlbCB2b2NhYnVsYXJpbyBiw6FzaWNvIGRlIGxhcyBwcm9wdWVzdGFzIGRlIGxvcyBhc3BpcmFudGVzIGEgZ29iZXJuYW50ZXMsIHkgdW5hIHLDoXBpZGEgY29tcGFyYWNpw7NuIGVudHJlIGVsbG9zLiAKCkRhZG8gcXVlIHNpZW1wcmUgc2UgcHVlZGUgdXNhciBsYSByZXTDs3JpY2EgZW4gbG9zIGRlYmF0ZXMgcG9sw610aWNvcyBlbnRyZSBjYW5kaWRhdG9zLCBzZSBoYWNlIGRpZsOtY2lsIHNhYmVyIHF1w6kgZXMgbG8gcXVlIHJlYWxtZW50ZSBwcm9wb25lbiBsb3MgcGFydGlkb3MuIE51ZXN0cm8gbcOpdG9kbyBhcXXDrSBlcyBtw6FzIGVzdGFuZGFyaXphZG8geSBjdWFudGl0YXRpdm8sIHBlcm8gcG9yIGxvIG1pc21vIG3DoXMgb2JqZXRpdm8sIGxvIHF1ZSBub3MgcGVybWl0ZSB2ZXIgY3Vlc3Rpb25lcyBhIHZlY2VzIG9jdWx0YXMgZW50cmUgdGFudG8gZXNwZWN0w6FjdWxvLiDCv1F1w6kgaW1hZ2VuIGRlIEJvbGl2aWEgdGllbmVuIGxvcyBjYW5kaWRhdG9zPyDCv1N1cyBwcm9wdWVzdGFzIHNvbiByZWFsbWVudGUgZGlmZXJlbnRlcyBlbnRyZSBzw60sIG3DoXMgYWxsw6EgZGUgc3VzIGVzdGlsb3MgbWVkacOhdGljb3MgcGVyc29uYWxlcz8KCkNhYmUgYWNsYXJhciBxdWUgYXF1w60gbm9zIGxpbWl0YXJlbW9zIGEgZGV0YWxsYXIgbnVlc3Ryb3MgcHJvY2VkaW1pZW50b3MsIGVqZW1wbGlmaWNhciBsYSBsZWN0dXJhIGRlIGxvcyBtaXNtb3MgeSBoYWNlciBub3RhciBhbGd1bmFzIHRlbmRlbmNpYXMgZ2VuZXJhbGVzLiBMYSBsZWN0dXJhIGRldGFsbGFkYSBkZSBsb3MgZ3LDoWZpY29zIHkgbG9zIGRhdG9zLCBzaW4gZW1iYXJnbywgY29ycmVzcG9uZGUgYSBsb3MgY2l1ZGFkYW5vcy4gTcOhcyBxdWUgdW4gdHJhYmFqbyBkZSBpbnRlcnByZXRhY2nDs24sIGVzdGUgZXMgdW4gdHJhYmFqbyBkZSBleHRyYWNjacOzbiAoKm1pbmluZyopLiBUYW1iacOpbiBwb25lbW9zIGEgZGlzcG9zaWNpw7NuIGxhIGRlc2NhcmdhIGRlIGxvcyBjb25qdW50b3MgZGUgZGF0b3MgdXNhZG9zLiAKCiMjIFByZXBhcmFjacOzbiBkZSBsb3MgZGF0b3MKClBhcnRpbW9zIGRlIGxvcyBwcm9ncmFtYXMgZGUgZ29iaWVybm8gcMO6YmxpY2Fkb3MgcG9yIGVsIFtPcmdhbm8gRWxlY3RvcmFsIFBsdXJpbmFjaW9uYWxdKGh0dHBzOi8vd3d3Lm9lcC5vcmcuYm8vZWxlY2Npb25lcy1nZW5lcmFsZXMtMjAyMC9wcm9ncmFtYXMtZGUtZ29iaWVybm8vKS4gQSBwYXJ0aXIgZGUgYWxsw60gcHJlcGFyYW1vcyBsb3MgZGF0b3MgcGFyYSBzdSBwb3N0ZXJpb3IgYW7DoWxpc2lzOgoKYGBge3IgbWVzc2FnZSA9IEZBTFNFfQojIENhcmdhbW9zIGxvcyA5IHByb2dyYW1hcyBkZSBnb2JpZXJubyBlbiBQREYsIGxvcyB0cmFuc2Zvcm1hbW9zIGEgdGV4dG8gcGxhbm8geSBsdWVnbyBsb3MgcGFzYW1vcyBhIHVuYSB0YWJsYSBkZSBkYXRvcwoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkocGRmdG9vbHMpCgpwcm9ncmFtYXNfcGRmIDwtIGxpc3QuZmlsZXMocGF0aCA9ICIuL1BERnMyMDIwIiwgcGF0dGVybiA9ICJwZGYkIiwgZnVsbC5uYW1lcyA9IFRSVUUpCnByb2dyYW1hc190ZXh0byA8LSBtYXAocHJvZ3JhbWFzX3BkZiwgcGRmX3RleHQpIApwYXJ0aWRvcyA8LSBjKCJBRE4iLCAiQ0MiLCAiQ1JFRU1PUyIsICJGUFYiLCAiSlVOVE9TIiwgIkxpYnJlMjEiLCAiTUFTLUlQU1AiLCAiUEFOLUJPTCIpCnByb2dyYW1hc19kZiA8LSB0aWJibGUocGFydGlkbyA9IHBhcnRpZG9zLCBwcm9ncmFtYSA9IHByb2dyYW1hc190ZXh0bykKcHJvZ3JhbWFzX2RmCmBgYAoKW0Rlc2NhcmdhIGVzdGEgYmFzZSBkZSBkYXRvcyBlbiBmb3JtYXRvIENTVl0oLi9DU1YvcHJvZ3JhbWFzX2RmLmNzdikKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgVG9rZW5pemFtb3MgcG9yIHBhbGFicmFzLCByZW1vdmVtb3MgbGFzIHBhbGFicmFzIHZhY8OtYXMgZ2VuZXJhbGVzIHkgZXNwZWPDrWZpY2FzIGFsIGNvcnB1cywgeSBjb3JyZWdpbW9zIGFsZ3VuYXMgY3Vlc3Rpb25lcyBjb24gdGlsZGVzCgpsaWJyYXJ5KHRpZHl0ZXh0KQpsaWJyYXJ5KHN0b3B3b3JkcykKbGlicmFyeShzdHJpbmdyKQoKdmFjIDwtIGMoImJvbGl2aWEiLCAicGHDrXMiLCAiY3JlZW1vcy5vcmciLCAiYS5kLm4iLCAiZi5wLnYiLCJib2xpdmlhbm8iLCAiYm9saXZpYW5vcyIsICJib2xpdmlhbmEiLCAiYSIsICJiIiwgImMiLCAiZCIpCnZhY2lhc19lc3BlY2lmaWNhcyA8LSB0aWJibGUocGFsYWJyYSA9IHZhYykKCnByb2dyYW1hc19wYWxhYnJhcyA8LSBwcm9ncmFtYXNfZGYgJT4lIAogIHVubmVzdCAlPiUgCiAgdW5uZXN0X3Rva2VucyhwYWxhYnJhLCBwcm9ncmFtYSwgc3RyaXBfbnVtZXJpYyA9IFRSVUUpICU+JQogIGFudGlfam9pbih0aWJibGUocGFsYWJyYSA9IHN0b3B3b3Jkcygic3BhbmlzaCIpKSkgJT4lCiAgYW50aV9qb2luKHZhY2lhc19lc3BlY2lmaWNhcykgJT4lCiAgbXV0YXRlKHBhbGFicmEgPSBzdHJfcmVwbGFjZV9hbGwocGFsYWJyYSwgImRlbW9jcmF0aWNhIiwgImRlbW9jcsOhdGljYSIpKQogIApgYGAKCgojIyBBbsOhbGlzaXMgZGUgZGF0b3MKCiMjIyAxLiBFeHRlbnNpw7NuIGRlIGxvcyBwcm9ncmFtYXMgZGUgZ29iaWVybm8KClVuYSBwcmltZXJhIGNvbXBhcmFjacOzbiBzZW5jaWxsYSBwZXJvIGlsdXN0cmF0aXZhIHF1ZSBoYXJlbW9zIHNlcsOhIHNvYnJlIGxhIGV4dGVuc2nDs24gZGUgbG9zIHByb2dyYW1hcyBkZSBnb2JpZXJuby4gU2UgZXNwZXJhIHF1ZSB1biBwcm9ncmFtYSBkZSBnb2JpZXJubyBwYXJhIHRvZG8gdW4gcGHDrXMgc2VhIGxvIHN1ZmljaWVudGVtZW50ZSBjb21wbGVqbyB5IHBvciB0YW50byB0ZW5nYSB1bmEgYnVlbmEgZXh0ZW5zacOzbi4KCmBgYHtyfQpwcm9ncmFtYXNfZGYkcGFnIDwtIGMoOSwgNTYsIDYwLCA5MiwgNTIsIDQ4LCA1OCwgNDIpIAoKcHJvZ3JhbWFzX2RmICU+JQogIGdncGxvdChhZXMocmVvcmRlcihwYXJ0aWRvLCBwYWcpLCBwYWcpKSArCiAgZ2VvbV9jb2woKSArCiAgY29vcmRfZmxpcCgpICsKICBnZW9tX2xhYmVsKGFlcyhsYWJlbCA9IHBhZykpICsKICBsYWJzKHRpdGxlID0gIk7Dum1lcm8gZGUgcMOhZ2luYXMgZGUgbG9zIHByb2dyYW1hcyBkZSBnb2JpZXJubyIsIHggPSBOVUxMLCB5ID0gIk7Dum1lcm8iKSArCiAgdGhlbWVfbWluaW1hbCgpCm1lZGlhbihwcm9ncmFtYXNfZGYkcGFnKQoKYGBgCgpWZW1vcyBxdWUgbGEgbWVkaWEgZGUgbG9zIHByb2dyYW1hcyBkZSBnb2JpZXJubyBlcyA1NCBww6FnaW5hcy4gTGxhbWEgbGEgYXRlbmNpw7NuIGxhIGV4dGVuc2nDs24gdGFuIG3DrW5pbWEgZGUgQUROIHkgbGEgbWF5b3IgYW1wdWxvc2lkYWQgZGVsIHByb2dyYW1hIGRlbCBGUFYsIGRlbCBjdWFsIHNlIGhhIGRldGVjdGFkbyBbcGxhZ2lvXShodHRwczovL3d3dy5sb3N0aWVtcG9zLmNvbS9hY3R1YWxpZGFkL3BhaXMvMjAyMDAyMTAvZnB2LXByZXNlbnRhLW51ZXZhbWVudGUtcHJvZ3JhbWEtZ29iaWVybm8tcGxhZ2lhZG8tcGFydGlkby1wZXJ1YW5vKS4KCiMjIyAyLiBGcmVjdWVuY2lhIGRlIHBhbGFicmFzCgpOYXR1cmFsbWVudGUsIGxhIGNhbnRpZGFkIGRlIHDDoWdpbmFzIG5vIG5vcyBkaWNlbiBtdWNobyBzb2JyZSBlbCBjb250ZW5pZG8gZW4gc8OtLiBBaG9yYSB2YW1vcyBhIGV4dHJhZXIgbGEgZnJlY3VlbmNpYSBkZSBsYXMgcGFsYWJyYXMgbcOhcyB1dGlsaXphZGFzLgoKYGBge3J9CiMgSGFjZW1vcyB1biBjb250ZW8gZGUgbGEgZnJlY3VlbmNpYSBkZSBwYWxhYnJhcyBtw6FzIHVzYWRhcyBwb3IgY2FkYSBwYXJ0aWRvIGVuIHN1cyBwcm9ncmFtYXMKZnJlcSA8LSBwcm9ncmFtYXNfcGFsYWJyYXMgJT4lCiAgY291bnQocGFydGlkbywgcGFsYWJyYSwgc29ydCA9IFRSVUUpICU+JQogIGFycmFuZ2UocGFydGlkbykKZnJlcQpgYGAKCltEZXNjYXJnYSBlc3RhIGJhc2UgZGUgZGF0b3MgZGUgMzAuOTEwIHggMyBlbiBmb3JtYXRvIENTVl0oLi9DU1YvZnJlcS5jc3YpCgpgYGB7ciBtZXNzYWdlPUZBTFNFfQojIFJlY29ydGFtb3MgbGFzIDEwIHBhbGFicmFzIG3DoXMgdXNhZGFzCnRvcCA8LSBmcmVxICU+JQogIGdyb3VwX2J5KHBhcnRpZG8pICU+JQogIHRvcF9uKDEwKSAlPiUKICBhcnJhbmdlKHBhcnRpZG8pCnRvcApgYGAKCltEZXNjYXJnYSBlc3RhIGJhc2UgZGUgZGF0b3MgZGUgODAgeCAzIGVuIGZvcm1hdG8gQ1NWXSguL0NTVi90b3AuY3N2KQoKTGEgYW50ZXJpb3IgdGFibGEgeWEgbm9zIGRhIGxhIGluZm9ybWFjacOzbiBxdWUgcXVlcmVtb3MsIHBlcm8gbmVjZXNpdGFtb3MgdW5hIHZpc3VhbGl6YWNpw7NuIHF1ZSBub3MgYXl1ZGUgYSBjb21wYXJhciBsYXMgcGFsYWJyYXMgbcOhcyBmcmVjdWVudGVzIGRlIGxvcyBkaXN0aW50b3MgcHJvZ3JhbWFzLiBVbmEgb3BjacOzbiBwb3B1bGFyIGFxdcOtIGVzIGVsIHVzbyBkZSAqbnViZXMgZGUgcGFsYWJyYXMqLCBxdWUgc2kgYmllbiB0aWVuZW4gdW5hIGZvcm1hIGF0cmFjdGl2YSwgZW4gcmVhbGlkYWQgbm8gcmVzdW1lbiBiaWVuIGxhIGluZm9ybWFjacOzbiwgcHVlcyBlbiBlbGxhcyAoYSkgbm8gc2UgcHVlZGUgZGlzdGluZ3VpciBsYSBtYWduaXR1ZCBkZSBsYSBmcmVjdWVuY2lhIGRlIHBhbGFicmFzIGRlIHVuYSBwYWxhYnJhIGZyZW50ZSBhIGxhcyBvdHJhcyB5IChiKSBlcyBkaWbDrWNpbCBjb21wYXJhciB2YXJpYXMgbnViZXMgZGUgcGFsYWJyYXMgZGUgZGlmZXJlbnRlcyBjYXNvcy4gCgpFbiBzdSBsdWdhciB1c2FyZW1vcyB1biBkaWFncmFtYSBkZSBiYXJyYXMgcXVlIGVzIG3DoXMgcHJlY2lzbyB5IGNvbXBhcmFibGUuCgpgYGB7ciwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBHcsOhZmljYW1vcwpnZ3Bsb3QodG9wLCBhZXMoeCA9IHJlb3JkZXJfd2l0aGluKHBhbGFicmEsIG4sIHBhcnRpZG8pLCB5ID0gbiwgZmlsbCA9IHBhcnRpZG8pKSArCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGKSArCiAgZmFjZXRfd3JhcCh+cGFydGlkbywgc2NhbGVzID0gImZyZWVfeSIsIG5jb2wgPSAyKSArCiAgY29vcmRfZmxpcCgpICsKICBzY2FsZV94X3Jlb3JkZXJlZCgpICsKICBsYWJzKHkgPSBOVUxMLAogICAgICAgICB4ID0gTlVMTCwKICAgICAgICAgdGl0bGUgPSAiTGFzIDEwIHBhbGFicmFzIG3DoXMgZnJlY3VlbnRlcyBkZSBsb3MgXG4gcHJvZ3JhbWFzIGRlIGdvYmllcm5vIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKQXF1w60gdW5hIHBhbGFicmEgY29tw7puIHV0aWxpemFkYSBkZSBmb3JtYSBtdXkgZnJlY3VlbnRlIGVuIHRvZG9zIGxvcyBwcm9ncmFtYXMgZGUgZ29iaWVybm8gZXMgbGEgZGUgYGRlc2Fycm9sbG9gLCBleGNlcHRvIHBvciBBRE4gcXVpZW5lcyB1dGlsaXphbiBlbiBzdSBsdWdhciBsYSBwYWxhYnJhIGBwcm9ncmVzb2AuIAoKIyMjIDMuIENvbXBhcmFjacOzbiBkZSBmcmVjdWVuY2lhcyAKCkFob3JhIGJpZW4sIMK/Y3XDoW4gcGFyZWNpZG9zIHNvbiBsb3MgcGFydGlkb3MgcG9sw610aWNvcyBlbnRyZSBzw60/IFlhIHZpbW9zIHF1ZSB1bmEgZGUgbGFzIHBhbGFicmFzIGNvbXVuZXMgZXMgZGVzYXJyb2xsbywgwr9xdcOpIGhheSBkZSBsYXMgZGVtw6FzIHBhbGFicmFzPyBQb2RlbW9zIGNvbXBhcmFyIGxhcyBmcmVjdWVuY2lhcyBkZSB1c28gZGUgbGFzIHBhbGFicmFzIGVudHJlIGxvcyBwYXJ0aWRvcy4gCgpgYGB7cn0KIyBBbnRlcyBkZSBjb21wYXJhciBwcmltZXJvIGPDoWxjdWxhbW9zIGxhcyBwcm9wb3JjaW9uZXMgZGUgcGFsYWJyYXMgZGVudHJvIGRlIGNhZGEgcHJvZ3JhbWEKcHJvcDEgPC0gZnJlcSAlPiUKICBncm91cF9ieShwYXJ0aWRvKSAlPiUKICBtdXRhdGUocHJvcG9yY2lvbiA9IG4gLyBzdW0obikpICU+JQogIHNlbGVjdCgtbikgICU+JQogIHNwcmVhZChwYXJ0aWRvLCBwcm9wb3JjaW9uKQoKcHJvcDIgPC0gcHJvcDEgJT4lCiAgZ2F0aGVyKHBhcnRpZG8sIHByb3BvcmNpb24sIGMoMiwgMywgNCwgNSwgNiwgNywgOSkpCmBgYAoKCmBgYHtyLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD02LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIEFob3JhIHJlYWxpemFtb3MgdW4gZ3LDoWZpY28gZGUgY29tcGFyYWNpw7NuIGRlIGZyZWN1ZW5jaWFzCmxpYnJhcnkoc2NhbGVzKQoKZ2dwbG90KHByb3AyLCBhZXMoeCA9IHByb3BvcmNpb24sIHkgPSBgTUFTLUlQU1BgLCBjb2xvciA9IGFicyhgTUFTLUlQU1BgIC0gcHJvcG9yY2lvbikpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZ2VvbV9hYmxpbmUoY29sb3IgPSAiZ3JheTQwIiwgbHR5ID0gMikgKwogIGdlb21faml0dGVyKGFscGhhID0gMC4xLCBzaXplID0gMi41LCB3aWR0aCA9IDAuMywgaGVpZ2h0ID0gMC4zKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhbGFicmEpLCBjaGVja19vdmVybGFwID0gVFJVRSwgdmp1c3QgPSAxLjUpICsKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpICsKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudChsaW1pdHMgPSBjKDAsIDAuMDAxKSwgbG93ID0gImRhcmtzbGF0ZWdyYXk0IiwgaGlnaCA9ICJncmF5NzUiKSArCiAgZmFjZXRfd3JhcCh+cGFydGlkbywgbmNvbCA9IDIpICsKICB0aGVtZV9saW5lZHJhdygpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLCBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKwogIGxhYnModGl0bGUgPSAiQ09NUEFSQUNJw5NOIERFIEZSRUNVRU5DSUFTIERFIFBBTEFCUkFTIEVOVFJFIFBST0dSQU1BUyBERSBHT0JJRVJOTyIsIHkgPSAiTUFTLUlQU1AiLCB4ID0gTlVMTCkgCiAgCmBgYAoKTGEgZm9ybWEgZGUgbGVlciBlc3RlIGdyw6FmaWNvIGVzIGxhIHNpZ3VpZW50ZTogCgoqIExhcyBwYWxhYnJhcyBxdWUgc2UgZW5jdWVudHJhbiBlbiBlbCBzZWN0b3IgZGlhZ29uYWwgc3VwZXJpb3IgZW4gdG9kb3MgbG9zIHBhbmVsZXMgcGVydGVuZWNlbiBhbCBwcm9ncmFtYSBkZWwgTUFTLUlQU1AsIG1pZW50cmFzIGxhcyBxdWUgc2UgZW5jdWVudHJhbiBlbiBsYSBwYXJ0ZSBkaWFnb25hbCBpbmZlcmlvciBwZXJ0ZW5lY2VuIGFsIHByb2dyYW1hIGRlIGNhZGEgcGFydGlkbyBxdWUgZXN0w6EgZW4gZWwgdMOtdHVsbyBkZWwgcGFuZWwuIAoqIExhcyBwYWxhYnJhcyBxdWUgZXN0w6FuIG3DoXMgY2VyY2EgZGUgbGEgbGluZWEgZGlhZ29uYWwgdGllbmVuIHVuYSBzaW1pbGFyIGZyZWN1ZW5jaWEgZW4gZWwgcGFyIGRlIHRleHRvcyBjb21wYXJhZG9zOyBhcXXDrSBlbCBjb2xvciBkZSBsYSBwYWxhYnJhIHRpZW5lIHNpZ25pZmljYWRvOiBlbnRyZSBtw6FzIGNlcmNhbm8gYSBsYSBsaW5lYSBzdSBmcmVjdWVuY2lhIGVzIHNpbWlsYXIgZW50cmUgbG9zIGRvcyBwcm9ncmFtYXMgY29tcGFyYWRvcywgeSBsYSBwYWxhYnJhIHNlIHBvbmUgdmVyZGU7IG1pZW50cmFzIHNpIGVzIG3DoXMgcGFydGljdWxhciBhIGNhZGEgcHJvZ3JhbWEgZW50b25jZXMgbGEgcGFsYWJyYSBlc3TDoSBhbGVqYWRhIGRlIGxhIGxpbmVhIHkgc2UgcG9uZSBtw6FzIGdyaXMuCiogUG9yIMO6bHRpbW8sIGxhIGxpbmVhIGRpYWdvbmFsIGFzY2llbmRlIGRlc2RlIGxhcyBwYWxhYnJhcyBtZW5vcyBmcmVjdWVudGVzIGhhY8OtYSBsYXMgbcOhcyBmcmVjdWVudGVzLiAKCkVudG9uY2VzIGxhcyBwYWxhYnJhcyBtw6FzIGNvbXVuZXMgZW4gY2FkYSBwYXIgZGUgcHJvZ3JhbWFzIHNvbiBsYXMgcGFsYWJyYXMgdmVyZGVzIHF1ZSBzZSBlbmN1ZW50cmFuIGVuIGVsIGV4dHJlbW8gc3VwZXJpb3IgZGUgbGEgZGlhZ29uYWwsIG1pZW50cmFzIGxhcyBtZW5vcyBjb211bmVzIGVudHJlIHPDrSBzb24gbGFzIHBhbGFicmFzIGdyaXNlcyBlbiBlbCBleHRyZW1vIGluZmVyaW9yIGRlIGxhIGRpYWdvbmFsLCBleGlzdGllbmRvIG11Y2hvcyB2YWxvcmVzIGludGVybWVkaW9zLgoKUGFyYSBtYXlvciBjbGFyaWRhZCwgZGVtb3MgdW4gZWplbXBsby4gTGVhbW9zIGVsIHRlcmNlciBwYW5lbCBxdWUgZXMgbGEgY29tcGFyYWNpw7NuIGVudHJlIGxvcyBwcm9ncmFtYXMgZGVsIE1BUy1JUFNQIHkgQ1JFRU1PUy4gTGFzIHBhbGFicmFzIGBkZXNhcnJvbGxvYCwgYGFjY2Vzb2AsIGBiaWVuYCB5IGBnYXNgIHNvbiBwYWxhYnJhcyBjb211bmVzIGVuIGZyZWN1ZW5jaWEgZW4gYW1ib3MgcHJvZ3JhbWFzLiBNaWVudHJhcyBxdWUgYGVjb27Ds21pY2FzYCBlcyBtw6FzIHVuYSBwYWxhYnJhIHBhcnRpY3VsYXIgYWwgcHJvZ3JhbWFzIGRlbCBNQVMgeSBgbGVnYWxlc2AgYSBkZSBDUkVFTU9TLiBEZSBlc3RhIGZvcm1hIHNlIHB1ZWRlbiBsZWVyIGxhcyBkZW3DoXMgY29tcGFyYWNpb25lcy4gCgojIyMgNC4gQ29ycmVsYWNpb25lcyBkZSBwYWxhYnJhcyBlbnRyZSBwcm9ncmFtYXMKCkVsIGFudGVyaW9yIGdyw6FmaWNvIG5vcyBtb3N0cmFiYSBlbCBkZXRhbGxlIGRlIGxhcyBwYWxhYnJhcyBjb21wYXJhZGFzLiBBaG9yYSB2ZWFtb3MgdW4gcmVzdW1lbiBjb24gdW5hIG1lZGlkYSBkZSBjb3JyZWxhY2nDs25eW0FxdcOtIHV0aWxpemFtb3MgZWwgW2NvZWZpY2llbnRlIHBoaV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUGhpX2NvZWZmaWNpZW50KS4gU3UgaW50ZXJwcmV0YWNpw7NuIGVzIHNpbWlsYXIgYSBsYSBjb3JyZWxhY2nDs24gZGUgUGVhcnNvbl0uIAoKYGBge3IsIG1lc3NhZ2U9Riwgd2FybmluZz1GfQojIENyZWFtb3MgdW5hIG1hdHJpeiBkZSBjb3JyZWxhY2nDs24geSBsdWVnbyBsYSB2aXN1YWxpemFtb3MKbGlicmFyeSh3aWR5cikKZnJlcV9jb3IgPC0gZnJlcSAlPiUKICBwYWlyd2lzZV9jb3IocGFydGlkbywgcGFsYWJyYSwgbiwgc29ydCA9IFRSVUUpCgpmcmVxX2NvcjIgPC0gc3ByZWFkKGZyZXFfY29yLCBpdGVtMiwgY29ycmVsYXRpb24pICU+JQogIHJlbmFtZShyb3duYW1lID0gaXRlbTEpICU+JQogIGNvbHVtbl90b19yb3duYW1lcygpCnJwbG90KGZyZXFfY29yMiwgc2hhcGUgPSAyMCwgcHJpbnRfY29yID0gVCwgY29sb3JzID0gYygicmVkIiwgImdyZWVuIiksIGxlZ2VuZCA9IEYpICsKICBsYWJzKHRpdGxlID0gIkNvcnJlbGFjaW9uZXMgZGUgcGFsYWJyYXMgZW50cmUgcHJvZ3JhbWFzIGRlIGdvYmllcm5vIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSAKCmBgYAoKTGEgZm9ybWEgZGUgbGVlciBlc3RlIGdyw6FmaWNvIGVzIGxhIHNpZ3VpZW50ZS4gRWwgY29lZmljaWVudGUgaW5kaWNhIGN1w6FuIHBhcmVjaWRhcyBzb24gbGFzIHBhbGFicmFzIHVzYWRhcyBlbnRyZSBkb3MgcHJvZ3JhbWFzIGRlIDAgYSAxLCBzaWVuZG8gMSBsYSBtw6F4aW1hIGNvcnJlbGFjacOzbiBwb3NpdGl2YS4gU2UgcHVlZGUgZW1wZXphciBkZSBsYSBmaWxhIHN1cGVyaW9yIGUgaXIgZGUgaXpxdWllcmRhIGEgZGVyZWNoYSBjb21wYXJhbmRvIGxhIGZpbGEgc2VsZWNjaW9uYWRvIGNvbiBsb3Mgb3Ryb3MgcGFydGlkb3MgeSBlbmNvbnRyYW5kbyBsYSBjb3JyZWxhY2nDs24gbcOhcyBhbHRhLiBQb3IgZWplbXBsbywgUEFOLUJPTCB0aWVuZSBsYSBjb3JyZWxhY2nDs24gbcOhcyBhbHRhIGNvbiBGUFYsIHVuIC43LgoKIyMjIDUuIFTDqXJtaW5vcyBwYXJ0aWN1bGFyZXMKCkFob3JhIHZlcmVtb3MgbG9zIHTDqXJtaW5vcyBtw6FzIHBhcnRpY3VsYXJlcyBkZSBjYWRhIGRvY3VtZW50byBlbiBjb21wYXJhY2nDs24gY29uIGxvcyBvdHJvcyBkb2N1bWVudG9zLiBVc2FyZW1vcyBlbCBlc3RhZMOtc3RpY28gZGUgdGYtaWRmXltTaWduaWZpY2EgKnRlcm0gZnJlcXVlbmN5IHRpbWVzIGludmVyc2UgZG9jdW1lbnQgZnJlcXVlbmN5Ki4gQsOhc2ljYW1lbnRlIGRpc21pbnV5ZSBlbCBwZXNvIGRlIGxhcyBwYWxhYnJhcyBkZSB1c28gY29tw7puIHkgYXVtZW50YSBlbCBwZXNvIGRlIGxhcyBwYWxhYnJhcyBxdWUgbm8gc2UgdXNhbiBtdWNobyBlbiB1bmEgY29sZWNjacOzbiBkZSBkb2N1bWVudG9zXSwgcXVlIG1pZGUgcHJlY2lzYW1lbnRlIGVzbzogTGEgZnJlY3VlbmNpYSBkZSB1biB0w6lybWlubyBhanVzdGFkbyBzZWfDum4gbGEgcGFydGljdWxhcmlkYWQgY29uIGxhIHF1ZSBzZSB1c2EuIAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgojIENhbGN1bGFtb3MgZWwgdG90YWwgZGUgbGFzIHBhbGFicmFzIGVuIGNhZGEgZG9jdW1lbnRvIHBhcmEgbHVlZ28gYWp1c3RhciBsYSBmcmVjdWVuY2lhIAp0b3RhbF9wYWxhYnJhcyA8LSBmcmVxJT4lCiAgZ3JvdXBfYnkocGFydGlkbykgJT4lCiAgc3VtbWFyaXplKHRvdGFsID0gc3VtKG4pKQpmcmVxIDwtIGxlZnRfam9pbihmcmVxLCB0b3RhbF9wYWxhYnJhcykKYGBgCgpgYGB7cn0KIyBDw6FsY3VsYW1vcyBlbCB0Zi1pZGYgZGUgY2FkYSB0ZXJtaW5vIApmcmVxIDwtIGZyZXEgJT4lCiAgYmluZF90Zl9pZGYocGFsYWJyYSwgcGFydGlkbywgbikKCmZyZXFfcGFydCA8LSBmcmVxICU+JQogIGFycmFuZ2UocGFydGlkbywgZGVzYyh0Zl9pZGYpKSAlPiUKICBtdXRhdGUocGFsYWJyYSA9IGZhY3RvcihwYWxhYnJhLCBsZXZlbHMgPSByZXYodW5pcXVlKHBhbGFicmEpKSkpCmZyZXFfcGFydApgYGAKCgpgYGB7ciBtZXNzYWdlPUZBTFNFfQojIFJlY29ydGFtb3MgbGFzIDEwIHBhbGFicmFzIHBhcnRpY3VsYXJlcyBtw6FzIHVzYWRhcwp0b3BfcGFydCA8LSBmcmVxX3BhcnQgJT4lCiAgZ3JvdXBfYnkocGFydGlkbykgJT4lCiAgc2xpY2UoMToxMCkgJT4lCiAgYXJyYW5nZShwYXJ0aWRvKQp0b3BfcGFydApgYGAKCgpgYGB7ciwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBWaXN1YWxpemFtb3MgbGFzIDEwIHBhbGFicmFzIG3DoXMgcGFydGljdWxhcmVzCnRvcF9wYXJ0ICU+JSAKICBnZ3Bsb3QoYWVzKHggPSByZW9yZGVyX3dpdGhpbihwYWxhYnJhLCB0Zl9pZGYsIHBhcnRpZG8pLCB5ID0gdGZfaWRmLCBmaWxsID0gcGFydGlkbykpICsKICAgIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsKICAgIGZhY2V0X3dyYXAofnBhcnRpZG8sIG5jb2wgPSAyLCBzY2FsZXMgPSAiZnJlZSIpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV94X3Jlb3JkZXJlZCgpICsKICAgIGxhYnMoeSA9ICJ0Zi1pZGYiLAogICAgICAgICB4ID0gTlVMTCwKICAgICAgICAgdGl0bGUgPSAiTGFzIDEwIHBhbGFicmFzIG3DoXMgcGFydGljdWxhcmVzIGRlIGxvcyBcbiBwcm9ncmFtYXMgZGUgZ29iaWVybm8iKSArCiAgICB0aGVtZV9taW5pbWFsKCkgKwogICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCmBgYAoKRXN0ZSBncsOhZmljbyBub3MgZGEgbGEgcGVyc3BlY3RpdmEgbcOhcyBwYXJ0aWN1bGFyIGRlIGxvcyBjb25jZXB0b3MgdXNhZG9zIGVuIGxvcyBwcm9ncmFtYXMgZGUgZ29iaWVybm8uIEFob3JhIHPDrSBhcGFyZWNlbiBhbGd1bm9zIHRlcm1pbm9zIGRpZmVyZW5jaWFkb3Jlcy4KCiMjIENvbmNsdXNpb25lcwoKRW4gdGVtYXMgcG9sw610aWNvLWVsZWN0b3JhbGVzIHN1ZWxlIGV4aXN0aXIgdW4gZGViYXRlIGFjYWxhcmFkbyBwYXJhIGludGVudGFyIGRpZmVyZW5jaWFyIHVuIHBhcnRpZG8gZGUgb3Ryby4gU2UganVlZ2FuIG11Y2hhcyBwZXJzcGVjdGl2YXMsIGludGVyZXNlcyB5IGVtb2Npb25lcywgY3Vlc3Rpb25lcyBtw6FzIHN1YmpldGl2YXMuIEFxdcOtIGludGVudGFtb3MgYnJpbmRhciB1bmEgaW5mb3JtYWNpw7NuIG3DoXMgb2JqZXRpdmEgc29icmUgbG9zIHByb2dyYW1hcyBkZSBnb2JpZXJubywgcXVlIGVuIHRlb3LDrWEgZGViZXLDrWFuIHNlciBsYSBiYXNlIGRlIGxvcyBkZWJhdGVzIHBvbMOtdGljb3MgeSBsYSBkZWNpc2nDs24gaW5mb3JtYWRhIHBvciBwYXJ0ZSBkZSBsb3MgY2l1ZGFkYW5vcy4gCgpFbiBnZW5lcmFsLCBlbmNvbnRyYW1vcyBxdWUgaGF5IG11Y2hvIHBhcmVjaWRvIGVudHJlIGxvcyBjb25jZXB0b3MgZGUgdG9kb3MgbG9zIHBhcnRpZG9zIGVuIGNhcnJlcmEgeSBhbGd1bmFzIGRpZmVyZW5jaWFzLiBObyBvYnN0YW50ZSwgbGFzIGNvbmNsdXNpb25lcyBmaW5hbGVzIGxhcyB0aWVuZSBlbCBjaXVkYWRhbm8sIGEgcGFydGlyIGRlIHVuYSBvYnNlcnZhY2nDs24gYXRlbnRhIGRlIGxvcyBncsOhZmljb3MgcXVlIGxlIHByZXNlbnRhbW9zLiAgCgpQb3Igc3VwdWVzdG8sIHF1ZSBubyBzw7NsbyBzZSBkZWJlIGp1emdhciBhIHVuIHBhcnRpZG8geSBzdXMgY2FuZGlkYXRvcyBwb3IgbG9zIHByb2dyYW1hcyBkZSBnb2JpZXJuby4gRXMgcG9yIGVzbyBxdWUgZW4gbGFzIHNpZ3VpZW50ZXMgZW50cmVnYXMgZGVsICJWb2NhYnVsYXJpbyBkZWwgcG9kZXIiLCBhbmFsaXphcmVtb3MgbG9zIGRpc2N1cnNvcyBlbiBUd2l0dGVyIGRlIGxvcyBjYW5kaWRhdG9zIHkgbHVlZ28gbG9zIGRpc2N1cnNvcyBlbiBtZWRpb3MgZGUgY29tdW5pY2FjacOzbi4=