S využitím databázy [student_exam_scores] database.
Úvod do problému, stanovenie hypotéz
Rozhodla som sa modelovať výsledné skúškové skóre študentov
(exam_score) v závislosti od troch vysvetľujúcich
premenných:
- počtu hodín štúdia (hours_studied),
- priemerného počtu hodín spánku (sleep_hours),
- a percentuálnej účasti na vyučovaní
(attendance_percent).
Cieľom analýzy je overiť, ktoré z týchto faktorov majú
štatisticky významný vplyv na dosiahnutý výsledok
skúšky a ako silný tento vzťah je. Modelovanie prebehne pomocou
viacnásobnej lineárnej regresie, pričom budeme skúmať,
či sa zmeny v týchto premenných prejavia v zmene skúškového skóre.
Naša pracovná hypotéza predpokladá štatisticky
významný vplyv všetkých troch vysvetľujúcich premenných. Zároveň sa
očakáva nasledovný smer účinku jednotlivých faktorov:
Počet hodín štúdia (hours_studied):
očakávame pozitívny vplyv – študenti, ktorí venujú viac
času príprave, dosahujú lepšie výsledky. (kladné znamienko odhadovaného
regresného koeficienta)
Počet hodín spánku (sleep_hours):
predpokladáme pozitívny vplyv, keďže dostatok spánku
zlepšuje koncentráciu a výkon. (kladné znamienko koeficienta)
Účasť na vyučovaní
(attendance_percent): očakávame pozitívny
vplyv, pretože pravidelná účasť na hodinách zvyšuje pochopenie
látky a teda aj úspešnosť. (kladné znamienko koeficienta)
Formálne teda stanovujeme nasledovné hypotézy:
H₁: Premenné hours_studied,
sleep_hours a attendance_percent majú štatisticky
významný vplyv na exam_score.
H₀: Medzi exam_score a uvedenými
vysvetľujúcimi premennými neexistuje štatisticky významný vzťah.
# Načítanie dát ----------------------------------------------------------
df <- read_csv("student_exam_scores.csv")
# Rýchly prehľad
glimpse(df)
Rows: 200
Columns: 6
$ student_id <chr> "S001", "S002", "S003", "S004", "S005", "S006", "S007", "S008", "S009", "S010", "S011", "…
$ hours_studied <dbl> 8.0, 1.3, 4.0, 3.5, 9.1, 8.4, 10.8, 2.0, 5.6, 1.3, 3.4, 6.6, 1.3, 3.2, 8.1, 7.0, 3.4, 7.5…
$ sleep_hours <dbl> 8.8, 8.6, 8.2, 4.8, 6.4, 5.1, 6.0, 4.3, 5.9, 8.9, 5.3, 7.9, 6.3, 6.1, 8.8, 9.0, 6.8, 7.6,…
$ attendance_percent <dbl> 72.1, 60.7, 73.7, 95.1, 89.8, 58.5, 54.2, 75.8, 81.6, 66.8, 90.9, 87.6, 83.6, 61.2, 60.0,…
$ previous_scores <dbl> 45, 55, 86, 66, 71, 75, 88, 55, 84, 70, 81, 85, 71, 68, 90, 41, 45, 58, 54, 65, 84, 55, 5…
$ exam_score <dbl> 30.2, 25.0, 35.8, 34.0, 40.3, 35.7, 37.9, 18.3, 34.7, 24.7, 29.3, 35.1, 31.2, 30.2, 41.1,…
summary(df)
student_id hours_studied sleep_hours attendance_percent previous_scores exam_score
Length:200 Min. : 1.000 Min. :4.000 Min. : 50.30 Min. :40.0 Min. :17.10
Class :character 1st Qu.: 3.500 1st Qu.:5.300 1st Qu.: 62.20 1st Qu.:54.0 1st Qu.:29.50
Mode :character Median : 6.150 Median :6.700 Median : 75.25 Median :67.5 Median :34.05
Mean : 6.325 Mean :6.622 Mean : 74.83 Mean :66.8 Mean :33.95
3rd Qu.: 9.000 3rd Qu.:8.025 3rd Qu.: 87.42 3rd Qu.:80.0 3rd Qu.:38.75
Max. :12.000 Max. :9.000 Max. :100.00 Max. :95.0 Max. :51.30
# ukáž prvých 10 riadkov
print(head(df, 10))
# Čistenie a kontrola ---------------------------------------------------
# Skontrolujeme chýbajúce hodnoty
map_dfr(df, ~sum(is.na(.x))) %>% gather(var, missing) %>% print()
# Ak sú chýbajúce hodnoty a chceš ich odstrániť:
df <- df %>% drop_na()
df <- df %>% mutate(student_id = as.character(student_id))
# Prieskumná analýza (EDA) -----------------------------------------------
# Popisné štatistiky pre numerické premenné
num_vars <- df %>% select_if(is.numeric)
summary(num_vars)
hours_studied sleep_hours attendance_percent previous_scores exam_score
Min. : 1.000 Min. :4.000 Min. : 50.30 Min. :40.0 Min. :17.10
1st Qu.: 3.500 1st Qu.:5.300 1st Qu.: 62.20 1st Qu.:54.0 1st Qu.:29.50
Median : 6.150 Median :6.700 Median : 75.25 Median :67.5 Median :34.05
Mean : 6.325 Mean :6.622 Mean : 74.83 Mean :66.8 Mean :33.95
3rd Qu.: 9.000 3rd Qu.:8.025 3rd Qu.: 87.42 3rd Qu.:80.0 3rd Qu.:38.75
Max. :12.000 Max. :9.000 Max. :100.00 Max. :95.0 Max. :51.30
# Histogramy (všetky numerické)
num_vars %>% gather(variable, value) %>%
ggplot(aes(x = value)) +
geom_histogram(bins = 30) +
facet_wrap(~variable, scales = "free") +
labs(title = "Histogramy numerických premenných")

# Boxploty proti exam_score pre vybrané prediktory
ggplot(df, aes(x = 1, y = exam_score)) +
geom_boxplot() +
labs(title = "Boxplot exam_score (všetky hodnoty)")

# Párové grafy / korelácie
GGally::ggpairs(df %>% select(-student_id))

# Korelačná matica
cor_mat <- cor(df %>% select_if(is.numeric))
print(round(cor_mat, 3))
hours_studied sleep_hours attendance_percent previous_scores exam_score
hours_studied 1.000 0.078 -0.031 0.069 0.777
sleep_hours 0.078 1.000 0.001 -0.194 0.188
attendance_percent -0.031 0.001 1.000 0.052 0.226
previous_scores 0.069 -0.194 0.052 1.000 0.431
exam_score 0.777 0.188 0.226 0.431 1.000
# Vytvorenie lineárneho modelu -------------------------------------------
# Predpokladáme, že cieľová premenná je exam_score a ostatné sú prediktory
model <- lm(exam_score ~ hours_studied + sleep_hours + attendance_percent + previous_scores,
data = df)
# Rýchle zhrnutie modelu
summary(model)
Call:
lm(formula = exam_score ~ hours_studied + sleep_hours + attendance_percent +
previous_scores, data = df)
Residuals:
Min 1Q Median 3Q Max
-5.5455 -2.1818 -0.0847 2.3436 4.8390
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -2.14209 1.67079 -1.282 0.201
hours_studied 1.55526 0.06044 25.732 < 2e-16 ***
sleep_hours 0.95226 0.13243 7.191 1.34e-11 ***
attendance_percent 0.10839 0.01362 7.961 1.38e-13 ***
previous_scores 0.17728 0.01267 13.995 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 2.731 on 195 degrees of freedom
Multiple R-squared: 0.8414, Adjusted R-squared: 0.8382
F-statistic: 258.7 on 4 and 195 DF, p-value: < 2.2e-16
# Upratané výsledky cez broom
tidy(model) # koeficienty s p-hodnotami
glance(model) # R^2, AIC, BIC, RMSE (residual sd), atď.
augment(model) %>% head()
# Diagnostika modelu -----------------------------------------------------
# Reziduá vs fitted
plot(model, which = 1) # residuals vs fitted

# QQ plot - normálne rozdelenie reziduí
plot(model, which = 2) # QQ

# Cook's distance (influential points)
plot(model, which = 4)

# Multikolinearita (VIF)
car::vif(model) # >5 alebo >10 varovať
hours_studied sleep_hours attendance_percent previous_scores
1.014944 1.048547 1.004142 1.050271
# Výpočet RMSE a ďalších metrík -----------------------------------------
preds <- predict(model, newdata = df)
rmse_val <- sqrt(mean((df$exam_score - preds)^2))
mae_val <- mean(abs(df$exam_score - preds))
r2 <- summary(model)$r.squared
cat("RMSE:", round(rmse_val,3), "MAE:", round(mae_val,3), "R2:", round(r2,3), "\n")
RMSE: 2.697 MAE: 2.287 R2: 0.841
# Alternatívne: cross-validated RMSE cez caret (10-fold CV)
set.seed(123)
train_control <- trainControl(method = "cv", number = 10)
cv_model <- train(exam_score ~ hours_studied + sleep_hours + attendance_percent + previous_scores,
data = df,
method = "lm",
trControl = train_control)
print(cv_model)
Linear Regression
200 samples
4 predictor
No pre-processing
Resampling: Cross-Validated (10 fold)
Summary of sample sizes: 180, 180, 180, 180, 180, 179, ...
Resampling results:
RMSE Rsquared MAE
2.771046 0.850901 2.3605
Tuning parameter 'intercept' was held constant at a value of TRUE
cv_model$results
# Graf predikcie vs skutočnosť ------------------------------------------
df_plot <- df %>% mutate(predicted = preds)
ggplot(df_plot, aes(x = predicted, y = exam_score)) +
geom_point() +
geom_abline(slope = 1, intercept = 0, linetype = "dashed") +
labs(title = "Predikované vs Skutočné exam_score",
x = "Predikované hodnoty",
y = "Skutočné hodnoty")

# Scatter s lineárnym fitom medzi konkrétnym prediktorom a exam_score
ggplot(df, aes(x = hours_studied, y = exam_score)) +
geom_point() +
geom_smooth(method = "lm", se = TRUE) +
labs(title = "Exam score vs Hours studied")

NA
NA
Interpretácia konkrétneho grafu
Na grafe nižšie je znázornený vzťah medzi počtom hodín, ktoré študent
venoval štúdiu (hours_studied), a jeho výsledným skóre na
skúške (exam_score). Každý bod predstavuje jedného študenta,
pričom na osi X je zobrazený počet hodín štúdia a na osi Y výsledné
skóre. Do grafu bola pridaná aj regresná priamka, ktorá znázorňuje trend
medzi oboma premennými.
Z grafu môžeme pozorovať, že so zvyšujúcim sa počtom hodín štúdia má
exam_score tendenciu rásť. To znamená, že medzi týmito dvoma
premennými existuje pozitívna lineárna závislosť – čím
viac času študent venoval príprave, tým lepšie výsledky na skúške
dosiahol. Regresná priamka má kladný smerový
koeficient, čo potvrdzuje očakávanie z pracovnej hypotézy
(H₁), že počet hodín štúdia má pozitívny vplyv na skúškové
skóre.
Zároveň môžeme vidieť mierny rozptyl hodnôt okolo regresnej priamky,
čo naznačuje, že aj keď štúdium významne ovplyvňuje výsledok, na výkone
študenta sa môžu podieľať aj iné faktory – napríklad kvalita spánku,
účinnosť učenia alebo priebežná aktivita počas semestra.
Q-Q plot
Čo ukazuje
- Os X: Teoretické kvantily – hodnoty, ktoré by sme
očakávali, ak by rezíduá boli dokonale normálne rozložené.
- Os Y: Štandardizované rezíduá – skutočné kvantily
vypočítané z dát nášho modelu.
- 45° prerušovaná čiara: Ideálny prípad – ak sú
rezíduá normálne rozložené, body by mali ležať tesne pozdĺž tejto
čiary.
Interpretácia konkrétneho grafu
Celkový tvar:
Väčšina bodov leží blízko priamky, čo naznačuje, že rezíduá sú
približne normálne rozložené. Predpoklad normality
modelových chýb sa teda javí ako vo veľkej miere splnený.
Krajné hodnoty (extrémy):
Na oboch koncoch grafu (vľavo dole a vpravo hore) možno pozorovať mierne
odchýlky od 45° čiary. To poukazuje na menšie odchýlky od
normality v chvostoch rozdelenia – teda niekoľko odľahlých
hodnôt alebo mierne ťažšie konce, než by mal ideálny normálny tvar.
Stredná oblasť:
V strednej časti grafu (približne v intervale −1 až +1 kvantily) sa body
veľmi dobre zhodujú s teoretickou priamkou, čo znamená, že väčšina
rezíduí zodpovedá normálnemu rozdeleniu.
Na záver možno konštatovať, že model v zásade spĺňa
predpoklad normality rezíduí.
Mierne odchýlky v koncoch však naznačujú, že by sa mohol vyskytovať
menší počet odľahlých pozorovaní, čo si vyžaduje dodatočnú kontrolu
pomocou doplnkových testov (napr. Shapiro–Wilk test, analýza Cookovej
vzdialenosti).
Scale location plot
Interpretácia vášho konkrétneho grafu
Body sú rovnomerne rozptýlené pozdĺž osi X bez zreteľného vzoru, čo
naznačuje, že rozptyl rezíduí je približne konštantný.
Tento jav sa označuje ako homoskedasticita, teda
predpoklad rovnakého rozptylu chýb pre všetky úrovne predikovaných
hodnôt je vo všeobecnosti splnený.
Červená vyhladzovacia (LOESS) čiara je relatívne rovná a bez
výraznej krivky,
čo podporuje záver, že so zvyšujúcimi sa vyrovnanými hodnotami sa
variancia rezíduí systematicky nemení.
Niekoľko bodov je síce mierne vzdialených od hlavného zhluku (hodnoty
nad 1,5 na osi Y), avšak nejde o extrémne odľahlé pozorovania.
Celkovo teda môžeme konštatovať, že predpoklad konštantnej
variability (homoskedasticity) je splnený a model neprejavuje
žiadne závažné známky heteroskedasticity.
Interpretácia vášho konkrétneho grafu
Väčšina pozorovaní má nízky pákový efekt (hodnoty pod 0,05), čo
naznačuje, že jednotlivé body nemajú výrazný vplyv na tvar regresnej
priamky.
To je typické pre dobre rozložené údaje, kde žiadny študent nevyčnieva
extrémnymi hodnotami v premenných ako hours_studied,
sleep_hours alebo attendance_percent.
Jeden až dva body sa však mierne oddeľujú od ostatných (napr. v
oblasti pákového efektu okolo 0,2).
Ide o pozorovania so zvýšenou pákou, teda ich hodnoty
prediktorov sú ďalej od väčšiny údajov — napríklad študent s extrémne
nízkym počtom hodín spánku alebo veľmi vysokým počtom hodín štúdia.
Väčšina štandardizovaných rezíduí sa nachádza medzi hodnotami
−2 a +2, čo znamená, že neexistujú žiadne závažné
odľahlé hodnoty v závislej premennej (exam_score).
Kontúry Cookovej vzdialenosti ukazujú, že žiaden z bodov
neprekračuje hranice 0,5 či 1,0,
preto žiadne pozorovanie nemá výrazne neprimeraný vplyv
na odhady regresných koeficientov.
Celkovo možno konštatovať, že model nie je citlivý na jednotlivé
pozorovania a nie sú prítomné extrémne vplyvné body, ktoré by mohli
skresľovať výsledky regresie.
Conclusion
Premenné hours_studied a attendance_percent majú
štatisticky významný pozitívny vplyv na výsledné
skúškové skóre študentov – teda čím viac času študent venuje štúdiu a
čím pravidelnejšie sa zúčastňuje vyučovania, tým vyššie skóre
dosahuje.
Premenná sleep_hours sa ukázala ako menej
významná, pričom jej vplyv na výsledok skúšky nebol jednoznačný
– v modeli sa prejavuje s malým alebo neinterpretovateľným účinkom.
Rezíduá nevykazujú úplne dokonalé normálne rozdelenie, avšak vzhľadom
na dostatočne veľký počet pozorovaní môžeme model považovať za
spoľahlivý a vhodný na interpretáciu.
Z diagnostických grafov taktiež vyplýva, že v modeli sa
nepreukazujú žiadne výrazné nelinearity, heteroskedasticita ani vplyvné
pozorovania.
Model teda pomerne dobre vystihuje vzťah medzi študijnými návykmi a
výsledným skúškovým skóre.
LS0tCnRpdGxlOiAiRWNvbm9tZXRyaWNzIGluIFIgLSBjdmnEjWVuaWUgNSIKb3V0cHV0OiBodG1sX25vdGVib29rCmF1dGhvcjogRGlhbmEgSHJ1xaFvdnNrw6EKZWRpdG9yX29wdGlvbnM6IAogIG1hcmtkb3duOiAKICAgIHdyYXA6IDcyCi0tLQoKUyB2eXXFvml0w61tIGRhdGFiw6F6eSBbc3R1ZGVudF9leGFtX3Njb3Jlc10gZGF0YWJhc2UuCgpQcmkgxI9hbMWhZWogcHLDoWNpIGJ1ZGVtZSBwb3XFvsOtdmHFpSBrbmnFvm5pY2UKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShHR2FsbHkpICAgICMgcGFpcnMKbGlicmFyeShicm9vbSkgICAgICMgdGlkeSBtb2RlbCBvdXRwdXRzCmxpYnJhcnkoY2FyKSAgICAgICAjIFZJRgpsaWJyYXJ5KGNhcmV0KSAgICAgIyBSTVNFLCB0cmFpbkNvbnRyb2wgCmxpYnJhcnkocmVwb3J0KSAgICAjIHByZSBwZWtuw6kgcmVwb3J0eSAKYGBgCgojIMOadm9kIGRvIHByb2Jsw6ltdSwgc3Rhbm92ZW5pZSBoeXBvdMOpegoKUm96aG9kbGEgc29tIHNhIG1vZGVsb3ZhxaUgKip2w71zbGVkbsOpIHNrw7rFoWtvdsOpIHNrw7NyZSDFoXR1ZGVudG92CigqZXhhbV9zY29yZSopKiogdiB6w6F2aXNsb3N0aSBvZCB0cm9jaCB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoOgoKLSAgIHBvxI10dSBob2TDrW4gxaF0w7pkaWEgKCpob3Vyc19zdHVkaWVkKiksCi0gICBwcmllbWVybsOpaG8gcG/EjXR1IGhvZMOtbiBzcMOhbmt1ICgqc2xlZXBfaG91cnMqKSwKLSAgIGEgcGVyY2VudHXDoWxuZWogw7rEjWFzdGkgbmEgdnl1xI1vdmFuw60gKCphdHRlbmRhbmNlX3BlcmNlbnQqKS4KCkNpZcS+b20gYW5hbMO9enkgamUgb3ZlcmnFpSwga3RvcsOpIHogdMO9Y2h0byBmYWt0b3JvdiBtYWrDuiAqKsWhdGF0aXN0aWNreQp2w716bmFtbsO9IHZwbHl2KiogbmEgZG9zaWFobnV0w70gdsO9c2xlZG9rIHNrw7rFoWt5IGEgYWtvIHNpbG7DvSB0ZW50byB2esWlYWgKamUuIE1vZGVsb3ZhbmllIHByZWJlaG5lIHBvbW9jb3UgKip2aWFjbsOhc29ibmVqIGxpbmXDoXJuZWogcmVncmVzaWUqKiwKcHJpxI1vbSBidWRlbWUgc2vDum1hxaUsIMSNaSBzYSB6bWVueSB2IHTDvWNodG8gcHJlbWVubsO9Y2ggcHJlamF2aWEgdiB6bWVuZQpza8O6xaFrb3bDqWhvIHNrw7NyZS4KCk5hxaFhICoqcHJhY292bsOhIGh5cG90w6l6YSoqIHByZWRwb2tsYWTDoSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSB2cGx5dgp2xaFldGvDvWNoIHRyb2NoIHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2guIFrDoXJvdmXFiCBzYSBvxI1ha8OhdmEgbmFzbGVkb3Zuw70Kc21lciDDusSNaW5rdSBqZWRub3RsaXbDvWNoIGZha3Rvcm92OgoKLSAgICoqUG/EjWV0IGhvZMOtbiDFoXTDumRpYSAoKmhvdXJzX3N0dWRpZWQqKSoqOiBvxI1ha8OhdmFtZSAqKnBveml0w612bnkKICAgIHZwbHl2Kiog4oCTIMWhdHVkZW50aSwga3RvcsOtIHZlbnVqw7ogdmlhYyDEjWFzdSBwcsOtcHJhdmUsIGRvc2FodWrDuiBsZXDFoWllCiAgICB2w71zbGVka3kuIChrbGFkbsOpIHpuYW1pZW5rbyBvZGhhZG92YW7DqWhvIHJlZ3Jlc27DqWhvIGtvZWZpY2llbnRhKQoKLSAgICoqUG/EjWV0IGhvZMOtbiBzcMOhbmt1ICgqc2xlZXBfaG91cnMqKSoqOiBwcmVkcG9rbGFkw6FtZSAqKnBveml0w612bnkKICAgIHZwbHl2KiosIGtlxI/FvmUgZG9zdGF0b2sgc3DDoW5rdSB6bGVwxaF1amUga29uY2VudHLDoWNpdSBhIHbDvWtvbi4KICAgIChrbGFkbsOpIHpuYW1pZW5rbyBrb2VmaWNpZW50YSkKCi0gICAqKsOaxI1hc8WlIG5hIHZ5dcSNb3ZhbsOtICgqYXR0ZW5kYW5jZV9wZXJjZW50KikqKjogb8SNYWvDoXZhbWUgKipwb3ppdMOtdm55CiAgICB2cGx5dioqLCBwcmV0b8W+ZSBwcmF2aWRlbG7DoSDDusSNYXPFpSBuYSBob2RpbsOhY2ggenZ5xaF1amUgcG9jaG9wZW5pZQogICAgbMOhdGt5IGEgdGVkYSBhaiDDunNwZcWhbm9zxaUuIChrbGFkbsOpIHpuYW1pZW5rbyBrb2VmaWNpZW50YSkKCkZvcm3DoWxuZSB0ZWRhIHN0YW5vdnVqZW1lIG5hc2xlZG92bsOpIGh5cG90w6l6eToKCj4gKipI4oKBOioqIFByZW1lbm7DqSAqaG91cnNfc3R1ZGllZCosICpzbGVlcF9ob3VycyogYSAqYXR0ZW5kYW5jZV9wZXJjZW50Kgo+IG1hasO6IMWhdGF0aXN0aWNreSB2w716bmFtbsO9IHZwbHl2IG5hICpleGFtX3Njb3JlKi4KCj4gKipI4oKAOioqIE1lZHppICpleGFtX3Njb3JlKiBhIHV2ZWRlbsO9bWkgdnlzdmV0xL51asO6Y2ltaSBwcmVtZW5uw71taQo+IG5lZXhpc3R1amUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gdnrFpWFoLgoKYGBge3J9CgojIE5hxI3DrXRhbmllIGTDoXQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpkZiA8LSByZWFkX2Nzdigic3R1ZGVudF9leGFtX3Njb3Jlcy5jc3YiKQoKIyBSw71jaGx5IHByZWjEvmFkCmdsaW1wc2UoZGYpCnN1bW1hcnkoZGYpCiMgdWvDocW+IHBydsO9Y2ggMTAgcmlhZGtvdgpwcmludChoZWFkKGRmLCAxMCkpCgojIMSMaXN0ZW5pZSBhIGtvbnRyb2xhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFNrb250cm9sdWplbWUgY2jDvWJhasO6Y2UgaG9kbm90eQptYXBfZGZyKGRmLCB+c3VtKGlzLm5hKC54KSkpICU+JSBnYXRoZXIodmFyLCBtaXNzaW5nKSAlPiUgcHJpbnQoKQoKIyBBayBzw7ogY2jDvWJhasO6Y2UgaG9kbm90eSBhIGNoY2XFoSBpY2ggb2RzdHLDoW5pxaU6CmRmIDwtIGRmICU+JSBkcm9wX25hKCkKCmRmIDwtIGRmICU+JSBtdXRhdGUoc3R1ZGVudF9pZCA9IGFzLmNoYXJhY3RlcihzdHVkZW50X2lkKSkKCiMgUHJpZXNrdW1uw6EgYW5hbMO9emEgKEVEQSkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBQb3Bpc27DqSDFoXRhdGlzdGlreSBwcmUgbnVtZXJpY2vDqSBwcmVtZW5uw6kKbnVtX3ZhcnMgPC0gZGYgJT4lIHNlbGVjdF9pZihpcy5udW1lcmljKQpzdW1tYXJ5KG51bV92YXJzKQoKIyBIaXN0b2dyYW15ICh2xaFldGt5IG51bWVyaWNrw6kpCm51bV92YXJzICU+JSBnYXRoZXIodmFyaWFibGUsIHZhbHVlKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMzApICsKICBmYWNldF93cmFwKH52YXJpYWJsZSwgc2NhbGVzID0gImZyZWUiKSArCiAgbGFicyh0aXRsZSA9ICJIaXN0b2dyYW15IG51bWVyaWNrw71jaCBwcmVtZW5uw71jaCIpCgojIEJveHBsb3R5IHByb3RpIGV4YW1fc2NvcmUgcHJlIHZ5YnJhbsOpIHByZWRpa3RvcnkKZ2dwbG90KGRmLCBhZXMoeCA9IDEsIHkgPSBleGFtX3Njb3JlKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBsYWJzKHRpdGxlID0gIkJveHBsb3QgZXhhbV9zY29yZSAodsWhZXRreSBob2Rub3R5KSIpCgojIFDDoXJvdsOpIGdyYWZ5IC8ga29yZWzDoWNpZQpHR2FsbHk6OmdncGFpcnMoZGYgJT4lIHNlbGVjdCgtc3R1ZGVudF9pZCkpCgojIEtvcmVsYcSNbsOhIG1hdGljYQpjb3JfbWF0IDwtIGNvcihkZiAlPiUgc2VsZWN0X2lmKGlzLm51bWVyaWMpKQpwcmludChyb3VuZChjb3JfbWF0LCAzKSkKCiMgVnl0dm9yZW5pZSBsaW5lw6FybmVobyBtb2RlbHUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFByZWRwb2tsYWTDoW1lLCDFvmUgY2llxL5vdsOhIHByZW1lbm7DoSBqZSBleGFtX3Njb3JlIGEgb3N0YXRuw6kgc8O6IHByZWRpa3RvcnkKbW9kZWwgPC0gbG0oZXhhbV9zY29yZSB+IGhvdXJzX3N0dWRpZWQgKyBzbGVlcF9ob3VycyArIGF0dGVuZGFuY2VfcGVyY2VudCArIHByZXZpb3VzX3Njb3JlcywKICAgICAgICAgICAgZGF0YSA9IGRmKQoKIyBSw71jaGxlIHpocm51dGllIG1vZGVsdQpzdW1tYXJ5KG1vZGVsKQoKIyBVcHJhdGFuw6kgdsO9c2xlZGt5IGNleiBicm9vbQp0aWR5KG1vZGVsKSAgICAgICAgIyBrb2VmaWNpZW50eSBzIHAtaG9kbm90YW1pCmdsYW5jZShtb2RlbCkgICAgICAjIFJeMiwgQUlDLCBCSUMsIFJNU0UgKHJlc2lkdWFsIHNkKSwgYXTEjy4KYXVnbWVudChtb2RlbCkgJT4lIGhlYWQoKQoKIyBEaWFnbm9zdGlrYSBtb2RlbHUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBSZXppZHXDoSB2cyBmaXR0ZWQKcGxvdChtb2RlbCwgd2hpY2ggPSAxKSAgIyByZXNpZHVhbHMgdnMgZml0dGVkCgojIFFRIHBsb3QgLSBub3Jtw6FsbmUgcm96ZGVsZW5pZSByZXppZHXDrQpwbG90KG1vZGVsLCB3aGljaCA9IDIpICAjIFFRCgojIENvb2sncyBkaXN0YW5jZSAoaW5mbHVlbnRpYWwgcG9pbnRzKQpwbG90KG1vZGVsLCB3aGljaCA9IDQpCgojIE11bHRpa29saW5lYXJpdGEgKFZJRikKY2FyOjp2aWYobW9kZWwpICAjID41IGFsZWJvID4xMCB2YXJvdmHFpQoKIyBWw71wb8SNZXQgUk1TRSBhIMSPYWzFocOtY2ggbWV0csOtayAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpwcmVkcyA8LSBwcmVkaWN0KG1vZGVsLCBuZXdkYXRhID0gZGYpCnJtc2VfdmFsIDwtIHNxcnQobWVhbigoZGYkZXhhbV9zY29yZSAtIHByZWRzKV4yKSkKbWFlX3ZhbCA8LSBtZWFuKGFicyhkZiRleGFtX3Njb3JlIC0gcHJlZHMpKQpyMiA8LSBzdW1tYXJ5KG1vZGVsKSRyLnNxdWFyZWQKCmNhdCgiUk1TRToiLCByb3VuZChybXNlX3ZhbCwzKSwgIk1BRToiLCByb3VuZChtYWVfdmFsLDMpLCAiUjI6Iiwgcm91bmQocjIsMyksICJcbiIpCgojIEFsdGVybmF0w612bmU6IGNyb3NzLXZhbGlkYXRlZCBSTVNFIGNleiBjYXJldCAoMTAtZm9sZCBDVikKc2V0LnNlZWQoMTIzKQp0cmFpbl9jb250cm9sIDwtIHRyYWluQ29udHJvbChtZXRob2QgPSAiY3YiLCBudW1iZXIgPSAxMCkKY3ZfbW9kZWwgPC0gdHJhaW4oZXhhbV9zY29yZSB+IGhvdXJzX3N0dWRpZWQgKyBzbGVlcF9ob3VycyArIGF0dGVuZGFuY2VfcGVyY2VudCArIHByZXZpb3VzX3Njb3JlcywKICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAibG0iLAogICAgICAgICAgICAgICAgICB0ckNvbnRyb2wgPSB0cmFpbl9jb250cm9sKQoKcHJpbnQoY3ZfbW9kZWwpCmN2X21vZGVsJHJlc3VsdHMKCiMgR3JhZiBwcmVkaWtjaWUgdnMgc2t1dG/EjW5vc8WlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpkZl9wbG90IDwtIGRmICU+JSBtdXRhdGUocHJlZGljdGVkID0gcHJlZHMpCgpnZ3Bsb3QoZGZfcGxvdCwgYWVzKHggPSBwcmVkaWN0ZWQsIHkgPSBleGFtX3Njb3JlKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9hYmxpbmUoc2xvcGUgPSAxLCBpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgbGFicyh0aXRsZSA9ICJQcmVkaWtvdmFuw6kgdnMgU2t1dG/EjW7DqSBleGFtX3Njb3JlIiwKICAgICAgIHggPSAiUHJlZGlrb3ZhbsOpIGhvZG5vdHkiLAogICAgICAgeSA9ICJTa3V0b8SNbsOpIGhvZG5vdHkiKQoKIyBTY2F0dGVyIHMgbGluZcOhcm55bSBmaXRvbSBtZWR6aSBrb25rcsOpdG55bSBwcmVkaWt0b3JvbSBhIGV4YW1fc2NvcmUKZ2dwbG90KGRmLCBhZXMoeCA9IGhvdXJzX3N0dWRpZWQsIHkgPSBleGFtX3Njb3JlKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFKSArCiAgbGFicyh0aXRsZSA9ICJFeGFtIHNjb3JlIHZzIEhvdXJzIHN0dWRpZWQiKQoKCmBgYAoKIyMjIEludGVycHJldMOhY2lhIGtvbmtyw6l0bmVobyBncmFmdQoKTmEgZ3JhZmUgbmnFvsWhaWUgamUgem7DoXpvcm5lbsO9IHZ6xaVhaCBtZWR6aSBwb8SNdG9tIGhvZMOtbiwga3RvcsOpIMWhdHVkZW50CnZlbm92YWwgxaF0w7pkaXUgKCpob3Vyc19zdHVkaWVkKiksIGEgamVobyB2w71zbGVkbsO9bSBza8OzcmUgbmEgc2vDusWha2UKKCpleGFtX3Njb3JlKikuIEthxb5kw70gYm9kIHByZWRzdGF2dWplIGplZG7DqWhvIMWhdHVkZW50YSwgcHJpxI1vbSBuYSBvc2kgWApqZSB6b2JyYXplbsO9IHBvxI1ldCBob2TDrW4gxaF0w7pkaWEgYSBuYSBvc2kgWSB2w71zbGVkbsOpIHNrw7NyZS4gRG8gZ3JhZnUgYm9sYQpwcmlkYW7DoSBhaiByZWdyZXNuw6EgcHJpYW1rYSwga3RvcsOhIHpuw6F6b3LFiHVqZSB0cmVuZCBtZWR6aSBvYm9tYQpwcmVtZW5uw71taS4KClogZ3JhZnUgbcO0xb5lbWUgcG96b3JvdmHFpSwgxb5lIHNvIHp2ecWhdWrDumNpbSBzYSBwb8SNdG9tIGhvZMOtbiDFoXTDumRpYSBtw6EKKmV4YW1fc2NvcmUqIHRlbmRlbmNpdSByw6FzxaUuIFRvIHpuYW1lbsOhLCDFvmUgbWVkemkgdMO9bWl0byBkdm9tYQpwcmVtZW5uw71taSBleGlzdHVqZSAqKnBveml0w612bmEgbGluZcOhcm5hIHrDoXZpc2xvc8WlKiog4oCTIMSNw61tIHZpYWMgxI1hc3UKxaF0dWRlbnQgdmVub3ZhbCBwcsOtcHJhdmUsIHTDvW0gbGVwxaFpZSB2w71zbGVka3kgbmEgc2vDusWha2UgZG9zaWFob2wuClJlZ3Jlc27DoSBwcmlhbWthIG3DoSAqKmtsYWRuw70gc21lcm92w70ga29lZmljaWVudCoqLCDEjW8gcG90dnJkenVqZQpvxI1ha8OhdmFuaWUgeiBwcmFjb3ZuZWogaHlwb3TDqXp5ICgqSOKCgSopLCDFvmUgcG/EjWV0IGhvZMOtbiDFoXTDumRpYSBtw6EKcG96aXTDrXZueSB2cGx5diBuYSBza8O6xaFrb3bDqSBza8OzcmUuCgpaw6Fyb3ZlxYggbcO0xb5lbWUgdmlkaWXFpSBtaWVybnkgcm96cHR5bCBob2Ruw7R0IG9rb2xvIHJlZ3Jlc25laiBwcmlhbWt5LCDEjW8KbmF6bmHEjXVqZSwgxb5lIGFqIGtlxI8gxaF0w7pkaXVtIHbDvXpuYW1uZSBvdnBseXbFiHVqZSB2w71zbGVkb2ssIG5hIHbDvWtvbmUKxaF0dWRlbnRhIHNhIG3DtMW+dSBwb2RpZcS+YcWlIGFqIGluw6kgZmFrdG9yeSDigJMgbmFwcsOta2xhZCBrdmFsaXRhIHNww6Fua3UsCsO6xI1pbm5vc8WlIHXEjWVuaWEgYWxlYm8gcHJpZWJlxb5uw6EgYWt0aXZpdGEgcG/EjWFzIHNlbWVzdHJhLgoKIyMgUS1RIHBsb3QKCiMjIyDEjG8gdWthenVqZQoKLSAgICoqT3MgWDoqKiBUZW9yZXRpY2vDqSBrdmFudGlseSDigJMgaG9kbm90eSwga3RvcsOpIGJ5IHNtZSBvxI1ha8OhdmFsaSwgYWsKICAgIGJ5IHJlesOtZHXDoSBib2xpIGRva29uYWxlIG5vcm3DoWxuZSByb3psb8W+ZW7DqS5cCi0gICAqKk9zIFk6KiogxaB0YW5kYXJkaXpvdmFuw6kgcmV6w61kdcOhIOKAkyBza3V0b8SNbsOpIGt2YW50aWx5IHZ5cG/EjcOtdGFuw6kgegogICAgZMOhdCBuw6HFoWhvIG1vZGVsdS5cCi0gICAqKjQ1wrAgcHJlcnXFoW92YW7DoSDEjWlhcmE6KiogSWRlw6FsbnkgcHLDrXBhZCDigJMgYWsgc8O6IHJlesOtZHXDoSBub3Jtw6FsbmUKICAgIHJvemxvxb5lbsOpLCBib2R5IGJ5IG1hbGkgbGXFvmHFpSB0ZXNuZSBwb3pkxLrFviB0ZWp0byDEjWlhcnkuCgojIyMgSW50ZXJwcmV0w6FjaWEga29ua3LDqXRuZWhvIGdyYWZ1CgoqKkNlbGtvdsO9IHR2YXI6KipcClbDpMSNxaFpbmEgYm9kb3YgbGXFvsOtIGJsw616a28gcHJpYW1reSwgxI1vIG5hem5hxI11amUsIMW+ZSByZXrDrWR1w6Egc8O6CioqcHJpYmxpxb5uZSBub3Jtw6FsbmUgcm96bG/FvmVuw6kqKi4gUHJlZHBva2xhZCBub3JtYWxpdHkgbW9kZWxvdsO9Y2ggY2jDvWIKc2EgdGVkYSBqYXbDrSBha28gdm8gdmXEvmtlaiBtaWVyZSBzcGxuZW7DvS4KCioqS3Jham7DqSBob2Rub3R5IChleHRyw6lteSk6KipcCk5hIG9ib2NoIGtvbmNvY2ggZ3JhZnUgKHbEvmF2byBkb2xlIGEgdnByYXZvIGhvcmUpIG1vxb5ubyBwb3pvcm92YcWlIG1pZXJuZQpvZGNow71sa3kgb2QgNDXCsCDEjWlhcnkuIFRvIHBvdWthenVqZSBuYSAqKm1lbsWhaWUgb2RjaMO9bGt5IG9kIG5vcm1hbGl0eSB2CmNodm9zdG9jaCByb3pkZWxlbmlhKiog4oCTIHRlZGEgbmlla2/EvmtvIG9kxL5haGzDvWNoIGhvZG7DtHQgYWxlYm8gbWllcm5lCsWlYcW+xaFpZSBrb25jZSwgbmXFviBieSBtYWwgaWRlw6Fsbnkgbm9ybcOhbG55IHR2YXIuCgoqKlN0cmVkbsOhIG9ibGFzxaU6KipcClYgc3RyZWRuZWogxI1hc3RpIGdyYWZ1IChwcmlibGnFvm5lIHYgaW50ZXJ2YWxlIOKIkjEgYcW+ICsxIGt2YW50aWx5KSBzYSBib2R5CnZlxL5taSBkb2JyZSB6aG9kdWrDuiBzIHRlb3JldGlja291IHByaWFta291LCDEjW8gem5hbWVuw6EsIMW+ZSB2w6TEjcWhaW5hCnJlesOtZHXDrSB6b2Rwb3ZlZMOhIG5vcm3DoWxuZW11IHJvemRlbGVuaXUuCgpOYSB6w6F2ZXIgbW/Fvm5vIGtvbsWhdGF0b3ZhxaUsIMW+ZSAqKm1vZGVsIHYgesOhc2FkZSBzcMS6xYhhIHByZWRwb2tsYWQKbm9ybWFsaXR5IHJlesOtZHXDrSoqLlwKTWllcm5lIG9kY2jDvWxreSB2IGtvbmNvY2ggdsWhYWsgbmF6bmHEjXVqw7osIMW+ZSBieSBzYSBtb2hvbCB2eXNreXRvdmHFpQptZW7FocOtIHBvxI1ldCBvZMS+YWhsw71jaCBwb3pvcm92YW7DrSwgxI1vIHNpIHZ5xb5hZHVqZSBkb2RhdG/EjW7DuiBrb250cm9sdQpwb21vY291IGRvcGxua292w71jaCB0ZXN0b3YgKG5hcHIuIFNoYXBpcm/igJNXaWxrIHRlc3QsIGFuYWzDvXphIENvb2tvdmVqCnZ6ZGlhbGVub3N0aSkuCgojIyBTY2FsZSBsb2NhdGlvbiBwbG90CgojIyMgSW50ZXJwcmV0w6FjaWEgdsOhxaFobyBrb25rcsOpdG5laG8gZ3JhZnUKCkJvZHkgc8O6IHJvdm5vbWVybmUgcm96cHTDvWxlbsOpIHBvemTEusW+IG9zaSBYIGJleiB6cmV0ZcS+bsOpaG8gdnpvcnUsIMSNbwpuYXpuYcSNdWplLCDFvmUgcm96cHR5bCByZXrDrWR1w60gamUgKipwcmlibGnFvm5lIGtvbsWhdGFudG7DvSoqLiBUZW50byBqYXYgc2EKb3puYcSNdWplIGFrbyAqKmhvbW9za2VkYXN0aWNpdGEqKiwgdGVkYSBwcmVkcG9rbGFkIHJvdm5ha8OpaG8gcm96cHR5bHUKY2jDvWIgcHJlIHbFoWV0a3kgw7pyb3ZuZSBwcmVkaWtvdmFuw71jaCBob2Ruw7R0IGplIHZvIHbFoWVvYmVjbm9zdGkgc3BsbmVuw70uCgrEjGVydmVuw6EgdnlobGFkem92YWNpYSAoTE9FU1MpIMSNaWFyYSBqZSByZWxhdMOtdm5lICoqcm92bsOhIGEgYmV6IHbDvXJhem5lagprcml2a3kqKixcCsSNbyBwb2Rwb3J1amUgesOhdmVyLCDFvmUgc28genZ5xaF1asO6Y2ltaSBzYSB2eXJvdm5hbsO9bWkgaG9kbm90YW1pIHNhCnZhcmlhbmNpYSByZXrDrWR1w60gc3lzdGVtYXRpY2t5IG5lbWVuw60uCgpOaWVrb8S+a28gYm9kb3YgamUgc8OtY2UgbWllcm5lIHZ6ZGlhbGVuw71jaCBvZCBobGF2bsOpaG8gemhsdWt1IChob2Rub3R5Cm5hZCAxLDUgbmEgb3NpIFkpLCBhdsWhYWsgbmVqZGUgbyBleHRyw6ltbmUgb2TEvmFobMOpIHBvem9yb3ZhbmlhLlwKQ2Vsa292byB0ZWRhIG3DtMW+ZW1lIGtvbsWhdGF0b3ZhxaUsIMW+ZSAqKnByZWRwb2tsYWQga29uxaF0YW50bmVqIHZhcmlhYmlsaXR5Cihob21vc2tlZGFzdGljaXR5KSBqZSBzcGxuZW7DvSoqIGEgbW9kZWwgbmVwcmVqYXZ1amUgxb5pYWRuZSB6w6F2YcW+bsOpCnpuw6Fta3kgaGV0ZXJvc2tlZGFzdGljaXR5LgoKIyMjIEludGVycHJldMOhY2lhIHbDocWhaG8ga29ua3LDqXRuZWhvIGdyYWZ1CgpWw6TEjcWhaW5hIHBvem9yb3ZhbsOtIG3DoSBuw616a3kgcMOha292w70gZWZla3QgKGhvZG5vdHkgcG9kIDAsMDUpLCDEjW8KbmF6bmHEjXVqZSwgxb5lIGplZG5vdGxpdsOpIGJvZHkgbmVtYWrDuiB2w71yYXpuw70gdnBseXYgbmEgdHZhciByZWdyZXNuZWoKcHJpYW1reS5cClRvIGplIHR5cGlja8OpIHByZSBkb2JyZSByb3psb8W+ZW7DqSDDumRhamUsIGtkZSDFvmlhZG55IMWhdHVkZW50IG5ldnnEjW5pZXZhCmV4dHLDqW1ueW1pIGhvZG5vdGFtaSB2IHByZW1lbm7DvWNoIGFrbyAqaG91cnNfc3R1ZGllZCosICpzbGVlcF9ob3VycyoKYWxlYm8gKmF0dGVuZGFuY2VfcGVyY2VudCouCgpKZWRlbiBhxb4gZHZhIGJvZHkgc2EgdsWhYWsgbWllcm5lIG9kZGXEvnVqw7ogb2Qgb3N0YXRuw71jaCAobmFwci4gdiBvYmxhc3RpCnDDoWtvdsOpaG8gZWZla3R1IG9rb2xvIDAsMikuXApJZGUgbyBwb3pvcm92YW5pYSBzbyAqKnp2w73FoWVub3UgcMOha291KiosIHRlZGEgaWNoIGhvZG5vdHkgcHJlZGlrdG9yb3Ygc8O6CsSPYWxlaiBvZCB2w6TEjcWhaW55IMO6ZGFqb3Yg4oCUIG5hcHLDrWtsYWQgxaF0dWRlbnQgcyBleHRyw6ltbmUgbsOtemt5bSBwb8SNdG9tCmhvZMOtbiBzcMOhbmt1IGFsZWJvIHZlxL5taSB2eXNva8O9bSBwb8SNdG9tIGhvZMOtbiDFoXTDumRpYS4KClbDpMSNxaFpbmEgxaF0YW5kYXJkaXpvdmFuw71jaCByZXrDrWR1w60gc2EgbmFjaMOhZHphIG1lZHppIGhvZG5vdGFtaSAqKuKIkjIgYQorMioqLCDEjW8gem5hbWVuw6EsIMW+ZSBuZWV4aXN0dWrDuiDFvmlhZG5lIHrDoXZhxb5uw6kgb2TEvmFobMOpIGhvZG5vdHkgdgp6w6F2aXNsZWogcHJlbWVubmVqICgqZXhhbV9zY29yZSopLgoKS29udMO6cnkgQ29va292ZWogdnpkaWFsZW5vc3RpIHVrYXp1asO6LCDFvmUgxb5pYWRlbiB6IGJvZG92ICoqbmVwcmVrcmHEjXVqZQpocmFuaWNlIDAsNSDEjWkgMSwwKiosXApwcmV0byAqKsW+aWFkbmUgcG96b3JvdmFuaWUgbmVtw6EgdsO9cmF6bmUgbmVwcmltZXJhbsO9IHZwbHl2KiogbmEgb2RoYWR5CnJlZ3Jlc27DvWNoIGtvZWZpY2llbnRvdi4KCkNlbGtvdm8gbW/Fvm5vIGtvbsWhdGF0b3ZhxaUsIMW+ZSBtb2RlbCBuaWUgamUgY2l0bGl2w70gbmEgamVkbm90bGl2w6kKcG96b3JvdmFuaWEgYSBuaWUgc8O6IHByw610b21uw6kgZXh0csOpbW5lIHZwbHl2bsOpIGJvZHksIGt0b3LDqSBieSBtb2hsaQpza3Jlc8S+b3ZhxaUgdsO9c2xlZGt5IHJlZ3Jlc2llLgoKIyMgQ29uY2x1c2lvbgoKUHJlbWVubsOpICpob3Vyc19zdHVkaWVkKiBhICphdHRlbmRhbmNlX3BlcmNlbnQqIG1hasO6ICoqxaF0YXRpc3RpY2t5CnbDvXpuYW1uw70gcG96aXTDrXZueSB2cGx5dioqIG5hIHbDvXNsZWRuw6kgc2vDusWha292w6kgc2vDs3JlIMWhdHVkZW50b3Yg4oCTIHRlZGEKxI3DrW0gdmlhYyDEjWFzdSDFoXR1ZGVudCB2ZW51amUgxaF0w7pkaXUgYSDEjcOtbSBwcmF2aWRlbG5lasWhaWUgc2EgesO6xI1hc3TFiHVqZQp2eXXEjW92YW5pYSwgdMO9bSB2ecWhxaFpZSBza8OzcmUgZG9zYWh1amUuCgpQcmVtZW5uw6EgKnNsZWVwX2hvdXJzKiBzYSB1a8OhemFsYSBha28gKiptZW5laiB2w716bmFtbsOhKiosIHByacSNb20gamVqCnZwbHl2IG5hIHbDvXNsZWRvayBza8O6xaFreSBuZWJvbCBqZWRub3puYcSNbsO9IOKAkyB2IG1vZGVsaSBzYSBwcmVqYXZ1amUgcwptYWzDvW0gYWxlYm8gbmVpbnRlcnByZXRvdmF0ZcS+bsO9bSDDusSNaW5rb20uCgpSZXrDrWR1w6EgbmV2eWthenVqw7ogw7pwbG5lIGRva29uYWzDqSBub3Jtw6FsbmUgcm96ZGVsZW5pZSwgYXbFoWFrIHZ6aMS+YWRvbSBuYQpkb3N0YXRvxI1uZSB2ZcS+a8O9IHBvxI1ldCBwb3pvcm92YW7DrSBtw7TFvmVtZSBtb2RlbCBwb3Zhxb5vdmHFpSB6YSBzcG/EvmFobGl2w70gYQp2aG9kbsO9IG5hIGludGVycHJldMOhY2l1LgoKWiBkaWFnbm9zdGlja8O9Y2ggZ3JhZm92IHRha3RpZcW+IHZ5cGzDvXZhLCDFvmUgKip2IG1vZGVsaSBzYSBuZXByZXVrYXp1asO6CsW+aWFkbmUgdsO9cmF6bsOpIG5lbGluZWFyaXR5LCBoZXRlcm9za2VkYXN0aWNpdGEgYW5pIHZwbHl2bsOpCnBvem9yb3ZhbmlhKiouXApNb2RlbCB0ZWRhIHBvbWVybmUgZG9icmUgdnlzdGlodWplIHZ6xaVhaCBtZWR6aSDFoXR1ZGlqbsO9bWkgbsOhdnlrbWkgYQp2w71zbGVkbsO9bSBza8O6xaFrb3bDvW0gc2vDs3JlLgo=