1 Define scoring 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 Quick ggwithinstats function

my_ggwithinstats <- function(data, title, x, y, outlier.label, xlab, ylab) {
  x <- rlang::enquo(x)
  y <- rlang::enquo(y)
  outlier.label <- rlang::enquo(outlier.label)
  
  data %>%
    ggstatsplot::ggwithinstats(
      x = !!x,
      y = !!y,
      title = title,
      xlab = xlab,
      ylab = ylab,
      outlier.tagging = TRUE,            # whether outliers need to be tagged
      outlier.label = !!outlier.label,   # variable to be used for tagging outliers
      outlier.coef = 2,
      pairwise.comparisons = TRUE,
      pairwise.display = "significant",
      results.subtitle = TRUE,
      type = "parametric",
      bf.message = FALSE, 
      p.adjust.method = "none",
      point.path = TRUE,
      ggtheme = ggprism::theme_prism(),
      # package = "RColorBrewer",  # "ggsci",
      # palette = "Dark",         # "default_jco",
      violin.args = list(width = 0.9, alpha = 0.2, size = 1, color = "black"),
      centrality.point.args = list(size = 5, color = "darkred"),
      centrality.label.args = list(size = 3, nudge_x = 0.2, segment.linetype = 5, fill = "#FFF8E7"), 
      ggplot.component = list(
        theme(
          plot.title = element_text(hjust = 0, size = 16),
          plot.subtitle = element_text(hjust = 0, size = 12), 
          plot.caption = element_text(hjust = 0, size = 12), 
          text = element_text(size = 14)
      ))
    ) + scale_colour_grey(start = 0.2, end = 0.2)   # hacky way to change point color
}

# For publication
my_ggwithinstats2 <- function(data, title, x, y, outlier.label, xlab, ylab, 
                              outlier.tagging = FALSE, results.subtitle = TRUE, 
                              centrality.label.args = TRUE, point.path = TRUE,
                              type = "parametric", 
                              ...) {  # ... for limits and breaks
  x <- rlang::enquo(x)
  y <- rlang::enquo(y)
  outlier.label <- rlang::enquo(outlier.label)
  
  if(centrality.label.args){
    centrality.label.args <- list(size = 3, nudge_x = 0.2, segment.linetype = 5, fill = "#FFF8E7")
  }else{
    centrality.label.args <- list(size = 0, nudge_x = 10, segment.linetype = 0, alpha = 0) # very hacky way of not showing label
  }
  
  data %>%
    ggstatsplot::ggwithinstats(
      x = !!x,
      y = !!y,
      title = title,
      xlab = xlab,
      ylab = ylab,
      outlier.tagging = outlier.tagging,                    # whether outlines need to be tagged
      outlier.label = !!outlier.label,                      # variable to be used for tagging outliers
      outlier.coef = 2,
      pairwise.comparisons = TRUE,
      pairwise.display = "all",
      results.subtitle = results.subtitle,
      type = type,
      bf.message = FALSE, 
      p.adjust.method = "none",
      point.path = point.path,
      ggtheme = ggprism::theme_prism(),
      # package = "RColorBrewer",  # "ggsci",
      # palette = "Dark",         # "default_jco",
      violin.args = list(width = 0.9, alpha = 0.2, size = 1, color = "black"),
      centrality.plotting = TRUE,
      centrality.type = "parameteric",
      centrality.point.args = list(size = 5, color = "darkred"),
      centrality.label.args = centrality.label.args,
      ggplot.component = list(
        theme(
          plot.title = element_text(hjust = 0, size = 16),
          plot.subtitle = element_text(hjust = 0, size = 12), 
          plot.caption = element_text(hjust = 0, size = 12), 
          text = element_text(size = 14)
      ))
    ) + scale_colour_grey(start = 0.2, end = 0.2) +  # hacky way to change point color
    scale_y_continuous(...)
}

# Fast ggsave - saves plot with filename of R plot object
fast_ggsave <- function(plot, device = "png", path = NULL,
                        units = "in", dpi = 300, width = 5, height = 5, ...){ 
  plot_name <- deparse(substitute(plot))
  ggplot2::ggsave(filename = paste0(plot_name, ".", device), plot = plot,
                  device = device, path = path,
                  units = units, dpi = dpi,
                  width = width, height = height,
                  ...
  )
  
} # use: fast_ggsave(jrad_ox_p, path = savefolder)

2.1 Behavioral scales

folder <- "C:/Users/Mihai/Desktop/R Notebooks/notebooks/PA4-geronto"
file_beh_pre <- "Set teste zi 1 pre grup vârstnici.xlsx"
file_beh_post <- "Set teste zi 5 post grup vârstnici.xlsx"


### Pre
behav_pre <- rio::import(file.path(folder, file_beh_pre))
behav_pre <- behav_pre[-1,]
names(behav_pre)[6] <- "id"
behav_pre[behav_pre$id == "CU16PA1",]$id <- "CN16PA1"     # typo, should be "CN_16" instead of "CU-16" -- in vas its "CN_16"
behav_pre <- behav_pre %>% 
  janitor::clean_names() %>%
  dplyr::mutate(id = stringr::str_remove(id, "PA1"),
                id = gsub('^(.{2})(.*)$', '\\1_\\2', id)) %>%        # insert "_" afeter code
  tidyr::separate(id, into = c("forma", "ID_no"), remove = FALSE, sep = "_") %>%
  dplyr::mutate(forma = gsub('^(.{1})(.*)$', '\\1_\\2', id)) %>%
  tidyr::separate(forma, into = c("Cond", "Cog_imp"), remove = FALSE, sep = "_") %>%
  dplyr::mutate(Cond = dplyr::case_when(Cond == "C" ~ "CTRL",
                                        Cond == "E" ~ "TR",
                                        TRUE ~ NA_character_)) %>%
  dplyr::mutate(id = stringr::str_replace(id, "O", "0"),
                id = stringr::str_replace(id, "o", "0")) %>%
  dplyr::mutate(ID_no = stringr::str_replace(ID_no, "O", "0"),
                ID_no = stringr::str_replace(ID_no, "o", "0"),
                ID_no = as.numeric(ID_no))

## Post
behav_post <- rio::import(file.path(folder, file_beh_post))
behav_post <- behav_post[-1,]
behav_post <- behav_post[,-c(6:9)]
names(behav_post)[6] <- "id"
behav_post <- behav_post %>% 
  janitor::clean_names() %>%
  dplyr::mutate(id = stringr::str_remove(id, "PA1"),
                id = gsub('^(.{2})(.*)$', '\\1_\\2', id)) %>%        # insert "_" afeter code
  tidyr::separate(id, into = c("forma", "ID_no"), remove = FALSE, sep = "_") %>%
  dplyr::mutate(forma = gsub('^(.{1})(.*)$', '\\1_\\2', id)) %>%
  tidyr::separate(forma, into = c("Cond", "Cog_imp"), remove = FALSE, sep = "_") %>%
  dplyr::mutate(Cond = dplyr::case_when(Cond == "C" ~ "CTRL",
                                        Cond == "E" ~ "TR",
                                        TRUE ~ NA_character_)) %>%
  dplyr::mutate(id = stringr::str_replace(id, "O", "0"),
                id = stringr::str_replace(id, "o", "0")) %>%
  dplyr::mutate(ID_no = stringr::str_replace(ID_no, "O", "0"),
                ID_no = stringr::str_replace(ID_no, "o", "0"),
                ID_no = as.numeric(ID_no))



# checks
bla <- data.frame(Pre = names(behav_pre), Post = names(behav_post))

behav_pre %>%
  dplyr::count(id) %>%  # 40 x 1
  dplyr::arrange(id) %>%
  dplyr::pull(id) -> behav_pre_ids
 
  
behav_post %>%
  dplyr::count(id) %>%  # 40 x 1
  dplyr::arrange(id) %>%
  dplyr::pull(id) -> behav_post_ids

identical(behav_pre_ids, behav_post_ids)    # one has CU_16, the other CN_16
[1] TRUE
## PANAS: Positive Affect Score = sum items 1, 3, 5, 9, 10, 12, 14, 16, 17, 19. Negative Affect Score = sum items 2, 4, 6, 7, 8, 11, 13, 15, 18, 20.  
index_item_panas <- 11:30
colnames(behav_pre)[index_item_panas] <- sprintf("PANAS_%d", 1:20)
colnames(behav_post)[index_item_panas] <- sprintf("PANAS_%d", 1:20)

behav_pre[, index_item_panas] <- data.frame(lapply(behav_pre[, index_item_panas], 
                                      function(x) {gsub(".*în foarte mică măsură.*", "1", x)}), stringsAsFactors = FALSE)
behav_pre[, index_item_panas] <- data.frame(lapply(behav_pre[, index_item_panas], 
                                      function(x) {gsub(".*în mică măsură.*", "2", x)}), stringsAsFactors = FALSE)
behav_pre[, index_item_panas] <- data.frame(lapply(behav_pre[, index_item_panas], 
                                      function(x) {gsub(".*într-o oarecare măsură.*", "3", x)}), stringsAsFactors = FALSE)
behav_pre[, index_item_panas] <- data.frame(lapply(behav_pre[, index_item_panas], 
                                      function(x) {gsub(".*în mare măsură.*", "4", x)}), stringsAsFactors = FALSE)
behav_pre[, index_item_panas] <- data.frame(lapply(behav_pre[, index_item_panas], 
                                      function(x) {gsub(".*în foarte mare măsură.*", "5", x)}), stringsAsFactors = FALSE)

behav_post[, index_item_panas] <- data.frame(lapply(behav_post[, index_item_panas], 
                                                      function(x) {gsub(".*în foarte mică măsură.*", "1", x)}), stringsAsFactors = FALSE)
behav_post[, index_item_panas] <- data.frame(lapply(behav_post[, index_item_panas], 
                                                      function(x) {gsub(".*în mică măsură.*", "2", x)}), stringsAsFactors = FALSE)
behav_post[, index_item_panas] <- data.frame(lapply(behav_post[, index_item_panas], 
                                                      function(x) {gsub(".*într-o oarecare măsură.*", "3", x)}), stringsAsFactors = FALSE)
behav_post[, index_item_panas] <- data.frame(lapply(behav_post[, index_item_panas], 
                                                      function(x) {gsub(".*în mare măsură.*", "4", x)}), stringsAsFactors = FALSE)
behav_post[, index_item_panas] <- data.frame(lapply(behav_post[, index_item_panas], 
                                                      function(x) {gsub(".*în foarte mare măsură.*", "5", x)}), stringsAsFactors = FALSE)

# Scoring
behav_pre$PA_Total <- ScoreLikert(behav_pre[, index_item_panas][c(1, 3, 5, 9, 10, 12, 14, 16, 17, 19)], 
                                    tonumeric = TRUE, napercent = .11)                              # not more than 1 NAs for 10 items
behav_pre$NA_Total <- ScoreLikert(behav_pre[, index_item_panas][c(2, 4, 6, 7, 8, 11, 13, 15, 18, 20)],
                                    tonumeric = TRUE, napercent = .11)                              # not more than 1 NAs for 10 items

behav_post$PA_Total <- ScoreLikert(behav_post[, index_item_panas][c(1, 3, 5, 9, 10, 12, 14, 16, 17, 19)], 
                                     tonumeric = TRUE, napercent = .11)                              # not more than 1 NAs for 10 items
behav_post$NA_Total <- ScoreLikert(behav_post[, index_item_panas][c(2, 4, 6, 7, 8, 11, 13, 15, 18, 20)],
                                     tonumeric = TRUE, napercent = .11)                              # not more than 1 NAs for 10 items




## PSS-SF 14 (likert 0-4). Items 4, 5, 6, 7, 9, 10, and 13 are scored in reverse direction.
index_item_pss <- 31:44
index_item_revPSS <- c(4, 5, 6, 7, 9, 10, 13)
colnames(behav_pre)[index_item_pss] <- sprintf("PSS_%d", 1:14)
colnames(behav_post)[index_item_pss] <- sprintf("PSS_%d", 1:14)

behav_pre[, index_item_pss] <- data.frame(lapply(behav_pre[, index_item_pss], 
                                      function(x) {gsub(".*niciodată.*", "0", x)}), stringsAsFactors = FALSE)
behav_pre[, index_item_pss] <- data.frame(lapply(behav_pre[, index_item_pss], 
                                      function(x) {gsub(".*aproape niciodată.*", "1", x)}), stringsAsFactors = FALSE)
behav_pre[, index_item_pss] <- data.frame(lapply(behav_pre[, index_item_pss], 
                                      function(x) {gsub(".*uneori.*", "2", x)}), stringsAsFactors = FALSE)
behav_pre[, index_item_pss] <- data.frame(lapply(behav_pre[, index_item_pss], 
                                      function(x) {gsub(".*destul de des.*", "3", x)}), stringsAsFactors = FALSE)
behav_pre[, index_item_pss] <- data.frame(lapply(behav_pre[, index_item_pss], 
                                      function(x) {gsub(".*foarte des.*", "4", x)}), stringsAsFactors = FALSE)

behav_post[, index_item_pss] <- data.frame(lapply(behav_post[, index_item_pss], 
                                                    function(x) {gsub(".*niciodată.*", "0", x)}), stringsAsFactors = FALSE)
behav_post[, index_item_pss] <- data.frame(lapply(behav_post[, index_item_pss], 
                                                    function(x) {gsub(".*aproape niciodată.*", "1", x)}), stringsAsFactors = FALSE)
behav_post[, index_item_pss] <- data.frame(lapply(behav_post[, index_item_pss], 
                                                    function(x) {gsub(".*uneori.*", "2", x)}), stringsAsFactors = FALSE)
behav_post[, index_item_pss] <- data.frame(lapply(behav_post[, index_item_pss], 
                                                    function(x) {gsub(".*destul de des.*", "3", x)}), stringsAsFactors = FALSE)
behav_post[, index_item_pss] <- data.frame(lapply(behav_post[, index_item_pss], 
                                                    function(x) {gsub(".*foarte des.*", "4", x)}), stringsAsFactors = FALSE)

# Score
behav_pre[, index_item_pss] <- colstonumeric(behav_pre[, index_item_pss])
behav_post[, index_item_pss] <- colstonumeric(behav_post[, index_item_pss])

behav_pre[, index_item_pss][index_item_revPSS] <- ReverseCode(behav_pre[, index_item_pss][index_item_revPSS], tonumeric = FALSE, min = 0, max = 4)
behav_post[, index_item_pss][index_item_revPSS] <- ReverseCode(behav_post[, index_item_pss][index_item_revPSS], tonumeric = FALSE, min = 0, max = 4)

behav_pre$PSS_Total <- ScoreLikert(behav_pre[, index_item_pss], napercent = .11)
behav_post$PSS_Total <- ScoreLikert(behav_post[, index_item_pss], napercent = .11)



## PS int
index_item_PSint <- 45:48    # 45:55
colnames(behav_pre)[index_item_PSint] <- sprintf("PSint_%d", 1:4)
colnames(behav_post)[index_item_PSint] <- sprintf("PSint_%d", 1:4)


behav_pre[, sprintf("PSint_%d", 1:4)] <-
  behav_pre[, sprintf("PSint_%d", 1:4)] %>%
    dplyr::mutate_all(readr::parse_number)


behav_post[, sprintf("PSint_%d", 1:4)] <-
  behav_post[, sprintf("PSint_%d", 1:4)] %>%
    dplyr::mutate_all(readr::parse_number)


# Score
behav_pre$PSint_Total <- ScoreLikert(behav_pre[, index_item_PSint], tonumeric = TRUE, napercent = .33)
behav_post$PSint_Total <- ScoreLikert(behav_post[, index_item_PSint], tonumeric = TRUE, napercent = .33)



## PS mot
index_item_PSmot <- 49:52      
colnames(behav_pre)[index_item_PSmot] <- sprintf("PSmot_%d", 1:4)
colnames(behav_post)[index_item_PSmot] <- sprintf("PSmot_%d", 1:4)


behav_pre[, sprintf("PSmot_%d", 1:4)] <-
  behav_pre[, sprintf("PSmot_%d", 1:4)] %>%
    dplyr::mutate_all(~case_when(stringr::str_detect(., "dezacord puternic") ~ 1,
                                 stringr::str_detect(., "dezacord") ~ 2,
                                 stringr::str_detect(., "neutru") ~ 3,
                                 stringr::str_detect(., "acord") ~ 4,
                                 stringr::str_detect(., "acord puternic") ~ 5,
                                TRUE ~ NA_real_))


behav_post[, sprintf("PSmot_%d", 1:4)] <-
  behav_post[, sprintf("PSmot_%d", 1:4)] %>%
    dplyr::mutate_all(~case_when(stringr::str_detect(., "dezacord puternic") ~ 1,
                               stringr::str_detect(., "dezacord") ~ 2,
                               stringr::str_detect(., "neutru") ~ 3,
                               stringr::str_detect(., "acord") ~ 4,
                               stringr::str_detect(., "acord puternic") ~ 5,
                              TRUE ~ NA_real_))


# Score
behav_pre$PSmot_Total <- ScoreLikert(behav_pre[, index_item_PSmot], tonumeric = TRUE, napercent = .33)
behav_post$PSmot_Total <- ScoreLikert(behav_post[, index_item_PSmot], tonumeric = TRUE, napercent = .33)



## PS iden
index_item_PSiden <- 53:55     
colnames(behav_pre)[index_item_PSiden] <- sprintf("PSiden_%d", 1:3)
colnames(behav_post)[index_item_PSiden] <- sprintf("PSiden_%d", 1:3)


behav_pre[, sprintf("PSiden_%d", 1:3)] <-
  behav_pre[, sprintf("PSiden_%d", 1:3)] %>%
  dplyr::mutate_all(~case_when(stringr::str_detect(., "dezacord puternic") ~ 1,
                               stringr::str_detect(., "dezacord") ~ 2,
                               stringr::str_detect(., "neutru") ~ 3,
                               stringr::str_detect(., "acord") ~ 4,
                               stringr::str_detect(., "acord puternic") ~ 5,
                               TRUE ~ NA_real_))


behav_post[, sprintf("PSiden_%d", 1:3)] <-
  behav_post[, sprintf("PSiden_%d", 1:3)] %>%
  dplyr::mutate_all(~case_when(stringr::str_detect(., "dezacord puternic") ~ 1,
                               stringr::str_detect(., "dezacord") ~ 2,
                               stringr::str_detect(., "neutru") ~ 3,
                               stringr::str_detect(., "acord") ~ 4,
                               stringr::str_detect(., "acord puternic") ~ 5,
                               TRUE ~ NA_real_))


# Score
behav_pre$PSiden_Total <- ScoreLikert(behav_pre[, index_item_PSiden], tonumeric = TRUE, napercent = .33)
behav_post$PSiden_Total <- ScoreLikert(behav_post[, index_item_PSiden], tonumeric = TRUE, napercent = .33)


## IOS
colnames(behav_pre)[56] <- "IOS"
colnames(behav_post)[56] <- "IOS"

behav_pre$IOS <- as.numeric(behav_pre$IOS)
behav_post$IOS <- as.numeric(behav_post$IOS) 



## Add some columns
behav_pre <- behav_pre %>%
  dplyr::mutate(PrePost = rep("Pre", nrow(.)))

behav_post <- behav_post %>%
  dplyr::mutate(PrePost = rep("Post", nrow(.)))

# Long format
behav_long <- dplyr::bind_rows(behav_pre, behav_post) %>%
  dplyr::mutate(PrePost = factor(PrePost, levels = c("Pre", "Post")))
# PSS
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  my_ggwithinstats2(x = PrePost, y = PSS_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Stress",
                   title = "CTRL")
Registered S3 methods overwritten by 'parameters':
  method                           from      
  as.double.parameters_kurtosis    datawizard
  as.double.parameters_skewness    datawizard
  as.double.parameters_smoothness  datawizard
  as.numeric.parameters_kurtosis   datawizard
  as.numeric.parameters_skewness   datawizard
  as.numeric.parameters_smoothness datawizard
  print.parameters_distribution    datawizard
  print.parameters_kurtosis        datawizard
  print.parameters_skewness        datawizard
  summary.parameters_kurtosis      datawizard
  summary.parameters_skewness      datawizard
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  my_ggwithinstats2(x = PrePost, y = PSS_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Stress",
                   title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# NA
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  my_ggwithinstats2(x = PrePost, y = NA_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Negative Affect",
                   title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  my_ggwithinstats2(x = PrePost, y = NA_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Negative Affect",
                   title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# PA
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  my_ggwithinstats2(x = PrePost, y = PA_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Positive Affect",
                   title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  my_ggwithinstats2(x = PrePost, y = PA_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Positive Affect",
                   title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# Psint
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  my_ggwithinstats2(x = PrePost, y = PSint_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Prosocial intention",
                   title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  my_ggwithinstats2(x = PrePost, y = PSint_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Prosocial intention",
                   title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# Psmot
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  my_ggwithinstats2(x = PrePost, y = PSint_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Prosocial motivation",
                   title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  my_ggwithinstats2(x = PrePost, y = PSint_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Prosocial motivation",
                   title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# IOS
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  my_ggwithinstats2(x = PrePost, y = IOS, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Closeness",
                   title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  my_ggwithinstats2(x = PrePost, y = IOS, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Closeness",
                   title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

2.2 VAS Stress

folder <- "C:/Users/Mihai/Desktop/R Notebooks/notebooks/PA4-geronto"
file_pre <- "date VAS STRES PRE varstnici - modif.xls"
file_post <- "date VAS STRES POST varstnici.xls"

stres_pre <- rio::import(file.path(folder, file_pre))
stres_pre <- stres_pre[-1, c(3:5, 10:11)]

stres_pre <- stres_pre[-37,]  # Sofi notebook: on 31-07 id 19 wanted 0 but put 25 ... he has two recodings with 25 and 0 ... delete the one with 25
#stres_pre <- stres_pre[-122,]   # no data
names(stres_pre)[4:5] <- c("id", "vas_stres")
stres_pre[stres_pre$id == "EN08PA1",]$id <- "EU08PA1"    # typo "EN_08", should be "EU_08"
stres_pre <- stres_pre %>% 
  janitor::clean_names() %>%
  dplyr::mutate(id = stringr::str_remove(id, "PA1"),
                id = gsub('^(.{2})(.*)$', '\\1_\\2', id)) %>%        # insert "_" after code
  tidyr::separate(id, into = c("forma", "ID_no"), remove = FALSE, sep = "_") %>%
  dplyr::mutate(forma = gsub('^(.{1})(.*)$', '\\1_\\2', id)) %>%
  tidyr::separate(forma, into = c("Cond", "Cog_imp"), remove = FALSE, sep = "_") %>%
  dplyr::mutate(Cond = dplyr::case_when(Cond == "C" ~ "CTRL",
                                        Cond == "E" ~ "TR",
                                        TRUE ~ NA_character_)) %>%
  dplyr::mutate(vas_stres = as.numeric(vas_stres)) %>%
  dplyr::mutate(id = stringr::str_replace(id, "O", "0"),
                id = stringr::str_replace(id, "o", "0")) %>%
  dplyr::mutate(ID_no = stringr::str_replace(ID_no, "O", "0"),
                ID_no = stringr::str_replace(ID_no, "o", "0"),
                ID_no = as.numeric(ID_no))


stres_post <- rio::import(file.path(folder, file_post))
stres_post <- stres_post[-1, c(3:5, 10:11)]
names(stres_post)[4:5] <- c("id", "vas_stres")
stres_post[stres_post$id == "CN12PA1",]$id <- "CU12PA1"    # typo "CN_12", should be "CU_12"
stres_post <- stres_post %>% 
  janitor::clean_names() %>%
  dplyr::mutate(id = stringr::str_remove(id, "PA1"),
                id = gsub('^(.{2})(.*)$', '\\1_\\2', id)) %>%        # insert "_" after code
  tidyr::separate(id, into = c("forma", "ID_no"), remove = FALSE, sep = "_") %>%
  dplyr::mutate(forma = gsub('^(.{1})(.*)$', '\\1_\\2', id)) %>%
  tidyr::separate(forma, into = c("Cond", "Cog_imp"), remove = FALSE, sep = "_") %>%
  dplyr::mutate(Cond = dplyr::case_when(Cond == "C" ~ "CTRL",
                                        Cond == "E" ~ "TR",
                                        TRUE ~ NA_character_)) %>%
  dplyr::mutate(vas_stres = as.numeric(vas_stres)) %>%
  dplyr::mutate(id = stringr::str_replace(id, "O", "0"),
                id = stringr::str_replace(id, "o", "0")) %>%
  dplyr::mutate(ID_no = stringr::str_replace(ID_no, "O", "0"),
                ID_no = stringr::str_replace(ID_no, "o", "0"),
                ID_no = as.numeric(ID_no))

  

# retrasi
retrasi_post <- c(1, 6, 7)

# check
stres_pre %>%
  dplyr::count(id) %>%
  dplyr::pull(id) -> stres_pre_ids
setdiff(stres_pre_ids, behav_pre_ids)   
stres_post %>%
  dplyr::count(id) %>%
  dplyr::pull(id) -> stres_post_ids
setdiff(stres_post_ids, behav_pre_ids)  
setdiff(stres_pre_ids, stres_post_ids)
# Add variable Time
# its: pre-post x4 + pre-post-post => pre = 1,3,5,7,9  post = 2,4,6,8,10,11
# in pre EN_19 have 6 instead of 5 data -- fixed now; EN_04 fixed in excel file

stres_pre_time <- 
  stres_pre %>%
  dplyr::mutate(row_numb = dplyr::row_number()) %>%
  dplyr::arrange(desc(row_numb)) %>%                     # order of rows needs to be inverted to be in chronological order
  dplyr::select(-row_numb) %>%
  dplyr::group_by(id) %>%
  dplyr::mutate(Time = dplyr::row_number()) %>%
  dplyr::mutate(Time = dplyr::case_when(Cond == "CTRL" & Time == 1 ~ 9,
                                        Cond == "TR" & Time == 1 ~ 1,
                                        Cond == "TR" & Time == 2 ~ 3,
                                        Cond == "TR" & Time == 3 ~ 5,
                                        Cond == "TR" & Time == 4 ~ 7,
                                        Cond == "TR" & Time == 5 ~ 9,
                                        TRUE ~ NA_real_)) %>%
  dplyr::ungroup()                    

stres_post_time <- 
  stres_post %>%
  tidyr::drop_na(vas_stres) %>%                      # there is one NA that ruins the flow
  dplyr::mutate(row_numb = dplyr::row_number()) %>%
  dplyr::arrange(desc(row_numb)) %>%                     # order of rows needs to be inverted to be in chronological order
  dplyr::select(-row_numb) %>%
  dplyr::group_by(id) %>%
  dplyr::mutate(Time = dplyr::row_number()) %>%
  dplyr::mutate(Time = dplyr::case_when(Cond == "CTRL" & Time == 1 ~ 10,
                                        Cond == "CTRL" & Time == 2 ~ 11,
                                        Cond == "TR" & Time == 1 ~ 2,
                                        Cond == "TR" & Time == 2 ~ 4,
                                        Cond == "TR" & Time == 3 ~ 6,
                                        Cond == "TR" & Time == 4 ~ 8,
                                        Cond == "TR" & Time == 5 ~ 10,
                                        Cond == "TR" & Time == 6 ~ 11,
                                        TRUE ~ NA_real_)) %>%
  dplyr::ungroup()


# check
stres_pre_time %>%
  dplyr::group_by(id) %>%
  filter(Time == max(Time)) %>% 
  print(n = Inf)               # all are 1 and 9 -- good

stres_post_time %>%
  dplyr::group_by(id) %>%
  filter(Time == max(Time)) %>% 
  print(n = Inf)              # all are 11 -- good because last post is same in TR and CTRL

# Long data
stres_time_long <- dplyr::bind_rows(stres_pre_time, stres_post_time) %>%
  dplyr::mutate(Time = factor(Time, levels = c(1:11)))

2.2.1 CTRL

stres_time_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  ggstatsplot::ggwithinstats(x = Time, y = vas_stres, outlier.label = id, 
                type = "np")

2.2.2 TR

stres_time_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Time %in% c(9, 10, 11)) %>%
  ggstatsplot::ggwithinstats(x = Time, y = vas_stres, outlier.label = id, 
                type = "np")

stres_time_long %>%
  dplyr::filter(Cond == "TR") %>%
  ggstatsplot::ggwithinstats(x = Time, y = vas_stres, outlier.label = id, 
                type = "np")
Warning: Number of labels is greater than default palette color count.
 Try using another color `palette` (and/or `package`).

stres_time_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(!Time %in% c(9, 10, 11)) %>%
  ggstatsplot::ggwithinstats(x = Time, y = vas_stres, outlier.label = id, 
                type = "np")

2.3 Only for Normal Cognition

# deficienta cognitiva (N-normal, U-usor deficit cognitiv)

# PSS
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  dplyr::filter(Cog_imp == "N") %>%
  my_ggwithinstats2(x = PrePost, y = PSS_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Stress",
                   title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Cog_imp == "N") %>%
  my_ggwithinstats2(x = PrePost, y = PSS_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Stress",
                   title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# NA
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  dplyr::filter(Cog_imp == "N") %>%
  my_ggwithinstats2(x = PrePost, y = NA_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Negative Affect",
                   title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Cog_imp == "N") %>%
  my_ggwithinstats2(x = PrePost, y = NA_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Negative Affect",
                   title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# PA
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  dplyr::filter(Cog_imp == "N") %>%
  my_ggwithinstats2(x = PrePost, y = PA_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Positive Affect",
                   title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Cog_imp == "N") %>%
  my_ggwithinstats2(x = PrePost, y = PA_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Positive Affect",
                   title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# Psint
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  dplyr::filter(Cog_imp == "N") %>%
  my_ggwithinstats2(x = PrePost, y = PSint_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Prosocial intention",
                   title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Cog_imp == "N") %>%
  my_ggwithinstats2(x = PrePost, y = PSint_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Prosocial intention",
                   title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# Psmot
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  dplyr::filter(Cog_imp == "N") %>%
  my_ggwithinstats2(x = PrePost, y = PSint_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Prosocial motivation",
                   title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Cog_imp == "N") %>%
  my_ggwithinstats2(x = PrePost, y = PSint_Total, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Prosocial motivation",
                   title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# IOS
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  dplyr::filter(Cog_imp == "N") %>%
  my_ggwithinstats2(x = PrePost, y = IOS, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Closeness",
                   title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Cog_imp == "N") %>%
  my_ggwithinstats2(x = PrePost, y = IOS, outlier.label = ID_no, type = "np", 
                   xlab = "", ylab = "Closeness",
                   title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

2.4 Only for Light Cognitive Deficit

# deficienta cognitiva (N-normal, U-usor deficit cognitiv)

# PSS
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  dplyr::filter(Cog_imp == "U") %>%
  my_ggwithinstats2(x = PrePost, y = PSS_Total, outlier.label = ID_no, type = "np", 
                    xlab = "", ylab = "Stress",
                    title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Cog_imp == "U") %>%
  my_ggwithinstats2(x = PrePost, y = PSS_Total, outlier.label = ID_no, type = "np", 
                    xlab = "", ylab = "Stress",
                    title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# NA
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  dplyr::filter(Cog_imp == "U") %>%
  my_ggwithinstats2(x = PrePost, y = NA_Total, outlier.label = ID_no, type = "np", 
                    xlab = "", ylab = "Negative Affect",
                    title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Cog_imp == "U") %>%
  my_ggwithinstats2(x = PrePost, y = NA_Total, outlier.label = ID_no, type = "np", 
                    xlab = "", ylab = "Negative Affect",
                    title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# PA
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  dplyr::filter(Cog_imp == "U") %>%
  my_ggwithinstats2(x = PrePost, y = PA_Total, outlier.label = ID_no, type = "np", 
                    xlab = "", ylab = "Positive Affect",
                    title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Cog_imp == "U") %>%
  my_ggwithinstats2(x = PrePost, y = PA_Total, outlier.label = ID_no, type = "np", 
                    xlab = "", ylab = "Positive Affect",
                    title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# Psint
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  dplyr::filter(Cog_imp == "U") %>%
  my_ggwithinstats2(x = PrePost, y = PSint_Total, outlier.label = ID_no, type = "np", 
                    xlab = "", ylab = "Prosocial intention",
                    title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Cog_imp == "U") %>%
  my_ggwithinstats2(x = PrePost, y = PSint_Total, outlier.label = ID_no, type = "np", 
                    xlab = "", ylab = "Prosocial intention",
                    title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# Psmot
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  dplyr::filter(Cog_imp == "U") %>%
  my_ggwithinstats2(x = PrePost, y = PSint_Total, outlier.label = ID_no, type = "np", 
                    xlab = "", ylab = "Prosocial motivation",
                    title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Cog_imp == "U") %>%
  my_ggwithinstats2(x = PrePost, y = PSint_Total, outlier.label = ID_no, type = "np", 
                    xlab = "", ylab = "Prosocial motivation",
                    title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

# IOS
behav_long %>%
  dplyr::filter(Cond == "CTRL") %>%
  dplyr::filter(Cog_imp == "U") %>%
  my_ggwithinstats2(x = PrePost, y = IOS, outlier.label = ID_no, type = "np", 
                    xlab = "", ylab = "Closeness",
                    title = "CTRL")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

behav_long %>%
  dplyr::filter(Cond == "TR") %>%
  dplyr::filter(Cog_imp == "U") %>%
  my_ggwithinstats2(x = PrePost, y = IOS, outlier.label = ID_no, type = "np", 
                    xlab = "", ylab = "Closeness",
                    title = "TR")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

3 Test VAS Stress differences in response to Bucharest Stress Task

3.1 see Brunner et al. (2002)

# experiment has the F1-LD-F1 designstructure with treatment being the whole-plot factor. (p. 13 art R Journal)

stres_f1ldf1 <- 
  stres_time_long %>%
    dplyr::filter(Time %in% c(9, 10, 11)) %>%
    dplyr::mutate(Time = factor(Time, levels = c(9, 10, 11))) 

nparLD::f1.ld.f1(y = stres_f1ldf1$vas_stres, time = stres_f1ldf1$Time, group = stres_f1ldf1$Cond, subject = stres_f1ldf1$id)

Attaching package: ‘MASS’

The following object is masked from ‘package:rstatix’:

    select

The following object is masked from ‘package:dplyr’:

    select
 Total number of observations:  120 
 Total number of subjects:   40 
 Total number of missing observations:  0 

 Class level information 
 ----------------------- 
 Levels of Time (sub-plot factor time) :  3 
 Levels of Group (whole-plot factor group) :  2 

 Abbreviations 
 ----------------------- 
 RankMeans = Rank means
 Nobs = Number of observations
 RTE = Relative treatment effect
 case2x2 = tests for 2-by-2 design
 Wald.test = Wald-type test statistic
 ANOVA.test = ANOVA-type test statistic with Box approximation
 ANOVA.test.mod.Box = modified ANOVA-type test statistic with Box approximation
 Wald.test.time = Wald-type test statistic for simple time effect
 ANOVA.test.time = ANOVA-type test statistic for simple time effect
 N = Standard Normal Distribution N(0,1)
 T = Student's T distribution with respective degrees of freedom
 pattern.time (time effects) = Test against patterned alternatives in time using normal distribution ( no pattern specified ) 
 pair.comparison = Tests for pairwise comparisions (without specifying a pattern) 
 pattern.pair.comparison = Test for pairwise comparisons with patterned alternatives in time ( no pattern specified ) 
 pattern.group (group effects) = Test against patterned alternatives in group ( no pattern specified ) 
 covariance = Covariance matrix 
 Note: The description output above will disappear by setting description=FALSE in the input. See the help file for details. 

 F1 LD F1 Model 
 ----------------------- 
 Check that the order of the time and group levels are correct.
 Time level:   9 10 11 
 Group level:   CTRL TR 
 If the order is not correct, specify the correct order in time.order or group.order.

$RTE

$case2x2
NULL

$Wald.test
             Statistic df          p-value
Group       0.11896719  1 0.73015736878659
Time       34.63043649  2 0.00000003020621
Group:Time  0.00187216  2 0.99906435792943

$ANOVA.test
              Statistic      df         p-value
Group       0.118967187 1.00000 0.7301573687866
Time       14.613795919 1.86256 0.0000009784007
Group:Time  0.001182357 1.86256 0.9981935278646

$ANOVA.test.mod.Box
      Statistic df1      df2   p-value
Group 0.1189672   1 37.99886 0.7320593

$Wald.test.time

$ANOVA.test.time

$pattern.time
NULL

$pair.comparison

$pattern.pair.comparison
NULL

$covariance
NULL

$model.name
[1] "F1 LD F1 Model"


4 Session Info

R version 4.1.0 (2021-05-18)
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    
system code page: 1252

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

other attached packages:
 [1] MASS_7.3-54                rio_0.5.27                 scales_1.1.1               ggpubr_0.4.0               summarytools_1.0.0        
 [6] rstatix_0.7.0              broom_0.7.9                PerformanceAnalytics_2.0.4 xts_0.12.1                 zoo_1.8-9                 
[11] psych_2.1.6                plyr_1.8.6                 forcats_0.5.1              stringr_1.4.0              dplyr_1.0.7               
[16] purrr_0.3.4                readr_2.0.1                tidyr_1.1.3                tibble_3.1.4               ggplot2_3.3.5             
[21] tidyverse_1.3.1            papaja_0.1.0.9997          pacman_0.5.1              

loaded via a namespace (and not attached):
  [1] readxl_1.3.1              pairwiseComparisons_3.1.6 backports_1.2.1           splines_4.1.0             gmp_0.6-2                
  [6] kSamples_1.2-9            ipmisc_6.0.2              TH.data_1.0-10            pryr_0.1.5                digest_0.6.28            
 [11] SuppDists_1.1-9.5         htmltools_0.5.2           magick_2.7.3              fansi_0.5.0               magrittr_2.0.1           
 [16] checkmate_2.0.0           memoise_2.0.0             paletteer_1.4.0           tzdb_0.1.2                openxlsx_4.2.4           
 [21] modelr_0.1.8              matrixStats_0.60.1        sandwich_3.0-1            colorspace_2.0-2          rvest_1.0.1              
 [26] ggrepel_0.9.1             haven_2.4.3               xfun_0.25                 prismatic_1.0.0           tcltk_4.1.0              
 [31] crayon_1.4.1              jsonlite_1.7.2            zeallot_0.1.0             survival_3.2-13           glue_1.4.2               
 [36] gtable_0.3.0              emmeans_1.6.3             MatrixModels_0.5-0        statsExpressions_1.1.0    car_3.0-11               
 [41] Rmpfr_0.8-4               abind_1.4-5               rapportools_1.0           mvtnorm_1.1-2             DBI_1.1.1                
 [46] PMCMRplus_1.9.0           Rcpp_1.0.7                performance_0.7.3         xtable_1.8-4              tmvnsim_1.0-2            
 [51] foreign_0.8-81            datawizard_0.2.0.1        httr_1.4.2                ellipsis_0.3.2            farver_2.1.0             
 [56] pkgconfig_2.0.3           reshape_0.8.8             multcompView_0.1-8        dbplyr_2.1.1              utf8_1.2.2               
 [61] janitor_2.1.0             labeling_0.4.2            effectsize_0.4.5          tidyselect_1.1.1          rlang_0.4.11             
 [66] munsell_0.5.0             cellranger_1.1.0          tools_4.1.0               cachem_1.0.6              ggprism_1.0.3            
 [71] cli_3.0.1                 generics_0.1.0            fastmap_1.1.0             BWStest_0.2.2             rematch2_2.1.2           
 [76] knitr_1.33                fs_1.5.0                  zip_2.2.0                 pander_0.6.4              WRS2_1.1-3               
 [81] pbapply_1.4-3             nlme_3.1-152              xml2_1.3.2                correlation_0.7.0         compiler_4.1.0           
 [86] rstudioapi_0.13           curl_4.3.2                ggsignif_0.6.2            reprex_2.0.1              stringi_1.7.4            
 [91] parameters_0.14.0         lattice_0.20-44           Matrix_1.3-4              vctrs_0.3.8               pillar_1.6.3             
 [96] lifecycle_1.0.1           mc2d_0.1-21               BiocManager_1.30.16       estimability_1.3          data.table_1.14.0        
[101] insight_0.14.4            patchwork_1.1.1           R6_2.5.1                  BayesFactor_0.9.12-4.2    codetools_0.2-18         
[106] boot_1.3-28               gtools_3.9.2              assertthat_0.2.1          nparLD_2.1                withr_2.4.2              
[111] mnormt_2.0.2              multcomp_1.4-17           bayestestR_0.11.0         parallel_4.1.0            hms_1.1.0                
[116] quadprog_1.5-8            grid_4.1.0                coda_0.19-4               snakecase_0.11.0          carData_3.0-4            
[121] lubridate_1.7.10          base64enc_0.1-3           ggstatsplot_0.8.0        
 

A work by Claudiu Papasteri

 

LS0tDQp0aXRsZTogIjxicj4gUEE0IFJlcG9ydCAtIEdlcmlhdHJpYyIgDQpzdWJ0aXRsZTogIkluaXRpYWwgQW5hbHlzaXMiDQphdXRob3I6ICI8YnI+IENsYXVkaXUgUGFwYXN0ZXJpIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJW0gJVknKWAiDQpvdXRwdXQ6IA0KICAgIGh0bWxfbm90ZWJvb2s6DQogICAgICAgICAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICAgICAgICAgIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICAgICAgICAgIHRoZW1lOiBzcGFjZWxhYg0KICAgICAgICAgICAgaGlnaGxpZ2h0OiB0YW5nbw0KICAgICAgICAgICAgZm9udC1mYW1pbHk6IEFyaWFsDQogICAgICAgICAgICBmaWdfd2lkdGg6IDEwDQogICAgICAgICAgICBmaWdfaGVpZ2h0OiA5DQogICAgIyBwZGZfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgIyB0b2M6IHRydWUNCiAgICAgICAgICAgICMgIHRvY19kZXB0aDogMg0KICAgICAgICAgICAgIyAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgICAgICAgICAjIGZvbnRzaXplOiAxMXB0DQogICAgICAgICAgICAjIGdlb21ldHJ5OiBtYXJnaW49MWluDQogICAgICAgICAgICAjIGZpZ193aWR0aDogNw0KICAgICAgICAgICAgIyBmaWdfaGVpZ2h0OiA2DQogICAgICAgICAgICAjIGZpZ19jYXB0aW9uOiB0cnVlDQogICAgIyBnaXRodWJfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgIyB0b2M6IHRydWUNCiAgICAgICAgICAgICMgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICAjIGh0bWxfcHJldmlldzogZmFsc2UNCiAgICAgICAgICAgICMgZmlnX3dpZHRoOiA1DQogICAgICAgICAgICAjIGZpZ19oZWlnaHQ6IDUNCiAgICAgICAgICAgICMgZGV2OiBqcGVnDQotLS0NCg0KDQo8IS0tIFNldHVwIC0tPg0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBraW50ciBvcHRpb25zDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIGNvbW1lbnQgPSAiIyIsDQogIGNvbGxhcHNlID0gVFJVRSwNCiAgZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IFRSVUUsIGNhY2hlID0gVFJVRSAgICAgICAjIGVjaG8gPSBGYWxzZSBmb3IgZ2l0aHViX2RvY3VtZW50LCBidXQgd2lsbCBiZSBmb2xkZWQgaW4gaHRtbF9ub3RlYm9vaw0KKQ0KDQojIEdlbmVyYWwgUiBvcHRpb25zIGFuZCBpbmZvDQpzZXQuc2VlZCgxMTEpICAgICAgICAgICAgICAgIyBpbiBjYXNlIHdlIHVzZSByYW5kb21pemVkIHByb2NlZHVyZXMgICAgICAgDQpvcHRpb25zKHNjaXBlbiA9IDk5OSkgICAgICAgIyBwb3NpdGl2ZSB2YWx1ZXMgYmlhcyB0b3dhcmRzIGZpeGVkIGFuZCBuZWdhdGl2ZSB0b3dhcmRzIHNjaWVudGlmaWMgbm90YXRpb24NCg0KIyBMb2FkIHBhY2thZ2VzDQppZiAoIXJlcXVpcmUoInBhY21hbiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KcGFja2FnZXMgPC0gYygNCiAgInBhcGFqYSIsDQogICJ0aWR5dmVyc2UiLCAicGx5ciIsICAgICAgDQogICJwc3ljaCIsICJQZXJmb3JtYW5jZUFuYWx5dGljcyIsICAgICAgICAgIA0KICAiYnJvb20iLCAicnN0YXRpeCIsDQogICJzdW1tYXJ5dG9vbHMiLCAidGFkYWF0b29sYm94IiwgICAgICAgICAgIA0KICAiZ2dwbG90MiIsICJnZ3B1YnIiLCAic2NhbGVzIiwgICAgICAgIA0KICAicmlvIg0KICAjICwgLi4uDQopDQppZiAoIXJlcXVpcmUoInBhY21hbiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KcGFjbWFuOjpwX2xvYWQoY2hhciA9IHBhY2thZ2VzKQ0KDQojIFRoZW1lcyBmb3IgZ2dwbG90MiBwbG90aW5nIChoZXJlIHVzZWQgQVBBIHN0eWxlKQ0KdGhlbWVfc2V0KHRoZW1lX2FwYSgpKQ0KYGBgDQoNCg0KDQoNCg0KPCEtLSBSZXBvcnQgLS0+DQoNCiMgRGVmaW5lIHNjb3JpbmcgZnVuY3Rpb25zDQoNCmBgYHtyIGRlZl9mdW5jfQ0KIyMgRGVmaW5lIGZ1bmN0aW9uIHRoYXQgcmVjb2RlcyB0byBudW1lcmljLCBidXQgd2F0Y2hlcyBvdXQgdG8gY29lcmNpb24gdG8gbm90IGludHJvZHVjZSBOQXMNCmNvbHN0b251bWVyaWMgPC0gZnVuY3Rpb24oZGYpew0KICB0cnlDYXRjaCh7DQogICAgZGZfbnVtIDwtIGFzLmRhdGEuZnJhbWUoDQogICAgICBsYXBwbHkoZGYsDQogICAgICAgICAgICAgZnVuY3Rpb24oeCkgeyBhcy5udW1lcmljKGFzLmNoYXJhY3Rlcih4KSl9KSkgDQogIH0sd2FybmluZyA9IGZ1bmN0aW9uKHN0b3Bfb25fd2FybmluZykgew0KICAgIG1lc3NhZ2UoIlN0b3BlZCB0aGUgZXhlY3V0aW9uIG9mIG51bWVyaWMgY29udmVyc2lvbjogIiwgY29uZGl0aW9uTWVzc2FnZShzdG9wX29uX3dhcm5pbmcpKQ0KICB9KSANCn0NCiMjDQojIyBEZWZpbmUgZnVuY3Rpb24gdGhhdCByZXZlcnNlIGNvZGVzIGl0ZW1zDQpSZXZlcnNlQ29kZSA8LSBmdW5jdGlvbihkZiwgdG9udW1lcmljID0gRkFMU0UsIG1pbiA9IE5VTEwsIG1heCA9IE5VTEwpIHsNCiAgaWYodG9udW1lcmljKSBkZiA8LSBjb2xzdG9udW1lcmljKGRmKQ0KICBkZiA8LSAobWF4ICsgbWluKSAtIGRmDQp9DQojIw0KIyMgRGVmaW5lIGZ1bmN0aW9uIHRoYXQgc2NvcmVzIG9ubHkgcm93cyB3aXRoIGxlc3MgdGhhbiAxMCUgTkFzIChyZXR1cm5zIE5BIGlmIGFsbCBvciBhYm92ZSB0aHJlc2hvbGQgcGVyY2VudGFnZSBvZiByb3dzIGFyZSBOQSk7IGNhbiByZXZlcnNlIGNvZGUgaWYgdmVjdG9yIG9mIGNvbHVtbiBpbmRleGVzIGFuZCBtaW4sIG1heCBhcmUgcHJvdmlkZWQuDQpTY29yZUxpa2VydCA8LSBmdW5jdGlvbihkZiwgbmFwZXJjZW50ID0gLjEsIHRvbnVtZXJpYyA9IEZBTFNFLCByZXZlcnNlY29scyA9IE5VTEwsIG1pbiA9IE5VTEwsIG1heCA9IE5VTEwpIHsNCiAgcmV2ZXJzZV9saXN0IDwtIGxpc3QocmV2ZXJzZWNvbHMgPSByZXZlcnNlY29scywgbWluID0gbWluLCBtYXggPSBtYXgpDQogIHJldmVyc2VfY2hlY2sgPC0gIXNhcHBseShyZXZlcnNlX2xpc3QsIGlzLm51bGwpDQogIA0KICAjIFJlY29kZSB0byBudW1lcmljLCBidXQgd2F0Y2ggb3V0IHRvIGNvZXJjaW9uIHRvIG5vdCBpbnRyb2R1Y2UgTkFzDQogIGNvbHN0b251bWVyaWMgPC0gZnVuY3Rpb24oZGYpew0KICAgIHRyeUNhdGNoKHsNCiAgICAgIGRmX251bSA8LSBhcy5kYXRhLmZyYW1lKA0KICAgICAgICBsYXBwbHkoZGYsDQogICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7IGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHgpKX0pKSANCiAgICB9LHdhcm5pbmcgPSBmdW5jdGlvbihzdG9wX29uX3dhcm5pbmcpIHsNCiAgICAgIG1lc3NhZ2UoIlN0b3BlZCB0aGUgZXhlY3V0aW9uIG9mIG51bWVyaWMgY29udmVyc2lvbjogIiwgY29uZGl0aW9uTWVzc2FnZShzdG9wX29uX3dhcm5pbmcpKQ0KICAgIH0pIA0KICB9DQogIA0KICBpZih0b251bWVyaWMpIGRmIDwtIGNvbHN0b251bWVyaWMoZGYpDQogIA0KICBpZihhbGwocmV2ZXJzZV9jaGVjaykpew0KICAgIGRmWyAscmV2ZXJzZWNvbHNdIDwtIChtYXggKyBtaW4pIC0gZGZbICxyZXZlcnNlY29sc10NCiAgfWVsc2UgaWYoYW55KHJldmVyc2VfY2hlY2spKXsNCiAgICBzdG9wKCJJbnN1ZmljaWVudCBpbmZvIGZvciByZXZlcnNpbmcuIFBsZWFzZSBwcm92aWRlOiAiLCBwYXN0ZShuYW1lcyhyZXZlcnNlX2xpc3QpWyFyZXZlcnNlX2NoZWNrXSwgY29sbGFwc2UgPSAiLCAiKSkNCiAgfQ0KICANCiAgaWZlbHNlKHJvd1N1bXMoaXMubmEoZGYpKSA+IG5jb2woZGYpICogbmFwZXJjZW50LA0KICAgICAgICAgTkEsDQogICAgICAgICByb3dTdW1zKGRmLCBuYS5ybSA9IFRSVUUpICogTkEgXiAocm93U3VtcyghaXMubmEoZGYpKSA9PSAwKQ0KICApDQp9DQojIw0KYGBgDQoNCg0KDQojIFF1aWNrIGdnd2l0aGluc3RhdHMgZnVuY3Rpb24NCg0KYGBge3J9DQpteV9nZ3dpdGhpbnN0YXRzIDwtIGZ1bmN0aW9uKGRhdGEsIHRpdGxlLCB4LCB5LCBvdXRsaWVyLmxhYmVsLCB4bGFiLCB5bGFiKSB7DQogIHggPC0gcmxhbmc6OmVucXVvKHgpDQogIHkgPC0gcmxhbmc6OmVucXVvKHkpDQogIG91dGxpZXIubGFiZWwgPC0gcmxhbmc6OmVucXVvKG91dGxpZXIubGFiZWwpDQogIA0KICBkYXRhICU+JQ0KICAgIGdnc3RhdHNwbG90OjpnZ3dpdGhpbnN0YXRzKA0KICAgICAgeCA9ICEheCwNCiAgICAgIHkgPSAhIXksDQogICAgICB0aXRsZSA9IHRpdGxlLA0KICAgICAgeGxhYiA9IHhsYWIsDQogICAgICB5bGFiID0geWxhYiwNCiAgICAgIG91dGxpZXIudGFnZ2luZyA9IFRSVUUsICAgICAgICAgICAgIyB3aGV0aGVyIG91dGxpZXJzIG5lZWQgdG8gYmUgdGFnZ2VkDQogICAgICBvdXRsaWVyLmxhYmVsID0gISFvdXRsaWVyLmxhYmVsLCAgICMgdmFyaWFibGUgdG8gYmUgdXNlZCBmb3IgdGFnZ2luZyBvdXRsaWVycw0KICAgICAgb3V0bGllci5jb2VmID0gMiwNCiAgICAgIHBhaXJ3aXNlLmNvbXBhcmlzb25zID0gVFJVRSwNCiAgICAgIHBhaXJ3aXNlLmRpc3BsYXkgPSAic2lnbmlmaWNhbnQiLA0KICAgICAgcmVzdWx0cy5zdWJ0aXRsZSA9IFRSVUUsDQogICAgICB0eXBlID0gInBhcmFtZXRyaWMiLA0KICAgICAgYmYubWVzc2FnZSA9IEZBTFNFLCANCiAgICAgIHAuYWRqdXN0Lm1ldGhvZCA9ICJub25lIiwNCiAgICAgIHBvaW50LnBhdGggPSBUUlVFLA0KICAgICAgZ2d0aGVtZSA9IGdncHJpc206OnRoZW1lX3ByaXNtKCksDQogICAgICAjIHBhY2thZ2UgPSAiUkNvbG9yQnJld2VyIiwgICMgImdnc2NpIiwNCiAgICAgICMgcGFsZXR0ZSA9ICJEYXJrIiwgICAgICAgICAjICJkZWZhdWx0X2pjbyIsDQogICAgICB2aW9saW4uYXJncyA9IGxpc3Qod2lkdGggPSAwLjksIGFscGhhID0gMC4yLCBzaXplID0gMSwgY29sb3IgPSAiYmxhY2siKSwNCiAgICAgIGNlbnRyYWxpdHkucG9pbnQuYXJncyA9IGxpc3Qoc2l6ZSA9IDUsIGNvbG9yID0gImRhcmtyZWQiKSwNCiAgICAgIGNlbnRyYWxpdHkubGFiZWwuYXJncyA9IGxpc3Qoc2l6ZSA9IDMsIG51ZGdlX3ggPSAwLjIsIHNlZ21lbnQubGluZXR5cGUgPSA1LCBmaWxsID0gIiNGRkY4RTciKSwgDQogICAgICBnZ3Bsb3QuY29tcG9uZW50ID0gbGlzdCgNCiAgICAgICAgdGhlbWUoDQogICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAsIHNpemUgPSAxNiksDQogICAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAsIHNpemUgPSAxMiksIA0KICAgICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAsIHNpemUgPSAxMiksIA0KICAgICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KQ0KICAgICAgKSkNCiAgICApICsgc2NhbGVfY29sb3VyX2dyZXkoc3RhcnQgPSAwLjIsIGVuZCA9IDAuMikgICAjIGhhY2t5IHdheSB0byBjaGFuZ2UgcG9pbnQgY29sb3INCn0NCg0KIyBGb3IgcHVibGljYXRpb24NCm15X2dnd2l0aGluc3RhdHMyIDwtIGZ1bmN0aW9uKGRhdGEsIHRpdGxlLCB4LCB5LCBvdXRsaWVyLmxhYmVsLCB4bGFiLCB5bGFiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dGxpZXIudGFnZ2luZyA9IEZBTFNFLCByZXN1bHRzLnN1YnRpdGxlID0gVFJVRSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZW50cmFsaXR5LmxhYmVsLmFyZ3MgPSBUUlVFLCBwb2ludC5wYXRoID0gVFJVRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSAicGFyYW1ldHJpYyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uKSB7ICAjIC4uLiBmb3IgbGltaXRzIGFuZCBicmVha3MNCiAgeCA8LSBybGFuZzo6ZW5xdW8oeCkNCiAgeSA8LSBybGFuZzo6ZW5xdW8oeSkNCiAgb3V0bGllci5sYWJlbCA8LSBybGFuZzo6ZW5xdW8ob3V0bGllci5sYWJlbCkNCiAgDQogIGlmKGNlbnRyYWxpdHkubGFiZWwuYXJncyl7DQogICAgY2VudHJhbGl0eS5sYWJlbC5hcmdzIDwtIGxpc3Qoc2l6ZSA9IDMsIG51ZGdlX3ggPSAwLjIsIHNlZ21lbnQubGluZXR5cGUgPSA1LCBmaWxsID0gIiNGRkY4RTciKQ0KICB9ZWxzZXsNCiAgICBjZW50cmFsaXR5LmxhYmVsLmFyZ3MgPC0gbGlzdChzaXplID0gMCwgbnVkZ2VfeCA9IDEwLCBzZWdtZW50LmxpbmV0eXBlID0gMCwgYWxwaGEgPSAwKSAjIHZlcnkgaGFja3kgd2F5IG9mIG5vdCBzaG93aW5nIGxhYmVsDQogIH0NCiAgDQogIGRhdGEgJT4lDQogICAgZ2dzdGF0c3Bsb3Q6Omdnd2l0aGluc3RhdHMoDQogICAgICB4ID0gISF4LA0KICAgICAgeSA9ICEheSwNCiAgICAgIHRpdGxlID0gdGl0bGUsDQogICAgICB4bGFiID0geGxhYiwNCiAgICAgIHlsYWIgPSB5bGFiLA0KICAgICAgb3V0bGllci50YWdnaW5nID0gb3V0bGllci50YWdnaW5nLCAgICAgICAgICAgICAgICAgICAgIyB3aGV0aGVyIG91dGxpbmVzIG5lZWQgdG8gYmUgdGFnZ2VkDQogICAgICBvdXRsaWVyLmxhYmVsID0gISFvdXRsaWVyLmxhYmVsLCAgICAgICAgICAgICAgICAgICAgICAjIHZhcmlhYmxlIHRvIGJlIHVzZWQgZm9yIHRhZ2dpbmcgb3V0bGllcnMNCiAgICAgIG91dGxpZXIuY29lZiA9IDIsDQogICAgICBwYWlyd2lzZS5jb21wYXJpc29ucyA9IFRSVUUsDQogICAgICBwYWlyd2lzZS5kaXNwbGF5ID0gImFsbCIsDQogICAgICByZXN1bHRzLnN1YnRpdGxlID0gcmVzdWx0cy5zdWJ0aXRsZSwNCiAgICAgIHR5cGUgPSB0eXBlLA0KICAgICAgYmYubWVzc2FnZSA9IEZBTFNFLCANCiAgICAgIHAuYWRqdXN0Lm1ldGhvZCA9ICJub25lIiwNCiAgICAgIHBvaW50LnBhdGggPSBwb2ludC5wYXRoLA0KICAgICAgZ2d0aGVtZSA9IGdncHJpc206OnRoZW1lX3ByaXNtKCksDQogICAgICAjIHBhY2thZ2UgPSAiUkNvbG9yQnJld2VyIiwgICMgImdnc2NpIiwNCiAgICAgICMgcGFsZXR0ZSA9ICJEYXJrIiwgICAgICAgICAjICJkZWZhdWx0X2pjbyIsDQogICAgICB2aW9saW4uYXJncyA9IGxpc3Qod2lkdGggPSAwLjksIGFscGhhID0gMC4yLCBzaXplID0gMSwgY29sb3IgPSAiYmxhY2siKSwNCiAgICAgIGNlbnRyYWxpdHkucGxvdHRpbmcgPSBUUlVFLA0KICAgICAgY2VudHJhbGl0eS50eXBlID0gInBhcmFtZXRlcmljIiwNCiAgICAgIGNlbnRyYWxpdHkucG9pbnQuYXJncyA9IGxpc3Qoc2l6ZSA9IDUsIGNvbG9yID0gImRhcmtyZWQiKSwNCiAgICAgIGNlbnRyYWxpdHkubGFiZWwuYXJncyA9IGNlbnRyYWxpdHkubGFiZWwuYXJncywNCiAgICAgIGdncGxvdC5jb21wb25lbnQgPSBsaXN0KA0KICAgICAgICB0aGVtZSgNCiAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCwgc2l6ZSA9IDE2KSwNCiAgICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCwgc2l6ZSA9IDEyKSwgDQogICAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCwgc2l6ZSA9IDEyKSwgDQogICAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpDQogICAgICApKQ0KICAgICkgKyBzY2FsZV9jb2xvdXJfZ3JleShzdGFydCA9IDAuMiwgZW5kID0gMC4yKSArICAjIGhhY2t5IHdheSB0byBjaGFuZ2UgcG9pbnQgY29sb3INCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoLi4uKQ0KfQ0KDQojIEZhc3QgZ2dzYXZlIC0gc2F2ZXMgcGxvdCB3aXRoIGZpbGVuYW1lIG9mIFIgcGxvdCBvYmplY3QNCmZhc3RfZ2dzYXZlIDwtIGZ1bmN0aW9uKHBsb3QsIGRldmljZSA9ICJwbmciLCBwYXRoID0gTlVMTCwNCiAgICAgICAgICAgICAgICAgICAgICAgIHVuaXRzID0gImluIiwgZHBpID0gMzAwLCB3aWR0aCA9IDUsIGhlaWdodCA9IDUsIC4uLil7IA0KICBwbG90X25hbWUgPC0gZGVwYXJzZShzdWJzdGl0dXRlKHBsb3QpKQ0KICBnZ3Bsb3QyOjpnZ3NhdmUoZmlsZW5hbWUgPSBwYXN0ZTAocGxvdF9uYW1lLCAiLiIsIGRldmljZSksIHBsb3QgPSBwbG90LA0KICAgICAgICAgICAgICAgICAgZGV2aWNlID0gZGV2aWNlLCBwYXRoID0gcGF0aCwNCiAgICAgICAgICAgICAgICAgIHVuaXRzID0gdW5pdHMsIGRwaSA9IGRwaSwNCiAgICAgICAgICAgICAgICAgIHdpZHRoID0gd2lkdGgsIGhlaWdodCA9IGhlaWdodCwNCiAgICAgICAgICAgICAgICAgIC4uLg0KICApDQogIA0KfSAjIHVzZTogZmFzdF9nZ3NhdmUoanJhZF9veF9wLCBwYXRoID0gc2F2ZWZvbGRlcikNCmBgYA0KDQoNCg0KDQoNCiMjIEJlaGF2aW9yYWwgc2NhbGVzDQoNCmBgYHtyfQ0KZm9sZGVyIDwtICJDOi9Vc2Vycy9NaWhhaS9EZXNrdG9wL1IgTm90ZWJvb2tzL25vdGVib29rcy9QQTQtZ2Vyb250byINCmZpbGVfYmVoX3ByZSA8LSAiU2V0IHRlc3RlIHppIDEgcHJlIGdydXAgdsOicnN0bmljaS54bHN4Ig0KZmlsZV9iZWhfcG9zdCA8LSAiU2V0IHRlc3RlIHppIDUgcG9zdCBncnVwIHbDonJzdG5pY2kueGxzeCINCg0KDQojIyMgUHJlDQpiZWhhdl9wcmUgPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKGZvbGRlciwgZmlsZV9iZWhfcHJlKSkNCmJlaGF2X3ByZSA8LSBiZWhhdl9wcmVbLTEsXQ0KbmFtZXMoYmVoYXZfcHJlKVs2XSA8LSAiaWQiDQpiZWhhdl9wcmVbYmVoYXZfcHJlJGlkID09ICJDVTE2UEExIixdJGlkIDwtICJDTjE2UEExIiAgICAgIyB0eXBvLCBzaG91bGQgYmUgIkNOXzE2IiBpbnN0ZWFkIG9mICJDVS0xNiIgLS0gaW4gdmFzIGl0cyAiQ05fMTYiDQpiZWhhdl9wcmUgPC0gYmVoYXZfcHJlICU+JSANCiAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKSAlPiUNCiAgZHBseXI6Om11dGF0ZShpZCA9IHN0cmluZ3I6OnN0cl9yZW1vdmUoaWQsICJQQTEiKSwNCiAgICAgICAgICAgICAgICBpZCA9IGdzdWIoJ14oLnsyfSkoLiopJCcsICdcXDFfXFwyJywgaWQpKSAlPiUgICAgICAgICMgaW5zZXJ0ICJfIiBhZmV0ZXIgY29kZQ0KICB0aWR5cjo6c2VwYXJhdGUoaWQsIGludG8gPSBjKCJmb3JtYSIsICJJRF9ubyIpLCByZW1vdmUgPSBGQUxTRSwgc2VwID0gIl8iKSAlPiUNCiAgZHBseXI6Om11dGF0ZShmb3JtYSA9IGdzdWIoJ14oLnsxfSkoLiopJCcsICdcXDFfXFwyJywgaWQpKSAlPiUNCiAgdGlkeXI6OnNlcGFyYXRlKGZvcm1hLCBpbnRvID0gYygiQ29uZCIsICJDb2dfaW1wIiksIHJlbW92ZSA9IEZBTFNFLCBzZXAgPSAiXyIpICU+JQ0KICBkcGx5cjo6bXV0YXRlKENvbmQgPSBkcGx5cjo6Y2FzZV93aGVuKENvbmQgPT0gIkMiIH4gIkNUUkwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbmQgPT0gIkUiIH4gIlRSIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gTkFfY2hhcmFjdGVyXykpICU+JQ0KICBkcGx5cjo6bXV0YXRlKGlkID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoaWQsICJPIiwgIjAiKSwNCiAgICAgICAgICAgICAgICBpZCA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlKGlkLCAibyIsICIwIikpICU+JQ0KICBkcGx5cjo6bXV0YXRlKElEX25vID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoSURfbm8sICJPIiwgIjAiKSwNCiAgICAgICAgICAgICAgICBJRF9ubyA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlKElEX25vLCAibyIsICIwIiksDQogICAgICAgICAgICAgICAgSURfbm8gPSBhcy5udW1lcmljKElEX25vKSkNCg0KIyMgUG9zdA0KYmVoYXZfcG9zdCA8LSByaW86OmltcG9ydChmaWxlLnBhdGgoZm9sZGVyLCBmaWxlX2JlaF9wb3N0KSkNCmJlaGF2X3Bvc3QgPC0gYmVoYXZfcG9zdFstMSxdDQpiZWhhdl9wb3N0IDwtIGJlaGF2X3Bvc3RbLC1jKDY6OSldDQpuYW1lcyhiZWhhdl9wb3N0KVs2XSA8LSAiaWQiDQpiZWhhdl9wb3N0IDwtIGJlaGF2X3Bvc3QgJT4lIA0KICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpICU+JQ0KICBkcGx5cjo6bXV0YXRlKGlkID0gc3RyaW5ncjo6c3RyX3JlbW92ZShpZCwgIlBBMSIpLA0KICAgICAgICAgICAgICAgIGlkID0gZ3N1YignXiguezJ9KSguKikkJywgJ1xcMV9cXDInLCBpZCkpICU+JSAgICAgICAgIyBpbnNlcnQgIl8iIGFmZXRlciBjb2RlDQogIHRpZHlyOjpzZXBhcmF0ZShpZCwgaW50byA9IGMoImZvcm1hIiwgIklEX25vIiksIHJlbW92ZSA9IEZBTFNFLCBzZXAgPSAiXyIpICU+JQ0KICBkcGx5cjo6bXV0YXRlKGZvcm1hID0gZ3N1YignXiguezF9KSguKikkJywgJ1xcMV9cXDInLCBpZCkpICU+JQ0KICB0aWR5cjo6c2VwYXJhdGUoZm9ybWEsIGludG8gPSBjKCJDb25kIiwgIkNvZ19pbXAiKSwgcmVtb3ZlID0gRkFMU0UsIHNlcCA9ICJfIikgJT4lDQogIGRwbHlyOjptdXRhdGUoQ29uZCA9IGRwbHlyOjpjYXNlX3doZW4oQ29uZCA9PSAiQyIgfiAiQ1RSTCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uZCA9PSAiRSIgfiAiVFIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiBOQV9jaGFyYWN0ZXJfKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoaWQgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZShpZCwgIk8iLCAiMCIpLA0KICAgICAgICAgICAgICAgIGlkID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoaWQsICJvIiwgIjAiKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoSURfbm8gPSBzdHJpbmdyOjpzdHJfcmVwbGFjZShJRF9ubywgIk8iLCAiMCIpLA0KICAgICAgICAgICAgICAgIElEX25vID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoSURfbm8sICJvIiwgIjAiKSwNCiAgICAgICAgICAgICAgICBJRF9ubyA9IGFzLm51bWVyaWMoSURfbm8pKQ0KDQoNCg0KIyBjaGVja3MNCmJsYSA8LSBkYXRhLmZyYW1lKFByZSA9IG5hbWVzKGJlaGF2X3ByZSksIFBvc3QgPSBuYW1lcyhiZWhhdl9wb3N0KSkNCg0KYmVoYXZfcHJlICU+JQ0KICBkcGx5cjo6Y291bnQoaWQpICU+JSAgIyA0MCB4IDENCiAgZHBseXI6OmFycmFuZ2UoaWQpICU+JQ0KICBkcGx5cjo6cHVsbChpZCkgLT4gYmVoYXZfcHJlX2lkcw0KIA0KICANCmJlaGF2X3Bvc3QgJT4lDQogIGRwbHlyOjpjb3VudChpZCkgJT4lICAjIDQwIHggMQ0KICBkcGx5cjo6YXJyYW5nZShpZCkgJT4lDQogIGRwbHlyOjpwdWxsKGlkKSAtPiBiZWhhdl9wb3N0X2lkcw0KDQppZGVudGljYWwoYmVoYXZfcHJlX2lkcywgYmVoYXZfcG9zdF9pZHMpICAgICMgb25lIGhhcyBDVV8xNiwgdGhlIG90aGVyIENOXzE2DQoNCg0KDQojIyBQQU5BUzogUG9zaXRpdmUgQWZmZWN0IFNjb3JlID0gc3VtIGl0ZW1zIDEsIDMsIDUsIDksIDEwLCAxMiwgMTQsIDE2LCAxNywgMTkuIE5lZ2F0aXZlIEFmZmVjdCBTY29yZSA9IHN1bSBpdGVtcyAyLCA0LCA2LCA3LCA4LCAxMSwgMTMsIDE1LCAxOCwgMjAuICANCmluZGV4X2l0ZW1fcGFuYXMgPC0gMTE6MzANCmNvbG5hbWVzKGJlaGF2X3ByZSlbaW5kZXhfaXRlbV9wYW5hc10gPC0gc3ByaW50ZigiUEFOQVNfJWQiLCAxOjIwKQ0KY29sbmFtZXMoYmVoYXZfcG9zdClbaW5kZXhfaXRlbV9wYW5hc10gPC0gc3ByaW50ZigiUEFOQVNfJWQiLCAxOjIwKQ0KDQpiZWhhdl9wcmVbLCBpbmRleF9pdGVtX3BhbmFzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShiZWhhdl9wcmVbLCBpbmRleF9pdGVtX3BhbmFzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKsOubiBmb2FydGUgbWljxIMgbcSDc3VyxIMuKiIsICIxIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KYmVoYXZfcHJlWywgaW5kZXhfaXRlbV9wYW5hc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoYmVoYXZfcHJlWywgaW5kZXhfaXRlbV9wYW5hc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLirDrm4gbWljxIMgbcSDc3VyxIMuKiIsICIyIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KYmVoYXZfcHJlWywgaW5kZXhfaXRlbV9wYW5hc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoYmVoYXZfcHJlWywgaW5kZXhfaXRlbV9wYW5hc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLirDrm50ci1vIG9hcmVjYXJlIG3Eg3N1csSDLioiLCAiMyIsIHgpfSksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCmJlaGF2X3ByZVssIGluZGV4X2l0ZW1fcGFuYXNdIDwtIGRhdGEuZnJhbWUobGFwcGx5KGJlaGF2X3ByZVssIGluZGV4X2l0ZW1fcGFuYXNdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oeCkge2dzdWIoIi4qw65uIG1hcmUgbcSDc3VyxIMuKiIsICI0IiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KYmVoYXZfcHJlWywgaW5kZXhfaXRlbV9wYW5hc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoYmVoYXZfcHJlWywgaW5kZXhfaXRlbV9wYW5hc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLirDrm4gZm9hcnRlIG1hcmUgbcSDc3VyxIMuKiIsICI1IiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KDQpiZWhhdl9wb3N0WywgaW5kZXhfaXRlbV9wYW5hc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fcGFuYXNdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKsOubiBmb2FydGUgbWljxIMgbcSDc3VyxIMuKiIsICIxIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fcGFuYXNdIDwtIGRhdGEuZnJhbWUobGFwcGx5KGJlaGF2X3Bvc3RbLCBpbmRleF9pdGVtX3BhbmFzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLirDrm4gbWljxIMgbcSDc3VyxIMuKiIsICIyIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fcGFuYXNdIDwtIGRhdGEuZnJhbWUobGFwcGx5KGJlaGF2X3Bvc3RbLCBpbmRleF9pdGVtX3BhbmFzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLirDrm50ci1vIG9hcmVjYXJlIG3Eg3N1csSDLioiLCAiMyIsIHgpfSksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCmJlaGF2X3Bvc3RbLCBpbmRleF9pdGVtX3BhbmFzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShiZWhhdl9wb3N0WywgaW5kZXhfaXRlbV9wYW5hc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oeCkge2dzdWIoIi4qw65uIG1hcmUgbcSDc3VyxIMuKiIsICI0IiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fcGFuYXNdIDwtIGRhdGEuZnJhbWUobGFwcGx5KGJlaGF2X3Bvc3RbLCBpbmRleF9pdGVtX3BhbmFzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLirDrm4gZm9hcnRlIG1hcmUgbcSDc3VyxIMuKiIsICI1IiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KDQojIFNjb3JpbmcNCmJlaGF2X3ByZSRQQV9Ub3RhbCA8LSBTY29yZUxpa2VydChiZWhhdl9wcmVbLCBpbmRleF9pdGVtX3BhbmFzXVtjKDEsIDMsIDUsIDksIDEwLCAxMiwgMTQsIDE2LCAxNywgMTkpXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b251bWVyaWMgPSBUUlVFLCBuYXBlcmNlbnQgPSAuMTEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBub3QgbW9yZSB0aGFuIDEgTkFzIGZvciAxMCBpdGVtcw0KYmVoYXZfcHJlJE5BX1RvdGFsIDwtIFNjb3JlTGlrZXJ0KGJlaGF2X3ByZVssIGluZGV4X2l0ZW1fcGFuYXNdW2MoMiwgNCwgNiwgNywgOCwgMTEsIDEzLCAxNSwgMTgsIDIwKV0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b251bWVyaWMgPSBUUlVFLCBuYXBlcmNlbnQgPSAuMTEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBub3QgbW9yZSB0aGFuIDEgTkFzIGZvciAxMCBpdGVtcw0KDQpiZWhhdl9wb3N0JFBBX1RvdGFsIDwtIFNjb3JlTGlrZXJ0KGJlaGF2X3Bvc3RbLCBpbmRleF9pdGVtX3BhbmFzXVtjKDEsIDMsIDUsIDksIDEwLCAxMiwgMTQsIDE2LCAxNywgMTkpXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9udW1lcmljID0gVFJVRSwgbmFwZXJjZW50ID0gLjExKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbm90IG1vcmUgdGhhbiAxIE5BcyBmb3IgMTAgaXRlbXMNCmJlaGF2X3Bvc3QkTkFfVG90YWwgPC0gU2NvcmVMaWtlcnQoYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fcGFuYXNdW2MoMiwgNCwgNiwgNywgOCwgMTEsIDEzLCAxNSwgMTgsIDIwKV0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9udW1lcmljID0gVFJVRSwgbmFwZXJjZW50ID0gLjExKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbm90IG1vcmUgdGhhbiAxIE5BcyBmb3IgMTAgaXRlbXMNCg0KDQoNCg0KIyMgUFNTLVNGIDE0IChsaWtlcnQgMC00KS4gSXRlbXMgNCwgNSwgNiwgNywgOSwgMTAsIGFuZCAxMyBhcmUgc2NvcmVkIGluIHJldmVyc2UgZGlyZWN0aW9uLg0KaW5kZXhfaXRlbV9wc3MgPC0gMzE6NDQNCmluZGV4X2l0ZW1fcmV2UFNTIDwtIGMoNCwgNSwgNiwgNywgOSwgMTAsIDEzKQ0KY29sbmFtZXMoYmVoYXZfcHJlKVtpbmRleF9pdGVtX3Bzc10gPC0gc3ByaW50ZigiUFNTXyVkIiwgMToxNCkNCmNvbG5hbWVzKGJlaGF2X3Bvc3QpW2luZGV4X2l0ZW1fcHNzXSA8LSBzcHJpbnRmKCJQU1NfJWQiLCAxOjE0KQ0KDQpiZWhhdl9wcmVbLCBpbmRleF9pdGVtX3Bzc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoYmVoYXZfcHJlWywgaW5kZXhfaXRlbV9wc3NdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oeCkge2dzdWIoIi4qbmljaW9kYXTEgy4qIiwgIjAiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpiZWhhdl9wcmVbLCBpbmRleF9pdGVtX3Bzc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoYmVoYXZfcHJlWywgaW5kZXhfaXRlbV9wc3NdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oeCkge2dzdWIoIi4qYXByb2FwZSBuaWNpb2RhdMSDLioiLCAiMSIsIHgpfSksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCmJlaGF2X3ByZVssIGluZGV4X2l0ZW1fcHNzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShiZWhhdl9wcmVbLCBpbmRleF9pdGVtX3Bzc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLip1bmVvcmkuKiIsICIyIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KYmVoYXZfcHJlWywgaW5kZXhfaXRlbV9wc3NdIDwtIGRhdGEuZnJhbWUobGFwcGx5KGJlaGF2X3ByZVssIGluZGV4X2l0ZW1fcHNzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKmRlc3R1bCBkZSBkZXMuKiIsICIzIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KYmVoYXZfcHJlWywgaW5kZXhfaXRlbV9wc3NdIDwtIGRhdGEuZnJhbWUobGFwcGx5KGJlaGF2X3ByZVssIGluZGV4X2l0ZW1fcHNzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKmZvYXJ0ZSBkZXMuKiIsICI0IiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KDQpiZWhhdl9wb3N0WywgaW5kZXhfaXRlbV9wc3NdIDwtIGRhdGEuZnJhbWUobGFwcGx5KGJlaGF2X3Bvc3RbLCBpbmRleF9pdGVtX3Bzc10sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIHtnc3ViKCIuKm5pY2lvZGF0xIMuKiIsICIwIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fcHNzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShiZWhhdl9wb3N0WywgaW5kZXhfaXRlbV9wc3NdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLiphcHJvYXBlIG5pY2lvZGF0xIMuKiIsICIxIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fcHNzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShiZWhhdl9wb3N0WywgaW5kZXhfaXRlbV9wc3NdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLip1bmVvcmkuKiIsICIyIiwgeCl9KSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fcHNzXSA8LSBkYXRhLmZyYW1lKGxhcHBseShiZWhhdl9wb3N0WywgaW5kZXhfaXRlbV9wc3NdLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSB7Z3N1YigiLipkZXN0dWwgZGUgZGVzLioiLCAiMyIsIHgpfSksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCmJlaGF2X3Bvc3RbLCBpbmRleF9pdGVtX3Bzc10gPC0gZGF0YS5mcmFtZShsYXBwbHkoYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fcHNzXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oeCkge2dzdWIoIi4qZm9hcnRlIGRlcy4qIiwgIjQiLCB4KX0pLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQoNCiMgU2NvcmUNCmJlaGF2X3ByZVssIGluZGV4X2l0ZW1fcHNzXSA8LSBjb2xzdG9udW1lcmljKGJlaGF2X3ByZVssIGluZGV4X2l0ZW1fcHNzXSkNCmJlaGF2X3Bvc3RbLCBpbmRleF9pdGVtX3Bzc10gPC0gY29sc3RvbnVtZXJpYyhiZWhhdl9wb3N0WywgaW5kZXhfaXRlbV9wc3NdKQ0KDQpiZWhhdl9wcmVbLCBpbmRleF9pdGVtX3Bzc11baW5kZXhfaXRlbV9yZXZQU1NdIDwtIFJldmVyc2VDb2RlKGJlaGF2X3ByZVssIGluZGV4X2l0ZW1fcHNzXVtpbmRleF9pdGVtX3JldlBTU10sIHRvbnVtZXJpYyA9IEZBTFNFLCBtaW4gPSAwLCBtYXggPSA0KQ0KYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fcHNzXVtpbmRleF9pdGVtX3JldlBTU10gPC0gUmV2ZXJzZUNvZGUoYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fcHNzXVtpbmRleF9pdGVtX3JldlBTU10sIHRvbnVtZXJpYyA9IEZBTFNFLCBtaW4gPSAwLCBtYXggPSA0KQ0KDQpiZWhhdl9wcmUkUFNTX1RvdGFsIDwtIFNjb3JlTGlrZXJ0KGJlaGF2X3ByZVssIGluZGV4X2l0ZW1fcHNzXSwgbmFwZXJjZW50ID0gLjExKQ0KYmVoYXZfcG9zdCRQU1NfVG90YWwgPC0gU2NvcmVMaWtlcnQoYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fcHNzXSwgbmFwZXJjZW50ID0gLjExKQ0KDQoNCg0KIyMgUFMgaW50DQppbmRleF9pdGVtX1BTaW50IDwtIDQ1OjQ4ICAgICMgNDU6NTUNCmNvbG5hbWVzKGJlaGF2X3ByZSlbaW5kZXhfaXRlbV9QU2ludF0gPC0gc3ByaW50ZigiUFNpbnRfJWQiLCAxOjQpDQpjb2xuYW1lcyhiZWhhdl9wb3N0KVtpbmRleF9pdGVtX1BTaW50XSA8LSBzcHJpbnRmKCJQU2ludF8lZCIsIDE6NCkNCg0KDQpiZWhhdl9wcmVbLCBzcHJpbnRmKCJQU2ludF8lZCIsIDE6NCldIDwtDQogIGJlaGF2X3ByZVssIHNwcmludGYoIlBTaW50XyVkIiwgMTo0KV0gJT4lDQogICAgZHBseXI6Om11dGF0ZV9hbGwocmVhZHI6OnBhcnNlX251bWJlcikNCg0KDQpiZWhhdl9wb3N0Wywgc3ByaW50ZigiUFNpbnRfJWQiLCAxOjQpXSA8LQ0KICBiZWhhdl9wb3N0Wywgc3ByaW50ZigiUFNpbnRfJWQiLCAxOjQpXSAlPiUNCiAgICBkcGx5cjo6bXV0YXRlX2FsbChyZWFkcjo6cGFyc2VfbnVtYmVyKQ0KDQoNCiMgU2NvcmUNCmJlaGF2X3ByZSRQU2ludF9Ub3RhbCA8LSBTY29yZUxpa2VydChiZWhhdl9wcmVbLCBpbmRleF9pdGVtX1BTaW50XSwgdG9udW1lcmljID0gVFJVRSwgbmFwZXJjZW50ID0gLjMzKQ0KYmVoYXZfcG9zdCRQU2ludF9Ub3RhbCA8LSBTY29yZUxpa2VydChiZWhhdl9wb3N0WywgaW5kZXhfaXRlbV9QU2ludF0sIHRvbnVtZXJpYyA9IFRSVUUsIG5hcGVyY2VudCA9IC4zMykNCg0KDQoNCiMjIFBTIG1vdA0KaW5kZXhfaXRlbV9QU21vdCA8LSA0OTo1MiAgICAgIA0KY29sbmFtZXMoYmVoYXZfcHJlKVtpbmRleF9pdGVtX1BTbW90XSA8LSBzcHJpbnRmKCJQU21vdF8lZCIsIDE6NCkNCmNvbG5hbWVzKGJlaGF2X3Bvc3QpW2luZGV4X2l0ZW1fUFNtb3RdIDwtIHNwcmludGYoIlBTbW90XyVkIiwgMTo0KQ0KDQoNCmJlaGF2X3ByZVssIHNwcmludGYoIlBTbW90XyVkIiwgMTo0KV0gPC0NCiAgYmVoYXZfcHJlWywgc3ByaW50ZigiUFNtb3RfJWQiLCAxOjQpXSAlPiUNCiAgICBkcGx5cjo6bXV0YXRlX2FsbCh+Y2FzZV93aGVuKHN0cmluZ3I6OnN0cl9kZXRlY3QoLiwgImRlemFjb3JkIHB1dGVybmljIikgfiAxLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5ncjo6c3RyX2RldGVjdCguLCAiZGV6YWNvcmQiKSB+IDIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdyOjpzdHJfZGV0ZWN0KC4sICJuZXV0cnUiKSB+IDMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdyOjpzdHJfZGV0ZWN0KC4sICJhY29yZCIpIH4gNCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3I6OnN0cl9kZXRlY3QoLiwgImFjb3JkIHB1dGVybmljIikgfiA1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gTkFfcmVhbF8pKQ0KDQoNCmJlaGF2X3Bvc3RbLCBzcHJpbnRmKCJQU21vdF8lZCIsIDE6NCldIDwtDQogIGJlaGF2X3Bvc3RbLCBzcHJpbnRmKCJQU21vdF8lZCIsIDE6NCldICU+JQ0KICAgIGRwbHlyOjptdXRhdGVfYWxsKH5jYXNlX3doZW4oc3RyaW5ncjo6c3RyX2RldGVjdCguLCAiZGV6YWNvcmQgcHV0ZXJuaWMiKSB+IDEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5ncjo6c3RyX2RldGVjdCguLCAiZGV6YWNvcmQiKSB+IDIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5ncjo6c3RyX2RldGVjdCguLCAibmV1dHJ1IikgfiAzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3I6OnN0cl9kZXRlY3QoLiwgImFjb3JkIikgfiA0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3I6OnN0cl9kZXRlY3QoLiwgImFjb3JkIHB1dGVybmljIikgfiA1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IE5BX3JlYWxfKSkNCg0KDQojIFNjb3JlDQpiZWhhdl9wcmUkUFNtb3RfVG90YWwgPC0gU2NvcmVMaWtlcnQoYmVoYXZfcHJlWywgaW5kZXhfaXRlbV9QU21vdF0sIHRvbnVtZXJpYyA9IFRSVUUsIG5hcGVyY2VudCA9IC4zMykNCmJlaGF2X3Bvc3QkUFNtb3RfVG90YWwgPC0gU2NvcmVMaWtlcnQoYmVoYXZfcG9zdFssIGluZGV4X2l0ZW1fUFNtb3RdLCB0b251bWVyaWMgPSBUUlVFLCBuYXBlcmNlbnQgPSAuMzMpDQoNCg0KDQojIyBQUyBpZGVuDQppbmRleF9pdGVtX1BTaWRlbiA8LSA1Mzo1NSAgICAgDQpjb2xuYW1lcyhiZWhhdl9wcmUpW2luZGV4X2l0ZW1fUFNpZGVuXSA8LSBzcHJpbnRmKCJQU2lkZW5fJWQiLCAxOjMpDQpjb2xuYW1lcyhiZWhhdl9wb3N0KVtpbmRleF9pdGVtX1BTaWRlbl0gPC0gc3ByaW50ZigiUFNpZGVuXyVkIiwgMTozKQ0KDQoNCmJlaGF2X3ByZVssIHNwcmludGYoIlBTaWRlbl8lZCIsIDE6MyldIDwtDQogIGJlaGF2X3ByZVssIHNwcmludGYoIlBTaWRlbl8lZCIsIDE6MyldICU+JQ0KICBkcGx5cjo6bXV0YXRlX2FsbCh+Y2FzZV93aGVuKHN0cmluZ3I6OnN0cl9kZXRlY3QoLiwgImRlemFjb3JkIHB1dGVybmljIikgfiAxLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3I6OnN0cl9kZXRlY3QoLiwgImRlemFjb3JkIikgfiAyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3I6OnN0cl9kZXRlY3QoLiwgIm5ldXRydSIpIH4gMywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdyOjpzdHJfZGV0ZWN0KC4sICJhY29yZCIpIH4gNCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdyOjpzdHJfZGV0ZWN0KC4sICJhY29yZCBwdXRlcm5pYyIpIH4gNSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gTkFfcmVhbF8pKQ0KDQoNCmJlaGF2X3Bvc3RbLCBzcHJpbnRmKCJQU2lkZW5fJWQiLCAxOjMpXSA8LQ0KICBiZWhhdl9wb3N0Wywgc3ByaW50ZigiUFNpZGVuXyVkIiwgMTozKV0gJT4lDQogIGRwbHlyOjptdXRhdGVfYWxsKH5jYXNlX3doZW4oc3RyaW5ncjo6c3RyX2RldGVjdCguLCAiZGV6YWNvcmQgcHV0ZXJuaWMiKSB+IDEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5ncjo6c3RyX2RldGVjdCguLCAiZGV6YWNvcmQiKSB+IDIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5ncjo6c3RyX2RldGVjdCguLCAibmV1dHJ1IikgfiAzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3I6OnN0cl9kZXRlY3QoLiwgImFjb3JkIikgfiA0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3I6OnN0cl9kZXRlY3QoLiwgImFjb3JkIHB1dGVybmljIikgfiA1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiBOQV9yZWFsXykpDQoNCg0KIyBTY29yZQ0KYmVoYXZfcHJlJFBTaWRlbl9Ub3RhbCA8LSBTY29yZUxpa2VydChiZWhhdl9wcmVbLCBpbmRleF9pdGVtX1BTaWRlbl0sIHRvbnVtZXJpYyA9IFRSVUUsIG5hcGVyY2VudCA9IC4zMykNCmJlaGF2X3Bvc3QkUFNpZGVuX1RvdGFsIDwtIFNjb3JlTGlrZXJ0KGJlaGF2X3Bvc3RbLCBpbmRleF9pdGVtX1BTaWRlbl0sIHRvbnVtZXJpYyA9IFRSVUUsIG5hcGVyY2VudCA9IC4zMykNCg0KDQojIyBJT1MNCmNvbG5hbWVzKGJlaGF2X3ByZSlbNTZdIDwtICJJT1MiDQpjb2xuYW1lcyhiZWhhdl9wb3N0KVs1Nl0gPC0gIklPUyINCg0KYmVoYXZfcHJlJElPUyA8LSBhcy5udW1lcmljKGJlaGF2X3ByZSRJT1MpDQpiZWhhdl9wb3N0JElPUyA8LSBhcy5udW1lcmljKGJlaGF2X3Bvc3QkSU9TKSANCg0KDQoNCiMjIEFkZCBzb21lIGNvbHVtbnMNCmJlaGF2X3ByZSA8LSBiZWhhdl9wcmUgJT4lDQogIGRwbHlyOjptdXRhdGUoUHJlUG9zdCA9IHJlcCgiUHJlIiwgbnJvdyguKSkpDQoNCmJlaGF2X3Bvc3QgPC0gYmVoYXZfcG9zdCAlPiUNCiAgZHBseXI6Om11dGF0ZShQcmVQb3N0ID0gcmVwKCJQb3N0IiwgbnJvdyguKSkpDQoNCiMgTG9uZyBmb3JtYXQNCmJlaGF2X2xvbmcgPC0gZHBseXI6OmJpbmRfcm93cyhiZWhhdl9wcmUsIGJlaGF2X3Bvc3QpICU+JQ0KICBkcGx5cjo6bXV0YXRlKFByZVBvc3QgPSBmYWN0b3IoUHJlUG9zdCwgbGV2ZWxzID0gYygiUHJlIiwgIlBvc3QiKSkpDQpgYGANCg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0NCiMgUFNTDQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIkNUUkwiKSAlPiUNCiAgbXlfZ2d3aXRoaW5zdGF0czIoeCA9IFByZVBvc3QsIHkgPSBQU1NfVG90YWwsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJTdHJlc3MiLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkNUUkwiKQ0KDQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIG15X2dnd2l0aGluc3RhdHMyKHggPSBQcmVQb3N0LCB5ID0gUFNTX1RvdGFsLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICB4bGFiID0gIiIsIHlsYWIgPSAiU3RyZXNzIiwNCiAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJUUiIpDQoNCg0KIyBOQQ0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIG15X2dnd2l0aGluc3RhdHMyKHggPSBQcmVQb3N0LCB5ID0gTkFfVG90YWwsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJOZWdhdGl2ZSBBZmZlY3QiLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkNUUkwiKQ0KDQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIG15X2dnd2l0aGluc3RhdHMyKHggPSBQcmVQb3N0LCB5ID0gTkFfVG90YWwsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJOZWdhdGl2ZSBBZmZlY3QiLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlRSIikNCg0KIyBQQQ0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIG15X2dnd2l0aGluc3RhdHMyKHggPSBQcmVQb3N0LCB5ID0gUEFfVG90YWwsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJQb3NpdGl2ZSBBZmZlY3QiLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkNUUkwiKQ0KDQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIG15X2dnd2l0aGluc3RhdHMyKHggPSBQcmVQb3N0LCB5ID0gUEFfVG90YWwsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJQb3NpdGl2ZSBBZmZlY3QiLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlRSIikNCg0KIyBQc2ludA0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIG15X2dnd2l0aGluc3RhdHMyKHggPSBQcmVQb3N0LCB5ID0gUFNpbnRfVG90YWwsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJQcm9zb2NpYWwgaW50ZW50aW9uIiwNCiAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJDVFJMIikNCg0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IFBTaW50X1RvdGFsLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICB4bGFiID0gIiIsIHlsYWIgPSAiUHJvc29jaWFsIGludGVudGlvbiIsDQogICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiVFIiKQ0KDQojIFBzbW90DQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIkNUUkwiKSAlPiUNCiAgbXlfZ2d3aXRoaW5zdGF0czIoeCA9IFByZVBvc3QsIHkgPSBQU2ludF9Ub3RhbCwgb3V0bGllci5sYWJlbCA9IElEX25vLCB0eXBlID0gIm5wIiwgDQogICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIlByb3NvY2lhbCBtb3RpdmF0aW9uIiwNCiAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJDVFJMIikNCg0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IFBTaW50X1RvdGFsLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICB4bGFiID0gIiIsIHlsYWIgPSAiUHJvc29jaWFsIG1vdGl2YXRpb24iLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlRSIikNCg0KIyBJT1MNCmJlaGF2X2xvbmcgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IElPUywgb3V0bGllci5sYWJlbCA9IElEX25vLCB0eXBlID0gIm5wIiwgDQogICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIkNsb3NlbmVzcyIsDQogICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiQ1RSTCIpDQoNCmJlaGF2X2xvbmcgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiVFIiKSAlPiUNCiAgbXlfZ2d3aXRoaW5zdGF0czIoeCA9IFByZVBvc3QsIHkgPSBJT1MsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJDbG9zZW5lc3MiLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlRSIikNCmBgYA0KDQojIyBWQVMgU3RyZXNzDQoNCmBgYHtyIHJlYWRfY2xlYW5fcmVjb2RlX21lcmdlX294dCwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQpmb2xkZXIgPC0gIkM6L1VzZXJzL01paGFpL0Rlc2t0b3AvUiBOb3RlYm9va3Mvbm90ZWJvb2tzL1BBNC1nZXJvbnRvIg0KZmlsZV9wcmUgPC0gImRhdGUgVkFTIFNUUkVTIFBSRSB2YXJzdG5pY2kgLSBtb2RpZi54bHMiDQpmaWxlX3Bvc3QgPC0gImRhdGUgVkFTIFNUUkVTIFBPU1QgdmFyc3RuaWNpLnhscyINCg0Kc3RyZXNfcHJlIDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aChmb2xkZXIsIGZpbGVfcHJlKSkNCnN0cmVzX3ByZSA8LSBzdHJlc19wcmVbLTEsIGMoMzo1LCAxMDoxMSldDQoNCnN0cmVzX3ByZSA8LSBzdHJlc19wcmVbLTM3LF0gICMgU29maSBub3RlYm9vazogb24gMzEtMDcgaWQgMTkgd2FudGVkIDAgYnV0IHB1dCAyNSAuLi4gaGUgaGFzIHR3byByZWNvZGluZ3Mgd2l0aCAyNSBhbmQgMCAuLi4gZGVsZXRlIHRoZSBvbmUgd2l0aCAyNQ0KI3N0cmVzX3ByZSA8LSBzdHJlc19wcmVbLTEyMixdICAgIyBubyBkYXRhDQpuYW1lcyhzdHJlc19wcmUpWzQ6NV0gPC0gYygiaWQiLCAidmFzX3N0cmVzIikNCnN0cmVzX3ByZVtzdHJlc19wcmUkaWQgPT0gIkVOMDhQQTEiLF0kaWQgPC0gIkVVMDhQQTEiICAgICMgdHlwbyAiRU5fMDgiLCBzaG91bGQgYmUgIkVVXzA4Ig0Kc3RyZXNfcHJlIDwtIHN0cmVzX3ByZSAlPiUgDQogIGphbml0b3I6OmNsZWFuX25hbWVzKCkgJT4lDQogIGRwbHlyOjptdXRhdGUoaWQgPSBzdHJpbmdyOjpzdHJfcmVtb3ZlKGlkLCAiUEExIiksDQogICAgICAgICAgICAgICAgaWQgPSBnc3ViKCdeKC57Mn0pKC4qKSQnLCAnXFwxX1xcMicsIGlkKSkgJT4lICAgICAgICAjIGluc2VydCAiXyIgYWZ0ZXIgY29kZQ0KICB0aWR5cjo6c2VwYXJhdGUoaWQsIGludG8gPSBjKCJmb3JtYSIsICJJRF9ubyIpLCByZW1vdmUgPSBGQUxTRSwgc2VwID0gIl8iKSAlPiUNCiAgZHBseXI6Om11dGF0ZShmb3JtYSA9IGdzdWIoJ14oLnsxfSkoLiopJCcsICdcXDFfXFwyJywgaWQpKSAlPiUNCiAgdGlkeXI6OnNlcGFyYXRlKGZvcm1hLCBpbnRvID0gYygiQ29uZCIsICJDb2dfaW1wIiksIHJlbW92ZSA9IEZBTFNFLCBzZXAgPSAiXyIpICU+JQ0KICBkcGx5cjo6bXV0YXRlKENvbmQgPSBkcGx5cjo6Y2FzZV93aGVuKENvbmQgPT0gIkMiIH4gIkNUUkwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbmQgPT0gIkUiIH4gIlRSIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gTkFfY2hhcmFjdGVyXykpICU+JQ0KICBkcGx5cjo6bXV0YXRlKHZhc19zdHJlcyA9IGFzLm51bWVyaWModmFzX3N0cmVzKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoaWQgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZShpZCwgIk8iLCAiMCIpLA0KICAgICAgICAgICAgICAgIGlkID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoaWQsICJvIiwgIjAiKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoSURfbm8gPSBzdHJpbmdyOjpzdHJfcmVwbGFjZShJRF9ubywgIk8iLCAiMCIpLA0KICAgICAgICAgICAgICAgIElEX25vID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoSURfbm8sICJvIiwgIjAiKSwNCiAgICAgICAgICAgICAgICBJRF9ubyA9IGFzLm51bWVyaWMoSURfbm8pKQ0KDQoNCnN0cmVzX3Bvc3QgPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKGZvbGRlciwgZmlsZV9wb3N0KSkNCnN0cmVzX3Bvc3QgPC0gc3RyZXNfcG9zdFstMSwgYygzOjUsIDEwOjExKV0NCm5hbWVzKHN0cmVzX3Bvc3QpWzQ6NV0gPC0gYygiaWQiLCAidmFzX3N0cmVzIikNCnN0cmVzX3Bvc3Rbc3RyZXNfcG9zdCRpZCA9PSAiQ04xMlBBMSIsXSRpZCA8LSAiQ1UxMlBBMSIgICAgIyB0eXBvICJDTl8xMiIsIHNob3VsZCBiZSAiQ1VfMTIiDQpzdHJlc19wb3N0IDwtIHN0cmVzX3Bvc3QgJT4lIA0KICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpICU+JQ0KICBkcGx5cjo6bXV0YXRlKGlkID0gc3RyaW5ncjo6c3RyX3JlbW92ZShpZCwgIlBBMSIpLA0KICAgICAgICAgICAgICAgIGlkID0gZ3N1YignXiguezJ9KSguKikkJywgJ1xcMV9cXDInLCBpZCkpICU+JSAgICAgICAgIyBpbnNlcnQgIl8iIGFmdGVyIGNvZGUNCiAgdGlkeXI6OnNlcGFyYXRlKGlkLCBpbnRvID0gYygiZm9ybWEiLCAiSURfbm8iKSwgcmVtb3ZlID0gRkFMU0UsIHNlcCA9ICJfIikgJT4lDQogIGRwbHlyOjptdXRhdGUoZm9ybWEgPSBnc3ViKCdeKC57MX0pKC4qKSQnLCAnXFwxX1xcMicsIGlkKSkgJT4lDQogIHRpZHlyOjpzZXBhcmF0ZShmb3JtYSwgaW50byA9IGMoIkNvbmQiLCAiQ29nX2ltcCIpLCByZW1vdmUgPSBGQUxTRSwgc2VwID0gIl8iKSAlPiUNCiAgZHBseXI6Om11dGF0ZShDb25kID0gZHBseXI6OmNhc2Vfd2hlbihDb25kID09ICJDIiB+ICJDVFJMIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25kID09ICJFIiB+ICJUUiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IE5BX2NoYXJhY3Rlcl8pKSAlPiUNCiAgZHBseXI6Om11dGF0ZSh2YXNfc3RyZXMgPSBhcy5udW1lcmljKHZhc19zdHJlcykpICU+JQ0KICBkcGx5cjo6bXV0YXRlKGlkID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoaWQsICJPIiwgIjAiKSwNCiAgICAgICAgICAgICAgICBpZCA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlKGlkLCAibyIsICIwIikpICU+JQ0KICBkcGx5cjo6bXV0YXRlKElEX25vID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoSURfbm8sICJPIiwgIjAiKSwNCiAgICAgICAgICAgICAgICBJRF9ubyA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlKElEX25vLCAibyIsICIwIiksDQogICAgICAgICAgICAgICAgSURfbm8gPSBhcy5udW1lcmljKElEX25vKSkNCg0KICANCg0KIyByZXRyYXNpDQpyZXRyYXNpX3Bvc3QgPC0gYygxLCA2LCA3KQ0KDQojIGNoZWNrDQpzdHJlc19wcmUgJT4lDQogIGRwbHlyOjpjb3VudChpZCkgJT4lDQogIGRwbHlyOjpwdWxsKGlkKSAtPiBzdHJlc19wcmVfaWRzDQpzZXRkaWZmKHN0cmVzX3ByZV9pZHMsIGJlaGF2X3ByZV9pZHMpICAgDQoNCnN0cmVzX3Bvc3QgJT4lDQogIGRwbHlyOjpjb3VudChpZCkgJT4lDQogIGRwbHlyOjpwdWxsKGlkKSAtPiBzdHJlc19wb3N0X2lkcw0Kc2V0ZGlmZihzdHJlc19wb3N0X2lkcywgYmVoYXZfcHJlX2lkcykgIA0Kc2V0ZGlmZihzdHJlc19wcmVfaWRzLCBzdHJlc19wb3N0X2lkcykNCg0KIyBBZGQgdmFyaWFibGUgVGltZQ0KIyBpdHM6IHByZS1wb3N0IHg0ICsgcHJlLXBvc3QtcG9zdCA9PiBwcmUgPSAxLDMsNSw3LDkgIHBvc3QgPSAyLDQsNiw4LDEwLDExDQojIGluIHByZSBFTl8xOSBoYXZlIDYgaW5zdGVhZCBvZiA1IGRhdGEgLS0gZml4ZWQgbm93OyBFTl8wNCBmaXhlZCBpbiBleGNlbCBmaWxlDQoNCnN0cmVzX3ByZV90aW1lIDwtIA0KICBzdHJlc19wcmUgJT4lDQogIGRwbHlyOjptdXRhdGUocm93X251bWIgPSBkcGx5cjo6cm93X251bWJlcigpKSAlPiUNCiAgZHBseXI6OmFycmFuZ2UoZGVzYyhyb3dfbnVtYikpICU+JSAgICAgICAgICAgICAgICAgICAgICMgb3JkZXIgb2Ygcm93cyBuZWVkcyB0byBiZSBpbnZlcnRlZCB0byBiZSBpbiBjaHJvbm9sb2dpY2FsIG9yZGVyDQogIGRwbHlyOjpzZWxlY3QoLXJvd19udW1iKSAlPiUNCiAgZHBseXI6Omdyb3VwX2J5KGlkKSAlPiUNCiAgZHBseXI6Om11dGF0ZShUaW1lID0gZHBseXI6OnJvd19udW1iZXIoKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoVGltZSA9IGRwbHlyOjpjYXNlX3doZW4oQ29uZCA9PSAiQ1RSTCIgJiBUaW1lID09IDEgfiA5LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbmQgPT0gIlRSIiAmIFRpbWUgPT0gMSB+IDEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uZCA9PSAiVFIiICYgVGltZSA9PSAyIH4gMywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25kID09ICJUUiIgJiBUaW1lID09IDMgfiA1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbmQgPT0gIlRSIiAmIFRpbWUgPT0gNCB+IDcsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uZCA9PSAiVFIiICYgVGltZSA9PSA1IH4gOSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gTkFfcmVhbF8pKSAlPiUNCiAgZHBseXI6OnVuZ3JvdXAoKSAgICAgICAgICAgICAgICAgICAgDQoNCnN0cmVzX3Bvc3RfdGltZSA8LSANCiAgc3RyZXNfcG9zdCAlPiUNCiAgdGlkeXI6OmRyb3BfbmEodmFzX3N0cmVzKSAlPiUgICAgICAgICAgICAgICAgICAgICAgIyB0aGVyZSBpcyBvbmUgTkEgdGhhdCBydWlucyB0aGUgZmxvdw0KICBkcGx5cjo6bXV0YXRlKHJvd19udW1iID0gZHBseXI6OnJvd19udW1iZXIoKSkgJT4lDQogIGRwbHlyOjphcnJhbmdlKGRlc2Mocm93X251bWIpKSAlPiUgICAgICAgICAgICAgICAgICAgICAjIG9yZGVyIG9mIHJvd3MgbmVlZHMgdG8gYmUgaW52ZXJ0ZWQgdG8gYmUgaW4gY2hyb25vbG9naWNhbCBvcmRlcg0KICBkcGx5cjo6c2VsZWN0KC1yb3dfbnVtYikgJT4lDQogIGRwbHlyOjpncm91cF9ieShpZCkgJT4lDQogIGRwbHlyOjptdXRhdGUoVGltZSA9IGRwbHlyOjpyb3dfbnVtYmVyKCkpICU+JQ0KICBkcGx5cjo6bXV0YXRlKFRpbWUgPSBkcGx5cjo6Y2FzZV93aGVuKENvbmQgPT0gIkNUUkwiICYgVGltZSA9PSAxIH4gMTAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uZCA9PSAiQ1RSTCIgJiBUaW1lID09IDIgfiAxMSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25kID09ICJUUiIgJiBUaW1lID09IDEgfiAyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbmQgPT0gIlRSIiAmIFRpbWUgPT0gMiB+IDQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29uZCA9PSAiVFIiICYgVGltZSA9PSAzIH4gNiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25kID09ICJUUiIgJiBUaW1lID09IDQgfiA4LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbmQgPT0gIlRSIiAmIFRpbWUgPT0gNSB+IDEwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbmQgPT0gIlRSIiAmIFRpbWUgPT0gNiB+IDExLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiBOQV9yZWFsXykpICU+JQ0KICBkcGx5cjo6dW5ncm91cCgpDQoNCg0KIyBjaGVjaw0Kc3RyZXNfcHJlX3RpbWUgJT4lDQogIGRwbHlyOjpncm91cF9ieShpZCkgJT4lDQogIGZpbHRlcihUaW1lID09IG1heChUaW1lKSkgJT4lIA0KICBwcmludChuID0gSW5mKSAgICAgICAgICAgICAgICMgYWxsIGFyZSAxIGFuZCA5IC0tIGdvb2QNCg0Kc3RyZXNfcG9zdF90aW1lICU+JQ0KICBkcGx5cjo6Z3JvdXBfYnkoaWQpICU+JQ0KICBmaWx0ZXIoVGltZSA9PSBtYXgoVGltZSkpICU+JSANCiAgcHJpbnQobiA9IEluZikgICAgICAgICAgICAgICMgYWxsIGFyZSAxMSAtLSBnb29kIGJlY2F1c2UgbGFzdCBwb3N0IGlzIHNhbWUgaW4gVFIgYW5kIENUUkwNCg0KIyBMb25nIGRhdGENCnN0cmVzX3RpbWVfbG9uZyA8LSBkcGx5cjo6YmluZF9yb3dzKHN0cmVzX3ByZV90aW1lLCBzdHJlc19wb3N0X3RpbWUpICU+JQ0KICBkcGx5cjo6bXV0YXRlKFRpbWUgPSBmYWN0b3IoVGltZSwgbGV2ZWxzID0gYygxOjExKSkpDQpgYGANCg0KIyMjIENUUkwNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9DQpzdHJlc190aW1lX2xvbmcgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBnZ3N0YXRzcGxvdDo6Z2d3aXRoaW5zdGF0cyh4ID0gVGltZSwgeSA9IHZhc19zdHJlcywgb3V0bGllci5sYWJlbCA9IGlkLCANCiAgICAgICAgICAgICAgICB0eXBlID0gIm5wIikNCmBgYA0KDQojIyMgVFINCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9DQpzdHJlc190aW1lX2xvbmcgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiVFIiKSAlPiUNCiAgZHBseXI6OmZpbHRlcihUaW1lICVpbiUgYyg5LCAxMCwgMTEpKSAlPiUNCiAgZ2dzdGF0c3Bsb3Q6Omdnd2l0aGluc3RhdHMoeCA9IFRpbWUsIHkgPSB2YXNfc3RyZXMsIG91dGxpZXIubGFiZWwgPSBpZCwgDQogICAgICAgICAgICAgICAgdHlwZSA9ICJucCIpDQpgYGANCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xMn0NCnN0cmVzX3RpbWVfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBnZ3N0YXRzcGxvdDo6Z2d3aXRoaW5zdGF0cyh4ID0gVGltZSwgeSA9IHZhc19zdHJlcywgb3V0bGllci5sYWJlbCA9IGlkLCANCiAgICAgICAgICAgICAgICB0eXBlID0gIm5wIikNCmBgYA0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEyfQ0Kc3RyZXNfdGltZV9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoIVRpbWUgJWluJSBjKDksIDEwLCAxMSkpICU+JQ0KICBnZ3N0YXRzcGxvdDo6Z2d3aXRoaW5zdGF0cyh4ID0gVGltZSwgeSA9IHZhc19zdHJlcywgb3V0bGllci5sYWJlbCA9IGlkLCANCiAgICAgICAgICAgICAgICB0eXBlID0gIm5wIikNCmBgYA0KDQoNCg0KIyMgT25seSBmb3IgTm9ybWFsIENvZ25pdGlvbg0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0NCiMgZGVmaWNpZW50YSBjb2duaXRpdmEgKE4tbm9ybWFsLCBVLXVzb3IgZGVmaWNpdCBjb2duaXRpdikNCg0KIyBQU1MNCmJlaGF2X2xvbmcgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvZ19pbXAgPT0gIk4iKSAlPiUNCiAgbXlfZ2d3aXRoaW5zdGF0czIoeCA9IFByZVBvc3QsIHkgPSBQU1NfVG90YWwsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJTdHJlc3MiLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkNUUkwiKQ0KDQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29nX2ltcCA9PSAiTiIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IFBTU19Ub3RhbCwgb3V0bGllci5sYWJlbCA9IElEX25vLCB0eXBlID0gIm5wIiwgDQogICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIlN0cmVzcyIsDQogICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiVFIiKQ0KDQoNCiMgTkENCmJlaGF2X2xvbmcgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvZ19pbXAgPT0gIk4iKSAlPiUNCiAgbXlfZ2d3aXRoaW5zdGF0czIoeCA9IFByZVBvc3QsIHkgPSBOQV9Ub3RhbCwgb3V0bGllci5sYWJlbCA9IElEX25vLCB0eXBlID0gIm5wIiwgDQogICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIk5lZ2F0aXZlIEFmZmVjdCIsDQogICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiQ1RSTCIpDQoNCmJlaGF2X2xvbmcgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiVFIiKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb2dfaW1wID09ICJOIikgJT4lDQogIG15X2dnd2l0aGluc3RhdHMyKHggPSBQcmVQb3N0LCB5ID0gTkFfVG90YWwsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJOZWdhdGl2ZSBBZmZlY3QiLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlRSIikNCg0KIyBQQQ0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29nX2ltcCA9PSAiTiIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IFBBX1RvdGFsLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICB4bGFiID0gIiIsIHlsYWIgPSAiUG9zaXRpdmUgQWZmZWN0IiwNCiAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJDVFJMIikNCg0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvZ19pbXAgPT0gIk4iKSAlPiUNCiAgbXlfZ2d3aXRoaW5zdGF0czIoeCA9IFByZVBvc3QsIHkgPSBQQV9Ub3RhbCwgb3V0bGllci5sYWJlbCA9IElEX25vLCB0eXBlID0gIm5wIiwgDQogICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIlBvc2l0aXZlIEFmZmVjdCIsDQogICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiVFIiKQ0KDQojIFBzaW50DQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIkNUUkwiKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb2dfaW1wID09ICJOIikgJT4lDQogIG15X2dnd2l0aGluc3RhdHMyKHggPSBQcmVQb3N0LCB5ID0gUFNpbnRfVG90YWwsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJQcm9zb2NpYWwgaW50ZW50aW9uIiwNCiAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJDVFJMIikNCg0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvZ19pbXAgPT0gIk4iKSAlPiUNCiAgbXlfZ2d3aXRoaW5zdGF0czIoeCA9IFByZVBvc3QsIHkgPSBQU2ludF9Ub3RhbCwgb3V0bGllci5sYWJlbCA9IElEX25vLCB0eXBlID0gIm5wIiwgDQogICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIlByb3NvY2lhbCBpbnRlbnRpb24iLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlRSIikNCg0KIyBQc21vdA0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29nX2ltcCA9PSAiTiIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IFBTaW50X1RvdGFsLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICB4bGFiID0gIiIsIHlsYWIgPSAiUHJvc29jaWFsIG1vdGl2YXRpb24iLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkNUUkwiKQ0KDQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29nX2ltcCA9PSAiTiIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IFBTaW50X1RvdGFsLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICB4bGFiID0gIiIsIHlsYWIgPSAiUHJvc29jaWFsIG1vdGl2YXRpb24iLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlRSIikNCg0KIyBJT1MNCmJlaGF2X2xvbmcgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvZ19pbXAgPT0gIk4iKSAlPiUNCiAgbXlfZ2d3aXRoaW5zdGF0czIoeCA9IFByZVBvc3QsIHkgPSBJT1MsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJDbG9zZW5lc3MiLA0KICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkNUUkwiKQ0KDQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29nX2ltcCA9PSAiTiIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IElPUywgb3V0bGllci5sYWJlbCA9IElEX25vLCB0eXBlID0gIm5wIiwgDQogICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIkNsb3NlbmVzcyIsDQogICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiVFIiKQ0KYGBgDQoNCg0KIyMgT25seSBmb3IgTGlnaHQgQ29nbml0aXZlIERlZmljaXQNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9DQojIGRlZmljaWVudGEgY29nbml0aXZhIChOLW5vcm1hbCwgVS11c29yIGRlZmljaXQgY29nbml0aXYpDQoNCiMgUFNTDQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIkNUUkwiKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb2dfaW1wID09ICJVIikgJT4lDQogIG15X2dnd2l0aGluc3RhdHMyKHggPSBQcmVQb3N0LCB5ID0gUFNTX1RvdGFsLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIlN0cmVzcyIsDQogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkNUUkwiKQ0KDQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29nX2ltcCA9PSAiVSIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IFBTU19Ub3RhbCwgb3V0bGllci5sYWJlbCA9IElEX25vLCB0eXBlID0gIm5wIiwgDQogICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJTdHJlc3MiLA0KICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJUUiIpDQoNCg0KIyBOQQ0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29nX2ltcCA9PSAiVSIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IE5BX1RvdGFsLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIk5lZ2F0aXZlIEFmZmVjdCIsDQogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkNUUkwiKQ0KDQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29nX2ltcCA9PSAiVSIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IE5BX1RvdGFsLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIk5lZ2F0aXZlIEFmZmVjdCIsDQogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlRSIikNCg0KIyBQQQ0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29nX2ltcCA9PSAiVSIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IFBBX1RvdGFsLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIlBvc2l0aXZlIEFmZmVjdCIsDQogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkNUUkwiKQ0KDQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIlRSIikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29nX2ltcCA9PSAiVSIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IFBBX1RvdGFsLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIlBvc2l0aXZlIEFmZmVjdCIsDQogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlRSIikNCg0KIyBQc2ludA0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJDVFJMIikgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29nX2ltcCA9PSAiVSIpICU+JQ0KICBteV9nZ3dpdGhpbnN0YXRzMih4ID0gUHJlUG9zdCwgeSA9IFBTaW50X1RvdGFsLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIlByb3NvY2lhbCBpbnRlbnRpb24iLA0KICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJDVFJMIikNCg0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvZ19pbXAgPT0gIlUiKSAlPiUNCiAgbXlfZ2d3aXRoaW5zdGF0czIoeCA9IFByZVBvc3QsIHkgPSBQU2ludF9Ub3RhbCwgb3V0bGllci5sYWJlbCA9IElEX25vLCB0eXBlID0gIm5wIiwgDQogICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJQcm9zb2NpYWwgaW50ZW50aW9uIiwNCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiVFIiKQ0KDQojIFBzbW90DQpiZWhhdl9sb25nICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvbmQgPT0gIkNUUkwiKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb2dfaW1wID09ICJVIikgJT4lDQogIG15X2dnd2l0aGluc3RhdHMyKHggPSBQcmVQb3N0LCB5ID0gUFNpbnRfVG90YWwsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgICB4bGFiID0gIiIsIHlsYWIgPSAiUHJvc29jaWFsIG1vdGl2YXRpb24iLA0KICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJDVFJMIikNCg0KYmVoYXZfbG9uZyAlPiUNCiAgZHBseXI6OmZpbHRlcihDb25kID09ICJUUiIpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvZ19pbXAgPT0gIlUiKSAlPiUNCiAgbXlfZ2d3aXRoaW5zdGF0czIoeCA9IFByZVBvc3QsIHkgPSBQU2ludF9Ub3RhbCwgb3V0bGllci5sYWJlbCA9IElEX25vLCB0eXBlID0gIm5wIiwgDQogICAgICAgICAgICAgICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9ICJQcm9zb2NpYWwgbW90aXZhdGlvbiIsDQogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlRSIikNCg0KIyBJT1MNCmJlaGF2X2xvbmcgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiQ1RSTCIpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKENvZ19pbXAgPT0gIlUiKSAlPiUNCiAgbXlfZ2d3aXRoaW5zdGF0czIoeCA9IFByZVBvc3QsIHkgPSBJT1MsIG91dGxpZXIubGFiZWwgPSBJRF9ubywgdHlwZSA9ICJucCIsIA0KICAgICAgICAgICAgICAgICAgICB4bGFiID0gIiIsIHlsYWIgPSAiQ2xvc2VuZXNzIiwNCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiQ1RSTCIpDQoNCmJlaGF2X2xvbmcgJT4lDQogIGRwbHlyOjpmaWx0ZXIoQ29uZCA9PSAiVFIiKSAlPiUNCiAgZHBseXI6OmZpbHRlcihDb2dfaW1wID09ICJVIikgJT4lDQogIG15X2dnd2l0aGluc3RhdHMyKHggPSBQcmVQb3N0LCB5ID0gSU9TLCBvdXRsaWVyLmxhYmVsID0gSURfbm8sIHR5cGUgPSAibnAiLCANCiAgICAgICAgICAgICAgICAgICAgeGxhYiA9ICIiLCB5bGFiID0gIkNsb3NlbmVzcyIsDQogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlRSIikNCmBgYA0KDQoNCiMgVGVzdCBWQVMgU3RyZXNzIGRpZmZlcmVuY2VzIGluIHJlc3BvbnNlIHRvIEJ1Y2hhcmVzdCBTdHJlc3MgVGFzayANCiMjIHNlZSAgQnJ1bm5lciBldCBhbC4gKDIwMDIpDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQ0KIyBleHBlcmltZW50IGhhcyB0aGUgRjEtTEQtRjEgZGVzaWduc3RydWN0dXJlIHdpdGggdHJlYXRtZW50IGJlaW5nIHRoZSB3aG9sZS1wbG90IGZhY3Rvci4gKHAuIDEzIGFydCBSIEpvdXJuYWwpDQoNCnN0cmVzX2YxbGRmMSA8LSANCiAgc3RyZXNfdGltZV9sb25nICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIoVGltZSAlaW4lIGMoOSwgMTAsIDExKSkgJT4lDQogICAgZHBseXI6Om11dGF0ZShUaW1lID0gZmFjdG9yKFRpbWUsIGxldmVscyA9IGMoOSwgMTAsIDExKSkpIA0KDQpucGFyTEQ6OmYxLmxkLmYxKHkgPSBzdHJlc19mMWxkZjEkdmFzX3N0cmVzLCB0aW1lID0gc3RyZXNfZjFsZGYxJFRpbWUsIGdyb3VwID0gc3RyZXNfZjFsZGYxJENvbmQsIHN1YmplY3QgPSBzdHJlc19mMWxkZjEkaWQpDQpgYGANCg0KDQoNCg0KPCEtLSBTZXNzaW9uIEluZm8gYW5kIExpY2Vuc2UgLS0+DQoNCjxicj4NCg0KIyBTZXNzaW9uIEluZm8NCmBgYHtyIHNlc3Npb25faW5mbywgZWNobyA9IEZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9DQpzZXNzaW9uSW5mbygpICAgIA0KYGBgDQoNCjwhLS0gRm9vdGVyIC0tPg0KJm5ic3A7DQo8aHIgLz4NCjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij5BIHdvcmsgYnkgPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL0NsYXVkaXVQYXBhc3RlcmkvIj5DbGF1ZGl1IFBhcGFzdGVyaTwvYT48L3A+DQo8cCBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyI+PHNwYW4gc3R5bGU9ImNvbG9yOiAjODA4MDgwOyI+PGVtPmNsYXVkaXUucGFwYXN0ZXJpQGdtYWlsLmNvbTwvZW0+PC9zcGFuPjwvcD4NCiZuYnNwOw0K