El bajo peso al nacer, definido como por un peso al nacer inferior a 2500 gr., ha sido una preocupación de los médicos durante años debido a que tanto las tasas de mortalidad como la de nacimientos defectuosos son muy altas para los niños con bajo peso al nacer. El comportamiento de la mujer durante el embarazo (incluyendo la dieta, los hábitos tabáquicos y los cuidados prenatales) pueden alterar las chances de un parto de un niño con bajo peso. Los datos que se presentan en este ejercicio corresponden a 189 nacimientos de los cuales 59 han resultado en niños con bajo peso. El objetivo de este ejercicio es determinar cuáles de las variables presentes en la base de datos que se adjunta son factores de riesgo de bajo peso al nacer.

library(RJSONIO)
library(epiR)
library(haven)
library(dplyr)

Levanto data

base_nacimientos <- read_sav("./LOWBWT.sav")%>%
  mutate(
    LOW= as.factor(LOW),
    RACE= as.factor(RACE),
    SMOKE= as.factor(SMOKE),
    PTL= as.factor(PTL),
    HT= as.factor(HT),
    UI= as.factor(UI),
    FTV= as.factor(FTV)
  )
# Función para calcular RR y OR
calculate_rr_or <- function(data, exposure_col) {
  
  # Expuestos
  exposed <- filter(data, !!sym(exposure_col) == 1)
  risk_exposed <- sum(exposed$LOW == 1) / nrow(exposed)
  
  # No expuestos
  non_exposed <- filter(data, !!sym(exposure_col) == 0)
  risk_non_exposed <- sum(non_exposed$LOW == 1) / nrow(non_exposed)
  
  # Riesgo Relativo
  RR <- risk_exposed / risk_non_exposed
  
  # Odds Ratio
  odds_exposed <- risk_exposed / (1 - risk_exposed)
  odds_non_exposed <- risk_non_exposed / (1 - risk_non_exposed)
  OR <- odds_exposed / odds_non_exposed
  
  return(list("Riesgo Relativo" = RR, "Odds Ratio" = OR))
}

# Variables dicotómicas a analizar
variables_dicotomicas <- c("SMOKE", "HT", "UI")
results <- data.frame()

for (var in variables_dicotomicas) {
  result <- calculate_rr_or(base_nacimientos, var)
  results <- rbind(results, data.frame(Variable = var, RR = result[["Riesgo Relativo"]], OR = result[["Odds Ratio"]]))
}

print(results)
##   Variable       RR       OR
## 1    SMOKE 1.607642 2.021944
## 2       HT 1.985577 3.365385
## 3       UI 1.788889 2.577778

-Calcular el riesgo relativo y los odds ratio de la variable dependiente con cada una las variables dicotómicas. Analizar los resultados.

SMOKE: las madres que fumaron durante el embarazo tienen un riesgo 1.6 veces mayor de tener un hijo con bajo peso al nacer en comparación con las madres que no fumaron. El odds ratio de 2.02 indica que las madres que fumaron durante el embarazo tienen más del doble de probabilidades de tener un hijo con bajo peso al nacer en comparación con las que no fumaron.

HT: las madres con antecedentes de hipertensión arterial tienen un riesgo casi 2 veces mayor de tener un hijo con bajo peso al nacer en comparación con las madres sin antecedentes de hipertensión. El odds ratio de 3.37 indica que las madres con antecedentes de hipertensión tienen más del triple de probabilidades de tener un hijo con bajo peso al nacer.

UI: las madres con irritabilidad uterina tienen un riesgo 1.79 veces mayor de tener un hijo con bajo peso al nacer en comparación con las madres sin irritabilidad uterina. El odds ratio de 2.58 indica que las madres con irritabilidad uterina tienen más de 2.5 veces más probabilidades de tener un hijo con bajo peso al nacer.

Cuál es la definición de odds ratio? Qué información suministra y de qué manera puede calcularse utilizando la regresión logística?

Odds Ratio (OR)

El Odds Ratio (OR) es una medida de asociación que indica cuánto más (o menos) probable es un evento dado la presencia (o ausencia) de cierta condición. Información que suministra: El OR suministra una comparación de las odds (probabilidades) de un evento entre dos grupos. Un OR de: - 1 sugiere que la condición no afecta la probabilidad del evento. - > 1 indica que la condición aumenta la probabilidad del evento. - < 1 indica que la condición disminuye la probabilidad del evento.

En la regresión logística, el exponente del coeficiente de una variable (exp(coeficiente)) es el OR asociado con un incremento de una unidad en esa variable, manteniendo constantes las demás variables.

Calculo de los Odds ratio de cada una de las variables predictoras disponibles con la variable dependiente? Comentar

modelo_logit <- glm(LOW ~ AGE + LWT + RACE + SMOKE + PTL + HT + UI + FTV, 
                   family = binomial(link = "logit"), data = base_nacimientos)

# Calcular los odds ratio
odds_ratio <- exp(coef(modelo_logit))

# Mostrar los odds ratio
print(odds_ratio)
##  (Intercept)          AGE          LWT        RACE2        RACE3       SMOKE1 
## 2.456198e+00 9.618513e-01 9.847621e-01 3.035773e+00 1.953761e+00 2.028524e+00 
##         PTL1         PTL2         PTL3          HT1          UI1         FTV1 
## 6.456179e+00 1.628221e+00 1.793530e-07 6.078369e+00 2.210117e+00 5.712966e-01 
##         FTV2         FTV3         FTV4         FTV6 
## 9.218192e-01 3.013492e+00 3.975350e-01 2.463609e-06
  1. AGE (Edad de la madre): OR = 0.9618: Por cada año adicional en la edad de la madre, las odds de tener un bebé con bajo peso disminuyen aproximadamente en un 3.82% (100 * (1 - 0.9618)), manteniendo constantes las otras variables.
  2. LWT (Peso de la madre al inicio del embarazo): OR = 0.9848: Por cada libra adicional en el peso de la madre al inicio del embarazo, las odds de tener un bebé con bajo peso disminuyen aproximadamente en un 1.52% (100 * (1 - 0.9848)), manteniendo todo lo demás constante.
  3. RACE2 (Raza Black): OR = 3.0358: Si la madre es de raza negra tiene aproximadamente 3.03 veces las odds de tener un bebé con bajo peso comparado con una madre de raza blanca, manteniendo constantes las otras variables.
  4. RACE3 (Raza Other): OR = 1.9538: Si la madre pertenece a otra raza diferente a blanca o negra tiene aproximadamente 1.95 veces las odds de tener un bebé con bajo peso comparado con una madre de raza blanca, manteniendo constantes las otras variables.
  5. SMOKE1 (Fumó durante el embarazo): OR = 2.0285: Las madres que fumaron durante el embarazo tienen aproximadamente 2.03 veces las odds de tener un bebé con bajo peso comparado con aquellas que no fumaron, manteniendo todo lo demás constante.
  6. PTL1 (Un embarazo prematuro anterior): OR = 6.4562: Las madres con un antecedente de embarazo prematuro tienen aproximadamente 6.46 veces las odds de tener un bebé con bajo peso, comparado con las madres sin dicho antecedente, manteniendo constantes las otras variables.

Los OR nos proporcionan una forma cuantitativa de determinar cuánto más probable es un evento en un grupo en comparación con otro. En el contexto de este estudio, estos OR proporcionan una medida del riesgo relativo de tener un bebé con bajo peso dado diferentes factores.

-Realizaré una regresión logística múltiple, seleccionando los mejores predictores entre las variables independientes disponibles, utilizando un método de selección automática.

modelo_completo <- glm(LOW ~ AGE + LWT + RACE + SMOKE + PTL + HT + UI + FTV, 
                       data = base_nacimientos, family = binomial)


modelo_optimizado <- step(modelo_completo, direction = "both")
## Start:  AIC=220.6
## LOW ~ AGE + LWT + RACE + SMOKE + PTL + HT + UI + FTV
## 
##         Df Deviance    AIC
## - FTV    5   192.45 214.45
## - AGE    1   189.58 219.58
## <none>       188.60 220.60
## - SMOKE  1   191.20 221.20
## - RACE   2   193.23 221.23
## - UI     1   191.32 221.32
## - LWT    1   193.13 223.13
## - HT     1   194.72 224.72
## - PTL    3   202.21 228.21
## 
## Step:  AIC=214.45
## LOW ~ AGE + LWT + RACE + SMOKE + PTL + HT + UI
## 
##         Df Deviance    AIC
## - AGE    1   193.59 213.59
## <none>       192.45 214.45
## - UI     1   195.67 215.67
## - RACE   2   197.91 215.91
## - SMOKE  1   196.91 216.91
## - LWT    1   198.05 218.05
## - HT     1   199.64 219.64
## - PTL    3   203.95 219.95
## + FTV    5   188.60 220.60
## 
## Step:  AIC=213.59
## LOW ~ LWT + RACE + SMOKE + PTL + HT + UI
## 
##         Df Deviance    AIC
## <none>       193.59 213.59
## + AGE    1   192.45 214.45
## - UI     1   197.17 215.17
## - RACE   2   200.27 216.27
## - SMOKE  1   198.40 216.40
## - PTL    3   204.22 218.22
## - LWT    1   200.29 218.29
## - HT     1   200.94 218.94
## + FTV    5   189.58 219.58
summary(modelo_optimizado)
## 
## Call:
## glm(formula = LOW ~ LWT + RACE + SMOKE + PTL + HT + UI, family = binomial, 
##     data = base_nacimientos)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -1.8644  -0.7707  -0.5171   0.9271   2.2084  
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)   
## (Intercept)   0.030369   0.986202   0.031  0.97543   
## LWT          -0.017173   0.007121  -2.412  0.01588 * 
## RACE2         1.248872   0.535197   2.333  0.01962 * 
## RACE3         0.796707   0.447359   1.781  0.07493 . 
## SMOKE1        0.885373   0.409389   2.163  0.03057 * 
## PTL1          1.457868   0.507406   2.873  0.00406 **
## PTL2          0.273850   0.980762   0.279  0.78007   
## PTL3        -14.744564 882.743533  -0.017  0.98667   
## HT1           1.898206   0.717535   2.645  0.00816 **
## UI1           0.894205   0.469649   1.904  0.05691 . 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 234.67  on 188  degrees of freedom
## Residual deviance: 193.59  on 179  degrees of freedom
## AIC: 213.59
## 
## Number of Fisher Scoring iterations: 13

A partir de la regresión logística múltiple realizada sobre las variables, se obtuvieron los siguientes resultados:

  1. La variable LWT tiene un coeficiente negativo, lo que sugiere que a medida que aumenta el peso de la madre en el último periodo menstrual, disminuye el log-odds de tener un bebé con bajo peso al nacer.
  2. RACE2 y RACE3 indican que, en comparación con la raza de referencia (White), ser de raza Black o Other aumenta el log-odds de tener un bebé con bajo peso al nacer.
  3. Fumar durante el embarazo (SMOKE1) aumenta el log-odds de tener un bebé con bajo peso al nacer.
  4. Tener antecedentes de embarazos prematuros (PTL1) también aumenta el riesgo.
  5. Tener antecedentes de hipertensión arterial (HT1) aumenta considerablemente el log-odds de dar a luz a un bebé con bajo peso.
  6. Es importante notar que PTL3 no es significativo y tiene un error estándar muy grande, lo que sugiere que es posible que no haya suficientes datos para hacer una estimación precisa para esa categoría.

-Según el modelo obtenido, cabe preguntarse cuáles son los principales factores de riesgo del bajo peso y cuál es la magnitud de su efecto?

Basándonos en la significancia estadística y los coeficientes, los principales factores de riesgo para el bajo peso al nacer y la magnitud de su efecto son los siguientes:

Coeficiente (Estimación) para Antecedentes de embarazos prematuros (PTL1): 1.457868. Tener un antecedente de embarazo prematuro (PTL1) aumenta considerablemente el log-odds (logaritmo de las odds) de dar a luz a un bebé con bajo peso al nacer. En términos de odds, se puede decir que las odds de tener un bebé con bajo peso al nacer son aproximadamente exp(1.457868) ≈ 4.29 veces mayores para las madres con un antecedente de embarazo prematuro en comparación con aquellas que no tienen antecedentes.

Coeficiente (Estimación) para Antecedentes de hipertensión arterial (HT1): 1.898206. Tener antecedentes de hipertensión arterial incrementa significativamente el log-odds de tener un bebé con bajo peso al nacer. Las odds de tener un bebé con bajo peso para madres con antecedentes de hipertensión son aproximadamente exp(1.898206) ≈ 6.68 veces mayores en comparación con madres sin tales antecedentes.

Coeficiente (Estimación) para Raza (RACE2): 1.248872. Las madres de raza negra (en comparación con las de raza blanca, que es la categoría de referencia) tienen un mayor log-odds de dar a luz a un bebé con bajo peso. Las odds son aproximadamente exp(1.248872) ≈ 3.49 veces mayores para las madres de raza negra.

Coeficiente (Estimación) para Fumó durante el embarazo (SMOKE1): 0.885373. Fumar durante el embarazo también aumenta el log-odds de tener un bebé con bajo peso al nacer. Las odds de tener un bebé con bajo peso para madres fumadoras durante el embarazo son aproximadamente exp(0.885373) ≈ 2.42 veces mayores en comparación con las no fumadoras.

Coeficiente (Estimación) para Peso de la madre en el último periodo menstrual (LWT): -0.017173. Aunque el efecto es más sutil que los otros factores mencionados, un aumento en el peso de la madre disminuye el log-odds de tener un bebé con bajo peso al nacer. Esto sugiere que un mayor peso al final del ciclo menstrual puede estar asociado con un menor riesgo de bajo peso al nacer.

Cuáles son los supuestos necesarios para definir la prueba inferencial de los estimadores de los parámetros?

Supuestos para la Prueba Inferencial de los Estimadores de los Parámetros

Para llevar a cabo pruebas inferenciales en el contexto de regresión logística es necesario que se cumplan ciertos supuestos. Estos supuestos aseguran que las pruebas y estimaciones son válidas. A continuación se describen los principales supuestos:

  1. Linealidad: La relación entre las variables independientes y la variable dependiente debe ser lineal. En el caso de la regresión logística, la relación es entre las variables independientes y el logaritmo de odds de la variable dependiente.
  2. Independencia: Las observaciones deben ser independientes entre sí. Esto generalmente se satisface con un diseño de muestreo adecuado.
  3. Ausencia de multicolinealidad: Las variables independientes no deben estar altamente correlacionadas entre sí. Esto porque la multicolinealidad puede hacer que los estimadores no sean únicos y por lo tanto los p-values asociados pueden no ser válidos.
  4. Ausencia de valores extremos: Los valores extremos o atípicos pueden afectar significativamente los estimadores y las pruebas inferenciales. Es fundamental verificar y, si es necesario, tratar estos valores antes del análisis.
  5. Especificación correcta del modelo: El modelo debe estar especificado correctamente, es decir, debe incluir todas las variables relevantes y no incluir variables irrelevantes.

Al no cumplirse estos supuestos, las pruebas inferenciales pueden no ser válidas y podríamos llegar a conclusiones incorrectas sobre la relación entre las variables independientes y la dependiente.

Porcentaje de casos bien predichos por el modelo.

# Calcular porcentaje de casos bien predichos
predichos <- ifelse(predict(modelo_optimizado, type = "response") > 0.5, 1, 0)
tabla <- table(base_nacimientos$LOW, predichos)
accuracy <- sum(diag(tabla)) / sum(tabla) * 100
print(paste("Porcentaje de casos bien predichos:", accuracy))
## [1] "Porcentaje de casos bien predichos: 75.6613756613757"
LS0tDQp0aXRsZTogIkJpcnRoOiByaXNrIGZhY3RvcnMiDQphdXRob3I6ICJMdWlzZWxsaSBMdWNhcyINCmRhdGU6ICIyMDIzLTExLTE4Ig0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0aGVtZTogImNvc21vIg0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KICAgIG51bWJlci1zZWN0aW9uczogVFJVRQ0KICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUNCmVkaXRvcl9vcHRpb25zOiANCiAgbWFya2Rvd246IA0KICAgIHdyYXA6IDcyDQotLS0NCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KHdhcm5pbmcgPSBGLCBtZXNzYWdlID0gRikNCmBgYA0KDQpFbCBiYWpvIHBlc28gYWwgbmFjZXIsIGRlZmluaWRvIGNvbW8gcG9yIHVuIHBlc28gYWwgbmFjZXIgaW5mZXJpb3IgYSAyNTAwIGdyLiwgaGEgc2lkbyB1bmEgcHJlb2N1cGFjacOzbg0KZGUgbG9zIG3DqWRpY29zIGR1cmFudGUgYcOxb3MgZGViaWRvIGEgcXVlIHRhbnRvIGxhcyB0YXNhcyBkZSBtb3J0YWxpZGFkIGNvbW8gbGEgZGUgbmFjaW1pZW50b3MNCmRlZmVjdHVvc29zIHNvbiBtdXkgYWx0YXMgcGFyYSBsb3MgbmnDsW9zIGNvbiBiYWpvIHBlc28gYWwgbmFjZXIuIEVsIGNvbXBvcnRhbWllbnRvIGRlIGxhIG11amVyIGR1cmFudGUNCmVsIGVtYmFyYXpvIChpbmNsdXllbmRvIGxhIGRpZXRhLCBsb3MgaMOhYml0b3MgdGFiw6FxdWljb3MgeSBsb3MgY3VpZGFkb3MgcHJlbmF0YWxlcykgcHVlZGVuIGFsdGVyYXIgbGFzDQpjaGFuY2VzIGRlIHVuIHBhcnRvIGRlIHVuIG5pw7FvIGNvbiBiYWpvIHBlc28uDQpMb3MgZGF0b3MgcXVlIHNlIHByZXNlbnRhbiBlbiBlc3RlIGVqZXJjaWNpbyBjb3JyZXNwb25kZW4gYSAxODkgbmFjaW1pZW50b3MgZGUgbG9zIGN1YWxlcyA1OSBoYW4NCnJlc3VsdGFkbyBlbiBuacOxb3MgY29uIGJham8gcGVzby4gRWwgb2JqZXRpdm8gZGUgZXN0ZSBlamVyY2ljaW8gZXMgZGV0ZXJtaW5hciBjdcOhbGVzIGRlIGxhcyB2YXJpYWJsZXMNCnByZXNlbnRlcyBlbiBsYSBiYXNlIGRlIGRhdG9zIHF1ZSBzZSBhZGp1bnRhIHNvbiBmYWN0b3JlcyBkZSByaWVzZ28gZGUgYmFqbyBwZXNvIGFsIG5hY2VyLg0KDQpgYGB7cn0NCmxpYnJhcnkoUkpTT05JTykNCmxpYnJhcnkoZXBpUikNCmxpYnJhcnkoaGF2ZW4pDQpsaWJyYXJ5KGRwbHlyKQ0KYGBgDQoNCkxldmFudG8gZGF0YQ0KDQpgYGB7cn0NCmJhc2VfbmFjaW1pZW50b3MgPC0gcmVhZF9zYXYoIi4vTE9XQldULnNhdiIpJT4lDQogIG11dGF0ZSgNCiAgICBMT1c9IGFzLmZhY3RvcihMT1cpLA0KICAgIFJBQ0U9IGFzLmZhY3RvcihSQUNFKSwNCiAgICBTTU9LRT0gYXMuZmFjdG9yKFNNT0tFKSwNCiAgICBQVEw9IGFzLmZhY3RvcihQVEwpLA0KICAgIEhUPSBhcy5mYWN0b3IoSFQpLA0KICAgIFVJPSBhcy5mYWN0b3IoVUkpLA0KICAgIEZUVj0gYXMuZmFjdG9yKEZUVikNCiAgKQ0KDQpgYGANCg0KYGBge3J9DQojIEZ1bmNpw7NuIHBhcmEgY2FsY3VsYXIgUlIgeSBPUg0KY2FsY3VsYXRlX3JyX29yIDwtIGZ1bmN0aW9uKGRhdGEsIGV4cG9zdXJlX2NvbCkgew0KICANCiAgIyBFeHB1ZXN0b3MNCiAgZXhwb3NlZCA8LSBmaWx0ZXIoZGF0YSwgISFzeW0oZXhwb3N1cmVfY29sKSA9PSAxKQ0KICByaXNrX2V4cG9zZWQgPC0gc3VtKGV4cG9zZWQkTE9XID09IDEpIC8gbnJvdyhleHBvc2VkKQ0KICANCiAgIyBObyBleHB1ZXN0b3MNCiAgbm9uX2V4cG9zZWQgPC0gZmlsdGVyKGRhdGEsICEhc3ltKGV4cG9zdXJlX2NvbCkgPT0gMCkNCiAgcmlza19ub25fZXhwb3NlZCA8LSBzdW0obm9uX2V4cG9zZWQkTE9XID09IDEpIC8gbnJvdyhub25fZXhwb3NlZCkNCiAgDQogICMgUmllc2dvIFJlbGF0aXZvDQogIFJSIDwtIHJpc2tfZXhwb3NlZCAvIHJpc2tfbm9uX2V4cG9zZWQNCiAgDQogICMgT2RkcyBSYXRpbw0KICBvZGRzX2V4cG9zZWQgPC0gcmlza19leHBvc2VkIC8gKDEgLSByaXNrX2V4cG9zZWQpDQogIG9kZHNfbm9uX2V4cG9zZWQgPC0gcmlza19ub25fZXhwb3NlZCAvICgxIC0gcmlza19ub25fZXhwb3NlZCkNCiAgT1IgPC0gb2Rkc19leHBvc2VkIC8gb2Rkc19ub25fZXhwb3NlZA0KICANCiAgcmV0dXJuKGxpc3QoIlJpZXNnbyBSZWxhdGl2byIgPSBSUiwgIk9kZHMgUmF0aW8iID0gT1IpKQ0KfQ0KDQojIFZhcmlhYmxlcyBkaWNvdMOzbWljYXMgYSBhbmFsaXphcg0KdmFyaWFibGVzX2RpY290b21pY2FzIDwtIGMoIlNNT0tFIiwgIkhUIiwgIlVJIikNCnJlc3VsdHMgPC0gZGF0YS5mcmFtZSgpDQoNCmZvciAodmFyIGluIHZhcmlhYmxlc19kaWNvdG9taWNhcykgew0KICByZXN1bHQgPC0gY2FsY3VsYXRlX3JyX29yKGJhc2VfbmFjaW1pZW50b3MsIHZhcikNCiAgcmVzdWx0cyA8LSByYmluZChyZXN1bHRzLCBkYXRhLmZyYW1lKFZhcmlhYmxlID0gdmFyLCBSUiA9IHJlc3VsdFtbIlJpZXNnbyBSZWxhdGl2byJdXSwgT1IgPSByZXN1bHRbWyJPZGRzIFJhdGlvIl1dKSkNCn0NCg0KcHJpbnQocmVzdWx0cykNCmBgYA0KDQotQ2FsY3VsYXIgZWwgcmllc2dvIHJlbGF0aXZvIHkgbG9zIG9kZHMgcmF0aW8gZGUgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUgY29uIGNhZGEgdW5hIGxhcyB2YXJpYWJsZXMgZGljb3TDs21pY2FzLiBBbmFsaXphciBsb3MgcmVzdWx0YWRvcy4NCg0KKipTTU9LRSoqOiBsYXMgbWFkcmVzIHF1ZSBmdW1hcm9uIGR1cmFudGUgZWwgZW1iYXJhem8gdGllbmVuIHVuIHJpZXNnbw0KKioxLjYgdmVjZXMqKiBtYXlvciBkZSB0ZW5lciB1biBoaWpvIGNvbiBiYWpvIHBlc28gYWwgbmFjZXIgZW4NCmNvbXBhcmFjacOzbiBjb24gbGFzIG1hZHJlcyBxdWUgbm8gZnVtYXJvbi4gRWwgb2RkcyByYXRpbyBkZSAqKjIuMDIqKg0KaW5kaWNhIHF1ZSBsYXMgbWFkcmVzIHF1ZSBmdW1hcm9uIGR1cmFudGUgZWwgZW1iYXJhem8gdGllbmVuIG3DoXMgZGVsDQpkb2JsZSBkZSBwcm9iYWJpbGlkYWRlcyBkZSB0ZW5lciB1biBoaWpvIGNvbiBiYWpvIHBlc28gYWwgbmFjZXIgZW4NCmNvbXBhcmFjacOzbiBjb24gbGFzIHF1ZSBubyBmdW1hcm9uLg0KDQoqKkhUKio6IGxhcyBtYWRyZXMgY29uIGFudGVjZWRlbnRlcyBkZSBoaXBlcnRlbnNpw7NuIGFydGVyaWFsIHRpZW5lbiB1bg0Kcmllc2dvIGNhc2kgKioyIHZlY2VzKiogbWF5b3IgZGUgdGVuZXIgdW4gaGlqbyBjb24gYmFqbyBwZXNvIGFsIG5hY2VyIGVuDQpjb21wYXJhY2nDs24gY29uIGxhcyBtYWRyZXMgc2luIGFudGVjZWRlbnRlcyBkZSBoaXBlcnRlbnNpw7NuLiBFbCBvZGRzDQpyYXRpbyBkZSAqKjMuMzcqKiBpbmRpY2EgcXVlIGxhcyBtYWRyZXMgY29uIGFudGVjZWRlbnRlcyBkZSBoaXBlcnRlbnNpw7NuDQp0aWVuZW4gbcOhcyBkZWwgdHJpcGxlIGRlIHByb2JhYmlsaWRhZGVzIGRlIHRlbmVyIHVuIGhpam8gY29uIGJham8gcGVzbw0KYWwgbmFjZXIuDQoNCioqVUkqKjogbGFzIG1hZHJlcyBjb24gaXJyaXRhYmlsaWRhZCB1dGVyaW5hIHRpZW5lbiB1biByaWVzZ28gKioxLjc5DQp2ZWNlcyoqIG1heW9yIGRlIHRlbmVyIHVuIGhpam8gY29uIGJham8gcGVzbyBhbCBuYWNlciBlbiBjb21wYXJhY2nDs24gY29uDQpsYXMgbWFkcmVzIHNpbiBpcnJpdGFiaWxpZGFkIHV0ZXJpbmEuIEVsIG9kZHMgcmF0aW8gZGUgKioyLjU4KiogaW5kaWNhDQpxdWUgbGFzIG1hZHJlcyBjb24gaXJyaXRhYmlsaWRhZCB1dGVyaW5hIHRpZW5lbiBtw6FzIGRlIDIuNSB2ZWNlcyBtw6FzDQpwcm9iYWJpbGlkYWRlcyBkZSB0ZW5lciB1biBoaWpvIGNvbiBiYWpvIHBlc28gYWwgbmFjZXIuDQoNCkN1w6FsIGVzIGxhIGRlZmluaWNpw7NuIGRlIG9kZHMgcmF0aW8/IFF1w6kgaW5mb3JtYWNpw7NuIHN1bWluaXN0cmEgeSBkZSBxdcOpIG1hbmVyYSBwdWVkZSBjYWxjdWxhcnNlIHV0aWxpemFuZG8gbGEgcmVncmVzacOzbiBsb2fDrXN0aWNhPw0KDQpPZGRzIFJhdGlvIChPUikNCg0KRWwgKipPZGRzIFJhdGlvIChPUikqKiBlcyB1bmEgbWVkaWRhIGRlIGFzb2NpYWNpw7NuIHF1ZSBpbmRpY2EgY3XDoW50byBtw6FzDQoobyBtZW5vcykgcHJvYmFibGUgZXMgdW4gZXZlbnRvIGRhZG8gbGEgcHJlc2VuY2lhIChvIGF1c2VuY2lhKSBkZSBjaWVydGENCmNvbmRpY2nDs24uIEluZm9ybWFjacOzbiBxdWUgc3VtaW5pc3RyYTogRWwgT1Igc3VtaW5pc3RyYSB1bmEgY29tcGFyYWNpw7NuDQpkZSBsYXMgb2RkcyAocHJvYmFiaWxpZGFkZXMpIGRlIHVuIGV2ZW50byBlbnRyZSBkb3MgZ3J1cG9zLiBVbiBPUiBkZTogLQ0KKioxKiogc3VnaWVyZSBxdWUgbGEgY29uZGljacOzbiBubyBhZmVjdGEgbGEgcHJvYmFiaWxpZGFkIGRlbCBldmVudG8uIC0NCioqXD4gMSoqIGluZGljYSBxdWUgbGEgY29uZGljacOzbiBhdW1lbnRhIGxhIHByb2JhYmlsaWRhZCBkZWwgZXZlbnRvLiAtDQoqKlw8IDEqKiBpbmRpY2EgcXVlIGxhIGNvbmRpY2nDs24gZGlzbWludXllIGxhIHByb2JhYmlsaWRhZCBkZWwgZXZlbnRvLg0KDQpFbiBsYSAqKnJlZ3Jlc2nDs24gbG9nw61zdGljYSoqLCBlbCBleHBvbmVudGUgZGVsIGNvZWZpY2llbnRlIGRlIHVuYQ0KdmFyaWFibGUgKGV4cChjb2VmaWNpZW50ZSkpIGVzIGVsIE9SIGFzb2NpYWRvIGNvbiB1biBpbmNyZW1lbnRvIGRlIHVuYQ0KdW5pZGFkIGVuIGVzYSB2YXJpYWJsZSwgbWFudGVuaWVuZG8gY29uc3RhbnRlcyBsYXMgZGVtw6FzIHZhcmlhYmxlcy4NCg0KDQpDYWxjdWxvIGRlIGxvcyBPZGRzIHJhdGlvIGRlIGNhZGEgdW5hIGRlIGxhcyB2YXJpYWJsZXMgcHJlZGljdG9yYXMgZGlzcG9uaWJsZXMgY29uIGxhIHZhcmlhYmxlIGRlcGVuZGllbnRlPyBDb21lbnRhcg0KDQpgYGB7cn0NCm1vZGVsb19sb2dpdCA8LSBnbG0oTE9XIH4gQUdFICsgTFdUICsgUkFDRSArIFNNT0tFICsgUFRMICsgSFQgKyBVSSArIEZUViwgDQogICAgICAgICAgICAgICAgICAgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICJsb2dpdCIpLCBkYXRhID0gYmFzZV9uYWNpbWllbnRvcykNCg0KIyBDYWxjdWxhciBsb3Mgb2RkcyByYXRpbw0Kb2Rkc19yYXRpbyA8LSBleHAoY29lZihtb2RlbG9fbG9naXQpKQ0KDQojIE1vc3RyYXIgbG9zIG9kZHMgcmF0aW8NCnByaW50KG9kZHNfcmF0aW8pDQpgYGANCg0KMS4gICoqQUdFIChFZGFkIGRlIGxhIG1hZHJlKToqKiAqKk9SID0gMC45NjE4Kio6IFBvciBjYWRhIGHDsW8gYWRpY2lvbmFsIGVuIGxhIGVkYWQgZGUgbGEgbWFkcmUsDQogICAgICAgIGxhcyBvZGRzIGRlIHRlbmVyIHVuIGJlYsOpIGNvbiBiYWpvIHBlc28gZGlzbWludXllbg0KICAgICAgICBhcHJveGltYWRhbWVudGUgZW4gdW4gMy44MiUgKDEwMCBcKiAoMSAtIDAuOTYxOCkpLCBtYW50ZW5pZW5kbw0KICAgICAgICBjb25zdGFudGVzIGxhcyBvdHJhcyB2YXJpYWJsZXMuDQoyLiAgKipMV1QgKFBlc28gZGUgbGEgbWFkcmUgYWwgaW5pY2lvIGRlbCBlbWJhcmF6byk6KiogKipPUiA9IDAuOTg0OCoqOiBQb3IgY2FkYSBsaWJyYSBhZGljaW9uYWwgZW4gZWwgcGVzbyBkZSBsYSBtYWRyZQ0KICAgICAgICBhbCBpbmljaW8gZGVsIGVtYmFyYXpvLCBsYXMgb2RkcyBkZSB0ZW5lciB1biBiZWLDqSBjb24gYmFqbyBwZXNvDQogICAgICAgIGRpc21pbnV5ZW4gYXByb3hpbWFkYW1lbnRlIGVuIHVuIDEuNTIlICgxMDAgXCogKDEgLSAwLjk4NDgpKSwNCiAgICAgICAgbWFudGVuaWVuZG8gdG9kbyBsbyBkZW3DoXMgY29uc3RhbnRlLg0KMy4gICoqUkFDRTIgKFJhemEgQmxhY2spOioqICoqT1IgPSAzLjAzNTgqKjogU2kgbGEgbWFkcmUgZXMgZGUgcmF6YSBuZWdyYSB0aWVuZQ0KICAgICAgICBhcHJveGltYWRhbWVudGUgMy4wMyB2ZWNlcyBsYXMgb2RkcyBkZSB0ZW5lciB1biBiZWLDqSBjb24gYmFqbw0KICAgICAgICBwZXNvIGNvbXBhcmFkbyBjb24gdW5hIG1hZHJlIGRlIHJhemEgYmxhbmNhLCBtYW50ZW5pZW5kbw0KICAgICAgICBjb25zdGFudGVzIGxhcyBvdHJhcyB2YXJpYWJsZXMuDQo0LiAgKipSQUNFMyAoUmF6YSBPdGhlcik6KiogKipPUiA9IDEuOTUzOCoqOiBTaSBsYSBtYWRyZSBwZXJ0ZW5lY2UgYSBvdHJhIHJhemEgZGlmZXJlbnRlIGENCiAgICAgICAgYmxhbmNhIG8gbmVncmEgdGllbmUgYXByb3hpbWFkYW1lbnRlIDEuOTUgdmVjZXMgbGFzIG9kZHMgZGUNCiAgICAgICAgdGVuZXIgdW4gYmViw6kgY29uIGJham8gcGVzbyBjb21wYXJhZG8gY29uIHVuYSBtYWRyZSBkZSByYXphDQogICAgICAgIGJsYW5jYSwgbWFudGVuaWVuZG8gY29uc3RhbnRlcyBsYXMgb3RyYXMgdmFyaWFibGVzLg0KNS4gICoqU01PS0UxIChGdW3DsyBkdXJhbnRlIGVsIGVtYmFyYXpvKToqKiAqKk9SID0gMi4wMjg1Kio6IExhcyBtYWRyZXMgcXVlIGZ1bWFyb24gZHVyYW50ZSBlbCBlbWJhcmF6bw0KICAgICAgICB0aWVuZW4gYXByb3hpbWFkYW1lbnRlIDIuMDMgdmVjZXMgbGFzIG9kZHMgZGUgdGVuZXIgdW4gYmViw6kgY29uDQogICAgICAgIGJham8gcGVzbyBjb21wYXJhZG8gY29uIGFxdWVsbGFzIHF1ZSBubyBmdW1hcm9uLCBtYW50ZW5pZW5kbw0KICAgICAgICB0b2RvIGxvIGRlbcOhcyBjb25zdGFudGUuDQo2LiAgKipQVEwxIChVbiBlbWJhcmF6byBwcmVtYXR1cm8gYW50ZXJpb3IpOioqICoqT1IgPSA2LjQ1NjIqKjogTGFzIG1hZHJlcyBjb24gdW4gYW50ZWNlZGVudGUgZGUgZW1iYXJhem8NCiAgICAgICAgcHJlbWF0dXJvIHRpZW5lbiBhcHJveGltYWRhbWVudGUgNi40NiB2ZWNlcyBsYXMgb2RkcyBkZSB0ZW5lciB1bg0KICAgICAgICBiZWLDqSBjb24gYmFqbyBwZXNvLCBjb21wYXJhZG8gY29uIGxhcyBtYWRyZXMgc2luIGRpY2hvDQogICAgICAgIGFudGVjZWRlbnRlLCBtYW50ZW5pZW5kbyBjb25zdGFudGVzIGxhcyBvdHJhcyB2YXJpYWJsZXMuDQoNCkxvcyBPUiBub3MgcHJvcG9yY2lvbmFuIHVuYSBmb3JtYSBjdWFudGl0YXRpdmEgZGUgZGV0ZXJtaW5hciBjdcOhbnRvIG3DoXMNCnByb2JhYmxlIGVzIHVuIGV2ZW50byBlbiB1biBncnVwbyBlbiBjb21wYXJhY2nDs24gY29uIG90cm8uIEVuIGVsDQpjb250ZXh0byBkZSBlc3RlIGVzdHVkaW8sIGVzdG9zIE9SIHByb3BvcmNpb25hbiB1bmEgbWVkaWRhIGRlbCByaWVzZ28NCnJlbGF0aXZvIGRlIHRlbmVyIHVuIGJlYsOpIGNvbiBiYWpvIHBlc28gZGFkbyBkaWZlcmVudGVzIGZhY3RvcmVzLg0KDQotUmVhbGl6YXLDqSB1bmEgcmVncmVzacOzbiBsb2fDrXN0aWNhIG3Dumx0aXBsZSwgc2VsZWNjaW9uYW5kbyBsb3MgbWVqb3JlcyBwcmVkaWN0b3JlcyBlbnRyZSBsYXMgdmFyaWFibGVzIGluZGVwZW5kaWVudGVzIGRpc3BvbmlibGVzLCB1dGlsaXphbmRvIHVuIG3DqXRvZG8gZGUgc2VsZWNjacOzbiBhdXRvbcOhdGljYS4NCg0KYGBge3J9DQptb2RlbG9fY29tcGxldG8gPC0gZ2xtKExPVyB+IEFHRSArIExXVCArIFJBQ0UgKyBTTU9LRSArIFBUTCArIEhUICsgVUkgKyBGVFYsIA0KICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gYmFzZV9uYWNpbWllbnRvcywgZmFtaWx5ID0gYmlub21pYWwpDQoNCg0KbW9kZWxvX29wdGltaXphZG8gPC0gc3RlcChtb2RlbG9fY29tcGxldG8sIGRpcmVjdGlvbiA9ICJib3RoIikNCg0KDQpzdW1tYXJ5KG1vZGVsb19vcHRpbWl6YWRvKQ0KYGBgDQoNCkEgcGFydGlyIGRlIGxhIHJlZ3Jlc2nDs24gbG9nw61zdGljYSBtw7psdGlwbGUgcmVhbGl6YWRhIHNvYnJlIGxhcw0KdmFyaWFibGVzLCBzZSBvYnR1dmllcm9uIGxvcyBzaWd1aWVudGVzIHJlc3VsdGFkb3M6DQoNCjEuICBMYSB2YXJpYWJsZSAqKkxXVCoqIHRpZW5lIHVuIGNvZWZpY2llbnRlIG5lZ2F0aXZvLCBsbyBxdWUgc3VnaWVyZQ0KICAgIHF1ZSBhIG1lZGlkYSBxdWUgYXVtZW50YSBlbCBwZXNvIGRlIGxhIG1hZHJlIGVuIGVsIMO6bHRpbW8gcGVyaW9kbw0KICAgIG1lbnN0cnVhbCwgZGlzbWludXllIGVsIGxvZy1vZGRzIGRlIHRlbmVyIHVuIGJlYsOpIGNvbiBiYWpvIHBlc28gYWwNCiAgICBuYWNlci4NCjIuICAqKlJBQ0UyKiogeSAqKlJBQ0UzKiogaW5kaWNhbiBxdWUsIGVuIGNvbXBhcmFjacOzbiBjb24gbGEgcmF6YSBkZQ0KICAgIHJlZmVyZW5jaWEgKFdoaXRlKSwgc2VyIGRlIHJhemEgQmxhY2sgbyBPdGhlciBhdW1lbnRhIGVsIGxvZy1vZGRzIGRlDQogICAgdGVuZXIgdW4gYmViw6kgY29uIGJham8gcGVzbyBhbCBuYWNlci4NCjMuICBGdW1hciBkdXJhbnRlIGVsIGVtYmFyYXpvICgqKlNNT0tFMSoqKSBhdW1lbnRhIGVsIGxvZy1vZGRzIGRlIHRlbmVyDQogICAgdW4gYmViw6kgY29uIGJham8gcGVzbyBhbCBuYWNlci4NCjQuICBUZW5lciBhbnRlY2VkZW50ZXMgZGUgZW1iYXJhem9zIHByZW1hdHVyb3MgKCoqUFRMMSoqKSB0YW1iacOpbg0KICAgIGF1bWVudGEgZWwgcmllc2dvLg0KNS4gIFRlbmVyIGFudGVjZWRlbnRlcyBkZSBoaXBlcnRlbnNpw7NuIGFydGVyaWFsICgqKkhUMSoqKSBhdW1lbnRhDQogICAgY29uc2lkZXJhYmxlbWVudGUgZWwgbG9nLW9kZHMgZGUgZGFyIGEgbHV6IGEgdW4gYmViw6kgY29uIGJham8gcGVzby4NCjYuICBFcyBpbXBvcnRhbnRlIG5vdGFyIHF1ZSAqKlBUTDMqKiBubyBlcyBzaWduaWZpY2F0aXZvIHkgdGllbmUgdW4NCiAgICBlcnJvciBlc3TDoW5kYXIgbXV5IGdyYW5kZSwgbG8gcXVlIHN1Z2llcmUgcXVlIGVzIHBvc2libGUgcXVlIG5vIGhheWENCiAgICBzdWZpY2llbnRlcyBkYXRvcyBwYXJhIGhhY2VyIHVuYSBlc3RpbWFjacOzbiBwcmVjaXNhIHBhcmEgZXNhDQogICAgY2F0ZWdvcsOtYS4NCg0KLVNlZ8O6biBlbCBtb2RlbG8gb2J0ZW5pZG8sIGNhYmUgcHJlZ3VudGFyc2UgY3XDoWxlcyBzb24gbG9zIHByaW5jaXBhbGVzIGZhY3RvcmVzIGRlIHJpZXNnbyBkZWwgYmFqbyBwZXNvIHkgY3XDoWwgZXMgbGEgbWFnbml0dWQgZGUgc3UgZWZlY3RvPw0KDQpCYXPDoW5kb25vcyBlbiBsYSBzaWduaWZpY2FuY2lhIGVzdGFkw61zdGljYSB5IGxvcyBjb2VmaWNpZW50ZXMsIGxvcw0KcHJpbmNpcGFsZXMgZmFjdG9yZXMgZGUgcmllc2dvIHBhcmEgZWwgYmFqbyBwZXNvIGFsIG5hY2VyIHkgbGEgbWFnbml0dWQNCmRlIHN1IGVmZWN0byBzb24gbG9zIHNpZ3VpZW50ZXM6DQoNCg0KQ29lZmljaWVudGUgKEVzdGltYWNpw7NuKSBwYXJhICoqQW50ZWNlZGVudGVzIGRlIGVtYmFyYXpvcyBwcmVtYXR1cm9zIChQVEwxKTogMS40NTc4NjgqKi4gVGVuZXIgdW4gYW50ZWNlZGVudGUgZGUgZW1iYXJhem8gcHJlbWF0dXJvDQogICAgKFBUTDEpIGF1bWVudGEgY29uc2lkZXJhYmxlbWVudGUgZWwgbG9nLW9kZHMgKGxvZ2FyaXRtbyBkZSBsYXMgb2RkcykNCiAgICBkZSBkYXIgYSBsdXogYSB1biBiZWLDqSBjb24gYmFqbyBwZXNvIGFsIG5hY2VyLiBFbiB0w6lybWlub3MgZGUgb2RkcywNCiAgICBzZSBwdWVkZSBkZWNpciBxdWUgbGFzIG9kZHMgZGUgdGVuZXIgdW4gYmViw6kgY29uIGJham8gcGVzbyBhbCBuYWNlcg0KICAgIHNvbiBhcHJveGltYWRhbWVudGUgYGV4cCgxLjQ1Nzg2OClgIOKJiCA0LjI5IHZlY2VzIG1heW9yZXMgcGFyYSBsYXMNCiAgICBtYWRyZXMgY29uIHVuIGFudGVjZWRlbnRlIGRlIGVtYmFyYXpvIHByZW1hdHVybyBlbiBjb21wYXJhY2nDs24gY29uDQogICAgYXF1ZWxsYXMgcXVlIG5vIHRpZW5lbiBhbnRlY2VkZW50ZXMuDQoNCkNvZWZpY2llbnRlIChFc3RpbWFjacOzbikgcGFyYSAqKkFudGVjZWRlbnRlcyBkZSBoaXBlcnRlbnNpw7NuIGFydGVyaWFsIChIVDEpOiAxLjg5ODIwNioqLiBUZW5lciBhbnRlY2VkZW50ZXMgZGUgaGlwZXJ0ZW5zacOzbiBhcnRlcmlhbCBpbmNyZW1lbnRhIHNpZ25pZmljYXRpdmFtZW50ZSBlbCBsb2ctb2RkcyBkZSB0ZW5lciB1biBiZWLDqSBjb24gYmFqbw0KICAgIHBlc28gYWwgbmFjZXIuIExhcyBvZGRzIGRlIHRlbmVyIHVuIGJlYsOpIGNvbiBiYWpvIHBlc28gcGFyYSBtYWRyZXMNCiAgICBjb24gYW50ZWNlZGVudGVzIGRlIGhpcGVydGVuc2nDs24gc29uIGFwcm94aW1hZGFtZW50ZSBgZXhwKDEuODk4MjA2KWANCiAgICDiiYggNi42OCB2ZWNlcyBtYXlvcmVzIGVuIGNvbXBhcmFjacOzbiBjb24gbWFkcmVzIHNpbiB0YWxlcw0KICAgIGFudGVjZWRlbnRlcy4NCg0KQ29lZmljaWVudGUgKEVzdGltYWNpw7NuKSBwYXJhICoqUmF6YSAoUkFDRTIpOiAxLjI0ODg3MioqLiBMYXMgbWFkcmVzIGRlIHJhemEgbmVncmEgKGVuIGNvbXBhcmFjacOzbiBjb24gbGFzDQogICAgZGUgcmF6YSBibGFuY2EsIHF1ZSBlcyBsYSBjYXRlZ29yw61hIGRlIHJlZmVyZW5jaWEpIHRpZW5lbiB1biBtYXlvcg0KICAgIGxvZy1vZGRzIGRlIGRhciBhIGx1eiBhIHVuIGJlYsOpIGNvbiBiYWpvIHBlc28uIExhcyBvZGRzIHNvbg0KICAgIGFwcm94aW1hZGFtZW50ZSBgZXhwKDEuMjQ4ODcyKWAg4omIIDMuNDkgdmVjZXMgbWF5b3JlcyBwYXJhIGxhcyBtYWRyZXMNCiAgICBkZSByYXphIG5lZ3JhLg0KDQoNCkNvZWZpY2llbnRlIChFc3RpbWFjacOzbikgcGFyYSAqKkZ1bcOzIGR1cmFudGUgZWwgZW1iYXJhem8gKFNNT0tFMSk6IDAuODg1MzczKiouIEZ1bWFyIGR1cmFudGUgZWwgZW1iYXJhem8gdGFtYmnDqW4gYXVtZW50YSBlbA0KICAgIGxvZy1vZGRzIGRlIHRlbmVyIHVuIGJlYsOpIGNvbiBiYWpvIHBlc28gYWwgbmFjZXIuIExhcyBvZGRzIGRlIHRlbmVyDQogICAgdW4gYmViw6kgY29uIGJham8gcGVzbyBwYXJhIG1hZHJlcyBmdW1hZG9yYXMgZHVyYW50ZSBlbCBlbWJhcmF6byBzb24NCiAgICBhcHJveGltYWRhbWVudGUgYGV4cCgwLjg4NTM3MylgIOKJiCAyLjQyIHZlY2VzIG1heW9yZXMgZW4gY29tcGFyYWNpw7NuDQogICAgY29uIGxhcyBubyBmdW1hZG9yYXMuDQoNCg0KDQpDb2VmaWNpZW50ZSAoRXN0aW1hY2nDs24pIHBhcmEgKipQZXNvIGRlIGxhIG1hZHJlIGVuIGVsIMO6bHRpbW8gcGVyaW9kbyBtZW5zdHJ1YWwgKExXVCk6IC0wLjAxNzE3MyoqLiBBdW5xdWUgZWwgZWZlY3RvIGVzIG3DoXMgc3V0aWwgcXVlIGxvcyBvdHJvcw0KICAgIGZhY3RvcmVzIG1lbmNpb25hZG9zLCB1biBhdW1lbnRvIGVuIGVsIHBlc28gZGUgbGEgbWFkcmUgZGlzbWludXllIGVsDQogICAgbG9nLW9kZHMgZGUgdGVuZXIgdW4gYmViw6kgY29uIGJham8gcGVzbyBhbCBuYWNlci4gRXN0byBzdWdpZXJlIHF1ZQ0KICAgIHVuIG1heW9yIHBlc28gYWwgZmluYWwgZGVsIGNpY2xvIG1lbnN0cnVhbCBwdWVkZSBlc3RhciBhc29jaWFkbyBjb24NCiAgICB1biBtZW5vciByaWVzZ28gZGUgYmFqbyBwZXNvIGFsIG5hY2VyLg0KDQpDdcOhbGVzIHNvbiBsb3Mgc3VwdWVzdG9zIG5lY2VzYXJpb3MgcGFyYSBkZWZpbmlyIGxhIHBydWViYSBpbmZlcmVuY2lhbCBkZSBsb3MgZXN0aW1hZG9yZXMgZGUgbG9zIHBhcsOhbWV0cm9zPw0KDQpTdXB1ZXN0b3MgcGFyYSBsYSBQcnVlYmEgSW5mZXJlbmNpYWwgZGUgbG9zIEVzdGltYWRvcmVzIGRlIGxvcw0KUGFyw6FtZXRyb3MNCg0KUGFyYSBsbGV2YXIgYSBjYWJvIHBydWViYXMgaW5mZXJlbmNpYWxlcyBlbiBlbCBjb250ZXh0byBkZSByZWdyZXNpw7NuDQpsb2fDrXN0aWNhIGVzIG5lY2VzYXJpbyBxdWUgc2UgY3VtcGxhbiBjaWVydG9zIHN1cHVlc3Rvcy4gRXN0b3Mgc3VwdWVzdG9zDQphc2VndXJhbiBxdWUgbGFzIHBydWViYXMgeSBlc3RpbWFjaW9uZXMgc29uIHbDoWxpZGFzLiBBIGNvbnRpbnVhY2nDs24gc2UNCmRlc2NyaWJlbiBsb3MgcHJpbmNpcGFsZXMgc3VwdWVzdG9zOg0KDQoxLiAgKipMaW5lYWxpZGFkOioqIExhIHJlbGFjacOzbiBlbnRyZSBsYXMgdmFyaWFibGVzIGluZGVwZW5kaWVudGVzIHkgbGEgdmFyaWFibGUNCiAgICAgICAgZGVwZW5kaWVudGUgZGViZSBzZXIgbGluZWFsLiBFbiBlbCBjYXNvIGRlIGxhIHJlZ3Jlc2nDs24NCiAgICAgICAgbG9nw61zdGljYSwgbGEgcmVsYWNpw7NuIGVzIGVudHJlIGxhcyB2YXJpYWJsZXMgaW5kZXBlbmRpZW50ZXMgeQ0KICAgICAgICBlbCBsb2dhcml0bW8gZGUgb2RkcyBkZSBsYSB2YXJpYWJsZSBkZXBlbmRpZW50ZS4NCjIuICAqKkluZGVwZW5kZW5jaWE6KiogTGFzIG9ic2VydmFjaW9uZXMgZGViZW4gc2VyIGluZGVwZW5kaWVudGVzIGVudHJlIHPDrS4gRXN0bw0KICAgICAgICBnZW5lcmFsbWVudGUgc2Ugc2F0aXNmYWNlIGNvbiB1biBkaXNlw7FvIGRlIG11ZXN0cmVvIGFkZWN1YWRvLg0KMy4gICoqQXVzZW5jaWEgZGUgbXVsdGljb2xpbmVhbGlkYWQ6KiogTGFzIHZhcmlhYmxlcyBpbmRlcGVuZGllbnRlcyBubyBkZWJlbiBlc3RhciBhbHRhbWVudGUNCiAgICAgICAgY29ycmVsYWNpb25hZGFzIGVudHJlIHPDrS4gRXN0byBwb3JxdWUgbGEgbXVsdGljb2xpbmVhbGlkYWQgcHVlZGUNCiAgICAgICAgaGFjZXIgcXVlIGxvcyBlc3RpbWFkb3JlcyBubyBzZWFuIMO6bmljb3MgeSBwb3IgbG8gdGFudG8gbG9zDQogICAgICAgIHAtdmFsdWVzIGFzb2NpYWRvcyBwdWVkZW4gbm8gc2VyIHbDoWxpZG9zLg0KNC4gICoqQXVzZW5jaWEgZGUgdmFsb3JlcyBleHRyZW1vczoqKiBMb3MgdmFsb3JlcyBleHRyZW1vcyBvIGF0w61waWNvcyBwdWVkZW4gYWZlY3Rhcg0KICAgICAgICBzaWduaWZpY2F0aXZhbWVudGUgbG9zIGVzdGltYWRvcmVzIHkgbGFzIHBydWViYXMgaW5mZXJlbmNpYWxlcy4NCiAgICAgICAgRXMgZnVuZGFtZW50YWwgdmVyaWZpY2FyIHksIHNpIGVzIG5lY2VzYXJpbywgdHJhdGFyIGVzdG9zDQogICAgICAgIHZhbG9yZXMgYW50ZXMgZGVsIGFuw6FsaXNpcy4NCjUuICAqKkVzcGVjaWZpY2FjacOzbiBjb3JyZWN0YSBkZWwgbW9kZWxvOioqIEVsIG1vZGVsbyBkZWJlIGVzdGFyIGVzcGVjaWZpY2FkbyBjb3JyZWN0YW1lbnRlLCBlcyBkZWNpciwgZGViZQ0KICAgICAgICBpbmNsdWlyIHRvZGFzIGxhcyB2YXJpYWJsZXMgcmVsZXZhbnRlcyB5IG5vIGluY2x1aXIgdmFyaWFibGVzDQogICAgICAgIGlycmVsZXZhbnRlcy4NCg0KQWwgbm8gY3VtcGxpcnNlIGVzdG9zIHN1cHVlc3RvcywgbGFzIHBydWViYXMgaW5mZXJlbmNpYWxlcyBwdWVkZW4gbm8gc2VyDQp2w6FsaWRhcyB5IHBvZHLDrWFtb3MgbGxlZ2FyIGEgY29uY2x1c2lvbmVzIGluY29ycmVjdGFzIHNvYnJlIGxhIHJlbGFjacOzbg0KZW50cmUgbGFzIHZhcmlhYmxlcyBpbmRlcGVuZGllbnRlcyB5IGxhIGRlcGVuZGllbnRlLg0KDQpQb3JjZW50YWplIGRlIGNhc29zIGJpZW4gcHJlZGljaG9zIHBvciBlbCBtb2RlbG8uDQoNCmBgYHtyfQ0KIyBDYWxjdWxhciBwb3JjZW50YWplIGRlIGNhc29zIGJpZW4gcHJlZGljaG9zDQpwcmVkaWNob3MgPC0gaWZlbHNlKHByZWRpY3QobW9kZWxvX29wdGltaXphZG8sIHR5cGUgPSAicmVzcG9uc2UiKSA+IDAuNSwgMSwgMCkNCnRhYmxhIDwtIHRhYmxlKGJhc2VfbmFjaW1pZW50b3MkTE9XLCBwcmVkaWNob3MpDQphY2N1cmFjeSA8LSBzdW0oZGlhZyh0YWJsYSkpIC8gc3VtKHRhYmxhKSAqIDEwMA0KcHJpbnQocGFzdGUoIlBvcmNlbnRhamUgZGUgY2Fzb3MgYmllbiBwcmVkaWNob3M6IiwgYWNjdXJhY3kpKQ0KYGBgDQo=