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:
Nivel de confianza (Zα): Representa la probabilidad de que el
intervalo de confianza contenga el valor verdadero. Ejemplo: 95% (( Z =
1.96 )).
Precisión deseada (( e )): Diferencia máxima aceptable entre la
proporción estimada y la real.
Proporción esperada (( p )): Estimación inicial basada en
literatura o estudios previos.
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:
( N ): Tamaño de la población.
( Z^2 ): Valor correspondiente al nivel de confianza (e.g., ( Z =
1.96 ) para 95%).
( p ): Proporción esperada.
( q = 1 - p ): Complemento de la proporción.
( d ): Precisión deseada.
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:
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.
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.
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