Azienda: Neonatal Health Solutions Obiettivo: Creare un modello
statistico in grado di prevedere con precisione il peso dei neonati alla
nascita, basandosi su variabili cliniche raccolte da tre ospedali. Il
progetto mira a migliorare la gestione delle gravidanze ad alto rischio,
ottimizzare le risorse ospedaliere e garantire migliori risultati per la
salute neonatale.
Il progetto si inserisce all’interno di un contesto di crescente
attenzione verso la prevenzione delle complicazioni neonatali. La
possibilità di prevedere il peso alla nascita dei neonati rappresenta
un’opportunità fondamentale per migliorare la pianificazione clinica e
ridurre i rischi associati a nascite problematiche, come parti prematuri
o neonati con basso peso. Di seguito, i principali benefici che questo
progetto porterà all’azienda e al settore sanitario:
1.Miglioramento delle previsioni cliniche:
2.Ottimizzazione delle risorse ospedaliere:
3.Prevenzione e identificazione dei fattori di
rischio:
4.Valutazione delle pratiche ospedaliere:
5.Supporto alla pianificazione strategica:
Ipotesi 1
in alcuni ospedali si fanno più parti cesarei
Step 1: Analizziamo prima la distribuzione dei tipi di parto tra
parto naturale e parto cesareo

Step 2: Calcoliamo distribuzione dei tipi di parto tra parto naturale
e parto cesareo tra ospedali
table(dati$Tipo.parto, dati$Ospedale)
osp1 osp2 osp3
Ces 242 254 232
Nat 574 595 603
Step 3 Visualizziamo graficamente

Step 4 effettuiamo il test
# Parti cesarei per ospedale
chisq.test(table(dati$Tipo.parto, dati$Ospedale))
Pearson's Chi-squared test
data: table(dati$Tipo.parto, dati$Ospedale)
X-squared = 1.0972, df = 2, p-value = 0.5778
Commenti:
Il p-value è maggiore di 0.05, quindi non ci sono differenze
statisticamente significative nella distribuzione dei tipi di parto tra
gli ospedali. La scelta tra parto naturale e cesareo non sembra
dipendere dall’ospedale in cui avviene l’evento per cui si rifiuta
l’ipotesi.
Ipotesi 2
La media del peso e della lunghezza di questo campione di neonati
sono significativamente uguali a quelle della popolazione
Step 1: Analizziamo la distribuzione delle variabili peso e
lunghezza

Step 2: Effettuiamo un test di confronto delle variabili con le medie
di riferimento della popolazione (con mu Peso=3300g e mu
lunghezza=500cm)
# Test t per il peso
t.test(dati$Peso, mu = 3300)
One Sample t-test
data: dati$Peso
t = -1.516, df = 2499, p-value = 0.1296
alternative hypothesis: true mean is not equal to 3300
95 percent confidence interval:
3263.490 3304.672
sample estimates:
mean of x
3284.081
# Test t per la lunghezza con valore di riferimento (es. 500cm)
t.test(dati$Lunghezza, mu = 500)
One Sample t-test
data: dati$Lunghezza
t = -10.084, df = 2499, p-value < 2.2e-16
alternative hypothesis: true mean is not equal to 500
95 percent confidence interval:
493.6598 495.7242
sample estimates:
mean of x
494.692
Commenti:
Peso: Il p-value è maggiore di 0.05, quindi non
c’è evidenza statistica che la media del peso sia diversa da quella
della popolazione. La media del campione è compatibile con 3300
g
lunghezza: Il p-value è molto inferiore a 0.05,
quindi la media della lunghezza è significativamente diversa da quella
della popolazione. Il campione mostra una lunghezza media inferiore
rispetto al valore atteso
Ipotesi 3
Le misure antropometriche sono significativamente diverse tra i due
sessi
Step 1: Analizziamo la distribuzione M/F
Il grafico mostra una distribuzione delle osservazioni tra maschi e
femmine quasi perfettamente bilanciata

Step 2: Analizziamo la distribuzione delle variabili peso e
lunghezza

Step 3: Effettuiamo il test condizionato
# Peso
t.test(Peso ~ Sesso, data = dati)
Welch Two Sample t-test
data: Peso by Sesso
t = -12.106, df = 2490.7, p-value < 2.2e-16
alternative hypothesis: true difference in means between group F and group M is not equal to 0
95 percent confidence interval:
-287.1051 -207.0615
sample estimates:
mean in group F mean in group M
3161.132 3408.215
# Lunghezza
t.test(Lunghezza ~ Sesso, data = dati)
Welch Two Sample t-test
data: Lunghezza by Sesso
t = -9.582, df = 2459.3, p-value < 2.2e-16
alternative hypothesis: true difference in means between group F and group M is not equal to 0
95 percent confidence interval:
-11.929470 -7.876273
sample estimates:
mean in group F mean in group M
489.7643 499.6672
# Cranio
t.test(Cranio ~ Sesso, data = dati)
Welch Two Sample t-test
data: Cranio by Sesso
t = -7.4102, df = 2491.4, p-value = 1.718e-13
alternative hypothesis: true difference in means between group F and group M is not equal to 0
95 percent confidence interval:
-6.089912 -3.541270
sample estimates:
mean in group F mean in group M
337.6330 342.4486
Commenti:
- Tutte le variabili mostrano differenze statisticamente significative
tra i sessi
- I maschi hanno in media:
- Peso maggiore di circa 247 g
- Lunghezza maggiore di circa 10 mm
- Circonferenza cranica maggiore di circa 5 mm
Focus particolare sull’impatto del fumo materno sul peso e sulle
settimane di gestazione, che potrebbero indicare nascite premature
L’obiettivo di questa analisi è verificare un eventuale correlazione
e impatto tra il fumo e la nascita prematura dei neonati ed il relativo
peso alla nascita.


t.test(Peso~ Fumatrici)
Welch Two Sample t-test
data: Peso by Fumatrici
t = 1.034, df = 114.1, p-value = 0.3033
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
95 percent confidence interval:
-45.61354 145.22674
sample estimates:
mean in group 0 mean in group 1
3286.153 3236.346

Commenti:
- Le settimane di gestazione sono fortemente correllate al peso, come
mostrato dal grafico
- Nel campione, le fumatrici sembrano avere meno parti prematuri
rispetto alle non fumatrici
- non ci sono evidenze statisticamente significative che il peso
differisca tra i due gruppi (fumatrici vs non fumatrici)
- Questo risultato è controintuitivo rispetto alla letteratura medica
Nota:Con così pochi casi, l’effetto statistico può essere instabile e
non rappresentativo e inoltre potrebbero esserci variabili confondenti
che influenzano il risultato
2 - Creazione del Modello di Regressione
Step 1 Analisi delle correlazioni tra le variabili quantitative
round(cor(variabili),2)
Anni.madre N.gravidanze Fumatrici Gestazione Peso Lunghezza Cranio
Anni.madre 1.00 0.38 0.01 -0.14 -0.02 -0.06 0.02
N.gravidanze 0.38 1.00 0.05 -0.10 0.00 -0.06 0.04
Fumatrici 0.01 0.05 1.00 0.03 -0.02 -0.02 -0.01
Gestazione -0.14 -0.10 0.03 1.00 0.59 0.62 0.46
Peso -0.02 0.00 -0.02 0.59 1.00 0.80 0.70
Lunghezza -0.06 -0.06 -0.02 0.62 0.80 1.00 0.60
Cranio 0.02 0.04 -0.01 0.46 0.70 0.60 1.00
Matrice di correlazione tra tutte le variabili

Osservazioni sulla matrice
- Correlazioni forti:
- Peso vs Sesso:: i neaonati maschi pesano mediamente
di più delle femmine
- Peso Vs Gestazione: 0.59 la durata della gravidanza
incide significativamente sul peso alla nascita
- Peso vs Lunghezza: 0.80 → fortissima correlazione
positiva. Più lungo è il neonato, maggiore è il peso
- Peso vs Cranio::0.70 anche la circonferenza cranica
è fortemente associata al peso
- Gestazione vs Lunghezza:: 0.62 più lunga è la
gestazione, maggiore è la lunghezza del neonato
- Correlazioni deboli o nulle:
- Fumatrici vs tutte le altre: valori vicini a 0 (es.
−0.02, 0.03) → il fumo materno non mostra una correlazione forte con le
variabili neonatali in questo dataset
- Correlazioni negative:
- Anni.madre vs Gestazione: leggerissima tendenza:
madri più anziane potrebbero avere gestazioni leggermente più brevi
- Gestazione vs N.gravidanze: più gravidanze sembrano
associate a gestazioni leggermente più brevi
Creazione del primo modello di regressione lineare multipla con
tutte le variabili (Mod1)
# Mod1= Modello completo
mod1 <- lm(Peso ~ ., data = dati)
summary(mod1)
Call:
lm(formula = Peso ~ ., data = dati)
Residuals:
Min 1Q Median 3Q Max
-1124.40 -181.66 -14.42 160.91 2611.89
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -6738.4762 141.3087 -47.686 < 2e-16 ***
Anni.madre 0.8921 1.1323 0.788 0.4308
N.gravidanze 11.2665 4.6608 2.417 0.0157 *
Fumatrici -30.1631 27.5386 -1.095 0.2735
Gestazione 32.5696 3.8187 8.529 < 2e-16 ***
Lunghezza 10.2945 0.3007 34.236 < 2e-16 ***
Cranio 10.4707 0.4260 24.578 < 2e-16 ***
Tipo.partoNat 29.5254 12.0844 2.443 0.0146 *
Ospedaleosp2 -11.2095 13.4379 -0.834 0.4043
Ospedaleosp3 28.0958 13.4957 2.082 0.0375 *
SessoM 77.5409 11.1776 6.937 5.08e-12 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 273.9 on 2489 degrees of freedom
Multiple R-squared: 0.7289, Adjusted R-squared: 0.7278
F-statistic: 669.2 on 10 and 2489 DF, p-value: < 2.2e-16
Creazione di un secondo modello ottimizzato di regressione lineare
multipla con le variabili escludendo le variabili poco significative
come Fumatrici e Ospedale (Mod2)
# Mod2= Modello ottimizzato
mod2 <- update(mod1,~ .- Ospedale - Fumatrici)
summary(mod2)
Call:
lm(formula = Peso ~ Anni.madre + N.gravidanze + Gestazione +
Lunghezza + Cranio + Tipo.parto + Sesso, data = dati)
Residuals:
Min 1Q Median 3Q Max
-1140.63 -181.17 -15.31 160.36 2633.22
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -6740.2053 141.4004 -47.668 < 2e-16 ***
Anni.madre 0.9637 1.1336 0.850 0.3953
N.gravidanze 11.3062 4.6600 2.426 0.0153 *
Gestazione 32.6164 3.8160 8.547 < 2e-16 ***
Lunghezza 10.2865 0.3007 34.205 < 2e-16 ***
Cranio 10.4874 0.4266 24.583 < 2e-16 ***
Tipo.partoNat 30.0205 12.0976 2.482 0.0131 *
SessoM 77.8423 11.1916 6.955 4.48e-12 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 274.3 on 2492 degrees of freedom
Multiple R-squared: 0.7278, Adjusted R-squared: 0.727
F-statistic: 951.6 on 7 and 2492 DF, p-value: < 2.2e-16
Creazione di un terzo modello ancora più parsimonioso, con il
principio del Rasoio di Occam, di regressione lineare multipla
escludendo un ulteriorie variabili come il tipo parto (Mod3)
mod3 <- update(mod2,~ .- Tipo.parto)
summary(mod3)
Call:
lm(formula = Peso ~ Anni.madre + N.gravidanze + Gestazione +
Lunghezza + Cranio + Sesso, data = dati)
Residuals:
Min 1Q Median 3Q Max
-1160.80 -181.84 -14.91 164.28 2634.06
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -6714.1927 141.1571 -47.565 < 2e-16 ***
Anni.madre 0.9674 1.1347 0.853 0.3940
N.gravidanze 11.0199 4.6634 2.363 0.0182 *
Gestazione 32.6784 3.8198 8.555 < 2e-16 ***
Lunghezza 10.2486 0.3006 34.088 < 2e-16 ***
Cranio 10.5218 0.4268 24.652 < 2e-16 ***
SessoM 77.9061 11.2032 6.954 4.52e-12 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 274.6 on 2493 degrees of freedom
Multiple R-squared: 0.7271, Adjusted R-squared: 0.7264
F-statistic: 1107 on 6 and 2493 DF, p-value: < 2.2e-16
3 - Selezione del Modello di Regressione
migliore
Per selezionare il modello migliore vengono messi a confronto i tre
modelli con la tecnica di Bayes (BIC), applicando ANOVA e VIF
anova(mod3,mod1)
Analysis of Variance Table
Model 1: Peso ~ Anni.madre + N.gravidanze + Gestazione + Lunghezza + Cranio +
Sesso
Model 2: Peso ~ Anni.madre + N.gravidanze + Fumatrici + Gestazione + Lunghezza +
Cranio + Tipo.parto + Ospedale + Sesso
Res.Df RSS Df Sum of Sq F Pr(>F)
1 2493 188010731
2 2489 186762521 4 1248209 4.1587 0.002325 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
vif<5
vif(mod3)
Anni.madre N.gravidanze Gestazione Lunghezza Cranio Sesso
1.186622 1.181758 1.688288 2.074689 1.628621 1.040140
Commenti:
mod3 risulta il modello ottimale secondo il BIC: più
semplice (7 parametri) e con il miglior equilibrio tra complessità e
adattamento.
In termini di selezione di variabili, significa che togliere
ulteriori predittori rispetto a mod2 ha reso il modello ancora più
parsimonioso senza peggiorare la capacità di spiegare i dati.
4- Analisi della qualità del Modello di Regressione
selezionato
Analisi dei residui

shapiro.test(residuals(mod3))
Shapiro-Wilk normality test
data: residuals(mod3)
W = 0.97413, p-value < 2.2e-16

#leverage
lev<-hatvalues(mod3)
plot(lev)
p<-sum(lev)
n<-length(lev)
soglia=2*p/n
abline(h=soglia,col=2)
lev[lev>soglia]
13 15 34 61 67 70 89 96 101 106
0.005684347 0.007060519 0.006747369 0.005664249 0.005895931 0.005612823 0.012966743 0.006042837 0.007745118 0.015033667
131 134 151 155 161 189 190 204 205 206
0.007338390 0.007583673 0.011289124 0.007304937 0.020643649 0.005798343 0.005740905 0.015669489 0.008732982 0.010786029
220 230 260 294 304 305 310 312 335 378
0.007859452 0.006505071 0.006048045 0.005915388 0.006144441 0.006963312 0.029108905 0.013381509 0.006554957 0.016026324
408 411 442 445 446 486 492 516 582 587
0.006110755 0.005792516 0.007732411 0.007533035 0.005739232 0.005824264 0.008433653 0.013092597 0.012822336 0.011877860
592 638 656 684 697 748 750 757 765 805
0.006385723 0.006854179 0.006954864 0.008833096 0.006154282 0.009502586 0.007088886 0.008923975 0.006294047 0.014420805
828 855 928 946 947 951 956 985 1014 1067
0.007398786 0.006178106 0.023008513 0.006910812 0.008432363 0.006175882 0.007786248 0.008445882 0.010011594 0.009364299
1072 1075 1091 1096 1106 1130 1152 1166 1181 1188
0.005805811 0.006181114 0.008945797 0.006116493 0.007866262 0.033179618 0.014053872 0.006026149 0.005677759 0.006901542
1194 1200 1219 1238 1248 1273 1291 1293 1311 1321
0.005895406 0.005870628 0.031495526 0.007417126 0.014903156 0.007179160 0.006450744 0.006168427 0.009802029 0.009293849
1323 1357 1380 1385 1400 1411 1428 1429 1450 1505
0.007113784 0.007677691 0.013304831 0.012869661 0.006544304 0.008339480 0.008241753 0.024434421 0.015169586 0.014596639
1551 1553 1556 1560 1593 1610 1619 1686 1692 1701
0.049353528 0.008845028 0.008277042 0.006092914 0.007010111 0.009082760 0.015189307 0.009416569 0.007069515 0.011563400
1712 1718 1727 1735 1780 1781 1806 1809 1827 1962
0.007069180 0.007092916 0.013525504 0.007569348 0.026634410 0.017423335 0.006322689 0.009556466 0.006147505 0.005965789
1967 1977 2026 2037 2040 2086 2089 2098 2114 2115
0.005994098 0.007252882 0.006354152 0.006435075 0.011554118 0.015940304 0.006389663 0.006593767 0.014361960 0.012189225
2120 2140 2146 2148 2149 2157 2175 2200 2216 2220
0.018762407 0.006256453 0.005838802 0.008144160 0.014148145 0.006125118 0.032750743 0.011932710 0.008943401 0.006252941
2221 2224 2244 2257 2307 2317 2318 2359 2408 2422
0.022368287 0.007961185 0.006944292 0.008765853 0.014264552 0.009747025 0.006030803 0.012649781 0.010185054 0.022811910
2437 2452 2458 2471 2478
0.024108318 0.023876497 0.008593048 0.022057423 0.005844481


# R² e RMSE
pred <- predict(mod3)
rmse(dati$Peso, pred)
Commenti sulla qualità del modello:
Il modello mod3 presenta residui quasi normali, con qualche
deviazione alle code.
La violazione della normalità è confermata dal test, ma non così
grave mostrate nei grafici.
La eteroscedasticità è lieve.
Alcuni outlier/influential points meritano attenzione, ma non
invalidano il modello
Il modello mod3 sbaglia di circa 275 g rispetto al peso reale dei
neonati (RMSE: 274.234)
Considerando che il peso medio è intorno ai 3200–3400 g,
l’errore è circa l’8% del valore medio → un livello di accuratezza
piuttosto buono per dati biologici, che hanno sempre variabilità
naturale.
5- Previsioni dei risultati
Testiamo il modello per effettuare delle previsioni
Previsione test: Proviamo a stimare il peso di una neonata
considerando una madre alla terza gravidanza che partorirà alla 39esima
settimana.
# Esempio: madre alla terza gravidanza, 39 settimane, non fumatrice
nuovo <- data.frame(
Anni.madre = 30,
Gestazione = 39,
N.gravidanze= 3,
Lunghezza = 500,
Cranio = 340,
Sesso = factor("F", levels = levels(dati$Sesso))
)
predict(mod3, nuovo, interval = "prediction")
fit lwr upr
1 3324.071 2785.035 3863.107
Commenti:
Il modello di regressione multipla mostra una buona capacità
predittiva, con un RMSE di circa 275 g. Questo significa che, in media,
la stima del peso neonatale differisce di meno di 300 g dal valore
osservato, un margine accettabile considerando la variabilità naturale
dei dati antropometrici.
6- Conclusioni finali
In questo lavoro sono state analizzate le misure antropometriche
neonatali con l’obiettivo di comprendere relazioni tra le diverse
variabili e di costruire un modello predittivo del peso alla
nascita.
I risultati dei test statistici hanno mostrato chiaramente che i
neonati maschi tendono ad avere valori medi più elevati rispetto alle
femmine in tutte le variabili considerate: peso, lunghezza e
circonferenza cranica.
Queste differenze non sono casuali, ma statisticamente significative,
e confermano quanto già osservato in letteratura.
Successivamente, è stato costruito un modello di regressione multipla
per stimare il peso neonatale in funzione di variabili come lunghezza,
cranio, sesso, numero di gravidanze e settimana di gestazione
Il modello ha mostrato una buona capacità
esplicativa: le variabili antropometriche e ostetriche
contribuiscono in modo significativo alla previsione del peso, e
l’errore medio di stima (RMSE) è risultato di circa 275 grammi. Questo
valore, se confrontato con il peso medio dei neonati del campione (circa
3200–3400 g), rappresenta un margine di errore contenuto e
accettabile
Infine, abbiamo applicato il modello a un caso pratico: una neonata,
figlia di una madre alla terza gravidanza, partorita alla 39ª settimana.
La previsione ha stimato un peso di circa 3300 g, con un intervallo di
predizione compreso tra 2785 e 3863 g.
LS0tDQp0aXRsZTogIk1vZGVsbG8gU3RhdGlzdGljbyBwZXIgbGEgUHJldmlzaW9uZSBkZWwgUGVzbyBOZW9uYXRhbGUiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCkNvbnRlc3RvIEF6aWVuZGFsZVxicg0KDQpBemllbmRhOiBOZW9uYXRhbCBIZWFsdGggU29sdXRpb25zDQpPYmlldHRpdm86IENyZWFyZSB1biBtb2RlbGxvIHN0YXRpc3RpY28gaW4gZ3JhZG8gZGkgcHJldmVkZXJlIGNvbiBwcmVjaXNpb25lIGlsIHBlc28gZGVpIG5lb25hdGkgYWxsYSBuYXNjaXRhLCBiYXNhbmRvc2kgc3UgdmFyaWFiaWxpIGNsaW5pY2hlIHJhY2NvbHRlIGRhIHRyZSBvc3BlZGFsaS4gSWwgcHJvZ2V0dG8gbWlyYSBhIG1pZ2xpb3JhcmUgbGEgZ2VzdGlvbmUgZGVsbGUgZ3JhdmlkYW56ZSBhZCBhbHRvIHJpc2NoaW8sIG90dGltaXp6YXJlIGxlIHJpc29yc2Ugb3NwZWRhbGllcmUgZSBnYXJhbnRpcmUgbWlnbGlvcmkgcmlzdWx0YXRpIHBlciBsYSBzYWx1dGUgbmVvbmF0YWxlLg0KDQpJbCBwcm9nZXR0byBzaSBpbnNlcmlzY2UgYWxsJ2ludGVybm8gZGkgdW4gY29udGVzdG8gZGkgY3Jlc2NlbnRlIGF0dGVuemlvbmUgdmVyc28gbGEgcHJldmVuemlvbmUgZGVsbGUgY29tcGxpY2F6aW9uaSBuZW9uYXRhbGkuIExhIHBvc3NpYmlsaXTDoCBkaSBwcmV2ZWRlcmUgaWwgcGVzbyBhbGxhIG5hc2NpdGEgZGVpIG5lb25hdGkgcmFwcHJlc2VudGEgdW4nb3Bwb3J0dW5pdMOgIGZvbmRhbWVudGFsZSBwZXIgbWlnbGlvcmFyZSBsYSBwaWFuaWZpY2F6aW9uZSBjbGluaWNhIGUgcmlkdXJyZSBpIHJpc2NoaSBhc3NvY2lhdGkgYSBuYXNjaXRlIHByb2JsZW1hdGljaGUsIGNvbWUgcGFydGkgcHJlbWF0dXJpIG8gbmVvbmF0aSBjb24gYmFzc28gcGVzby4gRGkgc2VndWl0bywgaSBwcmluY2lwYWxpIGJlbmVmaWNpIGNoZSBxdWVzdG8gcHJvZ2V0dG8gcG9ydGVyw6AgYWxs4oCZYXppZW5kYSBlIGFsIHNldHRvcmUgc2FuaXRhcmlvOlxicg0KDQoNCjEuKipNaWdsaW9yYW1lbnRvIGRlbGxlIHByZXZpc2lvbmkgY2xpbmljaGUqKjpcYnINCg0KDQotIElsIHBlc28gZGVsIG5lb25hdG8gw6ggdW4gaW5kaWNhdG9yZSBjaGlhdmUgZGVsbGEgc3VhIHNhbHV0ZS4gQXZlcmUgdW4gbW9kZWxsbyBwcmVkaXR0aXZvIGFjY3VyYXRvIGNvbnNlbnRlIGFsIHBlcnNvbmFsZSBtZWRpY28gZGkgaW50ZXJ2ZW5pcmUgdGVtcGVzdGl2YW1lbnRlIGluIGNhc28gZGkgYW5vbWFsaWUsIHJpZHVjZW5kbyBsZSBjb21wbGljYXppb25pIHBlcmluYXRhbGkgY29tZSBsZSBkaWZmaWNvbHTDoCByZXNwaXJhdG9yaWUgbyBs4oCZaXBvZ2xpY2VtaWEuXEJSDQoNCjIuKipPdHRpbWl6emF6aW9uZSBkZWxsZSByaXNvcnNlIG9zcGVkYWxpZXJlKio6DQoNCi0gU2FwZXJlIGluIGFudGljaXBvIHF1YWxpIG5lb25hdGkgcG90cmViYmVybyBhdmVyZSBiaXNvZ25vIGRpIGN1cmUgaW50ZW5zaXZlIGFpdXRhIGEgb3JnYW5penphcmUgbGUgcmlzb3JzZSB1bWFuZSBlIHRlY25vbG9naWNoZSBkZWdsaSBvc3BlZGFsaSBpbiBtb2RvIGVmZmljaWVudGUuIFF1ZXN0byBzaSB0cmFkdWNlIGluIHVuYSByaWR1emlvbmUgZGVpIGNvc3RpIG9wZXJhdGl2aSBlIHVuYSBtaWdsaW9yZSBwaWFuaWZpY2F6aW9uZSBkZWxs4oCZdXRpbGl6em8gZGVsbGUgdW5pdMOgIGRpIHRlcmFwaWEgaW50ZW5zaXZhIG5lb25hdGFsZSAoVElOKS5cQlINCg0KMy4qKlByZXZlbnppb25lIGUgaWRlbnRpZmljYXppb25lIGRlaSBmYXR0b3JpIGRpIHJpc2NoaW8qKjoNCg0KLSBJbCBtb2RlbGxvIHBvdHLDoCBldmlkZW56aWFyZSBpIGZhdHRvcmkgY2hlIG1hZ2dpb3JtZW50ZSBpbmZsdWVuemFubyBuZWdhdGl2YW1lbnRlIGlsIHBlc28gZGVsIG5lb25hdG8gKGNvbWUgaWwgZnVtbyBtYXRlcm5vLCBncmF2aWRhbnplIG11bHRpcGxlIG8gZXTDoCBhdmFuemF0YSBkZWxsYSBtYWRyZSkuIFF1ZXN0ZSBpbmZvcm1hemlvbmkgc29ubyBwcmV6aW9zZSBwZXIgbGEgcHJldmVuemlvbmUgZSBsYSBnZXN0aW9uZSBwZXJzb25hbGl6emF0YSBkZWxsZSBncmF2aWRhbnplLCBwZXJtZXR0ZW5kbyBpbnRlcnZlbnRpIHByb2F0dGl2aSBpbiBjYXNvIGRpIHJpc2NoaW8gZWxldmF0by5cQlINCg0KNC4qKlZhbHV0YXppb25lIGRlbGxlIHByYXRpY2hlIG9zcGVkYWxpZXJlKio6DQoNCi0gQXR0cmF2ZXJzbyB1buKAmWFuYWxpc2kgY29tcGFyYXRpdmEgdHJhIGkgdHJlIG9zcGVkYWxpIGNvaW52b2x0aSwgbOKAmWF6aWVuZGEgcG90csOgIGlkZW50aWZpY2FyZSBldmVudHVhbGkgZGlmZmVyZW56ZSBuZWkgcmlzdWx0YXRpIGNsaW5pY2ksIGNvbWUgdW5hIG1hZ2dpb3JlIGluY2lkZW56YSBkaSBwYXJ0aSBjZXNhcmVpIGluIHVuYSBkZXRlcm1pbmF0YSBzdHJ1dHR1cmEuIENpw7IgY29uc2VudGUgZGkgbW9uaXRvcmFyZSBsYSBxdWFsaXTDoCBkZWxsZSBwcmF0aWNoZSBlIGFybW9uaXp6YXJlIGkgcHJvdG9jb2xsaSB0cmEgaSBkaXZlcnNpIGNlbnRyaSBvc3BlZGFsaWVyaSwgbWlnbGlvcmFuZG8gbGEgY29lcmVuemEgZGVsbGUgY3VyZS5cQlINCg0KNS4qKlN1cHBvcnRvIGFsbGEgcGlhbmlmaWNhemlvbmUgc3RyYXRlZ2ljYSoqOg0KDQotIEzigJlhbmFsaXNpIGRlaSBkYXRpIGUgbGUgcHJldmlzaW9uaSBwb3Nzb25vIGVzc2VyZSB1dGlsaXp6YXRlIHBlciBwcmVuZGVyZSBkZWNpc2lvbmkgaW5mb3JtYXRlIG5vbiBzb2xvIGEgbGl2ZWxsbyBjbGluaWNvIG1hIGFuY2hlIHN0cmF0ZWdpY28uIEwnYXppZW5kYSBwb3Ryw6Agc2ZydXR0YXJlIHF1ZXN0ZSBpbmZvcm1hemlvbmkgcGVyIGltcGxlbWVudGFyZSBudW92ZSBwb2xpdGljaGUgZGkgc2FsdXRlIHB1YmJsaWNhLCBnYXJhbnRlbmRvIHVuIGltcGF0dG8gcG9zaXRpdm8gc3VpIHRhc3NpIGRpIG1vcnRhbGl0w6AgZSBtb3JiaWxpdMOgIG5lb25hdGFsZS4NCg0KDQpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KZ2V0d2QoKQ0KYGBgDQoNCmBgYHtyIGVjaG89RkFMU0V9DQpkYXRpIDwtIHJlYWQuY3N2KCJuZW9uYXRpLmNzdiIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBUKQ0KYGBgDQoNCmBgYHtyIGVjaG89RkFMU0V9DQphdHRhY2goZGF0aSkNCmBgYA0KDQoNCmBgYHtyIGVjaG89RkFMU0V9DQpuPC0gbnJvdyhkYXRpKQ0KYGBgDQoNCg0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0Kc2hhcGlyby50ZXN0KFBlc28pDQpgYGANCg0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KaW5zdGFsbC5wYWNrYWdlcygiY2FyIikNCmluc3RhbGwucGFja2FnZXMoImJyb29tIikNCmluc3RhbGwucGFja2FnZXMoIk1ldHJpY3MiKQ0KaW5zdGFsbC5wYWNrYWdlcygicmdsIikNCmluc3RhbGwucGFja2FnZXMoInBhdGNod29yayIpDQoNCmBgYA0KDQoNCmBgYHtyIGVjaG89RkFMU0V9DQojIPCfk5ogQ2FyaWNhbWVudG8gZGVsbGUgbGlicmVyaWUgbmVjZXNzYXJpZQ0KDQpsaWJyYXJ5KGRwbHlyKSAgICAgICAgIyBNYW5pcG9sYXppb25lIGRlaSBkYXRpDQpsaWJyYXJ5KGdncGxvdDIpICAgICAgIyBHcmFmaWNpIHN0YXRpY2kNCmxpYnJhcnkocGxvdGx5KSAgICAgICAjIEdyYWZpY2kgaW50ZXJhdHRpdmkNCmxpYnJhcnkoY3Jvc3N0YWxrKSAgICAjIEZpbHRyaSBpbnRlcmF0dGl2aSBjb25kaXZpc2kNCmxpYnJhcnkoYnNwbHVzKSAgICAgICAjIExheW91dCBpbnRlcmF0dGl2byBjb24gYnNjb2xzKCkNCmxpYnJhcnkoc2NhbGVzKSAgICAgICAjIEZvcm1hdHRhemlvbmUgbnVtZXJpY2EgKGV0aWNoZXR0ZSwgYXNzaSkNCmxpYnJhcnkocmVhZHIpICAgICAgICAjIExldHR1cmEgZmlsZSBDU1YgKHNlIHVzYXRvKQ0KIyBPcHppb25hbGkNCmxpYnJhcnkoRFQpICAgICAgICAgICAjIFRhYmVsbGUgaW50ZXJhdHRpdmUNCmxpYnJhcnkoa2FibGVFeHRyYSkgICAjIFRhYmVsbGUgc3RhdGljaGUgZWxlZ2FudGkNCmxpYnJhcnkodGlkeXIpICAgICAgICAjIFJpc3RydXR0dXJhemlvbmUgZGF0aQ0KbGlicmFyeShsdWJyaWRhdGUpICAgICMgR2VzdGlvbmUgZGF0ZQ0KbGlicmFyeShlMTA3MSkNCmxpYnJhcnkobW9tZW50cykNCmxpYnJhcnkocGF0Y2h3b3JrKQ0KbGlicmFyeShNZXRyaWNzKQ0KbGlicmFyeShjYXIpDQoNCmBgYA0KDQoNCg0KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18NCg0KIyMjICoqMSAtIFJhY2NvbHRhIGRlaSBEYXRpIGUgU3RydXR0dXJhIGRlbCBEYXRhc2V0KioNCg0KDQpQZXIgY29zdHJ1aXJlIGlsIG1vZGVsbG8gcHJlZGl0dGl2bywgc29ubyBzdGF0aSByYWNjb2x0aSBkYXRpIHN1IDI1MDAgbmVvbmF0aSBwcm92ZW5pZW50aSBkYSB0cmUgb3NwZWRhbGkuIExlIHZhcmlhYmlsaSByYWNjb2x0ZSBpbmNsdWRvbm86DQoNCi0gKipFdMOgIGRlbGxhIG1hZHJlKio6IE1pc3VyYSBkZWxsJ2V0w6AgaW4gYW5uaS4NCi0gKipOdW1lcm8gZGkgZ3JhdmlkYW56ZSoqOiBRdWFudGUgZ3JhdmlkYW56ZSBoYSBhdnV0byBsYSBtYWRyZS4NCi0gKipGdW1vIG1hdGVybm8qKjogVW4gaW5kaWNhdG9yZSBiaW5hcmlvICgwPW5vbiBmdW1hdHJpY2UsIDE9ZnVtYXRyaWNlKS4NCi0gKipEdXJhdGEgZGVsbGEgZ3JhdmlkYW56YSoqOiBOdW1lcm8gZGkgc2V0dGltYW5lIGRpIGdlc3RhemlvbmUuDQotICoqUGVzbyBkZWwgbmVvbmF0byoqOiBQZXNvIGFsbGEgbmFzY2l0YSBpbiBncmFtbWkuDQotICoqTHVuZ2hlenphIGUgZGlhbWV0cm8gZGVsIGNyYW5pbyoqOiBMdW5naGV6emEgZGVsIG5lb25hdG8gZSBkaWFtZXRybyBjcmFuaWFsZSwgbWlzdXJhYmlsaSBhbmNoZSBkdXJhbnRlIGxhIGdyYXZpZGFuemEgdHJhbWl0ZSBlY29ncmFmaWUuDQotICoqVGlwbyBkaSBwYXJ0byoqOiBOYXR1cmFsZSBvIGNlc2FyZW8uDQotICoqT3NwZWRhbGUgZGkgbmFzY2l0YSoqOiBPc3BlZGFsZSAxLCAyIG8gMy4NCi0gKipTZXNzbyBkZWwgbmVvbmF0byoqOiBNYXNjaGlvIChNKSBvIGZlbW1pbmEgKEYpLlxicg0KDQpM4oCZb2JpZXR0aXZvIHByaW5jaXBhbGUgw6ggaWRlbnRpZmljYXJlIHF1YWxpIGRpIHF1ZXN0ZSB2YXJpYWJpbGkgc29ubyBwacO5IHByZWRpdHRpdmUgZGVsIHBlc28gYWxsYSBuYXNjaXRhLCBjb24gdW4gZm9jdXMgcGFydGljb2xhcmUgc3VsbOKAmWltcGF0dG8gZGVsIGZ1bW8gbWF0ZXJubyBlIGRlbGxlIHNldHRpbWFuZSBkaSBnZXN0YXppb25lLCBjaGUgcG90cmViYmVybyBpbmRpY2FyZSBuYXNjaXRlIHByZW1hdHVyZS4NCg0KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18NCg0KIyMjIEVzcGxvcmF6aW9uZSBkYXRpDQoNCg0KYGBge3IgZWNobz1GQUxTRX0NCiMgU2VsZXppb25hIGxlIHZhcmlhYmlsaQ0KdmFyaWFiaWxpIDwtIGRhdGkgJT4lDQogIHNlbGVjdChBbm5pLm1hZHJlLCBOLmdyYXZpZGFuemUsIEZ1bWF0cmljaSwgR2VzdGF6aW9uZSwgUGVzbywgTHVuZ2hlenphLCBDcmFuaW8pDQoNCiMgQ2FsY29sYSBnbGkgaW5kaWNpDQp0YWJlbGxhX3ZhciA8LSB0aWJibGUoDQogIFZhcmlhYmlsZSA9IGMoIkFubmkubWFkcmUiLCAiTi5ncmF2aWRhbnplIiwiRnVtYXRyaWNpIiwiR2VzdGF6aW9uZSIsICJQZXNvIiwgIkx1bmdoZXp6YSIsICJDcmFuaW8iKSwNCiAgTWVkaWEgPSBzYXBwbHkodmFyaWFiaWxpLCBtZWFuKSwNCiAgRGV2aWF6aW9uZV9TdGFuZGFyZCA9IHNhcHBseSh2YXJpYWJpbGksIHNkKSwNCiAgQ29lZmZfVmFyaWF6aW9uZSA9IHNhcHBseSh2YXJpYWJpbGksIHNkKSAvIHNhcHBseSh2YXJpYWJpbGksIG1lYW4pLA0KICBNaW5pbW8gPSBzYXBwbHkodmFyaWFiaWxpLCBtaW4pLA0KICBNYXNzaW1vID0gc2FwcGx5KHZhcmlhYmlsaSwgbWF4KSwNCiAgU2tld25lc3MgPSBzYXBwbHkodmFyaWFiaWxpLCBza2V3bmVzcyksDQogIEt1cnRvc2lzID0gc2FwcGx5KHZhcmlhYmlsaSwga3VydG9zaXMpDQopICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+cm91bmQoLngsIDIpKSkNCg0KIyBWaXN1YWxpenphIGxhIHRhYmVsbGENCnRhYmVsbGFfdmFyICU+JQ0KICBrYWJsZShjYXB0aW9uID0gIlRhYmVsbGEtIEluZGljaSBkaSBwb3NpemlvbmUsIHZhcmlhYmlsaXTDoCBlIGFzaW1tZXRyaWEgcGVyIHZhcmlhYmlsaSBxdWFudGl0YXRpdmUiKSAlPiUNCiAga2FibGVfc3R5bGluZygNCiAgICBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIiwgInJlc3BvbnNpdmUiKSwNCiAgICBmdWxsX3dpZHRoID0gRkFMU0UsDQogICAgcG9zaXRpb24gPSAibGVmdCINCiAgKQ0KYGBgDQpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KYGBge3J9DQojIFByZXBhcmEgaSBkYXRpIGluIGZvcm1hdG8gbHVuZ28NCmRhdGlfbG9uZyA8LSBkYXRpICU+JQ0KICBzZWxlY3QoUGVzbywgTHVuZ2hlenphLCBDcmFuaW8sIEdlc3RhemlvbmUsIEFubmkubWFkcmUsIE4uZ3JhdmlkYW56ZSkgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gZXZlcnl0aGluZygpLCBuYW1lc190byA9ICJWYXJpYWJpbGUiLCB2YWx1ZXNfdG8gPSAiVmFsb3JlIikNCg0KIyBDYWxjb2xhIGxhIG1lZGlhIHBlciBvZ25pIHZhcmlhYmlsZQ0KbWVkaWUgPC0gZGF0aV9sb25nICU+JQ0KICBncm91cF9ieShWYXJpYWJpbGUpICU+JQ0KICBzdW1tYXJpc2UoTWVkaWEgPSBtZWFuKFZhbG9yZSkpDQoNCiMgQ3JlYSBpbCBncmFmaWNvIGNvbiBjb2xvcmUgdW5pY28NCmdncGxvdChkYXRpX2xvbmcsIGFlcyh4ID0gVmFsb3JlKSkgKw0KICBnZW9tX2RlbnNpdHkoZmlsbCA9ICJncmV5NjAiLCBhbHBoYSA9IDAuNiwgY29sb3IgPSAiZ3JleTMwIiwgbGluZXdpZHRoID0gMSkgKw0KICBnZW9tX3ZsaW5lKGRhdGEgPSBtZWRpZSwgYWVzKHhpbnRlcmNlcHQgPSBNZWRpYSksDQogICAgICAgICAgICAgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjgpICsNCiAgZmFjZXRfd3JhcCh+VmFyaWFiaWxlLCBzY2FsZXMgPSAiZnJlZSIsIG5jb2wgPSAyKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBOVUxMKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiR3JhZmljbyBkaXN0cmlidXppb25lIGRlbGxlIHZhcmlhYmlsaSBxdWFudGl0YXRpdmUiLA0KICAgIHggPSAiIiwNCiAgICB5ID0gTlVMTA0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpDQogICkNCmBgYA0KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18NCiMjIyBBbmFsaXNpIGRpc3RyaWJ1emlvbmUgZGVsbGUgdmFyaWFiaWxpIHF1YW50aXRhdGl2ZTpcYnINCg0KKipBbm5pLm1hZHJlKipcYnINCg0KLSBNZWRpYTogMjguMTYgYW5uaSDihpIgZXTDoCBtZWRpYSBkZWxsZSBtYWRyaSByZWxhdGl2YW1lbnRlIGdpb3ZhbmVcYnINCi0gU2tld25lc3Mg4omIIDAg4oaSIGRpc3RyaWJ1emlvbmUgc2ltbWV0cmljYVxicg0KLSBLdXJ0b3NpcyAzLjM4IOKGkiB2aWNpbmEgYWxsYSBub3JtYWxlLCBxdWluZGkgc2VuemEgY29kZSBlY2Nlc3NpdmVcYnINCi0gUHJlc2VuemEgZGkgb3V0bGllciBwcm9iYWJpbG1lbnRlIGRvdnV0aSBhZCBlcnJvcmkgKDIgY2FzaSBzb3R0byBpIDEzIGFubmkpXGJyDQoNCioqTi5ncmF2aWRhbnplKipcYnINCg0KLSBNZWRpYTogMC45OCDihpIgaW4gbWVkaWEgdW5hIGdyYXZpZGFuemEgcGVyIG1hZHJlLlxicg0KLSBDb2VmZi4gdmFyaWF6aW9uZSA9IDEuMzEg4oaSIGFsdGlzc2ltYSB2YXJpYWJpbGl0w6AgcmVsYXRpdmFcYnINCi0gU2tld25lc3MgMi41MSDihpIgZGlzdHJpYnV6aW9uZSBtb2x0byBhc2ltbWV0cmljYSBhIGRlc3RyYSAoYWxjdW5lIG1hZHJpIGNvbiBtb2x0ZSBncmF2aWRhbnplKVxicg0KDQoqKkZ1bWF0cmljaSoqXGJyDQoNCi0gTWVkaWE6IDAuMDQg4oaSIHNvbG8gaWwgNCUgZGVsbGUgbWFkcmkgZnVtYVxicg0KLSBTa2V3bmVzcyA0LjU5IOKGkiBmb3J0ZW1lbnRlIGFzaW1tZXRyaWNhIChxdWFzaSB0dXR0ZSBsZSBnZXN0YW50aSBub24gZnVtYW5vKVxicg0KDQoqKkdlc3RhemlvbmUqKlxicg0KDQotIE1lZGlhOiAzOC45OCBzZXR0aW1hbmUg4oaSIHZpY2luYSBhbCB0ZXJtaW5lIGZpc2lvbG9naWNvICjiiYggMzkpLlxicg0KLSBNaW5pbW86IDI1IHNldHRpbWFuZSDihpIgcHJlc2VuemEgZGkgcHJlbWF0dXJpIGVzdHJlbWlcYnINCi0gS3VydG9zaXMgMTEuMjYg4oaSIGRpc3RyaWJ1emlvbmUgY29uIGNvZGUgcGVzYW50aSwgb3V0bGllciBpbXBvcnRhbnRpXGJyDQoNCioqUGVzbyoqXGJyDQoNCi0gTWVkaWE6IDMyODQgZyDihpIgaW4gbGluZWEgY29uIHZhbG9yaSBhdHRlc2lcYnINCi0gTWluaW1vOiA4MzAgZyDihpIgbmVvbmF0aSBtb2x0byBwaWNjb2xpIChwcmVtYXR1cmkpXGJyDQotIEt1cnRvc2lzIDUuMDMg4oaSIGNvZGUgcGVzYW50aSwgcHJlc2VuemEgZGkgdmFsb3JpIGVzdHJlbWlcYnINCg0KDQoqKkx1bmdoZXp6YSoqXGJyDQoNCi0gTWVkaWE6IDQ5NC42OSBtbSAo4omIIDQ5LjUgY20pXGJyDQotIFNrZXduZXNzIC0xLjUxIOKGkiBkaXN0cmlidXppb25lIGFzaW1tZXRyaWNhIGEgc2luaXN0cmEgKGFsY3VuaSBuZW9uYXRpIG1vbHRvIHBpY2NvbGkpXGJyDQotIEt1cnRvc2lzIDkuNDkg4oaSIGNvZGUgcGVzYW50aSwgb3V0bGllclxicg0KDQoqKkNyYW5pbyoqXGJyDQoNCi0gTWVkaWE6IDM0MCBtbVxicg0KLSBTa2V3bmVzcyAtMC43OSDihpIgbGVnZ2VyYSBhc2ltbWV0cmlhIGEgc2luaXN0cmFcYnINCi0gS3VydG9zaXMgNS45NSDihpIgZGlzdHJpYnV6aW9uZSBsZXB0b2N1cnRpY2EsIGNvZGUgcGVzYW50aVxicg0KDQoqKlNpbnRlc2kqKlxicg0KDQotIEFubmkubWFkcmUgw6ggbGEgdmFyaWFiaWxlIHBpw7kg4oCccmVnb2xhcmXigJ0sIGNvbiBkaXN0cmlidXppb25lIHZpY2luYSBhbGxhIG5vcm1hbGVcYnINCi0gVmFyaWFiaWxpIGNvbWUgTi5ncmF2aWRhbnplLCBGdW1hdHJpY2kgZSBHZXN0YXppb25lIG1vc3RyYW5vIGRpc3RyaWJ1emlvbmkgbW9sdG8gYXNpbW1ldHJpY2hlIGUgY29uIG91dGxpZXIg4oaSIHJpY2hpZWRvbm8gYXR0ZW56aW9uZSBuZWkgdGVzdCBzdGF0aXN0aWNpXGJyDQotIFZhcmlhYmlsaSBhbnRyb3BvbWV0cmljaGUgKFBlc28sIEx1bmdoZXp6YSwgQ3JhbmlvKSBoYW5ubyBtZWRpZSBwbGF1c2liaWxpLCBtYSBjb2RlIHBlc2FudGkg4oaSIGNvbmZlcm1hIGxhIHByZXNlbnphIGRpIG5lb25hdGkgcHJlbWF0dXJpIG8gbWFjcm9zb21pY2lcYnINCg0KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18NCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQoNCiMjIElwb3Rlc2kgMQ0KDQppbiBhbGN1bmkgb3NwZWRhbGkgc2kgZmFubm8gcGnDuSBwYXJ0aSBjZXNhcmVpXGJyDQoNCg0KU3RlcCAxOiBBbmFsaXp6aWFtbyBwcmltYSBsYSBkaXN0cmlidXppb25lIGRlaSB0aXBpIGRpIHBhcnRvIHRyYSBwYXJ0byBuYXR1cmFsZSBlIHBhcnRvIGNlc2FyZW8NCg0KYGBge3J9DQojIENhbGNvbGEgbGUgZnJlcXVlbnplDQpwYXJ0aSA8LSB0YWJsZShkYXRpJFRpcG8ucGFydG8pDQoNCiMgQ3JlYSBpbCBncmFmaWNvIGEgdG9ydGENCnBpZShwYXJ0aSwNCiAgICBsYWJlbHMgPSBwYXN0ZShuYW1lcyhwYXJ0aSksICJcbiIsIHJvdW5kKDEwMCAqIHBhcnRpIC8gc3VtKHBhcnRpKSwgMSksICIlIiksDQogICAgY29sID0gYygiZ3JleSIsICJncmV5OTAiKSwNCiAgICBtYWluID0gIkRpc3RyaWJ1emlvbmUgZGVpIHRpcGkgZGkgcGFydG8iKQ0KDQpgYGANCg0KDQpTdGVwIDI6IENhbGNvbGlhbW8gZGlzdHJpYnV6aW9uZSBkZWkgdGlwaSBkaSBwYXJ0byB0cmEgcGFydG8gbmF0dXJhbGUgZSBwYXJ0byBjZXNhcmVvIHRyYSBvc3BlZGFsaQ0KDQoNCg0KYGBge3J9DQp0YWJsZShkYXRpJFRpcG8ucGFydG8sIGRhdGkkT3NwZWRhbGUpDQoNCmBgYA0KU3RlcCAzIFZpc3VhbGl6emlhbW8gZ3JhZmljYW1lbnRlDQpgYGB7cn0NCiMgRnJlcXVlbnplIHBlciBjaWFzY3VuIG9zcGVkYWxlDQpwYXJ0aV9vc3BlZGFsaSA8LSB0YWJsZShkYXRpJFRpcG8ucGFydG8sIGRhdGkkT3NwZWRhbGUpDQoNCiMgR3JhZmljbyBhIHRvcnRhIHBlciBvZ25pIG9zcGVkYWxlDQpwYXIobWZyb3cgPSBjKDEsIDMpKSAgIyAzIGdyYWZpY2kgYWZmaWFuY2F0aQ0KDQpmb3IgKG9zcCBpbiBjb2xuYW1lcyhwYXJ0aV9vc3BlZGFsaSkpIHsNCiAgcGllKHBhcnRpX29zcGVkYWxpWywgb3NwXSwNCiAgICAgIGxhYmVscyA9IHBhc3RlKHJvd25hbWVzKHBhcnRpX29zcGVkYWxpKSwgIlxuIiwgcm91bmQoMTAwICogcGFydGlfb3NwZWRhbGlbLCBvc3BdIC8gc3VtKHBhcnRpX29zcGVkYWxpWywgb3NwXSksIDEpLCAiJSIpLA0KICAgICAgY29sID0gYygiZ3JleSIsICJncmV5OTAiKSwNCiAgICAgIG1haW4gPSBwYXN0ZSgiUGFydGkgaW4iLCBvc3ApKQ0KfQ0KDQpgYGANCg0KU3RlcCA0IGVmZmV0dHVpYW1vIGlsIHRlc3QNCmBgYHtyfQ0KIyBQYXJ0aSBjZXNhcmVpIHBlciBvc3BlZGFsZQ0KY2hpc3EudGVzdCh0YWJsZShkYXRpJFRpcG8ucGFydG8sIGRhdGkkT3NwZWRhbGUpKQ0KYGBgDQoNCkNvbW1lbnRpOlxicg0KDQpJbCBwLXZhbHVlIMOoIG1hZ2dpb3JlIGRpIDAuMDUsIHF1aW5kaSBub24gY2kgc29ubyBkaWZmZXJlbnplIHN0YXRpc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZlIG5lbGxhIGRpc3RyaWJ1emlvbmUgZGVpIHRpcGkgZGkgcGFydG8gdHJhIGdsaSBvc3BlZGFsaS4NCkxhIHNjZWx0YSB0cmEgcGFydG8gbmF0dXJhbGUgZSBjZXNhcmVvIG5vbiBzZW1icmEgZGlwZW5kZXJlIGRhbGzigJlvc3BlZGFsZSBpbiBjdWkgYXZ2aWVuZSBsJ2V2ZW50byBwZXIgY3VpIHNpIHJpZml1dGEgbCdpcG90ZXNpLg0KDQpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQojIyBJcG90ZXNpIDINCg0KTGEgbWVkaWEgZGVsIHBlc28gZSBkZWxsYSBsdW5naGV6emEgZGkgcXVlc3RvIGNhbXBpb25lIGRpIG5lb25hdGkgc29ubyBzaWduaWZpY2F0aXZhbWVudGUgdWd1YWxpIGEgcXVlbGxlIGRlbGxhIHBvcG9sYXppb25lXGJyDQoNCg0KU3RlcCAxOiBBbmFsaXp6aWFtbyBsYSBkaXN0cmlidXppb25lIGRlbGxlIHZhcmlhYmlsaSBwZXNvIGUgbHVuZ2hlenphXGJyDQoNCmBgYHtyfQ0KDQoNCiMgQm94IHBsb3QgZGVsIFBlc28NCmJveF9wZXNvIDwtIGdncGxvdChkYXRpLCBhZXMoeSA9IFBlc28pKSArDQogIGdlb21fYm94cGxvdChmaWxsID0gImdyZXkiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMzMwMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAicmVkIikgKw0KICBsYWJzKHRpdGxlID0gIkJveCBwbG90IFBlc28iLCB5ID0gIlBlc28gKGcpIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KIyBCb3ggcGxvdCBkZWxsYSBMdW5naGV6emENCmJveF9sdW5naGV6emEgPC0gZ2dwbG90KGRhdGksIGFlcyh5ID0gTHVuZ2hlenphKSkgKw0KICBnZW9tX2JveHBsb3QoZmlsbCA9ICJncmV5IiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDUwMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAicmVkIikgKw0KICBsYWJzKHRpdGxlID0gIkJveCBwbG90IEx1bmdoZXp6YSIsIHkgPSAiTHVuZ2hlenphIChtbSkiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYm94X3Blc28gKyBib3hfbHVuZ2hlenphDQoNCg0KYGBgDQpTdGVwIDI6IEVmZmV0dHVpYW1vIHVuIHRlc3QgZGkgY29uZnJvbnRvIGRlbGxlIHZhcmlhYmlsaSBjb24gbGUgbWVkaWUgZGkgcmlmZXJpbWVudG8gZGVsbGEgcG9wb2xhemlvbmUgKGNvbiBtdSBQZXNvPTMzMDBnIGUgbXUgbHVuZ2hlenphPTUwMGNtKSBcYnINCg0KDQoNCmBgYHtyfQ0KDQojIFRlc3QgdCBwZXIgaWwgcGVzbw0KdC50ZXN0KGRhdGkkUGVzbywgbXUgPSAzMzAwKQ0KDQojIFRlc3QgdCBwZXIgbGEgbHVuZ2hlenphIGNvbiB2YWxvcmUgZGkgcmlmZXJpbWVudG8gKGVzLiA1MDBjbSkNCnQudGVzdChkYXRpJEx1bmdoZXp6YSwgbXUgPSA1MDApDQoNCg0KYGBgDQpDb21tZW50aToNCg0KLSAqKlBlc28qKjogIElsIHAtdmFsdWUgw6ggbWFnZ2lvcmUgZGkgMC4wNSwgcXVpbmRpIG5vbiBj4oCZw6ggZXZpZGVuemEgc3RhdGlzdGljYSBjaGUgbGEgbWVkaWEgZGVsIHBlc28gc2lhIGRpdmVyc2EgZGEgcXVlbGxhIGRlbGxhIHBvcG9sYXppb25lLiBMYSBtZWRpYSBkZWwgY2FtcGlvbmUgw6ggY29tcGF0aWJpbGUgY29uIDMzMDAgZ1xicg0KDQoNCi0gKipsdW5naGV6emEqKjogSWwgcC12YWx1ZSDDqCBtb2x0byBpbmZlcmlvcmUgYSAwLjA1LCBxdWluZGkgbGEgbWVkaWEgZGVsbGEgbHVuZ2hlenphIMOoIHNpZ25pZmljYXRpdmFtZW50ZSBkaXZlcnNhIGRhIHF1ZWxsYSBkZWxsYSBwb3BvbGF6aW9uZS4gSWwgY2FtcGlvbmUgbW9zdHJhIHVuYSBsdW5naGV6emEgbWVkaWEgaW5mZXJpb3JlIHJpc3BldHRvIGFsIHZhbG9yZSBhdHRlc28NCg0KDQpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQojIyBJcG90ZXNpIDMNCg0KTGUgbWlzdXJlIGFudHJvcG9tZXRyaWNoZSBzb25vIHNpZ25pZmljYXRpdmFtZW50ZSBkaXZlcnNlIHRyYSBpIGR1ZSBzZXNzaVxicg0KDQoNClN0ZXAgMTogQW5hbGl6emlhbW8gbGEgZGlzdHJpYnV6aW9uZSBNL0ZcYnINCg0KSWwgZ3JhZmljbyBtb3N0cmEgdW5hIGRpc3RyaWJ1emlvbmUgZGVsbGUgb3NzZXJ2YXppb25pIHRyYSBtYXNjaGkgZSBmZW1taW5lIHF1YXNpIHBlcmZldHRhbWVudGUgYmlsYW5jaWF0YQ0KDQoNCmBgYHtyfQ0KIyBDYWxjb2xhIGxlIGZyZXF1ZW56ZQ0KcGFydGkgPC0gdGFibGUoZGF0aSRTZXNzbykNCg0KIyBDcmVhIGlsIGdyYWZpY28gYSB0b3J0YQ0KcGllKHBhcnRpLA0KICAgIGxhYmVscyA9IHBhc3RlKG5hbWVzKHBhcnRpKSwgIlxuIiwgcm91bmQoMTAwICogcGFydGkgLyBzdW0ocGFydGkpLCAxKSwgIiUiKSwNCiAgICBjb2wgPSBjKCJncmV5IiwgImdyZXk5MCIpLA0KICAgIG1haW4gPSAiRGlzdHJpYnV6aW9uZSBzZXNzbyBkZWkgbmVvbmF0aSIpDQpgYGANCg0KDQpTdGVwIDI6IEFuYWxpenppYW1vIGxhIGRpc3RyaWJ1emlvbmUgZGVsbGUgdmFyaWFiaWxpIHBlc28gZSBsdW5naGV6emFcYnINCg0KDQpgYGB7cn0NCiMgQm94IHBsb3QgZGVsIFBlc28gcGVyIHNlc3NvDQpib3hfcGVzbyA8LSBnZ3Bsb3QoZGF0aSwgYWVzKHggPSBTZXNzbywgeSA9IFBlc28pKSArDQogIGdlb21fYm94cGxvdChmaWxsID0gImdyZXk3MCIsIGNvbG9yID0gImJsYWNrIiwgb3V0bGllci5jb2xvciA9ICJibGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJCb3ggcGxvdCBQZXNvIiwgeSA9ICJQZXNvIChnKSIsIHggPSAiIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KIyBCb3ggcGxvdCBkZWxsYSBMdW5naGV6emEgcGVyIHNlc3NvDQpib3hfbHVuZ2hlenphIDwtIGdncGxvdChkYXRpLCBhZXMoeCA9IFNlc3NvLCB5ID0gTHVuZ2hlenphKSkgKw0KICBnZW9tX2JveHBsb3QoZmlsbCA9ICJncmV5NzAiLCBjb2xvciA9ICJibGFjayIsIG91dGxpZXIuY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnModGl0bGUgPSAiQm94IHBsb3QgTHVuZ2hlenphIiwgeSA9ICJMdW5naGV6emEgKG1tKSIsIHggPSAiIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KIyBCb3ggcGxvdCBkZWwgQ3JhbmlvIHBlciBzZXNzbw0KYm94X2NyYW5pbyA8LSBnZ3Bsb3QoZGF0aSwgYWVzKHggPSBTZXNzbywgeSA9IENyYW5pbykpICsNCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAiZ3JleTcwIiwgY29sb3IgPSAiYmxhY2siLCBvdXRsaWVyLmNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHRpdGxlID0gIkJveCBwbG90IENyYW5pbyIsIHkgPSAiQ2lyY29uZmVyZW56YSBjcmFuaWNhIChtbSkiLCB4ID0gIiIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCiMgQWZmaWFuY2EgaSB0cmUgZ3JhZmljaQ0KYm94X3Blc28gKyBib3hfbHVuZ2hlenphICsgYm94X2NyYW5pbw0KYGBgDQoNClN0ZXAgMzogRWZmZXR0dWlhbW8gaWwgdGVzdCBjb25kaXppb25hdG9cYnINCg0KYGBge3J9DQojIFBlc28NCnQudGVzdChQZXNvIH4gU2Vzc28sIGRhdGEgPSBkYXRpKQ0KDQojIEx1bmdoZXp6YQ0KdC50ZXN0KEx1bmdoZXp6YSB+IFNlc3NvLCBkYXRhID0gZGF0aSkNCg0KIyBDcmFuaW8NCnQudGVzdChDcmFuaW8gfiBTZXNzbywgZGF0YSA9IGRhdGkpDQpgYGANCkNvbW1lbnRpOg0KDQotIFR1dHRlIGxlIHZhcmlhYmlsaSBtb3N0cmFubyBkaWZmZXJlbnplIHN0YXRpc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZlIHRyYSBpIHNlc3NpDQotIEkgbWFzY2hpIGhhbm5vIGluIG1lZGlhOg0KICAtIFBlc28gbWFnZ2lvcmUgZGkgY2lyY2EgMjQ3IGcNCiAgLSBMdW5naGV6emEgbWFnZ2lvcmUgZGkgY2lyY2EgMTAgbW0NCiAgLSBDaXJjb25mZXJlbnphIGNyYW5pY2EgbWFnZ2lvcmUgZGkgY2lyY2EgNSBtbQ0KDQpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQpGb2N1cyBwYXJ0aWNvbGFyZSBzdWxs4oCZaW1wYXR0byBkZWwgZnVtbyBtYXRlcm5vIHN1bCBwZXNvIGUgc3VsbGUgc2V0dGltYW5lIGRpIGdlc3RhemlvbmUsIGNoZSBwb3RyZWJiZXJvIGluZGljYXJlIG5hc2NpdGUgcHJlbWF0dXJlXGJyDQoNCkwnb2JpZXR0aXZvIGRpIHF1ZXN0YSBhbmFsaXNpIMOoIHZlcmlmaWNhcmUgdW4gZXZlbnR1YWxlIGNvcnJlbGF6aW9uZSBlIGltcGF0dG8gdHJhIGlsIGZ1bW8gZSBsYSBuYXNjaXRhIHByZW1hdHVyYSBkZWkgbmVvbmF0aSBlZCBpbCByZWxhdGl2byBwZXNvIGFsbGEgbmFzY2l0YS5cYnINCg0KDQoNCmBgYHtyIGVjaG89RkFMU0V9DQpkYXRpJFByZW1hdHVybyA8LSBpZmVsc2UoZGF0aSRHZXN0YXppb25lIDwgMzcsIDEsIDApDQoNCmBgYA0KDQoNCmBgYHtyfQ0KdGFiIDwtIGFzLmRhdGEuZnJhbWUocHJvcC50YWJsZSh0YWJsZShkYXRpJEZ1bWF0cmljaSwgZGF0aSRQcmVtYXR1cm8pLCBtYXJnaW4gPSAxKSkNCmNvbG5hbWVzKHRhYikgPC0gYygiRnVtYXRyaWNpIiwgIlByZW1hdHVybyIsICJQcm9wb3J6aW9uZSIpDQoNCmdncGxvdCh0YWIsIGFlcyh4ID0gRnVtYXRyaWNpLCB5ID0gUHJvcG9yemlvbmUsIGZpbGwgPSBmYWN0b3IoUHJlbWF0dXJvKSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJncmV5IiwgImJsYWNrIiksDQogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIk5hc2NpdGEgbm9uIHByZW1hdHVyYSIsICJOYXNjaXRhIHByZW1hdHVyYSIpKSArDQogIGxhYnMoeSA9ICJQZXJjZW50dWFsZSIsIGZpbGwgPSAiRXNpdG8gcGFydG8iKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCkpDQoNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoUGVzb34gRnVtYXRyaWNpKQ0KYGBgDQoNCmBgYHtyfQ0KdC50ZXN0KFBlc29+IEZ1bWF0cmljaSkNCmBgYA0KDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGksIGFlcyh4ID0gR2VzdGF6aW9uZSwgeSA9IFBlc28sIGNvbG9yID0gZmFjdG9yKEZ1bWF0cmljaSkpKSArDQogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFKSArDQogIGxhYnMoeCA9ICJTZXR0aW1hbmUgZGkgZ2VzdGF6aW9uZSIsIHkgPSAiUGVzbyAoZykiLCBjb2xvciA9ICJGdW1vIG1hdGVybm8iKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJzdGVlbGJsdWUiLCAidG9tYXRvIiksDQogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJOb24gZnVtYXRyaWNlIiwgIkZ1bWF0cmljZSIpKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCg0KDQoNCg0KDQpDb21tZW50aToNCg0KLSBMZSBzZXR0aW1hbmUgZGkgZ2VzdGF6aW9uZSBzb25vIGZvcnRlbWVudGUgY29ycmVsbGF0ZSBhbCBwZXNvLCBjb21lIG1vc3RyYXRvIGRhbCBncmFmaWNvDQotIE5lbCBjYW1waW9uZSwgbGUgZnVtYXRyaWNpIHNlbWJyYW5vIGF2ZXJlIG1lbm8gcGFydGkgcHJlbWF0dXJpIHJpc3BldHRvIGFsbGUgbm9uIGZ1bWF0cmljaVxicg0KLSBub24gY2kgc29ubyBldmlkZW56ZSBzdGF0aXN0aWNhbWVudGUgc2lnbmlmaWNhdGl2ZSBjaGUgaWwgcGVzbyBkaWZmZXJpc2NhIHRyYSBpIGR1ZSBncnVwcGkgKGZ1bWF0cmljaSB2cyBub24gZnVtYXRyaWNpKVxicg0KLSBRdWVzdG8gcmlzdWx0YXRvIMOoIGNvbnRyb2ludHVpdGl2byByaXNwZXR0byBhbGxhIGxldHRlcmF0dXJhIG1lZGljYVxicg0KTm90YTpDb24gY29zw6wgcG9jaGkgY2FzaSwgbOKAmWVmZmV0dG8gc3RhdGlzdGljbyBwdcOyIGVzc2VyZSBpbnN0YWJpbGUgZSBub24gcmFwcHJlc2VudGF0aXZvIGUgaW5vbHRyZSBwb3RyZWJiZXJvIGVzc2VyY2kgdmFyaWFiaWxpIGNvbmZvbmRlbnRpIGNoZSBpbmZsdWVuemFubyBpbCByaXN1bHRhdG8NCg0KDQoNCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18NCg0KIyMjICoqMiAtIENyZWF6aW9uZSBkZWwgTW9kZWxsbyBkaSBSZWdyZXNzaW9uZSoqDQoNCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18NCg0KU3RlcCAxIEFuYWxpc2kgZGVsbGUgY29ycmVsYXppb25pIHRyYSBsZSB2YXJpYWJpbGkgcXVhbnRpdGF0aXZlDQoNCg0KYGBge3J9DQpyb3VuZChjb3IodmFyaWFiaWxpKSwyKQ0KYGBgDQpNYXRyaWNlIGRpIGNvcnJlbGF6aW9uZSB0cmEgdHV0dGUgbGUgdmFyaWFiaWxpDQogDQoNCmBgYHtyfQ0KcGFuZWwuY29yIDwtIGZ1bmN0aW9uKHgsIHksIGRpZ2l0cyA9IDIsIHByZWZpeCA9ICIiLCBjZXguY29yLCAuLi4pDQp7DQogIHVzciA8LSBwYXIoInVzciIpOyBvbi5leGl0KHBhcih1c3IpKQ0KICBwYXIodXNyID0gYygwLCAxLCAwLCAxKSkNCiAgciA8LSAoY29yKHgsIHkpKQ0KICB0eHQgPC0gZm9ybWF0KGMociwgMSksIGRpZ2l0cyA9IGRpZ2l0cylbMV0NCiAgdHh0IDwtIHBhc3RlMChwcmVmaXgsIHR4dCkNCiAgaWYobWlzc2luZyhjZXguY29yKSkgY2V4LmNvciA8LSAwLjgvc3Ryd2lkdGgodHh0KQ0KICB0ZXh0KDAuNSwgMC41LCB0eHQsIGNleCA9IDEuNSkNCn0NCiNjb3JyZWxhemlvbmkNCnBhaXJzKGRhdGksbG93ZXIucGFuZWw9cGFuZWwuY29yLCB1cHBlci5wYW5lbD1wYW5lbC5zbW9vdGgpDQpgYGANCg0KDQoqKk9zc2VydmF6aW9uaSBzdWxsYSBtYXRyaWNlKioNCg0KLSAqKkNvcnJlbGF6aW9uaSBmb3J0aSoqOg0KICAtICoqUGVzbyB2cyBTZXNzbzoqKjogaSBuZWFvbmF0aSBtYXNjaGkgcGVzYW5vIG1lZGlhbWVudGUgZGkgcGnDuSBkZWxsZSBmZW1taW5lDQogIC0gKipQZXNvIFZzIEdlc3RhemlvbmUqKjogMC41OSBsYSBkdXJhdGEgZGVsbGEgZ3JhdmlkYW56YSBpbmNpZGUgc2lnbmlmaWNhdGl2YW1lbnRlIHN1bCBwZXNvIGFsbGEgbmFzY2l0YQ0KICAtICoqUGVzbyB2cyBMdW5naGV6emEqKjogMC44MCDihpIgZm9ydGlzc2ltYSBjb3JyZWxhemlvbmUgcG9zaXRpdmEuIFBpw7kgbHVuZ28gw6ggaWwgbmVvbmF0bywgbWFnZ2lvcmUgw6ggaWwgcGVzbw0KICAtICoqUGVzbyB2cyBDcmFuaW86Kio6MC43MCBhbmNoZSBsYSBjaXJjb25mZXJlbnphIGNyYW5pY2Egw6ggZm9ydGVtZW50ZSBhc3NvY2lhdGEgYWwgcGVzbw0KICAtICoqR2VzdGF6aW9uZSB2cyBMdW5naGV6emE6Kio6IDAuNjIgcGnDuSBsdW5nYSDDqCBsYSBnZXN0YXppb25lLCBtYWdnaW9yZSDDqCBsYSBsdW5naGV6emEgZGVsIG5lb25hdG8NCiANCiAgDQogIA0KLSAqKkNvcnJlbGF6aW9uaSBkZWJvbGkgbyBudWxsZSoqOg0KICAtICoqRnVtYXRyaWNpIHZzIHR1dHRlIGxlIGFsdHJlKio6IHZhbG9yaSB2aWNpbmkgYSAwIChlcy4g4oiSMC4wMiwgMC4wMykg4oaSIGlsIGZ1bW8gbWF0ZXJubyBub24gbW9zdHJhIHVuYSBjb3JyZWxhemlvbmUgZm9ydGUgY29uIGxlIHZhcmlhYmlsaSBuZW9uYXRhbGkgaW4gcXVlc3RvIGRhdGFzZXQNCiAgDQotICoqQ29ycmVsYXppb25pIG5lZ2F0aXZlKio6DQogIC0gKipBbm5pLm1hZHJlIHZzIEdlc3RhemlvbmUqKjogbGVnZ2VyaXNzaW1hIHRlbmRlbnphOiBtYWRyaSBwacO5IGFuemlhbmUgcG90cmViYmVybyBhdmVyZSBnZXN0YXppb25pIGxlZ2dlcm1lbnRlIHBpw7kgYnJldmkNCiAgLSAqKkdlc3RhemlvbmUgdnMgTi5ncmF2aWRhbnplKio6IHBpw7kgZ3JhdmlkYW56ZSBzZW1icmFubyBhc3NvY2lhdGUgYSBnZXN0YXppb25pIGxlZ2dlcm1lbnRlIHBpw7kgYnJldmkNCiAgDQoNCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQoNCiMjIyBDcmVhemlvbmUgZGVsIHByaW1vIG1vZGVsbG8gZGkgcmVncmVzc2lvbmUgbGluZWFyZSBtdWx0aXBsYSBjb24gdHV0dGUgbGUgdmFyaWFiaWxpIChNb2QxKQ0KDQoNCmBgYHtyfQ0KDQojIE1vZDE9IE1vZGVsbG8gY29tcGxldG8NCm1vZDEgPC0gbG0oUGVzbyB+IC4sIGRhdGEgPSBkYXRpKQ0KDQpzdW1tYXJ5KG1vZDEpDQoNCmBgYA0KDQojIyMgQ3JlYXppb25lIGRpIHVuIHNlY29uZG8gbW9kZWxsbyBvdHRpbWl6emF0byAgZGkgcmVncmVzc2lvbmUgbGluZWFyZSBtdWx0aXBsYSBjb24gbGUgdmFyaWFiaWxpIGVzY2x1ZGVuZG8gbGUgdmFyaWFiaWxpIHBvY28gc2lnbmlmaWNhdGl2ZSBjb21lIEZ1bWF0cmljaSBlIE9zcGVkYWxlIChNb2QyKQ0KDQoNCmBgYHtyfQ0KIyBNb2QyPSBNb2RlbGxvIG90dGltaXp6YXRvDQptb2QyIDwtIHVwZGF0ZShtb2QxLH4gLi0gT3NwZWRhbGUgLSBGdW1hdHJpY2kpDQpzdW1tYXJ5KG1vZDIpDQoNCmBgYA0KDQojIyMgQ3JlYXppb25lIGRpIHVuIHRlcnpvIG1vZGVsbG8gYW5jb3JhIHBpw7kgcGFyc2ltb25pb3NvLCBjb24gaWwgcHJpbmNpcGlvIGRlbCBSYXNvaW8gZGkgT2NjYW0sICBkaSByZWdyZXNzaW9uZSBsaW5lYXJlIG11bHRpcGxhIGVzY2x1ZGVuZG8gdW4gdWx0ZXJpb3JpZSB2YXJpYWJpbGkgY29tZSBpbCB0aXBvIHBhcnRvIChNb2QzKQ0KDQoNCg0KYGBge3J9DQojIE1vZDI9IE1vZGVsbG8gcGnDuSBwYXJzaW1vbmlvc28NCm1vZDMgPC0gdXBkYXRlKG1vZDIsfiAuLSBUaXBvLnBhcnRvKQ0Kc3VtbWFyeShtb2QzKQ0KDQpgYGANCg0KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQojIyMgKiozIC0gU2VsZXppb25lIGRlbCBNb2RlbGxvIGRpIFJlZ3Jlc3Npb25lIG1pZ2xpb3JlKioNCg0KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQoNClBlciBzZWxlemlvbmFyZSBpbCBtb2RlbGxvIG1pZ2xpb3JlIHZlbmdvbm8gbWVzc2kgYSBjb25mcm9udG8gaSB0cmUgbW9kZWxsaSBjb24gbGEgdGVjbmljYSBkaSBCYXllcyAoQklDKSwgYXBwbGljYW5kbyBBTk9WQSBlIFZJRg0KDQpgYGB7cn0NCkJJQyhtb2QxLG1vZDIsbW9kMykNCmBgYA0KDQoNCmBgYHtyfQ0KYW5vdmEobW9kMyxtb2QxKQ0KYGBgDQoNCnZpZjw1DQoNCmBgYHtyfQ0KdmlmKG1vZDMpDQpgYGANCg0KDQpDb21tZW50aTpcYnINCg0KKiptb2QzKiogcmlzdWx0YSBpbCBtb2RlbGxvIG90dGltYWxlIHNlY29uZG8gaWwgQklDOiBwacO5IHNlbXBsaWNlICg3IHBhcmFtZXRyaSkgZSBjb24gaWwgbWlnbGlvciBlcXVpbGlicmlvIHRyYSBjb21wbGVzc2l0w6AgZSBhZGF0dGFtZW50by4NCg0KSW4gdGVybWluaSBkaSBzZWxlemlvbmUgZGkgdmFyaWFiaWxpLCBzaWduaWZpY2EgY2hlIHRvZ2xpZXJlIHVsdGVyaW9yaSBwcmVkaXR0b3JpIHJpc3BldHRvIGEgbW9kMiBoYSByZXNvIGlsIG1vZGVsbG8gYW5jb3JhIHBpw7kgcGFyc2ltb25pb3NvIHNlbnphIHBlZ2dpb3JhcmUgbGEgY2FwYWNpdMOgIGRpIHNwaWVnYXJlIGkgZGF0aS4NCg0KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18NCg0KDQpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQoNCiMjIyAqKjQtIEFuYWxpc2kgZGVsbGEgcXVhbGl0w6AgZGVsIE1vZGVsbG8gZGkgUmVncmVzc2lvbmUgc2VsZXppb25hdG8qKg0KDQpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQoNCg0KIyMjIEFuYWxpc2kgZGVpIHJlc2lkdWkNCg0KDQoNCmBgYHtyfQ0KIyBBbmFsaXNpIGRlaSByZXNpZHVpDQoNCnBhcihtZnJvdz1jKDIsMikpDQoNCnBsb3QobW9kMykNCg0KYGBgDQoNCmBgYHtyfQ0Kc2hhcGlyby50ZXN0KHJlc2lkdWFscyhtb2QzKSkNCmBgYA0KDQoNCmBgYHtyfQ0KI2xldmVyYWdlDQpsZXY8LWhhdHZhbHVlcyhtb2QzKQ0KcGxvdChsZXYpDQpwPC1zdW0obGV2KQ0KbjwtbGVuZ3RoKGxldikNCnNvZ2xpYT0yKnAvbg0KYWJsaW5lKGg9c29nbGlhLGNvbD0yKQ0KbGV2W2xldj5zb2dsaWFdDQpgYGANCg0KDQpgYGB7cn0NCiNvdXRsaWVycw0KcGxvdChyc3R1ZGVudChtb2QzKSkNCmFibGluZShoPWMoLTIsMikpDQpjYXI6Om91dGxpZXJUZXN0KG1vZDMpDQpgYGANCg0KDQpgYGB7cn0NCiNkaXN0YW56YSBkaSBjb29rDQpjb29rPC1jb29rcy5kaXN0YW5jZShtb2QzKQ0KcGxvdChjb29rLHlsaW0gPSBjKDAsMSkpIA0KDQpgYGANCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQoNCmBgYHtyfQ0KIyBSwrIgZSBSTVNFDQoNCnByZWQgPC0gcHJlZGljdChtb2QzKQ0Kcm1zZShkYXRpJFBlc28sIHByZWQpDQoNCg0KYGBgDQoNCg0KDQoNCg0KDQpDb21tZW50aSBzdWxsYSBxdWFsaXTDoCBkZWwgbW9kZWxsbzoNCg0KDQotIElsIG1vZGVsbG8gbW9kMyBwcmVzZW50YSByZXNpZHVpIHF1YXNpIG5vcm1hbGksIGNvbiBxdWFsY2hlIGRldmlhemlvbmUgYWxsZSBjb2RlLg0KDQotIExhIHZpb2xhemlvbmUgZGVsbGEgbm9ybWFsaXTDoCDDqCBjb25mZXJtYXRhIGRhbCB0ZXN0LCBtYSBub24gY29zw6wgZ3JhdmUgbW9zdHJhdGUgbmVpIGdyYWZpY2kuDQoNCi0gTGEgZXRlcm9zY2VkYXN0aWNpdMOgIMOoIGxpZXZlLg0KDQotIEFsY3VuaSBvdXRsaWVyL2luZmx1ZW50aWFsIHBvaW50cyBtZXJpdGFubyBhdHRlbnppb25lLCBtYSBub24gaW52YWxpZGFubyBpbCBtb2RlbGxvDQoNCg0KLSBJbCBtb2RlbGxvIG1vZDMgc2JhZ2xpYSBkaSBjaXJjYSAyNzUgZyByaXNwZXR0byBhbCBwZXNvIHJlYWxlIGRlaSBuZW9uYXRpIChSTVNFOiAyNzQuMjM0KQ0KDQoqKkNvbnNpZGVyYW5kbyBjaGUgaWwgcGVzbyBtZWRpbyDDqCBpbnRvcm5vIGFpIDMyMDDigJMzNDAwIGcsIGzigJllcnJvcmUgw6ggY2lyY2EgbOKAmTglIGRlbCB2YWxvcmUgbWVkaW8g4oaSIHVuIGxpdmVsbG8gZGkgYWNjdXJhdGV6emEgcGl1dHRvc3RvIGJ1b25vIHBlciBkYXRpIGJpb2xvZ2ljaSwgY2hlIGhhbm5vIHNlbXByZSB2YXJpYWJpbGl0w6AgbmF0dXJhbGUuKioNCg0KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQojIyMgKio1LSBQcmV2aXNpb25pIGRlaSByaXN1bHRhdGkqKg0KDQpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQoNCg0KVGVzdGlhbW8gaWwgbW9kZWxsbyBwZXIgZWZmZXR0dWFyZSBkZWxsZSBwcmV2aXNpb25pDQoNCg0KUHJldmlzaW9uZSB0ZXN0Olxicg0KUHJvdmlhbW8gYSBzdGltYXJlIGlsIHBlc28gZGkgdW5hIG5lb25hdGEgY29uc2lkZXJhbmRvIHVuYSBtYWRyZSBhbGxhIHRlcnphIGdyYXZpZGFuemEgY2hlIHBhcnRvcmlyw6AgYWxsYSAzOWVzaW1hIHNldHRpbWFuYS4NCg0KDQpgYGB7cn0NCiMgRXNlbXBpbzogbWFkcmUgYWxsYSB0ZXJ6YSBncmF2aWRhbnphLCAzOSBzZXR0aW1hbmUsIG5vbiBmdW1hdHJpY2UNCm51b3ZvIDwtIGRhdGEuZnJhbWUoDQogIEFubmkubWFkcmUgPSAzMCwNCiAgR2VzdGF6aW9uZSA9IDM5LA0KICBOLmdyYXZpZGFuemU9IDMsDQogIEx1bmdoZXp6YSA9IDUwMCwNCiAgQ3JhbmlvID0gMzQwLA0KICBTZXNzbyA9IGZhY3RvcigiRiIsIGxldmVscyA9IGxldmVscyhkYXRpJFNlc3NvKSkNCikNCg0KcHJlZGljdChtb2QzLCBudW92bywgaW50ZXJ2YWwgPSAicHJlZGljdGlvbiIpDQoNCmBgYA0KDQpDb21tZW50aTpcYnINCg0KSWwgbW9kZWxsbyBkaSByZWdyZXNzaW9uZSBtdWx0aXBsYSBtb3N0cmEgdW5hIGJ1b25hIGNhcGFjaXTDoCBwcmVkaXR0aXZhLCBjb24gdW4gUk1TRSBkaSBjaXJjYSAyNzUgZy4gUXVlc3RvIHNpZ25pZmljYSBjaGUsIGluIG1lZGlhLCBsYSBzdGltYSBkZWwgcGVzbyBuZW9uYXRhbGUgZGlmZmVyaXNjZSBkaSBtZW5vIGRpIDMwMCBnIGRhbCB2YWxvcmUgb3NzZXJ2YXRvLCB1biBtYXJnaW5lIGFjY2V0dGFiaWxlIGNvbnNpZGVyYW5kbyBsYSB2YXJpYWJpbGl0w6AgbmF0dXJhbGUgZGVpIGRhdGkgYW50cm9wb21ldHJpY2kuDQoNCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18NCg0KIyMjICoqNi0gQ29uY2x1c2lvbmkgZmluYWxpKioNCg0KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQoNCkluIHF1ZXN0byBsYXZvcm8gc29ubyBzdGF0ZSBhbmFsaXp6YXRlIGxlIG1pc3VyZSBhbnRyb3BvbWV0cmljaGUgbmVvbmF0YWxpIGNvbiBs4oCZb2JpZXR0aXZvIGRpIGNvbXByZW5kZXJlIHJlbGF6aW9uaSB0cmEgbGUgZGl2ZXJzZSB2YXJpYWJpbGkgZSBkaSBjb3N0cnVpcmUgdW4gbW9kZWxsbyBwcmVkaXR0aXZvIGRlbCBwZXNvIGFsbGEgbmFzY2l0YS4NCg0KSSByaXN1bHRhdGkgZGVpIHRlc3Qgc3RhdGlzdGljaSBoYW5ubyBtb3N0cmF0byBjaGlhcmFtZW50ZSBjaGUgaSBuZW9uYXRpIG1hc2NoaSB0ZW5kb25vIGFkIGF2ZXJlIHZhbG9yaSBtZWRpIHBpw7kgZWxldmF0aSByaXNwZXR0byBhbGxlIGZlbW1pbmUgaW4gdHV0dGUgbGUgdmFyaWFiaWxpIGNvbnNpZGVyYXRlOiBwZXNvLCBsdW5naGV6emEgZSBjaXJjb25mZXJlbnphIGNyYW5pY2EuXGJyDQoNClF1ZXN0ZSBkaWZmZXJlbnplIG5vbiBzb25vIGNhc3VhbGksIG1hIHN0YXRpc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZlLCBlIGNvbmZlcm1hbm8gcXVhbnRvIGdpw6Agb3NzZXJ2YXRvIGluIGxldHRlcmF0dXJhLlxicg0KDQoNClN1Y2Nlc3NpdmFtZW50ZSwgw6ggc3RhdG8gY29zdHJ1aXRvIHVuIG1vZGVsbG8gZGkgcmVncmVzc2lvbmUgbXVsdGlwbGEgcGVyIHN0aW1hcmUgaWwgcGVzbyBuZW9uYXRhbGUgaW4gZnVuemlvbmUgZGkgdmFyaWFiaWxpIGNvbWUgbHVuZ2hlenphLCBjcmFuaW8sIHNlc3NvLCBudW1lcm8gZGkgZ3JhdmlkYW56ZSBlIHNldHRpbWFuYSBkaSBnZXN0YXppb25lXGJyDQoNCklsIG1vZGVsbG8gaGEgbW9zdHJhdG8gdW5hICoqYnVvbmEgY2FwYWNpdMOgIGVzcGxpY2F0aXZhKio6IGxlIHZhcmlhYmlsaSBhbnRyb3BvbWV0cmljaGUgZSBvc3RldHJpY2hlIGNvbnRyaWJ1aXNjb25vIGluIG1vZG8gc2lnbmlmaWNhdGl2byBhbGxhIHByZXZpc2lvbmUgZGVsIHBlc28sIGUgbOKAmWVycm9yZSBtZWRpbyBkaSBzdGltYSAoUk1TRSkgw6ggcmlzdWx0YXRvIGRpIGNpcmNhIDI3NSBncmFtbWkuIFF1ZXN0byB2YWxvcmUsIHNlIGNvbmZyb250YXRvIGNvbiBpbCBwZXNvIG1lZGlvIGRlaSBuZW9uYXRpIGRlbCBjYW1waW9uZSAoY2lyY2EgMzIwMOKAkzM0MDAgZyksIHJhcHByZXNlbnRhIHVuIG1hcmdpbmUgZGkgZXJyb3JlIGNvbnRlbnV0byBlIGFjY2V0dGFiaWxlDQoNCkluZmluZSwgYWJiaWFtbyBhcHBsaWNhdG8gaWwgbW9kZWxsbyBhIHVuIGNhc28gcHJhdGljbzogdW5hIG5lb25hdGEsIGZpZ2xpYSBkaSB1bmEgbWFkcmUgYWxsYSB0ZXJ6YSBncmF2aWRhbnphLCBwYXJ0b3JpdGEgYWxsYSAzOcKqIHNldHRpbWFuYS4gTGEgcHJldmlzaW9uZSBoYSBzdGltYXRvIHVuIHBlc28gZGkgY2lyY2EgMzMwMCBnLCBjb24gdW4gaW50ZXJ2YWxsbyBkaSBwcmVkaXppb25lIGNvbXByZXNvIHRyYSAqKjI3ODUgZSAzODYzIGcqKi4NCg==