knitr::opts_chunk$set(message=FALSE,warning=FALSE,dpi=300,fig.retina=2,fig.width=8)
source(here::here("src/common_basis.R"))
library(plotly)

Society-aligned output by member through time

In the following, we

  1. first calculate for each member the number of society-related printings they have a substantive relationship to,
  2. limit only to members for whom we have a time of admission (earliest estimate), and
  3. plot each such member on the graph with x=time of their admission and y=number of society-related printings contributed to.
  4. Further, we calculate a loess-smoothed average for the number of printings contributed to per member through time.

Overall

periods <- tribble(~period,~start_year,~end_year,
                   "Köthen", 1617L, 1650L,
                   "Weimar", 1651L, 1662L,
                   "Halle", 1667L, 1680L
)

p_to_a %>%
  inner_join(fbs_purpose_related_p) %>%
  inner_join(a_id_to_fbs_member_number) %>%
  filter(
    field_code %in% c("028A", "028B", "028C"),
    is.na(role) | !role %in% c("ctb", "dte"), # normed role has to be unknown or not one of these
    is.na(role2) | !str_detect(role2, !!!str_flatten(c( # role2 should not be one of these
      "^Adressat",
      "Erwähnte",
      "Gefeierte",
      "Mitglied eines Ausschusses, der akademische Grade vergibt",
      "Normerlassende Gebietskörperschaft",
      "Praeses",
      "Respondent",
      "Sonstige Person, Familie und Körperschaft",
      "Verfasser",
      "Vertragspartner",
      "Widmende",
      "Widmungsempfänger",
      "Drucker",
      "Zensor",
      "Beiträger",
      "GeistigeR Schöpfer",
      "Mitwirkender",
      "Herausgeber",
      "Angeklagte",
      "Auftraggeber"
    ), collapse = "|^"))
  ) %>%
  inner_join(fbs_metadata) %>%
  filter(field_code %in% c("028A", "028B") | is.na(rank_and_position) | !str_detect(rank_and_position,"graf|herzog|fürst")) %>%
  group_by(member_number) %>%
  summarise(works=n_distinct(p_id)) %>%
  right_join(fbs_metadata) %>%
  collect() %>%
  complete(nesting(member_number,earliest_year_of_admission),fill=list(works=0)) %>%
  inner_join(periods,join_by(earliest_year_of_admission>=start_year,earliest_year_of_admission<=end_year)) %>%
  mutate(label=str_c(member_number,": ",family_name,", ", first_name)) %>%
  ggplot(aes(x=earliest_year_of_admission,y=works)) +
  scale_x_continuous(breaks=seq(1600,1700,by=10)) +
  ylab("Mean contributions per member joining (N)") +
  xlab("Year of admission") +
  geom_smooth(span=0.3) +
  geom_point(data=. %>% group_by(period, earliest_year_of_admission) %>% summarise(works=mean(works))) +
  scale_y_continuous(breaks=seq(0,20,by=2)) +
  theme_hsci_discrete() +
  theme(legend.position = "bottom") +
  coord_cartesian(ylim=c(0,NA))
Joining with `by = join_by(p_id)`Joining with `by = join_by(a_id)`Joining with `by = join_by(member_number)`Joining with `by = join_by(member_number)`

periods <- tribble(~start_year,~end_year,~period,
1617L,1623L, "Köthen",
1624L,1630L, "Köthen",
1631L,1637L, "Köthen",
1638L,1644L, "Köthen",
1644L,1650L, "Köthen",
1651L,1656L, "Weimar",
1657L,1662L, "Weimar",
1667L,1673L, "Halle",
1674L,1680L, "Halle"
) %>% mutate(period_range=factor(str_c(start_year,"-",end_year)))

d <- p_to_a %>%
  inner_join(fbs_purpose_related_p) %>%
  inner_join(a_id_to_fbs_member_number) %>%
  filter(
    field_code %in% c("028A", "028B", "028C"),
    is.na(role) | !role %in% c("ctb", "dte"), # normed role has to be unknown or not one of these
    is.na(role2) | !str_detect(role2, !!!str_flatten(c( # role2 should not be one of these
      "^Adressat",
      "Erwähnte",
      "Gefeierte",
      "Mitglied eines Ausschusses, der akademische Grade vergibt",
      "Normerlassende Gebietskörperschaft",
      "Praeses",
      "Respondent",
      "Sonstige Person, Familie und Körperschaft",
      "Verfasser",
      "Vertragspartner",
      "Widmende",
      "Widmungsempfänger",
      "Drucker",
      "Zensor",
      "Beiträger",
      "GeistigeR Schöpfer",
      "Mitwirkender",
      "Herausgeber",
      "Angeklagte",
      "Auftraggeber"
    ), collapse = "|^"))
  ) %>%
  inner_join(fbs_metadata) %>%
  filter(field_code %in% c("028A", "028B") | is.na(rank_and_position) | !str_detect(rank_and_position,"graf|herzog|fürst")) %>%
  group_by(member_number) %>%
  summarise(works=n_distinct(p_id)) %>%
  right_join(fbs_metadata) %>%
  collect() %>%
  complete(nesting(member_number,earliest_year_of_admission),fill=list(works=0)) %>%
  inner_join(periods,join_by(earliest_year_of_admission>=start_year,earliest_year_of_admission<=end_year)) %>%
  mutate(period_range=fct_rev(period_range),printings=fct_relevel(case_when(
    works==0 ~ "0",
    works==1 ~ "1",
    works>=2 & works<5 ~ "2-4",
    works>=5 & works<10 ~ "5-9",
    works>=10 & works<20 ~ "10-19",
    works>=20 ~ ">=20"
  ), "0","1","2-4","5-9","10-19",">=20")) %>%
  mutate(label=str_c(member_number,": ",family_name,", ", first_name)) %>%
  count(period_range,printings) %>%
  group_by(period_range) %>%
  mutate(prop=n/sum(n)) %>%
  ungroup()
Joining with `by = join_by(p_id)`Joining with `by = join_by(a_id)`Joining with `by = join_by(member_number)`Joining with `by = join_by(member_number)`
d %>%
  group_by(period_range) %>%
  mutate(tn=sum(n)) %>%
  ungroup() %>%
  mutate(period_range=fct(str_c(period_range," N=(",tn,")"))) %>%
  filter(printings!="0") %>%
  ggplot(aes(x=period_range,y=prop,group=printings,fill=printings)) +
  ylab("Proportion of members") +
  xlab("Period of admission") +
  geom_col(position='stack') +
  theme_hsci_discrete() +
  theme(legend.position = "bottom") +
  scale_y_continuous(labels=scales::percent) +
  scale_coloropt(limits=c(">=20","10-19","5-9", "2-4", "1")) +
  labs(fill="Printings associated with member (N)") +
  coord_flip()
Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.

d %>%
  group_by(period_range) %>%
  mutate(tn=sum(n)) %>%
  ungroup() %>%
  mutate(period_range=fct(str_c(period_range," N=(",tn,")"))) %>%
  ggplot(aes(x=period_range,y=n,group=printings,fill=printings)) +
  ylab("Proportion of members") +
  xlab("Period of admission") +
  geom_col(position='stack') +
  theme_hsci_discrete() +
  theme(legend.position = "bottom") +
  scale_coloropt(limits=c(">=20","10-19","5-9", "2-4", "1", "0")) +
  labs(fill="Printings associated with member (N)") +
  coord_flip()
Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.

d
p1 <- p_to_a %>%
  inner_join(fbs_purpose_related_p) %>%
  inner_join(a_id_to_fbs_member_number) %>%
  filter(
    field_code %in% c("028A", "028B", "028C"),
    is.na(role) | !role %in% c("ctb", "dte"), # normed role has to be unknown or not one of these
    is.na(role2) | !str_detect(role2, !!!str_flatten(c( # role2 should not be one of these
      "^Adressat",
      "Erwähnte",
      "Gefeierte",
      "Mitglied eines Ausschusses, der akademische Grade vergibt",
      "Normerlassende Gebietskörperschaft",
      "Praeses",
      "Respondent",
      "Sonstige Person, Familie und Körperschaft",
      "Verfasser",
      "Vertragspartner",
      "Widmende",
      "Widmungsempfänger",
      "Drucker",
      "Zensor",
      "Beiträger",
      "GeistigeR Schöpfer",
      "Mitwirkender",
      "Herausgeber",
      "Angeklagte",
      "Auftraggeber"
    ), collapse = "|^"))
  ) %>% 
  group_by(member_number) %>%
  summarise(works=n_distinct(p_id)) %>%
  mutate(dataset="base set") %>%
  union_all(
    p_to_a %>%
    inner_join(fbs_purpose_related_p) %>%
    inner_join(a_id_to_fbs_member_number) %>%
    filter(
      field_code %in% c("028A", "028B", "028C"),
      is.na(role) | !role %in% c("ctb", "dte"), # normed role has to be unknown or not one of these
      is.na(role2) | !str_detect(role2, !!!str_flatten(c( # role2 should not be one of these
        "^Adressat",
        "Erwähnte",
        "Gefeierte",
        "Mitglied eines Ausschusses, der akademische Grade vergibt",
        "Normerlassende Gebietskörperschaft",
        "Praeses",
        "Respondent",
        "Sonstige Person, Familie und Körperschaft",
        "Verfasser",
        "Vertragspartner",
        "Widmende",
        "Widmungsempfänger",
        "Drucker",
        "Zensor",
        "Beiträger",
        "GeistigeR Schöpfer",
        "Mitwirkender",
        "Herausgeber",
        "Angeklagte",
        "Auftraggeber"
      ), collapse = "|^"))
    ) %>%
    inner_join(fbs_metadata) %>%
    filter(field_code %in% c("028A", "028B") | is.na(rank_and_position) | !str_detect(rank_and_position,"graf|herzog|fürst")) %>%
    group_by(member_number) %>%
    summarise(works=n_distinct(p_id)) %>%
    mutate(dataset="028C graf, herzog, fürst removed")
  ) %>%
  right_join(fbs_metadata) %>%
  collect() %>%
  complete(dataset,nesting(member_number,earliest_year_of_admission),fill=list(works=0)) %>%
  filter(!is.na(dataset)) %>%
  mutate(label=str_c(member_number,": ",family_name,", ", first_name)) %>%
  ggplot(aes(x=earliest_year_of_admission,y=works,color=dataset,fill=dataset)) +
  scale_x_continuous(breaks=seq(1600,1700,by=10)) +
  ylab("Society-related printings substantively contributed to (N)") +
  xlab("Year of admission") +
  theme_hsci_discrete()
Joining with `by = join_by(p_id)`Joining with `by = join_by(a_id)`Joining with `by = join_by(p_id)`Joining with `by = join_by(a_id)`Joining with `by = join_by(member_number)`Joining with `by = join_by(member_number)`
 
p1 + 
  geom_smooth(span=0.3) +
  geom_point(data=. %>% group_by(earliest_year_of_admission,dataset) %>% summarise(works=mean(works))) +
  scale_y_continuous(breaks=seq(0,10,by=1)) +
  theme(legend.position = "bottom") +
  coord_cartesian(ylim=c(0,NA))


(p1 + 
  scale_y_continuous(breaks=seq(0,500,by=50)) +
  geom_jitter(aes(text=label),size=0.5, height=0) +
  geom_smooth(span=0.3)
) %>%
  ggplotly(width=1024,height=768)
Warning: Ignoring unknown aesthetics: text`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
periods <- tribble(~period,~start_year,~end_year,
                   "Köthen", 1617L, 1650L,
                   "Weimar", 1651L, 1667L,
                   "Halle", 1668L, 1680L
)
d <- p_to_a %>%
  inner_join(fbs_purpose_related_p) %>%
  inner_join(a_id_to_fbs_member_number) %>%
  filter(
    field_code %in% c("028A", "028B", "028C"),
    is.na(role) | !role %in% c("ctb", "dte"), # normed role has to be unknown or not one of these
    is.na(role2) | !str_detect(role2, !!!str_flatten(c( # role2 should not be one of these
      "^Adressat",
      "Erwähnte",
      "Gefeierte",
      "Mitglied eines Ausschusses, der akademische Grade vergibt",
      "Normerlassende Gebietskörperschaft",
      "Praeses",
      "Respondent",
      "Sonstige Person, Familie und Körperschaft",
      "Verfasser",
      "Vertragspartner",
      "Widmende",
      "Widmungsempfänger",
      "Drucker",
      "Zensor",
      "Beiträger",
      "GeistigeR Schöpfer",
      "Mitwirkender",
      "Herausgeber",
      "Angeklagte",
      "Auftraggeber"
    ), collapse = "|^"))
  ) %>% 
  group_by(member_number) %>%
  summarise(works=n_distinct(p_id)) %>%
  mutate(dataset="base set") %>%
  union_all(
    p_to_a %>%
    inner_join(fbs_purpose_related_p) %>%
    inner_join(a_id_to_fbs_member_number) %>%
    filter(
      field_code %in% c("028A", "028B", "028C"),
      is.na(role) | !role %in% c("ctb", "dte"), # normed role has to be unknown or not one of these
      is.na(role2) | !str_detect(role2, !!!str_flatten(c( # role2 should not be one of these
        "^Adressat",
        "Erwähnte",
        "Gefeierte",
        "Mitglied eines Ausschusses, der akademische Grade vergibt",
        "Normerlassende Gebietskörperschaft",
        "Praeses",
        "Respondent",
        "Sonstige Person, Familie und Körperschaft",
        "Verfasser",
        "Vertragspartner",
        "Widmende",
        "Widmungsempfänger",
        "Drucker",
        "Zensor",
        "Beiträger",
        "GeistigeR Schöpfer",
        "Mitwirkender",
        "Herausgeber",
        "Angeklagte",
        "Auftraggeber"
      ), collapse = "|^"))
    ) %>%
    inner_join(fbs_metadata) %>%
    filter(field_code %in% c("028A", "028B") | is.na(rank_and_position) | !str_detect(rank_and_position,"graf|herzog|fürst")) %>%
    group_by(member_number) %>%
    summarise(works=n_distinct(p_id)) %>%
    mutate(dataset="028C graf, herzog, fürst removed")
  ) %>%
  right_join(fbs_metadata) %>%
  collect() %>%
  complete(dataset,nesting(member_number,earliest_year_of_admission),fill=list(works=0)) %>%
  filter(!is.na(dataset))
Joining with `by = join_by(p_id)`Joining with `by = join_by(a_id)`Joining with `by = join_by(p_id)`Joining with `by = join_by(a_id)`Joining with `by = join_by(member_number)`Joining with `by = join_by(member_number)`
d %>% 
  inner_join(periods, join_by(earliest_year_of_admission>=start_year,earliest_year_of_admission<=end_year)) %>%
  group_by(period, dataset) %>%
  summarise(mean_printings=mean(works)) %>%
  relocate(dataset,period,mean_printings) %>%
  arrange(dataset,period)
`summarise()` has grouped output by 'period'. You can override using the `.groups` argument.
periods <- tribble(~start_year,~end_year,~period,
1617L,1623L, "Köthen",
1624L,1630L, "Köthen",
1631L,1637L, "Köthen",
1638L,1644L, "Köthen",
1644L,1650L, "Köthen",
1651L,1656L, "Weimar",
1657L,1662L, "Weimar",
1667L,1673L, "Halle",
1674L,1680L, "Halle"
) %>% mutate(period_range=factor(str_c(start_year,"-",end_year)))

p_to_a %>%
  inner_join(fbs_purpose_related_p) %>%
  inner_join(a_id_to_fbs_member_number) %>%
  filter(
    field_code %in% c("028A", "028B", "028C"),
    is.na(role) | !role %in% c("ctb", "dte"), # normed role has to be unknown or not one of these
    is.na(role2) | !str_detect(role2, !!!str_flatten(c( # role2 should not be one of these
      "^Adressat",
      "Erwähnte",
      "Gefeierte",
      "Mitglied eines Ausschusses, der akademische Grade vergibt",
      "Normerlassende Gebietskörperschaft",
      "Praeses",
      "Respondent",
      "Sonstige Person, Familie und Körperschaft",
      "Verfasser",
      "Vertragspartner",
      "Widmende",
      "Widmungsempfänger",
      "Drucker",
      "Zensor",
      "Beiträger",
      "GeistigeR Schöpfer",
      "Mitwirkender",
      "Herausgeber",
      "Angeklagte",
      "Auftraggeber"
    ), collapse = "|^"))
  ) %>% 
  inner_join(fbs_metadata) %>%
  filter(field_code %in% c("028A", "028B") | is.na(rank_and_position) | !str_detect(rank_and_position,"graf|herzog|fürst")) %>%
  group_by(member_number) %>%
  summarise(works=n_distinct(p_id)) %>%
  right_join(fbs_metadata) %>%
  replace_na(list(works=0)) %>%
  collect() %>%
  inner_join(periods, join_by(earliest_year_of_admission>=start_year,earliest_year_of_admission<=end_year)) %>%
  group_by(period_range) %>%
  summarise(published_min_one=sum(works>=1)/n(),published_min_two=sum(works>=2)/n(),published_min_five=sum(works>=5)/n(),published_min_ten=sum(works>=10)/n(),published_min_twenty=sum(works>=20)/n(), published_min_fifty=sum(works>=50)/n()) %>%
  gt() %>%
  fmt_percent() %>%
  fmt_passthrough(period_range)
Joining with `by = join_by(p_id)`Joining with `by = join_by(a_id)`Joining with `by = join_by(member_number)`Joining with `by = join_by(member_number)`
period_range published_min_one published_min_two published_min_five published_min_ten published_min_twenty published_min_fifty
1617-1623 13.41% 6.10% 3.66% 2.44% 1.22% 0.00%
1624-1630 6.67% 5.00% 3.33% 2.50% 0.83% 0.83%
1631-1637 9.65% 4.39% 1.75% 0.00% 0.00% 0.00%
1638-1644 9.43% 8.49% 4.72% 3.77% 2.83% 0.94%
1644-1650 19.01% 14.05% 7.44% 5.79% 4.13% 2.48%
1651-1656 15.07% 8.22% 4.79% 4.11% 2.74% 0.00%
1657-1662 20.69% 12.07% 4.31% 3.45% 2.59% 1.72%
1667-1673 32.08% 20.75% 16.98% 11.32% 3.77% 1.89%
1674-1680 30.61% 22.45% 18.37% 10.20% 4.08% 2.04%

By genre

(p_to_a %>%
  inner_join(fbs_purpose_related_p) %>%
  inner_join(a_id_to_fbs_member_number) %>%
  filter(
    field_code %in% c("028A", "028B", "028C"),
    is.na(role) | !role %in% c("ctb", "dte"), # normed role has to be unknown or not one of these
    is.na(role2) | !str_detect(role2, !!!str_flatten(c( # role2 should not be one of these
      "^Adressat",
      "Erwähnte",
      "Gefeierte",
      "Mitglied eines Ausschusses, der akademische Grade vergibt",
      "Normerlassende Gebietskörperschaft",
      "Praeses",
      "Respondent",
      "Sonstige Person, Familie und Körperschaft",
      "Verfasser",
      "Vertragspartner",
      "Widmende",
      "Widmungsempfänger",
      "Drucker",
      "Zensor",
      "Beiträger",
      "GeistigeR Schöpfer",
      "Mitwirkender",
      "Herausgeber",
      "Angeklagte",
      "Auftraggeber"
    ), collapse = "|^"))
  ) %>% 
  left_join(p_genre) %>%
  left_join(genre_categorisation) %>%
  filter(is.na(full_genre) | group_1=="Society-related") %>%
  inner_join(fbs_metadata) %>%
  filter(field_code %in% c("028A", "028B") | is.na(rank_and_position) | !str_detect(rank_and_position,"graf|herzog|fürst")) %>%
  group_by(member_number, group_3) %>%
  summarise(works=n_distinct(p_id), .groups="drop") %>%
  right_join(fbs_metadata) %>%
  mutate(label=str_c(member_number,": ",family_name,", ", first_name)) %>%
  collect() %>%
  complete(earliest_year_of_admission, group_3, fill=list(works=0)) %>%
  ggplot(aes(x=earliest_year_of_admission,y=works)) + 
  geom_jitter(aes(text=label),size=0.5, height=0) +
  geom_smooth(span=0.3) +
  scale_x_continuous(breaks=seq(1600,1700,by=10)) +
  ylab("Society-related printings substantively contributed to (N)") +
  xlab("Year of admission") +
  facet_wrap(~group_3, scales="free_y") +
  theme_hsci_discrete()) %>%
  ggplotly(width=1024,height=768)
Joining with `by = join_by(p_id)`Joining with `by = join_by(a_id)`Joining with `by = join_by(p_id)`Joining with `by = join_by(full_genre)`Joining with `by = join_by(member_number)`Joining with `by = join_by(member_number)`Warning: Ignoring unknown aesthetics: text`geom_smooth()` using method = 'loess' and formula = 'y ~ x'
LS0tCnRpdGxlOiAiU29jaWV0eS1hbGlnbmVkIG91dHB1dCBhbmFseXNlcyIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIHRvYzogeWVzICAKLS0tCgpgYGB7ciBzZXR1cH0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSxkcGk9MzAwLGZpZy5yZXRpbmE9MixmaWcud2lkdGg9OCkKc291cmNlKGhlcmU6OmhlcmUoInNyYy9jb21tb25fYmFzaXMuUiIpKQpsaWJyYXJ5KHBsb3RseSkKYGBgCgojIFNvY2lldHktYWxpZ25lZCBvdXRwdXQgYnkgbWVtYmVyIHRocm91Z2ggdGltZQoKSW4gdGhlIGZvbGxvd2luZywgd2UgCgoxLiBmaXJzdCBjYWxjdWxhdGUgZm9yIGVhY2ggbWVtYmVyIHRoZSBudW1iZXIgb2Ygc29jaWV0eS1yZWxhdGVkIHByaW50aW5ncyB0aGV5IGhhdmUgYSBzdWJzdGFudGl2ZSByZWxhdGlvbnNoaXAgdG8sIAoxLiBsaW1pdCBvbmx5IHRvIG1lbWJlcnMgZm9yIHdob20gd2UgaGF2ZSBhIHRpbWUgb2YgYWRtaXNzaW9uIChlYXJsaWVzdCBlc3RpbWF0ZSksIGFuZAoxLiBwbG90IGVhY2ggc3VjaCBtZW1iZXIgb24gdGhlIGdyYXBoIHdpdGggeD10aW1lIG9mIHRoZWlyIGFkbWlzc2lvbiBhbmQgeT1udW1iZXIgb2Ygc29jaWV0eS1yZWxhdGVkIHByaW50aW5ncyBjb250cmlidXRlZCB0by4KMS4gRnVydGhlciwgd2UgY2FsY3VsYXRlIGEgbG9lc3Mtc21vb3RoZWQgYXZlcmFnZSBmb3IgdGhlIG51bWJlciBvZiBwcmludGluZ3MgY29udHJpYnV0ZWQgdG8gcGVyIG1lbWJlciB0aHJvdWdoIHRpbWUuCgojIyBPdmVyYWxsCgpgYGB7cn0KcGVyaW9kcyA8LSB0cmliYmxlKH5wZXJpb2QsfnN0YXJ0X3llYXIsfmVuZF95ZWFyLAogICAgICAgICAgICAgICAgICAgIkvDtnRoZW4iLCAxNjE3TCwgMTY1MEwsCiAgICAgICAgICAgICAgICAgICAiV2VpbWFyIiwgMTY1MUwsIDE2NjJMLAogICAgICAgICAgICAgICAgICAgIkhhbGxlIiwgMTY2N0wsIDE2ODBMCikKCnBfdG9fYSAlPiUKICBpbm5lcl9qb2luKGZic19wdXJwb3NlX3JlbGF0ZWRfcCkgJT4lCiAgaW5uZXJfam9pbihhX2lkX3RvX2Zic19tZW1iZXJfbnVtYmVyKSAlPiUKICBmaWx0ZXIoCiAgICBmaWVsZF9jb2RlICVpbiUgYygiMDI4QSIsICIwMjhCIiwgIjAyOEMiKSwKICAgIGlzLm5hKHJvbGUpIHwgIXJvbGUgJWluJSBjKCJjdGIiLCAiZHRlIiksICMgbm9ybWVkIHJvbGUgaGFzIHRvIGJlIHVua25vd24gb3Igbm90IG9uZSBvZiB0aGVzZQogICAgaXMubmEocm9sZTIpIHwgIXN0cl9kZXRlY3Qocm9sZTIsICEhIXN0cl9mbGF0dGVuKGMoICMgcm9sZTIgc2hvdWxkIG5vdCBiZSBvbmUgb2YgdGhlc2UKICAgICAgIl5BZHJlc3NhdCIsCiAgICAgICJFcnfDpGhudGUiLAogICAgICAiR2VmZWllcnRlIiwKICAgICAgIk1pdGdsaWVkIGVpbmVzIEF1c3NjaHVzc2VzLCBkZXIgYWthZGVtaXNjaGUgR3JhZGUgdmVyZ2lidCIsCiAgICAgICJOb3JtZXJsYXNzZW5kZSBHZWJpZXRza8O2cnBlcnNjaGFmdCIsCiAgICAgICJQcmFlc2VzIiwKICAgICAgIlJlc3BvbmRlbnQiLAogICAgICAiU29uc3RpZ2UgUGVyc29uLCBGYW1pbGllIHVuZCBLw7ZycGVyc2NoYWZ0IiwKICAgICAgIlZlcmZhc3NlciIsCiAgICAgICJWZXJ0cmFnc3BhcnRuZXIiLAogICAgICAiV2lkbWVuZGUiLAogICAgICAiV2lkbXVuZ3NlbXBmw6RuZ2VyIiwKICAgICAgIkRydWNrZXIiLAogICAgICAiWmVuc29yIiwKICAgICAgIkJlaXRyw6RnZXIiLAogICAgICAiR2Vpc3RpZ2VSIFNjaMO2cGZlciIsCiAgICAgICJNaXR3aXJrZW5kZXIiLAogICAgICAiSGVyYXVzZ2ViZXIiLAogICAgICAiQW5nZWtsYWd0ZSIsCiAgICAgICJBdWZ0cmFnZ2ViZXIiCiAgICApLCBjb2xsYXBzZSA9ICJ8XiIpKQogICkgJT4lCiAgaW5uZXJfam9pbihmYnNfbWV0YWRhdGEpICU+JQogIGZpbHRlcihmaWVsZF9jb2RlICVpbiUgYygiMDI4QSIsICIwMjhCIikgfCBpcy5uYShyYW5rX2FuZF9wb3NpdGlvbikgfCAhc3RyX2RldGVjdChyYW5rX2FuZF9wb3NpdGlvbiwiZ3JhZnxoZXJ6b2d8ZsO8cnN0IikpICU+JQogIGdyb3VwX2J5KG1lbWJlcl9udW1iZXIpICU+JQogIHN1bW1hcmlzZSh3b3Jrcz1uX2Rpc3RpbmN0KHBfaWQpKSAlPiUKICByaWdodF9qb2luKGZic19tZXRhZGF0YSkgJT4lCiAgY29sbGVjdCgpICU+JQogIGNvbXBsZXRlKG5lc3RpbmcobWVtYmVyX251bWJlcixlYXJsaWVzdF95ZWFyX29mX2FkbWlzc2lvbiksZmlsbD1saXN0KHdvcmtzPTApKSAlPiUKICBpbm5lcl9qb2luKHBlcmlvZHMsam9pbl9ieShlYXJsaWVzdF95ZWFyX29mX2FkbWlzc2lvbj49c3RhcnRfeWVhcixlYXJsaWVzdF95ZWFyX29mX2FkbWlzc2lvbjw9ZW5kX3llYXIpKSAlPiUKICBtdXRhdGUobGFiZWw9c3RyX2MobWVtYmVyX251bWJlciwiOiAiLGZhbWlseV9uYW1lLCIsICIsIGZpcnN0X25hbWUpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9ZWFybGllc3RfeWVhcl9vZl9hZG1pc3Npb24seT13b3JrcykpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgxNjAwLDE3MDAsYnk9MTApKSArCiAgeWxhYigiTWVhbiBjb250cmlidXRpb25zIHBlciBtZW1iZXIgam9pbmluZyAoTikiKSArCiAgeGxhYigiWWVhciBvZiBhZG1pc3Npb24iKSArCiAgZ2VvbV9zbW9vdGgoc3Bhbj0wLjMpICsKICBnZW9tX3BvaW50KGRhdGE9LiAlPiUgZ3JvdXBfYnkocGVyaW9kLCBlYXJsaWVzdF95ZWFyX29mX2FkbWlzc2lvbikgJT4lIHN1bW1hcmlzZSh3b3Jrcz1tZWFuKHdvcmtzKSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLDIwLGJ5PTIpKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltPWMoMCxOQSkpCmBgYApgYGB7cn0KcGVyaW9kcyA8LSB0cmliYmxlKH5zdGFydF95ZWFyLH5lbmRfeWVhcix+cGVyaW9kLAoxNjE3TCwxNjIzTCwgIkvDtnRoZW4iLAoxNjI0TCwxNjMwTCwgIkvDtnRoZW4iLAoxNjMxTCwxNjM3TCwgIkvDtnRoZW4iLAoxNjM4TCwxNjQ0TCwgIkvDtnRoZW4iLAoxNjQ0TCwxNjUwTCwgIkvDtnRoZW4iLAoxNjUxTCwxNjU2TCwgIldlaW1hciIsCjE2NTdMLDE2NjJMLCAiV2VpbWFyIiwKMTY2N0wsMTY3M0wsICJIYWxsZSIsCjE2NzRMLDE2ODBMLCAiSGFsbGUiCikgJT4lIG11dGF0ZShwZXJpb2RfcmFuZ2U9ZmFjdG9yKHN0cl9jKHN0YXJ0X3llYXIsIi0iLGVuZF95ZWFyKSkpCgpkIDwtIHBfdG9fYSAlPiUKICBpbm5lcl9qb2luKGZic19wdXJwb3NlX3JlbGF0ZWRfcCkgJT4lCiAgaW5uZXJfam9pbihhX2lkX3RvX2Zic19tZW1iZXJfbnVtYmVyKSAlPiUKICBmaWx0ZXIoCiAgICBmaWVsZF9jb2RlICVpbiUgYygiMDI4QSIsICIwMjhCIiwgIjAyOEMiKSwKICAgIGlzLm5hKHJvbGUpIHwgIXJvbGUgJWluJSBjKCJjdGIiLCAiZHRlIiksICMgbm9ybWVkIHJvbGUgaGFzIHRvIGJlIHVua25vd24gb3Igbm90IG9uZSBvZiB0aGVzZQogICAgaXMubmEocm9sZTIpIHwgIXN0cl9kZXRlY3Qocm9sZTIsICEhIXN0cl9mbGF0dGVuKGMoICMgcm9sZTIgc2hvdWxkIG5vdCBiZSBvbmUgb2YgdGhlc2UKICAgICAgIl5BZHJlc3NhdCIsCiAgICAgICJFcnfDpGhudGUiLAogICAgICAiR2VmZWllcnRlIiwKICAgICAgIk1pdGdsaWVkIGVpbmVzIEF1c3NjaHVzc2VzLCBkZXIgYWthZGVtaXNjaGUgR3JhZGUgdmVyZ2lidCIsCiAgICAgICJOb3JtZXJsYXNzZW5kZSBHZWJpZXRza8O2cnBlcnNjaGFmdCIsCiAgICAgICJQcmFlc2VzIiwKICAgICAgIlJlc3BvbmRlbnQiLAogICAgICAiU29uc3RpZ2UgUGVyc29uLCBGYW1pbGllIHVuZCBLw7ZycGVyc2NoYWZ0IiwKICAgICAgIlZlcmZhc3NlciIsCiAgICAgICJWZXJ0cmFnc3BhcnRuZXIiLAogICAgICAiV2lkbWVuZGUiLAogICAgICAiV2lkbXVuZ3NlbXBmw6RuZ2VyIiwKICAgICAgIkRydWNrZXIiLAogICAgICAiWmVuc29yIiwKICAgICAgIkJlaXRyw6RnZXIiLAogICAgICAiR2Vpc3RpZ2VSIFNjaMO2cGZlciIsCiAgICAgICJNaXR3aXJrZW5kZXIiLAogICAgICAiSGVyYXVzZ2ViZXIiLAogICAgICAiQW5nZWtsYWd0ZSIsCiAgICAgICJBdWZ0cmFnZ2ViZXIiCiAgICApLCBjb2xsYXBzZSA9ICJ8XiIpKQogICkgJT4lCiAgaW5uZXJfam9pbihmYnNfbWV0YWRhdGEpICU+JQogIGZpbHRlcihmaWVsZF9jb2RlICVpbiUgYygiMDI4QSIsICIwMjhCIikgfCBpcy5uYShyYW5rX2FuZF9wb3NpdGlvbikgfCAhc3RyX2RldGVjdChyYW5rX2FuZF9wb3NpdGlvbiwiZ3JhZnxoZXJ6b2d8ZsO8cnN0IikpICU+JQogIGdyb3VwX2J5KG1lbWJlcl9udW1iZXIpICU+JQogIHN1bW1hcmlzZSh3b3Jrcz1uX2Rpc3RpbmN0KHBfaWQpKSAlPiUKICByaWdodF9qb2luKGZic19tZXRhZGF0YSkgJT4lCiAgY29sbGVjdCgpICU+JQogIGNvbXBsZXRlKG5lc3RpbmcobWVtYmVyX251bWJlcixlYXJsaWVzdF95ZWFyX29mX2FkbWlzc2lvbiksZmlsbD1saXN0KHdvcmtzPTApKSAlPiUKICBpbm5lcl9qb2luKHBlcmlvZHMsam9pbl9ieShlYXJsaWVzdF95ZWFyX29mX2FkbWlzc2lvbj49c3RhcnRfeWVhcixlYXJsaWVzdF95ZWFyX29mX2FkbWlzc2lvbjw9ZW5kX3llYXIpKSAlPiUKICBtdXRhdGUocGVyaW9kX3JhbmdlPWZjdF9yZXYocGVyaW9kX3JhbmdlKSxwcmludGluZ3M9ZmN0X3JlbGV2ZWwoY2FzZV93aGVuKAogICAgd29ya3M9PTAgfiAiMCIsCiAgICB3b3Jrcz09MSB+ICIxIiwKICAgIHdvcmtzPj0yICYgd29ya3M8NSB+ICIyLTQiLAogICAgd29ya3M+PTUgJiB3b3JrczwxMCB+ICI1LTkiLAogICAgd29ya3M+PTEwICYgd29ya3M8MjAgfiAiMTAtMTkiLAogICAgd29ya3M+PTIwIH4gIj49MjAiCiAgKSwgIjAiLCIxIiwiMi00IiwiNS05IiwiMTAtMTkiLCI+PTIwIikpICU+JQogIG11dGF0ZShsYWJlbD1zdHJfYyhtZW1iZXJfbnVtYmVyLCI6ICIsZmFtaWx5X25hbWUsIiwgIiwgZmlyc3RfbmFtZSkpICU+JQogIGNvdW50KHBlcmlvZF9yYW5nZSxwcmludGluZ3MpICU+JQogIGdyb3VwX2J5KHBlcmlvZF9yYW5nZSkgJT4lCiAgbXV0YXRlKHByb3A9bi9zdW0obikpICU+JQogIHVuZ3JvdXAoKQpgYGAKCgpgYGB7cn0KZCAlPiUKICBncm91cF9ieShwZXJpb2RfcmFuZ2UpICU+JQogIG11dGF0ZSh0bj1zdW0obikpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUocGVyaW9kX3JhbmdlPWZjdChzdHJfYyhwZXJpb2RfcmFuZ2UsIiBOPSgiLHRuLCIpIikpKSAlPiUKICBmaWx0ZXIocHJpbnRpbmdzIT0iMCIpICU+JQogIGdncGxvdChhZXMoeD1wZXJpb2RfcmFuZ2UseT1wcm9wLGdyb3VwPXByaW50aW5ncyxmaWxsPXByaW50aW5ncykpICsKICB5bGFiKCJQcm9wb3J0aW9uIG9mIG1lbWJlcnMiKSArCiAgeGxhYigiUGVyaW9kIG9mIGFkbWlzc2lvbiIpICsKICBnZW9tX2NvbChwb3NpdGlvbj0nc3RhY2snKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHM9c2NhbGVzOjpwZXJjZW50KSArCiAgc2NhbGVfY29sb3JvcHQobGltaXRzPWMoIj49MjAiLCIxMC0xOSIsIjUtOSIsICIyLTQiLCAiMSIpKSArCiAgbGFicyhmaWxsPSJQcmludGluZ3MgYXNzb2NpYXRlZCB3aXRoIG1lbWJlciAoTikiKSArCiAgY29vcmRfZmxpcCgpCmBgYAoKCmBgYHtyfQpkICU+JQogIGdyb3VwX2J5KHBlcmlvZF9yYW5nZSkgJT4lCiAgbXV0YXRlKHRuPXN1bShuKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZShwZXJpb2RfcmFuZ2U9ZmN0KHN0cl9jKHBlcmlvZF9yYW5nZSwiIE49KCIsdG4sIikiKSkpICU+JQogIGdncGxvdChhZXMoeD1wZXJpb2RfcmFuZ2UseT1uLGdyb3VwPXByaW50aW5ncyxmaWxsPXByaW50aW5ncykpICsKICB5bGFiKCJQcm9wb3J0aW9uIG9mIG1lbWJlcnMiKSArCiAgeGxhYigiUGVyaW9kIG9mIGFkbWlzc2lvbiIpICsKICBnZW9tX2NvbChwb3NpdGlvbj0nc3RhY2snKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX2NvbG9yb3B0KGxpbWl0cz1jKCI+PTIwIiwiMTAtMTkiLCI1LTkiLCAiMi00IiwgIjEiLCAiMCIpKSArCiAgbGFicyhmaWxsPSJQcmludGluZ3MgYXNzb2NpYXRlZCB3aXRoIG1lbWJlciAoTikiKSArCiAgY29vcmRfZmxpcCgpCmBgYAoKYGBge3J9CmQKYGBgCgoKYGBge3J9CnAxIDwtIHBfdG9fYSAlPiUKICBpbm5lcl9qb2luKGZic19wdXJwb3NlX3JlbGF0ZWRfcCkgJT4lCiAgaW5uZXJfam9pbihhX2lkX3RvX2Zic19tZW1iZXJfbnVtYmVyKSAlPiUKICBmaWx0ZXIoCiAgICBmaWVsZF9jb2RlICVpbiUgYygiMDI4QSIsICIwMjhCIiwgIjAyOEMiKSwKICAgIGlzLm5hKHJvbGUpIHwgIXJvbGUgJWluJSBjKCJjdGIiLCAiZHRlIiksICMgbm9ybWVkIHJvbGUgaGFzIHRvIGJlIHVua25vd24gb3Igbm90IG9uZSBvZiB0aGVzZQogICAgaXMubmEocm9sZTIpIHwgIXN0cl9kZXRlY3Qocm9sZTIsICEhIXN0cl9mbGF0dGVuKGMoICMgcm9sZTIgc2hvdWxkIG5vdCBiZSBvbmUgb2YgdGhlc2UKICAgICAgIl5BZHJlc3NhdCIsCiAgICAgICJFcnfDpGhudGUiLAogICAgICAiR2VmZWllcnRlIiwKICAgICAgIk1pdGdsaWVkIGVpbmVzIEF1c3NjaHVzc2VzLCBkZXIgYWthZGVtaXNjaGUgR3JhZGUgdmVyZ2lidCIsCiAgICAgICJOb3JtZXJsYXNzZW5kZSBHZWJpZXRza8O2cnBlcnNjaGFmdCIsCiAgICAgICJQcmFlc2VzIiwKICAgICAgIlJlc3BvbmRlbnQiLAogICAgICAiU29uc3RpZ2UgUGVyc29uLCBGYW1pbGllIHVuZCBLw7ZycGVyc2NoYWZ0IiwKICAgICAgIlZlcmZhc3NlciIsCiAgICAgICJWZXJ0cmFnc3BhcnRuZXIiLAogICAgICAiV2lkbWVuZGUiLAogICAgICAiV2lkbXVuZ3NlbXBmw6RuZ2VyIiwKICAgICAgIkRydWNrZXIiLAogICAgICAiWmVuc29yIiwKICAgICAgIkJlaXRyw6RnZXIiLAogICAgICAiR2Vpc3RpZ2VSIFNjaMO2cGZlciIsCiAgICAgICJNaXR3aXJrZW5kZXIiLAogICAgICAiSGVyYXVzZ2ViZXIiLAogICAgICAiQW5nZWtsYWd0ZSIsCiAgICAgICJBdWZ0cmFnZ2ViZXIiCiAgICApLCBjb2xsYXBzZSA9ICJ8XiIpKQogICkgJT4lIAogIGdyb3VwX2J5KG1lbWJlcl9udW1iZXIpICU+JQogIHN1bW1hcmlzZSh3b3Jrcz1uX2Rpc3RpbmN0KHBfaWQpKSAlPiUKICBtdXRhdGUoZGF0YXNldD0iYmFzZSBzZXQiKSAlPiUKICB1bmlvbl9hbGwoCiAgICBwX3RvX2EgJT4lCiAgICBpbm5lcl9qb2luKGZic19wdXJwb3NlX3JlbGF0ZWRfcCkgJT4lCiAgICBpbm5lcl9qb2luKGFfaWRfdG9fZmJzX21lbWJlcl9udW1iZXIpICU+JQogICAgZmlsdGVyKAogICAgICBmaWVsZF9jb2RlICVpbiUgYygiMDI4QSIsICIwMjhCIiwgIjAyOEMiKSwKICAgICAgaXMubmEocm9sZSkgfCAhcm9sZSAlaW4lIGMoImN0YiIsICJkdGUiKSwgIyBub3JtZWQgcm9sZSBoYXMgdG8gYmUgdW5rbm93biBvciBub3Qgb25lIG9mIHRoZXNlCiAgICAgIGlzLm5hKHJvbGUyKSB8ICFzdHJfZGV0ZWN0KHJvbGUyLCAhISFzdHJfZmxhdHRlbihjKCAjIHJvbGUyIHNob3VsZCBub3QgYmUgb25lIG9mIHRoZXNlCiAgICAgICAgIl5BZHJlc3NhdCIsCiAgICAgICAgIkVyd8OkaG50ZSIsCiAgICAgICAgIkdlZmVpZXJ0ZSIsCiAgICAgICAgIk1pdGdsaWVkIGVpbmVzIEF1c3NjaHVzc2VzLCBkZXIgYWthZGVtaXNjaGUgR3JhZGUgdmVyZ2lidCIsCiAgICAgICAgIk5vcm1lcmxhc3NlbmRlIEdlYmlldHNrw7ZycGVyc2NoYWZ0IiwKICAgICAgICAiUHJhZXNlcyIsCiAgICAgICAgIlJlc3BvbmRlbnQiLAogICAgICAgICJTb25zdGlnZSBQZXJzb24sIEZhbWlsaWUgdW5kIEvDtnJwZXJzY2hhZnQiLAogICAgICAgICJWZXJmYXNzZXIiLAogICAgICAgICJWZXJ0cmFnc3BhcnRuZXIiLAogICAgICAgICJXaWRtZW5kZSIsCiAgICAgICAgIldpZG11bmdzZW1wZsOkbmdlciIsCiAgICAgICAgIkRydWNrZXIiLAogICAgICAgICJaZW5zb3IiLAogICAgICAgICJCZWl0csOkZ2VyIiwKICAgICAgICAiR2Vpc3RpZ2VSIFNjaMO2cGZlciIsCiAgICAgICAgIk1pdHdpcmtlbmRlciIsCiAgICAgICAgIkhlcmF1c2dlYmVyIiwKICAgICAgICAiQW5nZWtsYWd0ZSIsCiAgICAgICAgIkF1ZnRyYWdnZWJlciIKICAgICAgKSwgY29sbGFwc2UgPSAifF4iKSkKICAgICkgJT4lCiAgICBpbm5lcl9qb2luKGZic19tZXRhZGF0YSkgJT4lCiAgICBmaWx0ZXIoZmllbGRfY29kZSAlaW4lIGMoIjAyOEEiLCAiMDI4QiIpIHwgaXMubmEocmFua19hbmRfcG9zaXRpb24pIHwgIXN0cl9kZXRlY3QocmFua19hbmRfcG9zaXRpb24sImdyYWZ8aGVyem9nfGbDvHJzdCIpKSAlPiUKICAgIGdyb3VwX2J5KG1lbWJlcl9udW1iZXIpICU+JQogICAgc3VtbWFyaXNlKHdvcmtzPW5fZGlzdGluY3QocF9pZCkpICU+JQogICAgbXV0YXRlKGRhdGFzZXQ9IjAyOEMgZ3JhZiwgaGVyem9nLCBmw7xyc3QgcmVtb3ZlZCIpCiAgKSAlPiUKICByaWdodF9qb2luKGZic19tZXRhZGF0YSkgJT4lCiAgY29sbGVjdCgpICU+JQogIGNvbXBsZXRlKGRhdGFzZXQsbmVzdGluZyhtZW1iZXJfbnVtYmVyLGVhcmxpZXN0X3llYXJfb2ZfYWRtaXNzaW9uKSxmaWxsPWxpc3Qod29ya3M9MCkpICU+JQogIGZpbHRlcighaXMubmEoZGF0YXNldCkpICU+JQogIG11dGF0ZShsYWJlbD1zdHJfYyhtZW1iZXJfbnVtYmVyLCI6ICIsZmFtaWx5X25hbWUsIiwgIiwgZmlyc3RfbmFtZSkpICU+JQogIGdncGxvdChhZXMoeD1lYXJsaWVzdF95ZWFyX29mX2FkbWlzc2lvbix5PXdvcmtzLGNvbG9yPWRhdGFzZXQsZmlsbD1kYXRhc2V0KSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDE2MDAsMTcwMCxieT0xMCkpICsKICB5bGFiKCJTb2NpZXR5LXJlbGF0ZWQgcHJpbnRpbmdzIHN1YnN0YW50aXZlbHkgY29udHJpYnV0ZWQgdG8gKE4pIikgKwogIHhsYWIoIlllYXIgb2YgYWRtaXNzaW9uIikgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKQogCnAxICsgCiAgZ2VvbV9zbW9vdGgoc3Bhbj0wLjMpICsKICBnZW9tX3BvaW50KGRhdGE9LiAlPiUgZ3JvdXBfYnkoZWFybGllc3RfeWVhcl9vZl9hZG1pc3Npb24sZGF0YXNldCkgJT4lIHN1bW1hcmlzZSh3b3Jrcz1tZWFuKHdvcmtzKSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLDEwLGJ5PTEpKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKDAsTkEpKQoKKHAxICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1zZXEoMCw1MDAsYnk9NTApKSArCiAgZ2VvbV9qaXR0ZXIoYWVzKHRleHQ9bGFiZWwpLHNpemU9MC41LCBoZWlnaHQ9MCkgKwogIGdlb21fc21vb3RoKHNwYW49MC4zKQopICU+JQogIGdncGxvdGx5KHdpZHRoPTEwMjQsaGVpZ2h0PTc2OCkKYGBgCgpgYGB7cn0KcGVyaW9kcyA8LSB0cmliYmxlKH5wZXJpb2QsfnN0YXJ0X3llYXIsfmVuZF95ZWFyLAogICAgICAgICAgICAgICAgICAgIkvDtnRoZW4iLCAxNjE3TCwgMTY1MEwsCiAgICAgICAgICAgICAgICAgICAiV2VpbWFyIiwgMTY1MUwsIDE2NjdMLAogICAgICAgICAgICAgICAgICAgIkhhbGxlIiwgMTY2OEwsIDE2ODBMCikKZCA8LSBwX3RvX2EgJT4lCiAgaW5uZXJfam9pbihmYnNfcHVycG9zZV9yZWxhdGVkX3ApICU+JQogIGlubmVyX2pvaW4oYV9pZF90b19mYnNfbWVtYmVyX251bWJlcikgJT4lCiAgZmlsdGVyKAogICAgZmllbGRfY29kZSAlaW4lIGMoIjAyOEEiLCAiMDI4QiIsICIwMjhDIiksCiAgICBpcy5uYShyb2xlKSB8ICFyb2xlICVpbiUgYygiY3RiIiwgImR0ZSIpLCAjIG5vcm1lZCByb2xlIGhhcyB0byBiZSB1bmtub3duIG9yIG5vdCBvbmUgb2YgdGhlc2UKICAgIGlzLm5hKHJvbGUyKSB8ICFzdHJfZGV0ZWN0KHJvbGUyLCAhISFzdHJfZmxhdHRlbihjKCAjIHJvbGUyIHNob3VsZCBub3QgYmUgb25lIG9mIHRoZXNlCiAgICAgICJeQWRyZXNzYXQiLAogICAgICAiRXJ3w6RobnRlIiwKICAgICAgIkdlZmVpZXJ0ZSIsCiAgICAgICJNaXRnbGllZCBlaW5lcyBBdXNzY2h1c3NlcywgZGVyIGFrYWRlbWlzY2hlIEdyYWRlIHZlcmdpYnQiLAogICAgICAiTm9ybWVybGFzc2VuZGUgR2ViaWV0c2vDtnJwZXJzY2hhZnQiLAogICAgICAiUHJhZXNlcyIsCiAgICAgICJSZXNwb25kZW50IiwKICAgICAgIlNvbnN0aWdlIFBlcnNvbiwgRmFtaWxpZSB1bmQgS8O2cnBlcnNjaGFmdCIsCiAgICAgICJWZXJmYXNzZXIiLAogICAgICAiVmVydHJhZ3NwYXJ0bmVyIiwKICAgICAgIldpZG1lbmRlIiwKICAgICAgIldpZG11bmdzZW1wZsOkbmdlciIsCiAgICAgICJEcnVja2VyIiwKICAgICAgIlplbnNvciIsCiAgICAgICJCZWl0csOkZ2VyIiwKICAgICAgIkdlaXN0aWdlUiBTY2jDtnBmZXIiLAogICAgICAiTWl0d2lya2VuZGVyIiwKICAgICAgIkhlcmF1c2dlYmVyIiwKICAgICAgIkFuZ2VrbGFndGUiLAogICAgICAiQXVmdHJhZ2dlYmVyIgogICAgKSwgY29sbGFwc2UgPSAifF4iKSkKICApICU+JSAKICBncm91cF9ieShtZW1iZXJfbnVtYmVyKSAlPiUKICBzdW1tYXJpc2Uod29ya3M9bl9kaXN0aW5jdChwX2lkKSkgJT4lCiAgbXV0YXRlKGRhdGFzZXQ9ImJhc2Ugc2V0IikgJT4lCiAgdW5pb25fYWxsKAogICAgcF90b19hICU+JQogICAgaW5uZXJfam9pbihmYnNfcHVycG9zZV9yZWxhdGVkX3ApICU+JQogICAgaW5uZXJfam9pbihhX2lkX3RvX2Zic19tZW1iZXJfbnVtYmVyKSAlPiUKICAgIGZpbHRlcigKICAgICAgZmllbGRfY29kZSAlaW4lIGMoIjAyOEEiLCAiMDI4QiIsICIwMjhDIiksCiAgICAgIGlzLm5hKHJvbGUpIHwgIXJvbGUgJWluJSBjKCJjdGIiLCAiZHRlIiksICMgbm9ybWVkIHJvbGUgaGFzIHRvIGJlIHVua25vd24gb3Igbm90IG9uZSBvZiB0aGVzZQogICAgICBpcy5uYShyb2xlMikgfCAhc3RyX2RldGVjdChyb2xlMiwgISEhc3RyX2ZsYXR0ZW4oYyggIyByb2xlMiBzaG91bGQgbm90IGJlIG9uZSBvZiB0aGVzZQogICAgICAgICJeQWRyZXNzYXQiLAogICAgICAgICJFcnfDpGhudGUiLAogICAgICAgICJHZWZlaWVydGUiLAogICAgICAgICJNaXRnbGllZCBlaW5lcyBBdXNzY2h1c3NlcywgZGVyIGFrYWRlbWlzY2hlIEdyYWRlIHZlcmdpYnQiLAogICAgICAgICJOb3JtZXJsYXNzZW5kZSBHZWJpZXRza8O2cnBlcnNjaGFmdCIsCiAgICAgICAgIlByYWVzZXMiLAogICAgICAgICJSZXNwb25kZW50IiwKICAgICAgICAiU29uc3RpZ2UgUGVyc29uLCBGYW1pbGllIHVuZCBLw7ZycGVyc2NoYWZ0IiwKICAgICAgICAiVmVyZmFzc2VyIiwKICAgICAgICAiVmVydHJhZ3NwYXJ0bmVyIiwKICAgICAgICAiV2lkbWVuZGUiLAogICAgICAgICJXaWRtdW5nc2VtcGbDpG5nZXIiLAogICAgICAgICJEcnVja2VyIiwKICAgICAgICAiWmVuc29yIiwKICAgICAgICAiQmVpdHLDpGdlciIsCiAgICAgICAgIkdlaXN0aWdlUiBTY2jDtnBmZXIiLAogICAgICAgICJNaXR3aXJrZW5kZXIiLAogICAgICAgICJIZXJhdXNnZWJlciIsCiAgICAgICAgIkFuZ2VrbGFndGUiLAogICAgICAgICJBdWZ0cmFnZ2ViZXIiCiAgICAgICksIGNvbGxhcHNlID0gInxeIikpCiAgICApICU+JQogICAgaW5uZXJfam9pbihmYnNfbWV0YWRhdGEpICU+JQogICAgZmlsdGVyKGZpZWxkX2NvZGUgJWluJSBjKCIwMjhBIiwgIjAyOEIiKSB8IGlzLm5hKHJhbmtfYW5kX3Bvc2l0aW9uKSB8ICFzdHJfZGV0ZWN0KHJhbmtfYW5kX3Bvc2l0aW9uLCJncmFmfGhlcnpvZ3xmw7xyc3QiKSkgJT4lCiAgICBncm91cF9ieShtZW1iZXJfbnVtYmVyKSAlPiUKICAgIHN1bW1hcmlzZSh3b3Jrcz1uX2Rpc3RpbmN0KHBfaWQpKSAlPiUKICAgIG11dGF0ZShkYXRhc2V0PSIwMjhDIGdyYWYsIGhlcnpvZywgZsO8cnN0IHJlbW92ZWQiKQogICkgJT4lCiAgcmlnaHRfam9pbihmYnNfbWV0YWRhdGEpICU+JQogIGNvbGxlY3QoKSAlPiUKICBjb21wbGV0ZShkYXRhc2V0LG5lc3RpbmcobWVtYmVyX251bWJlcixlYXJsaWVzdF95ZWFyX29mX2FkbWlzc2lvbiksZmlsbD1saXN0KHdvcmtzPTApKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGRhdGFzZXQpKQoKZCAlPiUgCiAgaW5uZXJfam9pbihwZXJpb2RzLCBqb2luX2J5KGVhcmxpZXN0X3llYXJfb2ZfYWRtaXNzaW9uPj1zdGFydF95ZWFyLGVhcmxpZXN0X3llYXJfb2ZfYWRtaXNzaW9uPD1lbmRfeWVhcikpICU+JQogIGdyb3VwX2J5KHBlcmlvZCwgZGF0YXNldCkgJT4lCiAgc3VtbWFyaXNlKG1lYW5fcHJpbnRpbmdzPW1lYW4od29ya3MpKSAlPiUKICByZWxvY2F0ZShkYXRhc2V0LHBlcmlvZCxtZWFuX3ByaW50aW5ncykgJT4lCiAgYXJyYW5nZShkYXRhc2V0LHBlcmlvZCkKYGBgCgpgYGB7cn0KcGVyaW9kcyA8LSB0cmliYmxlKH5zdGFydF95ZWFyLH5lbmRfeWVhcix+cGVyaW9kLAoxNjE3TCwxNjIzTCwgIkvDtnRoZW4iLAoxNjI0TCwxNjMwTCwgIkvDtnRoZW4iLAoxNjMxTCwxNjM3TCwgIkvDtnRoZW4iLAoxNjM4TCwxNjQ0TCwgIkvDtnRoZW4iLAoxNjQ0TCwxNjUwTCwgIkvDtnRoZW4iLAoxNjUxTCwxNjU2TCwgIldlaW1hciIsCjE2NTdMLDE2NjJMLCAiV2VpbWFyIiwKMTY2N0wsMTY3M0wsICJIYWxsZSIsCjE2NzRMLDE2ODBMLCAiSGFsbGUiCikgJT4lIG11dGF0ZShwZXJpb2RfcmFuZ2U9ZmFjdG9yKHN0cl9jKHN0YXJ0X3llYXIsIi0iLGVuZF95ZWFyKSkpCgpwX3RvX2EgJT4lCiAgaW5uZXJfam9pbihmYnNfcHVycG9zZV9yZWxhdGVkX3ApICU+JQogIGlubmVyX2pvaW4oYV9pZF90b19mYnNfbWVtYmVyX251bWJlcikgJT4lCiAgZmlsdGVyKAogICAgZmllbGRfY29kZSAlaW4lIGMoIjAyOEEiLCAiMDI4QiIsICIwMjhDIiksCiAgICBpcy5uYShyb2xlKSB8ICFyb2xlICVpbiUgYygiY3RiIiwgImR0ZSIpLCAjIG5vcm1lZCByb2xlIGhhcyB0byBiZSB1bmtub3duIG9yIG5vdCBvbmUgb2YgdGhlc2UKICAgIGlzLm5hKHJvbGUyKSB8ICFzdHJfZGV0ZWN0KHJvbGUyLCAhISFzdHJfZmxhdHRlbihjKCAjIHJvbGUyIHNob3VsZCBub3QgYmUgb25lIG9mIHRoZXNlCiAgICAgICJeQWRyZXNzYXQiLAogICAgICAiRXJ3w6RobnRlIiwKICAgICAgIkdlZmVpZXJ0ZSIsCiAgICAgICJNaXRnbGllZCBlaW5lcyBBdXNzY2h1c3NlcywgZGVyIGFrYWRlbWlzY2hlIEdyYWRlIHZlcmdpYnQiLAogICAgICAiTm9ybWVybGFzc2VuZGUgR2ViaWV0c2vDtnJwZXJzY2hhZnQiLAogICAgICAiUHJhZXNlcyIsCiAgICAgICJSZXNwb25kZW50IiwKICAgICAgIlNvbnN0aWdlIFBlcnNvbiwgRmFtaWxpZSB1bmQgS8O2cnBlcnNjaGFmdCIsCiAgICAgICJWZXJmYXNzZXIiLAogICAgICAiVmVydHJhZ3NwYXJ0bmVyIiwKICAgICAgIldpZG1lbmRlIiwKICAgICAgIldpZG11bmdzZW1wZsOkbmdlciIsCiAgICAgICJEcnVja2VyIiwKICAgICAgIlplbnNvciIsCiAgICAgICJCZWl0csOkZ2VyIiwKICAgICAgIkdlaXN0aWdlUiBTY2jDtnBmZXIiLAogICAgICAiTWl0d2lya2VuZGVyIiwKICAgICAgIkhlcmF1c2dlYmVyIiwKICAgICAgIkFuZ2VrbGFndGUiLAogICAgICAiQXVmdHJhZ2dlYmVyIgogICAgKSwgY29sbGFwc2UgPSAifF4iKSkKICApICU+JSAKICBpbm5lcl9qb2luKGZic19tZXRhZGF0YSkgJT4lCiAgZmlsdGVyKGZpZWxkX2NvZGUgJWluJSBjKCIwMjhBIiwgIjAyOEIiKSB8IGlzLm5hKHJhbmtfYW5kX3Bvc2l0aW9uKSB8ICFzdHJfZGV0ZWN0KHJhbmtfYW5kX3Bvc2l0aW9uLCJncmFmfGhlcnpvZ3xmw7xyc3QiKSkgJT4lCiAgZ3JvdXBfYnkobWVtYmVyX251bWJlcikgJT4lCiAgc3VtbWFyaXNlKHdvcmtzPW5fZGlzdGluY3QocF9pZCkpICU+JQogIHJpZ2h0X2pvaW4oZmJzX21ldGFkYXRhKSAlPiUKICByZXBsYWNlX25hKGxpc3Qod29ya3M9MCkpICU+JQogIGNvbGxlY3QoKSAlPiUKICBpbm5lcl9qb2luKHBlcmlvZHMsIGpvaW5fYnkoZWFybGllc3RfeWVhcl9vZl9hZG1pc3Npb24+PXN0YXJ0X3llYXIsZWFybGllc3RfeWVhcl9vZl9hZG1pc3Npb248PWVuZF95ZWFyKSkgJT4lCiAgZ3JvdXBfYnkocGVyaW9kX3JhbmdlKSAlPiUKICBzdW1tYXJpc2UocHVibGlzaGVkX21pbl9vbmU9c3VtKHdvcmtzPj0xKS9uKCkscHVibGlzaGVkX21pbl90d289c3VtKHdvcmtzPj0yKS9uKCkscHVibGlzaGVkX21pbl9maXZlPXN1bSh3b3Jrcz49NSkvbigpLHB1Ymxpc2hlZF9taW5fdGVuPXN1bSh3b3Jrcz49MTApL24oKSxwdWJsaXNoZWRfbWluX3R3ZW50eT1zdW0od29ya3M+PTIwKS9uKCksIHB1Ymxpc2hlZF9taW5fZmlmdHk9c3VtKHdvcmtzPj01MCkvbigpKSAlPiUKICBndCgpICU+JQogIGZtdF9wZXJjZW50KCkgJT4lCiAgZm10X3Bhc3N0aHJvdWdoKHBlcmlvZF9yYW5nZSkKCmBgYAoKCiMjIEJ5IGdlbnJlCgpgYGB7cn0KKHBfdG9fYSAlPiUKICBpbm5lcl9qb2luKGZic19wdXJwb3NlX3JlbGF0ZWRfcCkgJT4lCiAgaW5uZXJfam9pbihhX2lkX3RvX2Zic19tZW1iZXJfbnVtYmVyKSAlPiUKICBmaWx0ZXIoCiAgICBmaWVsZF9jb2RlICVpbiUgYygiMDI4QSIsICIwMjhCIiwgIjAyOEMiKSwKICAgIGlzLm5hKHJvbGUpIHwgIXJvbGUgJWluJSBjKCJjdGIiLCAiZHRlIiksICMgbm9ybWVkIHJvbGUgaGFzIHRvIGJlIHVua25vd24gb3Igbm90IG9uZSBvZiB0aGVzZQogICAgaXMubmEocm9sZTIpIHwgIXN0cl9kZXRlY3Qocm9sZTIsICEhIXN0cl9mbGF0dGVuKGMoICMgcm9sZTIgc2hvdWxkIG5vdCBiZSBvbmUgb2YgdGhlc2UKICAgICAgIl5BZHJlc3NhdCIsCiAgICAgICJFcnfDpGhudGUiLAogICAgICAiR2VmZWllcnRlIiwKICAgICAgIk1pdGdsaWVkIGVpbmVzIEF1c3NjaHVzc2VzLCBkZXIgYWthZGVtaXNjaGUgR3JhZGUgdmVyZ2lidCIsCiAgICAgICJOb3JtZXJsYXNzZW5kZSBHZWJpZXRza8O2cnBlcnNjaGFmdCIsCiAgICAgICJQcmFlc2VzIiwKICAgICAgIlJlc3BvbmRlbnQiLAogICAgICAiU29uc3RpZ2UgUGVyc29uLCBGYW1pbGllIHVuZCBLw7ZycGVyc2NoYWZ0IiwKICAgICAgIlZlcmZhc3NlciIsCiAgICAgICJWZXJ0cmFnc3BhcnRuZXIiLAogICAgICAiV2lkbWVuZGUiLAogICAgICAiV2lkbXVuZ3NlbXBmw6RuZ2VyIiwKICAgICAgIkRydWNrZXIiLAogICAgICAiWmVuc29yIiwKICAgICAgIkJlaXRyw6RnZXIiLAogICAgICAiR2Vpc3RpZ2VSIFNjaMO2cGZlciIsCiAgICAgICJNaXR3aXJrZW5kZXIiLAogICAgICAiSGVyYXVzZ2ViZXIiLAogICAgICAiQW5nZWtsYWd0ZSIsCiAgICAgICJBdWZ0cmFnZ2ViZXIiCiAgICApLCBjb2xsYXBzZSA9ICJ8XiIpKQogICkgJT4lIAogIGxlZnRfam9pbihwX2dlbnJlKSAlPiUKICBsZWZ0X2pvaW4oZ2VucmVfY2F0ZWdvcmlzYXRpb24pICU+JQogIGZpbHRlcihpcy5uYShmdWxsX2dlbnJlKSB8IGdyb3VwXzE9PSJTb2NpZXR5LXJlbGF0ZWQiKSAlPiUKICBpbm5lcl9qb2luKGZic19tZXRhZGF0YSkgJT4lCiAgZmlsdGVyKGZpZWxkX2NvZGUgJWluJSBjKCIwMjhBIiwgIjAyOEIiKSB8IGlzLm5hKHJhbmtfYW5kX3Bvc2l0aW9uKSB8ICFzdHJfZGV0ZWN0KHJhbmtfYW5kX3Bvc2l0aW9uLCJncmFmfGhlcnpvZ3xmw7xyc3QiKSkgJT4lCiAgZ3JvdXBfYnkobWVtYmVyX251bWJlciwgZ3JvdXBfMykgJT4lCiAgc3VtbWFyaXNlKHdvcmtzPW5fZGlzdGluY3QocF9pZCksIC5ncm91cHM9ImRyb3AiKSAlPiUKICByaWdodF9qb2luKGZic19tZXRhZGF0YSkgJT4lCiAgbXV0YXRlKGxhYmVsPXN0cl9jKG1lbWJlcl9udW1iZXIsIjogIixmYW1pbHlfbmFtZSwiLCAiLCBmaXJzdF9uYW1lKSkgJT4lCiAgY29sbGVjdCgpICU+JQogIGNvbXBsZXRlKGVhcmxpZXN0X3llYXJfb2ZfYWRtaXNzaW9uLCBncm91cF8zLCBmaWxsPWxpc3Qod29ya3M9MCkpICU+JQogIGdncGxvdChhZXMoeD1lYXJsaWVzdF95ZWFyX29mX2FkbWlzc2lvbix5PXdvcmtzKSkgKyAKICBnZW9tX2ppdHRlcihhZXModGV4dD1sYWJlbCksc2l6ZT0wLjUsIGhlaWdodD0wKSArCiAgZ2VvbV9zbW9vdGgoc3Bhbj0wLjMpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgxNjAwLDE3MDAsYnk9MTApKSArCiAgeWxhYigiU29jaWV0eS1yZWxhdGVkIHByaW50aW5ncyBzdWJzdGFudGl2ZWx5IGNvbnRyaWJ1dGVkIHRvIChOKSIpICsKICB4bGFiKCJZZWFyIG9mIGFkbWlzc2lvbiIpICsKICBmYWNldF93cmFwKH5ncm91cF8zLCBzY2FsZXM9ImZyZWVfeSIpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkpICU+JQogIGdncGxvdGx5KHdpZHRoPTEwMjQsaGVpZ2h0PTc2OCkKYGBgCgojIFByb3BvcnRpb24gb2YgYWRtaXR0ZWQgbWVtYmVycyB3aXRoIHN1YnN0YW50aXZlIGNvbnRyaWJ1dGlvbnMgdG8gc29jaWV0eS1yZWxhdGVkIHByaW50aW5ncwoKYGBge3J9CnBlcmlvZHMgPC0gdHJpYmJsZSh+c3RhcnRfeWVhcix+ZW5kX3llYXIsfnBlcmlvZCwKMTYxN0wsMTYyM0wsICJLw7Z0aGVuIiwKMTYyNEwsMTYzMEwsICJLw7Z0aGVuIiwKMTYzMUwsMTYzN0wsICJLw7Z0aGVuIiwKMTYzOEwsMTY0NEwsICJLw7Z0aGVuIiwKMTY0NUwsMTY1MEwsICJLw7Z0aGVuIiwKMTY1MUwsMTY1NkwsICJXZWltYXIiLAoxNjU3TCwxNjYyTCwgIldlaW1hciIsCjE2NjdMLDE2NzNMLCAiSGFsbGUiLAoxNjc0TCwxNjgwTCwgIkhhbGxlIgopICU+JSBtdXRhdGUocGVyaW9kX3JhbmdlPWZhY3RvcihzdHJfYyhzdGFydF95ZWFyLCItIixlbmRfeWVhcikpKQoKcF90b19hICU+JQogIGlubmVyX2pvaW4oZmJzX3B1cnBvc2VfcmVsYXRlZF9wKSAlPiUKICBpbm5lcl9qb2luKGFfaWRfdG9fZmJzX21lbWJlcl9udW1iZXIpICU+JQogIGZpbHRlcigKICAgIGZpZWxkX2NvZGUgJWluJSBjKCIwMjhBIiwgIjAyOEIiLCAiMDI4QyIpLAogICAgaXMubmEocm9sZSkgfCAhcm9sZSAlaW4lIGMoImN0YiIsICJkdGUiKSwgIyBub3JtZWQgcm9sZSBoYXMgdG8gYmUgdW5rbm93biBvciBub3Qgb25lIG9mIHRoZXNlCiAgICBpcy5uYShyb2xlMikgfCAhc3RyX2RldGVjdChyb2xlMiwgISEhc3RyX2ZsYXR0ZW4oYyggIyByb2xlMiBzaG91bGQgbm90IGJlIG9uZSBvZiB0aGVzZQogICAgICAiXkFkcmVzc2F0IiwKICAgICAgIkVyd8OkaG50ZSIsCiAgICAgICJHZWZlaWVydGUiLAogICAgICAiTWl0Z2xpZWQgZWluZXMgQXVzc2NodXNzZXMsIGRlciBha2FkZW1pc2NoZSBHcmFkZSB2ZXJnaWJ0IiwKICAgICAgIk5vcm1lcmxhc3NlbmRlIEdlYmlldHNrw7ZycGVyc2NoYWZ0IiwKICAgICAgIlByYWVzZXMiLAogICAgICAiUmVzcG9uZGVudCIsCiAgICAgICJTb25zdGlnZSBQZXJzb24sIEZhbWlsaWUgdW5kIEvDtnJwZXJzY2hhZnQiLAogICAgICAiVmVyZmFzc2VyIiwKICAgICAgIlZlcnRyYWdzcGFydG5lciIsCiAgICAgICJXaWRtZW5kZSIsCiAgICAgICJXaWRtdW5nc2VtcGbDpG5nZXIiLAogICAgICAiRHJ1Y2tlciIsCiAgICAgICJaZW5zb3IiLAogICAgICAiQmVpdHLDpGdlciIsCiAgICAgICJHZWlzdGlnZVIgU2Now7ZwZmVyIiwKICAgICAgIk1pdHdpcmtlbmRlciIsCiAgICAgICJIZXJhdXNnZWJlciIsCiAgICAgICJBbmdla2xhZ3RlIiwKICAgICAgIkF1ZnRyYWdnZWJlciIKICAgICksIGNvbGxhcHNlID0gInxeIikpCiAgKSAlPiUgCiAgaW5uZXJfam9pbihmYnNfbWV0YWRhdGEpICU+JQogIGZpbHRlcihmaWVsZF9jb2RlICVpbiUgYygiMDI4QSIsICIwMjhCIikgfCBpcy5uYShyYW5rX2FuZF9wb3NpdGlvbikgfCAhc3RyX2RldGVjdChyYW5rX2FuZF9wb3NpdGlvbiwiZ3JhZnxoZXJ6b2d8ZsO8cnN0IikpICU+JQogIGdyb3VwX2J5KG1lbWJlcl9udW1iZXIpICU+JQogIHN1bW1hcmlzZSh3b3Jrcz1uX2Rpc3RpbmN0KHBfaWQpKSAlPiUKICByaWdodF9qb2luKGZic19tZXRhZGF0YSkgJT4lCiAgcmVwbGFjZV9uYShsaXN0KHdvcmtzPTApKSAlPiUKICBtdXRhdGUocHVibGlzaGluZz13b3Jrcz4wKSAlPiUKICBjb2xsZWN0KCkgJT4lCiAgaW5uZXJfam9pbihwZXJpb2RzLCBqb2luX2J5KGVhcmxpZXN0X3llYXJfb2ZfYWRtaXNzaW9uPj1zdGFydF95ZWFyLGVhcmxpZXN0X3llYXJfb2ZfYWRtaXNzaW9uPD1lbmRfeWVhcikpICU+JQogIGdyb3VwX2J5KHBlcmlvZF9yYW5nZSxwZXJpb2QpICU+JQogIHN1bW1hcmlzZShtZW1iZXJzX2pvaW5lZD1uKCkscHJvcF9wdWJsaXNoaW5nPXN1bShwdWJsaXNoaW5nKS9uKCkpICU+JQogIGdncGxvdChhZXMoeD1wZXJpb2RfcmFuZ2UseT1wcm9wX3B1Ymxpc2hpbmcsIGZpbGw9cGVyaW9kKSkgKyAKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsPW1lbWJlcnNfam9pbmVkKSwgbnVkZ2VfeT0tMC4wMiwgY29sb3I9IndoaXRlIikgKwogIHNjYWxlX3hfZGlzY3JldGUoKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscz1zY2FsZXM6OnBlcmNlbnQpICsKICB5bGFiKCJQcm9wb3J0aW9uIGluIHB1Ymxpc2hpbmciKSArCiAgeGxhYigiUGVyaW9kIG9mIGFkbWlzc2lvbiIpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikKYGBgCgpOdW1iZXJzIGRlbm90ZSB0aGUgbnVtYmVyIG9mIG1lbWJlcnMgam9pbmluZyBpbiBlYWNoIHBlcmlvZC4KCiMgU29jaWV0eS1wdXJwb3NlIC1yZWxhdGVkIHB1YmxpY2F0aW9ucyBieSBnZW5yZSB0aHJvdWdoIHRpbWUKCiMjIEFic29sdXRlCgpgYGB7cn0KcF95ZWFyICU+JQogIGZpbHRlcih5ZWFyPj0xNjAwLHllYXI8MTcwMCkgJT4lCiAgaW5uZXJfam9pbihmYnNfcHVycG9zZV9yZWxhdGVkX3ApICU+JQogIGxlZnRfam9pbihwX2dlbnJlKSAlPiUKICBsZWZ0X2pvaW4oZ2VucmVfY2F0ZWdvcmlzYXRpb24pICU+JQogIGZpbHRlcihpcy5uYShmdWxsX2dlbnJlKSB8IGdyb3VwXzE9PSJTb2NpZXR5LXJlbGF0ZWQiKSAlPiUKICBtdXRhdGUoZGVjYWRlPWZsb29yKHllYXIvMTApKjEwKSAlPiUKICBjb3VudChncm91cF8zLGRlY2FkZSkgJT4lCiAgY29sbGVjdCgpICU+JQogIGNvbXBsZXRlKGdyb3VwXzMsIGRlY2FkZSwgZmlsbD1saXN0KG49MCkpICU+JQogIGdncGxvdChhZXMoeD1kZWNhZGUseT1uKSkgKwogIGdlb21fc21vb3RoKHNwYW49MC4zKSArCiAgZ2VvbV9wb2ludCgpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKDAsTkEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMTYwMCwxNzAwLGJ5PTIwKSkgKwogIHlsYWIoIlByaW50aW5ncyBieSBtZW1iZXJzIChOKSIpICsKICB4bGFiKCJEZWNhZGUiKSArCiAgZmFjZXRfd3JhcCh+Z3JvdXBfMywgc2NhbGVzPSJmcmVlX3kiKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpCmBgYAoKIyMgTm9ybWFsaXNlZCBieSBudW1iZXIgb2YgbWVtYmVycwoKYGBge3J9Cm1lbWJlcnNfYnlfeWVhciA8LSB0aWJibGUoeWVhcj0xNjE3OjE2OTkpICU+JSAKICBpbm5lcl9qb2luKGZic19tZXRhZGF0YSAlPiUgY29sbGVjdCgpLCBqb2luX2J5KHllYXI+PWVhcmxpZXN0X3llYXJfb2ZfYWRtaXNzaW9uLHllYXI8PWxhdGVzdF95ZWFyX29mX2RlYXRoKSkgJT4lCiAgY291bnQoeWVhcikgJT4lCiAgcmlnaHRfam9pbih0aWJibGUoeWVhcj0xNjE3OjE2OTkpKSAlPiUKICByZXBsYWNlX25hKGxpc3Qobj0wKSkKYGBgCgpgYGB7cn0KcF95ZWFyICU+JQogIGZpbHRlcih5ZWFyPj0xNjAwLHllYXI8MTcwMCkgJT4lCiAgaW5uZXJfam9pbihmYnNfcHVycG9zZV9yZWxhdGVkX3ApICU+JQogIGxlZnRfam9pbihwX2dlbnJlKSAlPiUKICBsZWZ0X2pvaW4oZ2VucmVfY2F0ZWdvcmlzYXRpb24pICU+JQogIGZpbHRlcihpcy5uYShmdWxsX2dlbnJlKSB8IGdyb3VwXzE9PSJTb2NpZXR5LXJlbGF0ZWQiKSAlPiUKICBtdXRhdGUoZGVjYWRlPWZsb29yKHllYXIvMTApKjEwKSAlPiUKICBjb3VudChncm91cF8zLGRlY2FkZSkgJT4lCiAgY29sbGVjdCgpICU+JQogIGNvbXBsZXRlKGdyb3VwXzMsIGRlY2FkZSwgZmlsbD1saXN0KG49MCkpICU+JQogIGlubmVyX2pvaW4obWVtYmVyc19ieV95ZWFyICU+JSAKICAgICAgICAgICAgICAgbXV0YXRlKGRlY2FkZT1mbG9vcih5ZWFyLzEwKSoxMCkgJT4lCiAgICAgICAgICAgICAgIGdyb3VwX2J5KGRlY2FkZSkgJT4lCiAgICAgICAgICAgICAgIHN1bW1hcmlzZShtZWFuX21lbWJlcnM9bWVhbihuKSwuZ3JvdXBzPSJkcm9wIikpICU+JQogIGdncGxvdChhZXMoeD1kZWNhZGUseT1uL21lYW5fbWVtYmVycykpICsKICBnZW9tX3Ntb290aChzcGFuPTAuMykgKwogIGdlb21fcG9pbnQoKSArCiAgY29vcmRfY2FydGVzaWFuKHlsaW09YygwLE5BKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDE2MDAsMTcwMCxieT0yMCkpICsKICB5bGFiKCJQcmludGluZ3MgcGVyIG1lbWJlciIpICsKICB4bGFiKCJEZWNhZGUiKSArCiAgZmFjZXRfd3JhcCh+Z3JvdXBfMywgc2NhbGVzPSJmcmVlX3kiKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpCmBgYAoKIyMgUHJvcG9ydGlvbiBvZiBwdWJsaWNhdGlvbnMgYnkgZ2VucmUKCmBgYHtyfQp0IDwtIHBfeWVhciAlPiUKICBmaWx0ZXIoeWVhcj49MTYwMCx5ZWFyPDE3MDApICU+JQogIGlubmVyX2pvaW4oZmJzX3B1cnBvc2VfcmVsYXRlZF9wKSAlPiUKICBsZWZ0X2pvaW4ocF9nZW5yZSkgJT4lCiAgbGVmdF9qb2luKGdlbnJlX2NhdGVnb3Jpc2F0aW9uKSAlPiUKICBmaWx0ZXIoaXMubmEoZnVsbF9nZW5yZSkgfCBncm91cF8xPT0iU29jaWV0eS1yZWxhdGVkIikgJT4lCiAgbXV0YXRlKGRlY2FkZT1mbG9vcih5ZWFyLzEwKSoxMCkKCnQgJT4lCiAgZ3JvdXBfYnkoZGVjYWRlKSAlPiUKICBzdW1tYXJpc2UodG90YWxfbj1uX2Rpc3RpbmN0KHBfaWQpKSAlPiUKICBpbm5lcl9qb2luKHQgJT4lCiAgICBjb3VudChncm91cF8zLCBkZWNhZGUpCiAgKSAlPiUKICBtdXRhdGUocHJvcD1uL3RvdGFsX24pICU+JQogIGNvbGxlY3QoKSAlPiUKICBjb21wbGV0ZShncm91cF8zLCBkZWNhZGUsIGZpbGw9bGlzdChwcm9wPTApKSAlPiUKICBnZ3Bsb3QoYWVzKHg9ZGVjYWRlLHk9cHJvcCkpICsKICBnZW9tX3Ntb290aChzcGFuPTAuMykgKwogIGdlb21fcG9pbnQoKSArCiAgY29vcmRfY2FydGVzaWFuKHlsaW09YygwLE5BKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDE2MDAsMTcwMCxieT0yMCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6cGVyY2VudCkgKwogIHlsYWIoIlNvY2lldHkgcHJpbnRpbmdzIGJ5IGdlbnJlICglKSIpICsKICB4bGFiKCJEZWNhZGUiKSArCiAgZmFjZXRfd3JhcCh+Z3JvdXBfMywgc2NhbGVzPSJmcmVlX3kiKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpCmBgYAoK