Príprava údajov - import z csv súboru
Súbor Life_Expectancy_Data obsahuje databázu determinantov očakávanej
dĺžky života. Import údajov urobíme nasledovne:
# import the dataset and create a data.frame udaje
udaje_svet <- read.csv("udaje/Life-Expectancy-Data-Updated.csv",header=TRUE,sep=",",dec=".",check.names = TRUE)
head(udaje_svet)
Databáza obsahuje údaje o 2938 pozorovaniach a 22 premenných. V tejto
práci sa budeme zaoberať len časťou z nich, konkrétne tými, ktoré
súvisia s dĺžkou dožitia. Na začiatku si vyberieme krajinu, ktorej
zdravotný stav chceme analyzovať. V tomto prípade ide o už spomínané
Japonsko:
# z databázy udaje_svet si vyberieme len tie pozorovania, ktoré sa týkajú Japonska
udaje <- subset(udaje_svet, Country == "Japan")
Tabuľka uvedená nižšie nám poskytuje základné popisné štatistiky
vybraných kvantitatívnych premenných. Vylúčená je Hepatitída B nakoľko
údaj bol konštantný.
# niektoré štatistiky a ich prehľad v tabuľke KableExtra
library(kableExtra)
udaje %>%
select(Adult_mortality,Alcohol_consumption,Measles,BMI,Polio,Diphtheria,GDP_per_capita,Population_mln,Life_expectancy,Schooling) %>%
summary() %>%
kable() %>%
kable_styling(bootstrap_options = "striped", full_width = FALSE)
| |
Adult_mortality |
Alcohol_consumption |
Measles |
BMI |
Polio |
Diphtheria |
GDP_per_capita |
Population_mln |
Life_expectancy |
Schooling |
| |
Min. :53.59 |
Min. :6.980 |
Min. :78.00 |
Min. :22.50 |
Min. :81.00 |
Min. :85.00 |
Min. :31416 |
Min. :126.8 |
Min. :81.10 |
Min. :10.70 |
| |
1st Qu.:61.20 |
1st Qu.:7.638 |
1st Qu.:86.00 |
1st Qu.:22.57 |
1st Qu.:95.75 |
1st Qu.:96.00 |
1st Qu.:31785 |
1st Qu.:127.4 |
1st Qu.:81.88 |
1st Qu.:11.07 |
| |
Median :64.70 |
Median :7.970 |
Median :88.00 |
Median :22.60 |
Median :97.50 |
Median :97.00 |
Median :33055 |
Median :127.7 |
Median :82.55 |
Median :11.35 |
| |
Mean :64.52 |
Mean :7.932 |
Mean :88.81 |
Mean :22.62 |
Mean :96.00 |
Mean :96.25 |
Mean :32972 |
Mean :127.6 |
Mean :82.46 |
Mean :11.47 |
| |
3rd Qu.:69.23 |
3rd Qu.:8.402 |
3rd Qu.:92.25 |
3rd Qu.:22.70 |
3rd Qu.:99.00 |
3rd Qu.:98.00 |
3rd Qu.:33666 |
3rd Qu.:127.9 |
3rd Qu.:82.95 |
3rd Qu.:11.85 |
| |
Max. :72.95 |
Max. :8.650 |
Max. :97.00 |
Max. :22.70 |
Max. :99.00 |
Max. :99.00 |
Max. :34961 |
Max. :128.1 |
Max. :83.80 |
Max. :12.50 |
Vyššie uvedená tabuľka nám poskytuje prehľad o základných
štatistických charakteristikách vybraných premenných, ako sú priemerné
hodnoty, rozptyl, minimum a maximum. Tieto informácie nám pomáhajú
lepšie pochopiť rozdelenie a rozsah hodnôt v našich dátach. Na druhej
strane je zaujímavá aj informácia o vzájomných vzťahoch medzi týmito
premennými, čo môžeme merať pomocou korelačnej matice.
# grafický prehľad o korelačných vzťahoch vyjadruje nasledovný obrázok
cor_matrix <- cor(udaje %>% select(Adult_mortality,Alcohol_consumption,Measles,BMI,Polio,Diphtheria,GDP_per_capita,Population_mln,Life_expectancy,Schooling), use = "complete.obs")
corrplot(cor_matrix, method = "color", type = "upper", tl.col =
"darkblue", tl.srt = 45, title = "Korelačná matica vybraných premenných", mar = c(0,0,1,0))

Uvedený graf nám poskytuje vizuálny prehľad o korelačných vzťahoch
medzi vybranými premennými. Farby a intenzita farieb nám umožňujú rýchlo
identifikovať silné pozitívne alebo negatívne korelácie. Upozorňujeme,
že korelácia neznamená kauzalitu.
V nasledovnom zobrazení je uvedený graf vývoja očakávanej dĺžky
dožitia v Japonsku v rokoch 2000-2015. Vidíme, že očakávaná dĺžka života
sa zvyšovala od roku 2000 z 81 na 83 rokov v roku 2015, čo je pozitívny
trend.
# graf vývoja očakávanej dĺžky dožitia v Japonsku v rokoch 2000-2015.
library(ggplot2)
ggplot(udaje, aes(x = Year, y = Life_expectancy)) +
geom_line() +
geom_point() +
labs(title = "Vývoj očakávanej dĺžky dožitia v Japonsku (2000-2015)",
x = "Rok",
y = "Očakávaná dĺžka dožitia") +
theme_minimal()

Na začiatku sa pokúsme o vyrovnanie priebehu tejto premennej v čase
pomocou lineárnej regresie, kde nezávislou premennou bude rok a závislou
premennou bude očakávaná dĺžka dožitia. Odhadneme koeficienty tejto
regresie a posúdime kvalitu vyrovnania pomocou ukazovateľov, ako je
R-squared a p-value.
# vyrovnanie priebehu očakávanej dĺžky dožitia v čase
model <- lm(Life_expectancy ~ Year, data = udaje)
library(broom)
library(knitr)
library(kableExtra)
# koeficienty regresie
tidy(model) %>%
kable(digits = 3, caption = "Odhadnuté koeficienty regresie") %>%
kable_styling(bootstrap_options = "striped", full_width = FALSE)
Odhadnuté koeficienty regresie
| term |
estimate |
std.error |
statistic |
p.value |
| (Intercept) |
-242.582 |
17.119 |
-14.170 |
0 |
| Year |
0.162 |
0.009 |
18.987 |
0 |
# kvalita vyrovnania
glance(model) %>%
kable(digits = 3, caption = "Ukazovatele kvality vyrovnania") %>%
kable_styling(bootstrap_options = "striped", full_width = FALSE)
Ukazovatele kvality vyrovnania
| r.squared |
adj.r.squared |
sigma |
statistic |
p.value |
df |
logLik |
AIC |
BIC |
deviance |
df.residual |
nobs |
| 0.963 |
0.96 |
0.157 |
360.514 |
0 |
1 |
7.965 |
-9.93 |
-7.613 |
0.346 |
14 |
16 |
NA
Výsledky regresie nám ukazujú, že koeficient pre rok je pozitívny a
štatisticky významný, čo naznačuje, že očakávaná dĺžka dožitia v
Japonsku sa zvyšovala v priebehu rokov 2000-2015. Jej priemerný ročný
nárast dosahoval 0,162. Hodnota R-squared hodnota nám hovorí, že model
vysvetľuje 96 % variability modelu. Podľa hodnoty p-value môžeme
povedať, že model ako celok je štatisticky významný.
# teraz vyššie uvedený obrázok doplníme o regresnú priamku
ggplot(udaje, aes(x = Year, y = Life_expectancy)) +
geom_line() +
geom_point() +
geom_smooth(method = "lm", se = FALSE, color = "green") +
labs(title = "Vývoj očakávanej dĺžky dožitia v Japonsku (2000-2015) s regresnou priamkou",
x = "Rok",
y = "Očakávaná dĺžka dožitia") +
theme_minimal()

###Vývoj spotreby alkoholu Teraz sa pozrieme, ako sa vyvýja
konzumácia alkoholu v čase od roku 2000 do roku 2015 v Japonsku. Nakoľko
alkohol je faktorom negatívne vplývajúcim na dĺžku dožitia.
model_alkohol <- lm(Alcohol_consumption ~ Year, data = udaje)
# kvalita regresie
tidy(model_alkohol) %>%
kable(digits = 3, caption = "Odhadnuté koeficienty regresie pre spotrebu alkoholu") %>%
kable_styling(bootstrap_options = "striped", full_width = FALSE)
Odhadnuté koeficienty regresie pre spotrebu alkoholu
| term |
estimate |
std.error |
statistic |
p.value |
| (Intercept) |
-91.115 |
53.198 |
-1.713 |
0.109 |
| Year |
0.049 |
0.026 |
1.862 |
0.084 |
# a teraz model quality statistics R squared
r2<- summary(model_alkohol)$r.square
adj_r2 <-summary(model_alkohol)$adj.r.square
#printujeme koeficient determinancie a upravený koeficient determinancie
cat ("R-squared:",round (r2,3), "\n")
R-squared: 0.198
cat ("Adjusted R-squared:",round (adj_r2,3), "\n")
Adjusted R-squared: 0.141
Výsledky regresie ukazujú, že koeficient pre premennú rok je
pozitívny, čo naznačuje mierny rast spotreby alkoholu v Japonsku v
období rokov 2000 – 2015. Odhadovaný koeficient 0,049 znamená, že
spotreba alkoholu sa v priemere zvyšovala približne o 0,049 jednotky
ročne. Hodnota p-value (0,084) však naznačuje, že tento koeficient nie
je štatisticky významný na hladine významnosti 5 %, preto nie je možné s
dostatočnou istotou potvrdiť existenciu štatisticky významného trendu
rastu spotreby alkoholu v sledovanom období.
#Obrázok o skutočných vyrovnaných hodnotách spotreby alkoholu
fitted_vals <- fitted(model_alkohol)
# vykreslenie skutočných a vyrovnaných hodnôt - Alcohol_consumption a fitted_values
ggplot(udaje, aes(x = Year)) +
geom_line(aes(y = Alcohol_consumption), color = "darkblue", size = 1) +
geom_line(aes(y = fitted_vals), color = "orange", size = 1, linetype = "dashed") +
labs(title = "Skutočné vs. Vyrovnané hodnoty spotreby alkoholu v Japonsku (2000-2015)",
x = "Rok",
y = "Spotreba alkoholu") +
theme_minimal() +
scale_y_continuous(limits = c(0, max(udaje$Alcohol_consumption, fitted_vals) * 1.1)) +
theme(legend.position = "none")

Diagnostické grafy
Residuals vs Fitted
Graf Residuals vs Fitted slúži na posúdenie linearity modelu
a približnej konštantnosti rozptylu rezíduí. Reziduály by mali byť
rozložené náhodne okolo nulovej hodnoty bez výrazného systematického
vzoru. Ak sa objaví vizuálne významné zakrivenie červenej vyhladzovacej
čiary,
ktorá slúži na vizuálnu identifikáciu systematických odchýlok od
náhodného rozloženia rezíduí, signalizuje to určité systematické
problémy. Ak je LOESS približne horizontálna, model je špecifikovaný
vhodne; ak sa zakrivuje, môže to naznačovať nelinearitu, chybnú
špecifikáciu (teda výber vysvetľujúcich premenných) alebo iný problém v
modeli. Ak sa body rozširujú alebo zužujú v tvare lievika, môže ísť o
heteroskedasticitu.
plot(model, which = 1)

Reziduá sú rozložené približne okolo nulovej hodnoty, avšak pri
najmenších aj najväčších odhadnutých hodnotách model systematicky
nadhodnocuje, resp. podhodnocuje skutočné hodnoty. Do určitej miery to
môže byť ovplyvnené odľahlými pozorovaniami, najmä pozorovaním č. 1411 a
530. Počet pozorovaní je však relatívne malý, preto túto skutočnosť
zatiaľ nepovažujeme za zásadný problém a podrobnejšie sa k nej môžeme
vrátiť pri analýze ďalších diagnostických grafov.
Q-Q plot
Q-Q graf porovnáva rozdelenie štandardizovaných rezíduí s
teoretickým normálnym rozdelením. Ak body ležia približne na priamke,
predpoklad normality rezíduí je približne splnený. Výraznejšie odchýlky
na krajoch naznačujú možné problémy s extrémnymi hodnotami alebo s
ťažšími koncami rozdelenia. Určitou pomôckou tu môže byť nasledovná
tabuľka:
Interpretácia Q–Q grafu
| Prípad |
Tvar.Q.Q.grafu |
Ľavý.chvost |
Pravý.chvost |
Interpretácia |
| Normálne rozdelenie |
Priamka |
Na priamke |
Na priamke |
Dáta majú normálne rozdelenie |
| Ľavostranná šikmosť (negatívna) |
Prehnutý nadol (∩ tvar) |
Nad priamkou |
Pod priamkou |
Dlhý ľavý chvost (extrémne nízke hodnoty) |
| Pravostranná šikmosť (pozitívna) |
Prehnutý nahor (∪ tvar) |
Pod priamkou |
Nad priamkou |
Dlhý pravý chvost (extrémne vysoké hodnoty) |
| Symetrické, vysoká špicatosť (> 3) |
S-tvar |
Pod priamkou |
Nad priamkou |
Ťažké chvosty (viac extrémnych hodnôt) |
| Symetrické, nízka špicatosť (< 3) |
Obrátený S-tvar |
Nad priamkou |
Pod priamkou |
Ľahké chvosty (menej extrémnych hodnôt) |
Niekedy hovoríme o pomôcke:
- Priamka → normálne rozdelenie
- ∪ → pravostranná šikmosť
- ∩ → ľavostranná šikmosť
- S → vysoká špicatosť (ťažké chvosty)
- obrátené S → nízka špicatosť
plot(model, which = 2)

Upravený popis podľa grafu:
Q-Q graf porovnáva empirické rozdelenie štandardizovaných rezíduí s
teoretickým normálnym rozdelením. V prípade splnenia predpokladu
normality by mali body ležať približne na diagonálnej priamke.
V našom prípade väčšina bodov v strednej časti grafu leží pomerne
blízko priamky, čo naznačuje, že pre väčšinu pozorovaní je predpoklad
normality približne splnený. Centrálna časť rozdelenia rezíduí sa teda
správa podobne ako normálne rozdelenie.
Na ľavom konci grafu dochádza k výraznejšiemu odchýleniu bodov pod
referenčnú priamku. Najmä pozorovanie č. 530 predstavuje extrémne
záporné reziduum, čo naznačuje ťažší ľavý chvost rozdelenia oproti
normálnemu rozdeleniu. Menšia odchýlka je viditeľná aj pri pozorovaní č.
566.
Na pravom konci grafu sú body relatívne blízko referenčnej priamky.
Pozorovanie č. 1411 sa nachádza mierne pod priamkou, čo poukazuje len na
malú odchýlku od normality a nepredstavuje výrazný problém.
Celkovo možno konštatovať, že normalita rezíduí je približne splnená,
avšak s miernymi odchýlkami v chvostoch rozdelenia, najmä v ľavom
chvoste spôsobenými odľahlými pozorovaniami. Z praktického hľadiska ide
o mierne porušenie predpokladu normality, ktoré však vzhľadom na dobré
správanie väčšiny rezíduí nemusí predstavovať zásadný problém pre ďalšiu
analýzu.
Scale-Location plot
Scale-Location graf sa používa na posúdenie
homoskedasticity, teda konštantnosti rozptylu rezíduí. Ak sú body
rozložené približne rovnomerne a červená čiara je relatívne vodorovná,
ide o priaznivý výsledok. Systematický rast alebo pokles naznačuje, že
rozptyl rezíduí sa mení s úrovňou predikovaných hodnôt.
plot(model, which = 3)

Tu je upravený popis presnejšie podľa grafu:
Body sú rozptýlené pomerne rovnomerne v celom rozsahu vyrovnaných
hodnôt, bez výrazného systematického vzoru. Červená vyhladzovacia krivka
mierne rastie pri nižších hodnotách, následne sa stabilizuje a ku koncu
len veľmi mierne kolíše, bez výrazného rastúceho trendu pri vyšších
hodnotách.
Niektoré body (napr. pozorovania označené 530, 566 a 1411) sa od
ostatných mierne odchyľujú, môžu teda predstavovať potenciálne odľahlé
alebo vplyvné pozorovania, avšak ich vplyv nie je extrémny.
Nevzniká typický „lievikovitý“ tvar, ktorý by naznačoval výrazné
porušenie predpokladu konštantného rozptylu. Variabilita rezíduí sa javí
ako relatívne stabilná naprieč hodnotami, čo naznačuje, že predpoklad
homoskedasticity je splnený, prípadne len veľmi mierne narušený.
Residuals vs Leverage
Graf Residuals vs Leverage pomáha identifikovať vplyvné
pozorovania. Leverage to predstavuje vzialenosť daného pozorovania
všetkých vysvetľujúcich premenných (teda vektora) od ostatných, resp. od
stredného vektora všetkych pozorovaní. Títo vzdialenosť je normovaná na
interval (0,1) a väčšina pozorovaní má veľmi malý leverage. Ak sa
vyskytujú pozorovania s vysokým leverage, identifikujeme ich na
vodorovnej osi a môžu znamenať potenciálne nebezpečenstvo v skreslení
parametrov vyrovnávajúcej nadroviny (teda odhadovaných \(\beta\) koeficientov). Pozorovania s
vysokou hodnotou leverage a súčasne veľkými rezíduami môžu môžu
spôsobovať tento problém. Ak sa niektoré body nachádzajú blízko alebo za
krivkami Cookovej vzdialenosti, je vhodné ich podrobnejšie
preskúmať.
plot(model, which = 5)

Tu je upravený popis podľa zobrazeného grafu:
V našom prípade má väčšina pozorovaní nízke až stredné hodnoty
leverage a je rozptýlená najmä v intervale približne od 0.05 do 0.20, čo
naznačuje, že žiadne pozorovanie nemá extrémne vysokú pákovú hodnotu.
Dáta teda nepôsobia výrazne nevyvážene z hľadiska vysvetľujúcich
premenných.
Z hľadiska rezíduí väčšina bodov nevykazuje extrémne hodnoty, avšak
niektoré pozorovania (najmä 530) majú výraznejšie záporné rezíduum.
Okrem toho body ako 1197 a 566 majú vyššie leverage, čo znamená, že môžu
mať väčší vplyv na odhad modelu.
Kontúry Cookovej vzdialenosti ukazujú mieru vplyvu jednotlivých
pozorovaní. Žiadny bod zjavne neprekračuje hranicu hodnoty 1, avšak
pozorovanie 530 sa nachádza v oblasti vyšších hodnôt Cookovej
vzdialenosti (medzi 0.5 a 1), čo naznačuje, že môže byť potenciálne
vplyvné a zaslúži si bližšie preskúmanie.
Celkovo možno konštatovať, že model neobsahuje extrémne vplyvné
pozorovania, ktoré by zásadne narúšali jeho stabilitu, avšak existujú
jednotlivé body (najmä 530, prípadne 1197 a 566), ktoré môžu mať zvýšený
vplyv na výsledky a je vhodné im venovať pozornosť.
LS0tCnRpdGxlOiAiUHLDoWNhIHMgcmVncmVzaW91IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKYXV0aG9yOiBOYXTDoWxpYSBLdW5vdsOhCi0tLQojIyMgw5p2b2QgZG8gcmVncmVzaWUKUHLDoWNhIHMgw7pkYWptaSAgeiBKYXBvbnNrYSB6YSByb2t5IDIwMDAtMjAxNSAKCgpWIHRlanRvIHByw6FjaSBzYSBidWRlbWUgemFvYmVyYcWlIHBydsO9bWkga3Jva21pIHYgb2RoYWRlIHJlZ3Jlc25laiBmdW5rY2llLiBCdWRlbWUgdnl1xb7DrXZhxaUgZGF0YWLDoXp1IFtMaWZlIEV4cGVjdGFuY3kgKFdITykgRml4ZWQgZGF0YXNldF0KKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvbGFzaGFnb2NoL2xpZmUtZXhwZWN0YW5jeS13aG8tdXBkYXRlZCksIGt0b3LDoSBvYnNhaHVqZSB1a2F6b3ZhdGVsZSBuYSDDunJvdm5pIGtyYWrDrW4sIGFrbyBqZSBwcmllbWVybsOhIGTEusW+a2Egxb5pdm90YSwgSERQLCDFoWtvbHNrw6kgdnpkZWzDoXZhbmllIGEgdsO9ZGF2a3kgbmEgemRyYXZvdG7DrWN0dm8uIFZ5YmVyw6FtZSBrcmFqaW51IEphcG9uc2tvLgoKCiMjIFZ5dcW+w612YW5pZSBuaWVrdG9yw71jaCBrbmnFvm7DrWMKCmBgYHtyfQpybShsaXN0PWxzKCkpCmxpYnJhcnkobG10ZXN0KSAgICMgIHBvZHBvcmEgcmVncmVzaWUKbGlicmFyeShvdXRsaWVycykgIyBhbmFseXphIG9kbGFobHljaCBob2Rub3QgKG91dGxpZXJzKQpsaWJyYXJ5KGdwdHN0dWRpbykKbGlicmFyeShrYWJsZUV4dHJhKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGJyb29tKQpsaWJyYXJ5KGNvcnJwbG90KQpgYGAKCgoKIyMgUHLDrXByYXZhIMO6ZGFqb3YgLSBpbXBvcnQgeiBjc3Ygc8O6Ym9ydQoKU8O6Ym9yIExpZmVfRXhwZWN0YW5jeV9EYXRhIG9ic2FodWplIGRhdGFiw6F6dSBkZXRlcm1pbmFudG92IG/EjWFrw6F2YW5laiBkxLrFvmt5IMW+aXZvdGEuIEltcG9ydCDDumRham92IHVyb2LDrW1lIG5hc2xlZG92bmU6CgpgYGB7cn0KIyBpbXBvcnQgdGhlIGRhdGFzZXQgYW5kIGNyZWF0ZSBhIGRhdGEuZnJhbWUgdWRhamUKdWRhamVfc3ZldCA8LSByZWFkLmNzdigidWRhamUvTGlmZS1FeHBlY3RhbmN5LURhdGEtVXBkYXRlZC5jc3YiLGhlYWRlcj1UUlVFLHNlcD0iLCIsZGVjPSIuIixjaGVjay5uYW1lcyA9IFRSVUUpCmhlYWQodWRhamVfc3ZldCkKYGBgCkRhdGFiw6F6YSBvYnNhaHVqZSDDumRhamUgbyAyOTM4IHBvem9yb3ZhbmlhY2ggYSAyMiBwcmVtZW5uw71jaC4gViB0ZWp0byBwcsOhY2kgc2EgYnVkZW1lIHphb2JlcmHFpSBsZW4gxI1hc8Wlb3UgeiBuaWNoLCBrb25rcsOpdG5lIHTDvW1pLCBrdG9yw6kgc8O6dmlzaWEgcyBkxLrFvmtvdSBkb8W+aXRpYS4gTmEgemHEjWlhdGt1IHNpIHZ5YmVyaWVtZSBrcmFqaW51LCBrdG9yZWogemRyYXZvdG7DvSBzdGF2IGNoY2VtZSBhbmFseXpvdmHFpS4gViB0b210byBwcsOtcGFkZSBpZGUgbyB1xb4gc3BvbcOtbmFuw6kgSmFwb25za286CgpgYGB7cn0KIyB6IGRhdGFiw6F6eSB1ZGFqZV9zdmV0IHNpIHZ5YmVyaWVtZSBsZW4gdGllIHBvem9yb3ZhbmlhLCBrdG9yw6kgc2EgdMO9a2Fqw7ogSmFwb25za2EgCnVkYWplIDwtIHN1YnNldCh1ZGFqZV9zdmV0LCBDb3VudHJ5ID09ICJKYXBhbiIpCmBgYAoKVGFidcS+a2EgdXZlZGVuw6EgbmnFvsWhaWUgbsOhbSBwb3NreXR1amUgesOha2xhZG7DqSBwb3Bpc27DqSDFoXRhdGlzdGlreSB2eWJyYW7DvWNoIGt2YW50aXRhdMOtdm55Y2ggcHJlbWVubsO9Y2guIFZ5bMO6xI1lbsOhIGplIEhlcGF0aXTDrWRhIEIgbmFrb8S+a28gw7pkYWogYm9sIGtvbsWhdGFudG7DvS4KCmBgYHtyfQojIG5pZWt0b3LDqSDFoXRhdGlzdGlreSBhIGljaCBwcmVoxL5hZCB2IHRhYnXEvmtlIEthYmxlRXh0cmEKbGlicmFyeShrYWJsZUV4dHJhKQp1ZGFqZSAlPiUKICBzZWxlY3QoQWR1bHRfbW9ydGFsaXR5LEFsY29ob2xfY29uc3VtcHRpb24sTWVhc2xlcyxCTUksUG9saW8sRGlwaHRoZXJpYSxHRFBfcGVyX2NhcGl0YSxQb3B1bGF0aW9uX21sbixMaWZlX2V4cGVjdGFuY3ksU2Nob29saW5nKSAlPiUKICBzdW1tYXJ5KCkgJT4lCiAga2FibGUoKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRkFMU0UpCmBgYAoKVnnFocWhaWUgdXZlZGVuw6EgdGFidcS+a2EgbsOhbSBwb3NreXR1amUgcHJlaMS+YWQgbyB6w6FrbGFkbsO9Y2ggxaF0YXRpc3RpY2vDvWNoIGNoYXJha3RlcmlzdGlrw6FjaCB2eWJyYW7DvWNoIHByZW1lbm7DvWNoLCBha28gc8O6IHByaWVtZXJuw6kgaG9kbm90eSwgcm96cHR5bCwgbWluaW11bSBhIG1heGltdW0uIFRpZXRvIGluZm9ybcOhY2llIG7DoW0gcG9tw6FoYWrDuiBsZXDFoWllIHBvY2hvcGnFpSByb3pkZWxlbmllIGEgcm96c2FoIGhvZG7DtHQgdiBuYcWhaWNoIGTDoXRhY2guIE5hIGRydWhlaiBzdHJhbmUgamUgemF1asOtbWF2w6EgYWogaW5mb3Jtw6FjaWEgbyB2esOham9tbsO9Y2ggdnrFpWFob2NoIG1lZHppIHTDvW1pdG8gcHJlbWVubsO9bWksIMSNbyBtw7TFvmVtZSBtZXJhxaUgcG9tb2NvdSBrb3JlbGHEjW5laiBtYXRpY2UuCgpgYGB7cn0KIyBncmFmaWNrw70gcHJlaMS+YWQgbyBrb3JlbGHEjW7DvWNoIHZ6xaVhaG9jaCB2eWphZHJ1amUgbmFzbGVkb3Zuw70gb2Jyw6F6b2sKCmNvcl9tYXRyaXggPC0gY29yKHVkYWplICU+JSBzZWxlY3QoQWR1bHRfbW9ydGFsaXR5LEFsY29ob2xfY29uc3VtcHRpb24sTWVhc2xlcyxCTUksUG9saW8sRGlwaHRoZXJpYSxHRFBfcGVyX2NhcGl0YSxQb3B1bGF0aW9uX21sbixMaWZlX2V4cGVjdGFuY3ksU2Nob29saW5nKSwgdXNlID0gImNvbXBsZXRlLm9icyIpCmNvcnJwbG90KGNvcl9tYXRyaXgsIG1ldGhvZCA9ICJjb2xvciIsIHR5cGUgPSAidXBwZXIiLCB0bC5jb2wgPQoiZGFya2JsdWUiLCB0bC5zcnQgPSA0NSwgdGl0bGUgPSAiS29yZWxhxI1uw6EgbWF0aWNhIHZ5YnJhbsO9Y2ggcHJlbWVubsO9Y2giLCBtYXIgPSBjKDAsMCwxLDApKQoKYGBgClV2ZWRlbsO9IGdyYWYgbsOhbSBwb3NreXR1amUgdml6dcOhbG55IHByZWjEvmFkIG8ga29yZWxhxI1uw71jaCB2esWlYWhvY2ggbWVkemkgdnlicmFuw71taSBwcmVtZW5uw71taS4gRmFyYnkgYSBpbnRlbnppdGEgZmFyaWViIG7DoW0gdW1vxb7FiHVqw7ogcsO9Y2hsbyBpZGVudGlmaWtvdmHFpSBzaWxuw6kgcG96aXTDrXZuZSBhbGVibyBuZWdhdMOtdm5lIGtvcmVsw6FjaWUuIFVwb3pvcsWIdWplbWUsIMW+ZSBrb3JlbMOhY2lhIG5lem5hbWVuw6Ega2F1emFsaXR1LgoKCgogClYgbmFzbGVkb3Zub20gem9icmF6ZW7DrSBqZSB1dmVkZW7DvSBncmFmIHbDvXZvamEgb8SNYWvDoXZhbmVqIGTEusW+a3kgZG/Fvml0aWEgdiBKYXBvbnNrdSB2IHJva29jaCAyMDAwLTIwMTUuIFZpZMOtbWUsIMW+ZSBvxI1ha8OhdmFuw6EgZMS6xb5rYSDFvml2b3RhIHNhIHp2ecWhb3ZhbGEgIG9kIHJva3UgMjAwMCB6IDgxIG5hIDgzIHJva292IHYgcm9rdSAyMDE1LCDEjW8gamUgcG96aXTDrXZueSB0cmVuZC4KCmBgYHtyfQojICBncmFmIHbDvXZvamEgb8SNYWvDoXZhbmVqIGTEusW+a3kgZG/Fvml0aWEgdiBKYXBvbnNrdSB2IHJva29jaCAyMDAwLTIwMTUuCmxpYnJhcnkoZ2dwbG90MikKZ2dwbG90KHVkYWplLCBhZXMoeCA9IFllYXIsIHkgPSBMaWZlX2V4cGVjdGFuY3kpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgbGFicyh0aXRsZSA9ICJWw712b2ogb8SNYWvDoXZhbmVqIGTEusW+a3kgZG/Fvml0aWEgdiBKYXBvbnNrdSAoMjAwMC0yMDE1KSIsCiAgICAgICB4ID0gIlJvayIsCiAgICAgICB5ID0gIk/EjWFrw6F2YW7DoSBkxLrFvmthIGRvxb5pdGlhIikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCgpOYSB6YcSNaWF0a3Ugc2EgcG9rw7pzbWUgbyB2eXJvdm5hbmllIHByaWViZWh1IHRlanRvIHByZW1lbm5laiB2IMSNYXNlIHBvbW9jb3UgbGluZcOhcm5laiByZWdyZXNpZSwga2RlIG5lesOhdmlzbG91IHByZW1lbm5vdSBidWRlIHJvayBhIHrDoXZpc2xvdSBwcmVtZW5ub3UgYnVkZSBvxI1ha8OhdmFuw6EgZMS6xb5rYSBkb8W+aXRpYS4gT2RoYWRuZW1lIGtvZWZpY2llbnR5IHRlanRvIHJlZ3Jlc2llIGEgcG9zw7pkaW1lIGt2YWxpdHUgdnlyb3ZuYW5pYSBwb21vY291IHVrYXpvdmF0ZcS+b3YsIGFrbyBqZSBSLXNxdWFyZWQgYSBwLXZhbHVlLgoKYGBge3J9CiMgdnlyb3ZuYW5pZSBwcmllYmVodSBvxI1ha8OhdmFuZWogZMS6xb5reSBkb8W+aXRpYSB2IMSNYXNlCm1vZGVsIDwtIGxtKExpZmVfZXhwZWN0YW5jeSB+IFllYXIsIGRhdGEgPSB1ZGFqZSkKCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoa2FibGVFeHRyYSkKCiMga29lZmljaWVudHkgcmVncmVzaWUKdGlkeShtb2RlbCkgJT4lCiAga2FibGUoZGlnaXRzID0gMywgY2FwdGlvbiA9ICJPZGhhZG51dMOpIGtvZWZpY2llbnR5IHJlZ3Jlc2llIikgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEZBTFNFKQoKIyBrdmFsaXRhIHZ5cm92bmFuaWEKZ2xhbmNlKG1vZGVsKSAlPiUKICBrYWJsZShkaWdpdHMgPSAzLCBjYXB0aW9uID0gIlVrYXpvdmF0ZWxlIGt2YWxpdHkgdnlyb3ZuYW5pYSIpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGQUxTRSkKCmBgYAoKVsO9c2xlZGt5IHJlZ3Jlc2llIG7DoW0gdWthenVqw7osIMW+ZSBrb2VmaWNpZW50IHByZSByb2sgamUgcG96aXTDrXZueSBhIMWhdGF0aXN0aWNreSB2w716bmFtbsO9LCDEjW8gbmF6bmHEjXVqZSwgxb5lIG/EjWFrw6F2YW7DoSBkxLrFvmthIGRvxb5pdGlhIHYgSmFwb25za3Ugc2EgenZ5xaFvdmFsYSB2IHByaWViZWh1IHJva292IDIwMDAtMjAxNS4gSmVqIHByaWVtZXJuw70gcm/EjW7DvSBuw6FyYXN0IGRvc2Fob3ZhbCAwLDE2Mi4gSG9kbm90YSBSLXNxdWFyZWQgaG9kbm90YSBuw6FtIGhvdm9yw60sIMW+ZSBtb2RlbCB2eXN2ZXTEvnVqZSA5NiAlIHZhcmlhYmlsaXR5IG1vZGVsdS4gUG9kxL5hIGhvZG5vdHkgcC12YWx1ZSBtw7TFvmVtZSBwb3ZlZGHFpSwgxb5lIG1vZGVsIGFrbyBjZWxvayBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvS4KCmBgYHtyfQojIHRlcmF6IHZ5xaHFoWllIHV2ZWRlbsO9IG9icsOhem9rIGRvcGxuw61tZSBvIHJlZ3Jlc27DuiBwcmlhbWt1CmdncGxvdCh1ZGFqZSwgYWVzKHggPSBZZWFyLCB5ID0gTGlmZV9leHBlY3RhbmN5KSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UsIGNvbG9yID0gImdyZWVuIikgKwogIGxhYnModGl0bGUgPSAiVsO9dm9qIG/EjWFrw6F2YW5laiBkxLrFvmt5IGRvxb5pdGlhIHYgSmFwb25za3UgKDIwMDAtMjAxNSkgcyByZWdyZXNub3UgcHJpYW1rb3UiLAogICAgICAgeCA9ICJSb2siLAogICAgICAgeSA9ICJPxI1ha8OhdmFuw6EgZMS6xb5rYSBkb8W+aXRpYSIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgoKIyMjVsO9dm9qIHNwb3RyZWJ5IGFsa29ob2x1ClRlcmF6IHNhIHBvenJpZW1lLCBha28gc2Egdnl2w71qYSBrb256dW3DoWNpYSBhbGtvaG9sdSB2IMSNYXNlIG9kIHJva3UgMjAwMCBkbyByb2t1IDIwMTUgdiBKYXBvbnNrdS4gTmFrb8S+a28gYWxrb2hvbCBqZSBmYWt0b3JvbSBuZWdhdMOtdm5lIHZwbMO9dmFqw7pjaW0gbmEgZMS6xb5rdSBkb8W+aXRpYS4KCgpgYGB7cn0KbW9kZWxfYWxrb2hvbCA8LSBsbShBbGNvaG9sX2NvbnN1bXB0aW9uIH4gWWVhciwgZGF0YSA9IHVkYWplKQojIGt2YWxpdGEgcmVncmVzaWUKdGlkeShtb2RlbF9hbGtvaG9sKSAlPiUKICBrYWJsZShkaWdpdHMgPSAzLCBjYXB0aW9uID0gIk9kaGFkbnV0w6kga29lZmljaWVudHkgcmVncmVzaWUgcHJlIHNwb3RyZWJ1IGFsa29ob2x1IikgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEZBTFNFKQoKIyBhIHRlcmF6IG1vZGVsIHF1YWxpdHkgc3RhdGlzdGljcyBSIHNxdWFyZWQKcjI8LSBzdW1tYXJ5KG1vZGVsX2Fsa29ob2wpJHIuc3F1YXJlCmFkal9yMiA8LXN1bW1hcnkobW9kZWxfYWxrb2hvbCkkYWRqLnIuc3F1YXJlCiNwcmludHVqZW1lIGtvZWZpY2llbnQgZGV0ZXJtaW5hbmNpZSBhIHVwcmF2ZW7DvSBrb2VmaWNpZW50IGRldGVybWluYW5jaWUKY2F0ICgiUi1zcXVhcmVkOiIscm91bmQgKHIyLDMpLCAiXG4iKQpjYXQgKCJBZGp1c3RlZCBSLXNxdWFyZWQ6Iixyb3VuZCAoYWRqX3IyLDMpLCAiXG4iKQpgYGAKVsO9c2xlZGt5IHJlZ3Jlc2llIHVrYXp1asO6LCDFvmUga29lZmljaWVudCBwcmUgcHJlbWVubsO6IHJvayBqZSBwb3ppdMOtdm55LCDEjW8gbmF6bmHEjXVqZSBtaWVybnkgcmFzdCBzcG90cmVieSBhbGtvaG9sdSB2IEphcG9uc2t1IHYgb2Jkb2LDrSByb2tvdiAyMDAwIOKAkyAyMDE1LiBPZGhhZG92YW7DvSBrb2VmaWNpZW50IDAsMDQ5IHpuYW1lbsOhLCDFvmUgc3BvdHJlYmEgYWxrb2hvbHUgc2EgdiBwcmllbWVyZSB6dnnFoW92YWxhIHByaWJsacW+bmUgbyAwLDA0OSBqZWRub3RreSByb8SNbmUuIEhvZG5vdGEgcC12YWx1ZSAoMCwwODQpIHbFoWFrIG5hem5hxI11amUsIMW+ZSB0ZW50byBrb2VmaWNpZW50IG5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSBuYSBobGFkaW5lIHbDvXpuYW1ub3N0aSA1ICUsIHByZXRvIG5pZSBqZSBtb8W+bsOpIHMgZG9zdGF0b8SNbm91IGlzdG90b3UgcG90dnJkacWlIGV4aXN0ZW5jaXUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw6lobyB0cmVuZHUgcmFzdHUgc3BvdHJlYnkgYWxrb2hvbHUgdiBzbGVkb3Zhbm9tIG9iZG9iw60uCgoKI09icsOhem9rIG8gc2t1dG/EjW7DvWNoIHZ5cm92bmFuw71jaCBob2Rub3TDoWNoIHNwb3RyZWJ5IGFsa29ob2x1CiAgICAKYGBge3J9CmZpdHRlZF92YWxzIDwtIGZpdHRlZChtb2RlbF9hbGtvaG9sKQojIHZ5a3Jlc2xlbmllIHNrdXRvxI1uw71jaCBhIHZ5cm92bmFuw71jaCBob2Ruw7R0IC0gQWxjb2hvbF9jb25zdW1wdGlvbiBhIGZpdHRlZF92YWx1ZXMKZ2dwbG90KHVkYWplLCBhZXMoeCA9IFllYXIpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gQWxjb2hvbF9jb25zdW1wdGlvbiksIGNvbG9yID0gImRhcmtibHVlIiwgc2l6ZSA9IDEpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBmaXR0ZWRfdmFscyksIGNvbG9yID0gIm9yYW5nZSIsIHNpemUgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgbGFicyh0aXRsZSA9ICJTa3V0b8SNbsOpIHZzLiBWeXJvdm5hbsOpIGhvZG5vdHkgc3BvdHJlYnkgYWxrb2hvbHUgdiBKYXBvbnNrdSAoMjAwMC0yMDE1KSIsCiAgICAgICB4ID0gIlJvayIsCiAgICAgICB5ID0gIlNwb3RyZWJhIGFsa29ob2x1IikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgbWF4KHVkYWplJEFsY29ob2xfY29uc3VtcHRpb24sIGZpdHRlZF92YWxzKSAqIDEuMSkpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYAoKCiMjIERpYWdub3N0aWNrw6kgZ3JhZnkKCiMjIyBSZXNpZHVhbHMgdnMgRml0dGVkCgpHcmFmICpSZXNpZHVhbHMgdnMgRml0dGVkKiBzbMO6xb5pIG5hIHBvc8O6ZGVuaWUgbGluZWFyaXR5IG1vZGVsdSBhIHByaWJsacW+bmVqIGtvbsWhdGFudG5vc3RpIHJvenB0eWx1IHJlesOtZHXDrS4gUmV6aWR1w6FseSBieSBtYWxpIGJ5xaUgcm96bG/FvmVuw6kgbsOhaG9kbmUgb2tvbG8gbnVsb3ZlaiBob2Rub3R5IGJleiB2w71yYXpuw6lobyBzeXN0ZW1hdGlja8OpaG8gdnpvcnUuIEFrIHNhIG9iamF2w60gdml6dcOhbG5lIHbDvXpuYW1uw6kgemFrcml2ZW5pZSDEjWVydmVuZWogdnlobGFkem92YWNlaiDEjWlhcnksXltMT0VTUyAoTE9jYWwgcmVnckVTU2lvbikga3JpdmthIHByZWRzdGF2dWplIGxva8OhbG5lIHZ5aGxhZGVuw70gdHJlbmQgbWVkemkgcHJlbWVubsO9bWkgYmV6IHByZWRwb2tsYWR1IGtvbmtyw6l0bmVobyBmdW5rxI1uw6lobyB0dmFydS5dIGt0b3LDoSBzbMO6xb5pIG5hIHZpenXDoWxudSBpZGVudGlmaWvDoWNpdSBzeXN0ZW1hdGlja8O9Y2ggb2RjaMO9bG9rIG9kIG7DoWhvZG7DqWhvIHJvemxvxb5lbmlhIHJlesOtZHXDrSwgc2lnbmFsaXp1amUgdG8gdXLEjWl0w6kgc3lzdGVtYXRpY2vDqSBwcm9ibMOpbXkuIEFrIGplIExPRVNTIHByaWJsacW+bmUgaG9yaXpvbnTDoWxuYSwgbW9kZWwgamUgxaFwZWNpZmlrb3ZhbsO9IHZob2RuZTsgYWsgc2EgemFrcml2dWplLCBtw7TFvmUgdG8gbmF6bmHEjW92YcWlIG5lbGluZWFyaXR1LCBjaHlibsO6IMWhcGVjaWZpa8OhY2l1ICh0ZWRhIHbDvWJlciB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoKSBhbGVibyBpbsO9IHByb2Jsw6ltIHYgbW9kZWxpLiBBayBzYSBib2R5IHJvesWhaXJ1asO6IGFsZWJvIHp1xb51asO6IHYgdHZhcmUgbGlldmlrYSwgbcO0xb5lIMOtc8WlIG8gaGV0ZXJvc2tlZGFzdGljaXR1LgoKYGBge3IgcmVzaWQtZml0dGVkLCBmaWcuY2FwPSJSZXNpZHVhbHMgdnMgRml0dGVkIiwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NX0KcGxvdChtb2RlbCwgd2hpY2ggPSAxKQpgYGAKClJlemlkdcOhIHPDuiByb3psb8W+ZW7DqSBwcmlibGnFvm5lIG9rb2xvIG51bG92ZWogaG9kbm90eSwgYXbFoWFrIHByaSBuYWptZW7FocOtY2ggYWogbmFqdsOkxI3FocOtY2ggb2RoYWRudXTDvWNoIGhvZG5vdMOhY2ggbW9kZWwgc3lzdGVtYXRpY2t5IG5hZGhvZG5vY3VqZSwgcmVzcC4gcG9kaG9kbm9jdWplIHNrdXRvxI1uw6kgaG9kbm90eS4gRG8gdXLEjWl0ZWogbWllcnkgdG8gbcO0xb5lIGJ5xaUgb3ZwbHl2bmVuw6kgb2TEvmFobMO9bWkgcG96b3JvdmFuaWFtaSwgbmFqbcOkIHBvem9yb3ZhbsOtbSDEjS4gMTQxMSBhIDUzMC4gUG/EjWV0IHBvem9yb3ZhbsOtIGplIHbFoWFrIHJlbGF0w612bmUgbWFsw70sIHByZXRvIHTDunRvIHNrdXRvxI1ub3PFpSB6YXRpYcS+IG5lcG92YcW+dWplbWUgemEgesOhc2FkbsO9IHByb2Jsw6ltIGEgcG9kcm9ibmVqxaFpZSBzYSBrIG5laiBtw7TFvmVtZSB2csOhdGnFpSBwcmkgYW5hbMO9emUgxI9hbMWhw61jaCBkaWFnbm9zdGlja8O9Y2ggZ3JhZm92LgoKCiMjIyBRLVEgcGxvdAoKKlEtUSBncmFmKiBwb3Jvdm7DoXZhIHJvemRlbGVuaWUgxaF0YW5kYXJkaXpvdmFuw71jaCByZXrDrWR1w60gcyB0ZW9yZXRpY2vDvW0gbm9ybcOhbG55bSByb3pkZWxlbsOtbS4gQWsgYm9keSBsZcW+aWEgcHJpYmxpxb5uZSBuYSBwcmlhbWtlLCBwcmVkcG9rbGFkIG5vcm1hbGl0eSByZXrDrWR1w60gamUgcHJpYmxpxb5uZSBzcGxuZW7DvS4gVsO9cmF6bmVqxaFpZSBvZGNow71sa3kgbmEga3Jham9jaCBuYXpuYcSNdWrDuiBtb8W+bsOpIHByb2Jsw6lteSBzIGV4dHLDqW1ueW1pIGhvZG5vdGFtaSBhbGVibyBzIMWlYcW+xaHDrW1pIGtvbmNhbWkgcm96ZGVsZW5pYS4gVXLEjWl0b3UgcG9tw7Rja291IHR1IG3DtMW+ZSBiecWlIG5hc2xlZG92bsOhIHRhYnXEvmthOgoKYGBge3IgcXFfdGFibGVfc2ssIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoa2FibGVFeHRyYSkKCnFxX3RhYmxlIDwtIGRhdGEuZnJhbWUoCiAgUHLDrXBhZCA9IGMoCiAgICAiTm9ybcOhbG5lIHJvemRlbGVuaWUiLAogICAgIsS9YXZvc3RyYW5uw6EgxaFpa21vc8WlIChuZWdhdMOtdm5hKSIsCiAgICAiUHJhdm9zdHJhbm7DoSDFoWlrbW9zxaUgKHBveml0w612bmEpIiwKICAgICJTeW1ldHJpY2vDqSwgdnlzb2vDoSDFoXBpY2F0b3PFpSAoPiAzKSIsCiAgICAiU3ltZXRyaWNrw6ksIG7DrXprYSDFoXBpY2F0b3PFpSAoPCAzKSIKICApLAogIGBUdmFyIFEtUSBncmFmdWAgPSBjKAogICAgIlByaWFta2EiLAogICAgIlByZWhudXTDvSBuYWRvbCAo4oipIHR2YXIpIiwKICAgICJQcmVobnV0w70gbmFob3IgKOKIqiB0dmFyKSIsCiAgICAiUy10dmFyIiwKICAgICJPYnLDoXRlbsO9IFMtdHZhciIKICApLAogIGDEvWF2w70gY2h2b3N0YCA9IGMoCiAgICAiTmEgcHJpYW1rZSIsCiAgICAiTmFkIHByaWFta291IiwKICAgICJQb2QgcHJpYW1rb3UiLAogICAgIlBvZCBwcmlhbWtvdSIsCiAgICAiTmFkIHByaWFta291IgogICksCiAgYFByYXbDvSBjaHZvc3RgID0gYygKICAgICJOYSBwcmlhbWtlIiwKICAgICJQb2QgcHJpYW1rb3UiLAogICAgIk5hZCBwcmlhbWtvdSIsCiAgICAiTmFkIHByaWFta291IiwKICAgICJQb2QgcHJpYW1rb3UiCiAgKSwKICBJbnRlcnByZXTDoWNpYSA9IGMoCiAgICAiRMOhdGEgbWFqw7ogbm9ybcOhbG5lIHJvemRlbGVuaWUiLAogICAgIkRsaMO9IMS+YXbDvSBjaHZvc3QgKGV4dHLDqW1uZSBuw616a2UgaG9kbm90eSkiLAogICAgIkRsaMO9IHByYXbDvSBjaHZvc3QgKGV4dHLDqW1uZSB2eXNva8OpIGhvZG5vdHkpIiwKICAgICLFpGHFvmvDqSBjaHZvc3R5ICh2aWFjIGV4dHLDqW1ueWNoIGhvZG7DtHQpIiwKICAgICLEvWFoa8OpIGNodm9zdHkgKG1lbmVqIGV4dHLDqW1ueWNoIGhvZG7DtHQpIgogICkKKQoKa2FibGUocXFfdGFibGUsIGNhcHRpb24gPSAiSW50ZXJwcmV0w6FjaWEgUeKAk1EgZ3JhZnUiKSAlPiUKICBrYWJsZV9zdHlsaW5nKAogICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLAogICAgZnVsbF93aWR0aCA9IEZBTFNFLAogICAgcG9zaXRpb24gPSAiY2VudGVyIgogICkgJT4lCiAgcm93X3NwZWMoMCwgYm9sZCA9IFRSVUUpCmBgYAoKTmlla2VkeSBob3ZvcsOtbWUgbyBwb23DtGNrZToKCi0gUHJpYW1rYSDihpIgbm9ybcOhbG5lIHJvemRlbGVuaWUKLSDiiKog4oaSIHByYXZvc3RyYW5uw6EgxaFpa21vc8WlCi0g4oipIOKGkiDEvmF2b3N0cmFubsOhIMWhaWttb3PFpQotIFMg4oaSIHZ5c29rw6EgxaFwaWNhdG9zxaUgKMWlYcW+a8OpIGNodm9zdHkpCi0gb2Jyw6F0ZW7DqSBTIOKGkiBuw616a2EgxaFwaWNhdG9zxaUKCgpgYGB7ciBxcS1wbG90LCBmaWcuY2FwPSJOb3JtYWwgUS1RIHBsb3QiLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD01fQpwbG90KG1vZGVsLCB3aGljaCA9IDIpCmBgYAoKVXByYXZlbsO9IHBvcGlzIHBvZMS+YSBncmFmdToKCi0tLQoKUS1RIGdyYWYgcG9yb3Zuw6F2YSBlbXBpcmlja8OpIHJvemRlbGVuaWUgxaF0YW5kYXJkaXpvdmFuw71jaCByZXrDrWR1w60gcyB0ZW9yZXRpY2vDvW0gbm9ybcOhbG55bSByb3pkZWxlbsOtbS4gViBwcsOtcGFkZSBzcGxuZW5pYSBwcmVkcG9rbGFkdSBub3JtYWxpdHkgYnkgbWFsaSBib2R5IGxlxb5hxaUgcHJpYmxpxb5uZSBuYSBkaWFnb27DoWxuZWogcHJpYW1rZS4KClYgbmHFoW9tIHByw61wYWRlIHbDpMSNxaFpbmEgYm9kb3YgdiBzdHJlZG5laiDEjWFzdGkgZ3JhZnUgbGXFvsOtIHBvbWVybmUgYmzDrXprbyBwcmlhbWt5LCDEjW8gbmF6bmHEjXVqZSwgxb5lIHByZSB2w6TEjcWhaW51IHBvem9yb3ZhbsOtIGplIHByZWRwb2tsYWQgbm9ybWFsaXR5IHByaWJsacW+bmUgc3BsbmVuw70uIENlbnRyw6FsbmEgxI1hc8WlIHJvemRlbGVuaWEgcmV6w61kdcOtIHNhIHRlZGEgc3Byw6F2YSBwb2RvYm5lIGFrbyBub3Jtw6FsbmUgcm96ZGVsZW5pZS4KCk5hIMS+YXZvbSBrb25jaSBncmFmdSBkb2Now6FkemEgayB2w71yYXpuZWrFoWllbXUgb2RjaMO9bGVuaXUgYm9kb3YgcG9kIHJlZmVyZW7EjW7DuiBwcmlhbWt1LiBOYWptw6QgcG96b3JvdmFuaWUgxI0uIDUzMCBwcmVkc3RhdnVqZSBleHRyw6ltbmUgesOhcG9ybsOpIHJlemlkdXVtLCDEjW8gbmF6bmHEjXVqZSDFpWHFvsWhw60gxL5hdsO9IGNodm9zdCByb3pkZWxlbmlhIG9wcm90aSBub3Jtw6FsbmVtdSByb3pkZWxlbml1LiBNZW7FoWlhIG9kY2jDvWxrYSBqZSB2aWRpdGXEvm7DoSBhaiBwcmkgcG96b3JvdmFuw60gxI0uIDU2Ni4KCk5hIHByYXZvbSBrb25jaSBncmFmdSBzw7ogYm9keSByZWxhdMOtdm5lIGJsw616a28gcmVmZXJlbsSNbmVqIHByaWFta3kuIFBvem9yb3ZhbmllIMSNLiAxNDExIHNhIG5hY2jDoWR6YSBtaWVybmUgcG9kIHByaWFta291LCDEjW8gcG91a2F6dWplIGxlbiBuYSBtYWzDuiBvZGNow71sa3Ugb2Qgbm9ybWFsaXR5IGEgbmVwcmVkc3RhdnVqZSB2w71yYXpuw70gcHJvYmzDqW0uCgpDZWxrb3ZvIG1vxb5ubyBrb27FoXRhdG92YcWlLCDFvmUgbm9ybWFsaXRhIHJlesOtZHXDrSBqZSBwcmlibGnFvm5lIHNwbG5lbsOhLCBhdsWhYWsgcyBtaWVybnltaSBvZGNow71sa2FtaSB2IGNodm9zdG9jaCByb3pkZWxlbmlhLCBuYWptw6QgdiDEvmF2b20gY2h2b3N0ZSBzcMO0c29iZW7DvW1pIG9kxL5haGzDvW1pIHBvem9yb3ZhbmlhbWkuIFogcHJha3RpY2vDqWhvIGjEvmFkaXNrYSBpZGUgbyBtaWVybmUgcG9ydcWhZW5pZSBwcmVkcG9rbGFkdSBub3JtYWxpdHksIGt0b3LDqSB2xaFhayB2emjEvmFkb20gbmEgZG9icsOpIHNwcsOhdmFuaWUgdsOkxI3FoWlueSByZXrDrWR1w60gbmVtdXPDrSBwcmVkc3Rhdm92YcWlIHrDoXNhZG7DvSBwcm9ibMOpbSBwcmUgxI9hbMWhaXUgYW5hbMO9enUuCgojIyMgU2NhbGUtTG9jYXRpb24gcGxvdAoKKlNjYWxlLUxvY2F0aW9uIGdyYWYqIHNhIHBvdcW+w612YSBuYSBwb3PDumRlbmllIGhvbW9za2VkYXN0aWNpdHksIHRlZGEga29uxaF0YW50bm9zdGkgcm96cHR5bHUgcmV6w61kdcOtLiBBayBzw7ogYm9keSByb3psb8W+ZW7DqSBwcmlibGnFvm5lIHJvdm5vbWVybmUgYSDEjWVydmVuw6EgxI1pYXJhIGplIHJlbGF0w612bmUgdm9kb3Jvdm7DoSwgaWRlIG8gcHJpYXpuaXbDvSB2w71zbGVkb2suIFN5c3RlbWF0aWNrw70gcmFzdCBhbGVibyBwb2tsZXMgbmF6bmHEjXVqZSwgxb5lIHJvenB0eWwgcmV6w61kdcOtIHNhIG1lbsOtIHMgw7pyb3bFiG91IHByZWRpa292YW7DvWNoIGhvZG7DtHQuCgpgYGB7ciBzY2FsZS1sb2NhdGlvbiwgZmlnLmNhcD0iU2NhbGUtTG9jYXRpb24gcGxvdCIsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTV9CnBsb3QobW9kZWwsIHdoaWNoID0gMykKYGBgCgoKVHUgamUgdXByYXZlbsO9IHBvcGlzIHByZXNuZWrFoWllIHBvZMS+YSBncmFmdToKCkJvZHkgc8O6IHJvenB0w71sZW7DqSBwb21lcm5lIHJvdm5vbWVybmUgdiBjZWxvbSByb3pzYWh1IHZ5cm92bmFuw71jaCBob2Ruw7R0LCBiZXogdsO9cmF6bsOpaG8gc3lzdGVtYXRpY2vDqWhvIHZ6b3J1LiDEjGVydmVuw6EgdnlobGFkem92YWNpYSBrcml2a2EgbWllcm5lIHJhc3RpZSBwcmkgbmnFvsWhw61jaCBob2Rub3TDoWNoLCBuw6FzbGVkbmUgc2Egc3RhYmlsaXp1amUgYSBrdSBrb25jdSBsZW4gdmXEvm1pIG1pZXJuZSBrb2zDrcWhZSwgYmV6IHbDvXJhem7DqWhvIHJhc3TDumNlaG8gdHJlbmR1IHByaSB2ecWhxaHDrWNoIGhvZG5vdMOhY2guCgpOaWVrdG9yw6kgYm9keSAobmFwci4gcG96b3JvdmFuaWEgb3puYcSNZW7DqSA1MzAsIDU2NiBhIDE0MTEpIHNhIG9kIG9zdGF0bsO9Y2ggbWllcm5lIG9kY2h5xL51asO6LCBtw7TFvnUgdGVkYSBwcmVkc3Rhdm92YcWlIHBvdGVuY2nDoWxuZSBvZMS+YWhsw6kgYWxlYm8gdnBseXZuw6kgcG96b3JvdmFuaWEsIGF2xaFhayBpY2ggdnBseXYgbmllIGplIGV4dHLDqW1ueS4KCk5ldnpuaWvDoSB0eXBpY2vDvSDigJ5saWV2aWtvdml0w73igJwgdHZhciwga3RvcsO9IGJ5IG5hem5hxI1vdmFsIHbDvXJhem7DqSBwb3J1xaFlbmllIHByZWRwb2tsYWR1IGtvbsWhdGFudG7DqWhvIHJvenB0eWx1LiBWYXJpYWJpbGl0YSByZXrDrWR1w60gc2EgamF2w60gYWtvIHJlbGF0w612bmUgc3RhYmlsbsOhIG5hcHJpZcSNIGhvZG5vdGFtaSwgxI1vIG5hem5hxI11amUsIMW+ZSBwcmVkcG9rbGFkIGhvbW9za2VkYXN0aWNpdHkgamUgc3BsbmVuw70sIHByw61wYWRuZSBsZW4gdmXEvm1pIG1pZXJuZSBuYXJ1xaFlbsO9LgoKIyMjIFJlc2lkdWFscyB2cyBMZXZlcmFnZQoKR3JhZiAqUmVzaWR1YWxzIHZzIExldmVyYWdlKiBwb23DoWhhIGlkZW50aWZpa292YcWlIHZwbHl2bsOpIHBvem9yb3ZhbmlhLiBMZXZlcmFnZSB0byBwcmVkc3RhdnVqZSB2emlhbGVub3PFpSBkYW7DqWhvIHBvem9yb3ZhbmlhIHbFoWV0a8O9Y2ggdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCAodGVkYSB2ZWt0b3JhKSBvZCBvc3RhdG7DvWNoLCByZXNwLiBvZCBzdHJlZG7DqWhvIHZla3RvcmEgdsWhZXRreWNoIHBvem9yb3ZhbsOtLiBUw610byB2emRpYWxlbm9zxaUgamUgbm9ybW92YW7DoSBuYSBpbnRlcnZhbCAoMCwxKSBhIHbDpMSNxaFpbmEgcG96b3JvdmFuw60gbcOhIHZlxL5taSBtYWzDvSBsZXZlcmFnZS4gQWsgc2Egdnlza3l0dWrDuiBwb3pvcm92YW5pYSBzIHZ5c29rw71tIGxldmVyYWdlLCBpZGVudGlmaWt1amVtZSBpY2ggbmEgdm9kb3Jvdm5laiBvc2kgYSBtw7TFvnUgem5hbWVuYcWlIHBvdGVuY2nDoWxuZSBuZWJlenBlxI1lbnN0dm8gdiBza3Jlc2xlbsOtIHBhcmFtZXRyb3Ygdnlyb3Zuw6F2YWrDumNlaiBuYWRyb3ZpbnkgKHRlZGEgb2RoYWRvdmFuw71jaCAkXGJldGEkIGtvZWZpY2llbnRvdikuIFBvem9yb3ZhbmlhIHMgdnlzb2tvdSBob2Rub3RvdSBsZXZlcmFnZSBhIHPDusSNYXNuZSB2ZcS+a8O9bWkgcmV6w61kdWFtaSBtw7TFvnUgbcO0xb51IHNww7Rzb2JvdmHFpSB0ZW50byBwcm9ibMOpbS4gQWsgc2Egbmlla3RvcsOpIGJvZHkgbmFjaMOhZHphasO6IGJsw616a28gYWxlYm8gemEga3JpdmthbWkgQ29va292ZWogdnpkaWFsZW5vc3RpLCBqZSB2aG9kbsOpIGljaCBwb2Ryb2JuZWrFoWllIHByZXNrw7ptYcWlLgoKCmBgYHtyIHJlc2lkLWxldmVyYWdlLCBmaWcuY2FwPSJSZXNpZHVhbHMgdnMgTGV2ZXJhZ2UiLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD01fQpwbG90KG1vZGVsLCB3aGljaCA9IDUpCmBgYAoKClR1IGplIHVwcmF2ZW7DvSBwb3BpcyBwb2TEvmEgem9icmF6ZW7DqWhvIGdyYWZ1OgoKViBuYcWhb20gcHLDrXBhZGUgbcOhIHbDpMSNxaFpbmEgcG96b3JvdmFuw60gbsOtemtlIGHFviBzdHJlZG7DqSBob2Rub3R5IGxldmVyYWdlIGEgamUgcm96cHTDvWxlbsOhIG5ham3DpCB2IGludGVydmFsZSBwcmlibGnFvm5lIG9kIDAuMDUgZG8gMC4yMCwgxI1vIG5hem5hxI11amUsIMW+ZSDFvmlhZG5lIHBvem9yb3ZhbmllIG5lbcOhIGV4dHLDqW1uZSB2eXNva8O6IHDDoWtvdsO6IGhvZG5vdHUuIETDoXRhIHRlZGEgbmVww7Rzb2JpYSB2w71yYXpuZSBuZXZ5dsOhxb5lbmUgeiBoxL5hZGlza2EgdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaC4KClogaMS+YWRpc2thIHJlesOtZHXDrSB2w6TEjcWhaW5hIGJvZG92IG5ldnlrYXp1amUgZXh0csOpbW5lIGhvZG5vdHksIGF2xaFhayBuaWVrdG9yw6kgcG96b3JvdmFuaWEgKG5ham3DpCA1MzApIG1hasO6IHbDvXJhem5lasWhaWUgesOhcG9ybsOpIHJlesOtZHV1bS4gT2tyZW0gdG9obyBib2R5IGFrbyAxMTk3IGEgNTY2IG1hasO6IHZ5xaHFoWllIGxldmVyYWdlLCDEjW8gem5hbWVuw6EsIMW+ZSBtw7TFvnUgbWHFpSB2w6TEjcWhw60gdnBseXYgbmEgb2RoYWQgbW9kZWx1LgoKS29udMO6cnkgQ29va292ZWogdnpkaWFsZW5vc3RpIHVrYXp1asO6IG1pZXJ1IHZwbHl2dSBqZWRub3RsaXbDvWNoIHBvem9yb3ZhbsOtLiDFvWlhZG55IGJvZCB6amF2bmUgbmVwcmVrcmHEjXVqZSBocmFuaWN1IGhvZG5vdHkgMSwgYXbFoWFrIHBvem9yb3ZhbmllIDUzMCBzYSBuYWNow6FkemEgdiBvYmxhc3RpIHZ5xaHFocOtY2ggaG9kbsO0dCBDb29rb3ZlaiB2emRpYWxlbm9zdGkgKG1lZHppIDAuNSBhIDEpLCDEjW8gbmF6bmHEjXVqZSwgxb5lIG3DtMW+ZSBiecWlIHBvdGVuY2nDoWxuZSB2cGx5dm7DqSBhIHphc2zDusW+aSBzaSBibGnFvsWhaWUgcHJlc2vDum1hbmllLgoKQ2Vsa292byBtb8W+bm8ga29uxaF0YXRvdmHFpSwgxb5lIG1vZGVsIG5lb2JzYWh1amUgZXh0csOpbW5lIHZwbHl2bsOpIHBvem9yb3ZhbmlhLCBrdG9yw6kgYnkgesOhc2FkbmUgbmFyw7rFoWFsaSBqZWhvIHN0YWJpbGl0dSwgYXbFoWFrIGV4aXN0dWrDuiBqZWRub3RsaXbDqSBib2R5IChuYWptw6QgNTMwLCBwcsOtcGFkbmUgMTE5NyBhIDU2NiksIGt0b3LDqSBtw7TFvnUgbWHFpSB6dsO9xaFlbsO9IHZwbHl2IG5hIHbDvXNsZWRreSBhIGplIHZob2Ruw6kgaW0gdmVub3ZhxaUgcG96b3Jub3PFpS4K