V této úloze budu zpracovávat data z MS v hokeji z roku 2019, konkrétně o data české reprezentace.

Původ dat

Data jsem získala z https://www.quanthockey.com/whc/en/teams/team-czech-republic-players-2019-whc-stats.html a propojila je s údaji získanými z https://www.iihf.com/pdf/690/ihm6900cze_33_5_0_cze

Struktura dat

Data jsou tvořena řádky obsahující údaje pro jednotlivé hráče. A to konkrétně číslo, jméno, pozici (GK - brankář, F - útočník, D - obránce), stranu (levá, pravá), výšku v metrech, váhu v kilogramech, datum narození, klub, věk, počet odehraných zápasů, počet gólů, počet asistencí, počet trestných minut, statistika +/-, počet gólů v přesilové hře, počet gólů v oslabení, počet rozdílových gólů, průměrný počet gólů za utkání, průměrný počet asistencí za utkání a průměrný počet bodů za utkání

Načtení dat

library(ggplot2)
Warning messages:
1: In readChar(file, size, TRUE) : truncating string with embedded nuls
2: In readChar(file, size, TRUE) : truncating string with embedded nuls
3: In readChar(file, size, TRUE) : truncating string with embedded nuls
4: In readChar(file, size, TRUE) : truncating string with embedded nuls
5: In readChar(file, size, TRUE) : truncating string with embedded nuls
6: In readChar(file, size, TRUE) : truncating string with embedded nuls
7: In readChar(file, size, TRUE) : truncating string with embedded nuls
8: In readChar(file, size, TRUE) : truncating string with embedded nuls
9: In readChar(file, size, TRUE) : truncating string with embedded nuls
library(dplyr)
library(ggpubr)
data <-  read.csv("hokej2019.csv", sep = ";")
head(data)
NA

1

V tomto testu budu zkoumat, zda existuje vztah mezi počtem odehraných utkání a celkovým počtem získaných bodů. Očekávám, že čím více zápasů hráč odehrál, tím větší počet bodů získal. Provedu tedy lineární regresi. Nulová hypotéza: mezi počtem odehraných utkání a počtem získaných bodů není lineární vztah.

Nejprve si z dat vyberu vektory obsahující počty získaných bodů a počty odehraných utkání pro jednotlivé hráče mimo brankářů

players_no_gk <- data %>%
  filter(POS != "GK")
points <- players_no_gk$P; points
 [1]  4 14  4  3 11  2  4  6 10 12  2  1  2  7  3 12  1 16  5  1  0  1
games <- players_no_gk$GP; games
 [1]  7 10 10  6 10  5 10 10 10 10  8 10 10 10 10 10  9 10  9  5  8  9

Podívám se, jak data vypadají.

ggplot(players_no_gk, aes(x=GP, y=P)) + 
  geom_point(size=2, alpha=0.8)

Poté spočítám průměrný počet získaných bodů a průměrný počet odehraných zápasů.

points_mean = mean(points); points_mean
[1] 5.5
games_mean = mean(games); games_mean
[1] 8.909091

Spočítám a a b pro regresi.

a = sum((games-games_mean)*(points-points_mean))/sum((games-games_mean)^2); a
[1] 1.370821
b = pointsm - a*gamesm; b
[1] -6.712766

Vynesu přímku do grafu

ggplot(players_no_gk, aes(x=GP,y=P)) + 
  geom_point(size=2) + 
  geom_abline(slope=a, intercept=b, color="red")

Přímka docela dobře sedí pro hráče, kteří nehráli ve všech zápasech. U hráčů, kteří hráli všech 10 zápasů a kterých je největší množství jsou poměrně velké rozdíly - někdo neskóroval téměř žádné body, někteří hráči zas skórovali nadprůměrně.

relation <- lm(points~games)

summary(relation)

Call:
lm(formula = points ~ games)

Residuals:
   Min     1Q Median     3Q    Max 
-5.995 -3.745 -0.310  2.718  9.005 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)  
(Intercept)  -6.7128     5.0732  -1.323   0.2007  
games         1.3708     0.5599   2.448   0.0237 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 4.331 on 20 degrees of freedom
Multiple R-squared:  0.2306,    Adjusted R-squared:  0.1921 
F-statistic: 5.994 on 1 and 20 DF,  p-value: 0.02371
relation$coefficients 
(Intercept)       games 
  -6.712766    1.370821 

p-hodnota vyšla 0,02371, což je méně než hladina významnosti 0,05, takže nulovou hypotézu můžeme zamítnout.

2

V tomto testu budu zkoumat, zda je věk hráčů dobře modelovaný normálním rozdělením.

Budu k tomu používat chi-kvadrát test. Nulová hypotéza: Data jsou modelována normálním rozdělením. Hladina významnosti alfa bude 0.05

Postup

Nejprve si načtu vektor věku hráčů a podívám se, jak data vypadají na histogramu.

age <- data$Age
ggplot(data.frame(age), aes(x = age)) + 
  geom_histogram(bins=6, fill="#FF67A4", color="#e9ecef", alpha=0.8) +
  ggtitle("Histogram věku hráčů")

Histogram vzpadá celkem nadějně, že by se skutečně mohlo jednat o normální rozdělení.

Spočítám průměr, rozptyl a směrodatnou odchylku.

age_mean <- mean(age); age_mean
[1] 26.68
age_var <- var(age); age_var
[1] 12.31
age_sd <- sd(age); age_sd
[1] 3.508561

Vytvořím věkové intervaly: <20, <23, <26, <29, <32, >= 32 Spočítám počet hráčů zastoupených v jednotlivých věkových intervalech a dále pro každý interval spočítám z-skóre. Z skóre počítám jako podíl, kde v čitateli je rozdíl horní hranice intervalu a průměru, ve jmenovateli je směrodatná odchylka

k <- 6
bounds <- c(20,23,26,29,32)

observed <- rep(0,6)
observed[1] <- sum(age < bounds[1])
observed[6] <- sum(age >= bounds[5])
for (i in 2:5) {
  observed[i] <- sum(age < bounds[i]) - sum(age < bounds[i-1])
}

z_scores <- rep(0,5)
for (i in 1:5){
  z_scores[i] <-  (bounds[i] - age_mean) / age_sd
}

Ze z skóre spočítám plochu pod křivkou normální distribuce N(0,1)

area_under <- rep(0,6)
for (i in 1:5) {
  area_under[i] = pnorm(z_scores[i])
}
area_under[6] = 1

Dále spočítám plochu v rámci intervalů

area_inside <- rep(0,6)
area_inside[1] = area_under[1]
for (i in 2:6){
  area_inside[i] = area_under[i] - area_under[i-1]
}

Z toho spočítám očekávané počty hráčů v jednotlivých věkových intervalech

expected <- rep(0,6)
for (i in 1:6) {
  expected[i] <- area_inside[i] * 25
}

Když mám spočítané pozorované a očekávané hodnoty pro jednotlivé intervaly, mohu provést chi-squared test. Počet stupňů volnosti je 5 (6 intervalů - 1)

chi <- 0
for (i in 1:6) {
  chi <- chi + ((observed[i] - expected[i])^2)/expected[i]
}

Závěr

Pro hladinu významnosti a 5 stupňů volnosti je kritická hodnota 11.070. Protože hodnota vyšla menší nemůžeme hypotézu zamítnout.

Další možnosti

Ještě je možné podívat se na Q-Q plot (quantile - quantile plot)

ggqqplot(age)

Z grafu je vidět, že body jsou poměrně blízko přímce, což naznačuje, že by se mohlo jednat o normální rozdělení.

Dále je možné použít Shapiro-Wilkův test normality, pro který v R existuje funkce.

shapiro.test(age)

    Shapiro-Wilk normality test

data:  age
W = 0.98158, p-value = 0.9146

Protože vyšla p-hodnota vyšší než 0,05, nelze hypotézu zamítnout.

LS0tDQp0aXRsZTogIlN0YXRpc3Rpa2EgdsO9c2xlZGvFryBocsOhxI3FryBob2tlam92w6kgcmVwcmV6ZW50YWNlIMSMUiBuYSBNUyAyMDE5Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KViB0w6l0byDDumxvemUgYnVkdSB6cHJhY292w6F2YXQgZGF0YSB6IE1TIHYgaG9rZWppIHogcm9rdSAyMDE5LCBrb25rcsOpdG7EmyBvIGRhdGEgxI1lc2vDqSByZXByZXplbnRhY2UuDQoNCiMjIFDFr3ZvZCBkYXQNCkRhdGEganNlbSB6w61za2FsYSB6IGh0dHBzOi8vd3d3LnF1YW50aG9ja2V5LmNvbS93aGMvZW4vdGVhbXMvdGVhbS1jemVjaC1yZXB1YmxpYy1wbGF5ZXJzLTIwMTktd2hjLXN0YXRzLmh0bWwgYSBwcm9wb2ppbGEgamUgcyDDumRhamkgesOtc2thbsO9bWkgeiBodHRwczovL3d3dy5paWhmLmNvbS9wZGYvNjkwL2lobTY5MDBjemVfMzNfNV8wX2N6ZQ0KDQoNCiMjIFN0cnVrdHVyYSBkYXQNCkRhdGEganNvdSB0dm/FmWVuYSDFmcOhZGt5IG9ic2FodWrDrWPDrSDDumRhamUgcHJvIGplZG5vdGxpdsOpIGhyw6HEjWUuIEEgdG8ga29ua3LDqXRuxJsgxI3DrXNsbywgam3DqW5vLCBwb3ppY2kgKEdLIC0gYnJhbmvDocWZLCBGIC0gw7p0b8SNbsOtaywgRCAtIG9icsOhbmNlKSwgc3RyYW51IChsZXbDoSwgcHJhdsOhKSwgdsO9xaFrdSB2IG1ldHJlY2gsIHbDoWh1IHYga2lsb2dyYW1lY2gsIGRhdHVtIG5hcm96ZW7DrSwga2x1YiwgdsSbaywgcG/EjWV0IG9kZWhyYW7DvWNoIHrDoXBhc8WvLCBwb8SNZXQgZ8OzbMWvLCBwb8SNZXQgYXNpc3RlbmPDrSwgcG/EjWV0IHRyZXN0bsO9Y2ggbWludXQsIHN0YXRpc3Rpa2EgKy8tLCBwb8SNZXQgZ8OzbMWvIHYgcMWZZXNpbG92w6kgaMWZZSwgcG/EjWV0IGfDs2zFryB2IG9zbGFiZW7DrSwgcG/EjWV0IHJvemTDrWxvdsO9Y2ggZ8OzbMWvLCBwcsWvbcSbcm7DvSBwb8SNZXQgZ8OzbMWvIHphIHV0a8OhbsOtLCBwcsWvbcSbcm7DvSBwb8SNZXQgYXNpc3RlbmPDrSB6YSB1dGvDoW7DrSBhIHByxa9txJtybsO9IHBvxI1ldCBib2TFryB6YSB1dGvDoW7DrQ0KDQojIyBOYcSNdGVuw60gZGF0DQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncHVicikNCmRhdGEgPC0gIHJlYWQuY3N2KCJob2tlajIwMTkuY3N2Iiwgc2VwID0gIjsiKQ0KaGVhZChkYXRhKQ0KDQpgYGANCg0KIyMgMQ0KViB0b210byB0ZXN0dSBidWR1IHprb3VtYXQsIHpkYSBleGlzdHVqZSB2enRhaCBtZXppIHBvxI10ZW0gb2RlaHJhbsO9Y2ggdXRrw6Fuw60gYSBjZWxrb3bDvW0gcG/EjXRlbSB6w61za2Fuw71jaCBib2TFry4gT8SNZWvDoXbDoW0sIMW+ZSDEjcOtbSB2w61jZSB6w6FwYXPFryBocsOhxI0gb2RlaHLDoWwsIHTDrW0gdsSbdMWhw60gcG/EjWV0IGJvZMWvIHrDrXNrYWwuIFByb3ZlZHUgdGVkeSBsaW5lw6FybsOtIHJlZ3Jlc2kuDQpOdWxvdsOhIGh5cG90w6l6YTogbWV6aSBwb8SNdGVtIG9kZWhyYW7DvWNoIHV0a8OhbsOtIGEgcG/EjXRlbSB6w61za2Fuw71jaCBib2TFryBuZW7DrSBsaW5lw6FybsOtIHZ6dGFoLg0KDQpOZWpwcnZlIHNpIHogZGF0IHZ5YmVydSB2ZWt0b3J5IG9ic2FodWrDrWPDrSBwb8SNdHkgesOtc2thbsO9Y2ggYm9kxa8gYSBwb8SNdHkgb2RlaHJhbsO9Y2ggdXRrw6Fuw60gcHJvIGplZG5vdGxpdsOpIGhyw6HEjWUgbWltbyBicmFua8OhxZnFrw0KYGBge3J9DQpwbGF5ZXJzX25vX2drIDwtIGRhdGEgJT4lDQogIGZpbHRlcihQT1MgIT0gIkdLIikNCnBvaW50cyA8LSBwbGF5ZXJzX25vX2drJFA7IHBvaW50cw0KZ2FtZXMgPC0gcGxheWVyc19ub19nayRHUDsgZ2FtZXMNCmBgYA0KUG9kw612w6FtIHNlLCBqYWsgZGF0YSB2eXBhZGFqw60uDQpgYGB7cn0NCmdncGxvdChwbGF5ZXJzX25vX2drLCBhZXMoeD1HUCwgeT1QKSkgKyANCiAgZ2VvbV9wb2ludChzaXplPTIsIGFscGhhPTAuOCkNCmBgYA0KDQpQb3TDqSBzcG/EjcOtdMOhbSBwcsWvbcSbcm7DvSBwb8SNZXQgesOtc2thbsO9Y2ggYm9kxa8gYSBwcsWvbcSbcm7DvSBwb8SNZXQgb2RlaHJhbsO9Y2ggesOhcGFzxa8uDQpgYGB7cn0NCnBvaW50c19tZWFuID0gbWVhbihwb2ludHMpOyBwb2ludHNfbWVhbg0KZ2FtZXNfbWVhbiA9IG1lYW4oZ2FtZXMpOyBnYW1lc19tZWFuDQpgYGANClNwb8SNw610w6FtIGEgYSBiIHBybyByZWdyZXNpLg0KYGBge3J9DQphID0gc3VtKChnYW1lcy1nYW1lc19tZWFuKSoocG9pbnRzLXBvaW50c19tZWFuKSkvc3VtKChnYW1lcy1nYW1lc19tZWFuKV4yKTsgYQ0KYiA9IHBvaW50c20gLSBhKmdhbWVzbTsgYg0KYGBgDQpWeW5lc3UgcMWZw61ta3UgZG8gZ3JhZnUNCmBgYHtyfQ0KZ2dwbG90KHBsYXllcnNfbm9fZ2ssIGFlcyh4PUdQLHk9UCkpICsgDQogIGdlb21fcG9pbnQoc2l6ZT0yKSArIA0KICBnZW9tX2FibGluZShzbG9wZT1hLCBpbnRlcmNlcHQ9YiwgY29sb3I9InJlZCIpDQpgYGANClDFmcOtbWthIGRvY2VsYSBkb2LFmWUgc2Vkw60gcHJvIGhyw6HEjWUsIGt0ZcWZw60gbmVocsOhbGkgdmUgdsWhZWNoIHrDoXBhc2VjaC4gVSBocsOhxI3Frywga3RlxZnDrSBocsOhbGkgdsWhZWNoIDEwIHrDoXBhc8WvIGEga3RlcsO9Y2ggamUgbmVqdsSbdMWhw60gbW5vxb5zdHbDrSBqc291IHBvbcSbcm7EmyB2ZWxrw6kgcm96ZMOtbHkgLSBuxJtrZG8gbmVza8Ozcm92YWwgdMOpbcSbxZkgxb7DoWRuw6kgYm9keSwgbsSba3RlxZnDrSBocsOhxI1pIHphcyBza8Ozcm92YWxpIG5hZHByxa9txJtybsSbLg0KDQpgYGB7cn0NCnJlbGF0aW9uIDwtIGxtKHBvaW50c35nYW1lcykNCg0Kc3VtbWFyeShyZWxhdGlvbikNCnJlbGF0aW9uJGNvZWZmaWNpZW50cyANCmBgYA0KDQpwLWhvZG5vdGEgdnnFoWxhIDAsMDIzNzEsIGNvxb4gamUgbcOpbsSbIG5lxb4gaGxhZGluYSB2w716bmFtbm9zdGkgMCwwNSwgdGFrxb5lIG51bG92b3UgaHlwb3TDqXp1IG3Fr8W+ZW1lIHphbcOtdG5vdXQuDQoNCiMjIDINClYgdG9tdG8gdGVzdHUgYnVkdSB6a291bWF0LCB6ZGEgamUgdsSbayBocsOhxI3FryBkb2LFmWUgbW9kZWxvdmFuw70gbm9ybcOhbG7DrW0gcm96ZMSbbGVuw61tLg0KDQpCdWR1IGsgdG9tdSBwb3XFvsOtdmF0IGNoaS1rdmFkcsOhdCB0ZXN0LiANCk51bG92w6EgaHlwb3TDqXphOiBEYXRhIGpzb3UgbW9kZWxvdsOhbmEgbm9ybcOhbG7DrW0gcm96ZMSbbGVuw61tLiBIbGFkaW5hIHbDvXpuYW1ub3N0aSBhbGZhIGJ1ZGUgMC4wNQ0KDQojIyMgUG9zdHVwDQoNCk5lanBydmUgc2kgbmHEjXR1IHZla3RvciB2xJtrdSBocsOhxI3FryBhIHBvZMOtdsOhbSBzZSwgamFrIGRhdGEgdnlwYWRhasOtIG5hIGhpc3RvZ3JhbXUuDQoNCmBgYHtyfQ0KYWdlIDwtIGRhdGEkQWdlDQpnZ3Bsb3QoZGF0YS5mcmFtZShhZ2UpLCBhZXMoeCA9IGFnZSkpICsgDQogIGdlb21faGlzdG9ncmFtKGJpbnM9NiwgZmlsbD0iI0ZGNjdBNCIsIGNvbG9yPSIjZTllY2VmIiwgYWxwaGE9MC44KSArDQogIGdndGl0bGUoIkhpc3RvZ3JhbSB2xJtrdSBocsOhxI3FryIpDQoNCmBgYA0KDQpIaXN0b2dyYW0gdnpwYWTDoSBjZWxrZW0gbmFkxJtqbsSbLCDFvmUgYnkgc2Ugc2t1dGXEjW7EmyBtb2hsbyBqZWRuYXQgbyBub3Jtw6FsbsOtIHJvemTEm2xlbsOtLg0KDQpTcG/EjcOtdMOhbSBwcsWvbcSbciwgcm96cHR5bCBhIHNtxJtyb2RhdG5vdSBvZGNoeWxrdS4NCmBgYHtyfQ0KYWdlX21lYW4gPC0gbWVhbihhZ2UpOyBhZ2VfbWVhbg0KYWdlX3ZhciA8LSB2YXIoYWdlKTsgYWdlX3Zhcg0KYWdlX3NkIDwtIHNkKGFnZSk7IGFnZV9zZA0KYGBgDQoNClZ5dHZvxZnDrW0gdsSba292w6kgaW50ZXJ2YWx5OiA8MjAsIDwyMywgPDI2LCA8MjksIDwzMiwgPj0gMzINClNwb8SNw610w6FtIHBvxI1ldCBocsOhxI3FryB6YXN0b3VwZW7DvWNoIHYgamVkbm90bGl2w71jaCB2xJtrb3bDvWNoIGludGVydmFsZWNoIGEgZMOhbGUgcHJvIGthxb5kw70gaW50ZXJ2YWwgc3BvxI3DrXTDoW0gei1za8OzcmUuDQpaIHNrw7NyZSBwb8SNw610w6FtIGpha28gcG9kw61sLCBrZGUgdiDEjWl0YXRlbGkgamUgcm96ZMOtbCBob3Juw60gaHJhbmljZSBpbnRlcnZhbHUgYSBwcsWvbcSbcnUsIHZlIGptZW5vdmF0ZWxpIGplIHNtxJtyb2RhdG7DoSBvZGNoeWxrYQ0KYGBge3J9DQprIDwtIDYNCmJvdW5kcyA8LSBjKDIwLDIzLDI2LDI5LDMyKQ0KDQpvYnNlcnZlZCA8LSByZXAoMCw2KQ0Kb2JzZXJ2ZWRbMV0gPC0gc3VtKGFnZSA8IGJvdW5kc1sxXSkNCm9ic2VydmVkWzZdIDwtIHN1bShhZ2UgPj0gYm91bmRzWzVdKQ0KZm9yIChpIGluIDI6NSkgew0KICBvYnNlcnZlZFtpXSA8LSBzdW0oYWdlIDwgYm91bmRzW2ldKSAtIHN1bShhZ2UgPCBib3VuZHNbaS0xXSkNCn0NCg0Kel9zY29yZXMgPC0gcmVwKDAsNSkNCmZvciAoaSBpbiAxOjUpew0KICB6X3Njb3Jlc1tpXSA8LSAgKGJvdW5kc1tpXSAtIGFnZV9tZWFuKSAvIGFnZV9zZA0KfQ0KYGBgDQoNClplIHogc2vDs3JlIHNwb8SNw610w6FtIHBsb2NodSBwb2Qga8WZaXZrb3Ugbm9ybcOhbG7DrSBkaXN0cmlidWNlIE4oMCwxKQ0KYGBge3J9DQphcmVhX3VuZGVyIDwtIHJlcCgwLDYpDQpmb3IgKGkgaW4gMTo1KSB7DQogIGFyZWFfdW5kZXJbaV0gPSBwbm9ybSh6X3Njb3Jlc1tpXSkNCn0NCmFyZWFfdW5kZXJbNl0gPSAxDQpgYGANCkTDoWxlIHNwb8SNw610w6FtIHBsb2NodSB2IHLDoW1jaSBpbnRlcnZhbMWvDQpgYGB7cn0NCmFyZWFfaW5zaWRlIDwtIHJlcCgwLDYpDQphcmVhX2luc2lkZVsxXSA9IGFyZWFfdW5kZXJbMV0NCmZvciAoaSBpbiAyOjYpew0KICBhcmVhX2luc2lkZVtpXSA9IGFyZWFfdW5kZXJbaV0gLSBhcmVhX3VuZGVyW2ktMV0NCn0NCmBgYA0KWiB0b2hvIHNwb8SNw610w6FtIG/EjWVrw6F2YW7DqSBwb8SNdHkgaHLDocSNxa8gdiBqZWRub3RsaXbDvWNoIHbEm2tvdsO9Y2ggaW50ZXJ2YWxlY2gNCmBgYHtyfQ0KZXhwZWN0ZWQgPC0gcmVwKDAsNikNCmZvciAoaSBpbiAxOjYpIHsNCiAgZXhwZWN0ZWRbaV0gPC0gYXJlYV9pbnNpZGVbaV0gKiAyNQ0KfQ0KYGBgDQpLZHnFviBtw6FtIHNwb8SNw610YW7DqSBwb3pvcm92YW7DqSBhIG/EjWVrw6F2YW7DqSBob2Rub3R5IHBybyBqZWRub3RsaXbDqSBpbnRlcnZhbHksIG1vaHUgcHJvdsOpc3QgY2hpLXNxdWFyZWQgdGVzdC4NClBvxI1ldCBzdHVwxYjFryB2b2xub3N0aSBqZSA1ICg2IGludGVydmFsxa8gLSAxKQ0KYGBge3J9DQpjaGkgPC0gMA0KZm9yIChpIGluIDE6Nikgew0KICBjaGkgPC0gY2hpICsgKChvYnNlcnZlZFtpXSAtIGV4cGVjdGVkW2ldKV4yKS9leHBlY3RlZFtpXQ0KfQ0KYGBgDQojIyMgWsOhdsSbcg0KUHJvIGhsYWRpbnUgdsO9em5hbW5vc3RpIGEgNSBzdHVwxYjFryB2b2xub3N0aSBqZSBrcml0aWNrw6EgaG9kbm90YSAxMS4wNzAuIFByb3Rvxb5lIGhvZG5vdGEgdnnFoWxhIG1lbsWhw60gbmVtxa/FvmVtZSBoeXBvdMOpenUgemFtw610bm91dC4NCg0KIyMjIERhbMWhw60gbW/Fvm5vc3RpDQpKZcWhdMSbIGplIG1vxb5uw6kgcG9kw612YXQgc2UgbmEgUS1RIHBsb3QgKHF1YW50aWxlIC0gcXVhbnRpbGUgcGxvdCkNCmBgYHtyfQ0KZ2dxcXBsb3QoYWdlKQ0KYGBgDQpaIGdyYWZ1IGplIHZpZMSbdCwgxb5lIGJvZHkganNvdSBwb23Em3JuxJsgYmzDrXprbyBwxZnDrW1jZSwgY2/FviBuYXpuYcSNdWplLCDFvmUgYnkgc2UgbW9obG8gamVkbmF0IG8gbm9ybcOhbG7DrSByb3pkxJtsZW7DrS4NCg0KRMOhbGUgamUgbW/Fvm7DqSBwb3XFvsOtdCBTaGFwaXJvLVdpbGvFr3YgdGVzdCBub3JtYWxpdHksIHBybyBrdGVyw70gdiBSIGV4aXN0dWplIGZ1bmtjZS4NCmBgYHtyfQ0Kc2hhcGlyby50ZXN0KGFnZSkNCmBgYA0KUHJvdG/FvmUgdnnFoWxhIHAtaG9kbm90YSB2ecWhxaHDrSBuZcW+IDAsMDUsIG5lbHplIGh5cG90w6l6dSB6YW3DrXRub3V0Lg0K