This is the supplementary material to an invited commentary for Basole et al. (2021). We provide all code that are used to generate the figures in the commentary in addition to other supplementary figures (and its code).

List of figures

Code to load library and data
library(tidyverse)
library(ggtext)
library(patchwork)
library(readxl)
library(nullabor)
library(here)
library(janitor)
library(scales)
df_full <- read_xlsx(here("data/MaskedCoverage-Fig3.xlsx")) %>% 
  clean_names() %>% 
  add_row(state = c("OR", "WY", "SD", "WV", "DC", "AL")) %>% 
  mutate(row = case_when(
    state %in% c("ME") ~ 1L,
    state %in% c("VT", "NH") ~ 2L,
    state %in% c("WA", "ID", "MT", "ND", "MN", "IL", "WI", "MI", "NY", "RI", "MA") ~ 3L,
    state %in% c("OR", "NV", "WY", "SD", "IA", "IN", "OH", "PA", "NJ", "CT") ~ 4L,
    state %in% c("CA", "UT", "CO", "NE", "MO", "KY", "WV", "VA", "MD", "DE") ~ 5L,
    state %in% c("AZ", "NM", "KS", "AR", "TN", "NC", "SC", "DC") ~ 6L,
    state %in% c("OK", "LA", "MS", "AL", "GA") ~ 7L,
    state %in% c("TX", "FL") ~ 8L,
                         TRUE ~ 0L),
    col = case_when(
      state %in% c("WA", "OR", "CA") ~ 1L,
      state %in% c("ID", "NV", "UT", "AZ") ~ 2L,
      state %in% c("MT", "WY", "CO", "NM") ~ 3L,
      state %in% c("ND", "SD", "NE", "KS", "OK", "TX") ~ 4L,
      state %in% c("MN", "IA", "MO", "AR", "LA") ~ 5L,
      state %in% c("IL", "IN", "KY", "TN", "MS") ~ 6L,
      state %in% c("WI", "OH", "WV", "NC", "AL") ~ 7L,
      state %in% c("MI", "PA", "VA", "SC", "GA") ~ 8L,
      state %in% c("NY", "NJ", "MD", "DC", "FL") ~ 9L,
      state %in% c("VT", "RI", "CT", "DE") ~ 10L,
      state %in% c("ME", "NH", "MA") ~ 11L,
      TRUE ~ 0L
    ))

df_miss <- df_full %>% 
  filter(!is.na(readmission_rate))
g1 <- df_miss %>% 
  mutate(y = readmission_rate * 100) %>% 
  ggplot(aes(col, row)) +
  geom_point(aes(size = coverage_obscured, color = y), alpha = 0.8) +
  geom_text(aes(label = percent(y/100, 0.01)), nudge_y = -0.1, size = 2.5) +
  labs(color = "Readmission Rate", size = "Coverage") +
  scale_color_gradient2(low = "#3F6E9A", high = "#AB4C30", midpoint = median(df_miss$readmission_rate * 100), mid = "#ffffe0") +
  theme_void() +
  geom_text(data = df_full, aes(label = state), color = "black", nudge_y = 0.05) +
  scale_size(range = c(3, 30)) +
  scale_y_reverse() +
  theme(plot.margin = margin(r = 30))

g2 <- g1 %+% mutate(df_miss, y = colorectal_cancer_screenings) + 
  scale_color_gradient2(low = "#3F6E9A", high = "#AB4C30", midpoint = median(df_miss$colorectal_cancer_screenings), mid = "#ffffe0") +
  labs(color = "Cancer Screening Rate")

g1 + g2 + plot_layout(guides = "collect") 
This figure recreates Figure 3 in Basole et al. (2021) using the ggplot2 R-package (Wickham 2016). The code is displayed above by clicking on the CODE button just above the right corner of this plot.

Figure S1: This figure recreates Figure 3 in Basole et al. (2021) using the ggplot2 R-package (Wickham 2016). The code is displayed above by clicking on the CODE button just above the right corner of this plot.

theme_set(theme_classic())
g1 <- ggplot(df_miss, aes(coverage_obscured * 100, readmission_rate * 100)) +
  geom_point() +
  labs(x = "Coverage (%)", y = "Readmission (%)") +
  geom_smooth(method = loess, formula = y ~ x) +
  annotate("richtext", x = 80, y = 15.3, label.color = NA, fill = "transparent", label = glue::glue("R<sup>2</sup> = {scales::comma(cor(df_miss$coverage_obscured, df_miss$readmission_rate)^2, 0.001)}")) 

g2 <- ggplot(df_miss, aes(coverage_obscured * 100, colorectal_cancer_screenings)) +
  geom_point() +
  labs(x = "Coverage (%)", y = "Cancer Screening (%)") +
  geom_smooth(method = loess, formula = y ~ x) +
  annotate("richtext", x = 80, y = 73, label.color = NA, fill = "transparent", label = glue::glue("R<sup>2</sup> = {scales::comma(cor(df_miss$coverage_obscured, df_miss$colorectal_cancer_screenings)^2, 0.001)}")) 


g1 + g2 
The above figure show an alternative plot design to display the information in Figure S1 and is the same figure as Figure 1 in the main paper. The plot shows a scatter plot of percentage of readmission and coverage on the left and a scatter plot of percentage of cancer screening and coverage on the right. Both plots are superimposed by a local polynomial regression (displayed as a blue line) with confidence interval for the line (displayed in gray). The code is displayed above by clicking on the CODE button just above the right corner of this plot.

Figure S2: The above figure show an alternative plot design to display the information in Figure S1 and is the same figure as Figure 1 in the main paper. The plot shows a scatter plot of percentage of readmission and coverage on the left and a scatter plot of percentage of cancer screening and coverage on the right. Both plots are superimposed by a local polynomial regression (displayed as a blue line) with confidence interval for the line (displayed in gray). The code is displayed above by clicking on the CODE button just above the right corner of this plot.

set.seed(2021)
lineup_data <- null_permute("colorectal_cancer_screenings") %>% 
  lineup(true = df_miss, n = 20, pos = 3)
plot_lineup_theirs <- ggplot(lineup_data, aes(col, row)) +
  geom_point(aes(size = coverage_obscured, color = colorectal_cancer_screenings), alpha = 0.8) +
  theme_void() + 
  scale_color_gradient2(low = "#3F6E9A", high = "#AB4C30", midpoint = median(df_miss$colorectal_cancer_screenings), mid = "#ffffe0") +
  scale_size(range = c(1, 5)) +
  scale_y_reverse(expand = c(0.1, 0.2))  +
  guides(color = "none", size = "none") + 
  facet_wrap(~.sample, ncol = 5) +
  scale_x_continuous(expand = c(0.1, 0.1)) + 
  theme(legend.position = "bottom",
        strip.text = element_text(size = 18, margin = margin(t = 3, b = 3)),
        strip.background = element_rect(color = "black", size = 1.5))

plot_lineup_theirs
The above figure shows a lineup for this tile grid plot where one of the plots is made using the data, and the other nineteen plots are constructed after first permuting the percentage of cancer screening across different states with the missing value structure is preserved. Text and legends have been removed to minimise the bias in reading plots due to the reader being aware of the context. Which plot strikes the most different to you? The code is displayed above by clicking on the CODE button just above the right corner of this plot. Try the other lineups before finding the data plot position at the bottom of this document.

Figure S3: The above figure shows a lineup for this tile grid plot where one of the plots is made using the data, and the other nineteen plots are constructed after first permuting the percentage of cancer screening across different states with the missing value structure is preserved. Text and legends have been removed to minimise the bias in reading plots due to the reader being aware of the context. Which plot strikes the most different to you? The code is displayed above by clicking on the CODE button just above the right corner of this plot. Try the other lineups before finding the data plot position at the bottom of this document.

plot_lineup_ours <- ggplot(lineup_data, aes(coverage_obscured * 100, colorectal_cancer_screenings)) +
  geom_point() +  
  geom_smooth(method = loess, formula = y ~ x) +
  facet_wrap(~.sample, ncol = 5) +
  scale_x_continuous(expand = c(0.1, 0.1)) + 
  theme(legend.position = "bottom",
        strip.text = element_text(size = 18, margin = margin(t = 3, b = 3)),
        strip.background = element_rect(color = "black", size = 1.5),
        axis.text = element_blank(),
        axis.title = element_blank(),
        axis.line = element_blank(),
        axis.ticks.length = unit(0, "pt"))

plot_lineup_ours
The above figure shows a lineup for the scatter plot design used in Figure S2. The same data used to create Figure S3 (including the null data) is used to create this lineup. The code is displayed above by clicking on the CODE button just above the right corner of this plot. When you are ready, find the position of the data plot is revealed at the bottom of this document.

Figure S4: The above figure shows a lineup for the scatter plot design used in Figure S2. The same data used to create Figure S3 (including the null data) is used to create this lineup. The code is displayed above by clicking on the CODE button just above the right corner of this plot. When you are ready, find the position of the data plot is revealed at the bottom of this document.

Same plots with higher associations between variables

The following are plots based on data that purposely modifies cancer screening to induce a higher association with the coverage. This higher association is induced (as shown in the code below) by rearranging data by the coverage and modifying the cancer screening percentage so that it is ordered from low to high.

df_false <- df_miss %>% 
  arrange(coverage_obscured) %>% 
  mutate(colorectal_cancer_screenings = sort(colorectal_cancer_screenings))

lineup_false_data <- null_permute("colorectal_cancer_screenings") %>% 
  lineup(true = df_false, n = 20, pos = 5)
plot_lineup_theirs %+% lineup_false_data
The above shows a lineup for the tile grid plot design where the data was purposely manipulated to induce a higher association between the variables of interest. Which plot looks the most strikingly different to you? Try the next lineup to see if you can find the data plot before finding the position of the data plot here.

Figure S5: The above shows a lineup for the tile grid plot design where the data was purposely manipulated to induce a higher association between the variables of interest. Which plot looks the most strikingly different to you? Try the next lineup to see if you can find the data plot before finding the position of the data plot here.

plot_lineup_ours %+% lineup_false_data
The above shows a lineup for the scatter plot design with the data that was purposely manipulated so that two variables mapped to the \(x\)-axis and \(y\)-axis have a higher association. How easy was it to spot the data plot compared to Figure S5? You can find the code to generate the above lineup plot by collapsing all codes.

Figure S6: The above shows a lineup for the scatter plot design with the data that was purposely manipulated so that two variables mapped to the \(x\)-axis and \(y\)-axis have a higher association. How easy was it to spot the data plot compared to Figure S5? You can find the code to generate the above lineup plot by collapsing all codes.

Positions of the data plot

The positions of the data plot for the lineup are as follows:

We expect that you would have struggled to find the data plto in Figure S3 and Figure S4 as we do not observe strong association between the cancer screening rate and coverage. Additionally, we expect that most would spot the data plot in Figure S5 and all would spot the data plot in Figure S6. For those that spot the data plot in Figure S5, we suspect it took longer than spotting the data plot in Figure S6.

Acknowledgement

We thank Basole et al. (2021) for supplying us the synthetic data to draw the above plots.

Reference

Session Information
sessioninfo::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────
##  setting  value                       
##  version  R version 4.0.1 (2020-06-06)
##  os       macOS  10.16                
##  system   x86_64, darwin17.0          
##  ui       X11                         
##  language (EN)                        
##  collate  en_AU.UTF-8                 
##  ctype    en_AU.UTF-8                 
##  tz       Australia/Melbourne         
##  date     2021-10-19                  
## 
## ─ Packages ───────────────────────────────────────────────────────────────────
##  package     * version date       lib source                           
##  assertthat    0.2.1   2019-03-21 [2] CRAN (R 4.0.0)                   
##  backports     1.2.1   2020-12-09 [1] CRAN (R 4.0.2)                   
##  bookdown      0.22.17 2021-08-07 [1] Github (rstudio/bookdown@9615b14)
##  broom         0.7.9   2021-07-27 [1] CRAN (R 4.0.2)                   
##  bslib         0.3.0   2021-09-02 [1] CRAN (R 4.0.2)                   
##  cellranger    1.1.0   2016-07-27 [2] CRAN (R 4.0.0)                   
##  class         7.3-19  2021-05-03 [2] CRAN (R 4.0.2)                   
##  cli           3.0.1   2021-07-17 [1] CRAN (R 4.0.2)                   
##  cluster       2.1.2   2021-04-17 [2] CRAN (R 4.0.2)                   
##  colorspace    2.0-2   2021-06-24 [1] CRAN (R 4.0.2)                   
##  crayon        1.4.1   2021-02-08 [1] CRAN (R 4.0.2)                   
##  DBI           1.1.1   2021-01-15 [1] CRAN (R 4.0.2)                   
##  dbplyr        2.1.1   2021-04-06 [1] CRAN (R 4.0.2)                   
##  DEoptimR      1.0-8   2016-11-19 [2] CRAN (R 4.0.0)                   
##  digest        0.6.28  2021-09-23 [1] CRAN (R 4.0.2)                   
##  diptest       0.76-0  2021-05-04 [2] CRAN (R 4.0.2)                   
##  dplyr       * 1.0.7   2021-06-18 [1] CRAN (R 4.0.2)                   
##  ellipsis      0.3.2   2021-04-29 [1] CRAN (R 4.0.2)                   
##  evaluate      0.14    2019-05-28 [2] CRAN (R 4.0.0)                   
##  fansi         0.5.0   2021-05-25 [1] CRAN (R 4.0.2)                   
##  farver        2.1.0   2021-02-28 [1] CRAN (R 4.0.2)                   
##  fastmap       1.1.0   2021-01-25 [1] CRAN (R 4.0.2)                   
##  flexmix       2.3-17  2020-10-12 [1] CRAN (R 4.0.2)                   
##  forcats     * 0.5.1   2021-01-27 [1] CRAN (R 4.0.2)                   
##  fpc           2.2-9   2020-12-06 [2] CRAN (R 4.0.2)                   
##  fs            1.5.0   2020-07-31 [1] CRAN (R 4.0.2)                   
##  generics      0.1.0   2020-10-31 [2] CRAN (R 4.0.2)                   
##  ggplot2     * 3.3.5   2021-06-25 [1] CRAN (R 4.0.2)                   
##  ggtext      * 0.1.1   2020-12-17 [1] CRAN (R 4.0.2)                   
##  glue          1.4.2   2020-08-27 [1] CRAN (R 4.0.2)                   
##  gridtext      0.1.4   2020-12-10 [1] CRAN (R 4.0.2)                   
##  gtable        0.3.0   2019-03-25 [2] CRAN (R 4.0.0)                   
##  haven         2.4.1   2021-04-23 [2] CRAN (R 4.0.2)                   
##  here        * 1.0.1   2020-12-13 [2] CRAN (R 4.0.2)                   
##  highr         0.9     2021-04-16 [2] CRAN (R 4.0.2)                   
##  hms           1.1.1   2021-09-26 [1] CRAN (R 4.0.2)                   
##  htmltools     0.5.2   2021-08-25 [1] CRAN (R 4.0.2)                   
##  httr          1.4.2   2020-07-20 [1] CRAN (R 4.0.2)                   
##  janitor     * 2.1.0   2021-01-05 [2] CRAN (R 4.0.2)                   
##  jquerylib     0.1.4   2021-04-26 [1] CRAN (R 4.0.2)                   
##  jsonlite      1.7.2   2020-12-09 [1] CRAN (R 4.0.2)                   
##  kernlab       0.9-29  2019-11-12 [2] CRAN (R 4.0.0)                   
##  knitr         1.34    2021-09-09 [1] CRAN (R 4.0.2)                   
##  labeling      0.4.2   2020-10-20 [1] CRAN (R 4.0.2)                   
##  lattice       0.20-44 2021-05-02 [2] CRAN (R 4.0.2)                   
##  lifecycle     1.0.1   2021-09-24 [1] CRAN (R 4.0.2)                   
##  lubridate     1.7.10  2021-02-26 [1] CRAN (R 4.0.2)                   
##  magrittr      2.0.1   2020-11-17 [1] CRAN (R 4.0.2)                   
##  markdown      1.1     2019-08-07 [2] CRAN (R 4.0.0)                   
##  MASS          7.3-54  2021-05-03 [1] CRAN (R 4.0.2)                   
##  Matrix        1.3-3   2021-05-04 [2] CRAN (R 4.0.2)                   
##  mclust        5.4.7   2020-11-20 [2] CRAN (R 4.0.2)                   
##  mgcv          1.8-35  2021-04-18 [2] CRAN (R 4.0.2)                   
##  modelr        0.1.8   2020-05-19 [2] CRAN (R 4.0.0)                   
##  modeltools    0.2-23  2020-03-05 [2] CRAN (R 4.0.0)                   
##  moments       0.14    2015-01-05 [2] CRAN (R 4.0.0)                   
##  munsell       0.5.0   2018-06-12 [2] CRAN (R 4.0.0)                   
##  nlme          3.1-152 2021-02-04 [2] CRAN (R 4.0.2)                   
##  nnet          7.3-16  2021-05-03 [2] CRAN (R 4.0.2)                   
##  nullabor    * 0.3.9   2020-02-25 [1] CRAN (R 4.0.2)                   
##  patchwork   * 1.1.1   2020-12-17 [1] CRAN (R 4.0.2)                   
##  pillar        1.6.3   2021-09-26 [1] CRAN (R 4.0.1)                   
##  pkgconfig     2.0.3   2019-09-22 [2] CRAN (R 4.0.0)                   
##  prabclus      2.3-2   2020-01-08 [2] CRAN (R 4.0.0)                   
##  purrr       * 0.3.4   2020-04-17 [2] CRAN (R 4.0.0)                   
##  R6            2.5.1   2021-08-19 [1] CRAN (R 4.0.1)                   
##  Rcpp          1.0.7   2021-07-07 [1] CRAN (R 4.0.2)                   
##  readr       * 2.0.1   2021-08-10 [1] CRAN (R 4.0.2)                   
##  readxl      * 1.3.1   2019-03-13 [2] CRAN (R 4.0.0)                   
##  reprex        2.0.0   2021-04-02 [1] CRAN (R 4.0.2)                   
##  rlang         0.4.11  2021-04-30 [1] CRAN (R 4.0.2)                   
##  rmarkdown     2.11    2021-09-14 [1] CRAN (R 4.0.2)                   
##  robustbase    0.93-7  2021-01-04 [2] CRAN (R 4.0.2)                   
##  rprojroot     2.0.2   2020-11-15 [1] CRAN (R 4.0.2)                   
##  rstudioapi    0.13    2020-11-12 [1] CRAN (R 4.0.1)                   
##  rvest         1.0.1   2021-07-26 [1] CRAN (R 4.0.2)                   
##  sass          0.4.0   2021-05-12 [1] CRAN (R 4.0.2)                   
##  scales      * 1.1.1   2020-05-11 [2] CRAN (R 4.0.0)                   
##  sessioninfo   1.1.1   2018-11-05 [2] CRAN (R 4.0.0)                   
##  snakecase     0.11.0  2019-05-25 [2] CRAN (R 4.0.0)                   
##  stringi       1.7.4   2021-08-25 [1] CRAN (R 4.0.2)                   
##  stringr     * 1.4.0   2019-02-10 [2] CRAN (R 4.0.0)                   
##  tibble      * 3.1.5   2021-09-30 [1] CRAN (R 4.0.2)                   
##  tidyr       * 1.1.3   2021-03-03 [1] CRAN (R 4.0.2)                   
##  tidyselect    1.1.1   2021-04-30 [1] CRAN (R 4.0.2)                   
##  tidyverse   * 1.3.1   2021-04-15 [1] CRAN (R 4.0.2)                   
##  tzdb          0.1.2   2021-07-20 [1] CRAN (R 4.0.2)                   
##  utf8          1.2.2   2021-07-24 [1] CRAN (R 4.0.2)                   
##  vctrs         0.3.8   2021-04-29 [1] CRAN (R 4.0.2)                   
##  withr         2.4.2   2021-04-18 [1] CRAN (R 4.0.2)                   
##  xfun          0.26    2021-09-14 [1] CRAN (R 4.0.2)                   
##  xml2          1.3.2   2020-04-23 [2] CRAN (R 4.0.0)                   
##  yaml          2.2.1   2020-02-01 [1] CRAN (R 4.0.2)                   
## 
## [1] /Users/etan0038/Library/R/4.0/library
## [2] /Library/Frameworks/R.framework/Versions/4.0/Resources/library


Basole, Rahul C., Elliot Bendoly, Aravind Chandrasekaran, and Kevin Linderman. 2021. “Visualization in Operations Management Research.” INFORMS Journal on Data Science (to appear).
Wickham, Hadley. 2016. Ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York. https://doi.org/10.1007/978-0-387-98141-3.
LS0tCnRpdGxlOiAiU3VwcGxlbWVudGFyeSBtYXRlcmlhbCBmb3IgXCJJbmNvcnBvcmF0aW5nIHN0YXRpc3RpY2FsIHRoaW5raW5nIGludG8gdmlzdWFsaXNhdGlvbiBwcmFjdGljZXMgZm9yIGRlY2lzaW9uLW1ha2luZyBpbiBvcGVyYXRpb25hbCBtYW5hZ2VtZW50XCIiCmF1dGhvcjoKICAtIG5hbWU6IEVtaSBUYW5ha2EKICAgIGFmZmlsaWF0aW9uOiBEZXBhcnRtZW50IG9mIEVjb25vbWV0cmljcyBhbmQgQnVzaW5lc3MgU3RhdGlzdGljcywgTW9uYXNoIFVuaXZlcnNpdHksIE1lbGJvdXJuZSwgVklDIDM4MDAKICAgIGVtYWlsOiBlbWkudGFuYWthQG1vbmFzaC5lZHUKICAtIG5hbWU6IEplc3NpY2EgV2FpIFlpbiBMZXVuZwogICAgYWZmaWxpYXRpb246IERlcGFydG1lbnQgb2YgRWNvbm9tZXRyaWNzIGFuZCBCdXNpbmVzcyBTdGF0aXN0aWNzLCBNb25hc2ggVW5pdmVyc2l0eSwgTWVsYm91cm5lLCBWSUMgMzgwMAogICAgZW1haWw6IGplc3NpY2EubGV1bmdAbW9uYXNoLmVkdQogIC0gbmFtZTogRGlhbm5lIENvb2sKICAgIGFmZmlsaWF0aW9uOiBEZXBhcnRtZW50IG9mIEVjb25vbWV0cmljcyBhbmQgQnVzaW5lc3MgU3RhdGlzdGljcywgTW9uYXNoIFVuaXZlcnNpdHksIE1lbGJvdXJuZSwgVklDIDM4MDAKICAgIGVtYWlsOiBkaWNvb2tAbW9uYXNoLmVkdQpiaWJsaW9ncmFwaHk6IHJlZmVyZW5jZXMuYmliIApvdXRwdXQ6CiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgY29kZV9mb2xkaW5nOiAiaGlkZSIKICAgIHRoZW1lOiAicGFwZXIiCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCi0tLQoKClRoaXMgaXMgdGhlIHN1cHBsZW1lbnRhcnkgbWF0ZXJpYWwgdG8gYW4gaW52aXRlZCBjb21tZW50YXJ5IGZvciBAYmFzb2xlMjAyMS4gV2UgcHJvdmlkZSBhbGwgY29kZSB0aGF0IGFyZSB1c2VkIHRvIGdlbmVyYXRlIHRoZSBmaWd1cmVzIGluIHRoZSBjb21tZW50YXJ5IGluIGFkZGl0aW9uIHRvIG90aGVyIHN1cHBsZW1lbnRhcnkgZmlndXJlcyAoYW5kIGl0cyBjb2RlKS4gCgoKPHVsIGNsYXNzPSJmYS11bCI+CiAgPGxpPjxzcGFuIGNsYXNzPSJmYS1saSI+PGkgY2xhc3M9ImZhcyBmYS1jb2RlIj48L2k+PC9zcGFuPiBUbyBzZWUgdGhlIGNvZGUsIGNsaWNrIG9uIHRoZSBDT0RFIGJ1dHRvbi4gPC9saT4KICA8bGk+PHNwYW4gY2xhc3M9ImZhLWxpIj48aSBjbGFzcz0iZmFzIGZhLWRvd25sb2FkIj48L2k+PC9zcGFuPiBZb3UgY2FuIGFsc28gZG93bmxvYWQgdGhlIHdob2xlIFIgTWFya2Rvd24gZmlsZSBmcm9tIHRoZSBkcm9wIGRvd24gbWVudSBvbiB0aGUgdG9wIHJpZ2h0IGNvcm5lci48L2xpPgogIDxsaT48c3BhbiBjbGFzcz0iZmEtbGkiPjxpIGNsYXNzPSJmYWIgZmEtZ2l0aHViIj48L2k+PC9zcGFuPiBUaGUgR2l0SHViIHJlcG8gZm9yIHRoaXMgbWF0ZXJpYWwgY2FuIGJlIGZvdW5kIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9lbWl0YW5ha2Evc3VwcC12aXNPTS4gPC9saT4KPC91bD4KCioqTGlzdCBvZiBmaWd1cmVzKiogCgoqIFtGaWd1cmUgUzFdKCNmaWc6bWltaWMtb3JpZ2luYWwpOiBSZWNyZWF0aW5nIEZpZ3VyZSAzIG9mIEBiYXNvbGUyMDIxIHVzaW5nIGBnZ3Bsb3QyYC4gCiogW0ZpZ3VyZSBTMl0oI2ZpZzpmaWczLWFsdCk6IEFuIGFsdGVybmF0aXZlIGRlc2lnbiB0byBGaWd1cmUgMyBvZiBAYmFzb2xlMjAyMS4KKiBbRmlndXJlIFMzXSgjZmlnOmxpbmV1cC10aGVpcnMpOiBMaW5ldXAgZm9yIHRoZSB0aWxlIGdyaWQgcGxvdCB1c2VkIGluIEZpZ3VyZSAzIG9mIEBiYXNvbGUyMDIxLgoqIFtGaWd1cmUgUzRdKCNmaWc6bGluZXVwLW91cnMpOiBMaW5ldXAgZm9yIHRoZSBzY2F0dGVyIHBsb3QuIAoqIFtGaWd1cmUgUzVdKCNmaWc6bGluZXVwLXRoZWlycy1mYWxzZSk6IExpbmV1cCBmb3IgdGhlIHRpbGUgZ3JpZCBwbG90IG9uIGRhdGEgd2l0aCBwdXJwb3NlbHkgaGlnaCBhc3NvY2lhdGlvbi4KKiBbRmlndXJlIFM2XSgjZmlnOmxpbmV1cC1vdXJzLWZhbHNlKTogTGluZXVwIGZvciB0aGUgc2NhdHRlciBwbG90IG9uIGRhdGEgd2l0aCBwdXJwb3NlbHkgaGlnaCBhc3NvY2lhdGlvbi4KCjxkZXRhaWxzPgo8c3VtbWFyeT5Db2RlIHRvIGxvYWQgbGlicmFyeSBhbmQgZGF0YTwvc3VtbWFyeT4KYGBge3Igc2V0dXAsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBjbGFzcy5zb3VyY2UgPSAnZm9sZC1zaG93J30KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2d0ZXh0KQpsaWJyYXJ5KHBhdGNod29yaykKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkobnVsbGFib3IpCmxpYnJhcnkoaGVyZSkKbGlicmFyeShqYW5pdG9yKQpsaWJyYXJ5KHNjYWxlcykKYGBgCgpgYGB7ciBrbml0ci1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQpodG1sdG9vbHM6OnRhZ0xpc3Qocm1hcmtkb3duOjpodG1sX2RlcGVuZGVuY3lfZm9udF9hd2Vzb21lKCkpCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcucGF0aCA9ICJpbWFnZXMvIiwKICAgICAgICAgICAgICAgICAgICAgIGRldiA9IGMoInBuZyIsICJwZGYiLCAic3ZnIiksCiAgICAgICAgICAgICAgICAgICAgICBjYWNoZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgY2FjaGUucGF0aCA9ICJjYWNoZS8iLAogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFKQpvcHRpb25zKGtuaXRyLmR1cGxpY2F0ZS5sYWJlbCA9ICJhbGxvdyIpCmBgYAoKCgpgYGB7ciBkYXRhLCBjbGFzcy5zb3VyY2UgPSAnZm9sZC1zaG93J30KZGZfZnVsbCA8LSByZWFkX3hsc3goaGVyZSgiZGF0YS9NYXNrZWRDb3ZlcmFnZS1GaWczLnhsc3giKSkgJT4lIAogIGNsZWFuX25hbWVzKCkgJT4lIAogIGFkZF9yb3coc3RhdGUgPSBjKCJPUiIsICJXWSIsICJTRCIsICJXViIsICJEQyIsICJBTCIpKSAlPiUgCiAgbXV0YXRlKHJvdyA9IGNhc2Vfd2hlbigKICAgIHN0YXRlICVpbiUgYygiTUUiKSB+IDFMLAogICAgc3RhdGUgJWluJSBjKCJWVCIsICJOSCIpIH4gMkwsCiAgICBzdGF0ZSAlaW4lIGMoIldBIiwgIklEIiwgIk1UIiwgIk5EIiwgIk1OIiwgIklMIiwgIldJIiwgIk1JIiwgIk5ZIiwgIlJJIiwgIk1BIikgfiAzTCwKICAgIHN0YXRlICVpbiUgYygiT1IiLCAiTlYiLCAiV1kiLCAiU0QiLCAiSUEiLCAiSU4iLCAiT0giLCAiUEEiLCAiTkoiLCAiQ1QiKSB+IDRMLAogICAgc3RhdGUgJWluJSBjKCJDQSIsICJVVCIsICJDTyIsICJORSIsICJNTyIsICJLWSIsICJXViIsICJWQSIsICJNRCIsICJERSIpIH4gNUwsCiAgICBzdGF0ZSAlaW4lIGMoIkFaIiwgIk5NIiwgIktTIiwgIkFSIiwgIlROIiwgIk5DIiwgIlNDIiwgIkRDIikgfiA2TCwKICAgIHN0YXRlICVpbiUgYygiT0siLCAiTEEiLCAiTVMiLCAiQUwiLCAiR0EiKSB+IDdMLAogICAgc3RhdGUgJWluJSBjKCJUWCIsICJGTCIpIH4gOEwsCiAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gMEwpLAogICAgY29sID0gY2FzZV93aGVuKAogICAgICBzdGF0ZSAlaW4lIGMoIldBIiwgIk9SIiwgIkNBIikgfiAxTCwKICAgICAgc3RhdGUgJWluJSBjKCJJRCIsICJOViIsICJVVCIsICJBWiIpIH4gMkwsCiAgICAgIHN0YXRlICVpbiUgYygiTVQiLCAiV1kiLCAiQ08iLCAiTk0iKSB+IDNMLAogICAgICBzdGF0ZSAlaW4lIGMoIk5EIiwgIlNEIiwgIk5FIiwgIktTIiwgIk9LIiwgIlRYIikgfiA0TCwKICAgICAgc3RhdGUgJWluJSBjKCJNTiIsICJJQSIsICJNTyIsICJBUiIsICJMQSIpIH4gNUwsCiAgICAgIHN0YXRlICVpbiUgYygiSUwiLCAiSU4iLCAiS1kiLCAiVE4iLCAiTVMiKSB+IDZMLAogICAgICBzdGF0ZSAlaW4lIGMoIldJIiwgIk9IIiwgIldWIiwgIk5DIiwgIkFMIikgfiA3TCwKICAgICAgc3RhdGUgJWluJSBjKCJNSSIsICJQQSIsICJWQSIsICJTQyIsICJHQSIpIH4gOEwsCiAgICAgIHN0YXRlICVpbiUgYygiTlkiLCAiTkoiLCAiTUQiLCAiREMiLCAiRkwiKSB+IDlMLAogICAgICBzdGF0ZSAlaW4lIGMoIlZUIiwgIlJJIiwgIkNUIiwgIkRFIikgfiAxMEwsCiAgICAgIHN0YXRlICVpbiUgYygiTUUiLCAiTkgiLCAiTUEiKSB+IDExTCwKICAgICAgVFJVRSB+IDBMCiAgICApKQoKZGZfbWlzcyA8LSBkZl9mdWxsICU+JSAKICBmaWx0ZXIoIWlzLm5hKHJlYWRtaXNzaW9uX3JhdGUpKQpgYGAKPC9kZXRhaWxzPgoKKHJlZjptaW1pY2FyeSkgVGhpcyBmaWd1cmUgcmVjcmVhdGVzIEZpZ3VyZSAzIGluIEBiYXNvbGUyMDIxIHVzaW5nIHRoZSBgZ2dwbG90MmAgUi1wYWNrYWdlIFtAZ2dwbG90Ml0uIFRoZSBjb2RlIGlzIGRpc3BsYXllZCBhYm92ZSBieSBjbGlja2luZyBvbiB0aGUgQ09ERSBidXR0b24ganVzdCBhYm92ZSB0aGUgcmlnaHQgY29ybmVyIG9mIHRoaXMgcGxvdC4KCmBgYHtyIG1pbWljLW9yaWdpbmFsLCBmaWcuaGVpZ2h0ID0gOCwgZmlnLndpZHRoID0gMTgsIGZpZy5jYXAgPSAiKHJlZjptaW1pY2FyeSkifSAgICAgICAgICAgCmcxIDwtIGRmX21pc3MgJT4lIAogIG11dGF0ZSh5ID0gcmVhZG1pc3Npb25fcmF0ZSAqIDEwMCkgJT4lIAogIGdncGxvdChhZXMoY29sLCByb3cpKSArCiAgZ2VvbV9wb2ludChhZXMoc2l6ZSA9IGNvdmVyYWdlX29ic2N1cmVkLCBjb2xvciA9IHkpLCBhbHBoYSA9IDAuOCkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50KHkvMTAwLCAwLjAxKSksIG51ZGdlX3kgPSAtMC4xLCBzaXplID0gMi41KSArCiAgbGFicyhjb2xvciA9ICJSZWFkbWlzc2lvbiBSYXRlIiwgc2l6ZSA9ICJDb3ZlcmFnZSIpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93ID0gIiMzRjZFOUEiLCBoaWdoID0gIiNBQjRDMzAiLCBtaWRwb2ludCA9IG1lZGlhbihkZl9taXNzJHJlYWRtaXNzaW9uX3JhdGUgKiAxMDApLCBtaWQgPSAiI2ZmZmZlMCIpICsKICB0aGVtZV92b2lkKCkgKwogIGdlb21fdGV4dChkYXRhID0gZGZfZnVsbCwgYWVzKGxhYmVsID0gc3RhdGUpLCBjb2xvciA9ICJibGFjayIsIG51ZGdlX3kgPSAwLjA1KSArCiAgc2NhbGVfc2l6ZShyYW5nZSA9IGMoMywgMzApKSArCiAgc2NhbGVfeV9yZXZlcnNlKCkgKwogIHRoZW1lKHBsb3QubWFyZ2luID0gbWFyZ2luKHIgPSAzMCkpCgpnMiA8LSBnMSAlKyUgbXV0YXRlKGRmX21pc3MsIHkgPSBjb2xvcmVjdGFsX2NhbmNlcl9zY3JlZW5pbmdzKSArIAogIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiIzNGNkU5QSIsIGhpZ2ggPSAiI0FCNEMzMCIsIG1pZHBvaW50ID0gbWVkaWFuKGRmX21pc3MkY29sb3JlY3RhbF9jYW5jZXJfc2NyZWVuaW5ncyksIG1pZCA9ICIjZmZmZmUwIikgKwogIGxhYnMoY29sb3IgPSAiQ2FuY2VyIFNjcmVlbmluZyBSYXRlIikKCmcxICsgZzIgKyBwbG90X2xheW91dChndWlkZXMgPSAiY29sbGVjdCIpIApgYGAKCihyZWY6ZmlnMy1hbHQpIFRoZSBhYm92ZSBmaWd1cmUgc2hvdyBhbiBhbHRlcm5hdGl2ZSBwbG90IGRlc2lnbiB0byBkaXNwbGF5IHRoZSBpbmZvcm1hdGlvbiBpbiBbRmlndXJlIFMxXSgjZmlnOm1pbWljLW9yaWdpbmFsKSBhbmQgaXMgdGhlIHNhbWUgZmlndXJlIGFzIEZpZ3VyZSAxIGluIHRoZSBtYWluIHBhcGVyLiBUaGUgcGxvdCBzaG93cyBhIHNjYXR0ZXIgcGxvdCBvZiBwZXJjZW50YWdlIG9mIHJlYWRtaXNzaW9uIGFuZCBjb3ZlcmFnZSBvbiB0aGUgbGVmdCBhbmQgYSBzY2F0dGVyIHBsb3Qgb2YgcGVyY2VudGFnZSBvZiBjYW5jZXIgc2NyZWVuaW5nIGFuZCBjb3ZlcmFnZSBvbiB0aGUgcmlnaHQuIEJvdGggcGxvdHMgYXJlIHN1cGVyaW1wb3NlZCBieSBhIGxvY2FsIHBvbHlub21pYWwgcmVncmVzc2lvbiAoZGlzcGxheWVkIGFzIGEgYmx1ZSBsaW5lKSB3aXRoIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSBsaW5lIChkaXNwbGF5ZWQgaW4gZ3JheSkuIFRoZSBjb2RlIGlzIGRpc3BsYXllZCBhYm92ZSBieSBjbGlja2luZyBvbiB0aGUgQ09ERSBidXR0b24ganVzdCBhYm92ZSB0aGUgcmlnaHQgY29ybmVyIG9mIHRoaXMgcGxvdC4KIApgYGB7ciBmaWczLWFsdCwgZmlnLmhlaWdodCA9IDQsIGZpZy53aWR0aCA9IDgsIGZpZy5jYXAgPSAiKHJlZjpmaWczLWFsdCkifQp0aGVtZV9zZXQodGhlbWVfY2xhc3NpYygpKQpnMSA8LSBnZ3Bsb3QoZGZfbWlzcywgYWVzKGNvdmVyYWdlX29ic2N1cmVkICogMTAwLCByZWFkbWlzc2lvbl9yYXRlICogMTAwKSkgKwogIGdlb21fcG9pbnQoKSArCiAgbGFicyh4ID0gIkNvdmVyYWdlICglKSIsIHkgPSAiUmVhZG1pc3Npb24gKCUpIikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9IGxvZXNzLCBmb3JtdWxhID0geSB+IHgpICsKICBhbm5vdGF0ZSgicmljaHRleHQiLCB4ID0gODAsIHkgPSAxNS4zLCBsYWJlbC5jb2xvciA9IE5BLCBmaWxsID0gInRyYW5zcGFyZW50IiwgbGFiZWwgPSBnbHVlOjpnbHVlKCJSPHN1cD4yPC9zdXA+ID0ge3NjYWxlczo6Y29tbWEoY29yKGRmX21pc3MkY292ZXJhZ2Vfb2JzY3VyZWQsIGRmX21pc3MkcmVhZG1pc3Npb25fcmF0ZSleMiwgMC4wMDEpfSIpKSAKCmcyIDwtIGdncGxvdChkZl9taXNzLCBhZXMoY292ZXJhZ2Vfb2JzY3VyZWQgKiAxMDAsIGNvbG9yZWN0YWxfY2FuY2VyX3NjcmVlbmluZ3MpKSArCiAgZ2VvbV9wb2ludCgpICsKICBsYWJzKHggPSAiQ292ZXJhZ2UgKCUpIiwgeSA9ICJDYW5jZXIgU2NyZWVuaW5nICglKSIpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSBsb2VzcywgZm9ybXVsYSA9IHkgfiB4KSArCiAgYW5ub3RhdGUoInJpY2h0ZXh0IiwgeCA9IDgwLCB5ID0gNzMsIGxhYmVsLmNvbG9yID0gTkEsIGZpbGwgPSAidHJhbnNwYXJlbnQiLCBsYWJlbCA9IGdsdWU6OmdsdWUoIlI8c3VwPjI8L3N1cD4gPSB7c2NhbGVzOjpjb21tYShjb3IoZGZfbWlzcyRjb3ZlcmFnZV9vYnNjdXJlZCwgZGZfbWlzcyRjb2xvcmVjdGFsX2NhbmNlcl9zY3JlZW5pbmdzKV4yLCAwLjAwMSl9IikpIAoKCmcxICsgZzIgCmBgYAoKYGBge3IgbGluZXVwLWRhdGF9CnNldC5zZWVkKDIwMjEpCmxpbmV1cF9kYXRhIDwtIG51bGxfcGVybXV0ZSgiY29sb3JlY3RhbF9jYW5jZXJfc2NyZWVuaW5ncyIpICU+JSAKICBsaW5ldXAodHJ1ZSA9IGRmX21pc3MsIG4gPSAyMCwgcG9zID0gMykKYGBgCgoocmVmOmxpbmV1cC10aGVpcnMpIFRoZSBhYm92ZSBmaWd1cmUgc2hvd3MgYSBsaW5ldXAgZm9yIHRoaXMgdGlsZSBncmlkIHBsb3Qgd2hlcmUgb25lIG9mIHRoZSBwbG90cyBpcyBtYWRlIHVzaW5nIHRoZSBkYXRhLCBhbmQgdGhlIG90aGVyIG5pbmV0ZWVuIHBsb3RzIGFyZSBjb25zdHJ1Y3RlZCBhZnRlciBmaXJzdCBwZXJtdXRpbmcgdGhlIHBlcmNlbnRhZ2Ugb2YgY2FuY2VyIHNjcmVlbmluZyBhY3Jvc3MgZGlmZmVyZW50IHN0YXRlcyB3aXRoIHRoZSBtaXNzaW5nIHZhbHVlIHN0cnVjdHVyZSBpcyBwcmVzZXJ2ZWQuIFRleHQgYW5kIGxlZ2VuZHMgaGF2ZSBiZWVuIHJlbW92ZWQgdG8gbWluaW1pc2UgdGhlIGJpYXMgaW4gcmVhZGluZyBwbG90cyBkdWUgdG8gdGhlIHJlYWRlciBiZWluZyBhd2FyZSBvZiB0aGUgY29udGV4dC4gKipXaGljaCBwbG90IHN0cmlrZXMgdGhlIG1vc3QgZGlmZmVyZW50IHRvIHlvdT8qKiAgVGhlIGNvZGUgaXMgZGlzcGxheWVkIGFib3ZlIGJ5IGNsaWNraW5nIG9uIHRoZSBDT0RFIGJ1dHRvbiBqdXN0IGFib3ZlIHRoZSByaWdodCBjb3JuZXIgb2YgdGhpcyBwbG90LiBUcnkgdGhlIG90aGVyIGxpbmV1cHMgYmVmb3JlIGZpbmRpbmcgdGhlIGRhdGEgcGxvdCBwb3NpdGlvbiBhdCB0aGUgYm90dG9tIG9mIHRoaXMgZG9jdW1lbnQuCgpgYGB7ciBsaW5ldXAtdGhlaXJzLCBmaWcuaGVpZ2h0ID0gMTAsIGZpZy53aWR0aCA9IDEwLCBmaWcuY2FwID0gIihyZWY6bGluZXVwLXRoZWlycykifQpwbG90X2xpbmV1cF90aGVpcnMgPC0gZ2dwbG90KGxpbmV1cF9kYXRhLCBhZXMoY29sLCByb3cpKSArCiAgZ2VvbV9wb2ludChhZXMoc2l6ZSA9IGNvdmVyYWdlX29ic2N1cmVkLCBjb2xvciA9IGNvbG9yZWN0YWxfY2FuY2VyX3NjcmVlbmluZ3MpLCBhbHBoYSA9IDAuOCkgKwogIHRoZW1lX3ZvaWQoKSArIAogIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiIzNGNkU5QSIsIGhpZ2ggPSAiI0FCNEMzMCIsIG1pZHBvaW50ID0gbWVkaWFuKGRmX21pc3MkY29sb3JlY3RhbF9jYW5jZXJfc2NyZWVuaW5ncyksIG1pZCA9ICIjZmZmZmUwIikgKwogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDEsIDUpKSArCiAgc2NhbGVfeV9yZXZlcnNlKGV4cGFuZCA9IGMoMC4xLCAwLjIpKSAgKwogIGd1aWRlcyhjb2xvciA9ICJub25lIiwgc2l6ZSA9ICJub25lIikgKyAKICBmYWNldF93cmFwKH4uc2FtcGxlLCBuY29sID0gNSkgKwogIHNjYWxlX3hfY29udGludW91cyhleHBhbmQgPSBjKDAuMSwgMC4xKSkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCwgbWFyZ2luID0gbWFyZ2luKHQgPSAzLCBiID0gMykpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMS41KSkKCnBsb3RfbGluZXVwX3RoZWlycwpgYGAKCihyZWY6bGluZXVwLW91cnMpIFRoZSBhYm92ZSBmaWd1cmUgc2hvd3MgYSBsaW5ldXAgZm9yIHRoZSBzY2F0dGVyIHBsb3QgZGVzaWduIHVzZWQgaW4gW0ZpZ3VyZSBTMl0oI2ZpZzpmaWczLWFsdCkuIFRoZSBzYW1lIGRhdGEgdXNlZCB0byBjcmVhdGUgW0ZpZ3VyZSBTM10oI2ZpZzpsaW5ldXAtdGhlaXJzKSAoaW5jbHVkaW5nIHRoZSBudWxsIGRhdGEpIGlzIHVzZWQgdG8gY3JlYXRlIHRoaXMgbGluZXVwLiBUaGUgY29kZSBpcyBkaXNwbGF5ZWQgYWJvdmUgYnkgY2xpY2tpbmcgb24gdGhlIENPREUgYnV0dG9uIGp1c3QgYWJvdmUgdGhlIHJpZ2h0IGNvcm5lciBvZiB0aGlzIHBsb3QuIFdoZW4geW91IGFyZSByZWFkeSwgZmluZCB0aGUgcG9zaXRpb24gb2YgdGhlIGRhdGEgcGxvdCBpcyByZXZlYWxlZCBhdCB0aGUgW2JvdHRvbSBvZiB0aGlzIGRvY3VtZW50XSgjcG9zaXRpb24pLgoKYGBge3IgbGluZXVwLW91cnMsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoID0gMTAsIGZpZy5jYXAgPSAiKHJlZjpsaW5ldXAtb3VycykifQpwbG90X2xpbmV1cF9vdXJzIDwtIGdncGxvdChsaW5ldXBfZGF0YSwgYWVzKGNvdmVyYWdlX29ic2N1cmVkICogMTAwLCBjb2xvcmVjdGFsX2NhbmNlcl9zY3JlZW5pbmdzKSkgKwogIGdlb21fcG9pbnQoKSArICAKICBnZW9tX3Ntb290aChtZXRob2QgPSBsb2VzcywgZm9ybXVsYSA9IHkgfiB4KSArCiAgZmFjZXRfd3JhcCh+LnNhbXBsZSwgbmNvbCA9IDUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLjEsIDAuMSkpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIG1hcmdpbiA9IG1hcmdpbih0ID0gMywgYiA9IDMpKSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEuNSksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MubGVuZ3RoID0gdW5pdCgwLCAicHQiKSkKCnBsb3RfbGluZXVwX291cnMKYGBgCgoKCiMgU2FtZSBwbG90cyB3aXRoIGhpZ2hlciBhc3NvY2lhdGlvbnMgYmV0d2VlbiB2YXJpYWJsZXMKClRoZSBmb2xsb3dpbmcgYXJlIHBsb3RzIGJhc2VkIG9uIGRhdGEgdGhhdCBwdXJwb3NlbHkgbW9kaWZpZXMgY2FuY2VyIHNjcmVlbmluZyB0byBpbmR1Y2UgYSBoaWdoZXIgYXNzb2NpYXRpb24gd2l0aCB0aGUgY292ZXJhZ2UuIFRoaXMgaGlnaGVyIGFzc29jaWF0aW9uIGlzIGluZHVjZWQgKGFzIHNob3duIGluIHRoZSBjb2RlIGJlbG93KSBieSByZWFycmFuZ2luZyBkYXRhIGJ5IHRoZSBjb3ZlcmFnZSBhbmQgbW9kaWZ5aW5nIHRoZSBjYW5jZXIgc2NyZWVuaW5nIHBlcmNlbnRhZ2Ugc28gdGhhdCBpdCBpcyBvcmRlcmVkIGZyb20gbG93IHRvIGhpZ2guIAoKYGBge3IgZGF0YS1mYWxzZSwgY2xhc3Muc291cmNlPSJmb2xkLXNob3cifQpkZl9mYWxzZSA8LSBkZl9taXNzICU+JSAKICBhcnJhbmdlKGNvdmVyYWdlX29ic2N1cmVkKSAlPiUgCiAgbXV0YXRlKGNvbG9yZWN0YWxfY2FuY2VyX3NjcmVlbmluZ3MgPSBzb3J0KGNvbG9yZWN0YWxfY2FuY2VyX3NjcmVlbmluZ3MpKQoKbGluZXVwX2ZhbHNlX2RhdGEgPC0gbnVsbF9wZXJtdXRlKCJjb2xvcmVjdGFsX2NhbmNlcl9zY3JlZW5pbmdzIikgJT4lIAogIGxpbmV1cCh0cnVlID0gZGZfZmFsc2UsIG4gPSAyMCwgcG9zID0gNSkKYGBgCgoocmVmOmxpbmV1cC10aGVpcnMtZmFsc2UpIFRoZSBhYm92ZSBzaG93cyBhIGxpbmV1cCBmb3IgdGhlIHRpbGUgZ3JpZCBwbG90IGRlc2lnbiB3aGVyZSB0aGUgZGF0YSB3YXMgcHVycG9zZWx5IG1hbmlwdWxhdGVkIHRvIGluZHVjZSBhIGhpZ2hlciBhc3NvY2lhdGlvbiBiZXR3ZWVuIHRoZSB2YXJpYWJsZXMgb2YgaW50ZXJlc3QuIFdoaWNoIHBsb3QgbG9va3MgdGhlIG1vc3Qgc3RyaWtpbmdseSBkaWZmZXJlbnQgdG8geW91PyBUcnkgdGhlIG5leHQgbGluZXVwIHRvIHNlZSBpZiB5b3UgY2FuIGZpbmQgdGhlIGRhdGEgcGxvdCBiZWZvcmUgZmluZGluZyB0aGUgcG9zaXRpb24gb2YgdGhlIGRhdGEgcGxvdCBbaGVyZV0oI3Bvc2l0aW9uKS4KCmBgYHtyIGxpbmV1cC10aGVpcnMtZmFsc2UsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoID0gMTAsIGZpZy5jYXAgPSAiKHJlZjpsaW5ldXAtdGhlaXJzLWZhbHNlKSJ9CnBsb3RfbGluZXVwX3RoZWlycyAlKyUgbGluZXVwX2ZhbHNlX2RhdGEKYGBgCgoocmVmOmxpbmV1cC1vdXJzLWZhbHNlKSBUaGUgYWJvdmUgc2hvd3MgYSBsaW5ldXAgZm9yIHRoZSBzY2F0dGVyIHBsb3QgZGVzaWduIHdpdGggdGhlIGRhdGEgdGhhdCB3YXMgcHVycG9zZWx5IG1hbmlwdWxhdGVkIHNvIHRoYXQgdHdvIHZhcmlhYmxlcyBtYXBwZWQgdG8gdGhlICR4JC1heGlzIGFuZCAkeSQtYXhpcyBoYXZlIGEgaGlnaGVyIGFzc29jaWF0aW9uLiBIb3cgZWFzeSB3YXMgaXQgdG8gc3BvdCB0aGUgZGF0YSBwbG90IGNvbXBhcmVkIHRvIFtGaWd1cmUgUzVdKCNmaWc6bGluZXVwLXRoZWlycy1mYWxzZSk/IFlvdSBjYW4gZmluZCB0aGUgY29kZSB0byBnZW5lcmF0ZSB0aGUgYWJvdmUgbGluZXVwIHBsb3QgYnkgY29sbGFwc2luZyBhbGwgY29kZXMuIAoKYGBge3IgbGluZXVwLW91cnMtZmFsc2UsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoID0gMTAsIGZpZy5jYXAgPSAiKHJlZjpsaW5ldXAtb3Vycy1mYWxzZSkifQpwbG90X2xpbmV1cF9vdXJzICUrJSBsaW5ldXBfZmFsc2VfZGF0YQpgYGAKCiMgUG9zaXRpb25zIG9mIHRoZSBkYXRhIHBsb3QgeyNwb3NpdGlvbn0KClRoZSBwb3NpdGlvbnMgb2YgdGhlIGRhdGEgcGxvdCBmb3IgdGhlIGxpbmV1cCBhcmUgYXMgZm9sbG93czoKCiogW0ZpZ3VyZSBTM10oI2ZpZzpsaW5ldXAtdGhlaXJzKTogcG9zaXRpb24gMy4gCiogW0ZpZ3VyZSBTNF0oI2ZpZzpsaW5ldXAtb3Vycyk6IHBvc2l0aW9uIDMuIAoqIFtGaWd1cmUgUzVdKCNmaWc6bGluZXVwLXRoZWlycy1mYWxzZSk6IHBvc2l0aW9uIDUuIAoqIFtGaWd1cmUgUzZdKCNmaWc6bGluZXVwLW91cnMtZmFsc2UpOiBwb3NpdGlvbiA1LiAKCldlIGV4cGVjdCB0aGF0IHlvdSB3b3VsZCBoYXZlIHN0cnVnZ2xlZCB0byBmaW5kIHRoZSBkYXRhIHBsdG8gaW4gW0ZpZ3VyZSBTM10oI2ZpZzpsaW5ldXAtdGhlaXJzKSBhbmQgW0ZpZ3VyZSBTNF0oI2ZpZzpsaW5ldXAtb3VycykgYXMgd2UgZG8gbm90IG9ic2VydmUgc3Ryb25nIGFzc29jaWF0aW9uIGJldHdlZW4gdGhlIGNhbmNlciBzY3JlZW5pbmcgcmF0ZSBhbmQgY292ZXJhZ2UuIEFkZGl0aW9uYWxseSwgd2UgZXhwZWN0IHRoYXQgbW9zdCB3b3VsZCBzcG90IHRoZSBkYXRhIHBsb3QgaW4gW0ZpZ3VyZSBTNV0oI2ZpZzpsaW5ldXAtdGhlaXJzLWZhbHNlKSBhbmQgYWxsIHdvdWxkIHNwb3QgdGhlIGRhdGEgcGxvdCBpbiBbRmlndXJlIFM2XSgjZmlnOmxpbmV1cC1vdXJzLWZhbHNlKS4gRm9yIHRob3NlIHRoYXQgc3BvdCB0aGUgZGF0YSBwbG90IGluIFtGaWd1cmUgUzVdKCNmaWc6bGluZXVwLXRoZWlycy1mYWxzZSksIHdlIHN1c3BlY3QgaXQgdG9vayBsb25nZXIgdGhhbiBzcG90dGluZyB0aGUgZGF0YSBwbG90IGluIFtGaWd1cmUgUzZdKCNmaWc6bGluZXVwLW91cnMtZmFsc2UpLiAKCiMgQWNrbm93bGVkZ2VtZW50IAoKV2UgdGhhbmsgQGJhc29sZTIwMjEgZm9yIHN1cHBseWluZyB1cyB0aGUgc3ludGhldGljIGRhdGEgdG8gZHJhdyB0aGUgYWJvdmUgcGxvdHMuIAoKIyBSZWZlcmVuY2UKCjxkZXRhaWxzPgo8c3VtbWFyeT5TZXNzaW9uIEluZm9ybWF0aW9uPC9zdW1tYXJ5PgpgYGB7ciBzZXNzaW9uLWluZm99CnNlc3Npb25pbmZvOjpzZXNzaW9uX2luZm8oKQpgYGAKPC9kZXRhaWxzPgoKICAKPGJyPgoKCmBgYHtyIGNvcHktZm9yLXBhcGVyLCBpbmNsdWRlID0gRkFMU0V9CiMgdGhpcyBjaHVuayBtdXN0IGJlIHRoZSBsYXN0IG9uZQpmczo6ZmlsZV9jb3B5KCJpbWFnZXMvZmlnMy1hbHQtMS5wZGYiLCAicGFwZXIvIiwgb3ZlcndyaXRlID0gVFJVRSkKZnM6OmZpbGVfY29weSgiaW1hZ2VzL2xpbmV1cC10aGVpcnMtMS5wZGYiLCAicGFwZXIvIiwgb3ZlcndyaXRlID0gVFJVRSkKIyBleHRyYWN0IGFsbCB0aGUgUiBjb2RlIAprbml0cjo6cHVybCgiaW5kZXguUm1kIiwKICAgICAgICAgICAgZG9jdW1lbnRhdGlvbiA9IDEpCmZzOjpmaWxlX21vdmUoImluZGV4LlIiLCAiY29kZS9wbG90cy5SIikKIyByZW1vdmUgdGhpcyBjaHVuayBhbmQgdGhlIGtuaXRyIHNldHVwIGZyb20gdGhlIG91dHB1dCBSIGNvZGUKZiA8LSByZWFkTGluZXMoImNvZGUvcGxvdHMuUiIpCmkxIDwtIHdoaWNoKHN0cl9kZXRlY3QoZiwgIl4jIyAtLS0ta25pdHItc2V0dXAiKSkKY2h1bmtfaW5kZXhlcyA8LSB3aGljaChzdHJfZGV0ZWN0KGYsICJeIyMgLS0tLSIpKQpqMSA8LSBjaHVua19pbmRleGVzW2NodW5rX2luZGV4ZXMgPiBpMV1bMV0gLSAxCiAgCmkyIDwtIG1heCh3aGljaChzdHJfZGV0ZWN0KGYsICJeIyMgLS0tLWNvcHktZm9yLXBhcGVyIikpKQpqMiA8LSBsZW5ndGgoZikKb3V0IDwtIGZbLWMoaTE6ajEsIGkyOmoyKV0Kd3JpdGVMaW5lcyhvdXQsICJjb2RlL3Bsb3RzLlIiKQpgYGAKCg==