1 Zakład Bioinformatyki, Instytut Informatyki, Uniwersytet w Białymstoku

Correspondence: Jarosław Kotowicz <>

1 Realizacja 7 maja 2020r.

1.1 Grupa 1 i 2

1.1.1 Podczytanie biblioteki i danych

rm(list = ls())
library(tidyverse)
daneMieszkania <- read_delim("http://www.biecek.pl/R/dane/daneMieszkania.csv", 
                             ";", 
                             escape_double = FALSE, 
                             trim_ws = TRUE)
Parsed with column specification:
cols(
  cena = col_double(),
  pokoi = col_double(),
  powierzchnia = col_double(),
  dzielnica = col_character(),
  `typ budynku` = col_character()
)

1.1.2 Przekształcenie zmienncyh napisowych na czynnikowe

daneMieszkania %>% summary
      cena            pokoi       powierzchnia    dzielnica         typ budynku       
 Min.   : 83280   Min.   :1.00   Min.   :17.00   Length:200         Length:200        
 1st Qu.:143304   1st Qu.:2.00   1st Qu.:31.15   Class :character   Class :character  
 Median :174935   Median :3.00   Median :43.70   Mode  :character   Mode  :character  
 Mean   :175934   Mean   :2.55   Mean   :46.20                                        
 3rd Qu.:208741   3rd Qu.:3.00   3rd Qu.:61.40                                        
 Max.   :295762   Max.   :4.00   Max.   :87.70                                        
daneMieszkania <- daneMieszkania %>%
  mutate_if(is.character, list(factor))
daneMieszkania %>% summary
      cena            pokoi       powierzchnia         dzielnica      typ budynku
 Min.   : 83280   Min.   :1.00   Min.   :17.00   Biskupin   :65   kamienica :61  
 1st Qu.:143304   1st Qu.:2.00   1st Qu.:31.15   Krzyki     :79   niski blok:63  
 Median :174935   Median :3.00   Median :43.70   Srodmiescie:56   wiezowiec :76  
 Mean   :175934   Mean   :2.55   Mean   :46.20                                   
 3rd Qu.:208741   3rd Qu.:3.00   3rd Qu.:61.40                                   
 Max.   :295762   Max.   :4.00   Max.   :87.70                                   

1.1.3 Budowa modeli regresji i ANOVA (testowanie równości średnich w podgrupach)

model <- lm(cena ~ dzielnica, data = daneMieszkania)
model

Call:
lm(formula = cena ~ dzielnica, data = daneMieszkania)

Coefficients:
         (Intercept)       dzielnicaKrzyki  dzielnicaSrodmiescie  
              189494                -21321                -18351  

Interpretacja wyniku!

model_1 <- lm(cena ~ dzielnica - 1, data = daneMieszkania)
model_1

Call:
lm(formula = cena ~ dzielnica - 1, data = daneMieszkania)

Coefficients:
   dzielnicaBiskupin       dzielnicaKrzyki  dzielnicaSrodmiescie  
              189494                168173                171143  

Interpretacja wyniku!

anova(model)
Analysis of Variance Table

Response: cena
           Df     Sum Sq    Mean Sq F value   Pr(>F)   
dzielnica   2 1.7995e+10 8997691613  5.0456 0.007294 **
Residuals 197 3.5130e+11 1783263361                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Interpretacja wyniku!

anova(model_1)
Analysis of Variance Table

Response: cena
           Df     Sum Sq    Mean Sq F value    Pr(>F)    
dzielnica   3 6.2086e+12 2.0695e+12  1160.5 < 2.2e-16 ***
Residuals 197 3.5130e+11 1.7833e+09                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Interpretacja wyniku!

model$residuals  %>% head
        1         2         3         4         5         6 
 58125.20 -61372.64 -52810.03  30920.71 -37869.97 -33252.10 

1.1.3.1 Tesowanie założeń regresji

library(normtest)
jb.norm.test(model$residuals)

    Jarque-Bera test for normality

data:  model$residuals
JB = 5.2583, p-value = 0.054

Interpretacja wyniku!

library(lmtest)
dwtest(daneMieszkania$cena ~ daneMieszkania$dzielnica)

    Durbin-Watson test

data:  daneMieszkania$cena ~ daneMieszkania$dzielnica
DW = 2.1565, p-value = 0.8655
alternative hypothesis: true autocorrelation is greater than 0

Interpretacja wyniku!

gqtest(daneMieszkania$cena ~ daneMieszkania$dzielnica)

    Goldfeld-Quandt test

data:  daneMieszkania$cena ~ daneMieszkania$dzielnica
GQ = 1.0691, df1 = 97, df2 = 97, p-value = 0.3713
alternative hypothesis: variance increases from segment 1 to 2

Interpretacja wyniku!

1.1.3.2 Wykres pudełko-wąsy

boxplot(daneMieszkania$cena ~ daneMieszkania$dzielnica)

daneMieszkania %>%
  ggplot(aes(dzielnica, cena)) +
  geom_boxplot()

daneMieszkania %>%
  ggplot(aes(dzielnica, cena)) +
  geom_boxplot() +
  coord_flip()

detach(package:tidyverse)
detach(package:ggplot2)
detach(package:tibble)
detach(package:tidyr)
detach(package:readr)
detach(package:purrr)
detach(package:dplyr)
detach(package:stringr)
detach(package:forcats)

detach(package:normtest)
detach(package:lmtest)

1.2 Grupa 5

1.2.1 Generowanie ciągóW liczb pseudolosowych z zdanego rozkładu

rm(list = ls())
library(MASS)
set.seed(20200507)
x.norm <- rnorm(100, mean = 1, sd =2)
set.seed(20200507)
x.lnorm <- rlnorm(100, meanlog = .1, sdlog = 2)
set.seed(20200507)
x.gamma <- rgamma(100, 2, 3)

#MLE

1.2.2 Metoda największej wiarogodności (bibliotek MASS) - wyznaczanie parametrów rozkładu

fitdistr(x.norm, "normal")
     mean         sd    
  1.1618982   2.0215240 
 (0.2021524) (0.1429433)
x.norm.fitt <- fitdistr(x.norm, "normal")
x.norm.fitt$estimate
    mean       sd 
1.161898 2.021524 
x.lnorm.fitt <- fitdistr(x.lnorm, "log-normal")
x.lnorm.fitt$estimate
  meanlog     sdlog 
0.2618982 2.0215240 
(x.lnorm.fitt <- fitdistr(x.lnorm, "log-normal"))
    meanlog      sdlog  
  0.2618982   2.0215240 
 (0.2021524) (0.1429433)
(x.lnormGamma.fitt <- fitdistr(x.lnorm, "gamma", list(shape = 3, rate = 2)))
wyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaNwyprodukowano warto㤼㹣ci NaN
     shape         rate   
  0.36475915   0.04496287 
 (0.04138815) (0.00901971)

1.2.3 Podczytanie biblioteki i danych

library(readr)
daneMieszkania <- read_delim("http://www.biecek.pl/R/dane/daneMieszkania.csv", 
                             ";", escape_double = FALSE, trim_ws = TRUE)
Parsed with column specification:
cols(
  cena = col_double(),
  pokoi = col_double(),
  powierzchnia = col_double(),
  dzielnica = col_character(),
  `typ budynku` = col_character()
)
library(tidyverse)
-- Attaching packages --------------------------------------- tidyverse 1.3.0 --
<U+221A> ggplot2 3.3.0     <U+221A> dplyr   0.8.5
<U+221A> tibble  3.0.1     <U+221A> stringr 1.4.0
<U+221A> tidyr   1.0.2     <U+221A> forcats 0.5.0
<U+221A> purrr   0.3.4     
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
x dplyr::select() masks MASS::select()
daneMieszkania %>% summary
      cena            pokoi       powierzchnia    dzielnica         typ budynku       
 Min.   : 83280   Min.   :1.00   Min.   :17.00   Length:200         Length:200        
 1st Qu.:143304   1st Qu.:2.00   1st Qu.:31.15   Class :character   Class :character  
 Median :174935   Median :3.00   Median :43.70   Mode  :character   Mode  :character  
 Mean   :175934   Mean   :2.55   Mean   :46.20                                        
 3rd Qu.:208741   3rd Qu.:3.00   3rd Qu.:61.40                                        
 Max.   :295762   Max.   :4.00   Max.   :87.70                                        
daneMieszkania <- daneMieszkania %>%
  mutate_if(is.character, list(factor))
daneMieszkania %>% summary

1.2.4 Testowanie równości średnich (t.test)

t.test((daneMieszkania[daneMieszkania$dzielnica == "Biskupin",])$cena, 
       (daneMieszkania[daneMieszkania$dzielnica == "Krzyki",])$cena)

    Welch Two Sample t-test

data:  (daneMieszkania[daneMieszkania$dzielnica == "Biskupin", ])$cena and (daneMieszkania[daneMieszkania$dzielnica == "Krzyki", ])$cena
t = 2.9793, df = 140.82, p-value = 0.003404
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
  7173.093 35468.945
sample estimates:
mean of x mean of y 
   189494    168173 

Interpretacja wyniku!

daneMieszkania[daneMieszkania$dzielnica == "Krzyki",]

1.2.5 Regresja i testowanie równości średnich (ANOVA)

model <- lm(cena ~ dzielnica, data = daneMieszkania)
model

Call:
lm(formula = cena ~ dzielnica, data = daneMieszkania)

Coefficients:
         (Intercept)       dzielnicaKrzyki  dzielnicaSrodmiescie  
              189494                -21321                -18351  

Interpretacja wyniku!

anova(model)
Analysis of Variance Table

Response: cena
           Df     Sum Sq    Mean Sq F value   Pr(>F)   
dzielnica   2 1.7995e+10 8997691613  5.0456 0.007294 **
Residuals 197 3.5130e+11 1783263361                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Interpretacja wyniku!

model2 <- lm(cena ~ dzielnica - 1, data = daneMieszkania)
model2

Call:
lm(formula = cena ~ dzielnica - 1, data = daneMieszkania)

Coefficients:
   dzielnicaBiskupin       dzielnicaKrzyki  dzielnicaSrodmiescie  
              189494                168173                171143  

Interpretacja wyniku!

anova(model2)
Analysis of Variance Table

Response: cena
           Df     Sum Sq    Mean Sq F value    Pr(>F)    
dzielnica   3 6.2086e+12 2.0695e+12  1160.5 < 2.2e-16 ***
Residuals 197 3.5130e+11 1.7833e+09                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Interpretacja wyniku!

1.2.6 Coś na boku - użycie attach do ramki danych

# Użycie attach
attach(daneMieszkania)
Nast攼㹡puj戼㸹ce obiekty zosta戼㸳y zakryte z daneMieszkania (pos = 13):

    cena, dzielnica, pokoi, powierzchnia, typ budynku
boxplot(cena~dzielnica)

detach(daneMieszkania)
Było 28 ostrzeżenie (użyj 'warnings()' aby je zobaczyć)

1.2.7 Regresja i testowanie równości średnich (ANOVA) c.d.

colnames(daneMieszkania)[5] <- "typ"
model3 <- lm(cena ~ typ, data = daneMieszkania)
model3

Call:
lm(formula = cena ~ typ, data = daneMieszkania)

Coefficients:
  (Intercept)  typniski blok   typwiezowiec  
       178318          10473         -14955  

Interpretacja wyniku!

anova(model3)
Analysis of Variance Table

Response: cena
           Df     Sum Sq    Mean Sq F value   Pr(>F)   
typ         2 2.2770e+10 1.1385e+10  6.4725 0.001895 **
Residuals 197 3.4653e+11 1.7590e+09                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Interpretacja wyniku!

model4 <- lm(cena ~ typ - 1, data = daneMieszkania)
model4

Call:
lm(formula = cena ~ typ - 1, data = daneMieszkania)

Coefficients:
 typkamienica  typniski blok   typwiezowiec  
       178318         188791         163363  

Interpretacja wyniku!

anova(model4)
Analysis of Variance Table

Response: cena
           Df     Sum Sq    Mean Sq F value    Pr(>F)    
typ         3 6.2133e+12 2.0711e+12  1177.4 < 2.2e-16 ***
Residuals 197 3.4653e+11 1.7590e+09                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Interpretacja wyniku!

1.2.8 Testowanie założeń regresji

model4$residuals %>% length()
[1] 200
ks.test(model4$residuals, "pnorm")

    One-sample Kolmogorov-Smirnov test

data:  model4$residuals
D = 0.505, p-value < 2.2e-16
alternative hypothesis: two-sided

Interpretacja wyniku!

nortest::ad.test(model4$residuals)

    Anderson-Darling normality test

data:  model4$residuals
A = 0.63027, p-value = 0.09918

Interpretacja wyniku!

tseries::jarque.bera.test(model4$residuals)

    Jarque Bera Test

data:  model4$residuals
X-squared = 4.0672, df = 2, p-value = 0.1309

Interpretacja wyniku!

detach(package:tidyverse)
detach(package:ggplot2)
detach(package:tibble)
detach(package:tidyr)
detach(package:readr)
detach(package:purrr)
detach(package:dplyr)
detach(package:stringr)
detach(package:forcats)

detach(package:MASS)

2 Realizacja 14 maja 2020r.

2.1 Grupa 1 i 2

2.1.1 Kilka uwag o pozostałych testach nieparametrycznych

rm(list = ls())

2.1.1.1 Funkcja sample

set.seed(908)
probka <- sample(c("x", "y", "z"), 100, replace = TRUE, prob = c(.3, .5, .2))
summary(probka)
   Length     Class      Mode 
      100 character character 
probka
  [1] "z" "z" "x" "y" "x" "y" "y" "x" "y" "y" "y" "x" "y" "y" "x" "z" "z" "y" "y" "y" "y" "y" "y"
 [24] "x" "z" "y" "x" "x" "y" "x" "y" "x" "y" "x" "y" "y" "x" "y" "x" "y" "y" "y" "z" "y" "y" "x"
 [47] "y" "y" "y" "x" "x" "y" "y" "x" "y" "y" "y" "x" "x" "y" "y" "z" "x" "z" "x" "y" "y" "z" "y"
 [70] "y" "x" "x" "y" "y" "x" "y" "y" "y" "y" "y" "z" "x" "x" "z" "z" "x" "y" "x" "x" "z" "y" "x"
 [93] "z" "y" "y" "y" "z" "x" "z" "y"

2.1.1.2 Funkcja data.frame

probka2 <- sample(c("a", "b"), 100, replace = TRUE, prob = c(.8, .2))
df <- data.frame(probka = probka, probka2 = probka2)

2.1.1.3 Funkcja table - tablica kontyngencji

tablica <- table(df$probka, df$probka2)
tablica
   
     a  b
  x 21 10
  y 41 12
  z 10  6

2.1.1.4 Test niezależności chi-kwadrat

chisq.test(tablica)
Aproksymacja chi-kwadrat mo戼㹦e by攼㸶 niepoprawna

    Pearson's Chi-squared test

data:  tablica
X-squared = 1.7499, df = 2, p-value = 0.4169

Interpretacja wyniku!

set.seed(908)
x.norm<-rnorm(1000,5,2)
set.seed(908)
x.gamma<-rgamma(1000,2,3)

2.1.1.5 Testowanie niezależności przy użyciu współczynika korelacji (Pearsona i Spearmana)

Niewłaściwe stosowanie (niespełnione założenie o normalności)

cor.test(x.norm,x.gamma)

    Pearson's product-moment correlation

data:  x.norm and x.gamma
t = -1.9241, df = 998, p-value = 0.05462
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.122326536  0.001203135
sample estimates:
        cor 
-0.06079448 

Interpretacja wyniku!

cor.test(x.norm,x.gamma,method="spearman")

    Spearman's rank correlation rho

data:  x.norm and x.gamma
S = 177858726, p-value = 0.03374
alternative hypothesis: true rho is not equal to 0
sample estimates:
        rho 
-0.06715342 

Interpretacja wyniku!

cor.test(x.norm[1:100],x.norm[901:1000])

    Pearson's product-moment correlation

data:  x.norm[1:100] and x.norm[901:1000]
t = 1.5964, df = 98, p-value = 0.1136
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.0384156  0.3448386
sample estimates:
      cor 
0.1592038 

Interpretacja wyniku!

2.1.2 Kilka uwag o pozostałych testach parametrycznych

2.1.2.1 Testowanie równości wariancji

set.seed(908)
x.norm2 <- rnorm(1000,3,2)

Pamiętaj o założeniach!

var.test(x.norm, x.norm2)

    F test to compare two variances

data:  x.norm and x.norm2
F = 1, num df = 999, denom df = 999, p-value = 1
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
 0.8832987 1.1321198
sample estimates:
ratio of variances 
                 1 

Interpretacja wyniku!

var.test(x.norm[1:100], x.norm[901:1000])

    F test to compare two variances

data:  x.norm[1:100] and x.norm[901:1000]
F = 1.1009, num df = 99, denom df = 99, p-value = 0.6334
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
 0.7407362 1.6362053
sample estimates:
ratio of variances 
          1.100907 

Interpretacja wyniku!

mood.test(x.norm, x.norm2)

    Mood two-sample test of scale

data:  x.norm and x.norm2
Z = -0.15617, p-value = 0.8759
alternative hypothesis: two.sided

Interpretacja wyniku!

ansari.test(x.norm, x.norm2)

    Ansari-Bradley test

data:  x.norm and x.norm2
AB = 501504, p-value = 0.8764
alternative hypothesis: true ratio of scales is not equal to 1

Interpretacja wyniku!

2.1.2.2 Testowanie frakcji

prop.test(399, 1000, .5)

    1-sample proportions test with continuity correction

data:  399 out of 1000, null probability 0.5
X-squared = 40.401, df = 1, p-value = 2.068e-10
alternative hypothesis: true p is not equal to 0.5
95 percent confidence interval:
 0.3685995 0.4301862
sample estimates:
    p 
0.399 

Interpretacja wyniku!

2.1.2.2.1 Funkcja sample
set.seed(908)
probka3 <- sample(c(0,1), 100, replace=TRUE, prob = c(.4, .6))
sum(probka3)
[1] 63
prop.test(sum(probka3), length(probka3), .6)

    1-sample proportions test with continuity correction

data:  sum(probka3) out of length(probka3), null probability 0.6
X-squared = 0.26042, df = 1, p-value = 0.6098
alternative hypothesis: true p is not equal to 0.6
95 percent confidence interval:
 0.5271463 0.7227373
sample estimates:
   p 
0.63 

Interpretacja wyniku!

prop.test(sum(probka3), length(probka3), .7)

    1-sample proportions test with continuity correction

data:  sum(probka3) out of length(probka3), null probability 0.7
X-squared = 2.0119, df = 1, p-value = 0.1561
alternative hypothesis: true p is not equal to 0.7
95 percent confidence interval:
 0.5271463 0.7227373
sample estimates:
   p 
0.63 

Interpretacja wyniku!

2.1.3 Miary zależności oparte na statystyce chi-kwadrat

DescTools::CramerV(tablica)
[1] 0.1322852
library(DescTools)
ContCoef(tablica)
[1] 0.1311428
Phi(tablica)
[1] 0.1322852
TschuprowT(tablica)
[1] 0.1112382

2.1.4 Regresja, ANOVA i testowanie ich założeń

library(tidyverse)
-- Attaching packages --------------------------------------- tidyverse 1.3.0 --
<U+221A> ggplot2 3.3.0     <U+221A> purrr   0.3.4
<U+221A> tibble  3.0.1     <U+221A> dplyr   0.8.5
<U+221A> tidyr   1.0.2     <U+221A> stringr 1.4.0
<U+221A> readr   1.3.1     <U+221A> forcats 0.5.0
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
daneMieszkania <- read_delim("http://www.biecek.pl/R/dane/daneMieszkania.csv", 
                             ";", 
                             escape_double = FALSE, 
                             trim_ws = TRUE)
Parsed with column specification:
cols(
  cena = col_double(),
  pokoi = col_double(),
  powierzchnia = col_double(),
  dzielnica = col_character(),
  `typ budynku` = col_character()
)
daneMieszkania <- daneMieszkania %>%
  mutate_if(is.character, list(factor))
daneMieszkania %>% summary
      cena            pokoi       powierzchnia         dzielnica      typ budynku
 Min.   : 83280   Min.   :1.00   Min.   :17.00   Biskupin   :65   kamienica :61  
 1st Qu.:143304   1st Qu.:2.00   1st Qu.:31.15   Krzyki     :79   niski blok:63  
 Median :174935   Median :3.00   Median :43.70   Srodmiescie:56   wiezowiec :76  
 Mean   :175934   Mean   :2.55   Mean   :46.20                                   
 3rd Qu.:208741   3rd Qu.:3.00   3rd Qu.:61.40                                   
 Max.   :295762   Max.   :4.00   Max.   :87.70                                   
model <- lm(cena ~ dzielnica, data = daneMieszkania)
model_1 <- lm(cena ~ dzielnica - 1, data = daneMieszkania)

2.1.4.1 Testowanie autokorelacji

lmtest::dwtest(model)

    Durbin-Watson test

data:  model
DW = 2.1565, p-value = 0.8655
alternative hypothesis: true autocorrelation is greater than 0
# brak podstaw do odrzucenia hioptezy o braku autokorelacji

Interpretacja wyniku!

model$residuals %>% head(10)
         1          2          3          4          5          6          7          8 
 58125.195 -61372.644 -52810.033  30920.707 -37869.975 -33252.104  -2761.984 -69247.315 
         9         10 
 22043.257 -51866.395 

2.1.4.2 Testowanie normalności

nortest::cvm.test(model$residuals)

    Cramer-von Mises normality test

data:  model$residuals
W = 0.102, p-value = 0.1048

Interpretacja wyniku!

nortest::sf.test(model$residuals)

    Shapiro-Francia normality test

data:  model$residuals
W = 0.98656, p-value = 0.05273

Interpretacja wyniku!

normtest::jb.norm.test(model$residuals)

    Jarque-Bera test for normality

data:  model$residuals
JB = 5.2583, p-value = 0.06

Interpretacja wyniku!

detach(package:tidyverse)
detach(package:ggplot2)
detach(package:tibble)
detach(package:tidyr)
detach(package:readr)
detach(package:purrr)
detach(package:dplyr)
detach(package:stringr)
detach(package:forcats)

detach(package:DescTools)

2.2 Grupa 6

2.2.1 Pozostałe testy parametryczne i nieparametryczne

rm(list = ls())
set.seed(1735)
x.norm <- rnorm(1000, mean = 5, sd = 1)
set.seed(1735)
x.gamma <- rgamma(1000, 3, 5)

2.2.2 Testowanie wariancji

var.test(x.norm[1:100], x.norm[301:400])

    F test to compare two variances

data:  x.norm[1:100] and x.norm[301:400]
F = 1.0601, num df = 99, denom df = 99, p-value = 0.7721
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
 0.7132824 1.5755629
sample estimates:
ratio of variances 
          1.060104 

Interpretacja wyniku!

mood.test(x.norm[1:100], x.norm[901:1000])

    Mood two-sample test of scale

data:  x.norm[1:100] and x.norm[901:1000]
Z = 0.004164, p-value = 0.9967
alternative hypothesis: two.sided

Interpretacja wyniku!

ansari.test(x.norm[501:600], x.norm[701:800])

    Ansari-Bradley test

data:  x.norm[501:600] and x.norm[701:800]
AB = 5116, p-value = 0.747
alternative hypothesis: true ratio of scales is not equal to 1

Interpretacja wyniku!

2.2.3 Testowanie frakcji

prop.test(295, 750, .45)

    1-sample proportions test with continuity correction

data:  295 out of 750, null probability 0.45
X-squared = 9.503, df = 1, p-value = 0.002051
alternative hypothesis: true p is not equal to 0.45
95 percent confidence interval:
 0.3583488 0.4294256
sample estimates:
        p 
0.3933333 

Interpretacja wyniku!

prop.test(295, 750, .4)

    1-sample proportions test with continuity correction

data:  295 out of 750, null probability 0.4
X-squared = 0.1125, df = 1, p-value = 0.7373
alternative hypothesis: true p is not equal to 0.4
95 percent confidence interval:
 0.3583488 0.4294256
sample estimates:
        p 
0.3933333 

Interpretacja wyniku!

2.2.3.1 Funkcja sample

proba <- sample(0:1, 1000, replace=TRUE, prob = c(.2, .8))
sum(proba)
[1] 804
prop.test(sum(proba), length(proba), .78)

    1-sample proportions test with continuity correction

data:  sum(proba) out of length(proba), null probability 0.78
X-squared = 3.2182, df = 1, p-value = 0.07282
alternative hypothesis: true p is not equal to 0.78
95 percent confidence interval:
 0.7777307 0.8278955
sample estimates:
    p 
0.804 

Interpretacja wyniku!

z1 <- sample(c("x","y","z"), 100, replace = TRUE, prob = c(.3, .4, .3))
z2 <- sample(c("a","b"), 100, replace = TRUE, prob = c(.7, .3))

2.2.3.2 Tablica kontyngencji i funkcja table

tablica <- table(z1, z2)
tablica 
   z2
z1   a  b
  x 22  9
  y 32 13
  z 17  7

2.2.4 Test niezależności chi-kwadrat

chisq.test(tablica)

    Pearson's Chi-squared test

data:  tablica
X-squared = 0.00060927, df = 2, p-value = 0.9997

Interpretacja wyniku!

2.2.4.1 Funkcja data.frame

df <- data.frame(z1=z1, z2=z2)

2.2.5 Testowanie współczynnika korelacji Pearsona i rang Spearmana

Tak stosowany test chi-kwadrat obowiązuje tylko dla wielowymiarowego rozkładu normalnego

cor.test(x.norm, x.gamma)

    Pearson's product-moment correlation

data:  x.norm and x.gamma
t = 0.70572, df = 998, p-value = 0.4805
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.03971457  0.08420999
sample estimates:
       cor 
0.02233349 
# tak stosowany test pearsona obowiązuje tylko dla wielowymiarowego

Interpretacja wyniku!

cor.test(x.norm, x.gamma, method = "spearman")

    Spearman's rank correlation rho

data:  x.norm and x.gamma
S = 165662512, p-value = 0.8491
alternative hypothesis: true rho is not equal to 0
sample estimates:
        rho 
0.006023934 

Interpretacja wyniku!

2.2.6 Miary zależności oparte na statystyce chi-kwadrat

DescTools::CramerV(tablica)
[1] 0.002468333
CramerV(tablica)
[1] 0.002468333
DescTools::Phi(tablica)
[1] 0.002468333
DescTools::ContCoef(tablica)
[1] 0.002468325
DescTools::TschuprowT(tablica)
[1] 0.002075612

2.2.7 Testowanie równości średnich (t.test i ANOVA)

library(readr)
daneMieszkania <- read_delim("http://www.biecek.pl/R/dane/daneMieszkania.csv", 
                             ";", escape_double = FALSE, trim_ws = TRUE)
Parsed with column specification:
cols(
  cena = col_double(),
  pokoi = col_double(),
  powierzchnia = col_double(),
  dzielnica = col_character(),
  `typ budynku` = col_character()
)
library(tidyverse)
daneMieszkania <- daneMieszkania %>%
  mutate_if(is.character, list(factor))
daneMieszkania.Biskupin <- daneMieszkania %>% 
  filter(dzielnica=="Biskupin")
daneMieszkania.Biskupin %>% summary
      cena            pokoi        powierzchnia         dzielnica      typ budynku
 Min.   :120290   Min.   :1.000   Min.   :17.10   Biskupin   :65   kamienica :26  
 1st Qu.:156655   1st Qu.:2.000   1st Qu.:35.20   Krzyki     : 0   niski blok:17  
 Median :189291   Median :3.000   Median :45.10   Srodmiescie: 0   wiezowiec :22  
 Mean   :189494   Mean   :2.585   Mean   :47.05                                   
 3rd Qu.:214462   3rd Qu.:3.000   3rd Qu.:61.20                                   
 Max.   :295762   Max.   :4.000   Max.   :87.70                                   
daneMieszkania.Biskupin %>% dim
[1] 65  5
t.test(daneMieszkania.Biskupin$cena)

    One Sample t-test

data:  daneMieszkania.Biskupin$cena
t = 37.585, df = 64, p-value < 2.2e-16
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 179422 199566
sample estimates:
mean of x 
   189494 

Interpretacja wyniku!

daneMieszkania.krzyki <- daneMieszkania %>% 
  filter(dzielnica=="Krzyki")
t.test(daneMieszkania.krzyki$cena, daneMieszkania.Biskupin$cena)

    Welch Two Sample t-test

data:  daneMieszkania.krzyki$cena and daneMieszkania.Biskupin$cena
t = -2.9793, df = 140.82, p-value = 0.003404
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -35468.945  -7173.093
sample estimates:
mean of x mean of y 
   168173    189494 

Interpretacja wyniku!

daneMieszkania.srodmiescie <- daneMieszkania %>% 
  filter(dzielnica=="Srodmiescie")
t.test(daneMieszkania.Biskupin$cena, daneMieszkania.srodmiescie$cena)

    Welch Two Sample t-test

data:  daneMieszkania.Biskupin$cena and daneMieszkania.srodmiescie$cena
t = 2.5079, df = 117.13, p-value = 0.01351
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
  3859.764 32841.317
sample estimates:
mean of x mean of y 
 189494.0  171143.5 

Interpretacja wyniku!

model <- lm(cena ~ dzielnica, data = daneMieszkania)
model2 <- lm(cena ~ dzielnica - 1, data = daneMieszkania)
model

Call:
lm(formula = cena ~ dzielnica, data = daneMieszkania)

Coefficients:
         (Intercept)       dzielnicaKrzyki  dzielnicaSrodmiescie  
              189494                -21321                -18351  
anova(model)
Analysis of Variance Table

Response: cena
           Df     Sum Sq    Mean Sq F value   Pr(>F)   
dzielnica   2 1.7995e+10 8997691613  5.0456 0.007294 **
Residuals 197 3.5130e+11 1783263361                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Interpretacja wyniku!

detach(package:tidyverse)
detach(package:ggplot2)
detach(package:tibble)
detach(package:tidyr)
detach(package:readr)
detach(package:purrr)
detach(package:dplyr)
detach(package:stringr)
detach(package:forcats)

# detach(package:normtest)
# detach(package:lmtest)
LS0tDQp0aXRsZTogIk1ldG9keSBwcm9iYWJpbGlzdHljem5lIGkgc3RhdHl0eWthIC0gbGFib3JhdG9yaXVtIDYgKHJlYWxpemFjamEpIg0Kc3VidGl0bGU6ICIiDQphdXRob3I6DQotIEphcm9zxYJhdyBLb3Rvd2ljejoNCiAgICBjb3JyZXNwb25kZW5jZTogbm8NCiAgICBlbWFpbDogai5rb3Rvd2ljekB1d2IuZWR1LnBsDQogICAgaW5zdGl0dXRlOiBJSVV3Qg0KZGF0ZTogIjcgaSAxNCBtYWphIDIwMjByLiINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazoNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgaGlnaGxpZ2h0OiBoYWRkb2NrDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBwYW5kb2NfYXJnczoNCiAgICAtIC0tbHVhLWZpbHRlcj1zY2hvbGFybHktbWV0YWRhdGEubHVhDQogICAgLSAtLWx1YS1maWx0ZXI9YXV0aG9yLWluZm8tYmxvY2tzLmx1YQ0KICAgIHRoZW1lOiBjZXJ1bGVhbg0KICAgIHRvYzogeWVzDQppbnN0aXR1dGU6DQotIElJVXdCOiBaYWvFgmFkIEJpb2luZm9ybWF0eWtpLCBJbnN0eXR1dCBJbmZvcm1hdHlraSwgVW5pd2Vyc3l0ZXQgdyBCaWHFgnltc3Rva3UNCmNzbDogYmlnLWRhdGEtYW5kLWluZm9ybWF0aW9uLWFuYWx5dGljcy5jc2wNCmFsd2F5c19hbGxvd19odG1sOiB5ZXMNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQojIFJlYWxpemFjamEgNyBtYWphIDIwMjByLg0KDQojIyBHcnVwYSAxIGkgMg0KDQojIyMgUG9kY3p5dGFuaWUgYmlibGlvdGVraSBpIGRhbnljaCANCmBgYHtyfQ0Kcm0obGlzdCA9IGxzKCkpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KDQpgYGB7cn0NCmRhbmVNaWVzemthbmlhIDwtIHJlYWRfZGVsaW0oImh0dHA6Ly93d3cuYmllY2VrLnBsL1IvZGFuZS9kYW5lTWllc3prYW5pYS5jc3YiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjsiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXNjYXBlX2RvdWJsZSA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJpbV93cyA9IFRSVUUpDQpgYGANCg0KIyMjIFByemVrc3p0YcWCY2VuaWUgem1pZW5uY3loIG5hcGlzb3d5Y2ggbmEgY3p5bm5pa293ZQ0KYGBge3J9DQpkYW5lTWllc3prYW5pYSAlPiUgc3VtbWFyeQ0KYGBgDQoNCmBgYHtyfQ0KZGFuZU1pZXN6a2FuaWEgPC0gZGFuZU1pZXN6a2FuaWEgJT4lDQogIG11dGF0ZV9pZihpcy5jaGFyYWN0ZXIsIGxpc3QoZmFjdG9yKSkNCmBgYA0KDQpgYGB7cn0NCmRhbmVNaWVzemthbmlhICU+JSBzdW1tYXJ5DQpgYGANCg0KIyMjIEJ1ZG93YSBtb2RlbGkgcmVncmVzamkgaSBBTk9WQSAodGVzdG93YW5pZSByw7N3bm/Fm2NpIMWbcmVkbmljaCB3IHBvZGdydXBhY2gpDQpgYGB7cn0NCm1vZGVsIDwtIGxtKGNlbmEgfiBkemllbG5pY2EsIGRhdGEgPSBkYW5lTWllc3prYW5pYSkNCm1vZGVsDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCm1vZGVsXzEgPC0gbG0oY2VuYSB+IGR6aWVsbmljYSAtIDEsIGRhdGEgPSBkYW5lTWllc3prYW5pYSkNCm1vZGVsXzENCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0KYW5vdmEobW9kZWwpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCmFub3ZhKG1vZGVsXzEpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCm1vZGVsJHJlc2lkdWFscyAgJT4lIGhlYWQNCmBgYA0KDQojIyMjIFRlc293YW5pZSB6YcWCb8W8ZcWEIHJlZ3Jlc2ppDQpgYGB7cn0NCmxpYnJhcnkobm9ybXRlc3QpDQpgYGANCg0KYGBge3J9DQpqYi5ub3JtLnRlc3QobW9kZWwkcmVzaWR1YWxzKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQpsaWJyYXJ5KGxtdGVzdCkNCmBgYA0KDQpgYGB7cn0NCmR3dGVzdChkYW5lTWllc3prYW5pYSRjZW5hIH4gZGFuZU1pZXN6a2FuaWEkZHppZWxuaWNhKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQpncXRlc3QoZGFuZU1pZXN6a2FuaWEkY2VuYSB+IGRhbmVNaWVzemthbmlhJGR6aWVsbmljYSkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCiMjIyMgV3lrcmVzICpwdWRlxYJrby13xIVzeSoNCmBgYHtyfQ0KYm94cGxvdChkYW5lTWllc3prYW5pYSRjZW5hIH4gZGFuZU1pZXN6a2FuaWEkZHppZWxuaWNhKQ0KYGBgDQoNCmBgYHtyfQ0KZGFuZU1pZXN6a2FuaWEgJT4lDQogIGdncGxvdChhZXMoZHppZWxuaWNhLCBjZW5hKSkgKw0KICBnZW9tX2JveHBsb3QoKQ0KYGBgDQoNCmBgYHtyfQ0KZGFuZU1pZXN6a2FuaWEgJT4lDQogIGdncGxvdChhZXMoZHppZWxuaWNhLCBjZW5hKSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIGNvb3JkX2ZsaXAoKQ0KYGBgDQoNCmBgYHtyfQ0KZGV0YWNoKHBhY2thZ2U6dGlkeXZlcnNlKQ0KZGV0YWNoKHBhY2thZ2U6Z2dwbG90MikNCmRldGFjaChwYWNrYWdlOnRpYmJsZSkNCmRldGFjaChwYWNrYWdlOnRpZHlyKQ0KZGV0YWNoKHBhY2thZ2U6cmVhZHIpDQpkZXRhY2gocGFja2FnZTpwdXJycikNCmRldGFjaChwYWNrYWdlOmRwbHlyKQ0KZGV0YWNoKHBhY2thZ2U6c3RyaW5ncikNCmRldGFjaChwYWNrYWdlOmZvcmNhdHMpDQoNCmRldGFjaChwYWNrYWdlOm5vcm10ZXN0KQ0KZGV0YWNoKHBhY2thZ2U6bG10ZXN0KQ0KYGBgDQoNCiMjIEdydXBhIDUNCg0KIyMjIEdlbmVyb3dhbmllIGNpxIVnw7NXIGxpY3piIHBzZXVkb2xvc293eWNoIHogemRhbmVnbyByb3prxYJhZHUNCmBgYHtyfQ0Kcm0obGlzdCA9IGxzKCkpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KE1BU1MpDQpgYGANCg0KYGBge3J9DQpzZXQuc2VlZCgyMDIwMDUwNykNCngubm9ybSA8LSBybm9ybSgxMDAsIG1lYW4gPSAxLCBzZCA9MikNCmBgYA0KDQpgYGB7cn0NCnNldC5zZWVkKDIwMjAwNTA3KQ0KeC5sbm9ybSA8LSBybG5vcm0oMTAwLCBtZWFubG9nID0gLjEsIHNkbG9nID0gMikNCmBgYA0KDQpgYGB7cn0NCnNldC5zZWVkKDIwMjAwNTA3KQ0KeC5nYW1tYSA8LSByZ2FtbWEoMTAwLCAyLCAzKQ0KYGBgDQoNCiMjIyBNZXRvZGEgbmFqd2nEmWtzemVqIHdpYXJvZ29kbm/Fm2NpIChiaWJsaW90ZWsgKipNQVNTKiopIC0gd3l6bmFjemFuaWUgcGFyYW1ldHLDs3cgcm96a8WCYWR1DQpgYGB7cn0NCmZpdGRpc3RyKHgubm9ybSwgIm5vcm1hbCIpDQpgYGANCg0KYGBge3J9DQp4Lm5vcm0uZml0dCA8LSBmaXRkaXN0cih4Lm5vcm0sICJub3JtYWwiKQ0KeC5ub3JtLmZpdHQkZXN0aW1hdGUNCmBgYA0KDQpgYGB7cn0NCngubG5vcm0uZml0dCA8LSBmaXRkaXN0cih4Lmxub3JtLCAibG9nLW5vcm1hbCIpDQp4Lmxub3JtLmZpdHQkZXN0aW1hdGUNCmBgYA0KDQpgYGB7cn0NCih4Lmxub3JtLmZpdHQgPC0gZml0ZGlzdHIoeC5sbm9ybSwgImxvZy1ub3JtYWwiKSkNCmBgYA0KDQpgYGB7cn0NCih4Lmxub3JtR2FtbWEuZml0dCA8LSBmaXRkaXN0cih4Lmxub3JtLCAiZ2FtbWEiLCBsaXN0KHNoYXBlID0gMywgcmF0ZSA9IDIpKSkNCmBgYA0KDQojIyMgUG9kY3p5dGFuaWUgYmlibGlvdGVraSBpIGRhbnljaCANCmBgYHtyfQ0KbGlicmFyeShyZWFkcikNCmRhbmVNaWVzemthbmlhIDwtIHJlYWRfZGVsaW0oImh0dHA6Ly93d3cuYmllY2VrLnBsL1IvZGFuZS9kYW5lTWllc3prYW5pYS5jc3YiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjsiLCBlc2NhcGVfZG91YmxlID0gRkFMU0UsIHRyaW1fd3MgPSBUUlVFKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpgYGANCg0KYGBge3J9DQpkYW5lTWllc3prYW5pYSAlPiUgc3VtbWFyeQ0KYGBgDQoNCmBgYHtyfQ0KZGFuZU1pZXN6a2FuaWEgPC0gZGFuZU1pZXN6a2FuaWEgJT4lDQogIG11dGF0ZV9pZihpcy5jaGFyYWN0ZXIsIGxpc3QoZmFjdG9yKSkNCmBgYA0KDQpgYGB7cn0NCmRhbmVNaWVzemthbmlhICU+JSBzdW1tYXJ5DQpgYGANCg0KIyMjIFRlc3Rvd2FuaWUgcsOzd25vxZtjaSDFm3JlZG5pY2ggKCp0LnRlc3QqKQ0KYGBge3J9DQp0LnRlc3QoKGRhbmVNaWVzemthbmlhW2RhbmVNaWVzemthbmlhJGR6aWVsbmljYSA9PSAiQmlza3VwaW4iLF0pJGNlbmEsIA0KICAgICAgIChkYW5lTWllc3prYW5pYVtkYW5lTWllc3prYW5pYSRkemllbG5pY2EgPT0gIktyenlraSIsXSkkY2VuYSkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0KZGFuZU1pZXN6a2FuaWFbZGFuZU1pZXN6a2FuaWEkZHppZWxuaWNhID09ICJLcnp5a2kiLF0NCmBgYA0KDQojIyMgUmVncmVzamEgaSB0ZXN0b3dhbmllIHLDs3dub8WbY2kgxZtyZWRuaWNoICgqQU5PVkEqKQ0KYGBge3J9DQptb2RlbCA8LSBsbShjZW5hIH4gZHppZWxuaWNhLCBkYXRhID0gZGFuZU1pZXN6a2FuaWEpDQptb2RlbA0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQphbm92YShtb2RlbCkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0KbW9kZWwyIDwtIGxtKGNlbmEgfiBkemllbG5pY2EgLSAxLCBkYXRhID0gZGFuZU1pZXN6a2FuaWEpDQptb2RlbDINCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0KYW5vdmEobW9kZWwyKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KIyMjIENvxZsgbmEgYm9rdSAtIHXFvHljaWUgKiphdHRhY2gqKiBkbyByYW1raSBkYW55Y2gNCmBgYHtyfQ0KYXR0YWNoKGRhbmVNaWVzemthbmlhKQ0KYGBgDQoNCmBgYHtyfQ0KYm94cGxvdChjZW5hfmR6aWVsbmljYSkNCmBgYA0KYGBge3J9DQpkZXRhY2goZGFuZU1pZXN6a2FuaWEpDQpgYGANCg0KIyMjIFJlZ3Jlc2phIGkgdGVzdG93YW5pZSByw7N3bm/Fm2NpIMWbcmVkbmljaCAoKkFOT1ZBKikgYy5kLg0KYGBge3J9DQpjb2xuYW1lcyhkYW5lTWllc3prYW5pYSlbNV0gPC0gInR5cCINCmBgYA0KDQpgYGB7cn0NCm1vZGVsMyA8LSBsbShjZW5hIH4gdHlwLCBkYXRhID0gZGFuZU1pZXN6a2FuaWEpDQptb2RlbDMNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0KYW5vdmEobW9kZWwzKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQptb2RlbDQgPC0gbG0oY2VuYSB+IHR5cCAtIDEsIGRhdGEgPSBkYW5lTWllc3prYW5pYSkNCm1vZGVsNA0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQphbm92YShtb2RlbDQpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQojIyMgVGVzdG93YW5pZSB6YcWCb8W8ZcWEIHJlZ3Jlc2ppDQoNCmBgYHtyfQ0KbW9kZWw0JHJlc2lkdWFscyAlPiUgbGVuZ3RoKCkNCmBgYA0KDQpgYGB7cn0NCmtzLnRlc3QobW9kZWw0JHJlc2lkdWFscywgInBub3JtIikNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0Kbm9ydGVzdDo6YWQudGVzdChtb2RlbDQkcmVzaWR1YWxzKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQp0c2VyaWVzOjpqYXJxdWUuYmVyYS50ZXN0KG1vZGVsNCRyZXNpZHVhbHMpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCmRldGFjaChwYWNrYWdlOnRpZHl2ZXJzZSkNCmRldGFjaChwYWNrYWdlOmdncGxvdDIpDQpkZXRhY2gocGFja2FnZTp0aWJibGUpDQpkZXRhY2gocGFja2FnZTp0aWR5cikNCmRldGFjaChwYWNrYWdlOnJlYWRyKQ0KZGV0YWNoKHBhY2thZ2U6cHVycnIpDQpkZXRhY2gocGFja2FnZTpkcGx5cikNCmRldGFjaChwYWNrYWdlOnN0cmluZ3IpDQpkZXRhY2gocGFja2FnZTpmb3JjYXRzKQ0KDQpkZXRhY2gocGFja2FnZTpNQVNTKQ0KYGBgDQoNCiMgUmVhbGl6YWNqYSAxNCBtYWphIDIwMjByLg0KDQojIyBHcnVwYSAxIGkgMg0KDQojIyMgS2lsa2EgdXdhZyBvIHBvem9zdGHFgnljaCB0ZXN0YWNoIG5pZXBhcmFtZXRyeWN6bnljaA0KYGBge3J9DQpybShsaXN0ID0gbHMoKSkNCmBgYA0KDQojIyMjIEZ1bmtjamEgKnNhbXBsZSoNCmBgYHtyfQ0Kc2V0LnNlZWQoOTA4KQ0KcHJvYmthIDwtIHNhbXBsZShjKCJ4IiwgInkiLCAieiIpLCAxMDAsIHJlcGxhY2UgPSBUUlVFLCBwcm9iID0gYyguMywgLjUsIC4yKSkNCmBgYA0KDQpgYGB7cn0NCnN1bW1hcnkocHJvYmthKQ0KYGBgDQoNCmBgYHtyfQ0KcHJvYmthDQpgYGANCg0KIyMjIyBGdW5rY2phICpkYXRhLmZyYW1lKg0KYGBge3J9DQpwcm9ia2EyIDwtIHNhbXBsZShjKCJhIiwgImIiKSwgMTAwLCByZXBsYWNlID0gVFJVRSwgcHJvYiA9IGMoLjgsIC4yKSkNCmRmIDwtIGRhdGEuZnJhbWUocHJvYmthID0gcHJvYmthLCBwcm9ia2EyID0gcHJvYmthMikNCmBgYA0KDQojIyMjIEZ1bmtjamEgKnRhYmxlKiAtIHRhYmxpY2Ega29udHluZ2VuY2ppDQpgYGB7cn0NCnRhYmxpY2EgPC0gdGFibGUoZGYkcHJvYmthLCBkZiRwcm9ia2EyKQ0KdGFibGljYQ0KYGBgDQoNCiMjIyMgVGVzdCBuaWV6YWxlxbxub8WbY2kgY2hpLWt3YWRyYXQNCmBgYHtyfQ0KY2hpc3EudGVzdCh0YWJsaWNhKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQpzZXQuc2VlZCg5MDgpDQp4Lm5vcm08LXJub3JtKDEwMDAsNSwyKQ0Kc2V0LnNlZWQoOTA4KQ0KeC5nYW1tYTwtcmdhbW1hKDEwMDAsMiwzKQ0KYGBgDQoNCiMjIyMgVGVzdG93YW5pZSBuaWV6YWxlxbxub8WbY2kgcHJ6eSB1xbx5Y2l1IHdzcMOzxYJjenluaWthIGtvcmVsYWNqaSAoUGVhcnNvbmEgaSBTcGVhcm1hbmEpDQoNCjxoND48c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+Tmlld8WCYcWbY2l3ZSBzdG9zb3dhbmllIChuaWVzcGXFgm5pb25lIHphxYJvxbxlbmllIG8gbm9ybWFsbm/Fm2NpKTwvc3Bhbj48L2g0Pg0KYGBge3J9DQpjb3IudGVzdCh4Lm5vcm0seC5nYW1tYSkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0KY29yLnRlc3QoeC5ub3JtLHguZ2FtbWEsbWV0aG9kPSJzcGVhcm1hbiIpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCmNvci50ZXN0KHgubm9ybVsxOjEwMF0seC5ub3JtWzkwMToxMDAwXSkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCiMjIyBLaWxrYSB1d2FnIG8gcG96b3N0YcWCeWNoIHRlc3RhY2ggcGFyYW1ldHJ5Y3pueWNoDQoNCiMjIyMgVGVzdG93YW5pZSByw7N3bm/Fm2NpIHdhcmlhbmNqaQ0KDQpgYGB7cn0NCnNldC5zZWVkKDkwOCkNCngubm9ybTIgPC0gcm5vcm0oMTAwMCwzLDIpDQpgYGANCg0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBQYW1pxJl0YWogbyB6YcWCb8W8ZW5pYWNoITwvc3Bhbj4NCmBgYHtyfQ0KdmFyLnRlc3QoeC5ub3JtLCB4Lm5vcm0yKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQp2YXIudGVzdCh4Lm5vcm1bMToxMDBdLCB4Lm5vcm1bOTAxOjEwMDBdKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQptb29kLnRlc3QoeC5ub3JtLCB4Lm5vcm0yKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQphbnNhcmkudGVzdCh4Lm5vcm0sIHgubm9ybTIpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQojIyMjIFRlc3Rvd2FuaWUgZnJha2NqaQ0KYGBge3J9DQpwcm9wLnRlc3QoMzk5LCAxMDAwLCAuNSkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCiMjIyMjIEZ1bmtjamEgKnNhbXBsZSoNCmBgYHtyfQ0Kc2V0LnNlZWQoOTA4KQ0KcHJvYmthMyA8LSBzYW1wbGUoYygwLDEpLCAxMDAsIHJlcGxhY2U9VFJVRSwgcHJvYiA9IGMoLjQsIC42KSkNCmBgYA0KDQpgYGB7cn0NCnN1bShwcm9ia2EzKQ0KYGBgDQoNCmBgYHtyfQ0KcHJvcC50ZXN0KHN1bShwcm9ia2EzKSwgbGVuZ3RoKHByb2JrYTMpLCAuNikNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0KcHJvcC50ZXN0KHN1bShwcm9ia2EzKSwgbGVuZ3RoKHByb2JrYTMpLCAuNykNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCiMjIyBNaWFyeSB6YWxlxbxub8WbY2kgb3BhcnRlIG5hIHN0YXR5c3R5Y2UgY2hpLWt3YWRyYXQNCmBgYHtyfQ0KRGVzY1Rvb2xzOjpDcmFtZXJWKHRhYmxpY2EpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KERlc2NUb29scykNCmBgYA0KDQpgYGB7cn0NCkNvbnRDb2VmKHRhYmxpY2EpDQpgYGANCg0KYGBge3J9DQpQaGkodGFibGljYSkNCmBgYA0KDQpgYGB7cn0NClRzY2h1cHJvd1QodGFibGljYSkNCmBgYA0KDQojIyMgUmVncmVzamEsIEFOT1ZBIGkgdGVzdG93YW5pZSBpY2ggemHFgm/FvGXFhA0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KDQpgYGB7cn0NCmRhbmVNaWVzemthbmlhIDwtIHJlYWRfZGVsaW0oImh0dHA6Ly93d3cuYmllY2VrLnBsL1IvZGFuZS9kYW5lTWllc3prYW5pYS5jc3YiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjsiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXNjYXBlX2RvdWJsZSA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJpbV93cyA9IFRSVUUpDQpgYGANCg0KYGBge3J9DQpkYW5lTWllc3prYW5pYSA8LSBkYW5lTWllc3prYW5pYSAlPiUNCiAgbXV0YXRlX2lmKGlzLmNoYXJhY3RlciwgbGlzdChmYWN0b3IpKQ0KYGBgDQoNCmBgYHtyfQ0KZGFuZU1pZXN6a2FuaWEgJT4lIHN1bW1hcnkNCmBgYA0KDQpgYGB7cn0NCm1vZGVsIDwtIGxtKGNlbmEgfiBkemllbG5pY2EsIGRhdGEgPSBkYW5lTWllc3prYW5pYSkNCm1vZGVsXzEgPC0gbG0oY2VuYSB+IGR6aWVsbmljYSAtIDEsIGRhdGEgPSBkYW5lTWllc3prYW5pYSkNCmBgYA0KDQojIyMjIFRlc3Rvd2FuaWUgYXV0b2tvcmVsYWNqaSANCmBgYHtyfQ0KbG10ZXN0Ojpkd3Rlc3QobW9kZWwpDQojIGJyYWsgcG9kc3RhdyBkbyBvZHJ6dWNlbmlhIGhpb3B0ZXp5IG8gYnJha3UgYXV0b2tvcmVsYWNqaQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQptb2RlbCRyZXNpZHVhbHMgJT4lIGhlYWQoMTApDQpgYGANCiMjIyMgVGVzdG93YW5pZSBub3JtYWxub8WbY2kNCmBgYHtyfQ0Kbm9ydGVzdDo6Y3ZtLnRlc3QobW9kZWwkcmVzaWR1YWxzKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQpub3J0ZXN0OjpzZi50ZXN0KG1vZGVsJHJlc2lkdWFscykNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0Kbm9ybXRlc3Q6OmpiLm5vcm0udGVzdChtb2RlbCRyZXNpZHVhbHMpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCmRldGFjaChwYWNrYWdlOnRpZHl2ZXJzZSkNCmRldGFjaChwYWNrYWdlOmdncGxvdDIpDQpkZXRhY2gocGFja2FnZTp0aWJibGUpDQpkZXRhY2gocGFja2FnZTp0aWR5cikNCmRldGFjaChwYWNrYWdlOnJlYWRyKQ0KZGV0YWNoKHBhY2thZ2U6cHVycnIpDQpkZXRhY2gocGFja2FnZTpkcGx5cikNCmRldGFjaChwYWNrYWdlOnN0cmluZ3IpDQpkZXRhY2gocGFja2FnZTpmb3JjYXRzKQ0KDQpkZXRhY2gocGFja2FnZTpEZXNjVG9vbHMpDQpgYGANCg0KIyMgR3J1cGEgNg0KDQojIyMgUG96b3N0YcWCZSB0ZXN0eSBwYXJhbWV0cnljem5lIGkgbmllcGFyYW1ldHJ5Y3puZQ0KYGBge3J9DQpybShsaXN0ID0gbHMoKSkNCmBgYA0KDQpgYGB7cn0NCnNldC5zZWVkKDE3MzUpDQp4Lm5vcm0gPC0gcm5vcm0oMTAwMCwgbWVhbiA9IDUsIHNkID0gMSkNCmBgYA0KDQpgYGB7cn0NCnNldC5zZWVkKDE3MzUpDQp4LmdhbW1hIDwtIHJnYW1tYSgxMDAwLCAzLCA1KQ0KYGBgDQoNCiMjIyBUZXN0b3dhbmllIHdhcmlhbmNqaQ0KYGBge3J9DQp2YXIudGVzdCh4Lm5vcm1bMToxMDBdLCB4Lm5vcm1bMzAxOjQwMF0pDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCm1vb2QudGVzdCh4Lm5vcm1bMToxMDBdLCB4Lm5vcm1bOTAxOjEwMDBdKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQphbnNhcmkudGVzdCh4Lm5vcm1bNTAxOjYwMF0sIHgubm9ybVs3MDE6ODAwXSkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCiMjIyBUZXN0b3dhbmllIGZyYWtjamkNCmBgYHtyfQ0KcHJvcC50ZXN0KDI5NSwgNzUwLCAuNDUpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCnByb3AudGVzdCgyOTUsIDc1MCwgLjQpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQojIyMjIEZ1bmtjamEgKnNhbXBsZSoNCmBgYHtyfQ0KcHJvYmEgPC0gc2FtcGxlKDA6MSwgMTAwMCwgcmVwbGFjZT1UUlVFLCBwcm9iID0gYyguMiwgLjgpKQ0Kc3VtKHByb2JhKQ0KYGBgDQoNCmBgYHtyfQ0KcHJvcC50ZXN0KHN1bShwcm9iYSksIGxlbmd0aChwcm9iYSksIC43OCkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0KejEgPC0gc2FtcGxlKGMoIngiLCJ5IiwieiIpLCAxMDAsIHJlcGxhY2UgPSBUUlVFLCBwcm9iID0gYyguMywgLjQsIC4zKSkNCnoyIDwtIHNhbXBsZShjKCJhIiwiYiIpLCAxMDAsIHJlcGxhY2UgPSBUUlVFLCBwcm9iID0gYyguNywgLjMpKQ0KYGBgDQoNCiMjIyMgVGFibGljYSBrb250eW5nZW5jamkgaSBmdW5rY2phICp0YWJsZSoNCmBgYHtyfQ0KdGFibGljYSA8LSB0YWJsZSh6MSwgejIpDQp0YWJsaWNhIA0KYGBgDQoNCiMjIyBUZXN0IG5pZXphbGXFvG5vxZtjaSBjaGkta3dhZHJhdA0KYGBge3J9DQpjaGlzcS50ZXN0KHRhYmxpY2EpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQojIyMjIEZ1bmtjamEgKmRhdGEuZnJhbWUqDQpgYGB7cn0NCmRmIDwtIGRhdGEuZnJhbWUoejE9ejEsIHoyPXoyKQ0KYGBgDQoNCiMjIyBUZXN0b3dhbmllIHdzcMOzxYJjenlubmlrYSBrb3JlbGFjamkgUGVhcnNvbmEgaSByYW5nIFNwZWFybWFuYQ0KDQpUYWsgc3Rvc293YW55IHRlc3QgY2hpLWt3YWRyYXQgb2Jvd2nEhXp1amUgdHlsa28gZGxhIHdpZWxvd3ltaWFyb3dlZ28gcm96a8WCYWR1IG5vcm1hbG5lZ28NCmBgYHtyfQ0KY29yLnRlc3QoeC5ub3JtLCB4LmdhbW1hKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQpjb3IudGVzdCh4Lm5vcm0sIHguZ2FtbWEsIG1ldGhvZCA9ICJzcGVhcm1hbiIpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQojIyMgTWlhcnkgemFsZcW8bm/Fm2NpIG9wYXJ0ZSBuYSBzdGF0eXN0eWNlIGNoaS1rd2FkcmF0DQpgYGB7cn0NCkRlc2NUb29sczo6Q3JhbWVyVih0YWJsaWNhKQ0KYGBgDQoNCmBgYHtyfQ0KQ3JhbWVyVih0YWJsaWNhKQ0KYGBgDQoNCmBgYHtyfQ0KRGVzY1Rvb2xzOjpQaGkodGFibGljYSkNCmBgYA0KDQpgYGB7cn0NCkRlc2NUb29sczo6Q29udENvZWYodGFibGljYSkNCmBgYA0KDQpgYGB7cn0NCkRlc2NUb29sczo6VHNjaHVwcm93VCh0YWJsaWNhKQ0KYGBgDQoNCiMjIyBUZXN0b3dhbmllIHLDs3dub8WbY2kgxZtyZWRuaWNoICgqdC50ZXN0KiBpICpBTk9WQSopDQpgYGB7cn0NCmxpYnJhcnkocmVhZHIpDQpkYW5lTWllc3prYW5pYSA8LSByZWFkX2RlbGltKCJodHRwOi8vd3d3LmJpZWNlay5wbC9SL2RhbmUvZGFuZU1pZXN6a2FuaWEuY3N2IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICI7IiwgZXNjYXBlX2RvdWJsZSA9IEZBTFNFLCB0cmltX3dzID0gVFJVRSkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KYGBgDQoNCmBgYHtyfQ0KZGFuZU1pZXN6a2FuaWEgPC0gZGFuZU1pZXN6a2FuaWEgJT4lDQogIG11dGF0ZV9pZihpcy5jaGFyYWN0ZXIsIGxpc3QoZmFjdG9yKSkNCmBgYA0KDQpgYGB7cn0NCmRhbmVNaWVzemthbmlhLkJpc2t1cGluIDwtIGRhbmVNaWVzemthbmlhICU+JSANCiAgZmlsdGVyKGR6aWVsbmljYT09IkJpc2t1cGluIikNCmBgYA0KDQpgYGB7cn0NCmRhbmVNaWVzemthbmlhLkJpc2t1cGluICU+JSBzdW1tYXJ5DQpgYGANCg0KYGBge3J9DQpkYW5lTWllc3prYW5pYS5CaXNrdXBpbiAlPiUgZGltDQpgYGANCg0KYGBge3J9DQp0LnRlc3QoZGFuZU1pZXN6a2FuaWEuQmlza3VwaW4kY2VuYSkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0KZGFuZU1pZXN6a2FuaWEua3J6eWtpIDwtIGRhbmVNaWVzemthbmlhICU+JSANCiAgZmlsdGVyKGR6aWVsbmljYT09IktyenlraSIpDQpgYGANCg0KYGBge3J9DQp0LnRlc3QoZGFuZU1pZXN6a2FuaWEua3J6eWtpJGNlbmEsIGRhbmVNaWVzemthbmlhLkJpc2t1cGluJGNlbmEpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCmRhbmVNaWVzemthbmlhLnNyb2RtaWVzY2llIDwtIGRhbmVNaWVzemthbmlhICU+JSANCiAgZmlsdGVyKGR6aWVsbmljYT09IlNyb2RtaWVzY2llIikNCmBgYA0KDQpgYGB7cn0NCnQudGVzdChkYW5lTWllc3prYW5pYS5CaXNrdXBpbiRjZW5hLCBkYW5lTWllc3prYW5pYS5zcm9kbWllc2NpZSRjZW5hKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQptb2RlbCA8LSBsbShjZW5hIH4gZHppZWxuaWNhLCBkYXRhID0gZGFuZU1pZXN6a2FuaWEpDQptb2RlbDIgPC0gbG0oY2VuYSB+IGR6aWVsbmljYSAtIDEsIGRhdGEgPSBkYW5lTWllc3prYW5pYSkNCmBgYA0KDQpgYGB7cn0NCm1vZGVsDQpgYGANCg0KYGBge3J9DQphbm92YShtb2RlbCkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0KZGV0YWNoKHBhY2thZ2U6dGlkeXZlcnNlKQ0KZGV0YWNoKHBhY2thZ2U6Z2dwbG90MikNCmRldGFjaChwYWNrYWdlOnRpYmJsZSkNCmRldGFjaChwYWNrYWdlOnRpZHlyKQ0KZGV0YWNoKHBhY2thZ2U6cmVhZHIpDQpkZXRhY2gocGFja2FnZTpwdXJycikNCmRldGFjaChwYWNrYWdlOmRwbHlyKQ0KZGV0YWNoKHBhY2thZ2U6c3RyaW5ncikNCmRldGFjaChwYWNrYWdlOmZvcmNhdHMpDQoNCiMgZGV0YWNoKHBhY2thZ2U6bm9ybXRlc3QpDQojIGRldGFjaChwYWNrYWdlOmxtdGVzdCkNCmBgYA0K