General Setup
Analysis table creation. Don’t run if already created. Instead skip
to “Analysis table loads”
dbExecute(con,"DROP TABLE IF EXISTS articles_cdp")
articles_cdp <- articles %>% filter(case_when(
media == "HS" ~ section %in% c("Kotimaa", "Politiikka", "Talous"),
media == "IL" ~ subsection %in% c("kotimaa","politiikka","talous","uutiset"),
media == "STT" ~ section %in% c("Kotimaa","Politiikka","Talous"),
media == "YLE" ~ section == "Yle Uutiset" & str_detect(subject,"Kotimaan uutiset|politiikka|talous") & (!str_detect(subject,"Ulkomaat") | str_detect(subject,"Kotimaan uutiset")),
T ~ F
)) %>%
distinct(a_id) %>%
compute(name="articles_cdp",temporary=F,unique_indexes=c("a_id"))
dbExecute(con,"DROP TABLE IF EXISTS articles_opinionated")
articles_opinionated <- articles %>% mutate(opinionated=case_when(
media == "HS" ~ case_when(
str_to_lower(section) == "pääkirjoitus" & str_detect(str_to_lower(story_logo),"ieras") ~ "external editorial",
str_to_lower(section) == "pääkirjoitus" & is.na(story_logo) ~ "editorial",
str_to_lower(section) == "pääkirjoitus" & str_to_lower(story_logo) == "pääkirjoitus" ~ "editorial",
str_to_lower(section) == "mielipide" | str_to_lower(story_logo) == "mielipide" ~ "external opinion",
str_detect(str_to_lower(title),"analyysi:") | str_detect(str_to_lower(story_logo),"analyysi") ~ "analysis",
str_detect(str_to_lower(title),"näkökulma:") | str_detect(str_to_lower(story_logo),"näkökulma") ~ "perspective",
str_detect(str_to_lower(title),"kolumni:") | str_detect(str_to_lower(story_logo),"kolumni") ~ "column",
str_detect(str_to_lower(title),"blogi:") | str_detect(str_to_lower(story_logo),"blog") ~ "blog"
),
media == "IL" ~ case_when(
subsection == "paakirjoitus" ~ "editorial",
str_detect(str_to_lower(title),"kommentti:") ~ "commentary",
str_detect(str_to_lower(title),"analyysi:") ~ "analysis",
str_detect(str_to_lower(title),"kolumni:") ~ "column",
str_detect(str_to_lower(title),"näkökulma:") ~ "perspective"
),
media == "YLE" ~ case_when(
str_detect(str_to_lower(title),"kommentti:") ~ "commentary",
str_detect(str_to_lower(title),"analyysi:") | str_detect(subject,"Analyysit \\(Yle Uutiset\\)") ~ "analysis",
str_detect(str_to_lower(title),"kolumni:") | str_detect(str_to_lower(subject),"kolumn") ~ "column",
str_detect(str_to_lower(title),"näkökulma:") | str_detect(str_to_lower(subject),"näkökulm") ~ "perspective",
str_detect(str_to_lower(title),"blogi:") | str_detect(str_to_lower(subject),"blog") ~ "blog"
)
)) %>%
filter(!is.na(opinionated)) %>%
distinct(a_id, opinionated) %>%
compute(name="articles_opinionated",temporary=F,unique_indexes=c("a_id"))
labels <- read_tsv(here("data/person_labels.tsv")) %>%
filter(!category %in% c('adjektiivi', 'ei'))
lemmas_of_interest <- labels %>%
rename("lemma" = "name") %>%
copy_to(con,.,name="labels",overwrite=T) %>%
union_all(words %>%
filter(str_detect(lemma, "yhden#ve")) %>%
distinct(lemma) %>%
mutate(category="yhdenvertaisuus")) %>%
union_all(words %>%
filter(str_detect(lemma, "tasa#arv")) %>%
distinct(lemma) %>%
mutate(category="tasa-arvo")) %>%
distinct()
dbExecute(con,"DROP TABLE IF EXISTS words_of_interest")
words_of_interest <- words %>%
inner_join(lemmas_of_interest) %>%
distinct(w_id,lemma,category,genus) %>%
compute(name="words_of_interest",temporary=F,indexes=c("w_id","category","genus"))
dbExecute(con,"DROP TABLE IF EXISTS corpus_of_interest")
corpus_of_interest <- corpus %>%
inner_join(words_of_interest) %>%
compute(name="corpus_of_interest",temporary=F,indexes=list(c("a_id","par_id","s_id","pos"),c("w_id"),c("genus"),c("category"))
dbExecute(con,"DROP TABLE IF EXISTS article_types")
article_types <- articles %>%
left_join(articles_cdp %>% mutate(cdp=T)) %>%
left_join(articles_opinionated) %>%
mutate(type=case_when(
media == "STT" & version != "Loppuversio" ~ "Other",
!is.na(opinionated) & !str_detect(opinionated,"^external ") ~ "Journalistic opinion",
!is.na(opinionated) ~ "External opinion",
cdp ~ "Domestic general/political/economic news",
media == "HS" & section == "Kulttuuri" ~ "Culture/entertainment",
media == "IL" & section == "viihde" ~ "Culture/entertainment",
media == "STT" & section == "Kulttuuri" ~ "Culture/entertainment",
media == "YLE" & section == "Yle Uutiset" & str_detect(subject,"kulttuuri|musiikki|viihde") & !str_detect(subject, "Ulkomaat") ~ "Culture/entertainment",
media == "HS" & section == "Kaupunki" ~ "Local news",
media == "YLE" & section == "Yle Uutiset" & coverage=="local" ~ "Local news",
media == "STT" & section == "Urheilu" ~ "Sports",
media == "HS" & section == "Urheilu" ~ "Sports",
media == "YLE" & section == "YLE Urheilu" ~ "Sports",
media == "IL" & section == "urheilu" ~ "Sports",
media == "STT" & section == "Ulkomaat" ~ "Foreign news",
media == "HS" & section == "Ulkomaat" ~ "Foreign news",
media == "YLE" & section == "Yle Uutiset" & str_detect(subject,"Ulkomaat") & !str_detect(subject,"Kotimaan uutiset") ~ "Foreign news",
media == "IL" & subsection == "ulkomaat" ~ "Foreign news",
T ~ "Other"
)) %>%
distinct(a_id,type) %>%
compute(temporary=F,name="article_types",unique_indexes=list(c("a_id"),c("a_id","type"),c("type","a_id")))
dbExecute(con,"DROP TABLE IF EXISTS articles_by_type_by_year")
articles_by_type_by_year <- articles %>%
inner_join(article_types) %>%
mutate(year_created=year(date_created)) %>%
count(media,year_created,type,name="total_articles") %>%
compute(unique_indexes=list(c("media","year_created","type")),temporary=F,name="articles_by_type_by_year")
dbExecute(con,"DROP TABLE IF EXISTS articles_to_ref_categories")
articles_to_ref_categories <- words_of_interest %>%
filter(category %in% c("tasa-arvo","yhdenvertaisuus")) %>%
inner_join(corpus) %>%
group_by(a_id) %>%
summarize(yv=max(category=="yhdenvertaisuus"),ta=max(category=="tasa-arvo"),.groups="drop") %>%
mutate(ref_category=case_when(yv==1 & ta==1 ~ "both",yv==1 ~ "yhdenvertaisuus", ta==1 ~ "tasa-arvo")) %>%
select(a_id,ref_category) %>%
compute()
articles_to_ref_categories <- articles_to_ref_categories %>% union_all(
articles_to_ref_categories %>%
filter(ref_category=="both") %>%
mutate(ref_category="yhdenvertaisuus")
) %>%
union_all(
articles_to_ref_categories %>%
filter(ref_category=="both") %>%
mutate(ref_category="tasa-arvo")
) %>%
compute(temporary=F,name="articles_to_ref_categories",indexes=c("a_id"),unique_indexes=list(c("a_id","ref_category"),c("ref_category","a_id")))
yv_ta_corpus <- words_of_interest %>%
filter(category %in% c("tasa-arvo","yhdenvertaisuus")) %>%
inner_join(corpus)
dbExecute(con,"DROP TABLE IF EXISTS yv_ta_paragraphs")
yv_ta_paragraphs <- yv_ta_corpus %>%
distinct(a_id,par_id) %>%
compute(temporary=F,name="yv_ta_paragraphs", unique_indexes=list(c("a_id","par_id")))
Analysis table loads
articles_cdp <- tbl(con,"articles_cdp")
articles_opinionated <- tbl(con,"articles_opinionated")
article_types <- tbl(con,"article_types")
articles_by_type_by_year <- tbl(con,"articles_by_type_by_year")
words_of_interest <- tbl(con,"words_of_interest")
corpus_of_interest <- tbl(con,"corpus_of_interest")
articles_to_ref_categories <- tbl(con,"articles_to_ref_categories")
yv_ta_paragraphs <- tbl(con,"yv_ta_paragraphs")
Named query definitions
quotation_corpus <- quotes %>%
inner_join(corpus,sql_on="LHS.a_id=RHS.a_id AND (s_id > start_s_id OR (s_id=start_s_id AND pos >= start_pos)) AND (s_id < end_s_id OR (s_id=end_s_id AND pos <= end_pos))") %>%
select(a_id=a_id.x,par_id,s_id,pos, q_id)
quotation_sentence_corpus <- quotes %>%
inner_join(corpus,sql_on="LHS.a_id=RHS.a_id AND s_id >= start_s_id AND s_id <= end_s_id") %>%
select(a_id=a_id.x,par_id,s_id,pos, q_id)
yv_corpus <- corpus_of_interest %>%
filter(category=="yhdenvertaisuus")
yv_paragraphs <- yv_corpus %>%
distinct(a_id,par_id)
ta_corpus <- corpus_of_interest %>%
filter(category=="tasa-arvo")
ta_paragraphs <- ta_corpus %>%
distinct(a_id,par_id)
quote_orgs <- read_tsv(here("data/q_id_to_orgs.tsv")) %>%
select(c(author_head, a_id, org_cat))
New names:
• `` -> `...1`
Rows: 19362 Columns: 5
── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (2): org_cat, author_head
dbl (3): ...1, q_id, a_id
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
d <- corpus_of_interest %>%
inner_join(articles %>% select(a_id,date_created,media)) %>%
inner_join(article_types) %>%
left_join(articles_to_ref_categories) %>%
left_join(quotation_corpus %>% mutate(in_quote=T)) %>%
left_join(quotation_sentence_corpus %>% mutate(in_quote_sentence=T)) %>%
left_join(quote_orgs, copy = TRUE, auto_index = TRUE) %>%
mutate(in_quote_head=in_quote_sentence & !in_quote) %>%
mutate(year_created=year(date_created)) %>%
mutate(week_created=week(date_created)) %>%
mutate(type2=case_when(
str_detect(type,"opinion$") ~ type,
in_quote_sentence ~ str_c("Quotes in ",type),
TRUE ~ str_c("Journalistic text in ",type)
))
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = c("a_id", "par_id", "s_id", "pos")
Joining, by = c("a_id", "par_id", "s_id", "pos", "q_id")
Joining, by = "a_id"
d2 <- corpus_of_interest %>%
inner_join(yv_ta_paragraphs) %>%
inner_join(articles %>% select(a_id,date_created,media)) %>%
inner_join(article_types) %>%
inner_join(articles_to_ref_categories) %>%
left_join(quotation_corpus %>% mutate(in_quote=T)) %>%
left_join(quote_orgs, copy = TRUE, auto_index = TRUE) %>%
left_join(quotation_sentence_corpus %>% mutate(in_quote_sentence=T)) %>%
mutate(in_quote_head=in_quote_sentence & !in_quote) %>%
mutate(year_created=year(date_created)) %>%
mutate(week_created=week(date_created)) %>%
mutate(type2=case_when(
str_detect(type,"opinion$") ~ type,
in_quote_sentence ~ str_c("Quotes in ",type),
TRUE ~ str_c("Journalistic text in ",type)
))
Joining, by = c("a_id", "par_id")
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = c("a_id", "par_id", "s_id", "pos")
Joining, by = "a_id"
Joining, by = c("a_id", "par_id", "s_id", "pos", "q_id")
key_cats <- c('potilas', 'maahanmuutto', 'etnos', 'seksuaalisuus', 'työsuhde')
main_types <- c('core', 'opinionated', 'external opinion')
Analysis 1: development of yhdenvertaisuus/tasa-arvo in different
text genres
Master chart
my_d <- d %>%
filter(category %in% c("yhdenvertaisuus","tasa-arvo")) %>%
mutate(year_created=year(date_created),week_created=week(date_created)) %>%
group_by(media,category,type,type2,year_created) %>%
summarize(articles=n_distinct(a_id),days=n_distinct(date_created),.groups="drop") %>%
inner_join(articles_by_type_by_year,by=c("media","type","year_created")) %>%
collect()
my_d2 <- d %>%
filter(category %in% c("yhdenvertaisuus","tasa-arvo")) %>%
mutate(year_created=year(date_created),week_created=week(date_created)) %>%
group_by(a_id,media,type,type2,year_created) %>%
filter(any(category=="yhdenvertaisuus"),any(category=="tasa-arvo")) %>%
group_by(media,type,type2,year_created) %>%
summarize(articles=n_distinct(a_id),days=n_distinct(date_created),.groups="drop") %>%
inner_join(articles_by_type_by_year,by=c("media","type","year_created")) %>%
collect()
Warning: Missing values are always removed in SQL aggregation functions.
Use `na.rm = TRUE` to silence this warning
This warning is displayed once every 8 hours.
my_d <- my_d %>%
mutate(word="Word") %>%
union_all(my_d2 %>%
mutate(category="tasa-arvo") %>%
mutate(word="Both")) %>%
union_all(my_d2 %>%
mutate(category="yhdenvertaisuus") %>%
mutate(word="Both")) %>%
mutate(
word=fct_relevel(word,"Word"),
category=fct_relevel(category,"tasa-arvo","yhdenvertaisuus"),
type2=fct_relevel(type2,"External opinion", "Journalistic opinion", "Journalistic text in Domestic general/political/economic news", "Quotes in Domestic general/political/economic news", "Journalistic text in Local news", "Quotes in Local news", "Journalistic text in Foreign news", "Quotes in Foreign news", "Journalistic text in Culture/entertainment", "Quotes in Culture/entertainment", "Journalistic text in Sports", "Quotes in Sports"))
my_d %>%
filter(type=="Other") %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=media,linetype=word)) +
geom_step() +
geom_vline(xintercept = 2009,color="red") +
theme_hsci_discrete(base_family="Arial") +
scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
scale_x_continuous(breaks=seq(2000,2020,by=4)) +
facet_grid(category~type2,scales="free") +
labs(color="Media",linetype="Signal") +
xlab("Year") +
ylab("Percentage of articles of type containing the word")
1:3 %>% map(~
my_d %>%
filter(type!="Other") %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=media,linetype=word)) +
geom_step() +
geom_vline(xintercept = 2009,color="red") +
theme_hsci_discrete(base_family="Arial") +
scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
scale_x_continuous(breaks=seq(2000,2020,by=4)) +
facet_grid_paginate(category~type2,scales="free", nrow=2, ncol=4, page=.x) +
labs(color="Media",linetype="Signal") +
xlab("Year") +
ylab("Percentage of articles of type containing the word")
)
[[1]]
[[2]]
[[3]]



Conclusions:
- IL is behind other media in change, but same trajectory
- For foreign news, STT (and therefore IL) do not increase tasa-arvo
terminology usage
- For local news, terminology usage increases only for HS (Helsinki)
as opposed to YLE (regional news)
- For culture/entertainment, other sources differ from IL. This is
probably due to category heterogeneity: for IL, this category contains
entertainment news, for others, these are more culture reviews etc.
Final graph to include in article
d %>%
filter(category %in% c("yhdenvertaisuus","tasa-arvo")) %>%
filter(type %in% c("Domestic general/political/economic news", "Journalistic opinion", "External opinion")) %>%
left_join(articles_by_type_by_year %>% group_by(type,year_created) %>%
summarize(total_articles=sum(total_articles),.groups="drop"),by=c("type","year_created")) %>%
group_by(category,type2,year_created) %>%
summarize(total_articles=min(total_articles),articles=n_distinct(a_id),days=n_distinct(date_created),.groups="drop") %>%
collect() %>%
mutate(type2=fct_relevel(type2,"External opinion","Journalistic opinion")) %>%
mutate(category=fct_relevel(category,"yhdenvertaisuus")) %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=type2)) +
geom_step() +
theme_hsci_discrete(base_family="Arial") +
scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
scale_x_continuous(breaks=seq(2000,2020,by=5)) +
facet_wrap(~category, scales="free_y") +
labs(color="Text type") +
xlab("Year") +
ylab("Percentage of articles of type containing the word") +
theme(legend.justification = c(0, 1), legend.position = c(0.02, 0.98), legend.background = element_blank(), legend.box.just = "bottom", legend.key = element_blank(), legend.box = "horizontal")

Analysis 2: distribution of language by speaker and subject
category
d %>%
filter(org_cat %in% c("politiikka", "oikeus"), category %in% c("yhdenvertaisuus", "tasa-arvo"), in_quote == T) %>%
group_by(org_cat,year_created, category) %>%
summarize(n=n(),.groups="drop") %>%
ggplot(aes(x=year_created,y=n,color=category)) +
geom_step() +
theme_hsci_discrete(base_family="Arial") +
facet_grid(~org_cat, scales="free")

d %>%
filter(org_cat %in% c("politiikka", "oikeus"), category %in% key_cats, in_quote == T) %>%
group_by(org_cat,year_created, category) %>%
summarize(n=n(),.groups="drop") %>%
ggplot(aes(x=year_created,y=n,color=category)) +
geom_step() +
theme_hsci_discrete(base_family="Arial") +
facet_grid(~org_cat, scales="free")

Analysis 3: subject associations
sp <- yv_ta_paragraphs %>%
inner_join(
words %>%
filter(lemma=="suku#puoli") %>%
inner_join(corpus)
) %>% inner_join(articles %>% select(a_id,date_created,media)) %>%
inner_join(article_types) %>%
inner_join(articles_to_ref_categories) %>%
left_join(quotation_sentence_corpus %>% mutate(in_quote_sentence=T)) %>%
mutate(year_created=year(date_created)) %>%
mutate(week_created=week(date_created)) %>%
mutate(type2=case_when(
str_detect(type,"opinion$") ~ type,
in_quote_sentence ~ str_c("Quotes in ",type),
TRUE ~ str_c("Journalistic text in ",type)
)) %>%
group_by(media,ref_category,type,type2,year_created) %>%
summarize(articles=n_distinct(a_id),weeks=n_distinct(week_created),days=n_distinct(date_created),.groups="drop") %>%
collect() %>%
mutate(
ref_category=fct_relevel(ref_category,"tasa-arvo","yhdenvertaisuus"),
type2=fct_relevel(type2,"External opinion", "Journalistic opinion", "Journalistic text in Domestic general/political/economic news", "Quotes in Domestic general/political/economic news", "Journalistic text in Local news", "Quotes in Local news", "Journalistic text in Foreign news", "Quotes in Foreign news", "Journalistic text in Culture/entertainment", "Quotes in Culture/entertainment", "Journalistic text in Sports", "Quotes in Sports"))
Joining, by = "w_id"
Joining, by = c("a_id", "par_id")
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = c("a_id", "par_id", "s_id", "pos")
my_cd <- corpus_of_interest %>%
filter(lemma!="suomalainen") %>%
inner_join(yv_ta_paragraphs) %>%
inner_join(articles %>% select(a_id,date_created,media)) %>%
inner_join(article_types) %>%
inner_join(articles_to_ref_categories) %>%
mutate(year_created=year(date_created)) %>%
mutate(week_created=week(date_created)) %>%
left_join(quotation_sentence_corpus %>% mutate(in_quote_sentence=T)) %>%
mutate(type2=case_when(
str_detect(type,"opinion$") ~ type,
in_quote_sentence ~ str_c("Quotes in ",type),
TRUE ~ str_c("Journalistic text in ",type)
))
Joining, by = c("a_id", "par_id")
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = c("a_id", "par_id", "s_id", "pos")
cd2 <- my_cd %>%
group_by(ref_category,genus,type,type2,year_created) %>%
summarize(articles=n_distinct(a_id),weeks=n_distinct(week_created),days=n_distinct(date_created),.groups="drop") %>%
collect() %>%
mutate(
ref_category=fct_relevel(ref_category,"tasa-arvo","yhdenvertaisuus"),
type2=fct_relevel(type2,"External opinion", "Journalistic opinion", "Journalistic text in Domestic general/political/economic news", "Quotes in Domestic general/political/economic news", "Journalistic text in Local news", "Quotes in Local news", "Journalistic text in Foreign news", "Quotes in Foreign news", "Journalistic text in Culture/entertainment", "Quotes in Culture/entertainment", "Journalistic text in Sports", "Quotes in Sports"))
cd <- my_cd %>%
group_by(ref_category,category,type,type2,year_created) %>%
summarize(articles=n_distinct(a_id),weeks=n_distinct(week_created),days=n_distinct(date_created),.groups="drop") %>%
collect() %>%
mutate(
ref_category=fct_relevel(ref_category,"tasa-arvo","yhdenvertaisuus"),
type2=fct_relevel(type2,"External opinion", "Journalistic opinion", "Journalistic text in Domestic general/political/economic news", "Quotes in Domestic general/political/economic news", "Journalistic text in Local news", "Quotes in Local news", "Journalistic text in Foreign news", "Quotes in Foreign news", "Journalistic text in Culture/entertainment", "Quotes in Culture/entertainment", "Journalistic text in Sports", "Quotes in Sports"))
Gender
my_d <- sp %>%
filter(type!="Other") %>%
inner_join(articles_by_type_by_year %>%
group_by(year_created,type) %>%
summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>%
collect()
Joining, by = c("type", "year_created")
1:3 %>% map(~
my_d %>%
filter(ref_category!="both") %>%
mutate(fct=ref_category,word="Word") %>%
union_all(
my_d %>%
filter(ref_category=="both") %>%
mutate(fct="tasa-arvo",word="Both")
) %>%
union_all(
my_d %>%
filter(ref_category=="both") %>%
mutate(fct="yhdenvertaisuus",word="Both")
) %>%
mutate(word=fct_relevel(word,"Word")) %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=media,linetype=word)) +
geom_step() +
geom_vline(xintercept = 2009,color="red") +
theme_hsci_discrete(base_family="Arial") +
scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
scale_x_continuous(breaks=seq(2000,2020,by=4)) +
facet_grid_paginate(fct~type2,scales="free",ncol=4,nrow=2,page=.x) +
labs(color="Media",linetype="Signal") +
xlab("Year") +
ylab("Percentage of articles of type containing the word")
)
[[1]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[3]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?



1:3 %>% map(~
my_d %>%
filter(ref_category!="both") %>%
mutate(fct=ref_category,word="Word") %>%
union_all(
my_d %>%
filter(ref_category=="both") %>%
mutate(fct="tasa-arvo",word="Both")
) %>%
union_all(
my_d %>%
filter(ref_category=="both") %>%
mutate(fct="yhdenvertaisuus",word="Both")
) %>%
mutate(word=fct_relevel(word,"Word")) %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=media,linetype=word)) +
geom_step() +
geom_vline(xintercept = 2009,color="red") +
theme_hsci_discrete(base_family="Arial") +
scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
scale_x_continuous(breaks=seq(2000,2020,by=4)) +
facet_wrap_paginate(fct~type2,scales="free",ncol=4,nrow=2,page=.x) +
labs(color="Media",linetype="Signal") +
xlab("Year") +
ylab("Percentage of articles of type containing the word")
)
[[1]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[3]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?



Conclusions:
- Decline in “sukupuolten tasa-arvo” in STT for domestic news is
interesting. What could cause this?
- Otherwise, all sources seem to be following similar patterns.
sp %>%
filter(type=="Domestic general/political/economic news") %>%
group_by(ref_category,type,type2,year_created) %>%
summarize(articles=sum(articles),.groups="drop") %>%
inner_join(articles_by_type_by_year %>%
group_by(year_created,type) %>%
summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=ref_category,linetype=type2)) +
geom_step() +
theme_hsci_discrete(base_family="Arial") +
scale_x_continuous(breaks=seq(2000,2020,by=2))
Joining, by = c("type", "year_created")

Conclusions:
- Gender equality discussion also gets a boost after 2014
- When “yhdenvertaisuus” is used in relation to gender, “tasa-arvo” is
almost always also mentioned!
my_d <- cd2 %>%
filter(type!="Other") %>%
inner_join(articles_by_type_by_year %>%
group_by(year_created,type) %>%
summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>%
collect()
Joining, by = c("type", "year_created")
1:3 %>% map(~
my_d %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=ref_category)) +
geom_step() +
geom_vline(xintercept = 2009,color="red") +
theme_hsci_discrete(base_family="Arial") +
scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
scale_x_continuous(breaks=seq(2000,2020,by=4)) +
facet_grid_paginate(genus~type2,scales="free",ncol=4,nrow=2,page=.x) +
labs(color="ref-category",linetype="Signal") +
xlab("Year") +
ylab("Percentage of articles of type containing the word")
)
[[1]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[3]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?



1:3 %>% map(~
my_d %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=ref_category)) +
geom_step() +
geom_vline(xintercept = 2009,color="red") +
theme_hsci_discrete(base_family="Arial") +
scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
scale_x_continuous(breaks=seq(2000,2020,by=4)) +
facet_wrap_paginate(genus~type2,scales="free",ncol=4,nrow=2,page=.x) +
labs(color="ref-category",linetype="Signal") +
xlab("Year") +
ylab("Percentage of articles of type containing the word")
)
[[1]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[3]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?



Conclusions:
- Same behavior seen for “sukupuolten tasa-arvo/yhdenvertaisuus” is
also evident when looking at explicitly gendered words
(mies/nainen)
Subject topic
1:3 %>% map(~
cd %>%
filter(type!="Other") %>%
filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
inner_join(articles_by_type_by_year %>%
group_by(year_created,type) %>%
summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=category)) +
geom_step() +
theme_hsci_discrete(base_family="Arial") +
scale_x_continuous(breaks=seq(2000,2020,by=4)) +
facet_grid_paginate(ref_category~type2,scales="free",nrow=2,ncol=4,page=.x)
)
Joining, by = c("type", "year_created")
Joining, by = c("type", "year_created")
Joining, by = c("type", "year_created")
[[1]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[3]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?



1:3 %>% map(~
cd %>%
filter(type!="Other") %>%
filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
inner_join(articles_by_type_by_year %>%
group_by(year_created,type) %>%
summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=category)) +
geom_step() +
theme_hsci_discrete(base_family="Arial") +
scale_x_continuous(breaks=seq(2000,2020,by=4)) +
facet_wrap_paginate(ref_category~type2,scales="free",nrow=2,ncol=4,page=.x)
)
Joining, by = c("type", "year_created")
Joining, by = c("type", "year_created")
Joining, by = c("type", "year_created")
[[1]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[3]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?



Conclusions:
- There don’t seem to be major discernible patterns between different
subjects for equality
Supporting auxiliary analyses
Subject topic graphs using different measures
cd %>%
filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
group_by(ref_category) %>%
group_map(~.x %>%
ggplot(aes(x=year_created,y=days,color=category)) +
geom_line() +
theme_hsci_discrete(base_family="Arial") +
scale_x_continuous(breaks=seq(2000,2020,by=2)) +
facet_wrap(~type2,scales="free") +
ggtitle(.y[1]$ref_category))
[[1]]
[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[3]]



cd %>%
filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
group_by(ref_category) %>%
group_map(~.x %>%
ggplot(aes(x=year_created,y=weeks,color=category)) +
geom_line() +
theme_hsci_discrete(base_family="Arial") +
scale_x_continuous(breaks=seq(2000,2020,by=2)) +
facet_wrap(~type2,scales="free") +
ggtitle(.y[1]$ref_category))
[[1]]
[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[3]]



cd %>%
filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
inner_join(articles_by_type_by_year %>%
group_by(year_created,type) %>%
summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>%
group_by(ref_category) %>%
group_map(~.x %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=category)) +
geom_line() +
theme_hsci_discrete(base_family="Arial") +
scale_x_continuous(breaks=seq(2000,2020,by=2)) +
facet_wrap(~type2,scales="free") +
ggtitle(.y[1]$ref_category))
Joining, by = c("type", "year_created")
[[1]]
[[2]]
geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?
[[3]]



Do the subject topics combined capture the phenomenon?
cd3 <- yv_ta_paragraphs %>%
inner_join(corpus_of_interest) %>%
filter(lemma!="suomalainen") %>%
inner_join(articles %>% select(a_id,date_created,media)) %>%
inner_join(article_types) %>%
inner_join(articles_to_ref_categories) %>%
mutate(year_created=year(date_created)) %>%
mutate(week_created=week(date_created)) %>%
mutate(category="potilas") %>%
group_by(ref_category,category,type,year_created) %>%
summarize(articles=n_distinct(a_id),weeks=n_distinct(week_created),days=n_distinct(date_created),.groups="drop") %>%
collect()
Joining, by = c("a_id", "par_id")
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = "a_id"
cd3 %>%
filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
mutate(type=fct_relevel(type,"foreign","sports","other",after=Inf)) %>%
group_by(ref_category) %>%
group_map(~.x %>%
ggplot(aes(x=year_created,y=days,color=category)) +
geom_line() +
theme_hsci_discrete(base_family="Arial") +
scale_x_continuous(breaks=seq(2000,2020,by=2)) +
facet_wrap(~type,scales="free") +
ggtitle(.y[1]$ref_category))
Warning: Problem while computing `type = fct_relevel(type, "foreign", "sports", "other", after = Inf)`.
ℹ Unknown levels in `f`: foreign, sports, other
[[1]]
[[2]]
[[3]]



cd3 %>%
filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
mutate(type=fct_relevel(type,"foreign","sports","other",after=Inf)) %>%
group_by(ref_category) %>%
group_map(~.x %>%
ggplot(aes(x=year_created,y=weeks,color=category)) +
geom_line() +
theme_hsci_discrete(base_family="Arial") +
scale_x_continuous(breaks=seq(2000,2020,by=2)) +
facet_wrap(~type,scales="free") +
ggtitle(.y[1]$ref_category))
Warning: Problem while computing `type = fct_relevel(type, "foreign", "sports", "other", after = Inf)`.
ℹ Unknown levels in `f`: foreign, sports, other
[[1]]
[[2]]
[[3]]



cd3 %>%
filter(category %in% c("etnos","potilas","seksuaalisuus","työsuhde","maahanmuutto")) %>%
inner_join(articles_by_type_by_year %>%
group_by(year_created,type) %>%
summarize(total_articles=sum(total_articles),.groups="drop") %>% collect()) %>%
mutate(type=fct_relevel(type,"foreign","sports","other",after=Inf)) %>%
group_by(ref_category) %>%
group_map(~.x %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=category)) +
geom_line() +
theme_hsci_discrete(base_family="Arial") +
scale_x_continuous(breaks=seq(2000,2020,by=2)) +
facet_wrap(~type,scales="free") +
ggtitle(.y[1]$ref_category))
Joining, by = c("type", "year_created")
Warning: Problem while computing `type = fct_relevel(type, "foreign", "sports", "other", after = Inf)`.
ℹ Unknown levels in `f`: foreign, sports, other
[[1]]
[[2]]
[[3]]



Conclusions:
- While we saw no discernible patterns between subjects, we do seem to
be capturing the “whole” of equality discussion by targeting them ->
can conclude that everyone benefits.
Background Analyses
articles %>%
inner_join(articles_to_ref_categories) %>%
inner_join(article_types) %>%
mutate(year_created=year(date_created),week_created=week(date_created)) %>%
group_by(media,ref_category,type,year_created) %>%
summarize(articles=n_distinct(a_id),weeks=n_distinct(week_created),days=n_distinct(date_created),.groups="drop") %>%
ggplot(aes(x=year_created,y=days,color=media)) +
geom_step() +
theme_hsci_discrete(base_family="Arial") +
scale_x_continuous(breaks=seq(2000,2020,by=2)) +
facet_grid(ref_category~type,scales="free")
Joining, by = "a_id"
Joining, by = "a_id"

articles %>%
inner_join(articles_to_ref_categories) %>%
inner_join(article_types) %>%
mutate(year_created=year(date_created),week_created=week(date_created)) %>%
group_by(media,ref_category,type,year_created) %>%
summarize(articles=n_distinct(a_id),weeks=n_distinct(week_created),days=n_distinct(date_created),.groups="drop") %>%
ggplot(aes(x=year_created,y=weeks,color=media)) +
geom_step() +
theme_hsci_discrete(base_family="Arial") +
scale_x_continuous(breaks=seq(2000,2020,by=2)) +
facet_grid(ref_category~type,scales="free")
Joining, by = "a_id"
Joining, by = "a_id"

articles %>%
inner_join(articles_to_ref_categories) %>%
inner_join(article_types) %>%
mutate(year_created=year(date_created),week_created=week(date_created)) %>%
group_by(media,ref_category,type,year_created) %>%
summarize(articles=n_distinct(a_id),days=n_distinct(date_created),.groups="drop") %>%
inner_join(articles_by_type_by_year) %>%
ggplot(aes(x=year_created,y=articles/total_articles,color=media)) +
geom_step() +
theme_hsci_discrete(base_family="Arial") +
scale_y_continuous(labels=scales::percent_format(accuracy=0.1)) +
scale_x_continuous(breaks=seq(2000,2020,by=2)) +
facet_grid(ref_category~type,scales="free")
Joining, by = "a_id"
Joining, by = "a_id"
Joining, by = c("media", "type", "year_created")

Auxiliary background analyses
articles %>%
mutate(year_created=year(date_created),month_created=month(date_created)) %>%
count(media,year_created,month_created) %>%
ggplot(aes(x=as.Date(str_c(year_created,'-',month_created,'-01')),y=n,color=media)) +
geom_step() +
theme_hsci_discrete()

articles %>%
inner_join(article_types) %>%
mutate(year_created=year(date_created)) %>%
count(media,year_created,type) %>%
ggplot(aes(x=year_created,y=n,color=type)) +
geom_step() +
facet_wrap(~media,scales="free") +
theme_hsci_discrete()
Joining, by = "a_id"

articles %>%
inner_join(article_types) %>%
mutate(year_created=year(date_created)) %>%
mutate(from_stt=author=="STT") %>%
filter(media=="IL") %>%
count(media,year_created,type,from_stt) %>%
collect() %>%
group_by(media) %>%
mutate(type=fct_lump_n(type,11,w=n)) %>%
count(media,year_created,type,from_stt,wt=n) %>%
ggplot(aes(x=year_created,y=n,color=from_stt==1)) +
geom_step() +
facet_wrap(type~media,scales="free") +
theme_hsci_discrete()
Joining, by = "a_id"

LS0tCnRpdGxlOiAiRkxPUE8gWVYvVEEgYW5hbHlzaXMiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICB0b2M6IHllcwotLS0KCiMgR2VuZXJhbCBTZXR1cAoKYGBge3Igc2V0dXAsaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSBoZXJlOjpoZXJlKCkpCmxpYnJhcnkoaGVyZSkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoREJJKQpsaWJyYXJ5KGdsdWUpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGhtcykKbGlicmFyeShnZ2JlZXN3YXJtKQpsaWJyYXJ5KGdnZm9yY2UpCmxpYnJhcnkocGFrKQpwa2dfaW5zdGFsbCgiaHNjaS1yL2dnaHNjaSIpCmxpYnJhcnkoZ2doc2NpKQpsaWJyYXJ5KFJNYXJpYURCKQoKY29uIDwtIERCSTo6ZGJDb25uZWN0KAogIFJNYXJpYURCOjpNYXJpYURCKCksIAogIGhvc3QgPSAiMTI4LjIxNC4yNTMuMjExIiwgCiAgZGJuYW1lID0gImZsb3BvIiwgCiAgdXNlciA9ICJyb290IiwgCiAgcGFzc3dvcmQgPSAiZGhoMTciLAogIGJpZ2ludCA9ICJpbnRlZ2VyIiwKICBsb2FkX2RhdGFfbG9jYWxfaW5maWxlID0gVFJVRSwKICBhdXRvY29tbWl0ID0gVFJVRSwKICByZWNvbm5lY3QgPSBUUlVFKQpkYkV4ZWN1dGUoY29uLCAiU0VUIFNFU1NJT04gc3RvcmFnZV9lbmdpbmU9YXJpYSIpCgp0YmwoY29uLCAiYV9zaW0iKQphY3Rvcl9tZW50aW9ucyA8LSB0YmwoY29uLCAiYWN0b3JfbWVudGlvbnMiKQphY3Rvcl9vcmcgPC0gdGJsKGNvbiwgImFjdG9yX29yZyIpCmFjdG9yX3JvbGVzIDwtIHRibChjb24sICJhY3Rvcl9yb2xlcyIpCmFjdG9ycyA8LSB0YmwoY29uLCAiYWN0b3JzIikKYXJ0aWNsZXMgPC0gdGJsKGNvbiwgImFydGljbGVzIikKY29ycHVzIDwtIHRibChjb24sICJjb3JwdXMiKQptaXNjIDwtIHRibChjb24sICJtaXNjIikKcV9xYSA8LSB0YmwoY29uLCAicV9xYSIpCnF1b3RlX2F1dGhvcnMgPC0gdGJsKGNvbiwgInF1b3RlX2F1dGhvcnMiKQpxdW90ZXMgPC0gdGJsKGNvbiwgInF1b3RlcyIpCndvcmRzIDwtIHRibChjb24sICJ3b3JkcyIpCnF1b3RlX2F1dGhvcl9uYW1lc190b19jYW5vbmljYWxfbmFtZXMgPC0gdGJsKGNvbiwgInF1b3RlX2F1dGhvcl9uYW1lc190b19jYW5vbmljYWxfbmFtZXMiKQphY3Rvcl9uYW1lc190b19jYW5vbmljYWxfbmFtZXMgPC0gdGJsKGNvbiwgImFjdG9yX25hbWVzX3RvX2Nhbm9uaWNhbF9uYW1lcyIpCmFjdG9yX3JvbGVzX3RvX2Nhbm9uaWNhbF9yb2xlcyA8LSB0YmwoY29uLCAiYWN0b3Jfcm9sZXNfdG9fY2Fub25pY2FsX3JvbGVzIikKYWN0b3Jfb3Jnc190b19jYW5vbmljYWxfb3JncyA8LSB0YmwoY29uLCAiYWN0b3Jfb3Jnc190b19jYW5vbmljYWxfb3JncyIpCmFfY2FuX25hbWVzX3RvX2Nhbl9vcmdzX3JvbGVzX2J5X3RfY3JlYXRlZCA8LSB0YmwoY29uLCAiYV9jYW5fbmFtZXNfdG9fY2FuX29yZ3Nfcm9sZXNfYnlfdF9jcmVhdGVkIikKYGBgCgojIEFuYWx5c2lzIHRhYmxlIGNyZWF0aW9uLiBEb24ndCBydW4gaWYgYWxyZWFkeSBjcmVhdGVkLiBJbnN0ZWFkIHNraXAgdG8gIkFuYWx5c2lzIHRhYmxlIGxvYWRzIgoKYGBge3IsZXZhbD1GQUxTRX0KZGJFeGVjdXRlKGNvbiwiRFJPUCBUQUJMRSBJRiBFWElTVFMgYXJ0aWNsZXNfY2RwIikKYXJ0aWNsZXNfY2RwIDwtIGFydGljbGVzICU+JSBmaWx0ZXIoY2FzZV93aGVuKAogIG1lZGlhID09ICJIUyIgfiBzZWN0aW9uICVpbiUgYygiS290aW1hYSIsICJQb2xpdGlpa2thIiwgIlRhbG91cyIpLAogIG1lZGlhID09ICJJTCIgfiBzdWJzZWN0aW9uICVpbiUgYygia290aW1hYSIsInBvbGl0aWlra2EiLCJ0YWxvdXMiLCJ1dXRpc2V0IiksCiAgbWVkaWEgPT0gIlNUVCIgfiBzZWN0aW9uICVpbiUgYygiS290aW1hYSIsIlBvbGl0aWlra2EiLCJUYWxvdXMiKSwKICBtZWRpYSA9PSAiWUxFIiB+IHNlY3Rpb24gPT0gIllsZSBVdXRpc2V0IiAmIHN0cl9kZXRlY3Qoc3ViamVjdCwiS290aW1hYW4gdXV0aXNldHxwb2xpdGlpa2thfHRhbG91cyIpICYgKCFzdHJfZGV0ZWN0KHN1YmplY3QsIlVsa29tYWF0IikgfCBzdHJfZGV0ZWN0KHN1YmplY3QsIktvdGltYWFuIHV1dGlzZXQiKSksCiAgVCB+IEYKKSkgJT4lIAogIGRpc3RpbmN0KGFfaWQpICU+JSAKICBjb21wdXRlKG5hbWU9ImFydGljbGVzX2NkcCIsdGVtcG9yYXJ5PUYsdW5pcXVlX2luZGV4ZXM9YygiYV9pZCIpKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CmRiRXhlY3V0ZShjb24sIkRST1AgVEFCTEUgSUYgRVhJU1RTIGFydGljbGVzX29waW5pb25hdGVkIikKYXJ0aWNsZXNfb3BpbmlvbmF0ZWQgPC0gYXJ0aWNsZXMgJT4lIG11dGF0ZShvcGluaW9uYXRlZD1jYXNlX3doZW4oCiAgbWVkaWEgPT0gIkhTIiB+IGNhc2Vfd2hlbigKICAgIHN0cl90b19sb3dlcihzZWN0aW9uKSA9PSAicMOkw6RraXJqb2l0dXMiICYgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIoc3RvcnlfbG9nbyksImllcmFzIikgfiAiZXh0ZXJuYWwgZWRpdG9yaWFsIiwKICAgIHN0cl90b19sb3dlcihzZWN0aW9uKSA9PSAicMOkw6RraXJqb2l0dXMiICYgaXMubmEoc3RvcnlfbG9nbykgfiAiZWRpdG9yaWFsIiwKICAgIHN0cl90b19sb3dlcihzZWN0aW9uKSA9PSAicMOkw6RraXJqb2l0dXMiICYgc3RyX3RvX2xvd2VyKHN0b3J5X2xvZ28pID09ICJww6TDpGtpcmpvaXR1cyIgfiAiZWRpdG9yaWFsIiwKICAgIHN0cl90b19sb3dlcihzZWN0aW9uKSA9PSAibWllbGlwaWRlIiB8IHN0cl90b19sb3dlcihzdG9yeV9sb2dvKSA9PSAibWllbGlwaWRlIiB+ICJleHRlcm5hbCBvcGluaW9uIiwKICAgIHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHRpdGxlKSwiYW5hbHl5c2k6IikgfCBzdHJfZGV0ZWN0KHN0cl90b19sb3dlcihzdG9yeV9sb2dvKSwiYW5hbHl5c2kiKSAgfiAiYW5hbHlzaXMiLAogICAgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIodGl0bGUpLCJuw6Rrw7ZrdWxtYToiKSB8IHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHN0b3J5X2xvZ28pLCJuw6Rrw7ZrdWxtYSIpIH4gInBlcnNwZWN0aXZlIiwKICAgIHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHRpdGxlKSwia29sdW1uaToiKSB8IHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHN0b3J5X2xvZ28pLCJrb2x1bW5pIikgfiAiY29sdW1uIiwKICAgIHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHRpdGxlKSwiYmxvZ2k6IikgfCBzdHJfZGV0ZWN0KHN0cl90b19sb3dlcihzdG9yeV9sb2dvKSwiYmxvZyIpIH4gImJsb2ciICAgIAogICksCiAgbWVkaWEgPT0gIklMIiB+IGNhc2Vfd2hlbigKICAgIHN1YnNlY3Rpb24gPT0gInBhYWtpcmpvaXR1cyIgfiAiZWRpdG9yaWFsIiwKICAgIHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHRpdGxlKSwia29tbWVudHRpOiIpIH4gImNvbW1lbnRhcnkiLAogICAgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIodGl0bGUpLCJhbmFseXlzaToiKSB+ICJhbmFseXNpcyIsCiAgICBzdHJfZGV0ZWN0KHN0cl90b19sb3dlcih0aXRsZSksImtvbHVtbmk6IikgfiAiY29sdW1uIiwKICAgIHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHRpdGxlKSwibsOka8O2a3VsbWE6IikgfiAicGVyc3BlY3RpdmUiCiAgKSwKICBtZWRpYSA9PSAiWUxFIiB+IGNhc2Vfd2hlbigKICAgIHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHRpdGxlKSwia29tbWVudHRpOiIpIH4gImNvbW1lbnRhcnkiLAogICAgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIodGl0bGUpLCJhbmFseXlzaToiKSB8IHN0cl9kZXRlY3Qoc3ViamVjdCwiQW5hbHl5c2l0IFxcKFlsZSBVdXRpc2V0XFwpIikgfiAiYW5hbHlzaXMiLAogICAgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIodGl0bGUpLCJrb2x1bW5pOiIpIHwgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIoc3ViamVjdCksImtvbHVtbiIpIH4gImNvbHVtbiIsCiAgICBzdHJfZGV0ZWN0KHN0cl90b19sb3dlcih0aXRsZSksIm7DpGvDtmt1bG1hOiIpICB8IHN0cl9kZXRlY3Qoc3RyX3RvX2xvd2VyKHN1YmplY3QpLCJuw6Rrw7ZrdWxtIikgfiAicGVyc3BlY3RpdmUiLAogICAgc3RyX2RldGVjdChzdHJfdG9fbG93ZXIodGl0bGUpLCJibG9naToiKSAgfCBzdHJfZGV0ZWN0KHN0cl90b19sb3dlcihzdWJqZWN0KSwiYmxvZyIpIH4gImJsb2ciCiAgKQopKSAlPiUKICBmaWx0ZXIoIWlzLm5hKG9waW5pb25hdGVkKSkgJT4lCiAgZGlzdGluY3QoYV9pZCwgb3BpbmlvbmF0ZWQpICU+JQogIGNvbXB1dGUobmFtZT0iYXJ0aWNsZXNfb3BpbmlvbmF0ZWQiLHRlbXBvcmFyeT1GLHVuaXF1ZV9pbmRleGVzPWMoImFfaWQiKSkKYGBgCgpgYGB7cixldmFsPUZBTFNFfQpsYWJlbHMgPC0gcmVhZF90c3YoaGVyZSgiZGF0YS9wZXJzb25fbGFiZWxzLnRzdiIpKSAlPiUKICBmaWx0ZXIoIWNhdGVnb3J5ICVpbiUgYygnYWRqZWt0aWl2aScsICdlaScpKQoKbGVtbWFzX29mX2ludGVyZXN0IDwtIGxhYmVscyAlPiUKICByZW5hbWUoImxlbW1hIiA9ICJuYW1lIikgJT4lCiAgY29weV90byhjb24sLixuYW1lPSJsYWJlbHMiLG92ZXJ3cml0ZT1UKSAlPiUKICB1bmlvbl9hbGwod29yZHMgJT4lCiAgICBmaWx0ZXIoc3RyX2RldGVjdChsZW1tYSwgInloZGVuI3ZlIikpICU+JSAKICAgICAgZGlzdGluY3QobGVtbWEpICU+JSAKICAgICAgbXV0YXRlKGNhdGVnb3J5PSJ5aGRlbnZlcnRhaXN1dXMiKSkgJT4lCiAgdW5pb25fYWxsKHdvcmRzICU+JQogICAgICBmaWx0ZXIoc3RyX2RldGVjdChsZW1tYSwgInRhc2EjYXJ2IikpICU+JSAKICAgICAgZGlzdGluY3QobGVtbWEpICU+JSAKICAgICAgbXV0YXRlKGNhdGVnb3J5PSJ0YXNhLWFydm8iKSkgJT4lCiAgZGlzdGluY3QoKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CmRiRXhlY3V0ZShjb24sIkRST1AgVEFCTEUgSUYgRVhJU1RTIHdvcmRzX29mX2ludGVyZXN0IikKd29yZHNfb2ZfaW50ZXJlc3QgPC0gd29yZHMgJT4lIAogIGlubmVyX2pvaW4obGVtbWFzX29mX2ludGVyZXN0KSAlPiUgCiAgZGlzdGluY3Qod19pZCxsZW1tYSxjYXRlZ29yeSxnZW51cykgJT4lIAogIGNvbXB1dGUobmFtZT0id29yZHNfb2ZfaW50ZXJlc3QiLHRlbXBvcmFyeT1GLGluZGV4ZXM9Yygid19pZCIsImNhdGVnb3J5IiwiZ2VudXMiKSkKYGBgCgpgYGB7cixldmFsPUZBTFNFfQpkYkV4ZWN1dGUoY29uLCJEUk9QIFRBQkxFIElGIEVYSVNUUyBjb3JwdXNfb2ZfaW50ZXJlc3QiKQpjb3JwdXNfb2ZfaW50ZXJlc3QgPC0gY29ycHVzICU+JQogIGlubmVyX2pvaW4od29yZHNfb2ZfaW50ZXJlc3QpICU+JQogIGNvbXB1dGUobmFtZT0iY29ycHVzX29mX2ludGVyZXN0Iix0ZW1wb3Jhcnk9RixpbmRleGVzPWxpc3QoYygiYV9pZCIsInBhcl9pZCIsInNfaWQiLCJwb3MiKSxjKCJ3X2lkIiksYygiZ2VudXMiKSxjKCJjYXRlZ29yeSIpKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CmRiRXhlY3V0ZShjb24sIkRST1AgVEFCTEUgSUYgRVhJU1RTIGFydGljbGVfdHlwZXMiKQphcnRpY2xlX3R5cGVzIDwtIGFydGljbGVzICU+JSAKICBsZWZ0X2pvaW4oYXJ0aWNsZXNfY2RwICU+JSBtdXRhdGUoY2RwPVQpKSAlPiUKICBsZWZ0X2pvaW4oYXJ0aWNsZXNfb3BpbmlvbmF0ZWQpICU+JQogIG11dGF0ZSh0eXBlPWNhc2Vfd2hlbigKICAgIG1lZGlhID09ICJTVFQiICYgdmVyc2lvbiAhPSAiTG9wcHV2ZXJzaW8iIH4gIk90aGVyIiwKICAgICFpcy5uYShvcGluaW9uYXRlZCkgJiAhc3RyX2RldGVjdChvcGluaW9uYXRlZCwiXmV4dGVybmFsICIpIH4gIkpvdXJuYWxpc3RpYyBvcGluaW9uIiwKICAgICFpcy5uYShvcGluaW9uYXRlZCkgfiAiRXh0ZXJuYWwgb3BpbmlvbiIsCiAgICBjZHAgfiAiRG9tZXN0aWMgZ2VuZXJhbC9wb2xpdGljYWwvZWNvbm9taWMgbmV3cyIsCiAgICBtZWRpYSA9PSAiSFMiICYgc2VjdGlvbiA9PSAiS3VsdHR1dXJpIiB+ICJDdWx0dXJlL2VudGVydGFpbm1lbnQiLAogICAgbWVkaWEgPT0gIklMIiAmIHNlY3Rpb24gPT0gInZpaWhkZSIgfiAiQ3VsdHVyZS9lbnRlcnRhaW5tZW50IiwKICAgIG1lZGlhID09ICJTVFQiICYgc2VjdGlvbiA9PSAiS3VsdHR1dXJpIiB+ICJDdWx0dXJlL2VudGVydGFpbm1lbnQiLAogICAgbWVkaWEgPT0gIllMRSIgJiBzZWN0aW9uID09ICJZbGUgVXV0aXNldCIgJiBzdHJfZGV0ZWN0KHN1YmplY3QsImt1bHR0dXVyaXxtdXNpaWtraXx2aWloZGUiKSAmICFzdHJfZGV0ZWN0KHN1YmplY3QsICJVbGtvbWFhdCIpIH4gIkN1bHR1cmUvZW50ZXJ0YWlubWVudCIsCiAgICBtZWRpYSA9PSAiSFMiICYgc2VjdGlvbiA9PSAiS2F1cHVua2kiIH4gIkxvY2FsIG5ld3MiLAogICAgbWVkaWEgPT0gIllMRSIgJiBzZWN0aW9uID09ICJZbGUgVXV0aXNldCIgJiBjb3ZlcmFnZT09ImxvY2FsIiB+ICJMb2NhbCBuZXdzIiwKICAgIG1lZGlhID09ICJTVFQiICYgc2VjdGlvbiA9PSAiVXJoZWlsdSIgfiAiU3BvcnRzIiwKICAgIG1lZGlhID09ICJIUyIgJiBzZWN0aW9uID09ICJVcmhlaWx1IiB+ICJTcG9ydHMiLAogICAgbWVkaWEgPT0gIllMRSIgJiBzZWN0aW9uID09ICJZTEUgVXJoZWlsdSIgfiAiU3BvcnRzIiwKICAgIG1lZGlhID09ICJJTCIgJiBzZWN0aW9uID09ICJ1cmhlaWx1IiB+ICJTcG9ydHMiLAogICAgbWVkaWEgPT0gIlNUVCIgJiBzZWN0aW9uID09ICJVbGtvbWFhdCIgfiAiRm9yZWlnbiBuZXdzIiwKICAgIG1lZGlhID09ICJIUyIgJiBzZWN0aW9uID09ICJVbGtvbWFhdCIgfiAiRm9yZWlnbiBuZXdzIiwKICAgIG1lZGlhID09ICJZTEUiICYgc2VjdGlvbiA9PSAiWWxlIFV1dGlzZXQiICYgc3RyX2RldGVjdChzdWJqZWN0LCJVbGtvbWFhdCIpICYgIXN0cl9kZXRlY3Qoc3ViamVjdCwiS290aW1hYW4gdXV0aXNldCIpIH4gIkZvcmVpZ24gbmV3cyIsCiAgICBtZWRpYSA9PSAiSUwiICYgc3Vic2VjdGlvbiA9PSAidWxrb21hYXQiIH4gIkZvcmVpZ24gbmV3cyIsCiAgICBUIH4gIk90aGVyIgogICkpICU+JQogIGRpc3RpbmN0KGFfaWQsdHlwZSkgJT4lCiAgY29tcHV0ZSh0ZW1wb3Jhcnk9RixuYW1lPSJhcnRpY2xlX3R5cGVzIix1bmlxdWVfaW5kZXhlcz1saXN0KGMoImFfaWQiKSxjKCJhX2lkIiwidHlwZSIpLGMoInR5cGUiLCJhX2lkIikpKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CmRiRXhlY3V0ZShjb24sIkRST1AgVEFCTEUgSUYgRVhJU1RTIGFydGljbGVzX2J5X3R5cGVfYnlfeWVhciIpCmFydGljbGVzX2J5X3R5cGVfYnlfeWVhciA8LSBhcnRpY2xlcyAlPiUgCiAgaW5uZXJfam9pbihhcnRpY2xlX3R5cGVzKSAlPiUKICBtdXRhdGUoeWVhcl9jcmVhdGVkPXllYXIoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgY291bnQobWVkaWEseWVhcl9jcmVhdGVkLHR5cGUsbmFtZT0idG90YWxfYXJ0aWNsZXMiKSAlPiUKICBjb21wdXRlKHVuaXF1ZV9pbmRleGVzPWxpc3QoYygibWVkaWEiLCJ5ZWFyX2NyZWF0ZWQiLCJ0eXBlIikpLHRlbXBvcmFyeT1GLG5hbWU9ImFydGljbGVzX2J5X3R5cGVfYnlfeWVhciIpCmBgYAoKYGBge3IsZXZhbD1GQUxTRX0KZGJFeGVjdXRlKGNvbiwiRFJPUCBUQUJMRSBJRiBFWElTVFMgYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMiKQphcnRpY2xlc190b19yZWZfY2F0ZWdvcmllcyA8LSB3b3Jkc19vZl9pbnRlcmVzdCAlPiUKICAgIGZpbHRlcihjYXRlZ29yeSAlaW4lIGMoInRhc2EtYXJ2byIsInloZGVudmVydGFpc3V1cyIpKSAlPiUKICAgIGlubmVyX2pvaW4oY29ycHVzKSAlPiUKICAgIGdyb3VwX2J5KGFfaWQpICU+JQogICAgc3VtbWFyaXplKHl2PW1heChjYXRlZ29yeT09InloZGVudmVydGFpc3V1cyIpLHRhPW1heChjYXRlZ29yeT09InRhc2EtYXJ2byIpLC5ncm91cHM9ImRyb3AiKSAlPiUKICAgIG11dGF0ZShyZWZfY2F0ZWdvcnk9Y2FzZV93aGVuKHl2PT0xICYgdGE9PTEgfiAiYm90aCIseXY9PTEgfiAieWhkZW52ZXJ0YWlzdXVzIiwgdGE9PTEgfiAidGFzYS1hcnZvIikpICU+JSAKICBzZWxlY3QoYV9pZCxyZWZfY2F0ZWdvcnkpICU+JSAKICBjb21wdXRlKCkKYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMgPC0gYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMgJT4lIHVuaW9uX2FsbCgKICAgIGFydGljbGVzX3RvX3JlZl9jYXRlZ29yaWVzICU+JQogICAgZmlsdGVyKHJlZl9jYXRlZ29yeT09ImJvdGgiKSAlPiUgCiAgICBtdXRhdGUocmVmX2NhdGVnb3J5PSJ5aGRlbnZlcnRhaXN1dXMiKQogICkgJT4lCiAgdW5pb25fYWxsKAogICAgYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMgJT4lCiAgICBmaWx0ZXIocmVmX2NhdGVnb3J5PT0iYm90aCIpICU+JSAKICAgIG11dGF0ZShyZWZfY2F0ZWdvcnk9InRhc2EtYXJ2byIpCiAgKSAlPiUKICBjb21wdXRlKHRlbXBvcmFyeT1GLG5hbWU9ImFydGljbGVzX3RvX3JlZl9jYXRlZ29yaWVzIixpbmRleGVzPWMoImFfaWQiKSx1bmlxdWVfaW5kZXhlcz1saXN0KGMoImFfaWQiLCJyZWZfY2F0ZWdvcnkiKSxjKCJyZWZfY2F0ZWdvcnkiLCJhX2lkIikpKQpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9Cnl2X3RhX2NvcnB1cyA8LSB3b3Jkc19vZl9pbnRlcmVzdCAlPiUKICBmaWx0ZXIoY2F0ZWdvcnkgJWluJSBjKCJ0YXNhLWFydm8iLCJ5aGRlbnZlcnRhaXN1dXMiKSkgJT4lCiAgaW5uZXJfam9pbihjb3JwdXMpIAoKZGJFeGVjdXRlKGNvbiwiRFJPUCBUQUJMRSBJRiBFWElTVFMgeXZfdGFfcGFyYWdyYXBocyIpCnl2X3RhX3BhcmFncmFwaHMgPC0geXZfdGFfY29ycHVzICU+JQogIGRpc3RpbmN0KGFfaWQscGFyX2lkKSAlPiUKICBjb21wdXRlKHRlbXBvcmFyeT1GLG5hbWU9Inl2X3RhX3BhcmFncmFwaHMiLCB1bmlxdWVfaW5kZXhlcz1saXN0KGMoImFfaWQiLCJwYXJfaWQiKSkpCmBgYAoKIyBBbmFseXNpcyB0YWJsZSBsb2FkcwoKYGBge3J9CmFydGljbGVzX2NkcCA8LSB0YmwoY29uLCJhcnRpY2xlc19jZHAiKQphcnRpY2xlc19vcGluaW9uYXRlZCA8LSB0YmwoY29uLCJhcnRpY2xlc19vcGluaW9uYXRlZCIpCmFydGljbGVfdHlwZXMgPC0gdGJsKGNvbiwiYXJ0aWNsZV90eXBlcyIpCmFydGljbGVzX2J5X3R5cGVfYnlfeWVhciA8LSB0YmwoY29uLCJhcnRpY2xlc19ieV90eXBlX2J5X3llYXIiKQp3b3Jkc19vZl9pbnRlcmVzdCA8LSB0YmwoY29uLCJ3b3Jkc19vZl9pbnRlcmVzdCIpCmNvcnB1c19vZl9pbnRlcmVzdCA8LSB0YmwoY29uLCJjb3JwdXNfb2ZfaW50ZXJlc3QiKQphcnRpY2xlc190b19yZWZfY2F0ZWdvcmllcyA8LSB0YmwoY29uLCJhcnRpY2xlc190b19yZWZfY2F0ZWdvcmllcyIpCnl2X3RhX3BhcmFncmFwaHMgPC0gdGJsKGNvbiwieXZfdGFfcGFyYWdyYXBocyIpCmBgYAoKIyBOYW1lZCBxdWVyeSBkZWZpbml0aW9ucwoKYGBge3J9CnF1b3RhdGlvbl9jb3JwdXMgPC0gcXVvdGVzICU+JSAKICBpbm5lcl9qb2luKGNvcnB1cyxzcWxfb249IkxIUy5hX2lkPVJIUy5hX2lkIEFORCAoc19pZCA+IHN0YXJ0X3NfaWQgT1IgKHNfaWQ9c3RhcnRfc19pZCBBTkQgcG9zID49IHN0YXJ0X3BvcykpIEFORCAoc19pZCA8IGVuZF9zX2lkIE9SIChzX2lkPWVuZF9zX2lkIEFORCBwb3MgPD0gZW5kX3BvcykpIikgJT4lCiAgc2VsZWN0KGFfaWQ9YV9pZC54LHBhcl9pZCxzX2lkLHBvcywgcV9pZCkKCnF1b3RhdGlvbl9zZW50ZW5jZV9jb3JwdXMgPC0gcXVvdGVzICU+JSAKICBpbm5lcl9qb2luKGNvcnB1cyxzcWxfb249IkxIUy5hX2lkPVJIUy5hX2lkIEFORCBzX2lkID49IHN0YXJ0X3NfaWQgQU5EIHNfaWQgPD0gZW5kX3NfaWQiKSAlPiUKICBzZWxlY3QoYV9pZD1hX2lkLngscGFyX2lkLHNfaWQscG9zLCBxX2lkKQoKeXZfY29ycHVzIDwtIGNvcnB1c19vZl9pbnRlcmVzdCAlPiUgCiAgZmlsdGVyKGNhdGVnb3J5PT0ieWhkZW52ZXJ0YWlzdXVzIikKCnl2X3BhcmFncmFwaHMgPC0geXZfY29ycHVzICU+JSAKICBkaXN0aW5jdChhX2lkLHBhcl9pZCkKCnRhX2NvcnB1cyA8LSBjb3JwdXNfb2ZfaW50ZXJlc3QgJT4lIAogIGZpbHRlcihjYXRlZ29yeT09InRhc2EtYXJ2byIpCgp0YV9wYXJhZ3JhcGhzIDwtIHRhX2NvcnB1cyAlPiUgCiAgZGlzdGluY3QoYV9pZCxwYXJfaWQpCgpxdW90ZV9vcmdzIDwtIHJlYWRfdHN2KGhlcmUoImRhdGEvcV9pZF90b19vcmdzLnRzdiIpKSAlPiUKICBzZWxlY3QoYyhhdXRob3JfaGVhZCwgYV9pZCwgb3JnX2NhdCkpCgpkIDwtIGNvcnB1c19vZl9pbnRlcmVzdCAlPiUKICBpbm5lcl9qb2luKGFydGljbGVzICU+JSBzZWxlY3QoYV9pZCxkYXRlX2NyZWF0ZWQsbWVkaWEpKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVfdHlwZXMpICU+JQogIGxlZnRfam9pbihhcnRpY2xlc190b19yZWZfY2F0ZWdvcmllcykgJT4lCiAgbGVmdF9qb2luKHF1b3RhdGlvbl9jb3JwdXMgJT4lIG11dGF0ZShpbl9xdW90ZT1UKSkgJT4lCiAgbGVmdF9qb2luKHF1b3RhdGlvbl9zZW50ZW5jZV9jb3JwdXMgJT4lIG11dGF0ZShpbl9xdW90ZV9zZW50ZW5jZT1UKSkgJT4lCiAgbGVmdF9qb2luKHF1b3RlX29yZ3MsIGNvcHkgPSBUUlVFLCBhdXRvX2luZGV4ID0gVFJVRSkgJT4lCiAgbXV0YXRlKGluX3F1b3RlX2hlYWQ9aW5fcXVvdGVfc2VudGVuY2UgJiAhaW5fcXVvdGUpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpKSAlPiUKICBtdXRhdGUod2Vla19jcmVhdGVkPXdlZWsoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgbXV0YXRlKHR5cGUyPWNhc2Vfd2hlbigKICAgIHN0cl9kZXRlY3QodHlwZSwib3BpbmlvbiQiKSB+IHR5cGUsCiAgICBpbl9xdW90ZV9zZW50ZW5jZSB+IHN0cl9jKCJRdW90ZXMgaW4gIix0eXBlKSwKICAgIFRSVUUgfiBzdHJfYygiSm91cm5hbGlzdGljIHRleHQgaW4gIix0eXBlKQogICkpCiAgCmQyIDwtIGNvcnB1c19vZl9pbnRlcmVzdCAlPiUKICBpbm5lcl9qb2luKHl2X3RhX3BhcmFncmFwaHMpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZXMgJT4lIHNlbGVjdChhX2lkLGRhdGVfY3JlYXRlZCxtZWRpYSkpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZV90eXBlcykgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlc190b19yZWZfY2F0ZWdvcmllcykgJT4lCiAgbGVmdF9qb2luKHF1b3RhdGlvbl9jb3JwdXMgJT4lIG11dGF0ZShpbl9xdW90ZT1UKSkgJT4lCiAgbGVmdF9qb2luKHF1b3RlX29yZ3MsIGNvcHkgPSBUUlVFLCBhdXRvX2luZGV4ID0gVFJVRSkgJT4lCiAgbGVmdF9qb2luKHF1b3RhdGlvbl9zZW50ZW5jZV9jb3JwdXMgJT4lIG11dGF0ZShpbl9xdW90ZV9zZW50ZW5jZT1UKSkgJT4lCiAgbXV0YXRlKGluX3F1b3RlX2hlYWQ9aW5fcXVvdGVfc2VudGVuY2UgJiAhaW5fcXVvdGUpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpKSAlPiUKICBtdXRhdGUod2Vla19jcmVhdGVkPXdlZWsoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgbXV0YXRlKHR5cGUyPWNhc2Vfd2hlbigKICAgIHN0cl9kZXRlY3QodHlwZSwib3BpbmlvbiQiKSB+IHR5cGUsCiAgICBpbl9xdW90ZV9zZW50ZW5jZSB+IHN0cl9jKCJRdW90ZXMgaW4gIix0eXBlKSwKICAgIFRSVUUgfiBzdHJfYygiSm91cm5hbGlzdGljIHRleHQgaW4gIix0eXBlKQogICkpCmBgYAoKYGBge3J9CmtleV9jYXRzIDwtIGMoJ3BvdGlsYXMnLCAnbWFhaGFubXV1dHRvJywgJ2V0bm9zJywgJ3Nla3N1YWFsaXN1dXMnLCAndHnDtnN1aGRlJykKbWFpbl90eXBlcyA8LSBjKCdjb3JlJywgJ29waW5pb25hdGVkJywgJ2V4dGVybmFsIG9waW5pb24nKQpgYGAKCiMgQW5hbHlzaXMgMTogZGV2ZWxvcG1lbnQgb2YgeWhkZW52ZXJ0YWlzdXVzL3Rhc2EtYXJ2byBpbiBkaWZmZXJlbnQgdGV4dCBnZW5yZXMKCiMjIE1hc3RlciBjaGFydAoKYGBge3J9Cm15X2QgPC0gZCAlPiUgCiAgZmlsdGVyKGNhdGVnb3J5ICVpbiUgYygieWhkZW52ZXJ0YWlzdXVzIiwidGFzYS1hcnZvIikpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpLHdlZWtfY3JlYXRlZD13ZWVrKGRhdGVfY3JlYXRlZCkpICU+JQogIGdyb3VwX2J5KG1lZGlhLGNhdGVnb3J5LHR5cGUsdHlwZTIseWVhcl9jcmVhdGVkKSAlPiUKICBzdW1tYXJpemUoYXJ0aWNsZXM9bl9kaXN0aW5jdChhX2lkKSxkYXlzPW5fZGlzdGluY3QoZGF0ZV9jcmVhdGVkKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlc19ieV90eXBlX2J5X3llYXIsYnk9YygibWVkaWEiLCJ0eXBlIiwieWVhcl9jcmVhdGVkIikpICU+JQogIGNvbGxlY3QoKQoKbXlfZDIgPC0gZCAlPiUgCiAgZmlsdGVyKGNhdGVnb3J5ICVpbiUgYygieWhkZW52ZXJ0YWlzdXVzIiwidGFzYS1hcnZvIikpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpLHdlZWtfY3JlYXRlZD13ZWVrKGRhdGVfY3JlYXRlZCkpICU+JQogIGdyb3VwX2J5KGFfaWQsbWVkaWEsdHlwZSx0eXBlMix5ZWFyX2NyZWF0ZWQpICU+JQogIGZpbHRlcihhbnkoY2F0ZWdvcnk9PSJ5aGRlbnZlcnRhaXN1dXMiKSxhbnkoY2F0ZWdvcnk9PSJ0YXNhLWFydm8iKSkgJT4lCiAgZ3JvdXBfYnkobWVkaWEsdHlwZSx0eXBlMix5ZWFyX2NyZWF0ZWQpICU+JQogIHN1bW1hcml6ZShhcnRpY2xlcz1uX2Rpc3RpbmN0KGFfaWQpLGRheXM9bl9kaXN0aW5jdChkYXRlX2NyZWF0ZWQpLC5ncm91cHM9ImRyb3AiKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVzX2J5X3R5cGVfYnlfeWVhcixieT1jKCJtZWRpYSIsInR5cGUiLCJ5ZWFyX2NyZWF0ZWQiKSkgJT4lCiAgY29sbGVjdCgpCgpteV9kIDwtIG15X2QgJT4lIAogIG11dGF0ZSh3b3JkPSJXb3JkIikgJT4lCiAgdW5pb25fYWxsKG15X2QyICU+JSAKICAgICAgICAgICAgICBtdXRhdGUoY2F0ZWdvcnk9InRhc2EtYXJ2byIpICU+JQogICAgICAgICAgICAgIG11dGF0ZSh3b3JkPSJCb3RoIikpICU+JQogIHVuaW9uX2FsbChteV9kMiAlPiUgCiAgICAgICAgICAgICAgbXV0YXRlKGNhdGVnb3J5PSJ5aGRlbnZlcnRhaXN1dXMiKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUod29yZD0iQm90aCIpKSAlPiUKICBtdXRhdGUoCiAgICB3b3JkPWZjdF9yZWxldmVsKHdvcmQsIldvcmQiKSwKICAgIGNhdGVnb3J5PWZjdF9yZWxldmVsKGNhdGVnb3J5LCJ0YXNhLWFydm8iLCJ5aGRlbnZlcnRhaXN1dXMiKSwKICAgIHR5cGUyPWZjdF9yZWxldmVsKHR5cGUyLCJFeHRlcm5hbCBvcGluaW9uIiwgIkpvdXJuYWxpc3RpYyBvcGluaW9uIiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIERvbWVzdGljIGdlbmVyYWwvcG9saXRpY2FsL2Vjb25vbWljIG5ld3MiLCAiUXVvdGVzIGluIERvbWVzdGljIGdlbmVyYWwvcG9saXRpY2FsL2Vjb25vbWljIG5ld3MiLCAiSm91cm5hbGlzdGljIHRleHQgaW4gTG9jYWwgbmV3cyIsICJRdW90ZXMgaW4gTG9jYWwgbmV3cyIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBGb3JlaWduIG5ld3MiLCAiUXVvdGVzIGluIEZvcmVpZ24gbmV3cyIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBDdWx0dXJlL2VudGVydGFpbm1lbnQiLCAiUXVvdGVzIGluIEN1bHR1cmUvZW50ZXJ0YWlubWVudCIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBTcG9ydHMiLCAiUXVvdGVzIGluIFNwb3J0cyIpKSAgCmBgYAoKYGBge3IsZmlnLndpZHRoPTI4LGZpZy5oZWlnaHQ9OCxldmFsPUZBTFNFfQpteV9kICU+JQogIGZpbHRlcih0eXBlPT0iT3RoZXIiKSAlPiUKICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9bWVkaWEsbGluZXR5cGU9d29yZCkpICsKICBnZW9tX3N0ZXAoKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMjAwOSxjb2xvcj0icmVkIikgKyAKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3k9MC4xKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMDAsMjAyMCxieT00KSkgKwogIGZhY2V0X2dyaWQoY2F0ZWdvcnl+dHlwZTIsc2NhbGVzPSJmcmVlIikgKwogIGxhYnMoY29sb3I9Ik1lZGlhIixsaW5ldHlwZT0iU2lnbmFsIikgKwogIHhsYWIoIlllYXIiKSArCiAgeWxhYigiUGVyY2VudGFnZSBvZiBhcnRpY2xlcyBvZiB0eXBlIGNvbnRhaW5pbmcgdGhlIHdvcmQiKQpgYGAKCmBgYHtyLGZpZy53aWR0aD04LGZpZy5oZWlnaHQ9Nn0KMTozICU+JSBtYXAofgogIG15X2QgJT4lCiAgICBmaWx0ZXIodHlwZSE9Ik90aGVyIikgJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9bWVkaWEsbGluZXR5cGU9d29yZCkpICsKICAgIGdlb21fc3RlcCgpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDIwMDksY29sb3I9InJlZCIpICsgCiAgICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHM9c2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeT0wLjEpKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9NCkpICsKICAgIGZhY2V0X2dyaWRfcGFnaW5hdGUoY2F0ZWdvcnl+dHlwZTIsc2NhbGVzPSJmcmVlIiwgbnJvdz0yLCBuY29sPTQsIHBhZ2U9LngpICsKICAgIGxhYnMoY29sb3I9Ik1lZGlhIixsaW5ldHlwZT0iU2lnbmFsIikgKwogICAgeGxhYigiWWVhciIpICsKICAgIHlsYWIoIlBlcmNlbnRhZ2Ugb2YgYXJ0aWNsZXMgb2YgdHlwZSBjb250YWluaW5nIHRoZSB3b3JkIikKKQpgYGAKCkNvbmNsdXNpb25zOgoKLSBJTCBpcyBiZWhpbmQgb3RoZXIgbWVkaWEgaW4gY2hhbmdlLCBidXQgc2FtZSB0cmFqZWN0b3J5Ci0gRm9yIGZvcmVpZ24gbmV3cywgU1RUIChhbmQgdGhlcmVmb3JlIElMKSBkbyBub3QgaW5jcmVhc2UgdGFzYS1hcnZvIHRlcm1pbm9sb2d5IHVzYWdlCi0gRm9yIGxvY2FsIG5ld3MsIHRlcm1pbm9sb2d5IHVzYWdlIGluY3JlYXNlcyBvbmx5IGZvciBIUyAoSGVsc2lua2kpIGFzIG9wcG9zZWQgdG8gWUxFIChyZWdpb25hbCBuZXdzKQotIEZvciBjdWx0dXJlL2VudGVydGFpbm1lbnQsIG90aGVyIHNvdXJjZXMgZGlmZmVyIGZyb20gSUwuIFRoaXMgaXMgcHJvYmFibHkgZHVlIHRvIGNhdGVnb3J5IGhldGVyb2dlbmVpdHk6IGZvciBJTCwgdGhpcyBjYXRlZ29yeSBjb250YWlucyBlbnRlcnRhaW5tZW50IG5ld3MsIGZvciBvdGhlcnMsIHRoZXNlIGFyZSBtb3JlIGN1bHR1cmUgcmV2aWV3cyBldGMuCgojIyBEb2VzIGNoYW5nZSBpbiBtZWRpYSBjb21wb3NpdGlvbiBhZmZlY3QgcmVzdWx0cz8KCmBgYHtyLGZpZy53aWR0aD04LGZpZy5oZWlnaHQ9Nn0KMTozICU+JSBtYXAofgogIG15X2QgJT4lCiAgICBmaWx0ZXIodHlwZSE9Ik90aGVyIikgJT4lCiAgICBtdXRhdGUoCiAgICAgIGxfdG90YWxfYXJ0aWNsZXM9aWZfZWxzZShtZWRpYSAlaW4lIGMoIkhTIiwiU1RUIiksdG90YWxfYXJ0aWNsZXMsMEwpLAogICAgICBsX2FydGljbGVzPWlmX2Vsc2UobWVkaWEgJWluJSBjKCJIUyIsIlNUVCIpLGFydGljbGVzLDBMKQogICAgICApICU+JQogICAgZ3JvdXBfYnkoeWVhcl9jcmVhdGVkLGNhdGVnb3J5LHR5cGUyLHdvcmQpICU+JQogICAgc3VtbWFyaXplKGBIUy9TVFRgPXN1bShsX2FydGljbGVzKS9zdW0obF90b3RhbF9hcnRpY2xlcyksYEFsbCBtZWRpYXNgPXN1bShhcnRpY2xlcykvc3VtKHRvdGFsX2FydGljbGVzKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgICBwaXZvdF9sb25nZXIoYEhTL1NUVGA6YEFsbCBtZWRpYXNgKSAlPiUKICAgIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT12YWx1ZSxjb2xvcj1uYW1lLGxpbmV0eXBlPXdvcmQpKSArCiAgICBnZW9tX3N0ZXAoKSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAyMDA5LGNvbG9yPSJyZWQiKSArIAogICAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3k9MC4xKSkgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTQpKSArCiAgICBmYWNldF9ncmlkX3BhZ2luYXRlKGNhdGVnb3J5fnR5cGUyLHNjYWxlcz0iZnJlZSIsbnJvdz0yLG5jb2w9NCxwYWdlPS54KSArCiAgICBsYWJzKGNvbG9yPSJNZWRpYSIpICsKICAgIHhsYWIoIlllYXIiKSArCiAgICB5bGFiKCJQZXJjZW50YWdlIG9mIGFydGljbGVzIG9mIHR5cGUgY29udGFpbmluZyB0aGUgd29yZCIpCikKYGBgCgpDb25jbHVzaW9uczoKCiAtIElmIHdlIG1lbnRpb24gdGhlIElML1NUVCBiZWhhdmlvciBmcm9tIGFib3ZlIGluIHRleHQsIHdlIGNhbiB0aGVuIGRyb3AgdGhlIG1lZGlhcyBmcm9tIGdyYXBocyBhcyB0aGV5IGRvIG5vdCBvdGhlcndpc2UgYWZmZWN0IHJlc3VsdHMgZm9yIG1haW4gY2F0ZWdvcmllcyBvZiBpbnRlcmVzdC4KCiMjIEZpbmFsIGdyYXBoIHRvIGluY2x1ZGUgaW4gYXJ0aWNsZQoKYGBge3J9CmQgJT4lIAogIGZpbHRlcihjYXRlZ29yeSAlaW4lIGMoInloZGVudmVydGFpc3V1cyIsInRhc2EtYXJ2byIpKSAlPiUgCiAgZmlsdGVyKHR5cGUgJWluJSBjKCJEb21lc3RpYyBnZW5lcmFsL3BvbGl0aWNhbC9lY29ub21pYyBuZXdzIiwgIkpvdXJuYWxpc3RpYyBvcGluaW9uIiwgIkV4dGVybmFsIG9waW5pb24iKSkgJT4lCiAgbGVmdF9qb2luKGFydGljbGVzX2J5X3R5cGVfYnlfeWVhciAlPiUgZ3JvdXBfYnkodHlwZSx5ZWFyX2NyZWF0ZWQpICU+JQogICAgICAgICAgICAgICBzdW1tYXJpemUodG90YWxfYXJ0aWNsZXM9c3VtKHRvdGFsX2FydGljbGVzKSwuZ3JvdXBzPSJkcm9wIiksYnk9YygidHlwZSIsInllYXJfY3JlYXRlZCIpKSAlPiUKICBncm91cF9ieShjYXRlZ29yeSx0eXBlMix5ZWFyX2NyZWF0ZWQpICU+JQogIHN1bW1hcml6ZSh0b3RhbF9hcnRpY2xlcz1taW4odG90YWxfYXJ0aWNsZXMpLGFydGljbGVzPW5fZGlzdGluY3QoYV9pZCksZGF5cz1uX2Rpc3RpbmN0KGRhdGVfY3JlYXRlZCksLmdyb3Vwcz0iZHJvcCIpICU+JQogIGNvbGxlY3QoKSAlPiUKICBtdXRhdGUodHlwZTI9ZmN0X3JlbGV2ZWwodHlwZTIsIkV4dGVybmFsIG9waW5pb24iLCJKb3VybmFsaXN0aWMgb3BpbmlvbiIpKSAlPiUKICBtdXRhdGUoY2F0ZWdvcnk9ZmN0X3JlbGV2ZWwoY2F0ZWdvcnksInloZGVudmVydGFpc3V1cyIpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9dHlwZTIpKSArCiAgZ2VvbV9zdGVwKCkgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoYmFzZV9mYW1pbHk9IkFyaWFsIikgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHM9c2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeT0wLjEpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTUpKSArCiAgZmFjZXRfd3JhcCh+Y2F0ZWdvcnksIHNjYWxlcz0iZnJlZV95IikgKwogIGxhYnMoY29sb3I9IlRleHQgdHlwZSIpICsKICB4bGFiKCJZZWFyIikgKwogIHlsYWIoIlBlcmNlbnRhZ2Ugb2YgYXJ0aWNsZXMgb2YgdHlwZSBjb250YWluaW5nIHRoZSB3b3JkIikgKwogIHRoZW1lKGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygwLCAxKSwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjAyLCAwLjk4KSwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5ib3guanVzdCA9ICJib3R0b20iLCBsZWdlbmQua2V5ID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQuYm94ID0gImhvcml6b250YWwiKQpgYGAKCiMgQW5hbHlzaXMgMjogZGlzdHJpYnV0aW9uIG9mIGxhbmd1YWdlIGJ5IHNwZWFrZXIgYW5kIHN1YmplY3QgY2F0ZWdvcnkKCmBgYHtyfQoKZCAlPiUKICBmaWx0ZXIob3JnX2NhdCAlaW4lIGMoInBvbGl0aWlra2EiLCAib2lrZXVzIiksIGNhdGVnb3J5ICVpbiUgYygieWhkZW52ZXJ0YWlzdXVzIiwgInRhc2EtYXJ2byIpLCBpbl9xdW90ZSA9PSBUKSAlPiUKICBncm91cF9ieShvcmdfY2F0LHllYXJfY3JlYXRlZCwgY2F0ZWdvcnkpICU+JQogIHN1bW1hcml6ZShuPW4oKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgZ2dwbG90KGFlcyh4PXllYXJfY3JlYXRlZCx5PW4sY29sb3I9Y2F0ZWdvcnkpKSArCiAgZ2VvbV9zdGVwKCkgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoYmFzZV9mYW1pbHk9IkFyaWFsIikgKwogIGZhY2V0X2dyaWQofm9yZ19jYXQsIHNjYWxlcz0iZnJlZSIpCgpkICU+JQogIGZpbHRlcihvcmdfY2F0ICVpbiUgYygicG9saXRpaWtrYSIsICJvaWtldXMiKSwgY2F0ZWdvcnkgJWluJSBrZXlfY2F0cywgaW5fcXVvdGUgPT0gVCkgJT4lCiAgZ3JvdXBfYnkob3JnX2NhdCx5ZWFyX2NyZWF0ZWQsIGNhdGVnb3J5KSAlPiUKICBzdW1tYXJpemUobj1uKCksLmdyb3Vwcz0iZHJvcCIpICU+JQogIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1uLGNvbG9yPWNhdGVnb3J5KSkgKwogIGdlb21fc3RlcCgpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICBmYWNldF9ncmlkKH5vcmdfY2F0LCBzY2FsZXM9ImZyZWUiKQpgYGAKCiMgQW5hbHlzaXMgMzogc3ViamVjdCBhc3NvY2lhdGlvbnMKCmBgYHtyfQpzcCA8LSB5dl90YV9wYXJhZ3JhcGhzICU+JQogIGlubmVyX2pvaW4oCiAgICB3b3JkcyAlPiUgCiAgICAgIGZpbHRlcihsZW1tYT09InN1a3UjcHVvbGkiKSAlPiUKICAgICAgaW5uZXJfam9pbihjb3JwdXMpCiAgICApICU+JSBpbm5lcl9qb2luKGFydGljbGVzICU+JSBzZWxlY3QoYV9pZCxkYXRlX2NyZWF0ZWQsbWVkaWEpKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVfdHlwZXMpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMpICU+JQogIGxlZnRfam9pbihxdW90YXRpb25fc2VudGVuY2VfY29ycHVzICU+JSBtdXRhdGUoaW5fcXVvdGVfc2VudGVuY2U9VCkpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpKSAlPiUKICBtdXRhdGUod2Vla19jcmVhdGVkPXdlZWsoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgbXV0YXRlKHR5cGUyPWNhc2Vfd2hlbigKICAgIHN0cl9kZXRlY3QodHlwZSwib3BpbmlvbiQiKSB+IHR5cGUsCiAgICBpbl9xdW90ZV9zZW50ZW5jZSB+IHN0cl9jKCJRdW90ZXMgaW4gIix0eXBlKSwKICAgIFRSVUUgfiBzdHJfYygiSm91cm5hbGlzdGljIHRleHQgaW4gIix0eXBlKQogICkpICU+JQogIGdyb3VwX2J5KG1lZGlhLHJlZl9jYXRlZ29yeSx0eXBlLHR5cGUyLHllYXJfY3JlYXRlZCkgJT4lCiAgc3VtbWFyaXplKGFydGljbGVzPW5fZGlzdGluY3QoYV9pZCksd2Vla3M9bl9kaXN0aW5jdCh3ZWVrX2NyZWF0ZWQpLGRheXM9bl9kaXN0aW5jdChkYXRlX2NyZWF0ZWQpLC5ncm91cHM9ImRyb3AiKSAlPiUgCiAgY29sbGVjdCgpICU+JQogIG11dGF0ZSgKICAgIHJlZl9jYXRlZ29yeT1mY3RfcmVsZXZlbChyZWZfY2F0ZWdvcnksInRhc2EtYXJ2byIsInloZGVudmVydGFpc3V1cyIpLAogICAgdHlwZTI9ZmN0X3JlbGV2ZWwodHlwZTIsIkV4dGVybmFsIG9waW5pb24iLCAiSm91cm5hbGlzdGljIG9waW5pb24iLCAiSm91cm5hbGlzdGljIHRleHQgaW4gRG9tZXN0aWMgZ2VuZXJhbC9wb2xpdGljYWwvZWNvbm9taWMgbmV3cyIsICJRdW90ZXMgaW4gRG9tZXN0aWMgZ2VuZXJhbC9wb2xpdGljYWwvZWNvbm9taWMgbmV3cyIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBMb2NhbCBuZXdzIiwgIlF1b3RlcyBpbiBMb2NhbCBuZXdzIiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIEZvcmVpZ24gbmV3cyIsICJRdW90ZXMgaW4gRm9yZWlnbiBuZXdzIiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIEN1bHR1cmUvZW50ZXJ0YWlubWVudCIsICJRdW90ZXMgaW4gQ3VsdHVyZS9lbnRlcnRhaW5tZW50IiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIFNwb3J0cyIsICJRdW90ZXMgaW4gU3BvcnRzIikpCiAgCm15X2NkIDwtIGNvcnB1c19vZl9pbnRlcmVzdCAlPiUKICBmaWx0ZXIobGVtbWEhPSJzdW9tYWxhaW5lbiIpICU+JQogIGlubmVyX2pvaW4oeXZfdGFfcGFyYWdyYXBocykgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlcyAlPiUgc2VsZWN0KGFfaWQsZGF0ZV9jcmVhdGVkLG1lZGlhKSkgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlX3R5cGVzKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVzX3RvX3JlZl9jYXRlZ29yaWVzKSAlPiUKICBtdXRhdGUoeWVhcl9jcmVhdGVkPXllYXIoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgbXV0YXRlKHdlZWtfY3JlYXRlZD13ZWVrKGRhdGVfY3JlYXRlZCkpICU+JQogIGxlZnRfam9pbihxdW90YXRpb25fc2VudGVuY2VfY29ycHVzICU+JSBtdXRhdGUoaW5fcXVvdGVfc2VudGVuY2U9VCkpICU+JQogIG11dGF0ZSh0eXBlMj1jYXNlX3doZW4oCiAgICBzdHJfZGV0ZWN0KHR5cGUsIm9waW5pb24kIikgfiB0eXBlLAogICAgaW5fcXVvdGVfc2VudGVuY2UgfiBzdHJfYygiUXVvdGVzIGluICIsdHlwZSksCiAgICBUUlVFIH4gc3RyX2MoIkpvdXJuYWxpc3RpYyB0ZXh0IGluICIsdHlwZSkKICApKQoKY2QyIDwtIG15X2NkICU+JQogIGdyb3VwX2J5KHJlZl9jYXRlZ29yeSxnZW51cyx0eXBlLHR5cGUyLHllYXJfY3JlYXRlZCkgJT4lCiAgc3VtbWFyaXplKGFydGljbGVzPW5fZGlzdGluY3QoYV9pZCksd2Vla3M9bl9kaXN0aW5jdCh3ZWVrX2NyZWF0ZWQpLGRheXM9bl9kaXN0aW5jdChkYXRlX2NyZWF0ZWQpLC5ncm91cHM9ImRyb3AiKSAlPiUgCiAgY29sbGVjdCgpICU+JQogIG11dGF0ZSgKICAgIHJlZl9jYXRlZ29yeT1mY3RfcmVsZXZlbChyZWZfY2F0ZWdvcnksInRhc2EtYXJ2byIsInloZGVudmVydGFpc3V1cyIpLAogICAgdHlwZTI9ZmN0X3JlbGV2ZWwodHlwZTIsIkV4dGVybmFsIG9waW5pb24iLCAiSm91cm5hbGlzdGljIG9waW5pb24iLCAiSm91cm5hbGlzdGljIHRleHQgaW4gRG9tZXN0aWMgZ2VuZXJhbC9wb2xpdGljYWwvZWNvbm9taWMgbmV3cyIsICJRdW90ZXMgaW4gRG9tZXN0aWMgZ2VuZXJhbC9wb2xpdGljYWwvZWNvbm9taWMgbmV3cyIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBMb2NhbCBuZXdzIiwgIlF1b3RlcyBpbiBMb2NhbCBuZXdzIiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIEZvcmVpZ24gbmV3cyIsICJRdW90ZXMgaW4gRm9yZWlnbiBuZXdzIiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIEN1bHR1cmUvZW50ZXJ0YWlubWVudCIsICJRdW90ZXMgaW4gQ3VsdHVyZS9lbnRlcnRhaW5tZW50IiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIFNwb3J0cyIsICJRdW90ZXMgaW4gU3BvcnRzIikpCgpjZCA8LSBteV9jZCAlPiUKICBncm91cF9ieShyZWZfY2F0ZWdvcnksY2F0ZWdvcnksdHlwZSx0eXBlMix5ZWFyX2NyZWF0ZWQpICU+JQogIHN1bW1hcml6ZShhcnRpY2xlcz1uX2Rpc3RpbmN0KGFfaWQpLHdlZWtzPW5fZGlzdGluY3Qod2Vla19jcmVhdGVkKSxkYXlzPW5fZGlzdGluY3QoZGF0ZV9jcmVhdGVkKSwuZ3JvdXBzPSJkcm9wIikgJT4lIAogIGNvbGxlY3QoKSAlPiUKICBtdXRhdGUoCiAgICByZWZfY2F0ZWdvcnk9ZmN0X3JlbGV2ZWwocmVmX2NhdGVnb3J5LCJ0YXNhLWFydm8iLCJ5aGRlbnZlcnRhaXN1dXMiKSwKICAgIHR5cGUyPWZjdF9yZWxldmVsKHR5cGUyLCJFeHRlcm5hbCBvcGluaW9uIiwgIkpvdXJuYWxpc3RpYyBvcGluaW9uIiwgIkpvdXJuYWxpc3RpYyB0ZXh0IGluIERvbWVzdGljIGdlbmVyYWwvcG9saXRpY2FsL2Vjb25vbWljIG5ld3MiLCAiUXVvdGVzIGluIERvbWVzdGljIGdlbmVyYWwvcG9saXRpY2FsL2Vjb25vbWljIG5ld3MiLCAiSm91cm5hbGlzdGljIHRleHQgaW4gTG9jYWwgbmV3cyIsICJRdW90ZXMgaW4gTG9jYWwgbmV3cyIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBGb3JlaWduIG5ld3MiLCAiUXVvdGVzIGluIEZvcmVpZ24gbmV3cyIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBDdWx0dXJlL2VudGVydGFpbm1lbnQiLCAiUXVvdGVzIGluIEN1bHR1cmUvZW50ZXJ0YWlubWVudCIsICJKb3VybmFsaXN0aWMgdGV4dCBpbiBTcG9ydHMiLCAiUXVvdGVzIGluIFNwb3J0cyIpKQpgYGAKCiMjIEdlbmRlcgoKYGBge3IsZmlnLndpZHRoPTgsZmlnLmhlaWdodD02fQpteV9kIDwtIHNwICU+JQogIGZpbHRlcih0eXBlIT0iT3RoZXIiKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVzX2J5X3R5cGVfYnlfeWVhciAlPiUgCiAgICAgICAgICAgICAgIGdyb3VwX2J5KHllYXJfY3JlYXRlZCx0eXBlKSAlPiUKICAgICAgICAgICAgICAgc3VtbWFyaXplKHRvdGFsX2FydGljbGVzPXN1bSh0b3RhbF9hcnRpY2xlcyksLmdyb3Vwcz0iZHJvcCIpICU+JSBjb2xsZWN0KCkpICU+JSAKICBjb2xsZWN0KCkKCjE6MyAlPiUgbWFwKH4KICBteV9kICU+JSAKICAgIGZpbHRlcihyZWZfY2F0ZWdvcnkhPSJib3RoIikgJT4lCiAgICBtdXRhdGUoZmN0PXJlZl9jYXRlZ29yeSx3b3JkPSJXb3JkIikgJT4lCiAgICB1bmlvbl9hbGwoCiAgICAgIG15X2QgJT4lCiAgICAgICAgZmlsdGVyKHJlZl9jYXRlZ29yeT09ImJvdGgiKSAlPiUKICAgICAgICBtdXRhdGUoZmN0PSJ0YXNhLWFydm8iLHdvcmQ9IkJvdGgiKQogICAgKSAlPiUKICAgIHVuaW9uX2FsbCgKICAgICAgbXlfZCAlPiUKICAgICAgICBmaWx0ZXIocmVmX2NhdGVnb3J5PT0iYm90aCIpICU+JQogICAgICAgIG11dGF0ZShmY3Q9InloZGVudmVydGFpc3V1cyIsd29yZD0iQm90aCIpCiAgICApICU+JQogICAgbXV0YXRlKHdvcmQ9ZmN0X3JlbGV2ZWwod29yZCwiV29yZCIpKSAlPiUKICAgIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1hcnRpY2xlcy90b3RhbF9hcnRpY2xlcyxjb2xvcj1tZWRpYSxsaW5ldHlwZT13b3JkKSkgKwogICAgZ2VvbV9zdGVwKCkgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMjAwOSxjb2xvcj0icmVkIikgKyAKICAgIHRoZW1lX2hzY2lfZGlzY3JldGUoYmFzZV9mYW1pbHk9IkFyaWFsIikgKwogICAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscz1zY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5PTAuMSkpICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMDAsMjAyMCxieT00KSkgKwogICAgZmFjZXRfZ3JpZF9wYWdpbmF0ZShmY3R+dHlwZTIsc2NhbGVzPSJmcmVlIixuY29sPTQsbnJvdz0yLHBhZ2U9LngpICsKICAgIGxhYnMoY29sb3I9Ik1lZGlhIixsaW5ldHlwZT0iU2lnbmFsIikgKwogICAgeGxhYigiWWVhciIpICsKICAgIHlsYWIoIlBlcmNlbnRhZ2Ugb2YgYXJ0aWNsZXMgb2YgdHlwZSBjb250YWluaW5nIHRoZSB3b3JkIikKKQoKMTozICU+JSBtYXAofiAgCiAgbXlfZCAlPiUgCiAgICBmaWx0ZXIocmVmX2NhdGVnb3J5IT0iYm90aCIpICU+JQogICAgbXV0YXRlKGZjdD1yZWZfY2F0ZWdvcnksd29yZD0iV29yZCIpICU+JQogICAgdW5pb25fYWxsKAogICAgICBteV9kICU+JQogICAgICAgIGZpbHRlcihyZWZfY2F0ZWdvcnk9PSJib3RoIikgJT4lCiAgICAgICAgbXV0YXRlKGZjdD0idGFzYS1hcnZvIix3b3JkPSJCb3RoIikKICAgICkgJT4lCiAgICB1bmlvbl9hbGwoCiAgICAgIG15X2QgJT4lCiAgICAgICAgZmlsdGVyKHJlZl9jYXRlZ29yeT09ImJvdGgiKSAlPiUKICAgICAgICBtdXRhdGUoZmN0PSJ5aGRlbnZlcnRhaXN1dXMiLHdvcmQ9IkJvdGgiKQogICAgKSAlPiUKICAgIG11dGF0ZSh3b3JkPWZjdF9yZWxldmVsKHdvcmQsIldvcmQiKSkgJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9bWVkaWEsbGluZXR5cGU9d29yZCkpICsKICAgIGdlb21fc3RlcCgpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDIwMDksY29sb3I9InJlZCIpICsgCiAgICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHM9c2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeT0wLjEpKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9NCkpICsKICAgIGZhY2V0X3dyYXBfcGFnaW5hdGUoZmN0fnR5cGUyLHNjYWxlcz0iZnJlZSIsbmNvbD00LG5yb3c9MixwYWdlPS54KSArCiAgICBsYWJzKGNvbG9yPSJNZWRpYSIsbGluZXR5cGU9IlNpZ25hbCIpICsKICAgIHhsYWIoIlllYXIiKSArCiAgICB5bGFiKCJQZXJjZW50YWdlIG9mIGFydGljbGVzIG9mIHR5cGUgY29udGFpbmluZyB0aGUgd29yZCIpCikKYGBgCgpDb25jbHVzaW9uczoKCiAtIERlY2xpbmUgaW4gInN1a3VwdW9sdGVuIHRhc2EtYXJ2byIgaW4gU1RUIGZvciBkb21lc3RpYyBuZXdzIGlzIGludGVyZXN0aW5nLiBXaGF0IGNvdWxkIGNhdXNlIHRoaXM/CiAtIE90aGVyd2lzZSwgYWxsIHNvdXJjZXMgc2VlbSB0byBiZSBmb2xsb3dpbmcgc2ltaWxhciBwYXR0ZXJucy4KCmBgYHtyfQpzcCAlPiUgCiAgZmlsdGVyKHR5cGU9PSJEb21lc3RpYyBnZW5lcmFsL3BvbGl0aWNhbC9lY29ub21pYyBuZXdzIikgJT4lCiAgZ3JvdXBfYnkocmVmX2NhdGVnb3J5LHR5cGUsdHlwZTIseWVhcl9jcmVhdGVkKSAlPiUKICBzdW1tYXJpemUoYXJ0aWNsZXM9c3VtKGFydGljbGVzKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlc19ieV90eXBlX2J5X3llYXIgJT4lIAogICAgICAgICAgICAgICBncm91cF9ieSh5ZWFyX2NyZWF0ZWQsdHlwZSkgJT4lCiAgICAgICAgICAgICAgIHN1bW1hcml6ZSh0b3RhbF9hcnRpY2xlcz1zdW0odG90YWxfYXJ0aWNsZXMpLC5ncm91cHM9ImRyb3AiKSAlPiUgY29sbGVjdCgpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9cmVmX2NhdGVnb3J5LGxpbmV0eXBlPXR5cGUyKSkgKwogIGdlb21fc3RlcCgpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9MikpCmBgYAoKQ29uY2x1c2lvbnM6CgogLSBHZW5kZXIgZXF1YWxpdHkgZGlzY3Vzc2lvbiBhbHNvIGdldHMgYSBib29zdCBhZnRlciAyMDE0CiAtIFdoZW4gInloZGVudmVydGFpc3V1cyIgaXMgdXNlZCBpbiByZWxhdGlvbiB0byBnZW5kZXIsICJ0YXNhLWFydm8iIGlzIGFsbW9zdCBhbHdheXMgYWxzbyBtZW50aW9uZWQhCgpgYGB7cixmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTZ9Cm15X2QgPC0gY2QyICU+JQogIGZpbHRlcih0eXBlIT0iT3RoZXIiKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVzX2J5X3R5cGVfYnlfeWVhciAlPiUgCiAgICAgICAgICAgICAgIGdyb3VwX2J5KHllYXJfY3JlYXRlZCx0eXBlKSAlPiUKICAgICAgICAgICAgICAgc3VtbWFyaXplKHRvdGFsX2FydGljbGVzPXN1bSh0b3RhbF9hcnRpY2xlcyksLmdyb3Vwcz0iZHJvcCIpICU+JSBjb2xsZWN0KCkpICU+JSAKICBjb2xsZWN0KCkKCjE6MyAlPiUgbWFwKH4KICBteV9kICU+JSAKICAgIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1hcnRpY2xlcy90b3RhbF9hcnRpY2xlcyxjb2xvcj1yZWZfY2F0ZWdvcnkpKSArCiAgICBnZW9tX3N0ZXAoKSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAyMDA5LGNvbG9yPSJyZWQiKSArIAogICAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3k9MC4xKSkgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTQpKSArCiAgICBmYWNldF9ncmlkX3BhZ2luYXRlKGdlbnVzfnR5cGUyLHNjYWxlcz0iZnJlZSIsbmNvbD00LG5yb3c9MixwYWdlPS54KSArCiAgICBsYWJzKGNvbG9yPSJyZWYtY2F0ZWdvcnkiLGxpbmV0eXBlPSJTaWduYWwiKSArCiAgICB4bGFiKCJZZWFyIikgKwogICAgeWxhYigiUGVyY2VudGFnZSBvZiBhcnRpY2xlcyBvZiB0eXBlIGNvbnRhaW5pbmcgdGhlIHdvcmQiKQopCgoxOjMgJT4lIG1hcCh+ICAKICBteV9kICU+JSAKICAgIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1hcnRpY2xlcy90b3RhbF9hcnRpY2xlcyxjb2xvcj1yZWZfY2F0ZWdvcnkpKSArCiAgICBnZW9tX3N0ZXAoKSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAyMDA5LGNvbG9yPSJyZWQiKSArIAogICAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3k9MC4xKSkgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTQpKSArCiAgICBmYWNldF93cmFwX3BhZ2luYXRlKGdlbnVzfnR5cGUyLHNjYWxlcz0iZnJlZSIsbmNvbD00LG5yb3c9MixwYWdlPS54KSArCiAgICBsYWJzKGNvbG9yPSJyZWYtY2F0ZWdvcnkiLGxpbmV0eXBlPSJTaWduYWwiKSArCiAgICB4bGFiKCJZZWFyIikgKwogICAgeWxhYigiUGVyY2VudGFnZSBvZiBhcnRpY2xlcyBvZiB0eXBlIGNvbnRhaW5pbmcgdGhlIHdvcmQiKQopCmBgYAoKQ29uY2x1c2lvbnM6CgotIFNhbWUgYmVoYXZpb3Igc2VlbiBmb3IgInN1a3VwdW9sdGVuIHRhc2EtYXJ2by95aGRlbnZlcnRhaXN1dXMiIGlzIGFsc28gZXZpZGVudCB3aGVuIGxvb2tpbmcgYXQgZXhwbGljaXRseSBnZW5kZXJlZCB3b3JkcyAobWllcy9uYWluZW4pCgojIyBTdWJqZWN0IHRvcGljCgpgYGB7cixmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTZ9CjE6MyAlPiUgbWFwKH4KICBjZCAlPiUgCiAgICBmaWx0ZXIodHlwZSE9Ik90aGVyIikgJT4lCiAgICBmaWx0ZXIoY2F0ZWdvcnkgJWluJSBjKCJldG5vcyIsInBvdGlsYXMiLCJzZWtzdWFhbGlzdXVzIiwidHnDtnN1aGRlIiwibWFhaGFubXV1dHRvIikpICU+JQogICAgaW5uZXJfam9pbihhcnRpY2xlc19ieV90eXBlX2J5X3llYXIgJT4lIAogICAgICAgICAgICAgICAgIGdyb3VwX2J5KHllYXJfY3JlYXRlZCx0eXBlKSAlPiUKICAgICAgICAgICAgICAgICBzdW1tYXJpemUodG90YWxfYXJ0aWNsZXM9c3VtKHRvdGFsX2FydGljbGVzKSwuZ3JvdXBzPSJkcm9wIikgJT4lIGNvbGxlY3QoKSkgJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9Y2F0ZWdvcnkpKSArCiAgICBnZW9tX3N0ZXAoKSArCiAgICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMDAsMjAyMCxieT00KSkgKwogICAgZmFjZXRfZ3JpZF9wYWdpbmF0ZShyZWZfY2F0ZWdvcnl+dHlwZTIsc2NhbGVzPSJmcmVlIixucm93PTIsbmNvbD00LHBhZ2U9LngpCikKCjE6MyAlPiUgbWFwKH4gCiAgY2QgJT4lIAogICAgZmlsdGVyKHR5cGUhPSJPdGhlciIpICU+JQogICAgZmlsdGVyKGNhdGVnb3J5ICVpbiUgYygiZXRub3MiLCJwb3RpbGFzIiwic2Vrc3VhYWxpc3V1cyIsInR5w7ZzdWhkZSIsIm1hYWhhbm11dXR0byIpKSAlPiUKICAgIGlubmVyX2pvaW4oYXJ0aWNsZXNfYnlfdHlwZV9ieV95ZWFyICU+JSAKICAgICAgICAgICAgICAgICBncm91cF9ieSh5ZWFyX2NyZWF0ZWQsdHlwZSkgJT4lCiAgICAgICAgICAgICAgICAgc3VtbWFyaXplKHRvdGFsX2FydGljbGVzPXN1bSh0b3RhbF9hcnRpY2xlcyksLmdyb3Vwcz0iZHJvcCIpICU+JSBjb2xsZWN0KCkpICU+JQogICAgZ2dwbG90KGFlcyh4PXllYXJfY3JlYXRlZCx5PWFydGljbGVzL3RvdGFsX2FydGljbGVzLGNvbG9yPWNhdGVnb3J5KSkgKwogICAgZ2VvbV9zdGVwKCkgKwogICAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9NCkpICsKICAgIGZhY2V0X3dyYXBfcGFnaW5hdGUocmVmX2NhdGVnb3J5fnR5cGUyLHNjYWxlcz0iZnJlZSIsbnJvdz0yLG5jb2w9NCxwYWdlPS54KQopCmBgYAoKQ29uY2x1c2lvbnM6CgogLSBUaGVyZSBkb24ndCBzZWVtIHRvIGJlIG1ham9yIGRpc2Nlcm5pYmxlIHBhdHRlcm5zIGJldHdlZW4gZGlmZmVyZW50IHN1YmplY3RzIGZvciBlcXVhbGl0eQoKIyMgU3VwcG9ydGluZyBhdXhpbGlhcnkgYW5hbHlzZXMKCiMjIyBTdWJqZWN0IHRvcGljIGdyYXBocyB1c2luZyBkaWZmZXJlbnQgbWVhc3VyZXMKCmBgYHtyfQpjZCAlPiUgCiAgZmlsdGVyKGNhdGVnb3J5ICVpbiUgYygiZXRub3MiLCJwb3RpbGFzIiwic2Vrc3VhYWxpc3V1cyIsInR5w7ZzdWhkZSIsIm1hYWhhbm11dXR0byIpKSAlPiUKICBncm91cF9ieShyZWZfY2F0ZWdvcnkpICU+JQogIGdyb3VwX21hcCh+LnggJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9ZGF5cyxjb2xvcj1jYXRlZ29yeSkpICsKICAgIGdlb21fbGluZSgpICsKICAgIHRoZW1lX2hzY2lfZGlzY3JldGUoYmFzZV9mYW1pbHk9IkFyaWFsIikgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTIpKSArCiAgICBmYWNldF93cmFwKH50eXBlMixzY2FsZXM9ImZyZWUiKSArCiAgICBnZ3RpdGxlKC55WzFdJHJlZl9jYXRlZ29yeSkpCgpjZCAlPiUgCiAgZmlsdGVyKGNhdGVnb3J5ICVpbiUgYygiZXRub3MiLCJwb3RpbGFzIiwic2Vrc3VhYWxpc3V1cyIsInR5w7ZzdWhkZSIsIm1hYWhhbm11dXR0byIpKSAlPiUKICBncm91cF9ieShyZWZfY2F0ZWdvcnkpICU+JQogIGdyb3VwX21hcCh+LnggJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9d2Vla3MsY29sb3I9Y2F0ZWdvcnkpKSArCiAgICBnZW9tX2xpbmUoKSArCiAgICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMDAsMjAyMCxieT0yKSkgKwogICAgZmFjZXRfd3JhcCh+dHlwZTIsc2NhbGVzPSJmcmVlIikgKwogICAgZ2d0aXRsZSgueVsxXSRyZWZfY2F0ZWdvcnkpKQoKY2QgJT4lIAogIGZpbHRlcihjYXRlZ29yeSAlaW4lIGMoImV0bm9zIiwicG90aWxhcyIsInNla3N1YWFsaXN1dXMiLCJ0ecO2c3VoZGUiLCJtYWFoYW5tdXV0dG8iKSkgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlc19ieV90eXBlX2J5X3llYXIgJT4lIAogICAgICAgICAgICAgICBncm91cF9ieSh5ZWFyX2NyZWF0ZWQsdHlwZSkgJT4lCiAgICAgICAgICAgICAgIHN1bW1hcml6ZSh0b3RhbF9hcnRpY2xlcz1zdW0odG90YWxfYXJ0aWNsZXMpLC5ncm91cHM9ImRyb3AiKSAlPiUgY29sbGVjdCgpKSAlPiUKICBncm91cF9ieShyZWZfY2F0ZWdvcnkpICU+JQogIGdyb3VwX21hcCh+LnggJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9Y2F0ZWdvcnkpKSArCiAgICBnZW9tX2xpbmUoKSArCiAgICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMDAsMjAyMCxieT0yKSkgKwogICAgZmFjZXRfd3JhcCh+dHlwZTIsc2NhbGVzPSJmcmVlIikgKwogICAgZ2d0aXRsZSgueVsxXSRyZWZfY2F0ZWdvcnkpKQpgYGAKCiMjIyBEbyB0aGUgc3ViamVjdCB0b3BpY3MgY29tYmluZWQgY2FwdHVyZSB0aGUgcGhlbm9tZW5vbj8KCmBgYHtyfQpjZDMgPC0geXZfdGFfcGFyYWdyYXBocyAlPiUKICBpbm5lcl9qb2luKGNvcnB1c19vZl9pbnRlcmVzdCkgJT4lCiAgZmlsdGVyKGxlbW1hIT0ic3VvbWFsYWluZW4iKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVzICU+JSBzZWxlY3QoYV9pZCxkYXRlX2NyZWF0ZWQsbWVkaWEpKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVfdHlwZXMpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpKSAlPiUKICBtdXRhdGUod2Vla19jcmVhdGVkPXdlZWsoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgbXV0YXRlKGNhdGVnb3J5PSJwb3RpbGFzIikgJT4lCiAgZ3JvdXBfYnkocmVmX2NhdGVnb3J5LGNhdGVnb3J5LHR5cGUseWVhcl9jcmVhdGVkKSAlPiUKICBzdW1tYXJpemUoYXJ0aWNsZXM9bl9kaXN0aW5jdChhX2lkKSx3ZWVrcz1uX2Rpc3RpbmN0KHdlZWtfY3JlYXRlZCksZGF5cz1uX2Rpc3RpbmN0KGRhdGVfY3JlYXRlZCksLmdyb3Vwcz0iZHJvcCIpICU+JSAKICBjb2xsZWN0KCkKCmNkMyAlPiUgCiAgZmlsdGVyKGNhdGVnb3J5ICVpbiUgYygiZXRub3MiLCJwb3RpbGFzIiwic2Vrc3VhYWxpc3V1cyIsInR5w7ZzdWhkZSIsIm1hYWhhbm11dXR0byIpKSAlPiUKICBtdXRhdGUodHlwZT1mY3RfcmVsZXZlbCh0eXBlLCJmb3JlaWduIiwic3BvcnRzIiwib3RoZXIiLGFmdGVyPUluZikpICU+JQogIGdyb3VwX2J5KHJlZl9jYXRlZ29yeSkgJT4lCiAgZ3JvdXBfbWFwKH4ueCAlPiUKICAgIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1kYXlzLGNvbG9yPWNhdGVnb3J5KSkgKwogICAgZ2VvbV9saW5lKCkgKwogICAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9MikpICsKICAgIGZhY2V0X3dyYXAofnR5cGUsc2NhbGVzPSJmcmVlIikgKwogICAgZ2d0aXRsZSgueVsxXSRyZWZfY2F0ZWdvcnkpKQoKY2QzICU+JSAKICBmaWx0ZXIoY2F0ZWdvcnkgJWluJSBjKCJldG5vcyIsInBvdGlsYXMiLCJzZWtzdWFhbGlzdXVzIiwidHnDtnN1aGRlIiwibWFhaGFubXV1dHRvIikpICU+JQogIG11dGF0ZSh0eXBlPWZjdF9yZWxldmVsKHR5cGUsImZvcmVpZ24iLCJzcG9ydHMiLCJvdGhlciIsYWZ0ZXI9SW5mKSkgJT4lCiAgZ3JvdXBfYnkocmVmX2NhdGVnb3J5KSAlPiUKICBncm91cF9tYXAofi54ICU+JQogICAgZ2dwbG90KGFlcyh4PXllYXJfY3JlYXRlZCx5PXdlZWtzLGNvbG9yPWNhdGVnb3J5KSkgKwogICAgZ2VvbV9saW5lKCkgKwogICAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9MikpICsKICAgIGZhY2V0X3dyYXAofnR5cGUsc2NhbGVzPSJmcmVlIikgKwogICAgZ2d0aXRsZSgueVsxXSRyZWZfY2F0ZWdvcnkpKQoKY2QzICU+JSAKICBmaWx0ZXIoY2F0ZWdvcnkgJWluJSBjKCJldG5vcyIsInBvdGlsYXMiLCJzZWtzdWFhbGlzdXVzIiwidHnDtnN1aGRlIiwibWFhaGFubXV1dHRvIikpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZXNfYnlfdHlwZV9ieV95ZWFyICU+JSAKICAgICAgICAgICAgICAgZ3JvdXBfYnkoeWVhcl9jcmVhdGVkLHR5cGUpICU+JQogICAgICAgICAgICAgICBzdW1tYXJpemUodG90YWxfYXJ0aWNsZXM9c3VtKHRvdGFsX2FydGljbGVzKSwuZ3JvdXBzPSJkcm9wIikgJT4lIGNvbGxlY3QoKSkgJT4lCiAgbXV0YXRlKHR5cGU9ZmN0X3JlbGV2ZWwodHlwZSwiZm9yZWlnbiIsInNwb3J0cyIsIm90aGVyIixhZnRlcj1JbmYpKSAlPiUKICBncm91cF9ieShyZWZfY2F0ZWdvcnkpICU+JQogIGdyb3VwX21hcCh+LnggJT4lCiAgICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9YXJ0aWNsZXMvdG90YWxfYXJ0aWNsZXMsY29sb3I9Y2F0ZWdvcnkpKSArCiAgICBnZW9tX2xpbmUoKSArCiAgICB0aGVtZV9oc2NpX2Rpc2NyZXRlKGJhc2VfZmFtaWx5PSJBcmlhbCIpICsKICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDIwMDAsMjAyMCxieT0yKSkgKwogICAgZmFjZXRfd3JhcCh+dHlwZSxzY2FsZXM9ImZyZWUiKSArCiAgICBnZ3RpdGxlKC55WzFdJHJlZl9jYXRlZ29yeSkpCmBgYAoKQ29uY2x1c2lvbnM6CgogLSBXaGlsZSB3ZSBzYXcgbm8gZGlzY2VybmlibGUgcGF0dGVybnMgYmV0d2VlbiBzdWJqZWN0cywgd2UgZG8gc2VlbSB0byBiZSBjYXB0dXJpbmcgdGhlICJ3aG9sZSIgb2YgZXF1YWxpdHkgZGlzY3Vzc2lvbiBieSB0YXJnZXRpbmcgdGhlbSAtPiBjYW4gY29uY2x1ZGUgdGhhdCBldmVyeW9uZSBiZW5lZml0cy4KCiMgQmFja2dyb3VuZCBBbmFseXNlcwoKYGBge3J9CmFydGljbGVzICU+JSAKICBpbm5lcl9qb2luKGFydGljbGVzX3RvX3JlZl9jYXRlZ29yaWVzKSAlPiUKICBpbm5lcl9qb2luKGFydGljbGVfdHlwZXMpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpLHdlZWtfY3JlYXRlZD13ZWVrKGRhdGVfY3JlYXRlZCkpICU+JQogIGdyb3VwX2J5KG1lZGlhLHJlZl9jYXRlZ29yeSx0eXBlLHllYXJfY3JlYXRlZCkgJT4lCiAgc3VtbWFyaXplKGFydGljbGVzPW5fZGlzdGluY3QoYV9pZCksd2Vla3M9bl9kaXN0aW5jdCh3ZWVrX2NyZWF0ZWQpLGRheXM9bl9kaXN0aW5jdChkYXRlX2NyZWF0ZWQpLC5ncm91cHM9ImRyb3AiKSAlPiUKICBnZ3Bsb3QoYWVzKHg9eWVhcl9jcmVhdGVkLHk9ZGF5cyxjb2xvcj1tZWRpYSkpICsKICBnZW9tX3N0ZXAoKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTIpKSArCiAgZmFjZXRfZ3JpZChyZWZfY2F0ZWdvcnl+dHlwZSxzY2FsZXM9ImZyZWUiKQoKYXJ0aWNsZXMgJT4lIAogIGlubmVyX2pvaW4oYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZV90eXBlcykgJT4lCiAgbXV0YXRlKHllYXJfY3JlYXRlZD15ZWFyKGRhdGVfY3JlYXRlZCksd2Vla19jcmVhdGVkPXdlZWsoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgZ3JvdXBfYnkobWVkaWEscmVmX2NhdGVnb3J5LHR5cGUseWVhcl9jcmVhdGVkKSAlPiUKICBzdW1tYXJpemUoYXJ0aWNsZXM9bl9kaXN0aW5jdChhX2lkKSx3ZWVrcz1uX2Rpc3RpbmN0KHdlZWtfY3JlYXRlZCksZGF5cz1uX2Rpc3RpbmN0KGRhdGVfY3JlYXRlZCksLmdyb3Vwcz0iZHJvcCIpICU+JQogIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT13ZWVrcyxjb2xvcj1tZWRpYSkpICsKICBnZW9tX3N0ZXAoKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMjAwMCwyMDIwLGJ5PTIpKSArCiAgZmFjZXRfZ3JpZChyZWZfY2F0ZWdvcnl+dHlwZSxzY2FsZXM9ImZyZWUiKQoKYXJ0aWNsZXMgJT4lIAogIGlubmVyX2pvaW4oYXJ0aWNsZXNfdG9fcmVmX2NhdGVnb3JpZXMpICU+JQogIGlubmVyX2pvaW4oYXJ0aWNsZV90eXBlcykgJT4lCiAgbXV0YXRlKHllYXJfY3JlYXRlZD15ZWFyKGRhdGVfY3JlYXRlZCksd2Vla19jcmVhdGVkPXdlZWsoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgZ3JvdXBfYnkobWVkaWEscmVmX2NhdGVnb3J5LHR5cGUseWVhcl9jcmVhdGVkKSAlPiUKICBzdW1tYXJpemUoYXJ0aWNsZXM9bl9kaXN0aW5jdChhX2lkKSxkYXlzPW5fZGlzdGluY3QoZGF0ZV9jcmVhdGVkKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgaW5uZXJfam9pbihhcnRpY2xlc19ieV90eXBlX2J5X3llYXIpICU+JQogIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1hcnRpY2xlcy90b3RhbF9hcnRpY2xlcyxjb2xvcj1tZWRpYSkpICsKICBnZW9tX3N0ZXAoKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZShiYXNlX2ZhbWlseT0iQXJpYWwiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscz1zY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5PTAuMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgyMDAwLDIwMjAsYnk9MikpICsKICBmYWNldF9ncmlkKHJlZl9jYXRlZ29yeX50eXBlLHNjYWxlcz0iZnJlZSIpCmBgYAoKIyBBdXhpbGlhcnkgYmFja2dyb3VuZCBhbmFseXNlcwoKYGBge3J9CmFydGljbGVzICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpLG1vbnRoX2NyZWF0ZWQ9bW9udGgoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgY291bnQobWVkaWEseWVhcl9jcmVhdGVkLG1vbnRoX2NyZWF0ZWQpICU+JQogIGdncGxvdChhZXMoeD1hcy5EYXRlKHN0cl9jKHllYXJfY3JlYXRlZCwnLScsbW9udGhfY3JlYXRlZCwnLTAxJykpLHk9bixjb2xvcj1tZWRpYSkpICsKICBnZW9tX3N0ZXAoKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpCmBgYAoKYGBge3J9CmFydGljbGVzICU+JSAKICBpbm5lcl9qb2luKGFydGljbGVfdHlwZXMpICU+JQogIG11dGF0ZSh5ZWFyX2NyZWF0ZWQ9eWVhcihkYXRlX2NyZWF0ZWQpKSAlPiUKICBjb3VudChtZWRpYSx5ZWFyX2NyZWF0ZWQsdHlwZSkgJT4lCiAgZ2dwbG90KGFlcyh4PXllYXJfY3JlYXRlZCx5PW4sY29sb3I9dHlwZSkpICsKICBnZW9tX3N0ZXAoKSArCiAgZmFjZXRfd3JhcCh+bWVkaWEsc2NhbGVzPSJmcmVlIikgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKQpgYGAKCmBgYHtyfQphcnRpY2xlcyAlPiUgCiAgaW5uZXJfam9pbihhcnRpY2xlX3R5cGVzKSAlPiUKICBtdXRhdGUoeWVhcl9jcmVhdGVkPXllYXIoZGF0ZV9jcmVhdGVkKSkgJT4lCiAgbXV0YXRlKGZyb21fc3R0PWF1dGhvcj09IlNUVCIpICU+JQogIGZpbHRlcihtZWRpYT09IklMIikgJT4lCiAgY291bnQobWVkaWEseWVhcl9jcmVhdGVkLHR5cGUsZnJvbV9zdHQpICU+JQogIGNvbGxlY3QoKSAlPiUKICBncm91cF9ieShtZWRpYSkgJT4lCiAgbXV0YXRlKHR5cGU9ZmN0X2x1bXBfbih0eXBlLDExLHc9bikpICU+JQogIGNvdW50KG1lZGlhLHllYXJfY3JlYXRlZCx0eXBlLGZyb21fc3R0LHd0PW4pICU+JQogIGdncGxvdChhZXMoeD15ZWFyX2NyZWF0ZWQseT1uLGNvbG9yPWZyb21fc3R0PT0xKSkgKwogIGdlb21fc3RlcCgpICsKICBmYWNldF93cmFwKHR5cGV+bWVkaWEsc2NhbGVzPSJmcmVlIikgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKQpgYGAK