library(tidyverse)
library(targets)
library(tidybayes)
library(glue)
library(brms)
library(scales)
library(kableExtra)
library(modelsummary)
library(here)

# Generated via random.org
set.seed(9936)

# Load data and models
withr::with_dir(here::here(), {
  source(tar_read(plot_funs))
  
  # Load big list of models
  model_df <- tar_read(model_df) %>% 
    filter(!str_detect(model, "v2csreprss"))
  
  # Load actual model objects
  tar_load(c(m_pts_baseline, m_pts_total, m_pts_total_new, 
             m_pts_advocacy, m_pts_entry, m_pts_funding,
             m_lhr_baseline, m_lhr_total, m_lhr_total_new, 
             m_lhr_advocacy, m_lhr_entry, m_lhr_funding))
  
  # Load regression tables
  tar_load(c(models_tbl_e1a, models_tbl_e1b))
  
  # Load lookup list for coefficients in regression tables
  tar_load(coef_list)
})
models <- model_df %>% 
  filter(!str_detect(model, "train")) %>% 
  mutate(actual_model = model %>% map(~eval(rlang::sym(.)))) %>% 
  mutate(across(c(outcome_var, explan_var, family), ~fct_inorder(., ordered = TRUE)))

coefs_clean <- tribble(
  ~coef, ~coef_clean,
  "b_barriers_total", "Total legal barriers",
  "b_barriers_total_lag1", "Total legal barriers (t - 1)",
  "b_barriers_total_new", "New legal barriers",
  "b_barriers_total_new_lag1", "New legal barriers (t - 1)",
  "b_advocacy", "Barriers to advocacy",
  "b_advocacy_lag1", "Barriers to advocacy (t - 1)",
  "b_entry", "Barriers to entry",
  "b_entry_lag1", "Barriers to entry (t - 1)",
  "b_funding", "Barriers to funding",
  "b_funding_lag1", "Barriers to funding (t - 1)",
  "b_barriers_total_within", "Total legal barriers (within)",
  "b_barriers_total_lag1_within", "Total legal barriers (within; t - 1)",
  "b_advocacy_within", "Barriers to advocacy (within)",
  "b_advocacy_lag1_within", "Barriers to advocacy (within; t - 1)",
  "b_entry_within", "Barriers to entry (within)",
  "b_entry_lag1_within", "Barriers to entry (within; t - 1)",
  "b_funding_within", "Barriers to funding (within)",
  "b_funding_lag1_within", "Barriers to funding (within; t - 1)"
) %>% 
  mutate(across(everything(), ~fct_inorder(., ordered = TRUE))) %>% 
  mutate(lagging = str_detect(coef, "lag1"))

Confounders

Time-varying:

  • v2x_polyarchy
  • GDP_log
  • population_log
  • armed_conflict
  • un_trade_pct_gdp

E1a: NGO laws and political terror

Results table

# Build nicer column names
models_for_table_e1a <- models %>% 
  filter(outcome_var == "Political terror") %>% 
  mutate(outcome_var = recode(outcome_var, "Political terror" = "PTS"),
         explan_var = recode(explan_var, "Civil society repression" = "CS repression")) %>% 
  mutate(model_name = glue("{outcome_var} (t + 1)<br>({explan_var})"))

# Make a named vector of original model names and nice names
models_names_table_e1a <- models_for_table_e1a %>% 
  pull(model_name) %>% 
  set_names(models_for_table_e1a$model)

# Rename the columns
names(models_tbl_e1a) <- recode(names(models_tbl_e1a), 
                                !!!models_names_table_e1a)

modelsummary(models_tbl_e1a,
             statistic = "[{conf.low}, {conf.high}]",
             coef_map = coef_list,
             gof_omit = "ELPD",
             escape = FALSE,
             notes = list("Posterior means; 95% credible intervals in brackets"))
PTS (t + 1)
(Baseline)
PTS (t + 1)
(Total legal barriers)
PTS (t + 1)
(New legal barriers)
PTS (t + 1)
(Barriers to advocacy)
PTS (t + 1)
(Barriers to entry)
PTS (t + 1)
(Barriers to funding)
Total legal barriers 0.157
[−0.019, 0.308]
Total legal barriers (t - 1) 0.021
[−0.144, 0.186]
New legal barriers 0.069
[−0.101, 0.226]
New legal barriers (t - 1) −0.071
[−0.233, 0.095]
Barriers to advocacy 0.457
[−0.160, 1.100]
Barriers to advocacy (t - 1) −0.092
[−0.730, 0.596]
Barriers to entry 0.270
[−0.068, 0.580]
Barriers to entry (t - 1) 0.056
[−0.256, 0.404]
Barriers to funding 0.273
[−0.070, 0.616]
Barriers to funding (t - 1) 0.066
[−0.284, 0.418]
PTS = 2 2.399 2.250 2.213 2.288 2.259 2.257
[2.112, 2.688] [1.948, 2.542] [1.932, 2.539] [1.990, 2.583] [1.981, 2.572] [1.973, 2.580]
PTS = 3 4.423 4.221 4.150 4.305 4.242 4.236
[4.057, 4.798] [3.857, 4.609] [3.786, 4.562] [3.926, 4.685] [3.867, 4.630] [3.868, 4.625]
PTS = 4 6.518 6.227 6.223 6.344 6.255 6.215
[6.035, 6.978] [5.720, 6.696] [5.723, 6.713] [5.887, 6.878] [5.776, 6.733] [5.727, 6.692]
PTS = 5 8.861 8.566 8.522 8.628 8.588 8.535
[8.272, 9.502] [7.924, 9.193] [7.841, 9.182] [8.012, 9.278] [7.977, 9.223] [7.906, 9.135]
Polyarchy index −2.220 −2.215 −2.667 −2.302 −2.369 −2.239
[−2.889, −1.609] [−2.957, −1.555] [−3.367, −1.974] [−2.959, −1.610] [−3.095, −1.725] [−2.962, −1.589]
Log GDP per capita −0.397 −0.471 −0.419 −0.434 −0.443 −0.471
[−0.539, −0.269] [−0.621, −0.320] [−0.573, −0.267] [−0.574, −0.288] [−0.584, −0.299] [−0.626, −0.321]
Trade as % of GDP −0.368 −0.438 −0.380 −0.431 −0.422 −0.415
[−0.668, −0.068] [−0.751, −0.118] [−0.689, −0.017] [−0.743, −0.096] [−0.722, −0.097] [−0.729, −0.096]
Armed conflict 1.010 1.083 1.050 1.067 1.077 1.089
[0.720, 1.326] [0.767, 1.411] [0.732, 1.369] [0.737, 1.363] [0.770, 1.375] [0.769, 1.392]
Num.Obs. 3736 3594 3438 3594 3594 3594
R2 0.805 0.807 0.807 0.806 0.807 0.807
R2 Marg. 0.711 0.711 0.697 0.709 0.710 0.706
LOOIC 5456.1 5194.4 4960.8 5219.3 5199.7 5197.7
LOOIC s.e. 98.5 97.0 95.0 97.2 97.2 97.0
WAIC 5455.6 5193.8 4960.0 5218.6 5199.0 5197.0
Posterior means; 95% credible intervals in brackets

Coefficients

coef_plots <- models %>% 
  filter(str_detect(model, "pts_"), !str_detect(model, "baseline")) %>% 
  mutate(coef_draws = map(
    actual_model, 
    ~gather_draws(model = ., `.*barriers.*|.*advocacy.*|.*entry.*|.*funding.*`, regex = TRUE))) %>% 
  select(-actual_model) %>% 
  unnest(coef_draws) %>% 
  left_join(coefs_clean, by = c(".variable" = "coef"))

coef_plots %>% 
  ggplot(aes(y = fct_rev(coef_clean), x = .value)) +
  stat_halfeye(aes(alpha = lagging), .width = c(0.8, 0.95)) +
  geom_vline(xintercept = 0) +
  guides(fill = "none", alpha = "none") +
  scale_alpha_manual(values = c(1, 0.4)) +
  labs(x = "Coefficient", y = NULL) +
  theme_ngo()

Marginal effects

plot_pts_vars_lookup <- tribble(
  ~model, ~plot_var, ~plot_var_nice,
  "m_pts_total", "barriers_total", "Total legal barriers",
  "m_pts_total_new", "barriers_total_new", "New legal barriers",
  "m_pts_advocacy", "advocacy", "Barriers to advocacy",
  "m_pts_entry", "entry", "Barriers to entry",
  "m_pts_funding", "funding", "Barriers to funding"
) %>% 
  mutate(plot_var_nice = fct_inorder(plot_var_nice, ordered = TRUE))

mfx <- models %>% 
  filter(str_detect(model, "_pts"), !str_detect(model, "baseline|new")) %>% 
  left_join(plot_pts_vars_lookup, by = "model") %>% 
  mutate(fx = map2(actual_model, plot_var, 
                   ~conditional_effects(.x, effects = .y,
                                        categorical = TRUE)[[1]])) %>% 
  select(-actual_model) %>% 
  unnest(fx)

mfx %>% 
  mutate(x_rounded = floor(effect1__)) %>% 
  group_by(x_rounded, effect2__, plot_var_nice) %>% 
  slice(1) %>% 
  ungroup() %>% 
  ggplot(aes(x = x_rounded, y = estimate__, color = effect2__)) +
  geom_pointrange(aes(ymin = lower__, ymax = upper__),
                  position = position_dodge(width = 0.2),
                  fatten = 1) +
  scale_x_continuous(breaks = 0:9) +
  scale_y_continuous(labels = percent_format(accuracy = 1)) +
  scale_color_viridis_d(option = "viridis", end = 0.95) +
  labs(x = "Count of legal barriers\n",
       y = "Predicted probability of category",
       color = "Political terror scale", fill = "Political terror scale") + 
  facet_wrap(vars(plot_var_nice), scales = "free_x") +
  theme_ngo() +
  theme(panel.grid.major.x = element_blank())

 

E1b: NGO laws and latent human rights

Results table

models_for_table_e1b <- models %>% 
  filter(outcome_var == "Latent human rights") %>% 
  mutate(model_name = glue("{outcome_var} (t + 1)<br>({explan_var})"))

model_names_tbl_e1b <- models_for_table_e1b %>% 
  pull(model_name) %>% 
  set_names(models_for_table_e1b$model)

names(models_tbl_e1b) <- recode(names(models_tbl_e1b), 
                                !!!model_names_tbl_e1b)

modelsummary(models_tbl_e1b,
             statistic = "[{conf.low}, {conf.high}]",
             coef_map = coef_list,
             gof_omit = "ELPD",
             escape = FALSE,
             notes = list("Posterior means; 95% credible intervals in brackets"))
Latent human rights (t + 1)
(Baseline)
Latent human rights (t + 1)
(Total legal barriers)
Latent human rights (t + 1)
(New legal barriers)
Latent human rights (t + 1)
(Barriers to advocacy)
Latent human rights (t + 1)
(Barriers to entry)
Latent human rights (t + 1)
(Barriers to funding)
Total legal barriers −0.013
[−0.031, 0.005]
Total legal barriers (t - 1) 0.007
[−0.012, 0.025]
New legal barriers −0.011
[−0.029, 0.008]
New legal barriers (t - 1) −0.001
[−0.020, 0.018]
Barriers to advocacy −0.024
[−0.092, 0.049]
Barriers to advocacy (t - 1) 0.007
[−0.064, 0.080]
Barriers to entry −0.027
[−0.062, 0.008]
Barriers to entry (t - 1) 0.019
[−0.018, 0.053]
Barriers to funding −0.016
[−0.053, 0.021]
Barriers to funding (t - 1) 0.006
[−0.030, 0.046]
Latent human rights (t) 0.965 0.964 0.965 0.964 0.964 0.965
[0.954, 0.975] [0.951, 0.975] [0.953, 0.976] [0.952, 0.975] [0.951, 0.976] [0.952, 0.975]
Polyarchy index 0.090 0.074 0.096 0.080 0.082 0.076
[0.053, 0.130] [0.032, 0.115] [0.055, 0.141] [0.040, 0.126] [0.040, 0.126] [0.032, 0.117]
Log GDP per capita 0.006 0.008 0.006 0.007 0.007 0.008
[0.000, 0.014] [−0.001, 0.015] [−0.001, 0.014] [0.000, 0.015] [−0.001, 0.015] [0.000, 0.016]
Trade as % of GDP 0.022 0.024 0.023 0.024 0.024 0.023
[0.003, 0.041] [0.002, 0.044] [0.004, 0.045] [0.004, 0.044] [0.003, 0.044] [0.004, 0.043]
Armed conflict −0.007 −0.004 −0.002 −0.005 −0.004 −0.005
[−0.031, 0.019] [−0.029, 0.021] [−0.028, 0.024] [−0.032, 0.019] [−0.030, 0.022] [−0.030, 0.022]
Intercept −0.076 −0.073 −0.080 −0.075 −0.073 −0.076
[−0.135, −0.019] [−0.136, −0.010] [−0.144, −0.021] [−0.133, −0.011] [−0.138, −0.010] [−0.136, −0.014]
Num.Obs. 3769 3609 3449 3609 3609 3609
R2 0.968 0.969 0.968 0.968 0.969 0.968
R2 Marg. 0.968 0.968 0.967 0.968 0.968 0.968
LOOIC 118.9 47.9 135.9 49.4 51.5 49.3
LOOIC s.e. 352.5 351.7 342.5 351.1 352.4 351.2
WAIC 118.3 46.5 134.6 48.4 50.1 48.6
RMSE 0.79 0.79 0.79 0.79 0.79 0.79
Posterior means; 95% credible intervals in brackets

Coefficients

coef_plots <- models %>% 
  filter(str_detect(model, "lhr"), !str_detect(model, "baseline")) %>% 
  mutate(coef_draws = map(
    actual_model, 
    ~gather_draws(model = ., `.*barriers.*|.*advocacy.*|.*entry.*|.*funding.*`, regex = TRUE))) %>% 
  select(-actual_model) %>% 
  unnest(coef_draws) %>% 
  left_join(coefs_clean, by = c(".variable" = "coef"))

coef_plots %>% 
  ggplot(aes(y = fct_rev(coef_clean), x = .value)) +
  stat_halfeye(aes(alpha = lagging), .width = c(0.8, 0.95)) +
  geom_vline(xintercept = 0) +
  guides(fill = "none", alpha = "none") +
  scale_alpha_manual(values = c(1, 0.4)) +
  labs(x = "Coefficient", y = NULL) +
  theme_ngo()

Marginal effects

plot_lhr_vars_lookup <- tribble(
  ~model, ~plot_var, ~plot_var_nice,
  "m_lhr_total", "barriers_total", "Total legal barriers",
  "m_lhr_total_new", "barriers_total_new", "New legal barriers",
  "m_lhr_advocacy", "advocacy", "Advocacy",
  "m_lhr_entry", "entry", "Entry",
  "m_lhr_funding", "funding", "Funding"
) %>% 
  mutate(plot_var_nice = fct_inorder(plot_var_nice, ordered = TRUE))

mfx <- models %>% 
  filter(str_detect(model, "lhr"), !str_detect(model, "new|baseline")) %>% 
  left_join(plot_lhr_vars_lookup, by = "model") %>% 
  mutate(fx = map2(actual_model, plot_var, 
                   ~conditional_effects(.x, effects = .y)[[1]])) %>% 
  select(-actual_model) %>% 
  unnest(fx)

mfx %>% 
  mutate(x_rounded = floor(effect1__)) %>% 
  group_by(x_rounded, plot_var_nice) %>% 
  slice(1) %>% 
  ungroup() %>% 
  ggplot(aes(x = x_rounded, y = estimate__, color = plot_var_nice)) +
  geom_line(size = 0.5, color = "grey90") +
  geom_pointrange(aes(ymin = lower__, ymax = upper__),
                  fatten = 1) +
  scale_x_continuous(breaks = 0:9) +
  scale_color_viridis_d(option = "plasma", end = 0.8) +
  guides(color = "none") +
  labs(x = "Count of legal barriers",
       y = "Predicted latent human rights value\n(higher values = better human rights)") +
  facet_grid(cols = vars(plot_var_nice), scales = "free_x", space = "free_x") +
  theme_ngo() +
  theme(panel.grid.major.x = element_blank())

LS0tCnRpdGxlOiAiRX4xfjogTGF3cyBwcmVkaWN0IGRldGVyaW9yYXRpbmcgaHVtYW4gcmlnaHRzIgphdXRob3I6ICJTdXBhcm5hIENoYXVkaHJ5IGFuZCBBbmRyZXcgSGVpc3MiCmRhdGU6ICJMYXN0IHJ1bjogYHIgZm9ybWF0KFN5cy50aW1lKCksICclRicpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9mb2xkaW5nOiBoaWRlCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmtuaXRfcHJpbnQuZGF0YS5mcmFtZSA8LSBmdW5jdGlvbih4LCAuLi4pIHsKICByZXMgPC0gcGFzdGUoYygnJywgJycsIGthYmxlX3N0eWxpbmcoa2FibGUoeCwgYm9va3RhYnMgPSBUUlVFKSkpLCBjb2xsYXBzZSA9ICdcbicpCiAgYXNpc19vdXRwdXQocmVzKQp9CgpyZWdpc3RlclMzbWV0aG9kKCJrbml0X3ByaW50IiwgImRhdGEuZnJhbWUiLCBrbml0X3ByaW50LmRhdGEuZnJhbWUpCnJlZ2lzdGVyUzNtZXRob2QoImtuaXRfcHJpbnQiLCAiZ3JvdXBlZF9kZiIsIGtuaXRfcHJpbnQuZGF0YS5mcmFtZSkKCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcucmV0aW5hID0gMywKICAgICAgICAgICAgICAgICAgICAgIHRpZHkub3B0cyA9IGxpc3Qod2lkdGguY3V0b2ZmID0gMTIwKSwgICMgRm9yIGNvZGUKICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMod2lkdGggPSA5MCksICAjIEZvciBvdXRwdXQKICAgICAgICAgICAgICAgICAgICAgIGZpZy5hc3AgPSAwLjYxOCwgZmlnLndpZHRoID0gNywgCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYWxpZ24gPSAiY2VudGVyIiwgb3V0LndpZHRoID0gIjg1JSIpCgpvcHRpb25zKGRwbHlyLnN1bW1hcmlzZS5pbmZvcm0gPSBGQUxTRSwKICAgICAgICBrbml0ci5rYWJsZS5OQSA9ICIiKQpgYGAKCmBgYHtyIGxvYWQtbGlicmFyaWVzLWRhdGEsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHRhcmdldHMpCmxpYnJhcnkodGlkeWJheWVzKQpsaWJyYXJ5KGdsdWUpCmxpYnJhcnkoYnJtcykKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkoa2FibGVFeHRyYSkKbGlicmFyeShtb2RlbHN1bW1hcnkpCmxpYnJhcnkoaGVyZSkKCiMgR2VuZXJhdGVkIHZpYSByYW5kb20ub3JnCnNldC5zZWVkKDk5MzYpCgojIExvYWQgZGF0YSBhbmQgbW9kZWxzCndpdGhyOjp3aXRoX2RpcihoZXJlOjpoZXJlKCksIHsKICBzb3VyY2UodGFyX3JlYWQocGxvdF9mdW5zKSkKICAKICAjIExvYWQgYmlnIGxpc3Qgb2YgbW9kZWxzCiAgbW9kZWxfZGYgPC0gdGFyX3JlYWQobW9kZWxfZGYpICU+JSAKICAgIGZpbHRlcighc3RyX2RldGVjdChtb2RlbCwgInYyY3NyZXByc3MiKSkKICAKICAjIExvYWQgYWN0dWFsIG1vZGVsIG9iamVjdHMKICB0YXJfbG9hZChjKG1fcHRzX2Jhc2VsaW5lLCBtX3B0c190b3RhbCwgbV9wdHNfdG90YWxfbmV3LCAKICAgICAgICAgICAgIG1fcHRzX2Fkdm9jYWN5LCBtX3B0c19lbnRyeSwgbV9wdHNfZnVuZGluZywKICAgICAgICAgICAgIG1fbGhyX2Jhc2VsaW5lLCBtX2xocl90b3RhbCwgbV9saHJfdG90YWxfbmV3LCAKICAgICAgICAgICAgIG1fbGhyX2Fkdm9jYWN5LCBtX2xocl9lbnRyeSwgbV9saHJfZnVuZGluZykpCiAgCiAgIyBMb2FkIHJlZ3Jlc3Npb24gdGFibGVzCiAgdGFyX2xvYWQoYyhtb2RlbHNfdGJsX2UxYSwgbW9kZWxzX3RibF9lMWIpKQogIAogICMgTG9hZCBsb29rdXAgbGlzdCBmb3IgY29lZmZpY2llbnRzIGluIHJlZ3Jlc3Npb24gdGFibGVzCiAgdGFyX2xvYWQoY29lZl9saXN0KQp9KQpgYGAKCmBgYHtyIGNsZWFuLWRhdGF9Cm1vZGVscyA8LSBtb2RlbF9kZiAlPiUgCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KG1vZGVsLCAidHJhaW4iKSkgJT4lIAogIG11dGF0ZShhY3R1YWxfbW9kZWwgPSBtb2RlbCAlPiUgbWFwKH5ldmFsKHJsYW5nOjpzeW0oLikpKSkgJT4lIAogIG11dGF0ZShhY3Jvc3MoYyhvdXRjb21lX3ZhciwgZXhwbGFuX3ZhciwgZmFtaWx5KSwgfmZjdF9pbm9yZGVyKC4sIG9yZGVyZWQgPSBUUlVFKSkpCgpjb2Vmc19jbGVhbiA8LSB0cmliYmxlKAogIH5jb2VmLCB+Y29lZl9jbGVhbiwKICAiYl9iYXJyaWVyc190b3RhbCIsICJUb3RhbCBsZWdhbCBiYXJyaWVycyIsCiAgImJfYmFycmllcnNfdG90YWxfbGFnMSIsICJUb3RhbCBsZWdhbCBiYXJyaWVycyAodCAtIDEpIiwKICAiYl9iYXJyaWVyc190b3RhbF9uZXciLCAiTmV3IGxlZ2FsIGJhcnJpZXJzIiwKICAiYl9iYXJyaWVyc190b3RhbF9uZXdfbGFnMSIsICJOZXcgbGVnYWwgYmFycmllcnMgKHQgLSAxKSIsCiAgImJfYWR2b2NhY3kiLCAiQmFycmllcnMgdG8gYWR2b2NhY3kiLAogICJiX2Fkdm9jYWN5X2xhZzEiLCAiQmFycmllcnMgdG8gYWR2b2NhY3kgKHQgLSAxKSIsCiAgImJfZW50cnkiLCAiQmFycmllcnMgdG8gZW50cnkiLAogICJiX2VudHJ5X2xhZzEiLCAiQmFycmllcnMgdG8gZW50cnkgKHQgLSAxKSIsCiAgImJfZnVuZGluZyIsICJCYXJyaWVycyB0byBmdW5kaW5nIiwKICAiYl9mdW5kaW5nX2xhZzEiLCAiQmFycmllcnMgdG8gZnVuZGluZyAodCAtIDEpIiwKICAiYl9iYXJyaWVyc190b3RhbF93aXRoaW4iLCAiVG90YWwgbGVnYWwgYmFycmllcnMgKHdpdGhpbikiLAogICJiX2JhcnJpZXJzX3RvdGFsX2xhZzFfd2l0aGluIiwgIlRvdGFsIGxlZ2FsIGJhcnJpZXJzICh3aXRoaW47IHQgLSAxKSIsCiAgImJfYWR2b2NhY3lfd2l0aGluIiwgIkJhcnJpZXJzIHRvIGFkdm9jYWN5ICh3aXRoaW4pIiwKICAiYl9hZHZvY2FjeV9sYWcxX3dpdGhpbiIsICJCYXJyaWVycyB0byBhZHZvY2FjeSAod2l0aGluOyB0IC0gMSkiLAogICJiX2VudHJ5X3dpdGhpbiIsICJCYXJyaWVycyB0byBlbnRyeSAod2l0aGluKSIsCiAgImJfZW50cnlfbGFnMV93aXRoaW4iLCAiQmFycmllcnMgdG8gZW50cnkgKHdpdGhpbjsgdCAtIDEpIiwKICAiYl9mdW5kaW5nX3dpdGhpbiIsICJCYXJyaWVycyB0byBmdW5kaW5nICh3aXRoaW4pIiwKICAiYl9mdW5kaW5nX2xhZzFfd2l0aGluIiwgIkJhcnJpZXJzIHRvIGZ1bmRpbmcgKHdpdGhpbjsgdCAtIDEpIgopICU+JSAKICBtdXRhdGUoYWNyb3NzKGV2ZXJ5dGhpbmcoKSwgfmZjdF9pbm9yZGVyKC4sIG9yZGVyZWQgPSBUUlVFKSkpICU+JSAKICBtdXRhdGUobGFnZ2luZyA9IHN0cl9kZXRlY3QoY29lZiwgImxhZzEiKSkKYGBgCgoKIyBDb25mb3VuZGVycwoKVGltZS12YXJ5aW5nOgoKLSBgdjJ4X3BvbHlhcmNoeWAKLSBHRFBfbG9nCi0gcG9wdWxhdGlvbl9sb2cKLSBhcm1lZF9jb25mbGljdAotIHVuX3RyYWRlX3BjdF9nZHAKCgojIEV+MWF+OiBOR08gbGF3cyBhbmQgcG9saXRpY2FsIHRlcnJvcgoKIyMgUmVzdWx0cyB0YWJsZQoKYGBge3IgdGJsLWUxYS1yZX0KIyBCdWlsZCBuaWNlciBjb2x1bW4gbmFtZXMKbW9kZWxzX2Zvcl90YWJsZV9lMWEgPC0gbW9kZWxzICU+JSAKICBmaWx0ZXIob3V0Y29tZV92YXIgPT0gIlBvbGl0aWNhbCB0ZXJyb3IiKSAlPiUgCiAgbXV0YXRlKG91dGNvbWVfdmFyID0gcmVjb2RlKG91dGNvbWVfdmFyLCAiUG9saXRpY2FsIHRlcnJvciIgPSAiUFRTIiksCiAgICAgICAgIGV4cGxhbl92YXIgPSByZWNvZGUoZXhwbGFuX3ZhciwgIkNpdmlsIHNvY2lldHkgcmVwcmVzc2lvbiIgPSAiQ1MgcmVwcmVzc2lvbiIpKSAlPiUgCiAgbXV0YXRlKG1vZGVsX25hbWUgPSBnbHVlKCJ7b3V0Y29tZV92YXJ9ICh0ICsgMSk8YnI+KHtleHBsYW5fdmFyfSkiKSkKCiMgTWFrZSBhIG5hbWVkIHZlY3RvciBvZiBvcmlnaW5hbCBtb2RlbCBuYW1lcyBhbmQgbmljZSBuYW1lcwptb2RlbHNfbmFtZXNfdGFibGVfZTFhIDwtIG1vZGVsc19mb3JfdGFibGVfZTFhICU+JSAKICBwdWxsKG1vZGVsX25hbWUpICU+JSAKICBzZXRfbmFtZXMobW9kZWxzX2Zvcl90YWJsZV9lMWEkbW9kZWwpCgojIFJlbmFtZSB0aGUgY29sdW1ucwpuYW1lcyhtb2RlbHNfdGJsX2UxYSkgPC0gcmVjb2RlKG5hbWVzKG1vZGVsc190YmxfZTFhKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgISEhbW9kZWxzX25hbWVzX3RhYmxlX2UxYSkKCm1vZGVsc3VtbWFyeShtb2RlbHNfdGJsX2UxYSwKICAgICAgICAgICAgIHN0YXRpc3RpYyA9ICJbe2NvbmYubG93fSwge2NvbmYuaGlnaH1dIiwKICAgICAgICAgICAgIGNvZWZfbWFwID0gY29lZl9saXN0LAogICAgICAgICAgICAgZ29mX29taXQgPSAiRUxQRCIsCiAgICAgICAgICAgICBlc2NhcGUgPSBGQUxTRSwKICAgICAgICAgICAgIG5vdGVzID0gbGlzdCgiUG9zdGVyaW9yIG1lYW5zOyA5NSUgY3JlZGlibGUgaW50ZXJ2YWxzIGluIGJyYWNrZXRzIikpCmBgYAoKIyMgQ29lZmZpY2llbnRzCgpgYGB7ciBwbG90LWNvZWZzLWUxYX0KY29lZl9wbG90cyA8LSBtb2RlbHMgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KG1vZGVsLCAicHRzXyIpLCAhc3RyX2RldGVjdChtb2RlbCwgImJhc2VsaW5lIikpICU+JSAKICBtdXRhdGUoY29lZl9kcmF3cyA9IG1hcCgKICAgIGFjdHVhbF9tb2RlbCwgCiAgICB+Z2F0aGVyX2RyYXdzKG1vZGVsID0gLiwgYC4qYmFycmllcnMuKnwuKmFkdm9jYWN5Lip8LiplbnRyeS4qfC4qZnVuZGluZy4qYCwgcmVnZXggPSBUUlVFKSkpICU+JSAKICBzZWxlY3QoLWFjdHVhbF9tb2RlbCkgJT4lIAogIHVubmVzdChjb2VmX2RyYXdzKSAlPiUgCiAgbGVmdF9qb2luKGNvZWZzX2NsZWFuLCBieSA9IGMoIi52YXJpYWJsZSIgPSAiY29lZiIpKQoKY29lZl9wbG90cyAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3Jldihjb2VmX2NsZWFuKSwgeCA9IC52YWx1ZSkpICsKICBzdGF0X2hhbGZleWUoYWVzKGFscGhhID0gbGFnZ2luZyksIC53aWR0aCA9IGMoMC44LCAwLjk1KSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDApICsKICBndWlkZXMoZmlsbCA9ICJub25lIiwgYWxwaGEgPSAibm9uZSIpICsKICBzY2FsZV9hbHBoYV9tYW51YWwodmFsdWVzID0gYygxLCAwLjQpKSArCiAgbGFicyh4ID0gIkNvZWZmaWNpZW50IiwgeSA9IE5VTEwpICsKICB0aGVtZV9uZ28oKQpgYGAKCiMjIE1hcmdpbmFsIGVmZmVjdHMKCmBgYHtyIHBsb3QtbWZ4LWUxYX0KcGxvdF9wdHNfdmFyc19sb29rdXAgPC0gdHJpYmJsZSgKICB+bW9kZWwsIH5wbG90X3ZhciwgfnBsb3RfdmFyX25pY2UsCiAgIm1fcHRzX3RvdGFsIiwgImJhcnJpZXJzX3RvdGFsIiwgIlRvdGFsIGxlZ2FsIGJhcnJpZXJzIiwKICAibV9wdHNfdG90YWxfbmV3IiwgImJhcnJpZXJzX3RvdGFsX25ldyIsICJOZXcgbGVnYWwgYmFycmllcnMiLAogICJtX3B0c19hZHZvY2FjeSIsICJhZHZvY2FjeSIsICJCYXJyaWVycyB0byBhZHZvY2FjeSIsCiAgIm1fcHRzX2VudHJ5IiwgImVudHJ5IiwgIkJhcnJpZXJzIHRvIGVudHJ5IiwKICAibV9wdHNfZnVuZGluZyIsICJmdW5kaW5nIiwgIkJhcnJpZXJzIHRvIGZ1bmRpbmciCikgJT4lIAogIG11dGF0ZShwbG90X3Zhcl9uaWNlID0gZmN0X2lub3JkZXIocGxvdF92YXJfbmljZSwgb3JkZXJlZCA9IFRSVUUpKQoKbWZ4IDwtIG1vZGVscyAlPiUgCiAgZmlsdGVyKHN0cl9kZXRlY3QobW9kZWwsICJfcHRzIiksICFzdHJfZGV0ZWN0KG1vZGVsLCAiYmFzZWxpbmV8bmV3IikpICU+JSAKICBsZWZ0X2pvaW4ocGxvdF9wdHNfdmFyc19sb29rdXAsIGJ5ID0gIm1vZGVsIikgJT4lIAogIG11dGF0ZShmeCA9IG1hcDIoYWN0dWFsX21vZGVsLCBwbG90X3ZhciwgCiAgICAgICAgICAgICAgICAgICB+Y29uZGl0aW9uYWxfZWZmZWN0cygueCwgZWZmZWN0cyA9IC55LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0ZWdvcmljYWwgPSBUUlVFKVtbMV1dKSkgJT4lIAogIHNlbGVjdCgtYWN0dWFsX21vZGVsKSAlPiUgCiAgdW5uZXN0KGZ4KQoKbWZ4ICU+JSAKICBtdXRhdGUoeF9yb3VuZGVkID0gZmxvb3IoZWZmZWN0MV9fKSkgJT4lIAogIGdyb3VwX2J5KHhfcm91bmRlZCwgZWZmZWN0Ml9fLCBwbG90X3Zhcl9uaWNlKSAlPiUgCiAgc2xpY2UoMSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0geF9yb3VuZGVkLCB5ID0gZXN0aW1hdGVfXywgY29sb3IgPSBlZmZlY3QyX18pKSArCiAgZ2VvbV9wb2ludHJhbmdlKGFlcyh5bWluID0gbG93ZXJfXywgeW1heCA9IHVwcGVyX18pLAogICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC4yKSwKICAgICAgICAgICAgICAgICAgZmF0dGVuID0gMSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAwOjkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAidmlyaWRpcyIsIGVuZCA9IDAuOTUpICsKICBsYWJzKHggPSAiQ291bnQgb2YgbGVnYWwgYmFycmllcnNcbiIsCiAgICAgICB5ID0gIlByZWRpY3RlZCBwcm9iYWJpbGl0eSBvZiBjYXRlZ29yeSIsCiAgICAgICBjb2xvciA9ICJQb2xpdGljYWwgdGVycm9yIHNjYWxlIiwgZmlsbCA9ICJQb2xpdGljYWwgdGVycm9yIHNjYWxlIikgKyAKICBmYWNldF93cmFwKHZhcnMocGxvdF92YXJfbmljZSksIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgdGhlbWVfbmdvKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgpcIAoKIyBFfjFifjogTkdPIGxhd3MgYW5kIGxhdGVudCBodW1hbiByaWdodHMKCiMjIFJlc3VsdHMgdGFibGUKCmBgYHtyIHRibC1lMWJ9Cm1vZGVsc19mb3JfdGFibGVfZTFiIDwtIG1vZGVscyAlPiUgCiAgZmlsdGVyKG91dGNvbWVfdmFyID09ICJMYXRlbnQgaHVtYW4gcmlnaHRzIikgJT4lIAogIG11dGF0ZShtb2RlbF9uYW1lID0gZ2x1ZSgie291dGNvbWVfdmFyfSAodCArIDEpPGJyPih7ZXhwbGFuX3Zhcn0pIikpCgptb2RlbF9uYW1lc190YmxfZTFiIDwtIG1vZGVsc19mb3JfdGFibGVfZTFiICU+JSAKICBwdWxsKG1vZGVsX25hbWUpICU+JSAKICBzZXRfbmFtZXMobW9kZWxzX2Zvcl90YWJsZV9lMWIkbW9kZWwpCgpuYW1lcyhtb2RlbHNfdGJsX2UxYikgPC0gcmVjb2RlKG5hbWVzKG1vZGVsc190YmxfZTFiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgISEhbW9kZWxfbmFtZXNfdGJsX2UxYikKCm1vZGVsc3VtbWFyeShtb2RlbHNfdGJsX2UxYiwKICAgICAgICAgICAgIHN0YXRpc3RpYyA9ICJbe2NvbmYubG93fSwge2NvbmYuaGlnaH1dIiwKICAgICAgICAgICAgIGNvZWZfbWFwID0gY29lZl9saXN0LAogICAgICAgICAgICAgZ29mX29taXQgPSAiRUxQRCIsCiAgICAgICAgICAgICBlc2NhcGUgPSBGQUxTRSwKICAgICAgICAgICAgIG5vdGVzID0gbGlzdCgiUG9zdGVyaW9yIG1lYW5zOyA5NSUgY3JlZGlibGUgaW50ZXJ2YWxzIGluIGJyYWNrZXRzIikpCmBgYAoKIyMgQ29lZmZpY2llbnRzCgpgYGB7ciBwbG90LWNvZWZzLWUxYn0KY29lZl9wbG90cyA8LSBtb2RlbHMgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KG1vZGVsLCAibGhyIiksICFzdHJfZGV0ZWN0KG1vZGVsLCAiYmFzZWxpbmUiKSkgJT4lIAogIG11dGF0ZShjb2VmX2RyYXdzID0gbWFwKAogICAgYWN0dWFsX21vZGVsLCAKICAgIH5nYXRoZXJfZHJhd3MobW9kZWwgPSAuLCBgLipiYXJyaWVycy4qfC4qYWR2b2NhY3kuKnwuKmVudHJ5Lip8LipmdW5kaW5nLipgLCByZWdleCA9IFRSVUUpKSkgJT4lIAogIHNlbGVjdCgtYWN0dWFsX21vZGVsKSAlPiUgCiAgdW5uZXN0KGNvZWZfZHJhd3MpICU+JSAKICBsZWZ0X2pvaW4oY29lZnNfY2xlYW4sIGJ5ID0gYygiLnZhcmlhYmxlIiA9ICJjb2VmIikpCgpjb2VmX3Bsb3RzICU+JSAKICBnZ3Bsb3QoYWVzKHkgPSBmY3RfcmV2KGNvZWZfY2xlYW4pLCB4ID0gLnZhbHVlKSkgKwogIHN0YXRfaGFsZmV5ZShhZXMoYWxwaGEgPSBsYWdnaW5nKSwgLndpZHRoID0gYygwLjgsIDAuOTUpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKwogIGd1aWRlcyhmaWxsID0gIm5vbmUiLCBhbHBoYSA9ICJub25lIikgKwogIHNjYWxlX2FscGhhX21hbnVhbCh2YWx1ZXMgPSBjKDEsIDAuNCkpICsKICBsYWJzKHggPSAiQ29lZmZpY2llbnQiLCB5ID0gTlVMTCkgKwogIHRoZW1lX25nbygpCmBgYAoKIyMgTWFyZ2luYWwgZWZmZWN0cwoKYGBge3IgcGxvdC1tZngtZTFifQpwbG90X2xocl92YXJzX2xvb2t1cCA8LSB0cmliYmxlKAogIH5tb2RlbCwgfnBsb3RfdmFyLCB+cGxvdF92YXJfbmljZSwKICAibV9saHJfdG90YWwiLCAiYmFycmllcnNfdG90YWwiLCAiVG90YWwgbGVnYWwgYmFycmllcnMiLAogICJtX2xocl90b3RhbF9uZXciLCAiYmFycmllcnNfdG90YWxfbmV3IiwgIk5ldyBsZWdhbCBiYXJyaWVycyIsCiAgIm1fbGhyX2Fkdm9jYWN5IiwgImFkdm9jYWN5IiwgIkFkdm9jYWN5IiwKICAibV9saHJfZW50cnkiLCAiZW50cnkiLCAiRW50cnkiLAogICJtX2xocl9mdW5kaW5nIiwgImZ1bmRpbmciLCAiRnVuZGluZyIKKSAlPiUgCiAgbXV0YXRlKHBsb3RfdmFyX25pY2UgPSBmY3RfaW5vcmRlcihwbG90X3Zhcl9uaWNlLCBvcmRlcmVkID0gVFJVRSkpCgptZnggPC0gbW9kZWxzICU+JSAKICBmaWx0ZXIoc3RyX2RldGVjdChtb2RlbCwgImxociIpLCAhc3RyX2RldGVjdChtb2RlbCwgIm5ld3xiYXNlbGluZSIpKSAlPiUgCiAgbGVmdF9qb2luKHBsb3RfbGhyX3ZhcnNfbG9va3VwLCBieSA9ICJtb2RlbCIpICU+JSAKICBtdXRhdGUoZnggPSBtYXAyKGFjdHVhbF9tb2RlbCwgcGxvdF92YXIsIAogICAgICAgICAgICAgICAgICAgfmNvbmRpdGlvbmFsX2VmZmVjdHMoLngsIGVmZmVjdHMgPSAueSlbWzFdXSkpICU+JSAKICBzZWxlY3QoLWFjdHVhbF9tb2RlbCkgJT4lIAogIHVubmVzdChmeCkKCm1meCAlPiUgCiAgbXV0YXRlKHhfcm91bmRlZCA9IGZsb29yKGVmZmVjdDFfXykpICU+JSAKICBncm91cF9ieSh4X3JvdW5kZWQsIHBsb3RfdmFyX25pY2UpICU+JSAKICBzbGljZSgxKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSB4X3JvdW5kZWQsIHkgPSBlc3RpbWF0ZV9fLCBjb2xvciA9IHBsb3RfdmFyX25pY2UpKSArCiAgZ2VvbV9saW5lKHNpemUgPSAwLjUsIGNvbG9yID0gImdyZXk5MCIpICsKICBnZW9tX3BvaW50cmFuZ2UoYWVzKHltaW4gPSBsb3dlcl9fLCB5bWF4ID0gdXBwZXJfXyksCiAgICAgICAgICAgICAgICAgIGZhdHRlbiA9IDEpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gMDo5KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJwbGFzbWEiLCBlbmQgPSAwLjgpICsKICBndWlkZXMoY29sb3IgPSAibm9uZSIpICsKICBsYWJzKHggPSAiQ291bnQgb2YgbGVnYWwgYmFycmllcnMiLAogICAgICAgeSA9ICJQcmVkaWN0ZWQgbGF0ZW50IGh1bWFuIHJpZ2h0cyB2YWx1ZVxuKGhpZ2hlciB2YWx1ZXMgPSBiZXR0ZXIgaHVtYW4gcmlnaHRzKSIpICsKICBmYWNldF9ncmlkKGNvbHMgPSB2YXJzKHBsb3RfdmFyX25pY2UpLCBzY2FsZXMgPSAiZnJlZV94Iiwgc3BhY2UgPSAiZnJlZV94IikgKwogIHRoZW1lX25nbygpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCkpCmBgYAo=