install.packages(c("tidyverse", "psych", "skimr", "ggridges", "tidytext", "lme4", "performance", "sjPlot", "here", "emo", "broom.mixed"))
library(tidyverse)
library(psych)
library(skimr)
library(ggridges)
library(tidytext)
library(lme4)
library(performance)
library(sjPlot)
library(broom.mixed)

theme_set(theme_light())

Main questions

In this blind analysis, we are going to address 2 research questions:

  1. Do religious people report higher well-being?
  2. Does the relation between religiosity and well-being depend on how important people consider religion to be in their country (i.e., perceived cultural norms of religion)?

Blinded data

The point of blinded data is to let analysts explore the data without the danger of p-hacking. Therefore, only the relationship of the outcomes and predctor variables are destroyed by shuffling, and the remainder is kept intact. This means that:

  • Data reduction techinques (PCA, EFA) will yield valid results.
  • Outiers, missing data can be observed and treated.
  • Confounders can be explored, meaning that not only univariate distributions but correlations are also kept intact.
  • Country level means should remain intact

Analysis issues to resolve

In order to best address the hypotheses, we need to decide a few things.

  • Operationalization of variables: How should we conceptualize key variables?
  • Outliers how should we handle them?
  • Choose statistical model (multilevel?)
    • Confounders (which ones to use?)
    • Moderators
    • Lumping levels for nominal variables

Read and pre-process data

At this point, we only exclude participants who did not pass the attention check.

# Read raw data
marp_raw <- 
  # read_csv(here::here("data/MARP_data_blinded.csv"))
  read_csv(here::here("data/MARP_data.csv"))
## 
## -- Column specification --------------------------------------------------------
## cols(
##   .default = col_double(),
##   country = col_character(),
##   gender = col_character(),
##   ethnicity = col_character(),
##   denomination = col_character(),
##   sample_type = col_character(),
##   compensation = col_character()
## )
## i Use `spec()` for the full column specifications.
marp_proc <-
  marp_raw %>% 
  filter(attention_check == 1) %>% 
  mutate( gender = recode(gender, 
                          "man" = "Male", 
                          "woman" = "Female",
                          "other" = "Other"))

Descriptives and potential moderators

marp_proc %>% 
        select(country, 
               gender, ses, education, ethnicity, denomination,
               sample_type, compensation, 
               ends_with("_mean")) %>% 
        skim()
Data summary
Name Piped data
Number of rows 10195
Number of columns 12
_______________________
Column type frequency:
character 6
numeric 6
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
country 0 1.00 2 11 0 24 0
gender 0 1.00 4 6 0 3 0
ethnicity 405 0.96 5 22 0 17 0
denomination 5567 0.45 4 41 0 20 0
sample_type 0 1.00 5 14 0 4 0
compensation 0 1.00 6 31 0 5 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
ses 5 1 6.10 1.77 1.00 5.00 6.00 7.00 10 ▁▃▇▇▁
education 0 1 4.64 1.26 1.00 4.00 5.00 5.00 7 ▁▃▆▇▆
wb_overall_mean 0 1 3.67 0.61 1.22 3.28 3.78 4.11 5 ▁▁▃▇▂
wb_phys_mean 0 1 3.84 0.66 1.00 3.43 4.00 4.29 5 ▁▁▃▇▆
wb_psych_mean 0 1 3.51 0.72 1.00 3.00 3.67 4.00 5 ▁▂▅▇▂
wb_soc_mean 0 1 3.56 0.87 1.00 3.00 3.67 4.17 5 ▁▂▇▇▆

Demographics by country

N of participants

marp_proc %>% 
        mutate(country = fct_infreq(country) %>% fct_rev()) %>% 
        ggplot() +
        aes(y = country) +
        geom_bar() +
        scale_x_continuous(breaks = seq(0, 1500, 250)) +
        labs(title = "Number of participants by country",
             y = NULL)

Age

Age has a few obvious outliers (e.g. age of 0 or 1), that we could remove. However, the sample size makes it unlikely that these outliers have a large influence on the model, therefore we won’t remove them.

marp_proc %>% 
  drop_na(age) %>% 
  mutate(country = fct_reorder(country, age)) %>%
  ggplot() +
  aes(y = country, x = age, fill = country) +
  geom_boxplot(alpha = .5, width = .2, 
               outlier.alpha = .2, show.legend = FALSE) +
  geom_density_ridges(alpha = .5, show.legend = FALSE) +
  labs(title = "Age distribution by country",
       y = NULL)
## Picking joint bandwidth of 2.45

Gender

marp_proc %>% 
        group_by(country) %>% 
        summarise(pct_female = mean(gender == "Female", 
                                    na.rm = TRUE)) %>% 
        mutate(country = fct_reorder(country, pct_female)) %>%
        ggplot() +
        aes(y = country, x = pct_female) +
        geom_point() +
        scale_x_continuous(limits = c(0,1),
                           labels = scales::percent_format()) +
        labs(title = "Proportion of females by country",
             x = NULL, y = NULL)
## `summarise()` ungrouping output (override with `.groups` argument)

Education

Education is a common confounder when the relationship between religiosity and well-being is considered. There is a considerable spread of education within and between countries.

marp_proc %>% 
  mutate(country = fct_reorder(country, education, median)) %>%
  ggplot() +
  aes(y = country, x = education, fill = country) +
  geom_density_ridges(show.legend = FALSE) +
  labs(title = "Education by country",
       y = NULL, x = NULL)
## Picking joint bandwidth of 0.288

SES

Socio-economic status is a common confounder when the relationship between religiosity and well-being is considered. There is a considerable spread of SES within and between countries.

marp_proc %>% 
  drop_na(ses) %>% 
  mutate(country = fct_reorder(country, ses)) %>%
  ggplot() +
  aes(y = country, x = ses, fill = country) +
  geom_density_ridges(show.legend = FALSE) +
  labs(title = "Socio-economic status by country",
       y = NULL, x = NULL)
## Picking joint bandwidth of 0.403

Denomination

Religious denomination is often used when the connection between religiosity and well being is considered.

marp_proc %>% 
  mutate(country = fct_infreq(country) %>% fct_rev()) %>%
  count(country, denomination) %>%
  ggplot() +
  aes(y = country, x = n, fill = denomination) +
  geom_col(position = "stack") +
  labs(title = "Number/Proportion of denominations by country",
       y = NULL,
       fill = "Denomination")

However, in its current form, the variable contains categories that are ratther sparse, and this may interfere with the statistical model that we want to use. Therefore we choose to lump together levels that constitute less than 1% of the categories into “Other”.

lumped_denom <-
  marp_proc %>% 
  transmute(subject, 
            denom_lump = case_when(str_detect(denomination, "Muslim") ~ "Muslim",
                                   str_detect(denomination, "Christian|Evangelical") ~ "Christian",
                                   str_detect(denomination, "Other") ~ "Other",
                                   is.na(denomination) ~ "No denomination",
                                   TRUE ~ denomination) %>% 
                          fct_lump_prop(.01, other_level = "Other"))

marp_proc %>% 
  left_join(lumped_denom, by = "subject") %>% 
  mutate(country = fct_infreq(country) %>% fct_rev()) %>%
  count(country, denom_lump) %>%
  ggplot() +
  aes(y = country, x = n, fill = denom_lump, label = denom_lump) +
  geom_col(position = "stack") +
  labs(title = "Number/Proportion of denominations by country",
       subtitle = "Denominations that were infrequent (<1%) were lumped together",
       y = NULL,
       fill = "Denomination")

Ethnicity

Well-being might be influenced by ethicity, but not directly. For e.g. minority status might be associated with WB, but there were no questions about this. Therefore, in my opinion, raw ethnicity should not be added to the model.

marp_proc %>% 
  mutate(ethnicity = fct_infreq(ethnicity) %>% fct_rev()) %>% 
  ggplot() +
  aes(y = ethnicity, fill = ethnicity) +
  geom_bar(show.legend = FALSE) +
  labs(y = NULL)

Importance of religion

cnorm_questions <- 
  tibble(name = c("cnorm_1", "cnorm_2"),
         question = c("Importance of religious lifestyle for average person in country",
                      "Importance of belief in God/Gods for average person in country"
                    ))

marp_proc %>% 
  select(subject, country, cnorm_1, cnorm_2) %>% 
  pivot_longer(c("cnorm_1", "cnorm_2")) %>% 
  group_by(country, name) %>% 
  summarise(avg = mean(value)) %>% 
  ungroup() %>% 
  left_join(cnorm_questions, by = "name") %>%
  mutate(country = reorder_within(country, avg, question)) %>% 
  ggplot() +
  aes(x = avg, y = country) +
  geom_point() +
  scale_y_reordered(NULL) +
  facet_wrap(~question, ncol = 2, scales = "free_y") +
  labs(title = "Normativity of religion by country in two questions")  
## `summarise()` regrouping output by 'country' (override with `.groups` argument)

GDP per capita

marp_proc %>% 
  group_by(country) %>% 
  summarise(gdp = mean(gdp)) %>% 
  ungroup() %>% 
  mutate(country = fct_reorder(country, gdp)) %>% 
  ggplot() +
  aes(x = gdp, y = country) +
  geom_point() +
  scale_x_continuous(labels = scales::dollar_format()) +
  labs(title = "GDP per capita by country")  
## `summarise()` ungrouping output (override with `.groups` argument)

Sample type

marp_proc %>% 
  mutate(country = fct_infreq(country) %>% fct_rev()) %>%
  count(country, sample_type) %>% 
  ggplot() +
  aes(y = country, x = n, fill = sample_type) +
  geom_col(position = "stack") +
  labs(title = "Proportion of sample type by country",
       x = NULL, y = NULL, fill = "Sample type")

Compensation

Compensation is very closely associated with the sample type, therefore using it in the model would be redundant.

marp_proc %>% 
  mutate(country = fct_infreq(country) %>% fct_rev()) %>%
  count(country, compensation) %>% 
  ggplot() +
  aes(y = country, x = n, fill = compensation) +
  geom_col(position = "stack") +
  labs(title = "Proportion of compensation by country",
       x = NULL, y = NULL, fill = "Compensation")

Operationalization of variables

Religiosity and well-being has multiple items that we can use. According to previous studies of similar topics, norms about religion should be aggregated to the country level.

Religiosity

Although religiosity is an elusive concept, and no one-size-fits-all metric is available. We don’t feel competent to choose just one question, so We try to use as much information from all available questions as possible. I’m also not feeling confident to relevel specific questions (e.g. rel_3). Therefore, We choose to use PCA to extract an aggregated variable.

marp_proc %>% 
  select(starts_with("rel_")) %>% 
  pivot_longer(everything()) %>% 
  ggplot(aes(value)) +
  geom_histogram() +
  facet_wrap(~name) +
  labs(title = "Distribution of rel_ variables to be used in PCA")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# Number of components
marp_proc %>% 
        select(starts_with("rel_")) %>% 
        fa.parallel()

## Parallel analysis suggests that the number of factors =  4  and the number of components =  1
# Parallel analysis suggests to use a single component.
rel_pca <-
        marp_proc %>% 
        select(starts_with("rel_")) %>% 
        pca(nfactors = 1)

# Correlation of religiosity items and the PCA component
marp_proc %>% 
  select(starts_with("rel")) %>% 
  mutate(rel_pca = rel_pca$scores[,1]) %>% 
  cor.plot()

The religiosity values seems to vary considerably by country.

  marp_proc %>%
  mutate(rel_pca = rel_pca$scores[,1]) %>% 
  mutate(country = fct_reorder(country, rel_pca, median)) %>%
  ggplot() +
  aes(y = country, x = rel_pca, fill = country) +
  geom_boxplot(outlier.alpha = .2, show.legend = FALSE) +
  labs(title = "Religiosity by country",
       subtitle = "Aggregated religiosity component",
       x = NULL,
       y = NULL)

marp_proc %>%
  bind_cols(rel_pca = rel_pca$scores[,1]) %>% 
  left_join(lumped_denom, by = "subject") %>% 
  mutate(denom_lump = fct_reorder(denom_lump, rel_pca, median)) %>%
  ggplot() +
  aes(y = denom_lump, x = rel_pca, fill = denom_lump) +
  geom_boxplot(alpha = .5,
               width = .2,
               outlier.alpha = .2, show.legend = FALSE) +
  geom_density_ridges(alpha = .5) +
  labs(title = "Religiosity by denomination",
       subtitle = "Aggregated religiosity component",
       fill = "Denomination",
       x = NULL,
       y = NULL)
## Picking joint bandwidth of 0.173

We compared the PCA operationalization with the self-admitted single item religiosity. The difference on the country level seems quite subtle.

marp_proc %>% 
  mutate(rel_pca = rel_pca$scores[,1]) %>% 
  group_by(country) %>% 
  summarise(rel_item = mean(rel_3 == 1),
                  rel_pca = mean(rel_pca),
                  n = n()) %>% 
  mutate(across(starts_with("rel_"), ~scale(.x) %>% as.numeric())) %>% 
  pivot_longer(cols = c("rel_item", "rel_pca")) %>% 
  mutate(country = fct_reorder(country, value)) %>% 
  ggplot() +
  aes(x = value, y = country, color = name) +
  geom_point(size = 2) +
  labs(title = "Different operationalizations of religiosity lead to similar country-wise values (r = .91)",
       subtitle = "One item religiosity (rel_3) vs. 9-item PCA religiosity component (rel_pca) values",
       y = NULL, x = NULL, color = "Operationalization")
## `summarise()` ungrouping output (override with `.groups` argument)

Well-being

The well-being questions have calculated values for subscales and overall

marp_proc %>% 
  select(starts_with("wb")) %>% 
  cor.plot()

marp_proc %>% 
  mutate(country = fct_reorder(country, wb_overall_mean)) %>% 
  ggplot() +
  aes(x = wb_overall_mean, y = country, fill = country) +
  geom_boxplot(alpha = .5,
           width = .2,
           outlier.alpha = .2, show.legend = FALSE) +
  geom_density_ridges(alpha = .5, show.legend = FALSE) +
  labs(title = "Overall well-being by country",
       y = NULL)
## Picking joint bandwidth of 0.153

Cultural norms about religiosity into one variable.

According to previous research, norms should be handled on the country level. We use the mean of the two variables that are otherwise strongly correlated, since it makes no sense to use a more complicated method (PCA or EFA). Then we calculate the country level mean from this variable.

# Country norm of religiosity
country_norms <-
  marp_proc %>% 
  # Create new variable with the average of the 2 cnorm vairalbes
  mutate(cnorm_avg = ((cnorm_1 + cnorm_2)/2)) %>% 
  # Calculate country level norms
  group_by(country) %>% 
  summarise(cnorm_mean = mean(cnorm_avg)) %>% 
  ungroup() %>% 
  # Standardize the variable
  mutate(cnorm_mean = scale(cnorm_mean) %>% as.numeric())
## `summarise()` ungrouping output (override with `.groups` argument)
country_norms %>% 
  mutate(country = fct_reorder(country, cnorm_mean)) %>% 
  ggplot() +
  aes(y = country, x = cnorm_mean) +
  geom_point() +
  labs(title = "Average of cultural norms about religion by country",
       x = NULL, y = NULL)

Construct final dataset

Using all information from the exploratory analysis, we create a dataset for modeling. This dataset still doesn’t contain potential problems that may emerge during model diagnostics.

We add the religiosity component, the country-wise norms, the lumped denomination data, and set baselines for categorical variables. We also drop participants with missing values in varibles that we want to use in the statistical models, as those can cause difficulties when comparing models. This means dropping 25 participants.

marp_nodiag <-
  marp_proc %>% 
  # Add religiosity scores from PCA
  bind_cols(religiosity = rel_pca$scores[,1]) %>%
  # Add country level norms
  left_join(country_norms, by = "country") %>% 
  # Merge different branches of the same religion, lump levels < 1%
  left_join(lumped_denom, by = "subject") %>% 
  # Set baselines
  mutate(sample_type = fct_relevel(sample_type, "online panel"),
         denom_lump = fct_relevel(denom_lump, "No denomination"),
         gender = fct_relevel(gender, "Female")) %>% 
  # Drop participants with missing variables
  drop_na(age,  gender, ses, education, denom_lump, sample_type)

Investigating model assumptions

Before creating the final dataset and models, we investigate if there is anything strange in the model diagnostics that would necessitate further changes in the dataset. Therefore we create a model that contains all the terms that we want to include in the analysis, and we check all assumptions.

model_diag <- 
  lmer(wb_overall_mean ~ religiosity * cnorm_mean + 
         # personal level confounders
                         age + gender + ses + education + denom_lump +
         # country and sample level confounders
                         gdp_scaled + sample_type + 
         # random intercept and slope model
                         (religiosity|country), data = marp_nodiag)

check_model(model_diag)
## `geom_smooth()` using formula 'y ~ x'
## `geom_smooth()` using formula 'y ~ x'
## `geom_smooth()` using formula 'y ~ x'
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 10170 rows containing missing values (geom_text_repel).
## `geom_smooth()` using formula 'y ~ x'

Model diagnostics show:

  • ✅ No multicollinearity,
  • ✅ Normally distributed residuals
  • ✅ No influential cases
  • ✅ Normally distributed random effects
  • ❌ Homoskedasticity

Apart from heteroscedasticity, it seems like there is a strange separation in the fitted values. All residuals on the left hand side come from the Japanese sample. As the separation is complete and the difference is huge, we should handle the Japanese data with extra care. Further, there is very small variability in the Japanese fitted values.
Taken together, we decided to remove the Japanese data.

augment(model_diag) %>% 
  mutate(country = fct_reorder(country, .fitted)) %>% 
  ggplot() +
  aes(x = .fitted, y = country, fill = country) +
  geom_boxplot(show.legend = FALSE) +
  labs(title = "The fitted Japanese values are much lower than for any other country",
       y = NULL)

Correcting the final dataset

In the final dataset we remove the Japanese answers.

marp <- 
  marp_nodiag %>% 
  filter(country != "Japan")

Building models

1) Do religious people report higher well-being?

h1 <- 
  lmer(wb_overall_mean ~ religiosity + 
         # personal level confounders
                         age + gender + ses + education + denom_lump +
         # country and sample level confounders
                         gdp_scaled + sample_type +
         # random intercept and slope model
                         (religiosity|country), 
       data = marp)

# Create a null model for comparisons that does not contain the main predictor
h0 <- update(h1, . ~ . -religiosity)

check_model(h1)
## `geom_smooth()` using formula 'y ~ x'
## `geom_smooth()` using formula 'y ~ x'
## `geom_smooth()` using formula 'y ~ x'
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 9747 rows containing missing values (geom_text_repel).
## `geom_smooth()` using formula 'y ~ x'

We can handle heteroscedasticity by using cluster robust standard errors (CR2), using the clubSandwich package. https://strengejacke.github.io/sjPlot/articles/tab_model_robust.html

tab_model(h1, 
          show.aic = TRUE, 
          show.reflvl = TRUE, 
          string.ci = "95% CI", 
          vcov.fun = "CR", 
          vcov.type = "CR2", 
          vcov.args = list(cluster = h1@frame$country))
  wb_overall_mean
Predictors Estimates 95% CI p
(Intercept) 2.68 2.54 – 2.82 <0.001
age 0.00 -0.00 – 0.00 0.076
Female Reference
Male 0.04 0.01 – 0.08 0.011
Other -0.29 -0.44 – -0.13 <0.001
No denomination Reference
Buddhist 0.02 -0.05 – 0.10 0.567
Christian -0.02 -0.07 – 0.03 0.422
Hindu -0.08 -0.16 – -0.01 0.027
education 0.04 0.02 – 0.05 <0.001
gdp_scaled 0.03 -0.01 – 0.07 0.204
Jewish -0.08 -0.15 – -0.00 0.049
Muslim -0.09 -0.17 – -0.01 0.035
Other -0.09 -0.19 – 0.01 0.072
religiosity 0.08 0.06 – 0.10 <0.001
online panel Reference
general public 0.07 0.04 – 0.11 <0.001
mixed 0.09 -0.00 – 0.19 0.051
students 0.14 -0.10 – 0.38 0.248
ses 0.12 0.10 – 0.13 <0.001
Random Effects
σ2 0.28
τ00 country 0.01
τ11 country.religiosity 0.00
ρ01 country -0.27
ICC 0.03
N country 23
Observations 9747
Marginal R2 / Conditional R2 0.171 / 0.200
AIC 15522.052

2) Does the relation between religiosity and well-being depend on how important people consider religion to be in their country (i.e., perceived cultural norms of religion)?

h2 <- 
  lmer(wb_overall_mean ~ religiosity * cnorm_mean + 
         # personal level confounders
                         age + gender + ses + education + denom_lump +
         # country level confounders
                         gdp_scaled + sample_type + 
         # random intercept and slope model
                         (religiosity|country), 
       data = marp)

check_model(h2)
## `geom_smooth()` using formula 'y ~ x'
## `geom_smooth()` using formula 'y ~ x'
## `geom_smooth()` using formula 'y ~ x'
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 9747 rows containing missing values (geom_text_repel).
## `geom_smooth()` using formula 'y ~ x'

Model diagnostics show heteroscedasticity, therefore cluster robust standard errors are calculated.

tab_model(h2, 
          show.aic = TRUE, 
          show.reflvl = TRUE, 
          string.ci = "95% CI", 
          vcov.fun = "CR", 
          vcov.type = "CR2", 
          vcov.args = list(cluster = h1@frame$country))
  wb_overall_mean
Predictors Estimates 95% CI p
(Intercept) 2.67 2.53 – 2.81 <0.001
age 0.00 -0.00 – 0.00 0.067
cnorm_mean -0.03 -0.07 – 0.01 0.133
Female Reference
Male 0.04 0.01 – 0.08 0.011
Other -0.29 -0.44 – -0.13 <0.001
No denomination Reference
Buddhist 0.03 -0.04 – 0.10 0.465
Christian -0.02 -0.07 – 0.03 0.483
Hindu -0.09 -0.17 – -0.01 0.030
education 0.04 0.03 – 0.05 <0.001
gdp_scaled 0.02 -0.03 – 0.07 0.526
Jewish -0.08 -0.15 – -0.00 0.039
Muslim -0.10 -0.17 – -0.04 0.002
Other -0.09 -0.19 – 0.00 0.063
religiosity 0.08 0.06 – 0.09 <0.001
religiosity:cnorm_mean 0.03 0.02 – 0.04 <0.001
online panel Reference
general public 0.07 0.04 – 0.11 <0.001
mixed 0.09 -0.00 – 0.19 0.053
students 0.15 -0.08 – 0.39 0.207
ses 0.12 0.10 – 0.13 <0.001
Random Effects
σ2 0.28
τ00 country 0.01
τ11 country.religiosity 0.00
ρ01 country 0.09
ICC 0.03
N country 23
Observations 9747
Marginal R2 / Conditional R2 0.173 / 0.200
AIC 15520.787

Model comparisons and Bayes Factors

anova(h0, h1)
## refitting model(s) with ML (instead of REML)
## Data: marp
## Models:
## h0: wb_overall_mean ~ age + gender + ses + education + denom_lump + 
## h0:     gdp_scaled + sample_type + (religiosity | country)
## h1: wb_overall_mean ~ religiosity + age + gender + ses + education + 
## h1:     denom_lump + gdp_scaled + sample_type + (religiosity | country)
##    npar   AIC   BIC  logLik deviance  Chisq Df Pr(>Chisq)    
## h0   20 15448 15592 -7704.2    15408                         
## h1   21 15418 15569 -7688.0    15376 32.335  1  1.297e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(h1, h2)
## refitting model(s) with ML (instead of REML)
## Data: marp
## Models:
## h1: wb_overall_mean ~ religiosity + age + gender + ses + education + 
## h1:     denom_lump + gdp_scaled + sample_type + (religiosity | country)
## h2: wb_overall_mean ~ religiosity * cnorm_mean + age + gender + ses + 
## h2:     education + denom_lump + gdp_scaled + sample_type + (religiosity | 
## h2:     country)
##    npar   AIC   BIC logLik deviance  Chisq Df Pr(>Chisq)    
## h1   21 15418 15569  -7688    15376                         
## h2   23 15402 15567  -7678    15356 19.971  2  4.606e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(h0, h2)
## refitting model(s) with ML (instead of REML)
## Data: marp
## Models:
## h0: wb_overall_mean ~ age + gender + ses + education + denom_lump + 
## h0:     gdp_scaled + sample_type + (religiosity | country)
## h2: wb_overall_mean ~ religiosity * cnorm_mean + age + gender + ses + 
## h2:     education + denom_lump + gdp_scaled + sample_type + (religiosity | 
## h2:     country)
##    npar   AIC   BIC  logLik deviance  Chisq Df Pr(>Chisq)    
## h0   20 15448 15592 -7704.2    15408                         
## h2   23 15402 15567 -7678.0    15356 52.306  3  2.577e-11 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Calculate BIC based Bayes factors for 
# H0 vs H1
exp((BIC(h0) - BIC(h1))/2)
## [1] 2127.347
# H1 vs H2
exp((BIC(h1) - BIC(h2))/2)
## [1] 0.00142744
# H0 vs H2
exp((BIC(h0) - BIC(h2))/2)
## [1] 3.03666
LS0tDQp0aXRsZTogIk1BUlAgZXhwbG9yYXRpb24gLSBUZWFtIDQwYiINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCmF1dGhvcjogIlRhbWFzIE5hZ3kiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgdGhlbWU6IHNwYWNlbGFiDQogICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICB0b2M6IHRydWUNCiAgIHRvY19mbG9hdDogdHJ1ZQ0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQ0KLS0tDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgZXZhbCA9IEZBTFNFfQ0KaW5zdGFsbC5wYWNrYWdlcyhjKCJ0aWR5dmVyc2UiLCAicHN5Y2giLCAic2tpbXIiLCAiZ2dyaWRnZXMiLCAidGlkeXRleHQiLCAibG1lNCIsICJwZXJmb3JtYW5jZSIsICJzalBsb3QiLCAiaGVyZSIsICJlbW8iLCAiYnJvb20ubWl4ZWQiKSkNCmBgYA0KDQoNCg0KYGBge3Igc2V0dXAsIGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0NCg0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHBzeWNoKQ0KbGlicmFyeShza2ltcikNCmxpYnJhcnkoZ2dyaWRnZXMpDQpsaWJyYXJ5KHRpZHl0ZXh0KQ0KbGlicmFyeShsbWU0KQ0KbGlicmFyeShwZXJmb3JtYW5jZSkNCmxpYnJhcnkoc2pQbG90KQ0KbGlicmFyeShicm9vbS5taXhlZCkNCg0KdGhlbWVfc2V0KHRoZW1lX2xpZ2h0KCkpDQoNCmBgYA0KDQojIE1haW4gcXVlc3Rpb25zDQoNCkluIHRoaXMgYmxpbmQgYW5hbHlzaXMsIHdlIGFyZSBnb2luZyB0byBhZGRyZXNzIDIgcmVzZWFyY2ggcXVlc3Rpb25zOg0KDQoxKSBEbyByZWxpZ2lvdXMgcGVvcGxlIHJlcG9ydCBoaWdoZXIgd2VsbC1iZWluZz8gDQoyKSBEb2VzIHRoZSByZWxhdGlvbiBiZXR3ZWVuIHJlbGlnaW9zaXR5IGFuZCB3ZWxsLWJlaW5nIGRlcGVuZCBvbiBob3cgaW1wb3J0YW50IHBlb3BsZSBjb25zaWRlciByZWxpZ2lvbiB0byBiZSBpbiB0aGVpciBjb3VudHJ5IChpLmUuLCBwZXJjZWl2ZWQgY3VsdHVyYWwgbm9ybXMgb2YgcmVsaWdpb24pPw0KDQojIEJsaW5kZWQgZGF0YQ0KDQpUaGUgcG9pbnQgb2YgYmxpbmRlZCBkYXRhIGlzIHRvIGxldCBhbmFseXN0cyBleHBsb3JlIHRoZSBkYXRhIHdpdGhvdXQgdGhlIGRhbmdlciBvZiBwLWhhY2tpbmcuIFRoZXJlZm9yZSwgb25seSB0aGUgcmVsYXRpb25zaGlwIG9mIHRoZSBvdXRjb21lcyBhbmQgcHJlZGN0b3IgdmFyaWFibGVzIGFyZSBkZXN0cm95ZWQgYnkgc2h1ZmZsaW5nLCBhbmQgdGhlIHJlbWFpbmRlciBpcyBrZXB0IGludGFjdC4gDQpUaGlzIG1lYW5zIHRoYXQ6IA0KDQotIERhdGEgcmVkdWN0aW9uIHRlY2hpbnF1ZXMgKFBDQSwgRUZBKSB3aWxsIHlpZWxkIHZhbGlkIHJlc3VsdHMuDQotIE91dGllcnMsIG1pc3NpbmcgZGF0YSBjYW4gYmUgb2JzZXJ2ZWQgYW5kIHRyZWF0ZWQuDQotIENvbmZvdW5kZXJzIGNhbiBiZSBleHBsb3JlZCwgbWVhbmluZyB0aGF0IG5vdCBvbmx5IHVuaXZhcmlhdGUgZGlzdHJpYnV0aW9ucyBidXQgY29ycmVsYXRpb25zIGFyZSBhbHNvIGtlcHQgaW50YWN0Lg0KLSBDb3VudHJ5IGxldmVsIG1lYW5zIHNob3VsZCByZW1haW4gaW50YWN0DQoNCiMjIEFuYWx5c2lzIGlzc3VlcyB0byByZXNvbHZlDQoNCkluIG9yZGVyIHRvIGJlc3QgYWRkcmVzcyB0aGUgaHlwb3RoZXNlcywgd2UgbmVlZCB0byBkZWNpZGUgYSBmZXcgdGhpbmdzLiANCg0KLSBPcGVyYXRpb25hbGl6YXRpb24gb2YgdmFyaWFibGVzOiBIb3cgc2hvdWxkIHdlIGNvbmNlcHR1YWxpemUga2V5IHZhcmlhYmxlcz8NCi0gT3V0bGllcnMgaG93IHNob3VsZCB3ZSBoYW5kbGUgdGhlbT8NCi0gQ2hvb3NlIHN0YXRpc3RpY2FsIG1vZGVsIChtdWx0aWxldmVsPykNCiAgLSBDb25mb3VuZGVycyAod2hpY2ggb25lcyB0byB1c2U/KQ0KICAtIE1vZGVyYXRvcnMgDQogIC0gTHVtcGluZyBsZXZlbHMgZm9yIG5vbWluYWwgdmFyaWFibGVzDQoNCiMgUmVhZCBhbmQgcHJlLXByb2Nlc3MgZGF0YQ0KDQpBdCB0aGlzIHBvaW50LCB3ZSBvbmx5IGV4Y2x1ZGUgcGFydGljaXBhbnRzIHdobyBkaWQgbm90IHBhc3MgdGhlIGF0dGVudGlvbiBjaGVjay4gDQoNCmBgYHtyfQ0KIyBSZWFkIHJhdyBkYXRhDQptYXJwX3JhdyA8LSANCiAgIyByZWFkX2NzdihoZXJlOjpoZXJlKCJkYXRhL01BUlBfZGF0YV9ibGluZGVkLmNzdiIpKQ0KICByZWFkX2NzdihoZXJlOjpoZXJlKCJkYXRhL01BUlBfZGF0YS5jc3YiKSkNCg0KbWFycF9wcm9jIDwtDQogIG1hcnBfcmF3ICU+JSANCiAgZmlsdGVyKGF0dGVudGlvbl9jaGVjayA9PSAxKSAlPiUgDQogIG11dGF0ZSggZ2VuZGVyID0gcmVjb2RlKGdlbmRlciwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICJtYW4iID0gIk1hbGUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIndvbWFuIiA9ICJGZW1hbGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAib3RoZXIiID0gIk90aGVyIikpDQoNCmBgYA0KDQoNCiMgRGVzY3JpcHRpdmVzIGFuZCBwb3RlbnRpYWwgbW9kZXJhdG9ycw0KDQpgYGB7cn0NCm1hcnBfcHJvYyAlPiUgDQogICAgICAgIHNlbGVjdChjb3VudHJ5LCANCiAgICAgICAgICAgICAgIGdlbmRlciwgc2VzLCBlZHVjYXRpb24sIGV0aG5pY2l0eSwgZGVub21pbmF0aW9uLA0KICAgICAgICAgICAgICAgc2FtcGxlX3R5cGUsIGNvbXBlbnNhdGlvbiwgDQogICAgICAgICAgICAgICBlbmRzX3dpdGgoIl9tZWFuIikpICU+JSANCiAgICAgICAgc2tpbSgpDQpgYGANCg0KIyMgRGVtb2dyYXBoaWNzIGJ5IGNvdW50cnkgey50YWJzZXR9DQoNCiMjIyBOIG9mIHBhcnRpY2lwYW50cw0KDQpgYGB7cn0NCm1hcnBfcHJvYyAlPiUgDQogICAgICAgIG11dGF0ZShjb3VudHJ5ID0gZmN0X2luZnJlcShjb3VudHJ5KSAlPiUgZmN0X3JldigpKSAlPiUgDQogICAgICAgIGdncGxvdCgpICsNCiAgICAgICAgYWVzKHkgPSBjb3VudHJ5KSArDQogICAgICAgIGdlb21fYmFyKCkgKw0KICAgICAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDE1MDAsIDI1MCkpICsNCiAgICAgICAgbGFicyh0aXRsZSA9ICJOdW1iZXIgb2YgcGFydGljaXBhbnRzIGJ5IGNvdW50cnkiLA0KICAgICAgICAgICAgIHkgPSBOVUxMKQ0KDQpgYGANCg0KIyMjIEFnZQ0KDQpBZ2UgaGFzIGEgZmV3IG9idmlvdXMgb3V0bGllcnMgKGUuZy4gYWdlIG9mIDAgb3IgMSksIHRoYXQgd2UgY291bGQgcmVtb3ZlLiBIb3dldmVyLCB0aGUgc2FtcGxlIHNpemUgbWFrZXMgaXQgdW5saWtlbHkgdGhhdCB0aGVzZSBvdXRsaWVycyBoYXZlIGEgbGFyZ2UgaW5mbHVlbmNlIG9uIHRoZSBtb2RlbCwgdGhlcmVmb3JlIHdlIHdvbid0IHJlbW92ZSB0aGVtLg0KDQpgYGB7cn0NCm1hcnBfcHJvYyAlPiUgDQogIGRyb3BfbmEoYWdlKSAlPiUgDQogIG11dGF0ZShjb3VudHJ5ID0gZmN0X3Jlb3JkZXIoY291bnRyeSwgYWdlKSkgJT4lDQogIGdncGxvdCgpICsNCiAgYWVzKHkgPSBjb3VudHJ5LCB4ID0gYWdlLCBmaWxsID0gY291bnRyeSkgKw0KICBnZW9tX2JveHBsb3QoYWxwaGEgPSAuNSwgd2lkdGggPSAuMiwgDQogICAgICAgICAgICAgICBvdXRsaWVyLmFscGhhID0gLjIsIHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgZ2VvbV9kZW5zaXR5X3JpZGdlcyhhbHBoYSA9IC41LCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGxhYnModGl0bGUgPSAiQWdlIGRpc3RyaWJ1dGlvbiBieSBjb3VudHJ5IiwNCiAgICAgICB5ID0gTlVMTCkNCg0KYGBgDQoNCg0KIyMjIEdlbmRlcg0KDQpgYGB7cn0NCm1hcnBfcHJvYyAlPiUgDQogICAgICAgIGdyb3VwX2J5KGNvdW50cnkpICU+JSANCiAgICAgICAgc3VtbWFyaXNlKHBjdF9mZW1hbGUgPSBtZWFuKGdlbmRlciA9PSAiRmVtYWxlIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybSA9IFRSVUUpKSAlPiUgDQogICAgICAgIG11dGF0ZShjb3VudHJ5ID0gZmN0X3Jlb3JkZXIoY291bnRyeSwgcGN0X2ZlbWFsZSkpICU+JQ0KICAgICAgICBnZ3Bsb3QoKSArDQogICAgICAgIGFlcyh5ID0gY291bnRyeSwgeCA9IHBjdF9mZW1hbGUpICsNCiAgICAgICAgZ2VvbV9wb2ludCgpICsNCiAgICAgICAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwxKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSkgKw0KICAgICAgICBsYWJzKHRpdGxlID0gIlByb3BvcnRpb24gb2YgZmVtYWxlcyBieSBjb3VudHJ5IiwNCiAgICAgICAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwpDQpgYGANCg0KIyMjIEVkdWNhdGlvbg0KDQpFZHVjYXRpb24gaXMgYSBjb21tb24gY29uZm91bmRlciB3aGVuIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiByZWxpZ2lvc2l0eSBhbmQgd2VsbC1iZWluZyBpcyBjb25zaWRlcmVkLiBUaGVyZSBpcyBhIGNvbnNpZGVyYWJsZSBzcHJlYWQgb2YgZWR1Y2F0aW9uIHdpdGhpbiBhbmQgYmV0d2VlbiBjb3VudHJpZXMuDQoNCmBgYHtyfQ0KbWFycF9wcm9jICU+JSANCiAgbXV0YXRlKGNvdW50cnkgPSBmY3RfcmVvcmRlcihjb3VudHJ5LCBlZHVjYXRpb24sIG1lZGlhbikpICU+JQ0KICBnZ3Bsb3QoKSArDQogIGFlcyh5ID0gY291bnRyeSwgeCA9IGVkdWNhdGlvbiwgZmlsbCA9IGNvdW50cnkpICsNCiAgZ2VvbV9kZW5zaXR5X3JpZGdlcyhzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGxhYnModGl0bGUgPSAiRWR1Y2F0aW9uIGJ5IGNvdW50cnkiLA0KICAgICAgIHkgPSBOVUxMLCB4ID0gTlVMTCkNCmBgYA0KDQojIyMgU0VTDQoNClNvY2lvLWVjb25vbWljIHN0YXR1cyBpcyBhIGNvbW1vbiBjb25mb3VuZGVyIHdoZW4gdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHJlbGlnaW9zaXR5IGFuZCB3ZWxsLWJlaW5nIGlzIGNvbnNpZGVyZWQuIFRoZXJlIGlzIGEgY29uc2lkZXJhYmxlIHNwcmVhZCBvZiBTRVMgd2l0aGluIGFuZCBiZXR3ZWVuIGNvdW50cmllcy4NCg0KYGBge3J9DQptYXJwX3Byb2MgJT4lIA0KICBkcm9wX25hKHNlcykgJT4lIA0KICBtdXRhdGUoY291bnRyeSA9IGZjdF9yZW9yZGVyKGNvdW50cnksIHNlcykpICU+JQ0KICBnZ3Bsb3QoKSArDQogIGFlcyh5ID0gY291bnRyeSwgeCA9IHNlcywgZmlsbCA9IGNvdW50cnkpICsNCiAgZ2VvbV9kZW5zaXR5X3JpZGdlcyhzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGxhYnModGl0bGUgPSAiU29jaW8tZWNvbm9taWMgc3RhdHVzIGJ5IGNvdW50cnkiLA0KICAgICAgIHkgPSBOVUxMLCB4ID0gTlVMTCkNCmBgYA0KDQojIyMgRGVub21pbmF0aW9uDQoNClJlbGlnaW91cyBkZW5vbWluYXRpb24gaXMgb2Z0ZW4gdXNlZCB3aGVuIHRoZSBjb25uZWN0aW9uIGJldHdlZW4gcmVsaWdpb3NpdHkgYW5kIHdlbGwgYmVpbmcgaXMgY29uc2lkZXJlZC4gDQoNCmBgYHtyfQ0KbWFycF9wcm9jICU+JSANCiAgbXV0YXRlKGNvdW50cnkgPSBmY3RfaW5mcmVxKGNvdW50cnkpICU+JSBmY3RfcmV2KCkpICU+JQ0KICBjb3VudChjb3VudHJ5LCBkZW5vbWluYXRpb24pICU+JQ0KICBnZ3Bsb3QoKSArDQogIGFlcyh5ID0gY291bnRyeSwgeCA9IG4sIGZpbGwgPSBkZW5vbWluYXRpb24pICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAic3RhY2siKSArDQogIGxhYnModGl0bGUgPSAiTnVtYmVyL1Byb3BvcnRpb24gb2YgZGVub21pbmF0aW9ucyBieSBjb3VudHJ5IiwNCiAgICAgICB5ID0gTlVMTCwNCiAgICAgICBmaWxsID0gIkRlbm9taW5hdGlvbiIpDQpgYGANCg0KSG93ZXZlciwgaW4gaXRzIGN1cnJlbnQgZm9ybSwgdGhlIHZhcmlhYmxlIGNvbnRhaW5zIGNhdGVnb3JpZXMgdGhhdCBhcmUgcmF0dGhlciBzcGFyc2UsIGFuZCB0aGlzIG1heSBpbnRlcmZlcmUgd2l0aCB0aGUgc3RhdGlzdGljYWwgbW9kZWwgdGhhdCB3ZSB3YW50IHRvIHVzZS4gVGhlcmVmb3JlIHdlIGNob29zZSB0byBsdW1wIHRvZ2V0aGVyIGxldmVscyB0aGF0IGNvbnN0aXR1dGUgbGVzcyB0aGFuIDElIG9mIHRoZSBjYXRlZ29yaWVzIGludG8gIk90aGVyIi4NCg0KYGBge3J9DQpsdW1wZWRfZGVub20gPC0NCiAgbWFycF9wcm9jICU+JSANCiAgdHJhbnNtdXRlKHN1YmplY3QsIA0KICAgICAgICAgICAgZGVub21fbHVtcCA9IGNhc2Vfd2hlbihzdHJfZGV0ZWN0KGRlbm9taW5hdGlvbiwgIk11c2xpbSIpIH4gIk11c2xpbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cl9kZXRlY3QoZGVub21pbmF0aW9uLCAiQ2hyaXN0aWFufEV2YW5nZWxpY2FsIikgfiAiQ2hyaXN0aWFuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyX2RldGVjdChkZW5vbWluYXRpb24sICJPdGhlciIpIH4gIk90aGVyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMubmEoZGVub21pbmF0aW9uKSB+ICJObyBkZW5vbWluYXRpb24iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gZGVub21pbmF0aW9uKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGZjdF9sdW1wX3Byb3AoLjAxLCBvdGhlcl9sZXZlbCA9ICJPdGhlciIpKQ0KDQptYXJwX3Byb2MgJT4lIA0KICBsZWZ0X2pvaW4obHVtcGVkX2Rlbm9tLCBieSA9ICJzdWJqZWN0IikgJT4lIA0KICBtdXRhdGUoY291bnRyeSA9IGZjdF9pbmZyZXEoY291bnRyeSkgJT4lIGZjdF9yZXYoKSkgJT4lDQogIGNvdW50KGNvdW50cnksIGRlbm9tX2x1bXApICU+JQ0KICBnZ3Bsb3QoKSArDQogIGFlcyh5ID0gY291bnRyeSwgeCA9IG4sIGZpbGwgPSBkZW5vbV9sdW1wLCBsYWJlbCA9IGRlbm9tX2x1bXApICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAic3RhY2siKSArDQogIGxhYnModGl0bGUgPSAiTnVtYmVyL1Byb3BvcnRpb24gb2YgZGVub21pbmF0aW9ucyBieSBjb3VudHJ5IiwNCiAgICAgICBzdWJ0aXRsZSA9ICJEZW5vbWluYXRpb25zIHRoYXQgd2VyZSBpbmZyZXF1ZW50ICg8MSUpIHdlcmUgbHVtcGVkIHRvZ2V0aGVyIiwNCiAgICAgICB5ID0gTlVMTCwNCiAgICAgICBmaWxsID0gIkRlbm9taW5hdGlvbiIpDQoNCmBgYA0KDQoNCiMjIyBFdGhuaWNpdHkNCg0KV2VsbC1iZWluZyBtaWdodCBiZSBpbmZsdWVuY2VkIGJ5IGV0aGljaXR5LCBidXQgbm90IGRpcmVjdGx5LiBGb3IgZS5nLiBtaW5vcml0eSBzdGF0dXMgbWlnaHQgYmUgYXNzb2NpYXRlZCB3aXRoIFdCLCBidXQgdGhlcmUgd2VyZSBubyBxdWVzdGlvbnMgYWJvdXQgdGhpcy4gVGhlcmVmb3JlLCBpbiBteSBvcGluaW9uLCByYXcgZXRobmljaXR5IHNob3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIG1vZGVsLg0KDQpgYGB7cn0NCm1hcnBfcHJvYyAlPiUgDQogIG11dGF0ZShldGhuaWNpdHkgPSBmY3RfaW5mcmVxKGV0aG5pY2l0eSkgJT4lIGZjdF9yZXYoKSkgJT4lIA0KICBnZ3Bsb3QoKSArDQogIGFlcyh5ID0gZXRobmljaXR5LCBmaWxsID0gZXRobmljaXR5KSArDQogIGdlb21fYmFyKHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgbGFicyh5ID0gTlVMTCkNCmBgYA0KDQoNCiMjIyBJbXBvcnRhbmNlIG9mIHJlbGlnaW9uDQpgYGB7cn0NCmNub3JtX3F1ZXN0aW9ucyA8LSANCiAgdGliYmxlKG5hbWUgPSBjKCJjbm9ybV8xIiwgImNub3JtXzIiKSwNCiAgICAgICAgIHF1ZXN0aW9uID0gYygiSW1wb3J0YW5jZSBvZiByZWxpZ2lvdXMgbGlmZXN0eWxlIGZvciBhdmVyYWdlIHBlcnNvbiBpbiBjb3VudHJ5IiwNCiAgICAgICAgICAgICAgICAgICAgICAiSW1wb3J0YW5jZSBvZiBiZWxpZWYgaW4gR29kL0dvZHMgZm9yIGF2ZXJhZ2UgcGVyc29uIGluIGNvdW50cnkiDQogICAgICAgICAgICAgICAgICAgICkpDQoNCm1hcnBfcHJvYyAlPiUgDQogIHNlbGVjdChzdWJqZWN0LCBjb3VudHJ5LCBjbm9ybV8xLCBjbm9ybV8yKSAlPiUgDQogIHBpdm90X2xvbmdlcihjKCJjbm9ybV8xIiwgImNub3JtXzIiKSkgJT4lIA0KICBncm91cF9ieShjb3VudHJ5LCBuYW1lKSAlPiUgDQogIHN1bW1hcmlzZShhdmcgPSBtZWFuKHZhbHVlKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBsZWZ0X2pvaW4oY25vcm1fcXVlc3Rpb25zLCBieSA9ICJuYW1lIikgJT4lDQogIG11dGF0ZShjb3VudHJ5ID0gcmVvcmRlcl93aXRoaW4oY291bnRyeSwgYXZnLCBxdWVzdGlvbikpICU+JSANCiAgZ2dwbG90KCkgKw0KICBhZXMoeCA9IGF2ZywgeSA9IGNvdW50cnkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgc2NhbGVfeV9yZW9yZGVyZWQoTlVMTCkgKw0KICBmYWNldF93cmFwKH5xdWVzdGlvbiwgbmNvbCA9IDIsIHNjYWxlcyA9ICJmcmVlX3kiKSArDQogIGxhYnModGl0bGUgPSAiTm9ybWF0aXZpdHkgb2YgcmVsaWdpb24gYnkgY291bnRyeSBpbiB0d28gcXVlc3Rpb25zIikgIA0KICANCmBgYA0KDQoNCiMjIyBHRFAgcGVyIGNhcGl0YQ0KYGBge3J9DQptYXJwX3Byb2MgJT4lIA0KICBncm91cF9ieShjb3VudHJ5KSAlPiUgDQogIHN1bW1hcmlzZShnZHAgPSBtZWFuKGdkcCkpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgbXV0YXRlKGNvdW50cnkgPSBmY3RfcmVvcmRlcihjb3VudHJ5LCBnZHApKSAlPiUgDQogIGdncGxvdCgpICsNCiAgYWVzKHggPSBnZHAsIHkgPSBjb3VudHJ5KSArDQogIGdlb21fcG9pbnQoKSArDQogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmRvbGxhcl9mb3JtYXQoKSkgKw0KICBsYWJzKHRpdGxlID0gIkdEUCBwZXIgY2FwaXRhIGJ5IGNvdW50cnkiKSAgDQoNCg0KYGBgDQoNCiMjIyBTYW1wbGUgdHlwZQ0KDQpgYGB7cn0NCm1hcnBfcHJvYyAlPiUgDQogIG11dGF0ZShjb3VudHJ5ID0gZmN0X2luZnJlcShjb3VudHJ5KSAlPiUgZmN0X3JldigpKSAlPiUNCiAgY291bnQoY291bnRyeSwgc2FtcGxlX3R5cGUpICU+JSANCiAgZ2dwbG90KCkgKw0KICBhZXMoeSA9IGNvdW50cnksIHggPSBuLCBmaWxsID0gc2FtcGxlX3R5cGUpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAic3RhY2siKSArDQogIGxhYnModGl0bGUgPSAiUHJvcG9ydGlvbiBvZiBzYW1wbGUgdHlwZSBieSBjb3VudHJ5IiwNCiAgICAgICB4ID0gTlVMTCwgeSA9IE5VTEwsIGZpbGwgPSAiU2FtcGxlIHR5cGUiKQ0KYGBgDQoNCiMjIyBDb21wZW5zYXRpb24NCg0KQ29tcGVuc2F0aW9uIGlzIHZlcnkgY2xvc2VseSBhc3NvY2lhdGVkIHdpdGggdGhlIHNhbXBsZSB0eXBlLCB0aGVyZWZvcmUgdXNpbmcgaXQgaW4gdGhlIG1vZGVsIHdvdWxkIGJlIHJlZHVuZGFudC4NCg0KYGBge3J9DQptYXJwX3Byb2MgJT4lIA0KICBtdXRhdGUoY291bnRyeSA9IGZjdF9pbmZyZXEoY291bnRyeSkgJT4lIGZjdF9yZXYoKSkgJT4lDQogIGNvdW50KGNvdW50cnksIGNvbXBlbnNhdGlvbikgJT4lIA0KICBnZ3Bsb3QoKSArDQogIGFlcyh5ID0gY291bnRyeSwgeCA9IG4sIGZpbGwgPSBjb21wZW5zYXRpb24pICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAic3RhY2siKSArDQogIGxhYnModGl0bGUgPSAiUHJvcG9ydGlvbiBvZiBjb21wZW5zYXRpb24gYnkgY291bnRyeSIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMLCBmaWxsID0gIkNvbXBlbnNhdGlvbiIpDQpgYGANCg0KIyBPcGVyYXRpb25hbGl6YXRpb24gb2YgdmFyaWFibGVzIHsudGFic2V0fQ0KDQoqUmVsaWdpb3NpdHkqIGFuZCAqd2VsbC1iZWluZyogaGFzIG11bHRpcGxlIGl0ZW1zIHRoYXQgd2UgY2FuIHVzZS4gQWNjb3JkaW5nIHRvIHByZXZpb3VzIHN0dWRpZXMgb2Ygc2ltaWxhciB0b3BpY3MsICpub3JtcyBhYm91dCByZWxpZ2lvbiogc2hvdWxkIGJlIGFnZ3JlZ2F0ZWQgdG8gdGhlIGNvdW50cnkgbGV2ZWwuDQoNCiMjIFJlbGlnaW9zaXR5DQoNCkFsdGhvdWdoIHJlbGlnaW9zaXR5IGlzIGFuIGVsdXNpdmUgY29uY2VwdCwgYW5kIG5vIG9uZS1zaXplLWZpdHMtYWxsIG1ldHJpYyBpcyBhdmFpbGFibGUuIFdlIGRvbid0IGZlZWwgY29tcGV0ZW50IHRvIGNob29zZSBqdXN0IG9uZSBxdWVzdGlvbiwgc28gV2UgdHJ5IHRvIHVzZSBhcyBtdWNoIGluZm9ybWF0aW9uIGZyb20gYWxsIGF2YWlsYWJsZSBxdWVzdGlvbnMgYXMgcG9zc2libGUuIEknbSBhbHNvIG5vdCBmZWVsaW5nIGNvbmZpZGVudCB0byByZWxldmVsIHNwZWNpZmljIHF1ZXN0aW9ucyAoZS5nLiByZWxfMykuIFRoZXJlZm9yZSwgV2UgY2hvb3NlIHRvIHVzZSBQQ0EgdG8gZXh0cmFjdCBhbiBhZ2dyZWdhdGVkIHZhcmlhYmxlLg0KDQpgYGB7cn0NCm1hcnBfcHJvYyAlPiUgDQogIHNlbGVjdChzdGFydHNfd2l0aCgicmVsXyIpKSAlPiUgDQogIHBpdm90X2xvbmdlcihldmVyeXRoaW5nKCkpICU+JSANCiAgZ2dwbG90KGFlcyh2YWx1ZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oKSArDQogIGZhY2V0X3dyYXAofm5hbWUpICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgcmVsXyB2YXJpYWJsZXMgdG8gYmUgdXNlZCBpbiBQQ0EiKQ0KDQpgYGANCg0KYGBge3J9DQojIE51bWJlciBvZiBjb21wb25lbnRzDQptYXJwX3Byb2MgJT4lIA0KICAgICAgICBzZWxlY3Qoc3RhcnRzX3dpdGgoInJlbF8iKSkgJT4lIA0KICAgICAgICBmYS5wYXJhbGxlbCgpDQoNCiMgUGFyYWxsZWwgYW5hbHlzaXMgc3VnZ2VzdHMgdG8gdXNlIGEgc2luZ2xlIGNvbXBvbmVudC4NCnJlbF9wY2EgPC0NCiAgICAgICAgbWFycF9wcm9jICU+JSANCiAgICAgICAgc2VsZWN0KHN0YXJ0c193aXRoKCJyZWxfIikpICU+JSANCiAgICAgICAgcGNhKG5mYWN0b3JzID0gMSkNCg0KIyBDb3JyZWxhdGlvbiBvZiByZWxpZ2lvc2l0eSBpdGVtcyBhbmQgdGhlIFBDQSBjb21wb25lbnQNCm1hcnBfcHJvYyAlPiUgDQogIHNlbGVjdChzdGFydHNfd2l0aCgicmVsIikpICU+JSANCiAgbXV0YXRlKHJlbF9wY2EgPSByZWxfcGNhJHNjb3Jlc1ssMV0pICU+JSANCiAgY29yLnBsb3QoKQ0KDQpgYGANCg0KVGhlIHJlbGlnaW9zaXR5IHZhbHVlcyBzZWVtcyB0byB2YXJ5IGNvbnNpZGVyYWJseSBieSBjb3VudHJ5Lg0KDQpgYGB7cn0NCiAgbWFycF9wcm9jICU+JQ0KICBtdXRhdGUocmVsX3BjYSA9IHJlbF9wY2Ekc2NvcmVzWywxXSkgJT4lIA0KICBtdXRhdGUoY291bnRyeSA9IGZjdF9yZW9yZGVyKGNvdW50cnksIHJlbF9wY2EsIG1lZGlhbikpICU+JQ0KICBnZ3Bsb3QoKSArDQogIGFlcyh5ID0gY291bnRyeSwgeCA9IHJlbF9wY2EsIGZpbGwgPSBjb3VudHJ5KSArDQogIGdlb21fYm94cGxvdChvdXRsaWVyLmFscGhhID0gLjIsIHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgbGFicyh0aXRsZSA9ICJSZWxpZ2lvc2l0eSBieSBjb3VudHJ5IiwNCiAgICAgICBzdWJ0aXRsZSA9ICJBZ2dyZWdhdGVkIHJlbGlnaW9zaXR5IGNvbXBvbmVudCIsDQogICAgICAgeCA9IE5VTEwsDQogICAgICAgeSA9IE5VTEwpDQpgYGANCg0KDQoNCmBgYHtyfQ0KbWFycF9wcm9jICU+JQ0KICBiaW5kX2NvbHMocmVsX3BjYSA9IHJlbF9wY2Ekc2NvcmVzWywxXSkgJT4lIA0KICBsZWZ0X2pvaW4obHVtcGVkX2Rlbm9tLCBieSA9ICJzdWJqZWN0IikgJT4lIA0KICBtdXRhdGUoZGVub21fbHVtcCA9IGZjdF9yZW9yZGVyKGRlbm9tX2x1bXAsIHJlbF9wY2EsIG1lZGlhbikpICU+JQ0KICBnZ3Bsb3QoKSArDQogIGFlcyh5ID0gZGVub21fbHVtcCwgeCA9IHJlbF9wY2EsIGZpbGwgPSBkZW5vbV9sdW1wKSArDQogIGdlb21fYm94cGxvdChhbHBoYSA9IC41LA0KICAgICAgICAgICAgICAgd2lkdGggPSAuMiwNCiAgICAgICAgICAgICAgIG91dGxpZXIuYWxwaGEgPSAuMiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBnZW9tX2RlbnNpdHlfcmlkZ2VzKGFscGhhID0gLjUpICsNCiAgbGFicyh0aXRsZSA9ICJSZWxpZ2lvc2l0eSBieSBkZW5vbWluYXRpb24iLA0KICAgICAgIHN1YnRpdGxlID0gIkFnZ3JlZ2F0ZWQgcmVsaWdpb3NpdHkgY29tcG9uZW50IiwNCiAgICAgICBmaWxsID0gIkRlbm9taW5hdGlvbiIsDQogICAgICAgeCA9IE5VTEwsDQogICAgICAgeSA9IE5VTEwpDQpgYGANCg0KV2UgY29tcGFyZWQgdGhlIFBDQSBvcGVyYXRpb25hbGl6YXRpb24gd2l0aCB0aGUgc2VsZi1hZG1pdHRlZCBzaW5nbGUgaXRlbSByZWxpZ2lvc2l0eS4gVGhlIGRpZmZlcmVuY2Ugb24gdGhlIGNvdW50cnkgbGV2ZWwgc2VlbXMgcXVpdGUgc3VidGxlLg0KDQpgYGB7cn0NCm1hcnBfcHJvYyAlPiUgDQogIG11dGF0ZShyZWxfcGNhID0gcmVsX3BjYSRzY29yZXNbLDFdKSAlPiUgDQogIGdyb3VwX2J5KGNvdW50cnkpICU+JSANCiAgc3VtbWFyaXNlKHJlbF9pdGVtID0gbWVhbihyZWxfMyA9PSAxKSwNCiAgICAgICAgICAgICAgICAgIHJlbF9wY2EgPSBtZWFuKHJlbF9wY2EpLA0KICAgICAgICAgICAgICAgICAgbiA9IG4oKSkgJT4lIA0KICBtdXRhdGUoYWNyb3NzKHN0YXJ0c193aXRoKCJyZWxfIiksIH5zY2FsZSgueCkgJT4lIGFzLm51bWVyaWMoKSkpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKCJyZWxfaXRlbSIsICJyZWxfcGNhIikpICU+JSANCiAgbXV0YXRlKGNvdW50cnkgPSBmY3RfcmVvcmRlcihjb3VudHJ5LCB2YWx1ZSkpICU+JSANCiAgZ2dwbG90KCkgKw0KICBhZXMoeCA9IHZhbHVlLCB5ID0gY291bnRyeSwgY29sb3IgPSBuYW1lKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsNCiAgbGFicyh0aXRsZSA9ICJEaWZmZXJlbnQgb3BlcmF0aW9uYWxpemF0aW9ucyBvZiByZWxpZ2lvc2l0eSBsZWFkIHRvIHNpbWlsYXIgY291bnRyeS13aXNlIHZhbHVlcyAociA9IC45MSkiLA0KICAgICAgIHN1YnRpdGxlID0gIk9uZSBpdGVtIHJlbGlnaW9zaXR5IChyZWxfMykgdnMuIDktaXRlbSBQQ0EgcmVsaWdpb3NpdHkgY29tcG9uZW50IChyZWxfcGNhKSB2YWx1ZXMiLA0KICAgICAgIHkgPSBOVUxMLCB4ID0gTlVMTCwgY29sb3IgPSAiT3BlcmF0aW9uYWxpemF0aW9uIikNCmBgYA0KDQoNCg0KIyMgV2VsbC1iZWluZw0KDQpUaGUgd2VsbC1iZWluZyBxdWVzdGlvbnMgaGF2ZSBjYWxjdWxhdGVkIHZhbHVlcyBmb3Igc3Vic2NhbGVzIGFuZCBvdmVyYWxsIA0KDQpgYGB7cn0NCm1hcnBfcHJvYyAlPiUgDQogIHNlbGVjdChzdGFydHNfd2l0aCgid2IiKSkgJT4lIA0KICBjb3IucGxvdCgpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KbWFycF9wcm9jICU+JSANCiAgbXV0YXRlKGNvdW50cnkgPSBmY3RfcmVvcmRlcihjb3VudHJ5LCB3Yl9vdmVyYWxsX21lYW4pKSAlPiUgDQogIGdncGxvdCgpICsNCiAgYWVzKHggPSB3Yl9vdmVyYWxsX21lYW4sIHkgPSBjb3VudHJ5LCBmaWxsID0gY291bnRyeSkgKw0KICBnZW9tX2JveHBsb3QoYWxwaGEgPSAuNSwNCiAgICAgICAgICAgd2lkdGggPSAuMiwNCiAgICAgICAgICAgb3V0bGllci5hbHBoYSA9IC4yLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGdlb21fZGVuc2l0eV9yaWRnZXMoYWxwaGEgPSAuNSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBsYWJzKHRpdGxlID0gIk92ZXJhbGwgd2VsbC1iZWluZyBieSBjb3VudHJ5IiwNCiAgICAgICB5ID0gTlVMTCkNCg0KYGBgDQoNCiMjIEN1bHR1cmFsIG5vcm1zIGFib3V0IHJlbGlnaW9zaXR5IGludG8gb25lIHZhcmlhYmxlLg0KDQpBY2NvcmRpbmcgdG8gcHJldmlvdXMgcmVzZWFyY2gsIG5vcm1zIHNob3VsZCBiZSBoYW5kbGVkIG9uIHRoZSBjb3VudHJ5IGxldmVsLiANCldlIHVzZSB0aGUgbWVhbiBvZiB0aGUgdHdvIHZhcmlhYmxlcyB0aGF0IGFyZSBvdGhlcndpc2Ugc3Ryb25nbHkgY29ycmVsYXRlZCwgc2luY2UgaXQgbWFrZXMgbm8gc2Vuc2UgdG8gdXNlIGEgbW9yZSBjb21wbGljYXRlZCBtZXRob2QgKFBDQSBvciBFRkEpLiBUaGVuIHdlIGNhbGN1bGF0ZSB0aGUgY291bnRyeSBsZXZlbCBtZWFuIGZyb20gdGhpcyB2YXJpYWJsZS4NCg0KYGBge3J9DQojIENvdW50cnkgbm9ybSBvZiByZWxpZ2lvc2l0eQ0KY291bnRyeV9ub3JtcyA8LQ0KICBtYXJwX3Byb2MgJT4lIA0KICAjIENyZWF0ZSBuZXcgdmFyaWFibGUgd2l0aCB0aGUgYXZlcmFnZSBvZiB0aGUgMiBjbm9ybSB2YWlyYWxiZXMNCiAgbXV0YXRlKGNub3JtX2F2ZyA9ICgoY25vcm1fMSArIGNub3JtXzIpLzIpKSAlPiUgDQogICMgQ2FsY3VsYXRlIGNvdW50cnkgbGV2ZWwgbm9ybXMNCiAgZ3JvdXBfYnkoY291bnRyeSkgJT4lIA0KICBzdW1tYXJpc2UoY25vcm1fbWVhbiA9IG1lYW4oY25vcm1fYXZnKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICAjIFN0YW5kYXJkaXplIHRoZSB2YXJpYWJsZQ0KICBtdXRhdGUoY25vcm1fbWVhbiA9IHNjYWxlKGNub3JtX21lYW4pICU+JSBhcy5udW1lcmljKCkpDQoNCmNvdW50cnlfbm9ybXMgJT4lIA0KICBtdXRhdGUoY291bnRyeSA9IGZjdF9yZW9yZGVyKGNvdW50cnksIGNub3JtX21lYW4pKSAlPiUgDQogIGdncGxvdCgpICsNCiAgYWVzKHkgPSBjb3VudHJ5LCB4ID0gY25vcm1fbWVhbikgKw0KICBnZW9tX3BvaW50KCkgKw0KICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2Ugb2YgY3VsdHVyYWwgbm9ybXMgYWJvdXQgcmVsaWdpb24gYnkgY291bnRyeSIsDQogICAgICAgeCA9IE5VTEwsIHkgPSBOVUxMKQ0KDQpgYGANCg0KDQojIENvbnN0cnVjdCBmaW5hbCBkYXRhc2V0DQoNClVzaW5nIGFsbCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBleHBsb3JhdG9yeSBhbmFseXNpcywgd2UgY3JlYXRlIGEgZGF0YXNldCBmb3IgbW9kZWxpbmcuIFRoaXMgZGF0YXNldCBzdGlsbCBkb2Vzbid0IGNvbnRhaW4gcG90ZW50aWFsIHByb2JsZW1zIHRoYXQgbWF5IGVtZXJnZSBkdXJpbmcgbW9kZWwgZGlhZ25vc3RpY3MuDQoNCldlIGFkZCB0aGUgcmVsaWdpb3NpdHkgY29tcG9uZW50LCB0aGUgY291bnRyeS13aXNlIG5vcm1zLCB0aGUgbHVtcGVkIGRlbm9taW5hdGlvbiBkYXRhLCBhbmQgc2V0IGJhc2VsaW5lcyBmb3IgY2F0ZWdvcmljYWwgdmFyaWFibGVzLg0KV2UgYWxzbyBkcm9wIHBhcnRpY2lwYW50cyB3aXRoIG1pc3NpbmcgdmFsdWVzIGluIHZhcmlibGVzIHRoYXQgd2Ugd2FudCB0byB1c2UgaW4gdGhlIHN0YXRpc3RpY2FsIG1vZGVscywgYXMgdGhvc2UgY2FuIGNhdXNlIGRpZmZpY3VsdGllcyB3aGVuIGNvbXBhcmluZyBtb2RlbHMuIFRoaXMgbWVhbnMgZHJvcHBpbmcgMjUgcGFydGljaXBhbnRzLg0KDQpgYGB7cn0NCm1hcnBfbm9kaWFnIDwtDQogIG1hcnBfcHJvYyAlPiUgDQogICMgQWRkIHJlbGlnaW9zaXR5IHNjb3JlcyBmcm9tIFBDQQ0KICBiaW5kX2NvbHMocmVsaWdpb3NpdHkgPSByZWxfcGNhJHNjb3Jlc1ssMV0pICU+JQ0KICAjIEFkZCBjb3VudHJ5IGxldmVsIG5vcm1zDQogIGxlZnRfam9pbihjb3VudHJ5X25vcm1zLCBieSA9ICJjb3VudHJ5IikgJT4lIA0KICAjIE1lcmdlIGRpZmZlcmVudCBicmFuY2hlcyBvZiB0aGUgc2FtZSByZWxpZ2lvbiwgbHVtcCBsZXZlbHMgPCAxJQ0KICBsZWZ0X2pvaW4obHVtcGVkX2Rlbm9tLCBieSA9ICJzdWJqZWN0IikgJT4lIA0KICAjIFNldCBiYXNlbGluZXMNCiAgbXV0YXRlKHNhbXBsZV90eXBlID0gZmN0X3JlbGV2ZWwoc2FtcGxlX3R5cGUsICJvbmxpbmUgcGFuZWwiKSwNCiAgICAgICAgIGRlbm9tX2x1bXAgPSBmY3RfcmVsZXZlbChkZW5vbV9sdW1wLCAiTm8gZGVub21pbmF0aW9uIiksDQogICAgICAgICBnZW5kZXIgPSBmY3RfcmVsZXZlbChnZW5kZXIsICJGZW1hbGUiKSkgJT4lIA0KICAjIERyb3AgcGFydGljaXBhbnRzIHdpdGggbWlzc2luZyB2YXJpYWJsZXMNCiAgZHJvcF9uYShhZ2UsICBnZW5kZXIsIHNlcywgZWR1Y2F0aW9uLCBkZW5vbV9sdW1wLCBzYW1wbGVfdHlwZSkNCg0KYGBgDQoNCiMgSW52ZXN0aWdhdGluZyBtb2RlbCBhc3N1bXB0aW9ucw0KDQpCZWZvcmUgY3JlYXRpbmcgdGhlIGZpbmFsIGRhdGFzZXQgYW5kIG1vZGVscywgd2UgaW52ZXN0aWdhdGUgaWYgdGhlcmUgaXMgYW55dGhpbmcgc3RyYW5nZSBpbiB0aGUgbW9kZWwgZGlhZ25vc3RpY3MgdGhhdCB3b3VsZCBuZWNlc3NpdGF0ZSBmdXJ0aGVyIGNoYW5nZXMgaW4gdGhlIGRhdGFzZXQuIFRoZXJlZm9yZSB3ZSBjcmVhdGUgYSBtb2RlbCB0aGF0IGNvbnRhaW5zIGFsbCB0aGUgdGVybXMgdGhhdCB3ZSB3YW50IHRvIGluY2x1ZGUgaW4gdGhlIGFuYWx5c2lzLCBhbmQgd2UgY2hlY2sgYWxsIGFzc3VtcHRpb25zLg0KDQpgYGB7cn0NCm1vZGVsX2RpYWcgPC0gDQogIGxtZXIod2Jfb3ZlcmFsbF9tZWFuIH4gcmVsaWdpb3NpdHkgKiBjbm9ybV9tZWFuICsgDQogICAgICAgICAjIHBlcnNvbmFsIGxldmVsIGNvbmZvdW5kZXJzDQogICAgICAgICAgICAgICAgICAgICAgICAgYWdlICsgZ2VuZGVyICsgc2VzICsgZWR1Y2F0aW9uICsgZGVub21fbHVtcCArDQogICAgICAgICAjIGNvdW50cnkgYW5kIHNhbXBsZSBsZXZlbCBjb25mb3VuZGVycw0KICAgICAgICAgICAgICAgICAgICAgICAgIGdkcF9zY2FsZWQgKyBzYW1wbGVfdHlwZSArIA0KICAgICAgICAgIyByYW5kb20gaW50ZXJjZXB0IGFuZCBzbG9wZSBtb2RlbA0KICAgICAgICAgICAgICAgICAgICAgICAgIChyZWxpZ2lvc2l0eXxjb3VudHJ5KSwgZGF0YSA9IG1hcnBfbm9kaWFnKQ0KDQpjaGVja19tb2RlbChtb2RlbF9kaWFnKQ0KYGBgDQoNCk1vZGVsIGRpYWdub3N0aWNzIHNob3c6DQoNCi0gYHIgZW1vOjpqaSgiY2hlY2siKWAgTm8gbXVsdGljb2xsaW5lYXJpdHksIA0KLSBgciBlbW86OmppKCJjaGVjayIpYCBOb3JtYWxseSBkaXN0cmlidXRlZCByZXNpZHVhbHMNCi0gYHIgZW1vOjpqaSgiY2hlY2siKWAgTm8gaW5mbHVlbnRpYWwgY2FzZXMNCi0gYHIgZW1vOjpqaSgiY2hlY2siKWAgTm9ybWFsbHkgZGlzdHJpYnV0ZWQgcmFuZG9tIGVmZmVjdHMNCi0gYHIgZW1vOjpqaSgieCIpYCBIb21vc2tlZGFzdGljaXR5DQoNCkFwYXJ0IGZyb20gaGV0ZXJvc2NlZGFzdGljaXR5LCBpdCBzZWVtcyBsaWtlIHRoZXJlIGlzIGEgc3RyYW5nZSBzZXBhcmF0aW9uIGluIHRoZSBmaXR0ZWQgdmFsdWVzLiBBbGwgcmVzaWR1YWxzIG9uIHRoZSBsZWZ0IGhhbmQgc2lkZSBjb21lIGZyb20gdGhlIEphcGFuZXNlIHNhbXBsZS4gQXMgdGhlIHNlcGFyYXRpb24gaXMgY29tcGxldGUgYW5kIHRoZSBkaWZmZXJlbmNlIGlzIGh1Z2UsIHdlIHNob3VsZCBoYW5kbGUgdGhlIEphcGFuZXNlIGRhdGEgd2l0aCBleHRyYSBjYXJlLiBGdXJ0aGVyLCB0aGVyZSBpcyB2ZXJ5IHNtYWxsIHZhcmlhYmlsaXR5IGluIHRoZSBKYXBhbmVzZSBmaXR0ZWQgdmFsdWVzLiAgDQpUYWtlbiB0b2dldGhlciwgd2UgZGVjaWRlZCB0byByZW1vdmUgdGhlIEphcGFuZXNlIGRhdGEuDQoNCmBgYHtyfQ0KYXVnbWVudChtb2RlbF9kaWFnKSAlPiUgDQogIG11dGF0ZShjb3VudHJ5ID0gZmN0X3Jlb3JkZXIoY291bnRyeSwgLmZpdHRlZCkpICU+JSANCiAgZ2dwbG90KCkgKw0KICBhZXMoeCA9IC5maXR0ZWQsIHkgPSBjb3VudHJ5LCBmaWxsID0gY291bnRyeSkgKw0KICBnZW9tX2JveHBsb3Qoc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBsYWJzKHRpdGxlID0gIlRoZSBmaXR0ZWQgSmFwYW5lc2UgdmFsdWVzIGFyZSBtdWNoIGxvd2VyIHRoYW4gZm9yIGFueSBvdGhlciBjb3VudHJ5IiwNCiAgICAgICB5ID0gTlVMTCkNCg0KYGBgDQoNCiMgQ29ycmVjdGluZyB0aGUgZmluYWwgZGF0YXNldA0KDQpJbiB0aGUgZmluYWwgZGF0YXNldCB3ZSByZW1vdmUgdGhlIEphcGFuZXNlIGFuc3dlcnMuDQoNCmBgYHtyfQ0KbWFycCA8LSANCiAgbWFycF9ub2RpYWcgJT4lIA0KICBmaWx0ZXIoY291bnRyeSAhPSAiSmFwYW4iKQ0KYGBgDQoNCiMgQnVpbGRpbmcgbW9kZWxzDQojIyAxKSBEbyByZWxpZ2lvdXMgcGVvcGxlIHJlcG9ydCBoaWdoZXIgd2VsbC1iZWluZz8gDQoNCmBgYHtyfQ0KaDEgPC0gDQogIGxtZXIod2Jfb3ZlcmFsbF9tZWFuIH4gcmVsaWdpb3NpdHkgKyANCiAgICAgICAgICMgcGVyc29uYWwgbGV2ZWwgY29uZm91bmRlcnMNCiAgICAgICAgICAgICAgICAgICAgICAgICBhZ2UgKyBnZW5kZXIgKyBzZXMgKyBlZHVjYXRpb24gKyBkZW5vbV9sdW1wICsNCiAgICAgICAgICMgY291bnRyeSBhbmQgc2FtcGxlIGxldmVsIGNvbmZvdW5kZXJzDQogICAgICAgICAgICAgICAgICAgICAgICAgZ2RwX3NjYWxlZCArIHNhbXBsZV90eXBlICsNCiAgICAgICAgICMgcmFuZG9tIGludGVyY2VwdCBhbmQgc2xvcGUgbW9kZWwNCiAgICAgICAgICAgICAgICAgICAgICAgICAocmVsaWdpb3NpdHl8Y291bnRyeSksIA0KICAgICAgIGRhdGEgPSBtYXJwKQ0KDQojIENyZWF0ZSBhIG51bGwgbW9kZWwgZm9yIGNvbXBhcmlzb25zIHRoYXQgZG9lcyBub3QgY29udGFpbiB0aGUgbWFpbiBwcmVkaWN0b3INCmgwIDwtIHVwZGF0ZShoMSwgLiB+IC4gLXJlbGlnaW9zaXR5KQ0KDQpjaGVja19tb2RlbChoMSkNCmBgYA0KDQpXZSBjYW4gaGFuZGxlIGhldGVyb3NjZWRhc3RpY2l0eSBieSB1c2luZyBjbHVzdGVyIHJvYnVzdCBzdGFuZGFyZCBlcnJvcnMgKENSMiksIHVzaW5nIHRoZSBgY2x1YlNhbmR3aWNoYCBwYWNrYWdlLg0KaHR0cHM6Ly9zdHJlbmdlamFja2UuZ2l0aHViLmlvL3NqUGxvdC9hcnRpY2xlcy90YWJfbW9kZWxfcm9idXN0Lmh0bWwNCg0KYGBge3IgY2FjaGUgPSBGQUxTRX0NCnRhYl9tb2RlbChoMSwgDQogICAgICAgICAgc2hvdy5haWMgPSBUUlVFLCANCiAgICAgICAgICBzaG93LnJlZmx2bCA9IFRSVUUsIA0KICAgICAgICAgIHN0cmluZy5jaSA9ICI5NSUgQ0kiLCANCiAgICAgICAgICB2Y292LmZ1biA9ICJDUiIsIA0KICAgICAgICAgIHZjb3YudHlwZSA9ICJDUjIiLCANCiAgICAgICAgICB2Y292LmFyZ3MgPSBsaXN0KGNsdXN0ZXIgPSBoMUBmcmFtZSRjb3VudHJ5KSkNCmBgYA0KDQojIyAyKSBEb2VzIHRoZSByZWxhdGlvbiBiZXR3ZWVuIHJlbGlnaW9zaXR5IGFuZCB3ZWxsLWJlaW5nIGRlcGVuZCBvbiBob3cgaW1wb3J0YW50IHBlb3BsZSBjb25zaWRlciByZWxpZ2lvbiB0byBiZSBpbiB0aGVpciBjb3VudHJ5IChpLmUuLCBwZXJjZWl2ZWQgY3VsdHVyYWwgbm9ybXMgb2YgcmVsaWdpb24pPw0KDQpgYGB7cn0NCmgyIDwtIA0KICBsbWVyKHdiX292ZXJhbGxfbWVhbiB+IHJlbGlnaW9zaXR5ICogY25vcm1fbWVhbiArIA0KICAgICAgICAgIyBwZXJzb25hbCBsZXZlbCBjb25mb3VuZGVycw0KICAgICAgICAgICAgICAgICAgICAgICAgIGFnZSArIGdlbmRlciArIHNlcyArIGVkdWNhdGlvbiArIGRlbm9tX2x1bXAgKw0KICAgICAgICAgIyBjb3VudHJ5IGxldmVsIGNvbmZvdW5kZXJzDQogICAgICAgICAgICAgICAgICAgICAgICAgZ2RwX3NjYWxlZCArIHNhbXBsZV90eXBlICsgDQogICAgICAgICAjIHJhbmRvbSBpbnRlcmNlcHQgYW5kIHNsb3BlIG1vZGVsDQogICAgICAgICAgICAgICAgICAgICAgICAgKHJlbGlnaW9zaXR5fGNvdW50cnkpLCANCiAgICAgICBkYXRhID0gbWFycCkNCg0KY2hlY2tfbW9kZWwoaDIpDQpgYGANCg0KTW9kZWwgZGlhZ25vc3RpY3Mgc2hvdyBoZXRlcm9zY2VkYXN0aWNpdHksIHRoZXJlZm9yZSBjbHVzdGVyIHJvYnVzdCBzdGFuZGFyZCBlcnJvcnMgYXJlIGNhbGN1bGF0ZWQuDQoNCmBgYHtyIGNhY2hlID0gRkFMU0V9DQp0YWJfbW9kZWwoaDIsIA0KICAgICAgICAgIHNob3cuYWljID0gVFJVRSwgDQogICAgICAgICAgc2hvdy5yZWZsdmwgPSBUUlVFLCANCiAgICAgICAgICBzdHJpbmcuY2kgPSAiOTUlIENJIiwgDQogICAgICAgICAgdmNvdi5mdW4gPSAiQ1IiLCANCiAgICAgICAgICB2Y292LnR5cGUgPSAiQ1IyIiwgDQogICAgICAgICAgdmNvdi5hcmdzID0gbGlzdChjbHVzdGVyID0gaDFAZnJhbWUkY291bnRyeSkpDQpgYGANCg0KIyMgTW9kZWwgY29tcGFyaXNvbnMgYW5kIEJheWVzIEZhY3RvcnMNCg0KYGBge3J9DQoNCmFub3ZhKGgwLCBoMSkNCmFub3ZhKGgxLCBoMikNCmFub3ZhKGgwLCBoMikNCg0KIyBDYWxjdWxhdGUgQklDIGJhc2VkIEJheWVzIGZhY3RvcnMgZm9yIA0KIyBIMCB2cyBIMQ0KZXhwKChCSUMoaDApIC0gQklDKGgxKSkvMikNCiMgSDEgdnMgSDINCmV4cCgoQklDKGgxKSAtIEJJQyhoMikpLzIpDQojIEgwIHZzIEgyDQpleHAoKEJJQyhoMCkgLSBCSUMoaDIpKS8yKQ0KDQpgYGANCg0KDQoNCg==