Diseño de un Estudio de Casos y Controles

En un estudio de casos y controles, identificamos un grupo de personas con el desenlace de interés (casos) y otro grupo sin el desenlace (controles). Luego, evaluamos y comparamos las exposiciones previas entre ambos grupos para explorar asociaciones.

Ejemplo de Planteamiento

  • Pregunta de Investigación: ¿La hipertensión está asociada con un mayor riesgo de desarrollar diabetes?

  • Casos: Personas con diagnóstico de diabetes.

  • Controles: Personas sin diagnóstico de diabetes.

  • Exposición de interés: Hipertensión.

  • Covariables: Edad, IMC, actividad física, nivel educativo, hábito de fumar.

Planteamiento del Estudio

  1. Objetivo del Estudio:

    • Evaluar si la hipertensión aumenta el riesgo de diabetes.
  2. Pregunta de Investigación:

    • ¿Es más probable que las personas con hipertensión desarrollen diabetes que aquellas sin hipertensión?
  3. Variables:

    • Dependiente: Diabetes (Casos: Sí; Controles: No).

    • Independiente: Hipertensión (Sí/No).

    • Covariables: Edad, IMC, actividad física, nivel educativo, hábito de fumar.

Próximos Pasos

Este documento aborda el análisis de un estudio de casos y controles para explorar la asociación entre hipertensión y diabetes. Iniciaremos con:

Descargamos el data frame: https://colab.research.google.com/drive/1BPtDSgzEfWKysUBdbb2UFubOwQecEb8X?usp=sharing#scrollTo=Y6l8GwkV2dssestudio_casos_controles_errores.xlsx

lo guardamos como un objeto (datos)

1. Limpieza de una base de datos con errores intencionados. 

2. Exploración descriptiva de las variables. 

3. Análisis bivariado y multivariado mediante regresión logística.

# Instalar paquetes necesarios (si aún no están instalados)
#install.packages("readxl")
# install.packages("tidyverse")
# install.packages("janitor")
# install.packages("gtsummary")

# Cargar librerías
library(readxl)
library(tidyverse)
library(janitor)
library(gtsummary)
library(dlookr)
# Leer la base de datos desde Excel
#archivo <- "estudio_casos_controles_errores.xlsx"
library(readxl)
library(readxl)

estudio_casos_controles_errores <- read_excel("/Users/jesushernandez/Downloads/estudio_casos_controles_errores.xlsx")


#datos <- read_excel(archivo)

datos<-estudio_casos_controles_errores

# Visualizar las primeras filas
#head(datos)

Paso 2: Limpieza de la Base de Datos

En este paso, utilizaremos las funciones de janitor y dplyr para:

  1. Limpiar nombres de columnas.

  2. Corregir inconsistencias en valores categóricos.

# Limpiar nombres de columnas
datos <- datos %>% clean_names()

names(datos)
[1] "id"                       "diabetes"                 "edad"                     "sexo"                    
[5] "imc"                      "hipertension"             "actividad_fisica_min_sem" "fumador"                 
[9] "nivel_educativo"         
# Corregir inconsistencias en valores categóricos
datos <- datos %>%
  mutate(
    sexo = str_to_title(trimws(sexo)),  # Título (primera letra en mayúscula)
    fumador = str_to_lower(trimws(fumador)),  # Minúscula
    hipertension = str_to_lower(trimws(hipertension)),  # Minúscula
    nivel_educativo = str_to_title(trimws(nivel_educativo))  # Título
  )

# Visualizar los datos limpios
head(datos)
sapply(datos, unique)
$id
  [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32
 [33]  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64
 [65]  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96
 [97]  97  98  99 100

$diabetes
[1] "Sí" "No"

$edad
 [1] 75 32 58 64 68 47 49 72 52 63 62 79 77 39 76 55 44 66 46 34 33 50 69 78 37 71 65 51 60 57 42 70 35 30 41 40 43 48 45 73 74 36 56
[44] 31 67 53 59 54 38 61

$sexo
[1] "Masculino" "Femenino" 

$imc
  [1] 25.8 30.4 30.9 29.7 18.6 39.7 38.0 23.0 24.8 37.9 39.6 24.0 30.6 35.8 27.0 34.2 22.0 31.4 37.1 20.2 27.7 22.9 28.2 30.3 20.5
 [26] 24.9 38.4 30.7 28.3 34.7 34.5 19.5 33.7 36.5 22.1 35.3 24.7 25.1 32.8 20.9 37.6 33.5 28.0 27.9 34.9 20.3 31.0 36.0 25.7 34.6
 [51] 30.8 37.0 36.2 38.1 21.3 21.5 27.1 27.6 21.1 22.8 28.6 35.9 18.7 38.5 33.9 26.6 32.9 19.1 32.2 19.2 28.7 30.2 19.9 32.5 39.9
 [76] 35.0 20.7 32.7 19.6 35.5 35.4 23.9 25.5 35.6 21.4 26.5 33.0 32.0 23.1 38.8 33.6 30.0 23.6 34.0 24.1 35.7 39.2 19.7 28.4 24.3
[101] 30.1 25.4 37.4 22.2 30.5 36.6 19.4 18.8 28.1 33.1 32.1 22.7 29.6 21.7 24.4 26.0 23.5 31.6 37.2 31.1 39.8 32.4 19.3 29.9 21.8
[126] 39.3 34.8 34.1 38.7 21.0 31.3 26.1 39.0 31.5 36.7

$hipertension
[1] "no" "sí" "si"

$actividad_fisica_min_sem
  [1] 207 295 126 264 208 258 180 259 179 205 199  29  24  38 152  32 115 111 201 113  72   0 225  30 276  23  18  60 123  19 116 153
 [33]   6  71  93  10 248 174 191  42 234  15 118  49  33 253 231 290  63 268  26 297 143  45 292 142 289 213   8 245 256 278 288  94
 [65] 214 282 228 101 141 262 155 242  84 190 284  66 212  47 296 122 136  68 286  91   2 162  59   9 250 154 139  85  86  98  43  37
 [97]   7  97 216  74  58  16  56 137 121 246 272 124 105 188 267 170 151 100 275 172 133  96 112 217 215  11 178   3 132  52  75 138
[129] 125  20  27  80 127  67 108 119 281 202   5  51 240 144

$fumador
[1] "no" "sí"

$nivel_educativo
[1] "Primaria"      "Secundaria"    "Universitario"

limpieza para evitar que se repitan elementos u homogenizarlos:

# Limpieza y homogenización de datos categóricos
datos <- datos %>%
  mutate(
    # Homogeneizar valores en `fumador`
    hipertension = case_when(
      hipertension %in% c("sí", "Sí", "SÍ", "si") ~ "Sí",
      hipertension %in% c("no", "No", "NO") ~ "No",
      TRUE ~ NA_character_
    ))

sapply(datos, unique)
$id
  [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32
 [33]  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64
 [65]  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96
 [97]  97  98  99 100

$diabetes
[1] "Sí" "No"

$edad
 [1] 75 32 58 64 68 47 49 72 52 63 62 79 77 39 76 55 44 66 46 34 33 50 69 78 37 71 65 51 60 57 42 70 35 30 41 40 43 48 45 73 74 36 56
[44] 31 67 53 59 54 38 61

$sexo
[1] "Masculino" "Femenino" 

$imc
  [1] 25.8 30.4 30.9 29.7 18.6 39.7 38.0 23.0 24.8 37.9 39.6 24.0 30.6 35.8 27.0 34.2 22.0 31.4 37.1 20.2 27.7 22.9 28.2 30.3 20.5
 [26] 24.9 38.4 30.7 28.3 34.7 34.5 19.5 33.7 36.5 22.1 35.3 24.7 25.1 32.8 20.9 37.6 33.5 28.0 27.9 34.9 20.3 31.0 36.0 25.7 34.6
 [51] 30.8 37.0 36.2 38.1 21.3 21.5 27.1 27.6 21.1 22.8 28.6 35.9 18.7 38.5 33.9 26.6 32.9 19.1 32.2 19.2 28.7 30.2 19.9 32.5 39.9
 [76] 35.0 20.7 32.7 19.6 35.5 35.4 23.9 25.5 35.6 21.4 26.5 33.0 32.0 23.1 38.8 33.6 30.0 23.6 34.0 24.1 35.7 39.2 19.7 28.4 24.3
[101] 30.1 25.4 37.4 22.2 30.5 36.6 19.4 18.8 28.1 33.1 32.1 22.7 29.6 21.7 24.4 26.0 23.5 31.6 37.2 31.1 39.8 32.4 19.3 29.9 21.8
[126] 39.3 34.8 34.1 38.7 21.0 31.3 26.1 39.0 31.5 36.7

$hipertension
[1] "No" "Sí"

$actividad_fisica_min_sem
  [1] 207 295 126 264 208 258 180 259 179 205 199  29  24  38 152  32 115 111 201 113  72   0 225  30 276  23  18  60 123  19 116 153
 [33]   6  71  93  10 248 174 191  42 234  15 118  49  33 253 231 290  63 268  26 297 143  45 292 142 289 213   8 245 256 278 288  94
 [65] 214 282 228 101 141 262 155 242  84 190 284  66 212  47 296 122 136  68 286  91   2 162  59   9 250 154 139  85  86  98  43  37
 [97]   7  97 216  74  58  16  56 137 121 246 272 124 105 188 267 170 151 100 275 172 133  96 112 217 215  11 178   3 132  52  75 138
[129] 125  20  27  80 127  67 108 119 281 202   5  51 240 144

$fumador
[1] "no" "sí"

$nivel_educativo
[1] "Primaria"      "Secundaria"    "Universitario"

Paso 3: Exploración de Datos (EDA)

Resumen Estadístico de Variables Cuantitativas

podemos usar los paquetes, dlookr, gtsummary o simbplemete con base R:

# Resumen estadístico
datos %>%
  select_if(is.numeric) %>%
  summary()
       id              edad            imc        actividad_fisica_min_sem
 Min.   :  1.00   Min.   :30.00   Min.   :18.60   Min.   :  0.0           
 1st Qu.: 25.75   1st Qu.:45.00   1st Qu.:24.38   1st Qu.: 71.0           
 Median : 50.50   Median :56.50   Median :30.30   Median :140.0           
 Mean   : 50.50   Mean   :55.81   Mean   :29.53   Mean   :145.5           
 3rd Qu.: 75.25   3rd Qu.:68.00   3rd Qu.:34.70   3rd Qu.:214.2           
 Max.   :100.00   Max.   :79.00   Max.   :39.90   Max.   :297.0           

como lo harías con dlookr?

datos %>% describe()
datos %>% normality()
datos %>% plot_normality()

Distribución de Casos y Controles

# Frecuencia de diabetes
datos %>%
  count(diabetes) %>%
  mutate(porcentaje = n / sum(n) * 100)
# Gráfico de barras
datos %>%
  ggplot(aes(x = diabetes, fill = diabetes)) +
  geom_bar() +
  labs(title = "Distribución de Casos y Controles", x = "Diabetes", y = "Frecuencia") +
  theme_minimal()

Paso 4: Análisis Bivariado (Odds Ratios)

Usaremos tablas de contingencia para calcular las Odds Ratios de hipertensión.

# Tabla de contingencia

datos2 <- datos %>%
  mutate(
    diabetes = factor(diabetes, levels = c("Sí", "No")),  # Diabetes: "si" primero
    hipertension = factor(hipertension, levels = c("Sí", "No"))  # Hipertensión: "si" primero
  )

tabla_contingencia <- datos2 %>%
  count(diabetes, hipertension) %>%
  pivot_wider(names_from = hipertension, values_from = n, values_fill = 0)

tabla_contingencia
# Calcular Odds Ratio manualmente
odds_ratio <- (tabla_contingencia$Sí[1] * tabla_contingencia$No[2]) /
              (tabla_contingencia$Sí[2] * tabla_contingencia$No[1])


# Extraer valores de la tabla
a <- tabla_contingencia$Sí[1]  # Diabetes "Sí" e Hipertensión "Sí"
b <- tabla_contingencia$No[1]  # Diabetes "Sí" e Hipertensión "No"
c <- tabla_contingencia$Sí[2]  # Diabetes "No" e Hipertensión "Sí"
d <- tabla_contingencia$No[2]  # Diabetes "No" e Hipertensión "No"

# Calcular Odds Ratio
odds_ratio <- (a * d) / (b * c)

cat("Odds Ratio de hipertensión asociada a diabetes:", round(odds_ratio, 2))
Odds Ratio de hipertensión asociada a diabetes: 1.33

Determinar IC 95% a a los OR

# Logaritmo natural del OR
ln_or <- log(odds_ratio)

# Varianza del log(OR)
var_ln_or <- (1 / a) + (1 / b) + (1 / c) + (1 / d)

# Intervalo de confianza del 95%
z <- 1.96  # Valor crítico para 95%
se_ln_or <- sqrt(var_ln_or)  # Error estándar del log(OR)

# Límites inferior y superior del IC
ic_lower <- exp(ln_or - z * se_ln_or)
ic_upper <- exp(ln_or + z * se_ln_or)

# Imprimir resultados
cat("OR =", round(odds_ratio, 2), "\n","IC95%:", round(ic_lower, 2), "-", round(ic_upper, 2), "\n")
OR = 1.33 
 IC95%: 0.76 - 2.32 

Interpretación del Odds Ratio

  • OR>1: La hipertensión es más probable en personas con diabetes.

  • OR=1 : No hay asociación entre diabetes e hipertensión.

  • OR<1: La hipertensión es menos probable en personas con diabetes.

  • Frecuencias (a,b,c,d):

    • Se extraen directamente de la tabla de contingencia calculada con pivot_wider.
  • Odds Ratio (odds_ratio):

    • El cálculo del OR ya está realizado.
  • Logaritmo Natural del OR (ln_or):

    • Utilizamos log(odds_ratio) para calcular el logaritmo natural del OR.
  • Varianza del log(OR) (var_ln_or):

    • Fórmula:

  • Intervalo de Confianza:

    • Límite inferior:

    • Límite superior:

Interpretación del Resultado

  • El resultado de R=1.33 con un intervalo de confianza al 95% (C95%: 0.76 - 2.32) puede interpretarse de la siguiente manera:

    1. Valor del Odds Ratio (OR)

    • OR=1.33 (OR=>1)

      • Indica que las personas con diabetes tienen 1.33 veces más probabilidades de tener hipertensión en comparación con las personas sin diabetes.

      • Sin embargo, este valor debe evaluarse junto con el intervalo de confianza para determinar si la asociación es estadísticamente significativa.

    2. Intervalo de Confianza al 95% (IC95%)

    • IC95%=[0.76, 2.32]:

      • Este intervalo significa que, con un 95% de confianza, el verdadero Odds Ratio podría estar entre 0.76 y 2.32.

      • Incluye el valor 1, lo que implica que la asociación no es estadísticamente significativa(es posible que no haya diferencia real en las probabilidades de hipertensión entre personas con y sin diabetes).

Interpretación Práctica:

  • Existe una posible asociación positiva entre diabetes e hipertensión (OR=1.33), pero esta asociación no es estadísticamente significativa según el IC95%=[0.76, 2.32].

  • Más datos o estudios adicionales serían necesarios para confirmar esta relación.

nrow(datos)
[1] 120
LS0tCnRpdGxlOiAiRXN0dWRpbyBkZSBjYXNvcyB5IGNvbnRyb2xlcyIKQXV0aG9yOiAiSmVzdXMgQW5nZWwgSGVybsOhbmRleiBDaMOhdmV6IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIyMgKipEaXNlw7FvIGRlIHVuIEVzdHVkaW8gZGUgQ2Fzb3MgeSBDb250cm9sZXMqKgoKRW4gdW4gZXN0dWRpbyBkZSBjYXNvcyB5IGNvbnRyb2xlcywgaWRlbnRpZmljYW1vcyB1biBncnVwbyBkZSBwZXJzb25hcyBjb24gZWwgZGVzZW5sYWNlIGRlIGludGVyw6lzIChjYXNvcykgeSBvdHJvIGdydXBvIHNpbiBlbCBkZXNlbmxhY2UgKGNvbnRyb2xlcykuIEx1ZWdvLCBldmFsdWFtb3MgeSBjb21wYXJhbW9zIGxhcyBleHBvc2ljaW9uZXMgcHJldmlhcyBlbnRyZSBhbWJvcyBncnVwb3MgcGFyYSBleHBsb3JhciBhc29jaWFjaW9uZXMuCgojIyMjICoqRWplbXBsbyBkZSBQbGFudGVhbWllbnRvKioKCi0gICAqKlByZWd1bnRhIGRlIEludmVzdGlnYWNpw7NuOioqwqDCv0xhIGhpcGVydGVuc2nDs24gZXN0w6EgYXNvY2lhZGEgY29uIHVuIG1heW9yIHJpZXNnbyBkZSBkZXNhcnJvbGxhciBkaWFiZXRlcz8KCi0gICAqKkNhc29zOioqwqBQZXJzb25hcyBjb24gZGlhZ27Ds3N0aWNvIGRlIGRpYWJldGVzLgoKLSAgICoqQ29udHJvbGVzOioqwqBQZXJzb25hcyBzaW4gZGlhZ27Ds3N0aWNvIGRlIGRpYWJldGVzLgoKLSAgICoqRXhwb3NpY2nDs24gZGUgaW50ZXLDqXM6KirCoEhpcGVydGVuc2nDs24uCgotICAgKipDb3ZhcmlhYmxlczoqKsKgRWRhZCwgSU1DLCBhY3RpdmlkYWQgZsOtc2ljYSwgbml2ZWwgZWR1Y2F0aXZvLCBow6FiaXRvIGRlIGZ1bWFyLgoKIyMjICoqUGxhbnRlYW1pZW50byBkZWwgRXN0dWRpbyoqCgoxLiAgKipPYmpldGl2byBkZWwgRXN0dWRpbzoqKgoKICAgIC0gICBFdmFsdWFyIHNpIGxhIGhpcGVydGVuc2nDs24gYXVtZW50YSBlbCByaWVzZ28gZGUgZGlhYmV0ZXMuCgoyLiAgKipQcmVndW50YSBkZSBJbnZlc3RpZ2FjacOzbjoqKgoKICAgIC0gICDCv0VzIG3DoXMgcHJvYmFibGUgcXVlIGxhcyBwZXJzb25hcyBjb24gaGlwZXJ0ZW5zacOzbiBkZXNhcnJvbGxlbiBkaWFiZXRlcyBxdWUgYXF1ZWxsYXMgc2luIGhpcGVydGVuc2nDs24/CgozLiAgKipWYXJpYWJsZXM6KioKCiAgICAtICAgRGVwZW5kaWVudGU6wqAqKkRpYWJldGVzKirCoChDYXNvczogU8OtOyBDb250cm9sZXM6IE5vKS4KCiAgICAtICAgSW5kZXBlbmRpZW50ZTrCoCoqSGlwZXJ0ZW5zacOzbioqwqAoU8OtL05vKS4KCiAgICAtICAgQ292YXJpYWJsZXM6IEVkYWQsIElNQywgYWN0aXZpZGFkIGbDrXNpY2EsIG5pdmVsIGVkdWNhdGl2bywgaMOhYml0byBkZSBmdW1hci4KCiMjIyAqKlByw7N4aW1vcyBQYXNvcyoqCgotICAgTGltcGllemEgZGUgbGEgYmFzZSBkZSBkYXRvcyBzaW11bGFkYS4KCi0gICBFeHBsb3JhY2nDs24gZGVzY3JpcHRpdmEgKEVEQSkgZGUgbGFzIGNhcmFjdGVyw61zdGljYXMgZGUgY2Fzb3MgeSBjb250cm9sZXMuCgotICAgQW7DoWxpc2lzIGJpdmFyaWFkbyAoT2RkcyBSYXRpbyBwYXJhIGhpcGVydGVuc2nDs24pLgoKLSAgIEFqdXN0ZXMgbXVsdGl2YXJpYWRvcyB1c2FuZG8gcmVncmVzacOzbiBsb2fDrXN0aWNhLgoKRXN0ZSBkb2N1bWVudG8gYWJvcmRhIGVsIGFuw6FsaXNpcyBkZSB1biBlc3R1ZGlvIGRlIGNhc29zIHkgY29udHJvbGVzIHBhcmEgZXhwbG9yYXIgbGEgYXNvY2lhY2nDs24gZW50cmUgaGlwZXJ0ZW5zacOzbiB5IGRpYWJldGVzLiBJbmljaWFyZW1vcyBjb246CgpEZXNjYXJnYW1vcyBlbCBkYXRhIGZyYW1lOsKgPGh0dHBzOi8vY29sYWIucmVzZWFyY2guZ29vZ2xlLmNvbS9kcml2ZS8xQlB0RFNnekVmV0t5c1VCZGJiMlVGdWJPd1FlY0ViOFg/dXNwPXNoYXJpbmcjc2Nyb2xsVG89WTZsOEd3a1YyZHNzPltlc3R1ZGlvX2Nhc29zX2NvbnRyb2xlc19lcnJvcmVzLnhsc3hdKGh0dHBzOi8vcnN0dWRpby1wdWJzLXN0YXRpYy5zMy5hbWF6b25hd3MuY29tL2VzdHVkaW9fY2Fzb3NfY29udHJvbGVzX2Vycm9yZXMueGxzeCkKCmxvIGd1YXJkYW1vcyBjb21vIHVuIG9iamV0byAoZGF0b3MpCgpbMS5dey51bmRlcmxpbmV9wqBMaW1waWV6YSBkZSB1bmEgYmFzZSBkZSBkYXRvcyBjb24gZXJyb3JlcyBpbnRlbmNpb25hZG9zLsKgCgpbMi5dey51bmRlcmxpbmV9wqBFeHBsb3JhY2nDs24gZGVzY3JpcHRpdmEgZGUgbGFzIHZhcmlhYmxlcy7CoAoKWzMuXXsudW5kZXJsaW5lfcKgQW7DoWxpc2lzIGJpdmFyaWFkbyB5IG11bHRpdmFyaWFkbyBtZWRpYW50ZSByZWdyZXNpw7NuIGxvZ8Otc3RpY2EuCgpgYGB7cn0KIyBJbnN0YWxhciBwYXF1ZXRlcyBuZWNlc2FyaW9zIChzaSBhw7puIG5vIGVzdMOhbiBpbnN0YWxhZG9zKQojaW5zdGFsbC5wYWNrYWdlcygicmVhZHhsIikKIyBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQojIGluc3RhbGwucGFja2FnZXMoImphbml0b3IiKQojIGluc3RhbGwucGFja2FnZXMoImd0c3VtbWFyeSIpCgojIENhcmdhciBsaWJyZXLDrWFzCmxpYnJhcnkocmVhZHhsKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYGBgCgpgYGB7cn0KbGlicmFyeShqYW5pdG9yKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KGd0c3VtbWFyeSkKbGlicmFyeShkbG9va3IpCmBgYAoKYGBge3J9CiMgTGVlciBsYSBiYXNlIGRlIGRhdG9zIGRlc2RlIEV4Y2VsCiNhcmNoaXZvIDwtICJlc3R1ZGlvX2Nhc29zX2NvbnRyb2xlc19lcnJvcmVzLnhsc3giCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHJlYWR4bCkKCmVzdHVkaW9fY2Fzb3NfY29udHJvbGVzX2Vycm9yZXMgPC0gcmVhZF9leGNlbCgiL1VzZXJzL2plc3VzaGVybmFuZGV6L0Rvd25sb2Fkcy9lc3R1ZGlvX2Nhc29zX2NvbnRyb2xlc19lcnJvcmVzLnhsc3giKQoKCiNkYXRvcyA8LSByZWFkX2V4Y2VsKGFyY2hpdm8pCgpkYXRvczwtZXN0dWRpb19jYXNvc19jb250cm9sZXNfZXJyb3JlcwoKIyBWaXN1YWxpemFyIGxhcyBwcmltZXJhcyBmaWxhcwojaGVhZChkYXRvcykKYGBgCgojIyAqKlBhc28gMjogTGltcGllemEgZGUgbGEgQmFzZSBkZSBEYXRvcyoqCgpFbiBlc3RlIHBhc28sIHV0aWxpemFyZW1vcyBsYXMgZnVuY2lvbmVzIGRlwqBgamFuaXRvcmDCoHnCoGBkcGx5cmDCoHBhcmE6CgoxLiAgTGltcGlhciBub21icmVzIGRlIGNvbHVtbmFzLgoKMi4gIENvcnJlZ2lyIGluY29uc2lzdGVuY2lhcyBlbiB2YWxvcmVzIGNhdGVnw7NyaWNvcy4KCmBgYHtyfQojIExpbXBpYXIgbm9tYnJlcyBkZSBjb2x1bW5hcwpkYXRvcyA8LSBkYXRvcyAlPiUgY2xlYW5fbmFtZXMoKQoKbmFtZXMoZGF0b3MpCmBgYAoKYGBge3J9CiMgQ29ycmVnaXIgaW5jb25zaXN0ZW5jaWFzIGVuIHZhbG9yZXMgY2F0ZWfDs3JpY29zCmRhdG9zIDwtIGRhdG9zICU+JQogIG11dGF0ZSgKICAgIHNleG8gPSBzdHJfdG9fdGl0bGUodHJpbXdzKHNleG8pKSwgICMgVMOtdHVsbyAocHJpbWVyYSBsZXRyYSBlbiBtYXnDunNjdWxhKQogICAgZnVtYWRvciA9IHN0cl90b19sb3dlcih0cmltd3MoZnVtYWRvcikpLCAgIyBNaW7DunNjdWxhCiAgICBoaXBlcnRlbnNpb24gPSBzdHJfdG9fbG93ZXIodHJpbXdzKGhpcGVydGVuc2lvbikpLCAgIyBNaW7DunNjdWxhCiAgICBuaXZlbF9lZHVjYXRpdm8gPSBzdHJfdG9fdGl0bGUodHJpbXdzKG5pdmVsX2VkdWNhdGl2bykpICAjIFTDrXR1bG8KICApCgojIFZpc3VhbGl6YXIgbG9zIGRhdG9zIGxpbXBpb3MKaGVhZChkYXRvcykKYGBgCgpgYGB7cn0Kc2FwcGx5KGRhdG9zLCB1bmlxdWUpCmBgYAoKbGltcGllemEgcGFyYSBldml0YXIgcXVlIHNlIHJlcGl0YW4gZWxlbWVudG9zIHUgaG9tb2dlbml6YXJsb3M6CgpgYGB7cn0KIyBMaW1waWV6YSB5IGhvbW9nZW5pemFjacOzbiBkZSBkYXRvcyBjYXRlZ8Ozcmljb3MKZGF0b3MgPC0gZGF0b3MgJT4lCiAgbXV0YXRlKAogICAgIyBIb21vZ2VuZWl6YXIgdmFsb3JlcyBlbiBgZnVtYWRvcmAKICAgIGhpcGVydGVuc2lvbiA9IGNhc2Vfd2hlbigKICAgICAgaGlwZXJ0ZW5zaW9uICVpbiUgYygic8OtIiwgIlPDrSIsICJTw40iLCAic2kiKSB+ICJTw60iLAogICAgICBoaXBlcnRlbnNpb24gJWluJSBjKCJubyIsICJObyIsICJOTyIpIH4gIk5vIiwKICAgICAgVFJVRSB+IE5BX2NoYXJhY3Rlcl8KICAgICkpCgpzYXBwbHkoZGF0b3MsIHVuaXF1ZSkKYGBgCgojIyAqKlBhc28gMzogRXhwbG9yYWNpw7NuIGRlIERhdG9zIChFREEpKioKCiMjIyAqKlJlc3VtZW4gRXN0YWTDrXN0aWNvIGRlIFZhcmlhYmxlcyBDdWFudGl0YXRpdmFzKioKCnBvZGVtb3MgdXNhciBsb3MgcGFxdWV0ZXMswqAqKmRsb29rciwgZ3RzdW1tYXJ5KirCoG8gc2ltYnBsZW1ldGUgY29uIGJhc2UgUjoKCmBgYHtyfQojIFJlc3VtZW4gZXN0YWTDrXN0aWNvCmRhdG9zICU+JQogIHNlbGVjdF9pZihpcy5udW1lcmljKSAlPiUKICBzdW1tYXJ5KCkKYGBgCgoqKipjb21vIGxvIGhhcsOtYXMgY29uIGRsb29rcj8qKioKCmBgYHtyfQpkYXRvcyAlPiUgZGVzY3JpYmUoKQpgYGAKCmBgYHtyfQpkYXRvcyAlPiUgbm9ybWFsaXR5KCkKYGBgCgpgYGB7cn0KZGF0b3MgJT4lIHBsb3Rfbm9ybWFsaXR5KCkKYGBgCgpEaXN0cmlidWNpw7NuIGRlIENhc29zIHkgQ29udHJvbGVzCgpgYGB7cn0KIyBGcmVjdWVuY2lhIGRlIGRpYWJldGVzCmRhdG9zICU+JQogIGNvdW50KGRpYWJldGVzKSAlPiUKICBtdXRhdGUocG9yY2VudGFqZSA9IG4gLyBzdW0obikgKiAxMDApCmBgYAoKYGBge3J9CiMgR3LDoWZpY28gZGUgYmFycmFzCmRhdG9zICU+JQogIGdncGxvdChhZXMoeCA9IGRpYWJldGVzLCBmaWxsID0gZGlhYmV0ZXMpKSArCiAgZ2VvbV9iYXIoKSArCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGRlIENhc29zIHkgQ29udHJvbGVzIiwgeCA9ICJEaWFiZXRlcyIsIHkgPSAiRnJlY3VlbmNpYSIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgojIyAqKlBhc28gNDogQW7DoWxpc2lzIEJpdmFyaWFkbyAoT2RkcyBSYXRpb3MpKioKClVzYXJlbW9zIHRhYmxhcyBkZSBjb250aW5nZW5jaWEgcGFyYSBjYWxjdWxhciBsYXMgT2RkcyBSYXRpb3MgZGUgaGlwZXJ0ZW5zacOzbi4KCmBgYHtyfQojIFRhYmxhIGRlIGNvbnRpbmdlbmNpYQoKZGF0b3MyIDwtIGRhdG9zICU+JQogIG11dGF0ZSgKICAgIGRpYWJldGVzID0gZmFjdG9yKGRpYWJldGVzLCBsZXZlbHMgPSBjKCJTw60iLCAiTm8iKSksICAjIERpYWJldGVzOiAic2kiIHByaW1lcm8KICAgIGhpcGVydGVuc2lvbiA9IGZhY3RvcihoaXBlcnRlbnNpb24sIGxldmVscyA9IGMoIlPDrSIsICJObyIpKSAgIyBIaXBlcnRlbnNpw7NuOiAic2kiIHByaW1lcm8KICApCgp0YWJsYV9jb250aW5nZW5jaWEgPC0gZGF0b3MyICU+JQogIGNvdW50KGRpYWJldGVzLCBoaXBlcnRlbnNpb24pICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBoaXBlcnRlbnNpb24sIHZhbHVlc19mcm9tID0gbiwgdmFsdWVzX2ZpbGwgPSAwKQoKdGFibGFfY29udGluZ2VuY2lhCmBgYAoKYGBge3J9CiMgQ2FsY3VsYXIgT2RkcyBSYXRpbyBtYW51YWxtZW50ZQpvZGRzX3JhdGlvIDwtICh0YWJsYV9jb250aW5nZW5jaWEkU8OtWzFdICogdGFibGFfY29udGluZ2VuY2lhJE5vWzJdKSAvCiAgICAgICAgICAgICAgKHRhYmxhX2NvbnRpbmdlbmNpYSRTw61bMl0gKiB0YWJsYV9jb250aW5nZW5jaWEkTm9bMV0pCgoKIyBFeHRyYWVyIHZhbG9yZXMgZGUgbGEgdGFibGEKYSA8LSB0YWJsYV9jb250aW5nZW5jaWEkU8OtWzFdICAjIERpYWJldGVzICJTw60iIGUgSGlwZXJ0ZW5zacOzbiAiU8OtIgpiIDwtIHRhYmxhX2NvbnRpbmdlbmNpYSROb1sxXSAgIyBEaWFiZXRlcyAiU8OtIiBlIEhpcGVydGVuc2nDs24gIk5vIgpjIDwtIHRhYmxhX2NvbnRpbmdlbmNpYSRTw61bMl0gICMgRGlhYmV0ZXMgIk5vIiBlIEhpcGVydGVuc2nDs24gIlPDrSIKZCA8LSB0YWJsYV9jb250aW5nZW5jaWEkTm9bMl0gICMgRGlhYmV0ZXMgIk5vIiBlIEhpcGVydGVuc2nDs24gIk5vIgoKIyBDYWxjdWxhciBPZGRzIFJhdGlvCm9kZHNfcmF0aW8gPC0gKGEgKiBkKSAvIChiICogYykKCmNhdCgiT2RkcyBSYXRpbyBkZSBoaXBlcnRlbnNpw7NuIGFzb2NpYWRhIGEgZGlhYmV0ZXM6Iiwgcm91bmQob2Rkc19yYXRpbywgMikpCmBgYAoKRGV0ZXJtaW5hciBJQyA5NSUgYSBhIGxvcyBPUgoKYGBge3J9CiMgTG9nYXJpdG1vIG5hdHVyYWwgZGVsIE9SCmxuX29yIDwtIGxvZyhvZGRzX3JhdGlvKQoKIyBWYXJpYW56YSBkZWwgbG9nKE9SKQp2YXJfbG5fb3IgPC0gKDEgLyBhKSArICgxIC8gYikgKyAoMSAvIGMpICsgKDEgLyBkKQoKIyBJbnRlcnZhbG8gZGUgY29uZmlhbnphIGRlbCA5NSUKeiA8LSAxLjk2ICAjIFZhbG9yIGNyw610aWNvIHBhcmEgOTUlCnNlX2xuX29yIDwtIHNxcnQodmFyX2xuX29yKSAgIyBFcnJvciBlc3TDoW5kYXIgZGVsIGxvZyhPUikKCiMgTMOtbWl0ZXMgaW5mZXJpb3IgeSBzdXBlcmlvciBkZWwgSUMKaWNfbG93ZXIgPC0gZXhwKGxuX29yIC0geiAqIHNlX2xuX29yKQppY191cHBlciA8LSBleHAobG5fb3IgKyB6ICogc2VfbG5fb3IpCgojIEltcHJpbWlyIHJlc3VsdGFkb3MKY2F0KCJPUiA9Iiwgcm91bmQob2Rkc19yYXRpbywgMiksICJcbiIsIklDOTUlOiIsIHJvdW5kKGljX2xvd2VyLCAyKSwgIi0iLCByb3VuZChpY191cHBlciwgMiksICJcbiIpCmBgYAoKIyMjICoqSW50ZXJwcmV0YWNpw7NuIGRlbCBPZGRzIFJhdGlvKioKCi0gICBPUlw+MTogTGEgaGlwZXJ0ZW5zacOzbiBlcyBtw6FzIHByb2JhYmxlIGVuIHBlcnNvbmFzIGNvbiBkaWFiZXRlcy4KCi0gICBPUj0xIDogTm8gaGF5IGFzb2NpYWNpw7NuIGVudHJlIGRpYWJldGVzIGUgaGlwZXJ0ZW5zacOzbi4KCi0gICBPUlw8MTogTGEgaGlwZXJ0ZW5zacOzbiBlcyBtZW5vcyBwcm9iYWJsZSBlbiBwZXJzb25hcyBjb24gZGlhYmV0ZXMuCgo8IS0tIC0tPgoKLSAgICoqRnJlY3VlbmNpYXMgKCoqYSxiLGMsZCk6CgogICAgLSAgIFNlIGV4dHJhZW4gZGlyZWN0YW1lbnRlIGRlIGxhIHRhYmxhIGRlIGNvbnRpbmdlbmNpYSBjYWxjdWxhZGEgY29uwqBgcGl2b3Rfd2lkZXJgLgoKLSAgICoqT2RkcyBSYXRpbyAoYG9kZHNfcmF0aW9gKToqKgoKICAgIC0gICBFbCBjw6FsY3VsbyBkZWwgT1IgeWEgZXN0w6EgcmVhbGl6YWRvLgoKLSAgICoqTG9nYXJpdG1vIE5hdHVyYWwgZGVsIE9SIChgbG5fb3JgKToqKgoKICAgIC0gICBVdGlsaXphbW9zwqBgbG9nKG9kZHNfcmF0aW8pYMKgcGFyYSBjYWxjdWxhciBlbCBsb2dhcml0bW8gbmF0dXJhbCBkZWwgT1IuCgotICAgKipWYXJpYW56YSBkZWwgbG9nKE9SKSAoYHZhcl9sbl9vcmApOioqCgogICAgLSAgIEbDs3JtdWxhOgoKICAgICAgICAhW10oZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFRc0FBQUFpQ0FZQUFBQklnZndZQUFBTVpVbEVRVlI0QWUyYzFhdFZUeFRIL1FkVVZGQVFGUlVERlFNTEZBTVZUR3hGRkFOOUVCTzdBMFJVVkxBYnhUZFJ4TWJBZXJDN1VQRkJzVEd3RXdQbngyZGdYZWJNblgxcTlybm4vTTdkQzg3ZE5iRm03Vm5mV1RIN2xsQVJSUktJSkJCSklBa0psRWlpVEZRa2trQWtnVWdDS2dLTGFCS2tKSUczYjkrcUh6OStwRlFuVTRVL2ZmcWt2bno1a3FubVUybzNsM2o1L2Z1M2V2WHFWVXI4SjFNNEFvdGtwRlRNeXdBT0J3OGVWTU9HRFZPTkdqWEt5RVJNVnNSLy92eFJwMCtmVmhNbVRGQzFhOWRXTjIvZVRMWnE2T1Z5aVJjRzkrREJBN1Y4K1hMVm9FRUR0V0xGaXRESEc0RkY2Q0xOdndiLy92MnIzcjE3cHk1ZnZxeGF0bXlaVmJENDkrK2Zldi8rdlhyeTVJbm1KWnRna1V1OE1PdStmZnVtc0hCR2poeFp2TURpOCtmUENuTXFFOFRrLy9qeG8rSmxaNHZpalk5eDh6elhDTVhNTmxpSVREQ3o0U1diWUpHTHZNQlRzUUtMWThlT3FWbXpac1dBQmFqSml1S3I0Q2ppZ2dVTDFJRURCK1JkRnpyUzE1a3paOVMrZmZ2VWpSczNZdmdvVkRqTkc5ZXVYVk1qUm94d2dnSThUcDgrUFM2UGFYYnJWUzBDQzdmNGNnbTQ0RENqWURGanhneFZ1blJwVmJKa3lZTGZvRUdEMVBmdjN3dWtzM0hqeG9KbmxPdmR1M2ZNODRLQ25pZTNidDFTWGJ0MlZRVFNvTHQzNzZwcTFhcnB2cnQwNmFKTkxaOHUxcXhabzJiT25Pa0VIWUpsVTZaTVVmWHIxOWUrSDJBeGRlcFVWYjE2ZFVVOTI5TFp1bldycWxDaFFveGNhdGFzcWNxV0xhdmwyYk5uVDNYdTNEbG5YNHhoNTg2ZDJ2ZTIyK1Vad05pblR4OEZxT1FLUldEaGZoUEZDaXdRQVJOMjZOQ2hldUlIcmJxWExsMVNyVnExVWc4ZlBuUkx6Zk11Z2JRQkF3YW8zYnQzeDdRRWJ3TUhEbFMrWUhILy9uM1ZwazBiN2UvR2RLQ1VldkhpaFg3V3JWczM5ZUhEaDVqSGp4NDkwb0c5OGVQSEZ3SU1DaEpVQWtCMzdkcFZVQStldDIvZnJzcVVLYU1tVHB6b3JNZDQrL2Z2SDJoQm5EaHhRdlhvMGNNYklBdVk4anlKd01JdHdHSUhGb2dCSldYU0R4OCtYQkhwdFlubnJMeStyb0Rkcmx5akhDMWF0RkJ2M3J5Uld3VkhUQ3Nmc0lCbmVIZnhMMHFMVlFBd3VBamVzTDVXcmx4WmFQeEVucEhia1NOSFlxb2l3OEdEQit0bk5nQktRZTUzNk5EQjZZNFF0K0JaVUYxcG82aU9ZWUhGN05tejFaMDdkN3pZRGt0QmM0bVg5ZXZYcStQSGozdkpoY29aZFVPRU81UzBTWk1tT2lWRnROa2tKdjZZTVdQVWhRc1h6TnVobmFQTW8wYU4wbWEvcTFGZnNIajU4cVcyRGtpNzJRUVFsQ3BWU3ZjZkJJUUVSTEZLU05mWnNna0NDL3FCYjRDRVZKK0xIajkrckZOZFFYSWx2Z0xndU1EYjFWNG03NFVGRmdBMmJmbFFXR0NSUzd3d2ord0ZKeDBaRlFsWXlPckw1TjYyYlZzTW4rUndNWmxkVVhyOGEvTHdpeFl0VW52Mzd0WCt0bG41NTgrZk90MUcwUERxMWF2Nk9RajYvUG56Z21LazVwbzFheFpva3R0Z1FZcm8yYk5uV3JnQUFYM1FQc0tHSDVzQUNXSVJ1QnNtQ1VpNXhteVc0MXdVMzVaTkVGZ2tZMWtRRityZXZidDJaZXordUVaT2RlclVLY1MzcTJ5bTdpSHIrZlBucTQ0ZE8ycFE3ZGV2bjFxMWFwV1dlVHA5K2lnbzc1bSs0UUdBaHlkNGc4ZDBLSmQ0OFFVTDVncHp0R0xGaW5yT3NMamZ2bjA3SGJFNDZ4VGFaNEZTOFJKNjllb1ZzMU52OCtiTnp0d3RjWUNxVmF1cWVmUG1hVURZc1dPSERnaWFjUTlXa2ViTm0rc1Z0bDI3ZG5vRkovaEhQZXBEbEVFcGdsWWNHeXpXclZ1bktsV3FwTnRrOWNVcXdWd25JRm01Y3VWQ2dVRmVoTXVOSWZQQmZaY2JZVXRNWWhOang0Nk5lZVFDQzlLejhFUE1BbFBYRmNTVVJoZ2JtUkdYVllNOHNHYXVYNzh1eGYvM1J4OEZEWHZ3dWNTTEwxaUVMUnU3dlVKZ2dlV0FRcU9JOSs3ZDArWHg2Wm5NY20wMndrYWRjdVhLS1ZFZ3NVN3ExcTJyV1BHRlJDbkpiQkFnM2JScGsrcmN1WFBCaW9sRlVLTkdEWVZaN2lJYkxDaURBcFV2WHo0RzJMQWNVQzVBd3lUcXU4eDV6RmxBS2htd0VGQ2dMWlBrZnRPbVRUWHd0Ry9mWHNjM3NHUlFkaGNJMlBWZFFFWVo0UytSZVVxc3BYWHIxbm9zakNlWlg3WmlJYm1rb0xuRXkvOE9MSmlnaXhjdjFzckRFUUlRMk9xTENXZ1Rpa0Qyd0Z3NUdUUktiRm9KQWhaQlNvRXlNTUZSRGhlNXdJTDI2Y2QwQzBTNWJJWG0ycjVIUDErL2Z0V21iREpnQVFCUnptNUh3TUpVYU1tZzRHSzRYRGR6ak5RbkhrSmN4Q1laajVscHNjdGs4cHJ4eHZ2RjYxdmNUOFpnL2pDUFQ1NDhHWE9QNThuc284a0hYdEFWNG9PbVREaGZ1SENod2pLMzc3T05BRXMxSHFVcmwzaHQyczhLV1JZVXdJTEFzc0RDWUtJdldiSWtia1NlMVh6eTVNazZKb0J5c01JVkpWaVlTb3FnQVIxYm9ZUEFBckREaFVIWUtHMFFtZkdIdFd2WHhoUnpnUVVGQUxGRTdWS08rbGdocml5UWpNZnVNNGFCSEwxZ253cnBadnZYdUhGam5RcTM3L3ZFSGhLSklKZDRZUXVDUFhhdTBSdFM1ZmF6YWRPbXFhZFBueVlhWXNhZk84RUN0NE9ZQmJFTFRGVTJZTmtaQU9HTUZZS05TV3gwb2g3RTVBOENDMXVKcFIwZnk4SUhMT2lmTWFMVUxqZEYrTU9sd3JVeTNUTjVGZ1FXOEVXN1FmRUlzMzZReFNWZ1lZNVI2cGxIVmg1V0lIdFZpbmVOdFpjTjhqWDkyZWlHUXJHWjBQZXJVMTlld3BRZjh5alJlMDYyUDZ3MDRvaHNnMEJlWVpBVExHZ1lzNWVKWHF0V0xmMVNYSDQzWm1iZnZuMTF1dFZjRlFVc1lITDE2dFY2cDZlNElVRmdRZXFRZlE1QitYZnEyUW9sYm9ncFlGRXV1eCtDb0ZnOTVxNVVFU0M4Z2VnMndNbHpqdXkyUkI2WWlyWXNFb0VGRVh2Y25TQ0t4eHN4SE9TU0tQL091TmdtendxYTdJOE1WellvREFVbDJKd0loSk1aV3hpOEpOTlBNbVhDQkF2NlE1ZElMQVRGQVpQaHlTd1RDQlpZRWdRS3NTN1loK0FpQVFzem1Da2JuRkE4TWl1Z1A4b29ZQkdrc0V4Y2xNSzFENEsrWFdBaEFVNHo4eElFRnJnRXBHWkowYnFJTkN5ZlgzZnExRW05ZnYwNnBnaGJyckVvaGd3WjRvdy9TSmJFNUlNR0FFQ3lJUks0QlRBd3RaR0ZFTUREcExjRHN2S2NNZUtpWkV1eGhZOHdqNzRLS2k2aEdhdEtsejlmWHRMdDExVXZiTEE0ZlBpdy9uVENuRy8wRVM4MjZPSkw3Z1dDaGZqeVFZRTNhWUE4THQvUGcyQ1lobnhUQXBQc3hDU0ZTZFlEQU9DY2xaa2Y1N2d0SmdtWTJCT0FiME5RWXJPdWdKRDVQUXVLVFA3ZC9GYURldFNIc0VJYU5td1lWK2tBQ2JhOFY2bFNSUzFkdWxTdjBDZ3gxK3pjRkRkTCtPYmJFUGx1UmZnekFZOUFGbHU5QWR3NWMrWW92cS9CTkRRdEU0S2FiZHUyMVRLVGRzMGpGcDV0VVpuUGkvS2M4UkRNTnZsUHAzOWZCY1dLNWJPRGl4Y3ZhdkJQRlB5THg2TXZMOUkyTXNIME54VlRuaVY3REFzczJITUNIOHhkckZhVE1nSVdkTUJxeXlhcVJDU0NNcU8ydkVBelE1S29EWjZUZllrWE4waW1qYUF5a2hKT0pxdEEyVk9uVG1td1lLT1hLd3NVMUk5OUg5a1FuRHAwNkpBR1RSdHd5RFN4YTlZVkUySUZ4ZWVVckpUZGRsRmRNNGFqUjQrcWNlUEdLUUFTNjVDQU52eWxRNzRLaXNXR3BUZDY5R2kxWWNNR0RmQ0pNazVCZlByeVFydG56NTdWVmlldUt0ODJzVmltUTc1Z3dXTEhmTm15Wll0ZXBOaWNsUzR2THY0RExRdFg0VXpmSTkzSS95aHc3ZWNJbzI5ZUpsOXkyZ29iUnR2cHRJRVNFZ054eFVGb0QzbVFrZUtZVGNLU3d6MlRuYkc0aFBhS2xRcC9BQS91WXJwRVpvZ1BDMW1NV0VINVNqbFJUQ2VvTDE5ZUFDNnlHQ3dJV0R4WXMzdjI3QW5xTHU1OXNpVHB1cHZNYVlDS09RNWhTYlB2SjZ4NEJXM21GRmpBVUx4UHlMVVVQUDR3c2RnbUhCUVg4V2c2cmFxQUFLczBGcHhOQUFuYjUxMGZydGxsTTNrdGNTa0JCMUhPTUZlc1ZQaTM0eFh5bVlBWjVFNmxQWit5dG14ODJ2S3RTMXlSV0lTQUErOEhFT1Y5aFVVNUJ4YXNGcGlHKy9mdkQydU1NZTJnbUNDd1MwRmpDbWI0Z25HeXY4TU9pa3EzNTgrZjF5NVp1dWExdE9ON3hBSWcxaU1BeTJRa2pnWFEvZnIxeTdmNWxPc0REc1I0V05FaEFzRDE2dFhMbURVYWowRmtRM0EvWGFzbVh0dXBQc09GSVRNcExyUEVLNWhuUGpFZGs0K2NBd3VZSXcySWFTNG9hVEljeGptbUhxdDJOaWE3OE0vL3VnaktNckduZzVVODIwQUJyNWpXbU5tWXRSQm1MdHYwcjF5NW9tTTZNcDZpT2hJUUpzME5QK0xHRVVST04zN2l3emZBeGRaK0FFc0lkd1Izb3FnSjEweTJDK0F1NHI1aVhmQk5WMUFHTUZVZWN4SXNVaDFFVkQ1ekVrQWhjUTFacVpZdFc2YXRQckl6Z0szOUJXL211SWh0bWF3UzJUUVdGTEpNcnIwenNUVXlkNFZsU0FhTmpYMXo1ODdWTXNwR1RBeExHUmViQVBTa1NaUDBPVUZvdG8rSFJSRlloQ1hKUEc4SDMxZE1YSTV5bnExaHcwK1kvcmpQT0pDRm1RbjBhY3VuTHU0R2xoY0F6NDk5UFJ6RG9nZ3N3cEprMUU0a2dUeVhRQVFXZWY2Q28rRkZFZ2hMQWhGWWhDWEpxSjFJQW5rdWdRZ3M4dndGUjhPTEpCQ1dCQ0t3Q0V1U1VUdVJCUEpjQWhGWTVQa0xqb1lYU1NBc0NVUmdFWllrbzNZaUNlUzVCUDRES3liaU4wVTJnK2dBQUFBQVNVVk9SSzVDWUlJPSkKCi0gICAqKkludGVydmFsbyBkZSBDb25maWFuemE6KioKCiAgICAtICAgKipMw61taXRlIGluZmVyaW9yOioqCgogICAgICAgICFbXShkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUtJQUFBQWFDQVlBQUFBMGE0Y0RBQUFJQTBsRVFWUjRBZTJhK2F0TlhSakgvUVBJTDhxTkg0Z2tpWWd5cEZEWGxLRlFaSXBDbWJraE4wTXlsSlF4SkZPVW1aRE1Vc2FRZVpZcDg1QjVEbm5lUGl2UGFwMTkxajdPUHNmWmJyMzdxZE9lMWw3cldkLzFYYyswVHpsSkpFR2dEQ0JRcmd6b2tLaVFJQ0FKRVJNU2xBa0VZaVBpOCtmUDVkYXRXd1daOU5HalIrWHo1ODhGNlR1dVRuLzkraVZuenB5UmI5Kys1VHhrM0JnL2ZmcFVMbDY4bUxPKzdvdVJpUGpnd1FNWk4yNmNEQjgrWEc3Y3VPSDJrL0g4NGNPSE1ucjBhSG4vL3IxdDkvUG5UOW0yYlp0MDd0eFpoZ3daSXQyN2Q1Zmp4NDhMQzRMb1dDTkdqQkQ5alJrelJqWnUzQ2l2WDcrMi9XamJPWFBteVBmdjMxUHVSNzJnMzhtVEo5dnhkRnlPNjlhdFMrc09YYmR1M1NwdDI3WTE4MWkrZkxtc1hMbFNybDY5S212V3JQSDJvMzFldW5USjlrYy9peGN2bHAwN2Q5cDV4NEh4MTY5ZlpmNzgrV2w2enBzM1QyN2Z2bTNYQWtWWmp5REc2TDFpeFFvNWUvYXNuVXV1SjVHSXlDQlhybHlSaGcwYnlvVUxGN0lhODhlUEgxSmFXaXFuVDUrMjdiRmVnd2NQbGxtelpsbnlmUG55eFFCQ1d5VVV4Lzc5KzB2WHJsMkY1Ky9ldlpPOWUvZEs3ZHExemFMWkRrVU1BU0JCUG5MdzRFRnAyclNwWUdFL2ZmcGtGb0pGYWRTb2tiQ1pncko3OTI0Wk5XcVUxZmZVcVZOU3IxNDlndzI2SGpwMFNDcFhyaXpyMTYrWFo4K2VtZCtkTzNmTW5PYk9uV3U3dzZxTUhUdFd3QXFKRTJQSXRHWExGcWxhdGFwY3UzWk5JT2ZObXplbFhidDJ4bmpvV3FBWCtBWXhmdm55cFF3WU1FQTQ1aU9SaVFpZ3pabzF5NXFJVEc3Z3dJR0dTS3Jvd29VTHBWV3JWbW1XN2RHalI5S2dRUU5qOWJRdGhPWG5DdGVOR3plV1Y2OWUyZHRQbmp5UkhqMTZwTnl6RDdNOG1UMTd0bHkvZnQyMjNyRmpoOVNzV1ROMHg2TUhWa3lGUmNWajZDYmxDQkgzN05talRjengvdjM3eHJwd3dUc1RKa3dRTm9GSzNCaWpYNTA2ZGN4R1VSMjRWNkZDQlRsOCtMRGVrakNNMlZSQmd0cVhzanpKbTRqc0lGd2FnR0lGK0xteWFORWljWGMvNUlGRTA2Wk5jNXVaYy9xQXRPM2J0emNXaVp2WkVoRnJ3czUwZ1VzYklNT05EeDgreUtwVnE2dzdVaEppNWNKazJMQmgwckZqUjNuejVvMXRjdVRJRWVQR3VCRWtJdGRxYmRldVhXdkdldkhpaFhIckxMSktrSWlGeGpoYklvWmhmUExrU2VuYnQ2K3hwanFIcU1lOGlFaWMwN3AxYTJuU3BJbE1talRKbVBoZXZYb0pGZzlSWXJrV1FSZkhKYWVyTkhFSVZnaXJnYmhFeEUzczI3ZFA2dGV2THdjT0hIQmZNK2U4Qy9IekZXSWVkSUNNbVlSMnVMVHk1Y3RMeTVZdFpjbVNKUUtoVlhTdXVHWmNNdGJTeFlKMjU4NmRNNWFjVUVERkpXSWNHTHRFWk0zdTNyMHJIVHAwTVBHeTY1clJ6NGZ4NDhlUHpZWmtVK1VxZVJHUlFRR2J1QWdYakRBcHRXaUEyN05uVCt1cXREM3VLaE1ScTFTcElwY3ZYemI5UVVTU2dlM2J0eHNRNnRhdGE1SWNBQXNLZmZvc2JiQmRwbXRpUVdKQ1lzUGdHRndUUDdsa0kya2oyYXBSbzRZaFpJc1dMV3k4cEVRa0FTSU82OWF0V3hvUndZczV1dUlTa2Z1RnhoZ2QyRkNyVjY4MlNSWjRreXdSbHdmRmh6SDZ0bW5UeGhxUDREdlpYUDhWSWhJem9nenlKeUppNmJBMjdDeWZzQ2dRVzNlWGF4RnBqK3NqV1ZIaXUzMjRpNG9ibVRGamh0a1ViQXpmTDZpRGt0Qk5va2hJS0tzZ3pKRllpZ1FGSWVseXlZb2JaMEUzYmRwa25pc1IwUXZCK3FFL2dyWEZrcmc2bXdlL3gzSGpjUG9wSk1ibzRNYUloRnBzcUdYTGxxbEs5dWpUMTJkdzdBdFpuc1JPUkkwek5CTjI5WHo3OXExeGNTVWxKWGFCZzBUVXhkWEZkdC8zN1ZiM2VhWnpTa3VkT25VeW1idTZJeXpDbENsVEJMMlFvRVZrb1Q1Ky9HaTc1VGt4cmxwNzFWV0pxQTFwUjJKRXZPeGJXSjlGakVMRXFCZ0hpUWl4MkxoOSt2U3htYnpxN3NPNG9CYVJ4VGgvL3J6czJyVkx5R1pWb29Da0N4TmNpTEFZakJwaHNGUVNKQ0l1RzllTkN3WndzbHhxa29ndmZsRzlNeDJaSy9VOWlLaTFUdm9rZWFHY0ZDYlVOVStjT0dFZjAwKy9mdjFzQmh4R1JPYlB2RWhDL2hRajBua21pL2czTUE0U0VVc1BGc1M5Yk1KNzkrNVpYSHdZRnlSR0JFeUtuQ1FFUzVjdU5iRU5nU3ZaS0VWTmdDYXQ3OTI3dCt6ZnYxK0tpNHVsVXFWS01uTGtTTm04ZWJOSlhvZ0J4NDhmYnpKb2RwQmFDTHRpdjkwVUU1MDVjNmFwemsrZlB0MEV2SXlCY01ReTRzYUxpb3FNTytTZWtnWUxRY0t5WU1FQzB4NVNEaG8wU01qZ29nb3hYTVdLRlUzU01IVG9VT01HcTFXcmxsYStDUFpMMlFVOE9CTERUcHc0MGVpTWpoUzB3WVpFaHFLOUZyTEpzaG1MakJzaFcyYlJOV3VPRTJNMkFtdE53b21lZkZUUUpKRFFnVENEMkpZUUIzY2RoakdZZ3ozUGM1VVUxMHhITEQ0a1ZFTFFNUzRvMTJ6VVYwZFVaZG5ORkVJcGRuUGtPaHZSOXlnRXMrZ0lDMG41UmkxYU52M2syd1pMZ0ZDeXdsTm9HU3RLdjh3bFdFZU04ajV0QzRFeC9lS2k4VURNQ3duREdESkQySHdraFloWVBYWXJ3VHJDSXZOMW9FdVhMdDR2QzlrTURMa3BXN2hmVnJKNUwyb2JZa1pmM0JpMW4zL1JIdGRMQXBTclJmbVhHRU5TUWhRbGE2NzRwUkFSZDRHSnJsNjl1c2xjK2J5R2kzSExGYmtNNVB2V25Fcy9ZZTlndllsZDFEcUd0U3VyOTdHSytxMDVWeDMvQmNiby9kZS9OUk12VU9keTAvaGNRZkc5VjhoL2hoRHdKLysrRVlrYlk2eWcxbnQ5YXg3bG5yV0lzRHY0ZVUwN0lvUDBGVGYxZVhKTUVNZ1hBVXRFT2lMZ3JGV3JWa3FGSEFKT25UcFZObXpZa085WXlmdi9Fd1JJM1BDc3ZtcEpHQVFwUkNUR29wVFJ2SGx6VTI0Z1J1UmZNc2VPSFF0N1A3bWZJSkNHUU41RTFCNUoyK21NWXlJSkFuRWdrR0lSNHhnd0dTTkJ3SWRBUWtRZktzbTkyQkZJaUJnNzVNbUFQZ1FTSXZwUVNlN0Zqc0IvSXl0eFFCRmpKS29BQUFBQVNVVk9SSzVDWUlJPSkKCiAgICAtICAgKipMw61taXRlIHN1cGVyaW9yOioqCgogICAgICAgICFbXShkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUowQUFBQWpDQVlBQUFDTzVnalRBQUFIdVVsRVFWUjRBZTJheVdzVlFSREcvUWMwZUZHU2d5ZEZSQ1FoTGdkQlFjVzRCSTBHQlZkY3dDMWlZb2hlOUtUQmdKcW9jVGtJZWhCRVhGRVBMcWdJaWlpQ1lsUVV4WDFmY0Y5eHdaSmZZdzA5azNtK21ieThTUjUwUWRJelBUM1YxVjkvWFYzVjh6cUlFNGRBd2doMFNMZy8xNTFEUUJ6cEhBa1NSOENSTG5ISVhZZU9kSTREaVNQZ1NKYzQ1SzVEUnpySGdjUVJjS1JMSEhMWFlXS2tlL255cGR5K2ZUc3JpSjg5ZTFhK2Z2MmFGZDFKS2YzNDhhTTBOVFZsMUYzU0dOKzVjMGZ1M3IwYjIrWllwTHQ2OWFvc1dyUklxcXVyNWZYcjE1RTdlL3o0c1N4ZXZGZ0FWdVgzNzk5eTRNQUJHVHQyck15Yk4wOG1USmdnNTg2ZGt6OS8vcGdtang0OWtxVkxsNXIrNkZQNzNiMTd0N3g5KzFiVmVHM1hybDByUDMvKzlOWEh2YmwvLzc0c1diTEUxNmYyZmZyMDZXYnE2Ry9UcGsxU1VsSWk0OGVQbC8zNzk4djY5ZXZseVpNbnNtSERobEE5NkdOY2pFOEZYTUFIbkhJSlk4YS9aczBhWTdlT0pVb1ppM1FRNHVUSms5S3ZYejk1OGVKRkZQM3k2OWN2V2Jac21WeThlTkZyajFlYU8zZXUxTlhWZVVUNTl1MmJtU1RhS25rb1o4eVlJZVBHalJPZWYvandRWTRkT3lZOWUvYVV3NGNQZS9xNDJMNTl1L256VlZvMzJQN2p4dytycHZubDFxMWJaZVRJa1hMdDJqWDUvdjI3c1FPU2pCa3p4cmRnOU0yTkd6ZEtRME9EV1Nqb2gzUkZSVVh5L1BsenN6QjI3ZG9sWGJwMGtWT25UaG04d0F6ZHc0WU5rNk5IajZvYVExemVSWElONDVzM2I4ckNoUXZOL0hnRFNuTVJpM1RvdW5MbGlnd2NPREF5Nlc3Y3VDR3paOC8yR2NWa0RSa3lwSm5Id2tNd2FYZ3pGY2pKbnkzYzkrL2ZYOTY4ZWVOVlAzdjJUQ1pPbk9pcjh4NktHSHYzN3QxclYvbXVJZG55NWNzOUQ4N2s0N1g2OXUwYnVwSy9mUGxpK3J0OCtiS25oenBzMHdVSnNTQWRtTmx5L3Z4NWdaRElxMWV2Wk5xMGFhYlVOcm1FTVRpeE1NTjJBaDFQc015WWRIZ2Z3R2E3Wk10bDhteGgrMW0zYnAxWEJWRWd6SW9WSzd3NnZXQUFFSFRVcUZGR0ovVlJTWWRIblRWclZzckJRNFQva2U3cDA2ZXliOTgrWTRwTnVIdjM3cWw1dmhKdmpRY01ybkk4TUpnZ1FkSVJlMElvYkNHMFFFNmNPQ0VMRml6d3dncnFncVJyN3hqdjJiUEhoQ1ZtUUJIK1pVUTZ0clR1M2J1YmxicDY5V3JadVhPbkRCbzB5QXVJbFVUMlZnS2dySDZiaUxhZHhHYm9mUERnZ2FtMlNjZDJlL3o0Y1Nrc0xEU1RaYi9ITmU5QzhqQkpSenI3blVPSERoa2JMbDI2WkZjM3U2WmRYbDZlK1NzdExUV2tKZ3hRVWRLeHZlTHg1OHlaMDh6cllYTVFDNXQwdVlBeDNuN0tsQ21SazdtTVNBZTRBS1l4Ri9lUVJFSEVBMDZhTk1rSGRCVFM1ZWZubTloSDlZMFlNVUlPSGp4b1NOVzdkMi9qSlNCMFVPZzN6SVBTTGlycElCcWtoMUJCZ1ZEWHIxODNYcDFuMkVEeXcvYll0V3RYNmRpeG8weWRPdFVMSlNCZDU4NmREUjU0ZzlHalIvdXdRQWQ0Mll1U09wdDAzTGQzakxHWGhQRDkrL2VZbTFaYWhYUUFwNUtPZEhnd0pwVVZIaWE4MzZkUEh5L0c0ZDdXZitiTUdaTkk0RG1Dd3VScDJ3c1hMcGh0bXEyYXY2RkRoNXA0VWU4cEt5c3I1ZlBuejU0YUpSd2VXMG05YmRzMkw2WkRQOFFpbWVLNWZVekRQY2tBQzRhWURhRzlIZE1SOXpCQnlJNGRPK1RUcDArUlNhZmo0bDJ1Lzdld2s4TFlET1RmZ2daUEZuWVVTWngwR252WjNsRU5aYVVNSGp4WWFtcHF2RWtIWUJ0dzlaUjRqcUJrNHVrNHJpQnBJSGxRd2hIazR6bXhHYkU5SFY2Y2JGZmI4aHdDYzN5aW5pdElPcldYZG9RanhMK01UZHZyOHpCUFoyUEE5ZjlJbHpUR3JlYnBBSVRBRjBEc2M3RTRnREFoSkFaQlVOV2pCTGN3c3RaZ3RnakFOdUFjT2VCTmxBeWs3Q1F4U0V0ak9zN0pTQXJJd3ZTNEJvS3RYTGt5NVRFTXBHTnNkcUlCVG1WbFpTWit3NTVVcEdQY1pNcHFzeExJVktUWVhtME1iTksxQjR3emp1bllNamdnNVZpRUxZRFVmdmp3NGNMa2NuREpTaVpPWVd2YXZIbXo5T3JWeTJ5WFc3WnNrZnI2ZW5OZFhGeHMzZ1ZFQUEyQ1NqMkc0dFZXclZwbEVvL2EybG9oR05kRFUwbzhIbHR4UVVHQlZGVlZtV2VRQW5KZ0g1bGZZMk9qbVN0V040RzZibTA2Z1ZxbWl1bFlYTk9uVHpkam1qbHpwaUU0OWhPamRldldUVzdkdXFVcWZDV2tZL0tKNXpnZ0plWWtld1lUQ012aDhJQUJBNlJUcDA0eWVmSmtZek4yTTJhMmFFMTRqaHc1NHN0ZWN4RmpkcDFVc2JRUHRIODN2dTBWSU12THk0WEEzZjU2d09RendTMlJzSE02MWNNcTVaaUZnMk5LZTZ2U05tR2x2c2RuSS9WTW5OTXg2YmJkOXJ1cFNHZTNpWE1OeWRWbVBCejZPZHFJSzJIbmRIRjF0Q1hHekFYOHNBLy8wOW52SXgxQk15dFR6NnZ3QW5nNjB1RlVrNW11QXlhSHp6NXhqRXFuTSt3NXF5MHN6dE8yZ0pQdWk0UzJUYnJFS3lybUxlbTdMVEVtdkdCK2RmRkhzZDhqblI1MjR2cDc5T2doYkRFVkZSVm0yMkM3eUVUQ3ZyMW1vaS80TGxzeDhWeWNnUWQxdE9VOUMxcS92YmJVanJiQUdMd3ordmFxWHdwSWZkbG1XMXV5K1FzSTRrUDcrS0sxYlU5Q0g4UnJ6Nzh5Q2NNWW9qOTgrREEyUEo2bjAzVGZ6cEpVRzR4dXIxdVQydWpLM0VIQUl4MG04NnNQc2l2N1pQbmR1M2N5Zi83OGxGbGg3Z3pWV1pvVUFpUlZuR3FFblZwZ2c0OTB1SGd5UUg3ZVEzclBKeXcrM2ZCalBTY09nYWdJeENLZEtpWDE1MFd5VnljT2dkWkd3T2ZwV2x1NTArY1FDRVBBa1M0TUZWZVhWUVFjNmJJS3IxTWVob0FqWFJncXJpNnJDRGpTWlJWZXB6d01BVWU2TUZSY1hWWVJjS1RMS3J4T2VSZ0NqblJocUxpNnJDTHdGMUFtWG9wVE1oQldBQUFBQUVsRlRrU3VRbUNDKQoKICAgIC0gICAKCiMjIyAqKkludGVycHJldGFjacOzbiBkZWwgUmVzdWx0YWRvKioKCi0gICBFbCByZXN1bHRhZG8gZGUgUj0xLjMzIGNvbiB1biBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGFsIDk1JSAoQzk1JTogMC43NiAtIDIuMzIpIHB1ZWRlIGludGVycHJldGFyc2UgZGUgbGEgc2lndWllbnRlIG1hbmVyYToKCiAgICAjIyMgKioxLiBWYWxvciBkZWwgT2RkcyBSYXRpbyAoT1IpKioKCiAgICAtICAgT1I9MS4zMyAoT1I9XD4xKQoKICAgICAgICAtICAgSW5kaWNhIHF1ZSBsYXMgcGVyc29uYXMgY29uIGRpYWJldGVzIHRpZW5lbiAxLjMzIHZlY2VzIG3DoXMgcHJvYmFiaWxpZGFkZXMgZGUgdGVuZXIgaGlwZXJ0ZW5zacOzbiBlbiBjb21wYXJhY2nDs24gY29uIGxhcyBwZXJzb25hcyBzaW4gZGlhYmV0ZXMuCgogICAgICAgIC0gICBTaW4gZW1iYXJnbywgZXN0ZSB2YWxvciBkZWJlIGV2YWx1YXJzZSBqdW50byBjb24gZWwgaW50ZXJ2YWxvIGRlIGNvbmZpYW56YSBwYXJhIGRldGVybWluYXIgc2kgbGEgYXNvY2lhY2nDs24gZXMgZXN0YWTDrXN0aWNhbWVudGUgc2lnbmlmaWNhdGl2YS4KCiAgICAjIyMgKioyLiBJbnRlcnZhbG8gZGUgQ29uZmlhbnphIGFsIDk1JSAoSUM5NSUpKioKCiAgICAtICAgSUM5NSU9WzAuNzYsIDIuMzJdOgoKICAgICAgICAtICAgRXN0ZSBpbnRlcnZhbG8gc2lnbmlmaWNhIHF1ZSwgY29uIHVuIDk1JSBkZSBjb25maWFuemEsIGVsIHZlcmRhZGVybyBPZGRzIFJhdGlvIHBvZHLDrWEgZXN0YXIgZW50cmUgMC43NiB5IDIuMzIuCgogICAgICAgIC0gICBJbmNsdXllIGVsIHZhbG9ywqAqKjEqKiwgbG8gcXVlIGltcGxpY2EgcXVlwqAqKmxhIGFzb2NpYWNpw7NuIG5vIGVzIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmEqKihlcyBwb3NpYmxlIHF1ZSBubyBoYXlhIGRpZmVyZW5jaWEgcmVhbCBlbiBsYXMgcHJvYmFiaWxpZGFkZXMgZGUgaGlwZXJ0ZW5zacOzbiBlbnRyZSBwZXJzb25hcyBjb24geSBzaW4gZGlhYmV0ZXMpLgoKKipJbnRlcnByZXRhY2nDs24gUHLDoWN0aWNhKio6CgotICAgRXhpc3RlIHVuYSBwb3NpYmxlIGFzb2NpYWNpw7NuIHBvc2l0aXZhIGVudHJlIGRpYWJldGVzIGUgaGlwZXJ0ZW5zacOzbiAoT1I9MS4zMyksIHBlcm8gZXN0YSBhc29jaWFjacOzbiBubyBlcyBlc3RhZMOtc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZhIHNlZ8O6biBlbCBJQzk1JT1bMC43NiwgMi4zMl0uCgotICAgTcOhcyBkYXRvcyBvIGVzdHVkaW9zIGFkaWNpb25hbGVzIHNlcsOtYW4gbmVjZXNhcmlvcyBwYXJhIGNvbmZpcm1hciBlc3RhIHJlbGFjacOzbi4KCmBgYHtyfQpucm93KGRhdG9zKQpgYGAK