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

Moja databáza obsahuje ročné makroekonomické ukazovatele Slovenskej republiky v období 2010–2022. Ide o kombináciu ukazovateľov inflácie, rastu HDP, verejných financií, bežného účtu a výkonnosti ekonomiky.

Pomocou viacnásobnej lineárnej regresie skúmame, do akej miery je miera nezamestnanosti ovplyvnená makroekonomickými ukazovateľmi, konkrétne ročným rastom HDP (GDP_Growth_Annual) a infláciou meranou indexom CPI (Inflation_CPI). Cieľom je zistiť, ktoré z týchto faktorov štatisticky významne prispievajú k vysvetleniu miery nezamestnanosti.

Výsledok tejto regresie je uvedený nižšie:

#######################################################################
# PRIPRAVA UDAJOV
#######################################################################
udaje <- read.csv("data.csv",dec=".",sep=";",header = TRUE)
# výber relevantných premenných
udaje <- udaje[ ,c("Unemployment_Rate","GDP_Growth_Annual", "Inflation_CPI")] 

################################################################################
# ZAKLADNA REGRESIA
################################################################################
attach(udaje)
model <- lm(Unemployment_Rate ~ +1 + GDP_Growth_Annual + Inflation_CPI, data = udaje)
summary(model)

Call:
lm(formula = Unemployment_Rate ~ +1 + GDP_Growth_Annual + Inflation_CPI, 
    data = udaje)

Residuals:
    Min      1Q  Median      3Q     Max 
-4.0760 -2.4708 -0.2798  3.2210  4.5429 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)
(Intercept)        10.2438     1.8215   5.624  0.00022
GDP_Growth_Annual   0.1789     0.4251   0.421  0.68284
Inflation_CPI      -0.3054     0.3087  -0.989  0.34578
                     
(Intercept)       ***
GDP_Growth_Annual    
Inflation_CPI        
---
Signif. codes:  
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3.478 on 10 degrees of freedom
Multiple R-squared:  0.1318,    Adjusted R-squared:  -0.04185 
F-statistic: 0.759 on 2 and 10 DF,  p-value: 0.4933

Testovať, či je model v správnej funkčnej forme (t. j. či je lineárna špecifikácia vhodná, alebo či by sme mali transformovať premenné, napríklad pomocou logaritmov alebo mocninami), možno vykonať viacerými spôsobmi.

1. Test RESET (test chyby špecifikácie Ramseyho regresnej rovnice - Ramsey Reset Test)

Ide o najštandardnejší formálny test nesprávnej špecifikácie funkčnej formy ale dá sa použiť aj pre prípady, ak sme nešpecifikovali všetky vysvetľujúce premenné.

Myšlienka: Nech pôvodný model má tvar \[y_t = \beta_0 + \beta_1 x_{t10} + \dots +\beta_k x_{tk} + u_t\] Ak je náš model správne špecifikovaný, potom pridaním mocnín vyrovnaných hodnôt (napr. \(\hat y_t^2\), \(\hat{y}_t^3\)) by sa pôvodný model nemal podstatne zlepšiť, teda budeme testovať pôvodný model uvedený vyššie a model

\[y_t = \beta_0 + \beta_1 x_{t10} + \dots +\beta_k x_{tk} + \gamma_2\hat y_t^2 + \gamma_3\hat{y}_t^3 + u_t\]

Budeme testovať hypotézu

\(H_0:\) model je správne špecifikovaný (\(\gamma_2 = \gamma_3 = 0\))

oproti

\(H_1:\) model je nesprávne špecifikovaný (\(\gamma_2 \ne 0 \quad \text{alebo} \quad \gamma_3 \ne 0\))

# Suppose your model is:
model <- lm(Unemployment_Rate ~ +1 + GDP_Growth_Annual + Inflation_CPI, data = udaje)

# RESET test from 'lmtest' package:
library(lmtest)
resettest(model)

    RESET test

data:  model
RESET = 0.70943, df1 = 2, df2 = 8, p-value = 0.5204

Interpretácia:

Na základe výsledkov RESET testu (p-hodnota = 0.5204) nezamietame nulovú hypotézu o správnej špecifikácii modelu. Model teda pravdepodobne neobsahuje štrukturálnu chybu a lineárna forma sa javí ako vhodná.

2. Grafická analýza

Graf Residuals vs. Fitted

Grafická analýza vzťahu medzi vyrovnanými hodnotami náhodnej premennej a rezíduami:

plot(model, which = 1)

Graf rezíduí voči vyrovnaným hodnotám ukazuje mierne systematické zakrivenie, čo naznačuje, že rezíduá nemajú úplne náhodný charakter. Tento vzor môže poukazovať na nelinearitu v modeli alebo na chýbajúcu vysvetľujúcu premennú.

Grafy C+R

Táto analýza nám môže pomôcť pri hľadaní odpovede na otázku, ktorú premennú by sme mali transfomovať pomocou nejakej známej funkcie. Vychádzajme z pôvodnej rovnice

\[y_t = \beta_0 + \beta_1 x_{t1} + \dots +\beta_k x_{tk} + u_t\] Túto rovnicu najprv odhadneme a potom vykresľujeme grafy, kde výraz component+residual (C+R) plot vykresľuje na zvislej osi \(\hat{\beta}_ix_{ti}+e_t\) a na vodorovnej osi vykresľuje hodnoty \(x_{ti}\)

Tieto grafy pomáhajú identifikovať nelineárne vzťahy pre každý regresor:

car::crPlots(model)

Component + Residual grafy naznačujú, že v mojom modeli sú prítomné nelineárne vzťahy. Výrazný odklon od lineárnej špecifikácie vidíme pri premenných Inflation_CPI a GDP_Growth_Annual, kde sa ružová krivka podstatne odchyľuje od modrej priamky. To naznačuje, že lineárny model nemusí správne zachytávať ich vplyv na nezamestnanosť a môže byť vhodné zvážiť transformáciu týchto premenných.

3. Nelineárna špecifikácia

Častokrát môžeme aj zložitejšie nelineárne vzťahy modelovať s pomocou ich aproximácie s polynómom, teda v prípade kvadratických členov

\[y_t = \beta_0 + \beta_1 x_{t10} + \dots +\beta_k x_{tk} + \dots + \gamma_i\hat x_{ik}^2 + \dots + \gamma_j\hat x_{jk}^2 + \dots + u_t\] Príklad na túto modifikáciu uvidíme nižšie.

3. Porovnanie základného a modifikovaného modelu

Predpokladajme, že sa pri nelineárnych úpravách pôvodnej rovnice dostaneme k zavedeniu kvadrátu premenných GDP_Growth_Annual a Inflation_CPI, nakoľko nás k tomu motivuje Component + Residual Plot uvedený vyššie. Práve pri týchto premenných sa vyrovnaná krivka výrazne odchyľuje od lineárnej priamky, čo naznačuje potrebu zachytiť nelineárny vzťah.

Ak má transformovaný model vyšší upravený koefcient determinácie \(R^2_{adj}\) a pri RESET test prijmeme alternatívnu hypotézu, odporúčame si výsledky potvrdiť s pomocou Anova testu oboch modelov a prípadne opakovaného Reset Testu uplatneneného na nelineárne transformovaný model

model <- lm(Unemployment_Rate ~ +1 + GDP_Growth_Annual + Inflation_CPI)
model_kvadr <- lm(Unemployment_Rate ~ +1 + GDP_Growth_Annual + I(GDP_Growth_Annual^2) + Inflation_CPI + I(Inflation_CPI^2))
summary(model_kvadr)

Call:
lm(formula = Unemployment_Rate ~ +1 + GDP_Growth_Annual + I(GDP_Growth_Annual^2) + 
    Inflation_CPI + I(Inflation_CPI^2))

Residuals:
   Min     1Q Median     3Q    Max 
-4.369 -2.450 -0.166  3.813  4.252 

Coefficients:
                        Estimate Std. Error t value Pr(>|t|)
(Intercept)            10.210105   2.300219   4.439  0.00217
GDP_Growth_Annual       0.368454   0.795945   0.463  0.65576
I(GDP_Growth_Annual^2) -0.041092   0.138746  -0.296  0.77464
Inflation_CPI          -0.250819   1.000185  -0.251  0.80831
I(Inflation_CPI^2)     -0.005236   0.076596  -0.068  0.94717
                         
(Intercept)            **
GDP_Growth_Annual        
I(GDP_Growth_Annual^2)   
Inflation_CPI            
I(Inflation_CPI^2)       
---
Signif. codes:  
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3.867 on 8 degrees of freedom
Multiple R-squared:  0.1416,    Adjusted R-squared:  -0.2877 
F-statistic: 0.3298 on 4 and 8 DF,  p-value: 0.8506
anova(model, model_kvadr)
Analysis of Variance Table

Model 1: Unemployment_Rate ~ +1 + GDP_Growth_Annual + Inflation_CPI
Model 2: Unemployment_Rate ~ +1 + GDP_Growth_Annual + I(GDP_Growth_Annual^2) + 
    Inflation_CPI + I(Inflation_CPI^2)
  Res.Df    RSS Df Sum of Sq      F Pr(>F)
1     10 120.96                           
2      8 119.60  2    1.3594 0.0455 0.9558
resettest(model_kvadr)

    RESET test

data:  model_kvadr
RESET = 2.7558, df1 = 2, df2 = 6, p-value = 0.1416

Po rozšírení pôvodného modelu o kvadratické členy premenných GDP_Growth_Annual a Inflation_CPI sa ukazuje, že ani jedna z novopridaných premenných nie je štatisticky významná. Rovnako však ostávajú nevýznamné aj pôvodné vysvetľujúce premenné.

Upravený koeficient determinácie \(R^2_{adj}\) sa navyše znížil (z pôvodného nízkeho čísla na ešte nižšiu hodnotu – približne –0.29), čo znamená, že rozšírený model vysvetľuje variabilitu nezávislej premennej ešte horšie než základný model.

Porovnanie modelov pomocou ANOVA testu ukazuje, že pridanie kvadratických členov neviedlo k zlepšeniu modelu (p-hodnota ≈ 0.956). Rozšírený model teda nie je štatisticky odlišný od základného a neponúka lepší opis dát.

Aj podľa RESET testu (p ≈ 0.142) nemáme dôkazy o tom, že by model trpel nesprávnou funkčnou formou po pridaní kvadratických členov. To znamená, že rozšírenie modelu o druhé mocniny nezlepšilo špecifikáciu, ale zároveň ani nepoukazuje na novú nelinearitu.

Tento modifikovaný model teda nepriniesol žiadne zlepšenie – kvadratické členy sú štatisticky nevýznamné a hodnota \(R^2_{adj}\) klesla. Na rozdiel od príkladu v šablóne, kde sa po nelineárnej úprave model zlepšil, v mojom prípade doplnenie nelineárnych premenných nebolo prínosné.

Z tohto dôvodu nemá zmysel kvadratické členy ďalej používať a vhodnejšie je ostať pri pôvodnom lineárnom modeli.

5. Transformácia pomocou dummy premennej a lineárnej lomenej funkcie

Predpokladajme, že máme dummy premennú \(D_t\), ktorá obsahuje len nuly a jedničky. Takáto premenná sa dá využiť modelovanie zlomov, a to napr.

  1. zlom v autonómnom člene \(\beta_0\) a to nasledovnou špecifikáciou \[y_t = \beta_0 + \beta_D D+ \beta_1 x_{t1} + \dots +\beta_k x_{tk} + u_t\] čo interpretujeme ako posun regresnej priamky (regresnej nadroviny) o \(\beta_D\) jednotiek pozdĺž zvislej osi a to len v pozorovaniach, ak je splnená podmienka \(D_t = 1\)
  2. zlom v sklone regresnej priamky (nadroviny) a to len v pozorovaniach, ak je splnená podmienka \(D_t = 1\), čo dosiahneme nasledovnou špecifikáciou \[y_t = \beta_0 + \beta_1 x_{t1} + \dots + \beta_{i}x_{ti} + \beta_{Di}D_tx_{ti}+ \dots + \beta_k x_{tk} + u_t\] kde teda sklon priamky pozdĺž premenne \(x_{ti}\) je \(\beta_i\) ale len v prípade \(D_t=0\), inak je ten sklon rovný \(\beta_i+\beta_{D_i}\).

V mojom prípade hľadáme zlom v jednej z vysvetľujúcich premenných GDP_Growth_Annual alebo Inflation_CPI.

Podľa Component + Residual grafov sa najvýraznejší odklon od linearity objavuje pri premenných Inflation_CPI, kde krivka naznačuje zmenu smerovania približne pri hodnotách okolo 5–6 % inflácie.

Preto zavediem dummy premennú DUM, ktorá vyjadruje, či inflácia prekročila túto hodnotu.

Definícia dummy premennej:

ak je Inflation_CPI < 6, potom DUM = 0

ak je Inflation_CPI ≥ 6, potom DUM = 1

Takto dokážeme preskúmať, či sa intercept (autonómny člen) modelu mení pri vyššej úrovni inflácie.

udaje$DUM <- ifelse(udaje$Inflation_CPI < 6, 0, 1)
modelD_auto <- lm(Unemployment_Rate ~ +1 + DUM + GDP_Growth_Annual + Inflation_CPI,data=udaje ) 
summary(modelD_auto)

Call:
lm(formula = Unemployment_Rate ~ +1 + DUM + GDP_Growth_Annual + 
    Inflation_CPI, data = udaje)

Residuals:
   Min     1Q Median     3Q    Max 
-4.217 -2.530  0.000  3.296  4.295 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)   
(Intercept)        10.0627     2.1491   4.682  0.00115 **
DUM                -1.6582     8.9072  -0.186  0.85644   
GDP_Growth_Annual   0.1772     0.4473   0.396  0.70122   
Inflation_CPI      -0.1833     0.7320  -0.250  0.80793   
---
Signif. codes:  
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3.659 on 9 degrees of freedom
Multiple R-squared:  0.1351,    Adjusted R-squared:  -0.1532 
F-statistic: 0.4687 on 3 and 9 DF,  p-value: 0.7114

Na základe odhadu modelu môžeme konštatovať, že zavedenie dummy premennej DUM, ktorá reprezentuje možné zmeny v úrovni nezamestnanosti pri vyšších hodnotách inflácie, neprinieslo žiadny štatisticky významný efekt. Koeficient pri premennej DUM je síce záporný (–1.66), no jeho p-hodnota (0.856) je vysoko nad bežnými hladinami významnosti, čo znamená, že rozdiel v autonómnom člene medzi oboma skupinami (Inflation_CPI < 6 a ≥ 6) nie je štatisticky preukázateľný.

Rovnako aj ostatné premenné (GDP_Growth_Annual a Inflation_CPI) ostávajú v tomto modeli štatisticky nevýznamné a celková vysvetľovacia schopnosť modelu je nízka (R² = 0.1351, upravené R² dokonca negatívne).

V tomto prípade sa teda nepotvrdilo, že by existoval signifikantný zlom v autonómnom člene regresnej rovnice pri oddeľovaní krajín podľa úrovne inflácie. Zavedenie dummy premennej teda nezlepšuje model a nenaznačuje odlišné správanie nezamestnanosti v závislosti od toho, či inflácia prekročila stanovenú hranicu.


modelD_sklon <- lm(Unemployment_Rate ~ +1  + Inflation_CPI + I(DUM*Inflation_CPI) + GDP_Growth_Annual, data=udaje) 
summary(modelD_sklon)

Call:
lm(formula = Unemployment_Rate ~ +1 + Inflation_CPI + I(DUM * 
    Inflation_CPI) + GDP_Growth_Annual, data = udaje)

Residuals:
   Min     1Q Median     3Q    Max 
-4.217 -2.530  0.000  3.296  4.295 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)
(Intercept)             10.0627     2.1491   4.682  0.00115
Inflation_CPI           -0.1833     0.7320  -0.250  0.80793
I(DUM * Inflation_CPI)  -0.1298     0.6973  -0.186  0.85644
GDP_Growth_Annual        0.1772     0.4473   0.396  0.70122
                         
(Intercept)            **
Inflation_CPI            
I(DUM * Inflation_CPI)   
GDP_Growth_Annual        
---
Signif. codes:  
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3.659 on 9 degrees of freedom
Multiple R-squared:  0.1351,    Adjusted R-squared:  -0.1532 
F-statistic: 0.4687 on 3 and 9 DF,  p-value: 0.7114

V tomto modeli sme zaviedli interakčný člen I(DUM * Inflation_CPI), ktorý umožňuje, aby sa vplyv inflácie na mieru nezamestnanosti líšil medzi obdobiami s nižšou infláciou (DUM = 0) a obdobiami s vyššou infláciou (DUM = 1).

Z výsledkov však vyplýva, že:

koeficient pri Inflation_CPI je štatisticky nevýznamný (p = 0.80793),

interakčný koeficient I(DUM * Inflation_CPI) je taktiež úplne nevýznamný (p = 0.85644).

To znamená, že neexistuje dôkaz o tom, že by sa sklon regresnej priamky vzhľadom na infláciu líšil medzi obdobiami s nižšou a vyššou infláciou. Inými slovami, inflácia nemá štatisticky významny vplyv na mieru nezamestnanosti ani v jednej z týchto dvoch skupín období a rozdiel v sklonoch sa nepotvrdil.

Okrem toho:

upravený koeficient determinácie (−0.1532) naznačuje, že pridaním interakčného termu sa model nezlepšil, ale dokonca mierne zhoršil,

jediný štatisticky významný parameter je intercept,

celkový F-test (p = 0.7114) ukazuje, že model ako celok nie je štatisticky významný.

V tomto prípade sa teda nepotvrdilo, že by existoval štatisticky významný zlom v sklone regresnej funkcie. Interakcia medzi infláciou a dummy premennou je nevýznamná, takže vplyv inflácie na nezamestnanosť sa medzi obdobiami s nižšou a vyššou infláciou nelíši. Zavedením tejto úpravy sa model nezlepšil a jeho vysvetľovacia sila dokonca klesla.

anova(model, modelD_sklon)
Analysis of Variance Table

Model 1: Unemployment_Rate ~ +1 + GDP_Growth_Annual + Inflation_CPI
Model 2: Unemployment_Rate ~ +1 + Inflation_CPI + I(DUM * Inflation_CPI) + 
    GDP_Growth_Annual
  Res.Df    RSS Df Sum of Sq      F Pr(>F)
1     10 120.96                           
2      9 120.50  1   0.46403 0.0347 0.8564
resettest(modelD_sklon)

    RESET test

data:  modelD_sklon
RESET = 3.7203, df1 = 2, df2 = 7, p-value = 0.0793

ANOVA analýza ukázala, že pridanie interakčného členu I(DUM * Inflation_CPI) do modelu nezlepšilo jeho vysvetľovaciu schopnosť (p = 0.8564). RESET test naznačuje miernu možnosť nesprávnej špecifikácie modelu (p = 0.0793), preto je vhodné zvážiť doplnenie ďalších premenných alebo nelineárnych členov.

LS0tCnRpdGxlOiAixaBwZWNpZmlrw6FjaWEgbW9kZWx1IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKYXV0aG9yOiBCZWF0cml4IFTDs3Rob3bDoQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKYGBge3J9CmxpYnJhcnkoem9vKQpsaWJyYXJ5KHRzZXJpZXMpCmxpYnJhcnkobG10ZXN0KQpsaWJyYXJ5KHNhbmR3aWNoKQpsaWJyYXJ5KGNhcikKcm0obGlzdD1scygpKQpgYGAKCk1vamEgZGF0YWLDoXphIG9ic2FodWplIHJvxI1uw6kgbWFrcm9la29ub21pY2vDqSB1a2F6b3ZhdGVsZSBTbG92ZW5za2VqIHJlcHVibGlreSB2IG9iZG9iw60gMjAxMOKAkzIwMjIuIElkZSBvIGtvbWJpbsOhY2l1IHVrYXpvdmF0ZcS+b3YgaW5mbMOhY2llLCByYXN0dSBIRFAsIHZlcmVqbsO9Y2ggZmluYW5jacOtLCBiZcW+bsOpaG8gw7rEjXR1IGEgdsO9a29ubm9zdGkgZWtvbm9taWt5LgoKUG9tb2NvdSB2aWFjbsOhc29ibmVqIGxpbmXDoXJuZWogcmVncmVzaWUgc2vDum1hbWUsIGRvIGFrZWogbWllcnkgamUgbWllcmEgbmV6YW1lc3RuYW5vc3RpIG92cGx5dm5lbsOhIG1ha3JvZWtvbm9taWNrw71taSB1a2F6b3ZhdGXEvm1pLCBrb25rcsOpdG5lCnJvxI1uw71tIHJhc3RvbSBIRFAgKEdEUF9Hcm93dGhfQW5udWFsKSBhIGluZmzDoWNpb3UgbWVyYW5vdSBpbmRleG9tIENQSSAoSW5mbGF0aW9uX0NQSSkuCkNpZcS+b20gamUgemlzdGnFpSwga3RvcsOpIHogdMO9Y2h0byBmYWt0b3JvdiDFoXRhdGlzdGlja3kgdsO9em5hbW5lIHByaXNwaWV2YWrDuiBrIHZ5c3ZldGxlbml1IG1pZXJ5IG5lemFtZXN0bmFub3N0aS4KClbDvXNsZWRvayB0ZWp0byByZWdyZXNpZSBqZSB1dmVkZW7DvSBuacW+xaFpZToKCmBgYHtyfQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIFBSSVBSQVZBIFVEQUpPVgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwp1ZGFqZSA8LSByZWFkLmNzdigiZGF0YS5jc3YiLGRlYz0iLiIsc2VwPSI7IixoZWFkZXIgPSBUUlVFKQojIHbDvWJlciByZWxldmFudG7DvWNoIHByZW1lbm7DvWNoCnVkYWplIDwtIHVkYWplWyAsYygiVW5lbXBsb3ltZW50X1JhdGUiLCJHRFBfR3Jvd3RoX0FubnVhbCIsICJJbmZsYXRpb25fQ1BJIildIAoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBaQUtMQUROQSBSRUdSRVNJQQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwphdHRhY2godWRhamUpCm1vZGVsIDwtIGxtKFVuZW1wbG95bWVudF9SYXRlIH4gKzEgKyBHRFBfR3Jvd3RoX0FubnVhbCArIEluZmxhdGlvbl9DUEksIGRhdGEgPSB1ZGFqZSkKc3VtbWFyeShtb2RlbCkKYGBgCgpUZXN0b3ZhxaUsIMSNaSBqZSBtb2RlbCB2IHNwcsOhdm5laiBmdW5rxI1uZWogZm9ybWUgKHQuIGouIMSNaSBqZSBsaW5lw6FybmEgxaFwZWNpZmlrw6FjaWEgdmhvZG7DoSwgYWxlYm8gxI1pIGJ5IHNtZSBtYWxpIHRyYW5zZm9ybW92YcWlIHByZW1lbm7DqSwgbmFwcsOta2xhZCBwb21vY291IGxvZ2FyaXRtb3YgYWxlYm8gbW9jbmluYW1pKSwgbW/Fvm5vIHZ5a29uYcWlIHZpYWNlcsO9bWkgc3DDtHNvYm1pLgoKIyMjIDEuIFRlc3QgUkVTRVQgKHRlc3QgY2h5YnkgxaFwZWNpZmlrw6FjaWUgUmFtc2V5aG8gcmVncmVzbmVqIHJvdm5pY2UgLSBSYW1zZXkgUmVzZXQgVGVzdCkKCklkZSBvIG5hasWhdGFuZGFyZG5lasWhw60gZm9ybcOhbG55IHRlc3QgbmVzcHLDoXZuZWogxaFwZWNpZmlrw6FjaWUgZnVua8SNbmVqIGZvcm15IGFsZSBkw6Egc2EgcG91xb5pxaUgYWogcHJlIHByw61wYWR5LCBhayBzbWUgbmXFoXBlY2lmaWtvdmFsaSB2xaFldGt5IHZ5c3ZldMS+dWrDumNlIHByZW1lbm7DqS4KCk15xaFsaWVua2E6IE5lY2ggcMO0dm9kbsO9IG1vZGVsIG3DoSB0dmFyCiQkeV90ID0gXGJldGFfMCArIFxiZXRhXzEgeF97dDEwfSArIFxkb3RzICtcYmV0YV9rIHhfe3RrfSArIHVfdCQkCkFrIGplIG7DocWhIG1vZGVsIHNwcsOhdm5lIMWhcGVjaWZpa292YW7DvSwgcG90b20gcHJpZGFuw61tIG1vY27DrW4gdnlyb3ZuYW7DvWNoIGhvZG7DtHQgKG5hcHIuICRcaGF0IHlfdF4yJCwgJFxoYXR7eX1fdF4zJCkgYnkgc2EgcMO0dm9kbsO9IG1vZGVsIG5lbWFsIHBvZHN0YXRuZSB6bGVwxaFpxaUsIHRlZGEgYnVkZW1lIHRlc3RvdmHFpSBww7R2b2Ruw70gbW9kZWwgdXZlZGVuw70gdnnFocWhaWUgYSBtb2RlbAoKJCR5X3QgPSBcYmV0YV8wICsgXGJldGFfMSB4X3t0MTB9ICsgXGRvdHMgK1xiZXRhX2sgeF97dGt9ICsgXGdhbW1hXzJcaGF0IHlfdF4yICsgXGdhbW1hXzNcaGF0e3l9X3ReMyArIHVfdCQkCgpCdWRlbWUgdGVzdG92YcWlIGh5cG90w6l6dSAKCiRIXzA6JCBtb2RlbCBqZSBzcHLDoXZuZSDFoXBlY2lmaWtvdmFuw70gKCRcZ2FtbWFfMiA9IFxnYW1tYV8zID0gMCQpCgpvcHJvdGkKCiRIXzE6JCBtb2RlbCBqZSBuZXNwcsOhdm5lIMWhcGVjaWZpa292YW7DvSAoJFxnYW1tYV8yIFxuZSAwICBccXVhZCBcdGV4dHthbGVib30gIFxxdWFkIFxnYW1tYV8zIFxuZSAwJCkKCmBgYHtyfQojIFN1cHBvc2UgeW91ciBtb2RlbCBpczoKbW9kZWwgPC0gbG0oVW5lbXBsb3ltZW50X1JhdGUgfiArMSArIEdEUF9Hcm93dGhfQW5udWFsICsgSW5mbGF0aW9uX0NQSSwgZGF0YSA9IHVkYWplKQoKIyBSRVNFVCB0ZXN0IGZyb20gJ2xtdGVzdCcgcGFja2FnZToKbGlicmFyeShsbXRlc3QpCnJlc2V0dGVzdChtb2RlbCkKCmBgYAoKKipJbnRlcnByZXTDoWNpYToqKgoKTmEgesOha2xhZGUgdsO9c2xlZGtvdiBSRVNFVCB0ZXN0dSAocC1ob2Rub3RhID0gMC41MjA0KSBuZXphbWlldGFtZSBudWxvdsO6IGh5cG90w6l6dSBvIHNwcsOhdm5laiDFoXBlY2lmaWvDoWNpaSBtb2RlbHUuIE1vZGVsIHRlZGEgcHJhdmRlcG9kb2JuZSBuZW9ic2FodWplIMWhdHJ1a3R1csOhbG51IGNoeWJ1IGEgbGluZcOhcm5hIGZvcm1hIHNhIGphdsOtIGFrbyB2aG9kbsOhLgoKIyMjIDIuIEdyYWZpY2vDoSBhbmFsw716YQoKIyMjIyBHcmFmICpSZXNpZHVhbHMgdnMuIEZpdHRlZCoKCkdyYWZpY2vDoSBhbmFsw716YSB2esWlYWh1IG1lZHppIHZ5cm92bmFuw71taSBob2Rub3RhbWkgbsOhaG9kbmVqIHByZW1lbm5laiBhIHJlesOtZHVhbWk6CgpgYGB7cn0KcGxvdChtb2RlbCwgd2hpY2ggPSAxKQpgYGAKCkdyYWYgcmV6w61kdcOtIHZvxI1pIHZ5cm92bmFuw71tIGhvZG5vdMOhbSB1a2F6dWplIG1pZXJuZSBzeXN0ZW1hdGlja8OpIHpha3JpdmVuaWUsIMSNbyBuYXpuYcSNdWplLCDFvmUgcmV6w61kdcOhIG5lbWFqw7ogw7pwbG5lIG7DoWhvZG7DvSBjaGFyYWt0ZXIuIFRlbnRvIHZ6b3IgbcO0xb5lIHBvdWthem92YcWlIG5hIG5lbGluZWFyaXR1IHYgbW9kZWxpIGFsZWJvIG5hIGNow71iYWrDumN1IHZ5c3ZldMS+dWrDumN1IHByZW1lbm7Dui4KCiMjIyMgR3JhZnkgQytSCgpUw6F0byBhbmFsw716YSBuw6FtIG3DtMW+ZSBwb23DtGPFpSBwcmkgaMS+YWRhbsOtIG9kcG92ZWRlIG5hIG90w6F6a3UsIGt0b3LDuiBwcmVtZW5uw7ogYnkgc21lIG1hbGkgdHJhbnNmb21vdmHFpSBwb21vY291IG5lamFrZWogem7DoW1laiBmdW5rY2llLiBWeWNow6FkemFqbWUgeiBww7R2b2RuZWogcm92bmljZQoKJCR5X3QgPSBcYmV0YV8wICsgXGJldGFfMSB4X3t0MX0gKyBcZG90cyArXGJldGFfayB4X3t0a30gKyB1X3QkJApUw7p0byByb3ZuaWN1IG5hanBydiBvZGhhZG5lbWUgYSBwb3RvbSB2eWtyZXPEvnVqZW1lIGdyYWZ5LCBrZGUgdsO9cmF6IGNvbXBvbmVudCtyZXNpZHVhbCAoQytSKSBwbG90IHZ5a3Jlc8S+dWplIG5hIHp2aXNsZWogb3NpICRcaGF0e1xiZXRhfV9peF97dGl9K2VfdCQgYSBuYSB2b2Rvcm92bmVqIG9zaSB2eWtyZXPEvnVqZSBob2Rub3R5ICR4X3t0aX0kCgpUaWV0byBncmFmeSBwb23DoWhhasO6IGlkZW50aWZpa292YcWlIG5lbGluZcOhcm5lIHZ6xaVhaHkgcHJlIGthxb5kw70gcmVncmVzb3I6CgpgYGB7cn0KY2FyOjpjclBsb3RzKG1vZGVsKQoKYGBgCkNvbXBvbmVudCArIFJlc2lkdWFsIGdyYWZ5IG5hem5hxI11asO6LCDFvmUgdiBtb2pvbSBtb2RlbGkgc8O6IHByw610b21uw6kgbmVsaW5lw6FybmUgdnrFpWFoeS4gVsO9cmF6bsO9IG9ka2xvbiBvZCBsaW5lw6FybmVqIMWhcGVjaWZpa8OhY2llIHZpZMOtbWUgcHJpIHByZW1lbm7DvWNoIEluZmxhdGlvbl9DUEkgYSBHRFBfR3Jvd3RoX0FubnVhbCwga2RlIHNhIHJ1xb5vdsOhIGtyaXZrYSBwb2RzdGF0bmUgb2RjaHnEvnVqZSBvZCBtb2RyZWogcHJpYW1reS4gVG8gbmF6bmHEjXVqZSwgxb5lIGxpbmXDoXJueSBtb2RlbCBuZW11c8OtIHNwcsOhdm5lIHphY2h5dMOhdmHFpSBpY2ggdnBseXYgbmEgbmV6YW1lc3RuYW5vc8WlIGEgbcO0xb5lIGJ5xaUgdmhvZG7DqSB6dsOhxb5pxaUgdHJhbnNmb3Jtw6FjaXUgdMO9Y2h0byBwcmVtZW5uw71jaC4KCiMjIDMuIE5lbGluZcOhcm5hIMWhcGVjaWZpa8OhY2lhCgrEjGFzdG9rcsOhdCBtw7TFvmVtZSBhaiB6bG/Fvml0ZWrFoWllIG5lbGluZcOhcm5lIHZ6xaVhaHkgbW9kZWxvdmHFpSBzIHBvbW9jb3UgaWNoIGFwcm94aW3DoWNpZSBzIHBvbHluw7Ntb20sIHRlZGEgdiBwcsOtcGFkZSBrdmFkcmF0aWNrw71jaCDEjWxlbm92CgokJHlfdCA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfe3QxMH0gKyBcZG90cyArXGJldGFfayB4X3t0a30gKyBcZG90cyArIFxnYW1tYV9pXGhhdCB4X3tpa31eMiArIFxkb3RzICsgXGdhbW1hX2pcaGF0IHhfe2prfV4yICsgXGRvdHMgKyB1X3QkJApQcsOta2xhZCBuYSB0w7p0byBtb2RpZmlrw6FjaXUgdXZpZMOtbWUgbmnFvsWhaWUuCgojIyAzLiBQb3Jvdm5hbmllIHrDoWtsYWRuw6lobyBhIG1vZGlmaWtvdmFuw6lobyBtb2RlbHUKClByZWRwb2tsYWRham1lLCDFvmUgc2EgcHJpIG5lbGluZcOhcm55Y2ggw7pwcmF2w6FjaCBww7R2b2RuZWogcm92bmljZSBkb3N0YW5lbWUgayB6YXZlZGVuaXUga3ZhZHLDoXR1IHByZW1lbm7DvWNoIEdEUF9Hcm93dGhfQW5udWFsIGEgSW5mbGF0aW9uX0NQSSwgbmFrb8S+a28gbsOhcyBrIHRvbXUgbW90aXZ1amUgQ29tcG9uZW50ICsgUmVzaWR1YWwgUGxvdCB1dmVkZW7DvSB2ecWhxaFpZS4gUHLDoXZlIHByaSB0w71jaHRvIHByZW1lbm7DvWNoIHNhIHZ5cm92bmFuw6Ega3JpdmthIHbDvXJhem5lIG9kY2h5xL51amUgb2QgbGluZcOhcm5laiBwcmlhbWt5LCDEjW8gbmF6bmHEjXVqZSBwb3RyZWJ1IHphY2h5dGnFpSBuZWxpbmXDoXJueSB2esWlYWguIAoKQWsgbcOhIHRyYW5zZm9ybW92YW7DvSBtb2RlbCB2ecWhxaHDrSB1cHJhdmVuw70ga29lZmNpZW50IGRldGVybWluw6FjaWUgJFJeMl97YWRqfSQgYSBwcmkgUkVTRVQgdGVzdCBwcmlqbWVtZSBhbHRlcm5hdMOtdm51IGh5cG90w6l6dSwgb2Rwb3LDusSNYW1lIHNpIHbDvXNsZWRreSBwb3R2cmRpxaUgcyBwb21vY291IEFub3ZhIHRlc3R1IG9ib2NoIG1vZGVsb3YgYSBwcsOtcGFkbmUgb3Bha292YW7DqWhvIFJlc2V0IFRlc3R1IHVwbGF0bmVuZW7DqWhvIG5hIG5lbGluZcOhcm5lIHRyYW5zZm9ybW92YW7DvSBtb2RlbAoKYGBge3J9Cm1vZGVsIDwtIGxtKFVuZW1wbG95bWVudF9SYXRlIH4gKzEgKyBHRFBfR3Jvd3RoX0FubnVhbCArIEluZmxhdGlvbl9DUEkpCm1vZGVsX2t2YWRyIDwtIGxtKFVuZW1wbG95bWVudF9SYXRlIH4gKzEgKyBHRFBfR3Jvd3RoX0FubnVhbCArIEkoR0RQX0dyb3d0aF9Bbm51YWxeMikgKyBJbmZsYXRpb25fQ1BJICsgSShJbmZsYXRpb25fQ1BJXjIpKQpzdW1tYXJ5KG1vZGVsX2t2YWRyKQphbm92YShtb2RlbCwgbW9kZWxfa3ZhZHIpCnJlc2V0dGVzdChtb2RlbF9rdmFkcikKCmBgYAoKUG8gcm96xaHDrXJlbsOtIHDDtHZvZG7DqWhvIG1vZGVsdSBvIGt2YWRyYXRpY2vDqSDEjWxlbnkgcHJlbWVubsO9Y2ggR0RQX0dyb3d0aF9Bbm51YWwgYSBJbmZsYXRpb25fQ1BJIHNhIHVrYXp1amUsIMW+ZSBhbmkgamVkbmEgeiBub3ZvcHJpZGFuw71jaCBwcmVtZW5uw71jaCBuaWUgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw6EuIFJvdm5ha28gdsWhYWsgb3N0w6F2YWrDuiBuZXbDvXpuYW1uw6kgYWogcMO0dm9kbsOpIHZ5c3ZldMS+dWrDumNlIHByZW1lbm7DqS4KClVwcmF2ZW7DvSBrb2VmaWNpZW50IGRldGVybWluw6FjaWUgJFJeMl97YWRqfSQgc2EgbmF2ecWhZSB6bsOtxb5pbCAoeiBww7R2b2Ruw6lobyBuw616a2VobyDEjcOtc2xhIG5hIGXFoXRlIG5pxb7FoWl1IGhvZG5vdHUg4oCTIHByaWJsacW+bmUg4oCTMC4yOSksIMSNbyB6bmFtZW7DoSwgxb5lIHJvesWhw61yZW7DvSBtb2RlbCB2eXN2ZXTEvnVqZSB2YXJpYWJpbGl0dSBuZXrDoXZpc2xlaiBwcmVtZW5uZWogZcWhdGUgaG9yxaFpZSBuZcW+IHrDoWtsYWRuw70gbW9kZWwuCgpQb3Jvdm5hbmllIG1vZGVsb3YgcG9tb2NvdSBBTk9WQSB0ZXN0dSB1a2F6dWplLCDFvmUgcHJpZGFuaWUga3ZhZHJhdGlja8O9Y2ggxI1sZW5vdiBuZXZpZWRsbyBrIHpsZXDFoWVuaXUgbW9kZWx1IChwLWhvZG5vdGEg4omIIDAuOTU2KS4gUm96xaHDrXJlbsO9IG1vZGVsIHRlZGEgbmllIGplIMWhdGF0aXN0aWNreSBvZGxpxaFuw70gb2QgesOha2xhZG7DqWhvIGEgbmVwb27DumthIGxlcMWhw60gb3BpcyBkw6F0LgoKQWogcG9kxL5hIFJFU0VUIHRlc3R1IChwIOKJiCAwLjE0MikgbmVtw6FtZSBkw7RrYXp5IG8gdG9tLCDFvmUgYnkgbW9kZWwgdHJwZWwgbmVzcHLDoXZub3UgZnVua8SNbm91IGZvcm1vdSBwbyBwcmlkYW7DrSBrdmFkcmF0aWNrw71jaCDEjWxlbm92LiBUbyB6bmFtZW7DoSwgxb5lIHJvesWhw61yZW5pZSBtb2RlbHUgbyBkcnVow6kgbW9jbmlueSBuZXpsZXDFoWlsbyDFoXBlY2lmaWvDoWNpdSwgYWxlIHrDoXJvdmXFiCBhbmkgbmVwb3VrYXp1amUgbmEgbm92w7ogbmVsaW5lYXJpdHUuCgpUZW50byBtb2RpZmlrb3ZhbsO9IG1vZGVsIHRlZGEgbmVwcmluaWVzb2wgxb5pYWRuZSB6bGVwxaFlbmllIOKAkyBrdmFkcmF0aWNrw6kgxI1sZW55IHPDuiDFoXRhdGlzdGlja3kgbmV2w716bmFtbsOpIGEgaG9kbm90YSAkUl4yX3thZGp9JCBrbGVzbGEuIE5hIHJvemRpZWwgb2QgcHLDrWtsYWR1IHYgxaFhYmzDs25lLCBrZGUgc2EgcG8gbmVsaW5lw6FybmVqIMO6cHJhdmUgbW9kZWwgemxlcMWhaWwsIHYgbW9qb20gcHLDrXBhZGUgZG9wbG5lbmllIG5lbGluZcOhcm55Y2ggcHJlbWVubsO9Y2ggbmVib2xvIHByw61ub3Nuw6kuCgpaIHRvaHRvIGTDtHZvZHUgbmVtw6Egem15c2VsIGt2YWRyYXRpY2vDqSDEjWxlbnkgxI9hbGVqIHBvdcW+w612YcWlIGEgdmhvZG5lasWhaWUgamUgb3N0YcWlIHByaSBww7R2b2Rub20gbGluZcOhcm5vbSBtb2RlbGkuCgojIyMgNS4gVHJhbnNmb3Jtw6FjaWEgcG9tb2NvdSBkdW1teSBwcmVtZW5uZWogYSBsaW5lw6FybmVqIGxvbWVuZWogZnVua2NpZQoKUHJlZHBva2xhZGFqbWUsIMW+ZSBtw6FtZSBkdW1teSBwcmVtZW5uw7ogJERfdCQsIGt0b3LDoSBvYnNhaHVqZSBsZW4gbnVseSBhIGplZG5pxI1reS4gVGFrw6F0byBwcmVtZW5uw6Egc2EgZMOhIHZ5dcW+acWlIG1vZGVsb3ZhbmllIHpsb21vdiwgYSB0byBuYXByLgoKMS4gemxvbSB2IGF1dG9uw7Ntbm9tIMSNbGVuZSAkXGJldGFfMCQgYSB0byBuYXNsZWRvdm5vdSDFoXBlY2lmaWvDoWNpb3UKJCR5X3QgPSBcYmV0YV8wICsgXGJldGFfRCBEKyBcYmV0YV8xIHhfe3QxfSArIFxkb3RzICtcYmV0YV9rIHhfe3RrfSArIHVfdCQkCsSNbyBpbnRlcnByZXR1amVtZSBha28gcG9zdW4gcmVncmVzbmVqIHByaWFta3kgKHJlZ3Jlc25laiBuYWRyb3ZpbnkpIG8gJFxiZXRhX0QkIGplZG5vdGllayBwb3pkxLrFviB6dmlzbGVqIG9zaSBhIHRvIGxlbiB2IHBvem9yb3ZhbmlhY2gsIGFrIGplIHNwbG5lbsOhIHBvZG1pZW5rYSAkRF90ID0gMSQKMi4gemxvbSB2IHNrbG9uZSByZWdyZXNuZWogcHJpYW1reSAobmFkcm92aW55KSBhIHRvIGxlbiB2IHBvem9yb3ZhbmlhY2gsIGFrIGplIHNwbG5lbsOhIHBvZG1pZW5rYSAkRF90ID0gMSQsIMSNbyBkb3NpYWhuZW1lIG5hc2xlZG92bm91IMWhcGVjaWZpa8OhY2lvdQokJHlfdCA9IFxiZXRhXzAgKyAgXGJldGFfMSB4X3t0MX0gKyBcZG90cyArIFxiZXRhX3tpfXhfe3RpfSArIFxiZXRhX3tEaX1EX3R4X3t0aX0rIFxkb3RzICsgXGJldGFfayB4X3t0a30gKyB1X3QkJAprZGUgdGVkYSBza2xvbiBwcmlhbWt5IHBvemTEusW+IHByZW1lbm5lICR4X3t0aX0kIGplICRcYmV0YV9pJCBhbGUgbGVuIHYgcHLDrXBhZGUgJERfdD0wJCwgaW5hayBqZSB0ZW4gc2tsb24gcm92bsO9ICRcYmV0YV9pK1xiZXRhX3tEX2l9JC4KClYgbW9qb20gcHLDrXBhZGUgaMS+YWTDoW1lIHpsb20gdiBqZWRuZWogeiB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoIEdEUF9Hcm93dGhfQW5udWFsIGFsZWJvIEluZmxhdGlvbl9DUEkuCgpQb2TEvmEgQ29tcG9uZW50ICsgUmVzaWR1YWwgZ3JhZm92IHNhIG5hanbDvXJhem5lasWhw60gb2RrbG9uIG9kIGxpbmVhcml0eSBvYmphdnVqZSBwcmkgcHJlbWVubsO9Y2ggSW5mbGF0aW9uX0NQSSwga2RlIGtyaXZrYSBuYXpuYcSNdWplIHptZW51IHNtZXJvdmFuaWEgcHJpYmxpxb5uZSBwcmkgaG9kbm90w6FjaCBva29sbyA14oCTNiAlIGluZmzDoWNpZS4KClByZXRvIHphdmVkaWVtIGR1bW15IHByZW1lbm7DuiBEVU0sIGt0b3LDoSB2eWphZHJ1amUsIMSNaSBpbmZsw6FjaWEgcHJla3JvxI1pbGEgdMO6dG8gaG9kbm90dS4KCkRlZmluw61jaWEgZHVtbXkgcHJlbWVubmVqOgoKYWsgamUgSW5mbGF0aW9uX0NQSSA8IDYsIHBvdG9tIERVTSA9IDAKCmFrIGplIEluZmxhdGlvbl9DUEkg4omlIDYsIHBvdG9tIERVTSA9IDEKClRha3RvIGRva8Ohxb5lbWUgcHJlc2vDum1hxaUsIMSNaSBzYSBpbnRlcmNlcHQgKGF1dG9uw7NtbnkgxI1sZW4pIG1vZGVsdSBtZW7DrSBwcmkgdnnFocWhZWogw7pyb3ZuaSBpbmZsw6FjaWUuCgoKYGBge3J9CnVkYWplJERVTSA8LSBpZmVsc2UodWRhamUkSW5mbGF0aW9uX0NQSSA8IDYsIDAsIDEpCm1vZGVsRF9hdXRvIDwtIGxtKFVuZW1wbG95bWVudF9SYXRlIH4gKzEgKyBEVU0gKyBHRFBfR3Jvd3RoX0FubnVhbCArIEluZmxhdGlvbl9DUEksZGF0YT11ZGFqZSApIApzdW1tYXJ5KG1vZGVsRF9hdXRvKQpgYGAKTmEgesOha2xhZGUgb2RoYWR1IG1vZGVsdSBtw7TFvmVtZSBrb27FoXRhdG92YcWlLCDFvmUgemF2ZWRlbmllIGR1bW15IHByZW1lbm5laiBEVU0sIGt0b3LDoSByZXByZXplbnR1amUgbW/Fvm7DqSB6bWVueSB2IMO6cm92bmkgbmV6YW1lc3RuYW5vc3RpIHByaSB2ecWhxaHDrWNoIGhvZG5vdMOhY2ggaW5mbMOhY2llLCBuZXByaW5pZXNsbyDFvmlhZG55IMWhdGF0aXN0aWNreSB2w716bmFtbsO9IGVmZWt0LiBLb2VmaWNpZW50IHByaSBwcmVtZW5uZWogRFVNIGplIHPDrWNlIHrDoXBvcm7DvSAo4oCTMS42NiksIG5vIGplaG8gcC1ob2Rub3RhICgwLjg1NikgamUgdnlzb2tvIG5hZCBiZcW+bsO9bWkgaGxhZGluYW1pIHbDvXpuYW1ub3N0aSwgxI1vIHpuYW1lbsOhLCDFvmUgcm96ZGllbCB2IGF1dG9uw7Ntbm9tIMSNbGVuZSBtZWR6aSBvYm9tYSBza3VwaW5hbWkgKEluZmxhdGlvbl9DUEkgPCA2IGEg4omlIDYpIG5pZSBqZSDFoXRhdGlzdGlja3kgcHJldWvDoXphdGXEvm7DvS4KClJvdm5ha28gYWogb3N0YXRuw6kgcHJlbWVubsOpIChHRFBfR3Jvd3RoX0FubnVhbCBhIEluZmxhdGlvbl9DUEkpIG9zdMOhdmFqw7ogdiB0b210byBtb2RlbGkgxaF0YXRpc3RpY2t5IG5ldsO9em5hbW7DqSBhIGNlbGtvdsOhIHZ5c3ZldMS+b3ZhY2lhIHNjaG9wbm9zxaUgbW9kZWx1IGplIG7DrXprYSAoUsKyID0gMC4xMzUxLCB1cHJhdmVuw6kgUsKyIGRva29uY2EgbmVnYXTDrXZuZSkuCgpWIHRvbXRvIHByw61wYWRlIHNhIHRlZGEgbmVwb3R2cmRpbG8sIMW+ZSBieSBleGlzdG92YWwgc2lnbmlmaWthbnRuw70gemxvbSB2IGF1dG9uw7Ntbm9tIMSNbGVuZSByZWdyZXNuZWogcm92bmljZSBwcmkgb2RkZcS+b3ZhbsOtIGtyYWrDrW4gcG9kxL5hIMO6cm92bmUgaW5mbMOhY2llLiBaYXZlZGVuaWUgZHVtbXkgcHJlbWVubmVqIHRlZGEgbmV6bGVwxaF1amUgbW9kZWwgYSBuZW5hem5hxI11amUgb2RsacWhbsOpIHNwcsOhdmFuaWUgbmV6YW1lc3RuYW5vc3RpIHYgesOhdmlzbG9zdGkgb2QgdG9obywgxI1pIGluZmzDoWNpYSBwcmVrcm/EjWlsYSBzdGFub3ZlbsO6IGhyYW5pY3UuCgoKYGBge3J9Cgptb2RlbERfc2tsb24gPC0gbG0oVW5lbXBsb3ltZW50X1JhdGUgfiArMSAgKyBJbmZsYXRpb25fQ1BJICsgSShEVU0qSW5mbGF0aW9uX0NQSSkgKyBHRFBfR3Jvd3RoX0FubnVhbCwgZGF0YT11ZGFqZSkgCnN1bW1hcnkobW9kZWxEX3NrbG9uKQpgYGAKViB0b210byBtb2RlbGkgc21lIHphdmllZGxpIGludGVyYWvEjW7DvSDEjWxlbiBJKERVTSAqIEluZmxhdGlvbl9DUEkpLCBrdG9yw70gdW1vxb7FiHVqZSwgYWJ5IHNhIHZwbHl2IGluZmzDoWNpZSBuYSBtaWVydSBuZXphbWVzdG5hbm9zdGkgbMOtxaFpbCBtZWR6aSBvYmRvYmlhbWkgcyBuacW+xaFvdSBpbmZsw6FjaW91IChEVU0gPSAwKSBhIG9iZG9iaWFtaSBzIHZ5xaHFoW91IGluZmzDoWNpb3UgKERVTSA9IDEpLgoKWiB2w71zbGVka292IHbFoWFrIHZ5cGzDvXZhLCDFvmU6Cgprb2VmaWNpZW50IHByaSBJbmZsYXRpb25fQ1BJIGplIMWhdGF0aXN0aWNreSBuZXbDvXpuYW1uw70gKHAgPSAwLjgwNzkzKSwKCmludGVyYWvEjW7DvSBrb2VmaWNpZW50IEkoRFVNICogSW5mbGF0aW9uX0NQSSkgamUgdGFrdGllxb4gw7pwbG5lIG5ldsO9em5hbW7DvSAocCA9IDAuODU2NDQpLgoKVG8gem5hbWVuw6EsIMW+ZSBuZWV4aXN0dWplIGTDtGtheiBvIHRvbSwgxb5lIGJ5IHNhIHNrbG9uIHJlZ3Jlc25laiBwcmlhbWt5IHZ6aMS+YWRvbSBuYSBpbmZsw6FjaXUgbMOtxaFpbCBtZWR6aSBvYmRvYmlhbWkgcyBuacW+xaFvdSBhIHZ5xaHFoW91IGluZmzDoWNpb3UuIEluw71taSBzbG92YW1pLCBpbmZsw6FjaWEgbmVtw6EgxaF0YXRpc3RpY2t5IHbDvXpuYW1ueSB2cGx5diBuYSBtaWVydSBuZXphbWVzdG5hbm9zdGkgYW5pIHYgamVkbmVqIHogdMO9Y2h0byBkdm9jaCBza3Vww61uIG9iZG9iw60gYSByb3pkaWVsIHYgc2tsb25vY2ggc2EgbmVwb3R2cmRpbC4KCk9rcmVtIHRvaG86Cgp1cHJhdmVuw70ga29lZmljaWVudCBkZXRlcm1pbsOhY2llICjiiJIwLjE1MzIpIG5hem5hxI11amUsIMW+ZSBwcmlkYW7DrW0gaW50ZXJha8SNbsOpaG8gdGVybXUgc2EgbW9kZWwgbmV6bGVwxaFpbCwgYWxlIGRva29uY2EgbWllcm5lIHpob3LFoWlsLAoKamVkaW7DvSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSBwYXJhbWV0ZXIgamUgaW50ZXJjZXB0LAoKY2Vsa292w70gRi10ZXN0IChwID0gMC43MTE0KSB1a2F6dWplLCDFvmUgbW9kZWwgYWtvIGNlbG9rIG5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvS4KClYgdG9tdG8gcHLDrXBhZGUgc2EgdGVkYSBuZXBvdHZyZGlsbywgxb5lIGJ5IGV4aXN0b3ZhbCDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSB6bG9tIHYgc2tsb25lIHJlZ3Jlc25laiBmdW5rY2llLiBJbnRlcmFrY2lhIG1lZHppIGluZmzDoWNpb3UgYSBkdW1teSBwcmVtZW5ub3UgamUgbmV2w716bmFtbsOhLCB0YWvFvmUgdnBseXYgaW5mbMOhY2llIG5hIG5lemFtZXN0bmFub3PFpSBzYSBtZWR6aSBvYmRvYmlhbWkgcyBuacW+xaFvdSBhIHZ5xaHFoW91IGluZmzDoWNpb3UgbmVsw63FoWkuIFphdmVkZW7DrW0gdGVqdG8gw7pwcmF2eSBzYSBtb2RlbCBuZXpsZXDFoWlsIGEgamVobyB2eXN2ZXTEvm92YWNpYSBzaWxhIGRva29uY2Ega2xlc2xhLgoKYGBge3J9CmFub3ZhKG1vZGVsLCBtb2RlbERfc2tsb24pCnJlc2V0dGVzdChtb2RlbERfc2tsb24pCmBgYApBTk9WQSBhbmFsw716YSB1a8OhemFsYSwgxb5lIHByaWRhbmllIGludGVyYWvEjW7DqWhvIMSNbGVudSBJKERVTSAqIEluZmxhdGlvbl9DUEkpIGRvIG1vZGVsdSBuZXpsZXDFoWlsbyBqZWhvIHZ5c3ZldMS+b3ZhY2l1IHNjaG9wbm9zxaUgKHAgPSAwLjg1NjQpLiBSRVNFVCB0ZXN0IG5hem5hxI11amUgbWllcm51IG1vxb5ub3PFpSBuZXNwcsOhdm5laiDFoXBlY2lmaWvDoWNpZSBtb2RlbHUgKHAgPSAwLjA3OTMpLCBwcmV0byBqZSB2aG9kbsOpIHp2w6HFvmnFpSBkb3BsbmVuaWUgxI9hbMWhw61jaCBwcmVtZW5uw71jaCBhbGVibyBuZWxpbmXDoXJueWNoIMSNbGVub3YuCg==