knitr::opts_chunk$set(
echo = TRUE,
message = FALSE,
warning = FALSE
)
install.packages(c(
"tidyverse",
"readr",
"dplyr",
"ggplot2",
"knitr",
"kableExtra",
"broom",
"stringr",
"corrplot",
"zoo",
"tseries",
"lmtest",
"sandwich",
"car",
"corrplot",
"patchwork"
), dependencies = TRUE)
library(zoo)
library(tseries)
library(lmtest)
library(sandwich)
library(car)
rm(list=ls())
Úvod do problému, stanovenie hypotéz
V tejto úlohe pracujeme s databázou Indian Water
Data, ktorá obsahuje údaje o kvalite vody na rôznych lokalitách
v Indii.
Cieľom je:
- preskúmať štatistické vlastnosti jednotlivých ukazovateľov kvality
vody,
- analyzovať vzťahy medzi nimi,
- a pomocou lineárnej regresie vysvetliť, ktoré
faktory ovplyvňujú napríklad pH vody.
V tejto úlohe predpokladáme, že pH vody je
ovplyvňované viacerými faktormi kvality vody.
Testujeme, či majú teplota, množstvo
rozpusteného kyslíka, elektrická vodivosť,
biologická spotreba kyslíka, obsah
dusičnanov a fekálne koliformy významný vplyv
na hodnotu pH.
Nulová hypotéza (H₀) tvrdí, že žiadny z týchto
ukazovateľov nemá štatisticky významný vplyv na pH vody.
Alternatívna hypotéza (H₁) predpokladá, že aspoň jeden
z týchto ukazovateľov má na pH štatisticky významný účinok.
library(dplyr)
library(tidyverse)
library(kableExtra)
library(corrplot)
data <- read.csv("Indian_water_data.csv")
str(data)
summary(data)
# Doplnenie chýbajúcich hodnôt mediánom
column_medians <- sapply(data, median, na.rm = TRUE)
for (col in names(data)) {
if (is.numeric(data[[col]])) {
data[[col]][is.na(data[[col]])] <- column_medians[col]
}
}
# Vyber číselné premenné
data_num <- data %>% select(where(is.numeric))
# Základné štatistiky
data_num %>%
summary() %>%
kable(caption = "Základné štatistiky numerických premenných") %>%
kable_styling(full_width = FALSE)
# Vizualizácia dát
library(ggplot2)
library(tidyr)
library(dplyr)
library(scales)
# Prevedieme dáta do long formátu
data_long <- data_num %>%
pivot_longer(cols = everything(), names_to = "Premenná", values_to = "Hodnota")
# Normalizácia každej premennej (0–1 rozsah)
data_scaled <- data_long %>%
group_by(Premenná) %>%
mutate(Hodnota_scaled = (Hodnota - min(Hodnota, na.rm = TRUE)) /
(max(Hodnota, na.rm = TRUE) - min(Hodnota, na.rm = TRUE))) %>%
ungroup()
# Boxplot po škálovaní
ggplot(data_scaled, aes(x = Premenná, y = Hodnota_scaled, fill = Premenná)) +
geom_boxplot(outlier.color = "red", notch = TRUE, alpha = 0.7) +
theme_minimal(base_size = 16) +
theme(
axis.text.x = element_text(angle = 45, hjust = 1, size = 12),
legend.position = "none"
) +
labs(
title = "Boxploty jednotlivých numerických premenných (štandardizované)",
x = "",
y = "Škálovaná hodnota (0–1)"
)
Interpretácia boxplotov jednotlivých numerických premenných
Boxploty ukazujú rozdelenie hodnôt jednotlivých premenných po
štandardizácii (v rozsahu 0–1).
Z grafu vidno niekoľko dôležitých poznatkov:
Premenné Conductivity...µmho.cm....Max a
BOD..mg.L....Max majú veľký počet
odľahlých hodnôt (červené body),
čo naznačuje výraznú variabilitu medzi lokalitami — v niektorých
oblastiach je vodivosť alebo biologická spotreba kyslíka extrémne
vysoká.
pH...Min a pH...Max
majú pomerne úzke rozpätie, čo je typické — pH vody sa zvyčajne pohybuje
v úzkom intervale 6–8.
Temperature..C....Max a
Temperature..C....Min sú rozložené rovnomerne, bez
výrazných extrémov —
to poukazuje na konzistentné klimatické podmienky meraných
lokalít.
Total.Coliform..MPN.100ml....Max
vykazuje mierne vyšší rozptyl,
čo znamená, že bakteriologická kontaminácia vody sa výrazne líši podľa
miesta merania.
Year a STN.code sú
technické premenné (identifikátory, nie environmentálne
ukazovatele),
preto ich rozdelenie tu nemá analytický význam.
# Korelačná matica
corr <- cor(data_num, use = "complete.obs")
corrplot(corr, method = "color", type = "upper", tl.cex = 0.7)
Interpretácia korelačnej matice
Korelačná analýza naznačuje, že najvyššia korelácia s
pH...Max je pozorovaná pri ukazovateľoch
rozpusteného kyslíka (Dissolved...Max) a
vodivosti
(Conductivity...µmho.cm....Max).
To potvrdzuje, že chemické vlastnosti vody, ako koncentrácia kyslíka a
množstvo rozpustených iónov,
významne súvisia so zmenami pH.
Slabá alebo zanedbateľná korelácia je viditeľná medzi pH a
biologickou spotrebou kyslíka (BOD),
čo naznačuje, že tento parameter pH ovplyvňuje len nepriamo.
Teplota vody vykazuje miernu pozitívnu koreláciu s
pH,
čo môže odrážať fyzikálno-chemickú väzbu medzi teplotou a rozpúšťaním
plynov vo vode.
Lineárna regresia
Predpokladajme, že maximálna hodnota pH vody je závislá premenná a
ostatné chemické a biologické ukazovatele kvality vody, ako sú teplota,
obsah rozpusteného kyslíka, vodivosť, biologická spotreba kyslíka, obsah
dusičnanov a fekálnych koliformov, predstavujú nezávislé premenné.
# Najprv premeň prázdne bunky alebo texty ako "BDL" na NA
data$Fecal.Coliform..MPN.100ml....Max[data$Fecal.Coliform..MPN.100ml....Max %in% c("", "BDL", "NA")] <- NA
# Potom prevedieš na čísla
data$Fecal.Coliform..MPN.100ml....Max <- as.numeric(data$Fecal.Coliform..MPN.100ml....Max)
# Lineárny model – pH...Max ako závislá premenná
model <- lm(pH...Max ~ Temperature..C....Max + Dissolved...Max + Conductivity...µmho.cm....Max +
BOD..mg.L....Max + NitrateN..mg.L....Max + Fecal.Coliform..MPN.100ml....Max,
data = data)
# Výstupy modelu
cat("Odhadnuté koeficienty modelu:\n")
print(model$coefficients)
cat("Odhadnuté rezíduá (zvyšky):\n")
print(head(model$residuals, 10)) # len prvých 10 prehľadne
cat("Vyrovnané (predikované) hodnoty závislej premennej:\n")
print(head(model$fitted.values, 10)) # opäť len prvých 10
cat("Matica modelu (X):\n")
X <- model.matrix(model)
print(head(X))
cat("Projekčná matica (hat matrix):\n")
H <- X %*% solve(t(X) %*% X) %*% t(X)
print(round(H[1:5, 1:5], 4)) # len prvých 5x5 prvkov pre prehľadnosť
cat("Súhrn modelu:\n")
summary(model)
Interpretácia a diagnostika modelu
Súhrn odhadovaného modelu nám poskytuje súbor odhadnutých regresných
koeficientov, ktorých znamienka a významnosť budú interpretované
nižšie.
Ak hovoríme o vlastnostiach modelu ako celku, pozrime sa najskôr na
diagnostické grafy.
# Nastaviť rozloženie 2 x 2
par(mfrow = c(2, 2))
# Vykresliť všetky 4 diagnostické grafy modelu
plot(model)
# Pridať spoločný nadpis
mtext("Diagnostické grafy regresného modelu – pH...Max",
outer = TRUE, cex = 1.2, font = 2)
# Resetovať layout
par(mfrow = c(1, 1))
Interpretácia diagnostických grafov pre model pH…Max
Residuals vs. Fitted
- Rezíduá sa pohybujú približne okolo nulovej osi – model teda
nemá systematické skreslenie v predikcii hodnôt
pH.
- Červená LOESS čiara je relatívne rovná, čo naznačuje, že
vzťah medzi pH a zvolenými premennými (napr. teplota,
vodivosť, BOD, dusičnany) je prevažne lineárny.
- Vertikálny rozptyl je približne rovnomerný → predpoklad
homoskedasticity (konštantného rozptylu chýb) je v
zásade splnený.
- Niekoľko bodov mimo hlavný rozptyl môže predstavovať
lokality s extrémnymi hodnotami kvality vody
(potenciálne odľahlé pozorovania), ktoré si overíme pomocou testov.
Q–Q plot
- Väčšina bodov leží pozdĺž diagonály → rezíduá modelu pH…Max sú
takmer normálne rozložené.
- Na koncoch (vľavo dole a vpravo hore) možno pozorovať mierne
odchýlky – to naznačuje ťažšie chvosty rozdelenia,
pravdepodobne spôsobené extrémnymi hodnotami niektorých chemických
ukazovateľov.
- Stredná časť grafu je dobre zarovnaná, čo potvrdzuje, že
väčšina pozorovaní sa správa normálne.
Scale–Location plot
- Body sú rozptýlené rovnomerne po osi X bez vytvárania lievika →
rozptyl rezíduí je približne konštantný.
- Hladká LOESS čiara je takmer vodorovná, čo naznačuje, že
variabilita chýb sa nemení so zmenou predikovaných hodnôt
pH.
- Tento výsledok podporuje platnosť predpokladu o
homoskedasticite modelu.
Residuals vs. Leverage
- Väčšina bodov má nízky vplyv (Cookova vzdialenosť < 0.5) → žiadne
pozorovanie neovplyvňuje regresné koeficienty
výrazne.
- Jeden alebo dva body môžu mať zvýšenú pákovú hodnotu – ide
pravdepodobne o lokality s extrémne odlišnými parametrami
vody, ktoré však model výrazne nedeformujú.
- Celkovo pôsobí model stabilne a bez významných odľahlých
alebo vplyvných bodov.
Zhrnutie
Diagnostické grafy potvrdzujú, že model s vysvetľovanou premennou
pH…Max a prediktormi
(Temperature..C….Max, Dissolved…Max,
Conductivity…µmho.cm….Max,
BOD..mg.L….Max, NitrateN..mg.L….Max a
Fecal.Coliform..MPN.100ml….Max)
spĺňa hlavné predpoklady lineárnej regresie.
Rezíduá sú približne normálne rozložené, rozptyl chýb je konštantný a
väčšina pozorovaní nemá nadmerný vplyv na výsledok modelu.
Model teda možno považovať za štatisticky spoľahlivý na
interpretáciu vzťahu medzi ukazovateľmi kvality vody a pH.
# Nový model so zlogaritmovanou Conductivity
model2 <- lm(pH...Max ~ Temperature..C....Max + Dissolved...Max +
I(log(Conductivity...µmho.cm....Max)) +
BOD..mg.L....Max + NitrateN..mg.L....Max,
data = data)
summary(model2)
par(mfrow = c(2, 2))
plot(model2)
par(mfrow = c(1, 1))
Transformácia premennej Conductivity...µmho.cm....Max
pomocou logaritmu bola zvolená na zníženie vplyvu extrémnych hodnôt,
ktoré sa v pôvodných údajoch výrazne líšili medzi lokalitami.
Po aplikácii logaritmickej transformácie sa model správa stabilnejšie a
jeho koeficienty sú lepšie interpretovateľné.
Interpretácia diagnostických grafov pre model so zlogaritmovanou
vodivosťou
Residuals vs Fitted
Rezíduá sa pohybujú rovnomerne okolo nulovej osi, čo
naznačuje, že model nemá systematické skreslenie v
predikcii hodnôt pH.
Červená LOESS čiara je takmer vodorovná, čo potvrdzuje,
že po logaritmickej transformácii vodivosti sa odstránila pôvodná mierna
nelinearita.
Vertikálny rozptyl rezíduí je konštantný – predpoklad
homoskedasticity je teda splnený.
Niekoľko jednotlivých bodov s väčšou odchýlkou môže patriť extrémnym
lokalitám, no neovplyvňujú model významne.
Q–Q plot
Väčšina bodov leží veľmi blízko diagonály, čo
znamená, že rezíduá sú približne normálne
rozložené.
Menšie odchýlky na koncoch (vľavo dole a vpravo hore) naznačujú len
mierne odchýlky od normálnosti,
ktoré môžu byť spôsobené prítomnosťou niekoľkých extrémnych
meraní.
Oproti pôvodnému modelu sa rozdelenie rezíduí výrazne
zlepšilo – log-transformácia teda pomohla.
Scale–Location plot
Body sú rozptýlené rovnomerne pozdĺž osi X bez
známok rozširujúceho sa „lievika“,
čo potvrdzuje, že variancia rezíduí je konštantná
naprieč predikovanými hodnotami.
Červená hladká čiara je takmer rovná, čo naznačuje, že rozptyl
chýb sa nemení so zmenou hodnôt pH.
Model teda spĺňa predpoklad homoskedasticity veľmi
dobre.
Residuals vs Leverage
Väčšina pozorovaní má nízky pákový efekt (leverage
< 0.1) a Cookova vzdialenosť zostáva pod 0.5.
To znamená, že žiadne pozorovanie neovplyvňuje model
nadmerne.
Niekoľko bodov (napr. 191, 66) vykazuje mierne vyšší vplyv, ale
nepresahuje kritické hodnoty.
Model teda neobsahuje výrazne vplyvné alebo odľahlé
prípady.
Zhrnutie diagnostiky
Transformovaný model (so zlogaritmovanou vodivosťou) výrazne
zlepšil štatistické vlastnosti rezíduí: - odstránil miernu
nelinearitu z pôvodného modelu,
- znížil heteroskedasticitu,
- a priblížil rozdelenie rezíduí k normálnemu tvaru.
Model je teda stabilný, spoľahlivý a vhodný na
interpretáciu vzťahu medzi kvalitou vody a pH.
Testy normality a identifikácia odľahlých hodnôt
V tejto časti overíme, či rezíduá pôvodného modelu spĺňajú predpoklad
normality rozdelenia
a zároveň identifikujeme možné odľahlé pozorovania,
ktoré by mohli ovplyvňovať výsledky.
jarque.bera.test(residuals(model))
car::outlierTest(model)
Záver
Na základe regresnej analýzy možno konštatovať, že maximálne pH vody
(pH…Max)
je ovplyvnené viacerými faktormi kvality vody.
Premenné teplota vody, rozpustený
kyslík a vodivosť majú prevažne
pozitívny vplyv,
kým biologická spotreba kyslíka a fekálne
koliformy pH znížujú.
Transformácia premennej Conductivity...µmho.cm....Max
pomocou logaritmu
zlepšila štatistické vlastnosti modelu — rezíduá sú bližšie k normálnemu
rozdeleniu
a rozptyl chýb je stabilnejší (homoskedasticita).
Model je teda vo všeobecnosti spoľahlivejší a lepšie
spĺňa predpoklady lineárnej regresie.
Napriek tomu však testy odľahlých hodnôt ukázali, že
pozorovanie č. 191
zostáva odľahlé aj po transformácii.
Ide teda o extrémne meranie, ktoré má potenciál
ovplyvniť výsledky modelu —
v budúcnosti by bolo vhodné toto pozorovanie osobitne preskúmať
(napr. či nejde o chybu merania alebo špecifickú lokalitu s výrazne
odlišnými podmienkami).
Celkovo možno uzavrieť, že transformovaný model lepšie
vystihuje vzťahy medzi ukazovateľmi kvality vody a pH,
no prítomnosť jedného trvalého odľahlého pozorovania (č.
191)
je potrebné mať na pamäti pri interpretácii výsledkov.
Heteroskedasticita
Prítomnosť heteroskedasticity (nekonštantného
rozptylu náhodnej zložky) spôsobuje chybné vyhodnocovanie t-testov
významnosti jednotlivých regresných koeficientov.
Preto je nutné heteroskedasticitu:
- detekovať (vizuálne a pomocou testov),
- a v prípade jej prítomnosti ju odstrániť alebo
kompenzovať.
Aj v našom prípade sa pokúsime o vizuálne vyhodnotenie závislosti
štvorcov rezíduí od vysvetľujúcich premenných, u ktorých máme
podozrenie, že môžu heteroskedasticitu spôsobovať.
Budeme posudzovať dva modely: - model – pôvodný model, -
model2 – model so zlogaritmovanou
vodivosťou (Conductivity...µmho.cm....Max),
ktorého cieľom bolo znížiť vplyv extrémnych hodnôt.
# Heteroskedasticita – lokálne bez riadku 191 (globálne 'data' nemeníme)
library(ggplot2)
library(patchwork)
# 1) Lokálna kópia a vyhodenie 191. riadku
data_h <- data
if (nrow(data_h) >= 191) {
data_h <- data_h[-191, , drop = FALSE]
}
# 2) Refit modelov na data_h
model_h <- lm(
pH...Max ~ Temperature..C....Max + Dissolved...Max +
Conductivity...µmho.cm....Max + BOD..mg.L....Max +
NitrateN..mg.L....Max + Fecal.Coliform..MPN.100ml....Max,
data = data_h, na.action = na.exclude
)
model2_h <- lm(
pH...Max ~ Temperature..C....Max + Dissolved...Max +
I(log(Conductivity...µmho.cm....Max)) +
BOD..mg.L....Max + NitrateN..mg.L....Max,
data = data_h, na.action = na.exclude
)
# 3) Dáta použité v modeloch (len riadky, ktoré model skutočne použil)
df_model <- as.data.frame(model.frame(model_h))
df_model2 <- as.data.frame(model.frame(model2_h))
# --- ZAROVNANIE REZÍDUÍ PODĽA MIEN RIADKOV (kritické) ---
r1 <- residuals(model_h)
df_model$Residuals <- as.numeric(r1[match(rownames(df_model), names(r1))])
r2 <- residuals(model2_h)
df_model2$Residuals <- as.numeric(r2[match(rownames(df_model2), names(r2))])
# 4) Grafy – pôvodný model (analóg GDP/Schooling)
p1 <- ggplot(df_model, aes(x = `Conductivity...µmho.cm....Max`, y = Residuals^2)) +
geom_point(alpha = 0.6, color = "steelblue") +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "Vodivosť (µmho/cm)",
y = "Štvorce rezíduí",
title = "Štvorce rezíduí vs Vodivosť") +
theme_minimal()
p2 <- ggplot(df_model, aes(x = `Temperature..C....Max`, y = Residuals^2)) +
geom_point(alpha = 0.6, color = "steelblue") +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "Teplota (°C)",
y = "Štvorce rezíduí",
title = "Štvorce rezíduí vs Teplota") +
theme_minimal()
p1 + p2

a teraz transformovaný model
# doplň surovú vodivosť (a pre istotu aj teplotu) do df_model2 podľa rovnakých riadkov
idx2 <- as.integer(rownames(df_model2))
df_model2$Conductivity <- data_h$`Conductivity...µmho.cm....Max`[idx2]
df_model2$Temperature <- data_h$`Temperature..C....Max`[idx2]
# 5) Grafy – transformovaný model (log vodivosti)
p3 <- ggplot(df_model2, aes(x = log(Conductivity), y = Residuals^2)) +
geom_point(alpha = 0.6, color = "darkgreen") +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "log(Vodivosť)",
y = "Štvorce rezíduí",
title = "Štvorce rezíduí vs log(Vodivosť)") +
theme_minimal()
p4 <- ggplot(df_model2, aes(x = Temperature, y = Residuals^2)) +
geom_point(alpha = 0.6, color = "darkgreen") +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "Teplota (°C)",
y = "Štvorce rezíduí",
title = "Štvorce rezíduí vs Teplota") +
theme_minimal()
p3 + p4

Na tomto obrázku podľa vyhladených hodnôt štvorcov rezíduí (červená
krivka) môžeme konštatovať, že po logaritmickej transformácii vodivosti
log(Vodivosť) (pravý panel prvého riadku) krivka
nevykazuje systematický trend s vysvetľujúcou premennou a variancia chýb
je približne konštantná. Podobne pri Teplote vidíme iba
mierny lokálny „hrbol“ okolo 25–33 °C, ktorý však nepredstavuje výrazný
rast variability.
Kvôli demonštrácii ale ukážme, že bez predchádzajúcej logaritmickej
transformácie by to dopadlo inak. V pôvodnom modeli (ľavý panel prvého
riadku) je červená krivka pri Vodivosti mierne
klesajúca – naznačuje to slabú heteroskedasticitu
(väčší rozptyl chýb pri nižšej vodivosti), ktorá sa po prechode na
log(Vodivosť) vytráca a krivka sa výrazne
splošťuje.
Zhrnutie: Transformácia
log(Vodivosť) zjavne stabilizuje rozptyl a vizuálne
nevidíme významný vývoj štvorcov rezíduí s vysvetľujúcimi premennými.
Pre úplnosť je vhodné tento dojem potvrdiť formálnym testom (napr.
Breusch–Pagan/Koenker–Bassett) a reportovať inferenciu
s robustnými (HC1) chybami.
Testovanie prítomnosti heteroskedasticity
Najprv otestujeme prítomnosť heteroskedasticity pomocou
Breusch–Pagan testu (študentizovaná verzia =
Koenker–Bassett).
Následne – ak by heteroskedasticita pretrvávala – reportujeme odhady s
White/HC-robustnými smerodajnými chybami (typ
HC1).
m1 <- if (exists("model_h")) model_h else if (exists("model")) model else stop("Model m1 neexistuje.")
m2 <- if (exists("model2_h")) model2_h else if (exists("model2")) model2 else stop("Model m2 neexistuje.")
library(lmtest)
#Breusch–Pagan (Koenker–Bassett) pre oba modely
bp_m1 <- bptest(m1, studentize = TRUE)
bp_m2 <- bptest(m2, studentize = TRUE)
bp_m1
studentized Breusch-Pagan test
data: m1
BP = 13.349, df = 6, p-value = 0.03782
studentized Breusch-Pagan test
data: m2
BP = 10.227, df = 5, p-value = 0.06904
Na základe výsledkov regresie môžeme povedať, že
heteroskedasticita rezíduí nie je v modeli m2
prítomná, zatiaľ čo v prípade modelu m1
prítomná je. Ak by však heteroskedasticita pretrvávala a
logaritmizácia premenných alebo odstránenie
odľahlých hodnôt nepomohli, môžeme ju ošetriť pomocou tzv.
White heteroskedasticity-consistent matice (HC), kde sa
v t-testoch významnosti regresných koeficientov používajú
„hrubšie“ (robustné) odhady rozptylov. Postup je potom založený na
odhadoch s HC1/HC3 štandardnými chybami.
Výsledky BP (Koenker–Bassett) testu:
- m1: \(p = 0.0378 <
0.05\) → zamietame H₀ na 5 % hladine. V pôvodnom
modeli sú dôkazy heteroskedasticity.
- m2: \(p = 0.0690 >
0.05\) (ale \(<
0.10\)) → na 5 % hladine H₀ nezamietame, na 10 %
je to hraničné. Log-transformácia
vodivosti teda heteroskedasticitu
znížila.
# Robustné (heteroskedasticity-consistent) chyby – HC1
library(sandwich)
cat("\nRobustné (HC1) t-testy koeficientov – m1:\n")
Robustné (HC1) t-testy koeficientov – m1:
coeftest(m1, vcov = vcovHC(m1, type = "HC1"))
t test of coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 7.7614e+00 2.1608e-01 35.9199 < 2.2e-16
Temperature..C....Max -1.2691e-02 3.3629e-03 -3.7739 0.000221
Dissolved...Max 5.7580e-02 2.1286e-02 2.7051 0.007516
Conductivity...µmho.cm....Max 5.2391e-06 1.0837e-06 4.8345 2.945e-06
BOD..mg.L....Max 7.0291e-04 2.5874e-03 0.2717 0.786204
NitrateN..mg.L....Max 3.2757e-02 1.0526e-02 3.1120 0.002176
Fecal.Coliform..MPN.100ml....Max 1.4505e-08 8.2354e-09 1.7614 0.079955
(Intercept) ***
Temperature..C....Max ***
Dissolved...Max **
Conductivity...µmho.cm....Max ***
BOD..mg.L....Max
NitrateN..mg.L....Max **
Fecal.Coliform..MPN.100ml....Max .
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Všimnime si, že po použití robustných (HC)
smerodajných chýb vychádzajú ako štatisticky významne spojené s pH…Max
najmä premenné Teplota (–), Rozpustený O₂
(+), Vodivosť (+) a NitrateN
(+). Premenná BOD štatisticky významná nie je
a Fekálne koliformy sú len hranične
významné (≈ 10 % hladina). To je v súlade s tým, že robustné
chyby „sprísnia“ inferenciu v prítomnosti heteroskedasticity. Na druhej
strane treba podotknúť, že použitie tejto metódy je najspoľahlivejšie
pri väčších výberoch (orientačne > 100
pozorovaní).
LS0tCnRpdGxlOiAiQ3ZpxI1lbmllIDUg4oCTIFByw6FjYSBzIGRhdGFiw6F6b3UgKEluZGlhbiBXYXRlciBEYXRhKSIKYXV0aG9yOiAiU8OhcmEgTmlrb2wgU2Nob2x0em92w6EiCmRhdGU6ICJPa3TDs2JlciAyMDI1IgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0aGVtZTogdW5pdGVkCiAgICBoaWdobGlnaHQ6IHRhbmdvCmVkaXRvcl9vcHRpb25zOgogIG1hcmtkb3duOgogICAgd3JhcDogNzIKLS0tCmBgYHtyfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgICBlY2hvID0gVFJVRSwKICAgIG1lc3NhZ2UgPSBGQUxTRSwKICAgIHdhcm5pbmcgPSBGQUxTRQopCmBgYAoKYGBge3J9Cmluc3RhbGwucGFja2FnZXMoYygKICAidGlkeXZlcnNlIiwKICAicmVhZHIiLAogICJkcGx5ciIsCiAgImdncGxvdDIiLAogICJrbml0ciIsCiAgImthYmxlRXh0cmEiLAogICJicm9vbSIsCiAgInN0cmluZ3IiLAogICJjb3JycGxvdCIsCiAgInpvbyIsCiAgInRzZXJpZXMiLAogICJsbXRlc3QiLAogICJzYW5kd2ljaCIsCiAgImNhciIsCiAgImNvcnJwbG90IiwKICAicGF0Y2h3b3JrIgopLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQpsaWJyYXJ5KHpvbykKbGlicmFyeSh0c2VyaWVzKQpsaWJyYXJ5KGxtdGVzdCkKbGlicmFyeShzYW5kd2ljaCkKbGlicmFyeShjYXIpCnJtKGxpc3Q9bHMoKSkKYGBgCgojIMOadm9kIGRvIHByb2Jsw6ltdSwgc3Rhbm92ZW5pZSBoeXBvdMOpeiAKClYgdGVqdG8gw7psb2hlIHByYWN1amVtZSBzIGRhdGFiw6F6b3UgKipJbmRpYW4gV2F0ZXIgRGF0YSoqLCBrdG9yw6Egb2JzYWh1amUgw7pkYWplIG8ga3ZhbGl0ZSB2b2R5IG5hIHLDtHpueWNoIGxva2FsaXTDoWNoIHYgSW5kaWkuICAKQ2llxL5vbSBqZToKCi0gcHJlc2vDum1hxaUgxaF0YXRpc3RpY2vDqSB2bGFzdG5vc3RpIGplZG5vdGxpdsO9Y2ggdWthem92YXRlxL5vdiBrdmFsaXR5IHZvZHksICAKLSBhbmFseXpvdmHFpSB2esWlYWh5IG1lZHppIG5pbWksICAKLSBhIHBvbW9jb3UgKipsaW5lw6FybmVqIHJlZ3Jlc2llKiogdnlzdmV0bGnFpSwga3RvcsOpIGZha3Rvcnkgb3ZwbHl2xYh1asO6IG5hcHLDrWtsYWQgKnBIIHZvZHkqLgoKLS0tCgpWIHRlanRvIMO6bG9oZSBwcmVkcG9rbGFkw6FtZSwgxb5lICoqcEggdm9keSoqIGplIG92cGx5dsWIb3ZhbsOpIHZpYWNlcsO9bWkgZmFrdG9ybWkga3ZhbGl0eSB2b2R5LiAgClRlc3R1amVtZSwgxI1pIG1hasO6ICoqdGVwbG90YSoqLCAqKm1ub8W+c3R2byByb3pwdXN0ZW7DqWhvIGt5c2zDrWthKiosICoqZWxla3RyaWNrw6Egdm9kaXZvc8WlKiosICoqYmlvbG9naWNrw6Egc3BvdHJlYmEga3lzbMOta2EqKiwgKipvYnNhaCBkdXNpxI1uYW5vdioqIGEgKipmZWvDoWxuZSBrb2xpZm9ybXkqKiB2w716bmFtbsO9IHZwbHl2IG5hIGhvZG5vdHUgcEguCgoqKk51bG92w6EgaHlwb3TDqXphIChI4oKAKSoqIHR2cmTDrSwgxb5lIMW+aWFkbnkgeiB0w71jaHRvIHVrYXpvdmF0ZcS+b3YgbmVtw6EgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gdnBseXYgbmEgcEggdm9keS4gIAoqKkFsdGVybmF0w612bmEgaHlwb3TDqXphIChI4oKBKSoqIHByZWRwb2tsYWTDoSwgxb5lIGFzcG/FiCBqZWRlbiB6IHTDvWNodG8gdWthem92YXRlxL5vdiBtw6EgbmEgcEggxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gw7rEjWlub2suCgpgYGB7cn0KbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoa2FibGVFeHRyYSkKbGlicmFyeShjb3JycGxvdCkKCmRhdGEgPC0gcmVhZC5jc3YoIkluZGlhbl93YXRlcl9kYXRhLmNzdiIpCnN0cihkYXRhKQpzdW1tYXJ5KGRhdGEpCgojIERvcGxuZW5pZSBjaMO9YmFqw7pjaWNoIGhvZG7DtHQgbWVkacOhbm9tCmNvbHVtbl9tZWRpYW5zIDwtIHNhcHBseShkYXRhLCBtZWRpYW4sIG5hLnJtID0gVFJVRSkKZm9yIChjb2wgaW4gbmFtZXMoZGF0YSkpIHsKICBpZiAoaXMubnVtZXJpYyhkYXRhW1tjb2xdXSkpIHsKICAgIGRhdGFbW2NvbF1dW2lzLm5hKGRhdGFbW2NvbF1dKV0gPC0gY29sdW1uX21lZGlhbnNbY29sXQogIH0KfQoKIyBWeWJlciDEjcOtc2VsbsOpIHByZW1lbm7DqQoKZGF0YV9udW0gPC0gZGF0YSAlPiUgc2VsZWN0KHdoZXJlKGlzLm51bWVyaWMpKQoKIyBaw6FrbGFkbsOpIMWhdGF0aXN0aWt5CgpkYXRhX251bSAlPiUKc3VtbWFyeSgpICU+JQprYWJsZShjYXB0aW9uID0gIlrDoWtsYWRuw6kgxaF0YXRpc3Rpa3kgbnVtZXJpY2vDvWNoIHByZW1lbm7DvWNoIikgJT4lCmthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFKQoKIyBWaXp1YWxpesOhY2lhIGTDoXQKCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeSh0aWR5cikKbGlicmFyeShkcGx5cikKbGlicmFyeShzY2FsZXMpCgojIFByZXZlZGllbWUgZMOhdGEgZG8gbG9uZyBmb3Jtw6F0dQpkYXRhX2xvbmcgPC0gZGF0YV9udW0gJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBldmVyeXRoaW5nKCksIG5hbWVzX3RvID0gIlByZW1lbm7DoSIsIHZhbHVlc190byA9ICJIb2Rub3RhIikKCiMgTm9ybWFsaXrDoWNpYSBrYcW+ZGVqIHByZW1lbm5laiAoMOKAkzEgcm96c2FoKQpkYXRhX3NjYWxlZCA8LSBkYXRhX2xvbmcgJT4lCiAgZ3JvdXBfYnkoUHJlbWVubsOhKSAlPiUKICBtdXRhdGUoSG9kbm90YV9zY2FsZWQgPSAoSG9kbm90YSAtIG1pbihIb2Rub3RhLCBuYS5ybSA9IFRSVUUpKSAvIAogICAgICAgICAgICAgICAgICAgICAgICAgICAobWF4KEhvZG5vdGEsIG5hLnJtID0gVFJVRSkgLSBtaW4oSG9kbm90YSwgbmEucm0gPSBUUlVFKSkpICU+JQogIHVuZ3JvdXAoKQoKIyBCb3hwbG90IHBvIMWha8OhbG92YW7DrQpnZ3Bsb3QoZGF0YV9zY2FsZWQsIGFlcyh4ID0gUHJlbWVubsOhLCB5ID0gSG9kbm90YV9zY2FsZWQsIGZpbGwgPSBQcmVtZW5uw6EpKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3IgPSAicmVkIiwgbm90Y2ggPSBUUlVFLCBhbHBoYSA9IDAuNykgKwogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTYpICsKICB0aGVtZSgKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIgogICkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJCb3hwbG90eSBqZWRub3RsaXbDvWNoIG51bWVyaWNrw71jaCBwcmVtZW5uw71jaCAoxaF0YW5kYXJkaXpvdmFuw6kpIiwKICAgIHggPSAiIiwKICAgIHkgPSAixaBrw6Fsb3ZhbsOhIGhvZG5vdGEgKDDigJMxKSIKICApCmBgYAojIyBJbnRlcnByZXTDoWNpYSBib3hwbG90b3YgamVkbm90bGl2w71jaCBudW1lcmlja8O9Y2ggcHJlbWVubsO9Y2gKCkJveHBsb3R5IHVrYXp1asO6IHJvemRlbGVuaWUgaG9kbsO0dCBqZWRub3RsaXbDvWNoIHByZW1lbm7DvWNoIHBvIMWhdGFuZGFyZGl6w6FjaWkgKHYgcm96c2FodSAw4oCTMSkuICAKWiBncmFmdSB2aWRubyBuaWVrb8S+a28gZMO0bGXFvml0w71jaCBwb3puYXRrb3Y6CgotICoqUHJlbWVubsOpIGBDb25kdWN0aXZpdHkuLi7CtW1oby5jbS4uLi5NYXhgIGEgYEJPRC4ubWcuTC4uLi5NYXhgKiogbWFqw7ogKip2ZcS+a8O9IHBvxI1ldCBvZMS+YWhsw71jaCBob2Ruw7R0ICjEjWVydmVuw6kgYm9keSkqKiwgIAogIMSNbyBuYXpuYcSNdWplIHbDvXJhem7DuiB2YXJpYWJpbGl0dSBtZWR6aSBsb2thbGl0YW1pIOKAlCB2IG5pZWt0b3LDvWNoIG9ibGFzdGlhY2ggamUgdm9kaXZvc8WlIGFsZWJvIGJpb2xvZ2lja8OhIHNwb3RyZWJhIGt5c2zDrWthIGV4dHLDqW1uZSB2eXNva8OhLgoKLSAqKmBwSC4uLk1pbmAgYSBgcEguLi5NYXhgKiogbWFqw7ogcG9tZXJuZSDDunprZSByb3pww6R0aWUsIMSNbyBqZSB0eXBpY2vDqSDigJQgcEggdm9keSBzYSB6dnnEjWFqbmUgcG9oeWJ1amUgdiDDunprb20gaW50ZXJ2YWxlIDbigJM4LgoKLSAqKmBUZW1wZXJhdHVyZS4uQy4uLi5NYXhgIGEgYFRlbXBlcmF0dXJlLi5DLi4uLk1pbmAqKiBzw7ogcm96bG/FvmVuw6kgcm92bm9tZXJuZSwgYmV6IHbDvXJhem7DvWNoIGV4dHLDqW1vdiDigJQgIAogIHRvIHBvdWthenVqZSBuYSBrb256aXN0ZW50bsOpIGtsaW1hdGlja8OpIHBvZG1pZW5reSBtZXJhbsO9Y2ggbG9rYWzDrXQuCgotICoqYFRvdGFsLkNvbGlmb3JtLi5NUE4uMTAwbWwuLi4uTWF4YCoqIHZ5a2F6dWplIG1pZXJuZSB2ecWhxaHDrSByb3pwdHlsLCAgCiAgxI1vIHpuYW1lbsOhLCDFvmUgYmFrdGVyaW9sb2dpY2vDoSBrb250YW1pbsOhY2lhIHZvZHkgc2EgdsO9cmF6bmUgbMOtxaFpIHBvZMS+YSBtaWVzdGEgbWVyYW5pYS4KCi0gKipgWWVhcmAgYSBgU1ROLmNvZGVgKiogc8O6IHRlY2huaWNrw6kgcHJlbWVubsOpIChpZGVudGlmaWvDoXRvcnksIG5pZSBlbnZpcm9ubWVudMOhbG5lIHVrYXpvdmF0ZWxlKSwgIAogIHByZXRvIGljaCByb3pkZWxlbmllIHR1IG5lbcOhIGFuYWx5dGlja8O9IHbDvXpuYW0uCgpgYGB7cn0KIyBLb3JlbGHEjW7DoSBtYXRpY2EKCmNvcnIgPC0gY29yKGRhdGFfbnVtLCB1c2UgPSAiY29tcGxldGUub2JzIikKY29ycnBsb3QoY29yciwgbWV0aG9kID0gImNvbG9yIiwgdHlwZSA9ICJ1cHBlciIsIHRsLmNleCA9IDAuNykKYGBgCgojIyBJbnRlcnByZXTDoWNpYSBrb3JlbGHEjW5laiBtYXRpY2UKCktvcmVsYcSNbsOhIGFuYWzDvXphIG5hem5hxI11amUsIMW+ZSAqKm5hanZ5xaHFoWlhIGtvcmVsw6FjaWEgcyBgcEguLi5NYXhgKiogamUgcG96b3JvdmFuw6EgcHJpIHVrYXpvdmF0ZcS+b2NoICAKKipyb3pwdXN0ZW7DqWhvIGt5c2zDrWthIChgRGlzc29sdmVkLi4uTWF4YCkqKiBhICoqdm9kaXZvc3RpIChgQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4YCkqKi4gIApUbyBwb3R2cmR6dWplLCDFvmUgY2hlbWlja8OpIHZsYXN0bm9zdGkgdm9keSwgYWtvIGtvbmNlbnRyw6FjaWEga3lzbMOta2EgYSBtbm/FvnN0dm8gcm96cHVzdGVuw71jaCBpw7Nub3YsICAKdsO9em5hbW5lIHPDunZpc2lhIHNvIHptZW5hbWkgcEguCgpTbGFiw6EgYWxlYm8gemFuZWRiYXRlxL5uw6Ega29yZWzDoWNpYSBqZSB2aWRpdGXEvm7DoSBtZWR6aSBwSCBhICoqYmlvbG9naWNrb3Ugc3BvdHJlYm91IGt5c2zDrWthIChCT0QpKiosICAKxI1vIG5hem5hxI11amUsIMW+ZSB0ZW50byBwYXJhbWV0ZXIgcEggb3ZwbHl2xYh1amUgbGVuIG5lcHJpYW1vLgoKKipUZXBsb3RhIHZvZHkqKiB2eWthenVqZSBtaWVybnUgcG96aXTDrXZudSBrb3JlbMOhY2l1IHMgcEgsICAKxI1vIG3DtMW+ZSBvZHLDocW+YcWlIGZ5emlrw6Fsbm8tY2hlbWlja8O6IHbDpHpidSBtZWR6aSB0ZXBsb3RvdSBhIHJvenDDusWhxaVhbsOtbSBwbHlub3Ygdm8gdm9kZS4KCgojIyBMaW5lw6FybmEgcmVncmVzaWEKClByZWRwb2tsYWRham1lLCDFvmUgbWF4aW3DoWxuYSBob2Rub3RhIHBIIHZvZHkgamUgesOhdmlzbMOhIHByZW1lbm7DoSBhIG9zdGF0bsOpIGNoZW1pY2vDqSBhIGJpb2xvZ2lja8OpIHVrYXpvdmF0ZWxlIGt2YWxpdHkgdm9keSwgYWtvIHPDuiB0ZXBsb3RhLCBvYnNhaCByb3pwdXN0ZW7DqWhvIGt5c2zDrWthLCB2b2Rpdm9zxaUsIGJpb2xvZ2lja8OhIHNwb3RyZWJhIGt5c2zDrWthLCBvYnNhaCBkdXNpxI1uYW5vdiBhIGZla8OhbG55Y2gga29saWZvcm1vdiwgcHJlZHN0YXZ1asO6IG5lesOhdmlzbMOpIHByZW1lbm7DqS4KYGBge3J9CiMgTmFqcHJ2IHByZW1lxYggcHLDoXpkbmUgYnVua3kgYWxlYm8gdGV4dHkgYWtvICJCREwiIG5hIE5BCmRhdGEkRmVjYWwuQ29saWZvcm0uLk1QTi4xMDBtbC4uLi5NYXhbZGF0YSRGZWNhbC5Db2xpZm9ybS4uTVBOLjEwMG1sLi4uLk1heCAlaW4lIGMoIiIsICJCREwiLCAiTkEiKV0gPC0gTkEKCiMgUG90b20gcHJldmVkaWXFoSBuYSDEjcOtc2xhCmRhdGEkRmVjYWwuQ29saWZvcm0uLk1QTi4xMDBtbC4uLi5NYXggPC0gYXMubnVtZXJpYyhkYXRhJEZlY2FsLkNvbGlmb3JtLi5NUE4uMTAwbWwuLi4uTWF4KQoKIyBMaW5lw6FybnkgbW9kZWwg4oCTIHBILi4uTWF4IGFrbyB6w6F2aXNsw6EgcHJlbWVubsOhCm1vZGVsIDwtIGxtKHBILi4uTWF4IH4gVGVtcGVyYXR1cmUuLkMuLi4uTWF4ICsgRGlzc29sdmVkLi4uTWF4ICsgQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4ICsgCiAgICAgICAgICAgICAgQk9ELi5tZy5MLi4uLk1heCArIE5pdHJhdGVOLi5tZy5MLi4uLk1heCArIEZlY2FsLkNvbGlmb3JtLi5NUE4uMTAwbWwuLi4uTWF4LCAKICAgICAgICAgICAgZGF0YSA9IGRhdGEpCgojIFbDvXN0dXB5IG1vZGVsdQpjYXQoIk9kaGFkbnV0w6kga29lZmljaWVudHkgbW9kZWx1OlxuIikKcHJpbnQobW9kZWwkY29lZmZpY2llbnRzKQoKY2F0KCJPZGhhZG51dMOpIHJlesOtZHXDoSAoenZ5xaFreSk6XG4iKQpwcmludChoZWFkKG1vZGVsJHJlc2lkdWFscywgMTApKSAgIyBsZW4gcHJ2w71jaCAxMCBwcmVoxL5hZG5lCgpjYXQoIlZ5cm92bmFuw6kgKHByZWRpa292YW7DqSkgaG9kbm90eSB6w6F2aXNsZWogcHJlbWVubmVqOlxuIikKcHJpbnQoaGVhZChtb2RlbCRmaXR0ZWQudmFsdWVzLCAxMCkpICAjIG9ww6TFpSBsZW4gcHJ2w71jaCAxMAoKY2F0KCJNYXRpY2EgbW9kZWx1IChYKTpcbiIpClggPC0gbW9kZWwubWF0cml4KG1vZGVsKQpwcmludChoZWFkKFgpKQoKY2F0KCJQcm9qZWvEjW7DoSBtYXRpY2EgKGhhdCBtYXRyaXgpOlxuIikKSCA8LSBYICUqJSBzb2x2ZSh0KFgpICUqJSBYKSAlKiUgdChYKQpwcmludChyb3VuZChIWzE6NSwgMTo1XSwgNCkpICAjIGxlbiBwcnbDvWNoIDV4NSBwcnZrb3YgcHJlIHByZWjEvmFkbm9zxaUKCmNhdCgiU8O6aHJuIG1vZGVsdTpcbiIpCnN1bW1hcnkobW9kZWwpCgpgYGAKIyBJbnRlcnByZXTDoWNpYSBhIGRpYWdub3N0aWthIG1vZGVsdQoKU8O6aHJuIG9kaGFkb3ZhbsOpaG8gbW9kZWx1IG7DoW0gcG9za3l0dWplIHPDumJvciBvZGhhZG51dMO9Y2ggcmVncmVzbsO9Y2gga29lZmljaWVudG92LCBrdG9yw71jaCB6bmFtaWVua2EgYSB2w716bmFtbm9zxaUgYnVkw7ogaW50ZXJwcmV0b3ZhbsOpIG5pxb7FoWllLiAgCkFrIGhvdm9yw61tZSBvIHZsYXN0bm9zdGlhY2ggbW9kZWx1IGFrbyBjZWxrdSwgcG96cmltZSBzYSBuYWpza8O0ciBuYSBkaWFnbm9zdGlja8OpIGdyYWZ5LgoKYGBge3J9CiMgTmFzdGF2acWlIHJvemxvxb5lbmllIDIgeCAyCnBhcihtZnJvdyA9IGMoMiwgMikpCgojIFZ5a3Jlc2xpxaUgdsWhZXRreSA0IGRpYWdub3N0aWNrw6kgZ3JhZnkgbW9kZWx1CnBsb3QobW9kZWwpCgojIFByaWRhxaUgc3BvbG/EjW7DvSBuYWRwaXMKbXRleHQoIkRpYWdub3N0aWNrw6kgZ3JhZnkgcmVncmVzbsOpaG8gbW9kZWx1IOKAkyBwSC4uLk1heCIsIAogICAgICBvdXRlciA9IFRSVUUsIGNleCA9IDEuMiwgZm9udCA9IDIpCgojIFJlc2V0b3ZhxaUgbGF5b3V0CnBhcihtZnJvdyA9IGMoMSwgMSkpCmBgYAojIyBJbnRlcnByZXTDoWNpYSBkaWFnbm9zdGlja8O9Y2ggZ3JhZm92IHByZSBtb2RlbCBwSC4uLk1heAoKIyMjIFJlc2lkdWFscyB2cy4gRml0dGVkCgotIFJlesOtZHXDoSBzYSBwb2h5YnVqw7ogcHJpYmxpxb5uZSBva29sbyBudWxvdmVqIG9zaSDigJMgbW9kZWwgdGVkYSAqKm5lbcOhIHN5c3RlbWF0aWNrw6kgc2tyZXNsZW5pZSB2IHByZWRpa2NpaSBob2Ruw7R0IHBIKiouICAKLSDEjGVydmVuw6EgTE9FU1MgxI1pYXJhIGplIHJlbGF0w612bmUgcm92bsOhLCDEjW8gbmF6bmHEjXVqZSwgxb5lICoqdnrFpWFoIG1lZHppIHBIIGEgenZvbGVuw71taSBwcmVtZW5uw71taSoqIChuYXByLiB0ZXBsb3RhLCB2b2Rpdm9zxaUsIEJPRCwgZHVzacSNbmFueSkgamUgcHJldmHFvm5lIGxpbmXDoXJueS4gIAotIFZlcnRpa8OhbG55IHJvenB0eWwgamUgcHJpYmxpxb5uZSByb3Zub21lcm7DvSDihpIgcHJlZHBva2xhZCAqKmhvbW9za2VkYXN0aWNpdHkgKGtvbsWhdGFudG7DqWhvIHJvenB0eWx1IGNow71iKSoqIGplIHYgesOhc2FkZSBzcGxuZW7DvS4gIAotIE5pZWtvxL5rbyBib2RvdiBtaW1vIGhsYXZuw70gcm96cHR5bCBtw7TFvmUgcHJlZHN0YXZvdmHFpSAqKmxva2FsaXR5IHMgZXh0csOpbW55bWkgaG9kbm90YW1pIGt2YWxpdHkgdm9keSoqIChwb3RlbmNpw6FsbmUgb2TEvmFobMOpIHBvem9yb3ZhbmlhKSwga3RvcsOpIHNpIG92ZXLDrW1lIHBvbW9jb3UgdGVzdG92LgoKLS0tCgojIyMgUeKAk1EgcGxvdAoKLSBWw6TEjcWhaW5hIGJvZG92IGxlxb7DrSBwb3pkxLrFviBkaWFnb27DoWx5IOKGkiByZXrDrWR1w6EgbW9kZWx1IHBILi4uTWF4IHPDuiAqKnRha21lciBub3Jtw6FsbmUgcm96bG/FvmVuw6kqKi4gIAotIE5hIGtvbmNvY2ggKHbEvmF2byBkb2xlIGEgdnByYXZvIGhvcmUpIG1vxb5ubyBwb3pvcm92YcWlIG1pZXJuZSBvZGNow71sa3kg4oCTIHRvIG5hem5hxI11amUgKirFpWHFvsWhaWUgY2h2b3N0eSByb3pkZWxlbmlhKiosIHByYXZkZXBvZG9ibmUgc3DDtHNvYmVuw6kgZXh0csOpbW55bWkgaG9kbm90YW1pIG5pZWt0b3LDvWNoIGNoZW1pY2vDvWNoIHVrYXpvdmF0ZcS+b3YuICAKLSBTdHJlZG7DoSDEjWFzxaUgZ3JhZnUgamUgZG9icmUgemFyb3ZuYW7DoSwgxI1vIHBvdHZyZHp1amUsIMW+ZSAqKnbDpMSNxaFpbmEgcG96b3JvdmFuw60gc2Egc3Byw6F2YSBub3Jtw6FsbmUqKi4KCi0tLQoKIyMjIFNjYWxl4oCTTG9jYXRpb24gcGxvdAoKLSBCb2R5IHPDuiByb3pwdMO9bGVuw6kgcm92bm9tZXJuZSBwbyBvc2kgWCBiZXogdnl0dsOhcmFuaWEgbGlldmlrYSDihpIgcm96cHR5bCByZXrDrWR1w60gamUgKipwcmlibGnFvm5lIGtvbsWhdGFudG7DvSoqLiAgCi0gSGxhZGvDoSBMT0VTUyDEjWlhcmEgamUgdGFrbWVyIHZvZG9yb3Zuw6EsIMSNbyBuYXpuYcSNdWplLCDFvmUgKip2YXJpYWJpbGl0YSBjaMO9YiBzYSBuZW1lbsOtIHNvIHptZW5vdSBwcmVkaWtvdmFuw71jaCBob2Ruw7R0IHBIKiouICAKLSBUZW50byB2w71zbGVkb2sgcG9kcG9ydWplIHBsYXRub3PFpSBwcmVkcG9rbGFkdSBvICoqaG9tb3NrZWRhc3RpY2l0ZSBtb2RlbHUqKi4KCi0tLQoKIyMjIFJlc2lkdWFscyB2cy4gTGV2ZXJhZ2UKCi0gVsOkxI3FoWluYSBib2RvdiBtw6EgbsOtemt5IHZwbHl2IChDb29rb3ZhIHZ6ZGlhbGVub3PFpSA8IDAuNSkg4oaSIMW+aWFkbmUgcG96b3JvdmFuaWUgKipuZW92cGx5dsWIdWplIHJlZ3Jlc27DqSBrb2VmaWNpZW50eSB2w71yYXpuZSoqLiAgCi0gSmVkZW4gYWxlYm8gZHZhIGJvZHkgbcO0xb51IG1hxaUgenbDvcWhZW7DuiBww6Frb3bDuiBob2Rub3R1IOKAkyBpZGUgcHJhdmRlcG9kb2JuZSBvICoqbG9rYWxpdHkgcyBleHRyw6ltbmUgb2RsacWhbsO9bWkgcGFyYW1ldHJhbWkgdm9keSoqLCBrdG9yw6kgdsWhYWsgbW9kZWwgdsO9cmF6bmUgbmVkZWZvcm11asO6LiAgCi0gQ2Vsa292byBww7Rzb2LDrSBtb2RlbCAqKnN0YWJpbG5lIGEgYmV6IHbDvXpuYW1uw71jaCBvZMS+YWhsw71jaCBhbGVibyB2cGx5dm7DvWNoIGJvZG92KiouCgotLS0KCiMjIyBaaHJudXRpZQoKRGlhZ25vc3RpY2vDqSBncmFmeSBwb3R2cmR6dWrDuiwgxb5lIG1vZGVsIHMgdnlzdmV0xL5vdmFub3UgcHJlbWVubm91ICoqcEguLi5NYXgqKiBhIHByZWRpa3Rvcm1pICAKKCoqVGVtcGVyYXR1cmUuLkMuLi4uTWF4KiosICoqRGlzc29sdmVkLi4uTWF4KiosICoqQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4KiosICAKKipCT0QuLm1nLkwuLi4uTWF4KiosICoqTml0cmF0ZU4uLm1nLkwuLi4uTWF4KiogYSAqKkZlY2FsLkNvbGlmb3JtLi5NUE4uMTAwbWwuLi4uTWF4KiopICAKc3DEusWIYSBobGF2bsOpIHByZWRwb2tsYWR5IGxpbmXDoXJuZWogcmVncmVzaWUuICAKClJlesOtZHXDoSBzw7ogcHJpYmxpxb5uZSBub3Jtw6FsbmUgcm96bG/FvmVuw6ksIHJvenB0eWwgY2jDvWIgamUga29uxaF0YW50bsO9IGEgdsOkxI3FoWluYSBwb3pvcm92YW7DrSBuZW3DoSBuYWRtZXJuw70gdnBseXYgbmEgdsO9c2xlZG9rIG1vZGVsdS4gIApNb2RlbCB0ZWRhIG1vxb5ubyBwb3Zhxb5vdmHFpSB6YSAqKsWhdGF0aXN0aWNreSBzcG/EvmFobGl2w70gbmEgaW50ZXJwcmV0w6FjaXUgdnrFpWFodSBtZWR6aSB1a2F6b3ZhdGXEvm1pIGt2YWxpdHkgdm9keSBhIHBIKiouCmBgYHtyfQojIE5vdsO9IG1vZGVsIHNvIHpsb2dhcml0bW92YW5vdSBDb25kdWN0aXZpdHkKbW9kZWwyIDwtIGxtKHBILi4uTWF4IH4gVGVtcGVyYXR1cmUuLkMuLi4uTWF4ICsgRGlzc29sdmVkLi4uTWF4ICsKICAgICAgICAgICAgICAgSShsb2coQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4KSkgKwogICAgICAgICAgICAgICBCT0QuLm1nLkwuLi4uTWF4ICsgTml0cmF0ZU4uLm1nLkwuLi4uTWF4LCAKICAgICAgICAgICAgIGRhdGEgPSBkYXRhKQpzdW1tYXJ5KG1vZGVsMikKcGFyKG1mcm93ID0gYygyLCAyKSkKcGxvdChtb2RlbDIpCnBhcihtZnJvdyA9IGMoMSwgMSkpCmBgYAoKVHJhbnNmb3Jtw6FjaWEgcHJlbWVubmVqIGBDb25kdWN0aXZpdHkuLi7CtW1oby5jbS4uLi5NYXhgIHBvbW9jb3UgbG9nYXJpdG11IGJvbGEgenZvbGVuw6EgbmEgem7DrcW+ZW5pZSB2cGx5dnUgZXh0csOpbW55Y2ggaG9kbsO0dCwga3RvcsOpIHNhIHYgcMO0dm9kbsO9Y2ggw7pkYWpvY2ggdsO9cmF6bmUgbMOtxaFpbGkgbWVkemkgbG9rYWxpdGFtaS4gIApQbyBhcGxpa8OhY2lpIGxvZ2FyaXRtaWNrZWogdHJhbnNmb3Jtw6FjaWUgc2EgbW9kZWwgc3Byw6F2YSBzdGFiaWxuZWrFoWllIGEgamVobyBrb2VmaWNpZW50eSBzw7ogbGVwxaFpZSBpbnRlcnByZXRvdmF0ZcS+bsOpLgoKIyMgSW50ZXJwcmV0w6FjaWEgZGlhZ25vc3RpY2vDvWNoIGdyYWZvdiBwcmUgbW9kZWwgc28gemxvZ2FyaXRtb3Zhbm91IHZvZGl2b3PFpW91CgojIyMgUmVzaWR1YWxzIHZzIEZpdHRlZApSZXrDrWR1w6Egc2EgcG9oeWJ1asO6ICoqcm92bm9tZXJuZSBva29sbyBudWxvdmVqIG9zaSoqLCDEjW8gbmF6bmHEjXVqZSwgxb5lIG1vZGVsICoqbmVtw6Egc3lzdGVtYXRpY2vDqSBza3Jlc2xlbmllKiogdiBwcmVkaWtjaWkgaG9kbsO0dCBwSC4gIArEjGVydmVuw6EgTE9FU1MgxI1pYXJhIGplICoqdGFrbWVyIHZvZG9yb3Zuw6EqKiwgxI1vIHBvdHZyZHp1amUsIMW+ZSBwbyBsb2dhcml0bWlja2VqIHRyYW5zZm9ybcOhY2lpIHZvZGl2b3N0aSBzYSBvZHN0csOhbmlsYSBww7R2b2Ruw6EgbWllcm5hIG5lbGluZWFyaXRhLiAgClZlcnRpa8OhbG55IHJvenB0eWwgcmV6w61kdcOtIGplICoqa29uxaF0YW50bsO9Kiog4oCTIHByZWRwb2tsYWQgKipob21vc2tlZGFzdGljaXR5KiogamUgdGVkYSBzcGxuZW7DvS4gIApOaWVrb8S+a28gamVkbm90bGl2w71jaCBib2RvdiBzIHbDpMSNxaFvdSBvZGNow71sa291IG3DtMW+ZSBwYXRyacWlIGV4dHLDqW1ueW0gbG9rYWxpdMOhbSwgbm8gbmVvdnBseXbFiHVqw7ogbW9kZWwgdsO9em5hbW5lLgoKLS0tCgojIyMgUeKAk1EgcGxvdApWw6TEjcWhaW5hIGJvZG92IGxlxb7DrSAqKnZlxL5taSBibMOtemtvIGRpYWdvbsOhbHkqKiwgxI1vIHpuYW1lbsOhLCDFvmUgKipyZXrDrWR1w6Egc8O6IHByaWJsacW+bmUgbm9ybcOhbG5lIHJvemxvxb5lbsOpKiouICAKTWVuxaFpZSBvZGNow71sa3kgbmEga29uY29jaCAodsS+YXZvIGRvbGUgYSB2cHJhdm8gaG9yZSkgbmF6bmHEjXVqw7ogbGVuIG1pZXJuZSBvZGNow71sa3kgb2Qgbm9ybcOhbG5vc3RpLCAgCmt0b3LDqSBtw7TFvnUgYnnFpSBzcMO0c29iZW7DqSBwcsOtdG9tbm9zxaVvdSBuaWVrb8S+a8O9Y2ggZXh0csOpbW55Y2ggbWVyYW7DrS4gIApPcHJvdGkgcMO0dm9kbsOpbXUgbW9kZWx1IHNhIHJvemRlbGVuaWUgcmV6w61kdcOtICoqdsO9cmF6bmUgemxlcMWhaWxvKiog4oCTIGxvZy10cmFuc2Zvcm3DoWNpYSB0ZWRhIHBvbW9obGEuCgotLS0KCiMjIyBTY2FsZeKAk0xvY2F0aW9uIHBsb3QKQm9keSBzw7ogcm96cHTDvWxlbsOpICoqcm92bm9tZXJuZSBwb3pkxLrFviBvc2kgWCoqIGJleiB6bsOhbW9rIHJvesWhaXJ1asO6Y2VobyBzYSDigJ5saWV2aWth4oCcLCAgCsSNbyBwb3R2cmR6dWplLCDFvmUgKip2YXJpYW5jaWEgcmV6w61kdcOtIGplIGtvbsWhdGFudG7DoSoqIG5hcHJpZcSNIHByZWRpa292YW7DvW1pIGhvZG5vdGFtaS4gIArEjGVydmVuw6EgaGxhZGvDoSDEjWlhcmEgamUgdGFrbWVyIHJvdm7DoSwgxI1vIG5hem5hxI11amUsIMW+ZSAqKnJvenB0eWwgY2jDvWIgc2EgbmVtZW7DrSoqIHNvIHptZW5vdSBob2Ruw7R0IHBILiAgCk1vZGVsIHRlZGEgc3DEusWIYSBwcmVkcG9rbGFkICoqaG9tb3NrZWRhc3RpY2l0eSoqIHZlxL5taSBkb2JyZS4KCi0tLQoKIyMjIFJlc2lkdWFscyB2cyBMZXZlcmFnZQpWw6TEjcWhaW5hIHBvem9yb3ZhbsOtIG3DoSAqKm7DrXpreSBww6Frb3bDvSBlZmVrdCoqIChsZXZlcmFnZSA8IDAuMSkgYSBDb29rb3ZhIHZ6ZGlhbGVub3PFpSB6b3N0w6F2YSBwb2QgMC41LiAgClRvIHpuYW1lbsOhLCDFvmUgxb5pYWRuZSBwb3pvcm92YW5pZSAqKm5lb3ZwbHl2xYh1amUgbW9kZWwgbmFkbWVybmUqKi4gIApOaWVrb8S+a28gYm9kb3YgKG5hcHIuIDE5MSwgNjYpIHZ5a2F6dWplIG1pZXJuZSB2ecWhxaHDrSB2cGx5diwgYWxlIG5lcHJlc2FodWplIGtyaXRpY2vDqSBob2Rub3R5LiAgCk1vZGVsIHRlZGEgKipuZW9ic2FodWplIHbDvXJhem5lIHZwbHl2bsOpIGFsZWJvIG9kxL5haGzDqSBwcsOtcGFkeSoqLgoKLS0tCgojIyMgKipaaHJudXRpZSBkaWFnbm9zdGlreSoqClRyYW5zZm9ybW92YW7DvSBtb2RlbCAoc28gemxvZ2FyaXRtb3Zhbm91IHZvZGl2b3PFpW91KSAqKnbDvXJhem5lIHpsZXDFoWlsIMWhdGF0aXN0aWNrw6kgdmxhc3Rub3N0aSByZXrDrWR1w60qKjoKLSBvZHN0csOhbmlsIG1pZXJudSBuZWxpbmVhcml0dSB6IHDDtHZvZG7DqWhvIG1vZGVsdSwgIAotIHpuw63FvmlsIGhldGVyb3NrZWRhc3RpY2l0dSwgIAotIGEgcHJpYmzDrcW+aWwgcm96ZGVsZW5pZSByZXrDrWR1w60gayBub3Jtw6FsbmVtdSB0dmFydS4gIAoKTW9kZWwgamUgdGVkYSAqKnN0YWJpbG7DvSwgc3BvxL5haGxpdsO9KiogYSB2aG9kbsO9IG5hIGludGVycHJldMOhY2l1IHZ6xaVhaHUgbWVkemkga3ZhbGl0b3Ugdm9keSBhIHBILgoKIyMgVGVzdHkgbm9ybWFsaXR5IGEgaWRlbnRpZmlrw6FjaWEgb2TEvmFobMO9Y2ggaG9kbsO0dAoKViB0ZWp0byDEjWFzdGkgb3ZlcsOtbWUsIMSNaSByZXrDrWR1w6EgcMO0dm9kbsOpaG8gbW9kZWx1IHNwxLrFiGFqw7ogcHJlZHBva2xhZCAqKm5vcm1hbGl0eSByb3pkZWxlbmlhKiogIAphIHrDoXJvdmXFiCBpZGVudGlmaWt1amVtZSBtb8W+bsOpICoqb2TEvmFobMOpIHBvem9yb3ZhbmlhKiosIGt0b3LDqSBieSBtb2hsaSBvdnBseXbFiG92YcWlIHbDvXNsZWRreS4KYGBge3J9CmphcnF1ZS5iZXJhLnRlc3QocmVzaWR1YWxzKG1vZGVsKSkKY2FyOjpvdXRsaWVyVGVzdChtb2RlbCkKYGBgCgojIyDwn6eqIFRlc3R5IG5vcm1hbGl0eSBhIG9kxL5haGzDvWNoIGhvZG7DtHQgcG8gdHJhbnNmb3Jtw6FjaWkgKG1vZGVsMikKClBvIMO6cHJhdmUgbW9kZWx1IChsb2dhcml0bcOhY2lhIHZvZGl2b3N0aSkgb3ZlcsOtbWUsIMSNaSBzYSB6bGVwxaFpbGEgbm9ybWFsaXRhIHJvemRlbGVuaWEgcmV6w61kdcOtCmEgxI1pIHNhIHpuw63FvmlsIHBvxI1ldCBvZMS+YWhsw71jaCBob2Ruw7R0LgoKYGBge3J9CiMgSmFycXVl4oCTQmVyYSB0ZXN0IHByZSBtb2RlbDIKamFycXVlLmJlcmEudGVzdChyZXNpZHVhbHMobW9kZWwyKSkKCiMgVGVzdCBvZMS+YWhsw71jaCBob2Ruw7R0IHByZSBtb2RlbDIKY2FyOjpvdXRsaWVyVGVzdChtb2RlbDIpCmBgYAoqKkludGVycHJldMOhY2lhIHbDvXNsZWRrb3Y6KioKClbDvXNsZWRreSAqKkphcnF1ZeKAk0JlcmEgdGVzdHUqKiBwcmUgYG1vZGVsMmAgdWthenVqw7osIMW+ZSBwLWhvZG5vdGEgamUgKip2ecWhxaFpYSBuZcW+IHYgcMO0dm9kbm9tIG1vZGVsaSoqLiAgClRvIHpuYW1lbsOhLCDFvmUgcG8gbG9nYXJpdG1pY2tlaiB0cmFuc2Zvcm3DoWNpaSBwcmVtZW5uZWogYENvbmR1Y3Rpdml0eS4uLsK1bWhvLmNtLi4uLk1heGAgc2EgIAoqKm5vcm1hbGl0YSByZXrDrWR1w60gemxlcMWhaWxhKiosIGhvY2kgcHJpIG1lbsWhb20gcG/EjXRlIHBvem9yb3ZhbsOtIG5lbXVzw60gYnnFpSDDunBsbmUgZG9rb25hbMOhLgoKKipPdXRsaWVyIFRlc3QqKiB1xb4gbmVpZGVudGlmaWt1amUgxb5pYWRuZSB2w71yYXpuZSB2w716bmFtbsOpIG9kxL5haGzDqSBwb3pvcm92YW5pZSwgIArEjW8gcG90dnJkenVqZSwgxb5lIHDDtHZvZG7DvSBleHRyw6ltbnkgYm9kIChwb3pvcm92YW5pZSDEjS4gMTkxKSAqKnXFviBuZW3DoSBwb2RzdGF0bsO9IHZwbHl2KiogbmEgbW9kZWwuCgoqKlrDoXZlcjoqKiBUcmFuc2Zvcm1vdmFuw70gbW9kZWwgKGBtb2RlbDJgKSBsZXDFoWllIHNwxLrFiGEgcHJlZHBva2xhZHkgbGluZcOhcm5laiByZWdyZXNpZSDigJMgIApyZXrDrWR1w6Egc8O6ICoqYmxpxb7FoWllIGsgbm9ybcOhbG5lbXUgcm96ZGVsZW5pdSoqIGEgbW9kZWwgamUgKipyb2J1c3RuZWrFocOtIHZvxI1pIG9kxL5haGzDvW0gaG9kbm90w6FtKiouCgoKIyBaw6F2ZXIKCk5hIHrDoWtsYWRlIHJlZ3Jlc25laiBhbmFsw716eSBtb8W+bm8ga29uxaF0YXRvdmHFpSwgxb5lIG1heGltw6FsbmUgcEggdm9keSAoKipwSC4uLk1heCoqKSAgCmplIG92cGx5dm5lbsOpIHZpYWNlcsO9bWkgZmFrdG9ybWkga3ZhbGl0eSB2b2R5LiAgClByZW1lbm7DqSAqKnRlcGxvdGEgdm9keSoqLCAqKnJvenB1c3RlbsO9IGt5c2zDrWsqKiBhICoqdm9kaXZvc8WlKiogbWFqw7ogcHJldmHFvm5lICoqcG96aXTDrXZueSB2cGx5dioqLCAgCmvDvW0gKipiaW9sb2dpY2vDoSBzcG90cmViYSBreXNsw61rYSoqIGEgKipmZWvDoWxuZSBrb2xpZm9ybXkqKiBwSCAqKnpuw63FvnVqw7oqKi4KClRyYW5zZm9ybcOhY2lhIHByZW1lbm5laiBgQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4YCBwb21vY291ICoqbG9nYXJpdG11KiogIAp6bGVwxaFpbGEgxaF0YXRpc3RpY2vDqSB2bGFzdG5vc3RpIG1vZGVsdSDigJQgcmV6w61kdcOhIHPDuiBibGnFvsWhaWUgayBub3Jtw6FsbmVtdSByb3pkZWxlbml1ICAKYSByb3pwdHlsIGNow71iIGplIHN0YWJpbG5lasWhw60gKCoqaG9tb3NrZWRhc3RpY2l0YSoqKS4gIApNb2RlbCBqZSB0ZWRhIHZvIHbFoWVvYmVjbm9zdGkgKipzcG/EvmFobGl2ZWrFocOtKiogYSBsZXDFoWllIHNwxLrFiGEgcHJlZHBva2xhZHkgbGluZcOhcm5laiByZWdyZXNpZS4KCk5hcHJpZWsgdG9tdSB2xaFhayB0ZXN0eSBvZMS+YWhsw71jaCBob2Ruw7R0IHVrw6F6YWxpLCDFvmUgKipwb3pvcm92YW5pZSDEjS4gMTkxKiogIAp6b3N0w6F2YSAqKm9kxL5haGzDqSBhaiBwbyB0cmFuc2Zvcm3DoWNpaSoqLiAgCklkZSB0ZWRhIG8gKipleHRyw6ltbmUgbWVyYW5pZSoqLCBrdG9yw6kgbcOhIHBvdGVuY2nDoWwgb3ZwbHl2bmnFpSB2w71zbGVka3kgbW9kZWx1IOKAlCAgCnYgYnVkw7pjbm9zdGkgYnkgYm9sbyB2aG9kbsOpIHRvdG8gcG96b3JvdmFuaWUgb3NvYml0bmUgcHJlc2vDum1hxaUgIAoobmFwci4gxI1pIG5lamRlIG8gY2h5YnUgbWVyYW5pYSBhbGVibyDFoXBlY2lmaWNrw7ogbG9rYWxpdHUgcyB2w71yYXpuZSBvZGxpxaFuw71taSBwb2RtaWVua2FtaSkuCgpDZWxrb3ZvIG1vxb5ubyB1emF2cmllxaUsIMW+ZSB0cmFuc2Zvcm1vdmFuw70gbW9kZWwgKipsZXDFoWllIHZ5c3RpaHVqZSB2esWlYWh5IG1lZHppIHVrYXpvdmF0ZcS+bWkga3ZhbGl0eSB2b2R5IGEgcEgqKiwgIApubyBwcsOtdG9tbm9zxaUgamVkbsOpaG8gKip0cnZhbMOpaG8gb2TEvmFobMOpaG8gcG96b3JvdmFuaWEgKMSNLiAxOTEpKiogIApqZSBwb3RyZWJuw6kgbWHFpSBuYSBwYW3DpHRpIHByaSBpbnRlcnByZXTDoWNpaSB2w71zbGVka292LgoKIyBIZXRlcm9za2VkYXN0aWNpdGEKClByw610b21ub3PFpSAqKmhldGVyb3NrZWRhc3RpY2l0eSoqIChuZWtvbsWhdGFudG7DqWhvIHJvenB0eWx1IG7DoWhvZG5laiB6bG/Fvmt5KSBzcMO0c29idWplIGNoeWJuw6kgdnlob2Rub2NvdmFuaWUgCip0LXRlc3RvdiB2w716bmFtbm9zdGkqIGplZG5vdGxpdsO9Y2ggcmVncmVzbsO9Y2gga29lZmljaWVudG92LiAgClByZXRvIGplIG51dG7DqSBoZXRlcm9za2VkYXN0aWNpdHU6CgotICoqZGV0ZWtvdmHFpSoqICh2aXp1w6FsbmUgYSBwb21vY291IHRlc3RvdiksICAKLSBhIHYgcHLDrXBhZGUgamVqIHByw610b21ub3N0aSBqdSAqKm9kc3Ryw6FuacWlKiogYWxlYm8ga29tcGVuem92YcWlLgoKQWogdiBuYcWhb20gcHLDrXBhZGUgc2EgcG9rw7pzaW1lIG8gdml6dcOhbG5lIHZ5aG9kbm90ZW5pZSB6w6F2aXNsb3N0aSDFoXR2b3Jjb3YgcmV6w61kdcOtIApvZCB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoLCB1IGt0b3LDvWNoIG3DoW1lIHBvZG96cmVuaWUsIMW+ZSBtw7TFvnUgaGV0ZXJvc2tlZGFzdGljaXR1IHNww7Rzb2JvdmHFpS4gIAoKQnVkZW1lIHBvc3Vkem92YcWlIGR2YSBtb2RlbHk6Ci0gYG1vZGVsYCDigJMgcMO0dm9kbsO9IG1vZGVsLAotIGBtb2RlbDJgIOKAkyBtb2RlbCBzbyAqKnpsb2dhcml0bW92YW5vdSB2b2Rpdm9zxaVvdSoqIChgQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4YCksIAogIGt0b3LDqWhvIGNpZcS+b20gYm9sbyB6bsOtxb5pxaUgdnBseXYgZXh0csOpbW55Y2ggaG9kbsO0dC4KCmBgYHtyfQojIEhldGVyb3NrZWRhc3RpY2l0YSDigJMgbG9rw6FsbmUgYmV6IHJpYWRrdSAxOTEgKGdsb2LDoWxuZSAnZGF0YScgbmVtZW7DrW1lKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGF0Y2h3b3JrKQoKIyAxKSBMb2vDoWxuYSBrw7NwaWEgYSB2eWhvZGVuaWUgMTkxLiByaWFka3UKZGF0YV9oIDwtIGRhdGEKaWYgKG5yb3coZGF0YV9oKSA+PSAxOTEpIHsKICBkYXRhX2ggPC0gZGF0YV9oWy0xOTEsICwgZHJvcCA9IEZBTFNFXQp9CgojIDIpIFJlZml0IG1vZGVsb3YgbmEgZGF0YV9oCm1vZGVsX2ggPC0gbG0oCiAgcEguLi5NYXggfiBUZW1wZXJhdHVyZS4uQy4uLi5NYXggKyBEaXNzb2x2ZWQuLi5NYXggKwogICAgQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4ICsgQk9ELi5tZy5MLi4uLk1heCArCiAgICBOaXRyYXRlTi4ubWcuTC4uLi5NYXggKyBGZWNhbC5Db2xpZm9ybS4uTVBOLjEwMG1sLi4uLk1heCwKICBkYXRhID0gZGF0YV9oLCBuYS5hY3Rpb24gPSBuYS5leGNsdWRlCikKCm1vZGVsMl9oIDwtIGxtKAogIHBILi4uTWF4IH4gVGVtcGVyYXR1cmUuLkMuLi4uTWF4ICsgRGlzc29sdmVkLi4uTWF4ICsKICAgIEkobG9nKENvbmR1Y3Rpdml0eS4uLsK1bWhvLmNtLi4uLk1heCkpICsKICAgIEJPRC4ubWcuTC4uLi5NYXggKyBOaXRyYXRlTi4ubWcuTC4uLi5NYXgsCiAgZGF0YSA9IGRhdGFfaCwgbmEuYWN0aW9uID0gbmEuZXhjbHVkZQopCgojIDMpIETDoXRhIHBvdcW+aXTDqSB2IG1vZGVsb2NoIChsZW4gcmlhZGt5LCBrdG9yw6kgbW9kZWwgc2t1dG/EjW5lIHBvdcW+aWwpCmRmX21vZGVsICA8LSBhcy5kYXRhLmZyYW1lKG1vZGVsLmZyYW1lKG1vZGVsX2gpKQpkZl9tb2RlbDIgPC0gYXMuZGF0YS5mcmFtZShtb2RlbC5mcmFtZShtb2RlbDJfaCkpCgojIC0tLSBaQVJPVk5BTklFIFJFWsONRFXDjSBQT0TEvUEgTUlFTiBSSUFES09WIChrcml0aWNrw6kpIC0tLQpyMSA8LSByZXNpZHVhbHMobW9kZWxfaCkKZGZfbW9kZWwkUmVzaWR1YWxzIDwtIGFzLm51bWVyaWMocjFbbWF0Y2gocm93bmFtZXMoZGZfbW9kZWwpLCBuYW1lcyhyMSkpXSkKCnIyIDwtIHJlc2lkdWFscyhtb2RlbDJfaCkKZGZfbW9kZWwyJFJlc2lkdWFscyA8LSBhcy5udW1lcmljKHIyW21hdGNoKHJvd25hbWVzKGRmX21vZGVsMiksIG5hbWVzKHIyKSldKQoKIyA0KSBHcmFmeSDigJMgcMO0dm9kbsO9IG1vZGVsIChhbmFsw7NnIEdEUC9TY2hvb2xpbmcpCnAxIDwtIGdncGxvdChkZl9tb2RlbCwgYWVzKHggPSBgQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4YCwgeSA9IFJlc2lkdWFsc14yKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYsIGNvbG9yID0gInN0ZWVsYmx1ZSIpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJyZWQiKSArCiAgbGFicyh4ID0gIlZvZGl2b3PFpSAowrVtaG8vY20pIiwKICAgICAgIHkgPSAixaB0dm9yY2UgcmV6w61kdcOtIiwKICAgICAgIHRpdGxlID0gIsWgdHZvcmNlIHJlesOtZHXDrSB2cyBWb2Rpdm9zxaUiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwMiA8LSBnZ3Bsb3QoZGZfbW9kZWwsIGFlcyh4ID0gYFRlbXBlcmF0dXJlLi5DLi4uLk1heGAsIHkgPSBSZXNpZHVhbHNeMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJzdGVlbGJsdWUiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoeCA9ICJUZXBsb3RhICjCsEMpIiwKICAgICAgIHkgPSAixaB0dm9yY2UgcmV6w61kdcOtIiwKICAgICAgIHRpdGxlID0gIsWgdHZvcmNlIHJlesOtZHXDrSB2cyBUZXBsb3RhIikgKwogIHRoZW1lX21pbmltYWwoKQoKcDEgKyBwMgpgYGAKYSB0ZXJheiB0cmFuc2Zvcm1vdmFuw70gbW9kZWwKYGBge3J9CiMgZG9wbMWIIHN1cm92w7ogdm9kaXZvc8WlIChhIHByZSBpc3RvdHUgYWogdGVwbG90dSkgZG8gZGZfbW9kZWwyIHBvZMS+YSByb3ZuYWvDvWNoIHJpYWRrb3YKaWR4MiA8LSBhcy5pbnRlZ2VyKHJvd25hbWVzKGRmX21vZGVsMikpCmRmX21vZGVsMiRDb25kdWN0aXZpdHkgPC0gZGF0YV9oJGBDb25kdWN0aXZpdHkuLi7CtW1oby5jbS4uLi5NYXhgW2lkeDJdCmRmX21vZGVsMiRUZW1wZXJhdHVyZSAgPC0gZGF0YV9oJGBUZW1wZXJhdHVyZS4uQy4uLi5NYXhgW2lkeDJdCgojIDUpIEdyYWZ5IOKAkyB0cmFuc2Zvcm1vdmFuw70gbW9kZWwgKGxvZyB2b2Rpdm9zdGkpCnAzIDwtIGdncGxvdChkZl9tb2RlbDIsIGFlcyh4ID0gbG9nKENvbmR1Y3Rpdml0eSksIHkgPSBSZXNpZHVhbHNeMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoeCA9ICJsb2coVm9kaXZvc8WlKSIsCiAgICAgICB5ID0gIsWgdHZvcmNlIHJlesOtZHXDrSIsCiAgICAgICB0aXRsZSA9ICLFoHR2b3JjZSByZXrDrWR1w60gdnMgbG9nKFZvZGl2b3PFpSkiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwNCA8LSBnZ3Bsb3QoZGZfbW9kZWwyLCBhZXMoeCA9IFRlbXBlcmF0dXJlLCB5ID0gUmVzaWR1YWxzXjIpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNiwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKHggPSAiVGVwbG90YSAowrBDKSIsCiAgICAgICB5ID0gIsWgdHZvcmNlIHJlesOtZHXDrSIsCiAgICAgICB0aXRsZSA9ICLFoHR2b3JjZSByZXrDrWR1w60gdnMgVGVwbG90YSIpICsKICB0aGVtZV9taW5pbWFsKCkKCnAzICsgcDQKYGBgCk5hIHRvbXRvIG9icsOhemt1IHBvZMS+YSB2eWhsYWRlbsO9Y2ggaG9kbsO0dCDFoXR2b3Jjb3YgcmV6w61kdcOtICjEjWVydmVuw6Ega3JpdmthKSBtw7TFvmVtZSBrb27FoXRhdG92YcWlLCDFvmUgcG8gbG9nYXJpdG1pY2tlaiB0cmFuc2Zvcm3DoWNpaSB2b2Rpdm9zdGkgKipsb2coVm9kaXZvc8WlKSoqIChwcmF2w70gcGFuZWwgcHJ2w6lobyByaWFka3UpIGtyaXZrYSBuZXZ5a2F6dWplIHN5c3RlbWF0aWNrw70gdHJlbmQgcyB2eXN2ZXTEvnVqw7pjb3UgcHJlbWVubm91IGEgdmFyaWFuY2lhIGNow71iIGplIHByaWJsacW+bmUga29uxaF0YW50bsOhLiBQb2RvYm5lIHByaSAqKlRlcGxvdGUqKiB2aWTDrW1lIGliYSBtaWVybnkgbG9rw6Fsbnkg4oCeaHJib2zigJwgb2tvbG8gMjXigJMzMyDCsEMsIGt0b3LDvSB2xaFhayBuZXByZWRzdGF2dWplIHbDvXJhem7DvSByYXN0IHZhcmlhYmlsaXR5LgoKS3bDtGxpIGRlbW9uxaF0csOhY2lpIGFsZSB1a8Ohxb5tZSwgxb5lIGJleiBwcmVkY2jDoWR6YWrDumNlaiBsb2dhcml0bWlja2VqIHRyYW5zZm9ybcOhY2llIGJ5IHRvIGRvcGFkbG8gaW5hay4gViBww7R2b2Rub20gbW9kZWxpICjEvmF2w70gcGFuZWwgcHJ2w6lobyByaWFka3UpIGplIMSNZXJ2ZW7DoSBrcml2a2EgcHJpICoqVm9kaXZvc3RpKiogbWllcm5lIGtsZXNhasO6Y2Eg4oCTIG5hem5hxI11amUgdG8gKipzbGFiw7ogaGV0ZXJvc2tlZGFzdGljaXR1KiogKHbDpMSNxaHDrSByb3pwdHlsIGNow71iIHByaSBuacW+xaFlaiB2b2Rpdm9zdGkpLCBrdG9yw6Egc2EgcG8gcHJlY2hvZGUgbmEgKipsb2coVm9kaXZvc8WlKSoqIHZ5dHLDoWNhIGEga3JpdmthIHNhIHbDvXJhem5lIHNwbG/FocWldWplLgoKKipaaHJudXRpZToqKiBUcmFuc2Zvcm3DoWNpYSAqKmxvZyhWb2Rpdm9zxaUpKiogemphdm5lIHN0YWJpbGl6dWplIHJvenB0eWwgYSB2aXp1w6FsbmUgbmV2aWTDrW1lIHbDvXpuYW1uw70gdsO9dm9qIMWhdHZvcmNvdiByZXrDrWR1w60gcyB2eXN2ZXTEvnVqw7pjaW1pIHByZW1lbm7DvW1pLiBQcmUgw7pwbG5vc8WlIGplIHZob2Ruw6kgdGVudG8gZG9qZW0gcG90dnJkacWlIGZvcm3DoWxueW0gdGVzdG9tIChuYXByLiAqKkJyZXVzY2jigJNQYWdhbi9Lb2Vua2Vy4oCTQmFzc2V0dCoqKSBhIHJlcG9ydG92YcWlIGluZmVyZW5jaXUgcyAqKnJvYnVzdG7DvW1pIChIQzEpKiogY2h5YmFtaS4KCiMjIFRlc3RvdmFuaWUgcHLDrXRvbW5vc3RpIGhldGVyb3NrZWRhc3RpY2l0eQoKTmFqcHJ2IG90ZXN0dWplbWUgcHLDrXRvbW5vc8WlIGhldGVyb3NrZWRhc3RpY2l0eSBwb21vY291ICoqQnJldXNjaOKAk1BhZ2FuKiogdGVzdHUgKMWhdHVkZW50aXpvdmFuw6EgdmVyemlhID0gS29lbmtlcuKAk0Jhc3NldHQpLiAgCk7DoXNsZWRuZSDigJMgYWsgYnkgaGV0ZXJvc2tlZGFzdGljaXRhIHByZXRydsOhdmFsYSDigJMgcmVwb3J0dWplbWUgb2RoYWR5IHMgKipXaGl0ZS9IQy1yb2J1c3Ruw71taSoqIHNtZXJvZGFqbsO9bWkgY2h5YmFtaSAodHlwICoqSEMxKiopLgpgYGB7cn0KbTEgPC0gaWYgKGV4aXN0cygibW9kZWxfaCIpKSBtb2RlbF9oIGVsc2UgaWYgKGV4aXN0cygibW9kZWwiKSkgbW9kZWwgZWxzZSBzdG9wKCJNb2RlbCBtMSBuZWV4aXN0dWplLiIpCm0yIDwtIGlmIChleGlzdHMoIm1vZGVsMl9oIikpIG1vZGVsMl9oIGVsc2UgaWYgKGV4aXN0cygibW9kZWwyIikpIG1vZGVsMiBlbHNlIHN0b3AoIk1vZGVsIG0yIG5lZXhpc3R1amUuIikKCmxpYnJhcnkobG10ZXN0KQoKI0JyZXVzY2jigJNQYWdhbiAoS29lbmtlcuKAk0Jhc3NldHQpIHByZSBvYmEgbW9kZWx5CgpicF9tMSA8LSBicHRlc3QobTEsIHN0dWRlbnRpemUgPSBUUlVFKQpicF9tMiA8LSBicHRlc3QobTIsIHN0dWRlbnRpemUgPSBUUlVFKQoKYnBfbTEKYnBfbTIKYGBgCk5hIHrDoWtsYWRlIHbDvXNsZWRrb3YgcmVncmVzaWUgbcO0xb5lbWUgcG92ZWRhxaUsIMW+ZSAqKmhldGVyb3NrZWRhc3RpY2l0YSByZXrDrWR1w60gbmllIGplIHYgbW9kZWxpIGBtMmAgcHLDrXRvbW7DoSoqLCB6YXRpYcS+IMSNbyB2IHByw61wYWRlICoqbW9kZWx1IGBtMWAgcHLDrXRvbW7DoSBqZSoqLiBBayBieSB2xaFhayBoZXRlcm9za2VkYXN0aWNpdGEgcHJldHJ2w6F2YWxhIGEgKipsb2dhcml0bWl6w6FjaWEgcHJlbWVubsO9Y2gqKiBhbGVibyAqKm9kc3Ryw6FuZW5pZSBvZMS+YWhsw71jaCBob2Ruw7R0KiogbmVwb21vaGxpLCBtw7TFvmVtZSBqdSBvxaFldHJpxaUgcG9tb2NvdSB0enYuICoqV2hpdGUgaGV0ZXJvc2tlZGFzdGljaXR5LWNvbnNpc3RlbnQgbWF0aWNlKiogKEhDKSwga2RlIHNhIHYgKnQqLXRlc3RvY2ggdsO9em5hbW5vc3RpIHJlZ3Jlc27DvWNoIGtvZWZpY2llbnRvdiBwb3XFvsOtdmFqw7og4oCeaHJ1YsWhaWXigJwgKHJvYnVzdG7DqSkgb2RoYWR5IHJvenB0eWxvdi4gUG9zdHVwIGplIHBvdG9tIHphbG/FvmVuw70gbmEgb2RoYWRvY2ggcyAqKkhDMS9IQzMqKiDFoXRhbmRhcmRuw71taSBjaHliYW1pLgoKKipWw71zbGVka3kgQlAgKEtvZW5rZXLigJNCYXNzZXR0KSB0ZXN0dToqKgoKLSAqKm0xOioqIFwocCA9IDAuMDM3OCA8IDAuMDVcKSDihpIgKip6YW1pZXRhbWUgSOKCgCoqIG5hIDUgJSBobGFkaW5lLiBWIHDDtHZvZG5vbSBtb2RlbGkgc8O6IGTDtGthenkgKipoZXRlcm9za2VkYXN0aWNpdHkqKi4gIAotICoqbTI6KiogXChwID0gMC4wNjkwID4gMC4wNVwpICgqYWxlKiBcKDwgMC4xMFwpKSDihpIgbmEgNSAlIGhsYWRpbmUgKipI4oKAIG5lemFtaWV0YW1lKiosIG5hIDEwICUgamUgdG8gKipocmFuacSNbsOpKiouICoqTG9nLXRyYW5zZm9ybcOhY2lhIHZvZGl2b3N0aSoqIHRlZGEgaGV0ZXJvc2tlZGFzdGljaXR1ICoqem7DrcW+aWxhKiouCgoKYGBge3J9CiMgUm9idXN0bsOpIChoZXRlcm9za2VkYXN0aWNpdHktY29uc2lzdGVudCkgY2h5Ynkg4oCTIEhDMQoKbGlicmFyeShzYW5kd2ljaCkKCmNhdCgiXG5Sb2J1c3Ruw6kgKEhDMSkgdC10ZXN0eSBrb2VmaWNpZW50b3Yg4oCTIG0xOlxuIikKY29lZnRlc3QobTEsIHZjb3YgPSB2Y292SEMobTEsIHR5cGUgPSAiSEMxIikpCgpgYGAKVsWhaW1uaW1lIHNpLCDFvmUgcG8gcG91xb5pdMOtICoqcm9idXN0bsO9Y2ggKEhDKSoqIHNtZXJvZGFqbsO9Y2ggY2jDvWIgdnljaMOhZHphasO6IGFrbyDFoXRhdGlzdGlja3kgdsO9em5hbW5lIHNwb2plbsOpIHMgcEjigKZNYXggbmFqbcOkIHByZW1lbm7DqSAqKlRlcGxvdGEgKOKAkykqKiwgKipSb3pwdXN0ZW7DvSBP4oKCICgrKSoqLCAqKlZvZGl2b3PFpSAoKykqKiBhICoqTml0cmF0ZU4gKCspKiouIFByZW1lbm7DoSAqKkJPRCoqIMWhdGF0aXN0aWNreSB2w716bmFtbsOhIG5pZSBqZSBhICoqRmVrw6FsbmUga29saWZvcm15Kiogc8O6IGxlbiAqKmhyYW5pxI1uZSB2w716bmFtbsOpKiogKOKJiCAxMCAlIGhsYWRpbmEpLiBUbyBqZSB2IHPDumxhZGUgcyB0w71tLCDFvmUgcm9idXN0bsOpIGNoeWJ5IOKAnnNwcsOtc25pYeKAnCBpbmZlcmVuY2l1IHYgcHLDrXRvbW5vc3RpIGhldGVyb3NrZWRhc3RpY2l0eS4gTmEgZHJ1aGVqIHN0cmFuZSB0cmViYSBwb2RvdGtuw7rFpSwgxb5lIHBvdcW+aXRpZSB0ZWp0byBtZXTDs2R5IGplIG5hanNwb8S+YWhsaXZlasWhaWUgcHJpIHbDpMSNxaHDrWNoIHbDvWJlcm9jaCAob3JpZW50YcSNbmUgKio+IDEwMCBwb3pvcm92YW7DrSoqKS4KCg==