1 Read and Merge

Merge was succesful

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Derive new variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Data$D_VasS_Poz <- Data[, "VasS_postPoz"] - Data[, "VasS_prePoz"] 
Data$D_VasS_Neg <- Data[, "VasS_postNeg"] - Data[, "VasS_preNeg"]
Data$D_VasB_Poz <- Data[, "VasB_postPoz"] - Data[, "VasB_prePoz"] 
Data$D_VasB_Neg <- Data[, "VasB_postNeg"] - Data[, "VasB_preNeg"]
Data$D_IOS_Poz <- Data[, "IOS_postPoz"] - Data[, "IOS_prePoz"] 
Data$D_IOS_Neg <- Data[, "IOS_postNeg"] - Data[, "IOS_preNeg"]

Data$D_Sam1_Poz <- Data[, "Sam1_postPoz"] - Data[, "Sam1_prePoz"] 
Data$D_Sam1_Neg <- Data[, "Sam1_postNeg"] - Data[, "Sam1_preNeg"]
Data$D_Sam2_Poz <- Data[, "Sam2_postPoz"] - Data[, "Sam2_prePoz"] 
Data$D_Sam2_Neg <- Data[, "Sam2_postNeg"] - Data[, "Sam2_preNeg"]
Data$D_Sam3_Poz <- Data[, "Sam3_postPoz"] - Data[, "Sam3_prePoz"] 
Data$D_Sam3_Neg <- Data[, "Sam3_postNeg"] - Data[, "Sam3_preNeg"]

Data$D_DG_Poz <- Data[, "DG_postPozTot"] - Data[, "DG_prePozTot"] 
Data$D_DG_Neg <- Data[, "DG_postNegTot"] - Data[, "DG_preNegTot"]

Data$D_TrustMin_Poz <- Data[, "TrustMinPozPost"] - Data[, "TrustMinPozPre"] 
Data$D_TrustMin_Neg <- Data[, "TrustMinNegPost"] - Data[, "TrustMinNegPre"]
Data$D_TrustTot_Poz <- Data[, "TrustTotPozPost"] - Data[, "TrustTotPozPre"] 
Data$D_TrustTot_Neg <- Data[, "TrustTotNegPost"] - Data[, "TrustTotNegPre"]

Data$D_Cort_Poz <- Data[, "Cort_post_Poz"] - Data[, "Cort_pre_Poz"] 
Data$D_Cort_Neg <- Data[, "Cort_post_Neg"] - Data[, "Cort_pre_Neg"]
Data$D_Ox_Poz <- Data[, "Ox_post_Poz"] - Data[, "Ox_pre_Poz"] 
Data$D_Ox_Neg <- Data[, "Ox_post_Neg"] - Data[, "Ox_pre_Neg"]

–>

1.1 Dataset - Long Format

1.2 Dataset - Wide Format

2 Define functions

# Define Function for Two-way rmANOVA
# library(tidyverse)
# library(ggpubr)
# library(rstatix)
# library(rlang)

tw_rmANOVA_func <- 
  function(data, id_var, cond_var, time_var, value_var, 
           assum_check = TRUE, posthoc_sig_interac = FALSE, posthoc_ns_interac = FALSE,
           p_adjust_method = "bonferroni"){
  
  # input dataframe needs to have columns names diffrent from "variable" and "value" because it collides with rstatix::shapiro_test
    
  id_var_enq <- rlang::enquo(id_var)  
  cond_var_enq <- rlang::enquo(cond_var)
  cond_var_name <- rlang::as_name(cond_var_enq)
  time_var_enq <- rlang::enquo(time_var)
  time_var_name <- rlang::as_name(time_var_enq)
  value_var_enq <- rlang::enquo(value_var)
  value_var_name <- rlang::as_name(value_var_enq)
    
  # Assumptions
  if(assum_check){
    cat("\n Outliers \n")
    data %>%
      dplyr::group_by(!!cond_var_enq, !!time_var_enq) %>%
      rstatix::identify_outliers(!!value_var_enq) %>%                                  # outliers (needs to be 0)
      print()
    
    cat("\n Normality assumption (p>.05) \n")
    data %>%
      dplyr::group_by(!!cond_var_enq, !!time_var_enq) %>%
      rstatix::shapiro_test(!!value_var_enq) %>%                                        # normality assumption (p>.05)
      print()
    
    qq_plot <- 
      ggpubr::ggqqplot(data = data, value_var_name, ggtheme = theme_bw(), title = "QQ Plot") +
        ggplot2::facet_grid(vars(!!time_var_enq), vars(!!cond_var_enq), labeller = "label_both")    # QQ plot
  }
  
  # Two-way rmANOVA - check for interaction (ex. F(2, 22) = 30.4, p < 0.0001)
  cat("\n Two-way rmANOVA \n")
  res_aov <- anova_test(                         # automatically does sphericity Mauchly’s test
    data = data, dv = !!value_var_enq, wid = !!id_var_enq,                             
    within = c(!!cond_var_enq, !!time_var_enq)
  )
  get_anova_table(res_aov) %>%  # ges: Greenhouse-Geisser sphericity correction is automatically applied to factors violating the sphericity assumption  
  print()
  
  #- Procedure for a significant two-way interaction -
  if(posthoc_sig_interac){
    cat("\n Effect of treatment at each time point \n")
    one_way <- 
      data %>%
      group_by(!!time_var_enq) %>%
      anova_test(dv = !!value_var_enq, wid = !!id_var_enq, within = !!cond_var_enq) %>%
      get_anova_table() %>%
      adjust_pvalue(method = "bonferroni")
    one_way %>% print()
    
    cat("\n Pairwise comparisons between treatment groups \n")
    pwc <-
      data %>%
      group_by(!!time_var_enq) %>%
      pairwise_t_test(
        as.formula(paste0(value_var_name, " ~ ", cond_var_name)),
        paired = TRUE,
        p.adjust.method = p_adjust_method
      )
    pwc %>% print()

    cat("\n Effect of time at each level of treatment - One-way ANOVA \n")
    one_way2 <-
      data %>%
      group_by(!!cond_var_enq) %>%
      anova_test(dv = !!value_var_enq, wid = !!id_var_enq, within = !!time_var_enq) %>%
      get_anova_table() %>%
      adjust_pvalue(method = p_adjust_method)
    one_way2  %>% print()
    cat("\n Pairwise comparisons between time points \n")
    pwc2 <-
      data %>%
      group_by(!!cond_var_enq) %>%
      pairwise_t_test(
        as.formula(paste0(value_var_name, " ~ ", time_var_name)),     # paste formula, not quosure
        paired = TRUE,
        p.adjust.method = p_adjust_method
      )
    pwc2  %>% print()
  }
  
  #- Procedure for non-significant two-way interaction- 
  # If the interaction is not significant, you need to interpret the main effects for each of the two variables: treatment and time.
  if(posthoc_ns_interac){
    cat("\n Comparisons for treatment variable \n")
    pwc_cond <-
      data %>%
      pairwise_t_test(
        as.formula(paste0(value_var_name, " ~ ", cond_var_name)),     # paste formula, not quosure             
        paired = TRUE,
        p.adjust.method = p_adjust_method
      )
    pwc_cond %>% print()
    cat("\n Comparisons for time variable \n")
    pwc_time <-
      data %>% 
      pairwise_t_test(
        as.formula(paste0(value_var_name, " ~ ", time_var_name)),     # paste formula, not quosure
        paired = TRUE,
        p.adjust.method = p_adjust_method
      )
    pwc_time %>% print()
  }
  
  # Visualization
  bx_plot <- 
    ggboxplot(data, x = time_var_name, y = value_var_name,
    color = cond_var_name, palette = "jco")
  pwc <- 
    pwc %>% 
    add_xy_position(x = time_var_name)
  bx_plot <- 
    bx_plot + 
    stat_pvalue_manual(pwc, tip.length = 0, hide.ns = TRUE) +
    labs(
      subtitle = get_test_label(res_aov, detailed = TRUE),
      caption = get_pwc_label(pwc)
    )
  
  if(assum_check){ 
    list(qq_plot, bx_plot)
  }else{
    bx_plot
  } 
  
}

# ex. - run on long format
# tw_rmANOVA_func(data = selfesteem2, id_var = id, cond_var = treatment, time_var = time, value_var = scores, 
#                 posthoc_sig_interac = TRUE, posthoc_ns_interac = TRUE)
## Wilcoxon signed rank test on paired samples

# library(tidyverse)
# library(ggpubr)
# library(rstatix)
# library(rlang)

wilcoxon_paired_func <- function(data, id_var, time_var, value_var, 
                                 assum_check = TRUE){
  
  id_var_enq <- rlang::enquo(id_var)  
  id_var_name <- rlang::as_name(id_var_enq)
  time_var_enq <- rlang::enquo(time_var)
  time_var_name <- rlang::as_name(time_var_enq)
  value_var_enq <- rlang::enquo(value_var)
  value_var_name <- rlang::as_name(value_var_enq)
  
  cat("\n Summary statistics \n")
  data %>%
    group_by(!!time_var_enq) %>%
    get_summary_stats(!!value_var_enq, type = c("common")) %>%
    print() 
  
  if(assum_check){  # The test assumes that differences between paired samples should be distributed symmetrically around the median.
  data2 <- 
    data %>% 
    group_by(!!id_var_enq) %>% 
    mutate(differences = !!value_var_enq - lag(!!value_var_enq))

  hist_dif_plot <- gghistogram(data2, x = "differences", y = "..density..", 
                               fill = "steelblue", add_density = TRUE)
  }
  
  cat("\n Wilcoxon signed rank test on paired samples \n")
  stat_test <- 
    data  %>%
    wilcox_test(as.formula(paste0(value_var_name, " ~ ", time_var_name)), 
                paired = TRUE) %>%
    add_significance()
  stat_test %>% print()
  
  cat("\n Effect size \n")
  ef_size <-
    data %>%
    wilcox_effsize(as.formula(paste0(value_var_name, " ~ ", time_var_name)), 
                   paired = TRUE)
  ef_size %>% print()
  
  # Visualization
  bx_plot <- ggpaired(data, x = time_var_name, y = value_var_name, id = id_var_name,
                      ylab = value_var_name, xlab = time_var_name)
  
  stat_test <- 
    stat_test %>% 
    add_xy_position(x = time_var_name)
  
  bx_plot <-
    bx_plot + 
      stat_pvalue_manual(stat_test, tip.length = 0) +
      labs(subtitle = get_test_label(stat_test, detailed = TRUE))
  
  if(assum_check){ 
    list(hist_dif_plot, bx_plot)
  }else{
    bx_plot
  }  
  
}

3 rmANOVA OXT

## All subjects

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd      F        p p<.05   ges
1         Cond   1  28  0.537 0.470000       0.008
2      PrePost   1  28 17.388 0.000266     * 0.063
3 Cond:PrePost   1  28  0.220 0.642000       0.001

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

## Females

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd      F     p p<.05   ges
1         Cond   1  20  1.054 0.317       0.022
2      PrePost   1  20 10.660 0.004     * 0.055
3 Cond:PrePost   1  20  0.188 0.669       0.001

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

## Males

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05      ges
1         Cond   1   7 0.031 0.865       0.002000
2      PrePost   1   7 6.360 0.040     * 0.087000
3 Cond:PrePost   1   7 0.031 0.866       0.000557

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

4 rmANOVA Stres

## All subjects

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05       ges
1         Cond   1  29 0.004 0.949       0.0000565
2      PrePost   1  29 3.940 0.057       0.0060000
3 Cond:PrePost   1  29 4.259 0.048     * 0.0090000

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

## Females

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05      ges
1         Cond   1  21 0.014 0.907       0.000288
2      PrePost   1  21 1.407 0.249       0.003000
3 Cond:PrePost   1  21 5.206 0.033     * 0.017000

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

## Males

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05      ges
1         Cond   1   7 0.198 0.670       0.010000
2      PrePost   1   7 4.505 0.071       0.028000
3 Cond:PrePost   1   7 0.022 0.885       0.000121

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

5 rmANOVA WB

## All subjects

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05   ges
1         Cond   1  29 1.566 0.221       0.008
2      PrePost   1  29 2.072 0.161       0.003
3 Cond:PrePost   1  29 5.086 0.032     * 0.019

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

## Females

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05   ges
1         Cond   1  21 0.607 0.445       0.005
2      PrePost   1  21 0.850 0.367       0.003
3 Cond:PrePost   1  21 4.814 0.040     * 0.033

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

## Males

 Outliers 

 Normality assumption (p>.05) 

 Two-way rmANOVA 
ANOVA Table (type III tests)

        Effect DFn DFd     F     p p<.05   ges
1         Cond   1   7 1.735 0.229       0.021
2      PrePost   1   7 5.885 0.046     * 0.007
3 Cond:PrePost   1   7 0.414 0.540       0.001

 Effect of treatment at each time point 

 Pairwise comparisons between treatment groups 

 Effect of time at each level of treatment - One-way ANOVA 

 Pairwise comparisons between time points 

 Comparisons for treatment variable 

 Comparisons for time variable 
[[1]]

[[2]]

6 Wilcoxon paired on Order of Conditions - OXT

## Whole Sample - Poz first, Neg second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Whole Sample - Neg first, Poz second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Females - Poz first, Neg second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Females - Neg first, Poz second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

7 Wilcoxon paired on Order of Conditions - Stres

## Whole Sample - Poz first, Neg second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Whole Sample - Neg first, Poz second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Females - Poz first, Neg second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Females - Neg first, Poz second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

8 Wilcoxon paired on Order of Conditions - WB

## Whole Sample - Poz first, Neg second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Whole Sample - Neg first, Poz second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Females - Poz first, Neg second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]

## Females - Neg first, Poz second

 Summary statistics 

 Wilcoxon signed rank test on paired samples 

 Effect size 
[[1]]

[[2]]



9 Session Info

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

Matrix products: default

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

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

other attached packages:
 [1] rlang_0.4.6        rstatix_0.5.0      rio_0.5.16         summarytools_0.8.8 DT_0.5             ggpubr_0.2.5       magrittr_1.5       broom_0.5.6       
 [9] papaja_0.1.0.9842  psych_1.9.12.31    forcats_0.5.0      stringr_1.4.0      dplyr_0.8.5        purrr_0.3.3        readr_1.3.1        tidyr_1.0.2       
[17] tibble_3.0.0       ggplot2_3.3.0      tidyverse_1.3.0    pacman_0.5.1      

loaded via a namespace (and not attached):
 [1] nlme_3.1-140       bitops_1.0-6       matrixStats_0.54.0 fs_1.4.1           lubridate_1.7.4    httr_1.4.1         ggsci_2.9          tools_3.6.1       
 [9] backports_1.1.6    R6_2.4.1           DBI_1.0.0          colorspace_1.4-1   withr_2.1.2        tidyselect_1.0.0   mnormt_1.5-6       curl_4.3          
[17] compiler_3.6.1     cli_2.0.2          rvest_0.3.5        xml2_1.3.1         sandwich_2.5-0     labeling_0.3       scales_1.1.0       mvtnorm_1.1-0     
[25] digest_0.6.25      foreign_0.8-71     pkgconfig_2.0.3    htmltools_0.4.0    dbplyr_1.4.3       htmlwidgets_1.5.1  readxl_1.3.1       rstudioapi_0.11   
[33] pryr_0.1.4         shiny_1.2.0        farver_2.0.3       generics_0.0.2     zoo_1.8-4          jsonlite_1.6.1     crosstalk_1.0.0    zip_1.0.0         
[41] car_3.0-7          RCurl_1.95-4.11    modeltools_0.2-22  rapportools_1.0    Matrix_1.2-17      Rcpp_1.0.4.6       munsell_0.5.0      fansi_0.4.1       
[49] abind_1.4-5        lifecycle_0.2.0    multcomp_1.4-8     stringi_1.4.6      yaml_2.2.1         carData_3.0-2      MASS_7.3-51.4      plyr_1.8.6        
[57] grid_3.6.1         parallel_3.6.1     promises_1.0.1     crayon_1.3.4       lattice_0.20-38    splines_3.6.1      haven_2.2.0        pander_0.6.3      
[65] hms_0.5.3          knitr_1.28         pillar_1.4.3       ggsignif_0.4.0     stats4_3.6.1       codetools_0.2-16   reprex_0.3.0       glue_1.4.0        
[73] data.table_1.12.8  modelr_0.1.6       vctrs_0.2.4        httpuv_1.4.5       cellranger_1.1.0   gtable_0.3.0       assertthat_0.2.1   xfun_0.13         
[81] openxlsx_4.1.0     coin_1.2-2         mime_0.9           xtable_1.8-4       later_0.7.5        survival_2.44-1.1  TH.data_1.0-9      ellipsis_0.3.0    
 

A work by Claudiu Papasteri

 

LS0tDQp0aXRsZTogIjxicj4gTy4yIFJlcG9ydCAtIFJldmlldyIgDQpzdWJ0aXRsZTogIkZvY3VzIG9uIE9YVCBieSBHZW5kZXIiDQphdXRob3I6ICI8YnI+IENsYXVkaXUgUGFwYXN0ZXJpIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJW0gJVknKWAiDQpvdXRwdXQ6IA0KICAgIGh0bWxfbm90ZWJvb2s6DQogICAgICAgICAgIyBzZWxmX2NvbnRhaW5lZDogbm8NCiAgICAgICAgICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgICAgICAgICAgdG9jOiB0cnVlDQogICAgICAgICAgICB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgICAgICAgICAgdGhlbWU6IHNwYWNlbGFiDQogICAgICAgICAgICBoaWdobGlnaHQ6IHRhbmdvDQogICAgICAgICAgICBmb250LWZhbWlseTogQXJpYWwNCiAgICAgICAgICAgIGZpZ193aWR0aDogMTANCiAgICAgICAgICAgIGZpZ19oZWlnaHQ6IDkNCiAgICAgIyBwZGZfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgIyB0b2M6IHRydWUNCiAgICAgICAgICAgICMgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICAjIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgICAgICAgICAgIyBmb250c2l6ZTogMTFwdA0KICAgICAgICAgICAgIyBnZW9tZXRyeTogbWFyZ2luPTFpbg0KICAgICAgICAgICAgIyBmaWdfd2lkdGg6IDcNCiAgICAgICAgICAgICMgZmlnX2hlaWdodDogNg0KICAgICAgICAgICAgIyBmaWdfY2FwdGlvbjogdHJ1ZQ0KICAgICMgZ2l0aHViX2RvY3VtZW50OiANCiAgICAgICAgICAgICMgdG9jOiB0cnVlDQogICAgICAgICAgICAjIHRvY19kZXB0aDogMg0KICAgICAgICAgICAgIyBodG1sX3ByZXZpZXc6IGZhbHNlDQogICAgICAgICAgICAjIGZpZ193aWR0aDogNQ0KICAgICAgICAgICAgIyBmaWdfaGVpZ2h0OiA1DQogICAgICAgICAgICAjIGRldjoganBlZw0KLS0tDQoNCg0KPCEtLSBTZXR1cCAtLT4NCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMga2ludHIgb3B0aW9ucw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBjb21tZW50ID0gIiMiLA0KICBjb2xsYXBzZSA9IFRSVUUsDQogIGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgY2FjaGUgPSBUUlVFICAgICAgICMgZWNobyA9IEZhbHNlIGZvciBnaXRodWJfZG9jdW1lbnQsIGJ1dCB3aWxsIGJlIGZvbGRlZCBpbiBodG1sX25vdGVib29rDQopDQoNCiMgR2VuZXJhbCBSIG9wdGlvbnMgYW5kIGluZm8NCnNldC5zZWVkKDExMSkgICAgICAgICAgICAgICAjIGluIGNhc2Ugd2UgdXNlIHJhbmRvbWl6ZWQgcHJvY2VkdXJlcyAgICAgICANCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAgICAgICAjIHBvc2l0aXZlIHZhbHVlcyBiaWFzIHRvd2FyZHMgZml4ZWQgYW5kIG5lZ2F0aXZlIHRvd2FyZHMgc2NpZW50aWZpYyBub3RhdGlvbg0KDQojIExvYWQgcGFja2FnZXMNCmlmICghcmVxdWlyZSgicGFjbWFuIikpIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQpwYWNrYWdlcyA8LSBjKA0KICAidGlkeXZlcnNlIiwgICAgICAjIGJlc3QgdGhpbmcgdGhhdCBoYXBwZW5kIHRvIG1lDQogICJwc3ljaCIsICAgICAgICAgICMgZ2VuZXJhbCBwdXJwb3NlIHRvb2xib3ggZm9yIHBlcnNvbmFsaXR5LCBwc3ljaG9tZXRyaWMgdGhlb3J5IGFuZCBleHBlcmltZW50YWwgcHN5Y2hvbG9neQ0KICAicGFwYWphIiwgICAgICAgICAjIGZvciBBUEEgc3R5bGUNCiAgImJyb29tIiwgICAgICAgICAgIyBmb3IgdGlkeSBtb2RlbGxpbmcNCiAgImdncGxvdDIiLCAgICAgICAgIyBiZXN0IHBsb3RzDQogICJnZ3B1YnIiLCAgICAgICAgICMgZ2dwbG90MiB0byBwdWJsaWNhdGlvbiBxdWFsaXR5DQogICJEVCIsICAgICAgICAgICAgICMgbmljZSBzZWFyY2hhYmxlIGFuZCBkb3dubG9hZGFibGUgdGFibGVzDQogICJzdW1tYXJ5dG9vbHMiLA0KICAicmlvIiwNCiAgImdncHViciIsDQogICJyc3RhdGl4IiwNCiAgInJsYW5nIg0KICAjICwgLi4uDQopDQppZiAoIXJlcXVpcmUoInBhY21hbiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KcGFjbWFuOjpwX2xvYWQoY2hhciA9IHBhY2thZ2VzKQ0KDQojIFRoZW1lcyBmb3IgZ2dwbG90MiBwbG90aW5nIChoZXJlIHVzZWQgQVBBIHN0eWxlKQ0KdGhlbWVfc2V0KHRoZW1lX2FwYSgpKQ0KYGBgDQoNCg0KDQo8IS0tIFJlcG9ydCAtLT4NCg0KDQojIFJlYWQgYW5kIE1lcmdlDQoNCg0KYGBge3IgcmVhZF9tZXJnZSwgcmVzdWx0cz0nYXNpcyd9DQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQojIFJlYWQgYW5kIE1lcmdlDQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQp3ZCA8LSAiRTovQ2luZXRpYyBpZGVpIG5vaS9FWFBFUklNRU5URSBPR0wgRnJvbnRpZXJzIChPLjIgJiBPLjAuMyAmIE8uMC4yKSINCnNldHdkKHdkKQ0KDQpEYXRhVHJ1c3QgPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKHdkLCAiTy4yIFJFWlVMVEFURVxcTy4yIERhdGUgUHJlbHVjcmFyZVNQU1MgY3UgTkVPIHNpIFNUQUkiLCAiTy4yIERhdGUgcHQgVHJ1c3QgQlVOIGN1IE5FTyBzaSBTVEFJWS54bHN4IikpDQpEYXRhREcgPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKHdkLCAiTy4yIFJFWlVMVEFURVxcTy4yIERhdGUgUHJlbHVjcmFyZVNQU1MgY3UgTkVPIHNpIFNUQUkiLCAiTy4yIERhdGUgcHQgREcgQlVOIGN1IE5FTyBzaSBTVEFJWS54bHN4IikpDQpEYXRhVkFTIDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aCh3ZCwgIk8uMiBSRVpVTFRBVEVcXE8uMiBWQVMsSU9TIiwgIk8uMiBEYXRlIFByZWx1Y3JhcmVTUFNTLnhsc3giKSkNCkRhdGFCSU8gPC0gcmlvOjppbXBvcnQoZmlsZS5wYXRoKHdkLCAiTy4yIEJJTyIsICJPLjIgT3ggc2kgQ29ydGl6b2wueGxzeCIpKQ0KICANCkRhdGFfbWVyZ2UxIDwtIG1lcmdlKERhdGFWQVMsIERhdGFUcnVzdCkgIA0KRGF0YV9tZXJnZTIgPC0gbWVyZ2UoRGF0YV9tZXJnZTEsIERhdGFERykgDQpEYXRhX21lcmdlMyA8LSBtZXJnZShEYXRhX21lcmdlMiwgRGF0YUJJTykNCg0KRGF0YSA8LSBEYXRhX21lcmdlMw0KDQp0ZXN0X25hbWVzIDwtIHVuaXF1ZSh1bmxpc3QobGFwcGx5KGxpc3QoRGF0YVRydXN0LCBEYXRhREcsIERhdGFWQVMsIERhdGFCSU8pLCBuYW1lcykpKQ0KbWVyZ2VfbmFtZXMgPC0gbmFtZXMoRGF0YSkNCg0KaWYoaWRlbnRpY2FsKG1lcmdlX25hbWVzW29yZGVyKG1lcmdlX25hbWVzKV0sIHRlc3RfbmFtZXNbb3JkZXIodGVzdF9uYW1lcyldKSl7ICAgICMgdGhlIG9yZGVyIG1hdHRlcnMgaW4gaWRlbnRpY2FsKCkNCiAgY2F0KCIqKk1lcmdlIHdhcyBzdWNjZXNmdWwqKiIpDQogIHJtKCJEYXRhX21lcmdlMSIsICJEYXRhX21lcmdlMiIsICJEYXRhX21lcmdlMyIsICJEYXRhQklPIiwgIkRhdGFERyIsICJEYXRhVHJ1c3QiLCAiRGF0YVZBUyIsICJ0ZXN0X25hbWVzIiwgIm1lcmdlX25hbWVzIikNCn1lbHNlIGNhdCgiKipNZXJnZSB1bnN1Y2Nlc2Z1bCoqIikgDQoNCg0KIyBHZW5kZXIgRGF0YWZyYW1lDQpEYXRhX0dlbiA8LSByaW86OmltcG9ydChmaWxlLnBhdGgod2QsICJHZW4gdmFyc3RhIE8wMyBPMDIgTzIueGxzeCIpLCB3aGljaCA9ICJPLjIiKQ0KDQpEYXRhX0dlbl9tZXJnZWQgPC0gDQogIERhdGEgJT4lDQogIHRpZHlyOjpzZXBhcmF0ZShJbmRpY2F0aXYsICBjKCJJRF90YWciLCAiSUQiLCAic3R1ZHlfdGFnIiksICJcXHMrIikgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc3BsaXQgb24gd2hpdGUgc3BhY2UNCiAgc2VsZWN0KC1jKCJJRF90YWciLCAic3R1ZHlfdGFnIikpICU+JQ0KICBtdXRhdGUoSUQgPSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihJRCkpKSAlPiUNCiAgZHBseXI6OmxlZnRfam9pbiguLCBEYXRhX0dlbiwgYnkgPSBjKCJJRCIpKSAlPiUNCiAgc2VsZWN0KDE6NywgR2VuLCBWYXJzdGEsIGV2ZXJ5dGhpbmcoKSkNCg0KRGF0YV9HZW5fbWVyZ2VkX2xvbmcgPC0NCiAgRGF0YV9HZW5fbWVyZ2VkICU+JQ0KICBkcGx5cjo6c2VsZWN0KElELCBFeGVyY2l0aXVsLCBHZW4sIHN0YXJ0c193aXRoKCJWYXMiKSwgc3RhcnRzX3dpdGgoIk94IikpICU+JQ0KICBkcGx5cjo6cmVuYW1lKFZhc1NfcHJlX1BveiA9IFZhc1NfcHJlUG96LA0KICAgICAgICAgICAgICAgIFZhc0JfcHJlX1BveiA9IFZhc0JfcHJlUG96LA0KICAgICAgICAgICAgICAgIFZhc1NfcG9zdF9Qb3ogPSBWYXNTX3Bvc3RQb3osDQogICAgICAgICAgICAgICAgVmFzQl9wb3N0X1BveiA9IFZhc0JfcG9zdFBveiwNCiAgICAgICAgICAgICAgICBWYXNTX3ByZV9OZWcgPSBWYXNTX3ByZU5lZywNCiAgICAgICAgICAgICAgICBWYXNCX3ByZV9OZWcgPSBWYXNCX3ByZU5lZywNCiAgICAgICAgICAgICAgICBWYXNTX3Bvc3RfTmVnID0gVmFzU19wb3N0TmVnLA0KICAgICAgICAgICAgICAgIFZhc0JfcG9zdF9OZWcgPSBWYXNCX3Bvc3ROZWcpICU+JQ0KICBwaXZvdF9sb25nZXIoLWMoSUQsIEV4ZXJjaXRpdWwsIEdlbiksIG5hbWVzX3NlcCA9ICJfIiwgbmFtZXNfdG8gPSBjKCJWYXJzIiwgIlByZVBvc3QiLCAiQ29uZCIpLCB2YWx1ZXNfdG8gPSAiVmFscyIpICU+JQ0KICByc3RhdGl4Ojpjb252ZXJ0X2FzX2ZhY3RvcihJRCwgRXhlcmNpdGl1bCwgR2VuLCBWYXJzLCBQcmVQb3N0LCBDb25kKQ0KDQoNCg0KRGF0YV9mZW0gPC0gDQogIERhdGFfR2VuX21lcmdlZF9sb25nICU+JQ0KICBmaWx0ZXIoR2VuID09ICJGIikNCg0KRGF0YV9tYXNjIDwtIA0KICBEYXRhX0dlbl9tZXJnZWRfbG9uZyAlPiUNCiAgZmlsdGVyKEdlbiA9PSAiTSIpDQpgYGANCg0KPCEtLQ0KIyBEZXJpdmUgbmV3IHZhcmlhYmxlcw0KDQpgYGB7ciBkZXJpdmVfdmFyLCBoaWRlPVRSVUV9DQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQojIERlcml2ZSBuZXcgdmFyaWFibGVzDQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQpEYXRhJERfVmFzU19Qb3ogPC0gRGF0YVssICJWYXNTX3Bvc3RQb3oiXSAtIERhdGFbLCAiVmFzU19wcmVQb3oiXSANCkRhdGEkRF9WYXNTX05lZyA8LSBEYXRhWywgIlZhc1NfcG9zdE5lZyJdIC0gRGF0YVssICJWYXNTX3ByZU5lZyJdDQpEYXRhJERfVmFzQl9Qb3ogPC0gRGF0YVssICJWYXNCX3Bvc3RQb3oiXSAtIERhdGFbLCAiVmFzQl9wcmVQb3oiXSANCkRhdGEkRF9WYXNCX05lZyA8LSBEYXRhWywgIlZhc0JfcG9zdE5lZyJdIC0gRGF0YVssICJWYXNCX3ByZU5lZyJdDQpEYXRhJERfSU9TX1BveiA8LSBEYXRhWywgIklPU19wb3N0UG96Il0gLSBEYXRhWywgIklPU19wcmVQb3oiXSANCkRhdGEkRF9JT1NfTmVnIDwtIERhdGFbLCAiSU9TX3Bvc3ROZWciXSAtIERhdGFbLCAiSU9TX3ByZU5lZyJdDQoNCkRhdGEkRF9TYW0xX1BveiA8LSBEYXRhWywgIlNhbTFfcG9zdFBveiJdIC0gRGF0YVssICJTYW0xX3ByZVBveiJdIA0KRGF0YSREX1NhbTFfTmVnIDwtIERhdGFbLCAiU2FtMV9wb3N0TmVnIl0gLSBEYXRhWywgIlNhbTFfcHJlTmVnIl0NCkRhdGEkRF9TYW0yX1BveiA8LSBEYXRhWywgIlNhbTJfcG9zdFBveiJdIC0gRGF0YVssICJTYW0yX3ByZVBveiJdIA0KRGF0YSREX1NhbTJfTmVnIDwtIERhdGFbLCAiU2FtMl9wb3N0TmVnIl0gLSBEYXRhWywgIlNhbTJfcHJlTmVnIl0NCkRhdGEkRF9TYW0zX1BveiA8LSBEYXRhWywgIlNhbTNfcG9zdFBveiJdIC0gRGF0YVssICJTYW0zX3ByZVBveiJdIA0KRGF0YSREX1NhbTNfTmVnIDwtIERhdGFbLCAiU2FtM19wb3N0TmVnIl0gLSBEYXRhWywgIlNhbTNfcHJlTmVnIl0NCg0KRGF0YSREX0RHX1BveiA8LSBEYXRhWywgIkRHX3Bvc3RQb3pUb3QiXSAtIERhdGFbLCAiREdfcHJlUG96VG90Il0gDQpEYXRhJERfREdfTmVnIDwtIERhdGFbLCAiREdfcG9zdE5lZ1RvdCJdIC0gRGF0YVssICJER19wcmVOZWdUb3QiXQ0KDQpEYXRhJERfVHJ1c3RNaW5fUG96IDwtIERhdGFbLCAiVHJ1c3RNaW5Qb3pQb3N0Il0gLSBEYXRhWywgIlRydXN0TWluUG96UHJlIl0gDQpEYXRhJERfVHJ1c3RNaW5fTmVnIDwtIERhdGFbLCAiVHJ1c3RNaW5OZWdQb3N0Il0gLSBEYXRhWywgIlRydXN0TWluTmVnUHJlIl0NCkRhdGEkRF9UcnVzdFRvdF9Qb3ogPC0gRGF0YVssICJUcnVzdFRvdFBvelBvc3QiXSAtIERhdGFbLCAiVHJ1c3RUb3RQb3pQcmUiXSANCkRhdGEkRF9UcnVzdFRvdF9OZWcgPC0gRGF0YVssICJUcnVzdFRvdE5lZ1Bvc3QiXSAtIERhdGFbLCAiVHJ1c3RUb3ROZWdQcmUiXQ0KDQpEYXRhJERfQ29ydF9Qb3ogPC0gRGF0YVssICJDb3J0X3Bvc3RfUG96Il0gLSBEYXRhWywgIkNvcnRfcHJlX1BveiJdIA0KRGF0YSREX0NvcnRfTmVnIDwtIERhdGFbLCAiQ29ydF9wb3N0X05lZyJdIC0gRGF0YVssICJDb3J0X3ByZV9OZWciXQ0KRGF0YSREX094X1BveiA8LSBEYXRhWywgIk94X3Bvc3RfUG96Il0gLSBEYXRhWywgIk94X3ByZV9Qb3oiXSANCkRhdGEkRF9PeF9OZWcgPC0gRGF0YVssICJPeF9wb3N0X05lZyJdIC0gRGF0YVssICJPeF9wcmVfTmVnIl0NCmBgYA0KDQotLT4NCg0KIyMgRGF0YXNldCAtIExvbmcgRm9ybWF0DQoNCmBgYHtyIGRmX2V4Y2VsX2xvbmd9DQpEYXRhX0dlbl9tZXJnZWRfbG9uZyAlPiUNCiAgICBEVDo6ZGF0YXRhYmxlKA0KICAgICAgZXh0ZW5zaW9ucyA9ICdCdXR0b25zJywNCiAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCwNCiAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFg9JzUwMHB4JywNCiAgICAgICAgICAgICAgICAgICAgIGRvbSA9ICdCZnJ0aXAnLA0KICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2V4Y2VsJywgImNzdiIpKSkNCmBgYA0KDQoNCiMjIERhdGFzZXQgLSBXaWRlIEZvcm1hdA0KDQpgYGB7ciBkZl9leGNlbF93aWRlfQ0KRGF0YV9HZW5fbWVyZ2VkICU+JQ0KICBkcGx5cjo6c2VsZWN0KC0yKSAlPiUNCiAgICBEVDo6ZGF0YXRhYmxlKA0KICAgICAgZXh0ZW5zaW9ucyA9ICdCdXR0b25zJywNCiAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCwNCiAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFg9JzUwMHB4JywNCiAgICAgICAgICAgICAgICAgICAgIGRvbSA9ICdCZnJ0aXAnLA0KICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2V4Y2VsJywgImNzdiIpKSkNCmBgYA0KDQoNCiMgRGVmaW5lIGZ1bmN0aW9ucw0KDQpgYGB7ciBkZWZfZnVuY19ybUFOT1ZBfQ0KIyBEZWZpbmUgRnVuY3Rpb24gZm9yIFR3by13YXkgcm1BTk9WQQ0KIyBsaWJyYXJ5KHRpZHl2ZXJzZSkNCiMgbGlicmFyeShnZ3B1YnIpDQojIGxpYnJhcnkocnN0YXRpeCkNCiMgbGlicmFyeShybGFuZykNCg0KdHdfcm1BTk9WQV9mdW5jIDwtIA0KICBmdW5jdGlvbihkYXRhLCBpZF92YXIsIGNvbmRfdmFyLCB0aW1lX3ZhciwgdmFsdWVfdmFyLCANCiAgICAgICAgICAgYXNzdW1fY2hlY2sgPSBUUlVFLCBwb3N0aG9jX3NpZ19pbnRlcmFjID0gRkFMU0UsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IEZBTFNFLA0KICAgICAgICAgICBwX2FkanVzdF9tZXRob2QgPSAiYm9uZmVycm9uaSIpew0KICANCiAgIyBpbnB1dCBkYXRhZnJhbWUgbmVlZHMgdG8gaGF2ZSBjb2x1bW5zIG5hbWVzIGRpZmZyZW50IGZyb20gInZhcmlhYmxlIiBhbmQgInZhbHVlIiBiZWNhdXNlIGl0IGNvbGxpZGVzIHdpdGggcnN0YXRpeDo6c2hhcGlyb190ZXN0DQogICAgDQogIGlkX3Zhcl9lbnEgPC0gcmxhbmc6OmVucXVvKGlkX3ZhcikgIA0KICBjb25kX3Zhcl9lbnEgPC0gcmxhbmc6OmVucXVvKGNvbmRfdmFyKQ0KICBjb25kX3Zhcl9uYW1lIDwtIHJsYW5nOjphc19uYW1lKGNvbmRfdmFyX2VucSkNCiAgdGltZV92YXJfZW5xIDwtIHJsYW5nOjplbnF1byh0aW1lX3ZhcikNCiAgdGltZV92YXJfbmFtZSA8LSBybGFuZzo6YXNfbmFtZSh0aW1lX3Zhcl9lbnEpDQogIHZhbHVlX3Zhcl9lbnEgPC0gcmxhbmc6OmVucXVvKHZhbHVlX3ZhcikNCiAgdmFsdWVfdmFyX25hbWUgPC0gcmxhbmc6OmFzX25hbWUodmFsdWVfdmFyX2VucSkNCiAgICANCiAgIyBBc3N1bXB0aW9ucw0KICBpZihhc3N1bV9jaGVjayl7DQogICAgY2F0KCJcbiBPdXRsaWVycyBcbiIpDQogICAgZGF0YSAlPiUNCiAgICAgIGRwbHlyOjpncm91cF9ieSghIWNvbmRfdmFyX2VucSwgISF0aW1lX3Zhcl9lbnEpICU+JQ0KICAgICAgcnN0YXRpeDo6aWRlbnRpZnlfb3V0bGllcnMoISF2YWx1ZV92YXJfZW5xKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBvdXRsaWVycyAobmVlZHMgdG8gYmUgMCkNCiAgICAgIHByaW50KCkNCiAgICANCiAgICBjYXQoIlxuIE5vcm1hbGl0eSBhc3N1bXB0aW9uIChwPi4wNSkgXG4iKQ0KICAgIGRhdGEgJT4lDQogICAgICBkcGx5cjo6Z3JvdXBfYnkoISFjb25kX3Zhcl9lbnEsICEhdGltZV92YXJfZW5xKSAlPiUNCiAgICAgIHJzdGF0aXg6OnNoYXBpcm9fdGVzdCghIXZhbHVlX3Zhcl9lbnEpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG5vcm1hbGl0eSBhc3N1bXB0aW9uIChwPi4wNSkNCiAgICAgIHByaW50KCkNCiAgICANCiAgICBxcV9wbG90IDwtIA0KICAgICAgZ2dwdWJyOjpnZ3FxcGxvdChkYXRhID0gZGF0YSwgdmFsdWVfdmFyX25hbWUsIGdndGhlbWUgPSB0aGVtZV9idygpLCB0aXRsZSA9ICJRUSBQbG90IikgKw0KICAgICAgICBnZ3Bsb3QyOjpmYWNldF9ncmlkKHZhcnMoISF0aW1lX3Zhcl9lbnEpLCB2YXJzKCEhY29uZF92YXJfZW5xKSwgbGFiZWxsZXIgPSAibGFiZWxfYm90aCIpICAgICMgUVEgcGxvdA0KICB9DQogIA0KICAjIFR3by13YXkgcm1BTk9WQSAtIGNoZWNrIGZvciBpbnRlcmFjdGlvbiAoZXguIEYoMiwgMjIpID0gMzAuNCwgcCA8IDAuMDAwMSkNCiAgY2F0KCJcbiBUd28td2F5IHJtQU5PVkEgXG4iKQ0KICByZXNfYW92IDwtIGFub3ZhX3Rlc3QoICAgICAgICAgICAgICAgICAgICAgICAgICMgYXV0b21hdGljYWxseSBkb2VzIHNwaGVyaWNpdHkgTWF1Y2hseeKAmXMgdGVzdA0KICAgIGRhdGEgPSBkYXRhLCBkdiA9ICEhdmFsdWVfdmFyX2VucSwgd2lkID0gISFpZF92YXJfZW5xLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgd2l0aGluID0gYyghIWNvbmRfdmFyX2VucSwgISF0aW1lX3Zhcl9lbnEpDQogICkNCiAgZ2V0X2Fub3ZhX3RhYmxlKHJlc19hb3YpICU+JSAgIyBnZXM6IEdyZWVuaG91c2UtR2Vpc3NlciBzcGhlcmljaXR5IGNvcnJlY3Rpb24gaXMgYXV0b21hdGljYWxseSBhcHBsaWVkIHRvIGZhY3RvcnMgdmlvbGF0aW5nIHRoZSBzcGhlcmljaXR5IGFzc3VtcHRpb24gIA0KICBwcmludCgpDQogIA0KICAjLSBQcm9jZWR1cmUgZm9yIGEgc2lnbmlmaWNhbnQgdHdvLXdheSBpbnRlcmFjdGlvbiAtDQogIGlmKHBvc3Rob2Nfc2lnX2ludGVyYWMpew0KICAgIGNhdCgiXG4gRWZmZWN0IG9mIHRyZWF0bWVudCBhdCBlYWNoIHRpbWUgcG9pbnQgXG4iKQ0KICAgIG9uZV93YXkgPC0gDQogICAgICBkYXRhICU+JQ0KICAgICAgZ3JvdXBfYnkoISF0aW1lX3Zhcl9lbnEpICU+JQ0KICAgICAgYW5vdmFfdGVzdChkdiA9ICEhdmFsdWVfdmFyX2VucSwgd2lkID0gISFpZF92YXJfZW5xLCB3aXRoaW4gPSAhIWNvbmRfdmFyX2VucSkgJT4lDQogICAgICBnZXRfYW5vdmFfdGFibGUoKSAlPiUNCiAgICAgIGFkanVzdF9wdmFsdWUobWV0aG9kID0gImJvbmZlcnJvbmkiKQ0KICAgIG9uZV93YXkgJT4lIHByaW50KCkNCiAgICANCiAgICBjYXQoIlxuIFBhaXJ3aXNlIGNvbXBhcmlzb25zIGJldHdlZW4gdHJlYXRtZW50IGdyb3VwcyBcbiIpDQogICAgcHdjIDwtDQogICAgICBkYXRhICU+JQ0KICAgICAgZ3JvdXBfYnkoISF0aW1lX3Zhcl9lbnEpICU+JQ0KICAgICAgcGFpcndpc2VfdF90ZXN0KA0KICAgICAgICBhcy5mb3JtdWxhKHBhc3RlMCh2YWx1ZV92YXJfbmFtZSwgIiB+ICIsIGNvbmRfdmFyX25hbWUpKSwNCiAgICAgICAgcGFpcmVkID0gVFJVRSwNCiAgICAgICAgcC5hZGp1c3QubWV0aG9kID0gcF9hZGp1c3RfbWV0aG9kDQogICAgICApDQogICAgcHdjICU+JSBwcmludCgpDQoNCiAgICBjYXQoIlxuIEVmZmVjdCBvZiB0aW1lIGF0IGVhY2ggbGV2ZWwgb2YgdHJlYXRtZW50IC0gT25lLXdheSBBTk9WQSBcbiIpDQogICAgb25lX3dheTIgPC0NCiAgICAgIGRhdGEgJT4lDQogICAgICBncm91cF9ieSghIWNvbmRfdmFyX2VucSkgJT4lDQogICAgICBhbm92YV90ZXN0KGR2ID0gISF2YWx1ZV92YXJfZW5xLCB3aWQgPSAhIWlkX3Zhcl9lbnEsIHdpdGhpbiA9ICEhdGltZV92YXJfZW5xKSAlPiUNCiAgICAgIGdldF9hbm92YV90YWJsZSgpICU+JQ0KICAgICAgYWRqdXN0X3B2YWx1ZShtZXRob2QgPSBwX2FkanVzdF9tZXRob2QpDQogICAgb25lX3dheTIgICU+JSBwcmludCgpDQogICAgY2F0KCJcbiBQYWlyd2lzZSBjb21wYXJpc29ucyBiZXR3ZWVuIHRpbWUgcG9pbnRzIFxuIikNCiAgICBwd2MyIDwtDQogICAgICBkYXRhICU+JQ0KICAgICAgZ3JvdXBfYnkoISFjb25kX3Zhcl9lbnEpICU+JQ0KICAgICAgcGFpcndpc2VfdF90ZXN0KA0KICAgICAgICBhcy5mb3JtdWxhKHBhc3RlMCh2YWx1ZV92YXJfbmFtZSwgIiB+ICIsIHRpbWVfdmFyX25hbWUpKSwgICAgICMgcGFzdGUgZm9ybXVsYSwgbm90IHF1b3N1cmUNCiAgICAgICAgcGFpcmVkID0gVFJVRSwNCiAgICAgICAgcC5hZGp1c3QubWV0aG9kID0gcF9hZGp1c3RfbWV0aG9kDQogICAgICApDQogICAgcHdjMiAgJT4lIHByaW50KCkNCiAgfQ0KICANCiAgIy0gUHJvY2VkdXJlIGZvciBub24tc2lnbmlmaWNhbnQgdHdvLXdheSBpbnRlcmFjdGlvbi0gDQogICMgSWYgdGhlIGludGVyYWN0aW9uIGlzIG5vdCBzaWduaWZpY2FudCwgeW91IG5lZWQgdG8gaW50ZXJwcmV0IHRoZSBtYWluIGVmZmVjdHMgZm9yIGVhY2ggb2YgdGhlIHR3byB2YXJpYWJsZXM6IHRyZWF0bWVudCBhbmQgdGltZS4NCiAgaWYocG9zdGhvY19uc19pbnRlcmFjKXsNCiAgICBjYXQoIlxuIENvbXBhcmlzb25zIGZvciB0cmVhdG1lbnQgdmFyaWFibGUgXG4iKQ0KICAgIHB3Y19jb25kIDwtDQogICAgICBkYXRhICU+JQ0KICAgICAgcGFpcndpc2VfdF90ZXN0KA0KICAgICAgICBhcy5mb3JtdWxhKHBhc3RlMCh2YWx1ZV92YXJfbmFtZSwgIiB+ICIsIGNvbmRfdmFyX25hbWUpKSwgICAgICMgcGFzdGUgZm9ybXVsYSwgbm90IHF1b3N1cmUgICAgICAgICAgICAgDQogICAgICAgIHBhaXJlZCA9IFRSVUUsDQogICAgICAgIHAuYWRqdXN0Lm1ldGhvZCA9IHBfYWRqdXN0X21ldGhvZA0KICAgICAgKQ0KICAgIHB3Y19jb25kICU+JSBwcmludCgpDQogICAgY2F0KCJcbiBDb21wYXJpc29ucyBmb3IgdGltZSB2YXJpYWJsZSBcbiIpDQogICAgcHdjX3RpbWUgPC0NCiAgICAgIGRhdGEgJT4lIA0KICAgICAgcGFpcndpc2VfdF90ZXN0KA0KICAgICAgICBhcy5mb3JtdWxhKHBhc3RlMCh2YWx1ZV92YXJfbmFtZSwgIiB+ICIsIHRpbWVfdmFyX25hbWUpKSwgICAgICMgcGFzdGUgZm9ybXVsYSwgbm90IHF1b3N1cmUNCiAgICAgICAgcGFpcmVkID0gVFJVRSwNCiAgICAgICAgcC5hZGp1c3QubWV0aG9kID0gcF9hZGp1c3RfbWV0aG9kDQogICAgICApDQogICAgcHdjX3RpbWUgJT4lIHByaW50KCkNCiAgfQ0KICANCiAgIyBWaXN1YWxpemF0aW9uDQogIGJ4X3Bsb3QgPC0gDQogICAgZ2dib3hwbG90KGRhdGEsIHggPSB0aW1lX3Zhcl9uYW1lLCB5ID0gdmFsdWVfdmFyX25hbWUsDQogICAgY29sb3IgPSBjb25kX3Zhcl9uYW1lLCBwYWxldHRlID0gImpjbyIpDQogIHB3YyA8LSANCiAgICBwd2MgJT4lIA0KICAgIGFkZF94eV9wb3NpdGlvbih4ID0gdGltZV92YXJfbmFtZSkNCiAgYnhfcGxvdCA8LSANCiAgICBieF9wbG90ICsgDQogICAgc3RhdF9wdmFsdWVfbWFudWFsKHB3YywgdGlwLmxlbmd0aCA9IDAsIGhpZGUubnMgPSBUUlVFKSArDQogICAgbGFicygNCiAgICAgIHN1YnRpdGxlID0gZ2V0X3Rlc3RfbGFiZWwocmVzX2FvdiwgZGV0YWlsZWQgPSBUUlVFKSwNCiAgICAgIGNhcHRpb24gPSBnZXRfcHdjX2xhYmVsKHB3YykNCiAgICApDQogIA0KICBpZihhc3N1bV9jaGVjayl7IA0KICAgIGxpc3QocXFfcGxvdCwgYnhfcGxvdCkNCiAgfWVsc2V7DQogICAgYnhfcGxvdA0KICB9IA0KICANCn0NCg0KIyBleC4gLSBydW4gb24gbG9uZyBmb3JtYXQNCiMgdHdfcm1BTk9WQV9mdW5jKGRhdGEgPSBzZWxmZXN0ZWVtMiwgaWRfdmFyID0gaWQsIGNvbmRfdmFyID0gdHJlYXRtZW50LCB0aW1lX3ZhciA9IHRpbWUsIHZhbHVlX3ZhciA9IHNjb3JlcywgDQojICAgICAgICAgICAgICAgICBwb3N0aG9jX3NpZ19pbnRlcmFjID0gVFJVRSwgcG9zdGhvY19uc19pbnRlcmFjID0gVFJVRSkNCg0KYGBgDQoNCmBgYHtyIGRlZl9mdW5jX1dpbGNveG9ucGFpcmVkfQ0KIyMgV2lsY294b24gc2lnbmVkIHJhbmsgdGVzdCBvbiBwYWlyZWQgc2FtcGxlcw0KDQojIGxpYnJhcnkodGlkeXZlcnNlKQ0KIyBsaWJyYXJ5KGdncHVicikNCiMgbGlicmFyeShyc3RhdGl4KQ0KIyBsaWJyYXJ5KHJsYW5nKQ0KDQp3aWxjb3hvbl9wYWlyZWRfZnVuYyA8LSBmdW5jdGlvbihkYXRhLCBpZF92YXIsIHRpbWVfdmFyLCB2YWx1ZV92YXIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzdW1fY2hlY2sgPSBUUlVFKXsNCiAgDQogIGlkX3Zhcl9lbnEgPC0gcmxhbmc6OmVucXVvKGlkX3ZhcikgIA0KICBpZF92YXJfbmFtZSA8LSBybGFuZzo6YXNfbmFtZShpZF92YXJfZW5xKQ0KICB0aW1lX3Zhcl9lbnEgPC0gcmxhbmc6OmVucXVvKHRpbWVfdmFyKQ0KICB0aW1lX3Zhcl9uYW1lIDwtIHJsYW5nOjphc19uYW1lKHRpbWVfdmFyX2VucSkNCiAgdmFsdWVfdmFyX2VucSA8LSBybGFuZzo6ZW5xdW8odmFsdWVfdmFyKQ0KICB2YWx1ZV92YXJfbmFtZSA8LSBybGFuZzo6YXNfbmFtZSh2YWx1ZV92YXJfZW5xKQ0KICANCiAgY2F0KCJcbiBTdW1tYXJ5IHN0YXRpc3RpY3MgXG4iKQ0KICBkYXRhICU+JQ0KICAgIGdyb3VwX2J5KCEhdGltZV92YXJfZW5xKSAlPiUNCiAgICBnZXRfc3VtbWFyeV9zdGF0cyghIXZhbHVlX3Zhcl9lbnEsIHR5cGUgPSBjKCJjb21tb24iKSkgJT4lDQogICAgcHJpbnQoKSANCiAgDQogIGlmKGFzc3VtX2NoZWNrKXsgICMgVGhlIHRlc3QgYXNzdW1lcyB0aGF0IGRpZmZlcmVuY2VzIGJldHdlZW4gcGFpcmVkIHNhbXBsZXMgc2hvdWxkIGJlIGRpc3RyaWJ1dGVkIHN5bW1ldHJpY2FsbHkgYXJvdW5kIHRoZSBtZWRpYW4uDQogIGRhdGEyIDwtIA0KICAgIGRhdGEgJT4lIA0KICAgIGdyb3VwX2J5KCEhaWRfdmFyX2VucSkgJT4lIA0KICAgIG11dGF0ZShkaWZmZXJlbmNlcyA9ICEhdmFsdWVfdmFyX2VucSAtIGxhZyghIXZhbHVlX3Zhcl9lbnEpKQ0KDQogIGhpc3RfZGlmX3Bsb3QgPC0gZ2doaXN0b2dyYW0oZGF0YTIsIHggPSAiZGlmZmVyZW5jZXMiLCB5ID0gIi4uZGVuc2l0eS4uIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJzdGVlbGJsdWUiLCBhZGRfZGVuc2l0eSA9IFRSVUUpDQogIH0NCiAgDQogIGNhdCgiXG4gV2lsY294b24gc2lnbmVkIHJhbmsgdGVzdCBvbiBwYWlyZWQgc2FtcGxlcyBcbiIpDQogIHN0YXRfdGVzdCA8LSANCiAgICBkYXRhICAlPiUNCiAgICB3aWxjb3hfdGVzdChhcy5mb3JtdWxhKHBhc3RlMCh2YWx1ZV92YXJfbmFtZSwgIiB+ICIsIHRpbWVfdmFyX25hbWUpKSwgDQogICAgICAgICAgICAgICAgcGFpcmVkID0gVFJVRSkgJT4lDQogICAgYWRkX3NpZ25pZmljYW5jZSgpDQogIHN0YXRfdGVzdCAlPiUgcHJpbnQoKQ0KICANCiAgY2F0KCJcbiBFZmZlY3Qgc2l6ZSBcbiIpDQogIGVmX3NpemUgPC0NCiAgICBkYXRhICU+JQ0KICAgIHdpbGNveF9lZmZzaXplKGFzLmZvcm11bGEocGFzdGUwKHZhbHVlX3Zhcl9uYW1lLCAiIH4gIiwgdGltZV92YXJfbmFtZSkpLCANCiAgICAgICAgICAgICAgICAgICBwYWlyZWQgPSBUUlVFKQ0KICBlZl9zaXplICU+JSBwcmludCgpDQogIA0KICAjIFZpc3VhbGl6YXRpb24NCiAgYnhfcGxvdCA8LSBnZ3BhaXJlZChkYXRhLCB4ID0gdGltZV92YXJfbmFtZSwgeSA9IHZhbHVlX3Zhcl9uYW1lLCBpZCA9IGlkX3Zhcl9uYW1lLA0KICAgICAgICAgICAgICAgICAgICAgIHlsYWIgPSB2YWx1ZV92YXJfbmFtZSwgeGxhYiA9IHRpbWVfdmFyX25hbWUpDQogIA0KICBzdGF0X3Rlc3QgPC0gDQogICAgc3RhdF90ZXN0ICU+JSANCiAgICBhZGRfeHlfcG9zaXRpb24oeCA9IHRpbWVfdmFyX25hbWUpDQogIA0KICBieF9wbG90IDwtDQogICAgYnhfcGxvdCArIA0KICAgICAgc3RhdF9wdmFsdWVfbWFudWFsKHN0YXRfdGVzdCwgdGlwLmxlbmd0aCA9IDApICsNCiAgICAgIGxhYnMoc3VidGl0bGUgPSBnZXRfdGVzdF9sYWJlbChzdGF0X3Rlc3QsIGRldGFpbGVkID0gVFJVRSkpDQogIA0KICBpZihhc3N1bV9jaGVjayl7IA0KICAgIGxpc3QoaGlzdF9kaWZfcGxvdCwgYnhfcGxvdCkNCiAgfWVsc2V7DQogICAgYnhfcGxvdA0KICB9ICANCiAgDQp9DQpgYGANCg0KDQojIHJtQU5PVkEgT1hUDQoNCmBgYHtyIHJtQU5PVkFfb3h0LCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMH0NCmNhdCgiIyMgQWxsIHN1YmplY3RzIikNCkRhdGFfR2VuX21lcmdlZF9sb25nICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiT3giKSAlPiUNCiAgZHBseXI6OnJlbmFtZShPWFQgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lICAgICAgICAgICAgICAgICAgICAgIyBmb3IgY29tcGxldGUgY2FzZXMNCiAgdW5ncm91cCgpICU+JQ0KICB0d19ybUFOT1ZBX2Z1bmMoaWRfdmFyID0gSUQsIGNvbmRfdmFyID0gQ29uZCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBPWFQsIA0KICAgICAgICAgICAgICAgICAgcG9zdGhvY19zaWdfaW50ZXJhYyA9IFRSVUUsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IFRSVUUpDQoNCmNhdCgiIyMgRmVtYWxlcyIpDQpEYXRhX2ZlbSAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzKSAlPiUNCiAgZmlsdGVyKFZhcnMgPT0gIk94IikgJT4lDQogIGRwbHlyOjpyZW5hbWUoT1hUID0gVmFscykgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JSANCiAgZmlsdGVyKG4oKSA+IDMpICU+JSAgICAgICAgICAgICAgICAgICAgICMgZm9yIGNvbXBsZXRlIGNhc2VzDQogIHVuZ3JvdXAoKSAlPiUNCiAgdHdfcm1BTk9WQV9mdW5jKGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gUHJlUG9zdCwgdmFsdWVfdmFyID0gT1hULCANCiAgICAgICAgICAgICAgICAgIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KDQpjYXQoIiMjIE1hbGVzIikNCkRhdGFfbWFzYyAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzKSAlPiUNCiAgZmlsdGVyKFZhcnMgPT0gIk94IikgJT4lDQogIGRwbHlyOjpyZW5hbWUoT1hUID0gVmFscykgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JSANCiAgZmlsdGVyKG4oKSA+IDMpICU+JSAgICAgICAgICAgICAgICAgICAgICMgZm9yIGNvbXBsZXRlIGNhc2VzDQogIHVuZ3JvdXAoKSAlPiUNCiAgdHdfcm1BTk9WQV9mdW5jKGlkX3ZhciA9IElELCBjb25kX3ZhciA9IENvbmQsIHRpbWVfdmFyID0gUHJlUG9zdCwgdmFsdWVfdmFyID0gT1hULCANCiAgICAgICAgICAgICAgICAgIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KYGBgDQoNCiMgcm1BTk9WQSBTdHJlcw0KDQpgYGB7ciBybUFOT1ZBX3N0cmVzLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMH0NCmNhdCgiIyMgQWxsIHN1YmplY3RzIikNCkRhdGFfR2VuX21lcmdlZF9sb25nICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiVmFzUyIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKFZhc1MgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lICAgICAgICAgICAgICAgICAgICAgIyBmb3IgY29tcGxldGUgY2FzZXMNCiAgdW5ncm91cCgpICU+JQ0KICB0d19ybUFOT1ZBX2Z1bmMoaWRfdmFyID0gSUQsIGNvbmRfdmFyID0gQ29uZCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBWYXNTLCANCiAgICAgICAgICAgICAgICAgIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KDQpjYXQoIiMjIEZlbWFsZXMiKQ0KRGF0YV9mZW0gJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscykgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNTIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzUyA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUgICAgICAgICAgICAgICAgICAgICAjIGZvciBjb21wbGV0ZSBjYXNlcw0KICB1bmdyb3VwKCkgJT4lDQogIHR3X3JtQU5PVkFfZnVuYyhpZF92YXIgPSBJRCwgY29uZF92YXIgPSBDb25kLCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IFZhc1MsIA0KICAgICAgICAgICAgICAgICAgcG9zdGhvY19zaWdfaW50ZXJhYyA9IFRSVUUsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IFRSVUUpDQoNCmNhdCgiIyMgTWFsZXMiKQ0KRGF0YV9tYXNjICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiVmFzUyIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKFZhc1MgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lICAgICAgICAgICAgICAgICAgICAgIyBmb3IgY29tcGxldGUgY2FzZXMNCiAgdW5ncm91cCgpICU+JQ0KICB0d19ybUFOT1ZBX2Z1bmMoaWRfdmFyID0gSUQsIGNvbmRfdmFyID0gQ29uZCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBWYXNTLCANCiAgICAgICAgICAgICAgICAgIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KYGBgDQoNCiMgcm1BTk9WQSBXQg0KDQpgYGB7ciBybUFOT1ZBX3diLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMH0NCmNhdCgiIyMgQWxsIHN1YmplY3RzIikNCkRhdGFfR2VuX21lcmdlZF9sb25nICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiVmFzQiIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKFZhc0IgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lICAgICAgICAgICAgICAgICAgICAgIyBmb3IgY29tcGxldGUgY2FzZXMNCiAgdW5ncm91cCgpICU+JQ0KICB0d19ybUFOT1ZBX2Z1bmMoaWRfdmFyID0gSUQsIGNvbmRfdmFyID0gQ29uZCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBWYXNCLCANCiAgICAgICAgICAgICAgICAgIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KDQpjYXQoIiMjIEZlbWFsZXMiKQ0KRGF0YV9mZW0gJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscykgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNCIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzQiA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUgICAgICAgICAgICAgICAgICAgICAjIGZvciBjb21wbGV0ZSBjYXNlcw0KICB1bmdyb3VwKCkgJT4lDQogIHR3X3JtQU5PVkFfZnVuYyhpZF92YXIgPSBJRCwgY29uZF92YXIgPSBDb25kLCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IFZhc0IsIA0KICAgICAgICAgICAgICAgICAgcG9zdGhvY19zaWdfaW50ZXJhYyA9IFRSVUUsIHBvc3Rob2NfbnNfaW50ZXJhYyA9IFRSVUUpDQoNCmNhdCgiIyMgTWFsZXMiKQ0KRGF0YV9tYXNjICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiVmFzQiIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKFZhc0IgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lICAgICAgICAgICAgICAgICAgICAgIyBmb3IgY29tcGxldGUgY2FzZXMNCiAgdW5ncm91cCgpICU+JQ0KICB0d19ybUFOT1ZBX2Z1bmMoaWRfdmFyID0gSUQsIGNvbmRfdmFyID0gQ29uZCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBWYXNCLCANCiAgICAgICAgICAgICAgICAgIHBvc3Rob2Nfc2lnX2ludGVyYWMgPSBUUlVFLCBwb3N0aG9jX25zX2ludGVyYWMgPSBUUlVFKQ0KYGBgDQoNCg0KDQojIFdpbGNveG9uIHBhaXJlZCBvbiBPcmRlciBvZiBDb25kaXRpb25zIC0gT1hUDQoNCmBgYHtyIHdpbGxjb3hvbl9veHRfb3JkZXIsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9DQpjYXQoIiMjIFdob2xlIFNhbXBsZSAtIFBveiBmaXJzdCwgTmVnIHNlY29uZCIpDQpEYXRhX0dlbl9tZXJnZWRfbG9uZyAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzLCBFeGVyY2l0aXVsKSAlPiUNCiAgZmlsdGVyKEV4ZXJjaXRpdWwgPT0gIlBveml0aXYgLSBOZWdhdGl2IikgJT4lDQogIGZpbHRlcihWYXJzID09ICJPeCIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKE9YVCA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICB3aWxjb3hvbl9wYWlyZWRfZnVuYyhpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBPWFQsIGFzc3VtX2NoZWNrID0gVFJVRSkNCg0KY2F0KCIjIyBXaG9sZSBTYW1wbGUgLSBOZWcgZmlyc3QsIFBveiBzZWNvbmQiKQ0KRGF0YV9HZW5fbWVyZ2VkX2xvbmcgJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscywgRXhlcmNpdGl1bCkgJT4lDQogIGZpbHRlcihFeGVyY2l0aXVsID09ICJOZWdhdGl2IC0gUG96aXRpdiIpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiT3giKSAlPiUNCiAgZHBseXI6OnJlbmFtZShPWFQgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgd2lsY294b25fcGFpcmVkX2Z1bmMoaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgdmFsdWVfdmFyID0gT1hULCBhc3N1bV9jaGVjayA9IFRSVUUpDQoNCg0KDQpjYXQoIiMjIEZlbWFsZXMgLSBQb3ogZmlyc3QsIE5lZyBzZWNvbmQiKQ0KRGF0YV9mZW0gJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscywgRXhlcmNpdGl1bCkgJT4lDQogIGZpbHRlcihFeGVyY2l0aXVsID09ICJQb3ppdGl2IC0gTmVnYXRpdiIpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiT3giKSAlPiUNCiAgZHBseXI6OnJlbmFtZShPWFQgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgd2lsY294b25fcGFpcmVkX2Z1bmMoaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgdmFsdWVfdmFyID0gT1hULCBhc3N1bV9jaGVjayA9IFRSVUUpDQoNCmNhdCgiIyMgRmVtYWxlcyAtIE5lZyBmaXJzdCwgUG96IHNlY29uZCIpDQpEYXRhX2ZlbSAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzLCBFeGVyY2l0aXVsKSAlPiUNCiAgZmlsdGVyKEV4ZXJjaXRpdWwgPT0gIk5lZ2F0aXYgLSBQb3ppdGl2IikgJT4lDQogIGZpbHRlcihWYXJzID09ICJPeCIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKE9YVCA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICB3aWxjb3hvbl9wYWlyZWRfZnVuYyhpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBPWFQsIGFzc3VtX2NoZWNrID0gVFJVRSkNCg0KYGBgDQoNCiMgV2lsY294b24gcGFpcmVkIG9uIE9yZGVyIG9mIENvbmRpdGlvbnMgLSBTdHJlcw0KDQpgYGB7ciB3aWxsY294b25fc3RyZXNfb3JkZXIsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9DQpjYXQoIiMjIFdob2xlIFNhbXBsZSAtIFBveiBmaXJzdCwgTmVnIHNlY29uZCIpDQpEYXRhX0dlbl9tZXJnZWRfbG9uZyAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzLCBFeGVyY2l0aXVsKSAlPiUNCiAgZmlsdGVyKEV4ZXJjaXRpdWwgPT0gIlBveml0aXYgLSBOZWdhdGl2IikgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNTIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzUyA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICB3aWxjb3hvbl9wYWlyZWRfZnVuYyhpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBWYXNTLCBhc3N1bV9jaGVjayA9IFRSVUUpDQoNCmNhdCgiIyMgV2hvbGUgU2FtcGxlIC0gTmVnIGZpcnN0LCBQb3ogc2Vjb25kIikNCkRhdGFfR2VuX21lcmdlZF9sb25nICU+JQ0KICBzZWxlY3QoSUQsIFZhcnMsIFByZVBvc3QsIENvbmQsIFZhbHMsIEV4ZXJjaXRpdWwpICU+JQ0KICBmaWx0ZXIoRXhlcmNpdGl1bCA9PSAiTmVnYXRpdiAtIFBveml0aXYiKSAlPiUNCiAgZmlsdGVyKFZhcnMgPT0gIlZhc1MiKSAlPiUNCiAgZHBseXI6OnJlbmFtZShWYXNTID0gVmFscykgJT4lDQogIGRyb3BfbmEoKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JSANCiAgZmlsdGVyKG4oKSA+IDMpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIHdpbGNveG9uX3BhaXJlZF9mdW5jKGlkX3ZhciA9IElELCB0aW1lX3ZhciA9IFByZVBvc3QsIHZhbHVlX3ZhciA9IFZhc1MsIGFzc3VtX2NoZWNrID0gVFJVRSkNCg0KDQoNCmNhdCgiIyMgRmVtYWxlcyAtIFBveiBmaXJzdCwgTmVnIHNlY29uZCIpDQpEYXRhX2ZlbSAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzLCBFeGVyY2l0aXVsKSAlPiUNCiAgZmlsdGVyKEV4ZXJjaXRpdWwgPT0gIlBveml0aXYgLSBOZWdhdGl2IikgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNTIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzUyA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICB3aWxjb3hvbl9wYWlyZWRfZnVuYyhpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBWYXNTLCBhc3N1bV9jaGVjayA9IFRSVUUpDQoNCmNhdCgiIyMgRmVtYWxlcyAtIE5lZyBmaXJzdCwgUG96IHNlY29uZCIpDQpEYXRhX2ZlbSAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzLCBFeGVyY2l0aXVsKSAlPiUNCiAgZmlsdGVyKEV4ZXJjaXRpdWwgPT0gIk5lZ2F0aXYgLSBQb3ppdGl2IikgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNTIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzUyA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICB3aWxjb3hvbl9wYWlyZWRfZnVuYyhpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBWYXNTLCBhc3N1bV9jaGVjayA9IFRSVUUpDQpgYGANCg0KDQojIFdpbGNveG9uIHBhaXJlZCBvbiBPcmRlciBvZiBDb25kaXRpb25zIC0gV0INCg0KYGBge3Igd2lsbGNveG9uX3diX29yZGVyLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQ0KY2F0KCIjIyBXaG9sZSBTYW1wbGUgLSBQb3ogZmlyc3QsIE5lZyBzZWNvbmQiKQ0KRGF0YV9HZW5fbWVyZ2VkX2xvbmcgJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscywgRXhlcmNpdGl1bCkgJT4lDQogIGZpbHRlcihFeGVyY2l0aXVsID09ICJQb3ppdGl2IC0gTmVnYXRpdiIpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiVmFzQiIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKFZhc0IgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgd2lsY294b25fcGFpcmVkX2Z1bmMoaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgdmFsdWVfdmFyID0gVmFzQiwgYXNzdW1fY2hlY2sgPSBUUlVFKQ0KDQpjYXQoIiMjIFdob2xlIFNhbXBsZSAtIE5lZyBmaXJzdCwgUG96IHNlY29uZCIpDQpEYXRhX0dlbl9tZXJnZWRfbG9uZyAlPiUNCiAgc2VsZWN0KElELCBWYXJzLCBQcmVQb3N0LCBDb25kLCBWYWxzLCBFeGVyY2l0aXVsKSAlPiUNCiAgZmlsdGVyKEV4ZXJjaXRpdWwgPT0gIk5lZ2F0aXYgLSBQb3ppdGl2IikgJT4lDQogIGZpbHRlcihWYXJzID09ICJWYXNCIikgJT4lDQogIGRwbHlyOjpyZW5hbWUoVmFzQiA9IFZhbHMpICU+JQ0KICBkcm9wX25hKCkgJT4lDQogIGdyb3VwX2J5KElEKSAlPiUgDQogIGZpbHRlcihuKCkgPiAzKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICB3aWxjb3hvbl9wYWlyZWRfZnVuYyhpZF92YXIgPSBJRCwgdGltZV92YXIgPSBQcmVQb3N0LCB2YWx1ZV92YXIgPSBWYXNCLCBhc3N1bV9jaGVjayA9IFRSVUUpDQoNCg0KDQpjYXQoIiMjIEZlbWFsZXMgLSBQb3ogZmlyc3QsIE5lZyBzZWNvbmQiKQ0KRGF0YV9mZW0gJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscywgRXhlcmNpdGl1bCkgJT4lDQogIGZpbHRlcihFeGVyY2l0aXVsID09ICJQb3ppdGl2IC0gTmVnYXRpdiIpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiVmFzQiIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKFZhc0IgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgd2lsY294b25fcGFpcmVkX2Z1bmMoaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgdmFsdWVfdmFyID0gVmFzQiwgYXNzdW1fY2hlY2sgPSBUUlVFKQ0KDQpjYXQoIiMjIEZlbWFsZXMgLSBOZWcgZmlyc3QsIFBveiBzZWNvbmQiKQ0KRGF0YV9mZW0gJT4lDQogIHNlbGVjdChJRCwgVmFycywgUHJlUG9zdCwgQ29uZCwgVmFscywgRXhlcmNpdGl1bCkgJT4lDQogIGZpbHRlcihFeGVyY2l0aXVsID09ICJOZWdhdGl2IC0gUG96aXRpdiIpICU+JQ0KICBmaWx0ZXIoVmFycyA9PSAiVmFzQiIpICU+JQ0KICBkcGx5cjo6cmVuYW1lKFZhc0IgPSBWYWxzKSAlPiUNCiAgZHJvcF9uYSgpICU+JQ0KICBncm91cF9ieShJRCkgJT4lIA0KICBmaWx0ZXIobigpID4gMykgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgd2lsY294b25fcGFpcmVkX2Z1bmMoaWRfdmFyID0gSUQsIHRpbWVfdmFyID0gUHJlUG9zdCwgdmFsdWVfdmFyID0gVmFzQiwgYXNzdW1fY2hlY2sgPSBUUlVFKQ0KYGBgDQoNCg0KDQo8YnI+DQoNCg0KDQo8IS0tIFNlc3Npb24gSW5mbyBhbmQgTGljZW5zZSAtLT4NCg0KPGJyPg0KDQojIFNlc3Npb24gSW5mbw0KYGBge3Igc2Vzc2lvbl9pbmZvLCBlY2hvID0gRkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30NCnNlc3Npb25JbmZvKCkgICAgDQpgYGANCg0KPCEtLSBGb290ZXIgLS0+DQombmJzcDsNCjxociAvPg0KPHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPkEgd29yayBieSA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vQ2xhdWRpdVBhcGFzdGVyaS8iPkNsYXVkaXUgUGFwYXN0ZXJpPC9hPjwvcD4NCjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij48c3BhbiBzdHlsZT0iY29sb3I6ICM4MDgwODA7Ij48ZW0+Y2xhdWRpdS5wYXBhc3RlcmlAZ21haWwuY29tPC9lbT48L3NwYW4+PC9wPg0KJm5ic3A7DQo=