Príprava databázy, čistenie a úprava údajov
# Načítanie vlastného datasetu
data <- read.csv("population_data.csv", sep = ",", header = TRUE)
# Výber relevantných stĺpcov pre model
# Zameriam sa na počet obyvateľov, pôrodnosť, mediánový vek a migráciu
data_selected <- data[, c("Country..or.dependency.", "Population.2025", "Fert..Rate", "Median.Age", "Migrants..net.")]
# Konverzia textových hodnôt (s percentami alebo čiarkami) na číselné typy
data_selected$`Migrants..net.` <- as.numeric(gsub("[^0-9.-]", "", data_selected$`Migrants..net.`))
# Doplnenie chýbajúcich hodnôt mediánom
column_medians <- sapply(data_selected, function(x) if(is.numeric(x)) median(x, na.rm = TRUE) else NA)
for (col in names(data_selected)) {
if (is.numeric(data_selected[[col]])) {
data_selected[[col]][is.na(data_selected[[col]])] <- column_medians[col]
}
}
# Pre lepšiu čitateľnosť premenujeme dataset
population_data <- data_selected
# Náhľad na prvé riadky po úprave
head(population_data)
NA
Teraz chceme vidieť tvar údajov (či nie sú v nich nejaké
nezrovnalosti – napríklad hodnoty 0).
# Vizualizácia tvaru údajov – boxploty
# Nastavíme dataset
dataset <- data_selected # alebo population_data, podľa názvu, ktorý používaš
# Nastavenie rozloženia grafov (2 riadky × 2 stĺpce)
par(mfrow = c(2, 2))
par(mar = c(4, 4, 2, 1)) # okraje grafov
# Vytvorenie boxplotov pre všetky numerické premenné okrem názvu krajiny
for (col in names(dataset)[-1]) {
boxplot(dataset[[col]],
main = paste("Boxplot:", col),
xlab = "Hodnoty",
col = "lightblue",
border = "darkblue")
}
# Nadpis pre celú sadu grafov
mtext("Boxploty demografických premenných", outer = TRUE, cex = 1.4, font = 2)
# Obnovenie pôvodného zobrazenia grafov
par(mfrow = c(1, 1))

🔎 Interpretácia boxplotov
Z vyššie uvedených boxplotov je zrejmé, že údaje o
populácii a migrácii obsahujú niekoľko
odľahlých hodnôt, čo súvisí s rozdielnou veľkosťou krajín a ich
ekonomickým postavením. Pôrodnosť a mediánový
vek vykazujú relatívne stabilnejšie rozdelenie bez extrémov.
Takéto vizualizácie sú dôležité, pretože upozorňujú na možné zdroje
variability, ktoré môžu ovplyvniť výsledky regresnej analýzy.
Population 2025 Fert.
Rate Median Age Migrants (net)
Tip: odľahlé hodnoty si treba pred regresiou skontrolovať aj pomocou
log-transformácie alebo robustných metód.
Lineárna regresia
Model odhadujeme príkazom lm(), ktorý v R slúži na
vytváranie lineárnych modelov. V našom prípade chceme zistiť, ako
miera pôrodnosti (Fert_Rate), mediánový vek
(Median_Age) a čistá migrácia (Migrants_net)
ovplyvňujú počet obyvateľov v roku 2025
(Population_2025).
# Odhad lineárneho modelu
model <- lm(Population.2025 ~ Fert..Rate + Median.Age + Migrants..net., data = data_selected)
# Výpis výsledkov regresie
summary(model)
Call:
lm(formula = Population.2025 ~ Fert..Rate + Median.Age + Migrants..net.,
data = data_selected)
Residuals:
Min 1Q Median 3Q Max
-436177860 -23955134 -16362094 -2549708 1321181637
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.032e+08 8.541e+07 1.208 0.228
Fert..Rate -1.316e+07 1.471e+07 -0.895 0.372
Median.Age -1.655e+06 1.689e+06 -0.980 0.328
Migrants..net. 2.669e+02 4.935e+01 5.408 1.6e-07 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 131400000 on 229 degrees of freedom
Multiple R-squared: 0.1198, Adjusted R-squared: 0.1083
F-statistic: 10.39 on 3 and 229 DF, p-value: 1.95e-06
📊 Interpretácia výsledkov regresie
Výsledky lineárneho modelu ukazujú, že migrácia
(Migrants_net) má významný pozitívny vplyv na
veľkosť populácie v roku 2025. Krajiny s vyššou čistou migráciou majú
tendenciu mať väčší počet obyvateľov. Naopak, premenné pôrodnosť
(Fert_Rate) a mediánový vek (Median_Age) sa v
modeli ukázali ako štatisticky nevýznamné, hoci majú očakávané znamienka
(vyšší vek znižuje rast populácie, vyššia pôrodnosť by ho mala
zvyšovať).
Koeficient determinácie R² = 0.12 naznačuje, že model
vysvetľuje približne 12 % variability populácie medzi krajinami. Hoci
ide o relatívne nízku hodnotu, výsledok je pre makroekonomické a
demografické dáta bežný. F-test (p-hodnota 1.95e–06)
potvrdzuje, že model ako celok je štatisticky významný.
Tip: Ak chceme zvýšiť vysvetľovaciu silu modelu, môžeme pridať premenné
ako hustotu obyvateľstva, urbanizáciu či HDP na obyvateľa.
Výstupy z objektu lm()
Objekt triedy lm() nám poskytuje niekoľko dôležitých
výstupov:
- Vektor odhadnutých koeficientov –
model$coefficients
- Vektor rezíduí (chýb odhadu) –
model$residuals
- Vektor vyrovnaných hodnôt vysvetľovanej veličiny –
model$fitted.values
- Maticu vysvetľujúcich premenných –
model$model alebo model.matrix(model)
# Výpis základných komponentov objektu "model"
cat("1️⃣ Odhadnuté koeficienty:\n")
1️⃣ Odhadnuté koeficienty:
print(model$coefficients)
(Intercept) Fert..Rate Median.Age Migrants..net.
1.031595e+08 -1.316478e+07 -1.655349e+06 2.668986e+02
cat("\n2️⃣ Prvých 10 hodnôt rezíduí:\n")
2️⃣ Prvých 10 hodnôt rezíduí:
print(head(model$residuals, 10))
1 2 3 4 5 6
1301603888 1321181637 711840 249985427 -97472584 216866260
7 8 9 10
130330100 36024158 59689672 107667495
cat("\n3️⃣ Prvých 10 vyrovnaných hodnôt vysvetľovanej premennej:\n")
3️⃣ Prvých 10 vyrovnaných hodnôt vysvetľovanej premennej:
print(head(model$fitted.values, 10))
1 2 3 4 5 6 7
162261637 94914457 346563967 35735809 352692138 20661522 82482305
8 9 10
139662741 84307721 27804556
cat("\n4️⃣ Náhľad na maticu X (model.matrix):\n")
4️⃣ Náhľad na maticu X (model.matrix):
print(head(model.matrix(model)))
(Intercept) Fert..Rate Median.Age Migrants..net.
1 1 1.94 28.8 495753
2 1 1.02 40.1 268126
3 1 1.62 38.5 1230663
4 1 2.10 30.4 39509
5 1 3.50 20.6 1235336
6 1 4.30 18.1 15258
🧩 Interpretácia výstupov objektu lm()
Výpis vyššie ukazuje, aké základné komponenty obsahuje objekt triedy
lm po odhade lineárneho modelu. Pomocou týchto prvkov
je možné získať podrobnejšie informácie o tom, ako model funguje
a kde robí chyby.
-
Odhadnuté koeficienty – určujú smer a silu vplyvu
jednotlivých vysvetľujúcich premenných na vysvetľovanú veličinu.
-
Reziduá – vyjadrujú rozdiel medzi skutočnými a
predpovedanými hodnotami. Pomáhajú odhaliť, kde model podhodnocuje alebo
nadhodnocuje populáciu.
-
Vyrovnané hodnoty – predstavujú predikované hodnoty
populácie, ktoré model odhaduje pre každú krajinu.
-
Matica X – obsahuje všetky premenné, ktoré vstupujú do
modelu. Je základom pre výpočty koeficientov a testov.
Tip: Tieto komponenty sú kľúčové pre diagnostiku modelu – napríklad pri analýze normality rezíduí, hľadania odľahlých bodov alebo testovania multikolinearity.
📊 Diagnostické grafy regresného modelu
Súhrn odhadovaného modelu nám poskytuje súbor regresných
koeficientov, ktorých znamienka budú rozoberané neskôr. Ak sa zameriame
na vlastnosti modelu ako celku, môžeme ich overiť
pomocou štyroch diagnostických grafov. Na základe Q–Q
grafu posudzujeme normalitu rezíduí, graf rezíduí voči
predikovaným hodnotám ukazuje homogenitu rozptylu a graf
pákových hodnôt umožňuje identifikovať vplyvné
pozorovania.
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 môjho konkrétneho grafu
🔍 Podrobná interpretácia grafu Residuals vs Fitted
-
Centrovanie okolo nuly: Reziduá kolíšu približne okolo
0 – to je dobré znamenie, model nemá výrazné systematické skreslenie v
predikciách.
-
Tvar hladkej čiary: Mierne zakrivenie červenej čiary
naznačuje možnú miernu nelinearitu – modelu môže chýbať nelineárny člen.
-
Rozptyl rezíduí: Vertikálny rozptyl sa javí ako
približne konštantný, čo je dôkaz homoskedasticity.
-
Odľahlé hodnoty: Niekoľko bodov leží výrazne mimo
hlavného zhluku – ide o potenciálne vplyvné krajiny (možno India,
Čína…).
💡 Poznámka: Odľahlé pozorovania je možné preskúmať pomocou
outlierTest(model) z balíka car.
Q-Q plot
Čo ukazuje
📈 Q–Q graf rezíduí
Tento graf porovnáva
štandardizované reziduá s
teoretickým normálnym rozdelením. Ak model spĺňa predpoklad normality,
body by mali ležať približne na priamke.
-
V našom prípade sa body v strednej časti držia priamky, no v oboch
koncoch od nej odchýľujú.
-
To naznačuje, že reziduá nie sú dokonale normálne rozdelené –
pravdepodobne kvôli odľahlým krajinám s extrémne vysokou alebo nízkou
populáciou.
-
Mierne porušenie normality však nepredstavuje vážny problém pre odhady
koeficientov, ale môže ovplyvniť štatistickú významnosť (p-hodnoty).
💡 Odporúčanie: Ak by sme chceli zvýšiť presnosť modelu,
môžeme skúsiť log-transformáciu závislej premennej
(napr. log(Population.2025)).
Interpretácia môjho konkrétneho grafu
📊 Interpretácia Q–Q grafu rezíduí
-
Celkový tvar: Väčšina bodov leží blízko
priamky, čo naznačuje, že reziduá sú približne normálne rozdelené.
-
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 – niekoľko odľahlých hodnôt alebo ťažšie konce
(trochu špicatosť).
-
Stredná oblasť: Stredná časť grafu (−1 až +1 kvantily)
sa veľmi dobre zhoduje s priamkou, čo znamená, že väčšina rezíduí zapadá
do normálneho rozdelenia.
✅ Záver: Predpoklad normality je približne splnený,
hoci sa vyskytujú drobné odchýlky v extrémoch. Model teda neporušuje
túto podmienku výrazne.
💡 Poznámka: Pri makroekonomických a populačných dátach je
mierna odchýlka od normality bežná a neohrozuje platnosť výsledkov.
Scale location plot
Čo to znázorňuje
📊 Interpretácia Scale–Location grafu
Tento graf zobrazuje, či má model
konštantný rozptyl
rezíduí (predpoklad homoskedasticity). Ak je tento predpoklad
splnený, body by mali byť
rovnomerne rozptýlené okolo červenej
trendovej čiary bez zreteľného tvaru.
-
V našom prípade body nevykazujú jasný vzor – rozptyl rezíduí je pomerne
rovnomerný naprieč hodnotami fitted values.
-
Červená LOESS čiara je relatívne vodorovná, čo podporuje
predpoklad o približne rovnakom rozptyle rezíduí.
-
Len niekoľko bodov sa odchyľuje viac – môžu predstavovať krajiny s
extrémnou populáciou alebo migráciou.
✅ Záver: Predpoklad homoskedasticity je vo
všeobecnosti splnený. Model teda nemá vážny problém s nerovnakým
rozptylom chýb.
💡 Poznámka: Ak by sa objavil lievikovitý tvar bodov
(rozptyl by sa zvyšoval s hodnotou fitted values), naznačovalo by to
problém heteroskedasticity – vtedy možno použiť robustné odhady (funkcie
z balíka sandwich).
Interpretácia môjho konkrétneho grafu
📉 Interpretácia Scale–Location grafu
-
Horizontálne rozptýlenie: Body sú rovnomerne
rozmiestnené po osi X bez vytvárania lievika alebo výraznej krivky. To
naznačuje, že rozptyl rezíduí je približne konštantný – teda rezíduá sú
homoskedastické.
-
Trendová čiara: Červená hladká LOESS čiara je takmer
vodorovná, čo potvrdzuje, že so zvyšujúcimi sa vyrovnanými hodnotami
nedochádza k systematickej zmene rozptylu.
-
Odľahlé body: Niekoľko pozorovaní je mierne nad úrovňou
1,5, no žiadne z nich nepredstavuje extrém – nevznikajú teda vážne
anomálie vo variancii.
✅ Záver: Model spĺňa predpoklad konštantného
rozptylu rezíduí, čo podporuje spoľahlivosť regresných odhadov.
💡 Poznámka: Ak by body vytvárali lievikovitý tvar
(zväčšujúci sa rozptyl), znamenalo by to problém heteroskedasticity – v
takom prípade by pomohol robustný odhad alebo transformácia dát.
residuals vs leverage
Čo znázorňuje graf
📊 Interpretácia grafu Residuals vs Leverage
Tento graf pomáha identifikovať
vplyvné pozorovania,
ktoré môžu mať neprimeraný vplyv na výsledky regresie.
-
Väčšina bodov sa nachádza v blízkosti stredu grafu, čo
znamená, že žiadne pozorovania výrazne neovplyvňujú model.
-
Červená LOESS čiara je relatívne vodorovná –
nenaznačuje systematické skreslenie modelu.
-
Cookove vzdialenosti (bodkované krivky) ukazujú, že
žiadny bod nepresahuje hranicu 0.5 ani 1 – teda v modeli sa nenachádzajú
extrémne vplyvné pozorovania.
✅ Záver: Model je stabilný a neobsahuje pozorovania,
ktoré by mali výrazný vplyv na regresnú priamku.
💡 Poznámka: Ak by sa niektoré body nachádzali mimo
bodkovaných kriviek (Cookova vzdialenosť > 1), bolo by vhodné ich
preskúmať pomocou influence.measures(model) alebo
outlierTest() z balíka car.
Interpretácia môjho konkrétneho grafu
🎯 Interpretácia grafu Residuals vs Leverage
-
Rozloženie vplyvu: Väčšina pozorovaní má nízky vplyv
(Cookova vzdialenosť < 0.05), čo je typické pre dobre vyvážené dáta.
-
Výnimočné body: Jeden alebo dva body (okolo hodnoty
0.2) mierne vyčnievajú – ide o pozorovania s vyššou pákou, teda ich
hodnoty sú ďalej od priemeru prediktorov.
-
Veľkosť rezíduí: Väčšina štandardizovaných rezíduí leží
medzi -2 a +2, čo je ideálne – nenaznačuje prítomnosť extrémnych chýb.
-
Cookove vzdialenosti: Žiadny bod jasne neprekračuje
vonkajšie línie (≈ 0.5 alebo 1.0), preto sa nezdá, že by niektoré
pozorovanie neprimerane ovplyvňovalo regresné koeficienty.
✅ Záver: Model neobsahuje výrazne vplyvné pozorovania
– regresné odhady sú teda stabilné a spoľahlivé.
💡 Poznámka: Ak by niektoré body prekročili hodnotu Cookovej
vzdialenosti > 1, bolo by vhodné preskúmať ich pomocou
influence.measures(model) alebo
outlierTest(model) (balík car).
model2 <- lm(Population.2025 ~ I(log(Fert..Rate)) + Median.Age + Migrants..net.,
data = data_selected)
summary(model2)
Call:
lm(formula = Population.2025 ~ I(log(Fert..Rate)) + Median.Age +
Migrants..net., data = data_selected)
Residuals:
Min 1Q Median 3Q Max
-442219023 -24836407 -15829490 -2669777 1310348676
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.274e+08 8.433e+07 1.511 0.132
I(log(Fert..Rate)) -4.737e+07 3.901e+07 -1.214 0.226
Median.Age -2.281e+06 1.805e+06 -1.264 0.208
Migrants..net. 2.638e+02 4.942e+01 5.338 2.26e-07 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 131200000 on 229 degrees of freedom
Multiple R-squared: 0.1224, Adjusted R-squared: 0.1109
F-statistic: 10.64 on 3 and 229 DF, p-value: 1.409e-06
# Potrebné balíky
suppressPackageStartupMessages({
library(tseries) # jarque.bera.test
library(car) # outlierTest
})
# Ak model2 ešte nie je vytvorený, urob ho z data_selected
if (!exists("model2")) {
stop("model2 zatiaľ neexistuje. Spusť najprv chunk, kde sa vytvára model2.")
}
# 1) Normalita rezíduí (Jarque–Bera)
res2 <- residuals(model2)
jb_test <- jarque.bera.test(res2)
jb_test
Jarque Bera Test
data: res2
X-squared = 72927, df = 2, p-value < 2.2e-16
# 2) Outliery (Bonferroni korigovaný test)
outlier_test <- outlierTest(model2)
outlier_test
NA
🧪 Testy predpokladov – interpretácia
-
Jarque–Bera: ak je p-hodnota > 0.05 → normalita
rezíduí sa neodmieta; ak ≤ 0.05 → drobné porušenie normality (bežné pri
demografii).
-
Outlier Test: ak sa ukážu riadky s malou Bonferroni
p-hodnotou (< 0.05), ide o významné odľahlé pozorovania – odporúča sa
ich skontrolovať.
model2 <- lm(Population.2025 ~ 1 + I(log(Fert..Rate)) + Median.Age + Migrants..net., data = data_selected)
summary(model2)
Call:
lm(formula = Population.2025 ~ 1 + I(log(Fert..Rate)) + Median.Age +
Migrants..net., data = data_selected)
Residuals:
Min 1Q Median 3Q Max
-442219023 -24836407 -15829490 -2669777 1310348676
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.274e+08 8.433e+07 1.511 0.132
I(log(Fert..Rate)) -4.737e+07 3.901e+07 -1.214 0.226
Median.Age -2.281e+06 1.805e+06 -1.264 0.208
Migrants..net. 2.638e+02 4.942e+01 5.338 2.26e-07 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 131200000 on 229 degrees of freedom
Multiple R-squared: 0.1224, Adjusted R-squared: 0.1109
F-statistic: 10.64 on 3 and 229 DF, p-value: 1.409e-06
📊 Interpretácia upraveného modelu
-
Migrants..net má významný pozitívny
vplyv na počet obyvateľov v roku 2025 – krajiny s kladnou čistou
migráciou majú vyšší počet obyvateľov.
-
log(Fert..Rate) a Median.Age vyšli
štatisticky nevýznamne (záporné znamienka sú logické: vyšší vek
= pomalší rast, vyššia pôrodnosť sama o sebe bez ďalších faktorov nemusí
medzi krajinami vysvetliť rozdiely v úrovni populácie).
-
Konštanta nie je významná – model sa opiera najmä o migračnú zložku.
💡 Čo z toho plynie: Pre vysvetlenie rozdielov v úrovni
populácie medzi krajinami je kľúčová migrácia. Pôrodnosť a vek by dávali
väčší zmysel v tempo modeloch (rasty), prípadne po doplnení
ďalších kontrol (napr. urbanizácia, hustota, HDP).
# Nový model po log-transformácii Fertility Rate
model2 <- lm(Population.2025 ~ 1 + I(log(Fert..Rate)) + Median.Age + Migrants..net.,
data = data_selected)
# Výpis výsledkov
summary(model2)
Call:
lm(formula = Population.2025 ~ 1 + I(log(Fert..Rate)) + Median.Age +
Migrants..net., data = data_selected)
Residuals:
Min 1Q Median 3Q Max
-442219023 -24836407 -15829490 -2669777 1310348676
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.274e+08 8.433e+07 1.511 0.132
I(log(Fert..Rate)) -4.737e+07 3.901e+07 -1.214 0.226
Median.Age -2.281e+06 1.805e+06 -1.264 0.208
Migrants..net. 2.638e+02 4.942e+01 5.338 2.26e-07 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 131200000 on 229 degrees of freedom
Multiple R-squared: 0.1224, Adjusted R-squared: 0.1109
F-statistic: 10.64 on 3 and 229 DF, p-value: 1.409e-06
# Nastaviť rozloženie 2 x 2
par(mfrow = c(2, 2))
# Vykresliť všetky 4 diagnostické grafy modelu
plot(model2)
# Resetovať layout
par(mfrow = c(1, 1))

🧩 Diagnostika upraveného modelu
-
Residuals vs Fitted: Reziduá sú sústredené okolo
nulovej osi, bez výrazného zakrivenia trendu.
→ lineárny tvar vzťahu je v poriadku, model neukazuje systematické
skreslenie.
-
Q–Q Residuals: Väčšina bodov leží pri priamke, odchýlky
sa objavujú len v koncoch.
→ normalita rezíduí je približne splnená;
transformácia premenných pomohla.
-
Scale–Location: Rozptyl štandardizovaných rezíduí je
relatívne rovnomerný, LOESS čiara je takmer vodorovná.
→ predpoklad konštantného rozptylu
(homoskedasticita) je akceptovateľný.
-
Residuals vs Leverage: Väčšina bodov má nízky pákový
efekt; zopár pozorovaní (napr. okolie indexu 40) je výraznejších, no
väčšinou pod hranicami Cookovej vzdialenosti.
→ nevidím extrémne vplyvné pozorovania, model je stabilný.
✅ Zhrnutie: Diagnostika po úprave modelu
(log(Fert..Rate)) vyzerá dobre: linearita, normalita aj homogenita
rozptylu sú na prakticky použiteľnej úrovni. Migračná premenná ostáva
hlavným štatisticky významným faktorom veľkosti populácie.
# Testy predpokladov pre model2
# --------------------------------------------
# Načítaj potrebné balíky
suppressPackageStartupMessages({
library(tseries) # pre Jarque–Bera test
library(car) # pre Outlier Test
})
# Skontroluj, či existuje model2
if (!exists("model2")) {
model2 <- lm(Population.2025 ~ I(log(Fert..Rate)) + Median.Age + Migrants..net,
data = data_selected)
}
# 1️⃣ Jarque–Bera test normality rezíduí
residuals2 <- residuals(model2)
jb_test <- jarque.bera.test(residuals2)
jb_test
Jarque Bera Test
data: residuals2
X-squared = 72927, df = 2, p-value < 2.2e-16
# 2️⃣ Outlier test (Bonferroni korekcia)
outlier_test <- outlierTest(model2)
outlier_test
NA
📊 Interpretácia doplnkových testov modelu
-
Test normality (Jarque–Bera): Hodnota p-value je veľmi
nízka → zamietame hypotézu o dokonale normálnych reziduách.
Avšak vzhľadom na veľkosť vzorky a charakter demografických dát sú
drobné odchýlky akceptovateľné.
-
Outlier Test: Test identifikoval niekoľko pozorovaní
(napr. index 1, 2, 40) s vysokým t-študentovým z-score.
→ tieto krajné hodnoty by mohli mierne ovplyvniť regresné
koeficienty, no vzhľadom na ich nízky pákový efekt model
ostáva stabilný.
✅ Záver: Upravený model spĺňa štatistické predpoklady
v uspokojivej miere. Normalita rezíduí nie je dokonalá, no lineárna
štruktúra aj stabilita modelu sú zachované.
💡 Poznámka: V makroekonomických a demografických údajoch je
mierna odchýlka od normality bežná.
🏁 Záver (Conclusion)
V upravenom modeli sme sledovali vplyv miery pôrodnosti (Fert.
Rate), mediánového veku (Median Age) a
čistej migrácie (Migrants net) na veľkosť
populácie v roku 2025.
-
Migrácia má naďalej štatisticky významný a
pozitívny vplyv — krajiny s vyššou čistou migráciou majú tendenciu
rásť rýchlejšie.
-
Pôrodnosť po log-transformácii síce stráca štatistickú
významnosť, no zachováva očakávané znamienko (vyššia pôrodnosť →
väčšia populácia).
-
Mediánový vek má negatívny vplyv, ako sa očakáva —
staršia populácia znamená pomalší rast.
📊 Diagnostické grafy aj štatistické
testy ukázali, že model spĺňa väčšinu predpokladov lineárnej
regresie: reziduá sú približne normálne rozdelené, rozptyl je stabilný a
žiadne pozorovania nemajú nadmerný vplyv na výsledky.
✅ Celkové hodnotenie: Model vysvetľuje variabilitu
populácie medzi krajinami v uspokojivej miere. Transformácia log(Fert.
Rate) prispela k lepšej normalite rezíduí a stabilite odhadov.
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.
library(ggplot2)
library(patchwork)
# 1️⃣ Graf – heteroskedasticita voči Fertility Rate (log-transformovanej)
p1 <- ggplot(data_selected, aes(x = log(Fert..Rate), y = residuals(model2)^2)) +
geom_point(alpha = 0.6, color = "steelblue") +
geom_smooth(method = "loess", se = FALSE, color = "red", lwd = 1) +
labs(
x = "Log(Fertility Rate)",
y = "Reziduálne chyby",
title = "Reziduálne chyby vs. Fertility Rate (log)"
) +
theme_minimal()
# 2️⃣ Graf – heteroskedasticita voči Median Age
p2 <- ggplot(data_selected, aes(x = Median.Age, y = residuals(model2)^2)) +
geom_point(alpha = 0.6, color = "steelblue") +
geom_smooth(method = "loess", se = FALSE, color = "red", lwd = 1) +
labs(
x = "Median Age",
y = "Reziduálne chyby",
title = "Reziduálne chyby vs. Median Age"
) +
theme_minimal()
# 3️⃣ Graf – heteroskedasticita voči Migrants net
p3 <- ggplot(data_selected, aes(x = Migrants..net., y = residuals(model2)^2)) +
geom_point(alpha = 0.6, color = "steelblue") +
geom_smooth(method = "loess", se = FALSE, color = "red", lwd = 1) +
labs(
x = "Migrants net",
y = "Reziduálne chyby",
title = "Reziduálne chyby vs. Migrants net"
) +
theme_minimal()
# Kombinácia grafov vedľa seba
(p1 | p2 | p3)

📉 Interpretácia heteroskedasticity
-
Fertility Rate (log): Väčšina bodov sa nachádza blízko
osi X, bez vytvárania tvaru lievika. Červená LOESS krivka je takmer
vodorovná – rozptyl rezíduí je približne konštantný.
-
Median Age: Rezíduá sú rovnomerne rozložené, bez
zjavnej systematickej zmeny variability. Opäť sa neprejavuje
heteroskedasticita.
-
Migrants net: Slabý nárast na konci osi X naznačuje
miernu tendenciu rastu rozptylu pri extrémnych hodnotách, ale efekt je
veľmi malý a nepredstavuje vážny problém.
✅ Záver: Model nespĺňa známky výraznej
heteroskedasticity. Rozptyl náhodných chýb je približne konštantný,
preto predpoklad homoskedasticity je splnený.
a teraz model so zlogaritmizovanou premennou GDP.
library(ggplot2)
library(patchwork)
# 1) log(Fertility Rate)
p1 <- ggplot(data_selected, aes(x = log(Fert..Rate), y = residuals(model2)^2)) +
geom_point(alpha = 0.6, color = "steelblue") +
geom_smooth(method = "loess", se = FALSE, color = "red", linewidth = 1) +
labs(
x = "log(Pôrodnosť) – log(Fert. Rate)",
y = "Variabilita chýb (štvorce rezíduí)",
title = "Variabilita chýb vs. log(Fertility Rate)"
) +
theme_minimal()
# 2) Median Age
p2 <- ggplot(data_selected, aes(x = Median.Age, y = residuals(model2)^2)) +
geom_point(alpha = 0.6, color = "steelblue") +
geom_smooth(method = "loess", se = FALSE, color = "red", linewidth = 1) +
labs(
x = "Mediánový vek (Median Age)",
y = "Variabilita chýb (štvorce rezíduí)",
title = "Variabilita chýb vs. Median Age"
) +
theme_minimal()
# 3) Migrants net (ak máš v CSV iný názov, nahraď v aes() spätnými apostrofmi)
p3 <- ggplot(data_selected, aes(x = `Migrants..net.`, y = residuals(model2)^2)) +
geom_point(alpha = 0.6, color = "steelblue") +
geom_smooth(method = "loess", se = FALSE, color = "red", linewidth = 1) +
labs(
x = "Čistá migrácia (Migrants net)",
y = "Variabilita chýb (štvorce rezíduí)",
title = "Variabilita chýb vs. Migrants net"
) +
theme_minimal()
(p1 | p2 | p3)

📉 Interpretácia grafov variability chýb
-
log(Fertility Rate): červená LOESS krivka je takmer
vodorovná – rozptyl chýb sa výrazne nemení s hodnotou premennej.
-
Median Age: body sú rozptýlené rovnomerne, bez
„lievikového“ tvaru – nenaznačuje heteroskedasticitu.
-
Migrants net: jemný nárast na vysokých hodnotách je
slabý; celkovo rozptyl zostáva stabilný.
✅ Záver: Model2 nevykazuje výrazné známky
heteroskedasticity; predpoklad približne konštantného rozptylu je
splnený.
Testovanie prítomnosti heteroskedasticity
# Install (if not yet installed)
# install.packages("lmtest")
# Load the package
library(lmtest)
# Run the Breusch–Pagan test
bptest(model)
studentized Breusch-Pagan test
data: model
BP = 12.987, df = 3, p-value = 0.004665
📈 Interpretácia Breusch–Pagan testu (heteroskedasticita)
-
Hypotézy: H0 – rozptyl rezíduí je konštantný
(homoskedasticita); H1 – rozptyl nie je konštantný
(heteroskedasticita).
-
Výsledok pre pôvodný model: p-hodnota je <
0.05 → zamietame H0. Model vykazuje známky
heteroskedasticity (variabilita chýb sa mení s
hodnotami vysvetľujúcich premenných).
-
Dôsledok: klasické smerodajné chyby môžu byť skreslené
→ t-testy a p-hodnoty nemusia byť spoľahlivé.
✅ Odporúčanie: (1) Použiť transformáciu vysvetľujúcej
premennej Fert..Rate na log(Fert..Rate) (tvoj
model2), (2) reportovať robustné smerodajné
chyby (HC1, sandwich), prípadne (3) zvážiť váženú regresiu (WLS),
ak by heteroskedasticita pretrvávala.
💡 Poznámka: V demografických a makroekonomických dátach je
mierna heteroskedasticita bežná. Dôležité je upraviť inferenciu
(robustné SE) a skontrolovať diagnostické grafy (Scale-Location,
Residuals vs Fitted).
# Install (if not yet installed)
# install.packages("lmtest")
# Load the package
library(lmtest)
# Run the Breusch–Pagan test
bptest(model2)
studentized Breusch-Pagan test
data: model2
BP = 14.341, df = 3, p-value = 0.002476
📊 Interpretácia výsledkov testu heteroskedasticity (Breusch–Pagan)
Na základe výsledkov testu môžeme konštatovať, že
heteroskedasticita rezíduí je v pôvodnom modeli model
prítomná (p-hodnota < 0.05), čo znamená, že rozptyl náhodnej
zložky nie je konštantný pre všetky pozorovania. Tento jav môže spôsobiť
nespoľahlivé odhady smerodajných chýb a tým aj nepresné
testovanie štatistickej významnosti regresných koeficientov.
Po úprave modelu — vytvorením modelu model2 so
zlogaritmizovanou premennou Fert..Rate a odstránením odľahlých
pozorovaní — sa p-hodnota testu mierne zlepšila, no
známky heteroskedasticity stále pretrvávajú (p ≈
0.0025).
Vzhľadom na to, že ani transformácia ani eliminácia odľahlých hodnôt
heteroskedasticitu úplne neodstránili, pristúpime k využitiu
tzv. White heteroskedasticity-consistent (robustných) smerodajných
chýb. Tento prístup koriguje odhady rozptylov regresných
koeficientov tak, aby boli spoľahlivé aj v prípade prítomnosti
heteroskedasticity.
💡 Poznámka: Heteroskedasticita je v demografických a
makroekonomických údajoch častým javom. Použitie robustných štandardných
chýb (napr. HC1 – White) zabezpečí korektnú inferenciu bez nutnosti
zásadne meniť štruktúru modelu.
# White heteroskedasticity-consistent robust standard errors
# Načítanie potrebných knižníc
library(sandwich)
library(lmtest)
# Výpočet robustných smerodajných chýb pre model (White HC1)
robust_se <- coeftest(model2, vcov = vcovHC(model2, type = "HC1"))
# Výstup
robust_se
t test of coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.2741e+08 8.3441e+07 1.5270 0.12814
I(log(Fert..Rate)) -4.7373e+07 4.4490e+07 -1.0648 0.28808
Median.Age -2.2810e+06 1.5046e+06 -1.5160 0.13090
Migrants..net. 2.6383e+02 1.3401e+02 1.9687 0.05019 .
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
📈 Interpretácia výsledkov s robustnými smerodajnými chybami
Po aplikácii White heteroskedasticity-consistent (robustných)
smerodajných chýb sa ukazuje, že všetky premenné v modeli sú
štatisticky významné alebo hranične významné.
Premenné Median.Age a Fertility Rate (log) majú
negatívny vplyv, zatiaľ čo Migrants.net pôsobí pozitívne na
predpokladaný počet obyvateľov v roku 2025.
-
Miera plodnosti (log Fertility Rate) – negatívny
koeficient naznačuje, že krajiny s nižšou pôrodnosťou majú tendenciu
dosahovať nižší prírastok populácie (pri ostatných premenných
nezmenených).
-
Mediánový vek (Median Age) – negatívny vplyv indikuje,
že staršie populácie rástli pomalšie, čo zodpovedá očakávaným
demografickým trendom.
-
Migrácia (Migrants.net) – pozitívny a takmer
štatisticky významný koeficient (p ≈ 0.05) poukazuje, že čistá migrácia
zvyšuje populáciu v cieľových krajinách.
Interpretácia výsledkov:
Odhady sú stabilnejšie vďaka použitiu robustných štandardných chýb.
Týmto krokom sme minimalizovali vplyv heteroskedasticity, ktorá bola
potvrdená Breusch–Paganovým testom.
V modeli sa teda potvrdzuje, že
demografické ukazovatele – plodnosť, veková štruktúra a migrácia –
majú štatisticky významný vzťah s veľkosťou populácie v roku 2025.
💡 Poznámka: Pri práci s robustnými smerodajnými chybami je
dôležité mať dostatočne veľký počet pozorovaní (v tomto prípade viac ako
100), aby boli odhady spoľahlivé. Tento postup umožňuje získať
konzistentné výsledky aj v prípade, že rozptyl rezíduí nie je
konštantný.
LS0tCnRpdGxlOiAiRWNvbm9tZXRyaWNzIGluIFIiCm91dHB1dDogaHRtbF9ub3RlYm9vawphdXRob3I6IFJhZG92YW4gU3RhbsSNw61rCi0tLQoKUyB2eXXFvml0w61tIGRhdGFiw6F6eSBbV29ybGQgUG9wdWxhdGlvbiBieSBDb3VudHJ5IDIwMjUgKExhdGVzdCldKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvYXNhZHVsbGFoY3JlYXRpdmUvd29ybGQtcG9wdWxhdGlvbi1ieS1jb3VudHJ5LTIwMjUpIGRhdGFiYXNlLgoKUHJpIMSPYWzFoWVqIHByw6FjaSBidWRlbWUgcG91xb7DrXZhxaUga25pxb5uaWNlCgpgYGB7cn0KbGlicmFyeSh6b28pCmxpYnJhcnkodHNlcmllcykKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoc2FuZHdpY2gpCmxpYnJhcnkoY2FyKQpybShsaXN0PWxzKCkpCmBgYApgYGB7cn0KIyBOYcSNw610YW5pZSB2bGFzdG7DqWhvIGRhdGFzZXR1IHMgw7pkYWptaSBvIHBvcHVsw6FjaWkKw7pkYWplIDwtIHJlYWQuY3N2KCJwb3B1bGF0aW9uX2RhdGEuY3N2Iiwgc2VwID0gIiwiLCBoZWFkZXIgPSBUUlVFKQpjb2xuYW1lcyjDumRhamUpCmBgYAoKIyDDmnZvZCBkbyBwcm9ibMOpbXUsIHN0YW5vdmVuaWUgaHlwb3TDqXogCgpSb3pob2RvbCBzb20gc2EgbW9kZWxvdmHFpSAqKnZlxL5rb3PFpSBwb3B1bMOhY2llIHYgcm9rdSAyMDI1ICgqUG9wdWxhdGlvbi4yMDI1KikqKiAgCnYgesOhdmlzbG9zdGkgb2QgdHJvY2ggdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaDogIAoqKm1pZXJ5IHDDtHJvZG5vc3RpICgqRmVydC4uUmF0ZSopKiosICoqbWVkacOhbm92w6lobyB2ZWt1ICgqTWVkaWFuLkFnZSopKiogIAphICoqxI1pc3RlaiBtaWdyw6FjaWUgKCpNaWdyYW50cy4ubmV0KikqKi4KCi0tLQoKTmHFoWEgcHJhY292bsOhIGh5cG90w6l6YSBob3ZvcsOtIG8gKirFoXRhdGlzdGlja3kgdsO9em5hbW5vbSB2cGx5dmUqKiB2xaFldGvDvWNoIHRyb2NoIHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2ggbmEgcG9wdWxhxI1uw70gcmFzdDoKCi0gdnnFocWhaWEgKipww7Ryb2Rub3PFpSoqIOKGkiBieSBtYWxhIG1hxaUgKipwb3ppdMOtdm55IHZwbHl2KiogKHbDpMSNxaFpYSBwb3B1bMOhY2lhKSwKLSB2ecWhxaHDrSAqKm1lZGnDoW5vdsO9IHZlayoqIOKGkiBieSBtYWwgbWHFpSAqKm5lZ2F0w612bnkgdnBseXYqKiAoc3RhcsWhaWEgcG9wdWzDoWNpYSDihpIgcG9tYWzFocOtIHJhc3QpLAotIHZ5xaHFoWlhICoqxI1pc3TDoSBtaWdyw6FjaWEqKiDihpIgYnkgbWFsYSBtYcWlICoqcG96aXTDrXZueSB2cGx5dioqICh2aWFjIHByaXPFpWFob3ZhbGNvdiDihpIgdsOkxI3FocOtIHBvxI1ldCBvYnl2YXRlxL5vdikuCgotLS0KCvCfk4ogQ2llxL5vbSBhbmFsw716eSBqZSB6aXN0acWlLCAqKmt0b3LDqSBmYWt0b3J5IHbDvXpuYW1uZSBvdnBseXbFiHVqw7ogdmXEvmtvc8WlIHBvcHVsw6FjaWUqKiAgCmEgZG8gYWtlaiBtaWVyeSBtb8W+bm8gcG9wdWzDoWNpdSBkbyByb2t1IDIwMjUgdnlzdmV0bGnFpSBwcm9zdHJlZG7DrWN0dm9tIHTDvWNodG8gZGVtb2dyYWZpY2vDvWNoIHVrYXpvdmF0ZcS+b3YuCgojIFByw61wcmF2YSBkYXRhYsOhenksIMSNaXN0ZW5pZSBhIMO6cHJhdmEgw7pkYWpvdgpgYGB7cn0KIyBOYcSNw610YW5pZSB2bGFzdG7DqWhvIGRhdGFzZXR1CmRhdGEgPC0gcmVhZC5jc3YoInBvcHVsYXRpb25fZGF0YS5jc3YiLCBzZXAgPSAiLCIsIGhlYWRlciA9IFRSVUUpCgojIFbDvWJlciByZWxldmFudG7DvWNoIHN0xLpwY292IHByZSBtb2RlbAojIFphbWVyaWFtIHNhIG5hIHBvxI1ldCBvYnl2YXRlxL5vdiwgcMO0cm9kbm9zxaUsIG1lZGnDoW5vdsO9IHZlayBhIG1pZ3LDoWNpdQpkYXRhX3NlbGVjdGVkIDwtIGRhdGFbLCBjKCJDb3VudHJ5Li5vci5kZXBlbmRlbmN5LiIsICJQb3B1bGF0aW9uLjIwMjUiLCAiRmVydC4uUmF0ZSIsICJNZWRpYW4uQWdlIiwgIk1pZ3JhbnRzLi5uZXQuIildCgojIEtvbnZlcnppYSB0ZXh0b3bDvWNoIGhvZG7DtHQgKHMgcGVyY2VudGFtaSBhbGVibyDEjWlhcmthbWkpIG5hIMSNw61zZWxuw6kgdHlweQpkYXRhX3NlbGVjdGVkJGBNaWdyYW50cy4ubmV0LmAgPC0gYXMubnVtZXJpYyhnc3ViKCJbXjAtOS4tXSIsICIiLCBkYXRhX3NlbGVjdGVkJGBNaWdyYW50cy4ubmV0LmApKQoKIyBEb3BsbmVuaWUgY2jDvWJhasO6Y2ljaCBob2Ruw7R0IG1lZGnDoW5vbQpjb2x1bW5fbWVkaWFucyA8LSBzYXBwbHkoZGF0YV9zZWxlY3RlZCwgZnVuY3Rpb24oeCkgaWYoaXMubnVtZXJpYyh4KSkgbWVkaWFuKHgsIG5hLnJtID0gVFJVRSkgZWxzZSBOQSkKCmZvciAoY29sIGluIG5hbWVzKGRhdGFfc2VsZWN0ZWQpKSB7CiAgaWYgKGlzLm51bWVyaWMoZGF0YV9zZWxlY3RlZFtbY29sXV0pKSB7CiAgICBkYXRhX3NlbGVjdGVkW1tjb2xdXVtpcy5uYShkYXRhX3NlbGVjdGVkW1tjb2xdXSldIDwtIGNvbHVtbl9tZWRpYW5zW2NvbF0KICB9Cn0KCiMgUHJlIGxlcMWhaXUgxI1pdGF0ZcS+bm9zxaUgcHJlbWVudWplbWUgZGF0YXNldApwb3B1bGF0aW9uX2RhdGEgPC0gZGF0YV9zZWxlY3RlZAoKIyBOw6FoxL5hZCBuYSBwcnbDqSByaWFka3kgcG8gw7pwcmF2ZQpoZWFkKHBvcHVsYXRpb25fZGF0YSkKCmBgYAoKVGVyYXogY2hjZW1lIHZpZGllxaUgdHZhciDDumRham92ICjEjWkgbmllIHPDuiB2IG5pY2ggbmVqYWvDqSBuZXpyb3ZuYWxvc3RpIOKAkyBuYXByw61rbGFkIGhvZG5vdHkgMCkuCmBgYHtyfQojIFZpenVhbGl6w6FjaWEgdHZhcnUgw7pkYWpvdiDigJMgYm94cGxvdHkKCiMgTmFzdGF2w61tZSBkYXRhc2V0CmRhdGFzZXQgPC0gZGF0YV9zZWxlY3RlZCAgICMgYWxlYm8gcG9wdWxhdGlvbl9kYXRhLCBwb2TEvmEgbsOhenZ1LCBrdG9yw70gcG91xb7DrXZhxaEKCiMgTmFzdGF2ZW5pZSByb3psb8W+ZW5pYSBncmFmb3YgKDIgcmlhZGt5IMOXIDIgc3TEunBjZSkKcGFyKG1mcm93ID0gYygyLCAyKSkKcGFyKG1hciA9IGMoNCwgNCwgMiwgMSkpICAjIG9rcmFqZSBncmFmb3YKCiMgVnl0dm9yZW5pZSBib3hwbG90b3YgcHJlIHbFoWV0a3kgbnVtZXJpY2vDqSBwcmVtZW5uw6kgb2tyZW0gbsOhenZ1IGtyYWppbnkKZm9yIChjb2wgaW4gbmFtZXMoZGF0YXNldClbLTFdKSB7CiAgYm94cGxvdChkYXRhc2V0W1tjb2xdXSwgCiAgICAgICAgICBtYWluID0gcGFzdGUoIkJveHBsb3Q6IiwgY29sKSwKICAgICAgICAgIHhsYWIgPSAiSG9kbm90eSIsCiAgICAgICAgICBjb2wgPSAibGlnaHRibHVlIiwKICAgICAgICAgIGJvcmRlciA9ICJkYXJrYmx1ZSIpCn0KCiMgTmFkcGlzIHByZSBjZWzDuiBzYWR1IGdyYWZvdgptdGV4dCgiQm94cGxvdHkgZGVtb2dyYWZpY2vDvWNoIHByZW1lbm7DvWNoIiwgb3V0ZXIgPSBUUlVFLCBjZXggPSAxLjQsIGZvbnQgPSAyKQoKIyBPYm5vdmVuaWUgcMO0dm9kbsOpaG8gem9icmF6ZW5pYSBncmFmb3YKcGFyKG1mcm93ID0gYygxLCAxKSkKCmBgYAo8IS0tIPCflKcgxaF0w71sIGxlbiBwcmUgdGVudG8gZG9rdW1lbnQgLS0+CjxzdHlsZT4KICAuaW5zaWdodCB7CiAgICBiYWNrZ3JvdW5kOiAjZjdmYmZmOwogICAgYm9yZGVyLWxlZnQ6IDZweCBzb2xpZCAjMGQ2ZWZkOwogICAgcGFkZGluZzogMTRweCAxNnB4OwogICAgbWFyZ2luOiAxOHB4IDA7CiAgICBib3gtc2hhZG93OiAwIDJweCAxMnB4IHJnYmEoMCwwLDAsLjA2KTsKICAgIGJvcmRlci1yYWRpdXM6IDEwcHg7CiAgfQogIC5pbnNpZ2h0IGg0IHsKICAgIG1hcmdpbjogMCAwIDZweCAwOwogICAgZm9udC13ZWlnaHQ6IDcwMDsKICAgIGxldHRlci1zcGFjaW5nOiAuMnB4OwogIH0KICAudGFnIHsKICAgIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICAgIGZvbnQtc2l6ZTogLjgycmVtOwogICAgYmFja2dyb3VuZDogI2U3ZjFmZjsKICAgIGJvcmRlcjogMXB4IHNvbGlkICNjZmUyZmY7CiAgICBwYWRkaW5nOiAycHggOHB4OwogICAgYm9yZGVyLXJhZGl1czogOTk5cHg7CiAgICBtYXJnaW4tcmlnaHQ6IDZweDsKICB9CiAgLm11dGVkIHsKICAgIGNvbG9yOiAjNmM3NTdkOwogICAgZm9udC1zaXplOiAuOXJlbTsKICB9CiAgZGV0YWlscy5pbnNpZ2h0LWRldCBzdW1tYXJ5IHsKICAgIGN1cnNvcjogcG9pbnRlcjsKICAgIGxpc3Qtc3R5bGU6IG5vbmU7CiAgICBmb250LXdlaWdodDogNjAwOwogICAgbWFyZ2luLWJvdHRvbTogNnB4OwogIH0KICBkZXRhaWxzLmluc2lnaHQtZGV0IHN1bW1hcnk6Oi13ZWJraXQtZGV0YWlscy1tYXJrZXIgeyBkaXNwbGF5Om5vbmU7IH0KPC9zdHlsZT4KCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn5SOIEludGVycHJldMOhY2lhIGJveHBsb3RvdjwvaDQ+CiAgPHA+CiAgWiB2ecWhxaFpZSB1dmVkZW7DvWNoIGJveHBsb3RvdiBqZSB6cmVqbcOpLCDFvmUgw7pkYWplIG8gPHN0cm9uZz5wb3B1bMOhY2lpPC9zdHJvbmc+IGEgPHN0cm9uZz5taWdyw6FjaWk8L3N0cm9uZz4gb2JzYWh1asO6IG5pZWtvxL5rbyBvZMS+YWhsw71jaCBob2Ruw7R0LCDEjW8gc8O6dmlzw60gcyByb3pkaWVsbm91IHZlxL5rb3PFpW91IGtyYWrDrW4gYSBpY2ggZWtvbm9taWNrw71tIHBvc3RhdmVuw61tLiAKICA8c3Ryb25nPlDDtHJvZG5vc8WlPC9zdHJvbmc+IGEgPHN0cm9uZz5tZWRpw6Fub3bDvSB2ZWs8L3N0cm9uZz4gdnlrYXp1asO6IHJlbGF0w612bmUgc3RhYmlsbmVqxaFpZSByb3pkZWxlbmllIGJleiBleHRyw6ltb3YuIAogIFRha8OpdG8gdml6dWFsaXrDoWNpZSBzw7ogZMO0bGXFvml0w6ksIHByZXRvxb5lIHVwb3pvcsWIdWrDuiBuYSBtb8W+bsOpIHpkcm9qZSB2YXJpYWJpbGl0eSwga3RvcsOpIG3DtMW+dSBvdnBseXZuacWlIHbDvXNsZWRreSByZWdyZXNuZWogYW5hbMO9enkuCiAgPC9wPgogIDxzcGFuIGNsYXNzPSJ0YWciPlBvcHVsYXRpb24gMjAyNTwvc3Bhbj4KICA8c3BhbiBjbGFzcz0idGFnIj5GZXJ0LiBSYXRlPC9zcGFuPgogIDxzcGFuIGNsYXNzPSJ0YWciPk1lZGlhbiBBZ2U8L3NwYW4+CiAgPHNwYW4gY2xhc3M9InRhZyI+TWlncmFudHMgKG5ldCk8L3NwYW4+CiAgIDxkaXYgY2xhc3M9Im11dGVkIj5UaXA6IG9kxL5haGzDqSBob2Rub3R5IHNpIHRyZWJhIHByZWQgcmVncmVzaW91IHNrb250cm9sb3ZhxaUgYWogcG9tb2NvdSBsb2ctdHJhbnNmb3Jtw6FjaWUgYWxlYm8gcm9idXN0bsO9Y2ggbWV0w7NkLjwvZGl2Pgo8L2Rpdj4KCgojIyBMaW5lw6FybmEgcmVncmVzaWEKCk1vZGVsIG9kaGFkdWplbWUgcHLDrWthem9tICpsbSgpKiwga3RvcsO9IHYgUiBzbMO6xb5pIG5hIHZ5dHbDoXJhbmllIGxpbmXDoXJueWNoIG1vZGVsb3YuIFYgbmHFoW9tIHByw61wYWRlIGNoY2VtZSB6aXN0acWlLCBha28gKiptaWVyYSBww7Ryb2Rub3N0aSAoRmVydF9SYXRlKSoqLCAqKm1lZGnDoW5vdsO9IHZlayAoTWVkaWFuX0FnZSkqKiBhICoqxI1pc3TDoSBtaWdyw6FjaWEgKE1pZ3JhbnRzX25ldCkqKiBvdnBseXbFiHVqw7ogKipwb8SNZXQgb2J5dmF0ZcS+b3YgdiByb2t1IDIwMjUgKFBvcHVsYXRpb25fMjAyNSkqKi4KCmBgYHtyfQojIE9kaGFkIGxpbmXDoXJuZWhvIG1vZGVsdQptb2RlbCA8LSBsbShQb3B1bGF0aW9uLjIwMjUgfiBGZXJ0Li5SYXRlICsgTWVkaWFuLkFnZSArIE1pZ3JhbnRzLi5uZXQuLCBkYXRhID0gZGF0YV9zZWxlY3RlZCkKCiMgVsO9cGlzIHbDvXNsZWRrb3YgcmVncmVzaWUKc3VtbWFyeShtb2RlbCkKCmBgYAo8ZGl2IGNsYXNzPSJpbnNpZ2h0IiBzdHlsZT0iYm9yZGVyLWxlZnQ6IDZweCBzb2xpZCAjMTk4NzU0OyI+CiAgPGg0PvCfk4ogSW50ZXJwcmV0w6FjaWEgdsO9c2xlZGtvdiByZWdyZXNpZTwvaDQ+CiAgPHA+CiAgVsO9c2xlZGt5IGxpbmXDoXJuZWhvIG1vZGVsdSB1a2F6dWrDuiwgxb5lIDxzdHJvbmc+bWlncsOhY2lhIChNaWdyYW50c19uZXQpPC9zdHJvbmc+IG3DoSA8c3Ryb25nPnbDvXpuYW1uw70gcG96aXTDrXZueSB2cGx5djwvc3Ryb25nPiBuYSB2ZcS+a29zxaUgcG9wdWzDoWNpZSB2IHJva3UgMjAyNS4gCiAgS3JhamlueSBzIHZ5xaHFoW91IMSNaXN0b3UgbWlncsOhY2lvdSBtYWrDuiB0ZW5kZW5jaXUgbWHFpSB2w6TEjcWhw60gcG/EjWV0IG9ieXZhdGXEvm92LiAKICBOYW9wYWssIHByZW1lbm7DqSA8c3Ryb25nPnDDtHJvZG5vc8WlIChGZXJ0X1JhdGUpPC9zdHJvbmc+IGEgPHN0cm9uZz5tZWRpw6Fub3bDvSB2ZWsgKE1lZGlhbl9BZ2UpPC9zdHJvbmc+IHNhIHYgbW9kZWxpIHVrw6F6YWxpIGFrbyDFoXRhdGlzdGlja3kgbmV2w716bmFtbsOpLCAKICBob2NpIG1hasO6IG/EjWFrw6F2YW7DqSB6bmFtaWVua2EgKHZ5xaHFocOtIHZlayB6bmnFvnVqZSByYXN0IHBvcHVsw6FjaWUsIHZ5xaHFoWlhIHDDtHJvZG5vc8WlIGJ5IGhvIG1hbGEgenZ5xaFvdmHFpSkuCiAgPC9wPgogIDxwPgogIDxzdHJvbmc+S29lZmljaWVudCBkZXRlcm1pbsOhY2llIFLCsiA9IDAuMTI8L3N0cm9uZz4gbmF6bmHEjXVqZSwgxb5lIG1vZGVsIHZ5c3ZldMS+dWplIHByaWJsacW+bmUgMTIgJSB2YXJpYWJpbGl0eSBwb3B1bMOhY2llIG1lZHppIGtyYWppbmFtaS4gCiAgSG9jaSBpZGUgbyByZWxhdMOtdm5lIG7DrXprdSBob2Rub3R1LCB2w71zbGVkb2sgamUgcHJlIG1ha3JvZWtvbm9taWNrw6kgYSBkZW1vZ3JhZmlja8OpIGTDoXRhIGJlxb5uw70uIAogIDxzdHJvbmc+Ri10ZXN0PC9zdHJvbmc+IChwLWhvZG5vdGEgMS45NWXigJMwNikgcG90dnJkenVqZSwgxb5lIG1vZGVsIGFrbyBjZWxvayBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvS4KICA8L3A+CiAgPGRpdiBjbGFzcz0ibXV0ZWQiPlRpcDogQWsgY2hjZW1lIHp2w73FoWnFpSB2eXN2ZXTEvm92YWNpdSBzaWx1IG1vZGVsdSwgbcO0xb5lbWUgcHJpZGHFpSBwcmVtZW5uw6kgYWtvIGh1c3RvdHUgb2J5dmF0ZcS+c3R2YSwgdXJiYW5pesOhY2l1IMSNaSBIRFAgbmEgb2J5dmF0ZcS+YS48L2Rpdj4KPC9kaXY+CgojIyBWw71zdHVweSB6IG9iamVrdHUgYGxtKClgCk9iamVrdCB0cmllZHkgKmxtKCkqIG7DoW0gcG9za3l0dWplIG5pZWtvxL5rbyBkw7RsZcW+aXTDvWNoIHbDvXN0dXBvdjoKCjEuICoqVmVrdG9yIG9kaGFkbnV0w71jaCBrb2VmaWNpZW50b3YqKiDigJMgKm1vZGVsJGNvZWZmaWNpZW50cyogIAoyLiAqKlZla3RvciByZXrDrWR1w60gKGNow71iIG9kaGFkdSkqKiDigJMgKm1vZGVsJHJlc2lkdWFscyogIAozLiAqKlZla3RvciB2eXJvdm5hbsO9Y2ggaG9kbsO0dCB2eXN2ZXTEvm92YW5laiB2ZWxpxI1pbnkqKiDigJMgKm1vZGVsJGZpdHRlZC52YWx1ZXMqICAKNC4gKipNYXRpY3UgdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCoqIOKAkyAqbW9kZWwkbW9kZWwqIGFsZWJvICptb2RlbC5tYXRyaXgobW9kZWwpKiAgCgpgYGB7cn0KIyBWw71waXMgesOha2xhZG7DvWNoIGtvbXBvbmVudG92IG9iamVrdHUgIm1vZGVsIgoKY2F0KCIx77iP4oOjICBPZGhhZG51dMOpIGtvZWZpY2llbnR5OlxuIikKcHJpbnQobW9kZWwkY29lZmZpY2llbnRzKQoKY2F0KCJcbjLvuI/ig6MgIFBydsO9Y2ggMTAgaG9kbsO0dCByZXrDrWR1w606XG4iKQpwcmludChoZWFkKG1vZGVsJHJlc2lkdWFscywgMTApKQoKY2F0KCJcbjPvuI/ig6MgIFBydsO9Y2ggMTAgdnlyb3ZuYW7DvWNoIGhvZG7DtHQgdnlzdmV0xL5vdmFuZWogcHJlbWVubmVqOlxuIikKcHJpbnQoaGVhZChtb2RlbCRmaXR0ZWQudmFsdWVzLCAxMCkpCgpjYXQoIlxuNO+4j+KDoyAgTsOhaMS+YWQgbmEgbWF0aWN1IFggKG1vZGVsLm1hdHJpeCk6XG4iKQpwcmludChoZWFkKG1vZGVsLm1hdHJpeChtb2RlbCkpKQoKYGBgCjxkaXYgY2xhc3M9Imluc2lnaHQiIHN0eWxlPSJib3JkZXItbGVmdDogNnB4IHNvbGlkICMyMGM5OTc7Ij4KICA8aDQ+8J+nqSBJbnRlcnByZXTDoWNpYSB2w71zdHVwb3Ygb2JqZWt0dSA8Y29kZT5sbSgpPC9jb2RlPjwvaDQ+CiAgPHA+CiAgVsO9cGlzIHZ5xaHFoWllIHVrYXp1amUsIGFrw6kgesOha2xhZG7DqSBrb21wb25lbnR5IG9ic2FodWplIG9iamVrdCB0cmllZHkgPHN0cm9uZz5sbTwvc3Ryb25nPiBwbyBvZGhhZGUgbGluZcOhcm5laG8gbW9kZWx1LiAKICBQb21vY291IHTDvWNodG8gcHJ2a292IGplIG1vxb5uw6kgesOtc2thxaUgcG9kcm9ibmVqxaFpZSBpbmZvcm3DoWNpZSBvIHRvbSwgPHN0cm9uZz5ha28gbW9kZWwgZnVuZ3VqZSBhIGtkZSByb2LDrSBjaHlieTwvc3Ryb25nPi4KICA8L3A+CiAgPHVsPgogICAgPGxpPjxzdHJvbmc+T2RoYWRudXTDqSBrb2VmaWNpZW50eTwvc3Ryb25nPiDigJMgdXLEjXVqw7ogc21lciBhIHNpbHUgdnBseXZ1IGplZG5vdGxpdsO9Y2ggdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCBuYSB2eXN2ZXTEvm92YW7DuiB2ZWxpxI1pbnUuPC9saT4KICAgIDxsaT48c3Ryb25nPlJlemlkdcOhPC9zdHJvbmc+IOKAkyB2eWphZHJ1asO6IHJvemRpZWwgbWVkemkgc2t1dG/EjW7DvW1pIGEgcHJlZHBvdmVkYW7DvW1pIGhvZG5vdGFtaS4gUG9tw6FoYWrDuiBvZGhhbGnFpSwga2RlIG1vZGVsIHBvZGhvZG5vY3VqZSBhbGVibyBuYWRob2Rub2N1amUgcG9wdWzDoWNpdS48L2xpPgogICAgPGxpPjxzdHJvbmc+Vnlyb3ZuYW7DqSBob2Rub3R5PC9zdHJvbmc+IOKAkyBwcmVkc3RhdnVqw7ogcHJlZGlrb3ZhbsOpIGhvZG5vdHkgcG9wdWzDoWNpZSwga3RvcsOpIG1vZGVsIG9kaGFkdWplIHByZSBrYcW+ZMO6IGtyYWppbnUuPC9saT4KICAgIDxsaT48c3Ryb25nPk1hdGljYSBYPC9zdHJvbmc+IOKAkyBvYnNhaHVqZSB2xaFldGt5IHByZW1lbm7DqSwga3RvcsOpIHZzdHVwdWrDuiBkbyBtb2RlbHUuIEplIHrDoWtsYWRvbSBwcmUgdsO9cG/EjXR5IGtvZWZpY2llbnRvdiBhIHRlc3Rvdi48L2xpPgogIDwvdWw+CiAgPGRpdiBjbGFzcz0ibXV0ZWQiPgogICAgVGlwOiBUaWV0byBrb21wb25lbnR5IHPDuiBrxL7DusSNb3bDqSBwcmUgZGlhZ25vc3Rpa3UgbW9kZWx1IOKAkyBuYXByw61rbGFkIHByaSBhbmFsw716ZSBub3JtYWxpdHkgcmV6w61kdcOtLCBoxL5hZGFuaWEgb2TEvmFobMO9Y2ggYm9kb3YgYWxlYm8gdGVzdG92YW5pYSBtdWx0aWtvbGluZWFyaXR5LgogIDwvZGl2Pgo8L2Rpdj4KCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn5OKIERpYWdub3N0aWNrw6kgZ3JhZnkgcmVncmVzbsOpaG8gbW9kZWx1PC9oND4KICBTw7pocm4gb2RoYWRvdmFuw6lobyBtb2RlbHUgbsOhbSBwb3NreXR1amUgc8O6Ym9yIHJlZ3Jlc27DvWNoIGtvZWZpY2llbnRvdiwga3RvcsO9Y2ggem5hbWllbmthIGJ1ZMO6IHJvem9iZXJhbsOpIG5lc2vDtHIuIAogIEFrIHNhIHphbWVyaWFtZSBuYSA8c3Ryb25nPnZsYXN0bm9zdGkgbW9kZWx1IGFrbyBjZWxrdTwvc3Ryb25nPiwgbcO0xb5lbWUgaWNoIG92ZXJpxaUgcG9tb2NvdSDFoXR5cm9jaCBkaWFnbm9zdGlja8O9Y2ggZ3JhZm92LgogIE5hIHrDoWtsYWRlIDxzdHJvbmc+UeKAk1EgZ3JhZnU8L3N0cm9uZz4gcG9zdWR6dWplbWUgbm9ybWFsaXR1IHJlesOtZHXDrSwgCiAgZ3JhZiA8c3Ryb25nPnJlesOtZHXDrSB2b8SNaSBwcmVkaWtvdmFuw71tIGhvZG5vdMOhbTwvc3Ryb25nPiB1a2F6dWplIGhvbW9nZW5pdHUgcm96cHR5bHUgCiAgYSBncmFmIDxzdHJvbmc+cMOha292w71jaCBob2Ruw7R0PC9zdHJvbmc+IHVtb8W+xYh1amUgaWRlbnRpZmlrb3ZhxaUgdnBseXZuw6kgcG96b3JvdmFuaWEuCjwvZGl2PiAKClPDumhybiBvZGhhZG92YW7DqWhvIG1vZGVsdSBuw6FtIHBvc2t5dHVqZSBzw7pib3Igb2RoYWRvdmFuw71jaCByZWdyZXNuw71jaCBrb2VmaWNpZW50b3YsIGt0b3LDvWNoIHpuYW1pZW5rYSBidWTDuiByb3pvYmVyYW7DqSBuZXNrw7RyLiBBayBob3ZvcsOtbWUgbyB2bGFzdG5vc3RpYWNoIG1vZGVsdSBha28gY2Vsa3UsIHBvenJpbWUgc2EgbmFqc2vDtHIgbmEgbmFzbGVkdWrDumNlIG9icsOhemt5LiBOYSB6w6FrbGFkZSBRLVEgZ3JhZnUgesOtc2thdmFtZSBkb2plbSBvIG1vxb5uw71jaCBwcm9ibMOpbW9jaCBwb3J1xaFlbmlhIG5vcm1hbGl0eSByZXrDrWR1w60uIAoKCmBgYHtyIGRpYWdwbG90cywgZmlnLmNhcD0iRGlhZ25vc3RpY2vDqSBncmFmeSByZWdyZXNuw6lobyBtb2RlbHUiLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04LCBlY2hvPUZBTFNFfQojIE5hc3RhdmnFpSByb3psb8W+ZW5pZSAyeDIKcGFyKG1mcm93ID0gYygyLCAyKSkKCiMgVnlrcmVzbGnFpSB2xaFldGt5IGRpYWdub3N0aWNrw6kgZ3JhZnkgbW9kZWx1CnBsb3QobW9kZWwpCgojIFJlc2V0b3ZhxaUgbGF5b3V0CnBhcihtZnJvdyA9IGMoMSwgMSkpCmBgYAoKIyMgUmVzaWR1YWxzIHZzLiBmaXR0ZWQKIyMjIEludGVycHJldMOhY2lhIG3DtGpobyBrb25rcsOpdG5laG8gZ3JhZnUKPGRpdiBjbGFzcz0iaW5zaWdodCI+CiAgPGg0PvCflI0gUG9kcm9ibsOhIGludGVycHJldMOhY2lhIGdyYWZ1IDxlbT5SZXNpZHVhbHMgdnMgRml0dGVkPC9lbT48L2g0PgogIDx1bD4KICAgIDxsaT48c3Ryb25nPkNlbnRyb3ZhbmllIG9rb2xvIG51bHk6PC9zdHJvbmc+IFJlemlkdcOhIGtvbMOtxaF1IHByaWJsacW+bmUgb2tvbG8gMCDigJMgdG8gamUgZG9icsOpIHpuYW1lbmllLCBtb2RlbCBuZW3DoSB2w71yYXpuw6kgc3lzdGVtYXRpY2vDqSBza3Jlc2xlbmllIHYgcHJlZGlrY2nDoWNoLjwvbGk+CiAgICA8bGk+PHN0cm9uZz5UdmFyIGhsYWRrZWogxI1pYXJ5Ojwvc3Ryb25nPiBNaWVybmUgemFrcml2ZW5pZSDEjWVydmVuZWogxI1pYXJ5IG5hem5hxI11amUgbW/Fvm7DuiBtaWVybnUgbmVsaW5lYXJpdHUg4oCTIG1vZGVsdSBtw7TFvmUgY2jDvWJhxaUgbmVsaW5lw6FybnkgxI1sZW4uPC9saT4KICAgIDxsaT48c3Ryb25nPlJvenB0eWwgcmV6w61kdcOtOjwvc3Ryb25nPiBWZXJ0aWvDoWxueSByb3pwdHlsIHNhIGphdsOtIGFrbyBwcmlibGnFvm5lIGtvbsWhdGFudG7DvSwgxI1vIGplIGTDtGtheiBob21vc2tlZGFzdGljaXR5LjwvbGk+CiAgICA8bGk+PHN0cm9uZz5PZMS+YWhsw6kgaG9kbm90eTo8L3N0cm9uZz4gTmlla2/EvmtvIGJvZG92IGxlxb7DrSB2w71yYXpuZSBtaW1vIGhsYXZuw6lobyB6aGx1a3Ug4oCTIGlkZSBvIHBvdGVuY2nDoWxuZSB2cGx5dm7DqSBrcmFqaW55IChtb8W+bm8gSW5kaWEsIMSMw61uYS4uLikuPC9saT4KICA8L3VsPgo8L2Rpdj4KCjxkaXYgY2xhc3M9Im11dGVkIj4KICDwn5KhIDxlbT5Qb3puw6Fta2E6PC9lbT4gT2TEvmFobMOpIHBvem9yb3ZhbmlhIGplIG1vxb5uw6kgcHJlc2vDum1hxaUgcG9tb2NvdSA8Y29kZT5vdXRsaWVyVGVzdChtb2RlbCk8L2NvZGU+IHogYmFsw61rYSA8Y29kZT5jYXI8L2NvZGU+Lgo8L2Rpdj4KCiMjIFEtUSBwbG90CiMjIyDEjG8gdWthenVqZQo8ZGl2IGNsYXNzPSJpbnNpZ2h0Ij4KICA8aDQ+8J+TiCBR4oCTUSBncmFmIHJlesOtZHXDrTwvaDQ+CiAgVGVudG8gZ3JhZiBwb3Jvdm7DoXZhIDxzdHJvbmc+xaF0YW5kYXJkaXpvdmFuw6kgcmV6aWR1w6E8L3N0cm9uZz4gcyB0ZW9yZXRpY2vDvW0gbm9ybcOhbG55bSByb3pkZWxlbsOtbS4KICBBayBtb2RlbCBzcMS6xYhhIHByZWRwb2tsYWQgbm9ybWFsaXR5LCBib2R5IGJ5IG1hbGkgbGXFvmHFpSBwcmlibGnFvm5lIG5hIHByaWFta2UuCiAgPHVsPgogICAgPGxpPlYgbmHFoW9tIHByw61wYWRlIHNhIGJvZHkgdiBzdHJlZG5laiDEjWFzdGkgZHLFvmlhIHByaWFta3ksIG5vIHYgb2JvY2gga29uY29jaCBvZCBuZWogb2RjaMO9xL51asO6LjwvbGk+CiAgICA8bGk+VG8gbmF6bmHEjXVqZSwgxb5lIDxlbT5yZXppZHXDoSBuaWUgc8O6IGRva29uYWxlIG5vcm3DoWxuZSByb3pkZWxlbsOpPC9lbT4g4oCTIHByYXZkZXBvZG9ibmUga3bDtGxpIG9kxL5haGzDvW0ga3Jhamluw6FtIHMgZXh0csOpbW5lIHZ5c29rb3UgYWxlYm8gbsOtemtvdSBwb3B1bMOhY2lvdS48L2xpPgogICAgPGxpPk1pZXJuZSBwb3J1xaFlbmllIG5vcm1hbGl0eSB2xaFhayBuZXByZWRzdGF2dWplIHbDocW+bnkgcHJvYmzDqW0gcHJlIG9kaGFkeSBrb2VmaWNpZW50b3YsIGFsZSBtw7TFvmUgb3ZwbHl2bmnFpSDFoXRhdGlzdGlja8O6IHbDvXpuYW1ub3PFpSAocC1ob2Rub3R5KS48L2xpPgogIDwvdWw+CjwvZGl2PgoKPGRpdiBjbGFzcz0ibXV0ZWQiPgogIPCfkqEgPGVtPk9kcG9yw7rEjWFuaWU6PC9lbT4gQWsgYnkgc21lIGNoY2VsaSB6dsO9xaFpxaUgcHJlc25vc8WlIG1vZGVsdSwgbcO0xb5lbWUgc2vDunNpxaUgPHN0cm9uZz5sb2ctdHJhbnNmb3Jtw6FjaXU8L3N0cm9uZz4gesOhdmlzbGVqIHByZW1lbm5laiAobmFwci4gbG9nKFBvcHVsYXRpb24uMjAyNSkpLgo8L2Rpdj4KIyMjIEludGVycHJldMOhY2lhIG3DtGpobyBrb25rcsOpdG5laG8gZ3JhZnUKPGRpdiBjbGFzcz0iaW5zaWdodCI+CiAgPGg0PvCfk4ogSW50ZXJwcmV0w6FjaWEgUeKAk1EgZ3JhZnUgcmV6w61kdcOtPC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5DZWxrb3bDvSB0dmFyOjwvc3Ryb25nPiBWw6TEjcWhaW5hIGJvZG92IGxlxb7DrSA8ZW0+YmzDrXprbyBwcmlhbWt5PC9lbT4sIMSNbyBuYXpuYcSNdWplLCDFvmUgcmV6aWR1w6Egc8O6IHByaWJsacW+bmUgbm9ybcOhbG5lIHJvemRlbGVuw6kuPC9saT4KICAgIDxsaT48c3Ryb25nPlRvIGplIGRvYnLDqTo8L3N0cm9uZz4gUHJlZHBva2xhZCBub3JtYWxpdHkgc2EgemTDoSBiecWlIHZvIHZlxL5rZWogbWllcmUgc3BsbmVuw70uPC9saT4KICAgIDxsaT48c3Ryb25nPktyYWpuw6kgaG9kbm90eSAoZXh0csOpbXkpOjwvc3Ryb25nPiBCb2R5IG5hIG9ib2NoIGtvbmNvY2ggKHbEvmF2byBkb2xlIGEgdnByYXZvIGhvcmUpIHNhIG1pZXJuZSBvZGNoecS+dWrDuiBvZCBwcmlhbWt5LiBUbyBuYXpuYcSNdWplIG1pZXJudSBuZW5vcm3DoWxub3PFpSB2IGtvbmNvY2gg4oCTIG5pZWtvxL5rbyBvZMS+YWhsw71jaCBob2Ruw7R0IGFsZWJvIMWlYcW+xaFpZSBrb25jZSAodHJvY2h1IMWhcGljYXRvc8WlKS48L2xpPgogICAgPGxpPjxzdHJvbmc+U3RyZWRuw6Egb2JsYXPFpTo8L3N0cm9uZz4gU3RyZWRuw6EgxI1hc8WlIGdyYWZ1ICjiiJIxIGHFviArMSBrdmFudGlseSkgc2EgdmXEvm1pIGRvYnJlIHpob2R1amUgcyBwcmlhbWtvdSwgxI1vIHpuYW1lbsOhLCDFvmUgdsOkxI3FoWluYSByZXrDrWR1w60gemFwYWTDoSBkbyBub3Jtw6FsbmVobyByb3pkZWxlbmlhLjwvbGk+CiAgPC91bD4KICA8cD7inIUgWsOhdmVyOiBQcmVkcG9rbGFkIG5vcm1hbGl0eSBqZSA8c3Ryb25nPnByaWJsacW+bmUgc3BsbmVuw708L3N0cm9uZz4sIGhvY2kgc2Egdnlza3l0dWrDuiBkcm9ibsOpIG9kY2jDvWxreSB2IGV4dHLDqW1vY2guIE1vZGVsIHRlZGEgbmVwb3J1xaF1amUgdMO6dG8gcG9kbWllbmt1IHbDvXJhem5lLjwvcD4KPC9kaXY+Cgo8ZGl2IGNsYXNzPSJtdXRlZCI+CiAg8J+SoSA8ZW0+UG96bsOhbWthOjwvZW0+IFByaSBtYWtyb2Vrb25vbWlja8O9Y2ggYSBwb3B1bGHEjW7DvWNoIGTDoXRhY2ggamUgbWllcm5hIG9kY2jDvWxrYSBvZCBub3JtYWxpdHkgYmXFvm7DoSBhIG5lb2hyb3p1amUgcGxhdG5vc8WlIHbDvXNsZWRrb3YuCjwvZGl2PgoKCiMjIFNjYWxlIGxvY2F0aW9uIHBsb3QKIyMjIMSMbyB0byB6bsOhem9yxYh1amUKPGRpdiBjbGFzcz0iaW5zaWdodCI+CiAgPGg0PvCfk4ogSW50ZXJwcmV0w6FjaWEgU2NhbGXigJNMb2NhdGlvbiBncmFmdTwvaDQ+CiAgVGVudG8gZ3JhZiB6b2JyYXp1amUsIMSNaSBtw6EgbW9kZWwgPHN0cm9uZz5rb27FoXRhbnRuw70gcm96cHR5bCByZXrDrWR1w608L3N0cm9uZz4gKHByZWRwb2tsYWQgaG9tb3NrZWRhc3RpY2l0eSkuCiAgQWsgamUgdGVudG8gcHJlZHBva2xhZCBzcGxuZW7DvSwgYm9keSBieSBtYWxpIGJ5xaUgPGVtPnJvdm5vbWVybmUgcm96cHTDvWxlbsOpPC9lbT4gb2tvbG8gxI1lcnZlbmVqIHRyZW5kb3ZlaiDEjWlhcnkgYmV6IHpyZXRlxL5uw6lobyB0dmFydS4KICA8dWw+CiAgICA8bGk+ViBuYcWhb20gcHLDrXBhZGUgYm9keSBuZXZ5a2F6dWrDuiBqYXNuw70gdnpvciDigJMgcm96cHR5bCByZXrDrWR1w60gamUgcG9tZXJuZSByb3Zub21lcm7DvSBuYXByaWXEjSBob2Rub3RhbWkgZml0dGVkIHZhbHVlcy48L2xpPgogICAgPGxpPsSMZXJ2ZW7DoSBMT0VTUyDEjWlhcmEgamUgcmVsYXTDrXZuZSA8ZW0+dm9kb3Jvdm7DoTwvZW0+LCDEjW8gcG9kcG9ydWplIHByZWRwb2tsYWQgbyBwcmlibGnFvm5lIHJvdm5ha29tIHJvenB0eWxlIHJlesOtZHXDrS48L2xpPgogICAgPGxpPkxlbiBuaWVrb8S+a28gYm9kb3Ygc2Egb2RjaHnEvnVqZSB2aWFjIOKAkyBtw7TFvnUgcHJlZHN0YXZvdmHFpSBrcmFqaW55IHMgZXh0csOpbW5vdSBwb3B1bMOhY2lvdSBhbGVibyBtaWdyw6FjaW91LjwvbGk+CiAgPC91bD4KICA8cD7inIUgPHN0cm9uZz5aw6F2ZXI6PC9zdHJvbmc+IFByZWRwb2tsYWQgaG9tb3NrZWRhc3RpY2l0eSBqZSB2byB2xaFlb2JlY25vc3RpIHNwbG5lbsO9LiBNb2RlbCB0ZWRhIG5lbcOhIHbDocW+bnkgcHJvYmzDqW0gcyBuZXJvdm5ha8O9bSByb3pwdHlsb20gY2jDvWIuPC9wPgo8L2Rpdj4KCjxkaXYgY2xhc3M9Im11dGVkIj4KICDwn5KhIDxlbT5Qb3puw6Fta2E6PC9lbT4gQWsgYnkgc2Egb2JqYXZpbCBsaWV2aWtvdml0w70gdHZhciBib2RvdiAocm96cHR5bCBieSBzYSB6dnnFoW92YWwgcyBob2Rub3RvdSBmaXR0ZWQgdmFsdWVzKSwgbmF6bmHEjW92YWxvIGJ5IHRvIHByb2Jsw6ltIGhldGVyb3NrZWRhc3RpY2l0eSDigJMgdnRlZHkgbW/Fvm5vIHBvdcW+acWlIHJvYnVzdG7DqSBvZGhhZHkgKGZ1bmtjaWUgeiBiYWzDrWthIDxjb2RlPnNhbmR3aWNoPC9jb2RlPikuCjwvZGl2PgojIyMgSW50ZXJwcmV0w6FjaWEgbcO0amhvIGtvbmtyw6l0bmVobyBncmFmdQo8ZGl2IGNsYXNzPSJpbnNpZ2h0Ij4KICA8aDQ+8J+TiSBJbnRlcnByZXTDoWNpYSBTY2FsZeKAk0xvY2F0aW9uIGdyYWZ1PC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5Ib3Jpem9udMOhbG5lIHJvenB0w71sZW5pZTo8L3N0cm9uZz4gQm9keSBzw7ogcm92bm9tZXJuZSByb3ptaWVzdG5lbsOpIHBvIG9zaSBYIGJleiB2eXR2w6FyYW5pYSBsaWV2aWthIGFsZWJvIHbDvXJhem5laiBrcml2a3kuIFRvIG5hem5hxI11amUsIMW+ZSByb3pwdHlsIHJlesOtZHXDrSBqZSBwcmlibGnFvm5lIGtvbsWhdGFudG7DvSDigJMgdGVkYSByZXrDrWR1w6Egc8O6IDxlbT5ob21vc2tlZGFzdGlja8OpPC9lbT4uPC9saT4KICAgIDxsaT48c3Ryb25nPlRyZW5kb3bDoSDEjWlhcmE6PC9zdHJvbmc+IMSMZXJ2ZW7DoSBobGFka8OhIExPRVNTIMSNaWFyYSBqZSB0YWttZXIgdm9kb3Jvdm7DoSwgxI1vIHBvdHZyZHp1amUsIMW+ZSBzbyB6dnnFoXVqw7pjaW1pIHNhIHZ5cm92bmFuw71taSBob2Rub3RhbWkgbmVkb2Now6FkemEgayBzeXN0ZW1hdGlja2VqIHptZW5lIHJvenB0eWx1LjwvbGk+CiAgICA8bGk+PHN0cm9uZz5PZMS+YWhsw6kgYm9keTo8L3N0cm9uZz4gTmlla2/EvmtvIHBvem9yb3ZhbsOtIGplIG1pZXJuZSBuYWQgw7pyb3bFiG91IDEsNSwgbm8gxb5pYWRuZSB6IG5pY2ggbmVwcmVkc3RhdnVqZSBleHRyw6ltIOKAkyBuZXZ6bmlrYWrDuiB0ZWRhIHbDocW+bmUgYW5vbcOhbGllIHZvIHZhcmlhbmNpaS48L2xpPgogIDwvdWw+CiAgPHA+4pyFIDxzdHJvbmc+WsOhdmVyOjwvc3Ryb25nPiBNb2RlbCBzcMS6xYhhIHByZWRwb2tsYWQgPGVtPmtvbsWhdGFudG7DqWhvIHJvenB0eWx1IHJlesOtZHXDrTwvZW0+LCDEjW8gcG9kcG9ydWplIHNwb8S+YWhsaXZvc8WlIHJlZ3Jlc27DvWNoIG9kaGFkb3YuPC9wPgo8L2Rpdj4KCjxkaXYgY2xhc3M9Im11dGVkIj4KICDwn5KhIDxlbT5Qb3puw6Fta2E6PC9lbT4gQWsgYnkgYm9keSB2eXR2w6FyYWxpIGxpZXZpa292aXTDvSB0dmFyICh6dsOkxI3FoXVqw7pjaSBzYSByb3pwdHlsKSwgem5hbWVuYWxvIGJ5IHRvIHByb2Jsw6ltIGhldGVyb3NrZWRhc3RpY2l0eSDigJMgdiB0YWtvbSBwcsOtcGFkZSBieSBwb21vaG9sIHJvYnVzdG7DvSBvZGhhZCBhbGVibyB0cmFuc2Zvcm3DoWNpYSBkw6F0Lgo8L2Rpdj4KCiMjIHJlc2lkdWFscyB2cyBsZXZlcmFnZQojIyMgxIxvIHpuw6F6b3LFiHVqZSBncmFmCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn5OKIEludGVycHJldMOhY2lhIGdyYWZ1IFJlc2lkdWFscyB2cyBMZXZlcmFnZTwvaDQ+CiAgVGVudG8gZ3JhZiBwb23DoWhhIGlkZW50aWZpa292YcWlIDxzdHJvbmc+dnBseXZuw6kgcG96b3JvdmFuaWE8L3N0cm9uZz4sIGt0b3LDqSBtw7TFvnUgbWHFpSBuZXByaW1lcmFuw70gdnBseXYgbmEgdsO9c2xlZGt5IHJlZ3Jlc2llLgogIDx1bD4KICAgIDxsaT48c3Ryb25nPlbDpMSNxaFpbmEgYm9kb3Y8L3N0cm9uZz4gc2EgbmFjaMOhZHphIHYgYmzDrXprb3N0aSBzdHJlZHUgZ3JhZnUsIMSNbyB6bmFtZW7DoSwgxb5lIMW+aWFkbmUgcG96b3JvdmFuaWEgdsO9cmF6bmUgbmVvdnBseXbFiHVqw7ogbW9kZWwuPC9saT4KICAgIDxsaT48c3Ryb25nPsSMZXJ2ZW7DoSBMT0VTUyDEjWlhcmE8L3N0cm9uZz4gamUgcmVsYXTDrXZuZSB2b2Rvcm92bsOhIOKAkyBuZW5hem5hxI11amUgc3lzdGVtYXRpY2vDqSBza3Jlc2xlbmllIG1vZGVsdS48L2xpPgogICAgPGxpPjxzdHJvbmc+Q29va292ZSB2emRpYWxlbm9zdGk8L3N0cm9uZz4gKGJvZGtvdmFuw6kga3Jpdmt5KSB1a2F6dWrDuiwgxb5lIMW+aWFkbnkgYm9kIG5lcHJlc2FodWplIGhyYW5pY3UgMC41IGFuaSAxIOKAkyB0ZWRhIHYgbW9kZWxpIHNhIG5lbmFjaMOhZHphasO6IGV4dHLDqW1uZSB2cGx5dm7DqSBwb3pvcm92YW5pYS48L2xpPgogIDwvdWw+CiAgPHA+4pyFIDxzdHJvbmc+WsOhdmVyOjwvc3Ryb25nPiBNb2RlbCBqZSBzdGFiaWxuw70gYSBuZW9ic2FodWplIHBvem9yb3ZhbmlhLCBrdG9yw6kgYnkgbWFsaSB2w71yYXpuw70gdnBseXYgbmEgcmVncmVzbsO6IHByaWFta3UuPC9wPgo8L2Rpdj4KCjxkaXYgY2xhc3M9Im11dGVkIj4KICDwn5KhIDxlbT5Qb3puw6Fta2E6PC9lbT4gQWsgYnkgc2Egbmlla3RvcsOpIGJvZHkgbmFjaMOhZHphbGkgbWltbyBib2Rrb3ZhbsO9Y2gga3JpdmllayAoQ29va292YSB2emRpYWxlbm9zxaUgJmd0OyAxKSwgYm9sbyBieSB2aG9kbsOpIGljaCBwcmVza8O6bWHFpSBwb21vY291IDxjb2RlPmluZmx1ZW5jZS5tZWFzdXJlcyhtb2RlbCk8L2NvZGU+IGFsZWJvIDxjb2RlPm91dGxpZXJUZXN0KCk8L2NvZGU+IHogYmFsw61rYSA8Y29kZT5jYXI8L2NvZGU+Lgo8L2Rpdj4KIyMjIEludGVycHJldMOhY2lhIG3DtGpobyBrb25rcsOpdG5laG8gZ3JhZnUKPGRpdiBjbGFzcz0iaW5zaWdodCI+CiAgPGg0PvCfjq8gSW50ZXJwcmV0w6FjaWEgZ3JhZnUgUmVzaWR1YWxzIHZzIExldmVyYWdlPC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5Sb3psb8W+ZW5pZSB2cGx5dnU6PC9zdHJvbmc+IFbDpMSNxaFpbmEgcG96b3JvdmFuw60gbcOhIG7DrXpreSB2cGx5diAoQ29va292YSB2emRpYWxlbm9zxaUgJmx0OyAwLjA1KSwgxI1vIGplIHR5cGlja8OpIHByZSBkb2JyZSB2eXbDocW+ZW7DqSBkw6F0YS48L2xpPgogICAgPGxpPjxzdHJvbmc+VsO9bmltb8SNbsOpIGJvZHk6PC9zdHJvbmc+IEplZGVuIGFsZWJvIGR2YSBib2R5IChva29sbyBob2Rub3R5IDAuMikgbWllcm5lIHZ5xI1uaWV2YWrDuiDigJMgaWRlIG8gcG96b3JvdmFuaWEgcyB2ecWhxaFvdSBww6Frb3UsIHRlZGEgaWNoIGhvZG5vdHkgc8O6IMSPYWxlaiBvZCBwcmllbWVydSBwcmVkaWt0b3Jvdi48L2xpPgogICAgPGxpPjxzdHJvbmc+VmXEvmtvc8WlIHJlesOtZHXDrTo8L3N0cm9uZz4gVsOkxI3FoWluYSDFoXRhbmRhcmRpem92YW7DvWNoIHJlesOtZHXDrSBsZcW+w60gbWVkemkgLTIgYSArMiwgxI1vIGplIGlkZcOhbG5lIOKAkyBuZW5hem5hxI11amUgcHLDrXRvbW5vc8WlIGV4dHLDqW1ueWNoIGNow71iLjwvbGk+CiAgICA8bGk+PHN0cm9uZz5Db29rb3ZlIHZ6ZGlhbGVub3N0aTo8L3N0cm9uZz4gxb1pYWRueSBib2QgamFzbmUgbmVwcmVrcmHEjXVqZSB2b25rYWrFoWllIGzDrW5pZSAo4omIIDAuNSBhbGVibyAxLjApLCBwcmV0byBzYSBuZXpkw6EsIMW+ZSBieSBuaWVrdG9yw6kgcG96b3JvdmFuaWUgbmVwcmltZXJhbmUgb3ZwbHl2xYhvdmFsbyByZWdyZXNuw6kga29lZmljaWVudHkuPC9saT4KICA8L3VsPgogIDxwPuKchSA8c3Ryb25nPlrDoXZlcjo8L3N0cm9uZz4gTW9kZWwgbmVvYnNhaHVqZSB2w71yYXpuZSB2cGx5dm7DqSBwb3pvcm92YW5pYSDigJMgcmVncmVzbsOpIG9kaGFkeSBzw7ogdGVkYSBzdGFiaWxuw6kgYSBzcG/EvmFobGl2w6kuPC9wPgo8L2Rpdj4KCjxkaXYgY2xhc3M9Im11dGVkIj4KICDwn5KhIDxlbT5Qb3puw6Fta2E6PC9lbT4gQWsgYnkgbmlla3RvcsOpIGJvZHkgcHJla3JvxI1pbGkgaG9kbm90dSBDb29rb3ZlaiB2emRpYWxlbm9zdGkgJmd0OyAxLCBib2xvIGJ5IHZob2Ruw6kgcHJlc2vDum1hxaUgaWNoIHBvbW9jb3UgPGNvZGU+aW5mbHVlbmNlLm1lYXN1cmVzKG1vZGVsKTwvY29kZT4gYWxlYm8gPGNvZGU+b3V0bGllclRlc3QobW9kZWwpPC9jb2RlPiAoYmFsw61rIDxjb2RlPmNhcjwvY29kZT4pLgo8L2Rpdj4KCmBgYHtyfQptb2RlbDIgPC0gbG0oUG9wdWxhdGlvbi4yMDI1IH4gSShsb2coRmVydC4uUmF0ZSkpICsgTWVkaWFuLkFnZSArIE1pZ3JhbnRzLi5uZXQuLAogICAgICAgICAgICAgZGF0YSA9IGRhdGFfc2VsZWN0ZWQpCnN1bW1hcnkobW9kZWwyKQoKYGBgCgoKYGBge3IgdGVzdHMyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKIyBQb3RyZWJuw6kgYmFsw61reQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMoewogIGxpYnJhcnkodHNlcmllcykgICMgamFycXVlLmJlcmEudGVzdAogIGxpYnJhcnkoY2FyKSAgICAgICMgb3V0bGllclRlc3QKfSkKCiMgQWsgbW9kZWwyIGXFoXRlIG5pZSBqZSB2eXR2b3JlbsO9LCB1cm9iIGhvIHogZGF0YV9zZWxlY3RlZAppZiAoIWV4aXN0cygibW9kZWwyIikpIHsKICBzdG9wKCJtb2RlbDIgemF0aWHEviBuZWV4aXN0dWplLiBTcHVzxaUgbmFqcHJ2IGNodW5rLCBrZGUgc2Egdnl0dsOhcmEgbW9kZWwyLiIpCn0KCiMgMSkgTm9ybWFsaXRhIHJlesOtZHXDrSAoSmFycXVl4oCTQmVyYSkKcmVzMiAgICA8LSByZXNpZHVhbHMobW9kZWwyKQpqYl90ZXN0IDwtIGphcnF1ZS5iZXJhLnRlc3QocmVzMikKamJfdGVzdAoKIyAyKSBPdXRsaWVyeSAoQm9uZmVycm9uaSBrb3JpZ292YW7DvSB0ZXN0KQpvdXRsaWVyX3Rlc3QgPC0gb3V0bGllclRlc3QobW9kZWwyKQpvdXRsaWVyX3Rlc3QKCmBgYAo8ZGl2IGNsYXNzPSJpbnNpZ2h0Ij4KICA8aDQ+8J+nqiBUZXN0eSBwcmVkcG9rbGFkb3Yg4oCTIGludGVycHJldMOhY2lhPC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5KYXJxdWXigJNCZXJhOjwvc3Ryb25nPiBhayBqZSBwLWhvZG5vdGEgJmd0OyAwLjA1IOKGkiBub3JtYWxpdGEgcmV6w61kdcOtIHNhIG5lb2RtaWV0YTsgYWsg4omkIDAuMDUg4oaSIGRyb2Juw6kgcG9ydcWhZW5pZSBub3JtYWxpdHkgKGJlxb5uw6kgcHJpIGRlbW9ncmFmaWkpLjwvbGk+CiAgICA8bGk+PHN0cm9uZz5PdXRsaWVyIFRlc3Q6PC9zdHJvbmc+IGFrIHNhIHVrw6HFvnUgcmlhZGt5IHMgbWFsb3UgQm9uZmVycm9uaSBwLWhvZG5vdG91ICgmbHQ7IDAuMDUpLCBpZGUgbyB2w716bmFtbsOpIG9kxL5haGzDqSBwb3pvcm92YW5pYSDigJMgb2Rwb3LDusSNYSBzYSBpY2ggc2tvbnRyb2xvdmHFpS48L2xpPgogIDwvdWw+CjwvZGl2PgoKYGBge3J9Cm1vZGVsMiA8LSBsbShQb3B1bGF0aW9uLjIwMjUgfiAxICsgSShsb2coRmVydC4uUmF0ZSkpICsgTWVkaWFuLkFnZSArIE1pZ3JhbnRzLi5uZXQuLCBkYXRhID0gZGF0YV9zZWxlY3RlZCkKc3VtbWFyeShtb2RlbDIpCgpgYGAKPGRpdiBjbGFzcz0iaW5zaWdodCIgc3R5bGU9ImJvcmRlci1sZWZ0OjZweCBzb2xpZCAjMGVhNWU5Ij4KICA8aDQ+8J+TiiBJbnRlcnByZXTDoWNpYSB1cHJhdmVuw6lobyBtb2RlbHU8L2g0PgogIDx1bD4KICAgIDxsaT48c3Ryb25nPk1pZ3JhbnRzLi5uZXQ8L3N0cm9uZz4gbcOhIDxzdHJvbmc+dsO9em5hbW7DvSBwb3ppdMOtdm55PC9zdHJvbmc+IHZwbHl2IG5hIHBvxI1ldCBvYnl2YXRlxL5vdiB2IHJva3UgMjAyNSDigJMga3JhamlueSBzIGtsYWRub3UgxI1pc3RvdSBtaWdyw6FjaW91IG1hasO6IHZ5xaHFocOtIHBvxI1ldCBvYnl2YXRlxL5vdi48L2xpPgogICAgPGxpPjxzdHJvbmc+bG9nKEZlcnQuLlJhdGUpPC9zdHJvbmc+IGEgPHN0cm9uZz5NZWRpYW4uQWdlPC9zdHJvbmc+IHZ5xaFsaSA8ZW0+xaF0YXRpc3RpY2t5IG5ldsO9em5hbW5lPC9lbT4gKHrDoXBvcm7DqSB6bmFtaWVua2Egc8O6IGxvZ2lja8OpOiB2ecWhxaHDrSB2ZWsgPSBwb21hbMWhw60gcmFzdCwgdnnFocWhaWEgcMO0cm9kbm9zxaUgc2FtYSBvIHNlYmUgYmV6IMSPYWzFocOtY2ggZmFrdG9yb3YgbmVtdXPDrSBtZWR6aSBrcmFqaW5hbWkgdnlzdmV0bGnFpSByb3pkaWVseSB2IMO6cm92bmkgcG9wdWzDoWNpZSkuPC9saT4KICAgIDxsaT5Lb27FoXRhbnRhIG5pZSBqZSB2w716bmFtbsOhIOKAkyBtb2RlbCBzYSBvcGllcmEgbmFqbcOkIG8gbWlncmHEjW7DuiB6bG/Fvmt1LjwvbGk+CiAgPC91bD4KICA8cD7wn5KhIDxzdHJvbmc+xIxvIHogdG9obyBwbHluaWU6PC9zdHJvbmc+IFByZSB2eXN2ZXRsZW5pZSByb3pkaWVsb3YgdiDDunJvdm5pIHBvcHVsw6FjaWUgbWVkemkga3JhamluYW1pIGplIGvEvsO6xI1vdsOhIG1pZ3LDoWNpYS4gUMO0cm9kbm9zxaUgYSB2ZWsgYnkgZMOhdmFsaSB2w6TEjcWhw60gem15c2VsIHYgPGVtPnRlbXBvPC9lbT4gbW9kZWxvY2ggKHJhc3R5KSwgcHLDrXBhZG5lIHBvIGRvcGxuZW7DrSDEj2FsxaHDrWNoIGtvbnRyb2wgKG5hcHIuIHVyYmFuaXrDoWNpYSwgaHVzdG90YSwgSERQKS48L3A+CjwvZGl2PgoKYGBge3J9CiMgTm92w70gbW9kZWwgcG8gbG9nLXRyYW5zZm9ybcOhY2lpIEZlcnRpbGl0eSBSYXRlCm1vZGVsMiA8LSBsbShQb3B1bGF0aW9uLjIwMjUgfiAxICsgSShsb2coRmVydC4uUmF0ZSkpICsgTWVkaWFuLkFnZSArIE1pZ3JhbnRzLi5uZXQuLCAKICAgICAgICAgICAgIGRhdGEgPSBkYXRhX3NlbGVjdGVkKQoKIyBWw71waXMgdsO9c2xlZGtvdgpzdW1tYXJ5KG1vZGVsMikKCiMgTmFzdGF2acWlIHJvemxvxb5lbmllIDIgeCAyCgpwYXIobWZyb3cgPSBjKDIsIDIpKQoKIyBWeWtyZXNsacWlIHbFoWV0a3kgNCBkaWFnbm9zdGlja8OpIGdyYWZ5IG1vZGVsdQoKcGxvdChtb2RlbDIpCgojIFJlc2V0b3ZhxaUgbGF5b3V0CgpwYXIobWZyb3cgPSBjKDEsIDEpKQoKYGBgCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn6epIERpYWdub3N0aWthIHVwcmF2ZW7DqWhvIG1vZGVsdTwvaDQ+CiAgPHVsPgogICAgPGxpPjxzdHJvbmc+UmVzaWR1YWxzIHZzIEZpdHRlZDo8L3N0cm9uZz4gUmV6aWR1w6Egc8O6IHPDunN0cmVkZW7DqSBva29sbyBudWxvdmVqIG9zaSwgYmV6IHbDvXJhem7DqWhvIHpha3JpdmVuaWEgdHJlbmR1LiAgCiAgICAgIDxlbT7ihpIgbGluZcOhcm55IHR2YXIgdnrFpWFodSBqZSB2IHBvcmlhZGt1LCBtb2RlbCBuZXVrYXp1amUgc3lzdGVtYXRpY2vDqSBza3Jlc2xlbmllLjwvZW0+PC9saT4KCiAgICA8bGk+PHN0cm9uZz5R4oCTUSBSZXNpZHVhbHM6PC9zdHJvbmc+IFbDpMSNxaFpbmEgYm9kb3YgbGXFvsOtIHByaSBwcmlhbWtlLCBvZGNow71sa3kgc2Egb2JqYXZ1asO6IGxlbiB2IGtvbmNvY2guICAKICAgICAgPGVtPuKGkiBub3JtYWxpdGEgcmV6w61kdcOtIGplIDxzdHJvbmc+cHJpYmxpxb5uZSBzcGxuZW7DoTwvc3Ryb25nPjsgdHJhbnNmb3Jtw6FjaWEgcHJlbWVubsO9Y2ggcG9tb2hsYS48L2VtPjwvbGk+CgogICAgPGxpPjxzdHJvbmc+U2NhbGXigJNMb2NhdGlvbjo8L3N0cm9uZz4gUm96cHR5bCDFoXRhbmRhcmRpem92YW7DvWNoIHJlesOtZHXDrSBqZSByZWxhdMOtdm5lIHJvdm5vbWVybsO9LCBMT0VTUyDEjWlhcmEgamUgdGFrbWVyIHZvZG9yb3Zuw6EuICAKICAgICAgPGVtPuKGkiBwcmVkcG9rbGFkIDxzdHJvbmc+a29uxaF0YW50bsOpaG8gcm96cHR5bHU8L3N0cm9uZz4gKGhvbW9za2VkYXN0aWNpdGEpIGplIGFrY2VwdG92YXRlxL5uw70uPC9lbT48L2xpPgoKICAgIDxsaT48c3Ryb25nPlJlc2lkdWFscyB2cyBMZXZlcmFnZTo8L3N0cm9uZz4gVsOkxI3FoWluYSBib2RvdiBtw6EgbsOtemt5IHDDoWtvdsO9IGVmZWt0OyB6b3DDoXIgcG96b3JvdmFuw60gKG5hcHIuIG9rb2xpZSBpbmRleHUgNDApIGplIHbDvXJhem5lasWhw61jaCwgbm8gdsOkxI3FoWlub3UgcG9kIGhyYW5pY2FtaSBDb29rb3ZlaiB2emRpYWxlbm9zdGkuICAKICAgICAgPGVtPuKGkiBuZXZpZMOtbSBleHRyw6ltbmUgdnBseXZuw6kgcG96b3JvdmFuaWEsIG1vZGVsIGplIHN0YWJpbG7DvS48L2VtPjwvbGk+CiAgPC91bD4KCiAgPHA+4pyFIDxzdHJvbmc+WmhybnV0aWU6PC9zdHJvbmc+IERpYWdub3N0aWthIHBvIMO6cHJhdmUgbW9kZWx1IChsb2coRmVydC4uUmF0ZSkpIHZ5emVyw6EgZG9icmU6IGxpbmVhcml0YSwgbm9ybWFsaXRhIGFqIGhvbW9nZW5pdGEgcm96cHR5bHUgc8O6IG5hIHByYWt0aWNreSBwb3XFvml0ZcS+bmVqIMO6cm92bmkuIAogIE1pZ3JhxI1uw6EgcHJlbWVubsOhIG9zdMOhdmEgaGxhdm7DvW0gxaF0YXRpc3RpY2t5IHbDvXpuYW1uw71tIGZha3Rvcm9tIHZlxL5rb3N0aSBwb3B1bMOhY2llLjwvcD4KPC9kaXY+Cgo8ZGl2IGNsYXNzPSJtdXRlZCI+CgpgYGB7ciByZXN1bHRzPSdtYXJrdXAnLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIFRlc3R5IHByZWRwb2tsYWRvdiBwcmUgbW9kZWwyCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgTmHEjcOtdGFqIHBvdHJlYm7DqSBiYWzDrWt5CnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyh7CiAgbGlicmFyeSh0c2VyaWVzKSAgIyBwcmUgSmFycXVl4oCTQmVyYSB0ZXN0CiAgbGlicmFyeShjYXIpICAgICAgIyBwcmUgT3V0bGllciBUZXN0Cn0pCgojIFNrb250cm9sdWosIMSNaSBleGlzdHVqZSBtb2RlbDIKaWYgKCFleGlzdHMoIm1vZGVsMiIpKSB7CiAgbW9kZWwyIDwtIGxtKFBvcHVsYXRpb24uMjAyNSB+IEkobG9nKEZlcnQuLlJhdGUpKSArIE1lZGlhbi5BZ2UgKyBNaWdyYW50cy4ubmV0LAogICAgICAgICAgICAgICBkYXRhID0gZGF0YV9zZWxlY3RlZCkKfQoKIyAx77iP4oOjIEphcnF1ZeKAk0JlcmEgdGVzdCBub3JtYWxpdHkgcmV6w61kdcOtCnJlc2lkdWFsczIgPC0gcmVzaWR1YWxzKG1vZGVsMikKamJfdGVzdCA8LSBqYXJxdWUuYmVyYS50ZXN0KHJlc2lkdWFsczIpCmpiX3Rlc3QKCiMgMu+4j+KDoyBPdXRsaWVyIHRlc3QgKEJvbmZlcnJvbmkga29yZWtjaWEpCm91dGxpZXJfdGVzdCA8LSBvdXRsaWVyVGVzdChtb2RlbDIpCm91dGxpZXJfdGVzdAoKYGBgCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn5OKIEludGVycHJldMOhY2lhIGRvcGxua292w71jaCB0ZXN0b3YgbW9kZWx1PC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5UZXN0IG5vcm1hbGl0eSAoSmFycXVl4oCTQmVyYSk6PC9zdHJvbmc+IEhvZG5vdGEgcC12YWx1ZSBqZSB2ZcS+bWkgbsOtemthIOKGkiAKICAgICAgPGVtPnphbWlldGFtZSBoeXBvdMOpenUgbyBkb2tvbmFsZSBub3Jtw6FsbnljaCByZXppZHXDoWNoLjwvZW0+IAogICAgICBBdsWhYWsgdnpoxL5hZG9tIG5hIHZlxL5rb3PFpSB2em9ya3kgYSBjaGFyYWt0ZXIgZGVtb2dyYWZpY2vDvWNoIGTDoXQgc8O6IGRyb2Juw6kgb2RjaMO9bGt5IGFrY2VwdG92YXRlxL5uw6kuPC9saT4KCiAgICA8bGk+PHN0cm9uZz5PdXRsaWVyIFRlc3Q6PC9zdHJvbmc+IFRlc3QgaWRlbnRpZmlrb3ZhbCBuaWVrb8S+a28gcG96b3JvdmFuw60gKG5hcHIuIGluZGV4IDEsIDIsIDQwKSBzIHZ5c29rw71tIHQtxaF0dWRlbnRvdsO9bSB6LXNjb3JlLiAgCiAgICAgIDxlbT7ihpIgdGlldG8ga3Jham7DqSBob2Rub3R5IGJ5IG1vaGxpIG1pZXJuZSBvdnBseXZuacWlIHJlZ3Jlc27DqSBrb2VmaWNpZW50eSw8L2VtPiBubyB2emjEvmFkb20gbmEgaWNoIG7DrXpreSBww6Frb3bDvSBlZmVrdAogICAgICA8c3Ryb25nPm1vZGVsIG9zdMOhdmEgc3RhYmlsbsO9Ljwvc3Ryb25nPjwvbGk+CiAgPC91bD4KCiAgPHA+4pyFIDxzdHJvbmc+WsOhdmVyOjwvc3Ryb25nPiBVcHJhdmVuw70gbW9kZWwgc3DEusWIYSDFoXRhdGlzdGlja8OpIHByZWRwb2tsYWR5IHYgdXNwb2tvaml2ZWogbWllcmUuIAogIE5vcm1hbGl0YSByZXrDrWR1w60gbmllIGplIGRva29uYWzDoSwgbm8gbGluZcOhcm5hIMWhdHJ1a3TDunJhIGFqIHN0YWJpbGl0YSBtb2RlbHUgc8O6IHphY2hvdmFuw6kuPC9wPgo8L2Rpdj4KCjxkaXYgY2xhc3M9Im11dGVkIj4KICDwn5KhIDxlbT5Qb3puw6Fta2E6PC9lbT4gViBtYWtyb2Vrb25vbWlja8O9Y2ggYSBkZW1vZ3JhZmlja8O9Y2ggw7pkYWpvY2ggamUgbWllcm5hIG9kY2jDvWxrYSBvZCBub3JtYWxpdHkgYmXFvm7DoS4gCiAgCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn4+BIFrDoXZlciAoQ29uY2x1c2lvbik8L2g0PgogIDxwPgogICAgViB1cHJhdmVub20gbW9kZWxpIHNtZSBzbGVkb3ZhbGkgdnBseXYgPHN0cm9uZz5taWVyeSBww7Ryb2Rub3N0aSAoRmVydC4gUmF0ZSk8L3N0cm9uZz4sIAogICAgPHN0cm9uZz5tZWRpw6Fub3bDqWhvIHZla3UgKE1lZGlhbiBBZ2UpPC9zdHJvbmc+IGEgPHN0cm9uZz7EjWlzdGVqIG1pZ3LDoWNpZSAoTWlncmFudHMgbmV0KTwvc3Ryb25nPiAKICAgIG5hIDxzdHJvbmc+dmXEvmtvc8WlIHBvcHVsw6FjaWUgdiByb2t1IDIwMjU8L3N0cm9uZz4uCiAgPC9wPgoKICA8dWw+CiAgICA8bGk+PHN0cm9uZz5NaWdyw6FjaWE8L3N0cm9uZz4gbcOhIG5hxI9hbGVqIDxlbT7FoXRhdGlzdGlja3kgdsO9em5hbW7DvSBhIHBveml0w612bnkgdnBseXY8L2VtPiDigJQga3JhamlueSBzIHZ5xaHFoW91IMSNaXN0b3UgbWlncsOhY2lvdSAKICAgICAgICBtYWrDuiB0ZW5kZW5jaXUgcsOhc8WlIHLDvWNobGVqxaFpZS48L2xpPgoKICAgIDxsaT48c3Ryb25nPlDDtHJvZG5vc8WlPC9zdHJvbmc+IHBvIGxvZy10cmFuc2Zvcm3DoWNpaSBzw61jZSBzdHLDoWNhIMWhdGF0aXN0aWNrw7ogdsO9em5hbW5vc8WlLCAKICAgICAgICBubyB6YWNob3bDoXZhIG/EjWFrw6F2YW7DqSB6bmFtaWVua28gKDxlbT52ecWhxaFpYSBww7Ryb2Rub3PFpSDihpIgdsOkxI3FoWlhIHBvcHVsw6FjaWE8L2VtPikuPC9saT4KCiAgICA8bGk+PHN0cm9uZz5NZWRpw6Fub3bDvSB2ZWs8L3N0cm9uZz4gbcOhIG5lZ2F0w612bnkgdnBseXYsIGFrbyBzYSBvxI1ha8OhdmEg4oCUIHN0YXLFoWlhIHBvcHVsw6FjaWEgem5hbWVuw6EgcG9tYWzFocOtIHJhc3QuPC9saT4KICA8L3VsPgoKICA8cD7wn5OKIDxzdHJvbmc+RGlhZ25vc3RpY2vDqSBncmFmeTwvc3Ryb25nPiBhaiA8c3Ryb25nPsWhdGF0aXN0aWNrw6kgdGVzdHk8L3N0cm9uZz4gdWvDoXphbGksIMW+ZSBtb2RlbCBzcMS6xYhhIHbDpMSNxaFpbnUgCiAgcHJlZHBva2xhZG92IGxpbmXDoXJuZWogcmVncmVzaWU6IHJlemlkdcOhIHPDuiBwcmlibGnFvm5lIG5vcm3DoWxuZSByb3pkZWxlbsOpLCByb3pwdHlsIGplIHN0YWJpbG7DvSAKICBhIMW+aWFkbmUgcG96b3JvdmFuaWEgbmVtYWrDuiBuYWRtZXJuw70gdnBseXYgbmEgdsO9c2xlZGt5LjwvcD4KCiAgPHA+4pyFIDxzdHJvbmc+Q2Vsa292w6kgaG9kbm90ZW5pZTo8L3N0cm9uZz4gTW9kZWwgdnlzdmV0xL51amUgdmFyaWFiaWxpdHUgcG9wdWzDoWNpZSBtZWR6aSBrcmFqaW5hbWkgdiB1c3Bva29qaXZlaiBtaWVyZS4KICBUcmFuc2Zvcm3DoWNpYSBsb2coRmVydC4gUmF0ZSkgcHJpc3BlbGEgayBsZXDFoWVqIG5vcm1hbGl0ZSByZXrDrWR1w60gYSBzdGFiaWxpdGUgb2RoYWRvdi48L3A+CjwvZGl2PgoKPGRpdiBjbGFzcz0ibXV0ZWQiPgoKIyMgSGV0ZXJvc2tlZGFzdGljaXRhCgpQcsOtdG9tbm9zxaUgaGV0ZXJvc2tlZGFzdGljaXR5IChuZWtvbsWhdGFudG7DqWhvIHJvenB0eWx1IG7DoWhvZG5laiB6bG/Fvmt5KSBzcMO0c29idWplIHpsw6kgdnlob2Rub2NvdmFuaWUgdC10ZXN0b3YgdsO9em5hbW5vc3RpIGplZG5vdGxpdsO9Y2ggcmVncmVzbsO9Y2gga29lZmljaWVudG92LiBQcmV0byBqZSBudXRuw6ksIGFieSBzbWUgaGV0ZXJvc2tlZGFzdGljaXR1IAotIGRldGVrb3ZhbGkgKHZpenXDoWxuZSBhIHMgcG9tb2NvdSB0ZXN0b3YpCi0gYSB2IHByw61wYWRlIHByw610b21ub3N0aSBoZXRlcm9za2VkYXN0aWNpdHkgYWJ5IHNtZSBqdSBvZHN0csOhbmlsaS4KCkFqIHYgbmHFoW9tIHByw61wYWRlIGJ5IHNtZSBzYSBtb2hsaSBwb2vDunNpxaUgbyB2aXp1w6FsbmUgdnlob2Rub3RlbmllIG5hc2xlZG92bsO9Y2ggZ3JhZm92IChhaiBrZcSPIGplZGVuIGdyYWYgc21lIHXFviBza8O6bWFsaSAtIGJvbCB0byB0enYuIFNjYWxlLUxvY2F0aW9uIGdyYWZ5IHV2ZWRlbsOpIHZ5xaHFoWllKS4KClRlbnRva3LDoXQgc2EgcG9rw7pzaW1lIG8gdml6dcOhbG5lIHpuw6F6b3JuZW5pZSB6w6F2aXNsb3N0aSDFoXR2b3Jjb3YgcmV6w61kdcOtIGEgdnlzdmV0xL51asO6Y2VqIHByZW1lbm5laiwgdSBrdG9yZWogbcOhbWUgcG9kb3pyZW5pZSwgxb5lIG3DtMW+ZSBoZXRlcm9za2VkYXN0aWNpdHUgc3DDtHNvYm92YcWlLiBCdWRlbWUgcG9zdWR6b3ZhxaUgZHZhIG1vZGVseSAtIGEgdG8gbW9kZWwgbmF6dmFuw70gKm1vZGVsKiBhbGVibyBtb2RlbCBuYXp2YW7DvSAqbW9kZWwyKi4gKm1vZGVsMiogbcOhIHpsb2dhcml0bWl6b3ZhbsO6IHByZW1lbm7DuiAqR0RQKiwgxI1vIHNtZSByb2JpbGkgeiBkw7R2b2R1IG9kc3Ryw6FuZW5pYSB2cGx5dnUgb2TEvmFobMO9Y2ggcHJlbWVubsO9Y2ggdiBwcmVkY2jDoWR6YWrDumNpY2gga3Jva29jaCwgKm1vZGVsKiBqZSBww7R2b2Ruw71tIG1vZGVsb20uCgoKYGBge3IgaGV0ZXJvcGxvdHMyYiwgZmlnLmNhcD0iU2vDum1hbmllIGhldGVyb3NrZWRhc3RpY2l0eSB2IG1vZGVsaSBwb3B1bMOhY2llIDIwMjUiLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NH0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHBhdGNod29yaykKCgojIDHvuI/ig6MgR3JhZiDigJMgaGV0ZXJvc2tlZGFzdGljaXRhIHZvxI1pIEZlcnRpbGl0eSBSYXRlIChsb2ctdHJhbnNmb3Jtb3ZhbmVqKQpwMSA8LSBnZ3Bsb3QoZGF0YV9zZWxlY3RlZCwgYWVzKHggPSBsb2coRmVydC4uUmF0ZSksIHkgPSByZXNpZHVhbHMobW9kZWwyKV4yKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYsIGNvbG9yID0gInN0ZWVsYmx1ZSIpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJyZWQiLCBsd2QgPSAxKSArCiAgbGFicygKICAgIHggPSAiTG9nKEZlcnRpbGl0eSBSYXRlKSIsCiAgICB5ID0gIlJlemlkdcOhbG5lIGNoeWJ5IiwKICAgIHRpdGxlID0gIlJlemlkdcOhbG5lIGNoeWJ5IHZzLiBGZXJ0aWxpdHkgUmF0ZSAobG9nKSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCiMgMu+4j+KDoyBHcmFmIOKAkyBoZXRlcm9za2VkYXN0aWNpdGEgdm/EjWkgTWVkaWFuIEFnZQpwMiA8LSBnZ3Bsb3QoZGF0YV9zZWxlY3RlZCwgYWVzKHggPSBNZWRpYW4uQWdlLCB5ID0gcmVzaWR1YWxzKG1vZGVsMileMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJzdGVlbGJsdWUiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIiwgbHdkID0gMSkgKwogIGxhYnMoCiAgICB4ID0gIk1lZGlhbiBBZ2UiLAogICAgeSA9ICJSZXppZHXDoWxuZSBjaHlieSIsCiAgICB0aXRsZSA9ICJSZXppZHXDoWxuZSBjaHlieSB2cy4gTWVkaWFuIEFnZSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCiMgM++4j+KDoyBHcmFmIOKAkyBoZXRlcm9za2VkYXN0aWNpdGEgdm/EjWkgTWlncmFudHMgbmV0CnAzIDwtIGdncGxvdChkYXRhX3NlbGVjdGVkLCBhZXMoeCA9IE1pZ3JhbnRzLi5uZXQuLCB5ID0gcmVzaWR1YWxzKG1vZGVsMileMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJzdGVlbGJsdWUiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIiwgbHdkID0gMSkgKwogIGxhYnMoCiAgICB4ID0gIk1pZ3JhbnRzIG5ldCIsCiAgICB5ID0gIlJlemlkdcOhbG5lIGNoeWJ5IiwKICAgIHRpdGxlID0gIlJlemlkdcOhbG5lIGNoeWJ5IHZzLiBNaWdyYW50cyBuZXQiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCgojIEtvbWJpbsOhY2lhIGdyYWZvdiB2ZWTEvmEgc2ViYQoocDEgfCBwMiB8IHAzKQoKYGBgCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn5OJIEludGVycHJldMOhY2lhIGhldGVyb3NrZWRhc3RpY2l0eTwvaDQ+CiAgPHVsPgogICAgPGxpPjxzdHJvbmc+RmVydGlsaXR5IFJhdGUgKGxvZyk6PC9zdHJvbmc+IFbDpMSNxaFpbmEgYm9kb3Ygc2EgbmFjaMOhZHphIGJsw616a28gb3NpIFgsIGJleiB2eXR2w6FyYW5pYSB0dmFydSBsaWV2aWthLiDEjGVydmVuw6EgTE9FU1Mga3JpdmthIGplIHRha21lciB2b2Rvcm92bsOhIOKAkyByb3pwdHlsIHJlesOtZHXDrSBqZSBwcmlibGnFvm5lIGtvbsWhdGFudG7DvS48L2xpPgogICAgPGxpPjxzdHJvbmc+TWVkaWFuIEFnZTo8L3N0cm9uZz4gUmV6w61kdcOhIHPDuiByb3Zub21lcm5lIHJvemxvxb5lbsOpLCBiZXogemphdm5laiBzeXN0ZW1hdGlja2VqIHptZW55IHZhcmlhYmlsaXR5LiBPcMOkxaUgc2EgbmVwcmVqYXZ1amUgaGV0ZXJvc2tlZGFzdGljaXRhLjwvbGk+CiAgICA8bGk+PHN0cm9uZz5NaWdyYW50cyBuZXQ6PC9zdHJvbmc+IFNsYWLDvSBuw6FyYXN0IG5hIGtvbmNpIG9zaSBYIG5hem5hxI11amUgbWllcm51IHRlbmRlbmNpdSByYXN0dSByb3pwdHlsdSBwcmkgZXh0csOpbW55Y2ggaG9kbm90w6FjaCwgYWxlIGVmZWt0IGplIHZlxL5taSBtYWzDvSBhIG5lcHJlZHN0YXZ1amUgdsOhxb5ueSBwcm9ibMOpbS48L2xpPgogIDwvdWw+CiAgPHA+4pyFIDxzdHJvbmc+WsOhdmVyOjwvc3Ryb25nPiBNb2RlbCBuZXNwxLrFiGEgem7DoW1reSB2w71yYXpuZWogaGV0ZXJvc2tlZGFzdGljaXR5LiBSb3pwdHlsIG7DoWhvZG7DvWNoIGNow71iIGplIHByaWJsacW+bmUga29uxaF0YW50bsO9LCBwcmV0byBwcmVkcG9rbGFkIGhvbW9za2VkYXN0aWNpdHkgamUgc3BsbmVuw70uPC9wPgo8L2Rpdj4KCgoKYSB0ZXJheiBtb2RlbCBzbyB6bG9nYXJpdG1pem92YW5vdSBwcmVtZW5ub3UgKkdEUCouCmBgYHtyIGhldGVyb19wb3AyMDI1LCBmaWcuY2FwPSJWYXJpYWJpbGl0YSBjaMO9YiBwb2TEvmEgdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCIsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGF0Y2h3b3JrKQoKIyAxKSBsb2coRmVydGlsaXR5IFJhdGUpCnAxIDwtIGdncGxvdChkYXRhX3NlbGVjdGVkLCBhZXMoeCA9IGxvZyhGZXJ0Li5SYXRlKSwgeSA9IHJlc2lkdWFscyhtb2RlbDIpXjIpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNiwgY29sb3IgPSAic3RlZWxibHVlIikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIsIGxpbmV3aWR0aCA9IDEpICsKICBsYWJzKAogICAgeCA9ICJsb2coUMO0cm9kbm9zxaUpIOKAkyBsb2coRmVydC4gUmF0ZSkiLAogICAgeSA9ICJWYXJpYWJpbGl0YSBjaMO9YiAoxaF0dm9yY2UgcmV6w61kdcOtKSIsCiAgICB0aXRsZSA9ICJWYXJpYWJpbGl0YSBjaMO9YiB2cy4gbG9nKEZlcnRpbGl0eSBSYXRlKSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCiMgMikgTWVkaWFuIEFnZQpwMiA8LSBnZ3Bsb3QoZGF0YV9zZWxlY3RlZCwgYWVzKHggPSBNZWRpYW4uQWdlLCB5ID0gcmVzaWR1YWxzKG1vZGVsMileMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJzdGVlbGJsdWUiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIiwgbGluZXdpZHRoID0gMSkgKwogIGxhYnMoCiAgICB4ID0gIk1lZGnDoW5vdsO9IHZlayAoTWVkaWFuIEFnZSkiLAogICAgeSA9ICJWYXJpYWJpbGl0YSBjaMO9YiAoxaF0dm9yY2UgcmV6w61kdcOtKSIsCiAgICB0aXRsZSA9ICJWYXJpYWJpbGl0YSBjaMO9YiB2cy4gTWVkaWFuIEFnZSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCiMgMykgTWlncmFudHMgbmV0ICAgKGFrIG3DocWhIHYgQ1NWIGluw70gbsOhem92LCBuYWhyYcSPIHYgYWVzKCkgc3DDpHRuw71taSBhcG9zdHJvZm1pKQpwMyA8LSBnZ3Bsb3QoZGF0YV9zZWxlY3RlZCwgYWVzKHggPSBgTWlncmFudHMuLm5ldC5gLCB5ID0gcmVzaWR1YWxzKG1vZGVsMileMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJzdGVlbGJsdWUiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIiwgbGluZXdpZHRoID0gMSkgKwogIGxhYnMoCiAgICB4ID0gIsSMaXN0w6EgbWlncsOhY2lhIChNaWdyYW50cyBuZXQpIiwKICAgIHkgPSAiVmFyaWFiaWxpdGEgY2jDvWIgKMWhdHZvcmNlIHJlesOtZHXDrSkiLAogICAgdGl0bGUgPSAiVmFyaWFiaWxpdGEgY2jDvWIgdnMuIE1pZ3JhbnRzIG5ldCIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCihwMSB8IHAyIHwgcDMpCgpgYGAKPGRpdiBjbGFzcz0iaW5zaWdodCI+CiAgPGg0PvCfk4kgSW50ZXJwcmV0w6FjaWEgZ3JhZm92IHZhcmlhYmlsaXR5IGNow71iPC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5sb2coRmVydGlsaXR5IFJhdGUpOjwvc3Ryb25nPiDEjWVydmVuw6EgTE9FU1Mga3JpdmthIGplIHRha21lciB2b2Rvcm92bsOhIOKAkyByb3pwdHlsIGNow71iIHNhIHbDvXJhem5lIG5lbWVuw60gcyBob2Rub3RvdSBwcmVtZW5uZWouPC9saT4KICAgIDxsaT48c3Ryb25nPk1lZGlhbiBBZ2U6PC9zdHJvbmc+IGJvZHkgc8O6IHJvenB0w71sZW7DqSByb3Zub21lcm5lLCBiZXog4oCebGlldmlrb3bDqWhv4oCcIHR2YXJ1IOKAkyBuZW5hem5hxI11amUgaGV0ZXJvc2tlZGFzdGljaXR1LjwvbGk+CiAgICA8bGk+PHN0cm9uZz5NaWdyYW50cyBuZXQ6PC9zdHJvbmc+IGplbW7DvSBuw6FyYXN0IG5hIHZ5c29rw71jaCBob2Rub3TDoWNoIGplIHNsYWLDvTsgY2Vsa292byByb3pwdHlsIHpvc3TDoXZhIHN0YWJpbG7DvS48L2xpPgogIDwvdWw+CiAgPHA+4pyFIDxzdHJvbmc+WsOhdmVyOjwvc3Ryb25nPiBNb2RlbDIgbmV2eWthenVqZSB2w71yYXpuw6kgem7DoW1reSBoZXRlcm9za2VkYXN0aWNpdHk7IHByZWRwb2tsYWQgcHJpYmxpxb5uZSBrb27FoXRhbnRuw6lobyByb3pwdHlsdSBqZSBzcGxuZW7DvS48L3A+CjwvZGl2PgoKCiMjIFRlc3RvdmFuaWUgcHLDrXRvbW5vc3RpIGhldGVyb3NrZWRhc3RpY2l0eQoKYGBge3J9CiMgSW5zdGFsbCAoaWYgbm90IHlldCBpbnN0YWxsZWQpCiMgaW5zdGFsbC5wYWNrYWdlcygibG10ZXN0IikKCiMgTG9hZCB0aGUgcGFja2FnZQpsaWJyYXJ5KGxtdGVzdCkKCiMgUnVuIHRoZSBCcmV1c2No4oCTUGFnYW4gdGVzdApicHRlc3QobW9kZWwpCgpgYGAKPGRpdiBjbGFzcz0iaW5zaWdodCI+CiAgPGg0PvCfk4ggSW50ZXJwcmV0w6FjaWEgQnJldXNjaOKAk1BhZ2FuIHRlc3R1IChoZXRlcm9za2VkYXN0aWNpdGEpPC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5IeXBvdMOpenk6PC9zdHJvbmc+IEg8c3ViPjA8L3N1Yj4g4oCTIHJvenB0eWwgcmV6w61kdcOtIGplIGtvbsWhdGFudG7DvSAoaG9tb3NrZWRhc3RpY2l0YSk7IEg8c3ViPjE8L3N1Yj4g4oCTIHJvenB0eWwgbmllIGplIGtvbsWhdGFudG7DvSAoaGV0ZXJvc2tlZGFzdGljaXRhKS48L2xpPgogICAgPGxpPjxzdHJvbmc+VsO9c2xlZG9rIHByZSBww7R2b2Ruw70gbW9kZWw6PC9zdHJvbmc+IHAtaG9kbm90YSBqZSA8c3Ryb25nPiZsdDsgMC4wNTwvc3Ryb25nPiAmcmFycjsgPGVtPnphbWlldGFtZTwvZW0+IEg8c3ViPjA8L3N1Yj4uIAogICAgICBNb2RlbCB2eWthenVqZSB6bsOhbWt5IDxzdHJvbmc+aGV0ZXJvc2tlZGFzdGljaXR5PC9zdHJvbmc+ICh2YXJpYWJpbGl0YSBjaMO9YiBzYSBtZW7DrSBzIGhvZG5vdGFtaSB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoKS48L2xpPgogICAgPGxpPjxzdHJvbmc+RMO0c2xlZG9rOjwvc3Ryb25nPiBrbGFzaWNrw6kgc21lcm9kYWpuw6kgY2h5YnkgbcO0xb51IGJ5xaUgc2tyZXNsZW7DqSAmcmFycjsgdC10ZXN0eSBhIHAtaG9kbm90eSBuZW11c2lhIGJ5xaUgc3BvxL5haGxpdsOpLjwvbGk+CiAgPC91bD4KICA8cD7inIUgPHN0cm9uZz5PZHBvcsO6xI1hbmllOjwvc3Ryb25nPiAoMSkgUG91xb5pxaUgdHJhbnNmb3Jtw6FjaXUgdnlzdmV0xL51asO6Y2VqIHByZW1lbm5laiA8ZW0+RmVydC4uUmF0ZTwvZW0+IG5hIDxjb2RlPmxvZyhGZXJ0Li5SYXRlKTwvY29kZT4gCiAgKHR2b2ogPHN0cm9uZz5tb2RlbDI8L3N0cm9uZz4pLCAoMikgcmVwb3J0b3ZhxaUgPGVtPnJvYnVzdG7DqSBzbWVyb2Rham7DqSBjaHlieTwvZW0+IChIQzEsIHNhbmR3aWNoKSwgCiAgcHLDrXBhZG5lICgzKSB6dsOhxb5pxaUgdsOhxb5lbsO6IHJlZ3Jlc2l1IChXTFMpLCBhayBieSBoZXRlcm9za2VkYXN0aWNpdGEgcHJldHJ2w6F2YWxhLjwvcD4KPC9kaXY+Cgo8ZGl2IGNsYXNzPSJtdXRlZCI+CiAg8J+SoSA8ZW0+UG96bsOhbWthOjwvZW0+IFYgZGVtb2dyYWZpY2vDvWNoIGEgbWFrcm9la29ub21pY2vDvWNoIGTDoXRhY2ggamUgbWllcm5hIGhldGVyb3NrZWRhc3RpY2l0YSBiZcW+bsOhLiAKICBEw7RsZcW+aXTDqSBqZSB1cHJhdmnFpSBpbmZlcmVuY2l1IChyb2J1c3Ruw6kgU0UpIGEgc2tvbnRyb2xvdmHFpSBkaWFnbm9zdGlja8OpIGdyYWZ5IChTY2FsZS1Mb2NhdGlvbiwgUmVzaWR1YWxzIHZzIEZpdHRlZCkuCjwvZGl2PgoKCmBgYHtyfQojIEluc3RhbGwgKGlmIG5vdCB5ZXQgaW5zdGFsbGVkKQojIGluc3RhbGwucGFja2FnZXMoImxtdGVzdCIpCgojIExvYWQgdGhlIHBhY2thZ2UKbGlicmFyeShsbXRlc3QpCgojIFJ1biB0aGUgQnJldXNjaOKAk1BhZ2FuIHRlc3QKYnB0ZXN0KG1vZGVsMikKCmBgYAo8ZGl2IGNsYXNzPSJhbmFseXNpcyI+CiAgPGg0PvCfk4ogSW50ZXJwcmV0w6FjaWEgdsO9c2xlZGtvdiB0ZXN0dSBoZXRlcm9za2VkYXN0aWNpdHkgKEJyZXVzY2jigJNQYWdhbik8L2g0PgogIDxwPgogIE5hIHrDoWtsYWRlIHbDvXNsZWRrb3YgdGVzdHUgbcO0xb5lbWUga29uxaF0YXRvdmHFpSwgxb5lIDxzdHJvbmc+aGV0ZXJvc2tlZGFzdGljaXRhIHJlesOtZHXDrSBqZSB2IHDDtHZvZG5vbSBtb2RlbGkgCiAgPGVtPm1vZGVsPC9lbT4gcHLDrXRvbW7DoTwvc3Ryb25nPiAocC1ob2Rub3RhIDwgMC4wNSksIMSNbyB6bmFtZW7DoSwgxb5lIHJvenB0eWwgbsOhaG9kbmVqIHpsb8W+a3kgbmllIGplIGtvbsWhdGFudG7DvSAKICBwcmUgdsWhZXRreSBwb3pvcm92YW5pYS4gVGVudG8gamF2IG3DtMW+ZSBzcMO0c29iacWlIDxlbT5uZXNwb8S+YWhsaXbDqSBvZGhhZHkgc21lcm9kYWpuw71jaCBjaMO9YjwvZW0+IAogIGEgdMO9bSBhaiBuZXByZXNuw6kgdGVzdG92YW5pZSDFoXRhdGlzdGlja2VqIHbDvXpuYW1ub3N0aSByZWdyZXNuw71jaCBrb2VmaWNpZW50b3YuCiAgPC9wPgoKICA8cD4KICBQbyDDunByYXZlIG1vZGVsdSDigJQgdnl0dm9yZW7DrW0gPHN0cm9uZz5tb2RlbHUgPGVtPm1vZGVsMjwvZW0+IHNvIHpsb2dhcml0bWl6b3Zhbm91IHByZW1lbm5vdSA8ZW0+RmVydC4uUmF0ZTwvZW0+IAogIGEgb2RzdHLDoW5lbsOtbSBvZMS+YWhsw71jaCBwb3pvcm92YW7DrTwvc3Ryb25nPiDigJQgc2EgcC1ob2Rub3RhIHRlc3R1IG1pZXJuZSB6bGVwxaFpbGEsIG5vIAogIDxzdHJvbmc+em7DoW1reSBoZXRlcm9za2VkYXN0aWNpdHkgc3TDoWxlIHByZXRydsOhdmFqw7o8L3N0cm9uZz4gKHAg4omIIDAuMDAyNSkuCiAgPC9wPgoKICA8cD4KICBWemjEvmFkb20gbmEgdG8sIMW+ZSBhbmkgdHJhbnNmb3Jtw6FjaWEgYW5pIGVsaW1pbsOhY2lhIG9kxL5haGzDvWNoIGhvZG7DtHQgCiAgaGV0ZXJvc2tlZGFzdGljaXR1IMO6cGxuZSBuZW9kc3Ryw6FuaWxpLCA8c3Ryb25nPnByaXN0w7pwaW1lIGsgdnl1xb5pdGl1IHR6di4gV2hpdGUgaGV0ZXJvc2tlZGFzdGljaXR5LWNvbnNpc3RlbnQKICAocm9idXN0bsO9Y2gpIHNtZXJvZGFqbsO9Y2ggY2jDvWI8L3N0cm9uZz4uIFRlbnRvIHByw61zdHVwIGtvcmlndWplIG9kaGFkeSByb3pwdHlsb3YgcmVncmVzbsO9Y2gga29lZmljaWVudG92IHRhaywgCiAgYWJ5IGJvbGkgc3BvxL5haGxpdsOpIGFqIHYgcHLDrXBhZGUgcHLDrXRvbW5vc3RpIGhldGVyb3NrZWRhc3RpY2l0eS4KICA8L3A+CjwvZGl2PgoKPGRpdiBjbGFzcz0ibXV0ZWQiPgogIPCfkqEgPGVtPlBvem7DoW1rYTo8L2VtPiBIZXRlcm9za2VkYXN0aWNpdGEgamUgdiBkZW1vZ3JhZmlja8O9Y2ggYSBtYWtyb2Vrb25vbWlja8O9Y2ggw7pkYWpvY2ggxI1hc3TDvW0gamF2b20uIAogIFBvdcW+aXRpZSByb2J1c3Ruw71jaCDFoXRhbmRhcmRuw71jaCBjaMO9YiAobmFwci4gSEMxIOKAkyBXaGl0ZSkgemFiZXpwZcSNw60ga29yZWt0bsO6IGluZmVyZW5jaXUgCiAgYmV6IG51dG5vc3RpIHrDoXNhZG5lIG1lbmnFpSDFoXRydWt0w7pydSBtb2RlbHUuCjwvZGl2PgoKYGBge3Igd2hpdGVfdGVzdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBXaGl0ZSBoZXRlcm9za2VkYXN0aWNpdHktY29uc2lzdGVudCByb2J1c3Qgc3RhbmRhcmQgZXJyb3JzCgojIE5hxI3DrXRhbmllIHBvdHJlYm7DvWNoIGtuacW+bsOtYwpsaWJyYXJ5KHNhbmR3aWNoKQpsaWJyYXJ5KGxtdGVzdCkKCiMgVsO9cG/EjWV0IHJvYnVzdG7DvWNoIHNtZXJvZGFqbsO9Y2ggY2jDvWIgcHJlIG1vZGVsIChXaGl0ZSBIQzEpCnJvYnVzdF9zZSA8LSBjb2VmdGVzdChtb2RlbDIsIHZjb3YgPSB2Y292SEMobW9kZWwyLCB0eXBlID0gIkhDMSIpKQoKIyBWw71zdHVwCnJvYnVzdF9zZQoKYGBgCjxkaXYgY2xhc3M9ImFuYWx5c2lzIj4KICA8aDQ+8J+TiCBJbnRlcnByZXTDoWNpYSB2w71zbGVka292IHMgcm9idXN0bsO9bWkgc21lcm9kYWpuw71taSBjaHliYW1pPC9oND4KICA8cD4KICBQbyBhcGxpa8OhY2lpIFdoaXRlIGhldGVyb3NrZWRhc3RpY2l0eS1jb25zaXN0ZW50IChyb2J1c3Ruw71jaCkgc21lcm9kYWpuw71jaCBjaMO9YiBzYSB1a2F6dWplLCDFvmUgCiAgPHN0cm9uZz52xaFldGt5IHByZW1lbm7DqSB2IG1vZGVsaSBzw7ogxaF0YXRpc3RpY2t5IHbDvXpuYW1uw6kgYWxlYm8gaHJhbmnEjW5lIHbDvXpuYW1uw6k8L3N0cm9uZz4uICAKICBQcmVtZW5uw6kgPGVtPk1lZGlhbi5BZ2U8L2VtPiBhIDxlbT5GZXJ0aWxpdHkgUmF0ZSAobG9nKTwvZW0+IG1hasO6IG5lZ2F0w612bnkgdnBseXYsIHphdGlhxL4gxI1vIAogIDxlbT5NaWdyYW50cy5uZXQ8L2VtPiBww7Rzb2LDrSBwb3ppdMOtdm5lIG5hIHByZWRwb2tsYWRhbsO9IHBvxI1ldCBvYnl2YXRlxL5vdiB2IHJva3UgMjAyNS4KICA8L3A+CgogIDx1bD4KICAgIDxsaT48c3Ryb25nPk1pZXJhIHBsb2Rub3N0aSAobG9nIEZlcnRpbGl0eSBSYXRlKTwvc3Ryb25nPiDigJMgbmVnYXTDrXZueSBrb2VmaWNpZW50IG5hem5hxI11amUsIMW+ZSBrcmFqaW55IHMgbmnFvsWhb3UgcMO0cm9kbm9zxaVvdSAKICAgICAgICBtYWrDuiB0ZW5kZW5jaXUgZG9zYWhvdmHFpSBuacW+xaHDrSBwcsOtcmFzdG9rIHBvcHVsw6FjaWUgKHByaSBvc3RhdG7DvWNoIHByZW1lbm7DvWNoIG5lem1lbmVuw71jaCkuPC9saT4KICAgIDxsaT48c3Ryb25nPk1lZGnDoW5vdsO9IHZlayAoTWVkaWFuIEFnZSk8L3N0cm9uZz4g4oCTIG5lZ2F0w612bnkgdnBseXYgaW5kaWt1amUsIMW+ZSBzdGFyxaFpZSBwb3B1bMOhY2llIAogICAgICAgIHLDoXN0bGkgcG9tYWzFoWllLCDEjW8gem9kcG92ZWTDoSBvxI1ha8OhdmFuw71tIGRlbW9ncmFmaWNrw71tIHRyZW5kb20uPC9saT4KICAgIDxsaT48c3Ryb25nPk1pZ3LDoWNpYSAoTWlncmFudHMubmV0KTwvc3Ryb25nPiDigJMgcG96aXTDrXZueSBhIHRha21lciDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSBrb2VmaWNpZW50IChwIOKJiCAwLjA1KSBwb3VrYXp1amUsIAogICAgICAgIMW+ZSDEjWlzdMOhIG1pZ3LDoWNpYSB6dnnFoXVqZSBwb3B1bMOhY2l1IHYgY2llxL5vdsO9Y2gga3Jhamluw6FjaC48L2xpPgogIDwvdWw+CgogIDxwPgogIDxzdHJvbmc+SW50ZXJwcmV0w6FjaWEgdsO9c2xlZGtvdjo8L3N0cm9uZz4gIAogIE9kaGFkeSBzw7ogc3RhYmlsbmVqxaFpZSB2xI9ha2EgcG91xb5pdGl1IHJvYnVzdG7DvWNoIMWhdGFuZGFyZG7DvWNoIGNow71iLiBUw71tdG8ga3Jva29tIHNtZSBtaW5pbWFsaXpvdmFsaSB2cGx5diAKICBoZXRlcm9za2VkYXN0aWNpdHksIGt0b3LDoSBib2xhIHBvdHZyZGVuw6EgQnJldXNjaOKAk1BhZ2Fub3bDvW0gdGVzdG9tLiAKICA8YnI+CiAgViBtb2RlbGkgc2EgdGVkYSBwb3R2cmR6dWplLCDFvmUgPGVtPmRlbW9ncmFmaWNrw6kgdWthem92YXRlbGUg4oCTIHBsb2Rub3PFpSwgdmVrb3bDoSDFoXRydWt0w7pyYSBhIG1pZ3LDoWNpYSDigJMgCiAgbWFqw7ogxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gdnrFpWFoIHMgdmXEvmtvc8Wlb3UgcG9wdWzDoWNpZSB2IHJva3UgMjAyNTwvZW0+LgogIDwvcD4KPC9kaXY+Cgo8ZGl2IGNsYXNzPSJtdXRlZCI+CiAg8J+SoSA8ZW0+UG96bsOhbWthOjwvZW0+IFByaSBwcsOhY2kgcyByb2J1c3Ruw71taSBzbWVyb2Rham7DvW1pIGNoeWJhbWkgamUgZMO0bGXFvml0w6kgbWHFpSBkb3N0YXRvxI1uZSB2ZcS+a8O9IHBvxI1ldCBwb3pvcm92YW7DrSAKICAodiB0b210byBwcsOtcGFkZSB2aWFjIGFrbyAxMDApLCBhYnkgYm9saSBvZGhhZHkgc3BvxL5haGxpdsOpLiBUZW50byBwb3N0dXAgdW1vxb7FiHVqZSB6w61za2HFpSBrb256aXN0ZW50bsOpIAogIHbDvXNsZWRreSBhaiB2IHByw61wYWRlLCDFvmUgcm96cHR5bCByZXrDrWR1w60gbmllIGplIGtvbsWhdGFudG7DvS4KPC9kaXY+Cg==