1 Introducción

En una organización, se busca comprender y prever los factores que influyen en la rotación de empleados entre distintos cargos. La empresa ha recopilado datos históricos sobre el empleo de sus trabajadores, incluyendo variables como la antigüedad en el cargo actual, el nivel de satisfacción laboral, el salario actual, edad y otros factores relevantes. La gerencia planea desarrollar un modelo de regresión logística que permita estimar la probabilidad de que un empleado cambie de cargo en el próximo período y determinar cuales factores indicen en mayor proporción a estos cambios.

Con esta información, la empresa podrá tomar medidas proactivas para retener a su talento clave, identificar áreas de mejora en la gestión de recursos humanos y fomentar un ambiente laboral más estable y tranquilo. La predicción de la probabilidad de rotación de empleados ayudará a la empresa a tomar decisiones estratégicas informadas y a mantener un equipo de trabajo comprometido y satisfecho en sus roles actuales.

Fuente: Tomada de pixabay.com

El caso solicita:

  1. Seleccionar 3 variables categóricas (distintas de rotación) y 3 variables cuantitativas, que se consideren estén relacionadas con la rotación.
  2. Realizar un análisis univariado (caracterización) de la información contenida en la base de datos rotación.
  3. Realizar un análisis de bivariado en donde la variable respuesta sea rotacion codificada de la siguiente manera (y=1 es si rotación, y=0 es no rotación). Con base en estos resultados identifique cuáles son las variables determinantes de la rotación e interpretar el signo del coeficiente estimado. Compare estos resultados con la hipótesis planteada en el punto 2.
  4. Realizar la estimación de un modelo de regresión logístico en el cual la variable respuesta es rotacion (y=1 es si rotación, y=0 es no rotación) y las 6 covariables seleccionadas en el punto 1. Interprete los coeficientes del modelo y la significancia de los parámetros.
  5. Evaluar el poder predictivo del modelo con base en la curva ROC y el AUC.
  6. Realizar una predicción de la probabilidad de que un individuo (hipotético) rote y defina un corte para decidir si se debe intervenir a este empleado o no (posible estrategia para motivar al empleado).
  7. Concluir adicionando una discusión sobre cuál sería la estrategia para disminuir la rotación en la empresa (con base en las variables que resultaron significativas en el punto 3).

2 Análisis Exloratorio de Datos

2.1 Carga del Dataset

El conjunto de datos entregado consta de 1470 registros y 24, de las cuales 8 fueron leídas como texto y 16 como numéricas. La variable de interés, Rotación, está registrada con las categorías “Si” y “No”, por lo que deberá recodificarse como variable binaria (1 = rota, 0 = no rota). Entre las variables numéricas se identificaron varias que, según los valores observados, corresponden a escalas ordinales codificadas con números enteros y no a magnitudes continuas: Educación, Satisfacción_Ambiental, Satisfación_Laboral, Rendimiento_Laboral y Equilibrio_Trabajo_Vida.

2.1.1 Diccionario de Variables

La Tabla 1.1 muestra que, de las 24 variables, 13 son cualitativas y 11 cuantitativas. Entre las cualitativas, 7 son nominales, incluida la variable respuesta Rotación. Las otras 6 son ordinales. Entre las variables cuantitativas, 9 son discretas, en su mayoría conteos de años o de eventos, y 2 continuas: el ingreso mensual y el porcentaje de aumento salarial.

library(knitr)
library(kableExtra)

valores_observados <- function(x) {
  if (is.numeric(x)) {
    paste0(min(x, na.rm = TRUE), " – ", max(x, na.rm = TRUE))
  } else {
    paste(sort(unique(x)), collapse = ", ")
  }
}

rangos <- unname(sapply(rot_p1, valores_observados))

diccionario <- tibble(
  Variable = names(rot_p1),
  Descripción = c(
    "Indica si el empleado presentó rotación",
    "Edad del empleado en años",
    "Frecuencia con que el empleado realiza viajes de negocios",
    "Área de la empresa a la que pertenece el empleado",
    "Kilómetros de distancia desde la casa",
    "Nivel educativo (1 = primaria, 2 = secundaria, 3 = técnico/tecnólogo 4 = pregrado y 5=posgrado)",
    "Área de formación académica del empleado",
    "Satisfacción con el ambiente de trabajo (1 = Muy insatisfecho, 2 = Insatisfecho, 3 = Satisfecho y 4 = Muy satisfecho)",
    "Género del empleado",
    "Cargo que ocupa el empleado",
    "Satisfacción con el trabajo que realiza (1 = Muy insatisfecho, 2 = Insatisfecho, 3 = Satisfecho y 4 = Muy satisfecho)",
    "Estado civil del empleado",
    "Ingreso mensual del empleado",
    "Número de empresas en las que ha trabajado anteriormente",
    "Indica si el empleado trabaja horas extra",
    "Porcentaje de aumento salarial en el último año",
    "Calificación de desempeño (1 = bajo, 2 = medio, 3 = alto, 4 = Muy alto)",
    "Total de años de experiencia laboral",
    "Número de capacitaciones recibidas en el último año",
    "Equilibrio entre trabajo y vida personal (1 = Muy bajo, 2 = bajo, 3 = Medio, 4 = alto)",
    "Años de antigüedad en la empresa",
    "Años en el cargo actual",
    "Años transcurridos desde la última promoción",
    "Años trabajando con el mismo jefe"
  ),
  Tipo = c(
    "Cualitativa binaria", "Cuantitativa discreta", "Cualitativa ordinal",
    "Cualitativa nominal", "Cuantitativa discreta", "Cualitativa ordinal",
    "Cualitativa nominal", "Cualitativa ordinal", "Cualitativa nominal",
    "Cualitativa nominal", "Cualitativa ordinal", "Cualitativa nominal",
    "Cuantitativa continua", "Cuantitativa discreta", "Cualitativa nominal",
    "Cuantitativa continua", "Cualitativa ordinal", "Cuantitativa discreta",
    "Cuantitativa discreta", "Cualitativa ordinal", "Cuantitativa discreta",
    "Cuantitativa discreta", "Cuantitativa discreta", "Cuantitativa discreta"
  ),
  `Valores observados` = rangos
)

diccionario |>
  tabla_estilo(titulo = "",
               alineacion = c("l", "l", "c", "l")) |>
  column_spec(2, width = "22em")
Variable Descripción Tipo Valores observados
Rotación Indica si el empleado presentó rotación Cualitativa binaria No, Si
Edad Edad del empleado en años Cuantitativa discreta 18 – 60
Viaje de Negocios Frecuencia con que el empleado realiza viajes de negocios Cualitativa ordinal Frecuentemente, No_Viaja, Raramente
Departamento Área de la empresa a la que pertenece el empleado Cualitativa nominal IyD, RH, Ventas
Distancia_Casa Kilómetros de distancia desde la casa Cuantitativa discreta 1 – 29
Educación Nivel educativo (1 = primaria, 2 = secundaria, 3 = técnico/tecnólogo 4 = pregrado y 5=posgrado) Cualitativa ordinal 1 – 5
Campo_Educación Área de formación académica del empleado Cualitativa nominal Ciencias, Humanidades, Mercadeo, Otra, Salud, Tecnicos
Satisfacción_Ambiental Satisfacción con el ambiente de trabajo (1 = Muy insatisfecho, 2 = Insatisfecho, 3 = Satisfecho y 4 = Muy satisfecho) Cualitativa ordinal 1 – 4
Genero Género del empleado Cualitativa nominal F, M
Cargo Cargo que ocupa el empleado Cualitativa nominal Director_Investigación, Director_Manofactura, Ejecutivo_Ventas, Gerente, Investigador_Cientifico, Recursos_Humanos, Representante_Salud, Representante_Ventas, Tecnico_Laboratorio
Satisfación_Laboral Satisfacción con el trabajo que realiza (1 = Muy insatisfecho, 2 = Insatisfecho, 3 = Satisfecho y 4 = Muy satisfecho) Cualitativa ordinal 1 – 4
Estado_Civil Estado civil del empleado Cualitativa nominal Casado, Divorciado, Soltero
Ingreso_Mensual Ingreso mensual del empleado Cuantitativa continua 1009 – 19999
Trabajos_Anteriores Número de empresas en las que ha trabajado anteriormente Cuantitativa discreta 0 – 9
Horas_Extra Indica si el empleado trabaja horas extra Cualitativa nominal No, Si
Porcentaje_aumento_salarial Porcentaje de aumento salarial en el último año Cuantitativa continua 11 – 25
Rendimiento_Laboral Calificación de desempeño (1 = bajo, 2 = medio, 3 = alto, 4 = Muy alto) Cualitativa ordinal 3 – 4
Años_Experiencia Total de años de experiencia laboral Cuantitativa discreta 0 – 40
Capacitaciones Número de capacitaciones recibidas en el último año Cuantitativa discreta 0 – 6
Equilibrio_Trabajo_Vida Equilibrio entre trabajo y vida personal (1 = Muy bajo, 2 = bajo, 3 = Medio, 4 = alto) Cualitativa ordinal 1 – 4
Antigüedad Años de antigüedad en la empresa Cuantitativa discreta 0 – 40
Antigüedad_Cargo Años en el cargo actual Cuantitativa discreta 0 – 18
Años_ultima_promoción Años transcurridos desde la última promoción Cuantitativa discreta 0 – 15
Años_acargo_con_mismo_jefe Años trabajando con el mismo jefe Cuantitativa discreta 0 – 17

Tabla 1.1. Diccionario de variables de la base rotación

2.1.2 Valores Ausentes

No se encontraron valores ausentes en ninguna variables y tampoco registros incompletos, celdas vacías o compuestas de espacios.En consecuencia, el dataset no requirió imputación ni eliminación de registros, y los análisis posteriores se realizaron sobre la totalidad de las observaciones.

2.1.3 Revisión Tipos de Variable

La Tabla 1.2 muestra que, con base en la clasificación del diccionario de variables (Tabla 1.1), se corrige el tipo de dato de las variables que no correspondía a su naturaleza. Las variables cualitativas nominales se convirten en factores. Las ordinales, tanto la frecuencia de viajes de negocios como las cinco escalas registradas numéricamente, se transfan en factores ordenados, asignando a cada código su etiqueta. En la variable Rotación se fijó la categoría “No” como nivel de referencia. Para verificar que la conversión no generara pérdida de información, se comprueba que ningún valor quede sin categoría asignada.

rot_p3 <- rot_p2 |>
  mutate(
    across(c(Departamento, Campo_Educación, Genero, Cargo, Estado_Civil, Horas_Extra),
           as.factor),
    Rotación = factor(Rotación, levels = c("No", "Si")),
    `Viaje de Negocios` = factor(`Viaje de Negocios`,
                                 levels = c("No_Viaja", "Raramente", "Frecuentemente"),
                                 ordered = TRUE),
    Educación = factor(Educación, levels = 1:5,
                       labels = c("Primaria", "Secundaria", "Técnico/Tecnólogo",
                                  "Pregrado", "Posgrado"),
                       ordered = TRUE),
    across(c(Satisfacción_Ambiental, Satisfación_Laboral),
           ~ factor(.x, levels = 1:4,
                    labels = c("Muy insatisfecho", "Insatisfecho",
                               "Satisfecho", "Muy satisfecho"),
                    ordered = TRUE)),
    Rendimiento_Laboral = factor(Rendimiento_Laboral, levels = 1:4,
                                 labels = c("Bajo", "Medio", "Alto", "Muy alto"),
                                 ordered = TRUE),
    Equilibrio_Trabajo_Vida = factor(Equilibrio_Trabajo_Vida, levels = 1:4,
                                     labels = c("Muy bajo", "Bajo", "Medio", "Alto"),
                                     ordered = TRUE)
  )

# sum(is.na(rot_p3))

tabla_tipos <- tibble(
  Variable = names(rot_p3),
  `Tipo original` = unname(sapply(rot_p2, function(x) class(x)[1])),
  `Tipo corregido` = unname(sapply(rot_p3, function(x) class(x)[1]))
)

tabla_tipos |>
  tabla_estilo(titulo = "")
Variable Tipo original Tipo corregido
Rotación character factor
Edad numeric numeric
Viaje de Negocios character ordered
Departamento character factor
Distancia_Casa numeric numeric
Educación numeric ordered
Campo_Educación character factor
Satisfacción_Ambiental numeric ordered
Genero character factor
Cargo character factor
Satisfación_Laboral numeric ordered
Estado_Civil character factor
Ingreso_Mensual numeric numeric
Trabajos_Anteriores numeric numeric
Horas_Extra character factor
Porcentaje_aumento_salarial numeric numeric
Rendimiento_Laboral numeric ordered
Años_Experiencia numeric numeric
Capacitaciones numeric numeric
Equilibrio_Trabajo_Vida numeric ordered
Antigüedad numeric numeric
Antigüedad_Cargo numeric numeric
Años_ultima_promoción numeric numeric
Años_acargo_con_mismo_jefe numeric numeric

Tabla 1.2. Tipo de dato de las variables antes y después de la corrección

Tras la corrección, el dataset quedó conformado por 7 factores nominales, 6 factores ordenados y 11 variables numéricas, en correspondencia con la clasificación establecida en el diccionario (Tabla 1.1). Las 8 variables leídas originalmente como texto pasaron a ser categóricas. Además, cinco variables registradas como números (Educación, Satisfacción_Ambiental, Satisfación_Laboral, Rendimiento_Laboral y Equilibrio_Trabajo_Vida) dejaron de tratarse como cantidades y pasaron a representarse como niveles ordenados. La verificación posterior no registró valores sin categoría asignada, lo que confirma que todos los códigos presentes en la base correspondían a niveles válidos de sus respectivas escalas.

2.1.4 Revisión de las Categorías

Se revisa la consistencia de las categorías de las 13 variables cualitativas con el propósito de detectar una misma categoría registrada de formas distintas. Para ello se compara el número de categorías de cada variable antes y después de normalizar el texto, lo que implicó convertirlo a minúsculas, eliminar tildes y suprimir espacios en los extremos. Adicionalmente, se ajustan las etiquetas de las categorías para mejorar su lectura en tablas y gráficos, y se corrigieron los nombres de seis variables que presentaban espacios, errores ortográficos o un formato distinto al del resto del dataset (Ver Tablas 1.3 y 1.4).

revisar_categorias <- function(x) {
  niveles <- levels(x)
  texto <- as.character(x)
  normalizado <- stringi::stri_trans_general(tolower(trimws(texto)), "Latin-ASCII")
  tibble(
    `N.º de niveles` = length(niveles),
    `Espacios sobrantes` = sum(texto != trimws(texto)),
    `Variantes de escritura` = n_distinct(texto) - n_distinct(normalizado),
    Niveles = paste(niveles, collapse = ", ")
  )
}

tabla_categorias <- rot_p3 |>
  select(where(is.factor)) |>
  map_dfr(revisar_categorias, .id = "Variable")

tabla_categorias |>
  tabla_estilo(titulo = "",
               alineacion = c("l", "c", "c", "c", "l"))
Variable N.º de niveles Espacios sobrantes Variantes de escritura Niveles
Rotación 2 0 0 No, Si
Viaje de Negocios 3 0 0 No_Viaja, Raramente, Frecuentemente
Departamento 3 0 0 IyD, RH, Ventas
Educación 5 0 0 Primaria, Secundaria, Técnico/Tecnólogo, Pregrado, Posgrado
Campo_Educación 6 0 0 Ciencias, Humanidades, Mercadeo, Otra, Salud, Tecnicos
Satisfacción_Ambiental 4 0 0 Muy insatisfecho, Insatisfecho, Satisfecho, Muy satisfecho
Genero 2 0 0 F, M
Cargo 9 0 0 Director_Investigación, Director_Manofactura, Ejecutivo_Ventas, Gerente, Investigador_Cientifico, Recursos_Humanos, Representante_Salud, Representante_Ventas, Tecnico_Laboratorio
Satisfación_Laboral 4 0 0 Muy insatisfecho, Insatisfecho, Satisfecho, Muy satisfecho
Estado_Civil 3 0 0 Casado, Divorciado, Soltero
Horas_Extra 2 0 0 No, Si
Rendimiento_Laboral 4 0 0 Bajo, Medio, Alto, Muy alto
Equilibrio_Trabajo_Vida 4 0 0 Muy bajo, Bajo, Medio, Alto

Tabla 1.3. Revisión de las categorías de las variables cualitativas

tabla_nombres <- tibble(
  `Nombre original` = names(rot_p3),
  `Nombre corregido` = names(rot_p4)
) |>
  filter(`Nombre original` != `Nombre corregido`)

tabla_nombres |>
  tabla_estilo(titulo = "", alineacion = c("l", "l"))
Nombre original Nombre corregido
Viaje de Negocios Viaje_Negocios
Genero Género
Satisfación_Laboral Satisfacción_Laboral
Porcentaje_aumento_salarial Porcentaje_Aumento_Salarial
Años_ultima_promoción Años_Última_Promoción
Años_acargo_con_mismo_jefe Años_Mismo_Jefe

Tabla 1.4. Variables renombradas

2.1.5 Registros Duplicados

Se verifica la existencia de registros duplicados, entendidos en este caso como filas idénticas en la totalidad de las variables. La revisión se complementa con una búsqueda de registros coincidentes en todas las variables excepto Rotación. Esto permite detectar perfiles idénticos con resultados opuestos en la variable respuesta, una situación que afectaría la estimación del modelo logístico. La revisión no identificó registros duplicados: ninguna fila coincide con otra en la totalidad de las variables. Tampoco se encontraron perfiles idénticos con resultado distinto en Rotación.

2.1.6 Estadísticas Descriptivas Variables Continuas

Las 11 variables cuantitativas se caracterizan mediante medidas de tendencia central (media y mediana), de dispersión (desviación estándar, coeficiente de variación, valores mínimo y máximo, y cuartiles) y de forma (coeficientes de asimetría y curtosis). Estas medidas se complementan con histogramas para examinar visualmente la distribución de cada variable.

datos_num <- rot_p5 |>
  select(where(is.numeric)) |>
  pivot_longer(everything(), names_to = "Variable", values_to = "valor") |>
  mutate(Variable = fct_inorder(Variable))

descriptivos <- datos_num |>
  group_by(Variable) |>
  summarise(
    Media     = mean(valor),
    Mediana   = median(valor),
    DE        = sd(valor),
    `CV (%)`  = 100 * sd(valor) / mean(valor),
    Mín       = min(valor),
    Q1        = quantile(valor, 0.25),
    Q3        = quantile(valor, 0.75),
    Máx       = max(valor),
    Asimetría = e1071::skewness(valor, type = 2),
    Curtosis  = e1071::kurtosis(valor, type = 2)
  ) |>
  mutate(across(where(is.numeric), ~ round(.x, 2)))

descriptivos |>
  tabla_estilo(titulo = "",
               nota = "DE: desviación estándar; CV: coeficiente de variación; Q1 y Q3: primer y tercer cuartil. La curtosis se reporta como exceso respecto a la distribución normal.")
Variable Media Mediana DE CV (%) Mín Q1 Q3 Máx Asimetría Curtosis
Edad 36,92 36 9,14 24,74 18 30 43 60 0,41 -0,40
Distancia_Casa 9,19 7 8,11 88,19 1 2 14 29 0,96 -0,22
Ingreso_Mensual 6.502,93 4.919 4.707,96 72,40 1.009 2.911 8.379 19.999 1,37 1,01
Trabajos_Anteriores 2,69 2 2,50 92,75 0 1 4 9 1,03 0,01
Porcentaje_Aumento_Salarial 15,21 14 3,66 24,06 11 12 18 25 0,82 -0,30
Años_Experiencia 11,28 10 7,78 68,98 0 6 15 40 1,12 0,92
Capacitaciones 2,80 3 1,29 46,06 0 2 3 6 0,55 0,49
Antigüedad 7,01 5 6,13 87,42 0 3 9 40 1,76 3,94
Antigüedad_Cargo 4,23 3 3,62 85,67 0 2 7 18 0,92 0,48
Años_Última_Promoción 2,19 1 3,22 147,29 0 0 3 15 1,98 3,61
Años_Mismo_Jefe 4,12 3 3,57 86,54 0 2 7 17 0,83 0,17
Nota. DE: desviación estándar; CV: coeficiente de variación; Q1 y Q3: primer y tercer cuartil. La curtosis se reporta como exceso respecto a la distribución normal.

Tabla 1.5. Estadísticos descriptivos de las variables cuantitativas

La Tabla 1.5 muestra que la plantilla de cargos tiene una edad media de 36,9 años, con un rango entre 18 y 60 y una distribución aproximadamente simétrica (asimetría de 0,41), la única variable con esta distribución. Las diez variables restantes presentan asimetría positiva, con la media por encima de la mediana en todos los casos, patrón que confirman los histogramas de la Figura 1.1. El caso más marcado es el ingreso mensual, cuya media (6.502,93) supera en casi 1.600 unidades a la mediana (4.919), lo que indica que un grupo reducido de empleados con salarios altos, hasta un máximo de 19.999, eleva el promedio por encima del ingreso típico.

Las medidas de dispersión relativa revelan comportamientos muy distintos entre variables. La edad y el porcentaje de aumento salarial son las más homogéneas, con coeficientes de variación cercanos al 24%, mientras que los años desde la última promoción constituyen la variable más dispersa del conjunto (CV de 147,3%) lo que indica que la mitad de los empleados fue promovida hace un año o menos, pero algunos acumulan hasta 15 años sin ascenso. Un comportamiento similar se observa en la antigüedad en la empresa, donde la mediana de 5 años contrasta con un máximo de 40 y con la curtosis más alta de la tabla (3,94), lo que puede ser señal de una cola derecha pronunciada compuesta por empleados de trayectoria prolongada.

library(ggplot2)

datos_num |>
  ggplot(aes(x = valor, fill = Variable)) +
  geom_histogram(
    bins = 25,
    color = "white",
    linewidth = 0.25,
    alpha = 0.90
  ) +
  facet_wrap(~ Variable, scales = "free", ncol = 3) +
  scale_fill_viridis_d(
    option = "D",
    end = 0.90,
    guide = "none"
  ) +
  labs(
    title = "",
    x = NULL,
    y = "Frecuencia"
  ) +
  theme_minimal() +
  theme(
    strip.background = element_blank(),
    strip.text = element_text(
      face = "plain",
      color = "#333333",
      size = 10
    ),
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    legend.position = "none"
  )

Figura 1.1. Distribución de las variables cuantitativas

Las variables relacionadas con la trayectoria laboral guardan coherencia entre sí: la experiencia total (mediana de 10 años) supera a la antigüedad en la empresa (5 años), y esta a su vez a la antigüedad en el cargo actual (3 años), lo que refleja una estructura organizacional razonable. Por su parte, los histogramas evidencian que varias variables de conteo concentran sus valores en pocas categorías. Las capacitaciones se agrupan casi por completo en 2 y 3 al año, y el porcentaje de aumento salarial se acumula entre 11% y 14%, con frecuencias decrecientes hacia valores superiores. Finalmente, la distancia al lugar de trabajo muestra una fuerte concentración en trayectos cortos, con un 25% de los empleados residiendo a dos kilómetros o menos de su lugar de trabajo, pero con una cola que se extiende hasta 29 kilómetros.

2.1.7 Estadísticas Descriptivas Variables Categóricas

Las 13 variables cualitativas se caracterizan mediante gráficos de barras. La variable respuesta (Rotación), se analiza de forma independiente, incorporando la razón entre sus dos categorías con el fin de evaluar el equilibrio entre empleados que rotan y que permanecen, aspecto relevante para la posterior estimación y evaluación del modelo logístico.

La Figura 1.2 evidencia que la plantilla de empleados está concentrada en unos pocos perfiles. El 65,4% de los empleados pertenece a Investigación y Desarrollo y el 30,3% a Ventas, mientras que Recursos Humanos reúne apenas 63 personas (4,3%). Una concentración similar se observa en el cargo, la variable con mayor número de categorías: tres de los nueve cargos (Ejecutivo de Ventas, Investigador Científico y Técnico de Laboratorio) agrupan al 59,7% de la plantilla, en tanto que Recursos Humanos, con 52 empleados, es el menos frecuente.

Esta desproporción debe tenerse presente para la inlcusión de la variable al modelo, pues las categorías con pocos casos tienden a producir estimaciones inestables. En cuanto al perfil general, el 60% de los empleados son hombres, el 45,8% está casado. El nivel educativo predominante es el de técnico o tecnólogo (38,9%), seguido por pregrado (27,1%), mientras que el posgrado resulta marginal (3,3%). Un 30,8% de los empleados cuenta únicamente con educación primaria (11,6%) o secundaria (19,2%), proporción considerable para una organización con un peso tan alto del área de Investigación y Desarrollo. La formación se concentra en Ciencias (41,2%) y Salud (31,6%), coherente con el perfil técnico y científico de la empresa.

niveles_orden <- categoricas |>
  distinct(Variable, Categoría, Orden) |>
  arrange(Variable, desc(Orden)) |>
  mutate(Etiqueta = paste(Categoría, Variable, sep = "___")) |>
  pull(Etiqueta)

categoricas |>
  mutate(
    Etiqueta = factor(
      paste(Categoría, Variable, sep = "___"),
      levels = niveles_orden
    )
  ) |>
  ggplot(aes(y = Etiqueta, fill = Variable)) +
  geom_bar(
    width = 0.7,
    color = "white",
    linewidth = 0.25,
    alpha = 0.90
  ) +
  facet_wrap(~ Variable, scales = "free", ncol = 2) +
  scale_fill_viridis_d(
    option = "D",
    end = 0.90,
    guide = "none"
  ) +
  scale_y_discrete(
    labels = ~ scales::label_wrap(22)(sub("___.*$", "", .x))
  ) +
  labs(
    title = "",
    x = "Frecuencia",
    y = NULL
  ) +
  theme_minimal(base_size = 11) +
  theme(
    axis.text.y = element_text(
      size = 9,
      color = "#333333"
    ),
    strip.background = element_blank(),
    strip.text = element_text(
      face = "plain",
      size = 10,
      color = "#333333"
    ),
    panel.grid.minor = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.spacing = unit(1.2, "lines"),
    plot.title = element_text(
      face = "bold",
      size = 14,
      hjust = 0.5,
      color = "#21384A"
    ),
    legend.position = "none"
  )

Figura 1.2. Distribución de variables cualitativas

tabla_rotacion <- rot_p5 |>
  count(Rotación, name = "Frecuencia") |>
  mutate(`Porcentaje (%)` = round(100 * Frecuencia / sum(Frecuencia), 1))

tabla_rotacion |>
  tabla_estilo(titulo = "",
               nota = paste0("Razón entre empleados que no rotan y que rotan: ",
                             round(tabla_rotacion$Frecuencia[1] /
                                     tabla_rotacion$Frecuencia[2], 1), " a 1."))
Rotación Frecuencia Porcentaje (%)
No 1.233 83,9
Sí 237 16,1
Nota. Razón entre empleados que no rotan y que rotan: 5.2 a 1.

Tabla 1.6. Distribución de la variable Rotación

Con respecto a las condiciones laborales, el 71% de los empleados viaja rara vez y solo el 18,8% lo hace con frecuencia, mientras que el 28,3% trabaja horas extra. Las dos escalas de satisfacción muestran distribuciones casi idénticas: alrededor del 61% se declara satisfecha o muy satisfecha, mientras que cerca del 39% manifiesta algún grado de insatisfacción, con un 19% en el nivel de muy insatisfecho, tanto respecto al ambiente de trabajo como al trabajo desempeñado.

El equilibrio entre trabajo y vida personal presenta una distribución concentrada en el nivel intermedio, que agrupa al 60,7% de los empleados. Solo el 10,4% lo califica como alto, mientras que el 28,8% lo ubica en los niveles bajo (23,4%) o muy bajo (5,4%). Un hallazgo particular se presenta en el rendimiento laboral, ya que aunque la escala contempla cuatro niveles, la base solo registra los dos superiores, con un 84,6% de calificaciones “Alto” y un 15,4% “Muy alto”. La ausencia total de evaluaciones bajas o medias limita severamente la utilidad de esta variable como predictor, pues no permite distinguir entre empleados con desempeño satisfactorio e insatisfactorio.

Finalmente, la Tabla 1.6 muestra que el 16.1% de los empleados rota (cambia de empleo o puesto de trabajo) y el 83.9% no rota.

2.1.8 Identificación y Tratamiento de Valores Atípicos

Se examina la presencia de valores atípicos en las 11 variables cuantitativas mediante el criterio del rango intercuartílico, considerando como atípico todo valor situado fuera del intervalo comprendido entre Q1 − (k* RIC) y Q3 + (k* RIC). El análisis se realiza con dos umbrales, k = 1,5 y k = 3, dado que el criterio convencional tiende a señalar un número elevado de observaciones en distribuciones asimétricas como las identificadas la sección anterior. El conteo se complementa con diagramas de caja y con la comparación entre el valor máximo observado y el límite superior de cada variable, con el fin de establecer si los casos señalados correspondían a errores de registro o a valores extremos plausibles.

limites_ric <- function(x, k) {
  q <- quantile(x, c(0.25, 0.75))
  ric <- q[2] - q[1]
  c(q[1] - k * ric, q[2] + k * ric)
}

atipicos <- datos_num |>
  group_by(Variable) |>
  summarise(
    `Atípicos (1,5 RIC)` = sum(valor < limites_ric(valor, 1.5)[1] |
                                 valor > limites_ric(valor, 1.5)[2]),
    `Atípicos (3 RIC)`   = sum(valor < limites_ric(valor, 3)[1] |
                                 valor > limites_ric(valor, 3)[2]),
    `Límite superior (3 RIC)` = limites_ric(valor, 3)[2],
    Máximo = max(valor)
  ) |>
  mutate(`% (3 RIC)` = round(100 * `Atípicos (3 RIC)` / nrow(rot_p5), 1)) |>
  relocate(`% (3 RIC)`, .after = `Atípicos (3 RIC)`)

atipicos |>
  tabla_estilo(titulo = "",
               nota = "RIC: rango intercuartílico. El límite superior corresponde a Q3 + 3×RIC.")
Variable Atípicos (1,5 RIC) Atípicos (3 RIC) % (3 RIC) Límite superior (3 RIC) Máximo
Edad 0 0 0,0 82 60
Distancia_Casa 0 0 0,0 50 29
Ingreso_Mensual 114 0 0,0 24.783 19.999
Trabajos_Anteriores 52 0 0,0 13 9
Porcentaje_Aumento_Salarial 0 0 0,0 36 25
Años_Experiencia 63 0 0,0 42 40
Capacitaciones 238 0 0,0 6 6
Antigüedad 104 19 1,3 27 40
Antigüedad_Cargo 21 0 0,0 22 18
Años_Última_Promoción 107 32 2,2 12 15
Años_Mismo_Jefe 14 0 0,0 22 17
Nota. RIC: rango intercuartílico. El límite superior corresponde a Q3 + 3×RIC.

Tabla 1.7. Valores atípicos según el criterio del rango intercuartílico

Como muestra la Tabla 1.7, el criterio convencional de 1,5* RIC identifica valores atípicos en ocho de las once variables, con conteos que van de 14 a 238 casos. Sin embargo, al aplicar el umbral de 3 * RIC, nueve variables no registran ningún valor extremo y las dos restantes concentran un número reducido: 19 casos en la antigüedad en la empresa (1,3%) y 32 en los años desde la última promoción (2,2%). Esta diferencia puede obedecer a la naturaleza de las variables antes que a la presencia de datos atípicos. El caso de la varaible Capacitaciones muestra que su rango intercuartílico es de apenas una unidad, pues el 50% central de los empleados recibe entre 2 y 3 capacitaciones al año, de modo que cualquier valor distinto de 1 a 4 queda automáticamente señalado. Los 238 casos marcados corresponden en realidad a los empleados con 0, 5 o 6 capacitaciones, todos ellos valores perfectamente válidos dentro de la escala.

datos_num |>
  ggplot(aes(y = valor, fill = Variable)) +
  geom_boxplot(
    color = "#4A4A4A",
    width = 0.60,
    alpha = 0.85,
    outlier.colour = "#B8543F",
    outlier.alpha = 0.55,
    outlier.size = 1.6
  ) +
  facet_wrap(
    ~ Variable,
    scales = "free_y",
    ncol = 4,
    labeller = label_wrap_gen(20)
  ) +
  scale_fill_viridis_d(
    option = "D",
    end = 0.90,
    guide = "none"
  ) +
  labs(
    title = "",
    subtitle = "Los puntos corresponden a valores atípicos según el criterio de 1,5 RIC",
    x = NULL,
    y = NULL
  ) +
  theme_minimal(base_size = 11) +
  theme(
    axis.text.x = element_blank(),
    strip.background = element_blank(),
    strip.text = element_text(
      face = "plain",
      size = 10,
      color = "#333333"
    ),
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    plot.title = element_text(
      face = "bold",
      size = 14,
      hjust = 0.5,
      color = "#21384A"
    ),
    plot.subtitle = element_text(
      size = 10,
      hjust = 0.5,
      color = "#4B5563"
    ),
    panel.spacing = unit(1, "lines"),
    legend.position = "none"
  )

Figura 1.3. Diagramas de caja de las variables cuantitativas

Un examen de los casos señalados bajo el criterio de 3 RIC confirma que se trata de valores posibles y no de errores de registro. Los 19 empleados con más de 27 años de antigüedad y los 32 con más de 12 años sin promoción representan trayectorias prolongadas, consistentes con los valores máximos de experiencia total observados en la base. Ninguna variable presenta valores negativos, imposibles o fuera del rango lógico de su definición, y los límites inferiores del criterio no se activaron en ningún caso, lo que es coherente con la asimetría positiva documentada. Por esta razón se decide conservar la totalidad de las observaciones, dado que estos valores extremos aportan información sustantiva sobre los empleados de mayor permanencia, precisamente el grupo de interés en un análisis de rotación. Sin embargo, la Figura 1.3 (correspondiente a 1,5*RIC) evidencia dos aspectos que conviene señalar como limitación de la fuente: el ingreso mensual se acumula de forma notoria en su valor máximo (19.999) y la distancia al trabajo se interrumpe exactamente en 29, patrones que sugieren que la base original pudo truncar ambas variables en un tope predefinido.

2.1.9 Matriz de Correlaciones entre variables Cuantitativas

Se examinan las relaciones entre las 11 variables cuantitativas mediante el coeficiente de correlación de Spearman, elegido en lugar del de Pearson debido a la asimetría positiva que presentan diez de ellas, según se documentó en el análisis univariado. Este coeficiente se calcula sobre el orden de los valores y no sobre su magnitud, por lo que no requiere el supuesto de normalidad ni resulta sensible a los valores extremos identificados en el paso anterior. Los resultados se representan en una matriz de correlaciones y se resumieron los pares con asociación igual o superior a 0,5, con el fin de anticipar posibles problemas de multicolinealidad en la selección de covariables del modelo.

matriz_cor <- rot_p5 |>
  select(where(is.numeric)) |>
  cor(method = "spearman")

cor_larga <- matriz_cor |>
  as.data.frame() |>
  rownames_to_column("Variable_1") |>
  pivot_longer(-Variable_1, names_to = "Variable_2", values_to = "rho") |>
  mutate(across(c(Variable_1, Variable_2),
                ~ factor(.x, levels = colnames(matriz_cor))))

cor_larga |>
  ggplot(aes(x = Variable_1, y = fct_rev(Variable_2), fill = rho)) +
  geom_tile(color = "white") +
  geom_text(aes(label = format(round(rho, 2), decimal.mark = ","),
                color = abs(rho) > 0.6), size = 3, show.legend = FALSE) +
  scale_fill_gradient2(low = "#b8543f", mid = "white", high = "#21384a",
                       midpoint = 0, limits = c(-1, 1), name = "Rho") +
  scale_color_manual(values = c(`TRUE` = "white", `FALSE` = "#21384a")) +
  labs(title = "",
       x = NULL, y = NULL) +
  theme_minimal(base_size = 11) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title  = element_text(face = "bold", size = 14, hjust = 0.5),
        panel.grid  = element_blank())

Figura 1.4. Matriz de correlaciones de Spearman

La Figura 1.4 muestra una estructura de correlaciones claramente segmentada. Las cuatro variables que miden permanencia en la organización conforman un bloque fuertemente asociado: la antigüedad en la empresa se relaciona con la antigüedad en el cargo actual (rho = 0,85) y con los años trabajando con el mismo jefe (rho = 0,84), y estas dos últimas se asocian entre sí con un coeficiente de 0,72. Este comportamiento es esperado, pues las tres miden aspectos distintos de un mismo fenómeno: quien lleva más tiempo en la empresa tiende a acumular también más tiempo en su cargo y bajo la misma jefatura. A ellas se suman la experiencia laboral total, asociada con la antigüedad (rho = 0,59) y con la edad (rho = 0,66), y los años desde la última promoción, con coeficientes cercanos a 0,5 frente a las dos antigüedades.

También es relevante la asociación entre el ingreso mensual y los años de experiencia (rho = 0,71), el par más alto entre variables de naturaleza distinta. Esto indica que la remuneración en esta organización responde en buena medida a la trayectoria acumulada del empleado, lo que debe considerarse al interpretar el efecto del salario sobre la rotación, ya que ambas variables comparten información. En contraste, tres variables resultan prácticamente independientes del resto: la distancia al lugar de trabajo, el porcentaje de aumento salarial y el número de capacitaciones no superan en ningún caso un coeficiente de 0,05 en valor absoluto. Su independencia las convierte en candidatas atractivas para el modelo, pues aportarían información no contenida en las demás covariables.

cor_larga |>
  filter(as.integer(Variable_1) < as.integer(Variable_2), abs(rho) >= 0.5) |>
  arrange(desc(abs(rho))) |>
  mutate(Rho = round(rho, 2), .keep = "unused") |>
  tabla_estilo(titulo = "",
               alineacion = c("l", "l", "c"))
Variable_1 Variable_2 Rho
Antigüedad Antigüedad_Cargo 0,85
Antigüedad Años_Mismo_Jefe 0,84
Antigüedad_Cargo Años_Mismo_Jefe 0,72
Ingreso_Mensual Años_Experiencia 0,71
Edad Años_Experiencia 0,66
Años_Experiencia Antigüedad 0,59
Antigüedad Años_Última_Promoción 0,52
Antigüedad_Cargo Años_Última_Promoción 0,51

Tabla 1.8. Pares de variables con correlación de Spearman igual o superior a 0,5

La única asociación negativa apreciable se presenta entre el número de trabajos anteriores y las variables de permanencia (rho entre −0,13 y −0,17), coherente con la idea de que los empleados con mayor movilidad previa acumulan menos tiempo en su empleo actual (Ver Tabla 1.8). Así, la selección de covariables del modelo logístico deberá evitar incorporar simultáneamente varias de estas variables, dado que su solapamiento produciría coeficientes inestables y de interpretación ambigua.

2.1.10 Conclusiones del Análisis Exploratorio de Datos

El proceso de exploración y depuración permitió establecer que la base de datos de rotación presenta una calidad de datos alta: no contiene valores ausentes, registros duplicados ni inconsistencias en la escritura de sus categorías, por lo que la totalidad de las 1.470 observaciones se conservó para el análisis. Las intervenciones se limitaron a corregir el tipo de dato de trece variables cuya lectura no correspondía a su naturaleza, en particular cinco escalas ordinales registradas como números, y a depurar las etiquetas de categorías y nombres de variables con fines de presentación.

El análisis identificó además cuatro elementos que condicionan las etapas posteriores: el desbalance de la variable respuesta, con una razón de 5,2 a 1 entre permanencia y rotación; la ausencia de variabilidad relevante en el rendimiento laboral, restringido a los dos niveles superiores de su escala; la fuerte correlación entre las variables de trayectoria, que desaconseja incorporarlas de manera simultánea al modelo; y el posible truncamiento del ingreso mensual y la distancia al trabajo en la fuente original, que debe considerarse como limitación del estudio.

3 Modelo de Regresión Logística para la predicción de rotación de personal

3.1 Variables Seleccionadas e inlcuidas en el modelo

En nuestro caso y, después de una discertación sobre las variables a inlcuir, decidimos incluir covariables combinando el respaldo teórico de la literatura sobre rotación laboral (economía laboral y psicología organizacional) con los hallazgos del análisis exploratorio (EDA del punto 2).

Así, del conjunto inicial de 23 variables explicativas se descartan aquellas que carecen de variabilidad suficiente, las que presentan categorías con un número reducido de observaciones y las que conforman el bloque de trayectoria fuertemente correlacionado identificado en la matriz de correlaciones, del cual se retuvo una única representante. Sobre las seis variables resultantes se formuló una hipótesis explícita acerca del sentido esperado de su relación con la probabilidad de rotación, tal como se resume en la Tabla 3.1.

rotacion_sel <- rotacion_limpia |>
  select(Rotación,
         Horas_Extra, Estado_Civil, Satisfacción_Laboral,
         Edad, Ingreso_Mensual, Antigüedad_Cargo)

variables_sel <- tibble(
  Variable = c("Horas_Extra", "Estado_Civil", "Satisfacción_Laboral",
               "Edad", "Ingreso_Mensual", "Antigüedad_Cargo"),
  Tipo = c("Cualitativa nominal", "Cualitativa nominal", "Cualitativa ordinal",
           "Cuantitativa", "Cuantitativa", "Cuantitativa"),
  `Relación esperada con la rotación` = c(
    "Positiva: mayor probabilidad de rotación en quienes trabajan horas extra",
    "Positiva en solteros frente a casados y divorciados",
    "Negativa: a mayor satisfacción, menor probabilidad de rotación",
    "Negativa: a mayor edad, menor probabilidad de rotación",
    "Negativa: a mayor ingreso, menor probabilidad de rotación",
    "Negativa: a mayor antigüedad en el cargo, menor probabilidad de rotación")
)

variables_sel |>
  tabla_estilo(titulo = "",
               alineacion = c("l", "l", "l"),
               nota = "El signo esperado se refiere al efecto sobre la probabilidad de rotación (y = 1).") |>
  column_spec(3, width = "26em")
Variable Tipo Relación esperada con la rotación
Horas_Extra Cualitativa nominal Positiva: mayor probabilidad de rotación en quienes trabajan horas extra
Estado_Civil Cualitativa nominal Positiva en solteros frente a casados y divorciados
Satisfacción_Laboral Cualitativa ordinal Negativa: a mayor satisfacción, menor probabilidad de rotación
Edad Cuantitativa Negativa: a mayor edad, menor probabilidad de rotación
Ingreso_Mensual Cuantitativa Negativa: a mayor ingreso, menor probabilidad de rotación
Antigüedad_Cargo Cuantitativa Negativa: a mayor antigüedad en el cargo, menor probabilidad de rotación
Nota. El signo esperado se refiere al efecto sobre la probabilidad de rotación (y = 1).

Tabla 3.1. Variables seleccionadas e hipótesis de relación con la rotación

3.2 Elementos teóricos considerados

3.2.1 Hipótesis Variables Cualitativas

Se espera que las horas extras en el trabajo incremente la probabilidad de rotación. La literatura documenta que la sobrecarga laboral y el conflicto entre las demandas del trabajo y la vida personal constituyen antecedentes consistentes de la intención de renuncia, al deteriorar progresivamente la valoración que el empleado hace de su situación actual (Griffeth et al., 2000). En esta base, el 28,3% de los empleados trabaja horas extra, una proporción suficiente para estimar el efecto con precisión razonable. En cuanto al estado civil, se plantea que los empleados solteros presenten mayor probabilidad de rotación que los casados y divorciados. La explicación proviene de la teoría de las apuestas laterales de Becker (1960), según la cual las personas acumulan compromisos externos al trabajo (familiares, financieros, comunitarios) que elevan el costo de abandonar su empleo actual; quienes tienen menos vínculos de este tipo enfrentan un costo de salida menor. Finalmente, se espera una relación negativa entre la satisfacción laboral y la rotación: el modelo de vínculos intermedios de Mobley (1977) establece que la insatisfacción con el trabajo desencadena la búsqueda de alternativas, la evaluación comparativa de estas y, eventualmente, la decisión de renunciar.

3.2.2 Hipótesis Variables Cuantitativas

Para la edad se plantea una relación negativa, ya se que identifica esta variable como uno de los predictores demográficos más estables de la rotación (Griffeth et al., 2000). Los empleados de mayor edad suelen enfrentar un mercado laboral menos favorable y haber consolidado su trayectoria, lo que reduce su propensión al cambio. Respecto al ingreso mensual, se espera igualmente una relación negativa, bajo el argumento de que una remuneración más alta incrementa el costo de oportunidad de renunciar. Conviene anticipar, no obstante, que Allen et al. (2010) advierten que el nivel salarial constituye un predictor más débil de lo que suele suponerse en la práctica organizacional, por lo que el efecto podría resultar menor al esperado. Por último, se plantea que la antigüedad en el cargo actual reduzca la probabilidad de rotación, dado que el tiempo de permanencia refleja el grado de arraigo del empleado en su rol, en su equipo de trabajo y en las rutinas de la organización, un mecanismo que la literatura reciente agrupa bajo el concepto de incrustación laboral (Hom et al., 2017). Esta variable fue seleccionada como representante del bloque de trayectoria por su cercanía conceptual con el fenómeno que interesa estudiar, el cambio de cargo.

3.3 Análisis Univariado de las variables seleccionadas

El análisis univariado caracteriza la variable respuesta y las seis covariables seleccionadas, empleando en cada caso los indicadores que corresponden a su tipo. Las tres variables cuantitativas se describen mediante medidas de tendencia central, dispersión y forma, complementadas con histogramas. Las cuatro variables cualitativas, incluida Rotación, se caracterizan mediante distribuciones de frecuencia absoluta y relativa, representadas en gráficos de barras.

num_sel <- rotacion_sel |>
  select(where(is.numeric)) |>
  pivot_longer(everything(), names_to = "Variable", values_to = "valor") |>
  mutate(Variable = fct_inorder(Variable))

desc_sel <- num_sel |>
  group_by(Variable) |>
  summarise(Media = mean(valor), Mediana = median(valor), DE = sd(valor),
            `CV (%)` = 100 * sd(valor) / mean(valor),
            Mín = min(valor), Q1 = quantile(valor, 0.25),
            Q3 = quantile(valor, 0.75), Máx = max(valor),
            Asimetría = e1071::skewness(valor, type = 2)) |>
  mutate(across(where(is.numeric), ~ round(.x, 2)))

desc_sel |>
  tabla_estilo(titulo = "",
               nota = "DE: desviación estándar; CV: coeficiente de variación.")
Variable Media Mediana DE CV (%) Mín Q1 Q3 Máx Asimetría
Edad 36,92 36 9,14 24,74 18 30 43 60 0,41
Ingreso_Mensual 6.502,93 4.919 4.707,96 72,40 1.009 2.911 8.379 19.999 1,37
Antigüedad_Cargo 4,23 3 3,62 85,67 0 2 7 18 0,92
Nota. DE: desviación estándar; CV: coeficiente de variación.

Tabla 3.2. Estadísticos descriptivos de las covariables cuantitativas

La Tabla 3.2 muestra que la edad de los empleados oscila entre 18 y 60 años, con una media de 36,9 y una mediana de 36. Es la única de las tres variables con distribución aproximadamente simétrica (asimetría de 0,41) y la más homogénea del conjunto, con un coeficiente de variación del 24,7%. El ingreso mensual, en cambio, presenta una fuerte asimetría positiva (1,37): su media de 6.502,93 supera en casi 1.600 unidades a la mediana de 4.919, lo que indica que un grupo reducido de empleados con salarios elevados desplaza el promedio por encima del valor típico. El 50% central de la plantilla de empleados percibe entre 2.911 y 8.379, con un máximo de 19.999. Finalmente, la antigüedad en el cargo actual muestra una mediana de 3 años y una media de 4,2, también con asimetría positiva (0,92) y una dispersión relativa elevada (CV de 85,7%). Un 25% de los empleados lleva dos años o menos en su cargo, mientras que el valor máximo alcanza 18 años. La asimetría de estas dos últimas variables no compromete la estimación del modelo logístico, dado que este no exige normalidad en las covariables (Ver Figura 3.1).

num_sel |>
  ggplot(aes(x = valor)) +
  geom_histogram(bins = 25, fill = "#21384a", color = "white") +
  facet_wrap(~ Variable, scales = "free", ncol = 3,
             labeller = label_wrap_gen(20)) +
  labs(title = "",
       x = NULL, y = "Frecuencia") +
  theme_minimal(base_size = 11) +
  theme(strip.text = element_text(face = "bold", size = 10),
        plot.title = element_text(face = "bold", size = 14, hjust = 0.5))

Figura 3.1. Histograma de Distribución de Frecuencias las covariables cuantitativas

Ahora bien, La Tabla 3.3 muestra que el 28,3% de los empleados trabaja horas extra (416 personas), frente a un 71,7% que no lo hace. En cuanto al estado civil, el grupo predominante es el de los casados, con 673 empleados (45,8%), seguido por los solteros con 470 (32,0%) y los divorciados con 327 (22,2%). Las tres categorías cuentan con un número suficiente de observaciones, lo que permite estimar sus efectos sin riesgo de inestabilidad. La satisfacción laboral presenta una distribución favorable en términos agregados, pero con una proporción apreciable de empleados insatisfechos: el 61,3% se declara satisfecho (30,1%) o muy satisfecho (31,2%), mientras que el 19,0% se manifiesta insatisfecho y el 19,7% muy insatisfecho. Esta variabilidad es precisamente lo que hace útil a la variable como predictor, en contraste con el rendimiento laboral, descartado por concentrarse en un único extremo de su escala (Ver Figura 3.2).

cat_sel <- rotacion_sel |>
  select(where(is.factor)) |>
  imap_dfr(~ tibble(Variable = .y, Categoría = as.character(.x),
                    Orden = as.integer(.x))) |>
  mutate(Variable = fct_inorder(Variable))

cat_sel |>
  count(Variable, Categoría, Orden, name = "Frecuencia") |>
  group_by(Variable) |>
  mutate(`Porcentaje (%)` = round(100 * Frecuencia / sum(Frecuencia), 1)) |>
  ungroup() |>
  arrange(Variable, Orden) |>
  select(-Orden) |>
  tabla_estilo(titulo = "",
               alineacion = c("l", "l", "c", "c")) |>
  collapse_rows(columns = 1, valign = "top")
Variable Categoría Frecuencia Porcentaje (%)
Rotación No 1.233 83,9
Sí 237 16,1
Horas_Extra No 1.054 71,7
Sí 416 28,3
Estado_Civil Casado 673 45,8
Divorciado 327 22,2
Soltero 470 32,0
Satisfacción_Laboral Muy insatisfecho 289 19,7
Insatisfecho 280 19,0
Satisfecho 442 30,1
Muy satisfecho 459 31,2

Tabla 3.3. Distribución de la variable respuesta y de las covariables cualitativas

De los 1.470 empleados que integran la base, 237 registraron rotación, equivalentes al 16,1%, frente a 1.233 que permanecieron en su cargo (83,9%). La razón entre ambos grupos es de 5,2 a 1, lo que evidencia un marcado desbalance entre las categorías de la variable dependiente. Este comportamiento conlleva tres implicaciones metodológicas. En primer lugar, la exactitud global no es un criterio adecuado para evaluar el modelo, pues un clasificador que asignara a todos los empleados a la categoría “No rota” alcanzaría un 83,9% de aciertos sin capacidad discriminante alguna. En segundo lugar, el punto de corte convencional de 0,5 tiende a clasificar como no rotantes a la mayoría de los casos en contextos desbalanceados, por lo que su definición deberá analizarse de forma explícita. En tercer lugar, la magnitud del grupo minoritario, 237 casos, resulta suficiente para estimar seis covariables con precisión razonable, dado que supera ampliamente el criterio orientativo de diez eventos por parámetro habitualmente empleado en regresión logística (Ver Figura 3.2).

niveles_sel <- cat_sel |>
  distinct(Variable, Categoría, Orden) |>
  arrange(Variable, desc(Orden)) |>
  mutate(Etiqueta = paste(Categoría, Variable, sep = "___")) |>
  pull(Etiqueta)

cat_sel |>
  mutate(Etiqueta = factor(paste(Categoría, Variable, sep = "___"),
                           levels = niveles_sel)) |>
  ggplot(aes(y = Etiqueta)) +
  geom_bar(fill = "#21384a", width = 0.7) +
  facet_wrap(~ Variable, scales = "free", ncol = 2,
             labeller = label_wrap_gen(22)) +
  scale_y_discrete(labels = ~ sub("___.*$", "", .x)) +
  labs(title = "",
       x = "Frecuencia", y = NULL) +
  theme_minimal(base_size = 11) +
  theme(strip.text = element_text(face = "bold", size = 10),
        plot.title = element_text(face = "bold", size = 13, hjust = 0.5),
        panel.spacing = unit(1, "lines"))

Figura 3.2. Distribución de la variable respuesta y de las covariables cualitativas

3.4 Análisis Bivariado

El análisis bivariado examina la relación individual de cada covariable con la rotación, codificada como variable binaria en la que el valor 1 corresponde a los empleados que rotaron y el 0 a quienes permanecieron. Para las covariables cualitativas se calcula las tasas de rotación por categoría y se contrasta la independencia respecto de la variable respuesta mediante la prueba chi-cuadrado.

Para las cuantitativas se comparara las distribuciones de ambos grupos a través de medidas de tendencia central y dispersión, y se aplica la prueba de Wilcoxon-Mann-Whitney, elegida en lugar de la prueba t-Student debido a la asimetría documentada en el análisis univariado.

Finalmente, se estima una regresión logística simple por cada covariable, cuyos coeficientes permiten establecer el sentido y la magnitud de la asociación con la probabilidad de rotación, así como su significancia estadística. En el caso de la satisfacción laboral, la variable se trata como factor nominal con la categoría “Baja” como referencia, con el fin de obtener coeficientes directamente interpretables.

3.4.1 Tasas de Rotación por Categoría - Covariables Cualitativas

Las tres variables cualitativas presentan diferencias estadísticamente significativas en la tasa de rotación entre sus categorías (p < 0,001 en las tres pruebas chi-cuadrado). El contraste más pronunciado corresponde al trabajo en horas extra, donde rota el 30,5% de quienes las realizan frente al 10,4% de quienes no, es decir, casi el triple. En cuanto al estado civil, los solteros registran una tasa de rotación del 25,5%, muy por encima de la de casados (12,5%) y divorciados (10,1%). Finalmente, la satisfacción laboral muestra el comportamiento decreciente esperado, es decir, la tasa pasa del 22,8% en el nivel muy insatisfecho al 11,3% en el muy satisfecho (Ver Tabla 3.4 y Figura 3.3).

cat_biv <- rotacion_mod |>
  select(Horas_Extra, Estado_Civil, Satisfacción_Laboral) |>
  imap_dfr(~ tibble(Variable  = .y,
                    Categoría = as.character(.x),
                    Orden     = as.integer(.x),
                    y         = rotacion_mod$y)) |>
  mutate(Variable = fct_inorder(Variable))

tabla_cat_biv <- cat_biv |>
  group_by(Variable, Categoría, Orden) |>
  summarise(Empleados = n(), Rotaron = sum(y), .groups = "drop") |>
  mutate(`Tasa de rotación (%)` = round(100 * Rotaron / Empleados, 1)) |>
  arrange(Variable, Orden) |>
  select(-Orden)

pruebas_cat <- rotacion_mod |>
  select(all_of(covariables[1:3])) |>
  imap_dfr(~ {
    prueba <- chisq.test(table(.x, rotacion_mod$y))
    tibble(Variable = .y,
           `Chi cuadrado` = round(unname(prueba$statistic), 2),
           gl = unname(prueba$parameter),
           `Valor p` = str_replace(
             format.pval(prueba$p.value, digits = 3, eps = 0.001),
             "\\.", ","))
  })

tabla_cat_biv |>
  tabla_estilo(titulo = "",
               alineacion = c("l", "l", "c", "c", "c"),
               nota = paste0("Tasa global de rotación: 16,1 %. Pruebas chi-cuadrado: ",
                             paste(pruebas_cat$Variable, " (p ",
                                   pruebas_cat$`Valor p`, ")", collapse = "; "), ".")) |>
  collapse_rows(columns = 1, valign = "top")
Variable Categoría Empleados Rotaron Tasa de rotación (%)
Horas_Extra No 1.054 110 10,4
Sí 416 127 30,5
Estado_Civil Casado 673 84 12,5
Divorciado 327 33 10,1
Soltero 470 120 25,5
Satisfacción_Laboral Muy insatisfecho 289 66 22,8
Insatisfecho 280 46 16,4
Satisfecho 442 73 16,5
Muy satisfecho 459 52 11,3
Nota. Tasa global de rotación: 16,1 %. Pruebas chi-cuadrado: Horas_Extra (p <0,001 ); Estado_Civil (p <0,001 ); Satisfacción_Laboral (p <0,001 ).

Tabla 3.4. Tasa de rotación según las covariables cualitativas

tabla_cat_biv |>
  mutate(Etiqueta = fct_rev(fct_inorder(paste(Categoría, Variable, sep = "___")))) |>
  ggplot(aes(x = `Tasa de rotación (%)`, y = Etiqueta)) +
  geom_col(fill = "#21384a", width = 0.7) +
  geom_vline(xintercept = 16.1, color = "#b8543f", linetype = "dashed") +
  geom_text(aes(label = format(`Tasa de rotación (%)`, decimal.mark = ",")),
            hjust = -0.2, size = 3.2, color = "#21384a") +
  facet_wrap(~ Variable, scales = "free_y", ncol = 1) +
  scale_y_discrete(labels = ~ sub("___.*$", "", .x)) +
  scale_x_continuous(expand = expansion(mult = c(0, 0.12))) +
  labs(title = "",
       subtitle = "La línea punteada indica la tasa global de rotación (16,1 %)",
       x = "Tasa de rotación (%)", y = NULL) +
  theme_minimal(base_size = 11) +
  theme(strip.text = element_text(face = "bold", size = 10),
        plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
        plot.subtitle = element_text(size = 10, hjust = 0.5))

Figura 3.3. Tasa de rotación por categoría

3.4.2 Tasas de Rotación por Categoría - Covariables Cualitativas

num_biv <- rotacion_mod |>
  select(all_of(covariables[4:6])) |>
  imap_dfr(~ tibble(Variable = .y, valor = .x, Rotación = rotacion_mod$Rotación)) |>
  mutate(Variable = fct_inorder(Variable))

tabla_num_biv <- num_biv |>
  group_by(Variable, Rotación) |>
  summarise(Media = round(mean(valor), 2), Mediana = median(valor),
            DE = round(sd(valor), 2), .groups = "drop") |>
  pivot_wider(names_from = Rotación, values_from = c(Media, Mediana, DE),
              names_sep = " ")

pruebas_num <- rotacion_mod |>
  select(all_of(covariables[4:6])) |>
  imap_dfr(~ tibble(Variable = .y,
                    `Valor p` = str_replace(
                      format.pval(wilcox.test(.x ~ rotacion_mod$Rotación)$p.value,
                                  digits = 3, eps = 0.001),
                      "\\.", ",")))


num_biv |>
  ggplot(aes(x = Rotación, y = valor, fill = Rotación)) +
  geom_boxplot(alpha = 0.85, outlier.alpha = 0.4, width = 0.6) +
  facet_wrap(~ Variable, scales = "free_y", ncol = 3,
             labeller = label_wrap_gen(20)) +
  scale_fill_manual(values = c("No" = "#21384a", "Sí" = "#b8543f")) +
  labs(title = "",
       x = NULL, y = NULL) +
  theme_minimal(base_size = 11) +
  theme(legend.position = "none",
        strip.text = element_text(face = "bold", size = 10),
        plot.title = element_text(face = "bold", size = 14, hjust = 0.5))

Figura 3.4. Covariables cuantitativas según la rotación

La Figura 3.4 y La Tabla 3.5 muestran que las tres variables cuantiativas difieren significativamente entre quienes rotan y quienes permanecen (p < 0,001 en las pruebas de Wilcoxon-Mann-Whitney), y en todos los casos el grupo que rota presenta valores inferiores. Los empleados que rotaron tienen una edad mediana de 32 años frente a 36 entre quienes permanecieron.La diferencia más marcada se observa en el ingreso mensual, donde la mediana de quienes rotan (3.202) equivale a poco más del 60% de la de quienes permanecen (5.204), muestra que el tercer cuartil del grupo que rota se sitúa por debajo de la mediana del grupo que permanece. La antigüedad en el cargo sigue la misma dirección, con una mediana de 2 años entre quienes rotan frente a 3 entre quienes permanecen.

num_biv <- rotacion_mod |>
  select(all_of(covariables[4:6])) |>
  imap_dfr(~ tibble(Variable = .y, valor = .x, Rotación = rotacion_mod$Rotación)) |>
  mutate(Variable = fct_inorder(Variable))

tabla_num_biv <- num_biv |>
  group_by(Variable, Rotación) |>
  summarise(Media = round(mean(valor), 2), Mediana = median(valor),
            DE = round(sd(valor), 2), .groups = "drop") |>
  pivot_wider(names_from = Rotación, values_from = c(Media, Mediana, DE),
              names_sep = " ")

pruebas_num <- rotacion_mod |>
  select(all_of(covariables[4:6])) |>
  imap_dfr(~ tibble(Variable = .y,
                    `Valor p` = str_replace(
                      format.pval(wilcox.test(.x ~ rotacion_mod$Rotación)$p.value,
                                  digits = 3, eps = 0.001),
                      "\\.", ",")))

tabla_num_biv |>
  left_join(pruebas_num, by = "Variable") |>
  tabla_estilo(titulo = "",
               nota = "Valor p correspondiente a la prueba de Wilcoxon-Mann-Whitney.",
               grupos = c(" " = 1, "Media" = 2, "Mediana" = 2,
                          "Desviación estándar" = 2, " " = 1))
Media
Mediana
Desviación estándar
Variable Media No Media Sí Mediana No Mediana Sí DE No DE Sí Valor p
Edad 37,56 33,61 36 32 8,89 9,69 <0,001
Ingreso_Mensual 6.832,74 4.787,09 5.204 3.202 4.818,21 3.640,21 <0,001
Antigüedad_Cargo 4,48 2,90 3 2 3,65 3,17 <0,001
Nota. Valor p correspondiente a la prueba de Wilcoxon-Mann-Whitney.

Tabla 3.5. Comparación de las covariables cuantitativas según la rotación

3.4.3 Regresiones Logísticas Simples

A partir de los resultados de la Tabla 3.5.1, las seis covariables seleccionadas resultan determinantes de la rotación cuando se analizan de forma individual. Ordenadas por la magnitud de su efecto, el trabajo en horas extra encabeza la lista (OR = 3,77), seguido por la condición de soltero (OR = 2,40) y por la satisfacción laboral “Muy satisfecho” como factor protector (OR = 0,43). Entre las cuantitativas, la antigüedad en el cargo presenta el efecto más pronunciado por unidad (OR = 0,864), seguida por la edad (OR = 0,949) y el ingreso mensual.

modelos_simples <- map_dfr(covariables, function(v) {
  formula_v <- as.formula(paste0("y ~ `", v, "`"))
  modelo <- glm(formula_v, data = rotacion_mod, family = binomial)
  broom::tidy(modelo) |>
    filter(term != "(Intercept)") |>
    mutate(escala = if_else(v == "Ingreso_Mensual", 1000, 1)) |>
    transmute(Variable = v,
              Término = str_remove_all(term, paste0("`|", v)),
              Coeficiente = round(estimate * escala, 4),
              `Error estándar` = round(std.error * escala, 4),
              `Valor z` = round(statistic, 2),
              `Valor p` = str_replace(format.pval(p.value, digits = 3, eps = 0.001),
                                      "\\.", ","),
              `OR` = round(exp(estimate * escala), 3))
})

modelos_simples |>
  tabla_estilo(titulo = "",
               alineacion = c("l", "l", "c", "c", "c", "c", "c"),
               nota = "OR: razón de oportunidades (odds ratio). En las variables cualitativas, cada término se compara con la categoría de referencia: No (horas extra), Casado (estado civil) y Baja (satisfacción laboral).") |>
  collapse_rows(columns = 1, valign = "top")
Variable Término Coeficiente Error estándar Valor z Valor p OR
Horas_Extra Sí 1,3274 0,1466 9,06 <0,001 3,771
Estado_Civil Divorciado -0,2395 0,2175 -1,10 0,271 0,787
Soltero 0,8772 0,1575 5,57 <0,001 2,404
Satisfacción_Laboral Insatisfecho -0,4092 0,2137 -1,92 0,0555 0,664
Satisfecho -0,4028 0,1899 -2,12 0,0339 0,668
Muy satisfecho -0,8401 0,2033 -4,13 <0,001 0,432
Edad -0,0523 0,0087 -6,01 <0,001 0,949
Ingreso_Mensual -0,1271 0,0216 -5,88 <0,001 0,881
Antigüedad_Cargo -0,1463 0,0242 -6,03 <0,001 0,864
Nota. OR: razón de oportunidades (odds ratio). En las variables cualitativas, cada término se compara con la categoría de referencia: No (horas extra), Casado (estado civil) y Baja (satisfacción laboral).

Tabla 3.5.1 Regresiones logísticas simples de cada covariable sobre la rotación

Los resultados confirman en su totalidad el sentido esperado de las relaciones formuladas anteriormente. El signo positivo del coeficiente de horas extra respalda la hipótesis de que la sobrecarga laboral incrementa la propensión a la rotación, y su magnitud supera lo anticipado, situándolo como el factor individual más influyente. La hipótesis sobre el estado civil se verifica parcialmente: los solteros efectivamente presentan mayor probabilidad de rotación, en línea con la teoría de las apuestas laterales, pero no se observa una diferencia significativa entre casados y divorciados, lo que matiza el planteamiento inicial que agrupaba a ambos como categorías de menor riesgo.

El signo negativo de la satisfacción laboral concuerda con el modelo de vínculos intermedios, aunque la relación no resulta estrictamente gradual, pues los niveles “Insatisfecho” y “Satisfecho” se comportan de manera equivalente entre sí. En las variables cuantitativas, los tres signos negativos coinciden con lo previsto. Resulta destacable el caso del ingreso mensual: si bien la literatura habla sobre la debilidad del salario como predictor, lo que llevaba a esperar un efecto modesto, el análisis bivariado revela una asociación clara y significativa.

3.5 Estimación del modelo de regresión logística (para variables seleccionadas)

Se estima un modelo de regresión logística binaria en el que la variable respuesta corresponde a la rotación, (y=1 es si rotación, y=0 es no rotación), y las covariables son las seis variables seleccionadas en el punto anterior.

La estimación se realiza por el método de Máxima Verosimilitud (MV) mediante la función de enlace Logit. Las variables cualitativas se incorporan a través de variables indicadoras, tomando como categorías de referencia la ausencia de horas extra, es decir que la variable toma el valor de 1= Si el empleado trabaja horas extras y 0 = en otro caso.

Con respecto al estado civil, la referencia es casado; entonces la variable Soltero es igual a 1= Sí; 0= Otro Caso y, por otro lado, Divorciado es igual a 1 en acaso afirmativo, 0= Otro caso.

Para el nivel de satisfacción laboral la referencia es muy insatisfecho. Entonces, aparecen las categorías “Insatisfecho” = 1; 0= Otro Caso, “Satisfecho”= 1, 0= Otro caso y “Muy Satisfecho”= 1, 0= otro caso.

Por su parte, las variables cuantitativas como el coeficiente del ingreso mensual se expresa por cada 1.000 unidades monetarias, dado que el efecto asociado a una unidad individual resulta imperceptible en la escala de la variable. Además de los coeficientes y su significancia, se calculan las razones de oportunidades con sus intervalos de confianza del 95%, se evalua el ajuste global mediante la prueba de razón de verosimilitud frente al modelo nulo y el pseudo R² de McFadden, y se verifica la ausencia de multicolinealidad a través del factor de inflación de la varianza. El modelo a estimar tiene entonces la forma:

\[ \begin{aligned} \ln\left( \frac{P_i}{1 - P_i} \right) &= \ln\left(\text{Odds}_i\right) \\ &= \beta_0 + \beta_1 \, \text{HorasExtra}_i \\ &\quad + \beta_2 \, \text{Soltero}_i + \beta_3 \, \text{Divorciado}_i \\ &\quad + \beta_4 \, \text{Insatisfecho}_i + \beta_5 \, \text{Satisfecho}_i + \beta_6 \, \text{MuySatisfecho}_i \\ &\quad + \beta_7 \, \text{IngresoMensual}_i + \beta_8 \, \text{Edad}_i + \beta_9 \, \text{AntiguedadCargo}_i. + \varepsilon_i, \end{aligned} \] Donde:

\[ \text{odds}_i = \frac{P_i}{1 - P_i} = \frac{P(Y_i = 1 \mid \mathbf{X}_i)} {1 - P(Y_i = 1 \mid \mathbf{X}_i)}, \]

corresponde a la razón de oportunidades (odds) de que el empleado \(i\) presente rotación, dadas sus características \(\mathbf{X}_i\).

Por tanto, el logaritmo de la razón de oportunidades se expresa como:

\[ \ln(\text{odds}_i) = \ln\left( \frac{P_i}{1 - P_i} \right) = \ln\left( \frac{P(Y_i = 1 \mid \mathbf{X}_i)} {1 - P(Y_i = 1 \mid \mathbf{X}_i)} \right). \]

La variable respuesta se define como:

\[ Y_i = \begin{cases} 1, & \text{si el empleado } i \text{ presenta rotación del cargo}, \\ 0, & \text{si el empleado } i \text{ no presenta rotación del cargo}. \end{cases} \]

En este caso:

  • \(P_i\): probabilidad de que el empleado \(i\) presente rotación del cargo.

  • \(1 - P_i\): probabilidad de que el empleado \(i\) no presente rotación del cargo.

Los resultados de la estimación del modelo se aprecian en el Cuadro 3.1 (salida original en RStudio) y de forma más organizada en la Tabla 3.6

rotacion_mod <- rotacion_mod |>
  mutate(
    Ingreso_Mensual_mil = Ingreso_Mensual / 1000
  )

modelo <- glm(
  y ~ Horas_Extra + Estado_Civil + Satisfacción_Laboral +
    Edad + Ingreso_Mensual_mil + Antigüedad_Cargo,
  data = rotacion_mod,
  family = binomial
)

summary(modelo)
#> 
#> Call:
#> glm(formula = y ~ Horas_Extra + Estado_Civil + Satisfacción_Laboral + 
#>     Edad + Ingreso_Mensual_mil + Antigüedad_Cargo, family = binomial, 
#>     data = rotacion_mod)
#> 
#> Coefficients:
#>                                    Estimate Std. Error z value
#> (Intercept)                         -0.1654     0.3750   -0.44
#> Horas_ExtraSí                        1.5160     0.1596    9.50
#> Estado_CivilDivorciado              -0.3462     0.2303   -1.50
#> Estado_CivilSoltero                  0.8279     0.1717    4.82
#> Satisfacción_LaboralInsatisfecho    -0.4648     0.2357   -1.97
#> Satisfacción_LaboralSatisfecho      -0.4797     0.2083   -2.30
#> Satisfacción_LaboralMuy satisfecho  -1.0788     0.2228   -4.84
#> Edad                                -0.0285     0.0101   -2.83
#> Ingreso_Mensual_mil                 -0.0722     0.0252   -2.87
#> Antigüedad_Cargo                    -0.0993     0.0270   -3.67
#>                                                Pr(>|z|)    
#> (Intercept)                                     0.65925    
#> Horas_ExtraSí                      < 0.0000000000000002 ***
#> Estado_CivilDivorciado                          0.13276    
#> Estado_CivilSoltero                           0.0000014 ***
#> Satisfacción_LaboralInsatisfecho                0.04861 *  
#> Satisfacción_LaboralSatisfecho                  0.02126 *  
#> Satisfacción_LaboralMuy satisfecho            0.0000013 ***
#> Edad                                            0.00460 ** 
#> Ingreso_Mensual_mil                             0.00416 ** 
#> Antigüedad_Cargo                                0.00024 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 1298.6  on 1469  degrees of freedom
#> Residual deviance: 1078.0  on 1460  degrees of freedom
#> AIC: 1098
#> 
#> Number of Fisher Scoring iterations: 5

Cuadro 3.1. Salida del Paquete Estadístico R - Modelo de Regresión Logística

El modelo estimado resulta significativo en su conjunto. la desviación se reduce de 1.298,6 en el modelo nulo a 1.078,0 al incorporar las seis covariables, una ganancia de 220,6 puntos con 9 grados de libertad que supera ampliamente el valor crítico de la distribución chi-cuadrado.

El modelo presentó un pseudo-\(R^2\) de McFadden de:

\[ R^2_{\text{McFadden}} = 1 - \frac{1078.0}{1298.6} \approx 0.170. \] Indicando que el modelo explica el 17% de la desviación del modelo nulo, valor que se considera satisfactorio en regresión logística, donde este indicador alcanza magnitudes sistemáticamente inferiores a las del coeficiente de determinación de la regresión lineal.

El trabajo en horas extra constituye el factor de mayor peso: su coeficiente de 1,5160 equivale a una razón de oportunidades de 4,55 (e^1.1516), de modo que entre empleados equivalentes en las demás características, quienes realizan horas extra presentan oportunidades de rotación 4,55 veces superiores.

3.6 Interpretación de los coeficientes del modelo

La Tabla 3.6 presenta los coeficientes estimados junto con las razones de oportunidades y sus intervalos de confianza al 95%. Ocho de los nueve parámetros resultan significativos al 5%; el único que no alcanza significancia es el correspondiente al estado civil divorciado, cuyo intervalo (0,445 a 1,101) incluye el valor uno y, por tanto, no permite descartar la ausencia de efecto frente a los empleados casados.

El trabajo en horas extra constituye el factor de mayor peso del modelo: su coeficiente de 1,5160 equivale a una razón de oportunidades de 4,55, de modo que, entre empleados equivalentes en las demás características, quienes realizan horas extra presentan oportunidades de rotación 4,55 veces superiores, con un intervalo comprendido entre 3,34 y 6,24 que confirma la robustez del efecto. La condición de soltero multiplica dichas oportunidades por 2,29 respecto a los casados (1,64 a 3,21), mientras que el nivel de satisfacción muy alto las reduce al 34% (exp(-1.0788)) de las observadas entre los empleados muy insatisfechos (0,22 a 0,53).

tabla_modelo |>
  tabla_estilo(
    titulo = paste(
      ""
     
    ),
    alineacion = c("l", "l", "c", "c", "c", "c", "c", "c"),
    nota = paste(
      "Variable respuesta: rotación del cargo (1 = presenta rotación; 0 = no presenta rotación).",
      "OR: razón de oportunidades; IC 95%: intervalo de confianza al 95%.",
      "Categorías de referencia: No (horas extra), Casado (estado civil) y Muy Insatisfecho (satisfacción laboral).",
      "El efecto del ingreso mensual se expresa por cada 1.000 unidades monetarias."
    )
  ) |>
  collapse_rows(
    columns = 1,
    valign = "top"
  )
Variable Categoría Coeficiente (β) Error estándar Valor z Valor p OR IC 95% OR
Horas extra Sí 1,5160 0,1596 9,50 < 0,001 4,554 [3,337; 6,242]
Estado civil Divorciado -0,3462 0,2303 -1,50 0,13276 0,707 [0,445; 1,101]
Soltero 0,8279 0,1717 4,82 < 0,001 2,288 [1,637; 3,212]
Satisfacción laboral Insatisfecho -0,4648 0,2357 -1,97 0,04861 0,628 [0,394; 0,994]
Satisfecho -0,4797 0,2083 -2,30 0,02126 0,619 [0,411; 0,931]
Muy satisfecho -1,0788 0,2228 -4,84 < 0,001 0,340 [0,219; 0,525]
Edad Por cada año adicional -0,0285 0,0101 -2,83 0,00460 0,972 [0,953; 0,991]
Ingreso mensual Por cada 1.000 unidades monetarias -0,0722 0,0252 -2,87 0,00416 0,930 [0,884; 0,976]
Antigüedad en el cargo Por cada año adicional -0,0993 0,0270 -3,67 < 0,001 0,905 [0,858; 0,954]
Nota. Variable respuesta: rotación del cargo (1 = presenta rotación; 0 = no presenta rotación). OR: razón de oportunidades; IC 95%: intervalo de confianza al 95%. Categorías de referencia: No (horas extra), Casado (estado civil) y Muy Insatisfecho (satisfacción laboral). El efecto del ingreso mensual se expresa por cada 1.000 unidades monetarias.

Tabla 3.6. Resultados del modelo de regresión logística múltiple para la rotación del cargo

En cuanto a la satisfacción laboral, los niveles intermedios presentan razones de oportunidades prácticamente idénticas, de 0,628 para los empleados insatisfechos y 0,619 para los satisfechos, con intervalos que se solapan casi por completo, lo que indica que ambos niveles resultan estadísticamente indistinguibles entre sí. Solo el nivel máximo de la escala se diferencia con claridad, pues su intervalo se sitúa por debajo del de los demás niveles. Este patrón sugiere que la reducción del riesgo de rotación no opera de forma gradual a lo largo de la escala, sino que requiere alcanzar la satisfacción plena.

Respecto a las covariables cuantitativas, se evidencian asociaciones inversas y estadísticamente significativas con la rotación del cargo. Manteniendo constantes las demás variables del modelo, por cada año adicional de edad, las razones de oportunidades de rotación se multiplican por \(0,972\) (\(\beta = -0,0285\); \(p = 0,0046\)), lo que equivale a una disminución aproximada del 2,8% en las odds de rotación.

Asimismo, por cada incremento de 1.000 unidades monetarias en el ingreso mensual, las razones de oportunidades de rotación se multiplican por \(0,930\) (\(\beta = -0,0722\); \(p = 0,0042\)). En otras palabras, se asocian con una reducción aproximada del 7,0% en las odds de rotación.

Finalmente, por cada año adicional de antigüedad en el cargo, las razones de oportunidades de rotación se multiplican por \(0,905\) (\(\beta = -0,0993\); \(p < 0,001\)), lo que corresponde a una disminución aproximada del 9,5% en las odds de rotación.

3.7 Ajuste del modelo

Para evaluar el ajuste global del modelo se contrasta el modelo estimado frente a un modelo nulo que incluye únicamente el intercepto y que, por tanto, asigna a todos los empleados la misma probabilidad de rotación, equivalente a la tasa observada en la base. La comparación se realiza mediante la prueba de razón de verosimilitud, que evalúa si la reducción en la desviación obtenida al incorporar las covariables resulta estadísticamente significativa, bajo la hipótesis nula de que todos los coeficientes del modelo son iguales a cero. A partir de las desviaciones de ambos modelos se calcula el pseudo R² de McFadden, definido como la proporción de la desviación del modelo nulo que el modelo estimado logra eliminar, y se reporta adicionalmente el criterio de información de Akaike como referencia para eventuales comparaciones con especificaciones alternativas.

modelo_nulo <- glm(y ~ 1, data = rotacion_mod, family = binomial)

prueba_global <- anova(modelo_nulo, modelo, test = "Chisq")

r2_mcfadden <- 1 - (modelo$deviance / modelo_nulo$deviance)

ajuste <- tibble(
  Indicador = c("Desviación del modelo nulo", "Desviación del modelo estimado",
                "Chi-cuadrado de la prueba de razón de verosimilitud",
                "Grados de libertad", "Valor p", "Pseudo R² de McFadden", "AIC"),
  Valor = c(format(round(modelo_nulo$deviance, 2), decimal.mark = ",", big.mark = "."),
            format(round(modelo$deviance, 2), decimal.mark = ",", big.mark = "."),
            format(round(prueba_global$Deviance[2], 2), decimal.mark = ",", big.mark = "."),
            as.character(prueba_global$Df[2]),
            str_replace(format.pval(prueba_global$`Pr(>Chi)`[2], eps = 0.001), "\\.", ","),
            format(round(r2_mcfadden, 4), decimal.mark = ","),
            format(round(AIC(modelo), 2), decimal.mark = ",", big.mark = "."))
)

ajuste |>
  tabla_estilo(titulo = "",
               alineacion = c("l", "c"))
Indicador Valor
Desviación del modelo nulo 1.299
Desviación del modelo estimado 1.078
Chi-cuadrado de la prueba de razón de verosimilitud 220,6
Grados de libertad 9
Valor p <0,001
Pseudo R² de McFadden 0,1698
AIC 1.098

Tabla 3.7. Indicadores de ajuste global del modelo

La incorporación de las seis covariables reduce la desviación de 1.298,58 en el modelo nulo a 1.078,03 en el modelo estimado, lo que representa una ganancia de 220,55 puntos con 9 grados de libertad. Este valor supera el punto crítico de la distribución chi-cuadrado correspondiente, de 16,92 al nivel de significancia del 5%, por lo que se rechaza la hipótesis nula de que todos los coeficientes sean iguales a cero y se concluye que el modelo resulta globalmente significativo (p < 0,001).

El pseudo R² de McFadden asciende a 0,1698, indica que el modelo explica aproximadamente el 17% de la desviación inicial. Considerando además que la rotación laboral constituye un fenómeno multicausal, en el que intervienen factores no registrados en la base como la existencia de ofertas externas o la calidad de la relación con la jefatura inmediata, el nivel de ajuste alcanzado con seis covariables resulta satisfactorio. El criterio de información de Akaike, de 1.098,03, se reporta como valor de referencia para la comparación con modelos alternativos, careciendo de interpretación sustantiva de manera aislada.

3.8 Verificación de multicolinealidad

Se verifica la ausencia de multicolinealidad entre las covariables mediante el factor de inflación de la varianza, indicador que cuantifica en qué medida la correlación entre predictoras incrementa el error estándar de los coeficientes estimados. Dado que el modelo incluye variables categóricas con más de dos niveles, se reporta el factor ajustado por grados de libertad, que resulta comparable entre variables con distinto número de categorías.

library(car)
library(dplyr)
library(tibble)
library(stringr)

# 1. Calcular VIF/GVIF
vif_modelo <- car::vif(modelo)

# 2. Convertir el resultado a tabla
tabla_vif <- as.data.frame(vif_modelo) |>
  rownames_to_column(var = "Variable")

# 3. Elegir automáticamente VIF o GVIF ajustado
if (all(c("Df", "GVIF^(1/(2*Df))") %in% names(tabla_vif))) {

  tabla_vif <- tabla_vif |>
    transmute(
      Variable = str_replace_all(Variable, "_", " "),
      `Grados de libertad` = Df,
      `VIF ajustado` = round(`GVIF^(1/(2*Df))`, 3)
    )

} else {

  names(tabla_vif)[2] <- "VIF"

  tabla_vif <- tabla_vif |>
    transmute(
      Variable = str_replace_all(Variable, "_", " "),
      VIF = round(VIF, 3)
    )
}

# 4. Mostrar la tabla con la función personalizada
tabla_vif |>
  tabla_estilo(
    titulo = "",
    nota = "Se reporta el VIF o VIF ajustado por grados de libertad, según la estructura de las covariables."
  )
Variable Grados de libertad VIF ajustado
Horas Extra 1 1,022
Estado Civil 2 1,009
Satisfacción Laboral 3 1,005
Edad 1 1,128
Ingreso Mensual mil 1 1,154
Antigüedad Cargo 1 1,049
Nota. Se reporta el VIF o VIF ajustado por grados de libertad, según la estructura de las covariables.

Tabla 3.8. Factor de Inflación de la Varianza de las covariables

Los factores de inflación de la varianza se sitúan entre 1,005 y 1,154, muy por debajo del umbral de referencia, lo que descarta la presencia de multicolinealidad relevante. Los valores más altos corresponden al ingreso mensual (1,154) y a la edad (1,128), coherente con la correlación de Spearman de 0,47 identificada entre ambas en el análisis exploratorio, aunque su magnitud resulta insuficiente para comprometer la estimación.

La proximidad general de los indicadores a la unidad confirma que las seis covariables aportan información sustancialmente independiente y valida la decisión adoptada en la selección de variables de incorporar una única representante del bloque de trayectoria laboral, descartando la antigüedad en la empresa, los años con el mismo jefe y la experiencia total, cuyas correlaciones con la antigüedad en el cargo oscilaban entre 0,49 y 0,85.

3.9 Evaluación del Poder Predictivo del Modelo (Curva ROC y AUC)

El poder predictivo del modelo se evalua mediante la curva ROC y el área bajo la curva. A partir de los coeficientes estimados se calcula la probabilidad de rotación predicha para cada uno de los 1.470 empleados de la base.

Dado que la conversión de estas probabilidades en una clasificación binaria depende del punto de corte adoptado, y que dicha elección modifica el equilibrio entre la detección de casos de rotación y la generación de falsas alarmas, la curva ROC representa la sensibilidad frente a la tasa de falsos positivos a lo largo de todos los umbrales posibles. El área bajo esta curva resume la capacidad discriminante del modelo en un indicador independiente del punto de corte, el cual se reportó junto con su intervalo de confianza del 95 %.

datos_roc <- tibble(
  especificidad = roc_modelo$specificities,
  sensibilidad  = roc_modelo$sensitivities
) |>
  mutate(fpr = 1 - especificidad)

datos_roc |>
  ggplot(aes(x = fpr, y = sensibilidad)) +
  geom_abline(intercept = 0, slope = 1, linetype = "dashed", color = "#b8543f") +
  geom_line(color = "#21384a", linewidth = 1) +
  annotate("text", x = 0.62, y = 0.28,
           label = paste0("AUC = ", format(round(as.numeric(auc_valor), 3),
                                           decimal.mark = ",")),
           color = "#21384a", fontface = "bold", size = 4.5) +
  coord_equal() +
  labs(title = "",
       x = "1 − Especificidad (tasa de falsos positivos)",
       y = "Sensibilidad (tasa de verdaderos positivos)") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold", size = 14, hjust = 0.5))

Figura 3.5. Curva ROC del modelo de regresión logística

El área bajo la curva ROC alcanza un valor de 0,781, con un intervalo de confianza del 95% comprendido entre 0,746 y 0,816. Este resultado indica que, si se seleccionaran al azar un empleado que rotó y otro que permaneció en la organización, el modelo asignaría una probabilidad de rotación mayor al primero en el 78,1% de los casos. Dado que un valor de 0,5 correspondería a una clasificación puramente aleatoria, representada por la diagonal de la Figura 3.5, y que el intervalo de confianza se sitúa íntegramente por encima de ese umbral, la capacidad discriminante del modelo resulta estadísticamente significativa. Conforme a los criterios habitualmente empleados en la literatura, un área comprendida entre 0,7 y 0,8 refleja una discriminación aceptable, de modo que el valor obtenido se ubica en el extremo superior de dicho rango, próximo al umbral de 0,8 a partir del cual la discriminación se considera excelente.

La forma de la curva aporta información adicional de utilidad práctica. Su ascenso resulta particularmente pronunciado en el tramo inicial, donde alcanza una sensibilidad cercana al 60% con una tasa de falsos positivos inferior al 15%, y supera el 75% de sensibilidad con una tasa de falsos positivos próxima al 25%. A partir de ese punto la curva se aplana progresivamente, lo que implica que cada caso de rotación adicional detectado exige clasificar como población en riesgo a un número creciente de empleados que no habrían rotado. Este comportamiento indica que el modelo discrimina con especial eficacia en el extremo de mayor riesgo, condición favorable para su aplicación práctica, es decir, una estrategia de retención dirigida aproximadamente al 20% de los empleados con mayor probabilidad estimada permitiría identificar cerca de tres cuartas partes de los casos de rotación efectiva. Conviene señalar, como limitación, que el área bajo la curva se estimó sobre las mismas observaciones empleadas en el ajuste del modelo, lo que tiende a producir una medida optimista de su desempeño; una evaluación más rigurosa requeriría validarlo sobre una muestra independiente o mediante validación cruzada.

3.10 Simulación con un empleado hipotético

En este caso, se debe crear un perfil hipotético con las mismas variables del modelo calculado y evaluado en la sección aterior, calcular su probabilidad estimada con predict(..., type = "response") y compararla contra un punto de corte. Como el objetivo es intervenir preventivamente para no perder empleados, conviene usar un corte elegido con la curva ROC y el índice de Youden (usado en Ciencia de Datos, que equilibra sensibilidad y especificidad). Como alternativa, se puede elegir un corte más bajo si se prefiere detectar más posibles casos de rotación aunque se generen más falsas alertas. Las probabilidades en un Modelo de Regresión Logística binomial se obtienen con type = "response", luego el corte transforma esas probabilidades en una decisión sí/no.

Este procedimiento se realiza con ayuda de la libreríapROC. El índice de Youden selecciona el umbral que maximiza:

\[J = \text{Sensibilidad} + \text{Especificidad} - 1\] Un corte menor incrementa la sensibilidad y reduce la especificidad; en otras palabras, identificará más empleados con posible rotación, a costa de intervenir en más empleados que finalmente no rotarían.

library(pROC)

prob_entrenamiento <- predict(
  modelo,
  newdata = rotacion_mod,
  type = "response"
)

curva_roc <- roc(
  response = rotacion_mod$y,
  predictor = prob_entrenamiento,
  levels = c(0, 1),
  direction = "<"
)

corte_youden <- coords(
  curva_roc,
  x = "best",
  best.method = "youden",
  ret = c("threshold", "sensitivity", "specificity"),
  transpose = FALSE
)

corte_youden
resultado_prediccion <- empleado_hipotetico |>
  mutate(
    `Probabilidad estimada de rotación` = prob_rotacion,
    `Probabilidad (%)` = paste0(
      format(
        round(prob_rotacion * 100, 1),
        nsmall = 1,
        decimal.mark = ","
      ),
      "%"
    ),
    `Punto de corte` = round(corte, 3),
    Decisión = if_else(
      prob_rotacion >= corte,
      "Intervenir",
      "No intervenir de forma prioritaria"
    )
  ) |>
  pivot_longer(
    cols = everything(),
    names_to = "Característica",
    values_to = "Valor",
    values_transform = list(Valor = as.character)
  ) |>
  mutate(
    Valor = case_when(
      Característica == "Probabilidad estimada de rotación" ~
        format(
          round(as.numeric(Valor), 4),
          nsmall = 4,
          decimal.mark = ","
        ),
      Característica == "Punto de corte" ~
        format(
          round(as.numeric(Valor), 3),
          nsmall = 3,
          decimal.mark = ","
        ),
      TRUE ~ Valor
    ),
    
    Característica = dplyr::recode(
      Característica,
      Horas_Extra = "Horas extra",
      Estado_Civil = "Estado civil",
      Satisfacción_Laboral = "Satisfacción laboral",
      Edad = "Edad (años)",
      Ingreso_Mensual_mil = "Ingreso mensual (miles de unidades monetarias)",
      Antigüedad_Cargo = "Antigüedad en el cargo (años)"
    )
  )

resultado_prediccion |>
  tabla_estilo(
    titulo = "",
    alineacion = c("l", "l"),
    nota = paste(
      "La decisión se basa en la probabilidad estimada por el modelo de regresión logística.",
      "Se recomienda intervenir cuando la probabilidad estimada es igual o superior al punto de corte",
      "seleccionado mediante el índice de Youden."
    )
  )
Característica Valor
Horas extra Sí
Estado civil Soltero
Satisfacción laboral Insatisfecho
Edad (años) 40
Ingreso mensual (miles de unidades monetarias) 4.5
Antigüedad en el cargo (años) 2
Probabilidad estimada de rotación 0,5126
Probabilidad (%) 51,3%
Punto de corte 0,186
Decisión Intervenir
Nota. La decisión se basa en la probabilidad estimada por el modelo de regresión logística. Se recomienda intervenir cuando la probabilidad estimada es igual o superior al punto de corte seleccionado mediante el índice de Youden.

Tabla 3.9. Predicción de rotación para un empleado hipotético

Para ilustrar la aplicación predictiva del modelo, se evaluó un empleado hipotético que realiza horas extra, está soltero(a), presenta un nivel de satisfacción laboral “Insatisfecho”, tiene 40 años, percibe 4.500 unidades monetarias mensuales y cuenta con dos años de antigüedad en el cargo.

El modelo estimó una probabilidad de rotación de 51,3%. Se definió un punto de corte de 0.186, obtenido mediante el índice de Youden a partir de la curva ROC. Dado que la probabilidad estimada supera el punto de corte, se recomienda intervenir preventivamente al empleado mediante acciones de retención o motivación.

library(pROC)
library(ggplot2)
library(dplyr)

# Probabilidades estimadas para todos los empleados
prob_entrenamiento <- predict(
  modelo,
  newdata = rotacion_mod,
  type = "response"
)

# Curva ROC
curva_roc <- pROC::roc(
  response = rotacion_mod$y,
  predictor = prob_entrenamiento,
  levels = c(0, 1),
  direction = "<"
)

# Coordenadas asociadas al punto de corte ya elegido
coord_corte <- pROC::coords(
  curva_roc,
  x = corte,
  input = "threshold",
  ret = c("threshold", "sensitivity", "specificity"),
  transpose = FALSE
)

# Data frame para ggplot
datos_roc <- tibble(
  sensibilidad = curva_roc$sensitivities,
  especificidad = curva_roc$specificities
) |>
  mutate(
    uno_menos_especificidad = 1 - especificidad
  )

# Punto de corte en coordenadas ROC
punto_corte <- tibble(
  corte = as.numeric(coord_corte["threshold"]),
  sensibilidad = as.numeric(coord_corte["sensitivity"]),
  especificidad = as.numeric(coord_corte["specificity"]),
  uno_menos_especificidad = 1 - especificidad
)

# AUC
auc_modelo <- as.numeric(pROC::auc(curva_roc))

ggplot(
  datos_roc,
  aes(x = uno_menos_especificidad, y = sensibilidad)
) +
  geom_abline(
    linetype = "dashed",
    color = "#9CA3AF",
    linewidth = 0.7
  ) +
  geom_line(
    color = "#21384A",
    linewidth = 1.1
  ) +
  geom_point(
    data = punto_corte,
    aes(
      x = uno_menos_especificidad,
      y = sensibilidad
    ),
    inherit.aes = FALSE,
    color = "#B8543F",
    fill = "#B8543F",
    size = 3.5
  ) +
  geom_label(
    data = punto_corte,
    aes(
      x = uno_menos_especificidad,
      y = sensibilidad,
      label = paste0(
        "Corte de Youden = ",
        format(round(corte, 3), decimal.mark = ","),
        "\nSensibilidad = ",
        scales::percent(sensibilidad, accuracy = 0.1, decimal.mark = ","),
        "\nEspecificidad = ",
        scales::percent(especificidad, accuracy = 0.1, decimal.mark = ",")
      )
    ),
    inherit.aes = FALSE,
    hjust = -0.05,
    vjust = 1.1,
    size = 3.2,
    label.size = 0.25,
    fill = "white",
    color = "#21384A"
  ) +
  coord_cartesian(clip = "off") +
  labs(
    title = "",
    subtitle = paste0(
      "AUC = ",
      format(round(auc_modelo, 3), decimal.mark = ","),
      "; punto de corte seleccionado mediante el índice de Youden"
    ),
    x = "1 − Especificidad",
    y = "Sensibilidad"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    plot.title = element_text(
      face = "bold",
      size = 14,
      hjust = 0.5,
      color = "#21384A"
    ),
    plot.subtitle = element_text(
      size = 10,
      hjust = 0.5,
      color = "#4B5563"
    ),
    panel.grid.minor = element_blank(),
    plot.margin = margin(5.5, 80, 5.5, 5.5)
  )

Figura 3.6. Curva ROC y punto de corte óptimo

La curva ROC permitió seleccionar un punto de corte de 0,186 mediante el índice de Youden, criterio que busca equilibrar la sensibilidad y la especificidad del clasificador. En consecuencia, los empleados con una probabilidad estimada de rotación igual o superior a 18,6% se clasifican como de riesgo y se priorizan para una posible intervención preventiva (Ver Figura 3.6).

Para el empleado hipotético evaluado, el modelo estimó una probabilidad de rotación de 51,3%, valor que supera en 32,7 puntos porcentuales el umbral establecido. Por tanto, se recomienda intervenir preventivamente mediante acciones de retención, tales como una entrevista individual, revisión de carga laboral y horas extra, evaluación de satisfacción laboral, alternativas de desarrollo profesional o ajustes de compensación, según el diagnóstico particular del caso (Ver Figura 3.7).

library(ggplot2)

datos_decision <- tibble(
  indicador = "Empleado hipotético",
  probabilidad = as.numeric(prob_rotacion),
  corte = as.numeric(corte)
)

ggplot(datos_decision, aes(x = indicador, y = probabilidad)) +
  geom_col(
    fill = if_else(
      prob_rotacion >= corte,
      "#B8543F",
      "#2A9D8F"
    ),
    width = 0.45,
    alpha = 0.90
  ) +
  geom_hline(
    aes(yintercept = corte),
    color = "#21384A",
    linewidth = 1,
    linetype = "dashed"
  ) +
  geom_text(
    aes(
      y = probabilidad,
      label = paste0(
        scales::percent(probabilidad, accuracy = 0.1, decimal.mark = ","),
        "\nProbabilidad estimada"
      )
    ),
    vjust = -0.5,
    size = 4,
    color = "#333333"
  ) +
  annotate(
    "text",
    x = 1.25,
    y = corte,
    label = paste0(
      "Punto de corte (Youden): ",
      scales::percent(corte, accuracy = 0.1, decimal.mark = ",")
    ),
    hjust = 0,
    vjust = -0.6,
    size = 3.5,
    color = "#21384A"
  ) +
  annotate(
    "label",
    x = 1,
    y = 0.72,
    label = "Decisión: intervenir\npreventivamente",
    fill = "#FDE8E5",
    color = "#8F3523",
    label.size = 0.3,
    size = 3.8
  ) +
  scale_y_continuous(
    labels = scales::percent_format(
      accuracy = 10,
      decimal.mark = ","
    ),
    limits = c(0, 0.80),
    expand = expansion(mult = c(0, 0.08))
  ) +
  labs(
    title = "",
    subtitle = "",
    x = NULL,
    y = "Probabilidad estimada de rotación"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    axis.text.x = element_text(
      color = "#333333",
      size = 11
    ),
    plot.title = element_text(
      face = "bold",
      size = 14,
      hjust = 0.5,
      color = "#21384A"
    ),
    plot.subtitle = element_text(
      size = 10,
      hjust = 0.5,
      color = "#4B5563"
    ),
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank()
  )

**Figura 4.7. Decisión de intervención para un empleado hipotético. Comparación entre la probabilidad estimada de rotación y el punto de corte

4 Conclusiones

El modelo de regresión logística permitió identificar factores asociados significativamente con la rotación del cargo. La realización de horas extra se consolidó como el principal factor de riesgo, mientras que una mayor satisfacción laboral, un mayor ingreso mensual, una mayor edad y una mayor antigüedad en el cargo se asociaron con menores razones de oportunidades de rotación. Adicionalmente, los empleados solteros presentaron una mayor probabilidad relativa de rotación frente a los casados, aunque esta característica debe interpretarse de forma agregada y no utilizarse como un criterio autónomo para decisiones laborales individuales.

Con base en estos resultados, se propone una estrategia integral de retención centrada en factores organizacionales modificables. En primer lugar, la empresa debe monitorear y reducir la exposición sostenida a horas extra mediante una mejor distribución de cargas, revisión de dotación de personal, compensación adecuada y mecanismos de flexibilidad. En segundo lugar, se recomienda fortalecer la satisfacción laboral mediante mediciones periódicas de clima, entrevistas de permanencia, reconocimiento, formación de jefaturas y planes de mejora por equipo. En tercer lugar, es necesario revisar la competitividad y equidad de la compensación total, particularmente en cargos o grupos con mayor riesgo.

Finalmente, conviene reforzar los procesos de inducción, mentoría, formación y desarrollo de carrera durante los primeros años en el cargo, dado que la antigüedad presenta una asociación protectora frente a la rotación. El modelo puede utilizarse como una herramienta de alerta temprana. Bajo el punto de corte de 0,186 seleccionado mediante el índice de Youden, los empleados con una probabilidad estimada igual o superior a dicho valor deben ser priorizados para una conversación preventiva y una evaluación individual de sus condiciones de trabajo, carga laboral, satisfacción, desarrollo y compensación. No obstante, las predicciones deben complementar, y no sustituir, el juicio profesional de los responsables de gestión humana; además, las variables personales, como el estado civil y la edad, no deben emplearse de forma aislada para tomar decisiones adversas o discriminatorias.

5 Referencias

Griffeth, R. W., Hom, P. W., & Gaertner, S. (2000). A meta-analysis of antecedents and correlates of employee turnover: Update, moderator tests, and research implications for the next millennium. Journal of Management, 26(3), 463–488. https://doi.org/10.1177/014920630002600305

Allen, D. G., Bryant, P. C., & Vardaman, J. M. (2010). Retaining talent: Replacing misconceptions with evidence-based strategies. Academy of Management Perspectives, 24(2), 48–64. https://doi.org/10.5465/AMP.2010.51827775

Hom, P. W., Lee, T. W., Shaw, J. D., & Hausknecht, J. P. (2017). One hundred years of employee turnover theory and research. Journal of Applied Psychology, 102(3), 530–545. https://doi.org/10.1037/apl0000103

Mobley, W. H. (1977). Intermediate linkages in the relationship between job satisfaction and employee turnover. Journal of Applied Psychology, 62(2), 237–240.

5.1 Declaración de uso de inteligencia artificial

En la elaboración de este informe se utilizó AI como herramienta de apoyo para la elaboración de código en R y revisión de la presentación de resultados.

La inteligencia artificial no sustituyó el trabajo analítico de los autores. Los datos, definición de variables, depuración, filtrado de observaciones, ejecución de los modelos, obtención de resultados, validación de supuestos, interpretación final y recomendaciones fueron realizadas, revisadas y verificadas por los autores.

los autores asumen plena responsabilidad por la exactitud de los análisis, la verificación de los resultados generados en R, la utilización de las fuentes y el contenido final del documento.

LS0tDQp0aXRsZTogJ0FjdGl2aWRhZCAzOiBSb3RhY2nDs24gZGVsIENhcmdvJw0KYXV0aG9yOiAiUHJvZi4gRGVsaWEgT3J0ZWdhIExlbmlzIC0gRXN0dWRpYW50ZXM6IEVkaXduIExhcmdvIENhw7FhdmVyYWwgJiBDYW1pbG8gQW5kcsOpcyBQdWVudGVzIE1hcsOtbiINCmRhdGU6ICJgciBwYXN0ZShmb3JtYXQoU3lzLkRhdGUoKSwgJyVkJyksICdkZScsIGMoJ2VuZXJvJywnZmVicmVybycsJ21hcnpvJywnYWJyaWwnLCdtYXlvJywnanVuaW8nLCdqdWxpbycsJ2Fnb3N0bycsJ3NlcHRpZW1icmUnLCdvY3R1YnJlJywnbm92aWVtYnJlJywnZGljaWVtYnJlJylbYXMuaW50ZWdlcihmb3JtYXQoU3lzLkRhdGUoKSwgJyVtJykpXSwgJ2RlJywgZm9ybWF0KFN5cy5EYXRlKCksICclWScpKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdGhlbWU6IGZsYXRseQ0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IGZhbHNlDQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlDQogICAgdG9jX2RlcHRoOiAzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIGZpZ19jYXB0aW9uOiB0cnVlDQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgcGRmX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogJzMnDQpsYW5nOiBlcw0KZWRpdG9yX29wdGlvbnM6IA0KICBtYXJrZG93bjogDQogICAgd3JhcDogNzINCi0tLQ0KDQpgYGB7PWh0bWx9DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQovKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KICAgMS4gVElQT0dSQUbDjUEg4oCUIGZ1ZW50ZXMgd2ViIHBhcmEgcXVlIGVsIGRvY3VtZW50byBzZSB2ZWEgaWd1YWwNCiAgICAgIGVuIGN1YWxxdWllciBjb21wdXRhZG9yIHF1ZSBsbyBhYnJhIGRlc2RlIFJQdWJzDQogICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLw0KQGltcG9ydCB1cmwoJ2h0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzMj9mYW1pbHk9U3BlY3RyYWw6aXRhbCx3Z2h0QDAsNDAwOzAsNjAwOzEsNDAwJmZhbWlseT1Tb3VyY2UrU2FucyszOml0YWwsd2dodEAwLDQwMDswLDYwMDswLDcwMDsxLDQwMCZmYW1pbHk9SmV0QnJhaW5zK01vbm86d2dodEA0MDA7NTAwJmRpc3BsYXk9c3dhcCcpOw0KDQo6cm9vdCB7DQogIC0tdGludGE6ICAgICMxYzJiMzY7ICAgLyogdGV4dG8gY29ycmlkbyAgICAgICAgICAgICovDQogIC0tcGl6YXJyYTogICMyMTM4NGE7ICAgLyogdMOtdHVsb3MgeSByZWdsYXMgICAgICAgICAqLw0KICAtLWFjZW50bzogICAjMGY3NjZlOyAgIC8qIGVubGFjZXMgeSBlbGVtZW50b3Mgdml2b3MqLw0KICAtLWdyaXM6ICAgICAjZjVmN2Y4OyAgIC8qIGZvbmRvcyBzdWF2ZXMgICAgICAgICAgICAqLw0KICAtLWJvcmRlOiAgICAjZGZlNWU5OyAgIC8qIGJvcmRlcyBkaXNjcmV0b3MgICAgICAgICAqLw0KICAtLXRlbnVlOiAgICAjNmI3YTg1OyAgIC8qIGxleWVuZGFzIHkgbm90YXMgYWwgcGllICAqLw0KfQ0KDQpib2R5IHsNCiAgZm9udC1mYW1pbHk6ICdTb3VyY2UgU2FucyAzJywgJ09wZW4gU2FucycsICdTZWdvZSBVSScsIHNhbnMtc2VyaWY7DQogIGZvbnQtc2l6ZTogMTZweDsNCiAgbGluZS1oZWlnaHQ6IDEuNjg7DQogIGNvbG9yOiB2YXIoLS10aW50YSk7DQogIHRleHQtYWxpZ246IGp1c3RpZnk7DQogIGh5cGhlbnM6IGF1dG87DQp9DQoNCi8qIEFuY2hvIGRlIGxlY3R1cmEgY8OzbW9kbzogZW50cmUgNjUgeSA3NSBjYXJhY3RlcmVzIHBvciBsw61uZWEgKi8NCi5tYWluLWNvbnRhaW5lciB7DQogIG1heC13aWR0aDogMTEwMHB4Ow0KfQ0KDQovKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KICAgMi4gSkVSQVJRVcONQSBERSBUw41UVUxPUw0KICAgICAgU2VyaWYgcGFyYSBsb3MgZW5jYWJlemFkb3MsIHNhbnMgcGFyYSBlbCBjdWVycG86IGVsIGNvbnRyYXN0ZQ0KICAgICAgaGFjZSB2aXNpYmxlIGxhIGVzdHJ1Y3R1cmEgc2luIG5lY2VzaWRhZCBkZSBzdWJyYXlhZG9zIG5pIGNhamFzDQogICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLw0KaDEudGl0bGUgew0KICBmb250LWZhbWlseTogJ1NwZWN0cmFsJywgR2VvcmdpYSwgc2VyaWY7DQogIGZvbnQtc2l6ZTogMi4xZW07DQogIGZvbnQtd2VpZ2h0OiA2MDA7DQogIGNvbG9yOiB2YXIoLS1waXphcnJhKTsNCiAgbGluZS1oZWlnaHQ6IDEuMjU7DQogIG1hcmdpbi1ib3R0b206IDAuMmVtOw0KICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMS5zdWJ0aXRsZSB7DQogIGZvbnQtZmFtaWx5OiAnU291cmNlIFNhbnMgMycsIHNhbnMtc2VyaWY7DQogIGZvbnQtc2l6ZTogMS4wNWVtOw0KICBmb250LXdlaWdodDogNDAwOw0KICBjb2xvcjogdmFyKC0tdGVudWUpOw0KICBib3JkZXItYm90dG9tOiAycHggc29saWQgdmFyKC0tcGl6YXJyYSk7DQogIHBhZGRpbmctYm90dG9tOiAwLjhlbTsNCiAgbWFyZ2luLWJvdHRvbTogMC42ZW07DQogIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0LmF1dGhvciwgaDQuZGF0ZSB7DQogIGZvbnQtc2l6ZTogMC45MmVtOw0KICBmb250LXdlaWdodDogNDAwOw0KICBjb2xvcjogdmFyKC0tdGVudWUpOw0KICBtYXJnaW46IDAuMTVlbSAwOw0KICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMSwgaDIsIGgzLCBoNCB7DQogIGZvbnQtZmFtaWx5OiAnU3BlY3RyYWwnLCBHZW9yZ2lhLCBzZXJpZjsNCiAgY29sb3I6IHZhcigtLXBpemFycmEpOw0KICB0ZXh0LWFsaWduOiBsZWZ0Ow0KICBmb250LXdlaWdodDogNjAwOw0KfQ0KDQpoMSB7IGZvbnQtc2l6ZTogMS42NWVtOyBtYXJnaW4tdG9wOiAxLjhlbTsgcGFkZGluZy1ib3R0b206IDAuMjVlbTsNCiAgICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWJvcmRlKTsgfQ0KaDIgeyBmb250LXNpemU6IDEuMzJlbTsgbWFyZ2luLXRvcDogMS42ZW07IH0NCmgzIHsgZm9udC1zaXplOiAxLjEyZW07IG1hcmdpbi10b3A6IDEuM2VtOyBmb250LXdlaWdodDogNjAwOyB9DQpoNCB7IGZvbnQtc2l6ZTogMS4wMGVtOyBtYXJnaW4tdG9wOiAxLjFlbTsgZm9udC1zdHlsZTogaXRhbGljOyBmb250LXdlaWdodDogNDAwOyB9DQoNCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQogICAzLiBUQUJMQSBERSBDT05URU5JRE8gRkxPVEFOVEUNCiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovDQojVE9DIHsgZm9udC1zaXplOiAwLjg2ZW07IH0NCg0KLnRvY2lmeSAudG9jaWZ5LWl0ZW0gPiBhIHsgY29sb3I6IHZhcigtLXRlbnVlKTsgfQ0KDQoudG9jaWZ5IC5saXN0LWdyb3VwLWl0ZW0uYWN0aXZlLA0KLnRvY2lmeSAubGlzdC1ncm91cC1pdGVtLmFjdGl2ZTpob3ZlciwNCi50b2NpZnkgLmxpc3QtZ3JvdXAtaXRlbS5hY3RpdmU6Zm9jdXMgew0KICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1waXphcnJhKTsNCiAgYm9yZGVyLWNvbG9yOiB2YXIoLS1waXphcnJhKTsNCiAgY29sb3I6ICNmZmZmZmY7DQp9DQoNCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQogICA0LiBUQUJMQVMg4oCUIGVzdGlsbyBhY2Fkw6ltaWNvIHRpcG8gImJvb2t0YWJzIjoNCiAgICAgIHNvbG8gdHJlcyByZWdsYXMgaG9yaXpvbnRhbGVzLCBzaW4gY3VhZHLDrWN1bGEgY29tcGxldGENCiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovDQoubWFpbi1jb250YWluZXIgdGFibGU6bm90KC5kYXRhVGFibGUpIHsNCiAgd2lkdGg6IGF1dG87DQogIG1pbi13aWR0aDogNTUlOw0KICBtYXJnaW46IDEuNGVtIGF1dG87DQogIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7DQogIGZvbnQtc2l6ZTogMC44OGVtOw0KICBmb250LXZhcmlhbnQtbnVtZXJpYzogdGFidWxhci1udW1zOw0KfQ0KDQoubWFpbi1jb250YWluZXIgdGFibGU6bm90KC5kYXRhVGFibGUpIHRoZWFkIHRoIHsNCiAgYm9yZGVyLXRvcDogMnB4IHNvbGlkIHZhcigtLXBpemFycmEpOw0KICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tcGl6YXJyYSk7DQogIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50Ow0KICBmb250LXdlaWdodDogNjAwOw0KICBjb2xvcjogdmFyKC0tcGl6YXJyYSk7DQogIHBhZGRpbmc6IDhweCAxMnB4Ow0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCi5tYWluLWNvbnRhaW5lciB0YWJsZTpub3QoLmRhdGFUYWJsZSkgdGJvZHkgdGQgew0KICBib3JkZXI6IG5vbmU7DQogIHBhZGRpbmc6IDZweCAxMnB4Ow0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCi8qIGxhIHByaW1lcmEgY29sdW1uYSBzdWVsZSBzZXIgZWwgbm9tYnJlIGRlIGxhIHZhcmlhYmxlOiB2YSBhIGxhIGl6cXVpZXJkYSAqLw0KLm1haW4tY29udGFpbmVyIHRhYmxlOm5vdCguZGF0YVRhYmxlKSB0Ym9keSB0ZDpmaXJzdC1jaGlsZCB7IHRleHQtYWxpZ246IGxlZnQ7IH0NCg0KLm1haW4tY29udGFpbmVyIHRhYmxlOm5vdCguZGF0YVRhYmxlKSB0Ym9keSB0cjpudGgtY2hpbGQoZXZlbikgeyBiYWNrZ3JvdW5kOiB2YXIoLS1ncmlzKTsgfQ0KLm1haW4tY29udGFpbmVyIHRhYmxlOm5vdCguZGF0YVRhYmxlKSB0Ym9keSB0cjpsYXN0LWNoaWxkIHRkICAgeyBib3JkZXItYm90dG9tOiAycHggc29saWQgdmFyKC0tcGl6YXJyYSk7IH0NCg0KY2FwdGlvbiwgcC5jYXB0aW9uIHsNCiAgY2FwdGlvbi1zaWRlOiB0b3A7DQogIHRleHQtYWxpZ246IGxlZnQ7DQogIGZvbnQtc2l6ZTogMC44NmVtOw0KICBmb250LXN0eWxlOiBpdGFsaWM7DQogIGNvbG9yOiB2YXIoLS10ZW51ZSk7DQogIG1hcmdpbi1ib3R0b206IDZweDsNCn0NCg0KLyogbGFzIHRhYmxhcyBwYWdpbmFkYXMgKGRmX3ByaW50OiBwYWdlZCkgY29uc2VydmFuIHN1IHByb3BpbyBkaXNlw7FvICovDQoucGFnZWR0YWJsZSB0YWJsZSwgLnBhZ2VkdGFibGUgdGgsIC5wYWdlZHRhYmxlIHRkIHsgYm9yZGVyOiBub25lICFpbXBvcnRhbnQ7IH0NCg0KLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCiAgIDUuIEPDk0RJR08gWSBTQUxJREFTDQogICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLw0KcHJlLCBjb2RlIHsNCiAgZm9udC1mYW1pbHk6ICdKZXRCcmFpbnMgTW9ubycsICdDb25zb2xhcycsIG1vbm9zcGFjZTsNCiAgZm9udC1zaXplOiAwLjgyZW07DQp9DQoNCnByZSB7DQogIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWdyaXMpOw0KICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ib3JkZSk7DQogIGJvcmRlci1yYWRpdXM6IDVweDsNCiAgcGFkZGluZzogMTJweCAxNHB4Ow0KICBtYXgtaGVpZ2h0OiA0NjBweDsgICAgICAvKiBzYWxpZGFzIGxhcmdhcyBxdWVkYW4gY29uIHNjcm9sbCBwcm9waW8gKi8NCiAgb3ZlcmZsb3cteTogYXV0bzsNCiAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogZnJhbmphIGxhdGVyYWwgcXVlIGRpc3Rpbmd1ZSBlbCBjw7NkaWdvIGZ1ZW50ZSBkZSBzdSBzYWxpZGEgKi8NCnByZS5yLCBkaXYuc291cmNlQ29kZSBwcmUgeyBib3JkZXItbGVmdDogM3B4IHNvbGlkIHZhcigtLWFjZW50byk7IH0NCg0KY29kZTpub3QocHJlIGNvZGUpIHsNCiAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tZ3Jpcyk7DQogIGNvbG9yOiAjYTAzMDMwOw0KICBwYWRkaW5nOiAxcHggNXB4Ow0KICBib3JkZXItcmFkaXVzOiAzcHg7DQp9DQoNCi8qIGJvdG9uZXMgZGUgY29kZV9mb2xkaW5nLCBtw6FzIGRpc2NyZXRvcyAqLw0KLmJ0bi1kZWZhdWx0IHsNCiAgZm9udC1zaXplOiAwLjc4ZW07DQogIGJvcmRlci1jb2xvcjogdmFyKC0tYm9yZGUpOw0KICBjb2xvcjogdmFyKC0tdGVudWUpOw0KfQ0KDQovKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KICAgNi4gQ0lUQVMgWSBDQUpBUyBERSBBUE9ZTw0KICAgICAgRWwgYmxvY2txdW90ZSBxdWVkYSByZXNlcnZhZG8gcGFyYSBsb3MgcMOhcnJhZm9zIGRlIGludGVycHJldGFjacOzbg0KICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8NCmJsb2NrcXVvdGUgew0KICBib3JkZXItbGVmdDogM3B4IHNvbGlkIHZhcigtLWFjZW50byk7DQogIGJhY2tncm91bmQtY29sb3I6ICNmMmY4Zjc7DQogIHBhZGRpbmc6IDE0cHggMThweDsNCiAgbWFyZ2luOiAxLjRlbSAwOw0KICBmb250LXNpemU6IDAuOTdlbTsNCiAgY29sb3I6IHZhcigtLXRpbnRhKTsNCn0NCmJsb2NrcXVvdGUgcDpsYXN0LWNoaWxkIHsgbWFyZ2luLWJvdHRvbTogMDsgfQ0KDQovKiBVc28gZW4gZWwgLlJtZDogIDo6OiB7Lm5vdGF9ICB0ZXh0byAgOjo6ICAgKi8NCi5ub3RhLCAuYWxlcnRhIHsNCiAgcGFkZGluZzogMTJweCAxNnB4Ow0KICBtYXJnaW46IDEuM2VtIDA7DQogIGJvcmRlci1yYWRpdXM6IDAgNXB4IDVweCAwOw0KICBmb250LXNpemU6IDAuOTVlbTsNCn0NCi5ub3RhICAgeyBiYWNrZ3JvdW5kLWNvbG9yOiAjZWVmM2Y3OyBib3JkZXItbGVmdDogM3B4IHNvbGlkIHZhcigtLXBpemFycmEpOyB9DQouYWxlcnRhIHsgYmFja2dyb3VuZC1jb2xvcjogI2ZkZjNlNzsgYm9yZGVyLWxlZnQ6IDNweCBzb2xpZCAjYjU3NTFhOyB9DQoNCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQogICA3LiBGSUdVUkFTIFkgRU5MQUNFUw0KICAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8NCi5maWd1cmUgeyB0ZXh0LWFsaWduOiBjZW50ZXI7IG1hcmdpbjogMS42ZW0gMDsgfQ0KaW1nIHsgbWF4LXdpZHRoOiAxMDAlOyBoZWlnaHQ6IGF1dG87IH0NCg0KYSAgICAgICAgeyBjb2xvcjogdmFyKC0tYWNlbnRvKTsgdGV4dC1kZWNvcmF0aW9uOiBub25lOyB9DQphOmhvdmVyICB7IGNvbG9yOiB2YXIoLS1waXphcnJhKTsgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7IH0NCg0KaHIgeyBib3JkZXI6IDA7IGJvcmRlci10b3A6IDFweCBzb2xpZCB2YXIoLS1ib3JkZSk7IG1hcmdpbjogMi4yZW0gMDsgfQ0KDQovKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KICAgOC4gSU1QUkVTScOTTiAvIEVYUE9SVEFDScOTTiBBIFBERiBERVNERSBFTCBOQVZFR0FET1INCiAgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovDQpAbWVkaWEgcHJpbnQgew0KICBib2R5IHsgZm9udC1zaXplOiAxMXB0OyB9DQogICNUT0MsIC5idG4geyBkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7IH0NCiAgcHJlIHsgbWF4LWhlaWdodDogbm9uZTsgb3ZlcmZsb3c6IHZpc2libGU7IH0NCn0NCg0KPC9zdHlsZT4NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCiAgZWNobyAgICAgICA9IFRSVUUsDQogIHdhcm5pbmcgICAgPSBGQUxTRSwNCiAgbWVzc2FnZSAgICA9IEZBTFNFLA0KICBjb21tZW50ICAgID0gIiM+IiwNCiAgZmlnLmFsaWduICA9ICJjZW50ZXIiLA0KICBmaWcud2lkdGggID0gOCwNCiAgZmlnLmhlaWdodCA9IDQuOCwNCiAgb3V0LndpZHRoICA9ICI4OCUiLA0KICBkcGkgICAgICAgID0gMTEwLA0KICBmaWcucmV0aW5hID0gMg0KKQ0KDQpvcHRpb25zKA0KICBzY2lwZW4gPSA5OTksICAgICAgICAgICAgICAgICAgIyBwcmVjaW9zIGVuIHBlc29zLCBubyBlbiBub3RhY2nDs24gY2llbnTDrWZpY2ENCiAgZGlnaXRzID0gNCwNCiAga25pdHIua2FibGUuTkEgPSAi4oCUIiwgICAgICAgICAgIyBsb3MgYXVzZW50ZXMgc2UgdmVuIGNvbW8gcmF5YSwgbm8gY29tbyAiTkEiDQogIGtuaXRyLnRhYmxlLmZvcm1hdCA9ICJodG1sIiAgICAjIG5lY2VzYXJpbyBwYXJhIHF1ZSBjZWxsX3NwZWMgZ2VuZXJlIEhUTUwNCikNCg0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KHN0cmluZ2Rpc3QpDQpsaWJyYXJ5KHN0cmluZ2kpDQpsaWJyYXJ5KG5hbmlhcikNCmxpYnJhcnkocGF0Y2h3b3JrKQ0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBFc3RpbG8gw7puaWNvIHBhcmEgdG9kYXMgbGFzIHRhYmxhcyBkZWwgaW5mb3JtZS4NCiMgU2kgbcOhcyBhZGVsYW50ZSBxdWllcm8gY2FtYmlhciBjb2xvcmVzIG8gdGFtYcOxbywgbG8gaGFnbyBhcXXDrQ0KIyB5IHNlIGFjdHVhbGl6YSBlbCBkb2N1bWVudG8gY29tcGxldG8uDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KdGFibGFfZXN0aWxvIDwtIGZ1bmN0aW9uKGRmLCB0aXR1bG8gPSBOVUxMLCBub3RhID0gTlVMTCwgZ3J1cG9zID0gTlVMTCwNCiAgICAgICAgICAgICAgICAgICAgICAgICBhbGluZWFjaW9uID0gTlVMTCkgew0KDQogIGlmIChpcy5udWxsKGFsaW5lYWNpb24pKSBhbGluZWFjaW9uIDwtIGMoImwiLCByZXAoImMiLCBuY29sKGRmKSAtIDEpKQ0KDQogIHQgPC0ga2JsKGRmLA0KICAgICAgICAgICBjYXB0aW9uICAgICA9IHRpdHVsbywNCiAgICAgICAgICAgYWxpZ24gICAgICAgPSBhbGluZWFjaW9uLA0KICAgICAgICAgICBlc2NhcGUgICAgICA9IEZBTFNFLA0KICAgICAgICAgICBmb3JtYXQuYXJncyA9IGxpc3QoYmlnLm1hcmsgPSAiLiIsIGRlY2ltYWwubWFyayA9ICIsIikpIHw+DQogICAga2FibGVfc3R5bGluZygNCiAgICAgIGJvb3RzdHJhcF9vcHRpb25zID0gYygiaG92ZXIiLCAiY29uZGVuc2VkIiwgInJlc3BvbnNpdmUiKSwNCiAgICAgIGZ1bGxfd2lkdGggPSBGQUxTRSwNCiAgICAgIHBvc2l0aW9uICAgPSAiY2VudGVyIiwNCiAgICAgIGZvbnRfc2l6ZSAgPSAxMw0KICAgICkgfD4NCiAgICByb3dfc3BlYygwLCBib2xkID0gVFJVRSwgY29sb3IgPSAiIzIxMzg0YSIpIHw+DQogICAgY29sdW1uX3NwZWMoMSwgYm9sZCA9IFRSVUUsIGNvbG9yID0gIiMyMTM4NGEiKQ0KDQogIGlmICghaXMubnVsbChncnVwb3MpKSB7DQogICAgdCA8LSBhZGRfaGVhZGVyX2Fib3ZlKHQsIGdydXBvcywgYmFja2dyb3VuZCA9ICIjZWVmMmY1IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiIzIxMzg0YSIsIGJvbGQgPSBUUlVFKQ0KICB9DQogIGlmICghaXMubnVsbChub3RhKSkgew0KICAgIHQgPC0gZm9vdG5vdGUodCwgZ2VuZXJhbCA9IG5vdGEsIGdlbmVyYWxfdGl0bGUgPSAiTm90YS4iLA0KICAgICAgICAgICAgICAgICAgZm9vdG5vdGVfYXNfY2h1bmsgPSBUUlVFLCB0aXRsZV9mb3JtYXQgPSAiaXRhbGljIikNCiAgfQ0KICB0DQp9DQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIEJhcnJhIGRlIGNvbXBsZXRpdHVkLiBMYSBiYXJyYSBzb2xvIHNlIGxsZW5hIHBvciBjb21wbGV0bw0KIyBjdWFuZG8gbGEgdmFyaWFibGUgbm8gdGllbmUgbmluZ8O6biBhdXNlbnRlLg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmJhcnJhIDwtIGZ1bmN0aW9uKHBjdF9jb21wbGV0bywgbiA9IDEwKSB7DQogIGxsZW5vcyA8LSBpZmVsc2UocGN0X2NvbXBsZXRvID09IDEwMCwgbiwNCiAgICAgICAgICAgICAgICAgICBwbWluKGZsb29yKHBjdF9jb21wbGV0byAvIDEwMCAqIG4pLCBuIC0gMSkpDQogIHBhc3RlMChzdHJyZXAoIuKWiCIsIGxsZW5vcyksIHN0cnJlcCgi4paRIiwgbiAtIGxsZW5vcykpDQp9DQpgYGANCg0KIyBJbnRyb2R1Y2Npw7NuDQoNCkVuIHVuYSBvcmdhbml6YWNpw7NuLCBzZSBidXNjYSBjb21wcmVuZGVyIHkgcHJldmVyIGxvcyBmYWN0b3JlcyBxdWUNCmluZmx1eWVuIGVuIGxhIHJvdGFjacOzbiBkZSBlbXBsZWFkb3MgZW50cmUgZGlzdGludG9zIGNhcmdvcy4gTGEgZW1wcmVzYQ0KaGEgcmVjb3BpbGFkbyBkYXRvcyBoaXN0w7NyaWNvcyBzb2JyZSBlbCBlbXBsZW8gZGUgc3VzIHRyYWJhamFkb3JlcywNCmluY2x1eWVuZG8gdmFyaWFibGVzIGNvbW8gbGEgYW50aWfDvGVkYWQgZW4gZWwgY2FyZ28gYWN0dWFsLCBlbCBuaXZlbCBkZQ0Kc2F0aXNmYWNjacOzbiBsYWJvcmFsLCBlbCBzYWxhcmlvIGFjdHVhbCwgZWRhZCB5IG90cm9zIGZhY3RvcmVzDQpyZWxldmFudGVzLiBMYSBnZXJlbmNpYSBwbGFuZWEgZGVzYXJyb2xsYXIgdW4gbW9kZWxvIGRlIHJlZ3Jlc2nDs24NCmxvZ8Otc3RpY2EgcXVlIHBlcm1pdGEgZXN0aW1hciBsYSBwcm9iYWJpbGlkYWQgZGUgcXVlIHVuIGVtcGxlYWRvIGNhbWJpZQ0KZGUgY2FyZ28gZW4gZWwgcHLDs3hpbW8gcGVyw61vZG8geSBkZXRlcm1pbmFyIGN1YWxlcyBmYWN0b3JlcyBpbmRpY2VuIGVuDQptYXlvciBwcm9wb3JjacOzbiBhIGVzdG9zIGNhbWJpb3MuDQoNCkNvbiBlc3RhIGluZm9ybWFjacOzbiwgbGEgZW1wcmVzYSBwb2Ryw6EgdG9tYXIgbWVkaWRhcyBwcm9hY3RpdmFzIHBhcmENCnJldGVuZXIgYSBzdSB0YWxlbnRvIGNsYXZlLCBpZGVudGlmaWNhciDDoXJlYXMgZGUgbWVqb3JhIGVuIGxhIGdlc3Rpw7NuIGRlDQpyZWN1cnNvcyBodW1hbm9zIHkgZm9tZW50YXIgdW4gYW1iaWVudGUgbGFib3JhbCBtw6FzIGVzdGFibGUgeSB0cmFucXVpbG8uDQpMYSBwcmVkaWNjacOzbiBkZSBsYSBwcm9iYWJpbGlkYWQgZGUgcm90YWNpw7NuIGRlIGVtcGxlYWRvcyBheXVkYXLDoSBhIGxhDQplbXByZXNhIGEgdG9tYXIgZGVjaXNpb25lcyBlc3RyYXTDqWdpY2FzIGluZm9ybWFkYXMgeSBhIG1hbnRlbmVyIHVuDQplcXVpcG8gZGUgdHJhYmFqbyBjb21wcm9tZXRpZG8geSBzYXRpc2ZlY2hvIGVuIHN1cyByb2xlcyBhY3R1YWxlcy4NCg0KIVtdKGltYWdlcy9JbWFnZW4xLmpwZykNCg0KRnVlbnRlOiBUb21hZGEgZGUgcGl4YWJheS5jb20NCg0KRWwgY2FzbyBzb2xpY2l0YToNCg0KMS4gIFNlbGVjY2lvbmFyIDMgdmFyaWFibGVzIGNhdGVnw7NyaWNhcyAoZGlzdGludGFzIGRlIHJvdGFjacOzbikgeSAzDQogICAgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMsIHF1ZSBzZSBjb25zaWRlcmVuIGVzdMOpbiByZWxhY2lvbmFkYXMgY29uIGxhDQogICAgcm90YWNpw7NuLg0KMi4gIFJlYWxpemFyIHVuIGFuw6FsaXNpcyB1bml2YXJpYWRvIChjYXJhY3Rlcml6YWNpw7NuKSBkZSBsYSBpbmZvcm1hY2nDs24NCiAgICBjb250ZW5pZGEgZW4gbGEgYmFzZSBkZSBkYXRvcyByb3RhY2nDs24uDQozLiAgUmVhbGl6YXIgdW4gYW7DoWxpc2lzIGRlIGJpdmFyaWFkbyBlbiBkb25kZSBsYSB2YXJpYWJsZSByZXNwdWVzdGEgc2VhDQogICAgcm90YWNpb24gY29kaWZpY2FkYSBkZSBsYSBzaWd1aWVudGUgbWFuZXJhICh5PTEgZXMgc2kgcm90YWNpw7NuLCB5PTANCiAgICBlcyBubyByb3RhY2nDs24pLiBDb24gYmFzZSBlbiBlc3RvcyByZXN1bHRhZG9zIGlkZW50aWZpcXVlIGN1w6FsZXMgc29uDQogICAgbGFzIHZhcmlhYmxlcyBkZXRlcm1pbmFudGVzIGRlIGxhIHJvdGFjacOzbiBlIGludGVycHJldGFyIGVsIHNpZ25vDQogICAgZGVsIGNvZWZpY2llbnRlIGVzdGltYWRvLiBDb21wYXJlIGVzdG9zIHJlc3VsdGFkb3MgY29uIGxhIGhpcMOzdGVzaXMNCiAgICBwbGFudGVhZGEgZW4gZWwgcHVudG8gMi4NCjQuICBSZWFsaXphciBsYSBlc3RpbWFjacOzbiBkZSB1biBtb2RlbG8gZGUgcmVncmVzacOzbiBsb2fDrXN0aWNvIGVuIGVsDQogICAgY3VhbCBsYSB2YXJpYWJsZSByZXNwdWVzdGEgZXMgcm90YWNpb24gKHk9MSBlcyBzaSByb3RhY2nDs24sIHk9MCBlcw0KICAgIG5vIHJvdGFjacOzbikgeSBsYXMgNiBjb3ZhcmlhYmxlcyBzZWxlY2Npb25hZGFzIGVuIGVsIHB1bnRvIDEuDQogICAgSW50ZXJwcmV0ZSBsb3MgY29lZmljaWVudGVzIGRlbCBtb2RlbG8geSBsYSBzaWduaWZpY2FuY2lhIGRlIGxvcw0KICAgIHBhcsOhbWV0cm9zLg0KNS4gIEV2YWx1YXIgZWwgcG9kZXIgcHJlZGljdGl2byBkZWwgbW9kZWxvIGNvbiBiYXNlIGVuIGxhIGN1cnZhIFJPQyB5IGVsDQogICAgQVVDLg0KNi4gIFJlYWxpemFyIHVuYSBwcmVkaWNjacOzbiBkZSBsYSBwcm9iYWJpbGlkYWQgZGUgcXVlIHVuIGluZGl2aWR1bw0KICAgIChoaXBvdMOpdGljbykgcm90ZSB5IGRlZmluYSB1biBjb3J0ZSBwYXJhIGRlY2lkaXIgc2kgc2UgZGViZQ0KICAgIGludGVydmVuaXIgYSBlc3RlIGVtcGxlYWRvIG8gbm8gKHBvc2libGUgZXN0cmF0ZWdpYSBwYXJhIG1vdGl2YXIgYWwNCiAgICBlbXBsZWFkbykuDQo3LiAgQ29uY2x1aXIgYWRpY2lvbmFuZG8gdW5hIGRpc2N1c2nDs24gc29icmUgY3XDoWwgc2Vyw61hIGxhIGVzdHJhdGVnaWENCiAgICBwYXJhIGRpc21pbnVpciBsYSByb3RhY2nDs24gZW4gbGEgZW1wcmVzYSAoY29uIGJhc2UgZW4gbGFzIHZhcmlhYmxlcw0KICAgIHF1ZSByZXN1bHRhcm9uIHNpZ25pZmljYXRpdmFzIGVuIGVsIHB1bnRvIDMpLg0KDQojIEFuw6FsaXNpcyBFeGxvcmF0b3JpbyBkZSBEYXRvcw0KDQojIyBDYXJnYSBkZWwgRGF0YXNldA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkocGFxdWV0ZU1PREVMT1MpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpsaWJyYXJ5KGUxMDcxKQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KHBhcXVldGVNT0RFTE9TKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQoNCmRhdGEoInJvdGFjaW9uIikNCg0Kcm90YWNpb25fb3JpZ2luYWwgPC0gcm90YWNpb24NCnJvdF9wMSA8LSByb3RhY2lvbl9vcmlnaW5hbA0KDQpkaW1lbnNpb24gPC0gZGltKHJvdF9wMSkNCm51bV92YXIgPC0gZ2xpbXBzZShyb3RfcDEpDQp0YWJsZShzYXBwbHkocm90X3AxLCBjbGFzcykpDQpgYGANCg0KRWwgY29uanVudG8gZGUgZGF0b3MgZW50cmVnYWRvIGNvbnN0YSBkZSBgciBucm93KHJvdGFjaW9uKWAgcmVnaXN0cm9zIHkNCmByIG5jb2wocm90YWNpb24pYCwgZGUgbGFzIGN1YWxlcyA4IGZ1ZXJvbiBsZcOtZGFzIGNvbW8gdGV4dG8geSAxNiBjb21vDQpudW3DqXJpY2FzLiBMYSB2YXJpYWJsZSBkZSBpbnRlcsOpcywgUm90YWNpw7NuLCBlc3TDoSByZWdpc3RyYWRhIGNvbiBsYXMNCmNhdGVnb3LDrWFzICJTaSIgeSAiTm8iLCBwb3IgbG8gcXVlIGRlYmVyw6EgcmVjb2RpZmljYXJzZSBjb21vIHZhcmlhYmxlDQpiaW5hcmlhICgxID0gcm90YSwgMCA9IG5vIHJvdGEpLiBFbnRyZSBsYXMgdmFyaWFibGVzIG51bcOpcmljYXMgc2UNCmlkZW50aWZpY2Fyb24gdmFyaWFzIHF1ZSwgc2Vnw7puIGxvcyB2YWxvcmVzIG9ic2VydmFkb3MsIGNvcnJlc3BvbmRlbiBhDQplc2NhbGFzIG9yZGluYWxlcyBjb2RpZmljYWRhcyBjb24gbsO6bWVyb3MgZW50ZXJvcyB5IG5vIGEgbWFnbml0dWRlcw0KY29udGludWFzOiBFZHVjYWNpw7NuLCBTYXRpc2ZhY2Npw7NuX0FtYmllbnRhbCwgU2F0aXNmYWNpw7NuX0xhYm9yYWwsDQpSZW5kaW1pZW50b19MYWJvcmFsIHkgRXF1aWxpYnJpb19UcmFiYWpvX1ZpZGEuDQoNCiMjIyBEaWNjaW9uYXJpbyBkZSBWYXJpYWJsZXMNCg0KTGEgVGFibGEgMS4xIG11ZXN0cmEgcXVlLCBkZSBsYXMgMjQgdmFyaWFibGVzLCAxMyBzb24gY3VhbGl0YXRpdmFzIHkgMTENCmN1YW50aXRhdGl2YXMuIEVudHJlIGxhcyBjdWFsaXRhdGl2YXMsIDcgc29uIG5vbWluYWxlcywgaW5jbHVpZGEgbGENCnZhcmlhYmxlIHJlc3B1ZXN0YSBSb3RhY2nDs24uIExhcyBvdHJhcyA2IHNvbiBvcmRpbmFsZXMuIEVudHJlIGxhcw0KdmFyaWFibGVzIGN1YW50aXRhdGl2YXMsIDkgc29uIGRpc2NyZXRhcywgZW4gc3UgbWF5b3LDrWEgY29udGVvcyBkZSBhw7Fvcw0KbyBkZSBldmVudG9zLCB5IDIgY29udGludWFzOiBlbCBpbmdyZXNvIG1lbnN1YWwgeSBlbCBwb3JjZW50YWplIGRlDQphdW1lbnRvIHNhbGFyaWFsLg0KDQpgYGB7ciwgfQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoa2FibGVFeHRyYSkNCg0KdmFsb3Jlc19vYnNlcnZhZG9zIDwtIGZ1bmN0aW9uKHgpIHsNCiAgaWYgKGlzLm51bWVyaWMoeCkpIHsNCiAgICBwYXN0ZTAobWluKHgsIG5hLnJtID0gVFJVRSksICIg4oCTICIsIG1heCh4LCBuYS5ybSA9IFRSVUUpKQ0KICB9IGVsc2Ugew0KICAgIHBhc3RlKHNvcnQodW5pcXVlKHgpKSwgY29sbGFwc2UgPSAiLCAiKQ0KICB9DQp9DQoNCnJhbmdvcyA8LSB1bm5hbWUoc2FwcGx5KHJvdF9wMSwgdmFsb3Jlc19vYnNlcnZhZG9zKSkNCg0KZGljY2lvbmFyaW8gPC0gdGliYmxlKA0KICBWYXJpYWJsZSA9IG5hbWVzKHJvdF9wMSksDQogIERlc2NyaXBjacOzbiA9IGMoDQogICAgIkluZGljYSBzaSBlbCBlbXBsZWFkbyBwcmVzZW50w7Mgcm90YWNpw7NuIiwNCiAgICAiRWRhZCBkZWwgZW1wbGVhZG8gZW4gYcOxb3MiLA0KICAgICJGcmVjdWVuY2lhIGNvbiBxdWUgZWwgZW1wbGVhZG8gcmVhbGl6YSB2aWFqZXMgZGUgbmVnb2Npb3MiLA0KICAgICLDgXJlYSBkZSBsYSBlbXByZXNhIGEgbGEgcXVlIHBlcnRlbmVjZSBlbCBlbXBsZWFkbyIsDQogICAgIktpbMOzbWV0cm9zIGRlIGRpc3RhbmNpYSBkZXNkZSBsYSBjYXNhIiwNCiAgICAiTml2ZWwgZWR1Y2F0aXZvICgxID0gcHJpbWFyaWEsIDIgPSBzZWN1bmRhcmlhLCAzID0gdMOpY25pY28vdGVjbsOzbG9nbyA0ID0gcHJlZ3JhZG8geSA1PXBvc2dyYWRvKSIsDQogICAgIsOBcmVhIGRlIGZvcm1hY2nDs24gYWNhZMOpbWljYSBkZWwgZW1wbGVhZG8iLA0KICAgICJTYXRpc2ZhY2Npw7NuIGNvbiBlbCBhbWJpZW50ZSBkZSB0cmFiYWpvICgxID0gTXV5IGluc2F0aXNmZWNobywgMiA9IEluc2F0aXNmZWNobywgMyA9IFNhdGlzZmVjaG8geSA0ID0gTXV5IHNhdGlzZmVjaG8pIiwNCiAgICAiR8OpbmVybyBkZWwgZW1wbGVhZG8iLA0KICAgICJDYXJnbyBxdWUgb2N1cGEgZWwgZW1wbGVhZG8iLA0KICAgICJTYXRpc2ZhY2Npw7NuIGNvbiBlbCB0cmFiYWpvIHF1ZSByZWFsaXphICgxID0gTXV5IGluc2F0aXNmZWNobywgMiA9IEluc2F0aXNmZWNobywgMyA9IFNhdGlzZmVjaG8geSA0ID0gTXV5IHNhdGlzZmVjaG8pIiwNCiAgICAiRXN0YWRvIGNpdmlsIGRlbCBlbXBsZWFkbyIsDQogICAgIkluZ3Jlc28gbWVuc3VhbCBkZWwgZW1wbGVhZG8iLA0KICAgICJOw7ptZXJvIGRlIGVtcHJlc2FzIGVuIGxhcyBxdWUgaGEgdHJhYmFqYWRvIGFudGVyaW9ybWVudGUiLA0KICAgICJJbmRpY2Egc2kgZWwgZW1wbGVhZG8gdHJhYmFqYSBob3JhcyBleHRyYSIsDQogICAgIlBvcmNlbnRhamUgZGUgYXVtZW50byBzYWxhcmlhbCBlbiBlbCDDumx0aW1vIGHDsW8iLA0KICAgICJDYWxpZmljYWNpw7NuIGRlIGRlc2VtcGXDsW8gKDEgPSBiYWpvLCAyID0gbWVkaW8sIDMgPSBhbHRvLCA0ID0gTXV5IGFsdG8pIiwNCiAgICAiVG90YWwgZGUgYcOxb3MgZGUgZXhwZXJpZW5jaWEgbGFib3JhbCIsDQogICAgIk7Dum1lcm8gZGUgY2FwYWNpdGFjaW9uZXMgcmVjaWJpZGFzIGVuIGVsIMO6bHRpbW8gYcOxbyIsDQogICAgIkVxdWlsaWJyaW8gZW50cmUgdHJhYmFqbyB5IHZpZGEgcGVyc29uYWwgKDEgPSBNdXkgYmFqbywgMiA9IGJham8sIDMgPSBNZWRpbywgNCA9IGFsdG8pIiwNCiAgICAiQcOxb3MgZGUgYW50aWfDvGVkYWQgZW4gbGEgZW1wcmVzYSIsDQogICAgIkHDsW9zIGVuIGVsIGNhcmdvIGFjdHVhbCIsDQogICAgIkHDsW9zIHRyYW5zY3Vycmlkb3MgZGVzZGUgbGEgw7psdGltYSBwcm9tb2Npw7NuIiwNCiAgICAiQcOxb3MgdHJhYmFqYW5kbyBjb24gZWwgbWlzbW8gamVmZSINCiAgKSwNCiAgVGlwbyA9IGMoDQogICAgIkN1YWxpdGF0aXZhIGJpbmFyaWEiLCAiQ3VhbnRpdGF0aXZhIGRpc2NyZXRhIiwgIkN1YWxpdGF0aXZhIG9yZGluYWwiLA0KICAgICJDdWFsaXRhdGl2YSBub21pbmFsIiwgIkN1YW50aXRhdGl2YSBkaXNjcmV0YSIsICJDdWFsaXRhdGl2YSBvcmRpbmFsIiwNCiAgICAiQ3VhbGl0YXRpdmEgbm9taW5hbCIsICJDdWFsaXRhdGl2YSBvcmRpbmFsIiwgIkN1YWxpdGF0aXZhIG5vbWluYWwiLA0KICAgICJDdWFsaXRhdGl2YSBub21pbmFsIiwgIkN1YWxpdGF0aXZhIG9yZGluYWwiLCAiQ3VhbGl0YXRpdmEgbm9taW5hbCIsDQogICAgIkN1YW50aXRhdGl2YSBjb250aW51YSIsICJDdWFudGl0YXRpdmEgZGlzY3JldGEiLCAiQ3VhbGl0YXRpdmEgbm9taW5hbCIsDQogICAgIkN1YW50aXRhdGl2YSBjb250aW51YSIsICJDdWFsaXRhdGl2YSBvcmRpbmFsIiwgIkN1YW50aXRhdGl2YSBkaXNjcmV0YSIsDQogICAgIkN1YW50aXRhdGl2YSBkaXNjcmV0YSIsICJDdWFsaXRhdGl2YSBvcmRpbmFsIiwgIkN1YW50aXRhdGl2YSBkaXNjcmV0YSIsDQogICAgIkN1YW50aXRhdGl2YSBkaXNjcmV0YSIsICJDdWFudGl0YXRpdmEgZGlzY3JldGEiLCAiQ3VhbnRpdGF0aXZhIGRpc2NyZXRhIg0KICApLA0KICBgVmFsb3JlcyBvYnNlcnZhZG9zYCA9IHJhbmdvcw0KKQ0KDQpkaWNjaW9uYXJpbyB8Pg0KICB0YWJsYV9lc3RpbG8odGl0dWxvID0gIiIsDQogICAgICAgICAgICAgICBhbGluZWFjaW9uID0gYygibCIsICJsIiwgImMiLCAibCIpKSB8Pg0KICBjb2x1bW5fc3BlYygyLCB3aWR0aCA9ICIyMmVtIikNCg0KDQpgYGANCg0KKlRhYmxhIDEuMS4gRGljY2lvbmFyaW8gZGUgdmFyaWFibGVzIGRlIGxhIGJhc2Ugcm90YWNpw7NuKg0KDQojIyMgVmFsb3JlcyBBdXNlbnRlcw0KDQpObyBzZSBlbmNvbnRyYXJvbiB2YWxvcmVzIGF1c2VudGVzIGVuIG5pbmd1bmEgdmFyaWFibGVzIHkgdGFtcG9jbw0KcmVnaXN0cm9zIGluY29tcGxldG9zLCBjZWxkYXMgdmFjw61hcyBvIGNvbXB1ZXN0YXMgZGUgZXNwYWNpb3MuRW4NCmNvbnNlY3VlbmNpYSwgZWwgZGF0YXNldCBubyByZXF1aXJpw7MgaW1wdXRhY2nDs24gbmkgZWxpbWluYWNpw7NuIGRlDQpyZWdpc3Ryb3MsIHkgbG9zIGFuw6FsaXNpcyBwb3N0ZXJpb3JlcyBzZSByZWFsaXphcm9uIHNvYnJlIGxhIHRvdGFsaWRhZA0KZGUgbGFzIG9ic2VydmFjaW9uZXMuDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0Kcm90X3AyIDwtIHJvdF9wMQ0KDQpjb2xTdW1zKGlzLm5hKHJvdF9wMikpDQoNCnN1bShpcy5uYShyb3RfcDIpKQ0KDQpzdW0oIWNvbXBsZXRlLmNhc2VzKHJvdF9wMikpDQoNCnJvdF9wMiAlPiUNCiAgc2VsZWN0KHdoZXJlKGlzLmNoYXJhY3RlcikpICU+JQ0KICBzYXBwbHkoZnVuY3Rpb24oeCkgc3VtKHRyaW13cyh4KSA9PSAiIikpDQpgYGANCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQpvcHRpb25zKGtuaXRyLmthYmxlLk5BID0gIuKAlCIpDQoNCnRhYmxhX2F1c2VudGVzIDwtIHRpYmJsZSgNCiAgVmFyaWFibGUgPSBuYW1lcyhyb3RfcDIpLA0KICBgVGlwbyBlbiBSYCA9IHVubmFtZShzYXBwbHkocm90X3AyLCBjbGFzcykpLA0KICBgVmFsb3JlcyBOQWAgPSB1bm5hbWUoY29sU3Vtcyhpcy5uYShyb3RfcDIpKSksDQogIGBDZWxkYXMgdmFjw61hc2AgPSB1bm5hbWUoc2FwcGx5KHJvdF9wMiwgZnVuY3Rpb24oeCkgew0KICAgIGlmIChpcy5jaGFyYWN0ZXIoeCkpIHN1bSh0cmltd3MoeCkgPT0gIiIpIGVsc2UgTkENCiAgfSkpDQopIHw+DQogIG11dGF0ZShgJSBhdXNlbnRlc2AgPSByb3VuZCgxMDAgKiAoYFZhbG9yZXMgTkFgICsgY29hbGVzY2UoYENlbGRhcyB2YWPDrWFzYCwgMEwpKSAvDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5yb3cocm90X3AyKSwgMikpDQoNCnRhYmxhX2F1c2VudGVzIHw+DQogIHRhYmxhX2VzdGlsbyh0aXR1bG8gPSAiVGFibGEgMS4yLiBWYWxvcmVzIGF1c2VudGVzIHBvciB2YXJpYWJsZSIsDQogICAgICAgICAgICAgICBub3RhID0gcGFzdGUwKCJMYSByZXZpc2nDs24gZGUgY2VsZGFzIHZhY8OtYXMgc29sbyBhcGxpY2EgYSB2YXJpYWJsZXMgZGUgdGV4dG87ICIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJlbCBndWlvbiAo4oCUKSBpbmRpY2EgcXVlIG5vIGFwbGljYS4gIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlZ2lzdHJvcyBjb24gYWwgbWVub3MgdW4gZGF0byBmYWx0YW50ZTogIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtKCFjb21wbGV0ZS5jYXNlcyhyb3RfcDIpKSwgIiBkZSAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBucm93KHJvdF9wMiksICIuIikpDQpgYGANCg0KIyMjIFJldmlzacOzbiBUaXBvcyBkZSBWYXJpYWJsZQ0KDQpMYSBUYWJsYSAxLjIgbXVlc3RyYSBxdWUsIGNvbiBiYXNlIGVuIGxhIGNsYXNpZmljYWNpw7NuIGRlbCBkaWNjaW9uYXJpbw0KZGUgdmFyaWFibGVzIChUYWJsYSAxLjEpLCBzZSBjb3JyaWdlIGVsIHRpcG8gZGUgZGF0byBkZSBsYXMgdmFyaWFibGVzDQpxdWUgbm8gY29ycmVzcG9uZMOtYSBhIHN1IG5hdHVyYWxlemEuIExhcyB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzDQpub21pbmFsZXMgc2UgY29udmlydGVuIGVuIGZhY3RvcmVzLiBMYXMgb3JkaW5hbGVzLCB0YW50byBsYSBmcmVjdWVuY2lhDQpkZSB2aWFqZXMgZGUgbmVnb2Npb3MgY29tbyBsYXMgY2luY28gZXNjYWxhcyByZWdpc3RyYWRhcyBudW3DqXJpY2FtZW50ZSwNCnNlIHRyYW5zZmFuIGVuIGZhY3RvcmVzIG9yZGVuYWRvcywgYXNpZ25hbmRvIGEgY2FkYSBjw7NkaWdvIHN1IGV0aXF1ZXRhLg0KRW4gbGEgdmFyaWFibGUgUm90YWNpw7NuIHNlIGZpasOzIGxhIGNhdGVnb3LDrWEgIk5vIiBjb21vIG5pdmVsIGRlDQpyZWZlcmVuY2lhLiBQYXJhIHZlcmlmaWNhciBxdWUgbGEgY29udmVyc2nDs24gbm8gZ2VuZXJhcmEgcMOpcmRpZGEgZGUNCmluZm9ybWFjacOzbiwgc2UgY29tcHJ1ZWJhIHF1ZSBuaW5nw7puIHZhbG9yIHF1ZWRlIHNpbiBjYXRlZ29yw61hIGFzaWduYWRhLg0KDQpgYGB7cn0NCnJvdF9wMyA8LSByb3RfcDIgfD4NCiAgbXV0YXRlKA0KICAgIGFjcm9zcyhjKERlcGFydGFtZW50bywgQ2FtcG9fRWR1Y2FjacOzbiwgR2VuZXJvLCBDYXJnbywgRXN0YWRvX0NpdmlsLCBIb3Jhc19FeHRyYSksDQogICAgICAgICAgIGFzLmZhY3RvciksDQogICAgUm90YWNpw7NuID0gZmFjdG9yKFJvdGFjacOzbiwgbGV2ZWxzID0gYygiTm8iLCAiU2kiKSksDQogICAgYFZpYWplIGRlIE5lZ29jaW9zYCA9IGZhY3RvcihgVmlhamUgZGUgTmVnb2Npb3NgLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTm9fVmlhamEiLCAiUmFyYW1lbnRlIiwgIkZyZWN1ZW50ZW1lbnRlIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSksDQogICAgRWR1Y2FjacOzbiA9IGZhY3RvcihFZHVjYWNpw7NuLCBsZXZlbHMgPSAxOjUsDQogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIlByaW1hcmlhIiwgIlNlY3VuZGFyaWEiLCAiVMOpY25pY28vVGVjbsOzbG9nbyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlByZWdyYWRvIiwgIlBvc2dyYWRvIiksDQogICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSwNCiAgICBhY3Jvc3MoYyhTYXRpc2ZhY2Npw7NuX0FtYmllbnRhbCwgU2F0aXNmYWNpw7NuX0xhYm9yYWwpLA0KICAgICAgICAgICB+IGZhY3RvcigueCwgbGV2ZWxzID0gMTo0LA0KICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJNdXkgaW5zYXRpc2ZlY2hvIiwgIkluc2F0aXNmZWNobyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNhdGlzZmVjaG8iLCAiTXV5IHNhdGlzZmVjaG8iKSwNCiAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSwNCiAgICBSZW5kaW1pZW50b19MYWJvcmFsID0gZmFjdG9yKFJlbmRpbWllbnRvX0xhYm9yYWwsIGxldmVscyA9IDE6NCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkJham8iLCAiTWVkaW8iLCAiQWx0byIsICJNdXkgYWx0byIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpLA0KICAgIEVxdWlsaWJyaW9fVHJhYmFqb19WaWRhID0gZmFjdG9yKEVxdWlsaWJyaW9fVHJhYmFqb19WaWRhLCBsZXZlbHMgPSAxOjQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiTXV5IGJham8iLCAiQmFqbyIsICJNZWRpbyIsICJBbHRvIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpDQogICkNCg0KIyBzdW0oaXMubmEocm90X3AzKSkNCg0KdGFibGFfdGlwb3MgPC0gdGliYmxlKA0KICBWYXJpYWJsZSA9IG5hbWVzKHJvdF9wMyksDQogIGBUaXBvIG9yaWdpbmFsYCA9IHVubmFtZShzYXBwbHkocm90X3AyLCBmdW5jdGlvbih4KSBjbGFzcyh4KVsxXSkpLA0KICBgVGlwbyBjb3JyZWdpZG9gID0gdW5uYW1lKHNhcHBseShyb3RfcDMsIGZ1bmN0aW9uKHgpIGNsYXNzKHgpWzFdKSkNCikNCg0KdGFibGFfdGlwb3MgfD4NCiAgdGFibGFfZXN0aWxvKHRpdHVsbyA9ICIiKQ0KYGBgDQoNCipUYWJsYSAxLjIuIFRpcG8gZGUgZGF0byBkZSBsYXMgdmFyaWFibGVzIGFudGVzIHkgZGVzcHXDqXMgZGUgbGENCmNvcnJlY2Npw7NuKg0KDQpUcmFzIGxhIGNvcnJlY2Npw7NuLCBlbCBkYXRhc2V0IHF1ZWTDsyBjb25mb3JtYWRvIHBvciA3IGZhY3RvcmVzDQpub21pbmFsZXMsIDYgZmFjdG9yZXMgb3JkZW5hZG9zIHkgMTEgdmFyaWFibGVzIG51bcOpcmljYXMsIGVuDQpjb3JyZXNwb25kZW5jaWEgY29uIGxhIGNsYXNpZmljYWNpw7NuIGVzdGFibGVjaWRhIGVuIGVsIGRpY2Npb25hcmlvDQooVGFibGEgMS4xKS4gTGFzIDggdmFyaWFibGVzIGxlw61kYXMgb3JpZ2luYWxtZW50ZSBjb21vIHRleHRvIHBhc2Fyb24gYQ0Kc2VyIGNhdGVnw7NyaWNhcy4gQWRlbcOhcywgY2luY28gdmFyaWFibGVzIHJlZ2lzdHJhZGFzIGNvbW8gbsO6bWVyb3MNCihFZHVjYWNpw7NuLCBTYXRpc2ZhY2Npw7NuX0FtYmllbnRhbCwgU2F0aXNmYWNpw7NuX0xhYm9yYWwsDQpSZW5kaW1pZW50b19MYWJvcmFsIHkgRXF1aWxpYnJpb19UcmFiYWpvX1ZpZGEpIGRlamFyb24gZGUgdHJhdGFyc2UgY29tbw0KY2FudGlkYWRlcyB5IHBhc2Fyb24gYSByZXByZXNlbnRhcnNlIGNvbW8gbml2ZWxlcyBvcmRlbmFkb3MuIExhDQp2ZXJpZmljYWNpw7NuIHBvc3RlcmlvciBubyByZWdpc3Ryw7MgdmFsb3JlcyBzaW4gY2F0ZWdvcsOtYSBhc2lnbmFkYSwgbG8NCnF1ZSBjb25maXJtYSBxdWUgdG9kb3MgbG9zIGPDs2RpZ29zIHByZXNlbnRlcyBlbiBsYSBiYXNlIGNvcnJlc3BvbmTDrWFuIGENCm5pdmVsZXMgdsOhbGlkb3MgZGUgc3VzIHJlc3BlY3RpdmFzIGVzY2FsYXMuDQoNCiMjIyBSZXZpc2nDs24gZGUgbGFzIENhdGVnb3LDrWFzDQoNClNlIHJldmlzYSBsYSBjb25zaXN0ZW5jaWEgZGUgbGFzIGNhdGVnb3LDrWFzIGRlIGxhcyAxMyB2YXJpYWJsZXMNCmN1YWxpdGF0aXZhcyBjb24gZWwgcHJvcMOzc2l0byBkZSBkZXRlY3RhciB1bmEgbWlzbWEgY2F0ZWdvcsOtYSByZWdpc3RyYWRhDQpkZSBmb3JtYXMgZGlzdGludGFzLiBQYXJhIGVsbG8gc2UgY29tcGFyYSBlbCBuw7ptZXJvIGRlIGNhdGVnb3LDrWFzIGRlDQpjYWRhIHZhcmlhYmxlIGFudGVzIHkgZGVzcHXDqXMgZGUgbm9ybWFsaXphciBlbCB0ZXh0bywgbG8gcXVlIGltcGxpY8OzDQpjb252ZXJ0aXJsbyBhIG1pbsO6c2N1bGFzLCBlbGltaW5hciB0aWxkZXMgeSBzdXByaW1pciBlc3BhY2lvcyBlbiBsb3MNCmV4dHJlbW9zLiBBZGljaW9uYWxtZW50ZSwgc2UgYWp1c3RhbiBsYXMgZXRpcXVldGFzIGRlIGxhcyBjYXRlZ29yw61hcw0KcGFyYSBtZWpvcmFyIHN1IGxlY3R1cmEgZW4gdGFibGFzIHkgZ3LDoWZpY29zLCB5IHNlIGNvcnJpZ2llcm9uIGxvcw0Kbm9tYnJlcyBkZSBzZWlzIHZhcmlhYmxlcyBxdWUgcHJlc2VudGFiYW4gZXNwYWNpb3MsIGVycm9yZXMgb3J0b2dyw6FmaWNvcw0KbyB1biBmb3JtYXRvIGRpc3RpbnRvIGFsIGRlbCByZXN0byBkZWwgZGF0YXNldCAoVmVyIFRhYmxhcyAxLjMgeSAxLjQpLg0KDQpgYGB7cn0NCnJldmlzYXJfY2F0ZWdvcmlhcyA8LSBmdW5jdGlvbih4KSB7DQogIG5pdmVsZXMgPC0gbGV2ZWxzKHgpDQogIHRleHRvIDwtIGFzLmNoYXJhY3Rlcih4KQ0KICBub3JtYWxpemFkbyA8LSBzdHJpbmdpOjpzdHJpX3RyYW5zX2dlbmVyYWwodG9sb3dlcih0cmltd3ModGV4dG8pKSwgIkxhdGluLUFTQ0lJIikNCiAgdGliYmxlKA0KICAgIGBOLsK6IGRlIG5pdmVsZXNgID0gbGVuZ3RoKG5pdmVsZXMpLA0KICAgIGBFc3BhY2lvcyBzb2JyYW50ZXNgID0gc3VtKHRleHRvICE9IHRyaW13cyh0ZXh0bykpLA0KICAgIGBWYXJpYW50ZXMgZGUgZXNjcml0dXJhYCA9IG5fZGlzdGluY3QodGV4dG8pIC0gbl9kaXN0aW5jdChub3JtYWxpemFkbyksDQogICAgTml2ZWxlcyA9IHBhc3RlKG5pdmVsZXMsIGNvbGxhcHNlID0gIiwgIikNCiAgKQ0KfQ0KDQp0YWJsYV9jYXRlZ29yaWFzIDwtIHJvdF9wMyB8Pg0KICBzZWxlY3Qod2hlcmUoaXMuZmFjdG9yKSkgfD4NCiAgbWFwX2RmcihyZXZpc2FyX2NhdGVnb3JpYXMsIC5pZCA9ICJWYXJpYWJsZSIpDQoNCnRhYmxhX2NhdGVnb3JpYXMgfD4NCiAgdGFibGFfZXN0aWxvKHRpdHVsbyA9ICIiLA0KICAgICAgICAgICAgICAgYWxpbmVhY2lvbiA9IGMoImwiLCAiYyIsICJjIiwgImMiLCAibCIpKQ0KYGBgDQoNCipUYWJsYSAxLjMuIFJldmlzacOzbiBkZSBsYXMgY2F0ZWdvcsOtYXMgZGUgbGFzIHZhcmlhYmxlcyBjdWFsaXRhdGl2YXMqDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0Kcm90X3A0IDwtIHJvdF9wMyB8Pg0KICByZW5hbWUoDQogICAgVmlhamVfTmVnb2Npb3MgICAgICAgICAgICAgID0gYFZpYWplIGRlIE5lZ29jaW9zYCwNCiAgICBTYXRpc2ZhY2Npw7NuX0xhYm9yYWwgICAgICAgID0gU2F0aXNmYWNpw7NuX0xhYm9yYWwsDQogICAgR8OpbmVybyAgICAgICAgICAgICAgICAgICAgICA9IEdlbmVybywNCiAgICBBw7Fvc19NaXNtb19KZWZlICAgICAgICAgICAgID0gQcOxb3NfYWNhcmdvX2Nvbl9taXNtb19qZWZlLA0KICAgIEHDsW9zX8OabHRpbWFfUHJvbW9jacOzbiAgICAgICA9IEHDsW9zX3VsdGltYV9wcm9tb2Npw7NuLA0KICAgIFBvcmNlbnRhamVfQXVtZW50b19TYWxhcmlhbCA9IFBvcmNlbnRhamVfYXVtZW50b19zYWxhcmlhbA0KICApIHw+DQogIG11dGF0ZSgNCiAgICBhY3Jvc3MoYyhSb3RhY2nDs24sIEhvcmFzX0V4dHJhKSwgfiBmY3RfcmVjb2RlKC54LCAiU8OtIiA9ICJTaSIpKSwNCiAgICBWaWFqZV9OZWdvY2lvcyAgPSBmY3RfcmVjb2RlKFZpYWplX05lZ29jaW9zLCAiTm8gdmlhamEiID0gIk5vX1ZpYWphIiksDQogICAgRGVwYXJ0YW1lbnRvICAgID0gZmN0X3JlY29kZShEZXBhcnRhbWVudG8sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSW52ZXN0aWdhY2nDs24geSBEZXNhcnJvbGxvIiA9ICJJeUQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlY3Vyc29zIEh1bWFub3MiID0gIlJIIiksDQogICAgQ2FtcG9fRWR1Y2FjacOzbiA9IGZjdF9yZWNvZGUoQ2FtcG9fRWR1Y2FjacOzbiwgIlTDqWNuaWNvcyIgPSAiVGVjbmljb3MiKSwNCiAgICBHw6luZXJvICAgICAgICAgID0gZmN0X3JlY29kZShHw6luZXJvLCAiRmVtZW5pbm8iID0gIkYiLCAiTWFzY3VsaW5vIiA9ICJNIiksDQogICAgQ2FyZ28gICAgICAgICAgID0gZmN0X3JlY29kZShDYXJnbywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaXJlY3RvciBkZSBJbnZlc3RpZ2FjacOzbiIgPSAiRGlyZWN0b3JfSW52ZXN0aWdhY2nDs24iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpcmVjdG9yIGRlIE1hbnVmYWN0dXJhIiAgID0gIkRpcmVjdG9yX01hbm9mYWN0dXJhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFamVjdXRpdm8gZGUgVmVudGFzIiAgICAgICA9ICJFamVjdXRpdm9fVmVudGFzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbnZlc3RpZ2Fkb3IgQ2llbnTDrWZpY28iICAgPSAiSW52ZXN0aWdhZG9yX0NpZW50aWZpY28iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlY3Vyc29zIEh1bWFub3MiICAgICAgICAgID0gIlJlY3Vyc29zX0h1bWFub3MiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlcHJlc2VudGFudGUgZGUgU2FsdWQiICAgID0gIlJlcHJlc2VudGFudGVfU2FsdWQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlcHJlc2VudGFudGUgZGUgVmVudGFzIiAgID0gIlJlcHJlc2VudGFudGVfVmVudGFzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUw6ljbmljbyBkZSBMYWJvcmF0b3JpbyIgICAgPSAiVGVjbmljb19MYWJvcmF0b3JpbyIpDQogICkNCg0KYWxsKG1hcDJfbGdsKHNlbGVjdChyb3RfcDMsIHdoZXJlKGlzLmZhY3RvcikpLA0KICAgICAgICAgICAgIHNlbGVjdChyb3RfcDQsIHdoZXJlKGlzLmZhY3RvcikpLA0KICAgICAgICAgICAgIH4gaWRlbnRpY2FsKGFzLnZlY3Rvcih0YWJsZSgueCkpLCBhcy52ZWN0b3IodGFibGUoLnkpKSkpKQ0KYGBgDQoNCmBgYHtyfQ0KdGFibGFfbm9tYnJlcyA8LSB0aWJibGUoDQogIGBOb21icmUgb3JpZ2luYWxgID0gbmFtZXMocm90X3AzKSwNCiAgYE5vbWJyZSBjb3JyZWdpZG9gID0gbmFtZXMocm90X3A0KQ0KKSB8Pg0KICBmaWx0ZXIoYE5vbWJyZSBvcmlnaW5hbGAgIT0gYE5vbWJyZSBjb3JyZWdpZG9gKQ0KDQp0YWJsYV9ub21icmVzIHw+DQogIHRhYmxhX2VzdGlsbyh0aXR1bG8gPSAiIiwgYWxpbmVhY2lvbiA9IGMoImwiLCAibCIpKQ0KYGBgDQoNCipUYWJsYSAxLjQuIFZhcmlhYmxlcyByZW5vbWJyYWRhcyoNCg0KIyMjIFJlZ2lzdHJvcyBEdXBsaWNhZG9zDQoNClNlIHZlcmlmaWNhIGxhIGV4aXN0ZW5jaWEgZGUgcmVnaXN0cm9zIGR1cGxpY2Fkb3MsIGVudGVuZGlkb3MgZW4gZXN0ZQ0KY2FzbyBjb21vIGZpbGFzIGlkw6ludGljYXMgZW4gbGEgdG90YWxpZGFkIGRlIGxhcyB2YXJpYWJsZXMuIExhIHJldmlzacOzbg0Kc2UgY29tcGxlbWVudGEgY29uIHVuYSBiw7pzcXVlZGEgZGUgcmVnaXN0cm9zIGNvaW5jaWRlbnRlcyBlbiB0b2RhcyBsYXMNCnZhcmlhYmxlcyBleGNlcHRvIFJvdGFjacOzbi4gRXN0byBwZXJtaXRlIGRldGVjdGFyIHBlcmZpbGVzIGlkw6ludGljb3MgY29uDQpyZXN1bHRhZG9zIG9wdWVzdG9zIGVuIGxhIHZhcmlhYmxlIHJlc3B1ZXN0YSwgdW5hIHNpdHVhY2nDs24gcXVlDQphZmVjdGFyw61hIGxhIGVzdGltYWNpw7NuIGRlbCBtb2RlbG8gbG9nw61zdGljby4gTGEgcmV2aXNpw7NuIG5vIGlkZW50aWZpY8OzDQpyZWdpc3Ryb3MgZHVwbGljYWRvczogbmluZ3VuYSBmaWxhIGNvaW5jaWRlIGNvbiBvdHJhIGVuIGxhIHRvdGFsaWRhZCBkZQ0KbGFzIHZhcmlhYmxlcy4gVGFtcG9jbyBzZSBlbmNvbnRyYXJvbiBwZXJmaWxlcyBpZMOpbnRpY29zIGNvbiByZXN1bHRhZG8NCmRpc3RpbnRvIGVuIFJvdGFjacOzbi4NCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQpyb3RfcDUgPC0gcm90X3A0DQoNCnN1bShkdXBsaWNhdGVkKHJvdF9wNSkpDQoNCnN1bShkdXBsaWNhdGVkKHJvdF9wNSB8PiBzZWxlY3QoLVJvdGFjacOzbikpKQ0KDQpyb3RfcDUgfD4NCiAgZmlsdGVyKGR1cGxpY2F0ZWQocm90X3A1KSB8IGR1cGxpY2F0ZWQocm90X3A1LCBmcm9tTGFzdCA9IFRSVUUpKQ0KYGBgDQoNCiMjIyBFc3RhZMOtc3RpY2FzIERlc2NyaXB0aXZhcyBWYXJpYWJsZXMgQ29udGludWFzDQoNCkxhcyAxMSB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyBzZSBjYXJhY3Rlcml6YW4gbWVkaWFudGUgbWVkaWRhcyBkZQ0KdGVuZGVuY2lhIGNlbnRyYWwgKG1lZGlhIHkgbWVkaWFuYSksIGRlIGRpc3BlcnNpw7NuIChkZXN2aWFjacOzbiBlc3TDoW5kYXIsDQpjb2VmaWNpZW50ZSBkZSB2YXJpYWNpw7NuLCB2YWxvcmVzIG3DrW5pbW8geSBtw6F4aW1vLCB5IGN1YXJ0aWxlcykgeSBkZQ0KZm9ybWEgKGNvZWZpY2llbnRlcyBkZSBhc2ltZXRyw61hIHkgY3VydG9zaXMpLiBFc3RhcyBtZWRpZGFzIHNlDQpjb21wbGVtZW50YW4gY29uIGhpc3RvZ3JhbWFzIHBhcmEgZXhhbWluYXIgdmlzdWFsbWVudGUgbGEgZGlzdHJpYnVjacOzbg0KZGUgY2FkYSB2YXJpYWJsZS4NCg0KYGBge3J9DQpkYXRvc19udW0gPC0gcm90X3A1IHw+DQogIHNlbGVjdCh3aGVyZShpcy5udW1lcmljKSkgfD4NCiAgcGl2b3RfbG9uZ2VyKGV2ZXJ5dGhpbmcoKSwgbmFtZXNfdG8gPSAiVmFyaWFibGUiLCB2YWx1ZXNfdG8gPSAidmFsb3IiKSB8Pg0KICBtdXRhdGUoVmFyaWFibGUgPSBmY3RfaW5vcmRlcihWYXJpYWJsZSkpDQoNCmRlc2NyaXB0aXZvcyA8LSBkYXRvc19udW0gfD4NCiAgZ3JvdXBfYnkoVmFyaWFibGUpIHw+DQogIHN1bW1hcmlzZSgNCiAgICBNZWRpYSAgICAgPSBtZWFuKHZhbG9yKSwNCiAgICBNZWRpYW5hICAgPSBtZWRpYW4odmFsb3IpLA0KICAgIERFICAgICAgICA9IHNkKHZhbG9yKSwNCiAgICBgQ1YgKCUpYCAgPSAxMDAgKiBzZCh2YWxvcikgLyBtZWFuKHZhbG9yKSwNCiAgICBNw61uICAgICAgID0gbWluKHZhbG9yKSwNCiAgICBRMSAgICAgICAgPSBxdWFudGlsZSh2YWxvciwgMC4yNSksDQogICAgUTMgICAgICAgID0gcXVhbnRpbGUodmFsb3IsIDAuNzUpLA0KICAgIE3DoXggICAgICAgPSBtYXgodmFsb3IpLA0KICAgIEFzaW1ldHLDrWEgPSBlMTA3MTo6c2tld25lc3ModmFsb3IsIHR5cGUgPSAyKSwNCiAgICBDdXJ0b3NpcyAgPSBlMTA3MTo6a3VydG9zaXModmFsb3IsIHR5cGUgPSAyKQ0KICApIHw+DQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoLngsIDIpKSkNCg0KZGVzY3JpcHRpdm9zIHw+DQogIHRhYmxhX2VzdGlsbyh0aXR1bG8gPSAiIiwNCiAgICAgICAgICAgICAgIG5vdGEgPSAiREU6IGRlc3ZpYWNpw7NuIGVzdMOhbmRhcjsgQ1Y6IGNvZWZpY2llbnRlIGRlIHZhcmlhY2nDs247IFExIHkgUTM6IHByaW1lciB5IHRlcmNlciBjdWFydGlsLiBMYSBjdXJ0b3NpcyBzZSByZXBvcnRhIGNvbW8gZXhjZXNvIHJlc3BlY3RvIGEgbGEgZGlzdHJpYnVjacOzbiBub3JtYWwuIikNCg0KYGBgDQoNCipUYWJsYSAxLjUuIEVzdGFkw61zdGljb3MgZGVzY3JpcHRpdm9zIGRlIGxhcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyoNCg0KTGEgVGFibGEgMS41IG11ZXN0cmEgcXVlIGxhIHBsYW50aWxsYSBkZSBjYXJnb3MgdGllbmUgdW5hIGVkYWQgbWVkaWEgZGUNCjM2LDkgYcOxb3MsIGNvbiB1biByYW5nbyBlbnRyZSAxOCB5IDYwIHkgdW5hIGRpc3RyaWJ1Y2nDs24gYXByb3hpbWFkYW1lbnRlDQpzaW3DqXRyaWNhIChhc2ltZXRyw61hIGRlIDAsNDEpLCBsYSDDum5pY2EgdmFyaWFibGUgY29uIGVzdGEgZGlzdHJpYnVjacOzbi4NCkxhcyBkaWV6IHZhcmlhYmxlcyByZXN0YW50ZXMgcHJlc2VudGFuIGFzaW1ldHLDrWEgcG9zaXRpdmEsIGNvbiBsYSBtZWRpYQ0KcG9yIGVuY2ltYSBkZSBsYSBtZWRpYW5hIGVuIHRvZG9zIGxvcyBjYXNvcywgcGF0csOzbiBxdWUgY29uZmlybWFuIGxvcw0KaGlzdG9ncmFtYXMgZGUgbGEgRmlndXJhIDEuMS4gRWwgY2FzbyBtw6FzIG1hcmNhZG8gZXMgZWwgaW5ncmVzbyBtZW5zdWFsLA0KY3V5YSBtZWRpYSAoNi41MDIsOTMpIHN1cGVyYSBlbiBjYXNpIDEuNjAwIHVuaWRhZGVzIGEgbGEgbWVkaWFuYQ0KKDQuOTE5KSwgbG8gcXVlIGluZGljYSBxdWUgdW4gZ3J1cG8gcmVkdWNpZG8gZGUgZW1wbGVhZG9zIGNvbiBzYWxhcmlvcw0KYWx0b3MsIGhhc3RhIHVuIG3DoXhpbW8gZGUgMTkuOTk5LCBlbGV2YSBlbCBwcm9tZWRpbyBwb3IgZW5jaW1hIGRlbA0KaW5ncmVzbyB0w61waWNvLg0KDQpMYXMgbWVkaWRhcyBkZSBkaXNwZXJzacOzbiByZWxhdGl2YSByZXZlbGFuIGNvbXBvcnRhbWllbnRvcyBtdXkgZGlzdGludG9zDQplbnRyZSB2YXJpYWJsZXMuIExhIGVkYWQgeSBlbCBwb3JjZW50YWplIGRlIGF1bWVudG8gc2FsYXJpYWwgc29uIGxhcyBtw6FzDQpob21vZ8OpbmVhcywgY29uIGNvZWZpY2llbnRlcyBkZSB2YXJpYWNpw7NuIGNlcmNhbm9zIGFsIDI0JSwgbWllbnRyYXMgcXVlDQpsb3MgYcOxb3MgZGVzZGUgbGEgw7psdGltYSBwcm9tb2Npw7NuIGNvbnN0aXR1eWVuIGxhIHZhcmlhYmxlIG3DoXMgZGlzcGVyc2ENCmRlbCBjb25qdW50byAoQ1YgZGUgMTQ3LDMlKSBsbyBxdWUgaW5kaWNhIHF1ZSBsYSBtaXRhZCBkZSBsb3MgZW1wbGVhZG9zDQpmdWUgcHJvbW92aWRhIGhhY2UgdW4gYcOxbyBvIG1lbm9zLCBwZXJvIGFsZ3Vub3MgYWN1bXVsYW4gaGFzdGEgMTUgYcOxb3MNCnNpbiBhc2NlbnNvLiBVbiBjb21wb3J0YW1pZW50byBzaW1pbGFyIHNlIG9ic2VydmEgZW4gbGEgYW50aWfDvGVkYWQgZW4gbGENCmVtcHJlc2EsIGRvbmRlIGxhIG1lZGlhbmEgZGUgNSBhw7FvcyBjb250cmFzdGEgY29uIHVuIG3DoXhpbW8gZGUgNDAgeSBjb24NCmxhIGN1cnRvc2lzIG3DoXMgYWx0YSBkZSBsYSB0YWJsYSAoMyw5NCksIGxvIHF1ZSBwdWVkZSBzZXIgc2XDsWFsIGRlIHVuYQ0KY29sYSBkZXJlY2hhIHByb251bmNpYWRhIGNvbXB1ZXN0YSBwb3IgZW1wbGVhZG9zIGRlIHRyYXllY3RvcmlhDQpwcm9sb25nYWRhLg0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCg0KZGF0b3NfbnVtIHw+DQogIGdncGxvdChhZXMoeCA9IHZhbG9yLCBmaWxsID0gVmFyaWFibGUpKSArDQogIGdlb21faGlzdG9ncmFtKA0KICAgIGJpbnMgPSAyNSwNCiAgICBjb2xvciA9ICJ3aGl0ZSIsDQogICAgbGluZXdpZHRoID0gMC4yNSwNCiAgICBhbHBoYSA9IDAuOTANCiAgKSArDQogIGZhY2V0X3dyYXAofiBWYXJpYWJsZSwgc2NhbGVzID0gImZyZWUiLCBuY29sID0gMykgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfZCgNCiAgICBvcHRpb24gPSAiRCIsDQogICAgZW5kID0gMC45MCwNCiAgICBndWlkZSA9ICJub25lIg0KICApICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICIiLA0KICAgIHggPSBOVUxMLA0KICAgIHkgPSAiRnJlY3VlbmNpYSINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dCgNCiAgICAgIGZhY2UgPSAicGxhaW4iLA0KICAgICAgY29sb3IgPSAiIzMzMzMzMyIsDQogICAgICBzaXplID0gMTANCiAgICApLA0KICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICApDQpgYGANCg0KKkZpZ3VyYSAxLjEuIERpc3RyaWJ1Y2nDs24gZGUgbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzKg0KDQpMYXMgdmFyaWFibGVzIHJlbGFjaW9uYWRhcyBjb24gbGEgdHJheWVjdG9yaWEgbGFib3JhbCBndWFyZGFuIGNvaGVyZW5jaWENCmVudHJlIHPDrTogbGEgZXhwZXJpZW5jaWEgdG90YWwgKG1lZGlhbmEgZGUgMTAgYcOxb3MpIHN1cGVyYSBhIGxhDQphbnRpZ8O8ZWRhZCBlbiBsYSBlbXByZXNhICg1IGHDsW9zKSwgeSBlc3RhIGEgc3UgdmV6IGEgbGEgYW50aWfDvGVkYWQgZW4gZWwNCmNhcmdvIGFjdHVhbCAoMyBhw7FvcyksIGxvIHF1ZSByZWZsZWphIHVuYSBlc3RydWN0dXJhIG9yZ2FuaXphY2lvbmFsDQpyYXpvbmFibGUuIFBvciBzdSBwYXJ0ZSwgbG9zIGhpc3RvZ3JhbWFzIGV2aWRlbmNpYW4gcXVlIHZhcmlhcyB2YXJpYWJsZXMNCmRlIGNvbnRlbyBjb25jZW50cmFuIHN1cyB2YWxvcmVzIGVuIHBvY2FzIGNhdGVnb3LDrWFzLiBMYXMgY2FwYWNpdGFjaW9uZXMNCnNlIGFncnVwYW4gY2FzaSBwb3IgY29tcGxldG8gZW4gMiB5IDMgYWwgYcOxbywgeSBlbCBwb3JjZW50YWplIGRlIGF1bWVudG8NCnNhbGFyaWFsIHNlIGFjdW11bGEgZW50cmUgMTElIHkgMTQlLCBjb24gZnJlY3VlbmNpYXMgZGVjcmVjaWVudGVzIGhhY2lhDQp2YWxvcmVzIHN1cGVyaW9yZXMuIEZpbmFsbWVudGUsIGxhIGRpc3RhbmNpYSBhbCBsdWdhciBkZSB0cmFiYWpvIG11ZXN0cmENCnVuYSBmdWVydGUgY29uY2VudHJhY2nDs24gZW4gdHJheWVjdG9zIGNvcnRvcywgY29uIHVuIDI1JSBkZSBsb3MNCmVtcGxlYWRvcyByZXNpZGllbmRvIGEgZG9zIGtpbMOzbWV0cm9zIG8gbWVub3MgZGUgc3UgbHVnYXIgZGUgdHJhYmFqbywNCnBlcm8gY29uIHVuYSBjb2xhIHF1ZSBzZSBleHRpZW5kZSBoYXN0YSAyOSBraWzDs21ldHJvcy4NCg0KIyMjIEVzdGFkw61zdGljYXMgRGVzY3JpcHRpdmFzIFZhcmlhYmxlcyBDYXRlZ8OzcmljYXMNCg0KTGFzIDEzIHZhcmlhYmxlcyBjdWFsaXRhdGl2YXMgc2UgY2FyYWN0ZXJpemFuIG1lZGlhbnRlIGdyw6FmaWNvcyBkZQ0KYmFycmFzLiBMYSB2YXJpYWJsZSByZXNwdWVzdGEgKFJvdGFjacOzbiksIHNlIGFuYWxpemEgZGUgZm9ybWENCmluZGVwZW5kaWVudGUsIGluY29ycG9yYW5kbyBsYSByYXrDs24gZW50cmUgc3VzIGRvcyBjYXRlZ29yw61hcyBjb24gZWwgZmluDQpkZSBldmFsdWFyIGVsIGVxdWlsaWJyaW8gZW50cmUgZW1wbGVhZG9zIHF1ZSByb3RhbiB5IHF1ZSBwZXJtYW5lY2VuLA0KYXNwZWN0byByZWxldmFudGUgcGFyYSBsYSBwb3N0ZXJpb3IgZXN0aW1hY2nDs24geSBldmFsdWFjacOzbiBkZWwgbW9kZWxvDQpsb2fDrXN0aWNvLg0KDQpMYSBGaWd1cmEgMS4yIGV2aWRlbmNpYSBxdWUgbGEgcGxhbnRpbGxhIGRlIGVtcGxlYWRvcyBlc3TDoSBjb25jZW50cmFkYQ0KZW4gdW5vcyBwb2NvcyBwZXJmaWxlcy4gRWwgNjUsNCUgZGUgbG9zIGVtcGxlYWRvcyBwZXJ0ZW5lY2UgYQ0KSW52ZXN0aWdhY2nDs24geSBEZXNhcnJvbGxvIHkgZWwgMzAsMyUgYSBWZW50YXMsIG1pZW50cmFzIHF1ZSBSZWN1cnNvcw0KSHVtYW5vcyByZcO6bmUgYXBlbmFzIDYzIHBlcnNvbmFzICg0LDMlKS4gVW5hIGNvbmNlbnRyYWNpw7NuIHNpbWlsYXIgc2UNCm9ic2VydmEgZW4gZWwgY2FyZ28sIGxhIHZhcmlhYmxlIGNvbiBtYXlvciBuw7ptZXJvIGRlIGNhdGVnb3LDrWFzOiB0cmVzIGRlDQpsb3MgbnVldmUgY2FyZ29zIChFamVjdXRpdm8gZGUgVmVudGFzLCBJbnZlc3RpZ2Fkb3IgQ2llbnTDrWZpY28geSBUw6ljbmljbw0KZGUgTGFib3JhdG9yaW8pIGFncnVwYW4gYWwgNTksNyUgZGUgbGEgcGxhbnRpbGxhLCBlbiB0YW50byBxdWUgUmVjdXJzb3MNCkh1bWFub3MsIGNvbiA1MiBlbXBsZWFkb3MsIGVzIGVsIG1lbm9zIGZyZWN1ZW50ZS4NCg0KRXN0YSBkZXNwcm9wb3JjacOzbiBkZWJlIHRlbmVyc2UgcHJlc2VudGUgcGFyYSBsYSBpbmxjdXNpw7NuIGRlIGxhDQp2YXJpYWJsZSBhbCBtb2RlbG8sIHB1ZXMgbGFzIGNhdGVnb3LDrWFzIGNvbiBwb2NvcyBjYXNvcyB0aWVuZGVuIGENCnByb2R1Y2lyIGVzdGltYWNpb25lcyBpbmVzdGFibGVzLiBFbiBjdWFudG8gYWwgcGVyZmlsIGdlbmVyYWwsIGVsIDYwJSBkZQ0KbG9zIGVtcGxlYWRvcyBzb24gaG9tYnJlcywgZWwgNDUsOCUgZXN0w6EgY2FzYWRvLiBFbCBuaXZlbCBlZHVjYXRpdm8NCnByZWRvbWluYW50ZSBlcyBlbCBkZSB0w6ljbmljbyBvIHRlY27Ds2xvZ28gKDM4LDklKSwgc2VndWlkbyBwb3IgcHJlZ3JhZG8NCigyNywxJSksIG1pZW50cmFzIHF1ZSBlbCBwb3NncmFkbyByZXN1bHRhIG1hcmdpbmFsICgzLDMlKS4gVW4gMzAsOCUgZGUNCmxvcyBlbXBsZWFkb3MgY3VlbnRhIMO6bmljYW1lbnRlIGNvbiBlZHVjYWNpw7NuIHByaW1hcmlhICgxMSw2JSkgbw0Kc2VjdW5kYXJpYSAoMTksMiUpLCBwcm9wb3JjacOzbiBjb25zaWRlcmFibGUgcGFyYSB1bmEgb3JnYW5pemFjacOzbiBjb24gdW4NCnBlc28gdGFuIGFsdG8gZGVsIMOhcmVhIGRlIEludmVzdGlnYWNpw7NuIHkgRGVzYXJyb2xsby4gTGEgZm9ybWFjacOzbiBzZQ0KY29uY2VudHJhIGVuIENpZW5jaWFzICg0MSwyJSkgeSBTYWx1ZCAoMzEsNiUpLCBjb2hlcmVudGUgY29uIGVsIHBlcmZpbA0KdMOpY25pY28geSBjaWVudMOtZmljbyBkZSBsYSBlbXByZXNhLg0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCmNhdGVnb3JpY2FzIDwtIHJvdF9wNSB8Pg0KICBzZWxlY3Qod2hlcmUoaXMuZmFjdG9yKSkgfD4NCiAgaW1hcF9kZnIofiB0aWJibGUoVmFyaWFibGUgID0gLnksDQogICAgICAgICAgICAgICAgICAgIENhdGVnb3LDrWEgPSBhcy5jaGFyYWN0ZXIoLngpLA0KICAgICAgICAgICAgICAgICAgICBPcmRlbiAgICAgPSBhcy5pbnRlZ2VyKC54KSkpIHw+DQogIG11dGF0ZShWYXJpYWJsZSA9IGZjdF9pbm9yZGVyKFZhcmlhYmxlKSkNCg0KdGFibGFfZnJlY3VlbmNpYXMgPC0gY2F0ZWdvcmljYXMgfD4NCiAgY291bnQoVmFyaWFibGUsIENhdGVnb3LDrWEsIE9yZGVuLCBuYW1lID0gIkZyZWN1ZW5jaWEiKSB8Pg0KICBncm91cF9ieShWYXJpYWJsZSkgfD4NCiAgbXV0YXRlKGBQb3JjZW50YWplICglKWAgPSByb3VuZCgxMDAgKiBGcmVjdWVuY2lhIC8gc3VtKEZyZWN1ZW5jaWEpLCAxKSkgfD4NCiAgdW5ncm91cCgpIHw+DQogIGFycmFuZ2UoVmFyaWFibGUsIE9yZGVuKSB8Pg0KICBzZWxlY3QoLU9yZGVuKQ0KDQp0YWJsYV9mcmVjdWVuY2lhcyB8Pg0KICB0YWJsYV9lc3RpbG8odGl0dWxvID0gIlRhYmxhIDEuNy4gRGlzdHJpYnVjacOzbiBkZSBmcmVjdWVuY2lhcyBkZSBsYXMgdmFyaWFibGVzIGN1YWxpdGF0aXZhcyIsDQogICAgICAgICAgICAgICBhbGluZWFjaW9uID0gYygibCIsICJsIiwgImMiLCAiYyIpKSB8Pg0KICBjb2xsYXBzZV9yb3dzKGNvbHVtbnMgPSAxLCB2YWxpZ24gPSAidG9wIikNCg0KYGBgDQoNCmBgYHtyfQ0KI3wgbGFiZWw6IGZpZ3VyYS0xLTINCiN8IGZpZy13aWR0aDogMTANCiN8IGZpZy1oZWlnaHQ6IDE2DQojfCBmaWctYWxpZ246ICJjZW50ZXIiDQoNCm5pdmVsZXNfb3JkZW4gPC0gY2F0ZWdvcmljYXMgfD4NCiAgZGlzdGluY3QoVmFyaWFibGUsIENhdGVnb3LDrWEsIE9yZGVuKSB8Pg0KICBhcnJhbmdlKFZhcmlhYmxlLCBkZXNjKE9yZGVuKSkgfD4NCiAgbXV0YXRlKEV0aXF1ZXRhID0gcGFzdGUoQ2F0ZWdvcsOtYSwgVmFyaWFibGUsIHNlcCA9ICJfX18iKSkgfD4NCiAgcHVsbChFdGlxdWV0YSkNCg0KY2F0ZWdvcmljYXMgfD4NCiAgbXV0YXRlKA0KICAgIEV0aXF1ZXRhID0gZmFjdG9yKA0KICAgICAgcGFzdGUoQ2F0ZWdvcsOtYSwgVmFyaWFibGUsIHNlcCA9ICJfX18iKSwNCiAgICAgIGxldmVscyA9IG5pdmVsZXNfb3JkZW4NCiAgICApDQogICkgfD4NCiAgZ2dwbG90KGFlcyh5ID0gRXRpcXVldGEsIGZpbGwgPSBWYXJpYWJsZSkpICsNCiAgZ2VvbV9iYXIoDQogICAgd2lkdGggPSAwLjcsDQogICAgY29sb3IgPSAid2hpdGUiLA0KICAgIGxpbmV3aWR0aCA9IDAuMjUsDQogICAgYWxwaGEgPSAwLjkwDQogICkgKw0KICBmYWNldF93cmFwKH4gVmFyaWFibGUsIHNjYWxlcyA9ICJmcmVlIiwgbmNvbCA9IDIpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2QoDQogICAgb3B0aW9uID0gIkQiLA0KICAgIGVuZCA9IDAuOTAsDQogICAgZ3VpZGUgPSAibm9uZSINCiAgKSArDQogIHNjYWxlX3lfZGlzY3JldGUoDQogICAgbGFiZWxzID0gfiBzY2FsZXM6OmxhYmVsX3dyYXAoMjIpKHN1YigiX19fLiokIiwgIiIsIC54KSkNCiAgKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiIiwNCiAgICB4ID0gIkZyZWN1ZW5jaWEiLA0KICAgIHkgPSBOVUxMDQogICkgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDExKSArDQogIHRoZW1lKA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KA0KICAgICAgc2l6ZSA9IDksDQogICAgICBjb2xvciA9ICIjMzMzMzMzIg0KICAgICksDQogICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KA0KICAgICAgZmFjZSA9ICJwbGFpbiIsDQogICAgICBzaXplID0gMTAsDQogICAgICBjb2xvciA9ICIjMzMzMzMzIg0KICAgICksDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuc3BhY2luZyA9IHVuaXQoMS4yLCAibGluZXMiKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KA0KICAgICAgZmFjZSA9ICJib2xkIiwNCiAgICAgIHNpemUgPSAxNCwNCiAgICAgIGhqdXN0ID0gMC41LA0KICAgICAgY29sb3IgPSAiIzIxMzg0QSINCiAgICApLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICApDQpgYGANCg0KKkZpZ3VyYSAxLjIuIERpc3RyaWJ1Y2nDs24gZGUgdmFyaWFibGVzIGN1YWxpdGF0aXZhcyoNCg0KYGBge3J9DQp0YWJsYV9yb3RhY2lvbiA8LSByb3RfcDUgfD4NCiAgY291bnQoUm90YWNpw7NuLCBuYW1lID0gIkZyZWN1ZW5jaWEiKSB8Pg0KICBtdXRhdGUoYFBvcmNlbnRhamUgKCUpYCA9IHJvdW5kKDEwMCAqIEZyZWN1ZW5jaWEgLyBzdW0oRnJlY3VlbmNpYSksIDEpKQ0KDQp0YWJsYV9yb3RhY2lvbiB8Pg0KICB0YWJsYV9lc3RpbG8odGl0dWxvID0gIiIsDQogICAgICAgICAgICAgICBub3RhID0gcGFzdGUwKCJSYXrDs24gZW50cmUgZW1wbGVhZG9zIHF1ZSBubyByb3RhbiB5IHF1ZSByb3RhbjogIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQodGFibGFfcm90YWNpb24kRnJlY3VlbmNpYVsxXSAvDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFibGFfcm90YWNpb24kRnJlY3VlbmNpYVsyXSwgMSksICIgYSAxLiIpKQ0KYGBgDQoNCipUYWJsYSAxLjYuIERpc3RyaWJ1Y2nDs24gZGUgbGEgdmFyaWFibGUgUm90YWNpw7NuKg0KDQpDb24gcmVzcGVjdG8gYSBsYXMgY29uZGljaW9uZXMgbGFib3JhbGVzLCBlbCA3MSUgZGUgbG9zIGVtcGxlYWRvcyB2aWFqYQ0KcmFyYSB2ZXogeSBzb2xvIGVsIDE4LDglIGxvIGhhY2UgY29uIGZyZWN1ZW5jaWEsIG1pZW50cmFzIHF1ZSBlbCAyOCwzJQ0KdHJhYmFqYSBob3JhcyBleHRyYS4gTGFzIGRvcyBlc2NhbGFzIGRlIHNhdGlzZmFjY2nDs24gbXVlc3RyYW4NCmRpc3RyaWJ1Y2lvbmVzIGNhc2kgaWTDqW50aWNhczogYWxyZWRlZG9yIGRlbCA2MSUgc2UgZGVjbGFyYSBzYXRpc2ZlY2hhIG8NCm11eSBzYXRpc2ZlY2hhLCBtaWVudHJhcyBxdWUgY2VyY2EgZGVsIDM5JSBtYW5pZmllc3RhIGFsZ8O6biBncmFkbyBkZQ0KaW5zYXRpc2ZhY2Npw7NuLCBjb24gdW4gMTklIGVuIGVsIG5pdmVsIGRlIG11eSBpbnNhdGlzZmVjaG8sIHRhbnRvDQpyZXNwZWN0byBhbCBhbWJpZW50ZSBkZSB0cmFiYWpvIGNvbW8gYWwgdHJhYmFqbyBkZXNlbXBlw7FhZG8uDQoNCkVsIGVxdWlsaWJyaW8gZW50cmUgdHJhYmFqbyB5IHZpZGEgcGVyc29uYWwgcHJlc2VudGEgdW5hIGRpc3RyaWJ1Y2nDs24NCmNvbmNlbnRyYWRhIGVuIGVsIG5pdmVsIGludGVybWVkaW8sIHF1ZSBhZ3J1cGEgYWwgNjAsNyUgZGUgbG9zDQplbXBsZWFkb3MuIFNvbG8gZWwgMTAsNCUgbG8gY2FsaWZpY2EgY29tbyBhbHRvLCBtaWVudHJhcyBxdWUgZWwgMjgsOCUgbG8NCnViaWNhIGVuIGxvcyBuaXZlbGVzIGJham8gKDIzLDQlKSBvIG11eSBiYWpvICg1LDQlKS4gVW4gaGFsbGF6Z28NCnBhcnRpY3VsYXIgc2UgcHJlc2VudGEgZW4gZWwgcmVuZGltaWVudG8gbGFib3JhbCwgeWEgcXVlIGF1bnF1ZSBsYQ0KZXNjYWxhIGNvbnRlbXBsYSBjdWF0cm8gbml2ZWxlcywgbGEgYmFzZSBzb2xvIHJlZ2lzdHJhIGxvcyBkb3MNCnN1cGVyaW9yZXMsIGNvbiB1biA4NCw2JSBkZSBjYWxpZmljYWNpb25lcyAiQWx0byIgeSB1biAxNSw0JSAiTXV5IGFsdG8iLg0KTGEgYXVzZW5jaWEgdG90YWwgZGUgZXZhbHVhY2lvbmVzIGJhamFzIG8gbWVkaWFzIGxpbWl0YSBzZXZlcmFtZW50ZSBsYQ0KdXRpbGlkYWQgZGUgZXN0YSB2YXJpYWJsZSBjb21vIHByZWRpY3RvciwgcHVlcyBubyBwZXJtaXRlIGRpc3Rpbmd1aXINCmVudHJlIGVtcGxlYWRvcyBjb24gZGVzZW1wZcOxbyBzYXRpc2ZhY3RvcmlvIGUgaW5zYXRpc2ZhY3RvcmlvLg0KDQpGaW5hbG1lbnRlLCBsYSBUYWJsYSAxLjYgbXVlc3RyYSBxdWUgZWwgMTYuMSUgZGUgbG9zIGVtcGxlYWRvcyByb3RhDQooY2FtYmlhIGRlIGVtcGxlbyBvIHB1ZXN0byBkZSB0cmFiYWpvKSB5IGVsIDgzLjklIG5vIHJvdGEuDQoNCiMjIyBJZGVudGlmaWNhY2nDs24geSBUcmF0YW1pZW50byBkZSBWYWxvcmVzIEF0w61waWNvcw0KDQpTZSBleGFtaW5hIGxhIHByZXNlbmNpYSBkZSB2YWxvcmVzIGF0w61waWNvcyBlbiBsYXMgMTEgdmFyaWFibGVzDQpjdWFudGl0YXRpdmFzIG1lZGlhbnRlIGVsIGNyaXRlcmlvIGRlbCByYW5nbyBpbnRlcmN1YXJ0w61saWNvLA0KY29uc2lkZXJhbmRvIGNvbW8gYXTDrXBpY28gdG9kbyB2YWxvciBzaXR1YWRvIGZ1ZXJhIGRlbCBpbnRlcnZhbG8NCmNvbXByZW5kaWRvIGVudHJlIFExIOKIkiAoa1wqIFJJQykgeSBRMyArIChrXCogUklDKS4gRWwgYW7DoWxpc2lzIHNlDQpyZWFsaXphIGNvbiBkb3MgdW1icmFsZXMsIGsgPSAxLDUgeSBrID0gMywgZGFkbyBxdWUgZWwgY3JpdGVyaW8NCmNvbnZlbmNpb25hbCB0aWVuZGUgYSBzZcOxYWxhciB1biBuw7ptZXJvIGVsZXZhZG8gZGUgb2JzZXJ2YWNpb25lcyBlbg0KZGlzdHJpYnVjaW9uZXMgYXNpbcOpdHJpY2FzIGNvbW8gbGFzIGlkZW50aWZpY2FkYXMgbGEgc2VjY2nDs24gYW50ZXJpb3IuDQpFbCBjb250ZW8gc2UgY29tcGxlbWVudGEgY29uIGRpYWdyYW1hcyBkZSBjYWphIHkgY29uIGxhIGNvbXBhcmFjacOzbg0KZW50cmUgZWwgdmFsb3IgbcOheGltbyBvYnNlcnZhZG8geSBlbCBsw61taXRlIHN1cGVyaW9yIGRlIGNhZGEgdmFyaWFibGUsDQpjb24gZWwgZmluIGRlIGVzdGFibGVjZXIgc2kgbG9zIGNhc29zIHNlw7FhbGFkb3MgY29ycmVzcG9uZMOtYW4gYSBlcnJvcmVzDQpkZSByZWdpc3RybyBvIGEgdmFsb3JlcyBleHRyZW1vcyBwbGF1c2libGVzLg0KDQpgYGB7cn0NCmxpbWl0ZXNfcmljIDwtIGZ1bmN0aW9uKHgsIGspIHsNCiAgcSA8LSBxdWFudGlsZSh4LCBjKDAuMjUsIDAuNzUpKQ0KICByaWMgPC0gcVsyXSAtIHFbMV0NCiAgYyhxWzFdIC0gayAqIHJpYywgcVsyXSArIGsgKiByaWMpDQp9DQoNCmF0aXBpY29zIDwtIGRhdG9zX251bSB8Pg0KICBncm91cF9ieShWYXJpYWJsZSkgfD4NCiAgc3VtbWFyaXNlKA0KICAgIGBBdMOtcGljb3MgKDEsNSBSSUMpYCA9IHN1bSh2YWxvciA8IGxpbWl0ZXNfcmljKHZhbG9yLCAxLjUpWzFdIHwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbG9yID4gbGltaXRlc19yaWModmFsb3IsIDEuNSlbMl0pLA0KICAgIGBBdMOtcGljb3MgKDMgUklDKWAgICA9IHN1bSh2YWxvciA8IGxpbWl0ZXNfcmljKHZhbG9yLCAzKVsxXSB8DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxvciA+IGxpbWl0ZXNfcmljKHZhbG9yLCAzKVsyXSksDQogICAgYEzDrW1pdGUgc3VwZXJpb3IgKDMgUklDKWAgPSBsaW1pdGVzX3JpYyh2YWxvciwgMylbMl0sDQogICAgTcOheGltbyA9IG1heCh2YWxvcikNCiAgKSB8Pg0KICBtdXRhdGUoYCUgKDMgUklDKWAgPSByb3VuZCgxMDAgKiBgQXTDrXBpY29zICgzIFJJQylgIC8gbnJvdyhyb3RfcDUpLCAxKSkgfD4NCiAgcmVsb2NhdGUoYCUgKDMgUklDKWAsIC5hZnRlciA9IGBBdMOtcGljb3MgKDMgUklDKWApDQoNCmF0aXBpY29zIHw+DQogIHRhYmxhX2VzdGlsbyh0aXR1bG8gPSAiIiwNCiAgICAgICAgICAgICAgIG5vdGEgPSAiUklDOiByYW5nbyBpbnRlcmN1YXJ0w61saWNvLiBFbCBsw61taXRlIHN1cGVyaW9yIGNvcnJlc3BvbmRlIGEgUTMgKyAzw5dSSUMuIikNCg0KYGBgDQoNCipUYWJsYSAxLjcuIFZhbG9yZXMgYXTDrXBpY29zIHNlZ8O6biBlbCBjcml0ZXJpbyBkZWwgcmFuZ28NCmludGVyY3VhcnTDrWxpY28qDQoNCkNvbW8gbXVlc3RyYSBsYSBUYWJsYSAxLjcsIGVsIGNyaXRlcmlvIGNvbnZlbmNpb25hbCBkZSAxLDVcKiBSSUMNCmlkZW50aWZpY2EgdmFsb3JlcyBhdMOtcGljb3MgZW4gb2NobyBkZSBsYXMgb25jZSB2YXJpYWJsZXMsIGNvbiBjb250ZW9zDQpxdWUgdmFuIGRlIDE0IGEgMjM4IGNhc29zLiBTaW4gZW1iYXJnbywgYWwgYXBsaWNhciBlbCB1bWJyYWwgZGUgMyBcKg0KUklDLCBudWV2ZSB2YXJpYWJsZXMgbm8gcmVnaXN0cmFuIG5pbmfDum4gdmFsb3IgZXh0cmVtbyB5IGxhcyBkb3MNCnJlc3RhbnRlcyBjb25jZW50cmFuIHVuIG7Dum1lcm8gcmVkdWNpZG86IDE5IGNhc29zIGVuIGxhIGFudGlnw7xlZGFkIGVuIGxhDQplbXByZXNhICgxLDMlKSB5IDMyIGVuIGxvcyBhw7FvcyBkZXNkZSBsYSDDumx0aW1hIHByb21vY2nDs24gKDIsMiUpLiBFc3RhDQpkaWZlcmVuY2lhIHB1ZWRlIG9iZWRlY2VyIGEgbGEgbmF0dXJhbGV6YSBkZSBsYXMgdmFyaWFibGVzIGFudGVzIHF1ZSBhDQpsYSBwcmVzZW5jaWEgZGUgZGF0b3MgYXTDrXBpY29zLiBFbCBjYXNvIGRlIGxhIHZhcmFpYmxlIENhcGFjaXRhY2lvbmVzDQptdWVzdHJhIHF1ZSBzdSByYW5nbyBpbnRlcmN1YXJ0w61saWNvIGVzIGRlIGFwZW5hcyB1bmEgdW5pZGFkLCBwdWVzIGVsDQo1MCUgY2VudHJhbCBkZSBsb3MgZW1wbGVhZG9zIHJlY2liZSBlbnRyZSAyIHkgMyBjYXBhY2l0YWNpb25lcyBhbCBhw7FvLA0KZGUgbW9kbyBxdWUgY3VhbHF1aWVyIHZhbG9yIGRpc3RpbnRvIGRlIDEgYSA0IHF1ZWRhIGF1dG9tw6F0aWNhbWVudGUNCnNlw7FhbGFkby4gTG9zIDIzOCBjYXNvcyBtYXJjYWRvcyBjb3JyZXNwb25kZW4gZW4gcmVhbGlkYWQgYSBsb3MNCmVtcGxlYWRvcyBjb24gMCwgNSBvIDYgY2FwYWNpdGFjaW9uZXMsIHRvZG9zIGVsbG9zIHZhbG9yZXMgcGVyZmVjdGFtZW50ZQ0KdsOhbGlkb3MgZGVudHJvIGRlIGxhIGVzY2FsYS4NCg0KYGBge3IgZmlndXJhLTEtMywgZmlnLndpZHRoID0gMTEsIGZpZy5oZWlnaHQgPSA4LCBmaWcuYWxpZ24gPSAiY2VudGVyIn0NCmRhdG9zX251bSB8Pg0KICBnZ3Bsb3QoYWVzKHkgPSB2YWxvciwgZmlsbCA9IFZhcmlhYmxlKSkgKw0KICBnZW9tX2JveHBsb3QoDQogICAgY29sb3IgPSAiIzRBNEE0QSIsDQogICAgd2lkdGggPSAwLjYwLA0KICAgIGFscGhhID0gMC44NSwNCiAgICBvdXRsaWVyLmNvbG91ciA9ICIjQjg1NDNGIiwNCiAgICBvdXRsaWVyLmFscGhhID0gMC41NSwNCiAgICBvdXRsaWVyLnNpemUgPSAxLjYNCiAgKSArDQogIGZhY2V0X3dyYXAoDQogICAgfiBWYXJpYWJsZSwNCiAgICBzY2FsZXMgPSAiZnJlZV95IiwNCiAgICBuY29sID0gNCwNCiAgICBsYWJlbGxlciA9IGxhYmVsX3dyYXBfZ2VuKDIwKQ0KICApICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2QoDQogICAgb3B0aW9uID0gIkQiLA0KICAgIGVuZCA9IDAuOTAsDQogICAgZ3VpZGUgPSAibm9uZSINCiAgKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiIiwNCiAgICBzdWJ0aXRsZSA9ICJMb3MgcHVudG9zIGNvcnJlc3BvbmRlbiBhIHZhbG9yZXMgYXTDrXBpY29zIHNlZ8O6biBlbCBjcml0ZXJpbyBkZSAxLDUgUklDIiwNCiAgICB4ID0gTlVMTCwNCiAgICB5ID0gTlVMTA0KICApICsNCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMSkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoDQogICAgICBmYWNlID0gInBsYWluIiwNCiAgICAgIHNpemUgPSAxMCwNCiAgICAgIGNvbG9yID0gIiMzMzMzMzMiDQogICAgKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KA0KICAgICAgZmFjZSA9ICJib2xkIiwNCiAgICAgIHNpemUgPSAxNCwNCiAgICAgIGhqdXN0ID0gMC41LA0KICAgICAgY29sb3IgPSAiIzIxMzg0QSINCiAgICApLA0KICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoDQogICAgICBzaXplID0gMTAsDQogICAgICBoanVzdCA9IDAuNSwNCiAgICAgIGNvbG9yID0gIiM0QjU1NjMiDQogICAgKSwNCiAgICBwYW5lbC5zcGFjaW5nID0gdW5pdCgxLCAibGluZXMiKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSINCiAgKQ0KDQpgYGANCg0KKkZpZ3VyYSAxLjMuIERpYWdyYW1hcyBkZSBjYWphIGRlIGxhcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyoNCg0KVW4gZXhhbWVuIGRlIGxvcyBjYXNvcyBzZcOxYWxhZG9zIGJham8gZWwgY3JpdGVyaW8gZGUgMyBSSUMgY29uZmlybWEgcXVlDQpzZSB0cmF0YSBkZSB2YWxvcmVzIHBvc2libGVzIHkgbm8gZGUgZXJyb3JlcyBkZSByZWdpc3Ryby4gTG9zIDE5DQplbXBsZWFkb3MgY29uIG3DoXMgZGUgMjcgYcOxb3MgZGUgYW50aWfDvGVkYWQgeSBsb3MgMzIgY29uIG3DoXMgZGUgMTIgYcOxb3MNCnNpbiBwcm9tb2Npw7NuIHJlcHJlc2VudGFuIHRyYXllY3RvcmlhcyBwcm9sb25nYWRhcywgY29uc2lzdGVudGVzIGNvbiBsb3MNCnZhbG9yZXMgbcOheGltb3MgZGUgZXhwZXJpZW5jaWEgdG90YWwgb2JzZXJ2YWRvcyBlbiBsYSBiYXNlLiBOaW5ndW5hDQp2YXJpYWJsZSBwcmVzZW50YSB2YWxvcmVzIG5lZ2F0aXZvcywgaW1wb3NpYmxlcyBvIGZ1ZXJhIGRlbCByYW5nbyBsw7NnaWNvDQpkZSBzdSBkZWZpbmljacOzbiwgeSBsb3MgbMOtbWl0ZXMgaW5mZXJpb3JlcyBkZWwgY3JpdGVyaW8gbm8gc2UgYWN0aXZhcm9uDQplbiBuaW5nw7puIGNhc28sIGxvIHF1ZSBlcyBjb2hlcmVudGUgY29uIGxhIGFzaW1ldHLDrWEgcG9zaXRpdmENCmRvY3VtZW50YWRhLiBQb3IgZXN0YSByYXrDs24gc2UgZGVjaWRlIGNvbnNlcnZhciBsYSB0b3RhbGlkYWQgZGUgbGFzDQpvYnNlcnZhY2lvbmVzLCBkYWRvIHF1ZSBlc3RvcyB2YWxvcmVzIGV4dHJlbW9zIGFwb3J0YW4gaW5mb3JtYWNpw7NuDQpzdXN0YW50aXZhIHNvYnJlIGxvcyBlbXBsZWFkb3MgZGUgbWF5b3IgcGVybWFuZW5jaWEsIHByZWNpc2FtZW50ZSBlbA0KZ3J1cG8gZGUgaW50ZXLDqXMgZW4gdW4gYW7DoWxpc2lzIGRlIHJvdGFjacOzbi4gU2luIGVtYmFyZ28sIGxhIEZpZ3VyYSAxLjMNCihjb3JyZXNwb25kaWVudGUgYSAxLDVcKlJJQykgZXZpZGVuY2lhIGRvcyBhc3BlY3RvcyBxdWUgY29udmllbmUgc2XDsWFsYXINCmNvbW8gbGltaXRhY2nDs24gZGUgbGEgZnVlbnRlOiBlbCBpbmdyZXNvIG1lbnN1YWwgc2UgYWN1bXVsYSBkZSBmb3JtYQ0Kbm90b3JpYSBlbiBzdSB2YWxvciBtw6F4aW1vICgxOS45OTkpIHkgbGEgZGlzdGFuY2lhIGFsIHRyYWJham8gc2UNCmludGVycnVtcGUgZXhhY3RhbWVudGUgZW4gMjksIHBhdHJvbmVzIHF1ZSBzdWdpZXJlbiBxdWUgbGEgYmFzZSBvcmlnaW5hbA0KcHVkbyB0cnVuY2FyIGFtYmFzIHZhcmlhYmxlcyBlbiB1biB0b3BlIHByZWRlZmluaWRvLg0KDQojIyMgTWF0cml6IGRlIENvcnJlbGFjaW9uZXMgZW50cmUgdmFyaWFibGVzIEN1YW50aXRhdGl2YXMNCg0KU2UgZXhhbWluYW4gbGFzIHJlbGFjaW9uZXMgZW50cmUgbGFzIDExIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIG1lZGlhbnRlDQplbCBjb2VmaWNpZW50ZSBkZSBjb3JyZWxhY2nDs24gZGUgU3BlYXJtYW4sIGVsZWdpZG8gZW4gbHVnYXIgZGVsIGRlDQpQZWFyc29uIGRlYmlkbyBhIGxhIGFzaW1ldHLDrWEgcG9zaXRpdmEgcXVlIHByZXNlbnRhbiBkaWV6IGRlIGVsbGFzLA0Kc2Vnw7puIHNlIGRvY3VtZW50w7MgZW4gZWwgYW7DoWxpc2lzIHVuaXZhcmlhZG8uIEVzdGUgY29lZmljaWVudGUgc2UNCmNhbGN1bGEgc29icmUgZWwgb3JkZW4gZGUgbG9zIHZhbG9yZXMgeSBubyBzb2JyZSBzdSBtYWduaXR1ZCwgcG9yIGxvIHF1ZQ0Kbm8gcmVxdWllcmUgZWwgc3VwdWVzdG8gZGUgbm9ybWFsaWRhZCBuaSByZXN1bHRhIHNlbnNpYmxlIGEgbG9zIHZhbG9yZXMNCmV4dHJlbW9zIGlkZW50aWZpY2Fkb3MgZW4gZWwgcGFzbyBhbnRlcmlvci4gTG9zIHJlc3VsdGFkb3Mgc2UNCnJlcHJlc2VudGFuIGVuIHVuYSBtYXRyaXogZGUgY29ycmVsYWNpb25lcyB5IHNlIHJlc3VtaWVyb24gbG9zIHBhcmVzIGNvbg0KYXNvY2lhY2nDs24gaWd1YWwgbyBzdXBlcmlvciBhIDAsNSwgY29uIGVsIGZpbiBkZSBhbnRpY2lwYXIgcG9zaWJsZXMNCnByb2JsZW1hcyBkZSBtdWx0aWNvbGluZWFsaWRhZCBlbiBsYSBzZWxlY2Npw7NuIGRlIGNvdmFyaWFibGVzIGRlbA0KbW9kZWxvLg0KDQpgYGB7cn0NCm1hdHJpel9jb3IgPC0gcm90X3A1IHw+DQogIHNlbGVjdCh3aGVyZShpcy5udW1lcmljKSkgfD4NCiAgY29yKG1ldGhvZCA9ICJzcGVhcm1hbiIpDQoNCmNvcl9sYXJnYSA8LSBtYXRyaXpfY29yIHw+DQogIGFzLmRhdGEuZnJhbWUoKSB8Pg0KICByb3duYW1lc190b19jb2x1bW4oIlZhcmlhYmxlXzEiKSB8Pg0KICBwaXZvdF9sb25nZXIoLVZhcmlhYmxlXzEsIG5hbWVzX3RvID0gIlZhcmlhYmxlXzIiLCB2YWx1ZXNfdG8gPSAicmhvIikgfD4NCiAgbXV0YXRlKGFjcm9zcyhjKFZhcmlhYmxlXzEsIFZhcmlhYmxlXzIpLA0KICAgICAgICAgICAgICAgIH4gZmFjdG9yKC54LCBsZXZlbHMgPSBjb2xuYW1lcyhtYXRyaXpfY29yKSkpKQ0KDQpjb3JfbGFyZ2EgfD4NCiAgZ2dwbG90KGFlcyh4ID0gVmFyaWFibGVfMSwgeSA9IGZjdF9yZXYoVmFyaWFibGVfMiksIGZpbGwgPSByaG8pKSArDQogIGdlb21fdGlsZShjb2xvciA9ICJ3aGl0ZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGZvcm1hdChyb3VuZChyaG8sIDIpLCBkZWNpbWFsLm1hcmsgPSAiLCIpLA0KICAgICAgICAgICAgICAgIGNvbG9yID0gYWJzKHJobykgPiAwLjYpLCBzaXplID0gMywgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50Mihsb3cgPSAiI2I4NTQzZiIsIG1pZCA9ICJ3aGl0ZSIsIGhpZ2ggPSAiIzIxMzg0YSIsDQogICAgICAgICAgICAgICAgICAgICAgIG1pZHBvaW50ID0gMCwgbGltaXRzID0gYygtMSwgMSksIG5hbWUgPSAiUmhvIikgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhgVFJVRWAgPSAid2hpdGUiLCBgRkFMU0VgID0gIiMyMTM4NGEiKSkgKw0KICBsYWJzKHRpdGxlID0gIiIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTEpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICAgICAgcGxvdC50aXRsZSAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0LCBoanVzdCA9IDAuNSksDQogICAgICAgIHBhbmVsLmdyaWQgID0gZWxlbWVudF9ibGFuaygpKQ0KDQpgYGANCg0KKkZpZ3VyYSAxLjQuIE1hdHJpeiBkZSBjb3JyZWxhY2lvbmVzIGRlIFNwZWFybWFuKg0KDQpMYSBGaWd1cmEgMS40IG11ZXN0cmEgdW5hIGVzdHJ1Y3R1cmEgZGUgY29ycmVsYWNpb25lcyBjbGFyYW1lbnRlDQpzZWdtZW50YWRhLiBMYXMgY3VhdHJvIHZhcmlhYmxlcyBxdWUgbWlkZW4gcGVybWFuZW5jaWEgZW4gbGENCm9yZ2FuaXphY2nDs24gY29uZm9ybWFuIHVuIGJsb3F1ZSBmdWVydGVtZW50ZSBhc29jaWFkbzogbGEgYW50aWfDvGVkYWQgZW4NCmxhIGVtcHJlc2Egc2UgcmVsYWNpb25hIGNvbiBsYSBhbnRpZ8O8ZWRhZCBlbiBlbCBjYXJnbyBhY3R1YWwgKHJobyA9DQowLDg1KSB5IGNvbiBsb3MgYcOxb3MgdHJhYmFqYW5kbyBjb24gZWwgbWlzbW8gamVmZSAocmhvID0gMCw4NCksIHkgZXN0YXMNCmRvcyDDumx0aW1hcyBzZSBhc29jaWFuIGVudHJlIHPDrSBjb24gdW4gY29lZmljaWVudGUgZGUgMCw3Mi4gRXN0ZQ0KY29tcG9ydGFtaWVudG8gZXMgZXNwZXJhZG8sIHB1ZXMgbGFzIHRyZXMgbWlkZW4gYXNwZWN0b3MgZGlzdGludG9zIGRlIHVuDQptaXNtbyBmZW7Ds21lbm86IHF1aWVuIGxsZXZhIG3DoXMgdGllbXBvIGVuIGxhIGVtcHJlc2EgdGllbmRlIGEgYWN1bXVsYXINCnRhbWJpw6luIG3DoXMgdGllbXBvIGVuIHN1IGNhcmdvIHkgYmFqbyBsYSBtaXNtYSBqZWZhdHVyYS4gQSBlbGxhcyBzZQ0Kc3VtYW4gbGEgZXhwZXJpZW5jaWEgbGFib3JhbCB0b3RhbCwgYXNvY2lhZGEgY29uIGxhIGFudGlnw7xlZGFkIChyaG8gPQ0KMCw1OSkgeSBjb24gbGEgZWRhZCAocmhvID0gMCw2NiksIHkgbG9zIGHDsW9zIGRlc2RlIGxhIMO6bHRpbWEgcHJvbW9jacOzbiwNCmNvbiBjb2VmaWNpZW50ZXMgY2VyY2Fub3MgYSAwLDUgZnJlbnRlIGEgbGFzIGRvcyBhbnRpZ8O8ZWRhZGVzLg0KDQpUYW1iacOpbiBlcyByZWxldmFudGUgbGEgYXNvY2lhY2nDs24gZW50cmUgZWwgaW5ncmVzbyBtZW5zdWFsIHkgbG9zIGHDsW9zDQpkZSBleHBlcmllbmNpYSAocmhvID0gMCw3MSksIGVsIHBhciBtw6FzIGFsdG8gZW50cmUgdmFyaWFibGVzIGRlDQpuYXR1cmFsZXphIGRpc3RpbnRhLiBFc3RvIGluZGljYSBxdWUgbGEgcmVtdW5lcmFjacOzbiBlbiBlc3RhDQpvcmdhbml6YWNpw7NuIHJlc3BvbmRlIGVuIGJ1ZW5hIG1lZGlkYSBhIGxhIHRyYXllY3RvcmlhIGFjdW11bGFkYSBkZWwNCmVtcGxlYWRvLCBsbyBxdWUgZGViZSBjb25zaWRlcmFyc2UgYWwgaW50ZXJwcmV0YXIgZWwgZWZlY3RvIGRlbCBzYWxhcmlvDQpzb2JyZSBsYSByb3RhY2nDs24sIHlhIHF1ZSBhbWJhcyB2YXJpYWJsZXMgY29tcGFydGVuIGluZm9ybWFjacOzbi4gRW4NCmNvbnRyYXN0ZSwgdHJlcyB2YXJpYWJsZXMgcmVzdWx0YW4gcHLDoWN0aWNhbWVudGUgaW5kZXBlbmRpZW50ZXMgZGVsDQpyZXN0bzogbGEgZGlzdGFuY2lhIGFsIGx1Z2FyIGRlIHRyYWJham8sIGVsIHBvcmNlbnRhamUgZGUgYXVtZW50bw0Kc2FsYXJpYWwgeSBlbCBuw7ptZXJvIGRlIGNhcGFjaXRhY2lvbmVzIG5vIHN1cGVyYW4gZW4gbmluZ8O6biBjYXNvIHVuDQpjb2VmaWNpZW50ZSBkZSAwLDA1IGVuIHZhbG9yIGFic29sdXRvLiBTdSBpbmRlcGVuZGVuY2lhIGxhcyBjb252aWVydGUgZW4NCmNhbmRpZGF0YXMgYXRyYWN0aXZhcyBwYXJhIGVsIG1vZGVsbywgcHVlcyBhcG9ydGFyw61hbiBpbmZvcm1hY2nDs24gbm8NCmNvbnRlbmlkYSBlbiBsYXMgZGVtw6FzIGNvdmFyaWFibGVzLg0KDQpgYGB7cn0NCmNvcl9sYXJnYSB8Pg0KICBmaWx0ZXIoYXMuaW50ZWdlcihWYXJpYWJsZV8xKSA8IGFzLmludGVnZXIoVmFyaWFibGVfMiksIGFicyhyaG8pID49IDAuNSkgfD4NCiAgYXJyYW5nZShkZXNjKGFicyhyaG8pKSkgfD4NCiAgbXV0YXRlKFJobyA9IHJvdW5kKHJobywgMiksIC5rZWVwID0gInVudXNlZCIpIHw+DQogIHRhYmxhX2VzdGlsbyh0aXR1bG8gPSAiIiwNCiAgICAgICAgICAgICAgIGFsaW5lYWNpb24gPSBjKCJsIiwgImwiLCAiYyIpKQ0KYGBgDQoNCipUYWJsYSAxLjguIFBhcmVzIGRlIHZhcmlhYmxlcyBjb24gY29ycmVsYWNpw7NuIGRlIFNwZWFybWFuIGlndWFsIG8NCnN1cGVyaW9yIGEgMCw1Kg0KDQpMYSDDum5pY2EgYXNvY2lhY2nDs24gbmVnYXRpdmEgYXByZWNpYWJsZSBzZSBwcmVzZW50YSBlbnRyZSBlbCBuw7ptZXJvIGRlDQp0cmFiYWpvcyBhbnRlcmlvcmVzIHkgbGFzIHZhcmlhYmxlcyBkZSBwZXJtYW5lbmNpYSAocmhvIGVudHJlIOKIkjAsMTMgeQ0K4oiSMCwxNyksIGNvaGVyZW50ZSBjb24gbGEgaWRlYSBkZSBxdWUgbG9zIGVtcGxlYWRvcyBjb24gbWF5b3IgbW92aWxpZGFkDQpwcmV2aWEgYWN1bXVsYW4gbWVub3MgdGllbXBvIGVuIHN1IGVtcGxlbyBhY3R1YWwgKFZlciBUYWJsYSAxLjgpLiBBc8OtLA0KbGEgc2VsZWNjacOzbiBkZSBjb3ZhcmlhYmxlcyBkZWwgbW9kZWxvIGxvZ8Otc3RpY28gZGViZXLDoSBldml0YXINCmluY29ycG9yYXIgc2ltdWx0w6FuZWFtZW50ZSB2YXJpYXMgZGUgZXN0YXMgdmFyaWFibGVzLCBkYWRvIHF1ZSBzdQ0Kc29sYXBhbWllbnRvIHByb2R1Y2lyw61hIGNvZWZpY2llbnRlcyBpbmVzdGFibGVzIHkgZGUgaW50ZXJwcmV0YWNpw7NuDQphbWJpZ3VhLg0KDQojIyMgQ29uY2x1c2lvbmVzIGRlbCBBbsOhbGlzaXMgRXhwbG9yYXRvcmlvIGRlIERhdG9zDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0Kcm90YWNpb25fbGltcGlhIDwtIHJvdF9wNQ0Kc2F2ZVJEUyhyb3RhY2lvbl9saW1waWEsICJyb3RhY2lvbl9saW1waWEucmRzIikNCmBgYA0KDQpFbCBwcm9jZXNvIGRlIGV4cGxvcmFjacOzbiB5IGRlcHVyYWNpw7NuIHBlcm1pdGnDsyBlc3RhYmxlY2VyIHF1ZSBsYSBiYXNlDQpkZSBkYXRvcyBkZSByb3RhY2nDs24gcHJlc2VudGEgdW5hIGNhbGlkYWQgZGUgZGF0b3MgYWx0YTogbm8gY29udGllbmUNCnZhbG9yZXMgYXVzZW50ZXMsIHJlZ2lzdHJvcyBkdXBsaWNhZG9zIG5pIGluY29uc2lzdGVuY2lhcyBlbiBsYQ0KZXNjcml0dXJhIGRlIHN1cyBjYXRlZ29yw61hcywgcG9yIGxvIHF1ZSBsYSB0b3RhbGlkYWQgZGUgbGFzIDEuNDcwDQpvYnNlcnZhY2lvbmVzIHNlIGNvbnNlcnbDsyBwYXJhIGVsIGFuw6FsaXNpcy4gTGFzIGludGVydmVuY2lvbmVzIHNlDQpsaW1pdGFyb24gYSBjb3JyZWdpciBlbCB0aXBvIGRlIGRhdG8gZGUgdHJlY2UgdmFyaWFibGVzIGN1eWEgbGVjdHVyYSBubw0KY29ycmVzcG9uZMOtYSBhIHN1IG5hdHVyYWxlemEsIGVuIHBhcnRpY3VsYXIgY2luY28gZXNjYWxhcyBvcmRpbmFsZXMNCnJlZ2lzdHJhZGFzIGNvbW8gbsO6bWVyb3MsIHkgYSBkZXB1cmFyIGxhcyBldGlxdWV0YXMgZGUgY2F0ZWdvcsOtYXMgeQ0Kbm9tYnJlcyBkZSB2YXJpYWJsZXMgY29uIGZpbmVzIGRlIHByZXNlbnRhY2nDs24uDQoNCkVsIGFuw6FsaXNpcyBpZGVudGlmaWPDsyBhZGVtw6FzIGN1YXRybyBlbGVtZW50b3MgcXVlIGNvbmRpY2lvbmFuIGxhcw0KZXRhcGFzIHBvc3RlcmlvcmVzOiBlbCBkZXNiYWxhbmNlIGRlIGxhIHZhcmlhYmxlIHJlc3B1ZXN0YSwgY29uIHVuYQ0KcmF6w7NuIGRlIDUsMiBhIDEgZW50cmUgcGVybWFuZW5jaWEgeSByb3RhY2nDs247IGxhIGF1c2VuY2lhIGRlDQp2YXJpYWJpbGlkYWQgcmVsZXZhbnRlIGVuIGVsIHJlbmRpbWllbnRvIGxhYm9yYWwsIHJlc3RyaW5naWRvIGEgbG9zIGRvcw0Kbml2ZWxlcyBzdXBlcmlvcmVzIGRlIHN1IGVzY2FsYTsgbGEgZnVlcnRlIGNvcnJlbGFjacOzbiBlbnRyZSBsYXMNCnZhcmlhYmxlcyBkZSB0cmF5ZWN0b3JpYSwgcXVlIGRlc2Fjb25zZWphIGluY29ycG9yYXJsYXMgZGUgbWFuZXJhDQpzaW11bHTDoW5lYSBhbCBtb2RlbG87IHkgZWwgcG9zaWJsZSB0cnVuY2FtaWVudG8gZGVsIGluZ3Jlc28gbWVuc3VhbCB5IGxhDQpkaXN0YW5jaWEgYWwgdHJhYmFqbyBlbiBsYSBmdWVudGUgb3JpZ2luYWwsIHF1ZSBkZWJlIGNvbnNpZGVyYXJzZSBjb21vDQpsaW1pdGFjacOzbiBkZWwgZXN0dWRpby4NCg0KIyBNb2RlbG8gZGUgUmVncmVzacOzbiBMb2fDrXN0aWNhIHBhcmEgbGEgcHJlZGljY2nDs24gZGUgcm90YWNpw7NuIGRlIHBlcnNvbmFsDQoNCiMjIFZhcmlhYmxlcyBTZWxlY2Npb25hZGFzIGUgaW5sY3VpZGFzIGVuIGVsIG1vZGVsbw0KDQpFbiBudWVzdHJvIGNhc28geSwgZGVzcHXDqXMgZGUgdW5hIGRpc2NlcnRhY2nDs24gc29icmUgbGFzIHZhcmlhYmxlcyBhDQppbmxjdWlyLCBkZWNpZGltb3MgaW5jbHVpciBjb3ZhcmlhYmxlcyBjb21iaW5hbmRvIGVsIHJlc3BhbGRvIHRlw7NyaWNvIGRlDQpsYSBsaXRlcmF0dXJhIHNvYnJlIHJvdGFjacOzbiBsYWJvcmFsIChlY29ub23DrWEgbGFib3JhbCB5IHBzaWNvbG9nw61hDQpvcmdhbml6YWNpb25hbCkgY29uIGxvcyBoYWxsYXpnb3MgZGVsIGFuw6FsaXNpcyBleHBsb3JhdG9yaW8gKEVEQSBkZWwNCnB1bnRvIDIpLg0KDQpBc8OtLCBkZWwgY29uanVudG8gaW5pY2lhbCBkZSAyMyB2YXJpYWJsZXMgZXhwbGljYXRpdmFzIHNlIGRlc2NhcnRhbg0KYXF1ZWxsYXMgcXVlIGNhcmVjZW4gZGUgdmFyaWFiaWxpZGFkIHN1ZmljaWVudGUsIGxhcyBxdWUgcHJlc2VudGFuDQpjYXRlZ29yw61hcyBjb24gdW4gbsO6bWVybyByZWR1Y2lkbyBkZSBvYnNlcnZhY2lvbmVzIHkgbGFzIHF1ZSBjb25mb3JtYW4NCmVsIGJsb3F1ZSBkZSB0cmF5ZWN0b3JpYSBmdWVydGVtZW50ZSBjb3JyZWxhY2lvbmFkbyBpZGVudGlmaWNhZG8gZW4gbGENCm1hdHJpeiBkZSBjb3JyZWxhY2lvbmVzLCBkZWwgY3VhbCBzZSByZXR1dm8gdW5hIMO6bmljYSByZXByZXNlbnRhbnRlLg0KU29icmUgbGFzIHNlaXMgdmFyaWFibGVzIHJlc3VsdGFudGVzIHNlIGZvcm11bMOzIHVuYSBoaXDDs3Rlc2lzIGV4cGzDrWNpdGENCmFjZXJjYSBkZWwgc2VudGlkbyBlc3BlcmFkbyBkZSBzdSByZWxhY2nDs24gY29uIGxhIHByb2JhYmlsaWRhZCBkZQ0Kcm90YWNpw7NuLCB0YWwgY29tbyBzZSByZXN1bWUgZW4gbGEgVGFibGEgMy4xLg0KDQpgYGB7cn0NCnJvdGFjaW9uX3NlbCA8LSByb3RhY2lvbl9saW1waWEgfD4NCiAgc2VsZWN0KFJvdGFjacOzbiwNCiAgICAgICAgIEhvcmFzX0V4dHJhLCBFc3RhZG9fQ2l2aWwsIFNhdGlzZmFjY2nDs25fTGFib3JhbCwNCiAgICAgICAgIEVkYWQsIEluZ3Jlc29fTWVuc3VhbCwgQW50aWfDvGVkYWRfQ2FyZ28pDQoNCnZhcmlhYmxlc19zZWwgPC0gdGliYmxlKA0KICBWYXJpYWJsZSA9IGMoIkhvcmFzX0V4dHJhIiwgIkVzdGFkb19DaXZpbCIsICJTYXRpc2ZhY2Npw7NuX0xhYm9yYWwiLA0KICAgICAgICAgICAgICAgIkVkYWQiLCAiSW5ncmVzb19NZW5zdWFsIiwgIkFudGlnw7xlZGFkX0NhcmdvIiksDQogIFRpcG8gPSBjKCJDdWFsaXRhdGl2YSBub21pbmFsIiwgIkN1YWxpdGF0aXZhIG5vbWluYWwiLCAiQ3VhbGl0YXRpdmEgb3JkaW5hbCIsDQogICAgICAgICAgICJDdWFudGl0YXRpdmEiLCAiQ3VhbnRpdGF0aXZhIiwgIkN1YW50aXRhdGl2YSIpLA0KICBgUmVsYWNpw7NuIGVzcGVyYWRhIGNvbiBsYSByb3RhY2nDs25gID0gYygNCiAgICAiUG9zaXRpdmE6IG1heW9yIHByb2JhYmlsaWRhZCBkZSByb3RhY2nDs24gZW4gcXVpZW5lcyB0cmFiYWphbiBob3JhcyBleHRyYSIsDQogICAgIlBvc2l0aXZhIGVuIHNvbHRlcm9zIGZyZW50ZSBhIGNhc2Fkb3MgeSBkaXZvcmNpYWRvcyIsDQogICAgIk5lZ2F0aXZhOiBhIG1heW9yIHNhdGlzZmFjY2nDs24sIG1lbm9yIHByb2JhYmlsaWRhZCBkZSByb3RhY2nDs24iLA0KICAgICJOZWdhdGl2YTogYSBtYXlvciBlZGFkLCBtZW5vciBwcm9iYWJpbGlkYWQgZGUgcm90YWNpw7NuIiwNCiAgICAiTmVnYXRpdmE6IGEgbWF5b3IgaW5ncmVzbywgbWVub3IgcHJvYmFiaWxpZGFkIGRlIHJvdGFjacOzbiIsDQogICAgIk5lZ2F0aXZhOiBhIG1heW9yIGFudGlnw7xlZGFkIGVuIGVsIGNhcmdvLCBtZW5vciBwcm9iYWJpbGlkYWQgZGUgcm90YWNpw7NuIikNCikNCg0KdmFyaWFibGVzX3NlbCB8Pg0KICB0YWJsYV9lc3RpbG8odGl0dWxvID0gIiIsDQogICAgICAgICAgICAgICBhbGluZWFjaW9uID0gYygibCIsICJsIiwgImwiKSwNCiAgICAgICAgICAgICAgIG5vdGEgPSAiRWwgc2lnbm8gZXNwZXJhZG8gc2UgcmVmaWVyZSBhbCBlZmVjdG8gc29icmUgbGEgcHJvYmFiaWxpZGFkIGRlIHJvdGFjacOzbiAoeSA9IDEpLiIpIHw+DQogIGNvbHVtbl9zcGVjKDMsIHdpZHRoID0gIjI2ZW0iKQ0KYGBgDQoNCipUYWJsYSAzLjEuIFZhcmlhYmxlcyBzZWxlY2Npb25hZGFzIGUgaGlww7N0ZXNpcyBkZSByZWxhY2nDs24gY29uIGxhDQpyb3RhY2nDs24qDQoNCiMjIEVsZW1lbnRvcyB0ZcOzcmljb3MgY29uc2lkZXJhZG9zDQoNCiMjIyBIaXDDs3Rlc2lzIFZhcmlhYmxlcyBDdWFsaXRhdGl2YXMNCg0KU2UgZXNwZXJhIHF1ZSBsYXMgaG9yYXMgZXh0cmFzIGVuIGVsIHRyYWJham8gaW5jcmVtZW50ZSBsYSBwcm9iYWJpbGlkYWQNCmRlIHJvdGFjacOzbi4gTGEgbGl0ZXJhdHVyYSBkb2N1bWVudGEgcXVlIGxhIHNvYnJlY2FyZ2EgbGFib3JhbCB5IGVsDQpjb25mbGljdG8gZW50cmUgbGFzIGRlbWFuZGFzIGRlbCB0cmFiYWpvIHkgbGEgdmlkYSBwZXJzb25hbCBjb25zdGl0dXllbg0KYW50ZWNlZGVudGVzIGNvbnNpc3RlbnRlcyBkZSBsYSBpbnRlbmNpw7NuIGRlIHJlbnVuY2lhLCBhbCBkZXRlcmlvcmFyDQpwcm9ncmVzaXZhbWVudGUgbGEgdmFsb3JhY2nDs24gcXVlIGVsIGVtcGxlYWRvIGhhY2UgZGUgc3Ugc2l0dWFjacOzbg0KYWN0dWFsIChHcmlmZmV0aCBldCBhbC4sIDIwMDApLiBFbiBlc3RhIGJhc2UsIGVsIDI4LDMlIGRlIGxvcyBlbXBsZWFkb3MNCnRyYWJhamEgaG9yYXMgZXh0cmEsIHVuYSBwcm9wb3JjacOzbiBzdWZpY2llbnRlIHBhcmEgZXN0aW1hciBlbCBlZmVjdG8NCmNvbiBwcmVjaXNpw7NuIHJhem9uYWJsZS4gRW4gY3VhbnRvIGFsIGVzdGFkbyBjaXZpbCwgc2UgcGxhbnRlYSBxdWUgbG9zDQplbXBsZWFkb3Mgc29sdGVyb3MgcHJlc2VudGVuIG1heW9yIHByb2JhYmlsaWRhZCBkZSByb3RhY2nDs24gcXVlIGxvcw0KY2FzYWRvcyB5IGRpdm9yY2lhZG9zLiBMYSBleHBsaWNhY2nDs24gcHJvdmllbmUgZGUgbGEgdGVvcsOtYSBkZSBsYXMNCmFwdWVzdGFzIGxhdGVyYWxlcyBkZSBCZWNrZXIgKDE5NjApLCBzZWfDum4gbGEgY3VhbCBsYXMgcGVyc29uYXMgYWN1bXVsYW4NCmNvbXByb21pc29zIGV4dGVybm9zIGFsIHRyYWJham8gKGZhbWlsaWFyZXMsIGZpbmFuY2llcm9zLCBjb211bml0YXJpb3MpDQpxdWUgZWxldmFuIGVsIGNvc3RvIGRlIGFiYW5kb25hciBzdSBlbXBsZW8gYWN0dWFsOyBxdWllbmVzIHRpZW5lbiBtZW5vcw0KdsOtbmN1bG9zIGRlIGVzdGUgdGlwbyBlbmZyZW50YW4gdW4gY29zdG8gZGUgc2FsaWRhIG1lbm9yLiBGaW5hbG1lbnRlLCBzZQ0KZXNwZXJhIHVuYSByZWxhY2nDs24gbmVnYXRpdmEgZW50cmUgbGEgc2F0aXNmYWNjacOzbiBsYWJvcmFsIHkgbGENCnJvdGFjacOzbjogZWwgbW9kZWxvIGRlIHbDrW5jdWxvcyBpbnRlcm1lZGlvcyBkZSBNb2JsZXkgKDE5NzcpIGVzdGFibGVjZQ0KcXVlIGxhIGluc2F0aXNmYWNjacOzbiBjb24gZWwgdHJhYmFqbyBkZXNlbmNhZGVuYSBsYSBiw7pzcXVlZGEgZGUNCmFsdGVybmF0aXZhcywgbGEgZXZhbHVhY2nDs24gY29tcGFyYXRpdmEgZGUgZXN0YXMgeSwgZXZlbnR1YWxtZW50ZSwgbGENCmRlY2lzacOzbiBkZSByZW51bmNpYXIuDQoNCiMjIyBIaXDDs3Rlc2lzIFZhcmlhYmxlcyBDdWFudGl0YXRpdmFzDQoNClBhcmEgbGEgZWRhZCBzZSBwbGFudGVhIHVuYSByZWxhY2nDs24gbmVnYXRpdmEsIHlhIHNlIHF1ZSBpZGVudGlmaWNhIGVzdGENCnZhcmlhYmxlIGNvbW8gdW5vIGRlIGxvcyBwcmVkaWN0b3JlcyBkZW1vZ3LDoWZpY29zIG3DoXMgZXN0YWJsZXMgZGUgbGENCnJvdGFjacOzbiAoR3JpZmZldGggZXQgYWwuLCAyMDAwKS4gTG9zIGVtcGxlYWRvcyBkZSBtYXlvciBlZGFkIHN1ZWxlbg0KZW5mcmVudGFyIHVuIG1lcmNhZG8gbGFib3JhbCBtZW5vcyBmYXZvcmFibGUgeSBoYWJlciBjb25zb2xpZGFkbyBzdQ0KdHJheWVjdG9yaWEsIGxvIHF1ZSByZWR1Y2Ugc3UgcHJvcGVuc2nDs24gYWwgY2FtYmlvLiBSZXNwZWN0byBhbCBpbmdyZXNvDQptZW5zdWFsLCBzZSBlc3BlcmEgaWd1YWxtZW50ZSB1bmEgcmVsYWNpw7NuIG5lZ2F0aXZhLCBiYWpvIGVsIGFyZ3VtZW50bw0KZGUgcXVlIHVuYSByZW11bmVyYWNpw7NuIG3DoXMgYWx0YSBpbmNyZW1lbnRhIGVsIGNvc3RvIGRlIG9wb3J0dW5pZGFkIGRlDQpyZW51bmNpYXIuIENvbnZpZW5lIGFudGljaXBhciwgbm8gb2JzdGFudGUsIHF1ZSBBbGxlbiBldCBhbC4gKDIwMTApDQphZHZpZXJ0ZW4gcXVlIGVsIG5pdmVsIHNhbGFyaWFsIGNvbnN0aXR1eWUgdW4gcHJlZGljdG9yIG3DoXMgZMOpYmlsIGRlIGxvDQpxdWUgc3VlbGUgc3Vwb25lcnNlIGVuIGxhIHByw6FjdGljYSBvcmdhbml6YWNpb25hbCwgcG9yIGxvIHF1ZSBlbCBlZmVjdG8NCnBvZHLDrWEgcmVzdWx0YXIgbWVub3IgYWwgZXNwZXJhZG8uIFBvciDDumx0aW1vLCBzZSBwbGFudGVhIHF1ZSBsYQ0KYW50aWfDvGVkYWQgZW4gZWwgY2FyZ28gYWN0dWFsIHJlZHV6Y2EgbGEgcHJvYmFiaWxpZGFkIGRlIHJvdGFjacOzbiwgZGFkbw0KcXVlIGVsIHRpZW1wbyBkZSBwZXJtYW5lbmNpYSByZWZsZWphIGVsIGdyYWRvIGRlIGFycmFpZ28gZGVsIGVtcGxlYWRvIGVuDQpzdSByb2wsIGVuIHN1IGVxdWlwbyBkZSB0cmFiYWpvIHkgZW4gbGFzIHJ1dGluYXMgZGUgbGEgb3JnYW5pemFjacOzbiwgdW4NCm1lY2FuaXNtbyBxdWUgbGEgbGl0ZXJhdHVyYSByZWNpZW50ZSBhZ3J1cGEgYmFqbyBlbCBjb25jZXB0byBkZQ0KaW5jcnVzdGFjacOzbiBsYWJvcmFsIChIb20gZXQgYWwuLCAyMDE3KS4gRXN0YSB2YXJpYWJsZSBmdWUgc2VsZWNjaW9uYWRhDQpjb21vIHJlcHJlc2VudGFudGUgZGVsIGJsb3F1ZSBkZSB0cmF5ZWN0b3JpYSBwb3Igc3UgY2VyY2Fuw61hIGNvbmNlcHR1YWwNCmNvbiBlbCBmZW7Ds21lbm8gcXVlIGludGVyZXNhIGVzdHVkaWFyLCBlbCBjYW1iaW8gZGUgY2FyZ28uDQoNCiMjIEFuw6FsaXNpcyBVbml2YXJpYWRvIGRlIGxhcyB2YXJpYWJsZXMgc2VsZWNjaW9uYWRhcw0KDQpFbCBhbsOhbGlzaXMgdW5pdmFyaWFkbyBjYXJhY3Rlcml6YSBsYSB2YXJpYWJsZSByZXNwdWVzdGEgeSBsYXMgc2Vpcw0KY292YXJpYWJsZXMgc2VsZWNjaW9uYWRhcywgZW1wbGVhbmRvIGVuIGNhZGEgY2FzbyBsb3MgaW5kaWNhZG9yZXMgcXVlDQpjb3JyZXNwb25kZW4gYSBzdSB0aXBvLiBMYXMgdHJlcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyBzZSBkZXNjcmliZW4NCm1lZGlhbnRlIG1lZGlkYXMgZGUgdGVuZGVuY2lhIGNlbnRyYWwsIGRpc3BlcnNpw7NuIHkgZm9ybWEsDQpjb21wbGVtZW50YWRhcyBjb24gaGlzdG9ncmFtYXMuIExhcyBjdWF0cm8gdmFyaWFibGVzIGN1YWxpdGF0aXZhcywNCmluY2x1aWRhIFJvdGFjacOzbiwgc2UgY2FyYWN0ZXJpemFuIG1lZGlhbnRlIGRpc3RyaWJ1Y2lvbmVzIGRlIGZyZWN1ZW5jaWENCmFic29sdXRhIHkgcmVsYXRpdmEsIHJlcHJlc2VudGFkYXMgZW4gZ3LDoWZpY29zIGRlIGJhcnJhcy4NCg0KYGBge3J9DQpudW1fc2VsIDwtIHJvdGFjaW9uX3NlbCB8Pg0KICBzZWxlY3Qod2hlcmUoaXMubnVtZXJpYykpIHw+DQogIHBpdm90X2xvbmdlcihldmVyeXRoaW5nKCksIG5hbWVzX3RvID0gIlZhcmlhYmxlIiwgdmFsdWVzX3RvID0gInZhbG9yIikgfD4NCiAgbXV0YXRlKFZhcmlhYmxlID0gZmN0X2lub3JkZXIoVmFyaWFibGUpKQ0KDQpkZXNjX3NlbCA8LSBudW1fc2VsIHw+DQogIGdyb3VwX2J5KFZhcmlhYmxlKSB8Pg0KICBzdW1tYXJpc2UoTWVkaWEgPSBtZWFuKHZhbG9yKSwgTWVkaWFuYSA9IG1lZGlhbih2YWxvciksIERFID0gc2QodmFsb3IpLA0KICAgICAgICAgICAgYENWICglKWAgPSAxMDAgKiBzZCh2YWxvcikgLyBtZWFuKHZhbG9yKSwNCiAgICAgICAgICAgIE3DrW4gPSBtaW4odmFsb3IpLCBRMSA9IHF1YW50aWxlKHZhbG9yLCAwLjI1KSwNCiAgICAgICAgICAgIFEzID0gcXVhbnRpbGUodmFsb3IsIDAuNzUpLCBNw6F4ID0gbWF4KHZhbG9yKSwNCiAgICAgICAgICAgIEFzaW1ldHLDrWEgPSBlMTA3MTo6c2tld25lc3ModmFsb3IsIHR5cGUgPSAyKSkgfD4NCiAgbXV0YXRlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiByb3VuZCgueCwgMikpKQ0KDQpkZXNjX3NlbCB8Pg0KICB0YWJsYV9lc3RpbG8odGl0dWxvID0gIiIsDQogICAgICAgICAgICAgICBub3RhID0gIkRFOiBkZXN2aWFjacOzbiBlc3TDoW5kYXI7IENWOiBjb2VmaWNpZW50ZSBkZSB2YXJpYWNpw7NuLiIpDQoNCmBgYA0KDQoqVGFibGEgMy4yLiBFc3RhZMOtc3RpY29zIGRlc2NyaXB0aXZvcyBkZSBsYXMgY292YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyoNCg0KTGEgVGFibGEgMy4yIG11ZXN0cmEgcXVlIGxhIGVkYWQgZGUgbG9zIGVtcGxlYWRvcyBvc2NpbGEgZW50cmUgMTggeSA2MA0KYcOxb3MsIGNvbiB1bmEgbWVkaWEgZGUgMzYsOSB5IHVuYSBtZWRpYW5hIGRlIDM2LiBFcyBsYSDDum5pY2EgZGUgbGFzIHRyZXMNCnZhcmlhYmxlcyBjb24gZGlzdHJpYnVjacOzbiBhcHJveGltYWRhbWVudGUgc2ltw6l0cmljYSAoYXNpbWV0csOtYSBkZSAwLDQxKQ0KeSBsYSBtw6FzIGhvbW9nw6luZWEgZGVsIGNvbmp1bnRvLCBjb24gdW4gY29lZmljaWVudGUgZGUgdmFyaWFjacOzbiBkZWwNCjI0LDclLiBFbCBpbmdyZXNvIG1lbnN1YWwsIGVuIGNhbWJpbywgcHJlc2VudGEgdW5hIGZ1ZXJ0ZSBhc2ltZXRyw61hDQpwb3NpdGl2YSAoMSwzNyk6IHN1IG1lZGlhIGRlIDYuNTAyLDkzIHN1cGVyYSBlbiBjYXNpIDEuNjAwIHVuaWRhZGVzIGEgbGENCm1lZGlhbmEgZGUgNC45MTksIGxvIHF1ZSBpbmRpY2EgcXVlIHVuIGdydXBvIHJlZHVjaWRvIGRlIGVtcGxlYWRvcyBjb24NCnNhbGFyaW9zIGVsZXZhZG9zIGRlc3BsYXphIGVsIHByb21lZGlvIHBvciBlbmNpbWEgZGVsIHZhbG9yIHTDrXBpY28uIEVsDQo1MCUgY2VudHJhbCBkZSBsYSBwbGFudGlsbGEgZGUgZW1wbGVhZG9zIHBlcmNpYmUgZW50cmUgMi45MTEgeSA4LjM3OSwNCmNvbiB1biBtw6F4aW1vIGRlIDE5Ljk5OS4gRmluYWxtZW50ZSwgbGEgYW50aWfDvGVkYWQgZW4gZWwgY2FyZ28gYWN0dWFsDQptdWVzdHJhIHVuYSBtZWRpYW5hIGRlIDMgYcOxb3MgeSB1bmEgbWVkaWEgZGUgNCwyLCB0YW1iacOpbiBjb24gYXNpbWV0csOtYQ0KcG9zaXRpdmEgKDAsOTIpIHkgdW5hIGRpc3BlcnNpw7NuIHJlbGF0aXZhIGVsZXZhZGEgKENWIGRlIDg1LDclKS4gVW4gMjUlDQpkZSBsb3MgZW1wbGVhZG9zIGxsZXZhIGRvcyBhw7FvcyBvIG1lbm9zIGVuIHN1IGNhcmdvLCBtaWVudHJhcyBxdWUgZWwNCnZhbG9yIG3DoXhpbW8gYWxjYW56YSAxOCBhw7Fvcy4gTGEgYXNpbWV0csOtYSBkZSBlc3RhcyBkb3Mgw7psdGltYXMNCnZhcmlhYmxlcyBubyBjb21wcm9tZXRlIGxhIGVzdGltYWNpw7NuIGRlbCBtb2RlbG8gbG9nw61zdGljbywgZGFkbyBxdWUNCmVzdGUgbm8gZXhpZ2Ugbm9ybWFsaWRhZCBlbiBsYXMgY292YXJpYWJsZXMgKFZlciBGaWd1cmEgMy4xKS4NCg0KYGBge3J9DQpudW1fc2VsIHw+DQogIGdncGxvdChhZXMoeCA9IHZhbG9yKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMjUsIGZpbGwgPSAiIzIxMzg0YSIsIGNvbG9yID0gIndoaXRlIikgKw0KICBmYWNldF93cmFwKH4gVmFyaWFibGUsIHNjYWxlcyA9ICJmcmVlIiwgbmNvbCA9IDMsDQogICAgICAgICAgICAgbGFiZWxsZXIgPSBsYWJlbF93cmFwX2dlbigyMCkpICsNCiAgbGFicyh0aXRsZSA9ICIiLA0KICAgICAgIHggPSBOVUxMLCB5ID0gIkZyZWN1ZW5jaWEiKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTEpICsNCiAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTApLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCwgaGp1c3QgPSAwLjUpKQ0KDQpgYGANCg0KKkZpZ3VyYSAzLjEuIEhpc3RvZ3JhbWEgZGUgRGlzdHJpYnVjacOzbiBkZSBGcmVjdWVuY2lhcyBsYXMgY292YXJpYWJsZXMNCmN1YW50aXRhdGl2YXMqDQoNCkFob3JhIGJpZW4sIExhIFRhYmxhIDMuMyBtdWVzdHJhIHF1ZSBlbCAyOCwzJSBkZSBsb3MgZW1wbGVhZG9zIHRyYWJhamENCmhvcmFzIGV4dHJhICg0MTYgcGVyc29uYXMpLCBmcmVudGUgYSB1biA3MSw3JSBxdWUgbm8gbG8gaGFjZS4gRW4gY3VhbnRvDQphbCBlc3RhZG8gY2l2aWwsIGVsIGdydXBvIHByZWRvbWluYW50ZSBlcyBlbCBkZSBsb3MgY2FzYWRvcywgY29uIDY3Mw0KZW1wbGVhZG9zICg0NSw4JSksIHNlZ3VpZG8gcG9yIGxvcyBzb2x0ZXJvcyBjb24gNDcwICgzMiwwJSkgeSBsb3MNCmRpdm9yY2lhZG9zIGNvbiAzMjcgKDIyLDIlKS4gTGFzIHRyZXMgY2F0ZWdvcsOtYXMgY3VlbnRhbiBjb24gdW4gbsO6bWVybw0Kc3VmaWNpZW50ZSBkZSBvYnNlcnZhY2lvbmVzLCBsbyBxdWUgcGVybWl0ZSBlc3RpbWFyIHN1cyBlZmVjdG9zIHNpbg0Kcmllc2dvIGRlIGluZXN0YWJpbGlkYWQuIExhIHNhdGlzZmFjY2nDs24gbGFib3JhbCBwcmVzZW50YSB1bmENCmRpc3RyaWJ1Y2nDs24gZmF2b3JhYmxlIGVuIHTDqXJtaW5vcyBhZ3JlZ2Fkb3MsIHBlcm8gY29uIHVuYSBwcm9wb3JjacOzbg0KYXByZWNpYWJsZSBkZSBlbXBsZWFkb3MgaW5zYXRpc2ZlY2hvczogZWwgNjEsMyUgc2UgZGVjbGFyYSBzYXRpc2ZlY2hvDQooMzAsMSUpIG8gbXV5IHNhdGlzZmVjaG8gKDMxLDIlKSwgbWllbnRyYXMgcXVlIGVsIDE5LDAlIHNlIG1hbmlmaWVzdGENCmluc2F0aXNmZWNobyB5IGVsIDE5LDclIG11eSBpbnNhdGlzZmVjaG8uIEVzdGEgdmFyaWFiaWxpZGFkIGVzDQpwcmVjaXNhbWVudGUgbG8gcXVlIGhhY2Ugw7p0aWwgYSBsYSB2YXJpYWJsZSBjb21vIHByZWRpY3RvciwgZW4gY29udHJhc3RlDQpjb24gZWwgcmVuZGltaWVudG8gbGFib3JhbCwgZGVzY2FydGFkbyBwb3IgY29uY2VudHJhcnNlIGVuIHVuIMO6bmljbw0KZXh0cmVtbyBkZSBzdSBlc2NhbGEgKFZlciBGaWd1cmEgMy4yKS4NCg0KYGBge3J9DQpjYXRfc2VsIDwtIHJvdGFjaW9uX3NlbCB8Pg0KICBzZWxlY3Qod2hlcmUoaXMuZmFjdG9yKSkgfD4NCiAgaW1hcF9kZnIofiB0aWJibGUoVmFyaWFibGUgPSAueSwgQ2F0ZWdvcsOtYSA9IGFzLmNoYXJhY3RlcigueCksDQogICAgICAgICAgICAgICAgICAgIE9yZGVuID0gYXMuaW50ZWdlcigueCkpKSB8Pg0KICBtdXRhdGUoVmFyaWFibGUgPSBmY3RfaW5vcmRlcihWYXJpYWJsZSkpDQoNCmNhdF9zZWwgfD4NCiAgY291bnQoVmFyaWFibGUsIENhdGVnb3LDrWEsIE9yZGVuLCBuYW1lID0gIkZyZWN1ZW5jaWEiKSB8Pg0KICBncm91cF9ieShWYXJpYWJsZSkgfD4NCiAgbXV0YXRlKGBQb3JjZW50YWplICglKWAgPSByb3VuZCgxMDAgKiBGcmVjdWVuY2lhIC8gc3VtKEZyZWN1ZW5jaWEpLCAxKSkgfD4NCiAgdW5ncm91cCgpIHw+DQogIGFycmFuZ2UoVmFyaWFibGUsIE9yZGVuKSB8Pg0KICBzZWxlY3QoLU9yZGVuKSB8Pg0KICB0YWJsYV9lc3RpbG8odGl0dWxvID0gIiIsDQogICAgICAgICAgICAgICBhbGluZWFjaW9uID0gYygibCIsICJsIiwgImMiLCAiYyIpKSB8Pg0KICBjb2xsYXBzZV9yb3dzKGNvbHVtbnMgPSAxLCB2YWxpZ24gPSAidG9wIikNCmBgYA0KDQoqVGFibGEgMy4zLiBEaXN0cmlidWNpw7NuIGRlIGxhIHZhcmlhYmxlIHJlc3B1ZXN0YSB5IGRlIGxhcyBjb3ZhcmlhYmxlcw0KY3VhbGl0YXRpdmFzKg0KDQpEZSBsb3MgMS40NzAgZW1wbGVhZG9zIHF1ZSBpbnRlZ3JhbiBsYSBiYXNlLCAyMzcgcmVnaXN0cmFyb24gcm90YWNpw7NuLA0KZXF1aXZhbGVudGVzIGFsIDE2LDElLCBmcmVudGUgYSAxLjIzMyBxdWUgcGVybWFuZWNpZXJvbiBlbiBzdSBjYXJnbw0KKDgzLDklKS4gTGEgcmF6w7NuIGVudHJlIGFtYm9zIGdydXBvcyBlcyBkZSA1LDIgYSAxLCBsbyBxdWUgZXZpZGVuY2lhIHVuDQptYXJjYWRvIGRlc2JhbGFuY2UgZW50cmUgbGFzIGNhdGVnb3LDrWFzIGRlIGxhIHZhcmlhYmxlIGRlcGVuZGllbnRlLiBFc3RlDQpjb21wb3J0YW1pZW50byBjb25sbGV2YSB0cmVzIGltcGxpY2FjaW9uZXMgbWV0b2RvbMOzZ2ljYXMuIEVuIHByaW1lcg0KbHVnYXIsIGxhIGV4YWN0aXR1ZCBnbG9iYWwgbm8gZXMgdW4gY3JpdGVyaW8gYWRlY3VhZG8gcGFyYSBldmFsdWFyIGVsDQptb2RlbG8sIHB1ZXMgdW4gY2xhc2lmaWNhZG9yIHF1ZSBhc2lnbmFyYSBhIHRvZG9zIGxvcyBlbXBsZWFkb3MgYSBsYQ0KY2F0ZWdvcsOtYSAiTm8gcm90YSIgYWxjYW56YXLDrWEgdW4gODMsOSUgZGUgYWNpZXJ0b3Mgc2luIGNhcGFjaWRhZA0KZGlzY3JpbWluYW50ZSBhbGd1bmEuIEVuIHNlZ3VuZG8gbHVnYXIsIGVsIHB1bnRvIGRlIGNvcnRlIGNvbnZlbmNpb25hbA0KZGUgMCw1IHRpZW5kZSBhIGNsYXNpZmljYXIgY29tbyBubyByb3RhbnRlcyBhIGxhIG1heW9yw61hIGRlIGxvcyBjYXNvcyBlbg0KY29udGV4dG9zIGRlc2JhbGFuY2VhZG9zLCBwb3IgbG8gcXVlIHN1IGRlZmluaWNpw7NuIGRlYmVyw6EgYW5hbGl6YXJzZSBkZQ0KZm9ybWEgZXhwbMOtY2l0YS4gRW4gdGVyY2VyIGx1Z2FyLCBsYSBtYWduaXR1ZCBkZWwgZ3J1cG8gbWlub3JpdGFyaW8sIDIzNw0KY2Fzb3MsIHJlc3VsdGEgc3VmaWNpZW50ZSBwYXJhIGVzdGltYXIgc2VpcyBjb3ZhcmlhYmxlcyBjb24gcHJlY2lzacOzbg0KcmF6b25hYmxlLCBkYWRvIHF1ZSBzdXBlcmEgYW1wbGlhbWVudGUgZWwgY3JpdGVyaW8gb3JpZW50YXRpdm8gZGUgZGlleg0KZXZlbnRvcyBwb3IgcGFyw6FtZXRybyBoYWJpdHVhbG1lbnRlIGVtcGxlYWRvIGVuIHJlZ3Jlc2nDs24gbG9nw61zdGljYSAoVmVyDQpGaWd1cmEgMy4yKS4NCg0KYGBge3J9DQoNCm5pdmVsZXNfc2VsIDwtIGNhdF9zZWwgfD4NCiAgZGlzdGluY3QoVmFyaWFibGUsIENhdGVnb3LDrWEsIE9yZGVuKSB8Pg0KICBhcnJhbmdlKFZhcmlhYmxlLCBkZXNjKE9yZGVuKSkgfD4NCiAgbXV0YXRlKEV0aXF1ZXRhID0gcGFzdGUoQ2F0ZWdvcsOtYSwgVmFyaWFibGUsIHNlcCA9ICJfX18iKSkgfD4NCiAgcHVsbChFdGlxdWV0YSkNCg0KY2F0X3NlbCB8Pg0KICBtdXRhdGUoRXRpcXVldGEgPSBmYWN0b3IocGFzdGUoQ2F0ZWdvcsOtYSwgVmFyaWFibGUsIHNlcCA9ICJfX18iKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IG5pdmVsZXNfc2VsKSkgfD4NCiAgZ2dwbG90KGFlcyh5ID0gRXRpcXVldGEpKSArDQogIGdlb21fYmFyKGZpbGwgPSAiIzIxMzg0YSIsIHdpZHRoID0gMC43KSArDQogIGZhY2V0X3dyYXAofiBWYXJpYWJsZSwgc2NhbGVzID0gImZyZWUiLCBuY29sID0gMiwNCiAgICAgICAgICAgICBsYWJlbGxlciA9IGxhYmVsX3dyYXBfZ2VuKDIyKSkgKw0KICBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IH4gc3ViKCJfX18uKiQiLCAiIiwgLngpKSArDQogIGxhYnModGl0bGUgPSAiIiwNCiAgICAgICB4ID0gIkZyZWN1ZW5jaWEiLCB5ID0gTlVMTCkgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDExKSArDQogIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDEwKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTMsIGhqdXN0ID0gMC41KSwNCiAgICAgICAgcGFuZWwuc3BhY2luZyA9IHVuaXQoMSwgImxpbmVzIikpDQpgYGANCg0KKkZpZ3VyYSAzLjIuIERpc3RyaWJ1Y2nDs24gZGUgbGEgdmFyaWFibGUgcmVzcHVlc3RhIHkgZGUgbGFzIGNvdmFyaWFibGVzDQpjdWFsaXRhdGl2YXMqDQoNCiMjIEFuw6FsaXNpcyBCaXZhcmlhZG8NCg0KRWwgYW7DoWxpc2lzIGJpdmFyaWFkbyBleGFtaW5hIGxhIHJlbGFjacOzbiBpbmRpdmlkdWFsIGRlIGNhZGEgY292YXJpYWJsZQ0KY29uIGxhIHJvdGFjacOzbiwgY29kaWZpY2FkYSBjb21vIHZhcmlhYmxlIGJpbmFyaWEgZW4gbGEgcXVlIGVsIHZhbG9yIDENCmNvcnJlc3BvbmRlIGEgbG9zIGVtcGxlYWRvcyBxdWUgcm90YXJvbiB5IGVsIDAgYSBxdWllbmVzIHBlcm1hbmVjaWVyb24uDQpQYXJhIGxhcyBjb3ZhcmlhYmxlcyBjdWFsaXRhdGl2YXMgc2UgY2FsY3VsYSBsYXMgdGFzYXMgZGUgcm90YWNpw7NuIHBvcg0KY2F0ZWdvcsOtYSB5IHNlIGNvbnRyYXN0YSBsYSBpbmRlcGVuZGVuY2lhIHJlc3BlY3RvIGRlIGxhIHZhcmlhYmxlDQpyZXNwdWVzdGEgbWVkaWFudGUgbGEgcHJ1ZWJhIGNoaS1jdWFkcmFkby4NCg0KUGFyYSBsYXMgY3VhbnRpdGF0aXZhcyBzZSBjb21wYXJhcmEgbGFzIGRpc3RyaWJ1Y2lvbmVzIGRlIGFtYm9zIGdydXBvcyBhDQp0cmF2w6lzIGRlIG1lZGlkYXMgZGUgdGVuZGVuY2lhIGNlbnRyYWwgeSBkaXNwZXJzacOzbiwgeSBzZSBhcGxpY2EgbGENCnBydWViYSBkZSBXaWxjb3hvbi1NYW5uLVdoaXRuZXksIGVsZWdpZGEgZW4gbHVnYXIgZGUgbGEgcHJ1ZWJhIHQtU3R1ZGVudA0KZGViaWRvIGEgbGEgYXNpbWV0csOtYSBkb2N1bWVudGFkYSBlbiBlbCBhbsOhbGlzaXMgdW5pdmFyaWFkby4NCg0KRmluYWxtZW50ZSwgc2UgZXN0aW1hIHVuYSByZWdyZXNpw7NuIGxvZ8Otc3RpY2Egc2ltcGxlIHBvciBjYWRhDQpjb3ZhcmlhYmxlLCBjdXlvcyBjb2VmaWNpZW50ZXMgcGVybWl0ZW4gZXN0YWJsZWNlciBlbCBzZW50aWRvIHkgbGENCm1hZ25pdHVkIGRlIGxhIGFzb2NpYWNpw7NuIGNvbiBsYSBwcm9iYWJpbGlkYWQgZGUgcm90YWNpw7NuLCBhc8OtIGNvbW8gc3UNCnNpZ25pZmljYW5jaWEgZXN0YWTDrXN0aWNhLiBFbiBlbCBjYXNvIGRlIGxhIHNhdGlzZmFjY2nDs24gbGFib3JhbCwgbGENCnZhcmlhYmxlIHNlIHRyYXRhIGNvbW8gZmFjdG9yIG5vbWluYWwgY29uIGxhIGNhdGVnb3LDrWEgIkJhamEiIGNvbW8NCnJlZmVyZW5jaWEsIGNvbiBlbCBmaW4gZGUgb2J0ZW5lciBjb2VmaWNpZW50ZXMgZGlyZWN0YW1lbnRlDQppbnRlcnByZXRhYmxlcy4NCg0KIyMjIFRhc2FzIGRlIFJvdGFjacOzbiBwb3IgQ2F0ZWdvcsOtYSAtIENvdmFyaWFibGVzIEN1YWxpdGF0aXZhcw0KDQpMYXMgdHJlcyB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzIHByZXNlbnRhbiBkaWZlcmVuY2lhcyBlc3RhZMOtc3RpY2FtZW50ZQ0Kc2lnbmlmaWNhdGl2YXMgZW4gbGEgdGFzYSBkZSByb3RhY2nDs24gZW50cmUgc3VzIGNhdGVnb3LDrWFzIChwIFw8IDAsMDAxDQplbiBsYXMgdHJlcyBwcnVlYmFzIGNoaS1jdWFkcmFkbykuIEVsIGNvbnRyYXN0ZSBtw6FzIHByb251bmNpYWRvDQpjb3JyZXNwb25kZSBhbCB0cmFiYWpvIGVuIGhvcmFzIGV4dHJhLCBkb25kZSByb3RhIGVsIDMwLDUlIGRlIHF1aWVuZXMNCmxhcyByZWFsaXphbiBmcmVudGUgYWwgMTAsNCUgZGUgcXVpZW5lcyBubywgZXMgZGVjaXIsIGNhc2kgZWwgdHJpcGxlLiBFbg0KY3VhbnRvIGFsIGVzdGFkbyBjaXZpbCwgbG9zIHNvbHRlcm9zIHJlZ2lzdHJhbiB1bmEgdGFzYSBkZSByb3RhY2nDs24gZGVsDQoyNSw1JSwgbXV5IHBvciBlbmNpbWEgZGUgbGEgZGUgY2FzYWRvcyAoMTIsNSUpIHkgZGl2b3JjaWFkb3MgKDEwLDElKS4NCkZpbmFsbWVudGUsIGxhIHNhdGlzZmFjY2nDs24gbGFib3JhbCBtdWVzdHJhIGVsIGNvbXBvcnRhbWllbnRvDQpkZWNyZWNpZW50ZSBlc3BlcmFkbywgZXMgZGVjaXIsIGxhIHRhc2EgcGFzYSBkZWwgMjIsOCUgZW4gZWwgbml2ZWwgbXV5DQppbnNhdGlzZmVjaG8gYWwgMTEsMyUgZW4gZWwgbXV5IHNhdGlzZmVjaG8gKFZlciBUYWJsYSAzLjQgeSBGaWd1cmEgMy4zKS4NCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQpyb3RhY2lvbl9tb2QgPC0gcm90YWNpb25fc2VsIHw+DQogIG11dGF0ZSh5ID0gaWZfZWxzZShSb3RhY2nDs24gPT0gIlPDrSIsIDFMLCAwTCksDQogICAgICAgICBTYXRpc2ZhY2Npw7NuX0xhYm9yYWwgPSBmYWN0b3IoU2F0aXNmYWNjacOzbl9MYWJvcmFsLCBvcmRlcmVkID0gRkFMU0UpKQ0KDQpjb3ZhcmlhYmxlcyA8LSBjKCJIb3Jhc19FeHRyYSIsICJFc3RhZG9fQ2l2aWwiLCAiU2F0aXNmYWNjacOzbl9MYWJvcmFsIiwNCiAgICAgICAgICAgICAgICAgIkVkYWQiLCAiSW5ncmVzb19NZW5zdWFsIiwgIkFudGlnw7xlZGFkX0NhcmdvIikNCmBgYA0KDQpgYGB7cn0NCmNhdF9iaXYgPC0gcm90YWNpb25fbW9kIHw+DQogIHNlbGVjdChIb3Jhc19FeHRyYSwgRXN0YWRvX0NpdmlsLCBTYXRpc2ZhY2Npw7NuX0xhYm9yYWwpIHw+DQogIGltYXBfZGZyKH4gdGliYmxlKFZhcmlhYmxlICA9IC55LA0KICAgICAgICAgICAgICAgICAgICBDYXRlZ29yw61hID0gYXMuY2hhcmFjdGVyKC54KSwNCiAgICAgICAgICAgICAgICAgICAgT3JkZW4gICAgID0gYXMuaW50ZWdlcigueCksDQogICAgICAgICAgICAgICAgICAgIHkgICAgICAgICA9IHJvdGFjaW9uX21vZCR5KSkgfD4NCiAgbXV0YXRlKFZhcmlhYmxlID0gZmN0X2lub3JkZXIoVmFyaWFibGUpKQ0KDQp0YWJsYV9jYXRfYml2IDwtIGNhdF9iaXYgfD4NCiAgZ3JvdXBfYnkoVmFyaWFibGUsIENhdGVnb3LDrWEsIE9yZGVuKSB8Pg0KICBzdW1tYXJpc2UoRW1wbGVhZG9zID0gbigpLCBSb3Rhcm9uID0gc3VtKHkpLCAuZ3JvdXBzID0gImRyb3AiKSB8Pg0KICBtdXRhdGUoYFRhc2EgZGUgcm90YWNpw7NuICglKWAgPSByb3VuZCgxMDAgKiBSb3Rhcm9uIC8gRW1wbGVhZG9zLCAxKSkgfD4NCiAgYXJyYW5nZShWYXJpYWJsZSwgT3JkZW4pIHw+DQogIHNlbGVjdCgtT3JkZW4pDQoNCnBydWViYXNfY2F0IDwtIHJvdGFjaW9uX21vZCB8Pg0KICBzZWxlY3QoYWxsX29mKGNvdmFyaWFibGVzWzE6M10pKSB8Pg0KICBpbWFwX2Rmcih+IHsNCiAgICBwcnVlYmEgPC0gY2hpc3EudGVzdCh0YWJsZSgueCwgcm90YWNpb25fbW9kJHkpKQ0KICAgIHRpYmJsZShWYXJpYWJsZSA9IC55LA0KICAgICAgICAgICBgQ2hpIGN1YWRyYWRvYCA9IHJvdW5kKHVubmFtZShwcnVlYmEkc3RhdGlzdGljKSwgMiksDQogICAgICAgICAgIGdsID0gdW5uYW1lKHBydWViYSRwYXJhbWV0ZXIpLA0KICAgICAgICAgICBgVmFsb3IgcGAgPSBzdHJfcmVwbGFjZSgNCiAgICAgICAgICAgICBmb3JtYXQucHZhbChwcnVlYmEkcC52YWx1ZSwgZGlnaXRzID0gMywgZXBzID0gMC4wMDEpLA0KICAgICAgICAgICAgICJcXC4iLCAiLCIpKQ0KICB9KQ0KDQp0YWJsYV9jYXRfYml2IHw+DQogIHRhYmxhX2VzdGlsbyh0aXR1bG8gPSAiIiwNCiAgICAgICAgICAgICAgIGFsaW5lYWNpb24gPSBjKCJsIiwgImwiLCAiYyIsICJjIiwgImMiKSwNCiAgICAgICAgICAgICAgIG5vdGEgPSBwYXN0ZTAoIlRhc2EgZ2xvYmFsIGRlIHJvdGFjacOzbjogMTYsMSAlLiBQcnVlYmFzIGNoaS1jdWFkcmFkbzogIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUocHJ1ZWJhc19jYXQkVmFyaWFibGUsICIgKHAgIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJ1ZWJhc19jYXQkYFZhbG9yIHBgLCAiKSIsIGNvbGxhcHNlID0gIjsgIiksICIuIikpIHw+DQogIGNvbGxhcHNlX3Jvd3MoY29sdW1ucyA9IDEsIHZhbGlnbiA9ICJ0b3AiKQ0KYGBgDQoNCipUYWJsYSAzLjQuIFRhc2EgZGUgcm90YWNpw7NuIHNlZ8O6biBsYXMgY292YXJpYWJsZXMgY3VhbGl0YXRpdmFzKg0KDQpgYGB7cn0NCnRhYmxhX2NhdF9iaXYgfD4NCiAgbXV0YXRlKEV0aXF1ZXRhID0gZmN0X3JldihmY3RfaW5vcmRlcihwYXN0ZShDYXRlZ29yw61hLCBWYXJpYWJsZSwgc2VwID0gIl9fXyIpKSkpIHw+DQogIGdncGxvdChhZXMoeCA9IGBUYXNhIGRlIHJvdGFjacOzbiAoJSlgLCB5ID0gRXRpcXVldGEpKSArDQogIGdlb21fY29sKGZpbGwgPSAiIzIxMzg0YSIsIHdpZHRoID0gMC43KSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDE2LjEsIGNvbG9yID0gIiNiODU0M2YiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBmb3JtYXQoYFRhc2EgZGUgcm90YWNpw7NuICglKWAsIGRlY2ltYWwubWFyayA9ICIsIikpLA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4yLCBzaXplID0gMy4yLCBjb2xvciA9ICIjMjEzODRhIikgKw0KICBmYWNldF93cmFwKH4gVmFyaWFibGUsIHNjYWxlcyA9ICJmcmVlX3kiLCBuY29sID0gMSkgKw0KICBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IH4gc3ViKCJfX18uKiQiLCAiIiwgLngpKSArDQogIHNjYWxlX3hfY29udGludW91cyhleHBhbmQgPSBleHBhbnNpb24obXVsdCA9IGMoMCwgMC4xMikpKSArDQogIGxhYnModGl0bGUgPSAiIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJMYSBsw61uZWEgcHVudGVhZGEgaW5kaWNhIGxhIHRhc2EgZ2xvYmFsIGRlIHJvdGFjacOzbiAoMTYsMSAlKSIsDQogICAgICAgeCA9ICJUYXNhIGRlIHJvdGFjacOzbiAoJSkiLCB5ID0gTlVMTCkgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDExKSArDQogIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDEwKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTQsIGhqdXN0ID0gMC41KSwNCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGhqdXN0ID0gMC41KSkNCmBgYA0KDQoqRmlndXJhIDMuMy4gVGFzYSBkZSByb3RhY2nDs24gcG9yIGNhdGVnb3LDrWEqDQoNCiMjIyBUYXNhcyBkZSBSb3RhY2nDs24gcG9yIENhdGVnb3LDrWEgLSBDb3ZhcmlhYmxlcyBDdWFsaXRhdGl2YXMNCg0KYGBge3J9DQpudW1fYml2IDwtIHJvdGFjaW9uX21vZCB8Pg0KICBzZWxlY3QoYWxsX29mKGNvdmFyaWFibGVzWzQ6Nl0pKSB8Pg0KICBpbWFwX2Rmcih+IHRpYmJsZShWYXJpYWJsZSA9IC55LCB2YWxvciA9IC54LCBSb3RhY2nDs24gPSByb3RhY2lvbl9tb2QkUm90YWNpw7NuKSkgfD4NCiAgbXV0YXRlKFZhcmlhYmxlID0gZmN0X2lub3JkZXIoVmFyaWFibGUpKQ0KDQp0YWJsYV9udW1fYml2IDwtIG51bV9iaXYgfD4NCiAgZ3JvdXBfYnkoVmFyaWFibGUsIFJvdGFjacOzbikgfD4NCiAgc3VtbWFyaXNlKE1lZGlhID0gcm91bmQobWVhbih2YWxvciksIDIpLCBNZWRpYW5hID0gbWVkaWFuKHZhbG9yKSwNCiAgICAgICAgICAgIERFID0gcm91bmQoc2QodmFsb3IpLCAyKSwgLmdyb3VwcyA9ICJkcm9wIikgfD4NCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IFJvdGFjacOzbiwgdmFsdWVzX2Zyb20gPSBjKE1lZGlhLCBNZWRpYW5hLCBERSksDQogICAgICAgICAgICAgIG5hbWVzX3NlcCA9ICIgIikNCg0KcHJ1ZWJhc19udW0gPC0gcm90YWNpb25fbW9kIHw+DQogIHNlbGVjdChhbGxfb2YoY292YXJpYWJsZXNbNDo2XSkpIHw+DQogIGltYXBfZGZyKH4gdGliYmxlKFZhcmlhYmxlID0gLnksDQogICAgICAgICAgICAgICAgICAgIGBWYWxvciBwYCA9IHN0cl9yZXBsYWNlKA0KICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdC5wdmFsKHdpbGNveC50ZXN0KC54IH4gcm90YWNpb25fbW9kJFJvdGFjacOzbikkcC52YWx1ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSAzLCBlcHMgPSAwLjAwMSksDQogICAgICAgICAgICAgICAgICAgICAgIlxcLiIsICIsIikpKQ0KDQoNCm51bV9iaXYgfD4NCiAgZ2dwbG90KGFlcyh4ID0gUm90YWNpw7NuLCB5ID0gdmFsb3IsIGZpbGwgPSBSb3RhY2nDs24pKSArDQogIGdlb21fYm94cGxvdChhbHBoYSA9IDAuODUsIG91dGxpZXIuYWxwaGEgPSAwLjQsIHdpZHRoID0gMC42KSArDQogIGZhY2V0X3dyYXAofiBWYXJpYWJsZSwgc2NhbGVzID0gImZyZWVfeSIsIG5jb2wgPSAzLA0KICAgICAgICAgICAgIGxhYmVsbGVyID0gbGFiZWxfd3JhcF9nZW4oMjApKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIk5vIiA9ICIjMjEzODRhIiwgIlPDrSIgPSAiI2I4NTQzZiIpKSArDQogIGxhYnModGl0bGUgPSAiIiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDEwKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTQsIGhqdXN0ID0gMC41KSkNCmBgYA0KDQoqRmlndXJhIDMuNC4gQ292YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyBzZWfDum4gbGEgcm90YWNpw7NuKg0KDQpMYSBGaWd1cmEgMy40IHkgTGEgVGFibGEgMy41IG11ZXN0cmFuIHF1ZSBsYXMgdHJlcyB2YXJpYWJsZXMNCmN1YW50aWF0aXZhcyBkaWZpZXJlbiBzaWduaWZpY2F0aXZhbWVudGUgZW50cmUgcXVpZW5lcyByb3RhbiB5IHF1aWVuZXMNCnBlcm1hbmVjZW4gKHAgXDwgMCwwMDEgZW4gbGFzIHBydWViYXMgZGUgV2lsY294b24tTWFubi1XaGl0bmV5KSwgeSBlbg0KdG9kb3MgbG9zIGNhc29zIGVsIGdydXBvIHF1ZSByb3RhIHByZXNlbnRhIHZhbG9yZXMgaW5mZXJpb3Jlcy4gTG9zDQplbXBsZWFkb3MgcXVlIHJvdGFyb24gdGllbmVuIHVuYSBlZGFkIG1lZGlhbmEgZGUgMzIgYcOxb3MgZnJlbnRlIGEgMzYNCmVudHJlIHF1aWVuZXMgcGVybWFuZWNpZXJvbi5MYSBkaWZlcmVuY2lhIG3DoXMgbWFyY2FkYSBzZSBvYnNlcnZhIGVuIGVsDQppbmdyZXNvIG1lbnN1YWwsIGRvbmRlIGxhIG1lZGlhbmEgZGUgcXVpZW5lcyByb3RhbiAoMy4yMDIpIGVxdWl2YWxlIGENCnBvY28gbcOhcyBkZWwgNjAlIGRlIGxhIGRlIHF1aWVuZXMgcGVybWFuZWNlbiAoNS4yMDQpLCBtdWVzdHJhIHF1ZSBlbA0KdGVyY2VyIGN1YXJ0aWwgZGVsIGdydXBvIHF1ZSByb3RhIHNlIHNpdMO6YSBwb3IgZGViYWpvIGRlIGxhIG1lZGlhbmEgZGVsDQpncnVwbyBxdWUgcGVybWFuZWNlLiBMYSBhbnRpZ8O8ZWRhZCBlbiBlbCBjYXJnbyBzaWd1ZSBsYSBtaXNtYSBkaXJlY2Npw7NuLA0KY29uIHVuYSBtZWRpYW5hIGRlIDIgYcOxb3MgZW50cmUgcXVpZW5lcyByb3RhbiBmcmVudGUgYSAzIGVudHJlIHF1aWVuZXMNCnBlcm1hbmVjZW4uDQoNCmBgYHtyfQ0KbnVtX2JpdiA8LSByb3RhY2lvbl9tb2QgfD4NCiAgc2VsZWN0KGFsbF9vZihjb3ZhcmlhYmxlc1s0OjZdKSkgfD4NCiAgaW1hcF9kZnIofiB0aWJibGUoVmFyaWFibGUgPSAueSwgdmFsb3IgPSAueCwgUm90YWNpw7NuID0gcm90YWNpb25fbW9kJFJvdGFjacOzbikpIHw+DQogIG11dGF0ZShWYXJpYWJsZSA9IGZjdF9pbm9yZGVyKFZhcmlhYmxlKSkNCg0KdGFibGFfbnVtX2JpdiA8LSBudW1fYml2IHw+DQogIGdyb3VwX2J5KFZhcmlhYmxlLCBSb3RhY2nDs24pIHw+DQogIHN1bW1hcmlzZShNZWRpYSA9IHJvdW5kKG1lYW4odmFsb3IpLCAyKSwgTWVkaWFuYSA9IG1lZGlhbih2YWxvciksDQogICAgICAgICAgICBERSA9IHJvdW5kKHNkKHZhbG9yKSwgMiksIC5ncm91cHMgPSAiZHJvcCIpIHw+DQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBSb3RhY2nDs24sIHZhbHVlc19mcm9tID0gYyhNZWRpYSwgTWVkaWFuYSwgREUpLA0KICAgICAgICAgICAgICBuYW1lc19zZXAgPSAiICIpDQoNCnBydWViYXNfbnVtIDwtIHJvdGFjaW9uX21vZCB8Pg0KICBzZWxlY3QoYWxsX29mKGNvdmFyaWFibGVzWzQ6Nl0pKSB8Pg0KICBpbWFwX2Rmcih+IHRpYmJsZShWYXJpYWJsZSA9IC55LA0KICAgICAgICAgICAgICAgICAgICBgVmFsb3IgcGAgPSBzdHJfcmVwbGFjZSgNCiAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQucHZhbCh3aWxjb3gudGVzdCgueCB+IHJvdGFjaW9uX21vZCRSb3RhY2nDs24pJHAudmFsdWUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlnaXRzID0gMywgZXBzID0gMC4wMDEpLA0KICAgICAgICAgICAgICAgICAgICAgICJcXC4iLCAiLCIpKSkNCg0KdGFibGFfbnVtX2JpdiB8Pg0KICBsZWZ0X2pvaW4ocHJ1ZWJhc19udW0sIGJ5ID0gIlZhcmlhYmxlIikgfD4NCiAgdGFibGFfZXN0aWxvKHRpdHVsbyA9ICIiLA0KICAgICAgICAgICAgICAgbm90YSA9ICJWYWxvciBwIGNvcnJlc3BvbmRpZW50ZSBhIGxhIHBydWViYSBkZSBXaWxjb3hvbi1NYW5uLVdoaXRuZXkuIiwNCiAgICAgICAgICAgICAgIGdydXBvcyA9IGMoIiAiID0gMSwgIk1lZGlhIiA9IDIsICJNZWRpYW5hIiA9IDIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICJEZXN2aWFjacOzbiBlc3TDoW5kYXIiID0gMiwgIiAiID0gMSkpDQpgYGANCg0KKlRhYmxhIDMuNS4gQ29tcGFyYWNpw7NuIGRlIGxhcyBjb3ZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIHNlZ8O6biBsYQ0Kcm90YWNpw7NuKg0KDQojIyMgUmVncmVzaW9uZXMgTG9nw61zdGljYXMgU2ltcGxlcw0KDQpBIHBhcnRpciBkZSBsb3MgcmVzdWx0YWRvcyBkZSBsYSBUYWJsYSAzLjUuMSwgbGFzIHNlaXMgY292YXJpYWJsZXMNCnNlbGVjY2lvbmFkYXMgcmVzdWx0YW4gZGV0ZXJtaW5hbnRlcyBkZSBsYSByb3RhY2nDs24gY3VhbmRvIHNlIGFuYWxpemFuDQpkZSBmb3JtYSBpbmRpdmlkdWFsLiBPcmRlbmFkYXMgcG9yIGxhIG1hZ25pdHVkIGRlIHN1IGVmZWN0bywgZWwgdHJhYmFqbw0KZW4gaG9yYXMgZXh0cmEgZW5jYWJlemEgbGEgbGlzdGEgKE9SID0gMyw3NyksIHNlZ3VpZG8gcG9yIGxhIGNvbmRpY2nDs24NCmRlIHNvbHRlcm8gKE9SID0gMiw0MCkgeSBwb3IgbGEgc2F0aXNmYWNjacOzbiBsYWJvcmFsICJNdXkgc2F0aXNmZWNobyINCmNvbW8gZmFjdG9yIHByb3RlY3RvciAoT1IgPSAwLDQzKS4gRW50cmUgbGFzIGN1YW50aXRhdGl2YXMsIGxhDQphbnRpZ8O8ZWRhZCBlbiBlbCBjYXJnbyBwcmVzZW50YSBlbCBlZmVjdG8gbcOhcyBwcm9udW5jaWFkbyBwb3IgdW5pZGFkIChPUg0KPSAwLDg2NCksIHNlZ3VpZGEgcG9yIGxhIGVkYWQgKE9SID0gMCw5NDkpIHkgZWwgaW5ncmVzbyBtZW5zdWFsLg0KDQpgYGB7cn0NCm1vZGVsb3Nfc2ltcGxlcyA8LSBtYXBfZGZyKGNvdmFyaWFibGVzLCBmdW5jdGlvbih2KSB7DQogIGZvcm11bGFfdiA8LSBhcy5mb3JtdWxhKHBhc3RlMCgieSB+IGAiLCB2LCAiYCIpKQ0KICBtb2RlbG8gPC0gZ2xtKGZvcm11bGFfdiwgZGF0YSA9IHJvdGFjaW9uX21vZCwgZmFtaWx5ID0gYmlub21pYWwpDQogIGJyb29tOjp0aWR5KG1vZGVsbykgfD4NCiAgICBmaWx0ZXIodGVybSAhPSAiKEludGVyY2VwdCkiKSB8Pg0KICAgIG11dGF0ZShlc2NhbGEgPSBpZl9lbHNlKHYgPT0gIkluZ3Jlc29fTWVuc3VhbCIsIDEwMDAsIDEpKSB8Pg0KICAgIHRyYW5zbXV0ZShWYXJpYWJsZSA9IHYsDQogICAgICAgICAgICAgIFTDqXJtaW5vID0gc3RyX3JlbW92ZV9hbGwodGVybSwgcGFzdGUwKCJgfCIsIHYpKSwNCiAgICAgICAgICAgICAgQ29lZmljaWVudGUgPSByb3VuZChlc3RpbWF0ZSAqIGVzY2FsYSwgNCksDQogICAgICAgICAgICAgIGBFcnJvciBlc3TDoW5kYXJgID0gcm91bmQoc3RkLmVycm9yICogZXNjYWxhLCA0KSwNCiAgICAgICAgICAgICAgYFZhbG9yIHpgID0gcm91bmQoc3RhdGlzdGljLCAyKSwNCiAgICAgICAgICAgICAgYFZhbG9yIHBgID0gc3RyX3JlcGxhY2UoZm9ybWF0LnB2YWwocC52YWx1ZSwgZGlnaXRzID0gMywgZXBzID0gMC4wMDEpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXFwuIiwgIiwiKSwNCiAgICAgICAgICAgICAgYE9SYCA9IHJvdW5kKGV4cChlc3RpbWF0ZSAqIGVzY2FsYSksIDMpKQ0KfSkNCg0KbW9kZWxvc19zaW1wbGVzIHw+DQogIHRhYmxhX2VzdGlsbyh0aXR1bG8gPSAiIiwNCiAgICAgICAgICAgICAgIGFsaW5lYWNpb24gPSBjKCJsIiwgImwiLCAiYyIsICJjIiwgImMiLCAiYyIsICJjIiksDQogICAgICAgICAgICAgICBub3RhID0gIk9SOiByYXrDs24gZGUgb3BvcnR1bmlkYWRlcyAob2RkcyByYXRpbykuIEVuIGxhcyB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzLCBjYWRhIHTDqXJtaW5vIHNlIGNvbXBhcmEgY29uIGxhIGNhdGVnb3LDrWEgZGUgcmVmZXJlbmNpYTogTm8gKGhvcmFzIGV4dHJhKSwgQ2FzYWRvIChlc3RhZG8gY2l2aWwpIHkgQmFqYSAoc2F0aXNmYWNjacOzbiBsYWJvcmFsKS4iKSB8Pg0KICBjb2xsYXBzZV9yb3dzKGNvbHVtbnMgPSAxLCB2YWxpZ24gPSAidG9wIikNCmBgYA0KDQoqVGFibGEgMy41LjEgUmVncmVzaW9uZXMgbG9nw61zdGljYXMgc2ltcGxlcyBkZSBjYWRhIGNvdmFyaWFibGUgc29icmUgbGENCnJvdGFjacOzbioNCg0KTG9zIHJlc3VsdGFkb3MgY29uZmlybWFuIGVuIHN1IHRvdGFsaWRhZCBlbCBzZW50aWRvIGVzcGVyYWRvIGRlIGxhcw0KcmVsYWNpb25lcyBmb3JtdWxhZGFzIGFudGVyaW9ybWVudGUuIEVsIHNpZ25vIHBvc2l0aXZvIGRlbCBjb2VmaWNpZW50ZQ0KZGUgaG9yYXMgZXh0cmEgcmVzcGFsZGEgbGEgaGlww7N0ZXNpcyBkZSBxdWUgbGEgc29icmVjYXJnYSBsYWJvcmFsDQppbmNyZW1lbnRhIGxhIHByb3BlbnNpw7NuIGEgbGEgcm90YWNpw7NuLCB5IHN1IG1hZ25pdHVkIHN1cGVyYSBsbw0KYW50aWNpcGFkbywgc2l0dcOhbmRvbG8gY29tbyBlbCBmYWN0b3IgaW5kaXZpZHVhbCBtw6FzIGluZmx1eWVudGUuIExhDQpoaXDDs3Rlc2lzIHNvYnJlIGVsIGVzdGFkbyBjaXZpbCBzZSB2ZXJpZmljYSBwYXJjaWFsbWVudGU6IGxvcyBzb2x0ZXJvcw0KZWZlY3RpdmFtZW50ZSBwcmVzZW50YW4gbWF5b3IgcHJvYmFiaWxpZGFkIGRlIHJvdGFjacOzbiwgZW4gbMOtbmVhIGNvbiBsYQ0KdGVvcsOtYSBkZSBsYXMgYXB1ZXN0YXMgbGF0ZXJhbGVzLCBwZXJvIG5vIHNlIG9ic2VydmEgdW5hIGRpZmVyZW5jaWENCnNpZ25pZmljYXRpdmEgZW50cmUgY2FzYWRvcyB5IGRpdm9yY2lhZG9zLCBsbyBxdWUgbWF0aXphIGVsDQpwbGFudGVhbWllbnRvIGluaWNpYWwgcXVlIGFncnVwYWJhIGEgYW1ib3MgY29tbyBjYXRlZ29yw61hcyBkZSBtZW5vcg0Kcmllc2dvLg0KDQpFbCBzaWdubyBuZWdhdGl2byBkZSBsYSBzYXRpc2ZhY2Npw7NuIGxhYm9yYWwgY29uY3VlcmRhIGNvbiBlbCBtb2RlbG8gZGUNCnbDrW5jdWxvcyBpbnRlcm1lZGlvcywgYXVucXVlIGxhIHJlbGFjacOzbiBubyByZXN1bHRhIGVzdHJpY3RhbWVudGUNCmdyYWR1YWwsIHB1ZXMgbG9zIG5pdmVsZXMgIkluc2F0aXNmZWNobyIgeSAiU2F0aXNmZWNobyIgc2UgY29tcG9ydGFuIGRlDQptYW5lcmEgZXF1aXZhbGVudGUgZW50cmUgc8OtLiBFbiBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMsIGxvcyB0cmVzDQpzaWdub3MgbmVnYXRpdm9zIGNvaW5jaWRlbiBjb24gbG8gcHJldmlzdG8uIFJlc3VsdGEgZGVzdGFjYWJsZSBlbCBjYXNvDQpkZWwgaW5ncmVzbyBtZW5zdWFsOiBzaSBiaWVuIGxhIGxpdGVyYXR1cmEgaGFibGEgc29icmUgbGEgZGViaWxpZGFkIGRlbA0Kc2FsYXJpbyBjb21vIHByZWRpY3RvciwgbG8gcXVlIGxsZXZhYmEgYSBlc3BlcmFyIHVuIGVmZWN0byBtb2Rlc3RvLCBlbA0KYW7DoWxpc2lzIGJpdmFyaWFkbyByZXZlbGEgdW5hIGFzb2NpYWNpw7NuIGNsYXJhIHkgc2lnbmlmaWNhdGl2YS4NCg0KIyMgRXN0aW1hY2nDs24gZGVsIG1vZGVsbyBkZSByZWdyZXNpw7NuIGxvZ8Otc3RpY2EgKHBhcmEgdmFyaWFibGVzIHNlbGVjY2lvbmFkYXMpDQoNClNlIGVzdGltYSB1biBtb2RlbG8gZGUgcmVncmVzacOzbiBsb2fDrXN0aWNhIGJpbmFyaWEgZW4gZWwgcXVlIGxhIHZhcmlhYmxlDQpyZXNwdWVzdGEgY29ycmVzcG9uZGUgYSBsYSByb3RhY2nDs24sICh5PTEgZXMgc2kgcm90YWNpw7NuLCB5PTAgZXMgbm8NCnJvdGFjacOzbiksIHkgbGFzIGNvdmFyaWFibGVzIHNvbiBsYXMgc2VpcyB2YXJpYWJsZXMgc2VsZWNjaW9uYWRhcyBlbiBlbA0KcHVudG8gYW50ZXJpb3IuDQoNCkxhIGVzdGltYWNpw7NuIHNlIHJlYWxpemEgcG9yIGVsIG3DqXRvZG8gZGUgTcOheGltYSBWZXJvc2ltaWxpdHVkIChNVikNCm1lZGlhbnRlIGxhIGZ1bmNpw7NuIGRlIGVubGFjZSBMb2dpdC4gTGFzIHZhcmlhYmxlcyBjdWFsaXRhdGl2YXMgc2UNCmluY29ycG9yYW4gYSB0cmF2w6lzIGRlIHZhcmlhYmxlcyBpbmRpY2Fkb3JhcywgdG9tYW5kbyBjb21vIGNhdGVnb3LDrWFzIGRlDQpyZWZlcmVuY2lhIGxhIGF1c2VuY2lhIGRlIGhvcmFzIGV4dHJhLCBlcyBkZWNpciBxdWUgbGEgdmFyaWFibGUgdG9tYSBlbA0KdmFsb3IgZGUgMT0gU2kgZWwgZW1wbGVhZG8gdHJhYmFqYSBob3JhcyBleHRyYXMgeSAwID0gZW4gb3RybyBjYXNvLg0KDQpDb24gcmVzcGVjdG8gYWwgZXN0YWRvIGNpdmlsLCBsYSByZWZlcmVuY2lhIGVzIGNhc2FkbzsgZW50b25jZXMgbGENCnZhcmlhYmxlIFNvbHRlcm8gZXMgaWd1YWwgYSAxPSBTw607IDA9IE90cm8gQ2FzbyB5LCBwb3Igb3RybyBsYWRvLA0KRGl2b3JjaWFkbyBlcyBpZ3VhbCBhIDEgZW4gYWNhc28gYWZpcm1hdGl2bywgMD0gT3RybyBjYXNvLg0KDQpQYXJhIGVsIG5pdmVsIGRlIHNhdGlzZmFjY2nDs24gbGFib3JhbCBsYSByZWZlcmVuY2lhIGVzIG11eSBpbnNhdGlzZmVjaG8uDQpFbnRvbmNlcywgYXBhcmVjZW4gbGFzIGNhdGVnb3LDrWFzICJJbnNhdGlzZmVjaG8iID0gMTsgMD0gT3RybyBDYXNvLA0KIlNhdGlzZmVjaG8iPSAxLCAwPSBPdHJvIGNhc28geSAiTXV5IFNhdGlzZmVjaG8iPSAxLCAwPSBvdHJvIGNhc28uDQoNClBvciBzdSBwYXJ0ZSwgbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIGNvbW8gZWwgY29lZmljaWVudGUgZGVsDQppbmdyZXNvIG1lbnN1YWwgc2UgZXhwcmVzYSBwb3IgY2FkYSAxLjAwMCB1bmlkYWRlcyBtb25ldGFyaWFzLCBkYWRvIHF1ZQ0KZWwgZWZlY3RvIGFzb2NpYWRvIGEgdW5hIHVuaWRhZCBpbmRpdmlkdWFsIHJlc3VsdGEgaW1wZXJjZXB0aWJsZSBlbiBsYQ0KZXNjYWxhIGRlIGxhIHZhcmlhYmxlLiBBZGVtw6FzIGRlIGxvcyBjb2VmaWNpZW50ZXMgeSBzdSBzaWduaWZpY2FuY2lhLCBzZQ0KY2FsY3VsYW4gbGFzIHJhem9uZXMgZGUgb3BvcnR1bmlkYWRlcyBjb24gc3VzIGludGVydmFsb3MgZGUgY29uZmlhbnphDQpkZWwgOTUlLCBzZSBldmFsdWEgZWwgYWp1c3RlIGdsb2JhbCBtZWRpYW50ZSBsYSBwcnVlYmEgZGUgcmF6w7NuIGRlDQp2ZXJvc2ltaWxpdHVkIGZyZW50ZSBhbCBtb2RlbG8gbnVsbyB5IGVsIHBzZXVkbyBSwrIgZGUgTWNGYWRkZW4sIHkgc2UNCnZlcmlmaWNhIGxhIGF1c2VuY2lhIGRlIG11bHRpY29saW5lYWxpZGFkIGEgdHJhdsOpcyBkZWwgZmFjdG9yIGRlDQppbmZsYWNpw7NuIGRlIGxhIHZhcmlhbnphLiBFbCBtb2RlbG8gYSBlc3RpbWFyIHRpZW5lIGVudG9uY2VzIGxhIGZvcm1hOg0KDQokJA0KXGJlZ2lue2FsaWduZWR9DQpcbG5cbGVmdCgNClxmcmFje1BfaX17MSAtIFBfaX0NClxyaWdodCkNCiY9DQpcbG5cbGVmdChcdGV4dHtPZGRzfV9pXHJpZ2h0KSBcXA0KJj0NClxiZXRhXzANCisgXGJldGFfMSBcLCBcdGV4dHtIb3Jhc0V4dHJhfV9pIFxcDQomXHF1YWQNCisgXGJldGFfMiBcLCBcdGV4dHtTb2x0ZXJvfV9pDQorIFxiZXRhXzMgXCwgXHRleHR7RGl2b3JjaWFkb31faSBcXA0KJlxxdWFkDQorIFxiZXRhXzQgXCwgXHRleHR7SW5zYXRpc2ZlY2hvfV9pDQorIFxiZXRhXzUgXCwgXHRleHR7U2F0aXNmZWNob31faQ0KKyBcYmV0YV82IFwsIFx0ZXh0e011eVNhdGlzZmVjaG99X2kgXFwNCiZccXVhZA0KKyBcYmV0YV83IFwsIFx0ZXh0e0luZ3Jlc29NZW5zdWFsfV9pDQorIFxiZXRhXzggXCwgXHRleHR7RWRhZH1faQ0KKyBcYmV0YV85IFwsIFx0ZXh0e0FudGlndWVkYWRDYXJnb31faS4NCisgXHZhcmVwc2lsb25faSwNClxlbmR7YWxpZ25lZH0NCiQkIERvbmRlOg0KDQokJA0KXHRleHR7b2Rkc31faSA9DQpcZnJhY3tQX2l9ezEgLSBQX2l9DQo9DQpcZnJhY3tQKFlfaSA9IDEgXG1pZCBcbWF0aGJme1h9X2kpfQ0KezEgLSBQKFlfaSA9IDEgXG1pZCBcbWF0aGJme1h9X2kpfSwNCiQkDQoNCmNvcnJlc3BvbmRlIGEgbGEgKipyYXrDs24gZGUgb3BvcnR1bmlkYWRlcyoqICgqb2RkcyopIGRlIHF1ZSBlbCBlbXBsZWFkbw0KJGkkIHByZXNlbnRlIHJvdGFjacOzbiwgZGFkYXMgc3VzIGNhcmFjdGVyw61zdGljYXMgJFxtYXRoYmZ7WH1faSQuDQoNClBvciB0YW50bywgZWwgbG9nYXJpdG1vIGRlIGxhIHJhesOzbiBkZSBvcG9ydHVuaWRhZGVzIHNlIGV4cHJlc2EgY29tbzoNCg0KJCQNClxsbihcdGV4dHtvZGRzfV9pKQ0KPQ0KXGxuXGxlZnQoDQpcZnJhY3tQX2l9ezEgLSBQX2l9DQpccmlnaHQpDQo9DQpcbG5cbGVmdCgNClxmcmFje1AoWV9pID0gMSBcbWlkIFxtYXRoYmZ7WH1faSl9DQp7MSAtIFAoWV9pID0gMSBcbWlkIFxtYXRoYmZ7WH1faSl9DQpccmlnaHQpLg0KJCQNCg0KTGEgdmFyaWFibGUgcmVzcHVlc3RhIHNlIGRlZmluZSBjb21vOg0KDQokJA0KWV9pID0NClxiZWdpbntjYXNlc30NCjEsICYgXHRleHR7c2kgZWwgZW1wbGVhZG8gfSBpIFx0ZXh0eyBwcmVzZW50YSByb3RhY2nDs24gZGVsIGNhcmdvfSwgXFwNCjAsICYgXHRleHR7c2kgZWwgZW1wbGVhZG8gfSBpIFx0ZXh0eyBubyBwcmVzZW50YSByb3RhY2nDs24gZGVsIGNhcmdvfS4NClxlbmR7Y2FzZXN9DQokJA0KDQpFbiBlc3RlIGNhc286DQoNCi0gJFBfaSQ6IHByb2JhYmlsaWRhZCBkZSBxdWUgZWwgZW1wbGVhZG8gJGkkIHByZXNlbnRlIHJvdGFjacOzbiBkZWwNCiAgY2FyZ28uDQoNCi0gJDEgLSBQX2kkOiBwcm9iYWJpbGlkYWQgZGUgcXVlIGVsIGVtcGxlYWRvICRpJCBubyBwcmVzZW50ZSByb3RhY2nDs24NCiAgZGVsIGNhcmdvLg0KDQpMb3MgcmVzdWx0YWRvcyBkZSBsYSBlc3RpbWFjacOzbiBkZWwgbW9kZWxvIHNlIGFwcmVjaWFuIGVuIGVsIEN1YWRybyAzLjENCihzYWxpZGEgb3JpZ2luYWwgZW4gUlN0dWRpbykgeSBkZSBmb3JtYSBtw6FzIG9yZ2FuaXphZGEgZW4gbGEgVGFibGEgMy42DQoNCmBgYHtyfQ0Kcm90YWNpb25fbW9kIDwtIHJvdGFjaW9uX21vZCB8Pg0KICBtdXRhdGUoDQogICAgSW5ncmVzb19NZW5zdWFsX21pbCA9IEluZ3Jlc29fTWVuc3VhbCAvIDEwMDANCiAgKQ0KDQptb2RlbG8gPC0gZ2xtKA0KICB5IH4gSG9yYXNfRXh0cmEgKyBFc3RhZG9fQ2l2aWwgKyBTYXRpc2ZhY2Npw7NuX0xhYm9yYWwgKw0KICAgIEVkYWQgKyBJbmdyZXNvX01lbnN1YWxfbWlsICsgQW50aWfDvGVkYWRfQ2FyZ28sDQogIGRhdGEgPSByb3RhY2lvbl9tb2QsDQogIGZhbWlseSA9IGJpbm9taWFsDQopDQoNCnN1bW1hcnkobW9kZWxvKQ0KYGBgDQoNCipDdWFkcm8gMy4xLiBTYWxpZGEgZGVsIFBhcXVldGUgRXN0YWTDrXN0aWNvIFIgLSBNb2RlbG8gZGUgUmVncmVzacOzbg0KTG9nw61zdGljYSoNCg0KRWwgbW9kZWxvIGVzdGltYWRvIHJlc3VsdGEgc2lnbmlmaWNhdGl2byBlbiBzdSBjb25qdW50by4gbGEgZGVzdmlhY2nDs24NCnNlIHJlZHVjZSBkZSAxLjI5OCw2IGVuIGVsIG1vZGVsbyBudWxvIGEgMS4wNzgsMCBhbCBpbmNvcnBvcmFyIGxhcyBzZWlzDQpjb3ZhcmlhYmxlcywgdW5hIGdhbmFuY2lhIGRlIDIyMCw2IHB1bnRvcyBjb24gOSBncmFkb3MgZGUgbGliZXJ0YWQgcXVlDQpzdXBlcmEgYW1wbGlhbWVudGUgZWwgdmFsb3IgY3LDrXRpY28gZGUgbGEgZGlzdHJpYnVjacOzbiBjaGktY3VhZHJhZG8uDQoNCkVsIG1vZGVsbyBwcmVzZW50w7MgdW4gcHNldWRvLSRSXjIkIGRlIE1jRmFkZGVuIGRlOg0KDQokJA0KUl4yX3tcdGV4dHtNY0ZhZGRlbn19DQo9DQoxIC0NClxmcmFjezEwNzguMH17MTI5OC42fQ0KXGFwcHJveCAwLjE3MC4NCiQkIEluZGljYW5kbyBxdWUgZWwgbW9kZWxvIGV4cGxpY2EgZWwgMTclIGRlIGxhIGRlc3ZpYWNpw7NuIGRlbCBtb2RlbG8NCm51bG8sIHZhbG9yIHF1ZSBzZSBjb25zaWRlcmEgc2F0aXNmYWN0b3JpbyBlbiByZWdyZXNpw7NuIGxvZ8Otc3RpY2EsIGRvbmRlDQplc3RlIGluZGljYWRvciBhbGNhbnphIG1hZ25pdHVkZXMgc2lzdGVtw6F0aWNhbWVudGUgaW5mZXJpb3JlcyBhIGxhcyBkZWwNCmNvZWZpY2llbnRlIGRlIGRldGVybWluYWNpw7NuIGRlIGxhIHJlZ3Jlc2nDs24gbGluZWFsLg0KDQpFbCB0cmFiYWpvIGVuIGhvcmFzIGV4dHJhIGNvbnN0aXR1eWUgZWwgZmFjdG9yIGRlIG1heW9yIHBlc286IHN1DQpjb2VmaWNpZW50ZSBkZSAxLDUxNjAgZXF1aXZhbGUgYSB1bmEgcmF6w7NuIGRlIG9wb3J0dW5pZGFkZXMgZGUgNCw1NQ0KKGVcXjEuMTUxNiksIGRlIG1vZG8gcXVlIGVudHJlIGVtcGxlYWRvcyBlcXVpdmFsZW50ZXMgZW4gbGFzIGRlbcOhcw0KY2FyYWN0ZXLDrXN0aWNhcywgcXVpZW5lcyByZWFsaXphbiBob3JhcyBleHRyYSBwcmVzZW50YW4gb3BvcnR1bmlkYWRlcyBkZQ0Kcm90YWNpw7NuIDQsNTUgdmVjZXMgc3VwZXJpb3Jlcy4NCg0KIyMgSW50ZXJwcmV0YWNpw7NuIGRlIGxvcyBjb2VmaWNpZW50ZXMgZGVsIG1vZGVsbw0KDQpMYSBUYWJsYSAzLjYgcHJlc2VudGEgbG9zIGNvZWZpY2llbnRlcyBlc3RpbWFkb3MganVudG8gY29uIGxhcyByYXpvbmVzDQpkZSBvcG9ydHVuaWRhZGVzIHkgc3VzIGludGVydmFsb3MgZGUgY29uZmlhbnphIGFsIDk1JS4gT2NobyBkZSBsb3MgbnVldmUNCnBhcsOhbWV0cm9zIHJlc3VsdGFuIHNpZ25pZmljYXRpdm9zIGFsIDUlOyBlbCDDum5pY28gcXVlIG5vIGFsY2FuemENCnNpZ25pZmljYW5jaWEgZXMgZWwgY29ycmVzcG9uZGllbnRlIGFsIGVzdGFkbyBjaXZpbCBkaXZvcmNpYWRvLCBjdXlvDQppbnRlcnZhbG8gKDAsNDQ1IGEgMSwxMDEpIGluY2x1eWUgZWwgdmFsb3IgdW5vIHksIHBvciB0YW50bywgbm8gcGVybWl0ZQ0KZGVzY2FydGFyIGxhIGF1c2VuY2lhIGRlIGVmZWN0byBmcmVudGUgYSBsb3MgZW1wbGVhZG9zIGNhc2Fkb3MuDQoNCkVsIHRyYWJham8gZW4gaG9yYXMgZXh0cmEgY29uc3RpdHV5ZSBlbCBmYWN0b3IgZGUgbWF5b3IgcGVzbyBkZWwgbW9kZWxvOg0Kc3UgY29lZmljaWVudGUgZGUgMSw1MTYwIGVxdWl2YWxlIGEgdW5hIHJhesOzbiBkZSBvcG9ydHVuaWRhZGVzIGRlIDQsNTUsDQpkZSBtb2RvIHF1ZSwgZW50cmUgZW1wbGVhZG9zIGVxdWl2YWxlbnRlcyBlbiBsYXMgZGVtw6FzIGNhcmFjdGVyw61zdGljYXMsDQpxdWllbmVzIHJlYWxpemFuIGhvcmFzIGV4dHJhIHByZXNlbnRhbiBvcG9ydHVuaWRhZGVzIGRlIHJvdGFjacOzbiA0LDU1DQp2ZWNlcyBzdXBlcmlvcmVzLCBjb24gdW4gaW50ZXJ2YWxvIGNvbXByZW5kaWRvIGVudHJlIDMsMzQgeSA2LDI0IHF1ZQ0KY29uZmlybWEgbGEgcm9idXN0ZXogZGVsIGVmZWN0by4gTGEgY29uZGljacOzbiBkZSBzb2x0ZXJvIG11bHRpcGxpY2ENCmRpY2hhcyBvcG9ydHVuaWRhZGVzIHBvciAyLDI5IHJlc3BlY3RvIGEgbG9zIGNhc2Fkb3MgKDEsNjQgYSAzLDIxKSwNCm1pZW50cmFzIHF1ZSBlbCBuaXZlbCBkZSBzYXRpc2ZhY2Npw7NuIG11eSBhbHRvIGxhcyByZWR1Y2UgYWwgMzQlDQooZXhwKC0xLjA3ODgpKSBkZSBsYXMgb2JzZXJ2YWRhcyBlbnRyZSBsb3MgZW1wbGVhZG9zIG11eSBpbnNhdGlzZmVjaG9zDQooMCwyMiBhIDAsNTMpLg0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCnRhYmxhX21vZGVsbyA8LSBicm9vbTo6dGlkeSgNCiAgbW9kZWxvLA0KICBjb25mLmludCA9IFRSVUUsDQogIGNvbmYubGV2ZWwgPSAwLjk1DQopIHw+DQogIGZpbHRlcih0ZXJtICE9ICIoSW50ZXJjZXB0KSIpIHw+DQogIG11dGF0ZSgNCiAgICBWYXJpYWJsZSA9IGNhc2Vfd2hlbigNCiAgICAgIHN0cl9kZXRlY3QodGVybSwgIl5Ib3Jhc19FeHRyYSIpIH4gIkhvcmFzIGV4dHJhIiwNCiAgICAgIHN0cl9kZXRlY3QodGVybSwgIl5Fc3RhZG9fQ2l2aWwiKSB+ICJFc3RhZG8gY2l2aWwiLA0KICAgICAgc3RyX2RldGVjdCh0ZXJtLCAiXlNhdGlzZmFjY2nDs25fTGFib3JhbCIpIH4gIlNhdGlzZmFjY2nDs24gbGFib3JhbCIsDQogICAgICB0ZXJtID09ICJFZGFkIiB+ICJFZGFkIiwNCiAgICAgIHRlcm0gPT0gIkluZ3Jlc29fTWVuc3VhbF9taWwiIH4gIkluZ3Jlc28gbWVuc3VhbCIsDQogICAgICB0ZXJtID09ICJBbnRpZ8O8ZWRhZF9DYXJnbyIgfiAiQW50aWfDvGVkYWQgZW4gZWwgY2FyZ28iDQogICAgKSwNCiAgICANCiAgICBDYXRlZ29yw61hID0gY2FzZV93aGVuKA0KICAgICAgdGVybSA9PSAiSG9yYXNfRXh0cmFTw60iIH4gIlPDrSIsDQogICAgICB0ZXJtID09ICJFc3RhZG9fQ2l2aWxEaXZvcmNpYWRvIiB+ICJEaXZvcmNpYWRvIiwNCiAgICAgIHRlcm0gPT0gIkVzdGFkb19DaXZpbFNvbHRlcm8iIH4gIlNvbHRlcm8iLA0KICAgICAgdGVybSA9PSAiU2F0aXNmYWNjacOzbl9MYWJvcmFsSW5zYXRpc2ZlY2hvIiB+ICJJbnNhdGlzZmVjaG8iLA0KICAgICAgdGVybSA9PSAiU2F0aXNmYWNjacOzbl9MYWJvcmFsU2F0aXNmZWNobyIgfiAiU2F0aXNmZWNobyIsDQogICAgICB0ZXJtID09ICJTYXRpc2ZhY2Npw7NuX0xhYm9yYWxNdXkgc2F0aXNmZWNobyIgfiAiTXV5IHNhdGlzZmVjaG8iLA0KICAgICAgdGVybSA9PSAiRWRhZCIgfiAiUG9yIGNhZGEgYcOxbyBhZGljaW9uYWwiLA0KICAgICAgdGVybSA9PSAiSW5ncmVzb19NZW5zdWFsX21pbCIgfiAiUG9yIGNhZGEgMS4wMDAgdW5pZGFkZXMgbW9uZXRhcmlhcyIsDQogICAgICB0ZXJtID09ICJBbnRpZ8O8ZWRhZF9DYXJnbyIgfiAiUG9yIGNhZGEgYcOxbyBhZGljaW9uYWwiDQogICAgKSwNCiAgICANCiAgICBgQ29lZmljaWVudGUgKM6yKWAgPSByb3VuZChlc3RpbWF0ZSwgNCksDQogICAgYEVycm9yIGVzdMOhbmRhcmAgPSByb3VuZChzdGQuZXJyb3IsIDQpLA0KICAgIGBWYWxvciB6YCA9IHJvdW5kKHN0YXRpc3RpYywgMiksDQogICAgDQogICAgYFZhbG9yIHBgID0gc3RyX3JlcGxhY2UoDQogICAgICBmb3JtYXQucHZhbChwLnZhbHVlLCBkaWdpdHMgPSAzLCBlcHMgPSAwLjAwMSksDQogICAgICAiXFwuIiwNCiAgICAgICIsIg0KICAgICksDQogICAgDQogICAgT1IgPSByb3VuZChleHAoZXN0aW1hdGUpLCAzKSwNCiAgICANCiAgICBgSUMgOTUlIE9SYCA9IHBhc3RlMCgNCiAgICAgICJbIiwNCiAgICAgIGZvcm1hdCgNCiAgICAgICAgcm91bmQoZXhwKGNvbmYubG93KSwgMyksDQogICAgICAgIG5zbWFsbCA9IDMsDQogICAgICAgIGRlY2ltYWwubWFyayA9ICIsIg0KICAgICAgKSwNCiAgICAgICI7ICIsDQogICAgICBmb3JtYXQoDQogICAgICAgIHJvdW5kKGV4cChjb25mLmhpZ2gpLCAzKSwNCiAgICAgICAgbnNtYWxsID0gMywNCiAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiDQogICAgICApLA0KICAgICAgIl0iDQogICAgKQ0KICApIHw+DQogIHNlbGVjdCgNCiAgICBWYXJpYWJsZSwNCiAgICBDYXRlZ29yw61hLA0KICAgIGBDb2VmaWNpZW50ZSAozrIpYCwNCiAgICBgRXJyb3IgZXN0w6FuZGFyYCwNCiAgICBgVmFsb3IgemAsDQogICAgYFZhbG9yIHBgLA0KICAgIE9SLA0KICAgIGBJQyA5NSUgT1JgDQogICkNCmBgYA0KDQpgYGB7cn0NCnRhYmxhX21vZGVsbyB8Pg0KICB0YWJsYV9lc3RpbG8oDQogICAgdGl0dWxvID0gcGFzdGUoDQogICAgICAiIg0KICAgICANCiAgICApLA0KICAgIGFsaW5lYWNpb24gPSBjKCJsIiwgImwiLCAiYyIsICJjIiwgImMiLCAiYyIsICJjIiwgImMiKSwNCiAgICBub3RhID0gcGFzdGUoDQogICAgICAiVmFyaWFibGUgcmVzcHVlc3RhOiByb3RhY2nDs24gZGVsIGNhcmdvICgxID0gcHJlc2VudGEgcm90YWNpw7NuOyAwID0gbm8gcHJlc2VudGEgcm90YWNpw7NuKS4iLA0KICAgICAgIk9SOiByYXrDs24gZGUgb3BvcnR1bmlkYWRlczsgSUMgOTUlOiBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGFsIDk1JS4iLA0KICAgICAgIkNhdGVnb3LDrWFzIGRlIHJlZmVyZW5jaWE6IE5vIChob3JhcyBleHRyYSksIENhc2FkbyAoZXN0YWRvIGNpdmlsKSB5IE11eSBJbnNhdGlzZmVjaG8gKHNhdGlzZmFjY2nDs24gbGFib3JhbCkuIiwNCiAgICAgICJFbCBlZmVjdG8gZGVsIGluZ3Jlc28gbWVuc3VhbCBzZSBleHByZXNhIHBvciBjYWRhIDEuMDAwIHVuaWRhZGVzIG1vbmV0YXJpYXMuIg0KICAgICkNCiAgKSB8Pg0KICBjb2xsYXBzZV9yb3dzKA0KICAgIGNvbHVtbnMgPSAxLA0KICAgIHZhbGlnbiA9ICJ0b3AiDQogICkNCmBgYA0KDQoqVGFibGEgMy42LiBSZXN1bHRhZG9zIGRlbCBtb2RlbG8gZGUgcmVncmVzacOzbiBsb2fDrXN0aWNhIG3Dumx0aXBsZSBwYXJhDQpsYSByb3RhY2nDs24gZGVsIGNhcmdvKg0KDQpFbiBjdWFudG8gYSBsYSBzYXRpc2ZhY2Npw7NuIGxhYm9yYWwsIGxvcyBuaXZlbGVzIGludGVybWVkaW9zIHByZXNlbnRhbg0KcmF6b25lcyBkZSBvcG9ydHVuaWRhZGVzIHByw6FjdGljYW1lbnRlIGlkw6ludGljYXMsIGRlIDAsNjI4IHBhcmEgbG9zDQplbXBsZWFkb3MgaW5zYXRpc2ZlY2hvcyB5IDAsNjE5IHBhcmEgbG9zIHNhdGlzZmVjaG9zLCBjb24gaW50ZXJ2YWxvcyBxdWUNCnNlIHNvbGFwYW4gY2FzaSBwb3IgY29tcGxldG8sIGxvIHF1ZSBpbmRpY2EgcXVlIGFtYm9zIG5pdmVsZXMgcmVzdWx0YW4NCmVzdGFkw61zdGljYW1lbnRlIGluZGlzdGluZ3VpYmxlcyBlbnRyZSBzw60uIFNvbG8gZWwgbml2ZWwgbcOheGltbyBkZSBsYQ0KZXNjYWxhIHNlIGRpZmVyZW5jaWEgY29uIGNsYXJpZGFkLCBwdWVzIHN1IGludGVydmFsbyBzZSBzaXTDumEgcG9yIGRlYmFqbw0KZGVsIGRlIGxvcyBkZW3DoXMgbml2ZWxlcy4gRXN0ZSBwYXRyw7NuIHN1Z2llcmUgcXVlIGxhIHJlZHVjY2nDs24gZGVsDQpyaWVzZ28gZGUgcm90YWNpw7NuIG5vIG9wZXJhIGRlIGZvcm1hIGdyYWR1YWwgYSBsbyBsYXJnbyBkZSBsYSBlc2NhbGEsDQpzaW5vIHF1ZSByZXF1aWVyZSBhbGNhbnphciBsYSBzYXRpc2ZhY2Npw7NuIHBsZW5hLg0KDQpSZXNwZWN0byBhIGxhcyBjb3ZhcmlhYmxlcyBjdWFudGl0YXRpdmFzLCBzZSBldmlkZW5jaWFuIGFzb2NpYWNpb25lcw0KaW52ZXJzYXMgeSBlc3RhZMOtc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZhcyBjb24gbGEgcm90YWNpw7NuIGRlbCBjYXJnby4NCk1hbnRlbmllbmRvIGNvbnN0YW50ZXMgbGFzIGRlbcOhcyB2YXJpYWJsZXMgZGVsIG1vZGVsbywgcG9yIGNhZGEgYcOxbw0KYWRpY2lvbmFsIGRlIGVkYWQsIGxhcyByYXpvbmVzIGRlIG9wb3J0dW5pZGFkZXMgZGUgcm90YWNpw7NuIHNlDQptdWx0aXBsaWNhbiBwb3IgJDAsOTcyJCAoJFxiZXRhID0gLTAsMDI4NSQ7ICRwID0gMCwwMDQ2JCksIGxvIHF1ZQ0KZXF1aXZhbGUgYSB1bmEgZGlzbWludWNpw7NuIGFwcm94aW1hZGEgZGVsIDIsOCUgZW4gbGFzICpvZGRzKiBkZQ0Kcm90YWNpw7NuLg0KDQpBc2ltaXNtbywgcG9yIGNhZGEgaW5jcmVtZW50byBkZSAxLjAwMCB1bmlkYWRlcyBtb25ldGFyaWFzIGVuIGVsIGluZ3Jlc28NCm1lbnN1YWwsIGxhcyByYXpvbmVzIGRlIG9wb3J0dW5pZGFkZXMgZGUgcm90YWNpw7NuIHNlIG11bHRpcGxpY2FuIHBvcg0KJDAsOTMwJCAoJFxiZXRhID0gLTAsMDcyMiQ7ICRwID0gMCwwMDQyJCkuIEVuIG90cmFzIHBhbGFicmFzLCBzZSBhc29jaWFuDQpjb24gdW5hIHJlZHVjY2nDs24gYXByb3hpbWFkYSBkZWwgNywwJSBlbiBsYXMgKm9kZHMqIGRlIHJvdGFjacOzbi4NCg0KRmluYWxtZW50ZSwgcG9yIGNhZGEgYcOxbyBhZGljaW9uYWwgZGUgYW50aWfDvGVkYWQgZW4gZWwgY2FyZ28sIGxhcw0KcmF6b25lcyBkZSBvcG9ydHVuaWRhZGVzIGRlIHJvdGFjacOzbiBzZSBtdWx0aXBsaWNhbiBwb3IgJDAsOTA1JA0KKCRcYmV0YSA9IC0wLDA5OTMkOyAkcCA8IDAsMDAxJCksIGxvIHF1ZSBjb3JyZXNwb25kZSBhIHVuYSBkaXNtaW51Y2nDs24NCmFwcm94aW1hZGEgZGVsIDksNSUgZW4gbGFzICpvZGRzKiBkZSByb3RhY2nDs24uDQoNCiMjIEFqdXN0ZSBkZWwgbW9kZWxvDQoNClBhcmEgZXZhbHVhciBlbCBhanVzdGUgZ2xvYmFsIGRlbCBtb2RlbG8gc2UgY29udHJhc3RhIGVsIG1vZGVsbyBlc3RpbWFkbw0KZnJlbnRlIGEgdW4gbW9kZWxvIG51bG8gcXVlIGluY2x1eWUgw7puaWNhbWVudGUgZWwgaW50ZXJjZXB0byB5IHF1ZSwgcG9yDQp0YW50bywgYXNpZ25hIGEgdG9kb3MgbG9zIGVtcGxlYWRvcyBsYSBtaXNtYSBwcm9iYWJpbGlkYWQgZGUgcm90YWNpw7NuLA0KZXF1aXZhbGVudGUgYSBsYSB0YXNhIG9ic2VydmFkYSBlbiBsYSBiYXNlLiBMYSBjb21wYXJhY2nDs24gc2UgcmVhbGl6YQ0KbWVkaWFudGUgbGEgcHJ1ZWJhIGRlIHJhesOzbiBkZSB2ZXJvc2ltaWxpdHVkLCBxdWUgZXZhbMO6YSBzaSBsYSByZWR1Y2Npw7NuDQplbiBsYSBkZXN2aWFjacOzbiBvYnRlbmlkYSBhbCBpbmNvcnBvcmFyIGxhcyBjb3ZhcmlhYmxlcyByZXN1bHRhDQplc3RhZMOtc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZhLCBiYWpvIGxhIGhpcMOzdGVzaXMgbnVsYSBkZSBxdWUgdG9kb3MgbG9zDQpjb2VmaWNpZW50ZXMgZGVsIG1vZGVsbyBzb24gaWd1YWxlcyBhIGNlcm8uIEEgcGFydGlyIGRlIGxhcyBkZXN2aWFjaW9uZXMNCmRlIGFtYm9zIG1vZGVsb3Mgc2UgY2FsY3VsYSBlbCBwc2V1ZG8gUsKyIGRlIE1jRmFkZGVuLCBkZWZpbmlkbyBjb21vIGxhDQpwcm9wb3JjacOzbiBkZSBsYSBkZXN2aWFjacOzbiBkZWwgbW9kZWxvIG51bG8gcXVlIGVsIG1vZGVsbyBlc3RpbWFkbyBsb2dyYQ0KZWxpbWluYXIsIHkgc2UgcmVwb3J0YSBhZGljaW9uYWxtZW50ZSBlbCBjcml0ZXJpbyBkZSBpbmZvcm1hY2nDs24gZGUNCkFrYWlrZSBjb21vIHJlZmVyZW5jaWEgcGFyYSBldmVudHVhbGVzIGNvbXBhcmFjaW9uZXMgY29uDQplc3BlY2lmaWNhY2lvbmVzIGFsdGVybmF0aXZhcy4NCg0KYGBge3J9DQptb2RlbG9fbnVsbyA8LSBnbG0oeSB+IDEsIGRhdGEgPSByb3RhY2lvbl9tb2QsIGZhbWlseSA9IGJpbm9taWFsKQ0KDQpwcnVlYmFfZ2xvYmFsIDwtIGFub3ZhKG1vZGVsb19udWxvLCBtb2RlbG8sIHRlc3QgPSAiQ2hpc3EiKQ0KDQpyMl9tY2ZhZGRlbiA8LSAxIC0gKG1vZGVsbyRkZXZpYW5jZSAvIG1vZGVsb19udWxvJGRldmlhbmNlKQ0KDQphanVzdGUgPC0gdGliYmxlKA0KICBJbmRpY2Fkb3IgPSBjKCJEZXN2aWFjacOzbiBkZWwgbW9kZWxvIG51bG8iLCAiRGVzdmlhY2nDs24gZGVsIG1vZGVsbyBlc3RpbWFkbyIsDQogICAgICAgICAgICAgICAgIkNoaS1jdWFkcmFkbyBkZSBsYSBwcnVlYmEgZGUgcmF6w7NuIGRlIHZlcm9zaW1pbGl0dWQiLA0KICAgICAgICAgICAgICAgICJHcmFkb3MgZGUgbGliZXJ0YWQiLCAiVmFsb3IgcCIsICJQc2V1ZG8gUsKyIGRlIE1jRmFkZGVuIiwgIkFJQyIpLA0KICBWYWxvciA9IGMoZm9ybWF0KHJvdW5kKG1vZGVsb19udWxvJGRldmlhbmNlLCAyKSwgZGVjaW1hbC5tYXJrID0gIiwiLCBiaWcubWFyayA9ICIuIiksDQogICAgICAgICAgICBmb3JtYXQocm91bmQobW9kZWxvJGRldmlhbmNlLCAyKSwgZGVjaW1hbC5tYXJrID0gIiwiLCBiaWcubWFyayA9ICIuIiksDQogICAgICAgICAgICBmb3JtYXQocm91bmQocHJ1ZWJhX2dsb2JhbCREZXZpYW5jZVsyXSwgMiksIGRlY2ltYWwubWFyayA9ICIsIiwgYmlnLm1hcmsgPSAiLiIpLA0KICAgICAgICAgICAgYXMuY2hhcmFjdGVyKHBydWViYV9nbG9iYWwkRGZbMl0pLA0KICAgICAgICAgICAgc3RyX3JlcGxhY2UoZm9ybWF0LnB2YWwocHJ1ZWJhX2dsb2JhbCRgUHIoPkNoaSlgWzJdLCBlcHMgPSAwLjAwMSksICJcXC4iLCAiLCIpLA0KICAgICAgICAgICAgZm9ybWF0KHJvdW5kKHIyX21jZmFkZGVuLCA0KSwgZGVjaW1hbC5tYXJrID0gIiwiKSwNCiAgICAgICAgICAgIGZvcm1hdChyb3VuZChBSUMobW9kZWxvKSwgMiksIGRlY2ltYWwubWFyayA9ICIsIiwgYmlnLm1hcmsgPSAiLiIpKQ0KKQ0KDQphanVzdGUgfD4NCiAgdGFibGFfZXN0aWxvKHRpdHVsbyA9ICIiLA0KICAgICAgICAgICAgICAgYWxpbmVhY2lvbiA9IGMoImwiLCAiYyIpKQ0KDQpgYGANCg0KKlRhYmxhIDMuNy4gSW5kaWNhZG9yZXMgZGUgYWp1c3RlIGdsb2JhbCBkZWwgbW9kZWxvKg0KDQpMYSBpbmNvcnBvcmFjacOzbiBkZSBsYXMgc2VpcyBjb3ZhcmlhYmxlcyByZWR1Y2UgbGEgZGVzdmlhY2nDs24gZGUNCjEuMjk4LDU4IGVuIGVsIG1vZGVsbyBudWxvIGEgMS4wNzgsMDMgZW4gZWwgbW9kZWxvIGVzdGltYWRvLCBsbyBxdWUNCnJlcHJlc2VudGEgdW5hIGdhbmFuY2lhIGRlIDIyMCw1NSBwdW50b3MgY29uIDkgZ3JhZG9zIGRlIGxpYmVydGFkLiBFc3RlDQp2YWxvciBzdXBlcmEgZWwgcHVudG8gY3LDrXRpY28gZGUgbGEgZGlzdHJpYnVjacOzbiBjaGktY3VhZHJhZG8NCmNvcnJlc3BvbmRpZW50ZSwgZGUgMTYsOTIgYWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBkZWwgNSUsIHBvciBsbyBxdWUNCnNlIHJlY2hhemEgbGEgaGlww7N0ZXNpcyBudWxhIGRlIHF1ZSB0b2RvcyBsb3MgY29lZmljaWVudGVzIHNlYW4gaWd1YWxlcw0KYSBjZXJvIHkgc2UgY29uY2x1eWUgcXVlIGVsIG1vZGVsbyByZXN1bHRhIGdsb2JhbG1lbnRlIHNpZ25pZmljYXRpdm8gKHANClw8IDAsMDAxKS4NCg0KRWwgcHNldWRvIFLCsiBkZSBNY0ZhZGRlbiBhc2NpZW5kZSBhIDAsMTY5OCwgaW5kaWNhIHF1ZSBlbCBtb2RlbG8gZXhwbGljYQ0KYXByb3hpbWFkYW1lbnRlIGVsIDE3JSBkZSBsYSBkZXN2aWFjacOzbiBpbmljaWFsLiBDb25zaWRlcmFuZG8gYWRlbcOhcyBxdWUNCmxhIHJvdGFjacOzbiBsYWJvcmFsIGNvbnN0aXR1eWUgdW4gZmVuw7NtZW5vIG11bHRpY2F1c2FsLCBlbiBlbCBxdWUNCmludGVydmllbmVuIGZhY3RvcmVzIG5vIHJlZ2lzdHJhZG9zIGVuIGxhIGJhc2UgY29tbyBsYSBleGlzdGVuY2lhIGRlDQpvZmVydGFzIGV4dGVybmFzIG8gbGEgY2FsaWRhZCBkZSBsYSByZWxhY2nDs24gY29uIGxhIGplZmF0dXJhIGlubWVkaWF0YSwNCmVsIG5pdmVsIGRlIGFqdXN0ZSBhbGNhbnphZG8gY29uIHNlaXMgY292YXJpYWJsZXMgcmVzdWx0YSBzYXRpc2ZhY3RvcmlvLg0KRWwgY3JpdGVyaW8gZGUgaW5mb3JtYWNpw7NuIGRlIEFrYWlrZSwgZGUgMS4wOTgsMDMsIHNlIHJlcG9ydGEgY29tbyB2YWxvcg0KZGUgcmVmZXJlbmNpYSBwYXJhIGxhIGNvbXBhcmFjacOzbiBjb24gbW9kZWxvcyBhbHRlcm5hdGl2b3MsIGNhcmVjaWVuZG8NCmRlIGludGVycHJldGFjacOzbiBzdXN0YW50aXZhIGRlIG1hbmVyYSBhaXNsYWRhLg0KDQojIyBWZXJpZmljYWNpw7NuIGRlIG11bHRpY29saW5lYWxpZGFkDQoNClNlIHZlcmlmaWNhIGxhIGF1c2VuY2lhIGRlIG11bHRpY29saW5lYWxpZGFkIGVudHJlIGxhcyBjb3ZhcmlhYmxlcw0KbWVkaWFudGUgZWwgZmFjdG9yIGRlIGluZmxhY2nDs24gZGUgbGEgdmFyaWFuemEsIGluZGljYWRvciBxdWUgY3VhbnRpZmljYQ0KZW4gcXXDqSBtZWRpZGEgbGEgY29ycmVsYWNpw7NuIGVudHJlIHByZWRpY3RvcmFzIGluY3JlbWVudGEgZWwgZXJyb3INCmVzdMOhbmRhciBkZSBsb3MgY29lZmljaWVudGVzIGVzdGltYWRvcy4gRGFkbyBxdWUgZWwgbW9kZWxvIGluY2x1eWUNCnZhcmlhYmxlcyBjYXRlZ8OzcmljYXMgY29uIG3DoXMgZGUgZG9zIG5pdmVsZXMsIHNlIHJlcG9ydGEgZWwgZmFjdG9yDQphanVzdGFkbyBwb3IgZ3JhZG9zIGRlIGxpYmVydGFkLCBxdWUgcmVzdWx0YSBjb21wYXJhYmxlIGVudHJlIHZhcmlhYmxlcw0KY29uIGRpc3RpbnRvIG7Dum1lcm8gZGUgY2F0ZWdvcsOtYXMuDQoNCmBgYHtyfQ0KbGlicmFyeShjYXIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh0aWJibGUpDQpsaWJyYXJ5KHN0cmluZ3IpDQoNCiMgMS4gQ2FsY3VsYXIgVklGL0dWSUYNCnZpZl9tb2RlbG8gPC0gY2FyOjp2aWYobW9kZWxvKQ0KDQojIDIuIENvbnZlcnRpciBlbCByZXN1bHRhZG8gYSB0YWJsYQ0KdGFibGFfdmlmIDwtIGFzLmRhdGEuZnJhbWUodmlmX21vZGVsbykgfD4NCiAgcm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICJWYXJpYWJsZSIpDQoNCiMgMy4gRWxlZ2lyIGF1dG9tw6F0aWNhbWVudGUgVklGIG8gR1ZJRiBhanVzdGFkbw0KaWYgKGFsbChjKCJEZiIsICJHVklGXigxLygyKkRmKSkiKSAlaW4lIG5hbWVzKHRhYmxhX3ZpZikpKSB7DQoNCiAgdGFibGFfdmlmIDwtIHRhYmxhX3ZpZiB8Pg0KICAgIHRyYW5zbXV0ZSgNCiAgICAgIFZhcmlhYmxlID0gc3RyX3JlcGxhY2VfYWxsKFZhcmlhYmxlLCAiXyIsICIgIiksDQogICAgICBgR3JhZG9zIGRlIGxpYmVydGFkYCA9IERmLA0KICAgICAgYFZJRiBhanVzdGFkb2AgPSByb3VuZChgR1ZJRl4oMS8oMipEZikpYCwgMykNCiAgICApDQoNCn0gZWxzZSB7DQoNCiAgbmFtZXModGFibGFfdmlmKVsyXSA8LSAiVklGIg0KDQogIHRhYmxhX3ZpZiA8LSB0YWJsYV92aWYgfD4NCiAgICB0cmFuc211dGUoDQogICAgICBWYXJpYWJsZSA9IHN0cl9yZXBsYWNlX2FsbChWYXJpYWJsZSwgIl8iLCAiICIpLA0KICAgICAgVklGID0gcm91bmQoVklGLCAzKQ0KICAgICkNCn0NCg0KIyA0LiBNb3N0cmFyIGxhIHRhYmxhIGNvbiBsYSBmdW5jacOzbiBwZXJzb25hbGl6YWRhDQp0YWJsYV92aWYgfD4NCiAgdGFibGFfZXN0aWxvKA0KICAgIHRpdHVsbyA9ICIiLA0KICAgIG5vdGEgPSAiU2UgcmVwb3J0YSBlbCBWSUYgbyBWSUYgYWp1c3RhZG8gcG9yIGdyYWRvcyBkZSBsaWJlcnRhZCwgc2Vnw7puIGxhIGVzdHJ1Y3R1cmEgZGUgbGFzIGNvdmFyaWFibGVzLiINCiAgKQ0KYGBgDQoNCipUYWJsYSAzLjguIEZhY3RvciBkZSBJbmZsYWNpw7NuIGRlIGxhIFZhcmlhbnphIGRlIGxhcyBjb3ZhcmlhYmxlcyoNCg0KTG9zIGZhY3RvcmVzIGRlIGluZmxhY2nDs24gZGUgbGEgdmFyaWFuemEgc2Ugc2l0w7phbiBlbnRyZSAxLDAwNSB5IDEsMTU0LA0KbXV5IHBvciBkZWJham8gZGVsIHVtYnJhbCBkZSByZWZlcmVuY2lhLCBsbyBxdWUgZGVzY2FydGEgbGEgcHJlc2VuY2lhIGRlDQptdWx0aWNvbGluZWFsaWRhZCByZWxldmFudGUuIExvcyB2YWxvcmVzIG3DoXMgYWx0b3MgY29ycmVzcG9uZGVuIGFsDQppbmdyZXNvIG1lbnN1YWwgKDEsMTU0KSB5IGEgbGEgZWRhZCAoMSwxMjgpLCBjb2hlcmVudGUgY29uIGxhDQpjb3JyZWxhY2nDs24gZGUgU3BlYXJtYW4gZGUgMCw0NyBpZGVudGlmaWNhZGEgZW50cmUgYW1iYXMgZW4gZWwgYW7DoWxpc2lzDQpleHBsb3JhdG9yaW8sIGF1bnF1ZSBzdSBtYWduaXR1ZCByZXN1bHRhIGluc3VmaWNpZW50ZSBwYXJhIGNvbXByb21ldGVyDQpsYSBlc3RpbWFjacOzbi4NCg0KTGEgcHJveGltaWRhZCBnZW5lcmFsIGRlIGxvcyBpbmRpY2Fkb3JlcyBhIGxhIHVuaWRhZCBjb25maXJtYSBxdWUgbGFzDQpzZWlzIGNvdmFyaWFibGVzIGFwb3J0YW4gaW5mb3JtYWNpw7NuIHN1c3RhbmNpYWxtZW50ZSBpbmRlcGVuZGllbnRlIHkNCnZhbGlkYSBsYSBkZWNpc2nDs24gYWRvcHRhZGEgZW4gbGEgc2VsZWNjacOzbiBkZSB2YXJpYWJsZXMgZGUgaW5jb3Jwb3Jhcg0KdW5hIMO6bmljYSByZXByZXNlbnRhbnRlIGRlbCBibG9xdWUgZGUgdHJheWVjdG9yaWEgbGFib3JhbCwgZGVzY2FydGFuZG8NCmxhIGFudGlnw7xlZGFkIGVuIGxhIGVtcHJlc2EsIGxvcyBhw7FvcyBjb24gZWwgbWlzbW8gamVmZSB5IGxhIGV4cGVyaWVuY2lhDQp0b3RhbCwgY3V5YXMgY29ycmVsYWNpb25lcyBjb24gbGEgYW50aWfDvGVkYWQgZW4gZWwgY2FyZ28gb3NjaWxhYmFuIGVudHJlDQowLDQ5IHkgMCw4NS4NCg0KIyMgRXZhbHVhY2nDs24gZGVsIFBvZGVyIFByZWRpY3Rpdm8gZGVsIE1vZGVsbyAoQ3VydmEgUk9DIHkgQVVDKQ0KDQpFbCBwb2RlciBwcmVkaWN0aXZvIGRlbCBtb2RlbG8gc2UgZXZhbHVhIG1lZGlhbnRlIGxhIGN1cnZhIFJPQyB5IGVsIMOhcmVhDQpiYWpvIGxhIGN1cnZhLiBBIHBhcnRpciBkZSBsb3MgY29lZmljaWVudGVzIGVzdGltYWRvcyBzZSBjYWxjdWxhIGxhDQpwcm9iYWJpbGlkYWQgZGUgcm90YWNpw7NuIHByZWRpY2hhIHBhcmEgY2FkYSB1bm8gZGUgbG9zIDEuNDcwIGVtcGxlYWRvcw0KZGUgbGEgYmFzZS4NCg0KRGFkbyBxdWUgbGEgY29udmVyc2nDs24gZGUgZXN0YXMgcHJvYmFiaWxpZGFkZXMgZW4gdW5hIGNsYXNpZmljYWNpw7NuDQpiaW5hcmlhIGRlcGVuZGUgZGVsIHB1bnRvIGRlIGNvcnRlIGFkb3B0YWRvLCB5IHF1ZSBkaWNoYSBlbGVjY2nDs24NCm1vZGlmaWNhIGVsIGVxdWlsaWJyaW8gZW50cmUgbGEgZGV0ZWNjacOzbiBkZSBjYXNvcyBkZSByb3RhY2nDs24geSBsYQ0KZ2VuZXJhY2nDs24gZGUgZmFsc2FzIGFsYXJtYXMsIGxhIGN1cnZhIFJPQyByZXByZXNlbnRhIGxhIHNlbnNpYmlsaWRhZA0KZnJlbnRlIGEgbGEgdGFzYSBkZSBmYWxzb3MgcG9zaXRpdm9zIGEgbG8gbGFyZ28gZGUgdG9kb3MgbG9zIHVtYnJhbGVzDQpwb3NpYmxlcy4gRWwgw6FyZWEgYmFqbyBlc3RhIGN1cnZhIHJlc3VtZSBsYSBjYXBhY2lkYWQgZGlzY3JpbWluYW50ZSBkZWwNCm1vZGVsbyBlbiB1biBpbmRpY2Fkb3IgaW5kZXBlbmRpZW50ZSBkZWwgcHVudG8gZGUgY29ydGUsIGVsIGN1YWwgc2UNCnJlcG9ydMOzIGp1bnRvIGNvbiBzdSBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGRlbCA5NSAlLg0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCnJvdGFjaW9uX21vZCA8LSByb3RhY2lvbl9tb2QgfD4NCiAgbXV0YXRlKHByb2IgPSBwcmVkaWN0KG1vZGVsbywgdHlwZSA9ICJyZXNwb25zZSIpKQ0KDQpyb2NfbW9kZWxvIDwtIHBST0M6OnJvYyhyZXNwb25zZSA9IHJvdGFjaW9uX21vZCR5LA0KICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdG9yID0gcm90YWNpb25fbW9kJHByb2IsDQogICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKDAsIDEpLCBkaXJlY3Rpb24gPSAiPCIpDQoNCmF1Y192YWxvciA8LSBwUk9DOjphdWMocm9jX21vZGVsbykNCmljX2F1YyA8LSBwUk9DOjpjaS5hdWMocm9jX21vZGVsbykNCg0KYXVjX3ZhbG9yDQppY19hdWMNCmBgYA0KDQpgYGB7cn0NCmRhdG9zX3JvYyA8LSB0aWJibGUoDQogIGVzcGVjaWZpY2lkYWQgPSByb2NfbW9kZWxvJHNwZWNpZmljaXRpZXMsDQogIHNlbnNpYmlsaWRhZCAgPSByb2NfbW9kZWxvJHNlbnNpdGl2aXRpZXMNCikgfD4NCiAgbXV0YXRlKGZwciA9IDEgLSBlc3BlY2lmaWNpZGFkKQ0KDQpkYXRvc19yb2MgfD4NCiAgZ2dwbG90KGFlcyh4ID0gZnByLCB5ID0gc2Vuc2liaWxpZGFkKSkgKw0KICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gIiNiODU0M2YiKSArDQogIGdlb21fbGluZShjb2xvciA9ICIjMjEzODRhIiwgbGluZXdpZHRoID0gMSkgKw0KICBhbm5vdGF0ZSgidGV4dCIsIHggPSAwLjYyLCB5ID0gMC4yOCwNCiAgICAgICAgICAgbGFiZWwgPSBwYXN0ZTAoIkFVQyA9ICIsIGZvcm1hdChyb3VuZChhcy5udW1lcmljKGF1Y192YWxvciksIDMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2ltYWwubWFyayA9ICIsIikpLA0KICAgICAgICAgICBjb2xvciA9ICIjMjEzODRhIiwgZm9udGZhY2UgPSAiYm9sZCIsIHNpemUgPSA0LjUpICsNCiAgY29vcmRfZXF1YWwoKSArDQogIGxhYnModGl0bGUgPSAiIiwNCiAgICAgICB4ID0gIjEg4oiSIEVzcGVjaWZpY2lkYWQgKHRhc2EgZGUgZmFsc29zIHBvc2l0aXZvcykiLA0KICAgICAgIHkgPSAiU2Vuc2liaWxpZGFkICh0YXNhIGRlIHZlcmRhZGVyb3MgcG9zaXRpdm9zKSIpICsNCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxMSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCwgaGp1c3QgPSAwLjUpKQ0KYGBgDQoNCipGaWd1cmEgMy41LiBDdXJ2YSBST0MgZGVsIG1vZGVsbyBkZSByZWdyZXNpw7NuIGxvZ8Otc3RpY2EqDQoNCkVsIMOhcmVhIGJham8gbGEgY3VydmEgUk9DIGFsY2FuemEgdW4gdmFsb3IgZGUgMCw3ODEsIGNvbiB1biBpbnRlcnZhbG8gZGUNCmNvbmZpYW56YSBkZWwgOTUlIGNvbXByZW5kaWRvIGVudHJlIDAsNzQ2IHkgMCw4MTYuIEVzdGUgcmVzdWx0YWRvIGluZGljYQ0KcXVlLCBzaSBzZSBzZWxlY2Npb25hcmFuIGFsIGF6YXIgdW4gZW1wbGVhZG8gcXVlIHJvdMOzIHkgb3RybyBxdWUNCnBlcm1hbmVjacOzIGVuIGxhIG9yZ2FuaXphY2nDs24sIGVsIG1vZGVsbyBhc2lnbmFyw61hIHVuYSBwcm9iYWJpbGlkYWQgZGUNCnJvdGFjacOzbiBtYXlvciBhbCBwcmltZXJvIGVuIGVsIDc4LDElIGRlIGxvcyBjYXNvcy4gRGFkbyBxdWUgdW4gdmFsb3IgZGUNCjAsNSBjb3JyZXNwb25kZXLDrWEgYSB1bmEgY2xhc2lmaWNhY2nDs24gcHVyYW1lbnRlIGFsZWF0b3JpYSwgcmVwcmVzZW50YWRhDQpwb3IgbGEgZGlhZ29uYWwgZGUgbGEgRmlndXJhIDMuNSwgeSBxdWUgZWwgaW50ZXJ2YWxvIGRlIGNvbmZpYW56YSBzZQ0Kc2l0w7phIMOtbnRlZ3JhbWVudGUgcG9yIGVuY2ltYSBkZSBlc2UgdW1icmFsLCBsYSBjYXBhY2lkYWQgZGlzY3JpbWluYW50ZQ0KZGVsIG1vZGVsbyByZXN1bHRhIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmEuIENvbmZvcm1lIGEgbG9zDQpjcml0ZXJpb3MgaGFiaXR1YWxtZW50ZSBlbXBsZWFkb3MgZW4gbGEgbGl0ZXJhdHVyYSwgdW4gw6FyZWEgY29tcHJlbmRpZGENCmVudHJlIDAsNyB5IDAsOCByZWZsZWphIHVuYSBkaXNjcmltaW5hY2nDs24gYWNlcHRhYmxlLCBkZSBtb2RvIHF1ZSBlbA0KdmFsb3Igb2J0ZW5pZG8gc2UgdWJpY2EgZW4gZWwgZXh0cmVtbyBzdXBlcmlvciBkZSBkaWNobyByYW5nbywgcHLDs3hpbW8NCmFsIHVtYnJhbCBkZSAwLDggYSBwYXJ0aXIgZGVsIGN1YWwgbGEgZGlzY3JpbWluYWNpw7NuIHNlIGNvbnNpZGVyYQ0KZXhjZWxlbnRlLg0KDQpMYSBmb3JtYSBkZSBsYSBjdXJ2YSBhcG9ydGEgaW5mb3JtYWNpw7NuIGFkaWNpb25hbCBkZSB1dGlsaWRhZCBwcsOhY3RpY2EuDQpTdSBhc2NlbnNvIHJlc3VsdGEgcGFydGljdWxhcm1lbnRlIHByb251bmNpYWRvIGVuIGVsIHRyYW1vIGluaWNpYWwsDQpkb25kZSBhbGNhbnphIHVuYSBzZW5zaWJpbGlkYWQgY2VyY2FuYSBhbCA2MCUgY29uIHVuYSB0YXNhIGRlIGZhbHNvcw0KcG9zaXRpdm9zIGluZmVyaW9yIGFsIDE1JSwgeSBzdXBlcmEgZWwgNzUlIGRlIHNlbnNpYmlsaWRhZCBjb24gdW5hIHRhc2ENCmRlIGZhbHNvcyBwb3NpdGl2b3MgcHLDs3hpbWEgYWwgMjUlLiBBIHBhcnRpciBkZSBlc2UgcHVudG8gbGEgY3VydmEgc2UNCmFwbGFuYSBwcm9ncmVzaXZhbWVudGUsIGxvIHF1ZSBpbXBsaWNhIHF1ZSBjYWRhIGNhc28gZGUgcm90YWNpw7NuDQphZGljaW9uYWwgZGV0ZWN0YWRvIGV4aWdlIGNsYXNpZmljYXIgY29tbyBwb2JsYWNpw7NuIGVuIHJpZXNnbyBhIHVuDQpuw7ptZXJvIGNyZWNpZW50ZSBkZSBlbXBsZWFkb3MgcXVlIG5vIGhhYnLDrWFuIHJvdGFkby4gRXN0ZSBjb21wb3J0YW1pZW50bw0KaW5kaWNhIHF1ZSBlbCBtb2RlbG8gZGlzY3JpbWluYSBjb24gZXNwZWNpYWwgZWZpY2FjaWEgZW4gZWwgZXh0cmVtbyBkZQ0KbWF5b3Igcmllc2dvLCBjb25kaWNpw7NuIGZhdm9yYWJsZSBwYXJhIHN1IGFwbGljYWNpw7NuIHByw6FjdGljYSwgZXMgZGVjaXIsDQp1bmEgZXN0cmF0ZWdpYSBkZSByZXRlbmNpw7NuIGRpcmlnaWRhIGFwcm94aW1hZGFtZW50ZSBhbCAyMCUgZGUgbG9zDQplbXBsZWFkb3MgY29uIG1heW9yIHByb2JhYmlsaWRhZCBlc3RpbWFkYSBwZXJtaXRpcsOtYSBpZGVudGlmaWNhciBjZXJjYQ0KZGUgdHJlcyBjdWFydGFzIHBhcnRlcyBkZSBsb3MgY2Fzb3MgZGUgcm90YWNpw7NuIGVmZWN0aXZhLiBDb252aWVuZQ0Kc2XDsWFsYXIsIGNvbW8gbGltaXRhY2nDs24sIHF1ZSBlbCDDoXJlYSBiYWpvIGxhIGN1cnZhIHNlIGVzdGltw7Mgc29icmUgbGFzDQptaXNtYXMgb2JzZXJ2YWNpb25lcyBlbXBsZWFkYXMgZW4gZWwgYWp1c3RlIGRlbCBtb2RlbG8sIGxvIHF1ZSB0aWVuZGUgYQ0KcHJvZHVjaXIgdW5hIG1lZGlkYSBvcHRpbWlzdGEgZGUgc3UgZGVzZW1wZcOxbzsgdW5hIGV2YWx1YWNpw7NuIG3DoXMNCnJpZ3Vyb3NhIHJlcXVlcmlyw61hIHZhbGlkYXJsbyBzb2JyZSB1bmEgbXVlc3RyYSBpbmRlcGVuZGllbnRlIG8gbWVkaWFudGUNCnZhbGlkYWNpw7NuIGNydXphZGEuDQoNCiMjIFNpbXVsYWNpw7NuIGNvbiB1biBlbXBsZWFkbyBoaXBvdMOpdGljbw0KDQpFbiBlc3RlIGNhc28sIHNlIGRlYmUgY3JlYXIgdW4gcGVyZmlsIGhpcG90w6l0aWNvIGNvbiBsYXMgbWlzbWFzDQp2YXJpYWJsZXMgZGVsIG1vZGVsbyBjYWxjdWxhZG8geSBldmFsdWFkbyBlbiBsYSBzZWNjacOzbiBhdGVyaW9yLA0KY2FsY3VsYXIgc3UgcHJvYmFiaWxpZGFkIGVzdGltYWRhIGNvbiBgcHJlZGljdCguLi4sIHR5cGUgPSAicmVzcG9uc2UiKWANCnkgY29tcGFyYXJsYSBjb250cmEgdW4gcHVudG8gZGUgY29ydGUuIENvbW8gZWwgb2JqZXRpdm8gZXMgaW50ZXJ2ZW5pcg0KcHJldmVudGl2YW1lbnRlIHBhcmEgbm8gcGVyZGVyIGVtcGxlYWRvcywgY29udmllbmUgdXNhciB1biBjb3J0ZSBlbGVnaWRvDQpjb24gbGEgY3VydmEgUk9DIHkgZWwgw61uZGljZSBkZSBZb3VkZW4gKHVzYWRvIGVuIENpZW5jaWEgZGUgRGF0b3MsIHF1ZQ0KZXF1aWxpYnJhIHNlbnNpYmlsaWRhZCB5IGVzcGVjaWZpY2lkYWQpLiBDb21vIGFsdGVybmF0aXZhLCBzZSBwdWVkZQ0KZWxlZ2lyIHVuIGNvcnRlIG3DoXMgYmFqbyBzaSBzZSBwcmVmaWVyZSBkZXRlY3RhciBtw6FzIHBvc2libGVzIGNhc29zIGRlDQpyb3RhY2nDs24gYXVucXVlIHNlIGdlbmVyZW4gbcOhcyBmYWxzYXMgYWxlcnRhcy4gTGFzIHByb2JhYmlsaWRhZGVzIGVuIHVuDQpNb2RlbG8gZGUgUmVncmVzacOzbiBMb2fDrXN0aWNhIGJpbm9taWFsIHNlIG9idGllbmVuIGNvbg0KYHR5cGUgPSAicmVzcG9uc2UiYCwgbHVlZ28gZWwgY29ydGUgdHJhbnNmb3JtYSBlc2FzIHByb2JhYmlsaWRhZGVzIGVuDQp1bmEgZGVjaXNpw7NuIHPDrS9uby4NCg0KRXN0ZSBwcm9jZWRpbWllbnRvIHNlIHJlYWxpemEgY29uIGF5dWRhIGRlIGxhIGxpYnJlcsOtYWBwUk9DYC4gRWwgw61uZGljZQ0KZGUgWW91ZGVuIHNlbGVjY2lvbmEgZWwgdW1icmFsIHF1ZSBtYXhpbWl6YToNCg0KJCRKID0gXHRleHR7U2Vuc2liaWxpZGFkfSArIFx0ZXh0e0VzcGVjaWZpY2lkYWR9IC0gMSQkIFVuIGNvcnRlIG1lbm9yDQppbmNyZW1lbnRhIGxhIHNlbnNpYmlsaWRhZCB5IHJlZHVjZSBsYSBlc3BlY2lmaWNpZGFkOyBlbiBvdHJhcyBwYWxhYnJhcywNCmlkZW50aWZpY2Fyw6EgbcOhcyBlbXBsZWFkb3MgY29uIHBvc2libGUgcm90YWNpw7NuLCBhIGNvc3RhIGRlIGludGVydmVuaXINCmVuIG3DoXMgZW1wbGVhZG9zIHF1ZSBmaW5hbG1lbnRlIG5vIHJvdGFyw61hbi4NCg0KYGBge3IsfQ0KbGlicmFyeShwUk9DKQ0KDQpwcm9iX2VudHJlbmFtaWVudG8gPC0gcHJlZGljdCgNCiAgbW9kZWxvLA0KICBuZXdkYXRhID0gcm90YWNpb25fbW9kLA0KICB0eXBlID0gInJlc3BvbnNlIg0KKQ0KDQpjdXJ2YV9yb2MgPC0gcm9jKA0KICByZXNwb25zZSA9IHJvdGFjaW9uX21vZCR5LA0KICBwcmVkaWN0b3IgPSBwcm9iX2VudHJlbmFtaWVudG8sDQogIGxldmVscyA9IGMoMCwgMSksDQogIGRpcmVjdGlvbiA9ICI8Ig0KKQ0KDQpjb3J0ZV95b3VkZW4gPC0gY29vcmRzKA0KICBjdXJ2YV9yb2MsDQogIHggPSAiYmVzdCIsDQogIGJlc3QubWV0aG9kID0gInlvdWRlbiIsDQogIHJldCA9IGMoInRocmVzaG9sZCIsICJzZW5zaXRpdml0eSIsICJzcGVjaWZpY2l0eSIpLA0KICB0cmFuc3Bvc2UgPSBGQUxTRQ0KKQ0KDQpjb3J0ZV95b3VkZW4NCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCmNvcnRlIDwtIGFzLm51bWVyaWMoY29ydGVfeW91ZGVuWyJ0aHJlc2hvbGQiXSkNCnJvdW5kKGNvcnRlLCAzKQ0KYGBgDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0KZW1wbGVhZG9faGlwb3RldGljbyA8LSBkYXRhLmZyYW1lKA0KICBIb3Jhc19FeHRyYSA9IGZhY3RvcigNCiAgICAiU8OtIiwNCiAgICBsZXZlbHMgPSBsZXZlbHMocm90YWNpb25fbW9kJEhvcmFzX0V4dHJhKQ0KICApLA0KICBFc3RhZG9fQ2l2aWwgPSBmYWN0b3IoDQogICAgIlNvbHRlcm8iLA0KICAgIGxldmVscyA9IGxldmVscyhyb3RhY2lvbl9tb2QkRXN0YWRvX0NpdmlsKQ0KICApLA0KICBTYXRpc2ZhY2Npw7NuX0xhYm9yYWwgPSBmYWN0b3IoDQogICAgIkluc2F0aXNmZWNobyIsDQogICAgbGV2ZWxzID0gbGV2ZWxzKHJvdGFjaW9uX21vZCRTYXRpc2ZhY2Npw7NuX0xhYm9yYWwpDQogICksDQogIEVkYWQgPSA0MCwNCiAgSW5ncmVzb19NZW5zdWFsX21pbCA9IDQuNSwNCiAgQW50aWfDvGVkYWRfQ2FyZ28gPSAyDQopDQoNCnByb2Jfcm90YWNpb24gPC0gcHJlZGljdCgNCiAgbW9kZWxvLA0KICBuZXdkYXRhID0gZW1wbGVhZG9faGlwb3RldGljbywNCiAgdHlwZSA9ICJyZXNwb25zZSINCikNCg0KcHJvYl9yb3RhY2lvbg0KcGFzdGUwKHJvdW5kKHByb2Jfcm90YWNpb24gKiAxMDAsIDEpLCAiJSIpDQpgYGANCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQpkZWNpc2lvbiA8LSBpZl9lbHNlKA0KICBwcm9iX3JvdGFjaW9uID49IGNvcnRlLA0KICAiSW50ZXJ2ZW5pcjogcmllc2dvIGVzdGltYWRvIGRlIHJvdGFjacOzbiBhbHRvIiwNCiAgIk5vIGludGVydmVuaXIgZGUgZm9ybWEgcHJpb3JpdGFyaWE6IHJpZXNnbyBlc3RpbWFkbyBiYWpvIg0KKQ0KDQpkZWNpc2lvbg0KYGBgDQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0KcmVzdWx0YWRvX3ByZWRpY2Npb24gPC0gZW1wbGVhZG9faGlwb3RldGljbyB8Pg0KICBtdXRhdGUoDQogICAgYFByb2JhYmlsaWRhZCBlc3RpbWFkYSBkZSByb3RhY2nDs25gID0gcHJvYl9yb3RhY2lvbiwNCiAgICBgUHJvYmFiaWxpZGFkICglKWAgPSBwYXN0ZTAoDQogICAgICBmb3JtYXQoDQogICAgICAgIHJvdW5kKHByb2Jfcm90YWNpb24gKiAxMDAsIDEpLA0KICAgICAgICBuc21hbGwgPSAxLA0KICAgICAgICBkZWNpbWFsLm1hcmsgPSAiLCINCiAgICAgICksDQogICAgICAiJSINCiAgICApLA0KICAgIGBQdW50byBkZSBjb3J0ZWAgPSByb3VuZChjb3J0ZSwgMyksDQogICAgRGVjaXNpw7NuID0gaWZfZWxzZSgNCiAgICAgIHByb2Jfcm90YWNpb24gPj0gY29ydGUsDQogICAgICAiSW50ZXJ2ZW5pciIsDQogICAgICAiTm8gaW50ZXJ2ZW5pciBkZSBmb3JtYSBwcmlvcml0YXJpYSINCiAgICApDQogICkgfD4NCiAgcGl2b3RfbG9uZ2VyKA0KICAgIGNvbHMgPSBldmVyeXRoaW5nKCksDQogICAgbmFtZXNfdG8gPSAiQ2FyYWN0ZXLDrXN0aWNhIiwNCiAgICB2YWx1ZXNfdG8gPSAiVmFsb3IiLA0KICAgIHZhbHVlc190cmFuc2Zvcm0gPSBsaXN0KFZhbG9yID0gYXMuY2hhcmFjdGVyKQ0KICApIHw+DQogIG11dGF0ZSgNCiAgICBWYWxvciA9IGNhc2Vfd2hlbigNCiAgICAgIENhcmFjdGVyw61zdGljYSA9PSAiUHJvYmFiaWxpZGFkIGVzdGltYWRhIGRlIHJvdGFjacOzbiIgfg0KICAgICAgICBmb3JtYXQoDQogICAgICAgICAgcm91bmQoYXMubnVtZXJpYyhWYWxvciksIDQpLA0KICAgICAgICAgIG5zbWFsbCA9IDQsDQogICAgICAgICAgZGVjaW1hbC5tYXJrID0gIiwiDQogICAgICAgICksDQogICAgICBDYXJhY3RlcsOtc3RpY2EgPT0gIlB1bnRvIGRlIGNvcnRlIiB+DQogICAgICAgIGZvcm1hdCgNCiAgICAgICAgICByb3VuZChhcy5udW1lcmljKFZhbG9yKSwgMyksDQogICAgICAgICAgbnNtYWxsID0gMywNCiAgICAgICAgICBkZWNpbWFsLm1hcmsgPSAiLCINCiAgICAgICAgKSwNCiAgICAgIFRSVUUgfiBWYWxvcg0KICAgICksDQogICAgDQogICAgQ2FyYWN0ZXLDrXN0aWNhID0gZHBseXI6OnJlY29kZSgNCiAgICAgIENhcmFjdGVyw61zdGljYSwNCiAgICAgIEhvcmFzX0V4dHJhID0gIkhvcmFzIGV4dHJhIiwNCiAgICAgIEVzdGFkb19DaXZpbCA9ICJFc3RhZG8gY2l2aWwiLA0KICAgICAgU2F0aXNmYWNjacOzbl9MYWJvcmFsID0gIlNhdGlzZmFjY2nDs24gbGFib3JhbCIsDQogICAgICBFZGFkID0gIkVkYWQgKGHDsW9zKSIsDQogICAgICBJbmdyZXNvX01lbnN1YWxfbWlsID0gIkluZ3Jlc28gbWVuc3VhbCAobWlsZXMgZGUgdW5pZGFkZXMgbW9uZXRhcmlhcykiLA0KICAgICAgQW50aWfDvGVkYWRfQ2FyZ28gPSAiQW50aWfDvGVkYWQgZW4gZWwgY2FyZ28gKGHDsW9zKSINCiAgICApDQogICkNCg0KcmVzdWx0YWRvX3ByZWRpY2Npb24gfD4NCiAgdGFibGFfZXN0aWxvKA0KICAgIHRpdHVsbyA9ICIiLA0KICAgIGFsaW5lYWNpb24gPSBjKCJsIiwgImwiKSwNCiAgICBub3RhID0gcGFzdGUoDQogICAgICAiTGEgZGVjaXNpw7NuIHNlIGJhc2EgZW4gbGEgcHJvYmFiaWxpZGFkIGVzdGltYWRhIHBvciBlbCBtb2RlbG8gZGUgcmVncmVzacOzbiBsb2fDrXN0aWNhLiIsDQogICAgICAiU2UgcmVjb21pZW5kYSBpbnRlcnZlbmlyIGN1YW5kbyBsYSBwcm9iYWJpbGlkYWQgZXN0aW1hZGEgZXMgaWd1YWwgbyBzdXBlcmlvciBhbCBwdW50byBkZSBjb3J0ZSIsDQogICAgICAic2VsZWNjaW9uYWRvIG1lZGlhbnRlIGVsIMOtbmRpY2UgZGUgWW91ZGVuLiINCiAgICApDQogICkNCmBgYA0KDQoqVGFibGEgMy45LiBQcmVkaWNjacOzbiBkZSByb3RhY2nDs24gcGFyYSB1biBlbXBsZWFkbyBoaXBvdMOpdGljbyoNCg0KUGFyYSBpbHVzdHJhciBsYSBhcGxpY2FjacOzbiBwcmVkaWN0aXZhIGRlbCBtb2RlbG8sIHNlIGV2YWx1w7MgdW4gZW1wbGVhZG8NCmhpcG90w6l0aWNvIHF1ZSByZWFsaXphIGhvcmFzIGV4dHJhLCBlc3TDoSBzb2x0ZXJvKGEpLCBwcmVzZW50YSB1biBuaXZlbA0KZGUgc2F0aXNmYWNjacOzbiBsYWJvcmFsICJJbnNhdGlzZmVjaG8iLCB0aWVuZSA0MCBhw7FvcywgcGVyY2liZSA0LjUwMA0KdW5pZGFkZXMgbW9uZXRhcmlhcyBtZW5zdWFsZXMgeSBjdWVudGEgY29uIGRvcyBhw7FvcyBkZSBhbnRpZ8O8ZWRhZCBlbiBlbA0KY2FyZ28uDQoNCkVsIG1vZGVsbyBlc3RpbcOzIHVuYSBwcm9iYWJpbGlkYWQgZGUgcm90YWNpw7NuIGRlDQpgciBzY2FsZXM6OnBlcmNlbnQocHJvYl9yb3RhY2lvbiwgYWNjdXJhY3kgPSAwLjEsIGRlY2ltYWwubWFyayA9ICIsIilgLg0KU2UgZGVmaW5pw7MgdW4gcHVudG8gZGUgY29ydGUgZGUgYHIgcm91bmQoY29ydGUsIDMpYCwgb2J0ZW5pZG8gbWVkaWFudGUNCmVsIMOtbmRpY2UgZGUgWW91ZGVuIGEgcGFydGlyIGRlIGxhIGN1cnZhIFJPQy4gRGFkbyBxdWUgbGEgcHJvYmFiaWxpZGFkDQplc3RpbWFkYSBgciBpZmVsc2UocHJvYl9yb3RhY2lvbiA+PSBjb3J0ZSwgInN1cGVyYSAiLCAiZXMgaW5mZXJpb3IgYSIpYA0KZWwgcHVudG8gZGUgY29ydGUsIHNlIHJlY29taWVuZGENCmByIGlmZWxzZShwcm9iX3JvdGFjaW9uID49IGNvcnRlLCAiaW50ZXJ2ZW5pciBwcmV2ZW50aXZhbWVudGUgYWwgZW1wbGVhZG8gbWVkaWFudGUgYWNjaW9uZXMgZGUgcmV0ZW5jacOzbiBvIG1vdGl2YWNpw7NuLiIsICJubyBwcmlvcml6YXIgdW5hIGludGVydmVuY2nDs24gZXNwZWPDrWZpY2EgZGUgcmV0ZW5jacOzbiBwYXJhIGVzdGUgZW1wbGVhZG8uIilgDQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShwUk9DKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCg0KIyBQcm9iYWJpbGlkYWRlcyBlc3RpbWFkYXMgcGFyYSB0b2RvcyBsb3MgZW1wbGVhZG9zDQpwcm9iX2VudHJlbmFtaWVudG8gPC0gcHJlZGljdCgNCiAgbW9kZWxvLA0KICBuZXdkYXRhID0gcm90YWNpb25fbW9kLA0KICB0eXBlID0gInJlc3BvbnNlIg0KKQ0KDQojIEN1cnZhIFJPQw0KY3VydmFfcm9jIDwtIHBST0M6OnJvYygNCiAgcmVzcG9uc2UgPSByb3RhY2lvbl9tb2QkeSwNCiAgcHJlZGljdG9yID0gcHJvYl9lbnRyZW5hbWllbnRvLA0KICBsZXZlbHMgPSBjKDAsIDEpLA0KICBkaXJlY3Rpb24gPSAiPCINCikNCg0KIyBDb29yZGVuYWRhcyBhc29jaWFkYXMgYWwgcHVudG8gZGUgY29ydGUgeWEgZWxlZ2lkbw0KY29vcmRfY29ydGUgPC0gcFJPQzo6Y29vcmRzKA0KICBjdXJ2YV9yb2MsDQogIHggPSBjb3J0ZSwNCiAgaW5wdXQgPSAidGhyZXNob2xkIiwNCiAgcmV0ID0gYygidGhyZXNob2xkIiwgInNlbnNpdGl2aXR5IiwgInNwZWNpZmljaXR5IiksDQogIHRyYW5zcG9zZSA9IEZBTFNFDQopDQoNCiMgRGF0YSBmcmFtZSBwYXJhIGdncGxvdA0KZGF0b3Nfcm9jIDwtIHRpYmJsZSgNCiAgc2Vuc2liaWxpZGFkID0gY3VydmFfcm9jJHNlbnNpdGl2aXRpZXMsDQogIGVzcGVjaWZpY2lkYWQgPSBjdXJ2YV9yb2Mkc3BlY2lmaWNpdGllcw0KKSB8Pg0KICBtdXRhdGUoDQogICAgdW5vX21lbm9zX2VzcGVjaWZpY2lkYWQgPSAxIC0gZXNwZWNpZmljaWRhZA0KICApDQoNCiMgUHVudG8gZGUgY29ydGUgZW4gY29vcmRlbmFkYXMgUk9DDQpwdW50b19jb3J0ZSA8LSB0aWJibGUoDQogIGNvcnRlID0gYXMubnVtZXJpYyhjb29yZF9jb3J0ZVsidGhyZXNob2xkIl0pLA0KICBzZW5zaWJpbGlkYWQgPSBhcy5udW1lcmljKGNvb3JkX2NvcnRlWyJzZW5zaXRpdml0eSJdKSwNCiAgZXNwZWNpZmljaWRhZCA9IGFzLm51bWVyaWMoY29vcmRfY29ydGVbInNwZWNpZmljaXR5Il0pLA0KICB1bm9fbWVub3NfZXNwZWNpZmljaWRhZCA9IDEgLSBlc3BlY2lmaWNpZGFkDQopDQoNCiMgQVVDDQphdWNfbW9kZWxvIDwtIGFzLm51bWVyaWMocFJPQzo6YXVjKGN1cnZhX3JvYykpDQoNCmdncGxvdCgNCiAgZGF0b3Nfcm9jLA0KICBhZXMoeCA9IHVub19tZW5vc19lc3BlY2lmaWNpZGFkLCB5ID0gc2Vuc2liaWxpZGFkKQ0KKSArDQogIGdlb21fYWJsaW5lKA0KICAgIGxpbmV0eXBlID0gImRhc2hlZCIsDQogICAgY29sb3IgPSAiIzlDQTNBRiIsDQogICAgbGluZXdpZHRoID0gMC43DQogICkgKw0KICBnZW9tX2xpbmUoDQogICAgY29sb3IgPSAiIzIxMzg0QSIsDQogICAgbGluZXdpZHRoID0gMS4xDQogICkgKw0KICBnZW9tX3BvaW50KA0KICAgIGRhdGEgPSBwdW50b19jb3J0ZSwNCiAgICBhZXMoDQogICAgICB4ID0gdW5vX21lbm9zX2VzcGVjaWZpY2lkYWQsDQogICAgICB5ID0gc2Vuc2liaWxpZGFkDQogICAgKSwNCiAgICBpbmhlcml0LmFlcyA9IEZBTFNFLA0KICAgIGNvbG9yID0gIiNCODU0M0YiLA0KICAgIGZpbGwgPSAiI0I4NTQzRiIsDQogICAgc2l6ZSA9IDMuNQ0KICApICsNCiAgZ2VvbV9sYWJlbCgNCiAgICBkYXRhID0gcHVudG9fY29ydGUsDQogICAgYWVzKA0KICAgICAgeCA9IHVub19tZW5vc19lc3BlY2lmaWNpZGFkLA0KICAgICAgeSA9IHNlbnNpYmlsaWRhZCwNCiAgICAgIGxhYmVsID0gcGFzdGUwKA0KICAgICAgICAiQ29ydGUgZGUgWW91ZGVuID0gIiwNCiAgICAgICAgZm9ybWF0KHJvdW5kKGNvcnRlLCAzKSwgZGVjaW1hbC5tYXJrID0gIiwiKSwNCiAgICAgICAgIlxuU2Vuc2liaWxpZGFkID0gIiwNCiAgICAgICAgc2NhbGVzOjpwZXJjZW50KHNlbnNpYmlsaWRhZCwgYWNjdXJhY3kgPSAwLjEsIGRlY2ltYWwubWFyayA9ICIsIiksDQogICAgICAgICJcbkVzcGVjaWZpY2lkYWQgPSAiLA0KICAgICAgICBzY2FsZXM6OnBlcmNlbnQoZXNwZWNpZmljaWRhZCwgYWNjdXJhY3kgPSAwLjEsIGRlY2ltYWwubWFyayA9ICIsIikNCiAgICAgICkNCiAgICApLA0KICAgIGluaGVyaXQuYWVzID0gRkFMU0UsDQogICAgaGp1c3QgPSAtMC4wNSwNCiAgICB2anVzdCA9IDEuMSwNCiAgICBzaXplID0gMy4yLA0KICAgIGxhYmVsLnNpemUgPSAwLjI1LA0KICAgIGZpbGwgPSAid2hpdGUiLA0KICAgIGNvbG9yID0gIiMyMTM4NEEiDQogICkgKw0KICBjb29yZF9jYXJ0ZXNpYW4oY2xpcCA9ICJvZmYiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiIiwNCiAgICBzdWJ0aXRsZSA9IHBhc3RlMCgNCiAgICAgICJBVUMgPSAiLA0KICAgICAgZm9ybWF0KHJvdW5kKGF1Y19tb2RlbG8sIDMpLCBkZWNpbWFsLm1hcmsgPSAiLCIpLA0KICAgICAgIjsgcHVudG8gZGUgY29ydGUgc2VsZWNjaW9uYWRvIG1lZGlhbnRlIGVsIMOtbmRpY2UgZGUgWW91ZGVuIg0KICAgICksDQogICAgeCA9ICIxIOKIkiBFc3BlY2lmaWNpZGFkIiwNCiAgICB5ID0gIlNlbnNpYmlsaWRhZCINCiAgKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTEpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dCgNCiAgICAgIGZhY2UgPSAiYm9sZCIsDQogICAgICBzaXplID0gMTQsDQogICAgICBoanVzdCA9IDAuNSwNCiAgICAgIGNvbG9yID0gIiMyMTM4NEEiDQogICAgKSwNCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KA0KICAgICAgc2l6ZSA9IDEwLA0KICAgICAgaGp1c3QgPSAwLjUsDQogICAgICBjb2xvciA9ICIjNEI1NTYzIg0KICAgICksDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbig1LjUsIDgwLCA1LjUsIDUuNSkNCiAgKQ0KYGBgDQoNCipGaWd1cmEgMy42LiBDdXJ2YSBST0MgeSBwdW50byBkZSBjb3J0ZSDDs3B0aW1vKg0KDQpMYSBjdXJ2YSBST0MgcGVybWl0acOzIHNlbGVjY2lvbmFyIHVuIHB1bnRvIGRlIGNvcnRlIGRlIDAsMTg2IG1lZGlhbnRlIGVsDQrDrW5kaWNlIGRlIFlvdWRlbiwgY3JpdGVyaW8gcXVlIGJ1c2NhIGVxdWlsaWJyYXIgbGEgc2Vuc2liaWxpZGFkIHkgbGENCmVzcGVjaWZpY2lkYWQgZGVsIGNsYXNpZmljYWRvci4gRW4gY29uc2VjdWVuY2lhLCBsb3MgZW1wbGVhZG9zIGNvbiB1bmENCnByb2JhYmlsaWRhZCBlc3RpbWFkYSBkZSByb3RhY2nDs24gaWd1YWwgbyBzdXBlcmlvciBhIDE4LDYlIHNlIGNsYXNpZmljYW4NCmNvbW8gZGUgcmllc2dvIHkgc2UgcHJpb3JpemFuIHBhcmEgdW5hIHBvc2libGUgaW50ZXJ2ZW5jacOzbiBwcmV2ZW50aXZhDQooVmVyIEZpZ3VyYSAzLjYpLg0KDQpQYXJhIGVsIGVtcGxlYWRvIGhpcG90w6l0aWNvIGV2YWx1YWRvLCBlbCBtb2RlbG8gZXN0aW3DsyB1bmEgcHJvYmFiaWxpZGFkDQpkZSByb3RhY2nDs24gZGUgNTEsMyUsIHZhbG9yIHF1ZSBzdXBlcmEgZW4gMzIsNyBwdW50b3MgcG9yY2VudHVhbGVzIGVsDQp1bWJyYWwgZXN0YWJsZWNpZG8uIFBvciB0YW50bywgc2UgcmVjb21pZW5kYSBpbnRlcnZlbmlyIHByZXZlbnRpdmFtZW50ZQ0KbWVkaWFudGUgYWNjaW9uZXMgZGUgcmV0ZW5jacOzbiwgdGFsZXMgY29tbyB1bmEgZW50cmV2aXN0YSBpbmRpdmlkdWFsLA0KcmV2aXNpw7NuIGRlIGNhcmdhIGxhYm9yYWwgeSBob3JhcyBleHRyYSwgZXZhbHVhY2nDs24gZGUgc2F0aXNmYWNjacOzbg0KbGFib3JhbCwgYWx0ZXJuYXRpdmFzIGRlIGRlc2Fycm9sbG8gcHJvZmVzaW9uYWwgbyBhanVzdGVzIGRlDQpjb21wZW5zYWNpw7NuLCBzZWfDum4gZWwgZGlhZ27Ds3N0aWNvIHBhcnRpY3VsYXIgZGVsIGNhc28gKFZlciBGaWd1cmEgMy43KS4NCg0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KGdncGxvdDIpDQoNCmRhdG9zX2RlY2lzaW9uIDwtIHRpYmJsZSgNCiAgaW5kaWNhZG9yID0gIkVtcGxlYWRvIGhpcG90w6l0aWNvIiwNCiAgcHJvYmFiaWxpZGFkID0gYXMubnVtZXJpYyhwcm9iX3JvdGFjaW9uKSwNCiAgY29ydGUgPSBhcy5udW1lcmljKGNvcnRlKQ0KKQ0KDQpnZ3Bsb3QoZGF0b3NfZGVjaXNpb24sIGFlcyh4ID0gaW5kaWNhZG9yLCB5ID0gcHJvYmFiaWxpZGFkKSkgKw0KICBnZW9tX2NvbCgNCiAgICBmaWxsID0gaWZfZWxzZSgNCiAgICAgIHByb2Jfcm90YWNpb24gPj0gY29ydGUsDQogICAgICAiI0I4NTQzRiIsDQogICAgICAiIzJBOUQ4RiINCiAgICApLA0KICAgIHdpZHRoID0gMC40NSwNCiAgICBhbHBoYSA9IDAuOTANCiAgKSArDQogIGdlb21faGxpbmUoDQogICAgYWVzKHlpbnRlcmNlcHQgPSBjb3J0ZSksDQogICAgY29sb3IgPSAiIzIxMzg0QSIsDQogICAgbGluZXdpZHRoID0gMSwNCiAgICBsaW5ldHlwZSA9ICJkYXNoZWQiDQogICkgKw0KICBnZW9tX3RleHQoDQogICAgYWVzKA0KICAgICAgeSA9IHByb2JhYmlsaWRhZCwNCiAgICAgIGxhYmVsID0gcGFzdGUwKA0KICAgICAgICBzY2FsZXM6OnBlcmNlbnQocHJvYmFiaWxpZGFkLCBhY2N1cmFjeSA9IDAuMSwgZGVjaW1hbC5tYXJrID0gIiwiKSwNCiAgICAgICAgIlxuUHJvYmFiaWxpZGFkIGVzdGltYWRhIg0KICAgICAgKQ0KICAgICksDQogICAgdmp1c3QgPSAtMC41LA0KICAgIHNpemUgPSA0LA0KICAgIGNvbG9yID0gIiMzMzMzMzMiDQogICkgKw0KICBhbm5vdGF0ZSgNCiAgICAidGV4dCIsDQogICAgeCA9IDEuMjUsDQogICAgeSA9IGNvcnRlLA0KICAgIGxhYmVsID0gcGFzdGUwKA0KICAgICAgIlB1bnRvIGRlIGNvcnRlIChZb3VkZW4pOiAiLA0KICAgICAgc2NhbGVzOjpwZXJjZW50KGNvcnRlLCBhY2N1cmFjeSA9IDAuMSwgZGVjaW1hbC5tYXJrID0gIiwiKQ0KICAgICksDQogICAgaGp1c3QgPSAwLA0KICAgIHZqdXN0ID0gLTAuNiwNCiAgICBzaXplID0gMy41LA0KICAgIGNvbG9yID0gIiMyMTM4NEEiDQogICkgKw0KICBhbm5vdGF0ZSgNCiAgICAibGFiZWwiLA0KICAgIHggPSAxLA0KICAgIHkgPSAwLjcyLA0KICAgIGxhYmVsID0gIkRlY2lzacOzbjogaW50ZXJ2ZW5pclxucHJldmVudGl2YW1lbnRlIiwNCiAgICBmaWxsID0gIiNGREU4RTUiLA0KICAgIGNvbG9yID0gIiM4RjM1MjMiLA0KICAgIGxhYmVsLnNpemUgPSAwLjMsDQogICAgc2l6ZSA9IDMuOA0KICApICsNCiAgc2NhbGVfeV9jb250aW51b3VzKA0KICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoDQogICAgICBhY2N1cmFjeSA9IDEwLA0KICAgICAgZGVjaW1hbC5tYXJrID0gIiwiDQogICAgKSwNCiAgICBsaW1pdHMgPSBjKDAsIDAuODApLA0KICAgIGV4cGFuZCA9IGV4cGFuc2lvbihtdWx0ID0gYygwLCAwLjA4KSkNCiAgKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiIiwNCiAgICBzdWJ0aXRsZSA9ICIiLA0KICAgIHggPSBOVUxMLA0KICAgIHkgPSAiUHJvYmFiaWxpZGFkIGVzdGltYWRhIGRlIHJvdGFjacOzbiINCiAgKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTEpICsNCiAgdGhlbWUoDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoDQogICAgICBjb2xvciA9ICIjMzMzMzMzIiwNCiAgICAgIHNpemUgPSAxMQ0KICAgICksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dCgNCiAgICAgIGZhY2UgPSAiYm9sZCIsDQogICAgICBzaXplID0gMTQsDQogICAgICBoanVzdCA9IDAuNSwNCiAgICAgIGNvbG9yID0gIiMyMTM4NEEiDQogICAgKSwNCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KA0KICAgICAgc2l6ZSA9IDEwLA0KICAgICAgaGp1c3QgPSAwLjUsDQogICAgICBjb2xvciA9ICIjNEI1NTYzIg0KICAgICksDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCkNCiAgKQ0KYGBgDQoNClwqXCpGaWd1cmEgNC43LiBEZWNpc2nDs24gZGUgaW50ZXJ2ZW5jacOzbiBwYXJhIHVuIGVtcGxlYWRvIGhpcG90w6l0aWNvLg0KQ29tcGFyYWNpw7NuIGVudHJlIGxhIHByb2JhYmlsaWRhZCBlc3RpbWFkYSBkZSByb3RhY2nDs24geSBlbCBwdW50byBkZQ0KY29ydGUNCg0KIyBDb25jbHVzaW9uZXMNCg0KRWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbG9nw61zdGljYSBwZXJtaXRpw7MgaWRlbnRpZmljYXIgZmFjdG9yZXMgYXNvY2lhZG9zDQpzaWduaWZpY2F0aXZhbWVudGUgY29uIGxhIHJvdGFjacOzbiBkZWwgY2FyZ28uIExhIHJlYWxpemFjacOzbiBkZSBob3Jhcw0KZXh0cmEgc2UgY29uc29saWTDsyBjb21vIGVsIHByaW5jaXBhbCBmYWN0b3IgZGUgcmllc2dvLCBtaWVudHJhcyBxdWUgdW5hDQptYXlvciBzYXRpc2ZhY2Npw7NuIGxhYm9yYWwsIHVuIG1heW9yIGluZ3Jlc28gbWVuc3VhbCwgdW5hIG1heW9yIGVkYWQgeQ0KdW5hIG1heW9yIGFudGlnw7xlZGFkIGVuIGVsIGNhcmdvIHNlIGFzb2NpYXJvbiBjb24gbWVub3JlcyByYXpvbmVzIGRlDQpvcG9ydHVuaWRhZGVzIGRlIHJvdGFjacOzbi4gQWRpY2lvbmFsbWVudGUsIGxvcyBlbXBsZWFkb3Mgc29sdGVyb3MNCnByZXNlbnRhcm9uIHVuYSBtYXlvciBwcm9iYWJpbGlkYWQgcmVsYXRpdmEgZGUgcm90YWNpw7NuIGZyZW50ZSBhIGxvcw0KY2FzYWRvcywgYXVucXVlIGVzdGEgY2FyYWN0ZXLDrXN0aWNhIGRlYmUgaW50ZXJwcmV0YXJzZSBkZSBmb3JtYSBhZ3JlZ2FkYQ0KeSBubyB1dGlsaXphcnNlIGNvbW8gdW4gY3JpdGVyaW8gYXV0w7Nub21vIHBhcmEgZGVjaXNpb25lcyBsYWJvcmFsZXMNCmluZGl2aWR1YWxlcy4NCg0KQ29uIGJhc2UgZW4gZXN0b3MgcmVzdWx0YWRvcywgc2UgcHJvcG9uZSB1bmEgZXN0cmF0ZWdpYSBpbnRlZ3JhbCBkZQ0KcmV0ZW5jacOzbiBjZW50cmFkYSBlbiBmYWN0b3JlcyBvcmdhbml6YWNpb25hbGVzIG1vZGlmaWNhYmxlcy4gRW4gcHJpbWVyDQpsdWdhciwgbGEgZW1wcmVzYSBkZWJlIG1vbml0b3JlYXIgeSByZWR1Y2lyIGxhIGV4cG9zaWNpw7NuIHNvc3RlbmlkYSBhDQpob3JhcyBleHRyYSBtZWRpYW50ZSB1bmEgbWVqb3IgZGlzdHJpYnVjacOzbiBkZSBjYXJnYXMsIHJldmlzacOzbiBkZQ0KZG90YWNpw7NuIGRlIHBlcnNvbmFsLCBjb21wZW5zYWNpw7NuIGFkZWN1YWRhIHkgbWVjYW5pc21vcyBkZQ0KZmxleGliaWxpZGFkLiBFbiBzZWd1bmRvIGx1Z2FyLCBzZSByZWNvbWllbmRhIGZvcnRhbGVjZXIgbGEgc2F0aXNmYWNjacOzbg0KbGFib3JhbCBtZWRpYW50ZSBtZWRpY2lvbmVzIHBlcmnDs2RpY2FzIGRlIGNsaW1hLCBlbnRyZXZpc3RhcyBkZQ0KcGVybWFuZW5jaWEsIHJlY29ub2NpbWllbnRvLCBmb3JtYWNpw7NuIGRlIGplZmF0dXJhcyB5IHBsYW5lcyBkZSBtZWpvcmENCnBvciBlcXVpcG8uIEVuIHRlcmNlciBsdWdhciwgZXMgbmVjZXNhcmlvIHJldmlzYXIgbGEgY29tcGV0aXRpdmlkYWQgeQ0KZXF1aWRhZCBkZSBsYSBjb21wZW5zYWNpw7NuIHRvdGFsLCBwYXJ0aWN1bGFybWVudGUgZW4gY2FyZ29zIG8gZ3J1cG9zIGNvbg0KbWF5b3Igcmllc2dvLg0KDQpGaW5hbG1lbnRlLCBjb252aWVuZSByZWZvcnphciBsb3MgcHJvY2Vzb3MgZGUgaW5kdWNjacOzbiwgbWVudG9yw61hLA0KZm9ybWFjacOzbiB5IGRlc2Fycm9sbG8gZGUgY2FycmVyYSBkdXJhbnRlIGxvcyBwcmltZXJvcyBhw7FvcyBlbiBlbCBjYXJnbywNCmRhZG8gcXVlIGxhIGFudGlnw7xlZGFkIHByZXNlbnRhIHVuYSBhc29jaWFjacOzbiBwcm90ZWN0b3JhIGZyZW50ZSBhIGxhDQpyb3RhY2nDs24uIEVsIG1vZGVsbyBwdWVkZSB1dGlsaXphcnNlIGNvbW8gdW5hIGhlcnJhbWllbnRhIGRlIGFsZXJ0YQ0KdGVtcHJhbmEuIEJham8gZWwgcHVudG8gZGUgY29ydGUgZGUgMCwxODYgc2VsZWNjaW9uYWRvIG1lZGlhbnRlIGVsDQrDrW5kaWNlIGRlIFlvdWRlbiwgbG9zIGVtcGxlYWRvcyBjb24gdW5hIHByb2JhYmlsaWRhZCBlc3RpbWFkYSBpZ3VhbCBvDQpzdXBlcmlvciBhIGRpY2hvIHZhbG9yIGRlYmVuIHNlciBwcmlvcml6YWRvcyBwYXJhIHVuYSBjb252ZXJzYWNpw7NuDQpwcmV2ZW50aXZhIHkgdW5hIGV2YWx1YWNpw7NuIGluZGl2aWR1YWwgZGUgc3VzIGNvbmRpY2lvbmVzIGRlIHRyYWJham8sDQpjYXJnYSBsYWJvcmFsLCBzYXRpc2ZhY2Npw7NuLCBkZXNhcnJvbGxvIHkgY29tcGVuc2FjacOzbi4gTm8gb2JzdGFudGUsIGxhcw0KcHJlZGljY2lvbmVzIGRlYmVuIGNvbXBsZW1lbnRhciwgeSBubyBzdXN0aXR1aXIsIGVsIGp1aWNpbyBwcm9mZXNpb25hbA0KZGUgbG9zIHJlc3BvbnNhYmxlcyBkZSBnZXN0acOzbiBodW1hbmE7IGFkZW3DoXMsIGxhcyB2YXJpYWJsZXMgcGVyc29uYWxlcywNCmNvbW8gZWwgZXN0YWRvIGNpdmlsIHkgbGEgZWRhZCwgbm8gZGViZW4gZW1wbGVhcnNlIGRlIGZvcm1hIGFpc2xhZGEgcGFyYQ0KdG9tYXIgZGVjaXNpb25lcyBhZHZlcnNhcyBvIGRpc2NyaW1pbmF0b3JpYXMuDQoNCiMgUmVmZXJlbmNpYXMNCg0KR3JpZmZldGgsIFIuIFcuLCBIb20sIFAuIFcuLCAmIEdhZXJ0bmVyLCBTLiAoMjAwMCkuIEEgbWV0YS1hbmFseXNpcyBvZg0KYW50ZWNlZGVudHMgYW5kIGNvcnJlbGF0ZXMgb2YgZW1wbG95ZWUgdHVybm92ZXI6IFVwZGF0ZSwgbW9kZXJhdG9yDQp0ZXN0cywgYW5kIHJlc2VhcmNoIGltcGxpY2F0aW9ucyBmb3IgdGhlIG5leHQgbWlsbGVubml1bS4gSm91cm5hbCBvZg0KTWFuYWdlbWVudCwgMjYoMyksIDQ2M+KAkzQ4OC4gPGh0dHBzOi8vZG9pLm9yZy8xMC4xMTc3LzAxNDkyMDYzMDAwMjYwMDMwNT4NCg0KQWxsZW4sIEQuIEcuLCBCcnlhbnQsIFAuIEMuLCAmIFZhcmRhbWFuLCBKLiBNLiAoMjAxMCkuIFJldGFpbmluZyB0YWxlbnQ6DQpSZXBsYWNpbmcgbWlzY29uY2VwdGlvbnMgd2l0aCBldmlkZW5jZS1iYXNlZCBzdHJhdGVnaWVzLiBBY2FkZW15IG9mDQpNYW5hZ2VtZW50IFBlcnNwZWN0aXZlcywgMjQoMiksIDQ44oCTNjQuDQo8aHR0cHM6Ly9kb2kub3JnLzEwLjU0NjUvQU1QLjIwMTAuNTE4Mjc3NzU+DQoNCkhvbSwgUC4gVy4sIExlZSwgVC4gVy4sIFNoYXcsIEouIEQuLCAmIEhhdXNrbmVjaHQsIEouIFAuICgyMDE3KS4gT25lDQpodW5kcmVkIHllYXJzIG9mIGVtcGxveWVlIHR1cm5vdmVyIHRoZW9yeSBhbmQgcmVzZWFyY2guIEpvdXJuYWwgb2YNCkFwcGxpZWQgUHN5Y2hvbG9neSwgMTAyKDMpLCA1MzDigJM1NDUuDQo8aHR0cHM6Ly9kb2kub3JnLzEwLjEwMzcvYXBsMDAwMDEwMz4NCg0KTW9ibGV5LCBXLiBILiAoMTk3NykuIEludGVybWVkaWF0ZSBsaW5rYWdlcyBpbiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4NCmpvYiBzYXRpc2ZhY3Rpb24gYW5kIGVtcGxveWVlIHR1cm5vdmVyLiBKb3VybmFsIG9mIEFwcGxpZWQgUHN5Y2hvbG9neSwNCjYyKDIpLCAyMzfigJMyNDAuDQoNCiMjIERlY2xhcmFjacOzbiBkZSB1c28gZGUgaW50ZWxpZ2VuY2lhIGFydGlmaWNpYWwNCg0KRW4gbGEgZWxhYm9yYWNpw7NuIGRlIGVzdGUgaW5mb3JtZSBzZSB1dGlsaXrDsyBBSSBjb21vIGhlcnJhbWllbnRhIGRlDQphcG95byBwYXJhIGxhIGVsYWJvcmFjacOzbiBkZSBjw7NkaWdvIGVuIFIgeSByZXZpc2nDs24gZGUgbGEgcHJlc2VudGFjacOzbg0KZGUgcmVzdWx0YWRvcy4NCg0KKipMYSBpbnRlbGlnZW5jaWEgYXJ0aWZpY2lhbCBubyBzdXN0aXR1ecOzIGVsIHRyYWJham8gYW5hbMOtdGljbyBkZSBsb3MNCmF1dG9yZXMuKiogTG9zIGRhdG9zLCBkZWZpbmljacOzbiBkZSB2YXJpYWJsZXMsIGRlcHVyYWNpw7NuLCBmaWx0cmFkbyBkZQ0Kb2JzZXJ2YWNpb25lcywgZWplY3VjacOzbiBkZSBsb3MgbW9kZWxvcywgb2J0ZW5jacOzbiBkZSByZXN1bHRhZG9zLA0KdmFsaWRhY2nDs24gZGUgc3VwdWVzdG9zLCBpbnRlcnByZXRhY2nDs24gZmluYWwgeSByZWNvbWVuZGFjaW9uZXMgZnVlcm9uDQpyZWFsaXphZGFzLCByZXZpc2FkYXMgeSB2ZXJpZmljYWRhcyBwb3IgbG9zIGF1dG9yZXMuDQoNCmxvcyBhdXRvcmVzIGFzdW1lbiBwbGVuYSByZXNwb25zYWJpbGlkYWQgcG9yIGxhIGV4YWN0aXR1ZCBkZSBsb3MNCmFuw6FsaXNpcywgbGEgdmVyaWZpY2FjacOzbiBkZSBsb3MgcmVzdWx0YWRvcyBnZW5lcmFkb3MgZW4gUiwgbGENCnV0aWxpemFjacOzbiBkZSBsYXMgZnVlbnRlcyB5IGVsIGNvbnRlbmlkbyBmaW5hbCBkZWwgZG9jdW1lbnRvLg0K