knitr::opts_chunk$set(echo = TRUE)
library(zoo)
library(tseries)
library(lmtest)
library(sandwich)
library(car)
library(MASS)
rm(list=ls())

Ako závislú premennú som zvolila pce (osobná spotreba) a za vysvetľujúce premenné pop, psavert (osobné úspory) a uempmed (mediálna dĺžka nezamestnanosti)

PRÍPRAVA ÚDAJOV

udaje <- read.csv("economics.csv", header = TRUE, dec = ".")
# Vyberieme len stĺpce, ktoré budeme používať
udaje <- udaje[, c("pce","pop","psavert","uempmed")]


# Imputácia chýbajúcich hodnôt stĺpcov pomocou mediánu
column_medians <- sapply(udaje, median, na.rm = TRUE)
udaje_imputed <- udaje
for (col in names(udaje)) {
udaje_imputed[[col]][is.na(udaje_imputed[[col]])] <- column_medians[col]
}
udaje <- udaje_imputed


# Rýchly prehľad
summary(udaje)
      pce               pop            psavert          uempmed      
 Min.   :  506.7   Min.   :198712   Min.   : 2.200   Min.   : 4.000  
 1st Qu.: 1578.3   1st Qu.:224896   1st Qu.: 6.400   1st Qu.: 6.000  
 Median : 3936.8   Median :253060   Median : 8.400   Median : 7.500  
 Mean   : 4820.1   Mean   :257160   Mean   : 8.567   Mean   : 8.609  
 3rd Qu.: 7626.3   3rd Qu.:290291   3rd Qu.:11.100   3rd Qu.: 9.100  
 Max.   :12193.8   Max.   :320402   Max.   :17.300   Max.   :25.200  

ZÁKLADNÁ REGRESIA

attach(udaje)
model <- lm(pce ~ +1 + pop + psavert + uempmed, data = udaje)
summary(model)

Call:
lm(formula = pce ~ +1 + pop + psavert + uempmed, data = udaje)

Residuals:
   Min     1Q Median     3Q    Max 
-809.7 -392.7 -112.8  260.6 1296.0 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -2.162e+04  5.557e+02 -38.913  < 2e-16 ***
pop          9.869e-02  1.867e-03  52.857  < 2e-16 ***
psavert      8.682e+01  1.757e+01   4.942 1.02e-06 ***
uempmed      3.734e+01  9.669e+00   3.862 0.000125 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 519.5 on 570 degrees of freedom
Multiple R-squared:  0.9788,    Adjusted R-squared:  0.9787 
F-statistic:  8764 on 3 and 570 DF,  p-value: < 2.2e-16

1. TEST RESET (Ramsey RESET test)

resettest(model)

    RESET test

data:  model
RESET = 2997.9, df1 = 2, df2 = 568, p-value < 2.2e-16

2. Grafická analýza

plot(model, which = 1)

Component + Residual (C+R) plots pre každú vysvetľujúcu premennú

car::crPlots(model)

3. Nelineárna špecifikácia (pridanie kvadratických členov)

model_quad <- lm(pce ~ +1 + pop + psavert + uempmed + I(psavert^2) + I(pop^2))
summary(model_quad)

Call:
lm(formula = pce ~ +1 + pop + psavert + uempmed + I(psavert^2) + 
    I(pop^2))

Residuals:
    Min      1Q  Median      3Q     Max 
-290.97  -99.08   -7.56  112.23  327.74 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)   1.479e+04  4.871e+02  30.358  < 2e-16 ***
pop          -1.750e-01  3.648e-03 -47.970  < 2e-16 ***
psavert       3.173e+00  1.414e+01   0.224    0.823    
uempmed      -2.267e+01  2.969e+00  -7.636 9.52e-14 ***
I(psavert^2) -1.009e+00  7.577e-01  -1.332    0.184    
I(pop^2)      5.230e-07  6.956e-09  75.177  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 145.7 on 568 degrees of freedom
Multiple R-squared:  0.9983,    Adjusted R-squared:  0.9983 
F-statistic: 6.815e+04 on 5 and 568 DF,  p-value: < 2.2e-16
anova(model, model_quad)
Analysis of Variance Table

Model 1: pce ~ +1 + pop + psavert + uempmed
Model 2: pce ~ +1 + pop + psavert + uempmed + I(psavert^2) + I(pop^2)
  Res.Df       RSS Df Sum of Sq      F    Pr(>F)    
1    570 153826789                                  
2    568  12063268  2 141763522 3337.5 < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
resettest(model_quad)

    RESET test

data:  model_quad
RESET = 75.198, df1 = 2, df2 = 566, p-value < 2.2e-16

Ak sa ukáže, že niektoré kvadratické členy sú nevýznamné, odstránime ich a ponecháme len signifikantné.

# Ak napr. I(pop^2) nevychádza signifikantne, použijeme len psavert^2
model_quad2 <- lm(pce ~ +1 + pop + psavert + uempmed + I(psavert^2))
summary(model_quad2)

Call:
lm(formula = pce ~ +1 + pop + psavert + uempmed + I(psavert^2))

Residuals:
     Min       1Q   Median       3Q      Max 
-1890.50  -368.18   -74.83   160.65  1426.09 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -1.957e+04  5.576e+02 -35.091  < 2e-16 ***
pop           9.636e-02  1.748e-03  55.117  < 2e-16 ***
psavert      -3.151e+02  4.462e+01  -7.061 4.83e-12 ***
uempmed       5.636e+01  9.180e+00   6.139 1.56e-09 ***
I(psavert^2)  2.214e+01  2.289e+00   9.676  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 481.8 on 569 degrees of freedom
Multiple R-squared:  0.9818,    Adjusted R-squared:  0.9816 
F-statistic:  7664 on 4 and 569 DF,  p-value: < 2.2e-16

4. Rozšírený RESET test

model_rozsireny <- lm(pce ~ pop + psavert + uempmed + I(psavert^2) + I(pop^2) + I(uempmed^2))
summary(model_rozsireny)

Call:
lm(formula = pce ~ pop + psavert + uempmed + I(psavert^2) + I(pop^2) + 
    I(uempmed^2))

Residuals:
    Min      1Q  Median      3Q     Max 
-292.33  -99.21   -7.21  111.25  328.57 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)   1.475e+04  5.058e+02  29.159  < 2e-16 ***
pop          -1.747e-01  3.858e-03 -45.267  < 2e-16 ***
psavert       2.935e+00  1.418e+01   0.207  0.83611    
uempmed      -2.523e+01  9.651e+00  -2.614  0.00918 ** 
I(psavert^2) -9.791e-01  7.658e-01  -1.279  0.20155    
I(pop^2)      5.224e-07  7.262e-09  71.939  < 2e-16 ***
I(uempmed^2)  9.517e-02  3.417e-01   0.279  0.78072    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 145.9 on 567 degrees of freedom
Multiple R-squared:  0.9983,    Adjusted R-squared:  0.9983 
F-statistic: 5.67e+04 on 6 and 567 DF,  p-value: < 2.2e-16
anova(model, model_rozsireny)
Analysis of Variance Table

Model 1: pce ~ +1 + pop + psavert + uempmed
Model 2: pce ~ pop + psavert + uempmed + I(psavert^2) + I(pop^2) + I(uempmed^2)
  Res.Df       RSS Df Sum of Sq      F    Pr(>F)    
1    570 153826789                                  
2    567  12061617  3 141765172 2221.4 < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
resettest(model_rozsireny)

    RESET test

data:  model_rozsireny
RESET = 83.466, df1 = 2, df2 = 565, p-value < 2.2e-16

5. Transformácia pomocou dummy premennej (lom v sklone alebo intercepte)

udaje$DUM <- ifelse(udaje$psavert < 12, 0, 1)


# Zlom v autonómnom člene
modelD_auto <- lm(pce ~ +1 + DUM + pop + psavert + uempmed, data = udaje)
summary(modelD_auto)

Call:
lm(formula = pce ~ +1 + DUM + pop + psavert + uempmed, data = udaje)

Residuals:
   Min     1Q Median     3Q    Max 
-865.2 -333.8 -111.6  193.1 1431.7 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -2.077e+04  5.681e+02 -36.556  < 2e-16 ***
DUM          4.106e+02  7.913e+01   5.188 2.95e-07 ***
pop          9.647e-02  1.875e-03  51.443  < 2e-16 ***
psavert      3.553e+01  1.982e+01   1.792   0.0736 .  
uempmed      4.750e+01  9.656e+00   4.919 1.14e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 508.1 on 569 degrees of freedom
Multiple R-squared:  0.9797,    Adjusted R-squared:  0.9796 
F-statistic:  6878 on 4 and 569 DF,  p-value: < 2.2e-16
# Zlom v sklone (interakcia DUM * psavert)
modelD_sklon <- lm(pce ~ +1 + pop + psavert + I(DUM*psavert) + uempmed, data = udaje)
summary(modelD_sklon)

Call:
lm(formula = pce ~ +1 + pop + psavert + I(DUM * psavert) + uempmed, 
    data = udaje)

Residuals:
   Min     1Q Median     3Q    Max 
-841.1 -330.5 -113.2  197.6 1432.0 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)      -2.071e+04  5.711e+02 -36.271  < 2e-16 ***
pop               9.631e-02  1.883e-03  51.157  < 2e-16 ***
psavert           3.359e+01  2.002e+01   1.678   0.0939 .  
I(DUM * psavert)  3.168e+01  6.113e+00   5.182 3.05e-07 ***
uempmed           4.813e+01  9.683e+00   4.971 8.83e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 508.1 on 569 degrees of freedom
Multiple R-squared:  0.9797,    Adjusted R-squared:  0.9796 
F-statistic:  6878 on 4 and 569 DF,  p-value: < 2.2e-16
anova(model, modelD_sklon)
Analysis of Variance Table

Model 1: pce ~ +1 + pop + psavert + uempmed
Model 2: pce ~ +1 + pop + psavert + I(DUM * psavert) + uempmed
  Res.Df       RSS Df Sum of Sq      F    Pr(>F)    
1    570 153826789                                  
2    569 146894306  1   6932483 26.853 3.053e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
resettest(modelD_sklon)

    RESET test

data:  modelD_sklon
RESET = 3172.2, df1 = 2, df2 = 567, p-value < 2.2e-16

6. Box-Coxova transformácia

boxcox(model)

# Príklad pre lambda = 0 (log)
model_bc <- lm(I(log(pce)) ~ +1 + pop + psavert + uempmed, data = udaje)
summary(model_bc)

Call:
lm(formula = I(log(pce)) ~ +1 + pop + psavert + uempmed, data = udaje)

Residuals:
    Min      1Q  Median      3Q     Max 
-0.4294 -0.1419 -0.0129  0.1854  0.3044 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  2.249e+00  2.007e-01  11.209  < 2e-16 ***
pop          2.440e-05  6.742e-07  36.183  < 2e-16 ***
psavert     -3.058e-02  6.344e-03  -4.820 1.84e-06 ***
uempmed     -1.707e-02  3.491e-03  -4.888 1.33e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1876 on 570 degrees of freedom
Multiple R-squared:  0.9608,    Adjusted R-squared:  0.9606 
F-statistic:  4658 on 3 and 570 DF,  p-value: < 2.2e-16
resettest(model_bc)

    RESET test

data:  model_bc
RESET = 6935.7, df1 = 2, df2 = 568, p-value < 2.2e-16

Interpretácia a zhodnotenie výsledkov

1. Základný lineárny model

Model: \[ pce_i = β_0 + β_1 \, pop_i + β_2 \, psavert_i + β_3 \, uempmed_i + ε_i \]

Výsledky:

  • pop (obyvateľstvo): \(β_1 = 0.0987\), veľmi silno významný (p < 0.001).
    Väčší počet obyvateľov zvyšuje osobnú spotrebu – čím viac ľudí, tým väčší objem spotreby.
  • psavert (osobné úspory): \(β_2 = 86.82\), významný (p < 0.001).
    Vyššie úspory idú spolu s vyššou spotrebou – ľudia pri vyšších príjmoch môžu zároveň viac šetriť aj míňať.
  • uempmed (medián dĺžky nezamestnanosti): \(β_3 = 37.34\), významný (p = 0.0001).
    Dlhšia nezamestnanosť súvisí s mierne vyššou spotrebou – môže to byť spôsobené štruktúrou trhu práce, nie samotnou mierou nezamestnanosti.

Hodnotenie:

  • \(R^2 = 0.979\): model vysvetľuje takmer 98 % variability osobnej spotreby.
  • RESET test: p-hodnota < 0.001 → model je nesprávne špecifikovaný, chýbajú mu nelineárne prvky alebo interakcie.

2. Nelineárna špecifikácia – kvadratické členy

Pridali sa členy \(pop^2\) a \(psavert^2\).

Výsledky:

  • \(I(pop^2)\): veľmi významný (p < 0.001).
  • \(I(psavert^2)\): nevýznamný (p = 0.184).

To znamená, že populácia má nelineárny vplyv na spotrebu – rast obyvateľstva ju zvyšuje, ale s klesajúcou intenzitou.
Úspory sa správajú lineárne.

Porovnanie modelov:

  • ANOVA: p < 0.001 → kvadratické členy významne zlepšujú model.
  • \(R^2 = 0.9983\): model vysvetľuje takmer všetko.
  • RESET test: p < 0.001 → stále nelineárna špecifikácia.

3. Zjednodušený kvadratický model

Model s jedným kvadratickým členom \(psavert^2\):

  • \(I(psavert^2)\): významný (p < 0.001).
  • \(pop\) a \(uempmed\): ostávajú významné.
  • \(R^2 = 0.982\): veľmi dobrý model.

Model ukazuje mierne nelineárny vzťah medzi úsporami a spotrebou.


4. Rozšírený model – všetky kvadratické členy

Model doplnený o \(I(uempmed^2)\).

Výsledky:

  • Významné: \(I(pop^2)\), \(uempmed\).
  • Nevýznamné: \(psavert^2\), \(uempmed^2\).
  • \(R^2 = 0.9983\): takmer dokonalý fit.
  • RESET test: stále p < 0.001 → model nie je dokonale špecifikovaný.

Aj keď model vysvetľuje takmer všetku variabilitu, existujú nenachytené vzťahy alebo interakcie.


5. Dummy premenná – zmena v trende

Dummy premenná \(DUM = 1\) ak \(psavert > 12\).

a) Zlom v autonómnom členovi

  • DUM je významná (p < 0.001).
    Iný základný intercept pri vyšších úsporách – spotreba sa mení po prekročení istého prahu.

b) Zlom v sklone (interakcia DUM × psavert)

  • Interakcia významná (p < 0.001).
    Vplyv úspor na spotrebu sa mení pri vyšších úsporách – iné správanie domácností nad určitým prahom.

6. Box–Cox transformácia (log-transformácia)

Testovaná transformácia: \[ \log(pce) = β_0 + β_1 pop + β_2 psavert + β_3 uempmed + ε \]

Výsledky:

  • \(R^2 = 0.961\): model stále veľmi dobrý.
  • \(psavert\) a \(uempmed\): negatívny a významný vplyv.
  • RESET test: p < 0.001 → log-transformácia nelinearitu neodstránila.

Transformácia pomáha pri interpretácii (elasticity), ale nie v špecifikácii modelu.


7. Záver

Výsledky ukazujú, že:

  • Spotrebu najviac ovplyvňuje počet obyvateľov – rast populácie jednoznačne zvyšuje osobnú spotrebu.
  • Premenné psavert (úspory) a uempmed (nezamestnanosť) majú významný, ale mierne nelineárny vplyv.
  • RESET test opakovane potvrdzuje, že model nie je úplne správne špecifikovaný – je vhodné doplniť interakcie, časové trendy alebo iné ekonomické faktory.
  • Dummy premenná ukázala, že správanie spotreby sa mení pri vyššej miere úspor.
  • Box–Cox transformácia pomáha zlepšiť interpretáciu, ale nenahrádza potrebu vhodnej funkčnej formy.

Záver: Osobná spotreba je silne závislá od veľkosti populácie, pričom úspory a nezamestnanosť majú doplnkový vplyv. Model možno ešte vylepšiť nelineárnymi väzbami alebo interakciami medzi premennými.

LS0tCnRpdGxlOiAiTmVsaW5lw6FybmUgxaFwZWNpZmlrw6FjaWUiCmF1dGhvcjogIkJjLiBBbGljYSBUdnJkw6EiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCjxzdHlsZT4KLyogUnXFvm92w6kgcG96YWRpZSBwcmUgY2Vsw70gZG9rdW1lbnQgKi8KYm9keSB7CiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZlNmYwOwogICAgZm9udC1mYW1pbHk6IEFyaWFsLCBzYW5zLXNlcmlmOwogICAgbGluZS1oZWlnaHQ6IDEuNjsKfQoKLyogUnXFvm92w6kgbmFkcGlzeSAqLwpoMSwgaDIsIGgzLCBoNCB7CiAgICBjb2xvcjogI2ZmNjliNDsKfQoKLyogQ2l0w6F0eSAqLwpibG9ja3F1b3RlIHsKICAgIGJvcmRlci1sZWZ0OiA0cHggc29saWQgI2ZmNjliNDsKICAgIGJhY2tncm91bmQtY29sb3I6ICNmZmYwZjU7CiAgICBwYWRkaW5nOiAxMHB4IDE1cHg7CiAgICBtYXJnaW46IDEwcHggMDsKICAgIGZvbnQtc3R5bGU6IGl0YWxpYzsKfQoKLyogWnbDvXJhem5lbmllIGvEvsO6xI1vdsO9Y2ggc2xvdiAqLwpzcGFuLmhpZ2hsaWdodCB7CiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZiNmMxOwogICAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBwYWRkaW5nOiAycHggNHB4OwogICAgYm9yZGVyLXJhZGl1czogM3B4Owp9Cjwvc3R5bGU+CgoKCgpgYGB7cn0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KHpvbykKbGlicmFyeSh0c2VyaWVzKQpsaWJyYXJ5KGxtdGVzdCkKbGlicmFyeShzYW5kd2ljaCkKbGlicmFyeShjYXIpCmxpYnJhcnkoTUFTUykKcm0obGlzdD1scygpKQpgYGAKCkFrbyB6w6F2aXNsw7ogcHJlbWVubsO6IHNvbSB6dm9saWxhIHBjZSAob3NvYm7DoSBzcG90cmViYSkgYSB6YSB2eXN2ZXTEvnVqw7pjZSBwcmVtZW5uw6kgcG9wLCBwc2F2ZXJ0IChvc29ibsOpIMO6c3BvcnkpIGEgdWVtcG1lZCAobWVkacOhbG5hIGTEusW+a2EgbmV6YW1lc3RuYW5vc3RpKQoKIyBQUsONUFJBVkEgw5pEQUpPVgoKYGBge3J9CnVkYWplIDwtIHJlYWQuY3N2KCJlY29ub21pY3MuY3N2IiwgaGVhZGVyID0gVFJVRSwgZGVjID0gIi4iKQojIFZ5YmVyaWVtZSBsZW4gc3TEunBjZSwga3RvcsOpIGJ1ZGVtZSBwb3XFvsOtdmHFpQp1ZGFqZSA8LSB1ZGFqZVssIGMoInBjZSIsInBvcCIsInBzYXZlcnQiLCJ1ZW1wbWVkIildCgoKIyBJbXB1dMOhY2lhIGNow71iYWrDumNpY2ggaG9kbsO0dCBzdMS6cGNvdiBwb21vY291IG1lZGnDoW51CmNvbHVtbl9tZWRpYW5zIDwtIHNhcHBseSh1ZGFqZSwgbWVkaWFuLCBuYS5ybSA9IFRSVUUpCnVkYWplX2ltcHV0ZWQgPC0gdWRhamUKZm9yIChjb2wgaW4gbmFtZXModWRhamUpKSB7CnVkYWplX2ltcHV0ZWRbW2NvbF1dW2lzLm5hKHVkYWplX2ltcHV0ZWRbW2NvbF1dKV0gPC0gY29sdW1uX21lZGlhbnNbY29sXQp9CnVkYWplIDwtIHVkYWplX2ltcHV0ZWQKCgojIFLDvWNobHkgcHJlaMS+YWQKc3VtbWFyeSh1ZGFqZSkKYGBgCgojIFrDgUtMQUROw4EgUkVHUkVTSUEKCmBgYHtyfQphdHRhY2godWRhamUpCm1vZGVsIDwtIGxtKHBjZSB+ICsxICsgcG9wICsgcHNhdmVydCArIHVlbXBtZWQsIGRhdGEgPSB1ZGFqZSkKc3VtbWFyeShtb2RlbCkKYGBgCiMgMS4gVEVTVCBSRVNFVCAoUmFtc2V5IFJFU0VUIHRlc3QpCgpgYGB7cn0KcmVzZXR0ZXN0KG1vZGVsKQpgYGAKIyAyLiBHcmFmaWNrw6EgYW5hbMO9emEKCmBgYHtyfQpwbG90KG1vZGVsLCB3aGljaCA9IDEpCmBgYAoKIyMjIENvbXBvbmVudCArIFJlc2lkdWFsIChDK1IpIHBsb3RzIHByZSBrYcW+ZMO6IHZ5c3ZldMS+dWrDumN1IHByZW1lbm7DugoKYGBge3J9CmNhcjo6Y3JQbG90cyhtb2RlbCkKYGBgCiMgMy4gTmVsaW5lw6FybmEgxaFwZWNpZmlrw6FjaWEgKHByaWRhbmllIGt2YWRyYXRpY2vDvWNoIMSNbGVub3YpCgpgYGB7cn0KbW9kZWxfcXVhZCA8LSBsbShwY2UgfiArMSArIHBvcCArIHBzYXZlcnQgKyB1ZW1wbWVkICsgSShwc2F2ZXJ0XjIpICsgSShwb3BeMikpCnN1bW1hcnkobW9kZWxfcXVhZCkKYW5vdmEobW9kZWwsIG1vZGVsX3F1YWQpCnJlc2V0dGVzdChtb2RlbF9xdWFkKQpgYGAKQWsgc2EgdWvDocW+ZSwgxb5lIG5pZWt0b3LDqSBrdmFkcmF0aWNrw6kgxI1sZW55IHPDuiBuZXbDvXpuYW1uw6ksIG9kc3Ryw6FuaW1lIGljaCBhIHBvbmVjaMOhbWUgbGVuIHNpZ25pZmlrYW50bsOpLgoKYGBge3J9CiMgQWsgbmFwci4gSShwb3BeMikgbmV2eWNow6FkemEgc2lnbmlmaWthbnRuZSwgcG91xb5pamVtZSBsZW4gcHNhdmVydF4yCm1vZGVsX3F1YWQyIDwtIGxtKHBjZSB+ICsxICsgcG9wICsgcHNhdmVydCArIHVlbXBtZWQgKyBJKHBzYXZlcnReMikpCnN1bW1hcnkobW9kZWxfcXVhZDIpCmBgYAoKIyA0LiBSb3rFocOtcmVuw70gUkVTRVQgdGVzdAoKYGBge3J9Cm1vZGVsX3JvenNpcmVueSA8LSBsbShwY2UgfiBwb3AgKyBwc2F2ZXJ0ICsgdWVtcG1lZCArIEkocHNhdmVydF4yKSArIEkocG9wXjIpICsgSSh1ZW1wbWVkXjIpKQpzdW1tYXJ5KG1vZGVsX3JvenNpcmVueSkKYW5vdmEobW9kZWwsIG1vZGVsX3JvenNpcmVueSkKcmVzZXR0ZXN0KG1vZGVsX3JvenNpcmVueSkKYGBgCiMgNS4gVHJhbnNmb3Jtw6FjaWEgcG9tb2NvdSBkdW1teSBwcmVtZW5uZWogKGxvbSB2IHNrbG9uZSBhbGVibyBpbnRlcmNlcHRlKQoKYGBge3J9CnVkYWplJERVTSA8LSBpZmVsc2UodWRhamUkcHNhdmVydCA8IDEyLCAwLCAxKQoKCiMgWmxvbSB2IGF1dG9uw7Ntbm9tIMSNbGVuZQptb2RlbERfYXV0byA8LSBsbShwY2UgfiArMSArIERVTSArIHBvcCArIHBzYXZlcnQgKyB1ZW1wbWVkLCBkYXRhID0gdWRhamUpCnN1bW1hcnkobW9kZWxEX2F1dG8pCgoKIyBabG9tIHYgc2tsb25lIChpbnRlcmFrY2lhIERVTSAqIHBzYXZlcnQpCm1vZGVsRF9za2xvbiA8LSBsbShwY2UgfiArMSArIHBvcCArIHBzYXZlcnQgKyBJKERVTSpwc2F2ZXJ0KSArIHVlbXBtZWQsIGRhdGEgPSB1ZGFqZSkKc3VtbWFyeShtb2RlbERfc2tsb24pCgoKYW5vdmEobW9kZWwsIG1vZGVsRF9za2xvbikKcmVzZXR0ZXN0KG1vZGVsRF9za2xvbikKYGBgCiMgNi4gQm94LUNveG92YSB0cmFuc2Zvcm3DoWNpYQoKYGBge3J9CmJveGNveChtb2RlbCkKYGBgCgpgYGB7cn0KIyBQcsOta2xhZCBwcmUgbGFtYmRhID0gMCAobG9nKQptb2RlbF9iYyA8LSBsbShJKGxvZyhwY2UpKSB+ICsxICsgcG9wICsgcHNhdmVydCArIHVlbXBtZWQsIGRhdGEgPSB1ZGFqZSkKc3VtbWFyeShtb2RlbF9iYykKcmVzZXR0ZXN0KG1vZGVsX2JjKQpgYGAKIyBJbnRlcnByZXTDoWNpYSBhIHpob2Rub3RlbmllIHbDvXNsZWRrb3YgCgojIyAxLiBaw6FrbGFkbsO9IGxpbmXDoXJueSBtb2RlbAoKTW9kZWw6ClxbCnBjZV9pID0gzrJfMCArIM6yXzEgXCwgcG9wX2kgKyDOsl8yIFwsIHBzYXZlcnRfaSArIM6yXzMgXCwgdWVtcG1lZF9pICsgzrVfaQpcXQoKIyMjIFbDvXNsZWRreToKLSAqKnBvcCAob2J5dmF0ZcS+c3R2bykqKjogXCjOsl8xID0gMC4wOTg3XCksIHZlxL5taSBzaWxubyB2w716bmFtbsO9IChwIDwgMC4wMDEpLiAgCiAgVsOkxI3FocOtIHBvxI1ldCBvYnl2YXRlxL5vdiB6dnnFoXVqZSBvc29ibsO6IHNwb3RyZWJ1IOKAkyDEjcOtbSB2aWFjIMS+dWTDrSwgdMO9bSB2w6TEjcWhw60gb2JqZW0gc3BvdHJlYnkuCi0gKipwc2F2ZXJ0IChvc29ibsOpIMO6c3BvcnkpKio6IFwozrJfMiA9IDg2LjgyXCksIHbDvXpuYW1uw70gKHAgPCAwLjAwMSkuICAKICBWecWhxaFpZSDDunNwb3J5IGlkw7ogc3BvbHUgcyB2ecWhxaFvdSBzcG90cmVib3Ug4oCTIMS+dWRpYSBwcmkgdnnFocWhw61jaCBwcsOtam1vY2ggbcO0xb51IHrDoXJvdmXFiCB2aWFjIMWhZXRyacWlIGFqIG3DrcWIYcWlLgotICoqdWVtcG1lZCAobWVkacOhbiBkxLrFvmt5IG5lemFtZXN0bmFub3N0aSkqKjogXCjOsl8zID0gMzcuMzRcKSwgdsO9em5hbW7DvSAocCA9IDAuMDAwMSkuICAKICBEbGjFoWlhIG5lemFtZXN0bmFub3PFpSBzw7p2aXPDrSBzIG1pZXJuZSB2ecWhxaFvdSBzcG90cmVib3Ug4oCTIG3DtMW+ZSB0byBiecWlIHNww7Rzb2JlbsOpIMWhdHJ1a3TDunJvdSB0cmh1IHByw6FjZSwgbmllIHNhbW90bm91IG1pZXJvdSBuZXphbWVzdG5hbm9zdGkuCgojIyMgSG9kbm90ZW5pZToKLSBcKFJeMiA9IDAuOTc5XCk6IG1vZGVsIHZ5c3ZldMS+dWplICoqdGFrbWVyIDk4ICUgdmFyaWFiaWxpdHkqKiBvc29ibmVqIHNwb3RyZWJ5LgotICoqUkVTRVQgdGVzdCoqOiBwLWhvZG5vdGEgPCAwLjAwMSDihpIgbW9kZWwgamUgKipuZXNwcsOhdm5lIMWhcGVjaWZpa292YW7DvSoqLCBjaMO9YmFqw7ogbXUgbmVsaW5lw6FybmUgcHJ2a3kgYWxlYm8gaW50ZXJha2NpZS4KCi0tLQoKIyMgMi4gTmVsaW5lw6FybmEgxaFwZWNpZmlrw6FjaWEg4oCTIGt2YWRyYXRpY2vDqSDEjWxlbnkKClByaWRhbGkgc2EgxI1sZW55IFwocG9wXjJcKSBhIFwocHNhdmVydF4yXCkuCgojIyMgVsO9c2xlZGt5OgotIFwoSShwb3BeMilcKTogdmXEvm1pIHbDvXpuYW1uw70gKHAgPCAwLjAwMSkuICAKLSBcKEkocHNhdmVydF4yKVwpOiBuZXbDvXpuYW1uw70gKHAgPSAwLjE4NCkuICAKClRvIHpuYW1lbsOhLCDFvmUgcG9wdWzDoWNpYSBtw6EgKipuZWxpbmXDoXJueSB2cGx5dioqIG5hIHNwb3RyZWJ1IOKAkyByYXN0IG9ieXZhdGXEvnN0dmEganUgenZ5xaF1amUsIGFsZSBzIGtsZXNhasO6Y291IGludGVueml0b3UuICAKw5pzcG9yeSBzYSBzcHLDoXZhasO6ICoqbGluZcOhcm5lKiouCgojIyMgUG9yb3ZuYW5pZSBtb2RlbG92OgotIEFOT1ZBOiBwIDwgMC4wMDEg4oaSIGt2YWRyYXRpY2vDqSDEjWxlbnkgKip2w716bmFtbmUgemxlcMWhdWrDuiBtb2RlbCoqLiAgCi0gXChSXjIgPSAwLjk5ODNcKTogbW9kZWwgdnlzdmV0xL51amUgdGFrbWVyIHbFoWV0a28uICAKLSBSRVNFVCB0ZXN0OiBwIDwgMC4wMDEg4oaSIHN0w6FsZSBuZWxpbmXDoXJuYSDFoXBlY2lmaWvDoWNpYS4KCi0tLQoKIyMgMy4gWmplZG5vZHXFoWVuw70ga3ZhZHJhdGlja8O9IG1vZGVsCgpNb2RlbCBzIGplZG7DvW0ga3ZhZHJhdGlja8O9bSDEjWxlbm9tIFwocHNhdmVydF4yXCk6CgotIFwoSShwc2F2ZXJ0XjIpXCk6IHbDvXpuYW1uw70gKHAgPCAwLjAwMSkuICAKLSBcKHBvcFwpIGEgXCh1ZW1wbWVkXCk6IG9zdMOhdmFqw7ogdsO9em5hbW7DqS4gIAotIFwoUl4yID0gMC45ODJcKTogdmXEvm1pIGRvYnLDvSBtb2RlbC4KCk1vZGVsIHVrYXp1amUgKiptaWVybmUgbmVsaW5lw6FybnkgdnrFpWFoIG1lZHppIMO6c3BvcmFtaSBhIHNwb3RyZWJvdSoqLgoKLS0tCgojIyA0LiBSb3rFocOtcmVuw70gbW9kZWwg4oCTIHbFoWV0a3kga3ZhZHJhdGlja8OpIMSNbGVueQoKTW9kZWwgZG9wbG5lbsO9IG8gXChJKHVlbXBtZWReMilcKS4KCiMjIyBWw71zbGVka3k6Ci0gVsO9em5hbW7DqTogXChJKHBvcF4yKVwpLCBcKHVlbXBtZWRcKS4gIAotIE5ldsO9em5hbW7DqTogXChwc2F2ZXJ0XjJcKSwgXCh1ZW1wbWVkXjJcKS4gIAotIFwoUl4yID0gMC45OTgzXCk6IHRha21lciBkb2tvbmFsw70gZml0LiAgCi0gUkVTRVQgdGVzdDogc3TDoWxlIHAgPCAwLjAwMSDihpIgbW9kZWwgbmllIGplIGRva29uYWxlIMWhcGVjaWZpa292YW7DvS4KCkFqIGtlxI8gbW9kZWwgdnlzdmV0xL51amUgdGFrbWVyIHbFoWV0a3UgdmFyaWFiaWxpdHUsICoqZXhpc3R1asO6IG5lbmFjaHl0ZW7DqSB2esWlYWh5KiogYWxlYm8gaW50ZXJha2NpZS4KCi0tLQoKIyMgNS4gRHVtbXkgcHJlbWVubsOhIOKAkyB6bWVuYSB2IHRyZW5kZQoKRHVtbXkgcHJlbWVubsOhIFwoRFVNID0gMVwpIGFrIFwocHNhdmVydCA+IDEyXCkuCgojIyMgYSkgWmxvbSB2IGF1dG9uw7Ntbm9tIMSNbGVub3ZpCi0gRFVNIGplIHbDvXpuYW1uw6EgKHAgPCAwLjAwMSkuICAKSW7DvSB6w6FrbGFkbsO9IGludGVyY2VwdCBwcmkgdnnFocWhw61jaCDDunNwb3LDoWNoIOKAkyBzcG90cmViYSBzYSBtZW7DrSBwbyBwcmVrcm/EjWVuw60gaXN0w6lobyBwcmFodS4KCiMjIyBiKSBabG9tIHYgc2tsb25lIChpbnRlcmFrY2lhIERVTSDDlyBwc2F2ZXJ0KQotIEludGVyYWtjaWEgdsO9em5hbW7DoSAocCA8IDAuMDAxKS4gIAoqKlZwbHl2IMO6c3BvciBuYSBzcG90cmVidSBzYSBtZW7DrSBwcmkgdnnFocWhw61jaCDDunNwb3LDoWNoKiog4oCTIGluw6kgc3Byw6F2YW5pZSBkb23DoWNub3N0w60gbmFkIHVyxI1pdMO9bSBwcmFob20uCgotLS0KCiMjIDYuIEJveOKAk0NveCB0cmFuc2Zvcm3DoWNpYSAobG9nLXRyYW5zZm9ybcOhY2lhKQoKVGVzdG92YW7DoSB0cmFuc2Zvcm3DoWNpYToKXFsKXGxvZyhwY2UpID0gzrJfMCArIM6yXzEgcG9wICsgzrJfMiBwc2F2ZXJ0ICsgzrJfMyB1ZW1wbWVkICsgzrUKXF0KCiMjIyBWw71zbGVka3k6Ci0gXChSXjIgPSAwLjk2MVwpOiBtb2RlbCBzdMOhbGUgdmXEvm1pIGRvYnLDvS4gIAotIFwocHNhdmVydFwpIGEgXCh1ZW1wbWVkXCk6IG5lZ2F0w612bnkgYSB2w716bmFtbsO9IHZwbHl2LiAgCi0gUkVTRVQgdGVzdDogcCA8IDAuMDAxIOKGkiBsb2ctdHJhbnNmb3Jtw6FjaWEgbmVsaW5lYXJpdHUgKipuZW9kc3Ryw6FuaWxhKiouCgpUcmFuc2Zvcm3DoWNpYSBwb23DoWhhIHByaSBpbnRlcnByZXTDoWNpaSAoZWxhc3RpY2l0eSksIGFsZSBuaWUgdiDFoXBlY2lmaWvDoWNpaSBtb2RlbHUuCgotLS0KCiMjIDcuIFrDoXZlcgoKVsO9c2xlZGt5IHVrYXp1asO6LCDFvmU6CgotIFNwb3RyZWJ1IG5hanZpYWMgb3ZwbHl2xYh1amUgKipwb8SNZXQgb2J5dmF0ZcS+b3YqKiDigJMgcmFzdCBwb3B1bMOhY2llIGplZG5vem5hxI1uZSB6dnnFoXVqZSBvc29ibsO6IHNwb3RyZWJ1LgotIFByZW1lbm7DqSAqKnBzYXZlcnQqKiAow7pzcG9yeSkgYSAqKnVlbXBtZWQqKiAobmV6YW1lc3RuYW5vc8WlKSBtYWrDuiB2w716bmFtbsO9LCBhbGUgbWllcm5lIG5lbGluZcOhcm55IHZwbHl2LgotICoqUkVTRVQgdGVzdCoqIG9wYWtvdmFuZSBwb3R2cmR6dWplLCDFvmUgbW9kZWwgbmllIGplIMO6cGxuZSBzcHLDoXZuZSDFoXBlY2lmaWtvdmFuw70g4oCTIGplIHZob2Ruw6kgZG9wbG5pxaUgaW50ZXJha2NpZSwgxI1hc292w6kgdHJlbmR5IGFsZWJvIGluw6kgZWtvbm9taWNrw6kgZmFrdG9yeS4KLSAqKkR1bW15IHByZW1lbm7DoSoqIHVrw6F6YWxhLCDFvmUgc3Byw6F2YW5pZSBzcG90cmVieSBzYSBtZW7DrSBwcmkgdnnFocWhZWogbWllcmUgw7pzcG9yLgotICoqQm944oCTQ294IHRyYW5zZm9ybcOhY2lhKiogcG9tw6FoYSB6bGVwxaFpxaUgaW50ZXJwcmV0w6FjaXUsIGFsZSBuZW5haHLDoWR6YSBwb3RyZWJ1IHZob2RuZWogZnVua8SNbmVqIGZvcm15LgoKKipaw6F2ZXI6KiogT3NvYm7DoSBzcG90cmViYSBqZSBzaWxuZSB6w6F2aXNsw6Egb2QgdmXEvmtvc3RpIHBvcHVsw6FjaWUsIHByacSNb20gw7pzcG9yeSBhIG5lemFtZXN0bmFub3PFpSBtYWrDuiBkb3BsbmtvdsO9IHZwbHl2LiBNb2RlbCBtb8W+bm8gZcWhdGUgdnlsZXDFoWnFpSBuZWxpbmXDoXJueW1pIHbDpHpiYW1pIGFsZWJvIGludGVyYWtjaWFtaSBtZWR6aSBwcmVtZW5uw71taS4KCg==