knitr::opts_chunk$set(
    echo = TRUE,
    message = FALSE,
    warning = FALSE
)

Práca s údajmi

Tradičná práca s databázou

Príklad

Majme údaje o krasokorčuliarkach, ktoré sa na posledných majstrovstvách sveta umiestnili na prvých desiatich priečkach.

Meno <- c("Kaori Sakamoto", "Isabeau Levito", "Chaeyeon Kim",
          "Loena Hendrickx", "Kimmy Repond", "Lee Hae-In",
          "Mone Chiba", "Hana Yoshida", "Livia Kaiser", "Amber Glenn")

Krajina <- c("JPN", "USA", "KOR", "BEL", "SUI", "KOR", "JPN", "JPN", "SUI", "USA")

Body <- c(222.96, 212.16, 203.59, 200.25, 196.02, 195.48, 195.46, 194.93, 187.24, 186.53)

# Vytvorenie data frame
krasokorculiarky <- data.frame(Meno, Krajina, Body)

# Zobrazenie
print(krasokorculiarky)

Tieto tri premenné nie sú zatiaľ nijako prepojené, predstavujú izolované stĺpce tabuľky. Do tabuľky ich spojíme nasledovne

krasokorčuliarky <- data.frame(Meno,Krajina,Body)
print(krasokorculiarky)

Vysvetlenie: DataFrame má tri stĺpce: Meno, Krajina a Body. Niektoré operácie s údajmi organizovanými v .data.frame. sú uvedené nasledovne

print(krasokorculiarky$Krajina)                   # vypíše nám stĺpec s krajinami
 [1] "JPN" "USA" "KOR" "BEL" "SUI" "KOR" "JPN" "JPN" "SUI" "USA"
print(mean(krasokorculiarky$Body))                # priemerný počet bodov
[1] 199.462
print(krasokorculiarky[Meno=="Kaori Sakamoto",])  # adresovanie celého riadku podľa mena
print(krasokorculiarky[3])                       # ina moznost adresovania celeho riadku
print(krasokorculiarky[2:3])                     # vypisanie druheho a tretieho stlpca tabulky
print(krasokorculiarky[1,1])                      # vypisanie jednej bunky tabulky
[1] "Kaori Sakamoto"
summary(krasokorculiarky)                         # zakladna deskriptivna statistika celej tabulky
     Meno             Krajina               Body      
 Length:10          Length:10          Min.   :186.5  
 Class :character   Class :character   1st Qu.:195.1  
 Mode  :character   Mode  :character   Median :195.8  
                                       Mean   :199.5  
                                       3rd Qu.:202.8  
                                       Max.   :223.0  

Ak chceme pridať k tabuľke dodatočný stĺpec, potom to robíme nasledovne:

MaMedailu <- c(TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE)
krasokorculiarky <- cbind(krasokorculiarky,MaMedailu)
print(krasokorculiarky)

Pridali sme stlpec s informáciou, ktorá nám hovorí o tom, či si súťažiaca vybojovala medailu alebo nie. Ak chceme pridať riadok, potom

# New record (must match column order/types)
novy.riadok <- data.frame(Meno = "Anna Shcherbakova", Krajina = "RUS", Body = 184.50, MaMedailu = FALSE)

# Append
krasokorculiarky <- rbind(krasokorculiarky, novy.riadok)
print(krasokorculiarky)

Tabuľky v prostredí kableextra

library(knitr)
library(kableExtra)

Meno <- c("Kaori Sakamoto", "Isabeau Levito", "Chaeyeon Kim",
          "Loena Hendrickx", "Kimmy Repond", "Lee Hae-In",
          "Mone Chiba", "Hana Yoshida", "Livia Kaiser", "Amber Glenn")

Krajina <- c("JPN", "USA", "KOR", "BEL", "SUI", "KOR", "JPN", "JPN", "SUI", "USA")

Body <- c(222.96, 212.16, 203.59, 200.25, 196.02, 195.48, 195.46, 194.93, 187.24, 186.53)

MaMedailu <- c(TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE)

krasokorculiarky <- data.frame(Meno, Krajina, Body, MaMedailu)

kable(
  krasokorculiarky,
  digits = 2,
  align = c("l","c","r","c"),
  caption = "Konečné výsledky MS 2024 v krasokorčuľovaní žien"
) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = FALSE,
    position = "center"
  )
Konečné výsledky MS 2024 v krasokorčuľovaní žien
Meno Krajina Body MaMedailu
Kaori Sakamoto JPN 222.96 TRUE
Isabeau Levito USA 212.16 TRUE
Chaeyeon Kim KOR 203.59 TRUE
Loena Hendrickx BEL 200.25 FALSE
Kimmy Repond SUI 196.02 FALSE
Lee Hae-In KOR 195.48 FALSE
Mone Chiba JPN 195.46 FALSE
Hana Yoshida JPN 194.93 FALSE
Livia Kaiser SUI 187.24 FALSE
Amber Glenn USA 186.53 FALSE

Tidyverse - moderná práca s údajmi

Tidyverse je súbor knižníc, ktoré majú zjednodušiť prácu s údajmi. Majú jednotný komunikačný štandard, vzájomne sa doplňujú.

# Load tidyverse
library(tidyverse)

dplyr - pre manipuláciu s údajmi

.dplyr. poskytuje základné možnosti manipulácie s údajmi, ako napr.:

  1. filter(): vyberá riadky

  2. select(): vyberá stĺpce

  3. mutate(): vytvára nové stĺpce tabuľky

  4. arrange(): triedi riadky

  5. summarise(): sumarizuje

V nasledovnej ukážke využijeme tzv. .pipes. %>% alebo %<% umožňuje posielať výsledky z jednej funkcie priamo do volanie nasledovnej funkcie. To umožňuje ľahšiu čitateľnosť kódov, konvencia sa ujala a má široké použitie.

Výber a triedenie

# výber a následné triedenie
krasokorculiarky %>%
  filter(Body > 200) %>%     # vybera zaznamy s poctom bodov viac, ako 200
  arrange(desc(Body)) %>%     # vysledny subor triedi zostupne podla premennej Body
kable %>%
    kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = FALSE,
    position = "center"
  )
Meno Krajina Body MaMedailu
Kaori Sakamoto JPN 222.96 TRUE
Isabeau Levito USA 212.16 TRUE
Chaeyeon Kim KOR 203.59 TRUE
Loena Hendrickx BEL 200.25 FALSE

Zoskupenie a sumarizácia

# Zoskupí and sumarizuje
krasokorculiarky %>%
  group_by(Krajina) %>%      # zoskupi zaznamy podla premennej MaAuto a vypocita za kazdu skupinu jej priemer Body
  summarise(                # a taktiez spocita pocetnosti oboch skupin
    Priem.Body = mean(Body),
    count = n()
  ) %>%
 kable(
    caption = "Priemerné Body podľa premennej Krajina",
    col.names = c("Krajina", "Priemer Body", "Počet"),
    align = "c"
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = FALSE,
    position = "center"
  )
Priemerné Body podľa premennej Krajina
Krajina Priemer Body Počet
BEL 200.250 1
JPN 204.450 3
KOR 199.535 2
SUI 191.630 2
USA 199.345 2

Vytváranie novej premennej

library(dplyr)
library(knitr)
library(kableExtra)

# Pridanie grade a CloseToMedal
krasokorculiarky %>%
  mutate(
    grade = case_when(
      Body >= 220 ~ "A",
      Body >= 200 ~ "B",
      Body >= 190 ~ "C",
      TRUE ~ "D"
    ),
    CloseToMedal = Body >= 200 & Body < 203.59  # TRUE pre body tesne mimo top 3 čiže blízko ku medaile
  ) %>%
  kable() %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = FALSE,
    position = "center"
  ) 
Meno Krajina Body MaMedailu grade CloseToMedal
Kaori Sakamoto JPN 222.96 TRUE A FALSE
Isabeau Levito USA 212.16 TRUE B FALSE
Chaeyeon Kim KOR 203.59 TRUE B FALSE
Loena Hendrickx BEL 200.25 FALSE B TRUE
Kimmy Repond SUI 196.02 FALSE C FALSE
Lee Hae-In KOR 195.48 FALSE C FALSE
Mone Chiba JPN 195.46 FALSE C FALSE
Hana Yoshida JPN 194.93 FALSE C FALSE
Livia Kaiser SUI 187.24 FALSE D FALSE
Amber Glenn USA 186.53 FALSE D FALSE
LS0tCnRpdGxlOiAiUHLDoWNhIHMgZGF0YWLDoXpvdSIKYXV0aG9yOiAiTWlyaWFtYSDFoGt1bGNvdsOhICA8YnI+IChzIHZ5dcW+aXTDrW0gdmVyZWpuZSBkb3N0dXBuw71jaCBrw7Nkb3YpIgpkYXRlOiAiU2VwdGVtYmVyIDIwMjUiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRoZW1lOiB1bml0ZWQKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGNzczogc3R5bGVzLmNzcwogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIGRmX3ByaW50OiBwYWdlZAplZGl0b3Jfb3B0aW9uczoKICBtYXJrZG93bjoKICAgIHdyYXA6IDcyCi0tLQoKYGBge3J9CmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICAgIGVjaG8gPSBUUlVFLAogICAgbWVzc2FnZSA9IEZBTFNFLAogICAgd2FybmluZyA9IEZBTFNFCikKYGBgCgojIFByw6FjYSBzIMO6ZGFqbWkKCiMjIFRyYWRpxI1uw6EgcHLDoWNhIHMgZGF0YWLDoXpvdQoKIyMjIFByw61rbGFkCgpNYWptZSDDumRhamUgbyBrcmFzb2tvcsSNdWxpYXJrYWNoLCBrdG9yw6kgc2EgbmEgcG9zbGVkbsO9Y2ggbWFqc3Ryb3ZzdHbDoWNoCnN2ZXRhIHVtaWVzdG5pbGkgbmEgcHJ2w71jaCBkZXNpYXRpY2ggcHJpZcSNa2FjaC4KCmBgYHtyfQpNZW5vIDwtIGMoIkthb3JpIFNha2Ftb3RvIiwgIklzYWJlYXUgTGV2aXRvIiwgIkNoYWV5ZW9uIEtpbSIsCiAgICAgICAgICAiTG9lbmEgSGVuZHJpY2t4IiwgIktpbW15IFJlcG9uZCIsICJMZWUgSGFlLUluIiwKICAgICAgICAgICJNb25lIENoaWJhIiwgIkhhbmEgWW9zaGlkYSIsICJMaXZpYSBLYWlzZXIiLCAiQW1iZXIgR2xlbm4iKQoKS3JhamluYSA8LSBjKCJKUE4iLCAiVVNBIiwgIktPUiIsICJCRUwiLCAiU1VJIiwgIktPUiIsICJKUE4iLCAiSlBOIiwgIlNVSSIsICJVU0EiKQoKQm9keSA8LSBjKDIyMi45NiwgMjEyLjE2LCAyMDMuNTksIDIwMC4yNSwgMTk2LjAyLCAxOTUuNDgsIDE5NS40NiwgMTk0LjkzLCAxODcuMjQsIDE4Ni41MykKCiMgVnl0dm9yZW5pZSBkYXRhIGZyYW1lCmtyYXNva29yY3VsaWFya3kgPC0gZGF0YS5mcmFtZShNZW5vLCBLcmFqaW5hLCBCb2R5KQoKIyBab2JyYXplbmllCnByaW50KGtyYXNva29yY3VsaWFya3kpCmBgYAoKVGlldG8gdHJpIHByZW1lbm7DqSBuaWUgc8O6IHphdGlhxL4gbmlqYWtvIHByZXBvamVuw6ksIHByZWRzdGF2dWrDuiBpem9sb3ZhbsOpCnN0xLpwY2UgdGFidcS+a3kuIERvIHRhYnXEvmt5IGljaCBzcG9qw61tZSBuYXNsZWRvdm5lCgpgYGB7cn0Ka3Jhc29rb3LEjXVsaWFya3kgPC0gZGF0YS5mcmFtZShNZW5vLEtyYWppbmEsQm9keSkKcHJpbnQoa3Jhc29rb3JjdWxpYXJreSkKYGBgCgpWeXN2ZXRsZW5pZTogRGF0YUZyYW1lIG3DoSB0cmkgc3TEunBjZTogTWVubywgS3JhamluYSBhIEJvZHkuIE5pZWt0b3LDqQpvcGVyw6FjaWUgcyDDumRham1pIG9yZ2FuaXpvdmFuw71taSB2IC5kYXRhLmZyYW1lLiBzw7ogdXZlZGVuw6kgbmFzbGVkb3ZuZQoKYGBge3J9CnByaW50KGtyYXNva29yY3VsaWFya3kkS3JhamluYSkgICAgICAgICAgICAgICAgICAgIyB2eXDDrcWhZSBuw6FtIHN0xLpwZWMgcyBrcmFqaW5hbWkKcHJpbnQobWVhbihrcmFzb2tvcmN1bGlhcmt5JEJvZHkpKSAgICAgICAgICAgICAgICAjIHByaWVtZXJuw70gcG/EjWV0IGJvZG92CnByaW50KGtyYXNva29yY3VsaWFya3lbTWVubz09Ikthb3JpIFNha2Ftb3RvIixdKSAgIyBhZHJlc292YW5pZSBjZWzDqWhvIHJpYWRrdSBwb2TEvmEgbWVuYQpwcmludChrcmFzb2tvcmN1bGlhcmt5WzNdKSAgICAgICAgICAgICAgICAgICAgICAgIyBpbmEgbW96bm9zdCBhZHJlc292YW5pYSBjZWxlaG8gcmlhZGt1CnByaW50KGtyYXNva29yY3VsaWFya3lbMjozXSkgICAgICAgICAgICAgICAgICAgICAjIHZ5cGlzYW5pZSBkcnVoZWhvIGEgdHJldGllaG8gc3RscGNhIHRhYnVsa3kKcHJpbnQoa3Jhc29rb3JjdWxpYXJreVsxLDFdKSAgICAgICAgICAgICAgICAgICAgICAjIHZ5cGlzYW5pZSBqZWRuZWogYnVua3kgdGFidWxreQpzdW1tYXJ5KGtyYXNva29yY3VsaWFya3kpICAgICAgICAgICAgICAgICAgICAgICAgICMgemFrbGFkbmEgZGVza3JpcHRpdm5hIHN0YXRpc3Rpa2EgY2VsZWogdGFidWxreQpgYGAKCkFrIGNoY2VtZSBwcmlkYcWlIGsgdGFidcS+a2UgZG9kYXRvxI1uw70gc3TEunBlYywgcG90b20gdG8gcm9iw61tZSBuYXNsZWRvdm5lOgoKYGBge3J9Ck1hTWVkYWlsdSA8LSBjKFRSVUUsVFJVRSxUUlVFLEZBTFNFLEZBTFNFLEZBTFNFLEZBTFNFLEZBTFNFLEZBTFNFLEZBTFNFKQprcmFzb2tvcmN1bGlhcmt5IDwtIGNiaW5kKGtyYXNva29yY3VsaWFya3ksTWFNZWRhaWx1KQpwcmludChrcmFzb2tvcmN1bGlhcmt5KQpgYGAKClByaWRhbGkgc21lIHN0bHBlYyBzIGluZm9ybcOhY2lvdSwga3RvcsOhIG7DoW0gaG92b3LDrSBvIHRvbSwgxI1pIHNpCnPDusWlYcW+aWFjYSB2eWJvam92YWxhIG1lZGFpbHUgYWxlYm8gbmllLiBBayBjaGNlbWUgcHJpZGHFpSByaWFkb2ssIHBvdG9tCgpgYGB7cn0KIyBOZXcgcmVjb3JkIChtdXN0IG1hdGNoIGNvbHVtbiBvcmRlci90eXBlcykKbm92eS5yaWFkb2sgPC0gZGF0YS5mcmFtZShNZW5vID0gIkFubmEgU2hjaGVyYmFrb3ZhIiwgS3JhamluYSA9ICJSVVMiLCBCb2R5ID0gMTg0LjUwLCBNYU1lZGFpbHUgPSBGQUxTRSkKCiMgQXBwZW5kCmtyYXNva29yY3VsaWFya3kgPC0gcmJpbmQoa3Jhc29rb3JjdWxpYXJreSwgbm92eS5yaWFkb2spCnByaW50KGtyYXNva29yY3VsaWFya3kpCmBgYAoKIyMjIFRhYnXEvmt5IHYgcHJvc3RyZWTDrSBrYWJsZWV4dHJhCmBgYHtyfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCgpNZW5vIDwtIGMoIkthb3JpIFNha2Ftb3RvIiwgIklzYWJlYXUgTGV2aXRvIiwgIkNoYWV5ZW9uIEtpbSIsCiAgICAgICAgICAiTG9lbmEgSGVuZHJpY2t4IiwgIktpbW15IFJlcG9uZCIsICJMZWUgSGFlLUluIiwKICAgICAgICAgICJNb25lIENoaWJhIiwgIkhhbmEgWW9zaGlkYSIsICJMaXZpYSBLYWlzZXIiLCAiQW1iZXIgR2xlbm4iKQoKS3JhamluYSA8LSBjKCJKUE4iLCAiVVNBIiwgIktPUiIsICJCRUwiLCAiU1VJIiwgIktPUiIsICJKUE4iLCAiSlBOIiwgIlNVSSIsICJVU0EiKQoKQm9keSA8LSBjKDIyMi45NiwgMjEyLjE2LCAyMDMuNTksIDIwMC4yNSwgMTk2LjAyLCAxOTUuNDgsIDE5NS40NiwgMTk0LjkzLCAxODcuMjQsIDE4Ni41MykKCk1hTWVkYWlsdSA8LSBjKFRSVUUsIFRSVUUsIFRSVUUsIEZBTFNFLCBGQUxTRSwgRkFMU0UsIEZBTFNFLCBGQUxTRSwgRkFMU0UsIEZBTFNFKQoKa3Jhc29rb3JjdWxpYXJreSA8LSBkYXRhLmZyYW1lKE1lbm8sIEtyYWppbmEsIEJvZHksIE1hTWVkYWlsdSkKCmthYmxlKAogIGtyYXNva29yY3VsaWFya3ksCiAgZGlnaXRzID0gMiwKICBhbGlnbiA9IGMoImwiLCJjIiwiciIsImMiKSwKICBjYXB0aW9uID0gIktvbmXEjW7DqSB2w71zbGVka3kgTVMgMjAyNCB2IGtyYXNva29yxI11xL5vdmFuw60gxb5pZW4iCikgJT4lCiAga2FibGVfc3R5bGluZygKICAgIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiLCAicmVzcG9uc2l2ZSIpLAogICAgZnVsbF93aWR0aCA9IEZBTFNFLAogICAgcG9zaXRpb24gPSAiY2VudGVyIgogICkKYGBgCgojIyBUaWR5dmVyc2UgLSBtb2Rlcm7DoSBwcsOhY2EgcyDDumRham1pCgpUaWR5dmVyc2UgamUgc8O6Ym9yIGtuacW+bsOtYywga3RvcsOpIG1hasO6IHpqZWRub2R1xaFpxaUgcHLDoWN1IHMgw7pkYWptaS4gTWFqw7oKamVkbm90bsO9IGtvbXVuaWthxI1uw70gxaF0YW5kYXJkLCB2esOham9tbmUgc2EgZG9wbMWIdWrDui4KCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgTG9hZCB0aWR5dmVyc2UKbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKIyMjIGRwbHlyIC0gcHJlIG1hbmlwdWzDoWNpdSBzIMO6ZGFqbWkKCi5kcGx5ci4gcG9za3l0dWplIHrDoWtsYWRuw6kgbW/Fvm5vc3RpIG1hbmlwdWzDoWNpZSBzIMO6ZGFqbWksIGFrbyBuYXByLjoKCjEuICBmaWx0ZXIoKTogdnliZXLDoSByaWFka3kKCjIuICBzZWxlY3QoKTogdnliZXLDoSBzdMS6cGNlCgozLiAgbXV0YXRlKCk6IHZ5dHbDoXJhIG5vdsOpIHN0xLpwY2UgdGFidcS+a3kKCjQuICBhcnJhbmdlKCk6IHRyaWVkaSByaWFka3kKCjUuICBzdW1tYXJpc2UoKTogc3VtYXJpenVqZQoKViBuYXNsZWRvdm5laiB1a8Ohxb5rZSB2eXXFvmlqZW1lIHR6di4gLnBpcGVzLiAlXD4lIGFsZWJvICVcPCUgdW1vxb7FiHVqZQpwb3NpZWxhxaUgdsO9c2xlZGt5IHogamVkbmVqIGZ1bmtjaWUgcHJpYW1vIGRvIHZvbGFuaWUgbmFzbGVkb3ZuZWoKZnVua2NpZS4gVG8gdW1vxb7FiHVqZSDEvmFoxaFpdSDEjWl0YXRlxL5ub3PFpSBrw7Nkb3YsIGtvbnZlbmNpYSBzYSB1amFsYSBhIG3DoQrFoWlyb2vDqSBwb3XFvml0aWUuCgojIyMjIFbDvWJlciBhIHRyaWVkZW5pZQoKYGBge3J9CiMgdsO9YmVyIGEgbsOhc2xlZG7DqSB0cmllZGVuaWUKa3Jhc29rb3JjdWxpYXJreSAlPiUKICBmaWx0ZXIoQm9keSA+IDIwMCkgJT4lICAgICAjIHZ5YmVyYSB6YXpuYW15IHMgcG9jdG9tIGJvZG92IHZpYWMsIGFrbyAyMDAKICBhcnJhbmdlKGRlc2MoQm9keSkpICU+JSAgICAgIyB2eXNsZWRueSBzdWJvciB0cmllZGkgem9zdHVwbmUgcG9kbGEgcHJlbWVubmVqIEJvZHkKa2FibGUgJT4lCiAgICBrYWJsZV9zdHlsaW5nKAogICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIiksCiAgICBmdWxsX3dpZHRoID0gRkFMU0UsCiAgICBwb3NpdGlvbiA9ICJjZW50ZXIiCiAgKQpgYGAKCiMjIyMgWm9za3VwZW5pZSBhIHN1bWFyaXrDoWNpYQoKYGBge3J9CiMgWm9za3Vww60gYW5kIHN1bWFyaXp1amUKa3Jhc29rb3JjdWxpYXJreSAlPiUKICBncm91cF9ieShLcmFqaW5hKSAlPiUgICAgICAjIHpvc2t1cGkgemF6bmFteSBwb2RsYSBwcmVtZW5uZWogTWFBdXRvIGEgdnlwb2NpdGEgemEga2F6ZHUgc2t1cGludSBqZWogcHJpZW1lciBCb2R5CiAgc3VtbWFyaXNlKCAgICAgICAgICAgICAgICAjIGEgdGFrdGlleiBzcG9jaXRhIHBvY2V0bm9zdGkgb2JvY2ggc2t1cGluCiAgICBQcmllbS5Cb2R5ID0gbWVhbihCb2R5KSwKICAgIGNvdW50ID0gbigpCiAgKSAlPiUKIGthYmxlKAogICAgY2FwdGlvbiA9ICJQcmllbWVybsOpIEJvZHkgcG9kxL5hIHByZW1lbm5laiBLcmFqaW5hIiwKICAgIGNvbC5uYW1lcyA9IGMoIktyYWppbmEiLCAiUHJpZW1lciBCb2R5IiwgIlBvxI1ldCIpLAogICAgYWxpZ24gPSAiYyIKICApICU+JQogIGthYmxlX3N0eWxpbmcoCiAgICBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIiwgInJlc3BvbnNpdmUiKSwKICAgIGZ1bGxfd2lkdGggPSBGQUxTRSwKICAgIHBvc2l0aW9uID0gImNlbnRlciIKICApCmBgYAoKIyMjIyBWeXR2w6FyYW5pZSBub3ZlaiBwcmVtZW5uZWoKCmBgYHtyfQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCgojIFByaWRhbmllIGdyYWRlIGEgQ2xvc2VUb01lZGFsCmtyYXNva29yY3VsaWFya3kgJT4lCiAgbXV0YXRlKAogICAgZ3JhZGUgPSBjYXNlX3doZW4oCiAgICAgIEJvZHkgPj0gMjIwIH4gIkEiLAogICAgICBCb2R5ID49IDIwMCB+ICJCIiwKICAgICAgQm9keSA+PSAxOTAgfiAiQyIsCiAgICAgIFRSVUUgfiAiRCIKICAgICksCiAgICBDbG9zZVRvTWVkYWwgPSBCb2R5ID49IDIwMCAmIEJvZHkgPCAyMDMuNTkgICMgVFJVRSBwcmUgYm9keSB0ZXNuZSBtaW1vIHRvcCAzIMSNacW+ZSBibMOtemtvIGt1IG1lZGFpbGUKICApICU+JQogIGthYmxlKCkgJT4lCiAga2FibGVfc3R5bGluZygKICAgIGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiLCAicmVzcG9uc2l2ZSIpLAogICAgZnVsbF93aWR0aCA9IEZBTFNFLAogICAgcG9zaXRpb24gPSAiY2VudGVyIgogICkgCmBgYAo=