cat("\014")     # clean terminal

rm(list = ls()) # clean workspace
try(dev.off(), silent = TRUE) # close all plots
library(tidyverse)
library(afex)
library(emmeans)
library(ggdist)
library(GGally)
library(readxl)
library(data.table)
library(performance)
exclude_bad_eeg <- TRUE
my_dodge <- .3
theme_set(
  theme_minimal()
)
a_posteriori <- function(afex_aov, sig_level = .05) {
  factors  <- as.list(rownames(afex_aov$anova_table))
  for (j in 1:length(factors)) {
    if (grepl(":", factors[[j]])) {
      factors[[j]] <- unlist(strsplit(factors[[j]], ":"))
    }
  }
  p_values <- afex_aov$anova_table$`Pr(>F)`
  for (i in 1:length(p_values)) {
    if (p_values[i] <= sig_level) {
      print(emmeans(afex_aov, factors[[i]], contr = "pairwise"))
      cat(rep("_", 100), '\n', sep = "")
    }
  }
}
eeg_check <- read_excel(file.path('..', 'bad channels oddball pemycrep 2022.xlsx'))
eeg_check <- eeg_check %>%
  mutate(badchan_num = ifelse(badchan == '0', 0, sapply(strsplit(badchan, " "), length)))
bad_eeg   <- eeg_check$name[eeg_check$commentary != 'ok']
data_dir  <- file.path('..', 'results')
# target_and_standard_name <- file.path(data_dir, 'average_voltage_275_to_425_auditory_oddball_standard_and_target.txt')
target_and_standard_name <- file.path(data_dir, 'average_voltage_300_to_400_auditory_oddball_standard_and_target.txt')
target_and_standard_data <- read.table(target_and_standard_name, header = TRUE, strip.white = TRUE, sep = "\t")
names(target_and_standard_data)[names(target_and_standard_data) == "value"] <- "uvolts"
names(target_and_standard_data)[names(target_and_standard_data) == "binlabel"] <- "stimulus"
target_and_standard_data$num_id <- readr::parse_number(target_and_standard_data$ERPset)
target_and_standard_data$vulnerability[ grepl("nVul", target_and_standard_data$ERPset)] <- "Invulnerable"
target_and_standard_data$vulnerability[!grepl("nVul", target_and_standard_data$ERPset)] <- "Vulnerable"
target_and_standard_data$belief[ grepl("nCr", target_and_standard_data$ERPset)]         <- "Unbeliever"
target_and_standard_data$belief[!grepl("nCr", target_and_standard_data$ERPset)]         <- "Believer"
target_and_standard_data$sex[ grepl("F", target_and_standard_data$ERPset)]              <- "Female"
target_and_standard_data$sex[!grepl("F", target_and_standard_data$ERPset)]              <- "Male"
target_and_standard_data$anteroposterior[target_and_standard_data$chlabel %in% c('C1', 'Cz', 'C2')]                <- 'Central'
target_and_standard_data$anteroposterior[target_and_standard_data$chlabel %in% c('E112-CP1a', 'CPz', 'E034-CP2a')] <- 'Centro-parietal'
target_and_standard_data$mediolateral[target_and_standard_data$chlabel %in% c('C1', 'E112-CP1a')]                  <- 'Left'
target_and_standard_data$mediolateral[target_and_standard_data$chlabel %in% c('Cz', 'CPz')]                        <- 'Midline'
target_and_standard_data$mediolateral[target_and_standard_data$chlabel %in% c('C2', 'E034-CP2a')]                  <- 'Right'
target_and_standard_data$num_id          <- factor(target_and_standard_data$num_id)
target_and_standard_data$vulnerability   <- factor(target_and_standard_data$vulnerability)
target_and_standard_data$sex             <- factor(target_and_standard_data$sex)
target_and_standard_data$belief          <- factor(target_and_standard_data$belief)
target_and_standard_data$stimulus        <- factor(target_and_standard_data$stimulus, levels = c('Target', 'Standard'))
target_and_standard_data$anteroposterior <- factor(target_and_standard_data$anteroposterior)
target_and_standard_data$mediolateral    <- factor(target_and_standard_data$mediolateral, levels = c('Left', 'Midline', 'Right'))
just_sex <- subset(target_and_standard_data[c('ERPset', 'sex', 'chindex', 'stimulus')], chindex == 1 & stimulus == 'Target')
connectivity_file <- 'erplab/median_connectivity_auditory_oddball.csv'
connectivity_data <- read_csv(connectivity_file, show_col_types = FALSE) |> 
  left_join(y = just_sex[c('ERPset', 'sex')], by = c('ERPset')) |>
  mutate(log_median_connectivity = log(median_connectivity)) |> 
  mutate(stimulus = factor(stimulus, levels = c('target', 'standard'))) |> 
  mutate(num_id = parse_number(ERPset)) |> 
  mutate_if(is.character, as.factor) |> 
  mutate(region_b = factor(region_b, levels = c('cingulate_ipsi', 'cingulate_contra')))
if (exclude_bad_eeg) {
  target_and_standard_data <- target_and_standard_data[!(target_and_standard_data$ERPset %in% bad_eeg), ]
  connectivity_data        <- connectivity_data[!(connectivity_data$ERPset %in% bad_eeg), ]
  }
write.csv(target_and_standard_data,  file.path(data_dir, 'targets_and_standards_data_clean.csv'),  row.names = FALSE)

1 Participants

options(width = 100)
mytable <- xtabs(~ sex + belief, data = target_and_standard_data) / length(unique(target_and_standard_data$chindex)) / length(unique(target_and_standard_data$stimulus))
ftable(addmargins(mytable))
       belief Believer Unbeliever Sum
sex                                  
Female              24         24  48
Male                16         14  30
Sum                 40         38  78

2 Bad EEG channels

ggplot(eeg_check, aes(badchan_num)) + geom_histogram(bins = 12, color = 'darkblue', fill = 'lightblue') + scale_x_continuous(breaks=0:11)

xtabs(~ badchan_num, data = eeg_check)
badchan_num
 0  1  2  3  4  5  6  7 11 
 7 14 23 15  7  8  3  2  1 

3 ERP plots

3.1 Target and Standard:

3.2 Topographic layout:

4 General description

options(width = 100)
summary(target_and_standard_data[c('uvolts', 'sex', 'vulnerability', 'belief', 'stimulus', 'anteroposterior', 'mediolateral', 'num_id')])
     uvolts            sex           vulnerability        belief        stimulus  
 Min.   :-3.0668   Female:576   Invulnerable:780   Believer  :480   Target  :468  
 1st Qu.:-0.3816   Male  :360   Vulnerable  :156   Unbeliever:456   Standard:468  
 Median : 0.6861                                                                  
 Mean   : 1.7205                                                                  
 3rd Qu.: 3.4862                                                                  
 Max.   :10.9153                                                                  
                                                                                  
        anteroposterior  mediolateral     num_id   
 Central        :468    Left   :312   1      : 12  
 Centro-parietal:468    Midline:312   3      : 12  
                        Right  :312   6      : 12  
                                      15     : 12  
                                      16     : 12  
                                      18     : 12  
                                      (Other):864  

5 Targets and Standards by topography

options(width = 100)
target_and_standard_rep_anova = aov_ez("num_id", "uvolts", target_and_standard_data, within = c("stimulus", "anteroposterior", "mediolateral"))

target_and_standard_rain_central <- ggplot(target_and_standard_data[target_and_standard_data$anteroposterior == "Central", ], aes(y = uvolts, x = mediolateral, color = stimulus, fill = stimulus)) +
  ggtitle("Targets and Standards Central") +
  ylab("uvolts") +
  stat_halfeye(
    trim   = FALSE, 
    adjust = .75, 
    .width = 0, 
    justification = -.15, 
    alpha  = .4,
    point_colour = NA) + 
  # theme(legend.position='none')
  geom_boxplot(width = .15, alpha = .2, outlier.shape = NA) +
  geom_point(size = 2, alpha = .4, position = position_jitter(width = .05, height = 0)) 
suppressWarnings(print(target_and_standard_rain_central))


target_and_standard_rain_parietal <- ggplot(target_and_standard_data[target_and_standard_data$anteroposterior == "Centro-parietal", ], aes(y = uvolts, x = mediolateral, color = stimulus, fill = stimulus)) +
  ggtitle("Targets and Standards Centro-Parietal") +
  ylab("uvolts") +
  stat_halfeye(
    trim   = FALSE, 
    adjust = .75, 
    .width = 0, 
    justification = -.15, 
    alpha  = .4,
    point_colour = NA) + 
  # theme(legend.position='none')
  geom_boxplot(width = .15, alpha = .2, outlier.shape = NA) +
  geom_point(size = 2, alpha = .4, position = position_jitter(width = .05, height = 0)) 
suppressWarnings(print(target_and_standard_rain_parietal))


target_and_standard_afex_plot <-
  afex_plot(
    target_and_standard_rep_anova,
    x = "anteroposterior",
    trace = "stimulus",
    panel = "mediolateral",
    error = "within",
    error_arg = list(width = .15),
    dodge     = my_dodge,
    data_arg  = list(
      position = 
        position_jitterdodge(
          jitter.width  = .1, 
          dodge.width   = my_dodge
        )),
    mapping   = c('color'),
    point_arg = list(size = 4)
  )
suppressWarnings(print(target_and_standard_afex_plot))

nice(target_and_standard_rep_anova)
Anova Table (Type 3 tests)

Response: uvolts
                                 Effect           df   MSE          F   ges p.value
1                              stimulus        1, 77 18.45 211.26 ***  .499   <.001
2                       anteroposterior        1, 77  1.12  28.45 ***  .008   <.001
3                          mediolateral 1.67, 128.88  1.05       1.17 <.001    .308
4              stimulus:anteroposterior        1, 77  0.60  17.18 ***  .003   <.001
5                 stimulus:mediolateral 1.65, 126.97  0.80     3.47 *  .001    .043
6          anteroposterior:mediolateral 1.76, 135.18  0.29     2.88 + <.001    .066
7 stimulus:anteroposterior:mediolateral 1.95, 150.33  0.22       0.68 <.001    .507
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1

Sphericity correction method: GG 
a_posteriori(target_and_standard_rep_anova)
$emmeans
 stimulus emmean   SE df lower.CL upper.CL
 Target     3.76 0.29 77    3.183    4.340
 Standard  -0.32 0.11 77   -0.539   -0.101

Results are averaged over the levels of: mediolateral, anteroposterior 
Confidence level used: 0.95 

$contrasts
 contrast          estimate    SE df t.ratio p.value
 Target - Standard     4.08 0.281 77  14.535  <.0001

Results are averaged over the levels of: mediolateral, anteroposterior 

____________________________________________________________________________________________________
$emmeans
 anteroposterior emmean    SE df lower.CL upper.CL
 Central           1.54 0.171 77     1.20     1.88
 Centro.parietal   1.91 0.174 77     1.56     2.25

Results are averaged over the levels of: mediolateral, stimulus 
Confidence level used: 0.95 

$contrasts
 contrast                  estimate     SE df t.ratio p.value
 Central - Centro.parietal   -0.369 0.0692 77  -5.334  <.0001

Results are averaged over the levels of: mediolateral, stimulus 

____________________________________________________________________________________________________
$emmeans
 stimulus anteroposterior emmean    SE df lower.CL upper.CL
 Target   Central           3.47 0.297 77    2.881   4.0624
 Standard Central          -0.40 0.115 77   -0.629  -0.1710
 Target   Centro.parietal   4.05 0.295 77    3.464   4.6375
 Standard Centro.parietal  -0.24 0.111 77   -0.461  -0.0199

Results are averaged over the levels of: mediolateral 
Confidence level used: 0.95 

$contrasts
 contrast                                          estimate     SE df t.ratio p.value
 Target Central - Standard Central                    3.872 0.2920 77  13.259  <.0001
 Target Central - Target Centro.parietal             -0.579 0.1103 77  -5.250  <.0001
 Target Central - Standard Centro.parietal            3.712 0.2867 77  12.946  <.0001
 Standard Central - Target Centro.parietal           -4.451 0.2916 77 -15.260  <.0001
 Standard Central - Standard Centro.parietal         -0.159 0.0504 77  -3.162  0.0118
 Target Centro.parietal - Standard Centro.parietal    4.291 0.2785 77  15.409  <.0001

Results are averaged over the levels of: mediolateral 
P value adjustment: tukey method for comparing a family of 4 estimates 

____________________________________________________________________________________________________
$emmeans
 stimulus mediolateral emmean    SE df lower.CL upper.CL
 Target   Left          3.801 0.285 77    3.233   4.3683
 Standard Left         -0.357 0.115 77   -0.587  -0.1274
 Target   Midline       3.878 0.315 77    3.251   4.5046
 Standard Midline      -0.323 0.114 77   -0.550  -0.0964
 Target   Right         3.605 0.300 77    3.007   4.2033
 Standard Right        -0.280 0.111 77   -0.500  -0.0594

Results are averaged over the levels of: anteroposterior 
Confidence level used: 0.95 

$contrasts
 contrast                          estimate     SE df t.ratio p.value
 Target Left - Standard Left         4.1580 0.2776 77  14.979  <.0001
 Target Left - Target Midline       -0.0770 0.1346 77  -0.572  0.9926
 Target Left - Standard Midline      4.1241 0.2689 77  15.335  <.0001
 Target Left - Target Right          0.1957 0.1543 77   1.268  0.8012
 Target Left - Standard Right        4.0805 0.2625 77  15.546  <.0001
 Standard Left - Target Midline     -4.2350 0.3150 77 -13.443  <.0001
 Standard Left - Standard Midline   -0.0339 0.0434 77  -0.781  0.9700
 Standard Left - Target Right       -3.9624 0.3102 77 -12.774  <.0001
 Standard Left - Standard Right     -0.0776 0.0590 77  -1.315  0.7757
 Target Midline - Standard Midline   4.2011 0.3040 77  13.820  <.0001
 Target Midline - Target Right       0.2726 0.1027 77   2.655  0.0967
 Target Midline - Standard Right     4.1575 0.2952 77  14.082  <.0001
 Standard Midline - Target Right    -3.9284 0.3024 77 -12.990  <.0001
 Standard Midline - Standard Right  -0.0436 0.0374 77  -1.168  0.8505
 Target Right - Standard Right       3.8848 0.2899 77  13.401  <.0001

Results are averaged over the levels of: anteroposterior 
P value adjustment: tukey method for comparing a family of 6 estimates 

____________________________________________________________________________________________________
# P3_data_name   <- file.path(data_dir, 'average_voltage_275_to_425_auditory_oddball.txt')
P3_data_name   <- file.path(data_dir, 'average_voltage_300_to_400_auditory_oddball.txt')
P3_data        <- read.table(P3_data_name, header = TRUE, strip.white = TRUE, sep = "\t")
names(P3_data)[names(P3_data) == "value"] <- "uvolts"
P3_data$num_id <- readr::parse_number(P3_data$ERPset)
P3_data$vulnerability[ grepl("nVul", P3_data$ERPset)] <- "Invulnerable"
P3_data$vulnerability[!grepl("nVul", P3_data$ERPset)] <- "Vulnerable"
P3_data$belief[ grepl("nCr", P3_data$ERPset)]         <- "Unbeliever"
P3_data$belief[!grepl("nCr", P3_data$ERPset)]         <- "Believer"
P3_data$sex[ grepl("F", P3_data$ERPset)]              <- "Female"
P3_data$sex[!grepl("F", P3_data$ERPset)]              <- "Male"
P3_data$anteroposterior[P3_data$chlabel %in% c('C1', 'Cz', 'C2')]                <- 'Central'
P3_data$anteroposterior[P3_data$chlabel %in% c('E112-CP1a', 'CPz', 'E034-CP2a')] <- 'Centro-parietal'
P3_data$mediolateral[P3_data$chlabel %in% c('C1', 'E112-CP1a')]                  <- 'Left'
P3_data$mediolateral[P3_data$chlabel %in% c('Cz', 'CPz')]                        <- 'Midline'
P3_data$mediolateral[P3_data$chlabel %in% c('C2', 'E034-CP2a')]                  <- 'Right'
P3_data$num_id          <- factor(P3_data$num_id)
P3_data$vulnerability   <- factor(P3_data$vulnerability)
P3_data$sex             <- factor(P3_data$sex)
P3_data$belief          <- factor(P3_data$belief)
P3_data$anteroposterior <- factor(P3_data$anteroposterior)
P3_data$mediolateral    <- factor(P3_data$mediolateral, levels = c('Left', 'Midline', 'Right'))
if (exclude_bad_eeg) {
  P3_data <- P3_data[!(P3_data$ERPset %in% bad_eeg), ]
}
write.csv(P3_data,  file.path(data_dir, 'auditory_oddball_data_clean.csv'),  row.names = FALSE)
P3_data.table <- data.table(P3_data)
P3_by_subject <- unique(P3_data.table[, .(worklat, mlabel, uv_mean = mean(uvolts), bini, binlabel, num_id, vulnerability, belief, sex), by = .(ERPset)])
P3_by_subject$RUT <- sub("_odd.*", "", P3_by_subject$ERPset)
P3_by_subject$RUT <- sub(".*F", "", P3_by_subject$RUT)
P3_by_subject$RUT <- sub(".*M", "", P3_by_subject$RUT)
write.csv(P3_by_subject,  file.path(data_dir, 'P3_by_subject.csv'),  row.names = FALSE)

6 P3 plots

6.1 Wave difference, Target - Standard

6.2 Wave difference scalp, Target - Standard

6.3 Wave difference layout

7 P3 general description

Measurement window: [300.0 400.0] ms

options(width = 100)
summary(P3_data[c('uvolts', 'sex', 'vulnerability', 'belief', 'anteroposterior', 'mediolateral', 'num_id')])
     uvolts           sex           vulnerability        belief           anteroposterior
 Min.   :-3.501   Female:288   Invulnerable:390   Believer  :240   Central        :234   
 1st Qu.: 2.244   Male  :180   Vulnerable  : 78   Unbeliever:228   Centro-parietal:234   
 Median : 3.952                                                                          
 Mean   : 4.081                                                                          
 3rd Qu.: 5.522                                                                          
 Max.   :11.433                                                                          
                                                                                         
  mediolateral     num_id   
 Left   :156   1      :  6  
 Midline:156   3      :  6  
 Right  :156   6      :  6  
               15     :  6  
               16     :  6  
               18     :  6  
               (Other):432  

8 P3 by topography

options(width = 100)
P3_rain <- ggplot(P3_data, aes(y = uvolts, x = mediolateral, color = anteroposterior, fill = anteroposterior)) +
  ggtitle("P3") +
  ylab("uvolts") +
  stat_halfeye(
    trim   = FALSE, 
    adjust = .75, 
    .width = 0, 
    justification = -.15, 
    alpha  = .4,
    point_colour = NA) + 
  # theme(legend.position='none')
  # geom_boxplot(width = .15, alpha = .2, outlier.shape = NA) +
  geom_point(size = 2, alpha = .4, position = position_jitter(width = .05, height = 0)) 
suppressWarnings(print(P3_rain))

P3_rep_anova = aov_ez("num_id", "uvolts", P3_data, within = c("anteroposterior", "mediolateral"))
P3_afex_plot <-
  afex_plot(
    P3_rep_anova,
    x = "mediolateral",
    trace = "anteroposterior",
    error = "within",
    error_arg = list(width = .15),
    dodge     = my_dodge,
    data_arg  = list(
      position = 
        position_jitterdodge(
          jitter.width  = .1, 
          dodge.width   = my_dodge
        )),
    mapping   = c('color'),
    point_arg = list(size = 4)
  )
suppressWarnings(print(P3_afex_plot))

nice(P3_rep_anova)
Anova Table (Type 3 tests)

Response: uvolts
                        Effect           df  MSE         F   ges p.value
1              anteroposterior        1, 77 1.20 17.18 ***  .006   <.001
2                 mediolateral 1.65, 126.97 1.61    3.47 *  .003    .043
3 anteroposterior:mediolateral 1.95, 150.33 0.45      0.68 <.001    .507
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1

Sphericity correction method: GG 
a_posteriori(P3_rep_anova)
$emmeans
 anteroposterior emmean    SE df lower.CL upper.CL
 Central           3.87 0.292 77     3.29     4.45
 Centro.parietal   4.29 0.278 77     3.74     4.85

Results are averaged over the levels of: mediolateral 
Confidence level used: 0.95 

$contrasts
 contrast                  estimate    SE df t.ratio p.value
 Central - Centro.parietal    -0.42 0.101 77  -4.145  0.0001

Results are averaged over the levels of: mediolateral 

____________________________________________________________________________________________________
$emmeans
 mediolateral emmean    SE df lower.CL upper.CL
 Left           4.16 0.278 77     3.61     4.71
 Midline        4.20 0.304 77     3.60     4.81
 Right          3.88 0.290 77     3.31     4.46

Results are averaged over the levels of: anteroposterior 
Confidence level used: 0.95 

$contrasts
 contrast        estimate     SE df t.ratio p.value
 Left - Midline   -0.0431 0.1338 77  -0.322  0.9445
 Left - Right      0.2732 0.1525 77   1.792  0.1792
 Midline - Right   0.3163 0.0989 77   3.198  0.0056

Results are averaged over the levels of: anteroposterior 
P value adjustment: tukey method for comparing a family of 3 estimates 

____________________________________________________________________________________________________

9 P3 by belief and sex

options(width = 100)
P3_anova_sex = aov_ez("num_id", "uvolts", P3_data, between = c("belief", "sex"), fun_aggregate = mean)
Contrasts set to contr.sum for the following variables: belief, sex
mytable <- xtabs(~ sex + belief, data = P3_anova_sex$data$long)
ftable(addmargins(mytable))
       belief Believer Unbeliever Sum
sex                                  
Female              24         24  48
Male                16         14  30
Sum                 40         38  78
P3_afex_plot_sex <-
  afex_plot(
    P3_anova_sex,
    x     = "belief",
    trace = "sex",
    error = "between",
    error_arg = list(width = .15),
    dodge     = my_dodge,
    data_arg  = list(
      position = 
        position_jitterdodge(
          jitter.width  = .1, 
          dodge.width   = my_dodge
        )),
    mapping   = c('color'),
    point_arg = list(size = 4)
  )
suppressWarnings(print(P3_afex_plot_sex))

nice(P3_anova_sex)
Anova Table (Type 3 tests)

Response: uvolts
      Effect    df  MSE    F  ges p.value
1     belief 1, 74 6.03 0.11 .001    .746
2        sex 1, 74 6.03 2.70 .035    .105
3 belief:sex 1, 74 6.03 1.58 .021    .213
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1
a_posteriori(P3_anova_sex)

10 Decoding (MVPA)

Fahrenfort, J. J., van Driel, J., van Gaal, S., & Olivers, C. N. L. (2018). From ERPs to MVPA using the Amsterdam Decoding and Modeling toolbox (ADAM). Frontiers in Neuroscience, 12(JUL), 351586. https://doi.org/10.3389/FNINS.2018.00368/BIBTEX

All channels, reference to infinite, 40 Hz low-pass
Dong, L., Li, F., Liu, Q., Wen, X., Lai, Y., Xu, P., & Yao, D. (2017). MATLAB Toolboxes for Reference Electrode Standardization Technique (REST) of Scalp EEG. Frontiers in Neuroscience, 11(OCT), 601. https://doi.org/10.3389/fnins.2017.00601

10.1 Exemplar ERP on Cz

10.2 ERP difference on Cz

10.3 Decoding over time

10.3.1 10-fold cross validation

10.3.2 Train 1&3, test 2&4

10.4 Individual results

10.5 Activation patterns

10.5.1 10-fold cross validation

10.5.2 Train 1&3, test 2&4

10.6 Temporal generalization plot

10.6.1 10-fold cross validation

10.6.2 Train 1&3, test 2&4

10.7 Generalization over time

10.7.1 10-fold cross validation

10.7.2 Train 1&3, test 2&4

10.8 Group decoding differences

10.8.1 10-fold cross validation

10.8.2 Train 1&3, test 2&4

11 Temporo-cingulate theta-alpha (4-12 Hz) Functional Connectivity (ROIconnect)

Multivariate Interaction Measure, MIM [@Pellegrini2023].
800 ms post-stimulus.

options(width = 100)
summary(connectivity_data)
                     ERPset        stimulus             region_a               region_b  
 S001VulCrF20957113_odd :  8   target  :312   left_temporal :312   cingulate_ipsi  :312  
 S003nVulCrM18466555_odd:  8   standard:312   right_temporal:312   cingulate_contra:312  
 S006nVulCrM17923449_odd:  8                                                             
 S015nVulCrM18833005_odd:  8                                                             
 S016VulCrF19423156_odd :  8                                                             
 S018nVulCrF17671904_odd:  8                                                             
 (Other)                :576                                                             
 median_connectivity     sex      log_median_connectivity     num_id     
 Min.   :0.03258     Female:384   Min.   :-3.424          Min.   :  1.0  
 1st Qu.:0.05716     Male  :240   1st Qu.:-2.862          1st Qu.: 47.0  
 Median :0.07289                  Median :-2.619          Median : 76.5  
 Mean   :0.08027                  Mean   :-2.590          Mean   : 72.1  
 3rd Qu.:0.09631                  3rd Qu.:-2.340          3rd Qu.:101.0  
 Max.   :0.21169                  Max.   :-1.553          Max.   :120.0  
                                                                         
connectivity_data_wide_cingulate <- connectivity_data[c('ERPset', 'region_a', 'region_b', 'stimulus', 'log_median_connectivity')] |>
  pivot_wider(names_from = region_b, values_from = log_median_connectivity)
connectivity_data_wide_temporal <- connectivity_data[c('ERPset', 'region_a', 'region_b', 'stimulus', 'log_median_connectivity')] |>
  pivot_wider(names_from = region_a, values_from = log_median_connectivity)
connectivity_data_wide_stimulus   <- connectivity_data[c('ERPset', 'region_a', 'region_b', 'stimulus', 'log_median_connectivity')] |>
  pivot_wider(names_from = stimulus, values_from = log_median_connectivity)
stimulus   <- c('target'         , 'standard')
temporal   <- c('left_temporal'  , 'right_temporal')
cingulate <- c('cingulate_ipsi', 'cingulate_contra')
cingulate_pairs <- ggpairs(connectivity_data_wide_cingulate,
                            aes(colour = stimulus, alpha = .5, linewidth = NA),
                            columns  = cingulate,
                            lower    = list(continuous = wrap('points', alpha = .4)),
                            progress = FALSE
                            )
temporal_pairs <- ggpairs(connectivity_data_wide_temporal,
                            aes(colour = stimulus, alpha = .5, linewidth = NA),
                            columns  = temporal,
                            lower    = list(continuous = wrap('points', alpha = .4)),
                            progress = FALSE
                            )
stimulus_pairs <- ggpairs(connectivity_data_wide_stimulus,
                            aes(colour = region_b, alpha = .5, linewidth = NA),
                            columns  = stimulus,
                            lower    = list(continuous = wrap('points', alpha = .4)),
                            progress = FALSE
                            )
suppressWarnings(print(cingulate_pairs))

suppressWarnings(print(temporal_pairs))

suppressWarnings(print(stimulus_pairs))

11.1 Connectivity ANOVA:

connectivity_rep_anova <- aov_ez('num_id', 'log_median_connectivity', 
                             connectivity_data,
                             within = c('stimulus', 'region_a', 'region_b'))
connectivity_afex_plot <- afex_plot(connectivity_rep_anova,
                                x     = 'region_a',
                                trace = 'stimulus',
                                panel = 'region_b',
                                error = 'within',
                                error_arg = list(width = .3, lwd = .75),
                                dodge = .5,
                                data_arg  = list(
                                  position = 
                                    position_jitterdodge(
                                      jitter.width = .2, 
                                      dodge.width  = .5  ## needs to be same as dodge
                                    )),
                                mapping   = c('color'),, data_alpha = .3,
                                point_arg = list(size = 3)
                                )
suppressWarnings(print(connectivity_afex_plot))

mytable <- xtabs(~ stimulus + region_a + region_b, data = connectivity_rep_anova$data$long)
ftable(mytable)
                        region_b cingulate_ipsi cingulate_contra
stimulus region_a                                               
target   left_temporal                       78               78
         right_temporal                      78               78
standard left_temporal                       78               78
         right_temporal                      78               78
print(connectivity_rep_anova)
Anova Table (Type 3 tests)

Response: log_median_connectivity
                      Effect    df  MSE         F   ges p.value
1                   stimulus 1, 77 0.18 49.48 ***  .109   <.001
2                   region_a 1, 77 0.04    5.32 *  .003    .024
3                   region_b 1, 77 0.00   8.15 ** <.001    .006
4          stimulus:region_a 1, 77 0.03      1.19 <.001    .279
5          stimulus:region_b 1, 77 0.00      0.51 <.001    .476
6          region_a:region_b 1, 77 0.00    3.16 + <.001    .079
7 stimulus:region_a:region_b 1, 77 0.00      0.01 <.001    .914
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘+’ 0.1 ‘ ’ 1
a_posteriori(connectivity_rep_anova)
$emmeans
 stimulus emmean     SE df lower.CL upper.CL
 target    -2.47 0.0381 77    -2.55    -2.40
 standard  -2.71 0.0360 77    -2.78    -2.64

Results are averaged over the levels of: region_b, region_a 
Confidence level used: 0.95 

$contrasts
 contrast          estimate     SE df t.ratio p.value
 target - standard    0.238 0.0339 77   7.034  <.0001

Results are averaged over the levels of: region_b, region_a 

____________________________________________________________________________________________________
$emmeans
 region_a       emmean     SE df lower.CL upper.CL
 left_temporal   -2.61 0.0332 77    -2.68    -2.54
 right_temporal  -2.57 0.0347 77    -2.64    -2.50

Results are averaged over the levels of: region_b, stimulus 
Confidence level used: 0.95 

$contrasts
 contrast                       estimate     SE df t.ratio p.value
 left_temporal - right_temporal  -0.0386 0.0167 77  -2.307  0.0237

Results are averaged over the levels of: region_b, stimulus 

____________________________________________________________________________________________________
$emmeans
 region_b         emmean     SE df lower.CL upper.CL
 cingulate_ipsi    -2.59 0.0334 77    -2.66    -2.53
 cingulate_contra  -2.59 0.0325 77    -2.65    -2.52

Results are averaged over the levels of: region_a, stimulus 
Confidence level used: 0.95 

$contrasts
 contrast                          estimate      SE df t.ratio p.value
 cingulate_ipsi - cingulate_contra -0.00865 0.00303 77  -2.855  0.0055

Results are averaged over the levels of: region_a, stimulus 

____________________________________________________________________________________________________

11.2 Connectivity Assumptions:

norm_connectivity <- check_normality(connectivity_rep_anova)
print(norm_connectivity)
Warning: Non-normality of residuals detected (p < .001).
plot(norm_connectivity, type = 'density')

plot(norm_connectivity, type = 'qq')

hetero_connectivity <- check_heteroscedasticity(connectivity_rep_anova)
Data was changed during ANOVA calculation. Thus, fitted values cannot be added to original data.
fitted(..., append = TRUE) will return data and fitted values.
print(hetero_connectivity)
OK: Error variance appears to be homoscedastic (p = 0.385).
plot(hetero_connectivity)
Data was changed during ANOVA calculation. Thus, residuals cannot be added to original data.
residuals(..., append = TRUE) will return data and residuals.
Data was changed during ANOVA calculation. Thus, fitted values cannot be added to original data.
fitted(..., append = TRUE) will return data and fitted values.

check_sphericity(connectivity_rep_anova)
Warning in min(x) : no non-missing arguments to min; returning Inf
OK: Data seems to be spherical (p > .999).
LS0tCnRpdGxlOiAiQXVkaXRvcnkgT2RkYmFsbCBQMywgUGVNeUNyZVAiCmF1dGhvcjogIkFsdmFybyBSaXZlcmEtUmVpIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdGhlbWU6IGNlcnVsZWFuCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IG5vCiAgICAgIHNtb290aF9zY3JvbGw6IG5vCiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKc3VidGl0bGU6IFJlZmVyZW5jZSBhdCBJbmZpbml0eSwgUkVTVCAoUmVmZXJlbmNlIEVsZWN0cm9kZSBTdGFuZGFyZGl6YXRpb24gVGVjaG5pcXVlKS4KLS0tCgpgYGB7ciBDbGVhbiBhbmQgTG9hZCBMaWJyYXJpZXN9CmNhdCgiXDAxNCIpICAgICAjIGNsZWFuIHRlcm1pbmFsCnJtKGxpc3QgPSBscygpKSAjIGNsZWFuIHdvcmtzcGFjZQp0cnkoZGV2Lm9mZigpLCBzaWxlbnQgPSBUUlVFKSAjIGNsb3NlIGFsbCBwbG90cwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShhZmV4KQpsaWJyYXJ5KGVtbWVhbnMpCmxpYnJhcnkoZ2dkaXN0KQpsaWJyYXJ5KEdHYWxseSkKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShwZXJmb3JtYW5jZSkKYGBgCgpgYGB7ciBTZXQgRGVmYXVsdHN9CmV4Y2x1ZGVfYmFkX2VlZyA8LSBUUlVFCm15X2RvZGdlIDwtIC4zCnRoZW1lX3NldCgKICB0aGVtZV9taW5pbWFsKCkKKQphX3Bvc3RlcmlvcmkgPC0gZnVuY3Rpb24oYWZleF9hb3YsIHNpZ19sZXZlbCA9IC4wNSkgewogIGZhY3RvcnMgIDwtIGFzLmxpc3Qocm93bmFtZXMoYWZleF9hb3YkYW5vdmFfdGFibGUpKQogIGZvciAoaiBpbiAxOmxlbmd0aChmYWN0b3JzKSkgewogICAgaWYgKGdyZXBsKCI6IiwgZmFjdG9yc1tbal1dKSkgewogICAgICBmYWN0b3JzW1tqXV0gPC0gdW5saXN0KHN0cnNwbGl0KGZhY3RvcnNbW2pdXSwgIjoiKSkKICAgIH0KICB9CiAgcF92YWx1ZXMgPC0gYWZleF9hb3YkYW5vdmFfdGFibGUkYFByKD5GKWAKICBmb3IgKGkgaW4gMTpsZW5ndGgocF92YWx1ZXMpKSB7CiAgICBpZiAocF92YWx1ZXNbaV0gPD0gc2lnX2xldmVsKSB7CiAgICAgIHByaW50KGVtbWVhbnMoYWZleF9hb3YsIGZhY3RvcnNbW2ldXSwgY29udHIgPSAicGFpcndpc2UiKSkKICAgICAgY2F0KHJlcCgiXyIsIDEwMCksICdcbicsIHNlcCA9ICIiKQogICAgfQogIH0KfQpgYGAKCmBgYHtyIExvYWQgb2RkYmFsbCBkYXRhfQplZWdfY2hlY2sgPC0gcmVhZF9leGNlbChmaWxlLnBhdGgoJy4uJywgJ2JhZCBjaGFubmVscyBvZGRiYWxsIHBlbXljcmVwIDIwMjIueGxzeCcpKQplZWdfY2hlY2sgPC0gZWVnX2NoZWNrICU+JQogIG11dGF0ZShiYWRjaGFuX251bSA9IGlmZWxzZShiYWRjaGFuID09ICcwJywgMCwgc2FwcGx5KHN0cnNwbGl0KGJhZGNoYW4sICIgIiksIGxlbmd0aCkpKQpiYWRfZWVnICAgPC0gZWVnX2NoZWNrJG5hbWVbZWVnX2NoZWNrJGNvbW1lbnRhcnkgIT0gJ29rJ10KZGF0YV9kaXIgIDwtIGZpbGUucGF0aCgnLi4nLCAncmVzdWx0cycpCiMgdGFyZ2V0X2FuZF9zdGFuZGFyZF9uYW1lIDwtIGZpbGUucGF0aChkYXRhX2RpciwgJ2F2ZXJhZ2Vfdm9sdGFnZV8yNzVfdG9fNDI1X2F1ZGl0b3J5X29kZGJhbGxfc3RhbmRhcmRfYW5kX3RhcmdldC50eHQnKQp0YXJnZXRfYW5kX3N0YW5kYXJkX25hbWUgPC0gZmlsZS5wYXRoKGRhdGFfZGlyLCAnYXZlcmFnZV92b2x0YWdlXzMwMF90b180MDBfYXVkaXRvcnlfb2RkYmFsbF9zdGFuZGFyZF9hbmRfdGFyZ2V0LnR4dCcpCnRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSA8LSByZWFkLnRhYmxlKHRhcmdldF9hbmRfc3RhbmRhcmRfbmFtZSwgaGVhZGVyID0gVFJVRSwgc3RyaXAud2hpdGUgPSBUUlVFLCBzZXAgPSAiXHQiKQpuYW1lcyh0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEpW25hbWVzKHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSkgPT0gInZhbHVlIl0gPC0gInV2b2x0cyIKbmFtZXModGFyZ2V0X2FuZF9zdGFuZGFyZF9kYXRhKVtuYW1lcyh0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEpID09ICJiaW5sYWJlbCJdIDwtICJzdGltdWx1cyIKdGFyZ2V0X2FuZF9zdGFuZGFyZF9kYXRhJG51bV9pZCA8LSByZWFkcjo6cGFyc2VfbnVtYmVyKHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRFUlBzZXQpCnRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSR2dWxuZXJhYmlsaXR5WyBncmVwbCgiblZ1bCIsIHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRFUlBzZXQpXSA8LSAiSW52dWxuZXJhYmxlIgp0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkdnVsbmVyYWJpbGl0eVshZ3JlcGwoIm5WdWwiLCB0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkRVJQc2V0KV0gPC0gIlZ1bG5lcmFibGUiCnRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRiZWxpZWZbIGdyZXBsKCJuQ3IiLCB0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkRVJQc2V0KV0gICAgICAgICA8LSAiVW5iZWxpZXZlciIKdGFyZ2V0X2FuZF9zdGFuZGFyZF9kYXRhJGJlbGllZlshZ3JlcGwoIm5DciIsIHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRFUlBzZXQpXSAgICAgICAgIDwtICJCZWxpZXZlciIKdGFyZ2V0X2FuZF9zdGFuZGFyZF9kYXRhJHNleFsgZ3JlcGwoIkYiLCB0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkRVJQc2V0KV0gICAgICAgICAgICAgIDwtICJGZW1hbGUiCnRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRzZXhbIWdyZXBsKCJGIiwgdGFyZ2V0X2FuZF9zdGFuZGFyZF9kYXRhJEVSUHNldCldICAgICAgICAgICAgICA8LSAiTWFsZSIKdGFyZ2V0X2FuZF9zdGFuZGFyZF9kYXRhJGFudGVyb3Bvc3Rlcmlvclt0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkY2hsYWJlbCAlaW4lIGMoJ0MxJywgJ0N6JywgJ0MyJyldICAgICAgICAgICAgICAgIDwtICdDZW50cmFsJwp0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkYW50ZXJvcG9zdGVyaW9yW3RhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRjaGxhYmVsICVpbiUgYygnRTExMi1DUDFhJywgJ0NQeicsICdFMDM0LUNQMmEnKV0gPC0gJ0NlbnRyby1wYXJpZXRhbCcKdGFyZ2V0X2FuZF9zdGFuZGFyZF9kYXRhJG1lZGlvbGF0ZXJhbFt0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkY2hsYWJlbCAlaW4lIGMoJ0MxJywgJ0UxMTItQ1AxYScpXSAgICAgICAgICAgICAgICAgIDwtICdMZWZ0Jwp0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkbWVkaW9sYXRlcmFsW3RhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRjaGxhYmVsICVpbiUgYygnQ3onLCAnQ1B6JyldICAgICAgICAgICAgICAgICAgICAgICAgPC0gJ01pZGxpbmUnCnRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRtZWRpb2xhdGVyYWxbdGFyZ2V0X2FuZF9zdGFuZGFyZF9kYXRhJGNobGFiZWwgJWluJSBjKCdDMicsICdFMDM0LUNQMmEnKV0gICAgICAgICAgICAgICAgICA8LSAnUmlnaHQnCnRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRudW1faWQgICAgICAgICAgPC0gZmFjdG9yKHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRudW1faWQpCnRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSR2dWxuZXJhYmlsaXR5ICAgPC0gZmFjdG9yKHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSR2dWxuZXJhYmlsaXR5KQp0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkc2V4ICAgICAgICAgICAgIDwtIGZhY3Rvcih0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkc2V4KQp0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkYmVsaWVmICAgICAgICAgIDwtIGZhY3Rvcih0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkYmVsaWVmKQp0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkc3RpbXVsdXMgICAgICAgIDwtIGZhY3Rvcih0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkc3RpbXVsdXMsIGxldmVscyA9IGMoJ1RhcmdldCcsICdTdGFuZGFyZCcpKQp0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkYW50ZXJvcG9zdGVyaW9yIDwtIGZhY3Rvcih0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkYW50ZXJvcG9zdGVyaW9yKQp0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkbWVkaW9sYXRlcmFsICAgIDwtIGZhY3Rvcih0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkbWVkaW9sYXRlcmFsLCBsZXZlbHMgPSBjKCdMZWZ0JywgJ01pZGxpbmUnLCAnUmlnaHQnKSkKanVzdF9zZXggPC0gc3Vic2V0KHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YVtjKCdFUlBzZXQnLCAnc2V4JywgJ2NoaW5kZXgnLCAnc3RpbXVsdXMnKV0sIGNoaW5kZXggPT0gMSAmIHN0aW11bHVzID09ICdUYXJnZXQnKQpjb25uZWN0aXZpdHlfZmlsZSA8LSAnZXJwbGFiL21lZGlhbl9jb25uZWN0aXZpdHlfYXVkaXRvcnlfb2RkYmFsbC5jc3YnCmNvbm5lY3Rpdml0eV9kYXRhIDwtIHJlYWRfY3N2KGNvbm5lY3Rpdml0eV9maWxlLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSB8PiAKICBsZWZ0X2pvaW4oeSA9IGp1c3Rfc2V4W2MoJ0VSUHNldCcsICdzZXgnKV0sIGJ5ID0gYygnRVJQc2V0JykpIHw+CiAgbXV0YXRlKGxvZ19tZWRpYW5fY29ubmVjdGl2aXR5ID0gbG9nKG1lZGlhbl9jb25uZWN0aXZpdHkpKSB8PiAKICBtdXRhdGUoc3RpbXVsdXMgPSBmYWN0b3Ioc3RpbXVsdXMsIGxldmVscyA9IGMoJ3RhcmdldCcsICdzdGFuZGFyZCcpKSkgfD4gCiAgbXV0YXRlKG51bV9pZCA9IHBhcnNlX251bWJlcihFUlBzZXQpKSB8PiAKICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLCBhcy5mYWN0b3IpIHw+IAogIG11dGF0ZShyZWdpb25fYiA9IGZhY3RvcihyZWdpb25fYiwgbGV2ZWxzID0gYygnY2luZ3VsYXRlX2lwc2knLCAnY2luZ3VsYXRlX2NvbnRyYScpKSkKaWYgKGV4Y2x1ZGVfYmFkX2VlZykgewogIHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSA8LSB0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGFbISh0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGEkRVJQc2V0ICVpbiUgYmFkX2VlZyksIF0KICBjb25uZWN0aXZpdHlfZGF0YSAgICAgICAgPC0gY29ubmVjdGl2aXR5X2RhdGFbIShjb25uZWN0aXZpdHlfZGF0YSRFUlBzZXQgJWluJSBiYWRfZWVnKSwgXQogIH0Kd3JpdGUuY3N2KHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSwgIGZpbGUucGF0aChkYXRhX2RpciwgJ3RhcmdldHNfYW5kX3N0YW5kYXJkc19kYXRhX2NsZWFuLmNzdicpLCAgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoKIyBQYXJ0aWNpcGFudHMKYGBge3IgcGFydGljaXBhbnRzLCBmaWcud2lkdGggPSAxMn0Kb3B0aW9ucyh3aWR0aCA9IDEwMCkKbXl0YWJsZSA8LSB4dGFicyh+IHNleCArIGJlbGllZiwgZGF0YSA9IHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSkgLyBsZW5ndGgodW5pcXVlKHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRjaGluZGV4KSkgLyBsZW5ndGgodW5pcXVlKHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRzdGltdWx1cykpCmZ0YWJsZShhZGRtYXJnaW5zKG15dGFibGUpKQpgYGAKCiMgQmFkIEVFRyBjaGFubmVscwpgYGB7ciBiYWRjaGFuLCBmaWcud2lkdGggPSAxMn0KZ2dwbG90KGVlZ19jaGVjaywgYWVzKGJhZGNoYW5fbnVtKSkgKyBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTIsIGNvbG9yID0gJ2RhcmtibHVlJywgZmlsbCA9ICdsaWdodGJsdWUnKSArIHNjYWxlX3hfY29udGludW91cyhicmVha3M9MDoxMSkKeHRhYnMofiBiYWRjaGFuX251bSwgZGF0YSA9IGVlZ19jaGVjaykKYGBgCgojIEVSUCBwbG90cwojIyBUYXJnZXQgYW5kIFN0YW5kYXJkOgohW10oYXVkaXRvcnlfb2RkYmFsbC5wbmcpCgojIyBUb3BvZ3JhcGhpYyBsYXlvdXQ6CiFbXShhdWRpdG9yeV9vZGRiYWxsX3RvcG9ncmFwaHkucG5nKQoKIyBHZW5lcmFsIGRlc2NyaXB0aW9uCmBgYHtyIGdlbmVyYWwsIGZpZy53aWR0aCA9IDEyfQpvcHRpb25zKHdpZHRoID0gMTAwKQpzdW1tYXJ5KHRhcmdldF9hbmRfc3RhbmRhcmRfZGF0YVtjKCd1dm9sdHMnLCAnc2V4JywgJ3Z1bG5lcmFiaWxpdHknLCAnYmVsaWVmJywgJ3N0aW11bHVzJywgJ2FudGVyb3Bvc3RlcmlvcicsICdtZWRpb2xhdGVyYWwnLCAnbnVtX2lkJyldKQpgYGAKCiMgVGFyZ2V0cyBhbmQgU3RhbmRhcmRzIGJ5IHRvcG9ncmFwaHkKCmBgYHtyIHRyZyAmIHN0ZCwgZmlnLndpZHRoID0gMTJ9Cm9wdGlvbnMod2lkdGggPSAxMDApCnRhcmdldF9hbmRfc3RhbmRhcmRfcmVwX2Fub3ZhID0gYW92X2V6KCJudW1faWQiLCAidXZvbHRzIiwgdGFyZ2V0X2FuZF9zdGFuZGFyZF9kYXRhLCB3aXRoaW4gPSBjKCJzdGltdWx1cyIsICJhbnRlcm9wb3N0ZXJpb3IiLCAibWVkaW9sYXRlcmFsIikpCgp0YXJnZXRfYW5kX3N0YW5kYXJkX3JhaW5fY2VudHJhbCA8LSBnZ3Bsb3QodGFyZ2V0X2FuZF9zdGFuZGFyZF9kYXRhW3RhcmdldF9hbmRfc3RhbmRhcmRfZGF0YSRhbnRlcm9wb3N0ZXJpb3IgPT0gIkNlbnRyYWwiLCBdLCBhZXMoeSA9IHV2b2x0cywgeCA9IG1lZGlvbGF0ZXJhbCwgY29sb3IgPSBzdGltdWx1cywgZmlsbCA9IHN0aW11bHVzKSkgKwogIGdndGl0bGUoIlRhcmdldHMgYW5kIFN0YW5kYXJkcyBDZW50cmFsIikgKwogIHlsYWIoInV2b2x0cyIpICsKICBzdGF0X2hhbGZleWUoCiAgICB0cmltICAgPSBGQUxTRSwgCiAgICBhZGp1c3QgPSAuNzUsIAogICAgLndpZHRoID0gMCwgCiAgICBqdXN0aWZpY2F0aW9uID0gLS4xNSwgCiAgICBhbHBoYSAgPSAuNCwKICAgIHBvaW50X2NvbG91ciA9IE5BKSArIAogICMgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSdub25lJykKICBnZW9tX2JveHBsb3Qod2lkdGggPSAuMTUsIGFscGhhID0gLjIsIG91dGxpZXIuc2hhcGUgPSBOQSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gLjQsIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gLjA1LCBoZWlnaHQgPSAwKSkgCnN1cHByZXNzV2FybmluZ3MocHJpbnQodGFyZ2V0X2FuZF9zdGFuZGFyZF9yYWluX2NlbnRyYWwpKQoKdGFyZ2V0X2FuZF9zdGFuZGFyZF9yYWluX3BhcmlldGFsIDwtIGdncGxvdCh0YXJnZXRfYW5kX3N0YW5kYXJkX2RhdGFbdGFyZ2V0X2FuZF9zdGFuZGFyZF9kYXRhJGFudGVyb3Bvc3RlcmlvciA9PSAiQ2VudHJvLXBhcmlldGFsIiwgXSwgYWVzKHkgPSB1dm9sdHMsIHggPSBtZWRpb2xhdGVyYWwsIGNvbG9yID0gc3RpbXVsdXMsIGZpbGwgPSBzdGltdWx1cykpICsKICBnZ3RpdGxlKCJUYXJnZXRzIGFuZCBTdGFuZGFyZHMgQ2VudHJvLVBhcmlldGFsIikgKwogIHlsYWIoInV2b2x0cyIpICsKICBzdGF0X2hhbGZleWUoCiAgICB0cmltICAgPSBGQUxTRSwgCiAgICBhZGp1c3QgPSAuNzUsIAogICAgLndpZHRoID0gMCwgCiAgICBqdXN0aWZpY2F0aW9uID0gLS4xNSwgCiAgICBhbHBoYSAgPSAuNCwKICAgIHBvaW50X2NvbG91ciA9IE5BKSArIAogICMgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSdub25lJykKICBnZW9tX2JveHBsb3Qod2lkdGggPSAuMTUsIGFscGhhID0gLjIsIG91dGxpZXIuc2hhcGUgPSBOQSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gLjQsIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gLjA1LCBoZWlnaHQgPSAwKSkgCnN1cHByZXNzV2FybmluZ3MocHJpbnQodGFyZ2V0X2FuZF9zdGFuZGFyZF9yYWluX3BhcmlldGFsKSkKCnRhcmdldF9hbmRfc3RhbmRhcmRfYWZleF9wbG90IDwtCiAgYWZleF9wbG90KAogICAgdGFyZ2V0X2FuZF9zdGFuZGFyZF9yZXBfYW5vdmEsCiAgICB4ID0gImFudGVyb3Bvc3RlcmlvciIsCiAgICB0cmFjZSA9ICJzdGltdWx1cyIsCiAgICBwYW5lbCA9ICJtZWRpb2xhdGVyYWwiLAogICAgZXJyb3IgPSAid2l0aGluIiwKICAgIGVycm9yX2FyZyA9IGxpc3Qod2lkdGggPSAuMTUpLAogICAgZG9kZ2UgICAgID0gbXlfZG9kZ2UsCiAgICBkYXRhX2FyZyAgPSBsaXN0KAogICAgICBwb3NpdGlvbiA9IAogICAgICAgIHBvc2l0aW9uX2ppdHRlcmRvZGdlKAogICAgICAgICAgaml0dGVyLndpZHRoICA9IC4xLCAKICAgICAgICAgIGRvZGdlLndpZHRoICAgPSBteV9kb2RnZQogICAgICAgICkpLAogICAgbWFwcGluZyAgID0gYygnY29sb3InKSwKICAgIHBvaW50X2FyZyA9IGxpc3Qoc2l6ZSA9IDQpCiAgKQpzdXBwcmVzc1dhcm5pbmdzKHByaW50KHRhcmdldF9hbmRfc3RhbmRhcmRfYWZleF9wbG90KSkKbmljZSh0YXJnZXRfYW5kX3N0YW5kYXJkX3JlcF9hbm92YSkKYV9wb3N0ZXJpb3JpKHRhcmdldF9hbmRfc3RhbmRhcmRfcmVwX2Fub3ZhKQpgYGAKCmBgYHtyIExvYWQgcDMgZGF0YX0KIyBQM19kYXRhX25hbWUgICA8LSBmaWxlLnBhdGgoZGF0YV9kaXIsICdhdmVyYWdlX3ZvbHRhZ2VfMjc1X3RvXzQyNV9hdWRpdG9yeV9vZGRiYWxsLnR4dCcpClAzX2RhdGFfbmFtZSAgIDwtIGZpbGUucGF0aChkYXRhX2RpciwgJ2F2ZXJhZ2Vfdm9sdGFnZV8zMDBfdG9fNDAwX2F1ZGl0b3J5X29kZGJhbGwudHh0JykKUDNfZGF0YSAgICAgICAgPC0gcmVhZC50YWJsZShQM19kYXRhX25hbWUsIGhlYWRlciA9IFRSVUUsIHN0cmlwLndoaXRlID0gVFJVRSwgc2VwID0gIlx0IikKbmFtZXMoUDNfZGF0YSlbbmFtZXMoUDNfZGF0YSkgPT0gInZhbHVlIl0gPC0gInV2b2x0cyIKUDNfZGF0YSRudW1faWQgPC0gcmVhZHI6OnBhcnNlX251bWJlcihQM19kYXRhJEVSUHNldCkKUDNfZGF0YSR2dWxuZXJhYmlsaXR5WyBncmVwbCgiblZ1bCIsIFAzX2RhdGEkRVJQc2V0KV0gPC0gIkludnVsbmVyYWJsZSIKUDNfZGF0YSR2dWxuZXJhYmlsaXR5WyFncmVwbCgiblZ1bCIsIFAzX2RhdGEkRVJQc2V0KV0gPC0gIlZ1bG5lcmFibGUiClAzX2RhdGEkYmVsaWVmWyBncmVwbCgibkNyIiwgUDNfZGF0YSRFUlBzZXQpXSAgICAgICAgIDwtICJVbmJlbGlldmVyIgpQM19kYXRhJGJlbGllZlshZ3JlcGwoIm5DciIsIFAzX2RhdGEkRVJQc2V0KV0gICAgICAgICA8LSAiQmVsaWV2ZXIiClAzX2RhdGEkc2V4WyBncmVwbCgiRiIsIFAzX2RhdGEkRVJQc2V0KV0gICAgICAgICAgICAgIDwtICJGZW1hbGUiClAzX2RhdGEkc2V4WyFncmVwbCgiRiIsIFAzX2RhdGEkRVJQc2V0KV0gICAgICAgICAgICAgIDwtICJNYWxlIgpQM19kYXRhJGFudGVyb3Bvc3RlcmlvcltQM19kYXRhJGNobGFiZWwgJWluJSBjKCdDMScsICdDeicsICdDMicpXSAgICAgICAgICAgICAgICA8LSAnQ2VudHJhbCcKUDNfZGF0YSRhbnRlcm9wb3N0ZXJpb3JbUDNfZGF0YSRjaGxhYmVsICVpbiUgYygnRTExMi1DUDFhJywgJ0NQeicsICdFMDM0LUNQMmEnKV0gPC0gJ0NlbnRyby1wYXJpZXRhbCcKUDNfZGF0YSRtZWRpb2xhdGVyYWxbUDNfZGF0YSRjaGxhYmVsICVpbiUgYygnQzEnLCAnRTExMi1DUDFhJyldICAgICAgICAgICAgICAgICAgPC0gJ0xlZnQnClAzX2RhdGEkbWVkaW9sYXRlcmFsW1AzX2RhdGEkY2hsYWJlbCAlaW4lIGMoJ0N6JywgJ0NQeicpXSAgICAgICAgICAgICAgICAgICAgICAgIDwtICdNaWRsaW5lJwpQM19kYXRhJG1lZGlvbGF0ZXJhbFtQM19kYXRhJGNobGFiZWwgJWluJSBjKCdDMicsICdFMDM0LUNQMmEnKV0gICAgICAgICAgICAgICAgICA8LSAnUmlnaHQnClAzX2RhdGEkbnVtX2lkICAgICAgICAgIDwtIGZhY3RvcihQM19kYXRhJG51bV9pZCkKUDNfZGF0YSR2dWxuZXJhYmlsaXR5ICAgPC0gZmFjdG9yKFAzX2RhdGEkdnVsbmVyYWJpbGl0eSkKUDNfZGF0YSRzZXggICAgICAgICAgICAgPC0gZmFjdG9yKFAzX2RhdGEkc2V4KQpQM19kYXRhJGJlbGllZiAgICAgICAgICA8LSBmYWN0b3IoUDNfZGF0YSRiZWxpZWYpClAzX2RhdGEkYW50ZXJvcG9zdGVyaW9yIDwtIGZhY3RvcihQM19kYXRhJGFudGVyb3Bvc3RlcmlvcikKUDNfZGF0YSRtZWRpb2xhdGVyYWwgICAgPC0gZmFjdG9yKFAzX2RhdGEkbWVkaW9sYXRlcmFsLCBsZXZlbHMgPSBjKCdMZWZ0JywgJ01pZGxpbmUnLCAnUmlnaHQnKSkKaWYgKGV4Y2x1ZGVfYmFkX2VlZykgewogIFAzX2RhdGEgPC0gUDNfZGF0YVshKFAzX2RhdGEkRVJQc2V0ICVpbiUgYmFkX2VlZyksIF0KfQp3cml0ZS5jc3YoUDNfZGF0YSwgIGZpbGUucGF0aChkYXRhX2RpciwgJ2F1ZGl0b3J5X29kZGJhbGxfZGF0YV9jbGVhbi5jc3YnKSwgIHJvdy5uYW1lcyA9IEZBTFNFKQpQM19kYXRhLnRhYmxlIDwtIGRhdGEudGFibGUoUDNfZGF0YSkKUDNfYnlfc3ViamVjdCA8LSB1bmlxdWUoUDNfZGF0YS50YWJsZVssIC4od29ya2xhdCwgbWxhYmVsLCB1dl9tZWFuID0gbWVhbih1dm9sdHMpLCBiaW5pLCBiaW5sYWJlbCwgbnVtX2lkLCB2dWxuZXJhYmlsaXR5LCBiZWxpZWYsIHNleCksIGJ5ID0gLihFUlBzZXQpXSkKUDNfYnlfc3ViamVjdCRSVVQgPC0gc3ViKCJfb2RkLioiLCAiIiwgUDNfYnlfc3ViamVjdCRFUlBzZXQpClAzX2J5X3N1YmplY3QkUlVUIDwtIHN1YigiLipGIiwgIiIsIFAzX2J5X3N1YmplY3QkUlVUKQpQM19ieV9zdWJqZWN0JFJVVCA8LSBzdWIoIi4qTSIsICIiLCBQM19ieV9zdWJqZWN0JFJVVCkKd3JpdGUuY3N2KFAzX2J5X3N1YmplY3QsICBmaWxlLnBhdGgoZGF0YV9kaXIsICdQM19ieV9zdWJqZWN0LmNzdicpLCAgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoKIyBQMyBwbG90cwojIyBXYXZlIGRpZmZlcmVuY2UsIFRhcmdldCAtIFN0YW5kYXJkCiFbXShhdWRpdG9yeV9vZGRiYWxsX3AzLnBuZykKCiMjIFdhdmUgZGlmZmVyZW5jZSBzY2FscCwgVGFyZ2V0IC0gU3RhbmRhcmQKIVtdKGF1ZGl0b3J5X29kZGJhbGxfcDNfc2NhbHAucG5nKQoKIyMgV2F2ZSBkaWZmZXJlbmNlIGxheW91dAohW10oYXVkaXRvcnlfb2RkYmFsbF9wM190b3BvZ3JhcGh5LnBuZykKCiMgUDMgZ2VuZXJhbCBkZXNjcmlwdGlvbgpNZWFzdXJlbWVudCB3aW5kb3c6IGByIFAzX2RhdGEkd29ya2xhdFsxXWAgbXMKYGBge3IgZ2VuZXJhbCBwMywgZmlnLndpZHRoID0gMTJ9Cm9wdGlvbnMod2lkdGggPSAxMDApCnN1bW1hcnkoUDNfZGF0YVtjKCd1dm9sdHMnLCAnc2V4JywgJ3Z1bG5lcmFiaWxpdHknLCAnYmVsaWVmJywgJ2FudGVyb3Bvc3RlcmlvcicsICdtZWRpb2xhdGVyYWwnLCAnbnVtX2lkJyldKQpgYGAKCiMgUDMgYnkgdG9wb2dyYXBoeQoKYGBge3IgUDMsIGZpZy53aWR0aCA9IDEyfQpvcHRpb25zKHdpZHRoID0gMTAwKQpQM19yYWluIDwtIGdncGxvdChQM19kYXRhLCBhZXMoeSA9IHV2b2x0cywgeCA9IG1lZGlvbGF0ZXJhbCwgY29sb3IgPSBhbnRlcm9wb3N0ZXJpb3IsIGZpbGwgPSBhbnRlcm9wb3N0ZXJpb3IpKSArCiAgZ2d0aXRsZSgiUDMiKSArCiAgeWxhYigidXZvbHRzIikgKwogIHN0YXRfaGFsZmV5ZSgKICAgIHRyaW0gICA9IEZBTFNFLCAKICAgIGFkanVzdCA9IC43NSwgCiAgICAud2lkdGggPSAwLCAKICAgIGp1c3RpZmljYXRpb24gPSAtLjE1LCAKICAgIGFscGhhICA9IC40LAogICAgcG9pbnRfY29sb3VyID0gTkEpICsgCiAgIyB0aGVtZShsZWdlbmQucG9zaXRpb249J25vbmUnKQogICMgZ2VvbV9ib3hwbG90KHdpZHRoID0gLjE1LCBhbHBoYSA9IC4yLCBvdXRsaWVyLnNoYXBlID0gTkEpICsKICBnZW9tX3BvaW50KHNpemUgPSAyLCBhbHBoYSA9IC40LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IC4wNSwgaGVpZ2h0ID0gMCkpIApzdXBwcmVzc1dhcm5pbmdzKHByaW50KFAzX3JhaW4pKQpQM19yZXBfYW5vdmEgPSBhb3ZfZXooIm51bV9pZCIsICJ1dm9sdHMiLCBQM19kYXRhLCB3aXRoaW4gPSBjKCJhbnRlcm9wb3N0ZXJpb3IiLCAibWVkaW9sYXRlcmFsIikpClAzX2FmZXhfcGxvdCA8LQogIGFmZXhfcGxvdCgKICAgIFAzX3JlcF9hbm92YSwKICAgIHggPSAibWVkaW9sYXRlcmFsIiwKICAgIHRyYWNlID0gImFudGVyb3Bvc3RlcmlvciIsCiAgICBlcnJvciA9ICJ3aXRoaW4iLAogICAgZXJyb3JfYXJnID0gbGlzdCh3aWR0aCA9IC4xNSksCiAgICBkb2RnZSAgICAgPSBteV9kb2RnZSwKICAgIGRhdGFfYXJnICA9IGxpc3QoCiAgICAgIHBvc2l0aW9uID0gCiAgICAgICAgcG9zaXRpb25faml0dGVyZG9kZ2UoCiAgICAgICAgICBqaXR0ZXIud2lkdGggID0gLjEsIAogICAgICAgICAgZG9kZ2Uud2lkdGggICA9IG15X2RvZGdlCiAgICAgICAgKSksCiAgICBtYXBwaW5nICAgPSBjKCdjb2xvcicpLAogICAgcG9pbnRfYXJnID0gbGlzdChzaXplID0gNCkKICApCnN1cHByZXNzV2FybmluZ3MocHJpbnQoUDNfYWZleF9wbG90KSkKbmljZShQM19yZXBfYW5vdmEpCmFfcG9zdGVyaW9yaShQM19yZXBfYW5vdmEpCmBgYAoKIyBQMyBieSBiZWxpZWYgYW5kIHNleAoKYGBge3IgcDNfc2V4LCBmaWcud2lkdGggPSAxMn0Kb3B0aW9ucyh3aWR0aCA9IDEwMCkKUDNfYW5vdmFfc2V4ID0gYW92X2V6KCJudW1faWQiLCAidXZvbHRzIiwgUDNfZGF0YSwgYmV0d2VlbiA9IGMoImJlbGllZiIsICJzZXgiKSwgZnVuX2FnZ3JlZ2F0ZSA9IG1lYW4pCm15dGFibGUgPC0geHRhYnMofiBzZXggKyBiZWxpZWYsIGRhdGEgPSBQM19hbm92YV9zZXgkZGF0YSRsb25nKQpmdGFibGUoYWRkbWFyZ2lucyhteXRhYmxlKSkKUDNfYWZleF9wbG90X3NleCA8LQogIGFmZXhfcGxvdCgKICAgIFAzX2Fub3ZhX3NleCwKICAgIHggICAgID0gImJlbGllZiIsCiAgICB0cmFjZSA9ICJzZXgiLAogICAgZXJyb3IgPSAiYmV0d2VlbiIsCiAgICBlcnJvcl9hcmcgPSBsaXN0KHdpZHRoID0gLjE1KSwKICAgIGRvZGdlICAgICA9IG15X2RvZGdlLAogICAgZGF0YV9hcmcgID0gbGlzdCgKICAgICAgcG9zaXRpb24gPSAKICAgICAgICBwb3NpdGlvbl9qaXR0ZXJkb2RnZSgKICAgICAgICAgIGppdHRlci53aWR0aCAgPSAuMSwgCiAgICAgICAgICBkb2RnZS53aWR0aCAgID0gbXlfZG9kZ2UKICAgICAgICApKSwKICAgIG1hcHBpbmcgICA9IGMoJ2NvbG9yJyksCiAgICBwb2ludF9hcmcgPSBsaXN0KHNpemUgPSA0KQogICkKc3VwcHJlc3NXYXJuaW5ncyhwcmludChQM19hZmV4X3Bsb3Rfc2V4KSkKbmljZShQM19hbm92YV9zZXgpCmFfcG9zdGVyaW9yaShQM19hbm92YV9zZXgpCmBgYAoKIyBEZWNvZGluZyAoTVZQQSkKRmFocmVuZm9ydCwgSi4gSi4sIHZhbiBEcmllbCwgSi4sIHZhbiBHYWFsLCBTLiwgJiBPbGl2ZXJzLCBDLiBOLiBMLiAoMjAxOCkuIEZyb20gRVJQcyB0byBNVlBBIHVzaW5nIHRoZSBBbXN0ZXJkYW0gRGVjb2RpbmcgYW5kIE1vZGVsaW5nIHRvb2xib3ggKEFEQU0pLiBGcm9udGllcnMgaW4gTmV1cm9zY2llbmNlLCAxMihKVUwpLCAzNTE1ODYuIGh0dHBzOi8vZG9pLm9yZy8xMC4zMzg5L0ZOSU5TLjIwMTguMDAzNjgvQklCVEVYCgoqKkFsbCBjaGFubmVscywgcmVmZXJlbmNlIHRvIGluZmluaXRlLCA0MCBIeiBsb3ctcGFzcyoqXApEb25nLCBMLiwgTGksIEYuLCBMaXUsIFEuLCBXZW4sIFguLCBMYWksIFkuLCBYdSwgUC4sICYgWWFvLCBELiAoMjAxNykuIE1BVExBQiBUb29sYm94ZXMgZm9yIFJlZmVyZW5jZSBFbGVjdHJvZGUgU3RhbmRhcmRpemF0aW9uIFRlY2huaXF1ZSAoUkVTVCkgb2YgU2NhbHAgRUVHLiBGcm9udGllcnMgaW4gTmV1cm9zY2llbmNlLCAxMShPQ1QpLCA2MDEuIGh0dHBzOi8vZG9pLm9yZy8xMC4zMzg5L2ZuaW5zLjIwMTcuMDA2MDEKCiMjIEV4ZW1wbGFyIEVSUCBvbiBDegohW10oLi4vLi4vQURBTS9QTE9UUy8wMV9leGVtcGxhcl9FUlBfZmVtYWxlX0N6LnBuZykKIVtdKC4uLy4uL0FEQU0vUExPVFMvMDJfZXhlbXBsYXJfRVJQX21hbGVfQ3oucG5nKQoKIyMgRVJQIGRpZmZlcmVuY2Ugb24gQ3oKIVtdKC4uLy4uL0FEQU0vUExPVFMvMDNfZXhlbXBsYXJfRVJQX2RpZmZlcnJlbmNlX2JvdGhfQ3oucG5nKQoKIyMgRGVjb2Rpbmcgb3ZlciB0aW1lCiMjIyAxMC1mb2xkIGNyb3NzIHZhbGlkYXRpb24KIVtdKC4uLy4uL0FEQU0vUExPVFMvMDRfZGVjb2Rpbmdfb3Zlcl90aW1lX2JvdGgucG5nKQoKIyMjIFRyYWluIDEmMywgdGVzdCAyJjQKIVtdKC4uLy4uL0FEQU0vUExPVFNfY3Jvc3Nfc3RpbS8wNF9kZWNvZGluZ19vdmVyX3RpbWVfYm90aC5wbmcpCgoKIyMgSW5kaXZpZHVhbCByZXN1bHRzCiFbXSguLi8uLi9BREFNL1BMT1RTLzA1X2RlY29kaW5nX2J5X3N1YmplY3RfZmVtYWxlLnBuZykKIVtdKC4uLy4uL0FEQU0vUExPVFMvMDZfZGVjb2RpbmdfYnlfc3ViamVjdF9tYWxlLnBuZykKCiMjIEFjdGl2YXRpb24gcGF0dGVybnMKIyMjIDEwLWZvbGQgY3Jvc3MgdmFsaWRhdGlvbgohW10oLi4vLi4vQURBTS9QTE9UUy8wN19hY3RpdmF0aW9uX3BhdHRlcm5zLnBuZykKCiMjIyBUcmFpbiAxJjMsIHRlc3QgMiY0CiFbXSguLi8uLi9BREFNL1BMT1RTX2Nyb3NzX3N0aW0vMDdfYWN0aXZhdGlvbl9wYXR0ZXJucy5wbmcpCgojIyBUZW1wb3JhbCBnZW5lcmFsaXphdGlvbiBwbG90CiMjIyAxMC1mb2xkIGNyb3NzIHZhbGlkYXRpb24KIVtdKC4uLy4uL0FEQU0vUExPVFMvMDhfdGVtcG9yYWxfZ2VuZXJhbGl6YXRpb25fbWF0cml4LnBuZykKCiMjIyBUcmFpbiAxJjMsIHRlc3QgMiY0CiFbXSguLi8uLi9BREFNL1BMT1RTX2Nyb3NzX3N0aW0vMDhfdGVtcG9yYWxfZ2VuZXJhbGl6YXRpb25fbWF0cml4LnBuZykKCiMjIEdlbmVyYWxpemF0aW9uIG92ZXIgdGltZQojIyMgMTAtZm9sZCBjcm9zcyB2YWxpZGF0aW9uCiFbXSguLi8uLi9BREFNL1BMT1RTLzA5X3RlbXBvcmFsX2dlbmVyYWxpemF0aW9uX292ZXJfdGltZV90cmFpbmluZ18zNTBfNDAwLnBuZykKCiMjIyBUcmFpbiAxJjMsIHRlc3QgMiY0CiFbXSguLi8uLi9BREFNL1BMT1RTX2Nyb3NzX3N0aW0vMDlfdGVtcG9yYWxfZ2VuZXJhbGl6YXRpb25fb3Zlcl90aW1lX3RyYWluaW5nXzM1MF80MDAucG5nKQoKIyMgR3JvdXAgZGVjb2RpbmcgZGlmZmVyZW5jZXMKIyMjIDEwLWZvbGQgY3Jvc3MgdmFsaWRhdGlvbgohW10oLi4vLi4vQURBTS9QTE9UUy8xMF9ncm91cF9kZWNvZGluZ19kaWZmZXJlbmNlLnBuZykKCiMjIyBUcmFpbiAxJjMsIHRlc3QgMiY0CiFbXSguLi8uLi9BREFNL1BMT1RTX2Nyb3NzX3N0aW0vMTBfZ3JvdXBfZGVjb2RpbmdfZGlmZmVyZW5jZS5wbmcpCgojIFRlbXBvcm8tY2luZ3VsYXRlIHRoZXRhLWFscGhhICg0LTEyIEh6KSBGdW5jdGlvbmFsIENvbm5lY3Rpdml0eSAoUk9JY29ubmVjdCkKTXVsdGl2YXJpYXRlIEludGVyYWN0aW9uIE1lYXN1cmUsIE1JTSBbQFBlbGxlZ3JpbmkyMDIzXS4gXAo4MDAgbXMgcG9zdC1zdGltdWx1cy4KCmBgYHtyIGNvbm5lY3Rpdml0eSBkZXNjcmlwdGlvbn0Kb3B0aW9ucyh3aWR0aCA9IDEwMCkKc3VtbWFyeShjb25uZWN0aXZpdHlfZGF0YSkKY29ubmVjdGl2aXR5X2RhdGFfd2lkZV9jaW5ndWxhdGUgPC0gY29ubmVjdGl2aXR5X2RhdGFbYygnRVJQc2V0JywgJ3JlZ2lvbl9hJywgJ3JlZ2lvbl9iJywgJ3N0aW11bHVzJywgJ2xvZ19tZWRpYW5fY29ubmVjdGl2aXR5JyldIHw+CiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHJlZ2lvbl9iLCB2YWx1ZXNfZnJvbSA9IGxvZ19tZWRpYW5fY29ubmVjdGl2aXR5KQpjb25uZWN0aXZpdHlfZGF0YV93aWRlX3RlbXBvcmFsIDwtIGNvbm5lY3Rpdml0eV9kYXRhW2MoJ0VSUHNldCcsICdyZWdpb25fYScsICdyZWdpb25fYicsICdzdGltdWx1cycsICdsb2dfbWVkaWFuX2Nvbm5lY3Rpdml0eScpXSB8PgogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSByZWdpb25fYSwgdmFsdWVzX2Zyb20gPSBsb2dfbWVkaWFuX2Nvbm5lY3Rpdml0eSkKY29ubmVjdGl2aXR5X2RhdGFfd2lkZV9zdGltdWx1cyAgIDwtIGNvbm5lY3Rpdml0eV9kYXRhW2MoJ0VSUHNldCcsICdyZWdpb25fYScsICdyZWdpb25fYicsICdzdGltdWx1cycsICdsb2dfbWVkaWFuX2Nvbm5lY3Rpdml0eScpXSB8PgogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGltdWx1cywgdmFsdWVzX2Zyb20gPSBsb2dfbWVkaWFuX2Nvbm5lY3Rpdml0eSkKc3RpbXVsdXMgICA8LSBjKCd0YXJnZXQnICAgICAgICAgLCAnc3RhbmRhcmQnKQp0ZW1wb3JhbCAgIDwtIGMoJ2xlZnRfdGVtcG9yYWwnICAsICdyaWdodF90ZW1wb3JhbCcpCmNpbmd1bGF0ZSA8LSBjKCdjaW5ndWxhdGVfaXBzaScsICdjaW5ndWxhdGVfY29udHJhJykKY2luZ3VsYXRlX3BhaXJzIDwtIGdncGFpcnMoY29ubmVjdGl2aXR5X2RhdGFfd2lkZV9jaW5ndWxhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoY29sb3VyID0gc3RpbXVsdXMsIGFscGhhID0gLjUsIGxpbmV3aWR0aCA9IE5BKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbnMgID0gY2luZ3VsYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXIgICAgPSBsaXN0KGNvbnRpbnVvdXMgPSB3cmFwKCdwb2ludHMnLCBhbHBoYSA9IC40KSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9ncmVzcyA9IEZBTFNFCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCnRlbXBvcmFsX3BhaXJzIDwtIGdncGFpcnMoY29ubmVjdGl2aXR5X2RhdGFfd2lkZV90ZW1wb3JhbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyhjb2xvdXIgPSBzdGltdWx1cywgYWxwaGEgPSAuNSwgbGluZXdpZHRoID0gTkEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1ucyAgPSB0ZW1wb3JhbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VyICAgID0gbGlzdChjb250aW51b3VzID0gd3JhcCgncG9pbnRzJywgYWxwaGEgPSAuNCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3MgPSBGQUxTRQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKQpzdGltdWx1c19wYWlycyA8LSBnZ3BhaXJzKGNvbm5lY3Rpdml0eV9kYXRhX3dpZGVfc3RpbXVsdXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoY29sb3VyID0gcmVnaW9uX2IsIGFscGhhID0gLjUsIGxpbmV3aWR0aCA9IE5BKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbnMgID0gc3RpbXVsdXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb3dlciAgICA9IGxpc3QoY29udGludW91cyA9IHdyYXAoJ3BvaW50cycsIGFscGhhID0gLjQpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2dyZXNzID0gRkFMU0UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKc3VwcHJlc3NXYXJuaW5ncyhwcmludChjaW5ndWxhdGVfcGFpcnMpKQpzdXBwcmVzc1dhcm5pbmdzKHByaW50KHRlbXBvcmFsX3BhaXJzKSkKc3VwcHJlc3NXYXJuaW5ncyhwcmludChzdGltdWx1c19wYWlycykpCmBgYAoKIyMgQ29ubmVjdGl2aXR5IEFOT1ZBOgoKYGBge3IgY29ubmVjdGl2aXR5IGFub3ZhIGNhbGMsIGZpZy53aWR0aCA9IDh9CmNvbm5lY3Rpdml0eV9yZXBfYW5vdmEgPC0gYW92X2V6KCdudW1faWQnLCAnbG9nX21lZGlhbl9jb25uZWN0aXZpdHknLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aXZpdHlfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXRoaW4gPSBjKCdzdGltdWx1cycsICdyZWdpb25fYScsICdyZWdpb25fYicpKQpjb25uZWN0aXZpdHlfYWZleF9wbG90IDwtIGFmZXhfcGxvdChjb25uZWN0aXZpdHlfcmVwX2Fub3ZhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggICAgID0gJ3JlZ2lvbl9hJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFjZSA9ICdzdGltdWx1cycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFuZWwgPSAncmVnaW9uX2InLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gJ3dpdGhpbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JfYXJnID0gbGlzdCh3aWR0aCA9IC4zLCBsd2QgPSAuNzUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvZGdlID0gLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YV9hcmcgID0gbGlzdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uX2ppdHRlcmRvZGdlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGppdHRlci53aWR0aCA9IC4yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2RnZS53aWR0aCAgPSAuNSAgIyMgbmVlZHMgdG8gYmUgc2FtZSBhcyBkb2RnZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXBwaW5nICAgPSBjKCdjb2xvcicpLCwgZGF0YV9hbHBoYSA9IC4zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50X2FyZyA9IGxpc3Qoc2l6ZSA9IDMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQpzdXBwcmVzc1dhcm5pbmdzKHByaW50KGNvbm5lY3Rpdml0eV9hZmV4X3Bsb3QpKQpgYGAKCmBgYHtyIGNvbm5lY3Rpdml0eSBhbm92YSBzaG93fQpteXRhYmxlIDwtIHh0YWJzKH4gc3RpbXVsdXMgKyByZWdpb25fYSArIHJlZ2lvbl9iLCBkYXRhID0gY29ubmVjdGl2aXR5X3JlcF9hbm92YSRkYXRhJGxvbmcpCmZ0YWJsZShteXRhYmxlKQpwcmludChjb25uZWN0aXZpdHlfcmVwX2Fub3ZhKQphX3Bvc3RlcmlvcmkoY29ubmVjdGl2aXR5X3JlcF9hbm92YSkKYGBgCiMjIENvbm5lY3Rpdml0eSBBc3N1bXB0aW9uczoKCmBgYHtyIGNvbm5lY3Rpdml0eSBhc3N1bXB0aW9uc30Kbm9ybV9jb25uZWN0aXZpdHkgPC0gY2hlY2tfbm9ybWFsaXR5KGNvbm5lY3Rpdml0eV9yZXBfYW5vdmEpCnByaW50KG5vcm1fY29ubmVjdGl2aXR5KQpwbG90KG5vcm1fY29ubmVjdGl2aXR5LCB0eXBlID0gJ2RlbnNpdHknKQpwbG90KG5vcm1fY29ubmVjdGl2aXR5LCB0eXBlID0gJ3FxJykKaGV0ZXJvX2Nvbm5lY3Rpdml0eSA8LSBjaGVja19oZXRlcm9zY2VkYXN0aWNpdHkoY29ubmVjdGl2aXR5X3JlcF9hbm92YSkKcHJpbnQoaGV0ZXJvX2Nvbm5lY3Rpdml0eSkKcGxvdChoZXRlcm9fY29ubmVjdGl2aXR5KQpjaGVja19zcGhlcmljaXR5KGNvbm5lY3Rpdml0eV9yZXBfYW5vdmEpCmBgYAo=