1 Load data

# Read
file = "DATE O1A Complete.xlsx"
Date <- readxl::read_xlsx(file, sheet = "Date zilnice", skip = 5, col_names = FALSE)

1.1 Processing data

# Clean
varnames <- c("Nr_crt", "ID", "Nume_Prenume", "Zi", "Vas_stres_pre", "Vas_bine_pre",
             sprintf("Stais_pre_%01d", seq(1,20)),
             "SOP",
             "IOS_mama", "IOS_tata", "IOS_iubit", "IOS_prieten", "IOS_personalitate",
             "Vas_rel_global", "Vas_rel_arousal",
             "CRQ_1", "CRQ_2", "CRQ_3", "CRQ_4", "CRQ_5", "CRQ_6",
             "Vas_stres_post", "Vas_bine_post",
             sprintf("Stais_post_%01d", seq(1,20))
)
names(Date) <- varnames   # nume noi
Date <- Date[-c(1:2),]    # scoatem randurile cu numele precedente
Date$Nr_crt <- 1:nrow(Date)   # era gol, asa ca numerotam randurile ca sa avem acesta variabila 
# Process NAs
Date <- Date %>% 
    na_if("na") %>%  
    mutate(NA_per_row = rowSums(is.na(.)))     # count NAs by row
Date <- Date %>% 
    filter(NA_per_row < 20)         # arbitrary cutoff for NAs on columns ... it is normal to have 4 NAs for all columns
# Convert to numeric
varsnumeric <- c("Zi", "Vas_stres_pre", "Vas_bine_pre",
                 sprintf("Stais_pre_%01d", seq(1,20)),
                 "IOS_mama", "IOS_tata", "IOS_iubit", "IOS_prieten", "IOS_personalitate",
                 "Vas_rel_global", "Vas_rel_arousal",
                 "CRQ_1", "CRQ_2", "CRQ_3", "CRQ_4", "CRQ_5", "CRQ_6",
                 "Vas_stres_post", "Vas_bine_post",
                  sprintf("Stais_post_%01d", seq(1,20)))
Date <- Date %>% 
  mutate_at(varsnumeric, as.numeric)
# which(Date$Stais_post_11 == 47)    # typo Stais_post_11 value of 47 -> corrected to 4
Date$Stais_post_11[Date$Stais_post_11 == 47] <- 4

1.2 Compute new variables

# Compute new variables 
Conditie <- Date %>% 
    select(Nr_crt, ID, IOS_mama, IOS_tata, IOS_iubit, IOS_prieten, IOS_personalitate) %>% 
    gather(type, value, -c(Nr_crt, ID)) %>% 
    mutate(Conditie = ifelse(!is.na(value), type, NA) ) %>%
    mutate(Conditie = str_replace(Conditie, "IOS_", "")) %>%
    arrange(Nr_crt) %>%
    select(Conditie) %>% na.omit() 
Date$Conditie <- Conditie$Conditie     # tidyverse returns tibble, must do this
IOS <- Date %>% 
  mutate(IOS = coalesce(IOS_mama, IOS_tata, IOS_iubit, IOS_prieten, IOS_personalitate)) %>%
  select(IOS)
Date$IOS <- IOS$IOS   # tidyverse returns tibble, must do this
rm(Conditie, IOS)    # remove 2 tibbles
# Scoring Stai   (convert numeric - VAS)
itemiVAS <- c(5, 6, 41, 42)
itemiStaiS_pre <- 7:26
itemiStaiS_post <- 43:62
ReversedItems <- c(1,2,5,8,10,11,15,16,19,20)
Date <- Date %>%                 
  replace(Date == "na", NA) %>%        # scimbam codarea cu na a Doinei
  mutate_at(vars(itemiStaiS_pre), funs(as.numeric)) %>%        # facem coloanele numerice pt STAI
  mutate_at(vars(itemiStaiS_post), funs(as.numeric)) %>% 
  mutate_at(vars(itemiVAS), funs(as.numeric))
Date[ ,itemiStaiS_pre[ReversedItems]] = 5 - Date[ ,itemiStaiS_pre[ReversedItems]]
Date[ ,itemiStaiS_post[ReversedItems]] = 5 - Date[ ,itemiStaiS_post[ReversedItems]]
Date$StaiS_pre = rowSums(Date[ ,itemiStaiS_pre], na.rm=T ) * NA ^ (rowSums(!is.na(Date[ ,itemiStaiS_pre])) == 0)
Date$StaiS_post = rowSums(Date[ ,itemiStaiS_post], na.rm=T ) * NA ^ (rowSums(!is.na(Date[ ,itemiStaiS_post])) == 0)

1.3 Table of derived variables

varnottable <- c("Nume_Prenume", "NA_per_row", 
                 sprintf("Stais_pre_%01d", seq(1,20)), 
                 sprintf("Stais_post_%01d", seq(1,20)))
Date %>%                              
  select(-varnottable) %>%
    DT::datatable(                                  # excel downloadable  DT table
      extensions = 'Buttons',
      options = list(pageLength = 20,
                     scrollX='500px', 
                     dom = 'Bfrtip', 
                     buttons = c('excel', "csv")))



2 Conditions

## Number of subjects per Condition
Date %>% 
  count(Conditie) %>%
  knitr::kable(caption = "Number of subjects per Condition")
Conditie n
iubit 32
mama 42
personalitate 43
prieten 40
tata 42
## Means for all variables by Condition
# Date %>% 
#   select(ID, 
#          Vas_rel_global, Vas_rel_arousal, 
#          CRQ_1, CRQ_2, CRQ_3, CRQ_4, CRQ_5, CRQ_6, 
#          Conditie, IOS) %>%
#   group_by(Conditie) %>%
#   summarise_if(.predicate = function(x) is.numeric(x),
#              .funs = funs(mean="mean"))
## Plot CRQ items
my_comparisons <- 
  gtools::combinations(n = length(unique(Date$Conditie)), r = 2, v = Date$Conditie, repeats.allowed = FALSE) %>%
  as.data.frame() %>% 
  mutate_if(is.factor, as.character) %>%
  purrr::pmap(list) %>% 
  lapply(unlist)
  
Date %>% 
  select(ID, Conditie, 
         CRQ_1, CRQ_2, CRQ_3, CRQ_4, CRQ_5, CRQ_6) %>%
  gather(variable, value, CRQ_1:CRQ_6) %>%
  mutate(Conditie = factor(Conditie, levels = sort(unique(Conditie)))) %>%   # relevel just to match combination pattern for comparison
    ggboxplot(x = "Conditie", y = "value", facet.by = "variable" ) + 
    stat_compare_means(comparisons = my_comparisons,            # can't do paired t test because not all arguments have the same length  
                       label = "p.signif", paired = FALSE, method = "t.test",  na.rm = TRUE) +
    scale_x_discrete(labels = abbreviate)

## Plot VAS Rel and IOS
func_boxcomp_cond <- function(var){
    Date %>% 
      select(Conditie, var) %>%
      mutate(Conditie = factor(Conditie, levels = sort(unique(Conditie)))) %>%   # relevel just to match combination pattern for comparison
        ggboxplot(x = "Conditie", y = var, title = var) +
        stat_compare_means(comparisons = my_comparisons,            # can't do paired t test because not all arguments have the same length  
                           label = "p.signif", paired = FALSE, method = "t.test",  na.rm = TRUE)
}
plot_vasglob <- func_boxcomp_cond("Vas_rel_global")
plot_vasarou <- func_boxcomp_cond("Vas_rel_arousal")
plot_ios <- func_boxcomp_cond("IOS")
ggarrange(plot_vasglob, 
          plot_ios, 
          plot_vasarou, 
          ncol = 2, nrow = 2)



3 STAI-Y

3.1 Plots with p values

## STAI plot 
Staimelt <- Date[, c("ID", "Conditie", "StaiS_pre","StaiS_post")] %>% 
  gather("StaiS_pre", "StaiS_post", key = "Stai_cond", value = "value") %>% 
  mutate_at(vars(c(1, 2, 3)), funs(as.factor)) %>% 
  mutate(Stai_cond = factor(Stai_cond, levels = c("StaiS_pre","StaiS_post"))) # %>%    # change factor order for plot pre, post
ggplot(Staimelt, aes(x = Stai_cond, y = value)) +
  geom_boxplot() +
  facet_wrap(~Conditie) +
  ggpubr::stat_compare_means(method = "t.test", paired = TRUE, comparisons = list(c("StaiS_pre","StaiS_post")))

3.2 t tests

## STAI tables
Date %>% 
  group_by(Conditie) %>% 
  do(broom::tidy(t.test(.$StaiS_pre, 
                        .$StaiS_post, 
                        mu = 0, 
                        alt = "two.sided", 
                        paired = TRUE, 
                        conf.level = 0.95))) %>%
  knitr::kable(digits = 2)
Conditie estimate statistic p.value parameter conf.low conf.high method alternative
iubit 0.97 0.74 0.47 31 -1.70 3.64 Paired t-test two.sided
mama -0.40 -0.44 0.66 41 -2.28 1.47 Paired t-test two.sided
personalitate 1.30 1.26 0.21 42 -0.78 3.38 Paired t-test two.sided
prieten 3.12 4.05 0.00 39 1.56 4.69 Paired t-test two.sided
tata -0.88 -0.92 0.36 41 -2.82 1.06 Paired t-test two.sided


4 VAS Stres

4.1 Plots with p values

## Vas Stres plot 
Vasstresmelt <- Date[, c("ID", "Conditie", "Vas_stres_pre","Vas_stres_post")] %>% 
  gather("Vas_stres_pre","Vas_stres_post", key = "Vas_stres_cond", value = "value") %>% 
  mutate_at(vars(c(1,2,3)), funs(as.factor)) %>% 
  mutate_at(vars(c(4)), funs(as.numeric)) %>% 
  mutate(Vas_stres_cond = factor(Vas_stres_cond, levels = c("Vas_stres_pre","Vas_stres_post"))) # change factor order for plot pre, post
ggplot(Vasstresmelt, aes(x = Vas_stres_cond, y = value)) +
  geom_boxplot() +
  facet_wrap(~Conditie) +
  ggpubr::stat_compare_means(method = "t.test", paired = TRUE, comparisons = list(c("Vas_stres_pre","Vas_stres_post")))

4.2 t tests

## Vas Stres tables
Date %>% 
  group_by(Conditie) %>% 
  do(broom::tidy(t.test(.$Vas_stres_pre, 
                        .$Vas_stres_post, 
                        mu = 0, 
                        alt = "two.sided", 
                        paired = TRUE, 
                        conf.level = 0.95))) %>%
  knitr::kable(digits = 2)
Conditie estimate statistic p.value parameter conf.low conf.high method alternative
iubit 2.09 0.76 0.45 31 -3.53 7.72 Paired t-test two.sided
mama -2.38 -1.07 0.29 41 -6.86 2.09 Paired t-test two.sided
personalitate 1.65 1.02 0.31 42 -1.62 4.92 Paired t-test two.sided
prieten 3.08 1.59 0.12 39 -0.85 7.00 Paired t-test two.sided
tata -3.69 -1.96 0.06 41 -7.50 0.12 Paired t-test two.sided


5 VAS Wellbeing

5.1 Plots with p values

## Vas Stres plot 
Vasbinemelt <- Date[, c("ID", "Conditie", "Vas_bine_pre","Vas_bine_post")] %>% 
  gather("Vas_bine_pre","Vas_bine_post", key = "Vas_stres_cond", value = "value") %>% 
  mutate_at(vars(c(1,2,3)), funs(as.factor)) %>% 
  mutate_at(vars(c(4)), funs(as.numeric)) %>% 
  mutate(Vas_stres_cond = factor(Vas_stres_cond, levels = c("Vas_bine_pre","Vas_bine_post"))) # change factor order for plot pre, post
ggplot(Vasbinemelt, aes(x = Vas_stres_cond, y = value)) +
  geom_boxplot() +
  facet_wrap(~Conditie) +
  ggpubr::stat_compare_means(method = "t.test", paired = TRUE, comparisons = list(c("Vas_bine_pre","Vas_bine_post")))

5.2 t tests

## Vas Stres tables
Date %>% 
  group_by(Conditie) %>% 
  do(broom::tidy(t.test(.$Vas_bine_pre, 
                        .$Vas_bine_post, 
                        mu = 0, 
                        alt = "two.sided", 
                        paired = TRUE, 
                        conf.level = 0.95))) %>%
  knitr::kable(digits = 2)
Conditie estimate statistic p.value parameter conf.low conf.high method alternative
iubit -2.00 -0.75 0.46 31 -7.45 3.45 Paired t-test two.sided
mama -0.10 -0.04 0.96 41 -4.45 4.26 Paired t-test two.sided
personalitate -3.05 -1.37 0.18 42 -7.52 1.43 Paired t-test two.sided
prieten -4.90 -2.76 0.01 39 -8.50 -1.30 Paired t-test two.sided
tata -0.19 -0.06 0.95 41 -6.94 6.56 Paired t-test two.sided



6 Conditioning on VAS global

Click on IDs to show in plot

# will throw warning because color palette is too small
plotly_data <- 
  Date %>%
    mutate(ID = word(ID, 1)) %>%
    select(ID, Conditie, Vas_rel_global) %>%
    gather(variable, value, Vas_rel_global) %>%
    arrange(Conditie) 
# %>%                                  # just a test
#     ggplot(aes(x = Conditie, y = value, group = ID, colour = ID)) + 
#     geom_point() + 
#     geom_line() +
#     ylab("Vas_rel_global")
plotly::plot_ly(plotly_data,  x= ~Conditie, y= ~value, color = ~ID, 
                type = 'scatter', mode = 'lines+markers', visible = 'legendonly',
                hoverinfo = 'text',
                text = ~paste('ID: ', ID, '</br> ', 
                      '</br> Vas value: ', value,
                      '</br> Condition: ', Conditie)) %>%
        layout(yaxis = list(range = c(0, 10), title = "Vas_rel_global"))

6.1 STAI-Y

## STAY
lm_stai <- lm(StaiS_post ~ StaiS_pre + Vas_rel_global, data = Date)
apa_lm_stai <- apa_print(lm_stai)
# apa_table(apa_lm_stai$table,
#   caption = "Table",
#   escape = FALSE,
#   format = "markdown")               # doesnt render the caption and it cant be removed
knitr::kable(apa_lm_stai$table)

predictor estimate ci statistic p.value
Intercept 15.94 [11.35, 20.54] 6.84 < .001
StaiS pre 0.74 [0.65, 0.82] 16.89 < .001
Vas rel global -1.18 [ - 1.64, -0.72] -5.07 < .001

# apa_lm_stai$full_result$modelfit$r2
par(mfrow = c(1, 2)); termplot(lm_stai, partial.resid = TRUE, se = TRUE)

Is there an interaction Condition x Vas rel global?

lm_stai_inter <- lm(StaiS_post ~ StaiS_pre + Conditie * Vas_rel_global, data = Date)
knitr::kable(apa_print(lm_stai_inter)$table)

predictor estimate ci statistic p.value
Intercept 22.85 [13.81, 31.90] 4.98 < .001
StaiS pre 0.74 [0.65, 0.83] 16.67 < .001
Conditiemama -2.93 [ - 14.32, 8.47] -0.51 .613
Conditiepersonalitate -10.46 [ - 21.63, 0.71] -1.85 .066
Conditieprieten -11.63 [ - 28.07, 4.82] -1.39 .165
Conditietata -9.26 [ - 19.31, 0.78] -1.82 .071
Vas rel global -2.11 [ - 3.19, -1.02] -3.84 < .001
Conditiemama × Vas rel global 0.55 [ - 0.93, 2.04] 0.74 .462
Conditiepersonalitate × Vas rel global 1.26 [ - 0.27, 2.80] 1.62 .106
Conditieprieten × Vas rel global 1.37 [ - 0.72, 3.46] 1.29 .198
Conditietata × Vas rel global 1.40 [0.06, 2.74] 2.06 .041

plot(visreg::visreg(lm_stai_inter, xvar = "Vas_rel_global", by = "Conditie", plot = FALSE),
            overlay = TRUE, partial = FALSE, rug = FALSE,
            xlab = "Vas_rel_global", ylab = "Predicted STAI",
            line = list(
            lty = c(1:4, 6),     # 5 is long dash and doesnt look nice   
            col = c("black", "grey90", "grey70", "grey50", "grey30")),
            band = FALSE)

Conditoning: Vas_rel_global >= 7

## STAI plot Cond
Staimelt_cond <- 
  Date %>%
  filter(Vas_rel_global >= 7) %>%
  select(ID, Conditie, StaiS_pre, StaiS_post) %>%
  gather("StaiS_pre", "StaiS_post", key = "Stai_cond", value = "value") %>% 
  mutate_at(vars(c(1, 2, 3)), funs(as.factor)) %>% 
  mutate(Stai_cond = factor(Stai_cond, levels = c("StaiS_pre","StaiS_post"))) # %>%    # change factor order for plot pre, post
ggplot(Staimelt_cond, aes(x = Stai_cond, y = value)) +
  geom_boxplot() +
  facet_wrap(~Conditie) +
  ggpubr::stat_compare_means(method = "t.test", paired = TRUE, comparisons = list(c("StaiS_pre","StaiS_post")))

STAI Post - Pre diff by Vas_rel_global

Date %>%
  mutate(StaiS_diff = StaiS_post - StaiS_pre) %>%
  ggplot(aes(x = Vas_rel_global, y = StaiS_diff, color = Conditie, group = Conditie)) + 
  geom_point() + 
  geom_hline(yintercept = 0, linetype = "dashed", color = "darkgrey") +
  geom_smooth(method = "lm", size = 1, se = FALSE) +
  xlim(0, 10)

6.2 VAS Stres

## STAY
lm_vasS <- lm(Vas_stres_post ~ Vas_stres_pre + Vas_rel_global, data = Date)
apa_lm_vasS <- apa_print(lm_vasS)
knitr::kable(apa_lm_vasS$table)

predictor estimate ci statistic p.value
Intercept 17.19 [9.27, 25.11] 4.28 < .001
Vas stres pre 0.81 [0.71, 0.91] 15.91 < .001
Vas rel global -1.89 [ - 2.90, -0.88] -3.69 < .001

par(mfrow=c(1,2)); termplot(lm_vasS, partial.resid = TRUE, se = TRUE)

Is there an interaction Condition x Vas rel global?

lm_vasS_inter <- lm(Vas_stres_post ~ Vas_stres_pre + Conditie * Vas_rel_global, data = Date)
knitr::kable(apa_print(lm_vasS_inter)$table)

predictor estimate ci statistic p.value
Intercept 13.35 [ - 5.68, 32.38] 1.38 .168
Vas stres pre 0.82 [0.72, 0.93] 15.65 < .001
Conditiemama 19.55 [ - 5.84, 44.94] 1.52 .130
Conditiepersonalitate 2.55 [ - 22.28, 27.37] 0.20 .840
Conditieprieten -10.10 [ - 46.26, 26.06] -0.55 .582
Conditietata 1.48 [ - 20.98, 23.93] 0.13 .897
Vas rel global -1.61 [ - 4.04, 0.82] -1.31 .192
Conditiemama × Vas rel global -2.09 [ - 5.39, 1.21] -1.25 .213
Conditiepersonalitate × Vas rel global -0.53 [ - 3.94, 2.89] -0.30 .761
Conditieprieten × Vas rel global 1.35 [ - 3.27, 5.96] 0.58 .565
Conditietata × Vas rel global 0.44 [ - 2.55, 3.44] 0.29 .771

plot(visreg::visreg(lm_vasS_inter, xvar = "Vas_rel_global", by = "Conditie", plot = FALSE),
            overlay = TRUE, partial = FALSE, rug = FALSE,
            xlab = "Vas_rel_global", ylab = "Predicted VAS Stress",
            line = list(
            lty = c(1:4, 6),     # 5 is long dash and doesnt look nice   
            col = c("black", "grey90", "grey70", "grey50", "grey30")),
            band = FALSE)

Conditoning: Vas_rel_global >= 7

## Vas Stres plot 
Vasstresmelt_cond <- 
  Date %>%
  filter(Vas_rel_global >= 7) %>%
  select(ID, Conditie, Vas_stres_pre, Vas_stres_post) %>%
  gather("Vas_stres_pre","Vas_stres_post", key = "Vas_stres_cond", value = "value") %>% 
  mutate_at(vars(c(1,2,3)), funs(as.factor)) %>% 
  mutate_at(vars(c(4)), funs(as.numeric)) %>% 
  mutate(Vas_stres_cond = factor(Vas_stres_cond, levels = c("Vas_stres_pre","Vas_stres_post"))) # change factor order for plot pre, post
ggplot(Vasstresmelt_cond, aes(x = Vas_stres_cond, y = value)) +
  geom_boxplot() +
  facet_wrap(~Conditie) +
  ggpubr::stat_compare_means(method = "t.test", paired = TRUE, comparisons = list(c("Vas_stres_pre","Vas_stres_post")))

VAS Stres Post - Pre diff by Vas_rel_global

Date %>%
  mutate(Vas_stres_diff = Vas_stres_post - Vas_stres_pre) %>%
  ggplot(aes(x = Vas_rel_global, y = Vas_stres_diff, color = Conditie, group = Conditie)) + 
  geom_point() +
  geom_smooth(method = "lm", size = 1, se = FALSE) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "darkgrey") +
  xlim(0, 10)

6.3 VAS Wellbeing

## STAY
lm_vasB <- lm(Vas_bine_post ~ Vas_bine_pre + Vas_rel_global, data = Date)
apa_lm_vasB <- apa_print(lm_vasB)
knitr::kable(apa_lm_vasB$table)

predictor estimate ci statistic p.value
Intercept -1.52 [ - 11.46, 8.42] -0.30 .763
Vas bine pre 0.69 [0.59, 0.79] 13.90 < .001
Vas rel global 3.60 [2.48, 4.72] 6.35 < .001

par(mfrow=c(1,2)); termplot(lm_vasB, partial.resid = TRUE, se = TRUE)

Is there an interaction Condition x Vas rel global?

lm_vasB_inter <- lm(Vas_bine_post ~ Vas_bine_pre + Conditie * Vas_rel_global, data = Date)
knitr::kable(apa_print(lm_vasB_inter)$table)

predictor estimate ci statistic p.value
Intercept -7.44 [ - 28.26, 13.38] -0.70 .482
Vas bine pre 0.70 [0.60, 0.80] 13.55 < .001
Conditiemama 0.39 [ - 27.59, 28.36] 0.03 .978
Conditiepersonalitate 11.91 [ - 15.51, 39.34] 0.86 .393
Conditieprieten 24.71 [ - 15.45, 64.87] 1.21 .226
Conditietata 0.55 [ - 24.13, 25.23] 0.04 .965
Vas rel global 4.25 [1.58, 6.92] 3.14 .002
Conditiemama × Vas rel global -0.24 [ - 3.88, 3.40] -0.13 .896
Conditiepersonalitate × Vas rel global -1.21 [ - 4.99, 2.56] -0.63 .527
Conditieprieten × Vas rel global -3.18 [ - 8.30, 1.94] -1.23 .222
Conditietata × Vas rel global -0.07 [ - 3.37, 3.24] -0.04 .968

plot(visreg::visreg(lm_vasB_inter, xvar = "Vas_rel_global", by = "Conditie", plot = FALSE),
            overlay = TRUE, partial = FALSE, rug = FALSE,
            xlab = "Vas_rel_global", ylab = "Predicted VAS Wellbeing",
            line = list(
            lty = c(1:4, 6),     # 5 is long dash and doesnt look nice   
            col = c("black", "grey90", "grey70", "grey50", "grey30")),
            band = FALSE)

Conditoning: Vas_rel_global >= 7

## Vas Stres plot 
Vasbinemelt_cond <- 
  Date %>%
  filter(Vas_rel_global >= 7) %>%
  select(ID, Conditie, Vas_bine_pre, Vas_bine_post) %>%
  gather("Vas_bine_pre","Vas_bine_post", key = "Vas_bine_cond", value = "value") %>% 
  mutate_at(vars(c(1,2,3)), funs(as.factor)) %>% 
  mutate_at(vars(c(4)), funs(as.numeric)) %>% 
  mutate(Vas_bine_cond = factor(Vas_bine_cond, levels = c("Vas_bine_pre","Vas_bine_post"))) # change factor order for plot pre, post
ggplot(Vasbinemelt_cond, aes(x = Vas_bine_cond, y = value)) +
  geom_boxplot() +
  facet_wrap(~Conditie) +
  ggpubr::stat_compare_means(method = "t.test", paired = TRUE, comparisons = list(c("Vas_bine_pre","Vas_bine_post")))

VAS Bine Post - Pre diff by Vas_rel_global

Date %>%
  mutate(Vas_bine_diff = Vas_bine_post - Vas_bine_pre) %>%
  ggplot(aes(x = Vas_rel_global, y = Vas_bine_diff, color = Conditie, group = Conditie)) + 
  geom_point() +
  geom_smooth(method = "lm", size = 1, se = FALSE) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "darkgrey") +
  xlim(0, 10)





7 Melt dataframe for future analyses

# Data from Long to Wide
meltDate <- 
  Date %>% 
    select(ID, Conditie, 
           Vas_stres_pre, Vas_stres_post,
           Vas_bine_pre, Vas_bine_post,
           StaiS_pre, StaiS_post) %>%
      gather(variable, value, Vas_stres_pre:StaiS_post) %>%
      unite(VarCond, variable, Conditie) %>% 
      spread(VarCond, value)
# Some rownames are typos (ID 1 and 26)
func_collapseduplicate <- function(x) {           # collapses duplicate rows, but if all are NA returns NA
  sum(x, na.rm=T ) * NA ^ (sum(!is.na(x)) == 0)
}
meltDate <-
  meltDate %>%
    mutate(ID = word(ID, 1)) %>%
    group_by(ID) %>% 
    summarise_all(func_collapseduplicate)
  
# Test if all results are the same -- all seems good
# t.test(meltDate$Vas_bine_pre_prieten, meltDate$Vas_bine_post_prieten, 
#                         mu = 0, 
#                         alt = "two.sided", 
#                         paired = TRUE, 
#                         conf.level = 0.95)
meltDate %>%
      DT::datatable(                                  # excel downloadable  DT table
      extensions = 'Buttons',
      options = list(pageLength = 20,
                     scrollX='500px', 
                     dom = 'Bfrtip', 
                     buttons = c('excel', "csv")))


8 Session Info

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

Matrix products: default

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

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

other attached packages:
 [1] bindrcpp_0.2.2     plotly_4.8.0       summarytools_0.8.8 DT_0.5             ggpubr_0.2         magrittr_1.5       broom_0.5.1       
 [8] papaja_0.1.0.9842  psych_1.8.10       forcats_0.3.0      stringr_1.3.1      dplyr_0.7.8        purrr_0.2.5        readr_1.3.0       
[15] tidyr_0.8.2        tibble_1.4.2       ggplot2_3.1.0      tidyverse_1.2.1    pacman_0.5.0      

loaded via a namespace (and not attached):
 [1] httr_1.4.0         jsonlite_1.6       viridisLite_0.3.0  gtools_3.8.1       modelr_0.1.2       visreg_2.5-0       shiny_1.2.0       
 [8] assertthat_0.2.0   highr_0.7          pander_0.6.3       cellranger_1.1.0   yaml_2.2.0         pillar_1.3.1       backports_1.1.3   
[15] lattice_0.20-38    glue_1.3.0         digest_0.6.18      RColorBrewer_1.1-2 ggsignif_0.4.0     promises_1.0.1     pryr_0.1.4        
[22] rvest_0.3.2        colorspace_1.3-2   cowplot_0.9.3      htmltools_0.3.6    httpuv_1.4.5       plyr_1.8.4         pkgconfig_2.0.2   
[29] haven_2.1.0        xtable_1.8-3       scales_1.0.0       later_0.7.5        generics_0.0.2     withr_2.1.2        lazyeval_0.2.1    
[36] cli_1.0.1          mnormt_1.5-5       crayon_1.3.4       readxl_1.1.0       mime_0.6           evaluate_0.12      nlme_3.1-137      
[43] xml2_1.2.0         foreign_0.8-71     rapportools_1.0    MBESS_4.4.3        tools_3.5.2        data.table_1.11.8  hms_0.4.2         
[50] matrixStats_0.54.0 munsell_0.5.0      compiler_3.5.2     rlang_0.3.1        grid_3.5.2         RCurl_1.95-4.11    rstudioapi_0.8    
[57] htmlwidgets_1.3    crosstalk_1.0.0    labeling_0.3       bitops_1.0-6       rmarkdown_1.11     gtable_0.2.0       codetools_0.2-15  
[64] R6_2.3.0           lubridate_1.7.4    knitr_1.21         bindr_0.1.1        stringi_1.2.4      parallel_3.5.2     Rcpp_1.0.0        
[71] tidyselect_0.2.5   xfun_0.4          
 

A work by Claudiu Papasteri

claudiu.papasteri@gmail.com

 

LS0tDQp0aXRsZTogIjxicj4gTzFBIFJlcG9ydCIgDQpzdWJ0aXRsZTogIkZpbmFsIFJlcG9ydCINCmF1dGhvcjogIjxicj4gQ2xhdWRpdSBQYXBhc3RlcmkiDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlbSAlWScpYCINCm91dHB1dDogDQogICAgaHRtbF9ub3RlYm9vazoNCiAgICAgICAgICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgICAgICAgICAgdG9jOiB0cnVlDQogICAgICAgICAgICB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgICAgICAgICAgdGhlbWU6IHNwYWNlbGFiDQogICAgICAgICAgICBoaWdobGlnaHQ6IHRhbmdvDQogICAgICAgICAgICBmb250LWZhbWlseTogQXJpYWwNCiAgICAgICAgICAgIGZpZ193aWR0aDogMTANCiAgICAgICAgICAgIGZpZ19oZWlnaHQ6IDkNCiAgICBwZGZfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgdG9jOiB0cnVlDQogICAgICAgICAgICB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgICAgICAgICAgIyBmb250c2l6ZTogMTFwdA0KICAgICAgICAgICAgIyBnZW9tZXRyeTogbWFyZ2luPTFpbg0KICAgICAgICAgICAgIyBmaWdfd2lkdGg6IDcNCiAgICAgICAgICAgICMgZmlnX2hlaWdodDogNg0KICAgICAgICAgICAgIyBmaWdfY2FwdGlvbjogdHJ1ZQ0KICAgICMgZ2l0aHViX2RvY3VtZW50OiANCiAgICAgICAgICAgICMgdG9jOiB0cnVlDQogICAgICAgICAgICAjIHRvY19kZXB0aDogMg0KICAgICAgICAgICAgIyBodG1sX3ByZXZpZXc6IGZhbHNlDQogICAgICAgICAgICAjIGZpZ193aWR0aDogNQ0KICAgICAgICAgICAgIyBmaWdfaGVpZ2h0OiA1DQogICAgICAgICAgICAjIGRldjoganBlZw0KLS0tDQoNCg0KPCEtLSBTZXR1cCAtLT4NCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0KIyBraW50ciBvcHRpb25zDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIGNvbW1lbnQgPSAiIyIsDQogIGNvbGxhcHNlID0gVFJVRSwNCiAgZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBUUlVFLCBtZXNzYWdlID0gVFJVRSwgY2FjaGUgPSBUUlVFICAgICAgICMgZWNobyA9IEZhbHNlIGZvciBnaXRodWJfZG9jdW1lbnQsIGJ1dCB3aWxsIGJlIGZvbGRlZCBpbiBodG1sX25vdGVib29rDQopDQoNCiMgR2VuZXJhbCBSIG9wdGlvbnMgYW5kIGluZm8NCnNldC5zZWVkKDExMSkgICAgICAgICAgICAgICAjIGluIGNhc2Ugd2UgdXNlIHJhbmRvbWl6ZWQgcHJvY2VkdXJlcyAgICAgICANCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAgICAgICAjIHBvc2l0aXZlIHZhbHVlcyBiaWFzIHRvd2FyZHMgZml4ZWQgYW5kIG5lZ2F0aXZlIHRvd2FyZHMgc2NpZW50aWZpYyBub3RhdGlvbg0KDQojIExvYWQgcGFja2FnZXMNCmlmICghcmVxdWlyZSgicGFjbWFuIikpIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQpwYWNrYWdlcyA8LSBjKA0KICAidGlkeXZlcnNlIiwgICAgICAjIGJlc3QgdGhpbmcgdGhhdCBoYXBwZW5kIHRvIG1lDQogICJwc3ljaCIsICAgICAgICAgICMgZ2VuZXJhbCBwdXJwb3NlIHRvb2xib3ggZm9yIHBlcnNvbmFsaXR5LCBwc3ljaG9tZXRyaWMgdGhlb3J5IGFuZCBleHBlcmltZW50YWwgcHN5Y2hvbG9neQ0KICAicGFwYWphIiwgICAgICAgICAjIGZvciBBUEEgc3R5bGUNCiAgImJyb29tIiwgICAgICAgICAgIyBmb3IgdGlkeSBtb2RlbGxpbmcNCiAgImdncGxvdDIiLCAgICAgICAgIyBiZXN0IHBsb3RzDQogICJnZ3B1YnIiLCAgICAgICAgICMgZ2dwbG90MiB0byBwdWJsaWNhdGlvbiBxdWFsaXR5DQogICJEVCIsICAgICAgICAgICAgICMgbmljZSBzZWFyY2hhYmxlIGFuZCBkb3dubG9hZGFibGUgdGFibGVzDQogICJzdW1tYXJ5dG9vbHMiLA0KICAicGxvdGx5Ig0KICAjICwgLi4uDQopDQppZiAoIXJlcXVpcmUoInBhY21hbiIpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KcGFjbWFuOjpwX2xvYWQoY2hhciA9IHBhY2thZ2VzKQ0KDQojIFRoZW1lcyBmb3IgZ2dwbG90MiBwbG90aW5nIChoZXJlIHVzZWQgQVBBIHN0eWxlKQ0KdGhlbWVfc2V0KHRoZW1lX2FwYSgpKQ0KYGBgDQoNCmBgYHtyIHdvcmtpbmdfZGlyZWN0b3J5LCBpbmNsdWRlID0gRkFMU0V9DQojIGlmIG5lZWRlZA0KIyB3ZCA9ICIuL28xYS1yZXBvcnQiDQojIHNldHdkKHdkKQ0KYGBgDQoNCg0KPCEtLSBSZXBvcnQgLS0+DQoNCg0KIyBMb2FkIGRhdGENCg0KYGBge3IgcmF3X2RhdGEsIHJlc3VsdHMgPSAnaGlkZScsIGNhY2hlLmV4dHJhID0gZmlsZS5pbmZvKCJkaWFtb25kcy5jc3YiKX0NCiMgUmVhZA0KZmlsZSA9ICJEQVRFIE8xQSBDb21wbGV0ZS54bHN4Ig0KDQpEYXRlIDwtIHJlYWR4bDo6cmVhZF94bHN4KGZpbGUsIHNoZWV0ID0gIkRhdGUgemlsbmljZSIsIHNraXAgPSA1LCBjb2xfbmFtZXMgPSBGQUxTRSkNCmBgYA0KDQoNCiMjIFByb2Nlc3NpbmcgZGF0YQ0KDQpgYGB7ciBwcm9jZXNzZWRfZGF0YSwgY2FjaGUgPSBUUlVFLCBkZXBlbmRzb24gPSAicmF3X2RhdGEifQ0KIyBDbGVhbg0KdmFybmFtZXMgPC0gYygiTnJfY3J0IiwgIklEIiwgIk51bWVfUHJlbnVtZSIsICJaaSIsICJWYXNfc3RyZXNfcHJlIiwgIlZhc19iaW5lX3ByZSIsDQogICAgICAgICAgICAgc3ByaW50ZigiU3RhaXNfcHJlXyUwMWQiLCBzZXEoMSwyMCkpLA0KICAgICAgICAgICAgICJTT1AiLA0KICAgICAgICAgICAgICJJT1NfbWFtYSIsICJJT1NfdGF0YSIsICJJT1NfaXViaXQiLCAiSU9TX3ByaWV0ZW4iLCAiSU9TX3BlcnNvbmFsaXRhdGUiLA0KICAgICAgICAgICAgICJWYXNfcmVsX2dsb2JhbCIsICJWYXNfcmVsX2Fyb3VzYWwiLA0KICAgICAgICAgICAgICJDUlFfMSIsICJDUlFfMiIsICJDUlFfMyIsICJDUlFfNCIsICJDUlFfNSIsICJDUlFfNiIsDQogICAgICAgICAgICAgIlZhc19zdHJlc19wb3N0IiwgIlZhc19iaW5lX3Bvc3QiLA0KICAgICAgICAgICAgIHNwcmludGYoIlN0YWlzX3Bvc3RfJTAxZCIsIHNlcSgxLDIwKSkNCikNCm5hbWVzKERhdGUpIDwtIHZhcm5hbWVzICAgIyBudW1lIG5vaQ0KRGF0ZSA8LSBEYXRlWy1jKDE6MiksXSAgICAjIHNjb2F0ZW0gcmFuZHVyaWxlIGN1IG51bWVsZSBwcmVjZWRlbnRlDQpEYXRlJE5yX2NydCA8LSAxOm5yb3coRGF0ZSkgICAjIGVyYSBnb2wsIGFzYSBjYSBudW1lcm90YW0gcmFuZHVyaWxlIGNhIHNhIGF2ZW0gYWNlc3RhIHZhcmlhYmlsYSANCg0KIyBQcm9jZXNzIE5Bcw0KRGF0ZSA8LSBEYXRlICU+JSANCiAgICBuYV9pZigibmEiKSAlPiUgIA0KICAgIG11dGF0ZShOQV9wZXJfcm93ID0gcm93U3Vtcyhpcy5uYSguKSkpICAgICAjIGNvdW50IE5BcyBieSByb3cNCg0KRGF0ZSA8LSBEYXRlICU+JSANCiAgICBmaWx0ZXIoTkFfcGVyX3JvdyA8IDIwKSAgICAgICAgICMgYXJiaXRyYXJ5IGN1dG9mZiBmb3IgTkFzIG9uIGNvbHVtbnMgLi4uIGl0IGlzIG5vcm1hbCB0byBoYXZlIDQgTkFzIGZvciBhbGwgY29sdW1ucw0KDQojIENvbnZlcnQgdG8gbnVtZXJpYw0KdmFyc251bWVyaWMgPC0gYygiWmkiLCAiVmFzX3N0cmVzX3ByZSIsICJWYXNfYmluZV9wcmUiLA0KICAgICAgICAgICAgICAgICBzcHJpbnRmKCJTdGFpc19wcmVfJTAxZCIsIHNlcSgxLDIwKSksDQogICAgICAgICAgICAgICAgICJJT1NfbWFtYSIsICJJT1NfdGF0YSIsICJJT1NfaXViaXQiLCAiSU9TX3ByaWV0ZW4iLCAiSU9TX3BlcnNvbmFsaXRhdGUiLA0KICAgICAgICAgICAgICAgICAiVmFzX3JlbF9nbG9iYWwiLCAiVmFzX3JlbF9hcm91c2FsIiwNCiAgICAgICAgICAgICAgICAgIkNSUV8xIiwgIkNSUV8yIiwgIkNSUV8zIiwgIkNSUV80IiwgIkNSUV81IiwgIkNSUV82IiwNCiAgICAgICAgICAgICAgICAgIlZhc19zdHJlc19wb3N0IiwgIlZhc19iaW5lX3Bvc3QiLA0KICAgICAgICAgICAgICAgICAgc3ByaW50ZigiU3RhaXNfcG9zdF8lMDFkIiwgc2VxKDEsMjApKSkNCg0KRGF0ZSA8LSBEYXRlICU+JSANCiAgbXV0YXRlX2F0KHZhcnNudW1lcmljLCBhcy5udW1lcmljKQ0KDQojIHdoaWNoKERhdGUkU3RhaXNfcG9zdF8xMSA9PSA0NykgICAgIyB0eXBvIFN0YWlzX3Bvc3RfMTEgdmFsdWUgb2YgNDcgLT4gY29ycmVjdGVkIHRvIDQNCkRhdGUkU3RhaXNfcG9zdF8xMVtEYXRlJFN0YWlzX3Bvc3RfMTEgPT0gNDddIDwtIDQNCmBgYA0KDQo8IS0tIEluc3BlY3QgRGF0YSAtIHN3aXRjaGVkIG9mZiAtLT4NCmBgYHtyIGluc3BlY3RkYXRhLCBlY2hvPUZBTFNFLCByZXN1bHRzPSJoaWRlIn0gDQojIHByaW50KHN1bW1hcnl0b29sczo6ZGZTdW1tYXJ5KERhdGUsIHN0eWxlID0gJ2dyaWQnLCBwbGFpbi5hc2NpaSA9IEZBTFNFLCBncmFwaC5tYWduaWYgPSAwLjg1KSwgICAgIyBzdXBwcmVzcyBvdXRwdXQNCiMgICAgICAgbWV0aG9kID0gJ3JlbmRlcicsIGhlYWRpbmdzID0gRkFMU0UpDQojIHN0cihEYXRlLCBsaXN0Lmxlbj1uY29sKERhdGUpKSAgIyBkYXRhIHR5cGVzIGFyZSBmaW5lDQpgYGANCg0KDQojIyBDb21wdXRlIG5ldyB2YXJpYWJsZXMNCg0KYGBge3IgZGVyaXZlZF9kYXRhLCBjYWNoZSA9IFRSVUUsIGRlcGVuZHNvbiA9ICJwcm9jZXNzZWRfZGF0YSJ9DQojIENvbXB1dGUgbmV3IHZhcmlhYmxlcyANCkNvbmRpdGllIDwtIERhdGUgJT4lIA0KICAgIHNlbGVjdChOcl9jcnQsIElELCBJT1NfbWFtYSwgSU9TX3RhdGEsIElPU19pdWJpdCwgSU9TX3ByaWV0ZW4sIElPU19wZXJzb25hbGl0YXRlKSAlPiUgDQogICAgZ2F0aGVyKHR5cGUsIHZhbHVlLCAtYyhOcl9jcnQsIElEKSkgJT4lIA0KICAgIG11dGF0ZShDb25kaXRpZSA9IGlmZWxzZSghaXMubmEodmFsdWUpLCB0eXBlLCBOQSkgKSAlPiUNCiAgICBtdXRhdGUoQ29uZGl0aWUgPSBzdHJfcmVwbGFjZShDb25kaXRpZSwgIklPU18iLCAiIikpICU+JQ0KICAgIGFycmFuZ2UoTnJfY3J0KSAlPiUNCiAgICBzZWxlY3QoQ29uZGl0aWUpICU+JSBuYS5vbWl0KCkgDQpEYXRlJENvbmRpdGllIDwtIENvbmRpdGllJENvbmRpdGllICAgICAjIHRpZHl2ZXJzZSByZXR1cm5zIHRpYmJsZSwgbXVzdCBkbyB0aGlzDQpJT1MgPC0gRGF0ZSAlPiUgDQogIG11dGF0ZShJT1MgPSBjb2FsZXNjZShJT1NfbWFtYSwgSU9TX3RhdGEsIElPU19pdWJpdCwgSU9TX3ByaWV0ZW4sIElPU19wZXJzb25hbGl0YXRlKSkgJT4lDQogIHNlbGVjdChJT1MpDQpEYXRlJElPUyA8LSBJT1MkSU9TICAgIyB0aWR5dmVyc2UgcmV0dXJucyB0aWJibGUsIG11c3QgZG8gdGhpcw0Kcm0oQ29uZGl0aWUsIElPUykgICAgIyByZW1vdmUgMiB0aWJibGVzDQoNCiMgU2NvcmluZyBTdGFpICAgKGNvbnZlcnQgbnVtZXJpYyAtIFZBUykNCml0ZW1pVkFTIDwtIGMoNSwgNiwgNDEsIDQyKQ0KDQppdGVtaVN0YWlTX3ByZSA8LSA3OjI2DQppdGVtaVN0YWlTX3Bvc3QgPC0gNDM6NjINClJldmVyc2VkSXRlbXMgPC0gYygxLDIsNSw4LDEwLDExLDE1LDE2LDE5LDIwKQ0KDQpEYXRlIDwtIERhdGUgJT4lICAgICAgICAgICAgICAgICANCiAgcmVwbGFjZShEYXRlID09ICJuYSIsIE5BKSAlPiUgICAgICAgICMgc2NpbWJhbSBjb2RhcmVhIGN1IG5hIGEgRG9pbmVpDQogIG11dGF0ZV9hdCh2YXJzKGl0ZW1pU3RhaVNfcHJlKSwgZnVucyhhcy5udW1lcmljKSkgJT4lICAgICAgICAjIGZhY2VtIGNvbG9hbmVsZSBudW1lcmljZSBwdCBTVEFJDQogIG11dGF0ZV9hdCh2YXJzKGl0ZW1pU3RhaVNfcG9zdCksIGZ1bnMoYXMubnVtZXJpYykpICU+JSANCiAgbXV0YXRlX2F0KHZhcnMoaXRlbWlWQVMpLCBmdW5zKGFzLm51bWVyaWMpKQ0KDQpEYXRlWyAsaXRlbWlTdGFpU19wcmVbUmV2ZXJzZWRJdGVtc11dID0gNSAtIERhdGVbICxpdGVtaVN0YWlTX3ByZVtSZXZlcnNlZEl0ZW1zXV0NCkRhdGVbICxpdGVtaVN0YWlTX3Bvc3RbUmV2ZXJzZWRJdGVtc11dID0gNSAtIERhdGVbICxpdGVtaVN0YWlTX3Bvc3RbUmV2ZXJzZWRJdGVtc11dDQoNCkRhdGUkU3RhaVNfcHJlID0gcm93U3VtcyhEYXRlWyAsaXRlbWlTdGFpU19wcmVdLCBuYS5ybT1UICkgKiBOQSBeIChyb3dTdW1zKCFpcy5uYShEYXRlWyAsaXRlbWlTdGFpU19wcmVdKSkgPT0gMCkNCkRhdGUkU3RhaVNfcG9zdCA9IHJvd1N1bXMoRGF0ZVsgLGl0ZW1pU3RhaVNfcG9zdF0sIG5hLnJtPVQgKSAqIE5BIF4gKHJvd1N1bXMoIWlzLm5hKERhdGVbICxpdGVtaVN0YWlTX3Bvc3RdKSkgPT0gMCkNCmBgYA0KDQoNCiMjIFRhYmxlIG9mIGRlcml2ZWQgdmFyaWFibGVzDQoNCmBgYHtyIHRhYmxlX2Rlcml2ZWRfZGF0YX0NCnZhcm5vdHRhYmxlIDwtIGMoIk51bWVfUHJlbnVtZSIsICJOQV9wZXJfcm93IiwgDQogICAgICAgICAgICAgICAgIHNwcmludGYoIlN0YWlzX3ByZV8lMDFkIiwgc2VxKDEsMjApKSwgDQogICAgICAgICAgICAgICAgIHNwcmludGYoIlN0YWlzX3Bvc3RfJTAxZCIsIHNlcSgxLDIwKSkpDQoNCkRhdGUgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogIHNlbGVjdCgtdmFybm90dGFibGUpICU+JQ0KICAgIERUOjpkYXRhdGFibGUoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgZXhjZWwgZG93bmxvYWRhYmxlICBEVCB0YWJsZQ0KICAgICAgZXh0ZW5zaW9ucyA9ICdCdXR0b25zJywNCiAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAyMCwNCiAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFg9JzUwMHB4JywgDQogICAgICAgICAgICAgICAgICAgICBkb20gPSAnQmZydGlwJywgDQogICAgICAgICAgICAgICAgICAgICBidXR0b25zID0gYygnZXhjZWwnLCAiY3N2IikpKQ0KYGBgDQoNCg0KPGJyPg0KPGJyPg0KDQoNCiMgQ29uZGl0aW9ucw0KDQpgYGB7ciBjb25kX2NvdW50fQ0KIyMgTnVtYmVyIG9mIHN1YmplY3RzIHBlciBDb25kaXRpb24NCkRhdGUgJT4lIA0KICBjb3VudChDb25kaXRpZSkgJT4lDQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gIk51bWJlciBvZiBzdWJqZWN0cyBwZXIgQ29uZGl0aW9uIikNCmBgYA0KDQpgYGB7ciBjb25kX3Bsb3QsIGZpZy53aWR0aCA9IDEwLCBmaWcuYXNwID0gMC44fQ0KIyMgTWVhbnMgZm9yIGFsbCB2YXJpYWJsZXMgYnkgQ29uZGl0aW9uDQojIERhdGUgJT4lIA0KIyAgIHNlbGVjdChJRCwgDQojICAgICAgICAgIFZhc19yZWxfZ2xvYmFsLCBWYXNfcmVsX2Fyb3VzYWwsIA0KIyAgICAgICAgICBDUlFfMSwgQ1JRXzIsIENSUV8zLCBDUlFfNCwgQ1JRXzUsIENSUV82LCANCiMgICAgICAgICAgQ29uZGl0aWUsIElPUykgJT4lDQojICAgZ3JvdXBfYnkoQ29uZGl0aWUpICU+JQ0KIyAgIHN1bW1hcmlzZV9pZigucHJlZGljYXRlID0gZnVuY3Rpb24oeCkgaXMubnVtZXJpYyh4KSwNCiMgICAgICAgICAgICAgIC5mdW5zID0gZnVucyhtZWFuPSJtZWFuIikpDQoNCiMjIFBsb3QgQ1JRIGl0ZW1zDQpteV9jb21wYXJpc29ucyA8LSANCiAgZ3Rvb2xzOjpjb21iaW5hdGlvbnMobiA9IGxlbmd0aCh1bmlxdWUoRGF0ZSRDb25kaXRpZSkpLCByID0gMiwgdiA9IERhdGUkQ29uZGl0aWUsIHJlcGVhdHMuYWxsb3dlZCA9IEZBTFNFKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JSANCiAgbXV0YXRlX2lmKGlzLmZhY3RvciwgYXMuY2hhcmFjdGVyKSAlPiUNCiAgcHVycnI6OnBtYXAobGlzdCkgJT4lIA0KICBsYXBwbHkodW5saXN0KQ0KICANCkRhdGUgJT4lIA0KICBzZWxlY3QoSUQsIENvbmRpdGllLCANCiAgICAgICAgIENSUV8xLCBDUlFfMiwgQ1JRXzMsIENSUV80LCBDUlFfNSwgQ1JRXzYpICU+JQ0KICBnYXRoZXIodmFyaWFibGUsIHZhbHVlLCBDUlFfMTpDUlFfNikgJT4lDQogIG11dGF0ZShDb25kaXRpZSA9IGZhY3RvcihDb25kaXRpZSwgbGV2ZWxzID0gc29ydCh1bmlxdWUoQ29uZGl0aWUpKSkpICU+JSAgICMgcmVsZXZlbCBqdXN0IHRvIG1hdGNoIGNvbWJpbmF0aW9uIHBhdHRlcm4gZm9yIGNvbXBhcmlzb24NCiAgICBnZ2JveHBsb3QoeCA9ICJDb25kaXRpZSIsIHkgPSAidmFsdWUiLCBmYWNldC5ieSA9ICJ2YXJpYWJsZSIgKSArIA0KICAgIHN0YXRfY29tcGFyZV9tZWFucyhjb21wYXJpc29ucyA9IG15X2NvbXBhcmlzb25zLCAgICAgICAgICAgICMgY2FuJ3QgZG8gcGFpcmVkIHQgdGVzdCBiZWNhdXNlIG5vdCBhbGwgYXJndW1lbnRzIGhhdmUgdGhlIHNhbWUgbGVuZ3RoICANCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAicC5zaWduaWYiLCBwYWlyZWQgPSBGQUxTRSwgbWV0aG9kID0gInQudGVzdCIsICBuYS5ybSA9IFRSVUUpICsNCiAgICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGFiYnJldmlhdGUpDQoNCiMjIFBsb3QgVkFTIFJlbCBhbmQgSU9TDQpmdW5jX2JveGNvbXBfY29uZCA8LSBmdW5jdGlvbih2YXIpew0KICAgIERhdGUgJT4lIA0KICAgICAgc2VsZWN0KENvbmRpdGllLCB2YXIpICU+JQ0KICAgICAgbXV0YXRlKENvbmRpdGllID0gZmFjdG9yKENvbmRpdGllLCBsZXZlbHMgPSBzb3J0KHVuaXF1ZShDb25kaXRpZSkpKSkgJT4lICAgIyByZWxldmVsIGp1c3QgdG8gbWF0Y2ggY29tYmluYXRpb24gcGF0dGVybiBmb3IgY29tcGFyaXNvbg0KICAgICAgICBnZ2JveHBsb3QoeCA9ICJDb25kaXRpZSIsIHkgPSB2YXIsIHRpdGxlID0gdmFyKSArDQogICAgICAgIHN0YXRfY29tcGFyZV9tZWFucyhjb21wYXJpc29ucyA9IG15X2NvbXBhcmlzb25zLCAgICAgICAgICAgICMgY2FuJ3QgZG8gcGFpcmVkIHQgdGVzdCBiZWNhdXNlIG5vdCBhbGwgYXJndW1lbnRzIGhhdmUgdGhlIHNhbWUgbGVuZ3RoICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gInAuc2lnbmlmIiwgcGFpcmVkID0gRkFMU0UsIG1ldGhvZCA9ICJ0LnRlc3QiLCAgbmEucm0gPSBUUlVFKQ0KfQ0KDQpwbG90X3Zhc2dsb2IgPC0gZnVuY19ib3hjb21wX2NvbmQoIlZhc19yZWxfZ2xvYmFsIikNCnBsb3RfdmFzYXJvdSA8LSBmdW5jX2JveGNvbXBfY29uZCgiVmFzX3JlbF9hcm91c2FsIikNCnBsb3RfaW9zIDwtIGZ1bmNfYm94Y29tcF9jb25kKCJJT1MiKQ0KZ2dhcnJhbmdlKHBsb3RfdmFzZ2xvYiwgDQogICAgICAgICAgcGxvdF9pb3MsIA0KICAgICAgICAgIHBsb3RfdmFzYXJvdSwgDQogICAgICAgICAgbmNvbCA9IDIsIG5yb3cgPSAyKQ0KYGBgDQoNCg0KPGJyPg0KPGJyPg0KDQojIFNUQUktWQ0KDQojIyBQbG90cyB3aXRoIHAgdmFsdWVzDQpgYGB7ciBzdGFpX3Bsb3QsIGZpZy53aWR0aCA9IDEwLCBmaWcuYXNwID0gMC44fQ0KIyMgU1RBSSBwbG90IA0KU3RhaW1lbHQgPC0gRGF0ZVssIGMoIklEIiwgIkNvbmRpdGllIiwgIlN0YWlTX3ByZSIsIlN0YWlTX3Bvc3QiKV0gJT4lIA0KICBnYXRoZXIoIlN0YWlTX3ByZSIsICJTdGFpU19wb3N0Iiwga2V5ID0gIlN0YWlfY29uZCIsIHZhbHVlID0gInZhbHVlIikgJT4lIA0KICBtdXRhdGVfYXQodmFycyhjKDEsIDIsIDMpKSwgZnVucyhhcy5mYWN0b3IpKSAlPiUgDQogIG11dGF0ZShTdGFpX2NvbmQgPSBmYWN0b3IoU3RhaV9jb25kLCBsZXZlbHMgPSBjKCJTdGFpU19wcmUiLCJTdGFpU19wb3N0IikpKSAjICU+JSAgICAjIGNoYW5nZSBmYWN0b3Igb3JkZXIgZm9yIHBsb3QgcHJlLCBwb3N0DQoNCmdncGxvdChTdGFpbWVsdCwgYWVzKHggPSBTdGFpX2NvbmQsIHkgPSB2YWx1ZSkpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBmYWNldF93cmFwKH5Db25kaXRpZSkgKw0KICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAidC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgY29tcGFyaXNvbnMgPSBsaXN0KGMoIlN0YWlTX3ByZSIsIlN0YWlTX3Bvc3QiKSkpDQpgYGANCg0KIyMgdCB0ZXN0cw0KYGBge3Igc3RhaV90dGVzdH0NCiMjIFNUQUkgdGFibGVzDQpEYXRlICU+JSANCiAgZ3JvdXBfYnkoQ29uZGl0aWUpICU+JSANCiAgZG8oYnJvb206OnRpZHkodC50ZXN0KC4kU3RhaVNfcHJlLCANCiAgICAgICAgICAgICAgICAgICAgICAgIC4kU3RhaVNfcG9zdCwgDQogICAgICAgICAgICAgICAgICAgICAgICBtdSA9IDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgYWx0ID0gInR3by5zaWRlZCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgcGFpcmVkID0gVFJVRSwgDQogICAgICAgICAgICAgICAgICAgICAgICBjb25mLmxldmVsID0gMC45NSkpKSAlPiUNCiAga25pdHI6OmthYmxlKGRpZ2l0cyA9IDIpDQpgYGANCg0KDQo8YnI+DQoNCiMgVkFTIFN0cmVzDQoNCiMjIFBsb3RzIHdpdGggcCB2YWx1ZXMNCmBgYHtyIHZhc1NfcGxvdCwgZmlnLndpZHRoID0gMTAsIGZpZy5hc3AgPSAwLjh9DQojIyBWYXMgU3RyZXMgcGxvdCANClZhc3N0cmVzbWVsdCA8LSBEYXRlWywgYygiSUQiLCAiQ29uZGl0aWUiLCAiVmFzX3N0cmVzX3ByZSIsIlZhc19zdHJlc19wb3N0IildICU+JSANCiAgZ2F0aGVyKCJWYXNfc3RyZXNfcHJlIiwiVmFzX3N0cmVzX3Bvc3QiLCBrZXkgPSAiVmFzX3N0cmVzX2NvbmQiLCB2YWx1ZSA9ICJ2YWx1ZSIpICU+JSANCiAgbXV0YXRlX2F0KHZhcnMoYygxLDIsMykpLCBmdW5zKGFzLmZhY3RvcikpICU+JSANCiAgbXV0YXRlX2F0KHZhcnMoYyg0KSksIGZ1bnMoYXMubnVtZXJpYykpICU+JSANCiAgbXV0YXRlKFZhc19zdHJlc19jb25kID0gZmFjdG9yKFZhc19zdHJlc19jb25kLCBsZXZlbHMgPSBjKCJWYXNfc3RyZXNfcHJlIiwiVmFzX3N0cmVzX3Bvc3QiKSkpICMgY2hhbmdlIGZhY3RvciBvcmRlciBmb3IgcGxvdCBwcmUsIHBvc3QNCg0KZ2dwbG90KFZhc3N0cmVzbWVsdCwgYWVzKHggPSBWYXNfc3RyZXNfY29uZCwgeSA9IHZhbHVlKSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIGZhY2V0X3dyYXAofkNvbmRpdGllKSArDQogIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ0LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBjb21wYXJpc29ucyA9IGxpc3QoYygiVmFzX3N0cmVzX3ByZSIsIlZhc19zdHJlc19wb3N0IikpKQ0KYGBgDQoNCiMjIHQgdGVzdHMNCmBgYHtyIHZhc1NfdHRlc3R9DQojIyBWYXMgU3RyZXMgdGFibGVzDQpEYXRlICU+JSANCiAgZ3JvdXBfYnkoQ29uZGl0aWUpICU+JSANCiAgZG8oYnJvb206OnRpZHkodC50ZXN0KC4kVmFzX3N0cmVzX3ByZSwgDQogICAgICAgICAgICAgICAgICAgICAgICAuJFZhc19zdHJlc19wb3N0LCANCiAgICAgICAgICAgICAgICAgICAgICAgIG11ID0gMCwgDQogICAgICAgICAgICAgICAgICAgICAgICBhbHQgPSAidHdvLnNpZGVkIiwgDQogICAgICAgICAgICAgICAgICAgICAgICBwYWlyZWQgPSBUUlVFLCANCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmYubGV2ZWwgPSAwLjk1KSkpICU+JQ0KICBrbml0cjo6a2FibGUoZGlnaXRzID0gMikNCmBgYA0KDQoNCjxicj4NCg0KIyBWQVMgV2VsbGJlaW5nDQoNCiMjIFBsb3RzIHdpdGggcCB2YWx1ZXMNCmBgYHtyIHZhc0JfcGxvdCwgZmlnLndpZHRoID0gMTAsIGZpZy5hc3AgPSAwLjh9DQojIyBWYXMgU3RyZXMgcGxvdCANClZhc2JpbmVtZWx0IDwtIERhdGVbLCBjKCJJRCIsICJDb25kaXRpZSIsICJWYXNfYmluZV9wcmUiLCJWYXNfYmluZV9wb3N0IildICU+JSANCiAgZ2F0aGVyKCJWYXNfYmluZV9wcmUiLCJWYXNfYmluZV9wb3N0Iiwga2V5ID0gIlZhc19zdHJlc19jb25kIiwgdmFsdWUgPSAidmFsdWUiKSAlPiUgDQogIG11dGF0ZV9hdCh2YXJzKGMoMSwyLDMpKSwgZnVucyhhcy5mYWN0b3IpKSAlPiUgDQogIG11dGF0ZV9hdCh2YXJzKGMoNCkpLCBmdW5zKGFzLm51bWVyaWMpKSAlPiUgDQogIG11dGF0ZShWYXNfc3RyZXNfY29uZCA9IGZhY3RvcihWYXNfc3RyZXNfY29uZCwgbGV2ZWxzID0gYygiVmFzX2JpbmVfcHJlIiwiVmFzX2JpbmVfcG9zdCIpKSkgIyBjaGFuZ2UgZmFjdG9yIG9yZGVyIGZvciBwbG90IHByZSwgcG9zdA0KDQpnZ3Bsb3QoVmFzYmluZW1lbHQsIGFlcyh4ID0gVmFzX3N0cmVzX2NvbmQsIHkgPSB2YWx1ZSkpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBmYWNldF93cmFwKH5Db25kaXRpZSkgKw0KICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAidC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgY29tcGFyaXNvbnMgPSBsaXN0KGMoIlZhc19iaW5lX3ByZSIsIlZhc19iaW5lX3Bvc3QiKSkpDQpgYGANCg0KIyMgdCB0ZXN0cw0KYGBge3IgdmFzQl90dGVzdH0NCiMjIFZhcyBTdHJlcyB0YWJsZXMNCkRhdGUgJT4lIA0KICBncm91cF9ieShDb25kaXRpZSkgJT4lIA0KICBkbyhicm9vbTo6dGlkeSh0LnRlc3QoLiRWYXNfYmluZV9wcmUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgLiRWYXNfYmluZV9wb3N0LCANCiAgICAgICAgICAgICAgICAgICAgICAgIG11ID0gMCwgDQogICAgICAgICAgICAgICAgICAgICAgICBhbHQgPSAidHdvLnNpZGVkIiwgDQogICAgICAgICAgICAgICAgICAgICAgICBwYWlyZWQgPSBUUlVFLCANCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmYubGV2ZWwgPSAwLjk1KSkpICU+JQ0KICBrbml0cjo6a2FibGUoZGlnaXRzID0gMikNCmBgYA0KDQo8YnI+DQo8YnI+DQoNCiMgQ29uZGl0aW9uaW5nIG9uIFZBUyBnbG9iYWwNCg0KQ2xpY2sgb24gSURzIHRvIHNob3cgaW4gcGxvdA0KYGBge3IgdmFzZ2xvYl9wbG90LCBmaWcud2lkdGggPSAxMCwgZmlnLmFzcCA9IDAuOCwgd2FybmluZyA9IEZBTFNFfQ0KIyB3aWxsIHRocm93IHdhcm5pbmcgYmVjYXVzZSBjb2xvciBwYWxldHRlIGlzIHRvbyBzbWFsbA0KDQpwbG90bHlfZGF0YSA8LSANCiAgRGF0ZSAlPiUNCiAgICBtdXRhdGUoSUQgPSB3b3JkKElELCAxKSkgJT4lDQogICAgc2VsZWN0KElELCBDb25kaXRpZSwgVmFzX3JlbF9nbG9iYWwpICU+JQ0KICAgIGdhdGhlcih2YXJpYWJsZSwgdmFsdWUsIFZhc19yZWxfZ2xvYmFsKSAlPiUNCiAgICBhcnJhbmdlKENvbmRpdGllKSANCg0KIyAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBqdXN0IGEgdGVzdA0KIyAgICAgZ2dwbG90KGFlcyh4ID0gQ29uZGl0aWUsIHkgPSB2YWx1ZSwgZ3JvdXAgPSBJRCwgY29sb3VyID0gSUQpKSArIA0KIyAgICAgZ2VvbV9wb2ludCgpICsgDQojICAgICBnZW9tX2xpbmUoKSArDQojICAgICB5bGFiKCJWYXNfcmVsX2dsb2JhbCIpDQoNCnBsb3RseTo6cGxvdF9seShwbG90bHlfZGF0YSwgIHg9IH5Db25kaXRpZSwgeT0gfnZhbHVlLCBjb2xvciA9IH5JRCwgDQogICAgICAgICAgICAgICAgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcyttYXJrZXJzJywgdmlzaWJsZSA9ICdsZWdlbmRvbmx5JywNCiAgICAgICAgICAgICAgICBob3ZlcmluZm8gPSAndGV4dCcsDQogICAgICAgICAgICAgICAgdGV4dCA9IH5wYXN0ZSgnSUQ6ICcsIElELCAnPC9icj4gJywgDQogICAgICAgICAgICAgICAgICAgICAgJzwvYnI+IFZhcyB2YWx1ZTogJywgdmFsdWUsDQogICAgICAgICAgICAgICAgICAgICAgJzwvYnI+IENvbmRpdGlvbjogJywgQ29uZGl0aWUpKSAlPiUNCiAgICAgICAgbGF5b3V0KHlheGlzID0gbGlzdChyYW5nZSA9IGMoMCwgMTApLCB0aXRsZSA9ICJWYXNfcmVsX2dsb2JhbCIpKQ0KDQpgYGANCg0KIyMgU1RBSS1ZDQpgYGB7ciByZWdfc3RhaV92YXNnbG9iYWx9DQojIyBTVEFZDQpsbV9zdGFpIDwtIGxtKFN0YWlTX3Bvc3QgfiBTdGFpU19wcmUgKyBWYXNfcmVsX2dsb2JhbCwgZGF0YSA9IERhdGUpDQphcGFfbG1fc3RhaSA8LSBhcGFfcHJpbnQobG1fc3RhaSkNCiMgYXBhX3RhYmxlKGFwYV9sbV9zdGFpJHRhYmxlLA0KIyAgIGNhcHRpb24gPSAiVGFibGUiLA0KIyAgIGVzY2FwZSA9IEZBTFNFLA0KIyAgIGZvcm1hdCA9ICJtYXJrZG93biIpICAgICAgICAgICAgICAgIyBkb2VzbnQgcmVuZGVyIHRoZSBjYXB0aW9uIGFuZCBpdCBjYW50IGJlIHJlbW92ZWQNCmtuaXRyOjprYWJsZShhcGFfbG1fc3RhaSR0YWJsZSkNCg0KIyBhcGFfbG1fc3RhaSRmdWxsX3Jlc3VsdCRtb2RlbGZpdCRyMg0KDQpwYXIobWZyb3cgPSBjKDEsIDIpKTsgdGVybXBsb3QobG1fc3RhaSwgcGFydGlhbC5yZXNpZCA9IFRSVUUsIHNlID0gVFJVRSkNCg0KYGBgDQoNCjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTUwJTsiPipJcyB0aGVyZSBhbiBpbnRlcmFjdGlvbiBDb25kaXRpb24geCBWYXMgcmVsIGdsb2JhbD8qPC9zcGFuPg0KYGBge3IgaW50ZXJhY19zdGFpX3Zhc2dsb2JhbH0NCmxtX3N0YWlfaW50ZXIgPC0gbG0oU3RhaVNfcG9zdCB+IFN0YWlTX3ByZSArIENvbmRpdGllICogVmFzX3JlbF9nbG9iYWwsIGRhdGEgPSBEYXRlKQ0KDQprbml0cjo6a2FibGUoYXBhX3ByaW50KGxtX3N0YWlfaW50ZXIpJHRhYmxlKQ0KDQpwbG90KHZpc3JlZzo6dmlzcmVnKGxtX3N0YWlfaW50ZXIsIHh2YXIgPSAiVmFzX3JlbF9nbG9iYWwiLCBieSA9ICJDb25kaXRpZSIsIHBsb3QgPSBGQUxTRSksDQogICAgICAgICAgICBvdmVybGF5ID0gVFJVRSwgcGFydGlhbCA9IEZBTFNFLCBydWcgPSBGQUxTRSwNCiAgICAgICAgICAgIHhsYWIgPSAiVmFzX3JlbF9nbG9iYWwiLCB5bGFiID0gIlByZWRpY3RlZCBTVEFJIiwNCiAgICAgICAgICAgIGxpbmUgPSBsaXN0KA0KICAgICAgICAgICAgbHR5ID0gYygxOjQsIDYpLCAgICAgIyA1IGlzIGxvbmcgZGFzaCBhbmQgZG9lc250IGxvb2sgbmljZSAgIA0KICAgICAgICAgICAgY29sID0gYygiYmxhY2siLCAiZ3JleTkwIiwgImdyZXk3MCIsICJncmV5NTAiLCAiZ3JleTMwIikpLA0KICAgICAgICAgICAgYmFuZCA9IEZBTFNFKQ0KYGBgDQoNCjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTUwJTsiPipDb25kaXRvbmluZzogVmFzX3JlbF9nbG9iYWwgPj0gNyo8L3NwYW4+DQpgYGB7ciBzdGFpX3Bsb3RfY29uZCwgZmlnLndpZHRoID0gMTAsIGZpZy5hc3AgPSAwLjh9DQojIyBTVEFJIHBsb3QgQ29uZA0KU3RhaW1lbHRfY29uZCA8LSANCiAgRGF0ZSAlPiUNCiAgZmlsdGVyKFZhc19yZWxfZ2xvYmFsID49IDcpICU+JQ0KICBzZWxlY3QoSUQsIENvbmRpdGllLCBTdGFpU19wcmUsIFN0YWlTX3Bvc3QpICU+JQ0KICBnYXRoZXIoIlN0YWlTX3ByZSIsICJTdGFpU19wb3N0Iiwga2V5ID0gIlN0YWlfY29uZCIsIHZhbHVlID0gInZhbHVlIikgJT4lIA0KICBtdXRhdGVfYXQodmFycyhjKDEsIDIsIDMpKSwgZnVucyhhcy5mYWN0b3IpKSAlPiUgDQogIG11dGF0ZShTdGFpX2NvbmQgPSBmYWN0b3IoU3RhaV9jb25kLCBsZXZlbHMgPSBjKCJTdGFpU19wcmUiLCJTdGFpU19wb3N0IikpKSAjICU+JSAgICAjIGNoYW5nZSBmYWN0b3Igb3JkZXIgZm9yIHBsb3QgcHJlLCBwb3N0DQoNCmdncGxvdChTdGFpbWVsdF9jb25kLCBhZXMoeCA9IFN0YWlfY29uZCwgeSA9IHZhbHVlKSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIGZhY2V0X3dyYXAofkNvbmRpdGllKSArDQogIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ0LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBjb21wYXJpc29ucyA9IGxpc3QoYygiU3RhaVNfcHJlIiwiU3RhaVNfcG9zdCIpKSkNCmBgYA0KDQo8c3BhbiBzdHlsZT0iZm9udC1zaXplOjE1MCU7Ij4qU1RBSSBQb3N0IC0gUHJlIGRpZmYgYnkgVmFzX3JlbF9nbG9iYWwqPC9zcGFuPg0KYGBge3IgZGlmZl9zdGFpX3Zhc2dsb2J9DQpEYXRlICU+JQ0KICBtdXRhdGUoU3RhaVNfZGlmZiA9IFN0YWlTX3Bvc3QgLSBTdGFpU19wcmUpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBWYXNfcmVsX2dsb2JhbCwgeSA9IFN0YWlTX2RpZmYsIGNvbG9yID0gQ29uZGl0aWUsIGdyb3VwID0gQ29uZGl0aWUpKSArIA0KICBnZW9tX3BvaW50KCkgKyANCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiZGFya2dyZXkiKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNpemUgPSAxLCBzZSA9IEZBTFNFKSArDQogIHhsaW0oMCwgMTApDQpgYGANCg0KDQojIyBWQVMgU3RyZXMNCmBgYHtyIHJlZ192YXNTX3Zhc2dsb2JhbH0NCiMjIFNUQVkNCmxtX3Zhc1MgPC0gbG0oVmFzX3N0cmVzX3Bvc3QgfiBWYXNfc3RyZXNfcHJlICsgVmFzX3JlbF9nbG9iYWwsIGRhdGEgPSBEYXRlKQ0KYXBhX2xtX3Zhc1MgPC0gYXBhX3ByaW50KGxtX3Zhc1MpDQprbml0cjo6a2FibGUoYXBhX2xtX3Zhc1MkdGFibGUpDQoNCnBhcihtZnJvdz1jKDEsMikpOyB0ZXJtcGxvdChsbV92YXNTLCBwYXJ0aWFsLnJlc2lkID0gVFJVRSwgc2UgPSBUUlVFKQ0KYGBgDQoNCjxzcGFuIHN0eWxlPSJmb250LXNpemU6MTUwJTsiPipJcyB0aGVyZSBhbiBpbnRlcmFjdGlvbiBDb25kaXRpb24geCBWYXMgcmVsIGdsb2JhbD8qPC9zcGFuPg0KYGBge3IgaW50ZXJhY192YXNTX3Zhc2dsb2JhbH0NCmxtX3Zhc1NfaW50ZXIgPC0gbG0oVmFzX3N0cmVzX3Bvc3QgfiBWYXNfc3RyZXNfcHJlICsgQ29uZGl0aWUgKiBWYXNfcmVsX2dsb2JhbCwgZGF0YSA9IERhdGUpDQoNCmtuaXRyOjprYWJsZShhcGFfcHJpbnQobG1fdmFzU19pbnRlcikkdGFibGUpDQoNCnBsb3QodmlzcmVnOjp2aXNyZWcobG1fdmFzU19pbnRlciwgeHZhciA9ICJWYXNfcmVsX2dsb2JhbCIsIGJ5ID0gIkNvbmRpdGllIiwgcGxvdCA9IEZBTFNFKSwNCiAgICAgICAgICAgIG92ZXJsYXkgPSBUUlVFLCBwYXJ0aWFsID0gRkFMU0UsIHJ1ZyA9IEZBTFNFLA0KICAgICAgICAgICAgeGxhYiA9ICJWYXNfcmVsX2dsb2JhbCIsIHlsYWIgPSAiUHJlZGljdGVkIFZBUyBTdHJlc3MiLA0KICAgICAgICAgICAgbGluZSA9IGxpc3QoDQogICAgICAgICAgICBsdHkgPSBjKDE6NCwgNiksICAgICAjIDUgaXMgbG9uZyBkYXNoIGFuZCBkb2VzbnQgbG9vayBuaWNlICAgDQogICAgICAgICAgICBjb2wgPSBjKCJibGFjayIsICJncmV5OTAiLCAiZ3JleTcwIiwgImdyZXk1MCIsICJncmV5MzAiKSksDQogICAgICAgICAgICBiYW5kID0gRkFMU0UpDQpgYGANCg0KPHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxNTAlOyI+KkNvbmRpdG9uaW5nOiBWYXNfcmVsX2dsb2JhbCA+PSA3Kjwvc3Bhbj4NCmBgYHtyIHZhc1NfcGxvdF9jb25kLCBmaWcud2lkdGggPSAxMCwgZmlnLmFzcCA9IDAuOH0NCiMjIFZhcyBTdHJlcyBwbG90IA0KVmFzc3RyZXNtZWx0X2NvbmQgPC0gDQogIERhdGUgJT4lDQogIGZpbHRlcihWYXNfcmVsX2dsb2JhbCA+PSA3KSAlPiUNCiAgc2VsZWN0KElELCBDb25kaXRpZSwgVmFzX3N0cmVzX3ByZSwgVmFzX3N0cmVzX3Bvc3QpICU+JQ0KICBnYXRoZXIoIlZhc19zdHJlc19wcmUiLCJWYXNfc3RyZXNfcG9zdCIsIGtleSA9ICJWYXNfc3RyZXNfY29uZCIsIHZhbHVlID0gInZhbHVlIikgJT4lIA0KICBtdXRhdGVfYXQodmFycyhjKDEsMiwzKSksIGZ1bnMoYXMuZmFjdG9yKSkgJT4lIA0KICBtdXRhdGVfYXQodmFycyhjKDQpKSwgZnVucyhhcy5udW1lcmljKSkgJT4lIA0KICBtdXRhdGUoVmFzX3N0cmVzX2NvbmQgPSBmYWN0b3IoVmFzX3N0cmVzX2NvbmQsIGxldmVscyA9IGMoIlZhc19zdHJlc19wcmUiLCJWYXNfc3RyZXNfcG9zdCIpKSkgIyBjaGFuZ2UgZmFjdG9yIG9yZGVyIGZvciBwbG90IHByZSwgcG9zdA0KDQpnZ3Bsb3QoVmFzc3RyZXNtZWx0X2NvbmQsIGFlcyh4ID0gVmFzX3N0cmVzX2NvbmQsIHkgPSB2YWx1ZSkpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBmYWNldF93cmFwKH5Db25kaXRpZSkgKw0KICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAidC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgY29tcGFyaXNvbnMgPSBsaXN0KGMoIlZhc19zdHJlc19wcmUiLCJWYXNfc3RyZXNfcG9zdCIpKSkNCmBgYA0KDQo8c3BhbiBzdHlsZT0iZm9udC1zaXplOjE1MCU7Ij4qVkFTIFN0cmVzIFBvc3QgLSBQcmUgZGlmZiBieSBWYXNfcmVsX2dsb2JhbCo8L3NwYW4+DQpgYGB7ciBkaWZmX3Zhc1NfdmFzZ2xvYn0NCkRhdGUgJT4lDQogIG11dGF0ZShWYXNfc3RyZXNfZGlmZiA9IFZhc19zdHJlc19wb3N0IC0gVmFzX3N0cmVzX3ByZSkgJT4lDQogIGdncGxvdChhZXMoeCA9IFZhc19yZWxfZ2xvYmFsLCB5ID0gVmFzX3N0cmVzX2RpZmYsIGNvbG9yID0gQ29uZGl0aWUsIGdyb3VwID0gQ29uZGl0aWUpKSArIA0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzaXplID0gMSwgc2UgPSBGQUxTRSkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJkYXJrZ3JleSIpICsNCiAgeGxpbSgwLCAxMCkNCmBgYA0KDQoNCiMjIFZBUyBXZWxsYmVpbmcNCmBgYHtyIHJlZ192YXNCX3Zhc2dsb2JhbH0NCiMjIFNUQVkNCmxtX3Zhc0IgPC0gbG0oVmFzX2JpbmVfcG9zdCB+IFZhc19iaW5lX3ByZSArIFZhc19yZWxfZ2xvYmFsLCBkYXRhID0gRGF0ZSkNCmFwYV9sbV92YXNCIDwtIGFwYV9wcmludChsbV92YXNCKQ0Ka25pdHI6OmthYmxlKGFwYV9sbV92YXNCJHRhYmxlKQ0KDQpwYXIobWZyb3c9YygxLDIpKTsgdGVybXBsb3QobG1fdmFzQiwgcGFydGlhbC5yZXNpZCA9IFRSVUUsIHNlID0gVFJVRSkNCmBgYA0KDQo8c3BhbiBzdHlsZT0iZm9udC1zaXplOjE1MCU7Ij4qSXMgdGhlcmUgYW4gaW50ZXJhY3Rpb24gQ29uZGl0aW9uIHggVmFzIHJlbCBnbG9iYWw/Kjwvc3Bhbj4NCmBgYHtyIGludGVyYWNfdmFzQl92YXNnbG9iYWx9DQpsbV92YXNCX2ludGVyIDwtIGxtKFZhc19iaW5lX3Bvc3QgfiBWYXNfYmluZV9wcmUgKyBDb25kaXRpZSAqIFZhc19yZWxfZ2xvYmFsLCBkYXRhID0gRGF0ZSkNCg0Ka25pdHI6OmthYmxlKGFwYV9wcmludChsbV92YXNCX2ludGVyKSR0YWJsZSkNCg0KcGxvdCh2aXNyZWc6OnZpc3JlZyhsbV92YXNCX2ludGVyLCB4dmFyID0gIlZhc19yZWxfZ2xvYmFsIiwgYnkgPSAiQ29uZGl0aWUiLCBwbG90ID0gRkFMU0UpLA0KICAgICAgICAgICAgb3ZlcmxheSA9IFRSVUUsIHBhcnRpYWwgPSBGQUxTRSwgcnVnID0gRkFMU0UsDQogICAgICAgICAgICB4bGFiID0gIlZhc19yZWxfZ2xvYmFsIiwgeWxhYiA9ICJQcmVkaWN0ZWQgVkFTIFdlbGxiZWluZyIsDQogICAgICAgICAgICBsaW5lID0gbGlzdCgNCiAgICAgICAgICAgIGx0eSA9IGMoMTo0LCA2KSwgICAgICMgNSBpcyBsb25nIGRhc2ggYW5kIGRvZXNudCBsb29rIG5pY2UgICANCiAgICAgICAgICAgIGNvbCA9IGMoImJsYWNrIiwgImdyZXk5MCIsICJncmV5NzAiLCAiZ3JleTUwIiwgImdyZXkzMCIpKSwNCiAgICAgICAgICAgIGJhbmQgPSBGQUxTRSkNCmBgYA0KDQo8c3BhbiBzdHlsZT0iZm9udC1zaXplOjE1MCU7Ij4qQ29uZGl0b25pbmc6IFZhc19yZWxfZ2xvYmFsID49IDcqPC9zcGFuPg0KYGBge3IgdmFzQl9wbG90X2NvbmQsIGZpZy53aWR0aCA9IDEwLCBmaWcuYXNwID0gMC44fQ0KIyMgVmFzIFN0cmVzIHBsb3QgDQpWYXNiaW5lbWVsdF9jb25kIDwtIA0KICBEYXRlICU+JQ0KICBmaWx0ZXIoVmFzX3JlbF9nbG9iYWwgPj0gNykgJT4lDQogIHNlbGVjdChJRCwgQ29uZGl0aWUsIFZhc19iaW5lX3ByZSwgVmFzX2JpbmVfcG9zdCkgJT4lDQogIGdhdGhlcigiVmFzX2JpbmVfcHJlIiwiVmFzX2JpbmVfcG9zdCIsIGtleSA9ICJWYXNfYmluZV9jb25kIiwgdmFsdWUgPSAidmFsdWUiKSAlPiUgDQogIG11dGF0ZV9hdCh2YXJzKGMoMSwyLDMpKSwgZnVucyhhcy5mYWN0b3IpKSAlPiUgDQogIG11dGF0ZV9hdCh2YXJzKGMoNCkpLCBmdW5zKGFzLm51bWVyaWMpKSAlPiUgDQogIG11dGF0ZShWYXNfYmluZV9jb25kID0gZmFjdG9yKFZhc19iaW5lX2NvbmQsIGxldmVscyA9IGMoIlZhc19iaW5lX3ByZSIsIlZhc19iaW5lX3Bvc3QiKSkpICMgY2hhbmdlIGZhY3RvciBvcmRlciBmb3IgcGxvdCBwcmUsIHBvc3QNCg0KZ2dwbG90KFZhc2JpbmVtZWx0X2NvbmQsIGFlcyh4ID0gVmFzX2JpbmVfY29uZCwgeSA9IHZhbHVlKSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIGZhY2V0X3dyYXAofkNvbmRpdGllKSArDQogIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZCA9ICJ0LnRlc3QiLCBwYWlyZWQgPSBUUlVFLCBjb21wYXJpc29ucyA9IGxpc3QoYygiVmFzX2JpbmVfcHJlIiwiVmFzX2JpbmVfcG9zdCIpKSkNCmBgYA0KDQo8c3BhbiBzdHlsZT0iZm9udC1zaXplOjE1MCU7Ij4qVkFTIEJpbmUgUG9zdCAtIFByZSBkaWZmIGJ5IFZhc19yZWxfZ2xvYmFsKjwvc3Bhbj4NCmBgYHtyIGRpZmZfdmFzQl92YXNnbG9ifQ0KRGF0ZSAlPiUNCiAgbXV0YXRlKFZhc19iaW5lX2RpZmYgPSBWYXNfYmluZV9wb3N0IC0gVmFzX2JpbmVfcHJlKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gVmFzX3JlbF9nbG9iYWwsIHkgPSBWYXNfYmluZV9kaWZmLCBjb2xvciA9IENvbmRpdGllLCBncm91cCA9IENvbmRpdGllKSkgKyANCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2l6ZSA9IDEsIHNlID0gRkFMU0UpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiZGFya2dyZXkiKSArDQogIHhsaW0oMCwgMTApDQpgYGANCg0KDQo8YnI+DQo8YnI+DQo8YnI+DQo8YnI+DQoNCiMgTWVsdCBkYXRhZnJhbWUgZm9yIGZ1dHVyZSBhbmFseXNlcw0KDQpgYGB7ciB3aWRlZm9ybWF0X2RhdGF9DQojIERhdGEgZnJvbSBMb25nIHRvIFdpZGUNCm1lbHREYXRlIDwtIA0KICBEYXRlICU+JSANCiAgICBzZWxlY3QoSUQsIENvbmRpdGllLCANCiAgICAgICAgICAgVmFzX3N0cmVzX3ByZSwgVmFzX3N0cmVzX3Bvc3QsDQogICAgICAgICAgIFZhc19iaW5lX3ByZSwgVmFzX2JpbmVfcG9zdCwNCiAgICAgICAgICAgU3RhaVNfcHJlLCBTdGFpU19wb3N0KSAlPiUNCiAgICAgIGdhdGhlcih2YXJpYWJsZSwgdmFsdWUsIFZhc19zdHJlc19wcmU6U3RhaVNfcG9zdCkgJT4lDQogICAgICB1bml0ZShWYXJDb25kLCB2YXJpYWJsZSwgQ29uZGl0aWUpICU+JSANCiAgICAgIHNwcmVhZChWYXJDb25kLCB2YWx1ZSkNCg0KIyBTb21lIHJvd25hbWVzIGFyZSB0eXBvcyAoSUQgMSBhbmQgMjYpDQpmdW5jX2NvbGxhcHNlZHVwbGljYXRlIDwtIGZ1bmN0aW9uKHgpIHsgICAgICAgICAgICMgY29sbGFwc2VzIGR1cGxpY2F0ZSByb3dzLCBidXQgaWYgYWxsIGFyZSBOQSByZXR1cm5zIE5BDQogIHN1bSh4LCBuYS5ybT1UICkgKiBOQSBeIChzdW0oIWlzLm5hKHgpKSA9PSAwKQ0KfQ0KDQptZWx0RGF0ZSA8LQ0KICBtZWx0RGF0ZSAlPiUNCiAgICBtdXRhdGUoSUQgPSB3b3JkKElELCAxKSkgJT4lDQogICAgZ3JvdXBfYnkoSUQpICU+JSANCiAgICBzdW1tYXJpc2VfYWxsKGZ1bmNfY29sbGFwc2VkdXBsaWNhdGUpDQoNCiAgDQojIFRlc3QgaWYgYWxsIHJlc3VsdHMgYXJlIHRoZSBzYW1lIC0tIGFsbCBzZWVtcyBnb29kDQojIHQudGVzdChtZWx0RGF0ZSRWYXNfYmluZV9wcmVfcHJpZXRlbiwgbWVsdERhdGUkVmFzX2JpbmVfcG9zdF9wcmlldGVuLCANCiMgICAgICAgICAgICAgICAgICAgICAgICAgbXUgPSAwLCANCiMgICAgICAgICAgICAgICAgICAgICAgICAgYWx0ID0gInR3by5zaWRlZCIsIA0KIyAgICAgICAgICAgICAgICAgICAgICAgICBwYWlyZWQgPSBUUlVFLCANCiMgICAgICAgICAgICAgICAgICAgICAgICAgY29uZi5sZXZlbCA9IDAuOTUpDQoNCm1lbHREYXRlICU+JQ0KICAgICAgRFQ6OmRhdGF0YWJsZSggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBleGNlbCBkb3dubG9hZGFibGUgIERUIHRhYmxlDQogICAgICBleHRlbnNpb25zID0gJ0J1dHRvbnMnLA0KICAgICAgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDIwLA0KICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsWD0nNTAwcHgnLCANCiAgICAgICAgICAgICAgICAgICAgIGRvbSA9ICdCZnJ0aXAnLCANCiAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBjKCdleGNlbCcsICJjc3YiKSkpDQpgYGANCg0KDQoNCjwhLS0gU2Vzc2lvbiBJbmZvIGFuZCBMaWNlbnNlIC0tPg0KDQo8YnI+DQoNCiMgU2Vzc2lvbiBJbmZvDQpgYGB7ciBzZXNzaW9uX2luZm8sIGVjaG8gPSBGQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQ0Kc2Vzc2lvbkluZm8oKSAgICANCmBgYA0KDQo8IS0tIEZvb3RlciAtLT4NCiZuYnNwOw0KPGhyIC8+DQo8cCBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyI+QSB3b3JrIGJ5IDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9DbGF1ZGl1UGFwYXN0ZXJpLyI+Q2xhdWRpdSBQYXBhc3Rlcmk8L2E+PC9wPg0KPHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxzcGFuIHN0eWxlPSJjb2xvcjogIzgwODA4MDsiPjxlbT5jbGF1ZGl1LnBhcGFzdGVyaUBnbWFpbC5jb208L2VtPjwvc3Bhbj48L3A+DQombmJzcDsNCg==