1 Define functions

## Define function that recodes to numeric, but watches out to coercion to not introduce NAs
colstonumeric <- function(df){
  tryCatch({
    df_num <- as.data.frame(
      lapply(df,
             function(x) { as.numeric(as.character(x))})) 
  },warning = function(stop_on_warning) {
    message("Stoped the execution of numeric conversion: ", conditionMessage(stop_on_warning))
  }) 
}
##
## Define function that reverse codes items
ReverseCode <- function(df, tonumeric = FALSE, min = NULL, max = NULL) {
  if(tonumeric) df <- colstonumeric(df)
  df <- (max + min) - df
}
##
## Define function that scores only rows with less than 10% NAs (returns NA if all or above threshold percentage of rows are NA); can reverse code if vector of column indexes and min, max are provided.
ScoreLikert <- function(df, napercent = .1, tonumeric = FALSE, reversecols = NULL, min = NULL, max = NULL) {
  reverse_list <- list(reversecols = reversecols, min = min, max = max)
  reverse_check <- !sapply(reverse_list, is.null)
  
  # Recode to numeric, but watch out to coercion to not introduce NAs
  colstonumeric <- function(df){
    tryCatch({
      df_num <- as.data.frame(
        lapply(df,
               function(x) { as.numeric(as.character(x))})) 
    },warning = function(stop_on_warning) {
      message("Stoped the execution of numeric conversion: ", conditionMessage(stop_on_warning))
    }) 
  }
  
  if(tonumeric) df <- colstonumeric(df)
  
  if(all(reverse_check)){
    df[ ,reversecols] <- (max + min) - df[ ,reversecols]
  }else if(any(reverse_check)){
    stop("Insuficient info for reversing. Please provide: ", paste(names(reverse_list)[!reverse_check], collapse = ", "))
  }
  
  ifelse(rowSums(is.na(df)) > ncol(df) * napercent,
         NA,
         rowSums(df, na.rm = TRUE) * NA ^ (rowSums(!is.na(df)) == 0)
  )
}
##

2 Read, Clean, Recode

data_incadrari <- rio::import(file.path(folder, file_incadrari), skip = 0)

data_incadrari <- 
  data_incadrari %>%
  mutate(ID = toupper(ID),
         ID = stringr::str_replace_all(ID, "[[:blank:]]", ""),
         ID = stringr::str_remove(ID, "ID"),
         ID = stringr::str_remove(ID, "^0")) %>%
  mutate(Email = tolower(Email))

# Read data
data <- rio::import(file.path(folder, file),
                               skip = 0, which = "APS")
data <- data[-c(1:33), ]    # data begins with row 34, until 34 its a pilot study


# Rename
names(data)[13:28] <- sprintf("APS_%d", 1:16)
names(data)[29] <- "ID"

data <-
  data %>%
  dplyr::rename_all(~stringr::str_replace_all(., fixed(" "), "_")) %>%
  dplyr:: mutate(ID = toupper(ID),
                 ID = stringr::str_replace_all(ID, "[[:blank:]]", ""),
                 ID = stringr::str_replace_all(ID, "@.*", ""),
                 ID = stringr::str_remove(ID, "ID"),
                 ID = stringr::str_remove(ID, "^0")) %>%
  dplyr::filter(stringr::str_detect(ID, "A10"))

data <- dplyr::left_join(data, data_incadrari, by = "ID")



# Cherck - should be 3 for 21 subjs, but some will have 2 (Pre + Post, no Followup)
data %>%
  count(ID)  


# Add PrePost Column
data <- 
  data %>%
  dplyr::group_by(ID) %>%                           # can do arrange on Dates column if rows are not in order, but here they are
  dplyr::mutate(numbering = row_number()) %>%
  dplyr::mutate(PrePost = dplyr::case_when(numbering == 1 ~ "Pre",
                                           numbering == 2 ~ "Post",
                                           numbering == 3 ~ "Followup",
                                           TRUE ~ "Other")) %>% 
  dplyr::mutate(PrePost = factor(PrePost, levels = c("Pre", "Post", "Followup"))) %>% 
  dplyr::ungroup() %>%
  dplyr::mutate(Conditie = factor(Conditie, levels = c("experimental", "ctrl")))

2.1 Score APS

3 Analyses


4 Session Info

R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 8.1 x64 (build 9600)

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] ggstatsplot_0.8.0          pwr_1.2-2                  rlang_0.4.11               emmeans_1.5.4              rio_0.5.26                
 [6] scales_1.1.1               ggpubr_0.4.0               tadaatoolbox_0.16.1        summarytools_0.8.8         rstatix_0.7.0             
[11] broom_0.7.6                PerformanceAnalytics_1.5.2 xts_0.11-2                 zoo_1.8-4                  psych_2.0.12              
[16] forcats_0.5.1              stringr_1.4.0              dplyr_1.0.6                purrr_0.3.4                readr_1.4.0               
[21] tidyr_1.1.3                tibble_3.1.1               ggplot2_3.3.3              tidyverse_1.3.1            papaja_0.1.0.9997         
[26] pacman_0.5.1              

loaded via a namespace (and not attached):
  [1] utf8_1.2.1                tidyselect_1.1.0          lme4_1.1-26               grid_3.6.1                gmp_0.5-13.2             
  [6] munsell_0.5.0             codetools_0.2-16          effectsize_0.4.5          statmod_1.4.35            withr_2.4.1              
 [11] colorspace_2.0-0          knitr_1.31                rstudioapi_0.13           DescTools_0.99.40         ipmisc_6.0.2             
 [16] ggsignif_0.6.1            labeling_0.4.2            mnormt_2.0.2              farver_2.1.0              coda_0.19-2              
 [21] vctrs_0.3.8               generics_0.1.0            TH.data_1.0-9             afex_0.28-1               xfun_0.22                
 [26] BWStest_0.2.2             R6_2.5.0                  BayesFactor_0.9.12-4.2    bitops_1.0-6              reshape_0.8.8            
 [31] assertthat_0.2.1          multcomp_1.4-8            rootSolve_1.8.2.1         gtable_0.3.0              multcompView_0.1-7       
 [36] lmom_2.8                  sandwich_2.5-0            MatrixModels_0.4-1        zeallot_0.1.0             PMCMRplus_1.9.0          
 [41] splines_3.6.1             rapportools_1.0           prismatic_1.0.0           BiocManager_1.30.10       yaml_2.2.1               
 [46] reshape2_1.4.4            abind_1.4-5               modelr_0.1.8              backports_1.2.1           tools_3.6.1              
 [51] ellipsis_0.3.2            WRS2_1.1-1                Rcpp_1.0.6                plyr_1.8.6                RCurl_1.95-4.11          
 [56] pbapply_1.3-4             viridis_0.5.1             correlation_0.6.1         haven_2.4.1               ggrepel_0.9.1            
 [61] fs_1.5.0                  magrittr_2.0.1            data.table_1.14.0         openxlsx_4.1.0            lmerTest_3.0-1           
 [66] reprex_2.0.0              tmvnsim_1.0-2             mvtnorm_1.1-1             pixiedust_0.9.1           matrixStats_0.54.0       
 [71] hms_1.0.0                 patchwork_1.1.1           evaluate_0.14             xtable_1.8-4              pairwiseComparisons_3.1.6
 [76] readxl_1.3.1              gridExtra_2.3             compiler_3.6.1            crayon_1.4.1              minqa_1.2.4              
 [81] htmltools_0.5.1.1         mc2d_0.1-18               expm_0.999-3              Exact_2.1                 lubridate_1.7.10         
 [86] DBI_1.0.0                 SuppDists_1.1-9.4         kSamples_1.2-9            dbplyr_2.1.1              MASS_7.3-51.4            
 [91] boot_1.3-22               Matrix_1.2-17             car_3.0-10                cli_2.5.0                 pryr_0.1.4               
 [96] quadprog_1.5-5            parallel_3.6.1            insight_0.14.2            pkgconfig_2.0.3           statsExpressions_1.1.0   
[101] numDeriv_2016.8-1.1       foreign_0.8-71            xml2_1.3.2                paletteer_1.3.0           estimability_1.3         
[106] rvest_1.0.0               snakecase_0.9.2           digest_0.6.27             parameters_0.14.0         janitor_2.1.0            
[111] rmarkdown_2.7             cellranger_1.1.0          nortest_1.0-4             gld_2.6.2                 curl_4.3                 
[116] gtools_3.8.1              nloptr_1.2.2.2            lifecycle_1.0.0           nlme_3.1-140              jsonlite_1.7.2           
[121] carData_3.0-2             viridisLite_0.3.0         fansi_0.4.2               pillar_1.6.1              lattice_0.20-38          
[126] httr_1.4.2                survival_2.44-1.1         glue_1.4.2                bayestestR_0.10.0         zip_1.0.0                
[131] pander_0.6.3              class_7.3-15              stringi_1.5.3             performance_0.7.2         rematch2_2.1.2           
[136] memoise_1.1.0             Rmpfr_0.7-1               e1071_1.7-0              
 

A work by Claudiu Papasteri

 

LS0tDQp0aXRsZTogIjxicj4gUEE0IFJNTiIgDQpzdWJ0aXRsZTogIlJlcG9ydCINCmF1dGhvcjogIjxicj4gQ2xhdWRpdSBQYXBhc3RlcmkiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlbSAlWScpYCINCm91dHB1dDogDQogICAgaHRtbF9ub3RlYm9vazoNCiAgICAgICAgICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgICAgICAgICAgdG9jOiB0cnVlDQogICAgICAgICAgICB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgICAgICAgICAgdGhlbWU6IHNwYWNlbGFiDQogICAgICAgICAgICBoaWdobGlnaHQ6IHRhbmdvDQogICAgICAgICAgICBmb250LWZhbWlseTogQXJpYWwNCiAgICAgICAgICAgIGZpZ193aWR0aDogMTANCiAgICAgICAgICAgIGZpZ19oZWlnaHQ6IDkNCiAgICAjIHBkZl9kb2N1bWVudDogDQogICAgICAgICAgICAjIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgIyAgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICAjICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICAgICAgICAgICMgZm9udHNpemU6IDExcHQNCiAgICAgICAgICAgICMgZ2VvbWV0cnk6IG1hcmdpbj0xaW4NCiAgICAgICAgICAgICMgZmlnX3dpZHRoOiA3DQogICAgICAgICAgICAjIGZpZ19oZWlnaHQ6IDYNCiAgICAgICAgICAgICMgZmlnX2NhcHRpb246IHRydWUNCiAgICAjIGdpdGh1Yl9kb2N1bWVudDogDQogICAgICAgICAgICAjIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgIyB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgICMgaHRtbF9wcmV2aWV3OiBmYWxzZQ0KICAgICAgICAgICAgIyBmaWdfd2lkdGg6IDUNCiAgICAgICAgICAgICMgZmlnX2hlaWdodDogNQ0KICAgICAgICAgICAgIyBkZXY6IGpwZWcNCi0tLQ0KDQoNCjwhLS0gU2V0dXAgLS0+DQoNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIGtpbnRyIG9wdGlvbnMNCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCiAgY29tbWVudCA9ICIjIiwNCiAgY29sbGFwc2UgPSBUUlVFLA0KICBlcnJvciA9IFRSVUUsDQogIGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgY2FjaGUgPSBUUlVFICAgICAgICMgZWNobyA9IEZhbHNlIGZvciBnaXRodWJfZG9jdW1lbnQsIGJ1dCB3aWxsIGJlIGZvbGRlZCBpbiBodG1sX25vdGVib29rDQopDQoNCiMgR2VuZXJhbCBSIG9wdGlvbnMgYW5kIGluZm8NCnNldC5zZWVkKDExMSkgICAgICAgICAgICAgICAjIGluIGNhc2Ugd2UgdXNlIHJhbmRvbWl6ZWQgcHJvY2VkdXJlcyAgICAgICANCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAgICAgICAjIHBvc2l0aXZlIHZhbHVlcyBiaWFzIHRvd2FyZHMgZml4ZWQgYW5kIG5lZ2F0aXZlIHRvd2FyZHMgc2NpZW50aWZpYyBub3RhdGlvbg0KDQojIExvYWQgcGFja2FnZXMNCmlmICghcmVxdWlyZSgicGFjbWFuIikpIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQpwYWNrYWdlcyA8LSBjKA0KICAicGFwYWphIiwNCiAgInRpZHl2ZXJzZSIsICAgICAgIA0KICAicHN5Y2giLCAiUGVyZm9ybWFuY2VBbmFseXRpY3MiLCAgICAgICAgICANCiAgImJyb29tIiwgInJzdGF0aXgiLA0KICAic3VtbWFyeXRvb2xzIiwgInRhZGFhdG9vbGJveCIsICAgICAgICAgICANCiAgImdncGxvdDIiLCAiZ2dwdWJyIiwgInNjYWxlcyIsDQogICJybGFuZyIsDQogICJyaW8iLA0KICAicnN0YXRpeCIsICJicm9vbSIsICJlbW1lYW5zIiwgInB3ciIsDQogICJnZ3N0YXRzcGxvdCINCiAgIyAsIC4uLg0KKQ0KaWYgKCFyZXF1aXJlKCJwYWNtYW4iKSkgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCnBhY21hbjo6cF9sb2FkKGNoYXIgPSBwYWNrYWdlcykNCg0KIyBUaGVtZXMgZm9yIGdncGxvdDIgcGxvdGluZyAoaGVyZSB1c2VkIEFQQSBzdHlsZSkNCnRoZW1lX3NldCh0aGVtZV9hcGEoKSkNCmBgYA0KDQoNCg0KDQoNCjwhLS0gUmVwb3J0IC0tPg0KDQojIERlZmluZSBmdW5jdGlvbnMNCg0KYGBge3IgZGVmX2Z1bmN9DQojIyBEZWZpbmUgZnVuY3Rpb24gdGhhdCByZWNvZGVzIHRvIG51bWVyaWMsIGJ1dCB3YXRjaGVzIG91dCB0byBjb2VyY2lvbiB0byBub3QgaW50cm9kdWNlIE5Bcw0KY29sc3RvbnVtZXJpYyA8LSBmdW5jdGlvbihkZil7DQogIHRyeUNhdGNoKHsNCiAgICBkZl9udW0gPC0gYXMuZGF0YS5mcmFtZSgNCiAgICAgIGxhcHBseShkZiwNCiAgICAgICAgICAgICBmdW5jdGlvbih4KSB7IGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHgpKX0pKSANCiAgfSx3YXJuaW5nID0gZnVuY3Rpb24oc3RvcF9vbl93YXJuaW5nKSB7DQogICAgbWVzc2FnZSgiU3RvcGVkIHRoZSBleGVjdXRpb24gb2YgbnVtZXJpYyBjb252ZXJzaW9uOiAiLCBjb25kaXRpb25NZXNzYWdlKHN0b3Bfb25fd2FybmluZykpDQogIH0pIA0KfQ0KIyMNCiMjIERlZmluZSBmdW5jdGlvbiB0aGF0IHJldmVyc2UgY29kZXMgaXRlbXMNClJldmVyc2VDb2RlIDwtIGZ1bmN0aW9uKGRmLCB0b251bWVyaWMgPSBGQUxTRSwgbWluID0gTlVMTCwgbWF4ID0gTlVMTCkgew0KICBpZih0b251bWVyaWMpIGRmIDwtIGNvbHN0b251bWVyaWMoZGYpDQogIGRmIDwtIChtYXggKyBtaW4pIC0gZGYNCn0NCiMjDQojIyBEZWZpbmUgZnVuY3Rpb24gdGhhdCBzY29yZXMgb25seSByb3dzIHdpdGggbGVzcyB0aGFuIDEwJSBOQXMgKHJldHVybnMgTkEgaWYgYWxsIG9yIGFib3ZlIHRocmVzaG9sZCBwZXJjZW50YWdlIG9mIHJvd3MgYXJlIE5BKTsgY2FuIHJldmVyc2UgY29kZSBpZiB2ZWN0b3Igb2YgY29sdW1uIGluZGV4ZXMgYW5kIG1pbiwgbWF4IGFyZSBwcm92aWRlZC4NClNjb3JlTGlrZXJ0IDwtIGZ1bmN0aW9uKGRmLCBuYXBlcmNlbnQgPSAuMSwgdG9udW1lcmljID0gRkFMU0UsIHJldmVyc2Vjb2xzID0gTlVMTCwgbWluID0gTlVMTCwgbWF4ID0gTlVMTCkgew0KICByZXZlcnNlX2xpc3QgPC0gbGlzdChyZXZlcnNlY29scyA9IHJldmVyc2Vjb2xzLCBtaW4gPSBtaW4sIG1heCA9IG1heCkNCiAgcmV2ZXJzZV9jaGVjayA8LSAhc2FwcGx5KHJldmVyc2VfbGlzdCwgaXMubnVsbCkNCiAgDQogICMgUmVjb2RlIHRvIG51bWVyaWMsIGJ1dCB3YXRjaCBvdXQgdG8gY29lcmNpb24gdG8gbm90IGludHJvZHVjZSBOQXMNCiAgY29sc3RvbnVtZXJpYyA8LSBmdW5jdGlvbihkZil7DQogICAgdHJ5Q2F0Y2goew0KICAgICAgZGZfbnVtIDwtIGFzLmRhdGEuZnJhbWUoDQogICAgICAgIGxhcHBseShkZiwNCiAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHsgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoeCkpfSkpIA0KICAgIH0sd2FybmluZyA9IGZ1bmN0aW9uKHN0b3Bfb25fd2FybmluZykgew0KICAgICAgbWVzc2FnZSgiU3RvcGVkIHRoZSBleGVjdXRpb24gb2YgbnVtZXJpYyBjb252ZXJzaW9uOiAiLCBjb25kaXRpb25NZXNzYWdlKHN0b3Bfb25fd2FybmluZykpDQogICAgfSkgDQogIH0NCiAgDQogIGlmKHRvbnVtZXJpYykgZGYgPC0gY29sc3RvbnVtZXJpYyhkZikNCiAgDQogIGlmKGFsbChyZXZlcnNlX2NoZWNrKSl7DQogICAgZGZbICxyZXZlcnNlY29sc10gPC0gKG1heCArIG1pbikgLSBkZlsgLHJldmVyc2Vjb2xzXQ0KICB9ZWxzZSBpZihhbnkocmV2ZXJzZV9jaGVjaykpew0KICAgIHN0b3AoIkluc3VmaWNpZW50IGluZm8gZm9yIHJldmVyc2luZy4gUGxlYXNlIHByb3ZpZGU6ICIsIHBhc3RlKG5hbWVzKHJldmVyc2VfbGlzdClbIXJldmVyc2VfY2hlY2tdLCBjb2xsYXBzZSA9ICIsICIpKQ0KICB9DQogIA0KICBpZmVsc2Uocm93U3Vtcyhpcy5uYShkZikpID4gbmNvbChkZikgKiBuYXBlcmNlbnQsDQogICAgICAgICBOQSwNCiAgICAgICAgIHJvd1N1bXMoZGYsIG5hLnJtID0gVFJVRSkgKiBOQSBeIChyb3dTdW1zKCFpcy5uYShkZikpID09IDApDQogICkNCn0NCiMjDQpgYGANCg0KDQojIFJlYWQsIENsZWFuLCBSZWNvZGUNCg0KYGBge3IgcmVkX2NsZWFuX3JlY29kZV9tZXJnZSwgcmVzdWx0cz0naGlkZScsIG1lc3NhZ2U9RkFMU0V9DQojfn5+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+fg0KIyBSZWFkLCBDbGVhbiwgUmVjb2RlLCBVbml0ZQ0KI35+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+fn4NCg0KIyMgUmVhZCBmaWxlcw0KZm9sZGVyIDwtICJDOi9Vc2Vycy9NaWhhaS9EZXNrdG9wL1IgTm90ZWJvb2tzL25vdGVib29rcy9QQTQtcmVwb3J0LVJNTiINCmZpbGUgPC0gIjA5LjA2LjIwMjEgUmFzcHVuc3VyaSBjaGVzdGlvbmFyZSBvbmxpbmUueGxzeCINCmZpbGVfaW5jYWRyYXJpIDwtICJJbmNhZHJhcmUgUEE0IFJNTi54bHN4Ig0KDQpzZXR3ZChmb2xkZXIpDQoNCiMgUmVhZCBpbmNhZHJhcmUNCmRhdGFfaW5jYWRyYXJpIDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aChmb2xkZXIsIGZpbGVfaW5jYWRyYXJpKSwgc2tpcCA9IDApDQoNCmRhdGFfaW5jYWRyYXJpIDwtIA0KICBkYXRhX2luY2FkcmFyaSAlPiUNCiAgbXV0YXRlKElEID0gdG91cHBlcihJRCksDQogICAgICAgICBJRCA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChJRCwgIltbOmJsYW5rOl1dIiwgIiIpLA0KICAgICAgICAgSUQgPSBzdHJpbmdyOjpzdHJfcmVtb3ZlKElELCAiSUQiKSwNCiAgICAgICAgIElEID0gc3RyaW5ncjo6c3RyX3JlbW92ZShJRCwgIl4wIikpICU+JQ0KICBtdXRhdGUoRW1haWwgPSB0b2xvd2VyKEVtYWlsKSkNCg0KIyBSZWFkIGRhdGENCmRhdGEgPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKGZvbGRlciwgZmlsZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2tpcCA9IDAsIHdoaWNoID0gIkFQUyIpDQpkYXRhIDwtIGRhdGFbLWMoMTozMyksIF0gICAgIyBkYXRhIGJlZ2lucyB3aXRoIHJvdyAzNCwgdW50aWwgMzQgaXRzIGEgcGlsb3Qgc3R1ZHkNCg0KDQojIFJlbmFtZQ0KbmFtZXMoZGF0YSlbMTM6MjhdIDwtIHNwcmludGYoIkFQU18lZCIsIDE6MTYpDQpuYW1lcyhkYXRhKVsyOV0gPC0gIklEIg0KDQpkYXRhIDwtDQogIGRhdGEgJT4lDQogIGRwbHlyOjpyZW5hbWVfYWxsKH5zdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoLiwgZml4ZWQoIiAiKSwgIl8iKSkgJT4lDQogIGRwbHlyOjogbXV0YXRlKElEID0gdG91cHBlcihJRCksDQogICAgICAgICAgICAgICAgIElEID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKElELCAiW1s6Ymxhbms6XV0iLCAiIiksDQogICAgICAgICAgICAgICAgIElEID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKElELCAiQC4qIiwgIiIpLA0KICAgICAgICAgICAgICAgICBJRCA9IHN0cmluZ3I6OnN0cl9yZW1vdmUoSUQsICJJRCIpLA0KICAgICAgICAgICAgICAgICBJRCA9IHN0cmluZ3I6OnN0cl9yZW1vdmUoSUQsICJeMCIpKSAlPiUNCiAgZHBseXI6OmZpbHRlcihzdHJpbmdyOjpzdHJfZGV0ZWN0KElELCAiQTEwIikpDQoNCmRhdGEgPC0gZHBseXI6OmxlZnRfam9pbihkYXRhLCBkYXRhX2luY2FkcmFyaSwgYnkgPSAiSUQiKQ0KDQoNCg0KIyBDaGVyY2sgLSBzaG91bGQgYmUgMyBmb3IgMjEgc3VianMsIGJ1dCBzb21lIHdpbGwgaGF2ZSAyIChQcmUgKyBQb3N0LCBubyBGb2xsb3d1cCkNCmRhdGEgJT4lDQogIGNvdW50KElEKSAgDQoNCiMgQWRkIFByZVBvc3QgQ29sdW1uDQpkYXRhIDwtIA0KICBkYXRhICU+JQ0KICBkcGx5cjo6Z3JvdXBfYnkoSUQpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY2FuIGRvIGFycmFuZ2Ugb24gRGF0ZXMgY29sdW1uIGlmIHJvd3MgYXJlIG5vdCBpbiBvcmRlciwgYnV0IGhlcmUgdGhleSBhcmUNCiAgZHBseXI6Om11dGF0ZShudW1iZXJpbmcgPSByb3dfbnVtYmVyKCkpICU+JQ0KICBkcGx5cjo6bXV0YXRlKFByZVBvc3QgPSBkcGx5cjo6Y2FzZV93aGVuKG51bWJlcmluZyA9PSAxIH4gIlByZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyaW5nID09IDIgfiAiUG9zdCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyaW5nID09IDMgfiAiRm9sbG93dXAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAiT3RoZXIiKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKFByZVBvc3QgPSBmYWN0b3IoUHJlUG9zdCwgbGV2ZWxzID0gYygiUHJlIiwgIlBvc3QiLCAiRm9sbG93dXAiKSkpICU+JSANCiAgZHBseXI6OnVuZ3JvdXAoKSAlPiUNCiAgZHBseXI6Om11dGF0ZShDb25kaXRpZSA9IGZhY3RvcihDb25kaXRpZSwgbGV2ZWxzID0gYygiZXhwZXJpbWVudGFsIiwgImN0cmwiKSkpDQoNCnRhYmxlKGRhdGEkSUQsIGRhdGEkUHJlUG9zdCkgICAjIGNoZWNrDQp0YWJsZShkYXRhJElELCBkYXRhJENvbmRpdGllKQ0KdGFibGUoZGF0YSRDb25kaXRpZSwgZGF0YSRQcmVQb3N0KQ0KYGBgDQoNCg0KIyMgU2NvcmUgQVBTDQoNCmBgYHtyfQ0KIyBSZWNvZGUNCiMgZGF0YSA8LQ0KIyAgIGRhdGEgJT4lDQojICAgZHBseXI6Om11dGF0ZV9hdCh2YXJzKHNwcmludGYoIkFQU18lZCIsIDE6MTYpKSwgfmNhc2Vfd2hlbiguID09ICJuaWNpb2RhdMSDIC8gYXByb2FwZSBuaWNpb2RhdMSDIGFkZXbEg3JhdCIgfiAxLA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLiA9PSAib2NhemlvbmFsIGFkZXbEg3JhdCIgfiAyLA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLiA9PSAiY8OidGVvZGF0xIMgYWRldsSDcmF0IiB+IDMsDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuID09ICJkZXNlb3JpIGFkZXbEg3JhdCIgfiA0LA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLiA9PSAiYXByb2FwZSDDrm50b3RkZWF1bmEvw65udG90ZGVhdW5hIGFkZXbEg3JhdCIgfiA1LA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IE5BX3JlYWxfKSkNCg0KDQojIFVwZGF0ZWQgYmVjYXVzZSBzcGVjaWFsIGNoYXJhY3RlcnMgd2VyZSBub3QgcmVjb2duaXplZCAtLSByZXBsYWNlZCBhcyB3aWxkIGNhcmRzIGluIHJlZ2V4DQpkYXRhWywgc3ByaW50ZigiQVBTXyVkIiwgMToxNildIDwtDQogIGRhdGFbLCBzcHJpbnRmKCJBUFNfJWQiLCAxOjE2KV0gJT4lDQogIGRwbHlyOjptdXRhdGVfYWxsKH5jYXNlX3doZW4oc3RyaW5ncjo6c3RyX2RldGVjdCguLCAibmljaW9kYXQqIikgfiAxLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3I6OnN0cl9kZXRlY3QoLiwgIm9jYXppb25hbCoiKSB+IDIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5ncjo6c3RyX2RldGVjdCguLCAiYz90ZW9kYXQqIikgfiAzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3I6OnN0cl9kZXRlY3QoLiwgImRlc2VvcmkqIikgfiA0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3I6OnN0cl9kZXRlY3QoLiwgIm50b3RkZWF1bmEiKSB+IDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gTkFfcmVhbF8pKQ0KDQojIFNjb3JlDQpkYXRhJEFQU19Ub3RhbCA8LSBTY29yZUxpa2VydChkYXRhWywgc3ByaW50ZigiQVBTXyVkIiwgMToxNildLCBuYXBlcmNlbnQgPSAuMTMpDQpgYGANCg0KDQojIEFuYWx5c2VzDQoNCmBgYHtyLCBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD02LCBmaWcuc2VwPWMoJ1xcbmV3bGluZScsJ1xcbmV3bGluZScpfQ0KcF9hcHNfMSA8LSANCiAgZGF0YSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kaXRpZSA9PSAiZXhwZXJpbWVudGFsIiwgUHJlUG9zdCAlaW4lIGMoIlByZSIsICJQb3N0IikpICU+JQ0KICAgIGdnd2l0aGluc3RhdHMoDQogICAgICB4ID0gUHJlUG9zdCwNCiAgICAgIHkgPSBBUFNfVG90YWwsDQogICAgICB0eXBlID0gIm5wIiwgIyBub24tcGFyYW1ldHJpYyBzdGF0aXN0aWNzDQogICAgICB4bGFiID0gIiIsDQogICAgICBvdXRsaWVyLnRhZ2dpbmcgPSBUUlVFLA0KICAgICAgb3V0bGllci5sYWJlbCA9IElELCANCiAgICAgIGFubm90YXRpb24uYXJncyA9IGxpc3QodGl0bGUgPSAiRXhwZXJpbWVudGFsIC0gUHJlICYgUG9zdCIpKSANCg0KcF9hcHNfMQ0KZXh0cmFjdF9zdGF0cyhwX2Fwc18xKSRzdWJ0aXRsZV9kYXRhDQoNCg0KcF9hcHNfMiA8LSANCiAgZGF0YSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kaXRpZSA9PSAiZXhwZXJpbWVudGFsIikgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUNCiAgZHBseXI6OmZpbHRlcihuKCkgPT0gMykgJT4lDQogIGRwbHlyOjp1bmdyb3VwKCkgJT4lDQogICAgZ2d3aXRoaW5zdGF0cygNCiAgICAgIHggPSBQcmVQb3N0LA0KICAgICAgeSA9IEFQU19Ub3RhbCwNCiAgICAgIHR5cGUgPSAibnAiLCAjIG5vbi1wYXJhbWV0cmljIHN0YXRpc3RpY3MNCiAgICAgIHhsYWIgPSAiIiwNCiAgICAgIG91dGxpZXIudGFnZ2luZyA9IFRSVUUsDQogICAgICBvdXRsaWVyLmxhYmVsID0gSUQsIA0KICAgICAgYW5ub3RhdGlvbi5hcmdzID0gbGlzdCh0aXRsZSA9ICJFeHBlcmltZW50YWwgLSBQcmUsIFBvc3QgYW5kIEZvbGxvd3VwIikpIA0KDQpwX2Fwc18yDQpleHRyYWN0X3N0YXRzKHBfYXBzXzIpJHN1YnRpdGxlX2RhdGENCg0KDQpwX2Fwc18zIDwtIA0KICBkYXRhICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmRpdGllID09ICJjdHJsIiwgUHJlUG9zdCAlaW4lIGMoIlByZSIsICJQb3N0IikpICU+JQ0KICAgIGdnd2l0aGluc3RhdHMoDQogICAgICB4ID0gUHJlUG9zdCwNCiAgICAgIHkgPSBBUFNfVG90YWwsDQogICAgICB0eXBlID0gIm5wIiwgIyBub24tcGFyYW1ldHJpYyBzdGF0aXN0aWNzDQogICAgICB4bGFiID0gIiIsDQogICAgICBvdXRsaWVyLnRhZ2dpbmcgPSBUUlVFLA0KICAgICAgb3V0bGllci5sYWJlbCA9IElELCANCiAgICAgIGFubm90YXRpb24uYXJncyA9IGxpc3QodGl0bGUgPSAiQ29udHJvbCAtIFByZSAmIFBvc3QiKSkgDQoNCnBfYXBzXzMNCmV4dHJhY3Rfc3RhdHMocF9hcHNfMykkc3VidGl0bGVfZGF0YQ0KDQoNCnBfYXBzXzQgPC0gDQogIGRhdGEgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZGl0aWUgPT0gImN0cmwiKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKG4oKSA9PSAzKSAlPiUNCiAgZHBseXI6OnVuZ3JvdXAoKSAlPiUNCiAgICBnZ3dpdGhpbnN0YXRzKA0KICAgICAgeCA9IFByZVBvc3QsDQogICAgICB5ID0gQVBTX1RvdGFsLA0KICAgICAgdHlwZSA9ICJucCIsICMgbm9uLXBhcmFtZXRyaWMgc3RhdGlzdGljcw0KICAgICAgeGxhYiA9ICIiLA0KICAgICAgb3V0bGllci50YWdnaW5nID0gVFJVRSwNCiAgICAgIG91dGxpZXIubGFiZWwgPSBJRCwgDQogICAgICBhbm5vdGF0aW9uLmFyZ3MgPSBsaXN0KHRpdGxlID0gIkV4cGVyaW1lbnRhbCAtIFByZSwgUG9zdCBhbmQgRm9sbG93dXAiKSkgDQoNCnBfYXBzXzQNCmV4dHJhY3Rfc3RhdHMocF9hcHNfNCkkc3VidGl0bGVfZGF0YQ0KDQoNCmBgYA0KDQoNCg0KDQoNCg0KDQoNCjwhLS0gU2Vzc2lvbiBJbmZvIGFuZCBMaWNlbnNlIC0tPg0KDQo8YnI+DQoNCiMgU2Vzc2lvbiBJbmZvDQpgYGB7ciBzZXNzaW9uX2luZm8sIGVjaG8gPSBGQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQ0Kc2Vzc2lvbkluZm8oKSAgICANCmBgYA0KDQo8IS0tIEZvb3RlciAtLT4NCiZuYnNwOw0KPGhyIC8+DQo8cCBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyI+QSB3b3JrIGJ5IDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9DbGF1ZGl1UGFwYXN0ZXJpLyI+Q2xhdWRpdSBQYXBhc3Rlcmk8L2E+PC9wPg0KPHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxzcGFuIHN0eWxlPSJjb2xvcjogIzgwODA4MDsiPjxlbT5jbGF1ZGl1LnBhcGFzdGVyaUBnbWFpbC5jb208L2VtPjwvc3Bhbj48L3A+DQombmJzcDsNCg==