Kennzahlen

Umfang

\(n\) = Stichprobenumfang
\(N\) = Umfang der Population

Arithmetisches Mittel, Mittelwert

\(\bar{x}\) = Stichprobenmittelwert
\(\mu\) = Populationsmittelwert

\[\bar{x} = \frac{\sum_{i=1}^n x_i}{n}\]

mean()

Beispiel:

x <- c(2, 3, 4, 4, 5, 6)
mean(x)
## [1] 4

Median

wenn \(n\) ungerade

\[\tilde{x} = x_{\frac{n+1}{2}}\]

wenn \(n\) gerade

\[\tilde{x} = \frac{1}{2}(x_{\frac{n}{2}} + {x_{\frac{n}{2}+1}})\]

median()

Beispiel:

x <- c(2, 3, 4, 4, 5, 6, 10)
median(x)
## [1] 4

Varianz

\(s^2\) = Stichprobenvarianz
\(\sigma^2\) = Varianz der Population

\[s^2 = \frac{\sum_{i=1}^n (x_i - \bar{x})^2}{n-1}\]

\[\sigma^2 = \frac{\sum_{i=1}^n (x_i - \mu)^2}{n}\]

var()

Beispiel:

x <- c(2, 3, 4, 4, 5, 6, 10)
var(x)
## [1] 6.809524

Standardabweichung

\(s\) = Standardabweichung der Stichprobe
\(\sigma\) = Standardabweichung der Population

\[s = \sqrt{s^2}\]

\[\sigma = \sqrt{\sigma^2}\]

sd()

Beispiel:

x <- c(2, 3, 4, 4, 5, 6, 10)
sd(x)
## [1] 2.609506

Grafiken

Histogramm

hist()

Beispiel:

x <- c(2, 3, 4, 4, 5, 6, 10, 9, 8, 7, 7, 7, 5, 4)
hist(x)

Boxplot

boxplot()

Beispiel:

x <- c(2, 3, 4, 4, 5, 6, 10, 9, 8, 7, 7, 7, 5, 4)
boxplot(x)

Kreuztabelle, absolute Häufigkeiten

table()

Beispiel:

x <- c("a", "a", "b", "b", "b", "c")
table(x)
## x
## a b c 
## 2 3 1

Kreuztabelle, relative Häufigkeiten

prop.table()

Beispiel:

x = c("a", "a", "b", "b", "b", "c")
prop.table(table(x))
## x
##         a         b         c 
## 0.3333333 0.5000000 0.1666667

Balkendiagramm

barplot()

Beispiel:

x = c("a", "a", "b", "b", "b", "c")
barplot(table(x))




Wahrscheinlichkeiten

Wahrscheinlichkeit

  • Unter Wahrscheinlichkeit versteht man die Chance, dass bei einem Zufallsexperiment ein bestimmtes Ereignis auftritt.
  • Wahrscheinlichkeiten können nur Werte zwischen 0 (unmögliches Ereignis) und 1 (sicheres Ereignis) zugeordnet werden.
  • Nach Laplace ist die Wahrscheinlichkeit für ein günstiges Ereignis \(p(A)\):

\[p(A) = \frac{n_A}{N_{gesamt}} = \frac{Anzahl~der~günstigen~Ereignisse}{Anzahl~der~möglichen~Ereignisse}\]

Ereignis und Gegenereignis

\[p(A) + p(Nicht~A) = 1\]

Bedingte Wahrscheinlichkeiten

  • Die bedingte Wahrscheinlichkeit \(p(A|B)\) quantifiziert die Wahrscheinlichkeit des Ereignisses A unter der Bedingung, dass das Ereignis B eingetreten ist.

\[p(A|B) = \frac{p(A \cap B)}{P(B)}\]

  • Das Zeichen \(\cap\) ist das mathematische Symbol für UND (Schnittmenge von A und B).
  • Das Theorem von Bayes gibt an, wie man eine bedingte Wahrscheinlichkeit \(p(A|B)\) aus der umgekehrten bedingten Wahrscheinlichkeit \(p(B|A)\) berechnen kann.

\[p(A|B)= \frac{p(A) \times p(B|A)}{p(B)}\]

Unabhängigkeit

  • Zwei Ereignisse \(A\) und \(B\) sind unabhängig, wenn das Eintreffen oder Nicht-Eintreffen des Ereignisses \(B\) die Wahrscheinlichkeit für ein Ereignis \(A\) nicht verändert.

\[p(A) = p(A|B) ~, ~p(B) = p(B|A)\]




Normalverteilung

\[X \sim N(\mu, \sigma)\]

68-95-99.7-Regel

  • 68% in \(\mu \pm 1\sigma\)
  • 95% in \(\mu \pm 2\sigma\), genauer \(\mu \pm 1.96\sigma\)
  • 99.7% in \(\mu \pm 3\sigma\)

z-Wert

\[z = \frac{x_i-\bar{x}}{s}\]

  • Der z-Wert einer Beobachtung \(x_i\) gibt an, um wieviele Standardabweichungen die Beobachtung über oder unter dem Mittelwert liegt.
  • Der z-Wert des Mittelwerts ist 0
  • Ungewöhnliche Beobachtungen haben einen z-Wert von \(|z|>2\).

Perzentilen in R berechnen

# Fläche links von x
pnorm(x, mean, sd)  

# Fläche rechts von x
1 - pnorm(x, mean, sd)
pnorm(x, mean, sd, lower.tail = FALSE) 

# Wert auf einer bestimmten Perzentile
qnorm(percentile, mean, sd) 

Beispiel:

x <- c(2, 3, 4, 4, 5, 6, 10, 9, 8, 7, 7, 7, 5, 4)
mittelwert <- mean(x)
stdabw <- sd(x)

# Wahrscheinlichkeit für den Wert kleiner oder gleich 7
pnorm(7, mittelwert, stdabw)
## [1] 0.6991514
# Wahrscheinlichkeit für den Wert gleich oder grösser 7
1 - pnorm(7, mittelwert, stdabw)
## [1] 0.3008486
# Wert auf der 40%-Perzentile
qnorm(.4, mittelwert, stdabw)
## [1] 5.19633

QQ-Plot

# Punkte in Streudiagramm darstellen
qqnorm()

# Linie in QQ-Plot einzeichnen
qqline()

Beispiel:

# simulation von 100 normalverteilten Werten, mean = 0, s = 1
set.seed(1)
x <- rnorm(100)

## qq-plot erstellen
qqnorm(x)

## Linie in qq-plot einzeichnen
qqline(x, col = "blue")

qq-plots Interpretation




Binomialverteilung

\[X \sim Bin(n, p)\]

  • \(n\) = Anzahl Versuche
  • \(p\) = Eintrittswahrscheinlichkeit

Erwartungswert (Mittelwert) der Binomialverteilung

\[\mu = n \times p\]

Standardabweichung der Binomialverteilung

\[\sigma = \sqrt{np(1-p)}\]

Bedingungen für Binomialverteilung

  • Die Versuche müssen unabhängig sein.
  • Die Anzahl der Versuche muss bekannt sein.
  • Jedes Versuchsergebnis ist entweder ein Erfolg oder ein Misserfolg.
  • Die Wahrscheinlichkeit für einen Erfolg muss für jeden Versuch gleich sein.

Wahrscheinlichkeiten der Binomialverteilung

  • Wenn \(p\) die Wahrscheinlichkeit für einen Erfolg ist, ist \(1-p\) die Wahrscheinlichkeit für einen Misserfolg. \(n\) gibt die Anzahl der Versuche an und \(k\) die Anzahl der Erfolge.

\[p(k, n) = {n \choose k}p^k(1-p)^{n-k}\]

  • Wahrscheinlichkeit für \(k\) Erfolge in \(n\) Versuchen mit der Erfolgswahrscheinlichkeit \(p\) in R berechnen:
dbinom(k, n, p)
  • Anzahl Kombinationen von \(k\) Erfolgen in \(n\) Versuchen berechnen (Binomialkoeffizient)

\[{n \choose k} = \frac{n!}{k!(n-k)!}\]

choose(n, k)

Normalapproximation

  • Eine Binomialverteilung mit mindestens 10 erwarteten Erfolgen und mindestens 10 erwarteten Misserfolgen folgt annähernd einer Normalverteilung.

\[n \times p \times (1-p) \geq 10\] \[n(1-p) \geq 10\]

  • Falls diese Bedingung erfüllt ist, gilt:

\[Bin(n, p) \sim N(\mu, \sigma)\]

  • wobei

\[\mu = np\] \[\sigma = \sqrt{np(1-p)}\]




Grundlagen der Inferenzstatstik

Zentraler Grenzwertsatz

Die Verteilung von Stichprobenkennzahlen (z.B. Mittelwert) folgt annähernd einer Normalverteilung. Ihr Mittelwert liegt in der Nähe des Populationsmittelwertes \(\mu\) mit einer Standardabweichung geteilt durch die Quadratwurzel des Stichprobenumfangs.

\[\bar{x} \sim N(Mittelwert = \mu, SE = \frac{\sigma}{\sqrt{n}})\]

Wenn \(\sigma\) unbekannt ist (was eigentlich immer der Fall ist), wird die Standardabweichung \(s\) der Stichprobe als Schätzer für \(\sigma\) eingesetzt.

\[SE = \frac{s}{\sqrt{n}}\]

Bedingungen für die Gültigkeit des zentralen Grenzwertsatzes:

  • Die Beobachtungseinheiten in der Stichprobe sind unabhängig voneinander (zufällige Auswahl, zufällige Zuordnung zu Gruppen).
  • Faustregel: Stichprobenumfang \(n>30\)

Beispiel für die Berechnung des Standardfehlers \(SE\) in R

# simulation von 100 normalverteilten Werten, mean = 0, s = 1
set.seed(1234)
x <- rnorm(100)

# Stichprobenumfang von x ermitteln
n <- length(x)

# Standardabweichung von x berechnen
s <- sd(x)

# Berechnung von SE
SE <- s/sqrt(n)

# Output SE
SE
## [1] 0.1004405

Konfidenzintervalle

Konfidenzintervalle (Vertrauensintervalle, \(CI\)) können auf jedem Konfidenzniveau berechnet werden. Um die Sache nicht allzu kompliziert zu machen, wird hier v.a. exemplarisch die Berechnung von 95%-Konfidenzinteravallen vorgestellt.

  • Signifikanzniveau = \(\alpha\)
  • Konfidenzniveau = \(1-\alpha\)

\[CI^* = \bar{x} \pm z^* \times SE\]

\[z^* = \vert \frac{(1-CI^*)}{2} \vert\]

\[z^* \times SE = z^* \times \frac{s}{\sqrt{n}}\]

\(z^* \times SE\) wird auch als Fehlerbereich (engl. \(margin~ of~ error,~ ME\)) bezeichnet.

Der Wert von \(z^*\) ist abhängig vom Konfidenzniveau.

# z für ein 95% CI
CI <- .95
z95 <- abs(qnorm((1 - CI)/2))
z95
## [1] 1.959964
# z für ein 90% CI
CI <- .9
z90 <- abs(qnorm((1 - CI)/2))
z90
## [1] 1.644854
# z für ein 99% CI
CI <- .99
z99 <- abs(qnorm((1 - CI)/2))
z99
## [1] 2.575829

Beispiel für die Berechnung eines 95% Konfidenzintervalls

m <- 95.6       # Stichprobenmittelwert
s <- 15.8       # Standardabweichung der Stichprobe
n <- 100        # Stichprobenumfang

# gesucht ist das 95% Konfidenzintervall für den Populationsmittelwert  
CI <- .95       # Konfidenzniveau 95%
z <- abs(qnorm((1-CI)/2))
ME <- z * CI    # Fehlerbereich berechnen

# Obere und untere Grenze für 95%-Konfidenzintervall berechnen
CI95 <- m + c(-1, 1) * ME
CI95
## [1] 93.73803 97.46197

Zuverlässigkeit vs. Präzision

Wenn wir das Konfidenzniveau erhöhen (Konfidenzintervall wird breiter, z.B. von 95% auf 99%) nimmt die Zuverlässigkeit, dass wir den wahren Populationsparameter im Intervall haben zu, allerdings auf Kosten der Präzision.
Wie können wir Zuverlässigkeit und Präzision gleichzeitig verbessern? Antwort: Stichprobenumfang erhöhen.

Stichprobenumfang für einen bestimmten Fehlerbereich berechnen:

\[ME = z^* \times \frac{s}{\sqrt{n}} \rightarrow n = (\frac{z^* \times s}{ME})^2\]

Beispiel: Im Beispiel oben betrug unser ME = 1.862. Wir möchten den ME halbieren und bestimmen den benötigten Stichprobenumfang. (Kennzahlen wie oben)

ME.alt <- 1.862
ME.neu <- ME.alt/2

# neues 95%-Konfidenzintervall berechnen
CI95.neu <- m + c(-1, 1) * ME.neu
CI95.neu
## [1] 94.669 96.531
# Stichprobenumfang für das neue 95%-CI berechnen
n.neu <- ((z * s)/ME.neu)^2
n.neu
## [1] 1106.397

Hypothesentest für einen Mittelwert

Hypothesentests werden immer für einen Popultionsparameter, z.B. \(\mu\) durchgeführt und nicht für eine Stichprobe.

  1. Formuliere die wissenschaftliche Hypothese
  • \(H_0: \mu = Nullwert\)
  • \(H_A: \mu < oder > oder \neq Nullwert\)
  • Es wird empfohlen \(H_A:\) immer zweiseitig formulieren ausser in begründeten Ausnahmefällen.
  1. Berechne den Punktschätzer \(\bar{x}\) für \(\mu\)
  2. Überprüfe die Testvoraussetzungen
  • Beobachtungseinheiten in der Stichprobe sind unabhängig.
  • Stichprobe stammt aus eine annähernd normalverteilten Population.
  • Der Stichprobenumfang \(n \geq 30\) oder grösser bei stark schiefer Verteilung.
  1. Skizziere die Stichprobenverteilung, zeichne deinen Verwerfungsbereich ein und berechne die Teststatistik.

\[z = \frac{\bar{x} - \mu}{SE}, ~~ SE = \frac{s}{\sqrt{n}}\]

  1. Liegt \(z\) im Verwerfungsbereich wird \(H_0\) zu Gunsten von \(H_A\) zurückgewiesen.
  2. Interpretiere dein Resultat im Zusammenhang mit der Fragestellung.

p-Werte berechnen

Definition:

\[p-Wert = P(beobachtete~oder~extremere~Teststatistik~ | ~H_0~ wahr)\]

Der p-Wert quantifiziert die Evidenz gegen \(H_0\). Ein kleiner \(p\)-Wert (üblicherweise \(p \leq 0.05\)) bedeutet, dass du ausreichend Evidenz dafür hast, \(H_0\) zu Gunsten von \(H_A\) zu verwerfen.

Einseitiger Hypothesentest anhand von p-Werten

  1. Fall

\(H_A: \mu > Nullwert\)

\[z = \frac{\bar{x}-Nullwert}{SE_{\bar{x}}}\]

\(p\)-Wert in R berechnen:

p <- 1 - pnorm(z)
  1. Fall

\(H_A: \mu < Nullwert\)

\[z = \frac{\bar{x}-Nullwert}{SE_{\bar{x}}}\]

\(p\)-Wert in R berechnen:

p <- pnorm(z)

Zweiseitiger Hypothesentest anhand von p-Werten

Zweiseitige Hypothesen sind der Normalfall. Einseitige Hypothesen sollten nur in begründeten Ausnahmefällen formuliert werden.

\(H_A: \mu \neq Nullvalue\)

\[z = \frac{\bar{x}-Nullwert}{SE_{\bar{x}}}\]

\(p\)-Wert in R berechnen:

p <- 2 * pnorm(abs(z), lower.tail = FALSE)

# Alternative
p <- 2 * pnorm(-abs(z))

Entscheidungsfehler

  • Fehler 1. Art: \(H_0\) wird verworfen wenn \(H_0\) wahr ist.
  • Fehler 2. Art: \(H_0\) wird nicht verworfen wenn \(H_A\) wahr ist.

Bei einem Signifikanzniveau \(\alpha = 0.05\) nehmen wir ein Risiko von 5% in Kauf, einen Fehler 1. Art zu begehen.

  • \(\alpha:\) Wahrscheinlichkeit, einen Fehler 1. Art zu begehen.
  • \(\beta:\) Wahrscheinlichkeit, einen Fehler 2. Art zu begehen.
  • \(1-\beta:\) Power (Trennschärfe) eines Tests; Wahrscheinlichkeit, für \(H_A\) zu entscheiden, wenn \(H_A\) wahr ist.

Hypothesentests mit Konfidenzintervallen

  • Ein zweiseitiger Hypothesentest mit einem Signifikanzniveau \(\alpha\) entspricht einem Konfidenzintervall mit dem Konfidenzniveau \(1-\alpha\).
  • Ein einseitiger Hypothesentest mit einem Signifikanzniveau \(\alpha\) entspricht einem Vertrauensintervall mit einem Konfidenzniveau von \(1-(2 \times \alpha)\).
  • Enthält ein 95% Vertrauensintervall den Nullwert nicht, wird \(H_0\) verworfen.
  • Enthält ein 95% Vertrauensintervall den Nullwert, wird \(H_0\) nicht verworfen.




Inferenz für quantitative Daten

Hypothesentests für gepaarte Mittelwerte

  • Gepaarte (auch verbundene) Daten:

    • Gleiche Beobachtungseinheiten: Vorher-Nachher-Messungen, Messwiederholungen
    • Unterschiedlieche Beobachtungseinheiten (jedoch abhängig): Zwillingsstudien, Partner
  • Parameter: \(\mu_{\Delta}\) = Mittelwert der paarweisen Differenzen in der Population

  • Punktschätzer: \(\bar{x}_{\Delta}\) = Mittelwert der paarweisen Differenzen in der Stichprobe

  • Teststatistik: \(z\)-Wert

  • Hypothesen:

    • \(H_0: \mu_{\Delta} = Nullwert\)
    • \(H_A: \mu_{\Delta} \neq Nullwert\) (zweiseitige \(H_A\))

Vorgehen

  1. Wissenschaftliche Hypothesen formulieren
  2. Punktschätzer berechnen
  3. Annahmen prüfen
  • Unabhängigkeit der Beobachtungseinheiten
  • Paarweise Differenzen sind annähernd normalverteilt.
  • Stichprobenumfang \(n \geq 12\) oder grösser bei stark schiefen Verteilungen
  1. Stichprobenverteilung skizzieren, Verwerfungsbereich einzeichnen und Teststatistik berechnen

\[z = \frac{\bar{x}_{\Delta} - \mu_{\Delta}}{SE_{\bar{x}_{\Delta}}}\]

  1. Liegt \(z\) im Verwerfungsbereich wird \(H_0\) zu Gunsten von \(H_A\) zurückgewiesen.
  2. Resultat im Zusammenhang mit der Fragestellung interpretieren.

Konfidenzintervall für gepaarte Daten

\[CI^* = \bar{x}_{\Delta} \pm z* \times SE_{\Delta}\]

\[CI^* = \bar{x}_{\Delta} \pm z^* \times \frac{s_{\Delta}}{n}\]

Hypothesentest für unabhängige Mittelwerte

  • unabhängige Daten:

    • Unterschiedliche Beobachtungseinheiten, z.B. Vergleich von zwei Gruppen
  • Parameter: \(\mu_1 - \mu_2\), z.B. Differenz der Mittelwerte von zwei Populationen

  • Punktschätzer: \(\bar{x}_1 - \bar{x}_2\) z.B. Differenz der Mittelwerte von zwei Stichproben

  • Teststatistik: \(z\)-Wert

  • Hypothesen:

    • \(H_0: \mu_1 = \mu_2\) bzw. \(H_0: \mu_1 - \mu_2 = 0\)
    • \(H_A: \mu_1 \neq \mu_2\) bzw. \(H_A: \mu_1 - \mu_2 \neq 0\) (zweiseitige \(H_A\))

Vorgehen

  1. Wissenschaftliche Hypothese formulieren
  2. Punktschätzer berechnen
  3. Annahmen prüfen
  • Unabhängigkeit der Beobachtungseinheiten innerhalb und zwischen den Gruppen
  • Stichprobe stammt aus eine annähernd normalverteilten Population.
  • Stichprobenumfang \(n_1 \geq 30\) und \(n_2 \geq 30\) oder grösser bei stark schiefen Verteilungen
  1. Stichprobenverteilung skizzieren, Verwerfungsbereich einzeichnen und Teststatistik berechnen

\[z = \frac{(\bar{x}_1 - \bar{x}_2)-(\mu_1 - \mu_2)}{SE_{\bar{x}_1 - \bar{x}_2}}\]

\[SE_{\bar{x}_1 - \bar{x}_2} = \sqrt{\frac{s_1^2}{n_1}+\frac{s_2^2}{n_2}}\]

  1. Liegt \(z\) im Verwerfungsbereich wird \(H_0\) zu Gunsten von \(H_A\) zurückgewiesen.
  2. Resultat im Zusammenhang mit der Fragestellung interpretieren.

Konfidenzintervall für unabhängige Daten

\[CI^* = (\bar{x}_1 - \bar{x}_2) \pm z^* \times SE_{\bar{x}_1 - \bar{x}_2}\]




T-Verteilung und t-Tests

Die T-Verteilung

  • kann als Variante der Normalverteilung aufgefasst werden.
  • hat immer den Mittelwert 0.
  • hat eine Standardabweichung, die vom Stichprobenumfang \(n\) abhängig ist.
  • Wird nur durch einen einzigen Parameter, die Anzahl Freiheitsgrade \(df\) (engl. degrees of freedom), definiert.
  • Die T-Verteilung wird mit wachsendem \(n\) schmaler und geht für \(n \rightarrow \infty\) in die Normalverteilung über.

\[df = n-1\] \[t \sim T(df)\]

Die T-verteilung wird verwendet, wenn

  • der Stichprobenumfang klein ist (\(n \leq 30\))
  • die Standardabweichung \(\sigma\) der Population unbekannt ist und mit Hilfe der Stichprobenstandardabweichung \(s\) geschätzt werden muss.
  • also eigentlich immer; die Software rechnet standardmässig mit der T-Verteilung.
  • Die Teststatistik von T-Tests sind \(t\)-Werte. \(t\)-Werte werden gleich interpretiert wie \(z\)-Werte.

Inferenz für einen Mittelwert

Ziel: Vergleich eines Mittelwerts mit einem Vergleichswert (= Nullwert)

Hypothesen:

  • \(H_0: \mu = Nullwert\)
  • \(H_A: \mu \neq Nullwert\) (zweiseitig)

Konfidenzintervall

\[CI^* = \bar{x} \pm t_{df}^* \times SE_{\bar{x}}\]

\[SE_{\bar{x}} = \frac{s}{\sqrt{n}}, ~~ df = n-1\]

Quantilen für den kritischen t-Wert (Grenzen des Verwerfungsbereichs) und für die Konstruktion von Konfidenzintervallen mit Rberechnen:

# für Signifikanzniveau 0.05, 95% CI
t <- qt(.025, df = n - 1)  

# für Signifikanzniveau 0.1, 90% CI
t <- qt(0.05, df = n - 1)

# für Signifikanzniveau 0.01, 99% CI
t <- qt(0.005, df = n - 1)

Die R-Funktion qt() gibt die untere Grenze an. Da die T-Verteilung symmetrisch ist, entspricht die obere Grenze dem Absolutwert der unteren Grenze.

Beispiel zur Berechnung des Konfidenzintervalls in R

# Kennzahlen einer Stichprobe
n <- 25
m <- 15
s <- 3


ci_level <- .95                # Konfidenzniveau
SE <- s/sqrt(n)                # Standardfehler   
t_df <- qt(.025, df = 25 - 1)  # kritischer t-Wert

CI <- m + c(-1, 1) * abs(t_df) * SE
CI
## [1] 13.76166 16.23834

Einstichproben-t-Test

\[t = \frac{\mu-Nullwert}{SE}\]

Beispiel: Vergleich des Mittelwerts einer Stichprobe mit dem Nullwert in einer Population. Der Nullwert sei \(Nullwert = 13\)

Hypothesen:

  • \(H_0: \mu = 13\)
  • \(H_A: \mu \neq 13\) (zweiseitig)
# Kennzahlen unserer Stichprobe und Nullwert
n <- 25
m <- 15
s <- 3
nullwert <- 13

SE <- s/sqrt(n)                # Standardfehler   
t <- (m - nullwert)/SE         # Teststatistik 

# p-Wert für zweisseitige Hypothese berechnen
p <- 2 * pt(abs(t), df = n - 1, lower.tail = FALSE)

# output von t und p
paste("t =", t, ", p =", p)
## [1] "t = 3.33333333333333 , p = 0.00277631418305654"

Einfacher geht es mit der Funktion t.test()

# Daten simulieren (muss man nicht verstehen)
rnorm2 <- function(n, mean, sd) { mean + sd * scale(rnorm(n)) }
x <- rnorm2(n = 25, mean =15, sd = 3)

# t-Test in R
t.test(x, # Stichprobendaten mit m = 15, s = 3, n = 25
       mu = 13, # Nullwert
       alternative = "two.sided") # zweiseitiger Test
## 
##  One Sample t-test
## 
## data:  x
## t = 3.3333, df = 24, p-value = 0.002776
## alternative hypothesis: true mean is not equal to 13
## 95 percent confidence interval:
##  13.76166 16.23834
## sample estimates:
## mean of x 
##        15

Der Einstichproben-t-Test eignet sich auch als Test für gepaarte Daten mit der Prüfgrösse \(mu_{\Delta}\).

Inferenz für zwei Mittelwerte

Ziel: Vergleich von zwei Mittelwerten aus zwei Stichproben

Hypothesen:

  • \(H_0: \mu_1 = \mu_2\)
  • \(H_A: \mu_1 \neq \mu_2\) (zweiseitig)

Konfidenzintervall

\[CI^* = (\bar{x}_1 - \bar{x}_2) \pm t_{df}^* \times SE_{\bar{x}_1 - \bar{x}_2}\]

\[SE_{\bar{x}_1 - \bar{x}_2} = \sqrt{\frac{s_1^2}{n_1}+\frac{s_2^2}{n_2}}\]

\[df = n_1 + n_2 - 2\]

Die Formeln für die Berechnung von \(SE\) und \(df\) sind etwas vereinfacht; genaue Formeln findet man in Statistiklehrbüchern.

Zweistichproben-t-Test

\[t = \frac{(\bar{x}_1 - \bar{x}_2)-(\mu_1 - \mu_2)}{SE_{\bar{x}_1 - \bar{x}_2}}\]

# Kennzahlen unserer Stichprobe und Nullwert
n1 <- 25
m1 <- 15
s1 <- 3
n2 <- 20
m2 <- 18
s2 <- 4

# Standardfehler 
SE <- sqrt((s1^2 / n1) + (s2^2/n2))

# Teststatistik  
t <- (m1 - m2)/SE     

# Freiheitsgrade n2 - 1 ist kleiner als n1 - 1
df <- n1 + n2 - 2

# p-Wert für zweisseitige Hypothese berechnen
p <- 2 * pt(abs(t), df, lower.tail = FALSE)

# output von t und p
paste("t =", t, ", p =", p)
## [1] "t = -2.78543007265578 , p = 0.00791948797764193"

Einfacher geht es mit der Funktion t.test()

# Daten simulieren (muss man nicht verstehen)
rnorm2 <- function(n, mean, sd) { mean + sd * scale(rnorm(n)) }
x1 <- rnorm2(n = 25, mean =15, sd = 3)
x2 <- rnorm2(n = 20, mean =18, sd = 4)

# t-Test in R
t.test(x = x1, # Gruppe 1
       y = x2, # Gruppe 2
       paired = FALSE, 
       alternative = "two.sided")# zweiseitiger Test
## 
##  Welch Two Sample t-test
## 
## data:  x1 and x2
## t = -2.7854, df = 34.428, p-value = 0.00863
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -5.187792 -0.812208
## sample estimates:
## mean of x mean of y 
##        15        18




Nichtparametrische Tests

Nichtparametrische Tests kommen zur Anwendung, wenn die Annahme der Normalverteilung fraglich ist. Für die Anwendung von nichtparametrischen Tests ist es unerheblich, aus welcher Art von Verteilung die Daten stammen.

Vorzeichentest

Referenzen: King and Eckersley (2019)

Der Einstichproben-Test: Vergleicht einen Median (\(\tilde{x}\)) mit einem vorgegebenen Referenzmedian. \(H_0: \tilde{x} = Nullwert\). Prüfgrösse sind die Stichprobendaten.

Vorgehen:

  1. Vergleiche jeden Wert in der Stichprobe mit dem Nullwert. Für Werte die grösser als der Nullwert sind, schreibe ein \(+\), für Werte die kleiner als der Nullwert sind, schreibe ein \(-\).
  2. Zähle die Anzahl \(+\) und \(-\).
  3. Berechne anhand der Regeln für die Binomialverteilung die Wahrscheinlichkeit für dieses oder ein extremeres Resultat unter der Annahme, dass die Nullhypothese zutrifft. Dies ist auch unsere Teststatistik!
  • Wenn \(p\) die Wahrscheinlichkeit für einen Erfolg ist, ist \(1-p\) die Wahrscheinlichkeit für einen Misserfolg. \(n\) gibt die Anzahl der Versuche an und \(k\) die Anzahl der Erfolge.

\[p(k, n) = {n \choose k}p^k(1-p)^{n-k}\] 4. Vergleiche den p-Wert mit dem Signifikanzniveau. Beachte: Für eine zweiseitige \(H_A\) muss der p-Wert verdoppelt werden.

Beispiel

In einer neuen Produktionslinie soll die Kontamination eines Produkts mit Schadstoffen unter einem Grenzwert von 50 Einheiten liegen. Gemessen wurde die Kontamination an einer Stichprobe \(n\) = 10.

\(H_0: \tilde{x} = 50\), der Median der Stichprobe ist 50
\(H_A: \tilde{x} < 50\), der Median der Stichprobe ist kleiner als 50

## Kontaminationsdaten ---------------------------------------------------------
contamination <- tibble(
  value = c(45.344, 48.655, 36.199, 54.881, 49.287, 
            49.336, 53.492, 40.702, 46.318, 31.303)
)

nullvalue <- 50

## Differenz zum Nullwert plus oder minus --------------------------------------
contamination <- contamination %>% 
  mutate(
    diff = value - nullvalue,
    sign = if_else(diff >= 0, "plus", "minus")
  )
contamination %>% 
  kbl() %>% 
  kable_styling(full_width = FALSE)
value diff sign
45.344 -4.656 minus
48.655 -1.345 minus
36.199 -13.801 minus
54.881 4.881 plus
49.287 -0.713 minus
49.336 -0.664 minus
53.492 3.492 plus
40.702 -9.298 minus
46.318 -3.682 minus
31.303 -18.697 minus
## Summe der positiven und negativen Differenzen -------------------------------
contamination %>% 
  group_by(sign) %>% 
  summarise(
    n = n()
  ) %>% 
  kbl() %>% 
  kable_styling(full_width = FALSE)
sign n
minus 8
plus 2
## Wie gross ist die Wahrscheinlichkeit 8 oder mehr negative aus 10 zu ziehen  
p.Wert <- dbinom(8, 10, .5) + dbinom(9, 10, .5) + dbinom(10, 10, .5)


## Tabelle für Resultat erstellen ----------------------------------------------
cont.result <- tibble(
  Nr.successes = 8,
  Nr.trials = 10, 
  p.H0 = .5,
  p.Value = round(p.Wert, 4)
)
cont.result %>% 
  kbl(caption = "Vorzeichentest") %>% 
  kable_styling(full_width = FALSE)
Vorzeichentest
Nr.successes Nr.trials p.H0 p.Value
8 10 0.5 0.0547
# Einfacher geht es mit R 
binom.test(8, 10, .5, alternative = "greater")
## 
##  Exact binomial test
## 
## data:  8 and 10
## number of successes = 8, number of trials = 10, p-value = 0.05469
## alternative hypothesis: true probability of success is greater than 0.5
## 95 percent confidence interval:
##  0.4930987 1.0000000
## sample estimates:
## probability of success 
##                    0.8

Interpretation: Der kritische Wert für unsere Teststatistik ist das Signifikanzniveau \(\alpha\). Ist der \(p-Wert\) grösser als \(\alpha\), haben wir keine Evidenz dafür, dass wir die Nullhypothese verwerfen können. Es liegt nicht ausreichend Evidenz dafür vor, dass der Median der Kontamination signifikant tiefer ist, als der vorgegebene Grenzwert.

Beispiel 2

Der Vorzeichentest kann auch als Wilcoxon Vorzeichenrangtest mit dem Parameter mu = nullvalue durchgeführt werden. Das Resultat ist annähernd das selbe.

wilcox.test(x, mu = Referenzwert)

Beispiel:

# Wilcoxon-Vorzeichenrangtest
wilcox.test(x = contamination$value, mu = nullvalue, alternative = "less")
## 
##  Wilcoxon signed rank exact test
## 
## data:  contamination$value
## V = 11, p-value = 0.05273
## alternative hypothesis: true location is less than 50



Wilcoxon-Vorzeichenrangtest

Quellen: Leonhart (2013), Mi et al. (2022)

Wilcoxon Vorzeichenrang-Test für gepaarte Daten: \(H_0: \tilde{x}_{\Delta} = 0\), Prüfgrösse \(\tilde{x}_{\Delta}\) = Paarweise Differenzen Stichprobe B minus Stichprobe A.

Annahmen:

  • quantitative oder ordinal skalierte Daten
  • unabhängige Beobachtungseinheiten
  • Daten sind annähernd symmetrisch um den Median verteilt.

Vorgehen:

  1. Paarweise Differenzen nach Grösse sortieren. Die Vorzeichen werden für die Rangbildung ignoriert, das Vorzeichen wird notiert.
  2. Rangsummen für positive und negative Differenzen bilden.

\[T_+ = \sum Ränge ~mit ~positivem ~Vorzeichen\]

\[T_- = \sum Ränge ~mit ~negativem ~Vorzeichen\]

  1. Die Teststatistik \(T\) ist die kleinere der beiden Rangsummen.
  2. Kritischen Wert \(T_{krit}\) in Vorzeichen-Rang-Tabelle nachschlagen. Wenn \(T < T_{krit}\) wird \(H_0\) verworfen.

Normalapproximation

  • Für grössere Stichproben (Faustregel: \(n > 25\), je nach Autor etwas andere Angaben) ist \(T\) annähernd normalverteilt.

\[E(T) = \mu = \frac{n \times (n + 1)}{4}\]

\[\sigma^2 = \frac{n \times (n + 1) \times (2n + 1)}{24}\]

Korrektur für Bindungen

Wenn mehrere Bindungen vorliegen, ist ein besserer Schätzer für die Varianz

\[\sigma^2 = \frac{n \times (n + 1) \times (2n + 1)}{24} - \frac{1}{48} \sum_t(f_t^3 - f_t)\]

wobei:

  • \(t\) = Anzahl Sets von Bindungen
  • \(f_t\) = Häufigkeit von Rang \(t\)

Kontinuitäts-Korrektur

Die Approximation einer diskreten Verteilung mittels einer kontinuierlichen Verteilung kann durch eine Kontinuitätskorrektur bei der Berechnung von \(z\) berücksichtigt werden:

\[z = \frac{|U - \mu|-.5}{\sigma}\]

Beispiel

Zur Überprüfung einer neuen Unterrichtsmethode wurde in einer abhängigen Stichprobe vor und nach einem Sommerlager die Leistung im Fach Statsitik erhoben. Während des Ferienaufenthalts fand ein integrierter Nachhilfekurs in Statistik statt. Die Messung der Statsitikleistung ergab folgende Werte:

## Prüfergebnisse --------------------------------------------------------------

# library(dplyr)
prfg <- tibble(
  ID = seq(from = 1, to = 10, by = 1),
  vorher = c(22, 26, 12, 20, 22, 26, 22, 24, 40, 40),
  nachher = c(40, 22, 28, 30, 16, 38, 24, 32, 20, 26)
)

## Paarweise Differenzen berechnen ---------------------------------------------
prfg <- prfg %>% 
  mutate(
    diff = nachher - vorher
  )

## Nach Rängen sortieren -------------------------------------------------------
prfg <- prfg %>% 
  mutate(
    rang = rank(abs(diff))
  )

## Rangsummen für T berechnen --------------------------------------------------
T.plus <- prfg %>% 
  filter(diff > 0) %>% 
  summarise(
    value = sum(rang)
  )

T.minus <- prfg %>% 
  filter(diff < 0) %>% 
  summarise(
    value = sum(rang)
  )

## Testgrösse ist das kleinere T -----------------------------------------------
T <- min(T.plus$value, T.minus$value)

## p-Wert berechnen ------------------------------------------------------------
p <- 2 * psignrank(T, n = length(prfg$diff))

## Tabelle für Output erstellen ------------------------------------------------
prfg.result <- tibble(
  T.plus = T.plus$value,
  T.minus = T.minus$value,
  T = T,
  T.krit = 8,
  p.Wert = p
)

## Tabelle anzeigen ------------------------------------------------------------
# library(knitr)
# library(kableExtra)

prfg.result %>% 
  kbl(digits = 3, caption = "Wilcoxon Vorzeichenrangtest") %>% 
  kable_styling(full_width = FALSE)
Wilcoxon Vorzeichenrangtest
T.plus T.minus T T.krit p.Wert
33 22 22 8 0.625
## Überprüfung mit wilcox.test() -----------------------------------------------
wilcox.test(prfg$vorher, prfg$nachher, paired = TRUE, correct = FALSE)
## 
##  Wilcoxon signed rank exact test
## 
## data:  prfg$vorher and prfg$nachher
## V = 22, p-value = 0.625
## alternative hypothesis: true location shift is not equal to 0

Anmerkungen

  • Es wird im Beispiel keine Kontinuitätskorrektur oder eine Korrektur für Bindungen verwendet.
  • \(T.krit\) wurde manuell der Wilcoxon Vorzeichenrang-Tabelle entnommen (\(n\) = 10).
  • Der p-Wert wurde mit der Funktion psignrank(T, n = n) berechnet.
  • Der berechnete T-Wert muss gleich oder kleiner als der kritische T-Wert sein, damit ein signifikanter Unterschied belegt werden kann.
  • In R wird \(T\) als \(V\) angegeben.

Interpretation: Der beobachtete T-Wert unterschreitet den kritischen T-Wert nicht, somit ist der Unterschied zwischen den Testzeitpunkten nicht signifikant und der Sommerkurs hat keinen Effekt auf die Leistung der Schüler:innen in Statistik.

Mann-Whitney-U-Test

Referenz: King and Eckersley (2019)

Wird auch Wilcoxon Rangsummen-Test genannt.

Testet nicht ganz dasselbe wie der t-Test

  • \(H_0: P(X > Y) = P(Y > X)\), m.a.W: Es besteht eine 50%-Wahrscheinlichkeit dafür, dass ein zufällig gezogener Wert aus \(X\) grösser ist als ein zufällig gezogener Mittelwert aus \(Y\) (und umgekehrt)
  • \(H_0: P(X > Y) \neq P(Y > X)\), m.a.W: Die Wahrscheinlichkeit ist nicht 50%, dass ein zufällig gezogener Wert aus \(X\) grösser ist als ein zufällig gezogener Mittelwert aus \(Y\) (und umgekehrt)

Annahmen

  • quantiative oder ordinal skalierte Daten
  • unabhängige Beobachtungen

Idee: Die Werte beider Stichproben werden in einer einzige Rangordnung sortiert. Für \(H_0\) wird erwartet, dass \(x < y\) gleich häufig ist wie \(y < x\).

Teststatistik
* U misst, wie oft ein y-Wert kleiner ist als ein x-Wert. Definition: * wenn \(y < x, z = 1\)
* wenn \(x < y, z = 0\) * \(U = \sum{z}\)

  • Berechnung von U:

\[ U = n_1 \times n_2 + \frac{n_1(n_1 + 1)}{2} - T_1 \]

  • \(T_1\) = Summe der Ränge von Stichprobe 1
  • \(U' = (n_1 \times n_2) - U = \sum{(x < y)}\)

Für grosse Stichprobenumfänge (\(n_1\) oder \(n_2\) > 10) ist \(U\) annähernd normal verteilt mit:

\[ E(U) = \mu = \frac{n_1 \times n_2}{2} \]

und

\[ \sigma_U^2 = \frac{n_1 \times n_2 \times (n_1 + n_2 + 1)}{12} \]

Teststatistik:

\[ z = \frac{U - E(U)}{\sigma_U} \]

Wenn gebundene Ränge vorliegen (zwei Werte in einer Spalte belegen den selben Rang), wird die Standardabweichung von \(U\) wie folgt korrigiert:

\[ \sigma_{UCorr} = \sqrt{\frac{n_1 \times n_2}{n(n-1)}} \times \sqrt{\frac{n^3-n}{12}-\sum_{i=1}^k\frac{t_i^3-t_i}{12}} \]

wobei

  • \(n = n_1 + n_2\)
  • \(t_i\) = Anzahl einzelner Werte, welche den Rang \(i\) teilen.
  • \(k\) = Anzahl gebundene Ränge

in R

wilcox.test(x, y, alternative = "two.sided", paired = FALSE)

Beispiel:

# Daten generieren
X <- c(3, 3, 4, 5, 6, 7, 7, 8, 1, 2)
Y <- c(2, 3, 2, 5, 6, 2, 3, 8, 1, 2)

# Mann-Whitney-U-Test
wilcox.test(x = X, y = Y, alternative = "two.sided", paired = FALSE)
## 
##  Wilcoxon rank sum test with continuity correction
## 
## data:  X and Y
## W = 66, p-value = 0.2351
## alternative hypothesis: true location shift is not equal to 0

Beachte: R berechnet die Teststatistik etwas anders: Die Funktion wilcox.test() berechnet zwar die Teststatistik \(W\) wie oben angegeben, zieht dann jedoch \(\frac{n_1 (n_1 + 1)}{2}\) davon ab (Hughes 2012).




Varianzanalyse, ANOVA

  • ANOVA steht für Varianzanalyse (engl. Analysis of Variance) und wird verwendet um die Mittelwerte von mehr als 2 Gruppen zu vergleichen.

Hypothesen

  • \(H_0: \mu_1 = \mu_2 ... = \mu_n\)
  • \(H_A: Die ~Mittelwerte ~sind ~nicht ~alle ~gleich\)

Quadratsummenzerlegung

  • Bei der Varianzanalyse wird die “Gesamtvarianz” der abhängigen Variablen \(y\) in die Varianz zwischen den Gruppenmittelwerten und die Varianz zwischen den Messwerten innerhalb der Gruppen zerlegt.

\[SS_{total}=SS_{between} + SS_{within}\]

  • Die Gesamtquadratsumme \(SS_{total}\) misst die totale Variabilität der abhängigen Variablen.

\[SS_{total} = \sum_{i=1}^n(y_i-\bar{y})^2\]

  • \(y_i:\) Wert der abhängigen Variablen für jede Beobachtung

  • \(\bar{y}:\) Mittelwert der abhängigen Variablen (sog. grand mean)

  • Die Quadratsumme zwischen den Gruppen misst die Variabilität zwischen den Gruppen; entspricht der Variabilität, die durch die Gruppierungsvariable erklärt wird (erklärte Variabilität).

\[SS_{between} = \sum_{j=1}^k n_j(\bar{y}_i-\bar{y})^2\]

  • \(n_j:\) Anzahl Beobachtungen in Gruppe \(j\)

  • \(\bar{y}_j:\) Mittelwert der abhängigen Variablen in Gruppe \(j\)

  • \(\bar{y}:\) Mittelwert der abhängigen Variablen (grand mean)

  • Die Quadratsumme innerhalb der Gruppen misst die Variabilität innerhalb der einzelnen Gruppen; entspricht der Variabilität, die nicht durch die Gruppierungsvariable beschrieben wird, also andere Gründe hat (unerklärte Variabilität)

\[SS_{within} = SS_{total}-SS_{between}\]

  • Freiheitsgrade für ANOVA

    • Total: \(df_{tota} = n-1\)
    • für SS_{between}: \(df_{between} = k-1\)
    • für SS_{within}: \(df_{within} = df_{total}-df{between}\)
  • Die mittleren Quadratsummen beschreiben die durchschnittliche Variabilität zwischen und innerhalb der Gruppen.

\[MSS_{between} = SS_{between}/df_{between}\]

\[MSS_{within} = SS_{within}/df_{within}\]

  • Teststatistik \(F\)

\[F = \frac{MSS_{between}}{MSS_{within}}\]

  • \(p\)-Wert

    • gibt die Wahrscheinlichkeit eine so grosse oder noch grössere Teststatistik \(F\) unter der Annahme, dass die Mittelwerte aller Gruppen gleich gross sind.

    • ist die Fläche unter der Kurve der \(F\)-Verteilung mit den Freiheitsgraden \(df_{between}\) und \(df_{within}\) oberhalb des \(F\)-Werts.

    • in R

pf(F, df_between, df_within, lower.tail = FALSE)

Bedingungen für ANOVA

  • Unabhängigkeit der Messungen

    • zwischen den Gruppen: Die Gruppen müssen voneinander unabhängig sein, andernfalls ist eine ANOVA für Messwiederholungen (repeated measures anova) durchzuführen.
    • innerhalb der Gruppen: Die Beobachtungseinheiten müssen unabhängig voneinander sein.
  • Normalverteilung: Die Daten innerhalb jeder Gruppe sollten annähernd normalverteilt sein.

  • Die Gruppen sollten annähernd gleiche Varianzen haben.

Post-Hoc paarweise Vergleiche

  • Das Signifikanzniveau muss für die Anzahl der Vergleiche angepasst werden. Es existieren verschiedene Verfahren. Am einfachsten ist die Bonferroni-Korrektur. Vergleiche den \(p\)-Wert für jeden Test mit dem Signifikanzniveau \(\alpha^*\).

\[\alpha^* = \frac{\alpha}{K}\]

\[K = Anzahl ~Vergleiche = \frac{k(k-1)}{2}\]

  • Standardfehler für mehrere paarweise Vergleiche

\[SE = \sqrt{\frac{MSS_{within}}{n_1}+\frac{MSS_{within}}{n_2}}\]

  • Teststatistik \(t\)

\[t = \frac{(\bar{x}_1 - \bar{x}_2) - (\mu_1-\mu_2)}{\sqrt{\frac{MSS_{within}}{n_1}+\frac{MSS_{within}}{n_2}}}\]

# p-Wert für zweiseitigen t-Test
2 * pt(t-Wert, df, lower.tail = FALSE)

Beispiel

library(dplyr)

# create sample data -----------------------------------------------------------
data <- tibble(
  gruppe = c(rep("G1", 7), rep("G2", 7), rep("G3", 7)),
  score = c(92, 93, 100, 104, 89, 91, 99, 71, 62, 85, 94, 78, 66, 71, 64, 73, 87, 91, 56, 78, 87)
)

# create anova summary table ---------------------------------------------------
anova <- aov(score ~ gruppe, data = data)
summary(anova)
##             Df Sum Sq Mean Sq F value  Pr(>F)   
## gruppe       2   1780   890.1    8.18 0.00297 **
## Residuals   18   1959   108.8                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# post hoc analysis ------------------------------------------------------------
pairwise.t.test(data$score, data$gruppe, 
                p.adjust.method = "bonferroni", 
                paired = FALSE,
                alternative = "two.sided")
## 
##  Pairwise comparisons using t tests with pooled SD 
## 
## data:  data$score and data$gruppe 
## 
##    G1    G2   
## G2 0.006 -    
## G3 0.010 1.000
## 
## P value adjustment method: bonferroni
# 95%-Konfidenzintervalle für Differenzen --------------------------------------
TukeyHSD(anova)
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = score ~ gruppe, data = data)
## 
## $gruppe
##             diff       lwr       upr     p adj
## G2-G1 -20.142857 -34.37399 -5.911722 0.0053757
## G3-G1 -18.857143 -33.08828 -4.626008 0.0088636
## G3-G2   1.285714 -12.94542 15.516849 0.9711637
plot(TukeyHSD(anova))




Inferenz für qualitative Daten

  • \(p:\) Populationsparameter
  • \(\hat{p}:\) Punktschätzer für den Populationsparameter (Anzahl Erfolge/Stichprobenumfang)

Zentraler Grenzwertsatz für relative Häufigkeiten (engl. proportions)

  • Relative Häufigkeiten von Stichproben sind annähernd normalverteilt mit ihrem Zentrum bei der Häufigkeit in der Population und einem Standardfehler, der umgekehrt proportional ist zum Stichprobenumfang.

\[\hat{p} \sim N \lgroup Mittelwert = p, SE = \sqrt{\frac{p(1-p)}{n}} \rgroup\]

  • Voraussetzungen
    • Unabhängigkeit: Die Beobachtungen müssen voneinander unabhängig sein
    • Stichprobenumfang: Es müssen mindestens 10 Erfolge und 10 Misserfolge vorliegen
    \[n \times p \geq 10; ~n \times (1-p) \geq 10\]

Beispiel

  • Berechne die Wahrscheinlichkeit \(P(\hat{p} > 0.95)\) für ein Ereignis mit der Erfolgswahrscheinlichkeit \(p\) = 0.9 und einen Stichprobenumfang \(n\) = 200.
  1. Voraussetzungen prüfen
p <- 0.9
n <- 200

n * p       # Anzahl Erfolge
## [1] 180
n * (1 - p) # Anzahl Misserfolge
## [1] 20
  1. Normalverteilungsapproximation
  • Mittelwert und SE berechnen

\[\hat{p} \sim N \lgroup Mittelwert = 0.9, SE = \sqrt{\frac{0.9 \times 0.1}{200}} = 0.0212 \rgroup\]

  • \(z\)-Wert berechnen

\[z = \frac{0.95 - 0.9}{0.0212} = 2.36\]

  • \(p\)-Wert berechnen

\[P(Z > 2.36) \approx 0.0091\]

  • Unter Verwendung der Binomialverteilung

    • Die erwartete Wahrscheinlichkeit bei 200 Versuchen mit \(p\) = 0.95 ist \(\hat{p} = 200 \times 0.95 = 190\)
    • Wie gross ist die Wahrscheinlichkeit für \(p \geq 190\) bei 200 Stichproben und einer Wahrscheinlichkeit von \(p\) = 0.9 in der Population unter der Nullhypothese?
# Wahrscheinlichkeit für 190 oder mehr Erfolge

sum(dbinom(190 : 200, size = 200, prob = .9))
## [1] 0.00807125

Konfidenzintervall für eine relative Häufigkeit

Vorgehen

  1. Voraussetzungen prüfen: Die Beobachtungen sind unabhängig, \(\hat{p} n \geq 10\) und \((1-\hat{p})n \geq 10\) (Beachte: Wir verwenden hier den Schätzer für \(p\)!)
  2. Wenn die Voraussetzungen erfüllt sind, ist für die Stichprobenverteilung von \(\hat{p}\) näherungsweise das Normalverteilung gültig.
  3. Standardfehler \(SE\) mit \(\hat{p}\) anstelle von \(p\) berechnen mit der Formel

\[SE_{\hat{p}} = \sqrt{\frac{\hat{p}(1-\hat{p})}{n}}\]

  1. Konfidenzintervall berechnen

\[\hat{p} \pm z \times SE_{\hat{p}}\]

  • \(z\) = 1.96 für ein 95%-Konfidenzintervall


Hypothesentest für eine Stichprobe

Vorgehen

  1. Hypothesen formulieren:
  • \(H_0: p = Nullwert\)
  • \(H_A: p < oder > oder \neq Nullwert\)
  1. Punktschätzer \(\hat{p}\) berechnen.
  2. Voraussetzungen prüfen
  • Beobachtungen müssen unabhängig sein.
  • \(np \geq 10\) und \(n(p-1) \geq 10\) (hier \(p\) aus der Nullhypothese einsetzen!)
  1. Teststatistik \(z\) berechnen

\[z = \frac{\hat{p}-p}{SE} = \frac{\hat{p}-p}{\sqrt{\frac{p(1-p)}{n}}}\]

  1. Entscheide und interpretiere im Kontext der Forschungsfrage

    1. Verwerfe \(H_0\), wenn \(p \leq \alpha\); die Daten liefern Evidenz gegen \(H_0\).
    2. Verwerfe \(H_0\) nicht, wenn \(p > \alpha\); die Daten liefern keine Evidenz gegen \(H_0\).

\(\hat{p}\) versus \(p\)

  • Berechnung eines Konfidenzintervalls: \(p\) ist unbekannt und wir setzen den besten Schätzer \(\hat{p}\) ein.

\[n\hat{p} \geq 10; ~n(1-\hat{p}) \geq 10\]

\[SE_{\hat{p}} = \sqrt{\frac{\hat{p}(1-\hat{p})}{n}}\]

  • Hypothesentest: Wir testen gegen die Nullhypothese und setzen \(p\) aus \(H_0\) ein.

\[np \geq 10; ~n(1-p) \geq 10\]

\[SE = \sqrt{\frac{p(1-p)}{n}}\]

Beispiel

  • In einer Stichprobe von 100 Schüler:innen einer Schule sind 20 Raucher:innen.

\[n = 100, ~\hat{p} = 20/100 = 0.20\]

  • Konfidenzintervall berechnen

\[CI = \hat{p} \pm z \times SE\]

\[CI = \hat{p} \pm z \times \sqrt{\frac{\hat{p}(1-\hat{p})}{n}}\]

\[CI_{95} = 0.20 \pm 1.96 \times \sqrt{\frac{0.20 \times 0.80}{100}} \]

\[CI_{95} = 0.20 \pm 1.96 \times 0.04 \approx [0.12, ~0.28]\]

  • Interpretation: Wir können zu 95% darauf vertrauen, dass an dieser Schule zwischen 12% und 28% der Schüler:innen rauchen.


  • Hypothesentest

    • Frage: Unterscheidet sich der wahre Anteil an Schüler:innen, die an dieser Schule rauchen von 18%?
    • \(H_0: p = 18\)
    • \(H_A: p \neq 18\)

\[z = \frac{\hat{p}-p_0}{SE} = \frac{\hat{p}-p_0}{\sqrt(\frac{p_0(1-p_0)}{n})}\]

\[z = \frac{0.20-0.18}{\sqrt{\frac{0.18(1-0.18)}{100}}} = \frac{0.02}{0.0384} = 0.52\]

2 * pnorm(0.52, lower.tail = FALSE)
## [1] 0.6030636
  • Interpretation: \(p-Wert > \alpha\), wir haben keine Evidenz gegen die \(H_0\), die besagt, dass der wahre Anteil an Raucher:innen 18% beträgt. Das Ergebnis des Hypothesentests stimmt mit dem berechneten Konfidenzintervall von [0.12, 0.28] überein, das den Wert 0.18 enthält.

Vergleich von zwei relativen Häufigkeiten

  • Anwendung des zentralen Grenzwertsatzes

\[(\hat{p}_1-\hat{p}_2) \sim N \lgroup Mittelwert = (p_1-p_2), SE = \sqrt{\frac{p_1(1-p_1)}{n_1}+\frac{p_2(1-p_2)}{n_2}} \rgroup\]

  • Wir vergleichen die Zahlen der Schule mit einer zweiten Schule: Dort wurde eine Zufallsstichprobe von 120 Schüler:innen erhoben, wovon 30 Raucher:innen waren.

\[n_1 = 100, \hat{p}_1 = 20/100 = 0.20\]

\[n_2 = 120, \hat{p}_2 = 30/120 = 0.25\]

\[CI = (\hat{p}_1 - \hat{p}_2) \pm z \times \sqrt{\frac{\hat{p}_1(1-\hat{p}_1)}{n_1}+\frac{\hat{p}_2(1-\hat{p}_2)}{n_2}}\]

\[CI = (0.20-0.25) \pm z \times \sqrt{\frac{0.20 \times 0.80}{100}+\frac{0.25 \times 0.75}{120}}\]

\[CI_{95} = -0.05 \pm 1.96 \times 0.0562 \approx [-0.16, ~0.06]\]

  • Interpretation: Wir können zu 95% darauf vertrauen, dass der wahre Anteil an Raucher:innen in Schule 1 um -16% tiefer bis 6% höher ist als an Schule 2.


  • Hypothesentest

    • Frage: Unterscheiden sich die Anteile an Raucher:innen zwischen den beiden Schulen?
    • \(H_0: p_1 = p_2\)
    • \(H_A: p_1 \neq p_2\)

\[z = \frac{(\hat{p}_1-\hat{p}_2)-(p_1-p_2)}{\sqrt{\frac{\hat{p}_{pool}(1-\hat{p}_{pool})}{n_1} + \frac{\hat{p}_{pool}(1-\hat{p}_{pool})}{n_2}}}\]

\[\hat{p}_{pool} = \frac{Anzahl ~Erfolge}{Anzahl ~Fälle} = \frac{20+30}{100+120} \approx 0.23\]

\[z = \frac{(0.20-0.25)-0}{\sqrt{\frac{0.23 \times 0.77}{100} + \frac{0.23 \times 0.77}{120}}} = \frac{-0.05}{0.057} = -0.88\]

2 * pnorm(0.88, lower.tail = FALSE)
## [1] 0.3788593
  • Interpretation: \(p-Wert > \alpha\); wir haben keine Evidenz gegen die \(H_0\), die besagt, dass es keinen Unterschied zwischen den beiden Schulen bezüglich der Anteile an Raucher:innen gibt. Das 95%-Konfidenzintervall unterstützt dieses Ergebnis, da es Null enthält.




Chi-Quadrat-Test

auch Chi-Quadrat-Anpassungstest oder Chi-Quadrat-Unabhängigkeitstest
Untersucht, ob eine Zusammenhang zwischen zwei nominal oder ordinal skalierten Variablen besteht. Hypothesen:

  • \(H_0:\) Die Zeilen- und Spaltenvariablen sind voneineinander unabhängig.
  • \(H_A:\) Die Zeilen- und Spaltenvariablen sind hängen voneinander ab.

Für jede Zelle der Tabelle muss der erwartete Wert \(E\) unter der Nullhypothese berechnet werden.

\[E = \frac{Spaltentotal~\times~Zeilentotal}{Gesamttotal}\]

\(\chi^2\)-Teststatistik

\[\chi^2 = \sum_{i=1}^k \frac{(O-E)^2}{E}\]

  • \(O:\) beobachtete absolute Häufigkeiten
  • \(E:\) erwartete absolute Häufigkeiten
  • \(k:\) Anzahl Zellen

Die \(\chi^2\)-Verteilung hat nur einen Paramter: \(df\)

\[df = (R-1) \times (C-1)\]

  • \(R:\) Anzahl Zeilen
  • \(C:\) Anzahl Spalten

Merke: Der \(\chi^2\)-Test darf nur durchgeführt werden, wenn die erwartete Häufigkeit in jeder Zelle mindestens 5 beträgt. Andernfalls Fisher’s exakten Test durchführen.

Der \(\chi^2\)-Test kann in R einfach mit der Funktion chisq.test() durchgeführt werden.

Der kritische Wert für \(\chi^2\) kann in einer Verteilungstabelle abgelesen werden. Bei einer Vierfeldertafel (2 Zeilen und 2 Spalten) ist der Zusammenhang zwischen der Zeilen- und der Kolonnenvariable statistisch signifikant auf dem Niveau von 5% wenn \(\chi^2\) grösser als \(3.84~ (=1.96^2)\) ist.

Funktion in R

chisq.test()

Beispiel: Untersucht wurde bei 100 Schüler:innen, ob sie Tictoc verwenden.

# Beispielaten generieren
tictoc_m <- c(rep("ja", 23), rep("nein", 29))
tictoc_w <- c(rep("ja", 38), rep("nein", 10))
geschlecht <- c(rep("m", length(tictoc_m)), rep("w", length(tictoc_w)))
tictoc <- data.frame(Geschlecht = geschlecht,
                     tictoc = c(tictoc_m, tictoc_w))

# Chi-Quadrat-Test, Ergebnis in chisq speichern
chisq <- chisq.test(table(tictoc))

# Testergebnis anzeigen
chisq
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table(tictoc)
## X-squared = 11.379, df = 1, p-value = 0.0007428
# Beobachtete Werte anzeigen
chisq$observed
##           tictoc
## Geschlecht ja nein
##          m 23   29
##          w 38   10
# erwartete Werte anzeigen
chisq$expected
##           tictoc
## Geschlecht    ja  nein
##          m 31.72 20.28
##          w 29.28 18.72




Korrelation

Beschreibt die Stärke eines linearen Zusammenhangs zwischen zwei Variablen.
Zwei Korrelationskoeffizienten:

  • Korrelationskoeffizient nach Pearson \(r\)
    • ist empfindlich gegenüber Ausreissern

\[r = \frac{s_{xy}}{s_x \times s_y}\]

\(s_{xy}\) bezeichnet die Covarianz der beiden Variablen \(X\) und \(Y\):

\[s_{xy} = \frac{1}{n-1} \sum_{i=1}^n (x_i-\bar{x})(y_i-\bar{y})\]

  • Rangkorrelationskoeffizient nach Spearman \(r_s\)
    • ist robust gegenüber Ausreissern
    • misst den monotonen Zusammenhang zwischen zwei Variablen

Interpretation Korrelationskoeffizienten

  • Wertebereich: \([-1, ~1]\), \(0\) (kein Zusammenhang) \(\pm1\) (perfekter Zusammenhang)
  • Das Vorzeichen gibt die Richtung des Zusammenhangs an: - (Minus) bedeutet negativer Zusammenhang, + (Plus) bedeutet postitiver Zusammenhang.
  • Faustregel zur Interpretation:
    • -0.8 bis -1: starker negativer Zusammenhang
    • -0.8 bis -0.5: mittlerer negativer Zusammenhang
    • -0.5 bis 0.5: schwacher positiver Zusammenhang
    • 0.5 bis 0.8: mittlerer Zusammenhang
    • 0.8 bis 1: starker Zusammenhang
# Korrelationskoeffizient nach Pearson
cor(x, y)

# Rangkorrelationskoeffizient nach Spearman
cor(x, y, method = "spearman")

Hypothesentest für Korrelationskoeffizienten

  • \(H_0: \rho = 0\), es besteht kein linearer Zusammenhang zwischen zwei Variablen.
  • \(H_A: \rho \neq 0\), es besteht ein linearer Zusammenhang zwischen zwei Variablen.
# Korrelationskoeffizient nach Pearson
cor.test(x, y)

# Rangkorrelationskoeffizient nach Spearman
cor.test




Einfache lineare Regression

Quantifiziert den Zusammenhang zwischen zwei Variablen.
Unterscheide: abhängige Variable \(y\) und unabhängige Variable \(x\), Prädiktor

Lineares Modell

\[\hat{y} = \beta_0 + \beta_1 x + \epsilon\]

bzw. mit Stichprobendaten

\[\hat{y} = b_0 + b_1x + e\]

  • \(\hat{y}:\) geschätzte abhängige Variable
  • \(b_0:\) Achsenabschnitt (x = 0), intercept
  • \(b_1:\) Steigung der Regressionsgeraden, slope
  • \(x:\) Prädiktor
  • \(e:\) Fehler, Residuen

\[e_i = y_i - \hat{y}_i\]

Steigung der Regressionsgeraden \(b_1\)

  • Wenn \(x\) quantitativ ist: Wenn \(x\) um eine Einheit erhöht wird, erwarten wir, dass \(y\) um \(|b_1|\) Einheiten zunimmt bzw. abnimmt.
  • Wenn \(x\) nominal ist: Der Wert von \(y\) nimmt um \(|b_1|\) Einheiten gegenüber dem Referenzlevel zu bzw. ab.

\[b_1 = \frac{s_y}{s_y} r\]

  • \(s_y:\) Standardabweichung von y
  • \(s_y:\) Standardabweichung von x
  • \(r:\) Korrelationskoeffizient nach Pearson

Achsenabschnitt \(b_0\)

  • Wenn \(x\) quantitativ ist: Wenn \(x = 0\) ist \(y\) im Durchschnitt gleich \(b_0\)
  • Wenn \(x\) nominal ist: Der durchschnittliche Wert von \(y\) für ein bestimmtes Level von \(x\) ist gleich \(b_0\).

\[b_0 = \bar{y} - b_1 \bar{x}\]

  • \(\bar{y}:\) Mittelwert von \(y\)
  • \(\bar{x}:\) Mittelwert von \(x\)

Bedingungen für das lineare Regressionsmodell

  1. Linearität
  • Es besteht eine lineare Beziehung zwischen \(y\) und \(x\).
  • Wird anhand von einem Streudiagramm überprüft.
  1. Normalverteilung der Residuen
  • Die Residuen sind annähernd normalverteilt, mit einem Mittelwert um 0.
  • Wird anhand von einem QQ-Plot für die Residuen überprüft.
  1. Konstante Variabilität (Homoskedastizität)
  • Die Streuung der Punkte um die Regressionsgerade sollte annähernd konstant sein.
  • Das bedeutet, dass die Streuung der Residuen um den Mittelwert 0 annähernd konstant ist.
  • Wird an einem Streudiagramm für die Residuen geprüft.
# Beispieldaten generieren  
set.seed(1)
b0 <- 2
b1 <- .5
x <- runif(10) 
error <- rnorm(10, 0, .2)
y <- b0 + b1 * x + error
daten <- data.frame(x = x, y = y)

# lineares modell berechnen
model <- lm(y ~ x, data = daten)

# Zusammenfassung des Modells anzeigen
summary(model)
## 
## Call:
## lm(formula = y ~ x, data = daten)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.46653 -0.12534  0.04895  0.12012  0.25701 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   1.9728     0.1530  12.898 1.23e-06 ***
## x             0.5808     0.2437   2.383   0.0443 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.2308 on 8 degrees of freedom
## Multiple R-squared:  0.4151, Adjusted R-squared:  0.342 
## F-statistic: 5.679 on 1 and 8 DF,  p-value: 0.04434
# Diagnostische Plots anzeigen
plot(model, which = 1:2)

Bestimmtheitsmass \(R^2\)

Für die einfache lineare Regression:

\[R^2=r^2\]

  • \(r:\) Korrelationskoeffizient nach Pearson
  • Ist ein Mass für die Güte eines linearen Modells
  • sagt uns, wieviel Prozent der Streuung in \(y\) durch \(x\) erklärt werden.

\[R^2 = \frac{durch~ x ~erklärte~ Streuung~ von~ y}{Gesamtstreuung~ von~ y}\]

  • Die nicht durch \(R^2\) erklärbare Streuung wird durch Faktoren erklärt, die nicht im Modell eingeschlossen sind.
  • Wertebereich: [0, 1], 0 = 0%, 1 = 100%
  • Interpretation: \(R^2%\) der Variabilität von \(y\) wird durch \(x\) erklärt.

R-Funktionen

Zusammenstellung einiger häufig verwendeter R-Funktionen.

Wer etwas mehr Details sucht ist hier gut aufgehoben:

Hilfe erhalten

Hilfe zu einer bestimmten Funktion (in RStudio im Register Help)

?mean

Struktur eines Objekts anzeigen (in RStudio im Register Environment)

str(objectname)

Libraries verwenden

Eine Library herunterladen und installieren

install.packages("libraryname")

Eine Library laden

library(libraryname)

Arbeitsverzeichnis

Arbeitsverzeichnis anzeigen

getwd()

Arbeitsverzeichnis definieren

setwd("C://pfad")

Vektoren (Variablen)

Vektoren erzeugen

# Werte einem Vektor zuweisen
x <- 2
x
## [1] 2
# Elemente zu einem Vektor verbinden  
x <- c(2, 4, 6)
x
## [1] 2 4 6
# Eine ganzzahlige Sequenz erzeugen
x <- 2:6
x
## [1] 2 3 4 5 6
# Eine komplexe Sequenz erzeugen
x <- seq(2, 3, by = .5)
x
## [1] 2.0 2.5 3.0

Vektorfunktionen

# Beispielvariable erzeugen für Demo
x <- c(3, 2, 1, 2, 2, 1, 3, 4)  

# Variable sortieren
sort(x)
## [1] 1 1 2 2 2 3 3 4
# Werte zählen und in Tabelle ausgeben
table(x)
## x
## 1 2 3 4 
## 2 3 2 1
# Länge einer Variable bestimmen
length(x)
## [1] 8

Vektorelemente auswählen

# das 4. Element
x[4]
## [1] 2
# alle Elemente ausser dem 4. Element
x[-4]
## [1] 3 2 1 2 1 3 4
# Elemente 2 bis 4
x[2:4]
## [1] 2 1 2
# Elemente die gleich 3 sind
x[x == 3] 
## [1] 3 3
# Alle Elemente die kleiner als 3 sind  
x[x < 3]
## [1] 2 1 2 2 1

Datentypen

R kennt 4 Datentypen

# numeric (quantitativ)
x <- c(1, 0, 1)
str(x)
##  num [1:3] 1 0 1
# chraracter (string)
x <- c("Anna", "Felix", "Lena")
str(x)
##  chr [1:3] "Anna" "Felix" "Lena"
# factor (nominal), Verwendung als Gruppierungsvariable
x <- c("con", "exp", "exp")  
geschlecht <- factor(x,  levels = c("con", "exp"))
str(geschlecht)
##  Factor w/ 2 levels "con","exp": 1 2 2
# logical - TRUE, FALSE
x <- c(TRUE, FALSE, FALSE, TRUE)
x
## [1]  TRUE FALSE FALSE  TRUE
# Beispiel für die Verwendung von logischen Variablen
x <- 1:10
x
##  [1]  1  2  3  4  5  6  7  8  9 10
x > 5
##  [1] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
x[x > 5]
## [1]  6  7  8  9 10

Logische Operatoren

# a ist gleich b
a == b

# a ist nicht gleich b
a != b

# a ist grösser als b
a > b

# a ist kleiner als b
a < b

# a ist grösser gleich b
a >= b

# a ist kleiner gleich b
a <= B

# fehlende Wert in a
is.na(a)

Mathematische Funktionen

# Addieren
1 + 2
## [1] 3
# Subtrahieren
2 - 1
## [1] 1
# Multiplizieren
2 * 3
## [1] 6
# Dividieren
6 / 3
## [1] 2
# Quadrieren
3^2
## [1] 9
# Quadratwurzel ziehen
sqrt(9)
## [1] 3
# Absolutwert
abs(-2)
## [1] 2
# Beispielvariable erzeugen für Demo
x <- c(3, 2, 1, 2, 2, 1, 3, 4)  

# Summe berechnen
sum(x)
## [1] 18
# Maximum finden
max(x)
## [1] 4
# Minimum finden
min(x)
## [1] 1
# Wert auf 3 Stellen runden
Wert <- 3.1234567
round(Wert, 3)
## [1] 3.123
# Mittelwert von x
mean(x)
## [1] 2.25
# Median von x
median(x)
## [1] 2
# Varianz von x
var(x)
## [1] 1.071429
# Standardabweichung von x
sd(x)
## [1] 1.035098
# Spannweite, Variationsbreite (gibt min und max)
range(x)
## [1] 1 4
# Interquartilsabstand
IQR(x)
## [1] 1.25

Datensätze

In einem Datensatz haben alle Variablen die gleiche Länge!

# Einen Datensatz erstellen
df <- data.frame(
  variable1 = 1:3,
  variable2 = c("A", "B", "C")
)
df
##   variable1 variable2
## 1         1         A
## 2         2         B
## 3         3         C
# Gesamten Datensatz anzeigen
# View(df)

# Erste 6 Zeilen eines Datensatzes anzeigen
head(df)
##   variable1 variable2
## 1         1         A
## 2         2         B
## 3         3         C
# Anzahl Zeilen und Spalten anzeigen
dim(df)
## [1] 3 2
# Spalte des Datensatzes anzeigen
df[, 1]  
## [1] 1 2 3
# Zeile des Datensatzes anzeigen
df[2, ]
##   variable1 variable2
## 2         2         B
# Bestimmte Zelle des Datensatzes anzeigen
df[2, 2]
## [1] "B"
# Variable des Datensatzes
df$variable1
## [1] 1 2 3

Referenzen

Hughes, M. 2012. “Introduction to Nonparametric Statistics Using r.” Lecture Handout.
King, Andrew, and Robert Eckersley. 2019. Statistics for Biomedical Engineers and Scientists. Academic Press.
Leonhart, Rainer. 2013. Lehrbuch Statistik. Einstieg Und Vertiefung. Hans Huber.
Mi, Charles, Wadi, James Lindsay, James, Junyu Chen, Richard, and Mathieu Le et al. Corre. 2022. “Real Statistics Using Excel.” https://www.real-statistics.com/non-parametric-tests/wilcoxon-signed-ranks-test/.
LS0tDQp0aXRsZTogJ0dydW5ka3VycyBTdGF0aXN0aWs6IEZvcm1lbG4gdW5kIFItRnVua3Rpb25lbicNCmF1dGhvcjogIkx1a2FzIFN0YW1tbGVyIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRvY19mbG9hdDogeWVzDQogICAgdGhlbWU6IGZsYXRseQ0KICAgIGhpZ2hsaWdodDogZGVmYXVsdA0KICAgIGZpZ193aWR0aDogNQ0KICAgIGZpZ19oZWlnaHQ6IDMuNQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCmJpYmxpb2dyYXBoeTogYm9vay5iaWINCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCnJtKGxpc3QgPSBscygpKQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgICAgZmlnLmFsaWduPSJjZW50ZXIiKQ0KDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpgYGANCg0KIyBLZW5uemFobGVuDQoNCiMjIFVtZmFuZw0KDQokbiQgPSBTdGljaHByb2JlbnVtZmFuZyAgIA0KJE4kID0gVW1mYW5nIGRlciBQb3B1bGF0aW9uICANCg0KIyMgQXJpdGhtZXRpc2NoZXMgTWl0dGVsLCBNaXR0ZWx3ZXJ0DQoNCiRcYmFye3h9JCA9IFN0aWNocHJvYmVubWl0dGVsd2VydCAgDQokXG11JCA9IFBvcHVsYXRpb25zbWl0dGVsd2VydA0KDQokJFxiYXJ7eH0gPSBcZnJhY3tcc3VtX3tpPTF9Xm4geF9pfXtufSQkDQpgYGB7ciBtZWFuLCBldmFsPUZBTFNFfQ0KbWVhbigpDQpgYGANCg0KQmVpc3BpZWw6DQoNCmBgYHtyIG1lYW4tZXhwbH0NCnggPC0gYygyLCAzLCA0LCA0LCA1LCA2KQ0KbWVhbih4KQ0KYGBgDQojIyBNZWRpYW4NCg0Kd2VubiAkbiQgdW5nZXJhZGUNCg0KJCRcdGlsZGV7eH0gPSB4X3tcZnJhY3tuKzF9ezJ9fSQkDQoNCndlbm4gJG4kIGdlcmFkZSAgDQoNCiQkXHRpbGRle3h9ID0gXGZyYWN7MX17Mn0oeF97XGZyYWN7bn17Mn19ICsge3hfe1xmcmFje259ezJ9KzF9fSkkJA0KDQpgYGB7ciBtZWRpYW4sIGV2YWwgPSBGQUxTRX0NCm1lZGlhbigpDQpgYGANCg0KQmVpc3BpZWw6DQoNCmBgYHtyIG1lZGlhbi1leHBsfQ0KeCA8LSBjKDIsIDMsIDQsIDQsIDUsIDYsIDEwKQ0KbWVkaWFuKHgpDQpgYGANCg0KIyMgVmFyaWFueg0KDQokc14yJCA9IFN0aWNocHJvYmVudmFyaWFueiAgDQokXHNpZ21hXjIkID0gVmFyaWFueiBkZXIgUG9wdWxhdGlvbg0KDQokJHNeMiA9IFxmcmFje1xzdW1fe2k9MX1ebiAoeF9pIC0gXGJhcnt4fSleMn17bi0xfSQkDQoNCiQkXHNpZ21hXjIgPSBcZnJhY3tcc3VtX3tpPTF9Xm4gKHhfaSAtIFxtdSleMn17bn0kJA0KDQpgYGB7ciB2YXIsIGV2YWw9RkFMU0V9DQp2YXIoKQ0KYGBgDQoNCkJlaXNwaWVsOg0KDQpgYGB7ciB2YXItZXhwbH0NCnggPC0gYygyLCAzLCA0LCA0LCA1LCA2LCAxMCkNCnZhcih4KQ0KYGBgDQoNCg0KIyMgU3RhbmRhcmRhYndlaWNodW5nICANCg0KJHMkID0gU3RhbmRhcmRhYndlaWNodW5nIGRlciBTdGljaHByb2JlICANCiRcc2lnbWEkID0gU3RhbmRhcmRhYndlaWNodW5nIGRlciBQb3B1bGF0aW9uICANCg0KJCRzID0gXHNxcnR7c14yfSQkDQoNCiQkXHNpZ21hID0gXHNxcnR7XHNpZ21hXjJ9JCQNCg0KYGBge3Igc2QsIGV2YWw9RkFMU0V9DQpzZCgpDQpgYGANCg0KQmVpc3BpZWw6DQoNCmBgYHtyfQ0KeCA8LSBjKDIsIDMsIDQsIDQsIDUsIDYsIDEwKQ0Kc2QoeCkNCmBgYA0KDQojIEdyYWZpa2VuDQoNCiMjIEhpc3RvZ3JhbW0NCg0KYGBge3IgaGlzdCwgZXZhbD1GQUxTRX0NCmhpc3QoKQ0KYGBgDQoNCkJlaXNwaWVsOg0KDQpgYGB7ciBoaXN0LWV4cGx9DQp4IDwtIGMoMiwgMywgNCwgNCwgNSwgNiwgMTAsIDksIDgsIDcsIDcsIDcsIDUsIDQpDQpoaXN0KHgpDQpgYGANCg0KIyMgQm94cGxvdA0KDQpgYGB7ciBib3hwbG90LCBldmFsPUZBTFNFfQ0KYm94cGxvdCgpDQpgYGANCg0KQmVpc3BpZWw6DQoNCmBgYHtyIGJveHBsb3QtZXhwbH0NCnggPC0gYygyLCAzLCA0LCA0LCA1LCA2LCAxMCwgOSwgOCwgNywgNywgNywgNSwgNCkNCmJveHBsb3QoeCkNCmBgYA0KDQojIyBLcmV1enRhYmVsbGUsIGFic29sdXRlIEjDpHVmaWdrZWl0ZW4NCg0KYGBge3IgdGFibGUsIGV2YWw9RkFMU0V9DQp0YWJsZSgpDQpgYGANCg0KQmVpc3BpZWw6DQoNCmBgYHtyfQ0KeCA8LSBjKCJhIiwgImEiLCAiYiIsICJiIiwgImIiLCAiYyIpDQp0YWJsZSh4KQ0KYGBgDQoNCiMjIEtyZXV6dGFiZWxsZSwgcmVsYXRpdmUgSMOkdWZpZ2tlaXRlbg0KDQpgYGB7ciBwcm9wLnRhYmxlLCBldmFsPUZBTFNFfQ0KcHJvcC50YWJsZSgpDQpgYGANCg0KQmVpc3BpZWw6DQoNCmBgYHtyfQ0KeCA9IGMoImEiLCAiYSIsICJiIiwgImIiLCAiYiIsICJjIikNCnByb3AudGFibGUodGFibGUoeCkpDQpgYGANCg0KIyMgQmFsa2VuZGlhZ3JhbW0NCg0KYGBge3IgYmFycGxvdCwgZXZhbCA9IEZBTFNFfQ0KYmFycGxvdCgpDQpgYGANCg0KQmVpc3BpZWw6DQoNCmBgYHtyIGJhcnBsb3QtZXhwbH0NCnggPSBjKCJhIiwgImEiLCAiYiIsICJiIiwgImIiLCAiYyIpDQpiYXJwbG90KHRhYmxlKHgpKQ0KYGBgDQoNCjxici8+DQo8YnIvPg0KPGJyLz4NCg0KIyBXYWhyc2NoZWlubGljaGtlaXRlbiAgDQoNCg0KIyMgV2FocnNjaGVpbmxpY2hrZWl0IA0KDQoqIFVudGVyIFdhaHJzY2hlaW5saWNoa2VpdCB2ZXJzdGVodCBtYW4gZGllIENoYW5jZSwgZGFzcyBiZWkgZWluZW0gWnVmYWxsc2V4cGVyaW1lbnQgZWluIGJlc3RpbW10ZXMgRXJlaWduaXMgYXVmdHJpdHQuICAgDQoqIFdhaHJzY2hlaW5saWNoa2VpdGVuIGvDtm5uZW4gbnVyIFdlcnRlIHp3aXNjaGVuIDAgKHVubcO2Z2xpY2hlcyBFcmVpZ25pcykgdW5kIDEgKHNpY2hlcmVzIEVyZWlnbmlzKSB6dWdlb3JkbmV0IHdlcmRlbi4gICANCiogTmFjaCAqTGFwbGFjZSogaXN0IGRpZSBXYWhyc2NoZWlubGljaGtlaXQgZsO8ciBlaW4gZ8O8bnN0aWdlcyBFcmVpZ25pcyAkcChBKSQ6DQoNCiQkcChBKSA9IFxmcmFje25fQX17Tl97Z2VzYW10fX0gPSBcZnJhY3tBbnphaGx+ZGVyfmfDvG5zdGlnZW5+RXJlaWduaXNzZX17QW56YWhsfmRlcn5tw7ZnbGljaGVufkVyZWlnbmlzc2V9JCQNCg0KIyMgRXJlaWduaXMgdW5kIEdlZ2VuZXJlaWduaXMgIA0KDQokJHAoQSkgKyBwKE5pY2h0fkEpID0gMSQkDQoNCiMjIEJlZGluZ3RlIFdhaHJzY2hlaW5saWNoa2VpdGVuICANCg0KKiBEaWUgYmVkaW5ndGUgV2FocnNjaGVpbmxpY2hrZWl0ICRwKEF8QikkIHF1YW50aWZpemllcnQgZGllIFdhaHJzY2hlaW5saWNoa2VpdCBkZXMgRXJlaWduaXNzZXMgQSB1bnRlciBkZXIgQmVkaW5ndW5nLCBkYXNzIGRhcyBFcmVpZ25pcyBCIGVpbmdldHJldGVuIGlzdC4gIA0KDQokJHAoQXxCKSA9IFxmcmFje3AoQSBcY2FwIEIpfXtQKEIpfSQkDQoNCiogRGFzIFplaWNoZW4gJFxjYXAkIGlzdCBkYXMgbWF0aGVtYXRpc2NoZSBTeW1ib2wgZsO8ciBVTkQgKFNjaG5pdHRtZW5nZSB2b24gQSB1bmQgQikuICANCiogRGFzICpUaGVvcmVtIHZvbiBCYXllcyogZ2lidCBhbiwgd2llIG1hbiBlaW5lIGJlZGluZ3RlIFdhaHJzY2hlaW5saWNoa2VpdCAkcChBfEIpJCBhdXMgZGVyIHVtZ2VrZWhydGVuIGJlZGluZ3RlbiBXYWhyc2NoZWlubGljaGtlaXQgJHAoQnxBKSQgYmVyZWNobmVuIGthbm4uICAgDQoNCiQkcChBfEIpPSBcZnJhY3twKEEpIFx0aW1lcyBwKEJ8QSl9e3AoQil9JCQNCg0KIyMgVW5hYmjDpG5naWdrZWl0DQoNCiogWndlaSBFcmVpZ25pc3NlICRBJCB1bmQgJEIkIHNpbmQgdW5hYmjDpG5naWcsIHdlbm4gZGFzIEVpbnRyZWZmZW4gb2RlciBOaWNodC1FaW50cmVmZmVuIGRlcyBFcmVpZ25pc3NlcyAkQiQgZGllIFdhaHJzY2hlaW5saWNoa2VpdCBmw7xyIGVpbiBFcmVpZ25pcyAkQSQgbmljaHQgdmVyw6RuZGVydC4gIA0KDQokJHAoQSkgPSBwKEF8QikgfiwgfnAoQikgPSBwKEJ8QSkkJA0KDQo8YnIvPg0KPGJyLz4NCjxici8+DQoNCiMgTm9ybWFsdmVydGVpbHVuZw0KDQokJFggXHNpbSBOKFxtdSwgXHNpZ21hKSQkDQoNCiMjIDY4LTk1LTk5LjctUmVnZWwNCg0KKiA2OCUgaW4gJFxtdSBccG0gMVxzaWdtYSQgICANCiogOTUlIGluICRcbXUgXHBtIDJcc2lnbWEkLCBnZW5hdWVyICRcbXUgXHBtIDEuOTZcc2lnbWEkICANCiogOTkuNyUgaW4gJFxtdSBccG0gM1xzaWdtYSQgIA0KDQojIyB6LVdlcnQNCg0KJCR6ID0gXGZyYWN7eF9pLVxiYXJ7eH19e3N9JCQNCg0KKiBEZXIgei1XZXJ0IGVpbmVyIEJlb2JhY2h0dW5nICR4X2kkIGdpYnQgYW4sIHVtIHdpZXZpZWxlIFN0YW5kYXJkYWJ3ZWljaHVuZ2VuIGRpZSBCZW9iYWNodHVuZyDDvGJlciBvZGVyIHVudGVyIGRlbSBNaXR0ZWx3ZXJ0IGxpZWd0LiAgIA0KKiBEZXIgei1XZXJ0IGRlcyBNaXR0ZWx3ZXJ0cyBpc3QgMCAgDQoqIFVuZ2V3w7ZobmxpY2hlIEJlb2JhY2h0dW5nZW4gaGFiZW4gZWluZW4gei1XZXJ0IHZvbiAkfHp8PjIkLiAgDQoNCiMjIFBlcnplbnRpbGVuIGluIFIgYmVyZWNobmVuICAgDQoNCmBgYHtyIHBlcmNlbnRpbGVzLCBldmFsPUZBTFNFfQ0KIyBGbMOkY2hlIGxpbmtzIHZvbiB4DQpwbm9ybSh4LCBtZWFuLCBzZCkgIA0KDQojIEZsw6RjaGUgcmVjaHRzIHZvbiB4DQoxIC0gcG5vcm0oeCwgbWVhbiwgc2QpDQpwbm9ybSh4LCBtZWFuLCBzZCwgbG93ZXIudGFpbCA9IEZBTFNFKSANCg0KIyBXZXJ0IGF1ZiBlaW5lciBiZXN0aW1tdGVuIFBlcnplbnRpbGUNCnFub3JtKHBlcmNlbnRpbGUsIG1lYW4sIHNkKSANCmBgYA0KDQpCZWlzcGllbDoNCg0KYGBge3IgcGVyYy1leHBsLCBldmFsPVRSVUV9DQp4IDwtIGMoMiwgMywgNCwgNCwgNSwgNiwgMTAsIDksIDgsIDcsIDcsIDcsIDUsIDQpDQptaXR0ZWx3ZXJ0IDwtIG1lYW4oeCkNCnN0ZGFidyA8LSBzZCh4KQ0KDQojIFdhaHJzY2hlaW5saWNoa2VpdCBmw7xyIGRlbiBXZXJ0IGtsZWluZXIgb2RlciBnbGVpY2ggNw0KcG5vcm0oNywgbWl0dGVsd2VydCwgc3RkYWJ3KQ0KDQojIFdhaHJzY2hlaW5saWNoa2VpdCBmw7xyIGRlbiBXZXJ0IGdsZWljaCBvZGVyIGdyw7Zzc2VyIDcNCjEgLSBwbm9ybSg3LCBtaXR0ZWx3ZXJ0LCBzdGRhYncpDQoNCiMgV2VydCBhdWYgZGVyIDQwJS1QZXJ6ZW50aWxlDQpxbm9ybSguNCwgbWl0dGVsd2VydCwgc3RkYWJ3KQ0KYGBgDQoNCiMjIFFRLVBsb3QNCg0KYGBge3IgcXEsIGV2YWw9RkFMU0V9DQojIFB1bmt0ZSBpbiBTdHJldWRpYWdyYW1tIGRhcnN0ZWxsZW4NCnFxbm9ybSgpDQoNCiMgTGluaWUgaW4gUVEtUGxvdCBlaW56ZWljaG5lbg0KcXFsaW5lKCkNCmBgYA0KDQpCZWlzcGllbDoNCg0KYGBge3J9DQojIHNpbXVsYXRpb24gdm9uIDEwMCBub3JtYWx2ZXJ0ZWlsdGVuIFdlcnRlbiwgbWVhbiA9IDAsIHMgPSAxDQpzZXQuc2VlZCgxKQ0KeCA8LSBybm9ybSgxMDApDQoNCiMjIHFxLXBsb3QgZXJzdGVsbGVuDQpxcW5vcm0oeCkNCg0KIyMgTGluaWUgaW4gcXEtcGxvdCBlaW56ZWljaG5lbg0KcXFsaW5lKHgsIGNvbCA9ICJibHVlIikNCmBgYA0KDQo8Y2VudGVyPg0KIVtxcS1wbG90cyBJbnRlcnByZXRhdGlvbl0oLi9wbmcvcXEucG5nKQ0KPC9jZW50ZXI+DQoNCjxici8+DQo8YnIvPg0KPGJyLz4NCg0KIyBCaW5vbWlhbHZlcnRlaWx1bmcgICANCg0KJCRYIFxzaW0gQmluKG4sIHApJCQNCg0KKiAkbiQgPSBBbnphaGwgVmVyc3VjaGUgICAgDQoqICRwJCA9IEVpbnRyaXR0c3dhaHJzY2hlaW5saWNoa2VpdCAgIA0KDQojIyBFcndhcnR1bmdzd2VydCAoTWl0dGVsd2VydCkgZGVyIEJpbm9taWFsdmVydGVpbHVuZw0KDQokJFxtdSA9IG4gXHRpbWVzIHAkJA0KDQojIyBTdGFuZGFyZGFid2VpY2h1bmcgZGVyIEJpbm9taWFsdmVydGVpbHVuZyAgIA0KDQokJFxzaWdtYSA9IFxzcXJ0e25wKDEtcCl9JCQNCg0KIyMgQmVkaW5ndW5nZW4gZsO8ciBCaW5vbWlhbHZlcnRlaWx1bmcgICANCg0KKiBEaWUgVmVyc3VjaGUgbcO8c3NlbiB1bmFiaMOkbmdpZyBzZWluLiAgIA0KKiBEaWUgQW56YWhsIGRlciBWZXJzdWNoZSBtdXNzIGJla2FubnQgc2Vpbi4gICANCiogSmVkZXMgVmVyc3VjaHNlcmdlYm5pcyBpc3QgZW50d2VkZXIgZWluIEVyZm9sZyBvZGVyIGVpbiBNaXNzZXJmb2xnLiAgICANCiogRGllIFdhaHJzY2hlaW5saWNoa2VpdCBmw7xyIGVpbmVuIEVyZm9sZyBtdXNzIGbDvHIgamVkZW4gVmVyc3VjaCBnbGVpY2ggc2Vpbi4gICANCg0KIyMgV2FocnNjaGVpbmxpY2hrZWl0ZW4gZGVyIEJpbm9taWFsdmVydGVpbHVuZyAgICANCg0KKiBXZW5uICRwJCBkaWUgV2FocnNjaGVpbmxpY2hrZWl0IGbDvHIgZWluZW4gRXJmb2xnIGlzdCwgaXN0ICQxLXAkIGRpZSBXYWhyc2NoZWlubGljaGtlaXQgZsO8ciBlaW5lbiBNaXNzZXJmb2xnLiAkbiQgZ2lidCBkaWUgQW56YWhsIGRlciBWZXJzdWNoZSBhbiB1bmQgJGskIGRpZSBBbnphaGwgZGVyIEVyZm9sZ2UuICAgDQoNCiQkcChrLCBuKSA9ICB7biBcY2hvb3NlIGt9cF5rKDEtcClee24ta30kJA0KDQoqIFdhaHJzY2hlaW5saWNoa2VpdCBmw7xyICRrJCBFcmZvbGdlIGluICRuJCBWZXJzdWNoZW4gbWl0IGRlciBFcmZvbGdzd2FocnNjaGVpbmxpY2hrZWl0ICRwJCBpbiBgUmAgYmVyZWNobmVuOg0KDQpgYGB7ciwgZWNobz1UUlVFLCBldmFsPUZBTFNFfQ0KZGJpbm9tKGssIG4sIHApDQpgYGANCg0KKiBBbnphaGwgS29tYmluYXRpb25lbiB2b24gJGskIEVyZm9sZ2VuIGluICRuJCBWZXJzdWNoZW4gYmVyZWNobmVuIChCaW5vbWlhbGtvZWZmaXppZW50KSAgDQoNCiQke24gXGNob29zZSBrfSA9IFxmcmFje24hfXtrIShuLWspIX0kJA0KDQpgYGB7ciwgZWNobz1UUlVFLCBldmFsPUZBTFNFfQ0KY2hvb3NlKG4sIGspDQpgYGANCg0KIyMgTm9ybWFsYXBwcm94aW1hdGlvbiAgIA0KDQoqIEVpbmUgQmlub21pYWx2ZXJ0ZWlsdW5nIG1pdCBtaW5kZXN0ZW5zIDEwIGVyd2FydGV0ZW4gRXJmb2xnZW4gdW5kIG1pbmRlc3RlbnMgMTAgZXJ3YXJ0ZXRlbiBNaXNzZXJmb2xnZW4gZm9sZ3QgYW5uw6RoZXJuZCBlaW5lciBOb3JtYWx2ZXJ0ZWlsdW5nLiAgIA0KDQokJG4gXHRpbWVzIHAgXHRpbWVzICgxLXApIFxnZXEgMTAkJA0KJCRuKDEtcCkgXGdlcSAxMCQkICAgDQoNCiogRmFsbHMgZGllc2UgQmVkaW5ndW5nIGVyZsO8bGx0IGlzdCwgZ2lsdDoNCg0KJCRCaW4obiwgcCkgXHNpbSBOKFxtdSwgXHNpZ21hKSQkDQoNCiogd29iZWkNCg0KJCRcbXUgPSBucCQkDQokJFxzaWdtYSA9IFxzcXJ0e25wKDEtcCl9JCQNCg0KPGJyLz4NCjxici8+DQo8YnIvPg0KDQojIEdydW5kbGFnZW4gZGVyIEluZmVyZW56c3RhdHN0aWsNCg0KIyMgWmVudHJhbGVyIEdyZW56d2VydHNhdHoNCg0KRGllIFZlcnRlaWx1bmcgdm9uIFN0aWNocHJvYmVua2VubnphaGxlbiAoei5CLiBNaXR0ZWx3ZXJ0KSBmb2xndCBhbm7DpGhlcm5kIGVpbmVyIE5vcm1hbHZlcnRlaWx1bmcuIElociBNaXR0ZWx3ZXJ0IGxpZWd0IGluIGRlciBOw6RoZSBkZXMgUG9wdWxhdGlvbnNtaXR0ZWx3ZXJ0ZXMgJFxtdSQgbWl0IGVpbmVyIFN0YW5kYXJkYWJ3ZWljaHVuZyBnZXRlaWx0IGR1cmNoIGRpZSBRdWFkcmF0d3VyemVsIGRlcyBTdGljaHByb2JlbnVtZmFuZ3MuDQoNCiQkXGJhcnt4fSBcc2ltIE4oTWl0dGVsd2VydCA9IFxtdSwgU0UgPSBcZnJhY3tcc2lnbWF9e1xzcXJ0e259fSkkJA0KDQpXZW5uICRcc2lnbWEkIHVuYmVrYW5udCBpc3QgKHdhcyBlaWdlbnRsaWNoIGltbWVyIGRlciBGYWxsIGlzdCksIHdpcmQgZGllIFN0YW5kYXJkYWJ3ZWljaHVuZyAkcyQgZGVyIFN0aWNocHJvYmUgYWxzIFNjaMOkdHplciBmw7xyICRcc2lnbWEkIGVpbmdlc2V0enQuDQoNCiQkU0UgPSBcZnJhY3tzfXtcc3FydHtufX0kJA0KDQpCZWRpbmd1bmdlbiBmw7xyIGRpZSBHw7xsdGlna2VpdCBkZXMgemVudHJhbGVuIEdyZW56d2VydHNhdHplczogIA0KDQoqIERpZSBCZW9iYWNodHVuZ3NlaW5oZWl0ZW4gaW4gZGVyIFN0aWNocHJvYmUgc2luZCB1bmFiaMOkbmdpZyB2b25laW5hbmRlciAoenVmw6RsbGlnZSBBdXN3YWhsLCB6dWbDpGxsaWdlIFp1b3JkbnVuZyB6dSBHcnVwcGVuKS4gICANCiogRmF1c3RyZWdlbDogU3RpY2hwcm9iZW51bWZhbmcgJG4+MzAkDQoNCkJlaXNwaWVsIGbDvHIgZGllIEJlcmVjaG51bmcgZGVzIFN0YW5kYXJkZmVobGVycyAkU0UkIGluIGBSYA0KDQpgYGB7cn0NCiMgc2ltdWxhdGlvbiB2b24gMTAwIG5vcm1hbHZlcnRlaWx0ZW4gV2VydGVuLCBtZWFuID0gMCwgcyA9IDENCnNldC5zZWVkKDEyMzQpDQp4IDwtIHJub3JtKDEwMCkNCg0KIyBTdGljaHByb2JlbnVtZmFuZyB2b24geCBlcm1pdHRlbG4NCm4gPC0gbGVuZ3RoKHgpDQoNCiMgU3RhbmRhcmRhYndlaWNodW5nIHZvbiB4IGJlcmVjaG5lbg0KcyA8LSBzZCh4KQ0KDQojIEJlcmVjaG51bmcgdm9uIFNFDQpTRSA8LSBzL3NxcnQobikNCg0KIyBPdXRwdXQgU0UNClNFDQpgYGANCg0KIyMgS29uZmlkZW56aW50ZXJ2YWxsZSAgDQoNCktvbmZpZGVuemludGVydmFsbGUgKFZlcnRyYXVlbnNpbnRlcnZhbGxlLCAkQ0kkKSBrw7ZubmVuIGF1ZiBqZWRlbSBLb25maWRlbnpuaXZlYXUgYmVyZWNobmV0IHdlcmRlbi4gVW0gZGllIFNhY2hlIG5pY2h0IGFsbHp1IGtvbXBsaXppZXJ0IHp1IG1hY2hlbiwgd2lyZCBoaWVyIHYuYS4gZXhlbXBsYXJpc2NoIGRpZSBCZXJlY2hudW5nIHZvbiA5NSUtS29uZmlkZW56aW50ZXJhdmFsbGVuIHZvcmdlc3RlbGx0LiAgDQoNCiogU2lnbmlmaWthbnpuaXZlYXUgPSAkXGFscGhhJCANCiogS29uZmlkZW56bml2ZWF1ID0gJDEtXGFscGhhJCAgDQoNCiQkQ0leKiA9IFxiYXJ7eH0gXHBtIHpeKiBcdGltZXMgU0UkJA0KDQokJHpeKiA9IFx2ZXJ0IFxmcmFjeygxLUNJXiopfXsyfSBcdmVydCQkDQoNCiQkel4qIFx0aW1lcyBTRSA9IHpeKiBcdGltZXMgXGZyYWN7c317XHNxcnR7bn19JCQNCg0KJHpeKiBcdGltZXMgU0UkIHdpcmQgYXVjaCBhbHMgRmVobGVyYmVyZWljaCAoZW5nbC4gJG1hcmdpbn4gb2Z+IGVycm9yLH4gTUUkKSBiZXplaWNobmV0Lg0KDQpEZXIgV2VydCB2b24gJHpeKiQgaXN0IGFiaMOkbmdpZyB2b20gS29uZmlkZW56bml2ZWF1LiAgIA0KDQpgYGB7ciB6LXZhbHVlc30NCiMgeiBmw7xyIGVpbiA5NSUgQ0kNCkNJIDwtIC45NQ0Kejk1IDwtIGFicyhxbm9ybSgoMSAtIENJKS8yKSkNCno5NQ0KDQojIHogZsO8ciBlaW4gOTAlIENJDQpDSSA8LSAuOQ0KejkwIDwtIGFicyhxbm9ybSgoMSAtIENJKS8yKSkNCno5MA0KDQojIHogZsO8ciBlaW4gOTklIENJDQpDSSA8LSAuOTkNCno5OSA8LSBhYnMocW5vcm0oKDEgLSBDSSkvMikpDQp6OTkNCmBgYA0KDQpCZWlzcGllbCBmw7xyIGRpZSBCZXJlY2hudW5nIGVpbmVzIDk1JSBLb25maWRlbnppbnRlcnZhbGxzDQoNCmBgYHtyfQ0KbSA8LSA5NS42ICAgICAgICMgU3RpY2hwcm9iZW5taXR0ZWx3ZXJ0DQpzIDwtIDE1LjggICAgICAgIyBTdGFuZGFyZGFid2VpY2h1bmcgZGVyIFN0aWNocHJvYmUNCm4gPC0gMTAwICAgICAgICAjIFN0aWNocHJvYmVudW1mYW5nDQoNCiMgZ2VzdWNodCBpc3QgZGFzIDk1JSBLb25maWRlbnppbnRlcnZhbGwgZsO8ciBkZW4gUG9wdWxhdGlvbnNtaXR0ZWx3ZXJ0ICANCkNJIDwtIC45NSAgICAgICAjIEtvbmZpZGVuem5pdmVhdSA5NSUNCnogPC0gYWJzKHFub3JtKCgxLUNJKS8yKSkNCk1FIDwtIHogKiBDSSAgICAjIEZlaGxlcmJlcmVpY2ggYmVyZWNobmVuDQoNCiMgT2JlcmUgdW5kIHVudGVyZSBHcmVuemUgZsO8ciA5NSUtS29uZmlkZW56aW50ZXJ2YWxsIGJlcmVjaG5lbg0KQ0k5NSA8LSBtICsgYygtMSwgMSkgKiBNRQ0KQ0k5NQ0KYGBgDQoNCiMjIFp1dmVybMOkc3NpZ2tlaXQgdnMuIFByw6R6aXNpb24gIA0KDQpXZW5uIHdpciBkYXMgS29uZmlkZW56bml2ZWF1IGVyaMO2aGVuIChLb25maWRlbnppbnRlcnZhbGwgd2lyZCBicmVpdGVyLCB6LkIuIHZvbiA5NSUgYXVmIDk5JSkgbmltbXQgZGllIFp1dmVybMOkc3NpZ2tlaXQsIGRhc3Mgd2lyIGRlbiB3YWhyZW4gUG9wdWxhdGlvbnNwYXJhbWV0ZXIgaW0gSW50ZXJ2YWxsIGhhYmVuIHp1LCBhbGxlcmRpbmdzIGF1ZiBLb3N0ZW4gZGVyIFByw6R6aXNpb24uICAgDQpXaWUga8O2bm5lbiB3aXIgWnV2ZXJsw6Rzc2lna2VpdCB1bmQgUHLDpHppc2lvbiBnbGVpY2h6ZWl0aWcgdmVyYmVzc2Vybj8gQW50d29ydDogU3RpY2hwcm9iZW51bWZhbmcgZXJow7ZoZW4uICAgDQoNClN0aWNocHJvYmVudW1mYW5nIGbDvHIgZWluZW4gYmVzdGltbXRlbiBGZWhsZXJiZXJlaWNoIGJlcmVjaG5lbjoNCg0KJCRNRSA9IHpeKiBcdGltZXMgXGZyYWN7c317XHNxcnR7bn19IFxyaWdodGFycm93IG4gPSAoXGZyYWN7el4qIFx0aW1lcyBzfXtNRX0pXjIkJA0KDQpCZWlzcGllbDogSW0gQmVpc3BpZWwgb2JlbiBiZXRydWcgdW5zZXIgTUUgPSAxLjg2Mi4gV2lyIG3DtmNodGVuIGRlbiBNRSBoYWxiaWVyZW4gdW5kIGJlc3RpbW1lbiBkZW4gYmVuw7Z0aWd0ZW4gU3RpY2hwcm9iZW51bWZhbmcuIChLZW5uemFobGVuIHdpZSBvYmVuKQ0KDQpgYGB7cn0NCk1FLmFsdCA8LSAxLjg2Mg0KTUUubmV1IDwtIE1FLmFsdC8yDQoNCiMgbmV1ZXMgOTUlLUtvbmZpZGVuemludGVydmFsbCBiZXJlY2huZW4NCkNJOTUubmV1IDwtIG0gKyBjKC0xLCAxKSAqIE1FLm5ldQ0KQ0k5NS5uZXUNCg0KIyBTdGljaHByb2JlbnVtZmFuZyBmw7xyIGRhcyBuZXVlIDk1JS1DSSBiZXJlY2huZW4NCm4ubmV1IDwtICgoeiAqIHMpL01FLm5ldSleMg0Kbi5uZXUNCmBgYA0KDQojIyBIeXBvdGhlc2VudGVzdCBmw7xyIGVpbmVuIE1pdHRlbHdlcnQgICANCg0KKipIeXBvdGhlc2VudGVzdHMgd2VyZGVuIGltbWVyIGbDvHIgZWluZW4gUG9wdWx0aW9uc3BhcmFtZXRlciwgei5CLiAkXG11JCBkdXJjaGdlZsO8aHJ0IHVuZCBuaWNodCBmw7xyIGVpbmUgU3RpY2hwcm9iZS4qKg0KDQoxLiBGb3JtdWxpZXJlIGRpZSB3aXNzZW5zY2hhZnRsaWNoZSBIeXBvdGhlc2UgIA0KDQogICogJEhfMDogXG11ID0gTnVsbHdlcnQkICAgDQogICogJEhfQTogXG11IDwgb2RlciA+IG9kZXIgXG5lcSBOdWxsd2VydCQgIA0KICAqIEVzIHdpcmQgZW1wZm9obGVuICRIX0E6JCBpbW1lciB6d2Vpc2VpdGlnIGZvcm11bGllcmVuIGF1c3NlciBpbiBiZWdyw7xuZGV0ZW4gQXVzbmFobWVmw6RsbGVuLg0KICANCjIuIEJlcmVjaG5lIGRlbiBQdW5rdHNjaMOkdHplciAkXGJhcnt4fSQgZsO8ciAkXG11JCAgDQozLiDDnGJlcnByw7xmZSBkaWUgVGVzdHZvcmF1c3NldHp1bmdlbiAgIA0KDQogICogQmVvYmFjaHR1bmdzZWluaGVpdGVuIGluIGRlciBTdGljaHByb2JlIHNpbmQgdW5hYmjDpG5naWcuICAgDQogICogU3RpY2hwcm9iZSBzdGFtbXQgYXVzIGVpbmUgYW5uw6RoZXJuZCBub3JtYWx2ZXJ0ZWlsdGVuIFBvcHVsYXRpb24uICAgDQogICogRGVyIFN0aWNocHJvYmVudW1mYW5nICRuIFxnZXEgMzAkIG9kZXIgZ3LDtnNzZXIgYmVpIHN0YXJrIHNjaGllZmVyIFZlcnRlaWx1bmcuICAgDQogIA0KNC4gU2tpenppZXJlIGRpZSBTdGljaHByb2JlbnZlcnRlaWx1bmcsIHplaWNobmUgZGVpbmVuIFZlcndlcmZ1bmdzYmVyZWljaCBlaW4gdW5kIGJlcmVjaG5lIGRpZSBUZXN0c3RhdGlzdGlrLiAgICANCg0KJCR6ID0gXGZyYWN7XGJhcnt4fSAtIFxtdX17U0V9LCB+fiBTRSA9IFxmcmFje3N9e1xzcXJ0e259fSQkDQoNCjUuIExpZWd0ICR6JCBpbSBWZXJ3ZXJmdW5nc2JlcmVpY2ggd2lyZCAkSF8wJCB6dSBHdW5zdGVuIHZvbiAkSF9BJCB6dXLDvGNrZ2V3aWVzZW4uICAgDQo2LiBJbnRlcnByZXRpZXJlIGRlaW4gUmVzdWx0YXQgaW0gWnVzYW1tZW5oYW5nIG1pdCBkZXIgRnJhZ2VzdGVsbHVuZy4gIA0KDQogIA0KIyMjIHAtV2VydGUgYmVyZWNobmVuICAgDQoNCkRlZmluaXRpb246IA0KDQokJHAtV2VydCA9IFAoYmVvYmFjaHRldGV+b2Rlcn5leHRyZW1lcmV+VGVzdHN0YXRpc3Rpa34gfCB+SF8wfiB3YWhyKSQkDQoNCkRlciBwLVdlcnQgcXVhbnRpZml6aWVydCBkaWUgRXZpZGVueiBnZWdlbiAkSF8wJC4gRWluIGtsZWluZXIgJHAkLVdlcnQgKMO8YmxpY2hlcndlaXNlICRwIFxsZXEgMC4wNSQpIGJlZGV1dGV0LCBkYXNzIGR1IGF1c3JlaWNoZW5kIEV2aWRlbnogZGFmw7xyIGhhc3QsICRIXzAkIHp1IEd1bnN0ZW4gdm9uICRIX0EkIHp1IHZlcndlcmZlbi4gICANCg0KKipFaW5zZWl0aWdlciBIeXBvdGhlc2VudGVzdCBhbmhhbmQgdm9uIHAtV2VydGVuKioNCg0KMS4gRmFsbA0KDQokSF9BOiBcbXUgPiBOdWxsd2VydCQNCg0KJCR6ID0gXGZyYWN7XGJhcnt4fS1OdWxsd2VydH17U0Vfe1xiYXJ7eH19fSQkDQoNCiRwJC1XZXJ0IGluIGBSYCBiZXJlY2huZW46DQoNCmBgYHtyIHAtdmFsdWUtZywgZXZhbD1GQUxTRX0NCnAgPC0gMSAtIHBub3JtKHopDQpgYGANCg0KMi4gRmFsbA0KDQokSF9BOiBcbXUgPCBOdWxsd2VydCQNCg0KJCR6ID0gXGZyYWN7XGJhcnt4fS1OdWxsd2VydH17U0Vfe1xiYXJ7eH19fSQkDQoNCiRwJC1XZXJ0IGluIGBSYCBiZXJlY2huZW46DQoNCmBgYHtyIHAtdmFsdWUtbCwgZXZhbD1GQUxTRX0NCnAgPC0gcG5vcm0oeikNCmBgYA0KDQoNCioqWndlaXNlaXRpZ2VyIEh5cG90aGVzZW50ZXN0IGFuaGFuZCB2b24gcC1XZXJ0ZW4qKg0KDQpad2Vpc2VpdGlnZSBIeXBvdGhlc2VuIHNpbmQgZGVyIE5vcm1hbGZhbGwuIEVpbnNlaXRpZ2UgSHlwb3RoZXNlbiBzb2xsdGVuIG51ciBpbiBiZWdyw7xuZGV0ZW4gQXVzbmFobWVmw6RsbGVuIGZvcm11bGllcnQgd2VyZGVuLiAgDQoNCiRIX0E6IFxtdSBcbmVxIE51bGx2YWx1ZSQgICANCg0KJCR6ID0gXGZyYWN7XGJhcnt4fS1OdWxsd2VydH17U0Vfe1xiYXJ7eH19fSQkDQoNCiRwJC1XZXJ0IGluIGBSYCBiZXJlY2huZW46DQoNCmBgYHtyIHAtdmFsdWUtdHdvcywgZXZhbD1GQUxTRX0NCnAgPC0gMiAqIHBub3JtKGFicyh6KSwgbG93ZXIudGFpbCA9IEZBTFNFKQ0KDQojIEFsdGVybmF0aXZlDQpwIDwtIDIgKiBwbm9ybSgtYWJzKHopKQ0KYGBgDQoNCiMjIyBFbnRzY2hlaWR1bmdzZmVobGVyDQoNCiogRmVobGVyIDEuIEFydDogJEhfMCQgd2lyZCB2ZXJ3b3JmZW4gd2VubiAkSF8wJCB3YWhyIGlzdC4gICANCiogRmVobGVyIDIuIEFydDogJEhfMCQgd2lyZCBuaWNodCB2ZXJ3b3JmZW4gd2VubiAkSF9BJCB3YWhyIGlzdC4gICANCg0KQmVpIGVpbmVtIFNpZ25pZmlrYW56bml2ZWF1ICRcYWxwaGEgPSAwLjA1JCBuZWhtZW4gd2lyIGVpbiBSaXNpa28gdm9uIDUlIGluIEthdWYsIGVpbmVuIEZlaGxlciAxLiBBcnQgenUgYmVnZWhlbi4gDQoNCiogJFxhbHBoYTokIFdhaHJzY2hlaW5saWNoa2VpdCwgZWluZW4gRmVobGVyIDEuIEFydCB6dSBiZWdlaGVuLiAgDQoqICRcYmV0YTokIFdhaHJzY2hlaW5saWNoa2VpdCwgZWluZW4gRmVobGVyIDIuIEFydCB6dSBiZWdlaGVuLiAgIA0KKiAkMS1cYmV0YTokIFBvd2VyIChUcmVubnNjaMOkcmZlKSBlaW5lcyBUZXN0czsgV2FocnNjaGVpbmxpY2hrZWl0LCBmw7xyICRIX0EkIHp1IGVudHNjaGVpZGVuLCB3ZW5uICRIX0EkIHdhaHIgaXN0Lg0KDQojIyMgSHlwb3RoZXNlbnRlc3RzIG1pdCBLb25maWRlbnppbnRlcnZhbGxlbiAgDQoNCiogRWluIHp3ZWlzZWl0aWdlciBIeXBvdGhlc2VudGVzdCBtaXQgZWluZW0gU2lnbmlmaWthbnpuaXZlYXUgJFxhbHBoYSQgZW50c3ByaWNodCBlaW5lbSBLb25maWRlbnppbnRlcnZhbGwgbWl0IGRlbSBLb25maWRlbnpuaXZlYXUgJDEtXGFscGhhJC4gIA0KKiBFaW4gZWluc2VpdGlnZXIgSHlwb3RoZXNlbnRlc3QgbWl0IGVpbmVtIFNpZ25pZmlrYW56bml2ZWF1ICRcYWxwaGEkIGVudHNwcmljaHQgZWluZW0gVmVydHJhdWVuc2ludGVydmFsbCBtaXQgZWluZW0gS29uZmlkZW56bml2ZWF1IHZvbiAkMS0oMiBcdGltZXMgXGFscGhhKSQuICAgDQoqIEVudGjDpGx0IGVpbiA5NSUgVmVydHJhdWVuc2ludGVydmFsbCBkZW4gTnVsbHdlcnQgbmljaHQsIHdpcmQgJEhfMCQgdmVyd29yZmVuLiAgDQoqIEVudGjDpGx0IGVpbiA5NSUgVmVydHJhdWVuc2ludGVydmFsbCBkZW4gTnVsbHdlcnQsIHdpcmQgJEhfMCQgbmljaHQgdmVyd29yZmVuLiAgIA0KDQo8YnIvPg0KPGJyLz4NCjxici8+DQoNCiMgSW5mZXJlbnogZsO8ciBxdWFudGl0YXRpdmUgRGF0ZW4gIA0KDQojIyBIeXBvdGhlc2VudGVzdHMgZsO8ciBnZXBhYXJ0ZSBNaXR0ZWx3ZXJ0ZSAgIA0KDQoqIEdlcGFhcnRlIChhdWNoIHZlcmJ1bmRlbmUpIERhdGVuOiAgICANCg0KICAqIEdsZWljaGUgQmVvYmFjaHR1bmdzZWluaGVpdGVuOiBWb3JoZXItTmFjaGhlci1NZXNzdW5nZW4sIE1lc3N3aWVkZXJob2x1bmdlbiAgDQogICogVW50ZXJzY2hpZWRsaWVjaGUgQmVvYmFjaHR1bmdzZWluaGVpdGVuIChqZWRvY2ggYWJow6RuZ2lnKTogWndpbGxpbmdzc3R1ZGllbiwgUGFydG5lciAgIA0KDQoqIFBhcmFtZXRlcjogJFxtdV97XERlbHRhfSQgPSBNaXR0ZWx3ZXJ0IGRlciBwYWFyd2Vpc2VuIERpZmZlcmVuemVuIGluIGRlciBQb3B1bGF0aW9uICAgICAgDQoqIFB1bmt0c2Now6R0emVyOiAkXGJhcnt4fV97XERlbHRhfSQgPSBNaXR0ZWx3ZXJ0IGRlciBwYWFyd2Vpc2VuIERpZmZlcmVuemVuIGluIGRlciBTdGljaHByb2JlICAgDQoqIFRlc3RzdGF0aXN0aWs6ICR6JC1XZXJ0DQoqIEh5cG90aGVzZW46ICAgDQoNCiAgKiAkSF8wOiBcbXVfe1xEZWx0YX0gPSBOdWxsd2VydCQgICANCiAgKiAkSF9BOiBcbXVfe1xEZWx0YX0gXG5lcSBOdWxsd2VydCQgKHp3ZWlzZWl0aWdlICRIX0EkKSAgDQogIA0KIyMjIFZvcmdlaGVuDQoNCjEuIFdpc3NlbnNjaGFmdGxpY2hlIEh5cG90aGVzZW4gZm9ybXVsaWVyZW4gICANCjIuIFB1bmt0c2Now6R0emVyIGJlcmVjaG5lbiAgIA0KMy4gQW5uYWhtZW4gcHLDvGZlbiAgIA0KICANCiAgKiBVbmFiaMOkbmdpZ2tlaXQgZGVyIEJlb2JhY2h0dW5nc2VpbmhlaXRlbiAgDQogICogUGFhcndlaXNlIERpZmZlcmVuemVuIHNpbmQgYW5uw6RoZXJuZCBub3JtYWx2ZXJ0ZWlsdC4gICANCiAgKiBTdGljaHByb2JlbnVtZmFuZyAkbiBcZ2VxIDEyJCBvZGVyIGdyw7Zzc2VyIGJlaSBzdGFyayBzY2hpZWZlbiBWZXJ0ZWlsdW5nZW4gIA0KICANCjQuIFN0aWNocHJvYmVudmVydGVpbHVuZyBza2l6emllcmVuLCBWZXJ3ZXJmdW5nc2JlcmVpY2ggZWluemVpY2huZW4gdW5kIFRlc3RzdGF0aXN0aWsgYmVyZWNobmVuICAgICANCiAgDQogICQkeiA9IFxmcmFje1xiYXJ7eH1fe1xEZWx0YX0gLSBcbXVfe1xEZWx0YX19e1NFX3tcYmFye3h9X3tcRGVsdGF9fX0kJA0KDQo1LiBMaWVndCAkeiQgaW0gVmVyd2VyZnVuZ3NiZXJlaWNoIHdpcmQgJEhfMCQgenUgR3Vuc3RlbiB2b24gJEhfQSQgenVyw7xja2dld2llc2VuLiAgDQo2LiBSZXN1bHRhdCBpbSBadXNhbW1lbmhhbmcgbWl0IGRlciBGcmFnZXN0ZWxsdW5nIGludGVycHJldGllcmVuLiAgDQoNCiMjIyBLb25maWRlbnppbnRlcnZhbGwgZsO8ciBnZXBhYXJ0ZSBEYXRlbiAgICANCg0KJCRDSV4qID0gXGJhcnt4fV97XERlbHRhfSBccG0geiogXHRpbWVzIFNFX3tcRGVsdGF9JCQNCiAgDQogICQkQ0leKiA9IFxiYXJ7eH1fe1xEZWx0YX0gXHBtIHpeKiBcdGltZXMgXGZyYWN7c197XERlbHRhfX17bn0kJA0KDQojIyBIeXBvdGhlc2VudGVzdCBmw7xyIHVuYWJow6RuZ2lnZSBNaXR0ZWx3ZXJ0ZSAgIA0KDQoqIHVuYWJow6RuZ2lnZSBEYXRlbjogICANCg0KICAqIFVudGVyc2NoaWVkbGljaGUgQmVvYmFjaHR1bmdzZWluaGVpdGVuLCB6LkIuIFZlcmdsZWljaCB2b24gendlaSBHcnVwcGVuDQogIA0KKiBQYXJhbWV0ZXI6ICRcbXVfMSAtIFxtdV8yJCwgei5CLiBEaWZmZXJlbnogZGVyIE1pdHRlbHdlcnRlIHZvbiB6d2VpIFBvcHVsYXRpb25lbiAgDQoqIFB1bmt0c2Now6R0emVyOiAkXGJhcnt4fV8xIC0gXGJhcnt4fV8yJCB6LkIuIERpZmZlcmVueiBkZXIgTWl0dGVsd2VydGUgdm9uIHp3ZWkgU3RpY2hwcm9iZW4gICAgDQoqIFRlc3RzdGF0aXN0aWs6ICR6JC1XZXJ0DQoqIEh5cG90aGVzZW46ICAgDQoNCiAgKiAkSF8wOiBcbXVfMSA9IFxtdV8yJCBiencuICRIXzA6IFxtdV8xIC0gXG11XzIgPSAwJCAgIA0KICAqICRIX0E6IFxtdV8xIFxuZXEgXG11XzIkIGJ6dy4gJEhfQTogXG11XzEgLSBcbXVfMiBcbmVxIDAkICh6d2Vpc2VpdGlnZSAkSF9BJCkgDQogIA0KIyMjIFZvcmdlaGVuICAgDQoNCjEuIFdpc3NlbnNjaGFmdGxpY2hlIEh5cG90aGVzZSBmb3JtdWxpZXJlbiAgICAgDQoyLiBQdW5rdHNjaMOkdHplciBiZXJlY2huZW4gICAgDQozLiBBbm5haG1lbiBwcsO8ZmVuICAgDQogIA0KICAqIFVuYWJow6RuZ2lna2VpdCBkZXIgQmVvYmFjaHR1bmdzZWluaGVpdGVuIGlubmVyaGFsYiB1bmQgendpc2NoZW4gZGVuIEdydXBwZW4gICANCiAgKiBTdGljaHByb2JlIHN0YW1tdCBhdXMgZWluZSBhbm7DpGhlcm5kIG5vcm1hbHZlcnRlaWx0ZW4gUG9wdWxhdGlvbi4gICANCiAgKiBTdGljaHByb2JlbnVtZmFuZyAkbl8xIFxnZXEgMzAkIHVuZCAkbl8yIFxnZXEgMzAkIG9kZXIgZ3LDtnNzZXIgYmVpIHN0YXJrIHNjaGllZmVuIFZlcnRlaWx1bmdlbiAgIA0KICANCjQuIFN0aWNocHJvYmVudmVydGVpbHVuZyBza2l6emllcmVuLCBWZXJ3ZXJmdW5nc2JlcmVpY2ggZWluemVpY2huZW4gdW5kIFRlc3RzdGF0aXN0aWsgYmVyZWNobmVuICAgIA0KDQokJHogPSBcZnJhY3soXGJhcnt4fV8xIC0gXGJhcnt4fV8yKS0oXG11XzEgLSBcbXVfMil9e1NFX3tcYmFye3h9XzEgLSBcYmFye3h9XzJ9fSQkDQoNCiQkU0Vfe1xiYXJ7eH1fMSAtIFxiYXJ7eH1fMn0gPSBcc3FydHtcZnJhY3tzXzFeMn17bl8xfStcZnJhY3tzXzJeMn17bl8yfX0kJA0KDQo1LiBMaWVndCAkeiQgaW0gVmVyd2VyZnVuZ3NiZXJlaWNoIHdpcmQgJEhfMCQgenUgR3Vuc3RlbiB2b24gJEhfQSQgenVyw7xja2dld2llc2VuLiAgDQo2LiBSZXN1bHRhdCBpbSBadXNhbW1lbmhhbmcgbWl0IGRlciBGcmFnZXN0ZWxsdW5nIGludGVycHJldGllcmVuLiAgDQoNCiMjIyBLb25maWRlbnppbnRlcnZhbGwgZsO8ciB1bmFiaMOkbmdpZ2UgRGF0ZW4gIA0KDQokJENJXiogPSAoXGJhcnt4fV8xIC0gXGJhcnt4fV8yKSBccG0gel4qIFx0aW1lcyBTRV97XGJhcnt4fV8xIC0gXGJhcnt4fV8yfSQkDQoNCjxici8+DQo8YnIvPg0KPGJyLz4NCg0KIyBULVZlcnRlaWx1bmcgdW5kIHQtVGVzdHMgICANCg0KRGllIFQtVmVydGVpbHVuZyAgIA0KDQoqIGthbm4gYWxzIFZhcmlhbnRlIGRlciBOb3JtYWx2ZXJ0ZWlsdW5nIGF1ZmdlZmFzc3Qgd2VyZGVuLiAgDQoqIGhhdCBpbW1lciBkZW4gTWl0dGVsd2VydCAwLiAgDQoqIGhhdCBlaW5lIFN0YW5kYXJkYWJ3ZWljaHVuZywgZGllIHZvbSBTdGljaHByb2JlbnVtZmFuZyAkbiQgYWJow6RuZ2lnIGlzdC4gICANCiogV2lyZCBudXIgZHVyY2ggZWluZW4gZWluemlnZW4gUGFyYW1ldGVyLCBkaWUgQW56YWhsIEZyZWloZWl0c2dyYWRlICRkZiQgKGVuZ2wuIGRlZ3JlZXMgb2YgZnJlZWRvbSksIGRlZmluaWVydC4gIA0KKiBEaWUgVC1WZXJ0ZWlsdW5nIHdpcmQgbWl0IHdhY2hzZW5kZW0gJG4kIHNjaG1hbGVyIHVuZCBnZWh0IGbDvHIgJG4gXHJpZ2h0YXJyb3cgXGluZnR5JCBpbiBkaWUgTm9ybWFsdmVydGVpbHVuZyDDvGJlci4gICANCg0KJCRkZiA9IG4tMSQkDQokJHQgXHNpbSBUKGRmKSQkDQoNCkRpZSBULXZlcnRlaWx1bmcgd2lyZCB2ZXJ3ZW5kZXQsIHdlbm4gICAgDQoNCiogZGVyIFN0aWNocHJvYmVudW1mYW5nIGtsZWluIGlzdCAoJG4gXGxlcSAzMCQpICAgIA0KKiBkaWUgU3RhbmRhcmRhYndlaWNodW5nICRcc2lnbWEkIGRlciBQb3B1bGF0aW9uIHVuYmVrYW5udCBpc3QgdW5kIG1pdCBIaWxmZSBkZXIgU3RpY2hwcm9iZW5zdGFuZGFyZGFid2VpY2h1bmcgJHMkIGdlc2Now6R0enQgd2VyZGVuIG11c3MuIA0KKiBhbHNvIGVpZ2VudGxpY2ggaW1tZXI7IGRpZSBTb2Z0d2FyZSByZWNobmV0IHN0YW5kYXJkbcOkc3NpZyBtaXQgZGVyIFQtVmVydGVpbHVuZy4gIA0KKiBEaWUgVGVzdHN0YXRpc3RpayB2b24gVC1UZXN0cyBzaW5kICR0JC1XZXJ0ZS4gJHQkLVdlcnRlIHdlcmRlbiBnbGVpY2ggaW50ZXJwcmV0aWVydCB3aWUgJHokLVdlcnRlLiAgDQoNCiMjIEluZmVyZW56IGbDvHIgZWluZW4gTWl0dGVsd2VydA0KDQpaaWVsOiBWZXJnbGVpY2ggZWluZXMgTWl0dGVsd2VydHMgbWl0IGVpbmVtIFZlcmdsZWljaHN3ZXJ0ICg9IE51bGx3ZXJ0KQ0KDQpIeXBvdGhlc2VuOiAgDQoNCiogJEhfMDogXG11ID0gTnVsbHdlcnQkICAgDQoqICRIX0E6IFxtdSBcbmVxIE51bGx3ZXJ0JCAoendlaXNlaXRpZykgIA0KDQoNCiMjIyBLb25maWRlbnppbnRlcnZhbGwNCg0KJCRDSV4qID0gXGJhcnt4fSBccG0gdF97ZGZ9XiogXHRpbWVzIFNFX3tcYmFye3h9fSQkDQoNCiQkU0Vfe1xiYXJ7eH19ID0gXGZyYWN7c317XHNxcnR7bn19LCB+fiBkZiA9IG4tMSQkDQoNClF1YW50aWxlbiBmw7xyIGRlbiBrcml0aXNjaGVuIHQtV2VydCAoR3JlbnplbiBkZXMgVmVyd2VyZnVuZ3NiZXJlaWNocykgdW5kIGbDvHIgZGllIEtvbnN0cnVrdGlvbiB2b24gS29uZmlkZW56aW50ZXJ2YWxsZW4gbWl0IGBSYGJlcmVjaG5lbjoNCg0KYGBge3IgcXQsIGV2YWw9RkFMU0UsIGVjaG89VFJVRX0NCiMgZsO8ciBTaWduaWZpa2Fuem5pdmVhdSAwLjA1LCA5NSUgQ0kNCnQgPC0gcXQoLjAyNSwgZGYgPSBuIC0gMSkgIA0KDQojIGbDvHIgU2lnbmlmaWthbnpuaXZlYXUgMC4xLCA5MCUgQ0kNCnQgPC0gcXQoMC4wNSwgZGYgPSBuIC0gMSkNCg0KIyBmw7xyIFNpZ25pZmlrYW56bml2ZWF1IDAuMDEsIDk5JSBDSQ0KdCA8LSBxdCgwLjAwNSwgZGYgPSBuIC0gMSkNCmBgYA0KDQpEaWUgYFJgLUZ1bmt0aW9uIGBxdCgpYCBnaWJ0IGRpZSB1bnRlcmUgR3JlbnplIGFuLiBEYSBkaWUgVC1WZXJ0ZWlsdW5nIHN5bW1ldHJpc2NoIGlzdCwgZW50c3ByaWNodCBkaWUgb2JlcmUgR3JlbnplIGRlbSBBYnNvbHV0d2VydCBkZXIgdW50ZXJlbiBHcmVuemUuDQoNCkJlaXNwaWVsIHp1ciBCZXJlY2hudW5nIGRlcyBLb25maWRlbnppbnRlcnZhbGxzIGluIGBSYCANCg0KYGBge3IsIGVjaG89VFJVRX0NCiMgS2VubnphaGxlbiBlaW5lciBTdGljaHByb2JlDQpuIDwtIDI1DQptIDwtIDE1DQpzIDwtIDMNCg0KDQpjaV9sZXZlbCA8LSAuOTUgICAgICAgICAgICAgICAgIyBLb25maWRlbnpuaXZlYXUNClNFIDwtIHMvc3FydChuKSAgICAgICAgICAgICAgICAjIFN0YW5kYXJkZmVobGVyICAgDQp0X2RmIDwtIHF0KC4wMjUsIGRmID0gMjUgLSAxKSAgIyBrcml0aXNjaGVyIHQtV2VydA0KDQpDSSA8LSBtICsgYygtMSwgMSkgKiBhYnModF9kZikgKiBTRQ0KQ0kNCmBgYA0KDQojIyMgRWluc3RpY2hwcm9iZW4tdC1UZXN0DQoNCiQkdCA9IFxmcmFje1xtdS1OdWxsd2VydH17U0V9JCQNCg0KQmVpc3BpZWw6IFZlcmdsZWljaCBkZXMgTWl0dGVsd2VydHMgZWluZXIgU3RpY2hwcm9iZSBtaXQgZGVtIE51bGx3ZXJ0IGluIGVpbmVyIFBvcHVsYXRpb24uIERlciBOdWxsd2VydCBzZWkgJE51bGx3ZXJ0ID0gMTMkDQoNCkh5cG90aGVzZW46ICANCg0KKiAkSF8wOiBcbXUgPSAxMyQgICANCiogJEhfQTogXG11IFxuZXEgMTMkICh6d2Vpc2VpdGlnKSAgDQoNCmBgYHtyIGVpbnNwLXQtdGVzdCwgZWNobz1UUlVFfQ0KIyBLZW5uemFobGVuIHVuc2VyZXIgU3RpY2hwcm9iZSB1bmQgTnVsbHdlcnQNCm4gPC0gMjUNCm0gPC0gMTUNCnMgPC0gMw0KbnVsbHdlcnQgPC0gMTMNCg0KU0UgPC0gcy9zcXJ0KG4pICAgICAgICAgICAgICAgICMgU3RhbmRhcmRmZWhsZXIgICANCnQgPC0gKG0gLSBudWxsd2VydCkvU0UgICAgICAgICAjIFRlc3RzdGF0aXN0aWsgDQoNCiMgcC1XZXJ0IGbDvHIgendlaXNzZWl0aWdlIEh5cG90aGVzZSBiZXJlY2huZW4NCnAgPC0gMiAqIHB0KGFicyh0KSwgZGYgPSBuIC0gMSwgbG93ZXIudGFpbCA9IEZBTFNFKQ0KDQojIG91dHB1dCB2b24gdCB1bmQgcA0KcGFzdGUoInQgPSIsIHQsICIsIHAgPSIsIHApDQpgYGANCg0KRWluZmFjaGVyIGdlaHQgZXMgbWl0IGRlciBGdW5rdGlvbiBgdC50ZXN0KClgDQoNCmBgYHtyIHQudGVzdCwgZWNobz1UUlVFfQ0KIyBEYXRlbiBzaW11bGllcmVuIChtdXNzIG1hbiBuaWNodCB2ZXJzdGVoZW4pDQpybm9ybTIgPC0gZnVuY3Rpb24obiwgbWVhbiwgc2QpIHsgbWVhbiArIHNkICogc2NhbGUocm5vcm0obikpIH0NCnggPC0gcm5vcm0yKG4gPSAyNSwgbWVhbiA9MTUsIHNkID0gMykNCg0KIyB0LVRlc3QgaW4gUg0KdC50ZXN0KHgsICMgU3RpY2hwcm9iZW5kYXRlbiBtaXQgbSA9IDE1LCBzID0gMywgbiA9IDI1DQogICAgICAgbXUgPSAxMywgIyBOdWxsd2VydA0KICAgICAgIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIpICMgendlaXNlaXRpZ2VyIFRlc3QNCmBgYA0KDQpEZXIgRWluc3RpY2hwcm9iZW4tdC1UZXN0IGVpZ25ldCBzaWNoIGF1Y2ggYWxzIFRlc3QgZsO8ciBnZXBhYXJ0ZSBEYXRlbiBtaXQgZGVyIFByw7xmZ3LDtnNzZSAkbXVfe1xEZWx0YX0kLg0KDQojIyBJbmZlcmVueiBmw7xyIHp3ZWkgTWl0dGVsd2VydGUNCg0KWmllbDogVmVyZ2xlaWNoIHZvbiB6d2VpIE1pdHRlbHdlcnRlbiBhdXMgendlaSBTdGljaHByb2Jlbg0KDQpIeXBvdGhlc2VuOiAgDQoNCiogJEhfMDogXG11XzEgPSBcbXVfMiQgICANCiogJEhfQTogXG11XzEgXG5lcSBcbXVfMiQgKHp3ZWlzZWl0aWcpICANCg0KIyMjIEtvbmZpZGVuemludGVydmFsbA0KDQokJENJXiogPSAoXGJhcnt4fV8xIC0gXGJhcnt4fV8yKSBccG0gdF97ZGZ9XiogXHRpbWVzIFNFX3tcYmFye3h9XzEgLSBcYmFye3h9XzJ9JCQgDQoNCiQkU0Vfe1xiYXJ7eH1fMSAtIFxiYXJ7eH1fMn0gPSBcc3FydHtcZnJhY3tzXzFeMn17bl8xfStcZnJhY3tzXzJeMn17bl8yfX0kJA0KDQokJGRmID0gbl8xICsgbl8yIC0gMiQkDQoNCkRpZSBGb3JtZWxuIGbDvHIgZGllIEJlcmVjaG51bmcgdm9uICRTRSQgdW5kICRkZiQgc2luZCBldHdhcyB2ZXJlaW5mYWNodDsgZ2VuYXVlIEZvcm1lbG4gZmluZGV0IG1hbiBpbiBTdGF0aXN0aWtsZWhyYsO8Y2hlcm4uICAgDQoNCiMjIyBad2Vpc3RpY2hwcm9iZW4tdC1UZXN0ICANCg0KJCR0ID0gXGZyYWN7KFxiYXJ7eH1fMSAtIFxiYXJ7eH1fMiktKFxtdV8xIC0gXG11XzIpfXtTRV97XGJhcnt4fV8xIC0gXGJhcnt4fV8yfX0kJA0KDQpgYGB7ciB6d2Vpc3AtdC10ZXN0LCBlY2hvPVRSVUV9DQojIEtlbm56YWhsZW4gdW5zZXJlciBTdGljaHByb2JlIHVuZCBOdWxsd2VydA0KbjEgPC0gMjUNCm0xIDwtIDE1DQpzMSA8LSAzDQpuMiA8LSAyMA0KbTIgPC0gMTgNCnMyIDwtIDQNCg0KIyBTdGFuZGFyZGZlaGxlciANClNFIDwtIHNxcnQoKHMxXjIgLyBuMSkgKyAoczJeMi9uMikpDQoNCiMgVGVzdHN0YXRpc3RpayAgDQp0IDwtIChtMSAtIG0yKS9TRSAgICAgDQoNCiMgRnJlaWhlaXRzZ3JhZGUgbjIgLSAxIGlzdCBrbGVpbmVyIGFscyBuMSAtIDENCmRmIDwtIG4xICsgbjIgLSAyDQoNCiMgcC1XZXJ0IGbDvHIgendlaXNzZWl0aWdlIEh5cG90aGVzZSBiZXJlY2huZW4NCnAgPC0gMiAqIHB0KGFicyh0KSwgZGYsIGxvd2VyLnRhaWwgPSBGQUxTRSkNCg0KIyBvdXRwdXQgdm9uIHQgdW5kIHANCnBhc3RlKCJ0ID0iLCB0LCAiLCBwID0iLCBwKQ0KYGBgDQoNCkVpbmZhY2hlciBnZWh0IGVzIG1pdCBkZXIgRnVua3Rpb24gYHQudGVzdCgpYA0KDQpgYGB7ciB0LnRlc3QyLCBlY2hvPVRSVUV9DQojIERhdGVuIHNpbXVsaWVyZW4gKG11c3MgbWFuIG5pY2h0IHZlcnN0ZWhlbikNCnJub3JtMiA8LSBmdW5jdGlvbihuLCBtZWFuLCBzZCkgeyBtZWFuICsgc2QgKiBzY2FsZShybm9ybShuKSkgfQ0KeDEgPC0gcm5vcm0yKG4gPSAyNSwgbWVhbiA9MTUsIHNkID0gMykNCngyIDwtIHJub3JtMihuID0gMjAsIG1lYW4gPTE4LCBzZCA9IDQpDQoNCiMgdC1UZXN0IGluIFINCnQudGVzdCh4ID0geDEsICMgR3J1cHBlIDENCiAgICAgICB5ID0geDIsICMgR3J1cHBlIDINCiAgICAgICBwYWlyZWQgPSBGQUxTRSwgDQogICAgICAgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIikjIHp3ZWlzZWl0aWdlciBUZXN0DQpgYGANCg0KPGJyLz4NCjxici8+DQo8YnIvPg0KDQojIE5pY2h0cGFyYW1ldHJpc2NoZSBUZXN0cw0KDQpOaWNodHBhcmFtZXRyaXNjaGUgVGVzdHMga29tbWVuIHp1ciBBbndlbmR1bmcsIHdlbm4gZGllIEFubmFobWUgZGVyIE5vcm1hbHZlcnRlaWx1bmcgZnJhZ2xpY2ggaXN0LiBGw7xyIGRpZSBBbndlbmR1bmcgdm9uIG5pY2h0cGFyYW1ldHJpc2NoZW4gVGVzdHMgaXN0IGVzIHVuZXJoZWJsaWNoLCBhdXMgd2VsY2hlciBBcnQgdm9uIFZlcnRlaWx1bmcgZGllIERhdGVuIHN0YW1tZW4uICAgDQoNCiMjIFZvcnplaWNoZW50ZXN0ICAgDQoNClJlZmVyZW56ZW46IEBLaW5nMjAxOSAgDQoNCkRlciBFaW5zdGljaHByb2Jlbi1UZXN0OiBWZXJnbGVpY2h0IGVpbmVuIE1lZGlhbiAoJFx0aWxkZXt4fSQpIG1pdCBlaW5lbSB2b3JnZWdlYmVuZW4gUmVmZXJlbnptZWRpYW4uICRIXzA6IFx0aWxkZXt4fSA9IE51bGx3ZXJ0JC4gUHLDvGZncsO2c3NlIHNpbmQgZGllIFN0aWNocHJvYmVuZGF0ZW4uICAgDQoNClZvcmdlaGVuOiAgIA0KDQoxLiBWZXJnbGVpY2hlIGplZGVuIFdlcnQgaW4gZGVyIFN0aWNocHJvYmUgbWl0IGRlbSBOdWxsd2VydC4gRsO8ciBXZXJ0ZSBkaWUgZ3LDtnNzZXIgYWxzDQpkZXIgTnVsbHdlcnQgc2luZCwgc2NocmVpYmUgZWluICQrJCwgZsO8ciBXZXJ0ZSBkaWUga2xlaW5lciBhbHMgZGVyIE51bGx3ZXJ0IHNpbmQsIHNjaHJlaWJlIGVpbiAkLSQuICAgDQoyLiBaw6RobGUgZGllIEFuemFobCAkKyQgdW5kICQtJC4gDQozLiBCZXJlY2huZSBhbmhhbmQgZGVyIFJlZ2VsbiBmw7xyIGRpZSBCaW5vbWlhbHZlcnRlaWx1bmcgZGllIFdhaHJzY2hlaW5saWNoa2VpdCBmw7xyIGRpZXNlcyBvZGVyIGVpbiBleHRyZW1lcmVzIFJlc3VsdGF0IHVudGVyIGRlciBBbm5haG1lLCBkYXNzIGRpZSBOdWxsaHlwb3RoZXNlIHp1dHJpZmZ0LiBEaWVzIGlzdCBhdWNoIHVuc2VyZSBUZXN0c3RhdGlzdGlrISANCg0KICAqIFdlbm4gJHAkIGRpZSBXYWhyc2NoZWlubGljaGtlaXQgZsO8ciBlaW5lbiBFcmZvbGcgaXN0LCBpc3QgJDEtcCQgZGllIFdhaHJzY2hlaW5saWNoa2VpdCBmw7xyIGVpbmVuIE1pc3NlcmZvbGcuICRuJCBnaWJ0IGRpZSBBbnphaGwgZGVyIFZlcnN1Y2hlIGFuIHVuZCAkayQgZGllIEFuemFobCBkZXIgRXJmb2xnZS4gICANCg0KJCRwKGssIG4pID0gIHtuIFxjaG9vc2Uga31wXmsoMS1wKV57bi1rfSQkDQo0LiBWZXJnbGVpY2hlIGRlbiBwLVdlcnQgbWl0IGRlbSBTaWduaWZpa2Fuem5pdmVhdS4gQmVhY2h0ZTogRsO8ciBlaW5lIHp3ZWlzZWl0aWdlICRIX0EkIG11c3MgZGVyIHAtV2VydCB2ZXJkb3BwZWx0IHdlcmRlbi4gICANCg0KIyMjIEJlaXNwaWVsICANCg0KSW4gZWluZXIgbmV1ZW4gUHJvZHVrdGlvbnNsaW5pZSBzb2xsIGRpZSBLb250YW1pbmF0aW9uIGVpbmVzIFByb2R1a3RzIG1pdCBTY2hhZHN0b2ZmZW4gDQp1bnRlciBlaW5lbSBHcmVuendlcnQgdm9uIDUwIEVpbmhlaXRlbiBsaWVnZW4uIEdlbWVzc2VuIHd1cmRlIGRpZSBLb250YW1pbmF0aW9uIGFuIGVpbmVyIFN0aWNocHJvYmUgJG4kID0gMTAuDQoNCiRIXzA6IFx0aWxkZXt4fSA9IDUwJCwgZGVyIE1lZGlhbiBkZXIgU3RpY2hwcm9iZSBpc3QgNTAgICAgICANCiRIX0E6IFx0aWxkZXt4fSA8IDUwJCwgZGVyIE1lZGlhbiBkZXIgU3RpY2hwcm9iZSBpc3Qga2xlaW5lciBhbHMgNTAgICANCg0KYGBge3IsIGVjaG89VFJVRX0NCiMjIEtvbnRhbWluYXRpb25zZGF0ZW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpjb250YW1pbmF0aW9uIDwtIHRpYmJsZSgNCiAgdmFsdWUgPSBjKDQ1LjM0NCwgNDguNjU1LCAzNi4xOTksIDU0Ljg4MSwgNDkuMjg3LCANCiAgICAgICAgICAgIDQ5LjMzNiwgNTMuNDkyLCA0MC43MDIsIDQ2LjMxOCwgMzEuMzAzKQ0KKQ0KDQpudWxsdmFsdWUgPC0gNTANCg0KIyMgRGlmZmVyZW56IHp1bSBOdWxsd2VydCBwbHVzIG9kZXIgbWludXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmNvbnRhbWluYXRpb24gPC0gY29udGFtaW5hdGlvbiAlPiUgDQogIG11dGF0ZSgNCiAgICBkaWZmID0gdmFsdWUgLSBudWxsdmFsdWUsDQogICAgc2lnbiA9IGlmX2Vsc2UoZGlmZiA+PSAwLCAicGx1cyIsICJtaW51cyIpDQogICkNCmNvbnRhbWluYXRpb24gJT4lIA0KICBrYmwoKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFKQ0KDQojIyBTdW1tZSBkZXIgcG9zaXRpdmVuIHVuZCBuZWdhdGl2ZW4gRGlmZmVyZW56ZW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KY29udGFtaW5hdGlvbiAlPiUgDQogIGdyb3VwX2J5KHNpZ24pICU+JSANCiAgc3VtbWFyaXNlKA0KICAgIG4gPSBuKCkNCiAgKSAlPiUgDQogIGtibCgpICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UpDQoNCiMjIFdpZSBncm9zcyBpc3QgZGllIFdhaHJzY2hlaW5saWNoa2VpdCA4IG9kZXIgbWVociBuZWdhdGl2ZSBhdXMgMTAgenUgemllaGVuICANCnAuV2VydCA8LSBkYmlub20oOCwgMTAsIC41KSArIGRiaW5vbSg5LCAxMCwgLjUpICsgZGJpbm9tKDEwLCAxMCwgLjUpDQoNCg0KIyMgVGFiZWxsZSBmw7xyIFJlc3VsdGF0IGVyc3RlbGxlbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpjb250LnJlc3VsdCA8LSB0aWJibGUoDQogIE5yLnN1Y2Nlc3NlcyA9IDgsDQogIE5yLnRyaWFscyA9IDEwLCANCiAgcC5IMCA9IC41LA0KICBwLlZhbHVlID0gcm91bmQocC5XZXJ0LCA0KQ0KKQ0KY29udC5yZXN1bHQgJT4lIA0KICBrYmwoY2FwdGlvbiA9ICJWb3J6ZWljaGVudGVzdCIpICU+JSANCiAga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRkFMU0UpDQoNCiMgRWluZmFjaGVyIGdlaHQgZXMgbWl0IFIgDQpiaW5vbS50ZXN0KDgsIDEwLCAuNSwgYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciIpDQpgYGANCg0KSW50ZXJwcmV0YXRpb246IERlciBrcml0aXNjaGUgV2VydCBmw7xyIHVuc2VyZSBUZXN0c3RhdGlzdGlrIGlzdCBkYXMgU2lnbmlmaWthbnpuaXZlYXUgJFxhbHBoYSQuIElzdCBkZXIgJHAtV2VydCQgZ3LDtnNzZXIgYWxzICRcYWxwaGEkLCBoYWJlbiB3aXIga2VpbmUgRXZpZGVueiBkYWbDvHIsIGRhc3Mgd2lyIGRpZSBOdWxsaHlwb3RoZXNlIHZlcndlcmZlbiBrw7ZubmVuLiBFcyBsaWVndCBuaWNodCBhdXNyZWljaGVuZCBFdmlkZW56IGRhZsO8ciB2b3IsIGRhc3MgZGVyIE1lZGlhbiBkZXIgS29udGFtaW5hdGlvbiBzaWduaWZpa2FudCB0aWVmZXIgaXN0LCBhbHMgZGVyIHZvcmdlZ2ViZW5lIEdyZW56d2VydC4gICAgDQoNCiMjIEJlaXNwaWVsIDINCg0KRGVyIFZvcnplaWNoZW50ZXN0IGthbm4gYXVjaCBhbHMgV2lsY294b24gVm9yemVpY2hlbnJhbmd0ZXN0IG1pdCBkZW0gUGFyYW1ldGVyIGBtdSA9IG51bGx2YWx1ZWAgZHVyY2hnZWbDvGhydCB3ZXJkZW4uIERhcyBSZXN1bHRhdCBpc3QgYW5uw6RoZXJuZCBkYXMgc2VsYmUuDQoNCmBgYHtyLCBlY2hvPVRSVUUsIGV2YWw9RkFMU0V9DQp3aWxjb3gudGVzdCh4LCBtdSA9IFJlZmVyZW56d2VydCkNCmBgYA0KDQpCZWlzcGllbDogIA0KDQpgYGB7ciwgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KIyBXaWxjb3hvbi1Wb3J6ZWljaGVucmFuZ3Rlc3QNCndpbGNveC50ZXN0KHggPSBjb250YW1pbmF0aW9uJHZhbHVlLCBtdSA9IG51bGx2YWx1ZSwgYWx0ZXJuYXRpdmUgPSAibGVzcyIpDQpgYGANCg0KPGJyLz4NCjxici8+DQoNCiMjIFdpbGNveG9uLVZvcnplaWNoZW5yYW5ndGVzdCAgICANCg0KUXVlbGxlbjogQExlb25oYXJ0MjAxMywgQFJlYWxzdGF0ICANCg0KDQpXaWxjb3hvbiBWb3J6ZWljaGVucmFuZy1UZXN0IGbDvHIgZ2VwYWFydGUgRGF0ZW46ICRIXzA6IFx0aWxkZXt4fV97XERlbHRhfSA9IDAkLCBQcsO8Zmdyw7Zzc2UgDQokXHRpbGRle3h9X3tcRGVsdGF9JCA9IFBhYXJ3ZWlzZSBEaWZmZXJlbnplbiBTdGljaHByb2JlIEIgbWludXMgU3RpY2hwcm9iZSBBLiAgIA0KDQpBbm5haG1lbjogIA0KDQoqIHF1YW50aXRhdGl2ZSBvZGVyIG9yZGluYWwgc2thbGllcnRlIERhdGVuICAgDQoqIHVuYWJow6RuZ2lnZSBCZW9iYWNodHVuZ3NlaW5oZWl0ZW4gICANCiogRGF0ZW4gc2luZCBhbm7DpGhlcm5kIHN5bW1ldHJpc2NoIHVtIGRlbiBNZWRpYW4gdmVydGVpbHQuICAgDQoNClZvcmdlaGVuOg0KDQoxLiBQYWFyd2Vpc2UgRGlmZmVyZW56ZW4gbmFjaCBHcsO2c3NlIHNvcnRpZXJlbi4gRGllIFZvcnplaWNoZW4gd2VyZGVuIGbDvHIgZGllIFJhbmdiaWxkdW5nIGlnbm9yaWVydCwgZGFzIFZvcnplaWNoZW4gd2lyZCBub3RpZXJ0LiAgDQoyLiBSYW5nc3VtbWVuIGbDvHIgcG9zaXRpdmUgdW5kIG5lZ2F0aXZlIERpZmZlcmVuemVuIGJpbGRlbi4gIA0KDQokJFRfKyA9IFxzdW0gUsOkbmdlIH5taXQgfnBvc2l0aXZlbSB+Vm9yemVpY2hlbiQkIA0KDQokJFRfLSA9IFxzdW0gUsOkbmdlIH5taXQgfm5lZ2F0aXZlbSB+Vm9yemVpY2hlbiQkIA0KDQozLiBEaWUgVGVzdHN0YXRpc3RpayAkVCQgaXN0IGRpZSBrbGVpbmVyZSBkZXIgYmVpZGVuIFJhbmdzdW1tZW4uICAgDQo0LiBLcml0aXNjaGVuIFdlcnQgJFRfe2tyaXR9JCBpbiBbVm9yemVpY2hlbi1SYW5nLVRhYmVsbGVdKGh0dHBzOi8vd3d3LnJlYWwtc3RhdGlzdGljcy5jb20vc3RhdGlzdGljcy10YWJsZXMvd2lsY294b24tc2lnbmVkLXJhbmtzLXRhYmxlLykgbmFjaHNjaGxhZ2VuLiBXZW5uICRUIDwgVF97a3JpdH0kIHdpcmQgJEhfMCQgdmVyd29yZmVuLiAgIA0KDQoqKk5vcm1hbGFwcHJveGltYXRpb24qKiAgICAgDQoNCiogRsO8ciBncsO2c3NlcmUgU3RpY2hwcm9iZW4gKEZhdXN0cmVnZWw6ICRuID4gMjUkLCBqZSBuYWNoIEF1dG9yIGV0d2FzIGFuZGVyZSBBbmdhYmVuKSBpc3QgJFQkIGFubsOkaGVybmQgbm9ybWFsdmVydGVpbHQuICANCg0KJCRFKFQpID0gXG11ID0gXGZyYWN7biBcdGltZXMgKG4gKyAxKX17NH0kJA0KDQokJFxzaWdtYV4yID0gXGZyYWN7biBcdGltZXMgKG4gKyAxKSBcdGltZXMgKDJuICsgMSl9ezI0fSQkDQoNCioqS29ycmVrdHVyIGbDvHIgQmluZHVuZ2VuKioNCg0KV2VubiBtZWhyZXJlIEJpbmR1bmdlbiB2b3JsaWVnZW4sIGlzdCBlaW4gYmVzc2VyZXIgU2Now6R0emVyIGbDvHIgZGllIFZhcmlhbnogICANCg0KJCRcc2lnbWFeMiA9IFxmcmFje24gXHRpbWVzIChuICsgMSkgXHRpbWVzICgybiArIDEpfXsyNH0gLSBcZnJhY3sxfXs0OH0gXHN1bV90KGZfdF4zIC0gZl90KSQkDQoNCndvYmVpOg0KDQoqICR0JCA9IEFuemFobCBTZXRzIHZvbiBCaW5kdW5nZW4gICANCiogJGZfdCQgPSBIw6R1Zmlna2VpdCB2b24gUmFuZyAkdCQgDQogIA0KKipLb250aW51aXTDpHRzLUtvcnJla3R1cioqICAgDQoNCkRpZSBBcHByb3hpbWF0aW9uIGVpbmVyIGRpc2tyZXRlbiBWZXJ0ZWlsdW5nIG1pdHRlbHMgZWluZXIga29udGludWllcmxpY2hlbiBWZXJ0ZWlsdW5nIGthbm4gZHVyY2ggZWluZSBLb250aW51aXTDpHRza29ycmVrdHVyIGJlaSBkZXIgQmVyZWNobnVuZyB2b24gJHokIGJlcsO8Y2tzaWNodGlndCB3ZXJkZW46ICANCg0KJCR6ID0gXGZyYWN7fFUgLSBcbXV8LS41fXtcc2lnbWF9JCQNCg0KIyMjIEJlaXNwaWVsDQoNClp1ciDDnGJlcnByw7xmdW5nIGVpbmVyIG5ldWVuIFVudGVycmljaHRzbWV0aG9kZSB3dXJkZSBpbiBlaW5lciBhYmjDpG5naWdlbiBTdGljaHByb2JlIHZvciB1bmQgbmFjaCBlaW5lbSBTb21tZXJsYWdlciBkaWUgTGVpc3R1bmcgaW0gRmFjaCBTdGF0c2l0aWsgZXJob2Jlbi4gV8OkaHJlbmQgZGVzIEZlcmllbmF1ZmVudGhhbHRzIGZhbmQgZWluIGludGVncmllcnRlciBOYWNoaGlsZmVrdXJzIGluIFN0YXRpc3RpayBzdGF0dC4gRGllIE1lc3N1bmcgZGVyIFN0YXRzaXRpa2xlaXN0dW5nIGVyZ2FiIGZvbGdlbmRlIFdlcnRlOg0KDQpgYGB7ciwgZWNobz1UUlVFfQ0KIyMgUHLDvGZlcmdlYm5pc3NlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMgbGlicmFyeShkcGx5cikNCnByZmcgPC0gdGliYmxlKA0KICBJRCA9IHNlcShmcm9tID0gMSwgdG8gPSAxMCwgYnkgPSAxKSwNCiAgdm9yaGVyID0gYygyMiwgMjYsIDEyLCAyMCwgMjIsIDI2LCAyMiwgMjQsIDQwLCA0MCksDQogIG5hY2hoZXIgPSBjKDQwLCAyMiwgMjgsIDMwLCAxNiwgMzgsIDI0LCAzMiwgMjAsIDI2KQ0KKQ0KDQojIyBQYWFyd2Vpc2UgRGlmZmVyZW56ZW4gYmVyZWNobmVuIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KcHJmZyA8LSBwcmZnICU+JSANCiAgbXV0YXRlKA0KICAgIGRpZmYgPSBuYWNoaGVyIC0gdm9yaGVyDQogICkNCg0KIyMgTmFjaCBSw6RuZ2VuIHNvcnRpZXJlbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpwcmZnIDwtIHByZmcgJT4lIA0KICBtdXRhdGUoDQogICAgcmFuZyA9IHJhbmsoYWJzKGRpZmYpKQ0KICApDQoNCiMjIFJhbmdzdW1tZW4gZsO8ciBUIGJlcmVjaG5lbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KVC5wbHVzIDwtIHByZmcgJT4lIA0KICBmaWx0ZXIoZGlmZiA+IDApICU+JSANCiAgc3VtbWFyaXNlKA0KICAgIHZhbHVlID0gc3VtKHJhbmcpDQogICkNCg0KVC5taW51cyA8LSBwcmZnICU+JSANCiAgZmlsdGVyKGRpZmYgPCAwKSAlPiUgDQogIHN1bW1hcmlzZSgNCiAgICB2YWx1ZSA9IHN1bShyYW5nKQ0KICApDQoNCiMjIFRlc3RncsO2c3NlIGlzdCBkYXMga2xlaW5lcmUgVCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KVCA8LSBtaW4oVC5wbHVzJHZhbHVlLCBULm1pbnVzJHZhbHVlKQ0KDQojIyBwLVdlcnQgYmVyZWNobmVuIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KcCA8LSAyICogcHNpZ25yYW5rKFQsIG4gPSBsZW5ndGgocHJmZyRkaWZmKSkNCg0KIyMgVGFiZWxsZSBmw7xyIE91dHB1dCBlcnN0ZWxsZW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpwcmZnLnJlc3VsdCA8LSB0aWJibGUoDQogIFQucGx1cyA9IFQucGx1cyR2YWx1ZSwNCiAgVC5taW51cyA9IFQubWludXMkdmFsdWUsDQogIFQgPSBULA0KICBULmtyaXQgPSA4LA0KICBwLldlcnQgPSBwDQopDQoNCiMjIFRhYmVsbGUgYW56ZWlnZW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGxpYnJhcnkoa25pdHIpDQojIGxpYnJhcnkoa2FibGVFeHRyYSkNCg0KcHJmZy5yZXN1bHQgJT4lIA0KICBrYmwoZGlnaXRzID0gMywgY2FwdGlvbiA9ICJXaWxjb3hvbiBWb3J6ZWljaGVucmFuZ3Rlc3QiKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFKQ0KDQojIyDDnGJlcnByw7xmdW5nIG1pdCB3aWxjb3gudGVzdCgpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQp3aWxjb3gudGVzdChwcmZnJHZvcmhlciwgcHJmZyRuYWNoaGVyLCBwYWlyZWQgPSBUUlVFLCBjb3JyZWN0ID0gRkFMU0UpDQpgYGANCg0KQW5tZXJrdW5nZW4gIA0KDQoqIEVzIHdpcmQgaW0gQmVpc3BpZWwga2VpbmUgS29udGludWl0w6R0c2tvcnJla3R1ciBvZGVyIGVpbmUgS29ycmVrdHVyIGbDvHIgQmluZHVuZ2VuIHZlcndlbmRldC4gIA0KKiAkVC5rcml0JCB3dXJkZSBtYW51ZWxsIGRlciBXaWxjb3hvbiBWb3J6ZWljaGVucmFuZy1UYWJlbGxlIGVudG5vbW1lbiAoJG4kID0gMTApLiAgIA0KKiBEZXIgcC1XZXJ0IHd1cmRlIG1pdCBkZXIgRnVua3Rpb24gYHBzaWducmFuayhULCBuID0gbilgIGJlcmVjaG5ldC4gIA0KKiBEZXIgYmVyZWNobmV0ZSBULVdlcnQgbXVzcyBnbGVpY2ggb2RlciBrbGVpbmVyIGFscyBkZXIga3JpdGlzY2hlIFQtV2VydCBzZWluLCBkYW1pdCBlaW4gc2lnbmlmaWthbnRlciBVbnRlcnNjaGllZCBiZWxlZ3Qgd2VyZGVuIGthbm4uICANCiogSW4gYFJgIHdpcmQgJFQkIGFscyAkViQgYW5nZWdlYmVuLiAgICANCg0KSW50ZXJwcmV0YXRpb246ICpEZXIgYmVvYmFjaHRldGUgVC1XZXJ0IHVudGVyc2NocmVpdGV0IGRlbiBrcml0aXNjaGVuIFQtV2VydCBuaWNodCwgc29taXQgaXN0IGRlciBVbnRlcnNjaGllZCB6d2lzY2hlbiBkZW4gVGVzdHplaXRwdW5rdGVuIG5pY2h0IHNpZ25pZmlrYW50IHVuZCBkZXIgU29tbWVya3VycyBoYXQga2VpbmVuIEVmZmVrdCBhdWYgZGllIExlaXN0dW5nIGRlciBTY2jDvGxlcjppbm5lbiBpbiBTdGF0aXN0aWsuKiANCg0KDQoNCiMjIE1hbm4tV2hpdG5leS1VLVRlc3QNCg0KUmVmZXJlbno6IEBLaW5nMjAxOSANCg0KV2lyZCBhdWNoICpXaWxjb3hvbiBSYW5nc3VtbWVuLVRlc3QqIGdlbmFubnQuICAgDQoNClRlc3RldCBuaWNodCBnYW56IGRhc3NlbGJlIHdpZSBkZXIgdC1UZXN0ICAgDQoNCiogJEhfMDogUChYID4gWSkgPSBQKFkgPiBYKSQsIG0uYS5XOiBFcyBiZXN0ZWh0IGVpbmUgNTAlLVdhaHJzY2hlaW5saWNoa2VpdCBkYWbDvHIsIGRhc3MgZWluIHp1ZsOkbGxpZyBnZXpvZ2VuZXIgV2VydCBhdXMgJFgkIGdyw7Zzc2VyIGlzdCBhbHMgZWluIHp1ZsOkbGxpZyBnZXpvZ2VuZXIgTWl0dGVsd2VydCBhdXMgJFkkICh1bmQgdW1nZWtlaHJ0KSAgDQoqICAkSF8wOiBQKFggPiBZKSBcbmVxIFAoWSA+IFgpJCwgbS5hLlc6IERpZSBXYWhyc2NoZWlubGljaGtlaXQgaXN0IG5pY2h0IDUwJSwgZGFzcyBlaW4genVmw6RsbGlnIGdlem9nZW5lciBXZXJ0IGF1cyAkWCQgZ3LDtnNzZXIgaXN0IGFscyBlaW4genVmw6RsbGlnIGdlem9nZW5lciBNaXR0ZWx3ZXJ0IGF1cyAkWSQgKHVuZCB1bWdla2VocnQpICANCiAgDQpBbm5haG1lbiAgDQoNCiogcXVhbnRpYXRpdmUgb2RlciBvcmRpbmFsIHNrYWxpZXJ0ZSBEYXRlbiAgIA0KKiB1bmFiaMOkbmdpZ2UgQmVvYmFjaHR1bmdlbiAgDQoNCklkZWU6IERpZSBXZXJ0ZSBiZWlkZXIgU3RpY2hwcm9iZW4gd2VyZGVuIGluIGVpbmVyIGVpbnppZ2UgUmFuZ29yZG51bmcgc29ydGllcnQuIEbDvHIgJEhfMCQgd2lyZCBlcndhcnRldCwgZGFzcyAkeCA8IHkkIGdsZWljaCBow6R1ZmlnIGlzdCB3aWUgJHkgPCB4JC4gICANCg0KVGVzdHN0YXRpc3RpayAgIA0KICAgKiBVIG1pc3N0LCB3aWUgb2Z0IGVpbiB5LVdlcnQga2xlaW5lciBpc3QgYWxzIGVpbiB4LVdlcnQuIERlZmluaXRpb246DQogICAqIHdlbm4gJHkgPCB4LCB6ID0gMSQgIA0KICAgKiB3ZW5uICR4IDwgeSwgeiA9IDAkDQogICAqICRVID0gXHN1bXt6fSQNCiAgIA0KKiBCZXJlY2hudW5nIHZvbiBVOiAgDQoNCiQkDQpVID0gbl8xIFx0aW1lcyBuXzIgKyBcZnJhY3tuXzEobl8xICsgMSl9ezJ9IC0gVF8xDQokJA0KDQoqICRUXzEkID0gU3VtbWUgZGVyIFLDpG5nZSB2b24gU3RpY2hwcm9iZSAxICAgDQoqICRVJyA9IChuXzEgXHRpbWVzIG5fMikgLSBVID0gXHN1bXsoeCA8IHkpfSQNCg0KRsO8ciBncm9zc2UgU3RpY2hwcm9iZW51bWbDpG5nZSAoJG5fMSQgb2RlciAkbl8yJCA+IDEwKSBpc3QgJFUkIGFubsOkaGVybmQgbm9ybWFsIHZlcnRlaWx0IG1pdDoNCg0KJCQNCkUoVSkgPSBcbXUgPSBcZnJhY3tuXzEgXHRpbWVzIG5fMn17Mn0NCiQkDQoNCnVuZA0KDQokJA0KXHNpZ21hX1VeMiA9IFxmcmFje25fMSBcdGltZXMgbl8yIFx0aW1lcyAobl8xICsgbl8yICsgMSl9ezEyfQ0KJCQNCg0KVGVzdHN0YXRpc3RpazoNCg0KJCQNCnogPSBcZnJhY3tVIC0gRShVKX17XHNpZ21hX1V9DQokJA0KDQpXZW5uIGdlYnVuZGVuZSBSw6RuZ2Ugdm9ybGllZ2VuICh6d2VpIFdlcnRlIGluIGVpbmVyIFNwYWx0ZSBiZWxlZ2VuIGRlbiBzZWxiZW4gUmFuZyksIHdpcmQgZGllIFN0YW5kYXJkYWJ3ZWljaHVuZyB2b24gJFUkIHdpZSBmb2xndCBrb3JyaWdpZXJ0Og0KDQokJA0KXHNpZ21hX3tVQ29ycn0gPSBcc3FydHtcZnJhY3tuXzEgXHRpbWVzIG5fMn17bihuLTEpfX0gXHRpbWVzIFxzcXJ0e1xmcmFje25eMy1ufXsxMn0tXHN1bV97aT0xfV5rXGZyYWN7dF9pXjMtdF9pfXsxMn19DQokJA0KDQp3b2JlaQ0KDQoqICRuID0gbl8xICsgbl8yJCAgIA0KKiAkdF9pJCA9IEFuemFobCBlaW56ZWxuZXIgV2VydGUsIHdlbGNoZSBkZW4gUmFuZyAkaSQgdGVpbGVuLiAgDQoqICRrJCA9IEFuemFobCBnZWJ1bmRlbmUgUsOkbmdlDQoNCiMjIyBpbiBSDQogIA0KYGBge3IsIGVjaG89VFJVRSwgZXZhbD1GQUxTRX0NCndpbGNveC50ZXN0KHgsIHksIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIsIHBhaXJlZCA9IEZBTFNFKQ0KYGBgDQoNCkJlaXNwaWVsOg0KDQpgYGB7ciwgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFfQ0KIyBEYXRlbiBnZW5lcmllcmVuDQpYIDwtIGMoMywgMywgNCwgNSwgNiwgNywgNywgOCwgMSwgMikNClkgPC0gYygyLCAzLCAyLCA1LCA2LCAyLCAzLCA4LCAxLCAyKQ0KDQojIE1hbm4tV2hpdG5leS1VLVRlc3QNCndpbGNveC50ZXN0KHggPSBYLCB5ID0gWSwgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIiwgcGFpcmVkID0gRkFMU0UpDQpgYGANCg0KKipCZWFjaHRlOioqIGBSYCBiZXJlY2huZXQgZGllIFRlc3RzdGF0aXN0aWsgZXR3YXMgYW5kZXJzOiBEaWUgRnVua3Rpb24gYHdpbGNveC50ZXN0KClgIGJlcmVjaG5ldCB6d2FyIGRpZSBUZXN0c3RhdGlzdGlrICRXJCB3aWUgb2JlbiBhbmdlZ2ViZW4sIHppZWh0IGRhbm4gamVkb2NoICRcZnJhY3tuXzEgKG5fMSArIDEpfXsyfSQgZGF2b24gYWIgW0BIdWdoZXMyMDEyXS4gDQoNCjxici8+DQo8YnIvPg0KPGJyLz4NCg0KIyBWYXJpYW56YW5hbHlzZSwgQU5PVkEgDQoNCiogQU5PVkEgc3RlaHQgZsO8ciBWYXJpYW56YW5hbHlzZSAoZW5nbC4gQW5hbHlzaXMgb2YgVmFyaWFuY2UpIHVuZCB3aXJkIHZlcndlbmRldCB1bSBkaWUgTWl0dGVsd2VydGUgdm9uIG1laHIgYWxzIDIgR3J1cHBlbiB6dSB2ZXJnbGVpY2hlbi4gIA0KDQojIyBIeXBvdGhlc2VuICAgDQoNCiogJEhfMDogXG11XzEgPSBcbXVfMiAuLi4gPSBcbXVfbiQgICANCiogJEhfQTogRGllIH5NaXR0ZWx3ZXJ0ZSB+c2luZCB+bmljaHQgfmFsbGUgfmdsZWljaCQgDQoNCiMjIFF1YWRyYXRzdW1tZW56ZXJsZWd1bmcgIA0KDQoqIEJlaSBkZXIgVmFyaWFuemFuYWx5c2Ugd2lyZCBkaWUgIkdlc2FtdHZhcmlhbnoiIGRlciBhYmjDpG5naWdlbiBWYXJpYWJsZW4gJHkkIGluIGRpZSBWYXJpYW56IHp3aXNjaGVuIGRlbiBHcnVwcGVubWl0dGVsd2VydGVuIHVuZCBkaWUgVmFyaWFueiB6d2lzY2hlbiBkZW4gTWVzc3dlcnRlbiBpbm5lcmhhbGIgZGVyIEdydXBwZW4gemVybGVndC4gICANCg0KJCRTU197dG90YWx9PVNTX3tiZXR3ZWVufSArIFNTX3t3aXRoaW59JCQNCg0KKiBEaWUgKipHZXNhbXRxdWFkcmF0c3VtbWUqKiAkU1Nfe3RvdGFsfSQgbWlzc3QgZGllIHRvdGFsZSBWYXJpYWJpbGl0w6R0IGRlciBhYmjDpG5naWdlbiBWYXJpYWJsZW4uICANCg0KDQokJFNTX3t0b3RhbH0gPSBcc3VtX3tpPTF9Xm4oeV9pLVxiYXJ7eX0pXjIkJA0KDQogICAqICR5X2k6JCBXZXJ0IGRlciBhYmjDpG5naWdlbiBWYXJpYWJsZW4gZsO8ciBqZWRlIEJlb2JhY2h0dW5nICAgDQogICAqICRcYmFye3l9OiQgTWl0dGVsd2VydCBkZXIgYWJow6RuZ2lnZW4gVmFyaWFibGVuIChzb2cuICpncmFuZCBtZWFuKikgICANCg0KKiBEaWUgKipRdWFkcmF0c3VtbWUgendpc2NoZW4gZGVuIEdydXBwZW4qKiBtaXNzdCBkaWUgVmFyaWFiaWxpdMOkdCB6d2lzY2hlbiBkZW4gR3J1cHBlbjsgZW50c3ByaWNodCBkZXIgVmFyaWFiaWxpdMOkdCwgZGllIGR1cmNoIGRpZSBHcnVwcGllcnVuZ3N2YXJpYWJsZSBlcmtsw6RydCB3aXJkIChlcmtsw6RydGUgVmFyaWFiaWxpdMOkdCkuICAgICANCg0KJCRTU197YmV0d2Vlbn0gPSBcc3VtX3tqPTF9Xmsgbl9qKFxiYXJ7eX1faS1cYmFye3l9KV4yJCQNCg0KICAgKiAkbl9qOiQgQW56YWhsIEJlb2JhY2h0dW5nZW4gaW4gR3J1cHBlICRqJCAgDQogICAqICRcYmFye3l9X2o6JCBNaXR0ZWx3ZXJ0IGRlciBhYmjDpG5naWdlbiBWYXJpYWJsZW4gaW4gR3J1cHBlICRqJCAgIA0KICAgKiAkXGJhcnt5fTokIE1pdHRlbHdlcnQgZGVyIGFiaMOkbmdpZ2VuIFZhcmlhYmxlbiAoKmdyYW5kIG1lYW4qKSAgIA0KICAgDQoqIERpZSAqKlF1YWRyYXRzdW1tZSBpbm5lcmhhbGIgZGVyIEdydXBwZW4qKiBtaXNzdCBkaWUgVmFyaWFiaWxpdMOkdCBpbm5lcmhhbGIgZGVyIGVpbnplbG5lbiBHcnVwcGVuOyBlbnRzcHJpY2h0IGRlciBWYXJpYWJpbGl0w6R0LCBkaWUgbmljaHQgZHVyY2ggZGllIEdydXBwaWVydW5nc3ZhcmlhYmxlIGJlc2NocmllYmVuIHdpcmQsIGFsc28gYW5kZXJlIEdyw7xuZGUgaGF0ICh1bmVya2zDpHJ0ZSBWYXJpYWJpbGl0w6R0KSANCg0KJCRTU197d2l0aGlufSA9IFNTX3t0b3RhbH0tU1Nfe2JldHdlZW59JCQNCg0KKiBGcmVpaGVpdHNncmFkZSBmw7xyIEFOT1ZBDQoNCiAgICogVG90YWw6ICRkZl97dG90YX0gPSBuLTEkDQogICAqIGbDvHIgU1Nfe2JldHdlZW59OiAkZGZfe2JldHdlZW59ID0gay0xJCAgIA0KICAgKiBmw7xyIFNTX3t3aXRoaW59OiAkZGZfe3dpdGhpbn0gPSBkZl97dG90YWx9LWRme2JldHdlZW59JCAgIA0KICAgDQoqIERpZSAqKm1pdHRsZXJlbiBRdWFkcmF0c3VtbWVuKiogYmVzY2hyZWliZW4gZGllIGR1cmNoc2Nobml0dGxpY2hlIFZhcmlhYmlsaXTDpHQgendpc2NoZW4gdW5kIGlubmVyaGFsYiBkZXIgR3J1cHBlbi4gICANCg0KJCRNU1Nfe2JldHdlZW59ID0gU1Nfe2JldHdlZW59L2RmX3tiZXR3ZWVufSQkICANCg0KJCRNU1Nfe3dpdGhpbn0gPSBTU197d2l0aGlufS9kZl97d2l0aGlufSQkICANCg0KKiBUZXN0c3RhdGlzdGlrICRGJCAgIA0KDQokJEYgPSBcZnJhY3tNU1Nfe2JldHdlZW59fXtNU1Nfe3dpdGhpbn19JCQNCg0KKiAkcCQtV2VydA0KDQogICAqIGdpYnQgZGllIFdhaHJzY2hlaW5saWNoa2VpdCBlaW5lIHNvIGdyb3NzZSBvZGVyIG5vY2ggZ3LDtnNzZXJlIFRlc3RzdGF0aXN0aWsgJEYkIHVudGVyIGRlciBBbm5haG1lLCBkYXNzIGRpZSBNaXR0ZWx3ZXJ0ZSBhbGxlciBHcnVwcGVuIGdsZWljaCBncm9zcyBzaW5kLiAgIA0KICAgKiBpc3QgZGllIEZsw6RjaGUgdW50ZXIgZGVyIEt1cnZlIGRlciAkRiQtVmVydGVpbHVuZyBtaXQgZGVuIEZyZWloZWl0c2dyYWRlbiAkZGZfe2JldHdlZW59JCB1bmQgJGRmX3t3aXRoaW59JCBvYmVyaGFsYiBkZXMgJEYkLVdlcnRzLiAgIA0KICAgDQogICAqIGluIGBSYCANCiAgIA0KYGBge3IsIGVjaG89VFJVRSwgZXZhbD1GQUxTRX0NCnBmKEYsIGRmX2JldHdlZW4sIGRmX3dpdGhpbiwgbG93ZXIudGFpbCA9IEZBTFNFKQ0KYGBgDQogICANCg0KIyMgQmVkaW5ndW5nZW4gZsO8ciBBTk9WQSAgIA0KDQoqIFVuYWJow6RuZ2lna2VpdCBkZXIgTWVzc3VuZ2VuICAgDQoNCiAgICogendpc2NoZW4gZGVuIEdydXBwZW46IERpZSBHcnVwcGVuIG3DvHNzZW4gdm9uZWluYW5kZXIgdW5hYmjDpG5naWcgc2VpbiwgYW5kZXJuZmFsbHMgaXN0IGVpbmUgQU5PVkEgZsO8ciBNZXNzd2llZGVyaG9sdW5nZW4gKHJlcGVhdGVkIG1lYXN1cmVzIGFub3ZhKSBkdXJjaHp1ZsO8aHJlbi4gICANCiAgICogaW5uZXJoYWxiIGRlciBHcnVwcGVuOiBEaWUgQmVvYmFjaHR1bmdzZWluaGVpdGVuIG3DvHNzZW4gdW5hYmjDpG5naWcgdm9uZWluYW5kZXIgc2Vpbi4gICANCiAgIA0KKiBOb3JtYWx2ZXJ0ZWlsdW5nOiBEaWUgRGF0ZW4gaW5uZXJoYWxiIGplZGVyIEdydXBwZSBzb2xsdGVuIGFubsOkaGVybmQgbm9ybWFsdmVydGVpbHQgc2Vpbi4gIA0KKiBEaWUgR3J1cHBlbiBzb2xsdGVuIGFubsOkaGVybmQgZ2xlaWNoZSBWYXJpYW56ZW4gaGFiZW4uICAgDQoNCiMjIFBvc3QtSG9jIHBhYXJ3ZWlzZSBWZXJnbGVpY2hlICAgDQoNCiogRGFzIFNpZ25pZmlrYW56bml2ZWF1IG11c3MgZsO8ciBkaWUgQW56YWhsIGRlciBWZXJnbGVpY2hlIGFuZ2VwYXNzdCB3ZXJkZW4uIEVzIGV4aXN0aWVyZW4gdmVyc2NoaWVkZW5lIFZlcmZhaHJlbi4gQW0gZWluZmFjaHN0ZW4gaXN0IGRpZSAqKkJvbmZlcnJvbmktS29ycmVrdHVyKiouIFZlcmdsZWljaGUgZGVuICRwJC1XZXJ0IGbDvHIgamVkZW4gVGVzdCBtaXQgZGVtIFNpZ25pZmlrYW56bml2ZWF1ICRcYWxwaGFeKiQuDQoNCiQkXGFscGhhXiogPSBcZnJhY3tcYWxwaGF9e0t9JCQNCg0KJCRLID0gQW56YWhsIH5WZXJnbGVpY2hlID0gXGZyYWN7ayhrLTEpfXsyfSQkDQoNCiogU3RhbmRhcmRmZWhsZXIgZsO8ciBtZWhyZXJlIHBhYXJ3ZWlzZSBWZXJnbGVpY2hlICANCg0KJCRTRSA9IFxzcXJ0e1xmcmFje01TU197d2l0aGlufX17bl8xfStcZnJhY3tNU1Nfe3dpdGhpbn19e25fMn19JCQNCg0KKiBUZXN0c3RhdGlzdGlrICR0JCAgIA0KDQokJHQgPSBcZnJhY3soXGJhcnt4fV8xIC0gXGJhcnt4fV8yKSAtIChcbXVfMS1cbXVfMil9e1xzcXJ0e1xmcmFje01TU197d2l0aGlufX17bl8xfStcZnJhY3tNU1Nfe3dpdGhpbn19e25fMn19fSQkDQoNCmBgYHtyLCBlY2hvPVRSVUUsIGV2YWw9RkFMU0V9DQojIHAtV2VydCBmw7xyIHp3ZWlzZWl0aWdlbiB0LVRlc3QNCjIgKiBwdCh0LVdlcnQsIGRmLCBsb3dlci50YWlsID0gRkFMU0UpDQpgYGANCg0KQmVpc3BpZWwNCg0KYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89VFJVRX0NCmxpYnJhcnkoZHBseXIpDQoNCiMgY3JlYXRlIHNhbXBsZSBkYXRhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpkYXRhIDwtIHRpYmJsZSgNCiAgZ3J1cHBlID0gYyhyZXAoIkcxIiwgNyksIHJlcCgiRzIiLCA3KSwgcmVwKCJHMyIsIDcpKSwNCiAgc2NvcmUgPSBjKDkyLCA5MywgMTAwLCAxMDQsIDg5LCA5MSwgOTksIDcxLCA2MiwgODUsIDk0LCA3OCwgNjYsIDcxLCA2NCwgNzMsIDg3LCA5MSwgNTYsIDc4LCA4NykNCikNCg0KIyBjcmVhdGUgYW5vdmEgc3VtbWFyeSB0YWJsZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmFub3ZhIDwtIGFvdihzY29yZSB+IGdydXBwZSwgZGF0YSA9IGRhdGEpDQpzdW1tYXJ5KGFub3ZhKQ0KDQojIHBvc3QgaG9jIGFuYWx5c2lzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KcGFpcndpc2UudC50ZXN0KGRhdGEkc2NvcmUsIGRhdGEkZ3J1cHBlLCANCiAgICAgICAgICAgICAgICBwLmFkanVzdC5tZXRob2QgPSAiYm9uZmVycm9uaSIsIA0KICAgICAgICAgICAgICAgIHBhaXJlZCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIpDQoNCiMgOTUlLUtvbmZpZGVuemludGVydmFsbGUgZsO8ciBEaWZmZXJlbnplbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KVHVrZXlIU0QoYW5vdmEpDQpwbG90KFR1a2V5SFNEKGFub3ZhKSkNCmBgYA0KDQo8YnIvPg0KPGJyLz4NCjxici8+DQoNCiMgSW5mZXJlbnogZsO8ciBxdWFsaXRhdGl2ZSBEYXRlbiAgDQoNCiogJHA6JCBQb3B1bGF0aW9uc3BhcmFtZXRlciAgIA0KKiAkXGhhdHtwfTokIFB1bmt0c2Now6R0emVyIGbDvHIgZGVuIFBvcHVsYXRpb25zcGFyYW1ldGVyIChBbnphaGwgRXJmb2xnZS9TdGljaHByb2JlbnVtZmFuZykgIA0KDQojIyBaZW50cmFsZXIgR3Jlbnp3ZXJ0c2F0eiBmw7xyIHJlbGF0aXZlIEjDpHVmaWdrZWl0ZW4gKGVuZ2wuICpwcm9wb3J0aW9ucyopIA0KDQoqIFJlbGF0aXZlIEjDpHVmaWdrZWl0ZW4gdm9uIFN0aWNocHJvYmVuIHNpbmQgYW5uw6RoZXJuZCBub3JtYWx2ZXJ0ZWlsdCBtaXQgaWhyZW0gWmVudHJ1bSBiZWkgZGVyIEjDpHVmaWdrZWl0IGluIGRlciBQb3B1bGF0aW9uIHVuZCBlaW5lbSBTdGFuZGFyZGZlaGxlciwgZGVyIHVtZ2VrZWhydCBwcm9wb3J0aW9uYWwgaXN0IHp1bSBTdGljaHByb2JlbnVtZmFuZy4gICANCg0KJCRcaGF0e3B9IFxzaW0gTiBcbGdyb3VwIE1pdHRlbHdlcnQgPSBwLCBTRSA9IFxzcXJ0e1xmcmFje3AoMS1wKX17bn19IFxyZ3JvdXAkJA0KDQoqIFZvcmF1c3NldHp1bmdlbiAgIA0KICAgKiBVbmFiaMOkbmdpZ2tlaXQ6IERpZSBCZW9iYWNodHVuZ2VuIG3DvHNzZW4gdm9uZWluYW5kZXIgdW5hYmjDpG5naWcgc2VpbiAgIA0KICAgKiBTdGljaHByb2JlbnVtZmFuZzogRXMgbcO8c3NlbiBtaW5kZXN0ZW5zIDEwIEVyZm9sZ2UgdW5kIDEwIE1pc3NlcmZvbGdlIHZvcmxpZWdlbiAgDQogICANCiAgICQkbiBcdGltZXMgcCBcZ2VxIDEwOyB+biBcdGltZXMgKDEtcCkgXGdlcSAxMCQkDQoNCiMjIyBCZWlzcGllbA0KDQoqIEJlcmVjaG5lIGRpZSBXYWhyc2NoZWlubGljaGtlaXQgJFAoXGhhdHtwfSA+IDAuOTUpJCBmw7xyIGVpbiBFcmVpZ25pcyBtaXQgZGVyIEVyZm9sZ3N3YWhyc2NoZWlubGljaGtlaXQgJHAkID0gMC45IHVuZCBlaW5lbiBTdGljaHByb2JlbnVtZmFuZyAkbiQgPSAyMDAuIA0KDQoxLiBWb3JhdXNzZXR6dW5nZW4gcHLDvGZlbg0KDQpgYGB7cn0NCnAgPC0gMC45DQpuIDwtIDIwMA0KDQpuICogcCAgICAgICAjIEFuemFobCBFcmZvbGdlDQpuICogKDEgLSBwKSAjIEFuemFobCBNaXNzZXJmb2xnZQ0KYGBgDQoNCjIuIE5vcm1hbHZlcnRlaWx1bmdzYXBwcm94aW1hdGlvbiAgIA0KDQoqIE1pdHRlbHdlcnQgdW5kIFNFIGJlcmVjaG5lbiANCg0KJCRcaGF0e3B9IFxzaW0gTiBcbGdyb3VwIE1pdHRlbHdlcnQgPSAwLjksIFNFID0gXHNxcnR7XGZyYWN7MC45IFx0aW1lcyAwLjF9ezIwMH19ID0gMC4wMjEyIFxyZ3JvdXAkJA0KDQoqICR6JC1XZXJ0IGJlcmVjaG5lbiAgIA0KDQokJHogPSBcZnJhY3swLjk1IC0gMC45fXswLjAyMTJ9ID0gMi4zNiQkDQoNCiogJHAkLVdlcnQgYmVyZWNobmVuICAgDQoNCiQkUChaID4gMi4zNikgXGFwcHJveCAwLjAwOTEkJA0KDQoqIFVudGVyIFZlcndlbmR1bmcgZGVyIEJpbm9taWFsdmVydGVpbHVuZyAgIA0KDQogICAqIERpZSBlcndhcnRldGUgV2FocnNjaGVpbmxpY2hrZWl0IGJlaSAyMDAgVmVyc3VjaGVuIG1pdCAkcCQgPSAwLjk1IGlzdCAkXGhhdHtwfSA9IDIwMCBcdGltZXMgMC45NSA9IDE5MCQgICANCiAgICogV2llIGdyb3NzIGlzdCBkaWUgV2FocnNjaGVpbmxpY2hrZWl0IGbDvHIgJHAgXGdlcSAxOTAkIGJlaSAyMDAgU3RpY2hwcm9iZW4gdW5kIGVpbmVyIFdhaHJzY2hlaW5saWNoa2VpdCB2b24gJHAkID0gMC45IGluIGRlciBQb3B1bGF0aW9uIHVudGVyIGRlciBOdWxsaHlwb3RoZXNlPw0KDQpgYGB7ciwgZWNobyA9IFRSVUV9DQojIFdhaHJzY2hlaW5saWNoa2VpdCBmw7xyIDE5MCBvZGVyIG1laHIgRXJmb2xnZQ0KDQpzdW0oZGJpbm9tKDE5MCA6IDIwMCwgc2l6ZSA9IDIwMCwgcHJvYiA9IC45KSkNCmBgYA0KDQoNCiMjIEtvbmZpZGVuemludGVydmFsbCBmw7xyIGVpbmUgcmVsYXRpdmUgSMOkdWZpZ2tlaXQgIA0KDQojIyMgVm9yZ2VoZW4gICANCg0KMS4gVm9yYXVzc2V0enVuZ2VuIHByw7xmZW46IERpZSBCZW9iYWNodHVuZ2VuIHNpbmQgdW5hYmjDpG5naWcsICRcaGF0e3B9IG4gXGdlcSAxMCQgdW5kICQoMS1caGF0e3B9KW4gXGdlcSAxMCQgKEJlYWNodGU6IFdpciB2ZXJ3ZW5kZW4gaGllciBkZW4gU2Now6R0emVyIGbDvHIgJHAkISkgICANCjIuIFdlbm4gZGllIFZvcmF1c3NldHp1bmdlbiBlcmbDvGxsdCBzaW5kLCBpc3QgZsO8ciBkaWUgU3RpY2hwcm9iZW52ZXJ0ZWlsdW5nIHZvbiAkXGhhdHtwfSQgbsOkaGVydW5nc3dlaXNlIGRhcyBOb3JtYWx2ZXJ0ZWlsdW5nIGfDvGx0aWcuICAgDQozLiBTdGFuZGFyZGZlaGxlciAkU0UkIG1pdCAkXGhhdHtwfSQgYW5zdGVsbGUgdm9uICRwJCBiZXJlY2huZW4gbWl0IGRlciBGb3JtZWwgICANCg0KJCRTRV97XGhhdHtwfX0gPSBcc3FydHtcZnJhY3tcaGF0e3B9KDEtXGhhdHtwfSl9e259fSQkDQoNCjQuIEtvbmZpZGVuemludGVydmFsbCBiZXJlY2huZW4NCg0KJCRcaGF0e3B9IFxwbSB6IFx0aW1lcyBTRV97XGhhdHtwfX0kJA0KDQoqICR6JCA9IDEuOTYgZsO8ciBlaW4gOTUlLUtvbmZpZGVuemludGVydmFsbA0KDQo8YnIvPg0KDQojIyBIeXBvdGhlc2VudGVzdCBmw7xyIGVpbmUgU3RpY2hwcm9iZSAgIA0KDQojIyMgVm9yZ2VoZW4NCg0KMS4gSHlwb3RoZXNlbiBmb3JtdWxpZXJlbjogICANCg0KICAqICRIXzA6IHAgPSBOdWxsd2VydCQgICANCiAgKiAkSF9BOiBwIDwgb2RlciA+IG9kZXIgXG5lcSBOdWxsd2VydCQgIA0KICANCjIuIFB1bmt0c2Now6R0emVyICRcaGF0e3B9JCBiZXJlY2huZW4uICAgDQozLiBWb3JhdXNzZXR6dW5nZW4gcHLDvGZlbiAgDQoNCiAgKiBCZW9iYWNodHVuZ2VuIG3DvHNzZW4gdW5hYmjDpG5naWcgc2Vpbi4gIA0KICAqICRucCBcZ2VxIDEwJCB1bmQgJG4ocC0xKSBcZ2VxIDEwJCAoaGllciAkcCQgYXVzIGRlciBOdWxsaHlwb3RoZXNlIGVpbnNldHplbiEpICANCiAgDQo0LiBUZXN0c3RhdGlzdGlrICR6JCBiZXJlY2huZW4gICANCg0KJCR6ID0gXGZyYWN7XGhhdHtwfS1wfXtTRX0gPSBcZnJhY3tcaGF0e3B9LXB9e1xzcXJ0e1xmcmFje3AoMS1wKX17bn19fSQkDQoNCjUuIEVudHNjaGVpZGUgdW5kIGludGVycHJldGllcmUgaW0gS29udGV4dCBkZXIgRm9yc2NodW5nc2ZyYWdlICAgDQoNCiAgIGEpIFZlcndlcmZlICRIXzAkLCB3ZW5uICRwIFxsZXEgXGFscGhhJDsgZGllIERhdGVuIGxpZWZlcm4gRXZpZGVueiBnZWdlbiAkSF8wJC4gICANCiAgIGIpIFZlcndlcmZlICRIXzAkIG5pY2h0LCB3ZW5uICRwID4gXGFscGhhJDsgZGllIERhdGVuIGxpZWZlcm4ga2VpbmUgRXZpZGVueiBnZWdlbiAkSF8wJC4gICAgDQoNCiAgIA0KIyMjICRcaGF0e3B9JCB2ZXJzdXMgJHAkICAgDQoNCiogQmVyZWNobnVuZyBlaW5lcyBLb25maWRlbnppbnRlcnZhbGxzOiAkcCQgaXN0IHVuYmVrYW5udCB1bmQgd2lyIHNldHplbiBkZW4gYmVzdGVuIFNjaMOkdHplciAkXGhhdHtwfSQgZWluLiAgIA0KDQokJG5caGF0e3B9IFxnZXEgMTA7IH5uKDEtXGhhdHtwfSkgXGdlcSAxMCQkDQoNCiQkU0Vfe1xoYXR7cH19ID0gXHNxcnR7XGZyYWN7XGhhdHtwfSgxLVxoYXR7cH0pfXtufX0kJA0KDQoqIEh5cG90aGVzZW50ZXN0OiBXaXIgdGVzdGVuIGdlZ2VuIGRpZSBOdWxsaHlwb3RoZXNlIHVuZCBzZXR6ZW4gJHAkIGF1cyAkSF8wJCBlaW4uDQoNCiQkbnAgXGdlcSAxMDsgfm4oMS1wKSBcZ2VxIDEwJCQNCg0KJCRTRSA9IFxzcXJ0e1xmcmFje3AoMS1wKX17bn19JCQNCg0KIyMjIEJlaXNwaWVsDQoNCiogSW4gZWluZXIgU3RpY2hwcm9iZSB2b24gMTAwIFNjaMO8bGVyOmlubmVuIGVpbmVyIFNjaHVsZSBzaW5kIDIwIFJhdWNoZXI6aW5uZW4uICANCg0KJCRuID0gMTAwLCB+XGhhdHtwfSA9IDIwLzEwMCA9IDAuMjAkJA0KDQoqIEtvbmZpZGVuemludGVydmFsbCBiZXJlY2huZW4gICANCg0KJCRDSSA9IFxoYXR7cH0gXHBtIHogXHRpbWVzIFNFJCQNCg0KJCRDSSA9IFxoYXR7cH0gXHBtIHogXHRpbWVzIFxzcXJ0e1xmcmFje1xoYXR7cH0oMS1caGF0e3B9KX17bn19JCQNCg0KJCRDSV97OTV9ID0gMC4yMCBccG0gMS45NiBcdGltZXMgXHNxcnR7XGZyYWN7MC4yMCBcdGltZXMgMC44MH17MTAwfX0gJCQNCg0KJCRDSV97OTV9ID0gMC4yMCBccG0gMS45NiBcdGltZXMgMC4wNCBcYXBwcm94IFswLjEyLCB+MC4yOF0kJA0KDQoqICpJbnRlcnByZXRhdGlvbjogV2lyIGvDtm5uZW4genUgOTUlIGRhcmF1ZiB2ZXJ0cmF1ZW4sIGRhc3MgYW4gZGllc2VyIFNjaHVsZSB6d2lzY2hlbiAxMiUgdW5kIDI4JSBkZXIgU2Now7xsZXI6aW5uZW4gcmF1Y2hlbi4qDQoNCjxici8+DQoNCiogSHlwb3RoZXNlbnRlc3QNCg0KICAgKiBGcmFnZTogVW50ZXJzY2hlaWRldCBzaWNoIGRlciB3YWhyZSBBbnRlaWwgYW4gU2Now7xsZXI6aW5uZW4sIGRpZSBhbiBkaWVzZXIgU2NodWxlIHJhdWNoZW4gdm9uIDE4JT8NCiAgICogJEhfMDogcCA9IDE4JCAgIA0KICAgKiAkSF9BOiBwIFxuZXEgMTgkICAgDQogICANCiQkeiA9IFxmcmFje1xoYXR7cH0tcF8wfXtTRX0gPSBcZnJhY3tcaGF0e3B9LXBfMH17XHNxcnQoXGZyYWN7cF8wKDEtcF8wKX17bn0pfSQkDQoNCiQkeiA9IFxmcmFjezAuMjAtMC4xOH17XHNxcnR7XGZyYWN7MC4xOCgxLTAuMTgpfXsxMDB9fX0gPSBcZnJhY3swLjAyfXswLjAzODR9ID0gMC41MiQkDQogICANCmBgYHtyLCBlY2hvPVRSVUV9DQoyICogcG5vcm0oMC41MiwgbG93ZXIudGFpbCA9IEZBTFNFKQ0KYGBgDQogICANCiogKkludGVycHJldGF0aW9uOiAkcC1XZXJ0ID4gXGFscGhhJCwgd2lyIGhhYmVuIGtlaW5lIEV2aWRlbnogZ2VnZW4gZGllICRIXzAkLCBkaWUgYmVzYWd0LCBkYXNzIGRlciB3YWhyZSBBbnRlaWwgYW4gUmF1Y2hlcjppbm5lbiAxOCUgYmV0csOkZ3QuIERhcyBFcmdlYm5pcyBkZXMgSHlwb3RoZXNlbnRlc3RzIHN0aW1tdCBtaXQgZGVtIGJlcmVjaG5ldGVuIEtvbmZpZGVuemludGVydmFsbCB2b24gWzAuMTIsIDAuMjhdIMO8YmVyZWluLCBkYXMgZGVuIFdlcnQgMC4xOCBlbnRow6RsdC4qICAgICAgDQo8YnIvPg0KDQojIyBWZXJnbGVpY2ggdm9uIHp3ZWkgcmVsYXRpdmVuIEjDpHVmaWdrZWl0ZW4NCg0KKiBBbndlbmR1bmcgZGVzIHplbnRyYWxlbiBHcmVuendlcnRzYXR6ZXMgICANCg0KJCQoXGhhdHtwfV8xLVxoYXR7cH1fMikgXHNpbSBOIFxsZ3JvdXAgTWl0dGVsd2VydCA9IChwXzEtcF8yKSwgU0UgPSBcc3FydHtcZnJhY3twXzEoMS1wXzEpfXtuXzF9K1xmcmFje3BfMigxLXBfMil9e25fMn19IFxyZ3JvdXAkJA0KDQoqIFdpciB2ZXJnbGVpY2hlbiBkaWUgWmFobGVuIGRlciBTY2h1bGUgbWl0IGVpbmVyIHp3ZWl0ZW4gU2NodWxlOiBEb3J0IHd1cmRlIGVpbmUgWnVmYWxsc3N0aWNocHJvYmUgdm9uIDEyMCBTY2jDvGxlcjppbm5lbiBlcmhvYmVuLCB3b3ZvbiAzMCBSYXVjaGVyOmlubmVuIHdhcmVuLiAgIA0KDQokJG5fMSA9IDEwMCwgXGhhdHtwfV8xID0gMjAvMTAwID0gMC4yMCQkDQoNCiQkbl8yID0gMTIwLCBcaGF0e3B9XzIgPSAzMC8xMjAgPSAwLjI1JCQNCg0KJCRDSSA9IChcaGF0e3B9XzEgLSBcaGF0e3B9XzIpIFxwbSB6IFx0aW1lcyBcc3FydHtcZnJhY3tcaGF0e3B9XzEoMS1caGF0e3B9XzEpfXtuXzF9K1xmcmFje1xoYXR7cH1fMigxLVxoYXR7cH1fMil9e25fMn19JCQNCg0KJCRDSSA9ICgwLjIwLTAuMjUpIFxwbSB6IFx0aW1lcyBcc3FydHtcZnJhY3swLjIwIFx0aW1lcyAwLjgwfXsxMDB9K1xmcmFjezAuMjUgXHRpbWVzIDAuNzV9ezEyMH19JCQNCg0KJCRDSV97OTV9ID0gLTAuMDUgXHBtIDEuOTYgXHRpbWVzIDAuMDU2MiBcYXBwcm94IFstMC4xNiwgfjAuMDZdJCQNCg0KKiAqSW50ZXJwcmV0YXRpb246IFdpciBrw7ZubmVuIHp1IDk1JSBkYXJhdWYgdmVydHJhdWVuLCBkYXNzIGRlciB3YWhyZSBBbnRlaWwgYW4gUmF1Y2hlcjppbm5lbiBpbiBTY2h1bGUgMSB1bSAtMTYlIHRpZWZlciBiaXMgNiUgaMO2aGVyIGlzdCBhbHMgYW4gU2NodWxlIDIuKiAgIA0KDQo8YnIvPg0KDQoqIEh5cG90aGVzZW50ZXN0ICAgDQoNCiAgICogRnJhZ2U6IFVudGVyc2NoZWlkZW4gc2ljaCBkaWUgQW50ZWlsZSBhbiBSYXVjaGVyOmlubmVuIHp3aXNjaGVuIGRlbiBiZWlkZW4gU2NodWxlbj8gIA0KICAgKiAkSF8wOiBwXzEgPSBwXzIkICANCiAgICogJEhfQTogcF8xIFxuZXEgcF8yJCAgIA0KICAgDQokJHogPSBcZnJhY3soXGhhdHtwfV8xLVxoYXR7cH1fMiktKHBfMS1wXzIpfXtcc3FydHtcZnJhY3tcaGF0e3B9X3twb29sfSgxLVxoYXR7cH1fe3Bvb2x9KX17bl8xfSArIFxmcmFje1xoYXR7cH1fe3Bvb2x9KDEtXGhhdHtwfV97cG9vbH0pfXtuXzJ9fX0kJA0KDQokJFxoYXR7cH1fe3Bvb2x9ID0gXGZyYWN7QW56YWhsIH5FcmZvbGdlfXtBbnphaGwgfkbDpGxsZX0gPSBcZnJhY3syMCszMH17MTAwKzEyMH0gXGFwcHJveCAwLjIzJCQNCg0KJCR6ID0gXGZyYWN7KDAuMjAtMC4yNSktMH17XHNxcnR7XGZyYWN7MC4yMyBcdGltZXMgMC43N317MTAwfSArIFxmcmFjezAuMjMgXHRpbWVzIDAuNzd9ezEyMH19fSA9IFxmcmFjey0wLjA1fXswLjA1N30gPSAtMC44OCQkDQoNCmBgYHtyLCBlY2hvPVRSVUV9DQoyICogcG5vcm0oMC44OCwgbG93ZXIudGFpbCA9IEZBTFNFKQ0KYGBgDQoNCiogKkludGVycHJldGF0aW9uOiAkcC1XZXJ0ID4gXGFscGhhJDsgd2lyIGhhYmVuIGtlaW5lIEV2aWRlbnogZ2VnZW4gZGllICRIXzAkLCBkaWUgYmVzYWd0LCBkYXNzIGVzIGtlaW5lbiBVbnRlcnNjaGllZCB6d2lzY2hlbiBkZW4gYmVpZGVuIFNjaHVsZW4gYmV6w7xnbGljaCBkZXIgQW50ZWlsZSBhbiBSYXVjaGVyOmlubmVuIGdpYnQuIERhcyA5NSUtS29uZmlkZW56aW50ZXJ2YWxsIHVudGVyc3TDvHR6dCBkaWVzZXMgRXJnZWJuaXMsIGRhIGVzIE51bGwgZW50aMOkbHQuKg0KDQo8YnIvPg0KPGJyLz4NCjxici8+DQoNCiMjIENoaS1RdWFkcmF0LVRlc3QNCg0KYXVjaCAqQ2hpLVF1YWRyYXQtQW5wYXNzdW5nc3Rlc3QqIG9kZXIgKkNoaS1RdWFkcmF0LVVuYWJow6RuZ2lna2VpdHN0ZXN0KiAgIA0KVW50ZXJzdWNodCwgb2IgZWluZSBadXNhbW1lbmhhbmcgendpc2NoZW4gendlaSBub21pbmFsIG9kZXIgb3JkaW5hbCBza2FsaWVydGVuIFZhcmlhYmxlbiBiZXN0ZWh0Lg0KSHlwb3RoZXNlbjogICANCg0KKiAkSF8wOiQgRGllIFplaWxlbi0gdW5kIFNwYWx0ZW52YXJpYWJsZW4gc2luZCB2b25laW5laW5hbmRlciB1bmFiaMOkbmdpZy4gIA0KKiAkSF9BOiQgRGllIFplaWxlbi0gdW5kIFNwYWx0ZW52YXJpYWJsZW4gc2luZCBow6RuZ2VuIHZvbmVpbmFuZGVyIGFiLiAgIA0KICANCkbDvHIgamVkZSBaZWxsZSBkZXIgVGFiZWxsZSBtdXNzIGRlciBlcndhcnRldGUgV2VydCAkRSQgdW50ZXIgZGVyIE51bGxoeXBvdGhlc2UgYmVyZWNobmV0IHdlcmRlbi4gICAgDQoNCiQkRSA9IFxmcmFje1NwYWx0ZW50b3RhbH5cdGltZXN+WmVpbGVudG90YWx9e0dlc2FtdHRvdGFsfSQkDQoNCiRcY2hpXjIkLVRlc3RzdGF0aXN0aWsgDQoNCiQkXGNoaV4yID0gXHN1bV97aT0xfV5rIFxmcmFjeyhPLUUpXjJ9e0V9JCQNCg0KKiAkTzokIGJlb2JhY2h0ZXRlIGFic29sdXRlIEjDpHVmaWdrZWl0ZW4gICANCiogJEU6JCBlcndhcnRldGUgYWJzb2x1dGUgSMOkdWZpZ2tlaXRlbiAgIA0KKiAkazokIEFuemFobCBaZWxsZW4gICANCg0KDQpEaWUgJFxjaGleMiQtVmVydGVpbHVuZyBoYXQgbnVyIGVpbmVuIFBhcmFtdGVyOiAkZGYkICAgDQoNCiQkZGYgPSAoUi0xKSBcdGltZXMgKEMtMSkkJCAgDQoNCiogJFI6JCBBbnphaGwgWmVpbGVuICAgDQoqICRDOiQgQW56YWhsIFNwYWx0ZW4gICANCg0KKipNZXJrZToqKiBEZXIgJFxjaGleMiQtVGVzdCBkYXJmIG51ciBkdXJjaGdlZsO8aHJ0IHdlcmRlbiwgd2VubiBkaWUgZXJ3YXJ0ZXRlIEjDpHVmaWdrZWl0IGluIGplZGVyIFplbGxlIG1pbmRlc3RlbnMgNSBiZXRyw6RndC4gQW5kZXJuZmFsbHMgKkZpc2hlcidzIGV4YWt0ZW4gVGVzdCogZHVyY2hmw7xocmVuLiANCg0KRGVyICRcY2hpXjIkLVRlc3Qga2FubiBpbiBgUmAgZWluZmFjaCBtaXQgZGVyIEZ1bmt0aW9uIGBjaGlzcS50ZXN0KClgIGR1cmNoZ2Vmw7xocnQgd2VyZGVuLiAgIA0KDQpEZXIga3JpdGlzY2hlIFdlcnQgZsO8ciAkXGNoaV4yJCBrYW5uIGluIGVpbmVyIFZlcnRlaWx1bmdzdGFiZWxsZSBhYmdlbGVzZW4gd2VyZGVuLiBCZWkgZWluZXIgVmllcmZlbGRlcnRhZmVsICgyIFplaWxlbiB1bmQgMiBTcGFsdGVuKSBpc3QgZGVyIFp1c2FtbWVuaGFuZyB6d2lzY2hlbiBkZXIgWmVpbGVuLSB1bmQgZGVyIEtvbG9ubmVudmFyaWFibGUgc3RhdGlzdGlzY2ggc2lnbmlmaWthbnQgYXVmIGRlbSBOaXZlYXUgdm9uIDUlIHdlbm4gJFxjaGleMiQgZ3LDtnNzZXIgYWxzICQzLjg0fiAoPTEuOTZeMikkIGlzdC4gIA0KDQpGdW5rdGlvbiBpbiBgUmANCg0KYGBge3IsIGVjaG89VFJVRSwgZXZhbD1GQUxTRX0NCmNoaXNxLnRlc3QoKQ0KYGBgDQoNCkJlaXNwaWVsOiBVbnRlcnN1Y2h0IHd1cmRlIGJlaSAxMDAgU2Now7xsZXI6aW5uZW4sIG9iIHNpZSBUaWN0b2MgdmVyd2VuZGVuLg0KDQpgYGB7cn0NCiMgQmVpc3BpZWxhdGVuIGdlbmVyaWVyZW4NCnRpY3RvY19tIDwtIGMocmVwKCJqYSIsIDIzKSwgcmVwKCJuZWluIiwgMjkpKQ0KdGljdG9jX3cgPC0gYyhyZXAoImphIiwgMzgpLCByZXAoIm5laW4iLCAxMCkpDQpnZXNjaGxlY2h0IDwtIGMocmVwKCJtIiwgbGVuZ3RoKHRpY3RvY19tKSksIHJlcCgidyIsIGxlbmd0aCh0aWN0b2NfdykpKQ0KdGljdG9jIDwtIGRhdGEuZnJhbWUoR2VzY2hsZWNodCA9IGdlc2NobGVjaHQsDQogICAgICAgICAgICAgICAgICAgICB0aWN0b2MgPSBjKHRpY3RvY19tLCB0aWN0b2NfdykpDQoNCiMgQ2hpLVF1YWRyYXQtVGVzdCwgRXJnZWJuaXMgaW4gY2hpc3Egc3BlaWNoZXJuDQpjaGlzcSA8LSBjaGlzcS50ZXN0KHRhYmxlKHRpY3RvYykpDQoNCiMgVGVzdGVyZ2VibmlzIGFuemVpZ2VuDQpjaGlzcQ0KDQojIEJlb2JhY2h0ZXRlIFdlcnRlIGFuemVpZ2VuDQpjaGlzcSRvYnNlcnZlZA0KDQojIGVyd2FydGV0ZSBXZXJ0ZSBhbnplaWdlbg0KY2hpc3EkZXhwZWN0ZWQNCmBgYA0KPGJyLz4NCjxici8+DQo8YnIvPg0KDQojIEtvcnJlbGF0aW9uICANCg0KQmVzY2hyZWlidCBkaWUgU3TDpHJrZSBlaW5lcyBsaW5lYXJlbiBadXNhbW1lbmhhbmdzIHp3aXNjaGVuIHp3ZWkgVmFyaWFibGVuLiAgDQpad2VpIEtvcnJlbGF0aW9uc2tvZWZmaXppZW50ZW46ICANCg0KKiAqKktvcnJlbGF0aW9uc2tvZWZmaXppZW50IG5hY2ggUGVhcnNvbiAkciQqKiAgDQogICogaXN0IGVtcGZpbmRsaWNoIGdlZ2Vuw7xiZXIgQXVzcmVpc3Nlcm4NCiAgDQokJHIgPSBcZnJhY3tzX3t4eX19e3NfeCBcdGltZXMgc195fSQkDQoNCiRzX3t4eX0kIGJlemVpY2huZXQgZGllICpDb3ZhcmlhbnoqIGRlciBiZWlkZW4gVmFyaWFibGVuICRYJCB1bmQgJFkkOg0KDQokJHNfe3h5fSA9IFxmcmFjezF9e24tMX0gXHN1bV97aT0xfV5uICh4X2ktXGJhcnt4fSkoeV9pLVxiYXJ7eX0pJCQNCiAgDQoqICoqUmFuZ2tvcnJlbGF0aW9uc2tvZWZmaXppZW50IG5hY2ggU3BlYXJtYW4gJHJfcyQqKg0KICAqIGlzdCByb2J1c3QgZ2VnZW7DvGJlciBBdXNyZWlzc2VybiAgICANCiAgKiBtaXNzdCBkZW4gbW9ub3RvbmVuIFp1c2FtbWVuaGFuZyB6d2lzY2hlbiB6d2VpIFZhcmlhYmxlbiAgIA0KICANCkludGVycHJldGF0aW9uIEtvcnJlbGF0aW9uc2tvZWZmaXppZW50ZW4gICANCg0KKiBXZXJ0ZWJlcmVpY2g6ICRbLTEsIH4xXSQsICQwJCAoa2VpbiBadXNhbW1lbmhhbmcpICRccG0xJCAocGVyZmVrdGVyIFp1c2FtbWVuaGFuZykgICANCiogRGFzIFZvcnplaWNoZW4gZ2lidCBkaWUgUmljaHR1bmcgZGVzIFp1c2FtbWVuaGFuZ3MgYW46IC0gKE1pbnVzKSBiZWRldXRldCBuZWdhdGl2ZXIgWnVzYW1tZW5oYW5nLCArIChQbHVzKSBiZWRldXRldCBwb3N0aXRpdmVyIFp1c2FtbWVuaGFuZy4gIA0KKiBGYXVzdHJlZ2VsIHp1ciBJbnRlcnByZXRhdGlvbjogIA0KICAqIC0wLjggYmlzIC0xOiBzdGFya2VyIG5lZ2F0aXZlciBadXNhbW1lbmhhbmcgICANCiAgKiAtMC44IGJpcyAtMC41OiBtaXR0bGVyZXIgbmVnYXRpdmVyIFp1c2FtbWVuaGFuZyAgDQogICogLTAuNSBiaXMgMC41OiBzY2h3YWNoZXIgcG9zaXRpdmVyIFp1c2FtbWVuaGFuZyAgIA0KICAqIDAuNSBiaXMgMC44OiBtaXR0bGVyZXIgWnVzYW1tZW5oYW5nICAgDQogICogMC44IGJpcyAxOiBzdGFya2VyIFp1c2FtbWVuaGFuZyAgDQogIA0KYGBge3IsIGV2YWw9RkFMU0UsIGVjaG89VFJVRX0NCiMgS29ycmVsYXRpb25za29lZmZpemllbnQgbmFjaCBQZWFyc29uDQpjb3IoeCwgeSkNCg0KIyBSYW5na29ycmVsYXRpb25za29lZmZpemllbnQgbmFjaCBTcGVhcm1hbg0KY29yKHgsIHksIG1ldGhvZCA9ICJzcGVhcm1hbiIpDQpgYGANCg0KSHlwb3RoZXNlbnRlc3QgZsO8ciBLb3JyZWxhdGlvbnNrb2VmZml6aWVudGVuICANCg0KKiAkSF8wOiBccmhvID0gMCQsIGVzIGJlc3RlaHQga2VpbiBsaW5lYXJlciBadXNhbW1lbmhhbmcgendpc2NoZW4gendlaSBWYXJpYWJsZW4uICANCiogJEhfQTogXHJobyBcbmVxIDAkLCBlcyBiZXN0ZWh0IGVpbiBsaW5lYXJlciBadXNhbW1lbmhhbmcgendpc2NoZW4gendlaSBWYXJpYWJsZW4uICAgDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBlY2hvPVRSVUV9DQojIEtvcnJlbGF0aW9uc2tvZWZmaXppZW50IG5hY2ggUGVhcnNvbg0KY29yLnRlc3QoeCwgeSkNCg0KIyBSYW5na29ycmVsYXRpb25za29lZmZpemllbnQgbmFjaCBTcGVhcm1hbg0KY29yLnRlc3QNCmBgYA0KDQo8YnIvPg0KPGJyLz4NCjxici8+DQoNCiMgRWluZmFjaGUgbGluZWFyZSBSZWdyZXNzaW9uICAgDQoNClF1YW50aWZpemllcnQgZGVuIFp1c2FtbWVuaGFuZyB6d2lzY2hlbiB6d2VpIFZhcmlhYmxlbi4gICANClVudGVyc2NoZWlkZTogKiphYmjDpG5naWdlIFZhcmlhYmxlICR5JCoqIHVuZCAqKnVuYWJow6RuZ2lnZSBWYXJpYWJsZSAkeCQsIFByw6RkaWt0b3IqKiAgICANCg0KIyMgTGluZWFyZXMgTW9kZWxsICANCg0KJCRcaGF0e3l9ID0gXGJldGFfMCArIFxiZXRhXzEgeCArIFxlcHNpbG9uJCQgIA0KDQpiencuIG1pdCBTdGljaHByb2JlbmRhdGVuICANCg0KJCRcaGF0e3l9ID0gYl8wICsgYl8xeCArIGUkJA0KDQoqICRcaGF0e3l9OiQgZ2VzY2jDpHR6dGUgYWJow6RuZ2lnZSBWYXJpYWJsZSAgIA0KKiAkYl8wOiQgQWNoc2VuYWJzY2huaXR0ICh4ID0gMCksICppbnRlcmNlcHQqICANCiogJGJfMTokIFN0ZWlndW5nIGRlciBSZWdyZXNzaW9uc2dlcmFkZW4sICpzbG9wZSogICANCiogJHg6JCBQcsOkZGlrdG9yICAgIA0KKiAkZTokIEZlaGxlciwgKlJlc2lkdWVuKiAgIA0KDQokJGVfaSA9IHlfaSAtIFxoYXR7eX1faSQkDQoNClN0ZWlndW5nIGRlciBSZWdyZXNzaW9uc2dlcmFkZW4gJGJfMSQgIA0KDQoqIFdlbm4gJHgkIHF1YW50aXRhdGl2IGlzdDogV2VubiAkeCQgdW0gZWluZSBFaW5oZWl0IGVyaMO2aHQgd2lyZCwgZXJ3YXJ0ZW4gd2lyLCBkYXNzICR5JCB1bSAkfGJfMXwkIEVpbmhlaXRlbiB6dW5pbW10IGJ6dy4gYWJuaW1tdC4gICANCiogV2VubiAkeCQgbm9taW5hbCBpc3Q6IERlciBXZXJ0IHZvbiAkeSQgbmltbXQgdW0gJHxiXzF8JCBFaW5oZWl0ZW4gZ2VnZW7DvGJlciBkZW0gUmVmZXJlbnpsZXZlbCB6dSBiencuIGFiLiAgDQogIA0KJCRiXzEgPSBcZnJhY3tzX3l9e3NfeX0gciQkDQoNCiogJHNfeTokIFN0YW5kYXJkYWJ3ZWljaHVuZyB2b24geSAgIA0KKiAkc195OiQgU3RhbmRhcmRhYndlaWNodW5nIHZvbiB4ICAgDQoqICRyOiQgS29ycmVsYXRpb25za29lZmZpemllbnQgbmFjaCBQZWFyc29uICAgDQoNCkFjaHNlbmFic2Nobml0dCAkYl8wJCAgIA0KDQoqIFdlbm4gJHgkIHF1YW50aXRhdGl2IGlzdDogV2VubiAkeCA9IDAkIGlzdCAkeSQgaW0gRHVyY2hzY2huaXR0IGdsZWljaCAkYl8wJCAgIA0KKiBXZW5uICR4JCBub21pbmFsIGlzdDogRGVyIGR1cmNoc2Nobml0dGxpY2hlIFdlcnQgdm9uICR5JCBmw7xyIGVpbiBiZXN0aW1tdGVzIExldmVsIHZvbiAkeCQgaXN0IGdsZWljaCAkYl8wJC4gDQogIA0KJCRiXzAgPSBcYmFye3l9IC0gYl8xIFxiYXJ7eH0kJA0KDQoqICRcYmFye3l9OiQgTWl0dGVsd2VydCB2b24gJHkkICAgDQoqICRcYmFye3h9OiQgTWl0dGVsd2VydCB2b24gJHgkDQogIA0KIyMgQmVkaW5ndW5nZW4gZsO8ciBkYXMgbGluZWFyZSBSZWdyZXNzaW9uc21vZGVsbCAgIA0KDQoxLiBMaW5lYXJpdMOkdCAgDQoNCiogRXMgYmVzdGVodCBlaW5lIGxpbmVhcmUgQmV6aWVodW5nIHp3aXNjaGVuICR5JCB1bmQgJHgkLiAgICANCiogV2lyZCBhbmhhbmQgdm9uIGVpbmVtIFN0cmV1ZGlhZ3JhbW0gw7xiZXJwcsO8ZnQuICAgDQoNCjIuIE5vcm1hbHZlcnRlaWx1bmcgZGVyIFJlc2lkdWVuICAgICAgDQoNCiogRGllIFJlc2lkdWVuIHNpbmQgYW5uw6RoZXJuZCBub3JtYWx2ZXJ0ZWlsdCwgbWl0IGVpbmVtIE1pdHRlbHdlcnQgdW0gMC4gIA0KKiBXaXJkIGFuaGFuZCB2b24gZWluZW0gUVEtUGxvdCBmw7xyIGRpZSBSZXNpZHVlbiDDvGJlcnByw7xmdC4gIA0KDQozLiBLb25zdGFudGUgVmFyaWFiaWxpdMOkdCAoSG9tb3NrZWRhc3Rpeml0w6R0KSAgDQoNCiogRGllIFN0cmV1dW5nIGRlciBQdW5rdGUgdW0gZGllIFJlZ3Jlc3Npb25zZ2VyYWRlIHNvbGx0ZSBhbm7DpGhlcm5kIGtvbnN0YW50IHNlaW4uICAgDQoqIERhcyBiZWRldXRldCwgZGFzcyBkaWUgU3RyZXV1bmcgZGVyIFJlc2lkdWVuIHVtIGRlbiBNaXR0ZWx3ZXJ0IDAgYW5uw6RoZXJuZCBrb25zdGFudCBpc3QuICAgDQoqIFdpcmQgYW4gZWluZW0gU3RyZXVkaWFncmFtbSBmw7xyIGRpZSBSZXNpZHVlbiBnZXByw7xmdC4gICANCg0KYGBge3IsIGVjaG89VFJVRX0NCiMgQmVpc3BpZWxkYXRlbiBnZW5lcmllcmVuICANCnNldC5zZWVkKDEpDQpiMCA8LSAyDQpiMSA8LSAuNQ0KeCA8LSBydW5pZigxMCkgDQplcnJvciA8LSBybm9ybSgxMCwgMCwgLjIpDQp5IDwtIGIwICsgYjEgKiB4ICsgZXJyb3INCmRhdGVuIDwtIGRhdGEuZnJhbWUoeCA9IHgsIHkgPSB5KQ0KDQojIGxpbmVhcmVzIG1vZGVsbCBiZXJlY2huZW4NCm1vZGVsIDwtIGxtKHkgfiB4LCBkYXRhID0gZGF0ZW4pDQoNCiMgWnVzYW1tZW5mYXNzdW5nIGRlcyBNb2RlbGxzIGFuemVpZ2VuDQpzdW1tYXJ5KG1vZGVsKQ0KDQojIERpYWdub3N0aXNjaGUgUGxvdHMgYW56ZWlnZW4NCnBsb3QobW9kZWwsIHdoaWNoID0gMToyKQ0KYGBgDQoNCiMjIEJlc3RpbW10aGVpdHNtYXNzICRSXjIkICAgDQoNCkbDvHIgZGllIGVpbmZhY2hlIGxpbmVhcmUgUmVncmVzc2lvbjoNCg0KJCRSXjI9cl4yJCQNCiAgDQoqICRyOiQgS29ycmVsYXRpb25za29lZmZpemllbnQgbmFjaCBQZWFyc29uICANCiogSXN0IGVpbiBNYXNzIGbDvHIgZGllIEfDvHRlIGVpbmVzIGxpbmVhcmVuIE1vZGVsbHMgICANCiogc2FndCB1bnMsIHdpZXZpZWwgUHJvemVudCBkZXIgU3RyZXV1bmcgaW4gJHkkIGR1cmNoICR4JCBlcmtsw6RydCB3ZXJkZW4uICANCg0KJCRSXjIgPSBcZnJhY3tkdXJjaH4geCB+ZXJrbMOkcnRlfiBTdHJldXVuZ34gdm9ufiB5fXtHZXNhbXRzdHJldXVuZ34gdm9ufiB5fSQkDQoNCiogRGllIG5pY2h0IGR1cmNoICRSXjIkIGVya2zDpHJiYXJlIFN0cmV1dW5nIHdpcmQgZHVyY2ggRmFrdG9yZW4gZXJrbMOkcnQsIGRpZSBuaWNodCBpbSBNb2RlbGwgZWluZ2VzY2hsb3NzZW4gc2luZC4gICANCiogV2VydGViZXJlaWNoOiBbMCwgMV0sIDAgPSAwJSwgMSA9IDEwMCUgIA0KKiBJbnRlcnByZXRhdGlvbjogJFJeMiUkIGRlciBWYXJpYWJpbGl0w6R0IHZvbiAkeSQgd2lyZCBkdXJjaCAkeCQgZXJrbMOkcnQuICANCg0KIyBSLUZ1bmt0aW9uZW4gDQoNClp1c2FtbWVuc3RlbGx1bmcgZWluaWdlciBow6R1ZmlnIHZlcndlbmRldGVyIGBSYC1GdW5rdGlvbmVuLiAgIA0KDQpXZXIgZXR3YXMgbWVociBEZXRhaWxzIHN1Y2h0IGlzdCBoaWVyIGd1dCBhdWZnZWhvYmVuOg0KDQoqIFtFaW5mw7xocnVuZyBpbiBSXShodHRwczovL21ldGhvZGVubGVocmUuZ2l0aHViLmlvL2VpbmZ1ZWhydW5nLWluLVIvaW5kZXguaHRtbCkgIA0KKiBbQmFzZSBSIC0gQ2hlYXQgU2hlZXRdKGh0dHBzOi8vaXFzcy5naXRodWIuaW8vZHNzLXdvcmtzaG9wcy9SL1JpbnRyby9iYXNlLXItY2hlYXQtc2hlZXQucGRmKQ0KDQojIyBIaWxmZSBlcmhhbHRlbg0KDQpIaWxmZSB6dSBlaW5lciBiZXN0aW1tdGVuIEZ1bmt0aW9uIChpbiBgUlN0dWRpb2AgaW0gUmVnaXN0ZXIgSGVscCkNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQo/bWVhbg0KYGBgDQoNClN0cnVrdHVyIGVpbmVzIE9iamVrdHMgYW56ZWlnZW4gKGluIGBSU3R1ZGlvYCBpbSBSZWdpc3RlciBFbnZpcm9ubWVudCkNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpzdHIob2JqZWN0bmFtZSkNCmBgYA0KDQojIyBMaWJyYXJpZXMgdmVyd2VuZGVuDQoNCkVpbmUgTGlicmFyeSBoZXJ1bnRlcmxhZGVuIHVuZCBpbnN0YWxsaWVyZW4NCg0KYGBge3IsIGV2YWw9RkFMU0V9DQppbnN0YWxsLnBhY2thZ2VzKCJsaWJyYXJ5bmFtZSIpDQpgYGANCg0KRWluZSBMaWJyYXJ5IGxhZGVuDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KbGlicmFyeShsaWJyYXJ5bmFtZSkNCmBgYA0KDQojIyBBcmJlaXRzdmVyemVpY2huaXMNCg0KQXJiZWl0c3ZlcnplaWNobmlzIGFuemVpZ2VuICANCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpnZXR3ZCgpDQpgYGANCg0KQXJiZWl0c3ZlcnplaWNobmlzIGRlZmluaWVyZW4gDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0Kc2V0d2QoIkM6Ly9wZmFkIikNCmBgYA0KDQojIyBWZWt0b3JlbiAoVmFyaWFibGVuKQ0KDQojIyMgVmVrdG9yZW4gZXJ6ZXVnZW4NCg0KYGBge3IsIGV2YWw9VFJVRX0NCiMgV2VydGUgZWluZW0gVmVrdG9yIHp1d2Vpc2VuDQp4IDwtIDINCngNCg0KIyBFbGVtZW50ZSB6dSBlaW5lbSBWZWt0b3IgdmVyYmluZGVuICANCnggPC0gYygyLCA0LCA2KQ0KeA0KDQojIEVpbmUgZ2FuenphaGxpZ2UgU2VxdWVueiBlcnpldWdlbg0KeCA8LSAyOjYNCngNCg0KIyBFaW5lIGtvbXBsZXhlIFNlcXVlbnogZXJ6ZXVnZW4NCnggPC0gc2VxKDIsIDMsIGJ5ID0gLjUpDQp4DQpgYGANCg0KIyMjIFZla3RvcmZ1bmt0aW9uZW4gDQoNCmBgYHtyfQ0KIyBCZWlzcGllbHZhcmlhYmxlIGVyemV1Z2VuIGbDvHIgRGVtbw0KeCA8LSBjKDMsIDIsIDEsIDIsIDIsIDEsIDMsIDQpICANCg0KIyBWYXJpYWJsZSBzb3J0aWVyZW4NCnNvcnQoeCkNCg0KIyBXZXJ0ZSB6w6RobGVuIHVuZCBpbiBUYWJlbGxlIGF1c2dlYmVuDQp0YWJsZSh4KQ0KDQojIEzDpG5nZSBlaW5lciBWYXJpYWJsZSBiZXN0aW1tZW4NCmxlbmd0aCh4KQ0KYGBgDQoNCiMjIyBWZWt0b3JlbGVtZW50ZSBhdXN3w6RobGVuDQoNCmBgYHtyfQ0KIyBkYXMgNC4gRWxlbWVudA0KeFs0XQ0KDQojIGFsbGUgRWxlbWVudGUgYXVzc2VyIGRlbSA0LiBFbGVtZW50DQp4Wy00XQ0KDQojIEVsZW1lbnRlIDIgYmlzIDQNCnhbMjo0XQ0KDQojIEVsZW1lbnRlIGRpZSBnbGVpY2ggMyBzaW5kDQp4W3ggPT0gM10gDQoNCiMgQWxsZSBFbGVtZW50ZSBkaWUga2xlaW5lciBhbHMgMyBzaW5kICANCnhbeCA8IDNdDQpgYGANCg0KIyMgRGF0ZW50eXBlbg0KDQpgUmAga2VubnQgNCBEYXRlbnR5cGVuICAgDQoNCmBgYHtyfQ0KIyBudW1lcmljIChxdWFudGl0YXRpdikNCnggPC0gYygxLCAwLCAxKQ0Kc3RyKHgpDQoNCiMgY2hyYXJhY3RlciAoc3RyaW5nKQ0KeCA8LSBjKCJBbm5hIiwgIkZlbGl4IiwgIkxlbmEiKQ0Kc3RyKHgpDQoNCiMgZmFjdG9yIChub21pbmFsKSwgVmVyd2VuZHVuZyBhbHMgR3J1cHBpZXJ1bmdzdmFyaWFibGUNCnggPC0gYygiY29uIiwgImV4cCIsICJleHAiKSAgDQpnZXNjaGxlY2h0IDwtIGZhY3Rvcih4LCAgbGV2ZWxzID0gYygiY29uIiwgImV4cCIpKQ0Kc3RyKGdlc2NobGVjaHQpDQoNCiMgbG9naWNhbCAtIFRSVUUsIEZBTFNFDQp4IDwtIGMoVFJVRSwgRkFMU0UsIEZBTFNFLCBUUlVFKQ0KeA0KDQojIEJlaXNwaWVsIGbDvHIgZGllIFZlcndlbmR1bmcgdm9uIGxvZ2lzY2hlbiBWYXJpYWJsZW4NCnggPC0gMToxMA0KeA0KeCA+IDUNCnhbeCA+IDVdDQpgYGANCg0KIyMgTG9naXNjaGUgT3BlcmF0b3Jlbg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCiMgYSBpc3QgZ2xlaWNoIGINCmEgPT0gYg0KDQojIGEgaXN0IG5pY2h0IGdsZWljaCBiDQphICE9IGINCg0KIyBhIGlzdCBncsO2c3NlciBhbHMgYg0KYSA+IGINCg0KIyBhIGlzdCBrbGVpbmVyIGFscyBiDQphIDwgYg0KDQojIGEgaXN0IGdyw7Zzc2VyIGdsZWljaCBiDQphID49IGINCg0KIyBhIGlzdCBrbGVpbmVyIGdsZWljaCBiDQphIDw9IEINCg0KIyBmZWhsZW5kZSBXZXJ0IGluIGENCmlzLm5hKGEpDQpgYGANCg0KIyMgTWF0aGVtYXRpc2NoZSBGdW5rdGlvbmVuICAgDQoNCmBgYHtyfQ0KIyBBZGRpZXJlbg0KMSArIDINCg0KIyBTdWJ0cmFoaWVyZW4NCjIgLSAxDQoNCiMgTXVsdGlwbGl6aWVyZW4NCjIgKiAzDQoNCiMgRGl2aWRpZXJlbg0KNiAvIDMNCg0KIyBRdWFkcmllcmVuDQozXjINCg0KIyBRdWFkcmF0d3VyemVsIHppZWhlbg0Kc3FydCg5KQ0KDQojIEFic29sdXR3ZXJ0DQphYnMoLTIpDQoNCiMgQmVpc3BpZWx2YXJpYWJsZSBlcnpldWdlbiBmw7xyIERlbW8NCnggPC0gYygzLCAyLCAxLCAyLCAyLCAxLCAzLCA0KSAgDQoNCiMgU3VtbWUgYmVyZWNobmVuDQpzdW0oeCkNCg0KIyBNYXhpbXVtIGZpbmRlbg0KbWF4KHgpDQoNCiMgTWluaW11bSBmaW5kZW4NCm1pbih4KQ0KDQojIFdlcnQgYXVmIDMgU3RlbGxlbiBydW5kZW4NCldlcnQgPC0gMy4xMjM0NTY3DQpyb3VuZChXZXJ0LCAzKQ0KDQojIE1pdHRlbHdlcnQgdm9uIHgNCm1lYW4oeCkNCg0KIyBNZWRpYW4gdm9uIHgNCm1lZGlhbih4KQ0KDQojIFZhcmlhbnogdm9uIHgNCnZhcih4KQ0KDQojIFN0YW5kYXJkYWJ3ZWljaHVuZyB2b24geA0Kc2QoeCkNCg0KIyBTcGFubndlaXRlLCBWYXJpYXRpb25zYnJlaXRlIChnaWJ0IG1pbiB1bmQgbWF4KQ0KcmFuZ2UoeCkNCg0KIyBJbnRlcnF1YXJ0aWxzYWJzdGFuZA0KSVFSKHgpDQpgYGANCg0KIyMgRGF0ZW5zw6R0emUgDQoNCkluIGVpbmVtIERhdGVuc2F0eiBoYWJlbiBhbGxlIFZhcmlhYmxlbiBkaWUgZ2xlaWNoZSBMw6RuZ2UhDQoNCmBgYHtyfQ0KIyBFaW5lbiBEYXRlbnNhdHogZXJzdGVsbGVuDQpkZiA8LSBkYXRhLmZyYW1lKA0KICB2YXJpYWJsZTEgPSAxOjMsDQogIHZhcmlhYmxlMiA9IGMoIkEiLCAiQiIsICJDIikNCikNCmRmDQoNCiMgR2VzYW10ZW4gRGF0ZW5zYXR6IGFuemVpZ2VuDQojIFZpZXcoZGYpDQoNCiMgRXJzdGUgNiBaZWlsZW4gZWluZXMgRGF0ZW5zYXR6ZXMgYW56ZWlnZW4NCmhlYWQoZGYpDQoNCiMgQW56YWhsIFplaWxlbiB1bmQgU3BhbHRlbiBhbnplaWdlbg0KZGltKGRmKQ0KDQojIFNwYWx0ZSBkZXMgRGF0ZW5zYXR6ZXMgYW56ZWlnZW4NCmRmWywgMV0gIA0KDQojIFplaWxlIGRlcyBEYXRlbnNhdHplcyBhbnplaWdlbg0KZGZbMiwgXQ0KDQojIEJlc3RpbW10ZSBaZWxsZSBkZXMgRGF0ZW5zYXR6ZXMgYW56ZWlnZW4NCmRmWzIsIDJdDQoNCiMgVmFyaWFibGUgZGVzIERhdGVuc2F0emVzDQpkZiR2YXJpYWJsZTENCmBgYA0KDQojIFJlZmVyZW56ZW4=