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 3 [Correspondencias]

3.1. Objetivos

En esta tercera fase del estudio, se presentarán cálculos, visualizaciones e interpretaciones basadas en el conjunto de datos trabajado en la fase 1 y fase 2. Sin embargo, esta fase se enfocará en aplicar análisis de correspondencias simples y múltiples sobre las variables cualitativas, abarcando la construcción de tablas de contingencia y disyuntivas completas, así como la evaluación de calidades de representación, contribuciones e interpretaciones.

3.2. Correspondencias Simples

Según (Aldás & Uriel, 2017),el análisis de correspondencias simple (ACS) tiene como propósito reducir la dimensionalidad de las relaciones entre categorías de dos variables categóricas, representándolas en un espacio multidimensional. Este método permite analizar gráficamente las distancias entre las categorías de las variables, facilitando la interpretación de tablas de contingencia. El número máximo de dimensiones necesarias para explicar dichas relaciones corresponde a uno menos el número de categorías de la variable con menor cantidad de niveles.

Asimismo, el ACS, basado en tablas de contingencia, puede ampliarse para incluir más de dos variables categóricas, lo que se conoce como Análisis de correspondencias múltiples (ACM). Este enfoque utiliza una tabla disyuntiva completa, permitiendo explorar y representar relaciones más complejas entre múltiples variables categóricas.

3.3. Correspondencias Múltiples

Fase 4 [Conglomerados]

4.1. Objetivos

En esta cuarta etapa del estudio se presentarán cálculos, visualizaciones e interpretaciones, utilizando el conjunto de datos procesado en las fases previas (1, 2 y 3). El enfoque se centrará en el análisis de conglomerados, abarcando tanto su versión jerárquica mediante dendrogramas como la no jerárquica con K-medias.

4.2. Agrupación Jerárquica

El Profesor (EAMOTImo42023?), en su trabajo (al que se pueden remitir mediante el enlace), señalaba que los autores (Díaz Morales & Morales Rivera, 2012), basándose en el análisis de Everitt (1980) titulado Cluster Analysis, describen los conglomerados como zonas continuas en un espacio donde se concentra una alta densidad de puntos, separadas por áreas con menor densidad. Para identificar estas concentraciones, se emplean diferentes técnicas, destacándose los métodos jerárquicos. Estos inician con el cálculo de una matriz de distancias entre los elementos analizados, lo que permite agruparlos mediante un proceso de aglomeración. Este método comienza con conglomerados individuales y avanza hacia un único grupo final. A lo largo de este proceso, se generan fusiones y divisiones que establecen jerarquías basadas en similitudes, representadas gráficamente a través de un dendograma.

4.3. Agrupación No-Jerárquica

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

6. Conclusiones

7. Bibliografía

Aldás, J., & Uriel, E. (2017). Análisis multivariante aplicado con R (2nd ed.). ALFACENTAURO.
Devore, Jay L. (2008). Probabilidad y estadı́stica para ingenierı́a y ciencias (7th ed.). CENGAGE LEARNING.
Díaz Morales, L. G., & Morales Rivera, M. A. (2012). Análisis estadístico de datos multivariados (1st ed.). UNAL.
LS0tDQp0aXRsZTogIioqVEZDX0dERF8yMDI1X2dydXBvXzIqKiINCnN1YnRpdGxlOiAiRXN0dWRpbyBkZSBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvIGFwbGljYWRvIGEgdW4gY29uanVudG8gZGUgZGF0b3MgY2zDrW5pY29zIGNlbnRyYWRvcyBlbiBlbCBzZWN0b3Igb2Z0YWxtb2zDs2dpY28uIg0KYXV0aG9yOiAiUG9yOiBBbGlzc29uIEFuZHJlYSBSb2phcyBWYXJnYXMoYWxpc3Nvbi5yb2phc0Bjb3JyZW91bml2YWxsZS5lZHUuY28pLE1hbnVlbGEgR2FyY8OtYSBHYXJjw61hIChtYW51ZWxhLmdhcmNpYS5nYXJjaWFAY29ycmVvdW5pdmFsbGUuZWR1LmNvKSwgRnJlZGR5IEFsZWphbmRybyBBcmFuZ28gQ3J1eiAoYXJhbmdvLmZyZWRkeUBjb3JyZW91bml2YWxsZS5lZHUuY28sKSxIb3JsYW5kIEFkZWxtbyBQb3BvIE1hbWJ1c2NheSAoaG9ybGFuZC5wb3BvQGNvcnJlb3VuaXZhbGxlLmVkdS5jbyksIENhcmxvcyBIZXJtaWRlcyBTdWFyZXogU2FsZGFycmlhZ2EgKGNhcmxvcy5oZXJtaWRlcy5zdWFyZXpAY29ycmVvdW5pdmFsbGUuZWR1LmNvKSINCmRhdGU6ICJUcmFiYWpvIGVsYWJvcmFkbyBlbiBlbCBwZXJpb2RvIGFjYWTDqW1pY28gY29tcHJlbmRpZG8gZW50cmUgYWdvc3RvIHkgZGljaWVtYnJlIGRlbCBhw7FvIDIwMjUsIGNvbW8gYWN0aXZpZGFkIGZvcm1hdGl2YSB5IGV2YWx1YXRpdmEgZGVsIGN1cnNvIEdlc3Rpw7NuIGRlIERhdG9zIHBhcmEgSW5nZW5pZXLDrWEgSW5kdXN0cmlhbC4iDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KICAgIHRoZW1lOiBsdW1lbg0KYmlibGlvZ3JhcGh5OiBiaWJsaW9ncmFmaWFfTUUuYmliDQpjc2w6IGFwYS5jc2wNCmxpbmstY2l0YXRpb25zOiB5ZXMNCi0tLQ0KPCEtLSBDb25maWd1cmFjacOzbiBHbG9iYWwgZGUgUiAtLT4NCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkoY29ycnBsb3QpDQpsaWJyYXJ5KEdHYWxseSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoYW5kcmV3cykNCmxpYnJhcnkodGNsdGspDQpsaWJyYXJ5KGFwbHBhY2spDQpsaWJyYXJ5KGdyYXBoaWNzKQ0KbGlicmFyeShyZXNoYXBlMikNCmxpYnJhcnkoRmFjdG9NaW5lUikNCmxpYnJhcnkoZmFjdG9leHRyYSkNCmxpYnJhcnkocHN5Y2gpDQpsaWJyYXJ5KEZhY3RvQ2xhc3MpDQpsaWJyYXJ5KGNsdXN0ZXIpDQpsaWJyYXJ5KGRlbmRleHRlbmQpDQpsaWJyYXJ5KG1hZ3JpdHRyKQ0KbGlicmFyeShOYkNsdXN0KQ0KbGlicmFyeShzdGFyZ2F6ZXIpDQoNCg0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KG12bm9ybWFsVGVzdCkNCg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KDQpjb25qdW50b19kZV9kYXRvc192aXNpb24yMDIwX09yaWdpbmFsIDwtIHJlYWRfZXhjZWwoIkM6XFxVc2Vyc1xcSk9TRVxcRGVza3RvcFxcZ2RkXFxjY2RfdmlzaW9uMjAyMF9uRVRMLnhsc3giKQ0KDQoNCmNjZF92aXNpb24yMDIwX0VUTCA8LSByZWFkX2V4Y2VsKCJDOlxcVXNlcnNcXEpPU0VcXERlc2t0b3BcXGdkZFxcY2NkX3Zpc2lvbjIwMjBfRVRMLnhsc3giKQ0KDQoNCmBgYA0KDQojIyAqKkZhc2UgMSBbRGVzY3JpcGNpb25lcyBNdWx0aXZhcmlhbnRlc10qKg0KDQpFbiBsYSBwcmltZXJhIGV0YXBhIGRlbCBlc3R1ZGlvIHNlIHJlYWxpemFyw6FuIGPDoWxjdWxvcywgdmlzdWFsaXphY2lvbmVzIHkgdW4gYW7DoWxpc2lzIGRldGFsbGFkbyBkZWwgY29uanVudG8gZGUgZGF0b3MgY2zDrW5pY29zLCBlbCBjdWFsIHNlIGRlc2NyaWJpcsOhIGVuIGxhIFtzZWNjacOzbiAxLjJdKCNzZWMxLjIpLiBFc3RhIGZhc2Ugc2UgZW5mb2NhcsOhIGRlc2RlIGxhIGVzdGFkw61zdGljYSBkZXNjcmlwdGl2YSBtdWx0aXZhcmlhbnRlLCBjb24gZWwgZmluIGRlIG9mcmVjZXIgdW5hIHZpc2nDs24gZ2VuZXJhbCBkZWwgZGF0YXNldCB5LCBhbCBtaXNtbyB0aWVtcG8sIGV4YW1pbmFyIGRlIG1hbmVyYSBtw6FzIHByb2Z1bmRhIGxhcyByZWxhY2lvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMuDQpFc3RlIGVuZm9xdWUgcGVybWl0aXLDoSBpZGVudGlmaWNhciBwYXRyb25lcyB5IHRlbmRlbmNpYXMgaW1wb3J0YW50ZXMgZGVudHJvIGRlIGxvcyBkYXRvcy4gTGFzIHZpc3VhbGl6YWNpb25lcyBzZXLDoW4gZnVuZGFtZW50YWxlcyBwYXJhIG1vc3RyYXIgZ3LDoWZpY2FtZW50ZSBlc3RhcyByZWxhY2lvbmVzLCBwcm9wb3JjaW9uYW5kbyB1bmEgZm9ybWEgY2xhcmEgeSBjb21wcmVuc2libGUgZGUgZXhwbG9yYXJsYXMuIFRvZGFzIGVzdGFzIHRhcmVhcyBzZSBkZXNhcnJvbGxhcsOhbiB1dGlsaXphbmRvIFIgeSBSU3R1ZGlvLCBoZXJyYW1pZW50YXMgcXVlIGZhY2lsaXRhcsOhbiBsYSBlamVjdWNpw7NuIHByZWNpc2EgZGUgbG9zIGFuw6FsaXNpcyB5IGxhIGVsYWJvcmFjacOzbiBkZSBncsOhZmljb3MgaW50ZXJhY3Rpdm9zIHBhcmEgdW5hIGludGVycHJldGFjacOzbiBtw6FzIGNvbXBsZXRhIGRlIGxvcyByZXN1bHRhZG9zLg0KDQojIyMgMS4xLiBPYmpldGl2b3MNCg0KRWwgb2JqZXRpdm8gZGUgZXN0ZSBwcm95ZWN0byBlcyBhcGxpY2FyIHTDqWNuaWNhcyBkZSBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvIGFsIGNvbmp1bnRvIGRlIGRhdG9zIGFwcm9iYWRvLCBlbCBjdWFsIGNvbnRpZW5lIHJlZ2lzdHJvcyBjbMOtbmljb3MgZGUgbGEgZW1wcmVzYSBvZnRhbG1vbMOzZ2ljYSwgVmlzacOzbiAyMDIwLiBMYSBmaW5hbGlkYWQgZXMgb3JnYW5pemFyIHkgcHJvY2VzYXIgbGEgaW5mb3JtYWNpw7NuIGRlIG1hbmVyYSBlZmljaWVudGUsIGZvcnRhbGVjaWVuZG8gbGFzIGNvbXBldGVuY2lhcyBlbiBnZXN0acOzbiB5IGFuw6FsaXNpcyBkZSBkYXRvcy4gRXN0ZSB0cmFiYWpvIHNlIGRlc2Fycm9sbGEgZW4gZWwgbWFyY28gZGVsIGN1cnNvICpHZXN0acOzbiBkZSBEYXRvcyosIG9yaWVudGFkbyBhbCBwcm9ncmFtYSBkZSAgSW5nZW5pZXJpYSBJbmR1c3RyaWFsLCBlbiBlbCBzZWd1bmRvIHBlcmlvZG8gZGUgMjAyNSBlbiBsYSBVbml2ZXJzaWRhZCBkZWwgVmFsbGUsIFNlY2Npb25hbCBaYXJ6YWwuDQo8YSBuYW1lPSJzZWMxLjIiPjwvYT4NCg0KIyMjIDEuMi4gRGVzY3JpcGNpw7NuIGRlIGxvcyBkYXRvcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpFbCBjb25qdW50byBkZSBkYXRvcyB1dGlsaXphZG8gZW4gZXN0ZSBlc3R1ZGlvIGZ1ZSBwcm9wb3JjaW9uYWRvIHBvciBsYSBlbXByZXNhIGRlbCBzZWN0b3Igb2Z0YWxtb2zDs2dpY28gVmlzaW9uIDIwMjAsIGEgcGFydGlyIGRlIGxvcyByZWdpc3Ryb3MgZGUgcGFjaWVudGVzIGF0ZW5kaWRvcyBkdXJhbnRlIGVsIGHDsW8gMjAyNC4gTGEgaW5mb3JtYWNpw7NuIG9yaWdpbmFsIGZ1ZSBlbnRyZWdhZGEgZW4gdW4gYXJjaGl2byBwbGFubywgY29uIDEyNDkgcmVnaXN0cm9zIHkgcG9zdGVyaW9ybWVudGUgc29tZXRpZGEgYSB1biBwcm9jZXNvIGRlIGV4dHJhY2Npw7NuLCB0cmFuc2Zvcm1hY2nDs24geSBjYXJnYSAoRVRMKSwgZW4gZWwgY3VhbCBzZSBkZXB1cmFyb24gaW5jb25zaXN0ZW5jaWFzLCBzZSBub3JtYWxpemFyb24gZm9ybWF0b3MgeSBzZSBnZW5lcmFyb24gdmFyaWFibGVzIGRlcml2YWRhcyBwYXJhIGZhY2lsaXRhciBlbCBhbsOhbGlzaXMgZXN0YWTDrXN0aWNvLiBFbCBvYmpldGl2byBkZSBlc3RlIGNvbmp1bnRvIGVzIGNhcmFjdGVyaXphciBlbCBwZXJmaWwgdmlzdWFsIHkgZGUgaMOhYml0b3MgZGUgdXNvIGRlIHBhbnRhbGxhcyBkZSBsb3MgcGFjaWVudGVzLCBhc8OtIGNvbW8gc3UgcG9zaWJsZSByZWxhY2nDs24gY29uIGZhY3RvcmVzIGRlbW9ncsOhZmljb3MgeSBhbnRlY2VkZW50ZXMgZmFtaWxpYXJlcy4NCg0KVHJhcyBlbCBwcm9jZXNvIEVUTCBzZSBjb25zb2xpZMOzIHVuYSBiYXNlIGNvbiAxMTY2IHJlZ2lzdHJvcyAodW5vIHBvciBwYWNpZW50ZSkgeSAxMyB2YXJpYWJsZXMsIHF1ZSBjb21iaW5hbiBhc3BlY3RvcyBkZSBpZGVudGlmaWNhY2nDs24sIHNvY2lvZGVtb2dyw6FmaWNvcywgY2zDrW5pY2/igJF2aXN1YWxlcyB5IGRlIGVzdGlsbyBkZSB2aWRhLiBMYXMgdmFyaWFibGVzIHNlIGRlc2NyaWJlbiBhIGNvbnRpbnVhY2nDs24gZW4gZWwgb3JkZW4gZW4gcXVlIGFwYXJlY2VuIGVuIGxhIGJhc2UgZGUgZGF0b3MsIGluZGljYW5kbyBzdSB0aXBvIHkgZXNjYWxhIGRlIG1lZGljacOzbiBtZWRpYW50ZSBsYSBub3RhY2nDs24gKHRpcG9fZGVfdmFyaWFibGU6OmVzY2FsYV9kZV9tZWRpY2nDs25bb3JkZW5hbWllbnRvXSkuDQoNCioqUGFjX2lkKiogKGN1YW50aXRhdGl2YTo6bm9taW5hbCk6IElkZW50aWZpY2Fkb3IgbnVtw6lyaWNvIHNlY3VlbmNpYWwgcXVlIGFzaWduYSB1biBjw7NkaWdvIMO6bmljbyBhIGNhZGEgcGFjaWVudGUuIFBlcm1pdGUgcmVmZXJlbmNpYXIgbG9zIHJlZ2lzdHJvcyBzaW4gcmV2ZWxhciBkYXRvcyBwZXJzb25hbGVzIHkgbm8gdGllbmUgaW50ZXJwcmV0YWNpw7NuIG3DqXRyaWNhIHBvciBzw60gbWlzbW8uDQoNCioqRWRhZF9wYWNpZW50ZSoqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IEVkYWQgZGVsIHBhY2llbnRlIGV4cHJlc2FkYSBlbiBhw7FvcyBjdW1wbGlkb3MgYWwgbW9tZW50byBkZWwgcmVnaXN0cm8uIEVzIHVuYSB2YXJpYWJsZSBkZSByYXrDs24sIGNvbiBjZXJvIGFic29sdXRvIHkgcG9zaWJpbGlkYWQgZGUgcmVhbGl6YXIgY29tcGFyYWNpb25lcyBkZSBwcm9wb3JjaW9uZXMgZGUgZWRhZC4NCg0KKipPY3VwYWNpb24qKiAoY3VhbGl0YXRpdmE6Om5vbWluYWwpOiBQcm9mZXNpw7NuIHUgb2ZpY2lvIHByaW5jaXBhbCBkZWwgcGFjaWVudGUgKHBvciBlamVtcGxvLCBlc3R1ZGlhbnRlLCBhZG1pbmlzdHJhdGl2bywgb3BlcmFyaW8sIGluZGVwZW5kaWVudGUsIGVudHJlIG90cm9zKS4gU2UgdXRpbGl6YSBwYXJhIGNhcmFjdGVyaXphciBlbCB0aXBvIGRlIGFjdGl2aWRhZCBkaWFyaWEsIGVzcGVjaWFsbWVudGUgZW4gdMOpcm1pbm9zIGRlIGV4cG9zaWNpw7NuIHBvdGVuY2lhbCBhIHBhbnRhbGxhcy4NCg0KKipDYW5hbF9kaWZ1c2lvbioqIChjdWFsaXRhdGl2YTo6bm9taW5hbCk6IE1lZGlvIHBvciBlbCBjdWFsIGVsIHBhY2llbnRlIGNvbm9jacOzIGxhIMOzcHRpY2EgKHJlZmVyaWRvLCByZWRlcyBzb2NpYWxlcywgdm9sYW50ZSwgcGFzbyBwb3IgZWwgbG9jYWwsIGNvbnZlbmlvLCBldGMuKS4gRXN0YSB2YXJpYWJsZSBwZXJtaXRlIGlkZW50aWZpY2FyIGxvcyBjYW5hbGVzIGRlIGNhcHRhY2nDs24gbcOhcyBmcmVjdWVudGVzIGRlbnRybyBkZSBsYSBwb2JsYWNpw7NuIGF0ZW5kaWRhLg0KDQoqKkZlY2hhX3JlZ2lzdHJvKiogKGN1YWxpdGF0aXZhOjpvcmRpbmFsW3RpZW1wb10pOiBGZWNoYSBlbiBsYSBxdWUgZWwgcGFjaWVudGUgZnVlIHJlZ2lzdHJhZG8gZW4gZWwgc2lzdGVtYSwgZXhwcmVzYWRhIGNvbW8gZMOtYS9tZXMvYcOxby4gQXVucXVlIHNlIGFsbWFjZW5hIGNvbW8gdGV4dG8gbyBmZWNoYSBjYWxlbmRhcmlvLCBzdSBlc2NhbGEgZXMgb3JkaW5hbCBlbiBlbCB0aWVtcG8geSBzZSB1c2EgcGFyYSB1YmljYXIgbGEgYXRlbmNpw7NuIGRlbnRybyBkZWwgcGVyaW9kbyBkZSBlc3R1ZGlvLg0KDQoqKlBhY19zZXhvKiogKGN1YWxpdGF0aXZhOjpub21pbmFsKTogU2V4byBkZWwgcGFjaWVudGUsIHJlZ2lzdHJhZG8gdMOtcGljYW1lbnRlIGNvbW8g4oCcRmVtZW5pbm/igJ0gbyDigJxNYXNjdWxpbm/igJ0uIEVzdGEgdmFyaWFibGUgc2UgZW1wbGVhIHBhcmEgY29tcGFyYXIgcGF0cm9uZXMgZGUgYWd1ZGV6YSB2aXN1YWwgeSBow6FiaXRvcyBkZSBwYW50YWxsYSBlbnRyZSBncnVwb3MuDQoNCioqUmFuZ29fZXRhcmVvKiogKGN1YWxpdGF0aXZhOjpvcmRpbmFsKTogQ2xhc2lmaWNhY2nDs24gZGVsIHBhY2llbnRlIGVuIGdydXBvcyBkZSBlZGFkIChwb3IgZWplbXBsbywgQURPTEVTQ0VOVEUsIEpPVkVOX0FEVUxUTywgQURVTFRPLCBBRFVMVE9fTUFZT1IpLCBjb25zdHJ1aWRhIGEgcGFydGlyIGRlIGxhIHZhcmlhYmxlIGVkYWRfcGFjaWVudGUuIFByZXNlbnRhIHVuIG9yZGVuIG5hdHVyYWwgZGUgbG9zIGdydXBvcywgbG8gcXVlIHBlcm1pdGUgYW7DoWxpc2lzIHBvciBjYXRlZ29yw61hcyBldGFyaWFzLg0KDQoqKkFndWRlemFfdmlzdWFsX09EKiogKGN1YW50aXRhdGl2YTo6cmF6w7NuKTogTWVkaWRhIGRlIGxhIGFndWRlemEgdmlzdWFsIGRlbCBvam8gZGVyZWNobywgZXhwcmVzYWRhIGVuIGxhIGVzY2FsYSBlc3RhYmxlY2lkYSBwb3IgbGEgw7NwdGljYSAocG9yIGVqZW1wbG8sIGNvbnZlcnNpw7NuIGEgdW5hIG3DqXRyaWNhIGNvbnRpbnVhIGNvbXBhdGlibGUgY29uIGxhIHByw6FjdGljYSBjbMOtbmljYSkuIFZhbG9yZXMgbcOhcyBjZXJjYW5vcyBhIGxhIHJlZmVyZW5jaWEgZGUgdmlzacOzbiBub3JtYWwgaW5kaWNhbiBtZWpvciBhZ3VkZXphLCBtaWVudHJhcyBxdWUgdmFsb3JlcyBxdWUgc2UgYWxlamFuIGRlIGRpY2hvIGVzdMOhbmRhciByZXByZXNlbnRhbiBtYXlvciBjb21wcm9taXNvIHZpc3VhbC4NCg0KKipBZ3VkZXphX3Zpc3VhbF9PSSoqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IEFuw6Fsb2dhIGEgbGEgYW50ZXJpb3IsIHBlcm8gcGFyYSBlbCBvam8gaXpxdWllcmRvLiBKdW50byBjb24gbGEgYWd1ZGV6YSBkZWwgb2pvIGRlcmVjaG8sIHBlcm1pdGUgZXZhbHVhciBsYSBzaW1ldHLDrWEgbyBkaWZlcmVuY2lhcyBlbnRyZSBhbWJvcyBvam9zIHkgY29uc3RpdHV5ZSB1bmEgZGUgbGFzIHZhcmlhYmxlcyBjbMOtbmljYXMgY2VudHJhbGVzIGRlbCBlc3R1ZGlvLg0KDQoqKkhvcmFzX3BhbnRhbGxhX2RpYSoqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IE7Dum1lcm8gZGUgaG9yYXMgcHJvbWVkaW8gcXVlIGVsIHBhY2llbnRlIHBhc2EgZGlhcmlhbWVudGUgZnJlbnRlIGEgZGlzcG9zaXRpdm9zIGNvbiBwYW50YWxsYSAoY29tcHV0YWRvciwgdGVsw6lmb25vIGludGVsaWdlbnRlLCB0YWJsZXRhLCB0ZWxldmlzacOzbiwgY29uc29sYSwgZXRjLikuIEVzIHVuYSBtZWRpZGEgY29udGludWEgZGUgZXhwb3NpY2nDs24geSBzZSBjb25zaWRlcmEgdW4gcG90ZW5jaWFsIGZhY3RvciBkZSByaWVzZ28gYXNvY2lhZG8gYSBmYXRpZ2EgdmlzdWFsIHkgb3RyYXMgbW9sZXN0aWFzIG9jdWxhcmVzLg0KDQoqKkhvcmFzX2FjdGl2aWRhZGYqKiAoY3VhbnRpdGF0aXZhOjpyYXrDs24pOiBIb3JhcyBwcm9tZWRpbyBkZSBhY3RpdmlkYWQgZsOtc2ljYSBxdWUgZWwgcGFjaWVudGUgcmVhbGl6YSBhbCBkw61hIChvIGVuIHByb21lZGlvIGRpYXJpbyBhIHBhcnRpciBkZSBsYSBzZW1hbmEpLCBpbmNsdXllbmRvIGVqZXJjaWNpbyBlc3RydWN0dXJhZG8geSBhY3RpdmlkYWRlcyByZWNyZWF0aXZhcy4gRXN0YSB2YXJpYWJsZSBwZXJtaXRlIGV4cGxvcmFyIHNpIHVuIGVzdGlsbyBkZSB2aWRhIG3DoXMgYWN0aXZvIHNlIHJlbGFjaW9uYSBjb24gbWVqb3JlcyBpbmRpY2Fkb3JlcyB2aXN1YWxlcyBvIGNvbiBtZW5vciBleHBvc2ljacOzbiBhIHBhbnRhbGxhcy4NCg0KKipIb2JieV9wcmluY2lwYWxfcGFudGFsbGEqKiAoY3VhbGl0YXRpdmE6Om5vbWluYWwpOiBJbmRpY2Egc2kgZWwgcGFzYXRpZW1wbyBwcmluY2lwYWwgZGVsIHBhY2llbnRlIGltcGxpY2EgdXNvIGludGVuc2l2byBkZSBwYW50YWxsYXMgKHBvciBlamVtcGxvLCB2aWRlb2p1ZWdvcywgcmVkZXMgc29jaWFsZXMsIHNlcmllcyBlbiBzdHJlYW1pbmcpIG8gbm8uIFNlIGNvZGlmaWNhIHTDrXBpY2FtZW50ZSBjb21vIOKAnHPDreKAnSBvIOKAnG5v4oCdIHkgc2UgdXNhIHBhcmEgZGlmZXJlbmNpYXIgaG9iYmllcyBkaWdpdGFsZXMgZGUgYWN0aXZpZGFkZXMgYW5hbMOzZ2ljYXMgbyBhbCBhaXJlIGxpYnJlLg0KDQoqKlByZWRpc3Bvc2ljaW9uX2dlbmV0aWNhKiogKGN1YWxpdGF0aXZhOjpub21pbmFsKTogU2XDsWFsYSBzaSBlbCBwYWNpZW50ZSByZXBvcnRhIGFudGVjZWRlbnRlcyBmYW1pbGlhcmVzIGRlIHByb2JsZW1hcyBvZnRhbG1vbMOzZ2ljb3MgcmVsZXZhbnRlcyAobWlvcMOtYSBhbHRhLCBnbGF1Y29tYSwgZGVnZW5lcmFjacOzbiBtYWN1bGFyLCBlbnRyZSBvdHJvcykuIFNlIHJlZ2lzdHJhIGNvbW8g4oCcc8Ot4oCdIG8g4oCcbm/igJ0geSBmdW5jaW9uYSBjb21vIGFwcm94aW1hY2nDs24gYSB1biBmYWN0b3IgZGUgcmllc2dvIGdlbsOpdGljby4NCg0KRHVyYW50ZSBlbCBwcm9jZXNvIGRlIGRlcHVyYWNpw7NuIHNlIHZlcmlmaWPDsyBsYSBjb2hlcmVuY2lhIGRlIHJhbmdvcyAocG9yIGVqZW1wbG8sIGVkYWRlcyBubyBuZWdhdGl2YXMsIGhvcmFzIGRlIHBhbnRhbGxhIHkgYWN0aXZpZGFkIGbDrXNpY2EgZGVudHJvIGRlIGludGVydmFsb3MgcGxhdXNpYmxlcywgdmFsb3JlcyBkZSBhZ3VkZXphIHZpc3VhbCBkZW50cm8gZGUgbG9zIGzDrW1pdGVzIGFjZXB0YWRvcyBwb3IgbGEgZXNjYWxhIHV0aWxpemFkYSkuIExvcyB2YWxvcmVzIGZhbHRhbnRlcyBvIGNsYXJhbWVudGUgYXTDrXBpY29zIGZ1ZXJvbiByZXZpc2Fkb3MgY2FzbyBhIGNhc287IGVuIGxvcyBjYXNvcyBlbiBxdWUgbm8gZnVlIHBvc2libGUgcmVjdXBlcmFyIGluZm9ybWFjacOzbiBjb25maWFibGUsIHNlIHJlY3VycmnDsyBhIGVzdHJhdGVnaWFzIGRlIGltcHV0YWNpw7NuIG8gZXhjbHVzacOzbiBjb250cm9sYWRhLCBkb2N1bWVudGFkYXMgZW4gZWwgZmx1am8gRVRMLiBBIHBhcnRpciBkZSBlc3RlIGNvbmp1bnRvIGRlcHVyYWRvLCBzZSBkZXNhcnJvbGxhbiBsYXMgZmFzZXMgcG9zdGVyaW9yZXMgZGVsIGFuw6FsaXNpcyBtdWx0aXZhcmlhZG8sIGNlbnRyYWRhcyBlbiBsYSByZWxhY2nDs24gZW50cmUgYWd1ZGV6YSB2aXN1YWwsIGjDoWJpdG9zIGRlIHBhbnRhbGxhLCBhY3RpdmlkYWQgZsOtc2ljYSB5IGZhY3RvcmVzIGRlbW9ncsOhZmljb3MgeSBnZW7DqXRpY29zLg0KDQojIyMjIEVzdHJ1Y3R1cmEgZGVsIENvbmp1bnRvIGRlIERhdG9zIE9yaWdpbmFsDQpgYGB7ciBFc3RydWN0dXJhX2RlbF9Db25qdW50b19kZV9EYXRvc19PcmlnaW5hbCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpzdHIoY29uanVudG9fZGVfZGF0b3NfdmlzaW9uMjAyMF9PcmlnaW5hbCkNCmBgYA0KDQojIyMjIEVzdHJ1Y3R1cmEgZGVsIENvbmp1bnRvIGRlIERhdG9zIEVUTA0KYGBge3IgRXN0cnVjdHVyYV9kZWxfQ29uanVudG9fZGVfRGF0b3NfRVRMLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnN0cihjY2RfdmlzaW9uMjAyMF9FVEwpDQpgYGANCg0KDQojIyMgMS4zLiBFc3RpbWFjaW9uZXMgbXVsdGl2YXJpYWRhcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpFbCB2ZWN0b3IgZGUgbWVkaWFzIHkgbGEgbWF0cml6IGRlIHZhcmlhbnphc+KAkWNvdmFyaWFuemFzIHBlcm1pdGVuIGRlc2NyaWJpciBkZSBmb3JtYSBjb25qdW50YSBlbCBuaXZlbCB0w61waWNvLCBsYSBkaXNwZXJzacOzbiB5IGxhcyByZWxhY2lvbmVzIGxpbmVhbGVzIGVudHJlIGxhcyB2YXJpYWJsZXMgbcOpdHJpY2FzIHJlZ2lzdHJhZGFzIHBhcmEgbG9zIHBhY2llbnRlcyBkZSBsYSDDs3B0aWNhLiBFbiBlc3RlIGVzdHVkaW8gc2UgY29uc2lkZXJhbiBjb21vIHZhcmlhYmxlcyBhbGVhdG9yaWFzIGN1YW50aXRhdGl2YXM6IGVkYWRfcGFjaWVudGUsIEFndWRlemFfdmlzdWFsX09ELCBBZ3VkZXphX3Zpc3VhbF9PSSwgSG9yYXNfcGFudGFsbGFfZGlhIHkgSG9yYXNfYWYuIEVsIHZlY3RvciBkZSBtZWRpYXMgcmVzdW1lLCBwYXJhIGNhZGEgdW5hIGRlIGVzdGFzIHZhcmlhYmxlcywgZWwgdmFsb3IgcHJvbWVkaW8gb2JzZXJ2YWRvIGVuIGxhIG11ZXN0cmEsIGRlIG1vZG8gcXVlIHNpcnZlIGNvbW8gcmVmZXJlbmNpYSBkZWwg4oCccGVyZmlsIG1lZGlv4oCdIGRlIGxvcyBwYWNpZW50ZXMgZW4gdMOpcm1pbm9zIGRlIGVkYWQsIGNvbmRpY2nDs24gdmlzdWFsIHkgaMOhYml0b3MgZGUgdXNvIGRlIHBhbnRhbGxhcyB5IGRlIGFjdGl2aWRhZCBmw61zaWNhLiBMYSBtYXRyaXogZGUgdmFyaWFuemFz4oCRY292YXJpYW56YXMsIHBvciBzdSBwYXJ0ZSwgY3VhbnRpZmljYSBlbiBzdSBkaWFnb25hbCBwcmluY2lwYWwgbGEgdmFyaWFiaWxpZGFkIGluZGl2aWR1YWwgZGUgY2FkYSB2YXJpYWJsZSBhbHJlZGVkb3IgZGUgc3UgbWVkaWEsIG1pZW50cmFzIHF1ZSBlbiBsYXMgcG9zaWNpb25lcyBmdWVyYSBkZSBsYSBkaWFnb25hbCByZWNvZ2UgbGFzIGNvdmFyaWFuemFzIGVudHJlIHBhcmVzIGRlIHZhcmlhYmxlcywgbGFzIGN1YWxlcyBkZXNjcmliZW4gbGEgaW50ZW5zaWRhZCB5IGVsIHNlbnRpZG8gZGUgc3VzIHJlbGFjaW9uZXMgbGluZWFsZXMuDQoNClRyYWJhamFyIHNpbXVsdMOhbmVhbWVudGUgY29uIGVsIHZlY3RvciBkZSBtZWRpYXMgeSBsYSBtYXRyaXogZGUgdmFyaWFuemFz4oCRY292YXJpYW56YXMgcmVzdWx0YSBlc2VuY2lhbCBlbiBlbCBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvIHBvcnF1ZSBwZXJtaXRlIGNhcHR1cmFyLCBlbiB1biBzb2xvIG9iamV0byBtYXRlbcOhdGljbywgdGFudG8gbGEgdGVuZGVuY2lhIGNlbnRyYWwgY29tbyBsYXMgaW50ZXJkZXBlbmRlbmNpYXMgZW50cmUgbGFzIHZhcmlhYmxlcyBkZSBpbnRlcsOpcy4gQSBwYXJ0aXIgZGUgZXN0YXMgZXN0aW1hY2lvbmVzIGVzIHBvc2libGUgZGVyaXZhciBsYSBtYXRyaXogZGUgY29ycmVsYWNpb25lcywgcXVlIG5vcm1hbGl6YSBsYXMgY292YXJpYW56YXMgeSBmYWNpbGl0YSBjb21wYXJhciBsYSBmdWVyemEgZGUgYXNvY2lhY2nDs24gZW50cmUgdmFyaWFibGVzIG1lZGlkYXMgZW4gZXNjYWxhcyBkaWZlcmVudGVzLCBjb21vIGxhcyBob3JhcyBmcmVudGUgYSBwYW50YWxsYXMgeSBsYXMgbWVkaWRhcyBkZSBhZ3VkZXphIHZpc3VhbC4gRXN0b3MgZWxlbWVudG9zIGNvbnN0aXR1eWVuIGxhIGJhc2UgcGFyYSBsb3MgcHJvY2VkaW1pZW50b3MgcG9zdGVyaW9yZXMgZGUgYW7DoWxpc2lzIGRlIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLCBjb25nbG9tZXJhZG9zIHkgbW9kZWxvcyBkZSByZWdyZXNpw7NuLg0KDQojIyMjIFZlY3RvciBkZSBQcm9tZWRpb3MgeSBCb3hwbG90cw0KYGBge3IgVmVjdG9yX2RlX1Byb21lZGlvc195X0JveHBsb3RzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmFwcGx5KGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSwgMiwgbWVhbikNCmNjZF92aXNpb24yMDIwX0VUTF9SZWR1Y2lkbyA9IGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXQ0Kbm9tYnJlc19ib3hwbG90cyA8LSBjKCJlZGFkX3BhY2llbnRlIiwgIkFWX09EIiwgIkFWX09JIiwgIkhvcmFzX3BkIiwgIkhvcmFzX2FmIikNCnBhcihtZnJvdyA9IGMoMSwgbmNvbChjY2RfdmlzaW9uMjAyMF9FVExfUmVkdWNpZG8pKSkNCmludmlzaWJsZShsYXBwbHkoMTpuY29sKGNjZF92aXNpb24yMDIwX0VUTF9SZWR1Y2lkbyksIGZ1bmN0aW9uKGkpIHsNCiAgYm94cGxvdChjY2RfdmlzaW9uMjAyMF9FVExfUmVkdWNpZG9bLCBpXSwNCiAgICAgICAgICBtYWluID0gbm9tYnJlc19ib3hwbG90c1tpXSl9KSkNCmBgYA0KDQojIyMjIE1hdHJpeiBkZSBWYXJpYW56YXMtQ292YXJpYW56YXMNCmBgYHtyIE1hdHJpel9kZV9WYXJpYW56YXMtQ292YXJpYW56YXMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0Kcm91bmQoY292KGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSksMikNCmBgYA0KDQojIyMjIE1hdHJpeiBkZSBDb3JyZWxhY2lvbmVzDQpgYGB7ciBtYXRyaXpfZGVfQ29ycmVsYWNpb25lcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpyb3VuZChjb3IoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldKSwzKQ0KYGBgDQoNCkVsICoqdmVjdG9yIGRlIG1lZGlhcyoqIHkgbGEgKiptYXRyaXogZGUgdmFyaWFuemFzLWNvdmFyaWFuemFzKiogY29uZm9ybWFuIHVuIGNvbmp1bnRvIGRlIGhlcnJhbWllbnRhcyBmdW5kYW1lbnRhbGVzIHBhcmEgZGVzY3JpYmlyIGVsIGNvbXBvcnRhbWllbnRvIHBvc2ljaW9uYWwsIGRpc3BlcnNpdm8geSBjb3JyZWxhY2lvbmFsIGRlIGxhcyB2YXJpYWJsZXMgYWxlYXRvcmlhcyBlbiB1biBjb25qdW50byBkZSBkYXRvcy4gRXN0YXMgbWVkaWRhcyBzb24gZXNlbmNpYWxlcyBlbiBlbCBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvLCBwb3JxdWUgcGVybWl0ZW4gY2FwdHVyYXIgdGFudG8gbGEgdGVuZGVuY2lhIGNlbnRyYWwgY29tbyBsYXMgaW50ZXJkZXBlbmRlbmNpYXMgZW50cmUgbGFzIHZhcmlhYmxlcy4NCg0KIyMjIDEuNC4gR3LDoWZpY2FzIG11bHRpdmFyaWFkYXMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCkVuIGVzdGEgc2VjY2nDs24gc2UgcHJlc2VudGEgZWwgY8OhbGN1bG8gZSBpbnRlcnByZXRhY2nDs24gZGUgdHJlcyBvYmpldG9zIGZ1bmRhbWVudGFsZXM6ICoqVmVjdG9yIGRlIE1lZGlhcyoqICRcYmFyIHgkICwgKipNYXRyaXogZGUgVmFyaWFuemFzLUNvdmFyaWFuemFzKiogJFMkIHkgKipNYXRyaXogZGUgQ29ycmVsYWNpb25lcyoqICRSJC4sIGNvbnN0cnVpZG9zIGEgcGFydGlyIGRlIGxhcyB2YXJpYWJsZXMgZWRhZF9wYWNpZW50ZSwgQWd1ZGV6YV92aXN1YWxfT0QsIEFndWRlemFfdmlzdWFsX09JLCBIb3Jhc19wYW50YWxsYV9kaWEgeSBIb3Jhc19hZi4gTGEgcGVzdGHDsWEgY29ycmVzcG9uZGllbnRlIGFsIHZlY3RvciBkZSBtZWRpYXMgeSBhIGxvcyBib3hwbG90cyB1bml2YXJpYW50ZXMgcGVybWl0ZSBkZXNjcmliaXIgZWwgY29tcG9ydGFtaWVudG8gcG9zaWNpb25hbCB5IGRpc3BlcnNpdm8gZGUgY2FkYSB2YXJpYWJsZS4gRW4gdMOpcm1pbm9zIGdlbmVyYWxlcywgc2Ugb2JzZXJ2YSBzaSBsYSBkaXN0cmlidWNpw7NuIGRlIGxhIGVkYWQgZGUgbG9zIHBhY2llbnRlcyBzZSBhcHJveGltYSBhIHVuYSBmb3JtYSBhcHJveGltYWRhbWVudGUgc2ltw6l0cmljYSBvIHNpIHByZXNlbnRhIHNlc2dvcyBoYWNpYSBlZGFkZXMgbcOhcyBqw7N2ZW5lcyBvIG3DoXMgYXZhbnphZGFzLCBhc8OtIGNvbW8gZWwgcmFuZ28gdMOtcGljbyBkZSBob3JhcyBkaWFyaWFzIGZyZW50ZSBhIHBhbnRhbGxhcyB5IGRlIGFjdGl2aWRhZCBmw61zaWNhLiBEZSBpZ3VhbCBtYW5lcmEsIGxvcyBkaWFncmFtYXMgZGUgY2FqYSBkZSBsYXMgYWd1ZGV6YXMgdmlzdWFsZXMgZGVsIG9qbyBkZXJlY2hvIGUgaXpxdWllcmRvIHBlcm1pdGVuIGRldGVjdGFyIGxhIHByZXNlbmNpYSBkZSB2YWxvcmVzIGV4dHJlbW9zIHkgY29tcGFyYXIsIGRlIGZvcm1hIHZpc3VhbCwgcG9zaWJsZXMgZGlmZXJlbmNpYXMgZW50cmUgYW1ib3Mgb2pvcy4NCg0KQSBwYXJ0aXIgZGUgbGEgbWF0cml6IGRlIHZhcmlhbnphc+KAkWNvdmFyaWFuemFzIHkgZGUgbGEgbWF0cml6IGRlIGNvcnJlbGFjaW9uZXMgc2UgZXhhbWluYW4gbGFzIHJlbGFjaW9uZXMgbGluZWFsZXMgZW50cmUgbGFzIHZhcmlhYmxlcyBtw6l0cmljYXMuIExhIGluc3BlY2Npw7NuIGRlIGxvcyBjb2VmaWNpZW50ZXMgZGUgY29ycmVsYWNpw7NuIHBlcm1pdGUgaWRlbnRpZmljYXIsIHBvciBlamVtcGxvLCBzaSBleGlzdGUgdW5hIGFzb2NpYWNpw7NuIGFwcmVjaWFibGUgZW50cmUgZWwgdGllbXBvIGRlIGV4cG9zaWNpw7NuIGRpYXJpYSBhIHBhbnRhbGxhcyB5IGxhIGFndWRlemEgdmlzdWFsLCBvIGVudHJlIGxhIGVkYWQgeSBsYSBjYW50aWRhZCBkZSBob3JhcyBkZSBhY3RpdmlkYWQgZsOtc2ljYS4gVmFsb3JlcyBkZSBjb3JyZWxhY2nDs24gY2VyY2Fub3MgYSBjZXJvIGluZGljYW4gcmVsYWNpb25lcyBsaW5lYWxlcyBkw6liaWxlcyBvIGluZXhpc3RlbnRlcywgbG8gcXVlIHN1Z2llcmUgcXVlIGxhcyB2YXJpYWJsZXMgc29uIHJlbGF0aXZhbWVudGUgaW5kZXBlbmRpZW50ZXMgZGVzZGUgZWwgcHVudG8gZGUgdmlzdGEgbGluZWFsOyBwb3IgZWwgY29udHJhcmlvLCBjb2VmaWNpZW50ZXMgYWxlamFkb3MgZGUgY2VybyBzZcOxYWxhbiBhc29jaWFjaW9uZXMgcXVlIHB1ZWRlbiBzZXIgY2zDrW5pY2FtZW50ZSByZWxldmFudGVzIHkgcXVlIGNvbnZpZW5lIGV4cGxvcmFyIGVuIG1heW9yIGRldGFsbGUgZW4gZmFzZXMgcG9zdGVyaW9yZXMgZGVsIGFuw6FsaXNpcy4gRW4gY29uanVudG8sIGVzdG9zIHJlc3VsdGFkb3MgcHJvcG9yY2lvbmFuIHVuYSBwcmltZXJhIGFwcm94aW1hY2nDs24gYSBsYSBlc3RydWN0dXJhIGludGVybmEgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIHkgb3JpZW50YW4gbGEgc2VsZWNjacOzbiBkZSB0w6ljbmljYXMgbXVsdGl2YXJpYW50ZXMgYXByb3BpYWRhcyBwYXJhIGxhcyBzaWd1aWVudGVzIHNlY2Npb25lcy4NCg0KIyMjIyBEaWFncmFtYSBDb25qdW50byBkZSBEaXNwZXJzacOzbiwgRGlzdHJpYnVjacOzbiB5IENvcnJlbGFjaW9uZXNbU0FdDQpgYGB7ciBEaWFncmFtYV9Db25qdW50b19EaXNwZXJjaW9uX0Rpc3RyaWJ1Y2lvbl9Db3JyZWxhY2lvbiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpnZ3BhaXJzKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSkNCmBgYA0KDQojIyMjIERpYWdyYW1hIENvbmp1bnRvIGRlIERpc3BlcnNpw7NuLCBEaXN0cmlidWNpw7NuIHkgQ29ycmVsYWNpb25lc1tDQV0NCmBgYHtyIERpYWdyYW1hX0Nvbmp1bnRvX2RlX0Rpc3BlcmNpb25fRGlzdHJpYnVjaW9uX0NvcnJlbGFjaW9uX0NBLCBmaWcuYWxpZ249J2NlbnRlcid9DQpjY2RfdmlzaW9uMjAyMF9FVEwkcmFuZ29fZXRhcmVvIDwtIGZhY3RvcihjY2RfdmlzaW9uMjAyMF9FVEwkcmFuZ29fZXRhcmVvKQ0KbGV2ZWxzPSBjICgxLDIsMyw0LDUpDQpsYWJlbHM9IGMgKCAiRWRhZCIgLCAiQVZfT0QiICwgIkFWX09JIiAsICJIb3Jhc19wZCIgLCAiSG9yYXNfYWYiKQ0KZ2dwYWlycyhjY2RfdmlzaW9uMjAyMF9FVEwsIGNvbHVtbiA9IGMoMiw4LDksMTAsMTEpLCBhZXMoY29sb3IgPSByYW5nb19ldGFyZW8sIGFscGhhID0gMC41KSwgdXBwZXIgPSBsaXN0KGNvbnRpbnVvdXMgPSB3cmFwKCJjb3IiLCBzaXplID0gMi41KSkpDQpgYGANCg0KDQojIyMjIERpYWdyYW1hIGRlIEVzdHJlbGxhcw0KYGBge3IgRGlhZ3JhbWFfZGVfRXN0cmVsbGFzLCBmaWcuYWxpZ249J2NlbnRlcid9DQpzZXQuc2VlZCgxMjA1MjIpDQpjY2RfdmlzaW9uMjAyMF9FVExfTVVFU1RSRUFETyA9IGNjZF92aXNpb24yMDIwX0VUTFtzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksMjMpLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0NCnN0YXJzKGNjZF92aXNpb24yMDIwX0VUTF9NVUVTVFJFQURPLCBsZW4gPSAxLCBjZXggPSAwLjQsIGtleS5sb2MgPSBjKDEwLCAyKSwgZHJhdy5zZWdtZW50cyA9IFRSVUUpDQpgYGANCg0KIyMjIyBDYXJhcyBkZSBDaGVybm9mZg0KYGBge3IgQ2FyYXNfZGVfQ2hlcm5vZmYsIGZpZy5hbGlnbj0nY2VudGVyJ30NCnNldC5zZWVkKDEyMDUyMikNCmNjZF92aXNpb24yMDIwX0VUTF9NVUVTVFJFQURPID0gY2NkX3Zpc2lvbjIwMjBfRVRMIFtzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksMjMpLC1jKDExLDMsNCw1LDYsNywxMiwxMyldDQpmYWNlcyhjY2RfdmlzaW9uMjAyMF9FVExfTVVFU1RSRUFETykNCmBgYA0KDQoNCiMjIyAxLjUuIE5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkVzIHBvc2libGUgYW5hbGl6YXIgbyBkZXRlcm1pbmFyIGxhIGRpc3RyaWJ1Y2nDs24gbXVsdGl2YXJpYWRhIGRlIHVuIGNvbmp1bnRvIGRlIGRhdG9zIG1lZGlhbnRlIG3DqXRvZG9zIGRlc2NyaXB0aXZvcywgY29tbyBsb3MgZ3LDoWZpY29zLCBvIGluZmVyZW5jaWFsZXMsIGNvbW8gbGFzIHBydWViYXMgZXN0YWTDrXN0aWNhcy4gTWllbnRyYXMgcXVlIGxvcyBwcm9jZWRpbWllbnRvcyBpbmZlcmVuY2lhbGVzIHBlcm1pdGVuIG9idGVuZXIgY29uY2x1c2lvbmVzIG3DoXMgZ2VuZXJhbGl6YWJsZXMsIGxvcyBncsOhZmljb3MgcmVzdWx0YW4gw7p0aWxlcyBjb21vIHNvcG9ydGUgcGFyYSBsYSBpbnRlcnByZXRhY2nDs24gZGUgbG9zIHJlc3VsdGFkb3MuDQoNCkVuIGVzdGUgYXBhcnRhZG8gc2UgYWJvcmRhIGxhIGFwbGljYWNpw7NuIGRlIHByb2NlZGltaWVudG9zIGluZmVyZW5jaWFsZXMgcGFyYSB2ZXJpZmljYXIgc2kgZWwgY29uanVudG8gZGUgZGF0b3MgZGUgdHJhYmFqbywgcmVzcGVjdG8gYSBzdXMgdmFyaWFibGVzIG51bcOpcmljYXMsIHNpZ3VlIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEgKEROTSkuIExhcyBwcnVlYmFzIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIChQTk0pIHF1ZSBzZSBhcGxpY2Fyw6FuIHNvbjogTWFyZGlhLCBIZW56ZS1aaXJrbGVyLCBEb29ybmlrLUhhbnNlbiB5IFJveXN0b24uIEVzdGFzIHBydWViYXMgZGUgbm9ybWFsaWRhZCBzZSByZWFsaXphbiBiYWpvIHVuIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgZGV0ZXJtaW5hZG8gJFxhbHBoYSA9IDAuMDUkIHkgYSBsYXMgaGlww7N0ZXNpczokJEhfMDogXHRleHQge0xhcyB2YXJpYWJsZXMgdGllbmVuIHVuYSBETk19JCQgJCRIXzE6IFx0ZXh0IHtMYXMgdmFyaWFibGVzIE5PIHRpZW5lbiB1bmEgRE5NfSQkIA0KDQpMYSAqKnBydWViYSBkZSBNYXJkaWEqKiBzZSBmdW5kYW1lbnRhIGVuIGxhcyBleHRlbnNpb25lcyBkZSBhc2ltZXRyw61hIHkgY3VydG9zaXMsIGVsIGN1YWRyYWRvIGRlIGxhIGRpc3RhbmNpYSBkZSBNYWhhbGFub2JpcywgZWwgbsO6bWVybyBkZSB2YXJpYWJsZXMgJHAkIGEgYW5hbGl6YXIgeSBlbCBuw7ptZXJvIGRlIHJlZ2lzdHJvcyAkbiQuIEFzaW1pc21vLCBzZSBjb25zaWRlcmEgcXVlIGxhIGVzdGFkw61zdGljYSBkZSBsYSBwcnVlYmEgcGFyYSBsYSBhc2ltZXRyw61hIHNpZ3VlIHVuYSBkaXN0cmlidWNpw7NuICRcY2hpXjIkLCBtaWVudHJhcyBxdWUgbGEgZXN0YWTDrXN0aWNhIHBhcmEgbGEgY3VydG9zaXMgc2UgZGlzdHJpYnV5ZSBkZSBtYW5lcmEgYXByb3hpbWFkYSBkZSBmb3JtYSBub3JtYWwuIA0KDQpMYSAqKnBydWViYSBkZSBIZW56ZS1aaXJrbGVyKiogc2UgYmFzYSBlbiBsYSBkaXN0YW5jaWEgZnVuY2lvbmFsLCB5YSBxdWUgc2kgZWwgY29uanVudG8gZGUgZGF0b3Mgc2lndWUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYSwgZWwgZXN0YWTDrXN0aWNvIGRlIGxhIHBydWViYSBzZSBkaXN0cmlidXllIGRlIG1hbmVyYSBhcHJveGltYWRhIGNvbW8gdW5hIGxvZ25vcm1hbCwgY29uIHBhcsOhbWV0cm9zIGRlIG1lZGlhICRcbXUkIHkgdmFyaWFuemEgJFxzaWdtYV4yJC4gDQoNCkxhICoqcHJ1ZWJhIGRlIERvb3JuaWstSGFuc2VuKiogc2UgYmFzYSBlbiBsYSBhc2ltZXRyw61hIHkgbGEgY3VydG9zaXMgZGUgdW4gY29uanVudG8gZGUgZGF0b3MgbXVsdGl2YXJpYWRvcywgbG9zIGN1YWxlcyBzZSB0cmFuc2Zvcm1hbiBwYXJhIGFzZWd1cmFyIGxhIGluZGVwZW5kZW5jaWEuIFNlIGNvbnNpZGVyYSBtw6FzIHBvdGVudGUgcXVlIGxhIHBydWViYSBkZSBTaGFwaXJvLVdpbGsgZW4gY2Fzb3MgbXVsdGl2YXJpYWRvcy4gRWwgZXN0YWTDrXN0aWNvIGRlIGxhIHBydWViYSBzZSBkZWZpbmUgY29tbyBsYSBzdW1hIGRlIGxhcyB0cmFuc2Zvcm1hY2lvbmVzIGFsIGN1YWRyYWRvIGRlIGxhIGFzaW1ldHLDrWEgeSBsYSBjdXJ0b3NpcywgeSBzaWd1ZSBhcHJveGltYWRhbWVudGUgdW5hIGRpc3RyaWJ1Y2nDs24gJFxjaGleMiQuIA0KDQpQb3Igb3RybyBsYWRvLCBsYSBwcnVlYmEgZGUgUm95c3RvbiB1dGlsaXphIGxhcyAqKnBydWViYXMgZGUgU2hhcGlyby1XaWxrIG8gU2hhcGlyby1GcmFuY2lhKiogcGFyYSBldmFsdWFyIGxhIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhLiBTaSBsYSBjdXJ0b3NpcyBlcyBtYXlvciBxdWUgMywgc2UgZW1wbGVhIFNoYXBpcm8tRnJhbmNpYSBwYXJhIGRpc3RyaWJ1Y2lvbmVzIGxlcHRvY8O6cnRpY2FzLCBtaWVudHJhcyBxdWUgcGFyYSBkaXN0cmlidWNpb25lcyBwbGF0aWPDunJ0aWNhcyBzZSB1dGlsaXphIFNoYXBpcm8tV2lsay4gTG9zIHBhcsOhbWV0cm9zIGVuIGVzdGEgcHJ1ZWJhIHNlIG9idGllbmVuIG1lZGlhbnRlIGFwcm94aW1hY2lvbmVzIHBvbGlub21pYWxlcy4NCg0KIyMjIDEuNiBQbGFudGVhbWllbnRvIHkgRGVzYXJyb2xsbyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpBIHBhcnRpciBkZWwgY29uanVudG8gZGUgZGF0b3MgZGVzY3JpdG8gZW4gbGEgc2VjY2nDs24gMS4yLCBzZSBhcGxpY2EgdW5hIHBydWViYSBlc3RhZMOtc3RpY2EgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEgY29uIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgXChcYWxwaGEgPSAwLjA1XCksIGNvbiBlbCBwcm9ww7NzaXRvIGRlIGV2YWx1YXIgc2kgZWwgdmVjdG9yIGZvcm1hZG8gcG9yIGxhcyB2YXJpYWJsZXMgbcOpdHJpY2FzIHByb3ZpZW5lIGRlIHVuYSBwb2JsYWNpw7NuIGNvbiBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEuIEVuIGVzdGUgZXN0dWRpbywgbGFzIHZhcmlhYmxlcyBudW3DqXJpY2FzIGVuIGVzY2FsYSBkZSByYXrDs24gc29uOiAqKmVkYWRfcGFjaWVudGUqKiwgKipBZ3VkZXphX3Zpc3VhbF9PRCoqLCAqKkFndWRlemFfdmlzdWFsX09JKiosICoqSG9yYXNfcGFudGFsbGFfZGlhKiogeSAqKkhvcmFzX2FmKiouIEFudGVzIGRlIHJlYWxpemFyIGxhcyBwcnVlYmFzLCBlc3RhcyB2YXJpYWJsZXMgc2UgZXN0YW5kYXJpemFuIHBhcmEgZ2FyYW50aXphciBjb21wYXJhYmlsaWRhZCB5IGVzdGFiaWxpZGFkIG51bcOpcmljYSBlbiBsb3MgY8OhbGN1bG9zLg0KDQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBwcmVzZW50YSBkZSBtYW5lcmEgc2VwYXJhZGEgbG9zIHJlc3VsdGFkb3MgZGUgbGFzIHByaW5jaXBhbGVzIHBydWViYXMgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEgY29uc2lkZXJhZGFzOiBNYXJkaWEsIEhlbnpl4oCTWmlya2xlciwgRG9vcm5pa+KAk0hhbnNlbiB5IFJveXN0b24uIEVuIGxhIHBlc3Rhw7FhIGNvcnJlc3BvbmRpZW50ZSBhIGxhICoqUE5NIGRlIE1hcmRpYSoqIHNlIHJlcG9ydGFuIGxvcyBlc3RhZMOtc3RpY29zIGRlIGFzaW1ldHLDrWEgeSBjdXJ0b3NpcyBtdWx0aXZhcmlhZGFzLCBqdW50byBjb24gc3VzIHJlc3BlY3Rpdm9zIFwocFwpLXZhbG9yZXMuIERhZG8gcXVlLCBwYXJhIGFsIG1lbm9zIHVubyBkZSBlc3RvcyBjb21wb25lbnRlcywgZWwgXChwXCktdmFsb3IgcmVzdWx0YSBtZW5vciBxdWUgZWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBlc3RhYmxlY2lkbywgc2UgcHJvY2VkZSBhIHJlY2hhemFyIGxhIGhpcMOzdGVzaXMgbnVsYSBkZSBub3JtYWxpZGFkIG11bHRpdmFyaWFkYSwgY29uY2x1eWVuZG8gcXVlIGVsIGNvbmp1bnRvIGRlIHZhcmlhYmxlcyBtw6l0cmljYXMgbm8gc2lndWUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4NCg0KRGUgZm9ybWEgY29uc2lzdGVudGUsIGxhIHBlc3Rhw7FhIGFzb2NpYWRhIGEgbGEgKipQTk0gZGUgSGVuemXigJNaaXJrbGVyKiogbXVlc3RyYSB1biBcKHBcKS12YWxvciBpbmZlcmlvciBhIFwoXGFscGhhID0gMC4wNVwpLCBsbyBxdWUgbGxldmEgaWd1YWxtZW50ZSBhIHJlY2hhemFyIGxhIGhpcMOzdGVzaXMgbnVsYSB5IGFjZXB0YXIgbGEgaGlww7N0ZXNpcyBhbHRlcm5hdGl2YSBkZSBxdWUgbG9zIGRhdG9zIG5vIHByb3ZpZW5lbiBkZSB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwgbXVsdGl2YXJpYWRhLiBSZXN1bHRhZG9zIGFuw6Fsb2dvcyBzZSBvYnNlcnZhbiBlbiBsYSAqKlBOTSBkZSBEb29ybmlr4oCTSGFuc2VuKiosIGRvbmRlIGVsIFwocFwpLXZhbG9yIG9idGVuaWRvIHRhbWJpw6luIGVzIG1lbm9yIHF1ZSBlbCBuaXZlbCBkZSBzaWduaWZpY2FuY2lhLCByZWZvcnphbmRvIGxhIGRlY2lzacOzbiBkZSByZWNoYXphciBsYSBub3JtYWxpZGFkLiBGaW5hbG1lbnRlLCBsYSAqKlBOTSBkZSBSb3lzdG9uKiogcHJlc2VudGEgdW4gXChwXCktdmFsb3IgaW5mZXJpb3IgYSBcKFxhbHBoYVwpLCBjb25maXJtYW5kbyBxdWUsIGVuIGNvbmp1bnRvLCBsYXMgdmFyaWFibGVzICoqZWRhZF9wYWNpZW50ZSoqLCAqKkFndWRlemFfdmlzdWFsX09EKiosICoqQWd1ZGV6YV92aXN1YWxfT0kqKiwgKipIb3Jhc19wYW50YWxsYV9kaWEqKiB5ICoqSG9yYXNfYWYqKiBubyBzZSBhanVzdGFuIGEgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4gRW4gY29uc2VjdWVuY2lhLCB0b2RhcyBsYXMgcHJ1ZWJhcyBhcGxpY2FkYXMgY29pbmNpZGVuIGVuIHF1ZSwgYWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBjb25zaWRlcmFkbywgbm8gc2Ugc3VzdGVudGEgbGEgaGlww7N0ZXNpcyBudWxhIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIHBhcmEgZWwgdmVjdG9yIGRlIHZhcmlhYmxlcyBtw6l0cmljYXMsIGFjZXB0w6FuZG9zZSBsYSBoaXDDs3Rlc2lzIGFsdGVybmF0aXZhLg0KDQoNCiMjIyMgUE5NIE1hcmRpYQ0KYGBge3IgUE5NX01hcmRpYSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQptYXJkaWEoY2NkX3Zpc2lvbjIwMjBfRVRMWywgLWMoMTEsMyw0LDUsNiw3LDEyLDEzKV0pDQpgYGANCg0KIyMjIyBQTk0gSGVuemUtWmlya2xlcg0KYGBge3IgUE5NX0hlbnplX1ppcmtsZXIgPSAnY2VudGVyJ30NCm1oeihjY2RfdmlzaW9uMjAyMF9FVExbLCAtYygxMSwzLDQsNSw2LDcsMTIsMTMpXSkNCmBgYA0KDQojIyMjIFBOTSBNU0sNCmBgYHtyIFBOTV9NU0ssIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KbXNrKGNjZF92aXNpb24yMDIwX0VUTFssIC1jKDExLDMsNCw1LDYsNywxMiwxMyldLCBCPTEwKQ0KYGBgDQoNCiMjIyMgUE5NIG5UZXN0DQpgYGB7ciBQTk1fblRlc3QsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KbXZuVGVzdChjY2RfdmlzaW9uMjAyMF9FVExbLCAtYygxMSwzLDQsNSw2LDcsMTIsMTMpXSwgQj0xMCkNCg0KYGBgDQoNCiMjICoqRmFzZSAyIFtDb21wb25lbnRlcyBQcmluY2lwYWxlc10qKg0KDQpFbiBlc3RhICoqc2VndW5kYSBldGFwYSoqIGRlbCBlc3R1ZGlvLCBzZSBwcmVzZW50YXLDoW4gY8OhbGN1bG9zLCB2aXN1YWxpemFjaW9uZXMgZSBpbnRlcnByZXRhY2lvbmVzIGJhc2FkYXMgZW4gZWwgY29uanVudG8gZGUgZGF0b3MgYW5hbGl6YWRvIHByZXZpYW1lbnRlIGVuIGxhIFtGYXNlIDFdKCNzZWMxKS4gQWhvcmEsIGVsIGVuZm9xdWUgc2UgY2VudHJhcsOhIGVuIGVsIGFuw6FsaXNpcyBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcyAoQUNQKSBhcGxpY2FkbyBhIGxhcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcywgaW5jbHV5ZW5kbyBhc3BlY3RvcyBjb21vIGxhIHNlbGVjY2nDs24gZGUgY29tcG9uZW50ZXMsIGNhbGlkYWQgZGUgcmVwcmVzZW50YWNpw7NuLCBjb250cmlidWNpb25lcyB5IHN1IGludGVycHJldGFjacOzbi4NCg0KIyMjIDIuMS4gT2JqZXRpdm9zDQoNCkVsICoqQUNQKiogc2UgbG9ncmEgYSBsbyBsYXJnbyBkZSBsYXMgc2lndWllbnRlcyBmYXNlczogZ2VuZXJhY2nDs24gZGUgbnVldmFzIHZhcmlhYmxlcywgcmVkdWNjacOzbiBkaW1lbnNpb25hbCBkZWwgZXNwYWNpbyBkZSBsb3MgZGF0b3MsIGVsaW1pbmFjacOzbiBkZSB2YXJpYWJsZXMgZGUgcG9jbyBhcG9ydGUgZSBpbnRlcnByZXRhY2nDs24gZGUgbG9zIGNvbXBvbmVudGVzIHJlc3VsdGFudGVzIGVuIGVsIGNvbnRleHRvIGRlbCBwcm9ibGVtYSBkZWwgY3VhbCBzZSBvYnR1dmllcm9uIGxvcyBkYXRvLg0KDQpFc3RpbWFkbyBsZWN0b3IsIHNpIGRlc2VhIGV4cGxvcmFyIGxvcyBmdW5kYW1lbnRvcyBkZSBlc3RlIGFuw6FsaXNpcyBjb24gbWF5b3IgcHJvZnVuZGlkYWQuIExvcyBkZXRhbGxlcyBkZWwgY29uanVudG8gZGUgZGF0b3Mgc2UgZW5jdWVudHJhbiBkZXNjcml0b3MgZW4gbGEgW1NlY2Npw7NuIDEuMl0oI3NlYzEuMiksIG1pZW50cmFzIHF1ZSBsb3MgcHJpbmNpcGlvcyB0ZcOzcmljb3MgcXVlIHN1c3RlbnRhbiBlc3RlIGVzdHVkaW8gZXN0w6FuIGN1aWRhZG9zYW1lbnRlIGRlc2Fycm9sbGFkb3MgZW4gbGEgZGVub21pbmFkYSBbRmFzZSAxXSgjc2VjMSkuIFVuYSBsZWN0dXJhIGRldGVuaWRhIGRlIGVzdGFzIHNlY2Npb25lcyBlbnJpcXVlY2Vyw6Egc3UgY29tcHJlbnNpw7NuIHkgYXByZWNpYWNpw7NuIGRlbCB0cmFiYWpvIHByZXNlbnRhZG8uDQoNCg0KIyMjIDIuMi4gU2VsZWNjacOzbiBkZSBDb21wb25lbnRlcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpDb21vIHNlw7FhbGFuIETDrWF6IE1vcmFsZXMgeSBNb3JhbGVzIFJpdmVyYSAoMjAxMiksIGVsIEFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyAqKihBQ1ApKiogcGVybWl0ZSByZW9yZ2FuaXphciB1biBjb25qdW50byBkZSBkYXRvcyBtdWx0aXZhcmlhZG8gYWwgcmVkdWNpciBlbCBuw7ptZXJvIGRlIHZhcmlhYmxlcywgc2luIHJlcXVlcmlyIHN1cG9zaWNpb25lcyBlc3BlY8OtZmljYXMgc29icmUgbGEgZGlzdHJpYnVjacOzbiBkZSBwcm9iYWJpbGlkYWQgZGUgZXN0YXMuIEVzdGEgcmVkdWNjacOzbiBzZSBhbGNhbnphIG1lZGlhbnRlIGxhIGNyZWFjacOzbiBkZSBjb21iaW5hY2lvbmVzIGxpbmVhbGVzIGRlIGxhcyB2YXJpYWJsZXMgb3JpZ2luYWxlcywgZGlzZcOxYWRhcyBwYXJhIGNhcHRhciBsYSBtYXlvciB2YXJpYWJpbGlkYWQgcG9zaWJsZSBlbiBsb3MgZGF0b3MuIERlIGVzdGUgbW9kbywgZWwgKipBQ1AqKiBnZW5lcmEgbnVldmFzIHZhcmlhYmxlcywgZGVub21pbmFkYXMgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMsIHF1ZSBwcmVzZW50YW4gaW5kZXBlbmRlbmNpYSBlc3RhZMOtc3RpY2EgeSBhdXNlbmNpYSBkZSBjb3JyZWxhY2nDs24sIHNpZW1wcmUgYmFqbyBlbCBzdXB1ZXN0byBkZSBub3JtYWxpZGFkLg0KDQojIyMgMi4zLiBQbGFudGVhbWllbnRvIHkgRGVzYXJyb2xsbyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpBIHBhcnRpciBkZSBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIFtTZWNjacOzbiAxLjJdKCNzZWMxLjIpLCBzZSByZXF1aWVyZSBpbmljaWFsbWVudGUgZGV0ZXJtaW5hciBlbCBwb3JjZW50YWplIGRlIHZhcmlhbnphIGV4cGxpY2FkbyBwb3IgY2FkYSBkaW1lbnNpw7NuIHRyYXMgcmVhbGl6YXIgZWwgQW7DoWxpc2lzIGRlIENvbXBvbmVudGVzIFByaW5jaXBhbGVzIChBQ1ApLiBQb3N0ZXJpb3JtZW50ZSwgY29uIGJhc2UgZW4gZWwgYXV0b3ZhbG9yIHByb21lZGlvIG8gbWVkaWFudGUgdW4gZ3LDoWZpY28gZGUgc2VkaW1lbnRhY2nDs24sIHNlIGRlYmUgZGVjaWRpciBjdcOhbnRvcyBjb21wb25lbnRlcyBjb25zZXJ2YXIuDQoNCkxhIG5hdmVnYWNpw7NuIGEgdHJhdsOpcyBkZSBsYXMgcGVzdGHDsWFzIG11ZXN0cmEgcXVlIGVsIGNvbmp1bnRvIGRlIGRhdG9zLCBlbiByZWxhY2nDs24gY29uIHN1cyB2YXJpYWJsZXMgbnVtw6lyaWNhcywgcHVlZGUgc2VyIHJlcHJlc2VudGFkbyBwb3IgdW4gY29uanVudG8gbcOhcyBwZXF1ZcOxbyBkZSBkaW1lbnNpb25lcyBxdWUgcmV0aWVuZSBlbCAkNDMuMDElJCBkZSBsYSB2YXJpYWJpbGlkYWQgdG90YWwgZW4gbGFzIGRvcyBwcmltZXJhcyBkaW1lbnNpb25lcy4gRXN0ZSByZXN1bHRhZG8gc3VnaWVyZSBxdWUgbGEgdmFyaWFuemEgZXN0w6EgZGlzdHJpYnVpZGEgZGUgbWFuZXJhIHJlbGF0aXZhbWVudGUgdW5pZm9ybWUgZW50cmUgbGFzIHByaW5jaXBhbGVzIGRpbWVuc2lvbmVzLCBsbyBxdWUgaW5kaWNhIHVuYSBlc3RydWN0dXJhIGludGVybmEgZW4gbGEgcXVlIGxhcyB2YXJpYWJsZXMgb3JpZ2luYWxlcyAqKm5vIGVzdMOhbiBhbHRhbWVudGUgY29ycmVsYWNpb25hZGFzKiouIEVuIHBhcnRpY3VsYXI6DQoNCkxhICoqTWF0cml6IEFDUCoqIG11ZXN0cmEgY2luY28gZGltZW5zaW9uZXMsIGRvbmRlIGxhIHByaW1lcmEgcmV0aWVuZSBlbCAkMjIuNDklJCBkZSBsYSB2YXJpYW56YSwgc2VndWlkYSBwb3IgbGEgc2VndW5kYSBjb24gdW4gJDIwLjUyJSQsIHkgbGEgdGVyY2VyYSBjb24gdW4gJDE5Ljg1JCQlJC4gTGFzIGRvcyDDumx0aW1hcyBkaW1lbnNpb25lcyBleHBsaWNhbiB1biAkMTguODIlJCB5IHVuICQxOC4zMSUkLCByZXNwZWN0aXZhbWVudGUuIEVuIGVzdGUgc2VudGlkbywgbGEgcmVwcmVzZW50YXRpdmlkYWQgZGUgbGEgY29tYmluYWNpw7NuIGxpbmVhbCBxdWUgZGVmaW5lIGxhICoqZGltZW5zacOzbiAxKiogZXMgbW9kZXJhZGFtZW50ZSBzdXBlcmlvciBlbiBjb21wYXJhY2nDs24gY29uIGxhcyBkZW3DoXMuIENvbW8gZXN0YSBtYXRyaXogbm8gcHJvcG9yY2lvbmEgaW5mb3JtYWNpw7NuIGRpcmVjdGEgc29icmUgbGFzIHZhcmlhYmxlcyBvcmlnaW5hbGVzLCBzZSBjb250aW7DumEgZXhwbG9yYW5kbyBsYSBpZGVudGlmaWNhY2nDs24gZGUgbGFzIHZhcmlhYmxlcyBxdWUgbcOhcyBjb250cmlidXllbiBhIGxhIGRpbWVuc2nDs24gY29uIGVsIG1heW9yIHZhbG9yIHByb3Bpby4NCg0KTGEgKipNYXRyaXogZGUgQ29ycmVsYWNpb25lcyoqIGF5dWRhIGEgZGVzY3JpYmlyIGxhcyByZWxhY2lvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMgcXVlIGNvbmZvcm1hbiBsYSBkaW1lbnNpw7NuIDEuIFNlZ8O6biBlc3RhIG1hdHJpeiwgbGFzIGNvcnJlbGFjaW9uZXMgZW50cmUgbGFzIHZhcmlhYmxlcyBzb24gZW4gc3UgbWF5b3LDrWEgYmFqYXMsIGNvbiB1biB2YWxvciBtw6F4aW1vIGRlICQwLjA0JCBlbnRyZSAqKkhvcmFzX3BkKiogeSAqKmVkYWRfcGFjaWVudGUqKi4gRXN0byBpbmRpY2EgcXVlIGxhcyB2YXJpYWJsZXMgbm8gZXN0w6FuIGZ1ZXJ0ZW1lbnRlIHJlbGFjaW9uYWRhcyBlbnRyZSBzw60sIGxvIHF1ZSBwb2Ryw61hIGluZmx1aXIgZW4gY8OzbW8gY29udHJpYnV5ZW4gYSBsYSBjb21iaW5hY2nDs24gbGluZWFsIHF1ZSBkZWZpbmUgbGEgcHJpbWVyYSBkaW1lbnNpw7NuLg0KDQpMYSBwZXN0YcOxYSBWYWxvcmVzIHkgVmVjdG9yZXMgUHJvcGlvcyBwcmVzZW50YSBsb3MgcmVzdWx0YWRvcyBvYnRlbmlkb3MgYSBwYXJ0aXIgZGVsIGFuw6FsaXNpcyBkZSBsYSBtYXRyaXogZGUgY29ycmVsYWNpb25lcyBkZWwgY29uanVudG8gZGUgZGF0b3MgY2zDrW5pY29zLiBFbiBlc3RlIGFuw6FsaXNpcyBzZSB2ZXJpZmljYSBxdWUgbGEgc3VtYSBkZSBsb3MgdmFsb3JlcyBwcm9waW9zIGNvaW5jaWRlIGNvbiBlbCBuw7ptZXJvIGRlIHZhcmlhYmxlcyBhbmFsaXphZGFzLCBsbyBxdWUgZ2FyYW50aXphIHF1ZSBsYSB0b3RhbGlkYWQgZGUgbGEgdmFyaWFiaWxpZGFkIGRlbCBzaXN0ZW1hIHF1ZWRhIHJlcHJlc2VudGFkYSBwb3IgZWwgY29uanVudG8gZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuIEEgcGFydGlyIGRlIGVzdG9zIHZhbG9yZXMgcHJvcGlvcyBzZSBkZXRlcm1pbmFuIGRpcmVjdGFtZW50ZSBsYXMgcHJvcG9yY2lvbmVzIGRlIHZhcmlhbnphIGV4cGxpY2FkYSBwb3IgY2FkYSBjb21wb25lbnRlLg0KDQpQb3Igb3RyYSBwYXJ0ZSwgbGEgbWF0cml6IGRlIHZlY3RvcmVzIHByb3Bpb3MgcHJvcG9yY2lvbmEgbG9zIGNvZWZpY2llbnRlcyBxdWUgZGVmaW5lbiBsYXMgY29tYmluYWNpb25lcyBsaW5lYWxlcyBkZSBsYXMgdmFyaWFibGVzIG9yaWdpbmFsZXMgcXVlIGRhbiBsdWdhciBhIGNhZGEgY29tcG9uZW50ZSBwcmluY2lwYWwuIEVzdG9zIGNvZWZpY2llbnRlcywgdGFtYmnDqW4gY29ub2NpZG9zIGNvbW8gY2FyZ2FzIGZhY3RvcmlhbGVzLCBwZXJtaXRlbiBpZGVudGlmaWNhciBlbCBwZXNvIHkgbGEgZGlyZWNjacOzbiBkZSBsYSBjb250cmlidWNpw7NuIGRlIGNhZGEgdmFyaWFibGUgZW4gbGFzIG51ZXZhcyBkaW1lbnNpb25lcyBkZWwgYW7DoWxpc2lzLg0KDQpFbiBwYXJ0aWN1bGFyLCBwYXJhIGxhIHByaW1lcmEgY29tcG9uZW50ZSBwcmluY2lwYWwgKENQMSksIHkgY29uc2lkZXJhbmRvIGxvcyBjb2VmaWNpZW50ZXMgcmVkb25kZWFkb3MgYSBkb3MgY2lmcmFzIGRlY2ltYWxlcywgZG9uZGUgRWRhZCBjb3JyZXNwb25kZSBhIGxhIGVkYWQgZGVsIHBhY2llbnRlLCBBVl9PRCB5IEFWX09JIHJlcHJlc2VudGFuIGxhIGFndWRlemEgdmlzdWFsIGRlbCBvam8gZGVyZWNobyBlIGl6cXVpZXJkbyByZXNwZWN0aXZhbWVudGUsIEhvcmFzX1BEIGVsIHRpZW1wbyBkZSB1c28gZGUgcGFudGFsbGFzIGRpZ2l0YWxlcyB5IEhvcmFzX0FGIGxhcyBob3JhcyBkZSBhY3RpdmlkYWQgZsOtc2ljYSAodG9kYXMgdmFyaWFibGVzIHByZXZpYW1lbnRlIGVzdGFuZGFyaXphZGFzKSwgbGEgY29tcG9uZW50ZSBwdWVkZSBleHByZXNhcnNlIGNvbW86DQoNCg0KJENvbXBvbmVudGUgMSA9IDAuNDYgKiBFZGFkIOKIkiAwLjQ0ICogQVZfT0Qg4oiSIDAuNTIgKiBBVl9PSSArIDAuNTUgKiBIb3Jhc19QRCArIDAuMTYgKiBIb3Jhc19BRiQNCg0KRXN0YSBmb3JtdWxhY2nDs24gZXZpZGVuY2lhIHF1ZSBsYSBwcmltZXJhIGNvbXBvbmVudGUgZXN0w6EgcHJpbmNpcGFsbWVudGUgaW5mbHVlbmNpYWRhIHBvciBlbCB1c28gZGUgcGFudGFsbGFzIGRpZ2l0YWxlcywgbGEgZWRhZCBkZWwgcGFjaWVudGUgeSBsYSBhZ3VkZXphIHZpc3VhbCwgZXNwZWNpYWxtZW50ZSBkZWwgb2pvIGl6cXVpZXJkby4gRW4gY29uc2VjdWVuY2lhLCBlc3RhIGRpbWVuc2nDs24gcmVzdW1lIHVuIHBhdHLDs24gY2zDrW5pY28gYXNvY2lhZG8gYSBsb3MgaMOhYml0b3MgdmlzdWFsZXMgeSBzdSByZWxhY2nDs24gY29uIGxhIGZ1bmNpw7NuIHZpc3VhbCwgZmFjaWxpdGFuZG8gbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGxhcyBpbnRlcmFjY2lvbmVzIG11bHRpdmFyaWFudGVzIHByZXNlbnRlcyBlbiBsb3MgZGF0b3MuDQoNCkxvcyBncsOhZmljb3MgZGUgKipDYXR0ZWxsKiogeSAqKkNhdHRlbGwtS2Fpc2VyKiosIGNvbm9jaWRvcyBwb3Igc3VzIGZvcm1hcyBkZSBjb2RvIHkgc2VkaW1lbnRhY2nDs24sIHNvbiBoZXJyYW1pZW50YXMgw7p0aWxlcyBwYXJhIGRlY2lkaXIgY3XDoW50YXMgY29tcG9uZW50ZXMgcmV0ZW5lciBlbiB1biBhbsOhbGlzaXMgZGUgcmVkdWNjacOzbiBkZSBkaW1lbnNpw7NuLCBhc2VndXJhbmRvIHF1ZSBzZSBjb25zZXJ2ZSBzdWZpY2llbnRlIHZhcmlhYmlsaWRhZCBwYXJhIGFib3JkYXIgZWwgcHJvYmxlbWEuDQoNCkVsICoqR3LDoWZpY28gZGUgQ2F0dGVsbCoqIG11ZXN0cmEgY8OzbW8gdmFyw61hIGxhIHBlbmRpZW50ZSBlbnRyZSBsYXMgY29tcG9uZW50ZXMsIGRlc3RhY2FuZG8gcXVlIGxhIHByaW1lcmEgY29tcG9uZW50ZSB0aWVuZSB1bmEgY2FwYWNpZGFkIGV4cGxpY2F0aXZhIHNpZ25pZmljYXRpdmFtZW50ZSBtYXlvciwgZXhwbGljYW5kbyBlbCAkMjIuNSQkJSQgZGUgbGEgdmFyaWFuemEgdG90YWwuIEVzdGUgY2FtYmlvIGVuIGxhIHBlbmRpZW50ZSwgdGFtYmnDqW4gY29ub2NpZG8gY29tbyAicHVudG8gZGUgaW5mbGV4acOzbiIsIHN1Z2llcmUgcXVlIGxvcyBwcmltZXJvcyBjb21wb25lbnRlcyBzb24gY2xhdmUgcGFyYSByZXRlbmVyLCB5YSBxdWUgY2FwdHVyYW4gbGEgbWF5b3IgcGFydGUgZGUgbGEgdmFyaWFiaWxpZGFkIGRlbCBjb25qdW50byBkZSBkYXRvcy4NCg0KQWRlbcOhcywgZWwgKipHcsOhZmljbyBkZSBDYXR0ZWxsLUthaXNlcioqIGNvbWJpbmEgZXN0YSB2aXN1YWxpemFjacOzbiBjb24gZWwgY3JpdGVyaW8gZGUgS2Fpc2VyLCBxdWUgcmVjb21pZW5kYSByZXRlbmVyIGxvcyBjb21wb25lbnRlcyBjb24gdW4gdmFsb3IgcHJvcGlvIHN1cGVyaW9yIGEgMS4gU2Vnw7puIGVzdGUgY3JpdGVyaW8sIHNvbG8gbGEgcHJpbWVyYSBjb21wb25lbnRlIGN1bXBsZSBjb24gZXN0YSBjb25kaWNpw7NuLCBsbyBxdWUgaW5pY2lhbG1lbnRlIHJlc3BhbGRhIGxhIGVsZWNjacOzbiBkZSByZXRlbmVyIMO6bmljYW1lbnRlIGVzdGEuIFNpbiBlbWJhcmdvLCBhbCBjb25zaWRlcmFyIGxhIHZhcmlhbnphIGFjdW11bGFkYSwgc2Ugb2JzZXJ2YSBxdWUgbG9zIHRyZXMgcHJpbWVyb3MgY29tcG9uZW50ZXMgZXhwbGljYW4ganVudG9zIGVsICQ2Mi45JSQgZGUgbGEgdmFyaWFiaWxpZGFkLCBsbyBxdWUgc3VnaWVyZSBxdWUgaW5jbHVpciBtw6FzIGRlIHVuIGNvbXBvbmVudGUgcG9kcsOtYSBzZXIgdmFsaW9zbyBwYXJhIGNhcHR1cmFyIGRpbWVuc2lvbmVzIGFkaWNpb25hbGVzIHJlbGV2YW50ZXMgZW4gZWwgYW7DoWxpc2lzLCBlc3BlY2lhbG1lbnRlIGVuIHVuIGNvbnRleHRvIGNsw61uaWNvIGRvbmRlIGRpZmVyZW50ZXMgZmFjdG9yZXMgcHVlZGVuIGluZmx1aXIgZW4gZWwgZGlhZ25vc3RpY28gZGUgZW5mZXJtZWRhZGVzIG9jdWxhcmVzLg0KDQpQb3IgdGFudG8sIHNlIHRvbWEgbGEgZGVjaXNpw7NuIGRlIHRyYWJhamFyIGNvbiBkb3MgY29tcG9uZW50ZXMsIHlhIHF1ZSBwZXJtaXRlbiBjYXB0dXJhciBwYXRyb25lcyBpbXBvcnRhbnRlcyByZWxhY2lvbmFkb3MgY29uIGxhcyBhZmVjY2lvbmVzIGNhcmRpb3Zhc2N1bGFyZXMgc2luIGHDsWFkaXIgdW5hIGNvbXBsZWppZGFkIGlubmVjZXNhcmlhIGFsIGFuw6FsaXNpcy4gRXN0byBmYWNpbGl0YSBsYSBpbnRlcnByZXRhY2nDs24gZGUgbG9zIHJlc3VsdGFkb3MgeSBnYXJhbnRpemEgdW5hIHJlcHJlc2VudGFjacOzbiBzaWduaWZpY2F0aXZhIGRlIGxvcyBkYXRvcy4NCg0KIyMjIyBNYXRyaXogQUNQDQpgYGB7ciBNYXRyaXpfQUNQLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmdldF9laWdlbnZhbHVlKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpKQ0KYGBgDQoNCiMjIyMgTWF0cml6IGRlIENvcnJlbGFjaW9uZXMNCmBgYHtyIE1hdHJpel9kZV9Db3JyZWxhY2lvbmVzfQ0Kcm91bmQoY29yKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSksMikNCmBgYA0KDQojIyMjIFZhbG9yZXMgeSBWZWN0b3JlcyBQcm9waW9zDQpgYGB7ciBWYWxvcmVzX3lfVmVjdG9yZXNfUHJvcGlvcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpwcmluY29tcChjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIGNvciA9IFRSVUUpJHNkZXZeMg0KcHJpbmNvbXAoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBjb3IgPSBUUlVFKSRsb2FkaW5nc1sgLDE6NV0NCmBgYA0KDQojIyMjIENvcnJlbGFjaW9uZXMgQ29tcGFyYWRhcw0KYGBge3IgQ29ycmVsYWNpb25lc19Db21wYXJhZGFzLCBmaWcuYWxpZ249J2NlbnRlcid9DQpwYXIobWZyb3c9YygxLDIpKQ0KY29ycnBsb3Q6OmNvcnJwbG90KGNvcihjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0pLCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwgbnVtYmVyLmNleCA9IDAuNCkNCmNvcnJwbG90Ojpjb3JycGxvdChjb3IocHJpbmNvbXAoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBjb3IgPSBUUlVFKSRzY29yZXMpLCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwgbnVtYmVyLmNleCA9IDAuNCkNCmBgYA0KDQojIyMjIEdyw6FmaWNvIGRlIENhdHRlbGwNCmBgYHtyIEdyYWZpY29fZGVfQ2F0dGVsbCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X2VpZyhQQ0EoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBzY2FsZS51bml0ID0gVCwgZ3JhcGggPSBGKSwgYWRkbGFiZWxzID0gVCwgeWxpbT1jKDAsOTApLCBtYWluID0gIiIpDQpgYGANCg0KIyMjIyBHcsOhZmljbyBkZSBDYXR0ZWxsLUthaXNlcg0KYGBge3IgR3JhZmljb19kZV9DYXR0ZWxsX0thaXNlciwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpzY3JlZShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sZmFjdG9ycyA9IEZBTFNFLCBwYyA9IFRSVUUsIG1haW4gPSIiKQ0KYGBgDQoNCg0KIyMjIDIuNC4gQ2FsaWRhZCBkZSBSZXByZXNlbnRhY2nDs24gey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KQ29uIGJhc2UgZW4gbGEgcmVmZXJlbmNpYSBkZSAsc2UgY29uZmlybWEgcXVlLCB0cmFzIHJlZHVjaXIgbGEgZGltZW5zaW9uYWxpZGFkIGRlbCBjb25qdW50byBkZSBkYXRvcyB5IGVudGVuZGVyIHF1ZSBzdXMgdmFyaWFibGVzIGVzdGFuZGFyaXphZGFzIHNlIHJlcHJlc2VudGFuIGdyw6FmaWNhbWVudGUgY29tbyBwcm95ZWNjaW9uZXMgZGUgdW5hIGhpcGVyZXNmZXJhIGRlIGNvcnJlbGFjaW9uZXMsIGVzIGVzZW5jaWFsIGluaWNpYXIgbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGxhcyBjb21wb25lbnRlcyBhIHBhcnRpciBkZSBlc2FzIGNvcnJlbGFjaW9uZXMuIFBvc3Rlcmlvcm1lbnRlLCBzZSBkZWJlIGV2YWx1YXIgbGEgY2FsaWRhZCBkZSBsYXMgcmVwcmVzZW50YWNpb25lcyBvYnRlbmlkYXMsIGNvbnNpZGVyYW5kbyBsYSByZWR1Y2Npw7NuIGRpbWVuc2lvbmFsIGFwbGljYWRhIGFsIGNvbmp1bnRvIGRlIGRhdG9zIHkgc3UgaW1wYWN0byBlbiBsYXMgdmFyaWFibGVzLg0KDQpFcyBuZWNlc2FyaW8gZXZhbHVhciBsYSBjYWxpZGFkIGRlIGxhIHJlcHJlc2VudGFjacOzbiBkZSBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZW4gcmVsYWNpw7NuIGNvbiBlbCBuw7ptZXJvIGRlIGRpbWVuc2lvbmVzIGNhbGN1bGFkYXMgcXVlIGNhcHR1cmFuIGxhIG1heW9yIHByb3BvcmNpw7NuIGRlIHZhcmlhYmlsaWRhZDsgcGFyYSBtw6FzIGRldGFsbGVzLCBjb25zdWx0YXIgbGEgW3NlY2Npw7NuIDIuM10oI3NlYzIuMykuDQoNCiMjIyAyLjUgIERlc2Fycm9sbG8gZGVsIEFuw6FsaXNpcy4gey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KRXhwbG9yYXIgbGFzIHBlc3Rhw7FhcyByZXZlbGEgcXVlIHJlZHVjaXIgbGEgZGltZW5zaW9uYWxpZGFkIGRlbCBjb25qdW50byBkZSBkYXRvcyBwZXJtaXRlIGFuYWxpemFyIGxhIGNhbGlkYWQgZGUgbGEgcmVwcmVzZW50YWNpw7NuLCB1c2FuZG8gdW5hIGVzY2FsYSBkZSBjb250cmlidWNpb25lcyByZWxhdGl2YXMuIEVzdGEgZXNjYWxhIHNlIGJhc2EgZW4gdW4gY29jaWVudGUgZGUgcHJveWVjY2lvbmVzIGNvbiBwcm9waWVkYWRlcyBhZGl0aXZhcyB5IHVuYSBlc2NhbGEgY29udGludWEgcXVlIHZhcsOtYSBkZSAwIGEgMS4gRW4gcGFydGljdWxhcjoNCg0KDQpFbCAqKkPDrXJjdWxvIGRlIENvcnJlbGFjaW9uZXMqKiBleHByZXNhIHF1ZSBzZSBwdWVkZW4gaWRlbnRpZmljYXIgcGF0cm9uZXMgc2lnbmlmaWNhdGl2b3MgZW50cmUgbGFzIHZhcmlhYmxlcyBvcmlnaW5hbGVzLCBlbiBlbCBtYXJjbyBkZSB1bmEgc2VsZWNjacOzbiBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcy4gKipEaW1lbnNpw7NuIDEgKERpbTEpOioqIEV4cGxpY2EgZWwgJDIyLjVcJSQgZGUgbGEgdmFyaWFuemEuIE11ZXN0cmEgdW5hICoqY29ycmVsYWNpw7NuIHBvc2l0aXZhKiogY29uIHZhcmlhYmxlcyBjb21vICoqYEhvcmFzX3BkYCoqIHkgKipgZWRhZF9wYWNpZW50ZWAqKiwgbGFzIGN1YWxlcyBlc3TDoW4gb3JpZW50YWRhcyBoYWNpYSBlc3RlIGVqZSB5IGNlcmNhbmFzIGEgbGEgZnJvbnRlcmEgZGVsIGPDrXJjdWxvIHVuaXRhcmlvLiBFc3RvIGluZGljYSBxdWUgZXN0YXMgdmFyaWFibGVzICoqY29udHJpYnV5ZW4gc2lnbmlmaWNhdGl2YW1lbnRlKiogYSBsYSBjb25zdHJ1Y2Npw7NuIGRlIERpbTEsIHF1ZSBwb2Ryw61hIGVzdGFyIGNhcHR1cmFuZG8gY2FyYWN0ZXLDrXN0aWNhcyBjb211bmVzIGEgZWxsYXMuIA0KDQpQb3Igb3RyYSBwYXJ0ZSwgbGEgKipEaW1lbnNpw7NuIDIgKERpbTIpOioqIEV4cGxpY2EgZWwgJDIwLjVcJSQgZGUgbGEgdmFyaWFuemEuIEVzdMOhIGFzb2NpYWRhIGNvbiB2YXJpYWJsZXMgY29tbyAqKmBIb3Jhc19hZmAqKiwgcXVlIHRpZW5lIHVuYSAqKmFsdGEgY29ycmVsYWNpw7NuIHBvc2l0aXZhKiouIFBvciBlbCBjb250cmFyaW8sIGxhcyB2YXJpYWJsZXMgKipgQWd1ZGV6YV92aXN1YWxfT0RgKiogeSAqKmBBZ3VkZXphX3Zpc3VhbF9PSWAqKiBlc3TDoW4gY29ycmVsYWNpb25hZGFzIG5lZ2F0aXZhbWVudGUgY29uIERpbTIuIEVzdG8gc3VnaWVyZSBxdWUgRGltMiBlc3TDoSByZXByZXNlbnRhbmRvIHVuIGZlbsOzbWVubyBkaWZlcmVudGUgbyBjb21wbGVtZW50YXJpbyBhbCBkZXNjcml0byBwb3IgRGltMS4NCg0KDQoNCk90cm8gYXNwZWN0byBkZXN0YWNhYmxlIGVzIGxhIHJlbGFjacOzbiBtb3N0cmFkYSBlbnRyZSBwYXJlcyBkZSB2YXJpYWJsZXMgZW4gZWwgY8OtcmN1bG86IExhICoqQ29ycmVsYWNpw7NuIFBvc2l0aXZhIEZ1ZXJ0ZSoqIGVudHJlKipgSG9yYXNfcGRgKiogeSAqKmBlZGFkX3BhY2llbnRlYCoqIHByZXNlbnRhbiB2ZWN0b3JlcyBjZXJjYW5vcywgaW5kaWNhbmRvIHVuYSAqKnJlbGFjacOzbiBwb3NpdGl2YSoqLiBBZGVtYXMsICBkZSB0ZW5lciB1bmEgKioqQ29ycmVsYWNpw7NuIE5lZ2F0aXZhIEZ1ZXJ0ZSoqIGVudHJlICoqYEhvcmFzX3BkYCoqIHkgKipgZWRhZF9wYWNpZW50ZWAqKiBlc3TDoW4gZW4gb3Bvc2ljacOzbiBkaXJlY3RhIGEgKipgQWd1ZGV6YV92aXN1YWxfT0lgKiosIGxvIHF1ZSBpbXBsaWNhIHVuYSBmdWVydGUgY29ycmVsYWNpw7NuIG5lZ2F0aXZhLlkgdW5hICoqUG9jYSBDb3JyZWxhY2nDs24gZGUgT3J0b2dvbmFsaWRhZDoqKiBlbiB2YXJpYWJsZXMgY29tbyAqKmBIb3Jhc19hZmAqKiB5ICoqYEFndWRlemFfdmlzdWFsX09JYCoqIG11ZXN0cmFuIHZlY3RvcmVzIGNhc2kgcGVycGVuZGljdWxhcmVzLCBzdWdpcmllbmRvIHVuYSBiYWphIHJlbGFjacOzbiBlbiBlc3RlIGNvbnRleHRvIGJpZGltZW5zaW9uYWwuDQoNCkVzdGEgaW50ZXJwcmV0YWNpw7NuIHNlIGxpbWl0YSBhIGxhIGVzdHJ1Y3R1cmEgZGUgY29ycmVsYWNpb25lcyByZXByZXNlbnRhZGEgZW4gZWwgZ3LDoWZpY28geSBkZXNjcmliZSBjw7NtbyBsYXMgdmFyaWFibGVzIG9yaWdpbmFsZXMgY29udHJpYnV5ZW4gYSBsYXMgZGltZW5zaW9uZXMgcHJpbmNpcGFsZXMgc2VsZWNjaW9uYWRhcywgKipzaW4gaW1wbGljYXIgcmVsYWNpb25lcyBjYXVzYWxlcyBvIGRlIGRlcGVuZGVuY2lhIGRpcmVjdGEgZW50cmUgZWxsYXMuKioNCg0KDQpMYSAqKk1hdHJpeiBkZSBSZXByZXNlbnRhY2nDs24qKiAoJFxjb3NeMiQpIG11ZXN0cmEgbGEgY2FsaWRhZCBjb24gbGEgcXVlIGNhZGEgdmFyaWFibGUgZXMgcmVwcmVzZW50YWRhIHBvciBsYXMgZGltZW5zaW9uZXMgcHJpbmNpcGFsZXMuIEVzdGUgYW7DoWxpc2lzIHNlIGJhc2EgZW4gbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGxhIGNvcnJlbGFjacOzbiBlbnRyZSB2YXJpYWJsZXMgKEPDrXJjdWxvIGRlIENvcnJlbGFjaW9uZXMpLCBsYSBjYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbiAoJFxjb3NeMiQpLCB5IGxhIHBvc2ljacOzbiBkZSBsb3MgaW5kaXZpZHVvcyAoQ29vcmRlbmFkYXMgSW5kaXZpZHVhbGVzKSBlbiBlbCBlc3BhY2lvIGZhY3RvcmlhbDoNCg0KKipBc29jaWFjacOzbiBGdWVydGUgY29uIERpbWVuc2nDs24gMSAoRGltMSk6KiogTGFzIHZhcmlhYmxlcyAqKmBIb3Jhc19wZGAqKiAoJFxjb3NeMiA9IDAuMzM5JCkgeSAqKmBBZ3VkZXphX3Zpc3VhbF9PSWAqKiAoJFxjb3NeMiA9IDAuMzAzJCkgdGllbmVuIGxvcyB2YWxvcmVzIGRlIGNvc2VubyBjdWFkcmFkbyBtw6FzIGFsdG9zIGVuIHJlbGFjacOzbiBjb24gbGEgKipEaW1lbnNpw7NuIDEqKi4gRXN0byBpbmRpY2EgcXVlIGVzdMOhbiBmdWVydGVtZW50ZSBhc29jaWFkYXMgY29uIGVzdGUgY29tcG9uZW50ZSB5IGFwb3J0YW4gc2lnbmlmaWNhdGl2YW1lbnRlIGEgw6lsLg0KDQoqKlZhcmlhbnphIERpc3RyaWJ1aWRhIGVuIERpbWVuc2lvbmVzIFBvc3RlcmlvcmVzOioqIEVuIGNvbnRyYXN0ZSwgbGEgdmFyaWFibGUgKipgZWRhZF9wYWNpZW50ZWAqKiB0aWVuZSB1biB2YWxvciBiYWpvIGRlIGNvc2VubyBjdWFkcmFkbyBlbiBsYSAqKkRpbWVuc2nDs24gMSoqICgwLjIzNCkgeSBsYSAqKkRpbWVuc2nDs24gMioqICgwLjAwNykuIEVzdG8gc3VnaWVyZSBxdWUgc3UgdmFyaWFuemEgc2UgZGlzdHJpYnV5ZSBtw6FzIGhhY2lhIG90cmFzIGRpbWVuc2lvbmVzLCBlc3BlY2lhbG1lbnRlIGxhICoqRGltZW5zacOzbiAzKiosIGRvbmRlIG11ZXN0cmEgdW5hIG1lam9yIHJlcHJlc2VudGFjacOzbiAoMC40NzIpLiBFc3RvIGFmZWN0YSBsYSBjYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbiBkZSAqKmBlZGFkX3BhY2llbnRlYCoqIGVuIGVsIHBsYW5vIHByaW5jaXBhbCAoRGltMS9EaW0yKS4NCg0KDQpFbCBncsOhZmljbyBkZSBsYSAqKkNhbGlkYWQgZGUgUmVwcmVzZW50YWNpw7NuKiogKGNvZGlmaWNhZG8gcG9yIGNvbG9yKSBjb25maXJtYSB2aXN1YWxtZW50ZSBsYSBjb250cmlidWNpw7NuIGFsIHBsYW5vIERpbTEvRGltMi4gTG9zIGVsZW1lbnRvcyBtZWpvciByZXByZXNlbnRhZG9zIHBvciBsYXMgY29tcG9uZW50ZXMgMSB5IDIgaW5jbHV5ZW4gKipgSG9yYXNfYWZgKiogKGVsIHZlY3RvciBtw6FzIHJvam8pIHkgKipgQWd1ZGV6YV92aXN1YWxfT0RgKiogKG5hcmFuamEpLCBsbyBjdWFsIGluZGljYSBxdWUgbGEgbWF5b3IgcGFydGUgZGUgc3UgdmFyaWFuemEgZXMgZXhwbGljYWRhIHBvciBlc3RlIHBsYW5vIGJpZGltZW5zaW9uYWwuIFBvciBvdHJhIHBhcnRlLCBsYSB2YXJpYWJsZSAqKmBlZGFkX3BhY2llbnRlYCoqIHNlIG11ZXN0cmEgZW4gdW4gY29sb3IgbcOhcyBjbGFybyAoYW1hcmlsbG8pLCBjb25maXJtYW5kbyBzdSAqKmJhamEgcmVwcmVzZW50YWNpw7NuKiogZW4gZXN0ZSBwbGFubyBiaWRpbWVuc2lvbmFsLCBsbyBjdWFsIGVzIGNvaGVyZW50ZSBjb24gc3UgZnVlcnRlICRcY29zXjIkIGVuIGxhIERpbWVuc2nDs24gMy4NCg0KKiAqKlJvbGVzIERpbWVuc2lvbmFsZXM6KiogTGEgKipEaW1lbnNpw7NuIDIqKiB0aWVuZSB1bmEgZXhjZWxlbnRlIHJlcHJlc2VudGFjacOzbiBkZSAqKmBIb3Jhc19hZmAqKiAodmVjdG9yIGFsaW5lYWRvIHZlcnRpY2FsbWVudGUpLCBsbyBxdWUgaW1wbGljYSBxdWUsIGF1bnF1ZSBsYSBjb21wb25lbnRlIDEgZXMgbGEgcHJpbmNpcGFsIHBhcmEgYEhvcmFzX3BkYCwgbGEgY29tcG9uZW50ZSAyIHRhbWJpw6luIGp1ZWdhIHVuIHBhcGVsIHJlbGV2YW50ZSBlbiBsYSByZXByZXNlbnRhY2nDs24gZGUgY2llcnRvcyBhc3BlY3Rvcy4NCg0KTGFzICoqQ29vcmRlbmFkYXMgSW5kaXZpZHVhbGVzKiogcGVybWl0ZW4gaWRlbnRpZmljYXIgbG9zIHBlcmZpbGVzIGRlIGxvcyByZWdpc3Ryb3MgKHBhY2llbnRlcykgZW4gcmVsYWNpw7NuIGNvbiBsYXMgZGltZW5zaW9uZXMgcHJpbmNpcGFsZXMsIGxvIGN1YWwgZXMgY2xhdmUgcGFyYSBsYSBzZWdtZW50YWNpw7NuOg0KDQoqICoqRXh0cmVtb3MgZW4gRGltZW5zacOzbiAxIChDb3JyZWxhY2lvbmFkbyBjb24gSG9yYXMvRWRhZCk6KiogTG9zIHJlZ2lzdHJvcyAqKlwjIDYqKiAoMi40ODUpIHkgKipcIyAyKiogKDEuODY2KSB0aWVuZW4gbG9zIHZhbG9yZXMgcG9zaXRpdm9zIG3DoXMgZXh0cmVtb3MgZW4gRGltMS4gRXN0b3MgcGFjaWVudGVzIHJlcHJlc2VudGFuIHBlcmZpbGVzIGNvbiBhbHRvcyB2YWxvcmVzIGVuIGxhcyB2YXJpYWJsZXMgcG9zaXRpdmFtZW50ZSBjb3JyZWxhY2lvbmFkYXMgY29uIERpbTEsIGNvbW8gYEhvcmFzX3BkYCB5IGBlZGFkX3BhY2llbnRlYC4NCg0KKiAqKkV4dHJlbW9zIGVuIERpbWVuc2nDs24gMiAoQ29ycmVsYWNpb25hZG8gY29uIEhvcmFzX2FmKToqKiBFbiBsYSAqKmRpbWVuc2nDs24gMioqLCBsb3MgcmVnaXN0cm9zICoqXCMgNCoqICgxLjYyMikgeSAqKlwjIDE3KiogKDEuMDQ4KSBkZXN0YWNhbiBwb3Igc3VzIHZhbG9yZXMgcG9zaXRpdm9zLiBFc3RvcyBwYWNpZW50ZXMgbXVlc3RyYW4gdW4gY29tcG9ydGFtaWVudG8gc2ltaWxhciBlbiBsYSB2YXJpYWJsZSBgSG9yYXNfYWZgIChjb3JyZWxhY2lvbmFkYSBwb3NpdGl2YW1lbnRlIGNvbiBEaW0yKS4NCg0KKiAqKlBlcmZpbGVzIFByb21lZGlvIG8gTWFsIFJlcHJlc2VudGFkb3M6KiogTG9zIHJlZ2lzdHJvcyBjb24gdmFsb3JlcyBtdXkgY2VyY2Fub3MgYWwgb3JpZ2VuIChwb3IgZWplbXBsbywgKipcIyAxNCoqIGNvbiAwLjAzNCBlbiBEaW0xKSBzb24gcGVyZmlsZXMgcHJvbWVkaW8gbyBzdSB2YXJpYW56YSBlcyBleHBsaWNhZGEgcG9yIGRpbWVuc2lvbmVzIHBvc3RlcmlvcmVzLg0KDQoNCiMjIyMgQ8OtcmN1bG8gZGUgQ29ycmVsYWNpb25lcw0KYGBge3IgQ2lyY3Vsb19kZV9Db3JyZWxhY2lvbmVzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmZ2aXpfcGNhX3ZhcihQQ0EoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBzY2FsZS51bml0ID0gVCwgZ3JhcGggPSBGKSxjb2wudmFyPSIjM0I4M0JEIiwgcmVwZWwgPSBULCBjb2wuY2lyY2xlID0gIiNDRENEQ0QiLCBnZ3RoZW1lID0gdGhlbWVfYncoKSkNCmBgYA0KDQojIyMjIE1hdHJpeiBkZSBSZXByZXNlbnRhY2nDs24NCmBgYHtyIE1hdHJpel9kZV9SZXByZXNzZW50YWNpb25fQ09TMiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQooZ2V0X3BjYV92YXIoUENBKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSwgbmNwID0gNSwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRikpKSRjb3MyDQpgYGANCg0KIyMjIyBDYWxpZGFkIGRlIFJlcHJlc2VudGFjacOzbg0KYGBge3IgQ2FsaWRhZF9kZV9sYV9SZXByZXNlbnRhY2lvbiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X3BjYV92YXIoUENBKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSwgbmNwID0gNSwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNvbC52YXI9ImNvczIiLCBncmFkaWVudC5jb2xzPWMoIiMwMEFGQkIiLCIjRTdCODAwIiwiI0ZDNEUwNyIpLCByZXBlbCA9IFRSVUUpDQpgYGANCg0KIyMjIyBDb29yZGVuYWRhcyBJbmRpdmlkdWFsZXMNCmBgYHtyIENvb3JkZW5hZGFzX1JlZ2lzdHJvcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpoZWFkKChQQ0EoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBuY3AgPSA1LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSkkaW5kJGNvb3JkLCBuID0gMjNMKQ0KYGBgDQoNCiMjIyAyLjYuIENvbnRyaWJ1Y2lvbmVzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkxvcyBhdXRvcmVzICBzZcOxYWxhbiBxdWUgbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGxvcyByZXN1bHRhZG9zIGVzdMOhIGVzdHJlY2hhbWVudGUgbGlnYWRhIGFsIGPDoWxjdWxvIGRlIGVsZW1lbnRvcyBjb21vIGNvb3JkZW5hZGFzLCBjb250cmlidWNpb25lcyB5IGNvc2Vub3MgY3VhZHJhZG9zLiBQb3IgbG8gdGFudG8sIGVzIGVzZW5jaWFsIHF1ZSBsYXMgdmFyaWFibGVzIGVzdMOpbiBiaWVuIGNvbmNlcHR1YWxpemFkYXMgeSBjb250ZXh0dWFsaXphZGFzIHBhcmEgZmFjaWxpdGFyIHN1IGNvbXByZW5zacOzbi4gRW4gZXN0ZSBzZW50aWRvLCBhbmFsaXphciBsYSBjb250cmlidWNpw7NuIGRlIGNhZGEgdmFyaWFibGUgYSB1bmEgY29tcG9uZW50ZSBheXVkYSBhIGludGVycHJldGFyIGxvcyByZXN1bHRhZG9zLCBtb3N0cmFuZG8gY8OzbW8gY2FkYSB1bmEgaW5mbHV5ZSBlbiBsYSBkZWZpbmljacOzbiBkZSBsYXMgY29tcG9uZW50ZXMgZ2VuZXJhZGFzLiBFc3RlIGFuw6FsaXNpcyBzZSBsbGV2YSBhIGNhYm8gZW4gZXN0YSBzZWNjacOzbiBwYXJhIGRldGVybWluYXIgZWwgYXBvcnRlIGRlIGNhZGEgdmFyaWFibGUgZW4gbGEgY29uc3RydWNjacOzbiBkZSBsYXMgY29tcG9uZW50ZXMuDQoNCiMjIyAyLjcuIFBsYW50ZWFtaWVudG8geSBEZXNhcnJvbGxvIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkJhc2FkbyBlbiBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIFtzZWNjacOzbiAxLjJdKCNzZWMxLjIpLCBzZSByZXF1aWVyZSBkZXRlcm1pbmFyIGxhcyBjb250cmlidWNpb25lcyBkZSBjYWRhIHZhcmlhYmxlIGVuIGxhIGNvbnN0cnVjY2nDs24gZGUgbGFzIGNvbXBvbmVudGVzLg0KDQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBmYWNpbGl0YSBsYSB2aXN1YWxpemFjacOzbiBkZSBsYXMgY29udHJpYnVjaW9uZXMgZGUgbGFzIHZhcmlhYmxlcyBkZWwgY29uanVudG8gZGUgZGF0b3MgZW4gZm9ybWEgZGUgcmVwcmVzZW50YWNpb25lcyBudW3DqXJpY2FzIHkgZ3LDoWZpY2FzLCBwZXJtaXRpZW5kbyBjb21wcmVuZGVyIGPDs21vIGNhZGEgdmFyaWFibGUgaW5mbHV5ZSBlbiBsYSBjb25zdHJ1Y2Npw7NuIGRlIGxhcyBjb21wb25lbnRlcy4gRXN0byBwZXJtaXRlIGFuYWxpemFyIGxhIHByb3BvcmNpw7NuIGRlIHZhcmlhYmlsaWRhZCBxdWUgY2FkYSB2YXJpYWJsZSBhcG9ydGEgYSBsYSB2YXJpYWJpbGlkYWQgdG90YWwgZGUgbGEgY29tcG9uZW50ZSBjb24gbGEgcXVlIGVzdMOhIGFzb2NpYWRhLg0KDQpMYSAqKk1hdHJpeiBkZSBDb250cmlidWNpb25lcyoqIG11ZXN0cmEgY8OzbW8gY2FkYSB2YXJpYWJsZSBjb250cmlidXllIGEgbGEgcmV0ZW5jacOzbiBkZSB2YXJpYWJpbGlkYWQgZW4gbGEgY29uc3RydWNjacOzbiBkZSBjYWRhIGNvbXBvbmVudGUuIExvcyBkaWFncmFtYXMgZGUgYmFycmFzLCBxdWUgc2UgdmlzdWFsaXphbiBlbiBsYXMgcGVzdGHDsWFzIGRlc2RlICoqQ29udHJpYnVjaW9uZXMgYSBEMSoqIGhhc3RhICoqQ29udHJpYnVjaW9uZXMgYSBENSoqLCBpbHVzdHJhbiBsYXMgY29udHJpYnVjaW9uZXMgZXNwZWPDrWZpY2FzIGRlIGxhcyB2YXJpYWJsZXMgcGFyYSBleHBsaWNhciBsYSB2YXJpYWJpbGlkYWQgZW4gY2FkYSBjb21wb25lbnRlLiBDYWRhIGdyw6FmaWNvIGluY2x1eWUgdW5hIGzDrW5lYSBxdWUgaW5kaWNhIGxhICpjb250cmlidWNpw7NuIG1lZGlhKiwgbG8gcXVlIGZhY2lsaXRhIGxhIGlkZW50aWZpY2FjacOzbiBkZSBsYXMgdmFyaWFibGVzIHF1ZSB0aWVuZW4gbWF5b3IgaW1wYWN0byBlbiBsYSBleHBsaWNhY2nDs24gZGUgbGEgdmFyaWFiaWxpZGFkIGRlIGxvcyBjb21wb25lbnRlcy4NCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQxKiogc2UgdmlzdWFsaXphIHF1ZSBsYXMgdmFyaWFibGVzIHBvciBlbmNpbWEgZGUgbGEgY29udHJpYnVjacOzbiBtZWRpYTogKipBZ3VkZXphX3Zpc3VhbF9PSSoqIHkgKipIb3Jhc19wZCoqLHJldGllbmVuIGFwcm94aW1hZGFtZW50ZSBlbCAkNTcuMDclJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgMS4NCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQyKiogc2UgdmlzdWFsaXphIHF1ZSBsYXMgdmFyaWFibGVzIHBvciBlbmNpbWEgZGUgbGEgY29udHJpYnVjacOzbiBtZWRpYTogKipIb3Jhc19hZioqIHkgKipBZ3VkZXphX3Zpc3VhbF9PRCoqIHJldGllbmVuIGFwcm94aW1hZGFtZW50ZSBlbCAkODIuMjIlJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgMi4NCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQzKiogc2UgdmlzdWFsaXphIHF1ZSBsYXMgdmFyaWFibGVzIHBvciBlbmNpbWEgZGUgbGEgY29udHJpYnVjacOzbiBtZWRpYTogKipFZGFkX3BhY2llbnRlKiogeSAqKkFndWRlemFfdmlzdWFsX09JKiogcmV0aWVuZW4gYXByb3hpbWFkYW1lbnRlIGVsICQ2Ny41NiUkIGRlIGxhIHZhcmlhYmlsaWRhZCBkZWwgY29tcG9uZW50ZSAzLiANCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQ0Kiogc2UgdmlzdWFsaXphIHF1ZSBsYSB2YXJpYWJsZSBwb3IgZW5jaW1hIGRlIGxhIGNvbnRyaWJ1Y2nDs24gbWVkaWE6ICoqQWd1ZGV6YV92aXN1YWxfT0QqKiByZXRpZW5lIGFwcm94aW1hZGFtZW50ZSBlbCAkMjkuNTklJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgNC4NCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQ1Kiogc2UgdmlzdWFsaXphIHF1ZSBsYXMgdmFyaWFibGVzIHBvciBlbmNpbWEgZGUgbGEgY29udHJpYnVjacOzbiBtZWRpYTogKipIb3Jhc19wZCoqIHkgKipBZ3VkZXphX3Zpc3VhbF9PSSoqIHJldGllbmVuIGFwcm94aW1hZGFtZW50ZSBlbCAkNjAuOTclJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgNS4gDQoNCkNvbiBsb3MgZGF0b3MgcHJvY2VzYWRvcyBoYXN0YSBhaG9yYSBzZSBwdWVkZSBwcm9jZWRlciBjb24gbGEgaW50ZXByZXRhY2nDs24gZGUgbG9zIGNvbXBvbmVudGVzLg0KDQoNCiMjIyMgTWF0cml6IGRlIENvbnRyaWJ1Y2lvbmVzDQpgYGB7ciBNYXRyaXpfZGVfQ29udHJpYnVjaW9uZXMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KKGdldF9wY2FfdmFyKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDUsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpKSkkY29udHJpYg0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBEMQ0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzEsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDEsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBEMg0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzIsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDIsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBEMw0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDMsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBENA0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzQsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDQsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBENQ0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzUsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDUsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyAyLjguIEludGVycHJldGFjacOzbiB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpSZXByZXNlbnRhciBsb3MgcmVnaXN0cm9zIGVuIHVuIGVzcGFjaW8gZGUgZGltZW5zaW9uZXMgcmVkdWNpZGFzIHBlcm1pdGUgc2l0dWFybG9zIGVuIHVuIHBsYW5vIGRlIGZhY3RvcmVzLCBsbyBxdWUgZmFjaWxpdGEgc3UgYW7DoWxpc2lzIGUgaW50ZXJwcmV0YWNpw7NuLiBMYXMgdmFyaWFibGVzIHJlZHVjaWRhcyBzZSBjb3JyZXNwb25kZW4gY29uIGxhcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcywgcXVlIHNlIHV0aWxpemFuIGNvbW8gZWplcyBlbiBlbCBwbGFubyB5IGN1eW9zIHZhbG9yZXMgc29uIGxvcyBwdW50YWplcyBkZSBsYXMgY29tcG9uZW50ZXMuIExhIGRpc3RhbmNpYSBlbnRyZSBsb3MgcHVudG9zIHJlcHJlc2VudGFkb3MgcG9yIGVzdG9zIHB1bnRhamVzIGVzIGNsYXZlIHBhcmEgaWRlbnRpZmljYXIgc2ltaWxpdHVkZXMgZW50cmUgbG9zIHBlcmZpbGVzIGRlIGxhcyBvYnNlcnZhY2lvbmVzLiBObyBvYnN0YW50ZSwgbGFzIHNpbWlsaXR1ZGVzIHB1ZWRlbiBhcGFyZWNlciBzb2xvIGVuIGFsZ3VuYXMgdmFyaWFibGVzIHkgbm8gZW4gdG9kYXMuIEFzw60sIHNlIGJ1c2NhIHF1ZSBsYXMgZGlzdGFuY2lhcyBlbiBlbCBlc3BhY2lvIGRlIGFsdGEgZGltZW5zacOzbiBzZSBjb25zZXJ2ZW4gZW4gZWwgZXNwYWNpbyByZWR1Y2lkbywgbWFudGVuaWVuZG8gbGEgZXN0cnVjdHVyYSBkZSBsYXMgcmVsYWNpb25lcyBlbnRyZSBsb3MgZGF0b3MuIFNlZ8O6biBdLg0KDQojIyMgMi45LiBQbGFudGVhbWllbnRvIHkgRGVzYXJyb2xsbyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpMYSBuYXZlZ2FjacOzbiBlbnRyZSBsYXMgcGVzdGHDsWFzIGZhY2lsaXRhIGxhIHZpc3VhbGl6YWNpw7NuIGRlIG9iamV0b3MgZ3LDoWZpY29zIHkgbWF0cmljaWFsZXMgcXVlLCBhbCBpbnRlZ3JhciBsb3MgcmVzdWx0YWRvcyBkZSBsYXMgc2VjY2lvbmVzIGFudGVyaW9yZXMsIGZvcnRhbGVjZW4gbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGxhcyBjb250cmlidWNpb25lcyBkZSBsYXMgY29tcG9uZW50ZXMgY2FsY3VsYWRhcy4gVGFsIGNvbW8gc2UgcHJlc2VudMOzIGVuIGxhIFtzZWNjacOzbiAyLjNdKCNzZWMyLjMpLCBlbCBuw7ptZXJvIGRlIGNvbXBvbmVudGVzIHNlbGVjY2lvbmFkYXMgc2UgcmVkdWpvIGEgKipkb3MqKiwgc2lndWllbmRvIGVsIGNyaXRlcmlvIGRlIEthaXNlciB5IGNvbnNpZGVyYW5kbyBsYSB2YXJpYW56YSBhY3VtdWxhZGEuIEVzdGFzIGRvcyBjb21wb25lbnRlcyBleHBsaWNhbiBjb25qdW50YW1lbnRlIGVsICQ0My4wMSQkJSQgZGUgbGEgdmFyaWFiaWxpZGFkIGRlIGxvcyBkYXRvcywgbG8gcXVlIHBlcm1pdGUgY2FwdHVyYXIgcGF0cm9uZXMgcmVsZXZhbnRlcyBzaW4gcGVyZGVyIHNpbXBsaWNpZGFkLiBFbiBlc3RhIHNlY2Npw7NuLCBzZSBhbmFsaXphbiBsYXMgY29udHJpYnVjaW9uZXMgZXNwZWPDrWZpY2FzIGRlIGNhZGEgdmFyaWFibGUgYSBlc3RhcyBjb21wb25lbnRlcywgZGVzdGFjYW5kbyBzdSBpbXBvcnRhbmNpYSBlbiBsYSBpbnRlcnByZXRhY2nDs24gZGUgbG9zIGZhY3RvcmVzIGNsYXZlIHJlbGFjaW9uYWRvcyBjb24gbGFzIGFmZWNjaW9uZXMgY2FyZGlvdmFzY3VsYXJlcy4NCg0KTGFzIHBlc3Rhw7FhcyBkZSAqKkJpcGxvdCBkZSBWYXJpYWJsZXMgeSBSZWdpc3Ryb3MgVG90YWxlcyoqIGVuIGxhcyBjYXRlZ29yw61hcyAqKlBhY19zZXhvKiogKHNleG8gZGVsIHBhY2llbnRlKSwgKipSYW5nb19FdGFyZW8qKiAoZ3J1cG8gZXRhcmVvIGRlbCBwYWNpZW50ZSkgeSAqKkhvYmJ5X3BwYW50YWxsYXkqKiAoaG9iYnkgcXVlIGltcGxpcXVlIHVzbyBkZSBwYW50YWxsYXMpIG11ZXN0cmFuLCBjb24gYmFzZSBlbiBsYXMgYWdydXBhY2lvbmVzIHF1ZSBlc3RhcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIHB1ZWRlbiBlc3RhYmxlY2VyLCBsYSByZXByZXNlbnRhY2nDs24gZW4gZGltZW5zaW9uYWxpZGFkIHJlZHVjaWRhIGVuIGVsIHBsYW5vIGRlIGZhY3RvcmVzIGdlbmVyYWRvIHBvciBsb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuIA0KDQpFbiBlc3RlIHNlbnRpZG86DQoNCi0gTGEgYWdydXBhY2nDs24gY29uIGJhc2UgZW4gZWwgcmFuZ28gZXRhcmlvICoqKFByaW1lcmEgaW5mYW5jaWEsIE5pw7FleiwgSsOzdmVuZXMsIEFkdWx0byB5IEFkdWx0byBtYXlvcikqKiBwZXJtaXRlIG9ic2VydmFyIGPDs21vIGxhcyBkaXN0aW50YXMgZXRhcGFzIGRlbCBjaWNsbyBkZSB2aWRhIGdlbmVyYW4gdW5hIGRpc3RyaWJ1Y2nDs24gZGlmZXJlbmNpYWRhIGVuIGVsIGVzcGFjaW8gZGUgbG9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLCBlc3BlY2lhbG1lbnRlIGVuIGxhcyBkaW1lbnNpb25lcyAqKkRpbS4xKiogeSAqKkRpbS4yKiouIEVuIHBhcnRpY3VsYXIsIGxvcyBncnVwb3MgY29ycmVzcG9uZGllbnRlcyBhICoqYWR1bHRvcyBtYXlvcmVzIHRpZW5kZW4gYSBwcm95ZWN0YXJzZSBoYWNpYSB2YWxvcmVzIHBvc2l0aXZvcyBkZSBEaW0uMSoqLCBtb3N0cmFuZG8gdW5hIG1heW9yIGFzb2NpYWNpw7NuIGNvbiBsYSB2YXJpYWJsZSBlZGFkIGRlbCBwYWNpZW50ZSB5IGNvbiB2YXJpYWNpb25lcyBlbiBsYSAqKmFndWRlemEgdmlzdWFsIChBVl9PRCB5IEFWX09JKSoqLiBQb3Igc3UgcGFydGUsIGxvcyBncnVwb3MgZGUgKipwcmltZXJhIGluZmFuY2lhIHkgbmnDsWV6IHNlIGNvbmNlbnRyYW4gZW4gcmVnaW9uZXMgb3B1ZXN0YXMgZGVsIGVzcGFjaW8qKiwgbG8gcXVlIHN1Z2llcmUgcGF0cm9uZXMgdmlzdWFsZXMgeSBjb21wb3J0YW1lbnRhbGVzIGRpc3RpbnRvcyBmcmVudGUgYSBsYXMgdmFyaWFibGVzIGFuYWxpemFkYXMuDQoNCi1MYSBhZ3J1cGFjacOzbiBjb24gYmFzZSBlbiBlbCAqKnVzbyBkZSBwYW50YWxsYXMgY29tbyBob2JieSoqIChzw60gLyBubykgbXVlc3RyYSB1bmEgc2VwYXJhY2nDs24gbWVub3MgbWFyY2FkYSBlbnRyZSBsYXMgb2JzZXJ2YWNpb25lcyBlbiBlbCBlc3BhY2lvIGRlIGxvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcy4gTm8gb2JzdGFudGUsIHNlIG9ic2VydmEgcXVlIGxvcyBpbmRpdmlkdW9zIHF1ZSByZXBvcnRhbiB1c28gZGUgcGFudGFsbGFzIHByZXNlbnRhbiB1bmEgbWF5b3IgZGlzcGVyc2nDs24sIGVzcGVjaWFsbWVudGUgZW4gbGEgZGlyZWNjacOzbiBhc29jaWFkYSBhIGxhIHZhcmlhYmxlICoqSG9yYXNfcGQqKiwgbG8gcXVlIGluZGljYSBxdWUgZXN0ZSBow6FiaXRvIGludHJvZHVjZSB2YXJpYWJpbGlkYWQgYWRpY2lvbmFsIGVuIGxvcyBkYXRvcy4gRW4gY29udHJhc3RlLCBxdWllbmVzIG5vIHV0aWxpemFuIHBhbnRhbGxhcyB0aWVuZGVuIGEgY29uY2VudHJhcnNlIG3DoXMgY2VyY2EgZGVsIG9yaWdlbiwgbG8gcXVlIHN1Z2llcmUgdW5hIGluZmx1ZW5jaWEgbW9kZXJhZGEgZGUgZXN0YSB2YXJpYWJsZSBjYXRlZ8OzcmljYSBzb2JyZSBsYSBlc3RydWN0dXJhIGdsb2JhbCBkZWwgY29uanVudG8gZGUgZGF0b3MuDQoNCi1EZSBtYW5lcmEgY29tcGxlbWVudGFyaWEsIGVsIGFuw6FsaXNpcyBkZSBsb3MgdmVjdG9yZXMgZGVsIGJpcGxvdCBldmlkZW5jaWEgcXVlIGxhcyB2YXJpYWJsZXMgKipBVl9PRCoqIHkgKipBVl9PSSoqIHByZXNlbnRhbiB1bmEgYWx0YSBjb3JyZWxhY2nDs24gcG9zaXRpdmEsIHlhIHF1ZSBzZSBvcmllbnRhbiBlbiBkaXJlY2Npb25lcyBzaW1pbGFyZXMgZGVudHJvIGRlbCBlc3BhY2lvIGZhY3RvcmlhbC4gQXNpbWlzbW8sIGxhcyB2YXJpYWJsZXMgSG9yYXNfcGQgeSBIb3Jhc19hZiBtdWVzdHJhbiBvcmllbnRhY2lvbmVzIG9wdWVzdGFzLCBsbyBxdWUgaW5kaWNhIHVuYSByZWxhY2nDs24gaW52ZXJzYSBlbnRyZSBsb3MgZGlzdGludG9zIHRpcG9zIGRlIGFjdGl2aWRhZGVzIHZpc3VhbGVzLiBMYSB2YXJpYWJsZSBlZGFkIGRlbCBwYWNpZW50ZSBzZSBhc29jaWEgcHJpbmNpcGFsbWVudGUgY29uIGxhICoqRGltLjIqKiwgc3VnaXJpZW5kbyBxdWUgbGEgZWRhZCBleHBsaWNhIHVuYSBwYXJ0ZSBlc3BlY8OtZmljYSBkZSBsYSB2YXJpYWJpbGlkYWQgcXVlIG5vIGVzdMOhIGRpcmVjdGFtZW50ZSB2aW5jdWxhZGEgY29uIGxhIGFndWRlemEgdmlzdWFsLg0KDQpEZSBlc3RhIG1hbmVyYSwgbGEgcmVwcmVzZW50YWNpw7NuIGJpcGxvdCByZXNhbHRhIGxhIGNhcGFjaWRhZCBkZSB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIGNvbW8gZWwgcmFuZ28gZXRhcmlvIHBhcmEgZXN0YWJsZWNlciBhZ3J1cGFjaW9uZXMgc2lnbmlmaWNhdGl2YXMgZGVudHJvIGRlbCBlc3BhY2lvIGRlIGxvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcywgZXZpZGVuY2lhbmRvIHN1IGluZmx1ZW5jaWEgZW4gbG9zIHBhdHJvbmVzIGRlIGFndWRlemEgdmlzdWFsIHkgaMOhYml0b3MgYXNvY2lhZG9zLiBFbiBjb250cmFzdGUsIHZhcmlhYmxlcyBjb21vIGVsIHVzbyBkZSBwYW50YWxsYXMgY29tbyBob2JieSBtdWVzdHJhbiB1biBpbXBhY3RvIG3DoXMgbGltaXRhZG8sIHlhIHF1ZSBubyBnZW5lcmFuIHVuYSBzZXBhcmFjacOzbiBjbGFyYW1lbnRlIGRlZmluaWRhIGVudHJlIGxvcyBncnVwb3MsIGF1bnF1ZSBzw60gY29udHJpYnV5ZW4gYSB1bmEgbWF5b3IgZGlzcGVyc2nDs24gZGUgbGFzIG9ic2VydmFjaW9uZXMuIEVuIGNvbmp1bnRvLCBlbCBQQ0EgcGVybWl0ZSBpZGVudGlmaWNhciByZWxhY2lvbmVzIGVzdHJ1Y3R1cmFsZXMgcmVsZXZhbnRlcyBlbnRyZSBsYSBlZGFkLCBsYSBhZ3VkZXphIHZpc3VhbCB5IGxhcyBob3JhcyBkZSBhY3RpdmlkYWQgdmlzdWFsLCBwcm9wb3JjaW9uYW5kbyB1bmEgdmlzacOzbiBzaW50w6l0aWNhIHkgcm9idXN0YSBkZSBsYSB2YXJpYWJpbGlkYWQgcHJlc2VudGUgZW4gbG9zIGRhdG9zLg0KDQoNCkZpbmFsbWVudGUsIHBhcmEgZmFjaWxpdGFyIGxhIGludGVycHJldGFjacOzbiBkZSBsb3MgcHVudGFqZXMgZW4gZWwgcGxhbm8gZGVmaW5pZG8gcG9yIGxhcyBwcmltZXJhcyBkb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgKiooRGltLjEgeSBEaW0uMikqKiB5IGxhcyByZWxhY2lvbmVzIGVudHJlIHZhcmlhYmxlcywgc2UgZ2VuZXLDsyBsYSBwZXN0YcOxYSAqKkNvb3JkZW5hZGFzIEluZGl2aWR1YWxlcyoqIFtTdWJjb25qdW50byBDaGVzdFBhaW5dLiBFc3RhIHZpc3VhbGl6YWNpw7NuLCBiYXNhZGEgZW4gdW4gc3ViY29uanVudG8gZGVsICQ1JCAkJSQgWzQ3XSBkZSByZWdpc3Ryb3Mgc2VsZWNjaW9uYWRvcyBtZWRpYW50ZSBtdWVzdHJlbyBhbGVhdG9yaW8gc2ltcGxlLCBwZXJtaXRlIGV4cGxvcmFyIGxvcyBwdW50YWplcyBwb3IgY29tcG9uZW50ZXMuIEVzdGUgZW5mb3F1ZSBvZnJlY2UgdW5hIHJlcHJlc2VudGFjacOzbiBjbGFyYSB5IGNvbXByZW5zaWJsZSwgc2luIGNvbXByb21ldGVyIGxvcyBkZXRhbGxlcyBlc2VuY2lhbGVzLiBFcyBpbXBvcnRhbnRlIHNlw7FhbGFyIHF1ZSBlc3RlIHByb2NlZGltaWVudG8gdGllbmUgZmluZXMgZGUgdmlzdWFsaXphY2nDs24sIHlhIHF1ZSBlbCBjb25qdW50byBkZSBkYXRvcyBvcmlnaW5hbCwgbXVjaG8gbcOhcyBncmFuZGUgKipbOTQ3IHJlZ2lzdHJvc10qKiwgZGlmaWN1bHRhIGxhIGlkZW50aWZpY2FjacOzbiB2aXN1YWwgZGUgcGF0cm9uZXMgcmVsZXZhbnRlcy4NCg0KDQojIyMjIEJpcGxvdCBkZSBWYXJpYWJsZXMgeSBSZWdpc3Ryb3MgW2ZpbHRybzpQYWNfc2V4b10NCmBgYHtyIEJpcGxvdF9WYXJpYWJsZXNfUmVnaXN0cm9zX0ZpbHRyb19QYWNfc2V4b30NCmNjZF92aXNpb24yMDIwX0VUTCA8LSByZWFkX2V4Y2VsKCJDOlxcVXNlcnNcXEpPU0VcXERlc2t0b3BcXGdkZFxcY2NkX3Zpc2lvbjIwMjBfRVRMLnhsc3giKQ0KDQpjY2RfdmlzaW9uMjAyMF9FVExfUmVkdWNpZG8gPC0gY2NkX3Zpc2lvbjIwMjBfRVRMWw0Kc2FtcGxlKDE6bnJvdyhjY2RfdmlzaW9uMjAyMF9FVEwpLCAxMDApLA0KYygiZWRhZF9wYWNpZW50ZSIsIkFWX09EIiwiQVZfT0kiLCJIb3Jhc19wZCIsIkhvcmFzX2FmIiwicGFjX3NleG8iKQ0KXQ0KDQpjY2RfdmlzaW9uMjAyMF9FVExfUmVkdWNpZG8kcGFjX3NleG8gPC0gZmFjdG9yKGNjZF92aXNpb24yMDIwX0VUTF9SZWR1Y2lkbyRwYWNfc2V4byxsZXZlbHMgPSBjKDAsIDEpLA0KbGFiZWxzID0gYygiRmVtZW5pbm8iLCAiTWFzY3VsaW5vIikpDQoNCnJlc19wY2EgPC0gUENBKA0KY2NkX3Zpc2lvbjIwMjBfRVRMX1JlZHVjaWRvWywgYygiZWRhZF9wYWNpZW50ZSIsIkFWX09EIiwiQVZfT0kiLCJIb3Jhc19wZCIsIkhvcmFzX2FmIildLA0KbmNwID0gNSxzY2FsZS51bml0ID0gVFJVRSxncmFwaCA9IEZBTFNFKQ0KDQpmdml6X3BjYV9iaXBsb3QocmVzX3BjYSxheGVzID0gYygxLCAyKSxyZXBlbCA9IFRSVUUsaGFiaWxsYWdlID0gY2NkX3Zpc2lvbjIwMjBfRVRMX1JlZHVjaWRvJHBhY19zZXhvKQ0KYGBgDQoNCiMjIyMgQmlwbG90IGRlIFZhcmlhYmxlcyB5IFJlZ2lzdHJvcyBbZmlsdHJvOlJhbmdvIEV0YXJlb10NCmBgYHtyIEJpcGxvdF9WYXJpYWJsZXNfUmVnaXN0cm9zX0ZpbHRyb19SYW5nb19FdGFyZW99DQpsaWJyYXJ5KEZhY3RvTWluZVIpDQpsaWJyYXJ5KGZhY3RvZXh0cmEpDQpsaWJyYXJ5KHJlYWR4bCkNCg0KY2NkX3Zpc2lvbjIwMjBfRVRMIDwtIHJlYWRfZXhjZWwoIkM6XFxVc2Vyc1xcSk9TRVxcRGVza3RvcFxcZ2RkXFxjY2RfdmlzaW9uMjAyMF9FVEwueGxzeCIpDQoNCnNldC5zZWVkKDc4MDcyOSkNCg0KbXVlc3RyYV9yZSA8LSBjY2RfdmlzaW9uMjAyMF9FVExbDQpzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksIDE1MCksDQpjKCJlZGFkX3BhY2llbnRlIiwiQVZfT0QiLCJBVl9PSSIsIkhvcmFzX3BkIiwiSG9yYXNfYWYiLCJyYW5nb19ldGFyZW8iKQ0KXQ0KDQptdWVzdHJhX3JlJHJhbmdvX2V0YXJlbyA8LSBmYWN0b3IobXVlc3RyYV9yZSRyYW5nb19ldGFyZW8pDQoNCnJlc19wY2FfcmUgPC0gUENBKA0KbXVlc3RyYV9yZVssIGMoImVkYWRfcGFjaWVudGUiLCJBVl9PRCIsIkFWX09JIiwiSG9yYXNfcGQiLCJIb3Jhc19hZiIpXSwNCm5jcCA9IDUsDQpzY2FsZS51bml0ID0gVFJVRSwNCmdyYXBoID0gRkFMU0UNCikNCg0KZnZpel9wY2FfYmlwbG90KA0KcmVzX3BjYV9yZSwNCmF4ZXMgPSBjKDEsIDIpLA0KcmVwZWwgPSBUUlVFLA0KaGFiaWxsYWdlID0gbXVlc3RyYV9yZSRyYW5nb19ldGFyZW8NCikNCmBgYA0KDQoNCiMjIyMgQmlwbG90IGRlIFZhcmlhYmxlcyB5IFJlZ2lzdHJvcyBbZmlsdHJvOkhvYmJ5X3BwYW50YWxsYV0NCmBgYHtyIEJpcGxvdF9WYXJpYWJsZXNfUmVnaXN0cm9zX0ZpbHRyb19Ib2JieV9wcGFudGFsbGF9DQoNCnNldC5zZWVkKDc4MDcyOSkNCg0KbXVlc3RyYV9oYiA8LSBjY2RfdmlzaW9uMjAyMF9FVExbDQpzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksIDE1MCksDQpjKCJlZGFkX3BhY2llbnRlIiwiQVZfT0QiLCJBVl9PSSIsIkhvcmFzX3BkIiwiSG9yYXNfYWYiLCJIb2JieV9wcGFudGFsbGEiKQ0KXQ0KDQptdWVzdHJhX2hiJEhvYmJ5X3BwYW50YWxsYSA8LSBmYWN0b3IoDQptdWVzdHJhX2hiJEhvYmJ5X3BwYW50YWxsYSwNCmxldmVscyA9IGMoIm5vIiwic2kiKSAjIGFqdXN0YSBzZWfDum4gY29kaWZpY2FjacOzbiByZWFsDQopDQoNCnJlc19wY2FfaGIgPC0gUENBKA0KbXVlc3RyYV9oYlssIGMoImVkYWRfcGFjaWVudGUiLCJBVl9PRCIsIkFWX09JIiwiSG9yYXNfcGQiLCJIb3Jhc19hZiIpXSwNCm5jcCA9IDUsDQpzY2FsZS51bml0ID0gVFJVRSwNCmdyYXBoID0gRkFMU0UNCikNCg0KZnZpel9wY2FfYmlwbG90KA0KcmVzX3BjYV9oYiwNCmF4ZXMgPSBjKDEsIDIpLA0KcmVwZWwgPSBUUlVFLA0KaGFiaWxsYWdlID0gbXVlc3RyYV9oYiRIb2JieV9wcGFudGFsbGENCikNCmBgYA0KDQojIyAqKkZhc2UgMyBbQ29ycmVzcG9uZGVuY2lhc10qKg0KDQojIyMgMy4xLiBPYmpldGl2b3MNCg0KRW4gZXN0YSB0ZXJjZXJhIGZhc2UgZGVsIGVzdHVkaW8sIHNlIHByZXNlbnRhcsOhbiBjw6FsY3Vsb3MsIHZpc3VhbGl6YWNpb25lcyBlIGludGVycHJldGFjaW9uZXMgYmFzYWRhcyBlbiBlbCBjb25qdW50byBkZSBkYXRvcyB0cmFiYWphZG8gZW4gbGEgW2Zhc2UgMV0oI3NlYzEpIHkgW2Zhc2UgMl0oI3NlYzIpLiBTaW4gZW1iYXJnbywgZXN0YSBmYXNlIHNlIGVuZm9jYXLDoSBlbiBhcGxpY2FyIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIHNpbXBsZXMgeSBtw7psdGlwbGVzIHNvYnJlIGxhcyB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzLCBhYmFyY2FuZG8gbGEgY29uc3RydWNjacOzbiBkZSB0YWJsYXMgZGUgY29udGluZ2VuY2lhIHkgZGlzeXVudGl2YXMgY29tcGxldGFzLCBhc8OtIGNvbW8gbGEgZXZhbHVhY2nDs24gZGUgY2FsaWRhZGVzIGRlIHJlcHJlc2VudGFjacOzbiwgY29udHJpYnVjaW9uZXMgZSBpbnRlcnByZXRhY2lvbmVzLg0KDQojIyMgMy4yLiBDb3JyZXNwb25kZW5jaWFzIFNpbXBsZXMNCg0KU2Vnw7puIFtAQU1BUkFsZGFzLVVyaWVsMmVkXSxlbCAqKmFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzKiogc2ltcGxlICoqKEFDUykqKiB0aWVuZSBjb21vIHByb3DDs3NpdG8gcmVkdWNpciBsYSBkaW1lbnNpb25hbGlkYWQgZGUgbGFzIHJlbGFjaW9uZXMgZW50cmUgY2F0ZWdvcsOtYXMgZGUgZG9zIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMsIHJlcHJlc2VudMOhbmRvbGFzIGVuIHVuIGVzcGFjaW8gbXVsdGlkaW1lbnNpb25hbC4gRXN0ZSBtw6l0b2RvIHBlcm1pdGUgYW5hbGl6YXIgZ3LDoWZpY2FtZW50ZSBsYXMgZGlzdGFuY2lhcyBlbnRyZSBsYXMgY2F0ZWdvcsOtYXMgZGUgbGFzIHZhcmlhYmxlcywgZmFjaWxpdGFuZG8gbGEgaW50ZXJwcmV0YWNpw7NuIGRlIHRhYmxhcyBkZSBjb250aW5nZW5jaWEuIEVsIG7Dum1lcm8gbcOheGltbyBkZSBkaW1lbnNpb25lcyBuZWNlc2FyaWFzIHBhcmEgZXhwbGljYXIgZGljaGFzIHJlbGFjaW9uZXMgY29ycmVzcG9uZGUgYSB1bm8gbWVub3MgZWwgbsO6bWVybyBkZSBjYXRlZ29yw61hcyBkZSBsYSB2YXJpYWJsZSBjb24gbWVub3IgY2FudGlkYWQgZGUgbml2ZWxlcy4NCg0KQXNpbWlzbW8sIGVsICoqQUNTKiosIGJhc2FkbyBlbiB0YWJsYXMgZGUgY29udGluZ2VuY2lhLCBwdWVkZSBhbXBsaWFyc2UgcGFyYSBpbmNsdWlyIG3DoXMgZGUgZG9zIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMsIGxvIHF1ZSBzZSBjb25vY2UgY29tbyAqKkFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIG3Dumx0aXBsZXMgKEFDTSkqKi4gRXN0ZSBlbmZvcXVlIHV0aWxpemEgdW5hIHRhYmxhIGRpc3l1bnRpdmEgY29tcGxldGEsIHBlcm1pdGllbmRvIGV4cGxvcmFyIHkgcmVwcmVzZW50YXIgcmVsYWNpb25lcyBtw6FzIGNvbXBsZWphcyBlbnRyZSBtw7psdGlwbGVzIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMuDQoNCiMjIyAzLjMuIENvcnJlc3BvbmRlbmNpYXMgTcO6bHRpcGxlcw0KDQojIyAqKkZhc2UgNCBbQ29uZ2xvbWVyYWRvc10qKg0KDQojIyMgNC4xLiBPYmpldGl2b3MNCg0KRW4gZXN0YSAqKmN1YXJ0YSBldGFwYSoqIGRlbCBlc3R1ZGlvIHNlIHByZXNlbnRhcsOhbiBjw6FsY3Vsb3MsIHZpc3VhbGl6YWNpb25lcyBlIGludGVycHJldGFjaW9uZXMsIHV0aWxpemFuZG8gZWwgY29uanVudG8gZGUgZGF0b3MgcHJvY2VzYWRvIGVuIGxhcyBmYXNlcyBwcmV2aWFzICoqKDEsIDIgeSAzKSoqLiBFbCBlbmZvcXVlIHNlIGNlbnRyYXLDoSBlbiBlbCAqKmFuw6FsaXNpcyBkZSBjb25nbG9tZXJhZG9zKiosIGFiYXJjYW5kbyB0YW50byBzdSB2ZXJzacOzbiBqZXLDoXJxdWljYSBtZWRpYW50ZSBkZW5kcm9ncmFtYXMgY29tbyBsYSBubyBqZXLDoXJxdWljYSBjb24gSy1tZWRpYXMuDQoNCiMjIyA0LjIuIEFncnVwYWNpw7NuIEplcsOhcnF1aWNhIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkVsIFByb2Zlc29yIFtARUFNT1RJbW80MjAyM10sIGVuIHN1IHRyYWJham8gKGFsIHF1ZSBzZSBwdWVkZW4gcmVtaXRpciBtZWRpYW50ZSBlbCBlbmxhY2UpLCBzZcOxYWxhYmEgcXVlIGxvcyBhdXRvcmVzIFtAQUVETURpYXotTW9yYWxlczFlZF0sIGJhc8OhbmRvc2UgZW4gZWwgYW7DoWxpc2lzIGRlICpFdmVyaXR0ICgxOTgwKSogdGl0dWxhZG8gKipDbHVzdGVyIEFuYWx5c2lzKiosIGRlc2NyaWJlbiBsb3MgY29uZ2xvbWVyYWRvcyBjb21vICoqem9uYXMgY29udGludWFzKiogZW4gdW4gZXNwYWNpbyBkb25kZSBzZSBjb25jZW50cmEgdW5hIGFsdGEgZGVuc2lkYWQgZGUgcHVudG9zLCBzZXBhcmFkYXMgcG9yIMOhcmVhcyBjb24gbWVub3IgZGVuc2lkYWQuIFBhcmEgaWRlbnRpZmljYXIgZXN0YXMgY29uY2VudHJhY2lvbmVzLCBzZSBlbXBsZWFuIGRpZmVyZW50ZXMgdMOpY25pY2FzLCBkZXN0YWPDoW5kb3NlIGxvcyBtw6l0b2RvcyBqZXLDoXJxdWljb3MuIEVzdG9zIGluaWNpYW4gY29uIGVsICoqY8OhbGN1bG8gZGUgdW5hIG1hdHJpeiBkZSBkaXN0YW5jaWFzKiogZW50cmUgbG9zIGVsZW1lbnRvcyBhbmFsaXphZG9zLCBsbyBxdWUgcGVybWl0ZSBhZ3J1cGFybG9zIG1lZGlhbnRlIHVuIHByb2Nlc28gZGUgKiphZ2xvbWVyYWNpw7NuKiouIEVzdGUgbcOpdG9kbyBjb21pZW56YSBjb24gKipjb25nbG9tZXJhZG9zIGluZGl2aWR1YWxlcyoqIHkgYXZhbnphIGhhY2lhIHVuICoqw7puaWNvIGdydXBvIGZpbmFsKiouIEEgbG8gbGFyZ28gZGUgZXN0ZSBwcm9jZXNvLCBzZSBnZW5lcmFuIGZ1c2lvbmVzIHkgZGl2aXNpb25lcyBxdWUgZXN0YWJsZWNlbiBqZXJhcnF1w61hcyBiYXNhZGFzIGVuIHNpbWlsaXR1ZGVzLCByZXByZXNlbnRhZGFzIGdyw6FmaWNhbWVudGUgYSB0cmF2w6lzIGRlIHVuICoqZGVuZG9ncmFtYSoqLg0KDQojIyMgNC4zLiBBZ3J1cGFjacOzbiBOby1KZXLDoXJxdWljYQ0KDQojIyAqKkZhc2UgNSBbUmVncmVzaW9uZXNdKioNCg0KIyMjIDUuMS4gT2JqZXRpdm9zDQoNCkVzdGUgZXN0dWRpbyB0aWVuZSBjb21vIHByb3DDs3NpdG8gZXN0YWJsZWNlciBsYSAqKnJlbGFjacOzbiBlbnRyZSBkb3MgbyBtw6FzIHZhcmlhYmxlcyoqIG1lZGlhbnRlIGxhIG9idGVuY2nDs24gZGUgaW5mb3JtYWNpw7NuIHNvYnJlIHVuYSBkZSBlbGxhcywgYmFzYWRhIGVuIGVsIGNvbm9jaW1pZW50byBkZSBsb3MgdmFsb3JlcyBkZSBsYXMgb3RyYXMuIExhcyByZWxhY2lvbmVzIGVzdGFibGVjaWRhcyBzb24gZGUgY2Fyw6FjdGVyICoqbm8gZGV0ZXJtaW7DrXN0aWNvKiosIGVzIGRlY2lyLCBzZSBwbGFudGVhcsOhbiByZWxhY2lvbmVzIHByb2JhYmlsw61zdGljYXMgeSBzZSBpbXBsZW1lbnRhcsOhbiBwcm9jZWRpbWllbnRvcyBwYXJhIHJlYWxpemFyIGluZmVyZW5jaWFzIHNvYnJlIGxvcyBtb2RlbG9zIHV0aWxpemFkb3MuIEFkZW3DoXMsIHNlIG9idGVuZHLDoW4gbWVkaWRhcyBjdWFudGl0YXRpdmFzIHF1ZSBpbmRpcXVlbiBlbCBncmFkbyBkZSByZWxhY2nDs24gZW50cmUgbGFzIHZhcmlhYmxlcy4gTG9zIG1vZGVsb3MgY29uc2lkZXJhZG9zIGVuIGVzdGUgdHJhYmFqbyBjb3JyZXNwb25kZW4gYSBjYXNvcyBlc3BlY8OtZmljb3MgZGVsIG1vZGVsbyBsaW5lYWwgZ2VuZXJhbGl6YWRvOiAqKlJlZ3Jlc2nDs24gTGluZWFsIFNpbXBsZSoqLCAqKlJlZ3Jlc2nDs24gTGluZWFsIE3Dumx0aXBsZSoqIHkgKipSZWdyZXNpw7NuIExvZ8Otc3RpY2EqKi4gQ2FkYSBtb2RlbG8gc2Vyw6EgZGVzY3JpdG8gdGXDs3JpY2FtZW50ZSBlbiBzdSByZXNwZWN0aXZhIHNlY2Npw7NuLCB5IHNlIGFwbGljYXLDoSBhIHVuIGNvbmp1bnRvIGRlIGRhdG9zIGVzcGVjw61maWNvIGRlc2NyaXRvIGVuIGxhIFtzZWNjacOzbiAyXSgjc2VjMikuIA0KDQpMYSBlc3RydWN0dXJhIHkgcmVmZXJlbmNpYXMgcHJpbmNpcGFsZXMgc2UgYmFzYW4gZW4gZWwgRXN0dWRpbyBkZSAqKkFuw6FsaXNpcyBNdWx0aXZhcmlhZG8qKiBkZWwgcHJvZmVzb3IgW0BFQU1PVEltbzQyMDIzXS4gQWRlbcOhcywgc2UgdXRpbGl6YXJvbiBsaWJyb3MgY29tbyAqUHJvYmFiaWxpZGFkIHkgZXN0YWTDrXN0aWNhIHBhcmEgaW5nZW5pZXLDrWEgaW5kdXN0cmlhbCogZGUgW0BQRURldm9yZTdlZF0sICpBbsOhbGlzaXMgZXN0YWTDrXN0aWNvIGRlIGRhdG9zIG11bHRpdmFyaWFkb3MqIGRlIFtAQUVETURpYXotTW9yYWxlczFlZF0sIHkgKkFuw6FsaXNpcyBtdWx0aXZhcmlhbnRlIGFwbGljYWRvIGNvbiBSKiBkZSBbQEFNQVJBbGRhcy1VcmllbDJlZF0sIHF1ZSBwcm9wb3JjaW9uYXJvbiBmdW5kYW1lbnRvcyBjbGF2ZSBwYXJhIGVzdGUgYW7DoWxpc2lzLg0KDQoNClBhcmEgZmluZXMgZGUgdmlzdWFsaXphY2nDs24sIHNlIGNyZcOzIHVuIGFwYXJ0YWRvIGVzcGVjw61maWNvIHBhcmEgZWwgZGljY2lvbmFyaW8gZGUgdmFyaWFibGVzLiBBc2ltaXNtbywgc2UgYWNsYXJhIHF1ZSBzZSBwdWVkZSBjb25zdWx0YXIgZWwgZGljY2lvbmFyaW8gZGUgdmFyaWFibGVzIGV4dGVuZGlkbyBlbiBsYSBbc2VjY2nDs24gMS4yXSgjc2VjMS4yKTogDQoNCg0KPGRldGFpbHM+IDxzdW1tYXJ5PioqRGVzcGxlZ2FyIGVsIGRpY2Npb25hcmlvIGRlIHZhcmlhYmxlcyoqPC9zdW1tYXJ5Pg0KDQojIyMgNS4yLiBSZWdyZXNpw7NuIExpbmVhbCBTaW1wbGUgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIyBDb2VmaWNpZW50ZXMgZGVsIE1vZGVsbyBSTFMNCmBgYHtyIENvZWZpY2llbnRlc19Nb2RlbG9fUkxTLCBmaWcuYWxpZ249J2NlbnRlcid9DQptb2RlbG9fUkxfU2ltcGxlID0gbG0oY2NkX3Zpc2lvbjIwMjBfRVRMJEFWX09EfmNjZF92aXNpb24yMDIwX0VUTCRyYW5nb19ldGFyZW8pDQpjb2VmKG1vZGVsb19STF9TaW1wbGUpDQpgYGANCmBgYHtyIENvZWZpY2llbnRlc19Nb2RlbG9fUkxTMSwgZmlnLmFsaWduPSdjZW50ZXInfQ0KbW9kZWxvX1JMX1NpbXBsZTEgPSBsbShjY2RfdmlzaW9uMjAyMF9FVEwkQVZfT0l+Y2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbykNCmNvZWYobW9kZWxvX1JMX1NpbXBsZTEpDQpgYGANCg0KIyMjIyBSZXN1bWVuIEVzdGFkw61zdGljbyBkZWwgTW9kZWxvIFJMUw0KYGBge3IgUmVzdW1lbiBFc3RhZMOtc3RpY29fZGVsX01vZGVsb19STFMsZmlnLmFsaWduPSdjZW50ZXInfQ0Kc3VtbWFyeShtb2RlbG9fUkxfU2ltcGxlKQ0KYGBgDQoNCiMjIyMgVGFibGEgQU5PVkEgcGFyYSBlbCBNb2RlbG8gUkxTDQpgYGB7ciBUYWJsYV9BTk9WQV9wYXJhX2VsX01vZGVsb19STFMsZmlnLmFsaWduPSdjZW50ZXInfQ0KYW5vdmEobW9kZWxvX1JMX1NpbXBsZSkNCg0KYGBgDQojIyMgNS4zLiBSZWdyZXNpw7NuIExpbmVhbCBNw7psdGlwbGUNCg0KRXN0ZSBtb2RlbG8sIHF1ZSBhIHBhcnRpciBkZSBhaG9yYSBzZSBkZW5vbWluYXLDoSBjb21vIFJMUywgZXN0w6EgY29tcHVlc3RvIHBvciBkb3MgdmFyaWFibGVzOiB1bmEgcHJlZGljdG9yYSB5IG90cmEgcmVzcHVlc3RhLiBFc3BlY8OtZmljYW1lbnRlLCBsYSB2YXJpYWJsZSAkWSQgc2UgY29uc2lkZXJhIGluZmx1aWRhIHBvciBsYSB2YXJpYWJsZSBwcmVkaWN0b3JhICR4JC4gTGEgcmVsYWNpw7NuIGVudHJlIGVzdGFzIHZhcmlhYmxlcyBlc3TDoSBkZXNjcml0YSBwb3IgbGEgZWN1YWNpw7NuOg0KJCRZID0gXGJldGFfMCArIFxiZXRhXzF4ICsgXHZhcmVwc2lsb24kJA0KRG9uZGU6IA0KLSAkWSQ6IEVzIGxhIHZhcmlhYmxlIGRlcGVuZGllbnRlIChsYSBxdWUgc2UgZGVzZWEgcHJlZGVjaXIgbyBleHBsaWNhcikuDQotICR4JDogRXMgbGEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZSAocHJlZGljdG9yYSkuDQotICQoXGJldGFfMCkkOiBFcyBlbCBpbnRlcmNlcHRvICh2YWxvciBkZSAkWSQgY3VhbmRvICQoeCA9IDApJC4NCi0gJChcYmV0YV8xKSQ6IEVzIGxhIHBlbmRpZW50ZSAoaW5kaWNhIGN1w6FudG8gY2FtYmlhICRZJCBwb3IgY2FkYSB1bmlkYWQgcXVlIGNhbWJpYSAkKHgpJC4NCi0gJChcZXBzaWxvbikkOiBFcyBlbCB0w6lybWlubyBkZSBlcnJvciwgcXVlIGNhcHR1cmEgbGFzIGRlc3ZpYWNpb25lcyBlbnRyZSBsb3MgdmFsb3JlcyBvYnNlcnZhZG9zIHkgbG9zIHZhbG9yZXMgcHJlZGljaG9zIHBvciBlbCBtb2RlbG8uDQoNCkxhIHJlbGFjacOzbiBlbnRyZSBsYSB2YXJpYWJsZSBpbmRlcGVuZGllbnRlIHkgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUgZW4gZWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbGluZWFsIHNpbXBsZSBkZWJlIGN1bXBsaXIgY2llcnRhcyBzdXBvc2ljaW9uZXMgY2xhdmUgcGFyYSBxdWUgbG9zIHJlc3VsdGFkb3Mgc2VhbiB2w6FsaWRvcy4gRXN0YXMgc29uIGxhcyBzaWd1aWVudGVzOiAxLiBMYSByZWxhY2nDs24gZW50cmUgbGEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZSAkeCQgeSBsYSB2YXJpYWJsZSBkZXBlbmRpZW50ZSAkWSQgZGViZSBzZXIgbGluZWFsLiAyLiBFbCB0w6lybWlubyBkZSBlcnJvciAkzrUkIHNpZ3VlIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCB5IHRpZW5lIHVuYSBtZWRpYSBpZ3VhbCBhIGNlcm8uIDMuIExhcyBvYnNlcnZhY2lvbmVzIGRlYmVuIHNlciBpbmRlcGVuZGllbnRlcyBlbnRyZSBzw60sIGVzIGRlY2lyLCBlbCB2YWxvciBkZSAkWSQgcGFyYSB1biBkYXRvIG5vIGluZmx1eWUgZW4gbG9zIHZhbG9yZXMgZGUgJFkkIHBhcmEgb3Ryb3MgZGF0b3MuIDQuIExhIHZhcmlhbnphIGRlbCB0w6lybWlubyBkZSBlcnJvciAkzrUkIGRlYmUgc2VyIGNvbnN0YW50ZSBwYXJhIHRvZG9zIGxvcyB2YWxvcmVzIGRlIGxhIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgJHgkLCB1bmEgY29uZGljacOzbiBjb25vY2lkYSBjb21vIGhvbW9jZWRhc3RpY2lkYWQuIExhIHZhcmlhbnphIGRlICRcdmFyZXBzaWxvbiQgZXMgY29uc3RhbnRlIHBhcmEgdG9kb3MgbG9zIHZhbG9yZXMgZGUgJHgkLg0KDQpQYXJhIGVzdGltYXIgbG9zIHBhcsOhbWV0cm9zIGRlc2Nvbm9jaWRvcyAoJFxiZXRhXzAkLCAkXGJldGFfMSQgeSAkXHNpZ21hXjIkKSwgc2UgdXNhIGVsICoqbcOpdG9kbyBkZSBtw61uaW1vcyBjdWFkcmFkb3MqKiwgcXVlIGJ1c2NhIG1pbmltaXphciBsYSBzdW1hIGRlIGxvcyBjdWFkcmFkb3MgZGUgbGFzIGRlc3ZpYWNpb25lcyB2ZXJ0aWNhbGVzIGVudHJlIGxvcyBwdW50b3Mgb2JzZXJ2YWRvcyB5IGxhIGzDrW5lYSBkZSByZWdyZXNpw7NuOiQkU0NFID0gXHN1bV97aT0xfV5uIFxsZWZ0KHlfaSAtIChcYmV0YV8wICsgXGJldGFfMXhfaSlccmlnaHQpXjIkJC4gUmVzb2x2aWVuZG8gZXN0ZSBwcm9ibGVtYSwgbGFzIGVzdGltYWNpb25lcyBkZSBsb3MgcGFyw6FtZXRyb3Mgc29uOg0KJCRcaGF0e1xiZXRhfV8xID0gXGZyYWN7XHN1bV97aT0xfV5uICh4X2kgLSBcYmFye3h9KSh5X2kgLSBcYmFye3l9KX17XHN1bV97aT0xfV5uICh4X2kgLSBcYmFye3h9KV4yfSwgXHF1YWQgXGhhdHtcYmV0YX1fMCA9IFxiYXJ7eX0gLSBcaGF0e1xiZXRhfV8xIFxiYXJ7eH0uJCQNCkFxdcOtLCAkXGJhcnt4fSQgeSAkXGJhcnt5fSQgc29uIGxhcyBtZWRpYXMgbXVlc3RyYWxlcyBkZSAkeCQgZSAkeSQsIHJlc3BlY3RpdmFtZW50ZS4NCg0KRWwgY29lZmljaWVudGUgZGUgZGV0ZXJtaW5hY2nDs24gaW5kaWNhIGxhIHByb3BvcmNpw7NuIGRlIGxhIHZhcmlhYmlsaWRhZCBkZSAkWSQgcXVlIHB1ZWRlIGV4cGxpY2Fyc2UgbWVkaWFudGUgZWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbGluZWFsIHNpbXBsZTokJFJeMiA9IDEgLSBcZnJhY3tTQ0V9e1NUQ30sJCQgZG9uZGUgJFNDRSQgZXMgbGEgc3VtYSBkZSBjdWFkcmFkb3MgZGVsIGVycm9yIHkgJFNUQyQgZXMgbGEgc3VtYSB0b3RhbCBkZSBjdWFkcmFkb3MuIFVuIHZhbG9yIGRlICRSXjIkIGNlcmNhbm8gYSAxIGluZGljYSBxdWUgZWwgbW9kZWxvIGV4cGxpY2EgZ3JhbiBwYXJ0ZSBkZSBsYSB2YXJpYWJpbGlkYWQgb2JzZXJ2YWRhIGVuIGxvcyBkYXRvcy4NCg0KU2UgcHVlZGVuIGZvcm11bGFyIHBydWViYXMgcGFyYSBkZXRlcm1pbmFyIHNpIGxvcyBjb2VmaWNpZW50ZXMgZGVsIG1vZGVsbyBzb24gc2lnbmlmaWNhdGl2YW1lbnRlIGRpZmVyZW50ZXMgZGUgY2Vyby4gTGFzIGhpcMOzdGVzaXMgbnVsYXMgY29tdW5lcyBzb246DQotIFBhcmEgJFxiZXRhXzAkOiAkSF8wOiBcYmV0YV8wID0gXGJldGFfezAwfSQuDQotIFBhcmEgJFxiZXRhXzEkOiAkSF8wOiBcYmV0YV8xID0gMCQgKHBydWViYSBkZSB1dGlsaWRhZCBkZWwgbW9kZWxvKS4NCg0KRWwgZXN0YWTDrXN0aWNvIGRlIHBydWViYSBhc29jaWFkbyBlczokJCB0ID0gXGZyYWN7XGhhdHtcYmV0YX1fMSAtIDB9e1NFKFxoYXR7XGJldGF9XzEpfSwkJCBkb25kZSAkU0UoXGhhdHtcYmV0YX1fMSkkIGVzIGVsIGVycm9yIGVzdMOhbmRhciBkZSAkXGhhdHtcYmV0YX1fMSQgRXN0ZSBlc3RhZMOtc3RpY28gc2lndWUgdW5hIGRpc3RyaWJ1Y2nDs24gJHQkIGRlIFN0dWRlbnQgY29uICRuLTIkIGdyYWRvcyBkZSBsaWJlcnRhZC4NCg0KTG9zIGludGVydmFsb3MgZGUgY29uZmlhbnphIHBhcmEgbG9zIHBhcsOhbWV0cm9zIGVzdGltYWRvcyBzZSBjYWxjdWxhbiBjb21vOiAkJFxoYXR7XGJldGF9XzEgXHBtIHRfe1xhbHBoYS8yLCBuLTJ9IFxjZG90IFNFKFxoYXR7XGJldGF9XzEpLiQkIEVzdG9zIGludGVydmFsb3MgYnJpbmRhbiB1biByYW5nbyBwcm9iYWJsZSBwYXJhIGxvcyB2ZXJkYWRlcm9zIHZhbG9yZXMgZGUgJFxiZXRhXzAkIHkgJFxiZXRhXzEkLg0KDQpFbCBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgc2ltcGxlIGVzIHVuYSBoZXJyYW1pZW50YSBwb2Rlcm9zYSBwYXJhIGFuYWxpemFyIHJlbGFjaW9uZXMgbGluZWFsZXMuIFNpbiBlbWJhcmdvLCBkZWJlIHVzYXJzZSBjb24gY2F1dGVsYTogbm8gZXh0cmFwb2xlIG3DoXMgYWxsw6EgZGVsIHJhbmdvIGRlIGxvcyBkYXRvcyB5IGFzZWfDunJlc2UgZGUgcXVlIGxhcyBzdXBvc2ljaW9uZXMgZGVsIG1vZGVsbyBzZWFuIHJhem9uYWJsZXMgcGFyYSBsb3MgZGF0b3MuIEFsIGNvbXByZW5kZXIgbGEgdmFyaWFiaWxpZGFkIGV4cGxpY2FkYSB5IG5vIGV4cGxpY2FkYSBwb3IgZWwgbW9kZWxvLCBsb3MgYW5hbGlzdGFzIHB1ZWRlbiB0b21hciBkZWNpc2lvbmVzIGZ1bmRhbWVudGFkYXMgeSBldmFsdWFyIGxhIHV0aWxpZGFkIGRlbCBtb2RlbG8gZW4gY29udGV4dG9zIGVzcGVjw61maWNvcy4NCg0KDQpFbiBlbCBtb2RlbG8sICoqbG9zIHB1bnRvcyBvYnNlcnZhZG9zIHNlIGRpc3RyaWJ1eWVuIGFsZWF0b3JpYW1lbnRlIGFscmVkZWRvcioqIGRlIGxhIGzDrW5lYSBkZSAqKnJlZ3Jlc2nDs24gdmVyZGFkZXJhKiouIFBhcmEgYWp1c3RhcnNlIGEgZXN0b3MgcHVudG9zLCBsYSBlc3RpbWFjacOzbiAkeSA9IGJldGFfMCArIGJldGFfMSB4JCBkZWJlIHNlciB1bmEgbMOtbmVhIHF1ZSBtaW5pbWljZSBsYXMgZGlzdGFuY2lhcyB2ZXJ0aWNhbGVzIGRlc3ZpYWNpb25lcyBlbnRyZSBsb3MgcHVudG9zIG9ic2VydmFkb3MgeSBsYSBsw61uZWEuIExhIGNhbGlkYWQgZGVsIGFqdXN0ZSBzZSBldmFsw7phIG1lZGlhbnRlIGxhIHN1bWEgZGUgbG9zIGN1YWRyYWRvcyBkZSBlc3RhcyBkZXN2aWFjaW9uZXMsIHNpZW5kbyBsYSBtZWpvciBsw61uZWEgYXF1ZWxsYSBxdWUgbWluaW1pY2UgZXN0YSBzdW1hLiBFc3RlIGVuZm9xdWUsIGNvbm9jaWRvIGNvbW8gZWwgcHJpbmNpcGlvIGRlIGxvcyBtw61uaW1vcyBjdWFkcmFkb3MsIGZ1ZSBkZXNhcnJvbGxhZG8gcG9yICoqQ2FybCBGcmllZHJpY2ggR2F1c3MgeSBBZHJpZW4tTWFyaWUgTGVnZW5kcmUqKi4NCg0KUG9yIMO6bHRpbW8sIHNlIGVudGllbmRlIHF1ZSBlbiB1biBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgc2ltcGxlIHVuIHZhbG9yIGZ1dHVybyBkZSAkWSQgbm8gZXMgcGFyw6FtZXRybyBzaW5vIHVuYSB2YXJpYWJsZSBhbGVhdG9yaWEsIHBvciBsbyBxdWUgc2UgZGViZSBoYWNlciByZWZlcmVuY2lhIGEgdW4gaW50ZXJ2YWxvIGRlIHZhbG9yZXMgZmFjdGlibGVzIHBhcmEgdW4gdmFsb3IgZnV0dXJvIGRlICRZJCwgYWwgY3VhbCBzZSBsZSBsbGFtYSBpbnRlcnZhbG8gZGUgcHJlZGljY2nDs24uIFNlZ8O6bixbQEVBTU9USW1vNDIwMjNdLg0KIA0KDQojIyMgNS40LiBSZWdyZXNpw7NuIExvZ8Otc3RpY2EgU2ltcGxlIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjI0dyw6FmaWNhIGRlbCBNb2RlbG8gUkxvZ1MNCmBgYHtyIGdyYWZpY2FfTW9kZWxvX1JMb2dTLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCg0KdW1icmFsX09EIDwtIDAuOCAjIGVqZW1wbG8sIHJlZW1wbGF6YXIgcG9yIGVsIHZhbG9yIGFkZWN1YWRvDQp1bWJyYWxfT0kgPC0gMC44ICMgZWplbXBsbywgcmVlbXBsYXphciBwb3IgZWwgdmFsb3IgYWRlY3VhZG8NCg0KY2NkX3Zpc2lvbjIwMjBfRVRMJGJhamFfQVZfT0QgPC0gaWZlbHNlKGNjZF92aXNpb24yMDIwX0VUTCRBVl9PRCA8IHVtYnJhbF9PRCwgMSwgMCkNCmNjZF92aXNpb24yMDIwX0VUTCRiYWphX0FWX09JIDwtIGlmZWxzZShjY2RfdmlzaW9uMjAyMF9FVEwkQVZfT0kgPCB1bWJyYWxfT0ksIDEsIDApDQoNCmNjZF92aXNpb24yMDIwX0VUTCRiYWphX0FWX09EIDwtIGFzLm51bWVyaWMoY2NkX3Zpc2lvbjIwMjBfRVRMJGJhamFfQVZfT0QpDQpjY2RfdmlzaW9uMjAyMF9FVEwkYmFqYV9BVl9PSSA8LSBhcy5udW1lcmljKGNjZF92aXNpb24yMDIwX0VUTCRiYWphX0FWX09JKQ0KY2NkX3Zpc2lvbjIwMjBfRVRMJEhvcmFzX3BhbnRhbGxhX2RpYSA8LSBhcy5udW1lcmljKGNjZF92aXNpb24yMDIwX0VUTCRIb3Jhc19wZCkNCg0KbW9kX2xvZ19PRCA8LSBnbG0oYmFqYV9BVl9PRCB+IEhvcmFzX3BhbnRhbGxhX2RpYSwNCmZhbWlseSA9IGJpbm9taWFsLA0KZGF0YSA9IGNjZF92aXNpb24yMDIwX0VUTCkNCg0KDQptb2RfbG9nX09JIDwtIGdsbShiYWphX0FWX09JIH4gSG9yYXNfcGFudGFsbGFfZGlhLA0KZmFtaWx5ID0gYmlub21pYWwsDQpkYXRhID0gY2NkX3Zpc2lvbjIwMjBfRVRMKQ0KDQoNCnhfc2VxIDwtIHNlcSgNCmZyb20gPSBtaW4oY2NkX3Zpc2lvbjIwMjBfRVRMJEhvcmFzX3BhbnRhbGxhX2RpYSwgbmEucm0gPSBUUlVFKSwNCnRvID0gbWF4KGNjZF92aXNpb24yMDIwX0VUTCRIb3Jhc19wYW50YWxsYV9kaWEsIG5hLnJtID0gVFJVRSksDQpsZW5ndGgub3V0ID0gMjAwDQopDQoNCnBhcihtZnJvdyA9IGMoMSwgMikpDQpgYGANCg0KIyMjIyBHcsOhZmljYSBkZWwgTW9kZWxvIFJMb2dTIA0KYGBge3IgZ3JhZmljYV9Nb2RlbG9fUkxvZ1NfQVZfT0QsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KcGxvdChiYWphX0FWX09EIH4gSG9yYXNfcGFudGFsbGFfZGlhLA0KZGF0YSA9IGNjZF92aXNpb24yMDIwX0VUTCwNCm1haW4gPSAiTW9kZWxvIFJMb2dTOiBiYWphX0FWX09EIH4gSG9yYXNfcGFudGFsbGFfZGlhIiwNCnhsYWIgPSAiSG9yYXNfcGFudGFsbGFfZGlhIiwNCnlsYWIgPSAiYmFqYV9BVl9PRCAoMCA9IE5vLCAxID0gU8OtKSIsDQpjb2wgPSAiZ29sZCIsDQpwY2ggPSAxNikNCg0KbGluZXMoeF9zZXEsDQpwcmVkaWN0KG1vZF9sb2dfT0QsDQpuZXdkYXRhID0gZGF0YS5mcmFtZShIb3Jhc19wYW50YWxsYV9kaWEgPSB4X3NlcSksDQp0eXBlID0gInJlc3BvbnNlIiksDQpjb2wgPSAib3JhbmdlIiwNCmx3ZCA9IDMpDQoNCmBgYA0KDQojIyMjIEdyw6FmaWNhIGRlbCBNb2RlbG8gUkxvZ1MNCmBgYHtyIGdyYWZpY2FfTW9kZWxvX1JMb2dTX0FWX09JLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnBsb3QoYmFqYV9BVl9PSSB+IEhvcmFzX3BhbnRhbGxhX2RpYSwNCmRhdGEgPSBjY2RfdmlzaW9uMjAyMF9FVEwsDQptYWluID0gIk1vZGVsbyBSTG9nUzogYmFqYV9BVl9PSSB+IEhvcmFzX3BhbnRhbGxhX2RpYSIsDQp4bGFiID0gIkhvcmFzX3BhbnRhbGxhX2RpYSIsDQp5bGFiID0gImJhamFfQVZfT0kgKDAgPSBObywgMSA9IFPDrSkiLA0KY29sID0gImdvbGQiLA0KcGNoID0gMTYpDQoNCmxpbmVzKHhfc2VxLA0KcHJlZGljdChtb2RfbG9nX09JLA0KbmV3ZGF0YSA9IGRhdGEuZnJhbWUoSG9yYXNfcGFudGFsbGFfZGlhID0geF9zZXEpLA0KdHlwZSA9ICJyZXNwb25zZSIpLA0KY29sID0gIm9yYW5nZSIsDQpsd2QgPSAzKQ0KDQpwYXIobWZyb3cgPSBjKDEsIDEpKQ0KDQpgYGANCg0KDQojIyMgNS41LiBBanVzdGUgZGUgVmFyaWFuemENCg0KIyMgKio2LiBDb25jbHVzaW9uZXMqKg0KDQojIyAqKjcuIEJpYmxpb2dyYWbDrWEqKg0KDQoNCg==