Fase 1 [Descripciones Multivariantes]
En la primera etapa del estudio se realizarán cálculos,
visualizaciones y un análisis detallado del conjunto de datos clínicos,
el cual se describirá en la sección 1.2. Esta fase
se enfocará desde la estadística descriptiva multivariante, con el fin
de ofrecer una visión general del dataset y, al mismo tiempo, examinar
de manera más profunda las relaciones entre las variables. Este enfoque
permitirá identificar patrones y tendencias importantes dentro de los
datos. Las visualizaciones serán fundamentales para mostrar gráficamente
estas relaciones, proporcionando una forma clara y comprensible de
explorarlas. Todas estas tareas se desarrollarán utilizando R y RStudio,
herramientas que facilitarán la ejecución precisa de los análisis y la
elaboración de gráficos interactivos para una interpretación más
completa de los resultados.
1.1. Objetivos
El objetivo de este proyecto es aplicar técnicas de análisis
multivariado al conjunto de datos aprobado, el cual contiene registros
clínicos de la empresa oftalmológica, Visión 2020. La finalidad es
organizar y procesar la información de manera eficiente, fortaleciendo
las competencias en gestión y análisis de datos. Este trabajo se
desarrolla en el marco del curso Gestión de Datos, orientado al
programa de Ingenieria Industrial, en el segundo periodo de 2025 en la
Universidad del Valle, Seccional Zarzal.
1.2. Descripción de los datos
El conjunto de datos utilizado en este estudio fue proporcionado por
la empresa del sector oftalmológico Vision 2020, a partir de los
registros de pacientes atendidos durante el año 2024. La información
original fue entregada en un archivo plano, con 1249 registros y
posteriormente sometida a un proceso de extracción, transformación y
carga (ETL), en el cual se depuraron inconsistencias, se normalizaron
formatos y se generaron variables derivadas para facilitar el análisis
estadístico. El objetivo de este conjunto es caracterizar el perfil
visual y de hábitos de uso de pantallas de los pacientes, así como su
posible relación con factores demográficos y antecedentes
familiares.
Tras el proceso ETL se consolidó una base con 1166 registros (uno por
paciente) y 13 variables, que combinan aspectos de identificación,
sociodemográficos, clínico‑visuales y de estilo de vida. Las variables
se describen a continuación en el orden en que aparecen en la base de
datos, indicando su tipo y escala de medición mediante la notación
(tipo_de_variable::escala_de_medición[ordenamiento]).
Pac_id (cuantitativa::nominal): Identificador
numérico secuencial que asigna un código único a cada paciente. Permite
referenciar los registros sin revelar datos personales y no tiene
interpretación métrica por sí mismo.
Edad_paciente (cuantitativa::razón): Edad del
paciente expresada en años cumplidos al momento del registro. Es una
variable de razón, con cero absoluto y posibilidad de realizar
comparaciones de proporciones de edad.
Ocupacion (cualitativa::nominal): Profesión u oficio
principal del paciente (por ejemplo, estudiante, administrativo,
operario, independiente, entre otros). Se utiliza para caracterizar el
tipo de actividad diaria, especialmente en términos de exposición
potencial a pantallas.
Canal_difusion (cualitativa::nominal): Medio por el
cual el paciente conoció la óptica (referido, redes sociales, volante,
paso por el local, convenio, etc.). Esta variable permite identificar
los canales de captación más frecuentes dentro de la población
atendida.
Fecha_registro (cualitativa::ordinal[tiempo]): Fecha
en la que el paciente fue registrado en el sistema, expresada como
día/mes/año. Aunque se almacena como texto o fecha calendario, su escala
es ordinal en el tiempo y se usa para ubicar la atención dentro del
periodo de estudio.
Pac_sexo (cualitativa::nominal): Sexo del paciente,
registrado típicamente como “Femenino” o “Masculino”. Esta variable se
emplea para comparar patrones de agudeza visual y hábitos de pantalla
entre grupos.
Rango_etareo (cualitativa::ordinal): Clasificación
del paciente en grupos de edad (por ejemplo, ADOLESCENTE, JOVEN_ADULTO,
ADULTO, ADULTO_MAYOR), construida a partir de la variable edad_paciente.
Presenta un orden natural de los grupos, lo que permite análisis por
categorías etarias.
Agudeza_visual_OD (cuantitativa::razón): Medida de
la agudeza visual del ojo derecho, expresada en la escala establecida
por la óptica (por ejemplo, conversión a una métrica continua compatible
con la práctica clínica). Valores más cercanos a la referencia de visión
normal indican mejor agudeza, mientras que valores que se alejan de
dicho estándar representan mayor compromiso visual.
Agudeza_visual_OI (cuantitativa::razón): Análoga a
la anterior, pero para el ojo izquierdo. Junto con la agudeza del ojo
derecho, permite evaluar la simetría o diferencias entre ambos ojos y
constituye una de las variables clínicas centrales del estudio.
Horas_pantalla_dia (cuantitativa::razón): Número de
horas promedio que el paciente pasa diariamente frente a dispositivos
con pantalla (computador, teléfono inteligente, tableta, televisión,
consola, etc.). Es una medida continua de exposición y se considera un
potencial factor de riesgo asociado a fatiga visual y otras molestias
oculares.
Horas_actividadf (cuantitativa::razón): Horas
promedio de actividad física que el paciente realiza al día (o en
promedio diario a partir de la semana), incluyendo ejercicio
estructurado y actividades recreativas. Esta variable permite explorar
si un estilo de vida más activo se relaciona con mejores indicadores
visuales o con menor exposición a pantallas.
Hobby_principal_pantalla (cualitativa::nominal):
Indica si el pasatiempo principal del paciente implica uso intensivo de
pantallas (por ejemplo, videojuegos, redes sociales, series en
streaming) o no. Se codifica típicamente como “sí” o “no” y se usa para
diferenciar hobbies digitales de actividades analógicas o al aire
libre.
Predisposicion_genetica (cualitativa::nominal):
Señala si el paciente reporta antecedentes familiares de problemas
oftalmológicos relevantes (miopía alta, glaucoma, degeneración macular,
entre otros). Se registra como “sí” o “no” y funciona como aproximación
a un factor de riesgo genético.
Durante el proceso de depuración se verificó la coherencia de rangos
(por ejemplo, edades no negativas, horas de pantalla y actividad física
dentro de intervalos plausibles, valores de agudeza visual dentro de los
límites aceptados por la escala utilizada). Los valores faltantes o
claramente atípicos fueron revisados caso a caso; en los casos en que no
fue posible recuperar información confiable, se recurrió a estrategias
de imputación o exclusión controlada, documentadas en el flujo ETL. A
partir de este conjunto depurado, se desarrollan las fases posteriores
del análisis multivariado, centradas en la relación entre agudeza
visual, hábitos de pantalla, actividad física y factores demográficos y
genéticos.
Estructura del Conjunto de Datos Original
str(conjunto_de_datos_vision2020_Original)
## tibble [1,166 × 22] (S3: tbl_df/tbl/data.frame)
## $ pac_id : num [1:1166] 1 2 4 5 6 7 8 9 10 11 ...
## $ pac_carnet : num [1:1166] 0 0 0 0 0 1 1 1 1 1 ...
## $ nombre : chr [1:1166] "HECTOR GUSTAVO" "LUISA MARIA" "YOLANDA DEL SOCORRO" "MARIA GLADIS" ...
## $ apellido : chr [1:1166] "CUERVO" "TORO CORDOBA" "SANCHEZ" "TORO CORDOBA" ...
## $ edad : num [1:1166] 29 25 55 56 35 37 1 29 41 75 ...
## $ ocupacion : chr [1:1166] "admin" "Asesor Comercial" "OTRO" "OTRO" ...
## $ canal_difusion : chr [1:1166] "Convenio" "Usuario óptica" "Paso por la óptica" "Usuario óptica" ...
## $ fecha_registro : POSIXct[1:1166], format: "2024-05-20" "2024-05-24" ...
## $ pac_sexo : chr [1:1166] "Masculino" "Femenino" "Femenino" "Femenino" ...
## $ pac_vincula : chr [1:1166] "No registra" "No registra" "No registra" "No registra" ...
## $ tipo_afiliciacion : chr [1:1166] "No registra" "Particular" "Particular" "Particular" ...
## $ pac_observa : chr [1:1166] NA NA NA "Ninguna" ...
## $ rango_etareo : chr [1:1166] "ADULTO" "JÓVENES" "ADULTO" "ADULTO" ...
## $ pac_cond_disc : num [1:1166] 0 0 2 0 2 0 0 0 0 0 ...
## $ tipo_regimen : num [1:1166] 2 2 2 2 2 2 2 2 2 2 ...
## $ Agudeza_visual_OD : logi [1:1166] NA NA NA NA NA NA ...
## $ Agudeza_visual_OI2 : logi [1:1166] NA NA NA NA NA NA ...
## $ Error_refractivo_total_D: logi [1:1166] NA NA NA NA NA NA ...
## $ Horas_pantalla_dia : logi [1:1166] NA NA NA NA NA NA ...
## $ Horas_aire_libre_semana : logi [1:1166] NA NA NA NA NA NA ...
## $ Hobby_principal : logi [1:1166] NA NA NA NA NA NA ...
## $ Predisposicion_genetica : logi [1:1166] NA NA NA NA NA NA ...
Estructura del Conjunto de Datos ETL
str(ccd_vision2020_ETL)
## tibble [1,166 × 13] (S3: tbl_df/tbl/data.frame)
## $ pac_id : num [1:1166] 1 2 4 5 6 7 8 9 10 11 ...
## $ edad_paciente : num [1:1166] 29 25 55 56 35 37 1 29 41 75 ...
## $ ocupacion : chr [1:1166] "admin" "Asesor Comercial" "OTRO" "OTRO" ...
## $ canal_difusion : chr [1:1166] "Convenio" "Usuario óptica" "Paso por la óptica" "Usuario óptica" ...
## $ fecha_registro : POSIXct[1:1166], format: "2024-05-20" "2024-05-24" ...
## $ pac_sexo : chr [1:1166] "Masculino" "Femenino" "Femenino" "Femenino" ...
## $ rango_etareo : chr [1:1166] "ADULTO" "JÓVENES" "ADULTO" "ADULTO" ...
## $ AV_OD : num [1:1166] 0.847 0.213 0.717 0.592 0.404 ...
## $ AV_OI : num [1:1166] 0.488 0.765 0.799 0.142 0.974 ...
## $ Horas_pd : num [1:1166] 5.82 4.79 8.77 0.78 3.07 0.62 8.99 1.86 1.22 0.38 ...
## $ Horas_af : num [1:1166] 5 8 9 3 7 5 4 2 1 9 ...
## $ Hobby_ppantalla : chr [1:1166] "si" "no" "no" "no" ...
## $ Predisposicion_genetica: chr [1:1166] "1" "1" "0" "0" ...
1.3. Estimaciones multivariadas
El vector de medias y la matriz de varianzas‑covarianzas permiten
describir de forma conjunta el nivel típico, la dispersión y las
relaciones lineales entre las variables métricas registradas para los
pacientes de la óptica. En este estudio se consideran como variables
aleatorias cuantitativas: edad_paciente, Agudeza_visual_OD,
Agudeza_visual_OI, Horas_pantalla_dia y Horas_af. El vector de medias
resume, para cada una de estas variables, el valor promedio observado en
la muestra, de modo que sirve como referencia del “perfil medio” de los
pacientes en términos de edad, condición visual y hábitos de uso de
pantallas y de actividad física. La matriz de varianzas‑covarianzas, por
su parte, cuantifica en su diagonal principal la variabilidad individual
de cada variable alrededor de su media, mientras que en las posiciones
fuera de la diagonal recoge las covarianzas entre pares de variables,
las cuales describen la intensidad y el sentido de sus relaciones
lineales.
Trabajar simultáneamente con el vector de medias y la matriz de
varianzas‑covarianzas resulta esencial en el análisis multivariado
porque permite capturar, en un solo objeto matemático, tanto la
tendencia central como las interdependencias entre las variables de
interés. A partir de estas estimaciones es posible derivar la matriz de
correlaciones, que normaliza las covarianzas y facilita comparar la
fuerza de asociación entre variables medidas en escalas diferentes, como
las horas frente a pantallas y las medidas de agudeza visual. Estos
elementos constituyen la base para los procedimientos posteriores de
análisis de componentes principales, conglomerados y modelos de
regresión.
Vector de Promedios y Boxplots
apply(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], 2, mean)
## edad_paciente AV_OD AV_OI Horas_pd Horas_af
## 38.7178388 0.5367784 0.5662855 4.9418525 5.4631218
ccd_vision2020_ETL_Reducido = ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)]
nombres_boxplots <- c("edad_paciente", "AV_OD", "AV_OI", "Horas_pd", "Horas_af")
par(mfrow = c(1, ncol(ccd_vision2020_ETL_Reducido)))
invisible(lapply(1:ncol(ccd_vision2020_ETL_Reducido), function(i) {
boxplot(ccd_vision2020_ETL_Reducido[, i],
main = nombres_boxplots[i])}))

Matriz de Varianzas-Covarianzas
round(cov(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)]),2)
## edad_paciente AV_OD AV_OI Horas_pd Horas_af
## edad_paciente 502.21 -0.28 -0.14 2.86 -0.55
## AV_OD -0.28 0.07 0.00 -0.02 -0.03
## AV_OI -0.14 0.00 0.07 -0.05 0.00
## Horas_pd 2.86 -0.02 -0.05 8.08 0.05
## Horas_af -0.55 -0.03 0.00 0.05 8.31
Matriz de Correlaciones
round(cor(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)]),3)
## edad_paciente AV_OD AV_OI Horas_pd Horas_af
## edad_paciente 1.000 -0.048 -0.024 0.045 -0.009
## AV_OD -0.048 1.000 0.029 -0.020 -0.042
## AV_OI -0.024 0.029 1.000 -0.073 -0.005
## Horas_pd 0.045 -0.020 -0.073 1.000 0.006
## Horas_af -0.009 -0.042 -0.005 0.006 1.000
El vector de medias y la matriz de
varianzas-covarianzas conforman un conjunto de herramientas
fundamentales para describir el comportamiento posicional, dispersivo y
correlacional de las variables aleatorias en un conjunto de datos. Estas
medidas son esenciales en el análisis multivariado, porque permiten
capturar tanto la tendencia central como las interdependencias entre las
variables.
1.4. Gráficas multivariadas
En esta sección se presenta el cálculo e interpretación de tres
objetos fundamentales: Vector de Medias \(\bar x\) , Matriz de
Varianzas-Covarianzas \(S\) y
Matriz de Correlaciones \(R\)., construidos a partir de las variables
edad_paciente, Agudeza_visual_OD, Agudeza_visual_OI, Horas_pantalla_dia
y Horas_af. La pestaña correspondiente al vector de medias y a los
boxplots univariantes permite describir el comportamiento posicional y
dispersivo de cada variable. En términos generales, se observa si la
distribución de la edad de los pacientes se aproxima a una forma
aproximadamente simétrica o si presenta sesgos hacia edades más jóvenes
o más avanzadas, así como el rango típico de horas diarias frente a
pantallas y de actividad física. De igual manera, los diagramas de caja
de las agudezas visuales del ojo derecho e izquierdo permiten detectar
la presencia de valores extremos y comparar, de forma visual, posibles
diferencias entre ambos ojos.
A partir de la matriz de varianzas‑covarianzas y de la matriz de
correlaciones se examinan las relaciones lineales entre las variables
métricas. La inspección de los coeficientes de correlación permite
identificar, por ejemplo, si existe una asociación apreciable entre el
tiempo de exposición diaria a pantallas y la agudeza visual, o entre la
edad y la cantidad de horas de actividad física. Valores de correlación
cercanos a cero indican relaciones lineales débiles o inexistentes, lo
que sugiere que las variables son relativamente independientes desde el
punto de vista lineal; por el contrario, coeficientes alejados de cero
señalan asociaciones que pueden ser clínicamente relevantes y que
conviene explorar en mayor detalle en fases posteriores del análisis. En
conjunto, estos resultados proporcionan una primera aproximación a la
estructura interna del conjunto de datos y orientan la selección de
técnicas multivariantes apropiadas para las siguientes secciones.
Diagrama Conjunto de Dispersión, Distribución y
Correlaciones[SA]
ggpairs(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)])

Diagrama Conjunto de Dispersión, Distribución y
Correlaciones[CA]
ccd_vision2020_ETL$rango_etareo <- factor(ccd_vision2020_ETL$rango_etareo)
levels= c (1,2,3,4,5)
labels= c ( "Edad" , "AV_OD" , "AV_OI" , "Horas_pd" , "Horas_af")
ggpairs(ccd_vision2020_ETL, column = c(2,8,9,10,11), aes(color = rango_etareo, alpha = 0.5), upper = list(continuous = wrap("cor", size = 2.5)))

Diagrama de Estrellas
set.seed(120522)
ccd_vision2020_ETL_MUESTREADO = ccd_vision2020_ETL[sample(1:nrow(ccd_vision2020_ETL),23),-c(1,3,4,5,6,7,12,13)]
stars(ccd_vision2020_ETL_MUESTREADO, len = 1, cex = 0.4, key.loc = c(10, 2), draw.segments = TRUE)

Caras de Chernoff
set.seed(120522)
ccd_vision2020_ETL_MUESTREADO = ccd_vision2020_ETL [sample(1:nrow(ccd_vision2020_ETL),23),-c(11,3,4,5,6,7,12,13)]
faces(ccd_vision2020_ETL_MUESTREADO)

## effect of variables:
## modified item Var
## "height of face " "pac_id"
## "width of face " "edad_paciente"
## "structure of face" "AV_OD"
## "height of mouth " "AV_OI"
## "width of mouth " "Horas_pd"
## "smiling " "pac_id"
## "height of eyes " "edad_paciente"
## "width of eyes " "AV_OD"
## "height of hair " "AV_OI"
## "width of hair " "Horas_pd"
## "style of hair " "pac_id"
## "height of nose " "edad_paciente"
## "width of nose " "AV_OD"
## "width of ear " "AV_OI"
## "height of ear " "Horas_pd"
1.5. Normalidad multivariada
Es posible analizar o determinar la distribución multivariada de un
conjunto de datos mediante métodos descriptivos, como los gráficos, o
inferenciales, como las pruebas estadísticas. Mientras que los
procedimientos inferenciales permiten obtener conclusiones más
generalizables, los gráficos resultan útiles como soporte para la
interpretación de los resultados.
En este apartado se aborda la aplicación de procedimientos
inferenciales para verificar si el conjunto de datos de trabajo,
respecto a sus variables numéricas, sigue una distribución normal
multivariada (DNM). Las pruebas de normalidad multivariada (PNM) que se
aplicarán son: Mardia, Henze-Zirkler, Doornik-Hansen y Royston. Estas
pruebas de normalidad se realizan bajo un nivel de significancia
determinado \(\alpha = 0.05\) y a las
hipótesis:\[H_0: \text {Las variables tienen
una DNM}\] \[H_1: \text {Las variables
NO tienen una DNM}\]
La prueba de Mardia se fundamenta en las extensiones
de asimetría y curtosis, el cuadrado de la distancia de Mahalanobis, el
número de variables \(p\) a analizar y
el número de registros \(n\). Asimismo,
se considera que la estadística de la prueba para la asimetría sigue una
distribución \(\chi^2\), mientras que
la estadística para la curtosis se distribuye de manera aproximada de
forma normal.
La prueba de Henze-Zirkler se basa en la distancia
funcional, ya que si el conjunto de datos sigue una distribución normal
multivariada, el estadístico de la prueba se distribuye de manera
aproximada como una lognormal, con parámetros de media \(\mu\) y varianza \(\sigma^2\).
La prueba de Doornik-Hansen se basa en la asimetría
y la curtosis de un conjunto de datos multivariados, los cuales se
transforman para asegurar la independencia. Se considera más potente que
la prueba de Shapiro-Wilk en casos multivariados. El estadístico de la
prueba se define como la suma de las transformaciones al cuadrado de la
asimetría y la curtosis, y sigue aproximadamente una distribución \(\chi^2\).
Por otro lado, la prueba de Royston utiliza las pruebas de
Shapiro-Wilk o Shapiro-Francia para evaluar la normalidad
multivariada. Si la curtosis es mayor que 3, se emplea Shapiro-Francia
para distribuciones leptocúrticas, mientras que para distribuciones
platicúrticas se utiliza Shapiro-Wilk. Los parámetros en esta prueba se
obtienen mediante aproximaciones polinomiales.
1.6 Planteamiento y Desarrollo
A partir del conjunto de datos descrito en la sección 1.2, se aplica
una prueba estadística de normalidad multivariada con nivel de
significancia \(\alpha = 0.05\), con el
propósito de evaluar si el vector formado por las variables métricas
proviene de una población con distribución normal multivariada. En este
estudio, las variables numéricas en escala de razón son:
edad_paciente, Agudeza_visual_OD,
Agudeza_visual_OI, Horas_pantalla_dia
y Horas_af. Antes de realizar las pruebas, estas
variables se estandarizan para garantizar comparabilidad y estabilidad
numérica en los cálculos.
La navegación a través de las pestañas presenta de manera separada
los resultados de las principales pruebas de normalidad multivariada
consideradas: Mardia, Henze–Zirkler, Doornik–Hansen y Royston. En la
pestaña correspondiente a la PNM de Mardia se reportan
los estadísticos de asimetría y curtosis multivariadas, junto con sus
respectivos \(p\)-valores. Dado que,
para al menos uno de estos componentes, el \(p\)-valor resulta menor que el nivel de
significancia establecido, se procede a rechazar la hipótesis nula de
normalidad multivariada, concluyendo que el conjunto de variables
métricas no sigue una distribución normal multivariada.
De forma consistente, la pestaña asociada a la PNM de
Henze–Zirkler muestra un \(p\)-valor inferior a \(\alpha = 0.05\), lo que lleva igualmente a
rechazar la hipótesis nula y aceptar la hipótesis alternativa de que los
datos no provienen de una distribución normal multivariada. Resultados
análogos se observan en la PNM de Doornik–Hansen, donde
el \(p\)-valor obtenido también es
menor que el nivel de significancia, reforzando la decisión de rechazar
la normalidad. Finalmente, la PNM de Royston presenta
un \(p\)-valor inferior a \(\alpha\), confirmando que, en conjunto, las
variables edad_paciente,
Agudeza_visual_OD, Agudeza_visual_OI,
Horas_pantalla_dia y Horas_af no se
ajustan a una distribución normal multivariada. En consecuencia, todas
las pruebas aplicadas coinciden en que, al nivel de significancia
considerado, no se sustenta la hipótesis nula de normalidad multivariada
para el vector de variables métricas, aceptándose la hipótesis
alternativa.
PNM Mardia
mardia(ccd_vision2020_ETL[, -c(11,3,4,5,6,7,12,13)])
## $mv.test
## Test Statistic p-value Result
## 1 Skewness 38.1796 0.327 YES
## 2 Kurtosis -11.1804 0 NO
## 3 MV Normality <NA> <NA> NO
##
## $uv.shapiro
## W p-value UV.Normality
## pac_id 0.954 0 No
## edad_paciente 0.9721 0 No
## AV_OD 0.9565 0 No
## AV_OI 0.9577 0 No
## Horas_pd 0.9544 0 No
PNM Henze-Zirkler
mhz(ccd_vision2020_ETL[, -c(11,3,4,5,6,7,12,13)])
## $mv.test
## Statistic p-value Result
## 2.4619 0 NO
##
## $uv.shapiro
## W p-value UV.Normality
## pac_id 0.954 0 No
## edad_paciente 0.9721 0 No
## AV_OD 0.9565 0 No
## AV_OI 0.9577 0 No
## Horas_pd 0.9544 0 No
PNM MSK
msk(ccd_vision2020_ETL[, -c(11,3,4,5,6,7,12,13)], B=10)
## $mv.test
## Statistic p-value Result
## 163.18 0 NO
##
## $uv.shapiro
## W p-value UV.Normality
## pac_id 0.954 0 No
## edad_paciente 0.9721 0 No
## AV_OD 0.9565 0 No
## AV_OI 0.9577 0 No
## Horas_pd 0.9544 0 No
PNM nTest
mvnTest(ccd_vision2020_ETL[, -c(11,3,4,5,6,7,12,13)], B=10)
## $mv.test
## Tn p-value Result
## 1 0 NO
##
## $uv.shapiro
## W p-value UV.Normality
## pac_id 0.954 0 No
## edad_paciente 0.9721 0 No
## AV_OD 0.9565 0 No
## AV_OI 0.9577 0 No
## Horas_pd 0.9544 0 No
Fase 2 [Componentes Principales]
En esta segunda etapa del estudio, se presentarán
cálculos, visualizaciones e interpretaciones basadas en el conjunto de
datos analizado previamente en la Fase 1. Ahora, el
enfoque se centrará en el análisis de componentes principales (ACP)
aplicado a las variables cuantitativas, incluyendo aspectos como la
selección de componentes, calidad de representación, contribuciones y su
interpretación.
2.1. Objetivos
El ACP se logra a lo largo de las siguientes fases:
generación de nuevas variables, reducción dimensional del espacio de los
datos, eliminación de variables de poco aporte e interpretación de los
componentes resultantes en el contexto del problema del cual se
obtuvieron los dato.
Estimado lector, si desea explorar los fundamentos de este análisis
con mayor profundidad. Los detalles del conjunto de datos se encuentran
descritos en la Sección 1.2, mientras que los
principios teóricos que sustentan este estudio están cuidadosamente
desarrollados en la denominada Fase 1. Una lectura
detenida de estas secciones enriquecerá su comprensión y apreciación del
trabajo presentado.
2.2. Selección de Componentes
Como señalan Díaz Morales y Morales Rivera (2012), el Análisis de
Componentes Principales (ACP) permite reorganizar un
conjunto de datos multivariado al reducir el número de variables, sin
requerir suposiciones específicas sobre la distribución de probabilidad
de estas. Esta reducción se alcanza mediante la creación de
combinaciones lineales de las variables originales, diseñadas para
captar la mayor variabilidad posible en los datos. De este modo, el
ACP genera nuevas variables, denominadas componentes
principales, que presentan independencia estadística y ausencia de
correlación, siempre bajo el supuesto de normalidad.
2.3. Planteamiento y Desarrollo
A partir de las variables cuantitativas del conjunto de datos
descrito en la Sección 1.2, se requiere
inicialmente determinar el porcentaje de varianza explicado por cada
dimensión tras realizar el Análisis de Componentes Principales (ACP).
Posteriormente, con base en el autovalor promedio o mediante un gráfico
de sedimentación, se debe decidir cuántos componentes conservar.
La navegación a través de las pestañas muestra que el conjunto de
datos, en relación con sus variables numéricas, puede ser representado
por un conjunto más pequeño de dimensiones que retiene el \(43.01%\) de la variabilidad total en las
dos primeras dimensiones. Este resultado sugiere que la varianza está
distribuida de manera relativamente uniforme entre las principales
dimensiones, lo que indica una estructura interna en la que las
variables originales no están altamente
correlacionadas. En particular:
La Matriz ACP muestra cinco dimensiones, donde la
primera retiene el \(22.49%\) de la
varianza, seguida por la segunda con un \(20.52%\), y la tercera con un \(19.85\)\(%\). Las dos últimas dimensiones explican
un \(18.82%\) y un \(18.31%\), respectivamente. En este sentido,
la representatividad de la combinación lineal que define la
dimensión 1 es moderadamente superior en comparación
con las demás. Como esta matriz no proporciona información directa sobre
las variables originales, se continúa explorando la identificación de
las variables que más contribuyen a la dimensión con el mayor valor
propio.
La Matriz de Correlaciones ayuda a describir las
relaciones entre las variables que conforman la dimensión 1. Según esta
matriz, las correlaciones entre las variables son en su mayoría bajas,
con un valor máximo de \(0.04\) entre
Horas_pd y edad_paciente. Esto indica
que las variables no están fuertemente relacionadas entre sí, lo que
podría influir en cómo contribuyen a la combinación lineal que define la
primera dimensión.
La pestaña Valores y Vectores Propios presenta los resultados
obtenidos a partir del análisis de la matriz de correlaciones del
conjunto de datos clínicos. En este análisis se verifica que la suma de
los valores propios coincide con el número de variables analizadas, lo
que garantiza que la totalidad de la variabilidad del sistema queda
representada por el conjunto de componentes principales. A partir de
estos valores propios se determinan directamente las proporciones de
varianza explicada por cada componente.
Por otra parte, la matriz de vectores propios proporciona los
coeficientes que definen las combinaciones lineales de las variables
originales que dan lugar a cada componente principal. Estos
coeficientes, también conocidos como cargas factoriales, permiten
identificar el peso y la dirección de la contribución de cada variable
en las nuevas dimensiones del análisis.
En particular, para la primera componente principal (CP1), y
considerando los coeficientes redondeados a dos cifras decimales, donde
Edad corresponde a la edad del paciente, AV_OD y AV_OI representan la
agudeza visual del ojo derecho e izquierdo respectivamente, Horas_PD el
tiempo de uso de pantallas digitales y Horas_AF las horas de actividad
física (todas variables previamente estandarizadas), la componente puede
expresarse como:
\(Componente 1 = 0.46 * Edad − 0.44 * AV_OD
− 0.52 * AV_OI + 0.55 * Horas_PD + 0.16 * Horas_AF\)
Esta formulación evidencia que la primera componente está
principalmente influenciada por el uso de pantallas digitales, la edad
del paciente y la agudeza visual, especialmente del ojo izquierdo. En
consecuencia, esta dimensión resume un patrón clínico asociado a los
hábitos visuales y su relación con la función visual, facilitando la
interpretación de las interacciones multivariantes presentes en los
datos.
Los gráficos de Cattell y
Cattell-Kaiser, conocidos por sus formas de codo y
sedimentación, son herramientas útiles para decidir cuántas componentes
retener en un análisis de reducción de dimensión, asegurando que se
conserve suficiente variabilidad para abordar el problema.
El Gráfico de Cattell muestra cómo varía la
pendiente entre las componentes, destacando que la primera componente
tiene una capacidad explicativa significativamente mayor, explicando el
\(22.5\)\(%\) de la varianza total. Este cambio en la
pendiente, también conocido como “punto de inflexión”, sugiere que los
primeros componentes son clave para retener, ya que capturan la mayor
parte de la variabilidad del conjunto de datos.
Además, el Gráfico de Cattell-Kaiser combina esta
visualización con el criterio de Kaiser, que recomienda retener los
componentes con un valor propio superior a 1. Según este criterio, solo
la primera componente cumple con esta condición, lo que inicialmente
respalda la elección de retener únicamente esta. Sin embargo, al
considerar la varianza acumulada, se observa que los tres primeros
componentes explican juntos el \(62.9%\) de la variabilidad, lo que sugiere
que incluir más de un componente podría ser valioso para capturar
dimensiones adicionales relevantes en el análisis, especialmente en un
contexto clínico donde diferentes factores pueden influir en el
diagnostico de enfermedades oculares.
Por tanto, se toma la decisión de trabajar con dos componentes, ya
que permiten capturar patrones importantes relacionados con las
afecciones cardiovasculares sin añadir una complejidad innecesaria al
análisis. Esto facilita la interpretación de los resultados y garantiza
una representación significativa de los datos.
Matriz ACP
get_eigenvalue(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 6, scale.unit = TRUE, graph = F))
## eigenvalue variance.percent cumulative.variance.percent
## Dim.1 1.1246032 22.49206 22.49206
## Dim.2 1.0260493 20.52099 43.01305
## Dim.3 0.9926047 19.85209 62.86515
## Dim.4 0.9410322 18.82064 81.68579
## Dim.5 0.9157105 18.31421 100.00000
Matriz de Correlaciones
round(cor(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)]),2)
## edad_paciente AV_OD AV_OI Horas_pd Horas_af
## edad_paciente 1.00 -0.05 -0.02 0.04 -0.01
## AV_OD -0.05 1.00 0.03 -0.02 -0.04
## AV_OI -0.02 0.03 1.00 -0.07 0.00
## Horas_pd 0.04 -0.02 -0.07 1.00 0.01
## Horas_af -0.01 -0.04 0.00 0.01 1.00
Valores y Vectores Propios
princomp(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], cor = TRUE)$sdev^2
## Comp.1 Comp.2 Comp.3 Comp.4 Comp.5
## 1.1246032 1.0260493 0.9926047 0.9410322 0.9157105
princomp(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], cor = TRUE)$loadings[ ,1:5]
## Comp.1 Comp.2 Comp.3 Comp.4 Comp.5
## edad_paciente 0.4565059 0.08228379 0.6897766 0.3677253 0.4169150
## AV_OD -0.4405769 0.51649857 -0.2976844 0.5439600 0.3932082
## AV_OI -0.5186890 -0.26412446 0.4469383 0.4457841 -0.5125648
## Horas_pd 0.5492963 0.31829276 -0.2698032 0.4208646 -0.5891031
## Horas_af 0.1634920 -0.74524264 -0.4037878 0.4393577 0.2486042
Correlaciones Comparadas
par(mfrow=c(1,2))
corrplot::corrplot(cor(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)]), method = "color", type = "upper", number.cex = 0.4)
corrplot::corrplot(cor(princomp(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], cor = TRUE)$scores), method = "color", type = "upper", number.cex = 0.4)

Gráfico de Cattell
fviz_eig(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], scale.unit = T, graph = F), addlabels = T, ylim=c(0,90), main = "")
## Warning in geom_bar(stat = "identity", fill = barfill, color = barcolor, :
## Ignoring empty aesthetic: `width`.

Gráfico de Cattell-Kaiser
scree(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)],factors = FALSE, pc = TRUE, main ="")

2.4. Calidad de Representación
Con base en la referencia de ,se confirma que, tras reducir la
dimensionalidad del conjunto de datos y entender que sus variables
estandarizadas se representan gráficamente como proyecciones de una
hiperesfera de correlaciones, es esencial iniciar la interpretación de
las componentes a partir de esas correlaciones. Posteriormente, se debe
evaluar la calidad de las representaciones obtenidas, considerando la
reducción dimensional aplicada al conjunto de datos y su impacto en las
variables.
Es necesario evaluar la calidad de la representación de las variables
cuantitativas en relación con el número de dimensiones calculadas que
capturan la mayor proporción de variabilidad; para más detalles,
consultar la sección 2.3.
2.5 Desarrollo del Análisis.
Explorar las pestañas revela que reducir la dimensionalidad del
conjunto de datos permite analizar la calidad de la representación,
usando una escala de contribuciones relativas. Esta escala se basa en un
cociente de proyecciones con propiedades aditivas y una escala continua
que varía de 0 a 1. En particular:
El Círculo de Correlaciones expresa que se pueden
identificar patrones significativos entre las variables originales, en
el marco de una selección de componentes principales. Dimensión
1 (Dim1): Explica el \(22.5\%\) de la varianza. Muestra una
correlación positiva con variables como
Horas_pd y
edad_paciente, las cuales están orientadas
hacia este eje y cercanas a la frontera del círculo unitario. Esto
indica que estas variables contribuyen
significativamente a la construcción de Dim1, que podría estar
capturando características comunes a ellas.
Por otra parte, la Dimensión 2 (Dim2): Explica el
\(20.5\%\) de la varianza. Está
asociada con variables como Horas_af, que
tiene una alta correlación positiva. Por el contrario,
las variables Agudeza_visual_OD y
Agudeza_visual_OI están correlacionadas
negativamente con Dim2. Esto sugiere que Dim2 está representando un
fenómeno diferente o complementario al descrito por Dim1.
Otro aspecto destacable es la relación mostrada entre pares de
variables en el círculo: La Correlación Positiva Fuerte
entreHoras_pd y
edad_paciente presentan vectores cercanos,
indicando una relación positiva. Ademas, de tener una
*Correlación Negativa Fuerte entre
Horas_pd y
edad_paciente están en oposición directa a
Agudeza_visual_OI, lo que implica una
fuerte correlación negativa.Y una Poca Correlación de
Ortogonalidad: en variables como
Horas_af y
Agudeza_visual_OI muestran vectores casi
perpendiculares, sugiriendo una baja relación en este contexto
bidimensional.
Esta interpretación se limita a la estructura de correlaciones
representada en el gráfico y describe cómo las variables originales
contribuyen a las dimensiones principales seleccionadas, sin
implicar relaciones causales o de dependencia directa entre
ellas.
La Matriz de Representación (\(\cos^2\)) muestra la calidad con la que
cada variable es representada por las dimensiones principales. Este
análisis se basa en la interpretación de la correlación entre variables
(Círculo de Correlaciones), la calidad de representación (\(\cos^2\)), y la posición de los individuos
(Coordenadas Individuales) en el espacio factorial:
Asociación Fuerte con Dimensión 1 (Dim1): Las
variables Horas_pd (\(\cos^2 = 0.339\)) y
Agudeza_visual_OI (\(\cos^2 = 0.303\)) tienen los valores de
coseno cuadrado más altos en relación con la Dimensión
1. Esto indica que están fuertemente asociadas con este
componente y aportan significativamente a él.
Varianza Distribuida en Dimensiones Posteriores: En
contraste, la variable edad_paciente tiene
un valor bajo de coseno cuadrado en la Dimensión 1
(0.234) y la Dimensión 2 (0.007). Esto sugiere que su
varianza se distribuye más hacia otras dimensiones, especialmente la
Dimensión 3, donde muestra una mejor representación
(0.472). Esto afecta la calidad de representación de
edad_paciente en el plano principal
(Dim1/Dim2).
El gráfico de la Calidad de Representación
(codificado por color) confirma visualmente la contribución al plano
Dim1/Dim2. Los elementos mejor representados por las componentes 1 y 2
incluyen Horas_af (el vector más rojo) y
Agudeza_visual_OD (naranja), lo cual
indica que la mayor parte de su varianza es explicada por este plano
bidimensional. Por otra parte, la variable
edad_paciente se muestra en un color más
claro (amarillo), confirmando su baja representación en
este plano bidimensional, lo cual es coherente con su fuerte \(\cos^2\) en la Dimensión 3.
- Roles Dimensionales: La Dimensión
2 tiene una excelente representación de
Horas_af (vector alineado verticalmente),
lo que implica que, aunque la componente 1 es la principal para
Horas_pd, la componente 2 también juega un papel relevante
en la representación de ciertos aspectos.
Las Coordenadas Individuales permiten identificar
los perfiles de los registros (pacientes) en relación con las
dimensiones principales, lo cual es clave para la segmentación:
Extremos en Dimensión 1 (Correlacionado con
Horas/Edad): Los registros # 6 (2.485) y
# 2 (1.866) tienen los valores positivos más extremos
en Dim1. Estos pacientes representan perfiles con altos valores en las
variables positivamente correlacionadas con Dim1, como
Horas_pd y edad_paciente.
Extremos en Dimensión 2 (Correlacionado con
Horas_af): En la dimensión 2, los registros
# 4 (1.622) y # 17 (1.048) destacan
por sus valores positivos. Estos pacientes muestran un comportamiento
similar en la variable Horas_af (correlacionada
positivamente con Dim2).
Perfiles Promedio o Mal Representados: Los
registros con valores muy cercanos al origen (por ejemplo, #
14 con 0.034 en Dim1) son perfiles promedio o su varianza es
explicada por dimensiones posteriores.
Círculo de Correlaciones
fviz_pca_var(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], scale.unit = T, graph = F),col.var="#3B83BD", repel = T, col.circle = "#CDCDCD", ggtheme = theme_bw())
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## ℹ The deprecated feature was likely used in the ggpubr package.
## Please report the issue at <https://github.com/kassambara/ggpubr/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## ℹ The deprecated feature was likely used in the factoextra package.
## Please report the issue at <https://github.com/kassambara/factoextra/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Matriz de Representación
(get_pca_var(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 5, scale.unit = TRUE, graph = F)))$cos2
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## edad_paciente 0.23436466 0.006946992 0.47227316 0.1272481 0.15916706
## AV_OD 0.21829452 0.273719975 0.08796065 0.2784444 0.14158045
## AV_OI 0.30256128 0.071578979 0.19827664 0.1870052 0.24057790
## Horas_pd 0.33932255 0.103949347 0.07225545 0.1666822 0.31779045
## Horas_af 0.03006022 0.569854035 0.16183883 0.1816523 0.05659462
Calidad de Representación
fviz_pca_var(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 5, scale.unit = TRUE, graph = F), col.var="cos2", gradient.cols=c("#00AFBB","#E7B800","#FC4E07"), repel = TRUE)

Coordenadas Individuales
head((PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 5, scale.unit = TRUE, graph = F))$ind$coord, n = 23L)
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## 1 -0.42567484 -0.88216766 -0.81037907 0.41717919 -0.22422680
## 2 -0.01336895 1.57443439 -0.04585009 -0.19808633 0.89292052
## 3 0.49754320 0.30587312 -0.16098551 2.15496652 0.37533984
## 4 0.17002548 -0.77995612 0.47196388 -1.32851564 -1.90133626
## 5 -0.94713091 1.30481644 0.70942255 0.32409751 0.56308347
## 6 -1.14497181 -0.39163920 -0.17623904 -0.32755679 -1.57295708
## 7 0.27935505 -0.74035358 -1.52164253 -0.57119225 1.46939879
## 8 -1.36730302 -0.02579698 1.07534578 -0.88669061 0.54556754
## 9 -0.43180412 -1.58915621 0.08258649 -1.48771627 -1.57908548
## 10 -0.94234124 1.16957605 1.33834650 1.46030323 -1.64537774
## 11 1.22586500 0.20579448 0.91825949 1.17348883 1.25586736
## 12 -1.35037530 -0.14630831 -1.63139751 0.07945244 -0.68250829
## 13 0.82657970 0.11400445 -0.26658286 1.53032125 -0.91585980
## 14 0.03411531 -1.70147855 1.17619498 1.02583523 -0.33980577
## 15 0.31175414 2.04521114 0.29501956 0.86617469 1.05250095
## 16 0.66987214 -0.98774417 1.57400750 0.11141607 1.35202561
## 17 -1.44509242 0.90239818 -0.36157649 -1.47823560 0.37625363
## 18 -0.18279665 -1.10395541 0.10821778 1.35301876 -0.56745099
## 19 0.22284154 1.77410255 -1.07495769 -0.73307877 -0.41988904
## 20 1.79252255 -0.15604542 1.72697880 -0.79170369 -0.05372953
## 21 -0.21705558 0.12385166 -0.49414413 1.82978387 -0.67382747
## 22 -1.06144476 0.63277606 0.93237029 -1.94863520 1.07637249
## 23 -0.78089970 1.69774737 -0.34949488 0.64487642 -0.05193312
2.6. Contribuciones
Los autores señalan que la interpretación de los resultados está
estrechamente ligada al cálculo de elementos como coordenadas,
contribuciones y cosenos cuadrados. Por lo tanto, es esencial que las
variables estén bien conceptualizadas y contextualizadas para facilitar
su comprensión. En este sentido, analizar la contribución de cada
variable a una componente ayuda a interpretar los resultados, mostrando
cómo cada una influye en la definición de las componentes generadas.
Este análisis se lleva a cabo en esta sección para determinar el aporte
de cada variable en la construcción de las componentes.
2.7. Planteamiento y Desarrollo
Basado en las variables cuantitativas del conjunto de datos descrito
en la sección 1.2, se requiere determinar las
contribuciones de cada variable en la construcción de las
componentes.
La navegación a través de las pestañas facilita la visualización de
las contribuciones de las variables del conjunto de datos en forma de
representaciones numéricas y gráficas, permitiendo comprender cómo cada
variable influye en la construcción de las componentes. Esto permite
analizar la proporción de variabilidad que cada variable aporta a la
variabilidad total de la componente con la que está asociada.
La Matriz de Contribuciones muestra cómo cada
variable contribuye a la retención de variabilidad en la construcción de
cada componente. Los diagramas de barras, que se visualizan en las
pestañas desde Contribuciones a D1 hasta
Contribuciones a D5, ilustran las contribuciones
específicas de las variables para explicar la variabilidad en cada
componente. Cada gráfico incluye una línea que indica la
contribución media, lo que facilita la identificación de las
variables que tienen mayor impacto en la explicación de la variabilidad
de los componentes.
En Contribuciones a D1 se visualiza que las
variables por encima de la contribución media:
Agudeza_visual_OI y Horas_pd,retienen
aproximadamente el \(57.07%\) de la
variabilidad del componente 1.
En Contribuciones a D2 se visualiza que las
variables por encima de la contribución media: Horas_af
y Agudeza_visual_OD retienen aproximadamente el \(82.22%\) de la variabilidad del componente
2.
En Contribuciones a D3 se visualiza que las
variables por encima de la contribución media:
Edad_paciente y Agudeza_visual_OI
retienen aproximadamente el \(67.56%\)
de la variabilidad del componente 3.
En Contribuciones a D4 se visualiza que la variable
por encima de la contribución media: Agudeza_visual_OD
retiene aproximadamente el \(29.59%\)
de la variabilidad del componente 4.
En Contribuciones a D5 se visualiza que las
variables por encima de la contribución media: Horas_pd
y Agudeza_visual_OI retienen aproximadamente el \(60.97%\) de la variabilidad del componente
5.
Con los datos procesados hasta ahora se puede proceder con la
intepretación de los componentes.
Matriz de Contribuciones
(get_pca_var(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 5, scale.unit = TRUE, graph = F)))$contrib
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## edad_paciente 20.839764 0.6770621 47.579177 13.52219 17.381811
## AV_OD 19.410803 26.6770775 8.861599 29.58925 15.461268
## AV_OI 26.903825 6.9761732 19.975387 19.87235 26.272267
## Horas_pd 30.172646 10.1310283 7.279378 17.71270 34.704250
## Horas_af 2.672962 55.5386588 16.304459 19.30352 6.180405
Contribuciones a D1
fviz_contrib(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 1, top = 10)

Contribuciones a D2
fviz_contrib(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 2, top = 10)

Contribuciones a D3
fviz_contrib(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 3, top = 10)

Contribuciones a D4
fviz_contrib(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 4, top = 10)

Contribuciones a D5
fviz_contrib(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 5, top = 10)

2.8. Interpretación
Representar los registros en un espacio de dimensiones reducidas
permite situarlos en un plano de factores, lo que facilita su análisis e
interpretación. Las variables reducidas se corresponden con las
componentes principales, que se utilizan como ejes en el plano y cuyos
valores son los puntajes de las componentes. La distancia entre los
puntos representados por estos puntajes es clave para identificar
similitudes entre los perfiles de las observaciones. No obstante, las
similitudes pueden aparecer solo en algunas variables y no en todas.
Así, se busca que las distancias en el espacio de alta dimensión se
conserven en el espacio reducido, manteniendo la estructura de las
relaciones entre los datos. Según ].
2.9. Planteamiento y Desarrollo
La navegación entre las pestañas facilita la visualización de objetos
gráficos y matriciales que, al integrar los resultados de las secciones
anteriores, fortalecen la interpretación de las contribuciones de las
componentes calculadas. Tal como se presentó en la sección 2.3, el número de componentes seleccionadas
se redujo a dos, siguiendo el criterio de Kaiser y
considerando la varianza acumulada. Estas dos componentes explican
conjuntamente el \(43.01\)\(%\) de la variabilidad de los datos, lo que
permite capturar patrones relevantes sin perder simplicidad. En esta
sección, se analizan las contribuciones específicas de cada variable a
estas componentes, destacando su importancia en la interpretación de los
factores clave relacionados con las afecciones cardiovasculares.
Las pestañas de Biplot de Variables y Registros
Totales en las categorías Pac_sexo (sexo del
paciente), Rango_Etareo (grupo etareo del paciente) y
Hobby_ppantallay (hobby que implique uso de pantallas)
muestran, con base en las agrupaciones que estas variables categóricas
pueden establecer, la representación en dimensionalidad reducida en el
plano de factores generado por los componentes principales.
En este sentido:
- La agrupación con base en el rango etario (Primera infancia,
Niñez, Jóvenes, Adulto y Adulto mayor) permite observar cómo
las distintas etapas del ciclo de vida generan una distribución
diferenciada en el espacio de los componentes principales, especialmente
en las dimensiones Dim.1 y Dim.2. En
particular, los grupos correspondientes a adultos mayores
tienden a proyectarse hacia valores positivos de Dim.1,
mostrando una mayor asociación con la variable edad del paciente y con
variaciones en la agudeza visual (AV_OD y AV_OI). Por
su parte, los grupos de primera infancia y niñez se concentran
en regiones opuestas del espacio, lo que sugiere patrones
visuales y comportamentales distintos frente a las variables
analizadas.
-La agrupación con base en el uso de pantallas como
hobby (sí / no) muestra una separación menos marcada entre las
observaciones en el espacio de los componentes principales. No obstante,
se observa que los individuos que reportan uso de pantallas presentan
una mayor dispersión, especialmente en la dirección asociada a la
variable Horas_pd, lo que indica que este hábito
introduce variabilidad adicional en los datos. En contraste, quienes no
utilizan pantallas tienden a concentrarse más cerca del origen, lo que
sugiere una influencia moderada de esta variable categórica sobre la
estructura global del conjunto de datos.
-De manera complementaria, el análisis de los vectores del biplot
evidencia que las variables AV_OD y
AV_OI presentan una alta correlación positiva, ya que
se orientan en direcciones similares dentro del espacio factorial.
Asimismo, las variables Horas_pd y Horas_af muestran orientaciones
opuestas, lo que indica una relación inversa entre los distintos tipos
de actividades visuales. La variable edad del paciente se asocia
principalmente con la Dim.2, sugiriendo que la edad
explica una parte específica de la variabilidad que no está directamente
vinculada con la agudeza visual.
De esta manera, la representación biplot resalta la capacidad de
variables categóricas como el rango etario para establecer agrupaciones
significativas dentro del espacio de los componentes principales,
evidenciando su influencia en los patrones de agudeza visual y hábitos
asociados. En contraste, variables como el uso de pantallas como hobby
muestran un impacto más limitado, ya que no generan una separación
claramente definida entre los grupos, aunque sí contribuyen a una mayor
dispersión de las observaciones. En conjunto, el PCA permite identificar
relaciones estructurales relevantes entre la edad, la agudeza visual y
las horas de actividad visual, proporcionando una visión sintética y
robusta de la variabilidad presente en los datos.
Finalmente, para facilitar la interpretación de los puntajes en el
plano definido por las primeras dos componentes principales
(Dim.1 y Dim.2) y las relaciones entre variables, se
generó la pestaña Coordenadas Individuales [Subconjunto
ChestPain]. Esta visualización, basada en un subconjunto del \(5\) \(%\)
[47] de registros seleccionados mediante muestreo aleatorio simple,
permite explorar los puntajes por componentes. Este enfoque ofrece una
representación clara y comprensible, sin comprometer los detalles
esenciales. Es importante señalar que este procedimiento tiene fines de
visualización, ya que el conjunto de datos original, mucho más grande
[947 registros], dificulta la identificación visual de
patrones relevantes.
Biplot de Variables y Registros [filtro:Pac_sexo]
ccd_vision2020_ETL <- read_excel("C:\\Users\\JOSE\\Desktop\\gdd\\ccd_vision2020_ETL.xlsx")
ccd_vision2020_ETL_Reducido <- ccd_vision2020_ETL[
sample(1:nrow(ccd_vision2020_ETL), 100),
c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af","pac_sexo")
]
ccd_vision2020_ETL_Reducido$pac_sexo <- factor(ccd_vision2020_ETL_Reducido$pac_sexo,levels = c(0, 1),
labels = c("Femenino", "Masculino"))
res_pca <- PCA(
ccd_vision2020_ETL_Reducido[, c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af")],
ncp = 5,scale.unit = TRUE,graph = FALSE)
fviz_pca_biplot(res_pca,axes = c(1, 2),repel = TRUE,habillage = ccd_vision2020_ETL_Reducido$pac_sexo)
## Warning: Removed 100 rows containing missing values or values outside the scale range
## (`geom_point()`).
## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_point()`).

Biplot de Variables y Registros [filtro:Rango Etareo]
library(FactoMineR)
library(factoextra)
library(readxl)
ccd_vision2020_ETL <- read_excel("C:\\Users\\JOSE\\Desktop\\gdd\\ccd_vision2020_ETL.xlsx")
set.seed(780729)
muestra_re <- ccd_vision2020_ETL[
sample(1:nrow(ccd_vision2020_ETL), 150),
c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af","rango_etareo")
]
muestra_re$rango_etareo <- factor(muestra_re$rango_etareo)
res_pca_re <- PCA(
muestra_re[, c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af")],
ncp = 5,
scale.unit = TRUE,
graph = FALSE
)
fviz_pca_biplot(
res_pca_re,
axes = c(1, 2),
repel = TRUE,
habillage = muestra_re$rango_etareo
)

Biplot de Variables y Registros [filtro:Hobby_ppantalla]
set.seed(780729)
muestra_hb <- ccd_vision2020_ETL[
sample(1:nrow(ccd_vision2020_ETL), 150),
c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af","Hobby_ppantalla")
]
muestra_hb$Hobby_ppantalla <- factor(
muestra_hb$Hobby_ppantalla,
levels = c("no","si") # ajusta según codificación real
)
res_pca_hb <- PCA(
muestra_hb[, c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af")],
ncp = 5,
scale.unit = TRUE,
graph = FALSE
)
fviz_pca_biplot(
res_pca_hb,
axes = c(1, 2),
repel = TRUE,
habillage = muestra_hb$Hobby_ppantalla
)

Fase 5 [Regresiones]
5.1. Objetivos
Este estudio tiene como propósito establecer la relación
entre dos o más variables mediante la obtención de información
sobre una de ellas, basada en el conocimiento de los valores de las
otras. Las relaciones establecidas son de carácter no
determinístico, es decir, se plantearán relaciones
probabilísticas y se implementarán procedimientos para realizar
inferencias sobre los modelos utilizados. Además, se obtendrán medidas
cuantitativas que indiquen el grado de relación entre las variables. Los
modelos considerados en este trabajo corresponden a casos específicos
del modelo lineal generalizado: Regresión Lineal
Simple, Regresión Lineal Múltiple y
Regresión Logística. Cada modelo será descrito
teóricamente en su respectiva sección, y se aplicará a un conjunto de
datos específico descrito en la sección 2.
La estructura y referencias principales se basan en el Estudio de
Análisis Multivariado del profesor (EAMOTImo42023?).
Además, se utilizaron libros como Probabilidad y estadística para
ingeniería industrial de (Devore, Jay L., 2008), Análisis
estadístico de datos multivariados de (Díaz Morales & Morales Rivera,
2012), y Análisis multivariante aplicado con R de
(Aldás &
Uriel, 2017), que proporcionaron fundamentos clave para este
análisis.
Para fines de visualización, se creó un apartado específico para el
diccionario de variables. Asimismo, se aclara que se puede consultar el
diccionario de variables extendido en la sección
1.2:
Desplegar el diccionario de variables
5.2. Regresión Lineal Simple
Coeficientes del Modelo RLS
modelo_RL_Simple = lm(ccd_vision2020_ETL$AV_OD~ccd_vision2020_ETL$rango_etareo)
coef(modelo_RL_Simple)
## (Intercept)
## 0.523879056
## ccd_vision2020_ETL$rango_etareoADULTO MAYOR
## 0.008833255
## ccd_vision2020_ETL$rango_etareoJÓVENES
## 0.023976686
## ccd_vision2020_ETL$rango_etareoNIÑEZ
## 0.033517981
## ccd_vision2020_ETL$rango_etareoPRIMERA INFANCIA
## 0.055371215
modelo_RL_Simple1 = lm(ccd_vision2020_ETL$AV_OI~ccd_vision2020_ETL$rango_etareo)
coef(modelo_RL_Simple1)
## (Intercept)
## 0.57398313
## ccd_vision2020_ETL$rango_etareoADULTO MAYOR
## -0.03223597
## ccd_vision2020_ETL$rango_etareoJÓVENES
## 0.01530552
## ccd_vision2020_ETL$rango_etareoNIÑEZ
## -0.02340862
## ccd_vision2020_ETL$rango_etareoPRIMERA INFANCIA
## -0.03652918
Resumen Estadístico del Modelo RLS
summary(modelo_RL_Simple)
##
## Call:
## lm(formula = ccd_vision2020_ETL$AV_OD ~ ccd_vision2020_ETL$rango_etareo)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.45839 -0.21971 -0.00542 0.21120 0.47479
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) 0.523879 0.011409 45.919
## ccd_vision2020_ETL$rango_etareoADULTO MAYOR 0.008833 0.019984 0.442
## ccd_vision2020_ETL$rango_etareoJÓVENES 0.023977 0.020094 1.193
## ccd_vision2020_ETL$rango_etareoNIÑEZ 0.033518 0.031284 1.071
## ccd_vision2020_ETL$rango_etareoPRIMERA INFANCIA 0.055371 0.031457 1.760
## Pr(>|t|)
## (Intercept) <2e-16 ***
## ccd_vision2020_ETL$rango_etareoADULTO MAYOR 0.6586
## ccd_vision2020_ETL$rango_etareoJÓVENES 0.2330
## ccd_vision2020_ETL$rango_etareoNIÑEZ 0.2842
## ccd_vision2020_ETL$rango_etareoPRIMERA INFANCIA 0.0786 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2589 on 1161 degrees of freedom
## Multiple R-squared: 0.003766, Adjusted R-squared: 0.0003332
## F-statistic: 1.097 on 4 and 1161 DF, p-value: 0.3566
Tabla ANOVA para el Modelo RLS
anova(modelo_RL_Simple)
## Analysis of Variance Table
##
## Response: ccd_vision2020_ETL$AV_OD
## Df Sum Sq Mean Sq F value Pr(>F)
## ccd_vision2020_ETL$rango_etareo 4 0.294 0.073540 1.0971 0.3566
## Residuals 1161 77.825 0.067033
5.3. Regresión Lineal Múltiple
Este modelo, que a partir de ahora se denominará como RLS, está
compuesto por dos variables: una predictora y otra respuesta.
Específicamente, la variable \(Y\) se
considera influida por la variable predictora \(x\). La relación entre estas variables está
descrita por la ecuación: \[Y = \beta_0 +
\beta_1x + \varepsilon\] Donde: - \(Y\): Es la variable dependiente (la que se
desea predecir o explicar). - \(x\): Es
la variable independiente (predictora). - \((\beta_0)\): Es el intercepto (valor de
\(Y\) cuando \((x = 0)\). - \((\beta_1)\): Es la pendiente (indica cuánto
cambia \(Y\) por cada unidad que cambia
\((x)\). - \((\epsilon)\): Es el término de error, que
captura las desviaciones entre los valores observados y los valores
predichos por el modelo.
La relación entre la variable independiente y la variable dependiente
en el modelo de regresión lineal simple debe cumplir ciertas
suposiciones clave para que los resultados sean válidos. Estas son las
siguientes: 1. La relación entre la variable independiente \(x\) y la variable dependiente \(Y\) debe ser lineal. 2. El término de error
\(ε\) sigue una distribución normal y
tiene una media igual a cero. 3. Las observaciones deben ser
independientes entre sí, es decir, el valor de \(Y\) para un dato no influye en los valores
de \(Y\) para otros datos. 4. La
varianza del término de error \(ε\)
debe ser constante para todos los valores de la variable independiente
\(x\), una condición conocida como
homocedasticidad. La varianza de \(\varepsilon\) es constante para todos los
valores de \(x\).
Para estimar los parámetros desconocidos (\(\beta_0\), \(\beta_1\) y \(\sigma^2\)), se usa el método de
mínimos cuadrados, que busca minimizar la suma de los cuadrados
de las desviaciones verticales entre los puntos observados y la línea de
regresión:\[SCE = \sum_{i=1}^n \left(y_i -
(\beta_0 + \beta_1x_i)\right)^2\]. Resolviendo este problema, las
estimaciones de los parámetros son: \[\hat{\beta}_1 = \frac{\sum_{i=1}^n (x_i -
\bar{x})(y_i - \bar{y})}{\sum_{i=1}^n (x_i - \bar{x})^2}, \quad
\hat{\beta}_0 = \bar{y} - \hat{\beta}_1 \bar{x}.\] Aquí, \(\bar{x}\) y \(\bar{y}\) son las medias muestrales de
\(x\) e \(y\), respectivamente.
El coeficiente de determinación indica la proporción de la
variabilidad de \(Y\) que puede
explicarse mediante el modelo de regresión lineal simple:\[R^2 = 1 - \frac{SCE}{STC},\] donde \(SCE\) es la suma de cuadrados del error y
\(STC\) es la suma total de cuadrados.
Un valor de \(R^2\) cercano a 1 indica
que el modelo explica gran parte de la variabilidad observada en los
datos.
Se pueden formular pruebas para determinar si los coeficientes del
modelo son significativamente diferentes de cero. Las hipótesis nulas
comunes son: - Para \(\beta_0\): \(H_0: \beta_0 = \beta_{00}\). - Para \(\beta_1\): \(H_0:
\beta_1 = 0\) (prueba de utilidad del modelo).
El estadístico de prueba asociado es:\[ t
= \frac{\hat{\beta}_1 - 0}{SE(\hat{\beta}_1)},\] donde \(SE(\hat{\beta}_1)\) es el error estándar de
\(\hat{\beta}_1\) Este estadístico
sigue una distribución \(t\) de Student
con \(n-2\) grados de libertad.
Los intervalos de confianza para los parámetros estimados se calculan
como: \[\hat{\beta}_1 \pm t_{\alpha/2, n-2}
\cdot SE(\hat{\beta}_1).\] Estos intervalos brindan un rango
probable para los verdaderos valores de \(\beta_0\) y \(\beta_1\).
El modelo de regresión lineal simple es una herramienta poderosa para
analizar relaciones lineales. Sin embargo, debe usarse con cautela: no
extrapole más allá del rango de los datos y asegúrese de que las
suposiciones del modelo sean razonables para los datos. Al comprender la
variabilidad explicada y no explicada por el modelo, los analistas
pueden tomar decisiones fundamentadas y evaluar la utilidad del modelo
en contextos específicos.
En el modelo, los puntos observados se distribuyen
aleatoriamente alrededor de la línea de regresión
verdadera. Para ajustarse a estos puntos, la estimación \(y = beta_0 + beta_1 x\) debe ser una línea
que minimice las distancias verticales desviaciones entre los puntos
observados y la línea. La calidad del ajuste se evalúa mediante la suma
de los cuadrados de estas desviaciones, siendo la mejor línea aquella
que minimice esta suma. Este enfoque, conocido como el principio de los
mínimos cuadrados, fue desarrollado por Carl Friedrich Gauss y
Adrien-Marie Legendre.
Por último, se entiende que en un modelo de regresión lineal simple
un valor futuro de \(Y\) no es
parámetro sino una variable aleatoria, por lo que se debe hacer
referencia a un intervalo de valores factibles para un valor futuro de
\(Y\), al cual se le llama intervalo de
predicción. Según,(EAMOTImo42023?).
5.4. Regresión Logística Simple
###Gráfica del Modelo RLogS
umbral_OD <- 0.8 # ejemplo, reemplazar por el valor adecuado
umbral_OI <- 0.8 # ejemplo, reemplazar por el valor adecuado
ccd_vision2020_ETL$baja_AV_OD <- ifelse(ccd_vision2020_ETL$AV_OD < umbral_OD, 1, 0)
ccd_vision2020_ETL$baja_AV_OI <- ifelse(ccd_vision2020_ETL$AV_OI < umbral_OI, 1, 0)
ccd_vision2020_ETL$baja_AV_OD <- as.numeric(ccd_vision2020_ETL$baja_AV_OD)
ccd_vision2020_ETL$baja_AV_OI <- as.numeric(ccd_vision2020_ETL$baja_AV_OI)
ccd_vision2020_ETL$Horas_pantalla_dia <- as.numeric(ccd_vision2020_ETL$Horas_pd)
mod_log_OD <- glm(baja_AV_OD ~ Horas_pantalla_dia,
family = binomial,
data = ccd_vision2020_ETL)
mod_log_OI <- glm(baja_AV_OI ~ Horas_pantalla_dia,
family = binomial,
data = ccd_vision2020_ETL)
x_seq <- seq(
from = min(ccd_vision2020_ETL$Horas_pantalla_dia, na.rm = TRUE),
to = max(ccd_vision2020_ETL$Horas_pantalla_dia, na.rm = TRUE),
length.out = 200
)
par(mfrow = c(1, 2))
Gráfica del Modelo RLogS
plot(baja_AV_OD ~ Horas_pantalla_dia,
data = ccd_vision2020_ETL,
main = "Modelo RLogS: baja_AV_OD ~ Horas_pantalla_dia",
xlab = "Horas_pantalla_dia",
ylab = "baja_AV_OD (0 = No, 1 = Sí)",
col = "gold",
pch = 16)
lines(x_seq,
predict(mod_log_OD,
newdata = data.frame(Horas_pantalla_dia = x_seq),
type = "response"),
col = "orange",
lwd = 3)

Gráfica del Modelo RLogS
plot(baja_AV_OI ~ Horas_pantalla_dia,
data = ccd_vision2020_ETL,
main = "Modelo RLogS: baja_AV_OI ~ Horas_pantalla_dia",
xlab = "Horas_pantalla_dia",
ylab = "baja_AV_OI (0 = No, 1 = Sí)",
col = "gold",
pch = 16)
lines(x_seq,
predict(mod_log_OI,
newdata = data.frame(Horas_pantalla_dia = x_seq),
type = "response"),
col = "orange",
lwd = 3)

par(mfrow = c(1, 1))
5.5. Ajuste de Varianza
LS0tDQp0aXRsZTogIioqVEZDX0dERF8yMDI1X2dydXBvXzIqKiINCnN1YnRpdGxlOiAiRXN0dWRpbyBkZSBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvIGFwbGljYWRvIGEgdW4gY29uanVudG8gZGUgZGF0b3MgY2zDrW5pY29zIGNlbnRyYWRvcyBlbiBlbCBzZWN0b3Igb2Z0YWxtb2zDs2dpY28uIg0KYXV0aG9yOiAiUG9yOiBBbGlzc29uIEFuZHJlYSBSb2phcyBWYXJnYXMoYWxpc3Nvbi5yb2phc0Bjb3JyZW91bml2YWxsZS5lZHUuY28pLE1hbnVlbGEgR2FyY8OtYSBHYXJjw61hIChtYW51ZWxhLmdhcmNpYS5nYXJjaWFAY29ycmVvdW5pdmFsbGUuZWR1LmNvKSwgRnJlZGR5IEFsZWphbmRybyBBcmFuZ28gQ3J1eiAoYXJhbmdvLmZyZWRkeUBjb3JyZW91bml2YWxsZS5lZHUuY28sKSxIb3JsYW5kIEFkZWxtbyBQb3BvIE1hbWJ1c2NheSAoaG9ybGFuZC5wb3BvQGNvcnJlb3VuaXZhbGxlLmVkdS5jbyksIENhcmxvcyBIZXJtaWRlcyBTdWFyZXogU2FsZGFycmlhZ2EgKGNhcmxvcy5oZXJtaWRlcy5zdWFyZXpAY29ycmVvdW5pdmFsbGUuZWR1LmNvKSINCmRhdGU6ICJUcmFiYWpvIGVsYWJvcmFkbyBlbiBlbCBwZXJpb2RvIGFjYWTDqW1pY28gY29tcHJlbmRpZG8gZW50cmUgYWdvc3RvIHkgZGljaWVtYnJlIGRlbCBhw7FvIDIwMjUsIGNvbW8gYWN0aXZpZGFkIGZvcm1hdGl2YSB5IGV2YWx1YXRpdmEgZGVsIGN1cnNvIEdlc3Rpw7NuIGRlIERhdG9zIHBhcmEgSW5nZW5pZXLDrWEgSW5kdXN0cmlhbC4iDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KICAgIHRoZW1lOiBsdW1lbg0KYmlibGlvZ3JhcGh5OiBiaWJsaW9ncmFmaWFfTUUuYmliDQpjc2w6IGFwYS5jc2wNCmxpbmstY2l0YXRpb25zOiB5ZXMNCi0tLQ0KPCEtLSBDb25maWd1cmFjacOzbiBHbG9iYWwgZGUgUiAtLT4NCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkoY29ycnBsb3QpDQpsaWJyYXJ5KEdHYWxseSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoYW5kcmV3cykNCmxpYnJhcnkodGNsdGspDQpsaWJyYXJ5KGFwbHBhY2spDQpsaWJyYXJ5KGdyYXBoaWNzKQ0KbGlicmFyeShyZXNoYXBlMikNCmxpYnJhcnkoRmFjdG9NaW5lUikNCmxpYnJhcnkoZmFjdG9leHRyYSkNCmxpYnJhcnkocHN5Y2gpDQpsaWJyYXJ5KEZhY3RvQ2xhc3MpDQpsaWJyYXJ5KGNsdXN0ZXIpDQpsaWJyYXJ5KGRlbmRleHRlbmQpDQpsaWJyYXJ5KG1hZ3JpdHRyKQ0KbGlicmFyeShOYkNsdXN0KQ0KbGlicmFyeShzdGFyZ2F6ZXIpDQoNCg0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KG12bm9ybWFsVGVzdCkNCg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KDQpjb25qdW50b19kZV9kYXRvc192aXNpb24yMDIwX09yaWdpbmFsIDwtIHJlYWRfZXhjZWwoIkM6XFxVc2Vyc1xcSk9TRVxcRGVza3RvcFxcZ2RkXFxjY2RfdmlzaW9uMjAyMF9uRVRMLnhsc3giKQ0KDQoNCmNjZF92aXNpb24yMDIwX0VUTCA8LSByZWFkX2V4Y2VsKCJDOlxcVXNlcnNcXEpPU0VcXERlc2t0b3BcXGdkZFxcY2NkX3Zpc2lvbjIwMjBfRVRMLnhsc3giKQ0KDQoNCmBgYA0KDQojIyAqKkZhc2UgMSBbRGVzY3JpcGNpb25lcyBNdWx0aXZhcmlhbnRlc10qKg0KDQpFbiBsYSBwcmltZXJhIGV0YXBhIGRlbCBlc3R1ZGlvIHNlIHJlYWxpemFyw6FuIGPDoWxjdWxvcywgdmlzdWFsaXphY2lvbmVzIHkgdW4gYW7DoWxpc2lzIGRldGFsbGFkbyBkZWwgY29uanVudG8gZGUgZGF0b3MgY2zDrW5pY29zLCBlbCBjdWFsIHNlIGRlc2NyaWJpcsOhIGVuIGxhIFtzZWNjacOzbiAxLjJdKCNzZWMxLjIpLiBFc3RhIGZhc2Ugc2UgZW5mb2NhcsOhIGRlc2RlIGxhIGVzdGFkw61zdGljYSBkZXNjcmlwdGl2YSBtdWx0aXZhcmlhbnRlLCBjb24gZWwgZmluIGRlIG9mcmVjZXIgdW5hIHZpc2nDs24gZ2VuZXJhbCBkZWwgZGF0YXNldCB5LCBhbCBtaXNtbyB0aWVtcG8sIGV4YW1pbmFyIGRlIG1hbmVyYSBtw6FzIHByb2Z1bmRhIGxhcyByZWxhY2lvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMuDQpFc3RlIGVuZm9xdWUgcGVybWl0aXLDoSBpZGVudGlmaWNhciBwYXRyb25lcyB5IHRlbmRlbmNpYXMgaW1wb3J0YW50ZXMgZGVudHJvIGRlIGxvcyBkYXRvcy4gTGFzIHZpc3VhbGl6YWNpb25lcyBzZXLDoW4gZnVuZGFtZW50YWxlcyBwYXJhIG1vc3RyYXIgZ3LDoWZpY2FtZW50ZSBlc3RhcyByZWxhY2lvbmVzLCBwcm9wb3JjaW9uYW5kbyB1bmEgZm9ybWEgY2xhcmEgeSBjb21wcmVuc2libGUgZGUgZXhwbG9yYXJsYXMuIFRvZGFzIGVzdGFzIHRhcmVhcyBzZSBkZXNhcnJvbGxhcsOhbiB1dGlsaXphbmRvIFIgeSBSU3R1ZGlvLCBoZXJyYW1pZW50YXMgcXVlIGZhY2lsaXRhcsOhbiBsYSBlamVjdWNpw7NuIHByZWNpc2EgZGUgbG9zIGFuw6FsaXNpcyB5IGxhIGVsYWJvcmFjacOzbiBkZSBncsOhZmljb3MgaW50ZXJhY3Rpdm9zIHBhcmEgdW5hIGludGVycHJldGFjacOzbiBtw6FzIGNvbXBsZXRhIGRlIGxvcyByZXN1bHRhZG9zLg0KDQojIyMgMS4xLiBPYmpldGl2b3MNCg0KRWwgb2JqZXRpdm8gZGUgZXN0ZSBwcm95ZWN0byBlcyBhcGxpY2FyIHTDqWNuaWNhcyBkZSBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvIGFsIGNvbmp1bnRvIGRlIGRhdG9zIGFwcm9iYWRvLCBlbCBjdWFsIGNvbnRpZW5lIHJlZ2lzdHJvcyBjbMOtbmljb3MgZGUgbGEgZW1wcmVzYSBvZnRhbG1vbMOzZ2ljYSwgVmlzacOzbiAyMDIwLiBMYSBmaW5hbGlkYWQgZXMgb3JnYW5pemFyIHkgcHJvY2VzYXIgbGEgaW5mb3JtYWNpw7NuIGRlIG1hbmVyYSBlZmljaWVudGUsIGZvcnRhbGVjaWVuZG8gbGFzIGNvbXBldGVuY2lhcyBlbiBnZXN0acOzbiB5IGFuw6FsaXNpcyBkZSBkYXRvcy4gRXN0ZSB0cmFiYWpvIHNlIGRlc2Fycm9sbGEgZW4gZWwgbWFyY28gZGVsIGN1cnNvICpHZXN0acOzbiBkZSBEYXRvcyosIG9yaWVudGFkbyBhbCBwcm9ncmFtYSBkZSAgSW5nZW5pZXJpYSBJbmR1c3RyaWFsLCBlbiBlbCBzZWd1bmRvIHBlcmlvZG8gZGUgMjAyNSBlbiBsYSBVbml2ZXJzaWRhZCBkZWwgVmFsbGUsIFNlY2Npb25hbCBaYXJ6YWwuDQo8YSBuYW1lPSJzZWMxLjIiPjwvYT4NCg0KIyMjIDEuMi4gRGVzY3JpcGNpw7NuIGRlIGxvcyBkYXRvcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpFbCBjb25qdW50byBkZSBkYXRvcyB1dGlsaXphZG8gZW4gZXN0ZSBlc3R1ZGlvIGZ1ZSBwcm9wb3JjaW9uYWRvIHBvciBsYSBlbXByZXNhIGRlbCBzZWN0b3Igb2Z0YWxtb2zDs2dpY28gVmlzaW9uIDIwMjAsIGEgcGFydGlyIGRlIGxvcyByZWdpc3Ryb3MgZGUgcGFjaWVudGVzIGF0ZW5kaWRvcyBkdXJhbnRlIGVsIGHDsW8gMjAyNC4gTGEgaW5mb3JtYWNpw7NuIG9yaWdpbmFsIGZ1ZSBlbnRyZWdhZGEgZW4gdW4gYXJjaGl2byBwbGFubywgY29uIDEyNDkgcmVnaXN0cm9zIHkgcG9zdGVyaW9ybWVudGUgc29tZXRpZGEgYSB1biBwcm9jZXNvIGRlIGV4dHJhY2Npw7NuLCB0cmFuc2Zvcm1hY2nDs24geSBjYXJnYSAoRVRMKSwgZW4gZWwgY3VhbCBzZSBkZXB1cmFyb24gaW5jb25zaXN0ZW5jaWFzLCBzZSBub3JtYWxpemFyb24gZm9ybWF0b3MgeSBzZSBnZW5lcmFyb24gdmFyaWFibGVzIGRlcml2YWRhcyBwYXJhIGZhY2lsaXRhciBlbCBhbsOhbGlzaXMgZXN0YWTDrXN0aWNvLiBFbCBvYmpldGl2byBkZSBlc3RlIGNvbmp1bnRvIGVzIGNhcmFjdGVyaXphciBlbCBwZXJmaWwgdmlzdWFsIHkgZGUgaMOhYml0b3MgZGUgdXNvIGRlIHBhbnRhbGxhcyBkZSBsb3MgcGFjaWVudGVzLCBhc8OtIGNvbW8gc3UgcG9zaWJsZSByZWxhY2nDs24gY29uIGZhY3RvcmVzIGRlbW9ncsOhZmljb3MgeSBhbnRlY2VkZW50ZXMgZmFtaWxpYXJlcy4NCg0KVHJhcyBlbCBwcm9jZXNvIEVUTCBzZSBjb25zb2xpZMOzIHVuYSBiYXNlIGNvbiAxMTY2IHJlZ2lzdHJvcyAodW5vIHBvciBwYWNpZW50ZSkgeSAxMyB2YXJpYWJsZXMsIHF1ZSBjb21iaW5hbiBhc3BlY3RvcyBkZSBpZGVudGlmaWNhY2nDs24sIHNvY2lvZGVtb2dyw6FmaWNvcywgY2zDrW5pY2/igJF2aXN1YWxlcyB5IGRlIGVzdGlsbyBkZSB2aWRhLiBMYXMgdmFyaWFibGVzIHNlIGRlc2NyaWJlbiBhIGNvbnRpbnVhY2nDs24gZW4gZWwgb3JkZW4gZW4gcXVlIGFwYXJlY2VuIGVuIGxhIGJhc2UgZGUgZGF0b3MsIGluZGljYW5kbyBzdSB0aXBvIHkgZXNjYWxhIGRlIG1lZGljacOzbiBtZWRpYW50ZSBsYSBub3RhY2nDs24gKHRpcG9fZGVfdmFyaWFibGU6OmVzY2FsYV9kZV9tZWRpY2nDs25bb3JkZW5hbWllbnRvXSkuDQoNCioqUGFjX2lkKiogKGN1YW50aXRhdGl2YTo6bm9taW5hbCk6IElkZW50aWZpY2Fkb3IgbnVtw6lyaWNvIHNlY3VlbmNpYWwgcXVlIGFzaWduYSB1biBjw7NkaWdvIMO6bmljbyBhIGNhZGEgcGFjaWVudGUuIFBlcm1pdGUgcmVmZXJlbmNpYXIgbG9zIHJlZ2lzdHJvcyBzaW4gcmV2ZWxhciBkYXRvcyBwZXJzb25hbGVzIHkgbm8gdGllbmUgaW50ZXJwcmV0YWNpw7NuIG3DqXRyaWNhIHBvciBzw60gbWlzbW8uDQoNCioqRWRhZF9wYWNpZW50ZSoqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IEVkYWQgZGVsIHBhY2llbnRlIGV4cHJlc2FkYSBlbiBhw7FvcyBjdW1wbGlkb3MgYWwgbW9tZW50byBkZWwgcmVnaXN0cm8uIEVzIHVuYSB2YXJpYWJsZSBkZSByYXrDs24sIGNvbiBjZXJvIGFic29sdXRvIHkgcG9zaWJpbGlkYWQgZGUgcmVhbGl6YXIgY29tcGFyYWNpb25lcyBkZSBwcm9wb3JjaW9uZXMgZGUgZWRhZC4NCg0KKipPY3VwYWNpb24qKiAoY3VhbGl0YXRpdmE6Om5vbWluYWwpOiBQcm9mZXNpw7NuIHUgb2ZpY2lvIHByaW5jaXBhbCBkZWwgcGFjaWVudGUgKHBvciBlamVtcGxvLCBlc3R1ZGlhbnRlLCBhZG1pbmlzdHJhdGl2bywgb3BlcmFyaW8sIGluZGVwZW5kaWVudGUsIGVudHJlIG90cm9zKS4gU2UgdXRpbGl6YSBwYXJhIGNhcmFjdGVyaXphciBlbCB0aXBvIGRlIGFjdGl2aWRhZCBkaWFyaWEsIGVzcGVjaWFsbWVudGUgZW4gdMOpcm1pbm9zIGRlIGV4cG9zaWNpw7NuIHBvdGVuY2lhbCBhIHBhbnRhbGxhcy4NCg0KKipDYW5hbF9kaWZ1c2lvbioqIChjdWFsaXRhdGl2YTo6bm9taW5hbCk6IE1lZGlvIHBvciBlbCBjdWFsIGVsIHBhY2llbnRlIGNvbm9jacOzIGxhIMOzcHRpY2EgKHJlZmVyaWRvLCByZWRlcyBzb2NpYWxlcywgdm9sYW50ZSwgcGFzbyBwb3IgZWwgbG9jYWwsIGNvbnZlbmlvLCBldGMuKS4gRXN0YSB2YXJpYWJsZSBwZXJtaXRlIGlkZW50aWZpY2FyIGxvcyBjYW5hbGVzIGRlIGNhcHRhY2nDs24gbcOhcyBmcmVjdWVudGVzIGRlbnRybyBkZSBsYSBwb2JsYWNpw7NuIGF0ZW5kaWRhLg0KDQoqKkZlY2hhX3JlZ2lzdHJvKiogKGN1YWxpdGF0aXZhOjpvcmRpbmFsW3RpZW1wb10pOiBGZWNoYSBlbiBsYSBxdWUgZWwgcGFjaWVudGUgZnVlIHJlZ2lzdHJhZG8gZW4gZWwgc2lzdGVtYSwgZXhwcmVzYWRhIGNvbW8gZMOtYS9tZXMvYcOxby4gQXVucXVlIHNlIGFsbWFjZW5hIGNvbW8gdGV4dG8gbyBmZWNoYSBjYWxlbmRhcmlvLCBzdSBlc2NhbGEgZXMgb3JkaW5hbCBlbiBlbCB0aWVtcG8geSBzZSB1c2EgcGFyYSB1YmljYXIgbGEgYXRlbmNpw7NuIGRlbnRybyBkZWwgcGVyaW9kbyBkZSBlc3R1ZGlvLg0KDQoqKlBhY19zZXhvKiogKGN1YWxpdGF0aXZhOjpub21pbmFsKTogU2V4byBkZWwgcGFjaWVudGUsIHJlZ2lzdHJhZG8gdMOtcGljYW1lbnRlIGNvbW8g4oCcRmVtZW5pbm/igJ0gbyDigJxNYXNjdWxpbm/igJ0uIEVzdGEgdmFyaWFibGUgc2UgZW1wbGVhIHBhcmEgY29tcGFyYXIgcGF0cm9uZXMgZGUgYWd1ZGV6YSB2aXN1YWwgeSBow6FiaXRvcyBkZSBwYW50YWxsYSBlbnRyZSBncnVwb3MuDQoNCioqUmFuZ29fZXRhcmVvKiogKGN1YWxpdGF0aXZhOjpvcmRpbmFsKTogQ2xhc2lmaWNhY2nDs24gZGVsIHBhY2llbnRlIGVuIGdydXBvcyBkZSBlZGFkIChwb3IgZWplbXBsbywgQURPTEVTQ0VOVEUsIEpPVkVOX0FEVUxUTywgQURVTFRPLCBBRFVMVE9fTUFZT1IpLCBjb25zdHJ1aWRhIGEgcGFydGlyIGRlIGxhIHZhcmlhYmxlIGVkYWRfcGFjaWVudGUuIFByZXNlbnRhIHVuIG9yZGVuIG5hdHVyYWwgZGUgbG9zIGdydXBvcywgbG8gcXVlIHBlcm1pdGUgYW7DoWxpc2lzIHBvciBjYXRlZ29yw61hcyBldGFyaWFzLg0KDQoqKkFndWRlemFfdmlzdWFsX09EKiogKGN1YW50aXRhdGl2YTo6cmF6w7NuKTogTWVkaWRhIGRlIGxhIGFndWRlemEgdmlzdWFsIGRlbCBvam8gZGVyZWNobywgZXhwcmVzYWRhIGVuIGxhIGVzY2FsYSBlc3RhYmxlY2lkYSBwb3IgbGEgw7NwdGljYSAocG9yIGVqZW1wbG8sIGNvbnZlcnNpw7NuIGEgdW5hIG3DqXRyaWNhIGNvbnRpbnVhIGNvbXBhdGlibGUgY29uIGxhIHByw6FjdGljYSBjbMOtbmljYSkuIFZhbG9yZXMgbcOhcyBjZXJjYW5vcyBhIGxhIHJlZmVyZW5jaWEgZGUgdmlzacOzbiBub3JtYWwgaW5kaWNhbiBtZWpvciBhZ3VkZXphLCBtaWVudHJhcyBxdWUgdmFsb3JlcyBxdWUgc2UgYWxlamFuIGRlIGRpY2hvIGVzdMOhbmRhciByZXByZXNlbnRhbiBtYXlvciBjb21wcm9taXNvIHZpc3VhbC4NCg0KKipBZ3VkZXphX3Zpc3VhbF9PSSoqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IEFuw6Fsb2dhIGEgbGEgYW50ZXJpb3IsIHBlcm8gcGFyYSBlbCBvam8gaXpxdWllcmRvLiBKdW50byBjb24gbGEgYWd1ZGV6YSBkZWwgb2pvIGRlcmVjaG8sIHBlcm1pdGUgZXZhbHVhciBsYSBzaW1ldHLDrWEgbyBkaWZlcmVuY2lhcyBlbnRyZSBhbWJvcyBvam9zIHkgY29uc3RpdHV5ZSB1bmEgZGUgbGFzIHZhcmlhYmxlcyBjbMOtbmljYXMgY2VudHJhbGVzIGRlbCBlc3R1ZGlvLg0KDQoqKkhvcmFzX3BhbnRhbGxhX2RpYSoqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IE7Dum1lcm8gZGUgaG9yYXMgcHJvbWVkaW8gcXVlIGVsIHBhY2llbnRlIHBhc2EgZGlhcmlhbWVudGUgZnJlbnRlIGEgZGlzcG9zaXRpdm9zIGNvbiBwYW50YWxsYSAoY29tcHV0YWRvciwgdGVsw6lmb25vIGludGVsaWdlbnRlLCB0YWJsZXRhLCB0ZWxldmlzacOzbiwgY29uc29sYSwgZXRjLikuIEVzIHVuYSBtZWRpZGEgY29udGludWEgZGUgZXhwb3NpY2nDs24geSBzZSBjb25zaWRlcmEgdW4gcG90ZW5jaWFsIGZhY3RvciBkZSByaWVzZ28gYXNvY2lhZG8gYSBmYXRpZ2EgdmlzdWFsIHkgb3RyYXMgbW9sZXN0aWFzIG9jdWxhcmVzLg0KDQoqKkhvcmFzX2FjdGl2aWRhZGYqKiAoY3VhbnRpdGF0aXZhOjpyYXrDs24pOiBIb3JhcyBwcm9tZWRpbyBkZSBhY3RpdmlkYWQgZsOtc2ljYSBxdWUgZWwgcGFjaWVudGUgcmVhbGl6YSBhbCBkw61hIChvIGVuIHByb21lZGlvIGRpYXJpbyBhIHBhcnRpciBkZSBsYSBzZW1hbmEpLCBpbmNsdXllbmRvIGVqZXJjaWNpbyBlc3RydWN0dXJhZG8geSBhY3RpdmlkYWRlcyByZWNyZWF0aXZhcy4gRXN0YSB2YXJpYWJsZSBwZXJtaXRlIGV4cGxvcmFyIHNpIHVuIGVzdGlsbyBkZSB2aWRhIG3DoXMgYWN0aXZvIHNlIHJlbGFjaW9uYSBjb24gbWVqb3JlcyBpbmRpY2Fkb3JlcyB2aXN1YWxlcyBvIGNvbiBtZW5vciBleHBvc2ljacOzbiBhIHBhbnRhbGxhcy4NCg0KKipIb2JieV9wcmluY2lwYWxfcGFudGFsbGEqKiAoY3VhbGl0YXRpdmE6Om5vbWluYWwpOiBJbmRpY2Egc2kgZWwgcGFzYXRpZW1wbyBwcmluY2lwYWwgZGVsIHBhY2llbnRlIGltcGxpY2EgdXNvIGludGVuc2l2byBkZSBwYW50YWxsYXMgKHBvciBlamVtcGxvLCB2aWRlb2p1ZWdvcywgcmVkZXMgc29jaWFsZXMsIHNlcmllcyBlbiBzdHJlYW1pbmcpIG8gbm8uIFNlIGNvZGlmaWNhIHTDrXBpY2FtZW50ZSBjb21vIOKAnHPDreKAnSBvIOKAnG5v4oCdIHkgc2UgdXNhIHBhcmEgZGlmZXJlbmNpYXIgaG9iYmllcyBkaWdpdGFsZXMgZGUgYWN0aXZpZGFkZXMgYW5hbMOzZ2ljYXMgbyBhbCBhaXJlIGxpYnJlLg0KDQoqKlByZWRpc3Bvc2ljaW9uX2dlbmV0aWNhKiogKGN1YWxpdGF0aXZhOjpub21pbmFsKTogU2XDsWFsYSBzaSBlbCBwYWNpZW50ZSByZXBvcnRhIGFudGVjZWRlbnRlcyBmYW1pbGlhcmVzIGRlIHByb2JsZW1hcyBvZnRhbG1vbMOzZ2ljb3MgcmVsZXZhbnRlcyAobWlvcMOtYSBhbHRhLCBnbGF1Y29tYSwgZGVnZW5lcmFjacOzbiBtYWN1bGFyLCBlbnRyZSBvdHJvcykuIFNlIHJlZ2lzdHJhIGNvbW8g4oCcc8Ot4oCdIG8g4oCcbm/igJ0geSBmdW5jaW9uYSBjb21vIGFwcm94aW1hY2nDs24gYSB1biBmYWN0b3IgZGUgcmllc2dvIGdlbsOpdGljby4NCg0KRHVyYW50ZSBlbCBwcm9jZXNvIGRlIGRlcHVyYWNpw7NuIHNlIHZlcmlmaWPDsyBsYSBjb2hlcmVuY2lhIGRlIHJhbmdvcyAocG9yIGVqZW1wbG8sIGVkYWRlcyBubyBuZWdhdGl2YXMsIGhvcmFzIGRlIHBhbnRhbGxhIHkgYWN0aXZpZGFkIGbDrXNpY2EgZGVudHJvIGRlIGludGVydmFsb3MgcGxhdXNpYmxlcywgdmFsb3JlcyBkZSBhZ3VkZXphIHZpc3VhbCBkZW50cm8gZGUgbG9zIGzDrW1pdGVzIGFjZXB0YWRvcyBwb3IgbGEgZXNjYWxhIHV0aWxpemFkYSkuIExvcyB2YWxvcmVzIGZhbHRhbnRlcyBvIGNsYXJhbWVudGUgYXTDrXBpY29zIGZ1ZXJvbiByZXZpc2Fkb3MgY2FzbyBhIGNhc287IGVuIGxvcyBjYXNvcyBlbiBxdWUgbm8gZnVlIHBvc2libGUgcmVjdXBlcmFyIGluZm9ybWFjacOzbiBjb25maWFibGUsIHNlIHJlY3VycmnDsyBhIGVzdHJhdGVnaWFzIGRlIGltcHV0YWNpw7NuIG8gZXhjbHVzacOzbiBjb250cm9sYWRhLCBkb2N1bWVudGFkYXMgZW4gZWwgZmx1am8gRVRMLiBBIHBhcnRpciBkZSBlc3RlIGNvbmp1bnRvIGRlcHVyYWRvLCBzZSBkZXNhcnJvbGxhbiBsYXMgZmFzZXMgcG9zdGVyaW9yZXMgZGVsIGFuw6FsaXNpcyBtdWx0aXZhcmlhZG8sIGNlbnRyYWRhcyBlbiBsYSByZWxhY2nDs24gZW50cmUgYWd1ZGV6YSB2aXN1YWwsIGjDoWJpdG9zIGRlIHBhbnRhbGxhLCBhY3RpdmlkYWQgZsOtc2ljYSB5IGZhY3RvcmVzIGRlbW9ncsOhZmljb3MgeSBnZW7DqXRpY29zLg0KDQojIyMjIEVzdHJ1Y3R1cmEgZGVsIENvbmp1bnRvIGRlIERhdG9zIE9yaWdpbmFsDQpgYGB7ciBFc3RydWN0dXJhX2RlbF9Db25qdW50b19kZV9EYXRvc19PcmlnaW5hbCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpzdHIoY29uanVudG9fZGVfZGF0b3NfdmlzaW9uMjAyMF9PcmlnaW5hbCkNCmBgYA0KDQojIyMjIEVzdHJ1Y3R1cmEgZGVsIENvbmp1bnRvIGRlIERhdG9zIEVUTA0KYGBge3IgRXN0cnVjdHVyYV9kZWxfQ29uanVudG9fZGVfRGF0b3NfRVRMLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnN0cihjY2RfdmlzaW9uMjAyMF9FVEwpDQpgYGANCg0KDQojIyMgMS4zLiBFc3RpbWFjaW9uZXMgbXVsdGl2YXJpYWRhcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpFbCB2ZWN0b3IgZGUgbWVkaWFzIHkgbGEgbWF0cml6IGRlIHZhcmlhbnphc+KAkWNvdmFyaWFuemFzIHBlcm1pdGVuIGRlc2NyaWJpciBkZSBmb3JtYSBjb25qdW50YSBlbCBuaXZlbCB0w61waWNvLCBsYSBkaXNwZXJzacOzbiB5IGxhcyByZWxhY2lvbmVzIGxpbmVhbGVzIGVudHJlIGxhcyB2YXJpYWJsZXMgbcOpdHJpY2FzIHJlZ2lzdHJhZGFzIHBhcmEgbG9zIHBhY2llbnRlcyBkZSBsYSDDs3B0aWNhLiBFbiBlc3RlIGVzdHVkaW8gc2UgY29uc2lkZXJhbiBjb21vIHZhcmlhYmxlcyBhbGVhdG9yaWFzIGN1YW50aXRhdGl2YXM6IGVkYWRfcGFjaWVudGUsIEFndWRlemFfdmlzdWFsX09ELCBBZ3VkZXphX3Zpc3VhbF9PSSwgSG9yYXNfcGFudGFsbGFfZGlhIHkgSG9yYXNfYWYuIEVsIHZlY3RvciBkZSBtZWRpYXMgcmVzdW1lLCBwYXJhIGNhZGEgdW5hIGRlIGVzdGFzIHZhcmlhYmxlcywgZWwgdmFsb3IgcHJvbWVkaW8gb2JzZXJ2YWRvIGVuIGxhIG11ZXN0cmEsIGRlIG1vZG8gcXVlIHNpcnZlIGNvbW8gcmVmZXJlbmNpYSBkZWwg4oCccGVyZmlsIG1lZGlv4oCdIGRlIGxvcyBwYWNpZW50ZXMgZW4gdMOpcm1pbm9zIGRlIGVkYWQsIGNvbmRpY2nDs24gdmlzdWFsIHkgaMOhYml0b3MgZGUgdXNvIGRlIHBhbnRhbGxhcyB5IGRlIGFjdGl2aWRhZCBmw61zaWNhLiBMYSBtYXRyaXogZGUgdmFyaWFuemFz4oCRY292YXJpYW56YXMsIHBvciBzdSBwYXJ0ZSwgY3VhbnRpZmljYSBlbiBzdSBkaWFnb25hbCBwcmluY2lwYWwgbGEgdmFyaWFiaWxpZGFkIGluZGl2aWR1YWwgZGUgY2FkYSB2YXJpYWJsZSBhbHJlZGVkb3IgZGUgc3UgbWVkaWEsIG1pZW50cmFzIHF1ZSBlbiBsYXMgcG9zaWNpb25lcyBmdWVyYSBkZSBsYSBkaWFnb25hbCByZWNvZ2UgbGFzIGNvdmFyaWFuemFzIGVudHJlIHBhcmVzIGRlIHZhcmlhYmxlcywgbGFzIGN1YWxlcyBkZXNjcmliZW4gbGEgaW50ZW5zaWRhZCB5IGVsIHNlbnRpZG8gZGUgc3VzIHJlbGFjaW9uZXMgbGluZWFsZXMuDQoNClRyYWJhamFyIHNpbXVsdMOhbmVhbWVudGUgY29uIGVsIHZlY3RvciBkZSBtZWRpYXMgeSBsYSBtYXRyaXogZGUgdmFyaWFuemFz4oCRY292YXJpYW56YXMgcmVzdWx0YSBlc2VuY2lhbCBlbiBlbCBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvIHBvcnF1ZSBwZXJtaXRlIGNhcHR1cmFyLCBlbiB1biBzb2xvIG9iamV0byBtYXRlbcOhdGljbywgdGFudG8gbGEgdGVuZGVuY2lhIGNlbnRyYWwgY29tbyBsYXMgaW50ZXJkZXBlbmRlbmNpYXMgZW50cmUgbGFzIHZhcmlhYmxlcyBkZSBpbnRlcsOpcy4gQSBwYXJ0aXIgZGUgZXN0YXMgZXN0aW1hY2lvbmVzIGVzIHBvc2libGUgZGVyaXZhciBsYSBtYXRyaXogZGUgY29ycmVsYWNpb25lcywgcXVlIG5vcm1hbGl6YSBsYXMgY292YXJpYW56YXMgeSBmYWNpbGl0YSBjb21wYXJhciBsYSBmdWVyemEgZGUgYXNvY2lhY2nDs24gZW50cmUgdmFyaWFibGVzIG1lZGlkYXMgZW4gZXNjYWxhcyBkaWZlcmVudGVzLCBjb21vIGxhcyBob3JhcyBmcmVudGUgYSBwYW50YWxsYXMgeSBsYXMgbWVkaWRhcyBkZSBhZ3VkZXphIHZpc3VhbC4gRXN0b3MgZWxlbWVudG9zIGNvbnN0aXR1eWVuIGxhIGJhc2UgcGFyYSBsb3MgcHJvY2VkaW1pZW50b3MgcG9zdGVyaW9yZXMgZGUgYW7DoWxpc2lzIGRlIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLCBjb25nbG9tZXJhZG9zIHkgbW9kZWxvcyBkZSByZWdyZXNpw7NuLg0KDQojIyMjIFZlY3RvciBkZSBQcm9tZWRpb3MgeSBCb3hwbG90cw0KYGBge3IgVmVjdG9yX2RlX1Byb21lZGlvc195X0JveHBsb3RzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmFwcGx5KGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSwgMiwgbWVhbikNCmNjZF92aXNpb24yMDIwX0VUTF9SZWR1Y2lkbyA9IGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXQ0Kbm9tYnJlc19ib3hwbG90cyA8LSBjKCJlZGFkX3BhY2llbnRlIiwgIkFWX09EIiwgIkFWX09JIiwgIkhvcmFzX3BkIiwgIkhvcmFzX2FmIikNCnBhcihtZnJvdyA9IGMoMSwgbmNvbChjY2RfdmlzaW9uMjAyMF9FVExfUmVkdWNpZG8pKSkNCmludmlzaWJsZShsYXBwbHkoMTpuY29sKGNjZF92aXNpb24yMDIwX0VUTF9SZWR1Y2lkbyksIGZ1bmN0aW9uKGkpIHsNCiAgYm94cGxvdChjY2RfdmlzaW9uMjAyMF9FVExfUmVkdWNpZG9bLCBpXSwNCiAgICAgICAgICBtYWluID0gbm9tYnJlc19ib3hwbG90c1tpXSl9KSkNCmBgYA0KDQojIyMjIE1hdHJpeiBkZSBWYXJpYW56YXMtQ292YXJpYW56YXMNCmBgYHtyIE1hdHJpel9kZV9WYXJpYW56YXMtQ292YXJpYW56YXMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0Kcm91bmQoY292KGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSksMikNCmBgYA0KDQojIyMjIE1hdHJpeiBkZSBDb3JyZWxhY2lvbmVzDQpgYGB7ciBtYXRyaXpfZGVfQ29ycmVsYWNpb25lcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpyb3VuZChjb3IoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldKSwzKQ0KYGBgDQoNCkVsICoqdmVjdG9yIGRlIG1lZGlhcyoqIHkgbGEgKiptYXRyaXogZGUgdmFyaWFuemFzLWNvdmFyaWFuemFzKiogY29uZm9ybWFuIHVuIGNvbmp1bnRvIGRlIGhlcnJhbWllbnRhcyBmdW5kYW1lbnRhbGVzIHBhcmEgZGVzY3JpYmlyIGVsIGNvbXBvcnRhbWllbnRvIHBvc2ljaW9uYWwsIGRpc3BlcnNpdm8geSBjb3JyZWxhY2lvbmFsIGRlIGxhcyB2YXJpYWJsZXMgYWxlYXRvcmlhcyBlbiB1biBjb25qdW50byBkZSBkYXRvcy4gRXN0YXMgbWVkaWRhcyBzb24gZXNlbmNpYWxlcyBlbiBlbCBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvLCBwb3JxdWUgcGVybWl0ZW4gY2FwdHVyYXIgdGFudG8gbGEgdGVuZGVuY2lhIGNlbnRyYWwgY29tbyBsYXMgaW50ZXJkZXBlbmRlbmNpYXMgZW50cmUgbGFzIHZhcmlhYmxlcy4NCg0KIyMjIDEuNC4gR3LDoWZpY2FzIG11bHRpdmFyaWFkYXMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCkVuIGVzdGEgc2VjY2nDs24gc2UgcHJlc2VudGEgZWwgY8OhbGN1bG8gZSBpbnRlcnByZXRhY2nDs24gZGUgdHJlcyBvYmpldG9zIGZ1bmRhbWVudGFsZXM6ICoqVmVjdG9yIGRlIE1lZGlhcyoqICRcYmFyIHgkICwgKipNYXRyaXogZGUgVmFyaWFuemFzLUNvdmFyaWFuemFzKiogJFMkIHkgKipNYXRyaXogZGUgQ29ycmVsYWNpb25lcyoqICRSJC4sIGNvbnN0cnVpZG9zIGEgcGFydGlyIGRlIGxhcyB2YXJpYWJsZXMgZWRhZF9wYWNpZW50ZSwgQWd1ZGV6YV92aXN1YWxfT0QsIEFndWRlemFfdmlzdWFsX09JLCBIb3Jhc19wYW50YWxsYV9kaWEgeSBIb3Jhc19hZi4gTGEgcGVzdGHDsWEgY29ycmVzcG9uZGllbnRlIGFsIHZlY3RvciBkZSBtZWRpYXMgeSBhIGxvcyBib3hwbG90cyB1bml2YXJpYW50ZXMgcGVybWl0ZSBkZXNjcmliaXIgZWwgY29tcG9ydGFtaWVudG8gcG9zaWNpb25hbCB5IGRpc3BlcnNpdm8gZGUgY2FkYSB2YXJpYWJsZS4gRW4gdMOpcm1pbm9zIGdlbmVyYWxlcywgc2Ugb2JzZXJ2YSBzaSBsYSBkaXN0cmlidWNpw7NuIGRlIGxhIGVkYWQgZGUgbG9zIHBhY2llbnRlcyBzZSBhcHJveGltYSBhIHVuYSBmb3JtYSBhcHJveGltYWRhbWVudGUgc2ltw6l0cmljYSBvIHNpIHByZXNlbnRhIHNlc2dvcyBoYWNpYSBlZGFkZXMgbcOhcyBqw7N2ZW5lcyBvIG3DoXMgYXZhbnphZGFzLCBhc8OtIGNvbW8gZWwgcmFuZ28gdMOtcGljbyBkZSBob3JhcyBkaWFyaWFzIGZyZW50ZSBhIHBhbnRhbGxhcyB5IGRlIGFjdGl2aWRhZCBmw61zaWNhLiBEZSBpZ3VhbCBtYW5lcmEsIGxvcyBkaWFncmFtYXMgZGUgY2FqYSBkZSBsYXMgYWd1ZGV6YXMgdmlzdWFsZXMgZGVsIG9qbyBkZXJlY2hvIGUgaXpxdWllcmRvIHBlcm1pdGVuIGRldGVjdGFyIGxhIHByZXNlbmNpYSBkZSB2YWxvcmVzIGV4dHJlbW9zIHkgY29tcGFyYXIsIGRlIGZvcm1hIHZpc3VhbCwgcG9zaWJsZXMgZGlmZXJlbmNpYXMgZW50cmUgYW1ib3Mgb2pvcy4NCg0KQSBwYXJ0aXIgZGUgbGEgbWF0cml6IGRlIHZhcmlhbnphc+KAkWNvdmFyaWFuemFzIHkgZGUgbGEgbWF0cml6IGRlIGNvcnJlbGFjaW9uZXMgc2UgZXhhbWluYW4gbGFzIHJlbGFjaW9uZXMgbGluZWFsZXMgZW50cmUgbGFzIHZhcmlhYmxlcyBtw6l0cmljYXMuIExhIGluc3BlY2Npw7NuIGRlIGxvcyBjb2VmaWNpZW50ZXMgZGUgY29ycmVsYWNpw7NuIHBlcm1pdGUgaWRlbnRpZmljYXIsIHBvciBlamVtcGxvLCBzaSBleGlzdGUgdW5hIGFzb2NpYWNpw7NuIGFwcmVjaWFibGUgZW50cmUgZWwgdGllbXBvIGRlIGV4cG9zaWNpw7NuIGRpYXJpYSBhIHBhbnRhbGxhcyB5IGxhIGFndWRlemEgdmlzdWFsLCBvIGVudHJlIGxhIGVkYWQgeSBsYSBjYW50aWRhZCBkZSBob3JhcyBkZSBhY3RpdmlkYWQgZsOtc2ljYS4gVmFsb3JlcyBkZSBjb3JyZWxhY2nDs24gY2VyY2Fub3MgYSBjZXJvIGluZGljYW4gcmVsYWNpb25lcyBsaW5lYWxlcyBkw6liaWxlcyBvIGluZXhpc3RlbnRlcywgbG8gcXVlIHN1Z2llcmUgcXVlIGxhcyB2YXJpYWJsZXMgc29uIHJlbGF0aXZhbWVudGUgaW5kZXBlbmRpZW50ZXMgZGVzZGUgZWwgcHVudG8gZGUgdmlzdGEgbGluZWFsOyBwb3IgZWwgY29udHJhcmlvLCBjb2VmaWNpZW50ZXMgYWxlamFkb3MgZGUgY2VybyBzZcOxYWxhbiBhc29jaWFjaW9uZXMgcXVlIHB1ZWRlbiBzZXIgY2zDrW5pY2FtZW50ZSByZWxldmFudGVzIHkgcXVlIGNvbnZpZW5lIGV4cGxvcmFyIGVuIG1heW9yIGRldGFsbGUgZW4gZmFzZXMgcG9zdGVyaW9yZXMgZGVsIGFuw6FsaXNpcy4gRW4gY29uanVudG8sIGVzdG9zIHJlc3VsdGFkb3MgcHJvcG9yY2lvbmFuIHVuYSBwcmltZXJhIGFwcm94aW1hY2nDs24gYSBsYSBlc3RydWN0dXJhIGludGVybmEgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIHkgb3JpZW50YW4gbGEgc2VsZWNjacOzbiBkZSB0w6ljbmljYXMgbXVsdGl2YXJpYW50ZXMgYXByb3BpYWRhcyBwYXJhIGxhcyBzaWd1aWVudGVzIHNlY2Npb25lcy4NCg0KIyMjIyBEaWFncmFtYSBDb25qdW50byBkZSBEaXNwZXJzacOzbiwgRGlzdHJpYnVjacOzbiB5IENvcnJlbGFjaW9uZXNbU0FdDQpgYGB7ciBEaWFncmFtYV9Db25qdW50b19EaXNwZXJjaW9uX0Rpc3RyaWJ1Y2lvbl9Db3JyZWxhY2lvbiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpnZ3BhaXJzKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSkNCmBgYA0KDQojIyMjIERpYWdyYW1hIENvbmp1bnRvIGRlIERpc3BlcnNpw7NuLCBEaXN0cmlidWNpw7NuIHkgQ29ycmVsYWNpb25lc1tDQV0NCmBgYHtyIERpYWdyYW1hX0Nvbmp1bnRvX2RlX0Rpc3BlcmNpb25fRGlzdHJpYnVjaW9uX0NvcnJlbGFjaW9uX0NBLCBmaWcuYWxpZ249J2NlbnRlcid9DQpjY2RfdmlzaW9uMjAyMF9FVEwkcmFuZ29fZXRhcmVvIDwtIGZhY3RvcihjY2RfdmlzaW9uMjAyMF9FVEwkcmFuZ29fZXRhcmVvKQ0KbGV2ZWxzPSBjICgxLDIsMyw0LDUpDQpsYWJlbHM9IGMgKCAiRWRhZCIgLCAiQVZfT0QiICwgIkFWX09JIiAsICJIb3Jhc19wZCIgLCAiSG9yYXNfYWYiKQ0KZ2dwYWlycyhjY2RfdmlzaW9uMjAyMF9FVEwsIGNvbHVtbiA9IGMoMiw4LDksMTAsMTEpLCBhZXMoY29sb3IgPSByYW5nb19ldGFyZW8sIGFscGhhID0gMC41KSwgdXBwZXIgPSBsaXN0KGNvbnRpbnVvdXMgPSB3cmFwKCJjb3IiLCBzaXplID0gMi41KSkpDQpgYGANCg0KDQojIyMjIERpYWdyYW1hIGRlIEVzdHJlbGxhcw0KYGBge3IgRGlhZ3JhbWFfZGVfRXN0cmVsbGFzLCBmaWcuYWxpZ249J2NlbnRlcid9DQpzZXQuc2VlZCgxMjA1MjIpDQpjY2RfdmlzaW9uMjAyMF9FVExfTVVFU1RSRUFETyA9IGNjZF92aXNpb24yMDIwX0VUTFtzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksMjMpLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0NCnN0YXJzKGNjZF92aXNpb24yMDIwX0VUTF9NVUVTVFJFQURPLCBsZW4gPSAxLCBjZXggPSAwLjQsIGtleS5sb2MgPSBjKDEwLCAyKSwgZHJhdy5zZWdtZW50cyA9IFRSVUUpDQpgYGANCg0KIyMjIyBDYXJhcyBkZSBDaGVybm9mZg0KYGBge3IgQ2FyYXNfZGVfQ2hlcm5vZmYsIGZpZy5hbGlnbj0nY2VudGVyJ30NCnNldC5zZWVkKDEyMDUyMikNCmNjZF92aXNpb24yMDIwX0VUTF9NVUVTVFJFQURPID0gY2NkX3Zpc2lvbjIwMjBfRVRMIFtzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksMjMpLC1jKDExLDMsNCw1LDYsNywxMiwxMyldDQpmYWNlcyhjY2RfdmlzaW9uMjAyMF9FVExfTVVFU1RSRUFETykNCmBgYA0KDQoNCiMjIyAxLjUuIE5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkVzIHBvc2libGUgYW5hbGl6YXIgbyBkZXRlcm1pbmFyIGxhIGRpc3RyaWJ1Y2nDs24gbXVsdGl2YXJpYWRhIGRlIHVuIGNvbmp1bnRvIGRlIGRhdG9zIG1lZGlhbnRlIG3DqXRvZG9zIGRlc2NyaXB0aXZvcywgY29tbyBsb3MgZ3LDoWZpY29zLCBvIGluZmVyZW5jaWFsZXMsIGNvbW8gbGFzIHBydWViYXMgZXN0YWTDrXN0aWNhcy4gTWllbnRyYXMgcXVlIGxvcyBwcm9jZWRpbWllbnRvcyBpbmZlcmVuY2lhbGVzIHBlcm1pdGVuIG9idGVuZXIgY29uY2x1c2lvbmVzIG3DoXMgZ2VuZXJhbGl6YWJsZXMsIGxvcyBncsOhZmljb3MgcmVzdWx0YW4gw7p0aWxlcyBjb21vIHNvcG9ydGUgcGFyYSBsYSBpbnRlcnByZXRhY2nDs24gZGUgbG9zIHJlc3VsdGFkb3MuDQoNCkVuIGVzdGUgYXBhcnRhZG8gc2UgYWJvcmRhIGxhIGFwbGljYWNpw7NuIGRlIHByb2NlZGltaWVudG9zIGluZmVyZW5jaWFsZXMgcGFyYSB2ZXJpZmljYXIgc2kgZWwgY29uanVudG8gZGUgZGF0b3MgZGUgdHJhYmFqbywgcmVzcGVjdG8gYSBzdXMgdmFyaWFibGVzIG51bcOpcmljYXMsIHNpZ3VlIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEgKEROTSkuIExhcyBwcnVlYmFzIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIChQTk0pIHF1ZSBzZSBhcGxpY2Fyw6FuIHNvbjogTWFyZGlhLCBIZW56ZS1aaXJrbGVyLCBEb29ybmlrLUhhbnNlbiB5IFJveXN0b24uIEVzdGFzIHBydWViYXMgZGUgbm9ybWFsaWRhZCBzZSByZWFsaXphbiBiYWpvIHVuIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgZGV0ZXJtaW5hZG8gJFxhbHBoYSA9IDAuMDUkIHkgYSBsYXMgaGlww7N0ZXNpczokJEhfMDogXHRleHQge0xhcyB2YXJpYWJsZXMgdGllbmVuIHVuYSBETk19JCQgJCRIXzE6IFx0ZXh0IHtMYXMgdmFyaWFibGVzIE5PIHRpZW5lbiB1bmEgRE5NfSQkIA0KDQpMYSAqKnBydWViYSBkZSBNYXJkaWEqKiBzZSBmdW5kYW1lbnRhIGVuIGxhcyBleHRlbnNpb25lcyBkZSBhc2ltZXRyw61hIHkgY3VydG9zaXMsIGVsIGN1YWRyYWRvIGRlIGxhIGRpc3RhbmNpYSBkZSBNYWhhbGFub2JpcywgZWwgbsO6bWVybyBkZSB2YXJpYWJsZXMgJHAkIGEgYW5hbGl6YXIgeSBlbCBuw7ptZXJvIGRlIHJlZ2lzdHJvcyAkbiQuIEFzaW1pc21vLCBzZSBjb25zaWRlcmEgcXVlIGxhIGVzdGFkw61zdGljYSBkZSBsYSBwcnVlYmEgcGFyYSBsYSBhc2ltZXRyw61hIHNpZ3VlIHVuYSBkaXN0cmlidWNpw7NuICRcY2hpXjIkLCBtaWVudHJhcyBxdWUgbGEgZXN0YWTDrXN0aWNhIHBhcmEgbGEgY3VydG9zaXMgc2UgZGlzdHJpYnV5ZSBkZSBtYW5lcmEgYXByb3hpbWFkYSBkZSBmb3JtYSBub3JtYWwuIA0KDQpMYSAqKnBydWViYSBkZSBIZW56ZS1aaXJrbGVyKiogc2UgYmFzYSBlbiBsYSBkaXN0YW5jaWEgZnVuY2lvbmFsLCB5YSBxdWUgc2kgZWwgY29uanVudG8gZGUgZGF0b3Mgc2lndWUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYSwgZWwgZXN0YWTDrXN0aWNvIGRlIGxhIHBydWViYSBzZSBkaXN0cmlidXllIGRlIG1hbmVyYSBhcHJveGltYWRhIGNvbW8gdW5hIGxvZ25vcm1hbCwgY29uIHBhcsOhbWV0cm9zIGRlIG1lZGlhICRcbXUkIHkgdmFyaWFuemEgJFxzaWdtYV4yJC4gDQoNCkxhICoqcHJ1ZWJhIGRlIERvb3JuaWstSGFuc2VuKiogc2UgYmFzYSBlbiBsYSBhc2ltZXRyw61hIHkgbGEgY3VydG9zaXMgZGUgdW4gY29uanVudG8gZGUgZGF0b3MgbXVsdGl2YXJpYWRvcywgbG9zIGN1YWxlcyBzZSB0cmFuc2Zvcm1hbiBwYXJhIGFzZWd1cmFyIGxhIGluZGVwZW5kZW5jaWEuIFNlIGNvbnNpZGVyYSBtw6FzIHBvdGVudGUgcXVlIGxhIHBydWViYSBkZSBTaGFwaXJvLVdpbGsgZW4gY2Fzb3MgbXVsdGl2YXJpYWRvcy4gRWwgZXN0YWTDrXN0aWNvIGRlIGxhIHBydWViYSBzZSBkZWZpbmUgY29tbyBsYSBzdW1hIGRlIGxhcyB0cmFuc2Zvcm1hY2lvbmVzIGFsIGN1YWRyYWRvIGRlIGxhIGFzaW1ldHLDrWEgeSBsYSBjdXJ0b3NpcywgeSBzaWd1ZSBhcHJveGltYWRhbWVudGUgdW5hIGRpc3RyaWJ1Y2nDs24gJFxjaGleMiQuIA0KDQpQb3Igb3RybyBsYWRvLCBsYSBwcnVlYmEgZGUgUm95c3RvbiB1dGlsaXphIGxhcyAqKnBydWViYXMgZGUgU2hhcGlyby1XaWxrIG8gU2hhcGlyby1GcmFuY2lhKiogcGFyYSBldmFsdWFyIGxhIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhLiBTaSBsYSBjdXJ0b3NpcyBlcyBtYXlvciBxdWUgMywgc2UgZW1wbGVhIFNoYXBpcm8tRnJhbmNpYSBwYXJhIGRpc3RyaWJ1Y2lvbmVzIGxlcHRvY8O6cnRpY2FzLCBtaWVudHJhcyBxdWUgcGFyYSBkaXN0cmlidWNpb25lcyBwbGF0aWPDunJ0aWNhcyBzZSB1dGlsaXphIFNoYXBpcm8tV2lsay4gTG9zIHBhcsOhbWV0cm9zIGVuIGVzdGEgcHJ1ZWJhIHNlIG9idGllbmVuIG1lZGlhbnRlIGFwcm94aW1hY2lvbmVzIHBvbGlub21pYWxlcy4NCg0KIyMjIDEuNiBQbGFudGVhbWllbnRvIHkgRGVzYXJyb2xsbyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpBIHBhcnRpciBkZWwgY29uanVudG8gZGUgZGF0b3MgZGVzY3JpdG8gZW4gbGEgc2VjY2nDs24gMS4yLCBzZSBhcGxpY2EgdW5hIHBydWViYSBlc3RhZMOtc3RpY2EgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEgY29uIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgXChcYWxwaGEgPSAwLjA1XCksIGNvbiBlbCBwcm9ww7NzaXRvIGRlIGV2YWx1YXIgc2kgZWwgdmVjdG9yIGZvcm1hZG8gcG9yIGxhcyB2YXJpYWJsZXMgbcOpdHJpY2FzIHByb3ZpZW5lIGRlIHVuYSBwb2JsYWNpw7NuIGNvbiBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEuIEVuIGVzdGUgZXN0dWRpbywgbGFzIHZhcmlhYmxlcyBudW3DqXJpY2FzIGVuIGVzY2FsYSBkZSByYXrDs24gc29uOiAqKmVkYWRfcGFjaWVudGUqKiwgKipBZ3VkZXphX3Zpc3VhbF9PRCoqLCAqKkFndWRlemFfdmlzdWFsX09JKiosICoqSG9yYXNfcGFudGFsbGFfZGlhKiogeSAqKkhvcmFzX2FmKiouIEFudGVzIGRlIHJlYWxpemFyIGxhcyBwcnVlYmFzLCBlc3RhcyB2YXJpYWJsZXMgc2UgZXN0YW5kYXJpemFuIHBhcmEgZ2FyYW50aXphciBjb21wYXJhYmlsaWRhZCB5IGVzdGFiaWxpZGFkIG51bcOpcmljYSBlbiBsb3MgY8OhbGN1bG9zLg0KDQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBwcmVzZW50YSBkZSBtYW5lcmEgc2VwYXJhZGEgbG9zIHJlc3VsdGFkb3MgZGUgbGFzIHByaW5jaXBhbGVzIHBydWViYXMgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEgY29uc2lkZXJhZGFzOiBNYXJkaWEsIEhlbnpl4oCTWmlya2xlciwgRG9vcm5pa+KAk0hhbnNlbiB5IFJveXN0b24uIEVuIGxhIHBlc3Rhw7FhIGNvcnJlc3BvbmRpZW50ZSBhIGxhICoqUE5NIGRlIE1hcmRpYSoqIHNlIHJlcG9ydGFuIGxvcyBlc3RhZMOtc3RpY29zIGRlIGFzaW1ldHLDrWEgeSBjdXJ0b3NpcyBtdWx0aXZhcmlhZGFzLCBqdW50byBjb24gc3VzIHJlc3BlY3Rpdm9zIFwocFwpLXZhbG9yZXMuIERhZG8gcXVlLCBwYXJhIGFsIG1lbm9zIHVubyBkZSBlc3RvcyBjb21wb25lbnRlcywgZWwgXChwXCktdmFsb3IgcmVzdWx0YSBtZW5vciBxdWUgZWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBlc3RhYmxlY2lkbywgc2UgcHJvY2VkZSBhIHJlY2hhemFyIGxhIGhpcMOzdGVzaXMgbnVsYSBkZSBub3JtYWxpZGFkIG11bHRpdmFyaWFkYSwgY29uY2x1eWVuZG8gcXVlIGVsIGNvbmp1bnRvIGRlIHZhcmlhYmxlcyBtw6l0cmljYXMgbm8gc2lndWUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4NCg0KRGUgZm9ybWEgY29uc2lzdGVudGUsIGxhIHBlc3Rhw7FhIGFzb2NpYWRhIGEgbGEgKipQTk0gZGUgSGVuemXigJNaaXJrbGVyKiogbXVlc3RyYSB1biBcKHBcKS12YWxvciBpbmZlcmlvciBhIFwoXGFscGhhID0gMC4wNVwpLCBsbyBxdWUgbGxldmEgaWd1YWxtZW50ZSBhIHJlY2hhemFyIGxhIGhpcMOzdGVzaXMgbnVsYSB5IGFjZXB0YXIgbGEgaGlww7N0ZXNpcyBhbHRlcm5hdGl2YSBkZSBxdWUgbG9zIGRhdG9zIG5vIHByb3ZpZW5lbiBkZSB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwgbXVsdGl2YXJpYWRhLiBSZXN1bHRhZG9zIGFuw6Fsb2dvcyBzZSBvYnNlcnZhbiBlbiBsYSAqKlBOTSBkZSBEb29ybmlr4oCTSGFuc2VuKiosIGRvbmRlIGVsIFwocFwpLXZhbG9yIG9idGVuaWRvIHRhbWJpw6luIGVzIG1lbm9yIHF1ZSBlbCBuaXZlbCBkZSBzaWduaWZpY2FuY2lhLCByZWZvcnphbmRvIGxhIGRlY2lzacOzbiBkZSByZWNoYXphciBsYSBub3JtYWxpZGFkLiBGaW5hbG1lbnRlLCBsYSAqKlBOTSBkZSBSb3lzdG9uKiogcHJlc2VudGEgdW4gXChwXCktdmFsb3IgaW5mZXJpb3IgYSBcKFxhbHBoYVwpLCBjb25maXJtYW5kbyBxdWUsIGVuIGNvbmp1bnRvLCBsYXMgdmFyaWFibGVzICoqZWRhZF9wYWNpZW50ZSoqLCAqKkFndWRlemFfdmlzdWFsX09EKiosICoqQWd1ZGV6YV92aXN1YWxfT0kqKiwgKipIb3Jhc19wYW50YWxsYV9kaWEqKiB5ICoqSG9yYXNfYWYqKiBubyBzZSBhanVzdGFuIGEgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4gRW4gY29uc2VjdWVuY2lhLCB0b2RhcyBsYXMgcHJ1ZWJhcyBhcGxpY2FkYXMgY29pbmNpZGVuIGVuIHF1ZSwgYWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBjb25zaWRlcmFkbywgbm8gc2Ugc3VzdGVudGEgbGEgaGlww7N0ZXNpcyBudWxhIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIHBhcmEgZWwgdmVjdG9yIGRlIHZhcmlhYmxlcyBtw6l0cmljYXMsIGFjZXB0w6FuZG9zZSBsYSBoaXDDs3Rlc2lzIGFsdGVybmF0aXZhLg0KDQoNCiMjIyMgUE5NIE1hcmRpYQ0KYGBge3IgUE5NX01hcmRpYSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQptYXJkaWEoY2NkX3Zpc2lvbjIwMjBfRVRMWywgLWMoMTEsMyw0LDUsNiw3LDEyLDEzKV0pDQpgYGANCg0KIyMjIyBQTk0gSGVuemUtWmlya2xlcg0KYGBge3IgUE5NX0hlbnplX1ppcmtsZXIgPSAnY2VudGVyJ30NCm1oeihjY2RfdmlzaW9uMjAyMF9FVExbLCAtYygxMSwzLDQsNSw2LDcsMTIsMTMpXSkNCmBgYA0KDQojIyMjIFBOTSBNU0sNCmBgYHtyIFBOTV9NU0ssIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KbXNrKGNjZF92aXNpb24yMDIwX0VUTFssIC1jKDExLDMsNCw1LDYsNywxMiwxMyldLCBCPTEwKQ0KYGBgDQoNCiMjIyMgUE5NIG5UZXN0DQpgYGB7ciBQTk1fblRlc3QsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KbXZuVGVzdChjY2RfdmlzaW9uMjAyMF9FVExbLCAtYygxMSwzLDQsNSw2LDcsMTIsMTMpXSwgQj0xMCkNCg0KYGBgDQoNCiMjICoqRmFzZSAyIFtDb21wb25lbnRlcyBQcmluY2lwYWxlc10qKg0KDQpFbiBlc3RhICoqc2VndW5kYSBldGFwYSoqIGRlbCBlc3R1ZGlvLCBzZSBwcmVzZW50YXLDoW4gY8OhbGN1bG9zLCB2aXN1YWxpemFjaW9uZXMgZSBpbnRlcnByZXRhY2lvbmVzIGJhc2FkYXMgZW4gZWwgY29uanVudG8gZGUgZGF0b3MgYW5hbGl6YWRvIHByZXZpYW1lbnRlIGVuIGxhIFtGYXNlIDFdKCNzZWMxKS4gQWhvcmEsIGVsIGVuZm9xdWUgc2UgY2VudHJhcsOhIGVuIGVsIGFuw6FsaXNpcyBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcyAoQUNQKSBhcGxpY2FkbyBhIGxhcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcywgaW5jbHV5ZW5kbyBhc3BlY3RvcyBjb21vIGxhIHNlbGVjY2nDs24gZGUgY29tcG9uZW50ZXMsIGNhbGlkYWQgZGUgcmVwcmVzZW50YWNpw7NuLCBjb250cmlidWNpb25lcyB5IHN1IGludGVycHJldGFjacOzbi4NCg0KIyMjIDIuMS4gT2JqZXRpdm9zDQoNCkVsICoqQUNQKiogc2UgbG9ncmEgYSBsbyBsYXJnbyBkZSBsYXMgc2lndWllbnRlcyBmYXNlczogZ2VuZXJhY2nDs24gZGUgbnVldmFzIHZhcmlhYmxlcywgcmVkdWNjacOzbiBkaW1lbnNpb25hbCBkZWwgZXNwYWNpbyBkZSBsb3MgZGF0b3MsIGVsaW1pbmFjacOzbiBkZSB2YXJpYWJsZXMgZGUgcG9jbyBhcG9ydGUgZSBpbnRlcnByZXRhY2nDs24gZGUgbG9zIGNvbXBvbmVudGVzIHJlc3VsdGFudGVzIGVuIGVsIGNvbnRleHRvIGRlbCBwcm9ibGVtYSBkZWwgY3VhbCBzZSBvYnR1dmllcm9uIGxvcyBkYXRvLg0KDQpFc3RpbWFkbyBsZWN0b3IsIHNpIGRlc2VhIGV4cGxvcmFyIGxvcyBmdW5kYW1lbnRvcyBkZSBlc3RlIGFuw6FsaXNpcyBjb24gbWF5b3IgcHJvZnVuZGlkYWQuIExvcyBkZXRhbGxlcyBkZWwgY29uanVudG8gZGUgZGF0b3Mgc2UgZW5jdWVudHJhbiBkZXNjcml0b3MgZW4gbGEgW1NlY2Npw7NuIDEuMl0oI3NlYzEuMiksIG1pZW50cmFzIHF1ZSBsb3MgcHJpbmNpcGlvcyB0ZcOzcmljb3MgcXVlIHN1c3RlbnRhbiBlc3RlIGVzdHVkaW8gZXN0w6FuIGN1aWRhZG9zYW1lbnRlIGRlc2Fycm9sbGFkb3MgZW4gbGEgZGVub21pbmFkYSBbRmFzZSAxXSgjc2VjMSkuIFVuYSBsZWN0dXJhIGRldGVuaWRhIGRlIGVzdGFzIHNlY2Npb25lcyBlbnJpcXVlY2Vyw6Egc3UgY29tcHJlbnNpw7NuIHkgYXByZWNpYWNpw7NuIGRlbCB0cmFiYWpvIHByZXNlbnRhZG8uDQoNCg0KIyMjIDIuMi4gU2VsZWNjacOzbiBkZSBDb21wb25lbnRlcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpDb21vIHNlw7FhbGFuIETDrWF6IE1vcmFsZXMgeSBNb3JhbGVzIFJpdmVyYSAoMjAxMiksIGVsIEFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyAqKihBQ1ApKiogcGVybWl0ZSByZW9yZ2FuaXphciB1biBjb25qdW50byBkZSBkYXRvcyBtdWx0aXZhcmlhZG8gYWwgcmVkdWNpciBlbCBuw7ptZXJvIGRlIHZhcmlhYmxlcywgc2luIHJlcXVlcmlyIHN1cG9zaWNpb25lcyBlc3BlY8OtZmljYXMgc29icmUgbGEgZGlzdHJpYnVjacOzbiBkZSBwcm9iYWJpbGlkYWQgZGUgZXN0YXMuIEVzdGEgcmVkdWNjacOzbiBzZSBhbGNhbnphIG1lZGlhbnRlIGxhIGNyZWFjacOzbiBkZSBjb21iaW5hY2lvbmVzIGxpbmVhbGVzIGRlIGxhcyB2YXJpYWJsZXMgb3JpZ2luYWxlcywgZGlzZcOxYWRhcyBwYXJhIGNhcHRhciBsYSBtYXlvciB2YXJpYWJpbGlkYWQgcG9zaWJsZSBlbiBsb3MgZGF0b3MuIERlIGVzdGUgbW9kbywgZWwgKipBQ1AqKiBnZW5lcmEgbnVldmFzIHZhcmlhYmxlcywgZGVub21pbmFkYXMgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMsIHF1ZSBwcmVzZW50YW4gaW5kZXBlbmRlbmNpYSBlc3RhZMOtc3RpY2EgeSBhdXNlbmNpYSBkZSBjb3JyZWxhY2nDs24sIHNpZW1wcmUgYmFqbyBlbCBzdXB1ZXN0byBkZSBub3JtYWxpZGFkLg0KDQojIyMgMi4zLiBQbGFudGVhbWllbnRvIHkgRGVzYXJyb2xsbyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpBIHBhcnRpciBkZSBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIFtTZWNjacOzbiAxLjJdKCNzZWMxLjIpLCBzZSByZXF1aWVyZSBpbmljaWFsbWVudGUgZGV0ZXJtaW5hciBlbCBwb3JjZW50YWplIGRlIHZhcmlhbnphIGV4cGxpY2FkbyBwb3IgY2FkYSBkaW1lbnNpw7NuIHRyYXMgcmVhbGl6YXIgZWwgQW7DoWxpc2lzIGRlIENvbXBvbmVudGVzIFByaW5jaXBhbGVzIChBQ1ApLiBQb3N0ZXJpb3JtZW50ZSwgY29uIGJhc2UgZW4gZWwgYXV0b3ZhbG9yIHByb21lZGlvIG8gbWVkaWFudGUgdW4gZ3LDoWZpY28gZGUgc2VkaW1lbnRhY2nDs24sIHNlIGRlYmUgZGVjaWRpciBjdcOhbnRvcyBjb21wb25lbnRlcyBjb25zZXJ2YXIuDQoNCkxhIG5hdmVnYWNpw7NuIGEgdHJhdsOpcyBkZSBsYXMgcGVzdGHDsWFzIG11ZXN0cmEgcXVlIGVsIGNvbmp1bnRvIGRlIGRhdG9zLCBlbiByZWxhY2nDs24gY29uIHN1cyB2YXJpYWJsZXMgbnVtw6lyaWNhcywgcHVlZGUgc2VyIHJlcHJlc2VudGFkbyBwb3IgdW4gY29uanVudG8gbcOhcyBwZXF1ZcOxbyBkZSBkaW1lbnNpb25lcyBxdWUgcmV0aWVuZSBlbCAkNDMuMDElJCBkZSBsYSB2YXJpYWJpbGlkYWQgdG90YWwgZW4gbGFzIGRvcyBwcmltZXJhcyBkaW1lbnNpb25lcy4gRXN0ZSByZXN1bHRhZG8gc3VnaWVyZSBxdWUgbGEgdmFyaWFuemEgZXN0w6EgZGlzdHJpYnVpZGEgZGUgbWFuZXJhIHJlbGF0aXZhbWVudGUgdW5pZm9ybWUgZW50cmUgbGFzIHByaW5jaXBhbGVzIGRpbWVuc2lvbmVzLCBsbyBxdWUgaW5kaWNhIHVuYSBlc3RydWN0dXJhIGludGVybmEgZW4gbGEgcXVlIGxhcyB2YXJpYWJsZXMgb3JpZ2luYWxlcyAqKm5vIGVzdMOhbiBhbHRhbWVudGUgY29ycmVsYWNpb25hZGFzKiouIEVuIHBhcnRpY3VsYXI6DQoNCkxhICoqTWF0cml6IEFDUCoqIG11ZXN0cmEgY2luY28gZGltZW5zaW9uZXMsIGRvbmRlIGxhIHByaW1lcmEgcmV0aWVuZSBlbCAkMjIuNDklJCBkZSBsYSB2YXJpYW56YSwgc2VndWlkYSBwb3IgbGEgc2VndW5kYSBjb24gdW4gJDIwLjUyJSQsIHkgbGEgdGVyY2VyYSBjb24gdW4gJDE5Ljg1JCQlJC4gTGFzIGRvcyDDumx0aW1hcyBkaW1lbnNpb25lcyBleHBsaWNhbiB1biAkMTguODIlJCB5IHVuICQxOC4zMSUkLCByZXNwZWN0aXZhbWVudGUuIEVuIGVzdGUgc2VudGlkbywgbGEgcmVwcmVzZW50YXRpdmlkYWQgZGUgbGEgY29tYmluYWNpw7NuIGxpbmVhbCBxdWUgZGVmaW5lIGxhICoqZGltZW5zacOzbiAxKiogZXMgbW9kZXJhZGFtZW50ZSBzdXBlcmlvciBlbiBjb21wYXJhY2nDs24gY29uIGxhcyBkZW3DoXMuIENvbW8gZXN0YSBtYXRyaXogbm8gcHJvcG9yY2lvbmEgaW5mb3JtYWNpw7NuIGRpcmVjdGEgc29icmUgbGFzIHZhcmlhYmxlcyBvcmlnaW5hbGVzLCBzZSBjb250aW7DumEgZXhwbG9yYW5kbyBsYSBpZGVudGlmaWNhY2nDs24gZGUgbGFzIHZhcmlhYmxlcyBxdWUgbcOhcyBjb250cmlidXllbiBhIGxhIGRpbWVuc2nDs24gY29uIGVsIG1heW9yIHZhbG9yIHByb3Bpby4NCg0KTGEgKipNYXRyaXogZGUgQ29ycmVsYWNpb25lcyoqIGF5dWRhIGEgZGVzY3JpYmlyIGxhcyByZWxhY2lvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMgcXVlIGNvbmZvcm1hbiBsYSBkaW1lbnNpw7NuIDEuIFNlZ8O6biBlc3RhIG1hdHJpeiwgbGFzIGNvcnJlbGFjaW9uZXMgZW50cmUgbGFzIHZhcmlhYmxlcyBzb24gZW4gc3UgbWF5b3LDrWEgYmFqYXMsIGNvbiB1biB2YWxvciBtw6F4aW1vIGRlICQwLjA0JCBlbnRyZSAqKkhvcmFzX3BkKiogeSAqKmVkYWRfcGFjaWVudGUqKi4gRXN0byBpbmRpY2EgcXVlIGxhcyB2YXJpYWJsZXMgbm8gZXN0w6FuIGZ1ZXJ0ZW1lbnRlIHJlbGFjaW9uYWRhcyBlbnRyZSBzw60sIGxvIHF1ZSBwb2Ryw61hIGluZmx1aXIgZW4gY8OzbW8gY29udHJpYnV5ZW4gYSBsYSBjb21iaW5hY2nDs24gbGluZWFsIHF1ZSBkZWZpbmUgbGEgcHJpbWVyYSBkaW1lbnNpw7NuLg0KDQpMYSBwZXN0YcOxYSBWYWxvcmVzIHkgVmVjdG9yZXMgUHJvcGlvcyBwcmVzZW50YSBsb3MgcmVzdWx0YWRvcyBvYnRlbmlkb3MgYSBwYXJ0aXIgZGVsIGFuw6FsaXNpcyBkZSBsYSBtYXRyaXogZGUgY29ycmVsYWNpb25lcyBkZWwgY29uanVudG8gZGUgZGF0b3MgY2zDrW5pY29zLiBFbiBlc3RlIGFuw6FsaXNpcyBzZSB2ZXJpZmljYSBxdWUgbGEgc3VtYSBkZSBsb3MgdmFsb3JlcyBwcm9waW9zIGNvaW5jaWRlIGNvbiBlbCBuw7ptZXJvIGRlIHZhcmlhYmxlcyBhbmFsaXphZGFzLCBsbyBxdWUgZ2FyYW50aXphIHF1ZSBsYSB0b3RhbGlkYWQgZGUgbGEgdmFyaWFiaWxpZGFkIGRlbCBzaXN0ZW1hIHF1ZWRhIHJlcHJlc2VudGFkYSBwb3IgZWwgY29uanVudG8gZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuIEEgcGFydGlyIGRlIGVzdG9zIHZhbG9yZXMgcHJvcGlvcyBzZSBkZXRlcm1pbmFuIGRpcmVjdGFtZW50ZSBsYXMgcHJvcG9yY2lvbmVzIGRlIHZhcmlhbnphIGV4cGxpY2FkYSBwb3IgY2FkYSBjb21wb25lbnRlLg0KDQpQb3Igb3RyYSBwYXJ0ZSwgbGEgbWF0cml6IGRlIHZlY3RvcmVzIHByb3Bpb3MgcHJvcG9yY2lvbmEgbG9zIGNvZWZpY2llbnRlcyBxdWUgZGVmaW5lbiBsYXMgY29tYmluYWNpb25lcyBsaW5lYWxlcyBkZSBsYXMgdmFyaWFibGVzIG9yaWdpbmFsZXMgcXVlIGRhbiBsdWdhciBhIGNhZGEgY29tcG9uZW50ZSBwcmluY2lwYWwuIEVzdG9zIGNvZWZpY2llbnRlcywgdGFtYmnDqW4gY29ub2NpZG9zIGNvbW8gY2FyZ2FzIGZhY3RvcmlhbGVzLCBwZXJtaXRlbiBpZGVudGlmaWNhciBlbCBwZXNvIHkgbGEgZGlyZWNjacOzbiBkZSBsYSBjb250cmlidWNpw7NuIGRlIGNhZGEgdmFyaWFibGUgZW4gbGFzIG51ZXZhcyBkaW1lbnNpb25lcyBkZWwgYW7DoWxpc2lzLg0KDQpFbiBwYXJ0aWN1bGFyLCBwYXJhIGxhIHByaW1lcmEgY29tcG9uZW50ZSBwcmluY2lwYWwgKENQMSksIHkgY29uc2lkZXJhbmRvIGxvcyBjb2VmaWNpZW50ZXMgcmVkb25kZWFkb3MgYSBkb3MgY2lmcmFzIGRlY2ltYWxlcywgZG9uZGUgRWRhZCBjb3JyZXNwb25kZSBhIGxhIGVkYWQgZGVsIHBhY2llbnRlLCBBVl9PRCB5IEFWX09JIHJlcHJlc2VudGFuIGxhIGFndWRlemEgdmlzdWFsIGRlbCBvam8gZGVyZWNobyBlIGl6cXVpZXJkbyByZXNwZWN0aXZhbWVudGUsIEhvcmFzX1BEIGVsIHRpZW1wbyBkZSB1c28gZGUgcGFudGFsbGFzIGRpZ2l0YWxlcyB5IEhvcmFzX0FGIGxhcyBob3JhcyBkZSBhY3RpdmlkYWQgZsOtc2ljYSAodG9kYXMgdmFyaWFibGVzIHByZXZpYW1lbnRlIGVzdGFuZGFyaXphZGFzKSwgbGEgY29tcG9uZW50ZSBwdWVkZSBleHByZXNhcnNlIGNvbW86DQoNCg0KJENvbXBvbmVudGUgMSA9IDAuNDYgKiBFZGFkIOKIkiAwLjQ0ICogQVZfT0Qg4oiSIDAuNTIgKiBBVl9PSSArIDAuNTUgKiBIb3Jhc19QRCArIDAuMTYgKiBIb3Jhc19BRiQNCg0KRXN0YSBmb3JtdWxhY2nDs24gZXZpZGVuY2lhIHF1ZSBsYSBwcmltZXJhIGNvbXBvbmVudGUgZXN0w6EgcHJpbmNpcGFsbWVudGUgaW5mbHVlbmNpYWRhIHBvciBlbCB1c28gZGUgcGFudGFsbGFzIGRpZ2l0YWxlcywgbGEgZWRhZCBkZWwgcGFjaWVudGUgeSBsYSBhZ3VkZXphIHZpc3VhbCwgZXNwZWNpYWxtZW50ZSBkZWwgb2pvIGl6cXVpZXJkby4gRW4gY29uc2VjdWVuY2lhLCBlc3RhIGRpbWVuc2nDs24gcmVzdW1lIHVuIHBhdHLDs24gY2zDrW5pY28gYXNvY2lhZG8gYSBsb3MgaMOhYml0b3MgdmlzdWFsZXMgeSBzdSByZWxhY2nDs24gY29uIGxhIGZ1bmNpw7NuIHZpc3VhbCwgZmFjaWxpdGFuZG8gbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGxhcyBpbnRlcmFjY2lvbmVzIG11bHRpdmFyaWFudGVzIHByZXNlbnRlcyBlbiBsb3MgZGF0b3MuDQoNCkxvcyBncsOhZmljb3MgZGUgKipDYXR0ZWxsKiogeSAqKkNhdHRlbGwtS2Fpc2VyKiosIGNvbm9jaWRvcyBwb3Igc3VzIGZvcm1hcyBkZSBjb2RvIHkgc2VkaW1lbnRhY2nDs24sIHNvbiBoZXJyYW1pZW50YXMgw7p0aWxlcyBwYXJhIGRlY2lkaXIgY3XDoW50YXMgY29tcG9uZW50ZXMgcmV0ZW5lciBlbiB1biBhbsOhbGlzaXMgZGUgcmVkdWNjacOzbiBkZSBkaW1lbnNpw7NuLCBhc2VndXJhbmRvIHF1ZSBzZSBjb25zZXJ2ZSBzdWZpY2llbnRlIHZhcmlhYmlsaWRhZCBwYXJhIGFib3JkYXIgZWwgcHJvYmxlbWEuDQoNCkVsICoqR3LDoWZpY28gZGUgQ2F0dGVsbCoqIG11ZXN0cmEgY8OzbW8gdmFyw61hIGxhIHBlbmRpZW50ZSBlbnRyZSBsYXMgY29tcG9uZW50ZXMsIGRlc3RhY2FuZG8gcXVlIGxhIHByaW1lcmEgY29tcG9uZW50ZSB0aWVuZSB1bmEgY2FwYWNpZGFkIGV4cGxpY2F0aXZhIHNpZ25pZmljYXRpdmFtZW50ZSBtYXlvciwgZXhwbGljYW5kbyBlbCAkMjIuNSQkJSQgZGUgbGEgdmFyaWFuemEgdG90YWwuIEVzdGUgY2FtYmlvIGVuIGxhIHBlbmRpZW50ZSwgdGFtYmnDqW4gY29ub2NpZG8gY29tbyAicHVudG8gZGUgaW5mbGV4acOzbiIsIHN1Z2llcmUgcXVlIGxvcyBwcmltZXJvcyBjb21wb25lbnRlcyBzb24gY2xhdmUgcGFyYSByZXRlbmVyLCB5YSBxdWUgY2FwdHVyYW4gbGEgbWF5b3IgcGFydGUgZGUgbGEgdmFyaWFiaWxpZGFkIGRlbCBjb25qdW50byBkZSBkYXRvcy4NCg0KQWRlbcOhcywgZWwgKipHcsOhZmljbyBkZSBDYXR0ZWxsLUthaXNlcioqIGNvbWJpbmEgZXN0YSB2aXN1YWxpemFjacOzbiBjb24gZWwgY3JpdGVyaW8gZGUgS2Fpc2VyLCBxdWUgcmVjb21pZW5kYSByZXRlbmVyIGxvcyBjb21wb25lbnRlcyBjb24gdW4gdmFsb3IgcHJvcGlvIHN1cGVyaW9yIGEgMS4gU2Vnw7puIGVzdGUgY3JpdGVyaW8sIHNvbG8gbGEgcHJpbWVyYSBjb21wb25lbnRlIGN1bXBsZSBjb24gZXN0YSBjb25kaWNpw7NuLCBsbyBxdWUgaW5pY2lhbG1lbnRlIHJlc3BhbGRhIGxhIGVsZWNjacOzbiBkZSByZXRlbmVyIMO6bmljYW1lbnRlIGVzdGEuIFNpbiBlbWJhcmdvLCBhbCBjb25zaWRlcmFyIGxhIHZhcmlhbnphIGFjdW11bGFkYSwgc2Ugb2JzZXJ2YSBxdWUgbG9zIHRyZXMgcHJpbWVyb3MgY29tcG9uZW50ZXMgZXhwbGljYW4ganVudG9zIGVsICQ2Mi45JSQgZGUgbGEgdmFyaWFiaWxpZGFkLCBsbyBxdWUgc3VnaWVyZSBxdWUgaW5jbHVpciBtw6FzIGRlIHVuIGNvbXBvbmVudGUgcG9kcsOtYSBzZXIgdmFsaW9zbyBwYXJhIGNhcHR1cmFyIGRpbWVuc2lvbmVzIGFkaWNpb25hbGVzIHJlbGV2YW50ZXMgZW4gZWwgYW7DoWxpc2lzLCBlc3BlY2lhbG1lbnRlIGVuIHVuIGNvbnRleHRvIGNsw61uaWNvIGRvbmRlIGRpZmVyZW50ZXMgZmFjdG9yZXMgcHVlZGVuIGluZmx1aXIgZW4gZWwgZGlhZ25vc3RpY28gZGUgZW5mZXJtZWRhZGVzIG9jdWxhcmVzLg0KDQpQb3IgdGFudG8sIHNlIHRvbWEgbGEgZGVjaXNpw7NuIGRlIHRyYWJhamFyIGNvbiBkb3MgY29tcG9uZW50ZXMsIHlhIHF1ZSBwZXJtaXRlbiBjYXB0dXJhciBwYXRyb25lcyBpbXBvcnRhbnRlcyByZWxhY2lvbmFkb3MgY29uIGxhcyBhZmVjY2lvbmVzIGNhcmRpb3Zhc2N1bGFyZXMgc2luIGHDsWFkaXIgdW5hIGNvbXBsZWppZGFkIGlubmVjZXNhcmlhIGFsIGFuw6FsaXNpcy4gRXN0byBmYWNpbGl0YSBsYSBpbnRlcnByZXRhY2nDs24gZGUgbG9zIHJlc3VsdGFkb3MgeSBnYXJhbnRpemEgdW5hIHJlcHJlc2VudGFjacOzbiBzaWduaWZpY2F0aXZhIGRlIGxvcyBkYXRvcy4NCg0KIyMjIyBNYXRyaXogQUNQDQpgYGB7ciBNYXRyaXpfQUNQLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmdldF9laWdlbnZhbHVlKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpKQ0KYGBgDQoNCiMjIyMgTWF0cml6IGRlIENvcnJlbGFjaW9uZXMNCmBgYHtyIE1hdHJpel9kZV9Db3JyZWxhY2lvbmVzfQ0Kcm91bmQoY29yKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSksMikNCmBgYA0KDQojIyMjIFZhbG9yZXMgeSBWZWN0b3JlcyBQcm9waW9zDQpgYGB7ciBWYWxvcmVzX3lfVmVjdG9yZXNfUHJvcGlvcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpwcmluY29tcChjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIGNvciA9IFRSVUUpJHNkZXZeMg0KcHJpbmNvbXAoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBjb3IgPSBUUlVFKSRsb2FkaW5nc1sgLDE6NV0NCmBgYA0KDQojIyMjIENvcnJlbGFjaW9uZXMgQ29tcGFyYWRhcw0KYGBge3IgQ29ycmVsYWNpb25lc19Db21wYXJhZGFzLCBmaWcuYWxpZ249J2NlbnRlcid9DQpwYXIobWZyb3c9YygxLDIpKQ0KY29ycnBsb3Q6OmNvcnJwbG90KGNvcihjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0pLCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwgbnVtYmVyLmNleCA9IDAuNCkNCmNvcnJwbG90Ojpjb3JycGxvdChjb3IocHJpbmNvbXAoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBjb3IgPSBUUlVFKSRzY29yZXMpLCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwgbnVtYmVyLmNleCA9IDAuNCkNCmBgYA0KDQojIyMjIEdyw6FmaWNvIGRlIENhdHRlbGwNCmBgYHtyIEdyYWZpY29fZGVfQ2F0dGVsbCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X2VpZyhQQ0EoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBzY2FsZS51bml0ID0gVCwgZ3JhcGggPSBGKSwgYWRkbGFiZWxzID0gVCwgeWxpbT1jKDAsOTApLCBtYWluID0gIiIpDQpgYGANCg0KIyMjIyBHcsOhZmljbyBkZSBDYXR0ZWxsLUthaXNlcg0KYGBge3IgR3JhZmljb19kZV9DYXR0ZWxsX0thaXNlciwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpzY3JlZShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sZmFjdG9ycyA9IEZBTFNFLCBwYyA9IFRSVUUsIG1haW4gPSIiKQ0KYGBgDQoNCg0KIyMjIDIuNC4gQ2FsaWRhZCBkZSBSZXByZXNlbnRhY2nDs24gey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KQ29uIGJhc2UgZW4gbGEgcmVmZXJlbmNpYSBkZSAsc2UgY29uZmlybWEgcXVlLCB0cmFzIHJlZHVjaXIgbGEgZGltZW5zaW9uYWxpZGFkIGRlbCBjb25qdW50byBkZSBkYXRvcyB5IGVudGVuZGVyIHF1ZSBzdXMgdmFyaWFibGVzIGVzdGFuZGFyaXphZGFzIHNlIHJlcHJlc2VudGFuIGdyw6FmaWNhbWVudGUgY29tbyBwcm95ZWNjaW9uZXMgZGUgdW5hIGhpcGVyZXNmZXJhIGRlIGNvcnJlbGFjaW9uZXMsIGVzIGVzZW5jaWFsIGluaWNpYXIgbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGxhcyBjb21wb25lbnRlcyBhIHBhcnRpciBkZSBlc2FzIGNvcnJlbGFjaW9uZXMuIFBvc3Rlcmlvcm1lbnRlLCBzZSBkZWJlIGV2YWx1YXIgbGEgY2FsaWRhZCBkZSBsYXMgcmVwcmVzZW50YWNpb25lcyBvYnRlbmlkYXMsIGNvbnNpZGVyYW5kbyBsYSByZWR1Y2Npw7NuIGRpbWVuc2lvbmFsIGFwbGljYWRhIGFsIGNvbmp1bnRvIGRlIGRhdG9zIHkgc3UgaW1wYWN0byBlbiBsYXMgdmFyaWFibGVzLg0KDQpFcyBuZWNlc2FyaW8gZXZhbHVhciBsYSBjYWxpZGFkIGRlIGxhIHJlcHJlc2VudGFjacOzbiBkZSBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZW4gcmVsYWNpw7NuIGNvbiBlbCBuw7ptZXJvIGRlIGRpbWVuc2lvbmVzIGNhbGN1bGFkYXMgcXVlIGNhcHR1cmFuIGxhIG1heW9yIHByb3BvcmNpw7NuIGRlIHZhcmlhYmlsaWRhZDsgcGFyYSBtw6FzIGRldGFsbGVzLCBjb25zdWx0YXIgbGEgW3NlY2Npw7NuIDIuM10oI3NlYzIuMykuDQoNCiMjIyAyLjUgIERlc2Fycm9sbG8gZGVsIEFuw6FsaXNpcy4gey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KRXhwbG9yYXIgbGFzIHBlc3Rhw7FhcyByZXZlbGEgcXVlIHJlZHVjaXIgbGEgZGltZW5zaW9uYWxpZGFkIGRlbCBjb25qdW50byBkZSBkYXRvcyBwZXJtaXRlIGFuYWxpemFyIGxhIGNhbGlkYWQgZGUgbGEgcmVwcmVzZW50YWNpw7NuLCB1c2FuZG8gdW5hIGVzY2FsYSBkZSBjb250cmlidWNpb25lcyByZWxhdGl2YXMuIEVzdGEgZXNjYWxhIHNlIGJhc2EgZW4gdW4gY29jaWVudGUgZGUgcHJveWVjY2lvbmVzIGNvbiBwcm9waWVkYWRlcyBhZGl0aXZhcyB5IHVuYSBlc2NhbGEgY29udGludWEgcXVlIHZhcsOtYSBkZSAwIGEgMS4gRW4gcGFydGljdWxhcjoNCg0KDQpFbCAqKkPDrXJjdWxvIGRlIENvcnJlbGFjaW9uZXMqKiBleHByZXNhIHF1ZSBzZSBwdWVkZW4gaWRlbnRpZmljYXIgcGF0cm9uZXMgc2lnbmlmaWNhdGl2b3MgZW50cmUgbGFzIHZhcmlhYmxlcyBvcmlnaW5hbGVzLCBlbiBlbCBtYXJjbyBkZSB1bmEgc2VsZWNjacOzbiBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcy4gKipEaW1lbnNpw7NuIDEgKERpbTEpOioqIEV4cGxpY2EgZWwgJDIyLjVcJSQgZGUgbGEgdmFyaWFuemEuIE11ZXN0cmEgdW5hICoqY29ycmVsYWNpw7NuIHBvc2l0aXZhKiogY29uIHZhcmlhYmxlcyBjb21vICoqYEhvcmFzX3BkYCoqIHkgKipgZWRhZF9wYWNpZW50ZWAqKiwgbGFzIGN1YWxlcyBlc3TDoW4gb3JpZW50YWRhcyBoYWNpYSBlc3RlIGVqZSB5IGNlcmNhbmFzIGEgbGEgZnJvbnRlcmEgZGVsIGPDrXJjdWxvIHVuaXRhcmlvLiBFc3RvIGluZGljYSBxdWUgZXN0YXMgdmFyaWFibGVzICoqY29udHJpYnV5ZW4gc2lnbmlmaWNhdGl2YW1lbnRlKiogYSBsYSBjb25zdHJ1Y2Npw7NuIGRlIERpbTEsIHF1ZSBwb2Ryw61hIGVzdGFyIGNhcHR1cmFuZG8gY2FyYWN0ZXLDrXN0aWNhcyBjb211bmVzIGEgZWxsYXMuIA0KDQpQb3Igb3RyYSBwYXJ0ZSwgbGEgKipEaW1lbnNpw7NuIDIgKERpbTIpOioqIEV4cGxpY2EgZWwgJDIwLjVcJSQgZGUgbGEgdmFyaWFuemEuIEVzdMOhIGFzb2NpYWRhIGNvbiB2YXJpYWJsZXMgY29tbyAqKmBIb3Jhc19hZmAqKiwgcXVlIHRpZW5lIHVuYSAqKmFsdGEgY29ycmVsYWNpw7NuIHBvc2l0aXZhKiouIFBvciBlbCBjb250cmFyaW8sIGxhcyB2YXJpYWJsZXMgKipgQWd1ZGV6YV92aXN1YWxfT0RgKiogeSAqKmBBZ3VkZXphX3Zpc3VhbF9PSWAqKiBlc3TDoW4gY29ycmVsYWNpb25hZGFzIG5lZ2F0aXZhbWVudGUgY29uIERpbTIuIEVzdG8gc3VnaWVyZSBxdWUgRGltMiBlc3TDoSByZXByZXNlbnRhbmRvIHVuIGZlbsOzbWVubyBkaWZlcmVudGUgbyBjb21wbGVtZW50YXJpbyBhbCBkZXNjcml0byBwb3IgRGltMS4NCg0KDQoNCk90cm8gYXNwZWN0byBkZXN0YWNhYmxlIGVzIGxhIHJlbGFjacOzbiBtb3N0cmFkYSBlbnRyZSBwYXJlcyBkZSB2YXJpYWJsZXMgZW4gZWwgY8OtcmN1bG86IExhICoqQ29ycmVsYWNpw7NuIFBvc2l0aXZhIEZ1ZXJ0ZSoqIGVudHJlKipgSG9yYXNfcGRgKiogeSAqKmBlZGFkX3BhY2llbnRlYCoqIHByZXNlbnRhbiB2ZWN0b3JlcyBjZXJjYW5vcywgaW5kaWNhbmRvIHVuYSAqKnJlbGFjacOzbiBwb3NpdGl2YSoqLiBBZGVtYXMsICBkZSB0ZW5lciB1bmEgKioqQ29ycmVsYWNpw7NuIE5lZ2F0aXZhIEZ1ZXJ0ZSoqIGVudHJlICoqYEhvcmFzX3BkYCoqIHkgKipgZWRhZF9wYWNpZW50ZWAqKiBlc3TDoW4gZW4gb3Bvc2ljacOzbiBkaXJlY3RhIGEgKipgQWd1ZGV6YV92aXN1YWxfT0lgKiosIGxvIHF1ZSBpbXBsaWNhIHVuYSBmdWVydGUgY29ycmVsYWNpw7NuIG5lZ2F0aXZhLlkgdW5hICoqUG9jYSBDb3JyZWxhY2nDs24gZGUgT3J0b2dvbmFsaWRhZDoqKiBlbiB2YXJpYWJsZXMgY29tbyAqKmBIb3Jhc19hZmAqKiB5ICoqYEFndWRlemFfdmlzdWFsX09JYCoqIG11ZXN0cmFuIHZlY3RvcmVzIGNhc2kgcGVycGVuZGljdWxhcmVzLCBzdWdpcmllbmRvIHVuYSBiYWphIHJlbGFjacOzbiBlbiBlc3RlIGNvbnRleHRvIGJpZGltZW5zaW9uYWwuDQoNCkVzdGEgaW50ZXJwcmV0YWNpw7NuIHNlIGxpbWl0YSBhIGxhIGVzdHJ1Y3R1cmEgZGUgY29ycmVsYWNpb25lcyByZXByZXNlbnRhZGEgZW4gZWwgZ3LDoWZpY28geSBkZXNjcmliZSBjw7NtbyBsYXMgdmFyaWFibGVzIG9yaWdpbmFsZXMgY29udHJpYnV5ZW4gYSBsYXMgZGltZW5zaW9uZXMgcHJpbmNpcGFsZXMgc2VsZWNjaW9uYWRhcywgKipzaW4gaW1wbGljYXIgcmVsYWNpb25lcyBjYXVzYWxlcyBvIGRlIGRlcGVuZGVuY2lhIGRpcmVjdGEgZW50cmUgZWxsYXMuKioNCg0KDQpMYSAqKk1hdHJpeiBkZSBSZXByZXNlbnRhY2nDs24qKiAoJFxjb3NeMiQpIG11ZXN0cmEgbGEgY2FsaWRhZCBjb24gbGEgcXVlIGNhZGEgdmFyaWFibGUgZXMgcmVwcmVzZW50YWRhIHBvciBsYXMgZGltZW5zaW9uZXMgcHJpbmNpcGFsZXMuIEVzdGUgYW7DoWxpc2lzIHNlIGJhc2EgZW4gbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGxhIGNvcnJlbGFjacOzbiBlbnRyZSB2YXJpYWJsZXMgKEPDrXJjdWxvIGRlIENvcnJlbGFjaW9uZXMpLCBsYSBjYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbiAoJFxjb3NeMiQpLCB5IGxhIHBvc2ljacOzbiBkZSBsb3MgaW5kaXZpZHVvcyAoQ29vcmRlbmFkYXMgSW5kaXZpZHVhbGVzKSBlbiBlbCBlc3BhY2lvIGZhY3RvcmlhbDoNCg0KKipBc29jaWFjacOzbiBGdWVydGUgY29uIERpbWVuc2nDs24gMSAoRGltMSk6KiogTGFzIHZhcmlhYmxlcyAqKmBIb3Jhc19wZGAqKiAoJFxjb3NeMiA9IDAuMzM5JCkgeSAqKmBBZ3VkZXphX3Zpc3VhbF9PSWAqKiAoJFxjb3NeMiA9IDAuMzAzJCkgdGllbmVuIGxvcyB2YWxvcmVzIGRlIGNvc2VubyBjdWFkcmFkbyBtw6FzIGFsdG9zIGVuIHJlbGFjacOzbiBjb24gbGEgKipEaW1lbnNpw7NuIDEqKi4gRXN0byBpbmRpY2EgcXVlIGVzdMOhbiBmdWVydGVtZW50ZSBhc29jaWFkYXMgY29uIGVzdGUgY29tcG9uZW50ZSB5IGFwb3J0YW4gc2lnbmlmaWNhdGl2YW1lbnRlIGEgw6lsLg0KDQoqKlZhcmlhbnphIERpc3RyaWJ1aWRhIGVuIERpbWVuc2lvbmVzIFBvc3RlcmlvcmVzOioqIEVuIGNvbnRyYXN0ZSwgbGEgdmFyaWFibGUgKipgZWRhZF9wYWNpZW50ZWAqKiB0aWVuZSB1biB2YWxvciBiYWpvIGRlIGNvc2VubyBjdWFkcmFkbyBlbiBsYSAqKkRpbWVuc2nDs24gMSoqICgwLjIzNCkgeSBsYSAqKkRpbWVuc2nDs24gMioqICgwLjAwNykuIEVzdG8gc3VnaWVyZSBxdWUgc3UgdmFyaWFuemEgc2UgZGlzdHJpYnV5ZSBtw6FzIGhhY2lhIG90cmFzIGRpbWVuc2lvbmVzLCBlc3BlY2lhbG1lbnRlIGxhICoqRGltZW5zacOzbiAzKiosIGRvbmRlIG11ZXN0cmEgdW5hIG1lam9yIHJlcHJlc2VudGFjacOzbiAoMC40NzIpLiBFc3RvIGFmZWN0YSBsYSBjYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbiBkZSAqKmBlZGFkX3BhY2llbnRlYCoqIGVuIGVsIHBsYW5vIHByaW5jaXBhbCAoRGltMS9EaW0yKS4NCg0KDQpFbCBncsOhZmljbyBkZSBsYSAqKkNhbGlkYWQgZGUgUmVwcmVzZW50YWNpw7NuKiogKGNvZGlmaWNhZG8gcG9yIGNvbG9yKSBjb25maXJtYSB2aXN1YWxtZW50ZSBsYSBjb250cmlidWNpw7NuIGFsIHBsYW5vIERpbTEvRGltMi4gTG9zIGVsZW1lbnRvcyBtZWpvciByZXByZXNlbnRhZG9zIHBvciBsYXMgY29tcG9uZW50ZXMgMSB5IDIgaW5jbHV5ZW4gKipgSG9yYXNfYWZgKiogKGVsIHZlY3RvciBtw6FzIHJvam8pIHkgKipgQWd1ZGV6YV92aXN1YWxfT0RgKiogKG5hcmFuamEpLCBsbyBjdWFsIGluZGljYSBxdWUgbGEgbWF5b3IgcGFydGUgZGUgc3UgdmFyaWFuemEgZXMgZXhwbGljYWRhIHBvciBlc3RlIHBsYW5vIGJpZGltZW5zaW9uYWwuIFBvciBvdHJhIHBhcnRlLCBsYSB2YXJpYWJsZSAqKmBlZGFkX3BhY2llbnRlYCoqIHNlIG11ZXN0cmEgZW4gdW4gY29sb3IgbcOhcyBjbGFybyAoYW1hcmlsbG8pLCBjb25maXJtYW5kbyBzdSAqKmJhamEgcmVwcmVzZW50YWNpw7NuKiogZW4gZXN0ZSBwbGFubyBiaWRpbWVuc2lvbmFsLCBsbyBjdWFsIGVzIGNvaGVyZW50ZSBjb24gc3UgZnVlcnRlICRcY29zXjIkIGVuIGxhIERpbWVuc2nDs24gMy4NCg0KKiAqKlJvbGVzIERpbWVuc2lvbmFsZXM6KiogTGEgKipEaW1lbnNpw7NuIDIqKiB0aWVuZSB1bmEgZXhjZWxlbnRlIHJlcHJlc2VudGFjacOzbiBkZSAqKmBIb3Jhc19hZmAqKiAodmVjdG9yIGFsaW5lYWRvIHZlcnRpY2FsbWVudGUpLCBsbyBxdWUgaW1wbGljYSBxdWUsIGF1bnF1ZSBsYSBjb21wb25lbnRlIDEgZXMgbGEgcHJpbmNpcGFsIHBhcmEgYEhvcmFzX3BkYCwgbGEgY29tcG9uZW50ZSAyIHRhbWJpw6luIGp1ZWdhIHVuIHBhcGVsIHJlbGV2YW50ZSBlbiBsYSByZXByZXNlbnRhY2nDs24gZGUgY2llcnRvcyBhc3BlY3Rvcy4NCg0KTGFzICoqQ29vcmRlbmFkYXMgSW5kaXZpZHVhbGVzKiogcGVybWl0ZW4gaWRlbnRpZmljYXIgbG9zIHBlcmZpbGVzIGRlIGxvcyByZWdpc3Ryb3MgKHBhY2llbnRlcykgZW4gcmVsYWNpw7NuIGNvbiBsYXMgZGltZW5zaW9uZXMgcHJpbmNpcGFsZXMsIGxvIGN1YWwgZXMgY2xhdmUgcGFyYSBsYSBzZWdtZW50YWNpw7NuOg0KDQoqICoqRXh0cmVtb3MgZW4gRGltZW5zacOzbiAxIChDb3JyZWxhY2lvbmFkbyBjb24gSG9yYXMvRWRhZCk6KiogTG9zIHJlZ2lzdHJvcyAqKlwjIDYqKiAoMi40ODUpIHkgKipcIyAyKiogKDEuODY2KSB0aWVuZW4gbG9zIHZhbG9yZXMgcG9zaXRpdm9zIG3DoXMgZXh0cmVtb3MgZW4gRGltMS4gRXN0b3MgcGFjaWVudGVzIHJlcHJlc2VudGFuIHBlcmZpbGVzIGNvbiBhbHRvcyB2YWxvcmVzIGVuIGxhcyB2YXJpYWJsZXMgcG9zaXRpdmFtZW50ZSBjb3JyZWxhY2lvbmFkYXMgY29uIERpbTEsIGNvbW8gYEhvcmFzX3BkYCB5IGBlZGFkX3BhY2llbnRlYC4NCg0KKiAqKkV4dHJlbW9zIGVuIERpbWVuc2nDs24gMiAoQ29ycmVsYWNpb25hZG8gY29uIEhvcmFzX2FmKToqKiBFbiBsYSAqKmRpbWVuc2nDs24gMioqLCBsb3MgcmVnaXN0cm9zICoqXCMgNCoqICgxLjYyMikgeSAqKlwjIDE3KiogKDEuMDQ4KSBkZXN0YWNhbiBwb3Igc3VzIHZhbG9yZXMgcG9zaXRpdm9zLiBFc3RvcyBwYWNpZW50ZXMgbXVlc3RyYW4gdW4gY29tcG9ydGFtaWVudG8gc2ltaWxhciBlbiBsYSB2YXJpYWJsZSBgSG9yYXNfYWZgIChjb3JyZWxhY2lvbmFkYSBwb3NpdGl2YW1lbnRlIGNvbiBEaW0yKS4NCg0KKiAqKlBlcmZpbGVzIFByb21lZGlvIG8gTWFsIFJlcHJlc2VudGFkb3M6KiogTG9zIHJlZ2lzdHJvcyBjb24gdmFsb3JlcyBtdXkgY2VyY2Fub3MgYWwgb3JpZ2VuIChwb3IgZWplbXBsbywgKipcIyAxNCoqIGNvbiAwLjAzNCBlbiBEaW0xKSBzb24gcGVyZmlsZXMgcHJvbWVkaW8gbyBzdSB2YXJpYW56YSBlcyBleHBsaWNhZGEgcG9yIGRpbWVuc2lvbmVzIHBvc3RlcmlvcmVzLg0KDQoNCiMjIyMgQ8OtcmN1bG8gZGUgQ29ycmVsYWNpb25lcw0KYGBge3IgQ2lyY3Vsb19kZV9Db3JyZWxhY2lvbmVzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmZ2aXpfcGNhX3ZhcihQQ0EoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBzY2FsZS51bml0ID0gVCwgZ3JhcGggPSBGKSxjb2wudmFyPSIjM0I4M0JEIiwgcmVwZWwgPSBULCBjb2wuY2lyY2xlID0gIiNDRENEQ0QiLCBnZ3RoZW1lID0gdGhlbWVfYncoKSkNCmBgYA0KDQojIyMjIE1hdHJpeiBkZSBSZXByZXNlbnRhY2nDs24NCmBgYHtyIE1hdHJpel9kZV9SZXByZXNzZW50YWNpb25fQ09TMiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQooZ2V0X3BjYV92YXIoUENBKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSwgbmNwID0gNSwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRikpKSRjb3MyDQpgYGANCg0KIyMjIyBDYWxpZGFkIGRlIFJlcHJlc2VudGFjacOzbg0KYGBge3IgQ2FsaWRhZF9kZV9sYV9SZXByZXNlbnRhY2lvbiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X3BjYV92YXIoUENBKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSwgbmNwID0gNSwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNvbC52YXI9ImNvczIiLCBncmFkaWVudC5jb2xzPWMoIiMwMEFGQkIiLCIjRTdCODAwIiwiI0ZDNEUwNyIpLCByZXBlbCA9IFRSVUUpDQpgYGANCg0KIyMjIyBDb29yZGVuYWRhcyBJbmRpdmlkdWFsZXMNCmBgYHtyIENvb3JkZW5hZGFzX1JlZ2lzdHJvcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpoZWFkKChQQ0EoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBuY3AgPSA1LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSkkaW5kJGNvb3JkLCBuID0gMjNMKQ0KYGBgDQoNCiMjIyAyLjYuIENvbnRyaWJ1Y2lvbmVzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkxvcyBhdXRvcmVzICBzZcOxYWxhbiBxdWUgbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGxvcyByZXN1bHRhZG9zIGVzdMOhIGVzdHJlY2hhbWVudGUgbGlnYWRhIGFsIGPDoWxjdWxvIGRlIGVsZW1lbnRvcyBjb21vIGNvb3JkZW5hZGFzLCBjb250cmlidWNpb25lcyB5IGNvc2Vub3MgY3VhZHJhZG9zLiBQb3IgbG8gdGFudG8sIGVzIGVzZW5jaWFsIHF1ZSBsYXMgdmFyaWFibGVzIGVzdMOpbiBiaWVuIGNvbmNlcHR1YWxpemFkYXMgeSBjb250ZXh0dWFsaXphZGFzIHBhcmEgZmFjaWxpdGFyIHN1IGNvbXByZW5zacOzbi4gRW4gZXN0ZSBzZW50aWRvLCBhbmFsaXphciBsYSBjb250cmlidWNpw7NuIGRlIGNhZGEgdmFyaWFibGUgYSB1bmEgY29tcG9uZW50ZSBheXVkYSBhIGludGVycHJldGFyIGxvcyByZXN1bHRhZG9zLCBtb3N0cmFuZG8gY8OzbW8gY2FkYSB1bmEgaW5mbHV5ZSBlbiBsYSBkZWZpbmljacOzbiBkZSBsYXMgY29tcG9uZW50ZXMgZ2VuZXJhZGFzLiBFc3RlIGFuw6FsaXNpcyBzZSBsbGV2YSBhIGNhYm8gZW4gZXN0YSBzZWNjacOzbiBwYXJhIGRldGVybWluYXIgZWwgYXBvcnRlIGRlIGNhZGEgdmFyaWFibGUgZW4gbGEgY29uc3RydWNjacOzbiBkZSBsYXMgY29tcG9uZW50ZXMuDQoNCiMjIyAyLjcuIFBsYW50ZWFtaWVudG8geSBEZXNhcnJvbGxvIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkJhc2FkbyBlbiBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIFtzZWNjacOzbiAxLjJdKCNzZWMxLjIpLCBzZSByZXF1aWVyZSBkZXRlcm1pbmFyIGxhcyBjb250cmlidWNpb25lcyBkZSBjYWRhIHZhcmlhYmxlIGVuIGxhIGNvbnN0cnVjY2nDs24gZGUgbGFzIGNvbXBvbmVudGVzLg0KDQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBmYWNpbGl0YSBsYSB2aXN1YWxpemFjacOzbiBkZSBsYXMgY29udHJpYnVjaW9uZXMgZGUgbGFzIHZhcmlhYmxlcyBkZWwgY29uanVudG8gZGUgZGF0b3MgZW4gZm9ybWEgZGUgcmVwcmVzZW50YWNpb25lcyBudW3DqXJpY2FzIHkgZ3LDoWZpY2FzLCBwZXJtaXRpZW5kbyBjb21wcmVuZGVyIGPDs21vIGNhZGEgdmFyaWFibGUgaW5mbHV5ZSBlbiBsYSBjb25zdHJ1Y2Npw7NuIGRlIGxhcyBjb21wb25lbnRlcy4gRXN0byBwZXJtaXRlIGFuYWxpemFyIGxhIHByb3BvcmNpw7NuIGRlIHZhcmlhYmlsaWRhZCBxdWUgY2FkYSB2YXJpYWJsZSBhcG9ydGEgYSBsYSB2YXJpYWJpbGlkYWQgdG90YWwgZGUgbGEgY29tcG9uZW50ZSBjb24gbGEgcXVlIGVzdMOhIGFzb2NpYWRhLg0KDQpMYSAqKk1hdHJpeiBkZSBDb250cmlidWNpb25lcyoqIG11ZXN0cmEgY8OzbW8gY2FkYSB2YXJpYWJsZSBjb250cmlidXllIGEgbGEgcmV0ZW5jacOzbiBkZSB2YXJpYWJpbGlkYWQgZW4gbGEgY29uc3RydWNjacOzbiBkZSBjYWRhIGNvbXBvbmVudGUuIExvcyBkaWFncmFtYXMgZGUgYmFycmFzLCBxdWUgc2UgdmlzdWFsaXphbiBlbiBsYXMgcGVzdGHDsWFzIGRlc2RlICoqQ29udHJpYnVjaW9uZXMgYSBEMSoqIGhhc3RhICoqQ29udHJpYnVjaW9uZXMgYSBENSoqLCBpbHVzdHJhbiBsYXMgY29udHJpYnVjaW9uZXMgZXNwZWPDrWZpY2FzIGRlIGxhcyB2YXJpYWJsZXMgcGFyYSBleHBsaWNhciBsYSB2YXJpYWJpbGlkYWQgZW4gY2FkYSBjb21wb25lbnRlLiBDYWRhIGdyw6FmaWNvIGluY2x1eWUgdW5hIGzDrW5lYSBxdWUgaW5kaWNhIGxhICpjb250cmlidWNpw7NuIG1lZGlhKiwgbG8gcXVlIGZhY2lsaXRhIGxhIGlkZW50aWZpY2FjacOzbiBkZSBsYXMgdmFyaWFibGVzIHF1ZSB0aWVuZW4gbWF5b3IgaW1wYWN0byBlbiBsYSBleHBsaWNhY2nDs24gZGUgbGEgdmFyaWFiaWxpZGFkIGRlIGxvcyBjb21wb25lbnRlcy4NCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQxKiogc2UgdmlzdWFsaXphIHF1ZSBsYXMgdmFyaWFibGVzIHBvciBlbmNpbWEgZGUgbGEgY29udHJpYnVjacOzbiBtZWRpYTogKipBZ3VkZXphX3Zpc3VhbF9PSSoqIHkgKipIb3Jhc19wZCoqLHJldGllbmVuIGFwcm94aW1hZGFtZW50ZSBlbCAkNTcuMDclJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgMS4NCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQyKiogc2UgdmlzdWFsaXphIHF1ZSBsYXMgdmFyaWFibGVzIHBvciBlbmNpbWEgZGUgbGEgY29udHJpYnVjacOzbiBtZWRpYTogKipIb3Jhc19hZioqIHkgKipBZ3VkZXphX3Zpc3VhbF9PRCoqIHJldGllbmVuIGFwcm94aW1hZGFtZW50ZSBlbCAkODIuMjIlJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgMi4NCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQzKiogc2UgdmlzdWFsaXphIHF1ZSBsYXMgdmFyaWFibGVzIHBvciBlbmNpbWEgZGUgbGEgY29udHJpYnVjacOzbiBtZWRpYTogKipFZGFkX3BhY2llbnRlKiogeSAqKkFndWRlemFfdmlzdWFsX09JKiogcmV0aWVuZW4gYXByb3hpbWFkYW1lbnRlIGVsICQ2Ny41NiUkIGRlIGxhIHZhcmlhYmlsaWRhZCBkZWwgY29tcG9uZW50ZSAzLiANCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQ0Kiogc2UgdmlzdWFsaXphIHF1ZSBsYSB2YXJpYWJsZSBwb3IgZW5jaW1hIGRlIGxhIGNvbnRyaWJ1Y2nDs24gbWVkaWE6ICoqQWd1ZGV6YV92aXN1YWxfT0QqKiByZXRpZW5lIGFwcm94aW1hZGFtZW50ZSBlbCAkMjkuNTklJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgNC4NCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQ1Kiogc2UgdmlzdWFsaXphIHF1ZSBsYXMgdmFyaWFibGVzIHBvciBlbmNpbWEgZGUgbGEgY29udHJpYnVjacOzbiBtZWRpYTogKipIb3Jhc19wZCoqIHkgKipBZ3VkZXphX3Zpc3VhbF9PSSoqIHJldGllbmVuIGFwcm94aW1hZGFtZW50ZSBlbCAkNjAuOTclJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgNS4gDQoNCkNvbiBsb3MgZGF0b3MgcHJvY2VzYWRvcyBoYXN0YSBhaG9yYSBzZSBwdWVkZSBwcm9jZWRlciBjb24gbGEgaW50ZXByZXRhY2nDs24gZGUgbG9zIGNvbXBvbmVudGVzLg0KDQoNCiMjIyMgTWF0cml6IGRlIENvbnRyaWJ1Y2lvbmVzDQpgYGB7ciBNYXRyaXpfZGVfQ29udHJpYnVjaW9uZXMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KKGdldF9wY2FfdmFyKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDUsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpKSkkY29udHJpYg0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBEMQ0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzEsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDEsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBEMg0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzIsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDIsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBEMw0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDMsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBENA0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzQsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDQsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBENQ0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzUsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDUsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyAyLjguIEludGVycHJldGFjacOzbiB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpSZXByZXNlbnRhciBsb3MgcmVnaXN0cm9zIGVuIHVuIGVzcGFjaW8gZGUgZGltZW5zaW9uZXMgcmVkdWNpZGFzIHBlcm1pdGUgc2l0dWFybG9zIGVuIHVuIHBsYW5vIGRlIGZhY3RvcmVzLCBsbyBxdWUgZmFjaWxpdGEgc3UgYW7DoWxpc2lzIGUgaW50ZXJwcmV0YWNpw7NuLiBMYXMgdmFyaWFibGVzIHJlZHVjaWRhcyBzZSBjb3JyZXNwb25kZW4gY29uIGxhcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcywgcXVlIHNlIHV0aWxpemFuIGNvbW8gZWplcyBlbiBlbCBwbGFubyB5IGN1eW9zIHZhbG9yZXMgc29uIGxvcyBwdW50YWplcyBkZSBsYXMgY29tcG9uZW50ZXMuIExhIGRpc3RhbmNpYSBlbnRyZSBsb3MgcHVudG9zIHJlcHJlc2VudGFkb3MgcG9yIGVzdG9zIHB1bnRhamVzIGVzIGNsYXZlIHBhcmEgaWRlbnRpZmljYXIgc2ltaWxpdHVkZXMgZW50cmUgbG9zIHBlcmZpbGVzIGRlIGxhcyBvYnNlcnZhY2lvbmVzLiBObyBvYnN0YW50ZSwgbGFzIHNpbWlsaXR1ZGVzIHB1ZWRlbiBhcGFyZWNlciBzb2xvIGVuIGFsZ3VuYXMgdmFyaWFibGVzIHkgbm8gZW4gdG9kYXMuIEFzw60sIHNlIGJ1c2NhIHF1ZSBsYXMgZGlzdGFuY2lhcyBlbiBlbCBlc3BhY2lvIGRlIGFsdGEgZGltZW5zacOzbiBzZSBjb25zZXJ2ZW4gZW4gZWwgZXNwYWNpbyByZWR1Y2lkbywgbWFudGVuaWVuZG8gbGEgZXN0cnVjdHVyYSBkZSBsYXMgcmVsYWNpb25lcyBlbnRyZSBsb3MgZGF0b3MuIFNlZ8O6biBdLg0KDQojIyMgMi45LiBQbGFudGVhbWllbnRvIHkgRGVzYXJyb2xsbyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpMYSBuYXZlZ2FjacOzbiBlbnRyZSBsYXMgcGVzdGHDsWFzIGZhY2lsaXRhIGxhIHZpc3VhbGl6YWNpw7NuIGRlIG9iamV0b3MgZ3LDoWZpY29zIHkgbWF0cmljaWFsZXMgcXVlLCBhbCBpbnRlZ3JhciBsb3MgcmVzdWx0YWRvcyBkZSBsYXMgc2VjY2lvbmVzIGFudGVyaW9yZXMsIGZvcnRhbGVjZW4gbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGxhcyBjb250cmlidWNpb25lcyBkZSBsYXMgY29tcG9uZW50ZXMgY2FsY3VsYWRhcy4gVGFsIGNvbW8gc2UgcHJlc2VudMOzIGVuIGxhIFtzZWNjacOzbiAyLjNdKCNzZWMyLjMpLCBlbCBuw7ptZXJvIGRlIGNvbXBvbmVudGVzIHNlbGVjY2lvbmFkYXMgc2UgcmVkdWpvIGEgKipkb3MqKiwgc2lndWllbmRvIGVsIGNyaXRlcmlvIGRlIEthaXNlciB5IGNvbnNpZGVyYW5kbyBsYSB2YXJpYW56YSBhY3VtdWxhZGEuIEVzdGFzIGRvcyBjb21wb25lbnRlcyBleHBsaWNhbiBjb25qdW50YW1lbnRlIGVsICQ0My4wMSQkJSQgZGUgbGEgdmFyaWFiaWxpZGFkIGRlIGxvcyBkYXRvcywgbG8gcXVlIHBlcm1pdGUgY2FwdHVyYXIgcGF0cm9uZXMgcmVsZXZhbnRlcyBzaW4gcGVyZGVyIHNpbXBsaWNpZGFkLiBFbiBlc3RhIHNlY2Npw7NuLCBzZSBhbmFsaXphbiBsYXMgY29udHJpYnVjaW9uZXMgZXNwZWPDrWZpY2FzIGRlIGNhZGEgdmFyaWFibGUgYSBlc3RhcyBjb21wb25lbnRlcywgZGVzdGFjYW5kbyBzdSBpbXBvcnRhbmNpYSBlbiBsYSBpbnRlcnByZXRhY2nDs24gZGUgbG9zIGZhY3RvcmVzIGNsYXZlIHJlbGFjaW9uYWRvcyBjb24gbGFzIGFmZWNjaW9uZXMgY2FyZGlvdmFzY3VsYXJlcy4NCg0KTGFzIHBlc3Rhw7FhcyBkZSAqKkJpcGxvdCBkZSBWYXJpYWJsZXMgeSBSZWdpc3Ryb3MgVG90YWxlcyoqIGVuIGxhcyBjYXRlZ29yw61hcyAqKlBhY19zZXhvKiogKHNleG8gZGVsIHBhY2llbnRlKSwgKipSYW5nb19FdGFyZW8qKiAoZ3J1cG8gZXRhcmVvIGRlbCBwYWNpZW50ZSkgeSAqKkhvYmJ5X3BwYW50YWxsYXkqKiAoaG9iYnkgcXVlIGltcGxpcXVlIHVzbyBkZSBwYW50YWxsYXMpIG11ZXN0cmFuLCBjb24gYmFzZSBlbiBsYXMgYWdydXBhY2lvbmVzIHF1ZSBlc3RhcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIHB1ZWRlbiBlc3RhYmxlY2VyLCBsYSByZXByZXNlbnRhY2nDs24gZW4gZGltZW5zaW9uYWxpZGFkIHJlZHVjaWRhIGVuIGVsIHBsYW5vIGRlIGZhY3RvcmVzIGdlbmVyYWRvIHBvciBsb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuIA0KDQpFbiBlc3RlIHNlbnRpZG86DQoNCi0gTGEgYWdydXBhY2nDs24gY29uIGJhc2UgZW4gZWwgcmFuZ28gZXRhcmlvICoqKFByaW1lcmEgaW5mYW5jaWEsIE5pw7FleiwgSsOzdmVuZXMsIEFkdWx0byB5IEFkdWx0byBtYXlvcikqKiBwZXJtaXRlIG9ic2VydmFyIGPDs21vIGxhcyBkaXN0aW50YXMgZXRhcGFzIGRlbCBjaWNsbyBkZSB2aWRhIGdlbmVyYW4gdW5hIGRpc3RyaWJ1Y2nDs24gZGlmZXJlbmNpYWRhIGVuIGVsIGVzcGFjaW8gZGUgbG9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLCBlc3BlY2lhbG1lbnRlIGVuIGxhcyBkaW1lbnNpb25lcyAqKkRpbS4xKiogeSAqKkRpbS4yKiouIEVuIHBhcnRpY3VsYXIsIGxvcyBncnVwb3MgY29ycmVzcG9uZGllbnRlcyBhICoqYWR1bHRvcyBtYXlvcmVzIHRpZW5kZW4gYSBwcm95ZWN0YXJzZSBoYWNpYSB2YWxvcmVzIHBvc2l0aXZvcyBkZSBEaW0uMSoqLCBtb3N0cmFuZG8gdW5hIG1heW9yIGFzb2NpYWNpw7NuIGNvbiBsYSB2YXJpYWJsZSBlZGFkIGRlbCBwYWNpZW50ZSB5IGNvbiB2YXJpYWNpb25lcyBlbiBsYSAqKmFndWRlemEgdmlzdWFsIChBVl9PRCB5IEFWX09JKSoqLiBQb3Igc3UgcGFydGUsIGxvcyBncnVwb3MgZGUgKipwcmltZXJhIGluZmFuY2lhIHkgbmnDsWV6IHNlIGNvbmNlbnRyYW4gZW4gcmVnaW9uZXMgb3B1ZXN0YXMgZGVsIGVzcGFjaW8qKiwgbG8gcXVlIHN1Z2llcmUgcGF0cm9uZXMgdmlzdWFsZXMgeSBjb21wb3J0YW1lbnRhbGVzIGRpc3RpbnRvcyBmcmVudGUgYSBsYXMgdmFyaWFibGVzIGFuYWxpemFkYXMuDQoNCi1MYSBhZ3J1cGFjacOzbiBjb24gYmFzZSBlbiBlbCAqKnVzbyBkZSBwYW50YWxsYXMgY29tbyBob2JieSoqIChzw60gLyBubykgbXVlc3RyYSB1bmEgc2VwYXJhY2nDs24gbWVub3MgbWFyY2FkYSBlbnRyZSBsYXMgb2JzZXJ2YWNpb25lcyBlbiBlbCBlc3BhY2lvIGRlIGxvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcy4gTm8gb2JzdGFudGUsIHNlIG9ic2VydmEgcXVlIGxvcyBpbmRpdmlkdW9zIHF1ZSByZXBvcnRhbiB1c28gZGUgcGFudGFsbGFzIHByZXNlbnRhbiB1bmEgbWF5b3IgZGlzcGVyc2nDs24sIGVzcGVjaWFsbWVudGUgZW4gbGEgZGlyZWNjacOzbiBhc29jaWFkYSBhIGxhIHZhcmlhYmxlICoqSG9yYXNfcGQqKiwgbG8gcXVlIGluZGljYSBxdWUgZXN0ZSBow6FiaXRvIGludHJvZHVjZSB2YXJpYWJpbGlkYWQgYWRpY2lvbmFsIGVuIGxvcyBkYXRvcy4gRW4gY29udHJhc3RlLCBxdWllbmVzIG5vIHV0aWxpemFuIHBhbnRhbGxhcyB0aWVuZGVuIGEgY29uY2VudHJhcnNlIG3DoXMgY2VyY2EgZGVsIG9yaWdlbiwgbG8gcXVlIHN1Z2llcmUgdW5hIGluZmx1ZW5jaWEgbW9kZXJhZGEgZGUgZXN0YSB2YXJpYWJsZSBjYXRlZ8OzcmljYSBzb2JyZSBsYSBlc3RydWN0dXJhIGdsb2JhbCBkZWwgY29uanVudG8gZGUgZGF0b3MuDQoNCi1EZSBtYW5lcmEgY29tcGxlbWVudGFyaWEsIGVsIGFuw6FsaXNpcyBkZSBsb3MgdmVjdG9yZXMgZGVsIGJpcGxvdCBldmlkZW5jaWEgcXVlIGxhcyB2YXJpYWJsZXMgKipBVl9PRCoqIHkgKipBVl9PSSoqIHByZXNlbnRhbiB1bmEgYWx0YSBjb3JyZWxhY2nDs24gcG9zaXRpdmEsIHlhIHF1ZSBzZSBvcmllbnRhbiBlbiBkaXJlY2Npb25lcyBzaW1pbGFyZXMgZGVudHJvIGRlbCBlc3BhY2lvIGZhY3RvcmlhbC4gQXNpbWlzbW8sIGxhcyB2YXJpYWJsZXMgSG9yYXNfcGQgeSBIb3Jhc19hZiBtdWVzdHJhbiBvcmllbnRhY2lvbmVzIG9wdWVzdGFzLCBsbyBxdWUgaW5kaWNhIHVuYSByZWxhY2nDs24gaW52ZXJzYSBlbnRyZSBsb3MgZGlzdGludG9zIHRpcG9zIGRlIGFjdGl2aWRhZGVzIHZpc3VhbGVzLiBMYSB2YXJpYWJsZSBlZGFkIGRlbCBwYWNpZW50ZSBzZSBhc29jaWEgcHJpbmNpcGFsbWVudGUgY29uIGxhICoqRGltLjIqKiwgc3VnaXJpZW5kbyBxdWUgbGEgZWRhZCBleHBsaWNhIHVuYSBwYXJ0ZSBlc3BlY8OtZmljYSBkZSBsYSB2YXJpYWJpbGlkYWQgcXVlIG5vIGVzdMOhIGRpcmVjdGFtZW50ZSB2aW5jdWxhZGEgY29uIGxhIGFndWRlemEgdmlzdWFsLg0KDQpEZSBlc3RhIG1hbmVyYSwgbGEgcmVwcmVzZW50YWNpw7NuIGJpcGxvdCByZXNhbHRhIGxhIGNhcGFjaWRhZCBkZSB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIGNvbW8gZWwgcmFuZ28gZXRhcmlvIHBhcmEgZXN0YWJsZWNlciBhZ3J1cGFjaW9uZXMgc2lnbmlmaWNhdGl2YXMgZGVudHJvIGRlbCBlc3BhY2lvIGRlIGxvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcywgZXZpZGVuY2lhbmRvIHN1IGluZmx1ZW5jaWEgZW4gbG9zIHBhdHJvbmVzIGRlIGFndWRlemEgdmlzdWFsIHkgaMOhYml0b3MgYXNvY2lhZG9zLiBFbiBjb250cmFzdGUsIHZhcmlhYmxlcyBjb21vIGVsIHVzbyBkZSBwYW50YWxsYXMgY29tbyBob2JieSBtdWVzdHJhbiB1biBpbXBhY3RvIG3DoXMgbGltaXRhZG8sIHlhIHF1ZSBubyBnZW5lcmFuIHVuYSBzZXBhcmFjacOzbiBjbGFyYW1lbnRlIGRlZmluaWRhIGVudHJlIGxvcyBncnVwb3MsIGF1bnF1ZSBzw60gY29udHJpYnV5ZW4gYSB1bmEgbWF5b3IgZGlzcGVyc2nDs24gZGUgbGFzIG9ic2VydmFjaW9uZXMuIEVuIGNvbmp1bnRvLCBlbCBQQ0EgcGVybWl0ZSBpZGVudGlmaWNhciByZWxhY2lvbmVzIGVzdHJ1Y3R1cmFsZXMgcmVsZXZhbnRlcyBlbnRyZSBsYSBlZGFkLCBsYSBhZ3VkZXphIHZpc3VhbCB5IGxhcyBob3JhcyBkZSBhY3RpdmlkYWQgdmlzdWFsLCBwcm9wb3JjaW9uYW5kbyB1bmEgdmlzacOzbiBzaW50w6l0aWNhIHkgcm9idXN0YSBkZSBsYSB2YXJpYWJpbGlkYWQgcHJlc2VudGUgZW4gbG9zIGRhdG9zLg0KDQoNCkZpbmFsbWVudGUsIHBhcmEgZmFjaWxpdGFyIGxhIGludGVycHJldGFjacOzbiBkZSBsb3MgcHVudGFqZXMgZW4gZWwgcGxhbm8gZGVmaW5pZG8gcG9yIGxhcyBwcmltZXJhcyBkb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgKiooRGltLjEgeSBEaW0uMikqKiB5IGxhcyByZWxhY2lvbmVzIGVudHJlIHZhcmlhYmxlcywgc2UgZ2VuZXLDsyBsYSBwZXN0YcOxYSAqKkNvb3JkZW5hZGFzIEluZGl2aWR1YWxlcyoqIFtTdWJjb25qdW50byBDaGVzdFBhaW5dLiBFc3RhIHZpc3VhbGl6YWNpw7NuLCBiYXNhZGEgZW4gdW4gc3ViY29uanVudG8gZGVsICQ1JCAkJSQgWzQ3XSBkZSByZWdpc3Ryb3Mgc2VsZWNjaW9uYWRvcyBtZWRpYW50ZSBtdWVzdHJlbyBhbGVhdG9yaW8gc2ltcGxlLCBwZXJtaXRlIGV4cGxvcmFyIGxvcyBwdW50YWplcyBwb3IgY29tcG9uZW50ZXMuIEVzdGUgZW5mb3F1ZSBvZnJlY2UgdW5hIHJlcHJlc2VudGFjacOzbiBjbGFyYSB5IGNvbXByZW5zaWJsZSwgc2luIGNvbXByb21ldGVyIGxvcyBkZXRhbGxlcyBlc2VuY2lhbGVzLiBFcyBpbXBvcnRhbnRlIHNlw7FhbGFyIHF1ZSBlc3RlIHByb2NlZGltaWVudG8gdGllbmUgZmluZXMgZGUgdmlzdWFsaXphY2nDs24sIHlhIHF1ZSBlbCBjb25qdW50byBkZSBkYXRvcyBvcmlnaW5hbCwgbXVjaG8gbcOhcyBncmFuZGUgKipbOTQ3IHJlZ2lzdHJvc10qKiwgZGlmaWN1bHRhIGxhIGlkZW50aWZpY2FjacOzbiB2aXN1YWwgZGUgcGF0cm9uZXMgcmVsZXZhbnRlcy4NCg0KDQojIyMjIEJpcGxvdCBkZSBWYXJpYWJsZXMgeSBSZWdpc3Ryb3MgW2ZpbHRybzpQYWNfc2V4b10NCmBgYHtyIEJpcGxvdF9WYXJpYWJsZXNfUmVnaXN0cm9zX0ZpbHRyb19QYWNfc2V4b30NCmNjZF92aXNpb24yMDIwX0VUTCA8LSByZWFkX2V4Y2VsKCJDOlxcVXNlcnNcXEpPU0VcXERlc2t0b3BcXGdkZFxcY2NkX3Zpc2lvbjIwMjBfRVRMLnhsc3giKQ0KDQpjY2RfdmlzaW9uMjAyMF9FVExfUmVkdWNpZG8gPC0gY2NkX3Zpc2lvbjIwMjBfRVRMWw0Kc2FtcGxlKDE6bnJvdyhjY2RfdmlzaW9uMjAyMF9FVEwpLCAxMDApLA0KYygiZWRhZF9wYWNpZW50ZSIsIkFWX09EIiwiQVZfT0kiLCJIb3Jhc19wZCIsIkhvcmFzX2FmIiwicGFjX3NleG8iKQ0KXQ0KDQpjY2RfdmlzaW9uMjAyMF9FVExfUmVkdWNpZG8kcGFjX3NleG8gPC0gZmFjdG9yKGNjZF92aXNpb24yMDIwX0VUTF9SZWR1Y2lkbyRwYWNfc2V4byxsZXZlbHMgPSBjKDAsIDEpLA0KbGFiZWxzID0gYygiRmVtZW5pbm8iLCAiTWFzY3VsaW5vIikpDQoNCnJlc19wY2EgPC0gUENBKA0KY2NkX3Zpc2lvbjIwMjBfRVRMX1JlZHVjaWRvWywgYygiZWRhZF9wYWNpZW50ZSIsIkFWX09EIiwiQVZfT0kiLCJIb3Jhc19wZCIsIkhvcmFzX2FmIildLA0KbmNwID0gNSxzY2FsZS51bml0ID0gVFJVRSxncmFwaCA9IEZBTFNFKQ0KDQpmdml6X3BjYV9iaXBsb3QocmVzX3BjYSxheGVzID0gYygxLCAyKSxyZXBlbCA9IFRSVUUsaGFiaWxsYWdlID0gY2NkX3Zpc2lvbjIwMjBfRVRMX1JlZHVjaWRvJHBhY19zZXhvKQ0KYGBgDQoNCiMjIyMgQmlwbG90IGRlIFZhcmlhYmxlcyB5IFJlZ2lzdHJvcyBbZmlsdHJvOlJhbmdvIEV0YXJlb10NCmBgYHtyIEJpcGxvdF9WYXJpYWJsZXNfUmVnaXN0cm9zX0ZpbHRyb19SYW5nb19FdGFyZW99DQpsaWJyYXJ5KEZhY3RvTWluZVIpDQpsaWJyYXJ5KGZhY3RvZXh0cmEpDQpsaWJyYXJ5KHJlYWR4bCkNCg0KY2NkX3Zpc2lvbjIwMjBfRVRMIDwtIHJlYWRfZXhjZWwoIkM6XFxVc2Vyc1xcSk9TRVxcRGVza3RvcFxcZ2RkXFxjY2RfdmlzaW9uMjAyMF9FVEwueGxzeCIpDQoNCnNldC5zZWVkKDc4MDcyOSkNCg0KbXVlc3RyYV9yZSA8LSBjY2RfdmlzaW9uMjAyMF9FVExbDQpzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksIDE1MCksDQpjKCJlZGFkX3BhY2llbnRlIiwiQVZfT0QiLCJBVl9PSSIsIkhvcmFzX3BkIiwiSG9yYXNfYWYiLCJyYW5nb19ldGFyZW8iKQ0KXQ0KDQptdWVzdHJhX3JlJHJhbmdvX2V0YXJlbyA8LSBmYWN0b3IobXVlc3RyYV9yZSRyYW5nb19ldGFyZW8pDQoNCnJlc19wY2FfcmUgPC0gUENBKA0KbXVlc3RyYV9yZVssIGMoImVkYWRfcGFjaWVudGUiLCJBVl9PRCIsIkFWX09JIiwiSG9yYXNfcGQiLCJIb3Jhc19hZiIpXSwNCm5jcCA9IDUsDQpzY2FsZS51bml0ID0gVFJVRSwNCmdyYXBoID0gRkFMU0UNCikNCg0KZnZpel9wY2FfYmlwbG90KA0KcmVzX3BjYV9yZSwNCmF4ZXMgPSBjKDEsIDIpLA0KcmVwZWwgPSBUUlVFLA0KaGFiaWxsYWdlID0gbXVlc3RyYV9yZSRyYW5nb19ldGFyZW8NCikNCmBgYA0KDQoNCiMjIyMgQmlwbG90IGRlIFZhcmlhYmxlcyB5IFJlZ2lzdHJvcyBbZmlsdHJvOkhvYmJ5X3BwYW50YWxsYV0NCmBgYHtyIEJpcGxvdF9WYXJpYWJsZXNfUmVnaXN0cm9zX0ZpbHRyb19Ib2JieV9wcGFudGFsbGF9DQoNCnNldC5zZWVkKDc4MDcyOSkNCg0KbXVlc3RyYV9oYiA8LSBjY2RfdmlzaW9uMjAyMF9FVExbDQpzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksIDE1MCksDQpjKCJlZGFkX3BhY2llbnRlIiwiQVZfT0QiLCJBVl9PSSIsIkhvcmFzX3BkIiwiSG9yYXNfYWYiLCJIb2JieV9wcGFudGFsbGEiKQ0KXQ0KDQptdWVzdHJhX2hiJEhvYmJ5X3BwYW50YWxsYSA8LSBmYWN0b3IoDQptdWVzdHJhX2hiJEhvYmJ5X3BwYW50YWxsYSwNCmxldmVscyA9IGMoIm5vIiwic2kiKSAjIGFqdXN0YSBzZWfDum4gY29kaWZpY2FjacOzbiByZWFsDQopDQoNCnJlc19wY2FfaGIgPC0gUENBKA0KbXVlc3RyYV9oYlssIGMoImVkYWRfcGFjaWVudGUiLCJBVl9PRCIsIkFWX09JIiwiSG9yYXNfcGQiLCJIb3Jhc19hZiIpXSwNCm5jcCA9IDUsDQpzY2FsZS51bml0ID0gVFJVRSwNCmdyYXBoID0gRkFMU0UNCikNCg0KZnZpel9wY2FfYmlwbG90KA0KcmVzX3BjYV9oYiwNCmF4ZXMgPSBjKDEsIDIpLA0KcmVwZWwgPSBUUlVFLA0KaGFiaWxsYWdlID0gbXVlc3RyYV9oYiRIb2JieV9wcGFudGFsbGENCikNCmBgYA0KDQojIyAqKkZhc2UgMyBbQ29ycmVzcG9uZGVuY2lhc10qKg0KDQojIyMgMy4xLiBPYmpldGl2b3MNCg0KRW4gZXN0YSB0ZXJjZXJhIGZhc2UgZGVsIGVzdHVkaW8sIHNlIHByZXNlbnRhcsOhbiBjw6FsY3Vsb3MsIHZpc3VhbGl6YWNpb25lcyBlIGludGVycHJldGFjaW9uZXMgYmFzYWRhcyBlbiBlbCBjb25qdW50byBkZSBkYXRvcyB0cmFiYWphZG8gZW4gbGEgW2Zhc2UgMV0oI3NlYzEpIHkgW2Zhc2UgMl0oI3NlYzIpLiBTaW4gZW1iYXJnbywgZXN0YSBmYXNlIHNlIGVuZm9jYXLDoSBlbiBhcGxpY2FyIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIHNpbXBsZXMgeSBtw7psdGlwbGVzIHNvYnJlIGxhcyB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzLCBhYmFyY2FuZG8gbGEgY29uc3RydWNjacOzbiBkZSB0YWJsYXMgZGUgY29udGluZ2VuY2lhIHkgZGlzeXVudGl2YXMgY29tcGxldGFzLCBhc8OtIGNvbW8gbGEgZXZhbHVhY2nDs24gZGUgY2FsaWRhZGVzIGRlIHJlcHJlc2VudGFjacOzbiwgY29udHJpYnVjaW9uZXMgZSBpbnRlcnByZXRhY2lvbmVzLg0KDQojIyMgMy4yLiBDb3JyZXNwb25kZW5jaWFzIFNpbXBsZXMNCg0KU2Vnw7puIFtAQU1BUkFsZGFzLVVyaWVsMmVkXSxlbCAqKmFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzKiogc2ltcGxlICoqKEFDUykqKiB0aWVuZSBjb21vIHByb3DDs3NpdG8gcmVkdWNpciBsYSBkaW1lbnNpb25hbGlkYWQgZGUgbGFzIHJlbGFjaW9uZXMgZW50cmUgY2F0ZWdvcsOtYXMgZGUgZG9zIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMsIHJlcHJlc2VudMOhbmRvbGFzIGVuIHVuIGVzcGFjaW8gbXVsdGlkaW1lbnNpb25hbC4gRXN0ZSBtw6l0b2RvIHBlcm1pdGUgYW5hbGl6YXIgZ3LDoWZpY2FtZW50ZSBsYXMgZGlzdGFuY2lhcyBlbnRyZSBsYXMgY2F0ZWdvcsOtYXMgZGUgbGFzIHZhcmlhYmxlcywgZmFjaWxpdGFuZG8gbGEgaW50ZXJwcmV0YWNpw7NuIGRlIHRhYmxhcyBkZSBjb250aW5nZW5jaWEuIEVsIG7Dum1lcm8gbcOheGltbyBkZSBkaW1lbnNpb25lcyBuZWNlc2FyaWFzIHBhcmEgZXhwbGljYXIgZGljaGFzIHJlbGFjaW9uZXMgY29ycmVzcG9uZGUgYSB1bm8gbWVub3MgZWwgbsO6bWVybyBkZSBjYXRlZ29yw61hcyBkZSBsYSB2YXJpYWJsZSBjb24gbWVub3IgY2FudGlkYWQgZGUgbml2ZWxlcy4NCg0KQXNpbWlzbW8sIGVsICoqQUNTKiosIGJhc2FkbyBlbiB0YWJsYXMgZGUgY29udGluZ2VuY2lhLCBwdWVkZSBhbXBsaWFyc2UgcGFyYSBpbmNsdWlyIG3DoXMgZGUgZG9zIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMsIGxvIHF1ZSBzZSBjb25vY2UgY29tbyAqKkFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIG3Dumx0aXBsZXMgKEFDTSkqKi4gRXN0ZSBlbmZvcXVlIHV0aWxpemEgdW5hIHRhYmxhIGRpc3l1bnRpdmEgY29tcGxldGEsIHBlcm1pdGllbmRvIGV4cGxvcmFyIHkgcmVwcmVzZW50YXIgcmVsYWNpb25lcyBtw6FzIGNvbXBsZWphcyBlbnRyZSBtw7psdGlwbGVzIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMuDQoNCiMjIyAzLjMuIENvcnJlc3BvbmRlbmNpYXMgTcO6bHRpcGxlcw0KDQojIyAqKkZhc2UgNCBbQ29uZ2xvbWVyYWRvc10qKg0KDQojIyMgNC4xLiBPYmpldGl2b3MNCg0KRW4gZXN0YSAqKmN1YXJ0YSBldGFwYSoqIGRlbCBlc3R1ZGlvIHNlIHByZXNlbnRhcsOhbiBjw6FsY3Vsb3MsIHZpc3VhbGl6YWNpb25lcyBlIGludGVycHJldGFjaW9uZXMsIHV0aWxpemFuZG8gZWwgY29uanVudG8gZGUgZGF0b3MgcHJvY2VzYWRvIGVuIGxhcyBmYXNlcyBwcmV2aWFzICoqKDEsIDIgeSAzKSoqLiBFbCBlbmZvcXVlIHNlIGNlbnRyYXLDoSBlbiBlbCAqKmFuw6FsaXNpcyBkZSBjb25nbG9tZXJhZG9zKiosIGFiYXJjYW5kbyB0YW50byBzdSB2ZXJzacOzbiBqZXLDoXJxdWljYSBtZWRpYW50ZSBkZW5kcm9ncmFtYXMgY29tbyBsYSBubyBqZXLDoXJxdWljYSBjb24gSy1tZWRpYXMuDQoNCiMjIyA0LjIuIEFncnVwYWNpw7NuIEplcsOhcnF1aWNhIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkVsIFByb2Zlc29yIFtARUFNT1RJbW80MjAyM10sIGVuIHN1IHRyYWJham8gKGFsIHF1ZSBzZSBwdWVkZW4gcmVtaXRpciBtZWRpYW50ZSBlbCBlbmxhY2UpLCBzZcOxYWxhYmEgcXVlIGxvcyBhdXRvcmVzIFtAQUVETURpYXotTW9yYWxlczFlZF0sIGJhc8OhbmRvc2UgZW4gZWwgYW7DoWxpc2lzIGRlICpFdmVyaXR0ICgxOTgwKSogdGl0dWxhZG8gKipDbHVzdGVyIEFuYWx5c2lzKiosIGRlc2NyaWJlbiBsb3MgY29uZ2xvbWVyYWRvcyBjb21vICoqem9uYXMgY29udGludWFzKiogZW4gdW4gZXNwYWNpbyBkb25kZSBzZSBjb25jZW50cmEgdW5hIGFsdGEgZGVuc2lkYWQgZGUgcHVudG9zLCBzZXBhcmFkYXMgcG9yIMOhcmVhcyBjb24gbWVub3IgZGVuc2lkYWQuIFBhcmEgaWRlbnRpZmljYXIgZXN0YXMgY29uY2VudHJhY2lvbmVzLCBzZSBlbXBsZWFuIGRpZmVyZW50ZXMgdMOpY25pY2FzLCBkZXN0YWPDoW5kb3NlIGxvcyBtw6l0b2RvcyBqZXLDoXJxdWljb3MuIEVzdG9zIGluaWNpYW4gY29uIGVsICoqY8OhbGN1bG8gZGUgdW5hIG1hdHJpeiBkZSBkaXN0YW5jaWFzKiogZW50cmUgbG9zIGVsZW1lbnRvcyBhbmFsaXphZG9zLCBsbyBxdWUgcGVybWl0ZSBhZ3J1cGFybG9zIG1lZGlhbnRlIHVuIHByb2Nlc28gZGUgKiphZ2xvbWVyYWNpw7NuKiouIEVzdGUgbcOpdG9kbyBjb21pZW56YSBjb24gKipjb25nbG9tZXJhZG9zIGluZGl2aWR1YWxlcyoqIHkgYXZhbnphIGhhY2lhIHVuICoqw7puaWNvIGdydXBvIGZpbmFsKiouIEEgbG8gbGFyZ28gZGUgZXN0ZSBwcm9jZXNvLCBzZSBnZW5lcmFuIGZ1c2lvbmVzIHkgZGl2aXNpb25lcyBxdWUgZXN0YWJsZWNlbiBqZXJhcnF1w61hcyBiYXNhZGFzIGVuIHNpbWlsaXR1ZGVzLCByZXByZXNlbnRhZGFzIGdyw6FmaWNhbWVudGUgYSB0cmF2w6lzIGRlIHVuICoqZGVuZG9ncmFtYSoqLg0KDQojIyMgNC4zLiBBZ3J1cGFjacOzbiBOby1KZXLDoXJxdWljYQ0KDQojIyAqKkZhc2UgNSBbUmVncmVzaW9uZXNdKioNCg0KIyMjIDUuMS4gT2JqZXRpdm9zDQoNCkVzdGUgZXN0dWRpbyB0aWVuZSBjb21vIHByb3DDs3NpdG8gZXN0YWJsZWNlciBsYSAqKnJlbGFjacOzbiBlbnRyZSBkb3MgbyBtw6FzIHZhcmlhYmxlcyoqIG1lZGlhbnRlIGxhIG9idGVuY2nDs24gZGUgaW5mb3JtYWNpw7NuIHNvYnJlIHVuYSBkZSBlbGxhcywgYmFzYWRhIGVuIGVsIGNvbm9jaW1pZW50byBkZSBsb3MgdmFsb3JlcyBkZSBsYXMgb3RyYXMuIExhcyByZWxhY2lvbmVzIGVzdGFibGVjaWRhcyBzb24gZGUgY2Fyw6FjdGVyICoqbm8gZGV0ZXJtaW7DrXN0aWNvKiosIGVzIGRlY2lyLCBzZSBwbGFudGVhcsOhbiByZWxhY2lvbmVzIHByb2JhYmlsw61zdGljYXMgeSBzZSBpbXBsZW1lbnRhcsOhbiBwcm9jZWRpbWllbnRvcyBwYXJhIHJlYWxpemFyIGluZmVyZW5jaWFzIHNvYnJlIGxvcyBtb2RlbG9zIHV0aWxpemFkb3MuIEFkZW3DoXMsIHNlIG9idGVuZHLDoW4gbWVkaWRhcyBjdWFudGl0YXRpdmFzIHF1ZSBpbmRpcXVlbiBlbCBncmFkbyBkZSByZWxhY2nDs24gZW50cmUgbGFzIHZhcmlhYmxlcy4gTG9zIG1vZGVsb3MgY29uc2lkZXJhZG9zIGVuIGVzdGUgdHJhYmFqbyBjb3JyZXNwb25kZW4gYSBjYXNvcyBlc3BlY8OtZmljb3MgZGVsIG1vZGVsbyBsaW5lYWwgZ2VuZXJhbGl6YWRvOiAqKlJlZ3Jlc2nDs24gTGluZWFsIFNpbXBsZSoqLCAqKlJlZ3Jlc2nDs24gTGluZWFsIE3Dumx0aXBsZSoqIHkgKipSZWdyZXNpw7NuIExvZ8Otc3RpY2EqKi4gQ2FkYSBtb2RlbG8gc2Vyw6EgZGVzY3JpdG8gdGXDs3JpY2FtZW50ZSBlbiBzdSByZXNwZWN0aXZhIHNlY2Npw7NuLCB5IHNlIGFwbGljYXLDoSBhIHVuIGNvbmp1bnRvIGRlIGRhdG9zIGVzcGVjw61maWNvIGRlc2NyaXRvIGVuIGxhIFtzZWNjacOzbiAyXSgjc2VjMikuIA0KDQpMYSBlc3RydWN0dXJhIHkgcmVmZXJlbmNpYXMgcHJpbmNpcGFsZXMgc2UgYmFzYW4gZW4gZWwgRXN0dWRpbyBkZSAqKkFuw6FsaXNpcyBNdWx0aXZhcmlhZG8qKiBkZWwgcHJvZmVzb3IgW0BFQU1PVEltbzQyMDIzXS4gQWRlbcOhcywgc2UgdXRpbGl6YXJvbiBsaWJyb3MgY29tbyAqUHJvYmFiaWxpZGFkIHkgZXN0YWTDrXN0aWNhIHBhcmEgaW5nZW5pZXLDrWEgaW5kdXN0cmlhbCogZGUgW0BQRURldm9yZTdlZF0sICpBbsOhbGlzaXMgZXN0YWTDrXN0aWNvIGRlIGRhdG9zIG11bHRpdmFyaWFkb3MqIGRlIFtAQUVETURpYXotTW9yYWxlczFlZF0sIHkgKkFuw6FsaXNpcyBtdWx0aXZhcmlhbnRlIGFwbGljYWRvIGNvbiBSKiBkZSBbQEFNQVJBbGRhcy1VcmllbDJlZF0sIHF1ZSBwcm9wb3JjaW9uYXJvbiBmdW5kYW1lbnRvcyBjbGF2ZSBwYXJhIGVzdGUgYW7DoWxpc2lzLg0KDQoNClBhcmEgZmluZXMgZGUgdmlzdWFsaXphY2nDs24sIHNlIGNyZcOzIHVuIGFwYXJ0YWRvIGVzcGVjw61maWNvIHBhcmEgZWwgZGljY2lvbmFyaW8gZGUgdmFyaWFibGVzLiBBc2ltaXNtbywgc2UgYWNsYXJhIHF1ZSBzZSBwdWVkZSBjb25zdWx0YXIgZWwgZGljY2lvbmFyaW8gZGUgdmFyaWFibGVzIGV4dGVuZGlkbyBlbiBsYSBbc2VjY2nDs24gMS4yXSgjc2VjMS4yKTogDQoNCg0KPGRldGFpbHM+IDxzdW1tYXJ5PioqRGVzcGxlZ2FyIGVsIGRpY2Npb25hcmlvIGRlIHZhcmlhYmxlcyoqPC9zdW1tYXJ5Pg0KDQojIyMgNS4yLiBSZWdyZXNpw7NuIExpbmVhbCBTaW1wbGUgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIyBDb2VmaWNpZW50ZXMgZGVsIE1vZGVsbyBSTFMNCmBgYHtyIENvZWZpY2llbnRlc19Nb2RlbG9fUkxTLCBmaWcuYWxpZ249J2NlbnRlcid9DQptb2RlbG9fUkxfU2ltcGxlID0gbG0oY2NkX3Zpc2lvbjIwMjBfRVRMJEFWX09EfmNjZF92aXNpb24yMDIwX0VUTCRyYW5nb19ldGFyZW8pDQpjb2VmKG1vZGVsb19STF9TaW1wbGUpDQpgYGANCmBgYHtyIENvZWZpY2llbnRlc19Nb2RlbG9fUkxTMSwgZmlnLmFsaWduPSdjZW50ZXInfQ0KbW9kZWxvX1JMX1NpbXBsZTEgPSBsbShjY2RfdmlzaW9uMjAyMF9FVEwkQVZfT0l+Y2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbykNCmNvZWYobW9kZWxvX1JMX1NpbXBsZTEpDQpgYGANCg0KIyMjIyBSZXN1bWVuIEVzdGFkw61zdGljbyBkZWwgTW9kZWxvIFJMUw0KYGBge3IgUmVzdW1lbiBFc3RhZMOtc3RpY29fZGVsX01vZGVsb19STFMsZmlnLmFsaWduPSdjZW50ZXInfQ0Kc3VtbWFyeShtb2RlbG9fUkxfU2ltcGxlKQ0KYGBgDQoNCiMjIyMgVGFibGEgQU5PVkEgcGFyYSBlbCBNb2RlbG8gUkxTDQpgYGB7ciBUYWJsYV9BTk9WQV9wYXJhX2VsX01vZGVsb19STFMsZmlnLmFsaWduPSdjZW50ZXInfQ0KYW5vdmEobW9kZWxvX1JMX1NpbXBsZSkNCg0KYGBgDQojIyMgNS4zLiBSZWdyZXNpw7NuIExpbmVhbCBNw7psdGlwbGUNCg0KRXN0ZSBtb2RlbG8sIHF1ZSBhIHBhcnRpciBkZSBhaG9yYSBzZSBkZW5vbWluYXLDoSBjb21vIFJMUywgZXN0w6EgY29tcHVlc3RvIHBvciBkb3MgdmFyaWFibGVzOiB1bmEgcHJlZGljdG9yYSB5IG90cmEgcmVzcHVlc3RhLiBFc3BlY8OtZmljYW1lbnRlLCBsYSB2YXJpYWJsZSAkWSQgc2UgY29uc2lkZXJhIGluZmx1aWRhIHBvciBsYSB2YXJpYWJsZSBwcmVkaWN0b3JhICR4JC4gTGEgcmVsYWNpw7NuIGVudHJlIGVzdGFzIHZhcmlhYmxlcyBlc3TDoSBkZXNjcml0YSBwb3IgbGEgZWN1YWNpw7NuOg0KJCRZID0gXGJldGFfMCArIFxiZXRhXzF4ICsgXHZhcmVwc2lsb24kJA0KRG9uZGU6IA0KLSAkWSQ6IEVzIGxhIHZhcmlhYmxlIGRlcGVuZGllbnRlIChsYSBxdWUgc2UgZGVzZWEgcHJlZGVjaXIgbyBleHBsaWNhcikuDQotICR4JDogRXMgbGEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZSAocHJlZGljdG9yYSkuDQotICQoXGJldGFfMCkkOiBFcyBlbCBpbnRlcmNlcHRvICh2YWxvciBkZSAkWSQgY3VhbmRvICQoeCA9IDApJC4NCi0gJChcYmV0YV8xKSQ6IEVzIGxhIHBlbmRpZW50ZSAoaW5kaWNhIGN1w6FudG8gY2FtYmlhICRZJCBwb3IgY2FkYSB1bmlkYWQgcXVlIGNhbWJpYSAkKHgpJC4NCi0gJChcZXBzaWxvbikkOiBFcyBlbCB0w6lybWlubyBkZSBlcnJvciwgcXVlIGNhcHR1cmEgbGFzIGRlc3ZpYWNpb25lcyBlbnRyZSBsb3MgdmFsb3JlcyBvYnNlcnZhZG9zIHkgbG9zIHZhbG9yZXMgcHJlZGljaG9zIHBvciBlbCBtb2RlbG8uDQoNCkxhIHJlbGFjacOzbiBlbnRyZSBsYSB2YXJpYWJsZSBpbmRlcGVuZGllbnRlIHkgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUgZW4gZWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbGluZWFsIHNpbXBsZSBkZWJlIGN1bXBsaXIgY2llcnRhcyBzdXBvc2ljaW9uZXMgY2xhdmUgcGFyYSBxdWUgbG9zIHJlc3VsdGFkb3Mgc2VhbiB2w6FsaWRvcy4gRXN0YXMgc29uIGxhcyBzaWd1aWVudGVzOiAxLiBMYSByZWxhY2nDs24gZW50cmUgbGEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZSAkeCQgeSBsYSB2YXJpYWJsZSBkZXBlbmRpZW50ZSAkWSQgZGViZSBzZXIgbGluZWFsLiAyLiBFbCB0w6lybWlubyBkZSBlcnJvciAkzrUkIHNpZ3VlIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCB5IHRpZW5lIHVuYSBtZWRpYSBpZ3VhbCBhIGNlcm8uIDMuIExhcyBvYnNlcnZhY2lvbmVzIGRlYmVuIHNlciBpbmRlcGVuZGllbnRlcyBlbnRyZSBzw60sIGVzIGRlY2lyLCBlbCB2YWxvciBkZSAkWSQgcGFyYSB1biBkYXRvIG5vIGluZmx1eWUgZW4gbG9zIHZhbG9yZXMgZGUgJFkkIHBhcmEgb3Ryb3MgZGF0b3MuIDQuIExhIHZhcmlhbnphIGRlbCB0w6lybWlubyBkZSBlcnJvciAkzrUkIGRlYmUgc2VyIGNvbnN0YW50ZSBwYXJhIHRvZG9zIGxvcyB2YWxvcmVzIGRlIGxhIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgJHgkLCB1bmEgY29uZGljacOzbiBjb25vY2lkYSBjb21vIGhvbW9jZWRhc3RpY2lkYWQuIExhIHZhcmlhbnphIGRlICRcdmFyZXBzaWxvbiQgZXMgY29uc3RhbnRlIHBhcmEgdG9kb3MgbG9zIHZhbG9yZXMgZGUgJHgkLg0KDQpQYXJhIGVzdGltYXIgbG9zIHBhcsOhbWV0cm9zIGRlc2Nvbm9jaWRvcyAoJFxiZXRhXzAkLCAkXGJldGFfMSQgeSAkXHNpZ21hXjIkKSwgc2UgdXNhIGVsICoqbcOpdG9kbyBkZSBtw61uaW1vcyBjdWFkcmFkb3MqKiwgcXVlIGJ1c2NhIG1pbmltaXphciBsYSBzdW1hIGRlIGxvcyBjdWFkcmFkb3MgZGUgbGFzIGRlc3ZpYWNpb25lcyB2ZXJ0aWNhbGVzIGVudHJlIGxvcyBwdW50b3Mgb2JzZXJ2YWRvcyB5IGxhIGzDrW5lYSBkZSByZWdyZXNpw7NuOiQkU0NFID0gXHN1bV97aT0xfV5uIFxsZWZ0KHlfaSAtIChcYmV0YV8wICsgXGJldGFfMXhfaSlccmlnaHQpXjIkJC4gUmVzb2x2aWVuZG8gZXN0ZSBwcm9ibGVtYSwgbGFzIGVzdGltYWNpb25lcyBkZSBsb3MgcGFyw6FtZXRyb3Mgc29uOg0KJCRcaGF0e1xiZXRhfV8xID0gXGZyYWN7XHN1bV97aT0xfV5uICh4X2kgLSBcYmFye3h9KSh5X2kgLSBcYmFye3l9KX17XHN1bV97aT0xfV5uICh4X2kgLSBcYmFye3h9KV4yfSwgXHF1YWQgXGhhdHtcYmV0YX1fMCA9IFxiYXJ7eX0gLSBcaGF0e1xiZXRhfV8xIFxiYXJ7eH0uJCQNCkFxdcOtLCAkXGJhcnt4fSQgeSAkXGJhcnt5fSQgc29uIGxhcyBtZWRpYXMgbXVlc3RyYWxlcyBkZSAkeCQgZSAkeSQsIHJlc3BlY3RpdmFtZW50ZS4NCg0KRWwgY29lZmljaWVudGUgZGUgZGV0ZXJtaW5hY2nDs24gaW5kaWNhIGxhIHByb3BvcmNpw7NuIGRlIGxhIHZhcmlhYmlsaWRhZCBkZSAkWSQgcXVlIHB1ZWRlIGV4cGxpY2Fyc2UgbWVkaWFudGUgZWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbGluZWFsIHNpbXBsZTokJFJeMiA9IDEgLSBcZnJhY3tTQ0V9e1NUQ30sJCQgZG9uZGUgJFNDRSQgZXMgbGEgc3VtYSBkZSBjdWFkcmFkb3MgZGVsIGVycm9yIHkgJFNUQyQgZXMgbGEgc3VtYSB0b3RhbCBkZSBjdWFkcmFkb3MuIFVuIHZhbG9yIGRlICRSXjIkIGNlcmNhbm8gYSAxIGluZGljYSBxdWUgZWwgbW9kZWxvIGV4cGxpY2EgZ3JhbiBwYXJ0ZSBkZSBsYSB2YXJpYWJpbGlkYWQgb2JzZXJ2YWRhIGVuIGxvcyBkYXRvcy4NCg0KU2UgcHVlZGVuIGZvcm11bGFyIHBydWViYXMgcGFyYSBkZXRlcm1pbmFyIHNpIGxvcyBjb2VmaWNpZW50ZXMgZGVsIG1vZGVsbyBzb24gc2lnbmlmaWNhdGl2YW1lbnRlIGRpZmVyZW50ZXMgZGUgY2Vyby4gTGFzIGhpcMOzdGVzaXMgbnVsYXMgY29tdW5lcyBzb246DQotIFBhcmEgJFxiZXRhXzAkOiAkSF8wOiBcYmV0YV8wID0gXGJldGFfezAwfSQuDQotIFBhcmEgJFxiZXRhXzEkOiAkSF8wOiBcYmV0YV8xID0gMCQgKHBydWViYSBkZSB1dGlsaWRhZCBkZWwgbW9kZWxvKS4NCg0KRWwgZXN0YWTDrXN0aWNvIGRlIHBydWViYSBhc29jaWFkbyBlczokJCB0ID0gXGZyYWN7XGhhdHtcYmV0YX1fMSAtIDB9e1NFKFxoYXR7XGJldGF9XzEpfSwkJCBkb25kZSAkU0UoXGhhdHtcYmV0YX1fMSkkIGVzIGVsIGVycm9yIGVzdMOhbmRhciBkZSAkXGhhdHtcYmV0YX1fMSQgRXN0ZSBlc3RhZMOtc3RpY28gc2lndWUgdW5hIGRpc3RyaWJ1Y2nDs24gJHQkIGRlIFN0dWRlbnQgY29uICRuLTIkIGdyYWRvcyBkZSBsaWJlcnRhZC4NCg0KTG9zIGludGVydmFsb3MgZGUgY29uZmlhbnphIHBhcmEgbG9zIHBhcsOhbWV0cm9zIGVzdGltYWRvcyBzZSBjYWxjdWxhbiBjb21vOiAkJFxoYXR7XGJldGF9XzEgXHBtIHRfe1xhbHBoYS8yLCBuLTJ9IFxjZG90IFNFKFxoYXR7XGJldGF9XzEpLiQkIEVzdG9zIGludGVydmFsb3MgYnJpbmRhbiB1biByYW5nbyBwcm9iYWJsZSBwYXJhIGxvcyB2ZXJkYWRlcm9zIHZhbG9yZXMgZGUgJFxiZXRhXzAkIHkgJFxiZXRhXzEkLg0KDQpFbCBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgc2ltcGxlIGVzIHVuYSBoZXJyYW1pZW50YSBwb2Rlcm9zYSBwYXJhIGFuYWxpemFyIHJlbGFjaW9uZXMgbGluZWFsZXMuIFNpbiBlbWJhcmdvLCBkZWJlIHVzYXJzZSBjb24gY2F1dGVsYTogbm8gZXh0cmFwb2xlIG3DoXMgYWxsw6EgZGVsIHJhbmdvIGRlIGxvcyBkYXRvcyB5IGFzZWfDunJlc2UgZGUgcXVlIGxhcyBzdXBvc2ljaW9uZXMgZGVsIG1vZGVsbyBzZWFuIHJhem9uYWJsZXMgcGFyYSBsb3MgZGF0b3MuIEFsIGNvbXByZW5kZXIgbGEgdmFyaWFiaWxpZGFkIGV4cGxpY2FkYSB5IG5vIGV4cGxpY2FkYSBwb3IgZWwgbW9kZWxvLCBsb3MgYW5hbGlzdGFzIHB1ZWRlbiB0b21hciBkZWNpc2lvbmVzIGZ1bmRhbWVudGFkYXMgeSBldmFsdWFyIGxhIHV0aWxpZGFkIGRlbCBtb2RlbG8gZW4gY29udGV4dG9zIGVzcGVjw61maWNvcy4NCg0KDQpFbiBlbCBtb2RlbG8sICoqbG9zIHB1bnRvcyBvYnNlcnZhZG9zIHNlIGRpc3RyaWJ1eWVuIGFsZWF0b3JpYW1lbnRlIGFscmVkZWRvcioqIGRlIGxhIGzDrW5lYSBkZSAqKnJlZ3Jlc2nDs24gdmVyZGFkZXJhKiouIFBhcmEgYWp1c3RhcnNlIGEgZXN0b3MgcHVudG9zLCBsYSBlc3RpbWFjacOzbiAkeSA9IGJldGFfMCArIGJldGFfMSB4JCBkZWJlIHNlciB1bmEgbMOtbmVhIHF1ZSBtaW5pbWljZSBsYXMgZGlzdGFuY2lhcyB2ZXJ0aWNhbGVzIGRlc3ZpYWNpb25lcyBlbnRyZSBsb3MgcHVudG9zIG9ic2VydmFkb3MgeSBsYSBsw61uZWEuIExhIGNhbGlkYWQgZGVsIGFqdXN0ZSBzZSBldmFsw7phIG1lZGlhbnRlIGxhIHN1bWEgZGUgbG9zIGN1YWRyYWRvcyBkZSBlc3RhcyBkZXN2aWFjaW9uZXMsIHNpZW5kbyBsYSBtZWpvciBsw61uZWEgYXF1ZWxsYSBxdWUgbWluaW1pY2UgZXN0YSBzdW1hLiBFc3RlIGVuZm9xdWUsIGNvbm9jaWRvIGNvbW8gZWwgcHJpbmNpcGlvIGRlIGxvcyBtw61uaW1vcyBjdWFkcmFkb3MsIGZ1ZSBkZXNhcnJvbGxhZG8gcG9yICoqQ2FybCBGcmllZHJpY2ggR2F1c3MgeSBBZHJpZW4tTWFyaWUgTGVnZW5kcmUqKi4NCg0KUG9yIMO6bHRpbW8sIHNlIGVudGllbmRlIHF1ZSBlbiB1biBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgc2ltcGxlIHVuIHZhbG9yIGZ1dHVybyBkZSAkWSQgbm8gZXMgcGFyw6FtZXRybyBzaW5vIHVuYSB2YXJpYWJsZSBhbGVhdG9yaWEsIHBvciBsbyBxdWUgc2UgZGViZSBoYWNlciByZWZlcmVuY2lhIGEgdW4gaW50ZXJ2YWxvIGRlIHZhbG9yZXMgZmFjdGlibGVzIHBhcmEgdW4gdmFsb3IgZnV0dXJvIGRlICRZJCwgYWwgY3VhbCBzZSBsZSBsbGFtYSBpbnRlcnZhbG8gZGUgcHJlZGljY2nDs24uIFNlZ8O6bixbQEVBTU9USW1vNDIwMjNdLg0KIA0KDQojIyMgNS40LiBSZWdyZXNpw7NuIExvZ8Otc3RpY2EgU2ltcGxlIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjI0dyw6FmaWNhIGRlbCBNb2RlbG8gUkxvZ1MNCmBgYHtyIGdyYWZpY2FfTW9kZWxvX1JMb2dTLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCg0KdW1icmFsX09EIDwtIDAuOCAjIGVqZW1wbG8sIHJlZW1wbGF6YXIgcG9yIGVsIHZhbG9yIGFkZWN1YWRvDQp1bWJyYWxfT0kgPC0gMC44ICMgZWplbXBsbywgcmVlbXBsYXphciBwb3IgZWwgdmFsb3IgYWRlY3VhZG8NCg0KY2NkX3Zpc2lvbjIwMjBfRVRMJGJhamFfQVZfT0QgPC0gaWZlbHNlKGNjZF92aXNpb24yMDIwX0VUTCRBVl9PRCA8IHVtYnJhbF9PRCwgMSwgMCkNCmNjZF92aXNpb24yMDIwX0VUTCRiYWphX0FWX09JIDwtIGlmZWxzZShjY2RfdmlzaW9uMjAyMF9FVEwkQVZfT0kgPCB1bWJyYWxfT0ksIDEsIDApDQoNCmNjZF92aXNpb24yMDIwX0VUTCRiYWphX0FWX09EIDwtIGFzLm51bWVyaWMoY2NkX3Zpc2lvbjIwMjBfRVRMJGJhamFfQVZfT0QpDQpjY2RfdmlzaW9uMjAyMF9FVEwkYmFqYV9BVl9PSSA8LSBhcy5udW1lcmljKGNjZF92aXNpb24yMDIwX0VUTCRiYWphX0FWX09JKQ0KY2NkX3Zpc2lvbjIwMjBfRVRMJEhvcmFzX3BhbnRhbGxhX2RpYSA8LSBhcy5udW1lcmljKGNjZF92aXNpb24yMDIwX0VUTCRIb3Jhc19wZCkNCg0KbW9kX2xvZ19PRCA8LSBnbG0oYmFqYV9BVl9PRCB+IEhvcmFzX3BhbnRhbGxhX2RpYSwNCmZhbWlseSA9IGJpbm9taWFsLA0KZGF0YSA9IGNjZF92aXNpb24yMDIwX0VUTCkNCg0KDQptb2RfbG9nX09JIDwtIGdsbShiYWphX0FWX09JIH4gSG9yYXNfcGFudGFsbGFfZGlhLA0KZmFtaWx5ID0gYmlub21pYWwsDQpkYXRhID0gY2NkX3Zpc2lvbjIwMjBfRVRMKQ0KDQoNCnhfc2VxIDwtIHNlcSgNCmZyb20gPSBtaW4oY2NkX3Zpc2lvbjIwMjBfRVRMJEhvcmFzX3BhbnRhbGxhX2RpYSwgbmEucm0gPSBUUlVFKSwNCnRvID0gbWF4KGNjZF92aXNpb24yMDIwX0VUTCRIb3Jhc19wYW50YWxsYV9kaWEsIG5hLnJtID0gVFJVRSksDQpsZW5ndGgub3V0ID0gMjAwDQopDQoNCnBhcihtZnJvdyA9IGMoMSwgMikpDQpgYGANCg0KIyMjIyBHcsOhZmljYSBkZWwgTW9kZWxvIFJMb2dTIA0KYGBge3IgZ3JhZmljYV9Nb2RlbG9fUkxvZ1NfQVZfT0QsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KcGxvdChiYWphX0FWX09EIH4gSG9yYXNfcGFudGFsbGFfZGlhLA0KZGF0YSA9IGNjZF92aXNpb24yMDIwX0VUTCwNCm1haW4gPSAiTW9kZWxvIFJMb2dTOiBiYWphX0FWX09EIH4gSG9yYXNfcGFudGFsbGFfZGlhIiwNCnhsYWIgPSAiSG9yYXNfcGFudGFsbGFfZGlhIiwNCnlsYWIgPSAiYmFqYV9BVl9PRCAoMCA9IE5vLCAxID0gU8OtKSIsDQpjb2wgPSAiZ29sZCIsDQpwY2ggPSAxNikNCg0KbGluZXMoeF9zZXEsDQpwcmVkaWN0KG1vZF9sb2dfT0QsDQpuZXdkYXRhID0gZGF0YS5mcmFtZShIb3Jhc19wYW50YWxsYV9kaWEgPSB4X3NlcSksDQp0eXBlID0gInJlc3BvbnNlIiksDQpjb2wgPSAib3JhbmdlIiwNCmx3ZCA9IDMpDQoNCmBgYA0KDQojIyMjIEdyw6FmaWNhIGRlbCBNb2RlbG8gUkxvZ1MNCmBgYHtyIGdyYWZpY2FfTW9kZWxvX1JMb2dTX0FWX09JLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnBsb3QoYmFqYV9BVl9PSSB+IEhvcmFzX3BhbnRhbGxhX2RpYSwNCmRhdGEgPSBjY2RfdmlzaW9uMjAyMF9FVEwsDQptYWluID0gIk1vZGVsbyBSTG9nUzogYmFqYV9BVl9PSSB+IEhvcmFzX3BhbnRhbGxhX2RpYSIsDQp4bGFiID0gIkhvcmFzX3BhbnRhbGxhX2RpYSIsDQp5bGFiID0gImJhamFfQVZfT0kgKDAgPSBObywgMSA9IFPDrSkiLA0KY29sID0gImdvbGQiLA0KcGNoID0gMTYpDQoNCmxpbmVzKHhfc2VxLA0KcHJlZGljdChtb2RfbG9nX09JLA0KbmV3ZGF0YSA9IGRhdGEuZnJhbWUoSG9yYXNfcGFudGFsbGFfZGlhID0geF9zZXEpLA0KdHlwZSA9ICJyZXNwb25zZSIpLA0KY29sID0gIm9yYW5nZSIsDQpsd2QgPSAzKQ0KDQpwYXIobWZyb3cgPSBjKDEsIDEpKQ0KDQpgYGANCg0KDQojIyMgNS41LiBBanVzdGUgZGUgVmFyaWFuemENCg0KIyMgKio2LiBDb25jbHVzaW9uZXMqKg0KDQojIyAqKjcuIEJpYmxpb2dyYWbDrWEqKg0KDQoNCg==