source("0_helpers.R")
load("data/cleaned_selected.rdata")
opts_chunk$set(warning = F, message = F, error = T)
all_surveys <- all_surveys %>% 
  mutate(relationship_duration = duration_relationship_years + duration_relationship_month/12)
## mutate: new variable 'relationship_duration' with 187 unique values and 33% NA
library(knitr)
opts_chunk$set(fig.width = 9, fig.height = 7, cache = T, warning = F, message = F, cache = F, error = T)
library(kableExtra)

Study flow chart

knitr::include_graphics("sfig_flow_chart_general_desire.png")
Flow chart of the steps of the menstrual cycle diary study.

Flow chart of the steps of the menstrual cycle diary study.

began_s1_demo = sum(!is.na(s1_demo$created))
ended_s1_demo = sum(!is.na(s1_demo$ended))
diary <- s1_filter %>% left_join(diary, by = c('session', 'short'), suffix = c("_filter", ""))
ended_pre = diary %>% filter(!is.na(ended_initial)) %>% ungroup() %>% summarise(n = n_distinct(session)) %>% pull(n)
diary %>% group_by(gets_paid) %>% summarise(n = sum(!is.na(ended_initial[!duplicated(session)]), n = n_distinct(session)))
## # A tibble: 2 x 2
##   gets_paid     n
##   <chr>     <int>
## 1 0          1893
## 2 1          1087
at_least_one_diary_entry = diary %>% group_by(session) %>% summarise(n = n_nonmissing(ended_diary)) %>% filter(n >= 1) %>% nrow()
at_least_20_diary_entries = diary %>% group_by(session) %>% summarise(n = n_nonmissing(ended_diary)) %>% filter(n >= 20) %>% nrow()
at_least_50_diary_entries = diary %>% group_by(session) %>% summarise(n = n_nonmissing(ended_diary)) %>% filter(n >= 50) %>% nrow()

in_relationship = sum(s1_demo$hetero_relationship, na.rm = T)
singles = sum(! s1_demo$hetero_relationship, na.rm = T)

at_least_one_diary_entry = s3_daily %>% group_by(session) %>% summarise(n = n_nonmissing(ended)) %>% filter(n >= 1) %>% nrow()
at_least_20_diary_entries = s3_daily %>% group_by(session) %>% summarise(n = n_nonmissing(ended)) %>% filter(n >= 20) %>% nrow()
at_least_50_diary_entries = s3_daily %>% group_by(session) %>% summarise(n = n_nonmissing(ended)) %>% filter(n >= 50) %>% nrow()

mean_diary_entries <- s3_daily %>% group_by(session) %>% summarise(n = n_nonmissing(ended)) %>% summarise(mean(n))

mean_diary_entries_by_payment <- s1_filter %>% 
  select(-ended) %>% left_join(s3_daily, by = 'session') %>% 
  group_by(gets_paid, session) %>%
  summarise(n = n_nonmissing(ended)) %>% 
  filter(n > 0) %>% 
  group_by(gets_paid) %>% 
  summarise(responses = mean(n), n = n_distinct(session))

response_rate_over_time <- diary %>% 
  filter(day_number >= 0, day_number < 70) %>% 
  left_join(s1_filter, by = 'session', suffix = c("", "_filter")) %>% 
  group_by(gets_paid) %>% 
  mutate(
    n = n_distinct(session)
  ) %>% 
  group_by(gets_paid, day_number) %>% 
  summarise(
    n = unique(n),
    entries = n_nonmissing(ended_diary),
    rr = entries / unique(n))

ggplot(response_rate_over_time, aes(day_number, rr, colour = gets_paid)) + geom_point() +
    ggtitle("Response rate over time", "for people who started the diary") + ylim(0,1)

mean_diary_entries_finishers <- s4_followup %>% select(-ended) %>% left_join(s3_daily, by = 'session') %>% group_by(session) %>% summarise(n = n_nonmissing(ended)) %>% summarise(mean(n))

response_rate_over_time <- s4_followup %>% select(-ended) %>% 
  left_join(diary %>% select(session, day_number, created_diary, ended_diary)) %>% filter(day_number >= 0, day_number < 70) %>% 
  left_join(s1_filter, by = 'session', suffix = c("", "_filter")) %>% 
  group_by(gets_paid) %>% 
  mutate(
    n = n_distinct(session)
  ) %>% 
  group_by(gets_paid, day_number) %>% 
  summarise(
    entries = n_nonmissing(ended_diary),
    rr = entries / unique(n))

ggplot(response_rate_over_time, aes(day_number, rr, colour = gets_paid)) + 
  geom_point() +
    ggtitle("Response rate over time", "for people who finished the diary") + ylim(0,1)

response_rate_over_time <- diary %>% 
  # I am leaving in days that we excluded post-hoc (e.g., because fertility was not estimable, to show the real response rate, irrespective of diary-data-based exclusions)
  filter(reasons_for_exclusion == reasons_for_exclusion_diary) %>% 
  select(session, day_number, created_diary, ended_diary) %>% 
  filter(day_number >= 0, day_number < 70) %>% 
  left_join(s1_filter, by = 'session', suffix = c("", "_filter")) %>% 
  group_by(gets_paid) %>% 
  mutate(
    n = n_distinct(session)
  ) %>% 
  group_by(gets_paid, day_number) %>% 
  summarise(
    n = unique(n),
    entries = n_nonmissing(ended_diary),
    rr = entries / unique(n))

ggplot(response_rate_over_time, aes(day_number, rr, colour = gets_paid)) + 
  geom_point() +
    ggtitle("Response rate over time", "for included subsample") + ylim(0,1)

nsmt2d_over_time <- s4_followup %>% select(-ended) %>% 
  left_join(diary %>% select(session, day_number, never_skipped_more_than_2, created_diary, ended_diary)) %>% 
  left_join(s1_filter, by = 'session', suffix = c("", "_filter")) %>% 
  left_join(mean_diary_entries_by_payment) %>% 
  group_by(gets_paid, day_number) %>% 
  summarise(entries = sum(as.numeric(never_skipped_more_than_2), na.rm = T),
            rr = entries / unique(n))

ggplot(nsmt2d_over_time, aes(day_number, rr, colour = gets_paid)) + 
  geom_point() +
    ggtitle("Percentage who never skipped more than two days over time", "for people who finished the diary") + ylim(0,1)

mean_finishing_personality_by_payment <- s1_demo %>% 
  left_join(s1_filter, by = 'session', suffix = c("_demo", "")) %>% 
  left_join(s2_initial,by ='session', suffix = c("", "_initial")) %>% 
  group_by(gets_paid) %>% 
  summarise(finish_demo = n_nonmissing(ended_demo), 
            finish_initial = n_nonmissing(ended_initial), n = n(),
            prc_ini_over_demo = round(100*finish_initial/finish_demo),
            consc = mean(bfi_consc,na.rm=T))
kable(mean_finishing_personality_by_payment)
gets_paid finish_demo finish_initial n prc_ini_over_demo consc
0 1050 871 1050 83 3.577
1 557 540 557 97 3.478
NA 0 0 53 NaN NaN
mean_finishing_follow_up_by_payment <- s1_filter %>% select(-ended) %>% right_join(s2_initial,by ='session') %>% left_join(s4_followup, by = 'session', suffix = c("_initial", "_followup")) %>% group_by(gets_paid) %>% summarise(followup = n_nonmissing(ended_followup), initial = n_nonmissing(ended_initial), n(), prc_fu_over_initial = round(100*followup/initial))
kable(mean_finishing_follow_up_by_payment)
gets_paid followup initial n() prc_fu_over_initial
0 656 871 958 75
1 484 540 554 90
fertile_known_man_known = diary_social %>% group_by(session, created) %>% 
  summarise(n = n_nonmissing(person_attractiveness_short_term)) %>% 
  group_by(session) %>% summarise(n = sum(n)) # fertility known, man known
fertile_known_man_known$n %>% qplot() + xlim(1,NA)

fertile_known_person_known = diary_social %>% group_by(session, created) %>% 
  summarise(n = n_nonmissing(person_sex)) %>% 
  group_by(session) %>% summarise(n = sum(n)) # fertility known, man known

finished_timespent = s4_timespent %>% group_by(session) %>% summarise(n = n_nonmissing(ended)) %>% filter(n >= 1) %>% nrow()
timespent_gt3 = s4_timespent %>% group_by(session) %>% summarise(n = n_nonmissing(ended)) %>% filter(n > 3) %>% nrow()
timespent_men = network %>% group_by(session) %>% filter(person_sex == 2, person_relationship_to_anchor != "biological_relative") %>% summarise(n = n_nonmissing(ended)) %>% filter(n > 0) %>% nrow()
timespent_3men = network %>% group_by(session) %>% filter(person_sex == 2, person_relationship_to_anchor != "biological_relative") %>% summarise(n = n_nonmissing(ended)) %>% filter(n > 2) %>% nrow()

fertile_known_man_known_participants = fertile_known_man_known %>% filter(n > 0) %>% nrow()
fertile_known_person_known_participants = fertile_known_person_known %>% filter(n > 0) %>% nrow()

finished_followup = sum(!is.na(s4_followup$ended))

# all_surveys %>% mutate(
#   should_be_done = created_demo + days(70) < today()
# ) %>% filter(should_be_done == T) %>% xtabs(~ is.na(ended), .)

# all_surveys %>% mutate(
# should_be_done = created_demo + days(70) < today()
# ) %>% left_join(s3_daily %>% group_by(session) %>% summarise(n = n_nonmissing(ended))) %>% 
#  filter(should_be_done == T, n > 40) %>% xtabs(~ is.na(ended), .)

all_surveys %>% mutate(should_be_done = created_demo + days(70) < today()) %>%
 left_join( s4_timespent %>% group_by(session) %>% summarise(n_timespent = n_nonmissing(ended)), by = 'session') %>% 
 filter(hetero_relationship == 0, should_be_done == T, n_timespent > 0, !is.na(n_timespent)) %>% nrow()
## [1] 349
all_surveys %>% mutate(should_be_done = created_demo + days(70) < today()) %>%
 left_join( s4_timespent %>% group_by(session) %>% summarise(n_timespent =  n_nonmissing(ended)), by = 'session') %>% 
 filter(hetero_relationship == 0 & should_be_done == T & (is.na(n_timespent) | n_timespent == 0)) %>% nrow()
## [1] 184
  1. 1660 signed up for the study.
  2. 1607 finished the demographics (533 singles, 1091 in relationship).
  3. 1373 finished the demographic and personality questionnaires.
  4. 1345 submitted at least one diary entry (>= 20: 1075, >= 50 774). On average participants completed 44.5645 diary entries.
  5. 349 singles reported information on least one person mentioned during the diary (>3: 293, at least one man who wasn’t biologically related: 282, >2men: 124).
  6. 1140 (83% of those who finished the intake survey) finished the follow-up survey. Finishers completed on average 50.316 diary entries.

Contraception

library(UpSetR)
comma_separated_to_columns <- function(df, col) {
  colname <- deparse(substitute(col))
  df$splitcol <- df %>% pull(colname)
  separate_rows(df, splitcol, convert = TRUE, sep = ", ") %>% 
    mutate(splitcol = if_else(is.na(splitcol), "no", 
                        if_else(splitcol == "" | 
                                  splitcol %in% c(), "other", as.character(splitcol)))) %>% 
    mutate(#splitcol = stringr::str_c(colname, "_", splitcol), 
           value = 1) %>% 
    spread(splitcol, value, fill = 0) %>% 
    select(-colname)
}
library(UpSetR)
all_surveys %>% select(session, contraception_method) %>% 
  comma_separated_to_columns(contraception_method) %>% 
  select(-session) %>% 
  as.data.frame() %>% 
  {
  upset(., ncol(.), 20, show.numbers = TRUE, order.by = "freq",
      main.bar.color = "#6E8691",
      matrix.color = "#6E8691",
      sets.bar.color = "#53AC9B")
  }

social network

summary(as.factor(network$person_sex))
##    1    2    3 NA's 
## 1160  796  160  129
by_sex = s4_timespent %>% 
    group_by(session) %>% 
    summarise(female = sum(person_sex == 1, na.rm=T), male = sum(person_sex == 2, na.rm=T), n= n()) %>% select(female, male,n)
total_network = nrow(network)
persons= nrow(network %>% filter(person_remember == 1 & !is.na(ended)))

2245 number of persons who were mentioned in diary 2118 number of nicknames/names women remembered.

Comparison with quasi-control group

Comparisons on key variables

women <- all_surveys %>% filter(reasons_for_exclusion == "")
dig1 <- function(x) { sprintf("%.1f", x) }
dig2 <- function(x) { sprintf("%.2f", x) }
pct <- function(x) { sprintf("%.0f", x*100) }

remove_p_values <- function(planned_plot, call_parts = 3:10) {
  subtitle <- as.list(planned_plot$labels$subtitle)
  subtitle[call_parts] <- NULL
  planned_plot$labels$subtitle <- as.call(subtitle)
  planned_plot
}
comps = data_frame(Variable = character(0), 
                   `HC user - Mean (SD)` = character(0), 
                   `Cycling - Mean (SD)` = character(0),
                   `99% CI` = character(0),
)

compare_by_group = function(var, data, type = "np", ...) {
  var_s <- enquo(var)
  var <- rlang::as_name(var_s)
 sd_hc = sd(data[data$hormonal_contraception == 1,][[var]], na.rm = T)
 sd_nc = sd(data[data$hormonal_contraception == 0,][[var]], na.rm = T)
  data$`Hormonal contraception` = forcats::fct_relevel( forcats::fct_recode(forcats::as_factor(data$hormonal_contraception), "Cycling" = "FALSE", "HC user" = "TRUE"), "HC user")
 comp = as.formula(paste0("`",var, "` ~ `Hormonal contraception`"))
 tt = t.test(comp, data = data, conf.level = 0.99)

 summary = data_frame(Variable = var, 
                   `HC user - Mean (SD)` = paste0(dig1(tt$estimate[1])," (", dig1(sd_hc),")"), 
                   `Cycling - Mean (SD)` = paste0(dig1(tt$estimate[2]), " (", dig1(sd_nc), ")"),
                   `99% CI` = paste(dig1(tt$conf.int), collapse = ";")
 )
 rownames(summary) = NULL
 comps <<- bind_rows(comps, summary)
 data[[var]] <- data[[var]] %>% zap_attributes()
 planned_plot <- ggstatsplot::ggbetweenstats(
  data = data,
  x = `Hormonal contraception`,
  y = !! var_s,
  messages = FALSE,
  conf.level = 0.99,
  type = type, ..., 
  ggtheme = theme_cowplot(font_size = 18)
  ) + # further modification outside of ggstatsplot
  scale_color_manual("", values = c("Cycling" = "red", "HC user" = "black"), guide = F) +
  # scale_x_discrete("Hormonal contraception", labels = c("1" = "HC user", "2" = "Cycling")) +
  scale_fill_manual("", values = c("Cycling" = "red", "HC user" = "black"), guide = F)
 remove_p_values(planned_plot)
}
library(ggstatsplot)
library(cowplot)
women$`Age (years)` <- women$age
compare_by_group(`Age (years)`, women)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

{ ggbarstats(women %>% mutate(relationship_status=as_factor(relationship_status)), 
           relationship_status,
           hormonal_contraception,
           messages = FALSE,
  conf.level = 0.99,
  bf.message = F,
  ggtheme = theme_cowplot(font_size = 18)
  ) + # further modification outside of ggstatsplot
  scale_x_discrete("Hormonal contraception", labels = c("TRUE" = "HC user", "FALSE" = "Cycling"))
} %>% 
  remove_p_values(call_parts = 3:12)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of categories in each group and the results of a Chi-Square test for equal distribution.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of categories in each group and the results of a Chi-Square test for equal distribution.

women$`Age at first sex (years)` <- women$first_time
compare_by_group(`Age at first sex (years)`, women)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

women$`Age at menarche (years)` <- women$menarche
compare_by_group(`Age at menarche (years)`, women)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

women$`Relationship duration (years)` <- women$relationship_duration
compare_by_group(`Relationship duration (years)`, women) + scale_y_sqrt(breaks = c(1,5, 10, 20, 30))
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

women$`Avg. cycle length (days)` <- women$menstruation_length
compare_by_group(`Avg. cycle length (days)`, women)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

women$`Cycle regularity` <- women$menstruation_regularity
compare_by_group(`Cycle regularity`, women) + 
  scale_y_continuous(
    labels = c("1" = "no fluctuation",
               "2" = "1-2 days",
               "3" = "3-5 days",
               "4" = ">5 days"))
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

women$`No. lifetime sexual partners` <- women$number_sexual_partner
compare_by_group(`No. lifetime sexual partners`, women, type = "r") %>% 
  remove_p_values(call_parts = 3:4) + 
  scale_y_sqrt(breaks = c(1,5, 10, 20, 50, 100))
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of Yuen's test for trimmed means (10% trimmed).

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of Yuen’s test for trimmed means (10% trimmed).

women$`BFI Extraversion` <- women$bfi_extra
compare_by_group(`BFI Extraversion`, women)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

women$`BFI Agreeableness` <- women$bfi_agree
compare_by_group(`BFI Agreeableness`, women)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

women$`BFI Neuroticism` <- women$bfi_neuro
compare_by_group(`BFI Neuroticism`, women)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

women$`BFI Conscientiousness` <- women$bfi_consc
compare_by_group(`BFI Conscientiousness`, women)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

women$`BFI Openness` <- women$bfi_open
compare_by_group(`BFI Openness`, women)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

women$`Sociosexuality Inventory Revised` <- women$soi_r
compare_by_group(`Sociosexuality Inventory Revised`, women)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

women$`Relationship satisfaction` <- women$relationship_satisfaction
compare_by_group(`Relationship satisfaction`, women)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

compare_by_group(religiosity, women)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of values in each group and the results of a Mann-Whitney U test.

{ ggbarstats(women, 
           net_income,
           hormonal_contraception,
           messages = FALSE,
  bf.message = F,
  conf.level = 0.99,
  ggtheme = theme_cowplot(font_size = 18)
  ) + # further modification outside of ggstatsplot
  scale_x_discrete("Hormonal contraception", labels = c("TRUE" = "HC user", "FALSE" = "Cycling"))} %>% 
  remove_p_values(call_parts = 3:12)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of categories in each group and the results of a Chi-Square test for equal distribution.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of categories in each group and the results of a Chi-Square test for equal distribution.

{ ggbarstats(women, 
           living_situation,
           hormonal_contraception,
           messages = FALSE,
  conf.level = 0.99,
  bf.message = F,
  ggtheme = theme_cowplot(font_size = 18)
  ) + # further modification outside of ggstatsplot
  scale_x_discrete("Hormonal contraception", labels = c("TRUE" = "HC user", "FALSE" = "Cycling")) } %>% 
  remove_p_values(call_parts = 3:12)
Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of categories in each group and the results of a Chi-Square test for equal distribution.

Comparison of the hormonal contraception users (our quasi-control group) with women who are regularly cycling. The plot shows the distribution of categories in each group and the results of a Chi-Square test for equal distribution.

Summary

comps %>% 
    kable(caption = "Means, SDs, and differences between both groups for all continuous variables") %>%
  footnote("99% CI interval of the difference.") %>%
  kable_styling()
Means, SDs, and differences between both groups for all continuous variables
Variable HC user - Mean (SD) Cycling - Mean (SD) 99% CI
Age (years) 23.7 (4.4) 26.3 (5.9) -3.6;-1.8
Age at first sex (years) 16.8 (2.6) 17.1 (2.9) -0.8;0.2
Age at menarche (years) 12.7 (1.3) 12.7 (1.4) -0.3;0.2
Relationship duration (years) 3.4 (3.2) 4.2 (4.9) -1.6;0.1
Avg. cycle length (days) 27.7 (2.3) 28.9 (3.1) -1.7;-0.7
Cycle regularity 1.8 (0.7) 2.4 (0.7) -0.8;-0.5
No. lifetime sexual partners 5.8 (8.6) 8.8 (10.9) -4.7;-1.2
BFI Extraversion 3.5 (0.8) 3.4 (0.8) -0.1;0.2
BFI Agreeableness 3.7 (0.6) 3.7 (0.6) -0.0;0.2
BFI Neuroticism 3.0 (0.8) 3.0 (0.8) -0.2;0.1
BFI Conscientiousness 3.6 (0.7) 3.5 (0.7) 0.0;0.3
BFI Openness 3.7 (0.6) 3.8 (0.6) -0.2;0.0
Sociosexuality Inventory Revised 2.6 (0.8) 2.9 (0.9) -0.5;-0.2
Relationship satisfaction 4.2 (0.8) 3.9 (0.9) 0.1;0.5
religiosity 2.2 (1.4) 2.2 (1.4) -0.3;0.2
Note:
99% CI interval of the difference.

Multiple regression

altogether = glm(hormonal_contraception ~ age  + living_situation + religiosity + bfi_extra + bfi_neuro + bfi_agree + bfi_consc + bfi_open + soi_r + first_time + relationship_status + log1p(number_sexual_partner) + has_children + net_income, data = women %>% mutate(relationship_status=as_factor(relationship_status)), family = binomial("probit"))
ggcoefstats(altogether, package = "ggsci", palette = "default_igv", p.adjust.method = "BH",
            conv.level = 0.99, stats.labels = FALSE, point.color = "black") +
  ggrepel::geom_text_repel(aes(label = sprintf("%.2f [%.2f;%.2f]", estimate, conf.low, conf.high)), size = 3.3)
A probit regression predicting hormonal contraception with many predictors at once.

A probit regression predicting hormonal contraception with many predictors at once.

LS0tCnRpdGxlOiBEZXNjcmlwdGl2ZXMKLS0tCgoKYGBge3J9CnNvdXJjZSgiMF9oZWxwZXJzLlIiKQpsb2FkKCJkYXRhL2NsZWFuZWRfc2VsZWN0ZWQucmRhdGEiKQpvcHRzX2NodW5rJHNldCh3YXJuaW5nID0gRiwgbWVzc2FnZSA9IEYsIGVycm9yID0gVCkKYWxsX3N1cnZleXMgPC0gYWxsX3N1cnZleXMgJT4lIAogIG11dGF0ZShyZWxhdGlvbnNoaXBfZHVyYXRpb24gPSBkdXJhdGlvbl9yZWxhdGlvbnNoaXBfeWVhcnMgKyBkdXJhdGlvbl9yZWxhdGlvbnNoaXBfbW9udGgvMTIpCgpsaWJyYXJ5KGtuaXRyKQpvcHRzX2NodW5rJHNldChmaWcud2lkdGggPSA5LCBmaWcuaGVpZ2h0ID0gNywgY2FjaGUgPSBULCB3YXJuaW5nID0gRiwgbWVzc2FnZSA9IEYsIGNhY2hlID0gRiwgZXJyb3IgPSBUKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmBgYAoKIyMgU3R1ZHkgZmxvdyBjaGFydApgYGB7ciBmaWcuY2FwPSJGbG93IGNoYXJ0IG9mIHRoZSBzdGVwcyBvZiB0aGUgbWVuc3RydWFsIGN5Y2xlIGRpYXJ5IHN0dWR5LiIsZmlnLndpZHRoPTgsZmlnLmhlaWdodD04fQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygic2ZpZ19mbG93X2NoYXJ0X2dlbmVyYWxfZGVzaXJlLnBuZyIpCmBgYAoKYGBge3J9CmJlZ2FuX3MxX2RlbW8gPSBzdW0oIWlzLm5hKHMxX2RlbW8kY3JlYXRlZCkpCmVuZGVkX3MxX2RlbW8gPSBzdW0oIWlzLm5hKHMxX2RlbW8kZW5kZWQpKQpkaWFyeSA8LSBzMV9maWx0ZXIgJT4lIGxlZnRfam9pbihkaWFyeSwgYnkgPSBjKCdzZXNzaW9uJywgJ3Nob3J0JyksIHN1ZmZpeCA9IGMoIl9maWx0ZXIiLCAiIikpCmVuZGVkX3ByZSA9IGRpYXJ5ICU+JSBmaWx0ZXIoIWlzLm5hKGVuZGVkX2luaXRpYWwpKSAlPiUgdW5ncm91cCgpICU+JSBzdW1tYXJpc2UobiA9IG5fZGlzdGluY3Qoc2Vzc2lvbikpICU+JSBwdWxsKG4pCmRpYXJ5ICU+JSBncm91cF9ieShnZXRzX3BhaWQpICU+JSBzdW1tYXJpc2UobiA9IHN1bSghaXMubmEoZW5kZWRfaW5pdGlhbFshZHVwbGljYXRlZChzZXNzaW9uKV0pLCBuID0gbl9kaXN0aW5jdChzZXNzaW9uKSkpCmF0X2xlYXN0X29uZV9kaWFyeV9lbnRyeSA9IGRpYXJ5ICU+JSBncm91cF9ieShzZXNzaW9uKSAlPiUgc3VtbWFyaXNlKG4gPSBuX25vbm1pc3NpbmcoZW5kZWRfZGlhcnkpKSAlPiUgZmlsdGVyKG4gPj0gMSkgJT4lIG5yb3coKQphdF9sZWFzdF8yMF9kaWFyeV9lbnRyaWVzID0gZGlhcnkgJT4lIGdyb3VwX2J5KHNlc3Npb24pICU+JSBzdW1tYXJpc2UobiA9IG5fbm9ubWlzc2luZyhlbmRlZF9kaWFyeSkpICU+JSBmaWx0ZXIobiA+PSAyMCkgJT4lIG5yb3coKQphdF9sZWFzdF81MF9kaWFyeV9lbnRyaWVzID0gZGlhcnkgJT4lIGdyb3VwX2J5KHNlc3Npb24pICU+JSBzdW1tYXJpc2UobiA9IG5fbm9ubWlzc2luZyhlbmRlZF9kaWFyeSkpICU+JSBmaWx0ZXIobiA+PSA1MCkgJT4lIG5yb3coKQoKaW5fcmVsYXRpb25zaGlwID0gc3VtKHMxX2RlbW8kaGV0ZXJvX3JlbGF0aW9uc2hpcCwgbmEucm0gPSBUKQpzaW5nbGVzID0gc3VtKCEgczFfZGVtbyRoZXRlcm9fcmVsYXRpb25zaGlwLCBuYS5ybSA9IFQpCgphdF9sZWFzdF9vbmVfZGlhcnlfZW50cnkgPSBzM19kYWlseSAlPiUgZ3JvdXBfYnkoc2Vzc2lvbikgJT4lIHN1bW1hcmlzZShuID0gbl9ub25taXNzaW5nKGVuZGVkKSkgJT4lIGZpbHRlcihuID49IDEpICU+JSBucm93KCkKYXRfbGVhc3RfMjBfZGlhcnlfZW50cmllcyA9IHMzX2RhaWx5ICU+JSBncm91cF9ieShzZXNzaW9uKSAlPiUgc3VtbWFyaXNlKG4gPSBuX25vbm1pc3NpbmcoZW5kZWQpKSAlPiUgZmlsdGVyKG4gPj0gMjApICU+JSBucm93KCkKYXRfbGVhc3RfNTBfZGlhcnlfZW50cmllcyA9IHMzX2RhaWx5ICU+JSBncm91cF9ieShzZXNzaW9uKSAlPiUgc3VtbWFyaXNlKG4gPSBuX25vbm1pc3NpbmcoZW5kZWQpKSAlPiUgZmlsdGVyKG4gPj0gNTApICU+JSBucm93KCkKCm1lYW5fZGlhcnlfZW50cmllcyA8LSBzM19kYWlseSAlPiUgZ3JvdXBfYnkoc2Vzc2lvbikgJT4lIHN1bW1hcmlzZShuID0gbl9ub25taXNzaW5nKGVuZGVkKSkgJT4lIHN1bW1hcmlzZShtZWFuKG4pKQoKbWVhbl9kaWFyeV9lbnRyaWVzX2J5X3BheW1lbnQgPC0gczFfZmlsdGVyICU+JSAKICBzZWxlY3QoLWVuZGVkKSAlPiUgbGVmdF9qb2luKHMzX2RhaWx5LCBieSA9ICdzZXNzaW9uJykgJT4lIAogIGdyb3VwX2J5KGdldHNfcGFpZCwgc2Vzc2lvbikgJT4lCiAgc3VtbWFyaXNlKG4gPSBuX25vbm1pc3NpbmcoZW5kZWQpKSAlPiUgCiAgZmlsdGVyKG4gPiAwKSAlPiUgCiAgZ3JvdXBfYnkoZ2V0c19wYWlkKSAlPiUgCiAgc3VtbWFyaXNlKHJlc3BvbnNlcyA9IG1lYW4obiksIG4gPSBuX2Rpc3RpbmN0KHNlc3Npb24pKQoKcmVzcG9uc2VfcmF0ZV9vdmVyX3RpbWUgPC0gZGlhcnkgJT4lIAogIGZpbHRlcihkYXlfbnVtYmVyID49IDAsIGRheV9udW1iZXIgPCA3MCkgJT4lIAogIGxlZnRfam9pbihzMV9maWx0ZXIsIGJ5ID0gJ3Nlc3Npb24nLCBzdWZmaXggPSBjKCIiLCAiX2ZpbHRlciIpKSAlPiUgCiAgZ3JvdXBfYnkoZ2V0c19wYWlkKSAlPiUgCiAgbXV0YXRlKAogICAgbiA9IG5fZGlzdGluY3Qoc2Vzc2lvbikKICApICU+JSAKICBncm91cF9ieShnZXRzX3BhaWQsIGRheV9udW1iZXIpICU+JSAKICBzdW1tYXJpc2UoCiAgICBuID0gdW5pcXVlKG4pLAogICAgZW50cmllcyA9IG5fbm9ubWlzc2luZyhlbmRlZF9kaWFyeSksCiAgICByciA9IGVudHJpZXMgLyB1bmlxdWUobikpCgpnZ3Bsb3QocmVzcG9uc2VfcmF0ZV9vdmVyX3RpbWUsIGFlcyhkYXlfbnVtYmVyLCByciwgY29sb3VyID0gZ2V0c19wYWlkKSkgKyBnZW9tX3BvaW50KCkgKwogICAgZ2d0aXRsZSgiUmVzcG9uc2UgcmF0ZSBvdmVyIHRpbWUiLCAiZm9yIHBlb3BsZSB3aG8gc3RhcnRlZCB0aGUgZGlhcnkiKSArIHlsaW0oMCwxKQoKbWVhbl9kaWFyeV9lbnRyaWVzX2ZpbmlzaGVycyA8LSBzNF9mb2xsb3d1cCAlPiUgc2VsZWN0KC1lbmRlZCkgJT4lIGxlZnRfam9pbihzM19kYWlseSwgYnkgPSAnc2Vzc2lvbicpICU+JSBncm91cF9ieShzZXNzaW9uKSAlPiUgc3VtbWFyaXNlKG4gPSBuX25vbm1pc3NpbmcoZW5kZWQpKSAlPiUgc3VtbWFyaXNlKG1lYW4obikpCgpyZXNwb25zZV9yYXRlX292ZXJfdGltZSA8LSBzNF9mb2xsb3d1cCAlPiUgc2VsZWN0KC1lbmRlZCkgJT4lIAogIGxlZnRfam9pbihkaWFyeSAlPiUgc2VsZWN0KHNlc3Npb24sIGRheV9udW1iZXIsIGNyZWF0ZWRfZGlhcnksIGVuZGVkX2RpYXJ5KSkgJT4lIGZpbHRlcihkYXlfbnVtYmVyID49IDAsIGRheV9udW1iZXIgPCA3MCkgJT4lIAogIGxlZnRfam9pbihzMV9maWx0ZXIsIGJ5ID0gJ3Nlc3Npb24nLCBzdWZmaXggPSBjKCIiLCAiX2ZpbHRlciIpKSAlPiUgCiAgZ3JvdXBfYnkoZ2V0c19wYWlkKSAlPiUgCiAgbXV0YXRlKAogICAgbiA9IG5fZGlzdGluY3Qoc2Vzc2lvbikKICApICU+JSAKICBncm91cF9ieShnZXRzX3BhaWQsIGRheV9udW1iZXIpICU+JSAKICBzdW1tYXJpc2UoCiAgICBlbnRyaWVzID0gbl9ub25taXNzaW5nKGVuZGVkX2RpYXJ5KSwKICAgIHJyID0gZW50cmllcyAvIHVuaXF1ZShuKSkKCmdncGxvdChyZXNwb25zZV9yYXRlX292ZXJfdGltZSwgYWVzKGRheV9udW1iZXIsIHJyLCBjb2xvdXIgPSBnZXRzX3BhaWQpKSArIAogIGdlb21fcG9pbnQoKSArCiAgICBnZ3RpdGxlKCJSZXNwb25zZSByYXRlIG92ZXIgdGltZSIsICJmb3IgcGVvcGxlIHdobyBmaW5pc2hlZCB0aGUgZGlhcnkiKSArIHlsaW0oMCwxKQoKcmVzcG9uc2VfcmF0ZV9vdmVyX3RpbWUgPC0gZGlhcnkgJT4lIAogICMgSSBhbSBsZWF2aW5nIGluIGRheXMgdGhhdCB3ZSBleGNsdWRlZCBwb3N0LWhvYyAoZS5nLiwgYmVjYXVzZSBmZXJ0aWxpdHkgd2FzIG5vdCBlc3RpbWFibGUsIHRvIHNob3cgdGhlIHJlYWwgcmVzcG9uc2UgcmF0ZSwgaXJyZXNwZWN0aXZlIG9mIGRpYXJ5LWRhdGEtYmFzZWQgZXhjbHVzaW9ucykKICBmaWx0ZXIocmVhc29uc19mb3JfZXhjbHVzaW9uID09IHJlYXNvbnNfZm9yX2V4Y2x1c2lvbl9kaWFyeSkgJT4lIAogIHNlbGVjdChzZXNzaW9uLCBkYXlfbnVtYmVyLCBjcmVhdGVkX2RpYXJ5LCBlbmRlZF9kaWFyeSkgJT4lIAogIGZpbHRlcihkYXlfbnVtYmVyID49IDAsIGRheV9udW1iZXIgPCA3MCkgJT4lIAogIGxlZnRfam9pbihzMV9maWx0ZXIsIGJ5ID0gJ3Nlc3Npb24nLCBzdWZmaXggPSBjKCIiLCAiX2ZpbHRlciIpKSAlPiUgCiAgZ3JvdXBfYnkoZ2V0c19wYWlkKSAlPiUgCiAgbXV0YXRlKAogICAgbiA9IG5fZGlzdGluY3Qoc2Vzc2lvbikKICApICU+JSAKICBncm91cF9ieShnZXRzX3BhaWQsIGRheV9udW1iZXIpICU+JSAKICBzdW1tYXJpc2UoCiAgICBuID0gdW5pcXVlKG4pLAogICAgZW50cmllcyA9IG5fbm9ubWlzc2luZyhlbmRlZF9kaWFyeSksCiAgICByciA9IGVudHJpZXMgLyB1bmlxdWUobikpCgpnZ3Bsb3QocmVzcG9uc2VfcmF0ZV9vdmVyX3RpbWUsIGFlcyhkYXlfbnVtYmVyLCByciwgY29sb3VyID0gZ2V0c19wYWlkKSkgKyAKICBnZW9tX3BvaW50KCkgKwogICAgZ2d0aXRsZSgiUmVzcG9uc2UgcmF0ZSBvdmVyIHRpbWUiLCAiZm9yIGluY2x1ZGVkIHN1YnNhbXBsZSIpICsgeWxpbSgwLDEpCgpuc210MmRfb3Zlcl90aW1lIDwtIHM0X2ZvbGxvd3VwICU+JSBzZWxlY3QoLWVuZGVkKSAlPiUgCiAgbGVmdF9qb2luKGRpYXJ5ICU+JSBzZWxlY3Qoc2Vzc2lvbiwgZGF5X251bWJlciwgbmV2ZXJfc2tpcHBlZF9tb3JlX3RoYW5fMiwgY3JlYXRlZF9kaWFyeSwgZW5kZWRfZGlhcnkpKSAlPiUgCiAgbGVmdF9qb2luKHMxX2ZpbHRlciwgYnkgPSAnc2Vzc2lvbicsIHN1ZmZpeCA9IGMoIiIsICJfZmlsdGVyIikpICU+JSAKICBsZWZ0X2pvaW4obWVhbl9kaWFyeV9lbnRyaWVzX2J5X3BheW1lbnQpICU+JSAKICBncm91cF9ieShnZXRzX3BhaWQsIGRheV9udW1iZXIpICU+JSAKICBzdW1tYXJpc2UoZW50cmllcyA9IHN1bShhcy5udW1lcmljKG5ldmVyX3NraXBwZWRfbW9yZV90aGFuXzIpLCBuYS5ybSA9IFQpLAogICAgICAgICAgICByciA9IGVudHJpZXMgLyB1bmlxdWUobikpCgpnZ3Bsb3QobnNtdDJkX292ZXJfdGltZSwgYWVzKGRheV9udW1iZXIsIHJyLCBjb2xvdXIgPSBnZXRzX3BhaWQpKSArIAogIGdlb21fcG9pbnQoKSArCiAgICBnZ3RpdGxlKCJQZXJjZW50YWdlIHdobyBuZXZlciBza2lwcGVkIG1vcmUgdGhhbiB0d28gZGF5cyBvdmVyIHRpbWUiLCAiZm9yIHBlb3BsZSB3aG8gZmluaXNoZWQgdGhlIGRpYXJ5IikgKyB5bGltKDAsMSkKCgptZWFuX2ZpbmlzaGluZ19wZXJzb25hbGl0eV9ieV9wYXltZW50IDwtIHMxX2RlbW8gJT4lIAogIGxlZnRfam9pbihzMV9maWx0ZXIsIGJ5ID0gJ3Nlc3Npb24nLCBzdWZmaXggPSBjKCJfZGVtbyIsICIiKSkgJT4lIAogIGxlZnRfam9pbihzMl9pbml0aWFsLGJ5ID0nc2Vzc2lvbicsIHN1ZmZpeCA9IGMoIiIsICJfaW5pdGlhbCIpKSAlPiUgCiAgZ3JvdXBfYnkoZ2V0c19wYWlkKSAlPiUgCiAgc3VtbWFyaXNlKGZpbmlzaF9kZW1vID0gbl9ub25taXNzaW5nKGVuZGVkX2RlbW8pLCAKICAgICAgICAgICAgZmluaXNoX2luaXRpYWwgPSBuX25vbm1pc3NpbmcoZW5kZWRfaW5pdGlhbCksIG4gPSBuKCksCiAgICAgICAgICAgIHByY19pbmlfb3Zlcl9kZW1vID0gcm91bmQoMTAwKmZpbmlzaF9pbml0aWFsL2ZpbmlzaF9kZW1vKSwKICAgICAgICAgICAgY29uc2MgPSBtZWFuKGJmaV9jb25zYyxuYS5ybT1UKSkKa2FibGUobWVhbl9maW5pc2hpbmdfcGVyc29uYWxpdHlfYnlfcGF5bWVudCkKCm1lYW5fZmluaXNoaW5nX2ZvbGxvd191cF9ieV9wYXltZW50IDwtIHMxX2ZpbHRlciAlPiUgc2VsZWN0KC1lbmRlZCkgJT4lIHJpZ2h0X2pvaW4oczJfaW5pdGlhbCxieSA9J3Nlc3Npb24nKSAlPiUgbGVmdF9qb2luKHM0X2ZvbGxvd3VwLCBieSA9ICdzZXNzaW9uJywgc3VmZml4ID0gYygiX2luaXRpYWwiLCAiX2ZvbGxvd3VwIikpICU+JSBncm91cF9ieShnZXRzX3BhaWQpICU+JSBzdW1tYXJpc2UoZm9sbG93dXAgPSBuX25vbm1pc3NpbmcoZW5kZWRfZm9sbG93dXApLCBpbml0aWFsID0gbl9ub25taXNzaW5nKGVuZGVkX2luaXRpYWwpLCBuKCksIHByY19mdV9vdmVyX2luaXRpYWwgPSByb3VuZCgxMDAqZm9sbG93dXAvaW5pdGlhbCkpCmthYmxlKG1lYW5fZmluaXNoaW5nX2ZvbGxvd191cF9ieV9wYXltZW50KQoKZmVydGlsZV9rbm93bl9tYW5fa25vd24gPSBkaWFyeV9zb2NpYWwgJT4lIGdyb3VwX2J5KHNlc3Npb24sIGNyZWF0ZWQpICU+JSAKICBzdW1tYXJpc2UobiA9IG5fbm9ubWlzc2luZyhwZXJzb25fYXR0cmFjdGl2ZW5lc3Nfc2hvcnRfdGVybSkpICU+JSAKICBncm91cF9ieShzZXNzaW9uKSAlPiUgc3VtbWFyaXNlKG4gPSBzdW0obikpICMgZmVydGlsaXR5IGtub3duLCBtYW4ga25vd24KZmVydGlsZV9rbm93bl9tYW5fa25vd24kbiAlPiUgcXBsb3QoKSArIHhsaW0oMSxOQSkKCmZlcnRpbGVfa25vd25fcGVyc29uX2tub3duID0gZGlhcnlfc29jaWFsICU+JSBncm91cF9ieShzZXNzaW9uLCBjcmVhdGVkKSAlPiUgCiAgc3VtbWFyaXNlKG4gPSBuX25vbm1pc3NpbmcocGVyc29uX3NleCkpICU+JSAKICBncm91cF9ieShzZXNzaW9uKSAlPiUgc3VtbWFyaXNlKG4gPSBzdW0obikpICMgZmVydGlsaXR5IGtub3duLCBtYW4ga25vd24KCmZpbmlzaGVkX3RpbWVzcGVudCA9IHM0X3RpbWVzcGVudCAlPiUgZ3JvdXBfYnkoc2Vzc2lvbikgJT4lIHN1bW1hcmlzZShuID0gbl9ub25taXNzaW5nKGVuZGVkKSkgJT4lIGZpbHRlcihuID49IDEpICU+JSBucm93KCkKdGltZXNwZW50X2d0MyA9IHM0X3RpbWVzcGVudCAlPiUgZ3JvdXBfYnkoc2Vzc2lvbikgJT4lIHN1bW1hcmlzZShuID0gbl9ub25taXNzaW5nKGVuZGVkKSkgJT4lIGZpbHRlcihuID4gMykgJT4lIG5yb3coKQp0aW1lc3BlbnRfbWVuID0gbmV0d29yayAlPiUgZ3JvdXBfYnkoc2Vzc2lvbikgJT4lIGZpbHRlcihwZXJzb25fc2V4ID09IDIsIHBlcnNvbl9yZWxhdGlvbnNoaXBfdG9fYW5jaG9yICE9ICJiaW9sb2dpY2FsX3JlbGF0aXZlIikgJT4lIHN1bW1hcmlzZShuID0gbl9ub25taXNzaW5nKGVuZGVkKSkgJT4lIGZpbHRlcihuID4gMCkgJT4lIG5yb3coKQp0aW1lc3BlbnRfM21lbiA9IG5ldHdvcmsgJT4lIGdyb3VwX2J5KHNlc3Npb24pICU+JSBmaWx0ZXIocGVyc29uX3NleCA9PSAyLCBwZXJzb25fcmVsYXRpb25zaGlwX3RvX2FuY2hvciAhPSAiYmlvbG9naWNhbF9yZWxhdGl2ZSIpICU+JSBzdW1tYXJpc2UobiA9IG5fbm9ubWlzc2luZyhlbmRlZCkpICU+JSBmaWx0ZXIobiA+IDIpICU+JSBucm93KCkKCmZlcnRpbGVfa25vd25fbWFuX2tub3duX3BhcnRpY2lwYW50cyA9IGZlcnRpbGVfa25vd25fbWFuX2tub3duICU+JSBmaWx0ZXIobiA+IDApICU+JSBucm93KCkKZmVydGlsZV9rbm93bl9wZXJzb25fa25vd25fcGFydGljaXBhbnRzID0gZmVydGlsZV9rbm93bl9wZXJzb25fa25vd24gJT4lIGZpbHRlcihuID4gMCkgJT4lIG5yb3coKQoKZmluaXNoZWRfZm9sbG93dXAgPSBzdW0oIWlzLm5hKHM0X2ZvbGxvd3VwJGVuZGVkKSkKCiMgYWxsX3N1cnZleXMgJT4lIG11dGF0ZSgKIyAgIHNob3VsZF9iZV9kb25lID0gY3JlYXRlZF9kZW1vICsgZGF5cyg3MCkgPCB0b2RheSgpCiMgKSAlPiUgZmlsdGVyKHNob3VsZF9iZV9kb25lID09IFQpICU+JSB4dGFicyh+IGlzLm5hKGVuZGVkKSwgLikKCiMgYWxsX3N1cnZleXMgJT4lIG11dGF0ZSgKIyBzaG91bGRfYmVfZG9uZSA9IGNyZWF0ZWRfZGVtbyArIGRheXMoNzApIDwgdG9kYXkoKQojICkgJT4lIGxlZnRfam9pbihzM19kYWlseSAlPiUgZ3JvdXBfYnkoc2Vzc2lvbikgJT4lIHN1bW1hcmlzZShuID0gbl9ub25taXNzaW5nKGVuZGVkKSkpICU+JSAKIyAgZmlsdGVyKHNob3VsZF9iZV9kb25lID09IFQsIG4gPiA0MCkgJT4lIHh0YWJzKH4gaXMubmEoZW5kZWQpLCAuKQoKYWxsX3N1cnZleXMgJT4lIG11dGF0ZShzaG91bGRfYmVfZG9uZSA9IGNyZWF0ZWRfZGVtbyArIGRheXMoNzApIDwgdG9kYXkoKSkgJT4lCiBsZWZ0X2pvaW4oIHM0X3RpbWVzcGVudCAlPiUgZ3JvdXBfYnkoc2Vzc2lvbikgJT4lIHN1bW1hcmlzZShuX3RpbWVzcGVudCA9IG5fbm9ubWlzc2luZyhlbmRlZCkpLCBieSA9ICdzZXNzaW9uJykgJT4lIAogZmlsdGVyKGhldGVyb19yZWxhdGlvbnNoaXAgPT0gMCwgc2hvdWxkX2JlX2RvbmUgPT0gVCwgbl90aW1lc3BlbnQgPiAwLCAhaXMubmEobl90aW1lc3BlbnQpKSAlPiUgbnJvdygpCgphbGxfc3VydmV5cyAlPiUgbXV0YXRlKHNob3VsZF9iZV9kb25lID0gY3JlYXRlZF9kZW1vICsgZGF5cyg3MCkgPCB0b2RheSgpKSAlPiUKIGxlZnRfam9pbiggczRfdGltZXNwZW50ICU+JSBncm91cF9ieShzZXNzaW9uKSAlPiUgc3VtbWFyaXNlKG5fdGltZXNwZW50ID0gIG5fbm9ubWlzc2luZyhlbmRlZCkpLCBieSA9ICdzZXNzaW9uJykgJT4lIAogZmlsdGVyKGhldGVyb19yZWxhdGlvbnNoaXAgPT0gMCAmIHNob3VsZF9iZV9kb25lID09IFQgJiAoaXMubmEobl90aW1lc3BlbnQpIHwgbl90aW1lc3BlbnQgPT0gMCkpICU+JSBucm93KCkKYGBgCgoxLiBfX2ByIGJlZ2FuX3MxX2RlbW9gX18gc2lnbmVkIHVwIGZvciB0aGUgc3R1ZHkuCjIuIF9fYHIgZW5kZWRfczFfZGVtb2BfXyBmaW5pc2hlZCB0aGUgZGVtb2dyYXBoaWNzIChgciBzaW5nbGVzYCBzaW5nbGVzLCBgciBpbl9yZWxhdGlvbnNoaXBgIGluIHJlbGF0aW9uc2hpcCkuCjIuIF9fYHIgZW5kZWRfcHJlYF9fIGZpbmlzaGVkIHRoZSBkZW1vZ3JhcGhpYyBhbmQgcGVyc29uYWxpdHkgcXVlc3Rpb25uYWlyZXMuCjMuIF9fYHIgYXRfbGVhc3Rfb25lX2RpYXJ5X2VudHJ5YF9fIHN1Ym1pdHRlZCBhdCBsZWFzdCBvbmUgZGlhcnkgZW50cnkgKD49IDIwOiBgciBhdF9sZWFzdF8yMF9kaWFyeV9lbnRyaWVzYCwgPj0gNTAgYHIgYXRfbGVhc3RfNTBfZGlhcnlfZW50cmllc2ApLiBPbiBhdmVyYWdlIHBhcnRpY2lwYW50cyBjb21wbGV0ZWQgYHIgbWVhbl9kaWFyeV9lbnRyaWVzYCBkaWFyeSBlbnRyaWVzLgo0LiBgciBmaW5pc2hlZF90aW1lc3BlbnRgIHNpbmdsZXMgcmVwb3J0ZWQgaW5mb3JtYXRpb24gb24gbGVhc3Qgb25lIHBlcnNvbiBtZW50aW9uZWQgZHVyaW5nIHRoZSBkaWFyeSAoPjM6IGByIHRpbWVzcGVudF9ndDNgLCBhdCBsZWFzdCBvbmUgbWFuIHdobyB3YXNuJ3QgYmlvbG9naWNhbGx5IHJlbGF0ZWQ6IGByIHRpbWVzcGVudF9tZW5gLCA+Mm1lbjogYHIgdGltZXNwZW50XzNtZW5gKS4gCjUuIF9fYHIgZmluaXNoZWRfZm9sbG93dXBgX18gKGByIHJvdW5kKDEwMCpmaW5pc2hlZF9mb2xsb3d1cC9lbmRlZF9wcmUpYCUgb2YgdGhvc2Ugd2hvIGZpbmlzaGVkIHRoZSBpbnRha2Ugc3VydmV5KSBmaW5pc2hlZCB0aGUgZm9sbG93LXVwIHN1cnZleS4gRmluaXNoZXJzIGNvbXBsZXRlZCBvbiBhdmVyYWdlIGByIG1lYW5fZGlhcnlfZW50cmllc19maW5pc2hlcnNgIGRpYXJ5IGVudHJpZXMuCgoKCgojIENvbnRyYWNlcHRpb24KYGBge3J9CmxpYnJhcnkoVXBTZXRSKQpjb21tYV9zZXBhcmF0ZWRfdG9fY29sdW1ucyA8LSBmdW5jdGlvbihkZiwgY29sKSB7CiAgY29sbmFtZSA8LSBkZXBhcnNlKHN1YnN0aXR1dGUoY29sKSkKICBkZiRzcGxpdGNvbCA8LSBkZiAlPiUgcHVsbChjb2xuYW1lKQogIHNlcGFyYXRlX3Jvd3MoZGYsIHNwbGl0Y29sLCBjb252ZXJ0ID0gVFJVRSwgc2VwID0gIiwgIikgJT4lIAogICAgbXV0YXRlKHNwbGl0Y29sID0gaWZfZWxzZShpcy5uYShzcGxpdGNvbCksICJubyIsIAogICAgICAgICAgICAgICAgICAgICAgICBpZl9lbHNlKHNwbGl0Y29sID09ICIiIHwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGxpdGNvbCAlaW4lIGMoKSwgIm90aGVyIiwgYXMuY2hhcmFjdGVyKHNwbGl0Y29sKSkpKSAlPiUgCiAgICBtdXRhdGUoI3NwbGl0Y29sID0gc3RyaW5ncjo6c3RyX2MoY29sbmFtZSwgIl8iLCBzcGxpdGNvbCksIAogICAgICAgICAgIHZhbHVlID0gMSkgJT4lIAogICAgc3ByZWFkKHNwbGl0Y29sLCB2YWx1ZSwgZmlsbCA9IDApICU+JSAKICAgIHNlbGVjdCgtY29sbmFtZSkKfQpsaWJyYXJ5KFVwU2V0UikKYWxsX3N1cnZleXMgJT4lIHNlbGVjdChzZXNzaW9uLCBjb250cmFjZXB0aW9uX21ldGhvZCkgJT4lIAogIGNvbW1hX3NlcGFyYXRlZF90b19jb2x1bW5zKGNvbnRyYWNlcHRpb25fbWV0aG9kKSAlPiUgCiAgc2VsZWN0KC1zZXNzaW9uKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICB7CiAgdXBzZXQoLiwgbmNvbCguKSwgMjAsIHNob3cubnVtYmVycyA9IFRSVUUsIG9yZGVyLmJ5ID0gImZyZXEiLAogICAgICBtYWluLmJhci5jb2xvciA9ICIjNkU4NjkxIiwKICAgICAgbWF0cml4LmNvbG9yID0gIiM2RTg2OTEiLAogICAgICBzZXRzLmJhci5jb2xvciA9ICIjNTNBQzlCIikKICB9CmBgYAoKIyMgc29jaWFsIG5ldHdvcmsgCmBgYHtyfQpzdW1tYXJ5KGFzLmZhY3RvcihuZXR3b3JrJHBlcnNvbl9zZXgpKQpieV9zZXggPSBzNF90aW1lc3BlbnQgJT4lIAogICAgZ3JvdXBfYnkoc2Vzc2lvbikgJT4lIAogICAgc3VtbWFyaXNlKGZlbWFsZSA9IHN1bShwZXJzb25fc2V4ID09IDEsIG5hLnJtPVQpLCBtYWxlID0gc3VtKHBlcnNvbl9zZXggPT0gMiwgbmEucm09VCksIG49IG4oKSkgJT4lIHNlbGVjdChmZW1hbGUsIG1hbGUsbikKYGBgCgoKYGBge3J9CnRvdGFsX25ldHdvcmsgPSBucm93KG5ldHdvcmspCnBlcnNvbnM9IG5yb3cobmV0d29yayAlPiUgZmlsdGVyKHBlcnNvbl9yZW1lbWJlciA9PSAxICYgIWlzLm5hKGVuZGVkKSkpCgpgYGAKX19gciB0b3RhbF9uZXR3b3JrYF9fIG51bWJlciBvZiBwZXJzb25zIHdobyB3ZXJlIG1lbnRpb25lZCBpbiBkaWFyeQpfX2ByIHBlcnNvbnNgX18gbnVtYmVyIG9mIG5pY2tuYW1lcy9uYW1lcyB3b21lbiByZW1lbWJlcmVkLgoKCiMjIENvbXBhcmlzb24gd2l0aCBxdWFzaS1jb250cm9sIGdyb3VwCgojIyMgQ29tcGFyaXNvbnMgb24ga2V5IHZhcmlhYmxlcwoKYGBge3J9CndvbWVuIDwtIGFsbF9zdXJ2ZXlzICU+JSBmaWx0ZXIocmVhc29uc19mb3JfZXhjbHVzaW9uID09ICIiKQpkaWcxIDwtIGZ1bmN0aW9uKHgpIHsgc3ByaW50ZigiJS4xZiIsIHgpIH0KZGlnMiA8LSBmdW5jdGlvbih4KSB7IHNwcmludGYoIiUuMmYiLCB4KSB9CnBjdCA8LSBmdW5jdGlvbih4KSB7IHNwcmludGYoIiUuMGYiLCB4KjEwMCkgfQoKcmVtb3ZlX3BfdmFsdWVzIDwtIGZ1bmN0aW9uKHBsYW5uZWRfcGxvdCwgY2FsbF9wYXJ0cyA9IDM6MTApIHsKICBzdWJ0aXRsZSA8LSBhcy5saXN0KHBsYW5uZWRfcGxvdCRsYWJlbHMkc3VidGl0bGUpCiAgc3VidGl0bGVbY2FsbF9wYXJ0c10gPC0gTlVMTAogIHBsYW5uZWRfcGxvdCRsYWJlbHMkc3VidGl0bGUgPC0gYXMuY2FsbChzdWJ0aXRsZSkKICBwbGFubmVkX3Bsb3QKfQpjb21wcyA9IGRhdGFfZnJhbWUoVmFyaWFibGUgPSBjaGFyYWN0ZXIoMCksIAogICAgICAgICAgICAgICAgICAgYEhDIHVzZXIgLSBNZWFuIChTRClgID0gY2hhcmFjdGVyKDApLCAKICAgICAgICAgICAgICAgICAgIGBDeWNsaW5nIC0gTWVhbiAoU0QpYCA9IGNoYXJhY3RlcigwKSwKICAgICAgICAgICAgICAgICAgIGA5OSUgQ0lgID0gY2hhcmFjdGVyKDApLAopCgpjb21wYXJlX2J5X2dyb3VwID0gZnVuY3Rpb24odmFyLCBkYXRhLCB0eXBlID0gIm5wIiwgLi4uKSB7CiAgdmFyX3MgPC0gZW5xdW8odmFyKQogIHZhciA8LSBybGFuZzo6YXNfbmFtZSh2YXJfcykKIHNkX2hjID0gc2QoZGF0YVtkYXRhJGhvcm1vbmFsX2NvbnRyYWNlcHRpb24gPT0gMSxdW1t2YXJdXSwgbmEucm0gPSBUKQogc2RfbmMgPSBzZChkYXRhW2RhdGEkaG9ybW9uYWxfY29udHJhY2VwdGlvbiA9PSAwLF1bW3Zhcl1dLCBuYS5ybSA9IFQpCiAgZGF0YSRgSG9ybW9uYWwgY29udHJhY2VwdGlvbmAgPSBmb3JjYXRzOjpmY3RfcmVsZXZlbCggZm9yY2F0czo6ZmN0X3JlY29kZShmb3JjYXRzOjphc19mYWN0b3IoZGF0YSRob3Jtb25hbF9jb250cmFjZXB0aW9uKSwgIkN5Y2xpbmciID0gIkZBTFNFIiwgIkhDIHVzZXIiID0gIlRSVUUiKSwgIkhDIHVzZXIiKQogY29tcCA9IGFzLmZvcm11bGEocGFzdGUwKCJgIix2YXIsICJgIH4gYEhvcm1vbmFsIGNvbnRyYWNlcHRpb25gIikpCiB0dCA9IHQudGVzdChjb21wLCBkYXRhID0gZGF0YSwgY29uZi5sZXZlbCA9IDAuOTkpCgogc3VtbWFyeSA9IGRhdGFfZnJhbWUoVmFyaWFibGUgPSB2YXIsIAogICAgICAgICAgICAgICAgICAgYEhDIHVzZXIgLSBNZWFuIChTRClgID0gcGFzdGUwKGRpZzEodHQkZXN0aW1hdGVbMV0pLCIgKCIsIGRpZzEoc2RfaGMpLCIpIiksIAogICAgICAgICAgICAgICAgICAgYEN5Y2xpbmcgLSBNZWFuIChTRClgID0gcGFzdGUwKGRpZzEodHQkZXN0aW1hdGVbMl0pLCAiICgiLCBkaWcxKHNkX25jKSwgIikiKSwKICAgICAgICAgICAgICAgICAgIGA5OSUgQ0lgID0gcGFzdGUoZGlnMSh0dCRjb25mLmludCksIGNvbGxhcHNlID0gIjsiKQogKQogcm93bmFtZXMoc3VtbWFyeSkgPSBOVUxMCiBjb21wcyA8PC0gYmluZF9yb3dzKGNvbXBzLCBzdW1tYXJ5KQogZGF0YVtbdmFyXV0gPC0gZGF0YVtbdmFyXV0gJT4lIHphcF9hdHRyaWJ1dGVzKCkKIHBsYW5uZWRfcGxvdCA8LSBnZ3N0YXRzcGxvdDo6Z2diZXR3ZWVuc3RhdHMoCiAgZGF0YSA9IGRhdGEsCiAgeCA9IGBIb3Jtb25hbCBjb250cmFjZXB0aW9uYCwKICB5ID0gISEgdmFyX3MsCiAgbWVzc2FnZXMgPSBGQUxTRSwKICBjb25mLmxldmVsID0gMC45OSwKICB0eXBlID0gdHlwZSwgLi4uLCAKICBnZ3RoZW1lID0gdGhlbWVfY293cGxvdChmb250X3NpemUgPSAxOCkKICApICsgIyBmdXJ0aGVyIG1vZGlmaWNhdGlvbiBvdXRzaWRlIG9mIGdnc3RhdHNwbG90CiAgc2NhbGVfY29sb3JfbWFudWFsKCIiLCB2YWx1ZXMgPSBjKCJDeWNsaW5nIiA9ICJyZWQiLCAiSEMgdXNlciIgPSAiYmxhY2siKSwgZ3VpZGUgPSBGKSArCiAgIyBzY2FsZV94X2Rpc2NyZXRlKCJIb3Jtb25hbCBjb250cmFjZXB0aW9uIiwgbGFiZWxzID0gYygiMSIgPSAiSEMgdXNlciIsICIyIiA9ICJDeWNsaW5nIikpICsKICBzY2FsZV9maWxsX21hbnVhbCgiIiwgdmFsdWVzID0gYygiQ3ljbGluZyIgPSAicmVkIiwgIkhDIHVzZXIiID0gImJsYWNrIiksIGd1aWRlID0gRikKIHJlbW92ZV9wX3ZhbHVlcyhwbGFubmVkX3Bsb3QpCn0KbGlicmFyeShnZ3N0YXRzcGxvdCkKbGlicmFyeShjb3dwbG90KQpgYGAKCmBgYHtyIGZpZy5jYXA9IkNvbXBhcmlzb24gb2YgdGhlIGhvcm1vbmFsIGNvbnRyYWNlcHRpb24gdXNlcnMgKG91ciBxdWFzaS1jb250cm9sIGdyb3VwKSB3aXRoIHdvbWVuIHdobyBhcmUgcmVndWxhcmx5IGN5Y2xpbmcuIFRoZSBwbG90IHNob3dzIHRoZSBkaXN0cmlidXRpb24gb2YgdmFsdWVzIGluIGVhY2ggZ3JvdXAgYW5kIHRoZSByZXN1bHRzIG9mIGEgTWFubi1XaGl0bmV5IFUgdGVzdC4ifQp3b21lbiRgQWdlICh5ZWFycylgIDwtIHdvbWVuJGFnZQpjb21wYXJlX2J5X2dyb3VwKGBBZ2UgKHllYXJzKWAsIHdvbWVuKQpgYGAKCgoKYGBge3IgZmlnLmNhcD0iQ29tcGFyaXNvbiBvZiB0aGUgaG9ybW9uYWwgY29udHJhY2VwdGlvbiB1c2VycyAob3VyIHF1YXNpLWNvbnRyb2wgZ3JvdXApIHdpdGggd29tZW4gd2hvIGFyZSByZWd1bGFybHkgY3ljbGluZy4gVGhlIHBsb3Qgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiBjYXRlZ29yaWVzIGluIGVhY2ggZ3JvdXAgYW5kIHRoZSByZXN1bHRzIG9mIGEgQ2hpLVNxdWFyZSB0ZXN0IGZvciBlcXVhbCBkaXN0cmlidXRpb24uIn0KeyBnZ2JhcnN0YXRzKHdvbWVuICU+JSBtdXRhdGUocmVsYXRpb25zaGlwX3N0YXR1cz1hc19mYWN0b3IocmVsYXRpb25zaGlwX3N0YXR1cykpLCAKICAgICAgICAgICByZWxhdGlvbnNoaXBfc3RhdHVzLAogICAgICAgICAgIGhvcm1vbmFsX2NvbnRyYWNlcHRpb24sCiAgICAgICAgICAgbWVzc2FnZXMgPSBGQUxTRSwKICBjb25mLmxldmVsID0gMC45OSwKICBiZi5tZXNzYWdlID0gRiwKICBnZ3RoZW1lID0gdGhlbWVfY293cGxvdChmb250X3NpemUgPSAxOCkKICApICsgIyBmdXJ0aGVyIG1vZGlmaWNhdGlvbiBvdXRzaWRlIG9mIGdnc3RhdHNwbG90CiAgc2NhbGVfeF9kaXNjcmV0ZSgiSG9ybW9uYWwgY29udHJhY2VwdGlvbiIsIGxhYmVscyA9IGMoIlRSVUUiID0gIkhDIHVzZXIiLCAiRkFMU0UiID0gIkN5Y2xpbmciKSkKfSAlPiUgCiAgcmVtb3ZlX3BfdmFsdWVzKGNhbGxfcGFydHMgPSAzOjEyKQpgYGAKCgoKYGBge3IgZmlnLmNhcD0iQ29tcGFyaXNvbiBvZiB0aGUgaG9ybW9uYWwgY29udHJhY2VwdGlvbiB1c2VycyAob3VyIHF1YXNpLWNvbnRyb2wgZ3JvdXApIHdpdGggd29tZW4gd2hvIGFyZSByZWd1bGFybHkgY3ljbGluZy4gVGhlIHBsb3Qgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiB2YWx1ZXMgaW4gZWFjaCBncm91cCBhbmQgdGhlIHJlc3VsdHMgb2YgYSBNYW5uLVdoaXRuZXkgVSB0ZXN0LiJ9CndvbWVuJGBBZ2UgYXQgZmlyc3Qgc2V4ICh5ZWFycylgIDwtIHdvbWVuJGZpcnN0X3RpbWUKY29tcGFyZV9ieV9ncm91cChgQWdlIGF0IGZpcnN0IHNleCAoeWVhcnMpYCwgd29tZW4pCmBgYAoKCgpgYGB7ciBmaWcuY2FwPSJDb21wYXJpc29uIG9mIHRoZSBob3Jtb25hbCBjb250cmFjZXB0aW9uIHVzZXJzIChvdXIgcXVhc2ktY29udHJvbCBncm91cCkgd2l0aCB3b21lbiB3aG8gYXJlIHJlZ3VsYXJseSBjeWNsaW5nLiBUaGUgcGxvdCBzaG93cyB0aGUgZGlzdHJpYnV0aW9uIG9mIHZhbHVlcyBpbiBlYWNoIGdyb3VwIGFuZCB0aGUgcmVzdWx0cyBvZiBhIE1hbm4tV2hpdG5leSBVIHRlc3QuIn0Kd29tZW4kYEFnZSBhdCBtZW5hcmNoZSAoeWVhcnMpYCA8LSB3b21lbiRtZW5hcmNoZQpjb21wYXJlX2J5X2dyb3VwKGBBZ2UgYXQgbWVuYXJjaGUgKHllYXJzKWAsIHdvbWVuKQpgYGAKCgoKYGBge3IgZmlnLmNhcD0iQ29tcGFyaXNvbiBvZiB0aGUgaG9ybW9uYWwgY29udHJhY2VwdGlvbiB1c2VycyAob3VyIHF1YXNpLWNvbnRyb2wgZ3JvdXApIHdpdGggd29tZW4gd2hvIGFyZSByZWd1bGFybHkgY3ljbGluZy4gVGhlIHBsb3Qgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiB2YWx1ZXMgaW4gZWFjaCBncm91cCBhbmQgdGhlIHJlc3VsdHMgb2YgYSBNYW5uLVdoaXRuZXkgVSB0ZXN0LiJ9CndvbWVuJGBSZWxhdGlvbnNoaXAgZHVyYXRpb24gKHllYXJzKWAgPC0gd29tZW4kcmVsYXRpb25zaGlwX2R1cmF0aW9uCmNvbXBhcmVfYnlfZ3JvdXAoYFJlbGF0aW9uc2hpcCBkdXJhdGlvbiAoeWVhcnMpYCwgd29tZW4pICsgc2NhbGVfeV9zcXJ0KGJyZWFrcyA9IGMoMSw1LCAxMCwgMjAsIDMwKSkKYGBgCgoKCmBgYHtyIGZpZy5jYXA9IkNvbXBhcmlzb24gb2YgdGhlIGhvcm1vbmFsIGNvbnRyYWNlcHRpb24gdXNlcnMgKG91ciBxdWFzaS1jb250cm9sIGdyb3VwKSB3aXRoIHdvbWVuIHdobyBhcmUgcmVndWxhcmx5IGN5Y2xpbmcuIFRoZSBwbG90IHNob3dzIHRoZSBkaXN0cmlidXRpb24gb2YgdmFsdWVzIGluIGVhY2ggZ3JvdXAgYW5kIHRoZSByZXN1bHRzIG9mIGEgTWFubi1XaGl0bmV5IFUgdGVzdC4ifQp3b21lbiRgQXZnLiBjeWNsZSBsZW5ndGggKGRheXMpYCA8LSB3b21lbiRtZW5zdHJ1YXRpb25fbGVuZ3RoCmNvbXBhcmVfYnlfZ3JvdXAoYEF2Zy4gY3ljbGUgbGVuZ3RoIChkYXlzKWAsIHdvbWVuKQpgYGAKCgoKYGBge3IgZmlnLmNhcD0iQ29tcGFyaXNvbiBvZiB0aGUgaG9ybW9uYWwgY29udHJhY2VwdGlvbiB1c2VycyAob3VyIHF1YXNpLWNvbnRyb2wgZ3JvdXApIHdpdGggd29tZW4gd2hvIGFyZSByZWd1bGFybHkgY3ljbGluZy4gVGhlIHBsb3Qgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiB2YWx1ZXMgaW4gZWFjaCBncm91cCBhbmQgdGhlIHJlc3VsdHMgb2YgYSBNYW5uLVdoaXRuZXkgVSB0ZXN0LiJ9CndvbWVuJGBDeWNsZSByZWd1bGFyaXR5YCA8LSB3b21lbiRtZW5zdHJ1YXRpb25fcmVndWxhcml0eQpjb21wYXJlX2J5X2dyb3VwKGBDeWNsZSByZWd1bGFyaXR5YCwgd29tZW4pICsgCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbGFiZWxzID0gYygiMSIgPSAibm8gZmx1Y3R1YXRpb24iLAogICAgICAgICAgICAgICAiMiIgPSAiMS0yIGRheXMiLAogICAgICAgICAgICAgICAiMyIgPSAiMy01IGRheXMiLAogICAgICAgICAgICAgICAiNCIgPSAiPjUgZGF5cyIpKQpgYGAKCgoKYGBge3IgZmlnLmNhcD0iQ29tcGFyaXNvbiBvZiB0aGUgaG9ybW9uYWwgY29udHJhY2VwdGlvbiB1c2VycyAob3VyIHF1YXNpLWNvbnRyb2wgZ3JvdXApIHdpdGggd29tZW4gd2hvIGFyZSByZWd1bGFybHkgY3ljbGluZy4gVGhlIHBsb3Qgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiB2YWx1ZXMgaW4gZWFjaCBncm91cCBhbmQgdGhlIHJlc3VsdHMgb2YgWXVlbidzIHRlc3QgZm9yIHRyaW1tZWQgbWVhbnMgKDEwJSB0cmltbWVkKS4ifQp3b21lbiRgTm8uIGxpZmV0aW1lIHNleHVhbCBwYXJ0bmVyc2AgPC0gd29tZW4kbnVtYmVyX3NleHVhbF9wYXJ0bmVyCmNvbXBhcmVfYnlfZ3JvdXAoYE5vLiBsaWZldGltZSBzZXh1YWwgcGFydG5lcnNgLCB3b21lbiwgdHlwZSA9ICJyIikgJT4lIAogIHJlbW92ZV9wX3ZhbHVlcyhjYWxsX3BhcnRzID0gMzo0KSArIAogIHNjYWxlX3lfc3FydChicmVha3MgPSBjKDEsNSwgMTAsIDIwLCA1MCwgMTAwKSkKYGBgCgoKCmBgYHtyIGZpZy5jYXA9IkNvbXBhcmlzb24gb2YgdGhlIGhvcm1vbmFsIGNvbnRyYWNlcHRpb24gdXNlcnMgKG91ciBxdWFzaS1jb250cm9sIGdyb3VwKSB3aXRoIHdvbWVuIHdobyBhcmUgcmVndWxhcmx5IGN5Y2xpbmcuIFRoZSBwbG90IHNob3dzIHRoZSBkaXN0cmlidXRpb24gb2YgdmFsdWVzIGluIGVhY2ggZ3JvdXAgYW5kIHRoZSByZXN1bHRzIG9mIGEgTWFubi1XaGl0bmV5IFUgdGVzdC4ifQp3b21lbiRgQkZJIEV4dHJhdmVyc2lvbmAgPC0gd29tZW4kYmZpX2V4dHJhCmNvbXBhcmVfYnlfZ3JvdXAoYEJGSSBFeHRyYXZlcnNpb25gLCB3b21lbikKYGBgCgoKCmBgYHtyIGZpZy5jYXA9IkNvbXBhcmlzb24gb2YgdGhlIGhvcm1vbmFsIGNvbnRyYWNlcHRpb24gdXNlcnMgKG91ciBxdWFzaS1jb250cm9sIGdyb3VwKSB3aXRoIHdvbWVuIHdobyBhcmUgcmVndWxhcmx5IGN5Y2xpbmcuIFRoZSBwbG90IHNob3dzIHRoZSBkaXN0cmlidXRpb24gb2YgdmFsdWVzIGluIGVhY2ggZ3JvdXAgYW5kIHRoZSByZXN1bHRzIG9mIGEgTWFubi1XaGl0bmV5IFUgdGVzdC4ifQp3b21lbiRgQkZJIEFncmVlYWJsZW5lc3NgIDwtIHdvbWVuJGJmaV9hZ3JlZQpjb21wYXJlX2J5X2dyb3VwKGBCRkkgQWdyZWVhYmxlbmVzc2AsIHdvbWVuKQpgYGAKCgoKYGBge3IgZmlnLmNhcD0iQ29tcGFyaXNvbiBvZiB0aGUgaG9ybW9uYWwgY29udHJhY2VwdGlvbiB1c2VycyAob3VyIHF1YXNpLWNvbnRyb2wgZ3JvdXApIHdpdGggd29tZW4gd2hvIGFyZSByZWd1bGFybHkgY3ljbGluZy4gVGhlIHBsb3Qgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiB2YWx1ZXMgaW4gZWFjaCBncm91cCBhbmQgdGhlIHJlc3VsdHMgb2YgYSBNYW5uLVdoaXRuZXkgVSB0ZXN0LiJ9CndvbWVuJGBCRkkgTmV1cm90aWNpc21gIDwtIHdvbWVuJGJmaV9uZXVybwpjb21wYXJlX2J5X2dyb3VwKGBCRkkgTmV1cm90aWNpc21gLCB3b21lbikKYGBgCgoKCgpgYGB7ciBmaWcuY2FwPSJDb21wYXJpc29uIG9mIHRoZSBob3Jtb25hbCBjb250cmFjZXB0aW9uIHVzZXJzIChvdXIgcXVhc2ktY29udHJvbCBncm91cCkgd2l0aCB3b21lbiB3aG8gYXJlIHJlZ3VsYXJseSBjeWNsaW5nLiBUaGUgcGxvdCBzaG93cyB0aGUgZGlzdHJpYnV0aW9uIG9mIHZhbHVlcyBpbiBlYWNoIGdyb3VwIGFuZCB0aGUgcmVzdWx0cyBvZiBhIE1hbm4tV2hpdG5leSBVIHRlc3QuIn0Kd29tZW4kYEJGSSBDb25zY2llbnRpb3VzbmVzc2AgPC0gd29tZW4kYmZpX2NvbnNjCmNvbXBhcmVfYnlfZ3JvdXAoYEJGSSBDb25zY2llbnRpb3VzbmVzc2AsIHdvbWVuKQpgYGAKCgoKYGBge3IgZmlnLmNhcD0iQ29tcGFyaXNvbiBvZiB0aGUgaG9ybW9uYWwgY29udHJhY2VwdGlvbiB1c2VycyAob3VyIHF1YXNpLWNvbnRyb2wgZ3JvdXApIHdpdGggd29tZW4gd2hvIGFyZSByZWd1bGFybHkgY3ljbGluZy4gVGhlIHBsb3Qgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiB2YWx1ZXMgaW4gZWFjaCBncm91cCBhbmQgdGhlIHJlc3VsdHMgb2YgYSBNYW5uLVdoaXRuZXkgVSB0ZXN0LiJ9CndvbWVuJGBCRkkgT3Blbm5lc3NgIDwtIHdvbWVuJGJmaV9vcGVuCmNvbXBhcmVfYnlfZ3JvdXAoYEJGSSBPcGVubmVzc2AsIHdvbWVuKQpgYGAKCgoKYGBge3IgZmlnLmNhcD0iQ29tcGFyaXNvbiBvZiB0aGUgaG9ybW9uYWwgY29udHJhY2VwdGlvbiB1c2VycyAob3VyIHF1YXNpLWNvbnRyb2wgZ3JvdXApIHdpdGggd29tZW4gd2hvIGFyZSByZWd1bGFybHkgY3ljbGluZy4gVGhlIHBsb3Qgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiB2YWx1ZXMgaW4gZWFjaCBncm91cCBhbmQgdGhlIHJlc3VsdHMgb2YgYSBNYW5uLVdoaXRuZXkgVSB0ZXN0LiJ9CndvbWVuJGBTb2Npb3NleHVhbGl0eSBJbnZlbnRvcnkgUmV2aXNlZGAgPC0gd29tZW4kc29pX3IKY29tcGFyZV9ieV9ncm91cChgU29jaW9zZXh1YWxpdHkgSW52ZW50b3J5IFJldmlzZWRgLCB3b21lbikKYGBgCgoKCmBgYHtyIGZpZy5jYXA9IkNvbXBhcmlzb24gb2YgdGhlIGhvcm1vbmFsIGNvbnRyYWNlcHRpb24gdXNlcnMgKG91ciBxdWFzaS1jb250cm9sIGdyb3VwKSB3aXRoIHdvbWVuIHdobyBhcmUgcmVndWxhcmx5IGN5Y2xpbmcuIFRoZSBwbG90IHNob3dzIHRoZSBkaXN0cmlidXRpb24gb2YgdmFsdWVzIGluIGVhY2ggZ3JvdXAgYW5kIHRoZSByZXN1bHRzIG9mIGEgTWFubi1XaGl0bmV5IFUgdGVzdC4ifQp3b21lbiRgUmVsYXRpb25zaGlwIHNhdGlzZmFjdGlvbmAgPC0gd29tZW4kcmVsYXRpb25zaGlwX3NhdGlzZmFjdGlvbgpjb21wYXJlX2J5X2dyb3VwKGBSZWxhdGlvbnNoaXAgc2F0aXNmYWN0aW9uYCwgd29tZW4pCmBgYAoKCgpgYGB7ciBmaWcuY2FwPSJDb21wYXJpc29uIG9mIHRoZSBob3Jtb25hbCBjb250cmFjZXB0aW9uIHVzZXJzIChvdXIgcXVhc2ktY29udHJvbCBncm91cCkgd2l0aCB3b21lbiB3aG8gYXJlIHJlZ3VsYXJseSBjeWNsaW5nLiBUaGUgcGxvdCBzaG93cyB0aGUgZGlzdHJpYnV0aW9uIG9mIHZhbHVlcyBpbiBlYWNoIGdyb3VwIGFuZCB0aGUgcmVzdWx0cyBvZiBhIE1hbm4tV2hpdG5leSBVIHRlc3QuIn0KY29tcGFyZV9ieV9ncm91cChyZWxpZ2lvc2l0eSwgd29tZW4pCmBgYAoKCgpgYGB7ciBmaWcuY2FwPSJDb21wYXJpc29uIG9mIHRoZSBob3Jtb25hbCBjb250cmFjZXB0aW9uIHVzZXJzIChvdXIgcXVhc2ktY29udHJvbCBncm91cCkgd2l0aCB3b21lbiB3aG8gYXJlIHJlZ3VsYXJseSBjeWNsaW5nLiBUaGUgcGxvdCBzaG93cyB0aGUgZGlzdHJpYnV0aW9uIG9mIGNhdGVnb3JpZXMgaW4gZWFjaCBncm91cCBhbmQgdGhlIHJlc3VsdHMgb2YgYSBDaGktU3F1YXJlIHRlc3QgZm9yIGVxdWFsIGRpc3RyaWJ1dGlvbi4ifQp7IGdnYmFyc3RhdHMod29tZW4sIAogICAgICAgICAgIG5ldF9pbmNvbWUsCiAgICAgICAgICAgaG9ybW9uYWxfY29udHJhY2VwdGlvbiwKICAgICAgICAgICBtZXNzYWdlcyA9IEZBTFNFLAogIGJmLm1lc3NhZ2UgPSBGLAogIGNvbmYubGV2ZWwgPSAwLjk5LAogIGdndGhlbWUgPSB0aGVtZV9jb3dwbG90KGZvbnRfc2l6ZSA9IDE4KQogICkgKyAjIGZ1cnRoZXIgbW9kaWZpY2F0aW9uIG91dHNpZGUgb2YgZ2dzdGF0c3Bsb3QKICBzY2FsZV94X2Rpc2NyZXRlKCJIb3Jtb25hbCBjb250cmFjZXB0aW9uIiwgbGFiZWxzID0gYygiVFJVRSIgPSAiSEMgdXNlciIsICJGQUxTRSIgPSAiQ3ljbGluZyIpKX0gJT4lIAogIHJlbW92ZV9wX3ZhbHVlcyhjYWxsX3BhcnRzID0gMzoxMikKYGBgCgoKCmBgYHtyIGZpZy5jYXA9IkNvbXBhcmlzb24gb2YgdGhlIGhvcm1vbmFsIGNvbnRyYWNlcHRpb24gdXNlcnMgKG91ciBxdWFzaS1jb250cm9sIGdyb3VwKSB3aXRoIHdvbWVuIHdobyBhcmUgcmVndWxhcmx5IGN5Y2xpbmcuIFRoZSBwbG90IHNob3dzIHRoZSBkaXN0cmlidXRpb24gb2YgY2F0ZWdvcmllcyBpbiBlYWNoIGdyb3VwIGFuZCB0aGUgcmVzdWx0cyBvZiBhIENoaS1TcXVhcmUgdGVzdCBmb3IgZXF1YWwgZGlzdHJpYnV0aW9uLiJ9CnsgZ2diYXJzdGF0cyh3b21lbiwgCiAgICAgICAgICAgbGl2aW5nX3NpdHVhdGlvbiwKICAgICAgICAgICBob3Jtb25hbF9jb250cmFjZXB0aW9uLAogICAgICAgICAgIG1lc3NhZ2VzID0gRkFMU0UsCiAgY29uZi5sZXZlbCA9IDAuOTksCiAgYmYubWVzc2FnZSA9IEYsCiAgZ2d0aGVtZSA9IHRoZW1lX2Nvd3Bsb3QoZm9udF9zaXplID0gMTgpCiAgKSArICMgZnVydGhlciBtb2RpZmljYXRpb24gb3V0c2lkZSBvZiBnZ3N0YXRzcGxvdAogIHNjYWxlX3hfZGlzY3JldGUoIkhvcm1vbmFsIGNvbnRyYWNlcHRpb24iLCBsYWJlbHMgPSBjKCJUUlVFIiA9ICJIQyB1c2VyIiwgIkZBTFNFIiA9ICJDeWNsaW5nIikpIH0gJT4lIAogIHJlbW92ZV9wX3ZhbHVlcyhjYWxsX3BhcnRzID0gMzoxMikKYGBgCgoKCiMjIFN1bW1hcnkgCmBgYHtyfQpjb21wcyAlPiUgCiAgICBrYWJsZShjYXB0aW9uID0gIk1lYW5zLCBTRHMsIGFuZCBkaWZmZXJlbmNlcyBiZXR3ZWVuIGJvdGggZ3JvdXBzIGZvciBhbGwgY29udGludW91cyB2YXJpYWJsZXMiKSAlPiUKICBmb290bm90ZSgiOTklIENJIGludGVydmFsIG9mIHRoZSBkaWZmZXJlbmNlLiIpICU+JQogIGthYmxlX3N0eWxpbmcoKQpgYGAKCgoKIyMgTXVsdGlwbGUgcmVncmVzc2lvbgoKYGBge3IgZmlnLmNhcD0iQSBwcm9iaXQgcmVncmVzc2lvbiBwcmVkaWN0aW5nIGhvcm1vbmFsIGNvbnRyYWNlcHRpb24gd2l0aCBtYW55IHByZWRpY3RvcnMgYXQgb25jZS4iLCBmaWcuaGVpZ2h0PTEwLGZpZy53aWR0aD05fQphbHRvZ2V0aGVyID0gZ2xtKGhvcm1vbmFsX2NvbnRyYWNlcHRpb24gfiBhZ2UgICsgbGl2aW5nX3NpdHVhdGlvbiArIHJlbGlnaW9zaXR5ICsgYmZpX2V4dHJhICsgYmZpX25ldXJvICsgYmZpX2FncmVlICsgYmZpX2NvbnNjICsgYmZpX29wZW4gKyBzb2lfciArIGZpcnN0X3RpbWUgKyByZWxhdGlvbnNoaXBfc3RhdHVzICsgbG9nMXAobnVtYmVyX3NleHVhbF9wYXJ0bmVyKSArIGhhc19jaGlsZHJlbiArIG5ldF9pbmNvbWUsIGRhdGEgPSB3b21lbiAlPiUgbXV0YXRlKHJlbGF0aW9uc2hpcF9zdGF0dXM9YXNfZmFjdG9yKHJlbGF0aW9uc2hpcF9zdGF0dXMpKSwgZmFtaWx5ID0gYmlub21pYWwoInByb2JpdCIpKQpnZ2NvZWZzdGF0cyhhbHRvZ2V0aGVyLCBwYWNrYWdlID0gImdnc2NpIiwgcGFsZXR0ZSA9ICJkZWZhdWx0X2lndiIsIHAuYWRqdXN0Lm1ldGhvZCA9ICJCSCIsCiAgICAgICAgICAgIGNvbnYubGV2ZWwgPSAwLjk5LCBzdGF0cy5sYWJlbHMgPSBGQUxTRSwgcG9pbnQuY29sb3IgPSAiYmxhY2siKSArCiAgZ2dyZXBlbDo6Z2VvbV90ZXh0X3JlcGVsKGFlcyhsYWJlbCA9IHNwcmludGYoIiUuMmYgWyUuMmY7JS4yZl0iLCBlc3RpbWF0ZSwgY29uZi5sb3csIGNvbmYuaGlnaCkpLCBzaXplID0gMy4zKQpgYGAKCg==