Introducción a la regresión lineal múltiple

  • El análisis bivariado es un primer paso en el análisis estadístico. Se encuentran (cor)relaciones: X - Y

  • ¿Por qué agregar más variables? Se busca aproximarse a la causalidad: X -> Y

  • Para aproximarse a establecer causalidad es necesario el análisis multivariado.

  • Para hablar de causalidad, se requieren ciertos criterios:

    • Asociación estadística entre las variables, pero asociación no implica causalidad.

    • Orden temporal: que la causa ocurra antes que el efecto.

    • Eliminación de hipótesis alternativas. Estas hipótesis alternativas regularmente parten de la literatura.

    • Consistencia: la relación debe ser consistente en diferentes estudios, poblaciones y contextos.

    • Dosificación: cambios en la magnitud de X llevan a cambios correspondientes en Y.

    • Plausibilidad: debe haber una explicación teórica o mecanismo plausible que respalde la relación causal.

    • Especificidad: si una causa X lleva a un efecto Y específico y no a múltiples efectos diferentes.

    • Coherencia: la relación causal debe ser coherente con el conocimiento general existente, por ejemplo en diferentes disciplinas.

Control estadístico

Para evaluar (o eliminar) las hipótesis alternativas, se realiza un “control estadístico”. La idea es:

  • Evaluar si la asociación entre X - Y permanece si se remueve el efecto de otra variable, es decir, si se controla por una tercera variable (o cuarta o quinta o etc.).

  • Para controlar por variables importantes, como las sociodemográficas.

  • En un experimento se puede controlar por un gran número de variables desde el diseño. Por ejemplo, se puede asegurar que el sujeto experimental esté expuesto a las mismas condiciones. Control experimental.

  • En los métodos observacionales se puede aproximar un control experimental agrupando las observaciones en grupos de valores iguales o similares de las variables de control. Control estadístico.

  • En la práctica, se analiza la relación entre X - Y para valores similares o iguales de una variable Z. De esta manera se elimina la influencia de Z en la relación entre X - Y. Es un paso en el establecimiento de X -> Y.

  • Si la relación entre X - Y desaparece cuando se controla por Z, se dice que la relación era espúrea.

Para dar un ejemplo, usaremos los datos de la elección 2016. Esta base de datos incluye una variable de PBI per cápita en cada departamento. Con esta variable se ha creado otra variable agrupando el PBI en 3 grupos: alto, medio, bajo.

library(rio)
data16 = import("bases/datos2016_v3.sav")

En primer lugar, haremos una inspección visual de la relación entre el acceso a internet y el voto a PPK, mediante un gráfico de dispersión. Esta gráfico incluirá una tercera variable, PBI per cápita, que se visualizará como un color de cada observación.

library(ggplot2)
ggplot(data16, aes(x=Uso_internet, y=Voto_PPK_2016_1))+
  geom_point(aes(color=pbipc_grupos))+
  geom_smooth(method=lm, se=F)+ #agregar línea de tendencia
  geom_text(data=data16, aes(label=Dpto), 
            cex=2, nudge_y = 1.1, check_overlap = T)+ #Pata etiquetar los puntos, darles un tamaño, ubicación y prevenir que se sobrepongan
  labs(x="Porcentaje de uso de internet", 
       y="Voto a PPK (1era vuelta 2016)")+ #para etiquetar los ejes
  theme_light()
## `geom_smooth()` using formula =
## 'y ~ x'

library(tidyverse)
## ── Attaching core tidyverse pack
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ lubridate 1.9.3     ✔ tibble    3.2.1
## ✔ purrr     1.0.2     ✔ tidyr     1.3.1
## ── Conflicts ───────────────────
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
data16 = data16 %>%
  mutate(pbigrupo = factor(pbipc_grupos, labels=c("Bajo",
                                                  "Medio", 
                                                  "Alto")))
ggplot(data16, aes(x=Uso_internet, y=Voto_PPK_2016_1))+
  geom_point(aes(color=pbigrupo))+
  geom_smooth(method=lm, se=F)+ #agregar línea de tendencia
  geom_text(data=data16, aes(label=Dpto), 
            cex=2, nudge_y = 1.1, check_overlap = T)+ #Pata etiquetar los puntos, darles un tamaño, ubicación y prevenir que se sobrepongan
  labs(x="Porcentaje de uso de internet", 
       y="Voto a PPK (1era vuelta 2016)")+ #para etiquetar los ejes
  theme_light()
## `geom_smooth()` using formula =
## 'y ~ x'

El color de cada punto representa un nivel de PBI per cápita: negro significa PBI per cápita departamental bajo, rojo significa PBI per cápita departamental medio y verde significa PBI per cápita departamental alto.

Para analizar visualmente la relación entre acceso a internet y voto a PPK, controlando por el PBI per cápita, se puede analizar evaluar la relación entre X - Y para grupos de Z. Es decir, se puede evaluar visualmente la relación entre acceso a internet - voto a PPK, en cada grupo de color.

¿Cuál es la relación entre X - Y para el grupo de observaciones en rojo (PBI per cápita departamental bajo)? Se observa una relación positiva, aunque tenue.

¿Cuál es la relación entre X - Y para el grupo de observaciones en verde (PBI per cápita departamental medio)? Se observa una relación negativa, contrario a la hipótesis planteada.

¿Cuál es la relación entre X - Y para el grupo de observaciones en azul (PBI per cápita departamental alto)? Se observa una relación positiva.

Pregunta final: ¿se mantiene la relación entre acceso a internet y voto a PPK en cada grupo de PBI per cápita?

En un extremo, la relación entre X - Y se mantiene (en la misma dirección) para cada grupo de Z. Si esto es así, se dice que la relación entre X - Y se mantiene controlando por Z.

En el otro extremos, la relación entre X - Y no se mantiene para ningún grupo de Z. Si esto es así, se dice que la relación entre X - Y es una relación espúrea, que cuando se controla por Z, esta relación bivariada desaparece.

En la práctica, el análisis multivariado analiza si la relación entre X - Y se mantiene “en promedio” para cada grupo de Z. Para hacer esta evaluación no es suficiente (y a veces, no es necesario) el análisis visual en el diagrama de dispersión, sino que hace falta un modelo estadístico.

Modelo de regresión lineal múltiple

Se usa un modelo de regresión lineal múltiple para el cálculo de los efectos de varios predictores en una variable dependiente numérica en un mismo modelo. Por ejemplo, si quisiéramos evaluar la relación entre la variable acceso a internet y la variable PBI per cápita en el voto a PPK, se puede incluir ambas variables independientes en un mismo modelo.

En ese caso, el modelo sería: \(\hat{Y} = \hat{\alpha} + \hat{\beta_1}*X_1+\hat{\beta_2}*X_2\)

Si la relación bivariada se evalúa en un plano cartesiano, cuando se incluye una tercera variable, el análisis pasa de un plano cartesiano a un espacio cartesiano. Para fines explicativos, esto se puede graficar en un diagrama de dispersión en tres dimensiones.

#Este código NO se evaluará
library(scatterplot3d)
scatterplot3d(x=data16$Uso_internet, y=data16$Voto_PPK_2016_1, z=data16$pbipc_2014)

pairs(data16$Uso_internet ~ data16$Uso_internet+data16$pbipc_2014)

En este caso, cada punto estaría ubicado de acuerdo a los valores en las 3 variables. No es fácil visualizar la relaciones parciales entre X - Y y entre Z - Y. Una mejor visualización es mirando los lados del cubo.

Uno podría pensar que es suficiente con realizar dos regresiones lineales simples entre cada variable independiente con la dependiente. Si lo hacemos, tendríamos dos modelos simples. Para la relación original entre acceso a internet y voto a PPK, se tiene.

modelo1 = lm(data16$Voto_PPK_2016_1 ~ data16$Uso_internet)
summary(modelo1)
## 
## Call:
## lm(formula = data16$Voto_PPK_2016_1 ~ data16$Uso_internet)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -7.6001 -4.9871 -0.2939  3.2344 13.7498 
## 
## Coefficients:
##                     Estimate Std. Error t value Pr(>|t|)    
## (Intercept)          3.51789    3.23825   1.086 0.288576    
## data16$Uso_internet  0.37312    0.09264   4.028 0.000525 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 5.649 on 23 degrees of freedom
## Multiple R-squared:  0.4136, Adjusted R-squared:  0.3881 
## F-statistic: 16.22 on 1 and 23 DF,  p-value: 0.0005251

Y para la segunda variable, se tiene.

modelo2 = lm(data16$Voto_PPK_2016_1 ~ data16$pbipc_2014)
summary(modelo2)
## 
## Call:
## lm(formula = data16$Voto_PPK_2016_1 ~ data16$pbipc_2014)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -7.739 -3.634 -1.237  2.506 11.596 
## 
## Coefficients:
##                    Estimate Std. Error t value Pr(>|t|)   
## (Intercept)       8.0704028  2.2830875   3.535  0.00186 **
## data16$pbipc_2014 0.0004790  0.0001324   3.619  0.00152 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 5.584 on 22 degrees of freedom
##   (1 observation deleted due to missingness)
## Multiple R-squared:  0.3732, Adjusted R-squared:  0.3447 
## F-statistic:  13.1 on 1 and 22 DF,  p-value: 0.00152
modelo3 = lm(Voto_PPK_2016_1 ~ Analfabetismo_2014, data=data16)
summary(modelo3)
## 
## Call:
## lm(formula = Voto_PPK_2016_1 ~ Analfabetismo_2014, data = data16)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -10.701  -3.535  -1.225   4.402   9.015 
## 
## Coefficients:
##                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)         24.6354     2.2318  11.038 1.15e-10 ***
## Analfabetismo_2014  -1.1462     0.2523  -4.543 0.000146 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 5.356 on 23 degrees of freedom
## Multiple R-squared:  0.4729, Adjusted R-squared:   0.45 
## F-statistic: 20.63 on 1 and 23 DF,  p-value: 0.0001456

Mirando los resultados de ambos modelos lineales simples, se tiene que ambas variables, tanto acceso a internet como PBI, son significativas. Ambas tienen un efecto directo, es decir, a mayor acceso a internet, mayor voto a PPK en promedio, y a mayor PBI per cápita, mayor voto a PPK en promedio.

Estos modelos, sin embargo, analizan el impacto individual de cada variable, sin ningún tipo de control estadístico. Los modelos lineales simple, en ese sentido, están más cerca de un análisis de correlación, que de uno de causalidad.

Para tratar de acercarnos al ideal de causalidad, se tiene que controlar por posibles explicaciones alternativas. La discusión con respecto a la elección 2016 planteaba que el voto a PPK también tenía un componente económico. Se especulaba que los sectores más beneficiados del boom económico podían votar en mayor medida a favor de PPK. Si esto es así, la variable de PBI per cápita puede recoger este fenómeno.

La idea es evaluar si la relación entre acceso a internet y voto a PPK se mantiene controlando por una variable económica. Para esto, se realiza un modelo lineal múltiple usando el voto a PPK como variable dependiente y el acceso a internet y el PBI per cápita como variables independientes, en un mismo modelo. El comando lm permite incluir varios predictores independientes en un mismo modelo con el símbolo +.

modelo4 = lm(Voto_PPK_2016_1 ~ Uso_internet + Analfabetismo_2014 + pbipc_2014, data=data16)
summary(modelo4)
## 
## Call:
## lm(formula = Voto_PPK_2016_1 ~ Uso_internet + Analfabetismo_2014 + 
##     pbipc_2014, data = data16)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -10.2876  -2.6319  -0.6423   2.4823   8.1417 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)  
## (Intercept)        19.2084720  7.2748230   2.640   0.0157 *
## Uso_internet       -0.0634842  0.1681417  -0.378   0.7097  
## Analfabetismo_2014 -0.8535105  0.3884828  -2.197   0.0400 *
## pbipc_2014          0.0003255  0.0001645   1.979   0.0618 .
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 5.037 on 20 degrees of freedom
##   (1 observation deleted due to missingness)
## Multiple R-squared:  0.5363, Adjusted R-squared:  0.4668 
## F-statistic: 7.711 on 3 and 20 DF,  p-value: 0.001292

Leyendo el modelo

¿Es válido el modelo?

Como ahora tenemos tres variables independientes, la validez del modelo ya no depende solo de la relación de una variable independiente con la dependiente. Para evaluar la validez del modelo se tiene que hacer una evaluación general. Esta evaluación plantea una hipótesis cero que todas las pendientes (o coeficientes) son iguales a cero.

\(H0: \beta_1 = \beta_2 = \beta_3 =...\beta_n = 0\) La hipótesis alternativa indica que al menos una pendiente es diferente de cero, lo que indicaría que al menos una variable independiente tiene relación con la variable dependiente.

Para evaluar esta hipótesis se analiza los resultados de la prueba F (en la última línea de resultados del modelo). El estadístico F = 7.71 tiene un p-value asociado de 0.001. Este p-value es menor de 0.05, por lo que podemos rechazar la H0 y afirmar que al menos un coeficiente debe ser diferente de cero.

Test de inferencia: ¿hay relación entre las VIs y la VD?

Esta pregunta se responde para cada variable independiente, evaluación que se hace dentro de un modelo lineal multivariado, donde se controla por el resto de variables.

Cada variable independiente tiene una fila de resultados con su propia prueba de independencia. Esta pruebas tiene las siguientes hipótesis:

\(H0: \beta_1 = 0\) \(H0: \beta_2 = 0\)

Para la variable uso de internet, la fila correspondiente nos indica que tenemos un coeficiente de -0.06. Para esta variable el estadístico de la prueba t tiene un p-value de 0.71. Este p-value es mayor de 0.05, por lo que fallamos en rechazar la H0. Es decir, se tiene 71% de probabilidades de tener un coeficiente de -0.06, si el verdadero valor del parámetro es 0. En resumen, con estos valores, no encontramos una relación entre acceso a internet y voto a PPK.

Para la variable, PBI per cápita, tenemos un coeficiente de 0.0003, con un estadístico de la prueba t de 1.98 y un p-value de 0.06. Con este p-value no podemos rechazar la H0 a un valor crítico de 0.05). Este p-value no es menos a 0.05, por lo que no sería significativo. Pero, si se relaja el criterio, este p-value es menor a 0.10. Es decir, se tiene 6% de probabilidades de observar una pendiente de 0.0003 si la verdadera pendiente fuera 0. Podemos asumir que esta probabilidad es baja, por lo que podemos concluir que sí existe una relación entre PBI y voto a PPK al 0.1 de valor crítico.

Para la variable de analfabetismo, se tiene un coeficiente de -0.85 con un estadístico de -2.2 y un p-value de 0.04, que es menor que 0.05, por lo que podemos rechazar la H0. Se concluye que sí existe relación entre analfabetismo y voto a PPK, controlando por otros factores, como riqueza y uso de internet.

En conclusión, la relación entre acceso a internet y voto a PPK, que se había encontrado en el análisis bivariado, no se mantiene en un análisis multivariado, cuando se controla por la variable PBI. Muy probablemente estemos hablando de una relación espúrea, pues PBI podría tener un efecto tanto en el acceso a internet (departamentos más ricos, tienen familias que pueden pagar por el servicio de internet), como en el voto a PPK (departamentos más ricos, votan en mayor medida a PPK).

Dirección de la relación

De la misma manera que en análisis bivariado, la dirección de la relación entre las variables independientes y la dependiente está marcado por el signo del coeficiente.

En este caso, se analiza el signo del coeficiente de la variable PBI y analfabetismo. El signo del coeficiente de PBI es positivo (+), lo que indica que departamentos con un mayor PBI per cápita tendrían un mayor porcentaje de voto a PPK, en promedio. De El signo del coeficiente de analfabetismo es negativo (-), con lo que se concluye que departamentos que muestran mayor analfabetismo tienen menor voto a PPK, en promedio.

Ajuste del modelo

De la misma manera que en el análisis bivariado, el ajuste del modelo se entiende como el porcentaje de la variación total de la variable dependiente explicada por las variables independientes. Este dato se obtiene con el \(R^2\).

En nuestro ejemplo se tiene un \(R^2 ajustado = 0.47\). Esta dato indicaría que el modelo que incluye las variables acceso a internet y PBI per cápita explican el 47% de la variación total del voto a PPK.

El \(R^2\) ajustado se usa cuando se quiere comparar entre diferentes modelos, ya sea porque se usan diferentes variables o diferente número de variables. Esto es importante cuando se comparar modelos con diferente número de variables independientes, porque el \(R^2\) tiene la característica de aumentar cuando se incluyen más variables independientes. El \(R^2\) ajustado controla por esta inflación artificial.

Predicción

Para la predicción se tiene que construir la ecuación del modelo. Esta ecuación se construye con los valores de los coeficientes de todas las variables, así alguna de ellas no haya salido significativa. A esto se agrega el valor de la constante.

En nuestro ejemplo se tiene la siguiente ecuación, siendo Y el voto a PPK, X1 el acceso a internet y X2 en PBi per cápita:

\[\hat{Y} = 19.2 - 0.06*X_1 - 0.85*X_2 + 0.0003*X_3\]

Para hallar el voto estimado a PPK, se tiene que agregar valores de las tres variables independientes. Para poder aproximar valores estándar de estas variables, estas se pueden describir.

data16 %>%
  summarise(max(Uso_internet, na.rm=T), min(Analfabetismo_2014, na.rm=T), 
            max(pbipc_2014, na.rm=T))
##   max(Uso_internet, na.rm = T) min(Analfabetismo_2014, na.rm = T)
## 1                           58                                  2
##   max(pbipc_2014, na.rm = T)
## 1                      47564

Por lo tanto, si queremos calcular un voto promedio general estimado a PPK, se podría reemplazar las variables independientes, en su promedio: X1=32.8, X2=7.8 y X3=14946.

\[\hat{Y} = 19.2 - 0.06*32.8 - 0.85*7.8 + 0.0003*14946 = 15.1 % \]

En conclusión, para valores promedio de las variables independientes, el voto estimado a PPK, según el modelo, sería de 15.1%. Este mismo ejercicio se puede hacer para los valores mínimos, máximos, para algunos percentiles particulares, etc.

Si se quiere predecir el voto a PPK para diferentes valores de una variable independiente, se puede reemplazar dejando las otras variables en el promedio. Por ejemplo, se quiere calcular el voto estimado a PPK para diferentes valores de analfabetismo. Lo primero es calcular los valores de analfabetismo a reemplazar. En este caso usaremos el mínimo, media. mediana y máximo.

data16 %>%
  summarise(min(Analfabetismo_2014, na.rm=T), mean(Analfabetismo_2014, na.rm=T), 
            median(Analfabetismo_2014, na.rm=T), max(Analfabetismo_2014, na.rm=T))
##   min(Analfabetismo_2014, na.rm = T) mean(Analfabetismo_2014, na.rm = T)
## 1                                  2                                7.76
##   median(Analfabetismo_2014, na.rm = T) max(Analfabetismo_2014, na.rm = T)
## 1                                     6                                 17

Luego, podemos reemplazar estos diferentes valores de analfabetismo, dejando las otras dos variables constantes en el promedio.

19.2 - 0.06*32.76 - 0.85*2 + 0.0003*14946
## [1] 20.0182
19.2 - 0.06*32.76 - 0.85*6 + 0.0003*14946
## [1] 16.6182
19.2 - 0.06*32.76 - 0.85*7.76 + 0.0003*14946
## [1] 15.1222
19.2 - 0.06*32.76 - 0.85*17 + 0.0003*14946
## [1] 7.2682

Comparando entre variables

En ocasiones se quiere analizar qué variable independiente tiene un mayor efecto sobre la variable dependiente. Este análisis no se puede hacer simplemente comparando los coeficientes del modelo anterior, debido a que estos coeficientes están en diferentes unidades: acceso a internet en porcentaje y PBI per cápita en soles.

Para poder comparar el efecto de cada variable sobre la variable dependiente, se tiene que calcular los coeficientes estandarizados. Estos coeficientes son independientes de las unidades de medida.

Para poder calculas los coeficientes estandarizados, se puede usar la librería jtools, que cuenta con el comando summ, donde se puede especificar scale=TRUE para que se presenten los coeficientes estandarizados.

library(jtools)
summ(modelo4, scale=T)
Observations 24 (1 missing obs. deleted)
Dependent variable Voto_PPK_2016_1
Type OLS linear regression
F(3,20) 7.71
0.54
Adj. R² 0.47
Est. S.E. t val. p
(Intercept) 15.23 1.03 14.81 0.00
Uso_internet -0.74 1.95 -0.38 0.71
Analfabetismo_2014 -3.63 1.65 -2.20 0.04
pbipc_2014 2.86 1.45 1.98 0.06
Standard errors: OLS; Continuous predictors are mean-centered and scaled by 1 s.d. The outcome variable remains in its original units.

De acuerdo a estos resultados, la variable independiente que tiene un efecto mayor sobre la variable dependiente es analfabetismo. Este análisis es mucho más útil cuando tenemos una mayor cantidad de variables independientes y de variables significativas en diferentes unidades de medición.

Para graficar los coeficientes

plot_summs(modelo4)
## Registered S3 methods overwritten by 'broom':
##   method            from  
##   tidy.glht         jtools
##   tidy.summary.glht jtools
## Loading required namespace: broom.mixed

Leyendo resultados académicos

El análisis de regresión lineal multivariado es una de las herramientas académicas más usadas. Es muy común encontrar tablas, como la que se muestra abajo, con resultados de este tipo.

Un punto importante, además de producir resultados, es saber interpretarlos. La tabla proviene de la tesis de pregrado de Sebastián Lazo, luego reportada en su artículo “Comportamiento electoral en el Perú: Un análisis del rol de las variables sociodemográficas en las elecciones presidenciales en primera vuelta de 2006 y 2011”, disponible aquí.

El artículo hace una revisión de la literatura de los estudios en Perú sobre el comportamiento electoral e identifica las principales variables que se discuten cómo explicativas del voto por ciertos candidatos.

Luego identifica las variables disponibles y que están relacionadas con el marco teórico. La unidad de análisis son los distritos del Perú. Una una variable dependiente por cada candidato y un set de variables independientes, que refieren de alguna manera con la revisión de la literatura. En los estudios cuantitativos se tiene la restricción de la disponibilidad de la información. No todos los factores que se hipotetiza que tienen relación con una variable han sido medidos.

Lazo obtiene los siguientes resultados. Se muestran los coeficientes, los signos de los coeficientes y asteriscos que indican el nivel de significancia de los resultados.

Lazo además incluye una nota al pie con los detalles de las significancias y con la fuerza expplicativa de cada modelo mediante el R2. Se asume que todos los modelos son válidos.

¿Qué conclusiones se puede tener de estos resultados acerca del perfil de los candidatos?

LS0tCnRpdGxlOiAiQ2xhc2UgMTIiCmF1dGhvcjogIkFydHVybyBNYWxkb25hZG8iCmRhdGU6ICIwNC8xMS8yMDI0IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCiAgICB0b2NfZGVwdGg6IDEKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRoZW1lOiBjb3NtbwogICAgaGlnaGxpZ2h0OiB0ZXh0bWF0ZQplZGl0b3Jfb3B0aW9uczoKICBtYXJrZG93bjoKICAgIHdyYXA6IHNlbnRlbmNlCmJpYmxpb2dyYXBoeTogcmVmZXJlbmNlcy5iaWIKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCiMgSW50cm9kdWNjacOzbiBhIGxhIHJlZ3Jlc2nDs24gbGluZWFsIG3Dumx0aXBsZQoKLSAgIEVsIGFuw6FsaXNpcyBiaXZhcmlhZG8gZXMgdW4gcHJpbWVyIHBhc28gZW4gZWwgYW7DoWxpc2lzIGVzdGFkw61zdGljby4KICAgIFNlIGVuY3VlbnRyYW4gKGNvcilyZWxhY2lvbmVzOiBYIC0gWQoKLSAgIMK/UG9yIHF1w6kgYWdyZWdhciBtw6FzIHZhcmlhYmxlcz8KICAgIFNlIGJ1c2NhIGFwcm94aW1hcnNlIGEgbGEgY2F1c2FsaWRhZDogWCAtXD4gWQoKLSAgIFBhcmEgYXByb3hpbWFyc2UgYSBlc3RhYmxlY2VyIGNhdXNhbGlkYWQgZXMgbmVjZXNhcmlvIGVsIGFuw6FsaXNpcyBtdWx0aXZhcmlhZG8uCgotICAgUGFyYSBoYWJsYXIgZGUgY2F1c2FsaWRhZCwgc2UgcmVxdWllcmVuIGNpZXJ0b3MgY3JpdGVyaW9zOgoKICAgIC0gICBBc29jaWFjacOzbiBlc3RhZMOtc3RpY2EgZW50cmUgbGFzIHZhcmlhYmxlcywgcGVybyBhc29jaWFjacOzbiBubyBpbXBsaWNhIGNhdXNhbGlkYWQuCgogICAgLSAgIE9yZGVuIHRlbXBvcmFsOiBxdWUgbGEgY2F1c2Egb2N1cnJhIGFudGVzIHF1ZSBlbCBlZmVjdG8uCgogICAgLSAgIEVsaW1pbmFjacOzbiBkZSBoaXDDs3Rlc2lzIGFsdGVybmF0aXZhcy4KICAgICAgICBFc3RhcyBoaXDDs3Rlc2lzIGFsdGVybmF0aXZhcyByZWd1bGFybWVudGUgcGFydGVuIGRlIGxhIGxpdGVyYXR1cmEuCgogICAgLSAgIENvbnNpc3RlbmNpYTogbGEgcmVsYWNpw7NuIGRlYmUgc2VyIGNvbnNpc3RlbnRlIGVuIGRpZmVyZW50ZXMgZXN0dWRpb3MsIHBvYmxhY2lvbmVzIHkgY29udGV4dG9zLgoKICAgIC0gICBEb3NpZmljYWNpw7NuOiBjYW1iaW9zIGVuIGxhIG1hZ25pdHVkIGRlIFggbGxldmFuIGEgY2FtYmlvcyBjb3JyZXNwb25kaWVudGVzIGVuIFkuCgogICAgLSAgIFBsYXVzaWJpbGlkYWQ6IGRlYmUgaGFiZXIgdW5hIGV4cGxpY2FjacOzbiB0ZcOzcmljYSBvIG1lY2FuaXNtbyBwbGF1c2libGUgcXVlIHJlc3BhbGRlIGxhIHJlbGFjacOzbiBjYXVzYWwuCgogICAgLSAgIEVzcGVjaWZpY2lkYWQ6IHNpIHVuYSBjYXVzYSBYIGxsZXZhIGEgdW4gZWZlY3RvIFkgZXNwZWPDrWZpY28geSBubyBhIG3Dumx0aXBsZXMgZWZlY3RvcyBkaWZlcmVudGVzLgoKICAgIC0gICBDb2hlcmVuY2lhOiBsYSByZWxhY2nDs24gY2F1c2FsIGRlYmUgc2VyIGNvaGVyZW50ZSBjb24gZWwgY29ub2NpbWllbnRvIGdlbmVyYWwgZXhpc3RlbnRlLCBwb3IgZWplbXBsbyBlbiBkaWZlcmVudGVzIGRpc2NpcGxpbmFzLgoKIyBDb250cm9sIGVzdGFkw61zdGljbwoKUGFyYSBldmFsdWFyIChvIGVsaW1pbmFyKSBsYXMgaGlww7N0ZXNpcyBhbHRlcm5hdGl2YXMsIHNlIHJlYWxpemEgdW4gImNvbnRyb2wgZXN0YWTDrXN0aWNvIi4KTGEgaWRlYSBlczoKCi0gICBFdmFsdWFyIHNpIGxhIGFzb2NpYWNpw7NuIGVudHJlIFggLSBZIHBlcm1hbmVjZSBzaSBzZSByZW11ZXZlIGVsIGVmZWN0byBkZSBvdHJhIHZhcmlhYmxlLCBlcyBkZWNpciwgc2kgc2UgY29udHJvbGEgcG9yIHVuYSB0ZXJjZXJhIHZhcmlhYmxlIChvIGN1YXJ0YSBvIHF1aW50YSBvIGV0Yy4pLgoKLSAgIFBhcmEgY29udHJvbGFyIHBvciB2YXJpYWJsZXMgaW1wb3J0YW50ZXMsIGNvbW8gbGFzIHNvY2lvZGVtb2dyw6FmaWNhcy4KCi0gICBFbiB1biBleHBlcmltZW50byBzZSBwdWVkZSBjb250cm9sYXIgcG9yIHVuIGdyYW4gbsO6bWVybyBkZSB2YXJpYWJsZXMgZGVzZGUgZWwgZGlzZcOxby4KICAgIFBvciBlamVtcGxvLCBzZSBwdWVkZSBhc2VndXJhciBxdWUgZWwgc3VqZXRvIGV4cGVyaW1lbnRhbCBlc3TDqSBleHB1ZXN0byBhIGxhcyBtaXNtYXMgY29uZGljaW9uZXMuCiAgICBDb250cm9sIGV4cGVyaW1lbnRhbC4KCi0gICBFbiBsb3MgbcOpdG9kb3Mgb2JzZXJ2YWNpb25hbGVzIHNlIHB1ZWRlIGFwcm94aW1hciB1biBjb250cm9sIGV4cGVyaW1lbnRhbCBhZ3J1cGFuZG8gbGFzIG9ic2VydmFjaW9uZXMgZW4gZ3J1cG9zIGRlIHZhbG9yZXMgaWd1YWxlcyBvIHNpbWlsYXJlcyBkZSBsYXMgdmFyaWFibGVzIGRlIGNvbnRyb2wuCiAgICBDb250cm9sIGVzdGFkw61zdGljby4KCi0gICBFbiBsYSBwcsOhY3RpY2EsIHNlIGFuYWxpemEgbGEgcmVsYWNpw7NuIGVudHJlIFggLSBZIHBhcmEgdmFsb3JlcyBzaW1pbGFyZXMgbyBpZ3VhbGVzIGRlIHVuYSB2YXJpYWJsZSBaLgogICAgRGUgZXN0YSBtYW5lcmEgc2UgZWxpbWluYSBsYSBpbmZsdWVuY2lhIGRlIFogZW4gbGEgcmVsYWNpw7NuIGVudHJlIFggLSBZLgogICAgRXMgdW4gcGFzbyBlbiBlbCBlc3RhYmxlY2ltaWVudG8gZGUgWCAtXD4gWS4KCi0gICBTaSBsYSByZWxhY2nDs24gZW50cmUgWCAtIFkgZGVzYXBhcmVjZSBjdWFuZG8gc2UgY29udHJvbGEgcG9yIFosIHNlIGRpY2UgcXVlIGxhIHJlbGFjacOzbiBlcmEgZXNww7pyZWEuCgpQYXJhIGRhciB1biBlamVtcGxvLCB1c2FyZW1vcyBsb3MgZGF0b3MgZGUgbGEgZWxlY2Npw7NuIDIwMTYuCkVzdGEgYmFzZSBkZSBkYXRvcyBpbmNsdXllIHVuYSB2YXJpYWJsZSBkZSBQQkkgcGVyIGPDoXBpdGEgZW4gY2FkYSBkZXBhcnRhbWVudG8uCkNvbiBlc3RhIHZhcmlhYmxlIHNlIGhhIGNyZWFkbyBvdHJhIHZhcmlhYmxlIGFncnVwYW5kbyBlbCBQQkkgZW4gMyBncnVwb3M6IGFsdG8sIG1lZGlvLCBiYWpvLgoKYGBge3IgYmFzZX0KbGlicmFyeShyaW8pCmRhdGExNiA9IGltcG9ydCgiYmFzZXMvZGF0b3MyMDE2X3YzLnNhdiIpCmBgYAoKRW4gcHJpbWVyIGx1Z2FyLCBoYXJlbW9zIHVuYSBpbnNwZWNjacOzbiB2aXN1YWwgZGUgbGEgcmVsYWNpw7NuIGVudHJlIGVsIGFjY2VzbyBhIGludGVybmV0IHkgZWwgdm90byBhIFBQSywgbWVkaWFudGUgdW4gZ3LDoWZpY28gZGUgZGlzcGVyc2nDs24uCkVzdGEgZ3LDoWZpY28gaW5jbHVpcsOhIHVuYSB0ZXJjZXJhIHZhcmlhYmxlLCBQQkkgcGVyIGPDoXBpdGEsIHF1ZSBzZSB2aXN1YWxpemFyw6EgY29tbyB1biBjb2xvciBkZSBjYWRhIG9ic2VydmFjacOzbi4KCmBgYHtyIGRpc3BlcnNpb24xfQpsaWJyYXJ5KGdncGxvdDIpCmdncGxvdChkYXRhMTYsIGFlcyh4PVVzb19pbnRlcm5ldCwgeT1Wb3RvX1BQS18yMDE2XzEpKSsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1wYmlwY19ncnVwb3MpKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPUYpKyAjYWdyZWdhciBsw61uZWEgZGUgdGVuZGVuY2lhCiAgZ2VvbV90ZXh0KGRhdGE9ZGF0YTE2LCBhZXMobGFiZWw9RHB0byksIAogICAgICAgICAgICBjZXg9MiwgbnVkZ2VfeSA9IDEuMSwgY2hlY2tfb3ZlcmxhcCA9IFQpKyAjUGF0YSBldGlxdWV0YXIgbG9zIHB1bnRvcywgZGFybGVzIHVuIHRhbWHDsW8sIHViaWNhY2nDs24geSBwcmV2ZW5pciBxdWUgc2Ugc29icmVwb25nYW4KICBsYWJzKHg9IlBvcmNlbnRhamUgZGUgdXNvIGRlIGludGVybmV0IiwgCiAgICAgICB5PSJWb3RvIGEgUFBLICgxZXJhIHZ1ZWx0YSAyMDE2KSIpKyAjcGFyYSBldGlxdWV0YXIgbG9zIGVqZXMKICB0aGVtZV9saWdodCgpCmBgYAoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpkYXRhMTYgPSBkYXRhMTYgJT4lCiAgbXV0YXRlKHBiaWdydXBvID0gZmFjdG9yKHBiaXBjX2dydXBvcywgbGFiZWxzPWMoIkJham8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNZWRpbyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBbHRvIikpKQpgYGAKCmBgYHtyIGRpc3BlcnNpb24yfQpnZ3Bsb3QoZGF0YTE2LCBhZXMoeD1Vc29faW50ZXJuZXQsIHk9Vm90b19QUEtfMjAxNl8xKSkrCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9cGJpZ3J1cG8pKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPUYpKyAjYWdyZWdhciBsw61uZWEgZGUgdGVuZGVuY2lhCiAgZ2VvbV90ZXh0KGRhdGE9ZGF0YTE2LCBhZXMobGFiZWw9RHB0byksIAogICAgICAgICAgICBjZXg9MiwgbnVkZ2VfeSA9IDEuMSwgY2hlY2tfb3ZlcmxhcCA9IFQpKyAjUGF0YSBldGlxdWV0YXIgbG9zIHB1bnRvcywgZGFybGVzIHVuIHRhbWHDsW8sIHViaWNhY2nDs24geSBwcmV2ZW5pciBxdWUgc2Ugc29icmVwb25nYW4KICBsYWJzKHg9IlBvcmNlbnRhamUgZGUgdXNvIGRlIGludGVybmV0IiwgCiAgICAgICB5PSJWb3RvIGEgUFBLICgxZXJhIHZ1ZWx0YSAyMDE2KSIpKyAjcGFyYSBldGlxdWV0YXIgbG9zIGVqZXMKICB0aGVtZV9saWdodCgpCmBgYAoKRWwgY29sb3IgZGUgY2FkYSBwdW50byByZXByZXNlbnRhIHVuIG5pdmVsIGRlIFBCSSBwZXIgY8OhcGl0YTogbmVncm8gc2lnbmlmaWNhIFBCSSBwZXIgY8OhcGl0YSBkZXBhcnRhbWVudGFsIGJham8sIHJvam8gc2lnbmlmaWNhIFBCSSBwZXIgY8OhcGl0YSBkZXBhcnRhbWVudGFsIG1lZGlvIHkgdmVyZGUgc2lnbmlmaWNhIFBCSSBwZXIgY8OhcGl0YSBkZXBhcnRhbWVudGFsIGFsdG8uCgpQYXJhIGFuYWxpemFyIHZpc3VhbG1lbnRlIGxhIHJlbGFjacOzbiBlbnRyZSBhY2Nlc28gYSBpbnRlcm5ldCB5IHZvdG8gYSBQUEssIGNvbnRyb2xhbmRvIHBvciBlbCBQQkkgcGVyIGPDoXBpdGEsIHNlIHB1ZWRlIGFuYWxpemFyIGV2YWx1YXIgbGEgcmVsYWNpw7NuIGVudHJlIFggLSBZIHBhcmEgZ3J1cG9zIGRlIFouCkVzIGRlY2lyLCBzZSBwdWVkZSBldmFsdWFyIHZpc3VhbG1lbnRlIGxhIHJlbGFjacOzbiBlbnRyZSBhY2Nlc28gYSBpbnRlcm5ldCAtIHZvdG8gYSBQUEssIGVuIGNhZGEgZ3J1cG8gZGUgY29sb3IuCgrCv0N1w6FsIGVzIGxhIHJlbGFjacOzbiBlbnRyZSBYIC0gWSBwYXJhIGVsIGdydXBvIGRlIG9ic2VydmFjaW9uZXMgZW4gcm9qbyAoUEJJIHBlciBjw6FwaXRhIGRlcGFydGFtZW50YWwgYmFqbyk/ClNlIG9ic2VydmEgdW5hIHJlbGFjacOzbiBwb3NpdGl2YSwgYXVucXVlIHRlbnVlLgoKwr9DdcOhbCBlcyBsYSByZWxhY2nDs24gZW50cmUgWCAtIFkgcGFyYSBlbCBncnVwbyBkZSBvYnNlcnZhY2lvbmVzIGVuIHZlcmRlIChQQkkgcGVyIGPDoXBpdGEgZGVwYXJ0YW1lbnRhbCBtZWRpbyk/ClNlIG9ic2VydmEgdW5hIHJlbGFjacOzbiBuZWdhdGl2YSwgY29udHJhcmlvIGEgbGEgaGlww7N0ZXNpcyBwbGFudGVhZGEuCgrCv0N1w6FsIGVzIGxhIHJlbGFjacOzbiBlbnRyZSBYIC0gWSBwYXJhIGVsIGdydXBvIGRlIG9ic2VydmFjaW9uZXMgZW4gYXp1bCAoUEJJIHBlciBjw6FwaXRhIGRlcGFydGFtZW50YWwgYWx0byk/ClNlIG9ic2VydmEgdW5hIHJlbGFjacOzbiBwb3NpdGl2YS4KClByZWd1bnRhIGZpbmFsOiDCv3NlIG1hbnRpZW5lIGxhIHJlbGFjacOzbiBlbnRyZSBhY2Nlc28gYSBpbnRlcm5ldCB5IHZvdG8gYSBQUEsgZW4gY2FkYSBncnVwbyBkZSBQQkkgcGVyIGPDoXBpdGE/CgpFbiB1biBleHRyZW1vLCBsYSByZWxhY2nDs24gZW50cmUgWCAtIFkgc2UgbWFudGllbmUgKGVuIGxhIG1pc21hIGRpcmVjY2nDs24pIHBhcmEgY2FkYSBncnVwbyBkZSBaLgpTaSBlc3RvIGVzIGFzw60sIHNlIGRpY2UgcXVlIGxhIHJlbGFjacOzbiBlbnRyZSBYIC0gWSBzZSBtYW50aWVuZSBjb250cm9sYW5kbyBwb3IgWi4KCkVuIGVsIG90cm8gZXh0cmVtb3MsIGxhIHJlbGFjacOzbiBlbnRyZSBYIC0gWSBubyBzZSBtYW50aWVuZSBwYXJhIG5pbmfDum4gZ3J1cG8gZGUgWi4KU2kgZXN0byBlcyBhc8OtLCBzZSBkaWNlIHF1ZSBsYSByZWxhY2nDs24gZW50cmUgWCAtIFkgZXMgdW5hIHJlbGFjacOzbiBlc3DDunJlYSwgcXVlIGN1YW5kbyBzZSBjb250cm9sYSBwb3IgWiwgZXN0YSByZWxhY2nDs24gYml2YXJpYWRhIGRlc2FwYXJlY2UuCgpFbiBsYSBwcsOhY3RpY2EsIGVsIGFuw6FsaXNpcyBtdWx0aXZhcmlhZG8gYW5hbGl6YSBzaSBsYSByZWxhY2nDs24gZW50cmUgWCAtIFkgc2UgbWFudGllbmUgImVuIHByb21lZGlvIiBwYXJhIGNhZGEgZ3J1cG8gZGUgWi4KUGFyYSBoYWNlciBlc3RhIGV2YWx1YWNpw7NuIG5vIGVzIHN1ZmljaWVudGUgKHkgYSB2ZWNlcywgbm8gZXMgbmVjZXNhcmlvKSBlbCBhbsOhbGlzaXMgdmlzdWFsIGVuIGVsIGRpYWdyYW1hIGRlIGRpc3BlcnNpw7NuLCBzaW5vIHF1ZSBoYWNlIGZhbHRhIHVuIG1vZGVsbyBlc3RhZMOtc3RpY28uCgojIE1vZGVsbyBkZSByZWdyZXNpw7NuIGxpbmVhbCBtw7psdGlwbGUKClNlIHVzYSB1biBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgbcO6bHRpcGxlIHBhcmEgZWwgY8OhbGN1bG8gZGUgbG9zIGVmZWN0b3MgZGUgdmFyaW9zIHByZWRpY3RvcmVzIGVuIHVuYSB2YXJpYWJsZSBkZXBlbmRpZW50ZSBudW3DqXJpY2EgZW4gdW4gbWlzbW8gbW9kZWxvLgpQb3IgZWplbXBsbywgc2kgcXVpc2nDqXJhbW9zIGV2YWx1YXIgbGEgcmVsYWNpw7NuIGVudHJlIGxhIHZhcmlhYmxlIGFjY2VzbyBhIGludGVybmV0IHkgbGEgdmFyaWFibGUgUEJJIHBlciBjw6FwaXRhIGVuIGVsIHZvdG8gYSBQUEssIHNlIHB1ZWRlIGluY2x1aXIgYW1iYXMgdmFyaWFibGVzIGluZGVwZW5kaWVudGVzIGVuIHVuIG1pc21vIG1vZGVsby4KCkVuIGVzZSBjYXNvLCBlbCBtb2RlbG8gc2Vyw61hOiAkXGhhdHtZfSA9IFxoYXR7XGFscGhhfSArIFxoYXR7XGJldGFfMX0qWF8xK1xoYXR7XGJldGFfMn0qWF8yJAoKU2kgbGEgcmVsYWNpw7NuIGJpdmFyaWFkYSBzZSBldmFsw7phIGVuIHVuIHBsYW5vIGNhcnRlc2lhbm8sIGN1YW5kbyBzZSBpbmNsdXllIHVuYSB0ZXJjZXJhIHZhcmlhYmxlLCBlbCBhbsOhbGlzaXMgcGFzYSBkZSB1biBwbGFubyBjYXJ0ZXNpYW5vIGEgdW4gZXNwYWNpbyBjYXJ0ZXNpYW5vLgpQYXJhIGZpbmVzIGV4cGxpY2F0aXZvcywgZXN0byBzZSBwdWVkZSBncmFmaWNhciBlbiB1biBkaWFncmFtYSBkZSBkaXNwZXJzacOzbiBlbiB0cmVzIGRpbWVuc2lvbmVzLgoKYGBge3IgM2R9CiNFc3RlIGPDs2RpZ28gTk8gc2UgZXZhbHVhcsOhCmxpYnJhcnkoc2NhdHRlcnBsb3QzZCkKc2NhdHRlcnBsb3QzZCh4PWRhdGExNiRVc29faW50ZXJuZXQsIHk9ZGF0YTE2JFZvdG9fUFBLXzIwMTZfMSwgej1kYXRhMTYkcGJpcGNfMjAxNCkKcGFpcnMoZGF0YTE2JFVzb19pbnRlcm5ldCB+IGRhdGExNiRVc29faW50ZXJuZXQrZGF0YTE2JHBiaXBjXzIwMTQpCmBgYAoKRW4gZXN0ZSBjYXNvLCBjYWRhIHB1bnRvIGVzdGFyw61hIHViaWNhZG8gZGUgYWN1ZXJkbyBhIGxvcyB2YWxvcmVzIGVuIGxhcyAzIHZhcmlhYmxlcy4KTm8gZXMgZsOhY2lsIHZpc3VhbGl6YXIgbGEgcmVsYWNpb25lcyBwYXJjaWFsZXMgZW50cmUgWCAtIFkgeSBlbnRyZSBaIC0gWS4KVW5hIG1lam9yIHZpc3VhbGl6YWNpw7NuIGVzIG1pcmFuZG8gbG9zIGxhZG9zIGRlbCBjdWJvLgoKVW5vIHBvZHLDrWEgcGVuc2FyIHF1ZSBlcyBzdWZpY2llbnRlIGNvbiByZWFsaXphciBkb3MgcmVncmVzaW9uZXMgbGluZWFsZXMgc2ltcGxlcyBlbnRyZSBjYWRhIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgY29uIGxhIGRlcGVuZGllbnRlLgpTaSBsbyBoYWNlbW9zLCB0ZW5kcsOtYW1vcyBkb3MgbW9kZWxvcyBzaW1wbGVzLgpQYXJhIGxhIHJlbGFjacOzbiBvcmlnaW5hbCBlbnRyZSBhY2Nlc28gYSBpbnRlcm5ldCB5IHZvdG8gYSBQUEssIHNlIHRpZW5lLgoKYGBge3Igb2xzIHNpbXBsZX0KbW9kZWxvMSA9IGxtKGRhdGExNiRWb3RvX1BQS18yMDE2XzEgfiBkYXRhMTYkVXNvX2ludGVybmV0KQpzdW1tYXJ5KG1vZGVsbzEpCmBgYAoKWSBwYXJhIGxhIHNlZ3VuZGEgdmFyaWFibGUsIHNlIHRpZW5lLgoKYGBge3Igb2xzIHNpbXBsZSAyfQptb2RlbG8yID0gbG0oZGF0YTE2JFZvdG9fUFBLXzIwMTZfMSB+IGRhdGExNiRwYmlwY18yMDE0KQpzdW1tYXJ5KG1vZGVsbzIpCmBgYAoKYGBge3J9Cm1vZGVsbzMgPSBsbShWb3RvX1BQS18yMDE2XzEgfiBBbmFsZmFiZXRpc21vXzIwMTQsIGRhdGE9ZGF0YTE2KQpzdW1tYXJ5KG1vZGVsbzMpCmBgYAoKTWlyYW5kbyBsb3MgcmVzdWx0YWRvcyBkZSBhbWJvcyBtb2RlbG9zIGxpbmVhbGVzIHNpbXBsZXMsIHNlIHRpZW5lIHF1ZSBhbWJhcyB2YXJpYWJsZXMsIHRhbnRvIGFjY2VzbyBhIGludGVybmV0IGNvbW8gUEJJLCBzb24gc2lnbmlmaWNhdGl2YXMuCkFtYmFzIHRpZW5lbiB1biBlZmVjdG8gZGlyZWN0bywgZXMgZGVjaXIsIGEgbWF5b3IgYWNjZXNvIGEgaW50ZXJuZXQsIG1heW9yIHZvdG8gYSBQUEsgZW4gcHJvbWVkaW8sIHkgYSBtYXlvciBQQkkgcGVyIGPDoXBpdGEsIG1heW9yIHZvdG8gYSBQUEsgZW4gcHJvbWVkaW8uCgpFc3RvcyBtb2RlbG9zLCBzaW4gZW1iYXJnbywgYW5hbGl6YW4gZWwgaW1wYWN0byBpbmRpdmlkdWFsIGRlIGNhZGEgdmFyaWFibGUsIHNpbiBuaW5nw7puIHRpcG8gZGUgY29udHJvbCBlc3RhZMOtc3RpY28uCkxvcyBtb2RlbG9zIGxpbmVhbGVzIHNpbXBsZSwgZW4gZXNlIHNlbnRpZG8sIGVzdMOhbiBtw6FzIGNlcmNhIGRlIHVuIGFuw6FsaXNpcyBkZSBjb3JyZWxhY2nDs24sIHF1ZSBkZSB1bm8gZGUgY2F1c2FsaWRhZC4KClBhcmEgdHJhdGFyIGRlIGFjZXJjYXJub3MgYWwgaWRlYWwgZGUgY2F1c2FsaWRhZCwgc2UgdGllbmUgcXVlIGNvbnRyb2xhciBwb3IgcG9zaWJsZXMgZXhwbGljYWNpb25lcyBhbHRlcm5hdGl2YXMuCkxhIGRpc2N1c2nDs24gY29uIHJlc3BlY3RvIGEgbGEgZWxlY2Npw7NuIDIwMTYgcGxhbnRlYWJhIHF1ZSBlbCB2b3RvIGEgUFBLIHRhbWJpw6luIHRlbsOtYSB1biBjb21wb25lbnRlIGVjb27Ds21pY28uClNlIGVzcGVjdWxhYmEgcXVlIGxvcyBzZWN0b3JlcyBtw6FzIGJlbmVmaWNpYWRvcyBkZWwgYm9vbSBlY29uw7NtaWNvIHBvZMOtYW4gdm90YXIgZW4gbWF5b3IgbWVkaWRhIGEgZmF2b3IgZGUgUFBLLgpTaSBlc3RvIGVzIGFzw60sIGxhIHZhcmlhYmxlIGRlIFBCSSBwZXIgY8OhcGl0YSBwdWVkZSByZWNvZ2VyIGVzdGUgZmVuw7NtZW5vLgoKTGEgaWRlYSBlcyBldmFsdWFyIHNpIGxhIHJlbGFjacOzbiBlbnRyZSBhY2Nlc28gYSBpbnRlcm5ldCB5IHZvdG8gYSBQUEsgc2UgbWFudGllbmUgY29udHJvbGFuZG8gcG9yIHVuYSB2YXJpYWJsZSBlY29uw7NtaWNhLgpQYXJhIGVzdG8sIHNlIHJlYWxpemEgdW4gbW9kZWxvIGxpbmVhbCBtw7psdGlwbGUgdXNhbmRvIGVsIHZvdG8gYSBQUEsgY29tbyB2YXJpYWJsZSBkZXBlbmRpZW50ZSB5IGVsIGFjY2VzbyBhIGludGVybmV0IHkgZWwgUEJJIHBlciBjw6FwaXRhIGNvbW8gdmFyaWFibGVzIGluZGVwZW5kaWVudGVzLCBlbiB1biBtaXNtbyBtb2RlbG8uCkVsIGNvbWFuZG8gYGxtYCBwZXJtaXRlIGluY2x1aXIgdmFyaW9zIHByZWRpY3RvcmVzIGluZGVwZW5kaWVudGVzIGVuIHVuIG1pc21vIG1vZGVsbyBjb24gZWwgc8OtbWJvbG8gKy4KCmBgYHtyIG9scyBtdWx0aXBsZX0KbW9kZWxvNCA9IGxtKFZvdG9fUFBLXzIwMTZfMSB+IFVzb19pbnRlcm5ldCArIEFuYWxmYWJldGlzbW9fMjAxNCArIHBiaXBjXzIwMTQsIGRhdGE9ZGF0YTE2KQpzdW1tYXJ5KG1vZGVsbzQpCmBgYAoKIyBMZXllbmRvIGVsIG1vZGVsbwoKIyMgwr9FcyB2w6FsaWRvIGVsIG1vZGVsbz8KCkNvbW8gYWhvcmEgdGVuZW1vcyB0cmVzIHZhcmlhYmxlcyBpbmRlcGVuZGllbnRlcywgbGEgdmFsaWRleiBkZWwgbW9kZWxvIHlhIG5vIGRlcGVuZGUgc29sbyBkZSBsYSByZWxhY2nDs24gZGUgdW5hIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgY29uIGxhIGRlcGVuZGllbnRlLgpQYXJhIGV2YWx1YXIgbGEgdmFsaWRleiBkZWwgbW9kZWxvIHNlIHRpZW5lIHF1ZSBoYWNlciB1bmEgZXZhbHVhY2nDs24gZ2VuZXJhbC4KRXN0YSBldmFsdWFjacOzbiBwbGFudGVhIHVuYSBoaXDDs3Rlc2lzIGNlcm8gcXVlIHRvZGFzIGxhcyBwZW5kaWVudGVzIChvIGNvZWZpY2llbnRlcykgc29uIGlndWFsZXMgYSBjZXJvLgoKJEgwOiBcYmV0YV8xID0gXGJldGFfMiA9IFxiZXRhXzMgPS4uLlxiZXRhX24gPSAwJCBMYSBoaXDDs3Rlc2lzIGFsdGVybmF0aXZhIGluZGljYSBxdWUgYWwgbWVub3MgdW5hIHBlbmRpZW50ZSBlcyBkaWZlcmVudGUgZGUgY2VybywgbG8gcXVlIGluZGljYXLDrWEgcXVlIGFsIG1lbm9zIHVuYSB2YXJpYWJsZSBpbmRlcGVuZGllbnRlIHRpZW5lIHJlbGFjacOzbiBjb24gbGEgdmFyaWFibGUgZGVwZW5kaWVudGUuCgpQYXJhIGV2YWx1YXIgZXN0YSBoaXDDs3Rlc2lzIHNlIGFuYWxpemEgbG9zIHJlc3VsdGFkb3MgZGUgbGEgcHJ1ZWJhIEYgKGVuIGxhIMO6bHRpbWEgbMOtbmVhIGRlIHJlc3VsdGFkb3MgZGVsIG1vZGVsbykuCkVsIGVzdGFkw61zdGljbyBGID0gNy43MSB0aWVuZSB1biBwLXZhbHVlIGFzb2NpYWRvIGRlIDAuMDAxLgpFc3RlIHAtdmFsdWUgZXMgbWVub3IgZGUgMC4wNSwgcG9yIGxvIHF1ZSBwb2RlbW9zIHJlY2hhemFyIGxhIEgwIHkgYWZpcm1hciBxdWUgYWwgbWVub3MgdW4gY29lZmljaWVudGUgZGViZSBzZXIgZGlmZXJlbnRlIGRlIGNlcm8uCgojIyBUZXN0IGRlIGluZmVyZW5jaWE6IMK/aGF5IHJlbGFjacOzbiBlbnRyZSBsYXMgVklzIHkgbGEgVkQ/CgpFc3RhIHByZWd1bnRhIHNlIHJlc3BvbmRlIHBhcmEgY2FkYSB2YXJpYWJsZSBpbmRlcGVuZGllbnRlLCBldmFsdWFjacOzbiBxdWUgc2UgaGFjZSBkZW50cm8gZGUgdW4gbW9kZWxvIGxpbmVhbCBtdWx0aXZhcmlhZG8sIGRvbmRlIHNlIGNvbnRyb2xhIHBvciBlbCByZXN0byBkZSB2YXJpYWJsZXMuCgpDYWRhIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgdGllbmUgdW5hIGZpbGEgZGUgcmVzdWx0YWRvcyBjb24gc3UgcHJvcGlhIHBydWViYSBkZSBpbmRlcGVuZGVuY2lhLgpFc3RhIHBydWViYXMgdGllbmUgbGFzIHNpZ3VpZW50ZXMgaGlww7N0ZXNpczoKCiRIMDogXGJldGFfMSA9IDAkICRIMDogXGJldGFfMiA9IDAkCgpQYXJhIGxhIHZhcmlhYmxlIHVzbyBkZSBpbnRlcm5ldCwgbGEgZmlsYSBjb3JyZXNwb25kaWVudGUgbm9zIGluZGljYSBxdWUgdGVuZW1vcyB1biBjb2VmaWNpZW50ZSBkZSAtMC4wNi4KUGFyYSBlc3RhIHZhcmlhYmxlIGVsIGVzdGFkw61zdGljbyBkZSBsYSBwcnVlYmEgdCB0aWVuZSB1biBwLXZhbHVlIGRlIDAuNzEuCkVzdGUgcC12YWx1ZSBlcyBtYXlvciBkZSAwLjA1LCBwb3IgbG8gcXVlIGZhbGxhbW9zIGVuIHJlY2hhemFyIGxhIEgwLgpFcyBkZWNpciwgc2UgdGllbmUgNzElIGRlIHByb2JhYmlsaWRhZGVzIGRlIHRlbmVyIHVuIGNvZWZpY2llbnRlIGRlIC0wLjA2LCBzaSBlbCB2ZXJkYWRlcm8gdmFsb3IgZGVsIHBhcsOhbWV0cm8gZXMgMC4KRW4gcmVzdW1lbiwgY29uIGVzdG9zIHZhbG9yZXMsIG5vIGVuY29udHJhbW9zIHVuYSByZWxhY2nDs24gZW50cmUgYWNjZXNvIGEgaW50ZXJuZXQgeSB2b3RvIGEgUFBLLgoKUGFyYSBsYSB2YXJpYWJsZSwgUEJJIHBlciBjw6FwaXRhLCB0ZW5lbW9zIHVuIGNvZWZpY2llbnRlIGRlIDAuMDAwMywgY29uIHVuIGVzdGFkw61zdGljbyBkZSBsYSBwcnVlYmEgdCBkZSAxLjk4IHkgdW4gcC12YWx1ZSBkZSAwLjA2LgpDb24gZXN0ZSBwLXZhbHVlIG5vIHBvZGVtb3MgcmVjaGF6YXIgbGEgSDAgYSB1biB2YWxvciBjcsOtdGljbyBkZSAwLjA1KS4KRXN0ZSBwLXZhbHVlIG5vIGVzIG1lbm9zIGEgMC4wNSwgcG9yIGxvIHF1ZSBubyBzZXLDrWEgc2lnbmlmaWNhdGl2by4KUGVybywgc2kgc2UgcmVsYWphIGVsIGNyaXRlcmlvLCBlc3RlIHAtdmFsdWUgZXMgbWVub3IgYSAwLjEwLgpFcyBkZWNpciwgc2UgdGllbmUgNiUgZGUgcHJvYmFiaWxpZGFkZXMgZGUgb2JzZXJ2YXIgdW5hIHBlbmRpZW50ZSBkZSAwLjAwMDMgc2kgbGEgdmVyZGFkZXJhIHBlbmRpZW50ZSBmdWVyYSAwLgpQb2RlbW9zIGFzdW1pciBxdWUgZXN0YSBwcm9iYWJpbGlkYWQgZXMgYmFqYSwgcG9yIGxvIHF1ZSBwb2RlbW9zIGNvbmNsdWlyIHF1ZSBzw60gZXhpc3RlIHVuYSByZWxhY2nDs24gZW50cmUgUEJJIHkgdm90byBhIFBQSyBhbCAwLjEgZGUgdmFsb3IgY3LDrXRpY28uCgpQYXJhIGxhIHZhcmlhYmxlIGRlIGFuYWxmYWJldGlzbW8sIHNlIHRpZW5lIHVuIGNvZWZpY2llbnRlIGRlIC0wLjg1IGNvbiB1biBlc3RhZMOtc3RpY28gZGUgLTIuMiB5IHVuIHAtdmFsdWUgZGUgMC4wNCwgcXVlIGVzIG1lbm9yIHF1ZSAwLjA1LCBwb3IgbG8gcXVlIHBvZGVtb3MgcmVjaGF6YXIgbGEgSDAuClNlIGNvbmNsdXllIHF1ZSBzw60gZXhpc3RlIHJlbGFjacOzbiBlbnRyZSBhbmFsZmFiZXRpc21vIHkgdm90byBhIFBQSywgY29udHJvbGFuZG8gcG9yIG90cm9zIGZhY3RvcmVzLCBjb21vIHJpcXVlemEgeSB1c28gZGUgaW50ZXJuZXQuCgpFbiBjb25jbHVzacOzbiwgbGEgcmVsYWNpw7NuIGVudHJlIGFjY2VzbyBhIGludGVybmV0IHkgdm90byBhIFBQSywgcXVlIHNlIGhhYsOtYSBlbmNvbnRyYWRvIGVuIGVsIGFuw6FsaXNpcyBiaXZhcmlhZG8sIG5vIHNlIG1hbnRpZW5lIGVuIHVuIGFuw6FsaXNpcyBtdWx0aXZhcmlhZG8sIGN1YW5kbyBzZSBjb250cm9sYSBwb3IgbGEgdmFyaWFibGUgUEJJLgpNdXkgcHJvYmFibGVtZW50ZSBlc3RlbW9zIGhhYmxhbmRvIGRlIHVuYSByZWxhY2nDs24gZXNww7pyZWEsIHB1ZXMgUEJJIHBvZHLDrWEgdGVuZXIgdW4gZWZlY3RvIHRhbnRvIGVuIGVsIGFjY2VzbyBhIGludGVybmV0IChkZXBhcnRhbWVudG9zIG3DoXMgcmljb3MsIHRpZW5lbiBmYW1pbGlhcyBxdWUgcHVlZGVuIHBhZ2FyIHBvciBlbCBzZXJ2aWNpbyBkZSBpbnRlcm5ldCksIGNvbW8gZW4gZWwgdm90byBhIFBQSyAoZGVwYXJ0YW1lbnRvcyBtw6FzIHJpY29zLCB2b3RhbiBlbiBtYXlvciBtZWRpZGEgYSBQUEspLgoKIyMgRGlyZWNjacOzbiBkZSBsYSByZWxhY2nDs24KCkRlIGxhIG1pc21hIG1hbmVyYSBxdWUgZW4gYW7DoWxpc2lzIGJpdmFyaWFkbywgbGEgZGlyZWNjacOzbiBkZSBsYSByZWxhY2nDs24gZW50cmUgbGFzIHZhcmlhYmxlcyBpbmRlcGVuZGllbnRlcyB5IGxhIGRlcGVuZGllbnRlIGVzdMOhIG1hcmNhZG8gcG9yIGVsIHNpZ25vIGRlbCBjb2VmaWNpZW50ZS4KCkVuIGVzdGUgY2Fzbywgc2UgYW5hbGl6YSBlbCBzaWdubyBkZWwgY29lZmljaWVudGUgZGUgbGEgdmFyaWFibGUgUEJJIHkgYW5hbGZhYmV0aXNtby4KRWwgc2lnbm8gZGVsIGNvZWZpY2llbnRlIGRlIFBCSSBlcyBwb3NpdGl2byAoKyksIGxvIHF1ZSBpbmRpY2EgcXVlIGRlcGFydGFtZW50b3MgY29uIHVuIG1heW9yIFBCSSBwZXIgY8OhcGl0YSB0ZW5kcsOtYW4gdW4gbWF5b3IgcG9yY2VudGFqZSBkZSB2b3RvIGEgUFBLLCBlbiBwcm9tZWRpby4KRGUgRWwgc2lnbm8gZGVsIGNvZWZpY2llbnRlIGRlIGFuYWxmYWJldGlzbW8gZXMgbmVnYXRpdm8gKC0pLCBjb24gbG8gcXVlIHNlIGNvbmNsdXllIHF1ZSBkZXBhcnRhbWVudG9zIHF1ZSBtdWVzdHJhbiBtYXlvciBhbmFsZmFiZXRpc21vIHRpZW5lbiBtZW5vciB2b3RvIGEgUFBLLCBlbiBwcm9tZWRpby4KCiMjIEFqdXN0ZSBkZWwgbW9kZWxvCgpEZSBsYSBtaXNtYSBtYW5lcmEgcXVlIGVuIGVsIGFuw6FsaXNpcyBiaXZhcmlhZG8sIGVsIGFqdXN0ZSBkZWwgbW9kZWxvIHNlIGVudGllbmRlIGNvbW8gZWwgcG9yY2VudGFqZSBkZSBsYSB2YXJpYWNpw7NuIHRvdGFsIGRlIGxhIHZhcmlhYmxlIGRlcGVuZGllbnRlIGV4cGxpY2FkYSBwb3IgbGFzIHZhcmlhYmxlcyBpbmRlcGVuZGllbnRlcy4KRXN0ZSBkYXRvIHNlIG9idGllbmUgY29uIGVsICRSXjIkLgoKRW4gbnVlc3RybyBlamVtcGxvIHNlIHRpZW5lIHVuICRSXjIgYWp1c3RhZG8gPSAwLjQ3JC4KRXN0YSBkYXRvIGluZGljYXLDrWEgcXVlIGVsIG1vZGVsbyBxdWUgaW5jbHV5ZSBsYXMgdmFyaWFibGVzIGFjY2VzbyBhIGludGVybmV0IHkgUEJJIHBlciBjw6FwaXRhIGV4cGxpY2FuIGVsIDQ3JSBkZSBsYSB2YXJpYWNpw7NuIHRvdGFsIGRlbCB2b3RvIGEgUFBLLgoKRWwgJFJeMiQgYWp1c3RhZG8gc2UgdXNhIGN1YW5kbyBzZSBxdWllcmUgY29tcGFyYXIgZW50cmUgZGlmZXJlbnRlcyBtb2RlbG9zLCB5YSBzZWEgcG9ycXVlIHNlIHVzYW4gZGlmZXJlbnRlcyB2YXJpYWJsZXMgbyBkaWZlcmVudGUgbsO6bWVybyBkZSB2YXJpYWJsZXMuCkVzdG8gZXMgaW1wb3J0YW50ZSBjdWFuZG8gc2UgY29tcGFyYXIgbW9kZWxvcyBjb24gZGlmZXJlbnRlIG7Dum1lcm8gZGUgdmFyaWFibGVzIGluZGVwZW5kaWVudGVzLCBwb3JxdWUgZWwgJFJeMiQgdGllbmUgbGEgY2FyYWN0ZXLDrXN0aWNhIGRlIGF1bWVudGFyIGN1YW5kbyBzZSBpbmNsdXllbiBtw6FzIHZhcmlhYmxlcyBpbmRlcGVuZGllbnRlcy4KRWwgJFJeMiQgYWp1c3RhZG8gY29udHJvbGEgcG9yIGVzdGEgaW5mbGFjacOzbiBhcnRpZmljaWFsLgoKIyMgUHJlZGljY2nDs24KClBhcmEgbGEgcHJlZGljY2nDs24gc2UgdGllbmUgcXVlIGNvbnN0cnVpciBsYSBlY3VhY2nDs24gZGVsIG1vZGVsby4KRXN0YSBlY3VhY2nDs24gc2UgY29uc3RydXllIGNvbiBsb3MgdmFsb3JlcyBkZSBsb3MgY29lZmljaWVudGVzIGRlIHRvZGFzIGxhcyB2YXJpYWJsZXMsIGFzw60gYWxndW5hIGRlIGVsbGFzIG5vIGhheWEgc2FsaWRvIHNpZ25pZmljYXRpdmEuCkEgZXN0byBzZSBhZ3JlZ2EgZWwgdmFsb3IgZGUgbGEgY29uc3RhbnRlLgoKRW4gbnVlc3RybyBlamVtcGxvIHNlIHRpZW5lIGxhIHNpZ3VpZW50ZSBlY3VhY2nDs24sIHNpZW5kbyBZIGVsIHZvdG8gYSBQUEssIFgxIGVsIGFjY2VzbyBhIGludGVybmV0IHkgWDIgZW4gUEJpIHBlciBjw6FwaXRhOgoKJCRcaGF0e1l9ID0gMTkuMiAtIDAuMDYqWF8xIC0gMC44NSpYXzIgKyAwLjAwMDMqWF8zJCQKClBhcmEgaGFsbGFyIGVsIHZvdG8gZXN0aW1hZG8gYSBQUEssIHNlIHRpZW5lIHF1ZSBhZ3JlZ2FyIHZhbG9yZXMgZGUgbGFzIHRyZXMgdmFyaWFibGVzIGluZGVwZW5kaWVudGVzLgpQYXJhIHBvZGVyIGFwcm94aW1hciB2YWxvcmVzIGVzdMOhbmRhciBkZSBlc3RhcyB2YXJpYWJsZXMsIGVzdGFzIHNlIHB1ZWRlbiBkZXNjcmliaXIuCgpgYGB7ciBkZXNjcmliaXJ9CmRhdGExNiAlPiUKICBzdW1tYXJpc2UobWF4KFVzb19pbnRlcm5ldCwgbmEucm09VCksIG1pbihBbmFsZmFiZXRpc21vXzIwMTQsIG5hLnJtPVQpLCAKICAgICAgICAgICAgbWF4KHBiaXBjXzIwMTQsIG5hLnJtPVQpKQpgYGAKClBvciBsbyB0YW50bywgc2kgcXVlcmVtb3MgY2FsY3VsYXIgdW4gdm90byBwcm9tZWRpbyBnZW5lcmFsIGVzdGltYWRvIGEgUFBLLCBzZSBwb2Ryw61hIHJlZW1wbGF6YXIgbGFzIHZhcmlhYmxlcyBpbmRlcGVuZGllbnRlcywgZW4gc3UgcHJvbWVkaW86IFgxPTMyLjgsIFgyPTcuOCB5IFgzPTE0OTQ2LgoKJCRcaGF0e1l9ID0gMTkuMiAtIDAuMDYqMzIuOCAtIDAuODUqNy44ICsgMC4wMDAzKjE0OTQ2ID0gMTUuMSAlICQkCgpFbiBjb25jbHVzacOzbiwgcGFyYSB2YWxvcmVzIHByb21lZGlvIGRlIGxhcyB2YXJpYWJsZXMgaW5kZXBlbmRpZW50ZXMsIGVsIHZvdG8gZXN0aW1hZG8gYSBQUEssIHNlZ8O6biBlbCBtb2RlbG8sIHNlcsOtYSBkZSAxNS4xJS4KRXN0ZSBtaXNtbyBlamVyY2ljaW8gc2UgcHVlZGUgaGFjZXIgcGFyYSBsb3MgdmFsb3JlcyBtw61uaW1vcywgbcOheGltb3MsIHBhcmEgYWxndW5vcyBwZXJjZW50aWxlcyBwYXJ0aWN1bGFyZXMsIGV0Yy4KClNpIHNlIHF1aWVyZSBwcmVkZWNpciBlbCB2b3RvIGEgUFBLIHBhcmEgZGlmZXJlbnRlcyB2YWxvcmVzIGRlIHVuYSB2YXJpYWJsZSBpbmRlcGVuZGllbnRlLCBzZSBwdWVkZSByZWVtcGxhemFyIGRlamFuZG8gbGFzIG90cmFzIHZhcmlhYmxlcyBlbiBlbCBwcm9tZWRpby4KUG9yIGVqZW1wbG8sIHNlIHF1aWVyZSBjYWxjdWxhciBlbCB2b3RvIGVzdGltYWRvIGEgUFBLIHBhcmEgZGlmZXJlbnRlcyB2YWxvcmVzIGRlIGFuYWxmYWJldGlzbW8uCkxvIHByaW1lcm8gZXMgY2FsY3VsYXIgbG9zIHZhbG9yZXMgZGUgYW5hbGZhYmV0aXNtbyBhIHJlZW1wbGF6YXIuCkVuIGVzdGUgY2FzbyB1c2FyZW1vcyBlbCBtw61uaW1vLCBtZWRpYS4KbWVkaWFuYSB5IG3DoXhpbW8uCgpgYGB7cn0KZGF0YTE2ICU+JQogIHN1bW1hcmlzZShtaW4oQW5hbGZhYmV0aXNtb18yMDE0LCBuYS5ybT1UKSwgbWVhbihBbmFsZmFiZXRpc21vXzIwMTQsIG5hLnJtPVQpLCAKICAgICAgICAgICAgbWVkaWFuKEFuYWxmYWJldGlzbW9fMjAxNCwgbmEucm09VCksIG1heChBbmFsZmFiZXRpc21vXzIwMTQsIG5hLnJtPVQpKQpgYGAKCkx1ZWdvLCBwb2RlbW9zIHJlZW1wbGF6YXIgZXN0b3MgZGlmZXJlbnRlcyB2YWxvcmVzIGRlIGFuYWxmYWJldGlzbW8sIGRlamFuZG8gbGFzIG90cmFzIGRvcyB2YXJpYWJsZXMgY29uc3RhbnRlcyBlbiBlbCBwcm9tZWRpby4KCmBgYHtyfQoxOS4yIC0gMC4wNiozMi43NiAtIDAuODUqMiArIDAuMDAwMyoxNDk0NgoxOS4yIC0gMC4wNiozMi43NiAtIDAuODUqNiArIDAuMDAwMyoxNDk0NgoxOS4yIC0gMC4wNiozMi43NiAtIDAuODUqNy43NiArIDAuMDAwMyoxNDk0NgoxOS4yIC0gMC4wNiozMi43NiAtIDAuODUqMTcgKyAwLjAwMDMqMTQ5NDYKYGBgCgojIyBDb21wYXJhbmRvIGVudHJlIHZhcmlhYmxlcwoKRW4gb2Nhc2lvbmVzIHNlIHF1aWVyZSBhbmFsaXphciBxdcOpIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgdGllbmUgdW4gbWF5b3IgZWZlY3RvIHNvYnJlIGxhIHZhcmlhYmxlIGRlcGVuZGllbnRlLgpFc3RlIGFuw6FsaXNpcyBubyBzZSBwdWVkZSBoYWNlciBzaW1wbGVtZW50ZSBjb21wYXJhbmRvIGxvcyBjb2VmaWNpZW50ZXMgZGVsIG1vZGVsbyBhbnRlcmlvciwgZGViaWRvIGEgcXVlIGVzdG9zIGNvZWZpY2llbnRlcyBlc3TDoW4gZW4gZGlmZXJlbnRlcyB1bmlkYWRlczogYWNjZXNvIGEgaW50ZXJuZXQgZW4gcG9yY2VudGFqZSB5IFBCSSBwZXIgY8OhcGl0YSBlbiBzb2xlcy4KClBhcmEgcG9kZXIgY29tcGFyYXIgZWwgZWZlY3RvIGRlIGNhZGEgdmFyaWFibGUgc29icmUgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUsIHNlIHRpZW5lIHF1ZSBjYWxjdWxhciBsb3MgY29lZmljaWVudGVzIGVzdGFuZGFyaXphZG9zLgpFc3RvcyBjb2VmaWNpZW50ZXMgc29uIGluZGVwZW5kaWVudGVzIGRlIGxhcyB1bmlkYWRlcyBkZSBtZWRpZGEuCgpQYXJhIHBvZGVyIGNhbGN1bGFzIGxvcyBjb2VmaWNpZW50ZXMgZXN0YW5kYXJpemFkb3MsIHNlIHB1ZWRlIHVzYXIgbGEgbGlicmVyw61hIGBqdG9vbHNgLCBxdWUgY3VlbnRhIGNvbiBlbCBjb21hbmRvIGBzdW1tYCwgZG9uZGUgc2UgcHVlZGUgZXNwZWNpZmljYXIgYHNjYWxlPVRSVUVgIHBhcmEgcXVlIHNlIHByZXNlbnRlbiBsb3MgY29lZmljaWVudGVzIGVzdGFuZGFyaXphZG9zLgoKYGBge3IgZXN0YW5kYXJ9CmxpYnJhcnkoanRvb2xzKQpzdW1tKG1vZGVsbzQsIHNjYWxlPVQpCmBgYAoKRGUgYWN1ZXJkbyBhIGVzdG9zIHJlc3VsdGFkb3MsIGxhIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgcXVlIHRpZW5lIHVuIGVmZWN0byBtYXlvciBzb2JyZSBsYSB2YXJpYWJsZSBkZXBlbmRpZW50ZSBlcyBhbmFsZmFiZXRpc21vLgpFc3RlIGFuw6FsaXNpcyBlcyBtdWNobyBtw6FzIMO6dGlsIGN1YW5kbyB0ZW5lbW9zIHVuYSBtYXlvciBjYW50aWRhZCBkZSB2YXJpYWJsZXMgaW5kZXBlbmRpZW50ZXMgeSBkZSB2YXJpYWJsZXMgc2lnbmlmaWNhdGl2YXMgZW4gZGlmZXJlbnRlcyB1bmlkYWRlcyBkZSBtZWRpY2nDs24uCgpQYXJhIGdyYWZpY2FyIGxvcyBjb2VmaWNpZW50ZXMKCmBgYHtyfQpwbG90X3N1bW1zKG1vZGVsbzQpCmBgYAoKIyBMZXllbmRvIHJlc3VsdGFkb3MgYWNhZMOpbWljb3MKCkVsIGFuw6FsaXNpcyBkZSByZWdyZXNpw7NuIGxpbmVhbCBtdWx0aXZhcmlhZG8gZXMgdW5hIGRlIGxhcyBoZXJyYW1pZW50YXMgYWNhZMOpbWljYXMgbcOhcyB1c2FkYXMuCkVzIG11eSBjb23Dum4gZW5jb250cmFyIHRhYmxhcywgY29tbyBsYSBxdWUgc2UgbXVlc3RyYSBhYmFqbywgY29uIHJlc3VsdGFkb3MgZGUgZXN0ZSB0aXBvLgoKVW4gcHVudG8gaW1wb3J0YW50ZSwgYWRlbcOhcyBkZSBwcm9kdWNpciByZXN1bHRhZG9zLCBlcyBzYWJlciBpbnRlcnByZXRhcmxvcy4KTGEgdGFibGEgcHJvdmllbmUgZGUgbGEgdGVzaXMgZGUgcHJlZ3JhZG8gZGUgU2ViYXN0acOhbiBMYXpvLCBsdWVnbyByZXBvcnRhZGEgZW4gc3UgYXJ0w61jdWxvICJDb21wb3J0YW1pZW50byBlbGVjdG9yYWwgZW4gZWwgUGVyw7o6IFVuIGFuw6FsaXNpcyBkZWwgcm9sIGRlIGxhcyB2YXJpYWJsZXMgc29jaW9kZW1vZ3LDoWZpY2FzIGVuIGxhcyBlbGVjY2lvbmVzIHByZXNpZGVuY2lhbGVzIGVuIHByaW1lcmEgdnVlbHRhIGRlIDIwMDYgeSAyMDExIiwgZGlzcG9uaWJsZSBbYXF1w61dKGh0dHBzOi8vcmV2aXN0YXMucHVjcC5lZHUucGUvaW5kZXgucGhwL2NpZW5jaWFwb2xpdGljYS9hcnRpY2xlL3ZpZXcvMTQ1MjApLgoKRWwgYXJ0w61jdWxvIGhhY2UgdW5hIHJldmlzacOzbiBkZSBsYSBsaXRlcmF0dXJhIGRlIGxvcyBlc3R1ZGlvcyBlbiBQZXLDuiBzb2JyZSBlbCBjb21wb3J0YW1pZW50byBlbGVjdG9yYWwgZSBpZGVudGlmaWNhIGxhcyBwcmluY2lwYWxlcyB2YXJpYWJsZXMgcXVlIHNlIGRpc2N1dGVuIGPDs21vIGV4cGxpY2F0aXZhcyBkZWwgdm90byBwb3IgY2llcnRvcyBjYW5kaWRhdG9zLgoKIVtdKG1hcmNvLnBuZyl7d2lkdGg9IjU0NCJ9CgpMdWVnbyBpZGVudGlmaWNhIGxhcyB2YXJpYWJsZXMgZGlzcG9uaWJsZXMgeSBxdWUgZXN0w6FuIHJlbGFjaW9uYWRhcyBjb24gZWwgbWFyY28gdGXDs3JpY28uCkxhIHVuaWRhZCBkZSBhbsOhbGlzaXMgc29uIGxvcyBkaXN0cml0b3MgZGVsIFBlcsO6LgpVbmEgdW5hIHZhcmlhYmxlIGRlcGVuZGllbnRlIHBvciBjYWRhIGNhbmRpZGF0byB5IHVuIHNldCBkZSB2YXJpYWJsZXMgaW5kZXBlbmRpZW50ZXMsIHF1ZSByZWZpZXJlbiBkZSBhbGd1bmEgbWFuZXJhIGNvbiBsYSByZXZpc2nDs24gZGUgbGEgbGl0ZXJhdHVyYS4KRW4gbG9zIGVzdHVkaW9zIGN1YW50aXRhdGl2b3Mgc2UgdGllbmUgbGEgcmVzdHJpY2Npw7NuIGRlIGxhIGRpc3BvbmliaWxpZGFkIGRlIGxhIGluZm9ybWFjacOzbi4KTm8gdG9kb3MgbG9zIGZhY3RvcmVzIHF1ZSBzZSBoaXBvdGV0aXphIHF1ZSB0aWVuZW4gcmVsYWNpw7NuIGNvbiB1bmEgdmFyaWFibGUgaGFuIHNpZG8gbWVkaWRvcy4KCiFbXSh2YXJpYWJsZXMucG5nKXt3aWR0aD0iNTI0In0KCkxhem8gb2J0aWVuZSBsb3Mgc2lndWllbnRlcyByZXN1bHRhZG9zLgpTZSBtdWVzdHJhbiBsb3MgY29lZmljaWVudGVzLCBsb3Mgc2lnbm9zIGRlIGxvcyBjb2VmaWNpZW50ZXMgeSBhc3RlcmlzY29zIHF1ZSBpbmRpY2FuIGVsIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgZGUgbG9zIHJlc3VsdGFkb3MuCgohW10oTGF6by5wbmcpe3dpZHRoPSI0ODQifQoKTGF6byBhZGVtw6FzIGluY2x1eWUgdW5hIG5vdGEgYWwgcGllIGNvbiBsb3MgZGV0YWxsZXMgZGUgbGFzIHNpZ25pZmljYW5jaWFzIHkgY29uIGxhIGZ1ZXJ6YSBleHBwbGljYXRpdmEgZGUgY2FkYSBtb2RlbG8gbWVkaWFudGUgZWwgUjIuClNlIGFzdW1lIHF1ZSB0b2RvcyBsb3MgbW9kZWxvcyBzb24gdsOhbGlkb3MuCgohW10ocGllcGFnaW5hLnBuZyl7d2lkdGg9IjQ3MyJ9CgrCv1F1w6kgY29uY2x1c2lvbmVzIHNlIHB1ZWRlIHRlbmVyIGRlIGVzdG9zIHJlc3VsdGFkb3MgYWNlcmNhIGRlbCBwZXJmaWwgZGUgbG9zIGNhbmRpZGF0b3M/Cg==