Introducción:

El cálculo del tamaño de muestra es una etapa crucial en el diseño de estudios. Cuando deseamos estimar una proporción, debemos considerar:

En estos ejercicio 1, utilizaremos el paquete pwr para calcular el tamaño de muestra necesario para conocer la prevalencia de diabetes en una población, suponiendo que: - Nivel de confianza: 95% - Precisión deseada: 5% - Proporción esperada: 50% (0.5).

Es necesario instalar los siguientes paquetes:

install.packages("pwr")
library(pwr)

Fórmula para Estimar el Tamaño de Muestra:

El cálculo del tamaño de muestra para estimar una proporción se realiza con la fórmula:

knitr::include_graphics(
  "C:/Users/Silvi/OneDrive/Imágenes/Screenshots/Captura de pantalla 2025-12-13 235356.png"
)

Donde:

Aunque el paquete pwr simplifica este cálculo, también lo podemos hacer manualmente paso a paso cómo hacerlo con R.

Cálculo del Tamaño de Muestra Método 1: Cálculo Manual Utilizando directamente la fórmula.

# Parámetros
Z <- 1.96  # Nivel de confianza para 95%
p <- 0.5   # Proporción esperada
e <- 0.05  # Precisión deseada (5%)
# Cálculo del tamaño de muestra
n_manual <- (Z^2 * p * (1 - p)) / (e^2)
cat("Tamaño de muestra necesario (método manual):", ceiling(n_manual), "\n")
Tamaño de muestra necesario (método manual): 385 

Método 2: Usar el Paquete pwr El paquete pwr proporciona una manera intuitiva para calcular el tamaño de muestra utilizando funciones predefinidas.

knitr::include_graphics(
  "C:/Users/Silvi/OneDrive/Imágenes/Screenshots/Captura de pantalla 2025-12-13 235526.png"
)

# Parámetros
N <- 10000  # Tamaño de la población
Z <- 1.96   # Nivel de confianza para 95%
p <- 0.05   # Proporción esperada (5%)
q <- 1 - p  # Complemento de la proporción
d <- 0.03   # Precisión deseada (3%)
# Calcular tamaño de muestra
n <- (N * Z^2 * p * q) / ((d^2 * (N - 1)) + (Z^2 * p * q))

cat("Tamaño de muestra necesario:", ceiling(n), "\n")
Tamaño de muestra necesario: 199 
# Variar precisión
precisiones <- seq(0.01, 0.1, by = 0.01)
tamaños_muestra <- sapply(precisiones, function(d) {
  (N * Z^2 * p * q) / ((d^2 * (N - 1)) + (Z^2 * p * q))
})

# Crear data frame para el gráfico
datos_grafico <- data.frame(
  Precision = precisiones,
  Tamaño_Muestra = ceiling(tamaños_muestra)
)

# Graficar
library(ggplot2)
ggplot(datos_grafico, aes(x = Precision, y = Tamaño_Muestra)) +
  geom_line(color = "blue", size = 1) +
  geom_point(color = "red") +
  labs(
    title = "Relación entre Precisión y Tamaño de Muestra en Poblaciones Finitas",
    x = "Precisión Deseada (d)",
    y = "Tamaño de Muestra"
  ) +
  theme_minimal()

Paso del paquete pwr Uso del paquete: El paquete pwr utiliza una metodología basada en el cálculo del tamaño del efecto (h), definido por:

La función arcsin es una transformación matemática conocida como la transformación angular de Freeman-Tukey o transformación del arco seno. Se utiliza comúnmente en estadísticas para manejar proporciones o probabilidades (p) y mejorar ciertas propiedades de análisis, especialmente en pruebas de hipótesis para proporciones.

Propósito de la transformación arcsin

Normalizar proporciones:

Proporciones (p) están restringidas al rango [0, 1], lo que significa que no son simétricas ni normales. Esta transformación convierte las proporciones en un valor que puede aproximarse mejor a una distribución normal, lo cual es útil para cálculos estadísticos. Estabilizar la varianza:

En análisis de proporciones, la varianza tiende a cambiar dependiendo de (es más alta cuando está cerca de 0.5 y más baja cerca de 0 o 1). La transformación arcsin(raizcuadrada de p​) estabiliza la varianza, haciendo que los cálculos sean más consistentes. En pruebas de hipótesis para proporciones, como en el cálculo del tamaño de muestra usando pwr.p.test, necesitamos definir el tamaño del efecto hhh para comparar proporciones observadas y esperadas. La transformación arcsin⁡(raizcuadrada de p):

Permite comparar proporciones en un espacio donde las diferencias tienen un impacto constante, independientemente de si p está cerca de 0 o de 1.

Esto simplifica el cálculo del tamaño de muestra, porque el tamaño del efecto (h) se interpreta como una distancia entre dos proporciones en este espacio transformado.

Tamaño del efecto en pruebas estadísticas:

En el contexto de pruebas de hipótesis y cálculos de poder estadístico (como en el paquete pwr), esta transformación es utilizada para definir el tamaño del efecto (h) de una proporción en un marco que considera valores más manejables y simétricos. Prueba de hipótesis en pwr.p.test:

En lugar de simplemente calcular un tamaño de muestra para estimar p, pwr.p.test incluye:

El nivel de significancia α, como 0.05 para un 95% de confianza).

El poder estadístico (1−β), normalmente 0.8 o 80%).

Esto significa que el cálculo considera la probabilidad de detectar un efecto real dado un nivel de confianza y un poder.

Diferencia en resultados: El cálculo usando pwr.p.test genera un tamaño de muestra más conservador porque incluye:

Poder estadístico (1−β1): La capacidad de detectar el efecto real.

Tamaño del efecto h: Un enfoque más general que transforma proporciones.

Diferencia de Resultados Cálculo manual:

Asume una población infinita y se enfoca únicamente en estimar una proporción con una precisión deseada (eee).

No considera poder estadístico.

pwr.p.test:

Incluye el marco de pruebas de hipótesis y poder estadístico, lo que lleva a un tamaño de muestra más conservador.

Este enfoque es más robusto si el estudio requiere pruebas de hipótesis específicas (por ejemplo, comparar proporciones observadas con valores esperados).

Cuándo usar cada método Método manual:

Es adecuado cuando el objetivo es simplemente estimar una proporción dentro de un margen de error específico.

Útil para encuestas y estudios descriptivos.

Método con pwr.p.test:

Útil para estudios analíticos o experimentales que requieran pruebas de hipótesis.

Incluye poder estadístico, asegurando mayor confianza en los resultados.

INSERTAR IMAGENES:

knitr → es el paquete que procesa R Markdown

:: → indica que usas la función directamente desde el paquete

include_graphics() → función para insertar imágenes externas en el documento

Esta función no crea gráficos, solo muestra imágenes (PNG, JPG, etc.)

knitr::include_graphics(
  "C:/Users/Silvi/OneDrive/Imágenes/Screenshots/Calculo de la muestra.png"
)

NA

Donde:

En este ejercicio, calcularemos el tamaño de muestra para una población finita con:

Cálculo del Tamaño de Muestra Paso 1: Parámetros Iniciales Definimos los valores dados en el problema.

# Parámetros
N <- 10000  # Tamaño de la población
Z <- 1.96   # Nivel de confianza para 95%
p <- 0.05   # Proporción esperada (5%)
q <- 1 - p  # Complemento de la proporción
d <- 0.03   # Precisión deseada (3%)

Paso 2: Implementar la Fórmula Utilizamos la fórmula para calcular el tamaño de la muestra.

# Calcular tamaño de muestra
n <- (N * Z^2 * p * q) / ((d^2 * (N - 1)) + (Z^2 * p * q))

cat("Tamaño de muestra necesario:", ceiling(n), "\n")
Tamaño de muestra necesario: 199 

Visualización de los Resultados Cómo Varía el Tamaño de Muestra con Diferentes Niveles de Precisión Creamos un gráfico que muestre cómo el tamaño de muestra cambia con diferentes valores de d (precisión).

# Variar precisión
precisiones <- seq(0.01, 0.1, by = 0.01)
tamaños_muestra <- sapply(precisiones, function(d) {
  (N * Z^2 * p * q) / ((d^2 * (N - 1)) + (Z^2 * p * q))
})

# Crear data frame para el gráfico
datos_grafico <- data.frame(
  Precision = precisiones,
  Tamaño_Muestra = ceiling(tamaños_muestra)
)

# Graficar
library(ggplot2)
ggplot(datos_grafico, aes(x = Precision, y = Tamaño_Muestra)) +
  geom_line(color = "blue", size = 1) +
  geom_point(color = "red") +
  labs(
    title = "Relación entre Precisión y Tamaño de Muestra en Poblaciones Finitas",
    x = "Precisión Deseada (d)",
    y = "Tamaño de Muestra"
  ) +
  theme_minimal()

Reflexión

Puntos Clave:

  1. Relación Precisión-Tamaño: El tamaño de muestra crece rápidamente cuando la precisión deseada d es más pequeña.

  2. Impacto del Tamaño Poblacional: A medida que n aumenta, el ajuste por población finita es menos significativo, y el tamaño de muestra se aproxima al cálculo para poblaciones infinitas.

Parámetros Iniciales

Definimos los valores necesarios para el cálculo. En este ejercicio, calcularemos el tamaño de muestra necesario para estudiar la prevalencia de diabetes en una población finita de 15,000 habitantes, con:

knitr::include_graphics(
  "C:/Users/Silvi/OneDrive/Imágenes/Screenshots/Calculo de la muestra.png"
)

Donde:

- ( N ): Tamaño de la población (15,000).

- ( Z ): Valor Z para un nivel de confianza del 95% (( Z = 1.96 )).

- ( p ): Proporción esperada. -

( q ): Complemento de ( p ) (( q = 1 - p )). -

( d ): Precisión deseada.

Definimos los valores necesarios para el cálculo.

# Parámetros
N <- 15000  # Tamaño de la población
Z <- 1.96   # Nivel de confianza para 95%
p <- 0.05   # Proporción esperada (5%)
q <- 1 - p  # Complemento de la proporción
d <- 0.03   # Precisión deseada (3%)

# Calcular tamaño de muestra para población finita
n <- (N * Z^2 * p * q) / ((d^2 * (N - 1)) + (Z^2 * p * q))

cat("Tamaño de muestra necesario:", ceiling(n), "\n")
Tamaño de muestra necesario: 201 

Interpretación:

El cálculo muestra que necesitamos estudiar aproximadamente 200 personas para estimar la prevalencia de diabetes en una población de 15,000 habitantes, con un nivel de confianza del 95% y una precisión del 3%.

# Variar precisión
precisiones <- seq(0.01, 0.1, by = 0.01)
tamaños_muestra <- sapply(precisiones, function(d) {
  (N * Z^2 * p * q) / ((d^2 * (N - 1)) + (Z^2 * p * q))
})

# Crear data frame para el gráfico
datos_grafico <- data.frame(
  Precision = precisiones,
  Tamaño_Muestra = ceiling(tamaños_muestra)
)

# Graficar
library(ggplot2)
ggplot(datos_grafico, aes(x = Precision, y = Tamaño_Muestra)) +
  geom_line(color = "blue", size = 1) +
  geom_point(color = "red") +
  labs(
    title = "Relación entre Precisión y Tamaño de Muestra",
    x = "Precisión Deseada (d)",
    y = "Tamaño de Muestra"
  ) +
  theme_minimal()

knitr::include_graphics(
  "C:/Users/Silvi/OneDrive/Imágenes/Screenshots/Captura de pantalla 2025-12-14 000423.png"
)

# Parámetros
Z <- 1.96  # Nivel de confianza (95%)
S2 <- 250  # Varianza
d <- 3     # Precisión deseada

# Cálculo del tamaño de muestra
n_manual <- (Z^2 * S2) / (d^2)

cat("Tamaño de muestra (manual):", ceiling(n_manual), "\n")
Tamaño de muestra (manual): 107 

# Parámetros
Z_alpha <- 1.645  # Nivel de confianza (95%)
Z_beta <- 0.842   # Poder estadístico (80%)
p1 <- 0.7         # Proporción 1
p2 <- 0.9         # Proporción 2
p <- (p1 + p2) / 2  # Promedio de proporciones

# Cálculo del tamaño de muestra
n_manual <- ((Z_alpha * sqrt(2 * p * (1 - p)) + Z_beta * sqrt(p1 * (1 - p1) + p2 * (1 - p2)))^2) / (p1 - p2)^2

cat("Tamaño de muestra (manual):", ceiling(n_manual), "\n")
Tamaño de muestra (manual): 49 
# Instalar pwr si no está instalado
if (!requireNamespace("pwr", quietly = TRUE)) {
  install.packages("pwr")
}
library(pwr)

# Tamaño del efecto para proporciones
h <- ES.h(p1 = p1, p2 = p2)

# Calcular el tamaño de muestra
resultado <- pwr.2p.test(h = h, sig.level = 0.05, power = 0.8)

cat("Tamaño de muestra (con pwr):", ceiling(resultado$n), "\n")
Tamaño de muestra (con pwr): 60 

cat("Tamaño de muestra (manual):", ceiling(n_manual), "\n")
Tamaño de muestra (manual): 20 

Usando un Paquete: pwr

cat("Tamaño de muestra (con pwr):", ceiling(resultado$n), "\n")
Tamaño de muestra (con pwr): 25 

El paquete pwr también incluye la función pwr.t.test para calcular tamaños de muestra para la comparación de dos medias.

  • Tamaño del efecto d:

d = Diferencia esperada / DS

# Parámetros
Diferencia <- 15  # Diferencia esperada entre medias
S <- 16           # Desviación estándar
d <- Diferencia / S  # Tamaño del efecto

# Calcular tamaño de muestra
resultado <- pwr.t.test(d = d, sig.level = 0.05, power = 0.9, type = "two.sample")

cat("Tamaño de muestra para comparar dos medias (pwr):", ceiling(resultado$n), "por grupo\n")
Tamaño de muestra para comparar dos medias (pwr): 25 por grupo
  • Los cálculos manuales siguen las fórmulas clásicas.

  • El uso de paquetes como epiDisplay o pwr simplifica el proceso y permite ajustar parámetros como el nivel de confianza y el poder estadístico de forma más flexible.

Resultados del Paquete pwr

  • Estimación de una media: Usamos pwr.t.test con d=e/Sd = e / Sd=e/S.

  • Comparación de dos proporciones: Usamos pwr.2p.test, que calcula directamente tamaños de muestra para pruebas de hipótesis con proporciones.

  • Comparación de dos medias: Usamos pwr.t.test con d=Diferencia esperada/Desviacioˊn estaˊndard = \{Diferencia esperada} / \{Desviación estándard=Diferencia esperada/Desviacioˊn estándar.

¿Qué no cubre pwr directamente?

  • Poblaciones finitas: Necesitamos ajustar manualmente el tamaño de muestra calculado para considerar tamaños de población finitos.

  • Estimación de una media sin prueba de hipótesis: Aunque podemos adaptar el cálculo con pwr.t.test, el paquete está diseñado para pruebas de hipótesis.

LS0tDQp0aXRsZTogQ0FMQ1VMTyBERUwgVEFNQcORTyBERSBMQSBNVUVTVFJBDQpvdXRwdXQ6ICBodG1sX25vdGVib29rDQplZGl0b3Jfb3B0aW9uczogDQogIG1hcmtkb3duOiANCiAgICB3cmFwOiA3Mg0KLS0tDQoNCioqSW50cm9kdWNjacOzbioqOg0KDQpFbCBjw6FsY3VsbyBkZWwgdGFtYcOxbyBkZSBtdWVzdHJhIGVzIHVuYSBldGFwYSBjcnVjaWFsIGVuIGVsIGRpc2XDsW8gZGUNCmVzdHVkaW9zLiBDdWFuZG8gZGVzZWFtb3MgZXN0aW1hciB1bmEgcHJvcG9yY2nDs24sIGRlYmVtb3MgY29uc2lkZXJhcjoNCg0KLSAgIE5pdmVsIGRlIGNvbmZpYW56YSAoWs6xKTogUmVwcmVzZW50YSBsYSBwcm9iYWJpbGlkYWQgZGUgcXVlIGVsDQogICAgaW50ZXJ2YWxvIGRlIGNvbmZpYW56YSBjb250ZW5nYSBlbCB2YWxvciB2ZXJkYWRlcm8uIEVqZW1wbG86IDk1JSAoKA0KICAgIFogPSAxLjk2ICkpLg0KDQotICAgUHJlY2lzacOzbiBkZXNlYWRhICgoIGUgKSk6IERpZmVyZW5jaWEgbcOheGltYSBhY2VwdGFibGUgZW50cmUgbGENCiAgICBwcm9wb3JjacOzbiBlc3RpbWFkYSB5IGxhIHJlYWwuDQoNCi0gICBQcm9wb3JjacOzbiBlc3BlcmFkYSAoKCBwICkpOiBFc3RpbWFjacOzbiBpbmljaWFsIGJhc2FkYSBlbiBsaXRlcmF0dXJhDQogICAgbyBlc3R1ZGlvcyBwcmV2aW9zLg0KDQpFbiBlc3RvcyBlamVyY2ljaW8gMSwgdXRpbGl6YXJlbW9zIGVsIHBhcXVldGUgcHdyIHBhcmEgY2FsY3VsYXIgZWwNCnRhbWHDsW8gZGUgbXVlc3RyYSBuZWNlc2FyaW8gcGFyYSBjb25vY2VyIGxhIHByZXZhbGVuY2lhIGRlIGRpYWJldGVzIGVuDQp1bmEgcG9ibGFjacOzbiwgc3Vwb25pZW5kbyBxdWU6IC0gTml2ZWwgZGUgY29uZmlhbnphOiA5NSUgLSBQcmVjaXNpw7NuDQpkZXNlYWRhOiA1JSAtIFByb3BvcmNpw7NuIGVzcGVyYWRhOiA1MCUgKDAuNSkuDQoNCkVzIG5lY2VzYXJpbyBpbnN0YWxhciBsb3Mgc2lndWllbnRlcyBwYXF1ZXRlczoNCg0KYGBge3J9DQppbnN0YWxsLnBhY2thZ2VzKCJwd3IiKQ0KbGlicmFyeShwd3IpDQpgYGANCg0KKipGw7NybXVsYSBwYXJhIEVzdGltYXIgZWwgVGFtYcOxbyBkZSBNdWVzdHJhOioqDQoNCkVsIGPDoWxjdWxvIGRlbCB0YW1hw7FvIGRlIG11ZXN0cmEgcGFyYSBlc3RpbWFyIHVuYSBwcm9wb3JjacOzbiBzZSByZWFsaXphDQpjb24gbGEgZsOzcm11bGE6DQoNCmBgYHtyfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoDQogICJDOi9Vc2Vycy9TaWx2aS9PbmVEcml2ZS9JbcOhZ2VuZXMvU2NyZWVuc2hvdHMvQ2FwdHVyYSBkZSBwYW50YWxsYSAyMDI1LTEyLTEzIDIzNTM1Ni5wbmciDQopDQpgYGANCg0KRG9uZGU6DQoNCi0gICBaOiBWYWxvciBjb3JyZXNwb25kaWVudGUgYWwgbml2ZWwgZGUgY29uZmlhbnphIChlLmcuLCBaPTEuOTZaID0NCiAgICAxLjk2Wj0xLjk2IHBhcmEgOTUlKS4NCg0KLSAgIHA6IFByb3BvcmNpw7NuIGVzcGVyYWRhLg0KDQotICAgZTogUHJlY2lzacOzbiBkZXNlYWRhLg0KDQpBdW5xdWUgZWwgcGFxdWV0ZSBwd3Igc2ltcGxpZmljYSBlc3RlIGPDoWxjdWxvLCB0YW1iacOpbiBsbyBwb2RlbW9zIGhhY2VyDQptYW51YWxtZW50ZSBwYXNvIGEgcGFzbyBjw7NtbyBoYWNlcmxvIGNvbiBSLg0KDQpDw6FsY3VsbyBkZWwgVGFtYcOxbyBkZSBNdWVzdHJhIE3DqXRvZG8gMTogQ8OhbGN1bG8gTWFudWFsIFV0aWxpemFuZG8NCmRpcmVjdGFtZW50ZSBsYSBmw7NybXVsYS4NCg0KYGBge3J9DQojIFBhcsOhbWV0cm9zDQpaIDwtIDEuOTYgICMgTml2ZWwgZGUgY29uZmlhbnphIHBhcmEgOTUlDQpwIDwtIDAuNSAgICMgUHJvcG9yY2nDs24gZXNwZXJhZGENCmUgPC0gMC4wNSAgIyBQcmVjaXNpw7NuIGRlc2VhZGEgKDUlKQ0KDQpgYGANCg0KYGBge3J9DQojIEPDoWxjdWxvIGRlbCB0YW1hw7FvIGRlIG11ZXN0cmENCm5fbWFudWFsIDwtIChaXjIgKiBwICogKDEgLSBwKSkgLyAoZV4yKQ0KYGBgDQoNCmBgYHtyfQ0KY2F0KCJUYW1hw7FvIGRlIG11ZXN0cmEgbmVjZXNhcmlvIChtw6l0b2RvIG1hbnVhbCk6IiwgY2VpbGluZyhuX21hbnVhbCksICJcbiIpDQpgYGANCg0KTcOpdG9kbyAyOiBVc2FyIGVsIFBhcXVldGUgcHdyIEVsIHBhcXVldGUgcHdyIHByb3BvcmNpb25hIHVuYSBtYW5lcmENCmludHVpdGl2YSBwYXJhIGNhbGN1bGFyIGVsIHRhbWHDsW8gZGUgbXVlc3RyYSB1dGlsaXphbmRvIGZ1bmNpb25lcw0KcHJlZGVmaW5pZGFzLg0KDQpgYGB7cn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKA0KICAiQzovVXNlcnMvU2lsdmkvT25lRHJpdmUvSW3DoWdlbmVzL1NjcmVlbnNob3RzL0NhcHR1cmEgZGUgcGFudGFsbGEgMjAyNS0xMi0xMyAyMzU1MjYucG5nIg0KKQ0KYGBgDQoNCmBgYHtyfQ0KIyBQYXLDoW1ldHJvcw0KTiA8LSAxMDAwMCAgIyBUYW1hw7FvIGRlIGxhIHBvYmxhY2nDs24NClogPC0gMS45NiAgICMgTml2ZWwgZGUgY29uZmlhbnphIHBhcmEgOTUlDQpwIDwtIDAuMDUgICAjIFByb3BvcmNpw7NuIGVzcGVyYWRhICg1JSkNCnEgPC0gMSAtIHAgICMgQ29tcGxlbWVudG8gZGUgbGEgcHJvcG9yY2nDs24NCmQgPC0gMC4wMyAgICMgUHJlY2lzacOzbiBkZXNlYWRhICgzJSkNCg0KYGBgDQoNCg0KYGBge3J9DQojIENhbGN1bGFyIHRhbWHDsW8gZGUgbXVlc3RyYQ0KbiA8LSAoTiAqIFpeMiAqIHAgKiBxKSAvICgoZF4yICogKE4gLSAxKSkgKyAoWl4yICogcCAqIHEpKQ0KDQpjYXQoIlRhbWHDsW8gZGUgbXVlc3RyYSBuZWNlc2FyaW86IiwgY2VpbGluZyhuKSwgIlxuIikNCmBgYA0KDQpgYGB7cn0NCiMgVmFyaWFyIHByZWNpc2nDs24NCnByZWNpc2lvbmVzIDwtIHNlcSgwLjAxLCAwLjEsIGJ5ID0gMC4wMSkNCnRhbWHDsW9zX211ZXN0cmEgPC0gc2FwcGx5KHByZWNpc2lvbmVzLCBmdW5jdGlvbihkKSB7DQogIChOICogWl4yICogcCAqIHEpIC8gKChkXjIgKiAoTiAtIDEpKSArIChaXjIgKiBwICogcSkpDQp9KQ0KDQojIENyZWFyIGRhdGEgZnJhbWUgcGFyYSBlbCBncsOhZmljbw0KZGF0b3NfZ3JhZmljbyA8LSBkYXRhLmZyYW1lKA0KICBQcmVjaXNpb24gPSBwcmVjaXNpb25lcywNCiAgVGFtYcOxb19NdWVzdHJhID0gY2VpbGluZyh0YW1hw7Fvc19tdWVzdHJhKQ0KKQ0KDQojIEdyYWZpY2FyDQpsaWJyYXJ5KGdncGxvdDIpDQpnZ3Bsb3QoZGF0b3NfZ3JhZmljbywgYWVzKHggPSBQcmVjaXNpb24sIHkgPSBUYW1hw7FvX011ZXN0cmEpKSArDQogIGdlb21fbGluZShjb2xvciA9ICJibHVlIiwgc2l6ZSA9IDEpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJyZWQiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUmVsYWNpw7NuIGVudHJlIFByZWNpc2nDs24geSBUYW1hw7FvIGRlIE11ZXN0cmEgZW4gUG9ibGFjaW9uZXMgRmluaXRhcyIsDQogICAgeCA9ICJQcmVjaXNpw7NuIERlc2VhZGEgKGQpIiwNCiAgICB5ID0gIlRhbWHDsW8gZGUgTXVlc3RyYSINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNClBhc28gZGVsIHBhcXVldGUgcHdyIFVzbyBkZWwgcGFxdWV0ZTogRWwgcGFxdWV0ZSBwd3IgdXRpbGl6YSB1bmENCm1ldG9kb2xvZ8OtYSBiYXNhZGEgZW4gZWwgY8OhbGN1bG8gZGVsIHRhbWHDsW8gZGVsIGVmZWN0byAoaCksIGRlZmluaWRvDQpwb3I6DQoNCkxhIGZ1bmNpw7NuIGFyY3NpbiBlcyB1bmEgdHJhbnNmb3JtYWNpw7NuIG1hdGVtw6F0aWNhIGNvbm9jaWRhIGNvbW8gbGENCnRyYW5zZm9ybWFjacOzbiBhbmd1bGFyIGRlIEZyZWVtYW4tVHVrZXkgbyB0cmFuc2Zvcm1hY2nDs24gZGVsIGFyY28gc2Vuby4NClNlIHV0aWxpemEgY29tw7pubWVudGUgZW4gZXN0YWTDrXN0aWNhcyBwYXJhIG1hbmVqYXIgcHJvcG9yY2lvbmVzIG8NCnByb2JhYmlsaWRhZGVzIChwKSB5IG1lam9yYXIgY2llcnRhcyBwcm9waWVkYWRlcyBkZSBhbsOhbGlzaXMsDQplc3BlY2lhbG1lbnRlIGVuIHBydWViYXMgZGUgaGlww7N0ZXNpcyBwYXJhIHByb3BvcmNpb25lcy4NCg0KUHJvcMOzc2l0byBkZSBsYSB0cmFuc2Zvcm1hY2nDs24gYXJjc2luDQoNCk5vcm1hbGl6YXIgcHJvcG9yY2lvbmVzOg0KDQpQcm9wb3JjaW9uZXMgKHApIGVzdMOhbiByZXN0cmluZ2lkYXMgYWwgcmFuZ28gWzAsIDFdLCBsbyBxdWUgc2lnbmlmaWNhDQpxdWUgbm8gc29uIHNpbcOpdHJpY2FzIG5pIG5vcm1hbGVzLiBFc3RhIHRyYW5zZm9ybWFjacOzbiBjb252aWVydGUgbGFzDQpwcm9wb3JjaW9uZXMgZW4gdW4gdmFsb3IgcXVlIHB1ZWRlIGFwcm94aW1hcnNlIG1lam9yIGEgdW5hIGRpc3RyaWJ1Y2nDs24NCm5vcm1hbCwgbG8gY3VhbCBlcyDDunRpbCBwYXJhIGPDoWxjdWxvcyBlc3RhZMOtc3RpY29zLiBFc3RhYmlsaXphciBsYQ0KdmFyaWFuemE6DQoNCkVuIGFuw6FsaXNpcyBkZSBwcm9wb3JjaW9uZXMsIGxhIHZhcmlhbnphIHRpZW5kZSBhIGNhbWJpYXIgZGVwZW5kaWVuZG8gZGUNCihlcyBtw6FzIGFsdGEgY3VhbmRvIGVzdMOhIGNlcmNhIGRlIDAuNSB5IG3DoXMgYmFqYSBjZXJjYSBkZSAwIG8gMSkuIExhDQp0cmFuc2Zvcm1hY2nDs24gYXJjc2luKHJhaXpjdWFkcmFkYSBkZSBw4oCLKSBlc3RhYmlsaXphIGxhIHZhcmlhbnphLA0KaGFjaWVuZG8gcXVlIGxvcyBjw6FsY3Vsb3Mgc2VhbiBtw6FzIGNvbnNpc3RlbnRlcy4gRW4gcHJ1ZWJhcyBkZSBoaXDDs3Rlc2lzDQpwYXJhIHByb3BvcmNpb25lcywgY29tbyBlbiBlbCBjw6FsY3VsbyBkZWwgdGFtYcOxbyBkZSBtdWVzdHJhIHVzYW5kbw0KcHdyLnAudGVzdCwgbmVjZXNpdGFtb3MgZGVmaW5pciBlbCB0YW1hw7FvIGRlbCBlZmVjdG8gaGhoIHBhcmEgY29tcGFyYXINCnByb3BvcmNpb25lcyBvYnNlcnZhZGFzIHkgZXNwZXJhZGFzLiBMYSB0cmFuc2Zvcm1hY2nDs24NCmFyY3NpbuKBoShyYWl6Y3VhZHJhZGEgZGUgcCk6DQoNClBlcm1pdGUgY29tcGFyYXIgcHJvcG9yY2lvbmVzIGVuIHVuIGVzcGFjaW8gZG9uZGUgbGFzIGRpZmVyZW5jaWFzIHRpZW5lbg0KdW4gaW1wYWN0byBjb25zdGFudGUsIGluZGVwZW5kaWVudGVtZW50ZSBkZSBzaSBwIGVzdMOhIGNlcmNhIGRlIDAgbyBkZSAxLg0KDQpFc3RvIHNpbXBsaWZpY2EgZWwgY8OhbGN1bG8gZGVsIHRhbWHDsW8gZGUgbXVlc3RyYSwgcG9ycXVlIGVsIHRhbWHDsW8gZGVsDQplZmVjdG8gKGgpIHNlIGludGVycHJldGEgY29tbyB1bmEgZGlzdGFuY2lhIGVudHJlIGRvcyBwcm9wb3JjaW9uZXMgZW4NCmVzdGUgZXNwYWNpbyB0cmFuc2Zvcm1hZG8uDQoNClRhbWHDsW8gZGVsIGVmZWN0byBlbiBwcnVlYmFzIGVzdGFkw61zdGljYXM6DQoNCkVuIGVsIGNvbnRleHRvIGRlIHBydWViYXMgZGUgaGlww7N0ZXNpcyB5IGPDoWxjdWxvcyBkZSBwb2RlciBlc3RhZMOtc3RpY28NCihjb21vIGVuIGVsIHBhcXVldGUgcHdyKSwgZXN0YSB0cmFuc2Zvcm1hY2nDs24gZXMgdXRpbGl6YWRhIHBhcmEgZGVmaW5pcg0KZWwgdGFtYcOxbyBkZWwgZWZlY3RvIChoKSBkZSB1bmEgcHJvcG9yY2nDs24gZW4gdW4gbWFyY28gcXVlIGNvbnNpZGVyYQ0KdmFsb3JlcyBtw6FzIG1hbmVqYWJsZXMgeSBzaW3DqXRyaWNvcy4gUHJ1ZWJhIGRlIGhpcMOzdGVzaXMgZW4gcHdyLnAudGVzdDoNCg0KRW4gbHVnYXIgZGUgc2ltcGxlbWVudGUgY2FsY3VsYXIgdW4gdGFtYcOxbyBkZSBtdWVzdHJhIHBhcmEgZXN0aW1hciBwLA0KcHdyLnAudGVzdCBpbmNsdXllOg0KDQpFbCBuaXZlbCBkZSBzaWduaWZpY2FuY2lhIM6xLCBjb21vIDAuMDUgcGFyYSB1biA5NSUgZGUgY29uZmlhbnphKS4NCg0KRWwgcG9kZXIgZXN0YWTDrXN0aWNvICgx4oiSzrIpLCBub3JtYWxtZW50ZSAwLjggbyA4MCUpLg0KDQpFc3RvIHNpZ25pZmljYSBxdWUgZWwgY8OhbGN1bG8gY29uc2lkZXJhIGxhIHByb2JhYmlsaWRhZCBkZSBkZXRlY3RhciB1bg0KZWZlY3RvIHJlYWwgZGFkbyB1biBuaXZlbCBkZSBjb25maWFuemEgeSB1biBwb2Rlci4NCg0KRGlmZXJlbmNpYSBlbiByZXN1bHRhZG9zOiBFbCBjw6FsY3VsbyB1c2FuZG8gcHdyLnAudGVzdCBnZW5lcmEgdW4gdGFtYcOxbw0KZGUgbXVlc3RyYSBtw6FzIGNvbnNlcnZhZG9yIHBvcnF1ZSBpbmNsdXllOg0KDQpQb2RlciBlc3RhZMOtc3RpY28gKDHiiJLOsjEpOiBMYSBjYXBhY2lkYWQgZGUgZGV0ZWN0YXIgZWwgZWZlY3RvIHJlYWwuDQoNClRhbWHDsW8gZGVsIGVmZWN0byBoOiBVbiBlbmZvcXVlIG3DoXMgZ2VuZXJhbCBxdWUgdHJhbnNmb3JtYSBwcm9wb3JjaW9uZXMuDQoNCkRpZmVyZW5jaWEgZGUgUmVzdWx0YWRvcyBDw6FsY3VsbyBtYW51YWw6DQoNCkFzdW1lIHVuYSBwb2JsYWNpw7NuIGluZmluaXRhIHkgc2UgZW5mb2NhIMO6bmljYW1lbnRlIGVuIGVzdGltYXIgdW5hDQpwcm9wb3JjacOzbiBjb24gdW5hIHByZWNpc2nDs24gZGVzZWFkYSAoZWVlKS4NCg0KTm8gY29uc2lkZXJhIHBvZGVyIGVzdGFkw61zdGljby4NCg0KcHdyLnAudGVzdDoNCg0KSW5jbHV5ZSBlbCBtYXJjbyBkZSBwcnVlYmFzIGRlIGhpcMOzdGVzaXMgeSBwb2RlciBlc3RhZMOtc3RpY28sIGxvIHF1ZQ0KbGxldmEgYSB1biB0YW1hw7FvIGRlIG11ZXN0cmEgbcOhcyBjb25zZXJ2YWRvci4NCg0KRXN0ZSBlbmZvcXVlIGVzIG3DoXMgcm9idXN0byBzaSBlbCBlc3R1ZGlvIHJlcXVpZXJlIHBydWViYXMgZGUgaGlww7N0ZXNpcw0KZXNwZWPDrWZpY2FzIChwb3IgZWplbXBsbywgY29tcGFyYXIgcHJvcG9yY2lvbmVzIG9ic2VydmFkYXMgY29uIHZhbG9yZXMNCmVzcGVyYWRvcykuDQoNCkN1w6FuZG8gdXNhciBjYWRhIG3DqXRvZG8gTcOpdG9kbyBtYW51YWw6DQoNCkVzIGFkZWN1YWRvIGN1YW5kbyBlbCBvYmpldGl2byBlcyBzaW1wbGVtZW50ZSBlc3RpbWFyIHVuYSBwcm9wb3JjacOzbg0KZGVudHJvIGRlIHVuIG1hcmdlbiBkZSBlcnJvciBlc3BlY8OtZmljby4NCg0Kw5p0aWwgcGFyYSBlbmN1ZXN0YXMgeSBlc3R1ZGlvcyBkZXNjcmlwdGl2b3MuDQoNCk3DqXRvZG8gY29uIHB3ci5wLnRlc3Q6DQoNCsOadGlsIHBhcmEgZXN0dWRpb3MgYW5hbMOtdGljb3MgbyBleHBlcmltZW50YWxlcyBxdWUgcmVxdWllcmFuIHBydWViYXMgZGUNCmhpcMOzdGVzaXMuDQoNCkluY2x1eWUgcG9kZXIgZXN0YWTDrXN0aWNvLCBhc2VndXJhbmRvIG1heW9yIGNvbmZpYW56YSBlbiBsb3MgcmVzdWx0YWRvcy4NCg0KSU5TRVJUQVIgSU1BR0VORVM6DQoNCmtuaXRyIOKGkiBlcyBlbCBwYXF1ZXRlIHF1ZSBwcm9jZXNhIFIgTWFya2Rvd24NCg0KOjog4oaSIGluZGljYSBxdWUgdXNhcyBsYSBmdW5jacOzbiBkaXJlY3RhbWVudGUgZGVzZGUgZWwgcGFxdWV0ZQ0KDQppbmNsdWRlX2dyYXBoaWNzKCkg4oaSIGZ1bmNpw7NuIHBhcmEgaW5zZXJ0YXIgaW3DoWdlbmVzIGV4dGVybmFzIGVuIGVsDQpkb2N1bWVudG8NCg0KRXN0YSBmdW5jacOzbiBubyBjcmVhIGdyw6FmaWNvcywgc29sbyBtdWVzdHJhIGltw6FnZW5lcyAoUE5HLCBKUEcsIGV0Yy4pDQoNCmBgYHtyfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoDQogICJDOi9Vc2Vycy9TaWx2aS9PbmVEcml2ZS9JbcOhZ2VuZXMvU2NyZWVuc2hvdHMvQ2FsY3VsbyBkZSBsYSBtdWVzdHJhLnBuZyINCikNCg0KYGBgDQoNCkRvbmRlOg0KDQotICAgKCBOICk6IFRhbWHDsW8gZGUgbGEgcG9ibGFjacOzbi4NCg0KLSAgICggWlxeMiApOiBWYWxvciBjb3JyZXNwb25kaWVudGUgYWwgbml2ZWwgZGUgY29uZmlhbnphIChlLmcuLCAoIFogPQ0KICAgIDEuOTYgKSBwYXJhIDk1JSkuDQoNCi0gICAoIHAgKTogUHJvcG9yY2nDs24gZXNwZXJhZGEuDQoNCi0gICAoIHEgPSAxIC0gcCApOiBDb21wbGVtZW50byBkZSBsYSBwcm9wb3JjacOzbi4NCg0KLSAgICggZCApOiBQcmVjaXNpw7NuIGRlc2VhZGEuDQoNCkVuIGVzdGUgZWplcmNpY2lvLCBjYWxjdWxhcmVtb3MgZWwgdGFtYcOxbyBkZSBtdWVzdHJhIHBhcmEgdW5hIHBvYmxhY2nDs24NCmZpbml0YSBjb246DQoNCi0gICAoIE4gPSAxMCwwMDAgKQ0KDQotICAgTml2ZWwgZGUgY29uZmlhbnphOiA5NSUgKCggWiA9IDEuOTYgKSkNCg0KLSAgIFByb3BvcmNpw7NuIGVzcGVyYWRhOiAoIHAgPSAwLjA1ICkgKDUlKSBQcmVjaXNpw7NuIGRlc2VhZGE6ICggZCA9IDAuMDMNCiAgICApICgzJSkuDQoNCkPDoWxjdWxvIGRlbCBUYW1hw7FvIGRlIE11ZXN0cmEgUGFzbyAxOiBQYXLDoW1ldHJvcyBJbmljaWFsZXMgRGVmaW5pbW9zIGxvcw0KdmFsb3JlcyBkYWRvcyBlbiBlbCBwcm9ibGVtYS4NCg0KYGBge3J9DQojIFBhcsOhbWV0cm9zDQpOIDwtIDEwMDAwICAjIFRhbWHDsW8gZGUgbGEgcG9ibGFjacOzbg0KWiA8LSAxLjk2ICAgIyBOaXZlbCBkZSBjb25maWFuemEgcGFyYSA5NSUNCnAgPC0gMC4wNSAgICMgUHJvcG9yY2nDs24gZXNwZXJhZGEgKDUlKQ0KcSA8LSAxIC0gcCAgIyBDb21wbGVtZW50byBkZSBsYSBwcm9wb3JjacOzbg0KZCA8LSAwLjAzICAgIyBQcmVjaXNpw7NuIGRlc2VhZGEgKDMlKQ0KYGBgDQoNClBhc28gMjogSW1wbGVtZW50YXIgbGEgRsOzcm11bGEgVXRpbGl6YW1vcyBsYSBmw7NybXVsYSBwYXJhIGNhbGN1bGFyIGVsDQp0YW1hw7FvIGRlIGxhIG11ZXN0cmEuDQoNCmBgYHtyfQ0KIyBDYWxjdWxhciB0YW1hw7FvIGRlIG11ZXN0cmENCm4gPC0gKE4gKiBaXjIgKiBwICogcSkgLyAoKGReMiAqIChOIC0gMSkpICsgKFpeMiAqIHAgKiBxKSkNCg0KY2F0KCJUYW1hw7FvIGRlIG11ZXN0cmEgbmVjZXNhcmlvOiIsIGNlaWxpbmcobiksICJcbiIpDQpgYGANCg0KVmlzdWFsaXphY2nDs24gZGUgbG9zIFJlc3VsdGFkb3MgQ8OzbW8gVmFyw61hIGVsIFRhbWHDsW8gZGUgTXVlc3RyYSBjb24NCkRpZmVyZW50ZXMgTml2ZWxlcyBkZSBQcmVjaXNpw7NuIENyZWFtb3MgdW4gZ3LDoWZpY28gcXVlIG11ZXN0cmUgY8OzbW8gZWwNCnRhbWHDsW8gZGUgbXVlc3RyYSBjYW1iaWEgY29uIGRpZmVyZW50ZXMgdmFsb3JlcyBkZSBkIChwcmVjaXNpw7NuKS4NCg0KYGBge3J9DQojIFZhcmlhciBwcmVjaXNpw7NuDQpwcmVjaXNpb25lcyA8LSBzZXEoMC4wMSwgMC4xLCBieSA9IDAuMDEpDQp0YW1hw7Fvc19tdWVzdHJhIDwtIHNhcHBseShwcmVjaXNpb25lcywgZnVuY3Rpb24oZCkgew0KICAoTiAqIFpeMiAqIHAgKiBxKSAvICgoZF4yICogKE4gLSAxKSkgKyAoWl4yICogcCAqIHEpKQ0KfSkNCg0KIyBDcmVhciBkYXRhIGZyYW1lIHBhcmEgZWwgZ3LDoWZpY28NCmRhdG9zX2dyYWZpY28gPC0gZGF0YS5mcmFtZSgNCiAgUHJlY2lzaW9uID0gcHJlY2lzaW9uZXMsDQogIFRhbWHDsW9fTXVlc3RyYSA9IGNlaWxpbmcodGFtYcOxb3NfbXVlc3RyYSkNCikNCg0KIyBHcmFmaWNhcg0KbGlicmFyeShnZ3Bsb3QyKQ0KZ2dwbG90KGRhdG9zX2dyYWZpY28sIGFlcyh4ID0gUHJlY2lzaW9uLCB5ID0gVGFtYcOxb19NdWVzdHJhKSkgKw0KICBnZW9tX2xpbmUoY29sb3IgPSAiYmx1ZSIsIHNpemUgPSAxKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAicmVkIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlJlbGFjacOzbiBlbnRyZSBQcmVjaXNpw7NuIHkgVGFtYcOxbyBkZSBNdWVzdHJhIGVuIFBvYmxhY2lvbmVzIEZpbml0YXMiLA0KICAgIHggPSAiUHJlY2lzacOzbiBEZXNlYWRhIChkKSIsDQogICAgeSA9ICJUYW1hw7FvIGRlIE11ZXN0cmEiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoqKlJlZmxleGnDs24qKg0KDQpQdW50b3MgQ2xhdmU6DQoNCjEuICBSZWxhY2nDs24gUHJlY2lzacOzbi1UYW1hw7FvOiBFbCB0YW1hw7FvIGRlIG11ZXN0cmEgY3JlY2UgcsOhcGlkYW1lbnRlDQogICAgY3VhbmRvIGxhIHByZWNpc2nDs24gZGVzZWFkYSBkIGVzIG3DoXMgcGVxdWXDsWEuDQoNCjIuICBJbXBhY3RvIGRlbCBUYW1hw7FvIFBvYmxhY2lvbmFsOiBBIG1lZGlkYSBxdWUgbiBhdW1lbnRhLCBlbCBhanVzdGUNCiAgICBwb3IgcG9ibGFjacOzbiBmaW5pdGEgZXMgbWVub3Mgc2lnbmlmaWNhdGl2bywgeSBlbCB0YW1hw7FvIGRlIG11ZXN0cmENCiAgICBzZSBhcHJveGltYSBhbCBjw6FsY3VsbyBwYXJhIHBvYmxhY2lvbmVzIGluZmluaXRhcy4NCg0KIyMgKipQYXLDoW1ldHJvcyBJbmljaWFsZXMqKg0KDQpEZWZpbmltb3MgbG9zIHZhbG9yZXMgbmVjZXNhcmlvcyBwYXJhIGVsIGPDoWxjdWxvLiBFbiBlc3RlIGVqZXJjaWNpbywNCmNhbGN1bGFyZW1vcyBlbCB0YW1hw7FvIGRlIG11ZXN0cmEgbmVjZXNhcmlvIHBhcmEgZXN0dWRpYXIgbGEgcHJldmFsZW5jaWENCmRlIGRpYWJldGVzIGVuIHVuYSBwb2JsYWNpw7NuIGZpbml0YSBkZSAqKjE1LDAwMCBoYWJpdGFudGVzKiosIGNvbjoNCg0KLSAgICoqU2VndXJpZGFkOioqICggOTUgJSApDQoNCi0gICAqKlByZWNpc2nDs246KiogKCAzJSApICgoIGQgPSAwLjAzICkpDQoNCi0gICAqKlByb3BvcmNpw7NuIGVzcGVyYWRhOioqICggcCA9IDAuMDUgKSAoNSUpDQoNCi0gICBGw7NybXVsYToNCg0KYGBge3J9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygNCiAgIkM6L1VzZXJzL1NpbHZpL09uZURyaXZlL0ltw6FnZW5lcy9TY3JlZW5zaG90cy9DYWxjdWxvIGRlIGxhIG11ZXN0cmEucG5nIg0KKQ0KYGBgDQoNCkRvbmRlOg0KDQpcLSAoIE4gKTogVGFtYcOxbyBkZSBsYSBwb2JsYWNpw7NuICgxNSwwMDApLg0KDQpcLSAoIFogKTogVmFsb3IgWiBwYXJhIHVuIG5pdmVsIGRlIGNvbmZpYW56YSBkZWwgOTUlICgoIFogPSAxLjk2ICkpLg0KDQpcLSAoIHAgKTogUHJvcG9yY2nDs24gZXNwZXJhZGEuIC0NCg0KKCBxICk6IENvbXBsZW1lbnRvIGRlICggcCApICgoIHEgPSAxIC0gcCApKS4gLQ0KDQooIGQgKTogUHJlY2lzacOzbiBkZXNlYWRhLg0KDQpEZWZpbmltb3MgbG9zIHZhbG9yZXMgbmVjZXNhcmlvcyBwYXJhIGVsIGPDoWxjdWxvLg0KDQpgYGB7cn0NCiMgUGFyw6FtZXRyb3MNCk4gPC0gMTUwMDAgICMgVGFtYcOxbyBkZSBsYSBwb2JsYWNpw7NuDQpaIDwtIDEuOTYgICAjIE5pdmVsIGRlIGNvbmZpYW56YSBwYXJhIDk1JQ0KcCA8LSAwLjA1ICAgIyBQcm9wb3JjacOzbiBlc3BlcmFkYSAoNSUpDQpxIDwtIDEgLSBwICAjIENvbXBsZW1lbnRvIGRlIGxhIHByb3BvcmNpw7NuDQpkIDwtIDAuMDMgICAjIFByZWNpc2nDs24gZGVzZWFkYSAoMyUpDQoNCiMgQ2FsY3VsYXIgdGFtYcOxbyBkZSBtdWVzdHJhIHBhcmEgcG9ibGFjacOzbiBmaW5pdGENCm4gPC0gKE4gKiBaXjIgKiBwICogcSkgLyAoKGReMiAqIChOIC0gMSkpICsgKFpeMiAqIHAgKiBxKSkNCg0KY2F0KCJUYW1hw7FvIGRlIG11ZXN0cmEgbmVjZXNhcmlvOiIsIGNlaWxpbmcobiksICJcbiIpDQpgYGANCg0KIyMjIyAqKkludGVycHJldGFjacOzbjoqKg0KDQpFbCBjw6FsY3VsbyBtdWVzdHJhIHF1ZSBuZWNlc2l0YW1vcyBlc3R1ZGlhciBhcHJveGltYWRhbWVudGUgKioyMDANCnBlcnNvbmFzKiogcGFyYSBlc3RpbWFyIGxhIHByZXZhbGVuY2lhIGRlIGRpYWJldGVzIGVuIHVuYSBwb2JsYWNpw7NuIGRlDQoxNSwwMDAgaGFiaXRhbnRlcywgY29uIHVuIG5pdmVsIGRlIGNvbmZpYW56YSBkZWwgOTUlIHkgdW5hIHByZWNpc2nDs24gZGVsDQozJS4NCg0KYGBge3J9DQojIFZhcmlhciBwcmVjaXNpw7NuDQpwcmVjaXNpb25lcyA8LSBzZXEoMC4wMSwgMC4xLCBieSA9IDAuMDEpDQp0YW1hw7Fvc19tdWVzdHJhIDwtIHNhcHBseShwcmVjaXNpb25lcywgZnVuY3Rpb24oZCkgew0KICAoTiAqIFpeMiAqIHAgKiBxKSAvICgoZF4yICogKE4gLSAxKSkgKyAoWl4yICogcCAqIHEpKQ0KfSkNCg0KIyBDcmVhciBkYXRhIGZyYW1lIHBhcmEgZWwgZ3LDoWZpY28NCmRhdG9zX2dyYWZpY28gPC0gZGF0YS5mcmFtZSgNCiAgUHJlY2lzaW9uID0gcHJlY2lzaW9uZXMsDQogIFRhbWHDsW9fTXVlc3RyYSA9IGNlaWxpbmcodGFtYcOxb3NfbXVlc3RyYSkNCikNCg0KIyBHcmFmaWNhcg0KbGlicmFyeShnZ3Bsb3QyKQ0KZ2dwbG90KGRhdG9zX2dyYWZpY28sIGFlcyh4ID0gUHJlY2lzaW9uLCB5ID0gVGFtYcOxb19NdWVzdHJhKSkgKw0KICBnZW9tX2xpbmUoY29sb3IgPSAiYmx1ZSIsIHNpemUgPSAxKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAicmVkIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlJlbGFjacOzbiBlbnRyZSBQcmVjaXNpw7NuIHkgVGFtYcOxbyBkZSBNdWVzdHJhIiwNCiAgICB4ID0gIlByZWNpc2nDs24gRGVzZWFkYSAoZCkiLA0KICAgIHkgPSAiVGFtYcOxbyBkZSBNdWVzdHJhIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KYGBge3J9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygNCiAgIkM6L1VzZXJzL1NpbHZpL09uZURyaXZlL0ltw6FnZW5lcy9TY3JlZW5zaG90cy9DYXB0dXJhIGRlIHBhbnRhbGxhIDIwMjUtMTItMTQgMDAwNDIzLnBuZyINCikNCmBgYA0KDQpgYGB7cn0NCiMgUGFyw6FtZXRyb3MNClogPC0gMS45NiAgIyBOaXZlbCBkZSBjb25maWFuemEgKDk1JSkNClMyIDwtIDI1MCAgIyBWYXJpYW56YQ0KZCA8LSAzICAgICAjIFByZWNpc2nDs24gZGVzZWFkYQ0KDQojIEPDoWxjdWxvIGRlbCB0YW1hw7FvIGRlIG11ZXN0cmENCm5fbWFudWFsIDwtIChaXjIgKiBTMikgLyAoZF4yKQ0KDQpjYXQoIlRhbWHDsW8gZGUgbXVlc3RyYSAobWFudWFsKToiLCBjZWlsaW5nKG5fbWFudWFsKSwgIlxuIikNCmBgYA0KDQpgYGB7cn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKA0KICAiQzovVXNlcnMvU2lsdmkvT25lRHJpdmUvSW3DoWdlbmVzL1NjcmVlbnNob3RzL0NhcHR1cmEgZGUgcGFudGFsbGEgMjAyNS0xMi0xNCAwMDA1MzkucG5nIg0KKQ0KYGBgDQoNCmBgYHtyfQ0KIyBQYXLDoW1ldHJvcw0KWl9hbHBoYSA8LSAxLjY0NSAgIyBOaXZlbCBkZSBjb25maWFuemEgKDk1JSkNClpfYmV0YSA8LSAwLjg0MiAgICMgUG9kZXIgZXN0YWTDrXN0aWNvICg4MCUpDQpwMSA8LSAwLjcgICAgICAgICAjIFByb3BvcmNpw7NuIDENCnAyIDwtIDAuOSAgICAgICAgICMgUHJvcG9yY2nDs24gMg0KcCA8LSAocDEgKyBwMikgLyAyICAjIFByb21lZGlvIGRlIHByb3BvcmNpb25lcw0KDQojIEPDoWxjdWxvIGRlbCB0YW1hw7FvIGRlIG11ZXN0cmENCm5fbWFudWFsIDwtICgoWl9hbHBoYSAqIHNxcnQoMiAqIHAgKiAoMSAtIHApKSArIFpfYmV0YSAqIHNxcnQocDEgKiAoMSAtIHAxKSArIHAyICogKDEgLSBwMikpKV4yKSAvIChwMSAtIHAyKV4yDQoNCmNhdCgiVGFtYcOxbyBkZSBtdWVzdHJhIChtYW51YWwpOiIsIGNlaWxpbmcobl9tYW51YWwpLCAiXG4iKQ0KYGBgDQoNCmBgYHtyfQ0KIyBJbnN0YWxhciBwd3Igc2kgbm8gZXN0w6EgaW5zdGFsYWRvDQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoInB3ciIsIHF1aWV0bHkgPSBUUlVFKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwd3IiKQ0KfQ0KbGlicmFyeShwd3IpDQoNCiMgVGFtYcOxbyBkZWwgZWZlY3RvIHBhcmEgcHJvcG9yY2lvbmVzDQpoIDwtIEVTLmgocDEgPSBwMSwgcDIgPSBwMikNCg0KIyBDYWxjdWxhciBlbCB0YW1hw7FvIGRlIG11ZXN0cmENCnJlc3VsdGFkbyA8LSBwd3IuMnAudGVzdChoID0gaCwgc2lnLmxldmVsID0gMC4wNSwgcG93ZXIgPSAwLjgpDQoNCmNhdCgiVGFtYcOxbyBkZSBtdWVzdHJhIChjb24gcHdyKToiLCBjZWlsaW5nKHJlc3VsdGFkbyRuKSwgIlxuIikNCmBgYA0KDQpgYGB7cn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKA0KICAiQzovVXNlcnMvU2lsdmkvT25lRHJpdmUvSW3DoWdlbmVzL1NjcmVlbnNob3RzL0NhcHR1cmEgZGUgcGFudGFsbGEgMjAyNS0xMi0xNCAwMDA3NDIucG5nIg0KKQ0KYGBgDQoNCmBgYHtyfQ0KIyBQYXLDoW1ldHJvcw0KWl9hbHBoYSA8LSAxLjY0NSAgIyBOaXZlbCBkZSBjb25maWFuemEgKDk1JSkNClpfYmV0YSA8LSAxLjI4MiAgICMgUG9kZXIgZXN0YWTDrXN0aWNvICg5MCUpDQpTIDwtIDE2ICAgICAgICAgICAjIERlc3ZpYWNpw7NuIGVzdMOhbmRhcg0KZCA8LSAxNSAgICAgICAgICAgIyBEaWZlcmVuY2lhIGVzcGVyYWRhDQoNCiMgQ8OhbGN1bG8gZGVsIHRhbWHDsW8gZGUgbXVlc3RyYQ0Kbl9tYW51YWwgPC0gKDIgKiAoWl9hbHBoYSArIFpfYmV0YSleMiAqIFNeMikgLyAoZF4yKQ0KDQpjYXQoIlRhbWHDsW8gZGUgbXVlc3RyYSAobWFudWFsKToiLCBjZWlsaW5nKG5fbWFudWFsKSwgIlxuIikNCmBgYA0KDQpVc2FuZG8gdW4gUGFxdWV0ZTrCoGBwd3JgDQoNCmBgYHtyfQ0KIyBDYWxjdWxhciB0YW1hw7FvIGRlIG11ZXN0cmEgcGFyYSBjb21wYXJhY2nDs24gZGUgbWVkaWFzDQpyZXN1bHRhZG8gPC0gcHdyLnQudGVzdChkID0gZCAvIFMsIHNpZy5sZXZlbCA9IDAuMDUsIHBvd2VyID0gMC45LCB0eXBlID0gInR3by5zYW1wbGUiKQ0KDQpjYXQoIlRhbWHDsW8gZGUgbXVlc3RyYSAoY29uIHB3cik6IiwgY2VpbGluZyhyZXN1bHRhZG8kbiksICJcbiIpDQpgYGANCg0KRWwgcGFxdWV0ZSAqKmBwd3JgKiogdGFtYmnDqW4gaW5jbHV5ZSBsYSBmdW5jacOzbiAqKmBwd3IudC50ZXN0YCoqIHBhcmENCmNhbGN1bGFyIHRhbWHDsW9zIGRlIG11ZXN0cmEgcGFyYSBsYSBjb21wYXJhY2nDs24gZGUgZG9zIG1lZGlhcy4NCg0KLSAgIFRhbWHDsW8gZGVsIGVmZWN0byBkOg0KDQogIGQgPSAgRGlmZXJlbmNpYSBlc3BlcmFkYSAvIERTIA0KDQpgYGB7cn0NCiMgUGFyw6FtZXRyb3MNCkRpZmVyZW5jaWEgPC0gMTUgICMgRGlmZXJlbmNpYSBlc3BlcmFkYSBlbnRyZSBtZWRpYXMNClMgPC0gMTYgICAgICAgICAgICMgRGVzdmlhY2nDs24gZXN0w6FuZGFyDQpkIDwtIERpZmVyZW5jaWEgLyBTICAjIFRhbWHDsW8gZGVsIGVmZWN0bw0KDQojIENhbGN1bGFyIHRhbWHDsW8gZGUgbXVlc3RyYQ0KcmVzdWx0YWRvIDwtIHB3ci50LnRlc3QoZCA9IGQsIHNpZy5sZXZlbCA9IDAuMDUsIHBvd2VyID0gMC45LCB0eXBlID0gInR3by5zYW1wbGUiKQ0KDQpjYXQoIlRhbWHDsW8gZGUgbXVlc3RyYSBwYXJhIGNvbXBhcmFyIGRvcyBtZWRpYXMgKHB3cik6IiwgY2VpbGluZyhyZXN1bHRhZG8kbiksICJwb3IgZ3J1cG9cbiIpDQpgYGANCg0KLSAgIExvcyBjw6FsY3Vsb3MgbWFudWFsZXMgc2lndWVuIGxhcyBmw7NybXVsYXMgY2zDoXNpY2FzLg0KDQotICAgRWwgdXNvIGRlIHBhcXVldGVzIGNvbW8gKipgZXBpRGlzcGxheWAqKiBvICoqYHB3cmAqKiBzaW1wbGlmaWNhIGVsDQogICAgcHJvY2VzbyB5IHBlcm1pdGUgYWp1c3RhciBwYXLDoW1ldHJvcyBjb21vIGVsIG5pdmVsIGRlIGNvbmZpYW56YSB5IGVsDQogICAgcG9kZXIgZXN0YWTDrXN0aWNvIGRlIGZvcm1hIG3DoXMgZmxleGlibGUuDQoNCiMjIyAqKlJlc3VsdGFkb3MgZGVsIFBhcXVldGUgYHB3cmAqKg0KDQotICAgKipFc3RpbWFjacOzbiBkZSB1bmEgbWVkaWE6KiogVXNhbW9zICoqYHB3ci50LnRlc3RgKiogY29uIGQ9ZS9TZCA9IGUNCiAgICAvIFNkPWUvUy4NCg0KLSAgICoqQ29tcGFyYWNpw7NuIGRlIGRvcyBwcm9wb3JjaW9uZXM6KiogVXNhbW9zICoqYHB3ci4ycC50ZXN0YCoqLCBxdWUNCiAgICBjYWxjdWxhIGRpcmVjdGFtZW50ZSB0YW1hw7FvcyBkZSBtdWVzdHJhIHBhcmEgcHJ1ZWJhcyBkZSBoaXDDs3Rlc2lzDQogICAgY29uIHByb3BvcmNpb25lcy4NCg0KLSAgICoqQ29tcGFyYWNpw7NuIGRlIGRvcyBtZWRpYXM6KiogVXNhbW9zICoqYHB3ci50LnRlc3RgKiogY29uDQogICAgZD1EaWZlcmVuY2lhwqBlc3BlcmFkYS9EZXN2aWFjaW/Lim7CoGVzdGHLim5kYXJkID0gXFx7RGlmZXJlbmNpYQ0KICAgIGVzcGVyYWRhfSAvIFxce0Rlc3ZpYWNpw7NuDQogICAgZXN0w6FuZGFyZD1EaWZlcmVuY2lhwqBlc3BlcmFkYS9EZXN2aWFjaW/Lim7CoGVzdMOhbmRhci4NCg0KIyMjICoqwr9RdcOpIG5vIGN1YnJlIGBwd3JgIGRpcmVjdGFtZW50ZT8qKg0KDQotICAgKipQb2JsYWNpb25lcyBmaW5pdGFzOioqIE5lY2VzaXRhbW9zIGFqdXN0YXIgbWFudWFsbWVudGUgZWwgdGFtYcOxbw0KICAgIGRlIG11ZXN0cmEgY2FsY3VsYWRvIHBhcmEgY29uc2lkZXJhciB0YW1hw7FvcyBkZSBwb2JsYWNpw7NuIGZpbml0b3MuDQoNCi0gICAqKkVzdGltYWNpw7NuIGRlIHVuYSBtZWRpYSBzaW4gcHJ1ZWJhIGRlIGhpcMOzdGVzaXM6KiogQXVucXVlIHBvZGVtb3MNCiAgICBhZGFwdGFyIGVsIGPDoWxjdWxvIGNvbiAqKmBwd3IudC50ZXN0YCoqLCBlbCBwYXF1ZXRlIGVzdMOhIGRpc2XDsWFkbw0KICAgIHBhcmEgcHJ1ZWJhcyBkZSBoaXDDs3Rlc2lzLg0K