Introducción
En el ámbito de la investigación científica R se ha convertido en una
herramienta fundamental para la manipulación, exploración y
visualización de información. En este informe se exploraron los
fundamentos de R a traves de un caso de estudio: el análisis de
avistamiento de aves en la cuenca del ríos Usumacinta.
La cuenca del río Usumacinta, con su riqueza en biodiversidad, ofrece
un escenario único para estudiar la diversidad de especies de aves. Se
utilizó una matriz de datos que contiene información detallada sobre las
especies, los departamentos en los que se han avistado, así como las
coordenadas de latitud y longitud. A lo largo de esta práctica, se
pusieron en práctica conceptos clave en R, haciendo uso de la librería
“dplyr” y sus diversas funciones para manipulación y transformación de
datos.
Se exploró cómo cargar y examinar datos, realizar submuestreos para
análisis más manejables, calcular estadísticas descriptivas como la
moda, mediana y media de especies avistadas, así como también se
organizaron los datos en tablas y visualizaciones comprensibles. Se
observó cómo el uso de estructuras condicionales como if y else pueden
ayudarnos a filtrar y manipular datos con precisión.
Discusión y Resultados
Importancia de los comentarios
Las anotaciones realizadas en el código con ayuda de “#” son también
conocidas como comentarios. Dichos comentarios están diseñados para dar
una explicación del código o comandos que se están ejecutando, además de
poder documentar y describir la función de alguna formula (figura 1).
Estos comentarios también pueden ser una guía para rastrear y entender
donde pueden surgir los problemas en el codigo ya que al revisar los
comentarios estos pueden recordar el proposito original del codigo y así
detectar posibles problemas de logica, escritura, etc. Por lo tanto, los
comentarios en R tienen una gran importancia para mejorar la
legibilidad, documentar y facilitar el mantenimiento del código. Estos
al usarse de manera efectiva pueden hacer que el código sea más
comprensible tanto para el autor como para algún externo.
Es importante mencionar que estos comentarios no son ejecutados como
parte del programa.
Figura 1. Comentarios en código de R
Fuente: Datos obtenidos de la práctica
Fundamentos de R elaborada por Pavel García.
Se observa en la figura 1 los comentarios de coloración verde detallando
la funciones de las diferentes funciones matemáticas.
Consulta
Las consultas permiten a los usuarios extraer datos de una matriz
para el análisis en R, lo cual facilita el análisis de los datos (Lugon,
2023).
Para la realización de la consulta se conectó la base de datos de
aves en la cuenca del río Usumacinta. De dicha base de datos se
extrajeron las columnas de “Especies” y de “Departamentos” para
determinar sus medidas de tendencia central, siendo estos los valores de
moda y mediana que se utilizarón para obtener más información sobre la
distribución de los datos. La moda se utilizó para identificar el valor
más común de la distribución en la cuenca del Usumacinta, mientras que
la mediana se utilizó para identificar el valor central de la
distribución en la cuenca del Usumacinta.
La variable de especies presentó como moda el dato de Quiscalus
mexicanus (tabla 1), conocido comúnmente como zanate, lo cual tiene
sentido que sea el ave con mayor registro en la cuenca ya que es un ave
oportunista que se adapta con facilidad a los diferentes hábitats,
además de tener una alimentación muy variada (Monge-Nájera, 2002). Por
otro lado, la mediana para la variable de especie fue Myiarchus
crinitus (tabla 1), conocido comúnmente como copetón viajero, el
cual pudo haber demostrado una distribución de avistamientos más
equilibrada en comparación con otras especies, lo que resulta en una
posición central en la distribución de datos.
La variable de departamentos presentó el dato de Petén tanto en moda
como en mediana (tabla 1). Dicha repetición para los departamentos donde
se avistaron las especies de aves en la cuenca del Usumacinta podría
indicar características favorables de este departamento en relación con
el hábitat y las condiciones que atraen a las aves, además de que el
departamento de Petén es el mayor área de Guatemala abarcada por la
cuenca. Siendo Petén el departamento de mayor área dentro de la cuenca,
sumado con sus características geográficas y climáticas pueden ser
factores que respondan a la concentración de avistamientos (García,
2019). La repetición de “Petén” como moda y mediana enfatiza su papel
vital como refugio y entorno propicio para estas aves en la cuenca del
Usumacinta.
# Calcular la tabla de frecuencias de la columna "Especies"
especies_moda<-table(tabla$Especies)
# Encontrar el valor con la frecuencia más alta (moda) de la columna Especies
moda<-names(especies_moda)[which.max(especies_moda)]
print(paste("Moda:",moda))
[1] "Moda: Quiscalus mexicanus"
# Calcular la mediana de la columna "Especies"
especies_mediana<- median(tabla$Especies)
print(paste("Mediana:",especies_mediana))
[1] "Mediana: Myiarchus crinitus"
# Calcular la tabla de frecuencias de la columna "Especies"
Depas_moda<-table(tabla$Departamento)
# Encontrar el valor con la frecuencia más alta (moda)
modaDep<-names(Depas_moda)[which.max(Depas_moda)]
print(paste("Moda:",modaDep))
[1] "Moda: Petén"
# Calcular la mediana de la columna "Departamentos"
Depas_mediana<- median(tabla$Departamento)
print(paste("Mediana:",Depas_mediana))
[1] "Mediana: Petén"
Tabla 1. Moda y mediana de las variables de especies y
departamentos
En la tabla 1 se resumen los resultados de moda y mediana para
las variables “especies” y “departamentos”. Para la variable de especies
el valor de moda se determinó como Quiscalus mexicanus, siendo
esta la especie más frecuente en los datos analizados, por otro lado, la
mediana correspondiente a la variable de especies es Myiarchus
crinitus, representando el valor central de la distribución de
especies. Para la variable de departamentos, los resultados de moda y
mediana son consistentes, ya que ambos coinciden con el valor de Petén,
por lo cual este departamento destaca como el más común de los datos
bajo análisis, tanto en terminos de moda (valor frecuente) como de
mediana (valor central).
Variables |
Moda |
Mediana |
Especies |
Quiscalus mexicanus |
Myiarchus crinitus |
Departamentos |
Petén |
Petén |
Fuente: Datos obtenidos de GBIF el 20 de agosto del 2023 por Diana
Salguero
Suma
La suma de datos, tanto numericos como de texto, es una operación
fundamental en el análisis de datos (Irizarry, 2021).
Se realizó la suma de los datos de las especies de aves encontradas
en la cuenca del Usumacinta, así como también del total de avistamientos
(tabla 2). Dicha suma dio como resultado 642 especies de aves diferentes
y 1,048,107 avistamientos de aves en la cuenca del Usumacinta. Dicha
cuenca puede ser una región con gran riqueza de aves debido a que la
cuenca cuenta con una gran variedad de hábitats naturales que ofrecen
condiciones adecuadas para la presencia de aves, así como por sus las
áreas protegidas que se encuentran dentro de la cuenca, por ejemplo, el
Parque Nacional Tikal, la Reserva de la Biosfera Maya, Parque Nacional
Laguna del Tigre, entre otros (Pineda-Diez et al., 2020;
Cruz-Paz et al., 2018).
# Obtener la cantidad de especies de aves únicas en la cuenca del Usumacinta
especies_suma<-length(unique(tabla$Especies))
print(paste("Cantidad de especies de aves en la cuenca del Usumacinta:", especies_suma))
[1] "Cantidad de especies de aves en la cuenca del Usumacinta: 642"
# Obtener la cantidad de avistamiento de especies de aves en la cuenca del Usumacinta
avistamientos_suma<- length(tabla$Especies)
print(paste("Cantidad de avistamientos de aves en la cuenca del Usumacinta:", avistamientos_suma))
[1] "Cantidad de avistamientos de aves en la cuenca del Usumacinta: 1048107"
Tabla 2. Cantidad de especies y avistamientos de aves en la
Cuenca del Usumacinta
La tabla 2 presenta una resumen de la suma relacionada con la
riqueza y observación de aves en la cuenca del Usumacinta. La columna de
“especies de aves” muestra el numero total de especies de aves
documentadas en la región, siendo un total de 642 especies. La columna
“avistamiento de aves” destaca la notable cantidad de avistamientos
registrados, alcanzando la cifra de 1,048,107 observaciones. Estos datos
subrayan la riqueza de aves presentes en la cuenca del usumacinta y la
considerable actividad de avistamientos que contribuyen a nuestra
comprensión de la biodiversidad en esta área.
|
Cantidad |
Especies de aves |
642 |
Avistamientos de aves |
1,048,107 |
Fuente: Datos obtenidos en R por Diana Salguero el 22 de agosto del
2023.
Resumen de valores
El resumen de valores es una forma de presentar de manera concisa y
significativa las características clave de un conjunto de datos
numéricos. Este resumen incluye medidas como la media, mediana,
desviación estandar, el mínimo y los cuartiles, entre otros;
proporcionando una comprensión rápida y útil de la distribución y
tendencias del conjunto de datos (Coll & Pérez, s.f.; Mendoza, 2022;
Parker, 2020)
Las coordenadas de latitud y longitus representan als ubicaciones
geográficas exactas donde se han registrado avistamientos de aves (tabla
3). Sugiriendo la mediana de la latitud (16.84) que la mayoría de los
avistamientos ocurren en latitudes cercanas a esta cifra, mientras que
la dispersión de los valores alrededor de la mediana (16.37) podría
indicar una distribución relativamente uniforme de las observaciones a
lo largo de la cuenca del río Usumacinta.
En cuanto a la longitud, el rango desde -91.79 hasta -89.19 refleja
la variabilidad en las ubicaciones longitudinales de los avistamientos.
La presencia de valores en el primer y tercer cuartil (-90.36 y -89.69,
respectivamente) sugiere que existe cierta concentración de
observaciones en ciertos rangos longitudinales.
En conjunto, esta tabla revela que los avistamientos de aves en la
cuenca del río Usumacinta abarcan una gama de coordenadas geográficas.
La distribución de las observaciones a lo largo de diferentes latitudes
y longitudes podría estar influenciada por la diversidad de hábitats,
condiciones climáticas y disponibilidad de recursos en diferentes áreas
de la cuenca. El análisis de estas coordenadas puede ser crucial para
comprender los patrones de migración, los hábitats preferidos y las
interacciones ecológicas de las aves en esta región (Muñoz-Alonso et
al., 2018).
#Resumen estadístico de los datos
resumen<- summary(tabla)
print(resumen)
Especies Departamento
Length:1048107 Length:1048107
Class :character Class :character
Mode :character Mode :character
Latitud Longitud
Min. :14.91 Min. :-91.79
1st Qu.:15.42 1st Qu.:-90.36
Median :16.84 Median :-90.21
Mean :16.37 Mean :-90.10
3rd Qu.:17.22 3rd Qu.:-89.69
Max. :17.80 Max. :-89.19
Tabla 3. Resumen estadístico de las coordenadas de
avistamientos de aves en la Cuenca del Río Usumacinta
La tabla 3 muestra los valores mínimos, máximos, medios y
cuartiles de las coordenadas geográficas en donde se han reportado
avistamientos de aves en la cuenca del río Usumacinta. Las coordenadas
se refieren a la latitud y longitud de los lugares donde dichos
avistamientos han sido reportados. Estos datos ofrecen una visión
resumida de las ubicaciones geográficas donde se concentran los
avistamientos de aves en la cuenca del río Usumacinta
Mínimo |
14.91 |
-91.79 |
primer Cuartil |
15.42 |
-90.36 |
Mediana |
16.84 |
-90.21 |
Media |
16.37 |
-90.10 |
Tercer Cuartil |
17.22 |
-89.69 |
Máximo |
17.80 |
-89.19 |
Fuente: Datos obtenidos en R por Diana Salguero el 22 de agosto del
2023.
Submuestreo de matriz
El submuestreo de una matriz en R se refiere a la creación de una
nueva matriz que contiene un subconjunto de las filas y/o columnas de la
matriz original. Este proceso puede ser útil cuando deseas reducir el
tamaño de una matriz para realizar análisis más rápidos o cuando estás
interesado en trabajar con una muestra representativa de los datos en
lugar de la matriz completa (Coll & Pérez, s.f.; Hernández,
2023)
La matriz de datos se submuestreo de 1,048,107 datos a 50.
#Cargar datos
matriz_datos <- as.matrix(tabla)
# Definir el tamaño del submuestreo
tamaño<- 50
# Realizar el submuestreo
filas<- sample(1:nrow(tabla), size = tamaño, replace= FALSE)
tabla_submuestreada <- tabla[filas, ]
#imprimir matriz submuestreada
print(tabla_submuestreada)
“cheatsheet” del paquete dplyr
Se utilizó el paquete “dplyr” con la función “arrange()” para ordenar
los datos segun la columna de Especies de manera descendente.
install.packages("dplyr")
Error in install.packages : Updating loaded packages
library(dplyr)
# Ordenar los datos por la columna "especies"
datos_ordenados <- tabla_submuestreada%>%arrange(desc(Especies))
# Imprimir los primeros registros de los datos ordenados
head(datos_ordenados)
Comando “if” y “else”
Se utilizó el comando “If” y “else” para filtrar los datos que
correpondían solo al departamnento de Petén. Dicho departamento se
escogió ya que es el que presenta una mayor cantidad de avistamientos de
aves.
#Crear funcion para obtener solo las filas en las que el departamento sea Petén
filtro_peten<-function(tabla){ifelse(tabla$Departamento == "Petén", TRUE, FALSE)}
#Aplicar función filtro"
peten_datos<-tabla%>%filter(filtro_peten(.))
#imprimir
head(peten_datos)
NA
Anexos
Anexo 1. Instalación de paquete para leer archivos de Excel
(.xlsx) en R
install.packages("readxl")
WARNING: Rtools is required to build R packages but is not currently installed. Please download and install the appropriate version of Rtools before proceeding:
https://cran.rstudio.com/bin/windows/Rtools/
Installing package into ‘C:/Users/diana/AppData/Local/R/win-library/4.3’
(as ‘lib’ is unspecified)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/readxl_1.4.3.zip'
Content type 'application/zip' length 1194928 bytes (1.1 MB)
downloaded 1.1 MB
package ‘readxl’ successfully unpacked and MD5 sums checked
The downloaded binary packages are in
C:\Users\diana\AppData\Local\Temp\RtmpKAa0ES\downloaded_packages
Anexo 2. Código para leer y almacenar archivos de Excel
(.xlsx)
library(readxl)
tabla<-read_excel("D:\\Octavo Semestre\\AVES Cuenca GT\\AVES Cuenca.xlsx")
Anexo 3. Tabla de datos de avistamientos de
aves en la Cuenca del Río Usumacinta.
tabla
Referencias
Lugon, A. (2023) Ejecutar Consulta SQL en R (Ejemplo). Estadisticool.
https://estadisticool.com/ejecutar-consulta-sql-en-r-ejemplo/
Monge-Nájera, J. (2002) Biología General. EUNED
García, B. (2019) Observación de aves en Petén (pajarear en Petén).
Segundo, la biodiversidad y pajareando por Tikal, Yaxhá y lago Petén
Itzá. Diversidad y un poco de todo. https://www.diversidadyunpocodetodo.com/observacion-de-aves-en-peten-biodiversidad-y-pajareando/#Comparte_esto
Irizarry, R. (2021) Introducción a la ciencia de datos: análisis de
datos y algoritmos de predicción con R. CRC Press.
Pineda-Diez de Bonilla, E., Velázquez Velázquez, E., &
Mera-Ortiz, G. (2020). Riqueza y composición de la avifauna de tres
humedales del río Grijalva, Chiapas,
México. Huitzil, 21(2).
Cruz-Paz, G., Castillo, M. M., Espinoza-Tenorio, A., Bravo-Peña, L.
C., Valencia Barrera, E., & Mesa-Jurado, M. A. (2018). Áreas
prioritarias de conservación en la cuenca Usumacinta. La aplicación de
un enfoque multicriterio. Investigaciones geográficas,
(97).
Coll, V. & Pérez, P. (s.f.) R para el análisis estadístico de
datos. Universidad de Valencia. https://www.uv.es/vcoll/Temas_AED/2_Introduccion.html
Mendoza, J. (2022) Operaciones matemáticas en R. Estadísticamente. https://estadisticamente.com/operaciones-matematicas-en-r/
Parker, R. (2020) R lecture notes. Johns Hopkins.https://users.phhp.ufl.edu/rlp176/Courses/PHC6089/R_notes/index.html
Muñoz-Alonso, L. A., Rodiles-Hernández, R., López-León, N. P.,
González-Navarro, A., Chau-Cortés, A. M., & Nieblas-Camacho, J. A.
(2018). Diversidad de la herpetofauna en la cuenca del Usumacinta,
México. Revista mexicana de biodiversidad, 89,
79-99.
Hernández, F. & Usuga, O. (2023) Manual de R. https://usermanual.wiki/Pdf/ManualdeR.708910831.pdf
LS0tDQp0aXRsZTogIkZ1bmRhbWVudG9zIGRlIFIgcGFyYSBlbCBhbsOhbGlzaXMgZGUgZGF0b3MiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sgDQotLS0NCg0KLS0tDQpEaWFuYSBTb2ZpYSBTYWxndWVybyBHYXJjaWEsIDIwMTcwMTU4MA0KLS0tDQoNCiMjIEludHJvZHVjY2nDs24NCg0KRW4gZWwgw6FtYml0byBkZSBsYSBpbnZlc3RpZ2FjacOzbiBjaWVudMOtZmljYSBSIHNlIGhhIGNvbnZlcnRpZG8gZW4gdW5hIGhlcnJhbWllbnRhIGZ1bmRhbWVudGFsIHBhcmEgbGEgbWFuaXB1bGFjacOzbiwgZXhwbG9yYWNpw7NuIHkgdmlzdWFsaXphY2nDs24gZGUgaW5mb3JtYWNpw7NuLiBFbiBlc3RlIGluZm9ybWUgc2UgZXhwbG9yYXJvbiBsb3MgZnVuZGFtZW50b3MgZGUgUiBhIHRyYXZlcyBkZSB1biBjYXNvIGRlIGVzdHVkaW86IGVsIGFuw6FsaXNpcyBkZSBhdmlzdGFtaWVudG8gZGUgYXZlcyBlbiBsYSBjdWVuY2EgZGVsIHLDrW9zIFVzdW1hY2ludGEuDQoNCkxhIGN1ZW5jYSBkZWwgcsOtbyBVc3VtYWNpbnRhLCBjb24gc3UgcmlxdWV6YSBlbiBiaW9kaXZlcnNpZGFkLCBvZnJlY2UgdW4gZXNjZW5hcmlvIMO6bmljbyBwYXJhIGVzdHVkaWFyIGxhIGRpdmVyc2lkYWQgZGUgZXNwZWNpZXMgZGUgYXZlcy4gU2UgdXRpbGl6w7MgdW5hIG1hdHJpeiBkZSBkYXRvcyBxdWUgY29udGllbmUgaW5mb3JtYWNpw7NuIGRldGFsbGFkYSBzb2JyZSBsYXMgZXNwZWNpZXMsIGxvcyBkZXBhcnRhbWVudG9zIGVuIGxvcyBxdWUgc2UgaGFuIGF2aXN0YWRvLCBhc8OtIGNvbW8gbGFzIGNvb3JkZW5hZGFzIGRlIGxhdGl0dWQgeSBsb25naXR1ZC4gQSBsbyBsYXJnbyBkZSBlc3RhIHByw6FjdGljYSwgc2UgcHVzaWVyb24gZW4gcHLDoWN0aWNhIGNvbmNlcHRvcyBjbGF2ZSBlbiBSLCBoYWNpZW5kbyB1c28gZGUgbGEgbGlicmVyw61hICJkcGx5ciIgeSBzdXMgZGl2ZXJzYXMgZnVuY2lvbmVzIHBhcmEgbWFuaXB1bGFjacOzbiB5IHRyYW5zZm9ybWFjacOzbiBkZSBkYXRvcy4NCg0KU2UgZXhwbG9yw7MgY8OzbW8gY2FyZ2FyIHkgZXhhbWluYXIgZGF0b3MsIHJlYWxpemFyIHN1Ym11ZXN0cmVvcyBwYXJhIGFuw6FsaXNpcyBtw6FzIG1hbmVqYWJsZXMsIGNhbGN1bGFyIGVzdGFkw61zdGljYXMgZGVzY3JpcHRpdmFzIGNvbW8gbGEgbW9kYSwgbWVkaWFuYSB5IG1lZGlhIGRlIGVzcGVjaWVzIGF2aXN0YWRhcywgYXPDrSBjb21vIHRhbWJpw6luIHNlIG9yZ2FuaXphcm9uIGxvcyBkYXRvcyBlbiB0YWJsYXMgeSB2aXN1YWxpemFjaW9uZXMgY29tcHJlbnNpYmxlcy4gU2Ugb2JzZXJ2w7MgY8OzbW8gZWwgdXNvIGRlIGVzdHJ1Y3R1cmFzIGNvbmRpY2lvbmFsZXMgY29tbyBpZiB5IGVsc2UgcHVlZGVuIGF5dWRhcm5vcyBhIGZpbHRyYXIgeSBtYW5pcHVsYXIgZGF0b3MgY29uIHByZWNpc2nDs24uDQoNCiMjIERpc2N1c2nDs24geSBSZXN1bHRhZG9zDQoNCiMjIyBJbXBvcnRhbmNpYSBkZSBsb3MgY29tZW50YXJpb3MNCg0KTGFzIGFub3RhY2lvbmVzIHJlYWxpemFkYXMgZW4gZWwgY8OzZGlnbyBjb24gYXl1ZGEgZGUgIlwjIiBzb24gdGFtYmnDqW4gY29ub2NpZGFzIGNvbW8gY29tZW50YXJpb3MuIERpY2hvcyBjb21lbnRhcmlvcyBlc3TDoW4gZGlzZcOxYWRvcyBwYXJhIGRhciB1bmEgZXhwbGljYWNpw7NuIGRlbCBjw7NkaWdvIG8gY29tYW5kb3MgcXVlIHNlIGVzdMOhbiBlamVjdXRhbmRvLCBhZGVtw6FzIGRlIHBvZGVyIGRvY3VtZW50YXIgeSBkZXNjcmliaXIgbGEgZnVuY2nDs24gZGUgYWxndW5hIGZvcm11bGEgKGZpZ3VyYSAxKS4gRXN0b3MgY29tZW50YXJpb3MgdGFtYmnDqW4gcHVlZGVuIHNlciB1bmEgZ3XDrWEgcGFyYSByYXN0cmVhciB5IGVudGVuZGVyIGRvbmRlIHB1ZWRlbiBzdXJnaXIgbG9zIHByb2JsZW1hcyBlbiBlbCBjb2RpZ28geWEgcXVlIGFsIHJldmlzYXIgbG9zIGNvbWVudGFyaW9zIGVzdG9zIHB1ZWRlbiByZWNvcmRhciBlbCBwcm9wb3NpdG8gb3JpZ2luYWwgZGVsIGNvZGlnbyB5IGFzw60gZGV0ZWN0YXIgcG9zaWJsZXMgcHJvYmxlbWFzIGRlIGxvZ2ljYSwgZXNjcml0dXJhLCBldGMuIFBvciBsbyB0YW50bywgbG9zIGNvbWVudGFyaW9zIGVuIFIgdGllbmVuIHVuYSBncmFuIGltcG9ydGFuY2lhIHBhcmEgbWVqb3JhciBsYSBsZWdpYmlsaWRhZCwgZG9jdW1lbnRhciB5IGZhY2lsaXRhciBlbCBtYW50ZW5pbWllbnRvIGRlbCBjw7NkaWdvLiBFc3RvcyBhbCB1c2Fyc2UgZGUgbWFuZXJhIGVmZWN0aXZhIHB1ZWRlbiBoYWNlciBxdWUgZWwgY8OzZGlnbyBzZWEgbcOhcyBjb21wcmVuc2libGUgdGFudG8gcGFyYSBlbCBhdXRvciBjb21vIHBhcmEgYWxnw7puIGV4dGVybm8uDQoNCkVzIGltcG9ydGFudGUgbWVuY2lvbmFyIHF1ZSBlc3RvcyBjb21lbnRhcmlvcyBubyBzb24gZWplY3V0YWRvcyBjb21vIHBhcnRlIGRlbCBwcm9ncmFtYS4NCg0KKipGaWd1cmEgMS4gQ29tZW50YXJpb3MgZW4gY8OzZGlnbyBkZSBSKioNCg0KIVtGdWVudGU6IERhdG9zIG9idGVuaWRvcyBkZSBsYSBwcsOhY3RpY2EgRnVuZGFtZW50b3MgZGUgUiBlbGFib3JhZGEgcG9yIFBhdmVsIEdhcmPDrWEuXA0KXA0KU2Ugb2JzZXJ2YSBlbiBsYSBmaWd1cmEgMSBsb3MgY29tZW50YXJpb3MgZGUgY29sb3JhY2nDs24gdmVyZGUgZGV0YWxsYW5kbyBsYSBmdW5jaW9uZXMgZGUgbGFzIGRpZmVyZW50ZXMgZnVuY2lvbmVzIG1hdGVtw6F0aWNhcy5dKGNvbWVudGFyaW9zJTIwZW4lMjBjb2RpZ28ucG5nKQ0KDQojIyMgQ29uc3VsdGENCg0KTGFzIGNvbnN1bHRhcyBwZXJtaXRlbiBhIGxvcyB1c3VhcmlvcyBleHRyYWVyIGRhdG9zIGRlIHVuYSBtYXRyaXogcGFyYSBlbCBhbsOhbGlzaXMgZW4gUiwgbG8gY3VhbCBmYWNpbGl0YSBlbCBhbsOhbGlzaXMgZGUgbG9zIGRhdG9zIChMdWdvbiwgMjAyMykuDQoNClBhcmEgbGEgcmVhbGl6YWNpw7NuIGRlIGxhIGNvbnN1bHRhIHNlIGNvbmVjdMOzIGxhIGJhc2UgZGUgZGF0b3MgZGUgYXZlcyBlbiBsYSBjdWVuY2EgZGVsIHLDrW8gVXN1bWFjaW50YS4gRGUgZGljaGEgYmFzZSBkZSBkYXRvcyBzZSBleHRyYWplcm9uIGxhcyBjb2x1bW5hcyBkZSAiRXNwZWNpZXMiIHkgZGUgIkRlcGFydGFtZW50b3MiIHBhcmEgZGV0ZXJtaW5hciBzdXMgbWVkaWRhcyBkZSB0ZW5kZW5jaWEgY2VudHJhbCwgc2llbmRvIGVzdG9zIGxvcyB2YWxvcmVzIGRlIG1vZGEgeSBtZWRpYW5hIHF1ZSBzZSB1dGlsaXphcsOzbiBwYXJhIG9idGVuZXIgbcOhcyBpbmZvcm1hY2nDs24gc29icmUgbGEgZGlzdHJpYnVjacOzbiBkZSBsb3MgZGF0b3MuIExhIG1vZGEgc2UgdXRpbGl6w7MgcGFyYSBpZGVudGlmaWNhciBlbCB2YWxvciBtw6FzIGNvbcO6biBkZSBsYSBkaXN0cmlidWNpw7NuIGVuIGxhIGN1ZW5jYSBkZWwgVXN1bWFjaW50YSwgbWllbnRyYXMgcXVlIGxhIG1lZGlhbmEgc2UgdXRpbGl6w7MgcGFyYSBpZGVudGlmaWNhciBlbCB2YWxvciBjZW50cmFsIGRlIGxhIGRpc3RyaWJ1Y2nDs24gZW4gbGEgY3VlbmNhIGRlbCBVc3VtYWNpbnRhLg0KDQpMYSB2YXJpYWJsZSBkZSBlc3BlY2llcyBwcmVzZW50w7MgY29tbyBtb2RhIGVsIGRhdG8gZGUgKlF1aXNjYWx1cyBtZXhpY2FudXMqICh0YWJsYSAxKSwgY29ub2NpZG8gY29tw7pubWVudGUgY29tbyB6YW5hdGUsIGxvIGN1YWwgdGllbmUgc2VudGlkbyBxdWUgc2VhIGVsIGF2ZSBjb24gbWF5b3IgcmVnaXN0cm8gZW4gbGEgY3VlbmNhIHlhIHF1ZSBlcyB1biBhdmUgb3BvcnR1bmlzdGEgcXVlIHNlIGFkYXB0YSBjb24gZmFjaWxpZGFkIGEgbG9zIGRpZmVyZW50ZXMgaMOhYml0YXRzLCBhZGVtw6FzIGRlIHRlbmVyIHVuYSBhbGltZW50YWNpw7NuIG11eSB2YXJpYWRhIChNb25nZS1Ow6FqZXJhLCAyMDAyKS4gUG9yIG90cm8gbGFkbywgbGEgbWVkaWFuYSBwYXJhIGxhIHZhcmlhYmxlIGRlIGVzcGVjaWUgZnVlICpNeWlhcmNodXMgY3Jpbml0dXMqICh0YWJsYSAxKSwgY29ub2NpZG8gY29tw7pubWVudGUgY29tbyBjb3BldMOzbiB2aWFqZXJvLCBlbCBjdWFsIHB1ZG8gaGFiZXIgZGVtb3N0cmFkbyB1bmEgZGlzdHJpYnVjacOzbiBkZSBhdmlzdGFtaWVudG9zIG3DoXMgZXF1aWxpYnJhZGEgZW4gY29tcGFyYWNpw7NuIGNvbiBvdHJhcyBlc3BlY2llcywgbG8gcXVlIHJlc3VsdGEgZW4gdW5hIHBvc2ljacOzbiBjZW50cmFsIGVuIGxhIGRpc3RyaWJ1Y2nDs24gZGUgZGF0b3MuDQoNCkxhIHZhcmlhYmxlIGRlIGRlcGFydGFtZW50b3MgcHJlc2VudMOzIGVsIGRhdG8gZGUgUGV0w6luIHRhbnRvIGVuIG1vZGEgY29tbyBlbiBtZWRpYW5hICh0YWJsYSAxKS4gRGljaGEgcmVwZXRpY2nDs24gcGFyYSBsb3MgZGVwYXJ0YW1lbnRvcyBkb25kZSBzZSBhdmlzdGFyb24gbGFzIGVzcGVjaWVzIGRlIGF2ZXMgZW4gbGEgY3VlbmNhIGRlbCBVc3VtYWNpbnRhIHBvZHLDrWEgaW5kaWNhciBjYXJhY3RlcsOtc3RpY2FzIGZhdm9yYWJsZXMgZGUgZXN0ZSBkZXBhcnRhbWVudG8gZW4gcmVsYWNpw7NuIGNvbiBlbCBow6FiaXRhdCB5IGxhcyBjb25kaWNpb25lcyBxdWUgYXRyYWVuIGEgbGFzIGF2ZXMsIGFkZW3DoXMgZGUgcXVlIGVsIGRlcGFydGFtZW50byBkZSBQZXTDqW4gZXMgZWwgbWF5b3Igw6FyZWEgZGUgR3VhdGVtYWxhIGFiYXJjYWRhIHBvciBsYSBjdWVuY2EuIFNpZW5kbyBQZXTDqW4gZWwgZGVwYXJ0YW1lbnRvIGRlIG1heW9yIMOhcmVhIGRlbnRybyBkZSBsYSBjdWVuY2EsIHN1bWFkbyBjb24gc3VzIGNhcmFjdGVyw61zdGljYXMgZ2VvZ3LDoWZpY2FzIHkgY2xpbcOhdGljYXMgcHVlZGVuIHNlciBmYWN0b3JlcyBxdWUgcmVzcG9uZGFuIGEgbGEgY29uY2VudHJhY2nDs24gZGUgYXZpc3RhbWllbnRvcyAoR2FyY8OtYSwgMjAxOSkuIExhIHJlcGV0aWNpw7NuIGRlICJQZXTDqW4iIGNvbW8gbW9kYSB5IG1lZGlhbmEgZW5mYXRpemEgc3UgcGFwZWwgdml0YWwgY29tbyByZWZ1Z2lvIHkgZW50b3JubyBwcm9waWNpbyBwYXJhIGVzdGFzIGF2ZXMgZW4gbGEgY3VlbmNhIGRlbCBVc3VtYWNpbnRhLg0KDQpgYGB7cn0NCiMgQ2FsY3VsYXIgbGEgdGFibGEgZGUgZnJlY3VlbmNpYXMgZGUgbGEgY29sdW1uYSAiRXNwZWNpZXMiDQplc3BlY2llc19tb2RhPC10YWJsZSh0YWJsYSRFc3BlY2llcykNCg0KIyBFbmNvbnRyYXIgZWwgdmFsb3IgY29uIGxhIGZyZWN1ZW5jaWEgbcOhcyBhbHRhIChtb2RhKSBkZSBsYSBjb2x1bW5hIEVzcGVjaWVzDQptb2RhPC1uYW1lcyhlc3BlY2llc19tb2RhKVt3aGljaC5tYXgoZXNwZWNpZXNfbW9kYSldDQpwcmludChwYXN0ZSgiTW9kYToiLG1vZGEpKQ0KDQojIENhbGN1bGFyIGxhIG1lZGlhbmEgZGUgbGEgY29sdW1uYSAiRXNwZWNpZXMiDQplc3BlY2llc19tZWRpYW5hPC0gbWVkaWFuKHRhYmxhJEVzcGVjaWVzKQ0KcHJpbnQocGFzdGUoIk1lZGlhbmE6Iixlc3BlY2llc19tZWRpYW5hKSkNCg0KYGBgDQoNCmBgYHtyfQ0KIyBDYWxjdWxhciBsYSB0YWJsYSBkZSBmcmVjdWVuY2lhcyBkZSBsYSBjb2x1bW5hICJFc3BlY2llcyINCkRlcGFzX21vZGE8LXRhYmxlKHRhYmxhJERlcGFydGFtZW50bykNCg0KIyBFbmNvbnRyYXIgZWwgdmFsb3IgY29uIGxhIGZyZWN1ZW5jaWEgbcOhcyBhbHRhIChtb2RhKQ0KbW9kYURlcDwtbmFtZXMoRGVwYXNfbW9kYSlbd2hpY2gubWF4KERlcGFzX21vZGEpXQ0KcHJpbnQocGFzdGUoIk1vZGE6Iixtb2RhRGVwKSkNCg0KIyBDYWxjdWxhciBsYSBtZWRpYW5hIGRlIGxhIGNvbHVtbmEgIkRlcGFydGFtZW50b3MiDQpEZXBhc19tZWRpYW5hPC0gbWVkaWFuKHRhYmxhJERlcGFydGFtZW50bykNCnByaW50KHBhc3RlKCJNZWRpYW5hOiIsRGVwYXNfbWVkaWFuYSkpDQoNCmBgYA0KDQoqKlRhYmxhIDEuIE1vZGEgeSBtZWRpYW5hIGRlIGxhcyB2YXJpYWJsZXMgZGUgZXNwZWNpZXMgeSBkZXBhcnRhbWVudG9zKioNCg0KfCAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgfA0KfC0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tfA0KfCAqKlZhcmlhYmxlcyoqIHwgKipNb2RhKiogICAgICAgICAgICAgIHwgKipNZWRpYW5hKiogICAgICAgICAgfA0KfCBFc3BlY2llcyAgICAgIHwgKlF1aXNjYWx1cyBtZXhpY2FudXMqIHwgKk15aWFyY2h1cyBjcmluaXR1cyogfA0KfCBEZXBhcnRhbWVudG9zIHwgUGV0w6luICAgICAgICAgICAgICAgICB8IFBldMOpbiAgICAgICAgICAgICAgICB8DQoNCjogRW4gbGEgdGFibGEgMSBzZSByZXN1bWVuIGxvcyByZXN1bHRhZG9zIGRlIG1vZGEgeSBtZWRpYW5hIHBhcmEgbGFzIHZhcmlhYmxlcyAiZXNwZWNpZXMiIHkgImRlcGFydGFtZW50b3MiLiBQYXJhIGxhIHZhcmlhYmxlIGRlIGVzcGVjaWVzIGVsIHZhbG9yIGRlIG1vZGEgc2UgZGV0ZXJtaW7DsyBjb21vICpRdWlzY2FsdXMgbWV4aWNhbnVzLCogc2llbmRvIGVzdGEgbGEgZXNwZWNpZSBtw6FzIGZyZWN1ZW50ZSBlbiBsb3MgZGF0b3MgYW5hbGl6YWRvcywgcG9yIG90cm8gbGFkbywgbGEgbWVkaWFuYSBjb3JyZXNwb25kaWVudGUgYSBsYSB2YXJpYWJsZSBkZSBlc3BlY2llcyBlcyAqTXlpYXJjaHVzIGNyaW5pdHVzKiwgcmVwcmVzZW50YW5kbyBlbCB2YWxvciBjZW50cmFsIGRlIGxhIGRpc3RyaWJ1Y2nDs24gZGUgZXNwZWNpZXMuIFBhcmEgbGEgdmFyaWFibGUgZGUgZGVwYXJ0YW1lbnRvcywgbG9zIHJlc3VsdGFkb3MgZGUgbW9kYSB5IG1lZGlhbmEgc29uIGNvbnNpc3RlbnRlcywgeWEgcXVlIGFtYm9zIGNvaW5jaWRlbiBjb24gZWwgdmFsb3IgZGUgUGV0w6luLCBwb3IgbG8gY3VhbCBlc3RlIGRlcGFydGFtZW50byBkZXN0YWNhIGNvbW8gZWwgbcOhcyBjb23Dum4gZGUgbG9zIGRhdG9zIGJham8gYW7DoWxpc2lzLCB0YW50byBlbiB0ZXJtaW5vcyBkZSBtb2RhICh2YWxvciBmcmVjdWVudGUpIGNvbW8gZGUgbWVkaWFuYSAodmFsb3IgY2VudHJhbCkuDQoNCkZ1ZW50ZTogRGF0b3Mgb2J0ZW5pZG9zIGRlIEdCSUYgZWwgMjAgZGUgYWdvc3RvIGRlbCAyMDIzIHBvciBEaWFuYSBTYWxndWVybw0KDQojIyMgU3VtYQ0KDQpMYSBzdW1hIGRlIGRhdG9zLCB0YW50byBudW1lcmljb3MgY29tbyBkZSB0ZXh0bywgZXMgdW5hIG9wZXJhY2nDs24gZnVuZGFtZW50YWwgZW4gZWwgYW7DoWxpc2lzIGRlIGRhdG9zIChJcml6YXJyeSwgMjAyMSkuDQoNClNlIHJlYWxpesOzIGxhIHN1bWEgZGUgbG9zIGRhdG9zIGRlIGxhcyBlc3BlY2llcyBkZSBhdmVzIGVuY29udHJhZGFzIGVuIGxhIGN1ZW5jYSBkZWwgVXN1bWFjaW50YSwgYXPDrSBjb21vIHRhbWJpw6luIGRlbCB0b3RhbCBkZSBhdmlzdGFtaWVudG9zICh0YWJsYSAyKS4gRGljaGEgc3VtYSBkaW8gY29tbyByZXN1bHRhZG8gNjQyIGVzcGVjaWVzIGRlIGF2ZXMgZGlmZXJlbnRlcyB5IDEsMDQ4LDEwNyBhdmlzdGFtaWVudG9zIGRlIGF2ZXMgZW4gbGEgY3VlbmNhIGRlbCBVc3VtYWNpbnRhLiBEaWNoYSBjdWVuY2EgcHVlZGUgc2VyIHVuYSByZWdpw7NuIGNvbiBncmFuIHJpcXVlemEgZGUgYXZlcyBkZWJpZG8gYSBxdWUgbGEgY3VlbmNhIGN1ZW50YSBjb24gdW5hIGdyYW4gdmFyaWVkYWQgZGUgaMOhYml0YXRzIG5hdHVyYWxlcyBxdWUgb2ZyZWNlbiBjb25kaWNpb25lcyBhZGVjdWFkYXMgcGFyYSBsYSBwcmVzZW5jaWEgZGUgYXZlcywgYXPDrSBjb21vIHBvciBzdXMgbGFzIMOhcmVhcyBwcm90ZWdpZGFzIHF1ZSBzZSBlbmN1ZW50cmFuIGRlbnRybyBkZSBsYSBjdWVuY2EsIHBvciBlamVtcGxvLCBlbCBQYXJxdWUgTmFjaW9uYWwgVGlrYWwsIGxhIFJlc2VydmEgZGUgbGEgQmlvc2ZlcmEgTWF5YSwgUGFycXVlIE5hY2lvbmFsIExhZ3VuYSBkZWwgVGlncmUsIGVudHJlIG90cm9zIChQaW5lZGEtRGlleiAqZXQgYWwuKiwgMjAyMDsgQ3J1ei1QYXogKmV0IGFsKi4sIDIwMTgpLg0KDQpgYGB7cn0NCiMgT2J0ZW5lciBsYSBjYW50aWRhZCBkZSBlc3BlY2llcyBkZSBhdmVzIMO6bmljYXMgZW4gbGEgY3VlbmNhIGRlbCBVc3VtYWNpbnRhDQplc3BlY2llc19zdW1hPC1sZW5ndGgodW5pcXVlKHRhYmxhJEVzcGVjaWVzKSkNCnByaW50KHBhc3RlKCJDYW50aWRhZCBkZSBlc3BlY2llcyBkZSBhdmVzIGVuIGxhIGN1ZW5jYSBkZWwgVXN1bWFjaW50YToiLCBlc3BlY2llc19zdW1hKSkNCg0KIyBPYnRlbmVyIGxhIGNhbnRpZGFkIGRlIGF2aXN0YW1pZW50byBkZSBlc3BlY2llcyBkZSBhdmVzIGVuIGxhIGN1ZW5jYSBkZWwgVXN1bWFjaW50YQ0KYXZpc3RhbWllbnRvc19zdW1hPC0gbGVuZ3RoKHRhYmxhJEVzcGVjaWVzKQ0KcHJpbnQocGFzdGUoIkNhbnRpZGFkIGRlIGF2aXN0YW1pZW50b3MgZGUgYXZlcyBlbiBsYSBjdWVuY2EgZGVsIFVzdW1hY2ludGE6IiwgYXZpc3RhbWllbnRvc19zdW1hKSkNCmBgYA0KDQoqKlRhYmxhIDIuIENhbnRpZGFkIGRlIGVzcGVjaWVzIHkgYXZpc3RhbWllbnRvcyBkZSBhdmVzIGVuIGxhIEN1ZW5jYSBkZWwgVXN1bWFjaW50YSoqDQoNCnwgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgIHwNCnwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLXwNCnwgICAgICAgICAgICAgICAgICAgICAgIHwgKipDYW50aWRhZCoqIHwNCnwgRXNwZWNpZXMgZGUgYXZlcyAgICAgIHwgNjQyICAgICAgICAgIHwNCnwgQXZpc3RhbWllbnRvcyBkZSBhdmVzIHwgMSwwNDgsMTA3ICAgIHwNCg0KOiBMYSB0YWJsYSAyIHByZXNlbnRhIHVuYSByZXN1bWVuIGRlIGxhIHN1bWEgcmVsYWNpb25hZGEgY29uIGxhIHJpcXVlemEgeSBvYnNlcnZhY2nDs24gZGUgYXZlcyBlbiBsYSBjdWVuY2EgZGVsIFVzdW1hY2ludGEuIExhIGNvbHVtbmEgZGUgImVzcGVjaWVzIGRlIGF2ZXMiIG11ZXN0cmEgZWwgbnVtZXJvIHRvdGFsIGRlIGVzcGVjaWVzIGRlIGF2ZXMgZG9jdW1lbnRhZGFzIGVuIGxhIHJlZ2nDs24sIHNpZW5kbyB1biB0b3RhbCBkZSA2NDIgZXNwZWNpZXMuIExhIGNvbHVtbmEgImF2aXN0YW1pZW50byBkZSBhdmVzIiBkZXN0YWNhIGxhIG5vdGFibGUgY2FudGlkYWQgZGUgYXZpc3RhbWllbnRvcyByZWdpc3RyYWRvcywgYWxjYW56YW5kbyBsYSBjaWZyYSBkZSAxLDA0OCwxMDcgb2JzZXJ2YWNpb25lcy4gRXN0b3MgZGF0b3Mgc3VicmF5YW4gbGEgcmlxdWV6YSBkZSBhdmVzIHByZXNlbnRlcyBlbiBsYSBjdWVuY2EgZGVsIHVzdW1hY2ludGEgeSBsYSBjb25zaWRlcmFibGUgYWN0aXZpZGFkIGRlIGF2aXN0YW1pZW50b3MgcXVlIGNvbnRyaWJ1eWVuIGEgbnVlc3RyYSBjb21wcmVuc2nDs24gZGUgbGEgYmlvZGl2ZXJzaWRhZCBlbiBlc3RhIMOhcmVhLg0KDQpGdWVudGU6IERhdG9zIG9idGVuaWRvcyBlbiBSIHBvciBEaWFuYSBTYWxndWVybyBlbCAyMiBkZSBhZ29zdG8gZGVsIDIwMjMuDQoNCiMjIyBSZXN1bWVuIGRlIHZhbG9yZXMNCg0KRWwgcmVzdW1lbiBkZSB2YWxvcmVzIGVzIHVuYSBmb3JtYSBkZSBwcmVzZW50YXIgZGUgbWFuZXJhIGNvbmNpc2EgeSBzaWduaWZpY2F0aXZhIGxhcyBjYXJhY3RlcsOtc3RpY2FzIGNsYXZlIGRlIHVuIGNvbmp1bnRvIGRlIGRhdG9zIG51bcOpcmljb3MuIEVzdGUgcmVzdW1lbiBpbmNsdXllIG1lZGlkYXMgY29tbyBsYSBtZWRpYSwgbWVkaWFuYSwgZGVzdmlhY2nDs24gZXN0YW5kYXIsIGVsIG3DrW5pbW8geSBsb3MgY3VhcnRpbGVzLCBlbnRyZSBvdHJvczsgcHJvcG9yY2lvbmFuZG8gdW5hIGNvbXByZW5zacOzbiByw6FwaWRhIHkgw7p0aWwgZGUgbGEgZGlzdHJpYnVjacOzbiB5IHRlbmRlbmNpYXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIChDb2xsICYgUMOpcmV6LCBzLmYuOyBNZW5kb3phLCAyMDIyOyBQYXJrZXIsIDIwMjApDQoNCkxhcyBjb29yZGVuYWRhcyBkZSBsYXRpdHVkIHkgbG9uZ2l0dXMgcmVwcmVzZW50YW4gYWxzIHViaWNhY2lvbmVzIGdlb2dyw6FmaWNhcyBleGFjdGFzIGRvbmRlIHNlIGhhbiByZWdpc3RyYWRvIGF2aXN0YW1pZW50b3MgZGUgYXZlcyAodGFibGEgMykuIFN1Z2lyaWVuZG8gbGEgbWVkaWFuYSBkZSBsYSBsYXRpdHVkICgxNi44NCkgcXVlIGxhIG1heW9yw61hIGRlIGxvcyBhdmlzdGFtaWVudG9zIG9jdXJyZW4gZW4gbGF0aXR1ZGVzIGNlcmNhbmFzIGEgZXN0YSBjaWZyYSwgbWllbnRyYXMgcXVlIGxhIGRpc3BlcnNpw7NuIGRlIGxvcyB2YWxvcmVzIGFscmVkZWRvciBkZSBsYSBtZWRpYW5hICgxNi4zNykgcG9kcsOtYSBpbmRpY2FyIHVuYSBkaXN0cmlidWNpw7NuIHJlbGF0aXZhbWVudGUgdW5pZm9ybWUgZGUgbGFzIG9ic2VydmFjaW9uZXMgYSBsbyBsYXJnbyBkZSBsYSBjdWVuY2EgZGVsIHLDrW8gVXN1bWFjaW50YS4NCg0KRW4gY3VhbnRvIGEgbGEgbG9uZ2l0dWQsIGVsIHJhbmdvIGRlc2RlIC05MS43OSBoYXN0YSAtODkuMTkgcmVmbGVqYSBsYSB2YXJpYWJpbGlkYWQgZW4gbGFzIHViaWNhY2lvbmVzIGxvbmdpdHVkaW5hbGVzIGRlIGxvcyBhdmlzdGFtaWVudG9zLiBMYSBwcmVzZW5jaWEgZGUgdmFsb3JlcyBlbiBlbCBwcmltZXIgeSB0ZXJjZXIgY3VhcnRpbCAoLTkwLjM2IHkgLTg5LjY5LCByZXNwZWN0aXZhbWVudGUpIHN1Z2llcmUgcXVlIGV4aXN0ZSBjaWVydGEgY29uY2VudHJhY2nDs24gZGUgb2JzZXJ2YWNpb25lcyBlbiBjaWVydG9zIHJhbmdvcyBsb25naXR1ZGluYWxlcy4NCg0KRW4gY29uanVudG8sIGVzdGEgdGFibGEgcmV2ZWxhIHF1ZSBsb3MgYXZpc3RhbWllbnRvcyBkZSBhdmVzIGVuIGxhIGN1ZW5jYSBkZWwgcsOtbyBVc3VtYWNpbnRhIGFiYXJjYW4gdW5hIGdhbWEgZGUgY29vcmRlbmFkYXMgZ2VvZ3LDoWZpY2FzLiBMYSBkaXN0cmlidWNpw7NuIGRlIGxhcyBvYnNlcnZhY2lvbmVzIGEgbG8gbGFyZ28gZGUgZGlmZXJlbnRlcyBsYXRpdHVkZXMgeSBsb25naXR1ZGVzIHBvZHLDrWEgZXN0YXIgaW5mbHVlbmNpYWRhIHBvciBsYSBkaXZlcnNpZGFkIGRlIGjDoWJpdGF0cywgY29uZGljaW9uZXMgY2xpbcOhdGljYXMgeSBkaXNwb25pYmlsaWRhZCBkZSByZWN1cnNvcyBlbiBkaWZlcmVudGVzIMOhcmVhcyBkZSBsYSBjdWVuY2EuIEVsIGFuw6FsaXNpcyBkZSBlc3RhcyBjb29yZGVuYWRhcyBwdWVkZSBzZXIgY3J1Y2lhbCBwYXJhIGNvbXByZW5kZXIgbG9zIHBhdHJvbmVzIGRlIG1pZ3JhY2nDs24sIGxvcyBow6FiaXRhdHMgcHJlZmVyaWRvcyB5IGxhcyBpbnRlcmFjY2lvbmVzIGVjb2zDs2dpY2FzIGRlIGxhcyBhdmVzIGVuIGVzdGEgcmVnacOzbiAoTXXDsW96LUFsb25zbyAqZXQgYWwqLiwgMjAxOCkuDQoNCmBgYHtyfQ0KI1Jlc3VtZW4gZXN0YWTDrXN0aWNvIGRlIGxvcyBkYXRvcw0KcmVzdW1lbjwtIHN1bW1hcnkodGFibGEpDQpwcmludChyZXN1bWVuKQ0KYGBgDQoNCioqVGFibGEgMy4gUmVzdW1lbiBlc3RhZMOtc3RpY28gZGUgbGFzIGNvb3JkZW5hZGFzIGRlIGF2aXN0YW1pZW50b3MgZGUgYXZlcyBlbiBsYSBDdWVuY2EgZGVsIFLDrW8gVXN1bWFjaW50YSoqDQoNCnwgICAgICAgICAgICAgICAgfCBMYXRpdHVkIHwgTG9uZ2l0dWQgfA0KfC0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tfC0tLS0tLS0tLS18DQp8IE3DrW5pbW8gICAgICAgICB8IDE0LjkxICAgfCAtOTEuNzkgICB8DQp8IHByaW1lciBDdWFydGlsIHwgMTUuNDIgICB8IC05MC4zNiAgIHwNCnwgTWVkaWFuYSAgICAgICAgfCAxNi44NCAgIHwgLTkwLjIxICAgfA0KfCBNZWRpYSAgICAgICAgICB8IDE2LjM3ICAgfCAtOTAuMTAgICB8DQp8IFRlcmNlciBDdWFydGlsIHwgMTcuMjIgICB8IC04OS42OSAgIHwNCnwgTcOheGltbyAgICAgICAgIHwgMTcuODAgICB8IC04OS4xOSAgIHwNCg0KOiBMYSB0YWJsYSAzIG11ZXN0cmEgbG9zIHZhbG9yZXMgbcOtbmltb3MsIG3DoXhpbW9zLCBtZWRpb3MgeSBjdWFydGlsZXMgZGUgbGFzIGNvb3JkZW5hZGFzIGdlb2dyw6FmaWNhcyBlbiBkb25kZSBzZSBoYW4gcmVwb3J0YWRvIGF2aXN0YW1pZW50b3MgZGUgYXZlcyBlbiBsYSBjdWVuY2EgZGVsIHLDrW8gVXN1bWFjaW50YS4gTGFzIGNvb3JkZW5hZGFzIHNlIHJlZmllcmVuIGEgbGEgbGF0aXR1ZCB5IGxvbmdpdHVkIGRlIGxvcyBsdWdhcmVzIGRvbmRlIGRpY2hvcyBhdmlzdGFtaWVudG9zIGhhbiBzaWRvIHJlcG9ydGFkb3MuIEVzdG9zIGRhdG9zIG9mcmVjZW4gdW5hIHZpc2nDs24gcmVzdW1pZGEgZGUgbGFzIHViaWNhY2lvbmVzIGdlb2dyw6FmaWNhcyBkb25kZSBzZSBjb25jZW50cmFuIGxvcyBhdmlzdGFtaWVudG9zIGRlIGF2ZXMgZW4gbGEgY3VlbmNhIGRlbCByw61vIFVzdW1hY2ludGENCg0KRnVlbnRlOiBEYXRvcyBvYnRlbmlkb3MgZW4gUiBwb3IgRGlhbmEgU2FsZ3Vlcm8gZWwgMjIgZGUgYWdvc3RvIGRlbCAyMDIzLg0KDQojIyMgU3VibXVlc3RyZW8gZGUgbWF0cml6DQoNCkVsIHN1Ym11ZXN0cmVvIGRlIHVuYSBtYXRyaXogZW4gUiBzZSByZWZpZXJlIGEgbGEgY3JlYWNpw7NuIGRlIHVuYSBudWV2YSBtYXRyaXogcXVlIGNvbnRpZW5lIHVuIHN1YmNvbmp1bnRvIGRlIGxhcyBmaWxhcyB5L28gY29sdW1uYXMgZGUgbGEgbWF0cml6IG9yaWdpbmFsLiBFc3RlIHByb2Nlc28gcHVlZGUgc2VyIMO6dGlsIGN1YW5kbyBkZXNlYXMgcmVkdWNpciBlbCB0YW1hw7FvIGRlIHVuYSBtYXRyaXogcGFyYSByZWFsaXphciBhbsOhbGlzaXMgbcOhcyByw6FwaWRvcyBvIGN1YW5kbyBlc3TDoXMgaW50ZXJlc2FkbyBlbiB0cmFiYWphciBjb24gdW5hIG11ZXN0cmEgcmVwcmVzZW50YXRpdmEgZGUgbG9zIGRhdG9zIGVuIGx1Z2FyIGRlIGxhIG1hdHJpeiBjb21wbGV0YSAoQ29sbCAmIFDDqXJleiwgcy5mLjsgSGVybsOhbmRleiwgMjAyMykNCg0KTGEgbWF0cml6IGRlIGRhdG9zIHNlIHN1Ym11ZXN0cmVvIGRlIDEsMDQ4LDEwNyBkYXRvcyBhIDUwLg0KDQpgYGB7cn0NCiNDYXJnYXIgZGF0b3MNCm1hdHJpel9kYXRvcyA8LSBhcy5tYXRyaXgodGFibGEpDQoNCiMgRGVmaW5pciBlbCB0YW1hw7FvIGRlbCBzdWJtdWVzdHJlbw0KdGFtYcOxbzwtIDUwDQoNCiMgUmVhbGl6YXIgZWwgc3VibXVlc3RyZW8NCmZpbGFzPC0gc2FtcGxlKDE6bnJvdyh0YWJsYSksIHNpemUgPSB0YW1hw7FvLCByZXBsYWNlPSAgRkFMU0UpDQp0YWJsYV9zdWJtdWVzdHJlYWRhIDwtIHRhYmxhW2ZpbGFzLCBdDQoNCiNpbXByaW1pciBtYXRyaXogc3VibXVlc3RyZWFkYQ0KcHJpbnQodGFibGFfc3VibXVlc3RyZWFkYSkNCmBgYA0KDQojIyMgImNoZWF0c2hlZXQiIGRlbCBwYXF1ZXRlIGRwbHlyDQoNClNlIHV0aWxpesOzIGVsIHBhcXVldGUgImRwbHlyIiBjb24gbGEgZnVuY2nDs24gImFycmFuZ2UoKSIgcGFyYSBvcmRlbmFyIGxvcyBkYXRvcyBzZWd1biBsYSBjb2x1bW5hIGRlIEVzcGVjaWVzIGRlIG1hbmVyYSBkZXNjZW5kZW50ZS4NCg0KYGBge3J9DQppbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpDQpsaWJyYXJ5KGRwbHlyKQ0KDQojIE9yZGVuYXIgbG9zIGRhdG9zIHBvciBsYSBjb2x1bW5hICJlc3BlY2llcyINCmRhdG9zX29yZGVuYWRvcyA8LSB0YWJsYV9zdWJtdWVzdHJlYWRhJT4lYXJyYW5nZShkZXNjKEVzcGVjaWVzKSkNCg0KIyBJbXByaW1pciBsb3MgcHJpbWVyb3MgcmVnaXN0cm9zIGRlIGxvcyBkYXRvcyBvcmRlbmFkb3MNCmhlYWQoZGF0b3Nfb3JkZW5hZG9zKQ0KYGBgDQoNCiMjIyBDb21hbmRvICJpZiIgeSAiZWxzZSINCg0KU2UgdXRpbGl6w7MgZWwgY29tYW5kbyAiSWYiIHkgImVsc2UiIHBhcmEgZmlsdHJhciBsb3MgZGF0b3MgcXVlIGNvcnJlcG9uZMOtYW4gc29sbyBhbCBkZXBhcnRhbW5lbnRvIGRlIFBldMOpbi4gRGljaG8gZGVwYXJ0YW1lbnRvIHNlIGVzY29nacOzIHlhIHF1ZSBlcyBlbCBxdWUgcHJlc2VudGEgdW5hIG1heW9yIGNhbnRpZGFkIGRlIGF2aXN0YW1pZW50b3MgZGUgYXZlcy4NCg0KYGBge3J9DQojQ3JlYXIgZnVuY2lvbiBwYXJhIG9idGVuZXIgc29sbyBsYXMgZmlsYXMgZW4gbGFzIHF1ZSBlbCBkZXBhcnRhbWVudG8gc2VhIFBldMOpbg0KZmlsdHJvX3BldGVuPC1mdW5jdGlvbih0YWJsYSl7aWZlbHNlKHRhYmxhJERlcGFydGFtZW50byA9PSAiUGV0w6luIiwgVFJVRSwgRkFMU0UpfQ0KDQojQXBsaWNhciBmdW5jacOzbiBmaWx0cm8iDQpwZXRlbl9kYXRvczwtdGFibGElPiVmaWx0ZXIoZmlsdHJvX3BldGVuKC4pKQ0KDQojaW1wcmltaXINCmhlYWQocGV0ZW5fZGF0b3MpDQogIA0KYGBgDQoNCiMjIEFuZXhvcw0KDQoqKkFuZXhvIDEuIEluc3RhbGFjacOzbiBkZSBwYXF1ZXRlIHBhcmEgbGVlciBhcmNoaXZvcyBkZSBFeGNlbCAoLnhsc3gpIGVuIFIqKg0KDQpgYGB7cn0NCmluc3RhbGwucGFja2FnZXMoInJlYWR4bCIpDQpgYGANCg0KKipBbmV4byAyLiBDw7NkaWdvIHBhcmEgbGVlciB5IGFsbWFjZW5hciBhcmNoaXZvcyBkZSBFeGNlbCAoLnhsc3gpKioNCg0KYGBge3J9DQpsaWJyYXJ5KHJlYWR4bCkNCnRhYmxhPC1yZWFkX2V4Y2VsKCJEOlxcT2N0YXZvIFNlbWVzdHJlXFxBVkVTIEN1ZW5jYSBHVFxcQVZFUyBDdWVuY2EueGxzeCIpDQpgYGANCg0KKipBbmV4byAzLioqICoqVGFibGEgZGUgZGF0b3MgZGUgYXZpc3RhbWllbnRvcyBkZSBhdmVzIGVuIGxhIEN1ZW5jYSBkZWwgUsOtbyBVc3VtYWNpbnRhLioqDQoNCmBgYHtyfQ0KdGFibGENCmBgYA0KDQojIyBSZWZlcmVuY2lhcw0KDQo+IEx1Z29uLCBBLiAoMjAyMykgRWplY3V0YXIgQ29uc3VsdGEgU1FMIGVuIFIgKEVqZW1wbG8pLiBFc3RhZGlzdGljb29sLiA8aHR0cHM6Ly9lc3RhZGlzdGljb29sLmNvbS9lamVjdXRhci1jb25zdWx0YS1zcWwtZW4tci1lamVtcGxvLz4NCj4NCj4gTW9uZ2UtTsOhamVyYSwgSi4gKDIwMDIpIEJpb2xvZ8OtYSBHZW5lcmFsLiBFVU5FRA0KPg0KPiBHYXJjw61hLCBCLiAoMjAxOSkgT2JzZXJ2YWNpw7NuIGRlIGF2ZXMgZW4gUGV0w6luIChwYWphcmVhciBlbiBQZXTDqW4pLiBTZWd1bmRvLCBsYSBiaW9kaXZlcnNpZGFkIHkgcGFqYXJlYW5kbyBwb3IgVGlrYWwsIFlheGjDoSB5IGxhZ28gUGV0w6luIEl0esOhLiBEaXZlcnNpZGFkIHkgdW4gcG9jbyBkZSB0b2RvLiA8aHR0cHM6Ly93d3cuZGl2ZXJzaWRhZHl1bnBvY29kZXRvZG8uY29tL29ic2VydmFjaW9uLWRlLWF2ZXMtZW4tcGV0ZW4tYmlvZGl2ZXJzaWRhZC15LXBhamFyZWFuZG8vI0NvbXBhcnRlX2VzdG8+DQo+DQo+IElyaXphcnJ5LCBSLiAoMjAyMSkgSW50cm9kdWNjacOzbiBhIGxhIGNpZW5jaWEgZGUgZGF0b3M6IGFuw6FsaXNpcyBkZSBkYXRvcyB5IGFsZ29yaXRtb3MgZGUgcHJlZGljY2nDs24gY29uIFIuIENSQyBQcmVzcy4NCj4NCj4gUGluZWRhLURpZXogZGUgQm9uaWxsYSwgRS4sIFZlbMOhenF1ZXogVmVsw6F6cXVleiwgRS4sICYgTWVyYS1PcnRpeiwgRy4gKDIwMjApLiBSaXF1ZXphIHkgY29tcG9zaWNpw7NuIGRlIGxhIGF2aWZhdW5hIGRlIHRyZXMgaHVtZWRhbGVzIGRlbCByw61vIEdyaWphbHZhLCBDaGlhcGFzLCBNw6l4aWNvLsKgKkh1aXR6aWwqLMKgKjIxKigyKS4NCj4NCj4gQ3J1ei1QYXosIEcuLCBDYXN0aWxsbywgTS4gTS4sIEVzcGlub3phLVRlbm9yaW8sIEEuLCBCcmF2by1QZcOxYSwgTC4gQy4sIFZhbGVuY2lhIEJhcnJlcmEsIEUuLCAmIE1lc2EtSnVyYWRvLCBNLiBBLiAoMjAxOCkuIMOBcmVhcyBwcmlvcml0YXJpYXMgZGUgY29uc2VydmFjacOzbiBlbiBsYSBjdWVuY2EgVXN1bWFjaW50YS4gTGEgYXBsaWNhY2nDs24gZGUgdW4gZW5mb3F1ZSBtdWx0aWNyaXRlcmlvLsKgKkludmVzdGlnYWNpb25lcyBnZW9ncsOhZmljYXMqLCAoOTcpLg0KPg0KPiBDb2xsLCBWLiAmIFDDqXJleiwgUC4gKHMuZi4pIFIgcGFyYSBlbCBhbsOhbGlzaXMgZXN0YWTDrXN0aWNvIGRlIGRhdG9zLiBVbml2ZXJzaWRhZCBkZSBWYWxlbmNpYS4gPGh0dHBzOi8vd3d3LnV2LmVzL3Zjb2xsL1RlbWFzX0FFRC8yX0ludHJvZHVjY2lvbi5odG1sPg0KPg0KPiBNZW5kb3phLCBKLiAoMjAyMikgT3BlcmFjaW9uZXMgbWF0ZW3DoXRpY2FzIGVuIFIuIEVzdGFkw61zdGljYW1lbnRlLiA8aHR0cHM6Ly9lc3RhZGlzdGljYW1lbnRlLmNvbS9vcGVyYWNpb25lcy1tYXRlbWF0aWNhcy1lbi1yLz4NCj4NCj4gUGFya2VyLCBSLiAoMjAyMCkgUiBsZWN0dXJlIG5vdGVzLiBKb2hucyBIb3BraW5zLjxodHRwczovL3VzZXJzLnBoaHAudWZsLmVkdS9ybHAxNzYvQ291cnNlcy9QSEM2MDg5L1Jfbm90ZXMvaW5kZXguaHRtbD4NCj4NCj4gTXXDsW96LUFsb25zbywgTC4gQS4sIFJvZGlsZXMtSGVybsOhbmRleiwgUi4sIEzDs3Blei1MZcOzbiwgTi4gUC4sIEdvbnrDoWxlei1OYXZhcnJvLCBBLiwgQ2hhdS1Db3J0w6lzLCBBLiBNLiwgJiBOaWVibGFzLUNhbWFjaG8sIEouIEEuICgyMDE4KS4gRGl2ZXJzaWRhZCBkZSBsYSBoZXJwZXRvZmF1bmEgZW4gbGEgY3VlbmNhIGRlbCBVc3VtYWNpbnRhLCBNw6l4aWNvLsKgKlJldmlzdGEgbWV4aWNhbmEgZGUgYmlvZGl2ZXJzaWRhZCoswqAqODkqLCA3OS05OS4NCj4NCj4gSGVybsOhbmRleiwgRi4gJiBVc3VnYSwgTy4gKDIwMjMpIE1hbnVhbCBkZSBSLiA8aHR0cHM6Ly91c2VybWFudWFsLndpa2kvUGRmL01hbnVhbGRlUi43MDg5MTA4MzEucGRmPg0K