Commençons par charger quelques modules utiles.

Le test du \(\chi^2\) (lire “ki deux”) est central dans la culture statistique du fait de ses très nombreuses utilisations. Il peut en effet servir :

  1. à tester l’ajustement d’une distribution discrète à une loi donnée
  2. à tester l’ajustement d’une distribution discrète à une famille de lois donnée (paramétrée)
  3. à tester l’indépendance de deux distributions appariées
  4. à tester l’homogénéité de plusieurs échantillons de lois discrètes.

Par ailleurs, bien que ces 4 points d’utilisation concernent normalement des variables prenant des valeurs dans un ensemble discret et fini, des tests du \(\chi^2\) sont aussi régulièrement effectués pour répondre aux même questions sur des variables prenant des valeurs dans un ensemble continu, auquel cas une première étape de discrétisation des données sera effectuée.

L’objectif de ce cours est de comprendre les grands principes théoriques sous-jacents au test du \(\chi^2\), et d’être capable de réaliser des tests avec R dans les 4 cas qui nous intéressent. Commençons par le plus simple : le test d’ajustement à une distribution discrète.

Ajustement à une distribution discrète

Contexte formalisé

On dispose d’un échantillon de \(n\) valeurs observées \((X_1, X_2, ..., X_n)\) qui prennent leurs valeurs dans un ensemble discret de \(d\) valeurs \(\mathcal{X} = \{ x_1, x_2, ..., x_d \}\).

On considère que nos \(n\) observations proviennent de variables aléatoires indépendantes et identiquement distribuées dans une même loi qu’on note \(p = (p_1, p_2, ..., p_d)\), où \(p_i\) est la probabilité que la variable aléatoire prenne la valeur \(x_i\).

Par ailleurs, on dispose d’une loi de référence sur \(\mathcal{X}\) qu’on appelle \(p^\text{ref}\), à laquelle on souhaiterait comparer notre échantillon.
Plus précisément, on souhaite tester :

  • H0 : \(p = p^\text{ref}\)
  • H1 : \(p \neq p^\text{ref}\).

Contexte pratique

On simule un “toy dataset” très simple inspiré d’essais cliniques, contenant deux variables discrètes uniquement. On maîtrise ainsi la loi génératrice de nos variables :

  • le sexe est tiré dans une loi uniforme sur l’ensemble \(\{ F, M \}\),
  • le groupe est tiré dans une loi à valeurs dans \(\{ \text{Control, Treatment1, Treatment2} \}\), qui place la même probabilité de 0.3 sur les deux groupes traitement et une masse de probabilité de 0.4 sur le groupe contrôle.

Plusieurs questions peuvent se poser autour de ce dataset :

  • est-ce que les sexes sont équilibrés ? autrement dit, est-ce que la loi génératrice des sexes est \(p^\text{ref} = (0.5, 0.5)\) ?
  • est-ce que les groupes sont équilibrés ? i.e. est-ce que la loi génératrice est uniforme sur nos trois groupes ?

Ce que dit la théorie

On peut estimer chacun des \(p_i\) par la fréquence empirique \(\hat{p}_i\) de l’observation \(x_i\), c’est à dire : \[ \hat{p}_i = \frac{1}{n} \sum_{k=1}^n \delta_{X_k = x_i} \] où on note \(\delta_{X_k = x_i}\) la variable indicatrice de l’événement \(X_k = x_i\), c’est à dire la variable valant 1 lorsque \(X_k = x_i\) et 0 sinon.

On souhaite ensuite mesurer une certaine idée de “distance” entre la distribution empiriquement observée \(\hat{p}\) et celle de référence \(p^\text{ref}\). Cette distance est appelée “pseudo-distance du \(\chi^2\)”, et elle s’exprime comme : \[ D^2_n( \hat{p}, p^\text{ref} ) = n \sum_{i=1}^d \frac{\left(\hat{p}_i - p^\text{ref}_i \right)^2}{p^\text{ref}_i} \]

Un théorème nous assure alors que

  • sous H0, \(D^2_n ( \hat{p}, p^\text{ref} )\) tend en loi vers une distribution du \(\chi^2\) à \(d-1\) degrés de liberté.
  • sous H1, \(D^2_n ( \hat{p}, p^\text{ref} )\) tend vers l’infini presque sûrement.

Construction du test

Ce théorème est un théorème asymptotique : on ne peut donc l’appliquer pour effectuer notre test sur de vraies données que pour de grands effectifs \(n\) ! On demande aussi généralement à ce que \(n p^\text{ref}_i\) soit au moins égal à 5 pour tout \(i\).

Si ces conditions d’effectifs suffisants sont respectées, le test fonctionne ainsi :

  • la statistique de test \(D^2_n( \hat{p}, p^\text{ref} )\) est calculée,
  • on fixe l’erreur de premier ordre \(\alpha\) acceptable,
  • on calcule \(q_{1-\alpha}\), le quantile de la loi du \(\chi^2\) à \(d-1\) degrés de liberté de niveau \(1-\alpha\),
  • on rejette H0 si \(D^2_n( \hat{p}, p^\text{ref} ) > q_{1-\alpha}\).

Intuitivement, on mesure une pseudo-distance entre notre distribution empirique et notre distribution de référence, et on rejette l’hypothèse nulle d’égalité des deux distributions lorsque cette pseudo-distance devient trop grande.

Et avec R ? version courte

En une ligne très simple, est-ce que le sexe est distribué de façon uniforme ?

## 
##  F  M 
## 58 42
## 
##  Chi-squared test for given probabilities
## 
## data:  table(d$sex)
## X-squared = 2.56, df = 1, p-value = 0.1096

La lecture du compte-rendu de R présente :

  • la valeur de la statistique de test \(D^2_n\) qui est appelée X-squared ici,
  • le nombre de degrés de liberté (df pour degrees of freedom) de la loi du \(\chi^2\) que suit notre statistique de test sous H0,
  • et, très important, la p-value, qui est la probabilité que la statistique de test soit au moins aussi extrême qu’observée, sous H0.

Si la p-value est inférieure au risque de premier espèce \(\alpha\) qu’on s’est fixé, on s’autorise à rejeter H0.

Ici, la p-value est grande, on conserve donc H0 par défaut.

Et nos groupes alors, sont-ils distribués selon une loi uniforme, associant une probabilité \((\frac{1}{3}, \frac{1}{3}, \frac{1}{3})\) à chacun des trois groupes ? Pour gagner encore du temps, lorsqu’on compare notre distribution à une loi de référence uniforme, il n’est pas nécessaire de spécifier à R la loi de référence : implicitement, elle est uniforme.

## 
##    Control Treatment1 Treatment2 
##         30         29         41
## 
##  Chi-squared test for given probabilities
## 
## data:  table(d$group)
## X-squared = 2.66, df = 2, p-value = 0.2645

La p-value est ici faible. Selon les domaines scientifiques, l’erreur de première espèce qu’on s’autorise à commettre peut varier grandement. Dans le domaine des essais cliniques, les valeurs classiquement utilisées peuvent être 0.05, 0.025 ou encore 0.001, selon les conséquences qui sont associées au fait de rejeter H0 alors qu’on était sous H0.

Pour finir, peut-être était-il écrit au protocole que 40% des inclusions concerneraient le groupe contrôle, et que le reste serait réparti de façon uniforme entre les deux groupes traitement. Si on souhaite vérifier l’adéquation avec cette loi de référence (non-uniforme cette fois-ci), vous l’aurez deviné, la syntaxe est tout simplement :

## 
##  Chi-squared test for given probabilities
## 
## data:  table(d$group)
## X-squared = 6.5667, df = 2, p-value = 0.0375

Cette fois-ci, la p-value est forte, et on conserve H0. Ces trois tests étaient donc bien cohérents avec la façon dont les données ont été simulées.

Et avec R ? version longue

Une bonne façon de se convaincre que tout ça fonctionne bien consiste à calculer manuellement les différentes quantités d’intérêt, et surtout à représenter graphiquement la statistique de test et la loi du \(\chi^2\) que notre statistique de test est censée suivre sous H0.

## 
##    Control Treatment1 Treatment2 
##       0.30       0.29       0.41
## [1] "La statistique de test du chi2 est 2.66"

Sur nos deux graphes, la ligne noire pointillée correspond à la valeur de la statistique de test observée.

Sur le graphe de gauche, représentant la densité de la loi du \(\chi^2\) que suit notre statistique de test sous H0, la p-value correspond à l’aire coloriée en rouge : la probabilité que la statistique de test soit au moins aussi grande qu’observée.

Sur le graphe de gauche, représentant la probabilité que la statistique de test soit supérieure à une valeur donnée, la p-value se lit directement à l’intersection entre la ligne pointillée rouge et l’axe des ordonnées.

Puisqu’on dispose entre les mains toute la puissance de calcul d’un ordinateur moderne, on peut aussi se demander à quel point l’hypothèse asymptotique (\(n\) grand) est vérifiée pour \(n = 100\) comme on l’avait ici. On va pour cela simuler \(10^5\) datasets sous H0, et calculer pour chacun la valeur de la statistique de test. On pourra ensuite comparer visuellement la distribution empiriquement observée de nos statistiques de tests avec la distribution asymptotique du \(\chi^2\).

Pas trop mal, visuellement ! L’adéquation devrait être d’autant meilleure que \(n\) est grand dans vos simulations.

Nous savons à présent comparer une distribution empirique discrète à une distribution de référence fixée. Mais que se passe-t-il si on souhaite comparer notre distribution empirique à une famille paramétrée de distributions ?

Ajustement à une famille de loi paramétrée

Contexte formalisé

Comme précédemment, on dispose d’un échantillon \(X\) de taille \(n\), tiré dans une loi \(p\) inconnue prenant des valeurs dans un ensemble fini \(\mathcal{X}\) de \(d\) valeurs.

Cependant, plutôt que de comparer à une distribution de référence fixée \(p^\text{ref}\), on souhaite à présent savoir si notre échantillon a été tirée dans une loi de probabilité appartenant à une certaine famille de lois paramétrées par un ou plusieurs réels. On note cette famille \[\mathcal{P} = \{ p(\theta), \theta \in \Theta \subset \mathbb{R}^k \}.\]

On souhaite tester :

  • H0 : \(p \in \mathcal{P}\),
  • H1 : \(p \notin \mathcal{P}\).

Contexte pratique

Reprenons notre exemple précédent avec nos trois groupes : \(\mathcal{X} = \{ \text{Control, Treatment1, Treatment2} \}\). On pourrait se poser la question suivante :

  • H0 : les deux groupes traitement ont la même probabilité d’être choisis
  • H1 : l’un des deux groupes a une probabilité différente d’apparaître.

Une des façons de faire pourrait être de chercher à tester l’adéquation de nos observations avec la famille de lois paramétrées suivante : \[ \{ (\theta, \frac{1-\theta}{2}, \frac{1-\theta}{2}), \theta \in (0,1) \}. \]

La probabilité d’être choisi dans le groupe contrôle est un paramètre libre. Une fois fixé, les probabilités d’être dans chacun des deux groupes traitement sont égales et fixées également.

Ce que dit la théorie

Dans un premier temps, on va estimer le paramètre \(\theta\) par son estimateur de maximum de vraisemblance \(\hat{\theta}\).

On peut alors chercher à mesurer la “pseudo-distance du \(\chi^2\)” entre notre distribution empirique \(\hat{p}\) et une distribution de référence obtenue grâce à notre estimateur de maximum de vraisemblance : \(p(\hat{\theta})\). \[ D^2_n( \hat{p}, p(\hat{\theta}) ) = n \sum_{i=1}^d \frac{\left( \hat{p}_i - p_i(\hat{\theta}) \right)^2}{p_i(\hat{\theta})} \]

Il faut alors s’assurer que \(p\) vérifie un certain nombre de conditions techniques :

  • c’est une fonction injective de \(\Theta\) dans l’ensemble des distributions de probabilités sur \(d\) éléments,
  • c’est une fonction de classe \(\mathcal{C}^2\),
  • aucune de ses composantes ne s’annule sur \(\Theta\),
  • ses \(k\) dérivées partielles sont linéairement indépendantes en tout point de \(\Theta\).

Un théorème nous assure alors que, sous ces conditions,

  • sous H0, \(D^2_n( \hat{p}, p(\hat{\theta}) )\) tend en loi vers une distribution du \(\chi^2\) à \(d-1-k\) degrés de liberté.
  • sous H1, \(D^2_n( \hat{p}, p(\hat{\theta}) )\) tend vers l’infini presque sûrement.

Construction du test

Tout comme précédemment, on retiendra bien que ce théorème est un théorème asymptotique ! On ne pourra donc l’appliquer pour effectuer notre test sur de vraies données que pour de grands effectifs \(n\).

Si ces conditions d’effectifs suffisants sont respectées, le test fonctionne ainsi :

  • l’estimateur de maximum de vraisemblance \(\hat{\theta}\) est calculé,
  • la statistique de test \(D^2_n( \hat{p}, p(\hat{\theta}) )\) est calculée,
  • on fixe l’erreur de premier ordre \(\alpha\) acceptable,
  • on calcule \(q_{1-\alpha}\), le quantile de la loi du \(\chi^2\) à \(d-1-k\) degrés de liberté de niveau \(1-\alpha\),
  • on rejette H0 si \(D^2_n( \hat{p}, p^\text{ref} ) > q_{1-\alpha}\).

Intuitivement, on mesure une pseudo-distance entre notre distribution empirique et notre distribution de référence, et on rejette l’hypothèse nulle d’égalité des deux distributions lorsque cette pseudo-distance devient trop grande.

Et avec R ? une construction ad-hoc

Etant donnée le nombre immense de possibilités de familles de lois, nous n’avons pas ici une unique fonction qui nous renverrait directement notre réponse sur un plateau d’argent comme précédemment. Mais à présent que nous avons bien compris les différentes étapes, il n’est pas trop difficile d’enchaîner celles-ci avec R.

Dans notre example pratique, nous devons tout d’abord trouver l’estimateur de maximum de vraisemblance de \(\theta\). On écrit donc la vraisemblance : \[ \mathcal{L}(\theta) = \theta^{n_1} \left( \frac{1 - \theta}{2} \right)^{n_2 + n_3} \]\(n_1, n_2, n_3\) sont respectivement les effectifs observés dans les groupes contrôle, traitement1 et traitement2.

La log-vraisemblance est alors \[ \ln \mathcal{L}(\theta) = n_1 \ln \theta + (n_2 + n_3) \ln \frac{1 - \theta}{2} \]

On cherche à maximiser cette fonction, en cherchant comment annuler sa dérivée. Et on tombe sur un estimateur assez cohérent avec ce qu’on aurait pu imaginer intuitivement : \[ \hat{\theta} = \frac{n_1}{n} \]

## [1] 0.151494

La p-value est grande : on ne peut pas rejeter H0 dans notre cas. Et pour cause, on avait bien simulé nos données telles que la probabilité d’être dans chacun des deux groupes traitement était égale.

Nous savons à présent comparer une distribution empirique discrète à une loi de référence fixée, ou à une famille de loi paramétrées. Nous allons maintenant nous intéresser à un autre cas de figure fréquent : tester l’indépendance de deux distributions discrètes.

Indépendance de deux distributions discrètes appariées

Contexte formalisé

On dispose cette fois de \(n\) couples d’observations de variables discrètes \((X_i, Y_i)\) mesurées sur chaque individu \(i\). Les \((X_i)\) sont à valeur dans un ensemble \(\mathcal{X}\) à \(d\) éléments, tandis que les \((Y_i)\) sont à valeur dans un ensemble \(\mathcal{Y}\) à \(e\) éléments.

On suppose que nos couples sont indépendants et identiquement distribués selon une loi \(\nu\) sur \(\mathcal{X} \times \mathcal{Y}\). Typiquement, une telle distribution serait paramétrée par \((d e - 1)\) valeurs.

On souhaite à présent savoir si les \(X\) et les \(Y\) prennent leurs valeurs indépendamment l’un de l’autre, c’est à dire si la loi \(\nu\) appartient à la famille des lois produit. On note cette famille : \[ \mathcal{F} = \{ p \otimes q, ~ p \in \mathcal{P}(\mathcal{X}), q \in \mathcal{P}(\mathcal{Y}) \} \]\(\mathcal{P}(\mathcal{X})\) désigne l’ensemble des distributions sur l’ensemble discret \(\mathcal{X}\).

Typiquement, une distribution de \(\mathcal{F}\) n’est donc plus paramétrée que par \((d + e - 2)\) valeurs : les \((d-1)\) valeurs qui paramétrisent \(p\) et les \((e-1)\) valeurs qui paramétrisent \(q\).

Avec ces notations, on pourra tester :

  • H0 : \(\nu \in \mathcal{F}\),
  • H1 : \(\nu \notin \mathcal{F}\).

Contexte pratique

On continue de filer le même exemple que précédemment. Pour chaque individu \(i\), on observe le sexe \(X_i\) et le groupe \(Y_i\). On se demande si le choix du groupe est indépendant du sexe.

  • H0 : le choix du groupe est indépendant du sexe (i.e. la loi jointe appartient à la famille de lois produit \(\mathcal{F}\)),
  • H1 : le choix du groupe dépend du sexe.

Ce que dit la théorie

On peut estimer chacun des \(p_i\) par la fréquence empirique de l’observation \(x_i\), c’est à dire : \[ \hat{p}_i = \frac{1}{n} \sum_{k=1}^n \delta_{X_k = x_i} \] On peut également faire de même pour les fréquences empiriques des \(y_j\), en calculant : \[ \hat{q}_j = \frac{1}{n} \sum_{k=1}^n \delta_{Y_k = y_j} \] Et enfin, faire de même pour les fréquences empiriques des différents couples \((x_i, y_j)\) : \[ \hat{\nu}_{i,j} = \frac{1}{n} \sum_{k=1}^n \delta_{(X_k, Y_k) = (x_i, y_j)} \]

On souhaite ensuite mesurer la “pseudo-distance du \(\chi^2\)” entre la distribution empiriquement observée \(\hat{\nu}\) et celle donnée par le meilleur ajustement à une loi produit \(\hat{p} \otimes \hat{q}\), soit : \[ D^2_n( \hat{\nu}, \hat{p}\otimes\hat{q} ) = n \sum_{i=1}^d \sum_{j=1}^e \frac{\left( \hat{\nu}_{i,j} - \hat{p}_i \hat{q}_j \right)^2}{\hat{p}_i \hat{q}_j} \]

Un théorème nous assure alors que

  • sous H0, \(D^2_n( \hat{\nu}, \hat{p}\otimes\hat{q} )\) tend en loi vers une distribution du \(\chi^2\) à \((d-1) (e-1)\) degrés de liberté.
  • sous H1, \(D^2_n( \hat{\nu}, \hat{p}\otimes\hat{q} )\) tend vers l’infini presque sûrement.

Pour ceux qui souhaiteraient savoir d’où vient le nombre de degrés de liberté, notez que, comme précédemment, il correspond à la dimension de l’espace dans lequel vit la loi de probabilité \(\nu\) (soit \(de -1\)) moins la dimension de l’espace dans lequel vit la distribution à laquelle on souhaite se ramener (ici \(d + e - 2\)).

Construction du test

Comme toujours avec les tests du \(\chi^2\), notre test repose sur un théorème asymptotique : on ne peut donc l’appliquer pour effectuer notre test sur de vraies données que pour de grands effectifs \(n\) !

Si ces conditions d’effectifs suffisants sont respectées, le test fonctionne ainsi :

  • la statistique de test \(D^2_n( \hat{\nu}, \hat{p}\otimes\hat{q} )\) est calculée,
  • on fixe l’erreur de premier ordre \(\alpha\) acceptable,
  • on calcule \(q_{1-\alpha}\), le quantile de niveau \(1-\alpha\) de la loi du \(\chi^2\) à \((d-1) (e-1)\) degrés de liberté,
  • on rejette H0 si \(D^2_n( \hat{\nu}, \hat{p}\otimes\hat{q} ) > q_{1-\alpha}\).

Intuitivement, on mesure une pseudo-distance entre notre distribution empirique et notre meilleure estimation de loi produit, et on rejette l’hypothèse nulle d’égalité des deux distributions lorsque cette pseudo-distance devient trop grande.

Et avec R ? version courte

Dans notre example, on souhaite tester l’indépendance du sexe et du groupe chez nos individus. En une ligne, il nous suffit d’écrire :

## 
##  Pearson's Chi-squared test
## 
## data:  table(d$sex, d$group)
## X-squared = 2.4536, df = 2, p-value = 0.2932

Ou encore, pour un résultat équivalent avec une syntaxe différente,

## 
##  Pearson's Chi-squared test
## 
## data:  d$sex and d$group
## X-squared = 2.4536, df = 2, p-value = 0.2932

La p-value grande nous pousse ici à conserver H0 par défaut : on ne peut pas rejeter l’hypothèse nulle d’indépendance du sexe et du groupe.

Et avec R ? version longue

Pour se convaincre que tout fonctionne bien, il peut être utile de calculer et afficher certaines quantités.

##    
##     Control Treatment1 Treatment2
##   F      19         19         20
##   M      11         10         21
##    F    M 
## 0.58 0.42
##    Control Treatment1 Treatment2 
##       0.30       0.29       0.41
##   Control Treatment1 Treatment2
## F   0.174     0.1682     0.2378
## M   0.126     0.1218     0.1722
##    
##     Control Treatment1 Treatment2
##   F    0.19       0.19       0.20
##   M    0.11       0.10       0.21
## [1] 2.45364
## [1] 0.2932235

Cette p-value pourrait être reportée comme précédemment sur le graphe de densité de la loi du \(\chi^2\) que suit notre statistique de test sous H0. Il se trouve cependant qu’ici c’est exactement la même loi, et ce n’est donc pas très intéressant à répéter.

Nous savons à présent utiliser notre test du \(\chi^2\) pour tester l’indépendance de deux distributions discrètes appariées. Voyons à présent comment on peut adapter ces résultats pour tester l’homogénéité de plusieurs échantillons discrets.

Homogénéité de plusieurs échantillons discrets

Contexte formalisé

On observe un échantillon de taille \(n_1\) \(X^{(1)} = (X^{(1)}_1, X^{(1)}_2, ..., X^{(1)}_{n_1})\) ainsi qu’un échantillon de taille \(n_2\), \(X^{(2)}\).

On suppose que les \((X_i^{(1)})\) proviennent de variables aléatoires indépendantes et identiquement distribuées selon une loi \(p^{(1)}\) et que les \((X_i^{(2)})\) proviennent de variables aléatoires indépendantes et identiquement distribuées selon une loi \(p^{(2)}\).

On souhaite tester :

  • H0 : \(p^{(1)} = p^{(2)}\),
  • H0 : \(p^{(1)} \neq p^{(2)}\).

Contexte pratique

Imaginons qu’un deuxième centre de recrutement ouvre, et qu’il recrute également des individus dans trois groupes comme précédemment : contrôle, traitement1 et traitement2.

On peut chercher à tester :

  • H0 : la distribution des trois groupes est identique dans le premier centre (dataset d) et dans le second centre (dataset d2).
  • H1 : les deux distributions sont différentes.

Ce que dit la théorie

Pour répondre à la question, on va chercher à se ramener au cas précédent. On va former \(n_1 + n_2\) paires d’observations \((X_i, Y_i)\), avec :

  • pour \(i \leq n_1\), \((X_i, Y_i) = (X_i^{(1)}, 1)\),
  • pour \(n_1 < i \leq n_1+n_2\), \((X_i, Y_i) = (X_i^{(2)}, 2)\).

Notre test peut alors se reformuler en :

  • H0 : les variables \(X\) et \(Y\) sont indépendantes, c’est à dire la loi jointe correspond à la loi produit des \(X\) et \(Y\).
  • H1 : les deux variables ne sont pas indépendantes.

Et c’est tout. Et ça fonctionnerait encore de la même façon avec plus que deux échantillons. Finalement, tester l’homogénéité de plusieurs échantillons revient simplement à créer une variable correspondant au numéro de l’échantillon, et à tester l’indépendance entre le numéro de l’échantillon et la variable d’intérêt.

Et avec R ?

Nous avons déjà fait tout le boulot précédemment. Finalement, il ne s’agit ici que de manipuler nos données pour nous placer dans le même cas de figure.

##             
##              Center1 Center2
##   Control         30      35
##   Treatment1      29      24
##   Treatment2      41      21
## 
##  Pearson's Chi-squared test
## 
## data:  table(df$group, df$center)
## X-squared = 5.1493, df = 2, p-value = 0.07618

La p-value grande nous incite ici à conserver H0 par défaut. Notez que les simulations étaient pourtant réalisées à partir de loi sous-jacentes légèrement différentes. Trop légèrement différentes, visiblement, pour que notre test ait assez de puissance pour les discriminer. On obtiendra évidemment plus de puissance en augmentant les effectifs, ou en augmentant la différence entre les distributions de probabilité.

Conclusion

S’il y a bien deux choses à retenir à propos du test du \(\chi^2\), les voici :

  1. il s’applique pour comparer des distributions discrètes : soit une distribution à une distribution de référence, soit une distribution à une famille de distributions, soit plusieurs distributions empiriques ensemble.
  2. il repose sur des résultats asymptotiques : et requiert donc de grands effectifs !
LS0tCnRpdGxlOiAiTGUgdGVzdCBkdSBjaGkyIDogdW4gY291dGVhdSBzdWlzc2UgcG91ciBzdGF0aXN0aWNpZW4iCmF1dGhvcjogIk1hcmMgTWFuY2VhdSIKZGF0ZTogIjIwMjMtMDIiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogVFJVRQogICAgdG9jX2RlcHRoOiAyCiAgICB0b2NfZmxvYXQ6IFRSVUUKICAgIGhpZ2hsaWdodDogInRhbmdvIgogICAgY29kZV9kb3dubG9hZDogVFJVRQotLS0KCkNvbW1lbsOnb25zIHBhciBjaGFyZ2VyIHF1ZWxxdWVzIG1vZHVsZXMgdXRpbGVzLgoKYGBge3IgbWVzc2FnZT1GfQojIGNvbW1lIHRvdWpvdXJzLCBub3VzIHV0aWxpc2Vyb25zIGRhbnMgY2UgdHV0b3JpZWwgbGEgc3ludGF4ZSBkdSAidGlkeXZlcnNlIgpsaWJyYXJ5KHRpZHl2ZXJzZSkKIyBub3VzIHV0aWxpc2Vyb25zICJjb3dwbG90IiBwb3VyIGZhaXJlIGRlcyBmaWd1cmVzIG11bHRpcGxlcyBmYWNpbGVtZW50CmxpYnJhcnkoY293cGxvdCkKYGBgCgpMZSB0ZXN0IGR1ICRcY2hpXjIkIChsaXJlICJraSBkZXV4IikgZXN0IGNlbnRyYWwgZGFucyBsYSBjdWx0dXJlIHN0YXRpc3RpcXVlIGR1IGZhaXQgZGUgc2VzIHRyw6hzIG5vbWJyZXVzZXMgdXRpbGlzYXRpb25zLgpJbCBwZXV0IGVuIGVmZmV0IHNlcnZpciA6CgoxLiDDoCB0ZXN0ZXIgbCcqYWp1c3RlbWVudCogZCd1bmUgZGlzdHJpYnV0aW9uIGRpc2Nyw6h0ZSDDoCB1bmUgKmxvaSBkb25uw6llKgoyLiDDoCB0ZXN0ZXIgbCcqYWp1c3RlbWVudCogZCd1bmUgZGlzdHJpYnV0aW9uIGRpc2Nyw6h0ZSDDoCB1bmUgKmZhbWlsbGUgZGUgbG9pcyBkb25uw6llKiAocGFyYW3DqXRyw6llKQozLiDDoCB0ZXN0ZXIgbCcqaW5kw6lwZW5kYW5jZSogZGUgZGV1eCBkaXN0cmlidXRpb25zIGFwcGFyacOpZXMKNC4gw6AgdGVzdGVyIGwnKmhvbW9nw6luw6lpdMOpKiBkZSBwbHVzaWV1cnMgw6ljaGFudGlsbG9ucyBkZSBsb2lzIGRpc2Nyw6h0ZXMuCgpQYXIgYWlsbGV1cnMsIGJpZW4gcXVlIGNlcyA0IHBvaW50cyBkJ3V0aWxpc2F0aW9uIGNvbmNlcm5lbnQgbm9ybWFsZW1lbnQgZGVzIHZhcmlhYmxlcyBwcmVuYW50IGRlcyB2YWxldXJzIGRhbnMgdW4gZW5zZW1ibGUgKmRpc2NyZXQgZXQgZmluaSosIGRlcyB0ZXN0cyBkdSAkXGNoaV4yJCBzb250IGF1c3NpIHLDqWd1bGnDqHJlbWVudCBlZmZlY3R1w6lzIHBvdXIgcsOpcG9uZHJlIGF1eCBtw6ptZSBxdWVzdGlvbnMgc3VyIGRlcyB2YXJpYWJsZXMgcHJlbmFudCBkZXMgdmFsZXVycyBkYW5zIHVuIGVuc2VtYmxlIGNvbnRpbnUsIGF1cXVlbCBjYXMgdW5lIHByZW1pw6hyZSDDqXRhcGUgZGUgZGlzY3LDqXRpc2F0aW9uIGRlcyBkb25uw6llcyBzZXJhIGVmZmVjdHXDqWUuCgpMJ29iamVjdGlmIGRlIGNlIGNvdXJzIGVzdCBkZSBjb21wcmVuZHJlIGxlcyBncmFuZHMgcHJpbmNpcGVzIHRow6lvcmlxdWVzIHNvdXMtamFjZW50cyBhdSB0ZXN0IGR1ICRcY2hpXjIkLCBldCBkJ8OqdHJlIGNhcGFibGUgZGUgcsOpYWxpc2VyIGRlcyB0ZXN0cyBhdmVjIFIgZGFucyBsZXMgNCBjYXMgcXVpIG5vdXMgaW50w6lyZXNzZW50LiBDb21tZW7Dp29ucyBwYXIgbGUgcGx1cyBzaW1wbGUgOiBsZSB0ZXN0IGQnYWp1c3RlbWVudCDDoCB1bmUgZGlzdHJpYnV0aW9uIGRpc2Nyw6h0ZS4KCgojIEFqdXN0ZW1lbnQgw6AgdW5lIGRpc3RyaWJ1dGlvbiBkaXNjcsOodGUKCiMjIENvbnRleHRlIGZvcm1hbGlzw6kKCk9uIGRpc3Bvc2UgZCd1biDDqWNoYW50aWxsb24gZGUgJG4kIHZhbGV1cnMgb2JzZXJ2w6llcyAkKFhfMSwgWF8yLCAuLi4sIFhfbikkIHF1aSBwcmVubmVudCBsZXVycyB2YWxldXJzIGRhbnMgdW4gZW5zZW1ibGUgZGlzY3JldCBkZSAkZCQgdmFsZXVycyAkXG1hdGhjYWx7WH0gPSBceyB4XzEsIHhfMiwgLi4uLCB4X2QgXH0kLgoKT24gY29uc2lkw6hyZSBxdWUgbm9zICRuJCBvYnNlcnZhdGlvbnMgcHJvdmllbm5lbnQgZGUgdmFyaWFibGVzIGFsw6lhdG9pcmVzIGluZMOpcGVuZGFudGVzIGV0IGlkZW50aXF1ZW1lbnQgZGlzdHJpYnXDqWVzIGRhbnMgdW5lIG3Dqm1lIGxvaSBxdSdvbiBub3RlICRwID0gKHBfMSwgcF8yLCAuLi4sIHBfZCkkLCBvw7kgJHBfaSQgZXN0IGxhIHByb2JhYmlsaXTDqSBxdWUgbGEgdmFyaWFibGUgYWzDqWF0b2lyZSBwcmVubmUgbGEgdmFsZXVyICR4X2kkLgoKUGFyIGFpbGxldXJzLCBvbiBkaXNwb3NlIGQndW5lIGxvaSBkZSByw6lmw6lyZW5jZSBzdXIgJFxtYXRoY2Fse1h9JCBxdSdvbiBhcHBlbGxlICRwXlx0ZXh0e3JlZn0kLCDDoCBsYXF1ZWxsZSBvbiBzb3VoYWl0ZXJhaXQgY29tcGFyZXIgbm90cmUgw6ljaGFudGlsbG9uLlwKUGx1cyBwcsOpY2lzw6ltZW50LCBvbiBzb3VoYWl0ZSB0ZXN0ZXIgOgoKKiBIMCA6ICRwID0gcF5cdGV4dHtyZWZ9JAoqIEgxIDogJHAgXG5lcSBwXlx0ZXh0e3JlZn0kLgoKIyMgQ29udGV4dGUgcHJhdGlxdWUKCk9uIHNpbXVsZSB1biAidG95IGRhdGFzZXQiIHRyw6hzIHNpbXBsZSBpbnNwaXLDqSBkJ2Vzc2FpcyBjbGluaXF1ZXMsIGNvbnRlbmFudCBkZXV4IHZhcmlhYmxlcyBkaXNjcsOodGVzIHVuaXF1ZW1lbnQuCk9uIG1hw650cmlzZSBhaW5zaSBsYSBsb2kgZ8OpbsOpcmF0cmljZSBkZSBub3MgdmFyaWFibGVzIDoKCiogbGUgc2V4ZSBlc3QgdGlyw6kgZGFucyB1bmUgbG9pIHVuaWZvcm1lIHN1ciBsJ2Vuc2VtYmxlICRceyBGLCBNIFx9JCwKKiBsZSBncm91cGUgZXN0IHRpcsOpIGRhbnMgdW5lIGxvaSDDoCB2YWxldXJzIGRhbnMgJFx7IFx0ZXh0e0NvbnRyb2wsIFRyZWF0bWVudDEsIFRyZWF0bWVudDJ9IFx9JCwgcXVpIHBsYWNlIGxhIG3Dqm1lIHByb2JhYmlsaXTDqSBkZSAwLjMgc3VyIGxlcyBkZXV4IGdyb3VwZXMgdHJhaXRlbWVudCBldCB1bmUgbWFzc2UgZGUgcHJvYmFiaWxpdMOpIGRlIDAuNCBzdXIgbGUgZ3JvdXBlIGNvbnRyw7RsZS4KCmBgYHtyfQpuIDwtIDEwMApkIDwtIGRhdGEuZnJhbWUoc2V4ID0gc2FtcGxlKHNpemUgPSBuLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gYygiRiIsICJNIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2IgPSBjKDAuNSwgMC41KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZSA9IFQpLAogICAgICAgICAgICAgICAgZ3JvdXAgPSBzYW1wbGUoc2l6ZSA9IG4sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9IGMoIkNvbnRyb2wiLCAiVHJlYXRtZW50MSIsICJUcmVhdG1lbnQyIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvYiA9IGMoMC40LCAwLjMsIDAuMyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZSA9IFQpKQpgYGAKCgpQbHVzaWV1cnMgcXVlc3Rpb25zIHBldXZlbnQgc2UgcG9zZXIgYXV0b3VyIGRlIGNlIGRhdGFzZXQgOgoKKiBlc3QtY2UgcXVlIGxlcyBzZXhlcyBzb250IMOpcXVpbGlicsOpcyA/IGF1dHJlbWVudCBkaXQsIGVzdC1jZSBxdWUgbGEgbG9pIGfDqW7DqXJhdHJpY2UgZGVzIHNleGVzIGVzdCAkcF5cdGV4dHtyZWZ9ID0gKDAuNSwgMC41KSQgPwoqIGVzdC1jZSBxdWUgbGVzIGdyb3VwZXMgc29udCDDqXF1aWxpYnLDqXMgPyBpLmUuIGVzdC1jZSBxdWUgbGEgbG9pIGfDqW7DqXJhdHJpY2UgZXN0IHVuaWZvcm1lIHN1ciBub3MgdHJvaXMgZ3JvdXBlcyA/CgojIyBDZSBxdWUgZGl0IGxhIHRow6lvcmllCgpPbiBwZXV0IGVzdGltZXIgY2hhY3VuIGRlcyAkcF9pJCBwYXIgbGEgZnLDqXF1ZW5jZSBlbXBpcmlxdWUgJFxoYXR7cH1faSQgZGUgbCdvYnNlcnZhdGlvbiAkeF9pJCwgYydlc3Qgw6AgZGlyZSA6CiQkIFxoYXR7cH1faSA9IFxmcmFjezF9e259IFxzdW1fe2s9MX1ebiBcZGVsdGFfe1hfayA9IHhfaX0gJCQKb8O5IG9uIG5vdGUgJFxkZWx0YV97WF9rID0geF9pfSQgbGEgdmFyaWFibGUgaW5kaWNhdHJpY2UgZGUgbCfDqXbDqW5lbWVudCAkWF9rID0geF9pJCwgYydlc3Qgw6AgZGlyZSBsYSB2YXJpYWJsZSB2YWxhbnQgMSBsb3JzcXVlICRYX2sgPSB4X2kkIGV0IDAgc2lub24uCgpPbiBzb3VoYWl0ZSBlbnN1aXRlIG1lc3VyZXIgdW5lIGNlcnRhaW5lIGlkw6llIGRlICJkaXN0YW5jZSIgZW50cmUgbGEgZGlzdHJpYnV0aW9uIGVtcGlyaXF1ZW1lbnQgb2JzZXJ2w6llICRcaGF0e3B9JCBldCBjZWxsZSBkZSByw6lmw6lyZW5jZSAkcF5cdGV4dHtyZWZ9JC4gQ2V0dGUgZGlzdGFuY2UgZXN0IGFwcGVsw6llICJwc2V1ZG8tZGlzdGFuY2UgZHUgJFxjaGleMiQiLCBldCBlbGxlIHMnZXhwcmltZSBjb21tZSA6CiQkIEReMl9uKCBcaGF0e3B9LCBwXlx0ZXh0e3JlZn0gKSA9IG4gXHN1bV97aT0xfV5kIFxmcmFje1xsZWZ0KFxoYXR7cH1faSAtIHBeXHRleHR7cmVmfV9pIFxyaWdodCleMn17cF5cdGV4dHtyZWZ9X2l9ICQkCgpVbiB0aMOpb3LDqG1lIG5vdXMgYXNzdXJlIGFsb3JzIHF1ZQoKKiBzb3VzIEgwLCAkRF4yX24gKCBcaGF0e3B9LCBwXlx0ZXh0e3JlZn0gKSQgdGVuZCBlbiBsb2kgdmVycyB1bmUgZGlzdHJpYnV0aW9uIGR1ICRcY2hpXjIkIMOgICRkLTEkIGRlZ3LDqXMgZGUgbGliZXJ0w6kuCiogc291cyBIMSwgJEReMl9uICggXGhhdHtwfSwgcF5cdGV4dHtyZWZ9ICkkIHRlbmQgdmVycyBsJ2luZmluaSBwcmVzcXVlIHPDu3JlbWVudC4KCiMjIENvbnN0cnVjdGlvbiBkdSB0ZXN0CgpDZSB0aMOpb3LDqG1lIGVzdCB1biB0aMOpb3LDqG1lIGFzeW1wdG90aXF1ZSA6IG9uIG5lIHBldXQgZG9uYyBsJ2FwcGxpcXVlciBwb3VyIGVmZmVjdHVlciBub3RyZSB0ZXN0IHN1ciBkZSB2cmFpZXMgZG9ubsOpZXMgcXVlIHBvdXIgZGUgZ3JhbmRzIGVmZmVjdGlmcyAkbiQgISBPbiBkZW1hbmRlIGF1c3NpIGfDqW7DqXJhbGVtZW50IMOgIGNlIHF1ZSAkbiBwXlx0ZXh0e3JlZn1faSQgc29pdCBhdSBtb2lucyDDqWdhbCDDoCA1IHBvdXIgdG91dCAkaSQuCgpTaSBjZXMgY29uZGl0aW9ucyBkJ2VmZmVjdGlmcyBzdWZmaXNhbnRzIHNvbnQgcmVzcGVjdMOpZXMsIGxlIHRlc3QgZm9uY3Rpb25uZSBhaW5zaSA6CgoqIGxhIHN0YXRpc3RpcXVlIGRlIHRlc3QgJEReMl9uKCBcaGF0e3B9LCBwXlx0ZXh0e3JlZn0gKSQgZXN0IGNhbGN1bMOpZSwKKiBvbiBmaXhlIGwnZXJyZXVyIGRlIHByZW1pZXIgb3JkcmUgJFxhbHBoYSQgYWNjZXB0YWJsZSwKKiBvbiBjYWxjdWxlICRxX3sxLVxhbHBoYX0kLCBsZSBxdWFudGlsZSBkZSBsYSBsb2kgZHUgJFxjaGleMiQgw6AgJGQtMSQgZGVncsOpcyBkZSBsaWJlcnTDqSBkZSBuaXZlYXUgJDEtXGFscGhhJCwKKiBvbiByZWpldHRlIEgwIHNpICREXjJfbiggXGhhdHtwfSwgcF5cdGV4dHtyZWZ9ICkgPiBxX3sxLVxhbHBoYX0kLgoKSW50dWl0aXZlbWVudCwgb24gbWVzdXJlIHVuZSBwc2V1ZG8tZGlzdGFuY2UgZW50cmUgbm90cmUgZGlzdHJpYnV0aW9uIGVtcGlyaXF1ZSBldCBub3RyZSBkaXN0cmlidXRpb24gZGUgcsOpZsOpcmVuY2UsIGV0IG9uIHJlamV0dGUgbCdoeXBvdGjDqHNlIG51bGxlIGQnw6lnYWxpdMOpIGRlcyBkZXV4IGRpc3RyaWJ1dGlvbnMgbG9yc3F1ZSBjZXR0ZSBwc2V1ZG8tZGlzdGFuY2UgZGV2aWVudCB0cm9wIGdyYW5kZS4KCiMjIEV0IGF2ZWMgUiA/IHZlcnNpb24gY291cnRlCgpFbiB1bmUgbGlnbmUgdHLDqHMgc2ltcGxlLCBlc3QtY2UgcXVlIGxlIHNleGUgZXN0IGRpc3RyaWJ1w6kgZGUgZmHDp29uIHVuaWZvcm1lID8KCmBgYHtyfQojIG5vdXMgYWZmaWNob25zIGQnYWJvcmQgbGVzIGVmZmVjdGlmcyBkZXMgZGlmZsOpcmVudGVzIGNhdMOpZ29yaWVzCnRhYmxlKGQkc2V4KQojIHB1aXMgbm91cyBhZmZpY2hvbnMgbGUgcsOpc3VsdGF0IGR1IHRlc3QgZHUgY2hpMgpjaGlzcS50ZXN0KHRhYmxlKGQkc2V4KSwgcD1jKDAuNSwwLjUpKQpgYGAKCkxhIGxlY3R1cmUgZHUgY29tcHRlLXJlbmR1IGRlIFIgcHLDqXNlbnRlIDoKCiogbGEgdmFsZXVyIGRlIGxhIHN0YXRpc3RpcXVlIGRlIHRlc3QgJEReMl9uJCBxdWkgZXN0IGFwcGVsw6llIFgtc3F1YXJlZCBpY2ksCiogbGUgbm9tYnJlIGRlIGRlZ3LDqXMgZGUgbGliZXJ0w6kgKGRmIHBvdXIgZGVncmVlcyBvZiBmcmVlZG9tKSBkZSBsYSBsb2kgZHUgJFxjaGleMiQgcXVlIHN1aXQgbm90cmUgc3RhdGlzdGlxdWUgZGUgdGVzdCBzb3VzIEgwLAoqIGV0LCB0csOocyBpbXBvcnRhbnQsIGxhICpwLXZhbHVlKiwgcXVpIGVzdCBsYSBwcm9iYWJpbGl0w6kgcXVlIGxhIHN0YXRpc3RpcXVlIGRlIHRlc3Qgc29pdCBhdSBtb2lucyBhdXNzaSBleHRyw6ptZSBxdSdvYnNlcnbDqWUsIHNvdXMgSDAuCgpTaSBsYSAqcC12YWx1ZSogZXN0IGluZsOpcmlldXJlIGF1IHJpc3F1ZSBkZSBwcmVtaWVyIGVzcMOoY2UgJFxhbHBoYSQgcXUnb24gcydlc3QgZml4w6ksIG9uIHMnYXV0b3Jpc2Ugw6AgcmVqZXRlciBIMC4KCkljaSwgbGEgcC12YWx1ZSBlc3QgZ3JhbmRlLCBvbiBjb25zZXJ2ZSBkb25jIEgwIHBhciBkw6lmYXV0LgoKRXQgbm9zIGdyb3VwZXMgYWxvcnMsIHNvbnQtaWxzIGRpc3RyaWJ1w6lzIHNlbG9uIHVuZSBsb2kgdW5pZm9ybWUsIGFzc29jaWFudCB1bmUgcHJvYmFiaWxpdMOpICQoXGZyYWN7MX17M30sIFxmcmFjezF9ezN9LCBcZnJhY3sxfXszfSkkIMOgIGNoYWN1biBkZXMgdHJvaXMgZ3JvdXBlcyA/IFBvdXIgZ2FnbmVyIGVuY29yZSBkdSB0ZW1wcywgbG9yc3F1J29uIGNvbXBhcmUgbm90cmUgZGlzdHJpYnV0aW9uIMOgIHVuZSBsb2kgZGUgcsOpZsOpcmVuY2UgdW5pZm9ybWUsIGlsIG4nZXN0IHBhcyBuw6ljZXNzYWlyZSBkZSBzcMOpY2lmaWVyIMOgIFIgbGEgbG9pIGRlIHLDqWbDqXJlbmNlIDogaW1wbGljaXRlbWVudCwgZWxsZSBlc3QgdW5pZm9ybWUuCgpgYGB7cn0KdGFibGUoZCRncm91cCkKY2hpc3EudGVzdCh0YWJsZShkJGdyb3VwKSkKYGBgCgpMYSBwLXZhbHVlIGVzdCBpY2kgZmFpYmxlLiBTZWxvbiBsZXMgZG9tYWluZXMgc2NpZW50aWZpcXVlcywgbCdlcnJldXIgZGUgcHJlbWnDqHJlIGVzcMOoY2UgcXUnb24gcydhdXRvcmlzZSDDoCBjb21tZXR0cmUgcGV1dCB2YXJpZXIgZ3JhbmRlbWVudC4gRGFucyBsZSBkb21haW5lIGRlcyBlc3NhaXMgY2xpbmlxdWVzLCBsZXMgdmFsZXVycyBjbGFzc2lxdWVtZW50IHV0aWxpc8OpZXMgcGV1dmVudCDDqnRyZSAwLjA1LCAwLjAyNSBvdSBlbmNvcmUgMC4wMDEsIHNlbG9uIGxlcyBjb25zw6lxdWVuY2VzIHF1aSBzb250IGFzc29jacOpZXMgYXUgZmFpdCBkZSByZWpldGVyIEgwIGFsb3JzIHF1J29uIMOpdGFpdCBzb3VzIEgwLgoKUG91ciBmaW5pciwgcGV1dC3DqnRyZSDDqXRhaXQtaWwgw6ljcml0IGF1IHByb3RvY29sZSBxdWUgNDAlIGRlcyBpbmNsdXNpb25zIGNvbmNlcm5lcmFpZW50IGxlIGdyb3VwZSBjb250csO0bGUsIGV0IHF1ZSBsZSByZXN0ZSBzZXJhaXQgcsOpcGFydGkgZGUgZmHDp29uIHVuaWZvcm1lIGVudHJlIGxlcyBkZXV4IGdyb3VwZXMgdHJhaXRlbWVudC4gU2kgb24gc291aGFpdGUgdsOpcmlmaWVyIGwnYWTDqXF1YXRpb24gYXZlYyBjZXR0ZSBsb2kgZGUgcsOpZsOpcmVuY2UgKG5vbi11bmlmb3JtZSBjZXR0ZSBmb2lzLWNpKSwgdm91cyBsJ2F1cmV6IGRldmluw6ksIGxhIHN5bnRheGUgZXN0IHRvdXQgc2ltcGxlbWVudCA6CgpgYGB7cn0KY2hpc3EudGVzdCh0YWJsZShkJGdyb3VwKSwgcD1jKDAuNCwgMC4zLCAwLjMpKQpgYGAKCkNldHRlIGZvaXMtY2ksIGxhIHAtdmFsdWUgZXN0IGZvcnRlLCBldCBvbiBjb25zZXJ2ZSBIMC4KQ2VzIHRyb2lzIHRlc3RzIMOpdGFpZW50IGRvbmMgYmllbiBjb2jDqXJlbnRzIGF2ZWMgbGEgZmHDp29uIGRvbnQgbGVzIGRvbm7DqWVzIG9udCDDqXTDqSBzaW11bMOpZXMuCgojIyBFdCBhdmVjIFIgPyB2ZXJzaW9uIGxvbmd1ZQoKVW5lIGJvbm5lIGZhw6dvbiBkZSBzZSBjb252YWluY3JlIHF1ZSB0b3V0IMOnYSBmb25jdGlvbm5lIGJpZW4gY29uc2lzdGUgw6AgY2FsY3VsZXIgbWFudWVsbGVtZW50IGxlcyBkaWZmw6lyZW50ZXMgcXVhbnRpdMOpcyBkJ2ludMOpcsOqdCwgZXQgc3VydG91dCDDoCByZXByw6lzZW50ZXIgZ3JhcGhpcXVlbWVudCBsYSBzdGF0aXN0aXF1ZSBkZSB0ZXN0IGV0IGxhIGxvaSBkdSAkXGNoaV4yJCBxdWUgbm90cmUgc3RhdGlzdGlxdWUgZGUgdGVzdCBlc3QgY2Vuc8OpZSBzdWl2cmUgc291cyBIMC4KCmBgYHtyfQojIG9uIHBldXQgY2FsY3VsZXIgZXQgYWZmaWNoZXIgbGVzIGZyw6lxdWVuY2VzIGVtcGlyaXF1ZXMKdCA8LSB0YWJsZShkJGdyb3VwKQpoYXRwIDwtIHQvc3VtKHQpCmhhdHAKCiMgcXUnb24gc291aGFpdGUgY29tcGFyZXIgYXV4IHByb2JhYmlsaXTDqSBkZSByw6lmw6lyZW5jZQpwcmVmIDwtIHJlcCgxLzMsIDMpCgojIGV0IGxlcyB1dGlsaXNlciBwb3VyIGNhbGN1bGVyIGxhIHN0YXRpc3RpcXVlIGR1IENoaTIgOiAKRCA8LSBuICogc3VtKChoYXRwIC0gcHJlZikgXiAyIC8gcHJlZikKcHJpbnQocGFzdGUoIkxhIHN0YXRpc3RpcXVlIGRlIHRlc3QgZHUgY2hpMiBlc3QiLCBEKSkKYGBgCgpgYGB7ciBmaWcud2lkdGg9MTB9CiMgTGEgcC12YWx1ZSBlc3QgbGEgcHJvYmFiaWxpdMOpIGQnYXZvaXIgdW5lIHZhbGV1ciBkZSBzdGF0aXN0aXF1ZSBkZSB0ZXN0IHN1cMOpcmlldXJlIMOgIGxhIHZhbGV1ciBvYnNlcnbDqWUsIHNvdXMgSDAKcHZhbCA8LSAxIC0gcGNoaXNxKEQsIGRmPTIpCgojIE9uIHJlcHLDqXNlbnRlIGxhIGRlbnNpdMOpIGRlIGxhIGxvaSBkdSBjaGkyIHF1aSBub3VzIGludMOpcmVzc2UKeCA8LSBzZXEoMCwgMTAsIDAuMDEpCmRhdGFfY2hpc3EgPC0gZGF0YS5mcmFtZSh4ID0geCwKICAgICAgICAgICAgICAgICAgICAgICAgIGRjaGlzcSA9IGRjaGlzcSh4LCBkZj0yKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBjaGlzcSA9IHBjaGlzcSh4LCBkZj0yKSkKCnBsb3RfZGVuc2l0ZSA8LSBkYXRhX2NoaXNxICU+JSBnZ3Bsb3QoYWVzKHggPSB4LCB5ID0gZGNoaXNxKSkgKwogICAgZ2VvbV9saW5lKCkgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gRCwgbHR5PSJkYXNoZWQiKSArCiAgICBnZW9tX2FyZWEoZGF0YT1kYXRhX2NoaXNxW3g+RCxdLCBmaWxsPSJyZWQiKSArCiAgICB5bGFiKCJEZW5zaXTDqSBkZSBsYSBzdGF0aXN0aXF1ZSBkZSB0ZXN0IEQgc291cyBIMCIpICsKICAgIHhsYWIoImQiKSArCiAgICB0aGVtZV9idygpCgpwbG90X3Byb2JhIDwtIGRhdGFfY2hpc3EgJT4lIGdncGxvdCgpICsKICAgIGdlb21fbGluZShhZXMoeCA9IHgsIHkgPSAxLXBjaGlzcSkpICsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IHB2YWwsIGx0eT0iZGFzaGVkIiwgY29sb3I9InJlZCIpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IEQsIGx0eT0iZGFzaGVkIikgKwogICAgeWxhYigiUHJvYmFiaWxpdMOpIGRlIHZvaXIgdW5lIHN0YXRpc3RpcXVlIGRlIHRlc3QgRCBzdXDDqXJpZXVyZSDDoCBsYSB2YWxldXIgZW4gYWJzY2lzc2UiKSArCiAgICB4bGFiKCJkIikgKwogICAgdGhlbWVfYncoKQoKcGxvdF9ncmlkKHBsb3RfZGVuc2l0ZSwgcGxvdF9wcm9iYSwgbmNvbCA9IDIsIG5yb3cgPSAxLCBsYWJlbHM9YygiQSIsIkIiKSkKYGBgCgpTdXIgbm9zIGRldXggZ3JhcGhlcywgbGEgbGlnbmUgbm9pcmUgcG9pbnRpbGzDqWUgY29ycmVzcG9uZCDDoCBsYSB2YWxldXIgZGUgbGEgc3RhdGlzdGlxdWUgZGUgdGVzdCBvYnNlcnbDqWUuCgpTdXIgbGUgZ3JhcGhlIGRlIGdhdWNoZSwgcmVwcsOpc2VudGFudCBsYSBkZW5zaXTDqSBkZSBsYSBsb2kgZHUgJFxjaGleMiQgcXVlIHN1aXQgbm90cmUgc3RhdGlzdGlxdWUgZGUgdGVzdCBzb3VzIEgwLCBsYSBwLXZhbHVlIGNvcnJlc3BvbmQgw6AgbCdhaXJlIGNvbG9yacOpZSBlbiByb3VnZSA6IGxhIHByb2JhYmlsaXTDqSBxdWUgbGEgc3RhdGlzdGlxdWUgZGUgdGVzdCBzb2l0IGF1IG1vaW5zIGF1c3NpIGdyYW5kZSBxdSdvYnNlcnbDqWUuCgpTdXIgbGUgZ3JhcGhlIGRlIGdhdWNoZSwgcmVwcsOpc2VudGFudCBsYSBwcm9iYWJpbGl0w6kgcXVlIGxhIHN0YXRpc3RpcXVlIGRlIHRlc3Qgc29pdCBzdXDDqXJpZXVyZSDDoCB1bmUgdmFsZXVyIGRvbm7DqWUsIGxhIHAtdmFsdWUgc2UgbGl0IGRpcmVjdGVtZW50IMOgIGwnaW50ZXJzZWN0aW9uIGVudHJlIGxhIGxpZ25lIHBvaW50aWxsw6llIHJvdWdlIGV0IGwnYXhlIGRlcyBvcmRvbm7DqWVzLgoKUHVpc3F1J29uIGRpc3Bvc2UgZW50cmUgbGVzIG1haW5zIHRvdXRlIGxhIHB1aXNzYW5jZSBkZSBjYWxjdWwgZCd1biBvcmRpbmF0ZXVyIG1vZGVybmUsIG9uIHBldXQgYXVzc2kgc2UgZGVtYW5kZXIgw6AgcXVlbCBwb2ludCBsJ2h5cG90aMOoc2UgYXN5bXB0b3RpcXVlICgkbiQgZ3JhbmQpIGVzdCB2w6lyaWZpw6llIHBvdXIgJG4gPSAxMDAkIGNvbW1lIG9uIGwnYXZhaXQgaWNpLiBPbiB2YSBwb3VyIGNlbGEgc2ltdWxlciAkMTBeNSQgZGF0YXNldHMgc291cyBIMCwgZXQgY2FsY3VsZXIgcG91ciBjaGFjdW4gbGEgdmFsZXVyIGRlIGxhIHN0YXRpc3RpcXVlIGRlIHRlc3QuIE9uIHBvdXJyYSBlbnN1aXRlIGNvbXBhcmVyIHZpc3VlbGxlbWVudCBsYSBkaXN0cmlidXRpb24gZW1waXJpcXVlbWVudCBvYnNlcnbDqWUgZGUgbm9zIHN0YXRpc3RpcXVlcyBkZSB0ZXN0cyBhdmVjIGxhIGRpc3RyaWJ1dGlvbiBhc3ltcHRvdGlxdWUgZHUgJFxjaGleMiQuCgpgYGB7cn0Kc3RhdHMgPC0gYygpCnByZWYgPC0gcmVwKDEvMywgMykKCmZvciAoaSBpbiAxOjFlNSl7CiAgICAjIG9uIHNpbXVsZSBub3RyZSBkYXRhc2V0IHNvdXMgSDAKICAgIGdyb3VwcyA8LSBzYW1wbGUoc2l6ZSA9IG4sIHggPSBjKCJDb250cm9sIiwgIlRyZWF0bWVudDEiLCAiVHJlYXRtZW50MiIpLCBwcm9iID0gcHJlZiwgcmVwbGFjZSA9IFQpCiAgICAjIG9uIGNhbGN1bGUgbGVzIGZyw6lxdWVuY2VzIGVtcGlyaXF1ZXMKICAgIHQgPC0gdGFibGUoZ3JvdXBzKQogICAgaGF0cCA8LSB0L3N1bSh0KQogICAgIyBwdWlzIG9uIGNhbGN1bGUgbGEgc3RhdGlzdGlxdWUgZGUgdGVzdCBxdSdvbiBlbnJlZ2lzdHJlCiAgICBEIDwtIG4gKiBzdW0oKGhhdHAgLSBwcmVmKSBeIDIgLyBwcmVmKQogICAgc3RhdHMgPC0gYyhzdGF0cywgRCkKfQpgYGAKCmBgYHtyIGZpZy53aWR0aD0xMCwgd2FybmluZz1GfQojIG9uIGNyw6nDqSB1biBkYXRhZnJhbWUgYXZlYyBub3Mgc3RhdGlzdGlxdWVzIGRlIHRlc3RzIGNvbW1lIHVuaXF1ZSBjb2xvbm5lCnN0YXRzIDwtIGRhdGEuZnJhbWUoRCA9IHN0YXRzKQojIGV0IG9uIGNvbXBhcmUgbCdoaXN0b2dyYW1tZSBlbXBpcmlxdWUgw6AgbGEgZGVuc2l0w6kgYXN5bXB0b3RpcXVlCnBsb3RfZGVuc2l0ZV92c19oaXN0b2dyYW0gPC0gZ2dwbG90KCkgKwogICAgZ2VvbV9saW5lKGRhdGE9ZGF0YV9jaGlzcSwgYWVzKHggPSB4LCB5ID0gZGNoaXNxKSkgKwogICAgZ2VvbV9oaXN0b2dyYW0oZGF0YT1zdGF0cywgYWVzKHg9RCwgeSA9IC4uZGVuc2l0eS4uKSwgYmlucz01MCwgYWxwaGE9MC41KSArCiAgICB5bGFiKCJEZW5zaXTDqSBkZSBsYSBzdGF0aXN0aXF1ZSBkZSB0ZXN0IEQgc291cyBIMCIpICsKICAgIHhsYWIoImQiKSArCiAgICB4bGltKDAsIDEyKSArCiAgICB0aGVtZV9idygpCnBsb3RfZGVuc2l0ZV92c19oaXN0b2dyYW0KYGBgCgoKUGFzIHRyb3AgbWFsLCB2aXN1ZWxsZW1lbnQgISBMJ2Fkw6lxdWF0aW9uIGRldnJhaXQgw6p0cmUgZCdhdXRhbnQgbWVpbGxldXJlIHF1ZSAkbiQgZXN0IGdyYW5kIGRhbnMgdm9zIHNpbXVsYXRpb25zLgoKTm91cyBzYXZvbnMgw6AgcHLDqXNlbnQgY29tcGFyZXIgdW5lIGRpc3RyaWJ1dGlvbiBlbXBpcmlxdWUgZGlzY3LDqHRlIMOgIHVuZSBkaXN0cmlidXRpb24gZGUgcsOpZsOpcmVuY2UgZml4w6llLiBNYWlzIHF1ZSBzZSBwYXNzZS10LWlsIHNpIG9uIHNvdWhhaXRlIGNvbXBhcmVyIG5vdHJlIGRpc3RyaWJ1dGlvbiBlbXBpcmlxdWUgw6AgdW5lIGZhbWlsbGUgcGFyYW3DqXRyw6llIGRlIGRpc3RyaWJ1dGlvbnMgPwoKCiMgQWp1c3RlbWVudCDDoCB1bmUgZmFtaWxsZSBkZSBsb2kgcGFyYW3DqXRyw6llCgojIyBDb250ZXh0ZSBmb3JtYWxpc8OpCgpDb21tZSBwcsOpY8OpZGVtbWVudCwgb24gZGlzcG9zZSBkJ3VuIMOpY2hhbnRpbGxvbiAkWCQgZGUgdGFpbGxlICRuJCwgdGlyw6kgZGFucyB1bmUgbG9pICRwJCBpbmNvbm51ZSBwcmVuYW50IGRlcyB2YWxldXJzIGRhbnMgdW4gZW5zZW1ibGUgZmluaSAkXG1hdGhjYWx7WH0kIGRlICRkJCB2YWxldXJzLgoKQ2VwZW5kYW50LCBwbHV0w7R0IHF1ZSBkZSBjb21wYXJlciDDoCB1bmUgZGlzdHJpYnV0aW9uIGRlIHLDqWbDqXJlbmNlIGZpeMOpZSAkcF5cdGV4dHtyZWZ9JCwgb24gc291aGFpdGUgw6AgcHLDqXNlbnQgc2F2b2lyIHNpIG5vdHJlIMOpY2hhbnRpbGxvbiBhIMOpdMOpIHRpcsOpZSBkYW5zIHVuZSBsb2kgZGUgcHJvYmFiaWxpdMOpIGFwcGFydGVuYW50IMOgIHVuZSBjZXJ0YWluZSBmYW1pbGxlIGRlIGxvaXMgcGFyYW3DqXRyw6llcyBwYXIgdW4gb3UgcGx1c2lldXJzIHLDqWVscy4gT24gbm90ZSBjZXR0ZSBmYW1pbGxlCiQkXG1hdGhjYWx7UH0gPSBceyBwKFx0aGV0YSksIFx0aGV0YSBcaW4gXFRoZXRhIFxzdWJzZXQgXG1hdGhiYntSfV5rIFx9LiQkCgpPbiBzb3VoYWl0ZSB0ZXN0ZXIgOgoKKiBIMCA6ICRwIFxpbiBcbWF0aGNhbHtQfSQsCiogSDEgOiAkcCBcbm90aW4gXG1hdGhjYWx7UH0kLgoKIyMgQ29udGV4dGUgcHJhdGlxdWUKClJlcHJlbm9ucyBub3RyZSBleGVtcGxlIHByw6ljw6lkZW50IGF2ZWMgbm9zIHRyb2lzIGdyb3VwZXMgOiAkXG1hdGhjYWx7WH0gPSBceyBcdGV4dHtDb250cm9sLCBUcmVhdG1lbnQxLCBUcmVhdG1lbnQyfSBcfSQuIApPbiBwb3VycmFpdCBzZSBwb3NlciBsYSBxdWVzdGlvbiBzdWl2YW50ZSA6CgoqIEgwIDogbGVzIGRldXggZ3JvdXBlcyB0cmFpdGVtZW50IG9udCBsYSBtw6ptZSBwcm9iYWJpbGl0w6kgZCfDqnRyZSBjaG9pc2lzCiogSDEgOiBsJ3VuIGRlcyBkZXV4IGdyb3VwZXMgYSB1bmUgcHJvYmFiaWxpdMOpIGRpZmbDqXJlbnRlIGQnYXBwYXJhw650cmUuCgpVbmUgZGVzIGZhw6dvbnMgZGUgZmFpcmUgcG91cnJhaXQgw6p0cmUgZGUgY2hlcmNoZXIgw6AgdGVzdGVyIGwnYWTDqXF1YXRpb24gZGUgbm9zIG9ic2VydmF0aW9ucyBhdmVjIGxhIGZhbWlsbGUgZGUgbG9pcyBwYXJhbcOpdHLDqWVzIHN1aXZhbnRlIDogCiQkClx7IChcdGhldGEsIFxmcmFjezEtXHRoZXRhfXsyfSwgXGZyYWN7MS1cdGhldGF9ezJ9KSwgXHRoZXRhIFxpbiAoMCwxKSBcfS4KJCQKCkxhIHByb2JhYmlsaXTDqSBkJ8OqdHJlIGNob2lzaSBkYW5zIGxlIGdyb3VwZSBjb250csO0bGUgZXN0IHVuIHBhcmFtw6h0cmUgbGlicmUuIFVuZSBmb2lzIGZpeMOpLCBsZXMgcHJvYmFiaWxpdMOpcyBkJ8OqdHJlIGRhbnMgY2hhY3VuIGRlcyBkZXV4IGdyb3VwZXMgdHJhaXRlbWVudCBzb250IMOpZ2FsZXMgZXQgZml4w6llcyDDqWdhbGVtZW50LgoKIyMgQ2UgcXVlIGRpdCBsYSB0aMOpb3JpZQoKRGFucyB1biBwcmVtaWVyIHRlbXBzLCBvbiB2YSBlc3RpbWVyIGxlIHBhcmFtw6h0cmUgJFx0aGV0YSQgcGFyIHNvbiBlc3RpbWF0ZXVyIGRlIG1heGltdW0gZGUgdnJhaXNlbWJsYW5jZSAkXGhhdHtcdGhldGF9JC4KCk9uIHBldXQgYWxvcnMgY2hlcmNoZXIgw6AgbWVzdXJlciBsYSAicHNldWRvLWRpc3RhbmNlIGR1ICRcY2hpXjIkIiBlbnRyZSBub3RyZSBkaXN0cmlidXRpb24gZW1waXJpcXVlICRcaGF0e3B9JCBldCB1bmUgZGlzdHJpYnV0aW9uIGRlIHLDqWbDqXJlbmNlIG9idGVudWUgZ3LDomNlIMOgIG5vdHJlIGVzdGltYXRldXIgZGUgbWF4aW11bSBkZSB2cmFpc2VtYmxhbmNlIDogJHAoXGhhdHtcdGhldGF9KSQuCiQkIEReMl9uKCBcaGF0e3B9LCBwKFxoYXR7XHRoZXRhfSkgKSA9IG4gXHN1bV97aT0xfV5kIFxmcmFje1xsZWZ0KCBcaGF0e3B9X2kgLSBwX2koXGhhdHtcdGhldGF9KSBccmlnaHQpXjJ9e3BfaShcaGF0e1x0aGV0YX0pfSAkJAoKSWwgZmF1dCBhbG9ycyBzJ2Fzc3VyZXIgcXVlICRwJCB2w6lyaWZpZSB1biBjZXJ0YWluIG5vbWJyZSBkZSBjb25kaXRpb25zIHRlY2huaXF1ZXMgOgoKKiBjJ2VzdCB1bmUgZm9uY3Rpb24gaW5qZWN0aXZlIGRlICRcVGhldGEkIGRhbnMgbCdlbnNlbWJsZSBkZXMgZGlzdHJpYnV0aW9ucyBkZSBwcm9iYWJpbGl0w6lzIHN1ciAkZCQgw6lsw6ltZW50cywKKiBjJ2VzdCB1bmUgZm9uY3Rpb24gZGUgY2xhc3NlICRcbWF0aGNhbHtDfV4yJCwKKiBhdWN1bmUgZGUgc2VzIGNvbXBvc2FudGVzIG5lIHMnYW5udWxlIHN1ciAkXFRoZXRhJCwKKiBzZXMgJGskIGTDqXJpdsOpZXMgcGFydGllbGxlcyBzb250IGxpbsOpYWlyZW1lbnQgaW5kw6lwZW5kYW50ZXMgZW4gdG91dCBwb2ludCBkZSAkXFRoZXRhJC4KClVuIHRow6lvcsOobWUgbm91cyBhc3N1cmUgYWxvcnMgcXVlLCBzb3VzIGNlcyBjb25kaXRpb25zLCAKCiogc291cyBIMCwgJEReMl9uKCBcaGF0e3B9LCBwKFxoYXR7XHRoZXRhfSkgKSQgdGVuZCBlbiBsb2kgdmVycyB1bmUgZGlzdHJpYnV0aW9uIGR1ICRcY2hpXjIkIMOgICRkLTEtayQgZGVncsOpcyBkZSBsaWJlcnTDqS4KKiBzb3VzIEgxLCAkRF4yX24oIFxoYXR7cH0sIHAoXGhhdHtcdGhldGF9KSApJCB0ZW5kIHZlcnMgbCdpbmZpbmkgcHJlc3F1ZSBzw7tyZW1lbnQuCgojIyBDb25zdHJ1Y3Rpb24gZHUgdGVzdAoKVG91dCBjb21tZSBwcsOpY8OpZGVtbWVudCwgb24gcmV0aWVuZHJhIGJpZW4gcXVlIGNlIHRow6lvcsOobWUgZXN0IHVuIHRow6lvcsOobWUgYXN5bXB0b3RpcXVlICEgT24gbmUgcG91cnJhIGRvbmMgbCdhcHBsaXF1ZXIgcG91ciBlZmZlY3R1ZXIgbm90cmUgdGVzdCBzdXIgZGUgdnJhaWVzIGRvbm7DqWVzIHF1ZSBwb3VyIGRlIGdyYW5kcyBlZmZlY3RpZnMgJG4kLgoKU2kgY2VzIGNvbmRpdGlvbnMgZCdlZmZlY3RpZnMgc3VmZmlzYW50cyBzb250IHJlc3BlY3TDqWVzLCBsZSB0ZXN0IGZvbmN0aW9ubmUgYWluc2kgOgoKKiBsJ2VzdGltYXRldXIgZGUgbWF4aW11bSBkZSB2cmFpc2VtYmxhbmNlICRcaGF0e1x0aGV0YX0kIGVzdCBjYWxjdWzDqSwKKiBsYSBzdGF0aXN0aXF1ZSBkZSB0ZXN0ICREXjJfbiggXGhhdHtwfSwgcChcaGF0e1x0aGV0YX0pICkkIGVzdCBjYWxjdWzDqWUsCiogb24gZml4ZSBsJ2VycmV1ciBkZSBwcmVtaWVyIG9yZHJlICRcYWxwaGEkIGFjY2VwdGFibGUsCiogb24gY2FsY3VsZSAkcV97MS1cYWxwaGF9JCwgbGUgcXVhbnRpbGUgZGUgbGEgbG9pIGR1ICRcY2hpXjIkIMOgICRkLTEtayQgZGVncsOpcyBkZSBsaWJlcnTDqSBkZSBuaXZlYXUgJDEtXGFscGhhJCwKKiBvbiByZWpldHRlIEgwIHNpICREXjJfbiggXGhhdHtwfSwgcF5cdGV4dHtyZWZ9ICkgPiBxX3sxLVxhbHBoYX0kLgoKSW50dWl0aXZlbWVudCwgb24gbWVzdXJlIHVuZSBwc2V1ZG8tZGlzdGFuY2UgZW50cmUgbm90cmUgZGlzdHJpYnV0aW9uIGVtcGlyaXF1ZSBldCBub3RyZSBkaXN0cmlidXRpb24gZGUgcsOpZsOpcmVuY2UsIGV0IG9uIHJlamV0dGUgbCdoeXBvdGjDqHNlIG51bGxlIGQnw6lnYWxpdMOpIGRlcyBkZXV4IGRpc3RyaWJ1dGlvbnMgbG9yc3F1ZSBjZXR0ZSBwc2V1ZG8tZGlzdGFuY2UgZGV2aWVudCB0cm9wIGdyYW5kZS4KCiMjIEV0IGF2ZWMgUiA/IHVuZSBjb25zdHJ1Y3Rpb24gYWQtaG9jCgpFdGFudCBkb25uw6llIGxlIG5vbWJyZSBpbW1lbnNlIGRlIHBvc3NpYmlsaXTDqXMgZGUgZmFtaWxsZXMgZGUgbG9pcywgbm91cyBuJ2F2b25zIHBhcyBpY2kgdW5lIHVuaXF1ZSBmb25jdGlvbiBxdWkgbm91cyByZW52ZXJyYWl0IGRpcmVjdGVtZW50IG5vdHJlIHLDqXBvbnNlIHN1ciB1biBwbGF0ZWF1IGQnYXJnZW50IGNvbW1lIHByw6ljw6lkZW1tZW50LiBNYWlzIMOgIHByw6lzZW50IHF1ZSBub3VzIGF2b25zIGJpZW4gY29tcHJpcyBsZXMgZGlmZsOpcmVudGVzIMOpdGFwZXMsIGlsIG4nZXN0IHBhcyB0cm9wIGRpZmZpY2lsZSBkJ2VuY2hhw65uZXIgY2VsbGVzLWNpIGF2ZWMgUi4KCkRhbnMgbm90cmUgZXhhbXBsZSBwcmF0aXF1ZSwgbm91cyBkZXZvbnMgdG91dCBkJ2Fib3JkIHRyb3V2ZXIgbCdlc3RpbWF0ZXVyIGRlIG1heGltdW0gZGUgdnJhaXNlbWJsYW5jZSBkZSAkXHRoZXRhJC4gT24gw6ljcml0IGRvbmMgbGEgdnJhaXNlbWJsYW5jZSA6CiQkIFxtYXRoY2Fse0x9KFx0aGV0YSkgPSBcdGhldGFee25fMX0gXGxlZnQoIFxmcmFjezEgLSBcdGhldGF9ezJ9IFxyaWdodClee25fMiArIG5fM30gJCQKb8O5ICRuXzEsIG5fMiwgbl8zJCBzb250IHJlc3BlY3RpdmVtZW50IGxlcyBlZmZlY3RpZnMgb2JzZXJ2w6lzIGRhbnMgbGVzIGdyb3VwZXMgY29udHLDtGxlLCB0cmFpdGVtZW50MSBldCB0cmFpdGVtZW50Mi4KCkxhIGxvZy12cmFpc2VtYmxhbmNlIGVzdCBhbG9ycwokJCBcbG4gXG1hdGhjYWx7TH0oXHRoZXRhKSA9IG5fMSBcbG4gXHRoZXRhICsgKG5fMiArIG5fMykgXGxuIFxmcmFjezEgLSBcdGhldGF9ezJ9ICQkCgpPbiBjaGVyY2hlIMOgIG1heGltaXNlciBjZXR0ZSBmb25jdGlvbiwgZW4gY2hlcmNoYW50IGNvbW1lbnQgYW5udWxlciBzYSBkw6lyaXbDqWUuIEV0IG9uIHRvbWJlIHN1ciB1biBlc3RpbWF0ZXVyIGFzc2V6IGNvaMOpcmVudCBhdmVjIGNlIHF1J29uIGF1cmFpdCBwdSBpbWFnaW5lciBpbnR1aXRpdmVtZW50IDoKJCQgXGhhdHtcdGhldGF9ID0gXGZyYWN7bl8xfXtufSAkJAoKYGBge3J9CiMgZXN0aW1hdGlvbiBkZSBwIGNoYXBlYXUgZXQgdGhldGEgY2hhcGVhdQp0IDwtIHRhYmxlKGQkZ3JvdXApCmhhdHAgPC0gdC9zdW0odCkKaGF0X3RoZXRhIDwtIGhhdHBbMV0KCiMgZG9udCBvbiBkw6lkdWl0IHAodGhldGEgY2hhcGVhdSkKcF9oYXRfdGhldGEgPSBjKGhhdF90aGV0YSwgKDEtaGF0X3RoZXRhKS8yLCAoMS1oYXRfdGhldGEpLzIpCgojIHF1J29uIHV0aWxpc2UgcG91ciBjYWxjdWxlciBsYSBzdGF0aXN0aXF1ZSBkZSB0ZXN0CkQgPC0gbiAqIHN1bSgoaGF0cCAtIHBfaGF0X3RoZXRhKSBeIDIgLyBwX2hhdF90aGV0YSkKCiMgb24gY2FsY3VsZSBldCBvbiBhZmZpY2hlIGxhIHAtdmFsdWUgYXNzb2Npw6llIGF1IHRlc3QKcHZhbCA8LSAxIC0gcGNoaXNxKEQsIGRmPTEpCnB2YWwKYGBgCgpMYSBwLXZhbHVlIGVzdCBncmFuZGUgOiBvbiBuZSBwZXV0IHBhcyByZWpldGVyIEgwIGRhbnMgbm90cmUgY2FzLgpFdCBwb3VyIGNhdXNlLCBvbiBhdmFpdCBiaWVuIHNpbXVsw6kgbm9zIGRvbm7DqWVzIHRlbGxlcyBxdWUgbGEgcHJvYmFiaWxpdMOpIGQnw6p0cmUgZGFucyBjaGFjdW4gZGVzIGRldXggZ3JvdXBlcyB0cmFpdGVtZW50IMOpdGFpdCDDqWdhbGUuCgpOb3VzIHNhdm9ucyDDoCBwcsOpc2VudCBjb21wYXJlciB1bmUgZGlzdHJpYnV0aW9uIGVtcGlyaXF1ZSBkaXNjcsOodGUgw6AgdW5lIGxvaSBkZSByw6lmw6lyZW5jZSBmaXjDqWUsIG91IMOgIHVuZSBmYW1pbGxlIGRlIGxvaSBwYXJhbcOpdHLDqWVzLiBOb3VzIGFsbG9ucyBtYWludGVuYW50IG5vdXMgaW50w6lyZXNzZXIgw6AgdW4gYXV0cmUgY2FzIGRlIGZpZ3VyZSBmcsOpcXVlbnQgOiB0ZXN0ZXIgbCdpbmTDqXBlbmRhbmNlIGRlIGRldXggZGlzdHJpYnV0aW9ucyBkaXNjcsOodGVzLgoKCiMgSW5kw6lwZW5kYW5jZSBkZSBkZXV4IGRpc3RyaWJ1dGlvbnMgZGlzY3LDqHRlcyBhcHBhcmnDqWVzCgojIyBDb250ZXh0ZSBmb3JtYWxpc8OpCgpPbiBkaXNwb3NlIGNldHRlIGZvaXMgZGUgJG4kIGNvdXBsZXMgZCdvYnNlcnZhdGlvbnMgZGUgdmFyaWFibGVzIGRpc2Nyw6h0ZXMgJChYX2ksIFlfaSkkIG1lc3Vyw6llcyBzdXIgY2hhcXVlIGluZGl2aWR1ICRpJC4gTGVzICQoWF9pKSQgc29udCDDoCB2YWxldXIgZGFucyB1biBlbnNlbWJsZSAkXG1hdGhjYWx7WH0kIMOgICRkJCDDqWzDqW1lbnRzLCB0YW5kaXMgcXVlIGxlcyAkKFlfaSkkIHNvbnQgw6AgdmFsZXVyIGRhbnMgdW4gZW5zZW1ibGUgJFxtYXRoY2Fse1l9JCDDoCAkZSQgw6lsw6ltZW50cy4KCk9uIHN1cHBvc2UgcXVlIG5vcyBjb3VwbGVzIHNvbnQgaW5kw6lwZW5kYW50cyBldCBpZGVudGlxdWVtZW50IGRpc3RyaWJ1w6lzIHNlbG9uIHVuZSBsb2kgJFxudSQgc3VyICRcbWF0aGNhbHtYfSBcdGltZXMgXG1hdGhjYWx7WX0kLiBUeXBpcXVlbWVudCwgdW5lIHRlbGxlIGRpc3RyaWJ1dGlvbiBzZXJhaXQgcGFyYW3DqXRyw6llIHBhciAkKGQgZSAtIDEpJCB2YWxldXJzLiAKCk9uIHNvdWhhaXRlIMOgIHByw6lzZW50IHNhdm9pciBzaSBsZXMgJFgkIGV0IGxlcyAkWSQgcHJlbm5lbnQgbGV1cnMgdmFsZXVycyBpbmTDqXBlbmRhbW1lbnQgbCd1biBkZSBsJ2F1dHJlLCBjJ2VzdCDDoCBkaXJlIHNpIGxhIGxvaSAkXG51JCBhcHBhcnRpZW50IMOgIGxhIGZhbWlsbGUgZGVzIGxvaXMgcHJvZHVpdC4KT24gbm90ZSBjZXR0ZSBmYW1pbGxlIDoKJCQgXG1hdGhjYWx7Rn0gPSBceyBwIFxvdGltZXMgcSwgfiBwIFxpbiBcbWF0aGNhbHtQfShcbWF0aGNhbHtYfSksIHEgXGluIFxtYXRoY2Fse1B9KFxtYXRoY2Fse1l9KSBcfSAkJApvw7kgJFxtYXRoY2Fse1B9KFxtYXRoY2Fse1h9KSQgZMOpc2lnbmUgbCdlbnNlbWJsZSBkZXMgZGlzdHJpYnV0aW9ucyBzdXIgbCdlbnNlbWJsZSBkaXNjcmV0ICRcbWF0aGNhbHtYfSQuCgpUeXBpcXVlbWVudCwgdW5lIGRpc3RyaWJ1dGlvbiBkZSAkXG1hdGhjYWx7Rn0kIG4nZXN0IGRvbmMgcGx1cyBwYXJhbcOpdHLDqWUgcXVlIHBhciAkKGQgKyBlIC0gMikkIHZhbGV1cnMgOiBsZXMgJChkLTEpJCB2YWxldXJzIHF1aSBwYXJhbcOpdHJpc2VudCAkcCQgZXQgbGVzICQoZS0xKSQgdmFsZXVycyBxdWkgcGFyYW3DqXRyaXNlbnQgJHEkLgoKQXZlYyBjZXMgbm90YXRpb25zLCBvbiBwb3VycmEgdGVzdGVyIDoKCiogSDAgOiAkXG51IFxpbiBcbWF0aGNhbHtGfSQsCiogSDEgOiAkXG51IFxub3RpbiBcbWF0aGNhbHtGfSQuCgojIyBDb250ZXh0ZSBwcmF0aXF1ZQoKT24gY29udGludWUgZGUgZmlsZXIgbGUgbcOqbWUgZXhlbXBsZSBxdWUgcHLDqWPDqWRlbW1lbnQuClBvdXIgY2hhcXVlIGluZGl2aWR1ICRpJCwgb24gb2JzZXJ2ZSBsZSBzZXhlICRYX2kkIGV0IGxlIGdyb3VwZSAkWV9pJC4gT24gc2UgZGVtYW5kZSBzaSBsZSBjaG9peCBkdSBncm91cGUgZXN0IGluZMOpcGVuZGFudCBkdSBzZXhlLgoKKiBIMCA6IGxlIGNob2l4IGR1IGdyb3VwZSBlc3QgaW5kw6lwZW5kYW50IGR1IHNleGUgKGkuZS4gbGEgbG9pIGpvaW50ZSBhcHBhcnRpZW50IMOgIGxhIGZhbWlsbGUgZGUgbG9pcyBwcm9kdWl0ICRcbWF0aGNhbHtGfSQpLAoqIEgxIDogbGUgY2hvaXggZHUgZ3JvdXBlIGTDqXBlbmQgZHUgc2V4ZS4KCiMjIENlIHF1ZSBkaXQgbGEgdGjDqW9yaWUKCk9uIHBldXQgZXN0aW1lciBjaGFjdW4gZGVzICRwX2kkIHBhciBsYSBmcsOpcXVlbmNlIGVtcGlyaXF1ZSBkZSBsJ29ic2VydmF0aW9uICR4X2kkLCBjJ2VzdCDDoCBkaXJlIDoKJCQgXGhhdHtwfV9pID0gXGZyYWN7MX17bn0gXHN1bV97az0xfV5uIFxkZWx0YV97WF9rID0geF9pfSAkJApPbiBwZXV0IMOpZ2FsZW1lbnQgZmFpcmUgZGUgbcOqbWUgcG91ciBsZXMgZnLDqXF1ZW5jZXMgZW1waXJpcXVlcyBkZXMgJHlfaiQsIGVuIGNhbGN1bGFudCA6CiQkIFxoYXR7cX1faiA9IFxmcmFjezF9e259IFxzdW1fe2s9MX1ebiBcZGVsdGFfe1lfayA9IHlfan0gJCQKRXQgZW5maW4sIGZhaXJlIGRlIG3Dqm1lIHBvdXIgbGVzIGZyw6lxdWVuY2VzIGVtcGlyaXF1ZXMgZGVzIGRpZmbDqXJlbnRzIGNvdXBsZXMgJCh4X2ksIHlfaikkIDoKJCQgXGhhdHtcbnV9X3tpLGp9ID0gXGZyYWN7MX17bn0gXHN1bV97az0xfV5uIFxkZWx0YV97KFhfaywgWV9rKSA9ICh4X2ksIHlfail9ICQkCgpPbiBzb3VoYWl0ZSBlbnN1aXRlIG1lc3VyZXIgbGEgInBzZXVkby1kaXN0YW5jZSBkdSAkXGNoaV4yJCIgZW50cmUgbGEgZGlzdHJpYnV0aW9uIGVtcGlyaXF1ZW1lbnQgb2JzZXJ2w6llICRcaGF0e1xudX0kIGV0IGNlbGxlIGRvbm7DqWUgcGFyIGxlIG1laWxsZXVyIGFqdXN0ZW1lbnQgw6AgdW5lIGxvaSBwcm9kdWl0ICRcaGF0e3B9IFxvdGltZXMgXGhhdHtxfSQsIHNvaXQgOgokJCBEXjJfbiggXGhhdHtcbnV9LCBcaGF0e3B9XG90aW1lc1xoYXR7cX0gKSA9IApuIFxzdW1fe2k9MX1eZCBcc3VtX3tqPTF9XmUgXGZyYWN7XGxlZnQoIFxoYXR7XG51fV97aSxqfSAtIFxoYXR7cH1faSBcaGF0e3F9X2ogXHJpZ2h0KV4yfXtcaGF0e3B9X2kgXGhhdHtxfV9qfSAkJAoKVW4gdGjDqW9yw6htZSBub3VzIGFzc3VyZSBhbG9ycyBxdWUKCiogc291cyBIMCwgJEReMl9uKCBcaGF0e1xudX0sIFxoYXR7cH1cb3RpbWVzXGhhdHtxfSApJCB0ZW5kIGVuIGxvaSB2ZXJzIHVuZSBkaXN0cmlidXRpb24gZHUgJFxjaGleMiQgw6AgJChkLTEpIChlLTEpJCBkZWdyw6lzIGRlIGxpYmVydMOpLgoqIHNvdXMgSDEsICREXjJfbiggXGhhdHtcbnV9LCBcaGF0e3B9XG90aW1lc1xoYXR7cX0gKSQgdGVuZCB2ZXJzIGwnaW5maW5pIHByZXNxdWUgc8O7cmVtZW50LgoKUG91ciBjZXV4IHF1aSBzb3VoYWl0ZXJhaWVudCBzYXZvaXIgZCdvw7kgdmllbnQgbGUgbm9tYnJlIGRlIGRlZ3LDqXMgZGUgbGliZXJ0w6ksIG5vdGV6IHF1ZSwgY29tbWUgcHLDqWPDqWRlbW1lbnQsIGlsIGNvcnJlc3BvbmQgw6AgbGEgZGltZW5zaW9uIGRlIGwnZXNwYWNlIGRhbnMgbGVxdWVsIHZpdCBsYSBsb2kgZGUgcHJvYmFiaWxpdMOpICRcbnUkIChzb2l0ICRkZSAtMSQpIG1vaW5zIGxhIGRpbWVuc2lvbiBkZSBsJ2VzcGFjZSBkYW5zIGxlcXVlbCB2aXQgbGEgZGlzdHJpYnV0aW9uIMOgIGxhcXVlbGxlIG9uIHNvdWhhaXRlIHNlIHJhbWVuZXIgKGljaSAkZCArIGUgLSAyJCkuCgojIyBDb25zdHJ1Y3Rpb24gZHUgdGVzdAoKQ29tbWUgdG91am91cnMgYXZlYyBsZXMgdGVzdHMgZHUgJFxjaGleMiQsIG5vdHJlIHRlc3QgcmVwb3NlIHN1ciB1biB0aMOpb3LDqG1lIGFzeW1wdG90aXF1ZSA6IG9uIG5lIHBldXQgZG9uYyBsJ2FwcGxpcXVlciBwb3VyIGVmZmVjdHVlciBub3RyZSB0ZXN0IHN1ciBkZSB2cmFpZXMgZG9ubsOpZXMgcXVlIHBvdXIgZGUgZ3JhbmRzIGVmZmVjdGlmcyAkbiQgIQoKU2kgY2VzIGNvbmRpdGlvbnMgZCdlZmZlY3RpZnMgc3VmZmlzYW50cyBzb250IHJlc3BlY3TDqWVzLCBsZSB0ZXN0IGZvbmN0aW9ubmUgYWluc2kgOgoKKiBsYSBzdGF0aXN0aXF1ZSBkZSB0ZXN0ICREXjJfbiggXGhhdHtcbnV9LCBcaGF0e3B9XG90aW1lc1xoYXR7cX0gKSQgZXN0IGNhbGN1bMOpZSwKKiBvbiBmaXhlIGwnZXJyZXVyIGRlIHByZW1pZXIgb3JkcmUgJFxhbHBoYSQgYWNjZXB0YWJsZSwKKiBvbiBjYWxjdWxlICRxX3sxLVxhbHBoYX0kLCBsZSBxdWFudGlsZSBkZSBuaXZlYXUgJDEtXGFscGhhJCBkZSBsYSBsb2kgZHUgJFxjaGleMiQgw6AgJChkLTEpIChlLTEpJCBkZWdyw6lzIGRlIGxpYmVydMOpLAoqIG9uIHJlamV0dGUgSDAgc2kgJEReMl9uKCBcaGF0e1xudX0sIFxoYXR7cH1cb3RpbWVzXGhhdHtxfSApID4gcV97MS1cYWxwaGF9JC4KCkludHVpdGl2ZW1lbnQsIG9uIG1lc3VyZSB1bmUgcHNldWRvLWRpc3RhbmNlIGVudHJlIG5vdHJlIGRpc3RyaWJ1dGlvbiBlbXBpcmlxdWUgZXQgbm90cmUgbWVpbGxldXJlIGVzdGltYXRpb24gZGUgbG9pIHByb2R1aXQsIGV0IG9uIHJlamV0dGUgbCdoeXBvdGjDqHNlIG51bGxlIGQnw6lnYWxpdMOpIGRlcyBkZXV4IGRpc3RyaWJ1dGlvbnMgbG9yc3F1ZSBjZXR0ZSBwc2V1ZG8tZGlzdGFuY2UgZGV2aWVudCB0cm9wIGdyYW5kZS4KCiMjIEV0IGF2ZWMgUiA/IHZlcnNpb24gY291cnRlCgpEYW5zIG5vdHJlIGV4YW1wbGUsIG9uIHNvdWhhaXRlIHRlc3RlciBsJ2luZMOpcGVuZGFuY2UgZHUgc2V4ZSBldCBkdSBncm91cGUgY2hleiBub3MgaW5kaXZpZHVzLgpFbiB1bmUgbGlnbmUsIGlsIG5vdXMgc3VmZml0IGQnw6ljcmlyZSA6CgpgYGB7cn0KY2hpc3EudGVzdCh0YWJsZShkJHNleCwgZCRncm91cCkpCmBgYAoKT3UgZW5jb3JlLCBwb3VyIHVuIHLDqXN1bHRhdCDDqXF1aXZhbGVudCBhdmVjIHVuZSBzeW50YXhlIGRpZmbDqXJlbnRlLAoKYGBge3J9CmNoaXNxLnRlc3QoZCRzZXgsIGQkZ3JvdXApCmBgYAoKTGEgcC12YWx1ZSBncmFuZGUgbm91cyBwb3Vzc2UgaWNpIMOgIGNvbnNlcnZlciBIMCBwYXIgZMOpZmF1dCA6IG9uIG5lIHBldXQgcGFzIHJlamV0ZXIgbCdoeXBvdGjDqHNlIG51bGxlIGQnaW5kw6lwZW5kYW5jZSBkdSBzZXhlIGV0IGR1IGdyb3VwZS4KCiMjIyBFdCBhdmVjIFIgPyB2ZXJzaW9uIGxvbmd1ZQoKUG91ciBzZSBjb252YWluY3JlIHF1ZSB0b3V0IGZvbmN0aW9ubmUgYmllbiwgaWwgcGV1dCDDqnRyZSB1dGlsZSBkZSBjYWxjdWxlciBldCBhZmZpY2hlciBjZXJ0YWluZXMgcXVhbnRpdMOpcy4KCmBgYHtyfQojIGxhIHRhYmxlIGRlcyBmcsOpcXVlbmNlcyBlbXBpcmlxdWVzIGVzdCB0b3Vqb3VycyBpbnTDqXJlc3NhbnRlIMOgIGFmZmljaGVyCnQgPC0gdGFibGUoZCRzZXgsIGQkZ3JvdXApCnQKYGBgCgpgYGB7cn0KIyBvbiBwZXV0IGNhbGN1bGVyIGxlcyBmcsOpcXVlbmNlcyBtYXJnaW5hbGVzCnRvdCA8LSBzdW0odCkKaGF0cCA8LSByb3dTdW1zKHQpL3RvdApoYXRwCmhhdHEgPC0gY29sU3Vtcyh0KS90b3QKaGF0cQpgYGAKCmBgYHtyfQojIGxhIGxvaSBwcm9kdWl0IG9idGVudWUgZ3LDomdlIMOgIGhhdHAgZXQgaGF0cQpoYXRwcSA8LSBoYXRwICVvJSBoYXRxCmhhdHBxCmBgYAoKYGBge3J9CiMgbCdlc3RpbWF0aW9uIGRlIGhhdG51CmhhdG51IDwtIHQvdG90CmhhdG51CmBgYAoKYGBge3J9CiMgZXQgZW5maW4gbGEgc3RhdGlzdGlxdWUgZGUgdGVzdApEIDwtIG4gKiBzdW0oKGhhdG51IC0gaGF0cHEpIF4gMiAvIGhhdHBxKQpECmBgYAoKYGBge3J9CiMgcXUnb24gcGV1dCB1dGlsaXNlciBwb3VyIGNhbGN1bGVyIGxhIHAtdmFsdWUKcHZhbCA8LSAxIC0gcGNoaXNxKEQsIGRmPTIpCnB2YWwKYGBgCgpDZXR0ZSBwLXZhbHVlIHBvdXJyYWl0IMOqdHJlIHJlcG9ydMOpZSBjb21tZSBwcsOpY8OpZGVtbWVudCBzdXIgbGUgZ3JhcGhlIGRlIGRlbnNpdMOpIGRlIGxhIGxvaSBkdSAkXGNoaV4yJCBxdWUgc3VpdCBub3RyZSBzdGF0aXN0aXF1ZSBkZSB0ZXN0IHNvdXMgSDAuIElsIHNlIHRyb3V2ZSBjZXBlbmRhbnQgcXUnaWNpIGMnZXN0IGV4YWN0ZW1lbnQgbGEgbcOqbWUgbG9pLCBldCBjZSBuJ2VzdCBkb25jIHBhcyB0csOocyBpbnTDqXJlc3NhbnQgw6AgcsOpcMOpdGVyLgoKTm91cyBzYXZvbnMgw6AgcHLDqXNlbnQgdXRpbGlzZXIgbm90cmUgdGVzdCBkdSAkXGNoaV4yJCBwb3VyIHRlc3RlciBsJ2luZMOpcGVuZGFuY2UgZGUgZGV1eCBkaXN0cmlidXRpb25zIGRpc2Nyw6h0ZXMgYXBwYXJpw6llcy4gVm95b25zIMOgIHByw6lzZW50IGNvbW1lbnQgb24gcGV1dCBhZGFwdGVyIGNlcyByw6lzdWx0YXRzIHBvdXIgdGVzdGVyIGwnaG9tb2fDqW7DqWl0w6kgZGUgcGx1c2lldXJzIMOpY2hhbnRpbGxvbnMgZGlzY3JldHMuCgoKIyBIb21vZ8OpbsOpaXTDqSBkZSBwbHVzaWV1cnMgw6ljaGFudGlsbG9ucyBkaXNjcmV0cwoKIyMgQ29udGV4dGUgZm9ybWFsaXPDqQoKT24gb2JzZXJ2ZSB1biDDqWNoYW50aWxsb24gZGUgdGFpbGxlICRuXzEkICRYXnsoMSl9ID0gKFheeygxKX1fMSwgWF57KDEpfV8yLCAuLi4sIFheeygxKX1fe25fMX0pJCBhaW5zaSBxdSd1biDDqWNoYW50aWxsb24gZGUgdGFpbGxlICRuXzIkLCAkWF57KDIpfSQuCgpPbiBzdXBwb3NlIHF1ZSBsZXMgJChYX2leeygxKX0pJCBwcm92aWVubmVudCBkZSB2YXJpYWJsZXMgYWzDqWF0b2lyZXMgaW5kw6lwZW5kYW50ZXMgZXQgaWRlbnRpcXVlbWVudCBkaXN0cmlidcOpZXMgc2Vsb24gdW5lIGxvaSAkcF57KDEpfSQgZXQgcXVlIGxlcyAkKFhfaV57KDIpfSkkIHByb3ZpZW5uZW50IGRlIHZhcmlhYmxlcyBhbMOpYXRvaXJlcyBpbmTDqXBlbmRhbnRlcyBldCBpZGVudGlxdWVtZW50IGRpc3RyaWJ1w6llcyBzZWxvbiB1bmUgbG9pICRwXnsoMil9JC4KCk9uIHNvdWhhaXRlIHRlc3RlciA6CgoqIEgwIDogJHBeeygxKX0gPSBwXnsoMil9JCwKKiBIMCA6ICRwXnsoMSl9IFxuZXEgcF57KDIpfSQuCgojIyBDb250ZXh0ZSBwcmF0aXF1ZQoKSW1hZ2lub25zIHF1J3VuIGRldXhpw6htZSBjZW50cmUgZGUgcmVjcnV0ZW1lbnQgb3V2cmUsIGV0IHF1J2lsIHJlY3J1dGUgw6lnYWxlbWVudCBkZXMgaW5kaXZpZHVzIGRhbnMgdHJvaXMgZ3JvdXBlcyBjb21tZSBwcsOpY8OpZGVtbWVudCA6IGNvbnRyw7RsZSwgdHJhaXRlbWVudDEgZXQgdHJhaXRlbWVudDIuCgpgYGB7cn0KbjIgPC0gODAKZDIgPC0gZGF0YS5mcmFtZShzZXggPSBzYW1wbGUoc2l6ZSA9IG4yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gYygiRiIsICJNIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2IgPSBjKDAuNSwgMC41KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZSA9IFQpLAogICAgICAgICAgICAgICAgZ3JvdXAgPSBzYW1wbGUoc2l6ZSA9IG4yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSBjKCJDb250cm9sIiwgIlRyZWF0bWVudDEiLCAiVHJlYXRtZW50MiIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2IgPSBjKDAuMzUsIDAuMzUsIDAuMyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZSA9IFQpKQpgYGAKCk9uIHBldXQgY2hlcmNoZXIgw6AgdGVzdGVyIDoKCiogSDAgOiBsYSBkaXN0cmlidXRpb24gZGVzIHRyb2lzIGdyb3VwZXMgZXN0IGlkZW50aXF1ZSBkYW5zIGxlIHByZW1pZXIgY2VudHJlIChkYXRhc2V0IGQpIGV0IGRhbnMgbGUgc2Vjb25kIGNlbnRyZSAoZGF0YXNldCBkMikuCiogSDEgOiBsZXMgZGV1eCBkaXN0cmlidXRpb25zIHNvbnQgZGlmZsOpcmVudGVzLgoKIyMgQ2UgcXVlIGRpdCBsYSB0aMOpb3JpZQoKUG91ciByw6lwb25kcmUgw6AgbGEgcXVlc3Rpb24sIG9uIHZhIGNoZXJjaGVyIMOgIHNlIHJhbWVuZXIgYXUgY2FzIHByw6ljw6lkZW50LgpPbiB2YSBmb3JtZXIgJG5fMSArIG5fMiQgcGFpcmVzIGQnb2JzZXJ2YXRpb25zICQoWF9pLCBZX2kpJCwgYXZlYyA6CgoqIHBvdXIgJGkgXGxlcSBuXzEkLCAkKFhfaSwgWV9pKSA9IChYX2leeygxKX0sIDEpJCwKKiBwb3VyICRuXzEgPCBpIFxsZXEgbl8xK25fMiQsICQoWF9pLCBZX2kpID0gKFhfaV57KDIpfSwgMikkLgoKTm90cmUgdGVzdCBwZXV0IGFsb3JzIHNlIHJlZm9ybXVsZXIgZW4gOgoKKiBIMCA6IGxlcyB2YXJpYWJsZXMgJFgkIGV0ICRZJCBzb250IGluZMOpcGVuZGFudGVzLCBjJ2VzdCDDoCBkaXJlIGxhIGxvaSBqb2ludGUgY29ycmVzcG9uZCDDoCBsYSBsb2kgcHJvZHVpdCBkZXMgJFgkIGV0ICRZJC4KKiBIMSA6IGxlcyBkZXV4IHZhcmlhYmxlcyBuZSBzb250IHBhcyBpbmTDqXBlbmRhbnRlcy4KCkV0IGMnZXN0IHRvdXQuCkV0IMOnYSBmb25jdGlvbm5lcmFpdCBlbmNvcmUgZGUgbGEgbcOqbWUgZmHDp29uIGF2ZWMgcGx1cyBxdWUgZGV1eCDDqWNoYW50aWxsb25zLgpGaW5hbGVtZW50LCB0ZXN0ZXIgbCdob21vZ8OpbsOpaXTDqSBkZSBwbHVzaWV1cnMgw6ljaGFudGlsbG9ucyByZXZpZW50IHNpbXBsZW1lbnQgw6AgY3LDqWVyIHVuZSB2YXJpYWJsZSBjb3JyZXNwb25kYW50IGF1IG51bcOpcm8gZGUgbCfDqWNoYW50aWxsb24sIGV0IMOgIHRlc3RlciBsJ2luZMOpcGVuZGFuY2UgZW50cmUgbGUgbnVtw6lybyBkZSBsJ8OpY2hhbnRpbGxvbiBldCBsYSB2YXJpYWJsZSBkJ2ludMOpcsOqdC4KCiMjIEV0IGF2ZWMgUiA/CgpOb3VzIGF2b25zIGTDqWrDoCBmYWl0IHRvdXQgbGUgYm91bG90IHByw6ljw6lkZW1tZW50LiBGaW5hbGVtZW50LCBpbCBuZSBzJ2FnaXQgaWNpIHF1ZSBkZSBtYW5pcHVsZXIgbm9zIGRvbm7DqWVzIHBvdXIgbm91cyBwbGFjZXIgZGFucyBsZSBtw6ptZSBjYXMgZGUgZmlndXJlLgoKYGBge3J9CiMgb24gcmFqb3V0ZSDDoCBjaGFjdW4gZGVzIGRldXggZGF0YXNldHMgdW5lIG5vdXZlbGxlIGNvbG9ubmUgImNlbnRyZSIKZCA8LSBkICU+JSBtdXRhdGUoY2VudGVyID0gcmVwKCJDZW50ZXIxIiwgbikpCmQyIDwtIGQyICU+JSBtdXRhdGUoY2VudGVyID0gcmVwKCJDZW50ZXIyIiwgbjIpKQoKIyBvbiBjb2xsZSBsZXMgbGlnbmVzIGRlIGQyIMOgIGxhIHN1aXRlIGRlIGQxCmRmIDwtIHJiaW5kKGQsIGQyKQoKIyBldCBvbiBlZmZlY3R1ZSBub3RyZSB0ZXN0IGQnaW5kw6lwZW5kYW5jZSBlbnRyZSBsYSB2YXJpYWJsZSBkZSBjZW50cmUgZXQgbGEgdmFyaWFibGUgZGUgZ3JvdXBlCnRhYmxlKGRmJGdyb3VwLCBkZiRjZW50ZXIpCmNoaXNxLnRlc3QodGFibGUoZGYkZ3JvdXAsIGRmJGNlbnRlcikpCmBgYAoKTGEgcC12YWx1ZSBncmFuZGUgbm91cyBpbmNpdGUgaWNpIMOgIGNvbnNlcnZlciBIMCBwYXIgZMOpZmF1dC4KTm90ZXogcXVlIGxlcyBzaW11bGF0aW9ucyDDqXRhaWVudCBwb3VydGFudCByw6lhbGlzw6llcyDDoCBwYXJ0aXIgZGUgbG9pIHNvdXMtamFjZW50ZXMgbMOpZ8OocmVtZW50IGRpZmbDqXJlbnRlcy4gVHJvcCBsw6lnw6hyZW1lbnQgZGlmZsOpcmVudGVzLCB2aXNpYmxlbWVudCwgcG91ciBxdWUgbm90cmUgdGVzdCBhaXQgYXNzZXogZGUgcHVpc3NhbmNlIHBvdXIgbGVzIGRpc2NyaW1pbmVyLiBPbiBvYnRpZW5kcmEgw6l2aWRlbW1lbnQgcGx1cyBkZSBwdWlzc2FuY2UgZW4gYXVnbWVudGFudCBsZXMgZWZmZWN0aWZzLCBvdSBlbiBhdWdtZW50YW50IGxhIGRpZmbDqXJlbmNlIGVudHJlIGxlcyBkaXN0cmlidXRpb25zIGRlIHByb2JhYmlsaXTDqS4KCgojIENvbmNsdXNpb24KClMnaWwgeSBhIGJpZW4gZGV1eCBjaG9zZXMgw6AgcmV0ZW5pciDDoCBwcm9wb3MgZHUgdGVzdCBkdSAkXGNoaV4yJCwgbGVzIHZvaWNpIDoKCjEuIGlsIHMnYXBwbGlxdWUgcG91ciBjb21wYXJlciBkZXMgZGlzdHJpYnV0aW9ucyBkaXNjcsOodGVzIDogc29pdCB1bmUgZGlzdHJpYnV0aW9uIMOgIHVuZSBkaXN0cmlidXRpb24gZGUgcsOpZsOpcmVuY2UsIHNvaXQgdW5lIGRpc3RyaWJ1dGlvbiDDoCB1bmUgZmFtaWxsZSBkZSBkaXN0cmlidXRpb25zLCBzb2l0IHBsdXNpZXVycyBkaXN0cmlidXRpb25zIGVtcGlyaXF1ZXMgZW5zZW1ibGUuCjIuIGlsIHJlcG9zZSBzdXIgZGVzIHLDqXN1bHRhdHMgYXN5bXB0b3RpcXVlcyA6IGV0IHJlcXVpZXJ0IGRvbmMgZGUgZ3JhbmRzIGVmZmVjdGlmcyAhCgo=