Pour les utilisateurs de R, on commence par charger un certain nombre de modules intéressants.
Contexte
Les 4 catégories de patients
On considère que nos patients sont de 4 types différents, avec deux variables à deux modalités :
- Exposé (\(E\)) vs. Non-Exposé (\(\bar{E}\)) à un facteur environnemental. On peut penser à ces deux catégories dans un cadre épidémio, par exemple avec des patients exposé à l’amiante vs. non-exposés à l’amiante. Ou des patients fumeurs vs. non-fumeurs. Ou toute autre variable dichotomique. Dans un cadre de RCT, on peut s’intéresser aux patients du groupe traité vs. groupe contrôle.
- Malade (\(M\)) vs. Non-Malade (\(\bar{M}\)). Dans les exemples épidémiologiques ci-dessus, la maladie pourrait être un cancer des poumons. Dans le cadre de notre RCT, on pourrait s’intéresser à un aspect de la maladie étudiée, par exemple avoir des douleurs importantes, avoir un arrêt maladie, avoir une rechute…
On a donc des patients qui peuvent être classés dans 4 cases selon leur appartenance à ces modalités. Pour se simplifier les notations, on introduit deux variables aléatoires binaires :
- \(X\) vaut zéro si le patient est non-exposé, et 1 s’il est exposé.
- \(Y\) vaut zéro si le patient est non-malade, et 1 s’il est malade.
Scénario retenu
Pour nous fixer les idées sur un scénario particulier, nous allons considérer le scénario suivant :
- une population de taille totale \(n = 1e6\) patients,
- chaque patient a une probabilité d’être exposé \(\mathbb{P}(X=1) = 0.1\),
- sachant qu’il est exposé, il a une probabilité d’être malade de \(\mathbb{P}(Y = 1 | X = 1) = 0.02\),
- sachant qu’il est non-exposé, il a une probabilité d’être malade de \(\mathbb{P}(Y = 1 | X = 0) = 0.002\).
On peut simuler une réalisation de ce scénario pour simuler toute notre population d’intérêt sous-jacente à l’étude :
n <- 1e6
p_E <- 0.1
p_M_given_E <- 0.02
p_M_given_NE <- 0.002
n_E <- rbinom(1, n, p_E)
n_NE <- n - n_E
n_M_E <- rbinom(1, n_E, p_M_given_E)
n_NM_E <- n_E - n_M_E
n_M_NE <- rbinom(1, n_NE, p_M_given_NE)
n_NM_NE <- n_NE - n_M_NE
lE <- "Exposé\n(X=1)"
lNE <- "Non-Exposé\n(X=0)"
lM <- "Malade\n(Y=1)"
lNM <- "Non-Malade\n(Y=0)"
d <- data.frame(exposition = factor(c(lE, lE, lNE, lNE), levels=c(lNE, lE)),
maladie = as.factor(c(lM, lNM, lM, lNM)),
n = c(n_M_E, n_NM_E, n_M_NE, n_NM_NE))
d %>% ggplot(aes(x = exposition, y = maladie)) +
geom_raster(aes(fill=n)) +
geom_text(aes(label=n)) +
scale_x_discrete(position = "top") +
theme_bw()

Question
La question de recherche générale est toujours similaire :
Y-a-t’il une augmentation/diminution du risque d’être malade lorsqu’un patient est exposé ?
ou de façon équivalente,
Y-a-t’il une association entre le fait d’être malade et le fait d’être exposé ?
Définitions quantifiant une association
On peut répondre à cette question en calculant deux quantités d’intérêt alternatives :
- La Risk Difference (RD),
- Le Risk Ratio (RR).
Risk Difference (RD)
La Risk Difference (RD) parfois aussi appelée Absolute Risk Difference (ARD) ou Attributable Risk (AR) ou encore, selon qu’on la pense positive ou négative, Absolute Risk Reduction (ARR) ou Absolute Risk Increase (ARI), correspond à la définition suivante :
\[
RD = \mathbb{P}(Y = 1 | X = 1) - \mathbb{P}(Y = 1 | X = 0)
\]
Si la quantité est nulle, les patients ont la même probabilité d’être malade sachant qu’ils sont exposés ou non exposés. Si la quantité est positive, les patients ont une plus grande chance d’être malade sachant qu’ils sont exposés. Si la quantité est négative, les patients ont une moins grande chance d’être malade sachant qu’ils sont exposés.
On interprète la valeur en énonçant une phrase telle que “un patient exposé a une probabilité augmentée de RD d’être malade par rapport à un patient non-exposé”.
Sur notre exemple, on a fixé les deux probabilités conditionnelles nécessaires pour calculer RD, qui est donc :
RD <- p_M_given_E - p_M_given_NE
Le résultat vaut 0.018.
Risk Ratio (RR)
Le Risk Ratio (RR), encore appelé Relative Risk (RR aussi), correspond à la définition suivante :
\[
RR = \frac{ \mathbb{P}(Y = 1 | X = 1) }{ \mathbb{P}(Y = 1 | X = 0) }
\]
Si la quantité vaut 1, les patients ont la même probabilité d’être malade sachant qu’ils sont exposés ou non exposés. Si la quantité est supérieure à 1, les patients ont une plus grande chance d’être malade sachant qu’ils sont exposés. Si la quantité est inférieure à 1, les patients ont une moins grande chance d’être malade sachant qu’ils sont exposés.
On interprète la valeur en énonçant une phrase telle que “un patient exposé a une probabilité RR fois supérieure d’être malade par rapport à un patient non-exposé”.
Sur notre exemple, on peut encore calculer RR à partir des valeurs de probabilités conditionnelles fixées, qui est donc :
RR <- p_M_given_E / p_M_given_NE
Le résultat vaut 10.
Différents échantillonnages
Dans la réalité, on ne peut jamais observer notre population complète de 1 millions de patients. On a donc recours à une étude, au cours de laquelle on va échantillonner un certain nombre de patients selon des modalités bien choisies.
Quelque soit l’échantillonnage réalisé, on va toujours remplir un tableau similaire au tableau ci-dessus.
ATTENTION cependant ! On ne pourra pas toujours en faire la même chose !
Echantillon représentatif de la population
La première situation, en terme de simplicité, correspond au cas où on échantillonne nos individus uniformément dans la population générale.
Ce cas de figure est pratique, puisqu’il nous permet d’échantillonner nos individus de façon directement proportionnelle à la loi jointe de \(X\) et \(Y\). Autrement dit, si on échantillonne \(n_S\) individus, le nombre d’individus obtenu dans nos 4 catégories (0,0), (0,1), (1,0), (1,1) correspond à un tirage multinomial dans la loi jointe \((p_{00}, p_{01}, p_{10}, p_{11})\).
Dans le cas de notre scenario de départ, on peut simuler un tel échantillon de la façon suivante :
n_S <- 1e3
p_M_E <- p_E * p_M_given_E
p_M_NE <- (1 - p_E) * p_M_given_NE
p_NM_E <- p_E * (1 - p_M_given_E)
p_NM_NE <- (1 - p_E) * (1- p_M_given_NE)
samp <- rmultinom(1, n_S, prob = c(p_M_E, p_NM_E, p_M_NE, p_NM_NE))
d_S_1 <- data.frame(exposition = factor(c(lE, lE, lNE, lNE), levels=c(lNE, lE)),
maladie = as.factor(c(lM, lNM, lM, lNM)),
n = samp)
p1 <- d_S_1 %>% ggplot(aes(x = exposition, y = maladie)) +
geom_raster(aes(fill=n)) +
geom_text(aes(label=n)) +
scale_x_discrete(position = "top") +
theme_bw()
p1

Toutes nos probabilités d’intérêt peuvent être estimées comme on en a l’intuition, puisque l’échantillon est représentatif de la population. Notamment :
\[
\hat{ p_{\bar{E}\bar{M}} } = n_{\bar{E}\bar{M}} / n_S \\
\hat{ p_{\bar{E}M} } = n_{\bar{E}M} / n_S \\
\hat{ p_{E\bar{M}} } = n_{E\bar{M}} / n_S \\
\hat{ p_{EM} } = n_{EM} / n_S
\]
On obtient donc, en particulier, pour ce qui nous intéresse :
\[
\hat{ RR } = \frac{ \frac{ n_{EM} }{ n_{EM} + n_{E\bar{M}} } }{ \frac{ n_{\bar{E}M} }{ n_{\bar{E}M} + n_{\bar{E}\bar{M}} } }
\]
Ce qui, en R, donne :
RR_S_1 <- ( samp[1] / (samp[1] + samp[2]) ) / (samp[3] / (samp[3] + samp[4]))
On obtient la valeur 11.5. Etant donné la faible prévalence de la maladie, on comprend qu’il faut échantillonner un grand nombre de patients pour réduire la variance de notre estimateur. Ici, avec les effectifs considérés, on a une grande variance, ainsi qu’une chance non-négligeable d’obtenir un estimateur mal défini avec 0 patients au dénominateur.
Echantillon contrôlant l’exposition
C’est ce qu’on fait typiquement dans le domaine des essais cliniques. En contrôlant la quantité de patients \(E\) et \(\bar{E}\), le design expérimental nous fait tirer :
- d’une part les malades et non-malades parmi les \(E\), dans une loi binomiale de paramètre \(n_E, \mathbb{P}(Y=1 | X = 1)\).
- d’autre part les malades et non-malades parmi les \(\bar{E}\), dans une loi binomiale de paramètre \(n_{\bar{E}}, \mathbb{P}(Y=1 | X = 0)\).
Encore une fois, simulons ce que ça donne dans notre scénario :
n_S_2 <- 500
n_M_E <- rbinom(1, n_S_2, p_M_given_E)
n_NM_E <- n_S_2 - n_M_E
n_M_NE <- rbinom(1, n_S_2, p_M_given_NE)
n_NM_NE <- n_S_2 - n_M_NE
d_S_2 <- data.frame(exposition = factor(c(lE, lE, lNE, lNE), levels=c(lNE, lE)),
maladie = as.factor(c(lM, lNM, lM, lNM)),
n = c(n_M_E, n_NM_E, n_M_NE, n_NM_NE))
p2 <- d_S_2 %>% ggplot(aes(x = exposition, y = maladie)) +
geom_raster(aes(fill=n)) +
geom_text(aes(label=n)) +
scale_x_discrete(position = "top") +
theme_bw()
p2

On ne peut donc plus estimer \(\mathbb{P}(X = 0)\) ou \(\mathbb{P}(X = 1)\), mais on peut toujours estimer nos deux quantités d’intérêt, \(\mathbb{P}(Y = 1 | X = 1)\) par \(n_{EM} / (n_{EM} + n_{E\bar{M}})\), et \(\mathbb{P}(Y = 1 | X = 0)\) par \(n_{\bar{E}M} / (n_{\bar{E}M} + n_{\bar{E}\bar{M}})\).
On obtient donc, à nouveau, pour ce qui nous intéresse ici :
\[
\hat{ RR } = \frac{ \frac{ n_{EM} }{ n_{EM} + n_{E\bar{M}} } }{ \frac{ n_{\bar{E}M} }{ n_{\bar{E}M} + n_{\bar{E}\bar{M}} } }
\]
Ce qui, en R, donne :
RR_S_2 <- ( n_M_E / (n_M_E + n_NM_E) ) / ( n_M_NE / (n_M_NE + n_NM_NE))
On obtient la valeur infinie. Etant donné la faible prévalence de la maladie, on comprend qu’il faut échantillonner un grand nombre de patients pour réduire la variance de notre estimateur. Ici, avec les effectifs considérés, on a une grande variance, ainsi qu’une chance non-négligeable d’obtenir un estimateur mal défini avec 0 patients au dénominateur.
Par rapport au cas précédent, on contrôle le nombre d’exposés introduits, ce qui augmente l’effectif du groupe exposé par rapport à un cas où l’exposition serait rare. On augmente donc également la chance de voir des malades dans le groupe exposé, mais on diminue la chance de voir des malades dans le groupe non-exposé.
Echantillon contrôlant la maladie
Aussi appelé échantillonnage “cas-témoin”. Cette fois, on échantillonne un nombre fixé de \(M\) et de \(\bar{M}\). Le design expérimental est tel que, à présent,
- le nombre d’individus \(E\) et \(\bar{E}\) parmi les \(M\) est donné par un tirage binomial parmi \(N_M\) individus.
- le nombre d’individus \(E\) et \(\bar{E}\) parmi les \(\bar{M}\) est donné par un tirage binomial parmi \(N_{\bar{M}}\) individus.
Cette fois, on ne sait plus comment estimer \(\mathbb{P}(Y = 1 | X = 1)\) ni \(\mathbb{P}(Y = 1 | X = 0)\).
On pourrait bien faire l’inverse, c’est à dire estimer \(\mathbb{P}(X = 1 | Y = 1)\) ou \(\mathbb{P}(X = 1 | Y = 0)\), mais ça ne nous aidera pas à calculer RR ou RD.
n_S_3 <- 500
p_M <- p_E * p_M_given_E + (1 - p_E) * p_M_given_NE
p_E_given_M <-p_E * p_M_given_E / p_M
p_E_given_NM <- p_E * (1 - p_M_given_E) / (1 - p_M)
n_M_E <- rbinom(1, n_S_3, p_E_given_M)
n_M_NE <- n_S_3 - n_M_E
n_NM_E <- rbinom(1, n_S_3, p_E_given_NM)
n_NM_NE <- n_S_3 - n_NM_E
d_S_3 <- data.frame(exposition = factor(c(lE, lE, lNE, lNE), levels=c(lNE, lE)),
maladie = as.factor(c(lM, lNM, lM, lNM)),
n = c(n_M_E, n_NM_E, n_M_NE, n_NM_NE))
p3 <- d_S_3 %>% ggplot(aes(x = exposition, y = maladie)) +
geom_raster(aes(fill=n)) +
geom_text(aes(label=n)) +
scale_x_discrete(position = "top") +
theme_bw()
p3

Cet échantillonnage nous permet donc d’observer un nombre suffisant de malades dans le cas d’une maladie ayant une faible prévalence.
Mais que peut-on en faire ?
De l’utilité de l’Odds Ratio (OR)
Si RD et RR sont déjà deux quantités alternatives pour répondre à la même question, à quoi bon en introduire une troisième ?
La réponse est uniquement méthodologique : dans le cas du dernier échantillonnage discuté ci-dessus, il nous est impossible de calculer RR et RD, mais il nous sera toujours possible de calculer OR.
Définition
Passons à la définition, avant de pouvoir en dire plus :
\[
OR = \frac{ \frac{\mathbb{P}(Y = 1 | X = 1)}{ 1 - \mathbb{P}(Y = 1 | X = 1) } }{ \frac{\mathbb{P}(Y = 1 | X = 0)}{ 1 - \mathbb{P}(Y = 1 | X = 0) } }
\]
A première vue, comme pour RD et RR, il nous faut donc être en mesure de calculer la loi conditionnelle de \(Y\) sachant \(X\) pour utiliser la définition ci-dessus.
Sur notre exemple de scénario, on peut calculer sa valeur :
OR <- (p_M_given_E / (1 - p_M_given_E)) / (p_M_given_NE / (1 - p_M_given_NE))
On obtient une valeur de 10.1836735. Soit quelque chose d’assez proche de ce qu’on avait pour RR (souvenez-vous, RR valait 10).
Cas d’une maladie rare
Le problème principal de OR, c’est son interprétation. Le rapport d’odds (cotes, en français), est clairement pas une quantité qui s’interprète aussi facilement que RR. Difficile notamment d’obtenir une phrase simple qui résumé ce qu’on a appris avec OR. Ce pourrait être “la cote associée au fait d’avoir la maladie dans le groupe exposé est OR fois plus grande que la cote associée au fait d’avoir la maladie dans le groupe non-exposé”.
En réalité, un cas nous intéresse particulièrement : le cas d’une maladie rare dans nos deux groupes, c’est à dire avec \(\mathbb{P}(Y = 1 | X = 1)\) et \(\mathbb{P}(Y = 1 | X = 0)\) faibles. Dans ce cas, les dénominateurs des deux cotes sont proches de 1, et il vient tout simplement :
\[
OR \approx \frac{ \mathbb{P}(Y = 1 | X = 1) }{ \mathbb{P}(Y = 1 | X = 0) } = RR
\]
Voilà donc pourquoi, lorsqu’on étudie une maladie rare, on pourra interpréter intuitivement un OR comme un RR. Et voilà pourquoi la valeur qu’on obtient ci-dessus est si proche du RR calculé précédemment.
Symmétrie des deux groupes
Il se trouve qu’une propriété intéressante nous permet également de calculer OR lorsqu’on a accès à la loi conditionnelle de \(X\) sachant \(Y\).
Cette propriété, la voici :
\[
OR = \frac{ \frac{\mathbb{P}(X = 1 | Y = 1)}{ 1 - \mathbb{P}(X = 1 | Y = 1) } }{ \frac{\mathbb{P}(X = 1 | Y = 0)}{ 1 - \mathbb{P}(X = 1 | Y = 0) } }
\]
Pour se convaincre de cette propriété, simplifions les deux fractions. La fraction de définition tout d’abord :
\[
OR
= \frac{ \frac{\mathbb{P}(Y = 1 | X = 1)}{ 1 - \mathbb{P}(Y = 1 | X = 1) } }{ \frac{\mathbb{P}(Y = 1 | X = 0)}{ 1 - \mathbb{P}(Y = 1 | X = 0) } }
= \frac{ \frac{\mathbb{P}(Y = 1 | X = 1)}{ \mathbb{P}(Y = 0 | X = 1) } }{ \frac{\mathbb{P}(Y = 1 | X = 0)}{ \mathbb{P}(Y = 0 | X = 0) } }
= \frac{ \frac{\mathbb{P}(Y = 1 , X = 1)}{ \mathbb{P}(Y = 0 , X = 1) } }{ \frac{\mathbb{P}(Y = 1 , X = 0)}{ \mathbb{P}(Y = 0 , X = 0) } }
= \frac{ \mathbb{P}(Y = 1 , X = 1) \mathbb{P}(Y = 0 , X = 0) }{ \mathbb{P}(Y = 0 , X = 1) \mathbb{P}(Y = 1 , X = 0) }
\]
Et la fraction qui apparaît dans la propriété, à présent : \[
\frac{ \frac{\mathbb{P}(X = 1 | Y = 1)}{ 1 - \mathbb{P}(X = 1 | Y = 1) } }{ \frac{\mathbb{P}(X = 1 | Y = 0)}{ 1 - \mathbb{P}(X = 1 | Y = 0) } }
= \frac{ \frac{\mathbb{P}(X = 1 | Y = 1)}{ \mathbb{P}(X = 0 | Y = 1) } }{ \frac{\mathbb{P}(X = 1 | Y = 0)}{ \mathbb{P}(X = 0 | Y = 0) } }
= \frac{ \frac{\mathbb{P}(X = 1 , Y = 1)}{ \mathbb{P}(X = 0 , Y = 1) } }{ \frac{\mathbb{P}(X = 1 , Y = 0)}{ \mathbb{P}(X = 0 , Y = 0) } }
= \frac{ \mathbb{P}(X = 1 , Y = 1) \mathbb{P}(X = 0 , Y = 0) }{ \mathbb{P}(X = 0 , Y = 1) \mathbb{P}(X = 1 , Y = 0) }
\]
Indépendance des deux événements
Une seconde propriété peut nous aider à interpréter OR : celui-ci vaut 1 si et seulement si \(X\) est indépendante de \(Y\).
En effet, si \(X\) est indépendante de \(Y\), alors par application de la définition, \[
OR
= \frac{ \frac{\mathbb{P}(X = 1 | Y = 1)}{ 1 - \mathbb{P}(X = 1 | Y = 1) } }{ \frac{\mathbb{P}(X = 1 | Y = 0)}{ 1 - \mathbb{P}(X = 1 | Y = 0) } }
= \frac{ \frac{\mathbb{P}(X = 1)}{ 1 - \mathbb{P}(X = 1) } }{ \frac{\mathbb{P}(X = 1)}{ 1 - \mathbb{P}(X = 1) } }
= 1
\]
Et réciproquement, si \(OR = 1\), alors : \[
\frac{\mathbb{P}(X = 1 | Y = 1)}{ \mathbb{P}(X = 0 | Y = 1) }
= \frac{\mathbb{P}(X = 1 | Y = 0)}{ \mathbb{P}(X = 0 | Y = 0) }
= \frac{\mathbb{P}(X = 1)}{ \mathbb{P}(X = 0) }
\]
On peut faire de même symmétriquement pour la loi de \(Y\). On a donc bien indépendance de \(X\) et \(Y\).
Différents cas d’application
Reprenons les trois possibilités d’échantillonnage qu’on avait proposées précedemment.
La première, un échantillonnage représentatif de la population générale, menait au tableau suivant :

La probabilité \(\mathbb{P}(Y = 1 | X = 1)\) s’estime alors simplement en divisant \(n_{EM}\) par \(n_{EM} + n_{E\bar{M}}\). Les normalisations se simplifient et on peut estimer OR simplement avec :
\[
\hat{OR}
= \frac{ \frac{n_{EM}}{n_{E\bar{M}}} }{ \frac{n_{\bar{E}M}}{n_{\bar{E}\bar{M}}} }
= \frac{ n_{EM} n_{\bar{E}\bar{M}} }{ n_{E\bar{M}} n_{\bar{E}M} }
\]
On obtient alors :
OR1 <- d_S_1$n[1] * d_S_1$n[4] / (d_S_1$n[2] * d_S_1$n[3])
Ce qui vaut 11.6329114.
Dans le second cas, avec un échantillonnage contrôlant l’exposition, on avait obtenu le tableau suivant :

La même formule que précédemment s’applique encore, pour la même raison.
OR2 <- d_S_2$n[1] * d_S_2$n[4] / (d_S_2$n[2] * d_S_2$n[3])
Cette fois, l’application numérique nous donne l’infini.
Enfin, passons au troisième cas, l’échantillonnage en contrôlant la quantité de malades. C’était cet échantillonnage qui nous posait problème pour calculer RR. On avait :

la propriété de symmétrie de \(X\) et \(Y\) nous permet encore de calculer quelque chose, en estimant \(\mathbb{P}(X = 1 | Y = 1)\) par \(n_{EM} / (n_{EM} + n_{\bar{E}M})\). Les dénominateurs se simplifient encore, de sorte qu’on retombe sur la même formule que précédemment, une fois de plus.
OR3 <- d_S_3$n[1] * d_S_3$n[4] / (d_S_3$n[2] * d_S_3$n[3])
Cette fois, l’application numérique nous donne 13.0950997.
Ce dernier cas de figure est clairement le plus approprié pour estimer OR, puisqu’on maximise les effectifs de chacune des catégories, ce qui diminue la variance de notre estimateur.
LS0tCnRpdGxlOiAiUmlzay1SYXRpbyAoUlIpIGV0IE9kZHMtUmF0aW8gKE9SKSA6IHVuZSBtaXNlIGF1IHBvaW50IgphdXRob3I6ICJNYXJjIE1hbmNlYXUiCmRhdGU6ICIyMDIzLTA2IgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IFRSVUUKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OiBUUlVFCiAgICBoaWdobGlnaHQ6ICJ0YW5nbyIKICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUKLS0tCgpQb3VyIGxlcyB1dGlsaXNhdGV1cnMgZGUgUiwgb24gY29tbWVuY2UgcGFyIGNoYXJnZXIgdW4gY2VydGFpbiBub21icmUgZGUgbW9kdWxlcyBpbnTDqXJlc3NhbnRzLgoKYGBge3J9CiMgbGUgcGFja2FnZSBtb2Rlcm5lIHN0YW5kYXJkIHBvdXIgbWFuaXB1bGVyIHNlcyBkb25uw6llcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKIyBwb3VyIGZhaXJlIGRlcyBncmFwaGVzIG11bHRpcGxlcwpsaWJyYXJ5KGNvd3Bsb3QpCiMgcG91ciBhZmZpY2hlciBqb2xpbWVudCBsZXMgdGFibGVhdXggZGFucyB1biBkb2N1bWVudCBybWFya2Rvd24KbGlicmFyeShrbml0cikKCiMgcXVlbHF1ZXMgY291bGV1cnMgbWFudWVsbGVzCmJsZXVmb25jZSA8LSAiIzNkNTQ2OCIKYmxldWNsYWlyIDwtICIjNWI3Yzk4Igpyb3NlIDwtICIjZmY1NTU1IgpgYGAKCiMgQ29udGV4dGUKCiMjIExlcyA0IGNhdMOpZ29yaWVzIGRlIHBhdGllbnRzCgpPbiBjb25zaWTDqHJlIHF1ZSBub3MgcGF0aWVudHMgc29udCBkZSA0IHR5cGVzIGRpZmbDqXJlbnRzLCBhdmVjIGRldXggdmFyaWFibGVzIMOgIGRldXggbW9kYWxpdMOpcyA6CgoqIEV4cG9zw6kgKCRFJCkgdnMuIE5vbi1FeHBvc8OpICgkXGJhcntFfSQpIMOgIHVuIGZhY3RldXIgZW52aXJvbm5lbWVudGFsLgogIE9uIHBldXQgcGVuc2VyIMOgIGNlcyBkZXV4IGNhdMOpZ29yaWVzIGRhbnMgdW4gY2FkcmUgw6lwaWTDqW1pbywgcGFyIGV4ZW1wbGUgYXZlYyBkZXMgcGF0aWVudHMgZXhwb3PDqSDDoCBsJ2FtaWFudGUKICB2cy4gbm9uLWV4cG9zw6lzIMOgIGwnYW1pYW50ZS4gT3UgZGVzIHBhdGllbnRzIGZ1bWV1cnMgdnMuIG5vbi1mdW1ldXJzLiBPdSB0b3V0ZSBhdXRyZSB2YXJpYWJsZSBkaWNob3RvbWlxdWUuCiAgRGFucyB1biBjYWRyZSBkZSBSQ1QsIG9uIHBldXQgcydpbnTDqXJlc3NlciBhdXggcGF0aWVudHMgZHUgZ3JvdXBlIHRyYWl0w6kgdnMuIGdyb3VwZSBjb250csO0bGUuCiogTWFsYWRlICgkTSQpIHZzLiBOb24tTWFsYWRlICgkXGJhcntNfSQpLgogIERhbnMgbGVzIGV4ZW1wbGVzIMOpcGlkw6ltaW9sb2dpcXVlcyBjaS1kZXNzdXMsIGxhIG1hbGFkaWUgcG91cnJhaXQgw6p0cmUgdW4gY2FuY2VyIGRlcyBwb3Vtb25zLgogIERhbnMgbGUgY2FkcmUgZGUgbm90cmUgUkNULCBvbiBwb3VycmFpdCBzJ2ludMOpcmVzc2VyIMOgIHVuIGFzcGVjdCBkZSBsYSBtYWxhZGllIMOpdHVkacOpZSwKICBwYXIgZXhlbXBsZSBhdm9pciBkZXMgZG91bGV1cnMgaW1wb3J0YW50ZXMsCiAgYXZvaXIgdW4gYXJyw6p0IG1hbGFkaWUsIGF2b2lyIHVuZSByZWNodXRlLi4uCgpPbiBhIGRvbmMgZGVzIHBhdGllbnRzIHF1aSBwZXV2ZW50IMOqdHJlIGNsYXNzw6lzIGRhbnMgNCBjYXNlcyBzZWxvbiBsZXVyIGFwcGFydGVuYW5jZSDDoCBjZXMgbW9kYWxpdMOpcy4KUG91ciBzZSBzaW1wbGlmaWVyIGxlcyBub3RhdGlvbnMsIG9uIGludHJvZHVpdCBkZXV4IHZhcmlhYmxlcyBhbMOpYXRvaXJlcyBiaW5haXJlcyA6CgoqICRYJCB2YXV0IHrDqXJvIHNpIGxlIHBhdGllbnQgZXN0IG5vbi1leHBvc8OpLCBldCAxIHMnaWwgZXN0IGV4cG9zw6kuCiogJFkkIHZhdXQgesOpcm8gc2kgbGUgcGF0aWVudCBlc3Qgbm9uLW1hbGFkZSwgZXQgMSBzJ2lsIGVzdCBtYWxhZGUuCgojIyBTY8OpbmFyaW8gcmV0ZW51CgpQb3VyIG5vdXMgZml4ZXIgbGVzIGlkw6llcyBzdXIgdW4gc2PDqW5hcmlvIHBhcnRpY3VsaWVyLCBub3VzIGFsbG9ucyBjb25zaWTDqXJlciBsZSBzY8OpbmFyaW8gc3VpdmFudCA6CgoqIHVuZSBwb3B1bGF0aW9uIGRlIHRhaWxsZSB0b3RhbGUgJG4gPSAxZTYkIHBhdGllbnRzLAoqIGNoYXF1ZSBwYXRpZW50IGEgdW5lIHByb2JhYmlsaXTDqSBkJ8OqdHJlIGV4cG9zw6kgJFxtYXRoYmJ7UH0oWD0xKSA9IDAuMSQsCiogc2FjaGFudCBxdSdpbCBlc3QgZXhwb3PDqSwgaWwgYSB1bmUgcHJvYmFiaWxpdMOpIGQnw6p0cmUgbWFsYWRlIGRlICRcbWF0aGJie1B9KFkgPSAxIHwgWCA9IDEpID0gMC4wMiQsCiogc2FjaGFudCBxdSdpbCBlc3Qgbm9uLWV4cG9zw6ksIGlsIGEgdW5lIHByb2JhYmlsaXTDqSBkJ8OqdHJlIG1hbGFkZSBkZSAkXG1hdGhiYntQfShZID0gMSB8IFggPSAwKSA9IDAuMDAyJC4KCk9uIHBldXQgc2ltdWxlciB1bmUgcsOpYWxpc2F0aW9uIGRlIGNlIHNjw6luYXJpbyBwb3VyIHNpbXVsZXIgdG91dGUgbm90cmUgcG9wdWxhdGlvbiBkJ2ludMOpcsOqdApzb3VzLWphY2VudGUgw6AgbCfDqXR1ZGUgOgoKYGBge3J9Cm4gPC0gMWU2CnBfRSA8LSAwLjEKcF9NX2dpdmVuX0UgPC0gMC4wMgpwX01fZ2l2ZW5fTkUgPC0gMC4wMDIKCm5fRSA8LSByYmlub20oMSwgbiwgcF9FKQpuX05FIDwtIG4gLSBuX0UKCm5fTV9FIDwtIHJiaW5vbSgxLCBuX0UsIHBfTV9naXZlbl9FKQpuX05NX0UgPC0gbl9FIC0gbl9NX0UKbl9NX05FIDwtIHJiaW5vbSgxLCBuX05FLCBwX01fZ2l2ZW5fTkUpCm5fTk1fTkUgPC0gbl9ORSAtIG5fTV9ORQoKbEUgPC0gIkV4cG9zw6lcbihYPTEpIgpsTkUgPC0gIk5vbi1FeHBvc8OpXG4oWD0wKSIKbE0gPC0gIk1hbGFkZVxuKFk9MSkiCmxOTSA8LSAiTm9uLU1hbGFkZVxuKFk9MCkiCgpkIDwtIGRhdGEuZnJhbWUoZXhwb3NpdGlvbiA9IGZhY3RvcihjKGxFLCBsRSwgbE5FLCBsTkUpLCBsZXZlbHM9YyhsTkUsIGxFKSksCgkJCQltYWxhZGllID0gYXMuZmFjdG9yKGMobE0sIGxOTSwgbE0sIGxOTSkpLAoJCQkJbiA9IGMobl9NX0UsIG5fTk1fRSwgbl9NX05FLCBuX05NX05FKSkKCmQgJT4lIGdncGxvdChhZXMoeCA9IGV4cG9zaXRpb24sIHkgPSBtYWxhZGllKSkgKwoJZ2VvbV9yYXN0ZXIoYWVzKGZpbGw9bikpICsKCWdlb21fdGV4dChhZXMobGFiZWw9bikpICsKCXNjYWxlX3hfZGlzY3JldGUocG9zaXRpb24gPSAidG9wIikgKwoJdGhlbWVfYncoKQpgYGAKCiMjIFF1ZXN0aW9uCgpMYSBxdWVzdGlvbiBkZSByZWNoZXJjaGUgZ8OpbsOpcmFsZSBlc3QgdG91am91cnMgc2ltaWxhaXJlIDoKCj4gWS1hLXQnaWwgdW5lIGF1Z21lbnRhdGlvbi9kaW1pbnV0aW9uIGR1IHJpc3F1ZSBkJ8OqdHJlIG1hbGFkZSBsb3JzcXUndW4gcGF0aWVudCBlc3QgZXhwb3PDqSA/CgpvdSBkZSBmYcOnb24gw6lxdWl2YWxlbnRlLAoKPiBZLWEtdCdpbCB1bmUgYXNzb2NpYXRpb24gZW50cmUgbGUgZmFpdCBkJ8OqdHJlIG1hbGFkZSBldCBsZSBmYWl0IGQnw6p0cmUgZXhwb3PDqSA/CgoKCiMgRMOpZmluaXRpb25zIHF1YW50aWZpYW50IHVuZSBhc3NvY2lhdGlvbgoKT24gcGV1dCByw6lwb25kcmUgw6AgY2V0dGUgcXVlc3Rpb24gZW4gY2FsY3VsYW50IGRldXggcXVhbnRpdMOpcyBkJ2ludMOpcsOqdCBhbHRlcm5hdGl2ZXMgOgoKKiBMYSAqUmlzayBEaWZmZXJlbmNlIChSRCkqLAoqIExlICpSaXNrIFJhdGlvIChSUikqLgoKIyMgUmlzayBEaWZmZXJlbmNlIChSRCkKCkxhICpSaXNrIERpZmZlcmVuY2UgKFJEKSogcGFyZm9pcyBhdXNzaSBhcHBlbMOpZSAqQWJzb2x1dGUgUmlzayBEaWZmZXJlbmNlIChBUkQpKgpvdSAqQXR0cmlidXRhYmxlIFJpc2sgKEFSKSogb3UgZW5jb3JlLCBzZWxvbiBxdSdvbiBsYSBwZW5zZSBwb3NpdGl2ZSBvdSBuw6lnYXRpdmUsCipBYnNvbHV0ZSBSaXNrIFJlZHVjdGlvbiAoQVJSKSogb3UgKkFic29sdXRlIFJpc2sgSW5jcmVhc2UgKEFSSSkqLApjb3JyZXNwb25kIMOgIGxhIGTDqWZpbml0aW9uIHN1aXZhbnRlIDoKCiQkClJEID0gXG1hdGhiYntQfShZID0gMSB8IFggPSAxKSAtIFxtYXRoYmJ7UH0oWSA9IDEgfCBYID0gMCkKJCQKClNpIGxhIHF1YW50aXTDqSBlc3QgbnVsbGUsIGxlcyBwYXRpZW50cyBvbnQgbGEgbcOqbWUgcHJvYmFiaWxpdMOpIGQnw6p0cmUgbWFsYWRlIHNhY2hhbnQgcXUnaWxzIHNvbnQgZXhwb3PDqXMgb3Ugbm9uIGV4cG9zw6lzLgpTaSBsYSBxdWFudGl0w6kgZXN0IHBvc2l0aXZlLCBsZXMgcGF0aWVudHMgb250IHVuZSBwbHVzIGdyYW5kZSBjaGFuY2UgZCfDqnRyZSBtYWxhZGUgc2FjaGFudCBxdSdpbHMgc29udCBleHBvc8Opcy4KU2kgbGEgcXVhbnRpdMOpIGVzdCBuw6lnYXRpdmUsIGxlcyBwYXRpZW50cyBvbnQgdW5lIG1vaW5zIGdyYW5kZSBjaGFuY2UgZCfDqnRyZSBtYWxhZGUgc2FjaGFudCBxdSdpbHMgc29udCBleHBvc8Opcy4KCk9uIGludGVycHLDqHRlIGxhIHZhbGV1ciBlbiDDqW5vbsOnYW50IHVuZSBwaHJhc2UgdGVsbGUgcXVlIAoidW4gcGF0aWVudCBleHBvc8OpIGEgdW5lIHByb2JhYmlsaXTDqSBhdWdtZW50w6llIGRlIFJEIGQnw6p0cmUgbWFsYWRlIHBhciByYXBwb3J0IMOgIHVuIHBhdGllbnQgbm9uLWV4cG9zw6kiLgoKU3VyIG5vdHJlIGV4ZW1wbGUsIG9uIGEgZml4w6kgbGVzIGRldXggcHJvYmFiaWxpdMOpcyBjb25kaXRpb25uZWxsZXMgbsOpY2Vzc2FpcmVzIHBvdXIgY2FsY3VsZXIgUkQsCnF1aSBlc3QgZG9uYyA6CgpgYGB7cn0KUkQgPC0gcF9NX2dpdmVuX0UgLSBwX01fZ2l2ZW5fTkUKYGBgCgpMZSByw6lzdWx0YXQgdmF1dCBgciBSRGAuCgojIyBSaXNrIFJhdGlvIChSUikKCkxlICpSaXNrIFJhdGlvIChSUikqLCBlbmNvcmUgYXBwZWzDqSAqUmVsYXRpdmUgUmlzayAoUlIgYXVzc2kpKiwKY29ycmVzcG9uZCDDoCBsYSBkw6lmaW5pdGlvbiBzdWl2YW50ZSA6CgokJApSUiA9IFxmcmFjeyBcbWF0aGJie1B9KFkgPSAxIHwgWCA9IDEpIH17IFxtYXRoYmJ7UH0oWSA9IDEgfCBYID0gMCkgfQokJAoKU2kgbGEgcXVhbnRpdMOpIHZhdXQgMSwgbGVzIHBhdGllbnRzIG9udCBsYSBtw6ptZSBwcm9iYWJpbGl0w6kgZCfDqnRyZSBtYWxhZGUgc2FjaGFudCBxdSdpbHMgc29udCBleHBvc8OpcyBvdSBub24gZXhwb3PDqXMuClNpIGxhIHF1YW50aXTDqSBlc3Qgc3Vww6lyaWV1cmUgw6AgMSwgbGVzIHBhdGllbnRzIG9udCB1bmUgcGx1cyBncmFuZGUgY2hhbmNlIGQnw6p0cmUgbWFsYWRlIHNhY2hhbnQgcXUnaWxzIHNvbnQgZXhwb3PDqXMuClNpIGxhIHF1YW50aXTDqSBlc3QgaW5mw6lyaWV1cmUgw6AgMSwgbGVzIHBhdGllbnRzIG9udCB1bmUgbW9pbnMgZ3JhbmRlIGNoYW5jZSBkJ8OqdHJlIG1hbGFkZSBzYWNoYW50IHF1J2lscyBzb250IGV4cG9zw6lzLgoKT24gaW50ZXJwcsOodGUgbGEgdmFsZXVyIGVuIMOpbm9uw6dhbnQgdW5lIHBocmFzZSB0ZWxsZSBxdWUgCiJ1biBwYXRpZW50IGV4cG9zw6kgYSB1bmUgcHJvYmFiaWxpdMOpIFJSIGZvaXMgc3Vww6lyaWV1cmUgZCfDqnRyZSBtYWxhZGUgcGFyIHJhcHBvcnQgw6AgdW4gcGF0aWVudCBub24tZXhwb3PDqSIuCgpTdXIgbm90cmUgZXhlbXBsZSwgb24gcGV1dCBlbmNvcmUgY2FsY3VsZXIgUlIgw6AgcGFydGlyIGRlcyB2YWxldXJzIGRlIHByb2JhYmlsaXTDqXMgY29uZGl0aW9ubmVsbGVzIGZpeMOpZXMsCnF1aSBlc3QgZG9uYyA6CgpgYGB7cn0KUlIgPC0gcF9NX2dpdmVuX0UgLyBwX01fZ2l2ZW5fTkUKYGBgCgpMZSByw6lzdWx0YXQgdmF1dCBgciBSUmAuCgoKIyBEaWZmw6lyZW50cyDDqWNoYW50aWxsb25uYWdlcwoKRGFucyBsYSByw6lhbGl0w6ksIG9uIG5lIHBldXQgamFtYWlzIG9ic2VydmVyIG5vdHJlIHBvcHVsYXRpb24gY29tcGzDqHRlIGRlIDEgbWlsbGlvbnMgZGUgcGF0aWVudHMuCk9uIGEgZG9uYyByZWNvdXJzIMOgIHVuZSDDqXR1ZGUsIGF1IGNvdXJzIGRlIGxhcXVlbGxlIG9uIHZhIMOpY2hhbnRpbGxvbm5lciB1biBjZXJ0YWluIG5vbWJyZSBkZSBwYXRpZW50cwpzZWxvbiBkZXMgbW9kYWxpdMOpcyBiaWVuIGNob2lzaWVzLgoKUXVlbHF1ZSBzb2l0IGwnw6ljaGFudGlsbG9ubmFnZSByw6lhbGlzw6ksIG9uIHZhIHRvdWpvdXJzIHJlbXBsaXIgdW4gdGFibGVhdSBzaW1pbGFpcmUKYXUgdGFibGVhdSBjaS1kZXNzdXMuCgpBVFRFTlRJT04gY2VwZW5kYW50ICEgT24gbmUgcG91cnJhIHBhcyB0b3Vqb3VycyBlbiBmYWlyZSBsYSBtw6ptZSBjaG9zZSAhCgojIyBFY2hhbnRpbGxvbiByZXByw6lzZW50YXRpZiBkZSBsYSBwb3B1bGF0aW9uCgpMYSBwcmVtacOocmUgc2l0dWF0aW9uLCBlbiB0ZXJtZSBkZSBzaW1wbGljaXTDqSwgY29ycmVzcG9uZCBhdSBjYXMgb8O5IG9uIMOpY2hhbnRpbGxvbm5lCm5vcyBpbmRpdmlkdXMgdW5pZm9ybcOpbWVudCBkYW5zIGxhIHBvcHVsYXRpb24gZ8OpbsOpcmFsZS4KCkNlIGNhcyBkZSBmaWd1cmUgZXN0IHByYXRpcXVlLCBwdWlzcXUnaWwgbm91cyBwZXJtZXQgZCfDqWNoYW50aWxsb25uZXIgbm9zIGluZGl2aWR1cwpkZSBmYcOnb24gZGlyZWN0ZW1lbnQgcHJvcG9ydGlvbm5lbGxlIMOgIGxhIGxvaSBqb2ludGUgZGUgJFgkIGV0ICRZJC4KQXV0cmVtZW50IGRpdCwgc2kgb24gw6ljaGFudGlsbG9ubmUgJG5fUyQgaW5kaXZpZHVzLCBsZSBub21icmUgZCdpbmRpdmlkdXMgb2J0ZW51CmRhbnMgbm9zIDQgY2F0w6lnb3JpZXMgKDAsMCksICgwLDEpLCAoMSwwKSwgKDEsMSkgY29ycmVzcG9uZCDDoCB1biB0aXJhZ2UgbXVsdGlub21pYWwgZGFucyBsYSBsb2kKam9pbnRlICQocF97MDB9LCBwX3swMX0sIHBfezEwfSwgcF97MTF9KSQuCgpEYW5zIGxlIGNhcyBkZSBub3RyZSBzY2VuYXJpbyBkZSBkw6lwYXJ0LCBvbiBwZXV0IHNpbXVsZXIgdW4gdGVsIMOpY2hhbnRpbGxvbiBkZSBsYSBmYcOnb24gc3VpdmFudGUgOgoKYGBge3J9Cm5fUyA8LSAxZTMKCnBfTV9FIDwtIHBfRSAqIHBfTV9naXZlbl9FCnBfTV9ORSA8LSAoMSAtIHBfRSkgKiBwX01fZ2l2ZW5fTkUKcF9OTV9FIDwtIHBfRSAqICgxIC0gcF9NX2dpdmVuX0UpCnBfTk1fTkUgPC0gKDEgLSBwX0UpICogKDEtIHBfTV9naXZlbl9ORSkKCnNhbXAgPC0gcm11bHRpbm9tKDEsIG5fUywgcHJvYiA9IGMocF9NX0UsIHBfTk1fRSwgcF9NX05FLCBwX05NX05FKSkKCmRfU18xIDwtIGRhdGEuZnJhbWUoZXhwb3NpdGlvbiA9IGZhY3RvcihjKGxFLCBsRSwgbE5FLCBsTkUpLCBsZXZlbHM9YyhsTkUsIGxFKSksCgkJCQltYWxhZGllID0gYXMuZmFjdG9yKGMobE0sIGxOTSwgbE0sIGxOTSkpLAoJCQkJbiA9IHNhbXApCgpwMSA8LSBkX1NfMSAlPiUgZ2dwbG90KGFlcyh4ID0gZXhwb3NpdGlvbiwgeSA9IG1hbGFkaWUpKSArCglnZW9tX3Jhc3RlcihhZXMoZmlsbD1uKSkgKwoJZ2VvbV90ZXh0KGFlcyhsYWJlbD1uKSkgKwoJc2NhbGVfeF9kaXNjcmV0ZShwb3NpdGlvbiA9ICJ0b3AiKSArCgl0aGVtZV9idygpCnAxCmBgYAoKVG91dGVzIG5vcyBwcm9iYWJpbGl0w6lzIGQnaW50w6lyw6p0IHBldXZlbnQgw6p0cmUgZXN0aW3DqWVzIGNvbW1lIG9uIGVuIGEgbCdpbnR1aXRpb24sCnB1aXNxdWUgbCfDqWNoYW50aWxsb24gZXN0IHJlcHLDqXNlbnRhdGlmIGRlIGxhIHBvcHVsYXRpb24uIE5vdGFtbWVudCA6CgokJApcaGF0eyBwX3tcYmFye0V9XGJhcntNfX0gfSA9IG5fe1xiYXJ7RX1cYmFye019fSAvIG5fUyBcXApcaGF0eyBwX3tcYmFye0V9TX0gfSA9IG5fe1xiYXJ7RX1NfSAvIG5fUyBcXApcaGF0eyBwX3tFXGJhcntNfX0gfSA9IG5fe0VcYmFye019fSAvIG5fUyBcXApcaGF0eyBwX3tFTX0gfSA9IG5fe0VNfSAvIG5fUyAKJCQKCk9uIG9idGllbnQgZG9uYywgZW4gcGFydGljdWxpZXIsIHBvdXIgY2UgcXVpIG5vdXMgaW50w6lyZXNzZSA6CgokJApcaGF0eyBSUiB9ID0gXGZyYWN7IFxmcmFjeyBuX3tFTX0gfXsgbl97RU19ICsgbl97RVxiYXJ7TX19IH0gfXsgXGZyYWN7IG5fe1xiYXJ7RX1NfSB9eyBuX3tcYmFye0V9TX0gKyBuX3tcYmFye0V9XGJhcntNfX0gfSB9CiQkCgpDZSBxdWksIGVuIFIsIGRvbm5lIDoKCmBgYHtyfQpSUl9TXzEgPC0gKCBzYW1wWzFdIC8gKHNhbXBbMV0gKyBzYW1wWzJdKSApIC8gKHNhbXBbM10gLyAoc2FtcFszXSArIHNhbXBbNF0pKQpgYGAKCk9uIG9idGllbnQgbGEgdmFsZXVyIGByIGlmKFJSX1NfMSA9PSBJbmYpeyAiaW5maW5pZSIgfWVsc2V7IFJSX1NfMSB9YC4KRXRhbnQgZG9ubsOpIGxhIGZhaWJsZSBwcsOpdmFsZW5jZSBkZSBsYSBtYWxhZGllLCBvbiBjb21wcmVuZCBxdSdpbCBmYXV0IMOpY2hhbnRpbGxvbm5lcgp1biBncmFuZCBub21icmUgZGUgcGF0aWVudHMgcG91ciByw6lkdWlyZSBsYSB2YXJpYW5jZSBkZSBub3RyZSBlc3RpbWF0ZXVyLgpJY2ksIGF2ZWMgbGVzIGVmZmVjdGlmcyBjb25zaWTDqXLDqXMsIG9uIGEgdW5lIGdyYW5kZSB2YXJpYW5jZSwKYWluc2kgcXUndW5lIGNoYW5jZSBub24tbsOpZ2xpZ2VhYmxlIGQnb2J0ZW5pciB1biBlc3RpbWF0ZXVyIG1hbCBkw6lmaW5pCmF2ZWMgMCBwYXRpZW50cyBhdSBkw6lub21pbmF0ZXVyLgoKCiMjIEVjaGFudGlsbG9uIGNvbnRyw7RsYW50IGwnZXhwb3NpdGlvbgoKQydlc3QgY2UgcXUnb24gZmFpdCB0eXBpcXVlbWVudCBkYW5zIGxlIGRvbWFpbmUgZGVzIGVzc2FpcyBjbGluaXF1ZXMuCkVuIGNvbnRyw7RsYW50IGxhIHF1YW50aXTDqSBkZSBwYXRpZW50cyAkRSQgZXQgJFxiYXJ7RX0kLCBsZSBkZXNpZ24KZXhww6lyaW1lbnRhbCBub3VzIGZhaXQgdGlyZXIgOgoKKiBkJ3VuZSBwYXJ0IGxlcyBtYWxhZGVzIGV0IG5vbi1tYWxhZGVzIHBhcm1pIGxlcyAkRSQsCiAgZGFucyB1bmUgbG9pIGJpbm9taWFsZSBkZSBwYXJhbcOodHJlICRuX0UsIFxtYXRoYmJ7UH0oWT0xIHwgWCA9IDEpJC4KKiBkJ2F1dHJlIHBhcnQgbGVzIG1hbGFkZXMgZXQgbm9uLW1hbGFkZXMgcGFybWkgbGVzICRcYmFye0V9JCwKICBkYW5zIHVuZSBsb2kgYmlub21pYWxlIGRlIHBhcmFtw6h0cmUgJG5fe1xiYXJ7RX19LCBcbWF0aGJie1B9KFk9MSB8IFggPSAwKSQuCgpFbmNvcmUgdW5lIGZvaXMsIHNpbXVsb25zIGNlIHF1ZSDDp2EgZG9ubmUgZGFucyBub3RyZSBzY8OpbmFyaW8gOgoKYGBge3J9Cm5fU18yIDwtIDUwMAoKbl9NX0UgPC0gcmJpbm9tKDEsIG5fU18yLCBwX01fZ2l2ZW5fRSkKbl9OTV9FIDwtIG5fU18yIC0gbl9NX0UKbl9NX05FIDwtIHJiaW5vbSgxLCBuX1NfMiwgcF9NX2dpdmVuX05FKQpuX05NX05FIDwtIG5fU18yIC0gbl9NX05FCgpkX1NfMiA8LSBkYXRhLmZyYW1lKGV4cG9zaXRpb24gPSBmYWN0b3IoYyhsRSwgbEUsIGxORSwgbE5FKSwgbGV2ZWxzPWMobE5FLCBsRSkpLAoJCQkJbWFsYWRpZSA9IGFzLmZhY3RvcihjKGxNLCBsTk0sIGxNLCBsTk0pKSwKCQkJCW4gPSBjKG5fTV9FLCBuX05NX0UsIG5fTV9ORSwgbl9OTV9ORSkpCgpwMiA8LSBkX1NfMiAlPiUgZ2dwbG90KGFlcyh4ID0gZXhwb3NpdGlvbiwgeSA9IG1hbGFkaWUpKSArCglnZW9tX3Jhc3RlcihhZXMoZmlsbD1uKSkgKwoJZ2VvbV90ZXh0KGFlcyhsYWJlbD1uKSkgKwoJc2NhbGVfeF9kaXNjcmV0ZShwb3NpdGlvbiA9ICJ0b3AiKSArCgl0aGVtZV9idygpCnAyCmBgYAoKT24gbmUgcGV1dCBkb25jIHBsdXMgZXN0aW1lciAkXG1hdGhiYntQfShYID0gMCkkIG91ICRcbWF0aGJie1B9KFggPSAxKSQsCm1haXMgb24gcGV1dCB0b3Vqb3VycyBlc3RpbWVyIG5vcyBkZXV4IHF1YW50aXTDqXMgZCdpbnTDqXLDqnQsCiRcbWF0aGJie1B9KFkgPSAxIHwgWCA9IDEpJCBwYXIgJG5fe0VNfSAvIChuX3tFTX0gKyBuX3tFXGJhcntNfX0pJCwgZXQKJFxtYXRoYmJ7UH0oWSA9IDEgfCBYID0gMCkkIHBhciAkbl97XGJhcntFfU19IC8gKG5fe1xiYXJ7RX1NfSArIG5fe1xiYXJ7RX1cYmFye019fSkkLgoKT24gb2J0aWVudCBkb25jLCDDoCBub3V2ZWF1LCBwb3VyIGNlIHF1aSBub3VzIGludMOpcmVzc2UgaWNpIDoKCiQkClxoYXR7IFJSIH0gPSBcZnJhY3sgXGZyYWN7IG5fe0VNfSB9eyBuX3tFTX0gKyBuX3tFXGJhcntNfX0gfSB9eyBcZnJhY3sgbl97XGJhcntFfU19IH17IG5fe1xiYXJ7RX1NfSArIG5fe1xiYXJ7RX1cYmFye019fSB9IH0KJCQKCkNlIHF1aSwgZW4gUiwgZG9ubmUgOgoKYGBge3J9ClJSX1NfMiA8LSAoIG5fTV9FIC8gKG5fTV9FICsgbl9OTV9FKSApIC8gKCBuX01fTkUgLyAobl9NX05FICsgbl9OTV9ORSkpCmBgYAoKT24gb2J0aWVudCBsYSB2YWxldXIgYHIgaWYoUlJfU18yID09IEluZil7ICJpbmZpbmllIiB9ZWxzZXsgUlJfU18yIH1gLgpFdGFudCBkb25uw6kgbGEgZmFpYmxlIHByw6l2YWxlbmNlIGRlIGxhIG1hbGFkaWUsIG9uIGNvbXByZW5kIHF1J2lsIGZhdXQgw6ljaGFudGlsbG9ubmVyCnVuIGdyYW5kIG5vbWJyZSBkZSBwYXRpZW50cyBwb3VyIHLDqWR1aXJlIGxhIHZhcmlhbmNlIGRlIG5vdHJlIGVzdGltYXRldXIuCkljaSwgYXZlYyBsZXMgZWZmZWN0aWZzIGNvbnNpZMOpcsOpcywgb24gYSB1bmUgZ3JhbmRlIHZhcmlhbmNlLAphaW5zaSBxdSd1bmUgY2hhbmNlIG5vbi1uw6lnbGlnZWFibGUgZCdvYnRlbmlyIHVuIGVzdGltYXRldXIgbWFsIGTDqWZpbmkKYXZlYyAwIHBhdGllbnRzIGF1IGTDqW5vbWluYXRldXIuCgpQYXIgcmFwcG9ydCBhdSBjYXMgcHLDqWPDqWRlbnQsIG9uIGNvbnRyw7RsZSBsZSBub21icmUgZCdleHBvc8OpcyBpbnRyb2R1aXRzLCAKY2UgcXVpIGF1Z21lbnRlIGwnZWZmZWN0aWYgZHUgZ3JvdXBlIGV4cG9zw6kgcGFyIHJhcHBvcnQgw6AgdW4gY2FzIG/DuSBsJ2V4cG9zaXRpb24gc2VyYWl0IHJhcmUuCk9uIGF1Z21lbnRlIGRvbmMgw6lnYWxlbWVudCBsYSBjaGFuY2UgZGUgdm9pciBkZXMgbWFsYWRlcyBkYW5zIGxlIGdyb3VwZSBleHBvc8OpLAptYWlzIG9uIGRpbWludWUgbGEgY2hhbmNlIGRlIHZvaXIgZGVzIG1hbGFkZXMgZGFucyBsZSBncm91cGUgbm9uLWV4cG9zw6kuCgoKIyMgRWNoYW50aWxsb24gY29udHLDtGxhbnQgbGEgbWFsYWRpZQoKQXVzc2kgYXBwZWzDqSDDqWNoYW50aWxsb25uYWdlICJjYXMtdMOpbW9pbiIuCkNldHRlIGZvaXMsIG9uIMOpY2hhbnRpbGxvbm5lIHVuIG5vbWJyZSBmaXjDqSBkZSAkTSQgZXQgZGUgJFxiYXJ7TX0kLgpMZSBkZXNpZ24gZXhww6lyaW1lbnRhbCBlc3QgdGVsIHF1ZSwgw6AgcHLDqXNlbnQsCgoqIGxlIG5vbWJyZSBkJ2luZGl2aWR1cyAkRSQgZXQgJFxiYXJ7RX0kIHBhcm1pIGxlcyAkTSQgZXN0IGRvbm7DqSBwYXIgdW4gdGlyYWdlCiAgYmlub21pYWwgcGFybWkgJE5fTSQgaW5kaXZpZHVzLgoqIGxlIG5vbWJyZSBkJ2luZGl2aWR1cyAkRSQgZXQgJFxiYXJ7RX0kIHBhcm1pIGxlcyAkXGJhcntNfSQgZXN0IGRvbm7DqSBwYXIgdW4gdGlyYWdlCiAgYmlub21pYWwgcGFybWkgJE5fe1xiYXJ7TX19JCBpbmRpdmlkdXMuCgpDZXR0ZSBmb2lzLCBvbiBuZSBzYWl0IHBsdXMgY29tbWVudCBlc3RpbWVyICRcbWF0aGJie1B9KFkgPSAxIHwgWCA9IDEpJApuaSAkXG1hdGhiYntQfShZID0gMSB8IFggPSAwKSQuCgpPbiBwb3VycmFpdCBiaWVuIGZhaXJlIGwnaW52ZXJzZSwgYydlc3Qgw6AgZGlyZSBlc3RpbWVyICRcbWF0aGJie1B9KFggPSAxIHwgWSA9IDEpJApvdSAkXG1hdGhiYntQfShYID0gMSB8IFkgPSAwKSQsIG1haXMgw6dhIG5lIG5vdXMgYWlkZXJhIHBhcyDDoCBjYWxjdWxlciBSUiBvdSBSRC4KCmBgYHtyfQpuX1NfMyA8LSA1MDAKCnBfTSA8LSBwX0UgKiBwX01fZ2l2ZW5fRSArICgxIC0gcF9FKSAqIHBfTV9naXZlbl9ORQpwX0VfZ2l2ZW5fTSA8LXBfRSAqIHBfTV9naXZlbl9FIC8gcF9NCnBfRV9naXZlbl9OTSA8LSBwX0UgKiAoMSAtIHBfTV9naXZlbl9FKSAvICgxIC0gcF9NKQoKbl9NX0UgPC0gcmJpbm9tKDEsIG5fU18zLCBwX0VfZ2l2ZW5fTSkKbl9NX05FIDwtIG5fU18zIC0gbl9NX0UKbl9OTV9FIDwtIHJiaW5vbSgxLCBuX1NfMywgcF9FX2dpdmVuX05NKQpuX05NX05FIDwtIG5fU18zIC0gbl9OTV9FCgpkX1NfMyA8LSBkYXRhLmZyYW1lKGV4cG9zaXRpb24gPSBmYWN0b3IoYyhsRSwgbEUsIGxORSwgbE5FKSwgbGV2ZWxzPWMobE5FLCBsRSkpLAoJCQkJbWFsYWRpZSA9IGFzLmZhY3RvcihjKGxNLCBsTk0sIGxNLCBsTk0pKSwKCQkJCW4gPSBjKG5fTV9FLCBuX05NX0UsIG5fTV9ORSwgbl9OTV9ORSkpCgpwMyA8LSBkX1NfMyAlPiUgZ2dwbG90KGFlcyh4ID0gZXhwb3NpdGlvbiwgeSA9IG1hbGFkaWUpKSArCglnZW9tX3Jhc3RlcihhZXMoZmlsbD1uKSkgKwoJZ2VvbV90ZXh0KGFlcyhsYWJlbD1uKSkgKwoJc2NhbGVfeF9kaXNjcmV0ZShwb3NpdGlvbiA9ICJ0b3AiKSArCgl0aGVtZV9idygpCnAzCmBgYAoKQ2V0IMOpY2hhbnRpbGxvbm5hZ2Ugbm91cyBwZXJtZXQgZG9uYyBkJ29ic2VydmVyIHVuIG5vbWJyZSBzdWZmaXNhbnQgZGUgbWFsYWRlcwpkYW5zIGxlIGNhcyBkJ3VuZSBtYWxhZGllIGF5YW50IHVuZSBmYWlibGUgcHLDqXZhbGVuY2UuCgpNYWlzIHF1ZSBwZXV0LW9uIGVuIGZhaXJlID8KCgojIERlIGwndXRpbGl0w6kgZGUgbCdPZGRzIFJhdGlvIChPUikKClNpIFJEIGV0IFJSIHNvbnQgZMOpasOgIGRldXggcXVhbnRpdMOpcyBhbHRlcm5hdGl2ZXMgcG91ciByw6lwb25kcmUgw6AgbGEgbcOqbWUgcXVlc3Rpb24sIMOgIHF1b2kgYm9uIGVuIGludHJvZHVpcmUgdW5lIHRyb2lzacOobWUgPwoKTGEgcsOpcG9uc2UgZXN0IHVuaXF1ZW1lbnQgbcOpdGhvZG9sb2dpcXVlIDogZGFucyBsZSBjYXMgZHUgZGVybmllciDDqWNoYW50aWxsb25uYWdlIGRpc2N1dMOpIGNpLWRlc3N1cywKaWwgbm91cyBlc3QgaW1wb3NzaWJsZSBkZSBjYWxjdWxlciBSUiBldCBSRCwgCm1haXMgaWwgbm91cyBzZXJhIHRvdWpvdXJzIHBvc3NpYmxlIGRlIGNhbGN1bGVyIE9SLgoKIyMgRMOpZmluaXRpb24KClBhc3NvbnMgw6AgbGEgZMOpZmluaXRpb24sIGF2YW50IGRlIHBvdXZvaXIgZW4gZGlyZSBwbHVzIDoKCiQkCk9SID0gXGZyYWN7IFxmcmFje1xtYXRoYmJ7UH0oWSA9IDEgfCBYID0gMSl9eyAxIC0gXG1hdGhiYntQfShZID0gMSB8IFggPSAxKSB9IH17IFxmcmFje1xtYXRoYmJ7UH0oWSA9IDEgfCBYID0gMCl9eyAxIC0gXG1hdGhiYntQfShZID0gMSB8IFggPSAwKSB9IH0KJCQKCkEgcHJlbWnDqHJlIHZ1ZSwgY29tbWUgcG91ciBSRCBldCBSUiwgaWwgbm91cyBmYXV0IGRvbmMgw6p0cmUgZW4gbWVzdXJlIGRlIGNhbGN1bGVyIGxhIGxvaSBjb25kaXRpb25uZWxsZQpkZSAkWSQgc2FjaGFudCAkWCQgcG91ciB1dGlsaXNlciBsYSBkw6lmaW5pdGlvbiBjaS1kZXNzdXMuCgpTdXIgbm90cmUgZXhlbXBsZSBkZSBzY8OpbmFyaW8sIG9uIHBldXQgY2FsY3VsZXIgc2EgdmFsZXVyIDoKCmBgYHtyfQpPUiA8LSAocF9NX2dpdmVuX0UgLyAoMSAtIHBfTV9naXZlbl9FKSkgLyAocF9NX2dpdmVuX05FIC8gKDEgLSBwX01fZ2l2ZW5fTkUpKQpgYGAKCk9uIG9idGllbnQgdW5lIHZhbGV1ciBkZSBgciBPUmAuClNvaXQgcXVlbHF1ZSBjaG9zZSBkJ2Fzc2V6IHByb2NoZSBkZSBjZSBxdSdvbiBhdmFpdCBwb3VyIFJSIChzb3V2ZW5lei12b3VzLCBSUiB2YWxhaXQgYHIgUlJgKS4KCiMjIENhcyBkJ3VuZSBtYWxhZGllIHJhcmUKCkxlIHByb2Jsw6htZSBwcmluY2lwYWwgZGUgT1IsIGMnZXN0IHNvbiBpbnRlcnByw6l0YXRpb24uCkxlIHJhcHBvcnQgZCdvZGRzIChjb3RlcywgZW4gZnJhbsOnYWlzKSwgZXN0IGNsYWlyZW1lbnQgcGFzIHVuZSBxdWFudGl0w6kgcXVpIHMnaW50ZXJwcsOodGUgYXVzc2kgZmFjaWxlbWVudApxdWUgUlIuCkRpZmZpY2lsZSBub3RhbW1lbnQgZCdvYnRlbmlyIHVuZSBwaHJhc2Ugc2ltcGxlIHF1aSByw6lzdW3DqSBjZSBxdSdvbiBhIGFwcHJpcyBhdmVjIE9SLgpDZSBwb3VycmFpdCDDqnRyZSAibGEgY290ZSBhc3NvY2nDqWUgYXUgZmFpdCBkJ2F2b2lyIGxhIG1hbGFkaWUgZGFucyBsZSBncm91cGUgZXhwb3PDqSBlc3QgT1IgZm9pcwpwbHVzIGdyYW5kZSBxdWUgbGEgY290ZSBhc3NvY2nDqWUgYXUgZmFpdCBkJ2F2b2lyIGxhIG1hbGFkaWUgZGFucyBsZSBncm91cGUgbm9uLWV4cG9zw6kiLgoKRW4gcsOpYWxpdMOpLCB1biBjYXMgbm91cyBpbnTDqXJlc3NlIHBhcnRpY3VsacOocmVtZW50IDogbGUgY2FzIGQndW5lIG1hbGFkaWUgcmFyZSBkYW5zIG5vcyBkZXV4IGdyb3VwZXMsCmMnZXN0IMOgIGRpcmUgYXZlYyAkXG1hdGhiYntQfShZID0gMSB8IFggPSAxKSQgZXQgJFxtYXRoYmJ7UH0oWSA9IDEgfCBYID0gMCkkIGZhaWJsZXMuCkRhbnMgY2UgY2FzLCBsZXMgZMOpbm9taW5hdGV1cnMgZGVzIGRldXggY290ZXMgc29udCBwcm9jaGVzIGRlIDEsIGV0IGlsIHZpZW50IHRvdXQgc2ltcGxlbWVudCA6CgokJApPUiBcYXBwcm94IFxmcmFjeyBcbWF0aGJie1B9KFkgPSAxIHwgWCA9IDEpIH17IFxtYXRoYmJ7UH0oWSA9IDEgfCBYID0gMCkgfSA9IFJSCiQkCgpWb2lsw6AgZG9uYyBwb3VycXVvaSwgbG9yc3F1J29uIMOpdHVkaWUgdW5lIG1hbGFkaWUgcmFyZSwgb24gcG91cnJhIGludGVycHLDqXRlciBpbnR1aXRpdmVtZW50IHVuIE9SIGNvbW1lIHVuIFJSLiAKRXQgdm9pbMOgIHBvdXJxdW9pIGxhIHZhbGV1ciBxdSdvbiBvYnRpZW50IGNpLWRlc3N1cyBlc3Qgc2kgcHJvY2hlIGR1IFJSIGNhbGN1bMOpIHByw6ljw6lkZW1tZW50LgoKIyMgU3ltbcOpdHJpZSBkZXMgZGV1eCBncm91cGVzCgpJbCBzZSB0cm91dmUgcXUndW5lIHByb3ByacOpdMOpIGludMOpcmVzc2FudGUgbm91cyBwZXJtZXQgw6lnYWxlbWVudCBkZSBjYWxjdWxlciBPUgpsb3JzcXUnb24gYSBhY2PDqHMgw6AgbGEgbG9pIGNvbmRpdGlvbm5lbGxlIGRlICRYJCBzYWNoYW50ICRZJC4KCkNldHRlIHByb3ByacOpdMOpLCBsYSB2b2ljaSA6CgokJApPUiA9IFxmcmFjeyBcZnJhY3tcbWF0aGJie1B9KFggPSAxIHwgWSA9IDEpfXsgMSAtIFxtYXRoYmJ7UH0oWCA9IDEgfCBZID0gMSkgfSB9eyBcZnJhY3tcbWF0aGJie1B9KFggPSAxIHwgWSA9IDApfXsgMSAtIFxtYXRoYmJ7UH0oWCA9IDEgfCBZID0gMCkgfSB9CiQkCgpQb3VyIHNlIGNvbnZhaW5jcmUgZGUgY2V0dGUgcHJvcHJpw6l0w6ksIHNpbXBsaWZpb25zIGxlcyBkZXV4IGZyYWN0aW9ucy4KTGEgZnJhY3Rpb24gZGUgZMOpZmluaXRpb24gdG91dCBkJ2Fib3JkIDoKCiQkCk9SIAo9IFxmcmFjeyBcZnJhY3tcbWF0aGJie1B9KFkgPSAxIHwgWCA9IDEpfXsgMSAtIFxtYXRoYmJ7UH0oWSA9IDEgfCBYID0gMSkgfSB9eyBcZnJhY3tcbWF0aGJie1B9KFkgPSAxIHwgWCA9IDApfXsgMSAtIFxtYXRoYmJ7UH0oWSA9IDEgfCBYID0gMCkgfSB9Cj0gXGZyYWN7IFxmcmFje1xtYXRoYmJ7UH0oWSA9IDEgfCBYID0gMSl9eyBcbWF0aGJie1B9KFkgPSAwIHwgWCA9IDEpIH0gfXsgXGZyYWN7XG1hdGhiYntQfShZID0gMSB8IFggPSAwKX17IFxtYXRoYmJ7UH0oWSA9IDAgfCBYID0gMCkgfSB9Cj0gXGZyYWN7IFxmcmFje1xtYXRoYmJ7UH0oWSA9IDEgLCBYID0gMSl9eyBcbWF0aGJie1B9KFkgPSAwICwgWCA9IDEpIH0gfXsgXGZyYWN7XG1hdGhiYntQfShZID0gMSAsIFggPSAwKX17IFxtYXRoYmJ7UH0oWSA9IDAgLCBYID0gMCkgfSB9Cj0gXGZyYWN7IFxtYXRoYmJ7UH0oWSA9IDEgLCBYID0gMSkgXG1hdGhiYntQfShZID0gMCAsIFggPSAwKSB9eyBcbWF0aGJie1B9KFkgPSAwICwgWCA9IDEpIFxtYXRoYmJ7UH0oWSA9IDEgLCBYID0gMCkgfQokJAoKRXQgbGEgZnJhY3Rpb24gcXVpIGFwcGFyYcOudCBkYW5zIGxhIHByb3ByacOpdMOpLCDDoCBwcsOpc2VudCA6CiQkClxmcmFjeyBcZnJhY3tcbWF0aGJie1B9KFggPSAxIHwgWSA9IDEpfXsgMSAtIFxtYXRoYmJ7UH0oWCA9IDEgfCBZID0gMSkgfSB9eyBcZnJhY3tcbWF0aGJie1B9KFggPSAxIHwgWSA9IDApfXsgMSAtIFxtYXRoYmJ7UH0oWCA9IDEgfCBZID0gMCkgfSB9Cj0gXGZyYWN7IFxmcmFje1xtYXRoYmJ7UH0oWCA9IDEgfCBZID0gMSl9eyBcbWF0aGJie1B9KFggPSAwIHwgWSA9IDEpIH0gfXsgXGZyYWN7XG1hdGhiYntQfShYID0gMSB8IFkgPSAwKX17IFxtYXRoYmJ7UH0oWCA9IDAgfCBZID0gMCkgfSB9Cj0gXGZyYWN7IFxmcmFje1xtYXRoYmJ7UH0oWCA9IDEgLCBZID0gMSl9eyBcbWF0aGJie1B9KFggPSAwICwgWSA9IDEpIH0gfXsgXGZyYWN7XG1hdGhiYntQfShYID0gMSAsIFkgPSAwKX17IFxtYXRoYmJ7UH0oWCA9IDAgLCBZID0gMCkgfSB9Cj0gXGZyYWN7IFxtYXRoYmJ7UH0oWCA9IDEgLCBZID0gMSkgXG1hdGhiYntQfShYID0gMCAsIFkgPSAwKSB9eyBcbWF0aGJie1B9KFggPSAwICwgWSA9IDEpIFxtYXRoYmJ7UH0oWCA9IDEgLCBZID0gMCkgfQokJAoKIyMgSW5kw6lwZW5kYW5jZSBkZXMgZGV1eCDDqXbDqW5lbWVudHMKClVuZSBzZWNvbmRlIHByb3ByacOpdMOpIHBldXQgbm91cyBhaWRlciDDoCBpbnRlcnByw6l0ZXIgT1IgOiAKY2VsdWktY2kgdmF1dCAxIHNpIGV0IHNldWxlbWVudCBzaSAkWCQgZXN0IGluZMOpcGVuZGFudGUgZGUgJFkkLgoKRW4gZWZmZXQsIHNpICRYJCBlc3QgaW5kw6lwZW5kYW50ZSBkZSAkWSQsIGFsb3JzIHBhciBhcHBsaWNhdGlvbiBkZSBsYSBkw6lmaW5pdGlvbiwKJCQKT1IgCj0gXGZyYWN7IFxmcmFje1xtYXRoYmJ7UH0oWCA9IDEgfCBZID0gMSl9eyAxIC0gXG1hdGhiYntQfShYID0gMSB8IFkgPSAxKSB9IH17IFxmcmFje1xtYXRoYmJ7UH0oWCA9IDEgfCBZID0gMCl9eyAxIC0gXG1hdGhiYntQfShYID0gMSB8IFkgPSAwKSB9IH0KPSBcZnJhY3sgXGZyYWN7XG1hdGhiYntQfShYID0gMSl9eyAxIC0gXG1hdGhiYntQfShYID0gMSkgfSB9eyBcZnJhY3tcbWF0aGJie1B9KFggPSAxKX17IDEgLSBcbWF0aGJie1B9KFggPSAxKSB9IH0KPSAxCiQkCgpFdCByw6ljaXByb3F1ZW1lbnQsIHNpICRPUiA9IDEkLCBhbG9ycyA6CiQkClxmcmFje1xtYXRoYmJ7UH0oWCA9IDEgfCBZID0gMSl9eyBcbWF0aGJie1B9KFggPSAwIHwgWSA9IDEpIH0gCj0gXGZyYWN7XG1hdGhiYntQfShYID0gMSB8IFkgPSAwKX17IFxtYXRoYmJ7UH0oWCA9IDAgfCBZID0gMCkgfSAKPSBcZnJhY3tcbWF0aGJie1B9KFggPSAxKX17IFxtYXRoYmJ7UH0oWCA9IDApIH0gCiQkCgpPbiBwZXV0IGZhaXJlIGRlIG3Dqm1lIHN5bW3DqXRyaXF1ZW1lbnQgcG91ciBsYSBsb2kgZGUgJFkkLiAKT24gYSBkb25jIGJpZW4gaW5kw6lwZW5kYW5jZSBkZSAkWCQgZXQgJFkkLgoKIyMgRGlmZsOpcmVudHMgY2FzIGQnYXBwbGljYXRpb24KClJlcHJlbm9ucyBsZXMgdHJvaXMgcG9zc2liaWxpdMOpcyBkJ8OpY2hhbnRpbGxvbm5hZ2UgcXUnb24gYXZhaXQgcHJvcG9zw6llcyBwcsOpY2VkZW1tZW50LgoKTGEgcHJlbWnDqHJlLCB1biDDqWNoYW50aWxsb25uYWdlIHJlcHLDqXNlbnRhdGlmIGRlIGxhIHBvcHVsYXRpb24gZ8OpbsOpcmFsZSwKbWVuYWl0IGF1IHRhYmxlYXUgc3VpdmFudCA6CgpgYGB7cn0KcDEKYGBgCgpMYSBwcm9iYWJpbGl0w6kgJFxtYXRoYmJ7UH0oWSA9IDEgfCBYID0gMSkkIHMnZXN0aW1lIGFsb3JzIHNpbXBsZW1lbnQgZW4gZGl2aXNhbnQgJG5fe0VNfSQgcGFyICRuX3tFTX0gKyBuX3tFXGJhcntNfX0kLgpMZXMgbm9ybWFsaXNhdGlvbnMgc2Ugc2ltcGxpZmllbnQgZXQgb24gcGV1dCBlc3RpbWVyIE9SIHNpbXBsZW1lbnQgYXZlYyA6CgokJApcaGF0e09SfSAKPSBcZnJhY3sgXGZyYWN7bl97RU19fXtuX3tFXGJhcntNfX19IH17IFxmcmFje25fe1xiYXJ7RX1NfX17bl97XGJhcntFfVxiYXJ7TX19fSB9Cj0gXGZyYWN7IG5fe0VNfSBuX3tcYmFye0V9XGJhcntNfX0gfXsgbl97RVxiYXJ7TX19IG5fe1xiYXJ7RX1NfSB9CiQkCgpPbiBvYnRpZW50IGFsb3JzIDoKCmBgYHtyfQpPUjEgPC0gZF9TXzEkblsxXSAqIGRfU18xJG5bNF0gLyAoZF9TXzEkblsyXSAqIGRfU18xJG5bM10pCmBgYAoKQ2UgcXVpIHZhdXQgCmByIGlmKE9SMSA9PSBJbmYpeyAibCdpbmZpbmkiIH1lbHNleyBPUjEgfWAuCgpEYW5zIGxlIHNlY29uZCBjYXMsIGF2ZWMgdW4gw6ljaGFudGlsbG9ubmFnZSBjb250csO0bGFudCBsJ2V4cG9zaXRpb24sIG9uIGF2YWl0IG9idGVudQpsZSB0YWJsZWF1IHN1aXZhbnQgOgoKYGBge3J9CnAyCmBgYAoKTGEgbcOqbWUgZm9ybXVsZSBxdWUgcHLDqWPDqWRlbW1lbnQgcydhcHBsaXF1ZSBlbmNvcmUsIHBvdXIgbGEgbcOqbWUgcmFpc29uLgoKYGBge3J9Ck9SMiA8LSBkX1NfMiRuWzFdICogZF9TXzIkbls0XSAvIChkX1NfMiRuWzJdICogZF9TXzIkblszXSkKYGBgCgpDZXR0ZSBmb2lzLCBsJ2FwcGxpY2F0aW9uIG51bcOpcmlxdWUgbm91cyBkb25uZSAKYHIgaWYoT1IyID09IEluZil7ICJsJ2luZmluaSIgfWVsc2V7IE9SMiB9YC4KCkVuZmluLCBwYXNzb25zIGF1IHRyb2lzacOobWUgY2FzLCBsJ8OpY2hhbnRpbGxvbm5hZ2UgZW4gY29udHLDtGxhbnQgbGEgcXVhbnRpdMOpIGRlIG1hbGFkZXMuCkMnw6l0YWl0IGNldCDDqWNoYW50aWxsb25uYWdlIHF1aSBub3VzIHBvc2FpdCBwcm9ibMOobWUgcG91ciBjYWxjdWxlciBSUi4KT24gYXZhaXQgOgoKYGBge3J9CnAzCmBgYAoKbGEgcHJvcHJpw6l0w6kgZGUgc3ltbcOpdHJpZSBkZSAkWCQgZXQgJFkkIG5vdXMgcGVybWV0CmVuY29yZSBkZSBjYWxjdWxlciBxdWVscXVlIGNob3NlLCBlbiBlc3RpbWFudAokXG1hdGhiYntQfShYID0gMSB8IFkgPSAxKSQgcGFyICRuX3tFTX0gLyAobl97RU19ICsgbl97XGJhcntFfU19KSQuCkxlcyBkw6lub21pbmF0ZXVycyBzZSBzaW1wbGlmaWVudCBlbmNvcmUsIGRlIHNvcnRlIHF1J29uIHJldG9tYmUKc3VyIGxhIG3Dqm1lIGZvcm11bGUgcXVlIHByw6ljw6lkZW1tZW50LCB1bmUgZm9pcyBkZSBwbHVzLgoKYGBge3J9Ck9SMyA8LSBkX1NfMyRuWzFdICogZF9TXzMkbls0XSAvIChkX1NfMyRuWzJdICogZF9TXzMkblszXSkKYGBgCgpDZXR0ZSBmb2lzLCBsJ2FwcGxpY2F0aW9uIG51bcOpcmlxdWUgbm91cyBkb25uZSAKYHIgaWYoT1IzID09IEluZil7ICJsJ2luZmluaSIgfWVsc2V7IE9SMyB9YC4KCkNlIGRlcm5pZXIgY2FzIGRlIGZpZ3VyZSBlc3QgY2xhaXJlbWVudCBsZSBwbHVzIGFwcHJvcHJpw6kgcG91ciBlc3RpbWVyCk9SLCBwdWlzcXUnb24gbWF4aW1pc2UgbGVzIGVmZmVjdGlmcyBkZSBjaGFjdW5lIGRlcyBjYXTDqWdvcmllcywgY2UgcXVpIGRpbWludWUKbGEgdmFyaWFuY2UgZGUgbm90cmUgZXN0aW1hdGV1ci4KCgoK