S využitím databázy WHO
Life Expactancy Data database.
Pri ďalšej práci budeme používať knižnice
library(zoo)
library(tseries)
library(lmtest)
library(sandwich)
library(car)
rm(list=ls())
V hlavnom menu som Session nastavil na Source
File Location. Môžeme to urobiť aj interaktívnym spôsobom - napísať
dole do Console (alebo to zahrnúť priamo do skriptu) ako
setwd(“/Cloud/project/tyzdne/tyzden5”)
Organizácia priečinkov a podpriečinkov sa však môže líšiť v
závislosti od projektu, preto som ich nezaradil do Chunk-u.
Údaje o očakávanej dĺžke života sú usporiadané v súbore csv,
stĺpce sú oddelené znakom “,” a používajú desatinnú čiarku. V pracovnom
priečinku som vytvoril podpriečinok s názvom udaje, aby som
oddelil údaje od zvyšku projektu. Môj priečinok sa tiež nazýva
udaje.
Nie všetky údaje budú použité, preto som vybral len niektoré stĺpce
pre neskoršie použitie.
Úvod do problému, stanovenie hypotéz
Rozhodol som sa modelovať strednú dĺžku života
Life.expectancy v závislosti od troch vysvetľujúcich premenných
a to BMI, HDP na obyvateľa GDP a stredný počet rokov
štúdia Schooling.
Naša pracovná hypotéza hovorí o štatisticky významnom vplyve všetkých
troch vysvetľujúcich premenných, pričom u premenných GDP a
Schooling by malo ísť o pozitívny vplyv (očakávame kladné
znamienko odhadovaného regresného koeficienta) a v prípade BMI by malo
ísť of negatívny vplyv (so záporným znamienkom)
Príprava databázy, čistenie a úprava údajov
Keďže niektoré údaje chýbajú, doplnil som ich mediánovými hodnotami
premennej, ktorú zvažujem. lm
udaje <- read.csv("udaje/Life_Expectancy_Data.csv",dec=".",sep=",",header = TRUE)
Error in file(file, "rt") : cannot open the connection
Teraz chceme vidieť tvar údajov (či nie sú v nich nejaké
nezrovnalosti – napríklad hodnoty 0).
Lineárna regresia
Model odhadujeme príkazom lm()
Objekt triedy lm() nám poskytuje niekoľko výsledkov:
- Vector odhadnutých koeficientov model$coefficients
- Vektor rezíduí model$ residuals
- Vektor vyrovnaných hodnôt vysvetľovanej veličiny
model$fitted.values
- Maticu X model$x
Súhrn odhadovaného modelu nám poskytuje súbor odhadovaných regresných
koeficientov, ktorých znamienka budú rozoberané neskôr. Ak hovoríme o
vlastnostiach modelu ako celku, pozrime sa najskôr na nasledujúce
obrázky. Na základe Q-Q grafu získavame dojem o možných problémoch
porušenia normality rezíduí.
Residuals vs. fitted
Interpretácia vášho konkrétneho grafu
Centrovanie okolo nuly
Reziduály kolíšu približne okolo 0 – to je dobré.
Naznačuje to, že model nemá výrazné skreslenie v
predikciách.
Červená hladká čiara je mierne zakrivená (vpravo sa ohýba nadol a
uprostred nahor), to naznačuje možnú miernu nelinearitu – modelu môže
chýbať nelineárny tvar nejakej premennej.
Rozptyl rezíduí - Vertikálny rozptyl (variancia rezíduí) sa javí
ako približne konštantný v rámci prispôsobených hodnôt čo je dobrý dôkaz
homoscedasticity.
Ak by sa rezíduá rozprestierali (tvorili kónus), naznačovalo by
to heteroskedasticitu.
Odľahlé hodnoty - Niekoľko bodov (napr. v blízkosti −20) leží
ďaleko od ostatných – ide o potenciálne odľahlé hodnoty alebo vplyvné
pozorovania.
Môžeme ich preskúmať pomocou outlierTest(model) (z balíka car).
Q-Q plot
Čo ukazuje
- Os X: Teoretické kvantily – čo by sme očakávali, ak by rezíduá boli
dokonale normálne rozložené.
- Os Y: Štandardizované rezíduá – skutočné kvantily z vašej
vzorky.
- 45° prerušovaná čiara: Ideálny prípad – ak sú rezíduá normálne
rozložené, body by mali ležať tesne pozdĺž tejto čiary.
Interpretácia vášho konkrétneho grafu
Celkový tvar
Väčšina bodov leží blízko priamky — to naznačuje, že rezíduá sú
približne normálne.
To je dobré: predpoklad normality sa zdá byť vo veľkej miere
splnený.
Krajné hodnoty (extrémy)
Body na oboch koncoch (vľavo dole a vpravo hore) sa mierne odchyľujú
od priamky.
To naznačuje miernu nenormálnosť v koncoch – možno niekoľko odľahlých
hodnôt alebo ťažšie konce, ako je normálne (trochu špicatosť).
Stredná oblasť
Stredná časť grafu (−1 až +1 kvantily) sa veľmi dobre zhoduje – čo
znamená, že väčšina rezíduí pekne zapadá do normálneho rozdelenia.
Zároveň vykonávame následné testy, v ktorých zamietame hypotézu o
normálnom rozložení modelových chýb, ako aj prítomnosť extrémnych
hodnôt.
Scale location plot
Čo to znázorňuje
Os X: Vyrovnan0 hodnoty Os Y: Druhá odmocnina absolútnych
štandardizovaných rezíduí Červená čiara: LOESS (vyhladený) trend cez
body
Interpretácia nášho konkrétneho grafu
Horizontálne rozptýlenie
- Body sú rovnomerne rozptýlené po osi x bez vytvorenia lievika alebo
krivky. To naznačuje približne konštantnú varianciu – rezíduá sú
homoscedastické.
- Červená hladká čiara je takmer rovná – ďalší znak, že pri zvyšovaní
vyrovnaných hodnôt nedochádza k žiadnej systematickej zmene
variancie.
- Odľahlé hodnoty - niekoľko bodov je mierne nad 1,5, ale žiadny z
nich nie je extrémny – takže nedochádza k žiadnym závažným anomáliám
variancie.
residuals vs leverage
Čo znázorňuje graf
Os X: Pákový efekt — meria, ako ďaleko je prediktorový vektor bodu od
stredu všetkých 𝑥 x.
Os Y: Štandardizované rezíduá — ako ďaleko je pozorovaná hodnota od
vyrovnanej hodnoty v jednotkách štandardnej odchýlky.
Bodkované krivky: Kontúry Cookovej vzdialenosti, ktoré udávajú, do
akej miery pozorovanie ovplyvňuje regresnú priamku.
Červená čiara: Hladká LOESS čiara prechádzajúca rezíduami.lm
Interpretácia vášho konkrétneho grafu
Rozloženie vplyvu
Väčšina pozorovaní má nízky vplyv (pod 0,05) — typické pre veľké
vzorky alebo dobre vyvážené údaje.
Jeden alebo dva body (napr. okolo 0,2) vynikajú – ide o pozorovania s
vysokou pákou, čo znamená, že ich hodnoty sú ďaleko od väčšiny
údajov.
Veľkosť rezíduí
Štandardizované rezíduá väčšinou medzi −2 a +2 – to je dobré (žiadne
závažné výnimky v 𝑦 y).
Pozorovanie označené číslom 113 má zdanlivo stredný vplyv a relatívne
veľkú rezíduálnu hodnotu – potenciálne vplyvný prípad.
Kontúry Cookovej vzdialenosti
Žiaden z bodov jasne neprekračuje vonkajšie línie Cookovej
vzdialenosti (≈0,5 alebo 1,0).
Preto sa nezdá, že by niektoré pozorovanie neprimerane ovplyvňovalo
regresné koeficienty.
{r}lm # normality tests residuals <- residuals(model) jb_test <- jarque.bera.test(residuals) jb_test # outlier test (see p-value for Bonferroni correction) outlier_test <- outlierTest(model) outlier_test
Keďže sa nepreukázala normalita rezíduí, pokúsme sa eliminovať
odľahlé hodnoty v prípade GDP - dokážeme to logaritmickou transformáciou
tejto premennej a vylúčením BMI, ktoré sa ukázalo ako
neinterpretovateľné. Nová regresia bude mať tvar
Záver o analýze odľahlých hodnôt
Premenné GDP, a Schooling predlžujú štatisicky
významne strednú dĺžku života. Na druhej strane BMI nám dávalo
neinterpretovateľné výsledky. Rezíduá nevykazujú normálne rozdelenie,
keďže však máme veľké množstvo pozorovaní, aj naďalej budeme pracovať s
týmito údajmi. V modeli sa nepreukazujú žiadne významné nelinearity.
Heteroskedasticita
Prítomnosť heteroskedasticity (nekonštantného rozptylu náhodnej
zložky) spôsobuje zlé vyhodnocovanie t-testov významnosti jednotlivých
regresných koeficientov. Preto je nutné, aby sme heteroskedasticitu -
detekovali (vizuálne a s pomocou testov) - a v prípade prítomnosti
heteroskedasticity aby sme ju odstránili.
Aj v našom prípade by sme sa mohli pokúsiť o vizuálne vyhodnotenie
nasledovných grafov (aj keď jeden graf sme už skúmali - bol to tzv.
Scale-Location grafy uvedené vyššie).
Tentokrát sa pokúsime o vizuálne znázornenie závislosti štvorcov
rezíduí a vysvetľujúcej premennej, u ktorej máme podozrenie, že môže
heteroskedasticitu spôsobovať. Budeme posudzovať dva modely - a to model
nazvaný model alebo model nazvaný model2.
model2 má zlogaritmizovanú premennú GDP, čo sme robili
z dôvodu odstránenia vplyvu odľahlých premenných v predchádzajúcich
krokoch, model je pôvodným modelom.
a teraz model so zlogaritmizovanou premennou GDP.
Na tomto obrázku podľa vyhladených hodnôť štvorcov rezíduí (červená
krivka) môžeme konštatovať, že neobsahuje žiaden významný vývoj s
vysvetľujúcou premennou (či už \(log(GDP)\), alebo \(Schooling\)). Kvôli demonštrácii ale
ukážme, že bez predchádzajúcej logaritmickej transformácie by to dopadlo
inak, t.j. vychádzajme z pôvodného modelu označeného ako model
nasledovne:
Testovanie prítomnosti heteroskedasticity
Na základe výsledkov regresie môžeme povedať, že heteroskedasticita
rezíduí nie je v model2 prítomná, ale v prípade model
prétomná je. Ak by ale prítomná bola, a logaritmizácia premenných, alebo
odstránenie odľahlých premenných by nám nepomohli, môžeme to riešiť s
pomocou takzvanej White heteroskedasticity Consistent matrix, kde v t
testoch významnosti regresných koeficientov sa používajú “hrubšie”
odhady rozptylov regresných koeficientov. Urobíme to nasledovne
Všimnime si, že tentokrát je už každá premenná štatisticky významná.
Na druhej strane treba podotknúť, že použitie tejto metódy vyžaduje
veľký počet pozorovaní (> 100)
Menej používanou je možnosť, kedy predelíme všetky premenné v dátovom
sete premennou, ktorá heteroskedasticitu spôsobuje, čo ale často vedie k
zhoršeniu interpretačnej schopnosti modelu. V prípade napr. GDP,
množstva opyvateľov a rozlohy krajiny to ale napríklad možné je. Ak
napríklad (podľa grafov) zistíme, že premenná množstvo
obuvateľov spôsobuje heteroskedasticitu, vypočítame GDP na
obyvateľa, resp. počet km štvorcových na jedného obyvateľa a môžeme
dostať nový model s odstránenou heteroskedasticitou.
LS0tCnRpdGxlOiAiRWNvbm9tZXRyaWNzIGluIFIgLSBjdmnEjWVuaWUgNSIKb3V0cHV0OiBodG1sX25vdGVib29rCmF1dGhvcjogVi4gR2F6ZGEKLS0tCgpTIHZ5dcW+aXTDrW0gZGF0YWLDoXp5IFtXSE8gTGlmZSBFeHBhY3RhbmN5IERhdGFdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMva3VtYXJhamFyc2hpL2xpZmUtZXhwZWN0YW5jeS13aG8pIGRhdGFiYXNlLgoKUHJpIMSPYWzFoWVqIHByw6FjaSBidWRlbWUgcG91xb7DrXZhxaUga25pxb5uaWNlCgpgYGB7cn0KbGlicmFyeSh6b28pCmxpYnJhcnkodHNlcmllcykKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoc2FuZHdpY2gpCmxpYnJhcnkoY2FyKQpybShsaXN0PWxzKCkpCmBgYAoKClYgKmhsYXZub20gbWVudSogc29tICpTZXNzaW9uKiBuYXN0YXZpbCBuYSAqU291cmNlIEZpbGUgTG9jYXRpb24qLiBNw7TFvmVtZSB0byB1cm9iacWlIGFqIGludGVyYWt0w612bnltIHNww7Rzb2JvbSAtIG5hcMOtc2HFpSBkb2xlIGRvIENvbnNvbGUgKGFsZWJvIHRvIHphaHJuw7rFpSBwcmlhbW8gZG8gc2tyaXB0dSkgYWtvIAoKICoqc2V0d2QoIi9DbG91ZC9wcm9qZWN0L3R5emRuZS90eXpkZW41IikqKgoKT3JnYW5pesOhY2lhIHByaWXEjWlua292IGEgcG9kcHJpZcSNaW5rb3Ygc2EgdsWhYWsgbcO0xb5lIGzDrcWhacWlIHYgesOhdmlzbG9zdGkgb2QgcHJvamVrdHUsIHByZXRvIHNvbSBpY2ggbmV6YXJhZGlsIGRvIENodW5rLXUuCgrDmmRhamUgbyBvxI1ha8OhdmFuZWogZMS6xb5rZSDFvml2b3RhIHPDuiB1c3BvcmlhZGFuw6kgdiBzw7pib3JlICpjc3YqLCBzdMS6cGNlIHPDuiBvZGRlbGVuw6kgem5ha29tICIsIiBhIHBvdcW+w612YWrDuiBkZXNhdGlubsO6IMSNaWFya3UuIFYgcHJhY292bm9tIHByaWXEjWlua3Ugc29tIHZ5dHZvcmlsIHBvZHByaWXEjWlub2sgcyBuw6F6dm9tICp1ZGFqZSosIGFieSBzb20gb2RkZWxpbCDDumRhamUgb2QgenZ5xaFrdSBwcm9qZWt0dS4gTcO0aiBwcmllxI1pbm9rIHNhIHRpZcW+IG5hesO9dmEgKnVkYWplKi4gCgpOaWUgdsWhZXRreSDDumRhamUgYnVkw7ogcG91xb5pdMOpLCBwcmV0byBzb20gdnlicmFsIGxlbiBuaWVrdG9yw6kgc3TEunBjZSBwcmUgbmVza29yxaFpZSBwb3XFvml0aWUuCgojIMOadm9kIGRvIHByb2Jsw6ltdSwgc3Rhbm92ZW5pZSBoeXBvdMOpeiAKClJvemhvZG9sIHNvbSBzYSBtb2RlbG92YcWlIHN0cmVkbsO6IGTEusW+a3Ugxb5pdm90YSAqTGlmZS5leHBlY3RhbmN5KiB2IHrDoXZpc2xvc3RpIG9kIHRyb2NoIHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2ggYSB0byAqQk1JKiwgSERQIG5hIG9ieXZhdGXEvmEgKkdEUCogYSBzdHJlZG7DvSBwb8SNZXQgcm9rb3YgxaF0w7pkaWEgICpTY2hvb2xpbmcqLgoKTmHFoWEgcHJhY292bsOhIGh5cG90w6l6YSBob3ZvcsOtIG8gxaF0YXRpc3RpY2t5IHbDvXpuYW1ub20gdnBseXZlIHbFoWV0a8O9Y2ggdHJvY2ggdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCwgcHJpxI1vbSB1IHByZW1lbm7DvWNoICpHRFAqIGEgKlNjaG9vbGluZyogYnkgbWFsbyDDrXPFpSBvIHBveml0w612bnkgdnBseXYgKG/EjWFrw6F2YW1lIGtsYWRuw6kgem5hbWllbmtvIG9kaGFkb3ZhbsOpaG8gcmVncmVzbsOpaG8ga29lZmljaWVudGEpIGEgdiBwcsOtcGFkZSBCTUkgYnkgbWFsbyDDrXPFpSBvZiBuZWdhdMOtdm55IHZwbHl2IChzbyB6w6Fwb3Juw71tIHpuYW1pZW5rb20pCgoKCgojIFByw61wcmF2YSBkYXRhYsOhenksIMSNaXN0ZW5pZSBhIMO6cHJhdmEgw7pkYWpvdgoKS2XEj8W+ZSBuaWVrdG9yw6kgw7pkYWplIGNow71iYWrDuiwgZG9wbG5pbCBzb20gaWNoIG1lZGnDoW5vdsO9bWkgaG9kbm90YW1pIHByZW1lbm5laiwga3RvcsO6IHp2YcW+dWplbS4gbG0KCgpgYGB7cn0KdWRhamUgPC0gcmVhZC5jc3YoInVkYWplL0xpZmVfRXhwZWN0YW5jeV9EYXRhLmNzdiIsZGVjPSIuIixzZXA9IiwiLGhlYWRlciA9IFRSVUUpCiMgc2VsZWN0IGp1c3QgdGhlIHJlY29yZCBmcm9tIDIwMTUKdWRhamUuMjAxNSA8LSB1ZGFqZVt1ZGFqZSRZZWFyPT0yMDE1LGMoIkxpZmUuZXhwZWN0YW5jeSIsIkJNSSIsIkdEUCIsIlNjaG9vbGluZyIpXQoKIyBkYXRhIGltcHV0YXRpb24KCiMgQ29tcHV0ZSBjb2x1bW4gbWVkaWFucwojY29sdW1uX21lZGlhbnMgPC0gc2FwcGx5KHVkYWplLjIwMTUsIG1lZGlhbiwgbmEucm0gPSBUUlVFKQoKIyBJbXB1dGUgbWlzc2luZyB2YWx1ZXMgd2l0aCBjb2x1bW4gbWVkaWFucwojIENvbXB1dGUgY29sdW1uIG1lZGlhbnMKY29sdW1uX21lZGlhbnMgPC0gc2FwcGx5KHVkYWplLjIwMTUsIG1lZGlhbiwgbmEucm0gPSBUUlVFKQoKIyBJbXB1dGUgbWlzc2luZyB2YWx1ZXMgd2l0aCBjb2x1bW4gbWVkaWFucwp1ZGFqZV9pbXB1dGVkIDwtIHVkYWplLjIwMTUKZm9yIChjb2wgaW4gbmFtZXModWRhamUuMjAxNSkpIHsKICB1ZGFqZV9pbXB1dGVkW1tjb2xdXVtpcy5uYSh1ZGFqZV9pbXB1dGVkW1tjb2xdXSldIDwtIGNvbHVtbl9tZWRpYW5zW2NvbF0KfQoKdWRhamUuMjAxNSA8LSB1ZGFqZV9pbXB1dGVkCgpgYGAKCgoKVGVyYXogY2hjZW1lIHZpZGllxaUgdHZhciDDumRham92ICjEjWkgbmllIHPDuiB2IG5pY2ggbmVqYWvDqSBuZXpyb3ZuYWxvc3RpIOKAkyBuYXByw61rbGFkIGhvZG5vdHkgMCkuCgpgYGB7cn0KIyBTdXBwb3NlIHVkYWplLjIwMTUgaXMgeW91ciBkYXRhIGZyYW1lCgojIERldGVybWluZSBudW1iZXIgb2YgcGxvdHMKbnVtX3Bsb3RzIDwtIGxlbmd0aChuYW1lcyh1ZGFqZS4yMDE1KSkKCiMgU2V0IHRoZSBsYXlvdXQ6IDIgcm93cyDDlyAyIGNvbHVtbnMKcGFyKG1mcm93ID0gYygyLCAyKSkKcGFyKG1hciA9IGMoNCwgNCwgMiwgMSkpICAjIEFkanVzdCBtYXJnaW5zCgojIExvb3AgdGhyb3VnaCBjb2x1bW5zIGFuZCBwbG90IGVhY2ggYm94cGxvdCB3aXRoIHZhcmlhYmxlIG5hbWUgYXMgdGl0bGUKZm9yIChjb2wgaW4gbmFtZXModWRhamUuMjAxNSkpIHsKICBib3hwbG90KHVkYWplLjIwMTVbW2NvbF1dLCAKICAgICAgICAgIG1haW4gPSBjb2wsICAgICAgICAgICAjIHZhcmlhYmxlIG5hbWUgYXMgdGl0bGUKICAgICAgICAgIHhsYWIgPSAiVmFsdWUiLCAKICAgICAgICAgIGNvbCA9ICJsaWdodGJsdWUiKQp9CgojIEFkZCBhIGdsb2JhbCB0aXRsZQptdGV4dCgiQm94cGxvdHkgamVkbm90bGl2w71jaCBwcmVtZW5uw71jaCIsIG91dGVyID0gVFJVRSwgY2V4ID0gMS40LCBmb250ID0gMikKCmBgYAoKCgoKIyMgTGluZcOhcm5hIHJlZ3Jlc2lhCgpNb2RlbCBvZGhhZHVqZW1lIHByw61rYXpvbSAqbG0oKSoKCmBgYHtyfQptb2RlbCA8LSBsbShMaWZlLmV4cGVjdGFuY3kgfiArMSArIEJNSSArIEdEUCArIFNjaG9vbGluZyxkYXRhPXVkYWplLjIwMTUpCmBgYAoKT2JqZWt0IHRyaWVkeSAqbG0oKSogbsOhbSBwb3NreXR1amUgbmlla2/EvmtvIHbDvXNsZWRrb3Y6CgoxLiBWZWN0b3Igb2RoYWRudXTDvWNoIGtvZWZpY2llbnRvdiAqbW9kZWwkY29lZmZpY2llbnRzKgoyLiBWZWt0b3IgcmV6w61kdcOtICptb2RlbCQgcmVzaWR1YWxzKgozLiBWZWt0b3Igdnlyb3ZuYW7DvWNoIGhvZG7DtHQgdnlzdmV0xL5vdmFuZWogdmVsacSNaW55ICptb2RlbCRmaXR0ZWQudmFsdWVzKgo0LiBNYXRpY3UgWCAqbW9kZWwkeCoKCmBgYHtyfQojcHJpbnQoIk9kaGFkbnV0w6kga29lZmljaWVudHkgc8O6OiAiKQojICAgICAgcHJpbnQobW9kZWwkY29lZmZpY2llbnRzKQojcHJpbnQoIk9kaGFkbnV0w6kgcmV6w61kdcOhOiAiKQojcHJpbnQobW9kZWwkcmVzaWR1YWxzKQojcHJpbnQoIlZ5cm92bmFuw6kgaG9kbm90eSB2eXN2ZXTEvm92YW5laiBwcmVtZW5uZWogc8O6OiAiKQojcHJpbnQobW9kZWwkZml0dGVkLnZhbHVlcykKI3ByaW50KCJtYXRpY2EgbW9kZWwkeGxldmVsczogIikKI3ByaW50KG1vZGVsLm1hdHJpeChtb2RlbCkpCiNYIDwtIG1vZGVsLm1hdHJpeChtb2RlbCkKI2RpYWcoWCAlKiUgc29sdmUodChYKSAlKiUgWCkgJSolIHQoWCkpCgpzdW1tYXJ5KG1vZGVsKQoKYGBgCgoKClPDumhybiBvZGhhZG92YW7DqWhvIG1vZGVsdSBuw6FtIHBvc2t5dHVqZSBzw7pib3Igb2RoYWRvdmFuw71jaCByZWdyZXNuw71jaCBrb2VmaWNpZW50b3YsIGt0b3LDvWNoIHpuYW1pZW5rYSBidWTDuiByb3pvYmVyYW7DqSBuZXNrw7RyLiBBayBob3ZvcsOtbWUgbyB2bGFzdG5vc3RpYWNoIG1vZGVsdSBha28gY2Vsa3UsIHBvenJpbWUgc2EgbmFqc2vDtHIgbmEgbmFzbGVkdWrDumNlIG9icsOhemt5LiBOYSB6w6FrbGFkZSBRLVEgZ3JhZnUgesOtc2thdmFtZSBkb2plbSBvIG1vxb5uw71jaCBwcm9ibMOpbW9jaCBwb3J1xaFlbmlhIG5vcm1hbGl0eSByZXrDrWR1w60uIAoKYGBge3IgZGlhZ3Bsb3RzLCBmaWcuY2FwPSJEaWFnbm9zdGlja8OpIGdyYWZ5IHJlZ3Jlc27DqWhvIG1vZGVsdSJ9CiMgTmFzdGF2acWlIHJvemxvxb5lbmllIDIgeCAyCnBhcihtZnJvdyA9IGMoMiwgMikpCgojIFZ5a3Jlc2xpxaUgdsWhZXRreSA0IGRpYWdub3N0aWNrw6kgZ3JhZnkgbW9kZWx1CnBsb3QobW9kZWwpCgojIChWb2xpdGXEvm7DqSkgcHJpZGHFpSBzcG9sb8SNbsO9IG5hZHBpcwojbXRleHQoIkRpYWdub3N0aWNrw6kgZ3JhZnkgcmVncmVzbsOpaG8gbW9kZWx1Iiwgb3V0ZXIgPSBUUlVFLCBjZXggPSAxLjIsIGZvbnQgPSAyKQoKIyBSZXNldG92YcWlIGxheW91dApwYXIobWZyb3cgPSBjKDEsIDEpKQpgYGAKCgojIyBSZXNpZHVhbHMgdnMuIGZpdHRlZAoKIyMjIEludGVycHJldMOhY2lhIHbDocWhaG8ga29ua3LDqXRuZWhvIGdyYWZ1CgotIENlbnRyb3ZhbmllIG9rb2xvIG51bHkKLSBSZXppZHXDoWx5IGtvbMOtxaF1IHByaWJsacW+bmUgb2tvbG8gMCDigJMgdG8gamUgZG9icsOpLgotIE5hem5hxI11amUgdG8sIMW+ZSBtb2RlbCBuZW3DoSB2w71yYXpuw6kgc2tyZXNsZW5pZSB2IHByZWRpa2Npw6FjaC4KLSDEjGVydmVuw6EgaGxhZGvDoSDEjWlhcmEgamUgbWllcm5lIHpha3JpdmVuw6EgKHZwcmF2byBzYSBvaMO9YmEgbmFkb2wgYSB1cHJvc3RyZWQgbmFob3IpLCB0byBuYXpuYcSNdWplIG1vxb5uw7ogbWllcm51IG5lbGluZWFyaXR1IOKAkyBtb2RlbHUgbcO0xb5lIGNow71iYcWlIG5lbGluZcOhcm55IHR2YXIgbmVqYWtlaiBwcmVtZW5uZWouCgotIFJvenB0eWwgcmV6w61kdcOtIC0gVmVydGlrw6Fsbnkgcm96cHR5bCAodmFyaWFuY2lhIHJlesOtZHXDrSkgc2EgamF2w60gYWtvIHByaWJsacW+bmUga29uxaF0YW50bsO9IHYgcsOhbWNpIHByaXNww7Rzb2JlbsO9Y2ggaG9kbsO0dCAgxI1vIGplIGRvYnLDvSBkw7RrYXogaG9tb3NjZWRhc3RpY2l0eS4KCi0gQWsgYnkgc2EgcmV6w61kdcOhIHJvenByZXN0aWVyYWxpICh0dm9yaWxpIGvDs251cyksIG5hem5hxI1vdmFsbyBieSB0byBoZXRlcm9za2VkYXN0aWNpdHUuCgotIE9kxL5haGzDqSBob2Rub3R5IC0gTmlla2/EvmtvIGJvZG92IChuYXByLiB2IGJsw616a29zdGkg4oiSMjApIGxlxb7DrSDEj2FsZWtvIG9kIG9zdGF0bsO9Y2gg4oCTIGlkZSBvIHBvdGVuY2nDoWxuZSBvZMS+YWhsw6kgaG9kbm90eSBhbGVibyB2cGx5dm7DqSBwb3pvcm92YW5pYS4KCk3DtMW+ZW1lIGljaCBwcmVza8O6bWHFpSBwb21vY291IG91dGxpZXJUZXN0KG1vZGVsKSAoeiBiYWzDrWthIGNhcikuCgojIyBRLVEgcGxvdAoKIyMjIMSMbyB1a2F6dWplCgoKLSBPcyBYOiBUZW9yZXRpY2vDqSBrdmFudGlseSDigJMgxI1vIGJ5IHNtZSBvxI1ha8OhdmFsaSwgYWsgYnkgcmV6w61kdcOhIGJvbGkgZG9rb25hbGUgbm9ybcOhbG5lIHJvemxvxb5lbsOpLgotIE9zIFk6IMWgdGFuZGFyZGl6b3ZhbsOpIHJlesOtZHXDoSDigJMgc2t1dG/EjW7DqSBrdmFudGlseSB6IHZhxaFlaiB2em9ya3kuCi0gNDXCsCBwcmVydcWhb3ZhbsOhIMSNaWFyYTogSWRlw6FsbnkgcHLDrXBhZCDigJMgYWsgc8O6IHJlesOtZHXDoSBub3Jtw6FsbmUgcm96bG/FvmVuw6ksIGJvZHkgYnkgbWFsaSBsZcW+YcWlIHRlc25lIHBvemTEusW+IHRlanRvIMSNaWFyeS4KCiMjIyBJbnRlcnByZXTDoWNpYSB2w6HFoWhvIGtvbmtyw6l0bmVobyBncmFmdQoKQ2Vsa292w70gdHZhcgoKVsOkxI3FoWluYSBib2RvdiBsZcW+w60gYmzDrXprbyBwcmlhbWt5IOKAlCB0byBuYXpuYcSNdWplLCDFvmUgcmV6w61kdcOhIHPDuiBwcmlibGnFvm5lIG5vcm3DoWxuZS4KClRvIGplIGRvYnLDqTogcHJlZHBva2xhZCBub3JtYWxpdHkgc2EgemTDoSBiecWlIHZvIHZlxL5rZWogbWllcmUgc3BsbmVuw70uCgpLcmFqbsOpIGhvZG5vdHkgKGV4dHLDqW15KQoKQm9keSBuYSBvYm9jaCBrb25jb2NoICh2xL5hdm8gZG9sZSBhIHZwcmF2byBob3JlKSBzYSBtaWVybmUgb2RjaHnEvnVqw7ogb2QgcHJpYW1reS4KClRvIG5hem5hxI11amUgbWllcm51IG5lbm9ybcOhbG5vc8WlIHYga29uY29jaCDigJMgbW/Fvm5vIG5pZWtvxL5rbyBvZMS+YWhsw71jaCBob2Ruw7R0IGFsZWJvIMWlYcW+xaFpZSBrb25jZSwgYWtvIGplIG5vcm3DoWxuZSAodHJvY2h1IMWhcGljYXRvc8WlKS4KClN0cmVkbsOhIG9ibGFzxaUKClN0cmVkbsOhIMSNYXPFpSBncmFmdSAo4oiSMSBhxb4gKzEga3ZhbnRpbHkpIHNhIHZlxL5taSBkb2JyZSB6aG9kdWplIOKAkyDEjW8gem5hbWVuw6EsIMW+ZSB2w6TEjcWhaW5hIHJlesOtZHXDrSBwZWtuZSB6YXBhZMOhIGRvIG5vcm3DoWxuZWhvIHJvemRlbGVuaWEuCgpaw6Fyb3ZlxYggdnlrb27DoXZhbWUgbsOhc2xlZG7DqSB0ZXN0eSwgdiBrdG9yw71jaCB6YW1pZXRhbWUgaHlwb3TDqXp1IG8gbm9ybcOhbG5vbSByb3psb8W+ZW7DrSBtb2RlbG92w71jaCBjaMO9YiwgYWtvIGFqIHByw610b21ub3PFpSBleHRyw6ltbnljaCBob2Ruw7R0LiAKCiMjIFNjYWxlIGxvY2F0aW9uIHBsb3QKCiMjIyDEjG8gdG8gem7DoXpvcsWIdWplCgpPcyBYOiBWeXJvdm5hbjAgaG9kbm90eSAKT3MgWTogRHJ1aMOhIG9kbW9jbmluYSBhYnNvbMO6dG55Y2ggxaF0YW5kYXJkaXpvdmFuw71jaCByZXrDrWR1w60gCsSMZXJ2ZW7DoSDEjWlhcmE6IExPRVNTICh2eWhsYWRlbsO9KSB0cmVuZCBjZXogYm9keQoKIyMjIEludGVycHJldMOhY2lhIG7DocWhaG8ga29ua3LDqXRuZWhvIGdyYWZ1CgpIb3Jpem9udMOhbG5lIHJvenB0w71sZW5pZQoKLSBCb2R5IHPDuiByb3Zub21lcm5lIHJvenB0w71sZW7DqSBwbyBvc2kgeCBiZXogdnl0dm9yZW5pYSBsaWV2aWthIGFsZWJvIGtyaXZreS4gVG8gbmF6bmHEjXVqZSBwcmlibGnFvm5lIGtvbsWhdGFudG7DuiB2YXJpYW5jaXUg4oCTIHJlesOtZHXDoSBzw7ogaG9tb3NjZWRhc3RpY2vDqS4KLSDEjGVydmVuw6EgaGxhZGvDoSDEjWlhcmEgamUgdGFrbWVyIHJvdm7DoSDigJMgxI9hbMWhw60gem5haywgxb5lIHByaSB6dnnFoW92YW7DrSB2eXJvdm5hbsO9Y2ggaG9kbsO0dCBuZWRvY2jDoWR6YSBrIMW+aWFkbmVqIHN5c3RlbWF0aWNrZWogem1lbmUgdmFyaWFuY2llLgotIE9kxL5haGzDqSBob2Rub3R5IC0gbmlla2/EvmtvIGJvZG92IGplIG1pZXJuZSBuYWQgMSw1LCBhbGUgxb5pYWRueSB6IG5pY2ggbmllIGplIGV4dHLDqW1ueSDigJMgdGFrxb5lIG5lZG9jaMOhZHphIGsgxb5pYWRueW0gesOhdmHFvm7DvW0gYW5vbcOhbGnDoW0gdmFyaWFuY2llLgoKIyMgcmVzaWR1YWxzIHZzIGxldmVyYWdlCgojIyMgxIxvIHpuw6F6b3LFiHVqZSBncmFmCgpPcyBYOiBQw6Frb3bDvSBlZmVrdCAg4oCUIG1lcmlhLCBha28gxI9hbGVrbyBqZSBwcmVkaWt0b3JvdsO9IHZla3RvciBib2R1ICBvZCBzdHJlZHUgdsWhZXRrw71jaCAK8J2RpQp4LgoKT3MgWTogxaB0YW5kYXJkaXpvdmFuw6kgcmV6w61kdcOhIOKAlCBha28gxI9hbGVrbyBqZSBwb3pvcm92YW7DoSBob2Rub3RhIAogb2Qgdnlyb3ZuYW5laiBob2Rub3R5IHYgamVkbm90a8OhY2ggxaF0YW5kYXJkbmVqIG9kY2jDvWxreS4KCkJvZGtvdmFuw6kga3Jpdmt5OiBLb250w7pyeSBDb29rb3ZlaiB2emRpYWxlbm9zdGksIGt0b3LDqSB1ZMOhdmFqw7osIGRvIGFrZWogbWllcnkgcG96b3JvdmFuaWUgb3ZwbHl2xYh1amUgcmVncmVzbsO6IHByaWFta3UuCgrEjGVydmVuw6EgxI1pYXJhOiBIbGFka8OhIExPRVNTIMSNaWFyYSBwcmVjaMOhZHphasO6Y2EgcmV6w61kdWFtaS5sbQoKIyMjIEludGVycHJldMOhY2lhIHbDocWhaG8ga29ua3LDqXRuZWhvIGdyYWZ1CgpSb3psb8W+ZW5pZSB2cGx5dnUKClbDpMSNxaFpbmEgcG96b3JvdmFuw60gbcOhIG7DrXpreSB2cGx5diAocG9kIDAsMDUpIOKAlCB0eXBpY2vDqSBwcmUgdmXEvmvDqSB2em9ya3kgYWxlYm8gZG9icmUgdnl2w6HFvmVuw6kgw7pkYWplLgoKSmVkZW4gYWxlYm8gZHZhIGJvZHkgKG5hcHIuIG9rb2xvIDAsMikgdnluaWthasO6IOKAkyBpZGUgbyBwb3pvcm92YW5pYSBzIHZ5c29rb3UgcMOha291LCDEjW8gem5hbWVuw6EsIMW+ZSBpY2ggaG9kbm90eSBzw7ogxI9hbGVrbyBvZCB2w6TEjcWhaW55IMO6ZGFqb3YuCgpWZcS+a29zxaUgcmV6w61kdcOtCgrFoHRhbmRhcmRpem92YW7DqSByZXrDrWR1w6EgdsOkxI3FoWlub3UgbWVkemkg4oiSMiBhICsyIOKAkyB0byBqZSBkb2Jyw6kgKMW+aWFkbmUgesOhdmHFvm7DqSB2w71uaW1reSB2IArwnZGmCnkpLgoKUG96b3JvdmFuaWUgb3puYcSNZW7DqSDEjcOtc2xvbSAxMTMgbcOhIHpkYW5saXZvIHN0cmVkbsO9IHZwbHl2IGEgcmVsYXTDrXZuZSB2ZcS+a8O6IHJlesOtZHXDoWxudSBob2Rub3R1IOKAkyBwb3RlbmNpw6FsbmUgdnBseXZuw70gcHLDrXBhZC4KCktvbnTDunJ5IENvb2tvdmVqIHZ6ZGlhbGVub3N0aQoKxb1pYWRlbiB6IGJvZG92IGphc25lIG5lcHJla3JhxI11amUgdm9ua2FqxaFpZSBsw61uaWUgQ29va292ZWogdnpkaWFsZW5vc3RpICjiiYgwLDUgYWxlYm8gMSwwKS4KClByZXRvIHNhIG5lemTDoSwgxb5lIGJ5IG5pZWt0b3LDqSBwb3pvcm92YW5pZSBuZXByaW1lcmFuZSBvdnBseXbFiG92YWxvIHJlZ3Jlc27DqSBrb2VmaWNpZW50eS4KCmBgYHtyfWxtCiMgbm9ybWFsaXR5IHRlc3RzCnJlc2lkdWFscyA8LSByZXNpZHVhbHMobW9kZWwpCmpiX3Rlc3QgPC0gamFycXVlLmJlcmEudGVzdChyZXNpZHVhbHMpCmpiX3Rlc3QKIyBvdXRsaWVyIHRlc3QgKHNlZSBwLXZhbHVlIGZvciBCb25mZXJyb25pIGNvcnJlY3Rpb24pCm91dGxpZXJfdGVzdCA8LSBvdXRsaWVyVGVzdChtb2RlbCkKb3V0bGllcl90ZXN0CmBgYAoKS2XEj8W+ZSBzYSBuZXByZXVrw6F6YWxhIG5vcm1hbGl0YSByZXrDrWR1w60sIHBva8O6c21lIHNhIGVsaW1pbm92YcWlIG9kxL5haGzDqSBob2Rub3R5IHYgcHLDrXBhZGUgR0RQIC0gZG9rw6HFvmVtZSB0byBsb2dhcml0bWlja291IHRyYW5zZm9ybcOhY2lvdSB0ZWp0byBwcmVtZW5uZWogYSB2eWzDusSNZW7DrW0gQk1JLCBrdG9yw6kgc2EgdWvDoXphbG8gYWtvIG5laW50ZXJwcmV0b3ZhdGXEvm7DqS4gTm92w6EgcmVncmVzaWEgYnVkZSBtYcWlIHR2YXIKCgpgYGB7cn0KbW9kZWwyIDwtIGxtKExpZmUuZXhwZWN0YW5jeSB+ICsxICsgSShsb2coR0RQKSkgKyBTY2hvb2xpbmcsZGF0YT11ZGFqZS4yMDE1KQpzdW1tYXJ5KG1vZGVsMikKYGBgCmBgYHtyIGRpYWdwbG90czIsIGZpZy5jYXA9IkRpYWdub3N0aWNrw6kgZ3JhZnkgcmVncmVzbsOpaG8gbW9kZWx1In0KIyBOYXN0YXZpxaUgcm96bG/FvmVuaWUgMiB4IDIKcGFyKG1mcm93ID0gYygyLCAyKSkKCiMgVnlrcmVzbGnFpSB2xaFldGt5IDQgZGlhZ25vc3RpY2vDqSBncmFmeSBtb2RlbHUKcGxvdChtb2RlbDIpCgojIChWb2xpdGXEvm7DqSkgcHJpZGHFpSBzcG9sb8SNbsO9IG5hZHBpcwojbXRleHQoIkRpYWdub3N0aWNrw6kgZ3JhZnkgcmVncmVzbsOpaG8gbW9kZWx1Iiwgb3V0ZXIgPSBUUlVFLCBjZXggPSAxLjIsIGZvbnQgPSAyKQoKIyBSZXNldG92YcWlIGxheW91dApwYXIobWZyb3cgPSBjKDEsIDEpKQpgYGAKCgoKCmBgYHtyfQojIG5vcm1hbGl0eSB0ZXN0cwpyZXNpZHVhbHMgPC0gcmVzaWR1YWxzKG1vZGVsKQpqYl90ZXN0IDwtIGphcnF1ZS5iZXJhLnRlc3QocmVzaWR1YWxzKQpqYl90ZXN0CiMgb3V0bGllciB0ZXN0IChzZWUgcC12YWx1ZSBmb3IgQm9uZmVycm9uaSBjb3JyZWN0aW9uKQpvdXRsaWVyX3Rlc3QgPC0gb3V0bGllclRlc3QobW9kZWwpCm91dGxpZXJfdGVzdApgYGAKCiMjIFrDoXZlciBvIGFuYWzDvXplIG9kxL5haGzDvWNoIGhvZG7DtHQKClByZW1lbm7DqSAqR0RQKiwgYSAqU2Nob29saW5nKiBwcmVkbMW+dWrDuiDFoXRhdGlzaWNreSB2w716bmFtbmUgc3RyZWRuw7ogZMS6xb5rdSDFvml2b3RhLiBOYSBkcnVoZWogc3RyYW5lICpCTUkqIG7DoW0gZMOhdmFsbyBuZWludGVycHJldG92YXRlxL5uw6kgdsO9c2xlZGt5LiBSZXrDrWR1w6EgbmV2eWthenVqw7ogbm9ybcOhbG5lIHJvemRlbGVuaWUsIGtlxI/FvmUgdsWhYWsgbcOhbWUgdmXEvmvDqSBtbm/FvnN0dm8gcG96b3JvdmFuw60sIGFqIG5hxI9hbGVqIGJ1ZGVtZSBwcmFjb3ZhxaUgcyB0w71taXRvIMO6ZGFqbWkuIFYgbW9kZWxpIHNhIG5lcHJldWthenVqw7ogxb5pYWRuZSB2w716bmFtbsOpIG5lbGluZWFyaXR5LgoKIyMgSGV0ZXJvc2tlZGFzdGljaXRhCgpQcsOtdG9tbm9zxaUgaGV0ZXJvc2tlZGFzdGljaXR5IChuZWtvbsWhdGFudG7DqWhvIHJvenB0eWx1IG7DoWhvZG5laiB6bG/Fvmt5KSBzcMO0c29idWplIHpsw6kgdnlob2Rub2NvdmFuaWUgdC10ZXN0b3YgdsO9em5hbW5vc3RpIGplZG5vdGxpdsO9Y2ggcmVncmVzbsO9Y2gga29lZmljaWVudG92LiBQcmV0byBqZSBudXRuw6ksIGFieSBzbWUgaGV0ZXJvc2tlZGFzdGljaXR1IAotIGRldGVrb3ZhbGkgKHZpenXDoWxuZSBhIHMgcG9tb2NvdSB0ZXN0b3YpCi0gYSB2IHByw61wYWRlIHByw610b21ub3N0aSBoZXRlcm9za2VkYXN0aWNpdHkgYWJ5IHNtZSBqdSBvZHN0csOhbmlsaS4KCkFqIHYgbmHFoW9tIHByw61wYWRlIGJ5IHNtZSBzYSBtb2hsaSBwb2vDunNpxaUgbyB2aXp1w6FsbmUgdnlob2Rub3RlbmllIG5hc2xlZG92bsO9Y2ggZ3JhZm92IChhaiBrZcSPIGplZGVuIGdyYWYgc21lIHXFviBza8O6bWFsaSAtIGJvbCB0byB0enYuIFNjYWxlLUxvY2F0aW9uIGdyYWZ5IHV2ZWRlbsOpIHZ5xaHFoWllKS4KClRlbnRva3LDoXQgc2EgcG9rw7pzaW1lIG8gdml6dcOhbG5lIHpuw6F6b3JuZW5pZSB6w6F2aXNsb3N0aSDFoXR2b3Jjb3YgcmV6w61kdcOtIGEgdnlzdmV0xL51asO6Y2VqIHByZW1lbm5laiwgdSBrdG9yZWogbcOhbWUgcG9kb3pyZW5pZSwgxb5lIG3DtMW+ZSBoZXRlcm9za2VkYXN0aWNpdHUgc3DDtHNvYm92YcWlLiBCdWRlbWUgcG9zdWR6b3ZhxaUgZHZhIG1vZGVseSAtIGEgdG8gbW9kZWwgbmF6dmFuw70gKm1vZGVsKiBhbGVibyBtb2RlbCBuYXp2YW7DvSAqbW9kZWwyKi4gKm1vZGVsMiogbcOhIHpsb2dhcml0bWl6b3ZhbsO6IHByZW1lbm7DuiAqR0RQKiwgxI1vIHNtZSByb2JpbGkgeiBkw7R2b2R1IG9kc3Ryw6FuZW5pYSB2cGx5dnUgb2TEvmFobMO9Y2ggcHJlbWVubsO9Y2ggdiBwcmVkY2jDoWR6YWrDumNpY2gga3Jva29jaCwgKm1vZGVsKiBqZSBww7R2b2Ruw71tIG1vZGVsb20uCgoKYGBge3IgaGV0ZXJvcGxvdHMxLCBmaWcuY2FwPSJTa8O6bWFuaWUgaGV0ZXJvc2tlZGFzdGljaXR5IiwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTR9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwYXRjaHdvcmspICAjIGluc3RhbGwucGFja2FnZXMoInBhdGNod29yayIpCgpwMSA8LSBnZ3Bsb3QodWRhamUuMjAxNSwgYWVzKHggPSBHRFAsIHkgPSByZXNpZChtb2RlbCleMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoeCA9ICJHRFAiLCAKICAgICAgIHkgPSAiU3F1YXJlZCBSZXNpZHVhbHMiLAogICAgICAgdGl0bGUgPSAiU3FpYXJlZCBSZXNpZHVhbHMgdnMgR0RQIikgKwogIHRoZW1lX21pbmltYWwoKQoKcDIgPC0gZ2dwbG90KHVkYWplLjIwMTUsIGFlcyh4ID0gU2Nob29saW5nLCB5ID0gcmVzaWQobW9kZWwpXjIpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKHggPSAiU2Nob29saW5nIiwgCiAgICAgICB5ID0gIlNxdWFyZWQgUmVzaWR1YWxzIiwKICAgICAgIHRpdGxlID0gIlNxdWFyZWQgUmVzaWR1YWxzIHZzIFNjaG9vbGluZyIpICsKICB0aGVtZV9taW5pbWFsKCkKCiMgQ29tYmluZSBzaWRlIGJ5IHNpZGUKcDEgKyBwMgpgYGAKCmEgdGVyYXogbW9kZWwgc28gemxvZ2FyaXRtaXpvdmFub3UgcHJlbWVubm91ICpHRFAqLgoKYGBge3IgaGV0ZXJvcGxvdHMyLCBmaWcuY2FwPSJTa8O6bWFuaWUgaGV0ZXJvc2tlZGFzdGljaXR5IiwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTR9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwYXRjaHdvcmspICAjIGluc3RhbGwucGFja2FnZXMoInBhdGNod29yayIpCgpwMSA8LSBnZ3Bsb3QodWRhamUuMjAxNSwgYWVzKHggPSBsb2coR0RQKSwgeSA9IHJlc2lkKG1vZGVsMileMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoeCA9ICJsb2coR0RQKSIsIAogICAgICAgeSA9ICJTcXVhcmVkIFJlc2lkdWFscyIsCiAgICAgICB0aXRsZSA9ICJSZXNpZHVhbHMgdnMgbG9nKEdEUCkiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwMiA8LSBnZ3Bsb3QodWRhamUuMjAxNSwgYWVzKHggPSBTY2hvb2xpbmcsIHkgPSByZXNpZChtb2RlbDIpXjIpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKHggPSAiU2Nob29saW5nIiwgCiAgICAgICB5ID0gIlNxdWFyZWQgUmVzaWR1YWxzIiwKICAgICAgIHRpdGxlID0gIlJlc2lkdWFscyB2cyBTY2hvb2xpbmciKSArCiAgdGhlbWVfbWluaW1hbCgpCgojIENvbWJpbmUgc2lkZSBieSBzaWRlCnAxICsgcDIKYGBgCgoKTmEgdG9tdG8gb2Jyw6F6a3UgcG9kxL5hIHZ5aGxhZGVuw71jaCBob2Ruw7TFpSDFoXR2b3Jjb3YgcmV6w61kdcOtICjEjWVydmVuw6Ega3JpdmthKSBtw7TFvmVtZSBrb27FoXRhdG92YcWlLCDFvmUgbmVvYnNhaHVqZSDFvmlhZGVuIHbDvXpuYW1uw70gdsO9dm9qIHMgdnlzdmV0xL51asO6Y291IHByZW1lbm5vdSAoxI1pIHXFviAkbG9nKEdEUCkkLCBhbGVibyAkU2Nob29saW5nJCkuIEt2w7RsaSBkZW1vbsWhdHLDoWNpaSBhbGUgdWvDocW+bWUsIMW+ZSBiZXogcHJlZGNow6FkemFqw7pjZWogbG9nYXJpdG1pY2tlaiB0cmFuc2Zvcm3DoWNpZSBieSB0byBkb3BhZGxvIGluYWssIHQuai4gdnljaMOhZHpham1lIHogcMO0dm9kbsOpaG8gbW9kZWx1IG96bmHEjWVuw6lobyBha28gKm1vZGVsKiAgbmFzbGVkb3ZuZToKCgojIyBUZXN0b3ZhbmllIHByw610b21ub3N0aSBoZXRlcm9za2VkYXN0aWNpdHkKCmBgYHtyfQojIEluc3RhbGwgKGlmIG5vdCB5ZXQgaW5zdGFsbGVkKQojIGluc3RhbGwucGFja2FnZXMoImxtdGVzdCIpCgojIExvYWQgdGhlIHBhY2thZ2UKbGlicmFyeShsbXRlc3QpCgojIFJ1biB0aGUgQnJldXNjaOKAk1BhZ2FuIHRlc3QKYnB0ZXN0KG1vZGVsKQoKYGBgCgoKYGBge3J9CiMgSW5zdGFsbCAoaWYgbm90IHlldCBpbnN0YWxsZWQpCiMgaW5zdGFsbC5wYWNrYWdlcygibG10ZXN0IikKCiMgTG9hZCB0aGUgcGFja2FnZQpsaWJyYXJ5KGxtdGVzdCkKCiMgUnVuIHRoZSBCcmV1c2No4oCTUGFnYW4gdGVzdApicHRlc3QobW9kZWwyKQoKYGBgCgpOYSB6w6FrbGFkZSB2w71zbGVka292IHJlZ3Jlc2llIG3DtMW+ZW1lIHBvdmVkYcWlLCDFvmUgaGV0ZXJvc2tlZGFzdGljaXRhIHJlesOtZHXDrSBuaWUgamUgdiAqbW9kZWwyKiAgcHLDrXRvbW7DoSwgYWxlIHYgcHLDrXBhZGUgKm1vZGVsKiBwcsOpdG9tbsOhIGplLiBBayBieSBhbGUgcHLDrXRvbW7DoSBib2xhLCBhIGxvZ2FyaXRtaXrDoWNpYSBwcmVtZW5uw71jaCwgYWxlYm8gb2RzdHLDoW5lbmllIG9kxL5haGzDvWNoIHByZW1lbm7DvWNoIGJ5IG7DoW0gbmVwb21vaGxpLCBtw7TFvmVtZSB0byByaWXFoWnFpSBzIHBvbW9jb3UgdGFrenZhbmVqIFdoaXRlIGhldGVyb3NrZWRhc3RpY2l0eSBDb25zaXN0ZW50IG1hdHJpeCwga2RlIHYgdCB0ZXN0b2NoIHbDvXpuYW1ub3N0aSByZWdyZXNuw71jaCBrb2VmaWNpZW50b3Ygc2EgcG91xb7DrXZhasO6ICJocnVixaFpZSIgb2RoYWR5IHJvenB0eWxvdiByZWdyZXNuw71jaCBrb2VmaWNpZW50b3YuIFVyb2LDrW1lIHRvIG5hc2xlZG92bmUKCmBgYHtyfQojaW5zdGFsbC5wYWNrYWdlcygic2FuZHdpY2giKQojaW5zdGFsbC5wYWNrYWdlcygibG10ZXN0IikKbGlicmFyeShzYW5kd2ljaCkKbGlicmFyeShsbXRlc3QpCmNvZWZ0ZXN0KG1vZGVsLCB2Y292ID0gdmNvdkhDKG1vZGVsKSkKCgpgYGAKClbFoWltbmltZSBzaSwgxb5lIHRlbnRva3LDoXQgamUgdcW+IGthxb5kw6EgcHJlbWVubsOhIMWhdGF0aXN0aWNreSB2w716bmFtbsOhLiBOYSBkcnVoZWogc3RyYW5lIHRyZWJhIHBvZG90a27DusWlLCDFvmUgcG91xb5pdGllIHRlanRvIG1ldMOzZHkgdnnFvmFkdWplIHZlxL5rw70gcG/EjWV0IHBvem9yb3ZhbsOtICg+IDEwMCkKCk1lbmVqIHBvdcW+w612YW5vdSBqZSBtb8W+bm9zxaUsIGtlZHkgcHJlZGVsw61tZSB2xaFldGt5IHByZW1lbm7DqSB2IGTDoXRvdm9tIHNldGUgcHJlbWVubm91LCBrdG9yw6EgaGV0ZXJvc2tlZGFzdGljaXR1IHNww7Rzb2J1amUsIMSNbyBhbGUgxI1hc3RvIHZlZGllIGsgemhvcsWhZW5pdSBpbnRlcnByZXRhxI1uZWogc2Nob3Bub3N0aSBtb2RlbHUuIFYgcHLDrXBhZGUgbmFwci4gR0RQLCBtbm/FvnN0dmEgb3B5dmF0ZcS+b3YgYSByb3psb2h5IGtyYWppbnkgdG8gYWxlIG5hcHLDrWtsYWQgbW/Fvm7DqSBqZS4gQWsgbmFwcsOta2xhZCAocG9kxL5hIGdyYWZvdikgemlzdMOtbWUsIMW+ZSBwcmVtZW5uw6EgKm1ub8W+c3R2byBvYnV2YXRlxL5vdiogc3DDtHNvYnVqZSBoZXRlcm9za2VkYXN0aWNpdHUsIHZ5cG/EjcOtdGFtZSBHRFAgbmEgb2J5dmF0ZcS+YSwgcmVzcC4gcG/EjWV0IGttIMWhdHZvcmNvdsO9Y2ggbmEgamVkbsOpaG8gb2J5dmF0ZcS+YSBhIG3DtMW+ZW1lIGRvc3RhxaUgbm92w70gbW9kZWwgcyBvZHN0csOhbmVub3UgaGV0ZXJvc2tlZGFzdGljaXRvdS4KCgoKCg==