Secretaría de Emergencias y Gestión de Riesgos - Gobierno de la provincia de Neuquén

El Observatorio Provincial de Gestión de Riesgos tiene como objetivo contribuir al diseño, implementación y monitoreo de políticas públicas tendientes a optimizar la gestión integral del riesgo en la provincia del Neuquén, a través del desarrollo de un sistema de información que permita recopilar, analizar y consolidar datos relevantes para la toma de decisiones y la mejora continua de las estrategias de reducción de riesgo y abordaje de situaciones de emergencias. Sus funciones se enmarcan en la ley provincial 2713: “Enfoque de riesgo en políticas de planificación y desarrollo territorial de la Provincia del Neuquén” (Art 3 y 8).

FUENTES DE INFORMACIÓN:

CIAT – Centro de Información de Alerta Temprana

SIGISVI - Sistema Integral de Gestión de la Información de Seguridad Vial

Vialidad Provincial (Estado de las rutas)

RAPH (SIEN) Registro de Atención Pre Hospitalaria

Medios gráficos de comunicación

OpenWeatherMap

Servicio meteorológico Nacional

Policía de la provincia de Neuquén

Dirección Bomberos de la Policía

Sistema de Manejo del Fuego


ANÁLISIS EXPLORATORIO DE SINIESTROS VIALES CON DATOS DEL SIGISVI (Sistema Integral de Gestión de la Información de Seguridad Vial)

LIBRERIAS

library(dplyr)
library(tidyr)
library(ggplot2)
library(lubridate)
library(corrplot)  
library(reshape2)  

Selección inicial de campos para el análisis

data_sigisvi_siniestro <- read.csv("siniestros.csv")

campos_siniestro <- c("numero_formulario", "localidad", "siniestro_fecha", "siniestro_hora", "categoria_siniestro", "zona_ocurrencia", "via_publica", "nombre_via","altura_km", "latitud", "longitud", "tipo_siniestro_multiple", "tipo_siniestro_unico", "trazado_via", "configuracion_de_la_via", "material_de_la_calzada")

data_sigisvi_siniestro_filtrado <- data_sigisvi_siniestro %>%
  select(all_of(campos_siniestro))


summary(data_sigisvi_siniestro_filtrado)
 numero_formulario    localidad         siniestro_fecha    siniestro_hora     categoria_siniestro zona_ocurrencia    via_publica       
 Min.   :1.230e+02   Length:11591       Length:11591       Length:11591       Length:11591        Length:11591       Length:11591      
 1st Qu.:2.021e+09   Class :character   Class :character   Class :character   Class :character    Class :character   Class :character  
 Median :2.022e+09   Mode  :character   Mode  :character   Mode  :character   Mode  :character    Mode  :character   Mode  :character  
 Mean   :1.973e+09                                                                                                                     
 3rd Qu.:2.023e+09                                                                                                                     
 Max.   :2.024e+09                                                                                                                     
                                                                                                                                       
  nombre_via         altura_km            latitud          longitud      tipo_siniestro_multiple tipo_siniestro_unico trazado_via       
 Length:11591       Length:11591       Min.   :-41.05   Min.   :-71.79   Length:11591            Length:11591         Length:11591      
 Class :character   Class :character   1st Qu.:-38.97   1st Qu.:-70.11   Class :character        Class :character     Class :character  
 Mode  :character   Mode  :character   Median :-38.95   Median :-68.15   Mode  :character        Mode  :character     Mode  :character  
                                       Mean   :-39.06   Mean   :-69.06                                                                  
                                       3rd Qu.:-38.90   3rd Qu.:-68.09                                                                  
                                       Max.   :  0.00   Max.   :  0.00                                                                  
                                       NA's   :222      NA's   :222                                                                     
 configuracion_de_la_via material_de_la_calzada
 Length:11591            Length:11591          
 Class :character        Class :character      
 Mode  :character        Mode  :character      
                                               
                                               
                                               
                                               
datos <- data_sigisvi_siniestro_filtrado;
# Convertir siniestro_fecha a formato de fecha si aún no lo está
datos$siniestro_fecha <- as.Date(datos$siniestro_fecha, format = "%Y-%m-%d")

# Extraer el año utilizando la función base de R
datos$ano <- format(datos$siniestro_fecha, "%Y")

# Gráfico de barras por año
ggplot(data = datos, aes(x = ano)) +
  geom_bar() +
  labs(x = "Año", y = "Número de Siniestros", title = "Número de Siniestros Viales por Año")

# Agrupar y contar accidentes por mes
accidentes_por_mes <- datos %>%
  mutate(siniestro_fecha = as.Date(siniestro_fecha)) %>%
  mutate(mes = format(siniestro_fecha, "%Y-%m")) %>%
  group_by(mes) %>%
  summarise(cantidad = n())

# Convertir la columna 'mes' a Date para asegurar un eje x continuo
accidentes_por_mes$mes <- as.Date(paste0(accidentes_por_mes$mes, "-01"))

# Crear el gráfico de accidentes por mes

ggplot(accidentes_por_mes, aes(x = mes, y = cantidad)) +
  geom_line() +
  geom_point() +
  labs(title = "Cantidad de Accidentes Viales por Mes",
       x = "Mes",
       y = "Cantidad de Accidentes") +
  theme_minimal() +
  scale_x_date(date_labels = "%b - %y", date_breaks = "1 month") +  # Usar abreviaturas de mes
  theme(axis.text.x = element_text(angle = 90, hjust = 1, size = 8),
        plot.margin = margin(10, 10, 60, 10)) 

# Agrupar y contar accidentes por mes
accidentes_por_mes <- datos %>%
  mutate(siniestro_fecha = as.Date(siniestro_fecha)) %>%
  mutate(mes = format(siniestro_fecha, "%B")) %>%  # Formato con nombre completo del mes
  group_by(mes) %>%
  summarise(cantidad = n())

# Reordenar el factor 'mes' para que esté en orden cronológico
accidentes_por_mes$mes <- factor(accidentes_por_mes$mes, levels = c("enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"))

# Crear el gráfico de accidentes por mes
ggplot(accidentes_por_mes, aes(x = mes, y = cantidad)) +
  geom_bar(stat = "identity", fill = "skyblue", color = "black") +
  labs(title = "Cantidad de Accidentes Viales por Mes",
       x = "Mes",
       y = "Cantidad de Accidentes") +
  theme_minimal()

# Crear una columna para el día de la semana en formato de etiqueta
datos <- datos %>%
  mutate(dia_semana_etiqueta = format(siniestro_fecha, "%a") %>% tolower())

# Definir el orden deseado de los días de la semana
orden_dias <- c("lun.", "mar.", "mié.", "jue.", "vie.", "sáb.", "dom.")

# Contar los siniestros por día de la semana y asegurar el orden correcto
siniestros_por_dia_semana <- datos %>%
  count(dia_semana_etiqueta) %>%
  mutate(dia_semana_etiqueta = factor(dia_semana_etiqueta, levels = orden_dias))

# Crear el gráfico de barras por día de la semana
ggplot(siniestros_por_dia_semana, aes(x = dia_semana_etiqueta, y = n)) +
  geom_bar(stat = "identity", fill = "skyblue") +
  labs(title = "Cantidad de Siniestros Viales por Día de la Semana",
       x = "Día de la Semana",
       y = "Cantidad de Siniestros") +
  scale_x_discrete(labels = c(lun = "Lun", mar = "Mar", mié = "Mié", jue = "Jue", vie = "Vie", sáb = "Sáb", dom = "Dom")) +  # Etiquetas involucradoslizadas
  theme_minimal()

# Crear columnas para el día de la semana en formato de etiqueta y para el mes
datos <- datos %>%
  mutate(dia_semana_etiqueta = format(siniestro_fecha, "%a") %>% tolower(),
         mes_etiqueta = format(siniestro_fecha, "%b") %>% tolower())

# Definir el orden deseado de los días de la semana y los meses
orden_dias <- c("lun.", "mar.", "mié.", "jue.", "vie.", "sáb.", "dom.")
orden_meses <- c("ene.", "feb.", "mar.", "abr.", "may.", "jun.", "jul.", "ago.", "sep.", "oct.", "nov.", "dic.")

# Contar los siniestros por día de la semana y mes, y asegurar el orden correcto
siniestros_por_dia_mes <- datos %>%
  count(dia_semana_etiqueta, mes_etiqueta) %>%
  mutate(dia_semana_etiqueta = factor(dia_semana_etiqueta, levels = orden_dias),
         mes_etiqueta = factor(mes_etiqueta, levels = orden_meses))

# Crear la matriz de calor
ggplot(siniestros_por_dia_mes, aes(x = mes_etiqueta, y = dia_semana_etiqueta, fill = n)) +
  geom_tile(color = "white") +
  scale_fill_gradient(low = "skyblue", high = "red", name = "Cantidad de Siniestros") +
  labs(title = "Cantidad de Siniestros Viales por Día de la Semana y Mes",
       x = "Mes",
       y = "Día de la Semana") +
  scale_x_discrete(labels = c("ene" = "Ene", "feb" = "Feb", "mar" = "Mar", "abr" = "Abr", "may" = "May", "jun" = "Jun", "jul" = "Jul", "ago" = "Ago", "sep" = "Sep", "oct" = "Oct", "nov" = "Nov", "dic" = "Dic")) +  # Etiquetas involucradoslizadas
  scale_y_discrete(labels = c("lun." = "Lun", "mar." = "Mar", "mié." = "Mié", "jue." = "Jue", "vie." = "Vie", "sáb." = "Sáb", "dom." = "Dom")) +  # Etiquetas involucradoslizadas
  theme_minimal()

# Convertir siniestro_hora a formato de hora
datos$siniestro_hora <- hms::as_hms(datos$siniestro_hora)

# Extraer la hora como un número entero (0 a 23)
datos <- datos %>%
  mutate(hora = hour(siniestro_hora))

# Gráfico de barras de siniestros por hora del día
ggplot(datos, aes(x = factor(hora))) +
  geom_bar(fill = "skyblue") +
  labs(title = "Cantidad de Siniestros Viales por Hora del Día",
       x = "Hora del Día",
       y = "Cantidad de Siniestros") +
  theme_minimal()


# Contar los siniestros por mes y hora
siniestros_por_mes_hora <- datos %>%
  count(mes_etiqueta, hora) %>%
  mutate(mes_etiqueta = factor(mes_etiqueta, levels = orden_meses))

# Crear la matriz de calor
ggplot(siniestros_por_mes_hora, aes(x = mes_etiqueta, y = factor(hora), fill = n)) +
  geom_tile(color = "white") +
  scale_fill_gradient(low = "skyblue", high = "red", name = "Cantidad de Siniestros") +
  labs(title = "Cantidad de Siniestros Viales por Mes y Hora del Día",
       x = "Mes",
       y = "Hora del Día") +
  scale_x_discrete(labels = c("ene" = "Ene", "feb" = "Feb", "mar" = "Mar", "abr" = "Abr", "may" = "May", "jun" = "Jun", "jul" = "Jul", "ago" = "Ago", "sep" = "Sep", "oct" = "Oct", "nov" = "Nov", "dic" = "Dic")) +  # Etiquetas involucradoslizadas
  scale_y_discrete(labels = as.character(0:23)) +
  theme_minimal()


# Heatmap de siniestros por hora del día y día de la semana
siniestros_por_hora_dia_semana <- datos %>%
  count(dia_semana_etiqueta, hora) %>%
  mutate(dia_semana_etiqueta = factor(dia_semana_etiqueta, levels = orden_dias))

ggplot(siniestros_por_hora_dia_semana, aes(x = factor(hora), y = dia_semana_etiqueta, fill = n)) +
  geom_tile(color = "white") +
  scale_fill_gradient(low = "skyblue", high = "red", name = "Cantidad de Siniestros") +
  labs(title = "Cantidad de Siniestros Viales por Hora del Día y Día de la Semana",
       x = "Hora del Día",
       y = "Día de la Semana") +
  scale_x_discrete(labels = as.character(0:23)) +
  scale_y_discrete(labels = c("lun." = "Lun", "mar." = "Mar", "mié." = "Mié", "jue." = "Jue", "vie." = "Vie", "sáb." = "Sáb", "dom." = "Dom")) +
  theme_minimal()

# Filtrar los datos para eliminar las filas con "S/D" en categoria_siniestro
datos_filtrados <- datos %>%
  filter(categoria_siniestro != "S/D")

# Contar los siniestros por categoría
siniestros_por_categoria <- datos_filtrados %>%
  count(categoria_siniestro)


# Crear el gráfico de barras por categoría
ggplot(siniestros_por_categoria, aes(x = categoria_siniestro, y = n, fill = categoria_siniestro)) +
  geom_bar(stat = "identity") +
  labs(title = "Cantidad de Siniestros Viales por Categoría",
       x = "Categoría del Siniestro",
       y = "Cantidad de Siniestros") +
  scale_fill_manual(values = c("fatal" = "red", "no fatal" = "skyblue"), name = "Categoría") +
  theme_minimal()
Aviso: No shared levels found between `names(values)` of the manual scale and the data's fill values.
Aviso: No shared levels found between `names(values)` of the manual scale and the data's fill values.

# Filtrar los datos para eliminar las filas con "S/D" en zona_ocurrencia (si es necesario)
datos_filtrados_zona <- datos %>%
  filter(zona_ocurrencia != "S/D", zona_ocurrencia != "")

# Contar los siniestros por zona_ocurrencia
siniestros_por_zona <- datos_filtrados_zona %>%
  count(zona_ocurrencia)

# Crear el gráfico de barras por zona_ocurrencia
ggplot(siniestros_por_zona, aes(x = zona_ocurrencia, y = n, fill = zona_ocurrencia)) +
  geom_bar(stat = "identity") +
  labs(title = "Cantidad de Siniestros Viales por Zona de Ocurrencia",
       x = "Zona de Ocurrencia",
       y = "Cantidad de Siniestros") +
  scale_fill_discrete(name = "Zona de Ocurrencia") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Filtrar los datos para eliminar las filas con "S/D" en via_publica (si es necesario)
datos_filtrados_via <- datos %>%
  filter(via_publica != "S/D", via_publica != "")

# Contar los siniestros por via_publica
siniestros_por_via <- datos_filtrados_via %>%
  count(via_publica)

# Crear el gráfico de barras por via_publica
ggplot(siniestros_por_via, aes(x = via_publica, y = n, fill = via_publica)) +
  geom_bar(stat = "identity") +
  labs(title = "Cantidad de Siniestros Viales por Vía Pública",
       x = "Vía Pública",
       y = "Cantidad de Siniestros") +
  scale_fill_discrete(name = "Vía Pública") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Filtrar los datos para eliminar las filas con "S/D" en tipo_siniestro_unico (si es necesario)
datos_filtrados_tipo <- datos %>%
  filter(tipo_siniestro_unico != "S/D", tipo_siniestro_unico != "")

# Contar los siniestros por tipo_siniestro_unico
siniestros_por_tipo <- datos_filtrados_tipo %>%
  count(tipo_siniestro_unico)

# Crear el gráfico de barras por tipo_siniestro_unico
ggplot(siniestros_por_tipo, aes(x = tipo_siniestro_unico, y = n, fill = tipo_siniestro_unico)) +
  geom_bar(stat = "identity") +
  labs(title = "Cantidad de Siniestros Viales por Tipo de Siniestro Único",
       x = "Tipo de Siniestro Único",
       y = "Cantidad de Siniestros") +
  scale_fill_discrete(name = "Tipo de Siniestro Único") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Filtrar los datos para eliminar las filas con "S/D" en material_calzada (si es necesario)
datos_filtrados_material <- datos %>%
  filter(material_de_la_calzada != "S/D", material_de_la_calzada != "")

# Contar los siniestros por material_calzada
siniestros_por_material <- datos_filtrados_material %>%
  count(material_de_la_calzada)

# Crear el gráfico de barras por material_calzada
ggplot(siniestros_por_material, aes(x = material_de_la_calzada, y = n, fill = material_de_la_calzada)) +
  geom_bar(stat = "identity") +
  labs(title = "Cantidad de Siniestros Viales por Material de la Calzada",
       x = "Material de la Calzada",
       y = "Cantidad de Siniestros") +
  scale_fill_discrete(name = "Material de la Calzada") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

LS0tDQp0aXRsZTogIkFuw6FsaXNpcyBleHBsb3JhdG9yaW8gZGUgZGF0b3MgZGUgU0lHSVNWSSINCkVxdWlwbzogIk9CU0VSVkFUT1JJTyBQUk9WSU5DSUFMIERFIEdFU1RJw5NOIERFIFJJRVNHT1MiDQpGZWNoYTogIjE1LzA4LzIwMjQiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQo+IFNlY3JldGFyw61hIGRlIEVtZXJnZW5jaWFzIHkgR2VzdGnDs24gZGUgUmllc2dvcyAtIEdvYmllcm5vIGRlIGxhIHByb3ZpbmNpYSBkZSBOZXVxdcOpbiANCg0KDQpFbCAqKk9ic2VydmF0b3JpbyBQcm92aW5jaWFsIGRlIEdlc3Rpw7NuIGRlIFJpZXNnb3MqKiB0aWVuZSBjb21vIG9iamV0aXZvIGNvbnRyaWJ1aXIgYWwgZGlzZcOxbywgaW1wbGVtZW50YWNpw7NuIHkgbW9uaXRvcmVvIGRlIHBvbMOtdGljYXMgcMO6YmxpY2FzIHRlbmRpZW50ZXMgYSBvcHRpbWl6YXIgbGEgZ2VzdGnDs24gaW50ZWdyYWwgZGVsIHJpZXNnbyBlbiBsYSBwcm92aW5jaWEgZGVsIE5ldXF1w6luLCBhIHRyYXbDqXMgZGVsIGRlc2Fycm9sbG8gZGUgdW4gc2lzdGVtYSBkZSBpbmZvcm1hY2nDs24gcXVlIHBlcm1pdGEgcmVjb3BpbGFyLCBhbmFsaXphciB5IGNvbnNvbGlkYXIgZGF0b3MgcmVsZXZhbnRlcyBwYXJhIGxhIHRvbWEgZGUgZGVjaXNpb25lcyB5IGxhIG1lam9yYSBjb250aW51YSBkZSBsYXMgZXN0cmF0ZWdpYXMgZGUgcmVkdWNjacOzbiBkZSByaWVzZ28geSBhYm9yZGFqZSBkZSBzaXR1YWNpb25lcyBkZSBlbWVyZ2VuY2lhcy4gU3VzIGZ1bmNpb25lcyBzZSBlbm1hcmNhbiBlbiBsYSBsZXkgcHJvdmluY2lhbCAyNzEzOiDigJxFbmZvcXVlIGRlIHJpZXNnbyBlbiBwb2zDrXRpY2FzIGRlIHBsYW5pZmljYWNpw7NuIHkgZGVzYXJyb2xsbyB0ZXJyaXRvcmlhbCBkZSBsYSBQcm92aW5jaWEgZGVsIE5ldXF1w6lu4oCdIChBcnQgMyB5IDgpLg0KDQoqKkZVRU5URVMgREUgSU5GT1JNQUNJw5NOOioqDQoNCkNJQVQg4oCTIENlbnRybyBkZSBJbmZvcm1hY2nDs24gZGUgQWxlcnRhIFRlbXByYW5hDQoNClNJR0lTVkkgLSBTaXN0ZW1hIEludGVncmFsIGRlIEdlc3Rpw7NuIGRlIGxhIEluZm9ybWFjacOzbiBkZSBTZWd1cmlkYWQgVmlhbA0KDQpWaWFsaWRhZCBQcm92aW5jaWFsIChFc3RhZG8gZGUgbGFzIHJ1dGFzKQ0KDQpSQVBIIChTSUVOKSBSZWdpc3RybyBkZSBBdGVuY2nDs24gUHJlIEhvc3BpdGFsYXJpYQ0KDQpNZWRpb3MgZ3LDoWZpY29zIGRlIGNvbXVuaWNhY2nDs24NCg0KU2VydmljaW8gbWV0ZW9yb2zDs2dpY28gDQoNCkRpcmVjY2nDs24gQm9tYmVyb3MgZGUgbGEgUG9saWPDrWENCg0KU2VydmljaW8gZGUgTWFuZWpvIGRlbCBGdWVnbw0KDQoNCg0KDQoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KKkFOw4FMSVNJUyBFWFBMT1JBVE9SSU8gREUgU0lOSUVTVFJPUyBWSUFMRVMgQ09OIERBVE9TIERFTCBTSUdJU1ZJKg0KKihTaXN0ZW1hIEludGVncmFsIGRlIEdlc3Rpw7NuIGRlIGxhIEluZm9ybWFjacOzbiBkZSBTZWd1cmlkYWQgVmlhbCkqDQoNCg0KTElCUkVSSUFTDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KGNvcnJwbG90KSAgDQpsaWJyYXJ5KHJlc2hhcGUyKSAgDQpgYGANCg0KDQpTZWxlY2Npw7NuIGluaWNpYWwgZGUgY2FtcG9zIHBhcmEgZWwgYW7DoWxpc2lzDQoNCmBgYHtyfQ0KZGF0YV9zaWdpc3ZpX3Npbmllc3RybyA8LSByZWFkLmNzdigic2luaWVzdHJvcy5jc3YiKQ0KDQpjYW1wb3Nfc2luaWVzdHJvIDwtIGMoIm51bWVyb19mb3JtdWxhcmlvIiwgImxvY2FsaWRhZCIsICJzaW5pZXN0cm9fZmVjaGEiLCAic2luaWVzdHJvX2hvcmEiLCAiY2F0ZWdvcmlhX3Npbmllc3RybyIsICJ6b25hX29jdXJyZW5jaWEiLCAidmlhX3B1YmxpY2EiLCAibm9tYnJlX3ZpYSIsImFsdHVyYV9rbSIsICJsYXRpdHVkIiwgImxvbmdpdHVkIiwgInRpcG9fc2luaWVzdHJvX211bHRpcGxlIiwgInRpcG9fc2luaWVzdHJvX3VuaWNvIiwgInRyYXphZG9fdmlhIiwgImNvbmZpZ3VyYWNpb25fZGVfbGFfdmlhIiwgIm1hdGVyaWFsX2RlX2xhX2NhbHphZGEiKQ0KDQpkYXRhX3NpZ2lzdmlfc2luaWVzdHJvX2ZpbHRyYWRvIDwtIGRhdGFfc2lnaXN2aV9zaW5pZXN0cm8gJT4lDQogIHNlbGVjdChhbGxfb2YoY2FtcG9zX3Npbmllc3RybykpDQoNCg0Kc3VtbWFyeShkYXRhX3NpZ2lzdmlfc2luaWVzdHJvX2ZpbHRyYWRvKQ0KYGBgDQoNCmBgYHtyfQ0KZGF0b3MgPC0gZGF0YV9zaWdpc3ZpX3Npbmllc3Ryb19maWx0cmFkbzsNCiMgQ29udmVydGlyIHNpbmllc3Ryb19mZWNoYSBhIGZvcm1hdG8gZGUgZmVjaGEgc2kgYcO6biBubyBsbyBlc3TDoQ0KZGF0b3Mkc2luaWVzdHJvX2ZlY2hhIDwtIGFzLkRhdGUoZGF0b3Mkc2luaWVzdHJvX2ZlY2hhLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQojIEV4dHJhZXIgZWwgYcOxbyB1dGlsaXphbmRvIGxhIGZ1bmNpw7NuIGJhc2UgZGUgUg0KZGF0b3MkYW5vIDwtIGZvcm1hdChkYXRvcyRzaW5pZXN0cm9fZmVjaGEsICIlWSIpDQoNCiMgR3LDoWZpY28gZGUgYmFycmFzIHBvciBhw7FvDQpnZ3Bsb3QoZGF0YSA9IGRhdG9zLCBhZXMoeCA9IGFubykpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoeCA9ICJBw7FvIiwgeSA9ICJOw7ptZXJvIGRlIFNpbmllc3Ryb3MiLCB0aXRsZSA9ICJOw7ptZXJvIGRlIFNpbmllc3Ryb3MgVmlhbGVzIHBvciBBw7FvIikNCg0KYGBgDQoNCg0KDQoNCg0KYGBge3IsIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD02fQ0KIyBBZ3J1cGFyIHkgY29udGFyIGFjY2lkZW50ZXMgcG9yIG1lcw0KYWNjaWRlbnRlc19wb3JfbWVzIDwtIGRhdG9zICU+JQ0KICBtdXRhdGUoc2luaWVzdHJvX2ZlY2hhID0gYXMuRGF0ZShzaW5pZXN0cm9fZmVjaGEpKSAlPiUNCiAgbXV0YXRlKG1lcyA9IGZvcm1hdChzaW5pZXN0cm9fZmVjaGEsICIlWS0lbSIpKSAlPiUNCiAgZ3JvdXBfYnkobWVzKSAlPiUNCiAgc3VtbWFyaXNlKGNhbnRpZGFkID0gbigpKQ0KDQojIENvbnZlcnRpciBsYSBjb2x1bW5hICdtZXMnIGEgRGF0ZSBwYXJhIGFzZWd1cmFyIHVuIGVqZSB4IGNvbnRpbnVvDQphY2NpZGVudGVzX3Bvcl9tZXMkbWVzIDwtIGFzLkRhdGUocGFzdGUwKGFjY2lkZW50ZXNfcG9yX21lcyRtZXMsICItMDEiKSkNCg0KIyBDcmVhciBlbCBncsOhZmljbyBkZSBhY2NpZGVudGVzIHBvciBtZXMNCg0KZ2dwbG90KGFjY2lkZW50ZXNfcG9yX21lcywgYWVzKHggPSBtZXMsIHkgPSBjYW50aWRhZCkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBnZW9tX3BvaW50KCkgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIEFjY2lkZW50ZXMgVmlhbGVzIHBvciBNZXMiLA0KICAgICAgIHggPSAiTWVzIiwNCiAgICAgICB5ID0gIkNhbnRpZGFkIGRlIEFjY2lkZW50ZXMiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlYiAtICV5IiwgZGF0ZV9icmVha3MgPSAiMSBtb250aCIpICsgICMgVXNhciBhYnJldmlhdHVyYXMgZGUgbWVzDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSwgc2l6ZSA9IDgpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbigxMCwgMTAsIDYwLCAxMCkpIA0KDQpgYGANCmBgYHtyfQ0KIyBBZ3J1cGFyIHkgY29udGFyIGFjY2lkZW50ZXMgcG9yIG1lcw0KYWNjaWRlbnRlc19wb3JfbWVzIDwtIGRhdG9zICU+JQ0KICBtdXRhdGUoc2luaWVzdHJvX2ZlY2hhID0gYXMuRGF0ZShzaW5pZXN0cm9fZmVjaGEpKSAlPiUNCiAgbXV0YXRlKG1lcyA9IGZvcm1hdChzaW5pZXN0cm9fZmVjaGEsICIlQiIpKSAlPiUgICMgRm9ybWF0byBjb24gbm9tYnJlIGNvbXBsZXRvIGRlbCBtZXMNCiAgZ3JvdXBfYnkobWVzKSAlPiUNCiAgc3VtbWFyaXNlKGNhbnRpZGFkID0gbigpKQ0KDQojIFJlb3JkZW5hciBlbCBmYWN0b3IgJ21lcycgcGFyYSBxdWUgZXN0w6kgZW4gb3JkZW4gY3Jvbm9sw7NnaWNvDQphY2NpZGVudGVzX3Bvcl9tZXMkbWVzIDwtIGZhY3RvcihhY2NpZGVudGVzX3Bvcl9tZXMkbWVzLCBsZXZlbHMgPSBjKCJlbmVybyIsICJmZWJyZXJvIiwgIm1hcnpvIiwgImFicmlsIiwgIm1heW8iLCAianVuaW8iLCAianVsaW8iLCAiYWdvc3RvIiwgInNlcHRpZW1icmUiLCAib2N0dWJyZSIsICJub3ZpZW1icmUiLCAiZGljaWVtYnJlIikpDQoNCiMgQ3JlYXIgZWwgZ3LDoWZpY28gZGUgYWNjaWRlbnRlcyBwb3IgbWVzDQpnZ3Bsb3QoYWNjaWRlbnRlc19wb3JfbWVzLCBhZXMoeCA9IG1lcywgeSA9IGNhbnRpZGFkKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJza3libHVlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnModGl0bGUgPSAiQ2FudGlkYWQgZGUgQWNjaWRlbnRlcyBWaWFsZXMgcG9yIE1lcyIsDQogICAgICAgeCA9ICJNZXMiLA0KICAgICAgIHkgPSAiQ2FudGlkYWQgZGUgQWNjaWRlbnRlcyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQpgYGB7cn0NCiMgQ3JlYXIgdW5hIGNvbHVtbmEgcGFyYSBlbCBkw61hIGRlIGxhIHNlbWFuYSBlbiBmb3JtYXRvIGRlIGV0aXF1ZXRhDQpkYXRvcyA8LSBkYXRvcyAlPiUNCiAgbXV0YXRlKGRpYV9zZW1hbmFfZXRpcXVldGEgPSBmb3JtYXQoc2luaWVzdHJvX2ZlY2hhLCAiJWEiKSAlPiUgdG9sb3dlcigpKQ0KDQojIERlZmluaXIgZWwgb3JkZW4gZGVzZWFkbyBkZSBsb3MgZMOtYXMgZGUgbGEgc2VtYW5hDQpvcmRlbl9kaWFzIDwtIGMoImx1bi4iLCAibWFyLiIsICJtacOpLiIsICJqdWUuIiwgInZpZS4iLCAic8OhYi4iLCAiZG9tLiIpDQoNCiMgQ29udGFyIGxvcyBzaW5pZXN0cm9zIHBvciBkw61hIGRlIGxhIHNlbWFuYSB5IGFzZWd1cmFyIGVsIG9yZGVuIGNvcnJlY3RvDQpzaW5pZXN0cm9zX3Bvcl9kaWFfc2VtYW5hIDwtIGRhdG9zICU+JQ0KICBjb3VudChkaWFfc2VtYW5hX2V0aXF1ZXRhKSAlPiUNCiAgbXV0YXRlKGRpYV9zZW1hbmFfZXRpcXVldGEgPSBmYWN0b3IoZGlhX3NlbWFuYV9ldGlxdWV0YSwgbGV2ZWxzID0gb3JkZW5fZGlhcykpDQoNCiMgQ3JlYXIgZWwgZ3LDoWZpY28gZGUgYmFycmFzIHBvciBkw61hIGRlIGxhIHNlbWFuYQ0KZ2dwbG90KHNpbmllc3Ryb3NfcG9yX2RpYV9zZW1hbmEsIGFlcyh4ID0gZGlhX3NlbWFuYV9ldGlxdWV0YSwgeSA9IG4pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInNreWJsdWUiKSArDQogIGxhYnModGl0bGUgPSAiQ2FudGlkYWQgZGUgU2luaWVzdHJvcyBWaWFsZXMgcG9yIETDrWEgZGUgbGEgU2VtYW5hIiwNCiAgICAgICB4ID0gIkTDrWEgZGUgbGEgU2VtYW5hIiwNCiAgICAgICB5ID0gIkNhbnRpZGFkIGRlIFNpbmllc3Ryb3MiKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYyhsdW4gPSAiTHVuIiwgbWFyID0gIk1hciIsIG1pw6kgPSAiTWnDqSIsIGp1ZSA9ICJKdWUiLCB2aWUgPSAiVmllIiwgc8OhYiA9ICJTw6FiIiwgZG9tID0gIkRvbSIpKSArICAjIEV0aXF1ZXRhcyBpbnZvbHVjcmFkb3NsaXphZGFzDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCmBgYHtyfQ0KIyBDcmVhciBjb2x1bW5hcyBwYXJhIGVsIGTDrWEgZGUgbGEgc2VtYW5hIGVuIGZvcm1hdG8gZGUgZXRpcXVldGEgeSBwYXJhIGVsIG1lcw0KZGF0b3MgPC0gZGF0b3MgJT4lDQogIG11dGF0ZShkaWFfc2VtYW5hX2V0aXF1ZXRhID0gZm9ybWF0KHNpbmllc3Ryb19mZWNoYSwgIiVhIikgJT4lIHRvbG93ZXIoKSwNCiAgICAgICAgIG1lc19ldGlxdWV0YSA9IGZvcm1hdChzaW5pZXN0cm9fZmVjaGEsICIlYiIpICU+JSB0b2xvd2VyKCkpDQoNCiMgRGVmaW5pciBlbCBvcmRlbiBkZXNlYWRvIGRlIGxvcyBkw61hcyBkZSBsYSBzZW1hbmEgeSBsb3MgbWVzZXMNCm9yZGVuX2RpYXMgPC0gYygibHVuLiIsICJtYXIuIiwgIm1pw6kuIiwgImp1ZS4iLCAidmllLiIsICJzw6FiLiIsICJkb20uIikNCm9yZGVuX21lc2VzIDwtIGMoImVuZS4iLCAiZmViLiIsICJtYXIuIiwgImFici4iLCAibWF5LiIsICJqdW4uIiwgImp1bC4iLCAiYWdvLiIsICJzZXAuIiwgIm9jdC4iLCAibm92LiIsICJkaWMuIikNCg0KIyBDb250YXIgbG9zIHNpbmllc3Ryb3MgcG9yIGTDrWEgZGUgbGEgc2VtYW5hIHkgbWVzLCB5IGFzZWd1cmFyIGVsIG9yZGVuIGNvcnJlY3RvDQpzaW5pZXN0cm9zX3Bvcl9kaWFfbWVzIDwtIGRhdG9zICU+JQ0KICBjb3VudChkaWFfc2VtYW5hX2V0aXF1ZXRhLCBtZXNfZXRpcXVldGEpICU+JQ0KICBtdXRhdGUoZGlhX3NlbWFuYV9ldGlxdWV0YSA9IGZhY3RvcihkaWFfc2VtYW5hX2V0aXF1ZXRhLCBsZXZlbHMgPSBvcmRlbl9kaWFzKSwNCiAgICAgICAgIG1lc19ldGlxdWV0YSA9IGZhY3RvcihtZXNfZXRpcXVldGEsIGxldmVscyA9IG9yZGVuX21lc2VzKSkNCg0KIyBDcmVhciBsYSBtYXRyaXogZGUgY2Fsb3INCmdncGxvdChzaW5pZXN0cm9zX3Bvcl9kaWFfbWVzLCBhZXMoeCA9IG1lc19ldGlxdWV0YSwgeSA9IGRpYV9zZW1hbmFfZXRpcXVldGEsIGZpbGwgPSBuKSkgKw0KICBnZW9tX3RpbGUoY29sb3IgPSAid2hpdGUiKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gInNreWJsdWUiLCBoaWdoID0gInJlZCIsIG5hbWUgPSAiQ2FudGlkYWQgZGUgU2luaWVzdHJvcyIpICsNCiAgbGFicyh0aXRsZSA9ICJDYW50aWRhZCBkZSBTaW5pZXN0cm9zIFZpYWxlcyBwb3IgRMOtYSBkZSBsYSBTZW1hbmEgeSBNZXMiLA0KICAgICAgIHggPSAiTWVzIiwNCiAgICAgICB5ID0gIkTDrWEgZGUgbGEgU2VtYW5hIikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGMoImVuZSIgPSAiRW5lIiwgImZlYiIgPSAiRmViIiwgIm1hciIgPSAiTWFyIiwgImFiciIgPSAiQWJyIiwgIm1heSIgPSAiTWF5IiwgImp1biIgPSAiSnVuIiwgImp1bCIgPSAiSnVsIiwgImFnbyIgPSAiQWdvIiwgInNlcCIgPSAiU2VwIiwgIm9jdCIgPSAiT2N0IiwgIm5vdiIgPSAiTm92IiwgImRpYyIgPSAiRGljIikpICsgICMgRXRpcXVldGFzIGludm9sdWNyYWRvc2xpemFkYXMNCiAgc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBjKCJsdW4uIiA9ICJMdW4iLCAibWFyLiIgPSAiTWFyIiwgIm1pw6kuIiA9ICJNacOpIiwgImp1ZS4iID0gIkp1ZSIsICJ2aWUuIiA9ICJWaWUiLCAic8OhYi4iID0gIlPDoWIiLCAiZG9tLiIgPSAiRG9tIikpICsgICMgRXRpcXVldGFzIGludm9sdWNyYWRvc2xpemFkYXMNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KYGBge3J9DQojIENvbnZlcnRpciBzaW5pZXN0cm9faG9yYSBhIGZvcm1hdG8gZGUgaG9yYQ0KZGF0b3Mkc2luaWVzdHJvX2hvcmEgPC0gaG1zOjphc19obXMoZGF0b3Mkc2luaWVzdHJvX2hvcmEpDQoNCiMgRXh0cmFlciBsYSBob3JhIGNvbW8gdW4gbsO6bWVybyBlbnRlcm8gKDAgYSAyMykNCmRhdG9zIDwtIGRhdG9zICU+JQ0KICBtdXRhdGUoaG9yYSA9IGhvdXIoc2luaWVzdHJvX2hvcmEpKQ0KDQojIEdyw6FmaWNvIGRlIGJhcnJhcyBkZSBzaW5pZXN0cm9zIHBvciBob3JhIGRlbCBkw61hDQpnZ3Bsb3QoZGF0b3MsIGFlcyh4ID0gZmFjdG9yKGhvcmEpKSkgKw0KICBnZW9tX2JhcihmaWxsID0gInNreWJsdWUiKSArDQogIGxhYnModGl0bGUgPSAiQ2FudGlkYWQgZGUgU2luaWVzdHJvcyBWaWFsZXMgcG9yIEhvcmEgZGVsIETDrWEiLA0KICAgICAgIHggPSAiSG9yYSBkZWwgRMOtYSIsDQogICAgICAgeSA9ICJDYW50aWRhZCBkZSBTaW5pZXN0cm9zIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KIyBDb250YXIgbG9zIHNpbmllc3Ryb3MgcG9yIG1lcyB5IGhvcmENCnNpbmllc3Ryb3NfcG9yX21lc19ob3JhIDwtIGRhdG9zICU+JQ0KICBjb3VudChtZXNfZXRpcXVldGEsIGhvcmEpICU+JQ0KICBtdXRhdGUobWVzX2V0aXF1ZXRhID0gZmFjdG9yKG1lc19ldGlxdWV0YSwgbGV2ZWxzID0gb3JkZW5fbWVzZXMpKQ0KDQojIENyZWFyIGxhIG1hdHJpeiBkZSBjYWxvcg0KZ2dwbG90KHNpbmllc3Ryb3NfcG9yX21lc19ob3JhLCBhZXMoeCA9IG1lc19ldGlxdWV0YSwgeSA9IGZhY3Rvcihob3JhKSwgZmlsbCA9IG4pKSArDQogIGdlb21fdGlsZShjb2xvciA9ICJ3aGl0ZSIpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAic2t5Ymx1ZSIsIGhpZ2ggPSAicmVkIiwgbmFtZSA9ICJDYW50aWRhZCBkZSBTaW5pZXN0cm9zIikgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIFNpbmllc3Ryb3MgVmlhbGVzIHBvciBNZXMgeSBIb3JhIGRlbCBEw61hIiwNCiAgICAgICB4ID0gIk1lcyIsDQogICAgICAgeSA9ICJIb3JhIGRlbCBEw61hIikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGMoImVuZSIgPSAiRW5lIiwgImZlYiIgPSAiRmViIiwgIm1hciIgPSAiTWFyIiwgImFiciIgPSAiQWJyIiwgIm1heSIgPSAiTWF5IiwgImp1biIgPSAiSnVuIiwgImp1bCIgPSAiSnVsIiwgImFnbyIgPSAiQWdvIiwgInNlcCIgPSAiU2VwIiwgIm9jdCIgPSAiT2N0IiwgIm5vdiIgPSAiTm92IiwgImRpYyIgPSAiRGljIikpICsgICMgRXRpcXVldGFzIGludm9sdWNyYWRvc2xpemFkYXMNCiAgc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBhcy5jaGFyYWN0ZXIoMDoyMykpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCiMgSGVhdG1hcCBkZSBzaW5pZXN0cm9zIHBvciBob3JhIGRlbCBkw61hIHkgZMOtYSBkZSBsYSBzZW1hbmENCnNpbmllc3Ryb3NfcG9yX2hvcmFfZGlhX3NlbWFuYSA8LSBkYXRvcyAlPiUNCiAgY291bnQoZGlhX3NlbWFuYV9ldGlxdWV0YSwgaG9yYSkgJT4lDQogIG11dGF0ZShkaWFfc2VtYW5hX2V0aXF1ZXRhID0gZmFjdG9yKGRpYV9zZW1hbmFfZXRpcXVldGEsIGxldmVscyA9IG9yZGVuX2RpYXMpKQ0KDQpnZ3Bsb3Qoc2luaWVzdHJvc19wb3JfaG9yYV9kaWFfc2VtYW5hLCBhZXMoeCA9IGZhY3Rvcihob3JhKSwgeSA9IGRpYV9zZW1hbmFfZXRpcXVldGEsIGZpbGwgPSBuKSkgKw0KICBnZW9tX3RpbGUoY29sb3IgPSAid2hpdGUiKSArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gInNreWJsdWUiLCBoaWdoID0gInJlZCIsIG5hbWUgPSAiQ2FudGlkYWQgZGUgU2luaWVzdHJvcyIpICsNCiAgbGFicyh0aXRsZSA9ICJDYW50aWRhZCBkZSBTaW5pZXN0cm9zIFZpYWxlcyBwb3IgSG9yYSBkZWwgRMOtYSB5IETDrWEgZGUgbGEgU2VtYW5hIiwNCiAgICAgICB4ID0gIkhvcmEgZGVsIETDrWEiLA0KICAgICAgIHkgPSAiRMOtYSBkZSBsYSBTZW1hbmEiKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYXMuY2hhcmFjdGVyKDA6MjMpKSArDQogIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYygibHVuLiIgPSAiTHVuIiwgIm1hci4iID0gIk1hciIsICJtacOpLiIgPSAiTWnDqSIsICJqdWUuIiA9ICJKdWUiLCAidmllLiIgPSAiVmllIiwgInPDoWIuIiA9ICJTw6FiIiwgImRvbS4iID0gIkRvbSIpKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCg0KYGBge3J9DQojIEZpbHRyYXIgbG9zIGRhdG9zIHBhcmEgZWxpbWluYXIgbGFzIGZpbGFzIGNvbiAiUy9EIiBlbiBjYXRlZ29yaWFfc2luaWVzdHJvDQpkYXRvc19maWx0cmFkb3MgPC0gZGF0b3MgJT4lDQogIGZpbHRlcihjYXRlZ29yaWFfc2luaWVzdHJvICE9ICJTL0QiKQ0KDQojIENvbnRhciBsb3Mgc2luaWVzdHJvcyBwb3IgY2F0ZWdvcsOtYQ0Kc2luaWVzdHJvc19wb3JfY2F0ZWdvcmlhIDwtIGRhdG9zX2ZpbHRyYWRvcyAlPiUNCiAgY291bnQoY2F0ZWdvcmlhX3Npbmllc3RybykNCg0KDQojIENyZWFyIGVsIGdyw6FmaWNvIGRlIGJhcnJhcyBwb3IgY2F0ZWdvcsOtYQ0KZ2dwbG90KHNpbmllc3Ryb3NfcG9yX2NhdGVnb3JpYSwgYWVzKHggPSBjYXRlZ29yaWFfc2luaWVzdHJvLCB5ID0gbiwgZmlsbCA9IGNhdGVnb3JpYV9zaW5pZXN0cm8pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGxhYnModGl0bGUgPSAiQ2FudGlkYWQgZGUgU2luaWVzdHJvcyBWaWFsZXMgcG9yIENhdGVnb3LDrWEiLA0KICAgICAgIHggPSAiQ2F0ZWdvcsOtYSBkZWwgU2luaWVzdHJvIiwNCiAgICAgICB5ID0gIkNhbnRpZGFkIGRlIFNpbmllc3Ryb3MiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoImZhdGFsIiA9ICJyZWQiLCAibm8gZmF0YWwiID0gInNreWJsdWUiKSwgbmFtZSA9ICJDYXRlZ29yw61hIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpgYGB7cn0NCiMgRmlsdHJhciBsb3MgZGF0b3MgcGFyYSBlbGltaW5hciBsYXMgZmlsYXMgY29uICJTL0QiIGVuIHpvbmFfb2N1cnJlbmNpYSAoc2kgZXMgbmVjZXNhcmlvKQ0KZGF0b3NfZmlsdHJhZG9zX3pvbmEgPC0gZGF0b3MgJT4lDQogIGZpbHRlcih6b25hX29jdXJyZW5jaWEgIT0gIlMvRCIsIHpvbmFfb2N1cnJlbmNpYSAhPSAiIikNCg0KIyBDb250YXIgbG9zIHNpbmllc3Ryb3MgcG9yIHpvbmFfb2N1cnJlbmNpYQ0Kc2luaWVzdHJvc19wb3Jfem9uYSA8LSBkYXRvc19maWx0cmFkb3Nfem9uYSAlPiUNCiAgY291bnQoem9uYV9vY3VycmVuY2lhKQ0KDQojIENyZWFyIGVsIGdyw6FmaWNvIGRlIGJhcnJhcyBwb3Igem9uYV9vY3VycmVuY2lhDQpnZ3Bsb3Qoc2luaWVzdHJvc19wb3Jfem9uYSwgYWVzKHggPSB6b25hX29jdXJyZW5jaWEsIHkgPSBuLCBmaWxsID0gem9uYV9vY3VycmVuY2lhKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIFNpbmllc3Ryb3MgVmlhbGVzIHBvciBab25hIGRlIE9jdXJyZW5jaWEiLA0KICAgICAgIHggPSAiWm9uYSBkZSBPY3VycmVuY2lhIiwNCiAgICAgICB5ID0gIkNhbnRpZGFkIGRlIFNpbmllc3Ryb3MiKSArDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZSA9ICJab25hIGRlIE9jdXJyZW5jaWEiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg0KDQoNCmBgYHtyfQ0KIyBGaWx0cmFyIGxvcyBkYXRvcyBwYXJhIGVsaW1pbmFyIGxhcyBmaWxhcyBjb24gIlMvRCIgZW4gdmlhX3B1YmxpY2EgKHNpIGVzIG5lY2VzYXJpbykNCmRhdG9zX2ZpbHRyYWRvc192aWEgPC0gZGF0b3MgJT4lDQogIGZpbHRlcih2aWFfcHVibGljYSAhPSAiUy9EIiwgdmlhX3B1YmxpY2EgIT0gIiIpDQoNCiMgQ29udGFyIGxvcyBzaW5pZXN0cm9zIHBvciB2aWFfcHVibGljYQ0Kc2luaWVzdHJvc19wb3JfdmlhIDwtIGRhdG9zX2ZpbHRyYWRvc192aWEgJT4lDQogIGNvdW50KHZpYV9wdWJsaWNhKQ0KDQojIENyZWFyIGVsIGdyw6FmaWNvIGRlIGJhcnJhcyBwb3IgdmlhX3B1YmxpY2ENCmdncGxvdChzaW5pZXN0cm9zX3Bvcl92aWEsIGFlcyh4ID0gdmlhX3B1YmxpY2EsIHkgPSBuLCBmaWxsID0gdmlhX3B1YmxpY2EpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGxhYnModGl0bGUgPSAiQ2FudGlkYWQgZGUgU2luaWVzdHJvcyBWaWFsZXMgcG9yIFbDrWEgUMO6YmxpY2EiLA0KICAgICAgIHggPSAiVsOtYSBQw7pibGljYSIsDQogICAgICAgeSA9ICJDYW50aWRhZCBkZSBTaW5pZXN0cm9zIikgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWUgPSAiVsOtYSBQw7pibGljYSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KYGBgDQoNCg0KYGBge3J9DQojIEZpbHRyYXIgbG9zIGRhdG9zIHBhcmEgZWxpbWluYXIgbGFzIGZpbGFzIGNvbiAiUy9EIiBlbiB0aXBvX3Npbmllc3Ryb191bmljbyAoc2kgZXMgbmVjZXNhcmlvKQ0KZGF0b3NfZmlsdHJhZG9zX3RpcG8gPC0gZGF0b3MgJT4lDQogIGZpbHRlcih0aXBvX3Npbmllc3Ryb191bmljbyAhPSAiUy9EIiwgdGlwb19zaW5pZXN0cm9fdW5pY28gIT0gIiIpDQoNCiMgQ29udGFyIGxvcyBzaW5pZXN0cm9zIHBvciB0aXBvX3Npbmllc3Ryb191bmljbw0Kc2luaWVzdHJvc19wb3JfdGlwbyA8LSBkYXRvc19maWx0cmFkb3NfdGlwbyAlPiUNCiAgY291bnQodGlwb19zaW5pZXN0cm9fdW5pY28pDQoNCiMgQ3JlYXIgZWwgZ3LDoWZpY28gZGUgYmFycmFzIHBvciB0aXBvX3Npbmllc3Ryb191bmljbw0KZ2dwbG90KHNpbmllc3Ryb3NfcG9yX3RpcG8sIGFlcyh4ID0gdGlwb19zaW5pZXN0cm9fdW5pY28sIHkgPSBuLCBmaWxsID0gdGlwb19zaW5pZXN0cm9fdW5pY28pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGxhYnModGl0bGUgPSAiQ2FudGlkYWQgZGUgU2luaWVzdHJvcyBWaWFsZXMgcG9yIFRpcG8gZGUgU2luaWVzdHJvIMOabmljbyIsDQogICAgICAgeCA9ICJUaXBvIGRlIFNpbmllc3RybyDDmm5pY28iLA0KICAgICAgIHkgPSAiQ2FudGlkYWQgZGUgU2luaWVzdHJvcyIpICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lID0gIlRpcG8gZGUgU2luaWVzdHJvIMOabmljbyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQpgYGB7cn0NCiMgRmlsdHJhciBsb3MgZGF0b3MgcGFyYSBlbGltaW5hciBsYXMgZmlsYXMgY29uICJTL0QiIGVuIG1hdGVyaWFsX2NhbHphZGEgKHNpIGVzIG5lY2VzYXJpbykNCmRhdG9zX2ZpbHRyYWRvc19tYXRlcmlhbCA8LSBkYXRvcyAlPiUNCiAgZmlsdGVyKG1hdGVyaWFsX2RlX2xhX2NhbHphZGEgIT0gIlMvRCIsIG1hdGVyaWFsX2RlX2xhX2NhbHphZGEgIT0gIiIpDQoNCiMgQ29udGFyIGxvcyBzaW5pZXN0cm9zIHBvciBtYXRlcmlhbF9jYWx6YWRhDQpzaW5pZXN0cm9zX3Bvcl9tYXRlcmlhbCA8LSBkYXRvc19maWx0cmFkb3NfbWF0ZXJpYWwgJT4lDQogIGNvdW50KG1hdGVyaWFsX2RlX2xhX2NhbHphZGEpDQoNCiMgQ3JlYXIgZWwgZ3LDoWZpY28gZGUgYmFycmFzIHBvciBtYXRlcmlhbF9jYWx6YWRhDQpnZ3Bsb3Qoc2luaWVzdHJvc19wb3JfbWF0ZXJpYWwsIGFlcyh4ID0gbWF0ZXJpYWxfZGVfbGFfY2FsemFkYSwgeSA9IG4sIGZpbGwgPSBtYXRlcmlhbF9kZV9sYV9jYWx6YWRhKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIFNpbmllc3Ryb3MgVmlhbGVzIHBvciBNYXRlcmlhbCBkZSBsYSBDYWx6YWRhIiwNCiAgICAgICB4ID0gIk1hdGVyaWFsIGRlIGxhIENhbHphZGEiLA0KICAgICAgIHkgPSAiQ2FudGlkYWQgZGUgU2luaWVzdHJvcyIpICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lID0gIk1hdGVyaWFsIGRlIGxhIENhbHphZGEiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg==