Looking at the data

We plot the data and can see that there is no obvious large difference between the debt levels or scenarios.

Per debt level

likert.data <- d.both_completed %>%
  select(high_debt_version, quality_pre_task)

likert.data$quality_pre_task <- revalue(likert.data$quality_pre_task, c(
      "-3"="Very Bad",
      "-2"="Bad",
      "-1"="Somewhat Bad",
      "0"="Neutral",
      "1"="Somewhat Good",
      "2"="Good",
      "3"="Very Good"
    ))

likert.data$high_debt_version <- revalue(likert.data$high_debt_version, c(
      "true"="High Debt",
      "false"="Low Debt"
    ))

ggplot(likert.data, aes(x=quality_pre_task)) +
  geom_bar(fill= "Light Blue") +
  facet_grid(rows = vars(high_debt_version)) +
    scale_y_continuous(limits = NULL, breaks = c(2,4,6,8), labels = c("2","4","6","8")) +
  theme(axis.title.x=element_blank(),
        axis.title.y=element_blank())

Per scenario

likert.data <- d.both_completed %>%
  select(scenario, quality_pre_task)

likert.data$quality_pre_task <- revalue(likert.data$quality_pre_task, c(
      "-3"="Very Bad",
      "-2"="Bad",
      "-1"="Somewhat Bad",
      "0"="Neutral",
      "1"="Somewhat Good",
      "2"="Good",
      "3"="Very Good"
    ))

ggplot(likert.data, aes(x=quality_pre_task)) +
  geom_bar(fill= "Light Blue") +
  facet_grid(rows = vars(scenario)) +
    scale_y_continuous(limits = NULL, breaks = c(2,4,6,8), labels = c("2","4","6","8")) +
  theme(axis.title.x=element_blank(),
        axis.title.y=element_blank())

Initial model

As the data is collected from a likert scale we will use a cumulative family, indicating that each level on the scale is an incremental step. This model is also able to fit the data well.

We include high_debt_verison as a predictor in our model as this variable represent the very effect we want to measure. We also include a varying intercept for each individual to prevent the model from learning too much from single participants with extreme measurements.

Selecting priors

We iterate over the model until we have sane priors.

Base model with priors

scenario_quality.with <- extendable_model(
  base_name = "scenario_quality",
  base_formula = "quality_pre_task ~ 1 + high_debt_version + (1 | session)",
  base_priors = c(
    prior(normal(0, 1), class = "b"),
    prior(normal(0, 2), class = "Intercept"),
    prior(exponential(1), class = "sd")
  ),
  family = cumulative(),
  data = d.both_completed,
)

Default priors

prior_summary(scenario_quality.with(only_priors= TRUE))

Selected priors

prior_summary(scenario_quality.with(sample_prior = "only"))

Prior predictive check

pp_check(scenario_quality.with(sample_prior = "only"), nsamples = 200, type = "bars")

Beta parameter influence

We choose a beta parameter priors allowing for the beta parameter to account for 100% of the effect but that is skeptical to such strong effects from the beta parameter.

sim.size <- 1000
sim.intercept <- rnorm(sim.size, 0, 2)
sim.beta <- rnorm(sim.size, 0, 1)
sim.beta.diff <- (plogis(sim.intercept + sim.beta) / plogis(sim.intercept) * 100) - 100

data.frame(x = sim.beta.diff) %>%
  ggplot(aes(x)) +
  geom_density() +
  xlim(-150, 150) +
  labs(
    title = "Beta parameter prior influence",
    x = "Estimate with beta as % of estimate without beta",
    y = "Density"
  )

Model fit

We check the posterior distribution and can see that the model seems to have been able to fit the data well. Sampling seems to also have worked well as Rhat values are close to 1 and the sampling plots look nice.

Posterior predictive check

pp_check(scenario_quality.with(), nsamples = 200, type = "bars")
## Warning: Argument 'nsamples' is deprecated. Please use argument 'ndraws'
## instead.

Summary

summary(scenario_quality.with())
##  Family: cumulative 
##   Links: mu = logit; disc = identity 
## Formula: quality_pre_task ~ 1 + high_debt_version + (1 | session) 
##    Data: as.data.frame(data) (Number of observations: 44) 
##   Draws: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
##          total post-warmup draws = 4000
## 
## Group-Level Effects: 
## ~session (Number of levels: 22) 
##               Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept)     0.36      0.29     0.01     1.08 1.00     2157     2375
## 
## Population-Level Effects: 
##                        Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
## Intercept[1]              -1.90      0.55    -3.03    -0.87 1.00     4722
## Intercept[2]              -0.56      0.42    -1.40     0.25 1.00     6267
## Intercept[3]               0.22      0.42    -0.59     1.03 1.00     5807
## Intercept[4]               0.62      0.43    -0.24     1.48 1.00     5701
## Intercept[5]               1.91      0.49     0.96     2.89 1.00     5077
## Intercept[6]               3.94      0.72     2.62     5.50 1.00     5851
## high_debt_versionfalse     1.38      0.51     0.38     2.40 1.00     6286
##                        Tail_ESS
## Intercept[1]               2746
## Intercept[2]               3602
## Intercept[3]               3569
## Intercept[4]               3310
## Intercept[5]               2753
## Intercept[6]               3086
## high_debt_versionfalse     2942
## 
## Family Specific Parameters: 
##      Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## disc     1.00      0.00     1.00     1.00   NA       NA       NA
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).

Sampling plots

plot(scenario_quality.with(), ask = FALSE)

Model predictor extenstions

# default prior for monotonic predictor
edlvl_prior <- prior(dirichlet(2), class = "simo", coef = "moeducation_level1")

We use loo to check some possible extensions on the model.

One variable

loo_result <- loo(
  # Benchmark model(s)
  scenario_quality.with(),
  
  # New model(s)
  scenario_quality.with("work_domain"),
  scenario_quality.with("work_experience_programming.s"),
  scenario_quality.with("work_experience_java.s"),
  scenario_quality.with("education_field"),
  scenario_quality.with("mo(education_level)", edlvl_prior),
  scenario_quality.with("workplace_peer_review"),
  scenario_quality.with("workplace_td_tracking"),
  scenario_quality.with("workplace_pair_programming"),
  scenario_quality.with("workplace_coding_standards"),
  scenario_quality.with("scenario"),
  scenario_quality.with("group")
)

Comparison

loo_result[2]
## $diffs
##                                                           elpd_diff se_diff
## scenario_quality.with("workplace_coding_standards")        0.0       0.0   
## scenario_quality.with("work_experience_programming.s")    -0.1       1.7   
## scenario_quality.with("workplace_peer_review")            -0.4       1.2   
## scenario_quality.with("work_experience_java.s")           -0.5       1.8   
## scenario_quality.with()                                   -1.1       1.3   
## scenario_quality.with("mo(education_level)", edlvl_prior) -1.1       1.3   
## scenario_quality.with("workplace_pair_programming")       -1.6       1.4   
## scenario_quality.with("scenario")                         -1.8       1.4   
## scenario_quality.with("workplace_td_tracking")            -1.8       1.4   
## scenario_quality.with("education_field")                  -2.1       1.5   
## scenario_quality.with("group")                            -2.5       1.3   
## scenario_quality.with("work_domain")                      -3.1       1.7

Diagnostics

loo_result[1]
## $loos
## $loos$`scenario_quality.with()`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -81.3 4.1
## p_loo         8.4 0.9
## looic       162.7 8.1
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1548      
##  (0.5, 0.7]   (ok)        1     2.3%   2108      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("work_domain")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -83.3 4.4
## p_loo        13.3 1.7
## looic       166.6 8.8
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1014      
##  (0.5, 0.7]   (ok)        1     2.3%   807       
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("work_experience_programming.s")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.3 4.2
## p_loo         9.2 0.9
## looic       160.7 8.4
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("work_experience_java.s")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.8 4.2
## p_loo         9.2 0.9
## looic       161.5 8.4
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("education_field")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -82.3 4.1
## p_loo        10.0 1.1
## looic       164.6 8.2
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1821      
##  (0.5, 0.7]   (ok)        1     2.3%   4107      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("mo(education_level)", edlvl_prior)`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -81.4 4.2
## p_loo         9.3 1.0
## looic       162.7 8.4
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1403      
##  (0.5, 0.7]   (ok)        1     2.3%   3344      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("workplace_peer_review")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.7 4.3
## p_loo         8.9 0.9
## looic       161.3 8.6
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("workplace_td_tracking")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -82.0 4.1
## p_loo         9.5 1.0
## looic       164.1 8.1
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1345      
##  (0.5, 0.7]   (ok)        1     2.3%   1546      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("workplace_pair_programming")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -81.8 4.2
## p_loo         9.4 1.0
## looic       163.6 8.4
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     42    95.5%   1677      
##  (0.5, 0.7]   (ok)        2     4.5%   1812      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("workplace_coding_standards")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.2 4.2
## p_loo         8.7 0.9
## looic       160.5 8.4
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("scenario")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -82.0 4.0
## p_loo         9.3 0.9
## looic       164.1 8.1
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("group")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -82.7 4.4
## p_loo        11.0 1.2
## looic       165.4 8.8
## ------
## Monte Carlo SE of elpd_loo is NA.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     41    93.2%   1180      
##  (0.5, 0.7]   (ok)        2     4.5%   4832      
##    (0.7, 1]   (bad)       1     2.3%   408       
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## See help('pareto-k-diagnostic') for details.

Two variables

loo_result <- loo(
  # Benchmark model(s)
  scenario_quality.with(),
  scenario_quality.with("work_experience_programming.s"),
  scenario_quality.with("workplace_coding_standards"),
  scenario_quality.with("workplace_peer_review"),
  scenario_quality.with("work_experience_java.s"),
  
  # New model(s)
  scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards")),
  scenario_quality.with(c("work_experience_programming.s", "workplace_peer_review")),
  scenario_quality.with(c("work_experience_programming.s", "work_experience_java.s")),
  
  scenario_quality.with(c("workplace_coding_standards", "workplace_peer_review")),
  scenario_quality.with(c("workplace_coding_standards", "work_experience_java.s")),
  
  scenario_quality.with(c("workplace_peer_review", "work_experience_java.s"))
)

Comparison

loo_result[2]
## $diffs
##                                                                                         elpd_diff
## scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards"))  0.0     
## scenario_quality.with("workplace_coding_standards")                                      0.0     
## scenario_quality.with("work_experience_programming.s")                                  -0.1     
## scenario_quality.with(c("workplace_coding_standards", "work_experience_java.s"))        -0.3     
## scenario_quality.with("workplace_peer_review")                                          -0.4     
## scenario_quality.with(c("workplace_peer_review", "work_experience_java.s"))             -0.5     
## scenario_quality.with(c("work_experience_programming.s", "work_experience_java.s"))     -0.5     
## scenario_quality.with("work_experience_java.s")                                         -0.5     
## scenario_quality.with(c("work_experience_programming.s", "workplace_peer_review"))      -0.5     
## scenario_quality.with(c("workplace_coding_standards", "workplace_peer_review"))         -0.6     
## scenario_quality.with()                                                                 -1.1     
##                                                                                         se_diff
## scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards"))  0.0   
## scenario_quality.with("workplace_coding_standards")                                      1.3   
## scenario_quality.with("work_experience_programming.s")                                   0.9   
## scenario_quality.with(c("workplace_coding_standards", "work_experience_java.s"))         0.4   
## scenario_quality.with("workplace_peer_review")                                           1.7   
## scenario_quality.with(c("workplace_peer_review", "work_experience_java.s"))              1.0   
## scenario_quality.with(c("work_experience_programming.s", "work_experience_java.s"))      0.9   
## scenario_quality.with("work_experience_java.s")                                          1.1   
## scenario_quality.with(c("work_experience_programming.s", "workplace_peer_review"))       0.8   
## scenario_quality.with(c("workplace_coding_standards", "workplace_peer_review"))          1.3   
## scenario_quality.with()                                                                  1.9

Diagnostics

loo_result[1]
## $loos
## $loos$`scenario_quality.with()`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -81.3 4.1
## p_loo         8.4 0.9
## looic       162.7 8.1
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1548      
##  (0.5, 0.7]   (ok)        1     2.3%   2108      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("work_experience_programming.s")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.3 4.2
## p_loo         9.2 0.9
## looic       160.7 8.4
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("workplace_coding_standards")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.2 4.2
## p_loo         8.7 0.9
## looic       160.5 8.4
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("workplace_peer_review")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.7 4.3
## p_loo         8.9 0.9
## looic       161.3 8.6
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("work_experience_java.s")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.8 4.2
## p_loo         9.2 0.9
## looic       161.5 8.4
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.2 4.3
## p_loo         9.6 0.9
## looic       160.4 8.6
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1920      
##  (0.5, 0.7]   (ok)        1     2.3%   4737      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("work_experience_programming.s", "workplace_peer_review"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.8 4.4
## p_loo         9.9 0.9
## looic       161.5 8.8
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1832      
##  (0.5, 0.7]   (ok)        1     2.3%   3228      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("work_experience_programming.s", "work_experience_java.s"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.7 4.3
## p_loo         9.6 1.0
## looic       161.4 8.5
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("workplace_coding_standards", "workplace_peer_review"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.8 4.3
## p_loo         9.5 1.0
## looic       161.6 8.6
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1684      
##  (0.5, 0.7]   (ok)        1     2.3%   1410      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("workplace_coding_standards", "work_experience_java.s"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.6 4.3
## p_loo         9.8 1.0
## looic       161.1 8.6
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     41    93.2%   1701      
##  (0.5, 0.7]   (ok)        3     6.8%   2998      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("workplace_peer_review", "work_experience_java.s"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.7 4.4
## p_loo         9.7 1.0
## looic       161.3 8.7
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1574      
##  (0.5, 0.7]   (ok)        1     2.3%   3923      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.

Three variables

loo_result <- loo(
  # Benchmark model(s)
  scenario_quality.with(),
  
  scenario_quality.with("work_experience_programming.s"),
  scenario_quality.with("workplace_coding_standards"),
  scenario_quality.with("workplace_peer_review"),
  scenario_quality.with("work_experience_java.s"),
  
  scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards")),
  scenario_quality.with(c("work_experience_programming.s", "workplace_peer_review")),
  scenario_quality.with(c("workplace_coding_standards", "work_experience_java.s")),
  
  # New model(s)
  scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards", "workplace_peer_review")),
  scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards", "work_experience_java.s")),
  scenario_quality.with(c("work_experience_programming.s", "work_experience_java.s", "workplace_peer_review")),
  scenario_quality.with(c("workplace_coding_standards", "work_experience_java.s", "workplace_peer_review"))
)

Comparison

loo_result[2]
## $diffs
##                                                                                                                       elpd_diff
## scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards"))                                0.0     
## scenario_quality.with("workplace_coding_standards")                                                                    0.0     
## scenario_quality.with("work_experience_programming.s")                                                                -0.1     
## scenario_quality.with(c("workplace_coding_standards", "work_experience_java.s"))                                      -0.3     
## scenario_quality.with("workplace_peer_review")                                                                        -0.4     
## scenario_quality.with("work_experience_java.s")                                                                       -0.5     
## scenario_quality.with(c("work_experience_programming.s", "workplace_peer_review"))                                    -0.5     
## scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards",     "workplace_peer_review"))  -0.7     
## scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards",     "work_experience_java.s")) -0.7     
## scenario_quality.with(c("workplace_coding_standards", "work_experience_java.s",     "workplace_peer_review"))         -0.9     
## scenario_quality.with(c("work_experience_programming.s", "work_experience_java.s",     "workplace_peer_review"))      -1.0     
## scenario_quality.with()                                                                                               -1.1     
##                                                                                                                       se_diff
## scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards"))                                0.0   
## scenario_quality.with("workplace_coding_standards")                                                                    1.3   
## scenario_quality.with("work_experience_programming.s")                                                                 0.9   
## scenario_quality.with(c("workplace_coding_standards", "work_experience_java.s"))                                       0.4   
## scenario_quality.with("workplace_peer_review")                                                                         1.7   
## scenario_quality.with("work_experience_java.s")                                                                        1.1   
## scenario_quality.with(c("work_experience_programming.s", "workplace_peer_review"))                                     0.8   
## scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards",     "workplace_peer_review"))   0.3   
## scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards",     "work_experience_java.s"))  0.2   
## scenario_quality.with(c("workplace_coding_standards", "work_experience_java.s",     "workplace_peer_review"))          0.6   
## scenario_quality.with(c("work_experience_programming.s", "work_experience_java.s",     "workplace_peer_review"))       0.8   
## scenario_quality.with()                                                                                                1.9

Diagnostics

loo_result[1]
## $loos
## $loos$`scenario_quality.with()`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -81.3 4.1
## p_loo         8.4 0.9
## looic       162.7 8.1
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1548      
##  (0.5, 0.7]   (ok)        1     2.3%   2108      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("work_experience_programming.s")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.3 4.2
## p_loo         9.2 0.9
## looic       160.7 8.4
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("workplace_coding_standards")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.2 4.2
## p_loo         8.7 0.9
## looic       160.5 8.4
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("workplace_peer_review")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.7 4.3
## p_loo         8.9 0.9
## looic       161.3 8.6
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with("work_experience_java.s")`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.8 4.2
## p_loo         9.2 0.9
## looic       161.5 8.4
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.2 4.3
## p_loo         9.6 0.9
## looic       160.4 8.6
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1920      
##  (0.5, 0.7]   (ok)        1     2.3%   4737      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("work_experience_programming.s", "workplace_peer_review"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.8 4.4
## p_loo         9.9 0.9
## looic       161.5 8.8
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1832      
##  (0.5, 0.7]   (ok)        1     2.3%   3228      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("workplace_coding_standards", "work_experience_java.s"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.6 4.3
## p_loo         9.8 1.0
## looic       161.1 8.6
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     41    93.2%   1701      
##  (0.5, 0.7]   (ok)        3     6.8%   2998      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards",     "workplace_peer_review"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.9 4.4
## p_loo        10.3 1.0
## looic       161.8 8.7
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     42    95.5%   1565      
##  (0.5, 0.7]   (ok)        2     4.5%   3778      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("work_experience_programming.s", "workplace_coding_standards",     "work_experience_java.s"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -80.9 4.3
## p_loo        10.3 1.0
## looic       161.8 8.6
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     42    95.5%   1810      
##  (0.5, 0.7]   (ok)        2     4.5%   1245      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("work_experience_programming.s", "work_experience_java.s",     "workplace_peer_review"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -81.2 4.4
## p_loo        10.4 1.1
## looic       162.4 8.8
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## All Pareto k estimates are good (k < 0.5).
## See help('pareto-k-diagnostic') for details.
## 
## $loos$`scenario_quality.with(c("workplace_coding_standards", "work_experience_java.s",     "workplace_peer_review"))`
## 
## Computed from 4000 by 44 log-likelihood matrix
## 
##          Estimate  SE
## elpd_loo    -81.2 4.4
## p_loo        10.5 1.1
## looic       162.3 8.8
## ------
## Monte Carlo SE of elpd_loo is 0.1.
## 
## Pareto k diagnostic values:
##                          Count Pct.    Min. n_eff
## (-Inf, 0.5]   (good)     43    97.7%   1255      
##  (0.5, 0.7]   (ok)        1     2.3%   1744      
##    (0.7, 1]   (bad)       0     0.0%   <NA>      
##    (1, Inf)   (very bad)  0     0.0%   <NA>      
## 
## All Pareto k estimates are ok (k < 0.7).
## See help('pareto-k-diagnostic') for details.

Candidate models

We pick some of our top performing models as candidates and inspect them closer.

The candidate models are named and listed in order of complexity.

ScenarioQuality0

We select the simplest model as a baseline.

scenario_quality0 <- brm(
  "quality_pre_task ~ 1 + high_debt_version + (1 | session)",
  prior = c(
    prior(normal(0, 1), class = "b"),
    prior(normal(0, 2), class = "Intercept"),
    prior(exponential(1), class = "sd")
  ),
  family = cumulative(),
  data = as.data.frame(d.both_completed),
  file = "fits/scenario_quality0",
  file_refit = "on_change",
  seed = 20210421
)

Summary

summary(scenario_quality0)
##  Family: cumulative 
##   Links: mu = logit; disc = identity 
## Formula: quality_pre_task ~ 1 + high_debt_version + (1 | session) 
##    Data: as.data.frame(d.both_completed) (Number of observations: 44) 
##   Draws: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
##          total post-warmup draws = 4000
## 
## Group-Level Effects: 
## ~session (Number of levels: 22) 
##               Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept)     0.36      0.29     0.01     1.08 1.00     2157     2375
## 
## Population-Level Effects: 
##                        Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
## Intercept[1]              -1.90      0.55    -3.03    -0.87 1.00     4722
## Intercept[2]              -0.56      0.42    -1.40     0.25 1.00     6267
## Intercept[3]               0.22      0.42    -0.59     1.03 1.00     5807
## Intercept[4]               0.62      0.43    -0.24     1.48 1.00     5701
## Intercept[5]               1.91      0.49     0.96     2.89 1.00     5077
## Intercept[6]               3.94      0.72     2.62     5.50 1.00     5851
## high_debt_versionfalse     1.38      0.51     0.38     2.40 1.00     6286
##                        Tail_ESS
## Intercept[1]               2746
## Intercept[2]               3602
## Intercept[3]               3569
## Intercept[4]               3310
## Intercept[5]               2753
## Intercept[6]               3086
## high_debt_versionfalse     2942
## 
## Family Specific Parameters: 
##      Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## disc     1.00      0.00     1.00     1.00   NA       NA       NA
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).

Random effects

ranef(scenario_quality0)
## $session
## , , Intercept
## 
##                              Estimate Est.Error       Q2.5     Q97.5
## 6033d69a5af2c702367b3a95 -0.129903125 0.4188857 -1.2299003 0.5809392
## 6033d90a5af2c702367b3a96  0.009332742 0.3950992 -0.8300987 0.8522972
## 6034fc165af2c702367b3a98 -0.011157968 0.3905769 -0.8681339 0.8054951
## 603500725af2c702367b3a99  0.270396793 0.5335423 -0.4259196 1.7889557
## 603f97625af2c702367b3a9d -0.024159053 0.3859246 -0.8598157 0.7813736
## 603fd5d95af2c702367b3a9e  0.042621048 0.4100073 -0.7859991 1.0106544
## 60409b7b5af2c702367b3a9f -0.034372972 0.4106800 -0.9725467 0.7755178
## 604b82b5a7718fbed181b336  0.217655146 0.4817231 -0.4441285 1.5300886
## 6050c1bf856f36729d2e5218 -0.111418626 0.4153685 -1.1348366 0.6217000
## 6050e1e7856f36729d2e5219  0.024062186 0.4305651 -0.8408798 1.0065099
## 6055fdc6856f36729d2e521b  0.015782909 0.4060000 -0.8626181 0.9303131
## 60589862856f36729d2e521f -0.152063085 0.4395170 -1.3093359 0.5557654
## 605afa3a856f36729d2e5222 -0.019792100 0.3886462 -0.9549447 0.7941260
## 605c8bc6856f36729d2e5223 -0.153030454 0.4664495 -1.3579791 0.6397383
## 605f3f2d856f36729d2e5224 -0.159242583 0.4432931 -1.2930023 0.5596181
## 605f46c3856f36729d2e5225  0.052246427 0.3998679 -0.7400494 0.9765701
## 60605337856f36729d2e5226 -0.079268998 0.4080155 -1.0847426 0.7019991
## 60609ae6856f36729d2e5228  0.012534538 0.4034100 -0.8579773 0.9486387
## 6061ce91856f36729d2e522e  0.010486655 0.4007665 -0.8477178 0.9114304
## 6061f106856f36729d2e5231  0.234240817 0.5071045 -0.4486812 1.6131326
## 6068ea9f856f36729d2e523e -0.056338226 0.4066959 -0.9792076 0.7726060
## 6075ab05856f36729d2e5247  0.059047385 0.3845733 -0.7120678 0.9804833

Sampling plots

plot(scenario_quality0, ask = FALSE)

Posterior predictive check

pp_check(scenario_quality0, nsamples = 200, type = "bars")
## Warning: Argument 'nsamples' is deprecated. Please use argument 'ndraws'
## instead.

ScenarioQuality1

We select the best performing model with one variable.

scenario_quality1 <- brm(
  "quality_pre_task ~ 1 + high_debt_version + work_experience_programming.s + (1 | session)",
  prior = c(
    prior(normal(0, 1), class = "b"),
    prior(normal(0, 2), class = "Intercept"),
    prior(exponential(1), class = "sd")
  ),
  family = cumulative(),
  data = as.data.frame(d.both_completed),
  file = "fits/scenario_quality1",
  file_refit = "on_change",
  seed = 20210421
)

Summary

summary(scenario_quality1)
##  Family: cumulative 
##   Links: mu = logit; disc = identity 
## Formula: quality_pre_task ~ 1 + high_debt_version + work_experience_programming.s + (1 | session) 
##    Data: as.data.frame(d.both_completed) (Number of observations: 44) 
##   Draws: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
##          total post-warmup draws = 4000
## 
## Group-Level Effects: 
## ~session (Number of levels: 22) 
##               Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept)     0.34      0.28     0.01     1.06 1.00     2480     2292
## 
## Population-Level Effects: 
##                               Estimate Est.Error l-95% CI u-95% CI Rhat
## Intercept[1]                     -1.98      0.53    -3.10    -1.00 1.00
## Intercept[2]                     -0.55      0.42    -1.40     0.29 1.01
## Intercept[3]                      0.25      0.43    -0.60     1.06 1.00
## Intercept[4]                      0.65      0.43    -0.21     1.51 1.00
## Intercept[5]                      1.97      0.48     1.04     2.95 1.00
## Intercept[6]                      4.07      0.74     2.72     5.68 1.00
## high_debt_versionfalse            1.45      0.53     0.41     2.50 1.00
## work_experience_programming.s    -0.54      0.30    -1.15     0.03 1.00
##                               Bulk_ESS Tail_ESS
## Intercept[1]                      4561     2906
## Intercept[2]                      7037     2959
## Intercept[3]                      6509     3466
## Intercept[4]                      6227     3494
## Intercept[5]                      5972     3377
## Intercept[6]                      6730     3140
## high_debt_versionfalse            7589     2913
## work_experience_programming.s     7091     2980
## 
## Family Specific Parameters: 
##      Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## disc     1.00      0.00     1.00     1.00   NA       NA       NA
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).

Random effects

ranef(scenario_quality1)
## $session
## , , Intercept
## 
##                              Estimate Est.Error       Q2.5     Q97.5
## 6033d69a5af2c702367b3a95 -0.156324093 0.4228048 -1.2898998 0.4942763
## 6033d90a5af2c702367b3a96 -0.012759481 0.3944357 -0.8916087 0.8954872
## 6034fc165af2c702367b3a98 -0.046555071 0.3837114 -0.9378860 0.7432463
## 603500725af2c702367b3a99  0.229364484 0.5146324 -0.4314582 1.6567989
## 603f97625af2c702367b3a9d -0.056216128 0.3681785 -0.9269026 0.6919428
## 603fd5d95af2c702367b3a9e  0.014045577 0.4130713 -0.8307097 0.9153825
## 60409b7b5af2c702367b3a9f -0.072860414 0.3952675 -1.0628554 0.6589539
## 604b82b5a7718fbed181b336  0.193177759 0.4527226 -0.4613786 1.4454478
## 6050c1bf856f36729d2e5218 -0.082122079 0.3955144 -1.0687864 0.6205536
## 6050e1e7856f36729d2e5219  0.008848661 0.4292889 -0.9418675 0.9254945
## 6055fdc6856f36729d2e521b -0.023154826 0.3803876 -0.8903244 0.7815592
## 60589862856f36729d2e521f -0.044222350 0.4072477 -1.0242237 0.7698421
## 605afa3a856f36729d2e5222  0.073201385 0.3744533 -0.6355949 1.0288080
## 605c8bc6856f36729d2e5223 -0.129958314 0.4177075 -1.1933380 0.5445543
## 605f3f2d856f36729d2e5224 -0.011700803 0.4144657 -0.9096976 0.8629951
## 605f46c3856f36729d2e5225  0.031900177 0.3946281 -0.7760796 0.9358086
## 60605337856f36729d2e5226 -0.096617375 0.3953706 -1.1020617 0.6347367
## 60609ae6856f36729d2e5228 -0.021687185 0.3902530 -0.9279962 0.8087896
## 6061ce91856f36729d2e522e -0.020532041 0.3917740 -0.8967069 0.8195523
## 6061f106856f36729d2e5231  0.186195354 0.4575356 -0.4716529 1.4376291
## 6068ea9f856f36729d2e523e -0.060923418 0.4198880 -1.0576470 0.7425363
## 6075ab05856f36729d2e5247  0.045584175 0.3869492 -0.7113120 0.9555720

Sampling plots

plot(scenario_quality1, ask = FALSE)

Posterior predictive check

pp_check(scenario_quality1, nsamples = 200, type = "bars")
## Warning: Argument 'nsamples' is deprecated. Please use argument 'ndraws'
## instead.

ScenarioQuality2

We select the best performing model with two variables.

scenario_quality2 <- brm(
  "quality_pre_task ~ 1 + high_debt_version + work_experience_programming.s + workplace_coding_standards + (1 | session)",
  prior = c(
    prior(normal(0, 1), class = "b"),
    prior(normal(0, 2), class = "Intercept"),
    prior(exponential(1), class = "sd")
  ),
  family = cumulative(),
  data = as.data.frame(d.both_completed),
  file = "fits/scenario_quality2",
  file_refit = "on_change",
  seed = 20210421
)

Summary

summary(scenario_quality2)
##  Family: cumulative 
##   Links: mu = logit; disc = identity 
## Formula: quality_pre_task ~ 1 + high_debt_version + work_experience_programming.s + workplace_coding_standards + (1 | session) 
##    Data: as.data.frame(d.both_completed) (Number of observations: 44) 
##   Draws: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
##          total post-warmup draws = 4000
## 
## Group-Level Effects: 
## ~session (Number of levels: 22) 
##               Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept)     0.35      0.28     0.01     1.04 1.00     1769     1950
## 
## Population-Level Effects: 
##                                 Estimate Est.Error l-95% CI u-95% CI Rhat
## Intercept[1]                       -1.73      0.59    -2.94    -0.66 1.00
## Intercept[2]                       -0.30      0.47    -1.20     0.62 1.00
## Intercept[3]                        0.50      0.48    -0.43     1.44 1.00
## Intercept[4]                        0.91      0.49    -0.02     1.88 1.00
## Intercept[5]                        2.26      0.54     1.22     3.36 1.00
## Intercept[6]                        4.39      0.77     2.95     5.99 1.00
## high_debt_versionfalse              1.46      0.51     0.46     2.48 1.00
## work_experience_programming.s      -0.44      0.31    -1.07     0.16 1.00
## workplace_coding_standardsfalse     0.56      0.53    -0.48     1.62 1.00
##                                 Bulk_ESS Tail_ESS
## Intercept[1]                        4925     3390
## Intercept[2]                        5924     3620
## Intercept[3]                        5392     2949
## Intercept[4]                        5358     3352
## Intercept[5]                        4406     3108
## Intercept[6]                        5492     3535
## high_debt_versionfalse              6701     2956
## work_experience_programming.s       4789     2793
## workplace_coding_standardsfalse     4831     2512
## 
## Family Specific Parameters: 
##      Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## disc     1.00      0.00     1.00     1.00   NA       NA       NA
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).

Random effects

ranef(scenario_quality2)
## $session
## , , Intercept
## 
##                              Estimate Est.Error       Q2.5     Q97.5
## 6033d69a5af2c702367b3a95 -0.185747243 0.4365202 -1.3625338 0.4856064
## 6033d90a5af2c702367b3a96  0.004219249 0.3926383 -0.8605150 0.8819449
## 6034fc165af2c702367b3a98 -0.068997948 0.3926284 -1.0393832 0.6888253
## 603500725af2c702367b3a99  0.220885581 0.5082568 -0.4754369 1.6086947
## 603f97625af2c702367b3a9d -0.021591877 0.3820250 -0.8993056 0.7584072
## 603fd5d95af2c702367b3a9e  0.006671980 0.4176682 -0.8457328 0.9516715
## 60409b7b5af2c702367b3a9f -0.091684204 0.3871800 -1.0338906 0.6413740
## 604b82b5a7718fbed181b336  0.179039062 0.4618139 -0.5307246 1.4183830
## 6050c1bf856f36729d2e5218 -0.066804230 0.3945816 -1.0389064 0.6825417
## 6050e1e7856f36729d2e5219 -0.003540173 0.4150383 -0.9453250 0.8973239
## 6055fdc6856f36729d2e521b  0.019478872 0.3890875 -0.8141966 0.8991186
## 60589862856f36729d2e521f -0.030413659 0.4033890 -0.9310910 0.8388175
## 605afa3a856f36729d2e5222  0.094563284 0.4019942 -0.6453876 1.1210384
## 605c8bc6856f36729d2e5223 -0.107294429 0.4280647 -1.1843492 0.6373083
## 605f3f2d856f36729d2e5224  0.001413917 0.4277264 -0.9191924 0.8851699
## 605f46c3856f36729d2e5225  0.077048402 0.3874171 -0.6734111 1.0115066
## 60605337856f36729d2e5226 -0.064654146 0.3961882 -1.0375038 0.7130141
## 60609ae6856f36729d2e5228 -0.039800926 0.3721491 -0.8923937 0.7130692
## 6061ce91856f36729d2e522e  0.013653238 0.3956862 -0.8068239 0.9047648
## 6061f106856f36729d2e5231  0.162193709 0.4452366 -0.5149623 1.3327140
## 6068ea9f856f36729d2e523e -0.071444015 0.4027677 -1.0328201 0.7013173
## 6075ab05856f36729d2e5247  0.019111441 0.3850891 -0.8156413 0.9314004

Sampling plots

plot(scenario_quality2, ask = FALSE)

Posterior predictive check

pp_check(scenario_quality2, nsamples = 200, type = "bars")
## Warning: Argument 'nsamples' is deprecated. Please use argument 'ndraws'
## instead.

ScenarioQuality3

We select the best performing model with three variables.

scenario_quality3 <- brm(
  "quality_pre_task ~ 1 + high_debt_version + work_experience_programming.s + workplace_coding_standards + work_experience_java.s + (1 | session)",
  prior = c(
    prior(normal(0, 1), class = "b"),
    prior(normal(0, 2), class = "Intercept"),
    prior(exponential(1), class = "sd")
  ),
  family = cumulative(),
  data = as.data.frame(d.both_completed),
  file = "fits/scenario_quality3",
  file_refit = "on_change",
  seed = 20210421
)

Summary

summary(scenario_quality3)
##  Family: cumulative 
##   Links: mu = logit; disc = identity 
## Formula: quality_pre_task ~ 1 + high_debt_version + work_experience_programming.s + workplace_coding_standards + work_experience_java.s + (1 | session) 
##    Data: as.data.frame(d.both_completed) (Number of observations: 44) 
##   Draws: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
##          total post-warmup draws = 4000
## 
## Group-Level Effects: 
## ~session (Number of levels: 22) 
##               Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept)     0.35      0.28     0.01     1.02 1.00     2232     1866
## 
## Population-Level Effects: 
##                                 Estimate Est.Error l-95% CI u-95% CI Rhat
## Intercept[1]                       -1.75      0.60    -3.00    -0.64 1.00
## Intercept[2]                       -0.31      0.49    -1.29     0.62 1.00
## Intercept[3]                        0.50      0.49    -0.46     1.46 1.00
## Intercept[4]                        0.90      0.51    -0.09     1.89 1.00
## Intercept[5]                        2.25      0.57     1.17     3.40 1.00
## Intercept[6]                        4.39      0.80     2.92     6.09 1.00
## high_debt_versionfalse              1.46      0.50     0.47     2.45 1.00
## work_experience_programming.s      -0.38      0.63    -1.62     0.86 1.00
## workplace_coding_standardsfalse     0.55      0.55    -0.51     1.65 1.00
## work_experience_java.s             -0.09      0.62    -1.29     1.16 1.00
##                                 Bulk_ESS Tail_ESS
## Intercept[1]                        5223     3396
## Intercept[2]                        7157     3799
## Intercept[3]                        6025     3323
## Intercept[4]                        5696     3314
## Intercept[5]                        5098     2636
## Intercept[6]                        5784     2883
## high_debt_versionfalse              5117     2728
## work_experience_programming.s       3161     2898
## workplace_coding_standardsfalse     6725     2695
## work_experience_java.s              3395     2866
## 
## Family Specific Parameters: 
##      Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## disc     1.00      0.00     1.00     1.00   NA       NA       NA
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).

Random effects

ranef(scenario_quality3)
## $session
## , , Intercept
## 
##                              Estimate Est.Error       Q2.5     Q97.5
## 6033d69a5af2c702367b3a95 -0.183968515 0.4424785 -1.3355809 0.4932503
## 6033d90a5af2c702367b3a96  0.006153712 0.3817561 -0.8123480 0.8944321
## 6034fc165af2c702367b3a98 -0.069662603 0.3812510 -0.9480196 0.7061861
## 603500725af2c702367b3a99  0.212597291 0.5057904 -0.4791792 1.6075705
## 603f97625af2c702367b3a9d -0.029453586 0.3944049 -0.9498690 0.7747838
## 603fd5d95af2c702367b3a9e  0.005341444 0.3903356 -0.8431430 0.9020765
## 60409b7b5af2c702367b3a9f -0.104888010 0.4023436 -1.1248769 0.5933679
## 604b82b5a7718fbed181b336  0.181406366 0.4516697 -0.5215662 1.3454235
## 6050c1bf856f36729d2e5218 -0.060531758 0.3998653 -1.0009524 0.7228178
## 6050e1e7856f36729d2e5219  0.001218971 0.3970731 -0.8812060 0.8599051
## 6055fdc6856f36729d2e521b  0.003557873 0.3868659 -0.8264013 0.8420175
## 60589862856f36729d2e521f -0.029938970 0.4183108 -1.0651721 0.8023106
## 605afa3a856f36729d2e5222  0.099103740 0.3948460 -0.5896966 1.0703840
## 605c8bc6856f36729d2e5223 -0.107485145 0.4162012 -1.1875757 0.6199258
## 605f3f2d856f36729d2e5224 -0.002514301 0.4288634 -0.9433927 0.9410924
## 605f46c3856f36729d2e5225  0.058492104 0.4022862 -0.7093513 1.0085691
## 60605337856f36729d2e5226 -0.068200670 0.3901694 -0.9970055 0.6752643
## 60609ae6856f36729d2e5228 -0.037222949 0.3923003 -0.9739810 0.7488668
## 6061ce91856f36729d2e522e  0.011729049 0.3972338 -0.8238957 0.8633298
## 6061f106856f36729d2e5231  0.168208896 0.4488761 -0.5164507 1.3794813
## 6068ea9f856f36729d2e523e -0.077187951 0.4161270 -1.1091213 0.6391310
## 6075ab05856f36729d2e5247  0.015634150 0.3905241 -0.7791451 0.8986069

Sampling plots

plot(scenario_quality3, ask = FALSE)

Posterior predictive check

pp_check(scenario_quality3, nsamples = 200, type = "bars")
## Warning: Argument 'nsamples' is deprecated. Please use argument 'ndraws'
## instead.

Final model

All candidate models look nice, none is significantly better than the others, we will proceed the model containing work experince as it otherwise ourd be added in the next step: scenario_quality1

All data points

Some participants did only complete one scenario. Those has been excluded from the initial dataset to improve sampling of the models. We do however want to use all data we can and will therefore try to fit the model with the complete dataset.

scenario_quality1.all <- brm(
  "quality_pre_task ~ 1 + high_debt_version + work_experience_programming.s + (1 | session)",
  prior = c(
    prior(normal(0, 1), class = "b"),
    prior(normal(0, 2), class = "Intercept"),
    prior(exponential(1), class = "sd")
  ),
  family = cumulative(),
  data = as.data.frame(d.completed),
  file = "fits/scenario_quality1.all",
  file_refit = "on_change",
  seed = 20210421
)

Summary

summary(scenario_quality1.all)
##  Family: cumulative 
##   Links: mu = logit; disc = identity 
## Formula: quality_pre_task ~ 1 + high_debt_version + work_experience_programming.s + (1 | session) 
##    Data: as.data.frame(d.completed) (Number of observations: 51) 
##   Draws: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
##          total post-warmup draws = 4000
## 
## Group-Level Effects: 
## ~session (Number of levels: 29) 
##               Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept)     0.33      0.26     0.01     0.98 1.00     2031     2303
## 
## Population-Level Effects: 
##                               Estimate Est.Error l-95% CI u-95% CI Rhat
## Intercept[1]                     -2.07      0.53    -3.23    -1.12 1.00
## Intercept[2]                     -0.59      0.40    -1.38     0.16 1.00
## Intercept[3]                      0.29      0.39    -0.48     1.05 1.00
## Intercept[4]                      0.80      0.40     0.03     1.60 1.00
## Intercept[5]                      2.07      0.45     1.21     2.97 1.00
## Intercept[6]                      4.20      0.72     2.87     5.73 1.00
## high_debt_versionfalse            1.41      0.46     0.53     2.32 1.00
## work_experience_programming.s    -0.53      0.28    -1.09    -0.01 1.00
##                               Bulk_ESS Tail_ESS
## Intercept[1]                      5364     3202
## Intercept[2]                      7002     3150
## Intercept[3]                      5686     3185
## Intercept[4]                      5096     2788
## Intercept[5]                      4930     3176
## Intercept[6]                      5691     3121
## high_debt_versionfalse            6402     3014
## work_experience_programming.s     6128     2673
## 
## Family Specific Parameters: 
##      Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## disc     1.00      0.00     1.00     1.00   NA       NA       NA
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).

Random effects

ranef(scenario_quality1.all)
## $session
## , , Intercept
## 
##                              Estimate Est.Error       Q2.5     Q97.5
## 6033c6fc5af2c702367b3a93 -0.036344018 0.3778096 -0.9443224 0.7505782
## 6033d69a5af2c702367b3a95 -0.143880160 0.4067284 -1.2252806 0.5083088
## 6033d90a5af2c702367b3a96 -0.012651518 0.3629096 -0.8817472 0.7549010
## 6034fc165af2c702367b3a98 -0.026550109 0.3595660 -0.8477204 0.7387046
## 603500725af2c702367b3a99  0.216037415 0.4604108 -0.4222454 1.4852549
## 603f84f15af2c702367b3a9b -0.003780082 0.3803829 -0.8326188 0.8278322
## 603f97625af2c702367b3a9d -0.040929735 0.3666652 -0.8933498 0.7011871
## 603fd5d95af2c702367b3a9e  0.014026924 0.3845764 -0.8030918 0.8580742
## 60409b7b5af2c702367b3a9f -0.044290239 0.3568668 -0.8463546 0.6859541
## 604b82b5a7718fbed181b336  0.199405266 0.4540252 -0.4478257 1.4098924
## 604f1239a7718fbed181b33f  0.021776699 0.3898698 -0.7922127 0.9064980
## 6050c1bf856f36729d2e5218 -0.070180778 0.3807548 -0.9952862 0.6526994
## 6050e1e7856f36729d2e5219  0.006824639 0.4221551 -0.9162308 0.9179286
## 6055fdc6856f36729d2e521b -0.011133238 0.3782325 -0.8731314 0.7928925
## 60579f2a856f36729d2e521e -0.150126094 0.4693970 -1.4194407 0.6014127
## 60589862856f36729d2e521f -0.029848559 0.4007633 -0.9316652 0.7944116
## 605a30a7856f36729d2e5221  0.091605269 0.4086198 -0.6576940 1.0914805
## 605afa3a856f36729d2e5222  0.098228662 0.4069549 -0.6159270 1.0997090
## 605c8bc6856f36729d2e5223 -0.104956218 0.3984449 -1.0980014 0.6093432
## 605f3f2d856f36729d2e5224  0.016485113 0.4004776 -0.8215100 0.8891029
## 605f46c3856f36729d2e5225  0.044105277 0.3635976 -0.7131632 0.8564480
## 60605337856f36729d2e5226 -0.090580836 0.3784690 -1.0864748 0.5999590
## 60609ae6856f36729d2e5228 -0.021462566 0.3819059 -0.8899594 0.8060843
## 6061ce91856f36729d2e522e -0.016937451 0.3701515 -0.8359979 0.7785221
## 6061f106856f36729d2e5231  0.184549114 0.4486086 -0.4788589 1.4117604
## 60672faa856f36729d2e523c -0.061977456 0.3994896 -1.0018200 0.7256522
## 6068ea9f856f36729d2e523e -0.041880481 0.3881958 -0.9686586 0.7371543
## 606db69d856f36729d2e5243 -0.046806836 0.3703962 -0.9090831 0.6711855
## 6075ab05856f36729d2e5247  0.061664861 0.3751948 -0.6628332 1.0107697

Sampling plots

plot(scenario_quality1.all, ask = FALSE)

Posterior predictive check

pp_check(scenario_quality1.all, nsamples = 200, type = "bars")
## Warning: Argument 'nsamples' is deprecated. Please use argument 'ndraws'
## instead.

Final model

  • Fitting the model to all data point did not significantly damage the model and will be used as is a more fair representation of reality.

This means that our final model, with all data points and experience predictors, is scenario_quality1.all

Interpreting the model

To begin interpreting the model we look at how it’s parameters were estimated. As our research is focused on how the outcome of the model is effected we will mainly analyze the \(\beta\) parameters.

\(\beta\) parameters

mcmc_areas(scenario_quality1.all, pars = c("b_high_debt_versionfalse", "b_work_experience_programming.s"), prob = 0.95) + scale_y_discrete() +
  scale_y_discrete(labels=c("High debt version: false", "Professional programming experience")) +
  ggtitle("Beta parameters densities in scenario quality model", subtitle = "Shaded region marks 95% of the density. Line marks the median")

scale_programming_experience <- function(x) {
  (x - mean(d.completed$work_experience_programming))/ sd(d.completed$work_experience_programming)
}
unscale_programming_experience <- function(x) {
  x * sd(d.completed$work_experience_programming) + mean(d.completed$work_experience_programming)
}

post_settings <- expand.grid(
  high_debt_version = c("false", "true"),
  session = NA,
  work_experience_programming.s = sapply(c(0, 3, 10, 25, 40), scale_programming_experience)
)

post <- posterior_predict(scenario_quality1.all, newdata = post_settings) %>%
  melt(value.name = "estimate", varnames = c("sample_number", "settings_id")) %>%
  left_join(
    rowid_to_column(post_settings, var= "settings_id"),
    by = "settings_id"
  ) %>%
  mutate(work_experience_programming = unscale_programming_experience(work_experience_programming.s)) %>%
  select(
    estimate,
    high_debt_version,
    work_experience_programming
  )%>%
  mutate(estimate = estimate)


post.nice <- post %>%  mutate_at("estimate", function(x) revalue(as.ordered(x), c(
      "1"="Very Bad",
      "2"="Bad",
      "3"="Somewhat Bad",
      "4"="Neutral",
      "5"="Somewhat Good",
      "6"="Good",
      "7"="Very Good"
    )))

post.nice$high_debt_version <- revalue(post.nice$high_debt_version, c(
      "true"="High Debt",
      "false"="Low Debt"
    ))



post.nice.3 <- filter(post.nice, work_experience_programming == 3)

vline.data.3 <- post.nice.3 %>%
              group_by(high_debt_version) %>%
                    summarize(z = mean(as.numeric(estimate)))

sprintf("Estimations for 3 years experience")
## [1] "Estimations for 3 years experience"
post.nice.3 %>%
    ggplot() +
      geom_histogram(aes(x=estimate),fill= "Light Blue", stat = "count") +
      geom_vline(aes(xintercept = z),
            vline.data.3,
             col = "Dark Blue",
             lwd = 1)+
      facet_grid(rows = vars(high_debt_version)) +
        scale_y_continuous(limits = NULL, breaks = sapply(c(0.1, 0.2, 0.3, 0.4), function(x) x*nrow(post.nice.3) / 2), labels = c("10%","20%","30%","40%")) +
      theme(axis.title.x=element_blank(),
            axis.title.y=element_blank())

post.nice.25 <- filter(post.nice, work_experience_programming == 25)

vline.data.25 <- post.nice.25 %>%
              group_by(high_debt_version) %>%
                    summarize(z = mean(as.numeric(estimate)))

sprintf("Estimations for 25 years experience")
## [1] "Estimations for 25 years experience"
post.nice.25 %>%
    ggplot() +
      geom_histogram(aes(x=estimate),fill= "Light Blue", stat = "count") +
      geom_vline(aes(xintercept = z),
            vline.data.25,
             col = "Dark Blue",
             lwd = 1)+
      facet_grid(rows = vars(high_debt_version)) +
        scale_y_continuous(limits = NULL, breaks = sapply(c(0.1, 0.2, 0.3, 0.4), function(x) x*nrow(post.nice.25) / 2), labels = c("10%","20%","30%","40%")) +
      theme(axis.title.x=element_blank(),
            axis.title.y=element_blank())

post.diff <- post %>% filter(high_debt_version == "true")
post.diff$estimate = post.diff$estimate -  filter(post, high_debt_version == "false")$estimate

post.diff %>%
  ggplot(aes(x=estimate)) +
  geom_boxplot(quantile_lines = TRUE, quantile_fun = hdi, vline_linetype = 2) +
  facet_grid(rows = vars(work_experience_programming)) +
  labs(
    title = "Scenario rating diff / years of programming experience",
    subtitle = "Difference as: high debt rating - low debt rating",
    x = "Rating difference"
  ) +
  scale_y_continuous(breaks = NULL)

We can then proceed to calculate some likelihoods:

post.diff.10 <- post.diff %>% filter(work_experience_programming == 10)
high_debt_rated_higher <- sum(post.diff.10$estimate > 0)
low_debt_rated_higher <- sum(post.diff.10$estimate < 0)
x <- low_debt_rated_higher / high_debt_rated_higher
x
## [1] 3.136139

Participants with 10 years of professional programming experience were 214% more likely to rate the high debt version scenario as worse than then they were to rate the low debt version scenario as worse.

LS0tCnRpdGxlOiAiU3lzdGVtIFF1YWxpdHkgUmF0aW5nIE1vZGVsIgphdXRob3I6IEhhbXB1cyBCcm9tYW4gJiBXaWxsaWFtIExldsOpbgpkYXRlOiAyMDIxLTA1Cm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDogCiAgICBwYW5kb2NfYXJnczogWyAiLW8iLCAiZG9jcy9zeXN0ZW1fcXVhbGl0eV9yYXRpbmcuaHRtbCIgXQotLS0KCmBgYHtyIGluY2x1ZGUtc2V0dXAsIGluY2x1ZGU9RkFMU0V9CiMgTG9hZCBzZXR1cCBmaWxlCnNvdXJjZShrbml0cjo6cHVybCgnc2V0dXAuUm1kJywgb3V0cHV0ID0gdGVtcGZpbGUoKSkpCmBgYAoKCiMjIExvb2tpbmcgYXQgdGhlIGRhdGEgIHsudGFic2V0fQoKV2UgcGxvdCB0aGUgZGF0YSBhbmQgY2FuIHNlZSB0aGF0IHRoZXJlIGlzIG5vIG9idmlvdXMgbGFyZ2UgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBkZWJ0IGxldmVscyBvciBzY2VuYXJpb3MuCgojIyMgUGVyIGRlYnQgbGV2ZWwKCmBgYHtyfQpsaWtlcnQuZGF0YSA8LSBkLmJvdGhfY29tcGxldGVkICU+JQogIHNlbGVjdChoaWdoX2RlYnRfdmVyc2lvbiwgcXVhbGl0eV9wcmVfdGFzaykKCmxpa2VydC5kYXRhJHF1YWxpdHlfcHJlX3Rhc2sgPC0gcmV2YWx1ZShsaWtlcnQuZGF0YSRxdWFsaXR5X3ByZV90YXNrLCBjKAogICAgICAiLTMiPSJWZXJ5IEJhZCIsCiAgICAgICItMiI9IkJhZCIsCiAgICAgICItMSI9IlNvbWV3aGF0IEJhZCIsCiAgICAgICIwIj0iTmV1dHJhbCIsCiAgICAgICIxIj0iU29tZXdoYXQgR29vZCIsCiAgICAgICIyIj0iR29vZCIsCiAgICAgICIzIj0iVmVyeSBHb29kIgogICAgKSkKCmxpa2VydC5kYXRhJGhpZ2hfZGVidF92ZXJzaW9uIDwtIHJldmFsdWUobGlrZXJ0LmRhdGEkaGlnaF9kZWJ0X3ZlcnNpb24sIGMoCiAgICAgICJ0cnVlIj0iSGlnaCBEZWJ0IiwKICAgICAgImZhbHNlIj0iTG93IERlYnQiCiAgICApKQoKZ2dwbG90KGxpa2VydC5kYXRhLCBhZXMoeD1xdWFsaXR5X3ByZV90YXNrKSkgKwogIGdlb21fYmFyKGZpbGw9ICJMaWdodCBCbHVlIikgKwogIGZhY2V0X2dyaWQocm93cyA9IHZhcnMoaGlnaF9kZWJ0X3ZlcnNpb24pKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gTlVMTCwgYnJlYWtzID0gYygyLDQsNiw4KSwgbGFiZWxzID0gYygiMiIsIjQiLCI2IiwiOCIpKSArCiAgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpKQoKCmBgYAoKIyMjIFBlciBzY2VuYXJpbwoKYGBge3J9Cmxpa2VydC5kYXRhIDwtIGQuYm90aF9jb21wbGV0ZWQgJT4lCiAgc2VsZWN0KHNjZW5hcmlvLCBxdWFsaXR5X3ByZV90YXNrKQoKbGlrZXJ0LmRhdGEkcXVhbGl0eV9wcmVfdGFzayA8LSByZXZhbHVlKGxpa2VydC5kYXRhJHF1YWxpdHlfcHJlX3Rhc2ssIGMoCiAgICAgICItMyI9IlZlcnkgQmFkIiwKICAgICAgIi0yIj0iQmFkIiwKICAgICAgIi0xIj0iU29tZXdoYXQgQmFkIiwKICAgICAgIjAiPSJOZXV0cmFsIiwKICAgICAgIjEiPSJTb21ld2hhdCBHb29kIiwKICAgICAgIjIiPSJHb29kIiwKICAgICAgIjMiPSJWZXJ5IEdvb2QiCiAgICApKQoKZ2dwbG90KGxpa2VydC5kYXRhLCBhZXMoeD1xdWFsaXR5X3ByZV90YXNrKSkgKwogIGdlb21fYmFyKGZpbGw9ICJMaWdodCBCbHVlIikgKwogIGZhY2V0X2dyaWQocm93cyA9IHZhcnMoc2NlbmFyaW8pKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gTlVMTCwgYnJlYWtzID0gYygyLDQsNiw4KSwgbGFiZWxzID0gYygiMiIsIjQiLCI2IiwiOCIpKSArCiAgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpKQpgYGAKCiMjIEluaXRpYWwgbW9kZWwKQXMgdGhlIGRhdGEgaXMgY29sbGVjdGVkIGZyb20gYSBsaWtlcnQgc2NhbGUgd2Ugd2lsbCB1c2UgYSBjdW11bGF0aXZlIGZhbWlseSwgaW5kaWNhdGluZyB0aGF0IGVhY2ggbGV2ZWwgb24gdGhlIHNjYWxlIGlzIGFuIGluY3JlbWVudGFsIHN0ZXAuIFRoaXMgbW9kZWwgaXMgYWxzbyBhYmxlIHRvIGZpdCB0aGUgZGF0YSB3ZWxsLgoKV2UgaW5jbHVkZSBgaGlnaF9kZWJ0X3Zlcmlzb25gIGFzIGEgcHJlZGljdG9yIGluIG91ciBtb2RlbCBhcyB0aGlzIHZhcmlhYmxlIHJlcHJlc2VudCB0aGUgdmVyeSBlZmZlY3Qgd2Ugd2FudCB0byBtZWFzdXJlLgpXZSBhbHNvIGluY2x1ZGUgYSB2YXJ5aW5nIGludGVyY2VwdCBmb3IgZWFjaCBpbmRpdmlkdWFsIHRvIHByZXZlbnQgdGhlIG1vZGVsIGZyb20gbGVhcm5pbmcgdG9vIG11Y2ggZnJvbSBzaW5nbGUgcGFydGljaXBhbnRzIHdpdGggZXh0cmVtZSBtZWFzdXJlbWVudHMuCgojIyMgU2VsZWN0aW5nIHByaW9ycyB7LnRhYnNldH0KCldlIGl0ZXJhdGUgb3ZlciB0aGUgbW9kZWwgdW50aWwgd2UgaGF2ZSBzYW5lIHByaW9ycy4KCgojIyMjIEJhc2UgbW9kZWwgd2l0aCBwcmlvcnMKCmBgYHtyIGluaXRpYWwtbW9kZWwtZGVmaW5pdGlvbiwgY2xhc3Muc291cmNlID0gJ2ZvbGQtc2hvdyd9CnNjZW5hcmlvX3F1YWxpdHkud2l0aCA8LSBleHRlbmRhYmxlX21vZGVsKAogIGJhc2VfbmFtZSA9ICJzY2VuYXJpb19xdWFsaXR5IiwKICBiYXNlX2Zvcm11bGEgPSAicXVhbGl0eV9wcmVfdGFzayB+IDEgKyBoaWdoX2RlYnRfdmVyc2lvbiArICgxIHwgc2Vzc2lvbikiLAogIGJhc2VfcHJpb3JzID0gYygKICAgIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIpLAogICAgcHJpb3Iobm9ybWFsKDAsIDIpLCBjbGFzcyA9ICJJbnRlcmNlcHQiKSwKICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9ICJzZCIpCiAgKSwKICBmYW1pbHkgPSBjdW11bGF0aXZlKCksCiAgZGF0YSA9IGQuYm90aF9jb21wbGV0ZWQsCikKYGBgCgojIyMjIERlZmF1bHQgcHJpb3JzCgpgYGB7ciBkZWZhdWx0LXByaW9yc30KcHJpb3Jfc3VtbWFyeShzY2VuYXJpb19xdWFsaXR5LndpdGgob25seV9wcmlvcnM9IFRSVUUpKQpgYGAKCiMjIyMgU2VsZWN0ZWQgcHJpb3JzCgpgYGB7ciBzZWxlY3RlZC1wcmlvcnMsIHdhcm5pbmc9RkFMU0V9CnByaW9yX3N1bW1hcnkoc2NlbmFyaW9fcXVhbGl0eS53aXRoKHNhbXBsZV9wcmlvciA9ICJvbmx5IikpCmBgYAoKIyMjIyBQcmlvciBwcmVkaWN0aXZlIGNoZWNrCgpgYGB7ciBwcmlvcnMtY2hlY2ssIHdhcm5pbmc9RkFMU0V9CnBwX2NoZWNrKHNjZW5hcmlvX3F1YWxpdHkud2l0aChzYW1wbGVfcHJpb3IgPSAib25seSIpLCBuc2FtcGxlcyA9IDIwMCwgdHlwZSA9ICJiYXJzIikKYGBgCgojIyMjIEJldGEgcGFyYW1ldGVyIGluZmx1ZW5jZQoKV2UgY2hvb3NlIGEgYmV0YSBwYXJhbWV0ZXIgcHJpb3JzIGFsbG93aW5nIGZvciB0aGUgYmV0YSBwYXJhbWV0ZXIgdG8gYWNjb3VudCBmb3IgMTAwJSBvZiB0aGUgZWZmZWN0IGJ1dCB0aGF0IGlzIHNrZXB0aWNhbCB0byBzdWNoIHN0cm9uZyBlZmZlY3RzIGZyb20gdGhlIGJldGEgcGFyYW1ldGVyLgoKYGBge3IgcHJpb3JzLWJldGEsIHdhcm5pbmc9RkFMU0V9CnNpbS5zaXplIDwtIDEwMDAKc2ltLmludGVyY2VwdCA8LSBybm9ybShzaW0uc2l6ZSwgMCwgMikKc2ltLmJldGEgPC0gcm5vcm0oc2ltLnNpemUsIDAsIDEpCnNpbS5iZXRhLmRpZmYgPC0gKHBsb2dpcyhzaW0uaW50ZXJjZXB0ICsgc2ltLmJldGEpIC8gcGxvZ2lzKHNpbS5pbnRlcmNlcHQpICogMTAwKSAtIDEwMAoKZGF0YS5mcmFtZSh4ID0gc2ltLmJldGEuZGlmZikgJT4lCiAgZ2dwbG90KGFlcyh4KSkgKwogIGdlb21fZGVuc2l0eSgpICsKICB4bGltKC0xNTAsIDE1MCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJCZXRhIHBhcmFtZXRlciBwcmlvciBpbmZsdWVuY2UiLAogICAgeCA9ICJFc3RpbWF0ZSB3aXRoIGJldGEgYXMgJSBvZiBlc3RpbWF0ZSB3aXRob3V0IGJldGEiLAogICAgeSA9ICJEZW5zaXR5IgogICkKCmBgYAoKIyMjIE1vZGVsIGZpdCB7LnRhYnNldH0KCldlIGNoZWNrIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIGFuZCBjYW4gc2VlIHRoYXQgdGhlIG1vZGVsIHNlZW1zIHRvIGhhdmUgYmVlbiBhYmxlIHRvIGZpdCB0aGUgZGF0YSB3ZWxsLiAKU2FtcGxpbmcgc2VlbXMgdG8gYWxzbyBoYXZlIHdvcmtlZCB3ZWxsIGFzIFJoYXQgdmFsdWVzIGFyZSBjbG9zZSB0byAxIGFuZCB0aGUgc2FtcGxpbmcgcGxvdHMgbG9vayBuaWNlLgoKIyMjIyBQb3N0ZXJpb3IgcHJlZGljdGl2ZSBjaGVjawoKYGBge3IgYmFzZS1wcC1jaGVja30KcHBfY2hlY2soc2NlbmFyaW9fcXVhbGl0eS53aXRoKCksIG5zYW1wbGVzID0gMjAwLCB0eXBlID0gImJhcnMiKQpgYGAKCiMjIyMgU3VtbWFyeQoKYGBge3IgYmFzZS1zdW1tYXJ5fQpzdW1tYXJ5KHNjZW5hcmlvX3F1YWxpdHkud2l0aCgpKQpgYGAKCiMjIyMgU2FtcGxpbmcgcGxvdHMKCmBgYHtyIGJhc2UtcGxvdH0KcGxvdChzY2VuYXJpb19xdWFsaXR5LndpdGgoKSwgYXNrID0gRkFMU0UpCmBgYAoKIyMgTW9kZWwgcHJlZGljdG9yIGV4dGVuc3Rpb25zIHsudGFic2V0fQoKYGBge3IgbW8tcHJpb3JzfQojIGRlZmF1bHQgcHJpb3IgZm9yIG1vbm90b25pYyBwcmVkaWN0b3IKZWRsdmxfcHJpb3IgPC0gcHJpb3IoZGlyaWNobGV0KDIpLCBjbGFzcyA9ICJzaW1vIiwgY29lZiA9ICJtb2VkdWNhdGlvbl9sZXZlbDEiKQpgYGAKCldlIHVzZSBgbG9vYCB0byBjaGVjayBzb21lIHBvc3NpYmxlIGV4dGVuc2lvbnMgb24gdGhlIG1vZGVsLgoKIyMjIE9uZSB2YXJpYWJsZSB7LnRhYnNldH0KCmBgYHtyIG1vZGVsLWV4dGVuc2lvbi0xLCB3YXJuaW5nPUZBTFNFLCBjbGFzcy5zb3VyY2UgPSAnZm9sZC1zaG93J30KbG9vX3Jlc3VsdCA8LSBsb28oCiAgIyBCZW5jaG1hcmsgbW9kZWwocykKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoKSwKICAKICAjIE5ldyBtb2RlbChzKQogIHNjZW5hcmlvX3F1YWxpdHkud2l0aCgid29ya19kb21haW4iKSwKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoIndvcmtfZXhwZXJpZW5jZV9wcm9ncmFtbWluZy5zIiksCiAgc2NlbmFyaW9fcXVhbGl0eS53aXRoKCJ3b3JrX2V4cGVyaWVuY2VfamF2YS5zIiksCiAgc2NlbmFyaW9fcXVhbGl0eS53aXRoKCJlZHVjYXRpb25fZmllbGQiKSwKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoIm1vKGVkdWNhdGlvbl9sZXZlbCkiLCBlZGx2bF9wcmlvciksCiAgc2NlbmFyaW9fcXVhbGl0eS53aXRoKCJ3b3JrcGxhY2VfcGVlcl9yZXZpZXciKSwKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoIndvcmtwbGFjZV90ZF90cmFja2luZyIpLAogIHNjZW5hcmlvX3F1YWxpdHkud2l0aCgid29ya3BsYWNlX3BhaXJfcHJvZ3JhbW1pbmciKSwKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoIndvcmtwbGFjZV9jb2Rpbmdfc3RhbmRhcmRzIiksCiAgc2NlbmFyaW9fcXVhbGl0eS53aXRoKCJzY2VuYXJpbyIpLAogIHNjZW5hcmlvX3F1YWxpdHkud2l0aCgiZ3JvdXAiKQopCmBgYAoKIyMjIyBDb21wYXJpc29uCgpgYGB7ciBtb2RlbC1leHRlbnNpb24tMS1zdW0sIHdhcm5pbmc9RkFMU0V9Cmxvb19yZXN1bHRbMl0KYGBgCgojIyMjIERpYWdub3N0aWNzCgpgYGB7ciBtb2RlbC1leHRlbnNpb24tMS1kaWcsIHdhcm5pbmc9RkFMU0V9Cmxvb19yZXN1bHRbMV0KYGBgCgojIyMgVHdvIHZhcmlhYmxlcyB7LnRhYnNldH0KCmBgYHtyIG1vZGVsLWV4dGVuc2lvbi0yLCB3YXJuaW5nPUZBTFNFLCBjbGFzcy5zb3VyY2UgPSAnZm9sZC1zaG93J30KbG9vX3Jlc3VsdCA8LSBsb28oCiAgIyBCZW5jaG1hcmsgbW9kZWwocykKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoKSwKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoIndvcmtfZXhwZXJpZW5jZV9wcm9ncmFtbWluZy5zIiksCiAgc2NlbmFyaW9fcXVhbGl0eS53aXRoKCJ3b3JrcGxhY2VfY29kaW5nX3N0YW5kYXJkcyIpLAogIHNjZW5hcmlvX3F1YWxpdHkud2l0aCgid29ya3BsYWNlX3BlZXJfcmV2aWV3IiksCiAgc2NlbmFyaW9fcXVhbGl0eS53aXRoKCJ3b3JrX2V4cGVyaWVuY2VfamF2YS5zIiksCiAgCiAgIyBOZXcgbW9kZWwocykKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoYygid29ya19leHBlcmllbmNlX3Byb2dyYW1taW5nLnMiLCAid29ya3BsYWNlX2NvZGluZ19zdGFuZGFyZHMiKSksCiAgc2NlbmFyaW9fcXVhbGl0eS53aXRoKGMoIndvcmtfZXhwZXJpZW5jZV9wcm9ncmFtbWluZy5zIiwgIndvcmtwbGFjZV9wZWVyX3JldmlldyIpKSwKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoYygid29ya19leHBlcmllbmNlX3Byb2dyYW1taW5nLnMiLCAid29ya19leHBlcmllbmNlX2phdmEucyIpKSwKICAKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoYygid29ya3BsYWNlX2NvZGluZ19zdGFuZGFyZHMiLCAid29ya3BsYWNlX3BlZXJfcmV2aWV3IikpLAogIHNjZW5hcmlvX3F1YWxpdHkud2l0aChjKCJ3b3JrcGxhY2VfY29kaW5nX3N0YW5kYXJkcyIsICJ3b3JrX2V4cGVyaWVuY2VfamF2YS5zIikpLAogIAogIHNjZW5hcmlvX3F1YWxpdHkud2l0aChjKCJ3b3JrcGxhY2VfcGVlcl9yZXZpZXciLCAid29ya19leHBlcmllbmNlX2phdmEucyIpKQopCmBgYAoKIyMjIyBDb21wYXJpc29uCgpgYGB7ciBtb2RlbC1leHRlbnNpb24tMi1zdW0sIHdhcm5pbmc9RkFMU0V9Cmxvb19yZXN1bHRbMl0KYGBgCgojIyMjIERpYWdub3N0aWNzCgpgYGB7ciBtb2RlbC1leHRlbnNpb24tMi1kaWcsIHdhcm5pbmc9RkFMU0V9Cmxvb19yZXN1bHRbMV0KYGBgCgojIyMgVGhyZWUgdmFyaWFibGVzIHsudGFic2V0fQoKYGBge3IgbW9kZWwtZXh0ZW5zaW9uLTMsIHdhcm5pbmc9RkFMU0UsIGNsYXNzLnNvdXJjZSA9ICdmb2xkLXNob3cnfQpsb29fcmVzdWx0IDwtIGxvbygKICAjIEJlbmNobWFyayBtb2RlbChzKQogIHNjZW5hcmlvX3F1YWxpdHkud2l0aCgpLAogIAogIHNjZW5hcmlvX3F1YWxpdHkud2l0aCgid29ya19leHBlcmllbmNlX3Byb2dyYW1taW5nLnMiKSwKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoIndvcmtwbGFjZV9jb2Rpbmdfc3RhbmRhcmRzIiksCiAgc2NlbmFyaW9fcXVhbGl0eS53aXRoKCJ3b3JrcGxhY2VfcGVlcl9yZXZpZXciKSwKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoIndvcmtfZXhwZXJpZW5jZV9qYXZhLnMiKSwKICAKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoYygid29ya19leHBlcmllbmNlX3Byb2dyYW1taW5nLnMiLCAid29ya3BsYWNlX2NvZGluZ19zdGFuZGFyZHMiKSksCiAgc2NlbmFyaW9fcXVhbGl0eS53aXRoKGMoIndvcmtfZXhwZXJpZW5jZV9wcm9ncmFtbWluZy5zIiwgIndvcmtwbGFjZV9wZWVyX3JldmlldyIpKSwKICBzY2VuYXJpb19xdWFsaXR5LndpdGgoYygid29ya3BsYWNlX2NvZGluZ19zdGFuZGFyZHMiLCAid29ya19leHBlcmllbmNlX2phdmEucyIpKSwKICAKICAjIE5ldyBtb2RlbChzKQogIHNjZW5hcmlvX3F1YWxpdHkud2l0aChjKCJ3b3JrX2V4cGVyaWVuY2VfcHJvZ3JhbW1pbmcucyIsICJ3b3JrcGxhY2VfY29kaW5nX3N0YW5kYXJkcyIsICJ3b3JrcGxhY2VfcGVlcl9yZXZpZXciKSksCiAgc2NlbmFyaW9fcXVhbGl0eS53aXRoKGMoIndvcmtfZXhwZXJpZW5jZV9wcm9ncmFtbWluZy5zIiwgIndvcmtwbGFjZV9jb2Rpbmdfc3RhbmRhcmRzIiwgIndvcmtfZXhwZXJpZW5jZV9qYXZhLnMiKSksCiAgc2NlbmFyaW9fcXVhbGl0eS53aXRoKGMoIndvcmtfZXhwZXJpZW5jZV9wcm9ncmFtbWluZy5zIiwgIndvcmtfZXhwZXJpZW5jZV9qYXZhLnMiLCAid29ya3BsYWNlX3BlZXJfcmV2aWV3IikpLAogIHNjZW5hcmlvX3F1YWxpdHkud2l0aChjKCJ3b3JrcGxhY2VfY29kaW5nX3N0YW5kYXJkcyIsICJ3b3JrX2V4cGVyaWVuY2VfamF2YS5zIiwgIndvcmtwbGFjZV9wZWVyX3JldmlldyIpKQopCmBgYAoKIyMjIyBDb21wYXJpc29uCgpgYGB7ciBtb2RlbC1leHRlbnNpb24tMy1zdW0sIHdhcm5pbmc9RkFMU0V9Cmxvb19yZXN1bHRbMl0KYGBgCgojIyMjIERpYWdub3N0aWNzCgpgYGB7ciBtb2RlbC1leHRlbnNpb24tMy1kaWcsIHdhcm5pbmc9RkFMU0V9Cmxvb19yZXN1bHRbMV0KYGBgCgojIyBDYW5kaWRhdGUgbW9kZWxzICB7LnRhYnNldH0KV2UgcGljayBzb21lIG9mIG91ciB0b3AgcGVyZm9ybWluZyBtb2RlbHMgYXMgY2FuZGlkYXRlcyBhbmQgaW5zcGVjdCB0aGVtIGNsb3Nlci4KClRoZSBjYW5kaWRhdGUgbW9kZWxzIGFyZSBuYW1lZCBhbmQgbGlzdGVkIGluIG9yZGVyIG9mIGNvbXBsZXhpdHkuCgojIyMgU2NlbmFyaW9RdWFsaXR5MCAgey50YWJzZXR9CgpXZSBzZWxlY3QgdGhlIHNpbXBsZXN0IG1vZGVsIGFzIGEgYmFzZWxpbmUuCgpgYGB7ciBzY2VuYXJpb19xdWFsaXR5MCwgY2xhc3Muc291cmNlID0gJ2ZvbGQtc2hvdycsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnNjZW5hcmlvX3F1YWxpdHkwIDwtIGJybSgKICAicXVhbGl0eV9wcmVfdGFzayB+IDEgKyBoaWdoX2RlYnRfdmVyc2lvbiArICgxIHwgc2Vzc2lvbikiLAogIHByaW9yID0gYygKICAgIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIpLAogICAgcHJpb3Iobm9ybWFsKDAsIDIpLCBjbGFzcyA9ICJJbnRlcmNlcHQiKSwKICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9ICJzZCIpCiAgKSwKICBmYW1pbHkgPSBjdW11bGF0aXZlKCksCiAgZGF0YSA9IGFzLmRhdGEuZnJhbWUoZC5ib3RoX2NvbXBsZXRlZCksCiAgZmlsZSA9ICJmaXRzL3NjZW5hcmlvX3F1YWxpdHkwIiwKICBmaWxlX3JlZml0ID0gIm9uX2NoYW5nZSIsCiAgc2VlZCA9IDIwMjEwNDIxCikKYGBgCgojIyMjIFN1bW1hcnkKCmBgYHtyIHNjZW5hcmlvX3F1YWxpdHkwLXN1bX0Kc3VtbWFyeShzY2VuYXJpb19xdWFsaXR5MCkKYGBgCgojIyMjIFJhbmRvbSBlZmZlY3RzCgpgYGB7ciBzY2VuYXJpb19xdWFsaXR5MC1yYW5lZmZ9CnJhbmVmKHNjZW5hcmlvX3F1YWxpdHkwKQpgYGAKCiMjIyMgU2FtcGxpbmcgcGxvdHMKCmBgYHtyIHNjZW5hcmlvX3F1YWxpdHkwLXBsb3R9CnBsb3Qoc2NlbmFyaW9fcXVhbGl0eTAsIGFzayA9IEZBTFNFKQpgYGAKCiMjIyMgUG9zdGVyaW9yIHByZWRpY3RpdmUgY2hlY2sKCmBgYHtyIHNjZW5hcmlvX3F1YWxpdHkwLXBwfQpwcF9jaGVjayhzY2VuYXJpb19xdWFsaXR5MCwgbnNhbXBsZXMgPSAyMDAsIHR5cGUgPSAiYmFycyIpCmBgYAoKIyMjIFNjZW5hcmlvUXVhbGl0eTEgIHsudGFic2V0fQoKV2Ugc2VsZWN0IHRoZSBiZXN0IHBlcmZvcm1pbmcgbW9kZWwgd2l0aCBvbmUgdmFyaWFibGUuCgpgYGB7ciBzY2VuYXJpb19xdWFsaXR5MSwgY2xhc3Muc291cmNlID0gJ2ZvbGQtc2hvdycsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnNjZW5hcmlvX3F1YWxpdHkxIDwtIGJybSgKICAicXVhbGl0eV9wcmVfdGFzayB+IDEgKyBoaWdoX2RlYnRfdmVyc2lvbiArIHdvcmtfZXhwZXJpZW5jZV9wcm9ncmFtbWluZy5zICsgKDEgfCBzZXNzaW9uKSIsCiAgcHJpb3IgPSBjKAogICAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiksCiAgICBwcmlvcihub3JtYWwoMCwgMiksIGNsYXNzID0gIkludGVyY2VwdCIpLAogICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gInNkIikKICApLAogIGZhbWlseSA9IGN1bXVsYXRpdmUoKSwKICBkYXRhID0gYXMuZGF0YS5mcmFtZShkLmJvdGhfY29tcGxldGVkKSwKICBmaWxlID0gImZpdHMvc2NlbmFyaW9fcXVhbGl0eTEiLAogIGZpbGVfcmVmaXQgPSAib25fY2hhbmdlIiwKICBzZWVkID0gMjAyMTA0MjEKKQpgYGAKCiMjIyMgU3VtbWFyeQoKYGBge3Igc2NlbmFyaW9fcXVhbGl0eTEtc3VtfQpzdW1tYXJ5KHNjZW5hcmlvX3F1YWxpdHkxKQpgYGAKCiMjIyMgUmFuZG9tIGVmZmVjdHMKCmBgYHtyIHNjZW5hcmlvX3F1YWxpdHkxLXJhbmVmZn0KcmFuZWYoc2NlbmFyaW9fcXVhbGl0eTEpCmBgYAoKIyMjIyBTYW1wbGluZyBwbG90cwoKYGBge3Igc2NlbmFyaW9fcXVhbGl0eTEtcGxvdH0KcGxvdChzY2VuYXJpb19xdWFsaXR5MSwgYXNrID0gRkFMU0UpCmBgYAoKIyMjIyBQb3N0ZXJpb3IgcHJlZGljdGl2ZSBjaGVjawoKYGBge3Igc2NlbmFyaW9fcXVhbGl0eTEtcHB9CnBwX2NoZWNrKHNjZW5hcmlvX3F1YWxpdHkxLCBuc2FtcGxlcyA9IDIwMCwgdHlwZSA9ICJiYXJzIikKYGBgCgojIyMgU2NlbmFyaW9RdWFsaXR5MiAgey50YWJzZXR9CgpXZSBzZWxlY3QgdGhlIGJlc3QgcGVyZm9ybWluZyBtb2RlbCB3aXRoIHR3byB2YXJpYWJsZXMuCgpgYGB7ciBzY2VuYXJpb19xdWFsaXR5MiwgY2xhc3Muc291cmNlID0gJ2ZvbGQtc2hvdycsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnNjZW5hcmlvX3F1YWxpdHkyIDwtIGJybSgKICAicXVhbGl0eV9wcmVfdGFzayB+IDEgKyBoaWdoX2RlYnRfdmVyc2lvbiArIHdvcmtfZXhwZXJpZW5jZV9wcm9ncmFtbWluZy5zICsgd29ya3BsYWNlX2NvZGluZ19zdGFuZGFyZHMgKyAoMSB8IHNlc3Npb24pIiwKICBwcmlvciA9IGMoCiAgICBwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gImIiKSwKICAgIHByaW9yKG5vcm1hbCgwLCAyKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiksCiAgICBwcmlvcihleHBvbmVudGlhbCgxKSwgY2xhc3MgPSAic2QiKQogICksCiAgZmFtaWx5ID0gY3VtdWxhdGl2ZSgpLAogIGRhdGEgPSBhcy5kYXRhLmZyYW1lKGQuYm90aF9jb21wbGV0ZWQpLAogIGZpbGUgPSAiZml0cy9zY2VuYXJpb19xdWFsaXR5MiIsCiAgZmlsZV9yZWZpdCA9ICJvbl9jaGFuZ2UiLAogIHNlZWQgPSAyMDIxMDQyMQopCmBgYAoKIyMjIyBTdW1tYXJ5CgpgYGB7ciBzY2VuYXJpb19xdWFsaXR5Mi1zdW19CnN1bW1hcnkoc2NlbmFyaW9fcXVhbGl0eTIpCmBgYAoKIyMjIyBSYW5kb20gZWZmZWN0cwoKYGBge3Igc2NlbmFyaW9fcXVhbGl0eTItcmFuZWZmfQpyYW5lZihzY2VuYXJpb19xdWFsaXR5MikKYGBgCgojIyMjIFNhbXBsaW5nIHBsb3RzCgpgYGB7ciBzY2VuYXJpb19xdWFsaXR5Mi1wbG90fQpwbG90KHNjZW5hcmlvX3F1YWxpdHkyLCBhc2sgPSBGQUxTRSkKYGBgCgojIyMjIFBvc3RlcmlvciBwcmVkaWN0aXZlIGNoZWNrCgpgYGB7ciBzY2VuYXJpb19xdWFsaXR5Mi1wcH0KcHBfY2hlY2soc2NlbmFyaW9fcXVhbGl0eTIsIG5zYW1wbGVzID0gMjAwLCB0eXBlID0gImJhcnMiKQpgYGAKCiMjIyBTY2VuYXJpb1F1YWxpdHkzICB7LnRhYnNldH0KCldlIHNlbGVjdCB0aGUgYmVzdCBwZXJmb3JtaW5nIG1vZGVsIHdpdGggdGhyZWUgdmFyaWFibGVzLgoKYGBge3Igc2NlbmFyaW9fcXVhbGl0eTMsIGNsYXNzLnNvdXJjZSA9ICdmb2xkLXNob3cnLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpzY2VuYXJpb19xdWFsaXR5MyA8LSBicm0oCiAgInF1YWxpdHlfcHJlX3Rhc2sgfiAxICsgaGlnaF9kZWJ0X3ZlcnNpb24gKyB3b3JrX2V4cGVyaWVuY2VfcHJvZ3JhbW1pbmcucyArIHdvcmtwbGFjZV9jb2Rpbmdfc3RhbmRhcmRzICsgd29ya19leHBlcmllbmNlX2phdmEucyArICgxIHwgc2Vzc2lvbikiLAogIHByaW9yID0gYygKICAgIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIpLAogICAgcHJpb3Iobm9ybWFsKDAsIDIpLCBjbGFzcyA9ICJJbnRlcmNlcHQiKSwKICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9ICJzZCIpCiAgKSwKICBmYW1pbHkgPSBjdW11bGF0aXZlKCksCiAgZGF0YSA9IGFzLmRhdGEuZnJhbWUoZC5ib3RoX2NvbXBsZXRlZCksCiAgZmlsZSA9ICJmaXRzL3NjZW5hcmlvX3F1YWxpdHkzIiwKICBmaWxlX3JlZml0ID0gIm9uX2NoYW5nZSIsCiAgc2VlZCA9IDIwMjEwNDIxCikKYGBgCgojIyMjIFN1bW1hcnkKCmBgYHtyIHNjZW5hcmlvX3F1YWxpdHkzLXN1bX0Kc3VtbWFyeShzY2VuYXJpb19xdWFsaXR5MykKYGBgCgojIyMjIFJhbmRvbSBlZmZlY3RzCgpgYGB7ciBzY2VuYXJpb19xdWFsaXR5My1yYW5lZmZ9CnJhbmVmKHNjZW5hcmlvX3F1YWxpdHkzKQpgYGAKCiMjIyMgU2FtcGxpbmcgcGxvdHMKCmBgYHtyIHNjZW5hcmlvX3F1YWxpdHkzLXBsb3R9CnBsb3Qoc2NlbmFyaW9fcXVhbGl0eTMsIGFzayA9IEZBTFNFKQpgYGAKCiMjIyMgUG9zdGVyaW9yIHByZWRpY3RpdmUgY2hlY2sKCmBgYHtyIHNjZW5hcmlvX3F1YWxpdHkzLXBwfQpwcF9jaGVjayhzY2VuYXJpb19xdWFsaXR5MywgbnNhbXBsZXMgPSAyMDAsIHR5cGUgPSAiYmFycyIpCmBgYAoKIyMgRmluYWwgbW9kZWwgCkFsbCBjYW5kaWRhdGUgbW9kZWxzIGxvb2sgbmljZSwgbm9uZSBpcyBzaWduaWZpY2FudGx5IGJldHRlciB0aGFuIHRoZSBvdGhlcnMsIHdlIHdpbGwgcHJvY2VlZCB0aGUgbW9kZWwgY29udGFpbmluZyB3b3JrIGV4cGVyaW5jZSBhcyBpdCBvdGhlcndpc2Ugb3VyZCBiZSBhZGRlZCBpbiB0aGUgbmV4dCBzdGVwOiBgc2NlbmFyaW9fcXVhbGl0eTFgCgoKIyMjIEFsbCBkYXRhIHBvaW50cyB7LnRhYnNldH0KClNvbWUgcGFydGljaXBhbnRzIGRpZCBvbmx5IGNvbXBsZXRlIG9uZSBzY2VuYXJpby4gVGhvc2UgaGFzIGJlZW4gZXhjbHVkZWQgZnJvbSB0aGUgaW5pdGlhbCBkYXRhc2V0IHRvIGltcHJvdmUgc2FtcGxpbmcgb2YgdGhlIG1vZGVscy4gV2UgZG8gaG93ZXZlciB3YW50IHRvIHVzZSBhbGwgZGF0YSB3ZSBjYW4gYW5kIHdpbGwgdGhlcmVmb3JlIHRyeSB0byBmaXQgdGhlIG1vZGVsIHdpdGggdGhlIGNvbXBsZXRlIGRhdGFzZXQuCgpgYGB7ciB2YXJpYXRpb24uYWxsLCBjbGFzcy5zb3VyY2UgPSAnZm9sZC1zaG93J30Kc2NlbmFyaW9fcXVhbGl0eTEuYWxsIDwtIGJybSgKICAicXVhbGl0eV9wcmVfdGFzayB+IDEgKyBoaWdoX2RlYnRfdmVyc2lvbiArIHdvcmtfZXhwZXJpZW5jZV9wcm9ncmFtbWluZy5zICsgKDEgfCBzZXNzaW9uKSIsCiAgcHJpb3IgPSBjKAogICAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiksCiAgICBwcmlvcihub3JtYWwoMCwgMiksIGNsYXNzID0gIkludGVyY2VwdCIpLAogICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gInNkIikKICApLAogIGZhbWlseSA9IGN1bXVsYXRpdmUoKSwKICBkYXRhID0gYXMuZGF0YS5mcmFtZShkLmNvbXBsZXRlZCksCiAgZmlsZSA9ICJmaXRzL3NjZW5hcmlvX3F1YWxpdHkxLmFsbCIsCiAgZmlsZV9yZWZpdCA9ICJvbl9jaGFuZ2UiLAogIHNlZWQgPSAyMDIxMDQyMQopCmBgYAoKIyMjIyBTdW1tYXJ5CgpgYGB7ciB2YXJpYXRpb24uYWxsLXN1bX0Kc3VtbWFyeShzY2VuYXJpb19xdWFsaXR5MS5hbGwpCmBgYAoKIyMjIyBSYW5kb20gZWZmZWN0cwoKYGBge3IgdmFyaWF0aW9uLmFsbC1yYW5lZmZ9CnJhbmVmKHNjZW5hcmlvX3F1YWxpdHkxLmFsbCkKYGBgCgojIyMjIFNhbXBsaW5nIHBsb3RzCgpgYGB7ciB2YXJpYXRpb24uYWxsLXBsb3R9CnBsb3Qoc2NlbmFyaW9fcXVhbGl0eTEuYWxsLCBhc2sgPSBGQUxTRSkKYGBgCgojIyMjIFBvc3RlcmlvciBwcmVkaWN0aXZlIGNoZWNrCgpgYGB7ciB2YXJpYXRpb24uYWxsLXBwfQpwcF9jaGVjayhzY2VuYXJpb19xdWFsaXR5MS5hbGwsIG5zYW1wbGVzID0gMjAwLCB0eXBlID0gImJhcnMiKQpgYGAKCiMjIyBGaW5hbCBtb2RlbAoqIEZpdHRpbmcgdGhlIG1vZGVsIHRvIGFsbCBkYXRhIHBvaW50IGRpZCBub3Qgc2lnbmlmaWNhbnRseSBkYW1hZ2UgdGhlIG1vZGVsIGFuZCB3aWxsIGJlIHVzZWQgYXMgaXMgYSBtb3JlIGZhaXIgcmVwcmVzZW50YXRpb24gb2YgcmVhbGl0eS4KClRoaXMgbWVhbnMgdGhhdCBvdXIgZmluYWwgbW9kZWwsIHdpdGggYWxsIGRhdGEgcG9pbnRzIGFuZCBleHBlcmllbmNlIHByZWRpY3RvcnMsIGlzIGBzY2VuYXJpb19xdWFsaXR5MS5hbGxgCgojIyBJbnRlcnByZXRpbmcgdGhlIG1vZGVsClRvIGJlZ2luIGludGVycHJldGluZyB0aGUgbW9kZWwgd2UgbG9vayBhdCBob3cgaXQncyBwYXJhbWV0ZXJzIHdlcmUgZXN0aW1hdGVkLiBBcyBvdXIgcmVzZWFyY2ggaXMgZm9jdXNlZCBvbiBob3cgdGhlIG91dGNvbWUgb2YgdGhlIG1vZGVsIGlzIGVmZmVjdGVkIHdlIHdpbGwgbWFpbmx5IGFuYWx5emUgdGhlICRcYmV0YSQgcGFyYW1ldGVycy4KCiMjIyAkXGJldGEkIHBhcmFtZXRlcnMKYGBge3IgaW50ZXJwcmV0LWJldGEtcGxvdCwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KbWNtY19hcmVhcyhzY2VuYXJpb19xdWFsaXR5MS5hbGwsIHBhcnMgPSBjKCJiX2hpZ2hfZGVidF92ZXJzaW9uZmFsc2UiLCAiYl93b3JrX2V4cGVyaWVuY2VfcHJvZ3JhbW1pbmcucyIpLCBwcm9iID0gMC45NSkgKyBzY2FsZV95X2Rpc2NyZXRlKCkgKwogIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzPWMoIkhpZ2ggZGVidCB2ZXJzaW9uOiBmYWxzZSIsICJQcm9mZXNzaW9uYWwgcHJvZ3JhbW1pbmcgZXhwZXJpZW5jZSIpKSArCiAgZ2d0aXRsZSgiQmV0YSBwYXJhbWV0ZXJzIGRlbnNpdGllcyBpbiBzY2VuYXJpbyBxdWFsaXR5IG1vZGVsIiwgc3VidGl0bGUgPSAiU2hhZGVkIHJlZ2lvbiBtYXJrcyA5NSUgb2YgdGhlIGRlbnNpdHkuIExpbmUgbWFya3MgdGhlIG1lZGlhbiIpCmBgYAoKYGBge3IgZWZmZWN0LXNpemUtMSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kc2NhbGVfcHJvZ3JhbW1pbmdfZXhwZXJpZW5jZSA8LSBmdW5jdGlvbih4KSB7CiAgKHggLSBtZWFuKGQuY29tcGxldGVkJHdvcmtfZXhwZXJpZW5jZV9wcm9ncmFtbWluZykpLyBzZChkLmNvbXBsZXRlZCR3b3JrX2V4cGVyaWVuY2VfcHJvZ3JhbW1pbmcpCn0KdW5zY2FsZV9wcm9ncmFtbWluZ19leHBlcmllbmNlIDwtIGZ1bmN0aW9uKHgpIHsKICB4ICogc2QoZC5jb21wbGV0ZWQkd29ya19leHBlcmllbmNlX3Byb2dyYW1taW5nKSArIG1lYW4oZC5jb21wbGV0ZWQkd29ya19leHBlcmllbmNlX3Byb2dyYW1taW5nKQp9Cgpwb3N0X3NldHRpbmdzIDwtIGV4cGFuZC5ncmlkKAogIGhpZ2hfZGVidF92ZXJzaW9uID0gYygiZmFsc2UiLCAidHJ1ZSIpLAogIHNlc3Npb24gPSBOQSwKICB3b3JrX2V4cGVyaWVuY2VfcHJvZ3JhbW1pbmcucyA9IHNhcHBseShjKDAsIDMsIDEwLCAyNSwgNDApLCBzY2FsZV9wcm9ncmFtbWluZ19leHBlcmllbmNlKQopCgpwb3N0IDwtIHBvc3Rlcmlvcl9wcmVkaWN0KHNjZW5hcmlvX3F1YWxpdHkxLmFsbCwgbmV3ZGF0YSA9IHBvc3Rfc2V0dGluZ3MpICU+JQogIG1lbHQodmFsdWUubmFtZSA9ICJlc3RpbWF0ZSIsIHZhcm5hbWVzID0gYygic2FtcGxlX251bWJlciIsICJzZXR0aW5nc19pZCIpKSAlPiUKICBsZWZ0X2pvaW4oCiAgICByb3dpZF90b19jb2x1bW4ocG9zdF9zZXR0aW5ncywgdmFyPSAic2V0dGluZ3NfaWQiKSwKICAgIGJ5ID0gInNldHRpbmdzX2lkIgogICkgJT4lCiAgbXV0YXRlKHdvcmtfZXhwZXJpZW5jZV9wcm9ncmFtbWluZyA9IHVuc2NhbGVfcHJvZ3JhbW1pbmdfZXhwZXJpZW5jZSh3b3JrX2V4cGVyaWVuY2VfcHJvZ3JhbW1pbmcucykpICU+JQogIHNlbGVjdCgKICAgIGVzdGltYXRlLAogICAgaGlnaF9kZWJ0X3ZlcnNpb24sCiAgICB3b3JrX2V4cGVyaWVuY2VfcHJvZ3JhbW1pbmcKICApJT4lCiAgbXV0YXRlKGVzdGltYXRlID0gZXN0aW1hdGUpCgoKcG9zdC5uaWNlIDwtIHBvc3QgJT4lICBtdXRhdGVfYXQoImVzdGltYXRlIiwgZnVuY3Rpb24oeCkgcmV2YWx1ZShhcy5vcmRlcmVkKHgpLCBjKAogICAgICAiMSI9IlZlcnkgQmFkIiwKICAgICAgIjIiPSJCYWQiLAogICAgICAiMyI9IlNvbWV3aGF0IEJhZCIsCiAgICAgICI0Ij0iTmV1dHJhbCIsCiAgICAgICI1Ij0iU29tZXdoYXQgR29vZCIsCiAgICAgICI2Ij0iR29vZCIsCiAgICAgICI3Ij0iVmVyeSBHb29kIgogICAgKSkpCgpwb3N0Lm5pY2UkaGlnaF9kZWJ0X3ZlcnNpb24gPC0gcmV2YWx1ZShwb3N0Lm5pY2UkaGlnaF9kZWJ0X3ZlcnNpb24sIGMoCiAgICAgICJ0cnVlIj0iSGlnaCBEZWJ0IiwKICAgICAgImZhbHNlIj0iTG93IERlYnQiCiAgICApKQoKCgpwb3N0Lm5pY2UuMyA8LSBmaWx0ZXIocG9zdC5uaWNlLCB3b3JrX2V4cGVyaWVuY2VfcHJvZ3JhbW1pbmcgPT0gMykKCnZsaW5lLmRhdGEuMyA8LSBwb3N0Lm5pY2UuMyAlPiUKICAgICAgICAgICAgICBncm91cF9ieShoaWdoX2RlYnRfdmVyc2lvbikgJT4lCiAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXplKHogPSBtZWFuKGFzLm51bWVyaWMoZXN0aW1hdGUpKSkKCnNwcmludGYoIkVzdGltYXRpb25zIGZvciAzIHllYXJzIGV4cGVyaWVuY2UiKQoKcG9zdC5uaWNlLjMgJT4lCiAgICBnZ3Bsb3QoKSArCiAgICAgIGdlb21faGlzdG9ncmFtKGFlcyh4PWVzdGltYXRlKSxmaWxsPSAiTGlnaHQgQmx1ZSIsIHN0YXQgPSAiY291bnQiKSArCiAgICAgIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSB6KSwKICAgICAgICAgICAgdmxpbmUuZGF0YS4zLAogICAgICAgICAgICAgY29sID0gIkRhcmsgQmx1ZSIsCiAgICAgICAgICAgICBsd2QgPSAxKSsKICAgICAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhoaWdoX2RlYnRfdmVyc2lvbikpICsKICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gTlVMTCwgYnJlYWtzID0gc2FwcGx5KGMoMC4xLCAwLjIsIDAuMywgMC40KSwgZnVuY3Rpb24oeCkgeCpucm93KHBvc3QubmljZS4zKSAvIDIpLCBsYWJlbHMgPSBjKCIxMCUiLCIyMCUiLCIzMCUiLCI0MCUiKSkgKwogICAgICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpKQoKcG9zdC5uaWNlLjI1IDwtIGZpbHRlcihwb3N0Lm5pY2UsIHdvcmtfZXhwZXJpZW5jZV9wcm9ncmFtbWluZyA9PSAyNSkKCnZsaW5lLmRhdGEuMjUgPC0gcG9zdC5uaWNlLjI1ICU+JQogICAgICAgICAgICAgIGdyb3VwX2J5KGhpZ2hfZGVidF92ZXJzaW9uKSAlPiUKICAgICAgICAgICAgICAgICAgICBzdW1tYXJpemUoeiA9IG1lYW4oYXMubnVtZXJpYyhlc3RpbWF0ZSkpKQoKc3ByaW50ZigiRXN0aW1hdGlvbnMgZm9yIDI1IHllYXJzIGV4cGVyaWVuY2UiKQoKcG9zdC5uaWNlLjI1ICU+JQogICAgZ2dwbG90KCkgKwogICAgICBnZW9tX2hpc3RvZ3JhbShhZXMoeD1lc3RpbWF0ZSksZmlsbD0gIkxpZ2h0IEJsdWUiLCBzdGF0ID0gImNvdW50IikgKwogICAgICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0geiksCiAgICAgICAgICAgIHZsaW5lLmRhdGEuMjUsCiAgICAgICAgICAgICBjb2wgPSAiRGFyayBCbHVlIiwKICAgICAgICAgICAgIGx3ZCA9IDEpKwogICAgICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKGhpZ2hfZGVidF92ZXJzaW9uKSkgKwogICAgICAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBOVUxMLCBicmVha3MgPSBzYXBwbHkoYygwLjEsIDAuMiwgMC4zLCAwLjQpLCBmdW5jdGlvbih4KSB4Km5yb3cocG9zdC5uaWNlLjI1KSAvIDIpLCBsYWJlbHMgPSBjKCIxMCUiLCIyMCUiLCIzMCUiLCI0MCUiKSkgKwogICAgICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpKQoKYGBgCgpgYGB7ciBlZmZlY3Qtc2l6ZS1kaWZmLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpwb3N0LmRpZmYgPC0gcG9zdCAlPiUgZmlsdGVyKGhpZ2hfZGVidF92ZXJzaW9uID09ICJ0cnVlIikKcG9zdC5kaWZmJGVzdGltYXRlID0gcG9zdC5kaWZmJGVzdGltYXRlIC0gIGZpbHRlcihwb3N0LCBoaWdoX2RlYnRfdmVyc2lvbiA9PSAiZmFsc2UiKSRlc3RpbWF0ZQoKcG9zdC5kaWZmICU+JQogIGdncGxvdChhZXMoeD1lc3RpbWF0ZSkpICsKICBnZW9tX2JveHBsb3QocXVhbnRpbGVfbGluZXMgPSBUUlVFLCBxdWFudGlsZV9mdW4gPSBoZGksIHZsaW5lX2xpbmV0eXBlID0gMikgKwogIGZhY2V0X2dyaWQocm93cyA9IHZhcnMod29ya19leHBlcmllbmNlX3Byb2dyYW1taW5nKSkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJTY2VuYXJpbyByYXRpbmcgZGlmZiAvIHllYXJzIG9mIHByb2dyYW1taW5nIGV4cGVyaWVuY2UiLAogICAgc3VidGl0bGUgPSAiRGlmZmVyZW5jZSBhczogaGlnaCBkZWJ0IHJhdGluZyAtIGxvdyBkZWJ0IHJhdGluZyIsCiAgICB4ID0gIlJhdGluZyBkaWZmZXJlbmNlIgogICkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBOVUxMKQpgYGAKCldlIGNhbiB0aGVuIHByb2NlZWQgdG8gY2FsY3VsYXRlIHNvbWUgbGlrZWxpaG9vZHM6CgpgYGB7ciwgY2xhc3Muc291cmNlID0gJ2ZvbGQtc2hvdyd9CnBvc3QuZGlmZi4xMCA8LSBwb3N0LmRpZmYgJT4lIGZpbHRlcih3b3JrX2V4cGVyaWVuY2VfcHJvZ3JhbW1pbmcgPT0gMTApCmhpZ2hfZGVidF9yYXRlZF9oaWdoZXIgPC0gc3VtKHBvc3QuZGlmZi4xMCRlc3RpbWF0ZSA+IDApCmxvd19kZWJ0X3JhdGVkX2hpZ2hlciA8LSBzdW0ocG9zdC5kaWZmLjEwJGVzdGltYXRlIDwgMCkKeCA8LSBsb3dfZGVidF9yYXRlZF9oaWdoZXIgLyBoaWdoX2RlYnRfcmF0ZWRfaGlnaGVyCngKYGBgCgpQYXJ0aWNpcGFudHMgd2l0aCAxMCB5ZWFycyBvZiBwcm9mZXNzaW9uYWwgcHJvZ3JhbW1pbmcgZXhwZXJpZW5jZSB3ZXJlIGByIHNjYWxlczo6bGFiZWxfcGVyY2VudCgpKHggLSAxKWAgbW9yZSBsaWtlbHkgdG8gcmF0ZSB0aGUgaGlnaCBkZWJ0IHZlcnNpb24gc2NlbmFyaW8gYXMgd29yc2UgdGhhbiB0aGVuIHRoZXkgd2VyZSB0byByYXRlIHRoZSBsb3cgZGVidCB2ZXJzaW9uIHNjZW5hcmlvIGFzIHdvcnNlLg==