Planeación estratégica basada en analítica prescriptiva

Grupo 503

Profesor David Saucedo

Equipo 7:

A00833113 - Avril Lobato

Análisis Espacial y Temporal del Turismo en la Zona Metropolitana de Monterrey: Perspectivas Estratégicas para la Industria Hotelera y el Turismo de Negocios 2025–2026

Introducción

Contexto

La ZMM se ha consolidado como un polo estratégico para el turismo de negocios y entretenimiento en México. De acuerdo con la Secretaría de Turismo de Nuevo León, el estado recibió 4.1 millones de visitantes en 2021, una cifra que aumentó hasta alcanzar los 15 millones en 2024; generando una derrama económica de 17,721 millones de pesos. La ocupación hotelera alcanzó un promedio del 63.91%, con una tarifa promedio de $1,776.06 pesos.

El posicionamiento de Nuevo León como un hub de interconexión global, con vuelos directos a América Latina a través de Bogotá, a Asia mediante Tokio y Seúl, y a Europa con conexión a Madrid ha permitido que el Aeropuerto Internacional de Monterrey opere 64 destinos nacionales e internacionales, un crecimiento notable desde los 45 destinos registrados por la Secretaría de Turismo en 2021. A pesar de estos esfuerzos, el turismo en el estado sigue siendo predominantemente local, ya que el 86% de los visitantes provienen de otras partes de México (Secretaría de Turismo de Nuevo León. 2024).

Asimismo, Monterrey es un importante centro financiero y sede de convenciones, atrayendo viajeros corporativos. Por ello, el turismo de reuniones es un motor clave, con más de 250 eventos anuales, como congresos y exposiciones internacionales. Además, la región ha diversificado su oferta turística, impulsando segmentos como naturaleza y aventura, gastronomía, salud y cinematografía.

Dicho crecimiento acelerado junto con la participación de Nuevo León en eventos d egran nivel como el Mundial FIFA 2026 subrayan la necesidad de contar con indicadores robustos y mecanismos de análisis prospectivo que permitan anticipar riesgos. La volatilidad del entorno económico, los cambios en la movilidad nacional e internacional, así como la concentración de la demanda turística en ciertos segmentos, plantean desafíos para la sostenibilidad del crecimiento. Por ello, se vuelve crucial generar herramientas analíticas que faciliten la toma de decisiones estratégicas, minimicen vulnerabilidades y orienten políticas públicas más resilientes.

Desarrollo de Indicadores

Primer Indicador

Industria Hotelera: Llegada de Turistas Nacionales & Turistas Extranjeros

Variables de ocupación y habitaciones muy relacionadas con la derrama:

  • Turistas_Noche_Ext (noches de extranjeros) y Cuartos_Ocupados muestran correlaciones con la derrama de r ≈ 0.88 y r ≈ 0.86 respectivamente.

  • Llegada_Tur_Ext, Turistas_Noche_Nac y %Ocupacion_Hoteles también superan r ≈ 0.8.

Lo anterior confirma que a más ocupación y llegadas de turistas, mayor derrama.

df_log <- df_log[!is.na(df_log$"Derrama_Economica_Est_mdp"), ]

derrama_ts <- ts(df_log$"Derrama_Economica_Est_mdp", start = c(2004, 1), end = c(2024, 12), frequency = 12)
plot(derrama_ts, type = "l", col = "darkgreen", lwd = 2,
     xlab = "Año", ylab = "Derrama Económica",
     main = "Serie Temporal de Derrama_Economica_Est_mdp")

Meses de “temporada alta”

  • Abril (mes 4) y noviembre (mes 11) muestran las medianas más elevadas (alrededor de 750–800 mdp) y cuartiles superiores altos, lo que sugiere picos sistemáticos en primavera y justo antes de fin de año.

Meses de “temporada baja”

  • Enero (1) es el más bajo en mediana, con pocos outliers, reflejando el típico bajón tras la temporada navideña.

  • Septiembre (9) y febrero (2) también presentan medianas reducidas , posiblemente por vacaciones cortas o periodos de baja actividad turística.

boxplot(derrama_ts ~ cycle(derrama_ts),
        xlab = "Mes", ylab = "Derrama",
        main = "Estacionalidad mensual", col = "lightblue")

Pronóstico Llegada Turistas Nacionales

Un incremento sostenido del 50 % en las llegadas nacionales a partir de junio-2026 añadiría, en promedio, +46 mdp mensuales a la derrama hotelera durante el siguiente año, reduciendo a la mitad las caídas estacionales de diciembre y abril. Elevar el escenario al 75 % aportaría +15 mdp extra, pero con rendimientos decrecientes. Los meses de octubre y enero son los puntos de mayor sensibilidad: concentrar promociones en dichos momentos maximizaría el retorno por cada peso invertido en captar turistas nacionales. El coeficiente VAR de Llegada_Tur_Nac_diff es positivo, por ende, se calcula que:

  • Un alza del 25 % sólo ajusta la derrama mensual ±3 a 15 mdp según el signo de la serie (aliviana pérdidas, pero recorta leves ganancias).

  • Impacto proporcional: Junio-26: un +25 % / +50 % / +75 % en llegadas nacionales mejora la variación de derrama de -35 → -21 / -18 / -15 mdp

  • En meses con derrama positiva (p.ej. Jul-26 = 118 mdp), el aumento de turistas resta ~3-4 mdp al nivel registrado.

  • Incrementar 25-75 % las llegadas nacionales no genera saltos significativos: el rango completo de impacto está dentro de ±17 mdp mensuales.

  • Dic-26 y Abr-27 son los peores meses en el escenario real (-136 y -43 mdp). Con +50 % de turistas las caídas se recortan 19 % y 27 % respectivamente.

turistas_nacionales_ts <- ts(df_final$Llegada_Tur_Nac_diff, start = c(2015, 1), frequency = 12)
seasonplot(turistas_nacionales_ts, year.labels = TRUE, col = 1:20, main = "Estacionalidad por mes")

ts_decomp <- decompose(turistas_nacionales_ts)
plot(ts_decomp)

forecast_nacionales <- forecast::forecast(auto_nacionales, h = 30)

plot(forecast_nacionales,
     main = "Pronóstico Llegada de Turistas Nac para el Mundial 2026",
     ylab = "Llegadas de Turistas Nacionales",
     xlab = "Año")

# Extraer fechas a partir del último dato
fec_forecast <- function(ts_obj, h){
  ult <- end(ts_obj)                # c(año, mes) del último dato
  m_ini <- ifelse(ult[2] == 12, 1,  ult[2] + 1)
  a_ini <- ifelse(ult[2] == 12, ult[1] + 1, ult[1])
  seq(as.Date(sprintf("%d-%02d-01", a_ini, m_ini)),
      by = "1 month", length.out = h)
}

h<-30
fechas_nac<- fec_forecast(turistas_nacionales_ts,h)

# Creación del data frame con resultados
df_forecast <- data.frame(
  Fecha = fechas_nac,
  Pronostico = as.numeric(forecast_nacionales$mean),
  Lower80 = as.numeric(forecast_nacionales$lower[,1]),
  Upper80 = as.numeric(forecast_nacionales$upper[,1]),
  Lower95 = as.numeric(forecast_nacionales$lower[,2]),
  Upper95 = as.numeric(forecast_nacionales$upper[,2])
)


ggplot(df_forecast, aes(x = Fecha, y = Pronostico)) +
  geom_ribbon(aes(ymin = Lower95, ymax = Upper95), fill = "lightblue", alpha = 0.4) +
  geom_ribbon(aes(ymin = Lower80, ymax = Upper80), fill = "blue", alpha = 0.4) +
  geom_line(color = "darkblue", size = 1) +
  labs(title = "Pronóstico Llegada Turistas Nacionales hasta Mayo 2026",
       x = "Fecha", y = "Llegadas") +
  scale_x_date(date_labels = "%b-%Y", date_breaks = "2 months") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Pronóstico Llegada Turistas Extranjeros

El coeficiente de Llegada_Tur_Ext_diff en el VAR es negativo; por eso, al simular +25 % / +50 % / +75 % las curvas de color (rojo, verde, azul) se mueven ligeramente por debajo de la línea morada (Real) en casi todos los meses:

  • Dic-26 es el escenario más profundo (-154 mdp real). El aumento del 75 % de turistas ext. empeora la caída a -159 mdp: un ajuste -5 mdp adicional.

  • Ago-26 y Abr-27 muestran pequeños deterioros (-4 a -6 mdp) al comparar Real vs +75 %.

Para la derrama hotelera, un shock de turistas extranjeros no es rentable en el corto plazo bajo la estructura actual:

  • La elasticidad estimada es negativa y pequeña.

  • Incrementar flujos foráneos hasta +75 % apenas modifica la derrama (entre 0 y -6 mdp por mes).

turistas_ext_ts <- ts(df_final$Llegada_Tur_Ext_diff, start = c(2015, 1), frequency = 12)

seasonplot(turistas_ext_ts, year.labels = TRUE, col = 1:20, main = "Estacionalidad por mes")

ts_decomp_ext <- decompose(turistas_ext_ts)
plot(ts_decomp_ext)

forecast_extranjeros <- forecast::forecast(modelo_mejorado_log, h = 30)

plot(forecast_extranjeros,
     main = "Pronóstico Llegada de Turistas Extranjeros a un año del Mundial 2026",
     ylab = "Llegadas de Turistas Extranjeros",
     xlab = "Año")

sigma2 <- modelo_mejorado_log$sigma2      # varianza de los residuos
fc_exp <- forecast_extranjeros            # copia

fc_exp$mean   <- exp(forecast_extranjeros$mean + 0.5 * sigma2)
fc_exp$lower  <- exp(forecast_extranjeros$lower)
fc_exp$upper  <- exp(forecast_extranjeros$upper)
fc_exp$fitted <- exp(forecast_extranjeros$fitted)

fechas_ext<- fec_forecast(turistas_ext_ts,h)

df_forecast_ext <- data.frame(
  Fecha       = fechas_ext,
  Pronostico  = as.numeric(fc_exp$mean),
  Lower80     = as.numeric(fc_exp$lower[,1]),
  Upper80     = as.numeric(fc_exp$upper[,1]),
  Lower95     = as.numeric(fc_exp$lower[,2]),
  Upper95     = as.numeric(fc_exp$upper[,2])
)

library(ggplot2)

ggplot(df_forecast_ext, aes(x = Fecha, y = Pronostico)) +
  geom_ribbon(aes(ymin = Lower95, ymax = Upper95),
              fill = "lightblue", alpha = 0.4) +
  geom_ribbon(aes(ymin = Lower80, ymax = Upper80),
              fill = "skyblue",  alpha = 0.4) +
  geom_line(color = "darkblue", size = 1) +
  labs(title = "Pronóstico de Llegada de Turistas Extranjeros (escala original)",
       x = "Fecha", y = "Llegadas de turistas") +
  scale_x_date(date_labels = "%b-%Y", date_breaks = "2 months") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

PRONÓSTICO DERRAMA PARA VAR

El análisis prospectivo de la derrama económica asociada al turismo nacional revela un comportamiento fluctuante entre 2025 y 2027, con un crecimiento moderado en 2025 seguido de una marcada desaceleración y una severa contracción en los dos años posteriores, lo que subraya la necesidad de estrategias de mitigación y adaptación para enfrentar este escenario económico desafiante.

  • 2025: Se proyecta una derrama económica mensual promedio de 1,880 mdp, impulsada por el turismo nacional, la ocupación hotelera y la estadía promedio. Aunque positiva, el crecimiento es moderado, con un alza de solo +79 mdp por mes.

  • 2026: La derrama cae a 351 mdp mensuales en promedio, marcando una desaceleración significativa. El crecimiento se revierte, con una pérdida promedio de –169 mdp por mes.

  • 2027: Se anticipa una contracción severa, con un promedio mensual de –2,452 mdp. La caída se agrava mes a mes, con una reducción de –290 mdp, reflejando un declive económico preocupante.

forecast_derrama <- forecast::forecast(auto2_derrama, h = 30)

plot(forecast_derrama,
     main = "Pronóstico Derrama Ec. Hoteles haia el Mundial 2026",
     ylab = "Derrama Económica Hoteles",
     xlab = "Año")

fechas_derrama <- fec_forecast(derrama_timeseries, h)

df_forecast_derrama <- data.frame(
  Fecha = fechas_derrama,
  Pronostico = as.numeric(forecast_derrama$mean),
  Lower80 = as.numeric(forecast_derrama$lower[,1]),
  Upper80 = as.numeric(forecast_derrama$upper[,1]),
  Lower95 = as.numeric(forecast_derrama$lower[,2]),
  Upper95 = as.numeric(forecast_derrama$upper[,2])
)

ggplot(df_forecast_derrama, aes(x = Fecha, y = Pronostico)) +
  geom_ribbon(aes(ymin = Lower95, ymax = Upper95), fill = "lightgreen", alpha = 0.4) +
  geom_ribbon(aes(ymin = Lower80, ymax = Upper80), fill = "green", alpha = 0.4) +
  geom_line(color = "darkgreen", size = 1) +
  labs(title = "Pronóstico de Derrama Económica hasta Mayo 2026",
       x = "Fecha", y = "Derrama") +
  scale_x_date(date_labels = "%b-%Y", date_breaks = "2 months") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

ggplot(df_completo, aes(x = Fecha, y = Derrama, color = Escenario)) +
  geom_line(size = 1) +
  labs(title = "Serie histórica + escenarios de impacto",
       subtitle = "Impacto de aumento de turistas desde junio 2026",
       x = "Fecha", y = "Derrama Estimada (diff)") +
  scale_x_date(date_labels = "%b-%Y", date_breaks = "3 months") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Pronóstico Impacto de Llegada Turistas Extranjeros & Nacionales en Derrama

Se presentan escenarios de derrama económica estimada desde junio de 2026, comparando un valor base (denominado “Real”) con tres escenarios de incremento: 25%, 50% y 75%, con periodicidad mensual hasta junio de 2027.

Impactos en Turistas Nacionales

  • Julio 2026: Pico significativo en derrama económica para todos los escenarios, con el “Real” siendo el más alto.

  • Agosto-septiembre 2026: Caída abrupta de la derrama; el “Real” vuelve a diferenciarse marcadamente hacia abajo.

  • Octubre 2026 y enero 2027: Recuperaciones notorias, con el “Real” por encima de los escenarios de aumento.

  • Marzo-abril 2027: Se percibe una reversión: el escenario “Real” cae mientras los aumentos se mantienen relativamente estables.

library(tidyr)

df_tabla_long <- pivot_longer(
  df_tabla,
  cols = -Fecha,
  names_to = "Escenario",
  values_to = "Derrama"
)

ggplot(df_tabla_long, aes(x = Fecha, y = Derrama, color = Escenario)) +
  geom_line(size = 1.2) +
  labs(title = "Escenarios de derrama económica pronosticada con Incremento único en Turistas Nacionales",
       subtitle = "Desde junio 2026: base + aumento del 25%, 50% y 75%",
       x = "Fecha", y = "Derrama Estimada (diff)") +
  scale_x_date(date_labels = "%b-%Y", date_breaks = "1 month") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Impactos en Turistas Extranjeros

  • Alta estabilidad: A partir de junio de 2026, todos los escenarios crecen y decrecen de manera casi idéntica.

  • Picos y valles coincidentes: Todos los máximos y mínimos (julio, octubre, enero) son compartidos entre escenarios.

  • Escasa diferenciación: No hay una ventaja clara en los escenarios con aumento frente al “Real”, lo que podría reflejar supuestos conservadores o falta de sensibilidad en el modelo.

ggplot(df_completo_ext, aes(x = Fecha, y = Derrama, color = Escenario)) +
  geom_line(size = 1) +
  labs(title = "Serie histórica + escenarios de impacto",
       subtitle = "Impacto de aumento de turistas extranjeros desde junio 2026",
       x = "Fecha", y = "Derrama Estimada (diff)") +
  scale_x_date(date_labels = "%b-%Y", date_breaks = "3 months") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

df_tabla_ext <- df_impacto_ext[, c(
  "Fecha",
  "Derrama_Economica_Est_mdp_diff",  # Pronóstico base
  "Derrama_25",
  "Derrama_50",
  "Derrama_75"
)]

colnames(df_tabla_ext) <- c("Fecha", "Real", "Aumento_25", "Aumento_50", "Aumento_75")
df_tabla_ext
##          Fecha        Real  Aumento_25  Aumento_50  Aumento_75
## 138 2026-06-01  -35.501838  -39.032956  -39.739179  -40.445403
## 139 2026-07-01  117.642616  114.044209  113.324527  112.604846
## 140 2026-08-01   -3.354487   -6.889639   -7.596669   -8.303700
## 141 2026-09-01 -115.904502 -119.444804 -120.152865 -120.860926
## 142 2026-10-01   95.907766   92.392914   91.689944   90.986974
## 143 2026-11-01   68.347485   64.895798   64.205460   63.515123
## 144 2026-12-01 -153.577720 -157.146837 -157.860660 -158.574484
## 145 2027-01-01   -3.383341   -6.864210   -7.560384   -8.256558
## 146 2027-02-01   55.310428   51.776406   51.069602   50.362797
## 147 2027-03-01   68.337945   64.802780   64.095747   63.388714
## 148 2027-04-01  -41.829730  -45.343962  -46.046808  -46.749655
## 149 2027-05-01   -2.776601   -6.301542   -7.006530   -7.711518
## 150 2027-06-01  -12.697490  -16.228608  -16.934831  -17.641055
df_tabla_long_ext <- pivot_longer(
  df_tabla_ext,
  cols = -Fecha,
  names_to = "Escenario",
  values_to = "Derrama"
)

ggplot(df_tabla_long_ext, aes(x = Fecha, y = Derrama, color = Escenario)) +
  geom_line(size = 1.2) +
  labs(title = "Escenarios de derrama económica pronosticada con Incremento único en Turistas Extranjeros",
       subtitle = "Desde junio 2026: base + aumento del 25%, 50% y 75%",
       x = "Fecha", y = "Derrama Estimada (diff)") +
  scale_x_date(date_labels = "%b-%Y", date_breaks = "1 month") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Segundo Indicador

Industria Hotelera & Turismo de Negocios: Group Mix

En el contexto turístico de Nuevo León, donde se cuenta con demanda generada por eventos masivos como festivales musicales, congresos y partidos del Mundial 2026, resulta fundamental contar con métricas que permitan anticipar y optimizar la capacidad de respuesta del ecosistema hotelero. Uno de los indicadores clave propuestos es el Group Mix, que representa el porcentaje de reservas totales que provienen de grupos grandes (típicamente de 10 o más habitaciones), como delegaciones deportivas, convenciones, bodas o viajes corporativos.

Fórmula del KPI: Group Mix (%) = (Reservas del segmento grupal / Reservas totales) × 100

Relevancia:
Facilita la detección de eventos con alta concentración de grupos, lo que permite optimizar ingresos. Al identificar el peso del segmento grupal en diferentes periodos, se pueden ajustar tarifas, ofrecer paquetes promocionales o negociar alianzas con organizadores de eventos. Dicho indicador es útil no solo para hoteles, sino también para recintos, operadores turísticos y autoridades del clúster, al permitir una lectura coordinada de la demanda futura.

Estado Actual del KPI:
Usando como base las reservas generadas bajo los eventos de la OCV podemos visualizar el impacto que las conferencias u otros eventos del consorcio generan en la ocupación hotelera total de la ZMM. Durante el año pasado el índice ha promediado 4.4%. Lo que indica que el 4.4% de la ocupación hotelera proviene de los asistentes o stakeholders de la OCV.

df_OCV <- read.xlsx("Tabla_Macro_EventosOCV.xlsx")
kpi_df <- df_OCV %>%
  select("Año", "MesNombre", "Cuartos", "Cuartos_Ocupados")

kpi_df$Fecha <- as.Date(paste(kpi_df$Año, kpi_df$MesNombre, "01", sep = "-"))

kpi_df <- kpi_df %>%
  mutate(GroupMix = (Cuartos / Cuartos_Ocupados) * 100)

kpi_df %>%
  tail(48) %>%
  ggplot(aes(x = Fecha, y = GroupMix)) +
    geom_line(color = "steelblue") +
    geom_point(color = "steelblue") +
    geom_smooth(method = "lm", se = FALSE, color = "darkgrey", linetype = "dashed") +
    labs(title = "Tendencia de GroupMix", x = "Fecha", y = "GroupMix") +
   theme_minimal()

Rango Crítico:

groupmix_rangos <- data.frame(
  Rango = c("Riesgo", "Estable", "Oportunidad"),
  Desde = c(0, percentiles[1], percentiles[3]),
  Hasta = c(percentiles[1], percentiles[3], 100)
)

print(groupmix_rangos)
##           Rango Desde  Hasta
##          Riesgo  0.00   1.55
## 25%     Estable  1.55  11.31
## 75% Oportunidad 11.31 100.00

Interpretación

En los últimos tres meses del 2024 la métrica promedio 5.86%, dentro del rango Normal. Lo cual indica que a pesar de estar manteniendo el rendimiento común presenta la oportunidad de impulsar la atracción de eventos.

kpi_df <- subset(kpi_df, Fecha >= as.Date("2020-01-01"))

background_bands <- data.frame(
  ymin = c(0, percentiles[1], percentiles[3]),
  ymax = c(percentiles[1], percentiles[3], 100),
  fill = c("Riesgo", "Estable", "Oportunidad")
)

# Gráfico base con ggplot
g <- ggplot() +
  # Zonas de fondo
  geom_rect(data = background_bands,
            aes(xmin = min(kpi_df$Fecha), xmax = max(kpi_df$Fecha),
                ymin = ymin, ymax = ymax, fill = fill),
            alpha = 0.2) +
  # Línea de evolución del KPI
  geom_line(data = kpi_df, aes(x = Fecha, y = GroupMix), color = "#2c3e50", size = 1) +
  geom_point(data = kpi_df, aes(x = Fecha, y = GroupMix,
                                text = paste("Fecha:", Fecha,
                                             "<br>Group Mix:", round(GroupMix, 2), "%")),
             color = "#2980b9", size = 2) +
  # Líneas horizontales de referencia
  geom_hline(yintercept = percentiles[1], linetype = "dashed", color = "red") +
  geom_hline(yintercept = percentiles[2], linetype = "dashed", color = "orange") +
  geom_hline(yintercept = percentiles[3], linetype = "dashed", color = "green") +
  scale_fill_manual(values = c("Riesgo" = "red", "Estable" = "orange", "Oportunidad" = "green")) +
  labs(title = "Evolución del KPI Group Mix en la ZMM",
       subtitle = "Con rangos de interpretación: Riesgo, Estable, Oportunidad",
       x = "Fecha", y = "Group Mix (%)", fill = "Rango Crítico") +
  theme_minimal()

# Convertir a gráfico interactivo
plotly::ggplotly(g, tooltip = "text")
tabla_final <- data.frame(
  "Rango del KPI" = c("0% – 3.2%", "3.2% – 6.1%", ">6.1%"),
  Interpretación = c("Crítico / Riesgo", "Estable / Normal", "Oportunidad"),
  "Acción Estratégica" = c("Reforzar atracción de eventos grandes", "Mantener y monitorear relaciones OCV", "Promover inversiones en turismo de reuniones")
)

tabla_final
##   Rango.del.KPI   Interpretación                           Acción.Estratégica
## 1     0% – 3.2% Crítico / Riesgo        Reforzar atracción de eventos grandes
## 2   3.2% – 6.1% Estable / Normal         Mantener y monitorear relaciones OCV
## 3         >6.1%      Oportunidad Promover inversiones en turismo de reuniones

Tercer indicador

Industria Turismo de Negocios: Índice de Impacto del Turismo de Negocios (IITN)

Con base en lo anterior, se construye un KPI compuesto o índice agregador que concentre una visión sintética pero integral del impacto del Turismo de Negocios en la Zona Metropolitana de Monterrey (ZMM), especialmente considerando la cercanía de eventos como el Mundial FIFA 2026.

El Índice de Impacto del Turismo de Negocios (IITN) es un indicador compuesto que refleja el impacto total del turismo de negocios en la economía regional a partir de tres dimensiones clave:

  • Derrama Económica Generada: pondera el efecto monetario del turismo de negocios.

  • Participación de Ocupación Hotelera por Eventos de Negocios: mide la intensidad del turismo de negocios frente al turismo general.

  • Número y Escala de Eventos Realizados: captura la dinámica y volumen de la actividad.

Se observa que la raíz cuadrada aplicada a la derrama económica otorga mayor peso al componente económico, sin que este domine por completo. Por su parte, las raíces ponderadas de los otros dos indicadores capturan adecuadamente el dinamismo y el uso de infraestructura asociada al turismo de negocios.

Escala de Interpretación del IITN

  • Valor del IITN > 1.00
    • Nivel de Impacto: Alto impacto
    • Interpretación Estratégica: El turismo de negocios está superando metas estratégicas.
  • Valor del IITN entre 0.75 y 1.00
    • Nivel de Impacto: Impacto adecuado o esperado
    • Interpretación Estratégica: Se avanza conforme a lo proyectado; mantener estrategia actual.
  • Valor del IITN entre 0.50 y 0.74
    • Nivel de Impacto: Impacto moderado
    • Interpretación Estratégica: Requiere ajustes en promoción o logística de eventos.
  • Valor del IITN < 0.50
    • Nivel de Impacto: Bajo impacto
    • Interpretación Estratégica: Es necesario rediseñar la estrategia; subutilización de recursos.

Sin embargo, se observa que una meta fija implica que el KPI estará en constante aumento, por ende, se realizan alternativas de visualización del indicador con el fin de no solamente determinar un impacto

IITN mensual (no acumulado)

  • Mide el desempeño real de cada mes frente a las metas mensuales estimadas.

  • Ventaja: Detecta de inmediato si un mes está por debajo del objetivo.

  • Observación: Los primeros cuatro meses están por debajo de 0.50, a excepción de Febrero, el cual junto con Mayo, Agosto, Septiembre, Octubre y Noviembre alcanzan un impacto moderado.

IITN acumulado ajustado

  • Compara el acumulado real hasta el mes con el acumulado esperado.

  • Ventaja: Evalúa si vas adelantado o atrasado en el año.

  • Observación: El índice supera 1 a partir de marzo–abril, lo que indica que el desempeño acumulado ya va por delante del ritmo esperado.

Subindicadores individuales

  • Permiten aislar el análisis: saber si los avances son gracias a derrama, ocupación o eventos.

  • La derrama se comporta muy bien desde marzo.

  • La ocupación de cuartos por negocios está más estable y en algunos meses por debajo de 1.

  • Los eventos son clave para el crecimiento desde julio en adelante.

# df_OCV_numeric debe tener columnas: Año, Mes (número), Derrama
library(dplyr)
library(reshape2)
library(data.table)
library(tidyr)

# Filtrar años históricos (ej. 2020 a 2023)
df_hist <- df_OCV_numeric %>% filter(Año >= 2023 & Año <= 2024)

# Calcular derrama total por año
derrama_anual <- df_hist %>%
  group_by(Año) %>%
  summarise(Derrama_total_anual = sum(Derrama))

# Unir con el original para calcular proporción mensual
df_hist <- df_hist %>%
  left_join(derrama_anual, by = "Año") %>%
  mutate(Proporcion_mensual = Derrama / Derrama_total_anual)

# Promedio por mes entre años
pesos_estacionales <- df_hist %>%
  group_by(MesNombre) %>%
  summarise(Peso = mean(Proporcion_mensual)) %>%
  arrange(MesNombre)

# Vector de pesos (suma ≈ 1)
pesos_estacionales_vector <- pesos_estacionales$Peso
print(pesos_estacionales_vector)
##  [1] 0.009072928 0.056278612 0.059782285 0.107626317 0.050895092 0.052970227
##  [7] 0.102028056 0.107742556 0.101017732 0.140514859 0.182167924 0.029903412
# Calcular metas mensuales
pesos_estacionales <- c(
  0.009072928, 0.056278612, 0.059782285, 0.107626317,
  0.050895092, 0.052970227, 0.102028056, 0.107742556,
  0.101017732, 0.140514859, 0.182167924, 0.029903412
)

Meta_derrama_mensual <- Meta_derrama * pesos_estacionales
Meta_eventos_mensual <- Meta_eventos * pesos_estacionales

# Índice mensual NO acumulado
df_2024$IITN_mensual <- with(df_2024,
  (Derrama / Meta_derrama_mensual)^0.5 *
  (Cuartos / Cuartos_ocupados_mes)^0.25 *
  (Eventos / Meta_eventos_mensual)^0.25)

# Meta acumulada esperada por mes (lineal)
df_2024$Meta_derrama_acumulada <- Meta_derrama * (1:12)/12
df_2024$Meta_eventos_acumulados <- Meta_eventos * (1:12)/12

df_2024$IITN_t_ajustado <- with(df_2024,
  (Derrama_acumulada / Meta_derrama_acumulada)^0.5 *
  (Cuartos_acumulados / Cuartos_ocupados_mes)^0.25 *
  (Eventos_acumulados / Meta_eventos_acumulados)^0.25)

df_2024$Indicador_Derrama <- df_2024$Derrama / Meta_derrama_mensual
df_2024$Indicador_Cuartos <- df_2024$Cuartos / df_2024$Cuartos_ocupados_mes
df_2024$Indicador_Eventos <- df_2024$Eventos / Meta_eventos_mensual

# Gráficos

# IITN acumulado ajustado
ggplot(df_2024, aes(x = factor(MesNombre, levels = unique(MesNombre)), y = IITN_t_ajustado)) +
  geom_line(group = 1, color = "darkgreen", size = 1.2) +
  geom_point(size = 3, color = "darkgreen") +
  geom_hline(yintercept = 1, linetype = "dashed", color = "gray") +
  labs(title = "IITN Acumulado Ajustado por Mes",
       x = "Mes",
       y = "Índice IITN acumulado ajustado") +
  theme_minimal()

# Subindicadores
subindicadores <- df_2024[, c("MesNombre", "Indicador_Derrama", "Indicador_Eventos")]
subindicadores_largo <- pivot_longer(subindicadores, 
                                     cols = -MesNombre,
                                     names_to = "Indicador",
                                     values_to = "Valor")

ggplot(subindicadores_largo, aes(x = factor(MesNombre, levels = unique(MesNombre)),
                                 y = Valor, color = Indicador, group = Indicador)) +
  geom_line(size = 1.2) +
  geom_point(size = 3) +
  geom_hline(yintercept = 1, linetype = "dashed", color = "gray") +
  labs(title = "Subindicadores por Variable (Mensual)",
       x = "Mes",
       y = "Valor relativo a meta",
       color = "Indicador") +
  theme_minimal()

library(ggplot2)
library(dplyr)

# 1. IITN mensual
# Crear variable categórica de impacto según umbrales
df_2024 <- df_2024 %>%
  mutate(Nivel_Impacto = case_when(
    IITN_mensual > 1.00 ~ "Alto impacto",
    IITN_mensual >= 0.75 ~ "Impacto adecuado",
    IITN_mensual >= 0.50 ~ "Impacto moderado",
    TRUE ~ "Bajo impacto"
  ))

colores_impacto <- c(
  "Alto impacto" = "#1b9e77",
  "Impacto adecuado" = "#66a61e",
  "Impacto moderado" = "#e6ab02",
  "Bajo impacto" = "#d95f02"
)

# Crear data.frame para los rectángulos de fondo
fondos <- data.frame(
  ymin = c(0, 0.50, 0.75, 1.00),
  ymax = c(0.50, 0.75, 1.00, max(df_2024$IITN_mensual, na.rm = TRUE) + 0.1),
  fill = c("Bajo impacto", "Impacto moderado", "Impacto adecuado", "Alto impacto")
)

fondos$xmin <- -Inf
fondos$xmax <- Inf

ggplot(df_2024, aes(x = factor(MesNombre, levels = unique(MesNombre)), y = IITN_mensual)) +
  geom_rect(data = fondos, aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = fill),
            inherit.aes = FALSE, alpha = 0.15) +
  geom_line(group = 1, color = "black", size = 1.2) +
  geom_point(aes(color = Nivel_Impacto), size = 3) +
  scale_color_manual(values = colores_impacto) +
  scale_fill_manual(values = colores_impacto, guide = "none") +
  geom_hline(yintercept = 1, linetype = "dashed", color = "gray") +
  labs(title = "IITN Mensual (No Acumulado)",
       x = "Mes",
       y = "Índice IITN mensual",
       color = "Nivel de Impacto") +
  theme_minimal() +
  theme(legend.position = "bottom")

Riesgos para el Mundial FIFA 2026

A. Industria Hotelera

Riesgo Potencial: Saturación de la Capacidad y Volatilidad Tarifaria

Durante el Mundial de la FIFA la demanda hotelera suele dispararse de manera abrupta. En la ZMM, donde ya existe una alta concentración de oferta en zonas céntricas y de lujo (Monterrey y San Pedro), un incremento masivo de visitantes podría superar la capacidad actual, provocando:

  • Escasez de habitaciones disponibles para segmentos no relacionados al evento, con el consecuente riesgo de desplazamiento de clientes habituales.

  • Incrementos excesivos en las tarifas (price gouging), que, si bien generan ingresos adicionales en el corto plazo, pueden derivar en críticas mediáticas, quejas en plataformas de reseñas y daños a la reputación de la ciudad como destino.

Por consiguiente, con el objetivo de garantizar una experiencia turística equitativa y ordenada durante el periodo FIFA, se propone una estrategia enfocada en la transparencia tarifaria, la distribución eficiente de la demanda y la protección del consumidor. Se recomienda establecer un sistema de monitoreo dinámico en colaboración con plataformas como Booking o Expedia, que emitirá alertas cuando los precios superen umbrales predefinidos. Paralelamente, se lanzará una campaña de fomento al turismo nacional pre-FIFA, con paquetes promocionales para incentivar reservas anticipadas. Asimismo, para evitar la saturación de zonas premium, se impulsará la promoción de zonas hoteleras alternas como Apodaca, Guadalupe y Santa Catarina, apoyada en infraestructura y transporte. Finalmente, se establecerán alianzas con plataformas digitales para verificar hospedajes temporales, incorporando distintivos digitales de confianza que protejan a los visitantes de fraudes en línea.

Con base en las estrategias de mitigación planteadas, se propone utilizar el indicador de % Ocupación Hoteleraya sea utilizando tal cual el valor o realizando el siguiente cálculo: % = (Cuartos ocupados / Cuartos disponibles) × 100. Acorde a los gráficos, se observa que la ocupación hotelera mostró una tendencia fluctuante entre el 40% y 70%, con picos ocasionales superiores al 75%. Se identificó un patrón estacional semanal asociado posiblemente a fines de semana y temporadas vacacionales. Un evento disruptivo provocó una caída abrupta a niveles por debajo del 10%, seguido de una recuperación gradual que llevó la ocupación a estabilizarse nuevamente entre el 60% y 70%.

Se recomienda que a futuro se integre al valor una división ya sea por zona y/o por segmento. De esta manera, se identificarían los puntos de saturación o desequilibrio regional (ej. San Pedro vs Guadalupe).

library(ggplot2)
library(dplyr)

# Crear variable de fecha a partir de AÑO y MES
df <- df %>%
  mutate(Fecha = as.Date(paste(AÑO, MES, "01", sep = "-")))

# Gráfico de %Ocupacion_hoteles a través del tiempo
ggplot(df, aes(x = Fecha, y = `%Ocupacion_Hoteles`)) +
  geom_line(color = "steelblue", size = 1.2) +
  geom_point(color = "steelblue") +
  labs(title = "% de Ocupación Hotelera a lo largo del tiempo",
       x = "Fecha",
       y = "% Ocupación") +
  theme_minimal()

df$Ocupacion_Porc <- (df$Cuartos_Ocupados / df$Cuartos_Disponibles) * 100

ggplot(df, aes(x = Fecha, y = Ocupacion_Porc)) +
  geom_line(color = "steelblue", size = 1.2) +
  geom_point(color = "darkblue", size = 2) +
  labs(title = "% de Ocupación Hotelera a lo largo del tiempo",
       x = "Fecha",
       y = "% Ocupación") +
  theme_minimal() +
  scale_x_date(date_labels = "%b-%Y", date_breaks = "3 months") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

B. Industria Turismo de Negocios

Riesgo Potencial: Desvinculación entre Eventos FIFA y Eventos de Negocios

Existe la posibilidad de que los eventos organizados por FIFA en la ZMM, principalmente partidos y actividades deportivas, no se articulen de forma efectiva con la agenda de turismo de negocios (congresos, ferias, ruedas de inversión, networking empresarial), lo que resultaría en: * Subutilización de la infraestructura turística.

  • Baja captación de derrama económica por parte del sector empresarial local.

  • Pérdida de una ventana de oportunidad única para posicionar a Monterrey como destino MICE (Meetings, Incentives, Conferences, Exhibitions).

Lo anterior tiene el potencial de generar mayor impacto y probabilidad en riesgos como:

  • Menor afluencia de visitantes corporativos: Se traduce en una baja ocupación en hoteles orientados al segmento ejecutivo, lo cual afecta directamente la rentabilidad de la infraestructura diseñada para este tipo de turismo.

  • Afectación en economía local: La falta de visitantes de negocios implica una pérdida significativa de ingresos potenciales para sectores clave como la hospitalidad, el transporte y los servicios empresariales (B2B), limitando el dinamismo económico de la ciudad.

  • Bajo Posicionamiento de Monterrey: Al no aprovechar oportunidades para atraer grandes eventos internacionales, especialmente a partir de 2026, Monterrey pierde la posibilidad de posicionarse como un destino estratégico en el mapa global de congresos y convenciones.

  • Ineficiente Coordinación institucional: Existen problemas de duplicidad de esfuerzos entre distintas entidades, así como una dispersión de recursos y una calendarización ineficaz, lo que reduce la efectividad de las estrategias de promoción y atracción de eventos.

Por lo tanto, con el fin de mitigar los impactos negativos en el turismo de negocios y capitalizar las oportunidades que brinda el Mundial 2026, se propone una estrategia integral centrada en la coordinación público-privada y la planificación anticipada. La Mesa de Integración FIFA–OCV–Empresariado (2025) funcionará como plataforma colaborativa para alinear calendarios, sedes, públicos objetivos y paquetes integrados, evitando duplicidades y maximizando sinergias. Se diseñará un calendario complementario de eventos MICE, con al menos 12 meses de anticipación, que vincule temáticamente actividades empresariales con el Mundial, como congresos sobre innovación deportiva, turismo o smart cities. Además, se impulsarán ruedas de negocios y sesiones de networking en fechas cercanas a partidos de alto perfil, para atraer a líderes empresariales nacionales e internacionales. Se promoverá internacionalmente a Monterrey como sede del Mundial y hub de negocios, mediante una oferta integrada que combine partidos, eventos corporativos y hospedaje ejecutivo, atrayendo al turismo de negocios con una propuesta diferenciada. Con base en las estrategias de mitigación planteadas, se propone un KPI para dicho riesgo para medir qué porcentaje de los eventos de negocios (congresos, ferias, ruedas, etc.) están temáticamente o logísticamente integrados con el calendario FIFA 2026 en Monterrey.

Se estima que un valor ≥ 60% de los eventos MICE del primer semestre de 2026 deberían tener algún grado de vinculación con el Mundial (temática, sede, fechas, promoción conjunta, paquetes).

Acciones estratégicas enfocadas al Mundial FIFA 2026

Industria Hotelera

  • Establecer un acuerdo de tarifas máximas recomendadas con asociaciones hoteleras para evitar escaladas injustificadas.

  • Promover alojamientos alternativos certificados (Airbnb regulado, hostales de calidad) para diversificar la oferta y aliviar la presión sobre los hoteles tradicionales. Incluyendo la creación de un programa de sello de calidad para anfitriones de Airbnb y hostales, asegurando estándares mínimos de limpieza, atención y seguridad.

Industria Turismo de Negocios

Corto Plazo (2025 - 2026, pre y durante Mundial FIFA)

  • Alianzas OCV - FIFA - Gobierno Estatal: Desarrollar un calendario complementario de eventos de negocios en paralelo a partidos clave, integrando foros empresariales, expos temáticas y ruedas de inversión.

  • Integración de una Estrategia Binaria “Mundial + Turismo de Reuniones”: Usar hoteles, centros de convenciones y recintos deportivos para eventos duales (reuniones + entretenimiento).

Largo Plazo (2026 en adelante)

  • Legado FIFA para el turismo de negocios: Posicionar a Monterrey como sede internacional recurrente de congresos y eventos.

  • Clúster de turismo MICE (Meetings, Incentives, Conferences, Exhibitions): Formalizar una red local que articule a hoteles, agencias, gobierno, cámaras empresariales y universidades.

Conclusión

La analítica prescriptiva aplicada al turismo en la Zona Metropolitana de Monterrey destaca la importancia de contar con indicadores clave que permitan anticipar y gestionar la demanda turística, especialmente en un contexto de eventos de gran escala como el Mundial FIFA 2026. El monitoreo de la llegada de turistas nacionales se confirma como un KPI fundamental, cuyo impacto económico positivo está cuantificado mediante modelos estadísticos. Asimismo, el Group Mix revela la relevancia de los grupos grandes en la ocupación hotelera, ofreciendo oportunidades para optimizar ingresos y diseñar estrategias segmentadas. Por otra parte, el Índice de Impacto del Turismo de Negocios (IITN) permite evaluar el dinamismo y la efectividad de la agenda de eventos corporativos, evidenciando la necesidad de fortalecer la coordinación institucional y la planificación para evitar subutilización de infraestructura y maximizar la derrama económica. Frente a los riesgos asociados al Mundial 2026, se propone una serie de estrategias de mitigación centradas en la transparencia tarifaria, diversificación de la oferta hotelera y una integración efectiva entre eventos deportivos y de negocios. En conjunto, estos esfuerzos buscan posicionar a Monterrey como un destino turístico competitivo y sostenible, garantizando beneficios económicos amplios y un legado duradero para la región. Por ello, se presentan los insights de mayor relevancia:

  • La llegada de turistas nacionales genera una derrama económica significativa, estimada en +147.8 mdp por cada mil turistas adicionales, especialmente durante picos de actividad.

  • El porcentaje de reservas provenientes de grupos grandes (Group Mix) promedia 4.4%, lo que representa una oportunidad para diseñar paquetes y estrategias específicas para eventos masivos y corporativos.

  • El Índice de Impacto del Turismo de Negocios (IITN) ha mostrado volatilidad y un desempeño generalmente inferior al esperado, indicando la necesidad de mejorar la coordinación y promoción de eventos MICE.

  • Los riesgos de saturación hotelera y volatilidad tarifaria durante el Mundial FIFA 2026 pueden mitigarse mediante acuerdos de tarifas máximas, diversificación de la oferta y monitoreo dinámico con plataformas digitales.

  • La integración efectiva entre eventos deportivos y de negocios es crucial para maximizar la derrama económica y posicionar a Monterrey como un hub internacional de turismo MICE.

LS0tDQp0aXRsZTogIkV2aWRlbmNpYSAyIEFuYWzDrXRpY2EgUHJlc2NyaXB0aXZhOiBSZWNvbWVuZGFjaW9uZXMgRXN0cmF0w6lnaWNhcyBCYXNhZGFzIGVuIERhdG9zIg0Kc3VidGl0bGU6ICJFdmlkZW5jaWEgMDIiDQphdXRob3I6ICJFcXVpcG8gNyINCmRhdGU6ICIyMDI1LTAzLTI4Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICB0aGVtZTogY2VydWxlYW4NCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzDQotLS0NCg0KIVtdKGh0dHBzOi8vY2l0cmlzLXVjLm9yZy93cC1jb250ZW50L3VwbG9hZHMvMjAxOS8xMC9UZWMtZGUtTW9udGVycmV5LWxvZ28taG9yaXpvbnRhbC1ibHVlLnBuZykNCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyIj4NCiAgPHA+PHN0cm9uZz5QbGFuZWFjacOzbiBlc3RyYXTDqWdpY2EgYmFzYWRhIGVuIGFuYWzDrXRpY2EgcHJlc2NyaXB0aXZhPC9zdHJvbmc+PC9wPg0KICA8cD48c3Ryb25nPkdydXBvIDUwMzwvc3Ryb25nPjwvcD4NCiAgPHA+PHN0cm9uZz5Qcm9mZXNvciBEYXZpZCBTYXVjZWRvPC9zdHJvbmc+PC9wPg0KPC9kaXY+DQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlciI+DQogIDxwPjxzdHJvbmc+RXF1aXBvIDc6PC9zdHJvbmc+PC9wPg0KICA8cD5BMDA4MzMxMTMgLSBBdnJpbCBMb2JhdG88L3A+DQo8L2Rpdj4NCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoDQoJZWNobyA9IFRSVUUsDQoJbWVzc2FnZSA9IEZBTFNFLA0KCXdhcm5pbmcgPSBGQUxTRQ0KKQ0KI2luc3RhbGwucGFja2FnZXMoInJuYXR1cmFsZWFydGhoaXJlcyIsIHJlcG9zID0gImh0dHBzOi8vcGFja2FnZXMucm9wZW5zY2kub3JnIikNCiNpbnN0YWxsLnBhY2thZ2VzKCJkZXZ0b29scyIpDQpwYWNtYW46OnBfbG9hZChkcGx5ciwgZ2dwbG90MiwgY2FyLCB0c2VyaWVzLCBjb3JycGxvdCwgcGF0Y2h3b3JrLCByZWFkeGwsIHBzeWNoLCBtYXBzLCBNQVNTLCBBRVIsIHF1YW50bW9kLCBzdGF0cywgc2NhbGVzLCBkbG9va3IsIERhdGFFeHBsb3JlciwgdGlkeXIsIGtuaXRyLCBSQ29sb3JCcmV3ZXIsIHBsb3RseSwgZm9yZWNhc3QsIHRzZXJpZXMsIG9wZW54bHN4LCB2YXJzLCB0aWR5dmVyc2UsIGxtdGVzdCwgdXJjYSwgYVRTQSwgdGlkeXRleHQsIGdncGxvdDIsIG5hbmlhciwgdHNlcmllcywgY29ycnBsb3QsIHBhdGNod29yaywgcmVhZHhsLCBwc3ljaCwgbWFwcywgc2YsIHJuYXR1cmFsZWFydGgsIHJuYXR1cmFsZWFydGhkYXRhLCBzdHJpbmdpLCBzY2FsZXMsIGRsb29rciwgRGF0YUV4cGxvcmVyLCB0aWR5ciwga25pdHIsIFJDb2xvckJyZXdlciwgcGxvdGx5LCBmb3JlY2FzdCwgdHNlcmllcywgb3Blbnhsc3gsIHZhcnMsIGxtdGVzdCwgd29yZGNsb3VkLCB0ZXh0ZGF0YSwgZ3QsIGRwbHlyLCBnZ3Bsb3QyLCBuYW5pYXIsIHRzZXJpZXMsIGNvcnJwbG90LCBwYXRjaHdvcmssIHJlYWR4bCwgcHN5Y2gsIG1hcHMsIHNmLCBybmF0dXJhbGVhcnRoLCBybmF0dXJhbGVhcnRoZGF0YSwgc3RyaW5naSwgc2NhbGVzLCBkbG9va3IsIERhdGFFeHBsb3JlciwgdGlkeXIsIGtuaXRyLCBSQ29sb3JCcmV3ZXIsIHBsb3RseSwgZm9yZWNhc3QsIHRzZXJpZXMsIG9wZW54bHN4LCB2YXJzLCBsbXRlc3QpDQpgYGANCg0KDQojICoqQW7DoWxpc2lzIEVzcGFjaWFsIHkgVGVtcG9yYWwgZGVsIFR1cmlzbW8gZW4gbGEgWm9uYSBNZXRyb3BvbGl0YW5hIGRlIE1vbnRlcnJleTogUGVyc3BlY3RpdmFzIEVzdHJhdMOpZ2ljYXMgcGFyYSBsYSBJbmR1c3RyaWEgSG90ZWxlcmEgeSBlbCBUdXJpc21vIGRlIE5lZ29jaW9zIDIwMjXigJMyMDI2KioNCg0KIyMgKipJbnRyb2R1Y2Npw7NuKioNCg0KIyMjIENvbnRleHRvDQoNCkxhIFpNTSBzZSBoYSBjb25zb2xpZGFkbyBjb21vIHVuIHBvbG8gZXN0cmF0w6lnaWNvIHBhcmEgZWwgdHVyaXNtbyBkZSBuZWdvY2lvcyB5IGVudHJldGVuaW1pZW50byBlbiBNw6l4aWNvLiBEZSBhY3VlcmRvIGNvbiBsYSBTZWNyZXRhcsOtYSBkZSBUdXJpc21vIGRlIE51ZXZvIExlw7NuLCBlbCBlc3RhZG8gcmVjaWJpw7MgNC4xIG1pbGxvbmVzIGRlIHZpc2l0YW50ZXMgZW4gMjAyMSwgdW5hIGNpZnJhIHF1ZSBhdW1lbnTDsyAgaGFzdGEgYWxjYW56YXIgbG9zIDE1IG1pbGxvbmVzIGVuIDIwMjQ7IGdlbmVyYW5kbyB1bmEgZGVycmFtYSBlY29uw7NtaWNhIGRlIDE3LDcyMSBtaWxsb25lcyBkZSBwZXNvcy4gTGEgb2N1cGFjacOzbiBob3RlbGVyYSBhbGNhbnrDsyB1biBwcm9tZWRpbyBkZWwgNjMuOTElLCBjb24gdW5hIHRhcmlmYSBwcm9tZWRpbyBkZSAkMSw3NzYuMDYgcGVzb3MuDQoNCkVsIHBvc2ljaW9uYW1pZW50byBkZSBOdWV2byBMZcOzbiBjb21vIHVuIGh1YiAgZGUgaW50ZXJjb25leGnDs24gZ2xvYmFsLCBjb24gdnVlbG9zIGRpcmVjdG9zIGEgQW3DqXJpY2EgTGF0aW5hIGEgdHJhdsOpcyBkZSBCb2dvdMOhLCBhIEFzaWEgbWVkaWFudGUgVG9raW8geSBTZcO6bCwgeSBhIEV1cm9wYSBjb24gY29uZXhpw7NuIGEgTWFkcmlkIGhhIHBlcm1pdGlkbyBxdWUgZWwgQWVyb3B1ZXJ0byBJbnRlcm5hY2lvbmFsIGRlIE1vbnRlcnJleSBvcGVyZSA2NCBkZXN0aW5vcyBuYWNpb25hbGVzIGUgaW50ZXJuYWNpb25hbGVzLCB1biBjcmVjaW1pZW50byBub3RhYmxlIGRlc2RlIGxvcyA0NSBkZXN0aW5vcyByZWdpc3RyYWRvcyBwb3IgbGEgU2VjcmV0YXLDrWEgZGUgVHVyaXNtbyBlbiAyMDIxLiBBIHBlc2FyIGRlIGVzdG9zIGVzZnVlcnpvcywgZWwgdHVyaXNtbyBlbiBlbCBlc3RhZG8gc2lndWUgc2llbmRvIHByZWRvbWluYW50ZW1lbnRlIGxvY2FsLCB5YSBxdWUgZWwgODYlIGRlIGxvcyB2aXNpdGFudGVzIHByb3ZpZW5lbiBkZSBvdHJhcyBwYXJ0ZXMgZGUgTcOpeGljbyAoU2VjcmV0YXLDrWEgZGUgVHVyaXNtbyBkZSBOdWV2byBMZcOzbi4gMjAyNCkuDQoNCkFzaW1pc21vLCBNb250ZXJyZXkgZXMgdW4gaW1wb3J0YW50ZSBjZW50cm8gZmluYW5jaWVybyB5IHNlZGUgZGUgY29udmVuY2lvbmVzLCBhdHJheWVuZG8gdmlhamVyb3MgY29ycG9yYXRpdm9zLiBQb3IgZWxsbywgZWwgdHVyaXNtbyBkZSByZXVuaW9uZXMgZXMgdW4gbW90b3IgY2xhdmUsIGNvbiBtw6FzIGRlIDI1MCBldmVudG9zIGFudWFsZXMsIGNvbW8gY29uZ3Jlc29zIHkgZXhwb3NpY2lvbmVzIGludGVybmFjaW9uYWxlcy4gQWRlbcOhcywgbGEgcmVnacOzbiBoYSBkaXZlcnNpZmljYWRvIHN1IG9mZXJ0YSB0dXLDrXN0aWNhLCBpbXB1bHNhbmRvIHNlZ21lbnRvcyBjb21vIG5hdHVyYWxlemEgeSBhdmVudHVyYSwgZ2FzdHJvbm9tw61hLCBzYWx1ZCB5IGNpbmVtYXRvZ3JhZsOtYS4NCg0KRGljaG8gY3JlY2ltaWVudG8gYWNlbGVyYWRvIGp1bnRvIGNvbiBsYSBwYXJ0aWNpcGFjacOzbiBkZSBOdWV2byBMZcOzbiBlbiBldmVudG9zIGQgZWdyYW4gbml2ZWwgY29tbyBlbCBNdW5kaWFsIEZJRkEgMjAyNiBzdWJyYXlhbiBsYSBuZWNlc2lkYWQgZGUgY29udGFyIGNvbiBpbmRpY2Fkb3JlcyByb2J1c3RvcyB5IG1lY2FuaXNtb3MgZGUgYW7DoWxpc2lzIHByb3NwZWN0aXZvIHF1ZSBwZXJtaXRhbiBhbnRpY2lwYXIgcmllc2dvcy4gTGEgdm9sYXRpbGlkYWQgZGVsIGVudG9ybm8gZWNvbsOzbWljbywgbG9zIGNhbWJpb3MgZW4gbGEgbW92aWxpZGFkIG5hY2lvbmFsIGUgaW50ZXJuYWNpb25hbCwgYXPDrSBjb21vIGxhIGNvbmNlbnRyYWNpw7NuIGRlIGxhIGRlbWFuZGEgdHVyw61zdGljYSBlbiBjaWVydG9zIHNlZ21lbnRvcywgcGxhbnRlYW4gZGVzYWbDrW9zIHBhcmEgbGEgc29zdGVuaWJpbGlkYWQgZGVsIGNyZWNpbWllbnRvLiBQb3IgZWxsbywgc2UgdnVlbHZlIGNydWNpYWwgZ2VuZXJhciBoZXJyYW1pZW50YXMgYW5hbMOtdGljYXMgcXVlIGZhY2lsaXRlbiBsYSB0b21hIGRlIGRlY2lzaW9uZXMgZXN0cmF0w6lnaWNhcywgbWluaW1pY2VuIHZ1bG5lcmFiaWxpZGFkZXMgeSBvcmllbnRlbiBwb2zDrXRpY2FzIHDDumJsaWNhcyBtw6FzIHJlc2lsaWVudGVzLg0KDQoNCiMjICoqRGVzYXJyb2xsbyBkZSBJbmRpY2Fkb3JlcyoqDQoNCiMjIyBQcmltZXIgSW5kaWNhZG9yDQoNCioqSW5kdXN0cmlhIEhvdGVsZXJhOiBMbGVnYWRhIGRlIFR1cmlzdGFzIE5hY2lvbmFsZXMgJiBUdXJpc3RhcyBFeHRyYW5qZXJvcyoqIA0KDQpWYXJpYWJsZXMgZGUgb2N1cGFjacOzbiB5IGhhYml0YWNpb25lcyBtdXkgcmVsYWNpb25hZGFzIGNvbiBsYSBkZXJyYW1hOg0KDQoqIFR1cmlzdGFzX05vY2hlX0V4dCAobm9jaGVzIGRlIGV4dHJhbmplcm9zKSB5IEN1YXJ0b3NfT2N1cGFkb3MgbXVlc3RyYW4gY29ycmVsYWNpb25lcyBjb24gbGEgZGVycmFtYSBkZSByIOKJiCAwLjg4IHkgciDiiYggMC44NiByZXNwZWN0aXZhbWVudGUuDQoNCiogTGxlZ2FkYV9UdXJfRXh0LCBUdXJpc3Rhc19Ob2NoZV9OYWMgeSAlT2N1cGFjaW9uX0hvdGVsZXMgdGFtYmnDqW4gc3VwZXJhbiByIOKJiCAwLjguDQoNCkxvIGFudGVyaW9yIGNvbmZpcm1hIHF1ZSBhIG3DoXMgb2N1cGFjacOzbiB5IGxsZWdhZGFzIGRlIHR1cmlzdGFzLCBtYXlvciBkZXJyYW1hLg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShvcGVueGxzeCkNCmRmIDwtIHJlYWQueGxzeCgiSE9URUxFUy1CRC1GQ1NULnhsc3giLCBzaGVldCA9IkhPVEVMRVMiKQ0Ka2FibGUoaGVhZChkZikpDQpzdW0oaXMubmEoZGYpKQ0KZ2dfbWlzc192YXIoZGYpDQoNCmxpYnJhcnkoZHBseXIpDQpjb2xzX2xvZyA8LSBjKCAiQ3VhcnRvc19EaXNwb25pYmxlc19Qcm9tZWRpbyIsIA0KICAgICAgICAgICAgICAiRGVuc2lkYWRfT2N1cGFjacOzbiIsDQogICAgICAgICAgICAgICJFc3RhZGlhX1Byb21lZGlvIikNCg0KIyBDcmVhciBsYXMgY29sdW1uYXMgdHJhbnNmb3JtYWRhcyB5IGFncmVnYXJsYXMgYWwgZGF0YWZyYW1lIG9yaWdpbmFsDQpkZl9sb2cgPC0gZGYgJT4lDQogIG11dGF0ZShhY3Jvc3MoYWxsX29mKGNvbHNfbG9nKSwgfiBsb2coLiArIDEpLCAubmFtZXMgPSAiey5jb2x9X2xvZyIpKQ0KDQpkZl9sb2cgPC0gZGZfbG9nWywgIShuYW1lcyhkZl9sb2cpICVpbiUgY29sc19sb2cpXQ0KZGZfbnVtZXJpY28gPC0gZGZfbG9nW3NhcHBseShkZl9sb2csIGlzLm51bWVyaWMpXQ0KDQpgYGANCg0KYGBge3J9DQpkZl9sb2cgPC0gZGZfbG9nWyFpcy5uYShkZl9sb2ckIkRlcnJhbWFfRWNvbm9taWNhX0VzdF9tZHAiKSwgXQ0KDQpkZXJyYW1hX3RzIDwtIHRzKGRmX2xvZyQiRGVycmFtYV9FY29ub21pY2FfRXN0X21kcCIsIHN0YXJ0ID0gYygyMDA0LCAxKSwgZW5kID0gYygyMDI0LCAxMiksIGZyZXF1ZW5jeSA9IDEyKQ0KcGxvdChkZXJyYW1hX3RzLCB0eXBlID0gImwiLCBjb2wgPSAiZGFya2dyZWVuIiwgbHdkID0gMiwNCiAgICAgeGxhYiA9ICJBw7FvIiwgeWxhYiA9ICJEZXJyYW1hIEVjb27Ds21pY2EiLA0KICAgICBtYWluID0gIlNlcmllIFRlbXBvcmFsIGRlIERlcnJhbWFfRWNvbm9taWNhX0VzdF9tZHAiKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpkZWNvbXBvc2l0aW9uIDwtIGRlY29tcG9zZShkZXJyYW1hX3RzKQ0KcGxvdChkZWNvbXBvc2l0aW9uKQ0KDQpkZXNjb21wX3N0bCA8LSBzdGwoZGVycmFtYV90cywgcy53aW5kb3cgPSAicGVyaW9kaWMiKQ0KcGxvdChkZXNjb21wX3N0bCkNCmBgYA0KDQoqKk1lc2VzIGRlIOKAnHRlbXBvcmFkYSBhbHRh4oCdKioNCg0KKiBBYnJpbCAobWVzIDQpIHkgbm92aWVtYnJlIChtZXMgMTEpIG11ZXN0cmFuIGxhcyBtZWRpYW5hcyBtw6FzIGVsZXZhZGFzIChhbHJlZGVkb3IgZGUgNzUw4oCTODAwIG1kcCkgeSBjdWFydGlsZXMgc3VwZXJpb3JlcyBhbHRvcywgbG8gcXVlIHN1Z2llcmUgcGljb3Mgc2lzdGVtw6F0aWNvcyBlbiBwcmltYXZlcmEgeSBqdXN0byBhbnRlcyBkZSBmaW4gZGUgYcOxby4NCg0KKipNZXNlcyBkZSDigJx0ZW1wb3JhZGEgYmFqYeKAnSoqDQoNCiogRW5lcm8gKDEpIGVzIGVsIG3DoXMgYmFqbyBlbiBtZWRpYW5hLCBjb24gcG9jb3Mgb3V0bGllcnMsIHJlZmxlamFuZG8gZWwgdMOtcGljbyBiYWrDs24gdHJhcyBsYSB0ZW1wb3JhZGEgbmF2aWRlw7FhLg0KDQoqIFNlcHRpZW1icmUgKDkpIHkgZmVicmVybyAoMikgdGFtYmnDqW4gcHJlc2VudGFuIG1lZGlhbmFzIHJlZHVjaWRhcyAsIHBvc2libGVtZW50ZSBwb3IgdmFjYWNpb25lcyBjb3J0YXMgbyBwZXJpb2RvcyBkZSBiYWphIGFjdGl2aWRhZCB0dXLDrXN0aWNhLg0KDQpgYGB7cn0NCmJveHBsb3QoZGVycmFtYV90cyB+IGN5Y2xlKGRlcnJhbWFfdHMpLA0KICAgICAgICB4bGFiID0gIk1lcyIsIHlsYWIgPSAiRGVycmFtYSIsDQogICAgICAgIG1haW4gPSAiRXN0YWNpb25hbGlkYWQgbWVuc3VhbCIsIGNvbCA9ICJsaWdodGJsdWUiKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojIEF1dG9jb3JyZWxhY2nDs24geSBhdXRvY29ycmVsYWNpw7NuIHBhcmNpYWwNCmFjZihkZXJyYW1hX3RzLCBtYWluPSJBdXRvY29ycmVsYXRpb24gLSBEZXJyYW1hIEVjb27Ds21pY2EiKQ0KcGFjZihkZXJyYW1hX3RzLCBtYWluPSJQYXJ0aWFsIEF1dG9jb3JyZWxhdGlvbiAtRGVycmFtYSBFY29uw7NtaWNhIikgI2FwbGljYXIgMSBvIDINCmFkZl9vY3VwYWNpb24gPC0gYWRmLnRlc3QoZGZfbG9nJCJEZXJyYW1hX0Vjb25vbWljYV9Fc3RfbWRwIikNCnByaW50KGFkZl9vY3VwYWNpb24pDQojIEF1Y290b3JyZWxhY2nDs24gc2VyaWFsDQpsZ3Vual9ib3hfcmVzdWx0IDwtIEJveC50ZXN0KGRlcnJhbWFfdHMsIGxhZyA9IDUsIHR5cGUgPSAiTGp1bmctQm94IikNCmxndW5qX2JveF9yZXN1bHQNCmBgYA0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpkZXJyYW1hX2RpZmYgPC0gZGlmZihkZXJyYW1hX3RzKSAjIERpZmVyZW5jaWEgKGQgPSAxKQ0KYWRmLnRlc3QoZGVycmFtYV9kaWZmKSAjWWEgZXMgZXN0YWNpb25hcmlhLCBwb3IgZW5kZSBubyBzZSBhcGxpY2EgZA0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQptb2QxIDwtIGFyaW1hKGRlcnJhbWFfZGlmZiwgb3JkZXIgPSBjKDEsIDAsIDApKSAgIyAgZCA9IDAgcG9ycXVlIHlhIGxhIHNlcmllIGVzdMOhIGRpZmVyZW5jaWFkYQ0Kc3VtbWFyeShtb2QxKSAjcC12YWx1ZSA9IDIuMmUtMTYg4oaSIG11eSBtZW5vciBhIDAuMDUsIGxvcyByZXNpZHVvcyBubyBzZSBjb21wb3J0YW4gY29tbyBydWlkbyBibGFuY28g4oaSIGVsIG1vZGVsbyBubyBlc3TDoSBjYXB0dXJhbmRvIGNvbXBsZXRhbWVudGUgbGEgZXN0cnVjdHVyYSBkZSBsYSBzZXJpZS4NCmNoZWNrcmVzaWR1YWxzKG1vZDEpDQojYXIxLT4gY29lZmljaWVudGUgYmFqbywgbG8gcXVlIHN1Z2llcmUgdW5hIGTDqWJpbCBhdXRvY29ycmVsYWNpw7NuIHRlbXBvcmFsIGRpcmVjdGEuDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCm1vZGVsb19hdXRvIDwtIGF1dG8uYXJpbWEoZGVycmFtYV90cykNCnN1bW1hcnkobW9kZWxvX2F1dG8pDQpjaGVja3Jlc2lkdWFscyhtb2RlbG9fYXV0bykNCiNwLXZhbHVlID0gMC4wMDQ0ODQg4oaSIG1lbm9yIGEgMC4wNSwgbG8gcXVlIGluZGljYSBwcmVzZW5jaWEgZGUgYXV0b2NvcnJlbGFjacOzbiBlbiBsb3MgcmVzaWR1b3MNCiNObyBjYXB0dXJhIHRhbiBiaWVuIGxhIGVzdGFjaW9uYWxpZGFkDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkoZm9yZWNhc3QpDQoNCiMgTGlzdGEgcGFyYSBndWFyZGFyIHJlc3VsdGFkb3MNCnJlc3VsdGFkb3MgPC0gbGlzdCgpDQptb2RlbG9zX3ZhbGlkb3MgPC0gZGF0YS5mcmFtZSgpDQoNCiMgUmFuZ29zIGRlIHBhcsOhbWV0cm9zIChhanVzdGFyIHNpIHF1ZXJlbW9zICBtw6FzIG8gbWVub3MgY29tYmluYWNpb25lcykNCmZvciAocCBpbiAwOjIpIHsNCiAgZm9yIChkIGluIDE6MSkgew0KICAgIGZvciAocSBpbiAwOjIpIHsNCiAgICAgIGZvciAoUCBpbiAwOjIpIHsNCiAgICAgICAgZm9yIChEIGluIDA6MSkgew0KICAgICAgICAgIGZvciAoUSBpbiAwOjIpIHsNCiAgICAgICAgICAgIG9yZGVuIDwtIGMocCwgZCwgcSkNCiAgICAgICAgICAgIG9yZGVuX2VzdGFjaW9uYWwgPC0gYyhQLCBELCBRKQ0KICAgICAgICAgICAgdHJ5KHsNCiAgICAgICAgICAgICAgbW9kZWxvIDwtIGFyaW1hKGRlcnJhbWFfdHMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IG9yZGVuLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vhc29uYWwgPSBsaXN0KG9yZGVyID0gb3JkZW5fZXN0YWNpb25hbCwgcGVyaW9kID0gMTIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gIk1MIikNCiAgICAgICAgICAgICAgYWljX3ZhbCA8LSBBSUMobW9kZWxvKQ0KICAgICAgICAgICAgICBtb2RlbG9zX3ZhbGlkb3MgPC0gcmJpbmQobW9kZWxvc192YWxpZG9zLCBkYXRhLmZyYW1lKA0KICAgICAgICAgICAgICAgIHAsIGQsIHEsIFAsIEQsIFEsDQogICAgICAgICAgICAgICAgQUlDID0gYWljX3ZhbA0KICAgICAgICAgICAgICApKQ0KICAgICAgICAgICAgICBrZXkgPC0gcGFzdGUwKCIoIiwgcCwgIiwiLCBkLCAiLCIsIHEsICIpKCIsIFAsICIsIiwgRCwgIiwiLCBRLCAiKVsxMl0iKQ0KICAgICAgICAgICAgICByZXN1bHRhZG9zW1trZXldXSA8LSBtb2RlbG8gfSwgc2lsZW50ID0gVFJVRSl9fX19fX0NCg0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojIE9yZGVuYXIgcG9yIEFJQw0KbW9kZWxvc192YWxpZG9zIDwtIG1vZGVsb3NfdmFsaWRvc1tvcmRlcihtb2RlbG9zX3ZhbGlkb3MkQUlDKSwgXQ0KaGVhZChtb2RlbG9zX3ZhbGlkb3MsIDUpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCm1vZF9zdWdlcmlkbyA8LSBhcmltYShkZXJyYW1hX3RzLCBvcmRlciA9IGMoMiwxLDIpLCBzZWFzb25hbCA9IGxpc3Qob3JkZXIgPSBjKDAsMSwxKSwgcGVyaW9kID0gMTIpLCB0cmFuc2Zvcm0ucGFycyA9IEZBTFNFKQ0Kc3VtbWFyeShtb2Rfc3VnZXJpZG8pDQpjaGVja3Jlc2lkdWFscyhtb2Rfc3VnZXJpZG8pDQoNCiNManVuZy1Cb3g6DQojcC12YWx1ZSA9IDAuMTY4NSA+IDAuMDUg4oaSIG5vIGhheSBhdXRvY29ycmVsYWNpw7NuIHNpZ25pZmljYXRpdmEgZW4gbG9zIHJlc2lkdW9zLg0KIyBCdWVuIGluZGljaW8gZGUgcXVlIGVsIG1vZGVsbyBjYXB0YSBiaWVuIGxhIGVzdHJ1Y3R1cmEgZGUgbGEgc2VyaWUNCiNDYXB0dXJhIGFkZWN1YWRhbWVudGUgbGEgdGVuZGVuY2lhIHkgZXN0YWNpb25hbGlkYWQuDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCnZhcmlhYmxlc19sb2cgPC0gYyggIk1FUyIsICJBw5FPIiwNCiJDdWFydG9zX0Rpc3BvbmlibGVzIiwgIkN1YXJ0b3NfT2N1cGFkb3MiLCAiQ3VhcnRvc19SZWdpc3RyYWRvcyIsICJEZXJyYW1hX0Vjb25vbWljYV9Fc3RfbWRwIiwgICJJbXBfSG9zcGVkYWplIiwgIlR1cmlzdGFzX05vY2hlX0V4dCIsICJUdXJpc3Rhc19Ob2NoZV9OYWMiLCAiJU9jdXBhY2lvbl9Ib3RlbGVzIiwgICJMbGVnYWRhX1R1cl9FeHQiLCAiTGxlZ2FkYV9UdXJfTmFjIiwgIkN1YXJ0b3NfRGlzcG9uaWJsZXNfUHJvbWVkaW9fbG9nIiwgIkRlbnNpZGFkX09jdXBhY2nDs25fbG9nIiwgICJFc3RhZGlhX1Byb21lZGlvX2xvZyIgICAgICAgICAgDQopDQoNCnZhcmlhYmxlc19sb2cgPC0gc2V0ZGlmZih2YXJpYWJsZXNfbG9nLCBjKCJJbXBfSG9zcGVkYWplIiwgIk1FUyIsICJBw5FPIikpDQoNCg0KZm9yICh2YXIgaW4gdmFyaWFibGVzX2xvZykgew0KICBjYXQoIlxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIpDQogIGNhdCgiQURGIHRlc3QgZm9yOiIsIHZhciwgIlxuIikNCiAgc2VyaWUgPC0gdHMoZGZfbG9nW1t2YXJdXSwgc3RhcnQgPSBjKDIwMDQsIDEpLCBmcmVxdWVuY3kgPSAxMikNCiAgcHJpbnQoYWRmLnRlc3Qoc2VyaWUpKQ0KfQ0KDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkodHNlcmllcykNCg0Kc2VyaWVzX2RpZmVyZW5jaWFkYXMgPC0gbGlzdCgpDQoNCmZvciAodmFyIGluIHZhcmlhYmxlc19sb2cpIHsNCiAgY2F0KCJQcm9jZXNhbmRvIHZhcmlhYmxlOiIsIHZhciwgIlxuIikNCiAgDQogIHNlcmllIDwtIHRzKGRmX2xvZ1tbdmFyXV0sIHN0YXJ0ID0gYygyMDA0LCAxKSwgZnJlcXVlbmN5ID0gMTIpDQogIA0KICBhZGZfcmVzdWx0IDwtIHRyeUNhdGNoKHsNCiAgICB0ZXN0IDwtIHRzZXJpZXM6OmFkZi50ZXN0KHNlcmllKSAgIyBhc2Vnw7pyYXRlIHF1ZSBlcyBlbCBkZSB0c2VyaWVzDQogICAgdGVzdA0KICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsNCiAgICBjYXQoIkVycm9yIGNvbiBBREYgZGUiLCB2YXIsICI6IiwgZSRtZXNzYWdlLCAiXG4iKQ0KICAgIHJldHVybihOVUxMKQ0KICB9KQ0KICANCiAgaWYgKCFpcy5udWxsKGFkZl9yZXN1bHQpICYmICFpcy5uYShhZGZfcmVzdWx0JHAudmFsdWUpKSB7DQogICAgaWYgKGFkZl9yZXN1bHQkcC52YWx1ZSA+IDAuMDUpIHsNCiAgICAgIGNhdCgi4oaSIE5vIGVzdGFjaW9uYXJpYS4gU2UgZGlmZXJlbmNpYToiLCB2YXIsICJcbiIpDQogICAgICBzZXJpZV9kaWZmIDwtIGRpZmYoc2VyaWUpDQogICAgICBzZXJpZXNfZGlmZXJlbmNpYWRhc1tbcGFzdGUwKHZhciwgIl9kaWZmIildXSA8LSBzZXJpZV9kaWZmDQogICAgfSBlbHNlIHsNCiAgICAgIGNhdCgi4oaSIEVzdGFjaW9uYXJpYS4gU2UgY29uc2VydmE6IiwgdmFyLCAiXG4iKQ0KICAgICAgIyBSZWNvcnRhbW9zIGxhIHNlcmllIGEgcGFydGlyIGRlbCBzZWd1bmRvIG1lcyBwYXJhIHRlbmVyIG1pc21hIGxvbmdpdHVkIHF1ZSBkaWZmKCkNCiAgICAgIHNlcmllc19kaWZlcmVuY2lhZGFzW1t2YXJdXSA8LSB3aW5kb3coc2VyaWUsIHN0YXJ0ID0gYygyMDA0LCAyKSkNCiAgICB9DQogIH0gZWxzZSB7DQogICAgY2F0KCLihpIgTm8gc2UgcHVkbyBldmFsdWFyIEFERiBwYXJhIiwgdmFyLCAiXG4iKQ0KICB9DQp9DQpgYGANCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KIyBBcGxpY2FyIGxhIHBydWViYSBBREYgYSB0b2RhcyBsYXMgc2VyaWVzIGRpZmVyZW5jaWFkYXMNCmZvciAobm9tYnJlIGluIG5hbWVzKHNlcmllc19kaWZlcmVuY2lhZGFzKSkgew0KICBjYXQoIlxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIpDQogIGNhdCgiQURGIHRlc3QgZm9yOiIsIG5vbWJyZSwgIlxuIikNCiAgcHJpbnQoYWRmLnRlc3Qoc2VyaWVzX2RpZmVyZW5jaWFkYXNbW25vbWJyZV1dKSkNCn0NCmBgYA0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpkZl9sb2dbMiwgXQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpkZl9kaWZmIDwtIGFzLmRhdGEuZnJhbWUoc2VyaWVzX2RpZmVyZW5jaWFkYXMpDQpkZl9kaWZmWzEsIF0NCmBgYA0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCiMgMS4gTWFudGVuZXIgc29sbyBNRVMgeSBBw5FPIGRlIGRmX2xvZyAocmVjb3J0YWRvKQ0KZGZfbG9nMiA8LSBkZl9sb2dbLTEsIGMoIk1FUyIsICJBw5FPIiwgIkRlbnNpZGFkX09jdXBhY2nDs25fbG9nIildDQoNCiMgMi4gRWxpbWluYXIgZGUgZGZfZGlmZiBsYXMgY29sdW1uYXMgcXVlIHlhIGV4aXN0ZW4gZW4gZGZfbG9nMg0KY29sc19leGlzdGVudGVzIDwtIGludGVyc2VjdChuYW1lcyhkZl9sb2cyKSwgbmFtZXMoZGZfZGlmZikpDQpkZl9kaWZmX2ZpbHRyYWRvIDwtIGRmX2RpZmZbLCAhKG5hbWVzKGRmX2RpZmYpICVpbiUgY29sc19leGlzdGVudGVzKV0NCg0KIyAzLiBVbmlyIE1FUywgQcORTyB5IGxhcyBzZXJpZXMgZGlmZXJlbmNpYWRhcw0KZGZfZmluYWwgPC0gYmluZF9jb2xzKGRmX2xvZzIsIGRmX2RpZmZfZmlsdHJhZG8pDQpjb2xuYW1lcyhkZl9maW5hbCkNCmBgYA0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpkZl9maW5hbCA8LSBkZl9maW5hbFtkZl9maW5hbCRBw5FPID49IDIwMTUsIF0NCmBgYA0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpjb3JyZWxhY2lvbmVzIDwtIGNvcihkZl9maW5hbCwgdXNlID0gImNvbXBsZXRlLm9icyIpDQpyb3VuZChjb3JyZWxhY2lvbmVzLCAyKSAgIyBwYXJhIHZlciBtZWpvciBsb3MgdmFsb3Jlcw0KY29ycnBsb3QoY29ycmVsYWNpb25lcywgbWV0aG9kID0gImNvbG9yIiwgdHlwZSA9ICJ1cHBlciIsIHRsLmNleCA9IDAuNykNCmBgYA0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KGNhcmV0KQ0KDQojIERldGVjdGFyIGNvbHVtbmFzIGNvbiBhbHRhIGNvcnJlbGFjacOzbg0KY29yX21hdHJpeiA8LSBjb3IoZGZfZmluYWwsIHVzZSA9ICJjb21wbGV0ZS5vYnMiKQ0KY29sdW1uYXNfYV9yZW1vdmVyIDwtIGZpbmRDb3JyZWxhdGlvbihjb3JfbWF0cml6LCBjdXRvZmYgPSAwLjkpDQoNCiMgVmVyIG5vbWJyZXMgZGUgY29sdW1uYXMgYWx0YW1lbnRlIGNvcnJlbGFjaW9uYWRhcw0KbmFtZXMoZGZfZmluYWwpW2NvbHVtbmFzX2FfcmVtb3Zlcl0NCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0Kc3VtKGlzLm5hKGRmX2ZpbmFsJERlcnJhbWFfRWNvbsOzbWljYV9Fc3RfbWRwX2RpZmYpKQ0Kd2hpY2goaXMubmEoZGZfZmluYWwkRGVycmFtYV9FY29uw7NtaWNhX0VzdF9tZHBfZGlmZikpDQpgYGANCg0KIyMjIyBQcm9uw7NzdGljbyBMbGVnYWRhIFR1cmlzdGFzIE5hY2lvbmFsZXMNCg0KVW4gaW5jcmVtZW50byBzb3N0ZW5pZG8gZGVsIDUwICUgZW4gbGFzIGxsZWdhZGFzIG5hY2lvbmFsZXMgYSBwYXJ0aXIgZGUganVuaW8tMjAyNiBhw7FhZGlyw61hLCBlbiBwcm9tZWRpbywgKzQ2IG1kcCBtZW5zdWFsZXMgYSBsYSBkZXJyYW1hIGhvdGVsZXJhIGR1cmFudGUgZWwgc2lndWllbnRlIGHDsW8sIHJlZHVjaWVuZG8gYSBsYSBtaXRhZCBsYXMgY2HDrWRhcyBlc3RhY2lvbmFsZXMgZGUgZGljaWVtYnJlIHkgYWJyaWwuIEVsZXZhciBlbCBlc2NlbmFyaW8gYWwgNzUgJSBhcG9ydGFyw61hICsxNSBtZHAgZXh0cmEsIHBlcm8gY29uIHJlbmRpbWllbnRvcyBkZWNyZWNpZW50ZXMuIExvcyBtZXNlcyBkZSBvY3R1YnJlIHkgZW5lcm8gc29uIGxvcyBwdW50b3MgZGUgbWF5b3Igc2Vuc2liaWxpZGFkOiBjb25jZW50cmFyIHByb21vY2lvbmVzIGVuIGRpY2hvcyBtb21lbnRvcyBtYXhpbWl6YXLDrWEgZWwgcmV0b3JubyBwb3IgY2FkYSBwZXNvIGludmVydGlkbyBlbiBjYXB0YXIgdHVyaXN0YXMgbmFjaW9uYWxlcy4gRWwgY29lZmljaWVudGUgVkFSIGRlIExsZWdhZGFfVHVyX05hY19kaWZmIGVzIHBvc2l0aXZvLCBwb3IgZW5kZSwgc2UgY2FsY3VsYSBxdWU6DQoNCiogVW4gYWx6YSBkZWwgMjUgJSBzw7NsbyBhanVzdGEgbGEgZGVycmFtYSBtZW5zdWFsIMKxMyBhIDE1IG1kcCBzZWfDum4gZWwgc2lnbm8gZGUgbGEgc2VyaWUgKGFsaXZpYW5hIHDDqXJkaWRhcywgcGVybyByZWNvcnRhIGxldmVzIGdhbmFuY2lhcykuDQoNCiogSW1wYWN0byBwcm9wb3JjaW9uYWw6IEp1bmlvLTI2OiB1biArMjUgJSAvICs1MCAlIC8gKzc1ICUgZW4gbGxlZ2FkYXMgbmFjaW9uYWxlcyBtZWpvcmEgbGEgdmFyaWFjacOzbiBkZSBkZXJyYW1hIGRlIC0zNSDihpIgLTIxIC8gLTE4IC8gLTE1IG1kcA0KDQoqIEVuIG1lc2VzIGNvbiBkZXJyYW1hIHBvc2l0aXZhIChwLmVqLiBKdWwtMjYgPSAxMTggbWRwKSwgZWwgYXVtZW50byBkZSB0dXJpc3RhcyByZXN0YSB+My00IG1kcCBhbCBuaXZlbCByZWdpc3RyYWRvLg0KDQoqIEluY3JlbWVudGFyIDI1LTc1ICUgbGFzIGxsZWdhZGFzIG5hY2lvbmFsZXMgbm8gZ2VuZXJhIHNhbHRvcyBzaWduaWZpY2F0aXZvczogZWwgcmFuZ28gY29tcGxldG8gZGUgaW1wYWN0byBlc3TDoSBkZW50cm8gZGUgwrExNyBtZHAgbWVuc3VhbGVzLg0KDQoqIERpYy0yNiB5IEFici0yNyBzb24gbG9zIHBlb3JlcyBtZXNlcyBlbiBlbCBlc2NlbmFyaW8gcmVhbCAoLTEzNiB5IC00MyBtZHApLiBDb24gKzUwICUgZGUgdHVyaXN0YXMgbGFzIGNhw61kYXMgc2UgcmVjb3J0YW4gMTkgJSB5IDI3ICUgcmVzcGVjdGl2YW1lbnRlLg0KDQpgYGB7cn0NCnR1cmlzdGFzX25hY2lvbmFsZXNfdHMgPC0gdHMoZGZfZmluYWwkTGxlZ2FkYV9UdXJfTmFjX2RpZmYsIHN0YXJ0ID0gYygyMDE1LCAxKSwgZnJlcXVlbmN5ID0gMTIpDQpzZWFzb25wbG90KHR1cmlzdGFzX25hY2lvbmFsZXNfdHMsIHllYXIubGFiZWxzID0gVFJVRSwgY29sID0gMToyMCwgbWFpbiA9ICJFc3RhY2lvbmFsaWRhZCBwb3IgbWVzIikNCg0KdHNfZGVjb21wIDwtIGRlY29tcG9zZSh0dXJpc3Rhc19uYWNpb25hbGVzX3RzKQ0KcGxvdCh0c19kZWNvbXApDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCiMgQXV0b2NvcnJlbGFjacOzbiB5IGF1dG9jb3JyZWxhY2nDs24gcGFyY2lhbA0KYWNmKHR1cmlzdGFzX25hY2lvbmFsZXNfdHMsIG1haW49IkF1dG9jb3JyZWxhdGlvbiAtIExsZWdhZGEgVHVyaXN0YXMgTmFjaW9uYWxlcyIpDQpwYWNmKHR1cmlzdGFzX25hY2lvbmFsZXNfdHMsIG1haW49IlBhcnRpYWwgQXV0b2NvcnJlbGF0aW9uIC1MbGVnYWRhIFR1cmlzdGFzIE5hY2lvbmFsZXMiKSAjDQoNCg0KIwlQcnVlYmEgZGUgRXN0YWNpb25hcmVpZGFkIC0gQXVnbWVudGVkIERpY2tleS1GdWxsZXIgVGVzdCANCmFkZl90dXIgPC0gYWRmLnRlc3QodHVyaXN0YXNfbmFjaW9uYWxlc190cykNCnByaW50KGFkZl90dXIpDQoNCiNIaXDDs3Rlc2lzIG51bGEgKEjigoApOiBsYSBzZXJpZSBubyBlcyBlc3RhY2lvbmFyaWENCiNIaXDDs3Rlc2lzIGFsdGVybmF0aXZhIChI4oKBKTogbGEgc2VyaWUgZXMgZXN0YWNpb25hcmlhDQojQ29uIHVuIHAtdmFsdWUgZGUgMC4wMSwgcmVjaGF6YW1vcyBI4oKAIOKGkiBsYSBzZXJpZSBlcyBlc3RhY2lvbmFyaWEuDQoNCiMgQXVjb3RvcnJlbGFjacOzbiBzZXJpYWwgLSBCb3gtTGp1bmcgdGVzdA0KbGd1bmpfYm94X25hYyA8LSBCb3gudGVzdCh0dXJpc3Rhc19uYWNpb25hbGVzX3RzLCBsYWcgPSA1LCB0eXBlID0gIkxqdW5nLUJveCIpDQpsZ3Vual9ib3hfbmFjDQoNCiNIaXDDs3Rlc2lzIG51bGEgKEjigoApOiBOTyBoYXkgYXV0b2NvcnJlbGFjacOzbiBlbiBsb3MgcmVzaWR1b3MNCiNIaXDDs3Rlc2lzIGFsdGVybmF0aXZhIChI4oKBKTogU0kgSGF5IGF1dG9jb3JyZWxhY2nDs24gZW4gbG9zIHJlc2lkdW9zDQojQ29tbyBlbCBwLXZhbHVlIGVzIDAuMDcyICg+IDAuMDUpLCBubyBzZSByZWNoYXphIEjigoAg4oaSIG5vIGhheSBldmlkZW5jaWEgZnVlcnRlIGRlIGF1dG9jb3JyZWxhY2nDs24gZW4gbG9zIHJlc2lkdW9zLg0KDQpkaWZmX3R1cjwtIG5zZGlmZnModHVyaXN0YXNfbmFjaW9uYWxlc190cykNCmRpZmZfdHVyDQpgYGANCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KYXJpbWExX25hY2lvbmFsZXMgPC0gYXJpbWEodHVyaXN0YXNfbmFjaW9uYWxlc190cywgb3JkZXIgPSBjKDEsIDEsIDApKSAgIw0Kc3VtbWFyeShhcmltYTFfbmFjaW9uYWxlcykgDQpjaGVja3Jlc2lkdWFscyhhcmltYTFfbmFjaW9uYWxlcykNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KYXJpbWEyX25hY2lvbmFsZXMgPC0gYXJpbWEodHVyaXN0YXNfbmFjaW9uYWxlc190cywgb3JkZXIgPSBjKDAsIDEsIDEpKSAgIw0Kc3VtbWFyeShhcmltYTJfbmFjaW9uYWxlcykgDQpjaGVja3Jlc2lkdWFscyhhcmltYTJfbmFjaW9uYWxlcykNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KYXJpbWEzX25hY2lvbmFsZXMgPC0gYXJpbWEodHVyaXN0YXNfbmFjaW9uYWxlc190cywgb3JkZXIgPSBjKDEsIDEsIDEpKSAgIw0Kc3VtbWFyeShhcmltYTNfbmFjaW9uYWxlcykgDQpjaGVja3Jlc2lkdWFscyhhcmltYTNfbmFjaW9uYWxlcykNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KYXV0b19uYWNpb25hbGVzIDwtIGF1dG8uYXJpbWEodHVyaXN0YXNfbmFjaW9uYWxlc190cykNCnN1bW1hcnkoYXV0b19uYWNpb25hbGVzKQ0KY2hlY2tyZXNpZHVhbHMoYXV0b19uYWNpb25hbGVzKQ0KYGBgDQoNCg0KYGBge3J9DQpmb3JlY2FzdF9uYWNpb25hbGVzIDwtIGZvcmVjYXN0Ojpmb3JlY2FzdChhdXRvX25hY2lvbmFsZXMsIGggPSAzMCkNCg0KcGxvdChmb3JlY2FzdF9uYWNpb25hbGVzLA0KICAgICBtYWluID0gIlByb27Ds3N0aWNvIExsZWdhZGEgZGUgVHVyaXN0YXMgTmFjIHBhcmEgZWwgTXVuZGlhbCAyMDI2IiwNCiAgICAgeWxhYiA9ICJMbGVnYWRhcyBkZSBUdXJpc3RhcyBOYWNpb25hbGVzIiwNCiAgICAgeGxhYiA9ICJBw7FvIikNCg0KIyBFeHRyYWVyIGZlY2hhcyBhIHBhcnRpciBkZWwgw7psdGltbyBkYXRvDQpmZWNfZm9yZWNhc3QgPC0gZnVuY3Rpb24odHNfb2JqLCBoKXsNCiAgdWx0IDwtIGVuZCh0c19vYmopICAgICAgICAgICAgICAgICMgYyhhw7FvLCBtZXMpIGRlbCDDumx0aW1vIGRhdG8NCiAgbV9pbmkgPC0gaWZlbHNlKHVsdFsyXSA9PSAxMiwgMSwgIHVsdFsyXSArIDEpDQogIGFfaW5pIDwtIGlmZWxzZSh1bHRbMl0gPT0gMTIsIHVsdFsxXSArIDEsIHVsdFsxXSkNCiAgc2VxKGFzLkRhdGUoc3ByaW50ZigiJWQtJTAyZC0wMSIsIGFfaW5pLCBtX2luaSkpLA0KICAgICAgYnkgPSAiMSBtb250aCIsIGxlbmd0aC5vdXQgPSBoKQ0KfQ0KDQpoPC0zMA0KZmVjaGFzX25hYzwtIGZlY19mb3JlY2FzdCh0dXJpc3Rhc19uYWNpb25hbGVzX3RzLGgpDQoNCiMgQ3JlYWNpw7NuIGRlbCBkYXRhIGZyYW1lIGNvbiByZXN1bHRhZG9zDQpkZl9mb3JlY2FzdCA8LSBkYXRhLmZyYW1lKA0KICBGZWNoYSA9IGZlY2hhc19uYWMsDQogIFByb25vc3RpY28gPSBhcy5udW1lcmljKGZvcmVjYXN0X25hY2lvbmFsZXMkbWVhbiksDQogIExvd2VyODAgPSBhcy5udW1lcmljKGZvcmVjYXN0X25hY2lvbmFsZXMkbG93ZXJbLDFdKSwNCiAgVXBwZXI4MCA9IGFzLm51bWVyaWMoZm9yZWNhc3RfbmFjaW9uYWxlcyR1cHBlclssMV0pLA0KICBMb3dlcjk1ID0gYXMubnVtZXJpYyhmb3JlY2FzdF9uYWNpb25hbGVzJGxvd2VyWywyXSksDQogIFVwcGVyOTUgPSBhcy5udW1lcmljKGZvcmVjYXN0X25hY2lvbmFsZXMkdXBwZXJbLDJdKQ0KKQ0KDQoNCmdncGxvdChkZl9mb3JlY2FzdCwgYWVzKHggPSBGZWNoYSwgeSA9IFByb25vc3RpY28pKSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gTG93ZXI5NSwgeW1heCA9IFVwcGVyOTUpLCBmaWxsID0gImxpZ2h0Ymx1ZSIsIGFscGhhID0gMC40KSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gTG93ZXI4MCwgeW1heCA9IFVwcGVyODApLCBmaWxsID0gImJsdWUiLCBhbHBoYSA9IDAuNCkgKw0KICBnZW9tX2xpbmUoY29sb3IgPSAiZGFya2JsdWUiLCBzaXplID0gMSkgKw0KICBsYWJzKHRpdGxlID0gIlByb27Ds3N0aWNvIExsZWdhZGEgVHVyaXN0YXMgTmFjaW9uYWxlcyBoYXN0YSBNYXlvIDIwMjYiLA0KICAgICAgIHggPSAiRmVjaGEiLCB5ID0gIkxsZWdhZGFzIikgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJWItJVkiLCBkYXRlX2JyZWFrcyA9ICIyIG1vbnRocyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQojIyMjIFByb27Ds3N0aWNvIExsZWdhZGEgVHVyaXN0YXMgRXh0cmFuamVyb3MNCg0KRWwgY29lZmljaWVudGUgZGUgTGxlZ2FkYV9UdXJfRXh0X2RpZmYgZW4gZWwgVkFSIGVzIG5lZ2F0aXZvOyBwb3IgZXNvLCBhbCBzaW11bGFyICsyNSAlIC8gKzUwICUgLyArNzUgJSBsYXMgY3VydmFzIGRlIGNvbG9yIChyb2pvLCB2ZXJkZSwgYXp1bCkgc2UgbXVldmVuIGxpZ2VyYW1lbnRlIHBvciBkZWJham8gZGUgbGEgbMOtbmVhIG1vcmFkYSAoUmVhbCkgZW4gY2FzaSB0b2RvcyBsb3MgbWVzZXM6DQoNCiogRGljLTI2IGVzIGVsIGVzY2VuYXJpbyBtw6FzIHByb2Z1bmRvICgtMTU0IG1kcCByZWFsKS4gRWwgYXVtZW50byBkZWwgNzUgJSBkZSB0dXJpc3RhcyBleHQuIGVtcGVvcmEgbGEgY2HDrWRhIGEgLTE1OSBtZHA6IHVuIGFqdXN0ZSAtNSBtZHAgYWRpY2lvbmFsLg0KDQoqIEFnby0yNiB5IEFici0yNyBtdWVzdHJhbiBwZXF1ZcOxb3MgZGV0ZXJpb3JvcyAoLTQgYSAtNiBtZHApIGFsIGNvbXBhcmFyIFJlYWwgdnMgKzc1ICUuDQoNClBhcmEgbGEgZGVycmFtYSBob3RlbGVyYSwgdW4gc2hvY2sgZGUgdHVyaXN0YXMgZXh0cmFuamVyb3Mgbm8gZXMgcmVudGFibGUgZW4gZWwgY29ydG8gcGxhem8gYmFqbyBsYSBlc3RydWN0dXJhIGFjdHVhbDoNCg0KKiBMYSBlbGFzdGljaWRhZCBlc3RpbWFkYSBlcyBuZWdhdGl2YSB5IHBlcXVlw7FhLg0KDQoqIEluY3JlbWVudGFyIGZsdWpvcyBmb3LDoW5lb3MgaGFzdGEgKzc1ICUgYXBlbmFzIG1vZGlmaWNhIGxhIGRlcnJhbWEgKGVudHJlIDAgeSAtNiBtZHAgcG9yIG1lcykuDQoNCg0KYGBge3J9DQp0dXJpc3Rhc19leHRfdHMgPC0gdHMoZGZfZmluYWwkTGxlZ2FkYV9UdXJfRXh0X2RpZmYsIHN0YXJ0ID0gYygyMDE1LCAxKSwgZnJlcXVlbmN5ID0gMTIpDQoNCnNlYXNvbnBsb3QodHVyaXN0YXNfZXh0X3RzLCB5ZWFyLmxhYmVscyA9IFRSVUUsIGNvbCA9IDE6MjAsIG1haW4gPSAiRXN0YWNpb25hbGlkYWQgcG9yIG1lcyIpDQoNCnRzX2RlY29tcF9leHQgPC0gZGVjb21wb3NlKHR1cmlzdGFzX2V4dF90cykNCnBsb3QodHNfZGVjb21wX2V4dCkNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KIyBBdXRvY29ycmVsYWNpw7NuIHkgYXV0b2NvcnJlbGFjacOzbiBwYXJjaWFsDQphY2YodHVyaXN0YXNfZXh0X3RzLCBtYWluPSJBdXRvY29ycmVsYXRpb24gLSBMbGVnYWRhIFR1cmlzdGFzIEV4dHJhbmplcm9zIikNCnBhY2YodHVyaXN0YXNfZXh0X3RzLCBtYWluPSJQYXJ0aWFsIEF1dG9jb3JyZWxhdGlvbiAtTGxlZ2FkYSBUdXJpc3RhcyBFeHRyYW5qZXJvIikgIw0KDQoNCiMJUHJ1ZWJhIGRlIEVzdGFjaW9uYXJlaWRhZCAtIEF1Z21lbnRlZCBEaWNrZXktRnVsbGVyIFRlc3QgDQphZGZfdHVyX2V4dCA8LSBhZGYudGVzdCh0dXJpc3Rhc19leHRfdHMpDQpwcmludChhZGZfdHVyX2V4dCkNCg0KI0hpcMOzdGVzaXMgbnVsYSAoSOKCgCk6IGxhIHNlcmllIG5vIGVzIGVzdGFjaW9uYXJpYQ0KI0hpcMOzdGVzaXMgYWx0ZXJuYXRpdmEgKEjigoEpOiBsYSBzZXJpZSBlcyBlc3RhY2lvbmFyaWENCiNDb24gdW4gcC12YWx1ZSBkZSAwLjAxLCByZWNoYXphbW9zIEjigoAg4oaSIGxhIHNlcmllIGVzIGVzdGFjaW9uYXJpYS4NCg0KIyBBdWNvdG9ycmVsYWNpw7NuIHNlcmlhbCAtIEJveC1ManVuZyB0ZXN0DQpsZ3Vual9ib3hfZXh0IDwtIEJveC50ZXN0KHR1cmlzdGFzX2V4dF90cywgbGFnID0gNSwgdHlwZSA9ICJManVuZy1Cb3giKQ0KbGd1bmpfYm94X2V4dA0KDQojSGlww7N0ZXNpcyBudWxhIChI4oKAKTogTk8gaGF5IGF1dG9jb3JyZWxhY2nDs24gZW4gbG9zIHJlc2lkdW9zDQojSGlww7N0ZXNpcyBhbHRlcm5hdGl2YSAoSOKCgSk6IFNJIEhheSBhdXRvY29ycmVsYWNpw7NuIGVuIGxvcyByZXNpZHVvcw0KI0NvbW8gZWwgcC12YWx1ZSBlcyAwLjExODQgKD4gMC4wNSksIG5vIHNlIHJlY2hhemEgSOKCgCDihpIgbm8gaGF5IGV2aWRlbmNpYSBmdWVydGUgZGUgYXV0b2NvcnJlbGFjacOzbiBlbiBsb3MgcmVzaWR1b3MuDQoNCmRpZmZfdHVyX2V4dDwtIG5zZGlmZnModHVyaXN0YXNfZXh0X3RzKQ0KZGlmZl90dXJfZXh0DQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmF1dG9fZXh0cmFuamVyb3MgPC0gYXV0by5hcmltYSh0dXJpc3Rhc19leHRfdHMsc2Vhc29uYWwgPSBUUlVFLCBhbGxvd2RyaWZ0ID0gVFJVRSwgYWxsb3dtZWFuID0gVFJVRSkNCg0Kc3VtbWFyeShhdXRvX2V4dHJhbmplcm9zKQ0KY2hlY2tyZXNpZHVhbHMoYXV0b19leHRyYW5qZXJvcykNCnNoYXBpcm8udGVzdChyZXNpZHVhbHMoYXV0b19leHRyYW5qZXJvcykpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmF1dG9fZXh0cmFuamVyb3NfbWFudWFsIDwtIGFyaW1hKHR1cmlzdGFzX2V4dF90cywgb3JkZXIgPSBjKDIsMCwxKSwgc2Vhc29uYWwgPSBsaXN0KG9yZGVyID0gYygxLDAsMCksIHBlcmlvZCA9IDEyKSkNCg0Kc3VtbWFyeShhdXRvX2V4dHJhbmplcm9zX21hbnVhbCkNCmNoZWNrcmVzaWR1YWxzKGF1dG9fZXh0cmFuamVyb3NfbWFudWFsKQ0Kc2hhcGlyby50ZXN0KHJlc2lkdWFscyhhdXRvX2V4dHJhbmplcm9zX21hbnVhbCkpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmxvZ190cyA8LSBsb2codHVyaXN0YXNfZXh0X3RzKQ0KbW9kZWxvX2xvZyA8LSBhdXRvLmFyaW1hKGxvZ190cywgc2Vhc29uYWwgPSBUUlVFLCBhbGxvd2RyaWZ0ID0gVFJVRSwgYWxsb3dtZWFuID0gVFJVRSkNCg0Kc3VtbWFyeShtb2RlbG9fbG9nKQ0KY2hlY2tyZXNpZHVhbHMobW9kZWxvX2xvZykNCnNoYXBpcm8udGVzdChyZXNpZHVhbHMobW9kZWxvX2xvZykpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCm1vZGVsb19tZWpvcmFkb19sb2cgPC0gYXJpbWEobG9nX3RzLCBvcmRlciA9IGMoMiwwLDEpLCBzZWFzb25hbCA9IGxpc3Qob3JkZXIgPSBjKDEsMCwwKSwgcGVyaW9kID0gMTIpKQ0KDQpzdW1tYXJ5KG1vZGVsb19tZWpvcmFkb19sb2cpDQpjaGVja3Jlc2lkdWFscyhtb2RlbG9fbWVqb3JhZG9fbG9nKQ0Kc2hhcGlyby50ZXN0KHJlc2lkdWFscyhtb2RlbG9fbWVqb3JhZG9fbG9nKSkNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZm9yZWNhc3RfZXh0cmFuamVyb3MgPC0gZm9yZWNhc3Q6OmZvcmVjYXN0KG1vZGVsb19tZWpvcmFkb19sb2csIGggPSAzMCkNCg0KcGxvdChmb3JlY2FzdF9leHRyYW5qZXJvcywNCiAgICAgbWFpbiA9ICJQcm9uw7NzdGljbyBMbGVnYWRhIGRlIFR1cmlzdGFzIEV4dHJhbmplcm9zIGEgdW4gYcOxbyBkZWwgTXVuZGlhbCAyMDI2IiwNCiAgICAgeWxhYiA9ICJMbGVnYWRhcyBkZSBUdXJpc3RhcyBFeHRyYW5qZXJvcyIsDQogICAgIHhsYWIgPSAiQcOxbyIpDQoNCnNpZ21hMiA8LSBtb2RlbG9fbWVqb3JhZG9fbG9nJHNpZ21hMiAgICAgICMgdmFyaWFuemEgZGUgbG9zIHJlc2lkdW9zDQpmY19leHAgPC0gZm9yZWNhc3RfZXh0cmFuamVyb3MgICAgICAgICAgICAjIGNvcGlhDQoNCmZjX2V4cCRtZWFuICAgPC0gZXhwKGZvcmVjYXN0X2V4dHJhbmplcm9zJG1lYW4gKyAwLjUgKiBzaWdtYTIpDQpmY19leHAkbG93ZXIgIDwtIGV4cChmb3JlY2FzdF9leHRyYW5qZXJvcyRsb3dlcikNCmZjX2V4cCR1cHBlciAgPC0gZXhwKGZvcmVjYXN0X2V4dHJhbmplcm9zJHVwcGVyKQ0KZmNfZXhwJGZpdHRlZCA8LSBleHAoZm9yZWNhc3RfZXh0cmFuamVyb3MkZml0dGVkKQ0KDQpmZWNoYXNfZXh0PC0gZmVjX2ZvcmVjYXN0KHR1cmlzdGFzX2V4dF90cyxoKQ0KDQpkZl9mb3JlY2FzdF9leHQgPC0gZGF0YS5mcmFtZSgNCiAgRmVjaGEgICAgICAgPSBmZWNoYXNfZXh0LA0KICBQcm9ub3N0aWNvICA9IGFzLm51bWVyaWMoZmNfZXhwJG1lYW4pLA0KICBMb3dlcjgwICAgICA9IGFzLm51bWVyaWMoZmNfZXhwJGxvd2VyWywxXSksDQogIFVwcGVyODAgICAgID0gYXMubnVtZXJpYyhmY19leHAkdXBwZXJbLDFdKSwNCiAgTG93ZXI5NSAgICAgPSBhcy5udW1lcmljKGZjX2V4cCRsb3dlclssMl0pLA0KICBVcHBlcjk1ICAgICA9IGFzLm51bWVyaWMoZmNfZXhwJHVwcGVyWywyXSkNCikNCg0KbGlicmFyeShnZ3Bsb3QyKQ0KDQpnZ3Bsb3QoZGZfZm9yZWNhc3RfZXh0LCBhZXMoeCA9IEZlY2hhLCB5ID0gUHJvbm9zdGljbykpICsNCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBMb3dlcjk1LCB5bWF4ID0gVXBwZXI5NSksDQogICAgICAgICAgICAgIGZpbGwgPSAibGlnaHRibHVlIiwgYWxwaGEgPSAwLjQpICsNCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBMb3dlcjgwLCB5bWF4ID0gVXBwZXI4MCksDQogICAgICAgICAgICAgIGZpbGwgPSAic2t5Ymx1ZSIsICBhbHBoYSA9IDAuNCkgKw0KICBnZW9tX2xpbmUoY29sb3IgPSAiZGFya2JsdWUiLCBzaXplID0gMSkgKw0KICBsYWJzKHRpdGxlID0gIlByb27Ds3N0aWNvIGRlIExsZWdhZGEgZGUgVHVyaXN0YXMgRXh0cmFuamVyb3MgKGVzY2FsYSBvcmlnaW5hbCkiLA0KICAgICAgIHggPSAiRmVjaGEiLCB5ID0gIkxsZWdhZGFzIGRlIHR1cmlzdGFzIikgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJWItJVkiLCBkYXRlX2JyZWFrcyA9ICIyIG1vbnRocyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQoNCioqUFJPTsOTU1RJQ08gREVSUkFNQSBQQVJBIFZBUioqDQoNCkVsIGFuw6FsaXNpcyBwcm9zcGVjdGl2byBkZSBsYSBkZXJyYW1hIGVjb27Ds21pY2EgYXNvY2lhZGEgYWwgdHVyaXNtbyBuYWNpb25hbCByZXZlbGEgdW4gY29tcG9ydGFtaWVudG8gZmx1Y3R1YW50ZSBlbnRyZSAyMDI1IHkgMjAyNywgY29uIHVuIGNyZWNpbWllbnRvIG1vZGVyYWRvIGVuIDIwMjUgc2VndWlkbyBkZSB1bmEgbWFyY2FkYSBkZXNhY2VsZXJhY2nDs24geSB1bmEgc2V2ZXJhIGNvbnRyYWNjacOzbiBlbiBsb3MgZG9zIGHDsW9zIHBvc3RlcmlvcmVzLCBsbyBxdWUgc3VicmF5YSBsYSBuZWNlc2lkYWQgZGUgZXN0cmF0ZWdpYXMgZGUgbWl0aWdhY2nDs24geSBhZGFwdGFjacOzbiBwYXJhIGVuZnJlbnRhciBlc3RlIGVzY2VuYXJpbyBlY29uw7NtaWNvIGRlc2FmaWFudGUuDQoNCiogMjAyNTogU2UgcHJveWVjdGEgdW5hIGRlcnJhbWEgZWNvbsOzbWljYSBtZW5zdWFsIHByb21lZGlvIGRlIDEsODgwIG1kcCwgaW1wdWxzYWRhIHBvciBlbCB0dXJpc21vIG5hY2lvbmFsLCBsYSBvY3VwYWNpw7NuIGhvdGVsZXJhIHkgbGEgZXN0YWTDrWEgcHJvbWVkaW8uIEF1bnF1ZSBwb3NpdGl2YSwgZWwgY3JlY2ltaWVudG8gZXMgbW9kZXJhZG8sIGNvbiB1biBhbHphIGRlIHNvbG8gKzc5IG1kcCBwb3IgbWVzLg0KDQoqIDIwMjY6IExhIGRlcnJhbWEgY2FlIGEgMzUxIG1kcCBtZW5zdWFsZXMgZW4gcHJvbWVkaW8sIG1hcmNhbmRvIHVuYSBkZXNhY2VsZXJhY2nDs24gc2lnbmlmaWNhdGl2YS4gRWwgY3JlY2ltaWVudG8gc2UgcmV2aWVydGUsIGNvbiB1bmEgcMOpcmRpZGEgcHJvbWVkaW8gZGUg4oCTMTY5IG1kcCBwb3IgbWVzLg0KDQoqIDIwMjc6IFNlIGFudGljaXBhIHVuYSBjb250cmFjY2nDs24gc2V2ZXJhLCBjb24gdW4gcHJvbWVkaW8gbWVuc3VhbCBkZSDigJMyLDQ1MiBtZHAuIExhIGNhw61kYSBzZSBhZ3JhdmEgbWVzIGEgbWVzLCBjb24gdW5hIHJlZHVjY2nDs24gZGUg4oCTMjkwIG1kcCwgcmVmbGVqYW5kbyB1biBkZWNsaXZlIGVjb27Ds21pY28gcHJlb2N1cGFudGUuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpkZXJyYW1hX3RpbWVzZXJpZXMgPC0gdHMoZGZfZmluYWwkRGVycmFtYV9FY29ub21pY2FfRXN0X21kcF9kaWZmLCBzdGFydCA9IGMoMjAxNSwgMSksIGZyZXF1ZW5jeSA9IDEyKQ0KDQojIEF1dG9jb3JyZWxhY2nDs24geSBhdXRvY29ycmVsYWNpw7NuIHBhcmNpYWwNCmFjZihkZXJyYW1hX3RpbWVzZXJpZXMsIG1haW49IkF1dG9jb3JyZWxhdGlvbiAtIExsZWdhZGEgVHVyaXN0YXMgTmFjaW9uYWxlcyIpDQpwYWNmKGRlcnJhbWFfdGltZXNlcmllcywgbWFpbj0iUGFydGlhbCBBdXRvY29ycmVsYXRpb24gLUxsZWdhZGEgVHVyaXN0YXMgTmFjaW9uYWxlcyIpICMNCg0KDQojCVBydWViYSBkZSBFc3RhY2lvbmFyZWlkYWQgLSBBdWdtZW50ZWQgRGlja2V5LUZ1bGxlciBUZXN0IA0KYWRmX2RlcnJhbWEgPC0gYWRmLnRlc3QoZGVycmFtYV90aW1lc2VyaWVzKQ0KcHJpbnQoYWRmX2RlcnJhbWEpDQoNCiNIaXDDs3Rlc2lzIG51bGEgKEjigoApOiBsYSBzZXJpZSBubyBlcyBlc3RhY2lvbmFyaWENCiNIaXDDs3Rlc2lzIGFsdGVybmF0aXZhIChI4oKBKTogbGEgc2VyaWUgZXMgZXN0YWNpb25hcmlhDQojQ29tbyBlbCBwLXZhbHVlIGVzIDAuMDEsIHJlY2hhemFtb3MgSOKCgCDihpIgbGEgc2VyaWUgZXMgZXN0YWNpb25hcmlhLg0KDQojIEF1Y290b3JyZWxhY2nDs24gc2VyaWFsIC0gQm94LUxqdW5nIHRlc3QNCmxndW5qX2JveF9kZXJyYW1hIDwtIEJveC50ZXN0KGRlcnJhbWFfdGltZXNlcmllcywgbGFnID0gNSwgdHlwZSA9ICJManVuZy1Cb3giKQ0KbGd1bmpfYm94X2RlcnJhbWENCg0KI0hpcMOzdGVzaXMgbnVsYSAoSOKCgCk6IE5PIGhheSBhdXRvY29ycmVsYWNpw7NuIGVuIGxvcyByZXNpZHVvcw0KI0hpcMOzdGVzaXMgYWx0ZXJuYXRpdmEgKEjigoEpOiBTSSBIYXkgYXV0b2NvcnJlbGFjacOzbiBlbiBsb3MgcmVzaWR1b3MNCiNDb21vIGVsIHAtdmFsdWUgPCAwLjA1LCByZWNoYXphbW9zIEjigoAg4oaSIHPDrSBoYXkgYXV0b2NvcnJlbGFjacOzbiBzaWduaWZpY2F0aXZhIGVuIGxhIHNlcmllLg0KI1BvciBsbyBxdWUgY29udmllbmUgYcOxYWRpciBjb21wb25lbnRlcyBBUi9NQSB5IG5vIHPDs2xvIHVuIG1vZGVsbyBlc3RhY2lvbmFsIChzaW4gY29tcG9uZW50ZXMgQVIsIE1BIG5pIGRpZmVyZW5jaWFjacOzbi4pDQoNCmRpZmZfZGVycmFtYTwtIG5zZGlmZnMoZGVycmFtYV90aW1lc2VyaWVzKQ0KZGlmZl9kZXJyYW1hDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmF1dG9fZGVycmFtYSA8LSBhdXRvLmFyaW1hKGRlcnJhbWFfdGltZXNlcmllcykNCnN1bW1hcnkoYXV0b19kZXJyYW1hKQ0KY2hlY2tyZXNpZHVhbHMoYXV0b19kZXJyYW1hKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQphdXRvMl9kZXJyYW1hIDwtIGF1dG8uYXJpbWEoZGVycmFtYV90aW1lc2VyaWVzLCBzZWFzb25hbCA9IFRSVUUsIHN0ZXB3aXNlID0gRkFMU0UsIGFwcHJveGltYXRpb24gPSBGQUxTRSkNCnN1bW1hcnkoYXV0bzJfZGVycmFtYSkNCmNoZWNrcmVzaWR1YWxzKGF1dG8yX2RlcnJhbWEpDQpgYGANCg0KYGBge3J9DQpmb3JlY2FzdF9kZXJyYW1hIDwtIGZvcmVjYXN0Ojpmb3JlY2FzdChhdXRvMl9kZXJyYW1hLCBoID0gMzApDQoNCnBsb3QoZm9yZWNhc3RfZGVycmFtYSwNCiAgICAgbWFpbiA9ICJQcm9uw7NzdGljbyBEZXJyYW1hIEVjLiBIb3RlbGVzIGhhaWEgZWwgTXVuZGlhbCAyMDI2IiwNCiAgICAgeWxhYiA9ICJEZXJyYW1hIEVjb27Ds21pY2EgSG90ZWxlcyIsDQogICAgIHhsYWIgPSAiQcOxbyIpDQoNCmZlY2hhc19kZXJyYW1hIDwtIGZlY19mb3JlY2FzdChkZXJyYW1hX3RpbWVzZXJpZXMsIGgpDQoNCmRmX2ZvcmVjYXN0X2RlcnJhbWEgPC0gZGF0YS5mcmFtZSgNCiAgRmVjaGEgPSBmZWNoYXNfZGVycmFtYSwNCiAgUHJvbm9zdGljbyA9IGFzLm51bWVyaWMoZm9yZWNhc3RfZGVycmFtYSRtZWFuKSwNCiAgTG93ZXI4MCA9IGFzLm51bWVyaWMoZm9yZWNhc3RfZGVycmFtYSRsb3dlclssMV0pLA0KICBVcHBlcjgwID0gYXMubnVtZXJpYyhmb3JlY2FzdF9kZXJyYW1hJHVwcGVyWywxXSksDQogIExvd2VyOTUgPSBhcy5udW1lcmljKGZvcmVjYXN0X2RlcnJhbWEkbG93ZXJbLDJdKSwNCiAgVXBwZXI5NSA9IGFzLm51bWVyaWMoZm9yZWNhc3RfZGVycmFtYSR1cHBlclssMl0pDQopDQoNCmdncGxvdChkZl9mb3JlY2FzdF9kZXJyYW1hLCBhZXMoeCA9IEZlY2hhLCB5ID0gUHJvbm9zdGljbykpICsNCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBMb3dlcjk1LCB5bWF4ID0gVXBwZXI5NSksIGZpbGwgPSAibGlnaHRncmVlbiIsIGFscGhhID0gMC40KSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gTG93ZXI4MCwgeW1heCA9IFVwcGVyODApLCBmaWxsID0gImdyZWVuIiwgYWxwaGEgPSAwLjQpICsNCiAgZ2VvbV9saW5lKGNvbG9yID0gImRhcmtncmVlbiIsIHNpemUgPSAxKSArDQogIGxhYnModGl0bGUgPSAiUHJvbsOzc3RpY28gZGUgRGVycmFtYSBFY29uw7NtaWNhIGhhc3RhIE1heW8gMjAyNiIsDQogICAgICAgeCA9ICJGZWNoYSIsIHkgPSAiRGVycmFtYSIpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiViLSVZIiwgZGF0ZV9icmVha3MgPSAiMiBtb250aHMiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkobHVicmlkYXRlKQ0KDQpkZl9oaXN0IDwtIGRmX2ZpbmFsICU+JSANCiAgbXV0YXRlKEZlY2hhID0gbHVicmlkYXRlOjptYWtlX2RhdGUoQcORTywgTUVTLCAxKSkgJT4lIA0KICBkcGx5cjo6c2VsZWN0KCAgICAgICAgICAgICAgDQogICAgRmVjaGEsDQogICAgRGVycmFtYV9FY29ub21pY2FfRXN0X21kcF9kaWZmLA0KICAgIExsZWdhZGFfVHVyX05hY19kaWZmLA0KICAgIExsZWdhZGFfVHVyX0V4dF9kaWZmDQogICkNCg0KZGZfZm9yZWNhc3RfbmFjIDwtIHRpYmJsZSgNCiAgRmVjaGEgICAgICAgICAgICAgICA9IGZlY2hhc19uYWMsDQogIExsZWdhZGFfVHVyX05hY19kaWZmID0gYXMubnVtZXJpYyhmb3JlY2FzdF9uYWNpb25hbGVzJG1lYW4pDQopDQoNCmRmX2ZvcmVjYXN0X2V4dCA8LSB0aWJibGUoDQogIEZlY2hhICAgICAgICAgICAgICAgICA9IGZlY2hhc19leHQsDQogIExsZWdhZGFfVHVyX0V4dF9kaWZmICA9IGV4cChmb3JlY2FzdF9leHRyYW5qZXJvcyRtZWFuKQ0KKQ0KDQpkZl9mb3JlY2FzdF9kZXJyYW1hIDwtIHRpYmJsZSgNCiAgRmVjaGEgICA9IGZlY2hhc19kZXJyYW1hLA0KICBEZXJyYW1hX0Vjb25vbWljYV9Fc3RfbWRwX2RpZmYgPSBhcy5udW1lcmljKGZvcmVjYXN0X2RlcnJhbWEkbWVhbikNCikNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHB1cnJyKQ0KZGZfZm9yZWNhc3RfdG90YWwgPC0gcmVkdWNlKA0KICBsaXN0KGRmX2ZvcmVjYXN0X2RlcnJhbWEsIGRmX2ZvcmVjYXN0X25hYywgZGZfZm9yZWNhc3RfZXh0KSwNCiAgZnVsbF9qb2luLA0KICBieSA9ICJGZWNoYSINCikNCg0KZGZfcHJvbm9zdGljb3MgPC0gYmluZF9yb3dzKGRmX2hpc3QsIGRmX2ZvcmVjYXN0X3RvdGFsKSAlPiUgDQogIGFycmFuZ2UoRmVjaGEpDQoNCmhlYWQoZGZfcHJvbm9zdGljb3MsIDE1KQ0KDQpkZXJyYW1hX3RzX3ZhciA8LSB0cyhkZl9wcm9ub3N0aWNvcyREZXJyYW1hX0Vjb25vbWljYV9Fc3RfbWRwX2RpZmYsIHN0YXJ0ID0gYygyMDE1LCAxKSwgZnJlcXVlbmN5ID0gMTIpDQp0dXJuYWNfdHNfdmFyIDwtIHRzKGRmX3Byb25vc3RpY29zJExsZWdhZGFfVHVyX05hY19kaWZmLCBzdGFydCA9IGMoMjAxNSwgMSksIGZyZXF1ZW5jeSA9IDEyKQ0KdHVyZXh0X3RzX3ZhciA8LSB0cyhkZl9wcm9ub3N0aWNvcyRMbGVnYWRhX1R1cl9FeHRfZGlmZiwgc3RhcnQgPSBjKDIwMTUsIDEpLCBmcmVxdWVuY3kgPSAxMikNCmBgYA0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpkYXRvc190c190dXJpc3Rhc25hYyAgPC0gY2JpbmQoZGVycmFtYV90c192YXIsIHR1cm5hY190c192YXIpIA0KVkFSc2VsZWN0KGRhdG9zX3RzX3R1cmlzdGFzbmFjLCBsYWcubWF4ID0gMTIsIHR5cGUgPSAiY29uc3QiKQ0KDQp2YXJfZmluYWxfbmFjIDwtIFZBUihkYXRvc190c190dXJpc3Rhc25hYywgcCA9IDIsIHR5cGUgPSAiY29uc3QiKQ0Kc3VtbWFyeSh2YXJfZmluYWxfbmFjKQ0KDQoNCnN1bW1hcnkodmFyX2ZpbmFsX25hYyR2YXJyZXN1bHQkZGVycmFtYV90c192YXIpDQpzZXJpYWwudGVzdCh2YXJfZmluYWxfbmFjLCBsYWdzLnB0ID0gMTIsIHR5cGUgPSAiUFQuYXN5bXB0b3RpYyIpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmNvZWZzIDwtIGNvZWYodmFyX2ZpbmFsX25hYyR2YXJyZXN1bHQkZGVycmFtYV90c192YXIpDQoNCmJldGFfdG90YWwgPC0gY29lZnNbInR1cm5hY190c192YXIubDEiXSArIGNvZWZzWyJ0dXJuYWNfdHNfdmFyLmwyIl0NCg0KZGZfaW1wYWN0byA8LSBkZl9wcm9ub3N0aWNvc1tkZl9wcm9ub3N0aWNvcyRGZWNoYSA+PSBhcy5EYXRlKCIyMDI2LTA2LTAxIiksIF0NCg0KIyBDYWxjdWxhciBlbCBjYW1iaW8gZW4gWCBwYXJhIGNhZGEgZXNjZW5hcmlvDQpkZl9pbXBhY3RvJERlbHRhXzI1IDwtIGRmX2ltcGFjdG8kTGxlZ2FkYV9UdXJfTmFjX2RpZmYgKiAxLjI1DQpkZl9pbXBhY3RvJERlbHRhXzUwIDwtIGRmX2ltcGFjdG8kTGxlZ2FkYV9UdXJfTmFjX2RpZmYgKiAxLjUwDQpkZl9pbXBhY3RvJERlbHRhXzc1IDwtIGRmX2ltcGFjdG8kTGxlZ2FkYV9UdXJfTmFjX2RpZmYgKiAxLjc1DQoNCiMgQXBsaWNhciBlbCBpbXBhY3RvIGVzdGltYWRvIGEgWQ0KZGZfaW1wYWN0byREZXJyYW1hXzI1IDwtIGRmX2ltcGFjdG8kRGVycmFtYV9FY29ub21pY2FfRXN0X21kcF9kaWZmICsgKGRmX2ltcGFjdG8kRGVsdGFfMjUgKiBiZXRhX3RvdGFsKQ0KZGZfaW1wYWN0byREZXJyYW1hXzUwIDwtIGRmX2ltcGFjdG8kRGVycmFtYV9FY29ub21pY2FfRXN0X21kcF9kaWZmICsgKGRmX2ltcGFjdG8kRGVsdGFfNTAgKiBiZXRhX3RvdGFsKQ0KZGZfaW1wYWN0byREZXJyYW1hXzc1IDwtIGRmX2ltcGFjdG8kRGVycmFtYV9FY29ub21pY2FfRXN0X21kcF9kaWZmICsgKGRmX2ltcGFjdG8kRGVsdGFfNzUgKiBiZXRhX3RvdGFsKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KHRpZHlyKQ0KDQojIEVzY2VuYXJpb3MgZGVzZGUganVuaW8gMjAyNg0KZGZfcGxvdCA8LSBkZl9pbXBhY3RvWywgYygiRmVjaGEiLCAiRGVycmFtYV8yNSIsICJEZXJyYW1hXzUwIiwgIkRlcnJhbWFfNzUiKV0NCg0KZGZfcGxvdF9sb25nIDwtIHBpdm90X2xvbmdlcigNCiAgZGZfcGxvdCwNCiAgY29scyA9IC1GZWNoYSwNCiAgbmFtZXNfdG8gPSAiRXNjZW5hcmlvIiwNCiAgdmFsdWVzX3RvID0gIkRlcnJhbWEiDQopDQoNCmRmX2Jhc2VfcGxvdCA8LSBkZl9wcm9ub3N0aWNvc1ssIGMoIkZlY2hhIiwgIkRlcnJhbWFfRWNvbm9taWNhX0VzdF9tZHBfZGlmZiIpXQ0KY29sbmFtZXMoZGZfYmFzZV9wbG90KVsyXSA8LSAiRGVycmFtYSINCmRmX2Jhc2VfcGxvdCRFc2NlbmFyaW8gPC0gIlNlcmllX09yaWdpbmFsIg0KDQpkZl9jb21wbGV0byA8LSByYmluZChkZl9wbG90X2xvbmcsIGRmX2Jhc2VfcGxvdCkNCmBgYA0KDQoNCmBgYHtyfQ0KZ2dwbG90KGRmX2NvbXBsZXRvLCBhZXMoeCA9IEZlY2hhLCB5ID0gRGVycmFtYSwgY29sb3IgPSBFc2NlbmFyaW8pKSArDQogIGdlb21fbGluZShzaXplID0gMSkgKw0KICBsYWJzKHRpdGxlID0gIlNlcmllIGhpc3TDs3JpY2EgKyBlc2NlbmFyaW9zIGRlIGltcGFjdG8iLA0KICAgICAgIHN1YnRpdGxlID0gIkltcGFjdG8gZGUgYXVtZW50byBkZSB0dXJpc3RhcyBkZXNkZSBqdW5pbyAyMDI2IiwNCiAgICAgICB4ID0gIkZlY2hhIiwgeSA9ICJEZXJyYW1hIEVzdGltYWRhIChkaWZmKSIpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiViLSVZIiwgZGF0ZV9icmVha3MgPSAiMyBtb250aHMiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmRmX3RhYmxhIDwtIGRmX2ltcGFjdG9bLCBjKA0KICAiRmVjaGEiLA0KICAiRGVycmFtYV9FY29ub21pY2FfRXN0X21kcF9kaWZmIiwgICMgUHJvbsOzc3RpY28gYmFzZQ0KICAiRGVycmFtYV8yNSIsDQogICJEZXJyYW1hXzUwIiwNCiAgIkRlcnJhbWFfNzUiDQopXQ0KDQojIFJlbm9tYnJhciBjb2x1bW5hcyBwYXJhIHF1ZSBzZWFuIG3DoXMgY2xhcmFzDQpjb2xuYW1lcyhkZl90YWJsYSkgPC0gYygiRmVjaGEiLCAiUmVhbCIsICJBdW1lbnRvXzI1IiwgIkF1bWVudG9fNTAiLCAiQXVtZW50b183NSIpDQpkZl90YWJsYQ0KYGBgDQoNCiMjIyMgUHJvbsOzc3RpY28gSW1wYWN0byBkZSBMbGVnYWRhIFR1cmlzdGFzIEV4dHJhbmplcm9zICYgTmFjaW9uYWxlcyBlbiBEZXJyYW1hDQoNClNlIHByZXNlbnRhbiBlc2NlbmFyaW9zIGRlIGRlcnJhbWEgZWNvbsOzbWljYSBlc3RpbWFkYSBkZXNkZSBqdW5pbyBkZSAyMDI2LCBjb21wYXJhbmRvIHVuIHZhbG9yIGJhc2UgKGRlbm9taW5hZG8gIlJlYWwiKSBjb24gdHJlcyBlc2NlbmFyaW9zIGRlIGluY3JlbWVudG86IDI1JSwgNTAlIHkgNzUlLCBjb24gcGVyaW9kaWNpZGFkIG1lbnN1YWwgaGFzdGEganVuaW8gZGUgMjAyNy4NCiANCioqSW1wYWN0b3MgZW4gVHVyaXN0YXMgTmFjaW9uYWxlcyoqDQogDQoqIEp1bGlvIDIwMjY6IFBpY28gc2lnbmlmaWNhdGl2byBlbiBkZXJyYW1hIGVjb27Ds21pY2EgcGFyYSB0b2RvcyBsb3MgZXNjZW5hcmlvcywgY29uIGVsICJSZWFsIiBzaWVuZG8gZWwgbcOhcyBhbHRvLg0KDQoqIEFnb3N0by1zZXB0aWVtYnJlIDIwMjY6IENhw61kYSBhYnJ1cHRhIGRlIGxhIGRlcnJhbWE7IGVsICJSZWFsIiB2dWVsdmUgYSBkaWZlcmVuY2lhcnNlIG1hcmNhZGFtZW50ZSBoYWNpYSBhYmFqby4NCg0KKiBPY3R1YnJlIDIwMjYgeSBlbmVybyAyMDI3OiBSZWN1cGVyYWNpb25lcyBub3RvcmlhcywgY29uIGVsICJSZWFsIiBwb3IgZW5jaW1hIGRlIGxvcyBlc2NlbmFyaW9zIGRlIGF1bWVudG8uDQoNCiogTWFyem8tYWJyaWwgMjAyNzogU2UgcGVyY2liZSB1bmEgcmV2ZXJzacOzbjogZWwgZXNjZW5hcmlvICJSZWFsIiBjYWUgbWllbnRyYXMgbG9zIGF1bWVudG9zIHNlIG1hbnRpZW5lbiByZWxhdGl2YW1lbnRlIGVzdGFibGVzLg0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXIpDQoNCmRmX3RhYmxhX2xvbmcgPC0gcGl2b3RfbG9uZ2VyKA0KICBkZl90YWJsYSwNCiAgY29scyA9IC1GZWNoYSwNCiAgbmFtZXNfdG8gPSAiRXNjZW5hcmlvIiwNCiAgdmFsdWVzX3RvID0gIkRlcnJhbWEiDQopDQoNCmdncGxvdChkZl90YWJsYV9sb25nLCBhZXMoeCA9IEZlY2hhLCB5ID0gRGVycmFtYSwgY29sb3IgPSBFc2NlbmFyaW8pKSArDQogIGdlb21fbGluZShzaXplID0gMS4yKSArDQogIGxhYnModGl0bGUgPSAiRXNjZW5hcmlvcyBkZSBkZXJyYW1hIGVjb27Ds21pY2EgcHJvbm9zdGljYWRhIGNvbiBJbmNyZW1lbnRvIMO6bmljbyBlbiBUdXJpc3RhcyBOYWNpb25hbGVzIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEZXNkZSBqdW5pbyAyMDI2OiBiYXNlICsgYXVtZW50byBkZWwgMjUlLCA1MCUgeSA3NSUiLA0KICAgICAgIHggPSAiRmVjaGEiLCB5ID0gIkRlcnJhbWEgRXN0aW1hZGEgKGRpZmYpIikgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJWItJVkiLCBkYXRlX2JyZWFrcyA9ICIxIG1vbnRoIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQpgYGANCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KZGF0b3NfdHNfdHVyaXN0YXNleHQgIDwtIGNiaW5kKGRlcnJhbWFfdHNfdmFyLCB0dXJleHRfdHNfdmFyKSANClZBUnNlbGVjdChkYXRvc190c190dXJpc3Rhc2V4dCwgbGFnLm1heCA9IDEyLCB0eXBlID0gImNvbnN0IikNCg0KdmFyX2ZpbmFsX2V4dCA8LSBWQVIoZGF0b3NfdHNfdHVyaXN0YXNleHQsIHAgPSAyLCB0eXBlID0gImNvbnN0IikNCg0Kc2VyaWFsLnRlc3QodmFyX2ZpbmFsX2V4dCwgbGFncy5wdCA9IDEyLCB0eXBlID0gIlBULmFzeW1wdG90aWMiKQ0KDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmNvZWZzIDwtIGNvZWYodmFyX2ZpbmFsX2V4dCR2YXJyZXN1bHQkZGVycmFtYV90c192YXIpDQpiZXRhX3RvdGFsX2V4dCA8LSBjb2Vmc1sidHVyZXh0X3RzX3Zhci5sMSJdICsgY29lZnNbInR1cmV4dF90c192YXIubDIiXQ0KDQpkZl9pbXBhY3RvX2V4dCA8LSBkZl9wcm9ub3N0aWNvc1tkZl9wcm9ub3N0aWNvcyRGZWNoYSA+PSBhcy5EYXRlKCIyMDI2LTA2LTAxIiksIF0NCg0KZGZfaW1wYWN0b19leHQkRGVsdGFfMjUgPC0gZGZfaW1wYWN0b19leHQkTGxlZ2FkYV9UdXJfRXh0X2RpZmYgKiAxLjI1DQpkZl9pbXBhY3RvX2V4dCREZWx0YV81MCA8LSBkZl9pbXBhY3RvX2V4dCRMbGVnYWRhX1R1cl9FeHRfZGlmZiAqIDEuNTANCmRmX2ltcGFjdG9fZXh0JERlbHRhXzc1IDwtIGRmX2ltcGFjdG9fZXh0JExsZWdhZGFfVHVyX0V4dF9kaWZmICogMS43NQ0KDQojICBBcGxpY2FyIGJldGEgZGVsIG1vZGVsbyBWQVINCmRmX2ltcGFjdG9fZXh0JERlcnJhbWFfMjUgPC0gZGZfaW1wYWN0b19leHQkRGVycmFtYV9FY29ub21pY2FfRXN0X21kcF9kaWZmICsgKGRmX2ltcGFjdG9fZXh0JERlbHRhXzI1ICogYmV0YV90b3RhbF9leHQpDQpkZl9pbXBhY3RvX2V4dCREZXJyYW1hXzUwIDwtIGRmX2ltcGFjdG9fZXh0JERlcnJhbWFfRWNvbm9taWNhX0VzdF9tZHBfZGlmZiArIChkZl9pbXBhY3RvX2V4dCREZWx0YV81MCAqIGJldGFfdG90YWxfZXh0KQ0KZGZfaW1wYWN0b19leHQkRGVycmFtYV83NSA8LSBkZl9pbXBhY3RvX2V4dCREZXJyYW1hX0Vjb25vbWljYV9Fc3RfbWRwX2RpZmYgKyAoZGZfaW1wYWN0b19leHQkRGVsdGFfNzUgKiBiZXRhX3RvdGFsX2V4dCkNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeSh0aWR5cikNCg0KIyBGb3JtYXRvIGxhcmdvIGRlIGVzY2VuYXJpb3MNCmRmX3Bsb3RfZXh0IDwtIGRmX2ltcGFjdG9fZXh0WywgYygiRmVjaGEiLCAiRGVycmFtYV8yNSIsICJEZXJyYW1hXzUwIiwgIkRlcnJhbWFfNzUiKV0NCg0KZGZfcGxvdF9sb25nX2V4dCA8LSBwaXZvdF9sb25nZXIoDQogIGRmX3Bsb3RfZXh0LA0KICBjb2xzID0gLUZlY2hhLA0KICBuYW1lc190byA9ICJFc2NlbmFyaW8iLA0KICB2YWx1ZXNfdG8gPSAiRGVycmFtYSINCikNCg0KIyBTZXJpZSBiYXNlIGNvbXBsZXRhDQpkZl9iYXNlX3Bsb3RfZXh0IDwtIGRmX3Byb25vc3RpY29zWywgYygiRmVjaGEiLCAiRGVycmFtYV9FY29ub21pY2FfRXN0X21kcF9kaWZmIildDQpjb2xuYW1lcyhkZl9iYXNlX3Bsb3RfZXh0KVsyXSA8LSAiRGVycmFtYSINCmRmX2Jhc2VfcGxvdF9leHQkRXNjZW5hcmlvIDwtICJTZXJpZV9PcmlnaW5hbCINCg0KIyBDb21iaW5hciBiYXNlICsgZXNjZW5hcmlvcw0KZGZfY29tcGxldG9fZXh0IDwtIHJiaW5kKGRmX3Bsb3RfbG9uZ19leHQsIGRmX2Jhc2VfcGxvdF9leHQpDQoNCmBgYA0KDQoqKkltcGFjdG9zIGVuIFR1cmlzdGFzIEV4dHJhbmplcm9zKioNCg0KKiBBbHRhIGVzdGFiaWxpZGFkOiBBIHBhcnRpciBkZSBqdW5pbyBkZSAyMDI2LCB0b2RvcyBsb3MgZXNjZW5hcmlvcyBjcmVjZW4geSBkZWNyZWNlbiBkZSBtYW5lcmEgY2FzaSBpZMOpbnRpY2EuDQoNCiogUGljb3MgeSB2YWxsZXMgY29pbmNpZGVudGVzOiBUb2RvcyBsb3MgbcOheGltb3MgeSBtw61uaW1vcyAoanVsaW8sIG9jdHVicmUsIGVuZXJvKSBzb24gY29tcGFydGlkb3MgZW50cmUgZXNjZW5hcmlvcy4NCg0KKiBFc2Nhc2EgZGlmZXJlbmNpYWNpw7NuOiBObyBoYXkgdW5hIHZlbnRhamEgY2xhcmEgZW4gbG9zIGVzY2VuYXJpb3MgY29uIGF1bWVudG8gZnJlbnRlIGFsICJSZWFsIiwgbG8gcXVlIHBvZHLDrWEgcmVmbGVqYXIgc3VwdWVzdG9zIGNvbnNlcnZhZG9yZXMgbyBmYWx0YSBkZSBzZW5zaWJpbGlkYWQgZW4gZWwgbW9kZWxvLg0KDQpgYGB7cn0NCmdncGxvdChkZl9jb21wbGV0b19leHQsIGFlcyh4ID0gRmVjaGEsIHkgPSBEZXJyYW1hLCBjb2xvciA9IEVzY2VuYXJpbykpICsNCiAgZ2VvbV9saW5lKHNpemUgPSAxKSArDQogIGxhYnModGl0bGUgPSAiU2VyaWUgaGlzdMOzcmljYSArIGVzY2VuYXJpb3MgZGUgaW1wYWN0byIsDQogICAgICAgc3VidGl0bGUgPSAiSW1wYWN0byBkZSBhdW1lbnRvIGRlIHR1cmlzdGFzIGV4dHJhbmplcm9zIGRlc2RlIGp1bmlvIDIwMjYiLA0KICAgICAgIHggPSAiRmVjaGEiLCB5ID0gIkRlcnJhbWEgRXN0aW1hZGEgKGRpZmYpIikgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJWItJVkiLCBkYXRlX2JyZWFrcyA9ICIzIG1vbnRocyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQpgYGB7cn0NCmRmX3RhYmxhX2V4dCA8LSBkZl9pbXBhY3RvX2V4dFssIGMoDQogICJGZWNoYSIsDQogICJEZXJyYW1hX0Vjb25vbWljYV9Fc3RfbWRwX2RpZmYiLCAgIyBQcm9uw7NzdGljbyBiYXNlDQogICJEZXJyYW1hXzI1IiwNCiAgIkRlcnJhbWFfNTAiLA0KICAiRGVycmFtYV83NSINCildDQoNCmNvbG5hbWVzKGRmX3RhYmxhX2V4dCkgPC0gYygiRmVjaGEiLCAiUmVhbCIsICJBdW1lbnRvXzI1IiwgIkF1bWVudG9fNTAiLCAiQXVtZW50b183NSIpDQpkZl90YWJsYV9leHQNCmBgYA0KDQoNCmBgYHtyfQ0KZGZfdGFibGFfbG9uZ19leHQgPC0gcGl2b3RfbG9uZ2VyKA0KICBkZl90YWJsYV9leHQsDQogIGNvbHMgPSAtRmVjaGEsDQogIG5hbWVzX3RvID0gIkVzY2VuYXJpbyIsDQogIHZhbHVlc190byA9ICJEZXJyYW1hIg0KKQ0KDQpnZ3Bsb3QoZGZfdGFibGFfbG9uZ19leHQsIGFlcyh4ID0gRmVjaGEsIHkgPSBEZXJyYW1hLCBjb2xvciA9IEVzY2VuYXJpbykpICsNCiAgZ2VvbV9saW5lKHNpemUgPSAxLjIpICsNCiAgbGFicyh0aXRsZSA9ICJFc2NlbmFyaW9zIGRlIGRlcnJhbWEgZWNvbsOzbWljYSBwcm9ub3N0aWNhZGEgY29uIEluY3JlbWVudG8gw7puaWNvIGVuIFR1cmlzdGFzIEV4dHJhbmplcm9zIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEZXNkZSBqdW5pbyAyMDI2OiBiYXNlICsgYXVtZW50byBkZWwgMjUlLCA1MCUgeSA3NSUiLA0KICAgICAgIHggPSAiRmVjaGEiLCB5ID0gIkRlcnJhbWEgRXN0aW1hZGEgKGRpZmYpIikgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJWItJVkiLCBkYXRlX2JyZWFrcyA9ICIxIG1vbnRoIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQoNCg0KDQojIyMgU2VndW5kbyBJbmRpY2Fkb3INCg0KKkluZHVzdHJpYSBIb3RlbGVyYSAmIFR1cmlzbW8gZGUgTmVnb2Npb3M6IEdyb3VwIE1peCogICANCiAgIA0KRW4gZWwgY29udGV4dG8gdHVyw61zdGljbyBkZSBOdWV2byBMZcOzbiwgZG9uZGUgc2UgY3VlbnRhIGNvbiBkZW1hbmRhIGdlbmVyYWRhIHBvciBldmVudG9zIG1hc2l2b3MgY29tbyBmZXN0aXZhbGVzIG11c2ljYWxlcywgY29uZ3Jlc29zIHkgcGFydGlkb3MgZGVsIE11bmRpYWwgMjAyNiwgcmVzdWx0YSBmdW5kYW1lbnRhbCBjb250YXIgY29uIG3DqXRyaWNhcyBxdWUgcGVybWl0YW4gYW50aWNpcGFyIHkgb3B0aW1pemFyIGxhIGNhcGFjaWRhZCBkZSByZXNwdWVzdGEgZGVsIGVjb3Npc3RlbWEgaG90ZWxlcm8uIFVubyBkZSBsb3MgaW5kaWNhZG9yZXMgY2xhdmUgcHJvcHVlc3RvcyBlcyBlbCAqR3JvdXAgTWl4KiwgcXVlIHJlcHJlc2VudGEgZWwgcG9yY2VudGFqZSBkZSByZXNlcnZhcyB0b3RhbGVzIHF1ZSBwcm92aWVuZW4gZGUgZ3J1cG9zIGdyYW5kZXMgKHTDrXBpY2FtZW50ZSBkZSAxMCBvIG3DoXMgaGFiaXRhY2lvbmVzKSwgY29tbyBkZWxlZ2FjaW9uZXMgZGVwb3J0aXZhcywgY29udmVuY2lvbmVzLCBib2RhcyBvIHZpYWplcyBjb3Jwb3JhdGl2b3MuICAgDQogICANCl9Gw7NybXVsYSBkZWwgS1BJOl8NCkdyb3VwIE1peCAoJSkgPSAoUmVzZXJ2YXMgZGVsIHNlZ21lbnRvIGdydXBhbCAvIFJlc2VydmFzIHRvdGFsZXMpIMOXIDEwMA0KDQpfUmVsZXZhbmNpYTpfICAgDQpGYWNpbGl0YSBsYSBkZXRlY2Npw7NuIGRlIGV2ZW50b3MgY29uIGFsdGEgY29uY2VudHJhY2nDs24gZGUgZ3J1cG9zLCBsbyBxdWUgcGVybWl0ZSBvcHRpbWl6YXIgaW5ncmVzb3MuIEFsIGlkZW50aWZpY2FyIGVsIHBlc28gZGVsIHNlZ21lbnRvIGdydXBhbCBlbiBkaWZlcmVudGVzIHBlcmlvZG9zLCBzZSBwdWVkZW4gYWp1c3RhciB0YXJpZmFzLCBvZnJlY2VyIHBhcXVldGVzIHByb21vY2lvbmFsZXMgbyBuZWdvY2lhciBhbGlhbnphcyBjb24gb3JnYW5pemFkb3JlcyBkZSBldmVudG9zLiBEaWNobyBpbmRpY2Fkb3IgZXMgw7p0aWwgbm8gc29sbyBwYXJhIGhvdGVsZXMsIHNpbm8gdGFtYmnDqW4gcGFyYSByZWNpbnRvcywgb3BlcmFkb3JlcyB0dXLDrXN0aWNvcyB5IGF1dG9yaWRhZGVzIGRlbCBjbMO6c3RlciwgYWwgcGVybWl0aXIgdW5hIGxlY3R1cmEgY29vcmRpbmFkYSBkZSBsYSBkZW1hbmRhIGZ1dHVyYS4gICANCiAgIA0KX0VzdGFkbyBBY3R1YWwgZGVsIEtQSTpfICAgDQpVc2FuZG8gY29tbyBiYXNlIGxhcyByZXNlcnZhcyBnZW5lcmFkYXMgYmFqbyBsb3MgZXZlbnRvcyBkZSBsYSBPQ1YgcG9kZW1vcyB2aXN1YWxpemFyIGVsIGltcGFjdG8gcXVlIGxhcyBjb25mZXJlbmNpYXMgdSBvdHJvcyBldmVudG9zIGRlbCBjb25zb3JjaW8gZ2VuZXJhbiBlbiBsYSBvY3VwYWNpw7NuIGhvdGVsZXJhIHRvdGFsIGRlIGxhIFpNTS4gRHVyYW50ZSBlbCBhw7FvIHBhc2FkbyBlbCDDrW5kaWNlIGhhIHByb21lZGlhZG8gNC40JS4gTG8gcXVlIGluZGljYSBxdWUgZWwgNC40JSBkZSBsYSBvY3VwYWNpw7NuIGhvdGVsZXJhIHByb3ZpZW5lIGRlIGxvcyBhc2lzdGVudGVzIG8gc3Rha2Vob2xkZXJzIGRlIGxhIE9DVi4gICANCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGZfT0NWIDwtIHJlYWQueGxzeCgiVGFibGFfTWFjcm9fRXZlbnRvc09DVi54bHN4IikNCmtwaV9kZiA8LSBkZl9PQ1YgJT4lDQogIHNlbGVjdCgiQcOxbyIsICJNZXNOb21icmUiLCAiQ3VhcnRvcyIsICJDdWFydG9zX09jdXBhZG9zIikNCg0Ka3BpX2RmJEZlY2hhIDwtIGFzLkRhdGUocGFzdGUoa3BpX2RmJEHDsW8sIGtwaV9kZiRNZXNOb21icmUsICIwMSIsIHNlcCA9ICItIikpDQoNCmtwaV9kZiA8LSBrcGlfZGYgJT4lDQogIG11dGF0ZShHcm91cE1peCA9IChDdWFydG9zIC8gQ3VhcnRvc19PY3VwYWRvcykgKiAxMDApDQoNCmtwaV9kZiAlPiUNCiAgdGFpbCg0OCkgJT4lDQogIGdncGxvdChhZXMoeCA9IEZlY2hhLCB5ID0gR3JvdXBNaXgpKSArDQogICAgZ2VvbV9saW5lKGNvbG9yID0gInN0ZWVsYmx1ZSIpICsNCiAgICBnZW9tX3BvaW50KGNvbG9yID0gInN0ZWVsYmx1ZSIpICsNCiAgICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJkYXJrZ3JleSIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgICBsYWJzKHRpdGxlID0gIlRlbmRlbmNpYSBkZSBHcm91cE1peCIsIHggPSAiRmVjaGEiLCB5ID0gIkdyb3VwTWl4IikgKw0KICAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KX1JhbmdvIENyw610aWNvOl8gIA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KcGVyY2VudGlsZXMgPC0gcm91bmQocXVhbnRpbGUoa3BpX2RmJEdyb3VwTWl4LCBwcm9icyA9IGMoMC4yNSwgMC41MCwgMC43NSkpLCBkaWdpdHMgPSAyKQ0KcHJpbnQocGVyY2VudGlsZXMpDQpgYGANCg0KYGBge3J9DQpncm91cG1peF9yYW5nb3MgPC0gZGF0YS5mcmFtZSgNCiAgUmFuZ28gPSBjKCJSaWVzZ28iLCAiRXN0YWJsZSIsICJPcG9ydHVuaWRhZCIpLA0KICBEZXNkZSA9IGMoMCwgcGVyY2VudGlsZXNbMV0sIHBlcmNlbnRpbGVzWzNdKSwNCiAgSGFzdGEgPSBjKHBlcmNlbnRpbGVzWzFdLCBwZXJjZW50aWxlc1szXSwgMTAwKQ0KKQ0KDQpwcmludChncm91cG1peF9yYW5nb3MpDQpgYGANCg0KKipJbnRlcnByZXRhY2nDs24qKg0KDQpFbiBsb3Mgw7psdGltb3MgdHJlcyBtZXNlcyBkZWwgMjAyNCBsYSBtw6l0cmljYSBwcm9tZWRpbyA1Ljg2JSwgZGVudHJvIGRlbCByYW5nbyBOb3JtYWwuIExvIGN1YWwgaW5kaWNhIHF1ZSBhIHBlc2FyIGRlIGVzdGFyIG1hbnRlbmllbmRvIGVsIHJlbmRpbWllbnRvIGNvbcO6biBwcmVzZW50YSBsYSBvcG9ydHVuaWRhZCBkZSBpbXB1bHNhciBsYSBhdHJhY2Npw7NuIGRlIGV2ZW50b3MuICAgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQprcGlfZGYgPC0gc3Vic2V0KGtwaV9kZiwgRmVjaGEgPj0gYXMuRGF0ZSgiMjAyMC0wMS0wMSIpKQ0KDQpiYWNrZ3JvdW5kX2JhbmRzIDwtIGRhdGEuZnJhbWUoDQogIHltaW4gPSBjKDAsIHBlcmNlbnRpbGVzWzFdLCBwZXJjZW50aWxlc1szXSksDQogIHltYXggPSBjKHBlcmNlbnRpbGVzWzFdLCBwZXJjZW50aWxlc1szXSwgMTAwKSwNCiAgZmlsbCA9IGMoIlJpZXNnbyIsICJFc3RhYmxlIiwgIk9wb3J0dW5pZGFkIikNCikNCg0KIyBHcsOhZmljbyBiYXNlIGNvbiBnZ3Bsb3QNCmcgPC0gZ2dwbG90KCkgKw0KICAjIFpvbmFzIGRlIGZvbmRvDQogIGdlb21fcmVjdChkYXRhID0gYmFja2dyb3VuZF9iYW5kcywNCiAgICAgICAgICAgIGFlcyh4bWluID0gbWluKGtwaV9kZiRGZWNoYSksIHhtYXggPSBtYXgoa3BpX2RmJEZlY2hhKSwNCiAgICAgICAgICAgICAgICB5bWluID0geW1pbiwgeW1heCA9IHltYXgsIGZpbGwgPSBmaWxsKSwNCiAgICAgICAgICAgIGFscGhhID0gMC4yKSArDQogICMgTMOtbmVhIGRlIGV2b2x1Y2nDs24gZGVsIEtQSQ0KICBnZW9tX2xpbmUoZGF0YSA9IGtwaV9kZiwgYWVzKHggPSBGZWNoYSwgeSA9IEdyb3VwTWl4KSwgY29sb3IgPSAiIzJjM2U1MCIsIHNpemUgPSAxKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IGtwaV9kZiwgYWVzKHggPSBGZWNoYSwgeSA9IEdyb3VwTWl4LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoIkZlY2hhOiIsIEZlY2hhLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5Hcm91cCBNaXg6Iiwgcm91bmQoR3JvdXBNaXgsIDIpLCAiJSIpKSwNCiAgICAgICAgICAgICBjb2xvciA9ICIjMjk4MGI5Iiwgc2l6ZSA9IDIpICsNCiAgIyBMw61uZWFzIGhvcml6b250YWxlcyBkZSByZWZlcmVuY2lhDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IHBlcmNlbnRpbGVzWzFdLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJyZWQiKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IHBlcmNlbnRpbGVzWzJdLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IHBlcmNlbnRpbGVzWzNdLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJncmVlbiIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiUmllc2dvIiA9ICJyZWQiLCAiRXN0YWJsZSIgPSAib3JhbmdlIiwgIk9wb3J0dW5pZGFkIiA9ICJncmVlbiIpKSArDQogIGxhYnModGl0bGUgPSAiRXZvbHVjacOzbiBkZWwgS1BJIEdyb3VwIE1peCBlbiBsYSBaTU0iLA0KICAgICAgIHN1YnRpdGxlID0gIkNvbiByYW5nb3MgZGUgaW50ZXJwcmV0YWNpw7NuOiBSaWVzZ28sIEVzdGFibGUsIE9wb3J0dW5pZGFkIiwNCiAgICAgICB4ID0gIkZlY2hhIiwgeSA9ICJHcm91cCBNaXggKCUpIiwgZmlsbCA9ICJSYW5nbyBDcsOtdGljbyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCiMgQ29udmVydGlyIGEgZ3LDoWZpY28gaW50ZXJhY3Rpdm8NCnBsb3RseTo6Z2dwbG90bHkoZywgdG9vbHRpcCA9ICJ0ZXh0IikNCg0KYGBgDQoNCmBgYHtyfQ0KdGFibGFfZmluYWwgPC0gZGF0YS5mcmFtZSgNCiAgIlJhbmdvIGRlbCBLUEkiID0gYygiMCUg4oCTIDMuMiUiLCAiMy4yJSDigJMgNi4xJSIsICI+Ni4xJSIpLA0KICBJbnRlcnByZXRhY2nDs24gPSBjKCJDcsOtdGljbyAvIFJpZXNnbyIsICJFc3RhYmxlIC8gTm9ybWFsIiwgIk9wb3J0dW5pZGFkIiksDQogICJBY2Npw7NuIEVzdHJhdMOpZ2ljYSIgPSBjKCJSZWZvcnphciBhdHJhY2Npw7NuIGRlIGV2ZW50b3MgZ3JhbmRlcyIsICJNYW50ZW5lciB5IG1vbml0b3JlYXIgcmVsYWNpb25lcyBPQ1YiLCAiUHJvbW92ZXIgaW52ZXJzaW9uZXMgZW4gdHVyaXNtbyBkZSByZXVuaW9uZXMiKQ0KKQ0KDQp0YWJsYV9maW5hbA0KYGBgDQoNCg0KIyMjIFRlcmNlciBpbmRpY2Fkb3INCg0KKipJbmR1c3RyaWEgVHVyaXNtbyBkZSBOZWdvY2lvczogw41uZGljZSBkZSBJbXBhY3RvIGRlbCBUdXJpc21vIGRlIE5lZ29jaW9zIChJSVROKSoqDQoNCkNvbiBiYXNlIGVuIGxvIGFudGVyaW9yLCBzZSBjb25zdHJ1eWUgdW4gS1BJIGNvbXB1ZXN0byBvIMOtbmRpY2UgYWdyZWdhZG9yIHF1ZSBjb25jZW50cmUgdW5hIHZpc2nDs24gc2ludMOpdGljYSBwZXJvIGludGVncmFsIGRlbCBpbXBhY3RvIGRlbCBUdXJpc21vIGRlIE5lZ29jaW9zIGVuIGxhIFpvbmEgTWV0cm9wb2xpdGFuYSBkZSBNb250ZXJyZXkgKFpNTSksIGVzcGVjaWFsbWVudGUgY29uc2lkZXJhbmRvIGxhIGNlcmNhbsOtYSBkZSBldmVudG9zIGNvbW8gZWwgTXVuZGlhbCBGSUZBIDIwMjYuICANCg0KRWwgKirDjW5kaWNlIGRlIEltcGFjdG8gZGVsIFR1cmlzbW8gZGUgTmVnb2Npb3MgKElJVE4pKiogZXMgdW4gaW5kaWNhZG9yIGNvbXB1ZXN0byBxdWUgcmVmbGVqYSBlbCBpbXBhY3RvIHRvdGFsIGRlbCB0dXJpc21vIGRlIG5lZ29jaW9zIGVuIGxhIGVjb25vbcOtYSByZWdpb25hbCBhIHBhcnRpciBkZSB0cmVzIGRpbWVuc2lvbmVzIGNsYXZlOg0KDQotICoqRGVycmFtYSBFY29uw7NtaWNhIEdlbmVyYWRhKio6IHBvbmRlcmEgZWwgZWZlY3RvIG1vbmV0YXJpbyBkZWwgdHVyaXNtbyBkZSBuZWdvY2lvcy4NCg0KLSAqKlBhcnRpY2lwYWNpw7NuIGRlIE9jdXBhY2nDs24gSG90ZWxlcmEgcG9yIEV2ZW50b3MgZGUgTmVnb2Npb3MqKjogbWlkZSBsYSBpbnRlbnNpZGFkIGRlbCB0dXJpc21vIGRlIG5lZ29jaW9zIGZyZW50ZSBhbCB0dXJpc21vIGdlbmVyYWwuDQoNCi0gKipOw7ptZXJvIHkgRXNjYWxhIGRlIEV2ZW50b3MgUmVhbGl6YWRvcyoqOiBjYXB0dXJhIGxhIGRpbsOhbWljYSB5IHZvbHVtZW4gZGUgbGEgYWN0aXZpZGFkLg0KDQpTZSBvYnNlcnZhIHF1ZSBsYSByYcOteiBjdWFkcmFkYSBhcGxpY2FkYSBhIGxhIGRlcnJhbWEgZWNvbsOzbWljYSBvdG9yZ2EgbWF5b3IgcGVzbyBhbCBjb21wb25lbnRlIGVjb27Ds21pY28sIHNpbiBxdWUgZXN0ZSBkb21pbmUgcG9yIGNvbXBsZXRvLiBQb3Igc3UgcGFydGUsIGxhcyByYcOtY2VzIHBvbmRlcmFkYXMgZGUgbG9zIG90cm9zIGRvcyBpbmRpY2Fkb3JlcyBjYXB0dXJhbiBhZGVjdWFkYW1lbnRlIGVsIGRpbmFtaXNtbyB5IGVsIHVzbyBkZSBpbmZyYWVzdHJ1Y3R1cmEgYXNvY2lhZGEgYWwgdHVyaXNtbyBkZSBuZWdvY2lvcy4NCg0KKipFc2NhbGEgZGUgSW50ZXJwcmV0YWNpw7NuIGRlbCBJSVROKioNCg0KLSAqKlZhbG9yIGRlbCBJSVROID4gMS4wMCoqICANCiAgLSAqKk5pdmVsIGRlIEltcGFjdG86KiogQWx0byBpbXBhY3RvICANCiAgLSAqKkludGVycHJldGFjacOzbiBFc3RyYXTDqWdpY2E6KiogRWwgdHVyaXNtbyBkZSBuZWdvY2lvcyBlc3TDoSBzdXBlcmFuZG8gbWV0YXMgZXN0cmF0w6lnaWNhcy4NCg0KLSAqKlZhbG9yIGRlbCBJSVROIGVudHJlIDAuNzUgeSAxLjAwKiogIA0KICAtICoqTml2ZWwgZGUgSW1wYWN0bzoqKiBJbXBhY3RvIGFkZWN1YWRvIG8gZXNwZXJhZG8gIA0KICAtICoqSW50ZXJwcmV0YWNpw7NuIEVzdHJhdMOpZ2ljYToqKiBTZSBhdmFuemEgY29uZm9ybWUgYSBsbyBwcm95ZWN0YWRvOyBtYW50ZW5lciBlc3RyYXRlZ2lhIGFjdHVhbC4NCg0KLSAqKlZhbG9yIGRlbCBJSVROIGVudHJlIDAuNTAgeSAwLjc0KiogIA0KICAtICoqTml2ZWwgZGUgSW1wYWN0bzoqKiBJbXBhY3RvIG1vZGVyYWRvICANCiAgLSAqKkludGVycHJldGFjacOzbiBFc3RyYXTDqWdpY2E6KiogUmVxdWllcmUgYWp1c3RlcyBlbiBwcm9tb2Npw7NuIG8gbG9nw61zdGljYSBkZSBldmVudG9zLg0KDQotICoqVmFsb3IgZGVsIElJVE4gPCAwLjUwKiogIA0KICAtICoqTml2ZWwgZGUgSW1wYWN0bzoqKiBCYWpvIGltcGFjdG8gIA0KICAtICoqSW50ZXJwcmV0YWNpw7NuIEVzdHJhdMOpZ2ljYToqKiBFcyBuZWNlc2FyaW8gcmVkaXNlw7FhciBsYSBlc3RyYXRlZ2lhOyBzdWJ1dGlsaXphY2nDs24gZGUgcmVjdXJzb3MuDQoNClNpbiBlbWJhcmdvLCBzZSBvYnNlcnZhIHF1ZSB1bmEgbWV0YSBmaWphIGltcGxpY2EgcXVlIGVsIEtQSSBlc3RhcsOhIGVuIGNvbnN0YW50ZSBhdW1lbnRvLCBwb3IgZW5kZSwgc2UgcmVhbGl6YW4gYWx0ZXJuYXRpdmFzIGRlIHZpc3VhbGl6YWNpw7NuIGRlbCBpbmRpY2Fkb3IgY29uIGVsIGZpbiBkZSBubyBzb2xhbWVudGUgZGV0ZXJtaW5hciB1biBpbXBhY3RvIA0KDQoNCioqSUlUTiBtZW5zdWFsIChubyBhY3VtdWxhZG8pKioNCg0KKiBNaWRlIGVsIGRlc2VtcGXDsW8gcmVhbCBkZSBjYWRhIG1lcyBmcmVudGUgYSBsYXMgbWV0YXMgbWVuc3VhbGVzIGVzdGltYWRhcy4NCg0KKiBWZW50YWphOiBEZXRlY3RhIGRlIGlubWVkaWF0byBzaSB1biBtZXMgZXN0w6EgcG9yIGRlYmFqbyBkZWwgb2JqZXRpdm8uDQoNCiogT2JzZXJ2YWNpw7NuOiBMb3MgcHJpbWVyb3MgY3VhdHJvIG1lc2VzIGVzdMOhbiBwb3IgZGViYWpvIGRlIDAuNTAsIGEgZXhjZXBjacOzbiBkZSBGZWJyZXJvLCBlbCBjdWFsIGp1bnRvIGNvbiBNYXlvLCBBZ29zdG8sIFNlcHRpZW1icmUsIE9jdHVicmUgeSBOb3ZpZW1icmUgYWxjYW56YW4gdW4gaW1wYWN0byBtb2RlcmFkby4NCg0KDQoqKklJVE4gYWN1bXVsYWRvIGFqdXN0YWRvKioNCg0KKiBDb21wYXJhIGVsIGFjdW11bGFkbyByZWFsIGhhc3RhIGVsIG1lcyBjb24gZWwgYWN1bXVsYWRvIGVzcGVyYWRvLg0KDQoqIFZlbnRhamE6IEV2YWzDumEgc2kgdmFzIGFkZWxhbnRhZG8gbyBhdHJhc2FkbyBlbiBlbCBhw7FvLg0KDQoqIE9ic2VydmFjacOzbjogRWwgw61uZGljZSBzdXBlcmEgMSBhIHBhcnRpciBkZSBtYXJ6b+KAk2FicmlsLCBsbyBxdWUgaW5kaWNhIHF1ZSBlbCBkZXNlbXBlw7FvIGFjdW11bGFkbyB5YSB2YSBwb3IgZGVsYW50ZSBkZWwgcml0bW8gZXNwZXJhZG8uDQoNCioqU3ViaW5kaWNhZG9yZXMgaW5kaXZpZHVhbGVzKioNCg0KKiBQZXJtaXRlbiBhaXNsYXIgZWwgYW7DoWxpc2lzOiBzYWJlciBzaSBsb3MgYXZhbmNlcyBzb24gZ3JhY2lhcyBhIGRlcnJhbWEsIG9jdXBhY2nDs24gbyBldmVudG9zLg0KDQoqIExhIGRlcnJhbWEgc2UgY29tcG9ydGEgbXV5IGJpZW4gZGVzZGUgbWFyem8uDQoNCiogTGEgb2N1cGFjacOzbiBkZSBjdWFydG9zIHBvciBuZWdvY2lvcyBlc3TDoSBtw6FzIGVzdGFibGUgeSBlbiBhbGd1bm9zIG1lc2VzIHBvciBkZWJham8gZGUgMS4NCg0KKiBMb3MgZXZlbnRvcyBzb24gY2xhdmUgcGFyYSBlbCBjcmVjaW1pZW50byBkZXNkZSBqdWxpbyBlbiBhZGVsYW50ZS4NCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KZGZfT0NWIDwtIHJlYWQueGxzeCgiVGFibGFfTWFjcm9fRXZlbnRvc09DVi54bHN4IikNCg0KIyBDb252ZXJ0aXIgYSBSZWFsZXMNCmRmX09DViREZXJyYW1hPC0gKGRmX09DViREZXJyYW1hL2RmX09DViRJTlBDKSoxMDANCg0KIyBDcmVhciB1bmEgY29sdW1uYSBkZSBmZWNoYSBjb21iaW5hbmRvIEHDsW8geSBNZXMNCmRmX09DViRGZWNoYSA8LSBhcy5EYXRlKHBhc3RlKGRmX09DViRBw7FvLCBkZl9PQ1YkTWVzTm9tYnJlLCAiMDEiLCBzZXAgPSAiLSIpLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQojIEZpbHRyYXIgbG9zIGRhdG9zIGRlc2RlIGVuZXJvIGRlIDIwMjMgZW4gYWRlbGFudGUNCmRmX09DVl9maWx0ZXJlZCA8LSBzdWJzZXQoZGZfT0NWLCBGZWNoYSA+PSBhcy5EYXRlKCIyMDIzLTAxLTAxIikpDQoNCiMgRWxpbWluYXIgbGFzIGNvbHVtbmFzICJOb2NoZXMiIHkgIkRlc2NyaXBjaW9uIg0KZGZfT0NWX2NsZWFuIDwtIGRmX09DVl9maWx0ZXJlZFssIG5hbWVzKGRmX09DVl9maWx0ZXJlZCkgJWluJSBjKA0KICAiRmVjaGEiLA0KICAiQcOxbyIsDQogICJNZXNOb21icmUiLA0KICAiRXZlbnRvcyIsDQogICJDdWFydG9zIiwNCiAgIkFzaXN0ZW50ZXMiLA0KICAiRGVycmFtYSIsDQogICIlT2N1cGFjaW9uX0hvdGVsZXMiLA0KICAiTGxlZ2FkYV9UdXJfRXh0IiwNCiAgIkxsZWdhZGFfVHVyX05hYyINCildDQoNCg0KIyBGaWx0cmFyIHNvbG8gbGFzIGNvbHVtbmFzIG51bcOpcmljYXMNCmRmX09DVl9udW1lcmljIDwtIGRmX09DVl9jbGVhbltzYXBwbHkoZGZfT0NWX2NsZWFuLCBpcy5udW1lcmljKV0NCg0KIyBNZXRhcyBjb25zdGFudGVzIHBhcmEgMjAyMw0KTWV0YV9kZXJyYW1hIDwtIHN1bShkZl9PQ1ZfbnVtZXJpYyREZXJyYW1hW2RmX09DVl9udW1lcmljJEHDsW8gPT0gMjAyM10pDQpNZXRhX2V2ZW50b3MgPC0gc3VtKGRmX09DVl9udW1lcmljJEV2ZW50b3NbZGZfT0NWX251bWVyaWMkQcOxbyA9PSAyMDIzXSkNCg0KQ3VhcnRvc19vY3VwYWRvc19tZW5zdWFsIDwtIGMoMjkyNzQ5LCAzMTEyMzEsIDM0NDAwNiwgMzQxMDM4LCAzNDQ4MjAsIDMxMjM5NywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDM1NDIzNywgMzU2ODY3LCAzMjYwMDksIDM3MDk2NywgMzgyMDcyLCAzMTA3NjcpDQoNCiMgRmlsdHJhciBkYXRvcyAyMDI0IHkgb3JkZW5hciBwb3IgTWVzDQpkZl8yMDI0IDwtIGRmX09DVl9udW1lcmljW2RmX09DVl9udW1lcmljJEHDsW8gPT0gMjAyNCwgXQ0KZGZfMjAyNCA8LSBkZl8yMDI0W29yZGVyKGRmXzIwMjQkTWVzTm9tYnJlKSwgXQ0KDQojIENhbGN1bGFyIGFjdW11bGFkb3MgcGFyYSBEZXJyYW1hLCBDdWFydG9zIHkgRXZlbnRvcw0KZGZfMjAyNCREZXJyYW1hX2FjdW11bGFkYSA8LSBjdW1zdW0oZGZfMjAyNCREZXJyYW1hKQ0KZGZfMjAyNCRDdWFydG9zX2FjdW11bGFkb3MgPC0gY3Vtc3VtKGRmXzIwMjQkQ3VhcnRvcykNCmRmXzIwMjQkRXZlbnRvc19hY3VtdWxhZG9zIDwtIGN1bXN1bShkZl8yMDI0JEV2ZW50b3MpDQoNCiMgQWdyZWdhciBjb2x1bW5hIGNvbiBlbCBDdWFydG9zIG9jdXBhZG9zIG1lbnN1YWwgKGRlbm9taW5hZG9yIHZhcmlhYmxlIHNlZ8O6biBtZXMpDQpkZl8yMDI0JEN1YXJ0b3Nfb2N1cGFkb3NfbWVzIDwtIEN1YXJ0b3Nfb2N1cGFkb3NfbWVuc3VhbA0KDQojIENhbGN1bGFyIElJVE5fdCBjb24gZWwgZGVub21pbmFkb3IgdmFyaWFibGUgbWVzIGEgbWVzDQpkZl8yMDI0JElJVE5fdCA8LSB3aXRoKGRmXzIwMjQsDQogICAgICAgICAgICAgICAgICAgICAgIChEZXJyYW1hX2FjdW11bGFkYSAvIE1ldGFfZGVycmFtYSleMC41ICoNCiAgICAgICAgICAgICAgICAgICAgICAgKEN1YXJ0b3NfYWN1bXVsYWRvcyAvIEN1YXJ0b3Nfb2N1cGFkb3NfbWVzKV4wLjI1ICoNCiAgICAgICAgICAgICAgICAgICAgICAgKEV2ZW50b3NfYWN1bXVsYWRvcyAvIE1ldGFfZXZlbnRvcyleMC4yNSkNCg0KcHJpbnQoZGZfMjAyNFssIGMoIk1lc05vbWJyZSIsICJEZXJyYW1hX2FjdW11bGFkYSIsICJDdWFydG9zX2FjdW11bGFkb3MiLCAiQ3VhcnRvc19vY3VwYWRvc19tZXMiLCAiRXZlbnRvc19hY3VtdWxhZG9zIiwgIklJVE5fdCIpXSkNCg0KbGlicmFyeShnZ3Bsb3QyKQ0KZ2dwbG90KGRmXzIwMjQsIGFlcyh4ID0gZmFjdG9yKE1lc05vbWJyZSksIHkgPSBJSVROX3QsIGdyb3VwID0gMSkpICsNCiAgZ2VvbV9saW5lKGNvbG9yID0gImRhcmtncmVlbiIsIHNpemUgPSAxKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsNCiAgbGFicyh0aXRsZSA9ICLDjW5kaWNlIElJVE5fdCBhY3VtdWxhZG8gcG9yIG1lcyAyMDI0IiwNCiAgICAgICB4ID0gIk1lcyIsDQogICAgICAgeSA9ICJJSVROX3QiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCg0KYGBge3J9DQojIGRmX09DVl9udW1lcmljIGRlYmUgdGVuZXIgY29sdW1uYXM6IEHDsW8sIE1lcyAobsO6bWVybyksIERlcnJhbWENCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KbGlicmFyeShkYXRhLnRhYmxlKQ0KbGlicmFyeSh0aWR5cikNCg0KIyBGaWx0cmFyIGHDsW9zIGhpc3TDs3JpY29zIChlai4gMjAyMCBhIDIwMjMpDQpkZl9oaXN0IDwtIGRmX09DVl9udW1lcmljICU+JSBmaWx0ZXIoQcOxbyA+PSAyMDIzICYgQcOxbyA8PSAyMDI0KQ0KDQojIENhbGN1bGFyIGRlcnJhbWEgdG90YWwgcG9yIGHDsW8NCmRlcnJhbWFfYW51YWwgPC0gZGZfaGlzdCAlPiUNCiAgZ3JvdXBfYnkoQcOxbykgJT4lDQogIHN1bW1hcmlzZShEZXJyYW1hX3RvdGFsX2FudWFsID0gc3VtKERlcnJhbWEpKQ0KDQojIFVuaXIgY29uIGVsIG9yaWdpbmFsIHBhcmEgY2FsY3VsYXIgcHJvcG9yY2nDs24gbWVuc3VhbA0KZGZfaGlzdCA8LSBkZl9oaXN0ICU+JQ0KICBsZWZ0X2pvaW4oZGVycmFtYV9hbnVhbCwgYnkgPSAiQcOxbyIpICU+JQ0KICBtdXRhdGUoUHJvcG9yY2lvbl9tZW5zdWFsID0gRGVycmFtYSAvIERlcnJhbWFfdG90YWxfYW51YWwpDQoNCiMgUHJvbWVkaW8gcG9yIG1lcyBlbnRyZSBhw7Fvcw0KcGVzb3NfZXN0YWNpb25hbGVzIDwtIGRmX2hpc3QgJT4lDQogIGdyb3VwX2J5KE1lc05vbWJyZSkgJT4lDQogIHN1bW1hcmlzZShQZXNvID0gbWVhbihQcm9wb3JjaW9uX21lbnN1YWwpKSAlPiUNCiAgYXJyYW5nZShNZXNOb21icmUpDQoNCiMgVmVjdG9yIGRlIHBlc29zIChzdW1hIOKJiCAxKQ0KcGVzb3NfZXN0YWNpb25hbGVzX3ZlY3RvciA8LSBwZXNvc19lc3RhY2lvbmFsZXMkUGVzbw0KcHJpbnQocGVzb3NfZXN0YWNpb25hbGVzX3ZlY3RvcikNCg0KIyBDYWxjdWxhciBtZXRhcyBtZW5zdWFsZXMNCnBlc29zX2VzdGFjaW9uYWxlcyA8LSBjKA0KICAwLjAwOTA3MjkyOCwgMC4wNTYyNzg2MTIsIDAuMDU5NzgyMjg1LCAwLjEwNzYyNjMxNywNCiAgMC4wNTA4OTUwOTIsIDAuMDUyOTcwMjI3LCAwLjEwMjAyODA1NiwgMC4xMDc3NDI1NTYsDQogIDAuMTAxMDE3NzMyLCAwLjE0MDUxNDg1OSwgMC4xODIxNjc5MjQsIDAuMDI5OTAzNDEyDQopDQoNCk1ldGFfZGVycmFtYV9tZW5zdWFsIDwtIE1ldGFfZGVycmFtYSAqIHBlc29zX2VzdGFjaW9uYWxlcw0KTWV0YV9ldmVudG9zX21lbnN1YWwgPC0gTWV0YV9ldmVudG9zICogcGVzb3NfZXN0YWNpb25hbGVzDQoNCiMgw41uZGljZSBtZW5zdWFsIE5PIGFjdW11bGFkbw0KZGZfMjAyNCRJSVROX21lbnN1YWwgPC0gd2l0aChkZl8yMDI0LA0KICAoRGVycmFtYSAvIE1ldGFfZGVycmFtYV9tZW5zdWFsKV4wLjUgKg0KICAoQ3VhcnRvcyAvIEN1YXJ0b3Nfb2N1cGFkb3NfbWVzKV4wLjI1ICoNCiAgKEV2ZW50b3MgLyBNZXRhX2V2ZW50b3NfbWVuc3VhbCleMC4yNSkNCg0KIyBNZXRhIGFjdW11bGFkYSBlc3BlcmFkYSBwb3IgbWVzIChsaW5lYWwpDQpkZl8yMDI0JE1ldGFfZGVycmFtYV9hY3VtdWxhZGEgPC0gTWV0YV9kZXJyYW1hICogKDE6MTIpLzEyDQpkZl8yMDI0JE1ldGFfZXZlbnRvc19hY3VtdWxhZG9zIDwtIE1ldGFfZXZlbnRvcyAqICgxOjEyKS8xMg0KDQpkZl8yMDI0JElJVE5fdF9hanVzdGFkbyA8LSB3aXRoKGRmXzIwMjQsDQogIChEZXJyYW1hX2FjdW11bGFkYSAvIE1ldGFfZGVycmFtYV9hY3VtdWxhZGEpXjAuNSAqDQogIChDdWFydG9zX2FjdW11bGFkb3MgLyBDdWFydG9zX29jdXBhZG9zX21lcyleMC4yNSAqDQogIChFdmVudG9zX2FjdW11bGFkb3MgLyBNZXRhX2V2ZW50b3NfYWN1bXVsYWRvcyleMC4yNSkNCg0KZGZfMjAyNCRJbmRpY2Fkb3JfRGVycmFtYSA8LSBkZl8yMDI0JERlcnJhbWEgLyBNZXRhX2RlcnJhbWFfbWVuc3VhbA0KZGZfMjAyNCRJbmRpY2Fkb3JfQ3VhcnRvcyA8LSBkZl8yMDI0JEN1YXJ0b3MgLyBkZl8yMDI0JEN1YXJ0b3Nfb2N1cGFkb3NfbWVzDQpkZl8yMDI0JEluZGljYWRvcl9FdmVudG9zIDwtIGRmXzIwMjQkRXZlbnRvcyAvIE1ldGFfZXZlbnRvc19tZW5zdWFsDQoNCiMgR3LDoWZpY29zDQoNCiMgSUlUTiBhY3VtdWxhZG8gYWp1c3RhZG8NCmdncGxvdChkZl8yMDI0LCBhZXMoeCA9IGZhY3RvcihNZXNOb21icmUsIGxldmVscyA9IHVuaXF1ZShNZXNOb21icmUpKSwgeSA9IElJVE5fdF9hanVzdGFkbykpICsNCiAgZ2VvbV9saW5lKGdyb3VwID0gMSwgY29sb3IgPSAiZGFya2dyZWVuIiwgc2l6ZSA9IDEuMikgKw0KICBnZW9tX3BvaW50KHNpemUgPSAzLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImdyYXkiKSArDQogIGxhYnModGl0bGUgPSAiSUlUTiBBY3VtdWxhZG8gQWp1c3RhZG8gcG9yIE1lcyIsDQogICAgICAgeCA9ICJNZXMiLA0KICAgICAgIHkgPSAiw41uZGljZSBJSVROIGFjdW11bGFkbyBhanVzdGFkbyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCiMgU3ViaW5kaWNhZG9yZXMNCnN1YmluZGljYWRvcmVzIDwtIGRmXzIwMjRbLCBjKCJNZXNOb21icmUiLCAiSW5kaWNhZG9yX0RlcnJhbWEiLCAiSW5kaWNhZG9yX0V2ZW50b3MiKV0NCnN1YmluZGljYWRvcmVzX2xhcmdvIDwtIHBpdm90X2xvbmdlcihzdWJpbmRpY2Fkb3JlcywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29scyA9IC1NZXNOb21icmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiSW5kaWNhZG9yIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiVmFsb3IiKQ0KDQpnZ3Bsb3Qoc3ViaW5kaWNhZG9yZXNfbGFyZ28sIGFlcyh4ID0gZmFjdG9yKE1lc05vbWJyZSwgbGV2ZWxzID0gdW5pcXVlKE1lc05vbWJyZSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IFZhbG9yLCBjb2xvciA9IEluZGljYWRvciwgZ3JvdXAgPSBJbmRpY2Fkb3IpKSArDQogIGdlb21fbGluZShzaXplID0gMS4yKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiZ3JheSIpICsNCiAgbGFicyh0aXRsZSA9ICJTdWJpbmRpY2Fkb3JlcyBwb3IgVmFyaWFibGUgKE1lbnN1YWwpIiwNCiAgICAgICB4ID0gIk1lcyIsDQogICAgICAgeSA9ICJWYWxvciByZWxhdGl2byBhIG1ldGEiLA0KICAgICAgIGNvbG9yID0gIkluZGljYWRvciIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQoNCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KDQojIDEuIElJVE4gbWVuc3VhbA0KIyBDcmVhciB2YXJpYWJsZSBjYXRlZ8OzcmljYSBkZSBpbXBhY3RvIHNlZ8O6biB1bWJyYWxlcw0KZGZfMjAyNCA8LSBkZl8yMDI0ICU+JQ0KICBtdXRhdGUoTml2ZWxfSW1wYWN0byA9IGNhc2Vfd2hlbigNCiAgICBJSVROX21lbnN1YWwgPiAxLjAwIH4gIkFsdG8gaW1wYWN0byIsDQogICAgSUlUTl9tZW5zdWFsID49IDAuNzUgfiAiSW1wYWN0byBhZGVjdWFkbyIsDQogICAgSUlUTl9tZW5zdWFsID49IDAuNTAgfiAiSW1wYWN0byBtb2RlcmFkbyIsDQogICAgVFJVRSB+ICJCYWpvIGltcGFjdG8iDQogICkpDQoNCmNvbG9yZXNfaW1wYWN0byA8LSBjKA0KICAiQWx0byBpbXBhY3RvIiA9ICIjMWI5ZTc3IiwNCiAgIkltcGFjdG8gYWRlY3VhZG8iID0gIiM2NmE2MWUiLA0KICAiSW1wYWN0byBtb2RlcmFkbyIgPSAiI2U2YWIwMiIsDQogICJCYWpvIGltcGFjdG8iID0gIiNkOTVmMDIiDQopDQoNCiMgQ3JlYXIgZGF0YS5mcmFtZSBwYXJhIGxvcyByZWN0w6FuZ3Vsb3MgZGUgZm9uZG8NCmZvbmRvcyA8LSBkYXRhLmZyYW1lKA0KICB5bWluID0gYygwLCAwLjUwLCAwLjc1LCAxLjAwKSwNCiAgeW1heCA9IGMoMC41MCwgMC43NSwgMS4wMCwgbWF4KGRmXzIwMjQkSUlUTl9tZW5zdWFsLCBuYS5ybSA9IFRSVUUpICsgMC4xKSwNCiAgZmlsbCA9IGMoIkJham8gaW1wYWN0byIsICJJbXBhY3RvIG1vZGVyYWRvIiwgIkltcGFjdG8gYWRlY3VhZG8iLCAiQWx0byBpbXBhY3RvIikNCikNCg0KZm9uZG9zJHhtaW4gPC0gLUluZg0KZm9uZG9zJHhtYXggPC0gSW5mDQoNCmdncGxvdChkZl8yMDI0LCBhZXMoeCA9IGZhY3RvcihNZXNOb21icmUsIGxldmVscyA9IHVuaXF1ZShNZXNOb21icmUpKSwgeSA9IElJVE5fbWVuc3VhbCkpICsNCiAgZ2VvbV9yZWN0KGRhdGEgPSBmb25kb3MsIGFlcyh4bWluID0geG1pbiwgeG1heCA9IHhtYXgsIHltaW4gPSB5bWluLCB5bWF4ID0geW1heCwgZmlsbCA9IGZpbGwpLA0KICAgICAgICAgICAgaW5oZXJpdC5hZXMgPSBGQUxTRSwgYWxwaGEgPSAwLjE1KSArDQogIGdlb21fbGluZShncm91cCA9IDEsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEuMikgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IE5pdmVsX0ltcGFjdG8pLCBzaXplID0gMykgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3Jlc19pbXBhY3RvKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG9yZXNfaW1wYWN0bywgZ3VpZGUgPSAibm9uZSIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiZ3JheSIpICsNCiAgbGFicyh0aXRsZSA9ICJJSVROIE1lbnN1YWwgKE5vIEFjdW11bGFkbykiLA0KICAgICAgIHggPSAiTWVzIiwNCiAgICAgICB5ID0gIsONbmRpY2UgSUlUTiBtZW5zdWFsIiwNCiAgICAgICBjb2xvciA9ICJOaXZlbCBkZSBJbXBhY3RvIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikNCmBgYA0KDQoNCg0KIyMgKipSaWVzZ29zIHBhcmEgZWwgTXVuZGlhbCBGSUZBIDIwMjYqKg0KDQojIyMgQS4gSW5kdXN0cmlhIEhvdGVsZXJhDQoNCioqUmllc2dvIFBvdGVuY2lhbDogU2F0dXJhY2nDs24gZGUgbGEgQ2FwYWNpZGFkIHkgVm9sYXRpbGlkYWQgVGFyaWZhcmlhKioNCg0KRHVyYW50ZSBlbCBNdW5kaWFsIGRlIGxhIEZJRkEgbGEgZGVtYW5kYSBob3RlbGVyYSBzdWVsZSBkaXNwYXJhcnNlIGRlIG1hbmVyYSBhYnJ1cHRhLiBFbiBsYSBaTU0sIGRvbmRlIHlhIGV4aXN0ZSB1bmEgYWx0YSBjb25jZW50cmFjacOzbiBkZSBvZmVydGEgZW4gem9uYXMgY8OpbnRyaWNhcyB5IGRlIGx1am8gKE1vbnRlcnJleSB5IFNhbiBQZWRybyksIHVuIGluY3JlbWVudG8gbWFzaXZvIGRlIHZpc2l0YW50ZXMgcG9kcsOtYSBzdXBlcmFyIGxhIGNhcGFjaWRhZCBhY3R1YWwsIHByb3ZvY2FuZG86ICAgDQoNCiogRXNjYXNleiBkZSBoYWJpdGFjaW9uZXMgZGlzcG9uaWJsZXMgcGFyYSBzZWdtZW50b3Mgbm8gcmVsYWNpb25hZG9zIGFsIGV2ZW50bywgY29uIGVsIGNvbnNlY3VlbnRlIHJpZXNnbyBkZSBkZXNwbGF6YW1pZW50byBkZSBjbGllbnRlcyBoYWJpdHVhbGVzLiAgIA0KDQoqIEluY3JlbWVudG9zIGV4Y2VzaXZvcyBlbiBsYXMgdGFyaWZhcyAocHJpY2UgZ291Z2luZyksIHF1ZSwgc2kgYmllbiBnZW5lcmFuIGluZ3Jlc29zIGFkaWNpb25hbGVzIGVuIGVsIGNvcnRvIHBsYXpvLCBwdWVkZW4gZGVyaXZhciBlbiBjcsOtdGljYXMgbWVkacOhdGljYXMsIHF1ZWphcyBlbiBwbGF0YWZvcm1hcyBkZSByZXNlw7FhcyB5IGRhw7FvcyBhIGxhIHJlcHV0YWNpw7NuIGRlIGxhIGNpdWRhZCBjb21vIGRlc3Rpbm8uICAgDQoNClBvciBjb25zaWd1aWVudGUsIGNvbiBlbCBvYmpldGl2byBkZSBnYXJhbnRpemFyIHVuYSBleHBlcmllbmNpYSB0dXLDrXN0aWNhIGVxdWl0YXRpdmEgeSBvcmRlbmFkYSBkdXJhbnRlIGVsIHBlcmlvZG8gRklGQSwgc2UgcHJvcG9uZSB1bmEgZXN0cmF0ZWdpYSBlbmZvY2FkYSBlbiBsYSB0cmFuc3BhcmVuY2lhIHRhcmlmYXJpYSwgbGEgZGlzdHJpYnVjacOzbiBlZmljaWVudGUgZGUgbGEgZGVtYW5kYSB5IGxhIHByb3RlY2Npw7NuIGRlbCBjb25zdW1pZG9yLiBTZSByZWNvbWllbmRhIGVzdGFibGVjZXIgdW4gc2lzdGVtYSBkZSBtb25pdG9yZW8gZGluw6FtaWNvIGVuIGNvbGFib3JhY2nDs24gY29uIHBsYXRhZm9ybWFzIGNvbW8gQm9va2luZyBvIEV4cGVkaWEsIHF1ZSBlbWl0aXLDoSBhbGVydGFzIGN1YW5kbyBsb3MgcHJlY2lvcyBzdXBlcmVuIHVtYnJhbGVzIHByZWRlZmluaWRvcy4gUGFyYWxlbGFtZW50ZSwgc2UgbGFuemFyw6EgdW5hIGNhbXBhw7FhIGRlIGZvbWVudG8gYWwgdHVyaXNtbyBuYWNpb25hbCBwcmUtRklGQSwgY29uIHBhcXVldGVzIHByb21vY2lvbmFsZXMgcGFyYSBpbmNlbnRpdmFyIHJlc2VydmFzIGFudGljaXBhZGFzLiBBc2ltaXNtbywgcGFyYSBldml0YXIgbGEgc2F0dXJhY2nDs24gZGUgem9uYXMgcHJlbWl1bSwgc2UgaW1wdWxzYXLDoSBsYSBwcm9tb2Npw7NuIGRlIHpvbmFzIGhvdGVsZXJhcyBhbHRlcm5hcyBjb21vIEFwb2RhY2EsIEd1YWRhbHVwZSB5IFNhbnRhIENhdGFyaW5hLCBhcG95YWRhIGVuIGluZnJhZXN0cnVjdHVyYSB5IHRyYW5zcG9ydGUuIEZpbmFsbWVudGUsIHNlIGVzdGFibGVjZXLDoW4gYWxpYW56YXMgY29uIHBsYXRhZm9ybWFzIGRpZ2l0YWxlcyBwYXJhIHZlcmlmaWNhciBob3NwZWRhamVzIHRlbXBvcmFsZXMsIGluY29ycG9yYW5kbyBkaXN0aW50aXZvcyBkaWdpdGFsZXMgZGUgY29uZmlhbnphIHF1ZSBwcm90ZWphbiBhIGxvcyB2aXNpdGFudGVzIGRlIGZyYXVkZXMgZW4gbMOtbmVhLiANCg0KQ29uIGJhc2UgZW4gbGFzIGVzdHJhdGVnaWFzIGRlIG1pdGlnYWNpw7NuIHBsYW50ZWFkYXMsIHNlIHByb3BvbmUgdXRpbGl6YXIgZWwgaW5kaWNhZG9yIGRlICUgT2N1cGFjacOzbiBIb3RlbGVyYXlhIHNlYSB1dGlsaXphbmRvIHRhbCBjdWFsIGVsIHZhbG9yIG8gcmVhbGl6YW5kbyBlbCBzaWd1aWVudGUgY8OhbGN1bG86ICAlID0gKEN1YXJ0b3Mgb2N1cGFkb3MgLyBDdWFydG9zIGRpc3BvbmlibGVzKSDDlyAxMDAuIEFjb3JkZSBhIGxvcyBncsOhZmljb3MsIHNlIG9ic2VydmEgcXVlIGxhIG9jdXBhY2nDs24gaG90ZWxlcmEgbW9zdHLDsyB1bmEgdGVuZGVuY2lhIGZsdWN0dWFudGUgZW50cmUgZWwgNDAlIHkgNzAlLCBjb24gcGljb3Mgb2Nhc2lvbmFsZXMgc3VwZXJpb3JlcyBhbCA3NSUuIFNlIGlkZW50aWZpY8OzIHVuIHBhdHLDs24gZXN0YWNpb25hbCBzZW1hbmFsIGFzb2NpYWRvIHBvc2libGVtZW50ZSBhIGZpbmVzIGRlIHNlbWFuYSB5IHRlbXBvcmFkYXMgdmFjYWNpb25hbGVzLiBVbiBldmVudG8gZGlzcnVwdGl2byBwcm92b2PDsyB1bmEgY2HDrWRhIGFicnVwdGEgYSBuaXZlbGVzIHBvciBkZWJham8gZGVsIDEwJSwgc2VndWlkbyBkZSB1bmEgcmVjdXBlcmFjacOzbiBncmFkdWFsIHF1ZSBsbGV2w7MgbGEgb2N1cGFjacOzbiBhIGVzdGFiaWxpemFyc2UgbnVldmFtZW50ZSBlbnRyZSBlbCA2MCUgeSA3MCUuDQoNClNlIHJlY29taWVuZGEgcXVlIGEgZnV0dXJvIHNlIGludGVncmUgYWwgdmFsb3IgdW5hIGRpdmlzacOzbiB5YSBzZWEgcG9yIHpvbmEgeS9vIHBvciBzZWdtZW50by4gRGUgZXN0YSBtYW5lcmEsIHNlIGlkZW50aWZpY2Fyw61hbiBsb3MgcHVudG9zIGRlIHNhdHVyYWNpw7NuIG8gZGVzZXF1aWxpYnJpbyByZWdpb25hbCAoZWouIFNhbiBQZWRybyB2cyBHdWFkYWx1cGUpLg0KDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCg0KIyBDcmVhciB2YXJpYWJsZSBkZSBmZWNoYSBhIHBhcnRpciBkZSBBw5FPIHkgTUVTDQpkZiA8LSBkZiAlPiUNCiAgbXV0YXRlKEZlY2hhID0gYXMuRGF0ZShwYXN0ZShBw5FPLCBNRVMsICIwMSIsIHNlcCA9ICItIikpKQ0KDQojIEdyw6FmaWNvIGRlICVPY3VwYWNpb25faG90ZWxlcyBhIHRyYXbDqXMgZGVsIHRpZW1wbw0KZ2dwbG90KGRmLCBhZXMoeCA9IEZlY2hhLCB5ID0gYCVPY3VwYWNpb25fSG90ZWxlc2ApKSArDQogIGdlb21fbGluZShjb2xvciA9ICJzdGVlbGJsdWUiLCBzaXplID0gMS4yKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAic3RlZWxibHVlIikgKw0KICBsYWJzKHRpdGxlID0gIiUgZGUgT2N1cGFjacOzbiBIb3RlbGVyYSBhIGxvIGxhcmdvIGRlbCB0aWVtcG8iLA0KICAgICAgIHggPSAiRmVjaGEiLA0KICAgICAgIHkgPSAiJSBPY3VwYWNpw7NuIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KZGYkT2N1cGFjaW9uX1BvcmMgPC0gKGRmJEN1YXJ0b3NfT2N1cGFkb3MgLyBkZiRDdWFydG9zX0Rpc3BvbmlibGVzKSAqIDEwMA0KDQpnZ3Bsb3QoZGYsIGFlcyh4ID0gRmVjaGEsIHkgPSBPY3VwYWNpb25fUG9yYykpICsNCiAgZ2VvbV9saW5lKGNvbG9yID0gInN0ZWVsYmx1ZSIsIHNpemUgPSAxLjIpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJkYXJrYmx1ZSIsIHNpemUgPSAyKSArDQogIGxhYnModGl0bGUgPSAiJSBkZSBPY3VwYWNpw7NuIEhvdGVsZXJhIGEgbG8gbGFyZ28gZGVsIHRpZW1wbyIsDQogICAgICAgeCA9ICJGZWNoYSIsDQogICAgICAgeSA9ICIlIE9jdXBhY2nDs24iKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlYi0lWSIsIGRhdGVfYnJlYWtzID0gIjMgbW9udGhzIikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQpgYGANCg0KDQojIyMgQi4gSW5kdXN0cmlhIFR1cmlzbW8gZGUgTmVnb2Npb3MgIA0KDQoqKlJpZXNnbyBQb3RlbmNpYWw6IERlc3ZpbmN1bGFjacOzbiBlbnRyZSBFdmVudG9zIEZJRkEgeSBFdmVudG9zIGRlIE5lZ29jaW9zKioNCg0KRXhpc3RlIGxhIHBvc2liaWxpZGFkIGRlIHF1ZSBsb3MgZXZlbnRvcyBvcmdhbml6YWRvcyBwb3IgRklGQSBlbiBsYSBaTU0sIHByaW5jaXBhbG1lbnRlIHBhcnRpZG9zIHkgYWN0aXZpZGFkZXMgZGVwb3J0aXZhcywgbm8gc2UgYXJ0aWN1bGVuIGRlIGZvcm1hIGVmZWN0aXZhIGNvbiBsYSBhZ2VuZGEgZGUgdHVyaXNtbyBkZSBuZWdvY2lvcyAoY29uZ3Jlc29zLCBmZXJpYXMsIHJ1ZWRhcyBkZSBpbnZlcnNpw7NuLCBuZXR3b3JraW5nIGVtcHJlc2FyaWFsKSwgbG8gcXVlIHJlc3VsdGFyw61hIGVuOg0KKiBTdWJ1dGlsaXphY2nDs24gZGUgbGEgaW5mcmFlc3RydWN0dXJhIHR1csOtc3RpY2EuICAgDQoNCiogQmFqYSBjYXB0YWNpw7NuIGRlIGRlcnJhbWEgZWNvbsOzbWljYSBwb3IgcGFydGUgZGVsIHNlY3RvciBlbXByZXNhcmlhbCBsb2NhbC4gICANCg0KKiBQw6lyZGlkYSBkZSB1bmEgdmVudGFuYSBkZSBvcG9ydHVuaWRhZCDDum5pY2EgcGFyYSBwb3NpY2lvbmFyIGEgTW9udGVycmV5IGNvbW8gZGVzdGlubyBNSUNFIChNZWV0aW5ncywgSW5jZW50aXZlcywgQ29uZmVyZW5jZXMsIEV4aGliaXRpb25zKS4gICANCg0KTG8gYW50ZXJpb3IgdGllbmUgZWwgcG90ZW5jaWFsIGRlIGdlbmVyYXIgbWF5b3IgaW1wYWN0byB5IHByb2JhYmlsaWRhZCBlbiByaWVzZ29zIGNvbW86ICAgDQoNCiogKk1lbm9yIGFmbHVlbmNpYSBkZSB2aXNpdGFudGVzIGNvcnBvcmF0aXZvczoqIFNlIHRyYWR1Y2UgZW4gdW5hIGJhamEgb2N1cGFjacOzbiBlbiBob3RlbGVzIG9yaWVudGFkb3MgYWwgc2VnbWVudG8gZWplY3V0aXZvLCBsbyBjdWFsIGFmZWN0YSBkaXJlY3RhbWVudGUgbGEgcmVudGFiaWxpZGFkIGRlIGxhIGluZnJhZXN0cnVjdHVyYSBkaXNlw7FhZGEgcGFyYSBlc3RlIHRpcG8gZGUgdHVyaXNtby4gICANCg0KKiAqQWZlY3RhY2nDs24gZW4gZWNvbm9tw61hIGxvY2FsOiogTGEgZmFsdGEgZGUgdmlzaXRhbnRlcyBkZSBuZWdvY2lvcyBpbXBsaWNhIHVuYSBww6lyZGlkYSBzaWduaWZpY2F0aXZhIGRlIGluZ3Jlc29zIHBvdGVuY2lhbGVzIHBhcmEgc2VjdG9yZXMgY2xhdmUgY29tbyBsYSBob3NwaXRhbGlkYWQsIGVsIHRyYW5zcG9ydGUgeSBsb3Mgc2VydmljaW9zIGVtcHJlc2FyaWFsZXMgKEIyQiksIGxpbWl0YW5kbyBlbCBkaW5hbWlzbW8gZWNvbsOzbWljbyBkZSBsYSBjaXVkYWQuICANCg0KKiAqQmFqbyBQb3NpY2lvbmFtaWVudG8gZGUgTW9udGVycmV5OiogQWwgbm8gYXByb3ZlY2hhciBvcG9ydHVuaWRhZGVzIHBhcmEgYXRyYWVyIGdyYW5kZXMgZXZlbnRvcyBpbnRlcm5hY2lvbmFsZXMsIGVzcGVjaWFsbWVudGUgYSBwYXJ0aXIgZGUgMjAyNiwgTW9udGVycmV5IHBpZXJkZSBsYSBwb3NpYmlsaWRhZCBkZSBwb3NpY2lvbmFyc2UgY29tbyB1biBkZXN0aW5vIGVzdHJhdMOpZ2ljbyBlbiBlbCBtYXBhIGdsb2JhbCBkZSBjb25ncmVzb3MgeSBjb252ZW5jaW9uZXMuICAgDQoNCiogKkluZWZpY2llbnRlIENvb3JkaW5hY2nDs24gaW5zdGl0dWNpb25hbDoqIEV4aXN0ZW4gcHJvYmxlbWFzIGRlIGR1cGxpY2lkYWQgZGUgZXNmdWVyem9zIGVudHJlIGRpc3RpbnRhcyBlbnRpZGFkZXMsIGFzw60gY29tbyB1bmEgZGlzcGVyc2nDs24gZGUgcmVjdXJzb3MgeSB1bmEgY2FsZW5kYXJpemFjacOzbiBpbmVmaWNheiwgbG8gcXVlIHJlZHVjZSBsYSBlZmVjdGl2aWRhZCBkZSBsYXMgZXN0cmF0ZWdpYXMgZGUgcHJvbW9jacOzbiB5IGF0cmFjY2nDs24gZGUgZXZlbnRvcy4gIA0KDQpQb3IgbG8gdGFudG8sIGNvbiBlbCBmaW4gZGUgbWl0aWdhciBsb3MgaW1wYWN0b3MgbmVnYXRpdm9zIGVuIGVsIHR1cmlzbW8gZGUgbmVnb2Npb3MgeSBjYXBpdGFsaXphciBsYXMgb3BvcnR1bmlkYWRlcyBxdWUgYnJpbmRhIGVsIE11bmRpYWwgMjAyNiwgc2UgcHJvcG9uZSB1bmEgZXN0cmF0ZWdpYSBpbnRlZ3JhbCBjZW50cmFkYSBlbiBsYSBjb29yZGluYWNpw7NuIHDDumJsaWNvLXByaXZhZGEgeSBsYSBwbGFuaWZpY2FjacOzbiBhbnRpY2lwYWRhLiBMYSBNZXNhIGRlIEludGVncmFjacOzbiBGSUZB4oCTT0NW4oCTRW1wcmVzYXJpYWRvICgyMDI1KSBmdW5jaW9uYXLDoSBjb21vIHBsYXRhZm9ybWEgY29sYWJvcmF0aXZhIHBhcmEgYWxpbmVhciBjYWxlbmRhcmlvcywgc2VkZXMsIHDDumJsaWNvcyBvYmpldGl2b3MgeSBwYXF1ZXRlcyBpbnRlZ3JhZG9zLCBldml0YW5kbyBkdXBsaWNpZGFkZXMgeSBtYXhpbWl6YW5kbyBzaW5lcmdpYXMuIFNlIGRpc2XDsWFyw6EgdW4gY2FsZW5kYXJpbyBjb21wbGVtZW50YXJpbyBkZSBldmVudG9zIE1JQ0UsIGNvbiBhbCBtZW5vcyAxMiBtZXNlcyBkZSBhbnRpY2lwYWNpw7NuLCBxdWUgdmluY3VsZSB0ZW3DoXRpY2FtZW50ZSBhY3RpdmlkYWRlcyBlbXByZXNhcmlhbGVzIGNvbiBlbCBNdW5kaWFsLCBjb21vIGNvbmdyZXNvcyBzb2JyZSBpbm5vdmFjacOzbiBkZXBvcnRpdmEsIHR1cmlzbW8gbyBzbWFydCBjaXRpZXMuIEFkZW3DoXMsIHNlIGltcHVsc2Fyw6FuIHJ1ZWRhcyBkZSBuZWdvY2lvcyB5IHNlc2lvbmVzIGRlIG5ldHdvcmtpbmcgZW4gZmVjaGFzIGNlcmNhbmFzIGEgcGFydGlkb3MgZGUgYWx0byBwZXJmaWwsIHBhcmEgYXRyYWVyIGEgbMOtZGVyZXMgZW1wcmVzYXJpYWxlcyBuYWNpb25hbGVzIGUgaW50ZXJuYWNpb25hbGVzLiBTZSBwcm9tb3ZlcsOhIGludGVybmFjaW9uYWxtZW50ZSBhIE1vbnRlcnJleSBjb21vIHNlZGUgZGVsIE11bmRpYWwgeSBodWIgZGUgbmVnb2Npb3MsIG1lZGlhbnRlIHVuYSBvZmVydGEgaW50ZWdyYWRhIHF1ZSBjb21iaW5lIHBhcnRpZG9zLCBldmVudG9zIGNvcnBvcmF0aXZvcyB5IGhvc3BlZGFqZSBlamVjdXRpdm8sIGF0cmF5ZW5kbyBhbCB0dXJpc21vIGRlIG5lZ29jaW9zIGNvbiB1bmEgcHJvcHVlc3RhIGRpZmVyZW5jaWFkYS4gQ29uIGJhc2UgZW4gbGFzIGVzdHJhdGVnaWFzIGRlIG1pdGlnYWNpw7NuIHBsYW50ZWFkYXMsIHNlIHByb3BvbmUgdW4gS1BJIHBhcmEgZGljaG8gcmllc2dvIHBhcmEgbWVkaXIgcXXDqSBwb3JjZW50YWplIGRlIGxvcyBldmVudG9zIGRlIG5lZ29jaW9zIChjb25ncmVzb3MsIGZlcmlhcywgcnVlZGFzLCBldGMuKSBlc3TDoW4gdGVtw6F0aWNhbWVudGUgbyBsb2fDrXN0aWNhbWVudGUgaW50ZWdyYWRvcyBjb24gZWwgY2FsZW5kYXJpbyBGSUZBIDIwMjYgZW4gTW9udGVycmV5LiAgIA0KDQpTZSBlc3RpbWEgcXVlIHVuIHZhbG9yIOKJpSA2MCUgZGUgbG9zIGV2ZW50b3MgTUlDRSBkZWwgcHJpbWVyIHNlbWVzdHJlIGRlIDIwMjYgZGViZXLDrWFuIHRlbmVyIGFsZ8O6biBncmFkbyBkZSB2aW5jdWxhY2nDs24gY29uIGVsIE11bmRpYWwgKHRlbcOhdGljYSwgc2VkZSwgZmVjaGFzLCBwcm9tb2Npw7NuIGNvbmp1bnRhLCBwYXF1ZXRlcykuICAgDQoNCg0KIyMgKipBY2Npb25lcyBlc3RyYXTDqWdpY2FzIGVuZm9jYWRhcyBhbCBNdW5kaWFsIEZJRkEgMjAyNioqDQoNCioqSW5kdXN0cmlhIEhvdGVsZXJhKioNCg0KKiBFc3RhYmxlY2VyIHVuIGFjdWVyZG8gZGUgdGFyaWZhcyBtw6F4aW1hcyByZWNvbWVuZGFkYXMgY29uIGFzb2NpYWNpb25lcyBob3RlbGVyYXMgcGFyYSBldml0YXIgZXNjYWxhZGFzIGluanVzdGlmaWNhZGFzLiAgDQoNCiogUHJvbW92ZXIgYWxvamFtaWVudG9zIGFsdGVybmF0aXZvcyBjZXJ0aWZpY2Fkb3MgKEFpcmJuYiByZWd1bGFkbywgaG9zdGFsZXMgZGUgY2FsaWRhZCkgcGFyYSBkaXZlcnNpZmljYXIgbGEgb2ZlcnRhIHkgYWxpdmlhciBsYSBwcmVzacOzbiBzb2JyZSBsb3MgaG90ZWxlcyB0cmFkaWNpb25hbGVzLiBJbmNsdXllbmRvIGxhIGNyZWFjacOzbiBkZSB1biBwcm9ncmFtYSBkZSBzZWxsbyBkZSBjYWxpZGFkIHBhcmEgYW5maXRyaW9uZXMgZGUgQWlyYm5iIHkgaG9zdGFsZXMsIGFzZWd1cmFuZG8gZXN0w6FuZGFyZXMgbcOtbmltb3MgZGUgbGltcGllemEsIGF0ZW5jacOzbiB5IHNlZ3VyaWRhZC4gIA0KDQoqKkluZHVzdHJpYSBUdXJpc21vIGRlIE5lZ29jaW9zKiogIA0KDQpfQ29ydG8gUGxhem8gKDIwMjUgLSAyMDI2LCBwcmUgeSBkdXJhbnRlIE11bmRpYWwgRklGQSlfDQoNCiogQWxpYW56YXMgT0NWIC0gRklGQSAtIEdvYmllcm5vIEVzdGF0YWw6IERlc2Fycm9sbGFyIHVuIGNhbGVuZGFyaW8gY29tcGxlbWVudGFyaW8gZGUgZXZlbnRvcyBkZSBuZWdvY2lvcyBlbiBwYXJhbGVsbyBhIHBhcnRpZG9zIGNsYXZlLCBpbnRlZ3JhbmRvIGZvcm9zIGVtcHJlc2FyaWFsZXMsIGV4cG9zIHRlbcOhdGljYXMgeSBydWVkYXMgZGUgaW52ZXJzacOzbi4gIA0KDQoqIEludGVncmFjacOzbiBkZSB1bmEgRXN0cmF0ZWdpYSBCaW5hcmlhIOKAnE11bmRpYWwgKyBUdXJpc21vIGRlIFJldW5pb25lc+KAnTogVXNhciBob3RlbGVzLCBjZW50cm9zIGRlIGNvbnZlbmNpb25lcyB5IHJlY2ludG9zIGRlcG9ydGl2b3MgcGFyYSBldmVudG9zIGR1YWxlcyAocmV1bmlvbmVzICsgZW50cmV0ZW5pbWllbnRvKS4gIA0KDQpfTGFyZ28gUGxhem8gKDIwMjYgZW4gYWRlbGFudGUpXw0KDQoqIExlZ2FkbyBGSUZBIHBhcmEgZWwgdHVyaXNtbyBkZSBuZWdvY2lvczogUG9zaWNpb25hciBhIE1vbnRlcnJleSBjb21vIHNlZGUgaW50ZXJuYWNpb25hbCByZWN1cnJlbnRlIGRlIGNvbmdyZXNvcyB5IGV2ZW50b3MuICANCg0KKiBDbMO6c3RlciBkZSB0dXJpc21vIE1JQ0UgKE1lZXRpbmdzLCBJbmNlbnRpdmVzLCBDb25mZXJlbmNlcywgRXhoaWJpdGlvbnMpOiBGb3JtYWxpemFyIHVuYSByZWQgbG9jYWwgcXVlIGFydGljdWxlIGEgaG90ZWxlcywgYWdlbmNpYXMsIGdvYmllcm5vLCBjw6FtYXJhcyBlbXByZXNhcmlhbGVzIHkgdW5pdmVyc2lkYWRlcy4NCg0KDQojIyAqKkNvbmNsdXNpw7NuKioNCg0KTGEgYW5hbMOtdGljYSBwcmVzY3JpcHRpdmEgYXBsaWNhZGEgYWwgdHVyaXNtbyBlbiBsYSBab25hIE1ldHJvcG9saXRhbmEgZGUgTW9udGVycmV5IGRlc3RhY2EgbGEgaW1wb3J0YW5jaWEgZGUgY29udGFyIGNvbiBpbmRpY2Fkb3JlcyBjbGF2ZSBxdWUgcGVybWl0YW4gYW50aWNpcGFyIHkgZ2VzdGlvbmFyIGxhIGRlbWFuZGEgdHVyw61zdGljYSwgZXNwZWNpYWxtZW50ZSBlbiB1biBjb250ZXh0byBkZSBldmVudG9zIGRlIGdyYW4gZXNjYWxhIGNvbW8gZWwgTXVuZGlhbCBGSUZBIDIwMjYuIEVsIG1vbml0b3JlbyBkZSBsYSBsbGVnYWRhIGRlIHR1cmlzdGFzIG5hY2lvbmFsZXMgc2UgY29uZmlybWEgY29tbyB1biBLUEkgZnVuZGFtZW50YWwsIGN1eW8gaW1wYWN0byBlY29uw7NtaWNvIHBvc2l0aXZvIGVzdMOhIGN1YW50aWZpY2FkbyBtZWRpYW50ZSBtb2RlbG9zIGVzdGFkw61zdGljb3MuIEFzaW1pc21vLCBlbCBHcm91cCBNaXggcmV2ZWxhIGxhIHJlbGV2YW5jaWEgZGUgbG9zIGdydXBvcyBncmFuZGVzIGVuIGxhIG9jdXBhY2nDs24gaG90ZWxlcmEsIG9mcmVjaWVuZG8gb3BvcnR1bmlkYWRlcyBwYXJhIG9wdGltaXphciBpbmdyZXNvcyB5IGRpc2XDsWFyIGVzdHJhdGVnaWFzIHNlZ21lbnRhZGFzLiBQb3Igb3RyYSBwYXJ0ZSwgZWwgw41uZGljZSBkZSBJbXBhY3RvIGRlbCBUdXJpc21vIGRlIE5lZ29jaW9zIChJSVROKSBwZXJtaXRlIGV2YWx1YXIgZWwgZGluYW1pc21vIHkgbGEgZWZlY3RpdmlkYWQgZGUgbGEgYWdlbmRhIGRlIGV2ZW50b3MgY29ycG9yYXRpdm9zLCBldmlkZW5jaWFuZG8gbGEgbmVjZXNpZGFkIGRlIGZvcnRhbGVjZXIgbGEgY29vcmRpbmFjacOzbiBpbnN0aXR1Y2lvbmFsIHkgbGEgcGxhbmlmaWNhY2nDs24gcGFyYSBldml0YXIgc3VidXRpbGl6YWNpw7NuIGRlIGluZnJhZXN0cnVjdHVyYSB5IG1heGltaXphciBsYSBkZXJyYW1hIGVjb27Ds21pY2EuIEZyZW50ZSBhIGxvcyByaWVzZ29zIGFzb2NpYWRvcyBhbCBNdW5kaWFsIDIwMjYsIHNlIHByb3BvbmUgdW5hIHNlcmllIGRlIGVzdHJhdGVnaWFzIGRlIG1pdGlnYWNpw7NuIGNlbnRyYWRhcyBlbiBsYSB0cmFuc3BhcmVuY2lhIHRhcmlmYXJpYSwgZGl2ZXJzaWZpY2FjacOzbiBkZSBsYSBvZmVydGEgaG90ZWxlcmEgeSB1bmEgaW50ZWdyYWNpw7NuIGVmZWN0aXZhIGVudHJlIGV2ZW50b3MgZGVwb3J0aXZvcyB5IGRlIG5lZ29jaW9zLiBFbiBjb25qdW50bywgZXN0b3MgZXNmdWVyem9zIGJ1c2NhbiBwb3NpY2lvbmFyIGEgTW9udGVycmV5IGNvbW8gdW4gZGVzdGlubyB0dXLDrXN0aWNvIGNvbXBldGl0aXZvIHkgc29zdGVuaWJsZSwgZ2FyYW50aXphbmRvIGJlbmVmaWNpb3MgZWNvbsOzbWljb3MgYW1wbGlvcyB5IHVuIGxlZ2FkbyBkdXJhZGVybyBwYXJhIGxhIHJlZ2nDs24uIFBvciBlbGxvLCBzZSBwcmVzZW50YW4gbG9zIGluc2lnaHRzIGRlIG1heW9yIHJlbGV2YW5jaWE6DQoNCiogTGEgbGxlZ2FkYSBkZSB0dXJpc3RhcyBuYWNpb25hbGVzIGdlbmVyYSB1bmEgZGVycmFtYSBlY29uw7NtaWNhIHNpZ25pZmljYXRpdmEsIGVzdGltYWRhIGVuICsxNDcuOCBtZHAgcG9yIGNhZGEgbWlsIHR1cmlzdGFzIGFkaWNpb25hbGVzLCBlc3BlY2lhbG1lbnRlIGR1cmFudGUgcGljb3MgZGUgYWN0aXZpZGFkLg0KDQoqIEVsIHBvcmNlbnRhamUgZGUgcmVzZXJ2YXMgcHJvdmVuaWVudGVzIGRlIGdydXBvcyBncmFuZGVzIChHcm91cCBNaXgpIHByb21lZGlhIDQuNCUsIGxvIHF1ZSByZXByZXNlbnRhIHVuYSBvcG9ydHVuaWRhZCBwYXJhIGRpc2XDsWFyIHBhcXVldGVzIHkgZXN0cmF0ZWdpYXMgZXNwZWPDrWZpY2FzIHBhcmEgZXZlbnRvcyBtYXNpdm9zIHkgY29ycG9yYXRpdm9zLg0KDQoqIEVsIMONbmRpY2UgZGUgSW1wYWN0byBkZWwgVHVyaXNtbyBkZSBOZWdvY2lvcyAoSUlUTikgaGEgbW9zdHJhZG8gdm9sYXRpbGlkYWQgeSB1biBkZXNlbXBlw7FvIGdlbmVyYWxtZW50ZSBpbmZlcmlvciBhbCBlc3BlcmFkbywgaW5kaWNhbmRvIGxhIG5lY2VzaWRhZCBkZSBtZWpvcmFyIGxhIGNvb3JkaW5hY2nDs24geSBwcm9tb2Npw7NuIGRlIGV2ZW50b3MgTUlDRS4NCg0KKiBMb3Mgcmllc2dvcyBkZSBzYXR1cmFjacOzbiBob3RlbGVyYSB5IHZvbGF0aWxpZGFkIHRhcmlmYXJpYSBkdXJhbnRlIGVsIE11bmRpYWwgRklGQSAyMDI2IHB1ZWRlbiBtaXRpZ2Fyc2UgbWVkaWFudGUgYWN1ZXJkb3MgZGUgdGFyaWZhcyBtw6F4aW1hcywgZGl2ZXJzaWZpY2FjacOzbiBkZSBsYSBvZmVydGEgeSBtb25pdG9yZW8gZGluw6FtaWNvIGNvbiBwbGF0YWZvcm1hcyBkaWdpdGFsZXMuDQoNCiogTGEgaW50ZWdyYWNpw7NuIGVmZWN0aXZhIGVudHJlIGV2ZW50b3MgZGVwb3J0aXZvcyB5IGRlIG5lZ29jaW9zIGVzIGNydWNpYWwgcGFyYSBtYXhpbWl6YXIgbGEgZGVycmFtYSBlY29uw7NtaWNhIHkgcG9zaWNpb25hciBhIE1vbnRlcnJleSBjb21vIHVuIGh1YiBpbnRlcm5hY2lvbmFsIGRlIHR1cmlzbW8gTUlDRS4NCg0KDQo=