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

Východiskový model a údaje

library(readr)
library(dplyr)
library(car)

# načítanie tvojich dát
udaje <- read.csv("Indian_water_data.csv",
                  dec = ".",
                  sep = ",",
                  header = TRUE,
                  check.names = FALSE)

# vyberieme len premenné, ktoré chceš použiť v modeli
udaje.sub <- udaje[, c(
  "BOD (mg/L) - Max",
  "Temperature (C) - Max",
  "pH - Max"
)]

# pre istotu konverzia na numerické
for (col in names(udaje.sub)) {
  udaje.sub[[col]] <- as.numeric(udaje.sub[[col]])
}

# data imputation – výpočet mediánov
column_medians <- sapply(udaje.sub, median, na.rm = TRUE)

# Imputácia chýbajúcich hodnôt mediánmi
udaje_imputed <- udaje.sub
for (col in names(udaje.sub)) {
  udaje_imputed[[col]][is.na(udaje_imputed[[col]])] <- column_medians[col]
}

# finálny dataset
udaje <- udaje_imputed

summary(udaje)
 BOD (mg/L) - Max Temperature (C) - Max    pH - Max     
 Min.   : 1.000   Min.   : 8.00         Min.   : 6.600  
 1st Qu.: 2.000   1st Qu.:24.25         1st Qu.: 7.700  
 Median : 2.600   Median :29.00         Median : 8.000  
 Mean   : 4.997   Mean   :27.47         Mean   : 8.003  
 3rd Qu.: 2.900   3rd Qu.:32.00         3rd Qu.: 8.300  
 Max.   :90.000   Max.   :39.00         Max.   :11.200  
colSums(is.na(udaje))
     BOD (mg/L) - Max Temperature (C) - Max              pH - Max 
                    0                     0                     0 

Odhad základného regresného modelu

model <- lm(
  `BOD (mg/L) - Max` ~ 
    `Temperature (C) - Max` +
    `pH - Max`,
  data = udaje
)

summary(model)

Call:
lm(formula = `BOD (mg/L) - Max` ~ `Temperature (C) - Max` + `pH - Max`, 
    data = udaje)

Residuals:
   Min     1Q Median     3Q    Max 
-4.344 -3.049 -2.699 -1.859 85.121 

Coefficients:
                        Estimate Std. Error t value Pr(>|t|)
(Intercept)              3.31821   14.42947   0.230    0.818
`Temperature (C) - Max`  0.07662    0.11616   0.660    0.510
`pH - Max`              -0.05327    1.65470  -0.032    0.974

Residual standard error: 10.21 on 191 degrees of freedom
Multiple R-squared:  0.002507,  Adjusted R-squared:  -0.007938 
F-statistic:  0.24 on 2 and 191 DF,  p-value: 0.7868

Korelačná matica

xvars <- udaje[, c(
 "BOD (mg/L) - Max",
  "Temperature (C) - Max",
  "pH - Max"
)]

round(cor(xvars), 3)
                      BOD (mg/L) - Max Temperature (C) - Max pH - Max
BOD (mg/L) - Max                 1.000                 0.050   -0.015
Temperature (C) - Max            0.050                 1.000   -0.262
pH - Max                        -0.015                -0.262    1.000

Z korelačnej matice vidíme, že vzťahy medzi premennými sú veľmi slabé:

  • BOD (mg/L) – Max a Temperature (C) – Max
    Korelácia 0.050 znamená, že medzi BOD a teplotou je len veľmi slabý pozitívny lineárny vzťah.

  • BOD (mg/L) – Max a pH – Max
    Korelácia –0.015 je takmer nulová, takže pH prakticky vôbec nesúvisí so zmenami hodnoty BOD.

  • Temperature (C) – Max a pH – Max
    Korelácia –0.262 predstavuje slabú negatívnu koreláciu – pri vyššej teplote má voda mierne tendenciu mať nižšie pH, ale vzťah je stále relatívne slabý.

Záver

Žiadny z korelačných koeficientov nie je dostatočne silný na to, aby naznačoval problém s multikolinearitou. Premenné Temperature (C) - Max a pH - Max sú voči sebe len slabo závislé, čo je pre regresnú analýzu priaznivé.

pairs(
  xvars,
  main = "Scatterplotová matica – premenné BOD, teplota a pH"
)

Zo scatterplotovej matice môžeme pozorovať tieto vzťahy medzi premennými:

1. BOD (mg/L) – Max vs. Temperature (C) – Max

  • Body sú roztrúsené bez zjavného smerovania.
  • Nevidíme žiadny jednoznačný lineárny vzťah.
  • To potvrdzuje aj veľmi nízka korelácia (0.050).

2. BOD (mg/L) – Max vs. pH – Max

  • Body opäť nevykazujú jasný vzor.
  • BOD sa prakticky nemení so zmenou pH.
  • Zodpovedá takmer nulovej korelácii (–0.015).

3. Temperature (C) – Max vs. pH – Max

  • Viditeľný je mierny negatívny sklon – pri vyššej teplote sa hodnoty pH znižujú.
  • Vzťah však nie je silný; body sú stále pomerne rozptýlené.
  • To je v súlade s koreláciou –0.262, ktorá naznačuje slabší negatívny lineárny vzťah.

Zhrnutie

Scatterplotová matica vizuálne potvrdzuje, že:

  • Medzi premennými nie sú prítomné žiadne silné lineárne vzťahy.
  • Vzťah medzi teplotou a pH je mierne negatívny, ale vo všeobecnosti slabý.
  • BOD sa nezdá byť výrazne ovplyvnený ani teplotou, ani pH v lineárnej podobe.

Pre regresný model to znamená, že premenné neprejavujú problém multikolinearity, čo je priaznivé pre stabilitu odhadov.

VIF

vif(model)
`Temperature (C) - Max`              `pH - Max` 
                1.07343                 1.07343 

Výsledky:

  • Temperature (C) - Max: 1.073
  • pH - Max: 1.073

Interpretácia:

  • Hodnoty VIF sú veľmi blízko 1, čo znamená, že vysvetľujúce premenné prakticky nie sú lineárne závislé.
  • VIF < 5 vždy naznačuje, že multikolinearita nepredstavuje problém.
  • V tvojom prípade sú hodnoty extrémne nízke → multikolinearita je zanedbateľná.

Condition Number

X <- model.matrix(model)[, -1]   # odstráni intercept
XtX <- t(X) %*% X                # X'X matica
eig <- eigen(XtX)                # vlastné čísla

condition_number <- sqrt(max(eig$values) / min(eig$values))
condition_number
[1] 15.04439

Interpretácia

Náš výsledok (15) patrí do pásma:

mierna multikolinearita, ktorá však nie je nebezpečná

To znamená:

  • Vysvetľujúce premenné vykazujú len malé prekrytie informácie.
  • Model je stabilný a koeficienty sú dobre interpretovateľné.
  • Multikolinearita nie je problémom pre tvoj regresný model.

Zhrnutie

  • VIF ≈ 1 → premenné sú takmer nezávislé.
  • Condition number ≈ 15 → mierna, ale neškodná multikolinearita.

Model je teda z pohľadu multikolinearity veľmi dobre nastavený a spoľahlivý.

Riešenia multikolinearity

model_noTemp <- lm(
  `BOD (mg/L) - Max` ~ 
    `pH - Max`,
  data = udaje
)

summary(model_noTemp)

Call:
lm(formula = `BOD (mg/L) - Max` ~ `pH - Max`, data = udaje)

Residuals:
   Min     1Q Median     3Q    Max 
-4.167 -2.998 -2.434 -2.072 85.036 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)
(Intercept)   7.7079    12.7843   0.603    0.547
`pH - Max`   -0.3387     1.5948  -0.212    0.832

Residual standard error: 10.2 on 192 degrees of freedom
Multiple R-squared:  0.0002349, Adjusted R-squared:  -0.004972 
F-statistic: 0.04512 on 1 and 192 DF,  p-value: 0.832

Interpretácia modelu bez premennej Temperature (C) – Max

V tomto modeli vysvetľujeme hodnotu BOD (mg/L) – Max iba pomocou jednej premennej:

  • pH - Max

Koeficienty modelu

  • Intercept: 7.7079
    Odhadovaná hodnota BOD pri pH = 0 (čisto technická hodnota bez reálnej interpretácie, pretože pH = 0 sa v dátach nevyskytuje).

  • pH - Max: –0.3387
    Zmena pH o 1 jednotku je spojená s poklesom BOD približne o 0.34 mg/L, ale tento efekt nie je štatisticky významný (p-value = 0.832).

Štatistická významnosť

  • t-hodnota je veľmi nízka (–0.212),
  • p-hodnota = 0.832, čo znamená, že pH nevysvetľuje variabilitu BOD.

Kvalita modelu

  • R-squared = 0.00023, Adjusted R-squared = –0.00497
    → Model prakticky nevysvetľuje variabilitu BOD.

  • Residual standard error = 10.2
    → Rozptyl chýb zostal takmer rovnaký ako v pôvodnom modeli.

  • F-test (p-value = 0.832)
    → Model ako celok nie je štatisticky významný.

Zhrnutie

Model bez premennej teplota ukazuje, že:

  • pH samo o sebe nedokáže vysvetliť BOD,
  • predikčná sila modelu je prakticky nulová,
  • vylúčenie teploty model nezlepšilo, ani nezjednodušilo v zmysluplnom smere.

Tento výsledok je konzistentný so slabými koreláciami medzi premennými.

model_noPH <- lm(
  `BOD (mg/L) - Max` ~ 
    `Temperature (C) - Max`,
  data = udaje
)

summary(model_noPH)

Call:
lm(formula = `BOD (mg/L) - Max` ~ `Temperature (C) - Max`, data = udaje)

Residuals:
   Min     1Q Median     3Q    Max 
-4.348 -3.051 -2.698 -1.841 85.117 

Coefficients:
                        Estimate Std. Error t value Pr(>|t|)
(Intercept)               2.8650     3.1580   0.907    0.365
`Temperature (C) - Max`   0.0776     0.1118   0.694    0.489

Residual standard error: 10.19 on 192 degrees of freedom
Multiple R-squared:  0.002502,  Adjusted R-squared:  -0.002694 
F-statistic: 0.4815 on 1 and 192 DF,  p-value: 0.4886

Interpretácia modelu bez premennej pH – Max

V tomto modeli vysvetľujeme hodnotu BOD (mg/L) – Max iba pomocou jednej premennej:

  • Temperature (C) - Max

Koeficienty modelu

  • Intercept: 2.8650
    Predpokladaná hodnota BOD pri teplote 0 °C (opäť ide o technickú hodnotu mimo reálneho rozsahu dát).

  • Temperature (C) - Max: 0.0776
    Zvýšenie maximálnej teploty o 1 °C je spojené s nárastom BOD o približne 0.078 mg/L, avšak tento efekt nie je štatisticky významný
    (p-value = 0.489).

Štatistická významnosť

  • t-hodnota = 0.694, čo je veľmi nízke.
  • p-hodnota = 0.489, takže teplota nemá významný lineárny vplyv na hodnoty BOD.

Kvalita modelu

  • R-squared = 0.0025, Adjusted R-squared = –0.0027
    → Model vysvetľuje iba 0.25 % variability BOD, čo je zanedbateľné.

  • Residual standard error = 10.19, čo je prakticky rovnaké ako v predošlých modeloch.

  • F-test (p-value = 0.4886)
    → Model ako celok nie je štatisticky významný.

Zhrnutie

Model bez premennej pH ukazuje, že:

  • teplota sama o sebe nevysvetľuje variabilitu BOD,
  • predikčná schopnosť modelu je extrémne nízka,
  • výsledky zodpovedajú veľmi slabým koreláciám medzi premennými.

Tento model teda nie je vhodný ako náhrada pôvodného modelu a ukazuje, že BOD nie je lineárne ovplyvnené ani samotnou teplotou.

Škálovanie premenných

# centrónne škálovanie premenných
udaje$Temperature_c <- scale(udaje$`Temperature (C) - Max`, center = TRUE, scale = TRUE)
udaje$PH_c          <- scale(udaje$`pH - Max`,               center = TRUE, scale = TRUE)

# centrónny model
model_centered <- lm(
  `BOD (mg/L) - Max` ~ Temperature_c + PH_c,
  data = udaje
)

summary(model_centered)

Call:
lm(formula = `BOD (mg/L) - Max` ~ Temperature_c + PH_c, data = udaje)

Residuals:
   Min     1Q Median     3Q    Max 
-4.344 -3.049 -2.699 -1.859 85.121 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)    4.99691    0.73323   6.815  1.2e-10 ***
Temperature_c  0.50239    0.76164   0.660    0.510    
PH_c          -0.02452    0.76164  -0.032    0.974    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 10.21 on 191 degrees of freedom
Multiple R-squared:  0.002507,  Adjusted R-squared:  -0.007938 
F-statistic:  0.24 on 2 and 191 DF,  p-value: 0.7868

Škálovanie premenných

Premenné Temperature (C) - Max a pH - Max boli štandardizované (centrované a škálované).
Tým získali nulový priemer a jednotkovú smerodajnú odchýlku.
Takéto škálovanie nemente vzťahy medzi premennými, ale umožňuje porovnávať veľkosť ich koeficientov v spoločnej mierke.

vif(model_centered)
Temperature_c          PH_c 
      1.07343       1.07343 
  • Hodnoty VIF sú veľmi blízko 1, čo znamená, že vysvetľujúce premenné nie sú lineárne závislé.
  • Multikolinearita nie je problém v tomto modeli.
X <- model.matrix(model_centered)[, -1]   # odstráni intercept
XtX <- t(X) %*% X                         # X'X matica
eig <- eigen(XtX)                         # vlastné čísla

condition_number <- sqrt(max(eig$values) / min(eig$values))
condition_number
[1] 1.307043
  • Condition number blízky 1 potvrdzuje, že multikolinearita je takmer nulová.
  • Model je preto numericky stabilný a odhady koeficientov sú spoľahlivé.

Iná úprava premennej, ktorá zachová interpretovateľnosť

Teplota (Temperature (C) - Max) a pH (pH - Max) sú v rozdielnych mierkach – teplota sa pohybuje približne v desiatkach °C, zatiaľ čo pH v jednotkách.
Aby sme získali porovnateľné rády vysvetľujúcich premenných a zároveň zachovali jednoduchú interpretáciu, vytvoríme novú premennú Temp10, ktorá bude merať teplotu v desiatkach stupňov Celzia.

udaje$Temp10 <- udaje$`Temperature (C) - Max` / 10
head(udaje)

Odhad lineárneho modelu s Temp10

model_Temp10 <- lm(
  `BOD (mg/L) - Max` ~ Temp10 + `pH - Max`,
  data = udaje
)

summary(model_Temp10)

Call:
lm(formula = `BOD (mg/L) - Max` ~ Temp10 + `pH - Max`, data = udaje)

Residuals:
   Min     1Q Median     3Q    Max 
-4.344 -3.049 -2.699 -1.859 85.121 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)
(Intercept)  3.31821   14.42947   0.230    0.818
Temp10       0.76623    1.16163   0.660    0.510
`pH - Max`  -0.05327    1.65470  -0.032    0.974

Residual standard error: 10.21 on 191 degrees of freedom
Multiple R-squared:  0.002507,  Adjusted R-squared:  -0.007938 
F-statistic:  0.24 on 2 and 191 DF,  p-value: 0.7868

VIF pre nový model

vif(model_Temp10)
    Temp10 `pH - Max` 
   1.07343    1.07343 
  • Hodnoty VIF sú veľmi blízko 1, čo znamená takmer žiadnu multikolinearitu.

Condition number pre model s Temp10

X <- model.matrix(model_Temp10)[, -1]
XtX <- t(X) %*% X
eig <- eigen(XtX)

condition_number <- sqrt(max(eig$values) / min(eig$values))
condition_number
[1] 12.58774
  • Hodnota okolo 12 naznačuje miernu multikolinearitu, ktorá však nepredstavuje problém.
  • Model je z numerického hľadiska stabilný.

Zhrnutie

  • Ani Temp10, ani pH nemajú štatisticky významný vplyv na BOD.
  • Model nevysvetľuje variabilitu BOD (takmer nulové R²).
  • Multikolinearita nie je problémom, čo potvrdzujú veľmi nízke hodnoty VIF.
  • Condition number je mierne zvýšený, ale stále v bezpečnom pásme.
LS0tCnRpdGxlOiAiUHLDoWNhIHMgZGF0YWLDoXpvdSAtIE11bHRpa29saW5lYXJpdGEiCmF1dGhvcjogIlPDoXJhIE5pa29sIFNjaG9sdHpvdsOhIgpkYXRlOiAiRGVjZW1iZXIgMjAyNSIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRoZW1lOiB1bml0ZWQKICAgIGhpZ2hsaWdodDogdGFuZ28KICBlZGl0b3Jfb3B0aW9uczogCiAgbWFya2Rvd246IAogICAgd3JhcDogNzIKLS0tCmBgYHtyfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgICBlY2hvID0gVFJVRSwKICAgIG1lc3NhZ2UgPSBGQUxTRSwKICAgIHdhcm5pbmcgPSBGQUxTRSkKYGBgCiMjIFbDvWNob2Rpc2tvdsO9IG1vZGVsIGEgw7pkYWplCmBgYHtyfQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGNhcikKCiMgbmHEjcOtdGFuaWUgdHZvamljaCBkw6F0CnVkYWplIDwtIHJlYWQuY3N2KCJJbmRpYW5fd2F0ZXJfZGF0YS5jc3YiLAogICAgICAgICAgICAgICAgICBkZWMgPSAiLiIsCiAgICAgICAgICAgICAgICAgIHNlcCA9ICIsIiwKICAgICAgICAgICAgICAgICAgaGVhZGVyID0gVFJVRSwKICAgICAgICAgICAgICAgICAgY2hlY2submFtZXMgPSBGQUxTRSkKCiMgdnliZXJpZW1lIGxlbiBwcmVtZW5uw6ksIGt0b3LDqSBjaGNlxaEgcG91xb5pxaUgdiBtb2RlbGkKdWRhamUuc3ViIDwtIHVkYWplWywgYygKICAiQk9EIChtZy9MKSAtIE1heCIsCiAgIlRlbXBlcmF0dXJlIChDKSAtIE1heCIsCiAgInBIIC0gTWF4IgopXQoKIyBwcmUgaXN0b3R1IGtvbnZlcnppYSBuYSBudW1lcmlja8OpCmZvciAoY29sIGluIG5hbWVzKHVkYWplLnN1YikpIHsKICB1ZGFqZS5zdWJbW2NvbF1dIDwtIGFzLm51bWVyaWModWRhamUuc3ViW1tjb2xdXSkKfQoKIyBkYXRhIGltcHV0YXRpb24g4oCTIHbDvXBvxI1ldCBtZWRpw6Fub3YKY29sdW1uX21lZGlhbnMgPC0gc2FwcGx5KHVkYWplLnN1YiwgbWVkaWFuLCBuYS5ybSA9IFRSVUUpCgojIEltcHV0w6FjaWEgY2jDvWJhasO6Y2ljaCBob2Ruw7R0IG1lZGnDoW5taQp1ZGFqZV9pbXB1dGVkIDwtIHVkYWplLnN1Ygpmb3IgKGNvbCBpbiBuYW1lcyh1ZGFqZS5zdWIpKSB7CiAgdWRhamVfaW1wdXRlZFtbY29sXV1baXMubmEodWRhamVfaW1wdXRlZFtbY29sXV0pXSA8LSBjb2x1bW5fbWVkaWFuc1tjb2xdCn0KCiMgZmluw6FsbnkgZGF0YXNldAp1ZGFqZSA8LSB1ZGFqZV9pbXB1dGVkCgpzdW1tYXJ5KHVkYWplKQpjb2xTdW1zKGlzLm5hKHVkYWplKSkKYGBgCiMjIE9kaGFkIHrDoWtsYWRuw6lobyByZWdyZXNuw6lobyBtb2RlbHUKYGBge3J9Cm1vZGVsIDwtIGxtKAogIGBCT0QgKG1nL0wpIC0gTWF4YCB+IAogICAgYFRlbXBlcmF0dXJlIChDKSAtIE1heGAgKwogICAgYHBIIC0gTWF4YCwKICBkYXRhID0gdWRhamUKKQoKc3VtbWFyeShtb2RlbCkKYGBgCiMjIEtvcmVsYcSNbsOhIG1hdGljYQpgYGB7cn0KeHZhcnMgPC0gdWRhamVbLCBjKAogIkJPRCAobWcvTCkgLSBNYXgiLAogICJUZW1wZXJhdHVyZSAoQykgLSBNYXgiLAogICJwSCAtIE1heCIKKV0KCnJvdW5kKGNvcih4dmFycyksIDMpCmBgYApaIGtvcmVsYcSNbmVqIG1hdGljZSB2aWTDrW1lLCDFvmUgdnrFpWFoeSBtZWR6aSBwcmVtZW5uw71taSBzw7ogdmXEvm1pIHNsYWLDqToKCi0gKipCT0QgKG1nL0wpIOKAkyBNYXggYSBUZW1wZXJhdHVyZSAoQykg4oCTIE1heCoqICAKICBLb3JlbMOhY2lhICoqMC4wNTAqKiB6bmFtZW7DoSwgxb5lIG1lZHppIEJPRCBhIHRlcGxvdG91IGplIGxlbiB2ZcS+bWkgc2xhYsO9IHBveml0w612bnkgbGluZcOhcm55IHZ6xaVhaC4KCi0gKipCT0QgKG1nL0wpIOKAkyBNYXggYSBwSCDigJMgTWF4KiogIAogIEtvcmVsw6FjaWEgKirigJMwLjAxNSoqIGplIHRha21lciBudWxvdsOhLCB0YWvFvmUgcEggcHJha3RpY2t5IHbDtGJlYyBuZXPDunZpc8OtIHNvIHptZW5hbWkgaG9kbm90eSBCT0QuCgotICoqVGVtcGVyYXR1cmUgKEMpIOKAkyBNYXggYSBwSCDigJMgTWF4KiogIAogIEtvcmVsw6FjaWEgKirigJMwLjI2MioqIHByZWRzdGF2dWplICoqc2xhYsO6IG5lZ2F0w612bnUga29yZWzDoWNpdSoqIOKAkyBwcmkgdnnFocWhZWogdGVwbG90ZSBtw6Egdm9kYSBtaWVybmUgdGVuZGVuY2l1IG1hxaUgbmnFvsWhaWUgcEgsIGFsZSB2esWlYWggamUgc3TDoWxlIHJlbGF0w612bmUgc2xhYsO9LgoKIyMjIFrDoXZlcgrFvWlhZG55IHoga29yZWxhxI1uw71jaCBrb2VmaWNpZW50b3YgbmllIGplIGRvc3RhdG/EjW5lIHNpbG7DvSBuYSB0bywgYWJ5IG5hem5hxI1vdmFsIHByb2Jsw6ltIHMgbXVsdGlrb2xpbmVhcml0b3UuIFByZW1lbm7DqSBgVGVtcGVyYXR1cmUgKEMpIC0gTWF4YCBhIGBwSCAtIE1heGAgc8O6IHZvxI1pIHNlYmUgbGVuIHNsYWJvIHrDoXZpc2zDqSwgxI1vIGplIHByZSByZWdyZXNuw7ogYW5hbMO9enUgcHJpYXpuaXbDqS4KCmBgYHtyfQpwYWlycygKICB4dmFycywKICBtYWluID0gIlNjYXR0ZXJwbG90b3bDoSBtYXRpY2Eg4oCTIHByZW1lbm7DqSBCT0QsIHRlcGxvdGEgYSBwSCIKKQpgYGAKWm8gc2NhdHRlcnBsb3RvdmVqIG1hdGljZSBtw7TFvmVtZSBwb3pvcm92YcWlIHRpZXRvIHZ6xaVhaHkgbWVkemkgcHJlbWVubsO9bWk6CgojIyMgKioxLiBCT0QgKG1nL0wpIOKAkyBNYXggdnMuIFRlbXBlcmF0dXJlIChDKSDigJMgTWF4KioKLSBCb2R5IHPDuiByb3p0csO6c2Vuw6kgYmV6IHpqYXZuw6lobyBzbWVyb3ZhbmlhLgotIE5ldmlkw61tZSDFvmlhZG55IGplZG5vem5hxI1uw70gbGluZcOhcm55IHZ6xaVhaC4KLSBUbyBwb3R2cmR6dWplIGFqIHZlxL5taSBuw616a2Ega29yZWzDoWNpYSAoKiowLjA1MCoqKS4KCiMjIyAqKjIuIEJPRCAobWcvTCkg4oCTIE1heCB2cy4gcEgg4oCTIE1heCoqCi0gQm9keSBvcMOkxaUgbmV2eWthenVqw7ogamFzbsO9IHZ6b3IuCi0gQk9EIHNhIHByYWt0aWNreSBuZW1lbsOtIHNvIHptZW5vdSBwSC4KLSBab2Rwb3ZlZMOhIHRha21lciBudWxvdmVqIGtvcmVsw6FjaWkgKCoq4oCTMC4wMTUqKikuCgojIyMgKiozLiBUZW1wZXJhdHVyZSAoQykg4oCTIE1heCB2cy4gcEgg4oCTIE1heCoqCi0gVmlkaXRlxL5uw70gamUgbWllcm55IG5lZ2F0w612bnkgc2tsb24g4oCTIHByaSB2ecWhxaFlaiB0ZXBsb3RlIHNhIGhvZG5vdHkgcEggem5pxb51asO6LgotIFZ6xaVhaCB2xaFhayBuaWUgamUgc2lsbsO9OyBib2R5IHPDuiBzdMOhbGUgcG9tZXJuZSByb3pwdMO9bGVuw6kuCi0gVG8gamUgdiBzw7psYWRlIHMga29yZWzDoWNpb3UgKirigJMwLjI2MioqLCBrdG9yw6EgbmF6bmHEjXVqZSBzbGFixaHDrSBuZWdhdMOtdm55IGxpbmXDoXJueSB2esWlYWguCgotLS0KCiMjICoqWmhybnV0aWUqKgpTY2F0dGVycGxvdG92w6EgbWF0aWNhIHZpenXDoWxuZSBwb3R2cmR6dWplLCDFvmU6CgotIE1lZHppIHByZW1lbm7DvW1pIG5pZSBzw7ogcHLDrXRvbW7DqSDFvmlhZG5lIHNpbG7DqSBsaW5lw6FybmUgdnrFpWFoeS4KLSBWesWlYWggbWVkemkgdGVwbG90b3UgYSBwSCBqZSBtaWVybmUgbmVnYXTDrXZueSwgYWxlIHZvIHbFoWVvYmVjbm9zdGkgc2xhYsO9LgotIEJPRCBzYSBuZXpkw6EgYnnFpSB2w71yYXpuZSBvdnBseXZuZW7DvSBhbmkgdGVwbG90b3UsIGFuaSBwSCB2IGxpbmXDoXJuZWogcG9kb2JlLgoKUHJlIHJlZ3Jlc27DvSBtb2RlbCB0byB6bmFtZW7DoSwgxb5lIHByZW1lbm7DqSAqKm5lcHJlamF2dWrDuiBwcm9ibMOpbSBtdWx0aWtvbGluZWFyaXR5KiosIMSNbyBqZSBwcmlhem5pdsOpIHByZSBzdGFiaWxpdHUgb2RoYWRvdi4KCiMjIFZJRgpgYGB7cn0KdmlmKG1vZGVsKQpgYGAKVsO9c2xlZGt5OgoKLSBgVGVtcGVyYXR1cmUgKEMpIC0gTWF4YDogKioxLjA3MyoqCi0gYHBIIC0gTWF4YDogKioxLjA3MyoqCgoqKkludGVycHJldMOhY2lhOioqCgotIEhvZG5vdHkgVklGIHPDuiB2ZcS+bWkgYmzDrXprbyAqKjEqKiwgxI1vIHpuYW1lbsOhLCDFvmUgdnlzdmV0xL51asO6Y2UgcHJlbWVubsOpIHByYWt0aWNreSAqKm5pZSBzw7ogbGluZcOhcm5lIHrDoXZpc2zDqSoqLgotIFZJRiA8IDUgdsW+ZHkgbmF6bmHEjXVqZSwgxb5lIG11bHRpa29saW5lYXJpdGEgbmVwcmVkc3RhdnVqZSBwcm9ibMOpbS4KLSBWIHR2b2pvbSBwcsOtcGFkZSBzw7ogaG9kbm90eSBleHRyw6ltbmUgbsOtemtlIOKGkiAqKm11bHRpa29saW5lYXJpdGEgamUgemFuZWRiYXRlxL5uw6EqKi4KCiMjIENvbmRpdGlvbiBOdW1iZXIKYGBge3J9ClggPC0gbW9kZWwubWF0cml4KG1vZGVsKVssIC0xXSAgICMgb2RzdHLDoW5pIGludGVyY2VwdApYdFggPC0gdChYKSAlKiUgWCAgICAgICAgICAgICAgICAjIFgnWCBtYXRpY2EKZWlnIDwtIGVpZ2VuKFh0WCkgICAgICAgICAgICAgICAgIyB2bGFzdG7DqSDEjcOtc2xhCgpjb25kaXRpb25fbnVtYmVyIDwtIHNxcnQobWF4KGVpZyR2YWx1ZXMpIC8gbWluKGVpZyR2YWx1ZXMpKQpjb25kaXRpb25fbnVtYmVyCmBgYAoqKkludGVycHJldMOhY2lhKioKCk7DocWhIHbDvXNsZWRvayAoKioxNSoqKSBwYXRyw60gZG8gcMOhc21hOgoKIyMjIOKepCAqKm1pZXJuYSBtdWx0aWtvbGluZWFyaXRhKiosIGt0b3LDoSB2xaFhayBuaWUgamUgbmViZXpwZcSNbsOhCgpUbyB6bmFtZW7DoToKCi0gVnlzdmV0xL51asO6Y2UgcHJlbWVubsOpIHZ5a2F6dWrDuiAqKmxlbiBtYWzDqSBwcmVrcnl0aWUgaW5mb3Jtw6FjaWUqKi4KLSBNb2RlbCBqZSBzdGFiaWxuw70gYSBrb2VmaWNpZW50eSBzw7ogZG9icmUgaW50ZXJwcmV0b3ZhdGXEvm7DqS4KLSBNdWx0aWtvbGluZWFyaXRhIG5pZSBqZSBwcm9ibMOpbW9tIHByZSB0dm9qIHJlZ3Jlc27DvSBtb2RlbC4KCi0tLQoKIyMjICoqWmhybnV0aWUqKgoKLSAqKlZJRiDiiYggMSoqIOKGkiBwcmVtZW5uw6kgc8O6IHRha21lciBuZXrDoXZpc2zDqS4gIAotICoqQ29uZGl0aW9uIG51bWJlciDiiYggMTUqKiDihpIgbWllcm5hLCBhbGUgbmXFoWtvZG7DoSBtdWx0aWtvbGluZWFyaXRhLiAgCgpNb2RlbCBqZSB0ZWRhIHogcG9oxL5hZHUgbXVsdGlrb2xpbmVhcml0eSAqKnZlxL5taSBkb2JyZSBuYXN0YXZlbsO9IGEgc3BvxL5haGxpdsO9KiouCgojIyBSaWXFoWVuaWEgbXVsdGlrb2xpbmVhcml0eQpgYGB7cn0KbW9kZWxfbm9UZW1wIDwtIGxtKAogIGBCT0QgKG1nL0wpIC0gTWF4YCB+IAogICAgYHBIIC0gTWF4YCwKICBkYXRhID0gdWRhamUKKQoKc3VtbWFyeShtb2RlbF9ub1RlbXApCmBgYAojIyBJbnRlcnByZXTDoWNpYSBtb2RlbHUgYmV6IHByZW1lbm5laiAqVGVtcGVyYXR1cmUgKEMpIOKAkyBNYXgqCgpWIHRvbXRvIG1vZGVsaSB2eXN2ZXTEvnVqZW1lIGhvZG5vdHUgKipCT0QgKG1nL0wpIOKAkyBNYXgqKiBpYmEgcG9tb2NvdSBqZWRuZWogcHJlbWVubmVqOgoKLSBgcEggLSBNYXhgCgojIyMgKipLb2VmaWNpZW50eSBtb2RlbHUqKgotICoqSW50ZXJjZXB0OioqIDcuNzA3OSAgCiAgT2RoYWRvdmFuw6EgaG9kbm90YSBCT0QgcHJpIHBIID0gMCAoxI1pc3RvIHRlY2huaWNrw6EgaG9kbm90YSBiZXogcmXDoWxuZWogaW50ZXJwcmV0w6FjaWUsIHByZXRvxb5lIHBIID0gMCBzYSB2IGTDoXRhY2ggbmV2eXNreXR1amUpLgoKLSAqKnBIIC0gTWF4OioqIOKAkzAuMzM4NyAgCiAgWm1lbmEgcEggbyAxIGplZG5vdGt1IGplIHNwb2plbsOhIHMgcG9rbGVzb20gQk9EIHByaWJsacW+bmUgbyAwLjM0IG1nL0wsIGFsZSB0ZW50byBlZmVrdCAqKm5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSoqIChwLXZhbHVlID0gMC44MzIpLgoKIyMjICoqxaB0YXRpc3RpY2vDoSB2w716bmFtbm9zxaUqKgotIHQtaG9kbm90YSBqZSB2ZcS+bWkgbsOtemthICjigJMwLjIxMiksICAKLSBwLWhvZG5vdGEgPSAqKjAuODMyKiosIMSNbyB6bmFtZW7DoSwgxb5lICoqcEggbmV2eXN2ZXTEvnVqZSB2YXJpYWJpbGl0dSBCT0QqKi4KCiMjIyAqKkt2YWxpdGEgbW9kZWx1KioKLSAqKlItc3F1YXJlZCA9IDAuMDAwMjMqKiwgQWRqdXN0ZWQgUi1zcXVhcmVkID0g4oCTMC4wMDQ5NyAgCiAg4oaSIE1vZGVsIHByYWt0aWNreSAqKm5ldnlzdmV0xL51amUgdmFyaWFiaWxpdHUgQk9EKiouCgotICoqUmVzaWR1YWwgc3RhbmRhcmQgZXJyb3IgPSAxMC4yKiogIAogIOKGkiBSb3pwdHlsIGNow71iIHpvc3RhbCB0YWttZXIgcm92bmFrw70gYWtvIHYgcMO0dm9kbm9tIG1vZGVsaS4KCi0gKipGLXRlc3QgKHAtdmFsdWUgPSAwLjgzMikqKiAgCiAg4oaSIE1vZGVsIGFrbyBjZWxvayAqKm5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSoqLgoKIyMjICoqWmhybnV0aWUqKgpNb2RlbCBiZXogcHJlbWVubmVqIHRlcGxvdGEgdWthenVqZSwgxb5lOgoKLSAqKnBIIHNhbW8gbyBzZWJlIG5lZG9rw6HFvmUgdnlzdmV0bGnFpSBCT0QqKiwgIAotIHByZWRpa8SNbsOhIHNpbGEgbW9kZWx1IGplIHByYWt0aWNreSBudWxvdsOhLCAgCi0gdnlsw7rEjWVuaWUgdGVwbG90eSBtb2RlbCBuZXpsZXDFoWlsbywgYW5pIG5lemplZG5vZHXFoWlsbyB2IHpteXNsdXBsbm9tIHNtZXJlLgoKVGVudG8gdsO9c2xlZG9rIGplIGtvbnppc3RlbnRuw70gc28gc2xhYsO9bWkga29yZWzDoWNpYW1pIG1lZHppIHByZW1lbm7DvW1pLgpgYGB7cn0KbW9kZWxfbm9QSCA8LSBsbSgKICBgQk9EIChtZy9MKSAtIE1heGAgfiAKICAgIGBUZW1wZXJhdHVyZSAoQykgLSBNYXhgLAogIGRhdGEgPSB1ZGFqZQopCgpzdW1tYXJ5KG1vZGVsX25vUEgpCmBgYAojIyBJbnRlcnByZXTDoWNpYSBtb2RlbHUgYmV6IHByZW1lbm5laiAqcEgg4oCTIE1heCoKClYgdG9tdG8gbW9kZWxpIHZ5c3ZldMS+dWplbWUgaG9kbm90dSAqKkJPRCAobWcvTCkg4oCTIE1heCoqIGliYSBwb21vY291IGplZG5laiBwcmVtZW5uZWo6CgotIGBUZW1wZXJhdHVyZSAoQykgLSBNYXhgCgojIyMgKipLb2VmaWNpZW50eSBtb2RlbHUqKgotICoqSW50ZXJjZXB0OioqIDIuODY1MCAgCiAgUHJlZHBva2xhZGFuw6EgaG9kbm90YSBCT0QgcHJpIHRlcGxvdGUgMCDCsEMgKG9ww6TFpSBpZGUgbyB0ZWNobmlja8O6IGhvZG5vdHUgbWltbyByZcOhbG5laG8gcm96c2FodSBkw6F0KS4KCi0gKipUZW1wZXJhdHVyZSAoQykgLSBNYXg6KiogMC4wNzc2ICAKICBadsO9xaFlbmllIG1heGltw6FsbmVqIHRlcGxvdHkgbyAxIMKwQyBqZSBzcG9qZW7DqSBzIG7DoXJhc3RvbSBCT0QgbyBwcmlibGnFvm5lICoqMC4wNzggbWcvTCoqLCBhdsWhYWsgdGVudG8gZWZla3QgKipuaWUgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70qKiAgCiAgKHAtdmFsdWUgPSAqKjAuNDg5KiopLgoKIyMjICoqxaB0YXRpc3RpY2vDoSB2w716bmFtbm9zxaUqKgotIHQtaG9kbm90YSA9IDAuNjk0LCDEjW8gamUgdmXEvm1pIG7DrXprZS4gIAotIHAtaG9kbm90YSA9ICoqMC40ODkqKiwgdGFrxb5lIHRlcGxvdGEgKipuZW3DoSB2w716bmFtbsO9IGxpbmXDoXJueSB2cGx5dioqIG5hIGhvZG5vdHkgQk9ELgoKIyMjICoqS3ZhbGl0YSBtb2RlbHUqKgotICoqUi1zcXVhcmVkID0gMC4wMDI1KiosIEFkanVzdGVkIFItc3F1YXJlZCA9IOKAkzAuMDAyNyAgCiAg4oaSIE1vZGVsIHZ5c3ZldMS+dWplICoqaWJhIDAuMjUgJSoqIHZhcmlhYmlsaXR5IEJPRCwgxI1vIGplIHphbmVkYmF0ZcS+bsOpLgoKLSAqKlJlc2lkdWFsIHN0YW5kYXJkIGVycm9yID0gMTAuMTkqKiwgxI1vIGplIHByYWt0aWNreSByb3ZuYWvDqSBha28gdiBwcmVkb8WhbMO9Y2ggbW9kZWxvY2guCgotICoqRi10ZXN0IChwLXZhbHVlID0gMC40ODg2KSoqICAKICDihpIgTW9kZWwgYWtvIGNlbG9rICoqbmllIGplIMWhdGF0aXN0aWNreSB2w716bmFtbsO9KiouCgojIyMgKipaaHJudXRpZSoqCk1vZGVsIGJleiBwcmVtZW5uZWogcEggdWthenVqZSwgxb5lOgoKLSAqKnRlcGxvdGEgc2FtYSBvIHNlYmUgbmV2eXN2ZXTEvnVqZSB2YXJpYWJpbGl0dSBCT0QqKiwgIAotIHByZWRpa8SNbsOhIHNjaG9wbm9zxaUgbW9kZWx1IGplIGV4dHLDqW1uZSBuw616a2EsICAKLSB2w71zbGVka3kgem9kcG92ZWRhasO6IHZlxL5taSBzbGFiw71tIGtvcmVsw6FjacOhbSBtZWR6aSBwcmVtZW5uw71taS4KClRlbnRvIG1vZGVsIHRlZGEgbmllIGplIHZob2Ruw70gYWtvIG7DoWhyYWRhIHDDtHZvZG7DqWhvIG1vZGVsdSBhIHVrYXp1amUsIMW+ZSBCT0QgbmllIGplIGxpbmXDoXJuZSBvdnBseXZuZW7DqSBhbmkgc2Ftb3Rub3UgdGVwbG90b3UuCgojIyDFoGvDoWxvdmFuaWUgcHJlbWVubsO9Y2gKYGBge3J9CiMgY2VudHLDs25uZSDFoWvDoWxvdmFuaWUgcHJlbWVubsO9Y2gKdWRhamUkVGVtcGVyYXR1cmVfYyA8LSBzY2FsZSh1ZGFqZSRgVGVtcGVyYXR1cmUgKEMpIC0gTWF4YCwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKQp1ZGFqZSRQSF9jICAgICAgICAgIDwtIHNjYWxlKHVkYWplJGBwSCAtIE1heGAsICAgICAgICAgICAgICAgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKQoKIyBjZW50csOzbm55IG1vZGVsCm1vZGVsX2NlbnRlcmVkIDwtIGxtKAogIGBCT0QgKG1nL0wpIC0gTWF4YCB+IFRlbXBlcmF0dXJlX2MgKyBQSF9jLAogIGRhdGEgPSB1ZGFqZQopCgpzdW1tYXJ5KG1vZGVsX2NlbnRlcmVkKQpgYGAKIyMjIMWga8OhbG92YW5pZSBwcmVtZW5uw71jaApQcmVtZW5uw6kgYFRlbXBlcmF0dXJlIChDKSAtIE1heGAgYSBgcEggLSBNYXhgIGJvbGkgxaF0YW5kYXJkaXpvdmFuw6kgKGNlbnRyb3ZhbsOpIGEgxaFrw6Fsb3ZhbsOpKS4gIApUw71tIHrDrXNrYWxpIG51bG92w70gcHJpZW1lciBhIGplZG5vdGtvdsO6IHNtZXJvZGFqbsO6IG9kY2jDvWxrdS4gIApUYWvDqXRvIMWha8OhbG92YW5pZSAqKm5lbWVudGUgdnrFpWFoeSBtZWR6aSBwcmVtZW5uw71taSoqLCBhbGUgdW1vxb7FiHVqZSBwb3Jvdm7DoXZhxaUgdmXEvmtvc8WlIGljaCBrb2VmaWNpZW50b3YgdiBzcG9sb8SNbmVqIG1pZXJrZS4KCmBgYHtyfQp2aWYobW9kZWxfY2VudGVyZWQpCmBgYAotIEhvZG5vdHkgKipWSUYgc8O6IHZlxL5taSBibMOtemtvIDEqKiwgxI1vIHpuYW1lbsOhLCDFvmUgdnlzdmV0xL51asO6Y2UgcHJlbWVubsOpICoqbmllIHPDuiBsaW5lw6FybmUgesOhdmlzbMOpKiouICAKLSAqKk11bHRpa29saW5lYXJpdGEgbmllIGplIHByb2Jsw6ltKiogdiB0b210byBtb2RlbGkuICAKCmBgYHtyfQpYIDwtIG1vZGVsLm1hdHJpeChtb2RlbF9jZW50ZXJlZClbLCAtMV0gICAjIG9kc3Ryw6FuaSBpbnRlcmNlcHQKWHRYIDwtIHQoWCkgJSolIFggICAgICAgICAgICAgICAgICAgICAgICAgIyBYJ1ggbWF0aWNhCmVpZyA8LSBlaWdlbihYdFgpICAgICAgICAgICAgICAgICAgICAgICAgICMgdmxhc3Ruw6kgxI3DrXNsYQoKY29uZGl0aW9uX251bWJlciA8LSBzcXJ0KG1heChlaWckdmFsdWVzKSAvIG1pbihlaWckdmFsdWVzKSkKY29uZGl0aW9uX251bWJlcgpgYGAKLSAqKkNvbmRpdGlvbiBudW1iZXIgYmzDrXpreSAxKiogcG90dnJkenVqZSwgxb5lIG11bHRpa29saW5lYXJpdGEgamUgKip0YWttZXIgbnVsb3bDoSoqLiAgCi0gTW9kZWwgamUgcHJldG8gKipudW1lcmlja3kgc3RhYmlsbsO9KiogYSBvZGhhZHkga29lZmljaWVudG92IHPDuiBzcG/EvmFobGl2w6kuCgojIyBJbsOhIMO6cHJhdmEgcHJlbWVubmVqLCBrdG9yw6EgemFjaG92w6EgaW50ZXJwcmV0b3ZhdGXEvm5vc8WlClRlcGxvdGEgKGBUZW1wZXJhdHVyZSAoQykgLSBNYXhgKSBhIHBIIChgcEggLSBNYXhgKSBzw7ogdiByb3pkaWVsbnljaCBtaWVya2FjaCDigJMgdGVwbG90YSBzYSBwb2h5YnVqZSBwcmlibGnFvm5lIHYgZGVzaWF0a2FjaCDCsEMsIHphdGlhxL4gxI1vIHBIIHYgamVkbm90a8OhY2guICAKQWJ5IHNtZSB6w61za2FsaSBwb3Jvdm5hdGXEvm7DqSByw6FkeSB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoIGEgesOhcm92ZcWIIHphY2hvdmFsaSBqZWRub2R1Y2jDuiBpbnRlcnByZXTDoWNpdSwgdnl0dm9yw61tZSBub3bDuiBwcmVtZW5uw7ogKipUZW1wMTAqKiwga3RvcsOhIGJ1ZGUgbWVyYcWlIHRlcGxvdHUgdiAqZGVzaWF0a2FjaCBzdHVwxYhvdiBDZWx6aWEqLgpgYGB7cn0KdWRhamUkVGVtcDEwIDwtIHVkYWplJGBUZW1wZXJhdHVyZSAoQykgLSBNYXhgIC8gMTAKaGVhZCh1ZGFqZSkKYGBgCiMjIyBPZGhhZCBsaW5lw6FybmVobyBtb2RlbHUgcyBUZW1wMTAKYGBge3J9Cm1vZGVsX1RlbXAxMCA8LSBsbSgKICBgQk9EIChtZy9MKSAtIE1heGAgfiBUZW1wMTAgKyBgcEggLSBNYXhgLAogIGRhdGEgPSB1ZGFqZQopCgpzdW1tYXJ5KG1vZGVsX1RlbXAxMCkKYGBgCiMjIyBWSUYgcHJlIG5vdsO9IG1vZGVsCmBgYHtyfQp2aWYobW9kZWxfVGVtcDEwKQpgYGAKLSBIb2Rub3R5IFZJRiBzw7ogdmXEvm1pIGJsw616a28gKioxKiosIMSNbyB6bmFtZW7DoSAqKnRha21lciDFvmlhZG51IG11bHRpa29saW5lYXJpdHUqKi4KCiMjIyBDb25kaXRpb24gbnVtYmVyIHByZSBtb2RlbCBzIFRlbXAxMApgYGB7cn0KWCA8LSBtb2RlbC5tYXRyaXgobW9kZWxfVGVtcDEwKVssIC0xXQpYdFggPC0gdChYKSAlKiUgWAplaWcgPC0gZWlnZW4oWHRYKQoKY29uZGl0aW9uX251bWJlciA8LSBzcXJ0KG1heChlaWckdmFsdWVzKSAvIG1pbihlaWckdmFsdWVzKSkKY29uZGl0aW9uX251bWJlcgpgYGAKLSBIb2Rub3RhIG9rb2xvICoqMTIqKiBuYXpuYcSNdWplICoqbWllcm51IG11bHRpa29saW5lYXJpdHUqKiwga3RvcsOhIHbFoWFrICoqbmVwcmVkc3RhdnVqZSBwcm9ibMOpbSoqLgotIE1vZGVsIGplIHogbnVtZXJpY2vDqWhvIGjEvmFkaXNrYSBzdGFiaWxuw70uCgotLS0KCiMjIFpocm51dGllCi0gQW5pIFRlbXAxMCwgYW5pIHBIICoqbmVtYWrDuiDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSB2cGx5dioqIG5hIEJPRC4gIAotIE1vZGVsIG5ldnlzdmV0xL51amUgdmFyaWFiaWxpdHUgQk9EICh0YWttZXIgbnVsb3bDqSBSwrIpLiAgCi0gTXVsdGlrb2xpbmVhcml0YSAqKm5pZSBqZSBwcm9ibMOpbW9tKiosIMSNbyBwb3R2cmR6dWrDuiB2ZcS+bWkgbsOtemtlIGhvZG5vdHkgVklGLiAgCi0gQ29uZGl0aW9uIG51bWJlciBqZSBtaWVybmUgenbDvcWhZW7DvSwgYWxlIHN0w6FsZSB2ICoqYmV6cGXEjW5vbSBww6FzbWUqKi4K