library(readr)
library(dplyr)
library(scales)
library(tidyr)
library(ggplot2)
library(cowplot)
library(stringr)
library(forcats)
library(ggallin)

theme_set(theme_bw())

Read in data

alpha_threshold <- qnorm(0.975)
countries <- c("France", "Germany", "Spain", "Italy", "Singapore", "USA" )
countries_code <- c("FR", "DE", "ES", "IT", "SG", "US")
colorBlindGrey6 <- c("#0072B2", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#CC79A7")
races <- c("black", "hispanic_latino", "white", "asian", 
           "hawaiian_pacific_islander", "american_indian")  
Races <- rev(c('White', 'Black', 'Hispanic/Latino', 'Asian', 
               'American Indian', 'Hawaiian/Pacific Islander', 'Other/Unknown'))

demo_desc <- read_csv('results/demo_prelim.csv') %>% 
  filter(siteid != 'SITE157', siteid != 'SITE712') %>% 
  mutate(Country = fct_relevel(Country, countries))
## 
## ── Column specification ────────────────────────────────────────────────────────
## cols(
##   .default = col_double(),
##   siteid = col_character(),
##   Country = col_character()
## )
## ℹ Use `spec()` for the full column specifications.
demo_perc <- demo_desc %>% 
  mutate_at(vars(- num_patients_all, - siteid, - Country, - median_age),
            list(~ . / .data$num_patients_all)) %>% 
  mutate(Country = as.factor(Country)) 

demo_perc %>% 
  rename('perc_patients_ever_severe' = num_patients_ever_severe,
         'perc_patients_never_severe' = num_patients_never_severe) %>% 
  write_csv('results/demographics.csv')

Overall statistics

demo_desc %>% 
  summarise(across(c(num_patients_all, female, male, unknown_other_sex), sum)) 
## # A tibble: 1 x 4
##   num_patients_all female  male unknown_other_sex
##              <dbl>  <dbl> <dbl>             <dbl>
## 1            34647  13546 20814               287
demo_desc %>% 
  summarise(across(c(num_patients_all, races, unknown_other_race), sum)) %>% 
  print()
## Note: Using an external vector in selections is ambiguous.
## ℹ Use `all_of(races)` instead of `races` to silence this message.
## ℹ See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
## This message is displayed once per session.
## # A tibble: 1 x 8
##   num_patients_all black hispanic_latino white asian hawaiian_pacifi…
##              <dbl> <dbl>           <dbl> <dbl> <dbl>            <dbl>
## 1            34647  5706            1400  8532   621                9
## # … with 2 more variables: american_indian <dbl>, unknown_other_race <dbl>
unknowns <- demo_perc %>%
  select(siteid, Country, contains('unknown')) %>% 
  pivot_longer(- c(siteid, Country))
unknowns %>% filter(value < 0)
## # A tibble: 6 x 4
##   siteid  Country name                  value
##   <chr>   <fct>   <chr>                 <dbl>
## 1 SITE824 USA     unknown_other_sex  -0.00293
## 2 SITE864 USA     unknown_other_race -0.00443
## 3 SITE295 USA     unknown_other_race -0.0822 
## 4 SITE200 USA     unknown_other_race -0.0145 
## 5 SITE775 USA     unknown_other_race -0.0769 
## 6 SITE923 USA     unknown_other_race -0.107
unknowns %>% filter(value < 1, value > 0.1)
## # A tibble: 9 x 4
##   siteid  Country   name               value
##   <chr>   <fct>     <chr>              <dbl>
## 1 SITE824 USA       unknown_other_race 0.152
## 2 SITE599 USA       unknown_other_race 0.14 
## 3 SITE116 Singapore unknown_other_race 0.378
## 4 SITE798 USA       unknown_other_race 0.173
## 5 SITE510 USA       unknown_other_race 0.367
## 6 SITE533 USA       unknown_other_race 0.148
## 7 SITE432 USA       unknown_other_sex  0.107
## 8 SITE432 USA       unknown_other_race 0.214
## 9 SITE734 USA       unknown_other_race 0.258
# unknowns %>% 
#   ggplot(aes(y = value, x = name)) +
#   ggbeeswarm::geom_beeswarm() +
#   facet_wrap(~ name, scales = 'free_x')

Severity vs. gender/age/race?

demo_gender <- demo_perc %>% filter(unknown_other_sex < 1)
lm(num_patients_ever_severe ~ female, demo_gender) %>% 
  summary()
## 
## Call:
## lm(formula = num_patients_ever_severe ~ female, data = demo_gender)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.55272 -0.04966 -0.00420  0.10740  0.42322 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  1.00420    0.04687   21.43  < 2e-16 ***
## female      -1.32622    0.13873   -9.56 9.02e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1833 on 39 degrees of freedom
## Multiple R-squared:  0.7009, Adjusted R-squared:  0.6932 
## F-statistic: 91.38 on 1 and 39 DF,  p-value: 9.02e-12
age_perc <- demo_perc %>% 
  filter(unknown_other_age_group < 1) %>% 
  select(Country, num_patients_all, num_patients_ever_severe, contains('to'), ends_with('plus'))

lm(num_patients_ever_severe ~ . - Country - num_patients_all, age_perc) %>% 
  summary()
## 
## Call:
## lm(formula = num_patients_ever_severe ~ . - Country - num_patients_all, 
##     data = age_perc)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.56212 -0.07390  0.03572  0.10181  0.38724 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)   
## (Intercept)   -3.731      1.712  -2.179  0.03659 * 
## `00to02`      -4.334      7.509  -0.577  0.56772   
## `03to05`      73.690     33.517   2.199  0.03503 * 
## `06to11`     -18.079     15.938  -1.134  0.26484   
## `12to17`       4.277     15.450   0.277  0.78362   
## `18to25`       1.723      3.225   0.534  0.59675   
## `26to49`       3.803      1.815   2.096  0.04386 * 
## `50to69`       4.476      1.902   2.354  0.02470 * 
## `70to79`       6.186      1.887   3.278  0.00246 **
## `80plus`       2.964      1.638   1.810  0.07943 . 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.217 on 33 degrees of freedom
## Multiple R-squared:  0.6591, Adjusted R-squared:  0.5661 
## F-statistic: 7.089 on 9 and 33 DF,  p-value: 1.225e-05
lm(num_patients_ever_severe ~ black + white + asian + hispanic_latino + 
     american_indian + hawaiian_pacific_islander, 
   data = filter(demo_perc, unknown_other_race < 1)) %>% 
  summary()
## 
## Call:
## lm(formula = num_patients_ever_severe ~ black + white + asian + 
##     hispanic_latino + american_indian + hawaiian_pacific_islander, 
##     data = filter(demo_perc, unknown_other_race < 1))
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -0.5508 -0.1224  0.1029  0.1451  0.3034 
## 
## Coefficients:
##                           Estimate Std. Error t value Pr(>|t|)
## (Intercept)                 0.2270     0.6028   0.377    0.709
## black                       0.7031     0.6360   1.105    0.279
## white                       0.6638     0.6880   0.965    0.344
## asian                      -0.4146     1.1398  -0.364    0.719
## hispanic_latino            -0.3319     0.6205  -0.535    0.597
## american_indian           -31.0987    33.4578  -0.929    0.361
## hawaiian_pacific_islander -60.7964    71.6772  -0.848    0.404
## 
## Residual standard error: 0.2678 on 26 degrees of freedom
## Multiple R-squared:  0.3673, Adjusted R-squared:  0.2212 
## F-statistic: 2.515 on 6 and 26 DF,  p-value: 0.04703
lm(num_patients_ever_severe ~ median_age, demo_perc) %>% 
  summary()
## 
## Call:
## lm(formula = num_patients_ever_severe ~ median_age, data = demo_perc)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.69883 -0.22095 -0.01098  0.26950  0.45614 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)  
## (Intercept) -0.417341   0.452308  -0.923   0.3616  
## median_age   0.015701   0.006709   2.340   0.0242 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.3132 on 41 degrees of freedom
## Multiple R-squared:  0.1178, Adjusted R-squared:  0.09633 
## F-statistic: 5.477 on 1 and 41 DF,  p-value: 0.02421

Overall plot (A)

gender_count <- demo_desc %>% 
  # filter(unknown_other_sex/num_patients_all < 1) %>% 
  # mutate(siteid = as.factor(siteid)) %>% 
  # mutate(num_patients_all_gender = female + male) %>% 
  group_by(Country) %>% 
  summarise(num_patients_country = sum(num_patients_all),
            male_count = sum(male),
            female_count = sum(female),
            .groups = 'drop') %>% 
  {.}

showtext::showtext_auto()
female <- intToUtf8(9792)
male <- intToUtf8(9794)

overall_plot <- gender_count %>% 
  mutate(male_count = -male_count) %>% 
  pivot_longer(- c(Country, num_patients_country)) %>% 
  ggplot(aes(y = fct_relevel(Country, rev(countries)), 
             x = value, color = name, 
             fill = Country)) +
  geom_col(position = 'identity') +
  scale_color_manual(values = c('white', 'white')) +
  scale_x_continuous(breaks = c(-5000, -2000, 0, 2000, 5000),
                     labels = c(5000, 2000, 0, 2000, 5000),
                     trans = ssqrt_trans) +
  geom_vline(xintercept = 0, color = 'white') +
  geom_text(data = . %>% filter(name == 'male_count'),
            aes(y = Country, x = value - 22*sqrt(abs(value)), 
                label = abs(value)), color = 'grey40', size = 3) +
    geom_text(data = . %>% filter(name == 'female_count'),
            aes(y = Country, x = value + 19*sqrt(abs(value)), 
                label = abs(value)), color = 'grey40', size = 3) +
  geom_text(data = filter(gender_count, Country == 'France'),
            aes(y = 6, x = female_count - 600), fontface = 2,
            label = female, size = 3, color = 'white') +
  geom_text(data = filter(gender_count, Country == 'France'),
            aes(y = 6, x = - male_count + 600), fontface = 2,
            label = male, size = 3, color = 'white') +
  labs(y = NULL, 
       x = 'Number of male/female patients per country', 
       fill = NULL) +
  scale_fill_manual(values = colorBlindGrey6) +
  theme(legend.position = 'None',
        plot.margin = margin(15, 5.5, 15.5, 55.5),
        axis.ticks.y = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor = element_blank(),
        panel.border = element_blank(),
        panel.spacing.y = unit(0, 'pt'),
        strip.background = element_blank(),
        strip.placement = 'inside',
        legend.background = element_blank(),
        legend.key.height = unit(1, 'line'),
        legend.title = element_text(hjust = 0, size = 9)) +
  NULL

Age plot (B)

age_count <- demo_desc %>% 
  filter(unknown_other_age_group/num_patients_all < 1) %>% 
  select(Country, num_patients_all, contains('to'), ends_with('plus')) %>% 
  group_by(Country) %>% 
  summarise(across(.fns = sum), .groups = 'drop') %>% 
  mutate_at(vars(- num_patients_all, - Country),
            list(~ . / .data$num_patients_all)) %>% 
  select(-num_patients_all) %>% 
  pivot_longer(- Country) %>% 
  mutate(name = case_when(
    name == '00to02' ~ '0to2',
    name == '03to05' ~ '3to5',
    name == '06to11' ~ '6to11',
    TRUE ~ name
  )) %>% 
  mutate(name = gsub('to', '–', name) %>% gsub('plus', '+', .))
age_count$name <- factor(age_count$name, levels = unique(age_count$name))

age_plot <- age_count  %>% 
  ggplot(aes(name, value, fill = Country, group = Country)) +
  geom_col(position = 'dodge2') + 
  coord_flip() +
  facet_grid(rows = vars(Country)) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1),
                     breaks = seq(0, 1, 0.2),
                     expand = expansion(add = c(0,0.02))) +
  scale_size_continuous(guide = FALSE) +
  labs(x = NULL, y = 'Patients proportion per age group') +
  scale_color_manual(values = colorBlindGrey6, drop = FALSE) +
  scale_fill_manual(values = colorBlindGrey6, drop = FALSE) +
  theme(legend.position = 'None',
        axis.text.y = element_text(size = 7),
        panel.grid.major.y = element_blank(),
        plot.margin = margin(15, 5.5, 5.5, 5.5, 'pt')) +
  NULL

Severity vs. age plot (C)

country_codes <- read_csv('https://raw.githubusercontent.com/lukes/ISO-3166-Countries-with-Regional-Codes/master/all/all.csv') %>%
  mutate(name = ifelse(name == 'United States of America', 'USA', name)) %>%
  filter(name %in% countries) %>%
  select(Country = name, coun_code = `alpha-2`) %>%
  mutate(coun_code = as.factor(coun_code) %>% fct_relevel(countries_code))
## 
## ── Column specification ────────────────────────────────────────────────────────
## cols(
##   name = col_character(),
##   `alpha-2` = col_character(),
##   `alpha-3` = col_character(),
##   `country-code` = col_character(),
##   `iso_3166-2` = col_character(),
##   region = col_character(),
##   `sub-region` = col_character(),
##   `intermediate-region` = col_character(),
##   `region-code` = col_character(),
##   `sub-region-code` = col_character(),
##   `intermediate-region-code` = col_character()
## )
age_severity <- demo_perc %>% 
  left_join(country_codes, by = 'Country') %>%
  ggplot(aes(median_age, num_patients_ever_severe, 
             color = coun_code)) +
  geom_point(aes(size = num_patients_all), alpha = 0.8) +
  scale_y_continuous(labels = scales::percent_format(),
                     breaks = seq(0, 1, 0.2)) +
  labs(x = 'Median age estimate', 
       y = 'Severe case proportion', 
       color = NULL) +
  scale_size(trans = "log10", guide = FALSE) +
  scale_color_manual(values = colorBlindGrey6) +
  coord_cartesian(ylim = c(0, 1)) +
  theme(
    # legend.position = c(0.9, 0.7),
    legend.position = 'left',
    legend.background = element_blank(),
    plot.margin = margin(5.5, 5.5, 10.5, 15.5),
    panel.grid.minor = element_blank(),
    legend.key.height = unit(0.7, 'line'),
    legend.key.width = unit(0.4, 'line'),
    legend.title = element_text(hjust = 0, size = 9)) +
  NULL

Race plot (D)

race_count <- demo_desc %>% 
  filter(unknown_other_race/num_patients_all < 1) %>% 
  select(Country, num_patients_all, all_of(races), unknown_other_race) %>% 
  group_by(Country) %>% 
  summarise(across(.fns = sum), .groups = 'drop') %>% 
  mutate_at(vars(- num_patients_all, - Country),
            list(~ . / .data$num_patients_all)) %>% 
  select(-num_patients_all) %>% 
  pivot_longer(- Country) %>% 
  mutate(name = gsub('_', ' ', name) %>% 
           str_to_title(.) %>% 
           gsub('Hispanic ', 'Hispanic/', .) %>% 
           gsub('Hawaiian ', 'Hawaiian/', .) %>% 
           gsub('Unknown Other Race', 'Other/Unknown',. ),
         name = fct_relevel(name, Races))

race_plot <- race_count %>% 
  # remove one site in Italy that reported all white ethnicity
  filter(Country != 'Italy') %>% 
  ggplot(aes(name, value, fill = Country, group = Country)) +
  geom_col(position = 'dodge2') + 
  coord_flip() +
  facet_grid(rows = vars(Country)) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1),
                     breaks = seq(0, 1, 0.2),
                     expand = expansion(add = c(0,0.02))) +
  scale_size_continuous(guide = FALSE) +
  labs(x = NULL, y = 'Patient proportion per race/ethnicity group') +
  scale_color_manual(values = colorBlindGrey6, drop = FALSE) +
  scale_fill_manual(values = colorBlindGrey6, drop = FALSE) +
  theme(legend.position = 'None',
        axis.text.y = element_text(size = 8),
        panel.grid.major.y = element_blank(),
        axis.title.x = element_text(hjust = .8)) +
  NULL

Composite plot

gender_race <- plot_grid(overall_plot, age_severity, race_plot, ncol = 1,
          rel_heights = c(0.7, 1, 1), 
          labels = c('A', 'B', 'C'), axis = 'r')
abcd <- plot_grid(gender_race, age_plot, ncol = 2,
                  rel_widths = c(1.25, 1 ), labels = c('', 'D'),
                  axis = 'b')
abcd

ggsave('figs/composite_plot.png', abcd, height = 6.5, width = 9)
ggsave('figs/tiffs/fig_2.tiff', abcd, height = 6.5, width = 9, dpi = 300)
LS0tCnRpdGxlOiAiQW5hbHlzaXMgb2YgZGVtb2dyYXBoaWNzIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiBsdW1lbgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IGZhbHNlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBoaWdobGlnaHQ6IHRhbmdvCmtuaXQ6IChmdW5jdGlvbihpbnB1dEZpbGUsIGVuY29kaW5nKSB7CiAgcm1hcmtkb3duOjpyZW5kZXIoaW5wdXRGaWxlLCBlbmNvZGluZyA9IGVuY29kaW5nLCBvdXRwdXRfZGlyID0gImRvY3MiKSB9KQotLS0KCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkocmVhZHIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoY293cGxvdCkKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KGZvcmNhdHMpCmxpYnJhcnkoZ2dhbGxpbikKCnRoZW1lX3NldCh0aGVtZV9idygpKQpgYGAKCiMjIFJlYWQgaW4gZGF0YQpgYGB7cn0KYWxwaGFfdGhyZXNob2xkIDwtIHFub3JtKDAuOTc1KQpjb3VudHJpZXMgPC0gYygiRnJhbmNlIiwgIkdlcm1hbnkiLCAiU3BhaW4iLCAiSXRhbHkiLCAiU2luZ2Fwb3JlIiwgIlVTQSIgKQpjb3VudHJpZXNfY29kZSA8LSBjKCJGUiIsICJERSIsICJFUyIsICJJVCIsICJTRyIsICJVUyIpCmNvbG9yQmxpbmRHcmV5NiA8LSBjKCIjMDA3MkIyIiwgIiNFNjlGMDAiLCAiIzU2QjRFOSIsICIjMDA5RTczIiwgIiNGMEU0NDIiLCAiI0NDNzlBNyIpCnJhY2VzIDwtIGMoImJsYWNrIiwgImhpc3BhbmljX2xhdGlubyIsICJ3aGl0ZSIsICJhc2lhbiIsIAogICAgICAgICAgICJoYXdhaWlhbl9wYWNpZmljX2lzbGFuZGVyIiwgImFtZXJpY2FuX2luZGlhbiIpICAKUmFjZXMgPC0gcmV2KGMoJ1doaXRlJywgJ0JsYWNrJywgJ0hpc3BhbmljL0xhdGlubycsICdBc2lhbicsIAogICAgICAgICAgICAgICAnQW1lcmljYW4gSW5kaWFuJywgJ0hhd2FpaWFuL1BhY2lmaWMgSXNsYW5kZXInLCAnT3RoZXIvVW5rbm93bicpKQoKZGVtb19kZXNjIDwtIHJlYWRfY3N2KCdyZXN1bHRzL2RlbW9fcHJlbGltLmNzdicpICU+JSAKICBmaWx0ZXIoc2l0ZWlkICE9ICdTSVRFMTU3Jywgc2l0ZWlkICE9ICdTSVRFNzEyJykgJT4lIAogIG11dGF0ZShDb3VudHJ5ID0gZmN0X3JlbGV2ZWwoQ291bnRyeSwgY291bnRyaWVzKSkKCmRlbW9fcGVyYyA8LSBkZW1vX2Rlc2MgJT4lIAogIG11dGF0ZV9hdCh2YXJzKC0gbnVtX3BhdGllbnRzX2FsbCwgLSBzaXRlaWQsIC0gQ291bnRyeSwgLSBtZWRpYW5fYWdlKSwKICAgICAgICAgICAgbGlzdCh+IC4gLyAuZGF0YSRudW1fcGF0aWVudHNfYWxsKSkgJT4lIAogIG11dGF0ZShDb3VudHJ5ID0gYXMuZmFjdG9yKENvdW50cnkpKSAKCmRlbW9fcGVyYyAlPiUgCiAgcmVuYW1lKCdwZXJjX3BhdGllbnRzX2V2ZXJfc2V2ZXJlJyA9IG51bV9wYXRpZW50c19ldmVyX3NldmVyZSwKICAgICAgICAgJ3BlcmNfcGF0aWVudHNfbmV2ZXJfc2V2ZXJlJyA9IG51bV9wYXRpZW50c19uZXZlcl9zZXZlcmUpICU+JSAKICB3cml0ZV9jc3YoJ3Jlc3VsdHMvZGVtb2dyYXBoaWNzLmNzdicpCmBgYAoKIyMgT3ZlcmFsbCBzdGF0aXN0aWNzCmBgYHtyfQpkZW1vX2Rlc2MgJT4lIAogIHN1bW1hcmlzZShhY3Jvc3MoYyhudW1fcGF0aWVudHNfYWxsLCBmZW1hbGUsIG1hbGUsIHVua25vd25fb3RoZXJfc2V4KSwgc3VtKSkgCgpkZW1vX2Rlc2MgJT4lIAogIHN1bW1hcmlzZShhY3Jvc3MoYyhudW1fcGF0aWVudHNfYWxsLCByYWNlcywgdW5rbm93bl9vdGhlcl9yYWNlKSwgc3VtKSkgJT4lIAogIHByaW50KCkKCnVua25vd25zIDwtIGRlbW9fcGVyYyAlPiUKICBzZWxlY3Qoc2l0ZWlkLCBDb3VudHJ5LCBjb250YWlucygndW5rbm93bicpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKC0gYyhzaXRlaWQsIENvdW50cnkpKQp1bmtub3ducyAlPiUgZmlsdGVyKHZhbHVlIDwgMCkKdW5rbm93bnMgJT4lIGZpbHRlcih2YWx1ZSA8IDEsIHZhbHVlID4gMC4xKQoKIyB1bmtub3ducyAlPiUgCiMgICBnZ3Bsb3QoYWVzKHkgPSB2YWx1ZSwgeCA9IG5hbWUpKSArCiMgICBnZ2JlZXN3YXJtOjpnZW9tX2JlZXN3YXJtKCkgKwojICAgZmFjZXRfd3JhcCh+IG5hbWUsIHNjYWxlcyA9ICdmcmVlX3gnKQpgYGAKCiMjIFNldmVyaXR5IHZzLiBnZW5kZXIvYWdlL3JhY2U/CmBgYHtyfQpkZW1vX2dlbmRlciA8LSBkZW1vX3BlcmMgJT4lIGZpbHRlcih1bmtub3duX290aGVyX3NleCA8IDEpCmxtKG51bV9wYXRpZW50c19ldmVyX3NldmVyZSB+IGZlbWFsZSwgZGVtb19nZW5kZXIpICU+JSAKICBzdW1tYXJ5KCkKCmFnZV9wZXJjIDwtIGRlbW9fcGVyYyAlPiUgCiAgZmlsdGVyKHVua25vd25fb3RoZXJfYWdlX2dyb3VwIDwgMSkgJT4lIAogIHNlbGVjdChDb3VudHJ5LCBudW1fcGF0aWVudHNfYWxsLCBudW1fcGF0aWVudHNfZXZlcl9zZXZlcmUsIGNvbnRhaW5zKCd0bycpLCBlbmRzX3dpdGgoJ3BsdXMnKSkKCmxtKG51bV9wYXRpZW50c19ldmVyX3NldmVyZSB+IC4gLSBDb3VudHJ5IC0gbnVtX3BhdGllbnRzX2FsbCwgYWdlX3BlcmMpICU+JSAKICBzdW1tYXJ5KCkKCmxtKG51bV9wYXRpZW50c19ldmVyX3NldmVyZSB+IGJsYWNrICsgd2hpdGUgKyBhc2lhbiArIGhpc3BhbmljX2xhdGlubyArIAogICAgIGFtZXJpY2FuX2luZGlhbiArIGhhd2FpaWFuX3BhY2lmaWNfaXNsYW5kZXIsIAogICBkYXRhID0gZmlsdGVyKGRlbW9fcGVyYywgdW5rbm93bl9vdGhlcl9yYWNlIDwgMSkpICU+JSAKICBzdW1tYXJ5KCkKCmxtKG51bV9wYXRpZW50c19ldmVyX3NldmVyZSB+IG1lZGlhbl9hZ2UsIGRlbW9fcGVyYykgJT4lIAogIHN1bW1hcnkoKQpgYGAKCiMjIE92ZXJhbGwgcGxvdCAoQSkKCmBgYHtyfQpnZW5kZXJfY291bnQgPC0gZGVtb19kZXNjICU+JSAKICAjIGZpbHRlcih1bmtub3duX290aGVyX3NleC9udW1fcGF0aWVudHNfYWxsIDwgMSkgJT4lIAogICMgbXV0YXRlKHNpdGVpZCA9IGFzLmZhY3RvcihzaXRlaWQpKSAlPiUgCiAgIyBtdXRhdGUobnVtX3BhdGllbnRzX2FsbF9nZW5kZXIgPSBmZW1hbGUgKyBtYWxlKSAlPiUgCiAgZ3JvdXBfYnkoQ291bnRyeSkgJT4lIAogIHN1bW1hcmlzZShudW1fcGF0aWVudHNfY291bnRyeSA9IHN1bShudW1fcGF0aWVudHNfYWxsKSwKICAgICAgICAgICAgbWFsZV9jb3VudCA9IHN1bShtYWxlKSwKICAgICAgICAgICAgZmVtYWxlX2NvdW50ID0gc3VtKGZlbWFsZSksCiAgICAgICAgICAgIC5ncm91cHMgPSAnZHJvcCcpICU+JSAKICB7Ln0KCnNob3d0ZXh0OjpzaG93dGV4dF9hdXRvKCkKZmVtYWxlIDwtIGludFRvVXRmOCg5NzkyKQptYWxlIDwtIGludFRvVXRmOCg5Nzk0KQoKb3ZlcmFsbF9wbG90IDwtIGdlbmRlcl9jb3VudCAlPiUgCiAgbXV0YXRlKG1hbGVfY291bnQgPSAtbWFsZV9jb3VudCkgJT4lIAogIHBpdm90X2xvbmdlcigtIGMoQ291bnRyeSwgbnVtX3BhdGllbnRzX2NvdW50cnkpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JlbGV2ZWwoQ291bnRyeSwgcmV2KGNvdW50cmllcykpLCAKICAgICAgICAgICAgIHggPSB2YWx1ZSwgY29sb3IgPSBuYW1lLCAKICAgICAgICAgICAgIGZpbGwgPSBDb3VudHJ5KSkgKwogIGdlb21fY29sKHBvc2l0aW9uID0gJ2lkZW50aXR5JykgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd3aGl0ZScsICd3aGl0ZScpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoLTUwMDAsIC0yMDAwLCAwLCAyMDAwLCA1MDAwKSwKICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYyg1MDAwLCAyMDAwLCAwLCAyMDAwLCA1MDAwKSwKICAgICAgICAgICAgICAgICAgICAgdHJhbnMgPSBzc3FydF90cmFucykgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGNvbG9yID0gJ3doaXRlJykgKwogIGdlb21fdGV4dChkYXRhID0gLiAlPiUgZmlsdGVyKG5hbWUgPT0gJ21hbGVfY291bnQnKSwKICAgICAgICAgICAgYWVzKHkgPSBDb3VudHJ5LCB4ID0gdmFsdWUgLSAyMipzcXJ0KGFicyh2YWx1ZSkpLCAKICAgICAgICAgICAgICAgIGxhYmVsID0gYWJzKHZhbHVlKSksIGNvbG9yID0gJ2dyZXk0MCcsIHNpemUgPSAzKSArCiAgICBnZW9tX3RleHQoZGF0YSA9IC4gJT4lIGZpbHRlcihuYW1lID09ICdmZW1hbGVfY291bnQnKSwKICAgICAgICAgICAgYWVzKHkgPSBDb3VudHJ5LCB4ID0gdmFsdWUgKyAxOSpzcXJ0KGFicyh2YWx1ZSkpLCAKICAgICAgICAgICAgICAgIGxhYmVsID0gYWJzKHZhbHVlKSksIGNvbG9yID0gJ2dyZXk0MCcsIHNpemUgPSAzKSArCiAgZ2VvbV90ZXh0KGRhdGEgPSBmaWx0ZXIoZ2VuZGVyX2NvdW50LCBDb3VudHJ5ID09ICdGcmFuY2UnKSwKICAgICAgICAgICAgYWVzKHkgPSA2LCB4ID0gZmVtYWxlX2NvdW50IC0gNjAwKSwgZm9udGZhY2UgPSAyLAogICAgICAgICAgICBsYWJlbCA9IGZlbWFsZSwgc2l6ZSA9IDMsIGNvbG9yID0gJ3doaXRlJykgKwogIGdlb21fdGV4dChkYXRhID0gZmlsdGVyKGdlbmRlcl9jb3VudCwgQ291bnRyeSA9PSAnRnJhbmNlJyksCiAgICAgICAgICAgIGFlcyh5ID0gNiwgeCA9IC0gbWFsZV9jb3VudCArIDYwMCksIGZvbnRmYWNlID0gMiwKICAgICAgICAgICAgbGFiZWwgPSBtYWxlLCBzaXplID0gMywgY29sb3IgPSAnd2hpdGUnKSArCiAgbGFicyh5ID0gTlVMTCwgCiAgICAgICB4ID0gJ051bWJlciBvZiBtYWxlL2ZlbWFsZSBwYXRpZW50cyBwZXIgY291bnRyeScsIAogICAgICAgZmlsbCA9IE5VTEwpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvckJsaW5kR3JleTYpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAnTm9uZScsCiAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMTUsIDUuNSwgMTUuNSwgNTUuNSksCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5zcGFjaW5nLnkgPSB1bml0KDAsICdwdCcpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgc3RyaXAucGxhY2VtZW50ID0gJ2luc2lkZScsCiAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLmtleS5oZWlnaHQgPSB1bml0KDEsICdsaW5lJyksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCwgc2l6ZSA9IDkpKSArCiAgTlVMTApgYGAKCgoKIyMgQWdlIHBsb3QgKEIpCgpgYGB7cn0KYWdlX2NvdW50IDwtIGRlbW9fZGVzYyAlPiUgCiAgZmlsdGVyKHVua25vd25fb3RoZXJfYWdlX2dyb3VwL251bV9wYXRpZW50c19hbGwgPCAxKSAlPiUgCiAgc2VsZWN0KENvdW50cnksIG51bV9wYXRpZW50c19hbGwsIGNvbnRhaW5zKCd0bycpLCBlbmRzX3dpdGgoJ3BsdXMnKSkgJT4lIAogIGdyb3VwX2J5KENvdW50cnkpICU+JSAKICBzdW1tYXJpc2UoYWNyb3NzKC5mbnMgPSBzdW0pLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoLSBudW1fcGF0aWVudHNfYWxsLCAtIENvdW50cnkpLAogICAgICAgICAgICBsaXN0KH4gLiAvIC5kYXRhJG51bV9wYXRpZW50c19hbGwpKSAlPiUgCiAgc2VsZWN0KC1udW1fcGF0aWVudHNfYWxsKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKC0gQ291bnRyeSkgJT4lIAogIG11dGF0ZShuYW1lID0gY2FzZV93aGVuKAogICAgbmFtZSA9PSAnMDB0bzAyJyB+ICcwdG8yJywKICAgIG5hbWUgPT0gJzAzdG8wNScgfiAnM3RvNScsCiAgICBuYW1lID09ICcwNnRvMTEnIH4gJzZ0bzExJywKICAgIFRSVUUgfiBuYW1lCiAgKSkgJT4lIAogIG11dGF0ZShuYW1lID0gZ3N1YigndG8nLCAn4oCTJywgbmFtZSkgJT4lIGdzdWIoJ3BsdXMnLCAnKycsIC4pKQphZ2VfY291bnQkbmFtZSA8LSBmYWN0b3IoYWdlX2NvdW50JG5hbWUsIGxldmVscyA9IHVuaXF1ZShhZ2VfY291bnQkbmFtZSkpCgphZ2VfcGxvdCA8LSBhZ2VfY291bnQgICU+JSAKICBnZ3Bsb3QoYWVzKG5hbWUsIHZhbHVlLCBmaWxsID0gQ291bnRyeSwgZ3JvdXAgPSBDb3VudHJ5KSkgKwogIGdlb21fY29sKHBvc2l0aW9uID0gJ2RvZGdlMicpICsgCiAgY29vcmRfZmxpcCgpICsKICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKENvdW50cnkpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwKICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKDAsIDEsIDAuMiksCiAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGV4cGFuc2lvbihhZGQgPSBjKDAsMC4wMikpKSArCiAgc2NhbGVfc2l6ZV9jb250aW51b3VzKGd1aWRlID0gRkFMU0UpICsKICBsYWJzKHggPSBOVUxMLCB5ID0gJ1BhdGllbnRzIHByb3BvcnRpb24gcGVyIGFnZSBncm91cCcpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JCbGluZEdyZXk2LCBkcm9wID0gRkFMU0UpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvckJsaW5kR3JleTYsIGRyb3AgPSBGQUxTRSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICdOb25lJywKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gNyksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDE1LCA1LjUsIDUuNSwgNS41LCAncHQnKSkgKwogIE5VTEwKYGBgCgojIyBTZXZlcml0eSB2cy4gYWdlIHBsb3QgKEMpCgpgYGB7cn0KY291bnRyeV9jb2RlcyA8LSByZWFkX2NzdignaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2x1a2VzL0lTTy0zMTY2LUNvdW50cmllcy13aXRoLVJlZ2lvbmFsLUNvZGVzL21hc3Rlci9hbGwvYWxsLmNzdicpICU+JQogIG11dGF0ZShuYW1lID0gaWZlbHNlKG5hbWUgPT0gJ1VuaXRlZCBTdGF0ZXMgb2YgQW1lcmljYScsICdVU0EnLCBuYW1lKSkgJT4lCiAgZmlsdGVyKG5hbWUgJWluJSBjb3VudHJpZXMpICU+JQogIHNlbGVjdChDb3VudHJ5ID0gbmFtZSwgY291bl9jb2RlID0gYGFscGhhLTJgKSAlPiUKICBtdXRhdGUoY291bl9jb2RlID0gYXMuZmFjdG9yKGNvdW5fY29kZSkgJT4lIGZjdF9yZWxldmVsKGNvdW50cmllc19jb2RlKSkKCmFnZV9zZXZlcml0eSA8LSBkZW1vX3BlcmMgJT4lIAogIGxlZnRfam9pbihjb3VudHJ5X2NvZGVzLCBieSA9ICdDb3VudHJ5JykgJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5fYWdlLCBudW1fcGF0aWVudHNfZXZlcl9zZXZlcmUsIAogICAgICAgICAgICAgY29sb3IgPSBjb3VuX2NvZGUpKSArCiAgZ2VvbV9wb2ludChhZXMoc2l6ZSA9IG51bV9wYXRpZW50c19hbGwpLCBhbHBoYSA9IDAuOCkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCksCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHNlcSgwLCAxLCAwLjIpKSArCiAgbGFicyh4ID0gJ01lZGlhbiBhZ2UgZXN0aW1hdGUnLCAKICAgICAgIHkgPSAnU2V2ZXJlIGNhc2UgcHJvcG9ydGlvbicsIAogICAgICAgY29sb3IgPSBOVUxMKSArCiAgc2NhbGVfc2l6ZSh0cmFucyA9ICJsb2cxMCIsIGd1aWRlID0gRkFMU0UpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JCbGluZEdyZXk2KSArCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAsIDEpKSArCiAgdGhlbWUoCiAgICAjIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC45LCAwLjcpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gJ2xlZnQnLAogICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbig1LjUsIDUuNSwgMTAuNSwgMTUuNSksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLmtleS5oZWlnaHQgPSB1bml0KDAuNywgJ2xpbmUnKSwKICAgIGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDAuNCwgJ2xpbmUnKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAsIHNpemUgPSA5KSkgKwogIE5VTEwKYGBgCgojIyBSYWNlIHBsb3QgKEQpCgpgYGB7cn0KcmFjZV9jb3VudCA8LSBkZW1vX2Rlc2MgJT4lIAogIGZpbHRlcih1bmtub3duX290aGVyX3JhY2UvbnVtX3BhdGllbnRzX2FsbCA8IDEpICU+JSAKICBzZWxlY3QoQ291bnRyeSwgbnVtX3BhdGllbnRzX2FsbCwgYWxsX29mKHJhY2VzKSwgdW5rbm93bl9vdGhlcl9yYWNlKSAlPiUgCiAgZ3JvdXBfYnkoQ291bnRyeSkgJT4lIAogIHN1bW1hcmlzZShhY3Jvc3MoLmZucyA9IHN1bSksIC5ncm91cHMgPSAnZHJvcCcpICU+JSAKICBtdXRhdGVfYXQodmFycygtIG51bV9wYXRpZW50c19hbGwsIC0gQ291bnRyeSksCiAgICAgICAgICAgIGxpc3QofiAuIC8gLmRhdGEkbnVtX3BhdGllbnRzX2FsbCkpICU+JSAKICBzZWxlY3QoLW51bV9wYXRpZW50c19hbGwpICU+JSAKICBwaXZvdF9sb25nZXIoLSBDb3VudHJ5KSAlPiUgCiAgbXV0YXRlKG5hbWUgPSBnc3ViKCdfJywgJyAnLCBuYW1lKSAlPiUgCiAgICAgICAgICAgc3RyX3RvX3RpdGxlKC4pICU+JSAKICAgICAgICAgICBnc3ViKCdIaXNwYW5pYyAnLCAnSGlzcGFuaWMvJywgLikgJT4lIAogICAgICAgICAgIGdzdWIoJ0hhd2FpaWFuICcsICdIYXdhaWlhbi8nLCAuKSAlPiUgCiAgICAgICAgICAgZ3N1YignVW5rbm93biBPdGhlciBSYWNlJywgJ090aGVyL1Vua25vd24nLC4gKSwKICAgICAgICAgbmFtZSA9IGZjdF9yZWxldmVsKG5hbWUsIFJhY2VzKSkKCnJhY2VfcGxvdCA8LSByYWNlX2NvdW50ICU+JSAKICAjIHJlbW92ZSBvbmUgc2l0ZSBpbiBJdGFseSB0aGF0IHJlcG9ydGVkIGFsbCB3aGl0ZSBldGhuaWNpdHkKICBmaWx0ZXIoQ291bnRyeSAhPSAnSXRhbHknKSAlPiUgCiAgZ2dwbG90KGFlcyhuYW1lLCB2YWx1ZSwgZmlsbCA9IENvdW50cnksIGdyb3VwID0gQ291bnRyeSkpICsKICBnZW9tX2NvbChwb3NpdGlvbiA9ICdkb2RnZTInKSArIAogIGNvb3JkX2ZsaXAoKSArCiAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhDb3VudHJ5KSkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSksCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHNlcSgwLCAxLCAwLjIpLAogICAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBleHBhbnNpb24oYWRkID0gYygwLDAuMDIpKSkgKwogIHNjYWxlX3NpemVfY29udGludW91cyhndWlkZSA9IEZBTFNFKSArCiAgbGFicyh4ID0gTlVMTCwgeSA9ICdQYXRpZW50IHByb3BvcnRpb24gcGVyIHJhY2UvZXRobmljaXR5IGdyb3VwJykgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xvckJsaW5kR3JleTYsIGRyb3AgPSBGQUxTRSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG9yQmxpbmRHcmV5NiwgZHJvcCA9IEZBTFNFKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ05vbmUnLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjgpKSArCiAgTlVMTApgYGAKCiMjIENvbXBvc2l0ZSBwbG90CgpgYGB7ciBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9OCwgd2FybmluZz1GQUxTRX0KZ2VuZGVyX3JhY2UgPC0gcGxvdF9ncmlkKG92ZXJhbGxfcGxvdCwgYWdlX3NldmVyaXR5LCByYWNlX3Bsb3QsIG5jb2wgPSAxLAogICAgICAgICAgcmVsX2hlaWdodHMgPSBjKDAuNywgMSwgMSksIAogICAgICAgICAgbGFiZWxzID0gYygnQScsICdCJywgJ0MnKSwgYXhpcyA9ICdyJykKYWJjZCA8LSBwbG90X2dyaWQoZ2VuZGVyX3JhY2UsIGFnZV9wbG90LCBuY29sID0gMiwKICAgICAgICAgICAgICAgICAgcmVsX3dpZHRocyA9IGMoMS4yNSwgMSApLCBsYWJlbHMgPSBjKCcnLCAnRCcpLAogICAgICAgICAgICAgICAgICBheGlzID0gJ2InKQphYmNkCmdnc2F2ZSgnZmlncy9jb21wb3NpdGVfcGxvdC5wbmcnLCBhYmNkLCBoZWlnaHQgPSA2LjUsIHdpZHRoID0gOSkKZ2dzYXZlKCdmaWdzL3RpZmZzL2ZpZ18yLnRpZmYnLCBhYmNkLCBoZWlnaHQgPSA2LjUsIHdpZHRoID0gOSwgZHBpID0gMzAwKQpgYGAKCgoKCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMgZ2VuZGVyX3Bsb3QgPC0gZGVtb19nZW5kZXIgJT4lIAojICAgZ2dwbG90KGFlcyhmZW1hbGUsIG51bV9wYXRpZW50c19ldmVyX3NldmVyZSwgCiMgICAgICAgICAgICAgIGNvbG9yID0gQ291bnRyeSkpICsKIyAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAuNSwgbGluZXR5cGUgPSAnZGFzaGVkJykgKwojICAgZ2VvbV9wb2ludChhZXMoc2l6ZSA9IG51bV9wYXRpZW50c19hbGwpLCBhbHBoYSA9IDAuOCkgKwojICAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKIyAgICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDAsIDAuNjUpLAojICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGV4cGFuc2lvbihhZGQgPSBjKDAuMTgsIDApKSkgKwojICAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSwKIyAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoMCwgMSwgMC4yKSkgKwojICAgbGFicygKIyAgICAgeCA9ICdQcm9wb3J0aW9uIG9mIGZlbWFsZSBwYXRpZW50cycsIAojICAgICB5ID0gJ1Byb3BvcnRpb24gb2Ygc2V2ZXJlIGNhc2VzJywgCiMgICAgIGNvbG9yID0gTlVMTCwgCiMgICAgIHNpemUgPSAnVG90YWwgbnVtYmVyIG9mIHBhdGllbnRzCiMgYXQgZWFjaCBzaXRlJykgKwojICAgc2NhbGVfc2l6ZSh0cmFucyA9ICJsb2cxMCIsIGd1aWRlID0gRkFMU0UpICsKIyAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xvckJsaW5kR3JleTYpICsKIyAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4xNSwgMC4yOCksCiMgICAgICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbigxMC41LCA1LjUsIDUuNSwgNDUuNSwgJ3B0JyksCiMgICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKIyAgICAgICAgIGxlZ2VuZC5rZXkuaGVpZ2h0ID0gdW5pdCgxLCAnbGluZScpLAojICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCwgc2l6ZSA9IDkpKSArCiMgICBOVUxMCgojIGFnZV9yYWRhciA8LSBhZ2VfcGVyYyAlPiUgCiMgICBzZWxlY3QoLWNvbnRhaW5zKCdudW0nKSkgJT4lIAojICAgZ3JvdXBfYnkoQ291bnRyeSkgJT4lIAojICAgc3VtbWFyaXNlKGFjcm9zcyguZm5zID0gbWVhbl9zZSksIC5ncm91cHMgPSAnZHJvcCcpICU+JSAKIyAgIG11dGF0ZShDb3VudHJ5ID0gYXMuY2hhcmFjdGVyKENvdW50cnkpKSAlPiUgCiMgICByZW5hbWUoZ3JvdXAgPSBDb3VudHJ5KQojIAojIG10Y2FycyAlPiUKIyAgICAgIGFkZF9yb3duYW1lcyggdmFyID0gImdyb3VwIiApICU+JQojICAgICAgbXV0YXRlX2VhY2goZnVucyhyZXNjYWxlKSwgLWdyb3VwKSAlPiUKIyAgICAgIHRhaWwoNCkgJT4lIHNlbGVjdCgxOjEwKSAtPiBtdGNhcnNfcmFkYXIKIyAKIyBnZ3JhZGFyKGFnZV9yYWRhciwgCiMgICAgICAgICB2YWx1ZXMucmFkYXIgPSBjKE5BLCBwYXN0ZTAoYygyNSwgNTApLCAnJScpKSwKIyAgICAgICAgIGdyb3VwLmNvbG91cnMgPSBjb2xvckJsaW5kR3JleTZbLTRdLAojICAgICAgICAgZ3JpZC5taWQgPSAwLjI1LAojICAgICAgICAgZ3JpZC5tYXggPSAwLjUsCiMgICAgICAgICBiYXNlLnNpemUgPSAxKQoKIyBhZ2VfcGVyYyAlPiUgCiMgICBwaXZvdF9sb25nZXIoLSBjKENvdW50cnksIG51bV9wYXRpZW50c19hbGwsIG51bV9wYXRpZW50c19ldmVyX3NldmVyZSkpICU+JSAKIyAgIGdncGxvdChhZXModmFsdWUsIG51bV9wYXRpZW50c19ldmVyX3NldmVyZSwgCiMgICAgICAgICAgICAgIGNvbG9yID0gQ291bnRyeSkpICsKIyAgIGZhY2V0X3dyYXAofiBuYW1lKSArCiMgICBnZW9tX3BvaW50KGFlcyhzaXplID0gbG9nMihudW1fcGF0aWVudHNfYWxsKSksIGFscGhhID0gMC44KSArCiMgICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiMgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiMgICBzY2FsZV9zaXplX2NvbnRpbnVvdXMoZ3VpZGUgPSBGQUxTRSkgKwojICAgbGFicyh4ID0gJyUgcGF0aWVudHMgaW4gZWFjaCBhZ2UgZ3JvdXAnLCB5ID0gJyUgc2V2ZXJlIGNhc2VzJykgKwojICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9yQmxpbmRHcmV5NiwgZHJvcCA9IEZBTFNFKSArCiMgICBOVUxMCgojIGFnZV9wZXJjICU+JSAKIyAgIHBpdm90X2xvbmdlcigtIGMoQ291bnRyeSwgbnVtX3BhdGllbnRzX2FsbCwgbnVtX3BhdGllbnRzX2V2ZXJfc2V2ZXJlKSkgJT4lIAojICAgZ2dwbG90KGFlcyhuYW1lLCB2YWx1ZSwgY29sb3IgPSBDb3VudHJ5KSkgKwojICAgIyBmYWNldF9ncmlkKGNvbHMgPSB2YXJzKG5hbWUpLCBzY2FsZXMgPSAnZnJlZV94JykgKwojICAgZ2VvbV9ib3hwbG90KGFscGhhID0gMC44KSArCiMgICAjIGdlb21fdmlvbGluKGFlcyhjb2xvciA9IENvdW50cnkpKSArCiMgICAjIGdlb21faml0dGVyKCkgKwojICAgIyBnZW9tX3BvaW50KGFlcyhzaXplID0gbG9nMihudW1fcGF0aWVudHNfYWxsKSksIGFscGhhID0gMC44KSArCiMgICAjIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKIyAgICMgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwojICAgc2NhbGVfc2l6ZV9jb250aW51b3VzKGd1aWRlID0gRkFMU0UpICsKIyAgIGxhYnMoeCA9ICclIHBhdGllbnRzIGluIGVhY2ggYWdlIGdyb3VwJywgeSA9ICclIHBhdGllbnQnKSArCiMgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JCbGluZEdyZXk2LCBkcm9wID0gRkFMU0UpICsKIyAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG9yQmxpbmRHcmV5NiwgZHJvcCA9IEZBTFNFKSArCiMgICBjb29yZF9wb2xhcigpICsKIyAgIE5VTEwKIyAKIyByYWNlX3BlcmMgJT4lIAojICAgcGl2b3RfbG9uZ2VyKC0gYyhDb3VudHJ5LCBudW1fcGF0aWVudHNfYWxsLCBudW1fcGF0aWVudHNfZXZlcl9zZXZlcmUpKSAlPiUgCiMgICBnZ3Bsb3QoYWVzKHZhbHVlLCBudW1fcGF0aWVudHNfZXZlcl9zZXZlcmUsIAojICAgICAgICAgICAgICBjb2xvciA9IENvdW50cnkpKSArCiMgICBmYWNldF93cmFwKH4gbmFtZSkgKwojICAgZ2VvbV9wb2ludChhZXMoc2l6ZSA9IGxvZzIobnVtX3BhdGllbnRzX2FsbCkpLCBhbHBoYSA9IDAuOCkgKwojICAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAwLjEpKSArCiMgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDAuMSkpICsKIyAgIHNjYWxlX3NpemVfY29udGludW91cyhndWlkZSA9IEZBTFNFKSArCiMgICBsYWJzKHggPSAnJSBwYXRpZW50cyBpbiBlYWNoIHJhY2UvZXRobmljaXR5IGdyb3VwJywgeSA9ICclIHNldmVyZSBjYXNlcycpICsKIyAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xvckJsaW5kR3JleTYsIGRyb3AgPSBGQUxTRSwgZ3VpZGUgPSBGQUxTRSkgKwojICAgTlVMTAojIAojIHJhY2VfcGVyYyAlPiUgCiMgICBwaXZvdF9sb25nZXIoLSBjKENvdW50cnksIG51bV9wYXRpZW50c19hbGwsIG51bV9wYXRpZW50c19ldmVyX3NldmVyZSkpICU+JSAKIyAgIGdncGxvdChhZXMobmFtZSwgdmFsdWUsIGNvbG9yID0gQ291bnRyeSkpICsKIyAgICMgZmFjZXRfd3JhcCh+IG5hbWUpICsKIyAgICMgZ2VvbV9wb2ludChhZXMoc2l6ZSA9IGxvZzIobnVtX3BhdGllbnRzX2FsbCkpLCBhbHBoYSA9IDAuOCkgKwojICAgZ2VvbV9ib3hwbG90KCkgKwojICAgIyBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDAuMSkpICsKIyAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMC4xKSkgKwojICAgc2NhbGVfc2l6ZV9jb250aW51b3VzKGd1aWRlID0gRkFMU0UpICsKIyAgIGxhYnMoeCA9ICclIHBhdGllbnRzIGluIGVhY2ggcmFjZS9ldGhuaWNpdHkgZ3JvdXAnLCB5ID0gJyUgc2V2ZXJlIGNhc2VzJykgKwojICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9yQmxpbmRHcmV5NiwgZHJvcCA9IEZBTFNFLCBndWlkZSA9IEZBTFNFKSArCiMgICBOVUxMCmBgYAo=