Aprender a convertir una decisión empresarial en un problema
que pueda investigarse mediante datos.
En investigación de mercados, el análisis estadístico no comienza
cuando abrimos R.
Antes de analizar datos debemos establecer:
- qué decisión debe tomarse;
- cuál es el problema real;
- qué información necesitamos;
- qué preguntas podemos responder;
- qué variables representan esas preguntas;
- qué diseño de investigación es apropiado;
- y solamente entonces, qué datos debemos analizar.
Podemos disponer de millones de observaciones y, aun así, no tener
claramente identificado qué pregunta debe responder.
Por ejemplo:
- una aseguradora observa una reducción de renovaciones;
- una compañía quiere introducir un nuevo seguro;
- aumenta la frecuencia de reclamaciones;
- determinados clientes abandonan una póliza;
- existe poca demanda por un producto de microseguro;
- una aseguradora considera modificar una prima;
- una entidad previsional quiere aumentar la participación
voluntaria;
- una compañía quiere identificar nuevos segmentos de mercado.
En todos estos casos existe inicialmente una decisión
empresarial.
La investigación permite transformar esa decisión en una
pregunta susceptible de ser respondida mediante
evidencia.
Ruta de
aprendizaje
Durante esta clase seguiremos la siguiente secuencia:
Decisión empresarial - Problema de
investigación - Objetivos - Preguntas
de investigación - Hipótesis -
Variables - Información requerida -
Diseño de investigación - Datos -
Exploración inicial - Evidencia para la
decisión -
¿Qué es la
investigación de mercados?
La investigación de mercados puede entenderse como un proceso
sistemático para generar información que contribuya a la toma de
decisiones relacionadas con un mercado.
Lo importante de esta definición no es solamente la palabra
mercado.
La investigación no consiste simplemente en recopilar datos.
Tampoco consiste solamente en aplicar encuestas.
Mucho menos consiste únicamente en aplicar técnicas estadísticas.
Idea fundamental
Tener datos no significa tener información.
Tener información no significa tener conocimiento.
Y tener conocimiento no implica automáticamente una buena
decisión.
El trabajo del investigador consiste en construir una conexión lógica
entre:
problema → evidencia → interpretación →
decisión.
Investigación y toma
de decisiones
Considere el siguiente ejemplo.
Una aseguradora observa que la tasa de renovación de un seguro de
automóvil cayó de 82% a 74%.
La administración podría inmediatamente concluir:
“El problema es que la prima es demasiado alta.”
Pero esa afirmación todavía no ha sido demostrada.
Otras explicaciones podrían ser:
- mala atención;
- aumento de competencia;
- modificaciones en las coberturas;
- mala experiencia durante un siniestro;
- cambios en el ingreso de los clientes;
- nuevos productos sustitutos;
- promociones de competidores;
- modificaciones en canales digitales;
- características particulares de determinados segmentos.
La investigación de mercados busca reducir esta incertidumbre.
Aplicación en ciencias
actuariales
Tradicionalmente, el análisis actuarial se concentra en fenómenos
como:
- mortalidad;
- morbilidad;
- frecuencia de siniestros;
- severidad;
- reservas;
- solvencia;
- primas;
- supervivencia;
- abandono;
- riesgo financiero.
La investigación de mercados complementa esta perspectiva
incorporando preguntas como:
- ¿qué productos desea el consumidor?;
- ¿qué atributos valora?;
- ¿qué precio está dispuesto a aceptar?;
- ¿por qué abandona una póliza?;
- ¿qué canal prefiere?;
- ¿qué segmentos tienen mayor intención de compra?;
- ¿qué percepción tiene sobre una aseguradora?;
- ¿comprende adecuadamente las coberturas?;
- ¿qué factores influyen sobre su renovación?;
- ¿qué combinación de beneficios resulta más atractiva?
Perspectiva
actuarial
Un modelo actuarial puede responder:
¿Cuál debería ser la prima técnica asociada con determinado nivel de
riesgo?
La investigación de mercados puede responder:
¿Cómo reaccionará el consumidor frente a esa prima?
Son preguntas distintas.
Para tomar una decisión empresarial completa pueden ser necesarias
ambas respuestas.
Dos grandes propósitos
de la investigación
Podemos distinguir conceptualmente dos grandes propósitos.
Investigación para
identificar problemas
Busca detectar fenómenos que quizá todavía no son evidentes.
Ejemplos:
- reducción gradual de participación de mercado;
- cambio en preferencias;
- deterioro de imagen;
- aparición de nuevos segmentos;
- modificación del comportamiento de compra;
- cambios en percepción del precio;
- oportunidades para nuevos productos.
Investigación para
resolver problemas
Se realiza cuando el problema ya ha sido identificado.
Ejemplos:
- determinar qué prima comercial resulta aceptable;
- elegir entre dos productos;
- seleccionar un canal de distribución;
- evaluar una campaña;
- rediseñar una cobertura;
- identificar segmentos prioritarios.
El proceso de
investigación de mercados
Una investigación puede organizarse conceptualmente en seis grandes
etapas:
- definición del problema;
- desarrollo del enfoque;
- formulación del diseño;
- trabajo de campo o recopilación;
- preparación y análisis de datos;
- elaboración y presentación del informe.
Paso 1. Definir el
problema
Esta probablemente sea la etapa conceptualmente más importante.
Si definimos mal el problema, podemos realizar:
- una excelente encuesta;
- un excelente muestreo;
- una excelente regresión;
- un excelente análisis multivariado;
y aun así responder una pregunta equivocada.
Principio
metodológico
Una técnica estadística sofisticada no corrige una pregunta mal
formulada.
Paso 2. Desarrollar
el enfoque
Una vez definido el problema debemos determinar:
- qué sabemos;
- qué teoría puede orientarnos;
- qué variables podrían intervenir;
- qué relaciones esperamos;
- qué preguntas queremos responder;
- qué hipótesis pueden plantearse;
- qué información necesitamos.
Paso 5. Preparar y
analizar
Los datos deben:
- revisarse;
- codificarse;
- depurarse;
- transformarse;
- resumirse;
- analizarse.
R será nuestra herramienta principal durante el curso.
Paso 6. Comunicar
resultados
El producto final no es una salida de R.
El producto final es una respuesta fundamentada.
Por ejemplo:
“Los clientes expuestos a incrementos de prima superiores al 10%
presentan menor intención de renovación, especialmente cuando su
valoración del servicio también es baja.”
Esta afirmación es mucho más útil que mostrar únicamente una tabla de
coeficientes.
Problema empresarial
versus problema de investigación
Esta distinción es fundamental.
Problema
empresarial
Se concentra en:
¿Qué debemos hacer?
Ejemplos:
- ¿debemos reducir la prima?;
- ¿debemos lanzar el producto?;
- ¿debemos cambiar el canal?;
- ¿debemos modificar la cobertura?;
- ¿debemos dirigirnos a otro segmento?
Problema de
investigación
Se concentra en:
¿Qué información necesitamos para decidir?
Ejemplo:
Problema
empresarial
¿Debemos modificar la prima de renovación del seguro de
automóvil?
Problema de
investigación
Determinar la relación entre la variación de la prima y la intención
de renovación de los asegurados, considerando características del
cliente, experiencia de siniestros y percepción del servicio.
Observe el cambio.
La investigación no decide automáticamente si se reduce la prima.
Primero genera información sobre el fenómeno.
El contexto del
problema
Una decisión empresarial no ocurre de forma aislada.
Antes de formular la investigación debemos comprender el
contexto.
Entre los elementos que pueden analizarse se encuentran:
- información histórica;
- pronósticos;
- objetivos empresariales;
- comportamiento del consumidor;
- restricciones;
- recursos disponibles;
- ambiente económico;
- ambiente legal;
- tecnología;
- competencia.
Ejemplo de contexto
actuarial
Supongamos que una aseguradora observa mayor cancelación.
Antes de culpar al precio debemos revisar:
Entorno
económico
- inflación;
- ingreso disponible;
- desempleo;
- tasas de interés.
Entorno
competitivo
- nuevas aseguradoras;
- promociones;
- nuevos canales digitales;
- agregadores de seguros.
Entorno
regulatorio
- modificaciones normativas;
- coberturas obligatorias;
- protección al consumidor.
Entorno
interno
- incremento de primas;
- modificaciones en deducibles;
- cambios en servicio;
- procesos de reclamación.
Comportamiento del
cliente
- sensibilidad al precio;
- experiencia de siniestro;
- valoración de marca;
- preferencias digitales.
De objetivos a
preguntas de investigación
Una vez definido el problema, debemos estructurar el estudio.
Objetivo
general
Describe qué pretende lograr la investigación.
Ejemplo:
Analizar los factores relacionados con la intención de renovación de
los clientes de seguros de automóvil.
Objetivos
específicos
Podrían ser:
- describir el perfil de los clientes;
- determinar la distribución de la intención de renovación;
- analizar la relación entre aumento de prima e intención de
renovación;
- comparar la intención de renovación según experiencia de
siniestro;
- analizar la relación entre satisfacción e intención de
renovación;
- identificar variables potencialmente útiles para explicar la
renovación.
Preguntas débiles y
preguntas mejoradas
Ejemplo 1
Pregunta débil:
¿Por qué los seguros son caros?
Problemas:
- demasiado amplia;
- utiliza un juicio de valor;
- no define seguro;
- no define población;
- no define qué significa caro.
Pregunta mejorada:
¿Cómo se relaciona la percepción del precio de un seguro de automóvil
con la intención de renovación entre clientes actuales?
Ejemplo 2
Pregunta débil:
¿A las personas les gustan los seguros de vida?
Pregunta mejorada:
¿Qué atributos de un seguro de vida son valorados por adultos de 25 a
45 años que actualmente no poseen cobertura individual?
Marco conceptual
Las preguntas de investigación no deberían aparecer de manera
arbitraria.
Necesitamos establecer una explicación conceptual.
Por ejemplo:
Incremento de prima ──────────┐
│
Satisfacción ──────────────────┤
│
Experiencia de siniestro ──────┤──> Intención de renovación
│
Ingreso ───────────────────────┤
│
Antigüedad ────────────────────┘
Este esquema representa una hipótesis conceptual.
Todavía no es un modelo estadístico.
Nos ayuda a organizar el problema.
Modelo verbal, gráfico
y matemático
Una misma idea puede expresarse de diferentes maneras.
Modelo verbal
La intención de renovación de una póliza puede estar relacionada con
la variación de la prima, la satisfacción del cliente, su experiencia de
siniestros y características individuales.
Modelo gráfico
Precio ────────────────┐
│
Servicio ──────────────┤
├──> Renovación
Siniestros ────────────┤
│
Características ───────┘
Modelo matemático
conceptual
Podemos representarlo como:
\[
Y = f(X_1,X_2,X_3,\ldots,X_k)
\]
donde:
\[
Y = \text{intención de renovación}
\]
y, por ejemplo,
\[
X_1 = \text{incremento de prima}
\]
\[
X_2 = \text{satisfacción}
\]
\[
X_3 = \text{experiencia de siniestros}
\]
\[
X_4 = \text{ingreso}
\]
\[
Y_i =
\beta_0 +
\beta_1 X_{1i} +
\beta_2 X_{2i} +
\beta_3 X_{3i} +
\varepsilon_i
\]
Por ahora lo importante no es estimarlo.
Lo importante es comprender que el modelo estadístico debe originarse
en una pregunta y no al revés.
Hipótesis de
investigación
Una hipótesis establece una relación esperada entre variables.
Por ejemplo:
\[
H_1:
\text{a mayor incremento de prima, menor intención de renovación}
\]
Otra hipótesis:
\[
H_2:
\text{a mayor satisfacción, mayor intención de renovación}
\]
También:
\[
H_3:
\text{la intención de renovación difiere según la experiencia de
siniestros}
\]
Importante
En esta etapa estamos formulando hipótesis
conceptuales.
Más adelante aprenderemos a convertirlas en hipótesis
estadísticas.
No son exactamente lo mismo.
Variables
Una variable es una característica que puede presentar variación.
Ejemplos actuariales:
- edad;
- prima;
- suma asegurada;
- frecuencia de siniestros;
- severidad;
- ingreso;
- satisfacción;
- intención de renovación;
- canal;
- región.
Tipos iniciales de
variables
Desde una perspectiva práctica podemos comenzar distinguiendo:
Variables
numéricas
Ejemplos:
- edad;
- ingreso;
- prima;
- número de siniestros.
Variables
categóricas
Ejemplos:
- región;
- canal;
- producto;
- sexo;
- renovación.
Variables
ordinales
Ejemplo:
Intención de renovación:
- definitivamente no;
- probablemente no;
- indeciso;
- probablemente sí;
- definitivamente sí.
Del concepto a los
datos
Observe esta secuencia:
| Decisión |
¿Debemos cambiar la estrategia de renovación? |
| Problema de investigación |
Factores relacionados con la renovación |
| Pregunta |
¿El aumento de prima está relacionado con la intención de
renovar? |
| Hipótesis |
A mayor aumento, menor intención |
| Concepto |
Sensibilidad al precio |
| Variable |
Incremento porcentual de prima |
| Dato |
12.5% |
| Análisis |
Comparación/correlación/modelo |
| Evidencia |
Relación observada |
| Decisión |
Utilizar evidencia junto con criterios técnicos |
Diseños de
investigación
Una vez sabemos qué necesitamos investigar debemos decidir
cómo obtener la evidencia.
Los tres diseños principales que utilizaremos son:
- exploratorio;
- descriptivo;
- causal.
Investigación
exploratoria
Se utiliza cuando:
- el problema todavía no está claramente definido;
- necesitamos comprender el fenómeno;
- existen pocas hipótesis;
- queremos identificar posibles variables;
- buscamos generar ideas.
Métodos comunes:
- entrevistas con expertos;
- análisis de datos secundarios;
- grupos focales;
- entrevistas en profundidad;
- análisis exploratorio de datos.
Ejemplo
actuarial
Una aseguradora quiere saber por qué los jóvenes no adquieren seguros
de vida.
Todavía no sabe si el problema es:
- precio;
- falta de conocimiento;
- baja percepción de riesgo;
- productos inadecuados;
- canales;
- desconfianza.
Una primera investigación exploratoria puede ayudar a identificar
explicaciones.
Investigación
descriptiva
Se utiliza para cuantificar características del mercado.
Responde preguntas como:
- ¿quién?;
- ¿qué?;
- ¿cuánto?;
- ¿cuándo?;
- ¿dónde?;
- ¿con qué frecuencia?
Ejemplos:
- porcentaje de clientes que desea renovar;
- edad promedio;
- nivel promedio de satisfacción;
- participación de canales;
- distribución del mercado por región;
- proporción que conoce determinado producto.
Investigación
causal
Busca determinar si cambios en una variable producen cambios en
otra.
Ejemplo:
Una aseguradora quiere conocer si modificar la forma de presentar una
cotización aumenta la aceptación.
Podríamos comparar:
- grupo A: cotización tradicional;
- grupo B: nueva presentación.
Si la asignación y el diseño son adecuados, podemos aproximarnos a
una inferencia causal.
Exploratorio,
descriptivo o causal
Veamos algunos escenarios.
Situación A
No sabemos por qué los clientes están cancelando.
Diseño principal:
Exploratorio.
Situación B
Queremos conocer qué porcentaje de clientes considera cara la
prima.
Diseño principal:
Descriptivo.
Situación C
Queremos conocer si ofrecer un descuento aumenta la renovación.
Diseño principal:
Causal.
Diseños transversales
y longitudinales
Otra decisión importante es el momento en que observamos a los
individuos.
Estudio
transversal
Observamos una población en un punto o periodo específico.
Ejemplo:
Encuesta de satisfacción realizada durante octubre de 2026.
Podemos pensar en una fotografía.
Estudio
longitudinal
Observamos las mismas unidades repetidamente.
Ejemplo:
Seguimos durante 24 meses a los mismos asegurados y registramos:
- prima;
- siniestros;
- satisfacción;
- renovación.
Podemos pensar en una película.
Ejemplo actuarial
Supongamos que queremos estudiar abandono.
Diseño
transversal
Cliente Octubre 2026
A Renueva
B No renueva
C Renueva
Diseño
longitudinal
Cliente 2024 2025 2026
A Sí Sí Sí
B Sí Sí No
C Sí No -
El segundo diseño permite estudiar trayectorias.
Fuentes de error
Toda investigación contiene error.
El objetivo no es imaginar que podemos eliminarlo por completo.
El objetivo es:
- identificarlo;
- minimizarlo;
- cuantificarlo cuando sea posible;
- reconocer sus implicaciones.
Error de
muestreo
Surge porque estudiamos una muestra y no necesariamente toda la
población.
Supongamos una población con edad promedio conocida.
set.seed(2026)
poblacion_edad <- round(
rnorm(
n = 100000,
mean = 42,
sd = 13
)
)
mean(poblacion_edad)
## [1] 42.0142
Tomemos diferentes muestras de 100 personas.
set.seed(2026)
medias_muestrales <- replicate(
500,
mean(
sample(
poblacion_edad,
size = 100
)
)
)
summary(medias_muestrales)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 37.63 41.15 42.05 42.04 42.89 47.53
Visualicemos.
data.frame(
media = medias_muestrales
) %>%
ggplot(
aes(x = media)
) +
geom_histogram(
bins = 30,
color = "white"
) +
geom_vline(
xintercept = mean(poblacion_edad),
linetype = "dashed",
linewidth = 1
) +
labs(
title = "Variabilidad entre muestras",
subtitle = "500 muestras aleatorias de tamaño 100",
x = "Edad promedio de la muestra",
y = "Frecuencia"
) +
theme_minimal()

Observe que diferentes muestras generan diferentes estimaciones.
Eso es parte de la variabilidad muestral.
Más adelante estudiaremos formalmente:
- error estándar;
- intervalos de confianza;
- tamaño de muestra.
Error no atribuible al
muestreo
También pueden aparecer errores por:
- mala definición de población;
- preguntas ambiguas;
- falta de respuesta;
- errores de registro;
- errores de codificación;
- fraude;
- datos faltantes;
- errores de análisis;
- instrumentos deficientes.
Punto
fundamental
Aumentar el tamaño de la muestra puede reducir el error muestral.
Pero una muestra gigantesca no corrige un cuestionario mal
diseñado.
Investigación de
mercados, SIM y apoyo a decisiones
Las organizaciones producen información continuamente.
Por ejemplo, una aseguradora puede disponer de:
- pólizas;
- primas;
- cancelaciones;
- reclamaciones;
- canales;
- agentes;
- clientes;
- campañas;
- cotizaciones.
Bases internas
+
Datos externos
+
Investigaciones específicas
↓
Preparación
↓
Análisis
↓
Visualización
↓
Información
↓
Decisión
Construcción del caso
de trabajo del curso
Crearemos una base simulada de clientes de seguros.
set.seed(2026)
n <- 1200
mercado_seguros <- data.frame(
id = 1:n,
edad = round(
pmin(
pmax(
rnorm(n, 42, 12),
18
),
75
)
),
ingreso_mensual = round(
rlnorm(
n,
log(9000),
0.55
),
0
),
region = sample(
c(
"Metropolitana",
"Norte",
"Occidente",
"Oriente",
"Sur"
),
n,
replace = TRUE,
prob = c(
0.42,
0.12,
0.18,
0.15,
0.13
)
),
canal = sample(
c(
"Agente",
"Digital",
"Sucursal",
"Bancaseguros"
),
n,
replace = TRUE,
prob = c(
0.35,
0.30,
0.20,
0.15
)
),
antiguedad = pmax(
1,
round(
rgamma(
n,
shape = 2.5,
scale = 2
)
)
),
siniestros_2a = rpois(
n,
lambda = 0.35
),
satisfaccion = sample(
1:10,
n,
replace = TRUE,
prob = c(
0.02,
0.03,
0.04,
0.06,
0.10,
0.13,
0.18,
0.19,
0.15,
0.10
)
),
incremento_prima = round(
pmax(
rnorm(
n,
mean = 8,
sd = 6
),
-5
),
1
)
)
Ahora construiremos una intención de renovación simulada.
La construiremos de manera que dependa parcialmente de:
- satisfacción;
- incremento de prima;
- antigüedad;
- experiencia de siniestro.
indice_renovacion <-
0.45 * mercado_seguros$satisfaccion -
0.10 * mercado_seguros$incremento_prima +
0.05 * mercado_seguros$antiguedad -
0.20 * mercado_seguros$siniestros_2a +
rnorm(n, 0, 1.5)
mercado_seguros$intencion_renovar <- cut(
indice_renovacion,
breaks = quantile(
indice_renovacion,
probs = seq(0, 1, 0.2)
),
include.lowest = TRUE,
labels = 1:5
)
mercado_seguros$intencion_renovar <- as.integer(
as.character(
mercado_seguros$intencion_renovar
)
)
Crearemos también una variable binaria de renovación observada.
prob_renovar <- plogis(
-0.5 +
0.35 * mercado_seguros$satisfaccion -
0.09 * mercado_seguros$incremento_prima +
0.04 * mercado_seguros$antiguedad -
0.15 * mercado_seguros$siniestros_2a
)
mercado_seguros$renueva <- rbinom(
n,
size = 1,
prob = prob_renovar
)
mercado_seguros$renueva <- ifelse(
mercado_seguros$renueva == 1,
"Sí",
"No"
)
Guardemos la base para utilizarla posteriormente.
write.csv(
mercado_seguros,
"mercado_seguros_clase1.csv",
row.names = FALSE
)
Inspección
inicial
Supongamos que recibimos la base y todavía no conocemos su
contenido.
La primera instrucción sería:
Luego:
## 'data.frame': 1200 obs. of 11 variables:
## $ id : int 1 2 3 4 5 6 7 8 9 10 ...
## $ edad : num 48 29 44 41 34 18 33 30 43 36 ...
## $ ingreso_mensual : num 10569 13489 8979 7042 15722 ...
## $ region : chr "Oriente" "Metropolitana" "Metropolitana" "Metropolitana" ...
## $ canal : chr "Agente" "Agente" "Digital" "Digital" ...
## $ antiguedad : num 10 4 5 1 5 2 4 3 2 3 ...
## $ siniestros_2a : int 0 0 1 0 0 0 1 0 0 0 ...
## $ satisfaccion : int 8 9 9 7 8 8 9 9 3 8 ...
## $ incremento_prima : num 21.2 6.7 1.9 9 13.3 8.3 7.6 9.5 8.6 0.1 ...
## $ intencion_renovar: int 1 4 5 1 2 4 4 5 2 1 ...
## $ renueva : chr "No" "Sí" "Sí" "No" ...
Dimensiones:
## [1] 1200 11
Nombres:
## [1] "id" "edad" "ingreso_mensual"
## [4] "region" "canal" "antiguedad"
## [7] "siniestros_2a" "satisfaccion" "incremento_prima"
## [10] "intencion_renovar" "renueva"
Resumen:
## id edad ingreso_mensual region
## Min. : 1.0 Min. :18.00 Min. : 1193 Length :1200
## 1st Qu.: 300.8 1st Qu.:34.00 1st Qu.: 6224 N.unique : 5
## Median : 600.5 Median :42.00 Median : 8835 N.blank : 0
## Mean : 600.5 Mean :42.32 Mean :10181 Min.nchar: 3
## 3rd Qu.: 900.2 3rd Qu.:50.00 3rd Qu.:12664 Max.nchar: 13
## Max. :1200.0 Max. :75.00 Max. :38501
## canal antiguedad siniestros_2a satisfaccion
## Length :1200 Min. : 1.000 Min. :0.0000 Min. : 1.000
## N.unique : 4 1st Qu.: 3.000 1st Qu.:0.0000 1st Qu.: 5.000
## N.blank : 0 Median : 4.000 Median :0.0000 Median : 7.000
## Min.nchar: 6 Mean : 5.146 Mean :0.3667 Mean : 6.808
## Max.nchar: 12 3rd Qu.: 7.000 3rd Qu.:1.0000 3rd Qu.: 8.000
## Max. :23.000 Max. :4.0000 Max. :10.000
## incremento_prima intencion_renovar renueva
## Min. :-5.000 Min. :1 Length :1200
## 1st Qu.: 4.500 1st Qu.:2 N.unique : 2
## Median : 8.200 Median :3 N.blank : 0
## Mean : 8.311 Mean :3 Min.nchar: 2
## 3rd Qu.:12.200 3rd Qu.:4 Max.nchar: 2
## Max. :29.700 Max. :5
Diccionario inicial de
variables
diccionario <- data.frame(
Variable = names(mercado_seguros),
Descripcion = c(
"Identificador",
"Edad del cliente",
"Ingreso mensual estimado",
"Región",
"Canal principal",
"Antigüedad como cliente",
"Número de siniestros en los últimos dos años",
"Satisfacción de 1 a 10",
"Incremento porcentual de la prima",
"Intención de renovación de 1 a 5",
"Renovación observada"
)
)
knitr::kable(
diccionario,
caption = "Diccionario inicial de variables"
)
Diccionario inicial de variables
| id |
Identificador |
| edad |
Edad del cliente |
| ingreso_mensual |
Ingreso mensual estimado |
| region |
Región |
| canal |
Canal principal |
| antiguedad |
Antigüedad como cliente |
| siniestros_2a |
Número de siniestros en los últimos dos años |
| satisfaccion |
Satisfacción de 1 a 10 |
| incremento_prima |
Incremento porcentual de la prima |
| intencion_renovar |
Intención de renovación de 1 a 5 |
| renueva |
Renovación observada |
Pregunta exploratoria
1: ¿Quiénes integran el mercado?
Veamos la edad.
summary(
mercado_seguros$edad
)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 18.00 34.00 42.00 42.32 50.00 75.00
Visualicemos.
ggplot(
mercado_seguros,
aes(x = edad)
) +
geom_histogram(
bins = 25,
color = "white"
) +
labs(
title = "Distribución de edad",
x = "Edad",
y = "Número de clientes"
) +
theme_minimal()

Esta gráfica responde una pregunta descriptiva.
No explica por qué ocurre algo.
Pregunta exploratoria
2: ¿Dónde están los clientes?
tabla_region <- table(
mercado_seguros$region
)
tabla_region
##
## Metropolitana Norte Occidente Oriente Sur
## 497 143 228 193 139
Porcentajes:
round(
prop.table(tabla_region) * 100,
1
)
##
## Metropolitana Norte Occidente Oriente Sur
## 41.4 11.9 19.0 16.1 11.6
Gráfico:
mercado_seguros %>%
count(region) %>%
mutate(
porcentaje = n / sum(n)
) %>%
ggplot(
aes(
x = reorder(region, n),
y = porcentaje
)
) +
geom_col() +
coord_flip() +
scale_y_continuous(
labels = scales::percent
) +
labs(
title = "Distribución territorial de clientes",
x = NULL,
y = "Porcentaje"
) +
theme_minimal()

Pregunta exploratoria
3: ¿Cómo es la satisfacción?
summary(
mercado_seguros$satisfaccion
)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.000 5.000 7.000 6.808 8.000 10.000
Distribución:
mercado_seguros %>%
count(satisfaccion) %>%
ggplot(
aes(
x = factor(satisfaccion),
y = n
)
) +
geom_col() +
labs(
title = "Satisfacción de los clientes",
x = "Satisfacción",
y = "Número de clientes"
) +
theme_minimal()

Pregunta exploratoria
4: ¿Qué porcentaje renueva?
table(
mercado_seguros$renueva
)
##
## No Sí
## 310 890
round(
prop.table(
table(
mercado_seguros$renueva
)
) * 100,
1
)
##
## No Sí
## 25.8 74.2
Del análisis
descriptivo a nuevas preguntas
Supongamos que observamos una tasa considerable de no renovación.
La siguiente pregunta no debería ser automáticamente:
¿Cómo puedo construir una regresión?
La pregunta correcta es:
¿Qué hipótesis razonables podrían explicar la no renovación?
Podríamos explorar:
- incremento de prima;
- satisfacción;
- siniestros;
- antigüedad;
- canal;
- región.
Prima y
renovación
Calculemos el incremento promedio según renovación.
mercado_seguros %>%
group_by(renueva) %>%
summarise(
n = n(),
incremento_promedio = mean(incremento_prima),
mediana_incremento = median(incremento_prima)
)
Visualicemos.
ggplot(
mercado_seguros,
aes(
x = renueva,
y = incremento_prima
)
) +
geom_boxplot() +
labs(
title = "Incremento de prima según renovación",
x = "Renovación",
y = "Incremento de prima (%)"
) +
theme_minimal()

¿Qué podemos decir?
Podemos decir que existen diferencias descriptivas entre los
grupos.
Todavía no podemos decir que:
“el incremento de prima causa la no renovación”.
¿Por qué?
Porque no hemos controlado:
- satisfacción;
- antigüedad;
- siniestros;
- ingreso;
- posibles variables omitidas.
Satisfacción y
renovación
mercado_seguros %>%
group_by(renueva) %>%
summarise(
satisfaccion_promedio = mean(satisfaccion),
mediana = median(satisfaccion),
n = n()
)
ggplot(
mercado_seguros,
aes(
x = renueva,
y = satisfaccion
)
) +
geom_boxplot() +
labs(
title = "Satisfacción según renovación",
x = "Renovación",
y = "Satisfacción"
) +
theme_minimal()

Ahora tenemos otra pista.
Quizá el problema sea más complejo que simplemente el precio.
Combinando dos
dimensiones
Podemos explorar satisfacción e incremento de prima.
ggplot(
mercado_seguros,
aes(
x = incremento_prima,
y = satisfaccion
)
) +
geom_point(
alpha = 0.35
) +
facet_wrap(
~ renueva
) +
labs(
title = "Prima y satisfacción según renovación",
x = "Incremento de prima (%)",
y = "Satisfacción"
) +
theme_minimal()

Esta gráfica puede generar nuevas hipótesis.
Por ejemplo:
La combinación de incrementos altos y baja satisfacción podría estar
asociada con menor renovación.
Observe la dinámica:
DATOS
↓
EXPLORACIÓN
↓
PATRÓN
↓
PREGUNTA
↓
HIPÓTESIS
↓
ANÁLISIS POSTERIOR
Correlación no
significa causalidad
Esta distinción será recurrente durante el curso.
Supongamos que observamos:
\[
X \uparrow \quad \text{cuando} \quad Y \uparrow
\]
Eso demuestra asociación.
No necesariamente demuestra:
\[
X \rightarrow Y
\]
Puede existir:
\[
Z \rightarrow X
\]
y simultáneamente:
\[
Z \rightarrow Y
\]
Ejemplo actuarial de
confusión
Imagine que encontramos:
Los clientes con primas más altas tienen más siniestros.
¿Podemos concluir que aumentar la prima causa siniestros?
No.
Probablemente ambas variables están relacionadas con:
- exposición;
- tipo de vehículo;
- edad;
- suma asegurada;
- zona;
- características del riesgo.
La estructura podría ser:
Nivel de riesgo
↓
┌─────────────┐
↓ ↓
Prima Siniestros
La prima y los siniestros aparecen asociados, pero una variable
subyacente puede explicar parte de la relación.
Ejemplo de diseño
causal
Suponga que la empresa desea saber:
¿Enviar un mensaje personalizado aumenta la renovación?
Podemos imaginar un experimento.
set.seed(100)
experimento <- data.frame(
grupo = rep(
c(
"Mensaje estándar",
"Mensaje personalizado"
),
each = 500
)
)
experimento$renueva <- c(
rbinom(
500,
1,
0.67
),
rbinom(
500,
1,
0.75
)
)
aggregate(
renueva ~ grupo,
data = experimento,
FUN = mean
)
Visualicemos.
experimento %>%
group_by(grupo) %>%
summarise(
tasa = mean(renueva)
) %>%
ggplot(
aes(
x = grupo,
y = tasa
)
) +
geom_col() +
scale_y_continuous(
labels = scales::percent
) +
labs(
title = "Tasa de renovación por tratamiento",
x = NULL,
y = "Tasa de renovación"
) +
theme_minimal()

La lógica causal requiere mucho más que observar una diferencia.
Necesitamos considerar:
- asignación;
- comparabilidad;
- variables extrañas;
- tamaño de muestra;
- azar;
- validez interna;
- validez externa.
Lo estudiaremos con mayor detalle posteriormente.
Un principio
importante
Durante este curso evitaremos la lógica:
Tengo una base
↓
¿Qué análisis puedo hacer?
Intentaremos utilizar:
Tengo una decisión
↓
¿Qué necesito saber?
↓
¿Qué pregunta debo responder?
↓
¿Qué datos necesito?
↓
¿Qué análisis corresponde?
Primero la pregunta. Después el método.
No utilizaremos una técnica estadística simplemente porque esté
disponible.
Mapa conceptual
final
DECISIÓN EMPRESARIAL
│
▼
DEFINIR EL PROBLEMA
│
┌────────────────────┴─────────────────────┐
│ │
▼ ▼
CONTEXTO DEL PROBLEMA INFORMACIÓN EXISTENTE
│ │
└────────────────────┬─────────────────────┘
▼
PROBLEMA DE INVESTIGACIÓN
│
▼
OBJETIVOS
│
▼
PREGUNTAS DE INVESTIGACIÓN
│
▼
HIPÓTESIS
│
▼
VARIABLES
│
▼
INFORMACIÓN REQUERIDA
│
▼
DISEÑO DE INVESTIGACIÓN
/ | \
/ | \
EXPLORATORIO DESCRIPTIVO CAUSAL
\ | /
\ | /
▼
DATOS
│
▼
R
│
▼
EVIDENCIA
│
▼
TOMA DE DECISIONES
Referencia base
Malhotra, N. K. (2008). Investigación de mercados. Un enfoque
aplicado. Quinta edición. Pearson Educación.
LS0tCnRpdGxlOiAiRGUgbGEgZGVjaXNpw7NuIGVtcHJlc2FyaWFsIGEgbGEgcHJlZ3VudGEgZGUgaW52ZXN0aWdhY2nDs24iCnN1YnRpdGxlOiAiTWFlc3RyaWEgZW4gY2llbmNpYXMgYWN0dWFyaWFsZXMgYXBsaWNhZGFzIgphdXRob3I6ICJDdXJzbyBkZSBBbsOhbGlzaXMgZGUgTWVyY2FkbyIKZGF0ZTogImByIGZvcm1hdChTeXMuRGF0ZSgpLCAnJWQvJW0vJVknKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRoZW1lOiBmbGF0bHkKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGRmX3ByaW50OiBwYWdlZAogICAgc2VsZl9jb250YWluZWQ6IHRydWUKLS0tCgo8c3R5bGU+CmJvZHkgewogIGZvbnQtc2l6ZTogMTdweDsKICBsaW5lLWhlaWdodDogMS42NTsKfQoKaDEsIGgyLCBoMyB7CiAgZm9udC13ZWlnaHQ6IDYwMDsKfQoKYmxvY2txdW90ZSB7CiAgYm9yZGVyLWxlZnQ6IDVweCBzb2xpZCAjMmMzZTUwOwogIHBhZGRpbmc6IDEwcHggMjBweDsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjdmN2Y3Owp9CgouY2FqYSB7CiAgcGFkZGluZzogMThweDsKICBtYXJnaW46IDE4cHggMDsKICBib3JkZXItcmFkaXVzOiA3cHg7CiAgYmFja2dyb3VuZC1jb2xvcjogI2Y1ZjdmOTsKICBib3JkZXItbGVmdDogNnB4IHNvbGlkICMzNDQ5NWU7Cn0KCi5jYWphLWVqZW1wbG8gewogIHBhZGRpbmc6IDE4cHg7CiAgbWFyZ2luOiAxOHB4IDA7CiAgYm9yZGVyLXJhZGl1czogN3B4OwogIGJhY2tncm91bmQtY29sb3I6ICNmM2Y4ZmM7CiAgYm9yZGVyLWxlZnQ6IDZweCBzb2xpZCAjMzQ5OGRiOwp9CgouY2FqYS1hY3R1YXJpYWwgewogIHBhZGRpbmc6IDE4cHg7CiAgbWFyZ2luOiAxOHB4IDA7CiAgYm9yZGVyLXJhZGl1czogN3B4OwogIGJhY2tncm91bmQtY29sb3I6ICNmNGZhZjY7CiAgYm9yZGVyLWxlZnQ6IDZweCBzb2xpZCAjMjdhZTYwOwp9CgouY2FqYS1hbGVydGEgewogIHBhZGRpbmc6IDE4cHg7CiAgbWFyZ2luOiAxOHB4IDA7CiAgYm9yZGVyLXJhZGl1czogN3B4OwogIGJhY2tncm91bmQtY29sb3I6ICNmZmY4ZjI7CiAgYm9yZGVyLWxlZnQ6IDZweCBzb2xpZCAjZTY3ZTIyOwp9CgouY2FqYS1wcmVndW50YSB7CiAgcGFkZGluZzogMThweDsKICBtYXJnaW46IDE4cHggMDsKICBib3JkZXItcmFkaXVzOiA3cHg7CiAgYmFja2dyb3VuZC1jb2xvcjogI2ZhZjVmYzsKICBib3JkZXItbGVmdDogNnB4IHNvbGlkICM4ZTQ0YWQ7Cn0KCi5jYWphLXJlc3VtZW4gewogIHBhZGRpbmc6IDIwcHg7CiAgbWFyZ2luOiAyMHB4IDA7CiAgYm9yZGVyLXJhZGl1czogN3B4OwogIGJhY2tncm91bmQtY29sb3I6ICNlZWY1Zjk7CiAgYm9yZGVyOiAxcHggc29saWQgI2NjZDZkZDsKfQoKdGFibGUgewogIGZvbnQtc2l6ZTogMTVweDsKfQoKZGV0YWlscyB7CiAgbWFyZ2luOiAxMnB4IDA7CiAgcGFkZGluZzogMTJweDsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjhmOWZhOwogIGJvcmRlci1yYWRpdXM6IDVweDsKfQoKc3VtbWFyeSB7CiAgY3Vyc29yOiBwb2ludGVyOwogIGZvbnQtd2VpZ2h0OiBib2xkOwp9Cjwvc3R5bGU+CgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBUUlVFLAogIHdhcm5pbmcgPSBGQUxTRSwKICBtZXNzYWdlID0gRkFMU0UsCiAgZmlnLmFsaWduID0gImNlbnRlciIsCiAgZmlnLndpZHRoID0gOCwKICBmaWcuaGVpZ2h0ID0gNQopCgpzZXQuc2VlZCgyMDI2KQoKcGFxdWV0ZXMgPC0gYygKICAiZ2dwbG90MiIsCiAgImRwbHlyIiwKICAidGlkeXIiLAogICJrbml0ciIsCiAgInNjYWxlcyIKKQoKZmFsdGFudGVzIDwtIHBhcXVldGVzWwogICFwYXF1ZXRlcyAlaW4lIHJvd25hbWVzKGluc3RhbGxlZC5wYWNrYWdlcygpKQpdCgppZihsZW5ndGgoZmFsdGFudGVzKSA+IDApewogIGluc3RhbGwucGFja2FnZXMoZmFsdGFudGVzKQp9CgppbnZpc2libGUoCiAgbGFwcGx5KAogICAgcGFxdWV0ZXMsCiAgICBsaWJyYXJ5LAogICAgY2hhcmFjdGVyLm9ubHkgPSBUUlVFCiAgKQopCmBgYAoKPiAqKkFwcmVuZGVyIGEgY29udmVydGlyIHVuYSBkZWNpc2nDs24gZW1wcmVzYXJpYWwgZW4gdW4gcHJvYmxlbWEgcXVlIHB1ZWRhIGludmVzdGlnYXJzZSBtZWRpYW50ZSBkYXRvcy4qKgoKRW4gaW52ZXN0aWdhY2nDs24gZGUgbWVyY2Fkb3MsIGVsIGFuw6FsaXNpcyBlc3RhZMOtc3RpY28gbm8gY29taWVuemEgY3VhbmRvIGFicmltb3MgUi4KCkFudGVzIGRlIGFuYWxpemFyIGRhdG9zIGRlYmVtb3MgZXN0YWJsZWNlcjoKCjEuIHF1w6kgZGVjaXNpw7NuIGRlYmUgdG9tYXJzZTsKMi4gY3XDoWwgZXMgZWwgcHJvYmxlbWEgcmVhbDsKMy4gcXXDqSBpbmZvcm1hY2nDs24gbmVjZXNpdGFtb3M7CjQuIHF1w6kgcHJlZ3VudGFzIHBvZGVtb3MgcmVzcG9uZGVyOwo1LiBxdcOpIHZhcmlhYmxlcyByZXByZXNlbnRhbiBlc2FzIHByZWd1bnRhczsKNi4gcXXDqSBkaXNlw7FvIGRlIGludmVzdGlnYWNpw7NuIGVzIGFwcm9waWFkbzsKNy4geSBzb2xhbWVudGUgZW50b25jZXMsIHF1w6kgZGF0b3MgZGViZW1vcyBhbmFsaXphci4KCgpQb2RlbW9zIGRpc3BvbmVyIGRlIG1pbGxvbmVzIGRlIG9ic2VydmFjaW9uZXMgeSwgYXVuIGFzw60sIG5vIHRlbmVyIGNsYXJhbWVudGUgaWRlbnRpZmljYWRvIHF1w6kgcHJlZ3VudGEgZGViZSByZXNwb25kZXIuCgpQb3IgZWplbXBsbzoKCi0gdW5hIGFzZWd1cmFkb3JhIG9ic2VydmEgdW5hIHJlZHVjY2nDs24gZGUgcmVub3ZhY2lvbmVzOwotIHVuYSBjb21wYcOxw61hIHF1aWVyZSBpbnRyb2R1Y2lyIHVuIG51ZXZvIHNlZ3VybzsKLSBhdW1lbnRhIGxhIGZyZWN1ZW5jaWEgZGUgcmVjbGFtYWNpb25lczsKLSBkZXRlcm1pbmFkb3MgY2xpZW50ZXMgYWJhbmRvbmFuIHVuYSBww7NsaXphOwotIGV4aXN0ZSBwb2NhIGRlbWFuZGEgcG9yIHVuIHByb2R1Y3RvIGRlIG1pY3Jvc2VndXJvOwotIHVuYSBhc2VndXJhZG9yYSBjb25zaWRlcmEgbW9kaWZpY2FyIHVuYSBwcmltYTsKLSB1bmEgZW50aWRhZCBwcmV2aXNpb25hbCBxdWllcmUgYXVtZW50YXIgbGEgcGFydGljaXBhY2nDs24gdm9sdW50YXJpYTsKLSB1bmEgY29tcGHDscOtYSBxdWllcmUgaWRlbnRpZmljYXIgbnVldm9zIHNlZ21lbnRvcyBkZSBtZXJjYWRvLgoKRW4gdG9kb3MgZXN0b3MgY2Fzb3MgZXhpc3RlIGluaWNpYWxtZW50ZSB1bmEgKipkZWNpc2nDs24gZW1wcmVzYXJpYWwqKi4KCkxhIGludmVzdGlnYWNpw7NuIHBlcm1pdGUgdHJhbnNmb3JtYXIgZXNhIGRlY2lzacOzbiBlbiB1bmEgKipwcmVndW50YSBzdXNjZXB0aWJsZSBkZSBzZXIgcmVzcG9uZGlkYSBtZWRpYW50ZSBldmlkZW5jaWEqKi4KCi0tLQoKIyBSdXRhIGRlIGFwcmVuZGl6YWplCgpEdXJhbnRlIGVzdGEgY2xhc2Ugc2VndWlyZW1vcyBsYSBzaWd1aWVudGUgc2VjdWVuY2lhOgo8ZGl2IGNsYXNzPSJjYWphIj4KKipEZWNpc2nDs24gZW1wcmVzYXJpYWwqKiAtCioqUHJvYmxlbWEgZGUgaW52ZXN0aWdhY2nDs24qKiAtCioqT2JqZXRpdm9zKiogLQoqKlByZWd1bnRhcyBkZSBpbnZlc3RpZ2FjacOzbioqIC0KKipIaXDDs3Rlc2lzKiogLQoqKlZhcmlhYmxlcyoqIC0KKipJbmZvcm1hY2nDs24gcmVxdWVyaWRhKiogLQoqKkRpc2XDsW8gZGUgaW52ZXN0aWdhY2nDs24qKiAtCioqRGF0b3MqKiAtCioqRXhwbG9yYWNpw7NuIGluaWNpYWwqKiAtCioqRXZpZGVuY2lhIHBhcmEgbGEgZGVjaXNpw7NuKiogLQo8L2Rpdj4KCiMgwr9RdcOpIGVzIGxhIGludmVzdGlnYWNpw7NuIGRlIG1lcmNhZG9zPwoKTGEgaW52ZXN0aWdhY2nDs24gZGUgbWVyY2Fkb3MgcHVlZGUgZW50ZW5kZXJzZSBjb21vIHVuICoqcHJvY2VzbyBzaXN0ZW3DoXRpY28gcGFyYSBnZW5lcmFyIGluZm9ybWFjacOzbiBxdWUgY29udHJpYnV5YSBhIGxhIHRvbWEgZGUgZGVjaXNpb25lcyByZWxhY2lvbmFkYXMgY29uIHVuIG1lcmNhZG8qKi4KCkxvIGltcG9ydGFudGUgZGUgZXN0YSBkZWZpbmljacOzbiBubyBlcyBzb2xhbWVudGUgbGEgcGFsYWJyYSAqbWVyY2FkbyouCgpMYSBpbnZlc3RpZ2FjacOzbiBubyBjb25zaXN0ZSBzaW1wbGVtZW50ZSBlbiByZWNvcGlsYXIgZGF0b3MuCgpUYW1wb2NvIGNvbnNpc3RlIHNvbGFtZW50ZSBlbiBhcGxpY2FyIGVuY3Vlc3Rhcy4KCk11Y2hvIG1lbm9zIGNvbnNpc3RlIMO6bmljYW1lbnRlIGVuIGFwbGljYXIgdMOpY25pY2FzIGVzdGFkw61zdGljYXMuCgo8ZGl2IGNsYXNzPSJjYWphLWFsZXJ0YSI+CgojIyBJZGVhIGZ1bmRhbWVudGFsCgpUZW5lciBkYXRvcyBubyBzaWduaWZpY2EgdGVuZXIgaW5mb3JtYWNpw7NuLgoKVGVuZXIgaW5mb3JtYWNpw7NuIG5vIHNpZ25pZmljYSB0ZW5lciBjb25vY2ltaWVudG8uCgpZIHRlbmVyIGNvbm9jaW1pZW50byBubyBpbXBsaWNhIGF1dG9tw6F0aWNhbWVudGUgdW5hIGJ1ZW5hIGRlY2lzacOzbi4KCkVsIHRyYWJham8gZGVsIGludmVzdGlnYWRvciBjb25zaXN0ZSBlbiBjb25zdHJ1aXIgdW5hIGNvbmV4acOzbiBsw7NnaWNhIGVudHJlOgoKKipwcm9ibGVtYSDihpIgZXZpZGVuY2lhIOKGkiBpbnRlcnByZXRhY2nDs24g4oaSIGRlY2lzacOzbi4qKgoKPC9kaXY+CgojIyBJbnZlc3RpZ2FjacOzbiB5IHRvbWEgZGUgZGVjaXNpb25lcwoKQ29uc2lkZXJlIGVsIHNpZ3VpZW50ZSBlamVtcGxvLgoKVW5hIGFzZWd1cmFkb3JhIG9ic2VydmEgcXVlIGxhIHRhc2EgZGUgcmVub3ZhY2nDs24gZGUgdW4gc2VndXJvIGRlIGF1dG9tw7N2aWwgY2F5w7MgZGUgODIlIGEgNzQlLgoKTGEgYWRtaW5pc3RyYWNpw7NuIHBvZHLDrWEgaW5tZWRpYXRhbWVudGUgY29uY2x1aXI6Cgo+IOKAnEVsIHByb2JsZW1hIGVzIHF1ZSBsYSBwcmltYSBlcyBkZW1hc2lhZG8gYWx0YS7igJ0KClBlcm8gZXNhIGFmaXJtYWNpw7NuIHRvZGF2w61hIG5vIGhhIHNpZG8gZGVtb3N0cmFkYS4KCk90cmFzIGV4cGxpY2FjaW9uZXMgcG9kcsOtYW4gc2VyOgoKLSBtYWxhIGF0ZW5jacOzbjsKLSBhdW1lbnRvIGRlIGNvbXBldGVuY2lhOwotIG1vZGlmaWNhY2lvbmVzIGVuIGxhcyBjb2JlcnR1cmFzOwotIG1hbGEgZXhwZXJpZW5jaWEgZHVyYW50ZSB1biBzaW5pZXN0cm87Ci0gY2FtYmlvcyBlbiBlbCBpbmdyZXNvIGRlIGxvcyBjbGllbnRlczsKLSBudWV2b3MgcHJvZHVjdG9zIHN1c3RpdHV0b3M7Ci0gcHJvbW9jaW9uZXMgZGUgY29tcGV0aWRvcmVzOwotIG1vZGlmaWNhY2lvbmVzIGVuIGNhbmFsZXMgZGlnaXRhbGVzOwotIGNhcmFjdGVyw61zdGljYXMgcGFydGljdWxhcmVzIGRlIGRldGVybWluYWRvcyBzZWdtZW50b3MuCgpMYSBpbnZlc3RpZ2FjacOzbiBkZSBtZXJjYWRvcyBidXNjYSByZWR1Y2lyIGVzdGEgaW5jZXJ0aWR1bWJyZS4KCi0tLQoKIyBBcGxpY2FjacOzbiBlbiBjaWVuY2lhcyBhY3R1YXJpYWxlcwoKVHJhZGljaW9uYWxtZW50ZSwgZWwgYW7DoWxpc2lzIGFjdHVhcmlhbCBzZSBjb25jZW50cmEgZW4gZmVuw7NtZW5vcyBjb21vOgoKLSBtb3J0YWxpZGFkOwotIG1vcmJpbGlkYWQ7Ci0gZnJlY3VlbmNpYSBkZSBzaW5pZXN0cm9zOwotIHNldmVyaWRhZDsKLSByZXNlcnZhczsKLSBzb2x2ZW5jaWE7Ci0gcHJpbWFzOwotIHN1cGVydml2ZW5jaWE7Ci0gYWJhbmRvbm87Ci0gcmllc2dvIGZpbmFuY2llcm8uCgpMYSBpbnZlc3RpZ2FjacOzbiBkZSBtZXJjYWRvcyBjb21wbGVtZW50YSBlc3RhIHBlcnNwZWN0aXZhIGluY29ycG9yYW5kbyBwcmVndW50YXMgY29tbzoKCi0gwr9xdcOpIHByb2R1Y3RvcyBkZXNlYSBlbCBjb25zdW1pZG9yPzsKLSDCv3F1w6kgYXRyaWJ1dG9zIHZhbG9yYT87Ci0gwr9xdcOpIHByZWNpbyBlc3TDoSBkaXNwdWVzdG8gYSBhY2VwdGFyPzsKLSDCv3BvciBxdcOpIGFiYW5kb25hIHVuYSBww7NsaXphPzsKLSDCv3F1w6kgY2FuYWwgcHJlZmllcmU/OwotIMK/cXXDqSBzZWdtZW50b3MgdGllbmVuIG1heW9yIGludGVuY2nDs24gZGUgY29tcHJhPzsKLSDCv3F1w6kgcGVyY2VwY2nDs24gdGllbmUgc29icmUgdW5hIGFzZWd1cmFkb3JhPzsKLSDCv2NvbXByZW5kZSBhZGVjdWFkYW1lbnRlIGxhcyBjb2JlcnR1cmFzPzsKLSDCv3F1w6kgZmFjdG9yZXMgaW5mbHV5ZW4gc29icmUgc3UgcmVub3ZhY2nDs24/OwotIMK/cXXDqSBjb21iaW5hY2nDs24gZGUgYmVuZWZpY2lvcyByZXN1bHRhIG3DoXMgYXRyYWN0aXZhPwoKPGRpdiBjbGFzcz0iY2FqYS1hY3R1YXJpYWwiPgoKIyMgUGVyc3BlY3RpdmEgYWN0dWFyaWFsCgpVbiBtb2RlbG8gYWN0dWFyaWFsIHB1ZWRlIHJlc3BvbmRlcjoKCj4gwr9DdcOhbCBkZWJlcsOtYSBzZXIgbGEgcHJpbWEgdMOpY25pY2EgYXNvY2lhZGEgY29uIGRldGVybWluYWRvIG5pdmVsIGRlIHJpZXNnbz8KCkxhIGludmVzdGlnYWNpw7NuIGRlIG1lcmNhZG9zIHB1ZWRlIHJlc3BvbmRlcjoKCj4gwr9Dw7NtbyByZWFjY2lvbmFyw6EgZWwgY29uc3VtaWRvciBmcmVudGUgYSBlc2EgcHJpbWE/CgpTb24gcHJlZ3VudGFzIGRpc3RpbnRhcy4KClBhcmEgdG9tYXIgdW5hIGRlY2lzacOzbiBlbXByZXNhcmlhbCBjb21wbGV0YSBwdWVkZW4gc2VyIG5lY2VzYXJpYXMgYW1iYXMgcmVzcHVlc3Rhcy4KCjwvZGl2PgoKLS0tCgojIERvcyBncmFuZGVzIHByb3DDs3NpdG9zIGRlIGxhIGludmVzdGlnYWNpw7NuCgpQb2RlbW9zIGRpc3Rpbmd1aXIgY29uY2VwdHVhbG1lbnRlIGRvcyBncmFuZGVzIHByb3DDs3NpdG9zLgoKIyMgSW52ZXN0aWdhY2nDs24gcGFyYSBpZGVudGlmaWNhciBwcm9ibGVtYXMKCkJ1c2NhIGRldGVjdGFyIGZlbsOzbWVub3MgcXVlIHF1aXrDoSB0b2RhdsOtYSBubyBzb24gZXZpZGVudGVzLgoKRWplbXBsb3M6CgotIHJlZHVjY2nDs24gZ3JhZHVhbCBkZSBwYXJ0aWNpcGFjacOzbiBkZSBtZXJjYWRvOwotIGNhbWJpbyBlbiBwcmVmZXJlbmNpYXM7Ci0gZGV0ZXJpb3JvIGRlIGltYWdlbjsKLSBhcGFyaWNpw7NuIGRlIG51ZXZvcyBzZWdtZW50b3M7Ci0gbW9kaWZpY2FjacOzbiBkZWwgY29tcG9ydGFtaWVudG8gZGUgY29tcHJhOwotIGNhbWJpb3MgZW4gcGVyY2VwY2nDs24gZGVsIHByZWNpbzsKLSBvcG9ydHVuaWRhZGVzIHBhcmEgbnVldm9zIHByb2R1Y3Rvcy4KCiMjIEludmVzdGlnYWNpw7NuIHBhcmEgcmVzb2x2ZXIgcHJvYmxlbWFzCgpTZSByZWFsaXphIGN1YW5kbyBlbCBwcm9ibGVtYSB5YSBoYSBzaWRvIGlkZW50aWZpY2Fkby4KCkVqZW1wbG9zOgoKLSBkZXRlcm1pbmFyIHF1w6kgcHJpbWEgY29tZXJjaWFsIHJlc3VsdGEgYWNlcHRhYmxlOwotIGVsZWdpciBlbnRyZSBkb3MgcHJvZHVjdG9zOwotIHNlbGVjY2lvbmFyIHVuIGNhbmFsIGRlIGRpc3RyaWJ1Y2nDs247Ci0gZXZhbHVhciB1bmEgY2FtcGHDsWE7Ci0gcmVkaXNlw7FhciB1bmEgY29iZXJ0dXJhOwotIGlkZW50aWZpY2FyIHNlZ21lbnRvcyBwcmlvcml0YXJpb3MuCgotLS0KCiMgRGVtb3N0cmFjacOzbjogZGF0b3MgdmVyc3VzIGluZm9ybWFjacOzbgoKU3Vwb25nYW1vcyBxdWUgdW5hIGFzZWd1cmFkb3JhIHRpZW5lIGxhIHNpZ3VpZW50ZSBpbmZvcm1hY2nDs246CgpgYGB7cn0KY2xpZW50ZXMgPC0gZGF0YS5mcmFtZSgKICBDbGllbnRlID0gcGFzdGUwKCJDIiwgMToxMCksCiAgUHJpbWEgPSBjKDE4MDAsIDE5MDAsIDIyMDAsIDIwNTAsIDI1MDAsCiAgICAgICAgICAgIDIzMDAsIDE5NTAsIDI3MDAsIDI2MDAsIDIxMDApLAogIFJlbnVldmEgPSBjKCJTw60iLCAiU8OtIiwgIk5vIiwgIlPDrSIsICJObyIsCiAgICAgICAgICAgICAgIk5vIiwgIlPDrSIsICJObyIsICJObyIsICJTw60iKQopCgpjbGllbnRlcwpgYGAKCkVzdG9zIHNvbiAqKmRhdG9zKiouCgpQb2RlbW9zIGVtcGV6YXIgYSByZXN1bWlybG9zLgoKYGBge3J9CmFnZ3JlZ2F0ZSgKICBQcmltYSB+IFJlbnVldmEsCiAgZGF0YSA9IGNsaWVudGVzLAogIEZVTiA9IG1lYW4KKQpgYGAKCkFob3JhIHRlbmVtb3MgdW5hIHByaW1lcmEgcGllemEgZGUgKippbmZvcm1hY2nDs24qKi4KClBvZGVtb3MgdmlzdWFsaXphcmxhLgoKYGBge3J9CmdncGxvdCgKICBjbGllbnRlcywKICBhZXMoeCA9IFJlbnVldmEsIHkgPSBQcmltYSkKKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJQcmltYSBzZWfDum4gZGVjaXNpw7NuIGRlIHJlbm92YWNpw7NuIiwKICAgIHggPSAiwr9SZW51ZXZhPyIsCiAgICB5ID0gIlByaW1hIGFudWFsIgogICkgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCsK/UXXDqSBwb2RlbW9zIGNvbmNsdWlyPwoKUXVpesOhIGxvcyBjbGllbnRlcyBxdWUgbm8gcmVudWV2YW4gcHJlc2VudGFuIHByaW1hcyBtw6FzIGVsZXZhZGFzLgoKUGVybyB0b2RhdsOtYSAqKm5vIHBvZGVtb3MgYWZpcm1hciBxdWUgbGEgcHJpbWEgY2F1c2UgZWwgYWJhbmRvbm8qKi4KClBvZHLDrWEgZXhpc3RpciB1bmEgdGVyY2VyYSB2YXJpYWJsZToKCi0gZWRhZDsKLSB0aXBvIGRlIHZlaMOtY3VsbzsKLSBjb2JlcnR1cmE7Ci0gZXhwZXJpZW5jaWEgZGUgc2luaWVzdHJvczsKLSBpbmdyZXNvOwotIGNvbXBldGlkb3I7Ci0gY2FsaWRhZCBkZWwgc2VydmljaW8uCgo8ZGl2IGNsYXNzPSJjYWphLXByZWd1bnRhIj4KCiMjIyBQcmVndW50YQoKwr9DdcOhbCBkZSBsYXMgc2lndWllbnRlcyBhZmlybWFjaW9uZXMgZXMgbWV0b2RvbMOzZ2ljYW1lbnRlIG3DoXMgY29ycmVjdGE/CgpBLiBMYXMgcHJpbWFzIGFsdGFzIGNhdXNhbiBhYmFuZG9uby4KCkIuIEVuIGVzdG9zIGRhdG9zIHBhcmVjZSBleGlzdGlyIHVuYSBkaWZlcmVuY2lhIGVuIGxhcyBwcmltYXMgZGUgcXVpZW5lcyByZW51ZXZhbiB5IHF1aWVuZXMgbm8gcmVudWV2YW4uCgpDLiBMYSBjb21wYcOxw61hIGRlYmUgaW5tZWRpYXRhbWVudGUgcmVkdWNpciBsYXMgcHJpbWFzLgoKPC9kaXY+Cgo8ZGV0YWlscz4KPHN1bW1hcnk+VmVyIHJlc3B1ZXN0YTwvc3VtbWFyeT4KCkxhIHJlc3B1ZXN0YSBjb3JyZWN0YSBlcyAqKkIqKi4KCkVuIGVzdGEgZXRhcGEgw7puaWNhbWVudGUgb2JzZXJ2YW1vcyB1bmEgYXNvY2lhY2nDs24gZGVzY3JpcHRpdmEuCgpObyB0ZW5lbW9zIGV2aWRlbmNpYSBzdWZpY2llbnRlIHBhcmEgZXN0YWJsZWNlciBjYXVzYWxpZGFkIG5pIHBhcmEgcmVjb21lbmRhciB1bmEgcmVkdWNjacOzbiBkZSBwcmltYXMuCgo8L2RldGFpbHM+CgotLS0KCiMgRWwgcHJvY2VzbyBkZSBpbnZlc3RpZ2FjacOzbiBkZSBtZXJjYWRvcwoKVW5hIGludmVzdGlnYWNpw7NuIHB1ZWRlIG9yZ2FuaXphcnNlIGNvbmNlcHR1YWxtZW50ZSBlbiBzZWlzIGdyYW5kZXMgZXRhcGFzOgoKMS4gZGVmaW5pY2nDs24gZGVsIHByb2JsZW1hOwoyLiBkZXNhcnJvbGxvIGRlbCBlbmZvcXVlOwozLiBmb3JtdWxhY2nDs24gZGVsIGRpc2XDsW87CjQuIHRyYWJham8gZGUgY2FtcG8gbyByZWNvcGlsYWNpw7NuOwo1LiBwcmVwYXJhY2nDs24geSBhbsOhbGlzaXMgZGUgZGF0b3M7CjYuIGVsYWJvcmFjacOzbiB5IHByZXNlbnRhY2nDs24gZGVsIGluZm9ybWUuCgotLS0KCiMjIFBhc28gMS4gRGVmaW5pciBlbCBwcm9ibGVtYQoKRXN0YSBwcm9iYWJsZW1lbnRlIHNlYSBsYSBldGFwYSBjb25jZXB0dWFsbWVudGUgbcOhcyBpbXBvcnRhbnRlLgoKU2kgZGVmaW5pbW9zIG1hbCBlbCBwcm9ibGVtYSwgcG9kZW1vcyByZWFsaXphcjoKCi0gdW5hIGV4Y2VsZW50ZSBlbmN1ZXN0YTsKLSB1biBleGNlbGVudGUgbXVlc3RyZW87Ci0gdW5hIGV4Y2VsZW50ZSByZWdyZXNpw7NuOwotIHVuIGV4Y2VsZW50ZSBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvOwoKeSBhdW4gYXPDrSByZXNwb25kZXIgdW5hIHByZWd1bnRhIGVxdWl2b2NhZGEuCgo8ZGl2IGNsYXNzPSJjYWphLWFsZXJ0YSI+CgojIyMgUHJpbmNpcGlvIG1ldG9kb2zDs2dpY28KClVuYSB0w6ljbmljYSBlc3RhZMOtc3RpY2Egc29maXN0aWNhZGEgbm8gY29ycmlnZSB1bmEgcHJlZ3VudGEgbWFsIGZvcm11bGFkYS4KCjwvZGl2PgoKLS0tCgojIyBQYXNvIDIuIERlc2Fycm9sbGFyIGVsIGVuZm9xdWUKClVuYSB2ZXogZGVmaW5pZG8gZWwgcHJvYmxlbWEgZGViZW1vcyBkZXRlcm1pbmFyOgoKLSBxdcOpIHNhYmVtb3M7Ci0gcXXDqSB0ZW9yw61hIHB1ZWRlIG9yaWVudGFybm9zOwotIHF1w6kgdmFyaWFibGVzIHBvZHLDrWFuIGludGVydmVuaXI7Ci0gcXXDqSByZWxhY2lvbmVzIGVzcGVyYW1vczsKLSBxdcOpIHByZWd1bnRhcyBxdWVyZW1vcyByZXNwb25kZXI7Ci0gcXXDqSBoaXDDs3Rlc2lzIHB1ZWRlbiBwbGFudGVhcnNlOwotIHF1w6kgaW5mb3JtYWNpw7NuIG5lY2VzaXRhbW9zLgoKLS0tCgojIyBQYXNvIDMuIEZvcm11bGFyIGVsIGRpc2XDsW8KCkRlYmVtb3MgZGVjaWRpciBjw7NtbyBvYnRlbmRyZW1vcyBsYSBldmlkZW5jaWEuCgpFbCBlc3R1ZGlvIHB1ZWRlIHNlcjoKCi0gZXhwbG9yYXRvcmlvOwotIGRlc2NyaXB0aXZvOwotIGNhdXNhbDsKCnkgcHVlZGUgdXRpbGl6YXI6CgotIGluZm9ybWFjacOzbiBzZWN1bmRhcmlhOwotIGVudHJldmlzdGFzOwotIGdydXBvcyBmb2NhbGVzOwotIG9ic2VydmFjacOzbjsKLSBlbmN1ZXN0YXM7Ci0gZXhwZXJpbWVudG9zOwotIGRhdG9zIGFkbWluaXN0cmF0aXZvcy4KCi0tLQoKIyMgUGFzbyA0LiBSZWNvbGVjdGFyIGluZm9ybWFjacOzbgoKRW4gZXN0YSBmYXNlIHNlIGVqZWN1dGEgZWwgZGlzZcOxby4KCk3DoXMgYWRlbGFudGUgZXN0dWRpYXJlbW9zOgoKLSB0cmFiYWpvIGRlIGNhbXBvOwotIGN1ZXN0aW9uYXJpb3M7Ci0gbXVlc3RyZW87Ci0gY29udHJvbGVzOwotIGNhbGlkYWQuCgotLS0KCiMjIFBhc28gNS4gUHJlcGFyYXIgeSBhbmFsaXphcgoKTG9zIGRhdG9zIGRlYmVuOgoKLSByZXZpc2Fyc2U7Ci0gY29kaWZpY2Fyc2U7Ci0gZGVwdXJhcnNlOwotIHRyYW5zZm9ybWFyc2U7Ci0gcmVzdW1pcnNlOwotIGFuYWxpemFyc2UuCgpSIHNlcsOhIG51ZXN0cmEgaGVycmFtaWVudGEgcHJpbmNpcGFsIGR1cmFudGUgZWwgY3Vyc28uCgotLS0KCiMjIFBhc28gNi4gQ29tdW5pY2FyIHJlc3VsdGFkb3MKCkVsIHByb2R1Y3RvIGZpbmFsIG5vIGVzIHVuYSBzYWxpZGEgZGUgUi4KCkVsIHByb2R1Y3RvIGZpbmFsIGVzIHVuYSByZXNwdWVzdGEgZnVuZGFtZW50YWRhLgoKUG9yIGVqZW1wbG86Cgo+IOKAnExvcyBjbGllbnRlcyBleHB1ZXN0b3MgYSBpbmNyZW1lbnRvcyBkZSBwcmltYSBzdXBlcmlvcmVzIGFsIDEwJSBwcmVzZW50YW4gbWVub3IgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbiwgZXNwZWNpYWxtZW50ZSBjdWFuZG8gc3UgdmFsb3JhY2nDs24gZGVsIHNlcnZpY2lvIHRhbWJpw6luIGVzIGJhamEu4oCdCgpFc3RhIGFmaXJtYWNpw7NuIGVzIG11Y2hvIG3DoXMgw7p0aWwgcXVlIG1vc3RyYXIgw7puaWNhbWVudGUgdW5hIHRhYmxhIGRlIGNvZWZpY2llbnRlcy4KCi0tLQoKIyBQcm9ibGVtYSBlbXByZXNhcmlhbCB2ZXJzdXMgcHJvYmxlbWEgZGUgaW52ZXN0aWdhY2nDs24KCkVzdGEgZGlzdGluY2nDs24gZXMgZnVuZGFtZW50YWwuCgojIyBQcm9ibGVtYSBlbXByZXNhcmlhbAoKU2UgY29uY2VudHJhIGVuOgoKPiAqKsK/UXXDqSBkZWJlbW9zIGhhY2VyPyoqCgpFamVtcGxvczoKCi0gwr9kZWJlbW9zIHJlZHVjaXIgbGEgcHJpbWE/OwotIMK/ZGViZW1vcyBsYW56YXIgZWwgcHJvZHVjdG8/OwotIMK/ZGViZW1vcyBjYW1iaWFyIGVsIGNhbmFsPzsKLSDCv2RlYmVtb3MgbW9kaWZpY2FyIGxhIGNvYmVydHVyYT87Ci0gwr9kZWJlbW9zIGRpcmlnaXJub3MgYSBvdHJvIHNlZ21lbnRvPwoKIyMgUHJvYmxlbWEgZGUgaW52ZXN0aWdhY2nDs24KClNlIGNvbmNlbnRyYSBlbjoKCj4gKirCv1F1w6kgaW5mb3JtYWNpw7NuIG5lY2VzaXRhbW9zIHBhcmEgZGVjaWRpcj8qKgoKRWplbXBsbzoKCiMjIyBQcm9ibGVtYSBlbXByZXNhcmlhbAoKPiDCv0RlYmVtb3MgbW9kaWZpY2FyIGxhIHByaW1hIGRlIHJlbm92YWNpw7NuIGRlbCBzZWd1cm8gZGUgYXV0b23Ds3ZpbD8KCiMjIyBQcm9ibGVtYSBkZSBpbnZlc3RpZ2FjacOzbgoKPiBEZXRlcm1pbmFyIGxhIHJlbGFjacOzbiBlbnRyZSBsYSB2YXJpYWNpw7NuIGRlIGxhIHByaW1hIHkgbGEgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbiBkZSBsb3MgYXNlZ3VyYWRvcywgY29uc2lkZXJhbmRvIGNhcmFjdGVyw61zdGljYXMgZGVsIGNsaWVudGUsIGV4cGVyaWVuY2lhIGRlIHNpbmllc3Ryb3MgeSBwZXJjZXBjacOzbiBkZWwgc2VydmljaW8uCgpPYnNlcnZlIGVsIGNhbWJpby4KCkxhIGludmVzdGlnYWNpw7NuIG5vIGRlY2lkZSBhdXRvbcOhdGljYW1lbnRlIHNpIHNlIHJlZHVjZSBsYSBwcmltYS4KClByaW1lcm8gZ2VuZXJhIGluZm9ybWFjacOzbiBzb2JyZSBlbCBmZW7Ds21lbm8uCgotLS0KCiMgRGVtb3N0cmFjacOzbiBhY3R1YXJpYWw6IHRyYW5zZm9ybWFyIHVuYSBkZWNpc2nDs24gZW4gaW52ZXN0aWdhY2nDs24KCkNvbnNpZGVyZW1vcyBlbCBzaWd1aWVudGUgY2Fzby4KCjxkaXYgY2xhc3M9ImNhamEtYWN0dWFyaWFsIj4KCiMjIENhc286IEFzZWd1cmFkb3JhIEhvcml6b250ZQoKRHVyYW50ZSBsb3Mgw7psdGltb3MgZG9jZSBtZXNlcywgbGEgYXNlZ3VyYWRvcmEgaGEgb2JzZXJ2YWRvIHVuYSByZWR1Y2Npw7NuIGVuIGxhIHJlbm92YWNpw7NuIGRlIHDDs2xpemFzIGRlIGF1dG9tw7N2aWwuCgpMYSBnZXJlbmNpYSBjb21lcmNpYWwgcHJvcG9uZSBvdG9yZ2FyIHVuIGRlc2N1ZW50byBnZW5lcmFsIGRlbCAxMCUuCgpMYSBnZXJlbmNpYSB0w6ljbmljYSBhZHZpZXJ0ZSBxdWUgZXNhIHJlZHVjY2nDs24gcG9kcsOtYSBkZXRlcmlvcmFyIGVsIHJlc3VsdGFkbyB0w6ljbmljby4KCkFudGVzIGRlIHRvbWFyIGxhIGRlY2lzacOzbiBzZSBzb2xpY2l0YSB1bmEgaW52ZXN0aWdhY2nDs24uCgo8L2Rpdj4KCiMjIFBhc28gQS4gRGVjaXNpw7NuIGVtcHJlc2FyaWFsCgo+IMK/RGViZSBtb2RpZmljYXJzZSBsYSBlc3RyYXRlZ2lhIGRlIHByZWNpb3MgcGFyYSBtZWpvcmFyIGxhIHJlbm92YWNpw7NuPwoKIyMgUGFzbyBCLiBQcm9ibGVtYSBkZSBpbnZlc3RpZ2FjacOzbgoKPiBBbmFsaXphciBsb3MgZmFjdG9yZXMgYXNvY2lhZG9zIGNvbiBsYSBpbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NuIGRlIGxvcyBjbGllbnRlcyB5IGRldGVybWluYXIgbGEgaW1wb3J0YW5jaWEgcmVsYXRpdmEgZGUgbGEgdmFyaWFjacOzbiBkZSBsYSBwcmltYSBmcmVudGUgYSBvdHJvcyBmYWN0b3JlcyBkZSBleHBlcmllbmNpYSB5IHNlcnZpY2lvLgoKIyMgUGFzbyBDLiBWYXJpYWJsZXMgcG9zaWJsZXMKCi0gaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbjsKLSBwb3JjZW50YWplIGRlIGluY3JlbWVudG8gZGUgcHJpbWE7Ci0gc2F0aXNmYWNjacOzbjsKLSBleHBlcmllbmNpYSBkZSBzaW5pZXN0cm9zOwotIGluZ3Jlc287Ci0gYW50aWfDvGVkYWQ7Ci0gZWRhZDsKLSBjYW5hbDsKLSByZWdpw7NuLgoKIyMgUGFzbyBELiBJbmZvcm1hY2nDs24gcmVxdWVyaWRhCgpOZWNlc2l0YW1vcyBjb25vY2VyOgoKMS4gY3XDoW50byBhdW1lbnTDsyBsYSBwcmltYTsKMi4gcXXDqSB0YW4gc2F0aXNmZWNobyBlc3TDoSBlbCBjbGllbnRlOwozLiBzaSB0dXZvIHNpbmllc3Ryb3M7CjQuIGPDs21vIGZ1ZSBhdGVuZGlkbzsKNS4gc3UgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbjsKNi4gdmFyaWFibGVzIHNvY2lvZGVtb2dyw6FmaWNhczsKNy4gY2FyYWN0ZXLDrXN0aWNhcyBkZWwgcHJvZHVjdG8uCgotLS0KCiMgRWwgY29udGV4dG8gZGVsIHByb2JsZW1hCgpVbmEgZGVjaXNpw7NuIGVtcHJlc2FyaWFsIG5vIG9jdXJyZSBkZSBmb3JtYSBhaXNsYWRhLgoKQW50ZXMgZGUgZm9ybXVsYXIgbGEgaW52ZXN0aWdhY2nDs24gZGViZW1vcyBjb21wcmVuZGVyIGVsIGNvbnRleHRvLgoKRW50cmUgbG9zIGVsZW1lbnRvcyBxdWUgcHVlZGVuIGFuYWxpemFyc2Ugc2UgZW5jdWVudHJhbjoKCi0gaW5mb3JtYWNpw7NuIGhpc3TDs3JpY2E7Ci0gcHJvbsOzc3RpY29zOwotIG9iamV0aXZvcyBlbXByZXNhcmlhbGVzOwotIGNvbXBvcnRhbWllbnRvIGRlbCBjb25zdW1pZG9yOwotIHJlc3RyaWNjaW9uZXM7Ci0gcmVjdXJzb3MgZGlzcG9uaWJsZXM7Ci0gYW1iaWVudGUgZWNvbsOzbWljbzsKLSBhbWJpZW50ZSBsZWdhbDsKLSB0ZWNub2xvZ8OtYTsKLSBjb21wZXRlbmNpYS4KCi0tLQoKIyBFamVtcGxvIGRlIGNvbnRleHRvIGFjdHVhcmlhbAoKU3Vwb25nYW1vcyBxdWUgdW5hIGFzZWd1cmFkb3JhIG9ic2VydmEgbWF5b3IgY2FuY2VsYWNpw7NuLgoKQW50ZXMgZGUgY3VscGFyIGFsIHByZWNpbyBkZWJlbW9zIHJldmlzYXI6CgojIyMgRW50b3JubyBlY29uw7NtaWNvCgotIGluZmxhY2nDs247Ci0gaW5ncmVzbyBkaXNwb25pYmxlOwotIGRlc2VtcGxlbzsKLSB0YXNhcyBkZSBpbnRlcsOpcy4KCiMjIyBFbnRvcm5vIGNvbXBldGl0aXZvCgotIG51ZXZhcyBhc2VndXJhZG9yYXM7Ci0gcHJvbW9jaW9uZXM7Ci0gbnVldm9zIGNhbmFsZXMgZGlnaXRhbGVzOwotIGFncmVnYWRvcmVzIGRlIHNlZ3Vyb3MuCgojIyMgRW50b3JubyByZWd1bGF0b3JpbwoKLSBtb2RpZmljYWNpb25lcyBub3JtYXRpdmFzOwotIGNvYmVydHVyYXMgb2JsaWdhdG9yaWFzOwotIHByb3RlY2Npw7NuIGFsIGNvbnN1bWlkb3IuCgojIyMgRW50b3JubyBpbnRlcm5vCgotIGluY3JlbWVudG8gZGUgcHJpbWFzOwotIG1vZGlmaWNhY2lvbmVzIGVuIGRlZHVjaWJsZXM7Ci0gY2FtYmlvcyBlbiBzZXJ2aWNpbzsKLSBwcm9jZXNvcyBkZSByZWNsYW1hY2nDs24uCgojIyMgQ29tcG9ydGFtaWVudG8gZGVsIGNsaWVudGUKCi0gc2Vuc2liaWxpZGFkIGFsIHByZWNpbzsKLSBleHBlcmllbmNpYSBkZSBzaW5pZXN0cm87Ci0gdmFsb3JhY2nDs24gZGUgbWFyY2E7Ci0gcHJlZmVyZW5jaWFzIGRpZ2l0YWxlcy4KCi0tLQoKIyBEZSBvYmpldGl2b3MgYSBwcmVndW50YXMgZGUgaW52ZXN0aWdhY2nDs24KClVuYSB2ZXogZGVmaW5pZG8gZWwgcHJvYmxlbWEsIGRlYmVtb3MgZXN0cnVjdHVyYXIgZWwgZXN0dWRpby4KCiMjIE9iamV0aXZvIGdlbmVyYWwKCkRlc2NyaWJlIHF1w6kgcHJldGVuZGUgbG9ncmFyIGxhIGludmVzdGlnYWNpw7NuLgoKRWplbXBsbzoKCj4gQW5hbGl6YXIgbG9zIGZhY3RvcmVzIHJlbGFjaW9uYWRvcyBjb24gbGEgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbiBkZSBsb3MgY2xpZW50ZXMgZGUgc2VndXJvcyBkZSBhdXRvbcOzdmlsLgoKIyMgT2JqZXRpdm9zIGVzcGVjw61maWNvcwoKUG9kcsOtYW4gc2VyOgoKMS4gZGVzY3JpYmlyIGVsIHBlcmZpbCBkZSBsb3MgY2xpZW50ZXM7CjIuIGRldGVybWluYXIgbGEgZGlzdHJpYnVjacOzbiBkZSBsYSBpbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NuOwozLiBhbmFsaXphciBsYSByZWxhY2nDs24gZW50cmUgYXVtZW50byBkZSBwcmltYSBlIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs247CjQuIGNvbXBhcmFyIGxhIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs24gc2Vnw7puIGV4cGVyaWVuY2lhIGRlIHNpbmllc3RybzsKNS4gYW5hbGl6YXIgbGEgcmVsYWNpw7NuIGVudHJlIHNhdGlzZmFjY2nDs24gZSBpbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NuOwo2LiBpZGVudGlmaWNhciB2YXJpYWJsZXMgcG90ZW5jaWFsbWVudGUgw7p0aWxlcyBwYXJhIGV4cGxpY2FyIGxhIHJlbm92YWNpw7NuLgoKLS0tCgojIEPDs21vIGZvcm11bGFyIGJ1ZW5hcyBwcmVndW50YXMgZGUgaW52ZXN0aWdhY2nDs24KClVuYSBidWVuYSBwcmVndW50YSBkZWJlIHNlcjoKCi0gY2xhcmE7Ci0gZXNwZWPDrWZpY2E7Ci0gaW52ZXN0aWdhYmxlOwotIHZpbmN1bGFkYSBjb24gaW5mb3JtYWNpw7NuIG9ic2VydmFibGU7Ci0gcmVsZXZhbnRlIHBhcmEgbGEgZGVjaXNpw7NuLgoKRWplbXBsb3M6CgojIyMgUHJlZ3VudGEgMQoKPiDCv0N1w6FsIGVzIGVsIG5pdmVsIHByb21lZGlvIGRlIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs24/CgojIyMgUHJlZ3VudGEgMgoKPiDCv0xhIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs24gZGlmaWVyZSBlbnRyZSBjbGllbnRlcyBjb24geSBzaW4gc2luaWVzdHJvcyByZWNpZW50ZXM/CgojIyMgUHJlZ3VudGEgMwoKPiDCv0V4aXN0ZSBhc29jaWFjacOzbiBlbnRyZSBlbCBpbmNyZW1lbnRvIGRlIHByaW1hIHkgbGEgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbj8KCiMjIyBQcmVndW50YSA0Cgo+IMK/TGEgc2F0aXNmYWNjacOzbiBjb24gZWwgc2VydmljaW8gZXN0w6EgcmVsYWNpb25hZGEgY29uIGxhIHJlbm92YWNpw7NuPwoKIyMjIFByZWd1bnRhIDUKCj4gwr9RdcOpIGNhcmFjdGVyw61zdGljYXMgcHJlc2VudGFuIGxvcyBjbGllbnRlcyBjb24gYmFqYSBpbnRlbmNpw7NuIGRlIHJlbm92YXI/CgotLS0KCiMgUHJlZ3VudGFzIGTDqWJpbGVzIHkgcHJlZ3VudGFzIG1lam9yYWRhcwoKIyMgRWplbXBsbyAxCgpQcmVndW50YSBkw6liaWw6Cgo+IMK/UG9yIHF1w6kgbG9zIHNlZ3Vyb3Mgc29uIGNhcm9zPwoKUHJvYmxlbWFzOgoKLSBkZW1hc2lhZG8gYW1wbGlhOwotIHV0aWxpemEgdW4ganVpY2lvIGRlIHZhbG9yOwotIG5vIGRlZmluZSBzZWd1cm87Ci0gbm8gZGVmaW5lIHBvYmxhY2nDs247Ci0gbm8gZGVmaW5lIHF1w6kgc2lnbmlmaWNhIGNhcm8uCgpQcmVndW50YSBtZWpvcmFkYToKCj4gwr9Dw7NtbyBzZSByZWxhY2lvbmEgbGEgcGVyY2VwY2nDs24gZGVsIHByZWNpbyBkZSB1biBzZWd1cm8gZGUgYXV0b23Ds3ZpbCBjb24gbGEgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbiBlbnRyZSBjbGllbnRlcyBhY3R1YWxlcz8KCi0tLQoKIyMgRWplbXBsbyAyCgpQcmVndW50YSBkw6liaWw6Cgo+IMK/QSBsYXMgcGVyc29uYXMgbGVzIGd1c3RhbiBsb3Mgc2VndXJvcyBkZSB2aWRhPwoKUHJlZ3VudGEgbWVqb3JhZGE6Cgo+IMK/UXXDqSBhdHJpYnV0b3MgZGUgdW4gc2VndXJvIGRlIHZpZGEgc29uIHZhbG9yYWRvcyBwb3IgYWR1bHRvcyBkZSAyNSBhIDQ1IGHDsW9zIHF1ZSBhY3R1YWxtZW50ZSBubyBwb3NlZW4gY29iZXJ0dXJhIGluZGl2aWR1YWw/CgotLS0KCiMgTWFyY28gY29uY2VwdHVhbAoKTGFzIHByZWd1bnRhcyBkZSBpbnZlc3RpZ2FjacOzbiBubyBkZWJlcsOtYW4gYXBhcmVjZXIgZGUgbWFuZXJhIGFyYml0cmFyaWEuCgpOZWNlc2l0YW1vcyBlc3RhYmxlY2VyIHVuYSBleHBsaWNhY2nDs24gY29uY2VwdHVhbC4KClBvciBlamVtcGxvOgoKYGBgdGV4dApJbmNyZW1lbnRvIGRlIHByaW1hICDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggpTYXRpc2ZhY2Npw7NuIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUpAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCkV4cGVyaWVuY2lhIGRlIHNpbmllc3RybyDilIDilIDilIDilIDilIDilIDilKTilIDilIA+IEludGVuY2nDs24gZGUgcmVub3ZhY2nDs24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggpJbmdyZXNvIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUpAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCkFudGlnw7xlZGFkIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmApgYGAKCkVzdGUgZXNxdWVtYSByZXByZXNlbnRhIHVuYSBoaXDDs3Rlc2lzIGNvbmNlcHR1YWwuCgpUb2RhdsOtYSBubyBlcyB1biBtb2RlbG8gZXN0YWTDrXN0aWNvLgoKTm9zIGF5dWRhIGEgb3JnYW5pemFyIGVsIHByb2JsZW1hLgoKLS0tCgojIE1vZGVsbyB2ZXJiYWwsIGdyw6FmaWNvIHkgbWF0ZW3DoXRpY28KClVuYSBtaXNtYSBpZGVhIHB1ZWRlIGV4cHJlc2Fyc2UgZGUgZGlmZXJlbnRlcyBtYW5lcmFzLgoKIyMgTW9kZWxvIHZlcmJhbAoKPiBMYSBpbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NuIGRlIHVuYSBww7NsaXphIHB1ZWRlIGVzdGFyIHJlbGFjaW9uYWRhIGNvbiBsYSB2YXJpYWNpw7NuIGRlIGxhIHByaW1hLCBsYSBzYXRpc2ZhY2Npw7NuIGRlbCBjbGllbnRlLCBzdSBleHBlcmllbmNpYSBkZSBzaW5pZXN0cm9zIHkgY2FyYWN0ZXLDrXN0aWNhcyBpbmRpdmlkdWFsZXMuCgojIyBNb2RlbG8gZ3LDoWZpY28KCmBgYHRleHQKUHJlY2lvIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkAogICAgICAgICAgICAgICAgICAgICAgIOKUggpTZXJ2aWNpbyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilKQKICAgICAgICAgICAgICAgICAgICAgICDilJzilIDilIA+IFJlbm92YWNpw7NuClNpbmllc3Ryb3Mg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSkCiAgICAgICAgICAgICAgICAgICAgICAg4pSCCkNhcmFjdGVyw61zdGljYXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYCmBgYAoKIyMgTW9kZWxvIG1hdGVtw6F0aWNvIGNvbmNlcHR1YWwKClBvZGVtb3MgcmVwcmVzZW50YXJsbyBjb21vOgoKXFsKWSA9IGYoWF8xLFhfMixYXzMsXGxkb3RzLFhfaykKXF0KCmRvbmRlOgoKXFsKWSA9IFx0ZXh0e2ludGVuY2nDs24gZGUgcmVub3ZhY2nDs259ClxdCgp5LCBwb3IgZWplbXBsbywKClxbClhfMSA9IFx0ZXh0e2luY3JlbWVudG8gZGUgcHJpbWF9ClxdCgpcWwpYXzIgPSBcdGV4dHtzYXRpc2ZhY2Npw7NufQpcXQoKXFsKWF8zID0gXHRleHR7ZXhwZXJpZW5jaWEgZGUgc2luaWVzdHJvc30KXF0KClxbClhfNCA9IFx0ZXh0e2luZ3Jlc299ClxdCgoKClxbCllfaSA9ClxiZXRhXzAgKwpcYmV0YV8xIFhfezFpfSArClxiZXRhXzIgWF97Mml9ICsKXGJldGFfMyBYX3szaX0gKwpcdmFyZXBzaWxvbl9pClxdCgpQb3IgYWhvcmEgbG8gaW1wb3J0YW50ZSBubyBlcyBlc3RpbWFybG8uCgpMbyBpbXBvcnRhbnRlIGVzIGNvbXByZW5kZXIgcXVlIGVsIG1vZGVsbyBlc3RhZMOtc3RpY28gZGViZSBvcmlnaW5hcnNlIGVuIHVuYSBwcmVndW50YSB5IG5vIGFsIHJldsOpcy4KCi0tLQoKIyBIaXDDs3Rlc2lzIGRlIGludmVzdGlnYWNpw7NuCgpVbmEgaGlww7N0ZXNpcyBlc3RhYmxlY2UgdW5hIHJlbGFjacOzbiBlc3BlcmFkYSBlbnRyZSB2YXJpYWJsZXMuCgpQb3IgZWplbXBsbzoKClxbCkhfMToKXHRleHR7YSBtYXlvciBpbmNyZW1lbnRvIGRlIHByaW1hLCBtZW5vciBpbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NufQpcXQoKT3RyYSBoaXDDs3Rlc2lzOgoKXFsKSF8yOgpcdGV4dHthIG1heW9yIHNhdGlzZmFjY2nDs24sIG1heW9yIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs259ClxdCgpUYW1iacOpbjoKClxbCkhfMzoKXHRleHR7bGEgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbiBkaWZpZXJlIHNlZ8O6biBsYSBleHBlcmllbmNpYSBkZSBzaW5pZXN0cm9zfQpcXQoKPGRpdiBjbGFzcz0iY2FqYS1hbGVydGEiPgoKIyMjIEltcG9ydGFudGUKCkVuIGVzdGEgZXRhcGEgZXN0YW1vcyBmb3JtdWxhbmRvICoqaGlww7N0ZXNpcyBjb25jZXB0dWFsZXMqKi4KCk3DoXMgYWRlbGFudGUgYXByZW5kZXJlbW9zIGEgY29udmVydGlybGFzIGVuIGhpcMOzdGVzaXMgZXN0YWTDrXN0aWNhcy4KCk5vIHNvbiBleGFjdGFtZW50ZSBsbyBtaXNtby4KCjwvZGl2PgoKLS0tCgojIFZhcmlhYmxlcwoKVW5hIHZhcmlhYmxlIGVzIHVuYSBjYXJhY3RlcsOtc3RpY2EgcXVlIHB1ZWRlIHByZXNlbnRhciB2YXJpYWNpw7NuLgoKRWplbXBsb3MgYWN0dWFyaWFsZXM6CgotIGVkYWQ7Ci0gcHJpbWE7Ci0gc3VtYSBhc2VndXJhZGE7Ci0gZnJlY3VlbmNpYSBkZSBzaW5pZXN0cm9zOwotIHNldmVyaWRhZDsKLSBpbmdyZXNvOwotIHNhdGlzZmFjY2nDs247Ci0gaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbjsKLSBjYW5hbDsKLSByZWdpw7NuLgoKLS0tCgojIFRpcG9zIGluaWNpYWxlcyBkZSB2YXJpYWJsZXMKCkRlc2RlIHVuYSBwZXJzcGVjdGl2YSBwcsOhY3RpY2EgcG9kZW1vcyBjb21lbnphciBkaXN0aW5ndWllbmRvOgoKIyMjIFZhcmlhYmxlcyBudW3DqXJpY2FzCgpFamVtcGxvczoKCi0gZWRhZDsKLSBpbmdyZXNvOwotIHByaW1hOwotIG7Dum1lcm8gZGUgc2luaWVzdHJvcy4KCiMjIyBWYXJpYWJsZXMgY2F0ZWfDs3JpY2FzCgpFamVtcGxvczoKCi0gcmVnacOzbjsKLSBjYW5hbDsKLSBwcm9kdWN0bzsKLSBzZXhvOwotIHJlbm92YWNpw7NuLgoKIyMjIFZhcmlhYmxlcyBvcmRpbmFsZXMKCkVqZW1wbG86CgpJbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NuOgoKMS4gZGVmaW5pdGl2YW1lbnRlIG5vOwoyLiBwcm9iYWJsZW1lbnRlIG5vOwozLiBpbmRlY2lzbzsKNC4gcHJvYmFibGVtZW50ZSBzw607CjUuIGRlZmluaXRpdmFtZW50ZSBzw60uCgotLS0KCiMgRXNwZWNpZmljYWNpw7NuIGRlIGxhIGluZm9ybWFjacOzbiByZXF1ZXJpZGEKCkVzdGUgcGFzbyBvYmxpZ2EgYSB0cmFkdWNpciBudWVzdHJhcyBwcmVndW50YXMgZW4gaW5mb3JtYWNpw7NuIGNvbmNyZXRhLgoKU3Vwb25nYW1vcyBxdWUgcXVlcmVtb3MgcmVzcG9uZGVyOgoKPiDCv0VzdMOhIHJlbGFjaW9uYWRvIGVsIGF1bWVudG8gZGUgcHJpbWEgY29uIGxhIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs24/CgpOZWNlc2l0YW1vcyBhbCBtZW5vczoKCi0gcHJpbWEgYW50ZXJpb3I7Ci0gcHJpbWEgYWN0dWFsIG8gcG9yY2VudGFqZSBkZSBpbmNyZW1lbnRvOwotIGludGVuY2nDs24gZGUgcmVub3ZhY2nDs24uCgpQZXJvIHByb2JhYmxlbWVudGUgdGFtYmnDqW4gbmVjZXNpdGVtb3M6CgotIGVkYWQ7Ci0gaW5ncmVzbzsKLSB0aXBvIGRlIGNvYmVydHVyYTsKLSBleHBlcmllbmNpYSBkZSBzaW5pZXN0cm87Ci0gc2F0aXNmYWNjacOzbjsKLSBhbnRpZ8O8ZWRhZC4KCsK/UG9yIHF1w6k/CgpQb3JxdWUgdW4gZmVuw7NtZW5vIGRlIG1lcmNhZG8gcmFyYSB2ZXogZGVwZW5kZSBkZSB1bmEgc29sYSB2YXJpYWJsZS4KCi0tLQoKIyBEZWwgY29uY2VwdG8gYSBsb3MgZGF0b3MKCk9ic2VydmUgZXN0YSBzZWN1ZW5jaWE6Cgp8IE5pdmVsIHwgRWplbXBsbyB8CnwtLS18LS0tfAp8IERlY2lzacOzbiB8IMK/RGViZW1vcyBjYW1iaWFyIGxhIGVzdHJhdGVnaWEgZGUgcmVub3ZhY2nDs24/IHwKfCBQcm9ibGVtYSBkZSBpbnZlc3RpZ2FjacOzbiB8IEZhY3RvcmVzIHJlbGFjaW9uYWRvcyBjb24gbGEgcmVub3ZhY2nDs24gfAp8IFByZWd1bnRhIHwgwr9FbCBhdW1lbnRvIGRlIHByaW1hIGVzdMOhIHJlbGFjaW9uYWRvIGNvbiBsYSBpbnRlbmNpw7NuIGRlIHJlbm92YXI/IHwKfCBIaXDDs3Rlc2lzIHwgQSBtYXlvciBhdW1lbnRvLCBtZW5vciBpbnRlbmNpw7NuIHwKfCBDb25jZXB0byB8IFNlbnNpYmlsaWRhZCBhbCBwcmVjaW8gfAp8IFZhcmlhYmxlIHwgSW5jcmVtZW50byBwb3JjZW50dWFsIGRlIHByaW1hIHwKfCBEYXRvIHwgMTIuNSUgfAp8IEFuw6FsaXNpcyB8IENvbXBhcmFjacOzbi9jb3JyZWxhY2nDs24vbW9kZWxvIHwKfCBFdmlkZW5jaWEgfCBSZWxhY2nDs24gb2JzZXJ2YWRhIHwKfCBEZWNpc2nDs24gfCBVdGlsaXphciBldmlkZW5jaWEganVudG8gY29uIGNyaXRlcmlvcyB0w6ljbmljb3MgfAoKLS0tCgojIERpc2XDsW9zIGRlIGludmVzdGlnYWNpw7NuCgpVbmEgdmV6IHNhYmVtb3MgcXXDqSBuZWNlc2l0YW1vcyBpbnZlc3RpZ2FyIGRlYmVtb3MgZGVjaWRpciAqKmPDs21vIG9idGVuZXIgbGEgZXZpZGVuY2lhKiouCgpMb3MgdHJlcyBkaXNlw7FvcyBwcmluY2lwYWxlcyBxdWUgdXRpbGl6YXJlbW9zIHNvbjoKCjEuIGV4cGxvcmF0b3JpbzsKMi4gZGVzY3JpcHRpdm87CjMuIGNhdXNhbC4KCi0tLQoKIyBJbnZlc3RpZ2FjacOzbiBleHBsb3JhdG9yaWEKClNlIHV0aWxpemEgY3VhbmRvOgoKLSBlbCBwcm9ibGVtYSB0b2RhdsOtYSBubyBlc3TDoSBjbGFyYW1lbnRlIGRlZmluaWRvOwotIG5lY2VzaXRhbW9zIGNvbXByZW5kZXIgZWwgZmVuw7NtZW5vOwotIGV4aXN0ZW4gcG9jYXMgaGlww7N0ZXNpczsKLSBxdWVyZW1vcyBpZGVudGlmaWNhciBwb3NpYmxlcyB2YXJpYWJsZXM7Ci0gYnVzY2Ftb3MgZ2VuZXJhciBpZGVhcy4KCk3DqXRvZG9zIGNvbXVuZXM6CgotIGVudHJldmlzdGFzIGNvbiBleHBlcnRvczsKLSBhbsOhbGlzaXMgZGUgZGF0b3Mgc2VjdW5kYXJpb3M7Ci0gZ3J1cG9zIGZvY2FsZXM7Ci0gZW50cmV2aXN0YXMgZW4gcHJvZnVuZGlkYWQ7Ci0gYW7DoWxpc2lzIGV4cGxvcmF0b3JpbyBkZSBkYXRvcy4KCi0tLQoKIyMgRWplbXBsbyBhY3R1YXJpYWwKClVuYSBhc2VndXJhZG9yYSBxdWllcmUgc2FiZXIgcG9yIHF1w6kgbG9zIGrDs3ZlbmVzIG5vIGFkcXVpZXJlbiBzZWd1cm9zIGRlIHZpZGEuCgpUb2RhdsOtYSBubyBzYWJlIHNpIGVsIHByb2JsZW1hIGVzOgoKLSBwcmVjaW87Ci0gZmFsdGEgZGUgY29ub2NpbWllbnRvOwotIGJhamEgcGVyY2VwY2nDs24gZGUgcmllc2dvOwotIHByb2R1Y3RvcyBpbmFkZWN1YWRvczsKLSBjYW5hbGVzOwotIGRlc2NvbmZpYW56YS4KClVuYSBwcmltZXJhIGludmVzdGlnYWNpw7NuIGV4cGxvcmF0b3JpYSBwdWVkZSBheXVkYXIgYSBpZGVudGlmaWNhciBleHBsaWNhY2lvbmVzLgoKLS0tCgojIEludmVzdGlnYWNpw7NuIGRlc2NyaXB0aXZhCgpTZSB1dGlsaXphIHBhcmEgY3VhbnRpZmljYXIgY2FyYWN0ZXLDrXN0aWNhcyBkZWwgbWVyY2Fkby4KClJlc3BvbmRlIHByZWd1bnRhcyBjb21vOgoKLSDCv3F1acOpbj87Ci0gwr9xdcOpPzsKLSDCv2N1w6FudG8/OwotIMK/Y3XDoW5kbz87Ci0gwr9kw7NuZGU/OwotIMK/Y29uIHF1w6kgZnJlY3VlbmNpYT8KCkVqZW1wbG9zOgoKLSBwb3JjZW50YWplIGRlIGNsaWVudGVzIHF1ZSBkZXNlYSByZW5vdmFyOwotIGVkYWQgcHJvbWVkaW87Ci0gbml2ZWwgcHJvbWVkaW8gZGUgc2F0aXNmYWNjacOzbjsKLSBwYXJ0aWNpcGFjacOzbiBkZSBjYW5hbGVzOwotIGRpc3RyaWJ1Y2nDs24gZGVsIG1lcmNhZG8gcG9yIHJlZ2nDs247Ci0gcHJvcG9yY2nDs24gcXVlIGNvbm9jZSBkZXRlcm1pbmFkbyBwcm9kdWN0by4KCi0tLQoKIyBJbnZlc3RpZ2FjacOzbiBjYXVzYWwKCkJ1c2NhIGRldGVybWluYXIgc2kgY2FtYmlvcyBlbiB1bmEgdmFyaWFibGUgcHJvZHVjZW4gY2FtYmlvcyBlbiBvdHJhLgoKRWplbXBsbzoKClVuYSBhc2VndXJhZG9yYSBxdWllcmUgY29ub2NlciBzaSBtb2RpZmljYXIgbGEgZm9ybWEgZGUgcHJlc2VudGFyIHVuYSBjb3RpemFjacOzbiBhdW1lbnRhIGxhIGFjZXB0YWNpw7NuLgoKUG9kcsOtYW1vcyBjb21wYXJhcjoKCi0gZ3J1cG8gQTogY290aXphY2nDs24gdHJhZGljaW9uYWw7Ci0gZ3J1cG8gQjogbnVldmEgcHJlc2VudGFjacOzbi4KClNpIGxhIGFzaWduYWNpw7NuIHkgZWwgZGlzZcOxbyBzb24gYWRlY3VhZG9zLCBwb2RlbW9zIGFwcm94aW1hcm5vcyBhIHVuYSBpbmZlcmVuY2lhIGNhdXNhbC4KCi0tLQoKIyBFeHBsb3JhdG9yaW8sIGRlc2NyaXB0aXZvIG8gY2F1c2FsCgpWZWFtb3MgYWxndW5vcyBlc2NlbmFyaW9zLgoKIyMjIFNpdHVhY2nDs24gQQoKPiBObyBzYWJlbW9zIHBvciBxdcOpIGxvcyBjbGllbnRlcyBlc3TDoW4gY2FuY2VsYW5kby4KCkRpc2XDsW8gcHJpbmNpcGFsOgoKKipFeHBsb3JhdG9yaW8uKioKCiMjIyBTaXR1YWNpw7NuIEIKCj4gUXVlcmVtb3MgY29ub2NlciBxdcOpIHBvcmNlbnRhamUgZGUgY2xpZW50ZXMgY29uc2lkZXJhIGNhcmEgbGEgcHJpbWEuCgpEaXNlw7FvIHByaW5jaXBhbDoKCioqRGVzY3JpcHRpdm8uKioKCiMjIyBTaXR1YWNpw7NuIEMKCj4gUXVlcmVtb3MgY29ub2NlciBzaSBvZnJlY2VyIHVuIGRlc2N1ZW50byBhdW1lbnRhIGxhIHJlbm92YWNpw7NuLgoKRGlzZcOxbyBwcmluY2lwYWw6CgoqKkNhdXNhbC4qKgoKLS0tCgotLS0KCiMgRGlzZcOxb3MgdHJhbnN2ZXJzYWxlcyB5IGxvbmdpdHVkaW5hbGVzCgpPdHJhIGRlY2lzacOzbiBpbXBvcnRhbnRlIGVzIGVsIG1vbWVudG8gZW4gcXVlIG9ic2VydmFtb3MgYSBsb3MgaW5kaXZpZHVvcy4KCiMjIEVzdHVkaW8gdHJhbnN2ZXJzYWwKCk9ic2VydmFtb3MgdW5hIHBvYmxhY2nDs24gZW4gdW4gcHVudG8gbyBwZXJpb2RvIGVzcGVjw61maWNvLgoKRWplbXBsbzoKCkVuY3Vlc3RhIGRlIHNhdGlzZmFjY2nDs24gcmVhbGl6YWRhIGR1cmFudGUgb2N0dWJyZSBkZSAyMDI2LgoKUG9kZW1vcyBwZW5zYXIgZW4gdW5hIGZvdG9ncmFmw61hLgoKIyMgRXN0dWRpbyBsb25naXR1ZGluYWwKCk9ic2VydmFtb3MgbGFzIG1pc21hcyB1bmlkYWRlcyByZXBldGlkYW1lbnRlLgoKRWplbXBsbzoKClNlZ3VpbW9zIGR1cmFudGUgMjQgbWVzZXMgYSBsb3MgbWlzbW9zIGFzZWd1cmFkb3MgeSByZWdpc3RyYW1vczoKCi0gcHJpbWE7Ci0gc2luaWVzdHJvczsKLSBzYXRpc2ZhY2Npw7NuOwotIHJlbm92YWNpw7NuLgoKUG9kZW1vcyBwZW5zYXIgZW4gdW5hIHBlbMOtY3VsYS4KCi0tLQoKIyBFamVtcGxvIGFjdHVhcmlhbAoKU3Vwb25nYW1vcyBxdWUgcXVlcmVtb3MgZXN0dWRpYXIgYWJhbmRvbm8uCgojIyMgRGlzZcOxbyB0cmFuc3ZlcnNhbAoKYGBgdGV4dApDbGllbnRlICAgICAgIE9jdHVicmUgMjAyNgpBICAgICAgICAgICAgIFJlbnVldmEKQiAgICAgICAgICAgICBObyByZW51ZXZhCkMgICAgICAgICAgICAgUmVudWV2YQpgYGAKCiMjIyBEaXNlw7FvIGxvbmdpdHVkaW5hbAoKYGBgdGV4dApDbGllbnRlICAgICAyMDI0ICAgICAyMDI1ICAgICAyMDI2CkEgICAgICAgICAgIFPDrSAgICAgICBTw60gICAgICAgU8OtCkIgICAgICAgICAgIFPDrSAgICAgICBTw60gICAgICAgTm8KQyAgICAgICAgICAgU8OtICAgICAgIE5vICAgICAgIC0KYGBgCgpFbCBzZWd1bmRvIGRpc2XDsW8gcGVybWl0ZSBlc3R1ZGlhciB0cmF5ZWN0b3JpYXMuCgotLS0KCiMgRnVlbnRlcyBkZSBlcnJvcgoKVG9kYSBpbnZlc3RpZ2FjacOzbiBjb250aWVuZSBlcnJvci4KCkVsIG9iamV0aXZvIG5vIGVzIGltYWdpbmFyIHF1ZSBwb2RlbW9zIGVsaW1pbmFybG8gcG9yIGNvbXBsZXRvLgoKRWwgb2JqZXRpdm8gZXM6CgotIGlkZW50aWZpY2FybG87Ci0gbWluaW1pemFybG87Ci0gY3VhbnRpZmljYXJsbyBjdWFuZG8gc2VhIHBvc2libGU7Ci0gcmVjb25vY2VyIHN1cyBpbXBsaWNhY2lvbmVzLgoKLS0tCgojIyBFcnJvciBkZSBtdWVzdHJlbwoKU3VyZ2UgcG9ycXVlIGVzdHVkaWFtb3MgdW5hIG11ZXN0cmEgeSBubyBuZWNlc2FyaWFtZW50ZSB0b2RhIGxhIHBvYmxhY2nDs24uCgpTdXBvbmdhbW9zIHVuYSBwb2JsYWNpw7NuIGNvbiBlZGFkIHByb21lZGlvIGNvbm9jaWRhLgoKYGBge3J9CnNldC5zZWVkKDIwMjYpCgpwb2JsYWNpb25fZWRhZCA8LSByb3VuZCgKICBybm9ybSgKICAgIG4gPSAxMDAwMDAsCiAgICBtZWFuID0gNDIsCiAgICBzZCA9IDEzCiAgKQopCgptZWFuKHBvYmxhY2lvbl9lZGFkKQpgYGAKClRvbWVtb3MgZGlmZXJlbnRlcyBtdWVzdHJhcyBkZSAxMDAgcGVyc29uYXMuCgpgYGB7cn0Kc2V0LnNlZWQoMjAyNikKCm1lZGlhc19tdWVzdHJhbGVzIDwtIHJlcGxpY2F0ZSgKICA1MDAsCiAgbWVhbigKICAgIHNhbXBsZSgKICAgICAgcG9ibGFjaW9uX2VkYWQsCiAgICAgIHNpemUgPSAxMDAKICAgICkKICApCikKCnN1bW1hcnkobWVkaWFzX211ZXN0cmFsZXMpCmBgYAoKVmlzdWFsaWNlbW9zLgoKYGBge3J9CmRhdGEuZnJhbWUoCiAgbWVkaWEgPSBtZWRpYXNfbXVlc3RyYWxlcwopICU+JQogIGdncGxvdCgKICAgIGFlcyh4ID0gbWVkaWEpCiAgKSArCiAgZ2VvbV9oaXN0b2dyYW0oCiAgICBiaW5zID0gMzAsCiAgICBjb2xvciA9ICJ3aGl0ZSIKICApICsKICBnZW9tX3ZsaW5lKAogICAgeGludGVyY2VwdCA9IG1lYW4ocG9ibGFjaW9uX2VkYWQpLAogICAgbGluZXR5cGUgPSAiZGFzaGVkIiwKICAgIGxpbmV3aWR0aCA9IDEKICApICsKICBsYWJzKAogICAgdGl0bGUgPSAiVmFyaWFiaWxpZGFkIGVudHJlIG11ZXN0cmFzIiwKICAgIHN1YnRpdGxlID0gIjUwMCBtdWVzdHJhcyBhbGVhdG9yaWFzIGRlIHRhbWHDsW8gMTAwIiwKICAgIHggPSAiRWRhZCBwcm9tZWRpbyBkZSBsYSBtdWVzdHJhIiwKICAgIHkgPSAiRnJlY3VlbmNpYSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgpPYnNlcnZlIHF1ZSBkaWZlcmVudGVzIG11ZXN0cmFzIGdlbmVyYW4gZGlmZXJlbnRlcyBlc3RpbWFjaW9uZXMuCgpFc28gZXMgcGFydGUgZGUgbGEgdmFyaWFiaWxpZGFkIG11ZXN0cmFsLgoKTcOhcyBhZGVsYW50ZSBlc3R1ZGlhcmVtb3MgZm9ybWFsbWVudGU6CgotIGVycm9yIGVzdMOhbmRhcjsKLSBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YTsKLSB0YW1hw7FvIGRlIG11ZXN0cmEuCgotLS0KCiMgRXJyb3Igbm8gYXRyaWJ1aWJsZSBhbCBtdWVzdHJlbwoKVGFtYmnDqW4gcHVlZGVuIGFwYXJlY2VyIGVycm9yZXMgcG9yOgoKLSBtYWxhIGRlZmluaWNpw7NuIGRlIHBvYmxhY2nDs247Ci0gcHJlZ3VudGFzIGFtYmlndWFzOwotIGZhbHRhIGRlIHJlc3B1ZXN0YTsKLSBlcnJvcmVzIGRlIHJlZ2lzdHJvOwotIGVycm9yZXMgZGUgY29kaWZpY2FjacOzbjsKLSBmcmF1ZGU7Ci0gZGF0b3MgZmFsdGFudGVzOwotIGVycm9yZXMgZGUgYW7DoWxpc2lzOwotIGluc3RydW1lbnRvcyBkZWZpY2llbnRlcy4KCjxkaXYgY2xhc3M9ImNhamEtYWxlcnRhIj4KCiMjIyBQdW50byBmdW5kYW1lbnRhbAoKQXVtZW50YXIgZWwgdGFtYcOxbyBkZSBsYSBtdWVzdHJhIHB1ZWRlIHJlZHVjaXIgZWwgZXJyb3IgbXVlc3RyYWwuCgpQZXJvIHVuYSBtdWVzdHJhIGdpZ2FudGVzY2EgKipubyBjb3JyaWdlIHVuIGN1ZXN0aW9uYXJpbyBtYWwgZGlzZcOxYWRvKiouCgo8L2Rpdj4KCi0tLQoKIyBJbnZlc3RpZ2FjacOzbiBkZSBtZXJjYWRvcywgU0lNIHkgYXBveW8gYSBkZWNpc2lvbmVzCgpMYXMgb3JnYW5pemFjaW9uZXMgcHJvZHVjZW4gaW5mb3JtYWNpw7NuIGNvbnRpbnVhbWVudGUuCgpQb3IgZWplbXBsbywgdW5hIGFzZWd1cmFkb3JhIHB1ZWRlIGRpc3BvbmVyIGRlOgoKLSBww7NsaXphczsKLSBwcmltYXM7Ci0gY2FuY2VsYWNpb25lczsKLSByZWNsYW1hY2lvbmVzOwotIGNhbmFsZXM7Ci0gYWdlbnRlczsKLSBjbGllbnRlczsKLSBjYW1wYcOxYXM7Ci0gY290aXphY2lvbmVzLgoKCmBgYHRleHQKQmFzZXMgaW50ZXJuYXMKICAgICAgKwpEYXRvcyBleHRlcm5vcwogICAgICArCkludmVzdGlnYWNpb25lcyBlc3BlY8OtZmljYXMKICAgICAg4oaTClByZXBhcmFjacOzbgogICAgICDihpMKQW7DoWxpc2lzCiAgICAgIOKGkwpWaXN1YWxpemFjacOzbgogICAgICDihpMKSW5mb3JtYWNpw7NuCiAgICAgIOKGkwpEZWNpc2nDs24KYGBgCgotLS0KCiMgQ29uc3RydWNjacOzbiBkZWwgY2FzbyBkZSB0cmFiYWpvIGRlbCBjdXJzbwoKQ3JlYXJlbW9zIHVuYSBiYXNlIHNpbXVsYWRhIGRlIGNsaWVudGVzIGRlIHNlZ3Vyb3MuCgpgYGB7cn0Kc2V0LnNlZWQoMjAyNikKCm4gPC0gMTIwMAoKbWVyY2Fkb19zZWd1cm9zIDwtIGRhdGEuZnJhbWUoCiAgaWQgPSAxOm4sCiAgCiAgZWRhZCA9IHJvdW5kKAogICAgcG1pbigKICAgICAgcG1heCgKICAgICAgICBybm9ybShuLCA0MiwgMTIpLAogICAgICAgIDE4CiAgICAgICksCiAgICAgIDc1CiAgICApCiAgKSwKICAKICBpbmdyZXNvX21lbnN1YWwgPSByb3VuZCgKICAgIHJsbm9ybSgKICAgICAgbiwKICAgICAgbG9nKDkwMDApLAogICAgICAwLjU1CiAgICApLAogICAgMAogICksCiAgCiAgcmVnaW9uID0gc2FtcGxlKAogICAgYygKICAgICAgIk1ldHJvcG9saXRhbmEiLAogICAgICAiTm9ydGUiLAogICAgICAiT2NjaWRlbnRlIiwKICAgICAgIk9yaWVudGUiLAogICAgICAiU3VyIgogICAgKSwKICAgIG4sCiAgICByZXBsYWNlID0gVFJVRSwKICAgIHByb2IgPSBjKAogICAgICAwLjQyLAogICAgICAwLjEyLAogICAgICAwLjE4LAogICAgICAwLjE1LAogICAgICAwLjEzCiAgICApCiAgKSwKICAKICBjYW5hbCA9IHNhbXBsZSgKICAgIGMoCiAgICAgICJBZ2VudGUiLAogICAgICAiRGlnaXRhbCIsCiAgICAgICJTdWN1cnNhbCIsCiAgICAgICJCYW5jYXNlZ3Vyb3MiCiAgICApLAogICAgbiwKICAgIHJlcGxhY2UgPSBUUlVFLAogICAgcHJvYiA9IGMoCiAgICAgIDAuMzUsCiAgICAgIDAuMzAsCiAgICAgIDAuMjAsCiAgICAgIDAuMTUKICAgICkKICApLAogIAogIGFudGlndWVkYWQgPSBwbWF4KAogICAgMSwKICAgIHJvdW5kKAogICAgICByZ2FtbWEoCiAgICAgICAgbiwKICAgICAgICBzaGFwZSA9IDIuNSwKICAgICAgICBzY2FsZSA9IDIKICAgICAgKQogICAgKQogICksCiAgCiAgc2luaWVzdHJvc18yYSA9IHJwb2lzKAogICAgbiwKICAgIGxhbWJkYSA9IDAuMzUKICApLAogIAogIHNhdGlzZmFjY2lvbiA9IHNhbXBsZSgKICAgIDE6MTAsCiAgICBuLAogICAgcmVwbGFjZSA9IFRSVUUsCiAgICBwcm9iID0gYygKICAgICAgMC4wMiwKICAgICAgMC4wMywKICAgICAgMC4wNCwKICAgICAgMC4wNiwKICAgICAgMC4xMCwKICAgICAgMC4xMywKICAgICAgMC4xOCwKICAgICAgMC4xOSwKICAgICAgMC4xNSwKICAgICAgMC4xMAogICAgKQogICksCiAgCiAgaW5jcmVtZW50b19wcmltYSA9IHJvdW5kKAogICAgcG1heCgKICAgICAgcm5vcm0oCiAgICAgICAgbiwKICAgICAgICBtZWFuID0gOCwKICAgICAgICBzZCA9IDYKICAgICAgKSwKICAgICAgLTUKICAgICksCiAgICAxCiAgKQopCmBgYAoKQWhvcmEgY29uc3RydWlyZW1vcyB1bmEgaW50ZW5jacOzbiBkZSByZW5vdmFjacOzbiBzaW11bGFkYS4KCkxhIGNvbnN0cnVpcmVtb3MgZGUgbWFuZXJhIHF1ZSBkZXBlbmRhIHBhcmNpYWxtZW50ZSBkZToKCi0gc2F0aXNmYWNjacOzbjsKLSBpbmNyZW1lbnRvIGRlIHByaW1hOwotIGFudGlnw7xlZGFkOwotIGV4cGVyaWVuY2lhIGRlIHNpbmllc3Ryby4KCmBgYHtyfQppbmRpY2VfcmVub3ZhY2lvbiA8LQogIDAuNDUgKiBtZXJjYWRvX3NlZ3Vyb3Mkc2F0aXNmYWNjaW9uIC0KICAwLjEwICogbWVyY2Fkb19zZWd1cm9zJGluY3JlbWVudG9fcHJpbWEgKwogIDAuMDUgKiBtZXJjYWRvX3NlZ3Vyb3MkYW50aWd1ZWRhZCAtCiAgMC4yMCAqIG1lcmNhZG9fc2VndXJvcyRzaW5pZXN0cm9zXzJhICsKICBybm9ybShuLCAwLCAxLjUpCgptZXJjYWRvX3NlZ3Vyb3MkaW50ZW5jaW9uX3Jlbm92YXIgPC0gY3V0KAogIGluZGljZV9yZW5vdmFjaW9uLAogIGJyZWFrcyA9IHF1YW50aWxlKAogICAgaW5kaWNlX3Jlbm92YWNpb24sCiAgICBwcm9icyA9IHNlcSgwLCAxLCAwLjIpCiAgKSwKICBpbmNsdWRlLmxvd2VzdCA9IFRSVUUsCiAgbGFiZWxzID0gMTo1CikKCm1lcmNhZG9fc2VndXJvcyRpbnRlbmNpb25fcmVub3ZhciA8LSBhcy5pbnRlZ2VyKAogIGFzLmNoYXJhY3RlcigKICAgIG1lcmNhZG9fc2VndXJvcyRpbnRlbmNpb25fcmVub3ZhcgogICkKKQpgYGAKCkNyZWFyZW1vcyB0YW1iacOpbiB1bmEgdmFyaWFibGUgYmluYXJpYSBkZSByZW5vdmFjacOzbiBvYnNlcnZhZGEuCgpgYGB7cn0KcHJvYl9yZW5vdmFyIDwtIHBsb2dpcygKICAtMC41ICsKICAwLjM1ICogbWVyY2Fkb19zZWd1cm9zJHNhdGlzZmFjY2lvbiAtCiAgMC4wOSAqIG1lcmNhZG9fc2VndXJvcyRpbmNyZW1lbnRvX3ByaW1hICsKICAwLjA0ICogbWVyY2Fkb19zZWd1cm9zJGFudGlndWVkYWQgLQogIDAuMTUgKiBtZXJjYWRvX3NlZ3Vyb3Mkc2luaWVzdHJvc18yYQopCgptZXJjYWRvX3NlZ3Vyb3MkcmVudWV2YSA8LSByYmlub20oCiAgbiwKICBzaXplID0gMSwKICBwcm9iID0gcHJvYl9yZW5vdmFyCikKCm1lcmNhZG9fc2VndXJvcyRyZW51ZXZhIDwtIGlmZWxzZSgKICBtZXJjYWRvX3NlZ3Vyb3MkcmVudWV2YSA9PSAxLAogICJTw60iLAogICJObyIKKQpgYGAKCkd1YXJkZW1vcyBsYSBiYXNlIHBhcmEgdXRpbGl6YXJsYSBwb3N0ZXJpb3JtZW50ZS4KCmBgYHtyfQp3cml0ZS5jc3YoCiAgbWVyY2Fkb19zZWd1cm9zLAogICJtZXJjYWRvX3NlZ3Vyb3NfY2xhc2UxLmNzdiIsCiAgcm93Lm5hbWVzID0gRkFMU0UKKQpgYGAKCi0tLQoKIyBJbnNwZWNjacOzbiBpbmljaWFsCgpTdXBvbmdhbW9zIHF1ZSByZWNpYmltb3MgbGEgYmFzZSB5IHRvZGF2w61hIG5vIGNvbm9jZW1vcyBzdSBjb250ZW5pZG8uCgpMYSBwcmltZXJhIGluc3RydWNjacOzbiBzZXLDrWE6CgpgYGB7cn0KaGVhZChtZXJjYWRvX3NlZ3Vyb3MpCmBgYAoKTHVlZ286CgpgYGB7cn0Kc3RyKG1lcmNhZG9fc2VndXJvcykKYGBgCgpEaW1lbnNpb25lczoKCmBgYHtyfQpkaW0obWVyY2Fkb19zZWd1cm9zKQpgYGAKCk5vbWJyZXM6CgpgYGB7cn0KbmFtZXMobWVyY2Fkb19zZWd1cm9zKQpgYGAKClJlc3VtZW46CgpgYGB7cn0Kc3VtbWFyeShtZXJjYWRvX3NlZ3Vyb3MpCmBgYAoKLS0tCgojIERpY2Npb25hcmlvIGluaWNpYWwgZGUgdmFyaWFibGVzCgpgYGB7cn0KZGljY2lvbmFyaW8gPC0gZGF0YS5mcmFtZSgKICBWYXJpYWJsZSA9IG5hbWVzKG1lcmNhZG9fc2VndXJvcyksCiAgRGVzY3JpcGNpb24gPSBjKAogICAgIklkZW50aWZpY2Fkb3IiLAogICAgIkVkYWQgZGVsIGNsaWVudGUiLAogICAgIkluZ3Jlc28gbWVuc3VhbCBlc3RpbWFkbyIsCiAgICAiUmVnacOzbiIsCiAgICAiQ2FuYWwgcHJpbmNpcGFsIiwKICAgICJBbnRpZ8O8ZWRhZCBjb21vIGNsaWVudGUiLAogICAgIk7Dum1lcm8gZGUgc2luaWVzdHJvcyBlbiBsb3Mgw7psdGltb3MgZG9zIGHDsW9zIiwKICAgICJTYXRpc2ZhY2Npw7NuIGRlIDEgYSAxMCIsCiAgICAiSW5jcmVtZW50byBwb3JjZW50dWFsIGRlIGxhIHByaW1hIiwKICAgICJJbnRlbmNpw7NuIGRlIHJlbm92YWNpw7NuIGRlIDEgYSA1IiwKICAgICJSZW5vdmFjacOzbiBvYnNlcnZhZGEiCiAgKQopCgprbml0cjo6a2FibGUoCiAgZGljY2lvbmFyaW8sCiAgY2FwdGlvbiA9ICJEaWNjaW9uYXJpbyBpbmljaWFsIGRlIHZhcmlhYmxlcyIKKQpgYGAKCi0tLQoKIyBQcmVndW50YSBleHBsb3JhdG9yaWEgMTogwr9RdWnDqW5lcyBpbnRlZ3JhbiBlbCBtZXJjYWRvPwoKVmVhbW9zIGxhIGVkYWQuCgpgYGB7cn0Kc3VtbWFyeSgKICBtZXJjYWRvX3NlZ3Vyb3MkZWRhZAopCmBgYAoKVmlzdWFsaWNlbW9zLgoKYGBge3J9CmdncGxvdCgKICBtZXJjYWRvX3NlZ3Vyb3MsCiAgYWVzKHggPSBlZGFkKQopICsKICBnZW9tX2hpc3RvZ3JhbSgKICAgIGJpbnMgPSAyNSwKICAgIGNvbG9yID0gIndoaXRlIgogICkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGRlIGVkYWQiLAogICAgeCA9ICJFZGFkIiwKICAgIHkgPSAiTsO6bWVybyBkZSBjbGllbnRlcyIKICApICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgpFc3RhIGdyw6FmaWNhIHJlc3BvbmRlIHVuYSBwcmVndW50YSAqKmRlc2NyaXB0aXZhKiouCgpObyBleHBsaWNhIHBvciBxdcOpIG9jdXJyZSBhbGdvLgoKLS0tCgojIFByZWd1bnRhIGV4cGxvcmF0b3JpYSAyOiDCv0TDs25kZSBlc3TDoW4gbG9zIGNsaWVudGVzPwoKYGBge3J9CnRhYmxhX3JlZ2lvbiA8LSB0YWJsZSgKICBtZXJjYWRvX3NlZ3Vyb3MkcmVnaW9uCikKCnRhYmxhX3JlZ2lvbgpgYGAKClBvcmNlbnRhamVzOgoKYGBge3J9CnJvdW5kKAogIHByb3AudGFibGUodGFibGFfcmVnaW9uKSAqIDEwMCwKICAxCikKYGBgCgpHcsOhZmljbzoKCmBgYHtyfQptZXJjYWRvX3NlZ3Vyb3MgJT4lCiAgY291bnQocmVnaW9uKSAlPiUKICBtdXRhdGUoCiAgICBwb3JjZW50YWplID0gbiAvIHN1bShuKQogICkgJT4lCiAgZ2dwbG90KAogICAgYWVzKAogICAgICB4ID0gcmVvcmRlcihyZWdpb24sIG4pLAogICAgICB5ID0gcG9yY2VudGFqZQogICAgKQogICkgKwogIGdlb21fY29sKCkgKwogIGNvb3JkX2ZsaXAoKSArCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50CiAgKSArCiAgbGFicygKICAgIHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gdGVycml0b3JpYWwgZGUgY2xpZW50ZXMiLAogICAgeCA9IE5VTEwsCiAgICB5ID0gIlBvcmNlbnRhamUiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKLS0tCgojIFByZWd1bnRhIGV4cGxvcmF0b3JpYSAzOiDCv0PDs21vIGVzIGxhIHNhdGlzZmFjY2nDs24/CgpgYGB7cn0Kc3VtbWFyeSgKICBtZXJjYWRvX3NlZ3Vyb3Mkc2F0aXNmYWNjaW9uCikKYGBgCgpEaXN0cmlidWNpw7NuOgoKYGBge3J9Cm1lcmNhZG9fc2VndXJvcyAlPiUKICBjb3VudChzYXRpc2ZhY2Npb24pICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGZhY3RvcihzYXRpc2ZhY2Npb24pLAogICAgICB5ID0gbgogICAgKQogICkgKwogIGdlb21fY29sKCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJTYXRpc2ZhY2Npw7NuIGRlIGxvcyBjbGllbnRlcyIsCiAgICB4ID0gIlNhdGlzZmFjY2nDs24iLAogICAgeSA9ICJOw7ptZXJvIGRlIGNsaWVudGVzIgogICkgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCi0tLQoKIyBQcmVndW50YSBleHBsb3JhdG9yaWEgNDogwr9RdcOpIHBvcmNlbnRhamUgcmVudWV2YT8KCmBgYHtyfQp0YWJsZSgKICBtZXJjYWRvX3NlZ3Vyb3MkcmVudWV2YQopCmBgYAoKYGBge3J9CnJvdW5kKAogIHByb3AudGFibGUoCiAgICB0YWJsZSgKICAgICAgbWVyY2Fkb19zZWd1cm9zJHJlbnVldmEKICAgICkKICApICogMTAwLAogIDEKKQpgYGAKCi0tLQoKIyBEZWwgYW7DoWxpc2lzIGRlc2NyaXB0aXZvIGEgbnVldmFzIHByZWd1bnRhcwoKU3Vwb25nYW1vcyBxdWUgb2JzZXJ2YW1vcyB1bmEgdGFzYSBjb25zaWRlcmFibGUgZGUgbm8gcmVub3ZhY2nDs24uCgpMYSBzaWd1aWVudGUgcHJlZ3VudGEgbm8gZGViZXLDrWEgc2VyIGF1dG9tw6F0aWNhbWVudGU6Cgo+IMK/Q8OzbW8gcHVlZG8gY29uc3RydWlyIHVuYSByZWdyZXNpw7NuPwoKTGEgcHJlZ3VudGEgY29ycmVjdGEgZXM6Cgo+IMK/UXXDqSBoaXDDs3Rlc2lzIHJhem9uYWJsZXMgcG9kcsOtYW4gZXhwbGljYXIgbGEgbm8gcmVub3ZhY2nDs24/CgpQb2Ryw61hbW9zIGV4cGxvcmFyOgoKLSBpbmNyZW1lbnRvIGRlIHByaW1hOwotIHNhdGlzZmFjY2nDs247Ci0gc2luaWVzdHJvczsKLSBhbnRpZ8O8ZWRhZDsKLSBjYW5hbDsKLSByZWdpw7NuLgoKLS0tCgojIFByaW1hIHkgcmVub3ZhY2nDs24KCkNhbGN1bGVtb3MgZWwgaW5jcmVtZW50byBwcm9tZWRpbyBzZWfDum4gcmVub3ZhY2nDs24uCgpgYGB7cn0KbWVyY2Fkb19zZWd1cm9zICU+JQogIGdyb3VwX2J5KHJlbnVldmEpICU+JQogIHN1bW1hcmlzZSgKICAgIG4gPSBuKCksCiAgICBpbmNyZW1lbnRvX3Byb21lZGlvID0gbWVhbihpbmNyZW1lbnRvX3ByaW1hKSwKICAgIG1lZGlhbmFfaW5jcmVtZW50byA9IG1lZGlhbihpbmNyZW1lbnRvX3ByaW1hKQogICkKYGBgCgpWaXN1YWxpY2Vtb3MuCgpgYGB7cn0KZ2dwbG90KAogIG1lcmNhZG9fc2VndXJvcywKICBhZXMoCiAgICB4ID0gcmVudWV2YSwKICAgIHkgPSBpbmNyZW1lbnRvX3ByaW1hCiAgKQopICsKICBnZW9tX2JveHBsb3QoKSArCiAgbGFicygKICAgIHRpdGxlID0gIkluY3JlbWVudG8gZGUgcHJpbWEgc2Vnw7puIHJlbm92YWNpw7NuIiwKICAgIHggPSAiUmVub3ZhY2nDs24iLAogICAgeSA9ICJJbmNyZW1lbnRvIGRlIHByaW1hICglKSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgo8ZGl2IGNsYXNzPSJjYWphLXByZWd1bnRhIj4KCsK/UXXDqSBwb2RlbW9zIGRlY2lyPwoKUG9kZW1vcyBkZWNpciBxdWUgZXhpc3RlbiBkaWZlcmVuY2lhcyBkZXNjcmlwdGl2YXMgZW50cmUgbG9zIGdydXBvcy4KClRvZGF2w61hIG5vIHBvZGVtb3MgZGVjaXIgcXVlOgoKPiDigJxlbCBpbmNyZW1lbnRvIGRlIHByaW1hIGNhdXNhIGxhIG5vIHJlbm92YWNpw7Nu4oCdLgoKwr9Qb3IgcXXDqT8KClBvcnF1ZSBubyBoZW1vcyBjb250cm9sYWRvOgoKLSBzYXRpc2ZhY2Npw7NuOwotIGFudGlnw7xlZGFkOwotIHNpbmllc3Ryb3M7Ci0gaW5ncmVzbzsKLSBwb3NpYmxlcyB2YXJpYWJsZXMgb21pdGlkYXMuCgo8L2Rpdj4KCi0tLQoKIyBTYXRpc2ZhY2Npw7NuIHkgcmVub3ZhY2nDs24KCmBgYHtyfQptZXJjYWRvX3NlZ3Vyb3MgJT4lCiAgZ3JvdXBfYnkocmVudWV2YSkgJT4lCiAgc3VtbWFyaXNlKAogICAgc2F0aXNmYWNjaW9uX3Byb21lZGlvID0gbWVhbihzYXRpc2ZhY2Npb24pLAogICAgbWVkaWFuYSA9IG1lZGlhbihzYXRpc2ZhY2Npb24pLAogICAgbiA9IG4oKQogICkKYGBgCgpgYGB7cn0KZ2dwbG90KAogIG1lcmNhZG9fc2VndXJvcywKICBhZXMoCiAgICB4ID0gcmVudWV2YSwKICAgIHkgPSBzYXRpc2ZhY2Npb24KICApCikgKwogIGdlb21fYm94cGxvdCgpICsKICBsYWJzKAogICAgdGl0bGUgPSAiU2F0aXNmYWNjacOzbiBzZWfDum4gcmVub3ZhY2nDs24iLAogICAgeCA9ICJSZW5vdmFjacOzbiIsCiAgICB5ID0gIlNhdGlzZmFjY2nDs24iCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKQWhvcmEgdGVuZW1vcyBvdHJhIHBpc3RhLgoKUXVpesOhIGVsIHByb2JsZW1hIHNlYSBtw6FzIGNvbXBsZWpvIHF1ZSBzaW1wbGVtZW50ZSBlbCBwcmVjaW8uCgotLS0KCiMgQ29tYmluYW5kbyBkb3MgZGltZW5zaW9uZXMKClBvZGVtb3MgZXhwbG9yYXIgc2F0aXNmYWNjacOzbiBlIGluY3JlbWVudG8gZGUgcHJpbWEuCgpgYGB7cn0KZ2dwbG90KAogIG1lcmNhZG9fc2VndXJvcywKICBhZXMoCiAgICB4ID0gaW5jcmVtZW50b19wcmltYSwKICAgIHkgPSBzYXRpc2ZhY2Npb24KICApCikgKwogIGdlb21fcG9pbnQoCiAgICBhbHBoYSA9IDAuMzUKICApICsKICBmYWNldF93cmFwKAogICAgfiByZW51ZXZhCiAgKSArCiAgbGFicygKICAgIHRpdGxlID0gIlByaW1hIHkgc2F0aXNmYWNjacOzbiBzZWfDum4gcmVub3ZhY2nDs24iLAogICAgeCA9ICJJbmNyZW1lbnRvIGRlIHByaW1hICglKSIsCiAgICB5ID0gIlNhdGlzZmFjY2nDs24iCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKRXN0YSBncsOhZmljYSBwdWVkZSBnZW5lcmFyIG51ZXZhcyBoaXDDs3Rlc2lzLgoKUG9yIGVqZW1wbG86Cgo+IExhIGNvbWJpbmFjacOzbiBkZSBpbmNyZW1lbnRvcyBhbHRvcyB5IGJhamEgc2F0aXNmYWNjacOzbiBwb2Ryw61hIGVzdGFyIGFzb2NpYWRhIGNvbiBtZW5vciByZW5vdmFjacOzbi4KCk9ic2VydmUgbGEgZGluw6FtaWNhOgoKYGBgdGV4dApEQVRPUwogIOKGkwpFWFBMT1JBQ0nDk04KICDihpMKUEFUUsOTTgogIOKGkwpQUkVHVU5UQQogIOKGkwpISVDDk1RFU0lTCiAg4oaTCkFOw4FMSVNJUyBQT1NURVJJT1IKYGBgCgotLS0KCiMgRWplbXBsbzogZGUgb2JzZXJ2YWNpw7NuIGEgcHJlZ3VudGEgZm9ybWFsCgpEZXNwdcOpcyBkZSBsYSBleHBsb3JhY2nDs24gcG9kZW1vcyBmb3JtdWxhcjoKCiMjIyBPYnNlcnZhY2nDs24KCkxvcyBjbGllbnRlcyBxdWUgbm8gcmVudWV2YW4gcGFyZWNlbiBwcmVzZW50YXI6CgotIG1heW9yIGluY3JlbWVudG8gZGUgcHJpbWE7Ci0gbWVub3Igc2F0aXNmYWNjacOzbi4KCiMjIyBQcmVndW50YQoKPiDCv0PDs21vIHNlIHJlbGFjaW9uYW4gZWwgaW5jcmVtZW50byBkZSBwcmltYSB5IGxhIHNhdGlzZmFjY2nDs24gY29uIGxhIHByb2JhYmlsaWRhZCBkZSByZW5vdmFjacOzbj8KCiMjIyBIaXDDs3Rlc2lzIDEKCj4gQSBtYXlvciBpbmNyZW1lbnRvIGRlIHByaW1hLCBtZW5vciBwcm9iYWJpbGlkYWQgZGUgcmVub3ZhY2nDs24uCgojIyMgSGlww7N0ZXNpcyAyCgo+IEEgbWF5b3Igc2F0aXNmYWNjacOzbiwgbWF5b3IgcHJvYmFiaWxpZGFkIGRlIHJlbm92YWNpw7NuLgoKIyMjIERpc2XDsW8gaW5pY2lhbAoKKipEZXNjcmlwdGl2byAvIGV4cGxpY2F0aXZvIG9ic2VydmFjaW9uYWwuKioKCk3DoXMgYWRlbGFudGUgdXRpbGl6YXJlbW9zIHJlZ3Jlc2nDs24gbG9nw61zdGljYSBwYXJhIGFuYWxpemFyIGVzdGEgcHJlZ3VudGEuCgotLS0KCiMgQ29ycmVsYWNpw7NuIG5vIHNpZ25pZmljYSBjYXVzYWxpZGFkCgpFc3RhIGRpc3RpbmNpw7NuIHNlcsOhIHJlY3VycmVudGUgZHVyYW50ZSBlbCBjdXJzby4KClN1cG9uZ2Ftb3MgcXVlIG9ic2VydmFtb3M6CgpcWwpYIFx1cGFycm93IFxxdWFkIFx0ZXh0e2N1YW5kb30gXHF1YWQgWSBcdXBhcnJvdwpcXQoKRXNvIGRlbXVlc3RyYSBhc29jaWFjacOzbi4KCk5vIG5lY2VzYXJpYW1lbnRlIGRlbXVlc3RyYToKClxbClggXHJpZ2h0YXJyb3cgWQpcXQoKUHVlZGUgZXhpc3RpcjoKClxbClogXHJpZ2h0YXJyb3cgWApcXQoKeSBzaW11bHTDoW5lYW1lbnRlOgoKXFsKWiBccmlnaHRhcnJvdyBZClxdCgotLS0KCiMgRWplbXBsbyBhY3R1YXJpYWwgZGUgY29uZnVzacOzbgoKSW1hZ2luZSBxdWUgZW5jb250cmFtb3M6Cgo+IExvcyBjbGllbnRlcyBjb24gcHJpbWFzIG3DoXMgYWx0YXMgdGllbmVuIG3DoXMgc2luaWVzdHJvcy4KCsK/UG9kZW1vcyBjb25jbHVpciBxdWUgYXVtZW50YXIgbGEgcHJpbWEgY2F1c2Egc2luaWVzdHJvcz8KCk5vLgoKUHJvYmFibGVtZW50ZSBhbWJhcyB2YXJpYWJsZXMgZXN0w6FuIHJlbGFjaW9uYWRhcyBjb246CgotIGV4cG9zaWNpw7NuOwotIHRpcG8gZGUgdmVow61jdWxvOwotIGVkYWQ7Ci0gc3VtYSBhc2VndXJhZGE7Ci0gem9uYTsKLSBjYXJhY3RlcsOtc3RpY2FzIGRlbCByaWVzZ28uCgpMYSBlc3RydWN0dXJhIHBvZHLDrWEgc2VyOgoKYGBgdGV4dApOaXZlbCBkZSByaWVzZ28KICAgICDihpMKIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkAog4oaTICAgICAgICAgICAgIOKGkwpQcmltYSAgICAgIFNpbmllc3Ryb3MKYGBgCgpMYSBwcmltYSB5IGxvcyBzaW5pZXN0cm9zIGFwYXJlY2VuIGFzb2NpYWRvcywgcGVybyB1bmEgdmFyaWFibGUgc3VieWFjZW50ZSBwdWVkZSBleHBsaWNhciBwYXJ0ZSBkZSBsYSByZWxhY2nDs24uCgotLS0KCiMgRWplbXBsbyBkZSBkaXNlw7FvIGNhdXNhbAoKU3Vwb25nYSBxdWUgbGEgZW1wcmVzYSBkZXNlYSBzYWJlcjoKCj4gwr9FbnZpYXIgdW4gbWVuc2FqZSBwZXJzb25hbGl6YWRvIGF1bWVudGEgbGEgcmVub3ZhY2nDs24/CgpQb2RlbW9zIGltYWdpbmFyIHVuIGV4cGVyaW1lbnRvLgoKYGBge3J9CnNldC5zZWVkKDEwMCkKCmV4cGVyaW1lbnRvIDwtIGRhdGEuZnJhbWUoCiAgZ3J1cG8gPSByZXAoCiAgICBjKAogICAgICAiTWVuc2FqZSBlc3TDoW5kYXIiLAogICAgICAiTWVuc2FqZSBwZXJzb25hbGl6YWRvIgogICAgKSwKICAgIGVhY2ggPSA1MDAKICApCikKCmV4cGVyaW1lbnRvJHJlbnVldmEgPC0gYygKICByYmlub20oCiAgICA1MDAsCiAgICAxLAogICAgMC42NwogICksCiAgcmJpbm9tKAogICAgNTAwLAogICAgMSwKICAgIDAuNzUKICApCikKCmFnZ3JlZ2F0ZSgKICByZW51ZXZhIH4gZ3J1cG8sCiAgZGF0YSA9IGV4cGVyaW1lbnRvLAogIEZVTiA9IG1lYW4KKQpgYGAKClZpc3VhbGljZW1vcy4KCmBgYHtyfQpleHBlcmltZW50byAlPiUKICBncm91cF9ieShncnVwbykgJT4lCiAgc3VtbWFyaXNlKAogICAgdGFzYSA9IG1lYW4ocmVudWV2YSkKICApICU+JQogIGdncGxvdCgKICAgIGFlcygKICAgICAgeCA9IGdydXBvLAogICAgICB5ID0gdGFzYQogICAgKQogICkgKwogIGdlb21fY29sKCkgKwogIHNjYWxlX3lfY29udGludW91cygKICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudAogICkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJUYXNhIGRlIHJlbm92YWNpw7NuIHBvciB0cmF0YW1pZW50byIsCiAgICB4ID0gTlVMTCwKICAgIHkgPSAiVGFzYSBkZSByZW5vdmFjacOzbiIKICApICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgpMYSBsw7NnaWNhIGNhdXNhbCByZXF1aWVyZSBtdWNobyBtw6FzIHF1ZSBvYnNlcnZhciB1bmEgZGlmZXJlbmNpYS4KCk5lY2VzaXRhbW9zIGNvbnNpZGVyYXI6CgotIGFzaWduYWNpw7NuOwotIGNvbXBhcmFiaWxpZGFkOwotIHZhcmlhYmxlcyBleHRyYcOxYXM7Ci0gdGFtYcOxbyBkZSBtdWVzdHJhOwotIGF6YXI7Ci0gdmFsaWRleiBpbnRlcm5hOwotIHZhbGlkZXogZXh0ZXJuYS4KCkxvIGVzdHVkaWFyZW1vcyBjb24gbWF5b3IgZGV0YWxsZSBwb3N0ZXJpb3JtZW50ZS4KCi0tLQoKIyBVbiBwcmluY2lwaW8gaW1wb3J0YW50ZQoKRHVyYW50ZSBlc3RlIGN1cnNvIGV2aXRhcmVtb3MgbGEgbMOzZ2ljYToKCmBgYHRleHQKVGVuZ28gdW5hIGJhc2UKICAgICAg4oaTCsK/UXXDqSBhbsOhbGlzaXMgcHVlZG8gaGFjZXI/CmBgYAoKSW50ZW50YXJlbW9zIHV0aWxpemFyOgoKYGBgdGV4dApUZW5nbyB1bmEgZGVjaXNpw7NuCiAgICAgIOKGkwrCv1F1w6kgbmVjZXNpdG8gc2FiZXI/CiAgICAgIOKGkwrCv1F1w6kgcHJlZ3VudGEgZGVibyByZXNwb25kZXI/CiAgICAgIOKGkwrCv1F1w6kgZGF0b3MgbmVjZXNpdG8/CiAgICAgIOKGkwrCv1F1w6kgYW7DoWxpc2lzIGNvcnJlc3BvbmRlPwpgYGAKCjxkaXYgY2xhc3M9ImNhamEtYWN0dWFyaWFsIj4KCgoqKlByaW1lcm8gbGEgcHJlZ3VudGEuIERlc3B1w6lzIGVsIG3DqXRvZG8uKioKCk5vIHV0aWxpemFyZW1vcyB1bmEgdMOpY25pY2EgZXN0YWTDrXN0aWNhIHNpbXBsZW1lbnRlIHBvcnF1ZSBlc3TDqSBkaXNwb25pYmxlLgoKPC9kaXY+CgotLS0KCiMgRXJyb3JlcyBmcmVjdWVudGVzIGFsIGZvcm11bGFyIGludmVzdGlnYWNpb25lcwoKIyMgRXJyb3IgMS4gRW1wZXphciBwb3IgbGEgdMOpY25pY2EKCj4g4oCcUXVpZXJvIGhhY2VyIHVuYSByZWdyZXNpw7NuLuKAnQoKUHJlZ3VudGEgY29ycmVjdGE6Cgo+IMK/UXXDqSBwcm9ibGVtYSByZXF1aWVyZSB1biBtb2RlbG8gZGUgcmVncmVzacOzbj8KCi0tLQoKIyMgRXJyb3IgMi4gQ29uZnVuZGlyIHPDrW50b21hIGNvbiBwcm9ibGVtYQoKU8OtbnRvbWE6Cgo+IExhcyB2ZW50YXMgZGlzbWludXllcm9uLgoKUHJvYmxlbWE6CgpQb2Ryw61hIHNlcjoKCi0gcHJlY2lvOwotIHByb2R1Y3RvOwotIGNvbXBldGVuY2lhOwotIGNhbmFsOwotIG1lcmNhZG87Ci0gcGVyY2VwY2nDs24uCgotLS0KCiMjIEVycm9yIDMuIFByZWd1bnRhIGRlbWFzaWFkbyBhbXBsaWEKCj4gwr9RdcOpIHBpZW5zYSBsYSBnZW50ZSBkZSBsb3Mgc2VndXJvcz8KCkRlYmUgZGVsaW1pdGFyc2U6CgotIHF1w6kgcGVyc29uYXM7Ci0gcXXDqSBzZWd1cm9zOwotIHF1w6kgZGltZW5zacOzbjsKLSBxdcOpIHRlcnJpdG9yaW87Ci0gcXXDqSBwZXJpb2RvLgoKLS0tCgojIyBFcnJvciA0LiBBc3VtaXIgY2F1c2FsaWRhZAoKPiBMb3MgY2xpZW50ZXMgcXVlIHBhZ2FuIG3DoXMgY2FuY2VsYW4gbcOhcywgcG9yIGxvIHRhbnRvIGVsIHByZWNpbyBjYXVzYSBjYW5jZWxhY2nDs24uCgpVbmEgYXNvY2lhY2nDs24gb2JzZXJ2YWRhIG5vIGRlbXVlc3RyYSBjYXVzYWxpZGFkLgoKLS0tCgojIyBFcnJvciA1LiBEaXNlw7FhciBwcmltZXJvIGxhIGVuY3Vlc3RhCgpObyBkZWJlcsOtYW1vcyBwcmVndW50YXI6Cgo+IOKAnMK/UXXDqSBwcmVndW50YXMgcG9uZ28gZW4gZWwgY3Vlc3Rpb25hcmlvP+KAnQoKYW50ZXMgZGUgcmVzcG9uZGVyOgoKPiDigJzCv1F1w6kgaW5mb3JtYWNpw7NuIG5lY2VzaXRvP+KAnQoKLS0tCgojIE1hcGEgY29uY2VwdHVhbCBmaW5hbAoKYGBgdGV4dAogICAgICAgICAgICAgICAgICAgICAgICAgREVDSVNJw5NOIEVNUFJFU0FSSUFMCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKWvAogICAgICAgICAgICAgICAgICAgICAgICAgREVGSU5JUiBFTCBQUk9CTEVNQQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCiAgICAgICAgICAgICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilLTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAKICAgICAgICAgICAgIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggogICAgICAgICAgICAg4pa8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pa8CiAgICAgIENPTlRFWFRPIERFTCBQUk9CTEVNQSAgICAgICAgICAgICAgICAgICAgSU5GT1JNQUNJw5NOIEVYSVNURU5URQogICAgICAgICAgICAg4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCiAgICAgICAgICAgICDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilKzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKWvAogICAgICAgICAgICAgICAgICAgICAgIFBST0JMRU1BIERFIElOVkVTVElHQUNJw5NOCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKWvAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPQkpFVElWT1MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pa8CiAgICAgICAgICAgICAgICAgICAgIFBSRUdVTlRBUyBERSBJTlZFU1RJR0FDScOTTgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilrwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSElQw5NURVNJUwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilrwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFSSUFCTEVTCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKWvAogICAgICAgICAgICAgICAgICAgIElORk9STUFDScOTTiBSRVFVRVJJREEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pa8CiAgICAgICAgICAgICAgICAgICAgIERJU0XDkU8gREUgSU5WRVNUSUdBQ0nDk04KICAgICAgICAgICAgICAgICAgICAgICAvICAgICAgICAgIHwgICAgICAgICAgXAogICAgICAgICAgICAgICAgICAgICAgLyAgICAgICAgICAgfCAgICAgICAgICAgXAogICAgICAgICAgICAgRVhQTE9SQVRPUklPICAgREVTQ1JJUFRJVk8gICAgIENBVVNBTAogICAgICAgICAgICAgICAgICAgICAgXCAgICAgICAgICAgfCAgICAgICAgICAgLwogICAgICAgICAgICAgICAgICAgICAgIFwgICAgICAgICAgfCAgICAgICAgICAvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilrwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEQVRPUwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilrwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pa8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVZJREVOQ0lBCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKWvAogICAgICAgICAgICAgICAgICAgICAgICAgVE9NQSBERSBERUNJU0lPTkVTCmBgYAoKCiMgUmVmZXJlbmNpYSBiYXNlCgpNYWxob3RyYSwgTi4gSy4gKDIwMDgpLiAqSW52ZXN0aWdhY2nDs24gZGUgbWVyY2Fkb3MuIFVuIGVuZm9xdWUgYXBsaWNhZG8qLiBRdWludGEgZWRpY2nDs24uIFBlYXJzb24gRWR1Y2FjacOzbi4KCi0tLQo=