Tento report načíta súbor Databaza.csv (stĺpce: Okres, Obec, 2024M12, …, 2024M01), prevedie údaje do “long” formátu a vykoná základné grafy, štatistiky, testy a regresiu.

Balíčky a dáta

suppressPackageStartupMessages({
  library(dplyr)
  library(readr)
  library(tidyr)
  library(ggplot2)
  library(knitr)
  library(kableExtra)
  library(broom)
  library(stringr)
})
# CSV je bodkočiarkové
udaje_raw <- read_delim("Databaza.csv", delim = ";", show_col_types = FALSE)

# validácie
stopifnot(all(c("Okres","Obec") %in% names(udaje_raw)))
mesiac_cols <- grep("^2024M\\d{2}$", names(udaje_raw), value = TRUE)
if (length(mesiac_cols) == 0) {
  stop("Nenašiel som žiadne stĺpce typu 2024Mxx (napr. 2024M12, 2024M01).")
}

# Long formát
udaje_long <- udaje_raw |>
  pivot_longer(
    cols = all_of(mesiac_cols),
    names_to = "YM",
    values_to = "Hodnota"
  ) |>
  mutate(
    Rok    = as.integer(str_sub(YM, 1, 4)),
    Mesiac = as.integer(str_sub(YM, 6, 7)),
    Hodnota = suppressWarnings(as.numeric(Hodnota))
  )

# Wide podmnožina pre jednoduché modely
udaje_dec <- udaje_raw |>
  dplyr::select(Okres, Obec, any_of(c("2024M12","2024M11","2024M06","2024M01"))) |>
  mutate(across(-c(Okres, Obec), ~ suppressWarnings(as.numeric(.))))

Vizualizácie

Scatter plot: 2024M11 vs 2024M12

if (all(c("2024M12","2024M11") %in% names(udaje_dec))) {
  ggplot(udaje_dec, aes(x = `2024M11`, y = `2024M12`, colour = Okres)) +
    geom_point(alpha = 0.8) +
    theme_minimal() +
    labs(
      title = "Vzťah medzi 2024M11 a 2024M12 naprieč obcami",
      x = "Hodnota v 2024M11",
      y = "Hodnota v 2024M12",
      colour = "Okres"
    )
} else {
  plot.new(); title("Na scatter plot chýbajú 2024M11 a/alebo 2024M12")
}

Boxplot: rozdelenie hodnôt podľa mesiacov

ggplot(udaje_long, aes(x = factor(Mesiac), y = Hodnota)) +
  geom_boxplot(fill = "lightblue", colour = "darkblue") +
  labs(
    title = "Rozdelenie hodnôt podľa mesiacov (rok 2024)",
    x = "Mesiac",
    y = "Hodnota"
  ) +
  theme_minimal()

Základné štatistiky

stat_tbl <- udaje_long |>
  group_by(Mesiac) |>
  summarise(
    n      = n(),
    mean   = mean(Hodnota, na.rm = TRUE),
    sd     = sd(Hodnota, na.rm = TRUE),
    min    = min(Hodnota, na.rm = TRUE),
    q25    = quantile(Hodnota, 0.25, na.rm = TRUE),
    median = median(Hodnota, na.rm = TRUE),
    q75    = quantile(Hodnota, 0.75, na.rm = TRUE),
    max    = max(Hodnota, na.rm = TRUE),
    .groups = "drop"
  )

# knitr tabuľka
kable(stat_tbl, digits = 2, caption = "Základné štatistiky podľa mesiacov (2024)")
Základné štatistiky podľa mesiacov (2024)
Mesiac n mean sd min q25 median q75 max
1 200 4912.38 11845.18 102 880.50 1701.5 3250.50 112794
2 200 4913.83 11845.32 103 878.75 1702.5 3260.50 112740
3 200 4915.00 11844.50 103 881.75 1703.5 3257.00 112686
4 200 4916.87 11844.14 103 879.75 1707.5 3264.00 112661
5 200 4919.06 11846.72 103 882.00 1707.0 3266.00 112584
6 200 4921.61 11848.82 103 886.50 1710.0 3261.50 112553
7 200 4923.44 11853.09 101 887.75 1713.0 3267.50 112528
8 200 4925.03 11853.64 101 890.00 1717.0 3269.25 112469
9 200 4926.24 11854.74 100 889.50 1719.0 3268.25 112449
10 200 4927.26 11854.32 100 886.75 1717.5 3273.75 112436
11 200 4929.35 11856.14 101 892.00 1719.0 3276.50 112400
12 200 4930.90 11862.18 101 891.50 1720.0 3279.00 112447

# kableExtra tabuľka
stat_tbl |>
  kable(digits = 2, caption = "Základné štatistiky podľa mesiacov (2024)") |>
  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, "Štatistiky hodnôt" = 7))
Základné štatistiky podľa mesiacov (2024)
Štatistiky hodnôt
Mesiac n mean sd min q25 median q75 max
1 200 4912.38 11845.18 102 880.50 1701.5 3250.50 112794
2 200 4913.83 11845.32 103 878.75 1702.5 3260.50 112740
3 200 4915.00 11844.50 103 881.75 1703.5 3257.00 112686
4 200 4916.87 11844.14 103 879.75 1707.5 3264.00 112661
5 200 4919.06 11846.72 103 882.00 1707.0 3266.00 112584
6 200 4921.61 11848.82 103 886.50 1710.0 3261.50 112553
7 200 4923.44 11853.09 101 887.75 1713.0 3267.50 112528
8 200 4925.03 11853.64 101 890.00 1717.0 3269.25 112469
9 200 4926.24 11854.74 100 889.50 1719.0 3268.25 112449
10 200 4927.26 11854.32 100 886.75 1717.5 3273.75 112436
11 200 4929.35 11856.14 101 892.00 1719.0 3276.50 112400
12 200 4930.90 11862.18 101 891.50 1720.0 3279.00 112447

Testovanie hypotéz

t-test: porovnanie priemerov (2024M12 vs 2024M06)

if (all(c("2024M12","2024M06") %in% names(udaje_raw))) {
  t.test.result <- t.test(
    udaje_long$Hodnota[udaje_long$YM == "2024M12"],
    udaje_long$Hodnota[udaje_long$YM == "2024M06"]
  )
  t.test.result
} else {
  "Na t-test chýba 2024M12 a/alebo 2024M06."
}

    Welch Two Sample t-test

data:  udaje_long$Hodnota[udaje_long$YM == "2024M12"] and udaje_long$Hodnota[udaje_long$YM == "2024M06"]
t = 0.007836, df = 398, p-value = 0.9938
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -2321.433  2340.013
sample estimates:
mean of x mean of y 
  4930.90   4921.61 

ANOVA: Hodnota ~ Mesiac

anova.result <- aov(Hodnota ~ factor(Mesiac), data = udaje_long)
summary(anova.result)
                 Df    Sum Sq   Mean Sq F value Pr(>F)
factor(Mesiac)   11 8.663e+04      7875       0      1
Residuals      2388 3.354e+11 140439858               

Lineárna regresia

Predikujeme 2024M12 pomocou 2024M11 a 2024M01 (ak sú dostupné).

if (all(c("2024M12","2024M11","2024M01") %in% names(udaje_dec))) {
  model <- lm(`2024M12` ~ `2024M11` + `2024M01`, data = udaje_dec)
  summary(model)
} else {
  model <- NULL
  "Na regresiu chýbajú niektoré z 2024M12, 2024M11, 2024M01."
}

Call:
lm(formula = `2024M12` ~ `2024M11` + `2024M01`, data = udaje_dec)

Residuals:
    Min      1Q  Median      3Q     Max 
-51.294  -2.214   0.940   3.381  31.350 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) -1.778536   0.633074  -2.809  0.00546 ** 
`2024M11`    1.066640   0.006654 160.291  < 2e-16 ***
`2024M01`   -0.066194   0.006661  -9.938  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 8.195 on 197 degrees of freedom
Multiple R-squared:      1, Adjusted R-squared:      1 
F-statistic: 2.085e+08 on 2 and 197 DF,  p-value: < 2.2e-16

Koeficienty a intervaly spoľahlivosti

if (!is.null(model)) {
  coef.tbl <- broom::tidy(model, conf.int = TRUE) |>
    dplyr::mutate(
      term = dplyr::recode(term,
                           "(Intercept)" = "Intercept",
                           "`2024M11`"   = "Hodnota v 2024M11",
                           "`2024M01`"   = "Hodnota v 2024M01"),
      stars = dplyr::case_when(
        p.value < 0.001 ~ "***",
        p.value < 0.01  ~ "**",
        p.value < 0.05  ~ "*",
        p.value < 0.1   ~ "·",
        TRUE            ~ ""
      )
    ) |>
    dplyr::transmute(
      Term         = term,
      Estimate     = estimate,
      `Std. Error` = std.error,
      `t value`    = statistic,
      `p value`    = p.value,
      `95% CI`     = stringr::str_c("[", round(conf.low, 3), ", ", round(conf.high, 3), "]"),
      Sig          = stars
    )

  coef.tbl |>
    kable(digits = 3, caption = "OLS koeficienty: 2024M12 ~ 2024M11 + 2024M01") |>
    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
    )
} else {
  cat("Koeficienty nie sú k dispozícii (model sa nefitol).")
}
OLS koeficienty: 2024M12 ~ 2024M11 + 2024M01
Term Estimate Std. Error t value p value 95% CI Sig
Intercept -1.779 0.633 -2.809 0.005 [-3.027, -0.53] **
Hodnota v 2024M11 1.067 0.007 160.291 0.000 [1.054, 1.08] ***
Hodnota v 2024M01 -0.066 0.007 -9.938 0.000 [-0.079, -0.053] ***
Note:
Signif. codes: *** p<0.001, ** p<0.01, * p<0.05, · p<0.1.

Štatistiky kvality modelu

if (!is.null(model)) {
  fit.tbl <- broom::glance(model) |>
    dplyr::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"))
} else {
  cat("Fit štatistiky nie sú k dispozícii (model sa nefitol).")
}
Model Fit Statistics
R-squared Adj. R-squared F-statistic F p-value AIC BIC Num. obs.
1 1 208498789 0 1413.939 1427.133 200
LS0tCnRpdGxlOiAiUHLDoWNhIHMgZGF0YWLDoXpvdSAtIGltcG9ydCDDumRham92LCBncmFmeSwgxaF0YXRpc3Rpa3kiCmF1dGhvcjogIkZpbGlwIEp1cmvDocSNZWsgIDxicj4KKHMgdnl1xb5pdMOtbSB2ZXJlam5lIGRvc3R1cG7DvWNoIGvDs2RvdiBhIENoYXRHUFQpIgpkYXRlOiAiTm92ZW1iZXIgMjAyNSIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRoZW1lOiB1bml0ZWQKICAgIGhpZ2hsaWdodDogdGFuZ28KZWRpdG9yX29wdGlvbnM6IAogIG1hcmtkb3duOiAKICAgIHdyYXA6IDcyCi0tLQoKPiBUZW50byByZXBvcnQgbmHEjcOtdGEgc8O6Ym9yICoqRGF0YWJhemEuY3N2KiogKHN0xLpwY2U6ICpPa3JlcyosICpPYmVjKiwgKjIwMjRNMTIqLCAuLi4sICoyMDI0TTAxKiksIAo+IHByZXZlZGllIMO6ZGFqZSBkbyAibG9uZyIgZm9ybcOhdHUgYSB2eWtvbsOhIHrDoWtsYWRuw6kgZ3JhZnksIMWhdGF0aXN0aWt5LCB0ZXN0eSBhIHJlZ3Jlc2l1LgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsCiAgZmlnLndpZHRoID0gNywgZmlnLmhlaWdodCA9IDQuNQopCmBgYAoKIyBCYWzDrcSNa3kgYSBkw6F0YQoKYGBge3IgcGFja2FnZXN9CnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyh7CiAgbGlicmFyeShkcGx5cikKICBsaWJyYXJ5KHJlYWRyKQogIGxpYnJhcnkodGlkeXIpCiAgbGlicmFyeShnZ3Bsb3QyKQogIGxpYnJhcnkoa25pdHIpCiAgbGlicmFyeShrYWJsZUV4dHJhKQogIGxpYnJhcnkoYnJvb20pCiAgbGlicmFyeShzdHJpbmdyKQp9KQpgYGAKCmBgYHtyIGxvYWQtZGF0YX0KIyBDU1YgamUgYm9ka2/EjWlhcmtvdsOpCnVkYWplX3JhdyA8LSByZWFkX2RlbGltKCJEYXRhYmF6YS5jc3YiLCBkZWxpbSA9ICI7Iiwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkKCiMgdmFsaWTDoWNpZQpzdG9waWZub3QoYWxsKGMoIk9rcmVzIiwiT2JlYyIpICVpbiUgbmFtZXModWRhamVfcmF3KSkpCm1lc2lhY19jb2xzIDwtIGdyZXAoIl4yMDI0TVxcZHsyfSQiLCBuYW1lcyh1ZGFqZV9yYXcpLCB2YWx1ZSA9IFRSVUUpCmlmIChsZW5ndGgobWVzaWFjX2NvbHMpID09IDApIHsKICBzdG9wKCJOZW5hxaFpZWwgc29tIMW+aWFkbmUgc3TEunBjZSB0eXB1IDIwMjRNeHggKG5hcHIuIDIwMjRNMTIsIDIwMjRNMDEpLiIpCn0KCiMgTG9uZyBmb3Jtw6F0CnVkYWplX2xvbmcgPC0gdWRhamVfcmF3IHw+CiAgcGl2b3RfbG9uZ2VyKAogICAgY29scyA9IGFsbF9vZihtZXNpYWNfY29scyksCiAgICBuYW1lc190byA9ICJZTSIsCiAgICB2YWx1ZXNfdG8gPSAiSG9kbm90YSIKICApIHw+CiAgbXV0YXRlKAogICAgUm9rICAgID0gYXMuaW50ZWdlcihzdHJfc3ViKFlNLCAxLCA0KSksCiAgICBNZXNpYWMgPSBhcy5pbnRlZ2VyKHN0cl9zdWIoWU0sIDYsIDcpKSwKICAgIEhvZG5vdGEgPSBzdXBwcmVzc1dhcm5pbmdzKGFzLm51bWVyaWMoSG9kbm90YSkpCiAgKQoKIyBXaWRlIHBvZG1ub8W+aW5hIHByZSBqZWRub2R1Y2jDqSBtb2RlbHkKdWRhamVfZGVjIDwtIHVkYWplX3JhdyB8PgogIGRwbHlyOjpzZWxlY3QoT2tyZXMsIE9iZWMsIGFueV9vZihjKCIyMDI0TTEyIiwiMjAyNE0xMSIsIjIwMjRNMDYiLCIyMDI0TTAxIikpKSB8PgogIG11dGF0ZShhY3Jvc3MoLWMoT2tyZXMsIE9iZWMpLCB+IHN1cHByZXNzV2FybmluZ3MoYXMubnVtZXJpYyguKSkpKQpgYGAKCiMgVml6dWFsaXrDoWNpZQoKIyMgU2NhdHRlciBwbG90OiAyMDI0TTExIHZzIDIwMjRNMTIKCmBgYHtyIHNjYXR0ZXJ9CmlmIChhbGwoYygiMjAyNE0xMiIsIjIwMjRNMTEiKSAlaW4lIG5hbWVzKHVkYWplX2RlYykpKSB7CiAgZ2dwbG90KHVkYWplX2RlYywgYWVzKHggPSBgMjAyNE0xMWAsIHkgPSBgMjAyNE0xMmAsIGNvbG91ciA9IE9rcmVzKSkgKwogICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuOCkgKwogICAgdGhlbWVfbWluaW1hbCgpICsKICAgIGxhYnMoCiAgICAgIHRpdGxlID0gIlZ6xaVhaCBtZWR6aSAyMDI0TTExIGEgMjAyNE0xMiBuYXByaWXEjSBvYmNhbWkiLAogICAgICB4ID0gIkhvZG5vdGEgdiAyMDI0TTExIiwKICAgICAgeSA9ICJIb2Rub3RhIHYgMjAyNE0xMiIsCiAgICAgIGNvbG91ciA9ICJPa3JlcyIKICAgICkKfSBlbHNlIHsKICBwbG90Lm5ldygpOyB0aXRsZSgiTmEgc2NhdHRlciBwbG90IGNow71iYWrDuiAyMDI0TTExIGEvYWxlYm8gMjAyNE0xMiIpCn0KYGBgCgojIyBCb3hwbG90OiByb3pkZWxlbmllIGhvZG7DtHQgcG9kxL5hIG1lc2lhY292CgpgYGB7ciBib3hwbG90fQpnZ3Bsb3QodWRhamVfbG9uZywgYWVzKHggPSBmYWN0b3IoTWVzaWFjKSwgeSA9IEhvZG5vdGEpKSArCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAibGlnaHRibHVlIiwgY29sb3VyID0gImRhcmtibHVlIikgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJSb3pkZWxlbmllIGhvZG7DtHQgcG9kxL5hIG1lc2lhY292IChyb2sgMjAyNCkiLAogICAgeCA9ICJNZXNpYWMiLAogICAgeSA9ICJIb2Rub3RhIgogICkgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCiMgWsOha2xhZG7DqSDFoXRhdGlzdGlreQoKYGBge3Igc3RhdHN9CnN0YXRfdGJsIDwtIHVkYWplX2xvbmcgfD4KICBncm91cF9ieShNZXNpYWMpIHw+CiAgc3VtbWFyaXNlKAogICAgbiAgICAgID0gbigpLAogICAgbWVhbiAgID0gbWVhbihIb2Rub3RhLCBuYS5ybSA9IFRSVUUpLAogICAgc2QgICAgID0gc2QoSG9kbm90YSwgbmEucm0gPSBUUlVFKSwKICAgIG1pbiAgICA9IG1pbihIb2Rub3RhLCBuYS5ybSA9IFRSVUUpLAogICAgcTI1ICAgID0gcXVhbnRpbGUoSG9kbm90YSwgMC4yNSwgbmEucm0gPSBUUlVFKSwKICAgIG1lZGlhbiA9IG1lZGlhbihIb2Rub3RhLCBuYS5ybSA9IFRSVUUpLAogICAgcTc1ICAgID0gcXVhbnRpbGUoSG9kbm90YSwgMC43NSwgbmEucm0gPSBUUlVFKSwKICAgIG1heCAgICA9IG1heChIb2Rub3RhLCBuYS5ybSA9IFRSVUUpLAogICAgLmdyb3VwcyA9ICJkcm9wIgogICkKCiMga25pdHIgdGFidcS+a2EKa2FibGUoc3RhdF90YmwsIGRpZ2l0cyA9IDIsIGNhcHRpb24gPSAiWsOha2xhZG7DqSDFoXRhdGlzdGlreSBwb2TEvmEgbWVzaWFjb3YgKDIwMjQpIikKCiMga2FibGVFeHRyYSB0YWJ1xL5rYQpzdGF0X3RibCB8PgogIGthYmxlKGRpZ2l0cyA9IDIsIGNhcHRpb24gPSAiWsOha2xhZG7DqSDFoXRhdGlzdGlreSBwb2TEvmEgbWVzaWFjb3YgKDIwMjQpIikgfD4KICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiKSkgfD4KICBjb2x1bW5fc3BlYygxLCBib2xkID0gVFJVRSkgfD4KICByb3dfc3BlYygwLCBib2xkID0gVFJVRSwgYmFja2dyb3VuZCA9ICIjZjJmMmYyIikgfD4KICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiID0gMiwgIsWgdGF0aXN0aWt5IGhvZG7DtHQiID0gNykpCmBgYAoKIyBUZXN0b3ZhbmllIGh5cG90w6l6CgojIyB0LXRlc3Q6IHBvcm92bmFuaWUgcHJpZW1lcm92ICgyMDI0TTEyIHZzIDIwMjRNMDYpCgpgYGB7ciB0dGVzdH0KaWYgKGFsbChjKCIyMDI0TTEyIiwiMjAyNE0wNiIpICVpbiUgbmFtZXModWRhamVfcmF3KSkpIHsKICB0LnRlc3QucmVzdWx0IDwtIHQudGVzdCgKICAgIHVkYWplX2xvbmckSG9kbm90YVt1ZGFqZV9sb25nJFlNID09ICIyMDI0TTEyIl0sCiAgICB1ZGFqZV9sb25nJEhvZG5vdGFbdWRhamVfbG9uZyRZTSA9PSAiMjAyNE0wNiJdCiAgKQogIHQudGVzdC5yZXN1bHQKfSBlbHNlIHsKICAiTmEgdC10ZXN0IGNow71iYSAyMDI0TTEyIGEvYWxlYm8gMjAyNE0wNi4iCn0KYGBgCgojIyBBTk9WQTogSG9kbm90YSB+IE1lc2lhYwoKYGBge3IgYW5vdmF9CmFub3ZhLnJlc3VsdCA8LSBhb3YoSG9kbm90YSB+IGZhY3RvcihNZXNpYWMpLCBkYXRhID0gdWRhamVfbG9uZykKc3VtbWFyeShhbm92YS5yZXN1bHQpCmBgYAoKIyBMaW5lw6FybmEgcmVncmVzaWEKClByZWRpa3VqZW1lICoqMjAyNE0xMioqIHBvbW9jb3UgKioyMDI0TTExKiogYSAqKjIwMjRNMDEqKiAoYWsgc8O6IGRvc3R1cG7DqSkuCgpgYGB7ciByZWdyZXNzaW9ufQppZiAoYWxsKGMoIjIwMjRNMTIiLCIyMDI0TTExIiwiMjAyNE0wMSIpICVpbiUgbmFtZXModWRhamVfZGVjKSkpIHsKICBtb2RlbCA8LSBsbShgMjAyNE0xMmAgfiBgMjAyNE0xMWAgKyBgMjAyNE0wMWAsIGRhdGEgPSB1ZGFqZV9kZWMpCiAgc3VtbWFyeShtb2RlbCkKfSBlbHNlIHsKICBtb2RlbCA8LSBOVUxMCiAgIk5hIHJlZ3Jlc2l1IGNow71iYWrDuiBuaWVrdG9yw6kgeiAyMDI0TTEyLCAyMDI0TTExLCAyMDI0TTAxLiIKfQpgYGAKCiMjIEtvZWZpY2llbnR5IGEgaW50ZXJ2YWx5IHNwb8S+YWhsaXZvc3RpCgpgYGB7ciBjb2VmLXRhYmxlLCByZXN1bHRzPSdhc2lzJ30KaWYgKCFpcy5udWxsKG1vZGVsKSkgewogIGNvZWYudGJsIDwtIGJyb29tOjp0aWR5KG1vZGVsLCBjb25mLmludCA9IFRSVUUpIHw+CiAgICBkcGx5cjo6bXV0YXRlKAogICAgICB0ZXJtID0gZHBseXI6OnJlY29kZSh0ZXJtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiKEludGVyY2VwdCkiID0gIkludGVyY2VwdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJgMjAyNE0xMWAiICAgPSAiSG9kbm90YSB2IDIwMjRNMTEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiYDIwMjRNMDFgIiAgID0gIkhvZG5vdGEgdiAyMDI0TTAxIiksCiAgICAgIHN0YXJzID0gZHBseXI6OmNhc2Vfd2hlbigKICAgICAgICBwLnZhbHVlIDwgMC4wMDEgfiAiKioqIiwKICAgICAgICBwLnZhbHVlIDwgMC4wMSAgfiAiKioiLAogICAgICAgIHAudmFsdWUgPCAwLjA1ICB+ICIqIiwKICAgICAgICBwLnZhbHVlIDwgMC4xICAgfiAiwrciLAogICAgICAgIFRSVUUgICAgICAgICAgICB+ICIiCiAgICAgICkKICAgICkgfD4KICAgIGRwbHlyOjp0cmFuc211dGUoCiAgICAgIFRlcm0gICAgICAgICA9IHRlcm0sCiAgICAgIEVzdGltYXRlICAgICA9IGVzdGltYXRlLAogICAgICBgU3RkLiBFcnJvcmAgPSBzdGQuZXJyb3IsCiAgICAgIGB0IHZhbHVlYCAgICA9IHN0YXRpc3RpYywKICAgICAgYHAgdmFsdWVgICAgID0gcC52YWx1ZSwKICAgICAgYDk1JSBDSWAgICAgID0gc3RyaW5ncjo6c3RyX2MoIlsiLCByb3VuZChjb25mLmxvdywgMyksICIsICIsIHJvdW5kKGNvbmYuaGlnaCwgMyksICJdIiksCiAgICAgIFNpZyAgICAgICAgICA9IHN0YXJzCiAgICApCgogIGNvZWYudGJsIHw+CiAgICBrYWJsZShkaWdpdHMgPSAzLCBjYXB0aW9uID0gIk9MUyBrb2VmaWNpZW50eTogMjAyNE0xMiB+IDIwMjRNMTEgKyAyMDI0TTAxIikgfD4KICAgIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJob3ZlciIsImNvbmRlbnNlZCIpKSB8PgogICAgY29sdW1uX3NwZWMoMSwgYm9sZCA9IFRSVUUpIHw+CiAgICByb3dfc3BlYygwLCBib2xkID0gVFJVRSwgYmFja2dyb3VuZCA9ICIjZjJmMmYyIikgfD4KICAgIGZvb3Rub3RlKAogICAgICBnZW5lcmFsID0gIlNpZ25pZi4gY29kZXM6ICoqKiBwPDAuMDAxLCAqKiBwPDAuMDEsICogcDwwLjA1LCDCtyBwPDAuMS4iLAogICAgICB0aHJlZXBhcnR0YWJsZSA9IFRSVUUKICAgICkKfSBlbHNlIHsKICBjYXQoIktvZWZpY2llbnR5IG5pZSBzw7ogayBkaXNwb3rDrWNpaSAobW9kZWwgc2EgbmVmaXRvbCkuIikKfQpgYGAKCiMjIMWgdGF0aXN0aWt5IGt2YWxpdHkgbW9kZWx1CgpgYGB7ciBmaXQtdGFibGUsIHJlc3VsdHM9J2FzaXMnfQppZiAoIWlzLm51bGwobW9kZWwpKSB7CiAgZml0LnRibCA8LSBicm9vbTo6Z2xhbmNlKG1vZGVsKSB8PgogICAgZHBseXI6OnRyYW5zbXV0ZSgKICAgICAgYFItc3F1YXJlZGAgICAgICA9IHIuc3F1YXJlZCwKICAgICAgYEFkai4gUi1zcXVhcmVkYCA9IGFkai5yLnNxdWFyZWQsCiAgICAgIGBGLXN0YXRpc3RpY2AgICAgPSBzdGF0aXN0aWMsCiAgICAgIGBGIHAtdmFsdWVgICAgICAgPSBwLnZhbHVlLAogICAgICBgQUlDYCAgICAgICAgICAgID0gQUlDLAogICAgICBgQklDYCAgICAgICAgICAgID0gQklDLAogICAgICBgTnVtLiBvYnMuYCAgICAgID0gbm9icwogICAgKQoKICBmaXQudGJsIHw+CiAgICBrYWJsZShkaWdpdHMgPSAzLCBjYXB0aW9uID0gIk1vZGVsIEZpdCBTdGF0aXN0aWNzIikgfD4KICAgIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBib290c3RyYXBfb3B0aW9ucyA9IGMoImNvbmRlbnNlZCIpKQp9IGVsc2UgewogIGNhdCgiRml0IMWhdGF0aXN0aWt5IG5pZSBzw7ogayBkaXNwb3rDrWNpaSAobW9kZWwgc2EgbmVmaXRvbCkuIikKfQpgYGA=