Introducción

En este documento se verán aspectos básicos del uso de R y RStudio.

Objetos

En la sección anterior se mencionó que el Environment muestra los objetos creados. En R se puede crear objetos y luego manipularlos. Por ejemplo, el gráfico 1.1 muestra el porcentaje de personas que apoyan a la democracia en cada país. Si queremos guardar el resultados de Uruguay (UY), podemos crear un objeto.

La siguiente línea de código crea un objeto llamado “UY” que almacena el número 80. Esto objeto se muestra en el Environment, tanto el nombre, como el valor que almacena.

UY = 80

Si quisiéramos calcular la diferencia en porcentaje entre Uruguay, el país que muestra el mayor apoyo a la democracia, y Haití, el que muestra el menor porcentaje, se puede calcular haciendo la resta del objeto menos el valor del porcentaje en Haití. Cuando se corre este código, RStudio nos muestra el resultado. Otra opción es crear un objeto HT que almacene el valor de 46.

UY - 46
## [1] 34

Los objetos en R no solo almacenan números, sino que también pueden guardar cadenas de caracteres.

El Barómetro de las Américas recoge información de casi todos los países de las Américas. La tabla siguiente muestra los países en los que se ha recogido información en alguna ronda.

Si queremos guardar el nombre de un país en un objeto, se puede nombrar al objeto “pais1” y escribir el nombre del país (que es una cadena de caracteres) entre comillas.

pais1 = "México"

Como se observa, el nombre del objeto no lleva tilde en la palabra “país”. Es posible crear un objeto con tildes, pero se recomienda no hacerlo pues puede crear problemas posteriores. La cadena de caracteres “México” sí incluye la tilde. Esto no representa ningún problema.

Vectores

Un vector es un objeto que contiene un conjunto de elementos, sean números o cadenas de caracteres, entre otros. Estos datos tienen que ser concatenados. Por este motivo, la función c(...) antecede a la serie de números.

Por ejemplo, podemos crear un vector que almacene todos los porcentajes del Gráfico 1.1.

apoyo = c(80, 73, 71, 69, 68, 67, 66, 63, 63, 63, 62, 61, 61, 57, 53, 52, 50, 50, 49, 46)

De manera similar, podemos crear un vector con los nombres (o siglas) de los países, entre comillas e incluidos en la función c(…).

pais = c("UY", "SV", "CR", "AR", "CL", "BR", "GY", "MX", "EC", "NI", "DO", "PN", "BO", "JA", "CO", "GT", "PY", "PE", "HN", "HT")

No es necesario seguir el mismo orden del gráfico; sin embargo, es recomendable por razones que se explicarán más abajo.

Se puede seleccionar elementos particulares de un vector usando […]. Por ejemplo, si queremos seleccionar el país de Argentina, tanto su nombre, como su porcentaje, se tiene que colocar entre corchetes la posición en la que se encuentra.

pais[4]
## [1] "AR"
apoyo[4]
## [1] 69

Funciones

Una función es un procedimiento que recibe un input y produce un output. Por ejemplo, la función Y = X^2, recibe un valor X cualquiera, por ejemplo 2, y devuelve un valor Y, en este caso 4. En R se tienen las funciones algebraicas, como raíz cuadrada o logaritmo. Por ejemplo, la función log(…) recibe un valor X y devuelve un valor Y igual al logaritmo de X.

sqrt(36) #por squared root
## [1] 6
log(20)
## [1] 2.995732

También se puede aplicar una función a un conjunto de datos, como los almacenados en un vector. Por ejemplo, si quisiéramos calcular la tasa de personas que apoya a la democracia por cada 1000 habitantes en todos los países, tendríamos que multiplicar el vector “apoyo” por 10. En este caso, la función de multiplicación se aplica a cada elemento del vector.

apoyo2 = apoyo*10
apoyo2
##  [1] 800 730 710 690 680 670 660 630 630 630 620 610 610 570 530 520 500 500 490
## [20] 460

Hay otras funciones que resultan más útiles para nuestros objetivos porque trabajan sobre un conjunto de valores, como los almacenados en un vector, calculando un valor único. Por ejemplo, si queremos calcular el apoyo a la democracia promedio en todos los países mostrados en el Gráfico 1.1 se puede usar la función mean(…).

mean(apoyo)
## [1] 61.2

Esta función recibe todos los valores de un vector, los suma y los divide entre el número de observaciones, mostrando la media.

Otra funciones muy usadas en estadística son la mediana, la desviación estándar, el mínimo, el máximo y la suma.

median(apoyo)
## [1] 62.5
sd(apoyo)
## [1] 9.070484
min(apoyo)
## [1] 46
max(apoyo)
## [1] 80
sum(apoyo)
## [1] 1224

El Gráfico 1.1 muestra los resultados para los países donde se tiene información. Sin embargo, en algunos casos un vector puede incluir un valor perdido. Por ejemplo, el gráfico no muestra información para Venezuela, país donde no se realizó trabajo de campo por motivos de seguridad. Si quisiéramos crear un vector que incluya este valor faltante (NA en el lenguaje R), se podría hacer así:

apoyo2 = c(apoyo, NA)
apoyo2
##  [1] 80 73 71 69 68 67 66 63 63 63 62 61 61 57 53 52 50 50 49 46 NA

En el procedimiento que hemos realizado hemos usado el mismo nombre “apoyo2”, por lo que hemos sobreescrito el vector con estos nuevos resultados. La cadena de número ahora incluye un valor final NA.

Algunas funciones no pueden calcular directamente su procedimiento en vectores que contienen valores NA. Por ejemplo, la función mean.

mean(apoyo2)
## [1] NA

El cálculo directo de la media del vector “apoyo2” nos devuelve un resultado NA. Para poder hacer el cálculo, indicándole a la función que no tome en cuenta este valor NA, se tiene que usar la especificación na.rm=True.

mean(apoyo2, na.rm=T)
## [1] 61.2

Paquetes

R es un proyecto colaborativo. Muchos desarrolladores producen nuevos paquetes que son administrados por el mismo proyecto de R. Estos paquetes pueden incluir muchas funciones que ayudan a manejar datos.

R tiene funciones nativas para importar bases de datos de diferentes formatos, como Excel, SPSS o Stata. Cada formato tiene una función específica, como read_csv o read_dta. Sin embargo, unos desarrolladores han producido un paquete llamado “rio” que incluye una función import que permite importar cualquier tipo de base de datos. Este paquete no viene instalado en la descarga básica de R, por lo que se tiene que instalar el paquete para poder usarlo.

Para instalar un paquete se usa el comando install.packages con el nombre del paquete que se quiere instalar entre comillas. En este caso hemos usado un # antes del código debido a que ya se tiene instalado el paquete. Para mostrar los comentarios o líneas de código que queremos mostrar, pero que no se corran, se pueden hacer con un # antes del comentario o código.

# install.packages("rio")

Una vez instalado, se tiene que activar el paquete para poder usar sus funciones. Esto se hace con el comando library. Una vez activado, se puede usar cualquier función de esta librería, como la función import. Para activar ya no se requiere comillas. Este procedimiento se puede verificar en el panel inferior derecho, en la pestaña “Packages”. El paquete “rio” aparece con un check.

library(rio)

Dataframes

Los dataframes son estructuras de datos rectangulares. Como convención, los dataframes tienen en sus columnas a los vectores (o variables) y en las filas a las observaciones. Para crear un dataframe se usa el comando data.frame(...).

Por ejemplo, podemos crear un dataframe que junte los datos del vector “pais” con los del vector “apoyo”. Estos dos vectores tienen que tener las mismas dimensiones. Vemos en el Environment que ambos tienen como dimensión [1:20]. Este dataframe se puede guardar en un objeto “apoyoAL”.

apoyoAL = data.frame(pais, apoyo)
apoyoAL
##    pais apoyo
## 1    UY    80
## 2    SV    73
## 3    CR    71
## 4    AR    69
## 5    CL    68
## 6    BR    67
## 7    GY    66
## 8    MX    63
## 9    EC    63
## 10   NI    63
## 11   DO    62
## 12   PN    61
## 13   BO    61
## 14   JA    57
## 15   CO    53
## 16   GT    52
## 17   PY    50
## 18   PE    50
## 19   HN    49
## 20   HT    46

Vemos que el objeto “apoyoAL” se ha guardado en una sección aparte del Environment que se llama “Data”. Este objeto tiene 20 observaciones (es decir, 20 filas o países) y dos variables (es decir, dos vectores o dos columnas). Se puede hacer click en este objeto y se puede ver la plancha de datos en una pestaña aparte.

Si se quisiera hacer un dataframe con los vectores “pais” y “apoyo2”, R nos daría un mensaje de error debido a que estos vectores tienen diferentes dimensiones.

Ahora, el vector “apoyo” forma parte de la base de datos “apoyoAL”. Para poder usar las funciones en un dataframe se debe especificar la columna de la que se quiere calcular la función. Por ejemplo, si ahora se quisiera calcular el promedio de apoyo a la democracia desde la base de datos “apoyoAL” se tiene que especificar la variable (o vector) con “$”.

mean(apoyoAL$apoyo)
## [1] 61.2

En general, cualquier base de datos es una estructura rectangular donde en las filas tenemos las observaciones y en las columnas, las variables, lo que cambia es el número de filas y de columnas.

Por ejemplo, una base de datos del Barómetro de las Américas de un país puede tener 1,500 observaciones (1,500 filas) y más de 100 variables (más de 100 columnas o vectores). En ese caso, cada observación corresponde a una persona que respondió la encuesta y una columna (o vector de datos) representa las respuestas de todos los entrevistados a una pregunta del cuestionario.

Es más, la base de datos conjunta (el merge de datos) es la base de datos de todos los países en una ronda. Esta base de datos puede tener más de 30 mil observaciones (es decir, todos los entrevistados en todos los países en una ronda determinada) y más de 100 columnas.

Más allá del tamaño de la base de datos, las columnas son vectores a los que se les puede aplicar funciones.

En la siguiente sección sobre importación de los datos del Barómetro de las Américas en RStudio se verá la manera de descargar una base de datos del proyecto y cargarla en RStudio.

Resumen

En este documento se han revisado los elementos básico de R, como objetos y vectores, y las funciones básicas que se pueden aplicar a estos objetos. También se ha revisado la manera de instalar librerías y de activarlas para poder usar sus funciones. Finalmente, se ha explicado la idea de un dataframe.

LS0tCnRpdGxlOiAiUHJvY2VkaW1pZW50b3MgYsOhc2ljYXMiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIHRvY19kZXB0aDogMQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IGZsYXRseQogICAgI2NvZGVfZm9sZGluZzogaGlkZQplZGl0b3Jfb3B0aW9uczogCiAgbWFya2Rvd246IAogICAgd3JhcDogc2VudGVuY2UKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSwgY2FjaGU9VFJVRSkKYGBgCgpgYGB7Y3NzIGNvbG9yLCBlY2hvPUZBTFNFfQouY29sdW1ucyB7ZGlzcGxheTogZmxleDt9CmgxIHtjb2xvcjogIzMzNjZDQzt9CmBgYAoKIyBJbnRyb2R1Y2Npw7NuCgpFbiBlc3RlIGRvY3VtZW50byBzZSB2ZXLDoW4gYXNwZWN0b3MgYsOhc2ljb3MgZGVsIHVzbyBkZSBSIHkgUlN0dWRpby4KCiMgT2JqZXRvcwoKRW4gbGEgc2VjY2nDs24gYW50ZXJpb3Igc2UgbWVuY2lvbsOzIHF1ZSBlbCBFbnZpcm9ubWVudCBtdWVzdHJhIGxvcyBvYmpldG9zIGNyZWFkb3MuCkVuIFIgc2UgcHVlZGUgY3JlYXIgb2JqZXRvcyB5IGx1ZWdvIG1hbmlwdWxhcmxvcy4KUG9yIGVqZW1wbG8sIGVsIGdyw6FmaWNvIDEuMSBtdWVzdHJhIGVsIHBvcmNlbnRhamUgZGUgcGVyc29uYXMgcXVlIGFwb3lhbiBhIGxhIGRlbW9jcmFjaWEgZW4gY2FkYSBwYcOtcy4KU2kgcXVlcmVtb3MgZ3VhcmRhciBlbCByZXN1bHRhZG9zIGRlIFVydWd1YXkgKFVZKSwgcG9kZW1vcyBjcmVhciB1biBvYmpldG8uCgohW10oR3JhZmljbzEuMS5wbmcpCgpMYSBzaWd1aWVudGUgbMOtbmVhIGRlIGPDs2RpZ28gY3JlYSB1biBvYmpldG8gbGxhbWFkbyAiVVkiIHF1ZSBhbG1hY2VuYSBlbCBuw7ptZXJvIDgwLgpFc3RvIG9iamV0byBzZSBtdWVzdHJhIGVuIGVsIEVudmlyb25tZW50LCB0YW50byBlbCBub21icmUsIGNvbW8gZWwgdmFsb3IgcXVlIGFsbWFjZW5hLgoKYGBge3Igb2JqZXRvfQpVWSA9IDgwCmBgYAoKU2kgcXVpc2nDqXJhbW9zIGNhbGN1bGFyIGxhIGRpZmVyZW5jaWEgZW4gcG9yY2VudGFqZSBlbnRyZSBVcnVndWF5LCBlbCBwYcOtcyBxdWUgbXVlc3RyYSBlbCBtYXlvciBhcG95byBhIGxhIGRlbW9jcmFjaWEsIHkgSGFpdMOtLCBlbCBxdWUgbXVlc3RyYSBlbCBtZW5vciBwb3JjZW50YWplLCBzZSBwdWVkZSBjYWxjdWxhciBoYWNpZW5kbyBsYSByZXN0YSBkZWwgb2JqZXRvIG1lbm9zIGVsIHZhbG9yIGRlbCBwb3JjZW50YWplIGVuIEhhaXTDrS4KQ3VhbmRvIHNlIGNvcnJlIGVzdGUgY8OzZGlnbywgUlN0dWRpbyBub3MgbXVlc3RyYSBlbCByZXN1bHRhZG8uCk90cmEgb3BjacOzbiBlcyBjcmVhciB1biBvYmpldG8gSFQgcXVlIGFsbWFjZW5lIGVsIHZhbG9yIGRlIDQ2LgoKYGBge3IgcmVzdGF9ClVZIC0gNDYKYGBgCgpMb3Mgb2JqZXRvcyBlbiBSIG5vIHNvbG8gYWxtYWNlbmFuIG7Dum1lcm9zLCBzaW5vIHF1ZSB0YW1iacOpbiBwdWVkZW4gZ3VhcmRhciBjYWRlbmFzIGRlIGNhcmFjdGVyZXMuCgpFbCBCYXLDs21ldHJvIGRlIGxhcyBBbcOpcmljYXMgcmVjb2dlIGluZm9ybWFjacOzbiBkZSBjYXNpIHRvZG9zIGxvcyBwYcOtc2VzIGRlIGxhcyBBbcOpcmljYXMuCkxhIHRhYmxhIHNpZ3VpZW50ZSBtdWVzdHJhIGxvcyBwYcOtc2VzIGVuIGxvcyBxdWUgc2UgaGEgcmVjb2dpZG8gaW5mb3JtYWNpw7NuIGVuIGFsZ3VuYSByb25kYS4KCiFbXShwYWlzLnBuZyl7d2lkdGg9IjU1MiJ9CgpTaSBxdWVyZW1vcyBndWFyZGFyIGVsIG5vbWJyZSBkZSB1biBwYcOtcyBlbiB1biBvYmpldG8sIHNlIHB1ZWRlIG5vbWJyYXIgYWwgb2JqZXRvICJwYWlzMSIgeSBlc2NyaWJpciBlbCBub21icmUgZGVsIHBhw61zIChxdWUgZXMgdW5hIGNhZGVuYSBkZSBjYXJhY3RlcmVzKSBlbnRyZSBjb21pbGxhcy4KCmBgYHtyIHBhaXN9CnBhaXMxID0gIk3DqXhpY28iCmBgYAoKQ29tbyBzZSBvYnNlcnZhLCBlbCBub21icmUgZGVsIG9iamV0byBubyBsbGV2YSB0aWxkZSBlbiBsYSBwYWxhYnJhICJwYcOtcyIuCkVzIHBvc2libGUgY3JlYXIgdW4gb2JqZXRvIGNvbiB0aWxkZXMsIHBlcm8gc2UgcmVjb21pZW5kYSBubyBoYWNlcmxvIHB1ZXMgcHVlZGUgY3JlYXIgcHJvYmxlbWFzIHBvc3RlcmlvcmVzLgpMYSBjYWRlbmEgZGUgY2FyYWN0ZXJlcyAiTcOpeGljbyIgc8OtIGluY2x1eWUgbGEgdGlsZGUuCkVzdG8gbm8gcmVwcmVzZW50YSBuaW5nw7puIHByb2JsZW1hLgoKIyBWZWN0b3JlcwoKVW4gdmVjdG9yIGVzIHVuIG9iamV0byBxdWUgY29udGllbmUgdW4gY29uanVudG8gZGUgZWxlbWVudG9zLCBzZWFuIG7Dum1lcm9zIG8gY2FkZW5hcyBkZSBjYXJhY3RlcmVzLCBlbnRyZSBvdHJvcy4KRXN0b3MgZGF0b3MgdGllbmVuIHF1ZSBzZXIgY29uY2F0ZW5hZG9zLgpQb3IgZXN0ZSBtb3Rpdm8sIGxhIGZ1bmNpw7NuIGBjKC4uLilgIGFudGVjZWRlIGEgbGEgc2VyaWUgZGUgbsO6bWVyb3MuCgpQb3IgZWplbXBsbywgcG9kZW1vcyBjcmVhciB1biB2ZWN0b3IgcXVlIGFsbWFjZW5lIHRvZG9zIGxvcyBwb3JjZW50YWplcyBkZWwgR3LDoWZpY28gMS4xLgoKYGBge3IgdmVjdG9yIHBvcmNlbnRhamVzfQphcG95byA9IGMoODAsIDczLCA3MSwgNjksIDY4LCA2NywgNjYsIDYzLCA2MywgNjMsIDYyLCA2MSwgNjEsIDU3LCA1MywgNTIsIDUwLCA1MCwgNDksIDQ2KQpgYGAKCkRlIG1hbmVyYSBzaW1pbGFyLCBwb2RlbW9zIGNyZWFyIHVuIHZlY3RvciBjb24gbG9zIG5vbWJyZXMgKG8gc2lnbGFzKSBkZSBsb3MgcGHDrXNlcywgZW50cmUgY29taWxsYXMgZSBpbmNsdWlkb3MgZW4gbGEgZnVuY2nDs24gYGMo4oCmKWAuCgpgYGB7ciB2ZWN0b3IgcGFpc30KcGFpcyA9IGMoIlVZIiwgIlNWIiwgIkNSIiwgIkFSIiwgIkNMIiwgIkJSIiwgIkdZIiwgIk1YIiwgIkVDIiwgIk5JIiwgIkRPIiwgIlBOIiwgIkJPIiwgIkpBIiwgIkNPIiwgIkdUIiwgIlBZIiwgIlBFIiwgIkhOIiwgIkhUIikKYGBgCgpObyBlcyBuZWNlc2FyaW8gc2VndWlyIGVsIG1pc21vIG9yZGVuIGRlbCBncsOhZmljbzsgc2luIGVtYmFyZ28sIGVzIHJlY29tZW5kYWJsZSBwb3IgcmF6b25lcyBxdWUgc2UgZXhwbGljYXLDoW4gbcOhcyBhYmFqby4KClNlIHB1ZWRlIHNlbGVjY2lvbmFyIGVsZW1lbnRvcyBwYXJ0aWN1bGFyZXMgZGUgdW4gdmVjdG9yIHVzYW5kbyBgW+KApl1gLgpQb3IgZWplbXBsbywgc2kgcXVlcmVtb3Mgc2VsZWNjaW9uYXIgZWwgcGHDrXMgZGUgQXJnZW50aW5hLCB0YW50byBzdSBub21icmUsIGNvbW8gc3UgcG9yY2VudGFqZSwgc2UgdGllbmUgcXVlIGNvbG9jYXIgZW50cmUgY29yY2hldGVzIGxhIHBvc2ljacOzbiBlbiBsYSBxdWUgc2UgZW5jdWVudHJhLgoKYGBge3Igc2VsZWNjaW9uYXIgdmVjdG9yfQpwYWlzWzRdCmFwb3lvWzRdCmBgYAoKIyBGdW5jaW9uZXMKClVuYSBmdW5jacOzbiBlcyB1biBwcm9jZWRpbWllbnRvIHF1ZSByZWNpYmUgdW4gaW5wdXQgeSBwcm9kdWNlIHVuIG91dHB1dC4KUG9yIGVqZW1wbG8sIGxhIGZ1bmNpw7NuIFkgPSBYXF4yLCByZWNpYmUgdW4gdmFsb3IgWCBjdWFscXVpZXJhLCBwb3IgZWplbXBsbyAyLCB5IGRldnVlbHZlIHVuIHZhbG9yIFksIGVuIGVzdGUgY2FzbyA0LgpFbiBSIHNlIHRpZW5lbiBsYXMgZnVuY2lvbmVzIGFsZ2VicmFpY2FzLCBjb21vIHJhw616IGN1YWRyYWRhIG8gbG9nYXJpdG1vLgpQb3IgZWplbXBsbywgbGEgZnVuY2nDs24gYGxvZyjigKYpYCByZWNpYmUgdW4gdmFsb3IgWCB5IGRldnVlbHZlIHVuIHZhbG9yIFkgaWd1YWwgYWwgbG9nYXJpdG1vIGRlIFguCgpgYGB7ciByYWl6fQpzcXJ0KDM2KSAjcG9yIHNxdWFyZWQgcm9vdApsb2coMjApCmBgYAoKVGFtYmnDqW4gc2UgcHVlZGUgYXBsaWNhciB1bmEgZnVuY2nDs24gYSB1biBjb25qdW50byBkZSBkYXRvcywgY29tbyBsb3MgYWxtYWNlbmFkb3MgZW4gdW4gdmVjdG9yLgpQb3IgZWplbXBsbywgc2kgcXVpc2nDqXJhbW9zIGNhbGN1bGFyIGxhIHRhc2EgZGUgcGVyc29uYXMgcXVlIGFwb3lhIGEgbGEgZGVtb2NyYWNpYSBwb3IgY2FkYSAxMDAwIGhhYml0YW50ZXMgZW4gdG9kb3MgbG9zIHBhw61zZXMsIHRlbmRyw61hbW9zIHF1ZSBtdWx0aXBsaWNhciBlbCB2ZWN0b3IgImFwb3lvIiBwb3IgMTAuCkVuIGVzdGUgY2FzbywgbGEgZnVuY2nDs24gZGUgbXVsdGlwbGljYWNpw7NuIHNlIGFwbGljYSBhIGNhZGEgZWxlbWVudG8gZGVsIHZlY3Rvci4KCmBgYHtyIGFwb3lvMn0KYXBveW8yID0gYXBveW8qMTAKYXBveW8yCmBgYAoKSGF5IG90cmFzIGZ1bmNpb25lcyBxdWUgcmVzdWx0YW4gbcOhcyDDunRpbGVzIHBhcmEgbnVlc3Ryb3Mgb2JqZXRpdm9zIHBvcnF1ZSB0cmFiYWphbiBzb2JyZSB1biBjb25qdW50byBkZSB2YWxvcmVzLCBjb21vIGxvcyBhbG1hY2VuYWRvcyBlbiB1biB2ZWN0b3IsIGNhbGN1bGFuZG8gdW4gdmFsb3Igw7puaWNvLgpQb3IgZWplbXBsbywgc2kgcXVlcmVtb3MgY2FsY3VsYXIgZWwgYXBveW8gYSBsYSBkZW1vY3JhY2lhIHByb21lZGlvIGVuIHRvZG9zIGxvcyBwYcOtc2VzIG1vc3RyYWRvcyBlbiBlbCBHcsOhZmljbyAxLjEgc2UgcHVlZGUgdXNhciBsYSBmdW5jacOzbiBgbWVhbijigKYpYC4KCmBgYHtyIG1lZGlhfQptZWFuKGFwb3lvKQpgYGAKCkVzdGEgZnVuY2nDs24gcmVjaWJlIHRvZG9zIGxvcyB2YWxvcmVzIGRlIHVuIHZlY3RvciwgbG9zIHN1bWEgeSBsb3MgZGl2aWRlIGVudHJlIGVsIG7Dum1lcm8gZGUgb2JzZXJ2YWNpb25lcywgbW9zdHJhbmRvIGxhIG1lZGlhLgoKT3RyYSBmdW5jaW9uZXMgbXV5IHVzYWRhcyBlbiBlc3RhZMOtc3RpY2Egc29uIGxhIG1lZGlhbmEsIGxhIGRlc3ZpYWNpw7NuIGVzdMOhbmRhciwgZWwgbcOtbmltbywgZWwgbcOheGltbyB5IGxhIHN1bWEuCgpgYGB7ciBvdHJhcyBmdW5jaW9uZXN9Cm1lZGlhbihhcG95bykKc2QoYXBveW8pCm1pbihhcG95bykKbWF4KGFwb3lvKQpzdW0oYXBveW8pCmBgYAoKRWwgR3LDoWZpY28gMS4xIG11ZXN0cmEgbG9zIHJlc3VsdGFkb3MgcGFyYSBsb3MgcGHDrXNlcyBkb25kZSBzZSB0aWVuZSBpbmZvcm1hY2nDs24uClNpbiBlbWJhcmdvLCBlbiBhbGd1bm9zIGNhc29zIHVuIHZlY3RvciBwdWVkZSBpbmNsdWlyIHVuIHZhbG9yIHBlcmRpZG8uClBvciBlamVtcGxvLCBlbCBncsOhZmljbyBubyBtdWVzdHJhIGluZm9ybWFjacOzbiBwYXJhIFZlbmV6dWVsYSwgcGHDrXMgZG9uZGUgbm8gc2UgcmVhbGl6w7MgdHJhYmFqbyBkZSBjYW1wbyBwb3IgbW90aXZvcyBkZSBzZWd1cmlkYWQuClNpIHF1aXNpw6lyYW1vcyBjcmVhciB1biB2ZWN0b3IgcXVlIGluY2x1eWEgZXN0ZSB2YWxvciBmYWx0YW50ZSAoTkEgZW4gZWwgbGVuZ3VhamUgUiksIHNlIHBvZHLDrWEgaGFjZXIgYXPDrToKCmBgYHtyIGFwb3lvIGNvbiBOQX0KYXBveW8yID0gYyhhcG95bywgTkEpCmFwb3lvMgpgYGAKCkVuIGVsIHByb2NlZGltaWVudG8gcXVlIGhlbW9zIHJlYWxpemFkbyBoZW1vcyB1c2FkbyBlbCBtaXNtbyBub21icmUgImFwb3lvMiIsIHBvciBsbyBxdWUgaGVtb3Mgc29icmVlc2NyaXRvIGVsIHZlY3RvciBjb24gZXN0b3MgbnVldm9zIHJlc3VsdGFkb3MuCkxhIGNhZGVuYSBkZSBuw7ptZXJvIGFob3JhIGluY2x1eWUgdW4gdmFsb3IgZmluYWwgTkEuCgpBbGd1bmFzIGZ1bmNpb25lcyBubyBwdWVkZW4gY2FsY3VsYXIgZGlyZWN0YW1lbnRlIHN1IHByb2NlZGltaWVudG8gZW4gdmVjdG9yZXMgcXVlIGNvbnRpZW5lbiB2YWxvcmVzIE5BLgpQb3IgZWplbXBsbywgbGEgZnVuY2nDs24gYG1lYW5gLgoKYGBge3IgbWVkaWEgYXBveW8yfQptZWFuKGFwb3lvMikKYGBgCgpFbCBjw6FsY3VsbyBkaXJlY3RvIGRlIGxhIG1lZGlhIGRlbCB2ZWN0b3IgImFwb3lvMiIgbm9zIGRldnVlbHZlIHVuIHJlc3VsdGFkbyBOQS4KUGFyYSBwb2RlciBoYWNlciBlbCBjw6FsY3VsbywgaW5kaWPDoW5kb2xlIGEgbGEgZnVuY2nDs24gcXVlIG5vIHRvbWUgZW4gY3VlbnRhIGVzdGUgdmFsb3IgTkEsIHNlIHRpZW5lIHF1ZSB1c2FyIGxhIGVzcGVjaWZpY2FjacOzbiBgbmEucm09VHJ1ZWAuCgpgYGB7ciBtZWRpYSBhcG95byBuYS5ybX0KbWVhbihhcG95bzIsIG5hLnJtPVQpCmBgYAoKIyBQYXF1ZXRlcwoKUiBlcyB1biBwcm95ZWN0byBjb2xhYm9yYXRpdm8uCk11Y2hvcyBkZXNhcnJvbGxhZG9yZXMgcHJvZHVjZW4gbnVldm9zIHBhcXVldGVzIHF1ZSBzb24gYWRtaW5pc3RyYWRvcyBwb3IgZWwgbWlzbW8gcHJveWVjdG8gZGUgUi4KRXN0b3MgcGFxdWV0ZXMgcHVlZGVuIGluY2x1aXIgbXVjaGFzIGZ1bmNpb25lcyBxdWUgYXl1ZGFuIGEgbWFuZWphciBkYXRvcy4KClIgdGllbmUgZnVuY2lvbmVzIG5hdGl2YXMgcGFyYSBpbXBvcnRhciBiYXNlcyBkZSBkYXRvcyBkZSBkaWZlcmVudGVzIGZvcm1hdG9zLCBjb21vIEV4Y2VsLCBTUFNTIG8gU3RhdGEuCkNhZGEgZm9ybWF0byB0aWVuZSB1bmEgZnVuY2nDs24gZXNwZWPDrWZpY2EsIGNvbW8gYHJlYWRfY3N2YCBvIGByZWFkX2R0YWAuClNpbiBlbWJhcmdvLCB1bm9zIGRlc2Fycm9sbGFkb3JlcyBoYW4gcHJvZHVjaWRvIHVuIHBhcXVldGUgbGxhbWFkbyAicmlvIiBxdWUgaW5jbHV5ZSB1bmEgZnVuY2nDs24gYGltcG9ydGAgcXVlIHBlcm1pdGUgaW1wb3J0YXIgY3VhbHF1aWVyIHRpcG8gZGUgYmFzZSBkZSBkYXRvcy4KRXN0ZSBwYXF1ZXRlIG5vIHZpZW5lIGluc3RhbGFkbyBlbiBsYSBkZXNjYXJnYSBiw6FzaWNhIGRlIFIsIHBvciBsbyBxdWUgc2UgdGllbmUgcXVlIGluc3RhbGFyIGVsIHBhcXVldGUgcGFyYSBwb2RlciB1c2FybG8uCgpQYXJhIGluc3RhbGFyIHVuIHBhcXVldGUgc2UgdXNhIGVsIGNvbWFuZG8gYGluc3RhbGwucGFja2FnZXNgIGNvbiBlbCBub21icmUgZGVsIHBhcXVldGUgcXVlIHNlIHF1aWVyZSBpbnN0YWxhciBlbnRyZSBjb21pbGxhcy4KRW4gZXN0ZSBjYXNvIGhlbW9zIHVzYWRvIHVuIFwjIGFudGVzIGRlbCBjw7NkaWdvIGRlYmlkbyBhIHF1ZSB5YSBzZSB0aWVuZSBpbnN0YWxhZG8gZWwgcGFxdWV0ZS4KUGFyYSBtb3N0cmFyIGxvcyBjb21lbnRhcmlvcyBvIGzDrW5lYXMgZGUgY8OzZGlnbyBxdWUgcXVlcmVtb3MgbW9zdHJhciwgcGVybyBxdWUgbm8gc2UgY29ycmFuLCBzZSBwdWVkZW4gaGFjZXIgY29uIHVuIFwjIGFudGVzIGRlbCBjb21lbnRhcmlvIG8gY8OzZGlnby4KCmBgYHtyIGluc3RhbGFyIHBhcXVldGVzfQojIGluc3RhbGwucGFja2FnZXMoInJpbyIpCmBgYAoKVW5hIHZleiBpbnN0YWxhZG8sIHNlIHRpZW5lIHF1ZSBhY3RpdmFyIGVsIHBhcXVldGUgcGFyYSBwb2RlciB1c2FyIHN1cyBmdW5jaW9uZXMuCkVzdG8gc2UgaGFjZSBjb24gZWwgY29tYW5kbyBgbGlicmFyeWAuClVuYSB2ZXogYWN0aXZhZG8sIHNlIHB1ZWRlIHVzYXIgY3VhbHF1aWVyIGZ1bmNpw7NuIGRlIGVzdGEgbGlicmVyw61hLCBjb21vIGxhIGZ1bmNpw7NuIGBpbXBvcnRgLgpQYXJhIGFjdGl2YXIgeWEgbm8gc2UgcmVxdWllcmUgY29taWxsYXMuCkVzdGUgcHJvY2VkaW1pZW50byBzZSBwdWVkZSB2ZXJpZmljYXIgZW4gZWwgcGFuZWwgaW5mZXJpb3IgZGVyZWNobywgZW4gbGEgcGVzdGHDsWEgIlBhY2thZ2VzIi4KRWwgcGFxdWV0ZSAicmlvIiBhcGFyZWNlIGNvbiB1biBjaGVjay4KCmBgYHtyIGFjdGl2YXJ9CmxpYnJhcnkocmlvKQpgYGAKCiMgRGF0YWZyYW1lcwoKTG9zIGRhdGFmcmFtZXMgc29uIGVzdHJ1Y3R1cmFzIGRlIGRhdG9zIHJlY3Rhbmd1bGFyZXMuCkNvbW8gY29udmVuY2nDs24sIGxvcyBkYXRhZnJhbWVzIHRpZW5lbiBlbiBzdXMgY29sdW1uYXMgYSBsb3MgdmVjdG9yZXMgKG8gdmFyaWFibGVzKSB5IGVuIGxhcyBmaWxhcyBhIGxhcyBvYnNlcnZhY2lvbmVzLgpQYXJhIGNyZWFyIHVuIGRhdGFmcmFtZSBzZSB1c2EgZWwgY29tYW5kbyBgZGF0YS5mcmFtZSguLi4pYC4KClBvciBlamVtcGxvLCBwb2RlbW9zIGNyZWFyIHVuIGRhdGFmcmFtZSBxdWUganVudGUgbG9zIGRhdG9zIGRlbCB2ZWN0b3IgInBhaXMiIGNvbiBsb3MgZGVsIHZlY3RvciAiYXBveW8iLgpFc3RvcyBkb3MgdmVjdG9yZXMgdGllbmVuIHF1ZSB0ZW5lciBsYXMgbWlzbWFzIGRpbWVuc2lvbmVzLgpWZW1vcyBlbiBlbCBFbnZpcm9ubWVudCBxdWUgYW1ib3MgdGllbmVuIGNvbW8gZGltZW5zacOzbiBbMToyMF0uCkVzdGUgZGF0YWZyYW1lIHNlIHB1ZWRlIGd1YXJkYXIgZW4gdW4gb2JqZXRvICJhcG95b0FMIi4KCmBgYHtyIGRhdGFmcmFtZX0KYXBveW9BTCA9IGRhdGEuZnJhbWUocGFpcywgYXBveW8pCmFwb3lvQUwKYGBgCgpWZW1vcyBxdWUgZWwgb2JqZXRvICJhcG95b0FMIiBzZSBoYSBndWFyZGFkbyBlbiB1bmEgc2VjY2nDs24gYXBhcnRlIGRlbCBFbnZpcm9ubWVudCBxdWUgc2UgbGxhbWEgIkRhdGEiLgpFc3RlIG9iamV0byB0aWVuZSAyMCBvYnNlcnZhY2lvbmVzIChlcyBkZWNpciwgMjAgZmlsYXMgbyBwYcOtc2VzKSB5IGRvcyB2YXJpYWJsZXMgKGVzIGRlY2lyLCBkb3MgdmVjdG9yZXMgbyBkb3MgY29sdW1uYXMpLgpTZSBwdWVkZSBoYWNlciBjbGljayBlbiBlc3RlIG9iamV0byB5IHNlIHB1ZWRlIHZlciBsYSBwbGFuY2hhIGRlIGRhdG9zIGVuIHVuYSBwZXN0YcOxYSBhcGFydGUuCgpTaSBzZSBxdWlzaWVyYSBoYWNlciB1biBkYXRhZnJhbWUgY29uIGxvcyB2ZWN0b3JlcyAicGFpcyIgeSAiYXBveW8yIiwgUiBub3MgZGFyw61hIHVuIG1lbnNhamUgZGUgZXJyb3IgZGViaWRvIGEgcXVlIGVzdG9zIHZlY3RvcmVzIHRpZW5lbiBkaWZlcmVudGVzIGRpbWVuc2lvbmVzLgoKQWhvcmEsIGVsIHZlY3RvciAiYXBveW8iIGZvcm1hIHBhcnRlIGRlIGxhIGJhc2UgZGUgZGF0b3MgImFwb3lvQUwiLgpQYXJhIHBvZGVyIHVzYXIgbGFzIGZ1bmNpb25lcyBlbiB1biBkYXRhZnJhbWUgc2UgZGViZSBlc3BlY2lmaWNhciBsYSBjb2x1bW5hIGRlIGxhIHF1ZSBzZSBxdWllcmUgY2FsY3VsYXIgbGEgZnVuY2nDs24uClBvciBlamVtcGxvLCBzaSBhaG9yYSBzZSBxdWlzaWVyYSBjYWxjdWxhciBlbCBwcm9tZWRpbyBkZSBhcG95byBhIGxhIGRlbW9jcmFjaWEgZGVzZGUgbGEgYmFzZSBkZSBkYXRvcyAiYXBveW9BTCIgc2UgdGllbmUgcXVlIGVzcGVjaWZpY2FyIGxhIHZhcmlhYmxlIChvIHZlY3RvcikgY29uICJcJCIuCgpgYGB7ciBhcG95byBkYXRhfQptZWFuKGFwb3lvQUwkYXBveW8pCmBgYAoKRW4gZ2VuZXJhbCwgY3VhbHF1aWVyIGJhc2UgZGUgZGF0b3MgZXMgdW5hIGVzdHJ1Y3R1cmEgcmVjdGFuZ3VsYXIgZG9uZGUgZW4gbGFzIGZpbGFzIHRlbmVtb3MgbGFzIG9ic2VydmFjaW9uZXMgeSBlbiBsYXMgY29sdW1uYXMsIGxhcyB2YXJpYWJsZXMsIGxvIHF1ZSBjYW1iaWEgZXMgZWwgbsO6bWVybyBkZSBmaWxhcyB5IGRlIGNvbHVtbmFzLgoKUG9yIGVqZW1wbG8sIHVuYSBiYXNlIGRlIGRhdG9zIGRlbCBCYXLDs21ldHJvIGRlIGxhcyBBbcOpcmljYXMgZGUgdW4gcGHDrXMgcHVlZGUgdGVuZXIgMSw1MDAgb2JzZXJ2YWNpb25lcyAoMSw1MDAgZmlsYXMpIHkgbcOhcyBkZSAxMDAgdmFyaWFibGVzIChtw6FzIGRlIDEwMCBjb2x1bW5hcyBvIHZlY3RvcmVzKS4KRW4gZXNlIGNhc28sIGNhZGEgb2JzZXJ2YWNpw7NuIGNvcnJlc3BvbmRlIGEgdW5hIHBlcnNvbmEgcXVlIHJlc3BvbmRpw7MgbGEgZW5jdWVzdGEgeSB1bmEgY29sdW1uYSAobyB2ZWN0b3IgZGUgZGF0b3MpIHJlcHJlc2VudGEgbGFzIHJlc3B1ZXN0YXMgZGUgdG9kb3MgbG9zIGVudHJldmlzdGFkb3MgYSB1bmEgcHJlZ3VudGEgZGVsIGN1ZXN0aW9uYXJpby4KCkVzIG3DoXMsIGxhIGJhc2UgZGUgZGF0b3MgY29uanVudGEgKGVsIG1lcmdlIGRlIGRhdG9zKSBlcyBsYSBiYXNlIGRlIGRhdG9zIGRlIHRvZG9zIGxvcyBwYcOtc2VzIGVuIHVuYSByb25kYS4KRXN0YSBiYXNlIGRlIGRhdG9zIHB1ZWRlIHRlbmVyIG3DoXMgZGUgMzAgbWlsIG9ic2VydmFjaW9uZXMgKGVzIGRlY2lyLCB0b2RvcyBsb3MgZW50cmV2aXN0YWRvcyBlbiB0b2RvcyBsb3MgcGHDrXNlcyBlbiB1bmEgcm9uZGEgZGV0ZXJtaW5hZGEpIHkgbcOhcyBkZSAxMDAgY29sdW1uYXMuCgpNw6FzIGFsbMOhIGRlbCB0YW1hw7FvIGRlIGxhIGJhc2UgZGUgZGF0b3MsIGxhcyBjb2x1bW5hcyBzb24gdmVjdG9yZXMgYSBsb3MgcXVlIHNlIGxlcyBwdWVkZSBhcGxpY2FyIGZ1bmNpb25lcy4KCkVuIGxhIHNpZ3VpZW50ZSBzZWNjacOzbiBzb2JyZSBpbXBvcnRhY2nDs24gZGUgbG9zIGRhdG9zIGRlbCBCYXLDs21ldHJvIGRlIGxhcyBBbcOpcmljYXMgZW4gUlN0dWRpbyBzZSB2ZXLDoSBsYSBtYW5lcmEgZGUgZGVzY2FyZ2FyIHVuYSBiYXNlIGRlIGRhdG9zIGRlbCBwcm95ZWN0byB5IGNhcmdhcmxhIGVuIFJTdHVkaW8uCgojIFJlc3VtZW4KCkVuIGVzdGUgZG9jdW1lbnRvIHNlIGhhbiByZXZpc2FkbyBsb3MgZWxlbWVudG9zIGLDoXNpY28gZGUgUiwgY29tbyBvYmpldG9zIHkgdmVjdG9yZXMsIHkgbGFzIGZ1bmNpb25lcyBiw6FzaWNhcyBxdWUgc2UgcHVlZGVuIGFwbGljYXIgYSBlc3RvcyBvYmpldG9zLgpUYW1iacOpbiBzZSBoYSByZXZpc2FkbyBsYSBtYW5lcmEgZGUgaW5zdGFsYXIgbGlicmVyw61hcyB5IGRlIGFjdGl2YXJsYXMgcGFyYSBwb2RlciB1c2FyIHN1cyBmdW5jaW9uZXMuCkZpbmFsbWVudGUsIHNlIGhhIGV4cGxpY2FkbyBsYSBpZGVhIGRlIHVuIGRhdGFmcmFtZS4K