Packages
library(tidyverse)
[30m-- [1mAttaching packages[22m --------------------------------------- tidyverse 1.2.1 --[39m
[30m[32mv[30m [34mggplot2[30m 2.2.1 [32mv[30m [34mpurrr [30m 0.2.4
[32mv[30m [34mtibble [30m 1.4.2 [32mv[30m [34mdplyr [30m 0.7.4
[32mv[30m [34mtidyr [30m 0.8.0 [32mv[30m [34mstringr[30m 1.3.0
[32mv[30m [34mreadr [30m 1.1.1 [32mv[30m [34mforcats[30m 0.3.0[39m
[30m-- [1mConflicts[22m ------------------------------------------ tidyverse_conflicts() --
[31mx[30m [34mdplyr[30m::[32mfilter()[30m masks [34mstats[30m::filter()
[31mx[30m [34mdplyr[30m::[32mlag()[30m masks [34mstats[30m::lag()[39m
Dataset and data cleaning
df <- read_csv("https://docs.google.com/spreadsheets/d/e/2PACX-1vStv7Pr69DtRKv6Nw6gVBep8hbT3pEeO6B1vNwxK_1DUHgpoTgbuRpZ4SvgtHFQnBZJVGeeQVyRuXZl/pub?gid=1261585400&single=true&output=csv")
Missing column names filled in: 'X6' [6], 'X7' [7], 'X9' [9]Parsed with column specification:
cols(
N = col_integer(),
`Merijumu punkts` = col_character(),
Comparison = col_character(),
`difference i/o` = col_integer(),
`difference e/0` = col_integer(),
X6 = col_character(),
X7 = col_character(),
Clave = col_character(),
X9 = col_character()
)
df <- janitor::clean_names(df)
df <- df %>%
select(merijumu_punkts:difference_e_0)
df <- df %>%
rename(intraoral = difference_i_o,
extraoral = difference_e_0)
EDA
Summary
summary(df)
merijumu_punkts comparison intraoral extraoral
Length:540 Length:540 Min. : 0.00 Min. : 0.00
Class :character Class :character 1st Qu.:30.00 1st Qu.: 0.00
Mode :character Mode :character Median :30.00 Median : 0.00
Mean :26.33 Mean :13.06
3rd Qu.:30.00 3rd Qu.:30.00
Max. :90.00 Max. :30.00
Long to wide dataset (for easier calculations)
df <- df %>%
gather(key = "measurement", value = "value", intraoral:extraoral)
N of measurements
df %>%
group_by(comparison, measurement) %>%
summarise(N = n()) %>%
spread(measurement, N)
Mean and sd by type of measurement
df %>%
group_by(comparison, measurement) %>%
summarise(Mean = mean(value)) %>%
spread(measurement, Mean)
df %>%
group_by(comparison, measurement) %>%
summarise(sd = sd(value)) %>%
spread(measurement, sd)
Distributions
df %>%
ggplot(aes(x = value)) +
geom_histogram(bins = 4) +
facet_grid(measurement ~ .) +
theme_minimal() +
labs(
title = "Distribution of measurement",
y = "Count",
x = "Difference"
)

Boxplot
df %>%
ggplot(aes(x = measurement, y = value)) +
geom_boxplot() +
theme_minimal()

df %>%
group_by(comparison, measurement) %>%
summarise(Mean = mean(value)) %>%
ggplot(aes(x = fct_reorder(comparison, Mean), y = Mean)) +
geom_col() +
facet_grid(. ~ measurement) +
theme_minimal()

Se observan diferencias entre las mediciones intraorales y las extraorales. En general, las differencias son menores para las extraorales
Hay diferencias entre grupos?
tres factores - intra vs extraoral: 2 niveles - lugar de la medición: 19 niveles - comparación (1 vs 2, etc)
comparacion <- aov(df$value ~ df$merijumu_punkts + df$comparison + df$measurement)
summary(comparacion)
Df Sum Sq Mean Sq F value Pr(>F)
df$merijumu_punkts 59 53949 914 3.935 <2e-16 ***
df$comparison 8 3297 412 1.773 0.0785 .
df$measurement 1 47601 47601 204.826 <2e-16 ***
Residuals 1011 234952 232
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Interpretación: hay diferencias significativas entre puntos y entre intra/extra
df %>%
group_by(merijumu_punkts, measurement) %>%
summarise(mean = mean(value)) %>%
# spread(measurement, mean) %>%
ggplot(aes(x = fct_reorder(merijumu_punkts, mean), y = mean)) +
geom_boxplot() +
theme_minimal() +
coord_flip()

df %>%
ggplot(aes(x = fct_reorder(merijumu_punkts, value), y = value)) +
geom_col() +
#coord_flip() +
facet_wrap(~measurement)

NA
library(tidyverse)
[30m-- [1mAttaching packages[22m --------------------------------------- tidyverse 1.2.1 --[39m
[30m[32mv[30m [34mggplot2[30m 2.2.1 [32mv[30m [34mpurrr [30m 0.2.4
[32mv[30m [34mtibble [30m 1.4.2 [32mv[30m [34mdplyr [30m 0.7.4
[32mv[30m [34mtidyr [30m 0.8.0 [32mv[30m [34mstringr[30m 1.3.0
[32mv[30m [34mreadr [30m 1.1.1 [32mv[30m [34mforcats[30m 0.3.0[39m
[30m-- [1mConflicts[22m ------------------------------------------ tidyverse_conflicts() --
[31mx[30m [34mdplyr[30m::[32mfilter()[30m masks [34mstats[30m::filter()
[31mx[30m [34mdplyr[30m::[32mlag()[30m masks [34mstats[30m::lag()[39m
Aira 2
df2 <- read_csv("https://docs.google.com/spreadsheets/d/e/2PACX-1vStv7Pr69DtRKv6Nw6gVBep8hbT3pEeO6B1vNwxK_1DUHgpoTgbuRpZ4SvgtHFQnBZJVGeeQVyRuXZl/pub?gid=20675042&single=true&output=csv")
Parsed with column specification:
cols(
`Merijumu punkts` = col_character(),
`1_1` = col_integer(),
`1_2` = col_integer(),
`1_3` = col_integer(),
`1_4` = col_integer(),
`1_5` = col_integer(),
`1_6` = col_integer(),
`1_7` = col_integer(),
`1_8` = col_integer(),
`1_9` = col_integer(),
`1_10` = col_integer(),
Measurement = col_character()
)
df2 <- janitor::clean_names(df2)
head(df2)
df2 <- df2 %>%
gather(key = "comparison", value = "value", x1_1:x1_10)
df2 %>%
arrange(desc(value))
package 㤼㸱bindrcpp㤼㸲 was built under R version 3.4.4
voy a reemplazar el extraoral = 300 por 30
which(df2$value == 300)
[1] 1620
lo cambio
df2$value[1620] = 30
ordeno los factores
df2$measurement <- factor(df2$measurement, levels = c("intraoral", "extraoral", "intra_vs_extra"))
table(df2$measurement)
intraoral extraoral intra_vs_extra
600 600 600
cambio por valores absolutos
df2$value <- abs(df2$value)
Boxplot per group
intra and extraoral

Inferential
table(df2_intra_vs_extra$measurement)
intra_vs_extra
600
summary(model_intra_vs_extra)
Df Sum Sq Mean Sq F value Pr(>F)
merijumu_punkts 59 1474927 24999 55.969 < 2e-16 ***
comparison 9 31107 3456 7.738 9.78e-11 ***
Residuals 531 237173 447
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
mean(df2_intra_vs_extra$value)
[1] 89.43333

Convert the merijumu_punkts column
df2_intra_vs_extra$merijumu_punkts <- str_replace_all(df2_intra_vs_extra$merijumu_punkts, " ", "")
Warning messages:
1: Unknown or uninitialised column: 'str_replace_all'.
2: Unknown or uninitialised column: 'str_replace_all'.
df2_intra_vs_extra <- df2_intra_vs_extra %>%
separate(merijumu_punkts, c("merijumu_punkts", "delete"), sep = "L") %>%
separate(merijumu_punkts, c("merijumu_punkts", "delete"), sep = "V")
Expected 2 pieces. Missing pieces filled with `NA` in 600 rows [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...].Expected 2 pieces. Missing pieces filled with `NA` in 600 rows [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...].

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IA0KICBodG1sX25vdGVib29rOiANCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIGZpZ19jYXB0aW9uOiB0cnVlDQotLS0NCg0KIyBQYWNrYWdlcw0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KDQojIERhdGFzZXQgYW5kIGRhdGEgY2xlYW5pbmcNCmBgYHtyfQ0KZGYgPC0gcmVhZF9jc3YoImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kL2UvMlBBQ1gtMXZTdHY3UHI2OUR0Ukt2Nk53NmdWQmVwOGhiVDNwRWVPNkIxdk53eEtfMURVSGdwb1RnYnVScFo0U3ZndEhGUW5CWkpWR2VlUVZ5UnVYWmwvcHViP2dpZD0xMjYxNTg1NDAwJnNpbmdsZT10cnVlJm91dHB1dD1jc3YiKQ0KYGBgDQpgYGB7cn0NCg0KZGYgPC0gamFuaXRvcjo6Y2xlYW5fbmFtZXMoZGYpDQpkZiAgPC0gZGYgJT4lIA0KICBzZWxlY3QobWVyaWp1bXVfcHVua3RzOmRpZmZlcmVuY2VfZV8wKQ0KDQpkZiA8LSBkZiAlPiUgDQogIHJlbmFtZShpbnRyYW9yYWwgPSBkaWZmZXJlbmNlX2lfbywgDQogICAgICAgICBleHRyYW9yYWwgPSBkaWZmZXJlbmNlX2VfMCkNCmBgYA0KDQojIEVEQQ0KDQojIyBTdW1tYXJ5DQpgYGB7cn0NCnN1bW1hcnkoZGYpDQpgYGANCiMjIExvbmcgdG8gd2lkZSBkYXRhc2V0IChmb3IgZWFzaWVyIGNhbGN1bGF0aW9ucykNCmBgYHtyfQ0KZGYgPC0gZGYgJT4lIA0KICBnYXRoZXIoa2V5ID0gIm1lYXN1cmVtZW50IiwgdmFsdWUgPSAidmFsdWUiLCBpbnRyYW9yYWw6ZXh0cmFvcmFsKQ0KYGBgDQoNCiMjIE4gb2YgbWVhc3VyZW1lbnRzDQoNCmBgYHtyfQ0KZGYgJT4lIA0KICBncm91cF9ieShjb21wYXJpc29uLCBtZWFzdXJlbWVudCkgJT4lIA0KICBzdW1tYXJpc2UoTiA9IG4oKSkgJT4lIA0KICBzcHJlYWQobWVhc3VyZW1lbnQsIE4pDQpgYGANCiMjIE1lYW4gYW5kIHNkIGJ5IHR5cGUgb2YgbWVhc3VyZW1lbnQNCmBgYHtyfQ0KZGYgJT4lIA0KICBncm91cF9ieShjb21wYXJpc29uLCBtZWFzdXJlbWVudCkgJT4lIA0KICBzdW1tYXJpc2UoTWVhbiA9IG1lYW4odmFsdWUpKSAlPiUgDQogIHNwcmVhZChtZWFzdXJlbWVudCwgTWVhbikNCmBgYA0KYGBge3J9DQpkZiAlPiUgDQogIGdyb3VwX2J5KGNvbXBhcmlzb24sIG1lYXN1cmVtZW50KSAlPiUgDQogIHN1bW1hcmlzZShzZCA9IHNkKHZhbHVlKSkgJT4lIA0KICBzcHJlYWQobWVhc3VyZW1lbnQsIHNkKQ0KDQpgYGANCg0KIyMgRGlzdHJpYnV0aW9ucw0KDQpgYGB7cn0NCmRmICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArIA0KICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gNCkgKyANCiAgZmFjZXRfZ3JpZChtZWFzdXJlbWVudCB+IC4pICsNCiAgdGhlbWVfbWluaW1hbCgpICsgDQogIGxhYnMoDQogICAgdGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIG1lYXN1cmVtZW50IiwgDQogICAgeSA9ICJDb3VudCIsIA0KICAgIHggPSAiRGlmZmVyZW5jZSINCiAgKQ0KYGBgDQoNCkJveHBsb3QNCmBgYHtyfQ0KZGYgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtZWFzdXJlbWVudCwgeSA9IHZhbHVlKSkgKyANCiAgZ2VvbV9ib3hwbG90KCkgKyANCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KDQoNCg0KDQpgYGB7cn0NCmRmICU+JSANCiAgZ3JvdXBfYnkoY29tcGFyaXNvbiwgbWVhc3VyZW1lbnQpICU+JSANCiAgc3VtbWFyaXNlKE1lYW4gPSBtZWFuKHZhbHVlKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBmY3RfcmVvcmRlcihjb21wYXJpc29uLCBNZWFuKSwgeSA9IE1lYW4pKSArIA0KICBnZW9tX2NvbCgpICsgDQogIGZhY2V0X2dyaWQoLiB+IG1lYXN1cmVtZW50KSArIA0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KU2Ugb2JzZXJ2YW4gZGlmZXJlbmNpYXMgZW50cmUgbGFzIG1lZGljaW9uZXMgaW50cmFvcmFsZXMgeSBsYXMgZXh0cmFvcmFsZXMuIEVuIGdlbmVyYWwsIGxhcyBkaWZmZXJlbmNpYXMgc29uIG1lbm9yZXMgcGFyYSBsYXMgZXh0cmFvcmFsZXMNCg0KIyBIYXkgZGlmZXJlbmNpYXMgZW50cmUgZ3J1cG9zPw0KdHJlcyBmYWN0b3Jlcw0KIC0gaW50cmEgdnMgZXh0cmFvcmFsOiAyIG5pdmVsZXMNCiAtIGx1Z2FyIGRlIGxhIG1lZGljacOzbjogMTkgbml2ZWxlcw0KIC0gY29tcGFyYWNpw7NuICgxIHZzIDIsIGV0YykNCg0KYGBge3J9DQpjb21wYXJhY2lvbiA8LSAgYW92KGRmJHZhbHVlIH4gZGYkbWVyaWp1bXVfcHVua3RzICsgZGYkY29tcGFyaXNvbiArIGRmJG1lYXN1cmVtZW50KQ0KYGBgDQoNCmBgYHtyfQ0Kc3VtbWFyeShjb21wYXJhY2lvbikNCmBgYA0KDQpJbnRlcnByZXRhY2nDs246IGhheSBkaWZlcmVuY2lhcyBzaWduaWZpY2F0aXZhcyBlbnRyZSBwdW50b3MgeSBlbnRyZSBpbnRyYS9leHRyYQ0KDQpgYGB7cn0NCmRmICU+JSANCiAgZ3JvdXBfYnkobWVyaWp1bXVfcHVua3RzLCBtZWFzdXJlbWVudCkgJT4lIA0KICBzdW1tYXJpc2UobWVhbiA9IG1lYW4odmFsdWUpKSAlPiUgDQogICMgc3ByZWFkKG1lYXN1cmVtZW50LCBtZWFuKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZjdF9yZW9yZGVyKG1lcmlqdW11X3B1bmt0cywgbWVhbiksIHkgPSBtZWFuKSkgKyANCiAgZ2VvbV9ib3hwbG90KCkgKyANCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgY29vcmRfZmxpcCgpDQpgYGANCg0KYGBge3J9DQpkZiAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZjdF9yZW9yZGVyKG1lcmlqdW11X3B1bmt0cywgdmFsdWUpLCB5ID0gdmFsdWUpKSArIA0KICBnZW9tX2NvbCgpICsgDQogICNjb29yZF9mbGlwKCkgKyANCiAgZmFjZXRfd3JhcCh+bWVhc3VyZW1lbnQpDQogIA0KDQoNCmBgYA0KDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpgYGANCg0KIyBBaXJhIDINCmBgYHtyfQ0KZGYyIDwtIHJlYWRfY3N2KCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC9lLzJQQUNYLTF2U3R2N1ByNjlEdFJLdjZOdzZnVkJlcDhoYlQzcEVlTzZCMXZOd3hLXzFEVUhncG9UZ2J1UnBaNFN2Z3RIRlFuQlpKVkdlZVFWeVJ1WFpsL3B1Yj9naWQ9MjA2NzUwNDImc2luZ2xlPXRydWUmb3V0cHV0PWNzdiIpDQpgYGANCg0KYGBge3J9DQpkZjIgPC0gamFuaXRvcjo6Y2xlYW5fbmFtZXMoZGYyKQ0KaGVhZChkZjIpDQpgYGANCg0KDQpgYGB7cn0NCmRmMiA8LSBkZjIgJT4lIA0KICBnYXRoZXIoa2V5ID0gImNvbXBhcmlzb24iLCB2YWx1ZSA9ICJ2YWx1ZSIsIHgxXzE6eDFfMTApDQpgYGANCg0KDQpgYGB7cn0NCmRmMiAlPiUgDQogIGFycmFuZ2UoZGVzYyh2YWx1ZSkpDQpgYGANCnZveSBhIHJlZW1wbGF6YXIgZWwgZXh0cmFvcmFsID0gMzAwIHBvciAzMA0KDQoNCmBgYHtyfQ0Kd2hpY2goZGYyJHZhbHVlID09IDMwMCkNCmBgYA0KbG8gY2FtYmlvDQoNCmBgYHtyfQ0KZGYyJHZhbHVlWzE2MjBdID0gMzANCmBgYA0KDQoNCm9yZGVubyBsb3MgZmFjdG9yZXMNCmBgYHtyfQ0KZGYyJG1lYXN1cmVtZW50IDwtIGZhY3RvcihkZjIkbWVhc3VyZW1lbnQsIGxldmVscyA9IGMoImludHJhb3JhbCIsICJleHRyYW9yYWwiLCAiaW50cmFfdnNfZXh0cmEiKSkNCmBgYA0KDQpgYGB7cn0NCnRhYmxlKGRmMiRtZWFzdXJlbWVudCkNCmBgYA0KDQpjYW1iaW8gcG9yIHZhbG9yZXMgYWJzb2x1dG9zDQpgYGB7cn0NCmRmMiR2YWx1ZSA8LSBhYnMoZGYyJHZhbHVlKQ0KYGBgDQoNCiMjIE1FQU4gcGVyIGdyb3VwDQoNCmBgYHtyfQ0KZGYyICU+JSANCiAgZ3JvdXBfYnkobWVhc3VyZW1lbnQsIGNvbXBhcmlzb24pICU+JSANCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKHZhbHVlKSkgJT4lIA0KICBzcHJlYWQobWVhc3VyZW1lbnQsIG1lYW4pIA0KYGBgDQojIyBTRA0KYGBge3J9DQpkZjIgJT4lIA0KICBncm91cF9ieShtZWFzdXJlbWVudCwgY29tcGFyaXNvbikgJT4lIA0KICBzdW1tYXJpc2Uoc2QgPSBzZCh2YWx1ZSkpICU+JSANCiAgc3ByZWFkKG1lYXN1cmVtZW50LCBzZCkgDQpgYGANCg0KDQoNCiMjIEJveHBsb3QgcGVyIGdyb3VwDQoNCiMjIyBpbnRyYSBhbmQgZXh0cmFvcmFsDQoNCmBgYHtyfQ0KZGYyICU+JSANCiAgZmlsdGVyKG1lYXN1cmVtZW50ICE9ICJpbnRyYV92c19leHRyYSIpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVhc3VyZW1lbnQsIHkgPSB2YWx1ZSkpICsgDQogIGdlb21fYm94cGxvdCgpICsgDQogIGdlb21faml0dGVyKGFscGhhID0gMC4wNSkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQojIyMgaW50cmFfdnNfZXh0cmENCg0KYGBge3J9DQpkZjIgJT4lIA0KICBmaWx0ZXIobWVhc3VyZW1lbnQgPT0gImludHJhX3ZzX2V4dHJhIikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtZWFzdXJlbWVudCwgeSA9IHZhbHVlKSkgKyANCiAgZ2VvbV9ib3hwbG90KCkgKyANCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjA1KSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCmBgYHtyfQ0KZGYyICU+JSANCiAgZmlsdGVyKG1lYXN1cmVtZW50ID09ICJpbnRyYV92c19leHRyYSIpICU+JSANCiAgZ2dwbG90KGFlcyh4ICA9IHZhbHVlKSkgKyANCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDUpICsgDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCmRmMiAlPiUgDQogIGZpbHRlcihtZWFzdXJlbWVudCA9PSAiaW50cmFfdnNfZXh0cmEiKSAlPiUgDQogIGdyb3VwX2J5KG1lcmlqdW11X3B1bmt0cykgJT4lIA0KICBzdW1tYXJpc2UobWVhbiA9IG1lYW4odmFsdWUpLCBzZCA9IHNkKHZhbHVlKSkgJT4lIA0KICBhcnJhbmdlKGRlc2MobWVhbikpDQpgYGANCg0KIyBJbmZlcmVudGlhbA0KDQpgYGB7cn0NCmhlYWQoZGYyKQ0KYGBgDQpgYGB7cn0NCiMgY3JlYXRlIGEgbmV3IGRmIHdpdGggb25seSBtZWFzdXJlbWVudCA9IGludHJhX3ZzX2V4dHJhDQpkZjJfaW50cmFfdnNfZXh0cmEgPC0gZGYyICU+JSANCiAgZmlsdGVyKG1lYXN1cmVtZW50ID09ICJpbnRyYV92c19leHRyYSIpIA0KDQojIGRyb3AgdW51c2VkIGZhY3RvcnMNCmRmMl9pbnRyYV92c19leHRyYSRtZWFzdXJlbWVudCA8LSBmYWN0b3IoZGYyX2ludHJhX3ZzX2V4dHJhJG1lYXN1cmVtZW50KQ0KYGBgDQoNCmBgYHtyfQ0KbW9kZWxfaW50cmFfdnNfZXh0cmEgPC0gYW92KHZhbHVlIH4gbWVyaWp1bXVfcHVua3RzICsgY29tcGFyaXNvbiwgZGF0YSA9IGRmMl9pbnRyYV92c19leHRyYSkNCnN1bW1hcnkobW9kZWxfaW50cmFfdnNfZXh0cmEpDQpgYGANCg0KYGBge3J9DQpkZjJfbWVhbiA8LSBtZWFuKGRmMl9pbnRyYV92c19leHRyYSR2YWx1ZSkNCmRmMl9zZCA8LSBzZChkZjJfaW50cmFfdnNfZXh0cmEkdmFsdWUpDQpgYGANCg0KYGBge3J9DQoNCmRmMl9pbnRyYV92c19leHRyYSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGZjdF9yZW9yZGVyKG1lcmlqdW11X3B1bmt0cywgdmFsdWUpLCB5ID0gdmFsdWUpKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZGYyX21lYW4sIGx0eSA9IDIsIGNvbG9yID0gImRhcmtyZWQiKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGRmMl9tZWFuIC0gZGYyX3NkLCBsdHkgPSAyLCBjb2xvciA9ICJkYXJrZ3JleSIgKSArIA0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBkZjJfbWVhbiArIGRmMl9zZCwgbHR5ID0gMiwgY29sb3IgPSAiZGFya2dyZXkiICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKyANCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJFZGl0IEZvciBUaXRsZSIsIA0KICAgIHkgPSAiRWRpdCBmb3IgeSBheGlzIiwgDQogICAgeCA9ICJFZGl0IGZvciB4IGF4aXMiDQogICkNCmBgYA0KQ29udmVydCB0aGUgbWVyaWp1bXVfcHVua3RzIGNvbHVtbg0KYGBge3J9DQpkZjJfaW50cmFfdnNfZXh0cmEgPC0gDQogIGRmMl9pbnRyYV92c19leHRyYSAlPiUgDQogIG11dGF0ZShtZXJpanVtdV9wdW5rdHMgPSBzdHJfcmVwbGFjZV9hbGwobWVyaWp1bXVfcHVua3RzLCAiICIsICIiKSApDQpgYGANCg0KDQpgYGB7cn0NCmhlYWQoZGYyX2ludHJhX3ZzX2V4dHJhKQ0KYGBgDQpgYGB7cn0NCmRmMl9pbnRyYV92c19leHRyYSA8LSBkZjJfaW50cmFfdnNfZXh0cmEgJT4lIA0KICBzZXBhcmF0ZShtZXJpanVtdV9wdW5rdHMsIGMoIm1lcmlqdW11X3B1bmt0cyIsICJkZWxldGUiKSwgc2VwID0gIkwiKSAlPiUgDQogIHNlcGFyYXRlKG1lcmlqdW11X3B1bmt0cywgYygibWVyaWp1bXVfcHVua3RzIiwgImRlbGV0ZSIpLCBzZXAgPSAiViIpIA0KYGBgDQoNCmBgYHtyfQ0KZGYyX2ludHJhX3ZzX2V4dHJhIDwtIGRmMl9pbnRyYV92c19leHRyYSAlPiUgDQogIHNlbGVjdCgtZGVsZXRlKQ0KYGBgDQoNCmBgYHtyfQ0KZGYyX2ludHJhX3ZzX2V4dHJhICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZmN0X3Jlb3JkZXIobWVyaWp1bXVfcHVua3RzLCB2YWx1ZSksIHkgPSB2YWx1ZSkpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBkZjJfbWVhbiwgbHR5ID0gMiwgY29sb3IgPSAiZGFya3JlZCIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZGYyX21lYW4gLSBkZjJfc2QsIGx0eSA9IDIsIGNvbG9yID0gImRhcmtncmV5IiApICsgDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGRmMl9tZWFuICsgZGYyX3NkLCBsdHkgPSAyLCBjb2xvciA9ICJkYXJrZ3JleSIgKSArDQogIHRoZW1lX21pbmltYWwoKSArIA0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkRpZmZlcmVuY2UgQmV0d2VlbiBUZWV0aCIsDQogICAgc3VidGl0bGUgPSAiUmVkIGxpbmUgPSBtZWFuLCBncmV5IGxpbmVzID0gc3RhbmRhcmQgZGV2aWF0aW9uIiwgDQogICAgeSA9ICJEaWZmZXJlbmNlIiwgDQogICAgeCA9ICJUZWV0aCINCiAgKQ0KYGBgDQoNCg0K