Wir verwenden das frei erhältliche Statistik-Programm RStudio. Dieses HTML-Dokument kann im RMD-Format abgespeichert werden, siehe die Schaltfläche Code rechts oben. Das RMD-Dokument kann dann in RStudio geöffnet werden.

Binomialtests

Binomialtests werden verwendet, um Hypothesen über die unbekannte Wahrscheinlichkeit \(p\) einer Münze zu testen. Hierbei wirft man die Münze \(n\)-mal unabhängig und betrachtet die Zahl \(S_n\) der Erfolge. Ein kleiner Wert von \(S_n\) deutet auf ein kleines \(p\), ein großer Wert von \(S_n\) deutet auf ein großes \(p\). Die Verteilung der Zufallsgröße \(S_n\) ist die Binomialverteilung \(B_{n,p}\).

Rechtsseitiger Binomialtest

\[ H_0: p\le p_0 \qquad H_1:p>p_0 \]

Wir akzeptieren \(H_0\), falls \(S_n\) kleine Werte annimmt. Wir lehnen \(H_0\) ab, falls \(S_n\) große Werte annimmt. Wir verwerfen \(H_0\), wenn \(S_n\) einen kritischen Wert \(c_\alpha\) überschreitet. Dabei soll die Wahrscheinlichkeit für einen Fehler 1.Art höchstens \(\alpha\) betragen. Wir fordern also, dass für \(p\in H_0\) stets

\[ \mathbb P_p(H_0 \text{ verwerfen})=\mathbb P_p(S_n>c_\alpha) \le \mathbb P_{p_0}(S_n>c_\alpha) \le \alpha \]

gilt. In der ersten Ungleichung haben wir die Verwerfungs-Wahrscheinlichkeiten für \(p\in H_0\) durch ihren größten Wert ersetzt. Dies ist intuitiv verständlich: obiges Ereignis betrifft große Werte von \(S_n\). Die Wahrscheinlichkeit für große Werte von \(S_n\) steigt, falls \(p\) steigt.

Darüber hinaus soll die Güte des Tests hoch sein. Das bedeutet, dass wir \(c_\alpha\) möglichst klein wählen wollen, denn dann ist der Verwerfungsbereich möglichst groß. Wir verlangen also

\[ c_\alpha=\min\{k\in \mathbb N_0: \mathbb P_{p_0}(S_n>k)\le \alpha\} \]

Diese Zahl ist das kleinste \(\alpha\)-Fraktil bzw. \((1-\alpha)\)-Quantil der Binomialverteilung \(B_{n,p_0}\) mit Parametern \(n\) und \(p_0\).

rechtsseitiger Binomialtest in R

In R kann der rechtsseitige Binomialtest mit dem Befehl binom.test() durchgeführt werden. Wie zu allen Befehlen von R erhält man mit ?binom.test Informationen zum Befehl, und mit binom.test wird der Programmcode des Befehls angezeigt.

?binom.test

Wir testen auf \(p>1/2\) zum Niveau \(0.05\) mit den Daten der Jungengeburten in Erlangen im Jahr 2022.

k=536; n=1059 # Jungengeburten in Erlangen 2022
p_0=0.5; alpha=0.05
binom.test(k,n,p_0, alt="greater", conf.level=1-alpha)

    Exact binomial test

data:  k and n
number of successes = 536, number of trials = 1059, p-value = 0.3562
alternative hypothesis: true probability of success is greater than 0.5
95 percent confidence interval:
 0.4804054 1.0000000
sample estimates:
probability of success 
             0.5061379 

Der \(p\)-Wert der Zahl der Erfolge \(k\) ist definiert als \(p(k)=\mathbb P_{p_0}(S_n\ge k)\). Dies ist die Wahrscheinlichkeit, dass die Teststatistik einen Wert annimmt, der mindestens so extrem ist wie der beobachtete Wert. Der \(p\)-Wert einer Beobachtung ist also eine Maßzahl für die Plausibilität der Nullhypothese. Tatsächlich wird \(H_0\) abgelehnt genau dann wenn \(p(k)\le \alpha\) gilt. Das Konfidenzintervall gibt einen Bereich an, in dem der wahre unbekannte Wert von \(p\) mit Sicherheit \(1-\alpha\) erwartet werden kann.

Als zweites Beispiel führen wir den Test auf die Störfall-Wahrscheinlichkeit für ein AKW durch.

k=2; n=442*30 # 2 AKW-GAUs in 442*30 Reaktorjahren
p_0=4e-6 # berechnete Stoerfall-Wkeit
# p_0=10*4e-6 # Wkeit fuer Fragestellung "bedeutend groesser"
alpha=0.05
binom.test(k,n,p_0, alt="greater", conf.level=1-alpha)

    Exact binomial test

data:  k and n
number of successes = 2, number of trials = 13260, p-value = 0.001358
alternative hypothesis: true probability of success is greater than 4e-06
95 percent confidence interval:
 2.680016e-05 1.000000e+00
sample estimates:
probability of success 
          0.0001508296 

Gütefunktion des rechtsseitigen Binomialtests

Die Gütefunktion des rechtsseitigen Binomialtests kann man in R wie folgt berechnen.

n=23; p_0=0.7; alpha=0.05
# Definition der Gütefunktion
G=function(p) {
  # bestimme kleinstes (1-alpha)-Quantil von B(n,p0)
  # mit R-Befehl qbinom
  c_al=qbinom(1-alpha, n,p_0) 
  # alternativ Berechnung von Hand
  # c_al=min(which(pbinom(0:n,n,p_0)>=1-alpha))-1
  1-pbinom(c_al, n,p) # P_p(H0 ablehnen)
}
# Zeichne Gütefunktion im Intervall [0,1] und beschrifte die Achsen 
plot(G, main=paste("Gütefunktion rechtsseitiger Binomialtest, n=",n), xlab="p", ylab="G(p)", xlim=c(0,1), lwd=2)
# Trage Zusatzinformationen ein
abline(h=alpha, col="blue"); abline(v=p_0, col="red")
text(p_0, 0.7, pos=2, expression(p[0]), col="red")
text(0, alpha, pos=3, expression(alpha), col="blue")

Falls man die Stichprobengröße erhöht, nähert sich die stetige Gütekurve einer Sprungfunktion an, die bei \(p_0\) von \(0\) auf \(1\) springt. Dies kann man so interpretieren, dass der Test um so genauer wird, je mehr Daten zur Verfügung stehen. Tatsächlich kann man so für beliebiges \(p\in H_1\) eine Stichprobengröße bestimmen, so dass die Wahrscheinlichkeit für einen Fehler 2.Art bei \(p\) kleiner als ein vorgegebener Wert \(\beta\) ist. Damit hat man eine explizite Kontrolle über die Qualität des Tests.

effektives Niveau des rechtsseitigen Binomialtests

Da die Teststatistik diskret ist, kann man nicht erwarten, dass die Wahrscheinlichkeit für einen Fehler 1.Art ihren maximal zulässigen Wert \(\alpha\) erreicht. Der Test ist also konservativer als gefordert. Dies führt auch dazu, dass die Güte in der Nähe von \(p_0\) geringer ausfällt als vielleicht möglich.

p_0=0.7; alpha=0.05
Gn=function(n) {
  c_al=qbinom(1-alpha, n,p_0) # kleinstes (1-alpha)-Quantil von B(n,p0)
  1-pbinom(c_al, n,p_0) # P_p(H0 ablehnen)
}
# fuer plot-Befehl muss Funktion "vektorisiert" werden
Gnvec=Vectorize(Gn)
xn=10:150; yn=Gnvec(xn)
plot(xn,yn, type="h", main=paste("rechtsseitiger Binomialtest zum Niveau", alpha), xlab="Stichprobengröße n", ylab="effektives Niveau", ylim=c(0,2*alpha))
abline(h=alpha, col="blue")
text(xn[1],alpha, pos=3, expression(alpha), col="blue")

Dieses unerwünschte Phänomen tritt bei kontinuierlichen Zufallsgrößen nicht auf. Um das Phänomen zu umgehen, kann man bei diskreten Zufallsgrößen sogenannte randomisierte Tests betrachten.

randomisierter rechtsseitiger Binomialtest

Bei diesem Test entscheidet man per Münzwurf, ob schon bei \(c_\alpha\) die Nullhypothese verworfen wird. Die Wahrscheinlichkeit \(\gamma\) dieser Münze ist dabei so eingestellt, dass der randomisierte Test genau Wahrscheinlichkeit \(\alpha\) für einen Fehler 1. Art besitzt. Dies führt auf

\[ \gamma=\frac{\alpha-\mathbb P_{p_0}(S_n>c_\alpha)}{\mathbb P_{p_0}(S_n=c_\alpha)} \]

Wir vergleichen die Gütefunktionen beider Tests.

Gran=function(p){
  # berechne kritischen Wert
  c_al=qbinom(1-alpha, n,p_0) # kleinstes (1-alpha)-Quantil von B(n,p0)
  # berechne gamma
  gam=(alpha-G(p_0))/dbinom(c_al,n,p_0)
  # definiere Wkeit H0 abzulehnen
  G(p)+gam*dbinom(c_al,n,p)
}
plot(G, main=paste("Gütefunktion rechtsseitiger Binomialtest, n=",n), xlab="p", ylab="G(p)", xlim=c(0,1), lwd=2)
abline(h=alpha, col="blue"); abline(v=p_0, col="red")
text(p_0, 0.7, pos=2, expression(p[0]), col="red")
text(0, alpha, pos=3, expression(alpha), col="blue")
text(0,0.9, pos=4, "randomisiert", col="brown")
text(0,0.8, pos=4, "nicht randomisiert", col="black")
curve(Gran(x), add=TRUE, col="brown", lwd=2)

Offenbar hat der randomisierte Test gleichmäßig in \(p\) eine höhere Güte als der obige nicht randomisierte Test.

Tatsächlich ist dieser randomisierte Test innerhalb der Klasse aller randomisierten Tests für das obige Testproblem optimal. Dies bedeutet, dass es keinen anderen Niveau-\(\alpha\)-Test für das obige Problem gibt, welche eine gleichmäßig höhere Güte besitzt. Tatsächlich gilt sogar, dass jeder gleichmäßig beste Niveau-\(\alpha\)-Test die obige Form besitzt.

Linksseitiger Binomialtest

Das Hypothesenpaar für den linksseitigen Binomialtest ist

\[ H_0: p\ge p_0 \qquad H_1:p<p_0 \]

Wir verwerfen \(H_0\), falls \(S_n\) einen kritischen Wert \(c_\alpha\) unterschreitet. Dabei soll die Wahrscheinlichkeit für einen Fehler 1.Art höchstens \(\alpha\) betragen. Wir fordern also

\[ \mathbb P_p(H_0 \text{ verwerfen})=\mathbb P_p(S_n<c_\alpha) \le \mathbb P_{p_0}(S_n<c_\alpha) \le \alpha \]Darüber hinaus soll die Güte des Tests hoch sein. Das bedeutet, dass wir \(c_\alpha\) möglichst groß wählen. Wir haben also

\[ c_\alpha=\max\{k\in \mathbb N_0: \mathbb P_{p_0}(S_n<k)\le \alpha\} \]

Diese Zahl ist das größte \(\alpha\)-Quantil der Binomialverteilung \(B_{n,p_0}\) mit Parametern \(n\) und \(p_0\). Die Gütefunktion des linksseitigen Binomialtests kann man in R wie folgt bestimmen.

n=23; p_0=0.7; alpha=0.05
G=function(p) {
  # berechne groesstes alpha-Quantil von B(n,p0)
  # hierfuer gibt es keinen R-Befehl
  c_al=max(which(pbinom((-1):(n-1),n,p_0)<=alpha))-1
  pbinom(c_al-1, n,p) # P_p(H0 ablehnen)
}
plot(G, main=paste("Gütefunktion linksseitiger Binomialtest, n=",n), xlab="p", ylab="G(p)", xlim=c(0,1), lwd=2)
abline(h=alpha, col="blue"); abline(v=p_0, col="red")
text(p_0, 0.7, pos=2, expression(p[0]), col="red")
text(0, alpha, pos=3, expression(alpha), col="blue")

Zweiseitige Binomialtests

Wir konstruieren zweiseitige Binomialtests der Form

\[ H_0:p=p_0 \qquad H_1:p\ne p_0 \]

Konstruktion mit dem TOST-Verfahren

Beim TOST-Verfahren (Two One-Sided Tests) testen wir \(H_0^{(1)}:p\ge p_0\) gegen \(H_1^{(1)}: p<p_0\) und dann \(H_0^{(2)}:p\le p_0\) gegen \(H_1^{(2)}: p>p_0\), jeweils zum Niveau \(\alpha/2\). Wir lehnen \(H_0\) ab genau dann wenn \(H_0^{(1)}\) abgelehnt werden kann oder wenn \(H_0^{(2)}\) abgelehnt werden kann. Dies ergibt einen Niveau-\(\alpha\)-Test für das obige zweiseitige Testproblem.

Die Gütefunktion dieses Tests kann aus den obigen Tests wie folgt erhalten werden.

n=16; p_0=0.7; alpha=0.05
# c1 groesstes alpha/2-Quantil von B(n,p0)
# c2 kleinstes (1-alpha/2)-Quantil von B(n,p0)
# es gilt nach Konstruktion c1<=c2
c1_t=max(which(pbinom((-1):(n-1),n,p_0)<=alpha/2))-1
c2_t=min(which(pbinom(0:n,n,p_0)>=1-alpha/2))-1
# lehne H_0: p=p_0 ab, falls S_n<c1 oder S_n>c2
G_tost=function(p) pbinom(c1_t-1, n,p) + (1-pbinom(c2_t,n,p))
plot(G_tost, main=paste("Gütefunktion zweiseitiger TOST-Binomialtest, n=",n), xlab="p", ylab="G(p)", xlim=c(0,1), lwd=2)
abline(h=alpha, col="blue"); abline(v=p_0, col="red")
text(p_0, 0.7, pos=2, expression(p[0]), col="red")
text(0, alpha, pos=3, expression(alpha), col="blue")

Konstruktion mit dem MPVT-Verfahren

Beim MPVT-Verfahren (Most Probable Values Test) wählen wir als Akzeptanzbereich für die Nullhypothese diejenigen Werte aus, die für \(H_0\) am wahrscheinlichsten sind.

Dies kann man in R wie folgt implementieren.

n=16; p_0=0.7; alpha=0.05
# bestimme kritischen Wert
# Wkeiten der Werte unter H0
probs=dbinom(0:n,n,p_0)
# nach Groesse sortieren
cvals=sort(dbinom(0:n,n,p_0))
# fuege einen grosseren Wert ein
cvals=append(cvals,1.1)
# Funktion: Wert k klein genug fuer Niveau alpha?
adm=function(k) sum(probs*(probs<k))<=alpha
admvec=Vectorize(adm)
# waehle maximalen zulaessigen Wert in cvals
c_al=cvals[max(which(sapply(cvals, admvec)))]
# Definition der Guetefunktion
# lehne H_0: p=p_0 ab, falls Wkeit fuer Wert kleiner als c_al ist
G_m=function(p){
  probsp=dbinom(0:n,n,p)
  sum(probsp*(probs<c_al))
}
G_mvec=Vectorize(G_m)
# zeichne die Guetefunktion
plot(G_mvec, main=paste("Gütefunktion zweiseitiger MPVW-Binomialtest, n=",n), xlab="p", ylab="G(p)", xlim=c(0,1), ylim=c(0,1),lwd=2)
abline(h=alpha, col="blue"); abline(v=p_0, col="red")
text(p_0, 0.7, pos=2, expression(p[0]), col="red")
text(0, alpha, pos=3, expression(alpha), col="blue")

Konstruktion des optimalen zweiseitigen Tests

Die obigen Tests haben zwei kritische Werte \(c_1<c_2\). Wir lehnen \(H_0\) ab, falls \(S_n<c_1\) oder \(S_n>c_2\) gilt. Wir können solche Tests randomisieren, indem wir im Fall \(S_n=c_1\) die Nullhypothese \(H_0\) mit Wahrscheinlichkeit \(\gamma_1\) ablehnen und im Fall \(S_n=c_2\) die Nullhypothese \(H_0\) mit Wahrscheinlichkeit \(\gamma_2\) ablehnen. Solche Tests kann man mit einer Funktion \(\phi:\{0, \ldots, n\}\to [0,1]\) beschreiben, die jeder möglichen Beobachtung die Wahrscheinlichkeit zuordnet, mit der man die Gegenhypothese akzeptiert.

Der optimale Test für das zweiseitige Testproblem wird im Buch von Lehmann und Romano im Beispiel 4.2.1 beschrieben. Er ist von der obigen Form. Der Test werde durch die Funktion \(\phi\) beschrieben. Die Konstanten \(c_1,c_2, \gamma_1,\gamma_2\) sind eindeutig bestimmt über die zwei Gleichungen

\[ \mathbb E_{p_0}[\phi]=\alpha \ , \qquad \mathbb E_{p_0}[\phi \cdot S_n]=\alpha\cdot n p_0 \ . \]

Die erste Gleichung fordert, dass der Test das Niveau \(\alpha\) ausschöpft. Es soll also \(G_\phi(p_0)=\alpha\) gelten. Die zweite Gleichung legt den Erwartungswert von \(S_n\) auf dem Ablehnungsbereich fest. Es sollte sich der natürliche Werte \(\alpha\cdot n p_0\) ergeben.

Für festes \(c_1,c_2\) sind die obigen Gleichungen lineare Gleichungen für \(\gamma_1,\gamma_2\). Es gilt nämlich

\[ \begin{split} \gamma_1 \mathbb P_{p_0}[S_n=c_1]+\gamma_2 \mathbb P_{p_0}[S_n=c_2]&=\alpha-\mathbb P_{p_0}[S_n<c_1 \text{ oder } S_n>c_2]\\ \gamma_1 c_1\mathbb P_{p_0}[S_n=c_1]+\gamma_2 c_2\mathbb P_{p_0}[S_n=c_2]&= \alpha n p_0-\mathbb E_{p_0}[S_n \cdot 1_{\{S_n<c_1 \text{ oder } S_n>c_2\}}] \end{split} \]

Da die Konstanten \(0\le c_1<c_2\le n\) und \(0\le \gamma_1,\gamma_2<1\) durch obige Gleichungen eindeutig bestimmt sind, kann man sie durch “Ausprobieren” erhalten. Hierzu dient das folgende Programm. Es kann für große Stichproben noch optimiert werden.

n=16; p_0=0.7; alpha=0.05
# probiere alle (!) Wahlen c1<c2
# einfach zu programmieren
# aber fuer hohes n sehr ineffizient
for (c1 in 0:n){
  for (c2 in (c1+1):n){
    # Wkeit auf Ablehnungsbereich
    p=(pbinom(c1-1,n,p_0) + 1-pbinom(c2,n,p_0))
    # Erwartungswert auf Ablehnungsbereich
    probs=dbinom(0:n, n, p_0)
    e=sum((0:n)*probs*(((0:n)<c1)+((0:n)>c2)))
    if ((p>alpha) || (e>alpha*n*p_0)) next
    # bestimme Wkeiten fuer Muenzwurf bei kritischen Werten
    p1=dbinom(c1,n,p_0); p2=dbinom(c2,n,p_0)
    # loese die Matrixgleichung A*gam=b
    b=c(alpha-p, alpha*n*p_0-e)
    A=matrix(c(p1,c1*p1,p2,c2*p2), nrow = 2)
    # ignoriere zu große Werte gam_1, gam_2
    # diese erkennt man an sehr kleiner Determinante
    prec=.Machine$double.eps
    if (abs(det(A))<10*prec) next
    gam=solve(A,b)
    # Falls gam_1, gam_2 Wkeiten sind, haben wir die
    # korrekten Parameter gefunden
    # Ausgabe der korrekten Werte
    if (sum(gam>=0 & gam <1)==2) {
      print(c(c1,c2))
      print(gam)
    }
  }
}
[1]  7 14
[1] 0.85148648 0.01322789

Mit den oben bestimmten Parametern des optimalen Tests kann die Gütefunktion gezeichnet werden.

# lehne H_0: p=p_0 ab, falls S_n<c1 oder S_n>c2
# randomisiere Test mit Wkeiten gamma1, gamma2
# die folgenden Parameter wurden mit dem obigen Programm bestimmt
n=16; c1=7; c2=14; g1=0.85148648; g2=0.01322789
# Definition der Guetefunktion
G_opt=function(p) pbinom(c1-1, n,p) + (1-pbinom(c2,n,p)) + g1*dbinom(c1,n,p)+g2*dbinom(c2,n,p)
# Guetefunktion zeichnen
plot(G_opt, main=paste("Gütefunktion zweiseitiger Binomialtest, n=",n), xlab="p", ylab="G(p)", xlim=c(0,1), lwd=2, col="gray")
abline(h=alpha, col="blue"); abline(v=p_0, col="red")
text(p_0, 0.7, pos=2, expression(p[0]), col="red")
text(0, alpha, pos=3, expression(alpha), col="blue")
text(0,0.7, pos=4, "OPTI", col="gray")

Vergleich der Gütefunktionen

Wir vergleichen die Gütefunktion der drei Tests. Hierzu verwenden wir die nicht randomisierte Variante des optimalen Tests.

# lehne H_0: p=p_0 ab, falls S_n<c1 oder S_n>c2
c1=7; c2=14; g1=0.85148648; g2=0.01322789
G_opt=function(p) pbinom(c1-1, n,p) + (1-pbinom(c2,n,p)) 
#+ g1*dbinom(c1,n,p)+g2*dbinom(c2,n,p)
# (Zusatzterm fuer randomisierte Version)
# zeichne die drei nicht randomisierten Guetefunktionen
plot(G_mvec, main=paste("Gütefunktion zweiseitiger Binomialtest, n=",n), xlab="p", ylab="G(p)", xlim=c(0,1), lwd=2, col="black")
abline(h=alpha, col="blue"); abline(v=p_0, col="red")
text(p_0, 0.7, pos=2, expression(p[0]), col="red")
text(0, alpha, pos=3, expression(alpha), col="blue")
text(0,0.9, pos=4, "TOST", col="brown")
text(0,0.8, pos=4, "MPVT", col="black")
text(0,0.7, pos=4, "OPTI", col="gray")
curve(G_tost(x), add=TRUE, col="brown", lwd=2)
curve(G_opt(x), add=TRUE, col="gray", lwd=2)

Es ist auch instruktiv, die Gütefunktion des randomisierten optimalen Tests zu zeichnen. Dann kann man erkennen, dass der MPVT-Test teilweise eine höhere Güte als der optimale Test haben kann. Dies ist kein Widerspruch, weil die Optimalitätsaussage nur für unverfälschte Tests gilt. Der MPVT-Test ist aber verfälscht.

zweiseitiger Binomialtest in R

Der R-Befehl binom.test() erlaubt auch zweiseitige Binomialtests.

n=510400; k=334 # Geburtstagkinder 29. Februar in Nürnberg
p_0=(4*365+1)^(-1); alpha=0.05
binom.test(k,n,p_0, alt="two.sided", conf.level=1-alpha)

    Exact binomial test

data:  k and n
number of successes = 334, number of trials = 510400, p-value = 0.4376
alternative hypothesis: true probability of success is not equal to 0.0006844627
95 percent confidence interval:
 0.0005861023 0.0007284424
sample estimates:
probability of success 
          0.0006543887 

In binom.test() sind das TOST-Verfahren und das MPVT-Verfahren implementiert. Das TOST-Verfahren erhält man, in dem man das Konfidenzintervall für die Testentscheidung verwendet. Man akzeptiert \(H_0\), falls \(p_0\) im Konfidenzintervall für \(p\) liegt. Das MPVT-Verfahren erhält man, in dem für die Testentscheidung den \(p\)-Wert verwendet. Man lehnt \(H_0\) ab, falls \(p(k)\le \alpha\) gilt.

In unserem Beispiel führen beide Tests auf dieselbe Entscheidung. Dies ist auch der Fall für den optimalen Test, welcher in binom.test() nicht implementiert ist. Tatsächlich könnte man in unserem Beispiel auch einen \(t\)-Test oder einen \(z\)-Test verwenden, weil wegen der hohen Stichprobengröße die Normalapproximation eine gute Näherung ist (beachte \(n p_0(1-p_0)>10\)). Dies Verfahren ist weiter unten am Beispiel eines Äquivalenztests beschrieben.

Äquivalenztests

Bei Äquivalenztests untersucht man das Hypothesenpaar.

\[ H_0 : p\le p_1 \text{ oder } p\ge p_2 \qquad H_1:p_1<p<p_2 \]

Wir besprechen, wie solche Tests durchgeführt werden können. Es ist nicht schwer, hieraus Tests auf Inäquivalenz zu entwickeln.

TOST-Äquivalenztest

Beim TOST-Verfahren (Two One-Sided Tests) testen wir \(H_0^{(1)}:p\le p_1\) gegen \(H_1^{(1)}: p>p_1\) und dann \(H_0^{(2)}:p\ge p_2\) gegen \(H_1^{(2)}: p<p_2\), jeweils zum Niveau \(\alpha\). Wir lehnen \(H_0\) ab genau dann wenn \(H_0^{(1)}\) abgelehnt werden kann und wenn \(H_0^{(2)}\) abgelehnt werden kann. Dies ergibt einen Niveau-\(\alpha\)-Test für das obige zweiseitige Testproblem. Dieser Test ist asymptotisch optimal.

Der Test wird ähnlich wie beim TOST-Verfahren für den zweiseitigen Binomialtest konstruiert. Wir lehnen \(H_0\) ab, falls \(c_1<S_n<c_2\) gilt. Wir berechnen die kritischen Grenzen \(c_1\) und \(c_2\).

n=100; p_1=0.6; p_2=0.8; alpha=0.05
# c1 kleinstes (1-alpha)-Quantil von B(n,p_1)
# c2 groesstes alpha-Quantil von B(n,p_2)
c_1=min(which(pbinom(0:n,n,p_1)>=1-alpha))-1
c_2=max(which(pbinom((-1):(n-1),n,p_2)<=alpha))-1
c(c_1,c_2)
[1] 68 73

Falls für die kritischen Werte \(c_1<c_2\) gilt, ist der TOST-Test anwendbar. Dies ist für hinreichend große Stichproben der Fall.

n=100; p_1=0.6; p_2=0.8; alpha=0.05
# bestimme kritische Werte wie oben
c_1=68; c_2=73
# lehne H0 ab, falls c_1<S_n<c_2 gilt
G_tost=function(p) {
  vals=dbinom(0:n, n, p)
  sum(vals*(((0:n)>c_1) & ((0:n)<c_2)))
}
G_tostv=Vectorize(G_tost)
# zeichne Guetefunktion
plot(G_tostv, main=paste("Gütefunktion TOST-Äquivalenztest, n=",n), xlab="p", ylab="G(p)", xlim=c(0,1), lwd=2)
# zeichne Niveau-alpha-Linie
abline(h=alpha, col="blue")
text(0, alpha, pos=3, expression(alpha), col="blue")
# zeichne p1, p2
abline(v=p_1, col="red"); abline(v=p_2, col="red")
text(p_1, 0.7, pos=2, expression(p[1]), col="red")
text(p_2, 0.7, pos=2, expression(p[1]), col="red")

Optimaler Äquivalenztest

Für das obige Testproblem gibt es einen gleichmäßig besten Niveau-\(\alpha\)-Test. Wir lehnen \(H_0\) ab, falls \(c_1<S_n<c_2\) gilt. Wir akzeptieren \(H_0\), falls \(S_n<c_1\) oder \(S_n>c_2\) gilt. Im Fall \(S_n=c_1\) lehnen wir \(H_0\) mit Wahrscheinlichkeit \(\gamma_1\) ab, im Fall \(S_n=c_2\) lehnen wir \(H_0\) mit Wahrscheinlichkeit \(\gamma_2\) ab.

Es bezeichne \(p\mapsto G(p)\) die Gütefunktion des optimalen Tests. Dann gelten \(G(p_1)=\alpha\) und \(G(p_2)=\alpha\). Diese beiden Gleichungen legen die Konstanten \(0\le c_1<c_2\le n\) und \(0\le \gamma_1,\gamma_2<1\) eindeutig fest. Sie können durch “Ausprobieren” bestimmt werden.

Das R-Paket EQUIVNONINF implementiert die Algorithmen aus dem Buch von Wellek für Äquivalenztests. Das Paket kann über Packages/Install im rechten unteren Fenster installiert werden. Der Befehl für den Binomial-Äquivalenztest ist bi1st(). Der Algorithmus funktioniert nur für hinreichend kleine Stichproben.

library(EQUIVNONINF)
bi1st(0.05, 100, .6, .8)
 alpha = 0.05    n = 100    P1 = 0.6    P2 = 0.8    C1 = 68    C2 = 73 
 gam1 = 0.5965293    gam2 = 0.8318769    POWNONRD = 0.3367418    POW = 0.4429064

Es ergeben sich dieselben kritischen Werte \(c_1,c_2\) wie oben. Das Programm gibt auch die Güte des Tests bei \(p=(p_1+p_2)/2\) an. Für POWNONRD wird die nicht randomisierte Version des Tests verwendet, bei POW wird die randomisierte Version des Tests verwendet.

Anstatt das obige Programmpaket zu verwenden, kann man diese Funktion auch selbst programmieren, indem man den Code für den optimalen zweiseitigen Binomialtest anpasst.

Optimaler Äquivalenz-Test für normalverteilte Zufallsgrößen

Wir beschreiben den optimalen Äquivalenztest für den Erwartungswert einer normalverteilten Zufallsgröße bei bekannter Varianz. Der optimale Inäquivalenztest kann analog entwickelt werden. Dasselbe gilt für die klassischen einseitigen und zweiseitigen Tests auf Erwartungswert einer Normalverteilung bei bekannter Varianz (\(z\)-Tests).

Seien \(X_1, \ldots, X_n\) unabhängige wie \(N(\mu,\sigma^2)\) verteilte Zufallsvariablen. Wir nehmen an, dass \(\mu\) unbekannt ist und dass \(\sigma^2\) bekannt ist. Wir wollen auf das Hypothesenpaar

\[ H_0:|\mu-\mu_0|\ge \delta \qquad H_1: |\mu-\mu_0|<\delta \] testen. Hierzu verwenden wir die Test-Statistik

\[ T_n=(Y_n)^2 \ , \qquad Y_n=\frac{\overline{X}_n-\mu_0}{\sigma/\sqrt{n}} \ , \] mit \(\overline{X}_n=(X_1+\ldots+X_n)/n\) das arithmetische Mittel der Stichprobe. Wir lehnen \(H_0\) ab, falls \(T_n\) zu klein ist. Es handelt sich also um einen linksseitigen Test für den Parameter \(|\mu-\mu_0|\).

Die Zufallsgröße \(T_n\) ist das Quadrat der Zufallsgröße \(Y_n\). Die Zufallsgröße \(Y_n\) ist normalverteilt mit Erwartungswert \((\mu-\mu_0)/(\sigma/\sqrt{n})\) und Varianz \(1\). Die Verteilung von \(T_n\) heißt nichtzentrale \(\chi^2\)-Verteilung mit einem Freiheitsgrad und Nichtzentralitätsparameter

\[ \lambda=\left(\frac{\mu-\mu_0}{\sigma/\sqrt{n}}\right)^2 \] Wir lehnen also \(H_0\) ab, falls \(T_n< q\) gilt, mit \(q\) das \(\alpha\)-Quantil dieser Verteilung. Die Verteilung ist in R implementiert.

Wir wenden diesen Äquivalenz-Test auf die Frage nach der Wahrscheinlichkeit für den 29. Februar als Geburtstag an. Dies ist zulässig, weil beim Münzwurf die relative Häufigkeit der Erfolge bei großer Stichprobe in guter Näherung normalverteilt ist. Dies führt auf folgenden Code.

# Aequivalenztest fuer normalverteilte Zufallsgroessen
# Beispiel: p_0 fuer Geburtstage am 29. Februar?
p_0=(4*365+1)^(-1)
# Daten aus Nuernberg 2012
n=510400; k=334
# Normalapproximation zulaessig, falls n*p_0*(1-p_0)>10
n*p_0*(1-p_0)
[1] 349.1106
# waehle fuer delta relativen Fehler von 10 Prozent
del=p_0*0.1
# alpha-Quantil der nichtzentralen chi2-Verteilung
# 1 Freiheitsgrad (df), Nichtzentralitaetsparameter lam
alpha=0.05
sig=sqrt(p_0*(1-p_0)); lam=(del*sqrt(n)/sig)^2
q=qchisq(alpha, df=1, ncp=lam)
# Wert der Teststatistik
xbar=k/n; sig=sqrt(p_0*(1-p_0))
T=((xbar-p_0)*sqrt(n)/sig)^2
# Lehne H0 ab, falls T<q 
T; q
[1] 0.6749011
[1] 0.1178393

Im Beispiel können wir \(H_0\) nicht ablehnen. Dies könnte daran liegen, dass die Stichprobe nicht groß genug ist. Es wäre nun instruktiv, beispielsweise die Zahlen mehrerer Großstädte zusammenzufassen.

Jenseits des Binomialtests

Tests auf Erwartungswert in R

Der Einfachheit soll die hypothetische Fragestellung untersucht werden, ob der mittlere Wert einer Messgröße aus einem wiederholten Experiment größer als \(2.1\) ist.

Anstatt reale Daten zu verwenden, erzeugen wir mit dem Computer Daten aus einer Normalverteilung. Wir vergessen danach, wie die Daten erzeugt wurden. Mit diesem Verfahren kann man simulieren, wie sich der Test verhält. Damit kann man ein intuitives Verständnis für die Anwendung des Tests entwickeln.

mu0=2.2; sig=2; n=200
# n Zufallszahlen aus N(mu0, sig^2)
x=rnorm(n, mu0, sig)

Wir nehmen an, dass die Daten in guter Näherung einer Normalverteilung folgen. Dies kann zum Beispiel mit einem qq-Plot oder einem Test auf Normalverteilung untersucht werden.

Für den \(z\)-Test bei bekannter Varianz gehen wir wie folgt vor. Aus Bequemlichkeit verwenden wir das Paket BSDA, welches über Packages/Install im rechten unteren Fenster installiert werden kann.

# z-Test
# lade Paket mit z-Test
library(BSDA)
# rechtsseitiger z-Test bei bekannter Varianz auf mu>2.1 zum Niveau alpha
alpha=0.05
z.test(x,mu=2.1, sigma.x=sig, alt="greater", conf.level = 1-alpha)

    One-sample z-Test

data:  x
z = 0.10213, p-value = 0.4593
alternative hypothesis: true mean is greater than 2.1
95 percent confidence interval:
 1.881825       NA
sample estimates:
mean of x 
 2.114443 

Für den \(t\)-Test bei unbekannter Varianz gehen wir wie folgt vor.

# t-Test
# rechtsseitiger t-Test mu>2.1 bei unbekannter Varianz zum Niveau alpha
alpha=0.05
t.test(x,mu=2.1, alt="greater", conf.level = 1-alpha)

    One Sample t-test

data:  x
t = 0.1058, df = 199, p-value = 0.4579
alternative hypothesis: true mean is greater than 2.1
95 percent confidence interval:
 1.888846      Inf
sample estimates:
mean of x 
 2.114443 

Anpassungstests in R für diskrete Verteilungen

Als Standard-Beispiel untersuchen wir die Ziehung der Lottozahlen. Daten hierzu finden sich unter dem folgenden Link.

# Haeufigkeiten der Lottozahlen 1 bis 49 (Stand 4.3.2024)
x=c(607,587,607,593,584,649,594,544,585,587,614,557,520,558,560,581,591,582,602,558,547,615,565,586,606,618,589,550,589,559,617,621,618,570,563,591,581,606,575,579,599,603,611,569,533,561,583,592,636)
# Liste der Haeufigkeiten
x
 [1] 607 587 607 593 584 649 594 544 585 587 614 557 520 558 560 581 591 582 602 558
[21] 547 615 565 586 606 618 589 550 589 559 617 621 618 570 563 591 581 606 575 579
[41] 599 603 611 569 533 561 583 592 636

Wir verwenden das statistische Modell, dass sich die 49 Lottozahlen wie Zufallszahlen aus einer unbekannten gegebenen Verteilung mit 49 Werten verhalten. Die Nullhypothese des \(\chi^2\)-Anpassungstests lautet, dass die unbekannten Wahrscheinlichkeiten für die Lottozahlen den vermuteten Wahrscheinlichkeiten \(1/49\) gleichen. Als Teststatistik wird eine Größe verwendet, welche die Abweichung der beobachteten Häufigkeiten von den erwarteteten Häufigkeiten quantifiziert.

Die Durchführung des Tests in R ist sehr einfach. Wir wählen das Niveau \(\alpha=0.05\).

# Referenz-Wahrscheinlichkeiten
p0=rep(1/49,49)
# chi2-Anpassungstest
chisq.test(x,p=p0)

    Chi-squared test for given probabilities

data:  x
X-squared = 57.225, df = 48, p-value = 0.17

Weil der \(p\)-Wert größer als \(\alpha\) ist, müseen wir die Nullhypothese akzeptieren. Die Daten liefern keinen Anlass daran zu zweifeln, dass jede Zahl mit der gleichen Wahrscheinlichkeit auftritt.

Für die Testentscheidung wurde die asymptotisch exakte \(\chi^2\)-Verteilung der Teststatistik verwendet, welche auf einer Normalapproximation beruht. Als Faustregel gilt, dass die Normalapproximation zulässig ist, falls für jede vermutete Wahrscheinlichkeit \(p_i\) die Ungleichung \(n p_i\ge 5\) gilt, mit \(n\) die Stichprobengröße. In unserem Beispiel ist die Normalapproximation also unproblematisch.

Man kann die exakte Verteilung der Teststatistik ohne großen Aufwand mit dem Computer simulieren. Damit kann man zum einen überprüfen, wie gut die Normalapproximation ist. Zum anderen kann man den Anpassungstest mit der simulierten exakten Verteilung durchführen.

Man kann die \(\chi^2\)-Approximation für die asymptotische Verteilung der Teststatistik verwenden, um einen asymptotisch exakten Äquivalenztest auf Anpassung zu entwickeln.

Unabhängigkeitstests in R für diskrete Verteilungen

Wir beschränken uns auf den einfachsten Fall von Zufallsgrößen mit nur zwei Merkmalen und besprechen ein fiktives Beispiel.

Es soll zum Niveau \(\alpha=0.05\) untersucht werden, ob Smartphone-Nutzung einen signifikanten Einfluss auf schulische Leistungen hat. Hierzu wurde in der 12. Jahrgangsstufe eine Mathematik-Klausur gestellt, an der 87 Schüler:innen teilgenommen haben. Die Schüler:innen haben über einen Zeitraum von einem Monat vor der Klausur ihre Smartphone-Nutzungsdauer gemessen. Ihr Klausurergebnis war entweder besser (B) oder nicht besser (S) als das durchschnittliche Ergebnis. Ihre Smartphone-Nutzungsdauer war entweder niedrig (N, weniger als 2h/Tag) oder hoch (H, mindestens 2h/Tag).

Das Ergebnis ist in der folgenden Tabelle angegeben.

M=cbind(c(19,19),c(16,33))
rownames(M)=c("B", "S")
colnames(M)=c("N", "H")
M
   N  H
B 19 16
S 19 33

Wir verwenden das statistische Modell, dass die beiden Merkmale sich wie Zufallsgrößen mit fester unbekannter gemeinsamer Verteilung verhalten. Beim Unabhängigkeitstest lautet die Nullhypothese, dass die Merkmale unabhängig sind. Falls wir \(H_0\) ablehnen, haben wir eine signifikante Verletzung von Unabhängigkeit erkannt. Falls wir \(H_0\) akzeptieren, liefern die Daten keinen Hinweis darauf, dass die Annahme der Unabhängigkeit der Merkmale verletzt sein könnte.

Aufgrund der relativ großen Stichprobe sollten wir erwarten, dass eine Normalapproximation zulässig ist. Wir verwenden hierzu die Faustregel, dass jeder Eintrag in der Matrix größer als 5 ist. Also gehen wir davon aus, dass ein \(\chi^2\)-Anpassungstest zulässig ist.

# chi2-Unabhaengigkeitstest
chisq.test(M)

    Pearson's Chi-squared test with Yates' continuity correction

data:  M
X-squared = 2.0055, df = 1, p-value = 0.1567

Es ist vielleicht überraschend, dass die Unabhängigkeitshypothese akzeptiert werden muss. Die Stichprobe ist nicht groß genug, um eine Abweichung von Unabhängigkeit zu erkennen.

Der sogenannte exakte Test von Fisher hätte dasselbe Ergebnis geliefert. Seine Teststatistik ist der linke obere Eintrag in der Matrix. Die Verteilung der Teststatistik ist bei unabhängigen Merkmalen und festen Randhäufigkeiten hypergeometrisch. (Letztere Annahme ist für die Anwendung unproblematisch, weil man den Ergebnisraum in Teilräume mit festen Randhäufigkeiten zerlegen kann.) Es wird der \(p\)-Wert für das MPVT-Verfahren ausgegeben. Also ist nicht der optimale Test implementiert!

# exakter Test von Fisher
fisher.test(M)

    Fisher's Exact Test for Count Data

data:  M
p-value = 0.1252
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
 0.7895282 5.4037752
sample estimates:
odds ratio 
  2.044939 

Tatsächlich implementiert der R-Befehl ein verwandtes Testproblem. Man kann sich dafür interessieren, ob zwei unabhängige Merkmale mit denselben Wahrscheinlichkeiten auftreten. Diese Frage nach Homogenität unabhängiger Merkmale unterscheidet sich von der Frage nach Unabhängigkeit der beiden Merkmale. Als Teststatistik wird das Verhältnis der geschätzten Chancen (odds) für überdurchschnittliches Abschneiden bei niedriger und hoher Nutzungsdauer verwendet. Der R-Befehl gibt auch ein Konfidenzintervall für das unbekannte Chancenverhältnis \(\varrho\) an. Ein Niveau-\(\alpha\)-Test auf \(H_0:\varrho=\varrho_0\) gegen \(H_1:\varrho\neq\varrho_0\) kann hieraus auch mit folgender Entscheidungsregel erhalten werden: Akzeptiere \(H_0\) zum Niveau \(\alpha\), falls \(\varrho_0\) im \((1-\alpha)\)-Konfidenzintervall für \(\varrho\) liegt. Tatsächlich gilt, dass bei festen Randhäufigkeiten die Bedingung der Unabhängigkeit gerade durch \(\varrho=1\) beschrieben wird. Für Details siehe das Buch von Lehmann und Romano, Kapitel 4.5 und 4.6.

# h_N Haeufigkeit fuer besseres Abschneiden bei niedriger Dauer
h_N=M["B","N"]/(M["B","N"]+M["S","N"])
# h_M Haeufigkeit fuer besseres Abschneiden bei hoher Dauer
h_H=M["B","H"]/(M["B","H"]+M["S","H"])
# Wert des Chancen-Verhaeltnisses (odds ratio)
(h_N/(1-h_N))/(h_H/(1-h_H))
[1] 2.0625
LS0tDQp0aXRsZTogIkVpbiBBcmJlaXRzYmxhdHQgenUgc3RhdGlzdGlzY2hlbiBUZXN0dmVyZmFocmVuIg0KYXV0aG9yOiAiQ2hyaXN0b3BoIFJpY2hhcmQsIEZBVSBFcmxhbmdlbi1Ow7xybmJlcmcsIDEyLjAzLjIwMjQiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpXaXIgdmVyd2VuZGVuIGRhcyBmcmVpIGVyaMOkbHRsaWNoZSBTdGF0aXN0aWstUHJvZ3JhbW0gW1JTdHVkaW9dKGh0dHBzOi8vcG9zaXQuY28vZG93bmxvYWQvcnN0dWRpby1kZXNrdG9wLykuIERpZXNlcyBIVE1MLURva3VtZW50IGthbm4gaW0gUk1ELUZvcm1hdCBhYmdlc3BlaWNoZXJ0IHdlcmRlbiwgc2llaGUgZGllIFNjaGFsdGZsw6RjaGUgKkNvZGUqIHJlY2h0cyBvYmVuLiBEYXMgUk1ELURva3VtZW50IGthbm4gZGFubiBpbiBSU3R1ZGlvIGdlw7ZmZm5ldCB3ZXJkZW4uDQoNCiMgQmlub21pYWx0ZXN0cw0KDQpCaW5vbWlhbHRlc3RzIHdlcmRlbiB2ZXJ3ZW5kZXQsIHVtIEh5cG90aGVzZW4gw7xiZXIgZGllIHVuYmVrYW5udGUgV2FocnNjaGVpbmxpY2hrZWl0ICRwJCBlaW5lciBNw7xuemUgenUgdGVzdGVuLiBIaWVyYmVpIHdpcmZ0IG1hbiBkaWUgTcO8bnplICRuJC1tYWwgdW5hYmjDpG5naWcgdW5kIGJldHJhY2h0ZXQgZGllIFphaGwgJFNfbiQgZGVyIEVyZm9sZ2UuIEVpbiBrbGVpbmVyIFdlcnQgdm9uICRTX24kIGRldXRldCBhdWYgZWluIGtsZWluZXMgJHAkLCBlaW4gZ3Jvw59lciBXZXJ0IHZvbiAkU19uJCBkZXV0ZXQgYXVmIGVpbiBncm/Dn2VzICRwJC4gRGllIFZlcnRlaWx1bmcgZGVyIFp1ZmFsbHNncsO2w59lICRTX24kIGlzdCBkaWUgQmlub21pYWx2ZXJ0ZWlsdW5nICRCX3tuLHB9JC4NCg0KIyMgUmVjaHRzc2VpdGlnZXIgQmlub21pYWx0ZXN0DQoNCiQkDQpIXzA6IHBcbGUgcF8wIFxxcXVhZCBIXzE6cD5wXzANCiQkDQoNCldpciBha3plcHRpZXJlbiAkSF8wJCwgZmFsbHMgJFNfbiQga2xlaW5lIFdlcnRlIGFubmltbXQuIFdpciBsZWhuZW4gJEhfMCQgYWIsIGZhbGxzICRTX24kIGdyb8OfZSBXZXJ0ZSBhbm5pbW10LiBXaXIgdmVyd2VyZmVuICRIXzAkLCB3ZW5uICRTX24kIGVpbmVuIGtyaXRpc2NoZW4gV2VydCAkY19cYWxwaGEkIMO8YmVyc2NocmVpdGV0LiBEYWJlaSBzb2xsIGRpZSBXYWhyc2NoZWlubGljaGtlaXQgZsO8ciBlaW5lbiBGZWhsZXIgMS5BcnQgaMO2Y2hzdGVucyAkXGFscGhhJCBiZXRyYWdlbi4gV2lyIGZvcmRlcm4gYWxzbywgZGFzcyBmw7xyICRwXGluIEhfMCQgc3RldHMNCg0KJCQNClxtYXRoYmIgUF9wKEhfMCBcdGV4dHsgdmVyd2VyZmVufSk9XG1hdGhiYiBQX3AoU19uPmNfXGFscGhhKSBcbGUgDQpcbWF0aGJiIFBfe3BfMH0oU19uPmNfXGFscGhhKSBcbGUgXGFscGhhDQokJA0KDQpnaWx0LiBJbiBkZXIgZXJzdGVuIFVuZ2xlaWNodW5nIGhhYmVuIHdpciBkaWUgVmVyd2VyZnVuZ3MtV2FocnNjaGVpbmxpY2hrZWl0ZW4gZsO8ciAkcFxpbiBIXzAkIGR1cmNoIGlocmVuIGdyw7bDn3RlbiBXZXJ0IGVyc2V0enQuIERpZXMgaXN0IGludHVpdGl2IHZlcnN0w6RuZGxpY2g6IG9iaWdlcyBFcmVpZ25pcyBiZXRyaWZmdCBncm/Dn2UgV2VydGUgdm9uICRTX24kLiBEaWUgV2FocnNjaGVpbmxpY2hrZWl0IGbDvHIgZ3Jvw59lIFdlcnRlIHZvbiAkU19uJCBzdGVpZ3QsIGZhbGxzICRwJCBzdGVpZ3QuDQoNCkRhcsO8YmVyIGhpbmF1cyBzb2xsIGRpZSBHw7x0ZSBkZXMgVGVzdHMgaG9jaCBzZWluLiBEYXMgYmVkZXV0ZXQsIGRhc3Mgd2lyICRjX1xhbHBoYSQgbcO2Z2xpY2hzdCBrbGVpbiB3w6RobGVuIHdvbGxlbiwgZGVubiBkYW5uIGlzdCBkZXIgVmVyd2VyZnVuZ3NiZXJlaWNoIG3DtmdsaWNoc3QgZ3Jvw58uIFdpciB2ZXJsYW5nZW4gYWxzbw0KDQokJA0KY19cYWxwaGE9XG1pblx7a1xpbiBcbWF0aGJiIE5fMDogXG1hdGhiYiBQX3twXzB9KFNfbj5rKVxsZSBcYWxwaGFcfQ0KJCQNCg0KRGllc2UgWmFobCBpc3QgZGFzIGtsZWluc3RlICRcYWxwaGEkLUZyYWt0aWwgYnp3LiAkKDEtXGFscGhhKSQtUXVhbnRpbCBkZXIgQmlub21pYWx2ZXJ0ZWlsdW5nICRCX3tuLHBfMH0kIG1pdCBQYXJhbWV0ZXJuICRuJCB1bmQgJHBfMCQuDQoNCiMjIyByZWNodHNzZWl0aWdlciBCaW5vbWlhbHRlc3QgaW4gUg0KDQpJbiBSIGthbm4gZGVyIHJlY2h0c3NlaXRpZ2UgQmlub21pYWx0ZXN0IG1pdCBkZW0gQmVmZWhsICpiaW5vbS50ZXN0KCkqIGR1cmNoZ2Vmw7xocnQgd2VyZGVuLiBXaWUgenUgYWxsZW4gQmVmZWhsZW4gdm9uIFIgZXJow6RsdCBtYW4gbWl0ICo/Ymlub20udGVzdCogSW5mb3JtYXRpb25lbiB6dW0gQmVmZWhsLCB1bmQgbWl0ICpiaW5vbS50ZXN0KiB3aXJkIGRlciBQcm9ncmFtbWNvZGUgZGVzIEJlZmVobHMgYW5nZXplaWd0Lg0KDQpgYGB7cn0NCj9iaW5vbS50ZXN0DQpgYGANCg0KV2lyIHRlc3RlbiBhdWYgJHA+MS8yJCB6dW0gTml2ZWF1ICQwLjA1JCBtaXQgZGVuIERhdGVuIGRlciBKdW5nZW5nZWJ1cnRlbiBpbiBFcmxhbmdlbiBpbSBKYWhyIDIwMjIuDQoNCmBgYHtyfQ0Kaz01MzY7IG49MTA1OSAjIEp1bmdlbmdlYnVydGVuIGluIEVybGFuZ2VuIDIwMjINCnBfMD0wLjU7IGFscGhhPTAuMDUNCmJpbm9tLnRlc3QoayxuLHBfMCwgYWx0PSJncmVhdGVyIiwgY29uZi5sZXZlbD0xLWFscGhhKQ0KYGBgDQoNCkRlciAkcCQtV2VydCBkZXIgWmFobCBkZXIgRXJmb2xnZSAkayQgaXN0IGRlZmluaWVydCBhbHMgJHAoayk9XG1hdGhiYiBQX3twXzB9KFNfblxnZSBrKSQuIERpZXMgaXN0IGRpZSBXYWhyc2NoZWlubGljaGtlaXQsIGRhc3MgZGllIFRlc3RzdGF0aXN0aWsgZWluZW4gV2VydCBhbm5pbW10LCBkZXIgbWluZGVzdGVucyBzbyBleHRyZW0gaXN0IHdpZSBkZXIgYmVvYmFjaHRldGUgV2VydC4gRGVyICRwJC1XZXJ0IGVpbmVyIEJlb2JhY2h0dW5nIGlzdCBhbHNvIGVpbmUgTWHDn3phaGwgZsO8ciBkaWUgUGxhdXNpYmlsaXTDpHQgZGVyIE51bGxoeXBvdGhlc2UuIFRhdHPDpGNobGljaCB3aXJkICRIXzAkIGFiZ2VsZWhudCBnZW5hdSBkYW5uIHdlbm4gJHAoaylcbGUgXGFscGhhJCBnaWx0LiBEYXMgS29uZmlkZW56aW50ZXJ2YWxsIGdpYnQgZWluZW4gQmVyZWljaCBhbiwgaW4gZGVtIGRlciB3YWhyZSB1bmJla2FubnRlIFdlcnQgdm9uICRwJCBtaXQgU2ljaGVyaGVpdCAkMS1cYWxwaGEkIGVyd2FydGV0IHdlcmRlbiBrYW5uLg0KDQpBbHMgendlaXRlcyBCZWlzcGllbCBmw7xocmVuIHdpciBkZW4gVGVzdCBhdWYgZGllIFN0w7ZyZmFsbC1XYWhyc2NoZWlubGljaGtlaXQgZsO8ciBlaW4gQUtXIGR1cmNoLg0KDQpgYGB7cn0NCms9Mjsgbj00NDIqMzAgIyAyIEFLVy1HQVVzIGluIDQ0MiozMCBSZWFrdG9yamFocmVuDQpwXzA9NGUtNiAjIGJlcmVjaG5ldGUgU3RvZXJmYWxsLVdrZWl0DQojIHBfMD0xMCo0ZS02ICMgV2tlaXQgZnVlciBGcmFnZXN0ZWxsdW5nICJiZWRldXRlbmQgZ3JvZXNzZXIiDQphbHBoYT0wLjA1DQpiaW5vbS50ZXN0KGssbixwXzAsIGFsdD0iZ3JlYXRlciIsIGNvbmYubGV2ZWw9MS1hbHBoYSkNCmBgYA0KDQojIyMgR8O8dGVmdW5rdGlvbiBkZXMgcmVjaHRzc2VpdGlnZW4gQmlub21pYWx0ZXN0cw0KDQpEaWUgR8O8dGVmdW5rdGlvbiBkZXMgcmVjaHRzc2VpdGlnZW4gQmlub21pYWx0ZXN0cyBrYW5uIG1hbiBpbiBSIHdpZSBmb2xndCBiZXJlY2huZW4uDQoNCmBgYHtyfQ0Kbj0yMzsgcF8wPTAuNzsgYWxwaGE9MC4wNQ0KIyBEZWZpbml0aW9uIGRlciBHw7x0ZWZ1bmt0aW9uDQpHPWZ1bmN0aW9uKHApIHsNCiAgIyBiZXN0aW1tZSBrbGVpbnN0ZXMgKDEtYWxwaGEpLVF1YW50aWwgdm9uIEIobixwMCkNCiAgIyBtaXQgUi1CZWZlaGwgcWJpbm9tDQogIGNfYWw9cWJpbm9tKDEtYWxwaGEsIG4scF8wKSANCiAgIyBhbHRlcm5hdGl2IEJlcmVjaG51bmcgdm9uIEhhbmQNCiAgIyBjX2FsPW1pbih3aGljaChwYmlub20oMDpuLG4scF8wKT49MS1hbHBoYSkpLTENCiAgMS1wYmlub20oY19hbCwgbixwKSAjIFBfcChIMCBhYmxlaG5lbikNCn0NCiMgWmVpY2huZSBHw7x0ZWZ1bmt0aW9uIGltIEludGVydmFsbCBbMCwxXSB1bmQgYmVzY2hyaWZ0ZSBkaWUgQWNoc2VuIA0KcGxvdChHLCBtYWluPXBhc3RlKCJHw7x0ZWZ1bmt0aW9uIHJlY2h0c3NlaXRpZ2VyIEJpbm9taWFsdGVzdCwgbj0iLG4pLCB4bGFiPSJwIiwgeWxhYj0iRyhwKSIsIHhsaW09YygwLDEpLCBsd2Q9MikNCiMgVHJhZ2UgWnVzYXR6aW5mb3JtYXRpb25lbiBlaW4NCmFibGluZShoPWFscGhhLCBjb2w9ImJsdWUiKTsgYWJsaW5lKHY9cF8wLCBjb2w9InJlZCIpDQp0ZXh0KHBfMCwgMC43LCBwb3M9MiwgZXhwcmVzc2lvbihwWzBdKSwgY29sPSJyZWQiKQ0KdGV4dCgwLCBhbHBoYSwgcG9zPTMsIGV4cHJlc3Npb24oYWxwaGEpLCBjb2w9ImJsdWUiKQ0KDQpgYGANCg0KRmFsbHMgbWFuIGRpZSBTdGljaHByb2Jlbmdyw7bDn2UgZXJow7ZodCwgbsOkaGVydCBzaWNoIGRpZSBzdGV0aWdlIEfDvHRla3VydmUgZWluZXIgU3BydW5nZnVua3Rpb24gYW4sIGRpZSBiZWkgJHBfMCQgdm9uICQwJCBhdWYgJDEkIHNwcmluZ3QuIERpZXMga2FubiBtYW4gc28gaW50ZXJwcmV0aWVyZW4sIGRhc3MgZGVyIFRlc3QgdW0gc28gZ2VuYXVlciB3aXJkLCBqZSBtZWhyIERhdGVuIHp1ciBWZXJmw7xndW5nIHN0ZWhlbi4gVGF0c8OkY2hsaWNoIGthbm4gbWFuIHNvIGbDvHIgYmVsaWViaWdlcyAkcFxpbiBIXzEkIGVpbmUgU3RpY2hwcm9iZW5ncsO2w59lIGJlc3RpbW1lbiwgc28gZGFzcyBkaWUgV2FocnNjaGVpbmxpY2hrZWl0IGbDvHIgZWluZW4gRmVobGVyIDIuQXJ0IGJlaSAkcCQga2xlaW5lciBhbHMgZWluIHZvcmdlZ2ViZW5lciBXZXJ0ICRcYmV0YSQgaXN0LiBEYW1pdCBoYXQgbWFuIGVpbmUgZXhwbGl6aXRlIEtvbnRyb2xsZSDDvGJlciBkaWUgUXVhbGl0w6R0IGRlcyBUZXN0cy4NCg0KIyMjIGVmZmVrdGl2ZXMgTml2ZWF1IGRlcyByZWNodHNzZWl0aWdlbiBCaW5vbWlhbHRlc3RzDQoNCkRhIGRpZSBUZXN0c3RhdGlzdGlrIGRpc2tyZXQgaXN0LCBrYW5uIG1hbiBuaWNodCBlcndhcnRlbiwgZGFzcyBkaWUgV2FocnNjaGVpbmxpY2hrZWl0IGbDvHIgZWluZW4gRmVobGVyIDEuQXJ0IGlocmVuIG1heGltYWwgenVsw6Rzc2lnZW4gV2VydCAkXGFscGhhJCBlcnJlaWNodC4gRGVyIFRlc3QgaXN0IGFsc28ga29uc2VydmF0aXZlciBhbHMgZ2Vmb3JkZXJ0LiBEaWVzIGbDvGhydCBhdWNoIGRhenUsIGRhc3MgZGllIEfDvHRlIGluIGRlciBOw6RoZSB2b24gJHBfMCQgZ2VyaW5nZXIgYXVzZsOkbGx0IGFscyB2aWVsbGVpY2h0IG3DtmdsaWNoLg0KDQpgYGB7cn0NCnBfMD0wLjc7IGFscGhhPTAuMDUNCkduPWZ1bmN0aW9uKG4pIHsNCiAgY19hbD1xYmlub20oMS1hbHBoYSwgbixwXzApICMga2xlaW5zdGVzICgxLWFscGhhKS1RdWFudGlsIHZvbiBCKG4scDApDQogIDEtcGJpbm9tKGNfYWwsIG4scF8wKSAjIFBfcChIMCBhYmxlaG5lbikNCn0NCiMgZnVlciBwbG90LUJlZmVobCBtdXNzIEZ1bmt0aW9uICJ2ZWt0b3Jpc2llcnQiIHdlcmRlbg0KR252ZWM9VmVjdG9yaXplKEduKQ0KeG49MTA6MTUwOyB5bj1HbnZlYyh4bikNCnBsb3QoeG4seW4sIHR5cGU9ImgiLCBtYWluPXBhc3RlKCJyZWNodHNzZWl0aWdlciBCaW5vbWlhbHRlc3QgenVtIE5pdmVhdSIsIGFscGhhKSwgeGxhYj0iU3RpY2hwcm9iZW5ncsO2w59lIG4iLCB5bGFiPSJlZmZla3RpdmVzIE5pdmVhdSIsIHlsaW09YygwLDIqYWxwaGEpKQ0KYWJsaW5lKGg9YWxwaGEsIGNvbD0iYmx1ZSIpDQp0ZXh0KHhuWzFdLGFscGhhLCBwb3M9MywgZXhwcmVzc2lvbihhbHBoYSksIGNvbD0iYmx1ZSIpDQpgYGANCg0KRGllc2VzIHVuZXJ3w7xuc2NodGUgUGjDpG5vbWVuIHRyaXR0IGJlaSBrb250aW51aWVybGljaGVuIFp1ZmFsbHNncsO2w59lbiBuaWNodCBhdWYuIFVtIGRhcyBQaMOkbm9tZW4genUgdW1nZWhlbiwga2FubiBtYW4gYmVpIGRpc2tyZXRlbiBadWZhbGxzZ3LDtsOfZW4gc29nZW5hbm50ZSByYW5kb21pc2llcnRlIFRlc3RzIGJldHJhY2h0ZW4uDQoNCiMjIyByYW5kb21pc2llcnRlciByZWNodHNzZWl0aWdlciBCaW5vbWlhbHRlc3QNCg0KQmVpIGRpZXNlbSBUZXN0IGVudHNjaGVpZGV0IG1hbiBwZXIgTcO8bnp3dXJmLCBvYiBzY2hvbiBiZWkgJGNfXGFscGhhJCBkaWUgTnVsbGh5cG90aGVzZSB2ZXJ3b3JmZW4gd2lyZC4gRGllIFdhaHJzY2hlaW5saWNoa2VpdCAkXGdhbW1hJCBkaWVzZXIgTcO8bnplIGlzdCBkYWJlaSBzbyBlaW5nZXN0ZWxsdCwgZGFzcyBkZXIgcmFuZG9taXNpZXJ0ZSBUZXN0IGdlbmF1IFdhaHJzY2hlaW5saWNoa2VpdCAkXGFscGhhJCBmw7xyIGVpbmVuIEZlaGxlciAxLiBBcnQgYmVzaXR6dC4gRGllcyBmw7xocnQgYXVmDQoNCiQkDQpcZ2FtbWE9XGZyYWN7XGFscGhhLVxtYXRoYmIgUF97cF8wfShTX24+Y19cYWxwaGEpfXtcbWF0aGJiIFBfe3BfMH0oU19uPWNfXGFscGhhKX0NCiQkDQoNCldpciB2ZXJnbGVpY2hlbiBkaWUgR8O8dGVmdW5rdGlvbmVuIGJlaWRlciBUZXN0cy4NCg0KYGBge3J9DQpHcmFuPWZ1bmN0aW9uKHApew0KICAjIGJlcmVjaG5lIGtyaXRpc2NoZW4gV2VydA0KICBjX2FsPXFiaW5vbSgxLWFscGhhLCBuLHBfMCkgIyBrbGVpbnN0ZXMgKDEtYWxwaGEpLVF1YW50aWwgdm9uIEIobixwMCkNCiAgIyBiZXJlY2huZSBnYW1tYQ0KICBnYW09KGFscGhhLUcocF8wKSkvZGJpbm9tKGNfYWwsbixwXzApDQogICMgZGVmaW5pZXJlIFdrZWl0IEgwIGFienVsZWhuZW4NCiAgRyhwKStnYW0qZGJpbm9tKGNfYWwsbixwKQ0KfQ0KcGxvdChHLCBtYWluPXBhc3RlKCJHw7x0ZWZ1bmt0aW9uIHJlY2h0c3NlaXRpZ2VyIEJpbm9taWFsdGVzdCwgbj0iLG4pLCB4bGFiPSJwIiwgeWxhYj0iRyhwKSIsIHhsaW09YygwLDEpLCBsd2Q9MikNCmFibGluZShoPWFscGhhLCBjb2w9ImJsdWUiKTsgYWJsaW5lKHY9cF8wLCBjb2w9InJlZCIpDQp0ZXh0KHBfMCwgMC43LCBwb3M9MiwgZXhwcmVzc2lvbihwWzBdKSwgY29sPSJyZWQiKQ0KdGV4dCgwLCBhbHBoYSwgcG9zPTMsIGV4cHJlc3Npb24oYWxwaGEpLCBjb2w9ImJsdWUiKQ0KdGV4dCgwLDAuOSwgcG9zPTQsICJyYW5kb21pc2llcnQiLCBjb2w9ImJyb3duIikNCnRleHQoMCwwLjgsIHBvcz00LCAibmljaHQgcmFuZG9taXNpZXJ0IiwgY29sPSJibGFjayIpDQpjdXJ2ZShHcmFuKHgpLCBhZGQ9VFJVRSwgY29sPSJicm93biIsIGx3ZD0yKQ0KYGBgDQoNCk9mZmVuYmFyIGhhdCBkZXIgcmFuZG9taXNpZXJ0ZSBUZXN0IGdsZWljaG3DpMOfaWcgaW4gJHAkIGVpbmUgaMO2aGVyZSBHw7x0ZSBhbHMgZGVyIG9iaWdlIG5pY2h0IHJhbmRvbWlzaWVydGUgVGVzdC4NCg0KVGF0c8OkY2hsaWNoIGlzdCBkaWVzZXIgcmFuZG9taXNpZXJ0ZSBUZXN0IGlubmVyaGFsYiBkZXIgS2xhc3NlIGFsbGVyIHJhbmRvbWlzaWVydGVuIFRlc3RzIGbDvHIgZGFzIG9iaWdlIFRlc3Rwcm9ibGVtIG9wdGltYWwuIERpZXMgYmVkZXV0ZXQsIGRhc3MgZXMga2VpbmVuIGFuZGVyZW4gTml2ZWF1LSRcYWxwaGEkLVRlc3QgZsO8ciBkYXMgb2JpZ2UgUHJvYmxlbSBnaWJ0LCB3ZWxjaGUgZWluZSBnbGVpY2htw6TDn2lnIGjDtmhlcmUgR8O8dGUgYmVzaXR6dC4gVGF0c8OkY2hsaWNoIGdpbHQgc29nYXIsIGRhc3MgamVkZXIgZ2xlaWNobcOkw59pZyBiZXN0ZSBOaXZlYXUtJFxhbHBoYSQtVGVzdCBkaWUgb2JpZ2UgRm9ybSBiZXNpdHp0Lg0KDQojIyBMaW5rc3NlaXRpZ2VyIEJpbm9taWFsdGVzdA0KDQpEYXMgSHlwb3RoZXNlbnBhYXIgZsO8ciBkZW4gbGlua3NzZWl0aWdlbiBCaW5vbWlhbHRlc3QgaXN0DQoNCiQkDQpIXzA6IHBcZ2UgcF8wIFxxcXVhZCBIXzE6cDxwXzANCiQkDQoNCldpciB2ZXJ3ZXJmZW4gJEhfMCQsIGZhbGxzICRTX24kIGVpbmVuIGtyaXRpc2NoZW4gV2VydCAkY19cYWxwaGEkIHVudGVyc2NocmVpdGV0LiBEYWJlaSBzb2xsIGRpZSBXYWhyc2NoZWlubGljaGtlaXQgZsO8ciBlaW5lbiBGZWhsZXIgMS5BcnQgaMO2Y2hzdGVucyAkXGFscGhhJCBiZXRyYWdlbi4gV2lyIGZvcmRlcm4gYWxzbw0KDQokJA0KXG1hdGhiYiBQX3AoSF8wIFx0ZXh0eyB2ZXJ3ZXJmZW59KT1cbWF0aGJiIFBfcChTX248Y19cYWxwaGEpIFxsZSANClxtYXRoYmIgUF97cF8wfShTX248Y19cYWxwaGEpIFxsZSBcYWxwaGENCiQkRGFyw7xiZXIgaGluYXVzIHNvbGwgZGllIEfDvHRlIGRlcyBUZXN0cyBob2NoIHNlaW4uIERhcyBiZWRldXRldCwgZGFzcyB3aXIgJGNfXGFscGhhJCBtw7ZnbGljaHN0IGdyb8OfIHfDpGhsZW4uIFdpciBoYWJlbiBhbHNvDQoNCiQkDQpjX1xhbHBoYT1cbWF4XHtrXGluIFxtYXRoYmIgTl8wOiBcbWF0aGJiIFBfe3BfMH0oU19uPGspXGxlIFxhbHBoYVx9DQokJA0KDQpEaWVzZSBaYWhsIGlzdCBkYXMgZ3LDtsOfdGUgJFxhbHBoYSQtUXVhbnRpbCBkZXIgQmlub21pYWx2ZXJ0ZWlsdW5nICRCX3tuLHBfMH0kIG1pdCBQYXJhbWV0ZXJuICRuJCB1bmQgJHBfMCQuIERpZSBHw7x0ZWZ1bmt0aW9uIGRlcyBsaW5rc3NlaXRpZ2VuIEJpbm9taWFsdGVzdHMga2FubiBtYW4gaW4gUiB3aWUgZm9sZ3QgYmVzdGltbWVuLg0KDQpgYGB7cn0NCm49MjM7IHBfMD0wLjc7IGFscGhhPTAuMDUNCkc9ZnVuY3Rpb24ocCkgew0KICAjIGJlcmVjaG5lIGdyb2Vzc3RlcyBhbHBoYS1RdWFudGlsIHZvbiBCKG4scDApDQogICMgaGllcmZ1ZXIgZ2lidCBlcyBrZWluZW4gUi1CZWZlaGwNCiAgY19hbD1tYXgod2hpY2gocGJpbm9tKCgtMSk6KG4tMSksbixwXzApPD1hbHBoYSkpLTENCiAgcGJpbm9tKGNfYWwtMSwgbixwKSAjIFBfcChIMCBhYmxlaG5lbikNCn0NCnBsb3QoRywgbWFpbj1wYXN0ZSgiR8O8dGVmdW5rdGlvbiBsaW5rc3NlaXRpZ2VyIEJpbm9taWFsdGVzdCwgbj0iLG4pLCB4bGFiPSJwIiwgeWxhYj0iRyhwKSIsIHhsaW09YygwLDEpLCBsd2Q9MikNCmFibGluZShoPWFscGhhLCBjb2w9ImJsdWUiKTsgYWJsaW5lKHY9cF8wLCBjb2w9InJlZCIpDQp0ZXh0KHBfMCwgMC43LCBwb3M9MiwgZXhwcmVzc2lvbihwWzBdKSwgY29sPSJyZWQiKQ0KdGV4dCgwLCBhbHBoYSwgcG9zPTMsIGV4cHJlc3Npb24oYWxwaGEpLCBjb2w9ImJsdWUiKQ0KDQpgYGANCg0KIyMgWndlaXNlaXRpZ2UgQmlub21pYWx0ZXN0cw0KDQpXaXIga29uc3RydWllcmVuIHp3ZWlzZWl0aWdlIEJpbm9taWFsdGVzdHMgZGVyIEZvcm0NCg0KJCQNCkhfMDpwPXBfMCBccXF1YWQgSF8xOnBcbmUgcF8wDQokJA0KDQojIyMgS29uc3RydWt0aW9uIG1pdCBkZW0gVE9TVC1WZXJmYWhyZW4NCg0KQmVpbSBUT1NULVZlcmZhaHJlbiAoVHdvIE9uZS1TaWRlZCBUZXN0cykgdGVzdGVuIHdpciAkSF8wXnsoMSl9OnBcZ2UgcF8wJCBnZWdlbiAkSF8xXnsoMSl9OiBwPHBfMCQgdW5kIGRhbm4gJEhfMF57KDIpfTpwXGxlIHBfMCQgZ2VnZW4gJEhfMV57KDIpfTogcD5wXzAkLCBqZXdlaWxzIHp1bSBOaXZlYXUgJFxhbHBoYS8yJC4gV2lyIGxlaG5lbiAkSF8wJCBhYiBnZW5hdSBkYW5uIHdlbm4gJEhfMF57KDEpfSQgYWJnZWxlaG50IHdlcmRlbiBrYW5uIG9kZXIgd2VubiAkSF8wXnsoMil9JCBhYmdlbGVobnQgd2VyZGVuIGthbm4uIERpZXMgZXJnaWJ0IGVpbmVuIE5pdmVhdS0kXGFscGhhJC1UZXN0IGbDvHIgZGFzIG9iaWdlIHp3ZWlzZWl0aWdlIFRlc3Rwcm9ibGVtLg0KDQpEaWUgR8O8dGVmdW5rdGlvbiBkaWVzZXMgVGVzdHMga2FubiBhdXMgZGVuIG9iaWdlbiBUZXN0cyB3aWUgZm9sZ3QgZXJoYWx0ZW4gd2VyZGVuLg0KDQpgYGB7cn0NCm49MTY7IHBfMD0wLjc7IGFscGhhPTAuMDUNCiMgYzEgZ3JvZXNzdGVzIGFscGhhLzItUXVhbnRpbCB2b24gQihuLHAwKQ0KIyBjMiBrbGVpbnN0ZXMgKDEtYWxwaGEvMiktUXVhbnRpbCB2b24gQihuLHAwKQ0KIyBlcyBnaWx0IG5hY2ggS29uc3RydWt0aW9uIGMxPD1jMg0KYzFfdD1tYXgod2hpY2gocGJpbm9tKCgtMSk6KG4tMSksbixwXzApPD1hbHBoYS8yKSktMQ0KYzJfdD1taW4od2hpY2gocGJpbm9tKDA6bixuLHBfMCk+PTEtYWxwaGEvMikpLTENCiMgbGVobmUgSF8wOiBwPXBfMCBhYiwgZmFsbHMgU19uPGMxIG9kZXIgU19uPmMyDQpHX3Rvc3Q9ZnVuY3Rpb24ocCkgcGJpbm9tKGMxX3QtMSwgbixwKSArICgxLXBiaW5vbShjMl90LG4scCkpDQpwbG90KEdfdG9zdCwgbWFpbj1wYXN0ZSgiR8O8dGVmdW5rdGlvbiB6d2Vpc2VpdGlnZXIgVE9TVC1CaW5vbWlhbHRlc3QsIG49IixuKSwgeGxhYj0icCIsIHlsYWI9IkcocCkiLCB4bGltPWMoMCwxKSwgbHdkPTIpDQphYmxpbmUoaD1hbHBoYSwgY29sPSJibHVlIik7IGFibGluZSh2PXBfMCwgY29sPSJyZWQiKQ0KdGV4dChwXzAsIDAuNywgcG9zPTIsIGV4cHJlc3Npb24ocFswXSksIGNvbD0icmVkIikNCnRleHQoMCwgYWxwaGEsIHBvcz0zLCBleHByZXNzaW9uKGFscGhhKSwgY29sPSJibHVlIikNCmBgYA0KDQojIyMgS29uc3RydWt0aW9uIG1pdCBkZW0gTVBWVC1WZXJmYWhyZW4NCg0KQmVpbSBNUFZULVZlcmZhaHJlbiAoTW9zdCBQcm9iYWJsZSBWYWx1ZXMgVGVzdCkgd8OkaGxlbiB3aXIgYWxzIEFremVwdGFuemJlcmVpY2ggZsO8ciBkaWUgTnVsbGh5cG90aGVzZSBkaWVqZW5pZ2VuIFdlcnRlIGF1cywgZGllIGbDvHIgJEhfMCQgYW0gd2FocnNjaGVpbmxpY2hzdGVuIHNpbmQuDQoNCkRpZXMga2FubiBtYW4gaW4gUiB3aWUgZm9sZ3QgaW1wbGVtZW50aWVyZW4uDQoNCmBgYHtyfQ0Kbj0xNjsgcF8wPTAuNzsgYWxwaGE9MC4wNQ0KIyBiZXN0aW1tZSBrcml0aXNjaGVuIFdlcnQNCiMgV2tlaXRlbiBkZXIgV2VydGUgdW50ZXIgSDANCnByb2JzPWRiaW5vbSgwOm4sbixwXzApDQojIG5hY2ggR3JvZXNzZSBzb3J0aWVyZW4NCmN2YWxzPXNvcnQoZGJpbm9tKDA6bixuLHBfMCkpDQojIGZ1ZWdlIGVpbmVuIGdyb3NzZXJlbiBXZXJ0IGVpbg0KY3ZhbHM9YXBwZW5kKGN2YWxzLDEuMSkNCiMgRnVua3Rpb246IFdlcnQgayBrbGVpbiBnZW51ZyBmdWVyIE5pdmVhdSBhbHBoYT8NCmFkbT1mdW5jdGlvbihrKSBzdW0ocHJvYnMqKHByb2JzPGspKTw9YWxwaGENCmFkbXZlYz1WZWN0b3JpemUoYWRtKQ0KIyB3YWVobGUgbWF4aW1hbGVuIHp1bGFlc3NpZ2VuIFdlcnQgaW4gY3ZhbHMNCmNfYWw9Y3ZhbHNbbWF4KHdoaWNoKHNhcHBseShjdmFscywgYWRtdmVjKSkpXQ0KIyBEZWZpbml0aW9uIGRlciBHdWV0ZWZ1bmt0aW9uDQojIGxlaG5lIEhfMDogcD1wXzAgYWIsIGZhbGxzIFdrZWl0IGZ1ZXIgV2VydCBrbGVpbmVyIGFscyBjX2FsIGlzdA0KR19tPWZ1bmN0aW9uKHApew0KICBwcm9ic3A9ZGJpbm9tKDA6bixuLHApDQogIHN1bShwcm9ic3AqKHByb2JzPGNfYWwpKQ0KfQ0KR19tdmVjPVZlY3Rvcml6ZShHX20pDQojIHplaWNobmUgZGllIEd1ZXRlZnVua3Rpb24NCnBsb3QoR19tdmVjLCBtYWluPXBhc3RlKCJHw7x0ZWZ1bmt0aW9uIHp3ZWlzZWl0aWdlciBNUFZXLUJpbm9taWFsdGVzdCwgbj0iLG4pLCB4bGFiPSJwIiwgeWxhYj0iRyhwKSIsIHhsaW09YygwLDEpLCB5bGltPWMoMCwxKSxsd2Q9MikNCmFibGluZShoPWFscGhhLCBjb2w9ImJsdWUiKTsgYWJsaW5lKHY9cF8wLCBjb2w9InJlZCIpDQp0ZXh0KHBfMCwgMC43LCBwb3M9MiwgZXhwcmVzc2lvbihwWzBdKSwgY29sPSJyZWQiKQ0KdGV4dCgwLCBhbHBoYSwgcG9zPTMsIGV4cHJlc3Npb24oYWxwaGEpLCBjb2w9ImJsdWUiKQ0KYGBgDQoNCiMjIyBLb25zdHJ1a3Rpb24gZGVzIG9wdGltYWxlbiB6d2Vpc2VpdGlnZW4gVGVzdHMNCg0KRGllIG9iaWdlbiBUZXN0cyBoYWJlbiB6d2VpIGtyaXRpc2NoZSBXZXJ0ZSAkY18xPGNfMiQuIFdpciBsZWhuZW4gJEhfMCQgYWIsIGZhbGxzICRTX248Y18xJCBvZGVyICRTX24+Y18yJCBnaWx0LiBXaXIga8O2bm5lbiBzb2xjaGUgVGVzdHMgcmFuZG9taXNpZXJlbiwgaW5kZW0gd2lyIGltIEZhbGwgJFNfbj1jXzEkIGRpZSBOdWxsaHlwb3RoZXNlICRIXzAkIG1pdCBXYWhyc2NoZWlubGljaGtlaXQgJFxnYW1tYV8xJCBhYmxlaG5lbiB1bmQgaW0gRmFsbCAkU19uPWNfMiQgZGllIE51bGxoeXBvdGhlc2UgJEhfMCQgbWl0IFdhaHJzY2hlaW5saWNoa2VpdCAkXGdhbW1hXzIkIGFibGVobmVuLiBTb2xjaGUgVGVzdHMga2FubiBtYW4gbWl0IGVpbmVyIEZ1bmt0aW9uICRccGhpOlx7MCwgXGxkb3RzLCBuXH1cdG8gWzAsMV0kIGJlc2NocmVpYmVuLCBkaWUgamVkZXIgbcO2Z2xpY2hlbiBCZW9iYWNodHVuZyBkaWUgV2FocnNjaGVpbmxpY2hrZWl0IHp1b3JkbmV0LCBtaXQgZGVyIG1hbiBkaWUgR2VnZW5oeXBvdGhlc2UgYWt6ZXB0aWVydC4NCg0KRGVyIG9wdGltYWxlIFRlc3QgZsO8ciBkYXMgendlaXNlaXRpZ2UgVGVzdHByb2JsZW0gd2lyZCBpbSBCdWNoIHZvbiBMZWhtYW5uIHVuZCBSb21hbm8gaW0gQmVpc3BpZWwgNC4yLjEgYmVzY2hyaWViZW4uIEVyIGlzdCB2b24gZGVyIG9iaWdlbiBGb3JtLiBEZXIgVGVzdCB3ZXJkZSBkdXJjaCBkaWUgRnVua3Rpb24gJFxwaGkkIGJlc2NocmllYmVuLiBEaWUgS29uc3RhbnRlbiAkY18xLGNfMiwgXGdhbW1hXzEsXGdhbW1hXzIkIHNpbmQgZWluZGV1dGlnIGJlc3RpbW10IMO8YmVyIGRpZSB6d2VpIEdsZWljaHVuZ2VuDQoNCiQkDQpcbWF0aGJiIEVfe3BfMH1bXHBoaV09XGFscGhhIFwgLCBccXF1YWQgXG1hdGhiYiBFX3twXzB9W1xwaGkgXGNkb3QgU19uXT1cYWxwaGFcY2RvdCAgbiBwXzAgXCAuDQokJA0KDQpEaWUgZXJzdGUgR2xlaWNodW5nIGZvcmRlcnQsIGRhc3MgZGVyIFRlc3QgZGFzIE5pdmVhdSAkXGFscGhhJCBhdXNzY2jDtnBmdC4gRXMgc29sbCBhbHNvICRHX1xwaGkocF8wKT1cYWxwaGEkIGdlbHRlbi4gRGllIHp3ZWl0ZSBHbGVpY2h1bmcgbGVndCBkZW4gRXJ3YXJ0dW5nc3dlcnQgdm9uICRTX24kIGF1ZiBkZW0gQWJsZWhudW5nc2JlcmVpY2ggZmVzdC4gRXMgc29sbHRlIHNpY2ggZGVyIG5hdMO8cmxpY2hlIFdlcnRlICRcYWxwaGFcY2RvdCBuIHBfMCQgZXJnZWJlbi4NCg0KRsO8ciBmZXN0ZXMgJGNfMSxjXzIkIHNpbmQgZGllIG9iaWdlbiBHbGVpY2h1bmdlbiBsaW5lYXJlIEdsZWljaHVuZ2VuIGbDvHIgJFxnYW1tYV8xLFxnYW1tYV8yJC4gRXMgZ2lsdCBuw6RtbGljaA0KDQokJA0KXGJlZ2lue3NwbGl0fQ0KXGdhbW1hXzEgXG1hdGhiYiBQX3twXzB9W1Nfbj1jXzFdK1xnYW1tYV8yIFxtYXRoYmIgUF97cF8wfVtTX249Y18yXSY9XGFscGhhLVxtYXRoYmIgUF97cF8wfVtTX248Y18xIFx0ZXh0eyBvZGVyIH0gU19uPmNfMl1cXA0KXGdhbW1hXzEgY18xXG1hdGhiYiBQX3twXzB9W1Nfbj1jXzFdK1xnYW1tYV8yIGNfMlxtYXRoYmIgUF97cF8wfVtTX249Y18yXSY9IFxhbHBoYSBuIHBfMC1cbWF0aGJiIEVfe3BfMH1bU19uIFxjZG90IDFfe1x7U19uPGNfMSBcdGV4dHsgb2RlciB9IFNfbj5jXzJcfX1dDQpcZW5ke3NwbGl0fQ0KJCQNCg0KRGEgZGllIEtvbnN0YW50ZW4gJDBcbGUgY18xPGNfMlxsZSBuJCB1bmQgJDBcbGUgXGdhbW1hXzEsXGdhbW1hXzI8MSQgZHVyY2ggb2JpZ2UgR2xlaWNodW5nZW4gZWluZGV1dGlnIGJlc3RpbW10IHNpbmQsIGthbm4gbWFuIHNpZSBkdXJjaCAiQXVzcHJvYmllcmVuIiBlcmhhbHRlbi4gSGllcnp1IGRpZW50IGRhcyBmb2xnZW5kZSBQcm9ncmFtbS4gRXMga2FubiBmw7xyIGdyb8OfZSBTdGljaHByb2JlbiBub2NoIG9wdGltaWVydCB3ZXJkZW4uDQoNCmBgYHtyfQ0Kbj0xNjsgcF8wPTAuNzsgYWxwaGE9MC4wNQ0KIyBwcm9iaWVyZSBhbGxlICghKSBXYWhsZW4gYzE8YzINCiMgZWluZmFjaCB6dSBwcm9ncmFtbWllcmVuDQojIGFiZXIgZnVlciBob2hlcyBuIHNlaHIgaW5lZmZpemllbnQNCmZvciAoYzEgaW4gMDpuKXsNCiAgZm9yIChjMiBpbiAoYzErMSk6bil7DQogICAgIyBXa2VpdCBhdWYgQWJsZWhudW5nc2JlcmVpY2gNCiAgICBwPShwYmlub20oYzEtMSxuLHBfMCkgKyAxLXBiaW5vbShjMixuLHBfMCkpDQogICAgIyBFcndhcnR1bmdzd2VydCBhdWYgQWJsZWhudW5nc2JlcmVpY2gNCiAgICBwcm9icz1kYmlub20oMDpuLCBuLCBwXzApDQogICAgZT1zdW0oKDA6bikqcHJvYnMqKCgoMDpuKTxjMSkrKCgwOm4pPmMyKSkpDQogICAgaWYgKChwPmFscGhhKSB8fCAoZT5hbHBoYSpuKnBfMCkpIG5leHQNCiAgICAjIGJlc3RpbW1lIFdrZWl0ZW4gZnVlciBNdWVuend1cmYgYmVpIGtyaXRpc2NoZW4gV2VydGVuDQogICAgcDE9ZGJpbm9tKGMxLG4scF8wKTsgcDI9ZGJpbm9tKGMyLG4scF8wKQ0KICAgICMgbG9lc2UgZGllIE1hdHJpeGdsZWljaHVuZyBBKmdhbT1iDQogICAgYj1jKGFscGhhLXAsIGFscGhhKm4qcF8wLWUpDQogICAgQT1tYXRyaXgoYyhwMSxjMSpwMSxwMixjMipwMiksIG5yb3cgPSAyKQ0KICAgICMgaWdub3JpZXJlIHp1IGdyb8OfZSBXZXJ0ZSBnYW1fMSwgZ2FtXzINCiAgICAjIGRpZXNlIGVya2VubnQgbWFuIGFuIHNlaHIga2xlaW5lciBEZXRlcm1pbmFudGUNCiAgICBwcmVjPS5NYWNoaW5lJGRvdWJsZS5lcHMNCiAgICBpZiAoYWJzKGRldChBKSk8MTAqcHJlYykgbmV4dA0KICAgIGdhbT1zb2x2ZShBLGIpDQogICAgIyBGYWxscyBnYW1fMSwgZ2FtXzIgV2tlaXRlbiBzaW5kLCBoYWJlbiB3aXIgZGllDQogICAgIyBrb3JyZWt0ZW4gUGFyYW1ldGVyIGdlZnVuZGVuDQogICAgIyBBdXNnYWJlIGRlciBrb3JyZWt0ZW4gV2VydGUNCiAgICBpZiAoc3VtKGdhbT49MCAmIGdhbSA8MSk9PTIpIHsNCiAgICAgIHByaW50KGMoYzEsYzIpKQ0KICAgICAgcHJpbnQoZ2FtKQ0KICAgIH0NCiAgfQ0KfQ0KYGBgDQoNCk1pdCBkZW4gb2JlbiBiZXN0aW1tdGVuIFBhcmFtZXRlcm4gZGVzIG9wdGltYWxlbiBUZXN0cyBrYW5uIGRpZSBHw7x0ZWZ1bmt0aW9uIGdlemVpY2huZXQgd2VyZGVuLg0KDQpgYGB7cn0NCiMgbGVobmUgSF8wOiBwPXBfMCBhYiwgZmFsbHMgU19uPGMxIG9kZXIgU19uPmMyDQojIHJhbmRvbWlzaWVyZSBUZXN0IG1pdCBXa2VpdGVuIGdhbW1hMSwgZ2FtbWEyDQojIGRpZSBmb2xnZW5kZW4gUGFyYW1ldGVyIHd1cmRlbiBtaXQgZGVtIG9iaWdlbiBQcm9ncmFtbSBiZXN0aW1tdA0Kbj0xNjsgYzE9NzsgYzI9MTQ7IGcxPTAuODUxNDg2NDg7IGcyPTAuMDEzMjI3ODkNCiMgRGVmaW5pdGlvbiBkZXIgR3VldGVmdW5rdGlvbg0KR19vcHQ9ZnVuY3Rpb24ocCkgcGJpbm9tKGMxLTEsIG4scCkgKyAoMS1wYmlub20oYzIsbixwKSkgKyBnMSpkYmlub20oYzEsbixwKStnMipkYmlub20oYzIsbixwKQ0KIyBHdWV0ZWZ1bmt0aW9uIHplaWNobmVuDQpwbG90KEdfb3B0LCBtYWluPXBhc3RlKCJHw7x0ZWZ1bmt0aW9uIHp3ZWlzZWl0aWdlciBCaW5vbWlhbHRlc3QsIG49IixuKSwgeGxhYj0icCIsIHlsYWI9IkcocCkiLCB4bGltPWMoMCwxKSwgbHdkPTIsIGNvbD0iZ3JheSIpDQphYmxpbmUoaD1hbHBoYSwgY29sPSJibHVlIik7IGFibGluZSh2PXBfMCwgY29sPSJyZWQiKQ0KdGV4dChwXzAsIDAuNywgcG9zPTIsIGV4cHJlc3Npb24ocFswXSksIGNvbD0icmVkIikNCnRleHQoMCwgYWxwaGEsIHBvcz0zLCBleHByZXNzaW9uKGFscGhhKSwgY29sPSJibHVlIikNCnRleHQoMCwwLjcsIHBvcz00LCAiT1BUSSIsIGNvbD0iZ3JheSIpDQpgYGANCg0KIyMjIFZlcmdsZWljaCBkZXIgR8O8dGVmdW5rdGlvbmVuDQoNCldpciB2ZXJnbGVpY2hlbiBkaWUgR8O8dGVmdW5rdGlvbiBkZXIgZHJlaSBUZXN0cy4gSGllcnp1IHZlcndlbmRlbiB3aXIgZGllIG5pY2h0IHJhbmRvbWlzaWVydGUgVmFyaWFudGUgZGVzIG9wdGltYWxlbiBUZXN0cy4NCg0KYGBge3J9DQojIGxlaG5lIEhfMDogcD1wXzAgYWIsIGZhbGxzIFNfbjxjMSBvZGVyIFNfbj5jMg0KYzE9NzsgYzI9MTQ7IGcxPTAuODUxNDg2NDg7IGcyPTAuMDEzMjI3ODkNCkdfb3B0PWZ1bmN0aW9uKHApIHBiaW5vbShjMS0xLCBuLHApICsgKDEtcGJpbm9tKGMyLG4scCkpIA0KIysgZzEqZGJpbm9tKGMxLG4scCkrZzIqZGJpbm9tKGMyLG4scCkNCiMgKFp1c2F0enRlcm0gZnVlciByYW5kb21pc2llcnRlIFZlcnNpb24pDQojIHplaWNobmUgZGllIGRyZWkgbmljaHQgcmFuZG9taXNpZXJ0ZW4gR3VldGVmdW5rdGlvbmVuDQpwbG90KEdfbXZlYywgbWFpbj1wYXN0ZSgiR8O8dGVmdW5rdGlvbiB6d2Vpc2VpdGlnZXIgQmlub21pYWx0ZXN0LCBuPSIsbiksIHhsYWI9InAiLCB5bGFiPSJHKHApIiwgeGxpbT1jKDAsMSksIGx3ZD0yLCBjb2w9ImJsYWNrIikNCmFibGluZShoPWFscGhhLCBjb2w9ImJsdWUiKTsgYWJsaW5lKHY9cF8wLCBjb2w9InJlZCIpDQp0ZXh0KHBfMCwgMC43LCBwb3M9MiwgZXhwcmVzc2lvbihwWzBdKSwgY29sPSJyZWQiKQ0KdGV4dCgwLCBhbHBoYSwgcG9zPTMsIGV4cHJlc3Npb24oYWxwaGEpLCBjb2w9ImJsdWUiKQ0KdGV4dCgwLDAuOSwgcG9zPTQsICJUT1NUIiwgY29sPSJicm93biIpDQp0ZXh0KDAsMC44LCBwb3M9NCwgIk1QVlQiLCBjb2w9ImJsYWNrIikNCnRleHQoMCwwLjcsIHBvcz00LCAiT1BUSSIsIGNvbD0iZ3JheSIpDQpjdXJ2ZShHX3Rvc3QoeCksIGFkZD1UUlVFLCBjb2w9ImJyb3duIiwgbHdkPTIpDQpjdXJ2ZShHX29wdCh4KSwgYWRkPVRSVUUsIGNvbD0iZ3JheSIsIGx3ZD0yKQ0KYGBgDQoNCkVzIGlzdCBhdWNoIGluc3RydWt0aXYsIGRpZSBHw7x0ZWZ1bmt0aW9uIGRlcyByYW5kb21pc2llcnRlbiBvcHRpbWFsZW4gVGVzdHMgenUgemVpY2huZW4uIERhbm4ga2FubiBtYW4gZXJrZW5uZW4sIGRhc3MgZGVyIE1QVlQtVGVzdCB0ZWlsd2Vpc2UgZWluZSBow7ZoZXJlIEfDvHRlIGFscyBkZXIgb3B0aW1hbGUgVGVzdCBoYWJlbiBrYW5uLiBEaWVzIGlzdCBrZWluIFdpZGVyc3BydWNoLCB3ZWlsIGRpZSBPcHRpbWFsaXTDpHRzYXVzc2FnZSBudXIgZsO8ciB1bnZlcmbDpGxzY2h0ZSBUZXN0cyBnaWx0LiBEZXIgTVBWVC1UZXN0IGlzdCBhYmVyIHZlcmbDpGxzY2h0Lg0KDQojIyMgendlaXNlaXRpZ2VyIEJpbm9taWFsdGVzdCBpbiBSDQoNCkRlciBSLUJlZmVobCAqYmlub20udGVzdCgpKiBlcmxhdWJ0IGF1Y2ggendlaXNlaXRpZ2UgQmlub21pYWx0ZXN0cy4NCg0KYGBge3J9DQpuPTUxMDQwMDsgaz0zMzQgIyBHZWJ1cnRzdGFna2luZGVyIDI5LiBGZWJydWFyIGluIE7DvHJuYmVyZw0KcF8wPSg0KjM2NSsxKV4oLTEpOyBhbHBoYT0wLjA1DQpiaW5vbS50ZXN0KGssbixwXzAsIGFsdD0idHdvLnNpZGVkIiwgY29uZi5sZXZlbD0xLWFscGhhKQ0KYGBgDQoNCkluICpiaW5vbS50ZXN0KCkqIHNpbmQgZGFzIFRPU1QtVmVyZmFocmVuIHVuZCBkYXMgTVBWVC1WZXJmYWhyZW4gaW1wbGVtZW50aWVydC4gRGFzIFRPU1QtVmVyZmFocmVuIGVyaMOkbHQgbWFuLCBpbiBkZW0gbWFuIGRhcyBLb25maWRlbnppbnRlcnZhbGwgZsO8ciBkaWUgVGVzdGVudHNjaGVpZHVuZyB2ZXJ3ZW5kZXQuIE1hbiBha3plcHRpZXJ0ICRIXzAkLCBmYWxscyAkcF8wJCBpbSBLb25maWRlbnppbnRlcnZhbGwgZsO8ciAkcCQgbGllZ3QuIERhcyBNUFZULVZlcmZhaHJlbiBlcmjDpGx0IG1hbiwgaW4gZGVtIGbDvHIgZGllIFRlc3RlbnRzY2hlaWR1bmcgZGVuICRwJC1XZXJ0IHZlcndlbmRldC4gTWFuIGxlaG50ICRIXzAkIGFiLCBmYWxscyAkcChrKVxsZSBcYWxwaGEkIGdpbHQuDQoNCkluIHVuc2VyZW0gQmVpc3BpZWwgZsO8aHJlbiBiZWlkZSBUZXN0cyBhdWYgZGllc2VsYmUgRW50c2NoZWlkdW5nLiBEaWVzIGlzdCBhdWNoIGRlciBGYWxsIGbDvHIgZGVuIG9wdGltYWxlbiBUZXN0LCB3ZWxjaGVyIGluICpiaW5vbS50ZXN0KCkqIG5pY2h0IGltcGxlbWVudGllcnQgaXN0LiBUYXRzw6RjaGxpY2gga8O2bm50ZSBtYW4gaW4gdW5zZXJlbSBCZWlzcGllbCBhdWNoIGVpbmVuICR0JC1UZXN0IG9kZXIgZWluZW4gJHokLVRlc3QgdmVyd2VuZGVuLCB3ZWlsIHdlZ2VuIGRlciBob2hlbiBTdGljaHByb2Jlbmdyw7bDn2UgZGllIE5vcm1hbGFwcHJveGltYXRpb24gZWluZSBndXRlIE7DpGhlcnVuZyBpc3QgKGJlYWNodGUgJG4gcF8wKDEtcF8wKT4xMCQpLiBEaWVzIFZlcmZhaHJlbiBpc3Qgd2VpdGVyIHVudGVuIGFtIEJlaXNwaWVsIGVpbmVzIMOEcXVpdmFsZW56dGVzdHMgYmVzY2hyaWViZW4uDQoNCiMjIMOEcXVpdmFsZW56dGVzdHMNCg0KQmVpIMOEcXVpdmFsZW56dGVzdHMgdW50ZXJzdWNodCBtYW4gZGFzIEh5cG90aGVzZW5wYWFyLg0KDQokJA0KSF8wIDogcFxsZSBwXzEgXHRleHR7IG9kZXIgfSBwXGdlIHBfMiBccXF1YWQgSF8xOnBfMTxwPHBfMiAgDQokJA0KDQpXaXIgYmVzcHJlY2hlbiwgd2llIHNvbGNoZSBUZXN0cyBkdXJjaGdlZsO8aHJ0IHdlcmRlbiBrw7ZubmVuLiBFcyBpc3QgbmljaHQgc2Nod2VyLCBoaWVyYXVzIFRlc3RzIGF1ZiBJbsOkcXVpdmFsZW56IHp1IGVudHdpY2tlbG4uDQoNCiMjIyBUT1NULcOEcXVpdmFsZW56dGVzdA0KDQpCZWltIFRPU1QtVmVyZmFocmVuIChUd28gT25lLVNpZGVkIFRlc3RzKSB0ZXN0ZW4gd2lyICRIXzBeeygxKX06cFxsZSBwXzEkIGdlZ2VuICRIXzFeeygxKX06IHA+cF8xJCB1bmQgZGFubiAkSF8wXnsoMil9OnBcZ2UgcF8yJCBnZWdlbiAkSF8xXnsoMil9OiBwPHBfMiQsIGpld2VpbHMgenVtIE5pdmVhdSAkXGFscGhhJC4gV2lyIGxlaG5lbiAkSF8wJCBhYiBnZW5hdSBkYW5uIHdlbm4gJEhfMF57KDEpfSQgYWJnZWxlaG50IHdlcmRlbiBrYW5uIHVuZCB3ZW5uICRIXzBeeygyKX0kIGFiZ2VsZWhudCB3ZXJkZW4ga2Fubi4gRGllcyBlcmdpYnQgZWluZW4gTml2ZWF1LSRcYWxwaGEkLVRlc3QgZsO8ciBkYXMgb2JpZ2UgendlaXNlaXRpZ2UgVGVzdHByb2JsZW0uIERpZXNlciBUZXN0IGlzdCBhc3ltcHRvdGlzY2ggb3B0aW1hbC4NCg0KRGVyIFRlc3Qgd2lyZCDDpGhubGljaCB3aWUgYmVpbSBUT1NULVZlcmZhaHJlbiBmw7xyIGRlbiB6d2Vpc2VpdGlnZW4gQmlub21pYWx0ZXN0IGtvbnN0cnVpZXJ0LiBXaXIgbGVobmVuICRIXzAkIGFiLCBmYWxscyAkY18xPFNfbjxjXzIkIGdpbHQuIFdpciBiZXJlY2huZW4gZGllIGtyaXRpc2NoZW4gR3JlbnplbiAkY18xJCB1bmQgJGNfMiQuDQoNCmBgYHtyfQ0Kbj0xMDA7IHBfMT0wLjY7IHBfMj0wLjg7IGFscGhhPTAuMDUNCiMgYzEga2xlaW5zdGVzICgxLWFscGhhKS1RdWFudGlsIHZvbiBCKG4scF8xKQ0KIyBjMiBncm9lc3N0ZXMgYWxwaGEtUXVhbnRpbCB2b24gQihuLHBfMikNCmNfMT1taW4od2hpY2gocGJpbm9tKDA6bixuLHBfMSk+PTEtYWxwaGEpKS0xDQpjXzI9bWF4KHdoaWNoKHBiaW5vbSgoLTEpOihuLTEpLG4scF8yKTw9YWxwaGEpKS0xDQpjKGNfMSxjXzIpDQoNCmBgYA0KDQpGYWxscyBmw7xyIGRpZSBrcml0aXNjaGVuIFdlcnRlICRjXzE8Y18yJCBnaWx0LCBpc3QgZGVyIFRPU1QtVGVzdCBhbndlbmRiYXIuIERpZXMgaXN0IGbDvHIgaGlucmVpY2hlbmQgZ3Jvw59lIFN0aWNocHJvYmVuIGRlciBGYWxsLg0KDQpgYGB7cn0NCm49MTAwOyBwXzE9MC42OyBwXzI9MC44OyBhbHBoYT0wLjA1DQojIGJlc3RpbW1lIGtyaXRpc2NoZSBXZXJ0ZSB3aWUgb2Jlbg0KY18xPTY4OyBjXzI9NzMNCiMgbGVobmUgSDAgYWIsIGZhbGxzIGNfMTxTX248Y18yIGdpbHQNCkdfdG9zdD1mdW5jdGlvbihwKSB7DQogIHZhbHM9ZGJpbm9tKDA6biwgbiwgcCkNCiAgc3VtKHZhbHMqKCgoMDpuKT5jXzEpICYgKCgwOm4pPGNfMikpKQ0KfQ0KR190b3N0dj1WZWN0b3JpemUoR190b3N0KQ0KIyB6ZWljaG5lIEd1ZXRlZnVua3Rpb24NCnBsb3QoR190b3N0diwgbWFpbj1wYXN0ZSgiR8O8dGVmdW5rdGlvbiBUT1NULcOEcXVpdmFsZW56dGVzdCwgbj0iLG4pLCB4bGFiPSJwIiwgeWxhYj0iRyhwKSIsIHhsaW09YygwLDEpLCBsd2Q9MikNCiMgemVpY2huZSBOaXZlYXUtYWxwaGEtTGluaWUNCmFibGluZShoPWFscGhhLCBjb2w9ImJsdWUiKQ0KdGV4dCgwLCBhbHBoYSwgcG9zPTMsIGV4cHJlc3Npb24oYWxwaGEpLCBjb2w9ImJsdWUiKQ0KIyB6ZWljaG5lIHAxLCBwMg0KYWJsaW5lKHY9cF8xLCBjb2w9InJlZCIpOyBhYmxpbmUodj1wXzIsIGNvbD0icmVkIikNCnRleHQocF8xLCAwLjcsIHBvcz0yLCBleHByZXNzaW9uKHBbMV0pLCBjb2w9InJlZCIpDQp0ZXh0KHBfMiwgMC43LCBwb3M9MiwgZXhwcmVzc2lvbihwWzFdKSwgY29sPSJyZWQiKQ0KDQpgYGANCg0KIyMjIE9wdGltYWxlciDDhHF1aXZhbGVuenRlc3QNCg0KRsO8ciBkYXMgb2JpZ2UgVGVzdHByb2JsZW0gZ2lidCBlcyBlaW5lbiBnbGVpY2htw6TDn2lnIGJlc3RlbiBOaXZlYXUtJFxhbHBoYSQtVGVzdC4gV2lyIGxlaG5lbiAkSF8wJCBhYiwgZmFsbHMgJGNfMTxTX248Y18yJCBnaWx0LiBXaXIgYWt6ZXB0aWVyZW4gJEhfMCQsIGZhbGxzICRTX248Y18xJCBvZGVyICRTX24+Y18yJCBnaWx0LiBJbSBGYWxsICRTX249Y18xJCBsZWhuZW4gd2lyICRIXzAkIG1pdCBXYWhyc2NoZWlubGljaGtlaXQgJFxnYW1tYV8xJCBhYiwgaW0gRmFsbCAkU19uPWNfMiQgbGVobmVuIHdpciAkSF8wJCBtaXQgV2FocnNjaGVpbmxpY2hrZWl0ICRcZ2FtbWFfMiQgYWIuDQoNCkVzIGJlemVpY2huZSAkcFxtYXBzdG8gRyhwKSQgZGllIEfDvHRlZnVua3Rpb24gZGVzIG9wdGltYWxlbiBUZXN0cy4gRGFubiBnZWx0ZW4gJEcocF8xKT1cYWxwaGEkIHVuZCAkRyhwXzIpPVxhbHBoYSQuIERpZXNlIGJlaWRlbiBHbGVpY2h1bmdlbiBsZWdlbiBkaWUgS29uc3RhbnRlbiAkMFxsZSBjXzE8Y18yXGxlIG4kIHVuZCAkMFxsZSBcZ2FtbWFfMSxcZ2FtbWFfMjwxJCBlaW5kZXV0aWcgZmVzdC4gU2llIGvDtm5uZW4gZHVyY2ggIkF1c3Byb2JpZXJlbiIgYmVzdGltbXQgd2VyZGVuLg0KDQpEYXMgUi1QYWtldCAqRVFVSVZOT05JTkYqIGltcGxlbWVudGllcnQgZGllIEFsZ29yaXRobWVuIGF1cyBkZW0gQnVjaCB2b24gV2VsbGVrIGbDvHIgw4RxdWl2YWxlbnp0ZXN0cy4gRGFzIFBha2V0IGthbm4gw7xiZXIgKlBhY2thZ2VzL0luc3RhbGwqIGltIHJlY2h0ZW4gdW50ZXJlbiBGZW5zdGVyIGluc3RhbGxpZXJ0IHdlcmRlbi4gRGVyIEJlZmVobCBmw7xyIGRlbiBCaW5vbWlhbC3DhHF1aXZhbGVuenRlc3QgaXN0ICpiaTFzdCgpKi4gRGVyIEFsZ29yaXRobXVzIGZ1bmt0aW9uaWVydCBudXIgZsO8ciBoaW5yZWljaGVuZCBrbGVpbmUgU3RpY2hwcm9iZW4uDQoNCmBgYHtyfQ0KbGlicmFyeShFUVVJVk5PTklORikNCmJpMXN0KDAuMDUsIDEwMCwgLjYsIC44KQ0KYGBgDQoNCkVzIGVyZ2ViZW4gc2ljaCBkaWVzZWxiZW4ga3JpdGlzY2hlbiBXZXJ0ZSAkY18xLGNfMiQgd2llIG9iZW4uIERhcyBQcm9ncmFtbSBnaWJ0IGF1Y2ggZGllIEfDvHRlIGRlcyBUZXN0cyBiZWkgJHA9KHBfMStwXzIpLzIkIGFuLiBGw7xyICpQT1dOT05SRCogd2lyZCBkaWUgbmljaHQgcmFuZG9taXNpZXJ0ZSBWZXJzaW9uIGRlcyBUZXN0cyB2ZXJ3ZW5kZXQsIGJlaSAqUE9XKiB3aXJkIGRpZSByYW5kb21pc2llcnRlIFZlcnNpb24gZGVzIFRlc3RzIHZlcndlbmRldC4NCg0KQW5zdGF0dCBkYXMgb2JpZ2UgUHJvZ3JhbW1wYWtldCB6dSB2ZXJ3ZW5kZW4sIGthbm4gbWFuIGRpZXNlIEZ1bmt0aW9uIGF1Y2ggc2VsYnN0IHByb2dyYW1taWVyZW4sIGluZGVtIG1hbiBkZW4gQ29kZSBmw7xyIGRlbiBvcHRpbWFsZW4gendlaXNlaXRpZ2VuIEJpbm9taWFsdGVzdCBhbnBhc3N0Lg0KDQojIyMgT3B0aW1hbGVyIMOEcXVpdmFsZW56LVRlc3QgZsO8ciBub3JtYWx2ZXJ0ZWlsdGUgWnVmYWxsc2dyw7bDn2VuDQoNCldpciBiZXNjaHJlaWJlbiBkZW4gb3B0aW1hbGVuIMOEcXVpdmFsZW56dGVzdCBmw7xyIGRlbiBFcndhcnR1bmdzd2VydCBlaW5lciBub3JtYWx2ZXJ0ZWlsdGVuIFp1ZmFsbHNncsO2w59lIGJlaSBiZWthbm50ZXIgVmFyaWFuei4gRGVyIG9wdGltYWxlIEluw6RxdWl2YWxlbnp0ZXN0IGthbm4gYW5hbG9nIGVudHdpY2tlbHQgd2VyZGVuLiBEYXNzZWxiZSBnaWx0IGbDvHIgZGllIGtsYXNzaXNjaGVuIGVpbnNlaXRpZ2VuIHVuZCB6d2Vpc2VpdGlnZW4gVGVzdHMgYXVmIEVyd2FydHVuZ3N3ZXJ0IGVpbmVyIE5vcm1hbHZlcnRlaWx1bmcgYmVpIGJla2FubnRlciBWYXJpYW56ICgkeiQtVGVzdHMpLg0KDQpTZWllbiAkWF8xLCBcbGRvdHMsIFhfbiQgdW5hYmjDpG5naWdlIHdpZSAkTihcbXUsXHNpZ21hXjIpJCB2ZXJ0ZWlsdGUgWnVmYWxsc3ZhcmlhYmxlbi4gV2lyIG5laG1lbiBhbiwgZGFzcyAkXG11JCB1bmJla2FubnQgaXN0IHVuZCBkYXNzICRcc2lnbWFeMiQgYmVrYW5udCBpc3QuIFdpciB3b2xsZW4gYXVmIGRhcyBIeXBvdGhlc2VucGFhcg0KDQokJA0KSF8wOnxcbXUtXG11XzB8XGdlIFxkZWx0YSBccXF1YWQgSF8xOiB8XG11LVxtdV8wfDxcZGVsdGENCiQkIHRlc3Rlbi4gSGllcnp1IHZlcndlbmRlbiB3aXIgZGllIFRlc3QtU3RhdGlzdGlrDQoNCiQkDQpUX249KFlfbileMiBcICwgXHFxdWFkIFlfbj1cZnJhY3tcb3ZlcmxpbmV7WH1fbi1cbXVfMH17XHNpZ21hL1xzcXJ0e259fSBcICwNCiQkIG1pdCAkXG92ZXJsaW5le1h9X249KFhfMStcbGRvdHMrWF9uKS9uJCBkYXMgYXJpdGhtZXRpc2NoZSBNaXR0ZWwgZGVyIFN0aWNocHJvYmUuIFdpciBsZWhuZW4gJEhfMCQgYWIsIGZhbGxzICRUX24kIHp1IGtsZWluIGlzdC4gRXMgaGFuZGVsdCBzaWNoIGFsc28gdW0gZWluZW4gbGlua3NzZWl0aWdlbiBUZXN0IGbDvHIgZGVuIFBhcmFtZXRlciAkfFxtdS1cbXVfMHwkLg0KDQpEaWUgWnVmYWxsc2dyw7bDn2UgJFRfbiQgaXN0IGRhcyBRdWFkcmF0IGRlciBadWZhbGxzZ3LDtsOfZSAkWV9uJC4gRGllIFp1ZmFsbHNncsO2w59lICRZX24kIGlzdCBub3JtYWx2ZXJ0ZWlsdCBtaXQgRXJ3YXJ0dW5nc3dlcnQgJChcbXUtXG11XzApLyhcc2lnbWEvXHNxcnR7bn0pJCB1bmQgVmFyaWFueiAkMSQuIERpZSBWZXJ0ZWlsdW5nIHZvbiAkVF9uJCBoZWnDn3QgbmljaHR6ZW50cmFsZSAkXGNoaV4yJC1WZXJ0ZWlsdW5nIG1pdCBlaW5lbSBGcmVpaGVpdHNncmFkIHVuZCBOaWNodHplbnRyYWxpdMOkdHNwYXJhbWV0ZXINCg0KJCQNClxsYW1iZGE9XGxlZnQoXGZyYWN7XG11LVxtdV8wfXtcc2lnbWEvXHNxcnR7bn19XHJpZ2h0KV4yDQokJCBXaXIgbGVobmVuIGFsc28gJEhfMCQgYWIsIGZhbGxzICRUX248IHEkIGdpbHQsIG1pdCAkcSQgZGFzICRcYWxwaGEkLVF1YW50aWwgZGllc2VyIFZlcnRlaWx1bmcuIERpZSBWZXJ0ZWlsdW5nIGlzdCBpbiBSIGltcGxlbWVudGllcnQuDQoNCldpciB3ZW5kZW4gZGllc2VuIMOEcXVpdmFsZW56LVRlc3QgYXVmIGRpZSBGcmFnZSBuYWNoIGRlciBXYWhyc2NoZWlubGljaGtlaXQgZsO8ciBkZW4gMjkuIEZlYnJ1YXIgYWxzIEdlYnVydHN0YWcgYW4uIERpZXMgaXN0IHp1bMOkc3NpZywgd2VpbCBiZWltIE3DvG56d3VyZiBkaWUgcmVsYXRpdmUgSMOkdWZpZ2tlaXQgZGVyIEVyZm9sZ2UgYmVpIGdyb8OfZXIgU3RpY2hwcm9iZSBpbiBndXRlciBOw6RoZXJ1bmcgbm9ybWFsdmVydGVpbHQgaXN0LiBEaWVzIGbDvGhydCBhdWYgZm9sZ2VuZGVuIENvZGUuDQoNCmBgYHtyfQ0KIyBBZXF1aXZhbGVuenRlc3QgZnVlciBub3JtYWx2ZXJ0ZWlsdGUgWnVmYWxsc2dyb2Vzc2VuDQojIEJlaXNwaWVsOiBwXzAgZnVlciBHZWJ1cnRzdGFnZSBhbSAyOS4gRmVicnVhcj8NCnBfMD0oNCozNjUrMSleKC0xKQ0KIyBEYXRlbiBhdXMgTnVlcm5iZXJnIDIwMTINCm49NTEwNDAwOyBrPTMzNA0KIyBOb3JtYWxhcHByb3hpbWF0aW9uIHp1bGFlc3NpZywgZmFsbHMgbipwXzAqKDEtcF8wKT4xMA0KbipwXzAqKDEtcF8wKQ0KIyB3YWVobGUgZnVlciBkZWx0YSByZWxhdGl2ZW4gRmVobGVyIHZvbiAxMCBQcm96ZW50DQpkZWw9cF8wKjAuMQ0KIyBhbHBoYS1RdWFudGlsIGRlciBuaWNodHplbnRyYWxlbiBjaGkyLVZlcnRlaWx1bmcNCiMgMSBGcmVpaGVpdHNncmFkIChkZiksIE5pY2h0emVudHJhbGl0YWV0c3BhcmFtZXRlciBsYW0NCmFscGhhPTAuMDUNCnNpZz1zcXJ0KHBfMCooMS1wXzApKTsgbGFtPShkZWwqc3FydChuKS9zaWcpXjINCnE9cWNoaXNxKGFscGhhLCBkZj0xLCBuY3A9bGFtKQ0KIyBXZXJ0IGRlciBUZXN0c3RhdGlzdGlrDQp4YmFyPWsvbjsgc2lnPXNxcnQocF8wKigxLXBfMCkpDQpUPSgoeGJhci1wXzApKnNxcnQobikvc2lnKV4yDQojIExlaG5lIEgwIGFiLCBmYWxscyBUPHEgDQpUOyBxDQpgYGANCg0KSW0gQmVpc3BpZWwga8O2bm5lbiB3aXIgJEhfMCQgbmljaHQgYWJsZWhuZW4uIERpZXMga8O2bm50ZSBkYXJhbiBsaWVnZW4sIGRhc3MgZGllIFN0aWNocHJvYmUgbmljaHQgZ3Jvw58gZ2VudWcgaXN0LiBFcyB3w6RyZSBudW4gaW5zdHJ1a3RpdiwgYmVpc3BpZWxzd2Vpc2UgZGllIFphaGxlbiBtZWhyZXJlciBHcm/Dn3N0w6RkdGUgenVzYW1tZW56dWZhc3Nlbi4NCg0KIyBKZW5zZWl0cyBkZXMgQmlub21pYWx0ZXN0cw0KDQojIyMgVGVzdHMgYXVmIEVyd2FydHVuZ3N3ZXJ0IGluIFINCg0KRGVyIEVpbmZhY2hoZWl0IHNvbGwgZGllIGh5cG90aGV0aXNjaGUgRnJhZ2VzdGVsbHVuZyB1bnRlcnN1Y2h0IHdlcmRlbiwgb2IgZGVyIG1pdHRsZXJlIFdlcnQgZWluZXIgTWVzc2dyw7bDn2UgYXVzIGVpbmVtIHdpZWRlcmhvbHRlbiBFeHBlcmltZW50IGdyw7bDn2VyIGFscyAkMi4xJCBpc3QuDQoNCkFuc3RhdHQgcmVhbGUgRGF0ZW4genUgdmVyd2VuZGVuLCBlcnpldWdlbiB3aXIgbWl0IGRlbSBDb21wdXRlciBEYXRlbiBhdXMgZWluZXIgTm9ybWFsdmVydGVpbHVuZy4gV2lyIHZlcmdlc3NlbiBkYW5hY2gsIHdpZSBkaWUgRGF0ZW4gZXJ6ZXVndCB3dXJkZW4uIE1pdCBkaWVzZW0gVmVyZmFocmVuIGthbm4gbWFuIHNpbXVsaWVyZW4sIHdpZSBzaWNoIGRlciBUZXN0IHZlcmjDpGx0LiBEYW1pdCBrYW5uIG1hbiBlaW4gaW50dWl0aXZlcyBWZXJzdMOkbmRuaXMgZsO8ciBkaWUgQW53ZW5kdW5nIGRlcyBUZXN0cyBlbnR3aWNrZWxuLg0KDQpgYGB7cn0NCm11MD0yLjI7IHNpZz0yOyBuPTIwMA0KIyBuIFp1ZmFsbHN6YWhsZW4gYXVzIE4obXUwLCBzaWdeMikNCng9cm5vcm0obiwgbXUwLCBzaWcpDQpgYGANCg0KV2lyIG5laG1lbiBhbiwgZGFzcyBkaWUgRGF0ZW4gaW4gZ3V0ZXIgTsOkaGVydW5nIGVpbmVyIE5vcm1hbHZlcnRlaWx1bmcgZm9sZ2VuLiBEaWVzIGthbm4genVtIEJlaXNwaWVsIG1pdCBlaW5lbSBxcS1QbG90IG9kZXIgZWluZW0gVGVzdCBhdWYgTm9ybWFsdmVydGVpbHVuZyB1bnRlcnN1Y2h0IHdlcmRlbi4NCg0KRsO8ciBkZW4gJHokLVRlc3QgYmVpIGJla2FubnRlciBWYXJpYW56IGdlaGVuIHdpciB3aWUgZm9sZ3Qgdm9yLiBBdXMgQmVxdWVtbGljaGtlaXQgdmVyd2VuZGVuIHdpciBkYXMgUGFrZXQgKkJTREEqLCB3ZWxjaGVzIMO8YmVyICpQYWNrYWdlcy9JbnN0YWxsKiBpbSByZWNodGVuIHVudGVyZW4gRmVuc3RlciBpbnN0YWxsaWVydCB3ZXJkZW4ga2Fubi4NCg0KYGBge3J9DQojIHotVGVzdA0KIyBsYWRlIFBha2V0IG1pdCB6LVRlc3QNCmxpYnJhcnkoQlNEQSkNCiMgcmVjaHRzc2VpdGlnZXIgei1UZXN0IGJlaSBiZWthbm50ZXIgVmFyaWFueiBhdWYgbXU+Mi4xIHp1bSBOaXZlYXUgYWxwaGENCmFscGhhPTAuMDUNCnoudGVzdCh4LG11PTIuMSwgc2lnbWEueD1zaWcsIGFsdD0iZ3JlYXRlciIsIGNvbmYubGV2ZWwgPSAxLWFscGhhKQ0KYGBgDQoNCkbDvHIgZGVuICR0JC1UZXN0IGJlaSB1bmJla2FubnRlciBWYXJpYW56IGdlaGVuIHdpciB3aWUgZm9sZ3Qgdm9yLg0KDQpgYGB7cn0NCiMgdC1UZXN0DQojIHJlY2h0c3NlaXRpZ2VyIHQtVGVzdCBtdT4yLjEgYmVpIHVuYmVrYW5udGVyIFZhcmlhbnogenVtIE5pdmVhdSBhbHBoYQ0KYWxwaGE9MC4wNQ0KdC50ZXN0KHgsbXU9Mi4xLCBhbHQ9ImdyZWF0ZXIiLCBjb25mLmxldmVsID0gMS1hbHBoYSkNCmBgYA0KDQojIyMgQW5wYXNzdW5nc3Rlc3RzIGluIFIgZsO8ciBkaXNrcmV0ZSBWZXJ0ZWlsdW5nZW4NCg0KQWxzIFN0YW5kYXJkLUJlaXNwaWVsIHVudGVyc3VjaGVuIHdpciBkaWUgWmllaHVuZyBkZXIgTG90dG96YWhsZW4uIERhdGVuIGhpZXJ6dSBmaW5kZW4gc2ljaCB1bnRlciBkZW0gZm9sZ2VuZGVuIFtMaW5rXShodHRwczovL3d3dy5sb3R0by5kZS9sb3R0by02YXVzNDkvc3RhdGlzdGlrL3ppZWh1bmdzaGFldWZpZ2tlaXQpLg0KDQpgYGB7cn0NCiMgSGFldWZpZ2tlaXRlbiBkZXIgTG90dG96YWhsZW4gMSBiaXMgNDkgKFN0YW5kIDQuMy4yMDI0KQ0KeD1jKDYwNyw1ODcsNjA3LDU5Myw1ODQsNjQ5LDU5NCw1NDQsNTg1LDU4Nyw2MTQsNTU3LDUyMCw1NTgsNTYwLDU4MSw1OTEsNTgyLDYwMiw1NTgsNTQ3LDYxNSw1NjUsNTg2LDYwNiw2MTgsNTg5LDU1MCw1ODksNTU5LDYxNyw2MjEsNjE4LDU3MCw1NjMsNTkxLDU4MSw2MDYsNTc1LDU3OSw1OTksNjAzLDYxMSw1NjksNTMzLDU2MSw1ODMsNTkyLDYzNikNCiMgTGlzdGUgZGVyIEhhZXVmaWdrZWl0ZW4NCngNCmBgYA0KDQpXaXIgdmVyd2VuZGVuIGRhcyBzdGF0aXN0aXNjaGUgTW9kZWxsLCBkYXNzIHNpY2ggZGllIDQ5IExvdHRvemFobGVuIHdpZSBadWZhbGxzemFobGVuIGF1cyBlaW5lciB1bmJla2FubnRlbiBnZWdlYmVuZW4gVmVydGVpbHVuZyBtaXQgNDkgV2VydGVuIHZlcmhhbHRlbi4gRGllIE51bGxoeXBvdGhlc2UgZGVzICRcY2hpXjIkLUFucGFzc3VuZ3N0ZXN0cyBsYXV0ZXQsIGRhc3MgZGllIHVuYmVrYW5udGVuIFdhaHJzY2hlaW5saWNoa2VpdGVuIGbDvHIgZGllIExvdHRvemFobGVuIGRlbiB2ZXJtdXRldGVuIFdhaHJzY2hlaW5saWNoa2VpdGVuICQxLzQ5JCBnbGVpY2hlbi4gQWxzIFRlc3RzdGF0aXN0aWsgd2lyZCBlaW5lIEdyw7bDn2UgdmVyd2VuZGV0LCB3ZWxjaGUgZGllIEFid2VpY2h1bmcgZGVyIGJlb2JhY2h0ZXRlbiBIw6R1Zmlna2VpdGVuIHZvbiBkZW4gZXJ3YXJ0ZXRldGVuIEjDpHVmaWdrZWl0ZW4gcXVhbnRpZml6aWVydC4NCg0KRGllIER1cmNoZsO8aHJ1bmcgZGVzIFRlc3RzIGluIFIgaXN0IHNlaHIgZWluZmFjaC4gV2lyIHfDpGhsZW4gZGFzIE5pdmVhdSAkXGFscGhhPTAuMDUkLg0KDQpgYGB7cn0NCiMgUmVmZXJlbnotV2FocnNjaGVpbmxpY2hrZWl0ZW4NCnAwPXJlcCgxLzQ5LDQ5KQ0KIyBjaGkyLUFucGFzc3VuZ3N0ZXN0DQpjaGlzcS50ZXN0KHgscD1wMCkNCg0KYGBgDQoNCldlaWwgZGVyICRwJC1XZXJ0IGdyw7bDn2VyIGFscyAkXGFscGhhJCBpc3QsIG3DvHNlZW4gd2lyIGRpZSBOdWxsaHlwb3RoZXNlIGFremVwdGllcmVuLiBEaWUgRGF0ZW4gbGllZmVybiBrZWluZW4gQW5sYXNzIGRhcmFuIHp1IHp3ZWlmZWxuLCBkYXNzIGplZGUgWmFobCBtaXQgZGVyIGdsZWljaGVuIFdhaHJzY2hlaW5saWNoa2VpdCBhdWZ0cml0dC4NCg0KRsO8ciBkaWUgVGVzdGVudHNjaGVpZHVuZyB3dXJkZSBkaWUgYXN5bXB0b3Rpc2NoIGV4YWt0ZSAkXGNoaV4yJC1WZXJ0ZWlsdW5nIGRlciBUZXN0c3RhdGlzdGlrIHZlcndlbmRldCwgd2VsY2hlIGF1ZiBlaW5lciBOb3JtYWxhcHByb3hpbWF0aW9uIGJlcnVodC4gQWxzIEZhdXN0cmVnZWwgZ2lsdCwgZGFzcyBkaWUgTm9ybWFsYXBwcm94aW1hdGlvbiB6dWzDpHNzaWcgaXN0LCBmYWxscyBmw7xyIGplZGUgdmVybXV0ZXRlIFdhaHJzY2hlaW5saWNoa2VpdCAkcF9pJCBkaWUgVW5nbGVpY2h1bmcgJG4gcF9pXGdlIDUkIGdpbHQsIG1pdCAkbiQgZGllIFN0aWNocHJvYmVuZ3LDtsOfZS4gSW4gdW5zZXJlbSBCZWlzcGllbCBpc3QgZGllIE5vcm1hbGFwcHJveGltYXRpb24gYWxzbyB1bnByb2JsZW1hdGlzY2guDQoNCk1hbiBrYW5uIGRpZSBleGFrdGUgVmVydGVpbHVuZyBkZXIgVGVzdHN0YXRpc3RpayBvaG5lIGdyb8OfZW4gQXVmd2FuZCBtaXQgZGVtIENvbXB1dGVyIHNpbXVsaWVyZW4uIERhbWl0IGthbm4gbWFuIHp1bSBlaW5lbiDDvGJlcnByw7xmZW4sIHdpZSBndXQgZGllIE5vcm1hbGFwcHJveGltYXRpb24gaXN0LiBadW0gYW5kZXJlbiBrYW5uIG1hbiBkZW4gQW5wYXNzdW5nc3Rlc3QgbWl0IGRlciBzaW11bGllcnRlbiBleGFrdGVuIFZlcnRlaWx1bmcgZHVyY2hmw7xocmVuLg0KDQpNYW4ga2FubiBkaWUgJFxjaGleMiQtQXBwcm94aW1hdGlvbiBmw7xyIGRpZSBhc3ltcHRvdGlzY2hlIFZlcnRlaWx1bmcgZGVyIFRlc3RzdGF0aXN0aWsgdmVyd2VuZGVuLCB1bSBlaW5lbiBhc3ltcHRvdGlzY2ggZXhha3RlbiDDhHF1aXZhbGVuenRlc3QgYXVmIEFucGFzc3VuZyB6dSBlbnR3aWNrZWxuLg0KDQojIyMgVW5hYmjDpG5naWdrZWl0c3Rlc3RzIGluIFIgZsO8ciBkaXNrcmV0ZSBWZXJ0ZWlsdW5nZW4NCg0KV2lyIGJlc2NocsOkbmtlbiB1bnMgYXVmIGRlbiBlaW5mYWNoc3RlbiBGYWxsIHZvbiBadWZhbGxzZ3LDtsOfZW4gbWl0IG51ciB6d2VpIE1lcmttYWxlbiB1bmQgYmVzcHJlY2hlbiBlaW4gZmlrdGl2ZXMgQmVpc3BpZWwuDQoNCkVzIHNvbGwgenVtIE5pdmVhdSAkXGFscGhhPTAuMDUkIHVudGVyc3VjaHQgd2VyZGVuLCBvYiBTbWFydHBob25lLU51dHp1bmcgZWluZW4gc2lnbmlmaWthbnRlbiBFaW5mbHVzcyBhdWYgc2NodWxpc2NoZSBMZWlzdHVuZ2VuIGhhdC4gSGllcnp1IHd1cmRlIGluIGRlciAxMi4gSmFocmdhbmdzc3R1ZmUgZWluZSBNYXRoZW1hdGlrLUtsYXVzdXIgZ2VzdGVsbHQsIGFuIGRlciA4NyBTY2jDvGxlcjppbm5lbiB0ZWlsZ2Vub21tZW4gaGFiZW4uIERpZSBTY2jDvGxlcjppbm5lbiBoYWJlbiDDvGJlciBlaW5lbiBaZWl0cmF1bSB2b24gZWluZW0gTW9uYXQgdm9yIGRlciBLbGF1c3VyIGlocmUgU21hcnRwaG9uZS1OdXR6dW5nc2RhdWVyIGdlbWVzc2VuLiBJaHIgS2xhdXN1cmVyZ2VibmlzIHdhciBlbnR3ZWRlciBiZXNzZXIgKEIpIG9kZXIgbmljaHQgYmVzc2VyIChTKSBhbHMgZGFzIGR1cmNoc2Nobml0dGxpY2hlIEVyZ2VibmlzLiBJaHJlIFNtYXJ0cGhvbmUtTnV0enVuZ3NkYXVlciB3YXIgZW50d2VkZXIgbmllZHJpZyAoTiwgd2VuaWdlciBhbHMgMmgvVGFnKSBvZGVyIGhvY2ggKEgsIG1pbmRlc3RlbnMgMmgvVGFnKS4NCg0KRGFzIEVyZ2VibmlzIGlzdCBpbiBkZXIgZm9sZ2VuZGVuIFRhYmVsbGUgYW5nZWdlYmVuLg0KDQpgYGB7cn0NCk09Y2JpbmQoYygxOSwxOSksYygxNiwzMykpDQpyb3duYW1lcyhNKT1jKCJCIiwgIlMiKQ0KY29sbmFtZXMoTSk9YygiTiIsICJIIikNCk0NCmBgYA0KDQpXaXIgdmVyd2VuZGVuIGRhcyBzdGF0aXN0aXNjaGUgTW9kZWxsLCBkYXNzIGRpZSBiZWlkZW4gTWVya21hbGUgc2ljaCB3aWUgWnVmYWxsc2dyw7bDn2VuIG1pdCBmZXN0ZXIgdW5iZWthbm50ZXIgZ2VtZWluc2FtZXIgVmVydGVpbHVuZyB2ZXJoYWx0ZW4uIEJlaW0gVW5hYmjDpG5naWdrZWl0c3Rlc3QgbGF1dGV0IGRpZSBOdWxsaHlwb3RoZXNlLCBkYXNzIGRpZSBNZXJrbWFsZSB1bmFiaMOkbmdpZyBzaW5kLiBGYWxscyB3aXIgJEhfMCQgYWJsZWhuZW4sIGhhYmVuIHdpciBlaW5lIHNpZ25pZmlrYW50ZSBWZXJsZXR6dW5nIHZvbiBVbmFiaMOkbmdpZ2tlaXQgZXJrYW5udC4gRmFsbHMgd2lyICRIXzAkIGFremVwdGllcmVuLCBsaWVmZXJuIGRpZSBEYXRlbiBrZWluZW4gSGlud2VpcyBkYXJhdWYsIGRhc3MgZGllIEFubmFobWUgZGVyIFVuYWJow6RuZ2lna2VpdCBkZXIgTWVya21hbGUgdmVybGV0enQgc2VpbiBrw7ZubnRlLg0KDQpBdWZncnVuZCBkZXIgcmVsYXRpdiBncm/Dn2VuIFN0aWNocHJvYmUgc29sbHRlbiB3aXIgZXJ3YXJ0ZW4sIGRhc3MgZWluZSBOb3JtYWxhcHByb3hpbWF0aW9uIHp1bMOkc3NpZyBpc3QuIFdpciB2ZXJ3ZW5kZW4gaGllcnp1IGRpZSBGYXVzdHJlZ2VsLCBkYXNzIGplZGVyIEVpbnRyYWcgaW4gZGVyIE1hdHJpeCBncsO2w59lciBhbHMgNSBpc3QuIEFsc28gZ2VoZW4gd2lyIGRhdm9uIGF1cywgZGFzcyBlaW4gJFxjaGleMiQtQW5wYXNzdW5nc3Rlc3QgenVsw6Rzc2lnIGlzdC4NCg0KYGBge3J9DQojIGNoaTItVW5hYmhhZW5naWdrZWl0c3Rlc3QNCmNoaXNxLnRlc3QoTSkNCmBgYA0KDQpFcyBpc3QgdmllbGxlaWNodCDDvGJlcnJhc2NoZW5kLCBkYXNzIGRpZSBVbmFiaMOkbmdpZ2tlaXRzaHlwb3RoZXNlIGFremVwdGllcnQgd2VyZGVuIG11c3MuIERpZSBTdGljaHByb2JlIGlzdCBuaWNodCBncm/DnyBnZW51ZywgdW0gZWluZSBBYndlaWNodW5nIHZvbiBVbmFiaMOkbmdpZ2tlaXQgenUgZXJrZW5uZW4uDQoNCkRlciBzb2dlbmFubnRlIGV4YWt0ZSBUZXN0IHZvbiBGaXNoZXIgaMOkdHRlIGRhc3NlbGJlIEVyZ2VibmlzIGdlbGllZmVydC4gU2VpbmUgVGVzdHN0YXRpc3RpayBpc3QgZGVyIGxpbmtlIG9iZXJlIEVpbnRyYWcgaW4gZGVyIE1hdHJpeC4gRGllIFZlcnRlaWx1bmcgZGVyIFRlc3RzdGF0aXN0aWsgaXN0IGJlaSB1bmFiaMOkbmdpZ2VuIE1lcmttYWxlbiB1bmQgZmVzdGVuIFJhbmRow6R1Zmlna2VpdGVuIGh5cGVyZ2VvbWV0cmlzY2guIChMZXR6dGVyZSBBbm5haG1lIGlzdCBmw7xyIGRpZSBBbndlbmR1bmcgdW5wcm9ibGVtYXRpc2NoLCB3ZWlsIG1hbiBkZW4gRXJnZWJuaXNyYXVtIGluIFRlaWxyw6R1bWUgbWl0IGZlc3RlbiBSYW5kaMOkdWZpZ2tlaXRlbiB6ZXJsZWdlbiBrYW5uLikgRXMgd2lyZCBkZXIgJHAkLVdlcnQgZsO8ciBkYXMgTVBWVC1WZXJmYWhyZW4gYXVzZ2VnZWJlbi4gQWxzbyBpc3QgbmljaHQgZGVyIG9wdGltYWxlIFRlc3QgaW1wbGVtZW50aWVydCENCg0KYGBge3J9DQojIGV4YWt0ZXIgVGVzdCB2b24gRmlzaGVyDQpmaXNoZXIudGVzdChNKQ0KYGBgDQoNClRhdHPDpGNobGljaCBpbXBsZW1lbnRpZXJ0IGRlciBSLUJlZmVobCBlaW4gdmVyd2FuZHRlcyBUZXN0cHJvYmxlbS4gTWFuIGthbm4gc2ljaCBkYWbDvHIgaW50ZXJlc3NpZXJlbiwgb2IgendlaSB1bmFiaMOkbmdpZ2UgTWVya21hbGUgbWl0IGRlbnNlbGJlbiBXYWhyc2NoZWlubGljaGtlaXRlbiBhdWZ0cmV0ZW4uIERpZXNlIEZyYWdlIG5hY2ggSG9tb2dlbml0w6R0IHVuYWJow6RuZ2lnZXIgTWVya21hbGUgdW50ZXJzY2hlaWRldCBzaWNoIHZvbiBkZXIgRnJhZ2UgbmFjaCBVbmFiaMOkbmdpZ2tlaXQgZGVyIGJlaWRlbiBNZXJrbWFsZS4gQWxzIFRlc3RzdGF0aXN0aWsgd2lyZCBkYXMgVmVyaMOkbHRuaXMgZGVyIGdlc2Now6R0enRlbiBDaGFuY2VuIChvZGRzKSBmw7xyIMO8YmVyZHVyY2hzY2huaXR0bGljaGVzIEFic2NobmVpZGVuIGJlaSBuaWVkcmlnZXIgdW5kIGhvaGVyIE51dHp1bmdzZGF1ZXIgdmVyd2VuZGV0LiBEZXIgUi1CZWZlaGwgZ2lidCBhdWNoIGVpbiBLb25maWRlbnppbnRlcnZhbGwgZsO8ciBkYXMgdW5iZWthbm50ZSBDaGFuY2VudmVyaMOkbHRuaXMgJFx2YXJyaG8kIGFuLiBFaW4gTml2ZWF1LSRcYWxwaGEkLVRlc3QgYXVmICRIXzA6XHZhcnJobz1cdmFycmhvXzAkIGdlZ2VuICRIXzE6XHZhcnJob1xuZXFcdmFycmhvXzAkIGthbm4gaGllcmF1cyBhdWNoIG1pdCBmb2xnZW5kZXIgRW50c2NoZWlkdW5nc3JlZ2VsIGVyaGFsdGVuIHdlcmRlbjogQWt6ZXB0aWVyZSAkSF8wJCB6dW0gTml2ZWF1ICRcYWxwaGEkLCBmYWxscyAkXHZhcnJob18wJCBpbSAkKDEtXGFscGhhKSQtS29uZmlkZW56aW50ZXJ2YWxsIGbDvHIgJFx2YXJyaG8kIGxpZWd0LiBUYXRzw6RjaGxpY2ggZ2lsdCwgZGFzcyBiZWkgZmVzdGVuIFJhbmRow6R1Zmlna2VpdGVuIGRpZSBCZWRpbmd1bmcgZGVyIFVuYWJow6RuZ2lna2VpdCBnZXJhZGUgZHVyY2ggJFx2YXJyaG89MSQgYmVzY2hyaWViZW4gd2lyZC4gRsO8ciBEZXRhaWxzIHNpZWhlIGRhcyBCdWNoIHZvbiBMZWhtYW5uIHVuZCBSb21hbm8sIEthcGl0ZWwgNC41IHVuZCA0LjYuDQoNCmBgYHtyfQ0KIyBoX04gSGFldWZpZ2tlaXQgZnVlciBiZXNzZXJlcyBBYnNjaG5laWRlbiBiZWkgbmllZHJpZ2VyIERhdWVyDQpoX049TVsiQiIsIk4iXS8oTVsiQiIsIk4iXStNWyJTIiwiTiJdKQ0KIyBoX00gSGFldWZpZ2tlaXQgZnVlciBiZXNzZXJlcyBBYnNjaG5laWRlbiBiZWkgaG9oZXIgRGF1ZXINCmhfSD1NWyJCIiwiSCJdLyhNWyJCIiwiSCJdK01bIlMiLCJIIl0pDQojIFdlcnQgZGVzIENoYW5jZW4tVmVyaGFlbHRuaXNzZXMgKG9kZHMgcmF0aW8pDQooaF9OLygxLWhfTikpLyhoX0gvKDEtaF9IKSkNCmBgYA0K