1 Read

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Read and Merge
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wd <- "C:/Users/Mihai/Desktop/O.4 prealabil pt Frontiers/O.4 Scale Scoring/scorate 21.08.2019"
setwd(wd)
## Read
Data_arsq <- readRDS("Data_arsq.RDS")
Data_nycq <- readRDS("Data_nycq.RDS")
Data_vas <- xlsx::read.xlsx2("VAS, IOS.xlsx", sheetName = "Toti")
## Transform
Data_arsq <-
  Data_arsq %>%
  select(-"Data.x", -"Data.y") %>%
  na_if("NA") %>%                           # make NA chars NA so to not get warning message of NAs introduced by coercion
  mutate_at(vars(- c(1:5)), funs(as.numeric(as.character(.))))
Data_nycq <-
  Data_nycq %>%
  select(-"Data.x", -"Data.y") %>%
  na_if("NA") %>%                           # make NA chars NA so to not get warning message of NAs introduced by coercion
  mutate_at(vars(- c(1:5)), funs(as.numeric(as.character(.))))
## To numeric
Data_vas <-
  Data_vas %>%
  mutate_at(vars(6:11), function(x) as.numeric(as.character(x))) %>%
  filter(ID %in% c(2:8, 10:14, 16:33))
## Calc Diff Scores
Data_vas$VaS_Diff <- Data_vas$VaS_post - Data_vas$VaS_pre 
Data_vas$VaB_Diff <- Data_vas$VaB_post - Data_vas$VaB_pre
Data_vas$IOS_Diff <- Data_vas$IOS_post - Data_vas$IOS_pre
# Fix a typo
Data_arsq[(Data_arsq$ID == 32 & Data_arsq$Order == 2) ,]$Conditie <- "ECRAN"
Data_nycq[(Data_nycq$ID == 32 & Data_nycq$Order == 2) ,]$Conditie <- "ECRAN"
Data_vas[(Data_vas$ID == 32 & Data_vas$Data == "18.07.2019") ,]$Conditie <- "ECRAN"

2 Define Functions

## Func t test si boxplot simplu
func_t_box <- function(df, ind, cond, pre_var, post_var){
  df_modif <-
    df %>%
    filter(Conditie == cond) %>%
    select(ind, pre_var, post_var) %>% 
    tidyr::drop_na() %>%
    gather(pre_var, post_var, key = "PrePost", value = "value") %>% 
    mutate_at(vars(c(1, 2)), funs(as.factor)) %>% 
    mutate(PrePost = factor(PrePost, levels = c(pre_var, post_var))) 
  
  stat_comp <- ggpubr::compare_means(value ~ PrePost, data = df_modif, method = "t.test", paired = TRUE)
  
  #sample_size <- sum(duplicated(df_modif[, ind]))        # get nr of duplicates = sample size for paired test
  sample_size <-
    df_modif %>%
    filter(duplicated(.[["ID"]])) %>%      # something is fishy: OGL 31, ECRAN 29 observations
    dplyr::summarize(n = n())
  
  stat_comp2 <-
    df_modif %>% 
    do(tidy(t.test(.$value ~ .$PrePost,
                   paired = TRUE,
                   data=.)))
  
  plot <- 
    ggpubr::ggpaired(df_modif, x = "PrePost", y = "value", id = ind, title = cond, 
                     color = "PrePost", line.color = "gray", line.size = 0.4,
                     palette = c("#00AFBB", "#FC4E07"), legend = "none") +
    stat_summary(fun.data = mean_se,  colour = "darkred") +
    ggpubr::stat_compare_means(method = "t.test", paired = TRUE, label.x = as.numeric(df_modif$PrePost)-0.4, label.y = max(df_modif$value)+1) + 
    ggpubr::stat_compare_means(method = "t.test", paired = TRUE, label = "p.signif", comparisons = list(c(pre_var, post_var)))
  
  cat(paste0("#### ", cond, " - ", pre_var, " ", post_var, " (N = ", sample_size$n, ")", "\n", "\n"))
  print(stat_comp)
  print(stat_comp2)
  cat("\n")                      
  print(plot)
  cat("\n")
  plot.new()                     # Need this workaround for interleaving tables and plots in R Markdown, within loop
  dev.off()
}

3 Analyses

3.1 Simple before-after analyses with t test

## Simple before-after analyses with t test
# func_t_box(Data_arsq, "ID", "OGL", "discont_pre", "discont_post")  # sig  
# func_t_box(Data_arsq, "ID", "ECRAN", "discont_pre", "discont_post")  # nonsig
cat("#### VAS Stress")

3.1.0.1 VAS Stress

func_t_box(Data_vas, "ID", "OGL", "VaS_pre", "VaS_post")

3.1.0.2 OGL - VaS_pre VaS_post (N = 30)

NANA

null device 1

func_t_box(Data_vas, "ID", "ECRAN", "VaS_pre", "VaS_post")

3.1.0.3 ECRAN - VaS_pre VaS_post (N = 29)

NANA

null device 1

cat("#### VAS Well-being")

3.1.0.4 VAS Well-being

func_t_box(Data_vas, "ID", "OGL", "VaB_pre", "VaB_post")

3.1.0.5 OGL - VaB_pre VaB_post (N = 30)

NANA

null device 1

func_t_box(Data_vas, "ID", "ECRAN", "VaB_pre", "VaB_post")

3.1.0.6 ECRAN - VaB_pre VaB_post (N = 29)

NANA

null device 1

cat("#### IOS")

3.1.0.7 IOS

func_t_box(Data_vas, "ID", "OGL", "IOS_pre", "IOS_post")

3.1.0.8 OGL - IOS_pre IOS_post (N = 30)

NANA

null device 1

func_t_box(Data_vas, "ID", "ECRAN", "IOS_pre", "IOS_post")

3.1.0.9 ECRAN - IOS_pre IOS_post (N = 14)

NANA

null device 1

cat("#### ARSQ")

3.1.0.10 ARSQ

var_names <- colnames(Data_arsq)[c(6:15, 41:50)]                     # dont add individual items 
var_names_pre <- grep("_pre", var_names, value = TRUE)
var_names_post <- grep("_post", var_names, value = TRUE) 
var_names_length <- length(var_names_pre)
var_cond <- cbind(rep("OGL", var_names_length), rep("ECRAN", var_names_length))
for (i in seq_along(1:var_names_length)){ 
  func_t_box(Data_arsq, "ID", var_cond[i,1], var_names_pre[i], var_names_post[i])      # "OGL"  
  func_t_box(Data_arsq, "ID", var_cond[i,2] , var_names_pre[i], var_names_post[i])     # "ECRAN"
}

3.1.0.11 OGL - discont_pre discont_post (N = 30)

NANA

3.1.0.12 ECRAN - discont_pre discont_post (N = 29)

NANA

3.1.0.13 OGL - tom_pre tom_post (N = 29)

NANA

3.1.0.14 ECRAN - tom_pre tom_post (N = 27)

NANA

3.1.0.15 OGL - self_pre self_post (N = 30)

NANA

3.1.0.16 ECRAN - self_pre self_post (N = 30)

NANA

3.1.0.17 OGL - planning_pre planning_post (N = 30)

NANA

3.1.0.18 ECRAN - planning_pre planning_post (N = 29)

NANA

3.1.0.19 OGL - sleep_pre sleep_post (N = 30)

NANA

3.1.0.20 ECRAN - sleep_pre sleep_post (N = 29)

NANA

3.1.0.21 OGL - comfort_pre comfort_post (N = 30)

NANA

3.1.0.22 ECRAN - comfort_pre comfort_post (N = 30)

NANA

3.1.0.23 OGL - somatic_pre somatic_post (N = 30)

NANA

3.1.0.24 ECRAN - somatic_pre somatic_post (N = 30)

NANA

3.1.0.25 OGL - health_pre health_post (N = 30)

NANA

3.1.0.26 ECRAN - health_pre health_post (N = 30)

NANA

3.1.0.27 OGL - visual_pre visual_post (N = 27)

NANA

3.1.0.28 ECRAN - visual_pre visual_post (N = 30)

NANA

3.1.0.29 OGL - verbal_pre verbal_post (N = 27)

NANA

3.1.0.30 ECRAN - verbal_pre verbal_post (N = 30)

NANA

cat("#### NYCQ")

3.1.0.31 NYCQ

var_names <- colnames(Data_nycq)[-c(1:5)]                    
var_names_pre <- grep("_pre", var_names, value = TRUE)
var_names_post <- grep("_post", var_names, value = TRUE) 
var_names_length <- length(var_names_pre)
var_cond <- cbind(rep("OGL", var_names_length), rep("ECRAN", var_names_length))
for (i in seq_along(1:var_names_length)){ 
  func_t_box(Data_nycq, "ID", var_cond[i,1], var_names_pre[i], var_names_post[i])      # "OGL" 
  func_t_box(Data_nycq, "ID", var_cond[i,2] , var_names_pre[i], var_names_post[i])     # "ECRAN"
}

3.1.0.32 OGL - Past_pre Past_post (N = 30)

NANA

3.1.0.33 ECRAN - Past_pre Past_post (N = 29)

NANA

3.1.0.34 OGL - Positive_pre Positive_post (N = 30)

NANA

3.1.0.35 ECRAN - Positive_pre Positive_post (N = 29)

NANA

3.1.0.36 OGL - Future_pre Future_post (N = 30)

NANA

3.1.0.37 ECRAN - Future_pre Future_post (N = 29)

NANA

3.1.0.38 OGL - Negative_pre Negative_post (N = 30)

NANA

3.1.0.39 ECRAN - Negative_pre Negative_post (N = 29)

NANA

3.1.0.40 OGL - Friends_pre Friends_post (N = 30)

NANA

3.1.0.41 ECRAN - Friends_pre Friends_post (N = 29)

NANA

3.1.0.42 OGL - Vague_pre Vague_post (N = 29)

NANA

3.1.0.43 ECRAN - Vague_pre Vague_post (N = 29)

NANA

3.1.0.44 OGL - Words_pre Words_post (N = 29)

NANA

3.1.0.45 ECRAN - Words_pre Words_post (N = 29)

NANA

3.1.0.46 OGL - Images_pre Images_post (N = 29)

NANA

3.1.0.47 ECRAN - Images_pre Images_post (N = 29)

NANA

NA



4 Session Info

R version 3.5.2 (2018-12-20)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=Romanian_Romania.1250  LC_CTYPE=Romanian_Romania.1250    LC_MONETARY=Romanian_Romania.1250 LC_NUMERIC=C                     
[5] LC_TIME=Romanian_Romania.1250    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] bindrcpp_0.2.2     rio_0.5.16         plyr_1.8.4         summarytools_0.9.3 DT_0.5             ggpubr_0.2         magrittr_1.5      
 [8] broom_0.5.1        papaja_0.1.0.9842  psych_1.8.10       forcats_0.3.0      stringr_1.3.1      dplyr_0.7.8        purrr_0.2.5       
[15] readr_1.3.0        tidyr_0.8.2        tibble_1.4.2       ggplot2_3.2.0      tidyverse_1.2.1    pacman_0.5.1      

loaded via a namespace (and not attached):
 [1] httr_1.4.0         jsonlite_1.6       modelr_0.1.2       assertthat_0.2.1   pander_0.6.3       xlsxjars_0.6.1     cellranger_1.1.0  
 [8] yaml_2.2.0         pillar_1.3.1       backports_1.1.3    lattice_0.20-38    glue_1.3.1         digest_0.6.18      pryr_0.1.4        
[15] ggsignif_0.4.0     checkmate_1.8.5    rvest_0.3.2        colorspace_1.3-2   htmltools_0.3.6    pkgconfig_2.0.2    haven_2.1.1       
[22] magick_2.0         scales_1.0.0       openxlsx_4.1.0     generics_0.0.2     withr_2.1.2        lazyeval_0.2.1     cli_1.0.1         
[29] mnormt_1.5-5       crayon_1.3.4       readxl_1.1.0       nlme_3.1-137       xml2_1.2.0         foreign_0.8-71     rapportools_1.0   
[36] tools_3.5.2        data.table_1.12.2  hms_0.4.2          matrixStats_0.54.0 xlsx_0.6.1         munsell_0.5.0      zip_1.0.0         
[43] compiler_3.5.2     rlang_0.4.0        grid_3.5.2         RCurl_1.95-4.11    rstudioapi_0.8     htmlwidgets_1.3    labeling_0.3      
[50] bitops_1.0-6       tcltk_3.5.2        gtable_0.2.0       codetools_0.2-15   curl_4.0           R6_2.4.0           lubridate_1.7.4   
[57] knitr_1.24         bindr_0.1.1        rJava_0.9-10       stringi_1.2.4      parallel_3.5.2     Rcpp_1.0.2         tidyselect_0.2.5  
[64] xfun_0.8          
 

A work by Claudiu Papasteri

claudiu.papasteri@gmail.com

 

LS0tDQp0aXRsZTogIjxicj4gTy40IFJlc3RpbmcgU3RhdGUgLSBiZWhhdmlvcmFsIiANCnN1YnRpdGxlOiAiMzAgc3ViamVjdHMgLSBBUlNRICYgTllDUSINCmF1dGhvcjogIjxicj4gQ2xhdWRpdSBQYXBhc3RlcmkiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlbSAlWScpYCINCm91dHB1dDogDQogICAgaHRtbF9ub3RlYm9vazoNCiAgICAgICAgICAjIHNlbGZfY29udGFpbmVkOiBubw0KICAgICAgICAgICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgICAgICAgICB0b2M6IHRydWUNCiAgICAgICAgICAgIHRvY19kZXB0aDogMg0KICAgICAgICAgICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgICAgICAgICB0aGVtZTogc3BhY2VsYWINCiAgICAgICAgICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgICAgICAgICAgIGZvbnQtZmFtaWx5OiBBcmlhbA0KICAgICAgICAgICAgZmlnX3dpZHRoOiAxMA0KICAgICAgICAgICAgZmlnX2hlaWdodDogOQ0KICAgICAjIHBkZl9kb2N1bWVudDogDQogICAgICAgICAgICAjIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgIyB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgICMgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgICAgICAgICAjIGZvbnRzaXplOiAxMXB0DQogICAgICAgICAgICAjIGdlb21ldHJ5OiBtYXJnaW49MWluDQogICAgICAgICAgICAjIGZpZ193aWR0aDogNw0KICAgICAgICAgICAgIyBmaWdfaGVpZ2h0OiA2DQogICAgICAgICAgICAjIGZpZ19jYXB0aW9uOiB0cnVlDQogICAgIyBnaXRodWJfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgIyB0b2M6IHRydWUNCiAgICAgICAgICAgICMgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICAjIGh0bWxfcHJldmlldzogZmFsc2UNCiAgICAgICAgICAgICMgZmlnX3dpZHRoOiA1DQogICAgICAgICAgICAjIGZpZ19oZWlnaHQ6IDUNCiAgICAgICAgICAgICMgZGV2OiBqcGVnDQotLS0NCg0KDQo8IS0tIFNldHVwIC0tPg0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBraW50ciBvcHRpb25zDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIGNvbW1lbnQgPSAiIyIsDQogIGNvbGxhcHNlID0gVFJVRSwNCiAgZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBUUlVFLCBtZXNzYWdlID0gVFJVRSwgY2FjaGUgPSBUUlVFICAgICAgICMgZWNobyA9IEZhbHNlIGZvciBnaXRodWJfZG9jdW1lbnQsIGJ1dCB3aWxsIGJlIGZvbGRlZCBpbiBodG1sX25vdGVib29rDQopDQoNCiMgR2VuZXJhbCBSIG9wdGlvbnMgYW5kIGluZm8NCnNldC5zZWVkKDExMSkgICAgICAgICAgICAgICAjIGluIGNhc2Ugd2UgdXNlIHJhbmRvbWl6ZWQgcHJvY2VkdXJlcyAgICAgICANCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAgICAgICAjIHBvc2l0aXZlIHZhbHVlcyBiaWFzIHRvd2FyZHMgZml4ZWQgYW5kIG5lZ2F0aXZlIHRvd2FyZHMgc2NpZW50aWZpYyBub3RhdGlvbg0KDQojIExvYWQgcGFja2FnZXMNCmlmICghcmVxdWlyZSgicGFjbWFuIikpIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQpwYWNrYWdlcyA8LSBjKA0KICAidGlkeXZlcnNlIiwgICAgICAjIGJlc3QgdGhpbmcgdGhhdCBoYXBwZW5kIHRvIG1lDQogICJwc3ljaCIsICAgICAgICAgICMgZ2VuZXJhbCBwdXJwb3NlIHRvb2xib3ggZm9yIHBlcnNvbmFsaXR5LCBwc3ljaG9tZXRyaWMgdGhlb3J5IGFuZCBleHBlcmltZW50YWwgcHN5Y2hvbG9neQ0KICAicGFwYWphIiwgICAgICAgICAjIGZvciBBUEEgc3R5bGUNCiAgImJyb29tIiwgICAgICAgICAgIyBmb3IgdGlkeSBtb2RlbGxpbmcNCiAgImdncGxvdDIiLCAgICAgICAgIyBiZXN0IHBsb3RzDQogICJnZ3B1YnIiLCAgICAgICAgICMgZ2dwbG90MiB0byBwdWJsaWNhdGlvbiBxdWFsaXR5DQogICJEVCIsICAgICAgICAgICAgICMgbmljZSBzZWFyY2hhYmxlIGFuZCBkb3dubG9hZGFibGUgdGFibGVzDQogICJzdW1tYXJ5dG9vbHMiLA0KICAicGx5ciIsIA0KICAicmlvIg0KICAjICwgLi4uDQopDQppZiAoIXJlcXVpcmUoInBhY21hbiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KcGFjbWFuOjpwX2xvYWQoY2hhciA9IHBhY2thZ2VzKQ0KDQojIFRoZW1lcyBmb3IgZ2dwbG90MiBwbG90aW5nIChoZXJlIHVzZWQgQVBBIHN0eWxlKQ0KdGhlbWVfc2V0KHRoZW1lX2FwYSgpKQ0KYGBgDQoNCg0KDQo8IS0tIFJlcG9ydCAtLT4NCg0KDQojIFJlYWQgDQoNCg0KYGBge3IgcmVhZF9tZXJnZSwgcmVzdWx0cz0nYXNpcycsIHdhcm5pbmc9RkFMU0V9DQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQojIFJlYWQgYW5kIE1lcmdlDQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQp3ZCA8LSAiQzovVXNlcnMvTWloYWkvRGVza3RvcC9PLjQgcHJlYWxhYmlsIHB0IEZyb250aWVycy9PLjQgU2NhbGUgU2NvcmluZy9zY29yYXRlIDIxLjA4LjIwMTkiDQpzZXR3ZCh3ZCkNCg0KIyMgUmVhZA0KRGF0YV9hcnNxIDwtIHJlYWRSRFMoIkRhdGFfYXJzcS5SRFMiKQ0KRGF0YV9ueWNxIDwtIHJlYWRSRFMoIkRhdGFfbnljcS5SRFMiKQ0KRGF0YV92YXMgPC0geGxzeDo6cmVhZC54bHN4MigiVkFTLCBJT1MueGxzeCIsIHNoZWV0TmFtZSA9ICJUb3RpIikNCg0KIyMgVHJhbnNmb3JtDQpEYXRhX2Fyc3EgPC0NCiAgRGF0YV9hcnNxICU+JQ0KICBzZWxlY3QoLSJEYXRhLngiLCAtIkRhdGEueSIpICU+JQ0KICBuYV9pZigiTkEiKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG1ha2UgTkEgY2hhcnMgTkEgc28gdG8gbm90IGdldCB3YXJuaW5nIG1lc3NhZ2Ugb2YgTkFzIGludHJvZHVjZWQgYnkgY29lcmNpb24NCiAgbXV0YXRlX2F0KHZhcnMoLSBjKDE6NSkpLCBmdW5zKGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKC4pKSkpDQoNCkRhdGFfbnljcSA8LQ0KICBEYXRhX255Y3EgJT4lDQogIHNlbGVjdCgtIkRhdGEueCIsIC0iRGF0YS55IikgJT4lDQogIG5hX2lmKCJOQSIpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbWFrZSBOQSBjaGFycyBOQSBzbyB0byBub3QgZ2V0IHdhcm5pbmcgbWVzc2FnZSBvZiBOQXMgaW50cm9kdWNlZCBieSBjb2VyY2lvbg0KICBtdXRhdGVfYXQodmFycygtIGMoMTo1KSksIGZ1bnMoYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoLikpKSkNCg0KIyMgVG8gbnVtZXJpYw0KRGF0YV92YXMgPC0NCiAgRGF0YV92YXMgJT4lDQogIG11dGF0ZV9hdCh2YXJzKDY6MTEpLCBmdW5jdGlvbih4KSBhcy5udW1lcmljKGFzLmNoYXJhY3Rlcih4KSkpICU+JQ0KICBmaWx0ZXIoSUQgJWluJSBjKDI6OCwgMTA6MTQsIDE2OjMzKSkNCg0KIyMgQ2FsYyBEaWZmIFNjb3Jlcw0KRGF0YV92YXMkVmFTX0RpZmYgPC0gRGF0YV92YXMkVmFTX3Bvc3QgLSBEYXRhX3ZhcyRWYVNfcHJlIA0KRGF0YV92YXMkVmFCX0RpZmYgPC0gRGF0YV92YXMkVmFCX3Bvc3QgLSBEYXRhX3ZhcyRWYUJfcHJlDQpEYXRhX3ZhcyRJT1NfRGlmZiA8LSBEYXRhX3ZhcyRJT1NfcG9zdCAtIERhdGFfdmFzJElPU19wcmUNCg0KIyBGaXggYSB0eXBvDQpEYXRhX2Fyc3FbKERhdGFfYXJzcSRJRCA9PSAzMiAmIERhdGFfYXJzcSRPcmRlciA9PSAyKSAsXSRDb25kaXRpZSA8LSAiRUNSQU4iDQpEYXRhX255Y3FbKERhdGFfbnljcSRJRCA9PSAzMiAmIERhdGFfbnljcSRPcmRlciA9PSAyKSAsXSRDb25kaXRpZSA8LSAiRUNSQU4iDQpEYXRhX3Zhc1soRGF0YV92YXMkSUQgPT0gMzIgJiBEYXRhX3ZhcyREYXRhID09ICIxOC4wNy4yMDE5IikgLF0kQ29uZGl0aWUgPC0gIkVDUkFOIg0KYGBgDQoNCg0KIyBEZWZpbmUgRnVuY3Rpb25zIA0KDQpgYGB7ciBkZWZfZnVuYywgaGlkZT1UUlVFLCByZXN1bHRzPSdhc2lzJ30NCiMjIEZ1bmMgdCB0ZXN0IHNpIGJveHBsb3Qgc2ltcGx1DQpmdW5jX3RfYm94IDwtIGZ1bmN0aW9uKGRmLCBpbmQsIGNvbmQsIHByZV92YXIsIHBvc3RfdmFyKXsNCiAgZGZfbW9kaWYgPC0NCiAgICBkZiAlPiUNCiAgICBmaWx0ZXIoQ29uZGl0aWUgPT0gY29uZCkgJT4lDQogICAgc2VsZWN0KGluZCwgcHJlX3ZhciwgcG9zdF92YXIpICU+JSANCiAgICB0aWR5cjo6ZHJvcF9uYSgpICU+JQ0KICAgIGdhdGhlcihwcmVfdmFyLCBwb3N0X3Zhciwga2V5ID0gIlByZVBvc3QiLCB2YWx1ZSA9ICJ2YWx1ZSIpICU+JSANCiAgICBtdXRhdGVfYXQodmFycyhjKDEsIDIpKSwgZnVucyhhcy5mYWN0b3IpKSAlPiUgDQogICAgbXV0YXRlKFByZVBvc3QgPSBmYWN0b3IoUHJlUG9zdCwgbGV2ZWxzID0gYyhwcmVfdmFyLCBwb3N0X3ZhcikpKSANCiAgDQogIHN0YXRfY29tcCA8LSBnZ3B1YnI6OmNvbXBhcmVfbWVhbnModmFsdWUgfiBQcmVQb3N0LCBkYXRhID0gZGZfbW9kaWYsIG1ldGhvZCA9ICJ0LnRlc3QiLCBwYWlyZWQgPSBUUlVFKQ0KICANCiAgI3NhbXBsZV9zaXplIDwtIHN1bShkdXBsaWNhdGVkKGRmX21vZGlmWywgaW5kXSkpICAgICAgICAjIGdldCBuciBvZiBkdXBsaWNhdGVzID0gc2FtcGxlIHNpemUgZm9yIHBhaXJlZCB0ZXN0DQogIHNhbXBsZV9zaXplIDwtDQogICAgZGZfbW9kaWYgJT4lDQogICAgZmlsdGVyKGR1cGxpY2F0ZWQoLltbIklEIl1dKSkgJT4lICAgICAgIyBzb21ldGhpbmcgaXMgZmlzaHk6IE9HTCAzMSwgRUNSQU4gMjkgb2JzZXJ2YXRpb25zDQogICAgZHBseXI6OnN1bW1hcml6ZShuID0gbigpKQ0KICANCiAgc3RhdF9jb21wMiA8LQ0KICAgIGRmX21vZGlmICU+JSANCiAgICBkbyh0aWR5KHQudGVzdCguJHZhbHVlIH4gLiRQcmVQb3N0LA0KICAgICAgICAgICAgICAgICAgIHBhaXJlZCA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgZGF0YT0uKSkpDQogIA0KICBwbG90IDwtIA0KICAgIGdncHVicjo6Z2dwYWlyZWQoZGZfbW9kaWYsIHggPSAiUHJlUG9zdCIsIHkgPSAidmFsdWUiLCBpZCA9IGluZCwgdGl0bGUgPSBjb25kLCANCiAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIlByZVBvc3QiLCBsaW5lLmNvbG9yID0gImdyYXkiLCBsaW5lLnNpemUgPSAwLjQsDQogICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiIzAwQUZCQiIsICIjRkM0RTA3IiksIGxlZ2VuZCA9ICJub25lIikgKw0KICAgIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IG1lYW5fc2UsICBjb2xvdXIgPSAiZGFya3JlZCIpICsNCiAgICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAidC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgbGFiZWwueCA9IGFzLm51bWVyaWMoZGZfbW9kaWYkUHJlUG9zdCktMC40LCBsYWJlbC55ID0gbWF4KGRmX21vZGlmJHZhbHVlKSsxKSArIA0KICAgIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ0LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBsYWJlbCA9ICJwLnNpZ25pZiIsIGNvbXBhcmlzb25zID0gbGlzdChjKHByZV92YXIsIHBvc3RfdmFyKSkpDQogIA0KICBjYXQocGFzdGUwKCIjIyMjICIsIGNvbmQsICIgLSAiLCBwcmVfdmFyLCAiICIsIHBvc3RfdmFyLCAiIChOID0gIiwgc2FtcGxlX3NpemUkbiwgIikiLCAiXG4iLCAiXG4iKSkNCiAgcHJpbnQoc3RhdF9jb21wKQ0KICBwcmludChzdGF0X2NvbXAyKQ0KICBjYXQoIlxuIikgICAgICAgICAgICAgICAgICAgICAgDQogIHByaW50KHBsb3QpDQogIGNhdCgiXG4iKQ0KICBwbG90Lm5ldygpICAgICAgICAgICAgICAgICAgICAgIyBOZWVkIHRoaXMgd29ya2Fyb3VuZCBmb3IgaW50ZXJsZWF2aW5nIHRhYmxlcyBhbmQgcGxvdHMgaW4gUiBNYXJrZG93biwgd2l0aGluIGxvb3ANCiAgZGV2Lm9mZigpDQp9DQpgYGANCg0KDQojIEFuYWx5c2VzDQoNCiMjIFNpbXBsZSBiZWZvcmUtYWZ0ZXIgYW5hbHlzZXMgd2l0aCB0IHRlc3QNCg0KYGBge3IgdF90ZXN0LCBmaWcud2lkdGg9NSwgZmlnLmhlaWdodD02LCByZXN1bHRzPSdhc2lzJ30NCiMjIFNpbXBsZSBiZWZvcmUtYWZ0ZXIgYW5hbHlzZXMgd2l0aCB0IHRlc3QNCiMgZnVuY190X2JveChEYXRhX2Fyc3EsICJJRCIsICJPR0wiLCAiZGlzY29udF9wcmUiLCAiZGlzY29udF9wb3N0IikgICMgc2lnICANCiMgZnVuY190X2JveChEYXRhX2Fyc3EsICJJRCIsICJFQ1JBTiIsICJkaXNjb250X3ByZSIsICJkaXNjb250X3Bvc3QiKSAgIyBub25zaWcNCg0KY2F0KCIjIyMjIFZBUyBTdHJlc3MiKQ0KZnVuY190X2JveChEYXRhX3ZhcywgIklEIiwgIk9HTCIsICJWYVNfcHJlIiwgIlZhU19wb3N0IikNCmZ1bmNfdF9ib3goRGF0YV92YXMsICJJRCIsICJFQ1JBTiIsICJWYVNfcHJlIiwgIlZhU19wb3N0IikNCg0KY2F0KCIjIyMjIFZBUyBXZWxsLWJlaW5nIikNCmZ1bmNfdF9ib3goRGF0YV92YXMsICJJRCIsICJPR0wiLCAiVmFCX3ByZSIsICJWYUJfcG9zdCIpDQpmdW5jX3RfYm94KERhdGFfdmFzLCAiSUQiLCAiRUNSQU4iLCAiVmFCX3ByZSIsICJWYUJfcG9zdCIpDQoNCmNhdCgiIyMjIyBJT1MiKQ0KZnVuY190X2JveChEYXRhX3ZhcywgIklEIiwgIk9HTCIsICJJT1NfcHJlIiwgIklPU19wb3N0IikNCmZ1bmNfdF9ib3goRGF0YV92YXMsICJJRCIsICJFQ1JBTiIsICJJT1NfcHJlIiwgIklPU19wb3N0IikNCg0KDQoNCmNhdCgiIyMjIyBBUlNRIikNCnZhcl9uYW1lcyA8LSBjb2xuYW1lcyhEYXRhX2Fyc3EpW2MoNjoxNSwgNDE6NTApXSAgICAgICAgICAgICAgICAgICAgICMgZG9udCBhZGQgaW5kaXZpZHVhbCBpdGVtcyANCnZhcl9uYW1lc19wcmUgPC0gZ3JlcCgiX3ByZSIsIHZhcl9uYW1lcywgdmFsdWUgPSBUUlVFKQ0KdmFyX25hbWVzX3Bvc3QgPC0gZ3JlcCgiX3Bvc3QiLCB2YXJfbmFtZXMsIHZhbHVlID0gVFJVRSkgDQp2YXJfbmFtZXNfbGVuZ3RoIDwtIGxlbmd0aCh2YXJfbmFtZXNfcHJlKQ0KdmFyX2NvbmQgPC0gY2JpbmQocmVwKCJPR0wiLCB2YXJfbmFtZXNfbGVuZ3RoKSwgcmVwKCJFQ1JBTiIsIHZhcl9uYW1lc19sZW5ndGgpKQ0KDQpmb3IgKGkgaW4gc2VxX2Fsb25nKDE6dmFyX25hbWVzX2xlbmd0aCkpeyANCiAgZnVuY190X2JveChEYXRhX2Fyc3EsICJJRCIsIHZhcl9jb25kW2ksMV0sIHZhcl9uYW1lc19wcmVbaV0sIHZhcl9uYW1lc19wb3N0W2ldKSAgICAgICMgIk9HTCIgIA0KICBmdW5jX3RfYm94KERhdGFfYXJzcSwgIklEIiwgdmFyX2NvbmRbaSwyXSAsIHZhcl9uYW1lc19wcmVbaV0sIHZhcl9uYW1lc19wb3N0W2ldKSAgICAgIyAiRUNSQU4iDQp9DQoNCg0KY2F0KCIjIyMjIE5ZQ1EiKQ0KdmFyX25hbWVzIDwtIGNvbG5hbWVzKERhdGFfbnljcSlbLWMoMTo1KV0gICAgICAgICAgICAgICAgICAgIA0KdmFyX25hbWVzX3ByZSA8LSBncmVwKCJfcHJlIiwgdmFyX25hbWVzLCB2YWx1ZSA9IFRSVUUpDQp2YXJfbmFtZXNfcG9zdCA8LSBncmVwKCJfcG9zdCIsIHZhcl9uYW1lcywgdmFsdWUgPSBUUlVFKSANCnZhcl9uYW1lc19sZW5ndGggPC0gbGVuZ3RoKHZhcl9uYW1lc19wcmUpDQp2YXJfY29uZCA8LSBjYmluZChyZXAoIk9HTCIsIHZhcl9uYW1lc19sZW5ndGgpLCByZXAoIkVDUkFOIiwgdmFyX25hbWVzX2xlbmd0aCkpDQoNCmZvciAoaSBpbiBzZXFfYWxvbmcoMTp2YXJfbmFtZXNfbGVuZ3RoKSl7IA0KICBmdW5jX3RfYm94KERhdGFfbnljcSwgIklEIiwgdmFyX2NvbmRbaSwxXSwgdmFyX25hbWVzX3ByZVtpXSwgdmFyX25hbWVzX3Bvc3RbaV0pICAgICAgIyAiT0dMIiANCiAgZnVuY190X2JveChEYXRhX255Y3EsICJJRCIsIHZhcl9jb25kW2ksMl0gLCB2YXJfbmFtZXNfcHJlW2ldLCB2YXJfbmFtZXNfcG9zdFtpXSkgICAgICMgIkVDUkFOIg0KfQ0KICANCg0KYGBgDQoNCg0KDQoNCg0KDQo8YnI+DQoNCg0KDQo8IS0tIFNlc3Npb24gSW5mbyBhbmQgTGljZW5zZSAtLT4NCg0KPGJyPg0KDQojIFNlc3Npb24gSW5mbw0KYGBge3Igc2Vzc2lvbl9pbmZvLCBlY2hvID0gRkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30NCnNlc3Npb25JbmZvKCkgICAgDQpgYGANCg0KPCEtLSBGb290ZXIgLS0+DQombmJzcDsNCjxociAvPg0KPHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPkEgd29yayBieSA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vQ2xhdWRpdVBhcGFzdGVyaS8iPkNsYXVkaXUgUGFwYXN0ZXJpPC9hPjwvcD4NCjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij48c3BhbiBzdHlsZT0iY29sb3I6ICM4MDgwODA7Ij48ZW0+Y2xhdWRpdS5wYXBhc3RlcmlAZ21haWwuY29tPC9lbT48L3NwYW4+PC9wPg0KJm5ic3A7DQo=