Load and clean data

library(tidyverse)
library(crackdownsphilanthropy)
library(csvy)
library(here)

# Load data
# results_file <- file.path(here(), "data", "test_data.csv")
results_file <- here("data", "raw_data", "crackdowns_philanthropy_raw.csv")

# Possible answers
favorability <- c("Very unfavorable", "Unfavorable", "Neutral", 
                  "Favorable", "Very favorable")

likelihood <- c("Extremely unlikely", "Somewhat unlikely", 
                "Neither likely nor unlikely", 
                "Somewhat likely", "Extremely likely")

frequency_charity <- c("Once a week", "Once a month", "Once every three months", 
                       "Once every six months", "Once a year", "Once every few years", 
                       "Never")

frequency_public_affairs <- c("Most of the time", "Some of the time", 
                              "Only now and then", "Hardly at all")

levels_ideology <- c("Strong liberal", "Liberal", "Independent, leaning liberal", 
                     "Independent", "Independent, leaning conservative", 
                     "Conservative", "Very conservative")

levels_education <- c("Less than high school", "High school graduate", 
                      "Some college", "2 year degree", "4 year degree", 
                      "Graduate or professional degree", "Doctorate")

frequency_religion <- c("More than once a week", "Once a week", "Once or twice a month", 
                        "A few times a year", "Seldom", "Never", "Don't know")

levels_gender <- c("Female", "Male", "Transgender", "Other", "Prefer not to say")

levels_income <- c("Less than $10,000", "$10,000 – $19,999", "$20,000 – $29,999", 
                   "$30,000 – $39,999", "$40,000 – $49,999", "$50,000 – $59,999", 
                   "$60,000 – $69,999", "$70,000 – $79,999", "$80,000 – $89,999", 
                   "$90,000 – $99,999", "$100,000 – $149,999", "More than $150,000", 
                   "Prefer not to say")

levels_age <- c("Under 18", "18 – 24", "25 – 34", "35 – 44", "45 – 54", 
                "55 – 64", "65 – 74", "75 – 84", "85 or older")

attention1_answer <- c("Green", "Yellow")
attention2_answer <- "Blue"
levels_attention <- c("Correct", "Incorrect")

# Qualtrics stores question information in the first 3 rows. All we care about
# are the column names in the first row.
results_meta <- read_csv(results_file, n_max = 2)

# The first 10 rows need to be skipped because the consent question has a bunch
# of line breaks and it messes with CSV line counting. The actual responses
# start on row 11. This doesn't entirely make sense, since read_csv can read the
# line break-filled row in just fine. Skipping said lines makes it choke. <shrug>
results_raw <- read_csv(results_file, skip = 16,
                        col_names = colnames(results_meta))

# Confirmation codes to exclude. These are people who failed the attention
# checks or who took the survey outside of MTurk.
#
# The code for determining these is in a script that is excluded from the main
# repository because of privacy issues (it deals directly with MTurk worker
# IDs), called "data/private_data/approve_mturkers.R". It outputs this text list
# of codes.
codes_to_exclude <- read_csv(here("data", "derived_data", "codes_to_exclude.csv"))

# Clean everything
results_check_attention <- results_raw %>%
  # Only select necessary columns
  select(id = ResponseId, confirmation_code = mTurkCode, duration = `Duration (in seconds)`,
         start_date = StartDate, end_date = EndDate,
         crackdown, issue, funding, starts_with("Q")) %>%
  rename(favor_humanitarian = Q2.1_1, favor_human_rights = Q2.1_2, 
         favor_development = Q2.1_3, donate_likely = Q2.3, 
         amount_donate = Q2.4_1, amount_keep = Q2.4_2, amount_why = Q2.5,
         give_charity = Q3.2, volunteer = Q3.3, political_knowledge = Q3.4,
         ideology = Q3.5, education = Q3.6, religiosity = Q3.7,
         gender = Q3.9, gender_other = Q3.9_4_TEXT, income = Q3.10, age = Q3.11) %>%
  # Clean up experimental condition columns
  mutate(issue = recode(issue, `human rights for refugees` = "Human rights",
                        `humanitarian assistance for refugees` = "Humanitarian assistance"),
         funding = recode(funding, `government donors` = "Government",
                          `individual, private donors` = "Private")) %>%
  mutate(crackdown = ifelse(str_detect(crackdown, "harshly restrict"), 
                            "Crackdown", "No crackdown")) %>% 
  mutate(crackdown = factor(crackdown, levels = c("No crackdown", "Crackdown"), 
                            ordered = TRUE),
         issue = factor(issue, levels = c("Human rights", "Humanitarian assistance"), 
                        ordered = TRUE),
         funding = factor(funding, levels = c("Government", "Private"), 
                          ordered = TRUE)) %>% 
  # Attention checks
  mutate(attention1_correct = str_split(Q1.3, ",") %>% 
           map_lgl(~ all(attention1_answer %in% .) & length(.) == length(attention1_answer)),
         attention2_correct = Q3.8 == attention2_answer) %>% 
  # This person contacted me separately to say that they accidentally did the first
  # attention check wrong, but that they did pay attention: 6518634
  mutate(attention1_correct = ifelse(confirmation_code == 6518634,
                                     TRUE, attention1_correct)) 

results <- results_check_attention %>% 
  filter(!(confirmation_code %in% codes_to_exclude$confirmation_code)) %>% 
  filter(attention2_correct) %>%
  # Factorize variables
  mutate(donate_likely = factor(donate_likely, levels = likelihood, ordered = TRUE)) %>% 
  mutate_at(vars(favor_humanitarian, favor_human_rights, favor_development),
            list(~factor(., levels = favorability, ordered = TRUE))) %>% 
  mutate(give_charity = factor(give_charity, 
                               levels = frequency_charity, ordered = TRUE),
         volunteer = factor(volunteer, levels = c("No", "Yes"), ordered = TRUE),
         political_knowledge = factor(political_knowledge, 
                                      levels = frequency_public_affairs, ordered = TRUE),
         ideology = factor(ideology, levels = levels_ideology, ordered = TRUE),
         education = factor(education, levels = levels_education, ordered = TRUE),
         religiosity = factor(religiosity, levels = frequency_religion, ordered = TRUE),
         gender = recode(gender, `Other:` = "Other"),
         gender = factor(gender, levels = levels_gender, ordered = TRUE),
         income = factor(income, levels = levels_income, ordered = TRUE),
         age = factor(age, levels = levels_age, ordered = TRUE),
         check1 = factor(attention1_correct, levels = c(TRUE, FALSE),
                         labels = levels_attention, ordered = TRUE),
         check2 = factor(attention2_correct, levels = c(TRUE, FALSE),
                         labels = levels_attention, ordered = TRUE)) %>% 
  # Dichotomize variables
  mutate(donate_likely_bin = fct_recode(donate_likely,
                                        `Not likely` = "Extremely unlikely",
                                        `Not likely` = "Somewhat unlikely",
                                        `Not likely` = "Neither likely nor unlikely",
                                        Likely = "Somewhat likely",
                                        Likely = "Extremely likely")) %>% 
  mutate_at(vars(favor_humanitarian, favor_human_rights, favor_development),
            list(bin = ~fct_recode(., 
                                   `Not favorable` = "Very unfavorable",
                                   `Not favorable` = "Unfavorable",
                                   `Not favorable` = "Neutral",
                                   Favorable = "Favorable",
                                   Favorable = "Very favorable"))) %>% 
  mutate(give_charity_3 = fct_recode(give_charity,
                                     `At least once a month` = "Once a week",
                                     `At least once a month` = "Once a month",
                                     `Once a month-once a year` = "Once every three months",
                                     `Once a month-once a year` = "Once every six months",
                                     `Once a month-once a year` = "Once a year",
                                     Rarely = "Once every few years",
                                     Rarely = "Never") %>% fct_rev(),
         give_charity_2 = fct_recode(give_charity,
                                     `At least once a year` = "Once a week",
                                     `At least once a year` = "Once a month",
                                     `At least once a year` = "Once every three months",
                                     `At least once a year` = "Once every six months",
                                     `At least once a year` = "Once a year",
                                     Rarely = "Once every few years",
                                     Rarely = "Never")) %>% 
  mutate(political_knowledge_bin = fct_recode(political_knowledge,
                                              `Often` = "Most of the time",
                                              `Often` = "Some of the time",
                                              `Not often` = "Only now and then",
                                              `Not often` = "Hardly at all") %>% fct_rev()) %>% 
  mutate(ideology_3 = fct_recode(ideology,
                                 `Liberal` = "Strong liberal",
                                 `Liberal` = "Liberal",
                                 `Liberal` = "Independent, leaning liberal",
                                 `Independent` = "Independent",
                                 `Conservative` = "Independent, leaning conservative",
                                 `Conservative` = "Conservative",
                                 `Conservative` = "Very conservative") %>% fct_rev()) %>% 
  mutate(ideology_bin = fct_recode(ideology_3,
                                   `Not liberal` = "Independent",
                                   `Not liberal` = "Conservative")) %>% 
  mutate(education_bin = fct_recode(education,
                                    `No BA` = "Less than high school",
                                    `No BA` = "High school graduate",
                                    `No BA` = "Some college",
                                    `No BA` = "2 year degree",
                                    `BA and above` = "4 year degree",
                                    `BA and above` = "Graduate or professional degree",
                                    `BA and above` = "Doctorate")) %>% 
  mutate(religiosity_bin = fct_recode(religiosity,
                                      `At least once a month` = "More than once a week",
                                      `At least once a month` = "Once a week",
                                      `At least once a month` = "Once or twice a month",
                                      `Rarely` = "A few times a year",
                                      `Rarely` = "Seldom",
                                      `Rarely` = "Never",
                                      NULL = "Don't know") %>% fct_rev()) %>% 
  mutate(income_clean = fct_recode(income, NULL = "Prefer not to say"),
         income_bin = factor(income_clean >= median(.$income), levels = c(FALSE, TRUE),
                             labels = paste(c("Less than", "At least"), median(.$income)))) %>% 
  mutate(age_bin = factor(age >= median(.$age), levels = c(FALSE, TRUE),
                          labels = paste(c("Less than", "At least"), median(.$age))),
         gender_bin = fct_collapse(gender,
                                   Female = "Female",
                                   `Not Female` = c("Male", "Transgender", 
                                                    "Other", "Prefer not to say")))

# Save final clean data
saveRDS(results, here("data", "derived_data", "results_clean.rds"))
write_csvy(results, file = here("data", "derived_data", "results_clean.csv"),
           metadata = here("data", "derived_data", "results_clean.yaml"), na = "NA")
# Save information about completion rates
completed_skeleton <- results_check_attention %>% 
  left_join(codes_to_exclude, by = "confirmation_code") %>% 
  replace_na(list(reason = "Approved")) %>% 
  expand(reason, crackdown, issue, funding)

completed_summary <- results_check_attention %>% 
  left_join(codes_to_exclude, by = "confirmation_code") %>% 
  replace_na(list(reason = "Approved")) %>% 
  count(reason, crackdown, issue, funding) %>% 
  right_join(completed_skeleton, by = c("reason", "crackdown", "issue", "funding")) %>% 
  replace_na(list(n = 0))

saveRDS(completed_summary, here("data", "derived_data", "completion_summary.rds"))
write_csv(completed_summary, here("data", "derived_data", "completion_summary.csv"))

Original computing environment

writeLines(readLines(file.path(Sys.getenv("HOME"), ".R/Makevars")))
## # http://dirk.eddelbuettel.com/blog/2017/11/27/#011_faster_package_installation_one
## VER=
## CCACHE=ccache
## CC=$(CCACHE) gcc$(VER)
## CXX=$(CCACHE) g++$(VER)
## CXX11=$(CCACHE) g++$(VER)
## CXX14=$(CCACHE) g++$(VER)
## FC=$(CCACHE) gfortran$(VER)
## F77=$(CCACHE) gfortran$(VER)
## 
## CXX14FLAGS=-O3 -march=native -mtune=native -fPIC
devtools::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────
##  setting  value                       
##  version  R version 4.0.2 (2020-06-22)
##  os       macOS Catalina 10.15.6      
##  system   x86_64, darwin17.0          
##  ui       X11                         
##  language (EN)                        
##  collate  en_US.UTF-8                 
##  ctype    en_US.UTF-8                 
##  tz       America/New_York            
##  date     2020-10-01                  
## 
## ─ Packages ───────────────────────────────────────────────────────────────────
##  package                * version  date       lib source        
##  assertthat               0.2.1    2019-03-21 [1] CRAN (R 4.0.0)
##  backports                1.1.9    2020-08-24 [1] CRAN (R 4.0.2)
##  base64enc                0.1-3    2015-07-28 [1] CRAN (R 4.0.0)
##  blob                     1.2.1    2020-01-20 [1] CRAN (R 4.0.0)
##  broom                    0.7.0    2020-07-09 [1] CRAN (R 4.0.2)
##  callr                    3.4.3    2020-03-28 [1] CRAN (R 4.0.0)
##  cellranger               1.1.0    2016-07-27 [1] CRAN (R 4.0.0)
##  cli                      2.0.2    2020-02-28 [1] CRAN (R 4.0.0)
##  codetools                0.2-16   2018-12-24 [1] CRAN (R 4.0.2)
##  colorspace               1.4-1    2019-03-18 [1] CRAN (R 4.0.0)
##  crackdownsphilanthropy * 0.9      2020-10-01 [1] local         
##  crayon                   1.3.4    2017-09-16 [1] CRAN (R 4.0.0)
##  csvy                   * 0.3.0    2018-08-01 [1] CRAN (R 4.0.2)
##  curl                     4.3      2019-12-02 [1] CRAN (R 4.0.0)
##  data.table               1.13.0   2020-07-24 [1] CRAN (R 4.0.2)
##  DBI                      1.1.0    2019-12-15 [1] CRAN (R 4.0.0)
##  dbplyr                   1.4.4    2020-05-27 [1] CRAN (R 4.0.2)
##  desc                     1.2.0    2018-05-01 [1] CRAN (R 4.0.0)
##  devtools                 2.3.1    2020-07-21 [1] CRAN (R 4.0.2)
##  digest                   0.6.25   2020-02-23 [1] CRAN (R 4.0.0)
##  dplyr                  * 1.0.2    2020-08-18 [1] CRAN (R 4.0.2)
##  ellipsis                 0.3.1    2020-05-15 [1] CRAN (R 4.0.0)
##  evaluate                 0.14     2019-05-28 [1] CRAN (R 4.0.0)
##  fansi                    0.4.1    2020-01-08 [1] CRAN (R 4.0.0)
##  forcats                * 0.5.0    2020-03-01 [1] CRAN (R 4.0.0)
##  fs                       1.5.0    2020-07-31 [1] CRAN (R 4.0.2)
##  generics                 0.0.2    2018-11-29 [1] CRAN (R 4.0.0)
##  ggplot2                * 3.3.2    2020-06-19 [1] CRAN (R 4.0.2)
##  glue                     1.4.2    2020-08-27 [1] CRAN (R 4.0.2)
##  gridExtra                2.3      2017-09-09 [1] CRAN (R 4.0.0)
##  gtable                   0.3.0    2019-03-25 [1] CRAN (R 4.0.0)
##  haven                    2.3.1    2020-06-01 [1] CRAN (R 4.0.2)
##  here                   * 0.1      2017-05-28 [1] CRAN (R 4.0.0)
##  hms                      0.5.3    2020-01-08 [1] CRAN (R 4.0.0)
##  htmltools                0.5.0    2020-06-16 [1] CRAN (R 4.0.0)
##  httr                     1.4.2    2020-07-20 [1] CRAN (R 4.0.2)
##  inline                   0.3.15   2018-05-18 [1] CRAN (R 4.0.0)
##  jsonlite                 1.7.0    2020-06-25 [1] CRAN (R 4.0.2)
##  knitr                    1.29     2020-06-23 [1] CRAN (R 4.0.2)
##  lifecycle                0.2.0    2020-03-06 [1] CRAN (R 4.0.0)
##  loo                      2.3.1    2020-07-14 [1] CRAN (R 4.0.2)
##  lubridate                1.7.9    2020-06-08 [1] CRAN (R 4.0.2)
##  magrittr                 1.5      2014-11-22 [1] CRAN (R 4.0.0)
##  matrixStats              0.56.0   2020-03-13 [1] CRAN (R 4.0.0)
##  memoise                  1.1.0    2017-04-21 [1] CRAN (R 4.0.0)
##  modelr                   0.1.8    2020-05-19 [1] CRAN (R 4.0.2)
##  munsell                  0.5.0    2018-06-12 [1] CRAN (R 4.0.0)
##  pillar                   1.4.6    2020-07-10 [1] CRAN (R 4.0.2)
##  pkgbuild                 1.1.0    2020-07-13 [1] CRAN (R 4.0.2)
##  pkgconfig                2.0.3    2019-09-22 [1] CRAN (R 4.0.0)
##  pkgload                  1.1.0    2020-05-29 [1] CRAN (R 4.0.2)
##  prettyunits              1.1.1    2020-01-24 [1] CRAN (R 4.0.0)
##  processx                 3.4.3    2020-07-05 [1] CRAN (R 4.0.0)
##  ps                       1.3.4    2020-08-11 [1] CRAN (R 4.0.2)
##  purrr                  * 0.3.4    2020-04-17 [1] CRAN (R 4.0.0)
##  R6                       2.4.1    2019-11-12 [1] CRAN (R 4.0.0)
##  Rcpp                     1.0.5    2020-07-06 [1] CRAN (R 4.0.2)
##  RcppParallel             5.0.2    2020-06-24 [1] CRAN (R 4.0.2)
##  readr                  * 1.3.1    2018-12-21 [1] CRAN (R 4.0.0)
##  readxl                   1.3.1    2019-03-13 [1] CRAN (R 4.0.0)
##  remotes                  2.2.0    2020-07-21 [1] CRAN (R 4.0.2)
##  reprex                   0.3.0    2019-05-16 [1] CRAN (R 4.0.0)
##  rlang                    0.4.7    2020-07-09 [1] CRAN (R 4.0.2)
##  rmarkdown                2.3      2020-06-18 [1] CRAN (R 4.0.2)
##  rprojroot                1.3-2    2018-01-03 [1] CRAN (R 4.0.0)
##  rstan                    2.21.2   2020-07-27 [1] CRAN (R 4.0.2)
##  rstudioapi               0.11     2020-02-07 [1] CRAN (R 4.0.0)
##  rvest                    0.3.6    2020-07-25 [1] CRAN (R 4.0.2)
##  scales                   1.1.1    2020-05-11 [1] CRAN (R 4.0.0)
##  sessioninfo              1.1.1    2018-11-05 [1] CRAN (R 4.0.0)
##  StanHeaders              2.21.0-6 2020-08-16 [1] CRAN (R 4.0.2)
##  stringi                  1.4.6    2020-02-17 [1] CRAN (R 4.0.0)
##  stringr                * 1.4.0    2019-02-10 [1] CRAN (R 4.0.0)
##  testthat                 2.3.2    2020-03-02 [1] CRAN (R 4.0.0)
##  tibble                 * 3.0.3    2020-07-10 [1] CRAN (R 4.0.2)
##  tidyr                  * 1.1.2    2020-08-27 [1] CRAN (R 4.0.2)
##  tidyselect               1.1.0    2020-05-11 [1] CRAN (R 4.0.0)
##  tidyverse              * 1.3.0    2019-11-21 [1] CRAN (R 4.0.0)
##  usethis                  1.6.1    2020-04-29 [1] CRAN (R 4.0.0)
##  V8                       3.2.0    2020-06-19 [1] CRAN (R 4.0.2)
##  vctrs                    0.3.4    2020-08-29 [1] CRAN (R 4.0.2)
##  withr                    2.2.0    2020-04-20 [1] CRAN (R 4.0.0)
##  xfun                     0.16     2020-07-24 [1] CRAN (R 4.0.2)
##  xml2                     1.3.2    2020-04-23 [1] CRAN (R 4.0.0)
##  yaml                     2.2.1    2020-02-01 [1] CRAN (R 4.0.0)
## 
## [1] /Library/Frameworks/R.framework/Versions/4.0/Resources/library
LS0tCnRpdGxlOiAiQ2xlYW4gZGF0YSIKYXV0aG9yOiAiU3VwYXJuYSBDaGF1ZGhyeSBhbmQgQW5kcmV3IEhlaXNzIgpkYXRlOiAiTGFzdCBydW46IGByIGZvcm1hdChTeXMudGltZSgpLCAnJUYnKWAiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZm9sZGluZzogc2hvdwplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgojIExvYWQgYW5kIGNsZWFuIGRhdGEKCmBgYHtyIGNsZWFuLWRhdGEsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGNyYWNrZG93bnNwaGlsYW50aHJvcHkpCmxpYnJhcnkoY3N2eSkKbGlicmFyeShoZXJlKQoKIyBMb2FkIGRhdGEKIyByZXN1bHRzX2ZpbGUgPC0gZmlsZS5wYXRoKGhlcmUoKSwgImRhdGEiLCAidGVzdF9kYXRhLmNzdiIpCnJlc3VsdHNfZmlsZSA8LSBoZXJlKCJkYXRhIiwgInJhd19kYXRhIiwgImNyYWNrZG93bnNfcGhpbGFudGhyb3B5X3Jhdy5jc3YiKQoKIyBQb3NzaWJsZSBhbnN3ZXJzCmZhdm9yYWJpbGl0eSA8LSBjKCJWZXJ5IHVuZmF2b3JhYmxlIiwgIlVuZmF2b3JhYmxlIiwgIk5ldXRyYWwiLCAKICAgICAgICAgICAgICAgICAgIkZhdm9yYWJsZSIsICJWZXJ5IGZhdm9yYWJsZSIpCgpsaWtlbGlob29kIDwtIGMoIkV4dHJlbWVseSB1bmxpa2VseSIsICJTb21ld2hhdCB1bmxpa2VseSIsIAogICAgICAgICAgICAgICAgIk5laXRoZXIgbGlrZWx5IG5vciB1bmxpa2VseSIsIAogICAgICAgICAgICAgICAgIlNvbWV3aGF0IGxpa2VseSIsICJFeHRyZW1lbHkgbGlrZWx5IikKCmZyZXF1ZW5jeV9jaGFyaXR5IDwtIGMoIk9uY2UgYSB3ZWVrIiwgIk9uY2UgYSBtb250aCIsICJPbmNlIGV2ZXJ5IHRocmVlIG1vbnRocyIsIAogICAgICAgICAgICAgICAgICAgICAgICJPbmNlIGV2ZXJ5IHNpeCBtb250aHMiLCAiT25jZSBhIHllYXIiLCAiT25jZSBldmVyeSBmZXcgeWVhcnMiLCAKICAgICAgICAgICAgICAgICAgICAgICAiTmV2ZXIiKQoKZnJlcXVlbmN5X3B1YmxpY19hZmZhaXJzIDwtIGMoIk1vc3Qgb2YgdGhlIHRpbWUiLCAiU29tZSBvZiB0aGUgdGltZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT25seSBub3cgYW5kIHRoZW4iLCAiSGFyZGx5IGF0IGFsbCIpCgpsZXZlbHNfaWRlb2xvZ3kgPC0gYygiU3Ryb25nIGxpYmVyYWwiLCAiTGliZXJhbCIsICJJbmRlcGVuZGVudCwgbGVhbmluZyBsaWJlcmFsIiwgCiAgICAgICAgICAgICAgICAgICAgICJJbmRlcGVuZGVudCIsICJJbmRlcGVuZGVudCwgbGVhbmluZyBjb25zZXJ2YXRpdmUiLCAKICAgICAgICAgICAgICAgICAgICAgIkNvbnNlcnZhdGl2ZSIsICJWZXJ5IGNvbnNlcnZhdGl2ZSIpCgpsZXZlbHNfZWR1Y2F0aW9uIDwtIGMoIkxlc3MgdGhhbiBoaWdoIHNjaG9vbCIsICJIaWdoIHNjaG9vbCBncmFkdWF0ZSIsIAogICAgICAgICAgICAgICAgICAgICAgIlNvbWUgY29sbGVnZSIsICIyIHllYXIgZGVncmVlIiwgIjQgeWVhciBkZWdyZWUiLCAKICAgICAgICAgICAgICAgICAgICAgICJHcmFkdWF0ZSBvciBwcm9mZXNzaW9uYWwgZGVncmVlIiwgIkRvY3RvcmF0ZSIpCgpmcmVxdWVuY3lfcmVsaWdpb24gPC0gYygiTW9yZSB0aGFuIG9uY2UgYSB3ZWVrIiwgIk9uY2UgYSB3ZWVrIiwgIk9uY2Ugb3IgdHdpY2UgYSBtb250aCIsIAogICAgICAgICAgICAgICAgICAgICAgICAiQSBmZXcgdGltZXMgYSB5ZWFyIiwgIlNlbGRvbSIsICJOZXZlciIsICJEb24ndCBrbm93IikKCmxldmVsc19nZW5kZXIgPC0gYygiRmVtYWxlIiwgIk1hbGUiLCAiVHJhbnNnZW5kZXIiLCAiT3RoZXIiLCAiUHJlZmVyIG5vdCB0byBzYXkiKQoKbGV2ZWxzX2luY29tZSA8LSBjKCJMZXNzIHRoYW4gJDEwLDAwMCIsICIkMTAsMDAwIOKAkyAkMTksOTk5IiwgIiQyMCwwMDAg4oCTICQyOSw5OTkiLCAKICAgICAgICAgICAgICAgICAgICIkMzAsMDAwIOKAkyAkMzksOTk5IiwgIiQ0MCwwMDAg4oCTICQ0OSw5OTkiLCAiJDUwLDAwMCDigJMgJDU5LDk5OSIsIAogICAgICAgICAgICAgICAgICAgIiQ2MCwwMDAg4oCTICQ2OSw5OTkiLCAiJDcwLDAwMCDigJMgJDc5LDk5OSIsICIkODAsMDAwIOKAkyAkODksOTk5IiwgCiAgICAgICAgICAgICAgICAgICAiJDkwLDAwMCDigJMgJDk5LDk5OSIsICIkMTAwLDAwMCDigJMgJDE0OSw5OTkiLCAiTW9yZSB0aGFuICQxNTAsMDAwIiwgCiAgICAgICAgICAgICAgICAgICAiUHJlZmVyIG5vdCB0byBzYXkiKQoKbGV2ZWxzX2FnZSA8LSBjKCJVbmRlciAxOCIsICIxOCDigJMgMjQiLCAiMjUg4oCTIDM0IiwgIjM1IOKAkyA0NCIsICI0NSDigJMgNTQiLCAKICAgICAgICAgICAgICAgICI1NSDigJMgNjQiLCAiNjUg4oCTIDc0IiwgIjc1IOKAkyA4NCIsICI4NSBvciBvbGRlciIpCgphdHRlbnRpb24xX2Fuc3dlciA8LSBjKCJHcmVlbiIsICJZZWxsb3ciKQphdHRlbnRpb24yX2Fuc3dlciA8LSAiQmx1ZSIKbGV2ZWxzX2F0dGVudGlvbiA8LSBjKCJDb3JyZWN0IiwgIkluY29ycmVjdCIpCgojIFF1YWx0cmljcyBzdG9yZXMgcXVlc3Rpb24gaW5mb3JtYXRpb24gaW4gdGhlIGZpcnN0IDMgcm93cy4gQWxsIHdlIGNhcmUgYWJvdXQKIyBhcmUgdGhlIGNvbHVtbiBuYW1lcyBpbiB0aGUgZmlyc3Qgcm93LgpyZXN1bHRzX21ldGEgPC0gcmVhZF9jc3YocmVzdWx0c19maWxlLCBuX21heCA9IDIpCgojIFRoZSBmaXJzdCAxMCByb3dzIG5lZWQgdG8gYmUgc2tpcHBlZCBiZWNhdXNlIHRoZSBjb25zZW50IHF1ZXN0aW9uIGhhcyBhIGJ1bmNoCiMgb2YgbGluZSBicmVha3MgYW5kIGl0IG1lc3NlcyB3aXRoIENTViBsaW5lIGNvdW50aW5nLiBUaGUgYWN0dWFsIHJlc3BvbnNlcwojIHN0YXJ0IG9uIHJvdyAxMS4gVGhpcyBkb2Vzbid0IGVudGlyZWx5IG1ha2Ugc2Vuc2UsIHNpbmNlIHJlYWRfY3N2IGNhbiByZWFkIHRoZQojIGxpbmUgYnJlYWstZmlsbGVkIHJvdyBpbiBqdXN0IGZpbmUuIFNraXBwaW5nIHNhaWQgbGluZXMgbWFrZXMgaXQgY2hva2UuIDxzaHJ1Zz4KcmVzdWx0c19yYXcgPC0gcmVhZF9jc3YocmVzdWx0c19maWxlLCBza2lwID0gMTYsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbF9uYW1lcyA9IGNvbG5hbWVzKHJlc3VsdHNfbWV0YSkpCgojIENvbmZpcm1hdGlvbiBjb2RlcyB0byBleGNsdWRlLiBUaGVzZSBhcmUgcGVvcGxlIHdobyBmYWlsZWQgdGhlIGF0dGVudGlvbgojIGNoZWNrcyBvciB3aG8gdG9vayB0aGUgc3VydmV5IG91dHNpZGUgb2YgTVR1cmsuCiMKIyBUaGUgY29kZSBmb3IgZGV0ZXJtaW5pbmcgdGhlc2UgaXMgaW4gYSBzY3JpcHQgdGhhdCBpcyBleGNsdWRlZCBmcm9tIHRoZSBtYWluCiMgcmVwb3NpdG9yeSBiZWNhdXNlIG9mIHByaXZhY3kgaXNzdWVzIChpdCBkZWFscyBkaXJlY3RseSB3aXRoIE1UdXJrIHdvcmtlcgojIElEcyksIGNhbGxlZCAiZGF0YS9wcml2YXRlX2RhdGEvYXBwcm92ZV9tdHVya2Vycy5SIi4gSXQgb3V0cHV0cyB0aGlzIHRleHQgbGlzdAojIG9mIGNvZGVzLgpjb2Rlc190b19leGNsdWRlIDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCAiZGVyaXZlZF9kYXRhIiwgImNvZGVzX3RvX2V4Y2x1ZGUuY3N2IikpCgojIENsZWFuIGV2ZXJ5dGhpbmcKcmVzdWx0c19jaGVja19hdHRlbnRpb24gPC0gcmVzdWx0c19yYXcgJT4lCiAgIyBPbmx5IHNlbGVjdCBuZWNlc3NhcnkgY29sdW1ucwogIHNlbGVjdChpZCA9IFJlc3BvbnNlSWQsIGNvbmZpcm1hdGlvbl9jb2RlID0gbVR1cmtDb2RlLCBkdXJhdGlvbiA9IGBEdXJhdGlvbiAoaW4gc2Vjb25kcylgLAogICAgICAgICBzdGFydF9kYXRlID0gU3RhcnREYXRlLCBlbmRfZGF0ZSA9IEVuZERhdGUsCiAgICAgICAgIGNyYWNrZG93biwgaXNzdWUsIGZ1bmRpbmcsIHN0YXJ0c193aXRoKCJRIikpICU+JQogIHJlbmFtZShmYXZvcl9odW1hbml0YXJpYW4gPSBRMi4xXzEsIGZhdm9yX2h1bWFuX3JpZ2h0cyA9IFEyLjFfMiwgCiAgICAgICAgIGZhdm9yX2RldmVsb3BtZW50ID0gUTIuMV8zLCBkb25hdGVfbGlrZWx5ID0gUTIuMywgCiAgICAgICAgIGFtb3VudF9kb25hdGUgPSBRMi40XzEsIGFtb3VudF9rZWVwID0gUTIuNF8yLCBhbW91bnRfd2h5ID0gUTIuNSwKICAgICAgICAgZ2l2ZV9jaGFyaXR5ID0gUTMuMiwgdm9sdW50ZWVyID0gUTMuMywgcG9saXRpY2FsX2tub3dsZWRnZSA9IFEzLjQsCiAgICAgICAgIGlkZW9sb2d5ID0gUTMuNSwgZWR1Y2F0aW9uID0gUTMuNiwgcmVsaWdpb3NpdHkgPSBRMy43LAogICAgICAgICBnZW5kZXIgPSBRMy45LCBnZW5kZXJfb3RoZXIgPSBRMy45XzRfVEVYVCwgaW5jb21lID0gUTMuMTAsIGFnZSA9IFEzLjExKSAlPiUKICAjIENsZWFuIHVwIGV4cGVyaW1lbnRhbCBjb25kaXRpb24gY29sdW1ucwogIG11dGF0ZShpc3N1ZSA9IHJlY29kZShpc3N1ZSwgYGh1bWFuIHJpZ2h0cyBmb3IgcmVmdWdlZXNgID0gIkh1bWFuIHJpZ2h0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgIGBodW1hbml0YXJpYW4gYXNzaXN0YW5jZSBmb3IgcmVmdWdlZXNgID0gIkh1bWFuaXRhcmlhbiBhc3Npc3RhbmNlIiksCiAgICAgICAgIGZ1bmRpbmcgPSByZWNvZGUoZnVuZGluZywgYGdvdmVybm1lbnQgZG9ub3JzYCA9ICJHb3Zlcm5tZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICBgaW5kaXZpZHVhbCwgcHJpdmF0ZSBkb25vcnNgID0gIlByaXZhdGUiKSkgJT4lCiAgbXV0YXRlKGNyYWNrZG93biA9IGlmZWxzZShzdHJfZGV0ZWN0KGNyYWNrZG93biwgImhhcnNobHkgcmVzdHJpY3QiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ3JhY2tkb3duIiwgIk5vIGNyYWNrZG93biIpKSAlPiUgCiAgbXV0YXRlKGNyYWNrZG93biA9IGZhY3RvcihjcmFja2Rvd24sIGxldmVscyA9IGMoIk5vIGNyYWNrZG93biIsICJDcmFja2Rvd24iKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSksCiAgICAgICAgIGlzc3VlID0gZmFjdG9yKGlzc3VlLCBsZXZlbHMgPSBjKCJIdW1hbiByaWdodHMiLCAiSHVtYW5pdGFyaWFuIGFzc2lzdGFuY2UiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSwKICAgICAgICAgZnVuZGluZyA9IGZhY3RvcihmdW5kaW5nLCBsZXZlbHMgPSBjKCJHb3Zlcm5tZW50IiwgIlByaXZhdGUiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUgCiAgIyBBdHRlbnRpb24gY2hlY2tzCiAgbXV0YXRlKGF0dGVudGlvbjFfY29ycmVjdCA9IHN0cl9zcGxpdChRMS4zLCAiLCIpICU+JSAKICAgICAgICAgICBtYXBfbGdsKH4gYWxsKGF0dGVudGlvbjFfYW5zd2VyICVpbiUgLikgJiBsZW5ndGgoLikgPT0gbGVuZ3RoKGF0dGVudGlvbjFfYW5zd2VyKSksCiAgICAgICAgIGF0dGVudGlvbjJfY29ycmVjdCA9IFEzLjggPT0gYXR0ZW50aW9uMl9hbnN3ZXIpICU+JSAKICAjIFRoaXMgcGVyc29uIGNvbnRhY3RlZCBtZSBzZXBhcmF0ZWx5IHRvIHNheSB0aGF0IHRoZXkgYWNjaWRlbnRhbGx5IGRpZCB0aGUgZmlyc3QKICAjIGF0dGVudGlvbiBjaGVjayB3cm9uZywgYnV0IHRoYXQgdGhleSBkaWQgcGF5IGF0dGVudGlvbjogNjUxODYzNAogIG11dGF0ZShhdHRlbnRpb24xX2NvcnJlY3QgPSBpZmVsc2UoY29uZmlybWF0aW9uX2NvZGUgPT0gNjUxODYzNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUsIGF0dGVudGlvbjFfY29ycmVjdCkpIAoKcmVzdWx0cyA8LSByZXN1bHRzX2NoZWNrX2F0dGVudGlvbiAlPiUgCiAgZmlsdGVyKCEoY29uZmlybWF0aW9uX2NvZGUgJWluJSBjb2Rlc190b19leGNsdWRlJGNvbmZpcm1hdGlvbl9jb2RlKSkgJT4lIAogIGZpbHRlcihhdHRlbnRpb24yX2NvcnJlY3QpICU+JQogICMgRmFjdG9yaXplIHZhcmlhYmxlcwogIG11dGF0ZShkb25hdGVfbGlrZWx5ID0gZmFjdG9yKGRvbmF0ZV9saWtlbHksIGxldmVscyA9IGxpa2VsaWhvb2QsIG9yZGVyZWQgPSBUUlVFKSkgJT4lIAogIG11dGF0ZV9hdCh2YXJzKGZhdm9yX2h1bWFuaXRhcmlhbiwgZmF2b3JfaHVtYW5fcmlnaHRzLCBmYXZvcl9kZXZlbG9wbWVudCksCiAgICAgICAgICAgIGxpc3QofmZhY3RvciguLCBsZXZlbHMgPSBmYXZvcmFiaWxpdHksIG9yZGVyZWQgPSBUUlVFKSkpICU+JSAKICBtdXRhdGUoZ2l2ZV9jaGFyaXR5ID0gZmFjdG9yKGdpdmVfY2hhcml0eSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBmcmVxdWVuY3lfY2hhcml0eSwgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICB2b2x1bnRlZXIgPSBmYWN0b3Iodm9sdW50ZWVyLCBsZXZlbHMgPSBjKCJObyIsICJZZXMiKSwgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICBwb2xpdGljYWxfa25vd2xlZGdlID0gZmFjdG9yKHBvbGl0aWNhbF9rbm93bGVkZ2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGZyZXF1ZW5jeV9wdWJsaWNfYWZmYWlycywgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICBpZGVvbG9neSA9IGZhY3RvcihpZGVvbG9neSwgbGV2ZWxzID0gbGV2ZWxzX2lkZW9sb2d5LCBvcmRlcmVkID0gVFJVRSksCiAgICAgICAgIGVkdWNhdGlvbiA9IGZhY3RvcihlZHVjYXRpb24sIGxldmVscyA9IGxldmVsc19lZHVjYXRpb24sIG9yZGVyZWQgPSBUUlVFKSwKICAgICAgICAgcmVsaWdpb3NpdHkgPSBmYWN0b3IocmVsaWdpb3NpdHksIGxldmVscyA9IGZyZXF1ZW5jeV9yZWxpZ2lvbiwgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICBnZW5kZXIgPSByZWNvZGUoZ2VuZGVyLCBgT3RoZXI6YCA9ICJPdGhlciIpLAogICAgICAgICBnZW5kZXIgPSBmYWN0b3IoZ2VuZGVyLCBsZXZlbHMgPSBsZXZlbHNfZ2VuZGVyLCBvcmRlcmVkID0gVFJVRSksCiAgICAgICAgIGluY29tZSA9IGZhY3RvcihpbmNvbWUsIGxldmVscyA9IGxldmVsc19pbmNvbWUsIG9yZGVyZWQgPSBUUlVFKSwKICAgICAgICAgYWdlID0gZmFjdG9yKGFnZSwgbGV2ZWxzID0gbGV2ZWxzX2FnZSwgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICBjaGVjazEgPSBmYWN0b3IoYXR0ZW50aW9uMV9jb3JyZWN0LCBsZXZlbHMgPSBjKFRSVUUsIEZBTFNFKSwKICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGxldmVsc19hdHRlbnRpb24sIG9yZGVyZWQgPSBUUlVFKSwKICAgICAgICAgY2hlY2syID0gZmFjdG9yKGF0dGVudGlvbjJfY29ycmVjdCwgbGV2ZWxzID0gYyhUUlVFLCBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBsZXZlbHNfYXR0ZW50aW9uLCBvcmRlcmVkID0gVFJVRSkpICU+JSAKICAjIERpY2hvdG9taXplIHZhcmlhYmxlcwogIG11dGF0ZShkb25hdGVfbGlrZWx5X2JpbiA9IGZjdF9yZWNvZGUoZG9uYXRlX2xpa2VseSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBOb3QgbGlrZWx5YCA9ICJFeHRyZW1lbHkgdW5saWtlbHkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYE5vdCBsaWtlbHlgID0gIlNvbWV3aGF0IHVubGlrZWx5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBOb3QgbGlrZWx5YCA9ICJOZWl0aGVyIGxpa2VseSBub3IgdW5saWtlbHkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGlrZWx5ID0gIlNvbWV3aGF0IGxpa2VseSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaWtlbHkgPSAiRXh0cmVtZWx5IGxpa2VseSIpKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoZmF2b3JfaHVtYW5pdGFyaWFuLCBmYXZvcl9odW1hbl9yaWdodHMsIGZhdm9yX2RldmVsb3BtZW50KSwKICAgICAgICAgICAgbGlzdChiaW4gPSB+ZmN0X3JlY29kZSguLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTm90IGZhdm9yYWJsZWAgPSAiVmVyeSB1bmZhdm9yYWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYE5vdCBmYXZvcmFibGVgID0gIlVuZmF2b3JhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTm90IGZhdm9yYWJsZWAgPSAiTmV1dHJhbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmF2b3JhYmxlID0gIkZhdm9yYWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmF2b3JhYmxlID0gIlZlcnkgZmF2b3JhYmxlIikpKSAlPiUgCiAgbXV0YXRlKGdpdmVfY2hhcml0eV8zID0gZmN0X3JlY29kZShnaXZlX2NoYXJpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQXQgbGVhc3Qgb25jZSBhIG1vbnRoYCA9ICJPbmNlIGEgd2VlayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQXQgbGVhc3Qgb25jZSBhIG1vbnRoYCA9ICJPbmNlIGEgbW9udGgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYE9uY2UgYSBtb250aC1vbmNlIGEgeWVhcmAgPSAiT25jZSBldmVyeSB0aHJlZSBtb250aHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYE9uY2UgYSBtb250aC1vbmNlIGEgeWVhcmAgPSAiT25jZSBldmVyeSBzaXggbW9udGhzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBPbmNlIGEgbW9udGgtb25jZSBhIHllYXJgID0gIk9uY2UgYSB5ZWFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJhcmVseSA9ICJPbmNlIGV2ZXJ5IGZldyB5ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSYXJlbHkgPSAiTmV2ZXIiKSAlPiUgZmN0X3JldigpLAogICAgICAgICBnaXZlX2NoYXJpdHlfMiA9IGZjdF9yZWNvZGUoZ2l2ZV9jaGFyaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYEF0IGxlYXN0IG9uY2UgYSB5ZWFyYCA9ICJPbmNlIGEgd2VlayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQXQgbGVhc3Qgb25jZSBhIHllYXJgID0gIk9uY2UgYSBtb250aCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQXQgbGVhc3Qgb25jZSBhIHllYXJgID0gIk9uY2UgZXZlcnkgdGhyZWUgbW9udGhzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBBdCBsZWFzdCBvbmNlIGEgeWVhcmAgPSAiT25jZSBldmVyeSBzaXggbW9udGhzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBBdCBsZWFzdCBvbmNlIGEgeWVhcmAgPSAiT25jZSBhIHllYXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmFyZWx5ID0gIk9uY2UgZXZlcnkgZmV3IHllYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJhcmVseSA9ICJOZXZlciIpKSAlPiUgCiAgbXV0YXRlKHBvbGl0aWNhbF9rbm93bGVkZ2VfYmluID0gZmN0X3JlY29kZShwb2xpdGljYWxfa25vd2xlZGdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYE9mdGVuYCA9ICJNb3N0IG9mIHRoZSB0aW1lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBPZnRlbmAgPSAiU29tZSBvZiB0aGUgdGltZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTm90IG9mdGVuYCA9ICJPbmx5IG5vdyBhbmQgdGhlbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTm90IG9mdGVuYCA9ICJIYXJkbHkgYXQgYWxsIikgJT4lIGZjdF9yZXYoKSkgJT4lIAogIG11dGF0ZShpZGVvbG9neV8zID0gZmN0X3JlY29kZShpZGVvbG9neSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYExpYmVyYWxgID0gIlN0cm9uZyBsaWJlcmFsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYExpYmVyYWxgID0gIkxpYmVyYWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTGliZXJhbGAgPSAiSW5kZXBlbmRlbnQsIGxlYW5pbmcgbGliZXJhbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBJbmRlcGVuZGVudGAgPSAiSW5kZXBlbmRlbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQ29uc2VydmF0aXZlYCA9ICJJbmRlcGVuZGVudCwgbGVhbmluZyBjb25zZXJ2YXRpdmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQ29uc2VydmF0aXZlYCA9ICJDb25zZXJ2YXRpdmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQ29uc2VydmF0aXZlYCA9ICJWZXJ5IGNvbnNlcnZhdGl2ZSIpICU+JSBmY3RfcmV2KCkpICU+JSAKICBtdXRhdGUoaWRlb2xvZ3lfYmluID0gZmN0X3JlY29kZShpZGVvbG9neV8zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBOb3QgbGliZXJhbGAgPSAiSW5kZXBlbmRlbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBOb3QgbGliZXJhbGAgPSAiQ29uc2VydmF0aXZlIikpICU+JSAKICBtdXRhdGUoZWR1Y2F0aW9uX2JpbiA9IGZjdF9yZWNvZGUoZWR1Y2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTm8gQkFgID0gIkxlc3MgdGhhbiBoaWdoIHNjaG9vbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBObyBCQWAgPSAiSGlnaCBzY2hvb2wgZ3JhZHVhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgTm8gQkFgID0gIlNvbWUgY29sbGVnZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBObyBCQWAgPSAiMiB5ZWFyIGRlZ3JlZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBCQSBhbmQgYWJvdmVgID0gIjQgeWVhciBkZWdyZWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQkEgYW5kIGFib3ZlYCA9ICJHcmFkdWF0ZSBvciBwcm9mZXNzaW9uYWwgZGVncmVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYEJBIGFuZCBhYm92ZWAgPSAiRG9jdG9yYXRlIikpICU+JSAKICBtdXRhdGUocmVsaWdpb3NpdHlfYmluID0gZmN0X3JlY29kZShyZWxpZ2lvc2l0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQXQgbGVhc3Qgb25jZSBhIG1vbnRoYCA9ICJNb3JlIHRoYW4gb25jZSBhIHdlZWsiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBBdCBsZWFzdCBvbmNlIGEgbW9udGhgID0gIk9uY2UgYSB3ZWVrIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgQXQgbGVhc3Qgb25jZSBhIG1vbnRoYCA9ICJPbmNlIG9yIHR3aWNlIGEgbW9udGgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBSYXJlbHlgID0gIkEgZmV3IHRpbWVzIGEgeWVhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFJhcmVseWAgPSAiU2VsZG9tIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgUmFyZWx5YCA9ICJOZXZlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCA9ICJEb24ndCBrbm93IikgJT4lIGZjdF9yZXYoKSkgJT4lIAogIG11dGF0ZShpbmNvbWVfY2xlYW4gPSBmY3RfcmVjb2RlKGluY29tZSwgTlVMTCA9ICJQcmVmZXIgbm90IHRvIHNheSIpLAogICAgICAgICBpbmNvbWVfYmluID0gZmFjdG9yKGluY29tZV9jbGVhbiA+PSBtZWRpYW4oLiRpbmNvbWUpLCBsZXZlbHMgPSBjKEZBTFNFLCBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBwYXN0ZShjKCJMZXNzIHRoYW4iLCAiQXQgbGVhc3QiKSwgbWVkaWFuKC4kaW5jb21lKSkpKSAlPiUgCiAgbXV0YXRlKGFnZV9iaW4gPSBmYWN0b3IoYWdlID49IG1lZGlhbiguJGFnZSksIGxldmVscyA9IGMoRkFMU0UsIFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IHBhc3RlKGMoIkxlc3MgdGhhbiIsICJBdCBsZWFzdCIpLCBtZWRpYW4oLiRhZ2UpKSksCiAgICAgICAgIGdlbmRlcl9iaW4gPSBmY3RfY29sbGFwc2UoZ2VuZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZlbWFsZSA9ICJGZW1hbGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBOb3QgRmVtYWxlYCA9IGMoIk1hbGUiLCAiVHJhbnNnZW5kZXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPdGhlciIsICJQcmVmZXIgbm90IHRvIHNheSIpKSkKCiMgU2F2ZSBmaW5hbCBjbGVhbiBkYXRhCnNhdmVSRFMocmVzdWx0cywgaGVyZSgiZGF0YSIsICJkZXJpdmVkX2RhdGEiLCAicmVzdWx0c19jbGVhbi5yZHMiKSkKd3JpdGVfY3N2eShyZXN1bHRzLCBmaWxlID0gaGVyZSgiZGF0YSIsICJkZXJpdmVkX2RhdGEiLCAicmVzdWx0c19jbGVhbi5jc3YiKSwKICAgICAgICAgICBtZXRhZGF0YSA9IGhlcmUoImRhdGEiLCAiZGVyaXZlZF9kYXRhIiwgInJlc3VsdHNfY2xlYW4ueWFtbCIpLCBuYSA9ICJOQSIpCmBgYAoKYGBge3IgY29tcGxldGVkLXN1bW1hcnl9CiMgU2F2ZSBpbmZvcm1hdGlvbiBhYm91dCBjb21wbGV0aW9uIHJhdGVzCmNvbXBsZXRlZF9za2VsZXRvbiA8LSByZXN1bHRzX2NoZWNrX2F0dGVudGlvbiAlPiUgCiAgbGVmdF9qb2luKGNvZGVzX3RvX2V4Y2x1ZGUsIGJ5ID0gImNvbmZpcm1hdGlvbl9jb2RlIikgJT4lIAogIHJlcGxhY2VfbmEobGlzdChyZWFzb24gPSAiQXBwcm92ZWQiKSkgJT4lIAogIGV4cGFuZChyZWFzb24sIGNyYWNrZG93biwgaXNzdWUsIGZ1bmRpbmcpCgpjb21wbGV0ZWRfc3VtbWFyeSA8LSByZXN1bHRzX2NoZWNrX2F0dGVudGlvbiAlPiUgCiAgbGVmdF9qb2luKGNvZGVzX3RvX2V4Y2x1ZGUsIGJ5ID0gImNvbmZpcm1hdGlvbl9jb2RlIikgJT4lIAogIHJlcGxhY2VfbmEobGlzdChyZWFzb24gPSAiQXBwcm92ZWQiKSkgJT4lIAogIGNvdW50KHJlYXNvbiwgY3JhY2tkb3duLCBpc3N1ZSwgZnVuZGluZykgJT4lIAogIHJpZ2h0X2pvaW4oY29tcGxldGVkX3NrZWxldG9uLCBieSA9IGMoInJlYXNvbiIsICJjcmFja2Rvd24iLCAiaXNzdWUiLCAiZnVuZGluZyIpKSAlPiUgCiAgcmVwbGFjZV9uYShsaXN0KG4gPSAwKSkKCnNhdmVSRFMoY29tcGxldGVkX3N1bW1hcnksIGhlcmUoImRhdGEiLCAiZGVyaXZlZF9kYXRhIiwgImNvbXBsZXRpb25fc3VtbWFyeS5yZHMiKSkKd3JpdGVfY3N2KGNvbXBsZXRlZF9zdW1tYXJ5LCBoZXJlKCJkYXRhIiwgImRlcml2ZWRfZGF0YSIsICJjb21wbGV0aW9uX3N1bW1hcnkuY3N2IikpCmBgYAoKCiMgT3JpZ2luYWwgY29tcHV0aW5nIGVudmlyb25tZW50Cgo8YnV0dG9uIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9IiNzZXNzaW9uaW5mbyIgY2xhc3M9ImJ0biBidG4tcHJpbWFyeSBidG4tbWQgYnRuLWluZm8iPkhlcmUncyB3aGF0IHdlIHVzZWQgdGhlIGxhc3QgdGltZSB3ZSBidWlsdCB0aGlzIHBhZ2U8L2J1dHRvbj4KCjxkaXYgaWQ9InNlc3Npb25pbmZvIiBjbGFzcz0iY29sbGFwc2UiPgoKYGBge3Igc2hvdy1zZXNzaW9uLWluZm8sIGVjaG89VFJVRSwgd2lkdGg9OTB9CndyaXRlTGluZXMocmVhZExpbmVzKGZpbGUucGF0aChTeXMuZ2V0ZW52KCJIT01FIiksICIuUi9NYWtldmFycyIpKSkKCmRldnRvb2xzOjpzZXNzaW9uX2luZm8oKQpgYGAKCjwvZGl2PiAgCg==