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

Úvod do problému, stanovenie hypotéz

Rozhodla som sa modelovať priemernú teplotu (Temperature…C.) v závislosti od troch vysvetľujúcich premenných – atmosférického tlaku (Air.Pressure..hPa.), rýchlosti vetra (Wind.Speed..m.s.) a množstva zrážok (Precipitation..mm.) v roku 2020. Cieľom analýzy je zistiť, či tieto meteorologické faktory majú štatisticky významný vplyv na vývoj teploty a či medzi nimi existuje lineárny vzťah.

Hypotéza predpokladá, že všetky tri vysvetľujúce premenné majú určitý vplyv na priemernú teplotu. Očakávame, že vyšší atmosférický tlak bude súvisieť s nižšou teplotou, teda jeho vplyv bude negatívny. Podobne aj vyššia rýchlosť vetra by mohla viesť k poklesu teploty, pretože vietor prispieva k ochladzovaniu vzduchu. Naopak, vyššie množstvo zrážok môže byť spojené s vyššou teplotou, najmä počas teplejších období roka, keď sú zrážky časté v dôsledku búrkovej činnosti, a preto v tomto prípade predpokladáme pozitívny vplyv.

Nulová hypotéza (H0) hovorí, že žiadna z vysvetľujúcich premenných nemá štatisticky významný vplyv na teplotu. Alternatívna hypotéza (H1) predpokladá, že aspoň jedna z vysvetľujúcich premenných má na teplotu štatisticky významný vplyv.

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

udaje <- read.csv2("Temperature_2020.csv",header=TRUE,sep=";",dec=",",fileEncoding = "Windows-1250")
head(udaje)
colnames(udaje)
 [1] "Year"                             
 [2] "Month"                            
 [3] "Air.Pressure..hPa."               
 [4] "Temperature...C."                 
 [5] "Potential.Temperature..K."        
 [6] "Dew.Point...C."                   
 [7] "Relative.Humidity...."            
 [8] "Saturated.Vapour.Pressure..hPa."  
 [9] "Actual.Vapour.Pressure..hPa."     
[10] "Vapour.Pressure.Deficit..hPa."    
[11] "Specific.Humidity..g.kg."         
[12] "Water.Vapour.Concentration..g.m.."
[13] "Air.Density..kg.m.."              
[14] "Wind.Speed..m.s."                 
[15] "Max.Wind.Speed..m.s."             
[16] "Wind.Direction...."               
[17] "Precipitation..mm."               
[18] "Rain.Duration...."                
[19] "Solar.Radiation..W.m.."           
[20] "PAR..µmol.m.s."                   
[21] "Max.PAR..µmol.m.s."               
[22] "Soil.Temperature...C."            
udaje.2020 <- udaje[udaje$Year==2020,c("Temperature...C.","Air.Pressure..hPa.","Wind.Speed..m.s.","Precipitation..mm.")]

column_medians <- sapply(udaje.2020, median, na.rm = TRUE)

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

udaje.2020 <- udaje_imputed
num_plots <- length(names(udaje.2020))

par(mfrow = c(2, 2))
par(mar = c(4, 4, 2, 1))

for (col in names(udaje.2020)) {
  boxplot(udaje.2020[[col]], main = col, xlab = "Value", col = "lightblue")
}

mtext("Boxploty jednotlivých premenných (2020)", outer = TRUE, cex = 1.4, font = 2)

par(mfrow = c(1, 1))

Lineárna regresia

model <- lm(Temperature...C. ~ +1 + Air.Pressure..hPa. + Wind.Speed..m.s. + Precipitation..mm.,data=udaje.2020)
#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 = Temperature...C. ~ +1 + Air.Pressure..hPa. + Wind.Speed..m.s. + 
    Precipitation..mm., data = udaje.2020)

Residuals:
    Min      1Q  Median      3Q     Max 
-7.5810 -3.4298 -0.7333  2.6382 11.0651 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)
(Intercept)        -150.8686   471.8850  -0.320    0.757
Air.Pressure..hPa.    0.1579     0.4735   0.333    0.747
Wind.Speed..m.s.      0.2610     4.6864   0.056    0.957
Precipitation..mm.  412.2386   256.3898   1.608    0.147

Residual standard error: 6.04 on 8 degrees of freedom
Multiple R-squared:  0.3015,    Adjusted R-squared:  0.03954 
F-statistic: 1.151 on 3 and 8 DF,  p-value: 0.3862

par(mfrow = c(2, 2))

plot(model)

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

par(mfrow = c(1, 1))

Residuals vs. Fitted

Interpretácia grafu

Na grafe „Residuals vs Fitted“ vidíme, že väčšina rezíduí sa pohybuje okolo nulovej osi bez výrazného systematického vzoru. To znamená, že model je dobre centrovaný a nemá tendenciu systematicky nadhodnocovať alebo podhodnocovať predikcie. Rozptyl rezíduí je pomerne rovnomerný naprieč rozsahom prispôsobených hodnôt, čo podporuje predpoklad homoskedasticity, teda konštantnej variability chýb. Červená hladká čiara je mierne zakrivená, čo môže naznačovať, že vzťah medzi premennými nie je úplne lineárny. Niekoľko bodov, ako napríklad 7 a 8, sa odchyľuje od zvyšku, čo môže naznačovať prítomnosť odľahlých pozorovaní, ktoré by mohli mať určitý vplyv na model.

Q-Q Residuals

Interpretácia grafu

Q-Q graf porovnáva teoretické kvantily normálneho rozdelenia so skutočnými štandardizovanými rezíduami. Väčšina bodov leží blízko priamky, čo naznačuje, že rozdelenie rezíduí sa približuje normálnemu rozdeleniu. V strednej časti grafu je zhoda veľmi dobrá, zatiaľ čo v krajných častiach možno vidieť mierne odchýlky – najmä vpravo hore a vľavo dole. Tieto drobné rozdiely môžu naznačovať prítomnosť niekoľkých extrémnych hodnôt alebo mierne ťažšie chvosty rozdelenia. Celkovo však možno konštatovať, že predpoklad normality je v zásade splnený.

Scale-Location

Interpretácia grafu

Na grafe Scale-Location sú body rozložené rovnomerne pozdĺž osi X bez zreteľného tvaru lievika. To naznačuje, že rozptyl štandardizovaných rezíduí je približne konštantný, teda model spĺňa predpoklad homoskedasticity. Červená hladká čiara je relatívne plochá s len miernym poklesom, čo potvrdzuje stabilitu rozptylu naprieč rôznymi úrovňami prispôsobených hodnôt. Niektoré pozorovania sa síce nachádzajú mierne vyššie, ale nejde o extrémne odchýlky. Model teda nevykazuje významné problémy s heteroskedasticitou.

Residuals vs Leverage

Interpretácia grafu

Graf „Residuals vs Leverage“ ukazuje, ako jednotlivé pozorovania ovplyvňujú odhadnutý regresný model. Väčšina bodov má nízke hodnoty pákového efektu (leverage), čo znamená, že tieto pozorovania majú iba malý vplyv na výsledný model. Štandardizované rezíduá sa pohybujú prevažne v intervale od −2 do +2, čo je v bežnom rozsahu. Niektoré pozorovania, ako napríklad 7, 8 a 12, majú mierne vyššie hodnoty pákového efektu, ale žiadne z nich neprekračuje hranice Cookovej vzdialenosti (0,5 alebo 1,0). To naznačuje, že žiadne pozorovanie neovplyvňuje model neprimerane silno. Celkovo je model stabilný a nevykazuje prítomnosť extrémne vplyvných bodov.

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

    Jarque Bera Test

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

Keďže sa nepreukázala prítomnosť štatisticky významných odľahlých hodnôt (najväčšie studentizované rezíduum má hodnotu 2.72, pričom Bonferroni korigovaná p-hodnota = 0.359 > 0.05), nie je potrebné eliminovať žiadne pozorovania ani transformovať premenné. Jarque-Bera test normality rezíduí (X² = 0.815, p = 0.665) zároveň naznačuje, že rezíduá majú približne normálne rozdelenie. Z uvedeného vyplýva, že model je z hľadiska prítomnosti odľahlých hodnôt a normality rezíduí stabilný.

Conclusion

Na základe vykonanej analýzy môžeme konštatovať, že ani jedna z vysvetľujúcich premenných – Air.Pressure..hPa., Wind.Speed..m.s. a Precipitation..mm. – nemá štatisticky významný vplyv na priemernú teplotu v roku 2020. Hoci premenná Precipitation..mm. vykazuje najsilnejší, avšak stále nie štatisticky významný pozitívny vplyv, celkový model má nízku vysvetľovaciu schopnosť, čo naznačuje, že na vývoj teploty vplývajú aj iné faktory, ktoré neboli v modeli zahrnuté.

Rezíduá modelu sú približne normálne rozdelené, čo potvrdil aj Jarque-Bera test (p-hodnota = 0,6653). Diagnostické grafy neodhalili výrazné nelinearity ani prítomnosť heteroskedasticity. Identifikovaný bol jeden potenciálny odľahlý bod (pozorovanie č. 7), ktorý však po Bonferroniho korekcii nepredstavuje štatisticky významný vplyv na stabilitu modelu.

Celkovo môžeme povedať, že vytvorený lineárny model poskytuje základný pohľad na vzťahy medzi vybranými meteorologickými premennými a teplotou, avšak jeho vysvetľovacia schopnosť je obmedzená a pre lepšie pochopenie dynamiky teploty by bolo vhodné model rozšíriť o ďalšie relevantné faktory, ako napríklad vlhkosť vzduchu, ročné obdobie či geografické charakteristiky meraného územia.

Heteroskedasticita

Prítomnosť heteroskedasticity (nekonštantného rozptylu náhodnej zložky) môže spôsobiť nespoľahlivé vyhodnocovanie t-testov významnosti regresných koeficientov. Preto ju treba detegovať (vizuálne aj pomocou testov) a v prípade jej výskytu sa ju pokúsiť odstrániť.

V našom prípade heteroskedasticitu posudzujeme pomocou grafov zobrazujúcich závislosť štvorcov rezíduí od premenných Temperature…C. a Air.Pressure..hPa. Porovnávame dva modely – pôvodný (model) a upravovaný (model2), ktorý obsahuje zlogaritmizovanú premennú Temperature…C. s cieľom znížiť prípadnú heteroskedasticitu.

library(ggplot2)
library(patchwork)  # install.packages("patchwork")

p1 <- ggplot(udaje.2020, aes(x = Temperature...C., y = resid(model)^2)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "Temperature (°C)", 
       y = "Squared Residuals",
       title = "Sqiared Residuals vs Temperature") +
  theme_minimal()

p2 <- ggplot(udaje.2020, aes(x = Air.Pressure..hPa., y = resid(model)^2)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "Air Pressure (hPa)", 
       y = "Squared Residuals",
       title = "Squared Residuals vs Air Pressure") +
  theme_minimal()

# Combine side by side
p1 + p2

Na grafe Squared Residuals vs Temperature je vidieť, že červená vyhladená krivka má mierne kolísavý tvar. Pri nižších hodnotách Temperature…C. sú štvorce rezíduí rozptýlené rovnomerne, zatiaľ čo pri vyšších teplotách rozptyl rezíduí narastá. To naznačuje, že s rastúcou teplotou sa variabilita chýb mierne zvyšuje, čo môže poukazovať na slabú heteroskedasticitu.

Na grafe Squared Residuals vs Air Pressure má červená krivka tvar vlny – rozptyl rezíduí je najvyšší približne pri tlaku okolo 990 hPa a nižší pri extrémnejších hodnotách. Tento priebeh naznačuje, že Air.Pressure..hPa. môže mať vplyv na zmenu rozptylu rezíduí, no celkovo ide len o mierne známky heteroskedasticity, nie o výrazné porušenie predpokladov modelu.

a teraz model so zlogaritmizovanou premennou Temperature…C..

library(ggplot2)
library(patchwork)  # install.packages("patchwork")

p1 <- ggplot(udaje.2020, aes(x = log(Temperature...C.), y = resid(model2)^2)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "log(Temperature (°C))", 
       y = "Squared Residuals",
       title = "Residuals vs log(Temperature)") +
  theme_minimal()

p2 <- ggplot(udaje.2020, aes(x = Air.Pressure..hPa., y = resid(model2)^2)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "Air Pressure (hPa)", 
       y = "Squared Residuals",
       title = "Residuals vs Air Pressure") +
  theme_minimal()

# Combine side by side
p1 + p2

Po logaritmickej transformácii premennej Temperature…C. sa červená vyhladená krivka na grafe Residuals vs log(Temperature) stáva plynulejšou a bez výrazného trendu. Rozptyl rezíduí je rovnomernejší v celom rozsahu hodnôt, čo naznačuje, že logaritmická transformácia pomohla zmierniť heteroskedasticitu spojenú s teplotou.

Na grafe Residuals vs Air Pressure zostáva priebeh červenej krivky podobný ako v pôvodnom modeli – je viditeľné mierne kolísanie rozptylu rezíduí, najmä okolo hodnoty 990 hPa. To znamená, že tlak vzduchu môže aj naďalej prispievať k malej miere heteroskedasticity.

Celkovo však nový model (model2) vykazuje lepšiu stabilitu rozptylu rezíduí a naznačuje, že transformácia premennej Temperature…C. mala pozitívny efekt na zníženie heteroskedasticity v modeli.

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 = 2.1093, df = 3, p-value = 0.55
# 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 = 2.0944, df = 3, p-value = 0.553

Keďže p-hodnota je výrazne vyššia ako bežná hladina významnosti (0.05), nezamietame nulovú hypotézu o homoskedasticite. To znamená, že v našom modeli nie je prítomná heteroskedasticita – rozptyl rezíduí sa javí ako konštantný.

Na základe vizuálneho posúdenia grafov a výsledkov Breusch–Paganovho testu (p-hodnota = 0.55 pre model a 0.553 pre model2) môžeme konštatovať, že heteroskedasticita v rezíduách nie je prítomná. Preto nie je potrebné aplikovať Whiteovu korekciu ani ďalšie úpravy modelu.

LS0tCnRpdGxlOiAiRWNvbm9tZXRyaWNzIGluIFIgLSBjdmnEjWVuaWUgNS02IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKYXV0aG9yOiBWZXJvbmlrYSBSaXpzbnlvdnN6a8OhCmRhdGU6ICJOb3ZlbWJlciAyMDI1IgotLS0KCgpgYGB7cn0KbGlicmFyeSh6b28pCmxpYnJhcnkodHNlcmllcykKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoc2FuZHdpY2gpCmxpYnJhcnkoY2FyKQpybShsaXN0PWxzKCkpCmBgYAoKCiMgw5p2b2QgZG8gcHJvYmzDqW11LCBzdGFub3ZlbmllIGh5cG90w6l6IAoKUm96aG9kbGEgc29tIHNhIG1vZGVsb3ZhxaUgcHJpZW1lcm7DuiB0ZXBsb3R1IChUZW1wZXJhdHVyZS4uLkMuKSB2IHrDoXZpc2xvc3RpIG9kIHRyb2NoIHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2gg4oCTIGF0bW9zZsOpcmlja8OpaG8gdGxha3UgKEFpci5QcmVzc3VyZS4uaFBhLiksIHLDvWNobG9zdGkgdmV0cmEgKFdpbmQuU3BlZWQuLm0ucy4pIGEgbW5vxb5zdHZhIHpyw6HFvm9rIChQcmVjaXBpdGF0aW9uLi5tbS4pIHYgcm9rdSAyMDIwLiBDaWXEvm9tIGFuYWzDvXp5IGplIHppc3RpxaUsIMSNaSB0aWV0byBtZXRlb3JvbG9naWNrw6kgZmFrdG9yeSBtYWrDuiDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSB2cGx5diBuYSB2w712b2ogdGVwbG90eSBhIMSNaSBtZWR6aSBuaW1pIGV4aXN0dWplIGxpbmXDoXJueSB2esWlYWguCgpIeXBvdMOpemEgcHJlZHBva2xhZMOhLCDFvmUgdsWhZXRreSB0cmkgdnlzdmV0xL51asO6Y2UgcHJlbWVubsOpIG1hasO6IHVyxI1pdMO9IHZwbHl2IG5hIHByaWVtZXJuw7ogdGVwbG90dS4gT8SNYWvDoXZhbWUsIMW+ZSB2ecWhxaHDrSBhdG1vc2bDqXJpY2vDvSB0bGFrIGJ1ZGUgc8O6dmlzaWXFpSBzIG5pxb7FoW91IHRlcGxvdG91LCB0ZWRhIGplaG8gdnBseXYgYnVkZSBuZWdhdMOtdm55LiBQb2RvYm5lIGFqIHZ5xaHFoWlhIHLDvWNobG9zxaUgdmV0cmEgYnkgbW9obGEgdmllc8WlIGsgcG9rbGVzdSB0ZXBsb3R5LCBwcmV0b8W+ZSB2aWV0b3IgcHJpc3BpZXZhIGsgb2NobGFkem92YW5pdSB2emR1Y2h1LiBOYW9wYWssIHZ5xaHFoWllIG1ub8W+c3R2byB6csOhxb5vayBtw7TFvmUgYnnFpSBzcG9qZW7DqSBzIHZ5xaHFoW91IHRlcGxvdG91LCBuYWptw6QgcG/EjWFzIHRlcGxlasWhw61jaCBvYmRvYsOtIHJva2EsIGtlxI8gc8O6IHpyw6HFvmt5IMSNYXN0w6kgdiBkw7RzbGVka3UgYsO6cmtvdmVqIMSNaW5ub3N0aSwgYSBwcmV0byB2IHRvbXRvIHByw61wYWRlIHByZWRwb2tsYWTDoW1lIHBveml0w612bnkgdnBseXYuCgpOdWxvdsOhIGh5cG90w6l6YSAoSDApIGhvdm9yw60sIMW+ZSDFvmlhZG5hIHogdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCBuZW3DoSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSB2cGx5diBuYSB0ZXBsb3R1LiBBbHRlcm5hdMOtdm5hIGh5cG90w6l6YSAoSDEpIHByZWRwb2tsYWTDoSwgxb5lIGFzcG/FiCBqZWRuYSB6IHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2ggbcOhIG5hIHRlcGxvdHUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gdnBseXYuCgoKIyBQcsOtcHJhdmEgZGF0YWLDoXp5LCDEjWlzdGVuaWUgYSDDunByYXZhIMO6ZGFqb3YKCmBgYHtyfQp1ZGFqZSA8LSByZWFkLmNzdjIoIlRlbXBlcmF0dXJlXzIwMjAuY3N2IixoZWFkZXI9VFJVRSxzZXA9IjsiLGRlYz0iLCIsZmlsZUVuY29kaW5nID0gIldpbmRvd3MtMTI1MCIpCmhlYWQodWRhamUpCmNvbG5hbWVzKHVkYWplKQpgYGAKYGBge3J9CnVkYWplLjIwMjAgPC0gdWRhamVbdWRhamUkWWVhcj09MjAyMCxjKCJUZW1wZXJhdHVyZS4uLkMuIiwiQWlyLlByZXNzdXJlLi5oUGEuIiwiV2luZC5TcGVlZC4ubS5zLiIsIlByZWNpcGl0YXRpb24uLm1tLiIpXQoKY29sdW1uX21lZGlhbnMgPC0gc2FwcGx5KHVkYWplLjIwMjAsIG1lZGlhbiwgbmEucm0gPSBUUlVFKQoKdWRhamVfaW1wdXRlZCA8LSB1ZGFqZS4yMDIwCmZvciAoY29sIGluIG5hbWVzKHVkYWplLjIwMjApKSB7CiAgdWRhamVfaW1wdXRlZFtbY29sXV1baXMubmEodWRhamVfaW1wdXRlZFtbY29sXV0pXSA8LSBjb2x1bW5fbWVkaWFuc1tjb2xdCn0KCnVkYWplLjIwMjAgPC0gdWRhamVfaW1wdXRlZAoKYGBgCgoKCmBgYHtyfQpudW1fcGxvdHMgPC0gbGVuZ3RoKG5hbWVzKHVkYWplLjIwMjApKQoKcGFyKG1mcm93ID0gYygyLCAyKSkKcGFyKG1hciA9IGMoNCwgNCwgMiwgMSkpCgpmb3IgKGNvbCBpbiBuYW1lcyh1ZGFqZS4yMDIwKSkgewogIGJveHBsb3QodWRhamUuMjAyMFtbY29sXV0sIG1haW4gPSBjb2wsIHhsYWIgPSAiVmFsdWUiLCBjb2wgPSAibGlnaHRibHVlIikKfQoKbXRleHQoIkJveHBsb3R5IGplZG5vdGxpdsO9Y2ggcHJlbWVubsO9Y2ggKDIwMjApIiwgb3V0ZXIgPSBUUlVFLCBjZXggPSAxLjQsIGZvbnQgPSAyKQoKcGFyKG1mcm93ID0gYygxLCAxKSkKYGBgCgoKIyMgTGluZcOhcm5hIHJlZ3Jlc2lhCgpgYGB7cn0KbW9kZWwgPC0gbG0oVGVtcGVyYXR1cmUuLi5DLiB+ICsxICsgQWlyLlByZXNzdXJlLi5oUGEuICsgV2luZC5TcGVlZC4ubS5zLiArIFByZWNpcGl0YXRpb24uLm1tLixkYXRhPXVkYWplLjIwMjApCmBgYAoKCmBgYHtyfQojcHJpbnQoIk9kaGFkbnV0w6kga29lZmljaWVudHkgc8O6OiAiKQojICAgICAgcHJpbnQobW9kZWwkY29lZmZpY2llbnRzKQojcHJpbnQoIk9kaGFkbnV0w6kgcmV6w61kdcOhOiAiKQojcHJpbnQobW9kZWwkcmVzaWR1YWxzKQojcHJpbnQoIlZ5cm92bmFuw6kgaG9kbm90eSB2eXN2ZXTEvm92YW5laiBwcmVtZW5uZWogc8O6OiAiKQojcHJpbnQobW9kZWwkZml0dGVkLnZhbHVlcykKI3ByaW50KCJtYXRpY2EgbW9kZWwkeGxldmVsczogIikKI3ByaW50KG1vZGVsLm1hdHJpeChtb2RlbCkpCiNYIDwtIG1vZGVsLm1hdHJpeChtb2RlbCkKI2RpYWcoWCAlKiUgc29sdmUodChYKSAlKiUgWCkgJSolIHQoWCkpCgpzdW1tYXJ5KG1vZGVsKQoKYGBgCgoKYGBge3IgZGlhZ3Bsb3RzLCBmaWcuY2FwPSJEaWFnbm9zdGlja8OpIGdyYWZ5IHJlZ3Jlc27DqWhvIG1vZGVsdSJ9CgpwYXIobWZyb3cgPSBjKDIsIDIpKQoKcGxvdChtb2RlbCkKCm10ZXh0KCJEaWFnbm9zdGlja8OpIGdyYWZ5IHJlZ3Jlc27DqWhvIG1vZGVsdSIsIG91dGVyID0gVFJVRSwgY2V4ID0gMS4yLCBmb250ID0gMikKCnBhcihtZnJvdyA9IGMoMSwgMSkpCmBgYAoKIyMgUmVzaWR1YWxzIHZzLiBGaXR0ZWQKCiMjIyBJbnRlcnByZXTDoWNpYSBncmFmdQoKTmEgZ3JhZmUg4oCeUmVzaWR1YWxzIHZzIEZpdHRlZOKAnCB2aWTDrW1lLCDFvmUgdsOkxI3FoWluYSByZXrDrWR1w60gc2EgcG9oeWJ1amUgb2tvbG8gbnVsb3ZlaiBvc2kgYmV6IHbDvXJhem7DqWhvIHN5c3RlbWF0aWNrw6lobyB2em9ydS4gVG8gem5hbWVuw6EsIMW+ZSBtb2RlbCBqZSBkb2JyZSBjZW50cm92YW7DvSBhIG5lbcOhIHRlbmRlbmNpdSBzeXN0ZW1hdGlja3kgbmFkaG9kbm9jb3ZhxaUgYWxlYm8gcG9kaG9kbm9jb3ZhxaUgcHJlZGlrY2llLiBSb3pwdHlsIHJlesOtZHXDrSBqZSBwb21lcm5lIHJvdm5vbWVybsO9IG5hcHJpZcSNIHJvenNhaG9tIHByaXNww7Rzb2JlbsO9Y2ggaG9kbsO0dCwgxI1vIHBvZHBvcnVqZSBwcmVkcG9rbGFkIGhvbW9za2VkYXN0aWNpdHksIHRlZGEga29uxaF0YW50bmVqIHZhcmlhYmlsaXR5IGNow71iLiDEjGVydmVuw6EgaGxhZGvDoSDEjWlhcmEgamUgbWllcm5lIHpha3JpdmVuw6EsIMSNbyBtw7TFvmUgbmF6bmHEjW92YcWlLCDFvmUgdnrFpWFoIG1lZHppIHByZW1lbm7DvW1pIG5pZSBqZSDDunBsbmUgbGluZcOhcm55LiBOaWVrb8S+a28gYm9kb3YsIGFrbyBuYXByw61rbGFkIDcgYSA4LCBzYSBvZGNoecS+dWplIG9kIHp2ecWha3UsIMSNbyBtw7TFvmUgbmF6bmHEjW92YcWlIHByw610b21ub3PFpSBvZMS+YWhsw71jaCBwb3pvcm92YW7DrSwga3RvcsOpIGJ5IG1vaGxpIG1hxaUgdXLEjWl0w70gdnBseXYgbmEgbW9kZWwuCgojIyBRLVEgUmVzaWR1YWxzCgojIyMgSW50ZXJwcmV0w6FjaWEgZ3JhZnUKClEtUSBncmFmIHBvcm92bsOhdmEgdGVvcmV0aWNrw6kga3ZhbnRpbHkgbm9ybcOhbG5laG8gcm96ZGVsZW5pYSBzbyBza3V0b8SNbsO9bWkgxaF0YW5kYXJkaXpvdmFuw71taSByZXrDrWR1YW1pLiBWw6TEjcWhaW5hIGJvZG92IGxlxb7DrSBibMOtemtvIHByaWFta3ksIMSNbyBuYXpuYcSNdWplLCDFvmUgcm96ZGVsZW5pZSByZXrDrWR1w60gc2EgcHJpYmxpxb51amUgbm9ybcOhbG5lbXUgcm96ZGVsZW5pdS4gViBzdHJlZG5laiDEjWFzdGkgZ3JhZnUgamUgemhvZGEgdmXEvm1pIGRvYnLDoSwgemF0aWHEviDEjW8gdiBrcmFqbsO9Y2ggxI1hc3RpYWNoIG1vxb5ubyB2aWRpZcWlIG1pZXJuZSBvZGNow71sa3kg4oCTIG5ham3DpCB2cHJhdm8gaG9yZSBhIHbEvmF2byBkb2xlLiBUaWV0byBkcm9ibsOpIHJvemRpZWx5IG3DtMW+dSBuYXpuYcSNb3ZhxaUgcHLDrXRvbW5vc8WlIG5pZWtvxL5rw71jaCBleHRyw6ltbnljaCBob2Ruw7R0IGFsZWJvIG1pZXJuZSDFpWHFvsWhaWUgY2h2b3N0eSByb3pkZWxlbmlhLiBDZWxrb3ZvIHbFoWFrIG1vxb5ubyBrb27FoXRhdG92YcWlLCDFvmUgcHJlZHBva2xhZCBub3JtYWxpdHkgamUgdiB6w6FzYWRlIHNwbG5lbsO9LgoKIyMgU2NhbGUtTG9jYXRpb24KCiMjIyBJbnRlcnByZXTDoWNpYSBncmFmdQoKTmEgZ3JhZmUgU2NhbGUtTG9jYXRpb24gc8O6IGJvZHkgcm96bG/FvmVuw6kgcm92bm9tZXJuZSBwb3pkxLrFviBvc2kgWCBiZXogenJldGXEvm7DqWhvIHR2YXJ1IGxpZXZpa2EuIFRvIG5hem5hxI11amUsIMW+ZSByb3pwdHlsIMWhdGFuZGFyZGl6b3ZhbsO9Y2ggcmV6w61kdcOtIGplIHByaWJsacW+bmUga29uxaF0YW50bsO9LCB0ZWRhIG1vZGVsIHNwxLrFiGEgcHJlZHBva2xhZCBob21vc2tlZGFzdGljaXR5LiDEjGVydmVuw6EgaGxhZGvDoSDEjWlhcmEgamUgcmVsYXTDrXZuZSBwbG9jaMOhIHMgbGVuIG1pZXJueW0gcG9rbGVzb20sIMSNbyBwb3R2cmR6dWplIHN0YWJpbGl0dSByb3pwdHlsdSBuYXByaWXEjSByw7R6bnltaSDDunJvdsWIYW1pIHByaXNww7Rzb2JlbsO9Y2ggaG9kbsO0dC4gTmlla3RvcsOpIHBvem9yb3ZhbmlhIHNhIHPDrWNlIG5hY2jDoWR6YWrDuiBtaWVybmUgdnnFocWhaWUsIGFsZSBuZWpkZSBvIGV4dHLDqW1uZSBvZGNow71sa3kuIE1vZGVsIHRlZGEgbmV2eWthenVqZSB2w716bmFtbsOpIHByb2Jsw6lteSBzIGhldGVyb3NrZWRhc3RpY2l0b3UuCgojIyBSZXNpZHVhbHMgdnMgTGV2ZXJhZ2UKCiMjIyBJbnRlcnByZXTDoWNpYSBncmFmdQoKR3JhZiDigJ5SZXNpZHVhbHMgdnMgTGV2ZXJhZ2XigJwgdWthenVqZSwgYWtvIGplZG5vdGxpdsOpIHBvem9yb3ZhbmlhIG92cGx5dsWIdWrDuiBvZGhhZG51dMO9IHJlZ3Jlc27DvSBtb2RlbC4gVsOkxI3FoWluYSBib2RvdiBtw6EgbsOtemtlIGhvZG5vdHkgcMOha292w6lobyBlZmVrdHUgKGxldmVyYWdlKSwgxI1vIHpuYW1lbsOhLCDFvmUgdGlldG8gcG96b3JvdmFuaWEgbWFqw7ogaWJhIG1hbMO9IHZwbHl2IG5hIHbDvXNsZWRuw70gbW9kZWwuIMWgdGFuZGFyZGl6b3ZhbsOpIHJlesOtZHXDoSBzYSBwb2h5YnVqw7ogcHJldmHFvm5lIHYgaW50ZXJ2YWxlIG9kIOKIkjIgZG8gKzIsIMSNbyBqZSB2IGJlxb5ub20gcm96c2FodS4gTmlla3RvcsOpIHBvem9yb3ZhbmlhLCBha28gbmFwcsOta2xhZCA3LCA4IGEgMTIsIG1hasO6IG1pZXJuZSB2ecWhxaFpZSBob2Rub3R5IHDDoWtvdsOpaG8gZWZla3R1LCBhbGUgxb5pYWRuZSB6IG5pY2ggbmVwcmVrcmHEjXVqZSBocmFuaWNlIENvb2tvdmVqIHZ6ZGlhbGVub3N0aSAoMCw1IGFsZWJvIDEsMCkuIFRvIG5hem5hxI11amUsIMW+ZSDFvmlhZG5lIHBvem9yb3ZhbmllIG5lb3ZwbHl2xYh1amUgbW9kZWwgbmVwcmltZXJhbmUgc2lsbm8uIENlbGtvdm8gamUgbW9kZWwgc3RhYmlsbsO9IGEgbmV2eWthenVqZSBwcsOtdG9tbm9zxaUgZXh0csOpbW5lIHZwbHl2bsO9Y2ggYm9kb3YuCgoKCmBgYHtyfQojIG5vcm1hbGl0eSB0ZXN0cwpyZXNpZHVhbHMgPC0gcmVzaWR1YWxzKG1vZGVsKQpqYl90ZXN0IDwtIGphcnF1ZS5iZXJhLnRlc3QocmVzaWR1YWxzKQpqYl90ZXN0CiMgb3V0bGllciB0ZXN0IChzZWUgcC12YWx1ZSBmb3IgQm9uZmVycm9uaSBjb3JyZWN0aW9uKQpvdXRsaWVyX3Rlc3QgPC0gb3V0bGllclRlc3QobW9kZWwpCm91dGxpZXJfdGVzdApgYGAKCktlxI/FvmUgc2EgbmVwcmV1a8OhemFsYSBwcsOtdG9tbm9zxaUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw71jaCBvZMS+YWhsw71jaCBob2Ruw7R0IChuYWp2w6TEjcWhaWUgc3R1ZGVudGl6b3ZhbsOpIHJlesOtZHV1bSBtw6EgaG9kbm90dSAyLjcyLCBwcmnEjW9tIEJvbmZlcnJvbmkga29yaWdvdmFuw6EgcC1ob2Rub3RhID0gMC4zNTkgPiAwLjA1KSwgbmllIGplIHBvdHJlYm7DqSBlbGltaW5vdmHFpSDFvmlhZG5lIHBvem9yb3ZhbmlhIGFuaSB0cmFuc2Zvcm1vdmHFpSBwcmVtZW5uw6kuCkphcnF1ZS1CZXJhIHRlc3Qgbm9ybWFsaXR5IHJlesOtZHXDrSAoWMKyID0gMC44MTUsIHAgPSAwLjY2NSkgesOhcm92ZcWIIG5hem5hxI11amUsIMW+ZSByZXrDrWR1w6EgbWFqw7ogcHJpYmxpxb5uZSBub3Jtw6FsbmUgcm96ZGVsZW5pZS4KWiB1dmVkZW7DqWhvIHZ5cGzDvXZhLCDFvmUgbW9kZWwgamUgeiBoxL5hZGlza2EgcHLDrXRvbW5vc3RpIG9kxL5haGzDvWNoIGhvZG7DtHQgYSBub3JtYWxpdHkgcmV6w61kdcOtIHN0YWJpbG7DvS4KCiMjIENvbmNsdXNpb24KCk5hIHrDoWtsYWRlIHZ5a29uYW5laiBhbmFsw716eSBtw7TFvmVtZSBrb27FoXRhdG92YcWlLCDFvmUgYW5pIGplZG5hIHogdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCDigJMgQWlyLlByZXNzdXJlLi5oUGEuLCBXaW5kLlNwZWVkLi5tLnMuIGEgUHJlY2lwaXRhdGlvbi4ubW0uIOKAkyBuZW3DoSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSB2cGx5diBuYSBwcmllbWVybsO6IHRlcGxvdHUgdiByb2t1IDIwMjAuIEhvY2kgcHJlbWVubsOhIFByZWNpcGl0YXRpb24uLm1tLiB2eWthenVqZSBuYWpzaWxuZWrFocOtLCBhdsWhYWsgc3TDoWxlIG5pZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSBwb3ppdMOtdm55IHZwbHl2LCBjZWxrb3bDvSBtb2RlbCBtw6EgbsOtemt1IHZ5c3ZldMS+b3ZhY2l1IHNjaG9wbm9zxaUsIMSNbyBuYXpuYcSNdWplLCDFvmUgbmEgdsO9dm9qIHRlcGxvdHkgdnBsw712YWrDuiBhaiBpbsOpIGZha3RvcnksIGt0b3LDqSBuZWJvbGkgdiBtb2RlbGkgemFocm51dMOpLgoKUmV6w61kdcOhIG1vZGVsdSBzw7ogcHJpYmxpxb5uZSBub3Jtw6FsbmUgcm96ZGVsZW7DqSwgxI1vIHBvdHZyZGlsIGFqIEphcnF1ZS1CZXJhIHRlc3QgKHAtaG9kbm90YSA9IDAsNjY1MykuIERpYWdub3N0aWNrw6kgZ3JhZnkgbmVvZGhhbGlsaSB2w71yYXpuw6kgbmVsaW5lYXJpdHkgYW5pIHByw610b21ub3PFpSBoZXRlcm9za2VkYXN0aWNpdHkuIElkZW50aWZpa292YW7DvSBib2wgamVkZW4gcG90ZW5jacOhbG55IG9kxL5haGzDvSBib2QgKHBvem9yb3ZhbmllIMSNLiA3KSwga3RvcsO9IHbFoWFrIHBvIEJvbmZlcnJvbmlobyBrb3Jla2NpaSBuZXByZWRzdGF2dWplIMWhdGF0aXN0aWNreSB2w716bmFtbsO9IHZwbHl2IG5hIHN0YWJpbGl0dSBtb2RlbHUuCgpDZWxrb3ZvIG3DtMW+ZW1lIHBvdmVkYcWlLCDFvmUgdnl0dm9yZW7DvSBsaW5lw6FybnkgbW9kZWwgcG9za3l0dWplIHrDoWtsYWRuw70gcG9oxL5hZCBuYSB2esWlYWh5IG1lZHppIHZ5YnJhbsO9bWkgbWV0ZW9yb2xvZ2lja8O9bWkgcHJlbWVubsO9bWkgYSB0ZXBsb3RvdSwgYXbFoWFrIGplaG8gdnlzdmV0xL5vdmFjaWEgc2Nob3Bub3PFpSBqZSBvYm1lZHplbsOhIGEgcHJlIGxlcMWhaWUgcG9jaG9wZW5pZSBkeW5hbWlreSB0ZXBsb3R5IGJ5IGJvbG8gdmhvZG7DqSBtb2RlbCByb3rFocOtcmnFpSBvIMSPYWzFoWllIHJlbGV2YW50bsOpIGZha3RvcnksIGFrbyBuYXByw61rbGFkIHZsaGtvc8WlIHZ6ZHVjaHUsIHJvxI1uw6kgb2Jkb2JpZSDEjWkgZ2VvZ3JhZmlja8OpIGNoYXJha3RlcmlzdGlreSBtZXJhbsOpaG8gw7p6ZW1pYS4KCgojIyBIZXRlcm9za2VkYXN0aWNpdGEKClByw610b21ub3PFpSBoZXRlcm9za2VkYXN0aWNpdHkgKG5la29uxaF0YW50bsOpaG8gcm96cHR5bHUgbsOhaG9kbmVqIHpsb8W+a3kpIG3DtMW+ZSBzcMO0c29iacWlIG5lc3BvxL5haGxpdsOpIHZ5aG9kbm9jb3ZhbmllIHQtdGVzdG92IHbDvXpuYW1ub3N0aSByZWdyZXNuw71jaCBrb2VmaWNpZW50b3YuClByZXRvIGp1IHRyZWJhIGRldGVnb3ZhxaUgKHZpenXDoWxuZSBhaiBwb21vY291IHRlc3RvdikgYSB2IHByw61wYWRlIGplaiB2w71za3l0dSBzYSBqdSBwb2vDunNpxaUgb2RzdHLDoW5pxaUuCgpWIG5hxaFvbSBwcsOtcGFkZSBoZXRlcm9za2VkYXN0aWNpdHUgcG9zdWR6dWplbWUgcG9tb2NvdSBncmFmb3Ygem9icmF6dWrDumNpY2ggesOhdmlzbG9zxaUgxaF0dm9yY292IHJlesOtZHXDrSBvZCBwcmVtZW5uw71jaCBUZW1wZXJhdHVyZS4uLkMuIGEgQWlyLlByZXNzdXJlLi5oUGEuClBvcm92bsOhdmFtZSBkdmEgbW9kZWx5IOKAkyBww7R2b2Ruw70gKG1vZGVsKSBhIHVwcmF2b3ZhbsO9IChtb2RlbDIpLCBrdG9yw70gb2JzYWh1amUgemxvZ2FyaXRtaXpvdmFuw7ogcHJlbWVubsO6IFRlbXBlcmF0dXJlLi4uQy4gcyBjaWXEvm9tIHpuw63FvmnFpSBwcsOtcGFkbsO6IGhldGVyb3NrZWRhc3RpY2l0dS4KCgpgYGB7ciBoZXRlcm9wbG90czEsIGZpZy5jYXA9IlNrw7ptYW5pZSBoZXRlcm9za2VkYXN0aWNpdHkiLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NH0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHBhdGNod29yaykgICMgaW5zdGFsbC5wYWNrYWdlcygicGF0Y2h3b3JrIikKCnAxIDwtIGdncGxvdCh1ZGFqZS4yMDIwLCBhZXMoeCA9IFRlbXBlcmF0dXJlLi4uQy4sIHkgPSByZXNpZChtb2RlbCleMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoeCA9ICJUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgeSA9ICJTcXVhcmVkIFJlc2lkdWFscyIsCiAgICAgICB0aXRsZSA9ICJTcWlhcmVkIFJlc2lkdWFscyB2cyBUZW1wZXJhdHVyZSIpICsKICB0aGVtZV9taW5pbWFsKCkKCnAyIDwtIGdncGxvdCh1ZGFqZS4yMDIwLCBhZXMoeCA9IEFpci5QcmVzc3VyZS4uaFBhLiwgeSA9IHJlc2lkKG1vZGVsKV4yKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJyZWQiKSArCiAgbGFicyh4ID0gIkFpciBQcmVzc3VyZSAoaFBhKSIsIAogICAgICAgeSA9ICJTcXVhcmVkIFJlc2lkdWFscyIsCiAgICAgICB0aXRsZSA9ICJTcXVhcmVkIFJlc2lkdWFscyB2cyBBaXIgUHJlc3N1cmUiKSArCiAgdGhlbWVfbWluaW1hbCgpCgojIENvbWJpbmUgc2lkZSBieSBzaWRlCnAxICsgcDIKYGBgCk5hIGdyYWZlIFNxdWFyZWQgUmVzaWR1YWxzIHZzIFRlbXBlcmF0dXJlIGplIHZpZGllxaUsIMW+ZSDEjWVydmVuw6EgdnlobGFkZW7DoSBrcml2a2EgbcOhIG1pZXJuZSBrb2zDrXNhdsO9IHR2YXIuClByaSBuacW+xaHDrWNoIGhvZG5vdMOhY2ggVGVtcGVyYXR1cmUuLi5DLiBzw7ogxaF0dm9yY2UgcmV6w61kdcOtIHJvenB0w71sZW7DqSByb3Zub21lcm5lLCB6YXRpYcS+IMSNbyBwcmkgdnnFocWhw61jaCB0ZXBsb3TDoWNoIHJvenB0eWwgcmV6w61kdcOtIG5hcmFzdMOhLgpUbyBuYXpuYcSNdWplLCDFvmUgcyByYXN0w7pjb3UgdGVwbG90b3Ugc2EgdmFyaWFiaWxpdGEgY2jDvWIgbWllcm5lIHp2ecWhdWplLCDEjW8gbcO0xb5lIHBvdWthem92YcWlIG5hIHNsYWLDuiBoZXRlcm9za2VkYXN0aWNpdHUuCgpOYSBncmFmZSBTcXVhcmVkIFJlc2lkdWFscyB2cyBBaXIgUHJlc3N1cmUgbcOhIMSNZXJ2ZW7DoSBrcml2a2EgdHZhciB2bG55IOKAkyByb3pwdHlsIHJlesOtZHXDrSBqZSBuYWp2ecWhxaHDrSBwcmlibGnFvm5lIHByaSB0bGFrdSBva29sbyA5OTAgaFBhIGEgbmnFvsWhw60gcHJpIGV4dHLDqW1uZWrFocOtY2ggaG9kbm90w6FjaC4KVGVudG8gcHJpZWJlaCBuYXpuYcSNdWplLCDFvmUgQWlyLlByZXNzdXJlLi5oUGEuIG3DtMW+ZSBtYcWlIHZwbHl2IG5hIHptZW51IHJvenB0eWx1IHJlesOtZHXDrSwgbm8gY2Vsa292byBpZGUgbGVuIG8gbWllcm5lIHpuw6Fta3kgaGV0ZXJvc2tlZGFzdGljaXR5LCBuaWUgbyB2w71yYXpuw6kgcG9ydcWhZW5pZSBwcmVkcG9rbGFkb3YgbW9kZWx1LgoKYSB0ZXJheiBtb2RlbCBzbyB6bG9nYXJpdG1pem92YW5vdSBwcmVtZW5ub3UgKlRlbXBlcmF0dXJlLi4uQy4qLgoKYGBge3IgaGV0ZXJvcGxvdHMyLCBmaWcuY2FwPSJTa8O6bWFuaWUgaGV0ZXJvc2tlZGFzdGljaXR5IiwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTR9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwYXRjaHdvcmspICAjIGluc3RhbGwucGFja2FnZXMoInBhdGNod29yayIpCgpwMSA8LSBnZ3Bsb3QodWRhamUuMjAyMCwgYWVzKHggPSBsb2coVGVtcGVyYXR1cmUuLi5DLiksIHkgPSByZXNpZChtb2RlbDIpXjIpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKHggPSAibG9nKFRlbXBlcmF0dXJlICjCsEMpKSIsIAogICAgICAgeSA9ICJTcXVhcmVkIFJlc2lkdWFscyIsCiAgICAgICB0aXRsZSA9ICJSZXNpZHVhbHMgdnMgbG9nKFRlbXBlcmF0dXJlKSIpICsKICB0aGVtZV9taW5pbWFsKCkKCnAyIDwtIGdncGxvdCh1ZGFqZS4yMDIwLCBhZXMoeCA9IEFpci5QcmVzc3VyZS4uaFBhLiwgeSA9IHJlc2lkKG1vZGVsMileMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoeCA9ICJBaXIgUHJlc3N1cmUgKGhQYSkiLCAKICAgICAgIHkgPSAiU3F1YXJlZCBSZXNpZHVhbHMiLAogICAgICAgdGl0bGUgPSAiUmVzaWR1YWxzIHZzIEFpciBQcmVzc3VyZSIpICsKICB0aGVtZV9taW5pbWFsKCkKCiMgQ29tYmluZSBzaWRlIGJ5IHNpZGUKcDEgKyBwMgpgYGAKUG8gbG9nYXJpdG1pY2tlaiB0cmFuc2Zvcm3DoWNpaSBwcmVtZW5uZWogVGVtcGVyYXR1cmUuLi5DLiBzYSDEjWVydmVuw6EgdnlobGFkZW7DoSBrcml2a2EgbmEgZ3JhZmUgUmVzaWR1YWxzIHZzIGxvZyhUZW1wZXJhdHVyZSkgc3TDoXZhIHBseW51bGVqxaFvdSBhIGJleiB2w71yYXpuw6lobyB0cmVuZHUuClJvenB0eWwgcmV6w61kdcOtIGplIHJvdm5vbWVybmVqxaHDrSB2IGNlbG9tIHJvenNhaHUgaG9kbsO0dCwgxI1vIG5hem5hxI11amUsIMW+ZSBsb2dhcml0bWlja8OhIHRyYW5zZm9ybcOhY2lhIHBvbW9obGEgem1pZXJuacWlIGhldGVyb3NrZWRhc3RpY2l0dSBzcG9qZW7DuiBzIHRlcGxvdG91LgoKTmEgZ3JhZmUgUmVzaWR1YWxzIHZzIEFpciBQcmVzc3VyZSB6b3N0w6F2YSBwcmllYmVoIMSNZXJ2ZW5laiBrcml2a3kgcG9kb2Juw70gYWtvIHYgcMO0dm9kbm9tIG1vZGVsaSDigJMgamUgdmlkaXRlxL5uw6kgbWllcm5lIGtvbMOtc2FuaWUgcm96cHR5bHUgcmV6w61kdcOtLCBuYWptw6Qgb2tvbG8gaG9kbm90eSA5OTAgaFBhLgpUbyB6bmFtZW7DoSwgxb5lIHRsYWsgdnpkdWNodSBtw7TFvmUgYWogbmHEj2FsZWogcHJpc3BpZXZhxaUgayBtYWxlaiBtaWVyZSBoZXRlcm9za2VkYXN0aWNpdHkuCgpDZWxrb3ZvIHbFoWFrIG5vdsO9IG1vZGVsIChtb2RlbDIpIHZ5a2F6dWplIGxlcMWhaXUgc3RhYmlsaXR1IHJvenB0eWx1IHJlesOtZHXDrSBhIG5hem5hxI11amUsIMW+ZSB0cmFuc2Zvcm3DoWNpYSBwcmVtZW5uZWogVGVtcGVyYXR1cmUuLi5DLiBtYWxhIHBveml0w612bnkgZWZla3QgbmEgem7DrcW+ZW5pZSBoZXRlcm9za2VkYXN0aWNpdHkgdiBtb2RlbGkuCgoKIyMgVGVzdG92YW5pZSBwcsOtdG9tbm9zdGkgaGV0ZXJvc2tlZGFzdGljaXR5CgpgYGB7cn0KIyBJbnN0YWxsIChpZiBub3QgeWV0IGluc3RhbGxlZCkKIyBpbnN0YWxsLnBhY2thZ2VzKCJsbXRlc3QiKQoKIyBMb2FkIHRoZSBwYWNrYWdlCmxpYnJhcnkobG10ZXN0KQoKIyBSdW4gdGhlIEJyZXVzY2jigJNQYWdhbiB0ZXN0CmJwdGVzdChtb2RlbCkKCmBgYAoKCmBgYHtyfQojIEluc3RhbGwgKGlmIG5vdCB5ZXQgaW5zdGFsbGVkKQojIGluc3RhbGwucGFja2FnZXMoImxtdGVzdCIpCgojIExvYWQgdGhlIHBhY2thZ2UKbGlicmFyeShsbXRlc3QpCgojIFJ1biB0aGUgQnJldXNjaOKAk1BhZ2FuIHRlc3QKYnB0ZXN0KG1vZGVsMikKCmBgYAoKS2XEj8W+ZSBwLWhvZG5vdGEgamUgdsO9cmF6bmUgdnnFocWhaWEgYWtvIGJlxb5uw6EgaGxhZGluYSB2w716bmFtbm9zdGkgKDAuMDUpLCBuZXphbWlldGFtZSBudWxvdsO6IGh5cG90w6l6dSBvIGhvbW9za2VkYXN0aWNpdGUuClRvIHpuYW1lbsOhLCDFvmUgdiBuYcWhb20gbW9kZWxpIG5pZSBqZSBwcsOtdG9tbsOhIGhldGVyb3NrZWRhc3RpY2l0YSDigJMgcm96cHR5bCByZXrDrWR1w60gc2EgamF2w60gYWtvIGtvbsWhdGFudG7DvS4KCk5hIHrDoWtsYWRlIHZpenXDoWxuZWhvIHBvc8O6ZGVuaWEgZ3JhZm92IGEgdsO9c2xlZGtvdiBCcmV1c2No4oCTUGFnYW5vdmhvIHRlc3R1IChwLWhvZG5vdGEgPSAwLjU1IHByZSBtb2RlbCBhIDAuNTUzIHByZSBtb2RlbDIpIG3DtMW+ZW1lIGtvbsWhdGF0b3ZhxaUsIMW+ZSBoZXRlcm9za2VkYXN0aWNpdGEgdiByZXrDrWR1w6FjaCBuaWUgamUgcHLDrXRvbW7DoS4KUHJldG8gbmllIGplIHBvdHJlYm7DqSBhcGxpa292YcWlIFdoaXRlb3Z1IGtvcmVrY2l1IGFuaSDEj2FsxaFpZSDDunByYXZ5IG1vZGVsdS4KCg==