library(tidyverse)
library(targets)
library(brms)
library(tidybayes)
library(bayesplot)
library(fixest)
library(broom)
library(broom.mixed)
library(modelsummary)
library(patchwork)
library(tictoc)
library(latex2exp)
library(scales)
library(extraDistr)
library(glue)
library(here)

color_scheme_set("viridisC")

labs_exp_logged <- function(brks) {TeX(paste0("e^{", as.character(log(brks)), "}"))}
labs_exp <- function(brks) {TeX(paste0("e^{", as.character(brks), "}"))}

my_seed <- 1234
set.seed(my_seed)

withr::with_dir(here::here(), {
  source(tar_read(plot_funs))
  source(tar_read(misc_funs))
  
  # Data
  df_country_aid <- tar_read(country_aid_final)
  df_country_aid_laws <- filter(df_country_aid, laws)
  
  # Models
  tar_load(c(m_recip_treatment_total_dom))
  tar_load(c(m_recip_outcome_total_dom, m_recip_outcome_total_foreign,
             m_recip_outcome_advocacy_dom, m_recip_outcome_advocacy_foreign,
             m_recip_outcome_entry_dom, m_recip_outcome_entry_foreign,
             m_recip_outcome_funding_dom, m_recip_outcome_funding_foreign))
})

Weight models

  • Numerator is lagged treatment + non-varying confounders
  • Denominator is lagged treatment + lagged outcome + time-varying confounders + non-varying confounders

\[ sw = \prod^t_{t = 1} \frac{\phi(T_{it} | T_{i, t-1}, C_i)}{\phi(T_{it} | T_{i, t-1}, D_{i, t-1}, C_i)} \]

Priors for weight models

We use generic weakly informative priors for our model parameters:

  • Intercept: \(\mathcal{N} (0, 10)\)
  • Coefficients: \(\mathcal{N} (0, 2.5)\)
  • Sigma: \(\operatorname{Cauchy} (0, 1)\)
pri_int <- ggplot() +
  stat_function(fun = dnorm, args = list(mean = 0, sd = 10),
                geom = "area", fill = "grey80", color = "black") +
  labs(x = TeX("\\textbf{Intercept (β_0)}")) +
  annotate(geom = "label", x = 0, y = 0.01, label = "N(0, 10)", size = pts(9)) +
  xlim(-40, 40) +
  theme_donors(prior = TRUE)

pri_coef <- ggplot() +
  stat_function(fun = dnorm, args = list(mean = 0, sd = 2.5),
                geom = "area", fill = "grey80", color = "black") +
  labs(x = TeX("\\textbf{Coefficients (β_x)}")) +
  annotate(geom = "label", x = 0, y = 0.04, label = "N(0, 3)", size = pts(9)) +
  xlim(-10, 10) +
  theme_donors(prior = TRUE)

pri_sigma <- ggplot() +
  stat_function(fun = dcauchy, args = list(location = 0, scale = 1),
                geom = "area", fill = "grey80", color = "black") +
  labs(x = "σ") +
  annotate(geom = "label", x = 5, y = 0.08, label = "Cauchy(0, 1)", size = pts(9)) +
  xlim(0, 10) +
  theme_donors(prior = TRUE)

(pri_int + pri_coef + pri_sigma)

Check weight models

We check one of the denominator models for convergence and mixing and fit (not the numerator, since those models are the same as the ones in H1).

pp_check(m_recip_treatment_total_dom$model_denom, type = "dens_overlay", nsamples = 10) +
  theme_donors()

m_recip_treatment_total_dom$model_denom %>% 
  posterior_samples(add_chain = TRUE) %>% 
  select(-starts_with("r_gwcode"), -starts_with("z_"), -lp__, -iter) %>% 
  mcmc_trace() +
  theme_donors() +
  theme(legend.position = "right")

Outcome models

Modeling choice

We use two dependent variables for this hypothesis: the proportion of USAID aid channeled through either (1) domestic or (2) international or US-based (or foreign) NGOs, once again leaded by one year. The OECD and AidData do not track the channels of aid delivery, so we cannot see how aid is distributed on a global scale. USAID, however, does track channels, so we can measure how much aid goes to domestic NGOs (and also US-based and international NGOs). USAID didn’t start tracking this until 2001, though, so we have to limit our models to 2001–2013. (Boo.)

These variables are proportions and limited to a [0, 1] range. In the original version of this project, we used logit-linear models of the ratio of domestic or foriegn aid to all other channels, like this:

\[ln( \frac{\text{Aid to (domestic or foreign) NGOs}_{\text{USAID}}}{\text{Aid to other channels}_{\text{USAID}}} )_{i, t+1} = \text{NGO legislation}_{it} + \text{controls}_{it}\]

But as mentioned in our analysis for H2, this made interpretation really strange. It also fails to account for zero- and one- inflation. These two variables have a lot of zeroes and a handful of ones, which indicates that there’s something highly systematic about the choice to (1) channel any money through any kind of NGOs and (2) how much money if so.

df_channels_plot_hist <- df_country_aid_laws %>% 
  pivot_longer(names_to = "channel", values_to = "value", 
               c(prop_ngo_dom, prop_ngo_foreign)) %>% 
  mutate(channel = recode(channel, 
                          prop_ngo_dom = "Domestic NGOs", 
                          prop_ngo_foreign = "Foreign NGOs"))

ggplot(df_channels_plot_hist, 
       aes(x = value, fill = channel, alpha = value == 0)) +
  geom_histogram(binwidth = 0.05, color = "white", boundary = 0) +
  labs(x = "Proportion of aid to NGOs", y = "Count") +
  scale_fill_manual(values = c("#001f3f", "#FF851B"), 
                    labels = c("Domestic", "International"),
                    name = NULL) +
  scale_alpha_manual(values = c(1, 0.5), 
                     labels = c("% > 0", "% = 0"),
                     name = NULL) +
  guides(fill = FALSE) +
  scale_x_continuous(labels = percent_format(accuracy = 1)) +
  facet_wrap(vars(channel)) +
  theme_donors()

# Percent where prop_ngo_dom/foreign is 0:
df_channels_plot_hist %>% 
  count(channel, value == 0) %>% 
  group_by(channel) %>% 
  mutate(prop = n / sum(n))
## # A tibble: 4 x 4
## # Groups:   channel [2]
##   channel       `value == 0`     n  prop
##   <chr>         <lgl>        <int> <dbl>
## 1 Domestic NGOs FALSE         1841 0.559
## 2 Domestic NGOs TRUE          1452 0.441
## 3 Foreign NGOs  FALSE         1905 0.578
## 4 Foreign NGOs  TRUE          1388 0.422

Around 40% of observations are zero for both domestic and international NGOs, which is a lot (in H2, ≈18% of rows had 0% contentious aid). Accordingly, it’s really important to model both the choice of whether to channel aid to NGOs and how much.

We thus use zero-inflated beta regression. We do not use zero-one-inflated regression because there are so few 1-only rows and we’re less interested in why a country would channel all its aid through NGOs (also, that’s more likely a sign of low aid to a country and just an artefact of the data generating process). We winsorize the few 1-only rows to 0.999.

As explained in H2, zero-inflated beta models use a logit model to predict 0/not 0 and then use a beta family to model the rest of the data. In H2 we were less interested in the mechanics of the zero-inflation process and modeled it with an intercept-only logit model. Here, though, given that there are so many 0s, we use the same confounders that we used in the weights model. We do not include inverse probability weights in the zero-inflation part because (1) the inner mechanics of brms don’t allow for that and (2) I’m not sure that works with marginal structural models anyway.

Priors for outcome models

Once again there are a ton of moving parts in these outcome models. Here’s the full specification for the models and all priors:

\[ \begin{aligned} \text{y}_{i,t} | u_i, \text{Law}_{i, t} &\sim \operatorname{ZIBeta} (Z_i, \text{y}^\star_i, \phi_i) & \text{[likelihood]} \\ \operatorname{logit} (Z_i) &\sim \alpha_Z & \text{[logit if } \text{y}_{i, t} = 0 \text{]} \\ \operatorname{logit} (\text{y}^\star_i) &\sim (\beta_0 + \beta_1 \text{Law}_{i, t} + \beta_2 \text{Law}_{i, t-1}, \sigma^2_\epsilon, u_i) \times \text{IPW}_{i, t} & \text{[if } \text{y}_{i, t} > 0 \text{]}\\ \log (\phi_i) &\sim \alpha_\phi & \text{[intercept-only model for precision]} \\ u_i &\sim \mathcal{N} (0, \sigma^2_u) & \text{[country-specific intercepts]} \\ \ \\ \alpha_Z &\sim \operatorname{Logistic}(-0.5, 0.35) & \text{[prior proportion of rows where y = 0]} \\ \alpha_\phi &\sim \operatorname{Gamma} (0.01, 0.01) & \text{[prior Beta precision]} \\ \beta_0 &\sim \mathcal{N} (0, 10) & \text{[prior population intercept]} \\ \beta_1, \beta_2 &\sim \mathcal{N} (0, 3) & \text{[prior population effects]} \\ \sigma^2_e, \sigma^2_u &\sim \operatorname{Cauchy}(0, 1) & \text{[prior sd for population and country]} \\ \ \\ \text{IPW}_{i, t} &= \prod^t_{t = 1} \frac{\phi(T_{it} | T_{i, t-1}, C_i)}{\phi(T_{it} | T_{i, t-1}, D_{i, t-1}, C_i)} & \text{[stabilized weights]} \end{aligned} \]

For \(\phi\), we just use Stan’s default Gamma(0.01, 0.01). Here’s what all these prior distributions look like:

z_p <- ggplot() +
  stat_function(fun = dlogis, args = list(location = -1.5, scale = 0.5),
                geom = "area", fill = "grey80", color = "black") +
  labs(x = TeX("\\textbf{Prop. contentious = 0 (α_Z)}")) +
  annotate(geom = "label", x = -2, y = 0.07, label = "Logistic(-1.5, 0.5)", size = pts(9)) +
  xlim(-8, 3) +
  theme_donors(prior = TRUE)

b0_p <- ggplot() +
  stat_function(fun = dnorm, args = list(mean = 0, sd = 10),
                geom = "area", fill = "grey80", color = "black") +
  labs(x = TeX("\\textbf{Population intercept (β_0)}")) +
  annotate(geom = "label", x = 0, y = 0.0042, label = "N(0, 10)", size = pts(9)) +
  xlim(-40, 40) +
  theme_donors(prior = TRUE)

b12_p <- ggplot() +
  stat_function(fun = dnorm, args = list(mean = 0, sd = 3),
                geom = "area", fill = "grey80", color = "black") +
  labs(x = TeX("\\textbf{Population effects (β_1, β_2)}")) +
  annotate(geom = "label", x = 0, y = 0.02, label = "N(0, 3)", size = pts(9)) +
  xlim(-10, 10) +
  theme_donors(prior = TRUE)

sigma_p <- ggplot() +
  stat_function(fun = dcauchy, args = list(location = 0, scale = 1),
                geom = "area", fill = "grey80", color = "black") +
  labs(x = TeX("\\textbf{Population and country SD (σ_e, σ_u)}")) +
  annotate(geom = "label", x = 5, y = 0.04, label = "Cauchy(0, 1)", size = pts(9)) +
  xlim(0, 10) +
  theme_donors(prior = TRUE)

phi_p <- ggplot() +
  stat_function(fun = dgamma, args = list(shape = 0.1, scale = 0.1),
                geom = "area", fill = "grey80", color = "black") +
  labs(x = TeX("\\textbf{Beta precision (φ)}")) +
  annotate(geom = "label", x = 0.25, y = 2, label = "Gamma(0.01, 0.01)", size = pts(9)) +
  xlim(0, 0.5) +
  theme_donors(prior = TRUE)

layout <- "
AAAABBBBCCCC
AAAABBBBCCCC
##DDDDEEEE##
##DDDDEEEE##
"
z_p + sigma_p + phi_p + b0_p + b12_p +
  plot_layout(design = layout)

As with H1 and H2, the prior for the zero-inflated part of the model is a little weird. Internally, Stan uses a default of logistic(0, 1). We want to use an informative beta(8, 12) prior that approximates the proportion of zeroes in the data (but with fairly wide dispersion), but we once again need to translate it into the logistic distribution. Since there’s no easy way to do this, we used brms::logit_scaled to play around with distributional hyperparameters until it looked okay in the logistic distribution.

zi_prior_sim <- tibble(beta = rbeta(10000, 8, 12)) %>% 
  mutate(beta_logit_scale = brms::logit_scaled(beta)) %>% 
  mutate(logit_betaish_prior = rlogis(10000, -0.5, 0.35)) %>% 
  mutate(prior_probs = plogis(logit_betaish_prior))

zi_prior_plot1 <- ggplot(zi_prior_sim) +
  geom_density(aes(x = beta), fill = "grey80", color = "black") +
  labs(x = "Proportion where prop. contentious = 0",
       subtitle = "Original Beta(8, 12) distribution") +
  coord_cartesian(xlim = c(0, 1)) +
  theme_donors(prior = TRUE)

zi_prior_plot2 <- ggplot(zi_prior_sim) +
  geom_density(aes(x = beta_logit_scale), fill = "grey80", color = "black") +
  labs(x = "Logistic value where prop. contentious = 0",
       subtitle = "Beta(8, 12) scaled with brms::logit_scaled") +
  coord_cartesian(xlim = c(-4, 2)) +
  theme_donors(prior = TRUE)

zi_prior_plot3 <- ggplot(zi_prior_sim) +
  geom_density(aes(x = logit_betaish_prior), fill = "grey80", color = "black") +
  labs(x = "Logistic value where prop. contentious = 0",
       subtitle = "Estimated Logistic(-0.5, 0.35)") +
  coord_cartesian(xlim = c(-4, 2)) +
  theme_donors(prior = TRUE)

zi_prior_plot4 <- ggplot(zi_prior_sim) +
  geom_density(aes(x = prior_probs), fill = "grey80", color = "black") +
  labs(x = "Proportion where prop. contentious = 0",
       subtitle = "Logistic(-0.5, 0.35) transformed to probabilities") +
  coord_cartesian(xlim = c(0, 1)) +
  theme_donors(prior = TRUE)

(zi_prior_plot1 + zi_prior_plot2) / (zi_prior_plot3 + zi_prior_plot4)

Check outcome models

pp_check(m_recip_outcome_total_dom, type = "dens_overlay", nsamples = 10) +
  scale_x_continuous(labels = percent_format(accuracy = 1)) +
  theme_donors()

m_recip_outcome_total_dom %>% 
  posterior_samples(add_chain = TRUE) %>% 
  select(-starts_with("r_gwcode"), -starts_with("z_"), -lp__, -iter) %>% 
  mcmc_trace() +
  theme_donors()

Results

# Plots!
plot_total_dom <- m_recip_outcome_total_dom %>% 
  gather_draws(b_barriers_total) %>%
  mutate(.value = exp(.value) - 1) %>% 
  mutate(.variable = dplyr::recode(.variable, 
                                   b_barriers_total = "Additional law, t - 1")) %>% 
  ggplot(aes(y = fct_rev(.variable), x = .value, fill = fct_rev(.variable))) +
  geom_vline(xintercept = 0) +
  stat_halfeye(.width = c(0.8, 0.95), alpha = 0.8) +
  guides(fill = FALSE) +
  scale_x_continuous(labels = percent_format(accuracy = 1)) +
  scale_fill_manual(values = c("#FF851B", "#FFDC00")) +
  labs(y = NULL, x = NULL) +
  theme_donors()

plot_total_foreign <- m_recip_outcome_total_foreign %>% 
  gather_draws(b_barriers_total) %>%
  mutate(.value = exp(.value) - 1) %>% 
  mutate(.variable = dplyr::recode(.variable, 
                                   b_barriers_total = "Additional law, t - 1")) %>% 
  ggplot(aes(y = fct_rev(.variable), x = .value, fill = fct_rev(.variable))) +
  geom_vline(xintercept = 0) +
  stat_halfeye(.width = c(0.8, 0.95), alpha = 0.8) +
  guides(fill = FALSE) +
  scale_x_continuous(labels = percent_format(accuracy = 1)) +
  scale_fill_manual(values = c("#FF851B", "#FFDC00")) +
  labs(y = NULL, x = NULL) +
  theme_donors()

plot_advocacy_dom <- m_recip_outcome_advocacy_dom %>% 
  gather_draws(b_advocacy) %>% 
  mutate(.variable = dplyr::recode(.variable, 
                                   b_advocacy = "Additional advocacy law, t - 1")) %>% 
  mutate(.value = exp(.value) - 1) %>% 
  ggplot(aes(y = fct_rev(.variable), x = .value, fill = fct_rev(.variable))) +
  geom_vline(xintercept = 0) +
  stat_halfeye(.width = c(0.8, 0.95), alpha = 0.8) +
  guides(fill = FALSE) +
  scale_x_continuous(labels = percent_format(accuracy = 1)) +
  scale_fill_manual(values = c("#85144b", "#F012BE")) +
  labs(y = NULL, x = NULL) +
  theme_donors()

plot_advocacy_foreign <- m_recip_outcome_advocacy_foreign %>% 
  gather_draws(b_advocacy) %>% 
  mutate(.variable = dplyr::recode(.variable, 
                                   b_advocacy = "Additional advocacy law, t - 1")) %>% 
  mutate(.value = exp(.value) - 1) %>% 
  ggplot(aes(y = fct_rev(.variable), x = .value, fill = fct_rev(.variable))) +
  geom_vline(xintercept = 0) +
  stat_halfeye(.width = c(0.8, 0.95), alpha = 0.8) +
  guides(fill = FALSE) +
  scale_x_continuous(labels = percent_format(accuracy = 1)) +
  scale_fill_manual(values = c("#85144b", "#F012BE")) +
  labs(y = NULL, x = NULL) +
  theme_donors()

plot_entry_dom <- m_recip_outcome_entry_dom %>% 
  gather_draws(b_entry) %>% 
  mutate(.variable = dplyr::recode(.variable, 
                                   b_entry = "Additional entry law, t - 1")) %>% 
  mutate(.value = exp(.value) - 1) %>% 
  ggplot(aes(y = fct_rev(.variable), x = .value, fill = fct_rev(.variable))) +
  geom_vline(xintercept = 0) +
  stat_halfeye(.width = c(0.8, 0.95), alpha = 0.8) +
  guides(fill = FALSE) +
  scale_x_continuous(labels = percent_format(accuracy = 1)) +
  scale_fill_manual(values = c("#3D9970", "#2ECC40")) +
  labs(y = NULL, x = "% change in proportion of aid to domestic NGOs") +
  theme_donors()

plot_entry_foreign <- m_recip_outcome_entry_foreign %>% 
  gather_draws(b_entry) %>% 
  mutate(.variable = dplyr::recode(.variable, 
                                   b_entry = "Additional entry law, t - 1")) %>% 
  mutate(.value = exp(.value) - 1) %>% 
  ggplot(aes(y = fct_rev(.variable), x = .value, fill = fct_rev(.variable))) +
  geom_vline(xintercept = 0) +
  stat_halfeye(.width = c(0.8, 0.95), alpha = 0.8) +
  guides(fill = FALSE) +
  scale_x_continuous(labels = percent_format(accuracy = 1)) +
  scale_fill_manual(values = c("#3D9970", "#2ECC40")) +
  labs(y = NULL, x = "% change in proportion of aid to foreign NGOs") +
  theme_donors()

plot_funding_dom <- m_recip_outcome_funding_dom %>% 
  gather_draws(b_funding) %>% 
  mutate(.variable = dplyr::recode(.variable, 
                                   b_funding = "Additional funding law, t - 1")) %>% 
  mutate(.value = exp(.value) - 1) %>% 
  ggplot(aes(y = fct_rev(.variable), x = .value, fill = fct_rev(.variable))) +
  geom_vline(xintercept = 0) +
  stat_halfeye(.width = c(0.8, 0.95), alpha = 0.8) +
  guides(fill = FALSE) +
  scale_x_continuous(labels = percent_format(accuracy = 1)) +
  scale_fill_manual(values = c("#001f3f", "#0074D9")) +
  labs(y = NULL, x = "% change in proportion aid to domestic NGOs") +
  theme_donors()

plot_funding_foreign <- m_recip_outcome_funding_foreign %>% 
  gather_draws(b_funding) %>% 
  mutate(.variable = dplyr::recode(.variable, 
                                   b_funding = "Additional funding law, t - 1")) %>% 
  mutate(.value = exp(.value) - 1) %>% 
  ggplot(aes(y = fct_rev(.variable), x = .value, fill = fct_rev(.variable))) +
  geom_vline(xintercept = 0) +
  stat_halfeye(.width = c(0.8, 0.95), alpha = 0.8) +
  guides(fill = FALSE) +
  scale_x_continuous(labels = percent_format(accuracy = 1)) +
  scale_fill_manual(values = c("#001f3f", "#0074D9")) +
  labs(y = NULL, x = "% change in proportion aid to foreign NGOs") +
  theme_donors()

(plot_total_dom + plot_advocacy_dom) / (plot_entry_dom + plot_funding_dom)

(plot_total_foreign + plot_advocacy_foreign) / (plot_entry_foreign + plot_funding_foreign)

A one-unit change in X results in a relative change of \(e^\beta\) in \(\frac{\text{E(Proportion)}}{1 - \text{E(Proportion)}}\) - see https://stats.stackexchange.com/questions/297659/interpretation-of-betareg-coef - the ratio of contentious to non-contentious aid? the ratio of of contentious aid?

See also https://stats.stackexchange.com/a/230679/3025 and https://static1.squarespace.com/static/58a7d1e52994ca398697a621/t/5a2ebc43e4966b0fab6b02de/1513012293857/betareg_politics.pdf

m_recip_outcome_total_dom %>% 
  conditional_effects()

m_recip_outcome_advocacy_dom %>% 
  conditional_effects()

m_recip_outcome_entry_dom %>% 
  conditional_effects()

m_recip_outcome_funding_dom %>% 
  conditional_effects()

m_recip_outcome_total_foreign %>% 
  conditional_effects()

m_recip_outcome_advocacy_foreign %>% 
  conditional_effects()

m_recip_outcome_entry_foreign %>% 
  conditional_effects()

m_recip_outcome_funding_foreign %>% 
  conditional_effects()

LS0tCnRpdGxlOiAiSH4zfjogRWZmZWN0IG9mIGFudGktTkdPIGNyYWNrZG93biBvbiBhaWQgcmVjaXBpZW50cyIKYXV0aG9yOiAiU3VwYXJuYSBDaGF1ZGhyeSBhbmQgQW5kcmV3IEhlaXNzIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclRicpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9mb2xkaW5nOiBzaG93CmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLnJldGluYSA9IDMsCiAgICAgICAgICAgICAgICAgICAgICB0aWR5Lm9wdHMgPSBsaXN0KHdpZHRoLmN1dG9mZiA9IDEyMCksICAjIEZvciBjb2RlCiAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zKHdpZHRoID0gOTApLCAgIyBGb3Igb3V0cHV0CiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gMC42MTgsIGZpZy53aWR0aCA9IDcsIAogICAgICAgICAgICAgICAgICAgICAgZmlnLmFsaWduID0gImNlbnRlciIsIG91dC53aWR0aCA9ICI4NSUiKQoKb3B0aW9ucyhkcGx5ci5zdW1tYXJpc2UuaW5mb3JtID0gRkFMU0UpCmBgYAoKYGBge3IgbG9hZC1saWJyYXJpZXMsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHRhcmdldHMpCmxpYnJhcnkoYnJtcykKbGlicmFyeSh0aWR5YmF5ZXMpCmxpYnJhcnkoYmF5ZXNwbG90KQpsaWJyYXJ5KGZpeGVzdCkKbGlicmFyeShicm9vbSkKbGlicmFyeShicm9vbS5taXhlZCkKbGlicmFyeShtb2RlbHN1bW1hcnkpCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KHRpY3RvYykKbGlicmFyeShsYXRleDJleHApCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KGV4dHJhRGlzdHIpCmxpYnJhcnkoZ2x1ZSkKbGlicmFyeShoZXJlKQoKY29sb3Jfc2NoZW1lX3NldCgidmlyaWRpc0MiKQoKbGFic19leHBfbG9nZ2VkIDwtIGZ1bmN0aW9uKGJya3MpIHtUZVgocGFzdGUwKCJlXnsiLCBhcy5jaGFyYWN0ZXIobG9nKGJya3MpKSwgIn0iKSl9CmxhYnNfZXhwIDwtIGZ1bmN0aW9uKGJya3MpIHtUZVgocGFzdGUwKCJlXnsiLCBhcy5jaGFyYWN0ZXIoYnJrcyksICJ9IikpfQoKbXlfc2VlZCA8LSAxMjM0CnNldC5zZWVkKG15X3NlZWQpCgp3aXRocjo6d2l0aF9kaXIoaGVyZTo6aGVyZSgpLCB7CiAgc291cmNlKHRhcl9yZWFkKHBsb3RfZnVucykpCiAgc291cmNlKHRhcl9yZWFkKG1pc2NfZnVucykpCiAgCiAgIyBEYXRhCiAgZGZfY291bnRyeV9haWQgPC0gdGFyX3JlYWQoY291bnRyeV9haWRfZmluYWwpCiAgZGZfY291bnRyeV9haWRfbGF3cyA8LSBmaWx0ZXIoZGZfY291bnRyeV9haWQsIGxhd3MpCiAgCiAgIyBNb2RlbHMKICB0YXJfbG9hZChjKG1fcmVjaXBfdHJlYXRtZW50X3RvdGFsX2RvbSkpCiAgdGFyX2xvYWQoYyhtX3JlY2lwX291dGNvbWVfdG90YWxfZG9tLCBtX3JlY2lwX291dGNvbWVfdG90YWxfZm9yZWlnbiwKICAgICAgICAgICAgIG1fcmVjaXBfb3V0Y29tZV9hZHZvY2FjeV9kb20sIG1fcmVjaXBfb3V0Y29tZV9hZHZvY2FjeV9mb3JlaWduLAogICAgICAgICAgICAgbV9yZWNpcF9vdXRjb21lX2VudHJ5X2RvbSwgbV9yZWNpcF9vdXRjb21lX2VudHJ5X2ZvcmVpZ24sCiAgICAgICAgICAgICBtX3JlY2lwX291dGNvbWVfZnVuZGluZ19kb20sIG1fcmVjaXBfb3V0Y29tZV9mdW5kaW5nX2ZvcmVpZ24pKQp9KQpgYGAKCiMjIFdlaWdodCBtb2RlbHMKCi0gTnVtZXJhdG9yIGlzIGxhZ2dlZCB0cmVhdG1lbnQgKyBub24tdmFyeWluZyBjb25mb3VuZGVycwotIERlbm9taW5hdG9yIGlzIGxhZ2dlZCB0cmVhdG1lbnQgKyBsYWdnZWQgb3V0Y29tZSArIHRpbWUtdmFyeWluZyBjb25mb3VuZGVycyArIG5vbi12YXJ5aW5nIGNvbmZvdW5kZXJzCgokJApzdyA9IFxwcm9kXnRfe3QgPSAxfSBcZnJhY3tccGhpKFRfe2l0fSB8IFRfe2ksIHQtMX0sIENfaSl9e1xwaGkoVF97aXR9IHwgVF97aSwgdC0xfSwgRF97aSwgdC0xfSwgQ19pKX0KJCQKCiMjIyBQcmlvcnMgZm9yIHdlaWdodCBtb2RlbHMKCldlIHVzZSBbZ2VuZXJpYyB3ZWFrbHkgaW5mb3JtYXRpdmUgcHJpb3JzXSgpIGZvciBvdXIgbW9kZWwgcGFyYW1ldGVyczoKCi0gSW50ZXJjZXB0OiAkXG1hdGhjYWx7Tn0gKDAsIDEwKSQKLSBDb2VmZmljaWVudHM6ICRcbWF0aGNhbHtOfSAoMCwgMi41KSQKLSBTaWdtYTogJFxvcGVyYXRvcm5hbWV7Q2F1Y2h5fSAoMCwgMSkkCgpgYGB7ciBwbG90LXdlaWdodC1wcmlvcnMsIGZpZy5oZWlnaHQ9MiwgZmlnLndpZHRoPTYsIGZpZy5hc3A9TlVMTH0KcHJpX2ludCA8LSBnZ3Bsb3QoKSArCiAgc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgYXJncyA9IGxpc3QobWVhbiA9IDAsIHNkID0gMTApLAogICAgICAgICAgICAgICAgZ2VvbSA9ICJhcmVhIiwgZmlsbCA9ICJncmV5ODAiLCBjb2xvciA9ICJibGFjayIpICsKICBsYWJzKHggPSBUZVgoIlxcdGV4dGJme0ludGVyY2VwdCAozrJfMCl9IikpICsKICBhbm5vdGF0ZShnZW9tID0gImxhYmVsIiwgeCA9IDAsIHkgPSAwLjAxLCBsYWJlbCA9ICJOKDAsIDEwKSIsIHNpemUgPSBwdHMoOSkpICsKICB4bGltKC00MCwgNDApICsKICB0aGVtZV9kb25vcnMocHJpb3IgPSBUUlVFKQoKcHJpX2NvZWYgPC0gZ2dwbG90KCkgKwogIHN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBsaXN0KG1lYW4gPSAwLCBzZCA9IDIuNSksCiAgICAgICAgICAgICAgICBnZW9tID0gImFyZWEiLCBmaWxsID0gImdyZXk4MCIsIGNvbG9yID0gImJsYWNrIikgKwogIGxhYnMoeCA9IFRlWCgiXFx0ZXh0YmZ7Q29lZmZpY2llbnRzICjOsl94KX0iKSkgKwogIGFubm90YXRlKGdlb20gPSAibGFiZWwiLCB4ID0gMCwgeSA9IDAuMDQsIGxhYmVsID0gIk4oMCwgMykiLCBzaXplID0gcHRzKDkpKSArCiAgeGxpbSgtMTAsIDEwKSArCiAgdGhlbWVfZG9ub3JzKHByaW9yID0gVFJVRSkKCnByaV9zaWdtYSA8LSBnZ3Bsb3QoKSArCiAgc3RhdF9mdW5jdGlvbihmdW4gPSBkY2F1Y2h5LCBhcmdzID0gbGlzdChsb2NhdGlvbiA9IDAsIHNjYWxlID0gMSksCiAgICAgICAgICAgICAgICBnZW9tID0gImFyZWEiLCBmaWxsID0gImdyZXk4MCIsIGNvbG9yID0gImJsYWNrIikgKwogIGxhYnMoeCA9ICLPgyIpICsKICBhbm5vdGF0ZShnZW9tID0gImxhYmVsIiwgeCA9IDUsIHkgPSAwLjA4LCBsYWJlbCA9ICJDYXVjaHkoMCwgMSkiLCBzaXplID0gcHRzKDkpKSArCiAgeGxpbSgwLCAxMCkgKwogIHRoZW1lX2Rvbm9ycyhwcmlvciA9IFRSVUUpCgoocHJpX2ludCArIHByaV9jb2VmICsgcHJpX3NpZ21hKQpgYGAKCiMjIyBDaGVjayB3ZWlnaHQgbW9kZWxzCgpXZSBjaGVjayBvbmUgb2YgdGhlIGRlbm9taW5hdG9yIG1vZGVscyBmb3IgY29udmVyZ2VuY2UgYW5kIG1peGluZyBhbmQgZml0IChub3QgdGhlIG51bWVyYXRvciwgc2luY2UgdGhvc2UgbW9kZWxzIGFyZSB0aGUgc2FtZSBhcyB0aGUgb25lcyBpbiBIMSkuCgpgYGB7ciBoMy1jaGVjay1kZW5vbWluYXRvcn0KcHBfY2hlY2sobV9yZWNpcF90cmVhdG1lbnRfdG90YWxfZG9tJG1vZGVsX2Rlbm9tLCB0eXBlID0gImRlbnNfb3ZlcmxheSIsIG5zYW1wbGVzID0gMTApICsKICB0aGVtZV9kb25vcnMoKQoKbV9yZWNpcF90cmVhdG1lbnRfdG90YWxfZG9tJG1vZGVsX2Rlbm9tICU+JSAKICBwb3N0ZXJpb3Jfc2FtcGxlcyhhZGRfY2hhaW4gPSBUUlVFKSAlPiUgCiAgc2VsZWN0KC1zdGFydHNfd2l0aCgicl9nd2NvZGUiKSwgLXN0YXJ0c193aXRoKCJ6XyIpLCAtbHBfXywgLWl0ZXIpICU+JSAKICBtY21jX3RyYWNlKCkgKwogIHRoZW1lX2Rvbm9ycygpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQpgYGAKCgojIyBPdXRjb21lIG1vZGVscwoKIyMjIE1vZGVsaW5nIGNob2ljZQoKV2UgdXNlIHR3byBkZXBlbmRlbnQgdmFyaWFibGVzIGZvciB0aGlzIGh5cG90aGVzaXM6IHRoZSBwcm9wb3J0aW9uIG9mIFVTQUlEIGFpZCBjaGFubmVsZWQgdGhyb3VnaCBlaXRoZXIgKDEpIGRvbWVzdGljIG9yICgyKSBpbnRlcm5hdGlvbmFsIG9yIFVTLWJhc2VkIChvciBmb3JlaWduKSBOR09zLCBvbmNlIGFnYWluIGxlYWRlZCBieSBvbmUgeWVhci4gVGhlIE9FQ0QgYW5kIEFpZERhdGEgZG8gbm90IHRyYWNrIHRoZSBjaGFubmVscyBvZiBhaWQgZGVsaXZlcnksIHNvIHdlIGNhbm5vdCBzZWUgaG93IGFpZCBpcyBkaXN0cmlidXRlZCBvbiBhIGdsb2JhbCBzY2FsZS4gVVNBSUQsIGhvd2V2ZXIsIGRvZXMgdHJhY2sgY2hhbm5lbHMsIHNvIHdlIGNhbiBtZWFzdXJlIGhvdyBtdWNoIGFpZCBnb2VzIHRvIGRvbWVzdGljIE5HT3MgKGFuZCBhbHNvIFVTLWJhc2VkIGFuZCBpbnRlcm5hdGlvbmFsIE5HT3MpLiBVU0FJRCBkaWRu4oCZdCBzdGFydCB0cmFja2luZyB0aGlzIHVudGlsIDIwMDEsIHRob3VnaCwgc28gd2UgaGF2ZSB0byBsaW1pdCBvdXIgbW9kZWxzIHRvIDIwMDHigJMyMDEzLiAoQm9vLikKClRoZXNlIHZhcmlhYmxlcyBhcmUgcHJvcG9ydGlvbnMgYW5kIGxpbWl0ZWQgdG8gYSBbMCwgMV0gcmFuZ2UuIEluIHRoZSBvcmlnaW5hbCB2ZXJzaW9uIG9mIHRoaXMgcHJvamVjdCwgd2UgdXNlZCBsb2dpdC1saW5lYXIgbW9kZWxzIG9mIHRoZSByYXRpbyBvZiBkb21lc3RpYyBvciBmb3JpZWduIGFpZCB0byBhbGwgb3RoZXIgY2hhbm5lbHMsIGxpa2UgdGhpczoKCiQkbG4oIFxmcmFje1x0ZXh0e0FpZCB0byAoZG9tZXN0aWMgb3IgZm9yZWlnbikgTkdPc31fe1x0ZXh0e1VTQUlEfX19e1x0ZXh0e0FpZCB0byBvdGhlciBjaGFubmVsc31fe1x0ZXh0e1VTQUlEfX19IClfe2ksIHQrMX0gPSBcdGV4dHtOR08gbGVnaXNsYXRpb259X3tpdH0gKyBcdGV4dHtjb250cm9sc31fe2l0fSQkCgpCdXQgW2FzIG1lbnRpb25lZCBpbiBvdXIgYW5hbHlzaXMgZm9yIEh+Mn5dKDAzX2gyLWFpZC1jb250ZW50aW91c25lc3MuaHRtbCNPdXRjb21lX21vZGVscyksIHRoaXMgbWFkZSBpbnRlcnByZXRhdGlvbiByZWFsbHkgc3RyYW5nZS4gSXQgYWxzbyBmYWlscyB0byBhY2NvdW50IGZvciB6ZXJvLSBhbmQgb25lLSBpbmZsYXRpb24uIFRoZXNlIHR3byB2YXJpYWJsZXMgaGF2ZSAqYSBsb3QqIG9mIHplcm9lcyBhbmQgYSBoYW5kZnVsIG9mIG9uZXMsIHdoaWNoIGluZGljYXRlcyB0aGF0IHRoZXJlJ3Mgc29tZXRoaW5nIGhpZ2hseSBzeXN0ZW1hdGljIGFib3V0IHRoZSBjaG9pY2UgdG8gKDEpIGNoYW5uZWwgYW55IG1vbmV5IHRocm91Z2ggYW55IGtpbmQgb2YgTkdPcyBhbmQgKDIpIGhvdyBtdWNoIG1vbmV5IGlmIHNvLgoKYGBge3Igc2hvdy1vdXRjb21lLWRpc3QsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmRmX2NoYW5uZWxzX3Bsb3RfaGlzdCA8LSBkZl9jb3VudHJ5X2FpZF9sYXdzICU+JSAKICBwaXZvdF9sb25nZXIobmFtZXNfdG8gPSAiY2hhbm5lbCIsIHZhbHVlc190byA9ICJ2YWx1ZSIsIAogICAgICAgICAgICAgICBjKHByb3BfbmdvX2RvbSwgcHJvcF9uZ29fZm9yZWlnbikpICU+JSAKICBtdXRhdGUoY2hhbm5lbCA9IHJlY29kZShjaGFubmVsLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wX25nb19kb20gPSAiRG9tZXN0aWMgTkdPcyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BfbmdvX2ZvcmVpZ24gPSAiRm9yZWlnbiBOR09zIikpCgpnZ3Bsb3QoZGZfY2hhbm5lbHNfcGxvdF9oaXN0LCAKICAgICAgIGFlcyh4ID0gdmFsdWUsIGZpbGwgPSBjaGFubmVsLCBhbHBoYSA9IHZhbHVlID09IDApKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjA1LCBjb2xvciA9ICJ3aGl0ZSIsIGJvdW5kYXJ5ID0gMCkgKwogIGxhYnMoeCA9ICJQcm9wb3J0aW9uIG9mIGFpZCB0byBOR09zIiwgeSA9ICJDb3VudCIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjMDAxZjNmIiwgIiNGRjg1MUIiKSwgCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiRG9tZXN0aWMiLCAiSW50ZXJuYXRpb25hbCIpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSBOVUxMKSArCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoMSwgMC41KSwgCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIiUgPiAwIiwgIiUgPSAwIiksCiAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBOVUxMKSArCiAgZ3VpZGVzKGZpbGwgPSBGQUxTRSkgKwogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgZmFjZXRfd3JhcCh2YXJzKGNoYW5uZWwpKSArCiAgdGhlbWVfZG9ub3JzKCkKCiMgUGVyY2VudCB3aGVyZSBwcm9wX25nb19kb20vZm9yZWlnbiBpcyAwOgpkZl9jaGFubmVsc19wbG90X2hpc3QgJT4lIAogIGNvdW50KGNoYW5uZWwsIHZhbHVlID09IDApICU+JSAKICBncm91cF9ieShjaGFubmVsKSAlPiUgCiAgbXV0YXRlKHByb3AgPSBuIC8gc3VtKG4pKQpgYGAKCkFyb3VuZCA0MCUgb2Ygb2JzZXJ2YXRpb25zIGFyZSB6ZXJvIGZvciBib3RoIGRvbWVzdGljIGFuZCBpbnRlcm5hdGlvbmFsIE5HT3MsIHdoaWNoIGlzIGEgbG90IChpbiBIfjJ+LCDiiYgxOCUgb2Ygcm93cyBoYWQgMCUgY29udGVudGlvdXMgYWlkKS4gQWNjb3JkaW5nbHksIGl0J3MgcmVhbGx5IGltcG9ydGFudCB0byBtb2RlbCBib3RoIHRoZSBjaG9pY2Ugb2Ygd2hldGhlciB0byBjaGFubmVsIGFpZCB0byBOR09zICphbmQqIGhvdyBtdWNoLiAKCldlIHRodXMgdXNlIHplcm8taW5mbGF0ZWQgYmV0YSByZWdyZXNzaW9uLiBXZSBkbyBub3QgdXNlIHplcm8tb25lLWluZmxhdGVkIHJlZ3Jlc3Npb24gYmVjYXVzZSB0aGVyZSBhcmUgc28gZmV3IDEtb25seSByb3dzIGFuZCB3ZSdyZSBsZXNzIGludGVyZXN0ZWQgaW4gd2h5IGEgY291bnRyeSB3b3VsZCBjaGFubmVsIGFsbCBpdHMgYWlkIHRocm91Z2ggTkdPcyAoYWxzbywgdGhhdCdzIG1vcmUgbGlrZWx5IGEgc2lnbiBvZiBsb3cgYWlkIHRvIGEgY291bnRyeSBhbmQganVzdCBhbiBhcnRlZmFjdCBvZiB0aGUgZGF0YSBnZW5lcmF0aW5nIHByb2Nlc3MpLiBXZSB3aW5zb3JpemUgdGhlIGZldyAxLW9ubHkgcm93cyB0byAwLjk5OS4gCgpbQXMgZXhwbGFpbmVkIGluIEh+Mn5dKDAzX2gyLWFpZC1jb250ZW50aW91c25lc3MuaHRtbCNPdXRjb21lX21vZGVscyksIHplcm8taW5mbGF0ZWQgYmV0YSBtb2RlbHMgdXNlIGEgbG9naXQgbW9kZWwgdG8gcHJlZGljdCAwL25vdCAwIGFuZCB0aGVuIHVzZSBhIGJldGEgZmFtaWx5IHRvIG1vZGVsIHRoZSByZXN0IG9mIHRoZSBkYXRhLiBJbiBIfjJ+IHdlIHdlcmUgbGVzcyBpbnRlcmVzdGVkIGluIHRoZSBtZWNoYW5pY3Mgb2YgdGhlIHplcm8taW5mbGF0aW9uIHByb2Nlc3MgYW5kIG1vZGVsZWQgaXQgd2l0aCBhbiBpbnRlcmNlcHQtb25seSBsb2dpdCBtb2RlbC4gSGVyZSwgdGhvdWdoLCBnaXZlbiB0aGF0IHRoZXJlIGFyZSBzbyBtYW55IDBzLCB3ZSB1c2UgdGhlIHNhbWUgY29uZm91bmRlcnMgdGhhdCB3ZSB1c2VkIGluIHRoZSB3ZWlnaHRzIG1vZGVsLiBXZSBkbyBub3QgaW5jbHVkZSBpbnZlcnNlIHByb2JhYmlsaXR5IHdlaWdodHMgaW4gdGhlIHplcm8taW5mbGF0aW9uIHBhcnQgYmVjYXVzZSAoMSkgdGhlIGlubmVyIG1lY2hhbmljcyBvZiAqKmJybXMqKiBkb24ndCBhbGxvdyBmb3IgdGhhdCBhbmQgKDIpIEknbSBub3Qgc3VyZSB0aGF0IHdvcmtzIHdpdGggbWFyZ2luYWwgc3RydWN0dXJhbCBtb2RlbHMgYW55d2F5LgoKIyMjIFByaW9ycyBmb3Igb3V0Y29tZSBtb2RlbHMKCk9uY2UgYWdhaW4gdGhlcmUgYXJlIGEgdG9uIG9mIG1vdmluZyBwYXJ0cyBpbiB0aGVzZSBvdXRjb21lIG1vZGVscy4gSGVyZSdzIHRoZSBmdWxsIHNwZWNpZmljYXRpb24gZm9yIHRoZSBtb2RlbHMgYW5kIGFsbCBwcmlvcnM6CgokJApcYmVnaW57YWxpZ25lZH0KXHRleHR7eX1fe2ksdH0gfCB1X2ksIFx0ZXh0e0xhd31fe2ksIHR9ICZcc2ltIFxvcGVyYXRvcm5hbWV7WklCZXRhfSAoWl9pLCBcdGV4dHt5fV5cc3Rhcl9pLCBccGhpX2kpICYgXHRleHR7W2xpa2VsaWhvb2RdfSBcXApcb3BlcmF0b3JuYW1le2xvZ2l0fSAoWl9pKSAmXHNpbSBcYWxwaGFfWiAmIFx0ZXh0e1tsb2dpdCBpZiB9IFx0ZXh0e3l9X3tpLCB0fSA9IDAgXHRleHR7XX0gXFwKXG9wZXJhdG9ybmFtZXtsb2dpdH0gKFx0ZXh0e3l9XlxzdGFyX2kpICZcc2ltIChcYmV0YV8wICsgXGJldGFfMSBcdGV4dHtMYXd9X3tpLCB0fSArIFxiZXRhXzIgXHRleHR7TGF3fV97aSwgdC0xfSwgXHNpZ21hXjJfXGVwc2lsb24sIHVfaSkgXHRpbWVzIFx0ZXh0e0lQV31fe2ksIHR9ICYgXHRleHR7W2lmIH0gXHRleHR7eX1fe2ksIHR9ID4gMCBcdGV4dHtdfVxcClxsb2cgKFxwaGlfaSkgJlxzaW0gXGFscGhhX1xwaGkgJiBcdGV4dHtbaW50ZXJjZXB0LW9ubHkgbW9kZWwgZm9yIHByZWNpc2lvbl19IFxcCnVfaSAmXHNpbSBcbWF0aGNhbHtOfSAoMCwgXHNpZ21hXjJfdSkgJiBcdGV4dHtbY291bnRyeS1zcGVjaWZpYyBpbnRlcmNlcHRzXX0gXFwKXCBcXApcYWxwaGFfWiAmXHNpbSBcb3BlcmF0b3JuYW1le0xvZ2lzdGljfSgtMC41LCAwLjM1KSAmIFx0ZXh0e1twcmlvciBwcm9wb3J0aW9uIG9mIHJvd3Mgd2hlcmUgeSA9IDBdfSBcXApcYWxwaGFfXHBoaSAmXHNpbSBcb3BlcmF0b3JuYW1le0dhbW1hfSAoMC4wMSwgMC4wMSkgJiBcdGV4dHtbcHJpb3IgQmV0YSBwcmVjaXNpb25dfSBcXApcYmV0YV8wICZcc2ltIFxtYXRoY2Fse059ICgwLCAxMCkgJiBcdGV4dHtbcHJpb3IgcG9wdWxhdGlvbiBpbnRlcmNlcHRdfSBcXApcYmV0YV8xLCBcYmV0YV8yICZcc2ltIFxtYXRoY2Fse059ICgwLCAzKSAmIFx0ZXh0e1twcmlvciBwb3B1bGF0aW9uIGVmZmVjdHNdfSBcXApcc2lnbWFeMl9lLCBcc2lnbWFeMl91ICZcc2ltIFxvcGVyYXRvcm5hbWV7Q2F1Y2h5fSgwLCAxKSAmIFx0ZXh0e1twcmlvciBzZCBmb3IgcG9wdWxhdGlvbiBhbmQgY291bnRyeV19IFxcClwgXFwKXHRleHR7SVBXfV97aSwgdH0gJj0gXHByb2RedF97dCA9IDF9IFxmcmFje1xwaGkoVF97aXR9IHwgVF97aSwgdC0xfSwgQ19pKX17XHBoaShUX3tpdH0gfCBUX3tpLCB0LTF9LCBEX3tpLCB0LTF9LCBDX2kpfSAmIFx0ZXh0e1tzdGFiaWxpemVkIHdlaWdodHNdfQpcZW5ke2FsaWduZWR9CiQkCgpGb3IgJFxwaGkkLCB3ZSBqdXN0IHVzZSBTdGFuJ3MgZGVmYXVsdCBgR2FtbWEoMC4wMSwgMC4wMSlgLiBIZXJlJ3Mgd2hhdCBhbGwgdGhlc2UgcHJpb3IgZGlzdHJpYnV0aW9ucyBsb29rIGxpa2U6CgpgYGB7ciBoMy1zaG93LXByaW9ycywgZmlnLndpZHRoPTh9CnpfcCA8LSBnZ3Bsb3QoKSArCiAgc3RhdF9mdW5jdGlvbihmdW4gPSBkbG9naXMsIGFyZ3MgPSBsaXN0KGxvY2F0aW9uID0gLTEuNSwgc2NhbGUgPSAwLjUpLAogICAgICAgICAgICAgICAgZ2VvbSA9ICJhcmVhIiwgZmlsbCA9ICJncmV5ODAiLCBjb2xvciA9ICJibGFjayIpICsKICBsYWJzKHggPSBUZVgoIlxcdGV4dGJme1Byb3AuIGNvbnRlbnRpb3VzID0gMCAozrFfWil9IikpICsKICBhbm5vdGF0ZShnZW9tID0gImxhYmVsIiwgeCA9IC0yLCB5ID0gMC4wNywgbGFiZWwgPSAiTG9naXN0aWMoLTEuNSwgMC41KSIsIHNpemUgPSBwdHMoOSkpICsKICB4bGltKC04LCAzKSArCiAgdGhlbWVfZG9ub3JzKHByaW9yID0gVFJVRSkKCmIwX3AgPC0gZ2dwbG90KCkgKwogIHN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBsaXN0KG1lYW4gPSAwLCBzZCA9IDEwKSwKICAgICAgICAgICAgICAgIGdlb20gPSAiYXJlYSIsIGZpbGwgPSAiZ3JleTgwIiwgY29sb3IgPSAiYmxhY2siKSArCiAgbGFicyh4ID0gVGVYKCJcXHRleHRiZntQb3B1bGF0aW9uIGludGVyY2VwdCAozrJfMCl9IikpICsKICBhbm5vdGF0ZShnZW9tID0gImxhYmVsIiwgeCA9IDAsIHkgPSAwLjAwNDIsIGxhYmVsID0gIk4oMCwgMTApIiwgc2l6ZSA9IHB0cyg5KSkgKwogIHhsaW0oLTQwLCA0MCkgKwogIHRoZW1lX2Rvbm9ycyhwcmlvciA9IFRSVUUpCgpiMTJfcCA8LSBnZ3Bsb3QoKSArCiAgc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgYXJncyA9IGxpc3QobWVhbiA9IDAsIHNkID0gMyksCiAgICAgICAgICAgICAgICBnZW9tID0gImFyZWEiLCBmaWxsID0gImdyZXk4MCIsIGNvbG9yID0gImJsYWNrIikgKwogIGxhYnMoeCA9IFRlWCgiXFx0ZXh0YmZ7UG9wdWxhdGlvbiBlZmZlY3RzICjOsl8xLCDOsl8yKX0iKSkgKwogIGFubm90YXRlKGdlb20gPSAibGFiZWwiLCB4ID0gMCwgeSA9IDAuMDIsIGxhYmVsID0gIk4oMCwgMykiLCBzaXplID0gcHRzKDkpKSArCiAgeGxpbSgtMTAsIDEwKSArCiAgdGhlbWVfZG9ub3JzKHByaW9yID0gVFJVRSkKCnNpZ21hX3AgPC0gZ2dwbG90KCkgKwogIHN0YXRfZnVuY3Rpb24oZnVuID0gZGNhdWNoeSwgYXJncyA9IGxpc3QobG9jYXRpb24gPSAwLCBzY2FsZSA9IDEpLAogICAgICAgICAgICAgICAgZ2VvbSA9ICJhcmVhIiwgZmlsbCA9ICJncmV5ODAiLCBjb2xvciA9ICJibGFjayIpICsKICBsYWJzKHggPSBUZVgoIlxcdGV4dGJme1BvcHVsYXRpb24gYW5kIGNvdW50cnkgU0QgKM+DX2UsIM+DX3UpfSIpKSArCiAgYW5ub3RhdGUoZ2VvbSA9ICJsYWJlbCIsIHggPSA1LCB5ID0gMC4wNCwgbGFiZWwgPSAiQ2F1Y2h5KDAsIDEpIiwgc2l6ZSA9IHB0cyg5KSkgKwogIHhsaW0oMCwgMTApICsKICB0aGVtZV9kb25vcnMocHJpb3IgPSBUUlVFKQoKcGhpX3AgPC0gZ2dwbG90KCkgKwogIHN0YXRfZnVuY3Rpb24oZnVuID0gZGdhbW1hLCBhcmdzID0gbGlzdChzaGFwZSA9IDAuMSwgc2NhbGUgPSAwLjEpLAogICAgICAgICAgICAgICAgZ2VvbSA9ICJhcmVhIiwgZmlsbCA9ICJncmV5ODAiLCBjb2xvciA9ICJibGFjayIpICsKICBsYWJzKHggPSBUZVgoIlxcdGV4dGJme0JldGEgcHJlY2lzaW9uICjPhil9IikpICsKICBhbm5vdGF0ZShnZW9tID0gImxhYmVsIiwgeCA9IDAuMjUsIHkgPSAyLCBsYWJlbCA9ICJHYW1tYSgwLjAxLCAwLjAxKSIsIHNpemUgPSBwdHMoOSkpICsKICB4bGltKDAsIDAuNSkgKwogIHRoZW1lX2Rvbm9ycyhwcmlvciA9IFRSVUUpCgpsYXlvdXQgPC0gIgpBQUFBQkJCQkNDQ0MKQUFBQUJCQkJDQ0NDCiMjREREREVFRUUjIwojI0RERERFRUVFIyMKIgp6X3AgKyBzaWdtYV9wICsgcGhpX3AgKyBiMF9wICsgYjEyX3AgKwogIHBsb3RfbGF5b3V0KGRlc2lnbiA9IGxheW91dCkKYGBgCgpBcyB3aXRoIEh+MX4gYW5kIEh+Mn4sIHRoZSBwcmlvciBmb3IgdGhlIHplcm8taW5mbGF0ZWQgcGFydCBvZiB0aGUgbW9kZWwgaXMgYSBsaXR0bGUgd2VpcmQuIEludGVybmFsbHksIFN0YW4gdXNlcyBhIGRlZmF1bHQgb2YgYGxvZ2lzdGljKDAsIDEpYC4gV2Ugd2FudCB0byB1c2UgYW4gaW5mb3JtYXRpdmUgYGJldGEoOCwgMTIpYCBwcmlvciB0aGF0IGFwcHJveGltYXRlcyB0aGUgcHJvcG9ydGlvbiBvZiB6ZXJvZXMgaW4gdGhlIGRhdGEgKGJ1dCB3aXRoIGZhaXJseSB3aWRlIGRpc3BlcnNpb24pLCBidXQgd2Ugb25jZSBhZ2FpbiBuZWVkIHRvIHRyYW5zbGF0ZSBpdCBpbnRvIHRoZSBsb2dpc3RpYyBkaXN0cmlidXRpb24uIFNpbmNlIHRoZXJlJ3Mgbm8gZWFzeSB3YXkgdG8gZG8gdGhpcywgd2UgdXNlZCBgYnJtczo6bG9naXRfc2NhbGVkYCB0byBwbGF5IGFyb3VuZCB3aXRoIGRpc3RyaWJ1dGlvbmFsIGh5cGVycGFyYW1ldGVycyB1bnRpbCBpdCBsb29rZWQgb2theSBpbiB0aGUgbG9naXN0aWMgZGlzdHJpYnV0aW9uLgoKYGBge3IgemktcHJpb3Itd2VpcmRuZXNzfQp6aV9wcmlvcl9zaW0gPC0gdGliYmxlKGJldGEgPSByYmV0YSgxMDAwMCwgOCwgMTIpKSAlPiUgCiAgbXV0YXRlKGJldGFfbG9naXRfc2NhbGUgPSBicm1zOjpsb2dpdF9zY2FsZWQoYmV0YSkpICU+JSAKICBtdXRhdGUobG9naXRfYmV0YWlzaF9wcmlvciA9IHJsb2dpcygxMDAwMCwgLTAuNSwgMC4zNSkpICU+JSAKICBtdXRhdGUocHJpb3JfcHJvYnMgPSBwbG9naXMobG9naXRfYmV0YWlzaF9wcmlvcikpCgp6aV9wcmlvcl9wbG90MSA8LSBnZ3Bsb3QoemlfcHJpb3Jfc2ltKSArCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gYmV0YSksIGZpbGwgPSAiZ3JleTgwIiwgY29sb3IgPSAiYmxhY2siKSArCiAgbGFicyh4ID0gIlByb3BvcnRpb24gd2hlcmUgcHJvcC4gY29udGVudGlvdXMgPSAwIiwKICAgICAgIHN1YnRpdGxlID0gIk9yaWdpbmFsIEJldGEoOCwgMTIpIGRpc3RyaWJ1dGlvbiIpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMCwgMSkpICsKICB0aGVtZV9kb25vcnMocHJpb3IgPSBUUlVFKQoKemlfcHJpb3JfcGxvdDIgPC0gZ2dwbG90KHppX3ByaW9yX3NpbSkgKwogIGdlb21fZGVuc2l0eShhZXMoeCA9IGJldGFfbG9naXRfc2NhbGUpLCBmaWxsID0gImdyZXk4MCIsIGNvbG9yID0gImJsYWNrIikgKwogIGxhYnMoeCA9ICJMb2dpc3RpYyB2YWx1ZSB3aGVyZSBwcm9wLiBjb250ZW50aW91cyA9IDAiLAogICAgICAgc3VidGl0bGUgPSAiQmV0YSg4LCAxMikgc2NhbGVkIHdpdGggYnJtczo6bG9naXRfc2NhbGVkIikgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtNCwgMikpICsKICB0aGVtZV9kb25vcnMocHJpb3IgPSBUUlVFKQoKemlfcHJpb3JfcGxvdDMgPC0gZ2dwbG90KHppX3ByaW9yX3NpbSkgKwogIGdlb21fZGVuc2l0eShhZXMoeCA9IGxvZ2l0X2JldGFpc2hfcHJpb3IpLCBmaWxsID0gImdyZXk4MCIsIGNvbG9yID0gImJsYWNrIikgKwogIGxhYnMoeCA9ICJMb2dpc3RpYyB2YWx1ZSB3aGVyZSBwcm9wLiBjb250ZW50aW91cyA9IDAiLAogICAgICAgc3VidGl0bGUgPSAiRXN0aW1hdGVkIExvZ2lzdGljKC0wLjUsIDAuMzUpIikgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtNCwgMikpICsKICB0aGVtZV9kb25vcnMocHJpb3IgPSBUUlVFKQoKemlfcHJpb3JfcGxvdDQgPC0gZ2dwbG90KHppX3ByaW9yX3NpbSkgKwogIGdlb21fZGVuc2l0eShhZXMoeCA9IHByaW9yX3Byb2JzKSwgZmlsbCA9ICJncmV5ODAiLCBjb2xvciA9ICJibGFjayIpICsKICBsYWJzKHggPSAiUHJvcG9ydGlvbiB3aGVyZSBwcm9wLiBjb250ZW50aW91cyA9IDAiLAogICAgICAgc3VidGl0bGUgPSAiTG9naXN0aWMoLTAuNSwgMC4zNSkgdHJhbnNmb3JtZWQgdG8gcHJvYmFiaWxpdGllcyIpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMCwgMSkpICsKICB0aGVtZV9kb25vcnMocHJpb3IgPSBUUlVFKQoKKHppX3ByaW9yX3Bsb3QxICsgemlfcHJpb3JfcGxvdDIpIC8gKHppX3ByaW9yX3Bsb3QzICsgemlfcHJpb3JfcGxvdDQpCmBgYAoKIyMjIENoZWNrIG91dGNvbWUgbW9kZWxzCgpgYGB7ciBoMy1jaGVjay1vdXRjb21lfQpwcF9jaGVjayhtX3JlY2lwX291dGNvbWVfdG90YWxfZG9tLCB0eXBlID0gImRlbnNfb3ZlcmxheSIsIG5zYW1wbGVzID0gMTApICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIHRoZW1lX2Rvbm9ycygpCgptX3JlY2lwX291dGNvbWVfdG90YWxfZG9tICU+JSAKICBwb3N0ZXJpb3Jfc2FtcGxlcyhhZGRfY2hhaW4gPSBUUlVFKSAlPiUgCiAgc2VsZWN0KC1zdGFydHNfd2l0aCgicl9nd2NvZGUiKSwgLXN0YXJ0c193aXRoKCJ6XyIpLCAtbHBfXywgLWl0ZXIpICU+JSAKICBtY21jX3RyYWNlKCkgKwogIHRoZW1lX2Rvbm9ycygpCmBgYAoKIyMjIFJlc3VsdHMKCmBgYHtyIGgzLXBsb3RzLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01LCBmaWcuYXNwPU5VTEx9CiMgUGxvdHMhCnBsb3RfdG90YWxfZG9tIDwtIG1fcmVjaXBfb3V0Y29tZV90b3RhbF9kb20gJT4lIAogIGdhdGhlcl9kcmF3cyhiX2JhcnJpZXJzX3RvdGFsKSAlPiUKICBtdXRhdGUoLnZhbHVlID0gZXhwKC52YWx1ZSkgLSAxKSAlPiUgCiAgbXV0YXRlKC52YXJpYWJsZSA9IGRwbHlyOjpyZWNvZGUoLnZhcmlhYmxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiX2JhcnJpZXJzX3RvdGFsID0gIkFkZGl0aW9uYWwgbGF3LCB0IC0gMSIpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldigudmFyaWFibGUpLCB4ID0gLnZhbHVlLCBmaWxsID0gZmN0X3JldigudmFyaWFibGUpKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDApICsKICBzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjgsIDAuOTUpLCBhbHBoYSA9IDAuOCkgKwogIGd1aWRlcyhmaWxsID0gRkFMU0UpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNGRjg1MUIiLCAiI0ZGREMwMCIpKSArCiAgbGFicyh5ID0gTlVMTCwgeCA9IE5VTEwpICsKICB0aGVtZV9kb25vcnMoKQoKcGxvdF90b3RhbF9mb3JlaWduIDwtIG1fcmVjaXBfb3V0Y29tZV90b3RhbF9mb3JlaWduICU+JSAKICBnYXRoZXJfZHJhd3MoYl9iYXJyaWVyc190b3RhbCkgJT4lCiAgbXV0YXRlKC52YWx1ZSA9IGV4cCgudmFsdWUpIC0gMSkgJT4lIAogIG11dGF0ZSgudmFyaWFibGUgPSBkcGx5cjo6cmVjb2RlKC52YXJpYWJsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYl9iYXJyaWVyc190b3RhbCA9ICJBZGRpdGlvbmFsIGxhdywgdCAtIDEiKSkgJT4lIAogIGdncGxvdChhZXMoeSA9IGZjdF9yZXYoLnZhcmlhYmxlKSwgeCA9IC52YWx1ZSwgZmlsbCA9IGZjdF9yZXYoLnZhcmlhYmxlKSkpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArCiAgc3RhdF9oYWxmZXllKC53aWR0aCA9IGMoMC44LCAwLjk1KSwgYWxwaGEgPSAwLjgpICsKICBndWlkZXMoZmlsbCA9IEZBTFNFKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRkY4NTFCIiwgIiNGRkRDMDAiKSkgKwogIGxhYnMoeSA9IE5VTEwsIHggPSBOVUxMKSArCiAgdGhlbWVfZG9ub3JzKCkKCnBsb3RfYWR2b2NhY3lfZG9tIDwtIG1fcmVjaXBfb3V0Y29tZV9hZHZvY2FjeV9kb20gJT4lIAogIGdhdGhlcl9kcmF3cyhiX2Fkdm9jYWN5KSAlPiUgCiAgbXV0YXRlKC52YXJpYWJsZSA9IGRwbHlyOjpyZWNvZGUoLnZhcmlhYmxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiX2Fkdm9jYWN5ID0gIkFkZGl0aW9uYWwgYWR2b2NhY3kgbGF3LCB0IC0gMSIpKSAlPiUgCiAgbXV0YXRlKC52YWx1ZSA9IGV4cCgudmFsdWUpIC0gMSkgJT4lIAogIGdncGxvdChhZXMoeSA9IGZjdF9yZXYoLnZhcmlhYmxlKSwgeCA9IC52YWx1ZSwgZmlsbCA9IGZjdF9yZXYoLnZhcmlhYmxlKSkpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArCiAgc3RhdF9oYWxmZXllKC53aWR0aCA9IGMoMC44LCAwLjk1KSwgYWxwaGEgPSAwLjgpICsKICBndWlkZXMoZmlsbCA9IEZBTFNFKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjODUxNDRiIiwgIiNGMDEyQkUiKSkgKwogIGxhYnMoeSA9IE5VTEwsIHggPSBOVUxMKSArCiAgdGhlbWVfZG9ub3JzKCkKCnBsb3RfYWR2b2NhY3lfZm9yZWlnbiA8LSBtX3JlY2lwX291dGNvbWVfYWR2b2NhY3lfZm9yZWlnbiAlPiUgCiAgZ2F0aGVyX2RyYXdzKGJfYWR2b2NhY3kpICU+JSAKICBtdXRhdGUoLnZhcmlhYmxlID0gZHBseXI6OnJlY29kZSgudmFyaWFibGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJfYWR2b2NhY3kgPSAiQWRkaXRpb25hbCBhZHZvY2FjeSBsYXcsIHQgLSAxIikpICU+JSAKICBtdXRhdGUoLnZhbHVlID0gZXhwKC52YWx1ZSkgLSAxKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldigudmFyaWFibGUpLCB4ID0gLnZhbHVlLCBmaWxsID0gZmN0X3JldigudmFyaWFibGUpKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDApICsKICBzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjgsIDAuOTUpLCBhbHBoYSA9IDAuOCkgKwogIGd1aWRlcyhmaWxsID0gRkFMU0UpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM4NTE0NGIiLCAiI0YwMTJCRSIpKSArCiAgbGFicyh5ID0gTlVMTCwgeCA9IE5VTEwpICsKICB0aGVtZV9kb25vcnMoKQoKcGxvdF9lbnRyeV9kb20gPC0gbV9yZWNpcF9vdXRjb21lX2VudHJ5X2RvbSAlPiUgCiAgZ2F0aGVyX2RyYXdzKGJfZW50cnkpICU+JSAKICBtdXRhdGUoLnZhcmlhYmxlID0gZHBseXI6OnJlY29kZSgudmFyaWFibGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJfZW50cnkgPSAiQWRkaXRpb25hbCBlbnRyeSBsYXcsIHQgLSAxIikpICU+JSAKICBtdXRhdGUoLnZhbHVlID0gZXhwKC52YWx1ZSkgLSAxKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldigudmFyaWFibGUpLCB4ID0gLnZhbHVlLCBmaWxsID0gZmN0X3JldigudmFyaWFibGUpKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDApICsKICBzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjgsIDAuOTUpLCBhbHBoYSA9IDAuOCkgKwogIGd1aWRlcyhmaWxsID0gRkFMU0UpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiMzRDk5NzAiLCAiIzJFQ0M0MCIpKSArCiAgbGFicyh5ID0gTlVMTCwgeCA9ICIlIGNoYW5nZSBpbiBwcm9wb3J0aW9uIG9mIGFpZCB0byBkb21lc3RpYyBOR09zIikgKwogIHRoZW1lX2Rvbm9ycygpCgpwbG90X2VudHJ5X2ZvcmVpZ24gPC0gbV9yZWNpcF9vdXRjb21lX2VudHJ5X2ZvcmVpZ24gJT4lIAogIGdhdGhlcl9kcmF3cyhiX2VudHJ5KSAlPiUgCiAgbXV0YXRlKC52YXJpYWJsZSA9IGRwbHlyOjpyZWNvZGUoLnZhcmlhYmxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiX2VudHJ5ID0gIkFkZGl0aW9uYWwgZW50cnkgbGF3LCB0IC0gMSIpKSAlPiUgCiAgbXV0YXRlKC52YWx1ZSA9IGV4cCgudmFsdWUpIC0gMSkgJT4lIAogIGdncGxvdChhZXMoeSA9IGZjdF9yZXYoLnZhcmlhYmxlKSwgeCA9IC52YWx1ZSwgZmlsbCA9IGZjdF9yZXYoLnZhcmlhYmxlKSkpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArCiAgc3RhdF9oYWxmZXllKC53aWR0aCA9IGMoMC44LCAwLjk1KSwgYWxwaGEgPSAwLjgpICsKICBndWlkZXMoZmlsbCA9IEZBTFNFKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjM0Q5OTcwIiwgIiMyRUNDNDAiKSkgKwogIGxhYnMoeSA9IE5VTEwsIHggPSAiJSBjaGFuZ2UgaW4gcHJvcG9ydGlvbiBvZiBhaWQgdG8gZm9yZWlnbiBOR09zIikgKwogIHRoZW1lX2Rvbm9ycygpCgpwbG90X2Z1bmRpbmdfZG9tIDwtIG1fcmVjaXBfb3V0Y29tZV9mdW5kaW5nX2RvbSAlPiUgCiAgZ2F0aGVyX2RyYXdzKGJfZnVuZGluZykgJT4lIAogIG11dGF0ZSgudmFyaWFibGUgPSBkcGx5cjo6cmVjb2RlKC52YXJpYWJsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYl9mdW5kaW5nID0gIkFkZGl0aW9uYWwgZnVuZGluZyBsYXcsIHQgLSAxIikpICU+JSAKICBtdXRhdGUoLnZhbHVlID0gZXhwKC52YWx1ZSkgLSAxKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldigudmFyaWFibGUpLCB4ID0gLnZhbHVlLCBmaWxsID0gZmN0X3JldigudmFyaWFibGUpKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDApICsKICBzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjgsIDAuOTUpLCBhbHBoYSA9IDAuOCkgKwogIGd1aWRlcyhmaWxsID0gRkFMU0UpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiMwMDFmM2YiLCAiIzAwNzREOSIpKSArCiAgbGFicyh5ID0gTlVMTCwgeCA9ICIlIGNoYW5nZSBpbiBwcm9wb3J0aW9uIGFpZCB0byBkb21lc3RpYyBOR09zIikgKwogIHRoZW1lX2Rvbm9ycygpCgpwbG90X2Z1bmRpbmdfZm9yZWlnbiA8LSBtX3JlY2lwX291dGNvbWVfZnVuZGluZ19mb3JlaWduICU+JSAKICBnYXRoZXJfZHJhd3MoYl9mdW5kaW5nKSAlPiUgCiAgbXV0YXRlKC52YXJpYWJsZSA9IGRwbHlyOjpyZWNvZGUoLnZhcmlhYmxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiX2Z1bmRpbmcgPSAiQWRkaXRpb25hbCBmdW5kaW5nIGxhdywgdCAtIDEiKSkgJT4lIAogIG11dGF0ZSgudmFsdWUgPSBleHAoLnZhbHVlKSAtIDEpICU+JSAKICBnZ3Bsb3QoYWVzKHkgPSBmY3RfcmV2KC52YXJpYWJsZSksIHggPSAudmFsdWUsIGZpbGwgPSBmY3RfcmV2KC52YXJpYWJsZSkpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKwogIHN0YXRfaGFsZmV5ZSgud2lkdGggPSBjKDAuOCwgMC45NSksIGFscGhhID0gMC44KSArCiAgZ3VpZGVzKGZpbGwgPSBGQUxTRSkgKwogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzAwMWYzZiIsICIjMDA3NEQ5IikpICsKICBsYWJzKHkgPSBOVUxMLCB4ID0gIiUgY2hhbmdlIGluIHByb3BvcnRpb24gYWlkIHRvIGZvcmVpZ24gTkdPcyIpICsKICB0aGVtZV9kb25vcnMoKQoKKHBsb3RfdG90YWxfZG9tICsgcGxvdF9hZHZvY2FjeV9kb20pIC8gKHBsb3RfZW50cnlfZG9tICsgcGxvdF9mdW5kaW5nX2RvbSkKKHBsb3RfdG90YWxfZm9yZWlnbiArIHBsb3RfYWR2b2NhY3lfZm9yZWlnbikgLyAocGxvdF9lbnRyeV9mb3JlaWduICsgcGxvdF9mdW5kaW5nX2ZvcmVpZ24pCmBgYAoKQSBvbmUtdW5pdCBjaGFuZ2UgaW4gWCByZXN1bHRzIGluIGEgcmVsYXRpdmUgY2hhbmdlIG9mICRlXlxiZXRhJCBpbiAkXGZyYWN7XHRleHR7RShQcm9wb3J0aW9uKX19ezEgLSBcdGV4dHtFKFByb3BvcnRpb24pfX0kIC0gc2VlIDxodHRwczovL3N0YXRzLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy8yOTc2NTkvaW50ZXJwcmV0YXRpb24tb2YtYmV0YXJlZy1jb2VmPiAtIHRoZSByYXRpbyBvZiBjb250ZW50aW91cyB0byBub24tY29udGVudGlvdXMgYWlkPyB0aGUgcmF0aW8gb2Ygb2YgY29udGVudGlvdXMgYWlkPwoKU2VlIGFsc28gPGh0dHBzOi8vc3RhdHMuc3RhY2tleGNoYW5nZS5jb20vYS8yMzA2NzkvMzAyNT4gYW5kIDxodHRwczovL3N0YXRpYzEuc3F1YXJlc3BhY2UuY29tL3N0YXRpYy81OGE3ZDFlNTI5OTRjYTM5ODY5N2E2MjEvdC81YTJlYmM0M2U0OTY2YjBmYWI2YjAyZGUvMTUxMzAxMjI5Mzg1Ny9iZXRhcmVnX3BvbGl0aWNzLnBkZj4KCmBgYHtyIGgzLWNvbmRpdGlvbmFsLWVmZmVjdHMtZG9tZXN0aWN9Cm1fcmVjaXBfb3V0Y29tZV90b3RhbF9kb20gJT4lIAogIGNvbmRpdGlvbmFsX2VmZmVjdHMoKQoKbV9yZWNpcF9vdXRjb21lX2Fkdm9jYWN5X2RvbSAlPiUgCiAgY29uZGl0aW9uYWxfZWZmZWN0cygpCgptX3JlY2lwX291dGNvbWVfZW50cnlfZG9tICU+JSAKICBjb25kaXRpb25hbF9lZmZlY3RzKCkKCm1fcmVjaXBfb3V0Y29tZV9mdW5kaW5nX2RvbSAlPiUgCiAgY29uZGl0aW9uYWxfZWZmZWN0cygpCmBgYAoKCmBgYHtyIGgzLWNvbmRpdGlvbmFsLWVmZmVjdHMtZm9yZWlnbn0KbV9yZWNpcF9vdXRjb21lX3RvdGFsX2ZvcmVpZ24gJT4lIAogIGNvbmRpdGlvbmFsX2VmZmVjdHMoKQoKbV9yZWNpcF9vdXRjb21lX2Fkdm9jYWN5X2ZvcmVpZ24gJT4lIAogIGNvbmRpdGlvbmFsX2VmZmVjdHMoKQoKbV9yZWNpcF9vdXRjb21lX2VudHJ5X2ZvcmVpZ24gJT4lIAogIGNvbmRpdGlvbmFsX2VmZmVjdHMoKQoKbV9yZWNpcF9vdXRjb21lX2Z1bmRpbmdfZm9yZWlnbiAlPiUgCiAgY29uZGl0aW9uYWxfZWZmZWN0cygpCmBgYAo=