Las notas del presente curso fueron elaboradas originalmente por Diego Kozlowski y Guido Weksler. En las sucesivas modificaciones colaboraron: Natsumi Shokida y Matías Lioni

EPH

  • Descipción de la encuesta, periodicidad y cobertura.
  • Información relevada en distintos cuestionarios
  • Definción de variables de interés a abordar en el curso: Estados, Categorías ocupacionales, Ingresos y Ponderadores : Archivo “Metodologia_EPHContinua 2003.pdf” en la carpeta de Fuentes del curso.
  • Bases de Microdatos: Archivos “usu_individualt117” en la carpeta de Fuentes del curso.
  • Diseño de Registro : Archivo “EPH_registro_2_trim_2016.pdf” en la carpeta de Fuentes del curso.

Descripción del programa

¿Que es R?

  • Lenguaje para el procesamiento y análisis estadístico de datos
  • Software Libre
  • Sintaxis Básica: R base
  • Sintaxis incremental1: El lenguaje se va ampliando por aportes de Universidades, investigadores y empresas privadas, organizados en librerías (o paquetes)
  • Comunidad web muy grande para realizar preguntas y despejar dudas.
  • Graficos con calidad de publicación

El entorno más cómodo para utilizar el lenguaje R es el programa R studio

  • Rstudio es una empresa que produce productos asociados al lenguaje R, como el programa sobre el que corremos los comandos, y extensiones del lenguaje (librerías).

  • El programa es gratuito y se puede bajar de la página oficial

Pantalla Rstudio

Pantalla Rstudio

Diferencias con STATA y SPSS

  • Gratuito
  • Únicamente funciona por líneas de código (No hay botones para ejecutar comandos)
  • Posibilita trabajar con múltiples bases de microdatos al mismo tiempo, sin mayor dificultad (No requiere abrir cada base, trabajarla por separado y luego cerrarla)
  • Más potente
    • Totalmente automatizable
    • Aportes de usuarios
    • Extensible a otros lenguajes y usos (Presentación como esta, diseño de aplicaciones)
  • Más veloz:

Lógica sintáctica.

Definición de objetos

Los Objetos/Elementos constituyen la categoría escencial del R. De hecho, todo en R es un objeto, y se almacena con un nombre específico que no debe poseer espacios. Un número, un vector, una función, la progresión de letras del abecedario, una base de datos, un gráfico, constituyen para R objetos de distinto tipo. Los objetos que vamos creando a medida que trabajamos pueden visualizarse en la panel derecho superior de la pantalla.

El operador <- sirve para definir un objeto. A la izquierda del <- debe ubicarse el nombre que tomará el elemento a crear. Del lado derecho debe ir la definición del mismo

A <- 1

Al definir un elemento, el mismo queda guardado en el ambiente del programa, y podrá ser utilizado posteriormente para observar su contenido o para realizar una operación con el mismo

A 
[1] 1
A+6
[1] 7

Al correr una linea con el nombre del objeto, la consola del programa nos muestra su contenido. Entre Corchetes Observamos el número de orden del elemento en cuestión

El operador = es equivalente a <-, pero en la práctica no se utiliza para la definición de objetos.

B = 2
B
[1] 2

<- es un operador Unidireccional, es decir que:
A <- B implica que A va tomar como valor el contenido del objeto B, y no al revés.

A <- B
A   #Ahora A toma el valor de B, y B continua conservando el mismo valor
[1] 2
B
[1] 2

R base

Con R base nos referimos a los comandos básicos que vienen incorporados en el R, sin necesidad de cargar librerías.

Operadores lógicos:

  • \(>\)
  • \(>=\)
  • \(<\)
  • \(<=\)
  • \(==\)
  • \(!=\)
#Redefinimos los valores A y B
A <-  10
B  <-  20
#Realizamos comparaciones lógicas
A >  B
[1] FALSE
A >= B
[1] FALSE
A <  B
[1] TRUE
A <= B
[1] TRUE
A == B
[1] FALSE
A != B
[1] TRUE
C <- A != B
C
[1] TRUE

Como muestra el último ejemplo, el resultado de una operación lógica puede almacenarse como el valor de un objeto.

Operadores aritméticos:

#suma
A <- 5+6
A
[1] 11
#Resta
B <- 6-8
B
[1] -2
#cociente
C <- 6/2.5
C
[1] 2.4
#multiplicacion
D <- 6*2.5
D
[1] 15

Funciones:

Las funciones son series de procedimientos estandarizados, que toman como imput determinados argumentos a fijar por el usuario, y devuelven un resultado acorde a la aplicación de dichos procedimientos. Su lógica de funcionamiento es:
funcion(argumento1 = arg1, argumento2 = arg2)

A lo largo del curso iremos viendo numerosas funciones, según lo requieran los distintos ejercicios. Sin embargo, veamos ahora algunos ejemplos para comprender su funcionamiento:

  • paste() : concatena una serie de caracteres, indicando por última instancia como separar a cada uno de ellos
  • paste0(): concatena una serie de caracteres sin separar
  • sum(): suma de todos los elementos de un vector
  • mean() promedio aritmético de todos los elementos de un vector
paste("Pega","estas",4,"palabras", sep = " ")
[1] "Pega estas 4 palabras"
#Puedo concatenar caracteres almacenados en objetos
paste(A,B,C,sep = "**")
[1] "11**-2**2.4"
# Paste0 pega los caracteres sin separador
paste0(A,B,C)
[1] "11-22.4"
1:5
[1] 1 2 3 4 5
sum(1:5)
[1] 15
mean(1:5,na.rm = TRUE)
[1] 3

Caracteres especiales

  • R es sensible a mayúsculas y minúsculas, tanto para los nombres de las variables, como para las funciones y parámetros.
  • Los espacios en blanco y los carriage return (enter) no son considerados por el lenguaje. Los podemos aprovechar para emprolijar el código y que la lectura sea más simple2.
  • El numeral # se utiliza para hacer comentarios. Todo lo que se escribe después del # no es interpretado por R. Se debe utilizar un # por cada línea de código que se desea anular

  • Los corchetes [] se utilizan para acceder a un objeto:
    • en un vector[n° orden]
    • en una tabla[fila, columna]
    • en una lista[n° elemento]
  • el signo $ también es un método de acceso. Particularmente, en los dataframes, nos permitira acceder a una determinada columna de una tabla

  • Los paréntesis() se utilizan en las funciones para definir los parámetros.

  • Las comas , se utilizan para separar los parametros al interior de una función.

Objetos:

Existen un gran cantidad de objetos distintos en R, en lo que resepcta al curso trabajaremos principalmente con 3 de ellos:

  • Valores
  • Vectores
  • Data Frames
  • Listas

Valores

Los valores y vectores pueden ser a su vez de distintas clases:

Numeric

A <-  1
class(A)
[1] "numeric"

Character

A <-  paste('Soy', 'una', 'concatenación', 'de', 'caracteres', sep = " ")
A
[1] "Soy una concatenación de caracteres"
class(A)
[1] "character"

Factor

A <- factor("Soy un factor, con niveles fijos")
class(A)
[1] "factor"

La diferencia entre un character y un factor es que el último tiene solo algunos valores permitidos (levels), con un orden interno predefinido (el cual ,por ejemplo, se respetará a la hora de realizar un gráfico)

Vectores

Para crear un vector utilizamos el comando c(), de combinar.

C <- c(1, 3, 4)
C
[1] 1 3 4

sumarle 2 a cada elemento del vector anterior

C <- C + 2
C
[1] 3 5 6

sumarle 1 al primer elemento, 2 al segundo, y 3 al tercer elemento del vector anterior

D <- C + 1:3 #esto es equivalente a hacer 3+1, 5+2, 6+9 
D
[1] 4 7 9

1:3 significa que queremos todos los números enteros desde 1 hasta 3.

crear un vector que contenga las palabras: “Carlos”,“Federico”,“Pedro”

E <- c("Carlos","Federico","Pedro")
E
[1] "Carlos"   "Federico" "Pedro"   

para acceder a algún elemento del vector, podemos buscarlo por su número de orden, entre [ ]

 E[2]
[1] "Federico"

Si nos interesa almacenar dicho valor, al buscarlo lo asignamos a un nuevo objeto, dandole el nombre que deseemos

elemento2 <-  E[2]
elemento2
[1] "Federico"

para borrar un objeto del ambiente de trabajo, utilizamos el comando rm()

rm(elemento2)
elemento2
Error: object 'elemento2' not found

También podemos cambiar el texto del segundo elemento de E, por el texto “Pablo”

E[2] <- "Pablo"
E
[1] "Carlos" "Pablo"  "Pedro" 

Data Frames

Un Data Frame es una tabla de datos, donde cada columna representa una variable, y cada fila una observación.

Este objeto suele ser central en el proceso de trabajo, y suele ser la forma en que se cargan datos externos para trabajar en el ambiente de R, y en que se exportan los resultados de nuestros trabajo.

También Se puede crear como la combinación de N vectores de igual tamaño. Por ejemplo, tomamos algunos valores del Indice de salarios

INDICE  <- c(100,   100,   100,
             101.8, 101.2, 100.73,
             102.9, 102.4, 103.2)
FECHA  <-  c("Oct-16", "Oct-16", "Oct-16",
             "Nov-16", "Nov-16", "Nov-16",
             "Dic-16", "Dic-16", "Dic-16")
GRUPO  <-  c("Privado_Registrado","Público","Privado_No_Registrado",
             "Privado_Registrado","Público","Privado_No_Registrado",
             "Privado_Registrado","Público","Privado_No_Registrado")
             
Datos <- data.frame(INDICE, FECHA, GRUPO)
Datos

Tal como en un vector se ubica a los elementos mediante [ ], en un dataframe se obtienen sus elementos de la forma [fila, columna].

Otra opción es especificar la columna, mediante el operador $, y luego seleccionar dentro de esa columna el registro deseado mediante el número de orden.

Datos$FECHA
[1] Oct-16 Oct-16 Oct-16 Nov-16 Nov-16 Nov-16 Dic-16 Dic-16 Dic-16
Levels: Dic-16 Nov-16 Oct-16
Datos[3,2]
[1] Oct-16
Levels: Dic-16 Nov-16 Oct-16
Datos$FECHA[3]
[1] Oct-16
Levels: Dic-16 Nov-16 Oct-16

¿que pasa si hacemos Datos$FECHA[3,2] ?

Datos$FECHA[3,2]
Error in `[.default`(Datos$FECHA, 3, 2) : incorrect number of dimensions

Nótese que el último comando tiene un número incorrecto de dimensiones, porque estamos refiriendonos 2 veces a la columna FECHA.

Acorde a lo visto anteriormente, el acceso a los dataframes mediante [ ], puede utilizarse para realizar filtros sobre la base, especificando una condición para las filas. Por ejemplo, puedo utilizar los [ ] para conservar del dataframe Datos unicamente los registros con fecha de Diciembre 2016:

Datos[Datos$FECHA=="Dic-16",]

La lógica del paso anterior sería: Accedo al dataframe Datos, pidiendo únicamente conservar las filas (por eso la condición se ubica a la izquierda de la ,) que cumplan el requisito de pertenecer a la categoría “Dic-16” de la variable FECHA.
Aún más, podría aplicar el filtro y al mismo tiempo identificar una variable de interés para luego realizar un cálculo sobre aquella. Por ejemplo, podría calcular la media de los indices en el mes de Diciembre.

###Por separado
Indices_Dic <- Datos$INDICE[Datos$FECHA=="Dic-16"]
Indices_Dic
[1] 102.9 102.4 103.2
mean(Indices_Dic)
[1] 102.8333
### Todo junto
mean(Datos$INDICE[Datos$FECHA=="Dic-16"])
[1] 102.8333

La lógica de esta sintaxis sería: “Me quedó con la variable INDICE, cuando la variable FECHA sea igual a “Dic-16”, luego calculo la media de dichos valores”

Listas

Contienen una concatenación de objetos de cualquier tipo. Así como un vector contiene valores, un dataframe contiene vectores, una lista puede contener dataframes, pero también vectores, o valores, y todo ello a la vez

superlista <- list(A,B,C,D,E,FECHA, DF = Datos, INDICE, GRUPO)
superlista
[[1]]
[1] Soy un factor, con niveles fijos
Levels: Soy un factor, con niveles fijos

[[2]]
[1] -2

[[3]]
[1] 3 5 6

[[4]]
[1] 4 7 9

[[5]]
[1] "Carlos" "Pablo"  "Pedro" 

[[6]]
[1] "Oct-16" "Oct-16" "Oct-16" "Nov-16" "Nov-16" "Nov-16" "Dic-16" "Dic-16" "Dic-16"

$DF

[[8]]
[1] 100.00 100.00 100.00 101.80 101.20 100.73 102.90 102.40 103.20

[[9]]
[1] "Privado_Registrado"    "Público"               "Privado_No_Registrado"
[4] "Privado_Registrado"    "Público"               "Privado_No_Registrado"
[7] "Privado_Registrado"    "Público"               "Privado_No_Registrado"

Para acceder un elemento de una lista, podemos utilizar el operador $, que se puede usar a su vez de forma iterativa

superlista$DF$FECHA[2]
[1] Oct-16
Levels: Dic-16 Nov-16 Oct-16

Instalación de paquetes complementarios al R Base

Hasta aquí hemos visto múltiples funciones que están contenidas dentro del lenguaje básico de R. Ahora bien, al tratarse de un software libre, los usuarios de R con más experiencia contribuyen sistemáticamente a expandir este lenguaje mediante la creación y actualización de paquetes complementarios. Lógicamente, los mismos no están incluidos en la instalación inicial del programa, pero podemos descargarlos e instalarlos al mismo tiempo con el siguiente comando:

install.packages("nombre_del_paquete") 

Resulta recomendable ejecutar este comando desde la consola ya que solo necesitaremos correrlo una vez en nuestra computadora. Al ejecutar el mismo, se descargarán de la pagina de CRAN los archivos correspondientes al paquete hacia el directorio en donde hayamos instalado el programa. Típicamente los archivos se encontrarán en **C:Files-3.5.0**, siempre con la versión del programa correspondiente.
Una vez instalado el paquete, cada vez que abramos una nueva sesión de R y querramos utilizar el mismo debemos cargarlo al ambiente de trabajo mediante la siguiente función:

library(nombre_del_paquete)

Nótese que al cargar/activar el paquete no son necesarias las comillas.

Lectura y escritura de archivos

.csv y .txt

Hay muchas funciones para leer archivos de tipo .txt y .csv. La mayoría sólo cambia los parámetros que vienen por default.

Es importante tener en cuenta que una base de datos que proviene de archivos .txt, o .csv puede presentar diferencias en cuanto a los siguientes parametros:

  • encabezado
  • delimitador (,, tab, ;)
  • separador decimal
dataframe <- read.delim(file, header = TRUE, sep = "\t", quote = "\"", dec = ".", fill = TRUE, comment.char = "", ...) 

Ejemplo. Levantar la base individual de EPH del 1er trimestre 2017

En el parametro file tengo que especificar el nombre completo del archivo, incluyendo el directorio donde se encuentra. Lo más sencillo es abrir comillas, apretar Tab y se despliega el menú de las cosas que tenemos en el directorio de trabajo. Si queremos movernos hacia arriba, agregamos ../

individual_t117 <- read.table(file = '../Fuentes/usu_individual_t117.txt',sep=";", dec=",", header = TRUE, fill = TRUE)
individual_t117

Como puede observarse aquí, las bases individuales de la EPH cuentan con más de 58.000 registros y 177 variables. Al trabajar con bases de microdatos, resulta conveniente contar con algunos comandos para tener una mirada rápida de la base, antes de comenzar a realizar los procesamientos que deseemos.

Veamos algunos de ellos:

#View(individual_t117)
names(individual_t117)
  [1] "CODUSU"     "ANO4"       "TRIMESTRE"  "NRO_HOGAR"  "COMPONENTE" "H15"       
  [7] "REGION"     "MAS_500"    "AGLOMERADO" "PONDERA"    "CH03"       "CH04"      
 [13] "CH05"       "CH06"       "CH07"       "CH08"       "CH09"       "CH10"      
 [19] "CH11"       "CH12"       "CH13"       "CH14"       "CH15"       "CH15_COD"  
 [25] "CH16"       "CH16_COD"   "NIVEL_ED"   "ESTADO"     "CAT_OCUP"   "CAT_INAC"  
 [31] "IMPUTA"     "PP02C1"     "PP02C2"     "PP02C3"     "PP02C4"     "PP02C5"    
 [37] "PP02C6"     "PP02C7"     "PP02C8"     "PP02E"      "PP02H"      "PP02I"     
 [43] "PP03C"      "PP03D"      "PP3E_TOT"   "PP3F_TOT"   "PP03G"      "PP03H"     
 [49] "PP03I"      "PP03J"      "INTENSI"    "PP04A"      "PP04B_COD"  "PP04B1"    
 [55] "PP04B2"     "PP04B3_MES" "PP04B3_ANO" "PP04B3_DIA" "PP04C"      "PP04C99"   
 [61] "PP04D_COD"  "PP04G"      "PP05B2_MES" "PP05B2_ANO" "PP05B2_DIA" "PP05C_1"   
 [67] "PP05C_2"    "PP05C_3"    "PP05E"      "PP05F"      "PP05H"      "PP06A"     
 [73] "PP06C"      "PP06D"      "PP06E"      "PP06H"      "PP07A"      "PP07C"     
 [79] "PP07D"      "PP07E"      "PP07F1"     "PP07F2"     "PP07F3"     "PP07F4"    
 [85] "PP07F5"     "PP07G1"     "PP07G2"     "PP07G3"     "PP07G4"     "PP07G_59"  
 [91] "PP07H"      "PP07I"      "PP07J"      "PP07K"      "PP08D1"     "PP08D4"    
 [97] "PP08F1"     "PP08F2"     "PP08J1"     "PP08J2"     "PP08J3"     "PP09A"     
[103] "PP09A_ESP"  "PP09B"      "PP09C"      "PP09C_ESP"  "PP10A"      "PP10C"     
[109] "PP10D"      "PP10E"      "PP11A"      "PP11B_COD"  "PP11B1"     "PP11B2_MES"
[115] "PP11B2_ANO" "PP11B2_DIA" "PP11C"      "PP11C99"    "PP11D_COD"  "PP11G_ANO" 
[121] "PP11G_MES"  "PP11G_DIA"  "PP11L"      "PP11L1"     "PP11M"      "PP11N"     
[127] "PP11O"      "PP11P"      "PP11Q"      "PP11R"      "PP11S"      "PP11T"     
[133] "P21"        "DECOCUR"    "IDECOCUR"   "RDECOCUR"   "GDECOCUR"   "PDECOCUR"  
[139] "ADECOCUR"   "PONDIIO"    "TOT_P12"    "P47T"       "DECINDR"    "IDECINDR"  
[145] "RDECINDR"   "GDECINDR"   "PDECINDR"   "ADECINDR"   "PONDII"     "V2_M"      
[151] "V3_M"       "V4_M"       "V5_M"       "V8_M"       "V9_M"       "V10_M"     
[157] "V11_M"      "V12_M"      "V18_M"      "V19_AM"     "V21_M"      "T_VI"      
[163] "ITF"        "DECIFR"     "IDECIFR"    "RDECIFR"    "GDECIFR"    "PDECIFR"   
[169] "ADECIFR"    "IPCF"       "DECCFR"     "IDECCFR"    "RDECCFR"    "GDECCFR"   
[175] "PDECCFR"    "ADECCFR"    "PONDIH"    
summary(individual_t117)[,c(8,10,31,133)]
 MAS_500      PONDERA           IMPUTA              P21        
 N:31790   Min.   :  25.0   Min.   :0.000000   Min.   :    -9  
 S:26885   1st Qu.: 137.0   1st Qu.:0.000000   1st Qu.:     0  
           Median : 238.0   Median :0.000000   Median :     0  
           Mean   : 467.3   Mean   :0.002727   Mean   :  3671  
           3rd Qu.: 541.0   3rd Qu.:0.000000   3rd Qu.:  4800  
           Max.   :7001.0   Max.   :1.000000   Max.   :300000  
                                                               
head(individual_t117)[,1:5]

Excel

Para leer y escribir archivos excel debemos utilizar los comandos que vienen con la librería openxlsx

# install.packages("openxlsx") # por única vez
library(openxlsx) #activamos la librería
#creamos una tabla cualquiera de prueba
x <- 1:10
y <- 11:20
tabla_de_R <- data.frame(x,y)
# escribimos el archivo
write.xlsx( x = tabla_de_R, file = "archivo.xlsx",row.names = FALSE)
#Donde lo guardó? Hay un directorio por default en caso de que no hayamos definido alguno.
#getwd()
#Si queremos exportar multiples dataframes a un Excel, debemos armar previamente una lista de ellos. Cada dataframe, se guardará en una pestaña de excel, cuyo nombre correspondera al que definamos para cada Dataframe a la hora de crear la lista.
Lista_a_exportar <- list("Indices Salarios" = Datos,
                         "Tabla Numeros" = tabla_de_R)
write.xlsx( x = Lista_a_exportar, file = "archivo_2_hojas.xlsx",row.names = FALSE)
#leemos el archivo especificando la ruta (o el directorio por default) y el nombre de la hoja que contiene los datos
Indices_Salario <- read.xlsx(xlsxFile = "archivo_2_hojas.xlsx",sheet = "Indices Salarios")
#alternativamente podemos especificar el número de orden de la hoja que deseamos levantar
Indices_Salario <- read.xlsx(xlsxFile = "archivo_2_hojas.xlsx",sheet = 1)
Indices_Salario

Ambientes de trabajo

Hay algunas cosas que tenemos que tener en cuenta respecto del orden del ambiente en el que trabajamos:

  • Working Directory: El directorio de trabajo, pueden ver el suyo con getwd(), es hacia donde apunta el código, por ejemplo, si quieren leer un archivo, la ruta del archivo tiene que estar explicitada como el recorrido desde el Working Directory.
  • Environment: Esto engloba tanto la información que tenemos cargada en Data y Values, como las librerías que tenemos cargadas mientras trabajamos.

Es importante que mantengamos bien delimitadas estas cosas entre diferentes trabajos, sino:

  1. El directorio queda referido a un lugar específico en nuestra computadora.
  • Si se lo compartimos a otro se rompe
  • Si cambiamos de computadora se rompe
  • Si lo cambiamos de lugar se rompe
  • Si primero abrimos otro script se rompe
  1. Tenemos mezclados resultados de diferentes trabajos:
  • Nunca sabemos si esa variable/tabla/lista se creo en ese script y no otro
  • Perdemos espacio de la memoria
  • No estamos seguros de que el script cargue todas las librerías que necesita

Rstudio tiene una herramienta muy útil de trabajo que son los proyectos. Estos permiten mantener un ambiente de trabajo delimitado por cada uno de nuestros trabajos. Es decir:

  • El directorio de trabajo se refiere a donde esta ubicado el archivo .Rproj
  • El Environment es específico de nuestro proyecto.

Un proyecto no es un sólo script, sino toda una carpeta de trabajo.

logo Rpoject

logo Rpoject

Para crearlo, vamos al logo de nuevo projecto (Arriba a la izquierda de la panatalla), y elegimos la carpeta de trabajo.

Paquetes a utilizar a lo largo del curso:

Para quienes esten trabajando con sus computadoras personales, dejamos a continuación un listado de los paquetes complementarios del R base que utilizaremos a lo largo del curso. Como la instalación requiere descargar múltiples archivos de internet recomendamos hacerlo cuando dispongan de una buena conexión. Con el siguiente comando podrían instalarlos todos de una vez:

install.packages(c("tidyverse","openxlsx",'ggplot2','ggthemes', 'ggrepel','ggalt','kableExtra'))

Ejercicios para practicar

Reiniciar R (Session --> Restart R)

  • Crear un OBJETO llamado OBJETO definido como el resultado de la suma: 5 + 6
  • Crear un VECTOR VEC0 que contenga los números 1, 3, 4.
  • Crear 3 vectores ( VEC1, VEC2, VEC3) que sean transformaciones del anterior
  • Crear 3 vectores con la misma cantidad de elementos que VEC0, pero con variables string (texto) ( VEC4, VEC5, VEC6).
  • Crear un dataframe DFRAME como combinación de todos los vectores creados previamente

  • Levantar la base Individual del 1er trimestre de 2017, de la EPH
  • Levantar del Excel llamado CANASTAS que se encuentra en la carpeta de Fuentes, la hoja “CBT” y definirla como HojaCBT. Pueden usar la función read.xlsx de cualquiera de las siguientes librerías:
    • Vista en clase: openxlsx
    • Otra opción que utiliza otros parametros: readxl

Ejercicios de tarea

Crear un nuevo script en la carpeta de la clase 1 nombrado “Nombre_Alumno_Tarea_C1.R”, y realizar los siguientes procedimientos:

  • Crear un OBJETO llamado COSA definido como el resultado de la multiplicación: 5*6
  • Crear un VECTOR VECTOR0 que contenga los números 10, 20, 30.
  • Modificar el segundo elemento del VECTOR0, asignandole el valor 40
  • Crear 3 vectores con la misma cantidad de elementos que VEC0, pero con variables string (texto) ( VECTOR1, VECTOR2, VECTOR3).
  • Crear un dataframe DATAF como combinación de todos los vectores creados previamente
  • Crear un objeto llamado OTRA_COSA que guarde el valor contenido en la segunda fila y tercera columna del dataframe DATAF

  • Levantar la base Individual del 4to trimestre de 2016, de la EPH
  • Levantar del Excel llamado CANASTAS que se encuentra en la carpeta de Fuentes, la hoja “CBA” y definirla como HojaCBA.


  1. Más allá de los comandos elementales, comandos más sofisticados tienen muchas versiones, y algunas quedan en desuso en el tiempo.

  2. veremos que existen ciertas excepciones con algunos paquetes más adelante.

LS0tDQp0aXRsZTogVXRpbGl6YWNpw7NuIGRlbCBsZW5ndWFqZSBSIHBhcmEgYXBsaWNhY2nDs24gZW4gbGEgRW5jdWVzdGEgUGVybWFuZW50ZQ0KICBkZSBIb2dhcmVzDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogIHBkZl9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQpkYXRlOiAiIg0Kc3VidGl0bGU6IENsYXNlIDEgLSBDb25jZXB0b3MgUHJpbmNpcGFsZXMgZGUgRVBIIHkgUiBCYXNlDQotLS0NCipMYXMgbm90YXMgZGVsIHByZXNlbnRlIGN1cnNvIGZ1ZXJvbiBlbGFib3JhZGFzIG9yaWdpbmFsbWVudGUgcG9yIERpZWdvIEtvemxvd3NraSB5IEd1aWRvIFdla3NsZXIuIEVuIGxhcyBzdWNlc2l2YXMgbW9kaWZpY2FjaW9uZXMgY29sYWJvcmFyb246IE5hdHN1bWkgU2hva2lkYSB5IE1hdMOtYXMgTGlvbmkqDQoNCiMgRVBIDQoNCiAtICoqRGVzY2lwY2nDs24gZGUgbGEgZW5jdWVzdGEsIHBlcmlvZGljaWRhZCB5IGNvYmVydHVyYSoqLg0KIC0gKipJbmZvcm1hY2nDs24gcmVsZXZhZGEgZW4gZGlzdGludG9zIGN1ZXN0aW9uYXJpb3MqKg0KDQoNCg0KIVtdKFRlbWF0aWNhcyBFUEgucG5nKQ0KDQogIC0gICoqRGVmaW5jacOzbiBkZSB2YXJpYWJsZXMgZGUgaW50ZXLDqXMgYSBhYm9yZGFyIGVuIGVsIGN1cnNvOiBFc3RhZG9zLCBDYXRlZ29yw61hcyBvY3VwYWNpb25hbGVzLCBJbmdyZXNvcyB5IFBvbmRlcmFkb3JlcyoqIDogQXJjaGl2byAiTWV0b2RvbG9naWFfRVBIQ29udGludWEgMjAwMy5wZGYiIGVuIGxhIGNhcnBldGEgZGUgRnVlbnRlcyBkZWwgY3Vyc28uDQogIC0gKipCYXNlcyBkZSBNaWNyb2RhdG9zKio6IEFyY2hpdm9zICJ1c3VfaW5kaXZpZHVhbHQxMTciIGVuIGxhIGNhcnBldGEgZGUgRnVlbnRlcyBkZWwgY3Vyc28uDQogIC0gKipEaXNlw7FvIGRlIFJlZ2lzdHJvKiogOiBBcmNoaXZvICJFUEhfcmVnaXN0cm9fMl90cmltXzIwMTYucGRmIiBlbiBsYSBjYXJwZXRhIGRlIEZ1ZW50ZXMgZGVsIGN1cnNvLg0KDQojIERlc2NyaXBjacOzbiBkZWwgcHJvZ3JhbWEgICAgICAgIA0KDQoNCiFbaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvXShSbG9nby5wbmcpDQoNCiMjIMK/UXVlIGVzIFI/DQoNCi0gTGVuZ3VhamUgcGFyYSBlbCBwcm9jZXNhbWllbnRvIHkgYW7DoWxpc2lzIGVzdGFkw61zdGljbyBkZSBkYXRvcw0KLSBTb2Z0d2FyZSBMaWJyZQ0KLSBTaW50YXhpcyBCw6FzaWNhOiBSIGJhc2UgDQotIFNpbnRheGlzIGluY3JlbWVudGFsW14xXTogRWwgbGVuZ3VhamUgc2UgdmEgYW1wbGlhbmRvIHBvciBhcG9ydGVzIGRlIFVuaXZlcnNpZGFkZXMsIGludmVzdGlnYWRvcmVzIHkgZW1wcmVzYXMgcHJpdmFkYXMsIG9yZ2FuaXphZG9zIGVuIGxpYnJlcsOtYXMgKG8gcGFxdWV0ZXMpDQotIENvbXVuaWRhZCB3ZWIgbXV5IGdyYW5kZSBwYXJhIHJlYWxpemFyIHByZWd1bnRhcyB5IGRlc3BlamFyIGR1ZGFzLg0KLSBHcmFmaWNvcyBjb24gY2FsaWRhZCBkZSBwdWJsaWNhY2nDs24NCg0KW14xXTogTcOhcyBhbGzDoSBkZSBsb3MgY29tYW5kb3MgZWxlbWVudGFsZXMsIGNvbWFuZG9zIG3DoXMgc29maXN0aWNhZG9zIHRpZW5lbiBtdWNoYXMgdmVyc2lvbmVzLCB5IGFsZ3VuYXMgcXVlZGFuIGVuIGRlc3VzbyBlbiBlbCB0aWVtcG8uDQoNCiFbZnVlbnRlOiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9kYXJvY3ppZy8zY2YwNmQ2ZGI0YmUyYmJlMzM2OF0obnVtYmVyLW9mLXN1Ym1pdHRlZC1wYWNrYWdlcy10by1DUkFOLnBuZykNCg0KDQohW2h0dHBzOi8vd3d3LnJzdHVkaW8uY29tL10oUlN0dWRpb2xvZ28ucG5nKQ0KDQpFbCBfZW50b3Jub18gbcOhcyBjw7Ntb2RvIHBhcmEgdXRpbGl6YXIgZWwgX2xlbmd1YWplXyBfX1JfXyBlcyBlbCBfcHJvZ3JhbWFfIF9fUiBzdHVkaW9fXw0KDQotIFJzdHVkaW8gZXMgdW5hIGVtcHJlc2EgcXVlIHByb2R1Y2UgcHJvZHVjdG9zIGFzb2NpYWRvcyBhbCBsZW5ndWFqZSBSLCBjb21vIGVsIHByb2dyYW1hIHNvYnJlIGVsIHF1ZSBjb3JyZW1vcyBsb3MgY29tYW5kb3MsIHkgZXh0ZW5zaW9uZXMgZGVsIGxlbmd1YWplIChsaWJyZXLDrWFzKS4NCiANCi0gRWwgcHJvZ3JhbWEgZXMgX2dyYXR1aXRvXyB5IHNlIHB1ZWRlIGJhamFyIGRlIGxhIA0KW3DDoWdpbmEgb2ZpY2lhbF0oaHR0cHM6Ly93d3cucnN0dWRpby5jb20vKSANCg0KDQohW1BhbnRhbGxhIFJzdHVkaW9dKFBhbnRhbGxhIFJzdHVkaW8ucG5nKQ0KDQoNCiMjIERpZmVyZW5jaWFzIGNvbiBTVEFUQSB5IFNQU1MNCg0KLSBHcmF0dWl0bw0KLSDDmm5pY2FtZW50ZSBmdW5jaW9uYSBwb3IgbMOtbmVhcyBkZSBjw7NkaWdvIChObyBoYXkgYm90b25lcyBwYXJhIGVqZWN1dGFyIGNvbWFuZG9zKQ0KLSBQb3NpYmlsaXRhIHRyYWJhamFyIGNvbiBtw7psdGlwbGVzIGJhc2VzIGRlIG1pY3JvZGF0b3MgYWwgbWlzbW8gdGllbXBvLCBzaW4gbWF5b3IgZGlmaWN1bHRhZCAoTm8gcmVxdWllcmUgYWJyaXIgY2FkYSBiYXNlLCB0cmFiYWphcmxhIHBvciBzZXBhcmFkbyB5IGx1ZWdvIGNlcnJhcmxhKSANCi0gTcOhcyBwb3RlbnRlDQogICAgLSBUb3RhbG1lbnRlIGF1dG9tYXRpemFibGUNCiAgICAtIEFwb3J0ZXMgZGUgdXN1YXJpb3MgDQogICAgLSBFeHRlbnNpYmxlIGEgb3Ryb3MgbGVuZ3VhamVzIHkgdXNvcyAoUHJlc2VudGFjacOzbiBjb21vIGVzdGEsIGRpc2XDsW8gZGUgYXBsaWNhY2lvbmVzKQ0KLSBNw6FzIHZlbG96Og0KDQoNCiFbZnVlbnRlOiBodHRwczovL2dpdGh1Yi5jb20vbWF0dGhpZXVnb21lei9iZW5jaG1hcmstc3RhdGEtci9ibG9iL21hc3Rlci9vdXRwdXQvMWU3LnBuZ10oc3RhdGFSLnBuZykNCg0KDQoNCiMgTMOzZ2ljYSBzaW50w6FjdGljYS4NCg0KIyMgRGVmaW5pY2nDs24gZGUgb2JqZXRvcw0KTG9zIF9fT2JqZXRvcy9FbGVtZW50b3NfXyBjb25zdGl0dXllbiBsYSBjYXRlZ29yw61hIGVzY2VuY2lhbCBkZWwgUi4gRGUgaGVjaG8sIHRvZG8gZW4gUiBlcyB1biBvYmpldG8sIHkgc2UgYWxtYWNlbmEgY29uIHVuIG5vbWJyZSBlc3BlY8OtZmljbyBxdWUgKipubyBkZWJlIHBvc2VlciBlc3BhY2lvcyoqLiBVbiBuw7ptZXJvLCB1biB2ZWN0b3IsIHVuYSBmdW5jacOzbiwgbGEgcHJvZ3Jlc2nDs24gZGUgbGV0cmFzIGRlbCBhYmVjZWRhcmlvLCB1bmEgYmFzZSBkZSBkYXRvcywgdW4gZ3LDoWZpY28sIGNvbnN0aXR1eWVuIHBhcmEgUiBvYmpldG9zIGRlIGRpc3RpbnRvIHRpcG8uIExvcyBvYmpldG9zIHF1ZSB2YW1vcyBjcmVhbmRvIGEgbWVkaWRhIHF1ZSB0cmFiYWphbW9zIHB1ZWRlbiB2aXN1YWxpemFyc2UgZW4gbGEgcGFuZWwgZGVyZWNobyBzdXBlcmlvciBkZSBsYSBwYW50YWxsYS4gDQoNCkVsIG9wZXJhZG9yIF9fYGBgPC1gYGBfXyBzaXJ2ZSBwYXJhIGRlZmluaXIgdW4gb2JqZXRvLiAgX19BIGxhIGl6cXVpZXJkYV9fIGRlbCBfX2BgYDwtYGBgX18gZGViZSB1YmljYXJzZSBlbCBub21icmUgcXVlIHRvbWFyw6EgZWwgZWxlbWVudG8gYSBjcmVhci4gX19EZWwgbGFkbyBkZXJlY2hvX18gZGViZSBpciBsYSBkZWZpbmljacOzbiBkZWwgbWlzbW8NCg0KDQpgYGB7cn0NCkEgPC0gMQ0KYGBgDQoNCkFsIGRlZmluaXIgdW4gZWxlbWVudG8sIGVsIG1pc21vIHF1ZWRhIGd1YXJkYWRvIGVuIGVsIGFtYmllbnRlIGRlbCBwcm9ncmFtYSwgeSBwb2Ryw6Egc2VyIHV0aWxpemFkbyBwb3N0ZXJpb3JtZW50ZSBwYXJhIG9ic2VydmFyIHN1IGNvbnRlbmlkbyBvIHBhcmEgcmVhbGl6YXIgdW5hIG9wZXJhY2nDs24gY29uIGVsIG1pc21vDQoNCmBgYHtyfQ0KQSANCkErNg0KYGBgDQoNCkFsIGNvcnJlciB1bmEgbGluZWEgY29uIGVsIG5vbWJyZSBkZWwgb2JqZXRvLCBsYSBjb25zb2xhIGRlbCBwcm9ncmFtYSBub3MgbXVlc3RyYSBzdSBjb250ZW5pZG8uIEVudHJlIENvcmNoZXRlcyBPYnNlcnZhbW9zIGVsIG7Dum1lcm8gZGUgb3JkZW4gZGVsIGVsZW1lbnRvIGVuIGN1ZXN0acOzbg0KDQpFbCBvcGVyYWRvciBfX2BgYD1gYGBfXyBlcyBfX2VxdWl2YWxlbnRlX18gYSBfX2BgYDwtYGBgX18sIHBlcm8gZW4gbGEgcHLDoWN0aWNhIG5vIHNlIHV0aWxpemEgcGFyYSBsYSBkZWZpbmljacOzbiBkZSBvYmpldG9zLiAgIA0KDQpgYGB7cn0NCkIgPSAyDQpCDQpgYGANCg0KX19gYGA8LWBgYF9fIGVzIHVuIG9wZXJhZG9yIF9fVW5pZGlyZWNjaW9uYWxfXywgZXMgZGVjaXIgcXVlOiAgICAgDQpgYGBBIDwtIEJgYGAgaW1wbGljYSBxdWUgX19BX18gdmEgdG9tYXIgY29tbyB2YWxvciBlbCBjb250ZW5pZG8gZGVsIG9iamV0byBfX0JfXywgeSBubyBhbCByZXbDqXMuDQpgYGB7cn0NCkEgPC0gQg0KQSAgICNBaG9yYSBBIHRvbWEgZWwgdmFsb3IgZGUgQiwgeSBCIGNvbnRpbnVhIGNvbnNlcnZhbmRvIGVsIG1pc21vIHZhbG9yDQpCDQpgYGANCg0KDQojIyBSIGJhc2UNCg0KQ29uIF9SIGJhc2VfIG5vcyByZWZlcmltb3MgYSBsb3MgY29tYW5kb3MgYsOhc2ljb3MgcXVlIHZpZW5lbiBpbmNvcnBvcmFkb3MgZW4gZWwgUiwgc2luIG5lY2VzaWRhZCBkZSBjYXJnYXIgbGlicmVyw61hcy4gDQoNCiMjIE9wZXJhZG9yZXMgbMOzZ2ljb3M6IA0KDQotICQ+JA0KLSAkPj0kDQotICQ8JA0KLSAkPD0kDQotICQ9PSQNCi0gJCE9JA0KDQpgYGB7cn0NCiNSZWRlZmluaW1vcyBsb3MgdmFsb3JlcyBBIHkgQg0KQSA8LSAgMTANCkIgIDwtICAyMA0KI1JlYWxpemFtb3MgY29tcGFyYWNpb25lcyBsw7NnaWNhcw0KDQpBID4gIEINCkEgPj0gQg0KQSA8ICBCDQpBIDw9IEINCkEgPT0gQg0KQSAhPSBCDQoNCkMgPC0gQSAhPSBCDQpDDQpgYGANCg0KQ29tbyBtdWVzdHJhIGVsIMO6bHRpbW8gZWplbXBsbywgZWwgcmVzdWx0YWRvIGRlIHVuYSBvcGVyYWNpw7NuIGzDs2dpY2EgcHVlZGUgYWxtYWNlbmFyc2UgY29tbyBlbCB2YWxvciBkZSB1biBvYmpldG8uDQoNCiMjIE9wZXJhZG9yZXMgYXJpdG3DqXRpY29zOg0KDQpgYGB7cn0NCiNzdW1hDQpBIDwtIDUrNg0KQQ0KI1Jlc3RhDQpCIDwtIDYtOA0KQg0KI2NvY2llbnRlDQpDIDwtIDYvMi41DQpDDQojbXVsdGlwbGljYWNpb24NCkQgPC0gNioyLjUNCkQNCmBgYA0KIyMgRnVuY2lvbmVzOg0KTGFzIGZ1bmNpb25lcyBzb24gc2VyaWVzIGRlIHByb2NlZGltaWVudG9zIGVzdGFuZGFyaXphZG9zLCBxdWUgdG9tYW4gY29tbyBpbXB1dCBkZXRlcm1pbmFkb3MgYXJndW1lbnRvcyBhIGZpamFyIHBvciBlbCB1c3VhcmlvLCB5IGRldnVlbHZlbiB1biByZXN1bHRhZG8gYWNvcmRlIGEgbGEgYXBsaWNhY2nDs24gZGUgZGljaG9zIHByb2NlZGltaWVudG9zLiBTdSBsw7NnaWNhIGRlIGZ1bmNpb25hbWllbnRvIGVzOiAgIA0KYGBgZnVuY2lvbihhcmd1bWVudG8xID0gYXJnMSwgYXJndW1lbnRvMiA9IGFyZzIpYGBgICAgICAgDQoNCkEgbG8gbGFyZ28gZGVsIGN1cnNvIGlyZW1vcyB2aWVuZG8gbnVtZXJvc2FzIGZ1bmNpb25lcywgc2Vnw7puIGxvIHJlcXVpZXJhbiBsb3MgZGlzdGludG9zIGVqZXJjaWNpb3MuIFNpbiBlbWJhcmdvLCB2ZWFtb3MgYWhvcmEgYWxndW5vcyBlamVtcGxvcyBwYXJhIGNvbXByZW5kZXIgc3UgZnVuY2lvbmFtaWVudG86ICAgIA0KDQotIHBhc3RlKCkgOiBjb25jYXRlbmEgdW5hIHNlcmllIGRlIGNhcmFjdGVyZXMsIGluZGljYW5kbyBwb3Igw7psdGltYSBpbnN0YW5jaWEgY29tbyBzZXBhcmFyIGEgY2FkYSB1bm8gZGUgZWxsb3MgICAgICAgIA0KLSBwYXN0ZTAoKTogY29uY2F0ZW5hIHVuYSBzZXJpZSBkZSBjYXJhY3RlcmVzIHNpbiBzZXBhcmFyDQotIHN1bSgpOiBzdW1hIGRlIHRvZG9zIGxvcyBlbGVtZW50b3MgZGUgdW4gdmVjdG9yICAgDQotIG1lYW4oKSBwcm9tZWRpbyBhcml0bcOpdGljbyBkZSB0b2RvcyBsb3MgZWxlbWVudG9zIGRlIHVuIHZlY3RvciAgIA0KDQpgYGB7cn0NCnBhc3RlKCJQZWdhIiwiZXN0YXMiLDQsInBhbGFicmFzIiwgc2VwID0gIiAiKQ0KDQojUHVlZG8gY29uY2F0ZW5hciBjYXJhY3RlcmVzIGFsbWFjZW5hZG9zIGVuIG9iamV0b3MNCnBhc3RlKEEsQixDLHNlcCA9ICIqKiIpDQoNCiMgUGFzdGUwIHBlZ2EgbG9zIGNhcmFjdGVyZXMgc2luIHNlcGFyYWRvcg0KcGFzdGUwKEEsQixDKQ0KDQoxOjUNCg0Kc3VtKDE6NSkNCm1lYW4oMTo1LG5hLnJtID0gVFJVRSkNCmBgYA0KDQoNCiMjIENhcmFjdGVyZXMgZXNwZWNpYWxlcw0KDQotIFIgZXMgc2Vuc2libGUgYSBtYXnDunNjdWxhcyB5IG1pbsO6c2N1bGFzLCB0YW50byBwYXJhIGxvcyBub21icmVzIGRlIGxhcyB2YXJpYWJsZXMsIGNvbW8gcGFyYSBsYXMgZnVuY2lvbmVzIHkgcGFyw6FtZXRyb3MuDQotIExvcyBfX2VzcGFjaW9zIGVuIGJsYW5jb19fIHkgbG9zIF9fY2FycmlhZ2UgcmV0dXJuX18gKF9lbnRlcl8pIG5vIHNvbiBjb25zaWRlcmFkb3MgcG9yIGVsIGxlbmd1YWplLiBMb3MgcG9kZW1vcyBhcHJvdmVjaGFyIHBhcmEgZW1wcm9saWphciBlbCBjw7NkaWdvIHkgcXVlIGxhIGxlY3R1cmEgc2VhIG3DoXMgc2ltcGxlW14yXS4NCg0KW14yXTogdmVyZW1vcyBxdWUgZXhpc3RlbiBjaWVydGFzIGV4Y2VwY2lvbmVzIGNvbiBhbGd1bm9zIHBhcXVldGVzIG3DoXMgYWRlbGFudGUuIA0KDQotIEVsIF9fbnVtZXJhbF9fIGBgYCNgYGAgc2UgdXRpbGl6YSBwYXJhIGhhY2VyIGNvbWVudGFyaW9zLiBUb2RvIGxvIHF1ZSBzZSBlc2NyaWJlIGRlc3B1w6lzIGRlbCAjIG5vIGVzIGludGVycHJldGFkbyBwb3IgUi4gU2UgZGViZSB1dGlsaXphciB1biAjIHBvciBjYWRhIGzDrW5lYSBkZSBjw7NkaWdvIHF1ZSBzZSBkZXNlYSBhbnVsYXINCg0KLSBMb3MgX19jb3JjaGV0ZXNfXyBgYGBbXWBgYCBzZSB1dGlsaXphbiBwYXJhIGFjY2VkZXIgYSB1biBvYmpldG86DQogICAgLSBlbiB1biB2ZWN0b3JbbsKwIG9yZGVuXQ0KICAgIC0gZW4gdW5hIHRhYmxhW2ZpbGEsIGNvbHVtbmFdDQogICAgLSBlbiB1bmEgbGlzdGFbbsKwIGVsZW1lbnRvXQ0KLSBlbCBzaWdubyBfXyRfXyB0YW1iacOpbiBlcyB1biBtw6l0b2RvIGRlIGFjY2Vzby4gUGFydGljdWxhcm1lbnRlLCBlbiBsb3MgZGF0YWZyYW1lcywgbm9zIHBlcm1pdGlyYSBhY2NlZGVyIGEgdW5hIGRldGVybWluYWRhIGNvbHVtbmEgZGUgdW5hIHRhYmxhDQoNCi0gTG9zIF9fcGFyw6ludGVzaXNfX2BgYCgpYGBgIHNlIHV0aWxpemFuIGVuIGxhcyBmdW5jaW9uZXMgcGFyYSBkZWZpbmlyIGxvcyBwYXLDoW1ldHJvcy4NCg0KLSBMYXMgX19jb21hc19fIGBgYCwgYGBgICBzZSB1dGlsaXphbiBwYXJhIHNlcGFyYXIgbG9zIHBhcmFtZXRyb3MgYWwgaW50ZXJpb3IgZGUgdW5hIGZ1bmNpw7NuLiANCg0KIyMgT2JqZXRvczogICAgDQpFeGlzdGVuIHVuIGdyYW4gY2FudGlkYWQgZGUgb2JqZXRvcyBkaXN0aW50b3MgZW4gUiwgZW4gbG8gcXVlIHJlc2VwY3RhIGFsIGN1cnNvIHRyYWJhamFyZW1vcyBwcmluY2lwYWxtZW50ZSBjb24gMyBkZSBlbGxvczoNCg0KLSBWYWxvcmVzDQotIFZlY3RvcmVzDQotIERhdGEgRnJhbWVzDQotIExpc3Rhcw0KDQojIyMgVmFsb3Jlcw0KTG9zIHZhbG9yZXMgeSB2ZWN0b3JlcyBwdWVkZW4gc2VyIGEgc3UgdmV6IGRlIGRpc3RpbnRhcyBfY2xhc2VzXzogICANCg0KX19OdW1lcmljX18gICAgIA0KDQpgYGB7cn0NCkEgPC0gIDENCmNsYXNzKEEpDQpgYGANCg0KDQpfX0NoYXJhY3Rlcl9fDQpgYGB7cn0NCkEgPC0gIHBhc3RlKCdTb3knLCAndW5hJywgJ2NvbmNhdGVuYWNpw7NuJywgJ2RlJywgJ2NhcmFjdGVyZXMnLCBzZXAgPSAiICIpDQpBDQpjbGFzcyhBKQ0KYGBgDQoNCg0KDQpfX0ZhY3Rvcl9fDQpgYGB7cn0NCkEgPC0gZmFjdG9yKCJTb3kgdW4gZmFjdG9yLCBjb24gbml2ZWxlcyBmaWpvcyIpDQpjbGFzcyhBKQ0KYGBgDQoNCkxhIGRpZmVyZW5jaWEgZW50cmUgdW4gX2NoYXJhY3Rlcl8geSB1biBfZmFjdG9yXyBlcyBxdWUgZWwgw7psdGltbyB0aWVuZSBzb2xvIGFsZ3Vub3MgdmFsb3JlcyBwZXJtaXRpZG9zIChsZXZlbHMpLCBjb24gdW4gb3JkZW4gaW50ZXJubyBwcmVkZWZpbmlkbyAoZWwgY3VhbCAscG9yIGVqZW1wbG8sIHNlIHJlc3BldGFyw6EgYSBsYSBob3JhIGRlIHJlYWxpemFyIHVuIGdyw6FmaWNvKSAgDQoNCg0KIyMjIFZlY3RvcmVzDQoNClBhcmEgY3JlYXIgdW4gX192ZWN0b3JfXyB1dGlsaXphbW9zIGVsIGNvbWFuZG8gYGBgYygpYGBgLCBkZSBjb21iaW5hci4NCg0KYGBge3J9DQpDIDwtIGMoMSwgMywgNCkNCkMNCmBgYA0KDQpzdW1hcmxlICAyIGEgY2FkYSBlbGVtZW50byBkZWwgX192ZWN0b3JfXyBhbnRlcmlvcg0KDQpgYGB7cn0NCkMgPC0gQyArIDINCkMNCmBgYA0KDQpzdW1hcmxlICAxIGFsIHByaW1lciBlbGVtZW50bywgMiBhbCBzZWd1bmRvLCB5IDMgYWwgdGVyY2VyIGVsZW1lbnRvIGRlbCBfX3ZlY3Rvcl9fIGFudGVyaW9yDQpgYGB7cn0NCkQgPC0gQyArIDE6MyAjZXN0byBlcyBlcXVpdmFsZW50ZSBhIGhhY2VyIDMrMSwgNSsyLCA2KzkgDQpEDQpgYGANCg0KYGBgMTozYGBgIHNpZ25pZmljYSBxdWUgcXVlcmVtb3MgdG9kb3MgbG9zIG7Dum1lcm9zIGVudGVyb3MgZGVzZGUgMSBoYXN0YSAzLiANCg0KY3JlYXIgdW4gX192ZWN0b3JfXyBxdWUgY29udGVuZ2EgbGFzIHBhbGFicmFzOiAiQ2FybG9zIiwiRmVkZXJpY28iLCJQZWRybyINCmBgYHtyfQ0KRSA8LSBjKCJDYXJsb3MiLCJGZWRlcmljbyIsIlBlZHJvIikNCkUNCmBgYA0KDQpwYXJhIGFjY2VkZXIgYSBhbGfDum4gZWxlbWVudG8gZGVsIHZlY3RvciwgcG9kZW1vcyBidXNjYXJsbyBwb3Igc3UgbsO6bWVybyBkZSBvcmRlbiwgZW50cmUgYGBgWyBdYGBgDQoNCmBgYHtyfQ0KIEVbMl0NCg0KYGBgDQoNClNpIG5vcyBpbnRlcmVzYSBhbG1hY2VuYXIgZGljaG8gdmFsb3IsIGFsIGJ1c2NhcmxvIGxvIGFzaWduYW1vcyBhIHVuIG51ZXZvIG9iamV0bywgZGFuZG9sZSBlbCBub21icmUgcXVlIGRlc2VlbW9zDQoNCmBgYHtyfQ0KZWxlbWVudG8yIDwtICBFWzJdDQpgYGANCmBgYHtyfQ0KZWxlbWVudG8yDQpgYGANCg0KcGFyYSBfX2JvcnJhcl9fIHVuIG9iamV0byBkZWwgYW1iaWVudGUgZGUgdHJhYmFqbywgdXRpbGl6YW1vcyBlbCBjb21hbmRvIF9gYGBybSgpYGBgXw0KDQpgYGB7ciBlcnJvcj1UUlVFfQ0Kcm0oZWxlbWVudG8yKQ0KZWxlbWVudG8yDQpgYGANCg0KVGFtYmnDqW4gcG9kZW1vcyBjYW1iaWFyIGVsIHRleHRvIGRlbCBzZWd1bmRvIGVsZW1lbnRvIGRlIEUsIHBvciBlbCB0ZXh0byAiUGFibG8iDQoNCmBgYHtyfQ0KRVsyXSA8LSAiUGFibG8iDQpFDQpgYGANCg0KIyMjIERhdGEgRnJhbWVzDQoNClVuIERhdGEgRnJhbWUgZXMgdW5hIHRhYmxhIGRlIGRhdG9zLCBkb25kZSBjYWRhIGNvbHVtbmEgcmVwcmVzZW50YSB1bmEgdmFyaWFibGUsIHkgY2FkYSBmaWxhIHVuYSBvYnNlcnZhY2nDs24uDQoNCkVzdGUgb2JqZXRvIHN1ZWxlIHNlciBjZW50cmFsIGVuIGVsIHByb2Nlc28gZGUgdHJhYmFqbywgeSBzdWVsZSBzZXIgbGEgZm9ybWEgZW4gcXVlIHNlIGNhcmdhbiBkYXRvcyBleHRlcm5vcyBwYXJhIHRyYWJhamFyIGVuIGVsIGFtYmllbnRlIGRlIFIsIHkgZW4gcXVlIHNlIGV4cG9ydGFuIGxvcyByZXN1bHRhZG9zIGRlIG51ZXN0cm9zIHRyYWJham8uICANCg0KVGFtYmnDqW4gU2UgcHVlZGUgY3JlYXIgY29tbyBsYSBjb21iaW5hY2nDs24gZGUgTiB2ZWN0b3JlcyBkZSBpZ3VhbCB0YW1hw7FvLiBQb3IgZWplbXBsbywgdG9tYW1vcyBhbGd1bm9zIHZhbG9yZXMgZGVsIFtJbmRpY2UgZGUgc2FsYXJpb3NdKGh0dHA6Ly93d3cuaW5kZWMuZ29iLmFyL2JhamFyQ3VhZHJvRXN0YWRpc3RpY28uYXNwP2lkYz00MDIwQjMzNDQwNjA5NDYyNjU0NTQyQkQwQkMzMjBGMTUyM0RBMERDNTJDMzk2MjAxREI0REQ1ODYxRkZFREM5QUQxNDM2NjgxQUM4NDE3OSkNCg0KYGBge3J9DQpJTkRJQ0UgIDwtIGMoMTAwLCAgIDEwMCwgICAxMDAsDQogICAgICAgICAgICAgMTAxLjgsIDEwMS4yLCAxMDAuNzMsDQogICAgICAgICAgICAgMTAyLjksIDEwMi40LCAxMDMuMikNCg0KRkVDSEEgIDwtICBjKCJPY3QtMTYiLCAiT2N0LTE2IiwgIk9jdC0xNiIsDQogICAgICAgICAgICAgIk5vdi0xNiIsICJOb3YtMTYiLCAiTm92LTE2IiwNCiAgICAgICAgICAgICAiRGljLTE2IiwgIkRpYy0xNiIsICJEaWMtMTYiKQ0KDQoNCkdSVVBPICA8LSAgYygiUHJpdmFkb19SZWdpc3RyYWRvIiwiUMO6YmxpY28iLCJQcml2YWRvX05vX1JlZ2lzdHJhZG8iLA0KICAgICAgICAgICAgICJQcml2YWRvX1JlZ2lzdHJhZG8iLCJQw7pibGljbyIsIlByaXZhZG9fTm9fUmVnaXN0cmFkbyIsDQogICAgICAgICAgICAgIlByaXZhZG9fUmVnaXN0cmFkbyIsIlDDumJsaWNvIiwiUHJpdmFkb19Ob19SZWdpc3RyYWRvIikNCiAgICAgICAgICAgICANCg0KRGF0b3MgPC0gZGF0YS5mcmFtZShJTkRJQ0UsIEZFQ0hBLCBHUlVQTykNCkRhdG9zDQpgYGANCg0KVGFsIGNvbW8gZW4gdW4gX192ZWN0b3JfXyBzZSB1YmljYSBhIGxvcyBlbGVtZW50b3MgbWVkaWFudGUgYGBgWyBdYGBgLCBlbiB1biBfX2RhdGFmcmFtZV9fIHNlIG9idGllbmVuIHN1cyBlbGVtZW50b3MgZGUgbGEgZm9ybWEgX19gYGBbZmlsYSwgY29sdW1uYV1gYGBfXy4NCg0KT3RyYSBvcGNpw7NuIGVzIGVzcGVjaWZpY2FyIGxhIGNvbHVtbmEsIG1lZGlhbnRlIGVsIG9wZXJhZG9yIF9fYGBgJGBgYF9fLCB5IGx1ZWdvIHNlbGVjY2lvbmFyIGRlbnRybyBkZSBlc2EgY29sdW1uYSBlbCByZWdpc3RybyBkZXNlYWRvIG1lZGlhbnRlIGVsIG7Dum1lcm8gZGUgb3JkZW4uDQoNCmBgYHtyfQ0KRGF0b3MkRkVDSEENCkRhdG9zWzMsMl0NCkRhdG9zJEZFQ0hBWzNdDQpgYGANCg0Kwr9xdWUgcGFzYSBzaSBoYWNlbW9zIGBgYERhdG9zJEZFQ0hBWzMsMl1gYGAgPw0KDQpgYGB7ciBlcnJvcj1UUlVFfQ0KRGF0b3MkRkVDSEFbMywyXQ0KYGBgDQpOw7N0ZXNlIHF1ZSBlbCDDumx0aW1vIGNvbWFuZG8gdGllbmUgdW4gbsO6bWVybyBpbmNvcnJlY3RvIGRlIGRpbWVuc2lvbmVzLCBwb3JxdWUgZXN0YW1vcyByZWZpcmllbmRvbm9zIDIgdmVjZXMgYSBsYSBjb2x1bW5hIEZFQ0hBLiAgICANCg0KQWNvcmRlIGEgbG8gdmlzdG8gYW50ZXJpb3JtZW50ZSwgZWwgYWNjZXNvIGEgbG9zIF9fZGF0YWZyYW1lc19fIG1lZGlhbnRlICBgYGBbIF1gYGAsIHB1ZWRlIHV0aWxpemFyc2UgcGFyYSByZWFsaXphciBmaWx0cm9zIHNvYnJlIGxhIGJhc2UsIGVzcGVjaWZpY2FuZG8gdW5hIGNvbmRpY2nDs24gcGFyYSBsYXMgZmlsYXMuIFBvciBlamVtcGxvLCBwdWVkbyB1dGlsaXphciBsb3MgIGBgYFsgXWBgYCBwYXJhIGNvbnNlcnZhciBkZWwgX19kYXRhZnJhbWVfXyBgYGBEYXRvcyBgYGAgIHVuaWNhbWVudGUgbG9zIHJlZ2lzdHJvcyBjb24gZmVjaGEgZGUgRGljaWVtYnJlIDIwMTY6DQpgYGB7ciBlcnJvcj1UUlVFfQ0KRGF0b3NbRGF0b3MkRkVDSEE9PSJEaWMtMTYiLF0NCmBgYA0KTGEgbMOzZ2ljYSBkZWwgcGFzbyBhbnRlcmlvciBzZXLDrWE6IEFjY2VkbyBhbCBkYXRhZnJhbWUgYGBgRGF0b3NgYGAsIHBpZGllbmRvIMO6bmljYW1lbnRlIGNvbnNlcnZhciBsYXMgZmlsYXMgKHBvciBlc28gbGEgY29uZGljacOzbiBzZSB1YmljYSBhIGxhIF9penF1aWVyZGFfIGRlIGxhICBgYGAsIGBgYCkgcXVlIGN1bXBsYW4gZWwgcmVxdWlzaXRvIGRlIHBlcnRlbmVjZXIgYSBsYSBjYXRlZ29yw61hIF9fIkRpYy0xNiJfXyBkZSBsYSB2YXJpYWJsZSBfX0ZFQ0hBX18uICAgICAgDQpBw7puIG3DoXMsIHBvZHLDrWEgYXBsaWNhciBlbCBmaWx0cm8geSBhbCBtaXNtbyB0aWVtcG8gaWRlbnRpZmljYXIgdW5hIHZhcmlhYmxlIGRlIGludGVyw6lzIHBhcmEgbHVlZ28gcmVhbGl6YXIgdW4gY8OhbGN1bG8gc29icmUgYXF1ZWxsYS4gUG9yIGVqZW1wbG8sIHBvZHLDrWEgY2FsY3VsYXIgbGEgbWVkaWEgZGUgbG9zIGluZGljZXMgZW4gZWwgbWVzIGRlIERpY2llbWJyZS4gDQpgYGB7ciBlcnJvcj1UUlVFfQ0KIyMjUG9yIHNlcGFyYWRvDQpJbmRpY2VzX0RpYyA8LSBEYXRvcyRJTkRJQ0VbRGF0b3MkRkVDSEE9PSJEaWMtMTYiXQ0KSW5kaWNlc19EaWMNCmBgYA0KYGBge3IgZXJyb3I9VFJVRX0NCm1lYW4oSW5kaWNlc19EaWMpDQpgYGANCmBgYHtyIGVycm9yPVRSVUV9DQojIyMgVG9kbyBqdW50bw0KbWVhbihEYXRvcyRJTkRJQ0VbRGF0b3MkRkVDSEE9PSJEaWMtMTYiXSkNCmBgYA0KTGEgbMOzZ2ljYSBkZSBlc3RhIHNpbnRheGlzIHNlcsOtYTogIk1lIHF1ZWTDsyBjb24gbGEgdmFyaWFibGUgX19JTkRJQ0VfXywgY3VhbmRvIGxhIHZhcmlhYmxlIEZFQ0hBIHNlYSBpZ3VhbCBhIF9fIkRpYy0xNiJfXywgbHVlZ28gY2FsY3VsbyBsYSBtZWRpYSBkZSBkaWNob3MgdmFsb3JlcyINCg0KIyMjIExpc3Rhcw0KDQpDb250aWVuZW4gdW5hIGNvbmNhdGVuYWNpw7NuIGRlIG9iamV0b3MgZGUgY3VhbHF1aWVyIHRpcG8uIEFzw60gY29tbyB1biB2ZWN0b3IgY29udGllbmUgdmFsb3JlcywgdW4gZGF0YWZyYW1lIGNvbnRpZW5lIHZlY3RvcmVzLCB1bmEgbGlzdGEgcHVlZGUgY29udGVuZXIgZGF0YWZyYW1lcywgcGVybyB0YW1iacOpbiB2ZWN0b3JlcywgbyB2YWxvcmVzLCB5IF90b2RvIGVsbG8gYSBsYSB2ZXpfDQoNCmBgYHtyfQ0Kc3VwZXJsaXN0YSA8LSBsaXN0KEEsQixDLEQsRSxGRUNIQSwgREYgPSBEYXRvcywgSU5ESUNFLCBHUlVQTykNCnN1cGVybGlzdGENCmBgYA0KDQpQYXJhIGFjY2VkZXIgdW4gZWxlbWVudG8gZGUgdW5hIGxpc3RhLCBwb2RlbW9zIHV0aWxpemFyIGVsIG9wZXJhZG9yIF9fYGBgJGBgYF9fLCBxdWUgc2UgcHVlZGUgdXNhciBhIHN1IHZleiBkZSBmb3JtYSBpdGVyYXRpdmEgDQoNCmBgYHtyfQ0Kc3VwZXJsaXN0YSRERiRGRUNIQVsyXQ0KYGBgDQojIEluc3RhbGFjacOzbiBkZSBwYXF1ZXRlcyBjb21wbGVtZW50YXJpb3MgYWwgUiBCYXNlICAgICAgICAgIA0KDQpIYXN0YSBhcXXDrSBoZW1vcyB2aXN0byBtw7psdGlwbGVzIGZ1bmNpb25lcyBxdWUgZXN0w6FuIGNvbnRlbmlkYXMgZGVudHJvIGRlbCBsZW5ndWFqZSBiw6FzaWNvIGRlIFIuIEFob3JhIGJpZW4sIGFsIHRyYXRhcnNlIGRlIHVuIHNvZnR3YXJlIGxpYnJlLCBsb3MgdXN1YXJpb3MgZGUgUiBjb24gbcOhcyBleHBlcmllbmNpYSBjb250cmlidXllbiBzaXN0ZW3DoXRpY2FtZW50ZSBhIGV4cGFuZGlyIGVzdGUgbGVuZ3VhamUgbWVkaWFudGUgbGEgY3JlYWNpw7NuIHkgYWN0dWFsaXphY2nDs24gZGUgX19wYXF1ZXRlc19fIGNvbXBsZW1lbnRhcmlvcy4gTMOzZ2ljYW1lbnRlLCBsb3MgbWlzbW9zIG5vIGVzdMOhbiBpbmNsdWlkb3MgZW4gbGEgaW5zdGFsYWNpw7NuIGluaWNpYWwgZGVsIHByb2dyYW1hLCBwZXJvIHBvZGVtb3MgZGVzY2FyZ2FybG9zIGUgaW5zdGFsYXJsb3MgYWwgbWlzbW8gdGllbXBvIGNvbiBlbCBzaWd1aWVudGUgY29tYW5kbzogICANCmBgYCANCmluc3RhbGwucGFja2FnZXMoIm5vbWJyZV9kZWxfcGFxdWV0ZSIpIA0KYGBgDQpSZXN1bHRhIHJlY29tZW5kYWJsZSBfX2VqZWN1dGFyIGVzdGUgY29tYW5kbyBkZXNkZSBsYSBjb25zb2xhX18geWEgcXVlIHNvbG8gbmVjZXNpdGFyZW1vcyBjb3JyZXJsbyB1bmEgdmV6IGVuIG51ZXN0cmEgY29tcHV0YWRvcmEuIEFsIGVqZWN1dGFyIGVsIG1pc21vLCBzZSBkZXNjYXJnYXLDoW4gZGUgbGEgcGFnaW5hIGRlIFtDUkFOXSh3d3cuY3Jhbi5yLXByb2plY3Qub3JnKSBsb3MgYXJjaGl2b3MgY29ycmVzcG9uZGllbnRlcyBhbCBwYXF1ZXRlIGhhY2lhIGVsIGRpcmVjdG9yaW8gZW4gZG9uZGUgaGF5YW1vcyBpbnN0YWxhZG8gZWwgcHJvZ3JhbWEuIFTDrXBpY2FtZW50ZSBsb3MgYXJjaGl2b3Mgc2UgZW5jb250cmFyw6FuIGVuICoqQzpcUHJvZ3JhbSBGaWxlc1xSXFItMy41LjBcbGlicmFyeVwqKiwgc2llbXByZSBjb24gbGEgdmVyc2nDs24gZGVsIHByb2dyYW1hIGNvcnJlc3BvbmRpZW50ZS4gICAgICAgICAgICAgIA0KVW5hIHZleiBpbnN0YWxhZG8gZWwgcGFxdWV0ZSwgY2FkYSB2ZXogcXVlIGFicmFtb3MgdW5hIG51ZXZhIHNlc2nDs24gZGUgUiB5IHF1ZXJyYW1vcyB1dGlsaXphciBlbCBtaXNtbyBkZWJlbW9zICoqY2FyZ2FybG8gYWwgYW1iaWVudGUgZGUgdHJhYmFqbyoqIG1lZGlhbnRlIGxhIHNpZ3VpZW50ZSBmdW5jacOzbjoNCmBgYCANCmxpYnJhcnkobm9tYnJlX2RlbF9wYXF1ZXRlKQ0KYGBgDQpOw7N0ZXNlIHF1ZSBhbCBjYXJnYXIvYWN0aXZhciBlbCBwYXF1ZXRlIG5vIHNvbiBuZWNlc2FyaWFzIGxhcyBjb21pbGxhcy4NCg0KIyBMZWN0dXJhIHkgZXNjcml0dXJhIGRlIGFyY2hpdm9zDQoNCiMjIC5jc3YgIHkgIC50eHQNCg0KSGF5IF9fbXVjaGFzX18gZnVuY2lvbmVzIHBhcmEgbGVlciBhcmNoaXZvcyBkZSB0aXBvIF8udHh0XyB5IF8uY3N2Xy4gTGEgbWF5b3LDrWEgc8OzbG8gY2FtYmlhIGxvcyBwYXLDoW1ldHJvcyBxdWUgdmllbmVuIHBvciBkZWZhdWx0LiANCg0KRXMgaW1wb3J0YW50ZSB0ZW5lciBlbiBjdWVudGEgcXVlIHVuYSBiYXNlIGRlIGRhdG9zIHF1ZSBwcm92aWVuZSBkZSBhcmNoaXZvcyBfLnR4dF8sIG8gXy5jc3ZfIHB1ZWRlIHByZXNlbnRhciBkaWZlcmVuY2lhcyBlbiBjdWFudG8gYSBsb3Mgc2lndWllbnRlcyBwYXJhbWV0cm9zOg0KDQotIGVuY2FiZXphZG8NCi0gZGVsaW1pdGFkb3IgKGBgYCxgYGAsIHRhYiwgYGBgO2BgYCkNCi0gc2VwYXJhZG9yIGRlY2ltYWwgDQoNCg0KYGBgIA0KZGF0YWZyYW1lIDwtIHJlYWQuZGVsaW0oZmlsZSwgaGVhZGVyID0gVFJVRSwgc2VwID0gIlx0IiwgcXVvdGUgPSAiXCIiLCBkZWMgPSAiLiIsIGZpbGwgPSBUUlVFLCBjb21tZW50LmNoYXIgPSAiIiwgLi4uKSANCmBgYA0KDQpFamVtcGxvLiBMZXZhbnRhciBsYSBiYXNlIGluZGl2aWR1YWwgZGUgRVBIIGRlbCAxZXIgdHJpbWVzdHJlIDIwMTcNCg0KRW4gZWwgcGFyYW1ldHJvIGBmaWxlYCB0ZW5nbyBxdWUgZXNwZWNpZmljYXIgZWwgbm9tYnJlIGNvbXBsZXRvIGRlbCBhcmNoaXZvLCBpbmNsdXllbmRvIGVsIGRpcmVjdG9yaW8gZG9uZGUgc2UgZW5jdWVudHJhLiBMbyBtw6FzIHNlbmNpbGxvIGVzIGFicmlyIGNvbWlsbGFzLCBhcHJldGFyIGBUYWJgIHkgc2UgZGVzcGxpZWdhIGVsIG1lbsO6IGRlIGxhcyBjb3NhcyBxdWUgdGVuZW1vcyBlbiBlbCBkaXJlY3RvcmlvIGRlIHRyYWJham8uIFNpIHF1ZXJlbW9zIG1vdmVybm9zIGhhY2lhIGFycmliYSwgYWdyZWdhbW9zIGAuLi9gDQoNCg0KYGBge3IgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KaW5kaXZpZHVhbF90MTE3IDwtIHJlYWQudGFibGUoZmlsZSA9ICcuLi9GdWVudGVzL3VzdV9pbmRpdmlkdWFsX3QxMTcudHh0JyxzZXA9IjsiLCBkZWM9IiwiLCBoZWFkZXIgPSBUUlVFLCBmaWxsID0gVFJVRSkNCmluZGl2aWR1YWxfdDExNw0KYGBgDQpDb21vIHB1ZWRlIG9ic2VydmFyc2UgYXF1w60sIGxhcyBiYXNlcyBpbmRpdmlkdWFsZXMgZGUgbGEgRVBIIGN1ZW50YW4gY29uIG3DoXMgZGUgNTguMDAwIHJlZ2lzdHJvcyB5IDE3NyB2YXJpYWJsZXMuDQpBbCB0cmFiYWphciBjb24gYmFzZXMgZGUgbWljcm9kYXRvcywgcmVzdWx0YSBjb252ZW5pZW50ZSBjb250YXIgY29uIGFsZ3Vub3MgY29tYW5kb3MgcGFyYSB0ZW5lciB1bmEgbWlyYWRhIHLDoXBpZGEgZGUgbGEgYmFzZSwgYW50ZXMgZGUgY29tZW56YXIgYSByZWFsaXphciBsb3MgcHJvY2VzYW1pZW50b3MgcXVlIGRlc2VlbW9zLiAgICAgDQoNClZlYW1vcyBhbGd1bm9zIGRlIGVsbG9zOg0KDQpgYGB7cn0NCg0KI1ZpZXcoaW5kaXZpZHVhbF90MTE3KQ0KbmFtZXMoaW5kaXZpZHVhbF90MTE3KQ0Kc3VtbWFyeShpbmRpdmlkdWFsX3QxMTcpWyxjKDgsMTAsMzEsMTMzKV0NCmhlYWQoaW5kaXZpZHVhbF90MTE3KVssMTo1XQ0KDQpgYGANCg0KDQojIyBFeGNlbCANCg0KUGFyYSBsZWVyIHkgZXNjcmliaXIgYXJjaGl2b3MgZXhjZWwgZGViZW1vcyB1dGlsaXphciBsb3MgY29tYW5kb3MgcXVlIHZpZW5lbiBjb24gbGEgbGlicmVyw61hIG9wZW54bHN4DQoNCmBgYHtyLHdhcm5pbmc9RkFMU0V9DQoNCiMgaW5zdGFsbC5wYWNrYWdlcygib3Blbnhsc3giKSAjIHBvciDDum5pY2EgdmV6DQpsaWJyYXJ5KG9wZW54bHN4KSAjYWN0aXZhbW9zIGxhIGxpYnJlcsOtYQ0KDQojY3JlYW1vcyB1bmEgdGFibGEgY3VhbHF1aWVyYSBkZSBwcnVlYmENCnggPC0gMToxMA0KeSA8LSAxMToyMA0KdGFibGFfZGVfUiA8LSBkYXRhLmZyYW1lKHgseSkNCg0KIyBlc2NyaWJpbW9zIGVsIGFyY2hpdm8NCndyaXRlLnhsc3goIHggPSB0YWJsYV9kZV9SLCBmaWxlID0gImFyY2hpdm8ueGxzeCIscm93Lm5hbWVzID0gRkFMU0UpDQojRG9uZGUgbG8gZ3VhcmTDsz8gSGF5IHVuIGRpcmVjdG9yaW8gcG9yIGRlZmF1bHQgZW4gY2FzbyBkZSBxdWUgbm8gaGF5YW1vcyBkZWZpbmlkbyBhbGd1bm8uDQoNCiNnZXR3ZCgpDQoNCiNTaSBxdWVyZW1vcyBleHBvcnRhciBtdWx0aXBsZXMgZGF0YWZyYW1lcyBhIHVuIEV4Y2VsLCBkZWJlbW9zIGFybWFyIHByZXZpYW1lbnRlIHVuYSBsaXN0YSBkZSBlbGxvcy4gQ2FkYSBkYXRhZnJhbWUsIHNlIGd1YXJkYXLDoSBlbiB1bmEgcGVzdGHDsWEgZGUgZXhjZWwsIGN1eW8gbm9tYnJlIGNvcnJlc3BvbmRlcmEgYWwgcXVlIGRlZmluYW1vcyBwYXJhIGNhZGEgRGF0YWZyYW1lIGEgbGEgaG9yYSBkZSBjcmVhciBsYSBsaXN0YS4NCkxpc3RhX2FfZXhwb3J0YXIgPC0gbGlzdCgiSW5kaWNlcyBTYWxhcmlvcyIgPSBEYXRvcywNCiAgICAgICAgICAgICAgICAgICAgICAgICAiVGFibGEgTnVtZXJvcyIgPSB0YWJsYV9kZV9SKQ0KDQp3cml0ZS54bHN4KCB4ID0gTGlzdGFfYV9leHBvcnRhciwgZmlsZSA9ICJhcmNoaXZvXzJfaG9qYXMueGxzeCIscm93Lm5hbWVzID0gRkFMU0UpDQoNCiNsZWVtb3MgZWwgYXJjaGl2byBlc3BlY2lmaWNhbmRvIGxhIHJ1dGEgKG8gZWwgZGlyZWN0b3JpbyBwb3IgZGVmYXVsdCkgeSBlbCBub21icmUgZGUgbGEgaG9qYSBxdWUgY29udGllbmUgbG9zIGRhdG9zDQpJbmRpY2VzX1NhbGFyaW8gPC0gcmVhZC54bHN4KHhsc3hGaWxlID0gImFyY2hpdm9fMl9ob2phcy54bHN4IixzaGVldCA9ICJJbmRpY2VzIFNhbGFyaW9zIikNCiNhbHRlcm5hdGl2YW1lbnRlIHBvZGVtb3MgZXNwZWNpZmljYXIgZWwgbsO6bWVybyBkZSBvcmRlbiBkZSBsYSBob2phIHF1ZSBkZXNlYW1vcyBsZXZhbnRhcg0KSW5kaWNlc19TYWxhcmlvIDwtIHJlYWQueGxzeCh4bHN4RmlsZSA9ICJhcmNoaXZvXzJfaG9qYXMueGxzeCIsc2hlZXQgPSAxKQ0KSW5kaWNlc19TYWxhcmlvDQpgYGANCg0KDQoNCiMgQW1iaWVudGVzIGRlIHRyYWJham8NCg0KSGF5IGFsZ3VuYXMgY29zYXMgcXVlIHRlbmVtb3MgcXVlIHRlbmVyIGVuIGN1ZW50YSByZXNwZWN0byBkZWwgb3JkZW4gZGVsIGFtYmllbnRlIGVuIGVsIHF1ZSB0cmFiYWphbW9zOg0KDQotIFdvcmtpbmcgRGlyZWN0b3J5OiBFbCBkaXJlY3RvcmlvIGRlIHRyYWJham8sIHB1ZWRlbiB2ZXIgZWwgc3V5byBjb24gYGdldHdkKClgLCBlcyAqaGFjaWEgZG9uZGUgYXB1bnRhIGVsIGPDs2RpZ28qLCBwb3IgZWplbXBsbywgc2kgcXVpZXJlbiBsZWVyIHVuIGFyY2hpdm8sIGxhIHJ1dGEgZGVsIGFyY2hpdm8gdGllbmUgcXVlIGVzdGFyIGV4cGxpY2l0YWRhIGNvbW8gZWwgcmVjb3JyaWRvIGRlc2RlIGVsIFdvcmtpbmcgRGlyZWN0b3J5Lg0KLSBFbnZpcm9ubWVudDogRXN0byBlbmdsb2JhIHRhbnRvIGxhIGluZm9ybWFjacOzbiBxdWUgdGVuZW1vcyBjYXJnYWRhIGVuICpEYXRhKiB5ICpWYWx1ZXMqLCBjb21vIGxhcyBsaWJyZXLDrWFzIHF1ZSB0ZW5lbW9zIGNhcmdhZGFzIG1pZW50cmFzIHRyYWJhamFtb3MuIA0KDQpFcyBpbXBvcnRhbnRlIHF1ZSBtYW50ZW5nYW1vcyBiaWVuIGRlbGltaXRhZGFzIGVzdGFzIGNvc2FzIGVudHJlIGRpZmVyZW50ZXMgdHJhYmFqb3MsIHNpbm86DQoNCjEuIEVsIGRpcmVjdG9yaW8gcXVlZGEgcmVmZXJpZG8gYSB1biBsdWdhciBlc3BlY8OtZmljbyBlbiBudWVzdHJhIGNvbXB1dGFkb3JhLiANCiAgLSBTaSBzZSBsbyBjb21wYXJ0aW1vcyBhIG90cm8gKipzZSByb21wZSoqDQogIC0gU2kgY2FtYmlhbW9zIGRlIGNvbXB1dGFkb3JhICoqc2Ugcm9tcGUqKg0KICAtIFNpIGxvIGNhbWJpYW1vcyBkZSBsdWdhciAqKnNlIHJvbXBlKioNCiAgLSBTaSBwcmltZXJvIGFicmltb3Mgb3RybyBzY3JpcHQgKipzZSByb21wZSoqDQoyLiBUZW5lbW9zIG1lemNsYWRvcyByZXN1bHRhZG9zIGRlIGRpZmVyZW50ZXMgdHJhYmFqb3M6DQogIC0gTnVuY2Egc2FiZW1vcyBzaSBlc2EgdmFyaWFibGUvdGFibGEvbGlzdGEgc2UgY3JlbyBlbiBlc2Ugc2NyaXB0IHkgbm8gb3Rybw0KICAtIFBlcmRlbW9zIGVzcGFjaW8gZGUgbGEgbWVtb3JpYQ0KICAtIE5vIGVzdGFtb3Mgc2VndXJvcyBkZSBxdWUgZWwgc2NyaXB0IGNhcmd1ZSB0b2RhcyBsYXMgbGlicmVyw61hcyBxdWUgbmVjZXNpdGENCg0KUnN0dWRpbyB0aWVuZSB1bmEgaGVycmFtaWVudGEgbXV5IMO6dGlsIGRlIHRyYWJham8gcXVlIHNvbiBsb3MgKipwcm95ZWN0b3MqKi4gRXN0b3MgcGVybWl0ZW4gbWFudGVuZXIgdW4gYW1iaWVudGUgZGUgdHJhYmFqbyBkZWxpbWl0YWRvIHBvciBjYWRhIHVubyBkZSBudWVzdHJvcyB0cmFiYWpvcy4gRXMgZGVjaXI6DQoNCi0gRWwgZGlyZWN0b3JpbyBkZSB0cmFiYWpvIHNlIHJlZmllcmUgYSBkb25kZSBlc3RhIHViaWNhZG8gZWwgYXJjaGl2byAuUnByb2oNCi0gRWwgRW52aXJvbm1lbnQgZXMgZXNwZWPDrWZpY28gZGUgbnVlc3RybyBwcm95ZWN0by4NCg0KVW4gcHJveWVjdG8gbm8gZXMgdW4gc8OzbG8gc2NyaXB0LCBzaW5vIHRvZGEgdW5hIGNhcnBldGEgZGUgdHJhYmFqby4gDQoNCiFbbG9nbyBScG9qZWN0XShScHJvamVjdC5wbmcpDQoNClBhcmEgY3JlYXJsbywgdmFtb3MgYWwgbG9nbyBkZSBudWV2byBwcm9qZWN0byAoQXJyaWJhIGEgbGEgaXpxdWllcmRhIGRlIGxhIHBhbmF0YWxsYSksIHkgZWxlZ2ltb3MgbGEgY2FycGV0YSBkZSB0cmFiYWpvLiANCg0KDQojIFBhcXVldGVzIGEgdXRpbGl6YXIgYSBsbyBsYXJnbyBkZWwgY3Vyc286DQoNClBhcmEgcXVpZW5lcyBlc3RlbiB0cmFiYWphbmRvIGNvbiBzdXMgY29tcHV0YWRvcmFzIHBlcnNvbmFsZXMsIGRlamFtb3MgYSBjb250aW51YWNpw7NuIHVuIGxpc3RhZG8gZGUgbG9zIHBhcXVldGVzIGNvbXBsZW1lbnRhcmlvcyBkZWwgUiBiYXNlIHF1ZSB1dGlsaXphcmVtb3MgYSBsbyBsYXJnbyBkZWwgY3Vyc28uIENvbW8gbGEgaW5zdGFsYWNpw7NuIHJlcXVpZXJlIGRlc2NhcmdhciBtw7psdGlwbGVzIGFyY2hpdm9zIGRlIGludGVybmV0IHJlY29tZW5kYW1vcyBoYWNlcmxvIGN1YW5kbyBkaXNwb25nYW4gZGUgdW5hIGJ1ZW5hIGNvbmV4acOzbi4gQ29uIGVsIHNpZ3VpZW50ZSBjb21hbmRvIHBvZHLDrWFuIGluc3RhbGFybG9zIHRvZG9zIGRlIHVuYSB2ZXo6ICAgICAgIA0KYGBgDQppbnN0YWxsLnBhY2thZ2VzKGMoInRpZHl2ZXJzZSIsIm9wZW54bHN4IiwnZ2dwbG90MicsJ2dndGhlbWVzJywgJ2dncmVwZWwnLCdnZ2FsdCcsJ2thYmxlRXh0cmEnKSkNCmBgYA0KDQojIEVqZXJjaWNpb3MgcGFyYSBwcmFjdGljYXINCg0KPiBSZWluaWNpYXIgUiAoYFNlc3Npb24gLS0+IFJlc3RhcnQgUmApDQoNCi0gQ3JlYXIgdW4gT0JKRVRPIGxsYW1hZG8gX09CSkVUT18gZGVmaW5pZG8gY29tbyBlbCByZXN1bHRhZG8gZGUgbGEgc3VtYTogNSArIDYNCi0gQ3JlYXIgdW4gVkVDVE9SIF9WRUMwXyBxdWUgY29udGVuZ2EgbG9zIG7Dum1lcm9zIDEsIDMsIDQuDQotIENyZWFyIDMgdmVjdG9yZXMgKCBfVkVDMV8sIF9WRUMyXywgX1ZFQzNfKSBxdWUgc2VhbiB0cmFuc2Zvcm1hY2lvbmVzIGRlbCBhbnRlcmlvcg0KLSBDcmVhciAzIHZlY3RvcmVzIGNvbiBsYSBtaXNtYSBjYW50aWRhZCBkZSBlbGVtZW50b3MgcXVlIFZFQzAsIHBlcm8gY29uIHZhcmlhYmxlcyBzdHJpbmcgKHRleHRvKSAoIF9WRUM0XywgX1ZFQzVfLCBfVkVDNl8pLg0KLSBDcmVhciB1biBkYXRhZnJhbWUgX0RGUkFNRV8gY29tbyBjb21iaW5hY2nDs24gZGUgdG9kb3MgbG9zIF9fdmVjdG9yZXNfXyBjcmVhZG9zIHByZXZpYW1lbnRlDQoNCg0KLSBMZXZhbnRhciBsYSBiYXNlIEluZGl2aWR1YWwgZGVsIDFlciB0cmltZXN0cmUgZGUgMjAxNywgZGUgbGEgRVBIDQotIExldmFudGFyIGRlbCBFeGNlbCBsbGFtYWRvIENBTkFTVEFTIHF1ZSBzZSBlbmN1ZW50cmEgZW4gbGEgY2FycGV0YSBkZSBGdWVudGVzLCBsYSBob2phICJDQlQiIHkgZGVmaW5pcmxhIGNvbW8gX0hvamFDQlRfLiAgUHVlZGVuIHVzYXIgbGEgZnVuY2nDs24gX3JlYWQueGxzeF8gZGUgY3VhbHF1aWVyYSBkZSBsYXMgc2lndWllbnRlcyBsaWJyZXLDrWFzOg0KICAgIC0gVmlzdGEgZW4gY2xhc2U6IF9fb3Blbnhsc3hfXyANCiAgICAtIE90cmEgb3BjacOzbiBxdWUgdXRpbGl6YSBvdHJvcyBwYXJhbWV0cm9zOiBfX3JlYWR4bF9fDQoNCiMgRWplcmNpY2lvcyBkZSB0YXJlYQ0KQ3JlYXIgdW4gbnVldm8gc2NyaXB0IGVuIGxhIGNhcnBldGEgZGUgbGEgY2xhc2UgMSBub21icmFkbyAiTm9tYnJlX0FsdW1ub19UYXJlYV9DMS5SIiwgeSByZWFsaXphciBsb3Mgc2lndWllbnRlcyBwcm9jZWRpbWllbnRvczogICAgICAgICAgICANCg0KLSBDcmVhciB1biBPQkpFVE8gbGxhbWFkbyBfQ09TQV8gZGVmaW5pZG8gY29tbyBlbCByZXN1bHRhZG8gZGUgbGEgbXVsdGlwbGljYWNpw7NuOiA1KjYNCi0gQ3JlYXIgdW4gVkVDVE9SIF9WRUNUT1IwXyBxdWUgY29udGVuZ2EgbG9zIG7Dum1lcm9zIDEwLCAyMCwgMzAuDQotIE1vZGlmaWNhciBlbCBzZWd1bmRvIGVsZW1lbnRvIGRlbCBfVkVDVE9SMF8sIGFzaWduYW5kb2xlIGVsIHZhbG9yICo0MCoNCi0gQ3JlYXIgMyB2ZWN0b3JlcyBjb24gbGEgbWlzbWEgY2FudGlkYWQgZGUgZWxlbWVudG9zIHF1ZSBWRUMwLCBwZXJvIGNvbiB2YXJpYWJsZXMgc3RyaW5nICh0ZXh0bykgKCBfVkVDVE9SMV8sIF9WRUNUT1IyXywgX1ZFQ1RPUjNfKS4NCi0gQ3JlYXIgdW4gZGF0YWZyYW1lIF9EQVRBRl8gY29tbyBjb21iaW5hY2nDs24gZGUgdG9kb3MgbG9zIF9fdmVjdG9yZXNfXyBjcmVhZG9zIHByZXZpYW1lbnRlDQotIENyZWFyIHVuIG9iamV0byBsbGFtYWRvICpPVFJBX0NPU0EqIHF1ZSBndWFyZGUgZWwgdmFsb3IgY29udGVuaWRvIGVuIGxhIHNlZ3VuZGEgZmlsYSB5IHRlcmNlcmEgY29sdW1uYSBkZWwgZGF0YWZyYW1lIF9EQVRBRl8NCg0KLSBMZXZhbnRhciBsYSBiYXNlIEluZGl2aWR1YWwgZGVsIDR0byB0cmltZXN0cmUgZGUgMjAxNiwgZGUgbGEgRVBIDQotIExldmFudGFyIGRlbCBFeGNlbCBsbGFtYWRvIENBTkFTVEFTIHF1ZSBzZSBlbmN1ZW50cmEgZW4gbGEgY2FycGV0YSBkZSBGdWVudGVzLCBsYSBob2phICJDQkEiIHkgZGVmaW5pcmxhIGNvbW8gX0hvamFDQkFfLg==