knitr::opts_chunk$set(
echo = TRUE,
message = FALSE,
warning = FALSE
)
Priamy import z WDI
install.packages(“WDI”) # ak treba
library(WDI) library(dplyr)
countries <- c(“SVK”,“CZE”,“POL”,“HUN”)
indicators <- c( GDP.PCAP = “NY.GDP.PCAP.KD”, INFLATION =
“FP.CPI.TOTL.ZG”, UNEMP = “SL.UEM.TOTL.ZS”, EXPORTS = “NE.EXP.GNFS.ZS”
)
wdi_raw <- WDI( country = countries, indicator = indicators, start
= 2000, end = 2023 )
udaje <- wdi_raw %>% rename( COUNTRY = country, YEAR = year )
%>% arrange(COUNTRY, YEAR)
head(udaje) colnames(udaje)
Vidíme, že databáza obsahuje štyri numerické indikátory pre štyri
krajiny vo vybranom období. Rok (YEAR) slúži ako časová premenná.
zápis do csv
write.csv2(udaje, “udaje_WDI_V4.csv”, row.names = FALSE)
import z csv
udaje_csv <- read.csv2( “udaje_WDI_V4.csv”, header = TRUE, sep =
“;”, dec = “.” )
head(udaje_csv)
Pre ilustráciu sa zameriam na rok 2015 a porovnám krajiny V4.
library(ggplot2)
udaje_2015 <- udaje %>% filter(YEAR == 2015) %>%
select(COUNTRY, YEAR, GDP.PCAP, INFLATION, UNEMP, EXPORTS) %>%
na.omit()
udaje_2015 ggplot(udaje_2015, aes(x = EXPORTS, y = GDP.PCAP, color =
COUNTRY)) + geom_point(size = 3) + theme_minimal() + labs( title = “HDP
na obyvateľa vs. exporty (% HDP), rok 2015”, x = “Exporty (% HDP)”, y =
“HDP na obyvateľa (konštantné USD)”, color = “Krajina” ) # Z grafu
vidíme, že krajiny sa líšia tak v úrovni HDP na obyvateľa, ako aj v
podiele exportov na HDP. Často platí, že vyšší HDP na obyvateľa je
spojený s vyšším exportným podielom, ale vzťah nie je úplne
lineárny.
Boxplot – rozdelenie HDP podľa krajiny (2010–2020)Česká republika má
najvyššie mediánové hodnoty HDP na obyvateľa. Slovensko je mierne za
Českou republikou, ale nad Poľskom aj Maďarskom.Poľsko aj Maďarsko sú
zreteľne pod úrovňou Slovenska.
udaje_10_20 <- udaje %>% filter(YEAR >= 2010, YEAR <=
2020) %>% select(COUNTRY, YEAR, GDP.PCAP) %>% na.omit()
ggplot(udaje_10_20, aes(x = COUNTRY, y = GDP.PCAP)) +
geom_boxplot(fill = “lightblue”, color = “darkblue”) + theme_minimal() +
labs( title = “Rozdelenie HDP na obyvateľa podľa krajiny (2010–2020)”, x
= “Krajina”, y = “HDP na obyvateľa (konštantné USD)” ) # Boxplot
ukazuje, že Česko a Slovensko majú spravidla vyšší HDP na obyvateľa ako
Poľsko či Maďarsko. Rozptyl hodnôt v rámci krajiny súvisí s vývojom v
čase.
Line graf – HDP v čase
ggplot(udaje, aes(x = YEAR, y = GDP.PCAP, color = COUNTRY)) +
geom_line() + theme_minimal() + labs( title = “Vývoj HDP na obyvateľa v
krajinách V4 (2000–2023)”, x = “Rok”, y = “HDP na obyvateľa (konštantné
USD)”, color = “Krajina” ) # Čiarový graf ukazuje rastúci trend HDP na
obyvateľa vo všetkých krajinách, s viditeľnými poklesmi v krízových
rokoch (2008–2009, 2020).
tabuľka základných štatistík
library(knitr)
gdp_stats <- udaje %>% filter(YEAR %in% 2010:2020) %>%
group_by(YEAR) %>% summarise( n = n(), mean = mean(GDP.PCAP, na.rm =
TRUE), sd = sd(GDP.PCAP, na.rm = TRUE), min = min(GDP.PCAP, na.rm =
TRUE), q25 = quantile(GDP.PCAP, 0.25, na.rm = TRUE), median =
median(GDP.PCAP, na.rm = TRUE), q75 = quantile(GDP.PCAP, 0.75, na.rm =
TRUE), max = max(GDP.PCAP, na.rm = TRUE), .groups = “drop” )
kable(gdp_stats, digits = 2, caption = “Základné štatistiky HDP na
obyvateľa (2010–2020, krajiny V4)”) # Tabuľka ukazuje, ako sa priemerný
HDP na obyvateľa v krajinách V4 menil v čase.Vidíme rast priemeru aj
maxima, čo odráža ekonomický rast regiónu. library(kableExtra)
gdp_stats %>% kable( digits = 2, caption = “Základné štatistiky
HDP na obyvateľa (2010–2020, krajiny V4)” ) %>% kable_styling(
full_width = FALSE, bootstrap_options = c(“striped”,“hover”,“condensed”)
) %>% column_spec(1, bold = TRUE) %>% row_spec(0, bold = TRUE,
background = “#f2f2f2”) %>% add_header_above(c(” ” = 2, “HDP
štatistiky” = 7)) # Korelačná matica a Heatmap Vypočítam korelačnú
maticu numerických premenných pre rok 2015 a vykreslím heatmapu.
num_2015 <- udaje_2015 %>% select(GDP.PCAP, INFLATION, UNEMP,
EXPORTS)
cor_mat <- cor(num_2015, use = “pairwise.complete.obs”) cor_mat #
Heatmap pomocou ggplot2
library(tidyr)
cor_long <- as.data.frame(cor_mat) %>% mutate(var1 =
rownames(cor_mat)) %>% pivot_longer( cols = -var1, names_to = “var2”,
values_to = “corr” )
ggplot(cor_long, aes(x = var1, y = var2, fill = corr)) + geom_tile()
+ scale_fill_gradient2( low = “blue”, mid = “white”, high = “red”,
midpoint = 0 ) + theme_minimal() + labs( title = “Korelačná matica (rok
2015, krajiny V4)”, x = ““, y =”“, fill =”Korelácia” ) # Z heatmapy
vidíme napríklad, či je HDP na obyvateľa pozitívne alebo negatívne
korelovaný s infláciou, nezamestnanosťou a exportmi. Silne pozitívne
hodnoty (červené) znamenajú, že premenné rastú spolu, kým silne
negatívne (modré) naznačujú opačný pohyb.
t-test: Porovnanie priemeru HDP na obyvateľa v rokoch 2005 a
2015
t.test.result <- t.test( udaje\(GDP.PCAP[udaje\)YEAR == 2005], udaje\(GDP.PCAP[udaje\)YEAR == 2015] )
t.test.result # Výsledok t-testu ukazuje, či je rozdiel medzi
priemerným HDP na obyvateľa v rokoch 2005 a 2015 štatisticky významný.
Očakávame, že v roku 2015 je HDP výrazne vyšší – ak je p-hodnota malá
(napr. < 0.05), hypotézu o rovnakom priemere zamietame.
ANOVA: Porovnanie HDP medzi krajinami (2015)
anova.result <- aov(GDP.PCAP ~ COUNTRY, data = udaje_2015)
summary(anova.result)
Lineárna regresia Model: HDP ~ inflácia + nezamestnanosť + exporty
(2015)
wdi_reg <- udaje %>% filter(YEAR == 2015) %>%
select(GDP.PCAP, INFLATION, UNEMP, EXPORTS) %>% na.omit()
model <- lm(GDP.PCAP ~ INFLATION + UNEMP + EXPORTS, data =
wdi_reg) summary(model)
Tabuľka regresných koeficientov
install.packages(c(“broom”,“stringr”)) # ak treba
library(broom) library(stringr) library(kableExtra)
coef.tbl <- tidy(model, conf.int = TRUE) %>% mutate( term =
recode(term, “(Intercept)” = “Intercept”, “INFLATION” = “Inflácia”,
“UNEMP” = “Nezamestnanosť”, “EXPORTS” = “Exporty (% HDP)” ), stars =
case_when( p.value < 0.001 ~ “”, p.value < 0.01 ~
””, p.value < 0.05 ~ ””, p.value < 0.1 ~ “·”, TRUE ~
“” ) ) %>% transmute( Term = term, Estimate = estimate,
Std. Error= std.error, t value = statistic,
p value = p.value, 95% CI = str_c(“[”,
round(conf.low,3), ”, ”, round(conf.high,3), ”]”), Sig = stars )
coef.tbl %>% kable( digits = 3, caption = “OLS koeficienty (HDP na
obyvateľa ~ inflácia + nezamestnanosť + exporty)” ) %>%
kable_styling( full_width = FALSE, bootstrap_options =
c(“striped”,“hover”,“condensed”) ) %>% column_spec(1, bold = TRUE)
%>% row_spec(0, bold = TRUE, background = “#f2f2f2”) %>% footnote(
general = “Signif. codes: *** p<0.001, ** p<0.01, * p<0.05, ·
p<0.1.”, threeparttable = TRUE ) # koeficienty s hviezdičkami sú
štatisticky významné. Znamienko určuje, či daná premenná súvisí s HDP
pozitívne alebo negatívne.
Model Fit Statistics
fit.tbl <- glance(model) %>% transmute( R-squared
= r.squared, Adj. R-squared = adj.r.squared,
F-statistic = statistic, F p-value = p.value,
AIC = AIC, BIC = BIC, Num. obs. =
nobs )
fit.tbl %>% kable(digits = 3, caption = “Model Fit Statistics”)
%>% kable_styling( full_width = FALSE, bootstrap_options =
c(“condensed”) )
LS0tCnRpdGxlOiAicHLDoWNhIHMgZGF0YWLDoXpvdi1WNCBla29ub21pY2vDqSB1a2F6b3ZhdGVsZSIKYXV0aG9yOiAiTmF0w6FsaWEgU29saWdvdsOhIDxicj4KKHMgdnl1xb5pdMOtbSB2ZXJlam5lIGRvc3R1cG7DvWNoIGvDs2RvdiBhIENoYXRHUFQpIgpkYXRlOiAiU2VwdGVtYmVyIDIwMjUiCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0aGVtZTogdW5pdGVkCiAgICBoaWdobGlnaHQ6IHRhbmdvCmVkaXRvcl9vcHRpb25zOiAKICBtYXJrZG93bjogCiAgICB3cmFwOiA3MgotLS0KCmBgYHtyfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgICBlY2hvID0gVFJVRSwKICAgIG1lc3NhZ2UgPSBGQUxTRSwKICAgIHdhcm5pbmcgPSBGQUxTRQopCmBgYAojIFByaWFteSBpbXBvcnQgeiBXREkKIyBpbnN0YWxsLnBhY2thZ2VzKCJXREkiKSAgICMgYWsgdHJlYmEKCmxpYnJhcnkoV0RJKQpsaWJyYXJ5KGRwbHlyKQoKY291bnRyaWVzIDwtIGMoIlNWSyIsIkNaRSIsIlBPTCIsIkhVTiIpCgppbmRpY2F0b3JzIDwtIGMoCkdEUC5QQ0FQICA9ICJOWS5HRFAuUENBUC5LRCIsCklORkxBVElPTiA9ICJGUC5DUEkuVE9UTC5aRyIsClVORU1QICAgICA9ICJTTC5VRU0uVE9UTC5aUyIsCkVYUE9SVFMgICA9ICJORS5FWFAuR05GUy5aUyIKKQoKd2RpX3JhdyA8LSBXREkoCmNvdW50cnkgICA9IGNvdW50cmllcywKaW5kaWNhdG9yID0gaW5kaWNhdG9ycywKc3RhcnQgICAgID0gMjAwMCwKZW5kICAgICAgID0gMjAyMwopCgp1ZGFqZSA8LSB3ZGlfcmF3ICU+JQpyZW5hbWUoCkNPVU5UUlkgPSBjb3VudHJ5LApZRUFSICAgID0geWVhcgopICU+JQphcnJhbmdlKENPVU5UUlksIFlFQVIpCgpoZWFkKHVkYWplKQpjb2xuYW1lcyh1ZGFqZSkKCiMgVmlkw61tZSwgxb5lIGRhdGFiw6F6YSBvYnNhaHVqZSDFoXR5cmkgbnVtZXJpY2vDqSBpbmRpa8OhdG9yeSBwcmUgxaF0eXJpIGtyYWppbnkgdm8gdnlicmFub20gb2Jkb2LDrS4gUm9rIChZRUFSKSBzbMO6xb5pIGFrbyDEjWFzb3bDoSBwcmVtZW5uw6EuCiMgesOhcGlzIGRvIGNzdgoKd3JpdGUuY3N2Mih1ZGFqZSwgInVkYWplX1dESV9WNC5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkKCiMgaW1wb3J0IHogY3N2Cgp1ZGFqZV9jc3YgPC0gcmVhZC5jc3YyKAoidWRhamVfV0RJX1Y0LmNzdiIsCmhlYWRlciA9IFRSVUUsCnNlcCAgICA9ICI7IiwKZGVjICAgID0gIi4iCikKCmhlYWQodWRhamVfY3N2KQoKIyBQcmUgaWx1c3Ryw6FjaXUgc2EgemFtZXJpYW0gbmEgcm9rIDIwMTUgYSBwb3Jvdm7DoW0ga3JhamlueSBWNC4KbGlicmFyeShnZ3Bsb3QyKQoKdWRhamVfMjAxNSA8LSB1ZGFqZSAlPiUKZmlsdGVyKFlFQVIgPT0gMjAxNSkgJT4lCnNlbGVjdChDT1VOVFJZLCBZRUFSLCBHRFAuUENBUCwgSU5GTEFUSU9OLCBVTkVNUCwgRVhQT1JUUykgJT4lCm5hLm9taXQoKQoKdWRhamVfMjAxNQpnZ3Bsb3QodWRhamVfMjAxNSwgYWVzKHggPSBFWFBPUlRTLCB5ID0gR0RQLlBDQVAsIGNvbG9yID0gQ09VTlRSWSkpICsKZ2VvbV9wb2ludChzaXplID0gMykgKwp0aGVtZV9taW5pbWFsKCkgKwpsYWJzKAp0aXRsZSA9ICJIRFAgbmEgb2J5dmF0ZcS+YSB2cy4gZXhwb3J0eSAoJSBIRFApLCByb2sgMjAxNSIsCnggICAgID0gIkV4cG9ydHkgKCUgSERQKSIsCnkgICAgID0gIkhEUCBuYSBvYnl2YXRlxL5hIChrb27FoXRhbnRuw6kgVVNEKSIsCmNvbG9yID0gIktyYWppbmEiCikKIyBaIGdyYWZ1IHZpZMOtbWUsIMW+ZSBrcmFqaW55IHNhIGzDrcWhaWEgdGFrIHYgw7pyb3ZuaSBIRFAgbmEgb2J5dmF0ZcS+YSwgYWtvIGFqIHYgcG9kaWVsZSBleHBvcnRvdiBuYSBIRFAuIMSMYXN0byBwbGF0w60sIMW+ZSB2ecWhxaHDrSBIRFAgbmEgb2J5dmF0ZcS+YSBqZSBzcG9qZW7DvSBzIHZ5xaHFocOtbSBleHBvcnRuw71tIHBvZGllbG9tLCBhbGUgdnrFpWFoIG5pZSBqZSDDunBsbmUgbGluZcOhcm55LgoKIyBCb3hwbG90IOKAkyByb3pkZWxlbmllIEhEUCBwb2TEvmEga3JhamlueSAoMjAxMOKAkzIwMjApxIxlc2vDoSByZXB1Ymxpa2EgbcOhIG5hanZ5xaHFoWllIG1lZGnDoW5vdsOpIGhvZG5vdHkgSERQIG5hIG9ieXZhdGXEvmEuIFNsb3ZlbnNrbyBqZSBtaWVybmUgemEgxIxlc2tvdSByZXB1Ymxpa291LCBhbGUgbmFkIFBvxL5za29tIGFqIE1hxI9hcnNrb20uUG/EvnNrbyBhaiBNYcSPYXJza28gc8O6IHpyZXRlxL5uZSBwb2Qgw7pyb3bFiG91IFNsb3ZlbnNrYS4KCnVkYWplXzEwXzIwIDwtIHVkYWplICU+JQpmaWx0ZXIoWUVBUiA+PSAyMDEwLCBZRUFSIDw9IDIwMjApICU+JQpzZWxlY3QoQ09VTlRSWSwgWUVBUiwgR0RQLlBDQVApICU+JQpuYS5vbWl0KCkKCmdncGxvdCh1ZGFqZV8xMF8yMCwgYWVzKHggPSBDT1VOVFJZLCB5ID0gR0RQLlBDQVApKSArCmdlb21fYm94cGxvdChmaWxsID0gImxpZ2h0Ymx1ZSIsIGNvbG9yID0gImRhcmtibHVlIikgKwp0aGVtZV9taW5pbWFsKCkgKwpsYWJzKAp0aXRsZSA9ICJSb3pkZWxlbmllIEhEUCBuYSBvYnl2YXRlxL5hIHBvZMS+YSBrcmFqaW55ICgyMDEw4oCTMjAyMCkiLAp4ICAgICA9ICJLcmFqaW5hIiwKeSAgICAgPSAiSERQIG5hIG9ieXZhdGXEvmEgKGtvbsWhdGFudG7DqSBVU0QpIgopCiMgQm94cGxvdCB1a2F6dWplLCDFvmUgxIxlc2tvIGEgU2xvdmVuc2tvIG1hasO6IHNwcmF2aWRsYSB2ecWhxaHDrSBIRFAgbmEgb2J5dmF0ZcS+YSBha28gUG/EvnNrbyDEjWkgTWHEj2Fyc2tvLiBSb3pwdHlsIGhvZG7DtHQgdiByw6FtY2kga3JhamlueSBzw7p2aXPDrSBzIHbDvXZvam9tIHYgxI1hc2UuCgojIExpbmUgZ3JhZiDigJMgSERQIHYgxI1hc2UKZ2dwbG90KHVkYWplLCBhZXMoeCA9IFlFQVIsIHkgPSBHRFAuUENBUCwgY29sb3IgPSBDT1VOVFJZKSkgKwpnZW9tX2xpbmUoKSArCnRoZW1lX21pbmltYWwoKSArCmxhYnMoCnRpdGxlID0gIlbDvXZvaiBIRFAgbmEgb2J5dmF0ZcS+YSB2IGtyYWppbsOhY2ggVjQgKDIwMDDigJMyMDIzKSIsCnggICAgID0gIlJvayIsCnkgICAgID0gIkhEUCBuYSBvYnl2YXRlxL5hIChrb27FoXRhbnRuw6kgVVNEKSIsCmNvbG9yID0gIktyYWppbmEiCikKIyDEjGlhcm92w70gZ3JhZiB1a2F6dWplIHJhc3TDumNpIHRyZW5kIEhEUCBuYSBvYnl2YXRlxL5hIHZvIHbFoWV0a8O9Y2gga3Jhamluw6FjaCwgcyB2aWRpdGXEvm7DvW1pIHBva2xlc21pIHYga3LDrXpvdsO9Y2ggcm9rb2NoICgyMDA44oCTMjAwOSwgMjAyMCkuCgojIHRhYnXEvmthIHrDoWtsYWRuw71jaCDFoXRhdGlzdMOtawpsaWJyYXJ5KGtuaXRyKQoKZ2RwX3N0YXRzIDwtIHVkYWplICU+JQpmaWx0ZXIoWUVBUiAlaW4lIDIwMTA6MjAyMCkgJT4lCmdyb3VwX2J5KFlFQVIpICU+JQpzdW1tYXJpc2UoCm4gICAgICA9IG4oKSwKbWVhbiAgID0gbWVhbihHRFAuUENBUCwgbmEucm0gPSBUUlVFKSwKc2QgICAgID0gc2QoR0RQLlBDQVAsIG5hLnJtID0gVFJVRSksCm1pbiAgICA9IG1pbihHRFAuUENBUCwgbmEucm0gPSBUUlVFKSwKcTI1ICAgID0gcXVhbnRpbGUoR0RQLlBDQVAsIDAuMjUsIG5hLnJtID0gVFJVRSksCm1lZGlhbiA9IG1lZGlhbihHRFAuUENBUCwgbmEucm0gPSBUUlVFKSwKcTc1ICAgID0gcXVhbnRpbGUoR0RQLlBDQVAsIDAuNzUsIG5hLnJtID0gVFJVRSksCm1heCAgICA9IG1heChHRFAuUENBUCwgbmEucm0gPSBUUlVFKSwKLmdyb3VwcyA9ICJkcm9wIgopCgprYWJsZShnZHBfc3RhdHMsIGRpZ2l0cyA9IDIsCmNhcHRpb24gPSAiWsOha2xhZG7DqSDFoXRhdGlzdGlreSBIRFAgbmEgb2J5dmF0ZcS+YSAoMjAxMOKAkzIwMjAsIGtyYWppbnkgVjQpIikKIyBUYWJ1xL5rYSB1a2F6dWplLCBha28gc2EgcHJpZW1lcm7DvSBIRFAgbmEgb2J5dmF0ZcS+YSB2IGtyYWppbsOhY2ggVjQgbWVuaWwgdiDEjWFzZS5WaWTDrW1lIHJhc3QgcHJpZW1lcnUgYWogbWF4aW1hLCDEjW8gb2Ryw6HFvmEgZWtvbm9taWNrw70gcmFzdCByZWdpw7NudS4KbGlicmFyeShrYWJsZUV4dHJhKQoKZ2RwX3N0YXRzICU+JQprYWJsZSgKZGlnaXRzICA9IDIsCmNhcHRpb24gPSAiWsOha2xhZG7DqSDFoXRhdGlzdGlreSBIRFAgbmEgb2J5dmF0ZcS+YSAoMjAxMOKAkzIwMjAsIGtyYWppbnkgVjQpIgopICU+JQprYWJsZV9zdHlsaW5nKApmdWxsX3dpZHRoICAgICAgICA9IEZBTFNFLApib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJob3ZlciIsImNvbmRlbnNlZCIpCikgJT4lCmNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUUlVFKSAlPiUKcm93X3NwZWMoMCwgYm9sZCA9IFRSVUUsIGJhY2tncm91bmQgPSAiI2YyZjJmMiIpICU+JQphZGRfaGVhZGVyX2Fib3ZlKGMoIiAiID0gMiwgIkhEUCDFoXRhdGlzdGlreSIgPSA3KSkKIyBLb3JlbGHEjW7DoSBtYXRpY2EgYSBIZWF0bWFwICBWeXBvxI3DrXRhbSBrb3JlbGHEjW7DuiBtYXRpY3UgbnVtZXJpY2vDvWNoIHByZW1lbm7DvWNoIHByZSByb2sgMjAxNSBhIHZ5a3Jlc2zDrW0gaGVhdG1hcHUuCm51bV8yMDE1IDwtIHVkYWplXzIwMTUgJT4lCnNlbGVjdChHRFAuUENBUCwgSU5GTEFUSU9OLCBVTkVNUCwgRVhQT1JUUykKCmNvcl9tYXQgPC0gY29yKG51bV8yMDE1LCB1c2UgPSAicGFpcndpc2UuY29tcGxldGUub2JzIikKY29yX21hdAojIEhlYXRtYXAgcG9tb2NvdSBnZ3Bsb3QyCgpsaWJyYXJ5KHRpZHlyKQoKY29yX2xvbmcgPC0gYXMuZGF0YS5mcmFtZShjb3JfbWF0KSAlPiUKbXV0YXRlKHZhcjEgPSByb3duYW1lcyhjb3JfbWF0KSkgJT4lCnBpdm90X2xvbmdlcigKY29scyA9IC12YXIxLApuYW1lc190byA9ICJ2YXIyIiwKdmFsdWVzX3RvID0gImNvcnIiCikKCmdncGxvdChjb3JfbG9uZywgYWVzKHggPSB2YXIxLCB5ID0gdmFyMiwgZmlsbCA9IGNvcnIpKSArCmdlb21fdGlsZSgpICsKc2NhbGVfZmlsbF9ncmFkaWVudDIoCmxvdyAgPSAiYmx1ZSIsCm1pZCAgPSAid2hpdGUiLApoaWdoID0gInJlZCIsCm1pZHBvaW50ID0gMAopICsKdGhlbWVfbWluaW1hbCgpICsKbGFicygKdGl0bGUgPSAiS29yZWxhxI1uw6EgbWF0aWNhIChyb2sgMjAxNSwga3JhamlueSBWNCkiLAp4ICAgICA9ICIiLAp5ICAgICA9ICIiLApmaWxsICA9ICJLb3JlbMOhY2lhIgopCiMgWiBoZWF0bWFweSB2aWTDrW1lIG5hcHLDrWtsYWQsIMSNaSBqZSBIRFAgbmEgb2J5dmF0ZcS+YSBwb3ppdMOtdm5lIGFsZWJvIG5lZ2F0w612bmUga29yZWxvdmFuw70gcyBpbmZsw6FjaW91LCBuZXphbWVzdG5hbm9zxaVvdSBhIGV4cG9ydG1pLiBTaWxuZSBwb3ppdMOtdm5lIGhvZG5vdHkgKMSNZXJ2ZW7DqSkgem5hbWVuYWrDuiwgxb5lIHByZW1lbm7DqSByYXN0w7ogc3BvbHUsIGvDvW0gc2lsbmUgbmVnYXTDrXZuZSAobW9kcsOpKSBuYXpuYcSNdWrDuiBvcGHEjW7DvSBwb2h5Yi4KCiMgdC10ZXN0OiBQb3Jvdm5hbmllIHByaWVtZXJ1IEhEUCBuYSBvYnl2YXRlxL5hIHYgcm9rb2NoIDIwMDUgYSAyMDE1CnQudGVzdC5yZXN1bHQgPC0gdC50ZXN0KAp1ZGFqZSRHRFAuUENBUFt1ZGFqZSRZRUFSID09IDIwMDVdLAp1ZGFqZSRHRFAuUENBUFt1ZGFqZSRZRUFSID09IDIwMTVdCikKCnQudGVzdC5yZXN1bHQKIyBWw71zbGVkb2sgdC10ZXN0dSB1a2F6dWplLCDEjWkgamUgcm96ZGllbCBtZWR6aSBwcmllbWVybsO9bSBIRFAgbmEgb2J5dmF0ZcS+YSB2IHJva29jaCAyMDA1IGEgMjAxNSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvS4gT8SNYWvDoXZhbWUsIMW+ZSB2IHJva3UgMjAxNSBqZSBIRFAgdsO9cmF6bmUgdnnFocWhw60g4oCTIGFrIGplIHAtaG9kbm90YSBtYWzDoSAobmFwci4gPCAwLjA1KSwgaHlwb3TDqXp1IG8gcm92bmFrb20gcHJpZW1lcmUgemFtaWV0YW1lLgoKIyBBTk9WQTogUG9yb3ZuYW5pZSBIRFAgbWVkemkga3JhamluYW1pICgyMDE1KQphbm92YS5yZXN1bHQgPC0gYW92KEdEUC5QQ0FQIH4gQ09VTlRSWSwgZGF0YSA9IHVkYWplXzIwMTUpCnN1bW1hcnkoYW5vdmEucmVzdWx0KQoKIyBMaW5lw6FybmEgcmVncmVzaWEgTW9kZWw6IEhEUCB+IGluZmzDoWNpYSArIG5lemFtZXN0bmFub3PFpSArIGV4cG9ydHkgKDIwMTUpCndkaV9yZWcgPC0gdWRhamUgJT4lCmZpbHRlcihZRUFSID09IDIwMTUpICU+JQpzZWxlY3QoR0RQLlBDQVAsIElORkxBVElPTiwgVU5FTVAsIEVYUE9SVFMpICU+JQpuYS5vbWl0KCkKCm1vZGVsIDwtIGxtKEdEUC5QQ0FQIH4gSU5GTEFUSU9OICsgVU5FTVAgKyBFWFBPUlRTLCBkYXRhID0gd2RpX3JlZykKc3VtbWFyeShtb2RlbCkKCiMgVGFidcS+a2EgcmVncmVzbsO9Y2gga29lZmljaWVudG92CiMgaW5zdGFsbC5wYWNrYWdlcyhjKCJicm9vbSIsInN0cmluZ3IiKSkgICMgYWsgdHJlYmEKCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShrYWJsZUV4dHJhKQoKY29lZi50YmwgPC0gdGlkeShtb2RlbCwgY29uZi5pbnQgPSBUUlVFKSAlPiUKbXV0YXRlKAp0ZXJtID0gcmVjb2RlKHRlcm0sCiIoSW50ZXJjZXB0KSIgPSAiSW50ZXJjZXB0IiwKIklORkxBVElPTiIgICA9ICJJbmZsw6FjaWEiLAoiVU5FTVAiICAgICAgID0gIk5lemFtZXN0bmFub3PFpSIsCiJFWFBPUlRTIiAgICAgPSAiRXhwb3J0eSAoJSBIRFApIgopLApzdGFycyA9IGNhc2Vfd2hlbigKcC52YWx1ZSA8IDAuMDAxIH4gIioqKiIsCnAudmFsdWUgPCAwLjAxICB+ICIqKiIsCnAudmFsdWUgPCAwLjA1ICB+ICIqIiwKcC52YWx1ZSA8IDAuMSAgIH4gIsK3IiwKVFJVRSAgICAgICAgICAgIH4gIiIKKQopICU+JQp0cmFuc211dGUoClRlcm0gICAgICAgID0gdGVybSwKRXN0aW1hdGUgICAgPSBlc3RpbWF0ZSwKYFN0ZC4gRXJyb3JgPSBzdGQuZXJyb3IsCmB0IHZhbHVlYCAgID0gc3RhdGlzdGljLApgcCB2YWx1ZWAgICA9IHAudmFsdWUsCmA5NSUgQ0lgICAgID0gc3RyX2MoIlsiLCByb3VuZChjb25mLmxvdywzKSwgIiwgIiwgcm91bmQoY29uZi5oaWdoLDMpLCAiXSIpLApTaWcgICAgICAgICA9IHN0YXJzCikKCmNvZWYudGJsICU+JQprYWJsZSgKZGlnaXRzICA9IDMsCmNhcHRpb24gPSAiT0xTIGtvZWZpY2llbnR5IChIRFAgbmEgb2J5dmF0ZcS+YSB+IGluZmzDoWNpYSArIG5lemFtZXN0bmFub3PFpSArIGV4cG9ydHkpIgopICU+JQprYWJsZV9zdHlsaW5nKApmdWxsX3dpZHRoICAgICAgICA9IEZBTFNFLApib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJob3ZlciIsImNvbmRlbnNlZCIpCikgJT4lCmNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUUlVFKSAlPiUKcm93X3NwZWMoMCwgYm9sZCA9IFRSVUUsIGJhY2tncm91bmQgPSAiI2YyZjJmMiIpICU+JQpmb290bm90ZSgKZ2VuZXJhbCA9ICJTaWduaWYuIGNvZGVzOiAqKiogcDwwLjAwMSwgKiogcDwwLjAxLCAqIHA8MC4wNSwgwrcgcDwwLjEuIiwKdGhyZWVwYXJ0dGFibGUgPSBUUlVFCikKIyBrb2VmaWNpZW50eSBzIGh2aWV6ZGnEjWthbWkgc8O6IMWhdGF0aXN0aWNreSB2w716bmFtbsOpLiBabmFtaWVua28gdXLEjXVqZSwgxI1pIGRhbsOhIHByZW1lbm7DoSBzw7p2aXPDrSBzIEhEUCBwb3ppdMOtdm5lIGFsZWJvIG5lZ2F0w612bmUuCgojIE1vZGVsIEZpdCBTdGF0aXN0aWNzCmZpdC50YmwgPC0gZ2xhbmNlKG1vZGVsKSAlPiUKdHJhbnNtdXRlKApgUi1zcXVhcmVkYCAgICAgID0gci5zcXVhcmVkLApgQWRqLiBSLXNxdWFyZWRgID0gYWRqLnIuc3F1YXJlZCwKYEYtc3RhdGlzdGljYCAgICA9IHN0YXRpc3RpYywKYEYgcC12YWx1ZWAgICAgICA9IHAudmFsdWUsCmBBSUNgICAgICAgICAgICAgPSBBSUMsCmBCSUNgICAgICAgICAgICAgPSBCSUMsCmBOdW0uIG9icy5gICAgICAgPSBub2JzCikKCmZpdC50YmwgJT4lCmthYmxlKGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiTW9kZWwgRml0IFN0YXRpc3RpY3MiKSAlPiUKa2FibGVfc3R5bGluZygKZnVsbF93aWR0aCAgICAgICAgPSBGQUxTRSwKYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJjb25kZW5zZWQiKQopCgoKCgoKCgoKCgo=