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

Correspondence: Jarosław Kotowicz <>

1 Grupa 2 (6 maja 2020r.)

1.1 Praca z danymi i testowanie hipotez

1.1.1 Czyszczenie danych globalnych i podczytanie danych

rm(list = ls())
library(readr)
dane <- read_csv("http://www.jaredlander.com/data/acsNew.csv")
Parsed with column specification:
cols(
  Acres = col_character(),
  FamilyIncome = col_double(),
  FamilyType = col_character(),
  NumBedrooms = col_double(),
  NumChildren = col_double(),
  NumPeople = col_double(),
  NumRooms = col_double(),
  NumUnits = col_character(),
  NumVehicles = col_double(),
  NumWorkers = col_double(),
  OwnRent = col_character(),
  YearBuilt = col_character(),
  HouseCosts = col_double(),
  ElectricBill = col_double(),
  FoodStamp = col_character(),
  HeatingFuel = col_character(),
  Insurance = col_double(),
  Language = col_character(),
  Income = col_character()
)
Ostrzeżenie: zamykanie nieużywanego połączenia 3 (http://www.jaredlander.com/data/acsNew.csv)

1.1.2 Praca z danymi (tworzenie nowych zmiennych)

library(tidyverse)
Registered S3 method overwritten by 'dplyr':
  method           from
  print.rowwise_df     
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
-- 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()
dane <- dane %>%
  mutate(FamilyIncomeSd = (FamilyIncome - mean(FamilyIncome))/sd(FamilyIncome))

1.1.3 Testowanie hipotez nieparametrycznych

1.1.3.1 Testowanie zgodności z rozkładem normalnym

library(nortest)

Jak nie należy wywoływać (brak nazw zmiennych w środowisku)

ad.test(FamilyIncomesd)
Błąd w poleceniu 'sort(x[complete.cases(x)])':
  nie znaleziono obiektu 'FamilyIncomesd'

Prawidłowy sposób wywołania

ad.test(dane$FamilyIncomeSd)

    Anderson-Darling normality test

data:  dane$FamilyIncomeSd
A = 132.37, p-value < 2.2e-16

Interpretacja wyniku!

Można dołączyć nazwy zmiennych z ramki danych do zmiennych globalnych

attach(dane)

I wywołać test

ad.test(FamilyIncomeSd)

    Anderson-Darling normality test

data:  FamilyIncomeSd
A = 132.37, p-value < 2.2e-16

Interpretacja wyniku!

Usunięcie nazwy zmiennych ze środowiska

detach(dane)

Ponownie nie działa

ad.test(FamilyIncomesd)
Błąd w poleceniu 'sort(x[complete.cases(x)])':
  nie znaleziono obiektu 'FamilyIncomesd'

Test Kołomogorowa-Smirnowa

ks.test(dane$FamilyIncomeSd, "pnorm")
warto㤼㹣ci powt昼㸳rzone nie powinny by攼㸶 obecne w te㤼㹣cie Kolmogorowa-Smirnowa

    One-sample Kolmogorov-Smirnov test

data:  dane$FamilyIncomeSd
D = 0.15075, p-value < 2.2e-16
alternative hypothesis: two-sided

Interpretacja wyniku!

mean(dane$FamilyIncomeSd)
[1] 6.661647e-17
sd(dane$FamilyIncomeSd)
[1] 1

Interpretacja wyniku!

1.1.3.2 Generowanie ciągu liczb psudolosowych z rozkładu jednostajnego

set.seed(1115)
a <- runif(1000, -10, 5)

1.1.3.3 Testowanie zgodności z rozkładem jednostajnym

ks.test(a, "punif")

    One-sample Kolmogorov-Smirnov test

data:  a
D = 0.66, p-value < 2.2e-16
alternative hypothesis: two-sided

Interpretacja wyniku!

ks.test(a, "punif", -10, 5)

    One-sample Kolmogorov-Smirnov test

data:  a
D = 0.024471, p-value = 0.5872
alternative hypothesis: two-sided

Interpretacja wyniku!

ks.test(a, "punif", -12, 6)

    One-sample Kolmogorov-Smirnov test

data:  a
D = 0.11141, p-value = 3.313e-11
alternative hypothesis: two-sided

Interpretacja wyniku!

2 Grupa 1 (13 maja 2020r.)

2.1 Praca z danymi i testowanie hipotez

2.1.1 Czyszczenie danych globalnych i podczytanie danych

rm(list=ls())
# library(nortest)
# library(tidyverse)
dane <- read_csv("http://www.jaredlander.com/data/acsNew.csv")
Parsed with column specification:
cols(
  Acres = col_character(),
  FamilyIncome = col_double(),
  FamilyType = col_character(),
  NumBedrooms = col_double(),
  NumChildren = col_double(),
  NumPeople = col_double(),
  NumRooms = col_double(),
  NumUnits = col_character(),
  NumVehicles = col_double(),
  NumWorkers = col_double(),
  OwnRent = col_character(),
  YearBuilt = col_character(),
  HouseCosts = col_double(),
  ElectricBill = col_double(),
  FoodStamp = col_character(),
  HeatingFuel = col_character(),
  Insurance = col_double(),
  Language = col_character(),
  Income = col_character()
)
dane <- dane %>%
  mutate_if(is.character,list(as.factor))
dane <- dane %>%
  mutate(FamilyIncomeSd = (FamilyIncome - mean(FamilyIncome))/sd(FamilyIncome))

2.1.1.1 Dołącznie zmiennych (nazw z ramki danych) do środowiska

attach(dane)

2.1.2 Testy zgodności z rozkładem normalnym

sf.test(FamilyIncomeSd)

    Shapiro-Francia normality test

data:  FamilyIncomeSd
W = 0.73234, p-value < 2.2e-16

Interpretacja wyniku!

detach(dane)

2.1.3 Generowanie ciągu liczb pseudolosowych

set.seed(1050)
x.norm01 <- rnorm(1000)

2.1.4 Ponownie testy zgodności z rozkładem normalnym

cvm.test(x.norm01)

    Cramer-von Mises normality test

data:  x.norm01
W = 0.039185, p-value = 0.6967

Interpretacja wyniku!

2.1.4.1 Test zgodności Kołmogorowa-Smirnowa (zgodności z rozkładem wzorocwym i zgodności dóWch rozkładów)

Jak nie robić! (podczytuje wartości domyślne)

ks.test(x.norm01, "pnorm")

    One-sample Kolmogorov-Smirnov test

data:  x.norm01
D = 0.037062, p-value = 0.1282
alternative hypothesis: two-sided

Interpretacja wyniku!

set.seed(1050)
x.norm32 <- rnorm(1000, 3 ,2)

Interpretacja wyniku!

ks.test(x.norm32, "pnorm",0 ,1)

    One-sample Kolmogorov-Smirnov test

data:  x.norm32
D = 0.74095, p-value < 2.2e-16
alternative hypothesis: two-sided

Interpretacja wyniku!

ks.test(x.norm32, "pnorm", 3, 2)

    One-sample Kolmogorov-Smirnov test

data:  x.norm32
D = 0.037062, p-value = 0.1282
alternative hypothesis: two-sided

Interpretacja wyniku!

set.seed(1050)
x.unif <- runif(1000, -1, 1)
ks.test(x.unif, "punif")

    One-sample Kolmogorov-Smirnov test

data:  x.unif
D = 0.50657, p-value < 2.2e-16
alternative hypothesis: two-sided

Interpretacja wyniku!

ks.test(x.unif, "punif",-1, 1)

    One-sample Kolmogorov-Smirnov test

data:  x.unif
D = 0.016202, p-value = 0.9555
alternative hypothesis: two-sided

Interpretacja wyniku!

ks.test(x.unif[1:100],x.unif[901:1000])

    Two-sample Kolmogorov-Smirnov test

data:  x.unif[1:100] and x.unif[901:1000]
D = 0.12, p-value = 0.4676
alternative hypothesis: two-sided

Interpretacja wyniku!

ks.test(x.unif[1:100],x.unif[901:1000],alternative = "less")

    Two-sample Kolmogorov-Smirnov test

data:  x.unif[1:100] and x.unif[901:1000]
D^- = 0.07, p-value = 0.6126
alternative hypothesis: the CDF of x lies below that of y

Interpretacja wyniku!

ks.test(x.unif[1:100],x.unif[901:1000],alternative = "greater")

    Two-sample Kolmogorov-Smirnov test

data:  x.unif[1:100] and x.unif[901:1000]
D^+ = 0.12, p-value = 0.2369
alternative hypothesis: the CDF of x lies above that of y

2.1.5 Testy parametryczne równości wariancji

var.test(x.norm01, x.norm32)

    F test to compare two variances

data:  x.norm01 and x.norm32
F = 0.25, num df = 999, denom df = 999, p-value < 2.2e-16
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
 0.2208247 0.2830300
sample estimates:
ratio of variances 
              0.25 

Interpretacja wyniku!

ansari.test(x.norm01, x.norm32)

    Ansari-Bradley test

data:  x.norm01 and x.norm32
AB = 537652, p-value = 8.709e-09
alternative hypothesis: true ratio of scales is not equal to 1

Interpretacja wyniku!

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

    Mood two-sample test of scale

data:  x.norm01[1:100] and x.norm01[901:1000]
Z = 0.98507, p-value = 0.3246
alternative hypothesis: two.sided

Interpretacja wyniku!

2.2 Regresja

2.2.1 Budowa modelu

model_01 <- lm(FamilyIncome ~ NumPeople, dane)

2.2.2 Podsumowanie modelu

summary(model_01)

Call:
lm(formula = FamilyIncome ~ NumPeople, data = dane)

Residuals:
    Min      1Q  Median      3Q     Max 
-150196  -55913  -22018   25329  905682 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)    88377       5336  16.563  < 2e-16 ***
NumPeople       6647       1450   4.583 4.84e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 96970 on 2271 degrees of freedom
Multiple R-squared:  0.009163,  Adjusted R-squared:  0.008727 
F-statistic:    21 on 1 and 2271 DF,  p-value: 4.836e-06

Interpretacja wyniku!

2.2.3 Wykresy diagnostyczne dla modelu

plot(model_01)

2.2.4 Drugi model

model_02 <- lm(FamilyIncomeSd ~ NumPeople, dane)
summary(model_02)

Call:
lm(formula = FamilyIncomeSd ~ NumPeople, data = dane)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.5421 -0.5741 -0.2261  0.2601  9.2986 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.23209    0.05478  -4.237 2.36e-05 ***
NumPeople    0.06825    0.01489   4.583 4.84e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.9956 on 2271 degrees of freedom
Multiple R-squared:  0.009163,  Adjusted R-squared:  0.008727 
F-statistic:    21 on 1 and 2271 DF,  p-value: 4.836e-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:nortest)
LS0tDQp0aXRsZTogIlN0YXR5c3R5a2EgbWF0ZW1hdHljem5hIChraWVydW5layBpbmZvcm1hdHlrYSBpIGVrb25vbWV0cmlhKSINCnN1YnRpdGxlOiAiUHJhY2EgeiBkYW55bWkgaSB0ZXN0b3dhbmllIGRhbnljaCINCmF1dGhvcjoNCi0gSmFyb3PFgmF3IEtvdG93aWN6Og0KICAgIGNvcnJlc3BvbmRlbmNlOiBubw0KICAgIGVtYWlsOiBqLmtvdG93aWN6QHV3Yi5lZHUucGwNCiAgICBpbnN0aXR1dGU6IElJVXdCDQpkYXRlOiAiNiAoZ3J1cGEgMikgaSAxMyAoZ3J1cGEgMSkgbWFqYSAyMDIwIHIuIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBoaWdobGlnaHQ6IGhhZGRvY2sNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHBhbmRvY19hcmdzOg0KICAgIC0gLS1sdWEtZmlsdGVyPXNjaG9sYXJseS1tZXRhZGF0YS5sdWENCiAgICAtIC0tbHVhLWZpbHRlcj1hdXRob3ItaW5mby1ibG9ja3MubHVhDQogICAgdGhlbWU6IGNlcnVsZWFuDQogICAgdG9jOiB5ZXMNCmluc3RpdHV0ZToNCi0gSUlVd0I6IFpha8WCYWQgQmlvaW5mb3JtYXR5a2ksIEluc3R5dHV0IEluZm9ybWF0eWtpLCBVbml3ZXJzeXRldCB3IEJpYcWCeW1zdG9rdQ0KY3NsOiBiaWctZGF0YS1hbmQtaW5mb3JtYXRpb24tYW5hbHl0aWNzLmNzbA0KYWx3YXlzX2FsbG93X2h0bWw6IHllcw0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KYGBgDQoNCiMgR3J1cGEgMiAoNiBtYWphIDIwMjByLikNCg0KIyMgUHJhY2EgeiBkYW55bWkgaSB0ZXN0b3dhbmllIGhpcG90ZXoNCg0KIyMjIEN6eXN6Y3plbmllIGRhbnljaCBnbG9iYWxueWNoIGkgcG9kY3p5dGFuaWUgZGFueWNoDQpgYGB7cn0NCnJtKGxpc3QgPSBscygpKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShyZWFkcikNCmRhbmUgPC0gcmVhZF9jc3YoImh0dHA6Ly93d3cuamFyZWRsYW5kZXIuY29tL2RhdGEvYWNzTmV3LmNzdiIpDQpgYGANCiMjIyBQcmFjYSB6IGRhbnltaSAodHdvcnplbmllIG5vd3ljaCB6bWllbm55Y2gpDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KYGBgDQoNCmBgYHtyfQ0KZGFuZSA8LSBkYW5lICU+JQ0KICBtdXRhdGUoRmFtaWx5SW5jb21lU2QgPSAoRmFtaWx5SW5jb21lIC0gbWVhbihGYW1pbHlJbmNvbWUpKS9zZChGYW1pbHlJbmNvbWUpKQ0KYGBgDQoNCiMjIyBUZXN0b3dhbmllIGhpcG90ZXogbmllcGFyYW1ldHJ5Y3pueWNoDQoNCiMjIyMgVGVzdG93YW5pZSB6Z29kbm/Fm2NpIHogcm96a8WCYWRlbSBub3JtYWxueW0NCmBgYHtyfQ0KbGlicmFyeShub3J0ZXN0KQ0KYGBgDQoNCkphayBuaWUgbmFsZcW8eSB3eXdvxYJ5d2HEhyAoKipicmFrIG5hencgem1pZW5ueWNoIHcgxZtyb2Rvd2lza3UqKikNCmBgYHtyfQ0KYWQudGVzdChGYW1pbHlJbmNvbWVzZCkNCmBgYA0KDQpQcmF3aWTFgm93eSBzcG9zw7NiIHd5d2/FgmFuaWENCmBgYHtyfQ0KYWQudGVzdChkYW5lJEZhbWlseUluY29tZVNkKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+SW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpNb8W8bmEgZG/FgsSFY3p5xIcgbmF6d3kgem1pZW5ueWNoIHogcmFta2kgZGFueWNoIGRvIHptaWVubnljaCBnbG9iYWxueWNoDQpgYGB7cn0NCmF0dGFjaChkYW5lKQ0KYGBgDQpJIHd5d2/FgmHEhyB0ZXN0DQpgYGB7cn0NCmFkLnRlc3QoRmFtaWx5SW5jb21lU2QpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj5JbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNClVzdW5pxJljaWUgbmF6d3kgem1pZW5ueWNoIHplIMWbcm9kb3dpc2thDQpgYGB7cn0NCmRldGFjaChkYW5lKQ0KYGBgDQpQb25vd25pZSBuaWUgZHppYcWCYQ0KYGBge3J9DQphZC50ZXN0KEZhbWlseUluY29tZXNkKQ0KYGBgDQpUZXN0IEtvxYJvbW9nb3Jvd2EtU21pcm5vd2ENCmBgYHtyfQ0Ka3MudGVzdChkYW5lJEZhbWlseUluY29tZVNkLCAicG5vcm0iKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+SW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCm1lYW4oZGFuZSRGYW1pbHlJbmNvbWVTZCkNCnNkKGRhbmUkRmFtaWx5SW5jb21lU2QpDQoNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPkludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KIyMjIyBHZW5lcm93YW5pZSBjacSFZ3UgbGljemIgcHN1ZG9sb3Nvd3ljaCB6IHJvemvFgmFkdSBqZWRub3N0YWpuZWdvDQpgYGB7cn0NCnNldC5zZWVkKDExMTUpDQphIDwtIHJ1bmlmKDEwMDAsIC0xMCwgNSkNCmBgYA0KDQojIyMjIFRlc3Rvd2FuaWUgemdvZG5vxZtjaSB6IHJvemvFgmFkZW0gamVkbm9zdGFqbnltDQpgYGB7cn0NCmtzLnRlc3QoYSwgInB1bmlmIikNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPkludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQprcy50ZXN0KGEsICJwdW5pZiIsIC0xMCwgNSkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPkludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQprcy50ZXN0KGEsICJwdW5pZiIsIC0xMiwgNikNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPkludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KIyBHcnVwYSAxICgxMyBtYWphIDIwMjByLikNCg0KIyMgUHJhY2EgeiBkYW55bWkgaSB0ZXN0b3dhbmllIGhpcG90ZXoNCg0KIyMjIEN6eXN6Y3plbmllIGRhbnljaCBnbG9iYWxueWNoIGkgcG9kY3p5dGFuaWUgZGFueWNoDQpgYGB7cn0NCnJtKGxpc3Q9bHMoKSkNCmBgYA0KDQpgYGB7cn0NCiMgbGlicmFyeShub3J0ZXN0KQ0KIyBsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KDQpgYGB7cn0NCmRhbmUgPC0gcmVhZF9jc3YoImh0dHA6Ly93d3cuamFyZWRsYW5kZXIuY29tL2RhdGEvYWNzTmV3LmNzdiIpDQpgYGANCg0KYGBge3J9DQpkYW5lIDwtIGRhbmUgJT4lDQogIG11dGF0ZV9pZihpcy5jaGFyYWN0ZXIsbGlzdChhcy5mYWN0b3IpKQ0KYGBgDQoNCmBgYHtyfQ0KZGFuZSA8LSBkYW5lICU+JQ0KICBtdXRhdGUoRmFtaWx5SW5jb21lU2QgPSAoRmFtaWx5SW5jb21lIC0gbWVhbihGYW1pbHlJbmNvbWUpKS9zZChGYW1pbHlJbmNvbWUpKQ0KYGBgDQoNCiMjIyMgRG/FgsSFY3puaWUgem1pZW5ueWNoIChuYXp3IHogcmFta2kgZGFueWNoKSBkbyDFm3JvZG93aXNrYQ0KYGBge3J9DQphdHRhY2goZGFuZSkNCmBgYA0KDQojIyMgVGVzdHkgemdvZG5vxZtjaSB6IHJvemvFgmFkZW0gbm9ybWFsbnltDQpgYGB7cn0NCnNmLnRlc3QoRmFtaWx5SW5jb21lU2QpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCmRldGFjaChkYW5lKQ0KYGBgDQoNCiMjIyBHZW5lcm93YW5pZSBjacSFZ3UgbGljemIgcHNldWRvbG9zb3d5Y2gNCmBgYHtyfQ0Kc2V0LnNlZWQoMTA1MCkNCngubm9ybTAxIDwtIHJub3JtKDEwMDApDQpgYGANCg0KIyMjIFBvbm93bmllIHRlc3R5IHpnb2Rub8WbY2kgeiByb3prxYJhZGVtIG5vcm1hbG55bQ0KYGBge3J9DQpjdm0udGVzdCh4Lm5vcm0wMSkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCiMjIyMgVGVzdCB6Z29kbm/Fm2NpIEtvxYJtb2dvcm93YS1TbWlybm93YSAoemdvZG5vxZtjaSB6IHJvemvFgmFkZW0gd3pvcm9jd3ltIGkgemdvZG5vxZtjaSBkw7NXY2ggcm96a8WCYWTDs3cpDQoNCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSmFrIG5pZSByb2JpxIchIChwb2Rjenl0dWplIHdhcnRvxZtjaSBkb215xZtsbmUpPC9zcGFuPg0KYGBge3J9DQprcy50ZXN0KHgubm9ybTAxLCAicG5vcm0iKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQpzZXQuc2VlZCgxMDUwKQ0KeC5ub3JtMzIgPC0gcm5vcm0oMTAwMCwgMyAsMikNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0Ka3MudGVzdCh4Lm5vcm0zMiwgInBub3JtIiwwICwxKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQprcy50ZXN0KHgubm9ybTMyLCAicG5vcm0iLCAzLCAyKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQpzZXQuc2VlZCgxMDUwKQ0KeC51bmlmIDwtIHJ1bmlmKDEwMDAsIC0xLCAxKQ0KYGBgDQoNCmBgYHtyfQ0Ka3MudGVzdCh4LnVuaWYsICJwdW5pZiIpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCmtzLnRlc3QoeC51bmlmLCAicHVuaWYiLC0xLCAxKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQprcy50ZXN0KHgudW5pZlsxOjEwMF0seC51bmlmWzkwMToxMDAwXSkNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0Ka3MudGVzdCh4LnVuaWZbMToxMDBdLHgudW5pZls5MDE6MTAwMF0sYWx0ZXJuYXRpdmUgPSAibGVzcyIpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCmtzLnRlc3QoeC51bmlmWzE6MTAwXSx4LnVuaWZbOTAxOjEwMDBdLGFsdGVybmF0aXZlID0gImdyZWF0ZXIiKQ0KYGBgDQoNCiMjIyBUZXN0eSBwYXJhbWV0cnljem5lIHLDs3dub8WbY2kgd2FyaWFuY2ppDQpgYGB7cn0NCnZhci50ZXN0KHgubm9ybTAxLCB4Lm5vcm0zMikNCmBgYA0KPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQiPiBJbnRlcnByZXRhY2phIHd5bmlrdSE8L3NwYW4+DQoNCmBgYHtyfQ0KYW5zYXJpLnRlc3QoeC5ub3JtMDEsIHgubm9ybTMyKQ0KYGBgDQo8c3BhbiBzdHlsZT0iY29sb3I6IHJlZCI+IEludGVycHJldGFjamEgd3luaWt1ITwvc3Bhbj4NCg0KYGBge3J9DQptb29kLnRlc3QoeC5ub3JtMDFbMToxMDBdLCB4Lm5vcm0wMVs5MDE6MTAwMF0pDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQojIyBSZWdyZXNqYSANCg0KIyMjIEJ1ZG93YSBtb2RlbHUNCmBgYHtyfQ0KbW9kZWxfMDEgPC0gbG0oRmFtaWx5SW5jb21lIH4gTnVtUGVvcGxlLCBkYW5lKQ0KYGBgDQoNCiMjIyBQb2RzdW1vd2FuaWUgbW9kZWx1DQpgYGB7cn0NCnN1bW1hcnkobW9kZWxfMDEpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQojIyMgV3lrcmVzeSBkaWFnbm9zdHljem5lIGRsYSBtb2RlbHUNCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTh9DQpwbG90KG1vZGVsXzAxKQ0KYGBgDQoNCiMjIyBEcnVnaSBtb2RlbA0KYGBge3J9DQptb2RlbF8wMiA8LSBsbShGYW1pbHlJbmNvbWVTZCB+IE51bVBlb3BsZSwgZGFuZSkNCnN1bW1hcnkobW9kZWxfMDIpDQpgYGANCjxzcGFuIHN0eWxlPSJjb2xvcjogcmVkIj4gSW50ZXJwcmV0YWNqYSB3eW5pa3UhPC9zcGFuPg0KDQpgYGB7cn0NCmRldGFjaChwYWNrYWdlOnRpZHl2ZXJzZSkNCmRldGFjaChwYWNrYWdlOmdncGxvdDIpDQpkZXRhY2gocGFja2FnZTp0aWJibGUpDQpkZXRhY2gocGFja2FnZTp0aWR5cikNCmRldGFjaChwYWNrYWdlOnJlYWRyKQ0KZGV0YWNoKHBhY2thZ2U6cHVycnIpDQpkZXRhY2gocGFja2FnZTpkcGx5cikNCmRldGFjaChwYWNrYWdlOnN0cmluZ3IpDQpkZXRhY2gocGFja2FnZTpmb3JjYXRzKQ0KDQpkZXRhY2gocGFja2FnZTpub3J0ZXN0KQ0KYGBgDQo=