Import súboru

Naimportujeme si dataset s údajmi všetkých krajín.

# import the dataset and create a data.frame udaje
udaje_svet <- read.csv("udaje/Life-Expectancy-Data-Updated.csv",header=TRUE,sep=",",dec=".",check.names = TRUE)
head(udaje_svet)
 udaje_svet <- udaje_svet[-992,]

Vyberieme si len pozorovania pre Albánsko.

# z databázy udaje_svet si vyberieme len tie pozorovania, ktoré sa týkajú Abánska 
udaje <- subset(udaje_svet, Country == "Albania")

Zvolíme si tri premenné ktoré chceme pozorovať, nainštalujeme potrebné knižnice a vytvoríme regresný model.

# vyrovnanie priebehu očakávanej dĺžky dožitia v čase
model <- lm(Life_expectancy ~ Alcohol_consumption+Adult_mortality+Incidents_HIV,data = udaje)
library(broom)
library(knitr)
library(kableExtra)

# koeficienty regresie
tidy(model) %>%
  kable(digits = 3, caption = "Odhadnuté koeficienty regresie") %>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Odhadnuté koeficienty regresie
term estimate std.error statistic p.value
(Intercept) 105.254 3.678 28.614 0.000
Alcohol_consumption -0.018 0.202 -0.091 0.929
Adult_mortality -0.339 0.042 -8.006 0.000
Incidents_HIV -44.297 31.242 -1.418 0.184

# kvalita vyrovnania
glance(model) %>%
  kable(digits = 3, caption = "Ukazovatele kvality vyrovnania") %>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE)
Ukazovatele kvality vyrovnania
r.squared adj.r.squared sigma statistic p.value df logLik AIC BIC deviance df.residual nobs
0.953 0.941 0.299 74.885 0 3 -0.847 11.694 15.234 0.983 11 15
NA

Pre x vyberieme tri už zvolené premenné z dát, vypočítame medzi nimi korelačnú maticu s ignorovaním chýbajúcich hodnôt a výsledné korelácie zaokrúhlime na štyri desatinné miesta.

# výber premenných
X <- udaje[, c("Alcohol_consumption", "Adult_mortality", "Incidents_HIV")]

# výpočet korelačnej matice
cor_matrix <- cor(X, use = "complete.obs")

# zaokrúhlenie
round(cor_matrix, 4)
                    Alcohol_consumption Adult_mortality Incidents_HIV
Alcohol_consumption              1.0000          0.0106        0.4130
Adult_mortality                  0.0106          1.0000       -0.8066
Incidents_HIV                    0.4130         -0.8066        1.0000

Vidíme, že najsilnejší vzťah je medzi Adult_mortality a Incidents_HIV (korelácia −0.8066), čo znamená silnú negatívnu závislosť, keď jedna premenná rastie, druhá klesá.

Vzťah medzi Alcohol_consumption a Incidents_HIV je stredne silný pozitívny (0.4130) a medzi Alcohol_consumption a Adult_mortality je takmer nulový (0.0106), teda prakticky žiadny.

S pomocou knižnice knitr si môžeme vytvoriť aj vizuálne krajšiu a prehľadnejšiu tabuľku pre korelačnú maticu.

library(knitr)
round(cor_matrix, 4) %>%
  kable(caption = "Korelačná matica")
Korelačná matica
Alcohol_consumption Adult_mortality Incidents_HIV
Alcohol_consumption 1.0000 0.0106 0.4130
Adult_mortality 0.0106 1.0000 -0.8066
Incidents_HIV 0.4130 -0.8066 1.0000

Následne spravíme cor testy kedy ždy kombinujeme každú premennú s každou a pozorujeme výsledky p- value.

cor.test (udaje$Adult_mortality, udaje$Alcohol_consumption)

    Pearson's product-moment correlation

data:  udaje$Adult_mortality and udaje$Alcohol_consumption
t = 0.038131, df = 13, p-value = 0.9702
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.5044203  0.5200209
sample estimates:
      cor 
0.0105751 
cor.test (udaje$Alcohol_consumption, udaje$Incidents_HIV)

    Pearson's product-moment correlation

data:  udaje$Alcohol_consumption and udaje$Incidents_HIV
t = 1.6351, df = 13, p-value = 0.126
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.1258822  0.7636995
sample estimates:
      cor 
0.4130138 
cor.test (udaje$Adult_mortality, udaje$Incidents_HIV )

    Pearson's product-moment correlation

data:  udaje$Adult_mortality and udaje$Incidents_HIV
t = -4.9197, df = 13, p-value = 0.0002801
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.9332439 -0.5015452
sample estimates:
       cor 
-0.8065793 

Medzi premennými Adult_mortality a Alcohol_consumption je p-value 0.9702, čo je veľmi vysoká hodnota, takže vzťah nie je štatisticky významný. Medzi Alcohol_consumption a Incidents_HIV je p-value 0.126, čo je tiež viac ako 0.05, preto ani tento vzťah nie je štatisticky významný. Naopak medzi Adult_mortality a Incidents_HIV je p-value 0.0002801, čo je menej ako 0.05, takže tento vzťah je štatisticky významný.

Multicollinearity detection and testing

V prípade potreby nainštalujeme balík corrplot, následne ho načítame a zobrazíme korelačnú maticu ako graf s číselnými hodnotami v hornej časti.

if (!requireNamespace("corrplot", quietly = TRUE)) {
  install.packages("corrplot")}

library(corrplot)

corrplot(cor_matrix, method = "number", type = "upper")

Vidíme výrazný vzťah medzi Adult_mortality a Incidience_HIV s hodnotou -0.81, ktorá sa zobrazuje červenou farbou.

Variance Inflation Factor

Pre premennú \(x_j\) definujeme

\[ VIF_j = \frac{1}{1-R_j^2}, \]

kde \(R_j^2\) je koeficient determinácie z pomocnej regresie, v ktorej je \(x_j\) vysvetľovaná ostatnými regresormi.

Ak je \(R_j^2\) blízko jednej, potom je \(VIF_j\) veľký a premenná \(x_j\) je silno lineárne vysvetliteľná ostatnými premennými.

V prípade potreby nainštalujeme balík car. # install.packages(“car”) # run once if not installed

Urobíme načítanie balíka car, následne vypočítame hodnoty VIF (Variance Inflation Factors) pre model model a zobrazíme ich, aby sme posúdili multikolinearitu medzi premennými.

library(car)
# Variance Inflation Factors
vif_values <- vif(model)

vif_values
Alcohol_consumption     Adult_mortality       Incidents_HIV 
           2.035214            4.830860            5.823734 

Interpretation:

  • \(VIF_j = 1\): žiadna multikolinearita,
  • \(1 < VIF_j < 5\): mierna multikolinearita
  • \(VIF_j \geq 5\): silná multikolinearita (niektorí autori používajú prísnejší prah \(VIF_j \geq 10\)).

Číslo podmienenosti

Číslo podmienenosti je založené na vlastných číslach matice \(X'X\). Ak sú vlastné čísla veľmi rozdielne, matica je zle podmienená.

\[ \kappa = \sqrt{\frac{\lambda_{\max}}{\lambda_{\min}}}. \]

Urobíme štandardizáciu premenných v matici X, následne vypočítame vlastné čísla korelačnej matice a z nich určíme podmienené číslo (condition number), ktoré nám slúži na posúdenie multikolinearity a stability modelu, a potom zobrazíme vlastné čísla aj výsledné podmienené číslo.

X_scaled <- scale(X)
eigen_values <- eigen(cor(X_scaled))$values

condition_number <- sqrt(max(eigen_values) / min(eigen_values))
eigen_values
condition_number

Interpretácia čísla podmienenosti: - \(\kappa \approx 1\): žiadna multikolinearita, - \(\kappa > 10\): mierna multikolinearita, - \(\kappa > 30\): silná multikolinearita.

Malá p-hodnota znamená, že zamietame hypotézu \(R=I_k\), teda medzi vysvetľujúcimi premennými existuje štatisticky významná korelačná štruktúra.

Eliminácia problému multikolinearity

Multikolinearita nie je porušením exogenity. Nie je teda automaticky dôvodom na zamietnutie OLS modelu. Problém je hlavne inferenčný: veľké štandardné chyby a nestabilné individuálne koeficienty.

Možné riešenia:

  1. získať viac dát,
  2. odstrániť alebo spojiť silno korelované premenné,
  3. transformovať premenné,
  4. použiť teoretické obmedzenia,
  5. použiť regularizačné metódy, napríklad ridge regresiu.

Odstránenie jednej z korelovaných premenných

Ak sú dve premenné takmer rovnaké a ekonomická teória nevyžaduje obe, môžeme jednu z nich vynechať. Odstránime premennú Adult_mortality a pozorujeme výsledky.

model_reduced <- lm(Life_expectancy ~ Alcohol_consumption + Incidents_HIV, data = udaje)

summary(model)

Call:
lm(formula = Life_expectancy ~ Alcohol_consumption + Adult_mortality + 
    Incidents_HIV, data = udaje)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.30738 -0.07191  0.00501  0.06394  0.33087 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)         80.406412   0.629177 127.796  < 2e-16 ***
Alcohol_consumption -0.009374   0.038803  -0.242    0.813    
Adult_mortality     -0.056383   0.002029 -27.784 2.92e-12 ***
Incidents_HIV        1.342110   0.899627   1.492    0.162    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1938 on 12 degrees of freedom
Multiple R-squared:  0.9876,    Adjusted R-squared:  0.9845 
F-statistic: 318.6 on 3 and 12 DF,  p-value: 1.06e-11
summary(model_reduced)

Call:
lm(formula = Life_expectancy ~ Alcohol_consumption + Incidents_HIV, 
    data = udaje)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.4850 -1.0324 -0.5959  0.9277  2.5740 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         65.54601    2.57299  25.475 1.76e-12 ***
Alcohol_consumption -0.08151    0.30065  -0.271    0.791    
Incidents_HIV       10.91938    6.45281   1.692    0.114    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.505 on 13 degrees of freedom
Multiple R-squared:   0.19, Adjusted R-squared:  0.06535 
F-statistic: 1.524 on 2 and 13 DF,  p-value: 0.2542

V pôvodnom modeli, kde boli zahrnuté všetky tri premenné (Alcohol_consumption, Adult_mortality a Incidents_HIV), model vysvetľoval veľmi vysokú časť variability v očakávanej dĺžke života, keďže R² = 0.9876 a model bol celkovo štatisticky významný (p-value ≈ 1.06e-11). Z jednotlivých premenných sa však ako štatisticky významná ukázala iba Adult_mortality (p < 0.001), zatiaľ čo Alcohol_consumption aj Incidents_HIV neboli významné.

Po odstránení premennej Adult_mortality sa model výrazne zhoršil, keďže R² kleslo na 0.19 a upravené R² dokonca na 0.065, čo znamená, že model už vysvetľuje len malú časť variability. Celý model už nie je štatisticky významný (p-value = 0.2542) a ani jednotlivé premenné (Alcohol_consumption a Incidents_HIV) nie sú štatisticky významné.

Adult_mortality je teda kľúčová premenná v modeli, bez nej model stráca vysvetľovaciu silu a výrazne sa zhoršuje jeho kvalita.

LS0tCnRpdGxlOiAiTXVsdGlrb2xpbmVhcml0YSB2IGxpbmXDoXJuZWogcmVncmVzaWkiCmF1dGhvcjogIk5hdMOhbGlhIEt1bm92w6EiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKLS0tCiMjICBJbXBvcnQgc8O6Ym9ydQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkKc2V0LnNlZWQoMTIzKQpgYGAKCk5haW1wb3J0dWplbWUgc2kgZGF0YXNldCBzIMO6ZGFqbWkgdsWhZXRrw71jaCBrcmFqw61uLgpgYGB7cn0KIyBpbXBvcnQgdGhlIGRhdGFzZXQgYW5kIGNyZWF0ZSBhIGRhdGEuZnJhbWUgdWRhamUKdWRhamVfc3ZldCA8LSByZWFkLmNzdigidWRhamUvTGlmZS1FeHBlY3RhbmN5LURhdGEtVXBkYXRlZC5jc3YiLGhlYWRlcj1UUlVFLHNlcD0iLCIsZGVjPSIuIixjaGVjay5uYW1lcyA9IFRSVUUpCmhlYWQodWRhamVfc3ZldCkKIHVkYWplX3N2ZXQgPC0gdWRhamVfc3ZldFstOTkyLF0KYGBgCgpWeWJlcmllbWUgc2kgbGVuIHBvem9yb3ZhbmlhIHByZSBBbGLDoW5za28uCmBgYHtyfQojIHogZGF0YWLDoXp5IHVkYWplX3N2ZXQgc2kgdnliZXJpZW1lIGxlbiB0aWUgcG96b3JvdmFuaWEsIGt0b3LDqSBzYSB0w71rYWrDuiBBYsOhbnNrYSAKdWRhamUgPC0gc3Vic2V0KHVkYWplX3N2ZXQsIENvdW50cnkgPT0gIkFsYmFuaWEiKQpgYGAKClp2b2zDrW1lIHNpIHRyaSBwcmVtZW5uw6kga3RvcsOpIGNoY2VtZSBwb3pvcm92YcWlLCBuYWluxaF0YWx1amVtZSBwb3RyZWJuw6kga25pxb5uaWNlIGEgdnl0dm9yw61tZSByZWdyZXNuw70gbW9kZWwuCmBgYHtyfQojIHZ5cm92bmFuaWUgcHJpZWJlaHUgb8SNYWvDoXZhbmVqIGTEusW+a3kgZG/Fvml0aWEgdiDEjWFzZQptb2RlbCA8LSBsbShMaWZlX2V4cGVjdGFuY3kgfiBBbGNvaG9sX2NvbnN1bXB0aW9uK0FkdWx0X21vcnRhbGl0eStJbmNpZGVudHNfSElWLGRhdGEgPSB1ZGFqZSkKbGlicmFyeShicm9vbSkKbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQoKIyBrb2VmaWNpZW50eSByZWdyZXNpZQp0aWR5KG1vZGVsKSAlPiUKICBrYWJsZShkaWdpdHMgPSAzLCBjYXB0aW9uID0gIk9kaGFkbnV0w6kga29lZmljaWVudHkgcmVncmVzaWUiKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRkFMU0UpCgojIGt2YWxpdGEgdnlyb3ZuYW5pYQpnbGFuY2UobW9kZWwpICU+JQogIGthYmxlKGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiVWthem92YXRlbGUga3ZhbGl0eSB2eXJvdm5hbmlhIikgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEZBTFNFKQoKYGBgClByZSB4IHZ5YmVyaWVtZSB0cmkgdcW+IHp2b2xlbsOpIHByZW1lbm7DqSB6IGTDoXQsIHZ5cG/EjcOtdGFtZSBtZWR6aSBuaW1pIGtvcmVsYcSNbsO6IG1hdGljdSBzIGlnbm9yb3ZhbsOtbSBjaMO9YmFqw7pjaWNoIGhvZG7DtHQgYSB2w71zbGVkbsOpIGtvcmVsw6FjaWUgemFva3LDumhsaW1lIG5hIMWhdHlyaSBkZXNhdGlubsOpIG1pZXN0YS4KYGBge3J9CiMgdsO9YmVyIHByZW1lbm7DvWNoClggPC0gdWRhamVbLCBjKCJBbGNvaG9sX2NvbnN1bXB0aW9uIiwgIkFkdWx0X21vcnRhbGl0eSIsICJJbmNpZGVudHNfSElWIildCgojIHbDvXBvxI1ldCBrb3JlbGHEjW5laiBtYXRpY2UKY29yX21hdHJpeCA8LSBjb3IoWCwgdXNlID0gImNvbXBsZXRlLm9icyIpCgojIHphb2tyw7pobGVuaWUKcm91bmQoY29yX21hdHJpeCwgNCkKYGBgClZpZMOtbWUsIMW+ZSBuYWpzaWxuZWrFocOtIHZ6xaVhaCBqZSBtZWR6aSBBZHVsdF9tb3J0YWxpdHkgYSBJbmNpZGVudHNfSElWIChrb3JlbMOhY2lhIOKIkjAuODA2NiksIMSNbyB6bmFtZW7DoSBzaWxuw7ogbmVnYXTDrXZudSB6w6F2aXNsb3PFpSwga2XEjyBqZWRuYSBwcmVtZW5uw6EgcmFzdGllLCBkcnVow6Ega2xlc8OhLgoKVnrFpWFoIG1lZHppIEFsY29ob2xfY29uc3VtcHRpb24gYSBJbmNpZGVudHNfSElWIGplIHN0cmVkbmUgc2lsbsO9IHBveml0w612bnkgKDAuNDEzMCkgYSBtZWR6aSBBbGNvaG9sX2NvbnN1bXB0aW9uIGEgQWR1bHRfbW9ydGFsaXR5IGplIHRha21lciBudWxvdsO9ICgwLjAxMDYpLCB0ZWRhIHByYWt0aWNreSDFvmlhZG55LgoKCgoKUyBwb21vY291IGtuacW+bmljZSBrbml0ciBzaSBtw7TFvmVtZSB2eXR2b3JpxaUgYWogdml6dcOhbG5lIGtyYWrFoWl1IGEgcHJlaMS+YWRuZWrFoWl1IHRhYnXEvmt1IHByZSBrb3JlbGHEjW7DuiBtYXRpY3UuCmBgYHtyfQpsaWJyYXJ5KGtuaXRyKQpyb3VuZChjb3JfbWF0cml4LCA0KSAlPiUKICBrYWJsZShjYXB0aW9uID0gIktvcmVsYcSNbsOhIG1hdGljYSIpCmBgYAoKCgpOw6FzbGVkbmUgc3ByYXbDrW1lIGNvciB0ZXN0eSBrZWR5IMW+ZHkga29tYmludWplbWUga2HFvmTDuiBwcmVtZW5uw7ogcyBrYcW+ZG91IGEgcG96b3J1amVtZSB2w71zbGVka3kgcC0gdmFsdWUuCmBgYHtyfQpjb3IudGVzdCAodWRhamUkQWR1bHRfbW9ydGFsaXR5LCB1ZGFqZSRBbGNvaG9sX2NvbnN1bXB0aW9uKQpjb3IudGVzdCAodWRhamUkQWxjb2hvbF9jb25zdW1wdGlvbiwgdWRhamUkSW5jaWRlbnRzX0hJVikKY29yLnRlc3QgKHVkYWplJEFkdWx0X21vcnRhbGl0eSwgdWRhamUkSW5jaWRlbnRzX0hJViApCmBgYApNZWR6aSBwcmVtZW5uw71taSBBZHVsdF9tb3J0YWxpdHkgYSBBbGNvaG9sX2NvbnN1bXB0aW9uIGplIHAtdmFsdWUgMC45NzAyLCDEjW8gamUgdmXEvm1pIHZ5c29rw6EgaG9kbm90YSwgdGFrxb5lIHZ6xaVhaCBuaWUgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70uIE1lZHppIEFsY29ob2xfY29uc3VtcHRpb24gYSBJbmNpZGVudHNfSElWIGplIHAtdmFsdWUgMC4xMjYsIMSNbyBqZSB0aWXFviB2aWFjIGFrbyAwLjA1LCBwcmV0byBhbmkgdGVudG8gdnrFpWFoIG5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvS4gTmFvcGFrIG1lZHppIEFkdWx0X21vcnRhbGl0eSBhIEluY2lkZW50c19ISVYgamUgcC12YWx1ZSAwLjAwMDI4MDEsIMSNbyBqZSBtZW5laiBha28gMC4wNSwgdGFrxb5lIHRlbnRvIHZ6xaVhaCBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvS4KCgojIE11bHRpY29sbGluZWFyaXR5IGRldGVjdGlvbiBhbmQgdGVzdGluZwpWIHByw61wYWRlIHBvdHJlYnkgbmFpbsWhdGFsdWplbWUgYmFsw61rIGNvcnJwbG90LCBuw6FzbGVkbmUgaG8gbmHEjcOtdGFtZSBhIHpvYnJhesOtbWUga29yZWxhxI1uw7ogbWF0aWN1IGFrbyBncmFmIHMgxI3DrXNlbG7DvW1pIGhvZG5vdGFtaSB2IGhvcm5laiDEjWFzdGkuCgpgYGB7ciBjb3JyZWxhdGlvbi1wbG90fQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoImNvcnJwbG90IiwgcXVpZXRseSA9IFRSVUUpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiY29ycnBsb3QiKX0KCmxpYnJhcnkoY29ycnBsb3QpCgpjb3JycGxvdChjb3JfbWF0cml4LCBtZXRob2QgPSAibnVtYmVyIiwgdHlwZSA9ICJ1cHBlciIpCmBgYApWaWTDrW1lIHbDvXJhem7DvSB2esWlYWggbWVkemkgQWR1bHRfbW9ydGFsaXR5IGEgSW5jaWRpZW5jZV9ISVYgcyBob2Rub3RvdSAtMC44MSwga3RvcsOhIHNhIHpvYnJhenVqZSDEjWVydmVub3UgZmFyYm91LgoKIyMgIFZhcmlhbmNlIEluZmxhdGlvbiBGYWN0b3IKClByZSBwcmVtZW5uw7ogXCh4X2pcKSBkZWZpbnVqZW1lCgpcWwpWSUZfaiA9IFxmcmFjezF9ezEtUl9qXjJ9LApcXQoKa2RlIFwoUl9qXjJcKSBqZSBrb2VmaWNpZW50IGRldGVybWluw6FjaWUgeiBwb21vY25laiByZWdyZXNpZSwgdiBrdG9yZWogamUgXCh4X2pcKSB2eXN2ZXTEvm92YW7DoSBvc3RhdG7DvW1pIHJlZ3Jlc29ybWkuCgpBayBqZSBcKFJfal4yXCkgYmzDrXprbyBqZWRuZWosIHBvdG9tIGplIFwoVklGX2pcKSB2ZcS+a8O9IGEgcHJlbWVubsOhIFwoeF9qXCkgamUgc2lsbm8gbGluZcOhcm5lIHZ5c3ZldGxpdGXEvm7DoSBvc3RhdG7DvW1pIHByZW1lbm7DvW1pLgoKViBwcsOtcGFkZSBwb3RyZWJ5IG5haW7FoXRhbHVqZW1lIGJhbMOtayBjYXIuCiMgaW5zdGFsbC5wYWNrYWdlcygiY2FyIikgICMgcnVuIG9uY2UgaWYgbm90IGluc3RhbGxlZAoKVXJvYsOtbWUgbmHEjcOtdGFuaWUgYmFsw61rYSBjYXIsIG7DoXNsZWRuZSB2eXBvxI3DrXRhbWUgaG9kbm90eSBWSUYgKFZhcmlhbmNlIEluZmxhdGlvbiBGYWN0b3JzKSBwcmUgbW9kZWwgbW9kZWwgYSB6b2JyYXrDrW1lIGljaCwgYWJ5IHNtZSBwb3PDumRpbGkgbXVsdGlrb2xpbmVhcml0dSBtZWR6aSBwcmVtZW5uw71taS4KYGBge3J9CmxpYnJhcnkoY2FyKQojIFZhcmlhbmNlIEluZmxhdGlvbiBGYWN0b3JzCnZpZl92YWx1ZXMgPC0gdmlmKG1vZGVsKQoKdmlmX3ZhbHVlcwpgYGAKCioqSW50ZXJwcmV0YXRpb246KioKCi0gXChWSUZfaiA9IDFcKTogxb5pYWRuYSBtdWx0aWtvbGluZWFyaXRhLAotIFwoMSA8IFZJRl9qIDwgNVwpOiBtaWVybmEgbXVsdGlrb2xpbmVhcml0YQotIFwoVklGX2ogXGdlcSA1XCk6IHNpbG7DoSBtdWx0aWtvbGluZWFyaXRhIChuaWVrdG9yw60gYXV0b3JpIHBvdcW+w612YWrDuiBwcsOtc25lasWhw60gcHJhaCBcKFZJRl9qIFxnZXEgMTBcKSkuCgojIyAgxIzDrXNsbyBwb2RtaWVuZW5vc3RpCgrEjMOtc2xvIHBvZG1pZW5lbm9zdGkgamUgemFsb8W+ZW7DqSBuYSB2bGFzdG7DvWNoIMSNw61zbGFjaCBtYXRpY2UgXChYJ1hcKS4gQWsgc8O6IHZsYXN0bsOpIMSNw61zbGEgdmXEvm1pIHJvemRpZWxuZSwgbWF0aWNhIGplIHpsZSBwb2RtaWVuZW7DoS4KClxbClxrYXBwYSA9IFxzcXJ0e1xmcmFje1xsYW1iZGFfe1xtYXh9fXtcbGFtYmRhX3tcbWlufX19LgpcXQoKVXJvYsOtbWUgxaF0YW5kYXJkaXrDoWNpdSBwcmVtZW5uw71jaCB2IG1hdGljaSBgWGAsIG7DoXNsZWRuZSB2eXBvxI3DrXRhbWUgdmxhc3Ruw6kgxI3DrXNsYSBrb3JlbGHEjW5laiBtYXRpY2UgYSB6IG5pY2ggdXLEjcOtbWUgcG9kbWllbmVuw6kgxI3DrXNsbyAoY29uZGl0aW9uIG51bWJlciksIGt0b3LDqSBuw6FtIHNsw7rFvmkgbmEgcG9zw7pkZW5pZSBtdWx0aWtvbGluZWFyaXR5IGEgc3RhYmlsaXR5IG1vZGVsdSwgYSBwb3RvbSB6b2JyYXrDrW1lIHZsYXN0bsOpIMSNw61zbGEgYWogdsO9c2xlZG7DqSBwb2RtaWVuZW7DqSDEjcOtc2xvLgoKYGBge3IgY29uZGl0aW9uLW51bWJlcn0KWF9zY2FsZWQgPC0gc2NhbGUoWCkKZWlnZW5fdmFsdWVzIDwtIGVpZ2VuKGNvcihYX3NjYWxlZCkpJHZhbHVlcwoKY29uZGl0aW9uX251bWJlciA8LSBzcXJ0KG1heChlaWdlbl92YWx1ZXMpIC8gbWluKGVpZ2VuX3ZhbHVlcykpCmVpZ2VuX3ZhbHVlcwpjb25kaXRpb25fbnVtYmVyCmBgYAoKICAKKipJbnRlcnByZXTDoWNpYSDEjcOtc2xhIHBvZG1pZW5lbm9zdGk6KiogCi0gXChca2FwcGEgXGFwcHJveCAxXCk6IMW+aWFkbmEgbXVsdGlrb2xpbmVhcml0YSwKLSBcKFxrYXBwYSA+IDEwXCk6IG1pZXJuYSBtdWx0aWtvbGluZWFyaXRhLAotIFwoXGthcHBhID4gMzBcKTogc2lsbsOhIG11bHRpa29saW5lYXJpdGEuCgogIApNYWzDoSBwLWhvZG5vdGEgem5hbWVuw6EsIMW+ZSB6YW1pZXRhbWUgaHlwb3TDqXp1IFwoUj1JX2tcKSwgdGVkYSBtZWR6aSB2eXN2ZXTEvnVqw7pjaW1pIHByZW1lbm7DvW1pIGV4aXN0dWplIMWhdGF0aXN0aWNreSB2w716bmFtbsOhIGtvcmVsYcSNbsOhIMWhdHJ1a3TDunJhLgoKCiMgIEVsaW1pbsOhY2lhIHByb2Jsw6ltdSBtdWx0aWtvbGluZWFyaXR5CgpNdWx0aWtvbGluZWFyaXRhIG5pZSBqZSBwb3J1xaFlbsOtbSBleG9nZW5pdHkuIE5pZSBqZSB0ZWRhIGF1dG9tYXRpY2t5IGTDtHZvZG9tIG5hIHphbWlldG51dGllIE9MUyBtb2RlbHUuIFByb2Jsw6ltIGplIGhsYXZuZSBpbmZlcmVuxI1uw706IHZlxL5rw6kgxaF0YW5kYXJkbsOpIGNoeWJ5IGEgbmVzdGFiaWxuw6kgaW5kaXZpZHXDoWxuZSBrb2VmaWNpZW50eS4KCk1vxb5uw6kgcmllxaFlbmlhOgoKMS4gesOtc2thxaUgdmlhYyBkw6F0LAoyLiBvZHN0csOhbmnFpSBhbGVibyBzcG9qacWlIHNpbG5vIGtvcmVsb3ZhbsOpIHByZW1lbm7DqSwKMy4gdHJhbnNmb3Jtb3ZhxaUgcHJlbWVubsOpLAo0LiBwb3XFvmnFpSB0ZW9yZXRpY2vDqSBvYm1lZHplbmlhLAo1LiBwb3XFvmnFpSByZWd1bGFyaXphxI1uw6kgbWV0w7NkeSwgbmFwcsOta2xhZCByaWRnZSByZWdyZXNpdS4KCiMjICBPZHN0csOhbmVuaWUgamVkbmVqIHoga29yZWxvdmFuw71jaCBwcmVtZW5uw71jaAoKQWsgc8O6IGR2ZSBwcmVtZW5uw6kgdGFrbWVyIHJvdm5ha8OpIGEgZWtvbm9taWNrw6EgdGXDs3JpYSBuZXZ5xb5hZHVqZSBvYmUsIG3DtMW+ZW1lIGplZG51IHogbmljaCB2eW5lY2hhxaUuIE9kc3Ryw6FuaW1lIHByZW1lbm7DuiBBZHVsdF9tb3J0YWxpdHkgYSBwb3pvcnVqZW1lIHbDvXNsZWRreS4KCmBgYHtyIHJlZHVjZWQtbW9kZWx9Cm1vZGVsX3JlZHVjZWQgPC0gbG0oTGlmZV9leHBlY3RhbmN5IH4gQWxjb2hvbF9jb25zdW1wdGlvbiArIEluY2lkZW50c19ISVYsIGRhdGEgPSB1ZGFqZSkKCnN1bW1hcnkobW9kZWwpCnN1bW1hcnkobW9kZWxfcmVkdWNlZCkKYGBgCgpWIHDDtHZvZG5vbSBtb2RlbGksIGtkZSBib2xpIHphaHJudXTDqSB2xaFldGt5IHRyaSBwcmVtZW5uw6kgKEFsY29ob2xfY29uc3VtcHRpb24sIEFkdWx0X21vcnRhbGl0eSBhIEluY2lkZW50c19ISVYpLCBtb2RlbCB2eXN2ZXTEvm92YWwgdmXEvm1pIHZ5c29rw7ogxI1hc8WlIHZhcmlhYmlsaXR5IHYgb8SNYWvDoXZhbmVqIGTEusW+a2Ugxb5pdm90YSwga2XEj8W+ZSBSwrIgPSAwLjk4NzYgYSBtb2RlbCBib2wgY2Vsa292byDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSAocC12YWx1ZSDiiYggMS4wNmUtMTEpLiBaIGplZG5vdGxpdsO9Y2ggcHJlbWVubsO9Y2ggc2EgdsWhYWsgYWtvIMWhdGF0aXN0aWNreSB2w716bmFtbsOhIHVrw6F6YWxhIGliYSBBZHVsdF9tb3J0YWxpdHkgKHAgPCAwLjAwMSksIHphdGlhxL4gxI1vIEFsY29ob2xfY29uc3VtcHRpb24gYWogSW5jaWRlbnRzX0hJViBuZWJvbGkgdsO9em5hbW7DqS4KClBvIG9kc3Ryw6FuZW7DrSBwcmVtZW5uZWogQWR1bHRfbW9ydGFsaXR5IHNhIG1vZGVsIHbDvXJhem5lIHpob3LFoWlsLCBrZcSPxb5lIFLCsiBrbGVzbG8gbmEgMC4xOSBhIHVwcmF2ZW7DqSBSwrIgZG9rb25jYSBuYSAwLjA2NSwgxI1vIHpuYW1lbsOhLCDFvmUgbW9kZWwgdcW+IHZ5c3ZldMS+dWplIGxlbiBtYWzDuiDEjWFzxaUgdmFyaWFiaWxpdHkuIENlbMO9IG1vZGVsIHXFviBuaWUgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gKHAtdmFsdWUgPSAwLjI1NDIpIGEgYW5pIGplZG5vdGxpdsOpIHByZW1lbm7DqSAoQWxjb2hvbF9jb25zdW1wdGlvbiBhIEluY2lkZW50c19ISVYpIG5pZSBzw7ogxaF0YXRpc3RpY2t5IHbDvXpuYW1uw6kuCgpBZHVsdF9tb3J0YWxpdHkgamUgdGVkYSBrxL7DusSNb3bDoSBwcmVtZW5uw6EgdiBtb2RlbGksIGJleiBuZWogbW9kZWwgc3Ryw6FjYSB2eXN2ZXTEvm92YWNpdSBzaWx1IGEgdsO9cmF6bmUgc2EgemhvcsWhdWplIGplaG8ga3ZhbGl0YS4K