Introducción

Este estudio pretende descubrir la carga sentimental que poseen los tweets de Pedro Castillo y cuáles logran una mayor interacción con la población, para ello utilizaremos el entorno y lenguaje de programación R.

Herramientas

  • R
  • rtweet
  • ggplot2

Recolección de datos

Los datos serán obtenidos mediante la API de Twitter con la librería rtweet, para ello es necesario registrarse en la aplicación y obtener las credenciales en la sección desarrolladores, de forma predeterminada solo se puede acceder a información pública de los tweets y usuarios.

twitter_tokens <- create_token(app = "", consumer_key = "", consumer_secret = "")

Una vez autenticados pasamos a recolectar los tweets.

castillovar <- get_timeline("PedroCastilloTe", n = 4000)

Seleccionaremos la variable de interés y guardamos los datos en un archivo .csv:

castillovar <- castillovar[c("created_at", "text", "favorite_count", "retweet_count")]
num_rows = nrow(castillovar)
  
# creating ID column vector
X <- c(1:num_rows)
 
# binding id column to the data frame
castillovar <- cbind(X , castillovar)
write_as_csv(castillovar, "castillovar.csv")

Con readr cargamos el archivo .csv

library(readr)
castillovar <- read_csv("castillovar.csv")
castillovar

Preparación de los datos

Una pieza central para un análisis de texto (text mining) es el tokenizado. La tokenización es una forma de separar un fragmento de texto en unidades más pequeñas llamadas tokens. Aquí, los tokens pueden ser palabras, caracteres o subpalabras. Por lo tanto, la tokenización se puede clasificar ampliamente en 3 tipos: tokenización de palabra, carácter y subpalabra (caracteres n-grama).

Utilizaremos string y stringr para la manipulación de caracteres, dplyr para la manipulación del data frame, magrittr para el uso de pipes y tidytext para el tokenizado y el análisis de texto.

library(stringi)
library(stringr)
library(dplyr)
library(magrittr)
library(tidytext)

# Quitamos los acentos a los tweets.

castillovar$text <- stri_trans_general(castillovar$text, "Latin-ASCII")

# Limpiamos la variable text de algunos elementos innecesarios y  tokenizamos.

replace_reg <- "https://t.co/[A-Za-z\\d]+|http://[A-Za-z\\d]+|&amp;|&lt;|&gt;|RT|https"
unnest_reg <- "([^A-Za-z_\\d#@']|'(?![A-Za-z_\\d#@]))"
castillovar_t <- castillovar %>% 
  filter(!str_detect(text, "^RT")) %>%
  mutate(text = str_replace_all(text, replace_reg, "")) %>%
  unnest_tokens(word, text, token = "regex", pattern = unnest_reg)  # Tokenizado
rm(replace_reg, unnest_reg) 

El resultado es DataFrame más grande, de 42751 observaciones, Donde se reemplaza la columna (variable) text por word, manteniendo la variable X como ID:

str(castillovar_t)
tibble [42,751 x 5] (S3: tbl_df/tbl/data.frame)
 $ X             : num [1:42751] 1 1 1 1 1 1 1 1 1 1 ...
 $ created_at    : POSIXct[1:42751], format: "2022-10-18 22:21:14" "2022-10-18 22:21:14" "2022-10-18 22:21:14" ...
 $ favorite_count: num [1:42751] 0 0 0 0 0 0 0 0 0 0 ...
 $ retweet_count : num [1:42751] 199 199 199 199 199 199 199 199 199 199 ...
 $ word          : chr [1:42751] "u" "0001f534" "#ahora" "numeroso" ...

El siguiente problema es que las palabras con mayor frecuencia son, como era de esperarse, artículos, preposiciones, conjunciones, y otros similares:

library(ggplot2)
freq1 <- castillovar_t %>%
        count(word, sort = TRUE)
head(freq1, n = 30) %>%
        ggplot(aes(reorder(word, n), n)) +
        geom_bar(stat="identity", fill="#1a3a56") +
        coord_flip() + 
        xlab("Palabras más usadas") +
        ylab("Número") +
        theme_minimal()

Esas palabras no agregan ninguna información relevante para entender la polaridad de los sentiments, son “palabras vacías” que debemos filtrar. Para ello necesitamos una lista de ese tipo de palabras en español que extraeremos del paquete stopwords:

library(stopwords)

#crear una lista de palabras vacias en español
stopwords_ES <- tibble(stopwords("spanish")) 
colnames(stopwords_ES) <- "word"

#Agregamos algunas palabras vacias adicionales (lugares y monedas, etc.)
custom_stop <- tibble(word = c("lima", "cajamarca", "peru", "0001f134","0001f534", "dolar", "sol", "derecha", "u", "@pedrocastillote", "primero", "0001f1ea", "0001f1f5", "mas", "presidente","hoy", "fe0f", "#siempreconelpueblo","#palabrademaestro"))
stopwords_ES <- bind_rows(custom_stop, stopwords_ES)
rm(custom_stop)

#filtrado con la lista de palabras vacias
castillovar_tf <- castillovar_t %>% 
 filter(!word %in% stopwords_ES$word,
         str_detect(word, "[a-z]"))
str(castillovar_tf)
tibble [20,983 x 5] (S3: tbl_df/tbl/data.frame)
 $ X             : num [1:20983] 1 1 1 1 1 1 1 1 1 1 ...
 $ created_at    : POSIXct[1:20983], format: "2022-10-18 22:21:14" "2022-10-18 22:21:14" "2022-10-18 22:21:14" ...
 $ favorite_count: num [1:20983] 0 0 0 0 0 0 0 0 0 0 ...
 $ retweet_count : num [1:20983] 199 199 199 199 199 199 199 199 199 199 ...
 $ word          : chr [1:20983] "#ahora" "numeroso" "grupo" "licenciados" ...

Ahora sí podemos observar las palabras más utilizadas por Pedro Castillo (@PedroCastilloTe):

freq2 <- castillovar_tf %>%
        count(word, sort = TRUE)
head(freq2, n = 30) %>%
        ggplot(aes(reorder(word, n), n)) +
        geom_bar(stat="identity", fill="#1a3a56") +
        coord_flip() +
        xlab("Palabras más usadas") +
        ylab("Número")+
        theme_minimal()

Análisis de datos

El análisis de sentimiento nos permite aproximarnos a la intención emocional de los tweets que lanza el presidente Pedro Castillo. Este tipo de análisis puede basarse en el análisis de palabras o relaciones de palabras (n-gramas) y se pueden evaluar diferentes escalas de sentimiento (binarias, ponderadas, etc.).

Elegimos el enfoque de “bolsa de palabras”, el nivel del unigrama y la escala binaria, como una primera aproximación expedita. Ahora bien, existen diversos métodos para evaluar los sentiments en los textos, desde la anotación manual hasta el uso de machine learning, pero aquí utilizaremos el método basado en diccionario (Silge y Robinson 2017).

Este método conste en utilizar un diccionario en formato clave:valor para evaluar cada palabra. Se considera al tweet como una combinación de palabras individuales que tienen una carga emocional y la proporción de esas palabras nos da el sentimiento general del tweet, como posteriormente reflejaremos en un indice de sentimiento.

Los diccionarios para análisis de sentimiento en español son escasos y poco desarrollados. Después de una larga búsqueda pudimos encontrar el diccionario iSol que está formado por 8135 palabras, 2.509 positivas y 5.626 negativas, dejando a un lado las palabras emocionalmente neutras. Este diccionario a su vez está basado en otro diccionario en inglés bastante testeado como es el de Bing Liu, siendo una traducción especializada y mejorada.

#cargamos y adecuamos el diccionario al formato requerido.
negativas <- read_csv("isol/negativas_mejorada.csv", col_names = "word") %>%
  mutate(sentiment = "negativo") 
Rows: 5626 Columns: 1
-- Column specification ----------------------------------------------------------------------------
Delimiter: ","
chr (1): word

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
positivas <- read_csv("isol/positivas_mejorada.csv", col_names = "word") %>%
  mutate(sentiment = "positivo")
Rows: 2509 Columns: 1
-- Column specification ----------------------------------------------------------------------------
Delimiter: ","
chr (1): word

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
bingES <- bind_rows(negativas, positivas) 
rm(negativas, positivas)

# Quitamos los acentos.
bingES$word <- stri_trans_general(bingES$word, "Latin-ASCII") 
bingES

Una primera prueba del diccionario que realizaremos será comprobar qué porcentaje de las palabras únicas utilizadas por @PedroCastilloTe clasifica este diccionario:

# palabras únicas usadas por @PedroCastilloTe
castillo_w <- unique(castillovar_tf$word) %>% tibble() 
colnames(castillo_w) <- "word"
print(paste("Palabras únicas usadas por @PedroCastilloTe:", length(castillo_w$word)))
[1] "Palabras únicas usadas por @PedroCastilloTe: 6295"
# palabras en el diccionario
dic_w <- bingES$word 
print(paste("Palabras en el diccionario:", length(dic_w)))
[1] "Palabras en el diccionario: 8135"
# palabras clasificadas
castillo_wc <- castillo_w %>% filter(word %in% dic_w) 
print(paste("Palabras clasificadas:", length(castillo_wc$word)))
[1] "Palabras clasificadas: 688"
# palabras no clasificadas
castillo_uc <- castillo_w %>% filter(!word %in% dic_w) 
print(paste("Palabras no clasificadas:", length(castillo_uc$word)))
[1] "Palabras no clasificadas: 5607"
# Porcentaje de palabras clasificadaas
por_w <- (length(castillo_wc$word) / length(castillo_w$word)) * 100
print(paste("Porcentaje de palabras clasificadaas:", por_w, "%"))
[1] "Porcentaje de palabras clasificadaas: 10.9293089753773 %"

Palabras no clasificadas

castillo_uc 

El diccionario clasificó el 10.91% de las palabras. Lo ideal es que el diccionario se aproxime al 20% de las palabras siguiendo la ley de Zipf, por lo que efectuaremos unas modificaciones.

Al revisar el diccionario encontramos tres problemas:

  • Primero, si bien contiene muchas palabras con clara carga sentimental, en ocasiones no contiene todas sus flexiones.
  • Segundo, dado que es un diccionario general, no captura algunas particularidades del discurso político del presidente, particularmente su discurso nacionalista.
  • Tercero, existen palabras polarizadas que sirven para indicar el sentimiento frente a un producto o servicio, pero no tienen efectividad en temas políticos.

Para el primer problema añadiremos flexiones basadas ya en las palabras existentes en el diccionario, para el segundo añadiremos las palabras politizadas más utilizadas, evaluando su polaridad en un intento de un diccionario político inicial, y para el tercero retiraremos las palabras no apropiadas:

# Añadiendo flexiones y otras palabras polarizadas
flex_dic <- read_csv("CastilloNC.csv", col_names = c("word", "sentiment"))
Rows: 8985 Columns: 2
-- Column specification ----------------------------------------------------------------------------
Delimiter: ","
chr (2): word, sentiment

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
flex_dic <- flex_dic %>% filter(str_detect(sentiment, "positivo|negativo"))
flex_dic
bingESmod <- bind_rows(bingES, flex_dic)
bingESmod 

Añadiendo palabras politizadas

tribble(
  ~word, ~sentiment,
  "pueblo", "positivo",
  "eeuu", "negativo",
  "estadounidense", "negativo",
  "estadounidenses", "negativo",
  "chile", "negativo",
  "imperio", "negativo",
  "imperios", "negativo",
  "imperial", "negativo",
  "imperiales", "negativo",
  "imperialismo", "negativo",
  "capitalismo", "negativo",
  "capitalista", "negativo",
  "procapitalista", "negativo",
  "capitalización", "negativo",
  "neoliberal", "negativo",
  "neoliberales", "negativo",
  "neoliberalismo", "negativo",
  "neocolonial", "negativo",
  "neocoloniales", "negativo",
  "neocolonialismo", "negativo",
  "recolonizacion", "negativo",
  "oligarquia", "negativo",
  "oligarquias", "negativo",
  "oligarca", "negativo",
  "oligarcas", "negativo",
  "oligarquica", "negativo",
  "oligarquicos", "negativo",
  "derecha", "negativo",
  "derechistas", "negativo",
  "fmi", "negativo",
  "trump", "negativo",
  "patria", "positivo",
  "soberania", "positivo",
  "soberanias", "positivo",
  "soberano", "positivo",
  "soberanos", "positivo",
  "transnacional", "negativo",
  "opositor", "negativo",
  "opositora", "negativo",
  "vacadora", "negativo",
  "ultraderecha", "negativo",
  "vacadores", "negativo",
  "monopolio", "negativo",
  "opositor", "negativo",
  "golpistas", "negativo",
  "mermelera", "negativo",
  "prensa", "negativo",
  "congreso", "negativo",
  "discriminacion", "negativo",
  "desigualdad", "negativo",
  "igualdad", "positivo",
  "desinformaciones", "negativo",
  "desesperacion", "negativo",
  "imputaciones", "negativo",
  "portatiles", "negativo",
  "persecucion", "negativo",
  "opositores", "negativo"
) -> pol_dic
bingESmod <- bind_rows(bingESmod, pol_dic)

#Quitando otras palabras no pertinentes
supr_dic <- c("mejor", "mejores", "peor", "peores", "economico", "economicos", "nueva", "nuevas", "nuevo", "nuevos", "grande", "grandes", "importante", "importantes", "decision", "interes", "intereses", "mayor", "primera", "maduro", "garantizar", "humano", "humanos", "nuevas", "recursos", "lider", "lideres", "pronto", "seria", "corte", "primero", "seguro", "seguros", "principal", "principales", "sentido")
bingESmod <- bingESmod  %>% filter(!word %in% supr_dic)

Volvemos a evaluar el alcance del diccionario y llegamos al 12.2%:

# palabras en el diccionario
dic_w <- bingESmod$word 
print(paste("Palabras en el diccionario:", length(dic_w)))
[1] "Palabras en el diccionario: 8736"
# palabras clasificadas
castillo_wc <- castillo_w %>% filter(word %in% dic_w)
print(paste("Palabras clasificadas:", length(castillo_wc$word)))
[1] "Palabras clasificadas: 766"
# Porcentaje de palabras clasificadaas
por_w <- (length(castillo_wc$word) / length(castillo_w$word)) * 100
print(paste("Porcentaje de palabras clasificadaas:", por_w, "%"))
[1] "Porcentaje de palabras clasificadaas: 12.1683876092137 %"

Gracias al tokenizado, que nos dejo una estructura de una palabra por observación y al diccionario en formato clave: valor, esta clasificación solo nos ocupará la función inner_join que fusiona dos tablas de datos por valores comunes:

castillosentiment <- castillovar_tf %>%
  inner_join(bingESmod)
Joining, by = "word"
castillosentiment

Aquí un primer acercamiento al clima emocional de los tweets del presidente consiste en ver los porcentajes globales de palabras positivas y negativas:

castillosentiment %>%
        ggplot(aes(sentiment)) +
        geom_bar(aes(y = (..count..)/sum(..count..)*100),fill="#1a3a56") +
        xlab("sentimiento") + 
        ylab("porcentaje") +
        theme_minimal()

Aproximadamente un 68% de las palabras que ha utilizado Pedro Cstillo son positivas, mientras el 32% son negativas.

Las palabras que más peso aportan a la positividad y negatividad son las siguientes:

count_sent <- castillosentiment %>%
  count(word, sentiment, sort = TRUE) %>%
  ungroup()
count_sent

#Graficamos
count_sent %>%
 group_by(sentiment) %>%
  top_n(30) %>%
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(word, n, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~sentiment, scales = "free_y") +
  labs(y = "Contribución al sentimiento",
       x = NULL) +
  coord_flip() +
  theme_minimal()
Selecting by n

Ahora crearemos un indice de sentimiento (isent) para ponderar la carga de positividad o negatividad en cada tweet. Para ello: \(isent(t) = s / nw\) donde el indice de sentimiento para un tweet sera la proporción entre el numero de palabras con carga emocional \(s\) dividido entre el total de palabras \(nw\), excluyendo las palabras vacías. Crearemos un índice para cada polaridad:

#Contamos el total de palabras negativas y positivas por tweets
library(tidyr)
tweets_sen <- castillosentiment %>%
  group_by(X) %>%
  count(sentiment)
castillovar_sent <- inner_join(castillovar, tweets_sen)
Joining, by = "X"
castillovar_sent <- spread(castillovar_sent, sentiment, n)
castillovar_sent[is.na(castillovar_sent)] <- 0
#Limpiamos de las palabras vacias y las URL de la variable texto y la añadimos a nuestra tabla de datos
library(tm)
castillo_corpus <- (Corpus(VectorSource(castillovar_sent$text)))

corpus <- tm_map(castillo_corpus, removeWords, stopwords("spanish"))
Warning in tm_map.SimpleCorpus(castillo_corpus, removeWords, stopwords("spanish")) :
  transformation drops documents
removeURL <- function(x) gsub("http[[:alnum:][:punct:]]*", "", x) 

corpus <- tm_map(corpus, content_transformer(removeURL))
Warning in tm_map.SimpleCorpus(corpus, content_transformer(removeURL)) :
  transformation drops documents
text_c <- data.frame(text=sapply(corpus, identity), 
    stringsAsFactors=F)
castillovar_sent <- bind_cols(castillovar_sent, text_c)
New names:
* `text` -> `text...3`
* `text` -> `text...8`
#Contamos las palabras de cada tweet y calculamos los indices
castillovar_sent <- mutate(castillovar_sent, nw = str_count(castillovar_sent$text...3, "\\S+"))
castillovar_sent <- mutate(castillovar_sent, isent_neg =  (negativo / nw)*100)
castillovar_sent <- mutate(castillovar_sent, isent_pos =  (positivo / nw)*100)
castillovar_sent 

Ahora crearemos una variable nueva llamada interact que es simplemente la suma de de los favoritoss y retweets. Ello se justifica porque existe una fuerte correlación entre esos dos tipos de interacción.

#Correlación entre los favs y los retweets
cor(castillovar_sent$favorite_count, castillovar_sent$retweet_count)
[1] 0.7395054
#Creamos una nueva variable que es la interacción
castillovar_sent$interact <- castillovar_sent$favorite_count + castillovar_sent$retweet_count
castillovar_sent

Por ultimo graficaremos y calcularemos la relación entre el indice de sentimiento y la interacción:

castillovar_sent %>% 
  ggplot() +
  aes(x = isent_pos, y = interact) +
  geom_point() +
  theme_minimal()

cor(castillovar_sent$isent_pos, castillovar_sent$interact) #correlación
[1] 0.1795327
regpos <- lm(interact ~ isent_pos, castillovar_sent) #regresion lineal
summary(regpos)

Call:
lm(formula = interact ~ isent_pos, data = castillovar_sent)

Residuals:
   Min     1Q Median     3Q    Max 
 -6801  -2137  -1446    418  52853 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  1594.86     240.88   6.621 6.00e-11 ***
isent_pos     198.60      35.53   5.589 2.99e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 4470 on 938 degrees of freedom
Multiple R-squared:  0.03223,   Adjusted R-squared:  0.0312 
F-statistic: 31.24 on 1 and 938 DF,  p-value: 2.988e-08
castillovar_sent %>% 
  ggplot() +
  aes(x = isent_neg, y = interact) +
  geom_point() +
  theme_minimal()

cor(castillovar_sent$isent_neg, castillovar_sent$interact)#correlación
[1] 0.02045306
regneg <- lm(interact ~ isent_neg, castillovar_sent) #regresion lineal
summary(regneg)

Call:
lm(formula = interact ~ isent_neg, data = castillovar_sent)

Residuals:
   Min     1Q Median     3Q    Max 
 -3001  -2474  -1611    592  53767 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  2602.95     179.64  14.489   <2e-16 ***
isent_neg      23.33      37.23   0.627    0.531    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 4543 on 938 degrees of freedom
Multiple R-squared:  0.0004183, Adjusted R-squared:  -0.0006473 
F-statistic: 0.3926 on 1 and 938 DF,  p-value: 0.5311

Conclusión

La polaridad general de los tweets de la cuenta de Pedro Castillo apunta a un mayor uso de palabras positivas (68%) que negativas (32%). En la relación entre la polaridad de los tweets y la interacción, podemos encontrar una diferencia entre la recepción de los tweets positivos y los negativos. Los tweets positivos tienen una mayor interacción que los negativos, en la prueba de correlación los tweets positivos obtienen un 0,18 mientras los negativos tan sólo 0,02. Pasando a la prueba de regresión, los tweets por cada punto porcentual positivo reciben en promedio 199 interacciones más, con un p-valor significativo; mientras que los puntos porcentuales negativo no tiene el mismo efecto, consiguiendo 23 interacciones más, pero con un p-valor no significativo.

Lo anterior puede ilustrarse con el análisis de los diez tweets con mayor interacción:

pop_t <- castillovar_sent %>%
        select(text...3, interact, isent_neg, isent_pos) %>%
        arrange(desc(interact))
head(pop_t, n = 10) %>% knitr::kable()
text…3 interact isent_neg isent_pos
Felicito a Francesco de la Cruz por esta digna representacion del pais y hacer sentir que se oiga fuerte el nombre del Peru en esta competencia mundial. !Grande, campeon! #BalloonWorldCup https://t.co/chseXTOJ41 56370 0.000000 9.677419
Acabo de llamar a @petrogustavo para felicitarlo por su historico triunfo democratico en Colombia. Nos une un sentimiento en comun que busca mejoras colectivas, sociales y de integracion regional para nuestros pueblos. Hermano Gustavo, cuente siempre con el apoyo del Peru. 43589 2.439024 7.317073
Un nuevo tiempo se ha iniciado. Millones de peruanos/as se han alzado en defensa de su dignidad y justicia. Gracias a los pueblos de todo el Peru que desde su diversidad y fuerza historica me han brindado su confianza. Mi gobierno se debera a toda la ciudadania.
#PalabraDeMaestro https://t.co/sOt6GResPI 36576 0.000000 6.122449
!Felicitaciones por el triunfo, mi querido amigo @gabrielboric! !La victoria que has alcanzado es la del pueblo chileno y la compartimos los pueblos latinoamericanos que queremos vivir con libertad, paz, justicia y dignidad! Sigamos bregando por la unidad de nuestras naciones. 33823 0.000000 21.951220
!Gracias pueblo peruano por este historico triunfo! Ha llegado el momento de llamar a todos los sectores de la sociedad para construir unidos, en este Bicentenario, un Peru inclusivo, un Peru justo, un Peru Libre. Sin discriminacion y por los derechos y todos y todas. (1/2) https://t.co/JmMdT9miaY 31299 4.255319 10.638298
Estimados/as hermanos/as: agradezco a quienes siguen resistiendo en las calles. No caigamos en provocaciones de quienes quieren ver este pais en el caos. Por ello, hacemos un llamado de paz y tranquilidad. Sigamos firmes y alegres en esta lucha final que es de todos los peruanos. 27108 4.347826 6.521739
Nuestro compromiso es mantener el equilibrio fiscal y mejorar la calidad del gasto publico, promover las inversiones y respetar la independencia y autonomia del BCRP. Por ello nuestra voluntad de ratificar al Dr. Julio Velarde como presidente de esta importante institucion. 26161 0.000000 7.317073
Fallecio el cabecilla terrorista Abimael Guzman, responsable de la perdida de incontables vidas de nuestros compatriotas. Nuestra posicion de condena al terrorismo es firme e indeclinable. Solo en democracia construiremos un Peru de justicia y desarrollo para nuestro pueblo. 24624 10.256410 7.692308
Hemos trasladado a Vladimiro Montesinos al Penal Ancon II hasta el fin de su condena. En el #GobiernoDelBicentenario, ninguna persona privada de libertad tendra un trato privilegiado ni se le permitira burlar la seguridad de los penales para seguir delinquiendo. 20600 5.000000 5.000000
Compatriotas: que la movilizacion pacifica de hoy exprese al Peru y al mundo nuestras esperanzas de cambio hacia un pais mas justo. Ante quienes quieran provocarnos, ofrezcamos nuestra alegria y respeto. Mi corazon con ustedes. !Mucho animo! 19633 0.000000 16.216216

Aquí se puede apreciar que los 10 tweets tienen una considerable carga emocional positiva, lo cual queda representando en sus índices de positividad. Sólo cuatro de los diez tweets más populares de Pedro Castillo son negativos.

A pesar de esas limitaciones, este primer acercamiento nos permite mostrar la importancia de la variable emoción en los discursos políticos en red y un método de recolección y análisis para grandes cantidades de datos textuales en redes sociales.

LS0tDQp0aXRsZTogIkFuw6FsaXNpcyBkZSBzZW50aW1pZW50byBlIGludGVyYWNjacOzbiBlbiBsb3MgVHdlZXRzIGRlIFBlZHJvIENhc3RpbGxvIFRlcnJvbmVzIChAUGVkcm9DYXN0aWxsb1RlKSINCmF1dGhvcjogIkpvc3VlIEh1YW1hbiINCmRhdGU6ICIxOC8xMC8yMDIyIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICB0aGVtZTogeWV0aQ0KICAgIGZpZ193aWR0aDogMjANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICAgIGRmX3ByaW50OiBwYWdlZA0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCi0tLQ0KDQojIyBJbnRyb2R1Y2Npw7NuIA0KDQpFc3RlIGVzdHVkaW8gcHJldGVuZGUgZGVzY3VicmlyIGxhIGNhcmdhIHNlbnRpbWVudGFsIHF1ZSBwb3NlZW4gbG9zIHR3ZWV0cyBkZSBQZWRybyBDYXN0aWxsbyB5IGN1w6FsZXMgbG9ncmFuIHVuYSBtYXlvciBpbnRlcmFjY2nDs24gY29uIGxhIHBvYmxhY2nDs24sIHBhcmEgZWxsbyB1dGlsaXphcmVtb3MgZWwgZW50b3JubyB5IGxlbmd1YWplIGRlIHByb2dyYW1hY2nDs24gUi4NCg0KIyMgSGVycmFtaWVudGFzDQoNCiogUg0KKiBydHdlZXQNCiogZ2dwbG90Mg0KDQojIyBSZWNvbGVjY2nDs24gZGUgZGF0b3MNCg0KTG9zIGRhdG9zIHNlcsOhbiBvYnRlbmlkb3MgbWVkaWFudGUgbGEgQVBJIGRlIFR3aXR0ZXIgY29uIGxhIGxpYnJlcsOtYSBgcnR3ZWV0YCwgcGFyYSBlbGxvIGVzIG5lY2VzYXJpbyByZWdpc3RyYXJzZSBlbiBsYSBhcGxpY2FjacOzbiB5IG9idGVuZXIgbGFzIGNyZWRlbmNpYWxlcyBlbiBsYSBzZWNjacOzbiBkZXNhcnJvbGxhZG9yZXMsIGRlIGZvcm1hIHByZWRldGVybWluYWRhIHNvbG8gc2UgcHVlZGUgYWNjZWRlciBhIGluZm9ybWFjacOzbiBww7pibGljYSBkZSBsb3MgdHdlZXRzIHkgdXN1YXJpb3MuIA0KDQpgYGB7ciBldmFsID0gRn0NCnR3aXR0ZXJfdG9rZW5zIDwtIGNyZWF0ZV90b2tlbihhcHAgPSAiIiwgY29uc3VtZXJfa2V5ID0gIiIsIGNvbnN1bWVyX3NlY3JldCA9ICIiKQ0KYGBgDQoNClVuYSB2ZXogYXV0ZW50aWNhZG9zIHBhc2Ftb3MgYSByZWNvbGVjdGFyIGxvcyB0d2VldHMuIA0KDQpgYGB7ciBldmFsID0gRn0NCmNhc3RpbGxvdmFyIDwtIGdldF90aW1lbGluZSgiUGVkcm9DYXN0aWxsb1RlIiwgbiA9IDQwMDApDQpgYGANCg0KU2VsZWNjaW9uYXJlbW9zIGxhIHZhcmlhYmxlIGRlIGludGVyw6lzIHkgZ3VhcmRhbW9zIGxvcyBkYXRvcyBlbiB1biBhcmNoaXZvIC5jc3Y6DQoNCmBgYHtyIGV2YWwgPSBGfQ0KY2FzdGlsbG92YXIgPC0gY2FzdGlsbG92YXJbYygiY3JlYXRlZF9hdCIsICJ0ZXh0IiwgImZhdm9yaXRlX2NvdW50IiwgInJldHdlZXRfY291bnQiKV0NCmBgYA0KDQpgYGB7ciBldmFsID0gRn0NCm51bV9yb3dzID0gbnJvdyhjYXN0aWxsb3ZhcikNCiAgDQojIGNyZWF0aW5nIElEIGNvbHVtbiB2ZWN0b3INClggPC0gYygxOm51bV9yb3dzKQ0KIA0KIyBiaW5kaW5nIGlkIGNvbHVtbiB0byB0aGUgZGF0YSBmcmFtZQ0KY2FzdGlsbG92YXIgPC0gY2JpbmQoWCAsIGNhc3RpbGxvdmFyKQ0KYGBgDQoNCmBgYHtyIGV2YWwgPSBGfQ0Kd3JpdGVfYXNfY3N2KGNhc3RpbGxvdmFyLCAiY2FzdGlsbG92YXIuY3N2IikNCmBgYA0KDQpDb24gYHJlYWRyYCBjYXJnYW1vcyBlbCBhcmNoaXZvIC5jc3YNCg0KDQpgYGB7ciBldmFsID0gRn0NCmxpYnJhcnkocmVhZHIpDQpjYXN0aWxsb3ZhciA8LSByZWFkX2NzdigiY2FzdGlsbG92YXIuY3N2IikNCmNhc3RpbGxvdmFyDQpgYGANCg0KIyMgUHJlcGFyYWNpw7NuIGRlIGxvcyBkYXRvcw0KDQpVbmEgcGllemEgY2VudHJhbCBwYXJhIHVuIGFuw6FsaXNpcyBkZSB0ZXh0byAoKnRleHQgbWluaW5nKikgZXMgZWwgdG9rZW5pemFkby4gTGEgdG9rZW5pemFjacOzbiBlcyB1bmEgZm9ybWEgZGUgc2VwYXJhciB1biBmcmFnbWVudG8gZGUgdGV4dG8gZW4gdW5pZGFkZXMgbcOhcyBwZXF1ZcOxYXMgbGxhbWFkYXMgdG9rZW5zLiBBcXXDrSwgbG9zIHRva2VucyBwdWVkZW4gc2VyIHBhbGFicmFzLCBjYXJhY3RlcmVzIG8gc3VicGFsYWJyYXMuIFBvciBsbyB0YW50bywgbGEgdG9rZW5pemFjacOzbiBzZSBwdWVkZSBjbGFzaWZpY2FyIGFtcGxpYW1lbnRlIGVuIDMgdGlwb3M6IHRva2VuaXphY2nDs24gZGUgcGFsYWJyYSwgY2Fyw6FjdGVyIHkgc3VicGFsYWJyYSAoY2FyYWN0ZXJlcyBuLWdyYW1hKS4gDQoNClV0aWxpemFyZW1vcyBgc3RyaW5nYCB5IGBzdHJpbmdyYCBwYXJhIGxhIG1hbmlwdWxhY2nDs24gZGUgY2FyYWN0ZXJlcywgYGRwbHlyYCBwYXJhIGxhIG1hbmlwdWxhY2nDs24gZGVsIGRhdGEgZnJhbWUsIGBtYWdyaXR0cmAgcGFyYSBlbCB1c28gZGUgKnBpcGVzKiB5IGB0aWR5dGV4dGAgcGFyYSBlbCB0b2tlbml6YWRvIHkgZWwgYW7DoWxpc2lzIGRlIHRleHRvLiANCg0KYGBge3IgZXZhbCA9IEZ9DQpsaWJyYXJ5KHN0cmluZ2kpDQpsaWJyYXJ5KHN0cmluZ3IpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShtYWdyaXR0cikNCmxpYnJhcnkodGlkeXRleHQpDQoNCiMgUXVpdGFtb3MgbG9zIGFjZW50b3MgYSBsb3MgdHdlZXRzLg0KDQpjYXN0aWxsb3ZhciR0ZXh0IDwtIHN0cmlfdHJhbnNfZ2VuZXJhbChjYXN0aWxsb3ZhciR0ZXh0LCAiTGF0aW4tQVNDSUkiKQ0KDQojIExpbXBpYW1vcyBsYSB2YXJpYWJsZSB0ZXh0IGRlIGFsZ3Vub3MgZWxlbWVudG9zIGlubmVjZXNhcmlvcyB5ICB0b2tlbml6YW1vcy4NCg0KcmVwbGFjZV9yZWcgPC0gImh0dHBzOi8vdC5jby9bQS1aYS16XFxkXSt8aHR0cDovL1tBLVphLXpcXGRdK3wmYW1wO3wmbHQ7fCZndDt8UlR8aHR0cHMiDQp1bm5lc3RfcmVnIDwtICIoW15BLVphLXpfXFxkI0AnXXwnKD8hW0EtWmEtel9cXGQjQF0pKSINCmNhc3RpbGxvdmFyX3QgPC0gY2FzdGlsbG92YXIgJT4lIA0KICBmaWx0ZXIoIXN0cl9kZXRlY3QodGV4dCwgIl5SVCIpKSAlPiUNCiAgbXV0YXRlKHRleHQgPSBzdHJfcmVwbGFjZV9hbGwodGV4dCwgcmVwbGFjZV9yZWcsICIiKSkgJT4lDQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCwgdG9rZW4gPSAicmVnZXgiLCBwYXR0ZXJuID0gdW5uZXN0X3JlZykgICMgVG9rZW5pemFkbw0Kcm0ocmVwbGFjZV9yZWcsIHVubmVzdF9yZWcpIA0KYGBgDQoNCg0KRWwgcmVzdWx0YWRvIGVzIERhdGFGcmFtZSBtw6FzIGdyYW5kZSwgZGUgNDI3NTEgb2JzZXJ2YWNpb25lcywgRG9uZGUgc2UgcmVlbXBsYXphIGxhIGNvbHVtbmEgKHZhcmlhYmxlKSAqdGV4dCogcG9yICp3b3JkKiwgbWFudGVuaWVuZG8gbGEgdmFyaWFibGUgKlgqIGNvbW8gSUQ6DQoNCmBgYHtyfQ0Kc3RyKGNhc3RpbGxvdmFyX3QpDQpgYGANCg0KRWwgc2lndWllbnRlIHByb2JsZW1hIGVzIHF1ZSBsYXMgcGFsYWJyYXMgY29uIG1heW9yIGZyZWN1ZW5jaWEgc29uLCBjb21vIGVyYSBkZSBlc3BlcmFyc2UsIGFydMOtY3Vsb3MsIHByZXBvc2ljaW9uZXMsIGNvbmp1bmNpb25lcywgeSBvdHJvcyBzaW1pbGFyZXM6DQoNCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpmcmVxMSA8LSBjYXN0aWxsb3Zhcl90ICU+JQ0KICAgICAgICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkNCmhlYWQoZnJlcTEsIG4gPSAzMCkgJT4lDQogICAgICAgIGdncGxvdChhZXMocmVvcmRlcih3b3JkLCBuKSwgbikpICsNCiAgICAgICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBmaWxsPSIjMWEzYTU2IikgKw0KICAgICAgICBjb29yZF9mbGlwKCkgKyANCiAgICAgICAgeGxhYigiUGFsYWJyYXMgbcOhcyB1c2FkYXMiKSArDQogICAgICAgIHlsYWIoIk7Dum1lcm8iKSArDQogICAgICAgIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCkVzYXMgcGFsYWJyYXMgbm8gYWdyZWdhbiBuaW5ndW5hIGluZm9ybWFjacOzbiByZWxldmFudGUgcGFyYSBlbnRlbmRlciBsYSBwb2xhcmlkYWQgZGUgbG9zICpzZW50aW1lbnRzKiwgc29uICJwYWxhYnJhcyB2YWPDrWFzIiBxdWUgZGViZW1vcyBmaWx0cmFyLiBQYXJhIGVsbG8gbmVjZXNpdGFtb3MgdW5hIGxpc3RhIGRlIGVzZSB0aXBvIGRlIHBhbGFicmFzIGVuIGVzcGHDsW9sIHF1ZSBleHRyYWVyZW1vcyBkZWwgcGFxdWV0ZSBgc3RvcHdvcmRzYDoNCg0KYGBge3IgbWVzc2FnZT1GQUxTRX0NCmxpYnJhcnkoc3RvcHdvcmRzKQ0KDQojY3JlYXIgdW5hIGxpc3RhIGRlIHBhbGFicmFzIHZhY2lhcyBlbiBlc3Bhw7FvbA0Kc3RvcHdvcmRzX0VTIDwtIHRpYmJsZShzdG9wd29yZHMoInNwYW5pc2giKSkgDQpjb2xuYW1lcyhzdG9wd29yZHNfRVMpIDwtICJ3b3JkIg0KDQojQWdyZWdhbW9zIGFsZ3VuYXMgcGFsYWJyYXMgdmFjaWFzIGFkaWNpb25hbGVzIChsdWdhcmVzIHkgbW9uZWRhcywgZXRjLikNCmN1c3RvbV9zdG9wIDwtIHRpYmJsZSh3b3JkID0gYygibGltYSIsICJjYWphbWFyY2EiLCAicGVydSIsICIwMDAxZjEzNCIsIjAwMDFmNTM0IiwgImRvbGFyIiwgInNvbCIsICJkZXJlY2hhIiwgInUiLCAiQHBlZHJvY2FzdGlsbG90ZSIsICJwcmltZXJvIiwgIjAwMDFmMWVhIiwgIjAwMDFmMWY1IiwgIm1hcyIsICJwcmVzaWRlbnRlIiwiaG95IiwgImZlMGYiLCAiI3NpZW1wcmVjb25lbHB1ZWJsbyIsIiNwYWxhYnJhZGVtYWVzdHJvIikpDQpzdG9wd29yZHNfRVMgPC0gYmluZF9yb3dzKGN1c3RvbV9zdG9wLCBzdG9wd29yZHNfRVMpDQpybShjdXN0b21fc3RvcCkNCg0KI2ZpbHRyYWRvIGNvbiBsYSBsaXN0YSBkZSBwYWxhYnJhcyB2YWNpYXMNCmNhc3RpbGxvdmFyX3RmIDwtIGNhc3RpbGxvdmFyX3QgJT4lIA0KIGZpbHRlcighd29yZCAlaW4lIHN0b3B3b3Jkc19FUyR3b3JkLA0KICAgICAgICAgc3RyX2RldGVjdCh3b3JkLCAiW2Etel0iKSkNCnN0cihjYXN0aWxsb3Zhcl90ZikNCmBgYA0KDQpBaG9yYSBzw60gcG9kZW1vcyBvYnNlcnZhciBsYXMgcGFsYWJyYXMgbcOhcyB1dGlsaXphZGFzIHBvciBQZWRybyBDYXN0aWxsbyAoQFBlZHJvQ2FzdGlsbG9UZSk6DQoNCmBgYHtyfQ0KZnJlcTIgPC0gY2FzdGlsbG92YXJfdGYgJT4lDQogICAgICAgIGNvdW50KHdvcmQsIHNvcnQgPSBUUlVFKQ0KaGVhZChmcmVxMiwgbiA9IDMwKSAlPiUNCiAgICAgICAgZ2dwbG90KGFlcyhyZW9yZGVyKHdvcmQsIG4pLCBuKSkgKw0KICAgICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGZpbGw9IiMxYTNhNTYiKSArDQogICAgICAgIGNvb3JkX2ZsaXAoKSArDQogICAgICAgIHhsYWIoIlBhbGFicmFzIG3DoXMgdXNhZGFzIikgKw0KICAgICAgICB5bGFiKCJOw7ptZXJvIikrDQogICAgICAgIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCiMjIEFuw6FsaXNpcyBkZSBkYXRvcw0KDQpFbCBhbsOhbGlzaXMgZGUgc2VudGltaWVudG8gbm9zIHBlcm1pdGUgYXByb3hpbWFybm9zIGEgbGEgaW50ZW5jacOzbiBlbW9jaW9uYWwgZGUgbG9zIHR3ZWV0cyBxdWUgbGFuemEgZWwgcHJlc2lkZW50ZSBQZWRybyBDYXN0aWxsby4gRXN0ZSB0aXBvIGRlIGFuw6FsaXNpcyBwdWVkZSBiYXNhcnNlIGVuIGVsIGFuw6FsaXNpcyBkZSBwYWxhYnJhcyBvIHJlbGFjaW9uZXMgZGUgcGFsYWJyYXMgKG4tZ3JhbWFzKSB5IHNlIHB1ZWRlbiBldmFsdWFyIGRpZmVyZW50ZXMgZXNjYWxhcyBkZSBzZW50aW1pZW50byAoYmluYXJpYXMsIHBvbmRlcmFkYXMsIGV0Yy4pLg0KDQpFbGVnaW1vcyBlbCBlbmZvcXVlIGRlICJib2xzYSBkZSBwYWxhYnJhcyIsIGVsIG5pdmVsIGRlbCB1bmlncmFtYSB5IGxhIGVzY2FsYSBiaW5hcmlhLCBjb21vIHVuYSBwcmltZXJhIGFwcm94aW1hY2nDs24gZXhwZWRpdGEuIEFob3JhIGJpZW4sIGV4aXN0ZW4gZGl2ZXJzb3MgbcOpdG9kb3MgcGFyYSBldmFsdWFyIGxvcyAqc2VudGltZW50cyogZW4gbG9zIHRleHRvcywgZGVzZGUgbGEgYW5vdGFjacOzbiBtYW51YWwgaGFzdGEgZWwgdXNvIGRlICptYWNoaW5lIGxlYXJuaW5nKiwgcGVybyBhcXXDrSB1dGlsaXphcmVtb3MgZWwgbcOpdG9kbyBiYXNhZG8gZW4gZGljY2lvbmFyaW8gKFNpbGdlIHkgUm9iaW5zb24gMjAxNykuIA0KDQpFc3RlIG3DqXRvZG8gY29uc3RlIGVuIHV0aWxpemFyIHVuIGRpY2Npb25hcmlvIGVuIGZvcm1hdG8gKmNsYXZlOnZhbG9yKiBwYXJhIGV2YWx1YXIgY2FkYSBwYWxhYnJhLiBTZSBjb25zaWRlcmEgYWwgdHdlZXQgY29tbyB1bmEgY29tYmluYWNpw7NuIGRlIHBhbGFicmFzIGluZGl2aWR1YWxlcyBxdWUgdGllbmVuIHVuYSBjYXJnYSBlbW9jaW9uYWwgeSBsYSBwcm9wb3JjacOzbiBkZSBlc2FzIHBhbGFicmFzIG5vcyBkYSBlbCBzZW50aW1pZW50byBnZW5lcmFsIGRlbCB0d2VldCwgY29tbyBwb3N0ZXJpb3JtZW50ZSByZWZsZWphcmVtb3MgZW4gdW4gaW5kaWNlIGRlIHNlbnRpbWllbnRvLiAgDQoNCkxvcyBkaWNjaW9uYXJpb3MgcGFyYSBhbsOhbGlzaXMgZGUgc2VudGltaWVudG8gZW4gZXNwYcOxb2wgc29uIGVzY2Fzb3MgeSBwb2NvIGRlc2Fycm9sbGFkb3MuIERlc3B1w6lzIGRlIHVuYSBsYXJnYSBiw7pzcXVlZGEgcHVkaW1vcyBlbmNvbnRyYXIgZWwgZGljY2lvbmFyaW8gW2lTb2xdKGh0dHA6Ly90aW1tLnVqYWVuLmVzL3JlY3Vyc29zL2lzb2wvKSBxdWUgZXN0w6EgZm9ybWFkbyBwb3IgODEzNSBwYWxhYnJhcywgMi41MDkgcG9zaXRpdmFzIHkgNS42MjYgbmVnYXRpdmFzLCBkZWphbmRvIGEgdW4gbGFkbyBsYXMgcGFsYWJyYXMgZW1vY2lvbmFsbWVudGUgbmV1dHJhcy4gRXN0ZSBkaWNjaW9uYXJpbyBhIHN1IHZleiBlc3TDoSBiYXNhZG8gZW4gb3RybyBkaWNjaW9uYXJpbyBlbiBpbmdsw6lzIGJhc3RhbnRlIHRlc3RlYWRvIGNvbW8gZXMgZWwgZGUgW0JpbmcgTGl1XShodHRwczovL3d3dy5jcy51aWMuZWR1L35saXViL0ZCUy9zZW50aW1lbnQtYW5hbHlzaXMuaHRtbCksIHNpZW5kbyB1bmEgdHJhZHVjY2nDs24gZXNwZWNpYWxpemFkYSB5IG1lam9yYWRhLiAgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0V9DQojY2FyZ2Ftb3MgeSBhZGVjdWFtb3MgZWwgZGljY2lvbmFyaW8gYWwgZm9ybWF0byByZXF1ZXJpZG8uDQpuZWdhdGl2YXMgPC0gcmVhZF9jc3YoImlzb2wvbmVnYXRpdmFzX21lam9yYWRhLmNzdiIsIGNvbF9uYW1lcyA9ICJ3b3JkIikgJT4lDQogIG11dGF0ZShzZW50aW1lbnQgPSAibmVnYXRpdm8iKSANCnBvc2l0aXZhcyA8LSByZWFkX2NzdigiaXNvbC9wb3NpdGl2YXNfbWVqb3JhZGEuY3N2IiwgY29sX25hbWVzID0gIndvcmQiKSAlPiUNCiAgbXV0YXRlKHNlbnRpbWVudCA9ICJwb3NpdGl2byIpDQpiaW5nRVMgPC0gYmluZF9yb3dzKG5lZ2F0aXZhcywgcG9zaXRpdmFzKSANCnJtKG5lZ2F0aXZhcywgcG9zaXRpdmFzKQ0KDQojIFF1aXRhbW9zIGxvcyBhY2VudG9zLg0KYmluZ0VTJHdvcmQgPC0gc3RyaV90cmFuc19nZW5lcmFsKGJpbmdFUyR3b3JkLCAiTGF0aW4tQVNDSUkiKSANCmJpbmdFUw0KYGBgDQoNClVuYSBwcmltZXJhIHBydWViYSBkZWwgZGljY2lvbmFyaW8gcXVlIHJlYWxpemFyZW1vcyBzZXLDoSBjb21wcm9iYXIgcXXDqSBwb3JjZW50YWplIGRlIGxhcyBwYWxhYnJhcyDDum5pY2FzIHV0aWxpemFkYXMgcG9yIEBQZWRyb0Nhc3RpbGxvVGUgY2xhc2lmaWNhIGVzdGUgZGljY2lvbmFyaW86DQoNCmBgYHtyfQ0KIyBwYWxhYnJhcyDDum5pY2FzIHVzYWRhcyBwb3IgQFBlZHJvQ2FzdGlsbG9UZQ0KY2FzdGlsbG9fdyA8LSB1bmlxdWUoY2FzdGlsbG92YXJfdGYkd29yZCkgJT4lIHRpYmJsZSgpIA0KY29sbmFtZXMoY2FzdGlsbG9fdykgPC0gIndvcmQiDQpwcmludChwYXN0ZSgiUGFsYWJyYXMgw7puaWNhcyB1c2FkYXMgcG9yIEBQZWRyb0Nhc3RpbGxvVGU6IiwgbGVuZ3RoKGNhc3RpbGxvX3ckd29yZCkpKQ0KDQojIHBhbGFicmFzIGVuIGVsIGRpY2Npb25hcmlvDQpkaWNfdyA8LSBiaW5nRVMkd29yZCANCnByaW50KHBhc3RlKCJQYWxhYnJhcyBlbiBlbCBkaWNjaW9uYXJpbzoiLCBsZW5ndGgoZGljX3cpKSkNCg0KIyBwYWxhYnJhcyBjbGFzaWZpY2FkYXMNCmNhc3RpbGxvX3djIDwtIGNhc3RpbGxvX3cgJT4lIGZpbHRlcih3b3JkICVpbiUgZGljX3cpIA0KcHJpbnQocGFzdGUoIlBhbGFicmFzIGNsYXNpZmljYWRhczoiLCBsZW5ndGgoY2FzdGlsbG9fd2Mkd29yZCkpKQ0KDQojIHBhbGFicmFzIG5vIGNsYXNpZmljYWRhcw0KY2FzdGlsbG9fdWMgPC0gY2FzdGlsbG9fdyAlPiUgZmlsdGVyKCF3b3JkICVpbiUgZGljX3cpIA0KcHJpbnQocGFzdGUoIlBhbGFicmFzIG5vIGNsYXNpZmljYWRhczoiLCBsZW5ndGgoY2FzdGlsbG9fdWMkd29yZCkpKQ0KDQojIFBvcmNlbnRhamUgZGUgcGFsYWJyYXMgY2xhc2lmaWNhZGFhcw0KcG9yX3cgPC0gKGxlbmd0aChjYXN0aWxsb193YyR3b3JkKSAvIGxlbmd0aChjYXN0aWxsb193JHdvcmQpKSAqIDEwMA0KcHJpbnQocGFzdGUoIlBvcmNlbnRhamUgZGUgcGFsYWJyYXMgY2xhc2lmaWNhZGFhczoiLCBwb3JfdywgIiUiKSkNCg0KYGBgDQoNClBhbGFicmFzIG5vIGNsYXNpZmljYWRhcw0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFfQ0KY2FzdGlsbG9fdWMgDQpgYGANCg0KDQpFbCBkaWNjaW9uYXJpbyBjbGFzaWZpY8OzIGVsIDEwLjkxJSBkZSBsYXMgcGFsYWJyYXMuIExvIGlkZWFsIGVzIHF1ZSBlbCBkaWNjaW9uYXJpbyBzZSBhcHJveGltZSBhbCAyMCUgZGUgbGFzIHBhbGFicmFzIHNpZ3VpZW5kbyBsYSBsZXkgZGUgWmlwZiwgcG9yIGxvIHF1ZSBlZmVjdHVhcmVtb3MgdW5hcyBtb2RpZmljYWNpb25lcy4gIA0KDQpBbCByZXZpc2FyIGVsIGRpY2Npb25hcmlvIGVuY29udHJhbW9zIHRyZXMgcHJvYmxlbWFzOg0KDQoqIFByaW1lcm8sIHNpIGJpZW4gY29udGllbmUgbXVjaGFzIHBhbGFicmFzIGNvbiBjbGFyYSBjYXJnYSBzZW50aW1lbnRhbCwgZW4gb2Nhc2lvbmVzIG5vIGNvbnRpZW5lIHRvZGFzIHN1cyBmbGV4aW9uZXMuDQoqIFNlZ3VuZG8sIGRhZG8gcXVlIGVzIHVuIGRpY2Npb25hcmlvIGdlbmVyYWwsIG5vIGNhcHR1cmEgYWxndW5hcyBwYXJ0aWN1bGFyaWRhZGVzIGRlbCBkaXNjdXJzbyBwb2zDrXRpY28gZGVsIHByZXNpZGVudGUsIHBhcnRpY3VsYXJtZW50ZSBzdSBkaXNjdXJzbyBuYWNpb25hbGlzdGEuIA0KKiBUZXJjZXJvLCBleGlzdGVuIHBhbGFicmFzIHBvbGFyaXphZGFzIHF1ZSBzaXJ2ZW4gcGFyYSBpbmRpY2FyIGVsIHNlbnRpbWllbnRvIGZyZW50ZSBhIHVuIHByb2R1Y3RvIG8gc2VydmljaW8sIHBlcm8gbm8gdGllbmVuIGVmZWN0aXZpZGFkIGVuIHRlbWFzIHBvbMOtdGljb3MuIA0KDQpQYXJhIGVsIHByaW1lciBwcm9ibGVtYSBhw7FhZGlyZW1vcyBmbGV4aW9uZXMgYmFzYWRhcyB5YSBlbiBsYXMgcGFsYWJyYXMgZXhpc3RlbnRlcyBlbiBlbCBkaWNjaW9uYXJpbywgcGFyYSBlbCBzZWd1bmRvIGHDsWFkaXJlbW9zIGxhcyBwYWxhYnJhcyBwb2xpdGl6YWRhcyBtw6FzIHV0aWxpemFkYXMsIGV2YWx1YW5kbyBzdSBwb2xhcmlkYWQgZW4gdW4gaW50ZW50byBkZSB1biBkaWNjaW9uYXJpbyBwb2zDrXRpY28gaW5pY2lhbCwgeSBwYXJhIGVsIHRlcmNlcm8gcmV0aXJhcmVtb3MgbGFzIHBhbGFicmFzIG5vIGFwcm9waWFkYXM6DQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0V9DQojIEHDsWFkaWVuZG8gZmxleGlvbmVzIHkgb3RyYXMgcGFsYWJyYXMgcG9sYXJpemFkYXMNCmZsZXhfZGljIDwtIHJlYWRfY3N2KCJDYXN0aWxsb05DLmNzdiIsIGNvbF9uYW1lcyA9IGMoIndvcmQiLCAic2VudGltZW50IikpDQpmbGV4X2RpYyA8LSBmbGV4X2RpYyAlPiUgZmlsdGVyKHN0cl9kZXRlY3Qoc2VudGltZW50LCAicG9zaXRpdm98bmVnYXRpdm8iKSkNCmZsZXhfZGljDQpgYGANCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFfQ0KYmluZ0VTbW9kIDwtIGJpbmRfcm93cyhiaW5nRVMsIGZsZXhfZGljKQ0KYmluZ0VTbW9kIA0KYGBgDQoNCkHDsWFkaWVuZG8gcGFsYWJyYXMgcG9saXRpemFkYXMNCg0KYGBge3IgbWVzc2FnZT1GQUxTRX0NCnRyaWJibGUoDQogIH53b3JkLCB+c2VudGltZW50LA0KICAicHVlYmxvIiwgInBvc2l0aXZvIiwNCiAgImVldXUiLCAibmVnYXRpdm8iLA0KICAiZXN0YWRvdW5pZGVuc2UiLCAibmVnYXRpdm8iLA0KICAiZXN0YWRvdW5pZGVuc2VzIiwgIm5lZ2F0aXZvIiwNCiAgImNoaWxlIiwgIm5lZ2F0aXZvIiwNCiAgImltcGVyaW8iLCAibmVnYXRpdm8iLA0KICAiaW1wZXJpb3MiLCAibmVnYXRpdm8iLA0KICAiaW1wZXJpYWwiLCAibmVnYXRpdm8iLA0KICAiaW1wZXJpYWxlcyIsICJuZWdhdGl2byIsDQogICJpbXBlcmlhbGlzbW8iLCAibmVnYXRpdm8iLA0KICAiY2FwaXRhbGlzbW8iLCAibmVnYXRpdm8iLA0KICAiY2FwaXRhbGlzdGEiLCAibmVnYXRpdm8iLA0KICAicHJvY2FwaXRhbGlzdGEiLCAibmVnYXRpdm8iLA0KICAiY2FwaXRhbGl6YWNpw7NuIiwgIm5lZ2F0aXZvIiwNCiAgIm5lb2xpYmVyYWwiLCAibmVnYXRpdm8iLA0KICAibmVvbGliZXJhbGVzIiwgIm5lZ2F0aXZvIiwNCiAgIm5lb2xpYmVyYWxpc21vIiwgIm5lZ2F0aXZvIiwNCiAgIm5lb2NvbG9uaWFsIiwgIm5lZ2F0aXZvIiwNCiAgIm5lb2NvbG9uaWFsZXMiLCAibmVnYXRpdm8iLA0KICAibmVvY29sb25pYWxpc21vIiwgIm5lZ2F0aXZvIiwNCiAgInJlY29sb25pemFjaW9uIiwgIm5lZ2F0aXZvIiwNCiAgIm9saWdhcnF1aWEiLCAibmVnYXRpdm8iLA0KICAib2xpZ2FycXVpYXMiLCAibmVnYXRpdm8iLA0KICAib2xpZ2FyY2EiLCAibmVnYXRpdm8iLA0KICAib2xpZ2FyY2FzIiwgIm5lZ2F0aXZvIiwNCiAgIm9saWdhcnF1aWNhIiwgIm5lZ2F0aXZvIiwNCiAgIm9saWdhcnF1aWNvcyIsICJuZWdhdGl2byIsDQogICJkZXJlY2hhIiwgIm5lZ2F0aXZvIiwNCiAgImRlcmVjaGlzdGFzIiwgIm5lZ2F0aXZvIiwNCiAgImZtaSIsICJuZWdhdGl2byIsDQogICJ0cnVtcCIsICJuZWdhdGl2byIsDQogICJwYXRyaWEiLCAicG9zaXRpdm8iLA0KICAic29iZXJhbmlhIiwgInBvc2l0aXZvIiwNCiAgInNvYmVyYW5pYXMiLCAicG9zaXRpdm8iLA0KICAic29iZXJhbm8iLCAicG9zaXRpdm8iLA0KICAic29iZXJhbm9zIiwgInBvc2l0aXZvIiwNCiAgInRyYW5zbmFjaW9uYWwiLCAibmVnYXRpdm8iLA0KICAib3Bvc2l0b3IiLCAibmVnYXRpdm8iLA0KICAib3Bvc2l0b3JhIiwgIm5lZ2F0aXZvIiwNCiAgInZhY2Fkb3JhIiwgIm5lZ2F0aXZvIiwNCiAgInVsdHJhZGVyZWNoYSIsICJuZWdhdGl2byIsDQogICJ2YWNhZG9yZXMiLCAibmVnYXRpdm8iLA0KICAibW9ub3BvbGlvIiwgIm5lZ2F0aXZvIiwNCiAgIm9wb3NpdG9yIiwgIm5lZ2F0aXZvIiwNCiAgImdvbHBpc3RhcyIsICJuZWdhdGl2byIsDQogICJtZXJtZWxlcmEiLCAibmVnYXRpdm8iLA0KICAicHJlbnNhIiwgIm5lZ2F0aXZvIiwNCiAgImNvbmdyZXNvIiwgIm5lZ2F0aXZvIiwNCiAgImRpc2NyaW1pbmFjaW9uIiwgIm5lZ2F0aXZvIiwNCiAgImRlc2lndWFsZGFkIiwgIm5lZ2F0aXZvIiwNCiAgImlndWFsZGFkIiwgInBvc2l0aXZvIiwNCiAgImRlc2luZm9ybWFjaW9uZXMiLCAibmVnYXRpdm8iLA0KICAiZGVzZXNwZXJhY2lvbiIsICJuZWdhdGl2byIsDQogICJpbXB1dGFjaW9uZXMiLCAibmVnYXRpdm8iLA0KICAicG9ydGF0aWxlcyIsICJuZWdhdGl2byIsDQogICJwZXJzZWN1Y2lvbiIsICJuZWdhdGl2byIsDQogICJvcG9zaXRvcmVzIiwgIm5lZ2F0aXZvIg0KKSAtPiBwb2xfZGljDQpiaW5nRVNtb2QgPC0gYmluZF9yb3dzKGJpbmdFU21vZCwgcG9sX2RpYykNCg0KI1F1aXRhbmRvIG90cmFzIHBhbGFicmFzIG5vIHBlcnRpbmVudGVzDQpzdXByX2RpYyA8LSBjKCJtZWpvciIsICJtZWpvcmVzIiwgInBlb3IiLCAicGVvcmVzIiwgImVjb25vbWljbyIsICJlY29ub21pY29zIiwgIm51ZXZhIiwgIm51ZXZhcyIsICJudWV2byIsICJudWV2b3MiLCAiZ3JhbmRlIiwgImdyYW5kZXMiLCAiaW1wb3J0YW50ZSIsICJpbXBvcnRhbnRlcyIsICJkZWNpc2lvbiIsICJpbnRlcmVzIiwgImludGVyZXNlcyIsICJtYXlvciIsICJwcmltZXJhIiwgIm1hZHVybyIsICJnYXJhbnRpemFyIiwgImh1bWFubyIsICJodW1hbm9zIiwgIm51ZXZhcyIsICJyZWN1cnNvcyIsICJsaWRlciIsICJsaWRlcmVzIiwgInByb250byIsICJzZXJpYSIsICJjb3J0ZSIsICJwcmltZXJvIiwgInNlZ3VybyIsICJzZWd1cm9zIiwgInByaW5jaXBhbCIsICJwcmluY2lwYWxlcyIsICJzZW50aWRvIikNCmJpbmdFU21vZCA8LSBiaW5nRVNtb2QgICU+JSBmaWx0ZXIoIXdvcmQgJWluJSBzdXByX2RpYykNCmBgYA0KDQpWb2x2ZW1vcyBhIGV2YWx1YXIgZWwgYWxjYW5jZSBkZWwgZGljY2lvbmFyaW8geSBsbGVnYW1vcyBhbCAxMi4yJToNCg0KYGBge3J9DQojIHBhbGFicmFzIGVuIGVsIGRpY2Npb25hcmlvDQpkaWNfdyA8LSBiaW5nRVNtb2Qkd29yZCANCnByaW50KHBhc3RlKCJQYWxhYnJhcyBlbiBlbCBkaWNjaW9uYXJpbzoiLCBsZW5ndGgoZGljX3cpKSkNCg0KIyBwYWxhYnJhcyBjbGFzaWZpY2FkYXMNCmNhc3RpbGxvX3djIDwtIGNhc3RpbGxvX3cgJT4lIGZpbHRlcih3b3JkICVpbiUgZGljX3cpDQpwcmludChwYXN0ZSgiUGFsYWJyYXMgY2xhc2lmaWNhZGFzOiIsIGxlbmd0aChjYXN0aWxsb193YyR3b3JkKSkpDQoNCiMgUG9yY2VudGFqZSBkZSBwYWxhYnJhcyBjbGFzaWZpY2FkYWFzDQpwb3JfdyA8LSAobGVuZ3RoKGNhc3RpbGxvX3djJHdvcmQpIC8gbGVuZ3RoKGNhc3RpbGxvX3ckd29yZCkpICogMTAwDQpwcmludChwYXN0ZSgiUG9yY2VudGFqZSBkZSBwYWxhYnJhcyBjbGFzaWZpY2FkYWFzOiIsIHBvcl93LCAiJSIpKQ0KYGBgDQoNCkdyYWNpYXMgYWwgdG9rZW5pemFkbywgcXVlIG5vcyBkZWpvIHVuYSBlc3RydWN0dXJhIGRlIHVuYSBwYWxhYnJhIHBvciBvYnNlcnZhY2nDs24geSBhbCBkaWNjaW9uYXJpbyBlbiBmb3JtYXRvIGNsYXZlOiB2YWxvciwgZXN0YSBjbGFzaWZpY2FjacOzbiBzb2xvIG5vcyBvY3VwYXLDoSBsYSBmdW5jacOzbiBgaW5uZXJfam9pbmAgcXVlIGZ1c2lvbmEgZG9zIHRhYmxhcyBkZSBkYXRvcyBwb3IgdmFsb3JlcyBjb211bmVzOg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFfQ0KY2FzdGlsbG9zZW50aW1lbnQgPC0gY2FzdGlsbG92YXJfdGYgJT4lDQogIGlubmVyX2pvaW4oYmluZ0VTbW9kKQ0KY2FzdGlsbG9zZW50aW1lbnQNCmBgYA0KDQpBcXXDrSB1biBwcmltZXIgYWNlcmNhbWllbnRvIGFsIGNsaW1hIGVtb2Npb25hbCBkZSBsb3MgdHdlZXRzIGRlbCBwcmVzaWRlbnRlIGNvbnNpc3RlIGVuIHZlciBsb3MgcG9yY2VudGFqZXMgZ2xvYmFsZXMgZGUgcGFsYWJyYXMgcG9zaXRpdmFzIHkgbmVnYXRpdmFzOg0KDQpgYGB7cn0NCmNhc3RpbGxvc2VudGltZW50ICU+JQ0KICAgICAgICBnZ3Bsb3QoYWVzKHNlbnRpbWVudCkpICsNCiAgICAgICAgZ2VvbV9iYXIoYWVzKHkgPSAoLi5jb3VudC4uKS9zdW0oLi5jb3VudC4uKSoxMDApLGZpbGw9IiMxYTNhNTYiKSArDQogICAgICAgIHhsYWIoInNlbnRpbWllbnRvIikgKyANCiAgICAgICAgeWxhYigicG9yY2VudGFqZSIpICsNCiAgICAgICAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KQXByb3hpbWFkYW1lbnRlIHVuIDY4JSBkZSBsYXMgcGFsYWJyYXMgcXVlIGhhIHV0aWxpemFkbyBQZWRybyBDc3RpbGxvIHNvbiBwb3NpdGl2YXMsIG1pZW50cmFzIGVsIDMyJSBzb24gbmVnYXRpdmFzLiANCg0KTGFzIHBhbGFicmFzIHF1ZSBtw6FzIHBlc28gYXBvcnRhbiBhIGxhIHBvc2l0aXZpZGFkIHkgbmVnYXRpdmlkYWQgc29uIGxhcyBzaWd1aWVudGVzOg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFfQ0KY291bnRfc2VudCA8LSBjYXN0aWxsb3NlbnRpbWVudCAlPiUNCiAgY291bnQod29yZCwgc2VudGltZW50LCBzb3J0ID0gVFJVRSkgJT4lDQogIHVuZ3JvdXAoKQ0KY291bnRfc2VudA0KDQojR3JhZmljYW1vcw0KY291bnRfc2VudCAlPiUNCiBncm91cF9ieShzZW50aW1lbnQpICU+JQ0KICB0b3BfbigzMCkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKHdvcmQgPSByZW9yZGVyKHdvcmQsIG4pKSAlPiUNCiAgZ2dwbG90KGFlcyh3b3JkLCBuLCBmaWxsID0gc2VudGltZW50KSkgKw0KICBnZW9tX2NvbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGZhY2V0X3dyYXAofnNlbnRpbWVudCwgc2NhbGVzID0gImZyZWVfeSIpICsNCiAgbGFicyh5ID0gIkNvbnRyaWJ1Y2nDs24gYWwgc2VudGltaWVudG8iLA0KICAgICAgIHggPSBOVUxMKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCkFob3JhIGNyZWFyZW1vcyB1biBpbmRpY2UgZGUgc2VudGltaWVudG8gKCppc2VudCopIHBhcmEgcG9uZGVyYXIgbGEgY2FyZ2EgZGUgcG9zaXRpdmlkYWQgbyBuZWdhdGl2aWRhZCBlbiBjYWRhIHR3ZWV0LiBQYXJhIGVsbG86ICAkaXNlbnQodCkgPSBzIC8gbnckICBkb25kZSBlbCBpbmRpY2UgZGUgc2VudGltaWVudG8gcGFyYSB1biB0d2VldCBzZXJhIGxhIHByb3BvcmNpw7NuIGVudHJlIGVsIG51bWVybyBkZSBwYWxhYnJhcyBjb24gY2FyZ2EgZW1vY2lvbmFsICRzJCBkaXZpZGlkbyBlbnRyZSBlbCB0b3RhbCBkZSBwYWxhYnJhcyAkbnckLCBleGNsdXllbmRvIGxhcyBwYWxhYnJhcyB2YWPDrWFzLiBDcmVhcmVtb3MgdW4gw61uZGljZSBwYXJhIGNhZGEgcG9sYXJpZGFkOg0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0V9DQojQ29udGFtb3MgZWwgdG90YWwgZGUgcGFsYWJyYXMgbmVnYXRpdmFzIHkgcG9zaXRpdmFzIHBvciB0d2VldHMNCmxpYnJhcnkodGlkeXIpDQp0d2VldHNfc2VuIDwtIGNhc3RpbGxvc2VudGltZW50ICU+JQ0KICBncm91cF9ieShYKSAlPiUNCiAgY291bnQoc2VudGltZW50KQ0KY2FzdGlsbG92YXJfc2VudCA8LSBpbm5lcl9qb2luKGNhc3RpbGxvdmFyLCB0d2VldHNfc2VuKQ0KY2FzdGlsbG92YXJfc2VudCA8LSBzcHJlYWQoY2FzdGlsbG92YXJfc2VudCwgc2VudGltZW50LCBuKQ0KY2FzdGlsbG92YXJfc2VudFtpcy5uYShjYXN0aWxsb3Zhcl9zZW50KV0gPC0gMA0KYGBgDQoNCg0KYGBge3IgbWVzc2FnZT1GQUxTRX0NCiNMaW1waWFtb3MgZGUgbGFzIHBhbGFicmFzIHZhY2lhcyB5IGxhcyBVUkwgZGUgbGEgdmFyaWFibGUgdGV4dG8geSBsYSBhw7FhZGltb3MgYSBudWVzdHJhIHRhYmxhIGRlIGRhdG9zDQpsaWJyYXJ5KHRtKQ0KY2FzdGlsbG9fY29ycHVzIDwtIChDb3JwdXMoVmVjdG9yU291cmNlKGNhc3RpbGxvdmFyX3NlbnQkdGV4dCkpKQ0KDQpjb3JwdXMgPC0gdG1fbWFwKGNhc3RpbGxvX2NvcnB1cywgcmVtb3ZlV29yZHMsIHN0b3B3b3Jkcygic3BhbmlzaCIpKQ0KDQpyZW1vdmVVUkwgPC0gZnVuY3Rpb24oeCkgZ3N1YigiaHR0cFtbOmFsbnVtOl1bOnB1bmN0Ol1dKiIsICIiLCB4KSANCg0KY29ycHVzIDwtIHRtX21hcChjb3JwdXMsIGNvbnRlbnRfdHJhbnNmb3JtZXIocmVtb3ZlVVJMKSkNCg0KdGV4dF9jIDwtIGRhdGEuZnJhbWUodGV4dD1zYXBwbHkoY29ycHVzLCBpZGVudGl0eSksIA0KICAgIHN0cmluZ3NBc0ZhY3RvcnM9RikNCmNhc3RpbGxvdmFyX3NlbnQgPC0gYmluZF9jb2xzKGNhc3RpbGxvdmFyX3NlbnQsIHRleHRfYykNCmBgYA0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0V9DQojQ29udGFtb3MgbGFzIHBhbGFicmFzIGRlIGNhZGEgdHdlZXQgeSBjYWxjdWxhbW9zIGxvcyBpbmRpY2VzDQpjYXN0aWxsb3Zhcl9zZW50IDwtIG11dGF0ZShjYXN0aWxsb3Zhcl9zZW50LCBudyA9IHN0cl9jb3VudChjYXN0aWxsb3Zhcl9zZW50JHRleHQuLi4zLCAiXFxTKyIpKQ0KY2FzdGlsbG92YXJfc2VudCA8LSBtdXRhdGUoY2FzdGlsbG92YXJfc2VudCwgaXNlbnRfbmVnID0gIChuZWdhdGl2byAvIG53KSoxMDApDQpjYXN0aWxsb3Zhcl9zZW50IDwtIG11dGF0ZShjYXN0aWxsb3Zhcl9zZW50LCBpc2VudF9wb3MgPSAgKHBvc2l0aXZvIC8gbncpKjEwMCkNCmNhc3RpbGxvdmFyX3NlbnQgDQpgYGAgDQoNCkFob3JhIGNyZWFyZW1vcyB1bmEgdmFyaWFibGUgbnVldmEgbGxhbWFkYSAqaW50ZXJhY3QqIHF1ZSBlcyBzaW1wbGVtZW50ZSBsYSBzdW1hIGRlIGRlIGxvcyBmYXZvcml0b3NzIHkgcmV0d2VldHMuIEVsbG8gc2UganVzdGlmaWNhIHBvcnF1ZSBleGlzdGUgdW5hIGZ1ZXJ0ZSBjb3JyZWxhY2nDs24gZW50cmUgZXNvcyBkb3MgdGlwb3MgZGUgaW50ZXJhY2Npw7NuLiANCg0KYGBge3J9DQojQ29ycmVsYWNpw7NuIGVudHJlIGxvcyBmYXZzIHkgbG9zIHJldHdlZXRzDQpjb3IoY2FzdGlsbG92YXJfc2VudCRmYXZvcml0ZV9jb3VudCwgY2FzdGlsbG92YXJfc2VudCRyZXR3ZWV0X2NvdW50KQ0KYGBgDQpgYGB7cn0NCiNDcmVhbW9zIHVuYSBudWV2YSB2YXJpYWJsZSBxdWUgZXMgbGEgaW50ZXJhY2Npw7NuDQpjYXN0aWxsb3Zhcl9zZW50JGludGVyYWN0IDwtIGNhc3RpbGxvdmFyX3NlbnQkZmF2b3JpdGVfY291bnQgKyBjYXN0aWxsb3Zhcl9zZW50JHJldHdlZXRfY291bnQNCmNhc3RpbGxvdmFyX3NlbnQNCmBgYA0KDQoNClBvciB1bHRpbW8gZ3JhZmljYXJlbW9zIHkgY2FsY3VsYXJlbW9zIGxhIHJlbGFjacOzbiBlbnRyZSBlbCBpbmRpY2UgZGUgc2VudGltaWVudG8geSBsYSBpbnRlcmFjY2nDs246DQoNCmBgYHtyfQ0KY2FzdGlsbG92YXJfc2VudCAlPiUgDQogIGdncGxvdCgpICsNCiAgYWVzKHggPSBpc2VudF9wb3MsIHkgPSBpbnRlcmFjdCkgKw0KICBnZW9tX3BvaW50KCkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCmNvcihjYXN0aWxsb3Zhcl9zZW50JGlzZW50X3BvcywgY2FzdGlsbG92YXJfc2VudCRpbnRlcmFjdCkgI2NvcnJlbGFjacOzbg0KYGBgDQoNCmBgYHtyfQ0KcmVncG9zIDwtIGxtKGludGVyYWN0IH4gaXNlbnRfcG9zLCBjYXN0aWxsb3Zhcl9zZW50KSAjcmVncmVzaW9uIGxpbmVhbA0Kc3VtbWFyeShyZWdwb3MpDQpgYGANCg0KDQoNCmBgYHtyfQ0KY2FzdGlsbG92YXJfc2VudCAlPiUgDQogIGdncGxvdCgpICsNCiAgYWVzKHggPSBpc2VudF9uZWcsIHkgPSBpbnRlcmFjdCkgKw0KICBnZW9tX3BvaW50KCkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoNCmBgYHtyfQ0KY29yKGNhc3RpbGxvdmFyX3NlbnQkaXNlbnRfbmVnLCBjYXN0aWxsb3Zhcl9zZW50JGludGVyYWN0KSNjb3JyZWxhY2nDs24NCg0KDQpgYGANCg0KDQoNCmBgYHtyfQ0KcmVnbmVnIDwtIGxtKGludGVyYWN0IH4gaXNlbnRfbmVnLCBjYXN0aWxsb3Zhcl9zZW50KSAjcmVncmVzaW9uIGxpbmVhbA0Kc3VtbWFyeShyZWduZWcpDQoNCmBgYA0KDQoNCg0KIyMgQ29uY2x1c2nDs24NCg0KTGEgcG9sYXJpZGFkIGdlbmVyYWwgZGUgbG9zIHR3ZWV0cyBkZSBsYSBjdWVudGEgZGUgUGVkcm8gQ2FzdGlsbG8gYXB1bnRhIGEgdW4gbWF5b3IgdXNvIGRlIHBhbGFicmFzIHBvc2l0aXZhcyAoNjglKSBxdWUgbmVnYXRpdmFzICgzMiUpLiANCkVuIGxhIHJlbGFjacOzbiBlbnRyZSBsYSBwb2xhcmlkYWQgZGUgbG9zIHR3ZWV0cyB5IGxhIGludGVyYWNjacOzbiwgcG9kZW1vcyBlbmNvbnRyYXIgdW5hIGRpZmVyZW5jaWEgZW50cmUgbGEgcmVjZXBjacOzbiBkZSBsb3MgdHdlZXRzIHBvc2l0aXZvcyB5IGxvcyBuZWdhdGl2b3MuIExvcyB0d2VldHMgcG9zaXRpdm9zIHRpZW5lbiB1bmEgbWF5b3IgaW50ZXJhY2Npw7NuIHF1ZSBsb3MgbmVnYXRpdm9zLCBlbiBsYSBwcnVlYmEgZGUgY29ycmVsYWNpw7NuIGxvcyB0d2VldHMgcG9zaXRpdm9zIG9idGllbmVuIHVuIDAsMTggbWllbnRyYXMgbG9zIG5lZ2F0aXZvcyB0YW4gc8OzbG8gMCwwMi4gUGFzYW5kbyBhIGxhIHBydWViYSBkZSByZWdyZXNpw7NuLCBsb3MgdHdlZXRzIHBvciBjYWRhIHB1bnRvIHBvcmNlbnR1YWwgcG9zaXRpdm8gcmVjaWJlbiBlbiBwcm9tZWRpbyAxOTkgaW50ZXJhY2Npb25lcyBtw6FzLCBjb24gdW4gcC12YWxvciBzaWduaWZpY2F0aXZvOyBtaWVudHJhcyBxdWUgbG9zIHB1bnRvcyBwb3JjZW50dWFsZXMgbmVnYXRpdm8gbm8gdGllbmUgZWwgbWlzbW8gZWZlY3RvLCBjb25zaWd1aWVuZG8gMjMgaW50ZXJhY2Npb25lcyBtw6FzLCBwZXJvIGNvbiB1biBwLXZhbG9yIG5vIHNpZ25pZmljYXRpdm8uDQoNCkxvIGFudGVyaW9yIHB1ZWRlIGlsdXN0cmFyc2UgY29uIGVsIGFuw6FsaXNpcyBkZSBsb3MgZGlleiB0d2VldHMgY29uIG1heW9yIGludGVyYWNjacOzbjoNCg0KYGBge3J9DQpwb3BfdCA8LSBjYXN0aWxsb3Zhcl9zZW50ICU+JQ0KICAgICAgICBzZWxlY3QodGV4dC4uLjMsIGludGVyYWN0LCBpc2VudF9uZWcsIGlzZW50X3BvcykgJT4lDQogICAgICAgIGFycmFuZ2UoZGVzYyhpbnRlcmFjdCkpDQpoZWFkKHBvcF90LCBuID0gMTApICU+JSBrbml0cjo6a2FibGUoKQ0KYGBgDQoNCkFxdcOtIHNlIHB1ZWRlIGFwcmVjaWFyIHF1ZSBsb3MgMTAgdHdlZXRzIHRpZW5lbiB1bmEgY29uc2lkZXJhYmxlIGNhcmdhIGVtb2Npb25hbCBwb3NpdGl2YSwgbG8gY3VhbCBxdWVkYSByZXByZXNlbnRhbmRvIGVuIHN1cyDDrW5kaWNlcyBkZSBwb3NpdGl2aWRhZC4gU8OzbG8gY3VhdHJvIGRlIGxvcyBkaWV6IHR3ZWV0cyBtw6FzIHBvcHVsYXJlcyBkZSBQZWRybyBDYXN0aWxsbyBzb24gbmVnYXRpdm9zLg0KDQpBIHBlc2FyIGRlIGVzYXMgbGltaXRhY2lvbmVzLCBlc3RlIHByaW1lciBhY2VyY2FtaWVudG8gbm9zIHBlcm1pdGUgbW9zdHJhciBsYSBpbXBvcnRhbmNpYSBkZSBsYSB2YXJpYWJsZSBlbW9jacOzbiBlbiBsb3MgZGlzY3Vyc29zIHBvbMOtdGljb3MgZW4gcmVkIHkgdW4gbcOpdG9kbyBkZSByZWNvbGVjY2nDs24geSBhbsOhbGlzaXMgcGFyYSBncmFuZGVzIGNhbnRpZGFkZXMgZGUgZGF0b3MgdGV4dHVhbGVzIGVuIHJlZGVzIHNvY2lhbGVzLg0KDQo=