Determinación de la incertidumbre de la medición en Ensayos de Au

Integrantes: Andre Aldasabal, Edward Perez, Vicente Pastor y Fabiana Strobbe

library(readxl)
library(dplyr)
library(knitr)

# =========================
# 1. LEER EXCEL
# =========================
file_path <- "DATOS_GUM_Au_Ag.xlsx"

model  <- read_excel(file_path, sheet = 1)
params <- read_excel(file_path, sheet = 2)
tabla_Ya <- read_excel(file_path, sheet = 3)

# =========================
# 2. CREAR BASE DE DATOS
# =========================
DB <- as.list(params$Valor)
names(DB) <- params$Parametro

# =========================
# 4. FUNCIÓN g (CORRECCIÓN CLAVE)
# =========================
g <- function(x) {
  if (is.list(DB[[x]])) return(as.numeric(DB[[x]]$value))
  return(as.numeric(DB[[x]]))
}

# =========================
# 3. VARIABLES
# =========================

DB[["u_cal_Wm"]] <- list(
  value = sqrt(0.5 * (g("u_cal1")^2 + g("u_cal2")^2)),
  latex = "\\sqrt{\\frac{u_{cal1}^2 + u_{cal2}^2}{2}}"
)

DB[["u_r"]] <- list(
  value = sqrt(0.5 * (g("RepB1")^2 + g("RepB2")^2)),
  latex = "\\sqrt{\\frac{RepB1^2 + RepB2^2}{2}}"
)

DB[["u_res"]] <- list(
  value = g("legibilidad") / sqrt(12),
  latex = "\\frac{legibilidad}{\\sqrt{12}}"
)

DB[["u_p_Wm"]] <- list(
  value = sqrt(g("u_res")^2 + g("u_r")^2),
  latex = "\\sqrt{u_{res}^2 + u_{r}^2}"
)

DB[["u_d_Wm"]] <- list(
  value = g("sen") * g("delta_T") * g("Wm") / g("t_st"),
  latex = "\\frac{sen \\cdot \\Delta T \\cdot W_m}{t_{st}}"
)

DB[["u_Wm1"]] <- list(
  value = sqrt( g("u_cal_Wm")^2 +g("u_p_Wm")^2 + g("u_d_Wm")^2),
  latex = "\\sqrt{u_{cal}^2 + u_p^2 + u_d^2}"
)

DB[["u_Wm"]] <- list(
  value = sqrt(2*(g("u_Wm1")^2) ),
  latex = "\\sqrt{u_{cal}^2 + u_p^2 + u_d^2}"
)

DB[["Et"]] <- list(
  value = (g("Vn")/g("Vt"))*g("En"),
  latex = "\\sqrt{u_{cal}^2 + u_p^2 + u_d^2}"
)

DB[["u_cal_Vd"]] <- list(
  value = g("Et")/(100*sqrt(3))*g("Vt"),
  latex = "\\sqrt{u_{cal}^2 + u_p^2 + u_d^2}"
)

DB[["CVt"]] <- list(
  value = (g("Vn")/g("Vt"))*g("CVn"),
  latex = "\\sqrt{u_{cal}^2 + u_p^2 + u_d^2}"
)

DB[["u_r_Vd"]] <- list(
  value = (g("CVt")/100)*g("Vt"),
  latex = "\\sqrt{u_{cal}^2 + u_p^2 + u_d^2}"
)

DB[["u_T_Vd"]] <- list(
  value = (g("I")*g("a")*g("Vd"))/g("t_st"),
  latex = "\\sqrt{u_{cal}^2 + u_p^2 + u_d^2}"
)

DB[["u_T_Vd"]] <- list(
  value = (g("I")*g("a")*g("Vd"))/g("t_st"),
  latex = "\\sqrt{u_{cal}^2 + u_p^2 + u_d^2}"
)

DB[["u_Vd"]] <- list(
  value = sqrt( g("u_cal_Vd")^2 +g("u_r_Vd")^2 + g("u_T_Vd")^2),
  latex = "\\sqrt{u_{cal}^2 + u_p^2 + u_d^2}"
)

DB[["u_MRC"]] <- list(
  value =  g("Uexp")/2,
  latex = "\\sqrt{u_{cal}^2 + u_p^2 + u_d^2}"
)

DB[["u_Vaf"]] <- list(
  value = sqrt( g("ur_Vaf")^2 +g("ut_Vaf")^2 + g("ucal_Vaf")^2),
  latex = "\\sqrt{u_{cal}^2 + u_p^2 + u_d^2}"
)

# =========================
# 4. FUNCIONES DE ACCESO
# =========================

get_var <- function(id, DB) {
  if (is.list(DB[[id]])) return(DB[[id]]$value)
  return(DB[[id]])
}

get_latex <- function(id, DB) {
  if (is.list(DB[[id]])) return(DB[[id]]$latex)
  return(NA)
}

print_latex <- function(id, DB) {
  latex <- get_latex(id, DB)
  knitr::asis_output(paste0("$$", latex, "$$"))
}

1. Incertidumbre asociada a la masa de muestra (Wm)

La incertidumbre asociada a la masa de muestra se calcula considerando las contribuciones de calibración, precisión y deriva de sensibilidad.

La primera contribución corresponde a la incertidumbre de calibración de las balanzas.

Tipo B: Certificado de calibración UNIVERSA.

\[ u_{cal,Wm} = \sqrt{ 0.5\left( u_{cal1}^{2} + u_{cal2}^{2} \right) } \]

get_var("u_cal_Wm", DB)
[1] 0.005522681

La segunda contribución corresponde a la incertidumbre estándar experimental de las pesadas de la masa patrón.

Tipo A: Repetibilidad experimental

\[ u_r = \sqrt{ 0.5\left( RepB1^{2} + RepB2^{2} \right) } \]

get_var("u_r", DB)
[1] 0.003733631

La tercera contribución corresponde a la incertidumbre asociada a la resolución de la balanza.

Tipo B: Especificaciones técnicas de la balanza Sartorius TE212 Distribución rectangular \[ u_{res} = \frac{legibilidad} {\sqrt{12}} \]

get_var("u_res", DB)
[1] 0.002886751

La incertidumbre de precisión se obtiene combinando las contribuciones de repetibilidad y resolución.

\[ u_{p,Wm} = \sqrt{ u_r^{2} + u_{res}^{2} } \]

get_var("u_p_Wm", DB)
[1] 0.004719463

Luego, se calcula la incertidumbre por efecto de temperatura.

Tipo B: Modelo físico del instrumento bajo parámetros conocidos o asumidos

\[ u_{d,Wm} = \frac{ sen \cdot \Delta T \cdot Wm } { t_{st} } \]

get_var("u_d_Wm", DB)
[1] 0.0008069509

Las tres contribuciones anteriores se combinan para obtener la incertidumbre asociada a una pesada.

\[ u_{Wm1} = \sqrt{ u_{cal,Wm}^{2} + u_{p,Wm}^{2} + u_{d,Wm}^{2} } \]

get_var("u_Wm1", DB)
[1] 0.007309207

La incertidumbre final asociada a la masa de muestra se calcula considerando dos eventos de pesaje independientes: la operación de tarado (tare) y la pesada propiamente dicha.

\[ u_{Wm} = \sqrt{ 2\left( u_{Wm1}^{2} \right) } \]

get_var("u_Wm", DB)
[1] 0.01033678

La incertidumbre obtenida será utilizada posteriormente en la propagación de incertidumbres de la concentración final de Au.

2. Incertidumbre asociada al volumen de dilución (Vd)

La incertidumbre del volumen de dilución se obtiene a partir de tres contribuciones principales: la incertidumbre debida a la calibración del material volumétrico, la incertidumbre de repetibilidad asociada a las mediciones del dispensador y la incertidumbre debida al efecto de la temperatura sobre el volumen.


Corrección del efecto sistemático

El primer término corresponde a la corrección del efecto sistemático asociado a la exactitud del volumen parcial del material volumétrico, la cual relaciona el volumen nominal del instrumento con el volumen efectivamente utilizado,

Tipo B: Valor asignado

\[ E_t = \frac{V_n}{V_t} \cdot E_n \]

get_var("Et", DB)
[1] 2.5

Incertidumbre de calibración del aparato

La incertidumbre de calibración del volumen de dilución se estima como:

\[ u_{cal,Vd} = \frac{ E_t } { 100\sqrt{3} } \cdot V_t \]

get_var("u_cal_Vd", DB)
[1] 0.02886751

Coeficiente de variación corregido

Luego, se calcula la incertidumbre debida a la repetibilidad del volumen dosificado.

El coeficiente de variación ajustado por condiciones experimentales se calcula como:

\[ CV_t = \frac{V_n}{V_t} \cdot CV_n \]

get_var("CVt", DB)
[1] 0.5

Incertidumbre de repetibilidad del volumen

La incertidumbre asociada a la repetibilidad del volumen es:

\[ u_{r,Vd} = \frac{CV_t}{100} \cdot V_t \]

get_var("u_r_Vd", DB)
[1] 0.01

Incertidumbre por temperatura en volumen

El efecto de la temperatura sobre el volumen se modela como: Tipo B \[ u_{T,Vd} = \frac{ I \cdot a \cdot V_d } { t_{st} } \]

get_var("u_T_Vd", DB)
[1] 0.001023153

Incertidumbre estándar combinada del volumen de dilución

Finalmente, la incertidumbre del volumen de dilución se obtiene combinando todas las contribuciones:

\[ u(V_d) = \sqrt{ u_{cal,Vd}^{2} + u_{r,Vd}^{2} + u_{T,Vd}^{2} } \]

get_var("u_Vd", DB)
[1] 0.03056763

La incertidumbre obtenida en esta sección será utilizada posteriormente en la propagación de incertidumbre de la concentración de Au en la muestra.

3. Preparación de las soluciones de calibración (YAu)

Las soluciones de calibración se preparan a partir de un material de referencia certificado (MRC), el volumen transferido y el volumen final de aforo. Estas soluciones permiten construir la curva de calibración para la determinación de Au.


Modelo de medición

La concentración de cada solución de calibración se expresa como:

\[ Y_{Au,i} = \frac{ Y_{MRC} \cdot V_{ai} } { V_{af} } \]

donde:

  • \(Y_{MRC}\): concentración del material de referencia certificado
  • \(V_{ai}\): volumen transferido en cada nivel de calibración
  • \(V_{af}\): volumen final de aforo

Incertidumbre del material de referencia certificado (u(γMRC))

La incertidumbre asociada al material de referencia certificado se obtiene a partir de la incertidumbre expandida reportada en el certificado de análisis. Esta incertidumbre se transforma a incertidumbre estándar dividiendo por el factor de cobertura \(k\) indicado en dicho certificado:

\[ u_{MRC} = \frac{U_{exp}}{2} = \frac{0.5}{2} = 0.25 \; \text{ppm} \]


Incertidumbre del matraz aforado (u(Vaf))

La incertidumbre asociada al volumen de aforo se obtiene mediante la combinación cuadrática de tres contribuciones independientes: repetibilidad, temperatura y calibración del material volumétrico:

\[ u(V_{af}) = \sqrt{ u_r(V_{af})^2 + u_T(V_{af})^2 + u_{cal}(V_{af})^2 } \]

Donde:

  • \(u_r(V_{af})\): incertidumbre debida a la repetibilidad de las mediciones
  • \(u_T(V_{af})\): incertidumbre debida al efecto de la temperatura
  • \(u_{cal}(V_{af})\): incertidumbre debida a la calibración del matraz

Aplicando la ecuación correspondiente se obtiene:

get_var("u_Vaf", DB)
[1] 0.1476345

Incertidumbre debida a la alícuota (u(Vai))

La incertidumbre asociada al volumen de alícuota se evalúa a partir de la repetibilidad de las mediciones del volumen transferido en cada nivel de calibración.

tabla_Ya[, c(1,2)]

Coeficientes de sensibilidad

Para aplicar la ley de propagación de incertidumbres se calculan los coeficientes de sensibilidad:

\[ c_1 = \frac{V_{ai}}{V_{af}} \]

\[ c_2 = \frac{Y_{MRC}}{V_{af}} \]

\[ c_3 = -\frac{Y_{MRC}\cdot V_{ai}}{V_{af}^{2}} \]


Incertidumbre estándar combinada de cada punto de calibración

La incertidumbre asociada a cada solución de calibración se calcula como:

\[ u_c(Y_{Au,i}) = \sqrt{ (c_1 \cdot u_{MRC})^2 + (c_2 \cdot u(V_{ai}))^2 + (c_3 \cdot u(V_{af}))^2 } \]

tabla_resultados <- data.frame(
  Y_cal = tabla_Ya$Y_Au,
  u_c_Ycal = sqrt(
    (c1 * g("u_MRC"))^2 +
    (c2 * tabla_Ya$uc_Vai)^2 +
    (c3 * g("u_Vaf"))^2
  )
)

tabla_resultados

Incertidumbre combinada global de calibración

La contribución global de todas las soluciones de calibración se obtiene mediante suma cuadrática:

\[ u_{c,YAu} = \sqrt{ \sum_{i=1}^{n} u_c(Y_{Au,i})^2 } \]

u_c_YAu
[1] 0.01413815

Incertidumbre de preparación de soluciones

La incertidumbre experimental asociada a la preparación de cada punto de calibración es:

u_a_YAu <- tabla_Ya$u_Ya
u_a_YAu
[1] 0.0066 0.0064 0.0062 0.0063 0.0066 0.0071

Incertidumbre total de las soluciones de calibración

La incertidumbre total de cada punto de calibración se obtiene combinando la contribución experimental y la contribución de preparación:

\[ u(Y_{Au}) = \sqrt{ u_{a,YAu}^{2} + u_{c,YAu}^{2} } \]

tabla_Y_au <- data.frame(
  Y_Au = tabla_Ya$Ya,
  u_Y_Au = round(u_YAu, 5)
)

knitr::kable(tabla_Y_au)
Y_Au u_Y_Au
0.1 0.01560
0.2 0.01552
0.4 0.01544
0.6 0.01548
0.8 0.01560
1.0 0.01582

Los valores obtenidos en esta sección serán utilizados en la propagación de incertidumbre para la determinación final de Au en la muestra.

4. Determinación de Au en la muestra

Una vez obtenidas las soluciones de calibración y sus incertidumbres asociadas, se procede a calcular la concentración de Au en la muestra.


Modelo de medición

La concentración de Au en la muestra se calcula mediante:

\[ C_{Au} = \frac{ Y_{Au} \cdot V_d } { W_m } \]

donde:

  • \(Y_{Au}\): concentración obtenida por calibración
  • \(V_d\): volumen de dilución
  • \(W_m\): masa de muestra

Coeficientes de sensibilidad

Derivando el modelo de medición:

\[ c_1 = \frac{V_d}{W_m} \]

\[ c_2 = \frac{Y_{Au}}{W_m} \]

\[ c_3 = - \frac{Y_{Au}\cdot V_d}{W_m^2} \]


Incertidumbre estándar combinada de C_{Au}

La incertidumbre de la concentración de Au se obtiene mediante propagación de incertidumbres:

\[ u(C_{Au}) = \sqrt{ (c_1 \cdot u(Y_{Au}))^2 + (c_2 \cdot u(V_d))^2 + (c_3 \cdot u(W_m))^2 } \]


tabla_CA_u <- data.frame(
  `C_Au (mg/kg)` = round(tabla_resultados_2[,1], 5),
  `u(C_Au) (mg/kg)` = round(tabla_resultados_2[,2], 5)
)

knitr::kable(
  tabla_CA_u,
  caption = "Incertidumbre estándar combinada en la determinación de Au"
)
Incertidumbre estándar combinada en la determinación de Au
C_Au..mg.kg. u.C_Au…mg.kg.
0.00667 0.00105
0.01333 0.00105
0.02667 0.00111
0.04000 0.00120
0.05333 0.00132
0.06667 0.00147
NA
LS0tDQp0aXRsZTogIlByb3llY3RvIC0gRnVuZGFtZW50byBkZSBJbmdlbmllcsOtYSBkZSBsb3MgTWluZXJhbGVzIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiMjIERldGVybWluYWNpw7NuIGRlIGxhIGluY2VydGlkdW1icmUgZGUgbGEgbWVkaWNpw7NuIGVuIEVuc2F5b3MgZGUgQXUNCkludGVncmFudGVzOg0KQW5kcmUgQWxkYXNhYmFsLA0KRWR3YXJkIFBlcmV6LA0KVmljZW50ZSBQYXN0b3IgeQ0KRmFiaWFuYSBTdHJvYmJlDQoNCmBgYHtyfQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShrbml0cikNCg0KIyA9PT09PT09PT09PT09PT09PT09PT09PT09DQojIDEuIExFRVIgRVhDRUwNCiMgPT09PT09PT09PT09PT09PT09PT09PT09PQ0KZmlsZV9wYXRoIDwtICJEQVRPU19HVU1fQXVfQWcueGxzeCINCg0KbW9kZWwgIDwtIHJlYWRfZXhjZWwoZmlsZV9wYXRoLCBzaGVldCA9IDEpDQpwYXJhbXMgPC0gcmVhZF9leGNlbChmaWxlX3BhdGgsIHNoZWV0ID0gMikNCnRhYmxhX1lhIDwtIHJlYWRfZXhjZWwoZmlsZV9wYXRoLCBzaGVldCA9IDMpDQoNCiMgPT09PT09PT09PT09PT09PT09PT09PT09PQ0KIyAyLiBDUkVBUiBCQVNFIERFIERBVE9TDQojID09PT09PT09PT09PT09PT09PT09PT09PT0NCkRCIDwtIGFzLmxpc3QocGFyYW1zJFZhbG9yKQ0KbmFtZXMoREIpIDwtIHBhcmFtcyRQYXJhbWV0cm8NCg0KIyA9PT09PT09PT09PT09PT09PT09PT09PT09DQojIDQuIEZVTkNJw5NOIGcgKENPUlJFQ0NJw5NOIENMQVZFKQ0KIyA9PT09PT09PT09PT09PT09PT09PT09PT09DQpnIDwtIGZ1bmN0aW9uKHgpIHsNCiAgaWYgKGlzLmxpc3QoREJbW3hdXSkpIHJldHVybihhcy5udW1lcmljKERCW1t4XV0kdmFsdWUpKQ0KICByZXR1cm4oYXMubnVtZXJpYyhEQltbeF1dKSkNCn0NCg0KIyA9PT09PT09PT09PT09PT09PT09PT09PT09DQojIDMuIFZBUklBQkxFUw0KIyA9PT09PT09PT09PT09PT09PT09PT09PT09DQoNCkRCW1sidV9jYWxfV20iXV0gPC0gbGlzdCgNCiAgdmFsdWUgPSBzcXJ0KDAuNSAqIChnKCJ1X2NhbDEiKV4yICsgZygidV9jYWwyIileMikpLA0KICBsYXRleCA9ICJcXHNxcnR7XFxmcmFje3Vfe2NhbDF9XjIgKyB1X3tjYWwyfV4yfXsyfX0iDQopDQoNCkRCW1sidV9yIl1dIDwtIGxpc3QoDQogIHZhbHVlID0gc3FydCgwLjUgKiAoZygiUmVwQjEiKV4yICsgZygiUmVwQjIiKV4yKSksDQogIGxhdGV4ID0gIlxcc3FydHtcXGZyYWN7UmVwQjFeMiArIFJlcEIyXjJ9ezJ9fSINCikNCg0KREJbWyJ1X3JlcyJdXSA8LSBsaXN0KA0KICB2YWx1ZSA9IGcoImxlZ2liaWxpZGFkIikgLyBzcXJ0KDEyKSwNCiAgbGF0ZXggPSAiXFxmcmFje2xlZ2liaWxpZGFkfXtcXHNxcnR7MTJ9fSINCikNCg0KREJbWyJ1X3BfV20iXV0gPC0gbGlzdCgNCiAgdmFsdWUgPSBzcXJ0KGcoInVfcmVzIileMiArIGcoInVfciIpXjIpLA0KICBsYXRleCA9ICJcXHNxcnR7dV97cmVzfV4yICsgdV97cn1eMn0iDQopDQoNCkRCW1sidV9kX1dtIl1dIDwtIGxpc3QoDQogIHZhbHVlID0gZygic2VuIikgKiBnKCJkZWx0YV9UIikgKiBnKCJXbSIpIC8gZygidF9zdCIpLA0KICBsYXRleCA9ICJcXGZyYWN7c2VuIFxcY2RvdCBcXERlbHRhIFQgXFxjZG90IFdfbX17dF97c3R9fSINCikNCg0KREJbWyJ1X1dtMSJdXSA8LSBsaXN0KA0KICB2YWx1ZSA9IHNxcnQoIGcoInVfY2FsX1dtIileMiArZygidV9wX1dtIileMiArIGcoInVfZF9XbSIpXjIpLA0KICBsYXRleCA9ICJcXHNxcnR7dV97Y2FsfV4yICsgdV9wXjIgKyB1X2ReMn0iDQopDQoNCkRCW1sidV9XbSJdXSA8LSBsaXN0KA0KICB2YWx1ZSA9IHNxcnQoMiooZygidV9XbTEiKV4yKSApLA0KICBsYXRleCA9ICJcXHNxcnR7dV97Y2FsfV4yICsgdV9wXjIgKyB1X2ReMn0iDQopDQoNCkRCW1siRXQiXV0gPC0gbGlzdCgNCiAgdmFsdWUgPSAoZygiVm4iKS9nKCJWdCIpKSpnKCJFbiIpLA0KICBsYXRleCA9ICJcXHNxcnR7dV97Y2FsfV4yICsgdV9wXjIgKyB1X2ReMn0iDQopDQoNCkRCW1sidV9jYWxfVmQiXV0gPC0gbGlzdCgNCiAgdmFsdWUgPSBnKCJFdCIpLygxMDAqc3FydCgzKSkqZygiVnQiKSwNCiAgbGF0ZXggPSAiXFxzcXJ0e3Vfe2NhbH1eMiArIHVfcF4yICsgdV9kXjJ9Ig0KKQ0KDQpEQltbIkNWdCJdXSA8LSBsaXN0KA0KICB2YWx1ZSA9IChnKCJWbiIpL2coIlZ0IikpKmcoIkNWbiIpLA0KICBsYXRleCA9ICJcXHNxcnR7dV97Y2FsfV4yICsgdV9wXjIgKyB1X2ReMn0iDQopDQoNCkRCW1sidV9yX1ZkIl1dIDwtIGxpc3QoDQogIHZhbHVlID0gKGcoIkNWdCIpLzEwMCkqZygiVnQiKSwNCiAgbGF0ZXggPSAiXFxzcXJ0e3Vfe2NhbH1eMiArIHVfcF4yICsgdV9kXjJ9Ig0KKQ0KDQpEQltbInVfVF9WZCJdXSA8LSBsaXN0KA0KICB2YWx1ZSA9IChnKCJJIikqZygiYSIpKmcoIlZkIikpL2coInRfc3QiKSwNCiAgbGF0ZXggPSAiXFxzcXJ0e3Vfe2NhbH1eMiArIHVfcF4yICsgdV9kXjJ9Ig0KKQ0KDQpEQltbInVfVF9WZCJdXSA8LSBsaXN0KA0KICB2YWx1ZSA9IChnKCJJIikqZygiYSIpKmcoIlZkIikpL2coInRfc3QiKSwNCiAgbGF0ZXggPSAiXFxzcXJ0e3Vfe2NhbH1eMiArIHVfcF4yICsgdV9kXjJ9Ig0KKQ0KDQpEQltbInVfVmQiXV0gPC0gbGlzdCgNCiAgdmFsdWUgPSBzcXJ0KCBnKCJ1X2NhbF9WZCIpXjIgK2coInVfcl9WZCIpXjIgKyBnKCJ1X1RfVmQiKV4yKSwNCiAgbGF0ZXggPSAiXFxzcXJ0e3Vfe2NhbH1eMiArIHVfcF4yICsgdV9kXjJ9Ig0KKQ0KDQpEQltbInVfTVJDIl1dIDwtIGxpc3QoDQogIHZhbHVlID0gIGcoIlVleHAiKS8yLA0KICBsYXRleCA9ICJcXHNxcnR7dV97Y2FsfV4yICsgdV9wXjIgKyB1X2ReMn0iDQopDQoNCkRCW1sidV9WYWYiXV0gPC0gbGlzdCgNCiAgdmFsdWUgPSBzcXJ0KCBnKCJ1cl9WYWYiKV4yICtnKCJ1dF9WYWYiKV4yICsgZygidWNhbF9WYWYiKV4yKSwNCiAgbGF0ZXggPSAiXFxzcXJ0e3Vfe2NhbH1eMiArIHVfcF4yICsgdV9kXjJ9Ig0KKQ0KDQojID09PT09PT09PT09PT09PT09PT09PT09PT0NCiMgNC4gRlVOQ0lPTkVTIERFIEFDQ0VTTw0KIyA9PT09PT09PT09PT09PT09PT09PT09PT09DQoNCmdldF92YXIgPC0gZnVuY3Rpb24oaWQsIERCKSB7DQogIGlmIChpcy5saXN0KERCW1tpZF1dKSkgcmV0dXJuKERCW1tpZF1dJHZhbHVlKQ0KICByZXR1cm4oREJbW2lkXV0pDQp9DQoNCmdldF9sYXRleCA8LSBmdW5jdGlvbihpZCwgREIpIHsNCiAgaWYgKGlzLmxpc3QoREJbW2lkXV0pKSByZXR1cm4oREJbW2lkXV0kbGF0ZXgpDQogIHJldHVybihOQSkNCn0NCg0KcHJpbnRfbGF0ZXggPC0gZnVuY3Rpb24oaWQsIERCKSB7DQogIGxhdGV4IDwtIGdldF9sYXRleChpZCwgREIpDQogIGtuaXRyOjphc2lzX291dHB1dChwYXN0ZTAoIiQkIiwgbGF0ZXgsICIkJCIpKQ0KfQ0KDQpgYGANCg0KDQojIDEuIEluY2VydGlkdW1icmUgYXNvY2lhZGEgYSBsYSBtYXNhIGRlIG11ZXN0cmEgKFdtKQ0KDQpMYSBpbmNlcnRpZHVtYnJlIGFzb2NpYWRhIGEgbGEgbWFzYSBkZSBtdWVzdHJhIHNlIGNhbGN1bGEgY29uc2lkZXJhbmRvIGxhcyBjb250cmlidWNpb25lcyBkZSBjYWxpYnJhY2nDs24sIHByZWNpc2nDs24geSBkZXJpdmEgZGUgc2Vuc2liaWxpZGFkLg0KDQpMYSBwcmltZXJhIGNvbnRyaWJ1Y2nDs24gY29ycmVzcG9uZGUgYSBsYSBpbmNlcnRpZHVtYnJlIGRlIGNhbGlicmFjacOzbiBkZSBsYXMgYmFsYW56YXMuDQoNClRpcG8gQjogQ2VydGlmaWNhZG8gZGUgY2FsaWJyYWNpw7NuIFVOSVZFUlNBLg0KDQokJA0KdV97Y2FsLFdtfQ0KPQ0KXHNxcnR7DQowLjVcbGVmdCgNCnVfe2NhbDF9XnsyfQ0KKw0KdV97Y2FsMn1eezJ9DQpccmlnaHQpDQp9DQokJA0KDQpgYGB7cn0NCmdldF92YXIoInVfY2FsX1dtIiwgREIpDQpgYGANCg0KTGEgc2VndW5kYSBjb250cmlidWNpw7NuIGNvcnJlc3BvbmRlIGEgbGEgaW5jZXJ0aWR1bWJyZSBlc3TDoW5kYXIgZXhwZXJpbWVudGFsIGRlIGxhcyBwZXNhZGFzIGRlIGxhIG1hc2EgcGF0csOzbi4NCg0KVGlwbyBBOiBSZXBldGliaWxpZGFkIGV4cGVyaW1lbnRhbA0KDQokJA0KdV9yDQo9DQpcc3FydHsNCjAuNVxsZWZ0KA0KUmVwQjFeezJ9DQorDQpSZXBCMl57Mn0NClxyaWdodCkNCn0NCiQkDQoNCmBgYHtyfQ0KZ2V0X3ZhcigidV9yIiwgREIpDQpgYGANCg0KTGEgdGVyY2VyYSBjb250cmlidWNpw7NuIGNvcnJlc3BvbmRlIGEgbGEgaW5jZXJ0aWR1bWJyZSBhc29jaWFkYSBhIGxhIHJlc29sdWNpw7NuIGRlIGxhIGJhbGFuemEuDQoNClRpcG8gQjogRXNwZWNpZmljYWNpb25lcyB0w6ljbmljYXMgZGUgbGEgYmFsYW56YSBTYXJ0b3JpdXMgVEUyMTINCkRpc3RyaWJ1Y2nDs24gcmVjdGFuZ3VsYXINCiQkDQp1X3tyZXN9DQo9DQpcZnJhY3tsZWdpYmlsaWRhZH0NCntcc3FydHsxMn19DQokJA0KDQpgYGB7cn0NCmdldF92YXIoInVfcmVzIiwgREIpDQpgYGANCg0KTGEgaW5jZXJ0aWR1bWJyZSBkZSBwcmVjaXNpw7NuIHNlIG9idGllbmUgY29tYmluYW5kbyBsYXMgY29udHJpYnVjaW9uZXMgZGUgcmVwZXRpYmlsaWRhZCB5IHJlc29sdWNpw7NuLg0KDQokJA0KdV97cCxXbX0NCj0NClxzcXJ0ew0KdV9yXnsyfQ0KKw0KdV97cmVzfV57Mn0NCn0NCiQkDQoNCmBgYHtyfQ0KZ2V0X3ZhcigidV9wX1dtIiwgREIpDQpgYGANCg0KTHVlZ28sIHNlIGNhbGN1bGEgbGEgaW5jZXJ0aWR1bWJyZSBwb3IgZWZlY3RvIGRlIHRlbXBlcmF0dXJhLg0KDQpUaXBvIEI6IE1vZGVsbyBmw61zaWNvIGRlbCBpbnN0cnVtZW50byBiYWpvIHBhcsOhbWV0cm9zIGNvbm9jaWRvcyBvIGFzdW1pZG9zDQoNCiQkDQp1X3tkLFdtfQ0KPQ0KXGZyYWN7DQpzZW4gXGNkb3QgXERlbHRhIFQgXGNkb3QgV20NCn0NCnsNCnRfe3N0fQ0KfQ0KJCQNCg0KYGBge3J9DQpnZXRfdmFyKCJ1X2RfV20iLCBEQikNCmBgYA0KDQpMYXMgdHJlcyBjb250cmlidWNpb25lcyBhbnRlcmlvcmVzIHNlIGNvbWJpbmFuIHBhcmEgb2J0ZW5lciBsYSBpbmNlcnRpZHVtYnJlIGFzb2NpYWRhIGEgdW5hIHBlc2FkYS4NCg0KJCQNCnVfe1dtMX0NCj0NClxzcXJ0ew0KdV97Y2FsLFdtfV57Mn0NCisNCnVfe3AsV219XnsyfQ0KKw0KdV97ZCxXbX1eezJ9DQp9DQokJA0KDQpgYGB7cn0NCmdldF92YXIoInVfV20xIiwgREIpDQpgYGANCg0KTGEgaW5jZXJ0aWR1bWJyZSBmaW5hbCBhc29jaWFkYSBhIGxhIG1hc2EgZGUgbXVlc3RyYSBzZSBjYWxjdWxhIGNvbnNpZGVyYW5kbyBkb3MgZXZlbnRvcyBkZSBwZXNhamUgaW5kZXBlbmRpZW50ZXM6IGxhIG9wZXJhY2nDs24gZGUgdGFyYWRvICh0YXJlKSB5IGxhIHBlc2FkYSBwcm9waWFtZW50ZSBkaWNoYS4NCg0KJCQNCnVfe1dtfQ0KPQ0KXHNxcnR7DQoyXGxlZnQoDQp1X3tXbTF9XnsyfQ0KXHJpZ2h0KQ0KfQ0KJCQNCg0KYGBge3J9DQpnZXRfdmFyKCJ1X1dtIiwgREIpDQpgYGANCg0KTGEgaW5jZXJ0aWR1bWJyZSBvYnRlbmlkYSBzZXLDoSB1dGlsaXphZGEgcG9zdGVyaW9ybWVudGUgZW4gbGEgcHJvcGFnYWNpw7NuIGRlIGluY2VydGlkdW1icmVzIGRlIGxhIGNvbmNlbnRyYWNpw7NuIGZpbmFsIGRlIEF1Lg0KDQoNCiMgMi4gSW5jZXJ0aWR1bWJyZSBhc29jaWFkYSBhbCB2b2x1bWVuIGRlIGRpbHVjacOzbiAoVmQpDQoNCkxhIGluY2VydGlkdW1icmUgZGVsIHZvbHVtZW4gZGUgZGlsdWNpw7NuIHNlIG9idGllbmUgYSBwYXJ0aXIgZGUgdHJlcyBjb250cmlidWNpb25lcyBwcmluY2lwYWxlczogbGEgaW5jZXJ0aWR1bWJyZSBkZWJpZGEgYSBsYSBjYWxpYnJhY2nDs24gZGVsIG1hdGVyaWFsIHZvbHVtw6l0cmljbywgbGEgaW5jZXJ0aWR1bWJyZSBkZSByZXBldGliaWxpZGFkIGFzb2NpYWRhIGEgbGFzIG1lZGljaW9uZXMgZGVsIGRpc3BlbnNhZG9yIHkgbGEgaW5jZXJ0aWR1bWJyZSBkZWJpZGEgYWwgZWZlY3RvIGRlIGxhIHRlbXBlcmF0dXJhIHNvYnJlIGVsIHZvbHVtZW4uDQoNCi0tLQ0KDQojIyBDb3JyZWNjacOzbiBkZWwgZWZlY3RvIHNpc3RlbcOhdGljbw0KDQpFbCBwcmltZXIgdMOpcm1pbm8gY29ycmVzcG9uZGUgYSBsYSBjb3JyZWNjacOzbiBkZWwgZWZlY3RvIHNpc3RlbcOhdGljbyBhc29jaWFkbyBhIGxhIGV4YWN0aXR1ZCBkZWwgdm9sdW1lbiBwYXJjaWFsIGRlbCBtYXRlcmlhbCB2b2x1bcOpdHJpY28sIGxhIGN1YWwgcmVsYWNpb25hIGVsIHZvbHVtZW4gbm9taW5hbCBkZWwgaW5zdHJ1bWVudG8gY29uIGVsIHZvbHVtZW4gZWZlY3RpdmFtZW50ZSB1dGlsaXphZG8sDQoNClRpcG8gQjogVmFsb3IgYXNpZ25hZG8NCg0KJCQNCkVfdA0KPQ0KXGZyYWN7Vl9ufXtWX3R9DQpcY2RvdA0KRV9uDQokJA0KDQpgYGB7cn0NCmdldF92YXIoIkV0IiwgREIpDQpgYGANCg0KLS0tDQoNCiMjIEluY2VydGlkdW1icmUgZGUgY2FsaWJyYWNpw7NuIGRlbCBhcGFyYXRvDQoNCkxhIGluY2VydGlkdW1icmUgZGUgY2FsaWJyYWNpw7NuIGRlbCB2b2x1bWVuIGRlIGRpbHVjacOzbiBzZSBlc3RpbWEgY29tbzoNCg0KJCQNCnVfe2NhbCxWZH0NCj0NClxmcmFjew0KRV90DQp9DQp7DQoxMDBcc3FydHszfQ0KfQ0KXGNkb3QgVl90DQokJA0KDQpgYGB7cn0NCmdldF92YXIoInVfY2FsX1ZkIiwgREIpDQpgYGANCg0KLS0tDQoNCiMjIENvZWZpY2llbnRlIGRlIHZhcmlhY2nDs24gY29ycmVnaWRvDQoNCkx1ZWdvLCBzZSBjYWxjdWxhIGxhIGluY2VydGlkdW1icmUgZGViaWRhIGEgbGEgcmVwZXRpYmlsaWRhZCBkZWwgdm9sdW1lbiBkb3NpZmljYWRvLg0KDQpFbCBjb2VmaWNpZW50ZSBkZSB2YXJpYWNpw7NuIGFqdXN0YWRvIHBvciBjb25kaWNpb25lcyBleHBlcmltZW50YWxlcyBzZSBjYWxjdWxhIGNvbW86DQoNCiQkDQpDVl90DQo9DQpcZnJhY3tWX259e1ZfdH0NClxjZG90IENWX24NCiQkDQoNCmBgYHtyfQ0KZ2V0X3ZhcigiQ1Z0IiwgREIpDQpgYGANCg0KLS0tDQoNCiMjIEluY2VydGlkdW1icmUgZGUgcmVwZXRpYmlsaWRhZCBkZWwgdm9sdW1lbg0KDQpMYSBpbmNlcnRpZHVtYnJlIGFzb2NpYWRhIGEgbGEgcmVwZXRpYmlsaWRhZCBkZWwgdm9sdW1lbiBlczoNCg0KJCQNCnVfe3IsVmR9DQo9DQpcZnJhY3tDVl90fXsxMDB9DQpcY2RvdCBWX3QNCiQkDQoNCmBgYHtyfQ0KZ2V0X3ZhcigidV9yX1ZkIiwgREIpDQpgYGANCg0KLS0tDQoNCiMjIEluY2VydGlkdW1icmUgcG9yIHRlbXBlcmF0dXJhIGVuIHZvbHVtZW4NCg0KRWwgZWZlY3RvIGRlIGxhIHRlbXBlcmF0dXJhIHNvYnJlIGVsIHZvbHVtZW4gc2UgbW9kZWxhIGNvbW86DQpUaXBvIEINCiQkDQp1X3tULFZkfQ0KPQ0KXGZyYWN7DQpJIFxjZG90IGEgXGNkb3QgVl9kDQp9DQp7DQp0X3tzdH0NCn0NCiQkDQoNCmBgYHtyfQ0KZ2V0X3ZhcigidV9UX1ZkIiwgREIpDQpgYGANCg0KLS0tDQoNCiMjIEluY2VydGlkdW1icmUgZXN0w6FuZGFyIGNvbWJpbmFkYSBkZWwgdm9sdW1lbiBkZSBkaWx1Y2nDs24NCg0KRmluYWxtZW50ZSwgbGEgaW5jZXJ0aWR1bWJyZSBkZWwgdm9sdW1lbiBkZSBkaWx1Y2nDs24gc2Ugb2J0aWVuZSBjb21iaW5hbmRvIHRvZGFzIGxhcyBjb250cmlidWNpb25lczoNCg0KJCQNCnUoVl9kKQ0KPQ0KXHNxcnR7DQp1X3tjYWwsVmR9XnsyfQ0KKw0KdV97cixWZH1eezJ9DQorDQp1X3tULFZkfV57Mn0NCn0NCiQkDQoNCmBgYHtyfQ0KZ2V0X3ZhcigidV9WZCIsIERCKQ0KYGBgDQoNCi0tLQ0KDQpMYSBpbmNlcnRpZHVtYnJlIG9idGVuaWRhIGVuIGVzdGEgc2VjY2nDs24gc2Vyw6EgdXRpbGl6YWRhIHBvc3Rlcmlvcm1lbnRlIGVuIGxhIHByb3BhZ2FjacOzbiBkZSBpbmNlcnRpZHVtYnJlIGRlIGxhIGNvbmNlbnRyYWNpw7NuIGRlIEF1IGVuIGxhIG11ZXN0cmEuDQoNCg0KIyAzLiBQcmVwYXJhY2nDs24gZGUgbGFzIHNvbHVjaW9uZXMgZGUgY2FsaWJyYWNpw7NuIChZQXUpDQoNCkxhcyBzb2x1Y2lvbmVzIGRlIGNhbGlicmFjacOzbiBzZSBwcmVwYXJhbiBhIHBhcnRpciBkZSB1biBtYXRlcmlhbCBkZSByZWZlcmVuY2lhIGNlcnRpZmljYWRvIChNUkMpLCBlbCB2b2x1bWVuIHRyYW5zZmVyaWRvIHkgZWwgdm9sdW1lbiBmaW5hbCBkZSBhZm9yby4gRXN0YXMgc29sdWNpb25lcyBwZXJtaXRlbiBjb25zdHJ1aXIgbGEgY3VydmEgZGUgY2FsaWJyYWNpw7NuIHBhcmEgbGEgZGV0ZXJtaW5hY2nDs24gZGUgQXUuDQoNCi0tLQ0KDQojIyBNb2RlbG8gZGUgbWVkaWNpw7NuDQoNCkxhIGNvbmNlbnRyYWNpw7NuIGRlIGNhZGEgc29sdWNpw7NuIGRlIGNhbGlicmFjacOzbiBzZSBleHByZXNhIGNvbW86DQoNCiQkDQpZX3tBdSxpfQ0KPQ0KXGZyYWN7DQpZX3tNUkN9IFxjZG90IFZfe2FpfQ0KfQ0Kew0KVl97YWZ9DQp9DQokJA0KDQpkb25kZToNCg0KLSBcKFlfe01SQ31cKTogY29uY2VudHJhY2nDs24gZGVsIG1hdGVyaWFsIGRlIHJlZmVyZW5jaWEgY2VydGlmaWNhZG8gIA0KLSBcKFZfe2FpfVwpOiB2b2x1bWVuIHRyYW5zZmVyaWRvIGVuIGNhZGEgbml2ZWwgZGUgY2FsaWJyYWNpw7NuICANCi0gXChWX3thZn1cKTogdm9sdW1lbiBmaW5hbCBkZSBhZm9ybyAgDQoNCi0tLQ0KDQojIyBJbmNlcnRpZHVtYnJlIGRlbCBtYXRlcmlhbCBkZSByZWZlcmVuY2lhIGNlcnRpZmljYWRvICh1KM6zTVJDKSkNCg0KTGEgaW5jZXJ0aWR1bWJyZSBhc29jaWFkYSBhbCBtYXRlcmlhbCBkZSByZWZlcmVuY2lhIGNlcnRpZmljYWRvIHNlIG9idGllbmUgYSBwYXJ0aXIgZGUgbGEgaW5jZXJ0aWR1bWJyZSBleHBhbmRpZGEgcmVwb3J0YWRhIGVuIGVsIGNlcnRpZmljYWRvIGRlIGFuw6FsaXNpcy4gRXN0YSBpbmNlcnRpZHVtYnJlIHNlIHRyYW5zZm9ybWEgYSBpbmNlcnRpZHVtYnJlIGVzdMOhbmRhciBkaXZpZGllbmRvIHBvciBlbCBmYWN0b3IgZGUgY29iZXJ0dXJhIFwoa1wpIGluZGljYWRvIGVuIGRpY2hvIGNlcnRpZmljYWRvOg0KDQokJA0KdV97TVJDfSA9DQpcZnJhY3tVX3tleHB9fXsyfQ0KPQ0KXGZyYWN7MC41fXsyfQ0KPQ0KMC4yNSBcOyBcdGV4dHtwcG19DQokJA0KDQotLS0NCg0KIyMgSW5jZXJ0aWR1bWJyZSBkZWwgbWF0cmF6IGFmb3JhZG8gKHUoVmFmKSkNCg0KTGEgaW5jZXJ0aWR1bWJyZSBhc29jaWFkYSBhbCB2b2x1bWVuIGRlIGFmb3JvIHNlIG9idGllbmUgbWVkaWFudGUgbGEgY29tYmluYWNpw7NuIGN1YWRyw6F0aWNhIGRlIHRyZXMgY29udHJpYnVjaW9uZXMgaW5kZXBlbmRpZW50ZXM6IHJlcGV0aWJpbGlkYWQsIHRlbXBlcmF0dXJhIHkgY2FsaWJyYWNpw7NuIGRlbCBtYXRlcmlhbCB2b2x1bcOpdHJpY286DQoNCiQkDQp1KFZfe2FmfSkNCj0NClxzcXJ0ew0KdV9yKFZfe2FmfSleMg0KKw0KdV9UKFZfe2FmfSleMg0KKw0KdV97Y2FsfShWX3thZn0pXjINCn0NCiQkDQoNCkRvbmRlOg0KDQotIFwodV9yKFZfe2FmfSlcKTogaW5jZXJ0aWR1bWJyZSBkZWJpZGEgYSBsYSByZXBldGliaWxpZGFkIGRlIGxhcyBtZWRpY2lvbmVzICANCi0gXCh1X1QoVl97YWZ9KVwpOiBpbmNlcnRpZHVtYnJlIGRlYmlkYSBhbCBlZmVjdG8gZGUgbGEgdGVtcGVyYXR1cmEgIA0KLSBcKHVfe2NhbH0oVl97YWZ9KVwpOiBpbmNlcnRpZHVtYnJlIGRlYmlkYSBhIGxhIGNhbGlicmFjacOzbiBkZWwgbWF0cmF6ICANCg0KQXBsaWNhbmRvIGxhIGVjdWFjacOzbiBjb3JyZXNwb25kaWVudGUgc2Ugb2J0aWVuZToNCg0KYGBge3J9DQpnZXRfdmFyKCJ1X1ZhZiIsIERCKQ0KYGBgDQoNCiMjIEluY2VydGlkdW1icmUgZGViaWRhIGEgbGEgYWzDrWN1b3RhICh1KFZhaSkpDQoNCkxhIGluY2VydGlkdW1icmUgYXNvY2lhZGEgYWwgdm9sdW1lbiBkZSBhbMOtY3VvdGEgc2UgZXZhbMO6YSBhIHBhcnRpciBkZSBsYSByZXBldGliaWxpZGFkIGRlIGxhcyBtZWRpY2lvbmVzIGRlbCB2b2x1bWVuIHRyYW5zZmVyaWRvIGVuIGNhZGEgbml2ZWwgZGUgY2FsaWJyYWNpw7NuLg0KDQoNCmBgYHtyfQ0KdGFibGFfWWFbLCBjKDEsMildDQpgYGANCg0KDQojIyBDb2VmaWNpZW50ZXMgZGUgc2Vuc2liaWxpZGFkDQoNClBhcmEgYXBsaWNhciBsYSBsZXkgZGUgcHJvcGFnYWNpw7NuIGRlIGluY2VydGlkdW1icmVzIHNlIGNhbGN1bGFuIGxvcyBjb2VmaWNpZW50ZXMgZGUgc2Vuc2liaWxpZGFkOg0KDQokJA0KY18xID0NClxmcmFje1Zfe2FpfX17Vl97YWZ9fQ0KJCQNCg0KJCQNCmNfMiA9DQpcZnJhY3tZX3tNUkN9fXtWX3thZn19DQokJA0KDQokJA0KY18zID0NCi1cZnJhY3tZX3tNUkN9XGNkb3QgVl97YWl9fXtWX3thZn1eezJ9fQ0KJCQNCg0KLS0tDQoNCiMjIEluY2VydGlkdW1icmUgZXN0w6FuZGFyIGNvbWJpbmFkYSBkZSBjYWRhIHB1bnRvIGRlIGNhbGlicmFjacOzbg0KDQpMYSBpbmNlcnRpZHVtYnJlIGFzb2NpYWRhIGEgY2FkYSBzb2x1Y2nDs24gZGUgY2FsaWJyYWNpw7NuIHNlIGNhbGN1bGEgY29tbzoNCg0KJCQNCnVfYyhZX3tBdSxpfSkNCj0NClxzcXJ0ew0KKGNfMSBcY2RvdCB1X3tNUkN9KV4yDQorDQooY18yIFxjZG90IHUoVl97YWl9KSleMg0KKw0KKGNfMyBcY2RvdCB1KFZfe2FmfSkpXjINCn0NCiQkDQoNCmBgYHtyfQ0KdGFibGFfcmVzdWx0YWRvcyA8LSBkYXRhLmZyYW1lKA0KICBZX2NhbCA9IHRhYmxhX1lhJFlfQXUsDQogIHVfY19ZY2FsID0gc3FydCgNCiAgICAoYzEgKiBnKCJ1X01SQyIpKV4yICsNCiAgICAoYzIgKiB0YWJsYV9ZYSR1Y19WYWkpXjIgKw0KICAgIChjMyAqIGcoInVfVmFmIikpXjINCiAgKQ0KKQ0KDQp0YWJsYV9yZXN1bHRhZG9zDQpgYGANCg0KLS0tDQoNCiMjIEluY2VydGlkdW1icmUgY29tYmluYWRhIGdsb2JhbCBkZSBjYWxpYnJhY2nDs24NCg0KTGEgY29udHJpYnVjacOzbiBnbG9iYWwgZGUgdG9kYXMgbGFzIHNvbHVjaW9uZXMgZGUgY2FsaWJyYWNpw7NuIHNlIG9idGllbmUgbWVkaWFudGUgc3VtYSBjdWFkcsOhdGljYToNCg0KJCQNCnVfe2MsWUF1fQ0KPQ0KXHNxcnR7DQpcc3VtX3tpPTF9XntufQ0KdV9jKFlfe0F1LGl9KV4yDQp9DQokJA0KDQpgYGB7cn0NCnVfY19ZQXUNCmBgYA0KDQotLS0NCg0KIyMgSW5jZXJ0aWR1bWJyZSBkZSBwcmVwYXJhY2nDs24gZGUgc29sdWNpb25lcw0KDQpMYSBpbmNlcnRpZHVtYnJlIGV4cGVyaW1lbnRhbCBhc29jaWFkYSBhIGxhIHByZXBhcmFjacOzbiBkZSBjYWRhIHB1bnRvIGRlIGNhbGlicmFjacOzbiBlczoNCg0KYGBge3J9DQp1X2FfWUF1IDwtIHRhYmxhX1lhJHVfWWENCnVfYV9ZQXUNCmBgYA0KDQotLS0NCg0KIyMgSW5jZXJ0aWR1bWJyZSB0b3RhbCBkZSBsYXMgc29sdWNpb25lcyBkZSBjYWxpYnJhY2nDs24NCg0KTGEgaW5jZXJ0aWR1bWJyZSB0b3RhbCBkZSBjYWRhIHB1bnRvIGRlIGNhbGlicmFjacOzbiBzZSBvYnRpZW5lIGNvbWJpbmFuZG8gbGEgY29udHJpYnVjacOzbiBleHBlcmltZW50YWwgeSBsYSBjb250cmlidWNpw7NuIGRlIHByZXBhcmFjacOzbjoNCg0KJCQNCnUoWV97QXV9KQ0KPQ0KXHNxcnR7DQp1X3thLFlBdX1eezJ9DQorDQp1X3tjLFlBdX1eezJ9DQp9DQokJA0KDQpgYGB7cn0NCnRhYmxhX1lfYXUgPC0gZGF0YS5mcmFtZSgNCiAgWV9BdSA9IHRhYmxhX1lhJFlhLA0KICB1X1lfQXUgPSByb3VuZCh1X1lBdSwgNSkNCikNCg0Ka25pdHI6OmthYmxlKHRhYmxhX1lfYXUpDQpgYGANCg0KLS0tDQoNCkxvcyB2YWxvcmVzIG9idGVuaWRvcyBlbiBlc3RhIHNlY2Npw7NuIHNlcsOhbiB1dGlsaXphZG9zIGVuIGxhIHByb3BhZ2FjacOzbiBkZSBpbmNlcnRpZHVtYnJlIHBhcmEgbGEgZGV0ZXJtaW5hY2nDs24gZmluYWwgZGUgQXUgZW4gbGEgbXVlc3RyYS4NCg0KDQojIDQuIERldGVybWluYWNpw7NuIGRlIEF1IGVuIGxhIG11ZXN0cmENCg0KVW5hIHZleiBvYnRlbmlkYXMgbGFzIHNvbHVjaW9uZXMgZGUgY2FsaWJyYWNpw7NuIHkgc3VzIGluY2VydGlkdW1icmVzIGFzb2NpYWRhcywgc2UgcHJvY2VkZSBhIGNhbGN1bGFyIGxhIGNvbmNlbnRyYWNpw7NuIGRlIEF1IGVuIGxhIG11ZXN0cmEuDQoNCi0tLQ0KDQojIyBNb2RlbG8gZGUgbWVkaWNpw7NuDQoNCkxhIGNvbmNlbnRyYWNpw7NuIGRlIEF1IGVuIGxhIG11ZXN0cmEgc2UgY2FsY3VsYSBtZWRpYW50ZToNCg0KJCQNCkNfe0F1fQ0KPQ0KXGZyYWN7DQpZX3tBdX0gXGNkb3QgVl9kDQp9DQp7DQpXX20NCn0NCiQkDQoNCmRvbmRlOg0KDQotIFwoWV97QXV9XCk6IGNvbmNlbnRyYWNpw7NuIG9idGVuaWRhIHBvciBjYWxpYnJhY2nDs24gIA0KLSBcKFZfZFwpOiB2b2x1bWVuIGRlIGRpbHVjacOzbiAgDQotIFwoV19tXCk6IG1hc2EgZGUgbXVlc3RyYSAgDQoNCi0tLQ0KDQojIyBDb2VmaWNpZW50ZXMgZGUgc2Vuc2liaWxpZGFkDQoNCkRlcml2YW5kbyBlbCBtb2RlbG8gZGUgbWVkaWNpw7NuOg0KDQokJA0KY18xID0NClxmcmFje1ZfZH17V19tfQ0KJCQNCg0KJCQNCmNfMiA9DQpcZnJhY3tZX3tBdX19e1dfbX0NCiQkDQoNCiQkDQpjXzMgPQ0KLQ0KXGZyYWN7WV97QXV9XGNkb3QgVl9kfXtXX21eMn0NCiQkDQoNCi0tLQ0KDQojIyBJbmNlcnRpZHVtYnJlIGVzdMOhbmRhciBjb21iaW5hZGEgZGUgQ1xfe0F1fQ0KDQpMYSBpbmNlcnRpZHVtYnJlIGRlIGxhIGNvbmNlbnRyYWNpw7NuIGRlIEF1IHNlIG9idGllbmUgbWVkaWFudGUgcHJvcGFnYWNpw7NuIGRlIGluY2VydGlkdW1icmVzOg0KDQokJA0KdShDX3tBdX0pDQo9DQpcc3FydHsNCihjXzEgXGNkb3QgdShZX3tBdX0pKV4yDQorDQooY18yIFxjZG90IHUoVl9kKSleMg0KKw0KKGNfMyBcY2RvdCB1KFdfbSkpXjINCn0NCiQkDQoNCmBgYHtyfQ0KDQp0YWJsYV9DQV91IDwtIGRhdGEuZnJhbWUoDQogIGBDX0F1IChtZy9rZylgID0gcm91bmQodGFibGFfcmVzdWx0YWRvc18yWywxXSwgNSksDQogIGB1KENfQXUpIChtZy9rZylgID0gcm91bmQodGFibGFfcmVzdWx0YWRvc18yWywyXSwgNSkNCikNCg0Ka25pdHI6OmthYmxlKA0KICB0YWJsYV9DQV91LA0KICBjYXB0aW9uID0gIkluY2VydGlkdW1icmUgZXN0w6FuZGFyIGNvbWJpbmFkYSBlbiBsYSBkZXRlcm1pbmFjacOzbiBkZSBBdSINCikNCg0KYGBgDQoNCg0K