R para Cientistas Sociales: Taller Introductorio

💻¡Bienvenidos al Taller introductorio: R para Cientistas Sociales! 💻.

A a lo largo de esta jornada abordaremos el uso de R para las ciencias sociales. No se requiere experiencia previa en programación ni análisis de datos, ya que este taller está diseñado para todxs, desde principiantes hasta aquellos con cierta experiencia.

🤔 ¿Por qué R? R es un lenguaje de programación ampliamente utilizado en la ciencia de datos, estadísticas y análisis de datos. En las ciencias sociales, R puede ser una herramienta invaluable para explorar datos, identificar patrones, y comunicar tus hallazgos de manera efectiva estudies la carrera que estudies.

Podes acceder al repositorio acá. Allí vamos a estar subiendo los archivos y documentos del curso.

➡️ Este taller es organizado por el proyecto de investigación “La trama territorial de programas sociales en el conurbano bonaerense: entre nación, municipios y organizaciones sociales (2015-2023)” radicado en el Departamento de Derecho y Ciencia Política de la Universidad Nacional de La Matanza (UNLaM).

Instalación de R y RStudio

Instalación de R

1️⃣ Para descargar R y Rstudio, debes acceder a la página de intalación de Posit.

2️⃣ Lo primero que debemos hacer es instalar R. Para ello, seleccionaremos el paso 1 que te llevara a la página de CRAN (Comprehensive R Archive Network) que es el repositorio central de software de R. Allí, deberás seleccionar el sistema operativo que utilices.

3️⃣ Luego deberás seleccionar el “install for the first time” (Instalar por primera vez) en la parte superior de la página:

Instalación de R Studio

4️⃣ Una vez que lo descargas, deberás ejecutar el .exe y seguir los pasos de la instalación. La última versión de R es la 9.1.

5️⃣En cuanto hayas descargado R, deberás descargar RStudio que es el IDE que estaremos usando a lo largo del curso.

Para ello vuelve a la página de posit y selecciona el Paso 2.

También podés seleccionar la opción de descarga que mejor se adapte a tu sistema operativo

¡Felicidades! Ahora tienes R y RStudio instalados en tu compu. En caso de tener algún inconveniente no dudes en escribirnos.

📅 Nos vemos el 23 de noviembre a las 17 30 hs en la biblioteca de la UNLaM para continuar con este taller

✨ En esta página estaremos subiendo lo que veremos ese día ✨

¿Con qué trabajamos en R?

  • Scripts: Un script de R es un archivo de texto que contiene código R.

  • Rmarkdown: Un documento Rmd es un archivo de texto que combina texto con código R. Este formato de documento se utiliza para crear informes, presentaciones y otros tipos de documentos que contienen tanto texto como código. Podés aprender más de rmarkdown acá y de Quarto (un tipo de documento parecido y más chevere acá)

➡️ Si apretamos las teclas ALT+CTRL+I podemos introducir un chunk. Es como un mini script, un espacio para procesar código en R. para ejecutar el código hacemos clic en el botón verde

➡️ También podemos correr lineas de código usando CTRL + ENTER

# Esto es un comentario. Para comentar usamos el # o CTRL + ALT + C

Uno puede editar la estructura del documento

Esto es un titulo

Esto es un titulo mas chiquito

Esto es un título mini

Esto es texto normal

Esto es texto en cursiva

Esto es texto en negrita

En R todo es un objetos

R es un lenguaje orientado a objetos, lo que significa que todo en R es un objeto. Incluso los números, las funciones y los datos son objetos (“cosas”) en R.

➡️ Los objetos se crean con <- o el signo

# Creamos un objeto en R

esto_es_un_objeto <- 23
esto_tambien <- "Usamos comillas para el texto para que ningun elemento este suelto"

También podemos crear objetos con muchos objetos llamados vectores

esto_es_un_vector <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17)

R es una calculadora

Podemos hacer operaciones matemáticas con R. Y, podemos operar con los objetos

# suma
1 + 3
## [1] 4
# resta
4-2
## [1] 2
# division
25/5
## [1] 5
# multiplicacion
2*2
## [1] 4
# potencia
2^2
## [1] 4

A su vez, podes operar con tus objetos, vectores, dataframes…

# suma con mi objeto

esto_es_un_objeto + 5
## [1] 28
# Puedo crear un objeto con lo nuevo 
objeto_nuevo <- esto_es_un_objeto + 5

Y usar funciones de R o de librerías para calculos. Las funciones como sum() o mean() son bloques de código reutilizables que realizan tareas específicas. R tiene muchas funciones incorporadas y también podes crear las tuyas propias. Además hay librerías y paquetes que te permiten ampliar este universo de funciones

# Tambien operar con mis vectores

mean(esto_es_un_vector)
## [1] 9
sum(esto_es_un_vector)
## [1] 153

Podemos graficar nuestro vector con la función plot()

plot(esto_es_un_vector)

Levantar data

📂 En R podemos utilizar archivos csv, txt, excel, sav, entre otros. Incluso podes trabajar con googlesheets!

❗Para cada tipo de archivo hay una función diferente. CSV read.csv() , archivos SAV read_spss() , excel readxl::read_excel()

Vamos a trabajar con datos abiertos del Programa Nacional de Inclusión Socioproductiva y Desarrollo Local “Potenciar Trabajo” que fue creado en el año 2020 bajo la Resolución N° 121. Este programa busca es contribuir al mejoramiento de la empleabilidad y la generación de nuevas propuestas productivas. Para ello, se prevé la participación de las y los titulares del programa en al menos una de las tres alternativas:

  • proyectos socio-productivos;

  • terminalidad educativa;

  • proyectos socio-laborales o socio-comunitarios

#Defino url
# url <- ("https://datosabiertos.desarrollosocial.gob.ar/dataset/d45687c0-f2ba-41d9-9989-0ad9799308ae/resource/c5c925e0-7ce0-41e5-b3ff-8ebb51d4be72/download/potenciar-trabajo-titulares-2022-10-01.csv")
# 
# potenciar_trabajo <- read.csv(url)

potenciar_trabajo <- read.csv("potenciar-trabajo-titulares-2022-10-01.csv")

Para descargarlo a nuestro espacio de trabajo usamos la funcion write.csv() para CSV o write.xlsx de la librería openxlsx

# Guardo el csv
write.csv(potenciar_trabajo, "df_potenciar.csv")

para leer el archivo desde nuestra compu:

# Leo el df 
df <- read.csv("df_potenciar.csv")

Pueden encontrar más información sobre importacion y exportacion de archivos aquí o aquí

Analizamos el potenciar trabajo

Primero vamos a ver qué hay en el df del potenciar trabajo

# Primeras 10 observaciones
head(df) 
##   X    periodo    provincia provincia_id           departamento departamento_id
## 1 1 2020-12-01 Buenos Aires            6             25 de Mayo            6854
## 2 2 2020-12-01 Buenos Aires            6             9 de Julio            6588
## 3 3 2020-12-01 Buenos Aires            6          Adolfo Alsina            6007
## 4 4 2020-12-01 Buenos Aires            6 Adolfo Gonzales Chaves            6014
## 5 5 2020-12-01 Buenos Aires            6                Alberti            6021
## 6 6 2020-12-01 Buenos Aires            6        Almirante Brown            6028
##                municipio municipio_id titulares
## 1             25 De Mayo     68540854       379
## 2             9 De Julio     65880588       209
## 3          Adolfo Alsina     60070007       346
## 4 Adolfo Gonzales Chaves     60140014       248
## 5                Alberti     60210021       139
## 6        Almirante Brown     60280028     20469
# Ultimas 10 observaciones
tail(df)
##         X    periodo provincia provincia_id departamento departamento_id
## 4764 4764 2022-12-01   Tucumán           90      Trancas           90112
## 4765 4765 2022-12-01   Tucumán           90      Trancas           90112
## 4766 4766 2022-12-01   Tucumán           90  Yerba Buena           90119
## 4767 4767 2022-12-01   Tucumán           90  Yerba Buena           90119
## 4768 4768 2022-12-01   Tucumán           90  Yerba Buena           90119
## 4769 4769 2022-12-01   Tucumán           90  Yerba Buena           90119
##          municipio municipio_id titulares
## 4764         Tapia    901120104         6
## 4765       Trancas    901120106       536
## 4766 Cevil Redondo    901190019       263
## 4767    San Javier    901190087        29
## 4768 Villa Carmela    901190113        34
## 4769   Yerba Buena    901190112       590

Con el simbolo $ puedo elegir las variables de mi tabla y a cada una de ellas puedo aplicarle una función

max(df$titulares) #máximo de titulares
## [1] 100003
min(df$titulares) #mínimo de minimo de titulares
## [1] 1

Para saber más acerca de una función podes pedirle ayuda a R con:

#?max
#help(max)

Ver un resumen de los datos

str(df)
## 'data.frame':    4769 obs. of  9 variables:
##  $ X              : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ periodo        : chr  "2020-12-01" "2020-12-01" "2020-12-01" "2020-12-01" ...
##  $ provincia      : chr  "Buenos Aires" "Buenos Aires" "Buenos Aires" "Buenos Aires" ...
##  $ provincia_id   : int  6 6 6 6 6 6 6 6 6 6 ...
##  $ departamento   : chr  "25 de Mayo" "9 de Julio" "Adolfo Alsina" "Adolfo Gonzales Chaves" ...
##  $ departamento_id: int  6854 6588 6007 6014 6021 6028 6077 6035 6042 6049 ...
##  $ municipio      : chr  "25 De Mayo" "9 De Julio" "Adolfo Alsina" "Adolfo Gonzales Chaves" ...
##  $ municipio_id   : int  68540854 65880588 60070007 60140014 60210021 60280028 60770077 60350035 60420042 60490049 ...
##  $ titulares      : int  379 209 346 248 139 20469 185 12612 250 478 ...
summary(df)
##        X          periodo           provincia          provincia_id  
##  Min.   :   1   Length:4769        Length:4769        Min.   : 2.00  
##  1st Qu.:1193   Class :character   Class :character   1st Qu.:14.00  
##  Median :2385   Mode  :character   Mode  :character   Median :42.00  
##  Mean   :2385                                         Mean   :46.31  
##  3rd Qu.:3577                                         3rd Qu.:82.00  
##  Max.   :4769                                         Max.   :94.00  
##  departamento       departamento_id  municipio          municipio_id      
##  Length:4769        Min.   : 2001   Length:4769        Min.   :    90014  
##  Class :character   1st Qu.:14154   Class :character   1st Qu.:141540062  
##  Mode  :character   Median :42035   Mode  :character   Median :420350026  
##                     Mean   :46410                      Mean   :463560172  
##                     3rd Qu.:82021                      3rd Qu.:820210255  
##                     Max.   :94014                      Max.   :940140003  
##    titulares       
##  Min.   :     1.0  
##  1st Qu.:     5.0  
##  Median :    28.0  
##  Mean   :   759.1  
##  3rd Qu.:   165.0  
##  Max.   :100003.0

Graficamos

Para graficar usamos ggplot2, es un paquete que se encuentra dentro de Tidyverse.

Tidyverse es un conjunto de paquetes en R diseñados para la ciencia de datos. Estos paquetes comprenden funciones que facilitan el proceso de importación, limpieza, transformación, visualización, modelado y comunicación de datos. Pueden explorarlos mediante la documentación

# install.packages("tidyverse")

library(tidyverse) # Activamos el paquete
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.3     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.3     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Para instalar un paquete usamos install.packages("nombre_del_paquete") y siempre SIEMPRE que necesitamos usarlo hay que llamarlo en nuestra sesión o documento con library(nombre_del_paquete)

Existe una interfaz interactiva que permite dar los primeros pasos en este mundo de la visualización. El paquete esquisse te permite hacer un boceto del gráfico y luego copiar el codigo en tu trabajo a través de la función esquisser

#instalaremos el paquete esquisse

#install.packages("esquisse") #instalamos el paquete, por unica vez

library(esquisse)
## Warning: package 'esquisse' was built under R version 4.3.2
# Otra forma de llamar a las funciones de los paquetes esquisse::esquisser()
#esquisser(df) #corremos la funcion de visualizacion


# Gráfico resultante

ggplot(df) +
  aes(x = periodo, weight = titulares) +
  geom_bar(fill = "#36B08E") +
  labs(
    x = "Cantidad",
    y = "Período",
    title = "Titulares del potenciar trabajo por año",
    subtitle = "Cantidad de titulares (2021-2023)",
    caption = "Fuente: Datos abiertos del MDSN"
  ) +
  theme_classic() +
  theme(
    plot.title = element_text(size = 16L,
    face = "bold",
    hjust = 0.5),
    plot.subtitle = element_text(size = 15L,
    hjust = 0.5)
  )

Presentación

Accedé a la presentación acá

Fuente

LS0tDQp0aXRsZTogJ1IgcGFyYSBDaWVudGlzdGFzIFNvY2lhbGVzOiBUYWxsZXIgSW50cm9kdWN0b3JpbycNCmF1dGhvcjogIkFyaWFuYSBCYXJkYXVpbCINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCmxhbmc6ICJlcyINCm91dHB1dDoNCiAgcm1kZm9ybWF0czo6cm9ib2Jvb2s6DQogICAgbGlnaHRib3g6IFRSVUUNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogICAgdG9jOiAzDQogICAgbnVtYmVyLXNlY3Rpb25zOiBUUlVFDQogICAgY29kZS1mb2xkaW5nOiBzaG93DQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KZWRpdG9yX29wdGlvbnM6IA0KICBtYXJrZG93bjogDQogICAgd3JhcDogNzINCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQrwn5K7KsKhQmllbnZlbmlkb3MgYWwgVGFsbGVyIGludHJvZHVjdG9yaW86IFIgcGFyYSBDaWVudGlzdGFzIFNvY2lhbGVzISoNCvCfkrsuDQoNCkEgYSBsbyBsYXJnbyBkZSBlc3RhIGpvcm5hZGEgYWJvcmRhcmVtb3MgZWwgdXNvIGRlIFIgcGFyYSBsYXMgY2llbmNpYXMNCnNvY2lhbGVzLiAqKk5vIHNlIHJlcXVpZXJlIGV4cGVyaWVuY2lhIHByZXZpYSBlbiBwcm9ncmFtYWNpw7NuIG5pDQphbsOhbGlzaXMgZGUgZGF0b3MsKiogeWEgcXVlIGVzdGUgdGFsbGVyIGVzdMOhIGRpc2XDsWFkbyBwYXJhIHRvZHhzLCBkZXNkZQ0KcHJpbmNpcGlhbnRlcyBoYXN0YSBhcXVlbGxvcyBjb24gY2llcnRhIGV4cGVyaWVuY2lhLg0KDQrwn6SUICoqwr9Qb3IgcXXDqSBSPyoqIFIgZXMgdW4gbGVuZ3VhamUgZGUgcHJvZ3JhbWFjacOzbiBhbXBsaWFtZW50ZQ0KdXRpbGl6YWRvIGVuIGxhIGNpZW5jaWEgZGUgZGF0b3MsIGVzdGFkw61zdGljYXMgeSBhbsOhbGlzaXMgZGUgZGF0b3MuIEVuDQpsYXMgY2llbmNpYXMgc29jaWFsZXMsIFIgcHVlZGUgc2VyIHVuYSBoZXJyYW1pZW50YSBpbnZhbHVhYmxlIHBhcmENCmV4cGxvcmFyIGRhdG9zLCBpZGVudGlmaWNhciBwYXRyb25lcywgeSBjb211bmljYXIgdHVzIGhhbGxhemdvcyBkZQ0KbWFuZXJhIGVmZWN0aXZhIGVzdHVkaWVzIGxhIGNhcnJlcmEgcXVlIGVzdHVkaWVzLg0KDQoqKlBvZGVzIGFjY2VkZXIgYWwgcmVwb3NpdG9yaW8NClthY8OhXShodHRwczovL2dpdGh1Yi5jb20vYXJpaWJhcmQvUi1wYXJhLUNpZW5jaWFzLVNvY2lhbGVzKSoqLiBBbGzDrQ0KdmFtb3MgYSBlc3RhciBzdWJpZW5kbyBsb3MgYXJjaGl2b3MgeSBkb2N1bWVudG9zIGRlbCBjdXJzby4NCg0K4p6h77iPIEVzdGUgdGFsbGVyIGVzIG9yZ2FuaXphZG8gcG9yIGVsIHByb3llY3RvIGRlIGludmVzdGlnYWNpw7NuICoiTGEgdHJhbWENCnRlcnJpdG9yaWFsIGRlIHByb2dyYW1hcyBzb2NpYWxlcyBlbiBlbCBjb251cmJhbm8gYm9uYWVyZW5zZTogZW50cmUNCm5hY2nDs24sIG11bmljaXBpb3MgeSBvcmdhbml6YWNpb25lcyBzb2NpYWxlcyAoMjAxNS0yMDIzKSIgciphZGljYWRvIGVuDQplbCBEZXBhcnRhbWVudG8gZGUgRGVyZWNobyB5IENpZW5jaWEgUG9sw610aWNhIGRlIGxhICoqVW5pdmVyc2lkYWQNCk5hY2lvbmFsIGRlIExhIE1hdGFuemEqKiAoVU5MYU0pLg0KDQoNCiFbXShpbWFnZW5lcy9sb2dvLXVubGFtLnBuZyl7d2lkdGg9IjIxMiIgYWxpZ249InJpZ2h0In0NCg0KIyBJbnN0YWxhY2nDs24gZGUgUiB5IFJTdHVkaW8NCg0KIyMjIyBJbnN0YWxhY2nDs24gZGUgUg0KDQox77iP4oOjIFBhcmEgZGVzY2FyZ2FyIFIgeSBSc3R1ZGlvLCBkZWJlcyBhY2NlZGVyIGEgbGEgcMOhZ2luYSBkZSBpbnRhbGFjacOzbg0KZGUgW1Bvc2l0XShodHRwczovL3Bvc2l0LmNvL2Rvd25sb2FkL3JzdHVkaW8tZGVza3RvcC8pLg0KDQohW10oaW1hZ2VuZXMvMS1pbnN0YWxhY2lvbi5wbmcpDQoNCjLvuI/ig6MgTG8gcHJpbWVybyBxdWUgZGViZW1vcyBoYWNlciBlcyAqKmluc3RhbGFyIFIqKi4gUGFyYSBlbGxvLA0Kc2VsZWNjaW9uYXJlbW9zIGVsICoqcGFzbyAxKiogcXVlIHRlIGxsZXZhcmEgYSBsYSBbcMOhZ2luYSBkZQ0KQ1JBTl0oaHR0cHM6Ly9jcmFuLnJzdHVkaW8uY29tLykgKENvbXByZWhlbnNpdmUgUiBBcmNoaXZlIE5ldHdvcmspIHF1ZQ0KZXMgZWwgKnJlcG9zaXRvcmlvIGNlbnRyYWwgZGUgc29mdHdhcmUgZGUgUiouIEFsbMOtLCBkZWJlcsOhcyBzZWxlY2Npb25hcg0KZWwgKnNpc3RlbWEgb3BlcmF0aXZvIHF1ZSB1dGlsaWNlcyouDQoNCiFbXShpbWFnZW5lcy8xLjMtaW5zdGFsYWNpb24ucG5nKQ0KDQoz77iP4oOjIEx1ZWdvIGRlYmVyw6FzIHNlbGVjY2lvbmFyIGVsICJpbnN0YWxsIGZvciB0aGUgZmlyc3QgdGltZSIgKEluc3RhbGFyDQpwb3IgcHJpbWVyYSB2ZXopIGVuIGxhIHBhcnRlIHN1cGVyaW9yIGRlIGxhIHDDoWdpbmE6DQoNCiFbXShpbWFnZW5lcy8xLjEtaW5zdGFsYWNpb24ucG5nKQ0KDQojIyMjIEluc3RhbGFjacOzbiBkZSBSIFN0dWRpbw0KDQo077iP4oOjIFVuYSB2ZXogcXVlIGxvIGRlc2NhcmdhcywgZGViZXLDoXMgZWplY3V0YXIgZWwgLmV4ZSB5IHNlZ3VpciBsb3MgcGFzb3MNCmRlIGxhIGluc3RhbGFjacOzbi4gTGEgw7psdGltYSB2ZXJzacOzbiBkZSBSIGVzIGxhIDkuMS4NCg0KNe+4j+KDo0VuIGN1YW50byBoYXlhcyBkZXNjYXJnYWRvIFIsIGRlYmVyw6FzIGRlc2NhcmdhciBSU3R1ZGlvIHF1ZSBlcyBlbCBJREUNCnF1ZSBlc3RhcmVtb3MgdXNhbmRvIGEgbG8gbGFyZ28gZGVsIGN1cnNvLg0KDQpQYXJhIGVsbG8gdnVlbHZlIGEgbGEgW3DDoWdpbmEgZGUNCnBvc2l0XShodHRwczovL3Bvc2l0LmNvL2Rvd25sb2FkL3JzdHVkaW8tZGVza3RvcC8pIHkgc2VsZWNjaW9uYSBlbCBQYXNvDQoyLg0KDQohW10oaW1hZ2VuZXMvMS1pbnN0YWxhY2lvbi5wbmcpDQoNClRhbWJpw6luIHBvZMOpcyBzZWxlY2Npb25hciBsYSBvcGNpw7NuIGRlIGRlc2NhcmdhIHF1ZSBtZWpvciBzZSBhZGFwdGUgYSB0dQ0Kc2lzdGVtYSBvcGVyYXRpdm8NCg0KIVtdKGltYWdlbmVzLzEuMi1pbnN0YWxhY2lvbi5wbmcpDQoNCsKhRmVsaWNpZGFkZXMhIEFob3JhIHRpZW5lcyBSIHkgUlN0dWRpbyBpbnN0YWxhZG9zIGVuIHR1IGNvbXB1LiBFbiBjYXNvDQpkZSB0ZW5lciBhbGfDum4gaW5jb252ZW5pZW50ZSBubyBkdWRlcyBlbiBlc2NyaWJpcm5vcy4NCg0K8J+ThSAqKk5vcyB2ZW1vcyBlbCAyMyBkZSBub3ZpZW1icmUgYSBsYXMgMTcgMzAgaHMgZW4gbGEgYmlibGlvdGVjYSBkZSBsYQ0KVU5MYU0gcGFyYSBjb250aW51YXIgY29uIGVzdGUgdGFsbGVyKioNCg0K4pyoIEVuIGVzdGEgcMOhZ2luYSBlc3RhcmVtb3Mgc3ViaWVuZG8gbG8gcXVlIHZlcmVtb3MgZXNlIGTDrWEg4pyoDQoNCiMgwr9Db24gcXXDqSB0cmFiYWphbW9zIGVuIFI/DQoNCi0gICAqKlNjcmlwdHMqKjogVW4gc2NyaXB0IGRlIFIgZXMgdW4gYXJjaGl2byBkZSB0ZXh0byBxdWUgY29udGllbmUNCiAgICBjw7NkaWdvIFIuDQoNCi0gICAqKlJtYXJrZG93bioqOiBVbiBkb2N1bWVudG8gKipSbWQqKiBlcyB1biBhcmNoaXZvIGRlIHRleHRvIHF1ZQ0KICAgIGNvbWJpbmEgdGV4dG8gY29uIGPDs2RpZ28gUi4gRXN0ZSBmb3JtYXRvIGRlIGRvY3VtZW50byBzZSB1dGlsaXphDQogICAgcGFyYSBjcmVhciBpbmZvcm1lcywgcHJlc2VudGFjaW9uZXMgeSBvdHJvcyB0aXBvcyBkZSBkb2N1bWVudG9zIHF1ZQ0KICAgIGNvbnRpZW5lbiB0YW50byB0ZXh0byBjb21vIGPDs2RpZ28uIFBvZMOpcyBhcHJlbmRlciBtw6FzIGRlIHJtYXJrZG93bg0KICAgIFthY8OhXShodHRwczovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbS8pIHkgZGUgUXVhcnRvICh1biB0aXBvIGRlDQogICAgZG9jdW1lbnRvIHBhcmVjaWRvIHkgbcOhcyBjaGV2ZXJlIFthY8OhXShodHRwczovL3F1YXJ0by5vcmcvKSkNCg0K4p6h77iPIFNpIGFwcmV0YW1vcyBsYXMgdGVjbGFzIEFMVCtDVFJMK0kgcG9kZW1vcyBpbnRyb2R1Y2lyIHVuICoqY2h1bmsqKi4NCipFcyBjb21vIHVuIG1pbmkgc2NyaXB0LCogdW4gZXNwYWNpbyBwYXJhIHByb2Nlc2FyIGPDs2RpZ28gZW4gUi4gcGFyYQ0KZWplY3V0YXIgZWwgY8OzZGlnbyBoYWNlbW9zIGNsaWMgZW4gZWwgWyoqYm90w7NuDQp2ZXJkZSoqXXtzdHlsZT0iY29sb3I6Z3JlZW4ifQ0KDQrinqHvuI8gVGFtYmnDqW4gcG9kZW1vcyBjb3JyZXIgbGluZWFzIGRlIGPDs2RpZ28gdXNhbmRvIENUUkwgKyBFTlRFUg0KDQpgYGB7cn0NCiMgRXN0byBlcyB1biBjb21lbnRhcmlvLiBQYXJhIGNvbWVudGFyIHVzYW1vcyBlbCAjIG8gQ1RSTCArIEFMVCArIEMNCg0KDQpgYGANCg0KVW5vIHB1ZWRlIGVkaXRhciBsYSBlc3RydWN0dXJhIGRlbCBkb2N1bWVudG8NCg0KIyMgRXN0byBlcyB1biB0aXR1bG8NCg0KIyMjIEVzdG8gZXMgdW4gdGl0dWxvIG1hcyBjaGlxdWl0bw0KDQojIyMjIEVzdG8gZXMgdW4gdMOtdHVsbyBtaW5pDQoNCkVzdG8gZXMgdGV4dG8gbm9ybWFsDQoNCipFc3RvIGVzIHRleHRvIGVuIGN1cnNpdmEqDQoNCioqRXN0byBlcyB0ZXh0byBlbiBuZWdyaXRhKioNCg0KIyBFbiBSIHRvZG8gZXMgdW4gb2JqZXRvcw0KDQpSIGVzIHVuIGxlbmd1YWplIG9yaWVudGFkbyBhIG9iamV0b3MsIGxvIHF1ZSBzaWduaWZpY2EgcXVlIHRvZG8gZW4gUiBlcw0KdW4gb2JqZXRvLiBJbmNsdXNvIGxvcyBuw7ptZXJvcywgbGFzIGZ1bmNpb25lcyB5IGxvcyBkYXRvcyBzb24gb2JqZXRvcw0KKCJjb3NhcyIpIGVuIFIuDQoNCuKeoe+4jyBMb3Mgb2JqZXRvcyBzZSBjcmVhbiBjb24gKipcPC0qKiBvIGVsIHNpZ25vDQoNCmBgYHtyfQ0KIyBDcmVhbW9zIHVuIG9iamV0byBlbiBSDQoNCmVzdG9fZXNfdW5fb2JqZXRvIDwtIDIzDQplc3RvX3RhbWJpZW4gPC0gIlVzYW1vcyBjb21pbGxhcyBwYXJhIGVsIHRleHRvIHBhcmEgcXVlIG5pbmd1biBlbGVtZW50byBlc3RlIHN1ZWx0byINCmBgYA0KDQpUYW1iacOpbiBwb2RlbW9zIGNyZWFyIG9iamV0b3MgY29uIG11Y2hvcyBvYmpldG9zIGxsYW1hZG9zICoqdmVjdG9yZXMqKg0KDQpgYGB7cn0NCmVzdG9fZXNfdW5fdmVjdG9yIDwtIGMoMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcpDQoNCmBgYA0KDQojIFIgZXMgdW5hIGNhbGN1bGFkb3JhDQoNClBvZGVtb3MgaGFjZXIgb3BlcmFjaW9uZXMgbWF0ZW3DoXRpY2FzIGNvbiBSLiBZLCBwb2RlbW9zIG9wZXJhciBjb24gbG9zDQpvYmpldG9zDQoNCmBgYHtyfQ0KDQojIHN1bWENCjEgKyAzDQoNCiMgcmVzdGENCjQtMg0KDQojIGRpdmlzaW9uDQoyNS81DQoNCiMgbXVsdGlwbGljYWNpb24NCjIqMg0KDQojIHBvdGVuY2lhDQoyXjINCg0KYGBgDQoNCkEgc3UgdmV6LCBwb2RlcyBvcGVyYXIgY29uIHR1cyBvYmpldG9zLCB2ZWN0b3JlcywgZGF0YWZyYW1lcy4uLg0KDQpgYGB7cn0NCiMgc3VtYSBjb24gbWkgb2JqZXRvDQoNCmVzdG9fZXNfdW5fb2JqZXRvICsgNQ0KDQojIFB1ZWRvIGNyZWFyIHVuIG9iamV0byBjb24gbG8gbnVldm8gDQpvYmpldG9fbnVldm8gPC0gZXN0b19lc191bl9vYmpldG8gKyA1DQoNCg0KDQpgYGANCg0KWSB1c2FyIGZ1bmNpb25lcyBkZSBSIG8gZGUgbGlicmVyw61hcyBwYXJhIGNhbGN1bG9zLiBMYXMgKipmdW5jaW9uZXMqKg0KY29tbyBgc3VtKClgIG8gYG1lYW4oKWAgc29uIGJsb3F1ZXMgZGUgY8OzZGlnbyByZXV0aWxpemFibGVzIHF1ZSByZWFsaXphbg0KdGFyZWFzIGVzcGVjw61maWNhcy4gUiB0aWVuZSBtdWNoYXMgZnVuY2lvbmVzIGluY29ycG9yYWRhcyB5IHRhbWJpw6luDQpwb2RlcyBjcmVhciBsYXMgdHV5YXMgcHJvcGlhcy4gKkFkZW3DoXMgaGF5IGxpYnJlcsOtYXMgeSBwYXF1ZXRlcyBxdWUgdGUNCnBlcm1pdGVuIGFtcGxpYXIgZXN0ZSB1bml2ZXJzbyBkZSBmdW5jaW9uZXMqDQoNCmBgYHtyfQ0KDQojIFRhbWJpZW4gb3BlcmFyIGNvbiBtaXMgdmVjdG9yZXMNCg0KbWVhbihlc3RvX2VzX3VuX3ZlY3RvcikNCnN1bShlc3RvX2VzX3VuX3ZlY3RvcikNCmBgYA0KDQpQb2RlbW9zIGdyYWZpY2FyIG51ZXN0cm8gdmVjdG9yIGNvbiBsYSBmdW5jacOzbiBgcGxvdCgpYA0KDQpgYGB7cn0NCnBsb3QoZXN0b19lc191bl92ZWN0b3IpDQpgYGANCg0KIyBMZXZhbnRhciBkYXRhDQoNCvCfk4IgRW4gUiBwb2RlbW9zIHV0aWxpemFyIGFyY2hpdm9zIGNzdiwgdHh0LCBleGNlbCwgc2F2LCBlbnRyZSBvdHJvcy4NCkluY2x1c28gcG9kZXMgdHJhYmFqYXIgY29uDQpbZ29vZ2xlc2hlZXRzIV0oaHR0cHM6Ly9nb29nbGVzaGVldHM0LnRpZHl2ZXJzZS5vcmcvcmVmZXJlbmNlL2luZGV4Lmh0bWwpDQoNCuKdl1BhcmEgY2FkYSB0aXBvIGRlIGFyY2hpdm8gaGF5IHVuYSBmdW5jacOzbiBkaWZlcmVudGUuIENTViBgcmVhZC5jc3YoKWANCiwgYXJjaGl2b3MgU0FWIGByZWFkX3Nwc3MoKWAgLCBleGNlbCBgcmVhZHhsOjpyZWFkX2V4Y2VsKClgDQoNClZhbW9zIGEgdHJhYmFqYXIgY29uIFsqZGF0b3MNCmFiaWVydG9zKl0oaHR0cHM6Ly9kYXRvc2FiaWVydG9zLmRlc2Fycm9sbG9zb2NpYWwuZ29iLmFyL2RhdGFzZXQvcG90ZW5jaWFyLXRyYWJham8pDQpkZWwgKipQcm9ncmFtYSBOYWNpb25hbCBkZSBJbmNsdXNpw7NuIFNvY2lvcHJvZHVjdGl2YSB5IERlc2Fycm9sbG8gTG9jYWwNCiJQb3RlbmNpYXIgVHJhYmFqbyIqKiBxdWUgZnVlIGNyZWFkbyBlbiBlbCBhw7FvIDIwMjAgYmFqbyBsYSBSZXNvbHVjacOzbg0KTsKwIDEyMS4gRXN0ZSBwcm9ncmFtYSBidXNjYSBlcyBjb250cmlidWlyIGFsIG1lam9yYW1pZW50byBkZSBsYQ0KZW1wbGVhYmlsaWRhZCB5IGxhIGdlbmVyYWNpw7NuIGRlIG51ZXZhcyBwcm9wdWVzdGFzIHByb2R1Y3RpdmFzLiBQYXJhDQplbGxvLCBzZSBwcmV2w6kgbGEgcGFydGljaXBhY2nDs24gZGUgbGFzIHkgbG9zIHRpdHVsYXJlcyBkZWwgcHJvZ3JhbWEgZW4NCmFsIG1lbm9zIHVuYSBkZSBsYXMgdHJlcyBhbHRlcm5hdGl2YXM6DQoNCi0gICBwcm95ZWN0b3Mgc29jaW8tcHJvZHVjdGl2b3M7DQoNCi0gICB0ZXJtaW5hbGlkYWQgZWR1Y2F0aXZhOw0KDQotICAgcHJveWVjdG9zIHNvY2lvLWxhYm9yYWxlcyBvIHNvY2lvLWNvbXVuaXRhcmlvcw0KDQpgYGB7cn0NCiNEZWZpbm8gdXJsDQojIHVybCA8LSAoImh0dHBzOi8vZGF0b3NhYmllcnRvcy5kZXNhcnJvbGxvc29jaWFsLmdvYi5hci9kYXRhc2V0L2Q0NTY4N2MwLWYyYmEtNDFkOS05OTg5LTBhZDk3OTkzMDhhZS9yZXNvdXJjZS9jNWM5MjVlMC03Y2UwLTQxZTUtYjNmZi04ZWJiNTFkNGJlNzIvZG93bmxvYWQvcG90ZW5jaWFyLXRyYWJham8tdGl0dWxhcmVzLTIwMjItMTAtMDEuY3N2IikNCiMgDQojIHBvdGVuY2lhcl90cmFiYWpvIDwtIHJlYWQuY3N2KHVybCkNCg0KcG90ZW5jaWFyX3RyYWJham8gPC0gcmVhZC5jc3YoInBvdGVuY2lhci10cmFiYWpvLXRpdHVsYXJlcy0yMDIyLTEwLTAxLmNzdiIpDQpgYGANCg0KUGFyYSBkZXNjYXJnYXJsbyBhIG51ZXN0cm8gZXNwYWNpbyBkZSB0cmFiYWpvIHVzYW1vcyBsYSBmdW5jaW9uDQpgd3JpdGUuY3N2KClgIHBhcmEgQ1NWIG8gYHdyaXRlLnhsc3hgIGRlIGxhIGxpYnJlcsOtYSBgb3Blbnhsc3hgDQoNCmBgYHtyfQ0KDQojIEd1YXJkbyBlbCBjc3YNCndyaXRlLmNzdihwb3RlbmNpYXJfdHJhYmFqbywgImRmX3BvdGVuY2lhci5jc3YiKQ0KYGBgDQoNCnBhcmEgbGVlciBlbCBhcmNoaXZvIGRlc2RlIG51ZXN0cmEgY29tcHU6DQoNCmBgYHtyfQ0KDQojIExlbyBlbCBkZiANCmRmIDwtIHJlYWQuY3N2KCJkZl9wb3RlbmNpYXIuY3N2IikNCmBgYA0KDQpQdWVkZW4gZW5jb250cmFyIG3DoXMgaW5mb3JtYWNpw7NuIHNvYnJlIGltcG9ydGFjaW9uIHkgZXhwb3J0YWNpb24gZGUNCmFyY2hpdm9zIFthcXXDrV0oaHR0cHM6Ly9yLWNvZGVyLmNvbS9leHBvcnRhci1kYXRvcy1yLykgbw0KW2FxdcOtXShodHRwczovL215cmJvb2tzcC5uZXRsaWZ5LmFwcC9pbXBvcnQuaHRtbCkNCg0KIyBBbmFsaXphbW9zIGVsIHBvdGVuY2lhciB0cmFiYWpvDQoNClByaW1lcm8gdmFtb3MgYSB2ZXIgcXXDqSBoYXkgZW4gZWwgZGYgZGVsIHBvdGVuY2lhciB0cmFiYWpvDQoNCmBgYHtyfQ0KIyBQcmltZXJhcyAxMCBvYnNlcnZhY2lvbmVzDQpoZWFkKGRmKSANCg0KIyBVbHRpbWFzIDEwIG9ic2VydmFjaW9uZXMNCnRhaWwoZGYpDQpgYGANCg0KQ29uIGVsIHNpbWJvbG8gXCQgcHVlZG8gZWxlZ2lyIGxhcyB2YXJpYWJsZXMgZGUgbWkgdGFibGEgeSBhIGNhZGEgdW5hIGRlDQplbGxhcyBwdWVkbyBhcGxpY2FybGUgdW5hIGZ1bmNpw7NuDQoNCmBgYHtyfQ0KbWF4KGRmJHRpdHVsYXJlcykgI23DoXhpbW8gZGUgdGl0dWxhcmVzDQoNCm1pbihkZiR0aXR1bGFyZXMpICNtw61uaW1vIGRlIG1pbmltbyBkZSB0aXR1bGFyZXMNCg0KYGBgDQoNClBhcmEgc2FiZXIgbcOhcyBhY2VyY2EgZGUgdW5hIGZ1bmNpw7NuIHBvZGVzIHBlZGlybGUgYXl1ZGEgYSBSIGNvbjoNCg0KYGBge3J9DQojP21heA0KI2hlbHAobWF4KQ0KYGBgDQoNClZlciB1biByZXN1bWVuIGRlIGxvcyBkYXRvcw0KDQpgYGB7cn0NCnN0cihkZikNCnN1bW1hcnkoZGYpDQpgYGANCg0KIyBHcmFmaWNhbW9zDQoNClBhcmEgZ3JhZmljYXIgdXNhbW9zIGBnZ3Bsb3QyYCwgZXMgdW4gcGFxdWV0ZSBxdWUgc2UgZW5jdWVudHJhIGRlbnRybyBkZQ0KVGlkeXZlcnNlLg0KDQpgVGlkeXZlcnNlYCBlcyB1biBjb25qdW50byBkZSBwYXF1ZXRlcyBlbiBSIGRpc2XDsWFkb3MgcGFyYSBsYSBjaWVuY2lhIGRlDQpkYXRvcy4gRXN0b3MgcGFxdWV0ZXMgY29tcHJlbmRlbiBmdW5jaW9uZXMgcXVlIGZhY2lsaXRhbiBlbCBwcm9jZXNvIGRlDQppbXBvcnRhY2nDs24sIGxpbXBpZXphLCB0cmFuc2Zvcm1hY2nDs24sIHZpc3VhbGl6YWNpw7NuLCBtb2RlbGFkbyB5DQpjb211bmljYWNpw7NuIGRlIGRhdG9zLiBQdWVkZW4gZXhwbG9yYXJsb3MgbWVkaWFudGUgbGENCltkb2N1bWVudGFjacOzbl0oaHR0cHM6Ly93d3cudGlkeXZlcnNlLm9yZy9wYWNrYWdlcy8pDQoNCmBgYHtyfQ0KIyBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KDQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIyBBY3RpdmFtb3MgZWwgcGFxdWV0ZQ0KYGBgDQoNClBhcmEgaW5zdGFsYXIgdW4gcGFxdWV0ZSB1c2Ftb3MgYGluc3RhbGwucGFja2FnZXMoIm5vbWJyZV9kZWxfcGFxdWV0ZSIpYA0KeSBzaWVtcHJlIFNJRU1QUkUgcXVlIG5lY2VzaXRhbW9zIHVzYXJsbyBoYXkgcXVlIGxsYW1hcmxvIGVuIG51ZXN0cmENCnNlc2nDs24gbyBkb2N1bWVudG8gY29uIGBsaWJyYXJ5KG5vbWJyZV9kZWxfcGFxdWV0ZSlgDQoNCkV4aXN0ZSB1bmEgaW50ZXJmYXogaW50ZXJhY3RpdmEgcXVlIHBlcm1pdGUgZGFyIGxvcyBwcmltZXJvcyBwYXNvcyBlbg0KZXN0ZSBtdW5kbyBkZSBsYSB2aXN1YWxpemFjacOzbi4gRWwgcGFxdWV0ZSBgZXNxdWlzc2VgIHRlIHBlcm1pdGUgaGFjZXINCnVuIGJvY2V0byBkZWwgZ3LDoWZpY28geSBsdWVnbyBjb3BpYXIgZWwgY29kaWdvIGVuIHR1IHRyYWJham8gYSB0cmF2w6lzIGRlDQpsYSBmdW5jacOzbiBgZXNxdWlzc2VyYA0KDQpgYGB7cn0NCiNpbnN0YWxhcmVtb3MgZWwgcGFxdWV0ZSBlc3F1aXNzZQ0KDQojaW5zdGFsbC5wYWNrYWdlcygiZXNxdWlzc2UiKSAjaW5zdGFsYW1vcyBlbCBwYXF1ZXRlLCBwb3IgdW5pY2EgdmV6DQoNCmxpYnJhcnkoZXNxdWlzc2UpDQojIE90cmEgZm9ybWEgZGUgbGxhbWFyIGEgbGFzIGZ1bmNpb25lcyBkZSBsb3MgcGFxdWV0ZXMgZXNxdWlzc2U6OmVzcXVpc3NlcigpDQojZXNxdWlzc2VyKGRmKSAjY29ycmVtb3MgbGEgZnVuY2lvbiBkZSB2aXN1YWxpemFjaW9uDQoNCg0KIyBHcsOhZmljbyByZXN1bHRhbnRlDQoNCmdncGxvdChkZikgKw0KICBhZXMoeCA9IHBlcmlvZG8sIHdlaWdodCA9IHRpdHVsYXJlcykgKw0KICBnZW9tX2JhcihmaWxsID0gIiMzNkIwOEUiKSArDQogIGxhYnMoDQogICAgeCA9ICJDYW50aWRhZCIsDQogICAgeSA9ICJQZXLDrW9kbyIsDQogICAgdGl0bGUgPSAiVGl0dWxhcmVzIGRlbCBwb3RlbmNpYXIgdHJhYmFqbyBwb3IgYcOxbyIsDQogICAgc3VidGl0bGUgPSAiQ2FudGlkYWQgZGUgdGl0dWxhcmVzICgyMDIxLTIwMjMpIiwNCiAgICBjYXB0aW9uID0gIkZ1ZW50ZTogRGF0b3MgYWJpZXJ0b3MgZGVsIE1EU04iDQogICkgKw0KICB0aGVtZV9jbGFzc2ljKCkgKw0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNkwsDQogICAgZmFjZSA9ICJib2xkIiwNCiAgICBoanVzdCA9IDAuNSksDQogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTVMLA0KICAgIGhqdXN0ID0gMC41KQ0KICApDQpgYGANCg0KIyBQcmVzZW50YWNpw7NuDQoNCkFjY2Vkw6kgYSBsYSBwcmVzZW50YWNpw7NuDQpbYWPDoV0oaHR0cHM6Ly9hcmlhbmFiYXJkLm5ldGxpZnkuYXBwL3Bvc3RzL3JwYXJhY2llbnRpc3Rhc3NvY2lhbGVzLykNCg0KDQoNCiMjIEZ1ZW50ZQ0KDQotICAgW1IgZW4gOTANCiAgICBtaW51dG9zXShodHRwczovL3d3dy5udWNsZW9kZWlubm92YWNpb24uY29tL3Bvc3QvbmlzLWVuLWxhLWZhY3VsdGFkLWRlLWNpZW5jaWFzLXNvY2lhbGVzLWNvbi1yLWVuLTkwLW1pbnV0b3MpIC0NCiAgICBOdWNsZW8gZGUgSW5ub3ZhY2nDs24gU29jaWFsIChOSVMpDQoNCi0gICBbSW50cm9kdWNjacOzbiBhbCBBbsOhbGlzaXMgZGUgRGF0b3MgZW4NCiAgICBSXShodHRwczovL2dpdGh1Yi5jb20vZWxhdGVuZW9hYy9jdXJzb1JfMjAyMykgLSBlbCBBdGVuZW8gQS5DDQogICAgDQogICAgDQohW10oaW1hZ2VuZXMvbG9nby11bmxhbS5wbmcpe3dpZHRoPSIyMTIiIGFsaWduPSJyaWdodCJ9