library(tidyverse)
library(targets)
library(broom)
library(broom.mixed)
library(tidybayes)
library(glue)
library(brms)
library(scales)
library(kableExtra)
library(modelsummary)
library(lubridate)
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_pts_baseline_rewb, m_pts_total_rewb, 
             m_pts_advocacy_rewb, m_pts_entry_rewb, m_pts_funding_rewb, 
             m_clphy_baseline, m_clphy_total, m_clphy_total_new, 
             m_clphy_advocacy, m_clphy_entry, m_clphy_funding, 
             m_clphy_baseline_rewb, m_clphy_total_rewb, 
             m_clphy_advocacy_rewb, m_clphy_entry_rewb, m_clphy_funding_rewb, 
             m_clpriv_baseline, m_clpriv_total, m_clpriv_total_new,
             m_clpriv_advocacy, m_clpriv_entry, m_clpriv_funding, 
             m_clpriv_baseline_rewb, m_clpriv_total_rewb, 
             m_clpriv_advocacy_rewb, m_clpriv_entry_rewb, m_clpriv_funding_rewb,
             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_re, models_tbl_e1a_rewb, 
             models_tbl_e1b_re, models_tbl_e1c_re, models_tbl_e1d_re))
  
  # 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, re, 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_re <- models %>% 
  filter(outcome_var == "Political terror", re == "RE") %>% 
  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}; {re})"))

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

# Rename the columns
names(models_tbl_e1a_re) <- recode(names(models_tbl_e1a_re), 
                                   !!!models_names_table_e1a_re)

modelsummary(models_tbl_e1a_re,
             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; RE)
PTS (t + 1)
(Total legal barriers; RE)
PTS (t + 1)
(New legal barriers; RE)
PTS (t + 1)
(Barriers to advocacy; RE)
PTS (t + 1)
(Barriers to entry; RE)
PTS (t + 1)
(Barriers to funding; RE)
Total legal barriers 0.157
[-0.014, 0.324]
Total legal barriers (t - 1) 0.023
[-0.143, 0.194]
New legal barriers 0.068
[-0.090, 0.238]
New legal barriers (t - 1) -0.073
[-0.248, 0.092]
Barriers to advocacy 0.442
[-0.179, 1.122]
Barriers to advocacy (t - 1) -0.082
[-0.750, 0.590]
Barriers to entry 0.270
[-0.040, 0.584]
Barriers to entry (t - 1) 0.064
[-0.266, 0.370]
Barriers to funding 0.276
[-0.075, 0.601]
Barriers to funding (t - 1) 0.071
[-0.282, 0.399]
PTS = 2 2.401 2.251 2.218 2.285 2.268 2.259
[2.119, 2.714] [1.945, 2.548] [1.913, 2.533] [1.986, 2.588] [1.967, 2.562] [1.975, 2.566]
PTS = 3 4.427 4.222 4.159 4.303 4.258 4.245
[4.060, 4.787] [3.861, 4.620] [3.761, 4.550] [3.929, 4.684] [3.880, 4.649] [3.873, 4.631]
PTS = 4 6.533 6.231 6.239 6.351 6.285 6.228
[6.090, 7.015] [5.773, 6.750] [5.776, 6.736] [5.866, 6.833] [5.810, 6.756] [5.741, 6.720]
PTS = 5 8.886 8.564 8.549 8.646 8.632 8.552
[8.317, 9.516] [7.925, 9.197] [7.907, 9.186] [8.037, 9.286] [8.011, 9.218] [7.915, 9.169]
Polyarchy index -2.219 -2.226 -2.658 -2.310 -2.358 -2.252
[-2.840, -1.580] [-2.920, -1.532] [-3.392, -1.943] [-2.985, -1.595] [-3.071, -1.720] [-2.912, -1.534]
Log GDP per capita -0.403 -0.474 -0.425 -0.436 -0.449 -0.471
[-0.543, -0.261] [-0.627, -0.320] [-0.581, -0.273] [-0.590, -0.290] [-0.591, -0.299] [-0.612, -0.326]
Trade as % of GDP -0.370 -0.432 -0.373 -0.433 -0.419 -0.414
[-0.676, -0.061] [-0.742, -0.092] [-0.713, -0.041] [-0.763, -0.121] [-0.730, -0.081] [-0.728, -0.079]
Armed conflict 1.011 1.086 1.054 1.066 1.079 1.093
[0.706, 1.303] [0.793, 1.406] [0.735, 1.384] [0.746, 1.370] [0.768, 1.391] [0.781, 1.399]
Cutpoint 1/2 -5.152 -5.817 -5.916 -5.631 -5.634 -5.913
[-6.314, -3.997] [-7.081, -4.598] [-7.229, -4.621] [-6.935, -4.431] [-6.855, -4.416] [-7.124, -4.679]
Cutpoint 2/3 -1.197 -1.772 -1.862 -1.625 -1.589 -1.869
[-2.364, -0.100] [-2.970, -0.583] [-3.147, -0.572] [-2.922, -0.521] [-2.796, -0.402] [-3.078, -0.706]
Cutpoint 3/4 2.780 2.289 2.223 2.405 2.470 2.199
[1.698, 3.962] [1.105, 3.519] [0.871, 3.431] [1.276, 3.641] [1.265, 3.657] [0.947, 3.330]
Cutpoint 4/5 6.362 5.925 5.918 6.026 6.084 5.824
[5.236, 7.535] [4.616, 7.097] [4.530, 7.146] [4.795, 7.219] [4.878, 7.314] [4.567, 6.994]
Num.Obs. 3736 3594 3438 3594 3594 3594
R2 0.805 0.807 0.807 0.806 0.807 0.807
R2 Marg. 0.710 0.710 0.697 0.709 0.710 0.706
LOOIC 5457.4 5192.3 4962.9 5218.4 5199.5 5198.2
LOOIC s.e. 98.9 97.4 95.3 97.4 97.7 97.4
WAIC 5456.8 5191.7 4962.1 5217.7 5198.8 5197.4
Posterior means; 95% credible intervals in brackets
models_for_table_e1a_rewb <- models %>% 
  filter(outcome_var == "Political terror", re == "REWB") %>% 
  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}; {re})"))

models_names_table_e1a_rewb <- models_for_table_e1a_rewb %>% 
  pull(model_name) %>% 
  set_names(models_for_table_e1a_rewb$model)

names(models_tbl_e1a_rewb) <- recode(names(models_tbl_e1a_rewb), 
                                     !!!models_names_table_e1a_rewb)

modelsummary(models_tbl_e1a_rewb,
             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; REWB)
PTS (t + 1)
(Total legal barriers; REWB)
PTS (t + 1)
(Barriers to advocacy; REWB)
PTS (t + 1)
(Barriers to entry; REWB)
PTS (t + 1)
(Barriers to funding; REWB)
Total legal barriers (within) 0.114
[-0.054, 0.283]
Total legal barriers (between) 1.296
[-1.695, 4.252]
Total legal barriers (within; t - 1) 0.013
[-0.156, 0.184]
Total legal barriers (between; t - 1) -1.212
[-3.971, 2.009]
Barriers to advocacy (within) 0.300
[-0.332, 0.964]
Barriers to advocacy (between) 0.685
[-3.174, 4.558]
Barriers to advocacy (within; t - 1) -0.181
[-0.835, 0.509]
Barriers to advocacy (between; t - 1) -0.417
[-4.221, 3.612]
Barriers to entry (within) 0.193
[-0.154, 0.508]
Barriers to entry (between) 0.248
[-3.830, 3.748]
Barriers to entry (within; t - 1) 0.036
[-0.279, 0.361]
Barriers to entry (between; t - 1) -0.068
[-3.701, 3.809]
Barriers to funding (within) 0.212
[-0.134, 0.538]
Barriers to funding (between) 1.258
[-2.601, 4.785]
Barriers to funding (within; t - 1) 0.065
[-0.252, 0.409]
Barriers to funding (between; t - 1) -1.181
[-4.695, 2.822]
PTS = 2 2.288 2.176 2.177 2.180 2.161
[2.010, 2.592] [1.906, 2.507] [1.877, 2.481] [1.877, 2.491] [1.880, 2.484]
PTS = 3 4.232 4.089 4.128 4.101 4.087
[3.858, 4.611] [3.736, 4.494] [3.745, 4.513] [3.720, 4.483] [3.711, 4.472]
PTS = 4 6.334 6.112 6.172 6.135 6.085
[5.845, 6.788] [5.636, 6.592] [5.664, 6.647] [5.642, 6.591] [5.622, 6.585]
PTS = 5 8.841 8.563 8.607 8.583 8.530
[8.176, 9.417] [7.938, 9.214] [8.004, 9.263] [7.906, 9.180] [7.952, 9.187]
Polyarchy index (within) -1.586 -1.885 -1.797 -1.935 -1.850
[-2.518, -0.722] [-2.755, -0.917] [-2.723, -0.898] [-2.921, -0.983] [-2.793, -0.880]
Polyarchy index (between) -3.314 -3.095 -3.259 -3.286 -3.330
[-4.238, -2.456] [-4.187, -1.931] [-4.285, -2.243] [-4.317, -2.236] [-4.472, -2.235]
Log GDP per capita (within) 0.272 0.100 0.250 0.131 0.122
[-0.032, 0.595] [-0.234, 0.448] [-0.092, 0.575] [-0.201, 0.466] [-0.228, 0.457]
Log GDP per capita (between) -0.434 -0.492 -0.475 -0.468 -0.481
[-0.605, -0.275] [-0.688, -0.314] [-0.661, -0.301] [-0.650, -0.283] [-0.658, -0.282]
Trade as % of GDP (within) -0.075 -0.117 -0.108 -0.094 -0.113
[-0.490, 0.304] [-0.497, 0.273] [-0.499, 0.274] [-0.498, 0.287] [-0.512, 0.301]
Trade as % of GDP (between) -1.221 -1.211 -1.245 -1.243 -1.258
[-1.713, -0.703] [-1.784, -0.712] [-1.800, -0.686] [-1.786, -0.695] [-1.812, -0.682]
Armed conflict 1.000 1.051 1.036 1.054 1.062
[0.712, 1.293] [0.742, 1.362] [0.738, 1.342] [0.720, 1.345] [0.736, 1.365]
Cutpoint 1/2 -6.795 -7.198 -7.203 -7.136 -7.372
[-8.098, -5.405] [-8.779, -5.767] [-8.716, -5.685] [-8.625, -5.677] [-8.865, -5.963]
Cutpoint 2/3 -2.770 -3.109 -3.130 -3.059 -3.295
[-4.108, -1.544] [-4.575, -1.632] [-4.629, -1.713] [-4.617, -1.719] [-4.707, -1.904]
Cutpoint 3/4 1.216 0.962 0.919 1.011 0.774
[-0.135, 2.443] [-0.564, 2.345] [-0.522, 2.387] [-0.523, 2.363] [-0.593, 2.144]
Cutpoint 4/5 4.809 4.599 4.553 4.650 4.422
[3.494, 6.101] [3.166, 6.109] [3.085, 5.990] [3.142, 6.065] [3.076, 5.858]
Num.Obs. 3736 3594 3594 3594 3594
R2 0.807 0.808 0.808 0.808 0.809
R2 Marg. 0.734 0.728 0.729 0.728 0.726
LOOIC 5414.9 5171.5 5182.9 5174.1 5170.8
LOOIC s.e. 98.6 97.3 97.4 97.5 97.2
WAIC 5414.3 5170.8 5182.2 5173.3 5170.0
Posterior means; 95% credible intervals in brackets

Coefficients

coef_plots <- models %>% 
  filter(str_detect(model, "pts_"), !str_detect(model, "baseline")) %>% 
  mutate(re_fancy = case_when(
    re == "RE" ~ "Random effects models",
    re == "REWB" ~ "Random effects—within/between models"
  )) %>% 
  mutate(coef_draws = map(
    actual_model, 
    ~gather_draws(model = ., `.*barriers.*|.*advocacy.*|.*entry.*|.*funding.*`, regex = TRUE))) %>% 
  select(-actual_model) %>% 
  unnest(coef_draws) %>% 
  filter(!str_detect(.variable, "between")) %>% 
  left_join(coefs_clean, by = c(".variable" = "coef"))

coef_plots %>% 
  ggplot(aes(y = fct_rev(coef_clean), x = .value, fill = re_fancy)) +
  stat_halfeye(aes(alpha = lagging), .width = c(0.8, 0.95)) +
  geom_vline(xintercept = 0) +
  guides(fill = FALSE, alpha = FALSE) +
  scale_alpha_manual(values = c(1, 0.4)) +
  labs(x = "Coefficient", y = NULL) +
  facet_wrap(vars(re_fancy), ncol = 2, scales = "free_y") +
  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, "rewb|baseline")) %>% 
  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 physical violence

Results table

models_for_table_e1b_re <- models %>% 
  filter(outcome_var == "Physical violence", re == "RE") %>% 
  mutate(model_name = glue("{outcome_var} (t + 1)<br>({explan_var}; {re})"))

model_names_tbl_e1b_re <- models_for_table_e1b_re %>% 
  pull(model_name) %>% 
  set_names(models_for_table_e1b_re$model)

names(models_tbl_e1b_re) <- recode(names(models_tbl_e1b_re), 
                                   !!!model_names_tbl_e1b_re)

modelsummary(models_tbl_e1b_re,
             statistic = "[{conf.low}, {conf.high}]",
             coef_map = coef_list,
             gof_omit = "ELPD",
             escape = FALSE,
             notes = list("Posterior means; 95% credible intervals in brackets"))
Physical violence (t + 1)
(Baseline; RE)
Physical violence (t + 1)
(Total legal barriers; RE)
Physical violence (t + 1)
(New legal barriers; RE)
Physical violence (t + 1)
(Barriers to advocacy; RE)
Physical violence (t + 1)
(Barriers to entry; RE)
Physical violence (t + 1)
(Barriers to funding; RE)
Total legal barriers 0.001
[-0.002, 0.005]
Total legal barriers (t - 1) -0.003
[-0.007, 0.000]
New legal barriers 0.002
[-0.001, 0.006]
New legal barriers (t - 1) -0.002
[-0.006, 0.002]
Barriers to advocacy 0.005
[-0.009, 0.019]
Barriers to advocacy (t - 1) -0.011
[-0.026, 0.003]
Barriers to entry 0.006
[-0.001, 0.013]
Barriers to entry (t - 1) -0.008
[-0.015, -0.001]
Barriers to funding -0.001
[-0.009, 0.006]
Barriers to funding (t - 1) -0.002
[-0.009, 0.006]
Physical violence index (t) 0.967 0.966 0.964 0.965 0.966 0.967
[0.954, 0.979] [0.953, 0.978] [0.952, 0.978] [0.952, 0.976] [0.952, 0.979] [0.955, 0.979]
Polyarchy index 0.011 0.009 0.015 0.010 0.011 0.009
[0.001, 0.021] [-0.002, 0.019] [0.004, 0.026] [0.000, 0.021] [0.001, 0.022] [-0.002, 0.019]
Log GDP per capita 0.001 0.001 0.001 0.001 0.001 0.001
[0.000, 0.003] [0.000, 0.003] [0.000, 0.003] [0.000, 0.003] [-0.001, 0.003] [0.000, 0.003]
Trade as % of GDP -0.003 -0.002 -0.003 -0.002 -0.002 -0.002
[-0.007, 0.001] [-0.006, 0.002] [-0.007, 0.002] [-0.006, 0.002] [-0.006, 0.002] [-0.006, 0.001]
Armed conflict -0.001 -0.001 -0.001 -0.001 -0.001 -0.001
[-0.005, 0.004] [-0.006, 0.003] [-0.006, 0.003] [-0.006, 0.004] [-0.006, 0.004] [-0.006, 0.004]
Intercept 0.015 0.016 0.012 0.015 0.015 0.014
[0.004, 0.024] [0.006, 0.026] [0.002, 0.022] [0.005, 0.024] [0.005, 0.026] [0.004, 0.023]
Num.Obs. 3769 3609 3449 3609 3609 3609
R2 0.971 0.971 0.971 0.971 0.971 0.971
R2 Marg. 0.970 0.971 0.971 0.971 0.971 0.971
LOOIC -12083.2 -11663.0 -11169.8 -11660.8 -11655.1 -11658.7
LOOIC s.e. 424.4 427.7 428.5 428.3 428.7 427.9
WAIC -12084.4 -11663.8 -11172.3 -11663.8 -11658.8 -11660.0
Posterior means; 95% credible intervals in brackets

Coefficients

coef_plots <- models %>% 
  filter(str_detect(model, "clphy"), !str_detect(model, "baseline")) %>% 
  mutate(re_fancy = case_when(
    re == "RE" ~ "Random effects models",
    re == "REWB" ~ "Random effects—within/between models"
  )) %>% 
  mutate(coef_draws = map(
    actual_model, 
    ~gather_draws(model = ., `.*barriers.*|.*advocacy.*|.*entry.*|.*funding.*`, regex = TRUE))) %>% 
  select(-actual_model) %>% 
  unnest(coef_draws) %>% 
  filter(!str_detect(.variable, "between")) %>% 
  left_join(coefs_clean, by = c(".variable" = "coef"))

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

Marginal effects

plot_clphy_vars_lookup <- tribble(
  ~model, ~plot_var, ~plot_var_nice,
  "m_clphy_total", "barriers_total", "Total legal barriers",
  "m_clphy_total_new", "barriers_total_new", "New legal barriers",
  "m_clphy_advocacy", "advocacy", "Advocacy",
  "m_clphy_entry", "entry", "Entry",
  "m_clphy_funding", "funding", "Funding"
) %>% 
  mutate(plot_var_nice = fct_inorder(plot_var_nice, ordered = TRUE))

mfx <- models %>% 
  filter(str_detect(model, "clphy"), !str_detect(model, "rewb|baseline")) %>% 
  left_join(plot_clphy_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 = FALSE) +
  labs(x = "Count of legal barriers",
       y = "Predicted physical violence index\n(higher values = less violence)") +
  facet_grid(cols = vars(plot_var_nice), scales = "free_x", space = "free_x") +
  theme_ngo() +
  theme(panel.grid.major.x = element_blank())

 

E1c: NGO laws and civil liberties

Results table

models_for_table_e1c_re <- models %>% 
  filter(outcome_var == "Private civil liberties", re == "RE") %>% 
  mutate(model_name = glue("{outcome_var} (t + 1)<br>({explan_var}; {re})"))

model_names_tbl_e1c_re <- models_for_table_e1c_re %>% 
  pull(model_name) %>% 
  set_names(models_for_table_e1c_re$model)

names(models_tbl_e1c_re) <- recode(names(models_tbl_e1c_re), 
                                   !!!model_names_tbl_e1c_re)

modelsummary(models_tbl_e1c_re,
             statistic = "[{conf.low}, {conf.high}]",
             coef_map = coef_list,
             gof_omit = "ELPD",
             escape = FALSE,
             notes = list("Posterior means; 95% credible intervals in brackets"))
Private civil liberties (t + 1)
(Baseline; RE)
Private civil liberties (t + 1)
(Total legal barriers; RE)
Private civil liberties (t + 1)
(New legal barriers; RE)
Private civil liberties (t + 1)
(Barriers to advocacy; RE)
Private civil liberties (t + 1)
(Barriers to entry; RE)
Private civil liberties (t + 1)
(Barriers to funding; RE)
Total legal barriers -0.001
[-0.003, 0.002]
Total legal barriers (t - 1) -0.001
[-0.004, 0.001]
New legal barriers 0.000
[-0.003, 0.002]
New legal barriers (t - 1) -0.001
[-0.003, 0.002]
Barriers to advocacy -0.007
[-0.016, 0.003]
Barriers to advocacy (t - 1) 0.001
[-0.008, 0.011]
Barriers to entry 0.002
[-0.002, 0.008]
Barriers to entry (t - 1) -0.006
[-0.011, -0.001]
Barriers to funding -0.003
[-0.008, 0.002]
Barriers to funding (t - 1) 0.000
[-0.005, 0.005]
Private civil liberties index (t) 0.959 0.968 0.971 0.967 0.969 0.969
[0.939, 0.975] [0.957, 0.979] [0.960, 0.981] [0.954, 0.978] [0.958, 0.981] [0.958, 0.979]
Polyarchy index 0.019 0.012 0.015 0.014 0.013 0.013
[0.008, 0.030] [0.002, 0.022] [0.005, 0.025] [0.005, 0.025] [0.003, 0.024] [0.004, 0.023]
Log GDP per capita -0.001 -0.001 -0.001 -0.001 -0.001 -0.001
[-0.003, 0.000] [-0.002, 0.000] [-0.002, 0.000] [-0.002, 0.000] [-0.002, 0.000] [-0.002, 0.000]
Trade as % of GDP 0.000 0.001 0.001 0.001 0.001 0.001
[-0.004, 0.003] [-0.002, 0.004] [-0.002, 0.004] [-0.002, 0.004] [-0.002, 0.004] [-0.002, 0.004]
Armed conflict 0.000 0.000 0.001 0.000 0.000 0.000
[-0.004, 0.003] [-0.003, 0.003] [-0.002, 0.004] [-0.004, 0.003] [-0.003, 0.003] [-0.004, 0.003]
Intercept 0.033 0.030 0.024 0.029 0.030 0.028
[0.022, 0.045] [0.021, 0.039] [0.015, 0.033] [0.020, 0.039] [0.020, 0.039] [0.019, 0.036]
Num.Obs. 3769 3609 3449 3609 3609 3609
R2 0.981 0.983 0.984 0.983 0.983 0.983
R2 Marg. 0.980 0.983 0.983 0.983 0.983 0.983
LOOIC -14363.3 -14213.9 -13738.0 -14209.9 -14208.4 -14205.6
LOOIC s.e. 508.1 449.7 463.8 449.6 451.9 449.6
WAIC -14357.8 -14214.5 -13741.4 -14210.5 -14211.4 -14208.1
Posterior means; 95% credible intervals in brackets

Coefficients

coef_plots <- models %>% 
  filter(str_detect(model, "clpriv"), !str_detect(model, "baseline")) %>% 
  mutate(re_fancy = case_when(
    re == "RE" ~ "Random effects models",
    re == "REWB" ~ "Random effects—within/between models"
  )) %>% 
  mutate(coef_draws = map(
    actual_model, 
    ~gather_draws(model = ., `.*barriers.*|.*advocacy.*|.*entry.*|.*funding.*`, regex = TRUE))) %>% 
  select(-actual_model) %>% 
  unnest(coef_draws) %>% 
  filter(!str_detect(.variable, "between")) %>% 
  left_join(coefs_clean, by = c(".variable" = "coef"))

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

Marginal effects

plot_clpriv_vars_lookup <- tribble(
  ~model, ~plot_var, ~plot_var_nice,
  "m_clpriv_total", "barriers_total", "Total legal barriers",
  "m_clpriv_total_new", "barriers_total_new", "New legal barriers",
  "m_clpriv_advocacy", "advocacy", "Advocacy",
  "m_clpriv_entry", "entry", "Entry",
  "m_clpriv_funding", "funding", "Funding"
) %>% 
  mutate(plot_var_nice = fct_inorder(plot_var_nice, ordered = TRUE))

mfx <- models %>% 
  filter(str_detect(model, "clpriv"), !str_detect(model, "rewb|baseline")) %>% 
  left_join(plot_clpriv_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 = FALSE) +
  labs(x = "Count of legal barriers",
       y = "Predicted civil liberties index\n(higher values = better protection)") +
  facet_grid(cols = vars(plot_var_nice), scales = "free_x", space = "free_x") +
  theme_ngo() +
  theme(panel.grid.major.x = element_blank())

 

E1d: NGO laws and latent physical integrity rights

Results table

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

model_names_tbl_e1d_re <- models_for_table_e1d_re %>% 
  pull(model_name) %>% 
  set_names(models_for_table_e1d_re$model)

names(models_tbl_e1d_re) <- recode(names(models_tbl_e1d_re), 
                                   !!!model_names_tbl_e1d_re)

modelsummary(models_tbl_e1d_re,
             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; RE)
Latent human rights (t + 1)
(Total legal barriers; RE)
Latent human rights (t + 1)
(New legal barriers; RE)
Latent human rights (t + 1)
(Barriers to advocacy; RE)
Latent human rights (t + 1)
(Barriers to entry; RE)
Latent human rights (t + 1)
(Barriers to funding; RE)
Total legal barriers -0.013
[-0.032, 0.005]
Total legal barriers (t - 1) 0.007
[-0.011, 0.026]
New legal barriers -0.011
[-0.028, 0.009]
New legal barriers (t - 1) -0.001
[-0.019, 0.017]
Barriers to advocacy -0.024
[-0.093, 0.046]
Barriers to advocacy (t - 1) 0.008
[-0.061, 0.081]
Barriers to entry -0.027
[-0.063, 0.008]
Barriers to entry (t - 1) 0.019
[-0.017, 0.054]
Barriers to funding -0.016
[-0.053, 0.022]
Barriers to funding (t - 1) 0.006
[-0.035, 0.043]
Latent human rights (t) 0.965 0.964 0.965 0.964 0.964 0.965
[0.955, 0.976] [0.951, 0.976] [0.954, 0.976] [0.952, 0.975] [0.950, 0.976] [0.952, 0.975]
Polyarchy index 0.091 0.075 0.096 0.081 0.082 0.076
[0.048, 0.128] [0.032, 0.118] [0.052, 0.138] [0.040, 0.123] [0.038, 0.123] [0.033, 0.119]
Log GDP per capita 0.007 0.008 0.006 0.007 0.007 0.008
[-0.001, 0.014] [0.000, 0.017] [-0.002, 0.014] [0.000, 0.015] [0.000, 0.015] [0.001, 0.016]
Trade as % of GDP 0.023 0.024 0.023 0.024 0.024 0.023
[0.003, 0.043] [0.003, 0.043] [0.003, 0.045] [0.005, 0.046] [0.003, 0.045] [0.002, 0.043]
Armed conflict -0.007 -0.005 -0.002 -0.004 -0.004 -0.005
[-0.032, 0.019] [-0.030, 0.021] [-0.027, 0.024] [-0.032, 0.019] [-0.029, 0.023] [-0.030, 0.020]
Intercept -0.077 -0.074 -0.080 -0.076 -0.073 -0.076
[-0.136, -0.024] [-0.138, -0.009] [-0.143, -0.019] [-0.132, -0.012] [-0.141, -0.011] [-0.138, -0.018]
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 117.0 48.6 136.5 48.9 52.7 49.1
LOOIC s.e. 352.2 351.9 342.7 351.3 352.6 351.4
WAIC 116.4 46.7 135.9 47.7 51.3 48.4
Posterior means; 95% credible intervals in brackets

Coefficients

coef_plots <- models %>% 
  filter(str_detect(model, "lhr"), !str_detect(model, "baseline")) %>% 
  mutate(re_fancy = case_when(
    re == "RE" ~ "Random effects models",
    re == "REWB" ~ "Random effects—within/between models"
  )) %>% 
  mutate(coef_draws = map(
    actual_model, 
    ~gather_draws(model = ., `.*barriers.*|.*advocacy.*|.*entry.*|.*funding.*`, regex = TRUE))) %>% 
  select(-actual_model) %>% 
  unnest(coef_draws) %>% 
  filter(!str_detect(.variable, "between")) %>% 
  left_join(coefs_clean, by = c(".variable" = "coef"))

coef_plots %>% 
  ggplot(aes(y = fct_rev(coef_clean), x = .value, fill = re_fancy)) +
  stat_halfeye(aes(alpha = lagging), .width = c(0.8, 0.95)) +
  geom_vline(xintercept = 0) +
  guides(fill = FALSE, alpha = FALSE) +
  scale_alpha_manual(values = c(1, 0.4)) +
  labs(x = "Coefficient", y = NULL) +
  facet_wrap(vars(re_fancy), ncol = 2, scales = "free_y") +
  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, "rewb|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 = FALSE) +
  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())

LS0tCnRpdGxlOiAiRX4xfjogTGF3cyBwcmVkaWN0IGRldGVyaW9yYXRpbmcgaHVtYW4gcmlnaHRzIgphdXRob3I6ICJTdXBhcm5hIENoYXVkaHJ5IGFuZCBBbmRyZXcgSGVpc3MiCmRhdGU6ICJMYXN0IHJ1bjogYHIgZm9ybWF0KFN5cy50aW1lKCksICclRicpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9mb2xkaW5nOiBoaWRlCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmtuaXRfcHJpbnQuZGF0YS5mcmFtZSA8LSBmdW5jdGlvbih4LCAuLi4pIHsKICByZXMgPC0gcGFzdGUoYygnJywgJycsIGthYmxlX3N0eWxpbmcoa2FibGUoeCwgYm9va3RhYnMgPSBUUlVFKSkpLCBjb2xsYXBzZSA9ICdcbicpCiAgYXNpc19vdXRwdXQocmVzKQp9CgpyZWdpc3RlclMzbWV0aG9kKCJrbml0X3ByaW50IiwgImRhdGEuZnJhbWUiLCBrbml0X3ByaW50LmRhdGEuZnJhbWUpCnJlZ2lzdGVyUzNtZXRob2QoImtuaXRfcHJpbnQiLCAiZ3JvdXBlZF9kZiIsIGtuaXRfcHJpbnQuZGF0YS5mcmFtZSkKCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcucmV0aW5hID0gMywKICAgICAgICAgICAgICAgICAgICAgIHRpZHkub3B0cyA9IGxpc3Qod2lkdGguY3V0b2ZmID0gMTIwKSwgICMgRm9yIGNvZGUKICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMod2lkdGggPSA5MCksICAjIEZvciBvdXRwdXQKICAgICAgICAgICAgICAgICAgICAgIGZpZy5hc3AgPSAwLjYxOCwgZmlnLndpZHRoID0gNywgCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYWxpZ24gPSAiY2VudGVyIiwgb3V0LndpZHRoID0gIjg1JSIpCgpvcHRpb25zKGRwbHlyLnN1bW1hcmlzZS5pbmZvcm0gPSBGQUxTRSwKICAgICAgICBrbml0ci5rYWJsZS5OQSA9ICIiKQpgYGAKCmBgYHtyIGxvYWQtbGlicmFyaWVzLWRhdGEsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHRhcmdldHMpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkoYnJvb20ubWl4ZWQpCmxpYnJhcnkodGlkeWJheWVzKQpsaWJyYXJ5KGdsdWUpCmxpYnJhcnkoYnJtcykKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkoa2FibGVFeHRyYSkKbGlicmFyeShtb2RlbHN1bW1hcnkpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGhlcmUpCgojIEdlbmVyYXRlZCB2aWEgcmFuZG9tLm9yZwpzZXQuc2VlZCg5OTM2KQoKIyBMb2FkIGRhdGEgYW5kIG1vZGVscwp3aXRocjo6d2l0aF9kaXIoaGVyZTo6aGVyZSgpLCB7CiAgc291cmNlKHRhcl9yZWFkKHBsb3RfZnVucykpCiAgCiAgIyBMb2FkIGJpZyBsaXN0IG9mIG1vZGVscwogIG1vZGVsX2RmIDwtIHRhcl9yZWFkKG1vZGVsX2RmKSAlPiUgCiAgICBmaWx0ZXIoIXN0cl9kZXRlY3QobW9kZWwsICJ2MmNzcmVwcnNzIikpCiAgCiAgIyBMb2FkIGFjdHVhbCBtb2RlbCBvYmplY3RzCiAgdGFyX2xvYWQoYyhtX3B0c19iYXNlbGluZSwgbV9wdHNfdG90YWwsIG1fcHRzX3RvdGFsX25ldywgCiAgICAgICAgICAgICBtX3B0c19hZHZvY2FjeSwgbV9wdHNfZW50cnksIG1fcHRzX2Z1bmRpbmcsIAogICAgICAgICAgICAgbV9wdHNfYmFzZWxpbmVfcmV3YiwgbV9wdHNfdG90YWxfcmV3YiwgCiAgICAgICAgICAgICBtX3B0c19hZHZvY2FjeV9yZXdiLCBtX3B0c19lbnRyeV9yZXdiLCBtX3B0c19mdW5kaW5nX3Jld2IsIAogICAgICAgICAgICAgbV9jbHBoeV9iYXNlbGluZSwgbV9jbHBoeV90b3RhbCwgbV9jbHBoeV90b3RhbF9uZXcsIAogICAgICAgICAgICAgbV9jbHBoeV9hZHZvY2FjeSwgbV9jbHBoeV9lbnRyeSwgbV9jbHBoeV9mdW5kaW5nLCAKICAgICAgICAgICAgIG1fY2xwaHlfYmFzZWxpbmVfcmV3YiwgbV9jbHBoeV90b3RhbF9yZXdiLCAKICAgICAgICAgICAgIG1fY2xwaHlfYWR2b2NhY3lfcmV3YiwgbV9jbHBoeV9lbnRyeV9yZXdiLCBtX2NscGh5X2Z1bmRpbmdfcmV3YiwgCiAgICAgICAgICAgICBtX2NscHJpdl9iYXNlbGluZSwgbV9jbHByaXZfdG90YWwsIG1fY2xwcml2X3RvdGFsX25ldywKICAgICAgICAgICAgIG1fY2xwcml2X2Fkdm9jYWN5LCBtX2NscHJpdl9lbnRyeSwgbV9jbHByaXZfZnVuZGluZywgCiAgICAgICAgICAgICBtX2NscHJpdl9iYXNlbGluZV9yZXdiLCBtX2NscHJpdl90b3RhbF9yZXdiLCAKICAgICAgICAgICAgIG1fY2xwcml2X2Fkdm9jYWN5X3Jld2IsIG1fY2xwcml2X2VudHJ5X3Jld2IsIG1fY2xwcml2X2Z1bmRpbmdfcmV3YiwKICAgICAgICAgICAgIG1fbGhyX2Jhc2VsaW5lLCBtX2xocl90b3RhbCwgbV9saHJfdG90YWxfbmV3LCAKICAgICAgICAgICAgIG1fbGhyX2Fkdm9jYWN5LCBtX2xocl9lbnRyeSwgbV9saHJfZnVuZGluZykpCiAgCiAgIyBMb2FkIHJlZ3Jlc3Npb24gdGFibGVzCiAgdGFyX2xvYWQoYyhtb2RlbHNfdGJsX2UxYV9yZSwgbW9kZWxzX3RibF9lMWFfcmV3YiwgCiAgICAgICAgICAgICBtb2RlbHNfdGJsX2UxYl9yZSwgbW9kZWxzX3RibF9lMWNfcmUsIG1vZGVsc190YmxfZTFkX3JlKSkKICAKICAjIExvYWQgbG9va3VwIGxpc3QgZm9yIGNvZWZmaWNpZW50cyBpbiByZWdyZXNzaW9uIHRhYmxlcwogIHRhcl9sb2FkKGNvZWZfbGlzdCkKfSkKYGBgCgpgYGB7ciBjbGVhbi1kYXRhfQptb2RlbHMgPC0gbW9kZWxfZGYgJT4lIAogIGZpbHRlcighc3RyX2RldGVjdChtb2RlbCwgInRyYWluIikpICU+JSAKICBtdXRhdGUoYWN0dWFsX21vZGVsID0gbW9kZWwgJT4lIG1hcCh+ZXZhbChybGFuZzo6c3ltKC4pKSkpICU+JSAKICBtdXRhdGUoYWNyb3NzKGMob3V0Y29tZV92YXIsIGV4cGxhbl92YXIsIHJlLCBmYW1pbHkpLCB+ZmN0X2lub3JkZXIoLiwgb3JkZXJlZCA9IFRSVUUpKSkKCmNvZWZzX2NsZWFuIDwtIHRyaWJibGUoCiAgfmNvZWYsIH5jb2VmX2NsZWFuLAogICJiX2JhcnJpZXJzX3RvdGFsIiwgIlRvdGFsIGxlZ2FsIGJhcnJpZXJzIiwKICAiYl9iYXJyaWVyc190b3RhbF9sYWcxIiwgIlRvdGFsIGxlZ2FsIGJhcnJpZXJzICh0IC0gMSkiLAogICJiX2JhcnJpZXJzX3RvdGFsX25ldyIsICJOZXcgbGVnYWwgYmFycmllcnMiLAogICJiX2JhcnJpZXJzX3RvdGFsX25ld19sYWcxIiwgIk5ldyBsZWdhbCBiYXJyaWVycyAodCAtIDEpIiwKICAiYl9hZHZvY2FjeSIsICJCYXJyaWVycyB0byBhZHZvY2FjeSIsCiAgImJfYWR2b2NhY3lfbGFnMSIsICJCYXJyaWVycyB0byBhZHZvY2FjeSAodCAtIDEpIiwKICAiYl9lbnRyeSIsICJCYXJyaWVycyB0byBlbnRyeSIsCiAgImJfZW50cnlfbGFnMSIsICJCYXJyaWVycyB0byBlbnRyeSAodCAtIDEpIiwKICAiYl9mdW5kaW5nIiwgIkJhcnJpZXJzIHRvIGZ1bmRpbmciLAogICJiX2Z1bmRpbmdfbGFnMSIsICJCYXJyaWVycyB0byBmdW5kaW5nICh0IC0gMSkiLAogICJiX2JhcnJpZXJzX3RvdGFsX3dpdGhpbiIsICJUb3RhbCBsZWdhbCBiYXJyaWVycyAod2l0aGluKSIsCiAgImJfYmFycmllcnNfdG90YWxfbGFnMV93aXRoaW4iLCAiVG90YWwgbGVnYWwgYmFycmllcnMgKHdpdGhpbjsgdCAtIDEpIiwKICAiYl9hZHZvY2FjeV93aXRoaW4iLCAiQmFycmllcnMgdG8gYWR2b2NhY3kgKHdpdGhpbikiLAogICJiX2Fkdm9jYWN5X2xhZzFfd2l0aGluIiwgIkJhcnJpZXJzIHRvIGFkdm9jYWN5ICh3aXRoaW47IHQgLSAxKSIsCiAgImJfZW50cnlfd2l0aGluIiwgIkJhcnJpZXJzIHRvIGVudHJ5ICh3aXRoaW4pIiwKICAiYl9lbnRyeV9sYWcxX3dpdGhpbiIsICJCYXJyaWVycyB0byBlbnRyeSAod2l0aGluOyB0IC0gMSkiLAogICJiX2Z1bmRpbmdfd2l0aGluIiwgIkJhcnJpZXJzIHRvIGZ1bmRpbmcgKHdpdGhpbikiLAogICJiX2Z1bmRpbmdfbGFnMV93aXRoaW4iLCAiQmFycmllcnMgdG8gZnVuZGluZyAod2l0aGluOyB0IC0gMSkiCikgJT4lIAogIG11dGF0ZShhY3Jvc3MoZXZlcnl0aGluZygpLCB+ZmN0X2lub3JkZXIoLiwgb3JkZXJlZCA9IFRSVUUpKSkgJT4lIAogIG11dGF0ZShsYWdnaW5nID0gc3RyX2RldGVjdChjb2VmLCAibGFnMSIpKQpgYGAKCgojIENvbmZvdW5kZXJzCgpUaW1lLXZhcnlpbmc6CgotIGB2MnhfcG9seWFyY2h5YAotIEdEUF9sb2cKLSBwb3B1bGF0aW9uX2xvZwotIGFybWVkX2NvbmZsaWN0Ci0gdW5fdHJhZGVfcGN0X2dkcAoKCiMgRX4xYX46IE5HTyBsYXdzIGFuZCBwb2xpdGljYWwgdGVycm9yCgojIyBSZXN1bHRzIHRhYmxlCgpgYGB7ciB0YmwtZTFhLXJlfQojIEJ1aWxkIG5pY2VyIGNvbHVtbiBuYW1lcwptb2RlbHNfZm9yX3RhYmxlX2UxYV9yZSA8LSBtb2RlbHMgJT4lIAogIGZpbHRlcihvdXRjb21lX3ZhciA9PSAiUG9saXRpY2FsIHRlcnJvciIsIHJlID09ICJSRSIpICU+JSAKICBtdXRhdGUob3V0Y29tZV92YXIgPSByZWNvZGUob3V0Y29tZV92YXIsICJQb2xpdGljYWwgdGVycm9yIiA9ICJQVFMiKSwKICAgICAgICAgZXhwbGFuX3ZhciA9IHJlY29kZShleHBsYW5fdmFyLCAiQ2l2aWwgc29jaWV0eSByZXByZXNzaW9uIiA9ICJDUyByZXByZXNzaW9uIikpICU+JSAKICBtdXRhdGUobW9kZWxfbmFtZSA9IGdsdWUoIntvdXRjb21lX3Zhcn0gKHQgKyAxKTxicj4oe2V4cGxhbl92YXJ9OyB7cmV9KSIpKQoKIyBNYWtlIGEgbmFtZWQgdmVjdG9yIG9mIG9yaWdpbmFsIG1vZGVsIG5hbWVzIGFuZCBuaWNlIG5hbWVzCm1vZGVsc19uYW1lc190YWJsZV9lMWFfcmUgPC0gbW9kZWxzX2Zvcl90YWJsZV9lMWFfcmUgJT4lIAogIHB1bGwobW9kZWxfbmFtZSkgJT4lIAogIHNldF9uYW1lcyhtb2RlbHNfZm9yX3RhYmxlX2UxYV9yZSRtb2RlbCkKCiMgUmVuYW1lIHRoZSBjb2x1bW5zCm5hbWVzKG1vZGVsc190YmxfZTFhX3JlKSA8LSByZWNvZGUobmFtZXMobW9kZWxzX3RibF9lMWFfcmUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhISFtb2RlbHNfbmFtZXNfdGFibGVfZTFhX3JlKQoKbW9kZWxzdW1tYXJ5KG1vZGVsc190YmxfZTFhX3JlLAogICAgICAgICAgICAgc3RhdGlzdGljID0gIlt7Y29uZi5sb3d9LCB7Y29uZi5oaWdofV0iLAogICAgICAgICAgICAgY29lZl9tYXAgPSBjb2VmX2xpc3QsCiAgICAgICAgICAgICBnb2Zfb21pdCA9ICJFTFBEIiwKICAgICAgICAgICAgIGVzY2FwZSA9IEZBTFNFLAogICAgICAgICAgICAgbm90ZXMgPSBsaXN0KCJQb3N0ZXJpb3IgbWVhbnM7IDk1JSBjcmVkaWJsZSBpbnRlcnZhbHMgaW4gYnJhY2tldHMiKSkKYGBgCgpgYGB7ciB0YmwtZTFhLXJld2J9Cm1vZGVsc19mb3JfdGFibGVfZTFhX3Jld2IgPC0gbW9kZWxzICU+JSAKICBmaWx0ZXIob3V0Y29tZV92YXIgPT0gIlBvbGl0aWNhbCB0ZXJyb3IiLCByZSA9PSAiUkVXQiIpICU+JSAKICBtdXRhdGUob3V0Y29tZV92YXIgPSByZWNvZGUob3V0Y29tZV92YXIsICJQb2xpdGljYWwgdGVycm9yIiA9ICJQVFMiKSwKICAgICAgICAgZXhwbGFuX3ZhciA9IHJlY29kZShleHBsYW5fdmFyLCAiQ2l2aWwgc29jaWV0eSByZXByZXNzaW9uIiA9ICJDUyByZXByZXNzaW9uIikpICU+JSAKICBtdXRhdGUobW9kZWxfbmFtZSA9IGdsdWUoIntvdXRjb21lX3Zhcn0gKHQgKyAxKTxicj4oe2V4cGxhbl92YXJ9OyB7cmV9KSIpKQoKbW9kZWxzX25hbWVzX3RhYmxlX2UxYV9yZXdiIDwtIG1vZGVsc19mb3JfdGFibGVfZTFhX3Jld2IgJT4lIAogIHB1bGwobW9kZWxfbmFtZSkgJT4lIAogIHNldF9uYW1lcyhtb2RlbHNfZm9yX3RhYmxlX2UxYV9yZXdiJG1vZGVsKQoKbmFtZXMobW9kZWxzX3RibF9lMWFfcmV3YikgPC0gcmVjb2RlKG5hbWVzKG1vZGVsc190YmxfZTFhX3Jld2IpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICEhIW1vZGVsc19uYW1lc190YWJsZV9lMWFfcmV3YikKCm1vZGVsc3VtbWFyeShtb2RlbHNfdGJsX2UxYV9yZXdiLAogICAgICAgICAgICAgc3RhdGlzdGljID0gIlt7Y29uZi5sb3d9LCB7Y29uZi5oaWdofV0iLAogICAgICAgICAgICAgY29lZl9tYXAgPSBjb2VmX2xpc3QsCiAgICAgICAgICAgICBnb2Zfb21pdCA9ICJFTFBEIiwKICAgICAgICAgICAgIGVzY2FwZSA9IEZBTFNFLAogICAgICAgICAgICAgbm90ZXMgPSBsaXN0KCJQb3N0ZXJpb3IgbWVhbnM7IDk1JSBjcmVkaWJsZSBpbnRlcnZhbHMgaW4gYnJhY2tldHMiKSkKYGBgCgojIyBDb2VmZmljaWVudHMKCmBgYHtyIHBsb3QtY29lZnMtZTFhfQpjb2VmX3Bsb3RzIDwtIG1vZGVscyAlPiUgCiAgZmlsdGVyKHN0cl9kZXRlY3QobW9kZWwsICJwdHNfIiksICFzdHJfZGV0ZWN0KG1vZGVsLCAiYmFzZWxpbmUiKSkgJT4lIAogIG11dGF0ZShyZV9mYW5jeSA9IGNhc2Vfd2hlbigKICAgIHJlID09ICJSRSIgfiAiUmFuZG9tIGVmZmVjdHMgbW9kZWxzIiwKICAgIHJlID09ICJSRVdCIiB+ICJSYW5kb20gZWZmZWN0c+KAlHdpdGhpbi9iZXR3ZWVuIG1vZGVscyIKICApKSAlPiUgCiAgbXV0YXRlKGNvZWZfZHJhd3MgPSBtYXAoCiAgICBhY3R1YWxfbW9kZWwsIAogICAgfmdhdGhlcl9kcmF3cyhtb2RlbCA9IC4sIGAuKmJhcnJpZXJzLip8LiphZHZvY2FjeS4qfC4qZW50cnkuKnwuKmZ1bmRpbmcuKmAsIHJlZ2V4ID0gVFJVRSkpKSAlPiUgCiAgc2VsZWN0KC1hY3R1YWxfbW9kZWwpICU+JSAKICB1bm5lc3QoY29lZl9kcmF3cykgJT4lIAogIGZpbHRlcighc3RyX2RldGVjdCgudmFyaWFibGUsICJiZXR3ZWVuIikpICU+JSAKICBsZWZ0X2pvaW4oY29lZnNfY2xlYW4sIGJ5ID0gYygiLnZhcmlhYmxlIiA9ICJjb2VmIikpCgpjb2VmX3Bsb3RzICU+JSAKICBnZ3Bsb3QoYWVzKHkgPSBmY3RfcmV2KGNvZWZfY2xlYW4pLCB4ID0gLnZhbHVlLCBmaWxsID0gcmVfZmFuY3kpKSArCiAgc3RhdF9oYWxmZXllKGFlcyhhbHBoYSA9IGxhZ2dpbmcpLCAud2lkdGggPSBjKDAuOCwgMC45NSkpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArCiAgZ3VpZGVzKGZpbGwgPSBGQUxTRSwgYWxwaGEgPSBGQUxTRSkgKwogIHNjYWxlX2FscGhhX21hbnVhbCh2YWx1ZXMgPSBjKDEsIDAuNCkpICsKICBsYWJzKHggPSAiQ29lZmZpY2llbnQiLCB5ID0gTlVMTCkgKwogIGZhY2V0X3dyYXAodmFycyhyZV9mYW5jeSksIG5jb2wgPSAyLCBzY2FsZXMgPSAiZnJlZV95IikgKwogIHRoZW1lX25nbygpCmBgYAoKCiMjIE1hcmdpbmFsIGVmZmVjdHMKCmBgYHtyIHBsb3QtbWZ4LWUxYX0KcGxvdF9wdHNfdmFyc19sb29rdXAgPC0gdHJpYmJsZSgKICB+bW9kZWwsIH5wbG90X3ZhciwgfnBsb3RfdmFyX25pY2UsCiAgIm1fcHRzX3RvdGFsIiwgImJhcnJpZXJzX3RvdGFsIiwgIlRvdGFsIGxlZ2FsIGJhcnJpZXJzIiwKICAibV9wdHNfdG90YWxfbmV3IiwgImJhcnJpZXJzX3RvdGFsX25ldyIsICJOZXcgbGVnYWwgYmFycmllcnMiLAogICJtX3B0c19hZHZvY2FjeSIsICJhZHZvY2FjeSIsICJCYXJyaWVycyB0byBhZHZvY2FjeSIsCiAgIm1fcHRzX2VudHJ5IiwgImVudHJ5IiwgIkJhcnJpZXJzIHRvIGVudHJ5IiwKICAibV9wdHNfZnVuZGluZyIsICJmdW5kaW5nIiwgIkJhcnJpZXJzIHRvIGZ1bmRpbmciCikgJT4lIAogIG11dGF0ZShwbG90X3Zhcl9uaWNlID0gZmN0X2lub3JkZXIocGxvdF92YXJfbmljZSwgb3JkZXJlZCA9IFRSVUUpKQoKbWZ4IDwtIG1vZGVscyAlPiUgCiAgZmlsdGVyKHN0cl9kZXRlY3QobW9kZWwsICJfcHRzIiksICFzdHJfZGV0ZWN0KG1vZGVsLCAicmV3YnxiYXNlbGluZSIpKSAlPiUgCiAgbGVmdF9qb2luKHBsb3RfcHRzX3ZhcnNfbG9va3VwLCBieSA9ICJtb2RlbCIpICU+JSAKICBtdXRhdGUoZnggPSBtYXAyKGFjdHVhbF9tb2RlbCwgcGxvdF92YXIsIAogICAgICAgICAgICAgICAgICAgfmNvbmRpdGlvbmFsX2VmZmVjdHMoLngsIGVmZmVjdHMgPSAueSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGVnb3JpY2FsID0gVFJVRSlbWzFdXSkpICU+JSAKICBzZWxlY3QoLWFjdHVhbF9tb2RlbCkgJT4lIAogIHVubmVzdChmeCkKCm1meCAlPiUgCiAgbXV0YXRlKHhfcm91bmRlZCA9IGZsb29yKGVmZmVjdDFfXykpICU+JSAKICBncm91cF9ieSh4X3JvdW5kZWQsIGVmZmVjdDJfXywgcGxvdF92YXJfbmljZSkgJT4lIAogIHNsaWNlKDEpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHhfcm91bmRlZCwgeSA9IGVzdGltYXRlX18sIGNvbG9yID0gZWZmZWN0Ml9fKSkgKwogIGdlb21fcG9pbnRyYW5nZShhZXMoeW1pbiA9IGxvd2VyX18sIHltYXggPSB1cHBlcl9fKSwKICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuMiksCiAgICAgICAgICAgICAgICAgIGZhdHRlbiA9IDEpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gMDo5KSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gInZpcmlkaXMiLCBlbmQgPSAwLjk1KSArCiAgbGFicyh4ID0gIkNvdW50IG9mIGxlZ2FsIGJhcnJpZXJzXG4iLAogICAgICAgeSA9ICJQcmVkaWN0ZWQgcHJvYmFiaWxpdHkgb2YgY2F0ZWdvcnkiLAogICAgICAgY29sb3IgPSAiUG9saXRpY2FsIHRlcnJvciBzY2FsZSIsIGZpbGwgPSAiUG9saXRpY2FsIHRlcnJvciBzY2FsZSIpICsgCiAgZmFjZXRfd3JhcCh2YXJzKHBsb3RfdmFyX25pY2UpLCBzY2FsZXMgPSAiZnJlZV94IikgKwogIHRoZW1lX25nbygpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKXCAKCiMgRX4xYn46IE5HTyBsYXdzIGFuZCBwaHlzaWNhbCB2aW9sZW5jZQoKIyMgUmVzdWx0cyB0YWJsZQoKYGBge3IgdGJsLWUxYi1yZX0KbW9kZWxzX2Zvcl90YWJsZV9lMWJfcmUgPC0gbW9kZWxzICU+JSAKICBmaWx0ZXIob3V0Y29tZV92YXIgPT0gIlBoeXNpY2FsIHZpb2xlbmNlIiwgcmUgPT0gIlJFIikgJT4lIAogIG11dGF0ZShtb2RlbF9uYW1lID0gZ2x1ZSgie291dGNvbWVfdmFyfSAodCArIDEpPGJyPih7ZXhwbGFuX3Zhcn07IHtyZX0pIikpCgptb2RlbF9uYW1lc190YmxfZTFiX3JlIDwtIG1vZGVsc19mb3JfdGFibGVfZTFiX3JlICU+JSAKICBwdWxsKG1vZGVsX25hbWUpICU+JSAKICBzZXRfbmFtZXMobW9kZWxzX2Zvcl90YWJsZV9lMWJfcmUkbW9kZWwpCgpuYW1lcyhtb2RlbHNfdGJsX2UxYl9yZSkgPC0gcmVjb2RlKG5hbWVzKG1vZGVsc190YmxfZTFiX3JlKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgISEhbW9kZWxfbmFtZXNfdGJsX2UxYl9yZSkKCm1vZGVsc3VtbWFyeShtb2RlbHNfdGJsX2UxYl9yZSwKICAgICAgICAgICAgIHN0YXRpc3RpYyA9ICJbe2NvbmYubG93fSwge2NvbmYuaGlnaH1dIiwKICAgICAgICAgICAgIGNvZWZfbWFwID0gY29lZl9saXN0LAogICAgICAgICAgICAgZ29mX29taXQgPSAiRUxQRCIsCiAgICAgICAgICAgICBlc2NhcGUgPSBGQUxTRSwKICAgICAgICAgICAgIG5vdGVzID0gbGlzdCgiUG9zdGVyaW9yIG1lYW5zOyA5NSUgY3JlZGlibGUgaW50ZXJ2YWxzIGluIGJyYWNrZXRzIikpCmBgYAoKIyMgQ29lZmZpY2llbnRzCgpgYGB7ciBwbG90LWNvZWZzLWUxYn0KY29lZl9wbG90cyA8LSBtb2RlbHMgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KG1vZGVsLCAiY2xwaHkiKSwgIXN0cl9kZXRlY3QobW9kZWwsICJiYXNlbGluZSIpKSAlPiUgCiAgbXV0YXRlKHJlX2ZhbmN5ID0gY2FzZV93aGVuKAogICAgcmUgPT0gIlJFIiB+ICJSYW5kb20gZWZmZWN0cyBtb2RlbHMiLAogICAgcmUgPT0gIlJFV0IiIH4gIlJhbmRvbSBlZmZlY3Rz4oCUd2l0aGluL2JldHdlZW4gbW9kZWxzIgogICkpICU+JSAKICBtdXRhdGUoY29lZl9kcmF3cyA9IG1hcCgKICAgIGFjdHVhbF9tb2RlbCwgCiAgICB+Z2F0aGVyX2RyYXdzKG1vZGVsID0gLiwgYC4qYmFycmllcnMuKnwuKmFkdm9jYWN5Lip8LiplbnRyeS4qfC4qZnVuZGluZy4qYCwgcmVnZXggPSBUUlVFKSkpICU+JSAKICBzZWxlY3QoLWFjdHVhbF9tb2RlbCkgJT4lIAogIHVubmVzdChjb2VmX2RyYXdzKSAlPiUgCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KC52YXJpYWJsZSwgImJldHdlZW4iKSkgJT4lIAogIGxlZnRfam9pbihjb2Vmc19jbGVhbiwgYnkgPSBjKCIudmFyaWFibGUiID0gImNvZWYiKSkKCmNvZWZfcGxvdHMgJT4lIAogIGdncGxvdChhZXMoeSA9IGZjdF9yZXYoY29lZl9jbGVhbiksIHggPSAudmFsdWUsIGZpbGwgPSByZV9mYW5jeSkpICsKICBzdGF0X2hhbGZleWUoYWVzKGFscGhhID0gbGFnZ2luZyksIC53aWR0aCA9IGMoMC44LCAwLjk1KSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDApICsKICBndWlkZXMoZmlsbCA9IEZBTFNFLCBhbHBoYSA9IEZBTFNFKSArCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoMSwgMC40KSkgKwogIGxhYnMoeCA9ICJDb2VmZmljaWVudCIsIHkgPSBOVUxMKSArCiAgZmFjZXRfd3JhcCh2YXJzKHJlX2ZhbmN5KSwgbmNvbCA9IDIsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgdGhlbWVfbmdvKCkKYGBgCgojIyBNYXJnaW5hbCBlZmZlY3RzCgpgYGB7ciBwbG90LW1meC1lMWJ9CnBsb3RfY2xwaHlfdmFyc19sb29rdXAgPC0gdHJpYmJsZSgKICB+bW9kZWwsIH5wbG90X3ZhciwgfnBsb3RfdmFyX25pY2UsCiAgIm1fY2xwaHlfdG90YWwiLCAiYmFycmllcnNfdG90YWwiLCAiVG90YWwgbGVnYWwgYmFycmllcnMiLAogICJtX2NscGh5X3RvdGFsX25ldyIsICJiYXJyaWVyc190b3RhbF9uZXciLCAiTmV3IGxlZ2FsIGJhcnJpZXJzIiwKICAibV9jbHBoeV9hZHZvY2FjeSIsICJhZHZvY2FjeSIsICJBZHZvY2FjeSIsCiAgIm1fY2xwaHlfZW50cnkiLCAiZW50cnkiLCAiRW50cnkiLAogICJtX2NscGh5X2Z1bmRpbmciLCAiZnVuZGluZyIsICJGdW5kaW5nIgopICU+JSAKICBtdXRhdGUocGxvdF92YXJfbmljZSA9IGZjdF9pbm9yZGVyKHBsb3RfdmFyX25pY2UsIG9yZGVyZWQgPSBUUlVFKSkKCm1meCA8LSBtb2RlbHMgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KG1vZGVsLCAiY2xwaHkiKSwgIXN0cl9kZXRlY3QobW9kZWwsICJyZXdifGJhc2VsaW5lIikpICU+JSAKICBsZWZ0X2pvaW4ocGxvdF9jbHBoeV92YXJzX2xvb2t1cCwgYnkgPSAibW9kZWwiKSAlPiUgCiAgbXV0YXRlKGZ4ID0gbWFwMihhY3R1YWxfbW9kZWwsIHBsb3RfdmFyLCAKICAgICAgICAgICAgICAgICAgIH5jb25kaXRpb25hbF9lZmZlY3RzKC54LCBlZmZlY3RzID0gLnkpW1sxXV0pKSAlPiUgCiAgc2VsZWN0KC1hY3R1YWxfbW9kZWwpICU+JSAKICB1bm5lc3QoZngpCgptZnggJT4lIAogIG11dGF0ZSh4X3JvdW5kZWQgPSBmbG9vcihlZmZlY3QxX18pKSAlPiUgCiAgZ3JvdXBfYnkoeF9yb3VuZGVkLCBwbG90X3Zhcl9uaWNlKSAlPiUgCiAgc2xpY2UoMSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0geF9yb3VuZGVkLCB5ID0gZXN0aW1hdGVfXywgY29sb3IgPSBwbG90X3Zhcl9uaWNlKSkgKwogIGdlb21fbGluZShzaXplID0gMC41LCBjb2xvciA9ICJncmV5OTAiKSArCiAgZ2VvbV9wb2ludHJhbmdlKGFlcyh5bWluID0gbG93ZXJfXywgeW1heCA9IHVwcGVyX18pLAogICAgICAgICAgICAgICAgICBmYXR0ZW4gPSAxKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDA6OSkgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAicGxhc21hIiwgZW5kID0gMC44KSArCiAgZ3VpZGVzKGNvbG9yID0gRkFMU0UpICsKICBsYWJzKHggPSAiQ291bnQgb2YgbGVnYWwgYmFycmllcnMiLAogICAgICAgeSA9ICJQcmVkaWN0ZWQgcGh5c2ljYWwgdmlvbGVuY2UgaW5kZXhcbihoaWdoZXIgdmFsdWVzID0gbGVzcyB2aW9sZW5jZSkiKSArCiAgZmFjZXRfZ3JpZChjb2xzID0gdmFycyhwbG90X3Zhcl9uaWNlKSwgc2NhbGVzID0gImZyZWVfeCIsIHNwYWNlID0gImZyZWVfeCIpICsKICB0aGVtZV9uZ28oKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpKQpgYGAKClwgCgojIEV+MWN+OiBOR08gbGF3cyBhbmQgY2l2aWwgbGliZXJ0aWVzCgojIyBSZXN1bHRzIHRhYmxlCgpgYGB7ciB0YmwtZTFjLXJlfQptb2RlbHNfZm9yX3RhYmxlX2UxY19yZSA8LSBtb2RlbHMgJT4lIAogIGZpbHRlcihvdXRjb21lX3ZhciA9PSAiUHJpdmF0ZSBjaXZpbCBsaWJlcnRpZXMiLCByZSA9PSAiUkUiKSAlPiUgCiAgbXV0YXRlKG1vZGVsX25hbWUgPSBnbHVlKCJ7b3V0Y29tZV92YXJ9ICh0ICsgMSk8YnI+KHtleHBsYW5fdmFyfTsge3JlfSkiKSkKCm1vZGVsX25hbWVzX3RibF9lMWNfcmUgPC0gbW9kZWxzX2Zvcl90YWJsZV9lMWNfcmUgJT4lIAogIHB1bGwobW9kZWxfbmFtZSkgJT4lIAogIHNldF9uYW1lcyhtb2RlbHNfZm9yX3RhYmxlX2UxY19yZSRtb2RlbCkKCm5hbWVzKG1vZGVsc190YmxfZTFjX3JlKSA8LSByZWNvZGUobmFtZXMobW9kZWxzX3RibF9lMWNfcmUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhISFtb2RlbF9uYW1lc190YmxfZTFjX3JlKQoKbW9kZWxzdW1tYXJ5KG1vZGVsc190YmxfZTFjX3JlLAogICAgICAgICAgICAgc3RhdGlzdGljID0gIlt7Y29uZi5sb3d9LCB7Y29uZi5oaWdofV0iLAogICAgICAgICAgICAgY29lZl9tYXAgPSBjb2VmX2xpc3QsCiAgICAgICAgICAgICBnb2Zfb21pdCA9ICJFTFBEIiwKICAgICAgICAgICAgIGVzY2FwZSA9IEZBTFNFLAogICAgICAgICAgICAgbm90ZXMgPSBsaXN0KCJQb3N0ZXJpb3IgbWVhbnM7IDk1JSBjcmVkaWJsZSBpbnRlcnZhbHMgaW4gYnJhY2tldHMiKSkKYGBgCgojIyBDb2VmZmljaWVudHMKCmBgYHtyIHBsb3QtY29lZnMtZTFjfQpjb2VmX3Bsb3RzIDwtIG1vZGVscyAlPiUgCiAgZmlsdGVyKHN0cl9kZXRlY3QobW9kZWwsICJjbHByaXYiKSwgIXN0cl9kZXRlY3QobW9kZWwsICJiYXNlbGluZSIpKSAlPiUgCiAgbXV0YXRlKHJlX2ZhbmN5ID0gY2FzZV93aGVuKAogICAgcmUgPT0gIlJFIiB+ICJSYW5kb20gZWZmZWN0cyBtb2RlbHMiLAogICAgcmUgPT0gIlJFV0IiIH4gIlJhbmRvbSBlZmZlY3Rz4oCUd2l0aGluL2JldHdlZW4gbW9kZWxzIgogICkpICU+JSAKICBtdXRhdGUoY29lZl9kcmF3cyA9IG1hcCgKICAgIGFjdHVhbF9tb2RlbCwgCiAgICB+Z2F0aGVyX2RyYXdzKG1vZGVsID0gLiwgYC4qYmFycmllcnMuKnwuKmFkdm9jYWN5Lip8LiplbnRyeS4qfC4qZnVuZGluZy4qYCwgcmVnZXggPSBUUlVFKSkpICU+JSAKICBzZWxlY3QoLWFjdHVhbF9tb2RlbCkgJT4lIAogIHVubmVzdChjb2VmX2RyYXdzKSAlPiUgCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KC52YXJpYWJsZSwgImJldHdlZW4iKSkgJT4lIAogIGxlZnRfam9pbihjb2Vmc19jbGVhbiwgYnkgPSBjKCIudmFyaWFibGUiID0gImNvZWYiKSkKCmNvZWZfcGxvdHMgJT4lIAogIGdncGxvdChhZXMoeSA9IGZjdF9yZXYoY29lZl9jbGVhbiksIHggPSAudmFsdWUsIGZpbGwgPSByZV9mYW5jeSkpICsKICBzdGF0X2hhbGZleWUoYWVzKGFscGhhID0gbGFnZ2luZyksIC53aWR0aCA9IGMoMC44LCAwLjk1KSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDApICsKICBndWlkZXMoZmlsbCA9IEZBTFNFLCBhbHBoYSA9IEZBTFNFKSArCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoMSwgMC40KSkgKwogIGxhYnMoeCA9ICJDb2VmZmljaWVudCIsIHkgPSBOVUxMKSArCiAgZmFjZXRfd3JhcCh2YXJzKHJlX2ZhbmN5KSwgbmNvbCA9IDIsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgdGhlbWVfbmdvKCkKYGBgCgojIyBNYXJnaW5hbCBlZmZlY3RzCgpgYGB7ciBwbG90LW1meC1lMWN9CnBsb3RfY2xwcml2X3ZhcnNfbG9va3VwIDwtIHRyaWJibGUoCiAgfm1vZGVsLCB+cGxvdF92YXIsIH5wbG90X3Zhcl9uaWNlLAogICJtX2NscHJpdl90b3RhbCIsICJiYXJyaWVyc190b3RhbCIsICJUb3RhbCBsZWdhbCBiYXJyaWVycyIsCiAgIm1fY2xwcml2X3RvdGFsX25ldyIsICJiYXJyaWVyc190b3RhbF9uZXciLCAiTmV3IGxlZ2FsIGJhcnJpZXJzIiwKICAibV9jbHByaXZfYWR2b2NhY3kiLCAiYWR2b2NhY3kiLCAiQWR2b2NhY3kiLAogICJtX2NscHJpdl9lbnRyeSIsICJlbnRyeSIsICJFbnRyeSIsCiAgIm1fY2xwcml2X2Z1bmRpbmciLCAiZnVuZGluZyIsICJGdW5kaW5nIgopICU+JSAKICBtdXRhdGUocGxvdF92YXJfbmljZSA9IGZjdF9pbm9yZGVyKHBsb3RfdmFyX25pY2UsIG9yZGVyZWQgPSBUUlVFKSkKCm1meCA8LSBtb2RlbHMgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KG1vZGVsLCAiY2xwcml2IiksICFzdHJfZGV0ZWN0KG1vZGVsLCAicmV3YnxiYXNlbGluZSIpKSAlPiUgCiAgbGVmdF9qb2luKHBsb3RfY2xwcml2X3ZhcnNfbG9va3VwLCBieSA9ICJtb2RlbCIpICU+JSAKICBtdXRhdGUoZnggPSBtYXAyKGFjdHVhbF9tb2RlbCwgcGxvdF92YXIsIAogICAgICAgICAgICAgICAgICAgfmNvbmRpdGlvbmFsX2VmZmVjdHMoLngsIGVmZmVjdHMgPSAueSlbWzFdXSkpICU+JSAKICBzZWxlY3QoLWFjdHVhbF9tb2RlbCkgJT4lIAogIHVubmVzdChmeCkKCm1meCAlPiUgCiAgbXV0YXRlKHhfcm91bmRlZCA9IGZsb29yKGVmZmVjdDFfXykpICU+JSAKICBncm91cF9ieSh4X3JvdW5kZWQsIHBsb3RfdmFyX25pY2UpICU+JSAKICBzbGljZSgxKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSB4X3JvdW5kZWQsIHkgPSBlc3RpbWF0ZV9fLCBjb2xvciA9IHBsb3RfdmFyX25pY2UpKSArCiAgZ2VvbV9saW5lKHNpemUgPSAwLjUsIGNvbG9yID0gImdyZXk5MCIpICsKICBnZW9tX3BvaW50cmFuZ2UoYWVzKHltaW4gPSBsb3dlcl9fLCB5bWF4ID0gdXBwZXJfXyksCiAgICAgICAgICAgICAgICAgIGZhdHRlbiA9IDEpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gMDo5KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJwbGFzbWEiLCBlbmQgPSAwLjgpICsKICBndWlkZXMoY29sb3IgPSBGQUxTRSkgKwogIGxhYnMoeCA9ICJDb3VudCBvZiBsZWdhbCBiYXJyaWVycyIsCiAgICAgICB5ID0gIlByZWRpY3RlZCBjaXZpbCBsaWJlcnRpZXMgaW5kZXhcbihoaWdoZXIgdmFsdWVzID0gYmV0dGVyIHByb3RlY3Rpb24pIikgKwogIGZhY2V0X2dyaWQoY29scyA9IHZhcnMocGxvdF92YXJfbmljZSksIHNjYWxlcyA9ICJmcmVlX3giLCBzcGFjZSA9ICJmcmVlX3giKSArCiAgdGhlbWVfbmdvKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgpcIAoKIyBFfjFkfjogTkdPIGxhd3MgYW5kIGxhdGVudCBwaHlzaWNhbCBpbnRlZ3JpdHkgcmlnaHRzCgojIyBSZXN1bHRzIHRhYmxlCgpgYGB7ciB0YmwtZTFkLXJlfQptb2RlbHNfZm9yX3RhYmxlX2UxZF9yZSA8LSBtb2RlbHMgJT4lIAogIGZpbHRlcihvdXRjb21lX3ZhciA9PSAiTGF0ZW50IGh1bWFuIHJpZ2h0cyIsIHJlID09ICJSRSIpICU+JSAKICBtdXRhdGUobW9kZWxfbmFtZSA9IGdsdWUoIntvdXRjb21lX3Zhcn0gKHQgKyAxKTxicj4oe2V4cGxhbl92YXJ9OyB7cmV9KSIpKQoKbW9kZWxfbmFtZXNfdGJsX2UxZF9yZSA8LSBtb2RlbHNfZm9yX3RhYmxlX2UxZF9yZSAlPiUgCiAgcHVsbChtb2RlbF9uYW1lKSAlPiUgCiAgc2V0X25hbWVzKG1vZGVsc19mb3JfdGFibGVfZTFkX3JlJG1vZGVsKQoKbmFtZXMobW9kZWxzX3RibF9lMWRfcmUpIDwtIHJlY29kZShuYW1lcyhtb2RlbHNfdGJsX2UxZF9yZSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICEhIW1vZGVsX25hbWVzX3RibF9lMWRfcmUpCgptb2RlbHN1bW1hcnkobW9kZWxzX3RibF9lMWRfcmUsCiAgICAgICAgICAgICBzdGF0aXN0aWMgPSAiW3tjb25mLmxvd30sIHtjb25mLmhpZ2h9XSIsCiAgICAgICAgICAgICBjb2VmX21hcCA9IGNvZWZfbGlzdCwKICAgICAgICAgICAgIGdvZl9vbWl0ID0gIkVMUEQiLAogICAgICAgICAgICAgZXNjYXBlID0gRkFMU0UsCiAgICAgICAgICAgICBub3RlcyA9IGxpc3QoIlBvc3RlcmlvciBtZWFuczsgOTUlIGNyZWRpYmxlIGludGVydmFscyBpbiBicmFja2V0cyIpKQpgYGAKCiMjIENvZWZmaWNpZW50cwoKYGBge3IgcGxvdC1jb2Vmcy1lMWR9CmNvZWZfcGxvdHMgPC0gbW9kZWxzICU+JSAKICBmaWx0ZXIoc3RyX2RldGVjdChtb2RlbCwgImxociIpLCAhc3RyX2RldGVjdChtb2RlbCwgImJhc2VsaW5lIikpICU+JSAKICBtdXRhdGUocmVfZmFuY3kgPSBjYXNlX3doZW4oCiAgICByZSA9PSAiUkUiIH4gIlJhbmRvbSBlZmZlY3RzIG1vZGVscyIsCiAgICByZSA9PSAiUkVXQiIgfiAiUmFuZG9tIGVmZmVjdHPigJR3aXRoaW4vYmV0d2VlbiBtb2RlbHMiCiAgKSkgJT4lIAogIG11dGF0ZShjb2VmX2RyYXdzID0gbWFwKAogICAgYWN0dWFsX21vZGVsLCAKICAgIH5nYXRoZXJfZHJhd3MobW9kZWwgPSAuLCBgLipiYXJyaWVycy4qfC4qYWR2b2NhY3kuKnwuKmVudHJ5Lip8LipmdW5kaW5nLipgLCByZWdleCA9IFRSVUUpKSkgJT4lIAogIHNlbGVjdCgtYWN0dWFsX21vZGVsKSAlPiUgCiAgdW5uZXN0KGNvZWZfZHJhd3MpICU+JSAKICBmaWx0ZXIoIXN0cl9kZXRlY3QoLnZhcmlhYmxlLCAiYmV0d2VlbiIpKSAlPiUgCiAgbGVmdF9qb2luKGNvZWZzX2NsZWFuLCBieSA9IGMoIi52YXJpYWJsZSIgPSAiY29lZiIpKQoKY29lZl9wbG90cyAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3Jldihjb2VmX2NsZWFuKSwgeCA9IC52YWx1ZSwgZmlsbCA9IHJlX2ZhbmN5KSkgKwogIHN0YXRfaGFsZmV5ZShhZXMoYWxwaGEgPSBsYWdnaW5nKSwgLndpZHRoID0gYygwLjgsIDAuOTUpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKwogIGd1aWRlcyhmaWxsID0gRkFMU0UsIGFscGhhID0gRkFMU0UpICsKICBzY2FsZV9hbHBoYV9tYW51YWwodmFsdWVzID0gYygxLCAwLjQpKSArCiAgbGFicyh4ID0gIkNvZWZmaWNpZW50IiwgeSA9IE5VTEwpICsKICBmYWNldF93cmFwKHZhcnMocmVfZmFuY3kpLCBuY29sID0gMiwgc2NhbGVzID0gImZyZWVfeSIpICsKICB0aGVtZV9uZ28oKQpgYGAKCiMjIE1hcmdpbmFsIGVmZmVjdHMKCmBgYHtyIHBsb3QtbWZ4LWUxZH0KcGxvdF9saHJfdmFyc19sb29rdXAgPC0gdHJpYmJsZSgKICB+bW9kZWwsIH5wbG90X3ZhciwgfnBsb3RfdmFyX25pY2UsCiAgIm1fbGhyX3RvdGFsIiwgImJhcnJpZXJzX3RvdGFsIiwgIlRvdGFsIGxlZ2FsIGJhcnJpZXJzIiwKICAibV9saHJfdG90YWxfbmV3IiwgImJhcnJpZXJzX3RvdGFsX25ldyIsICJOZXcgbGVnYWwgYmFycmllcnMiLAogICJtX2xocl9hZHZvY2FjeSIsICJhZHZvY2FjeSIsICJBZHZvY2FjeSIsCiAgIm1fbGhyX2VudHJ5IiwgImVudHJ5IiwgIkVudHJ5IiwKICAibV9saHJfZnVuZGluZyIsICJmdW5kaW5nIiwgIkZ1bmRpbmciCikgJT4lIAogIG11dGF0ZShwbG90X3Zhcl9uaWNlID0gZmN0X2lub3JkZXIocGxvdF92YXJfbmljZSwgb3JkZXJlZCA9IFRSVUUpKQoKbWZ4IDwtIG1vZGVscyAlPiUgCiAgZmlsdGVyKHN0cl9kZXRlY3QobW9kZWwsICJsaHIiKSwgIXN0cl9kZXRlY3QobW9kZWwsICJyZXdifGJhc2VsaW5lIikpICU+JSAKICBsZWZ0X2pvaW4ocGxvdF9saHJfdmFyc19sb29rdXAsIGJ5ID0gIm1vZGVsIikgJT4lIAogIG11dGF0ZShmeCA9IG1hcDIoYWN0dWFsX21vZGVsLCBwbG90X3ZhciwgCiAgICAgICAgICAgICAgICAgICB+Y29uZGl0aW9uYWxfZWZmZWN0cygueCwgZWZmZWN0cyA9IC55KVtbMV1dKSkgJT4lIAogIHNlbGVjdCgtYWN0dWFsX21vZGVsKSAlPiUgCiAgdW5uZXN0KGZ4KQoKbWZ4ICU+JSAKICBtdXRhdGUoeF9yb3VuZGVkID0gZmxvb3IoZWZmZWN0MV9fKSkgJT4lIAogIGdyb3VwX2J5KHhfcm91bmRlZCwgcGxvdF92YXJfbmljZSkgJT4lIAogIHNsaWNlKDEpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHhfcm91bmRlZCwgeSA9IGVzdGltYXRlX18sIGNvbG9yID0gcGxvdF92YXJfbmljZSkpICsKICBnZW9tX2xpbmUoc2l6ZSA9IDAuNSwgY29sb3IgPSAiZ3JleTkwIikgKwogIGdlb21fcG9pbnRyYW5nZShhZXMoeW1pbiA9IGxvd2VyX18sIHltYXggPSB1cHBlcl9fKSwKICAgICAgICAgICAgICAgICAgZmF0dGVuID0gMSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAwOjkpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gInBsYXNtYSIsIGVuZCA9IDAuOCkgKwogIGd1aWRlcyhjb2xvciA9IEZBTFNFKSArCiAgbGFicyh4ID0gIkNvdW50IG9mIGxlZ2FsIGJhcnJpZXJzIiwKICAgICAgIHkgPSAiUHJlZGljdGVkIGxhdGVudCBodW1hbiByaWdodHMgdmFsdWVcbihoaWdoZXIgdmFsdWVzID0gYmV0dGVyIGh1bWFuIHJpZ2h0cykiKSArCiAgZmFjZXRfZ3JpZChjb2xzID0gdmFycyhwbG90X3Zhcl9uaWNlKSwgc2NhbGVzID0gImZyZWVfeCIsIHNwYWNlID0gImZyZWVfeCIpICsKICB0aGVtZV9uZ28oKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpKQpgYGAK