S využitím databázy [World Happiness report] / HETEROSKEDASTICITA NA KONCI ](https://www.kaggle.com/datasets/jahaidulislam/world-happiness-report-2005-2021) database.

library(zoo)
library(tseries)
library(lmtest)
library(sandwich)
library(car)
rm(list=ls())

Úvod do problému, stanovenie hypotéz

Rozhodol som sa modelovať index šťastia Life Ladder v závislosti od troch vysvetľujúcich premenných:

Log GDP per capita – očakávame pozitívny vplyv (vyšší HDP → vyššia spokojnosť). Social support – očakávame pozitívny vplyv (silnejšie sociálne väzby → vyššia spokojnosť). Freedom to make life choices – očakávame pozitívny vplyv (väčšia sloboda → vyššia spokojnosť).

Moja hypotéza: Všetky tri premenné majú štatisticky významný pozitívny vplyv na index šťastia Life Ladder.

Príprava databázy, čistenie a úprava údajov

# Načítanie knižníc

library(dplyr)
library(ggplot2)
library(lmtest)
library(sandwich)
library(car)

# Načítanie dát
udaje <- read.csv("World Happiness Report 2005-2021.csv", sep = ",", header = TRUE)

# Výber relevantných premenných a odstránenie NA
model_data <- udaje %>%
  select(Life.Ladder, Log.GDP.per.capita, Social.support, Freedom.to.make.life.choices) %>%
  na.omit()

# Imputácia chýbajúcich hodnôt mediánom
column_medians <- sapply(model_data, median, na.rm = TRUE)

for (col in names(model_data)) {
  model_data[[col]][is.na(model_data[[col]])] <- column_medians[col]
}

# Overenie, že už nie sú NA
colSums(is.na(model_data))
                 Life.Ladder           Log.GDP.per.capita 
                           0                            0 
              Social.support Freedom.to.make.life.choices 
                           0                            0 
# Odhad lineárneho modelu
model <- lm(Life.Ladder ~ Log.GDP.per.capita + Social.support + Freedom.to.make.life.choices,
            data = model_data)

# Výsledky
summary(model)

Call:
lm(formula = Life.Ladder ~ Log.GDP.per.capita + Social.support + 
    Freedom.to.make.life.choices, data = model_data)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.27317 -0.35672  0.00259  0.41187  2.22420 

Coefficients:
                             Estimate Std. Error t value Pr(>|t|)    
(Intercept)                  -2.65882    0.11549  -23.02   <2e-16 ***
Log.GDP.per.capita            0.50668    0.01605   31.57   <2e-16 ***
Social.support                2.45235    0.15745   15.57   <2e-16 ***
Freedom.to.make.life.choices  1.86548    0.10448   17.86   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.5971 on 2019 degrees of freedom
Multiple R-squared:  0.7155,    Adjusted R-squared:  0.7151 
F-statistic:  1693 on 3 and 2019 DF,  p-value: < 2.2e-16
# Diagnostika multikolinearity
library(car)
vif(model)
          Log.GDP.per.capita               Social.support 
                    1.917155                     1.999493 
Freedom.to.make.life.choices 
                    1.216990 
# Diagnostické grafy
par(mfrow = c(2, 2))
plot(model)


# Nastavenie layoutu: 2 riadky × 2 stĺpce
par(mfrow = c(2, 2))
par(mar = c(4, 4, 2, 1))  # okraje

# Vyber relevantných premenných
udaje_box <- udaje %>%
  select(Life.Ladder, Log.GDP.per.capita, Social.support, Freedom.to.make.life.choices)

# Štandardizácia (z-score)
udaje_scaled <- as.data.frame(scale(udaje_box))

# Boxploty po štandardizácii
par(mar = c(4, 4, 2, 1))  # menšie okraje
boxplot(udaje_scaled$Life.Ladder, main = "Life Ladder (scaled)", col = "lightblue")
boxplot(udaje_scaled$Log.GDP.per.capita, main = "Log GDP (scaled)", col = "lightgreen")
boxplot(udaje_scaled$Social.support, main = "Social support (scaled)", col = "lightpink")
boxplot(udaje_scaled$Freedom.to.make.life.choices, main = "Freedom (scaled)", col = "lightyellow")


# Globálny nadpis
mtext("Boxploty vybraných premenných (2005–2021)", outer = TRUE, cex = 1.4, font = 2)

# Reset layoutu
par(mfrow = c(1, 1))


# Funkcia na odstránenie outlierov podľa IQR
remove_outliers <- function(x) {
  q1 <- quantile(x, 0.25, na.rm = TRUE)
  q3 <- quantile(x, 0.75, na.rm = TRUE)
  iqr <- q3 - q1
  lower <- q1 - 1.5 * iqr
  upper <- q3 + 1.5 * iqr
  x[x < lower | x > upper] <- NA
  return(x)
}

# Aplikácia na všetky vybrané stĺpce
udaje_clean <- udaje_box %>%
  mutate(
    Life.Ladder = remove_outliers(Life.Ladder),
    Log.GDP.per.capita = remove_outliers(Log.GDP.per.capita),
    Social.support = remove_outliers(Social.support),
    Freedom.to.make.life.choices = remove_outliers(Freedom.to.make.life.choices)
  )

# Odstránenie riadkov s NA po čistení
udaje_clean <- na.omit(udaje_clean)

# Overenie počtu riadkov pred a po čistení
cat("Pôvodný počet riadkov:", nrow(udaje_box), "\n")
Pôvodný počet riadkov: 2089 
cat("Po odstránení outlierov:", nrow(udaje_clean), "\n")
Po odstránení outlierov: 1970 
# Boxploty po odstránení outlierov
par(mfrow = c(2, 2))
boxplot(udaje_clean$Life.Ladder, main = "Life Ladder (cleaned)", col = "lightblue")
boxplot(udaje_clean$Log.GDP.per.capita, main = "Log GDP (cleaned)", col = "lightgreen")
boxplot(udaje_clean$Social.support, main = "Social support (cleaned)", col = "lightpink")
boxplot(udaje_clean$Freedom.to.make.life.choices, main = "Freedom (cleaned)", col = "lightyellow")
par(mfrow = c(1, 1))

## Lineárna regresia
model <- lm(Life.Ladder ~ +1 + Log.GDP.per.capita + Social.support + Freedom.to.make.life.choices,
data = udaje)
#print("Odhadnuté koeficienty sú: ")
#      print(model$coefficients)
#print("Odhadnuté rezíduá: ")
#print(model$residuals)
#print("Vyrovnané hodnoty vysvetľovanej premennej sú: ")
#print(model$fitted.values)
#print("matica model$xlevels: ")
#print(model.matrix(model))
#X <- model.matrix(model)
#diag(X %*% solve(t(X) %*% X) %*% t(X))

summary(model)

Call:
lm(formula = Life.Ladder ~ +1 + Log.GDP.per.capita + Social.support + 
    Freedom.to.make.life.choices, data = udaje)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.27317 -0.35672  0.00259  0.41187  2.22420 

Coefficients:
                             Estimate Std. Error t value Pr(>|t|)    
(Intercept)                  -2.65882    0.11549  -23.02   <2e-16 ***
Log.GDP.per.capita            0.50668    0.01605   31.57   <2e-16 ***
Social.support                2.45235    0.15745   15.57   <2e-16 ***
Freedom.to.make.life.choices  1.86548    0.10448   17.86   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.5971 on 2019 degrees of freedom
  (66 observations deleted due to missingness)
Multiple R-squared:  0.7155,    Adjusted R-squared:  0.7151 
F-statistic:  1693 on 3 and 2019 DF,  p-value: < 2.2e-16

Interpretácia výsledkov:

Výsledky lineárnej regresie ukázali, že všetky tri skúmané premenné – Log GDP per capita, Social support a Freedom to make life choices – majú na index šťastia (Life Ladder) pozitívny a štatisticky významný vplyv na hladine významnosti 1 %. Model možno zapísať nasledovne:

Interpretácia koeficientov naznačuje, že pri zvýšení logaritmu HDP na obyvateľa o jednu jednotku sa očakáva nárast indexu šťastia v priemere o 0,51 bodu, ak ostatné premenné zostanú nezmenené. Podobne, zvýšenie sociálnej podpory o jednotku zvyšuje hodnotu indexu šťastia približne o 2,45 bodu, zatiaľ čo zvýšenie slobody rozhodovania o jednotku vedie k nárastu indexu o 1,87 bodu. Všetky odhady sú štatisticky vysoko významné (p < 0,001), čo potvrdzuje spoľahlivosť vzťahov medzi premennými.

Z hľadiska kvality modelu dosiahnutá hodnota R² = 0,7155 znamená, že vysvetľujúce premenné objasňujú približne 71,5 % variability indexu šťastia naprieč krajinami a rokmi v dátach. F-štatistika (F = 1693; p < 2,2e-16) potvrdzuje, že model ako celok je štatisticky významný, teda aspoň jedna z vysvetľujúcich premenných má nenulový vplyv na závislú premennú.

Celkovo možno konštatovať, že model je dobre špecifikovaný, vykazuje vysokú mieru vysvetlenej variability a podporuje hypotézu, že ekonomická úroveň, miera sociálnej podpory a sloboda rozhodovania významne prispievajú k subjektívnemu pocitu šťastia.

# Nastavenie rozloženia 2 x 2

par(mfrow = c(2, 2))

# Diagnostické grafy pre tvoj model

plot(model)

# Pridať spoločný nadpis (voliteľné)

#mtext("Diagnostické grafy regresného modelu – Life Ladder", outer = TRUE, cex = 1.2, font = 2)

# Resetovanie rozloženia

par(mfrow = c(1, 1))

Interpretácia vášho konkrétneho grafu

Residuals vs Fitted:

Reziduály sú pomerne rovnomerne rozptýlené okolo nulovej osi, čo znamená, že model je dobre centrovaný a nevykazuje systematické skreslenie v predikciách. Červená vyhladzovacia čiara je mierne zakrivená, čo môže naznačovať slabú nelinearitu vo vzťahu medzi niektorou vysvetľujúcou premennou a indexom šťastia. Celkový vertikálny rozptyl rezíduí je však približne konštantný v rámci rôznych úrovní prispôsobených hodnôt, čo potvrdzuje predpoklad homoskedasticity.

Q–Q Residuals:

Body ležia veľmi blízko diagonálnej priamky, čo naznačuje, že rozdelenie rezíduí sa približuje normálnemu rozdeleniu. Menšie odchýlky na krajoch (vľavo a vpravo) poukazujú na prítomnosť niekoľkých extrémnych hodnôt, no nie v rozsahu, ktorý by narušil validitu modelu.

Scale–Location:

Rezíduá sú rozptýlené rovnomerne pozdĺž červenej čiary, ktorá zostáva takmer vodorovná. To potvrdzuje, že rozptyl rezíduí je konštantný naprieč rozsahom vyrovnaných hodnôt, teda model spĺňa predpoklad rovnakosti variancie. Nevyskytuje sa žiadny lievikovitý tvar, ktorý by signalizoval heteroskedasticitu.

Residuals vs Leverage:

Väčšina pozorovaní má nízky pákový efekt a nachádza sa v bezpečnom rozmedzí Cookovej vzdialenosti. Len niekoľko bodov (napr. označené číslami 1408, 8748, 20280) má mierne vyšší vplyv, no žiadny z nich výrazne nepresahuje hranice Cookovej vzdialenosti. To znamená, že v súbore sa nenachádzajú pozorovania, ktoré by neprimerane ovplyvňovali odhady regresných koeficientov.

Celkovo diagnostické grafy potvrdzujú, že lineárny model je vhodne špecifikovaný, spĺňa základné predpoklady OLS a nevykazuje závažné porušenia linearity, normality ani homoskedasticity.

# normality tests
residuals <- residuals(model)
jb_test <- jarque.bera.test(residuals)
jb_test

    Jarque Bera Test

data:  residuals
X-squared = 45.91, df = 2, p-value = 1.073e-10
# outlier test (see p-value for Bonferroni correction)
outlier_test <- outlierTest(model)
outlier_test
No Studentized residuals with Bonferroni p < 0.05
Largest |rstudent|:

Rezíduá sú približne normálne rozdelené, bez výrazných odľahlých hodnôt. Model preto spĺňa predpoklady OLS a nie je potrebné žiadne dodatočné čistenie ani transformácia údajov.

Záver

Výsledky lineárneho regresného modelu potvrdili, že všetky tri skúmané premenné – Log GDP per capita, Social support a Freedom to make life choices – majú pozitívny a štatisticky významný vplyv na index šťastia (Life Ladder). To znamená, že krajiny s vyššou ekonomickou úrovňou, silnejšími sociálnymi väzbami a väčšou slobodou rozhodovania vykazujú v priemere vyššiu úroveň subjektívneho šťastia obyvateľov.

Koeficient determinácie R² = 0.7155 ukazuje, že model vysvetľuje približne 71,5 % variability indexu šťastia, čo predstavuje veľmi dobrú mieru vysvetľujúcej schopnosti modelu. F-štatistika (F = 1693; p < 2.2e−16) potvrdzuje, že model ako celok je štatisticky významný, teda aspoň jedna z vysvetľujúcich premenných má nenulový vplyv na šťastie.

Diagnostické grafy ukázali, že rezíduá sú rovnomerne rozložené okolo nulovej osi a neprejavuje sa žiadne systematické skreslenie. Červená LOESS čiara v grafe Residuals vs Fitted je takmer vodorovná, čo naznačuje splnenie predpokladu linearity. Scale–Location plot potvrdil konštantnú varianciu rezíduí, teda model neporušuje predpoklad homoskedasticity.

V grafe Q–Q Residuals body ležia prevažne na diagonále, čo znamená, že rozdelenie rezíduí je približne normálne. Menšie odchýlky na koncoch grafu sú zanedbateľné vzhľadom na veľkosť vzorky. Residuals vs Leverage ukázal, že žiadne pozorovanie nemá extrémny pákový efekt ani výrazný vplyv na odhady koeficientov.

Outlier test (car::outlierTest) identifikoval jedno pozorovanie (č. 221) s hodnotou študentizovaného rezídua -3.82, ale po Bonferroniho korekcii (p = 0.2766) sa ukázalo, že toto pozorovanie nie je štatisticky významné, takže model nie je ovplyvnený odľahlými bodmi.

Potvrdenie hypotéz

Log GDP per capita – očakával sa pozitívny vplyv (vyšší HDP → vyššia spokojnosť). Koeficient (0.5067) je kladný a štatisticky významný (p < 0.001), čím sa hypotéza potvrdzuje.

Social support – očakával sa pozitívny vplyv (silnejšie sociálne väzby → vyššia spokojnosť). Koeficient (2.4523) je kladný a štatisticky významný (p < 0.001), teda hypotéza sa potvrdzuje.

Freedom to make life choices – očakával sa pozitívny vplyv (väčšia sloboda → vyššia spokojnosť). Koeficient (1.8655) je kladný a štatisticky významný (p < 0.001), preto aj táto hypotéza sa potvrdzuje.

Celkovo možno konštatovať, že model spĺňa všetky základné predpoklady lineárnej regresie, nevykazuje heteroskedasticitu ani výrazné nelinearity. Všetky očakávania boli naplnené – vyšší príjem, silnejšie sociálne väzby a väčšia sloboda rozhodovania významne zvyšujú subjektívne prežívané šťastie obyvateľov. Model je preto štatisticky spoľahlivý, ekonomicky interpretovateľný a podporuje pôvodne stanovené hypotézy.

Heteroskedasticita

library(ggplot2)
library(patchwork)

# Rezíduá z modelu
resid_sq <- resid(model)^2

# Grafy
p1 <- ggplot(model_data, aes(x = Log.GDP.per.capita, y = resid_sq)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "Log GDP per capita", y = "Squared Residuals", title = "Residuals vs Log GDP") +
  theme_minimal()

p2 <- ggplot(model_data, aes(x = Social.support, y = resid_sq)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "Social support", y = "Squared Residuals", title = "Residuals vs Social support") +
  theme_minimal()

p3 <- ggplot(model_data, aes(x = Freedom.to.make.life.choices, y = resid_sq)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "Freedom", y = "Squared Residuals", title = "Residuals vs Freedom") +
  theme_minimal()

# Zobrazenie vedľa seba
(p1 | p2) / p3

Skúmanie heteroskedasticity – vizuálna kontrola

Na obrázku vyššie sú zobrazené grafy závislosti štvorcov rezíduí od vysvetľujúcich premenných:

  • Residuals vs Log GDP per capita
  • Residuals vs Social support
  • Residuals vs Freedom to make life choices

Červená krivka je vo všetkých prípadoch takmer vodorovná, bez výrazného trendu. Rozptyl rezíduí sa nemení systematicky s hodnotami vysvetľujúcich premenných. Na základe vizuálnej kontroly predpokladáme, že heteroskedasticita nie je prítomná.

Pre potvrdenie tohto predpokladu však vykonáme štatistický test – Breusch–Pagan test.

library(lmtest)
bptest(model)

    studentized Breusch-Pagan test

data:  model
BP = 28.549, df = 3, p-value = 2.786e-06

Skúmanie heteroskedasticity – opis

Keďže p-hodnota < 0.05, zamietame nulovú hypotézu o homoskedasticite. To znamená, že v našom modeli je prítomná heteroskedasticita. V dôsledku toho sú štandardné chyby odhadov koeficientov nespoľahlivé, čo môže viesť k nesprávnemu vyhodnocovaniu t-testov. ## Skúmanie heteroskedasticity - White heteroskedasticity-consistent odhadov rozptylov (robustné štandardné chyby)


# Inštalácia balíkov
# install.packages("sandwich")
# install.packages("lmtest")

# Načítanie balíkov
library(sandwich)
library(lmtest)

# Robustné štandardné chyby (White HC1)
coeftest(model, vcov = vcovHC(model, type = "HC1"))

t test of coefficients:

                              Estimate Std. Error t value  Pr(>|t|)    
(Intercept)                  -2.658819   0.121783 -21.832 < 2.2e-16 ***
Log.GDP.per.capita            0.506678   0.016597  30.529 < 2.2e-16 ***
Social.support                2.452346   0.180362  13.597 < 2.2e-16 ***
Freedom.to.make.life.choices  1.865476   0.107661  17.327 < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# Koeficienty sa nezmenili (rovnaké ako v pôvodnom modeli). Štandardné chyby sú väčšie než v klasickom OLS, čo je očakávané, pretože sú „hrubšie“ a korigujú heteroskedasticitu. Všetky premenné zostávajú štatisticky významné (p < 0.001). Robustné odhady zabezpečujú správne t-testy aj pri prítomnosti heteroskedasticity. Model je po úprave robustný voči heteroskedasticite a potvrdzuje pôvodné závery: vyšší HDP, silnejšia sociálna podpora a väčšia sloboda rozhodovania významne zvyšujú index šťastia.

Porovnanie

# Načítanie potrebných balíkov
library(lmtest)
library(sandwich)

# Robustné štandardné chyby (White HC1)
robust_results <- coeftest(model, vcov = vcovHC(model, type = "HC1"))
print(robust_results)

t test of coefficients:

                              Estimate Std. Error t value  Pr(>|t|)    
(Intercept)                  -2.658819   0.121783 -21.832 < 2.2e-16 ***
Log.GDP.per.capita            0.506678   0.016597  30.529 < 2.2e-16 ***
Social.support                2.452346   0.180362  13.597 < 2.2e-16 ***
Freedom.to.make.life.choices  1.865476   0.107661  17.327 < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# Porovnanie pôvodných vs robustných štandardných chýb
original <- summary(model)$coefficients
comparison <- cbind(
  Estimate = original[, 1],
  OLS_Std_Error = original[, 2],
  Robust_Std_Error = robust_results[, 2]
)
print(comparison)
                              Estimate OLS_Std_Error Robust_Std_Error
(Intercept)                  -2.658819    0.11549077        0.1217828
Log.GDP.per.capita            0.506678    0.01605084        0.0165966
Social.support                2.452346    0.15745146        0.1803624
Freedom.to.make.life.choices  1.865476    0.10447731        0.1076607
# Na základe týchto výsledkov som sa rozhodol o vytvorenie nového modelu so zlogaritmizovanými všetkými premennými

Vytvorenie nového modelu

# Vytvorenie nových premenných
model_data$log_Social.support <- log(model_data$Social.support)
model_data$log_Freedom <- log(model_data$Freedom.to.make.life.choices)

# Nový model
model_log <- lm(Life.Ladder ~ Log.GDP.per.capita + log_Social.support + log_Freedom,
                data = model_data)

# Výsledky
summary(model_log)

Call:
lm(formula = Life.Ladder ~ Log.GDP.per.capita + log_Social.support + 
    log_Freedom, data = model_data)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.30858 -0.38490 -0.00582  0.42215  2.30771 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)         1.06339    0.16846   6.312 3.37e-10 ***
Log.GDP.per.capita  0.54597    0.01585  34.444  < 2e-16 ***
log_Social.support  1.49964    0.11107  13.501  < 2e-16 ***
log_Freedom         1.20170    0.07046  17.055  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.6109 on 2019 degrees of freedom
Multiple R-squared:  0.7022,    Adjusted R-squared:  0.7018 
F-statistic:  1587 on 3 and 2019 DF,  p-value: < 2.2e-16

Vizuálna kontrola nového modelu

library(ggplot2)
library(patchwork)

resid_sq_log <- resid(model_log)^2

p1 <- ggplot(model_data, aes(x = Log.GDP.per.capita, y = resid_sq_log)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "Log GDP per capita", y = "Squared Residuals", title = "Residuals vs Log GDP") +
  theme_minimal()

p2 <- ggplot(model_data, aes(x = log_Social.support, y = resid_sq_log)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "log(Social support)", y = "Squared Residuals", title = "Residuals vs log(Social support)") +
  theme_minimal()

p3 <- ggplot(model_data, aes(x = log_Freedom, y = resid_sq_log)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "log(Freedom)", y = "Squared Residuals", title = "Residuals vs log(Freedom)") +
  theme_minimal()

(p1 | p2) / p3

Skúmanie heteroskedasticity po logaritmizácii premenných

Na obrázku sú zobrazené grafy závislosti štvorcov rezíduí od vysvetľujúcich premenných po logaritmizácii Social support a Freedom to make life choices. Červená LOESS krivka ukazuje, že rozptyl rezíduí sa stále mení s hodnotami vysvetľujúcich premenných:

  • Pri Log GDP per capita je rozptyl výrazne klesajúci.
  • Pri log(Social support) je rozptyl výrazne klesajúci.
  • Pri log(Freedom) je rozptyl taktiež výrazne klesajúci. Všetky klesajúce trendy však nastávajú na ľavej strane grafu.

Záver:

Logaritmizácia premenných nezlepšila situáciu. Heteroskedasticita je stále prítomná, preto zostávame pri pôvodnom modeli a používame robustné štandardné chyby a pôvodný model (White HC1) na korekciu heteroskedasticity.

LS0tCnRpdGxlOiAiRWNvbm9tZXRyaWNzIGluIFIgLSBBbmFsw716YSDFocWlYXN0aWEiCmF1dGhvcjogIklnb3IgWmVsZW5heSIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgpTIHZ5dcW+aXTDrW0gZGF0YWLDoXp5IFtXb3JsZCBIYXBwaW5lc3MgcmVwb3J0XSAvIEhFVEVST1NLRURBU1RJQ0lUQSBOQSBLT05DSSBdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvamFoYWlkdWxpc2xhbS93b3JsZC1oYXBwaW5lc3MtcmVwb3J0LTIwMDUtMjAyMSkgZGF0YWJhc2UuCgpgYGB7cn0KbGlicmFyeSh6b28pCmxpYnJhcnkodHNlcmllcykKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoc2FuZHdpY2gpCmxpYnJhcnkoY2FyKQpybShsaXN0PWxzKCkpCmBgYAoKIyDDmnZvZCBkbyBwcm9ibMOpbXUsIHN0YW5vdmVuaWUgaHlwb3TDqXogCgpSb3pob2RvbCBzb20gc2EgbW9kZWxvdmHFpSBpbmRleCDFocWlYXN0aWEgTGlmZSBMYWRkZXIgdiB6w6F2aXNsb3N0aSBvZCB0cm9jaCB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoOgoKTG9nIEdEUCBwZXIgY2FwaXRhIOKAkyBvxI1ha8OhdmFtZSBwb3ppdMOtdm55IHZwbHl2ICh2ecWhxaHDrSBIRFAg4oaSIHZ5xaHFoWlhIHNwb2tvam5vc8WlKS4KU29jaWFsIHN1cHBvcnQg4oCTIG/EjWFrw6F2YW1lIHBveml0w612bnkgdnBseXYgKHNpbG5lasWhaWUgc29jacOhbG5lIHbDpHpieSDihpIgdnnFocWhaWEgc3Bva29qbm9zxaUpLgpGcmVlZG9tIHRvIG1ha2UgbGlmZSBjaG9pY2VzIOKAkyBvxI1ha8OhdmFtZSBwb3ppdMOtdm55IHZwbHl2ICh2w6TEjcWhaWEgc2xvYm9kYSDihpIgdnnFocWhaWEgc3Bva29qbm9zxaUpLgoKTW9qYSBoeXBvdMOpemE6IFbFoWV0a3kgdHJpIHByZW1lbm7DqSBtYWrDuiDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSBwb3ppdMOtdm55IHZwbHl2IG5hIGluZGV4IMWhxaVhc3RpYSBMaWZlIExhZGRlci4KCiMgUHLDrXByYXZhIGRhdGFiw6F6eSwgxI1pc3RlbmllIGEgw7pwcmF2YSDDumRham92CgpgYGB7cn0KIyBOYcSNw610YW5pZSBrbmnFvm7DrWMKCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoc2FuZHdpY2gpCmxpYnJhcnkoY2FyKQoKIyBOYcSNw610YW5pZSBkw6F0CnVkYWplIDwtIHJlYWQuY3N2KCJXb3JsZCBIYXBwaW5lc3MgUmVwb3J0IDIwMDUtMjAyMS5jc3YiLCBzZXAgPSAiLCIsIGhlYWRlciA9IFRSVUUpCgojIFbDvWJlciByZWxldmFudG7DvWNoIHByZW1lbm7DvWNoIGEgb2RzdHLDoW5lbmllIE5BCm1vZGVsX2RhdGEgPC0gdWRhamUgJT4lCiAgc2VsZWN0KExpZmUuTGFkZGVyLCBMb2cuR0RQLnBlci5jYXBpdGEsIFNvY2lhbC5zdXBwb3J0LCBGcmVlZG9tLnRvLm1ha2UubGlmZS5jaG9pY2VzKSAlPiUKICBuYS5vbWl0KCkKCiMgSW1wdXTDoWNpYSBjaMO9YmFqw7pjaWNoIGhvZG7DtHQgbWVkacOhbm9tCmNvbHVtbl9tZWRpYW5zIDwtIHNhcHBseShtb2RlbF9kYXRhLCBtZWRpYW4sIG5hLnJtID0gVFJVRSkKCmZvciAoY29sIGluIG5hbWVzKG1vZGVsX2RhdGEpKSB7CiAgbW9kZWxfZGF0YVtbY29sXV1baXMubmEobW9kZWxfZGF0YVtbY29sXV0pXSA8LSBjb2x1bW5fbWVkaWFuc1tjb2xdCn0KCiMgT3ZlcmVuaWUsIMW+ZSB1xb4gbmllIHPDuiBOQQpjb2xTdW1zKGlzLm5hKG1vZGVsX2RhdGEpKQoKIyBPZGhhZCBsaW5lw6FybmVobyBtb2RlbHUKbW9kZWwgPC0gbG0oTGlmZS5MYWRkZXIgfiBMb2cuR0RQLnBlci5jYXBpdGEgKyBTb2NpYWwuc3VwcG9ydCArIEZyZWVkb20udG8ubWFrZS5saWZlLmNob2ljZXMsCiAgICAgICAgICAgIGRhdGEgPSBtb2RlbF9kYXRhKQoKIyBWw71zbGVka3kKc3VtbWFyeShtb2RlbCkKCiMgRGlhZ25vc3Rpa2EgbXVsdGlrb2xpbmVhcml0eQpsaWJyYXJ5KGNhcikKdmlmKG1vZGVsKQoKIyBEaWFnbm9zdGlja8OpIGdyYWZ5CnBhcihtZnJvdyA9IGMoMiwgMikpCnBsb3QobW9kZWwpCgpgYGAKCgpgYGB7cn0KCiMgTmFzdGF2ZW5pZSBsYXlvdXR1OiAyIHJpYWRreSDDlyAyIHN0xLpwY2UKcGFyKG1mcm93ID0gYygyLCAyKSkKcGFyKG1hciA9IGMoNCwgNCwgMiwgMSkpICAjIG9rcmFqZQoKIyBWeWJlciByZWxldmFudG7DvWNoIHByZW1lbm7DvWNoCnVkYWplX2JveCA8LSB1ZGFqZSAlPiUKICBzZWxlY3QoTGlmZS5MYWRkZXIsIExvZy5HRFAucGVyLmNhcGl0YSwgU29jaWFsLnN1cHBvcnQsIEZyZWVkb20udG8ubWFrZS5saWZlLmNob2ljZXMpCgojIMWgdGFuZGFyZGl6w6FjaWEgKHotc2NvcmUpCnVkYWplX3NjYWxlZCA8LSBhcy5kYXRhLmZyYW1lKHNjYWxlKHVkYWplX2JveCkpCgojIEJveHBsb3R5IHBvIMWhdGFuZGFyZGl6w6FjaWkKcGFyKG1hciA9IGMoNCwgNCwgMiwgMSkpICAjIG1lbsWhaWUgb2tyYWplCmJveHBsb3QodWRhamVfc2NhbGVkJExpZmUuTGFkZGVyLCBtYWluID0gIkxpZmUgTGFkZGVyIChzY2FsZWQpIiwgY29sID0gImxpZ2h0Ymx1ZSIpCmJveHBsb3QodWRhamVfc2NhbGVkJExvZy5HRFAucGVyLmNhcGl0YSwgbWFpbiA9ICJMb2cgR0RQIChzY2FsZWQpIiwgY29sID0gImxpZ2h0Z3JlZW4iKQpib3hwbG90KHVkYWplX3NjYWxlZCRTb2NpYWwuc3VwcG9ydCwgbWFpbiA9ICJTb2NpYWwgc3VwcG9ydCAoc2NhbGVkKSIsIGNvbCA9ICJsaWdodHBpbmsiKQpib3hwbG90KHVkYWplX3NjYWxlZCRGcmVlZG9tLnRvLm1ha2UubGlmZS5jaG9pY2VzLCBtYWluID0gIkZyZWVkb20gKHNjYWxlZCkiLCBjb2wgPSAibGlnaHR5ZWxsb3ciKQoKCiMgR2xvYsOhbG55IG5hZHBpcwptdGV4dCgiQm94cGxvdHkgdnlicmFuw71jaCBwcmVtZW5uw71jaCAoMjAwNeKAkzIwMjEpIiwgb3V0ZXIgPSBUUlVFLCBjZXggPSAxLjQsIGZvbnQgPSAyKQoKIyBSZXNldCBsYXlvdXR1CnBhcihtZnJvdyA9IGMoMSwgMSkpCgpgYGAKYGBge3J9CgojIEZ1bmtjaWEgbmEgb2RzdHLDoW5lbmllIG91dGxpZXJvdiBwb2TEvmEgSVFSCnJlbW92ZV9vdXRsaWVycyA8LSBmdW5jdGlvbih4KSB7CiAgcTEgPC0gcXVhbnRpbGUoeCwgMC4yNSwgbmEucm0gPSBUUlVFKQogIHEzIDwtIHF1YW50aWxlKHgsIDAuNzUsIG5hLnJtID0gVFJVRSkKICBpcXIgPC0gcTMgLSBxMQogIGxvd2VyIDwtIHExIC0gMS41ICogaXFyCiAgdXBwZXIgPC0gcTMgKyAxLjUgKiBpcXIKICB4W3ggPCBsb3dlciB8IHggPiB1cHBlcl0gPC0gTkEKICByZXR1cm4oeCkKfQoKIyBBcGxpa8OhY2lhIG5hIHbFoWV0a3kgdnlicmFuw6kgc3TEunBjZQp1ZGFqZV9jbGVhbiA8LSB1ZGFqZV9ib3ggJT4lCiAgbXV0YXRlKAogICAgTGlmZS5MYWRkZXIgPSByZW1vdmVfb3V0bGllcnMoTGlmZS5MYWRkZXIpLAogICAgTG9nLkdEUC5wZXIuY2FwaXRhID0gcmVtb3ZlX291dGxpZXJzKExvZy5HRFAucGVyLmNhcGl0YSksCiAgICBTb2NpYWwuc3VwcG9ydCA9IHJlbW92ZV9vdXRsaWVycyhTb2NpYWwuc3VwcG9ydCksCiAgICBGcmVlZG9tLnRvLm1ha2UubGlmZS5jaG9pY2VzID0gcmVtb3ZlX291dGxpZXJzKEZyZWVkb20udG8ubWFrZS5saWZlLmNob2ljZXMpCiAgKQoKIyBPZHN0csOhbmVuaWUgcmlhZGtvdiBzIE5BIHBvIMSNaXN0ZW7DrQp1ZGFqZV9jbGVhbiA8LSBuYS5vbWl0KHVkYWplX2NsZWFuKQoKIyBPdmVyZW5pZSBwb8SNdHUgcmlhZGtvdiBwcmVkIGEgcG8gxI1pc3RlbsOtCmNhdCgiUMO0dm9kbsO9IHBvxI1ldCByaWFka292OiIsIG5yb3codWRhamVfYm94KSwgIlxuIikKY2F0KCJQbyBvZHN0csOhbmVuw60gb3V0bGllcm92OiIsIG5yb3codWRhamVfY2xlYW4pLCAiXG4iKQoKIyBCb3hwbG90eSBwbyBvZHN0csOhbmVuw60gb3V0bGllcm92CnBhcihtZnJvdyA9IGMoMiwgMikpCmJveHBsb3QodWRhamVfY2xlYW4kTGlmZS5MYWRkZXIsIG1haW4gPSAiTGlmZSBMYWRkZXIgKGNsZWFuZWQpIiwgY29sID0gImxpZ2h0Ymx1ZSIpCmJveHBsb3QodWRhamVfY2xlYW4kTG9nLkdEUC5wZXIuY2FwaXRhLCBtYWluID0gIkxvZyBHRFAgKGNsZWFuZWQpIiwgY29sID0gImxpZ2h0Z3JlZW4iKQpib3hwbG90KHVkYWplX2NsZWFuJFNvY2lhbC5zdXBwb3J0LCBtYWluID0gIlNvY2lhbCBzdXBwb3J0IChjbGVhbmVkKSIsIGNvbCA9ICJsaWdodHBpbmsiKQpib3hwbG90KHVkYWplX2NsZWFuJEZyZWVkb20udG8ubWFrZS5saWZlLmNob2ljZXMsIG1haW4gPSAiRnJlZWRvbSAoY2xlYW5lZCkiLCBjb2wgPSAibGlnaHR5ZWxsb3ciKQpwYXIobWZyb3cgPSBjKDEsIDEpKQoKYGBgCmBgYHtyfQojIyBMaW5lw6FybmEgcmVncmVzaWEKbW9kZWwgPC0gbG0oTGlmZS5MYWRkZXIgfiArMSArIExvZy5HRFAucGVyLmNhcGl0YSArIFNvY2lhbC5zdXBwb3J0ICsgRnJlZWRvbS50by5tYWtlLmxpZmUuY2hvaWNlcywKZGF0YSA9IHVkYWplKQojcHJpbnQoIk9kaGFkbnV0w6kga29lZmljaWVudHkgc8O6OiAiKQojICAgICAgcHJpbnQobW9kZWwkY29lZmZpY2llbnRzKQojcHJpbnQoIk9kaGFkbnV0w6kgcmV6w61kdcOhOiAiKQojcHJpbnQobW9kZWwkcmVzaWR1YWxzKQojcHJpbnQoIlZ5cm92bmFuw6kgaG9kbm90eSB2eXN2ZXTEvm92YW5laiBwcmVtZW5uZWogc8O6OiAiKQojcHJpbnQobW9kZWwkZml0dGVkLnZhbHVlcykKI3ByaW50KCJtYXRpY2EgbW9kZWwkeGxldmVsczogIikKI3ByaW50KG1vZGVsLm1hdHJpeChtb2RlbCkpCiNYIDwtIG1vZGVsLm1hdHJpeChtb2RlbCkKI2RpYWcoWCAlKiUgc29sdmUodChYKSAlKiUgWCkgJSolIHQoWCkpCgpzdW1tYXJ5KG1vZGVsKQoKYGBgCgoKSW50ZXJwcmV0w6FjaWEgdsO9c2xlZGtvdjoKClbDvXNsZWRreSBsaW5lw6FybmVqIHJlZ3Jlc2llIHVrw6F6YWxpLCDFvmUgdsWhZXRreSB0cmkgc2vDum1hbsOpIHByZW1lbm7DqSDigJMgTG9nIEdEUCBwZXIgY2FwaXRhLCBTb2NpYWwgc3VwcG9ydCBhIEZyZWVkb20gdG8gbWFrZSBsaWZlIGNob2ljZXMg4oCTIG1hasO6IG5hIGluZGV4IMWhxaVhc3RpYSAoTGlmZSBMYWRkZXIpIHBveml0w612bnkgYSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSB2cGx5diBuYSBobGFkaW5lIHbDvXpuYW1ub3N0aSAxICUuIE1vZGVsIG1vxb5ubyB6YXDDrXNhxaUgbmFzbGVkb3ZuZToKCkludGVycHJldMOhY2lhIGtvZWZpY2llbnRvdiBuYXpuYcSNdWplLCDFvmUgcHJpIHp2w73FoWVuw60gbG9nYXJpdG11IEhEUCBuYSBvYnl2YXRlxL5hIG8gamVkbnUgamVkbm90a3Ugc2Egb8SNYWvDoXZhIG7DoXJhc3QgaW5kZXh1IMWhxaVhc3RpYSB2IHByaWVtZXJlIG8gMCw1MSBib2R1LCBhayBvc3RhdG7DqSBwcmVtZW5uw6kgem9zdGFuw7ogbmV6bWVuZW7DqS4gUG9kb2JuZSwgenbDvcWhZW5pZSBzb2Npw6FsbmVqIHBvZHBvcnkgbyBqZWRub3RrdSB6dnnFoXVqZSBob2Rub3R1IGluZGV4dSDFocWlYXN0aWEgcHJpYmxpxb5uZSBvIDIsNDUgYm9kdSwgemF0aWHEviDEjW8genbDvcWhZW5pZSBzbG9ib2R5IHJvemhvZG92YW5pYSBvIGplZG5vdGt1IHZlZGllIGsgbsOhcmFzdHUgaW5kZXh1IG8gMSw4NyBib2R1LiBWxaFldGt5IG9kaGFkeSBzw7ogxaF0YXRpc3RpY2t5IHZ5c29rbyB2w716bmFtbsOpIChwIDwgMCwwMDEpLCDEjW8gcG90dnJkenVqZSBzcG/EvmFobGl2b3PFpSB2esWlYWhvdiBtZWR6aSBwcmVtZW5uw71taS4KClogaMS+YWRpc2thIGt2YWxpdHkgbW9kZWx1IGRvc2lhaG51dMOhIGhvZG5vdGEgUsKyID0gMCw3MTU1IHpuYW1lbsOhLCDFvmUgdnlzdmV0xL51asO6Y2UgcHJlbWVubsOpIG9iamFzxYh1asO6IHByaWJsacW+bmUgNzEsNSAlIHZhcmlhYmlsaXR5IGluZGV4dSDFocWlYXN0aWEgbmFwcmllxI0ga3JhamluYW1pIGEgcm9rbWkgdiBkw6F0YWNoLiBGLcWhdGF0aXN0aWthIChGID0gMTY5MzsgcCA8IDIsMmUtMTYpIHBvdHZyZHp1amUsIMW+ZSBtb2RlbCBha28gY2Vsb2sgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70sIHRlZGEgYXNwb8WIIGplZG5hIHogdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCBtw6EgbmVudWxvdsO9IHZwbHl2IG5hIHrDoXZpc2zDuiBwcmVtZW5uw7ouCgpDZWxrb3ZvIG1vxb5ubyBrb27FoXRhdG92YcWlLCDFvmUgbW9kZWwgamUgZG9icmUgxaFwZWNpZmlrb3ZhbsO9LCB2eWthenVqZSB2eXNva8O6IG1pZXJ1IHZ5c3ZldGxlbmVqIHZhcmlhYmlsaXR5IGEgcG9kcG9ydWplIGh5cG90w6l6dSwgxb5lIGVrb25vbWlja8OhIMO6cm92ZcWILCBtaWVyYSBzb2Npw6FsbmVqIHBvZHBvcnkgYSBzbG9ib2RhIHJvemhvZG92YW5pYSB2w716bmFtbmUgcHJpc3BpZXZhasO6IGsgc3ViamVrdMOtdm5lbXUgcG9jaXR1IMWhxaVhc3RpYS4KCmBgYHtyIGRpYWdwbG90cywgZmlnLmNhcD0iRGlhZ25vc3RpY2vDqSBncmFmeSByZWdyZXNuw6lobyBtb2RlbHUifQojIE5hc3RhdmVuaWUgcm96bG/FvmVuaWEgMiB4IDIKCnBhcihtZnJvdyA9IGMoMiwgMikpCgojIERpYWdub3N0aWNrw6kgZ3JhZnkgcHJlIHR2b2ogbW9kZWwKCnBsb3QobW9kZWwpCgojIFByaWRhxaUgc3BvbG/EjW7DvSBuYWRwaXMgKHZvbGl0ZcS+bsOpKQoKI210ZXh0KCJEaWFnbm9zdGlja8OpIGdyYWZ5IHJlZ3Jlc27DqWhvIG1vZGVsdSDigJMgTGlmZSBMYWRkZXIiLCBvdXRlciA9IFRSVUUsIGNleCA9IDEuMiwgZm9udCA9IDIpCgojIFJlc2V0b3ZhbmllIHJvemxvxb5lbmlhCgpwYXIobWZyb3cgPSBjKDEsIDEpKQoKYGBgCiMjIyBJbnRlcnByZXTDoWNpYSB2w6HFoWhvIGtvbmtyw6l0bmVobyBncmFmdQoKIyMgUmVzaWR1YWxzIHZzIEZpdHRlZDoKUmV6aWR1w6FseSBzw7ogcG9tZXJuZSByb3Zub21lcm5lIHJvenB0w71sZW7DqSBva29sbyBudWxvdmVqIG9zaSwgxI1vIHpuYW1lbsOhLCDFvmUgbW9kZWwgamUgZG9icmUgY2VudHJvdmFuw70gYSBuZXZ5a2F6dWplIHN5c3RlbWF0aWNrw6kgc2tyZXNsZW5pZSB2IHByZWRpa2Npw6FjaC4gxIxlcnZlbsOhIHZ5aGxhZHpvdmFjaWEgxI1pYXJhIGplIG1pZXJuZSB6YWtyaXZlbsOhLCDEjW8gbcO0xb5lIG5hem5hxI1vdmHFpSBzbGFiw7ogbmVsaW5lYXJpdHUgdm8gdnrFpWFodSBtZWR6aSBuaWVrdG9yb3UgdnlzdmV0xL51asO6Y291IHByZW1lbm5vdSBhIGluZGV4b20gxaHFpWFzdGlhLiBDZWxrb3bDvSB2ZXJ0aWvDoWxueSByb3pwdHlsIHJlesOtZHXDrSBqZSB2xaFhayBwcmlibGnFvm5lIGtvbsWhdGFudG7DvSB2IHLDoW1jaSByw7R6bnljaCDDunJvdm7DrSBwcmlzcMO0c29iZW7DvWNoIGhvZG7DtHQsIMSNbyBwb3R2cmR6dWplIHByZWRwb2tsYWQgaG9tb3NrZWRhc3RpY2l0eS4KCiMjIFHigJNRIFJlc2lkdWFsczoKQm9keSBsZcW+aWEgdmXEvm1pIGJsw616a28gZGlhZ29uw6FsbmVqIHByaWFta3ksIMSNbyBuYXpuYcSNdWplLCDFvmUgcm96ZGVsZW5pZSByZXrDrWR1w60gc2EgcHJpYmxpxb51amUgbm9ybcOhbG5lbXUgcm96ZGVsZW5pdS4gTWVuxaFpZSBvZGNow71sa3kgbmEga3Jham9jaCAodsS+YXZvIGEgdnByYXZvKSBwb3VrYXp1asO6IG5hIHByw610b21ub3PFpSBuaWVrb8S+a8O9Y2ggZXh0csOpbW55Y2ggaG9kbsO0dCwgbm8gbmllIHYgcm96c2FodSwga3RvcsO9IGJ5IG5hcnXFoWlsIHZhbGlkaXR1IG1vZGVsdS4KCiMjIFNjYWxl4oCTTG9jYXRpb246ClJlesOtZHXDoSBzw7ogcm96cHTDvWxlbsOpIHJvdm5vbWVybmUgcG96ZMS6xb4gxI1lcnZlbmVqIMSNaWFyeSwga3RvcsOhIHpvc3TDoXZhIHRha21lciB2b2Rvcm92bsOhLiBUbyBwb3R2cmR6dWplLCDFvmUgcm96cHR5bCByZXrDrWR1w60gamUga29uxaF0YW50bsO9IG5hcHJpZcSNIHJvenNhaG9tIHZ5cm92bmFuw71jaCBob2Ruw7R0LCB0ZWRhIG1vZGVsIHNwxLrFiGEgcHJlZHBva2xhZCByb3ZuYWtvc3RpIHZhcmlhbmNpZS4gTmV2eXNreXR1amUgc2Egxb5pYWRueSBsaWV2aWtvdml0w70gdHZhciwga3RvcsO9IGJ5IHNpZ25hbGl6b3ZhbCBoZXRlcm9za2VkYXN0aWNpdHUuCgojIyBSZXNpZHVhbHMgdnMgTGV2ZXJhZ2U6ClbDpMSNxaFpbmEgcG96b3JvdmFuw60gbcOhIG7DrXpreSBww6Frb3bDvSBlZmVrdCBhIG5hY2jDoWR6YSBzYSB2IGJlenBlxI1ub20gcm96bWVkesOtIENvb2tvdmVqIHZ6ZGlhbGVub3N0aS4gTGVuIG5pZWtvxL5rbyBib2RvdiAobmFwci4gb3puYcSNZW7DqSDEjcOtc2xhbWkgMTQwOCwgODc0OCwgMjAyODApIG3DoSBtaWVybmUgdnnFocWhw60gdnBseXYsIG5vIMW+aWFkbnkgeiBuaWNoIHbDvXJhem5lIG5lcHJlc2FodWplIGhyYW5pY2UgQ29va292ZWogdnpkaWFsZW5vc3RpLiBUbyB6bmFtZW7DoSwgxb5lIHYgc8O6Ym9yZSBzYSBuZW5hY2jDoWR6YWrDuiBwb3pvcm92YW5pYSwga3RvcsOpIGJ5IG5lcHJpbWVyYW5lIG92cGx5dsWIb3ZhbGkgb2RoYWR5IHJlZ3Jlc27DvWNoIGtvZWZpY2llbnRvdi4KCkNlbGtvdm8gZGlhZ25vc3RpY2vDqSBncmFmeSBwb3R2cmR6dWrDuiwgxb5lIGxpbmXDoXJueSBtb2RlbCBqZSB2aG9kbmUgxaFwZWNpZmlrb3ZhbsO9LCBzcMS6xYhhIHrDoWtsYWRuw6kgcHJlZHBva2xhZHkgT0xTIGEgbmV2eWthenVqZSB6w6F2YcW+bsOpIHBvcnXFoWVuaWEgbGluZWFyaXR5LCBub3JtYWxpdHkgYW5pIGhvbW9za2VkYXN0aWNpdHkuCmBgYHtyfQojIG5vcm1hbGl0eSB0ZXN0cwpyZXNpZHVhbHMgPC0gcmVzaWR1YWxzKG1vZGVsKQpqYl90ZXN0IDwtIGphcnF1ZS5iZXJhLnRlc3QocmVzaWR1YWxzKQpqYl90ZXN0CiMgb3V0bGllciB0ZXN0IChzZWUgcC12YWx1ZSBmb3IgQm9uZmVycm9uaSBjb3JyZWN0aW9uKQpvdXRsaWVyX3Rlc3QgPC0gb3V0bGllclRlc3QobW9kZWwpCm91dGxpZXJfdGVzdApgYGAKUmV6w61kdcOhIHPDuiBwcmlibGnFvm5lIG5vcm3DoWxuZSByb3pkZWxlbsOpLCBiZXogdsO9cmF6bsO9Y2ggb2TEvmFobMO9Y2ggaG9kbsO0dC4KTW9kZWwgcHJldG8gc3DEusWIYSBwcmVkcG9rbGFkeSBPTFMgYSBuaWUgamUgcG90cmVibsOpIMW+aWFkbmUgZG9kYXRvxI1uw6kgxI1pc3RlbmllIGFuaSB0cmFuc2Zvcm3DoWNpYSDDumRham92LgoKIyMgWsOhdmVyClbDvXNsZWRreSBsaW5lw6FybmVobyByZWdyZXNuw6lobyBtb2RlbHUgcG90dnJkaWxpLCDFvmUgdsWhZXRreSB0cmkgc2vDum1hbsOpIHByZW1lbm7DqSDigJMgTG9nIEdEUCBwZXIgY2FwaXRhLCBTb2NpYWwgc3VwcG9ydCBhIEZyZWVkb20gdG8gbWFrZSBsaWZlIGNob2ljZXMg4oCTIG1hasO6IHBveml0w612bnkgYSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSB2cGx5diBuYSBpbmRleCDFocWlYXN0aWEgKExpZmUgTGFkZGVyKS4gVG8gem5hbWVuw6EsIMW+ZSBrcmFqaW55IHMgdnnFocWhb3UgZWtvbm9taWNrb3Ugw7pyb3bFiG91LCBzaWxuZWrFocOtbWkgc29jacOhbG55bWkgdsOkemJhbWkgYSB2w6TEjcWhb3Ugc2xvYm9kb3Ugcm96aG9kb3ZhbmlhIHZ5a2F6dWrDuiB2IHByaWVtZXJlIHZ5xaHFoWl1IMO6cm92ZcWIIHN1Ympla3TDrXZuZWhvIMWhxaVhc3RpYSBvYnl2YXRlxL5vdi4KCktvZWZpY2llbnQgZGV0ZXJtaW7DoWNpZSBSwrIgPSAwLjcxNTUgdWthenVqZSwgxb5lIG1vZGVsIHZ5c3ZldMS+dWplIHByaWJsacW+bmUgNzEsNSAlIHZhcmlhYmlsaXR5IGluZGV4dSDFocWlYXN0aWEsIMSNbyBwcmVkc3RhdnVqZSB2ZcS+bWkgZG9icsO6IG1pZXJ1IHZ5c3ZldMS+dWrDumNlaiBzY2hvcG5vc3RpIG1vZGVsdS4gRi3FoXRhdGlzdGlrYSAoRiA9IDE2OTM7IHAgPCAyLjJl4oiSMTYpIHBvdHZyZHp1amUsIMW+ZSBtb2RlbCBha28gY2Vsb2sgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70sIHRlZGEgYXNwb8WIIGplZG5hIHogdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCBtw6EgbmVudWxvdsO9IHZwbHl2IG5hIMWhxaVhc3RpZS4KCkRpYWdub3N0aWNrw6kgZ3JhZnkgdWvDoXphbGksIMW+ZSByZXrDrWR1w6Egc8O6IHJvdm5vbWVybmUgcm96bG/FvmVuw6kgb2tvbG8gbnVsb3ZlaiBvc2kgYSBuZXByZWphdnVqZSBzYSDFvmlhZG5lIHN5c3RlbWF0aWNrw6kgc2tyZXNsZW5pZS4gxIxlcnZlbsOhIExPRVNTIMSNaWFyYSB2IGdyYWZlIFJlc2lkdWFscyB2cyBGaXR0ZWQgamUgdGFrbWVyIHZvZG9yb3Zuw6EsIMSNbyBuYXpuYcSNdWplIHNwbG5lbmllIHByZWRwb2tsYWR1IGxpbmVhcml0eS4gU2NhbGXigJNMb2NhdGlvbiBwbG90IHBvdHZyZGlsIGtvbsWhdGFudG7DuiB2YXJpYW5jaXUgcmV6w61kdcOtLCB0ZWRhIG1vZGVsIG5lcG9ydcWhdWplIHByZWRwb2tsYWQgaG9tb3NrZWRhc3RpY2l0eS4KClYgZ3JhZmUgUeKAk1EgUmVzaWR1YWxzIGJvZHkgbGXFvmlhIHByZXZhxb5uZSBuYSBkaWFnb27DoWxlLCDEjW8gem5hbWVuw6EsIMW+ZSByb3pkZWxlbmllIHJlesOtZHXDrSBqZSBwcmlibGnFvm5lIG5vcm3DoWxuZS4gTWVuxaFpZSBvZGNow71sa3kgbmEga29uY29jaCBncmFmdSBzw7ogemFuZWRiYXRlxL5uw6kgdnpoxL5hZG9tIG5hIHZlxL5rb3PFpSB2em9ya3kuIFJlc2lkdWFscyB2cyBMZXZlcmFnZSB1a8OhemFsLCDFvmUgxb5pYWRuZSBwb3pvcm92YW5pZSBuZW3DoSBleHRyw6ltbnkgcMOha292w70gZWZla3QgYW5pIHbDvXJhem7DvSB2cGx5diBuYSBvZGhhZHkga29lZmljaWVudG92LgoKT3V0bGllciB0ZXN0IChjYXI6Om91dGxpZXJUZXN0KSBpZGVudGlmaWtvdmFsIGplZG5vIHBvem9yb3ZhbmllICjEjS4gMjIxKSBzIGhvZG5vdG91IMWhdHVkZW50aXpvdmFuw6lobyByZXrDrWR1YSAtMy44MiwgYWxlIHBvIEJvbmZlcnJvbmlobyBrb3Jla2NpaSAocCA9IDAuMjc2Nikgc2EgdWvDoXphbG8sIMW+ZSB0b3RvIHBvem9yb3ZhbmllIG5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DqSwgdGFrxb5lIG1vZGVsIG5pZSBqZSBvdnBseXZuZW7DvSBvZMS+YWhsw71taSBib2RtaS4KClBvdHZyZGVuaWUgaHlwb3TDqXoKCkxvZyBHRFAgcGVyIGNhcGl0YSDigJMgb8SNYWvDoXZhbCBzYSBwb3ppdMOtdm55IHZwbHl2ICh2ecWhxaHDrSBIRFAg4oaSIHZ5xaHFoWlhIHNwb2tvam5vc8WlKS4gS29lZmljaWVudCAoMC41MDY3KSBqZSBrbGFkbsO9IGEgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gKHAgPCAwLjAwMSksIMSNw61tIHNhIGh5cG90w6l6YSBwb3R2cmR6dWplLgoKU29jaWFsIHN1cHBvcnQg4oCTIG/EjWFrw6F2YWwgc2EgcG96aXTDrXZueSB2cGx5diAoc2lsbmVqxaFpZSBzb2Npw6FsbmUgdsOkemJ5IOKGkiB2ecWhxaFpYSBzcG9rb2pub3PFpSkuIEtvZWZpY2llbnQgKDIuNDUyMykgamUga2xhZG7DvSBhIMWhdGF0aXN0aWNreSB2w716bmFtbsO9IChwIDwgMC4wMDEpLCB0ZWRhIGh5cG90w6l6YSBzYSBwb3R2cmR6dWplLgoKRnJlZWRvbSB0byBtYWtlIGxpZmUgY2hvaWNlcyDigJMgb8SNYWvDoXZhbCBzYSBwb3ppdMOtdm55IHZwbHl2ICh2w6TEjcWhaWEgc2xvYm9kYSDihpIgdnnFocWhaWEgc3Bva29qbm9zxaUpLiBLb2VmaWNpZW50ICgxLjg2NTUpIGplIGtsYWRuw70gYSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSAocCA8IDAuMDAxKSwgcHJldG8gYWogdMOhdG8gaHlwb3TDqXphIHNhIHBvdHZyZHp1amUuCgpDZWxrb3ZvIG1vxb5ubyBrb27FoXRhdG92YcWlLCDFvmUgbW9kZWwgc3DEusWIYSB2xaFldGt5IHrDoWtsYWRuw6kgcHJlZHBva2xhZHkgbGluZcOhcm5laiByZWdyZXNpZSwgbmV2eWthenVqZSBoZXRlcm9za2VkYXN0aWNpdHUgYW5pIHbDvXJhem7DqSBuZWxpbmVhcml0eS4gVsWhZXRreSBvxI1ha8OhdmFuaWEgYm9saSBuYXBsbmVuw6kg4oCTIHZ5xaHFocOtIHByw61qZW0sIHNpbG5lasWhaWUgc29jacOhbG5lIHbDpHpieSBhIHbDpMSNxaFpYSBzbG9ib2RhIHJvemhvZG92YW5pYSB2w716bmFtbmUgenZ5xaF1asO6IHN1Ympla3TDrXZuZSBwcmXFvsOtdmFuw6kgxaHFpWFzdGllIG9ieXZhdGXEvm92LiBNb2RlbCBqZSBwcmV0byDFoXRhdGlzdGlja3kgc3BvxL5haGxpdsO9LCBla29ub21pY2t5IGludGVycHJldG92YXRlxL5uw70gYSBwb2Rwb3J1amUgcMO0dm9kbmUgc3Rhbm92ZW7DqSBoeXBvdMOpenkuCgojIyBIZXRlcm9za2VkYXN0aWNpdGEKCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGF0Y2h3b3JrKQoKIyBSZXrDrWR1w6EgeiBtb2RlbHUKcmVzaWRfc3EgPC0gcmVzaWQobW9kZWwpXjIKCiMgR3JhZnkKcDEgPC0gZ2dwbG90KG1vZGVsX2RhdGEsIGFlcyh4ID0gTG9nLkdEUC5wZXIuY2FwaXRhLCB5ID0gcmVzaWRfc3EpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKHggPSAiTG9nIEdEUCBwZXIgY2FwaXRhIiwgeSA9ICJTcXVhcmVkIFJlc2lkdWFscyIsIHRpdGxlID0gIlJlc2lkdWFscyB2cyBMb2cgR0RQIikgKwogIHRoZW1lX21pbmltYWwoKQoKcDIgPC0gZ2dwbG90KG1vZGVsX2RhdGEsIGFlcyh4ID0gU29jaWFsLnN1cHBvcnQsIHkgPSByZXNpZF9zcSkpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoeCA9ICJTb2NpYWwgc3VwcG9ydCIsIHkgPSAiU3F1YXJlZCBSZXNpZHVhbHMiLCB0aXRsZSA9ICJSZXNpZHVhbHMgdnMgU29jaWFsIHN1cHBvcnQiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwMyA8LSBnZ3Bsb3QobW9kZWxfZGF0YSwgYWVzKHggPSBGcmVlZG9tLnRvLm1ha2UubGlmZS5jaG9pY2VzLCB5ID0gcmVzaWRfc3EpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKHggPSAiRnJlZWRvbSIsIHkgPSAiU3F1YXJlZCBSZXNpZHVhbHMiLCB0aXRsZSA9ICJSZXNpZHVhbHMgdnMgRnJlZWRvbSIpICsKICB0aGVtZV9taW5pbWFsKCkKCiMgWm9icmF6ZW5pZSB2ZWTEvmEgc2ViYQoocDEgfCBwMikgLyBwMwpgYGAKIyMgU2vDum1hbmllIGhldGVyb3NrZWRhc3RpY2l0eSDigJMgdml6dcOhbG5hIGtvbnRyb2xhCgpOYSBvYnLDoXprdSB2ecWhxaFpZSBzw7ogem9icmF6ZW7DqSBncmFmeSB6w6F2aXNsb3N0aSDFoXR2b3Jjb3YgcmV6w61kdcOtIG9kIHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2g6CgotICoqUmVzaWR1YWxzIHZzIExvZyBHRFAgcGVyIGNhcGl0YSoqCi0gKipSZXNpZHVhbHMgdnMgU29jaWFsIHN1cHBvcnQqKgotICoqUmVzaWR1YWxzIHZzIEZyZWVkb20gdG8gbWFrZSBsaWZlIGNob2ljZXMqKgoKxIxlcnZlbsOhIGtyaXZrYSBqZSB2byB2xaFldGvDvWNoIHByw61wYWRvY2ggdGFrbWVyIHZvZG9yb3Zuw6EsIGJleiB2w71yYXpuw6lobyB0cmVuZHUuIFJvenB0eWwgcmV6w61kdcOtIHNhIG5lbWVuw60gc3lzdGVtYXRpY2t5IHMgaG9kbm90YW1pIHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2guIE5hIHrDoWtsYWRlIHZpenXDoWxuZWoga29udHJvbHkgKipwcmVkcG9rbGFkw6FtZSwgxb5lIGhldGVyb3NrZWRhc3RpY2l0YSBuaWUgamUgcHLDrXRvbW7DoSoqLgoKUHJlIHBvdHZyZGVuaWUgdG9odG8gcHJlZHBva2xhZHUgdsWhYWsgdnlrb27DoW1lIMWhdGF0aXN0aWNrw70gdGVzdCDigJMgKipCcmV1c2No4oCTUGFnYW4gdGVzdCoqLgoKYGBge3J9CmxpYnJhcnkobG10ZXN0KQpicHRlc3QobW9kZWwpCmBgYAojIyBTa8O6bWFuaWUgaGV0ZXJvc2tlZGFzdGljaXR5IOKAkyBvcGlzCktlxI/FvmUgcC1ob2Rub3RhIDwgMC4wNSwgemFtaWV0YW1lIG51bG92w7ogaHlwb3TDqXp1IG8gaG9tb3NrZWRhc3RpY2l0ZS4gVG8gem5hbWVuw6EsIMW+ZSB2IG5hxaFvbSBtb2RlbGkgamUgcHLDrXRvbW7DoSBoZXRlcm9za2VkYXN0aWNpdGEuIFYgZMO0c2xlZGt1IHRvaG8gc8O6IMWhdGFuZGFyZG7DqSBjaHlieSBvZGhhZG92IGtvZWZpY2llbnRvdiBuZXNwb8S+YWhsaXbDqSwgxI1vIG3DtMW+ZSB2aWVzxaUgayBuZXNwcsOhdm5lbXUgdnlob2Rub2NvdmFuaXUgdC10ZXN0b3YuCiMjIFNrw7ptYW5pZSBoZXRlcm9za2VkYXN0aWNpdHkgLSBXaGl0ZSBoZXRlcm9za2VkYXN0aWNpdHktY29uc2lzdGVudCBvZGhhZG92IHJvenB0eWxvdiAocm9idXN0bsOpIMWhdGFuZGFyZG7DqSBjaHlieSkKCmBgYHtyfQojIEluxaF0YWzDoWNpYSBiYWzDrWtvdgojIGluc3RhbGwucGFja2FnZXMoInNhbmR3aWNoIikKIyBpbnN0YWxsLnBhY2thZ2VzKCJsbXRlc3QiKQoKIyBOYcSNw610YW5pZSBiYWzDrWtvdgpsaWJyYXJ5KHNhbmR3aWNoKQpsaWJyYXJ5KGxtdGVzdCkKCiMgUm9idXN0bsOpIMWhdGFuZGFyZG7DqSBjaHlieSAoV2hpdGUgSEMxKQpjb2VmdGVzdChtb2RlbCwgdmNvdiA9IHZjb3ZIQyhtb2RlbCwgdHlwZSA9ICJIQzEiKSkKYGBgCgpgYGB7cn0KIyBLb2VmaWNpZW50eSBzYSBuZXptZW5pbGkgKHJvdm5ha8OpIGFrbyB2IHDDtHZvZG5vbSBtb2RlbGkpLiDFoHRhbmRhcmRuw6kgY2h5Ynkgc8O6IHbDpMSNxaFpZSBuZcW+IHYga2xhc2lja29tIE9MUywgxI1vIGplIG/EjWFrw6F2YW7DqSwgcHJldG/FvmUgc8O6IOKAnmhydWLFoWll4oCcIGEga29yaWd1asO6IGhldGVyb3NrZWRhc3RpY2l0dS4gVsWhZXRreSBwcmVtZW5uw6kgem9zdMOhdmFqw7ogxaF0YXRpc3RpY2t5IHbDvXpuYW1uw6kgKHAgPCAwLjAwMSkuIFJvYnVzdG7DqSBvZGhhZHkgemFiZXpwZcSNdWrDuiBzcHLDoXZuZSB0LXRlc3R5IGFqIHByaSBwcsOtdG9tbm9zdGkgaGV0ZXJvc2tlZGFzdGljaXR5LiBNb2RlbCBqZSBwbyDDunByYXZlIHJvYnVzdG7DvSB2b8SNaSBoZXRlcm9za2VkYXN0aWNpdGUgYSBwb3R2cmR6dWplIHDDtHZvZG7DqSB6w6F2ZXJ5OiB2ecWhxaHDrSBIRFAsIHNpbG5lasWhaWEgc29jacOhbG5hIHBvZHBvcmEgYSB2w6TEjcWhaWEgc2xvYm9kYSByb3pob2RvdmFuaWEgdsO9em5hbW5lIHp2ecWhdWrDuiBpbmRleCDFocWlYXN0aWEuCmBgYAoKIyMgUG9yb3ZuYW5pZQoKYGBge3J9CiMgTmHEjcOtdGFuaWUgcG90cmVibsO9Y2ggYmFsw61rb3YKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoc2FuZHdpY2gpCgojIFJvYnVzdG7DqSDFoXRhbmRhcmRuw6kgY2h5YnkgKFdoaXRlIEhDMSkKcm9idXN0X3Jlc3VsdHMgPC0gY29lZnRlc3QobW9kZWwsIHZjb3YgPSB2Y292SEMobW9kZWwsIHR5cGUgPSAiSEMxIikpCnByaW50KHJvYnVzdF9yZXN1bHRzKQoKIyBQb3Jvdm5hbmllIHDDtHZvZG7DvWNoIHZzIHJvYnVzdG7DvWNoIMWhdGFuZGFyZG7DvWNoIGNow71iCm9yaWdpbmFsIDwtIHN1bW1hcnkobW9kZWwpJGNvZWZmaWNpZW50cwpjb21wYXJpc29uIDwtIGNiaW5kKAogIEVzdGltYXRlID0gb3JpZ2luYWxbLCAxXSwKICBPTFNfU3RkX0Vycm9yID0gb3JpZ2luYWxbLCAyXSwKICBSb2J1c3RfU3RkX0Vycm9yID0gcm9idXN0X3Jlc3VsdHNbLCAyXQopCnByaW50KGNvbXBhcmlzb24pCmBgYAoKYGBge3J9CiMgTmEgesOha2xhZGUgdMO9Y2h0byB2w71zbGVka292IHNvbSBzYSByb3pob2RvbCBvIHZ5dHZvcmVuaWUgbm92w6lobyBtb2RlbHUgc28gemxvZ2FyaXRtaXpvdmFuw71taSB2xaFldGvDvW1pIHByZW1lbm7DvW1pCmBgYAoKIyMgVnl0dm9yZW5pZSBub3bDqWhvIG1vZGVsdQoKYGBge3J9CiMgVnl0dm9yZW5pZSBub3bDvWNoIHByZW1lbm7DvWNoCm1vZGVsX2RhdGEkbG9nX1NvY2lhbC5zdXBwb3J0IDwtIGxvZyhtb2RlbF9kYXRhJFNvY2lhbC5zdXBwb3J0KQptb2RlbF9kYXRhJGxvZ19GcmVlZG9tIDwtIGxvZyhtb2RlbF9kYXRhJEZyZWVkb20udG8ubWFrZS5saWZlLmNob2ljZXMpCgojIE5vdsO9IG1vZGVsCm1vZGVsX2xvZyA8LSBsbShMaWZlLkxhZGRlciB+IExvZy5HRFAucGVyLmNhcGl0YSArIGxvZ19Tb2NpYWwuc3VwcG9ydCArIGxvZ19GcmVlZG9tLAogICAgICAgICAgICAgICAgZGF0YSA9IG1vZGVsX2RhdGEpCgojIFbDvXNsZWRreQpzdW1tYXJ5KG1vZGVsX2xvZykKYGBgCgojIyBWaXp1w6FsbmEga29udHJvbGEgbm92w6lobyBtb2RlbHUKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwYXRjaHdvcmspCgpyZXNpZF9zcV9sb2cgPC0gcmVzaWQobW9kZWxfbG9nKV4yCgpwMSA8LSBnZ3Bsb3QobW9kZWxfZGF0YSwgYWVzKHggPSBMb2cuR0RQLnBlci5jYXBpdGEsIHkgPSByZXNpZF9zcV9sb2cpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKHggPSAiTG9nIEdEUCBwZXIgY2FwaXRhIiwgeSA9ICJTcXVhcmVkIFJlc2lkdWFscyIsIHRpdGxlID0gIlJlc2lkdWFscyB2cyBMb2cgR0RQIikgKwogIHRoZW1lX21pbmltYWwoKQoKcDIgPC0gZ2dwbG90KG1vZGVsX2RhdGEsIGFlcyh4ID0gbG9nX1NvY2lhbC5zdXBwb3J0LCB5ID0gcmVzaWRfc3FfbG9nKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJyZWQiKSArCiAgbGFicyh4ID0gImxvZyhTb2NpYWwgc3VwcG9ydCkiLCB5ID0gIlNxdWFyZWQgUmVzaWR1YWxzIiwgdGl0bGUgPSAiUmVzaWR1YWxzIHZzIGxvZyhTb2NpYWwgc3VwcG9ydCkiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwMyA8LSBnZ3Bsb3QobW9kZWxfZGF0YSwgYWVzKHggPSBsb2dfRnJlZWRvbSwgeSA9IHJlc2lkX3NxX2xvZykpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoeCA9ICJsb2coRnJlZWRvbSkiLCB5ID0gIlNxdWFyZWQgUmVzaWR1YWxzIiwgdGl0bGUgPSAiUmVzaWR1YWxzIHZzIGxvZyhGcmVlZG9tKSIpICsKICB0aGVtZV9taW5pbWFsKCkKCihwMSB8IHAyKSAvIHAzCmBgYAoKIyMgU2vDum1hbmllIGhldGVyb3NrZWRhc3RpY2l0eSBwbyBsb2dhcml0bWl6w6FjaWkgcHJlbWVubsO9Y2gKCk5hIG9icsOhemt1IHPDuiB6b2JyYXplbsOpIGdyYWZ5IHrDoXZpc2xvc3RpIMWhdHZvcmNvdiByZXrDrWR1w60gb2QgdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCBwbyBsb2dhcml0bWl6w6FjaWkgU29jaWFsIHN1cHBvcnQgYSBGcmVlZG9tIHRvIG1ha2UgbGlmZSBjaG9pY2VzLiDEjGVydmVuw6EgTE9FU1Mga3JpdmthIHVrYXp1amUsIMW+ZSByb3pwdHlsIHJlesOtZHXDrSBzYSBzdMOhbGUgbWVuw60gcyBob2Rub3RhbWkgdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaDoKCi0gUHJpIExvZyBHRFAgcGVyIGNhcGl0YSBqZSByb3pwdHlsIHbDvXJhem5lIGtsZXNhasO6Y2kuCi0gUHJpIGxvZyhTb2NpYWwgc3VwcG9ydCkgamUgcm96cHR5bCB2w71yYXpuZSBrbGVzYWrDumNpLgotIFByaSBsb2coRnJlZWRvbSkgamUgcm96cHR5bCB0YWt0aWXFviB2w71yYXpuZSBrbGVzYWrDumNpLgpWxaFldGt5IGtsZXNhasO6Y2UgdHJlbmR5IHbFoWFrIG5hc3TDoXZhasO6IG5hIMS+YXZlaiBzdHJhbmUgZ3JhZnUuCgojIyMgWsOhdmVyOgoKTG9nYXJpdG1pesOhY2lhIHByZW1lbm7DvWNoICoqbmV6bGVwxaFpbGEgc2l0dcOhY2l1KiouIEhldGVyb3NrZWRhc3RpY2l0YSBqZSBzdMOhbGUgcHLDrXRvbW7DoSwgcHJldG8gem9zdMOhdmFtZSBwcmkgcMO0dm9kbm9tIG1vZGVsaSBhIHBvdcW+w612YW1lIHJvYnVzdG7DqSDFoXRhbmRhcmRuw6kgY2h5YnkgYSBww7R2b2Ruw70gbW9kZWwgKFdoaXRlIEhDMSkgbmEga29yZWtjaXUgaGV0ZXJvc2tlZGFzdGljaXR5LgoKCgo=