Error : Table 'vd17.vd17_normalized_years_c' doesn't exist [1146]
Joining, by = "record_number"Joining, by = "record_number"
Joining vd17_id and vd17_titles tables with
fbs_links_of_interest
fbs_links_of_interest_local <- fbs_links_of_interest_a %>%
inner_join(fbs_metadata_a %>% select(GND,Member_number_new,First_name_new,Last_name_new,Society_name,Estimated_admission_year,Estimated_DOD) %>% mutate(GND = str_c("gnd/", GND))) %>%
inner_join(vd17_id_a) %>%
inner_join(vd17_titles_a %>% select(record_number,title)) %>%
collect() %>%
select(where(~!all(is.na(.x))))
Joining, by = "GND"Joining, by = "record_number"Joining, by = "record_number"
fbs_links_of_interest_local <- select (fbs_links_of_interest_local, c('record_number','vd17_id','title','Member_number_new','First_name_new', 'Last_name_new','Society_name','GND','Estimated_admission_year','Estimated_DOD','role2','field_code'))
Joining vd17_id and vd17_titles tables with whole FBS (not
links_of_interest)
fbs_all_links_local <- fbs_links_a %>%
inner_join(fbs_metadata_a %>% select(GND,Member_number_new,First_name_new,Last_name_new,Society_name,Estimated_admission_year,Estimated_DOD) %>% mutate(GND = str_c("gnd/", GND))) %>%
inner_join(vd17_id_a) %>%
inner_join(vd17_titles_a %>% select(record_number,title)) %>%
collect() %>%
select(where(~!all(is.na(.x))))
Joining, by = "GND"Joining, by = "record_number"Joining, by = "record_number"
fbs_all_links_local <- select (fbs_all_links_local, c('record_number','vd17_id','title','Member_number_new','First_name_new', 'Last_name_new','Society_name','GND','Estimated_admission_year','Estimated_DOD','role2','field_code'))
Creating local tables of vd17 normalized years, genres, languages
and id.
vd17_normalized_years_local <- vd17_normalized_years_a %>%
collect()
vd17_genres_local <- vd17_genres_a %>%
collect()
vd17_normalized_langs_local <- vd17_normalized_langs_a %>%
collect()
vd17_id_local <- vd17_id_a %>%
collect()
FBS publications by year for members (links of interest).
The below plot depicts the number of publications (plus cumulative
distribution) by FBS members by year for links of interest.
publications_fbs <- fbs_links_of_interest_local %>%
left_join(vd17_normalized_years_local, by = c("record_number")) %>%
filter(normalized_year >= 1600, normalized_year <= 1700) %>%
filter(nchar(normalized_year)==4)%>%
select (record_number,normalized_year,vd17_id,title,Member_number_new,First_name_new,Last_name_new,Society_name,Estimated_admission_year,Estimated_DOD,GND,role2,field_code)
pub_fbs <-publications_fbs %>%
group_by(normalized_year) %>%
summarize(records = n_distinct(record_number), .groups = "drop") %>%
mutate(phase = case_when(
normalized_year < 1617 ~ "< 1617",
normalized_year >= 1617 & normalized_year <= 1650 ~ "phase 1",
normalized_year >= 1651 & normalized_year <= 1667 ~ "phase 2",
normalized_year >= 1668 & normalized_year <= 1682 ~ "phase 3",
normalized_year > 1682 ~ "> 1682"
))
ggplot(pub_fbs,aes(x=normalized_year, y=records, color = phase)) +
geom_step()+
xlab("Year") + ylab("FBS-Publications(links of interest)")+
scale_x_continuous(breaks = seq(1000, 2000, by = 5))+
theme_hsci_discrete()+
theme(axis.text.x=element_text(angle=90,hjust=1,vjust=0.5))

cumulative_frequencies_pub <- pub_fbs %>%
arrange(normalized_year) %>%
mutate(cum_frequency=cumsum(records))%>%
mutate(phase = case_when(
normalized_year < 1617 ~ "< 1617",
normalized_year >= 1617 & normalized_year <= 1650 ~ "phase 1",
normalized_year >= 1651 & normalized_year <= 1667 ~ "phase 2",
normalized_year >= 1668 & normalized_year <= 1682 ~ "phase 3",
normalized_year > 1682 ~ "> 1682"
))
ggplot(cumulative_frequencies_pub, aes(x=normalized_year, y=cum_frequency)) +
geom_step()+
xlab("Year") + ylab("FBS-Publications-CD (links of interest)")+
scale_x_continuous(breaks = seq(1000, 2000, by = 5))+
theme_hsci_discrete()+
theme(axis.text.x=element_text(angle=90,hjust=1,vjust=0.5))

FBS publications by year for all members.
The below plot depicts the number of publications (plus cumulative
distribution) by whole FBS members by year.
publications_fbs_all <- fbs_all_links_local %>%
left_join(vd17_normalized_years_local, by = c("record_number")) %>%
filter(normalized_year >= 1600, normalized_year <= 1700) %>%
filter(nchar(normalized_year)==4)%>%
select (record_number,normalized_year,vd17_id,title,Member_number_new,First_name_new,Last_name_new,Society_name,Estimated_admission_year,Estimated_DOD,GND,role2,field_code)
pub_fbs_all <-publications_fbs_all %>%
group_by(normalized_year) %>%
summarize(records = n_distinct(record_number), .groups = "drop") %>%
mutate(phase = case_when(
normalized_year < 1617 ~ "< 1617",
normalized_year >= 1617 & normalized_year <= 1650 ~ "phase 1",
normalized_year >= 1651 & normalized_year <= 1667 ~ "phase 2",
normalized_year >= 1668 & normalized_year <= 1682 ~ "phase 3",
normalized_year > 1682 ~ "> 1682"
))
ggplot(pub_fbs_all,aes(x=normalized_year, y=records, color = phase)) +
geom_step()+
xlab("Year") + ylab("FBS-Publications (all)")+
scale_x_continuous(breaks = seq(1000, 2000, by = 5))+
theme_hsci_discrete()+
theme(axis.text.x=element_text(angle=90,hjust=1,vjust=0.5))

cumulative_frequencies_pub_all <- pub_fbs_all %>%
arrange(normalized_year) %>%
mutate(cum_frequency=cumsum(records))%>%
mutate(phase = case_when(
normalized_year < 1617 ~ "< 1617",
normalized_year >= 1617 & normalized_year <= 1650 ~ "phase 1",
normalized_year >= 1651 & normalized_year <= 1667 ~ "phase 2",
normalized_year >= 1668 & normalized_year <= 1682 ~ "phase 3",
normalized_year > 1682 ~ "> 1682"
))
ggplot(cumulative_frequencies_pub_all, aes(x=normalized_year, y=cum_frequency)) +
geom_step()+
xlab("Year") + ylab("FBS-Publications-CD (all)")+
scale_x_continuous(breaks = seq(1000, 2000, by = 5))+
theme_hsci_discrete()+
theme(axis.text.x=element_text(angle=90,hjust=1,vjust=0.5))

FBS genres by year (links of interest).
The below plot depicts the top genre of FBS publications by year for
links of interest.
genres_fbs <- fbs_links_of_interest_local %>%
left_join(vd17_normalized_years_local, by = c("record_number")) %>%
filter(normalized_year >= 1600, normalized_year <= 1700) %>%
filter(nchar(normalized_year)==4)%>%
left_join(vd17_genres_local, by = c("record_number"))%>%
select (record_number,normalized_year,vd17_id,title,Member_number_new,First_name_new,Last_name_new,Society_name,Estimated_admission_year,Estimated_DOD,GND,role2,field_code,genre)
genre_fbs_links_of_interest <- gs4_create(
"sheets-genre_fbs_links_of_interest",
sheets = genres_fbs)
✔ Creating new Sheet: sheets-genre_fbs_links_of_interest.
The googlesheets4 package is requesting access to your Google account.
Select a pre-authorised account or enter '0' to obtain a new token.
Press Esc/Ctrl + C to cancel.
1: narges.azizifard@gmail.com
1
Auto-refreshing stale OAuth token.
genre_fbs_links_of_interest
Spreadsheet name: sheets-genre_fbs_links_of_interest
ID: 1UM1quvDGOkxRRLtDnf1eA-k6SsaeP8BRIr_wtzoq0kw
Locale: en_US
Time zone: Etc/GMT
# of sheets: 1
(Sheet name): (Nominal extent in rows x columns)
genres_fbs: 20398 x 14
phase_genres_fbs <- genres_fbs%>%
select(record_number,normalized_year,genre)%>%
distinct(record_number,normalized_year,genre)%>%
na.omit(genres_fbs)%>%
group_by(normalized_year) %>%
count(genre)%>%
arrange(desc(n))%>%
mutate(phase = case_when(
normalized_year < 1617 ~ "< 1617",
normalized_year >= 1617 & normalized_year <= 1650 ~ "phase 1",
normalized_year >= 1651 & normalized_year <= 1667 ~ "phase 2",
normalized_year >= 1668 & normalized_year <= 1682 ~ "phase 3",
normalized_year > 1682 ~ "> 1682"
))
phase_genres_fbs%>%
slice(1:1)%>%
ggplot(aes(x=normalized_year,y=n,fill=genre))+
geom_col()+
xlab("Year") + ylab("FBS-Top Genre_links_of_interest")+
scale_x_continuous(breaks = seq(1000, 2000, by = 5))+
theme_hsci_discrete()+
theme(axis.text.x=element_text(angle=90,hjust=1,vjust=0.5))+
theme(legend.position="right",
legend.key.width=unit(0.15, "cm"))+
geom_text(aes(label = n), color = "black", size = 1, position = position_stack(vjust = 0.9))

FBS genres by year (all).
The below plot depicts the top genre of whole FBS publications by
year.
genres_fbs_all <- fbs_all_links_local %>%
left_join(vd17_normalized_years_local, by = c("record_number")) %>%
filter(normalized_year >= 1600, normalized_year <= 1700) %>%
filter(nchar(normalized_year)==4)%>%
left_join(vd17_genres_local, by = c("record_number"))%>%
select (record_number,normalized_year,vd17_id,title,Member_number_new,First_name_new,Last_name_new,Society_name,Estimated_admission_year,Estimated_DOD,GND,role2,field_code,genre)
genre_fbs_all <- gs4_create(
"sheets-genre_fbs_all",
sheets = genres_fbs_all)
✔ Creating new Sheet: sheets-genre_fbs_all.
genre_fbs_all
Spreadsheet name: sheets-genre_fbs_all
ID: 11W7X4MRfDIyAu2UPOFiHgK4xgr--8nUaQ4AL3Bm5TNI
Locale: en_US
Time zone: Etc/GMT
# of sheets: 1
(Sheet name): (Nominal extent in rows x columns)
genres_fbs_all: 23599 x 14
phase_genres_fbs_all <- genres_fbs_all%>%
select(record_number,normalized_year,genre)%>%
distinct(record_number,normalized_year,genre)%>%
na.omit(genres_fbs_all)%>%
group_by(normalized_year) %>%
count(genre)%>%
arrange(desc(n))%>%
mutate(phase = case_when(
normalized_year < 1617 ~ "< 1617",
normalized_year >= 1617 & normalized_year <= 1650 ~ "phase 1",
normalized_year >= 1651 & normalized_year <= 1667 ~ "phase 2",
normalized_year >= 1668 & normalized_year <= 1682 ~ "phase 3",
normalized_year > 1682 ~ "> 1682"
))
phase_genres_fbs_all%>%
slice(1:1)%>%
ggplot(aes(x=normalized_year,y=n,fill=genre))+
geom_col()+
xlab("Year") + ylab("FBS-Top Genre_all")+
scale_x_continuous(breaks = seq(1000, 2000, by = 5))+
theme_hsci_discrete()+
theme(axis.text.x=element_text(angle=90,hjust=1,vjust=0.5))+
theme(legend.position="right",
legend.key.width=unit(0.15, "cm"))+
geom_text(aes(label = n), color = "black", size = 1, position = position_stack(vjust = 0.9))

The below code, shows the keywords related to translations available
in notes, titles and subtitles of publications (in a case that their
original language is NA)
list1 <- c("Übertrag","Übersetz","Geteutsch","Gedolmetsch","Dolmetsch","Verdeütsch","Verdeutsch","Verteutsch","Übergesetz","Versetzt","Gegenübersetz","Ubergesatz","Uberbracht","Überbracht","Teutsch","Deutsch","Gebracht","übertrag","übersetz","geteutsch","gedolmetsch","dolmetsch","verdeütsch","verdeutsch","verteutsch","übergesetz","versetzt","gegenübersetz","ubergesatz","uberbracht","überbracht","teutsch","deutsch","gebracht")
list2 <- c("Übers","übers")
vd17_a_translations_link1 <- vd17_a %>%
mutate(value = str_replace_all(value, sql("CHR(0)"), "_")) %>%
collect()%>%
filter(field_code %in% c("021A","021G","021M","021N"),grepl(paste(list1, collapse="|"), value))%>%
mutate(translations_value1=value)%>%
select(record_number,translations_value1)%>%
distinct()
vd17_a_translations_link2 <- vd17_a %>%
mutate(value = str_replace_all(value, sql("CHR(0)"), "_")) %>%
collect()%>%
filter(field_code %in% c("037A","046L"),grepl(paste(list2, collapse="|"), value))%>%
mutate(translations_value2=value)%>%
select(record_number,translations_value2)%>%
distinct()
vd17_a_translations_link <- merge(vd17_a_translations_link1, vd17_a_translations_link2,by=c("record_number"),all=TRUE)
vd17_a_translations_link <- vd17_a_translations_link %>%
distinct()
vd17_id_translations_link <- vd17_a_translations_link %>%
inner_join(vd17_id_local,by=c("record_number"))
vd17_specific_link_translations <- gs4_create(
"sheets-vd17_specific_link_translations_fbs",
sheets = vd17_id_translations_link)
✔ Creating new Sheet: sheets-vd17_specific_link_translations_fbs.
vd17_specific_link_translations
Spreadsheet name: sheets-vd17_specific_link_translations_fbs
ID: 1I3hnXDo_wxUtEbzWN8v9uScPNWhIORYO9qLezaSqFr0
Locale: en_US
Time zone: Etc/GMT
# of sheets: 1
(Sheet name): (Nominal extent in rows x columns)
vd17_id_translations_link: 21799 x 4
vd17_id_translations_link_2 = subset(vd17_id_translations_link, select = -c(translations_value1,translations_value2,vd17_id))
# FBS translations (links of interest) (It includes all translations not only German one which their original language is not NA).
fbs_translation <- fbs_links_of_interest_local %>%
left_join(vd17_normalized_years_local, by = c("record_number")) %>%
filter(normalized_year >= 1600, normalized_year <= 1700) %>%
filter(nchar(normalized_year)==4)%>%
left_join(vd17_normalized_langs_local, by = c("record_number"))%>%
filter(!is.na(original_language))%>%
left_join(vd17_genres_local, by = c("record_number"))%>%
select (record_number,normalized_year,vd17_id,title,Member_number_new,First_name_new,Last_name_new,Society_name,Estimated_admission_year,Estimated_DOD,GND,role2,field_code,original_language,intermediary_language,publication_language,genre)%>%
distinct()
# Joining the vd17 translations (which extracted by the keywords in their notes, titles, subtitles) with fbs publications, to extract more translations (in a case that their original language is NA).
specified_translation_fbs <- fbs_links_of_interest_local %>%
inner_join(vd17_id_translations_link_2, by = c("record_number"))%>%
left_join(vd17_normalized_years_local, by = c("record_number")) %>%
filter(normalized_year >= 1600, normalized_year <= 1700) %>%
filter(nchar(normalized_year)==4)%>%
left_join(vd17_normalized_langs_local, by = c("record_number"))%>%
left_join(vd17_genres_local, by = c("record_number"))%>%
select (record_number,normalized_year,vd17_id,title,Member_number_new,First_name_new,Last_name_new,Society_name,Estimated_admission_year,Estimated_DOD,GND,role2,field_code,original_language,intermediary_language,publication_language,genre)%>%
distinct()
# Finding the records of of translations with keywords, which are not available in FBS translations (by original language).
needed_translation_fbs <- specified_translation_fbs[!specified_translation_fbs$record_number %in% fbs_translation$record_number, , drop = FALSE]
needed_translations_of_fbs <- gs4_create(
"sheets-translations_of_fbs",
sheets = needed_translation_fbs)
✔ Creating new Sheet: sheets-translations_of_fbs.
needed_translations_of_fbs
Spreadsheet name: sheets-translations_of_fbs
ID: 1aJzEHRMQwhMxC7IcqN5uJXfusPDbXp4xhqfspBMLwbw
Locale: en_US
Time zone: Etc/GMT
# of sheets: 1
(Sheet name): (Nominal extent in rows x columns)
needed_translation_fbs: 1327 x 17
Genre of FBS (links of interest) (for German translations).
The below wordcloud depicts the frequency of genres of FBS
translations for links of interest.
library(wordcloud)
Loading required package: RColorBrewer
genre_translation_fbs <- fbs_translation%>%
filter(publication_language=="ger")%>%
select(record_number,normalized_year,genre)%>%
distinct(record_number,normalized_year,genre)%>%
na.omit(translation_fbs)%>%
group_by(genre) %>%
count(genre)%>%
arrange(desc(n))
wordcloud(words = genre_translation_fbs$genre, freq = genre_translation_fbs$n, min.freq = 1,
colors = brewer.pal(20,"Paired"), random.order=FALSE, scale = c(1, 0.4))
Warning: n too large, allowed maximum for palette Paired is 12
Returning the palette you asked for with that many colors

Original language of FBS translations (links of interest)(It
includes all translations not only German one).
The below wordcloud depicts the frequency of original_language of
FBS translations for links of interest.
o_language_translation_fbs <- fbs_translation%>%
select(record_number,normalized_year,original_language)%>%
distinct(record_number,normalized_year,original_language)%>%
na.omit(ger_translation_fbs_all)%>%
group_by(original_language) %>%
count(original_language)%>%
arrange(desc(n))
wordcloud(words = o_language_translation_fbs$original_language, freq = o_language_translation_fbs$n, min.freq = 1,
colors = brewer.pal(20,"Paired"), random.order=FALSE, scale = c(1, 0.4))
Warning: n too large, allowed maximum for palette Paired is 12
Returning the palette you asked for with that many colors

Primary authors and Translators of FBS translations (links of
interest)(It includes all translations not only German one).
primary_authors_links_of_interests <- fbs_translation%>%
filter(field_code=="028A")
primary_authors <- gs4_create(
"sheets-primary_authors_translations_fbs_links_of_interest",
sheets = primary_authors_links_of_interests)
✔ Creating new Sheet: sheets-primary_authors_translations_fbs_links_of_interest.
primary_authors
Spreadsheet name: sheets-primary_authors_translations_fbs_links_of_interest
ID: 1xF3PQ22i52-v-0BoTaPKB4Nmb0WeW37fv_Rn8CDBw6c
Locale: en_US
Time zone: Etc/GMT
# of sheets: 1
(Sheet name): (Nominal extent in rows x columns)
primary_authors_links_of_interests: 120 x 17
translators_translation_links_of_interest <- fbs_translation %>%
filter(field_code=="028C",(grepl(paste(c("Übers"), collapse="|"), role2)|role2 %in%(NA)))
translators_translation <- gs4_create(
"sheets-translator_translations_fbs",
sheets = translators_translation_links_of_interest)
✔ Creating new Sheet: sheets-translator_translations_fbs.
translators_translation
Spreadsheet name: sheets-translator_translations_fbs
ID: 1MQZbvrXSwimDCe15cUwIKkCgvyhEwy_305Oh8HfXzW0
Locale: en_US
Time zone: Etc/GMT
# of sheets: 1
(Sheet name): (Nominal extent in rows x columns)
translators_translation_links_of_interest: 391 x 17
Translated vs Non-Translated member publications_fbs (all).
The below plot depicts the Translated vs Non-Translated member
publications of FBS.
trans_vs_non_trans <- fbs_all_links_local %>%
left_join(vd17_normalized_years_local, by = c("record_number")) %>%
filter(normalized_year >= 1600, normalized_year <= 1700) %>%
filter(nchar(normalized_year)==4)%>%
left_join(vd17_normalized_langs_local, by = c("record_number"))%>%
select (record_number,normalized_year,vd17_id,title,Member_number_new,First_name_new,Last_name_new,Society_name,Estimated_admission_year,Estimated_DOD,GND,role2,field_code,original_language,publication_language)
trans_vs_non_trans$type <- is.na(trans_vs_non_trans$original_language)
trans_vs_non_trans$type[trans_vs_non_trans$type == "FALSE"] <- "Translated"
trans_vs_non_trans$type[trans_vs_non_trans$type == "TRUE"] <- "Non-Translated"
translated_vs_non_translated <- gs4_create(
"sheets-translated_vs_non_translated_fbs",
sheets = trans_vs_non_trans)
✔ Creating new Sheet: sheets-translated_vs_non_translated_fbs.
translated_vs_non_translated
Spreadsheet name: sheets-translated_vs_non_translated_fbs
ID: 1sFSYxEPi8p9szQo5QfLHOLtqqmFLeVoeKu5h1H7RwdM
Locale: en_US
Time zone: Etc/GMT
# of sheets: 1
(Sheet name): (Nominal extent in rows x columns)
trans_vs_non_trans: 14678 x 16
trans_vs_non_trans%>%
distinct(record_number,normalized_year,type)%>%
select(normalized_year,type)%>%
group_by(normalized_year)%>%
count(type)%>%
arrange(desc(n))%>%
ggplot(aes(x=normalized_year,y=n, fill=type)) +
geom_col()+
labs(y = "Translated vs Non-Translated FBS", x= "Years")+
scale_x_continuous(breaks = seq(1000, 2000, by = 5))+
theme_hsci_discrete()+
theme(axis.text.x=element_text(angle=90,hjust=1,vjust=0.5))+
theme(legend.position="bottom",
legend.key.width=unit(0.15, "cm"))+
geom_text(aes(label = n), color = "green", size = 1.8, position = position_stack(vjust = 0.9))

Translated vs Non-Translated member publications_fbs (all)
(Percentage by year).
trans_non_trans_percentage <- trans_vs_non_trans%>%
distinct(record_number,normalized_year,type)%>%
select(normalized_year,type)%>%
mutate(type = factor(type)) %>%
count(normalized_year, type, .drop = FALSE, name = 'Percentage') %>%
group_by(normalized_year) %>%
mutate(Percentage = round(Percentage/sum(Percentage) * 100),2)
translated_non_translated_percentage <- gs4_create(
"sheets-translated_non_translated_percentage_fbs",
sheets = trans_non_trans_percentage)
✔ Creating new Sheet: sheets-translated_non_translated_percentage_fbs.
translated_non_translated_percentage
Spreadsheet name: sheets-translated_non_translated_percentage_fbs
ID: 1lngxNQmTxVjsKYyXtPeHlfhY4T_FVFlVcQeTUffBSUo
Locale: en_US
Time zone: Etc/GMT
# of sheets: 1
(Sheet name): (Nominal extent in rows x columns)
trans_non_trans_percentage: 201 x 4
Translated vs Non-Translated member publications_fbs (all)
(Percentage by whole).
print(c("Translated",round(sum(trans_vs_non_trans$type=="Translated")/length(trans_vs_non_trans$type)*100,2)))
[1] "Translated" "2.95"
print(c("Non-Translated",round(sum(trans_vs_non_trans$type=="Non-Translated")/length(trans_vs_non_trans$type)*100,2)))
[1] "Non-Translated" "97.05"
LS0tCnRpdGxlOiAiRkJTIGFuYWx5c2lzIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKLS0tCgpgYGB7ciBzZXR1cCxlY2hvPUZ9CmtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gaGVyZTo6aGVyZSgpKQpsaWJyYXJ5KGhlcmUpCnNvdXJjZShoZXJlKCJjb2RlL2NvbW1vbl9iYXNpcy5SIiksIGxvY2FsID0ga25pdHI6OmtuaXRfZ2xvYmFsKCkpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGdnaHNjaSkKbGlicmFyeShndCkKcCA8LSBmdW5jdGlvbihudW1iZXIpIHsKICByZXR1cm4oZm9ybWF0KG51bWJlciwgc2NpZW50aWZpYyA9IEZBTFNFLCBiaWcubWFyayA9ICIsIikpCn0KcHAgPC0gZnVuY3Rpb24ocGVyY2VudGFnZSwgYWNjdXJhY3kgPSAwLjAxKSB7CiAgcmV0dXJuKHNjYWxlczo6cGVyY2VudChwZXJjZW50YWdlLCBhY2N1cmFjeSA9IGFjY3VyYWN5KSkKfQpgYGAKCiMgSm9pbmluZyB2ZDE3X2lkIGFuZCB2ZDE3X3RpdGxlcyB0YWJsZXMgd2l0aCBmYnNfbGlua3Nfb2ZfaW50ZXJlc3QgCmBgYHtyfQpmYnNfbGlua3Nfb2ZfaW50ZXJlc3RfbG9jYWwgPC0gZmJzX2xpbmtzX29mX2ludGVyZXN0X2EgJT4lCiAgaW5uZXJfam9pbihmYnNfbWV0YWRhdGFfYSAlPiUgc2VsZWN0KEdORCxNZW1iZXJfbnVtYmVyX25ldyxGaXJzdF9uYW1lX25ldyxMYXN0X25hbWVfbmV3LFNvY2lldHlfbmFtZSxFc3RpbWF0ZWRfYWRtaXNzaW9uX3llYXIsRXN0aW1hdGVkX0RPRCkgJT4lIG11dGF0ZShHTkQgPSBzdHJfYygiZ25kLyIsIEdORCkpKSAlPiUKICBpbm5lcl9qb2luKHZkMTdfaWRfYSkgJT4lCiAgaW5uZXJfam9pbih2ZDE3X3RpdGxlc19hICU+JSBzZWxlY3QocmVjb3JkX251bWJlcix0aXRsZSkpICU+JQogIGNvbGxlY3QoKSAlPiUKICBzZWxlY3Qod2hlcmUofiFhbGwoaXMubmEoLngpKSkpCgpmYnNfbGlua3Nfb2ZfaW50ZXJlc3RfbG9jYWwgPC0gc2VsZWN0IChmYnNfbGlua3Nfb2ZfaW50ZXJlc3RfbG9jYWwsIGMoJ3JlY29yZF9udW1iZXInLCd2ZDE3X2lkJywndGl0bGUnLCdNZW1iZXJfbnVtYmVyX25ldycsJ0ZpcnN0X25hbWVfbmV3JywgJ0xhc3RfbmFtZV9uZXcnLCdTb2NpZXR5X25hbWUnLCdHTkQnLCdFc3RpbWF0ZWRfYWRtaXNzaW9uX3llYXInLCdFc3RpbWF0ZWRfRE9EJywncm9sZTInLCdmaWVsZF9jb2RlJykpCmBgYAojIEpvaW5pbmcgdmQxN19pZCBhbmQgdmQxN190aXRsZXMgdGFibGVzIHdpdGggd2hvbGUgRkJTIChub3QgbGlua3Nfb2ZfaW50ZXJlc3QpCmBgYHtyfQpmYnNfYWxsX2xpbmtzX2xvY2FsIDwtIGZic19saW5rc19hICU+JQogIGlubmVyX2pvaW4oZmJzX21ldGFkYXRhX2EgJT4lIHNlbGVjdChHTkQsTWVtYmVyX251bWJlcl9uZXcsRmlyc3RfbmFtZV9uZXcsTGFzdF9uYW1lX25ldyxTb2NpZXR5X25hbWUsRXN0aW1hdGVkX2FkbWlzc2lvbl95ZWFyLEVzdGltYXRlZF9ET0QpICU+JSBtdXRhdGUoR05EID0gc3RyX2MoImduZC8iLCBHTkQpKSkgJT4lCiAgaW5uZXJfam9pbih2ZDE3X2lkX2EpICU+JQogIGlubmVyX2pvaW4odmQxN190aXRsZXNfYSAlPiUgc2VsZWN0KHJlY29yZF9udW1iZXIsdGl0bGUpKSAlPiUKICBjb2xsZWN0KCkgJT4lCiAgc2VsZWN0KHdoZXJlKH4hYWxsKGlzLm5hKC54KSkpKQoKZmJzX2FsbF9saW5rc19sb2NhbCA8LSBzZWxlY3QgKGZic19hbGxfbGlua3NfbG9jYWwsIGMoJ3JlY29yZF9udW1iZXInLCd2ZDE3X2lkJywndGl0bGUnLCdNZW1iZXJfbnVtYmVyX25ldycsJ0ZpcnN0X25hbWVfbmV3JywgJ0xhc3RfbmFtZV9uZXcnLCdTb2NpZXR5X25hbWUnLCdHTkQnLCdFc3RpbWF0ZWRfYWRtaXNzaW9uX3llYXInLCdFc3RpbWF0ZWRfRE9EJywncm9sZTInLCdmaWVsZF9jb2RlJykpCmBgYAojIENyZWF0aW5nIGxvY2FsIHRhYmxlcyBvZiB2ZDE3IG5vcm1hbGl6ZWQgeWVhcnMsIGdlbnJlcywgbGFuZ3VhZ2VzIGFuZCBpZC4KYGBge3J9CnZkMTdfbm9ybWFsaXplZF95ZWFyc19sb2NhbCA8LSB2ZDE3X25vcm1hbGl6ZWRfeWVhcnNfYSAlPiUKICBjb2xsZWN0KCkKdmQxN19nZW5yZXNfbG9jYWwgPC0gdmQxN19nZW5yZXNfYSAlPiUKICBjb2xsZWN0KCkKdmQxN19ub3JtYWxpemVkX2xhbmdzX2xvY2FsIDwtIHZkMTdfbm9ybWFsaXplZF9sYW5nc19hICU+JQogIGNvbGxlY3QoKQp2ZDE3X2lkX2xvY2FsIDwtIHZkMTdfaWRfYSAlPiUKICBjb2xsZWN0KCkKYGBgCgojIEZCUyBwdWJsaWNhdGlvbnMgYnkgeWVhciBmb3IgbWVtYmVycyAobGlua3Mgb2YgaW50ZXJlc3QpLgojIFRoZSBiZWxvdyBwbG90IGRlcGljdHMgdGhlIG51bWJlciBvZiBwdWJsaWNhdGlvbnMgKHBsdXMgY3VtdWxhdGl2ZSBkaXN0cmlidXRpb24pIGJ5IEZCUyBtZW1iZXJzIGJ5IHllYXIgZm9yIGxpbmtzIG9mIGludGVyZXN0LiAKYGBge3J9CnB1YmxpY2F0aW9uc19mYnMgPC0gZmJzX2xpbmtzX29mX2ludGVyZXN0X2xvY2FsICU+JQogIGxlZnRfam9pbih2ZDE3X25vcm1hbGl6ZWRfeWVhcnNfbG9jYWwsIGJ5ID0gYygicmVjb3JkX251bWJlciIpKSAlPiUKICBmaWx0ZXIobm9ybWFsaXplZF95ZWFyID49IDE2MDAsIG5vcm1hbGl6ZWRfeWVhciA8PSAxNzAwKSAlPiUKICBmaWx0ZXIobmNoYXIobm9ybWFsaXplZF95ZWFyKT09NCklPiUKICBzZWxlY3QgKHJlY29yZF9udW1iZXIsbm9ybWFsaXplZF95ZWFyLHZkMTdfaWQsdGl0bGUsTWVtYmVyX251bWJlcl9uZXcsRmlyc3RfbmFtZV9uZXcsTGFzdF9uYW1lX25ldyxTb2NpZXR5X25hbWUsRXN0aW1hdGVkX2FkbWlzc2lvbl95ZWFyLEVzdGltYXRlZF9ET0QsR05ELHJvbGUyLGZpZWxkX2NvZGUpCgpwdWJfZmJzIDwtcHVibGljYXRpb25zX2ZicyAlPiUKICBncm91cF9ieShub3JtYWxpemVkX3llYXIpICU+JQogIHN1bW1hcml6ZShyZWNvcmRzID0gbl9kaXN0aW5jdChyZWNvcmRfbnVtYmVyKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgbXV0YXRlKHBoYXNlID0gY2FzZV93aGVuKAogICAgbm9ybWFsaXplZF95ZWFyIDwgMTYxNyB+ICI8IDE2MTciLAogICAgbm9ybWFsaXplZF95ZWFyID49IDE2MTcgJiBub3JtYWxpemVkX3llYXIgPD0gMTY1MCB+ICJwaGFzZSAxIiwKICAgIG5vcm1hbGl6ZWRfeWVhciA+PSAxNjUxICYgbm9ybWFsaXplZF95ZWFyIDw9IDE2NjcgfiAicGhhc2UgMiIsCiAgICBub3JtYWxpemVkX3llYXIgPj0gMTY2OCAmIG5vcm1hbGl6ZWRfeWVhciA8PSAxNjgyIH4gInBoYXNlIDMiLAogICAgbm9ybWFsaXplZF95ZWFyID4gMTY4MiB+ICI+IDE2ODIiCiAgKSkKCiAgZ2dwbG90KHB1Yl9mYnMsYWVzKHg9bm9ybWFsaXplZF95ZWFyLCB5PXJlY29yZHMsIGNvbG9yID0gcGhhc2UpKSArIAogIGdlb21fc3RlcCgpKwogIHhsYWIoIlllYXIiKSArIHlsYWIoIkZCUy1QdWJsaWNhdGlvbnMobGlua3Mgb2YgaW50ZXJlc3QpIikrCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxMDAwLCAyMDAwLCBieSA9IDUpKSsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkrCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTkwLGhqdXN0PTEsdmp1c3Q9MC41KSkKICAKICBjdW11bGF0aXZlX2ZyZXF1ZW5jaWVzX3B1YiA8LSBwdWJfZmJzICU+JSAKICBhcnJhbmdlKG5vcm1hbGl6ZWRfeWVhcikgJT4lIAogIG11dGF0ZShjdW1fZnJlcXVlbmN5PWN1bXN1bShyZWNvcmRzKSklPiUKICBtdXRhdGUocGhhc2UgPSBjYXNlX3doZW4oCiAgICBub3JtYWxpemVkX3llYXIgPCAxNjE3IH4gIjwgMTYxNyIsCiAgICBub3JtYWxpemVkX3llYXIgPj0gMTYxNyAmIG5vcm1hbGl6ZWRfeWVhciA8PSAxNjUwIH4gInBoYXNlIDEiLAogICAgbm9ybWFsaXplZF95ZWFyID49IDE2NTEgJiBub3JtYWxpemVkX3llYXIgPD0gMTY2NyB+ICJwaGFzZSAyIiwKICAgIG5vcm1hbGl6ZWRfeWVhciA+PSAxNjY4ICYgbm9ybWFsaXplZF95ZWFyIDw9IDE2ODIgfiAicGhhc2UgMyIsCiAgICBub3JtYWxpemVkX3llYXIgPiAxNjgyIH4gIj4gMTY4MiIKICApKQoKCmdncGxvdChjdW11bGF0aXZlX2ZyZXF1ZW5jaWVzX3B1YiwgYWVzKHg9bm9ybWFsaXplZF95ZWFyLCB5PWN1bV9mcmVxdWVuY3kpKSArCiAgZ2VvbV9zdGVwKCkrCiAgeGxhYigiWWVhciIpICsgeWxhYigiRkJTLVB1YmxpY2F0aW9ucy1DRCAobGlua3Mgb2YgaW50ZXJlc3QpIikrCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxMDAwLCAyMDAwLCBieSA9IDUpKSsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkrCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTkwLGhqdXN0PTEsdmp1c3Q9MC41KSkKYGBgCiMgRkJTIHB1YmxpY2F0aW9ucyBieSB5ZWFyIGZvciBhbGwgbWVtYmVycy4gCiMgVGhlIGJlbG93IHBsb3QgZGVwaWN0cyB0aGUgbnVtYmVyIG9mIHB1YmxpY2F0aW9ucyAocGx1cyBjdW11bGF0aXZlIGRpc3RyaWJ1dGlvbikgYnkgd2hvbGUgRkJTIG1lbWJlcnMgYnkgeWVhci4gCmBgYHtyfQpwdWJsaWNhdGlvbnNfZmJzX2FsbCA8LSBmYnNfYWxsX2xpbmtzX2xvY2FsICU+JQogIGxlZnRfam9pbih2ZDE3X25vcm1hbGl6ZWRfeWVhcnNfbG9jYWwsIGJ5ID0gYygicmVjb3JkX251bWJlciIpKSAlPiUKICBmaWx0ZXIobm9ybWFsaXplZF95ZWFyID49IDE2MDAsIG5vcm1hbGl6ZWRfeWVhciA8PSAxNzAwKSAlPiUKICBmaWx0ZXIobmNoYXIobm9ybWFsaXplZF95ZWFyKT09NCklPiUKICBzZWxlY3QgKHJlY29yZF9udW1iZXIsbm9ybWFsaXplZF95ZWFyLHZkMTdfaWQsdGl0bGUsTWVtYmVyX251bWJlcl9uZXcsRmlyc3RfbmFtZV9uZXcsTGFzdF9uYW1lX25ldyxTb2NpZXR5X25hbWUsRXN0aW1hdGVkX2FkbWlzc2lvbl95ZWFyLEVzdGltYXRlZF9ET0QsR05ELHJvbGUyLGZpZWxkX2NvZGUpCgpwdWJfZmJzX2FsbCA8LXB1YmxpY2F0aW9uc19mYnNfYWxsICU+JQogIGdyb3VwX2J5KG5vcm1hbGl6ZWRfeWVhcikgJT4lCiAgc3VtbWFyaXplKHJlY29yZHMgPSBuX2Rpc3RpbmN0KHJlY29yZF9udW1iZXIpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICBtdXRhdGUocGhhc2UgPSBjYXNlX3doZW4oCiAgICBub3JtYWxpemVkX3llYXIgPCAxNjE3IH4gIjwgMTYxNyIsCiAgICBub3JtYWxpemVkX3llYXIgPj0gMTYxNyAmIG5vcm1hbGl6ZWRfeWVhciA8PSAxNjUwIH4gInBoYXNlIDEiLAogICAgbm9ybWFsaXplZF95ZWFyID49IDE2NTEgJiBub3JtYWxpemVkX3llYXIgPD0gMTY2NyB+ICJwaGFzZSAyIiwKICAgIG5vcm1hbGl6ZWRfeWVhciA+PSAxNjY4ICYgbm9ybWFsaXplZF95ZWFyIDw9IDE2ODIgfiAicGhhc2UgMyIsCiAgICBub3JtYWxpemVkX3llYXIgPiAxNjgyIH4gIj4gMTY4MiIKICApKQoKICBnZ3Bsb3QocHViX2Zic19hbGwsYWVzKHg9bm9ybWFsaXplZF95ZWFyLCB5PXJlY29yZHMsIGNvbG9yID0gcGhhc2UpKSArIAogIGdlb21fc3RlcCgpKwogIHhsYWIoIlllYXIiKSArIHlsYWIoIkZCUy1QdWJsaWNhdGlvbnMgKGFsbCkiKSsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDEwMDAsIDIwMDAsIGJ5ID0gNSkpKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKSsKICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoYW5nbGU9OTAsaGp1c3Q9MSx2anVzdD0wLjUpKQogIAogIAogIGN1bXVsYXRpdmVfZnJlcXVlbmNpZXNfcHViX2FsbCA8LSBwdWJfZmJzX2FsbCAlPiUgCiAgYXJyYW5nZShub3JtYWxpemVkX3llYXIpICU+JSAKICBtdXRhdGUoY3VtX2ZyZXF1ZW5jeT1jdW1zdW0ocmVjb3JkcykpJT4lCiAgbXV0YXRlKHBoYXNlID0gY2FzZV93aGVuKAogICAgbm9ybWFsaXplZF95ZWFyIDwgMTYxNyB+ICI8IDE2MTciLAogICAgbm9ybWFsaXplZF95ZWFyID49IDE2MTcgJiBub3JtYWxpemVkX3llYXIgPD0gMTY1MCB+ICJwaGFzZSAxIiwKICAgIG5vcm1hbGl6ZWRfeWVhciA+PSAxNjUxICYgbm9ybWFsaXplZF95ZWFyIDw9IDE2NjcgfiAicGhhc2UgMiIsCiAgICBub3JtYWxpemVkX3llYXIgPj0gMTY2OCAmIG5vcm1hbGl6ZWRfeWVhciA8PSAxNjgyIH4gInBoYXNlIDMiLAogICAgbm9ybWFsaXplZF95ZWFyID4gMTY4MiB+ICI+IDE2ODIiCiAgKSkKCgpnZ3Bsb3QoY3VtdWxhdGl2ZV9mcmVxdWVuY2llc19wdWJfYWxsLCBhZXMoeD1ub3JtYWxpemVkX3llYXIsIHk9Y3VtX2ZyZXF1ZW5jeSkpICsKICBnZW9tX3N0ZXAoKSsKICB4bGFiKCJZZWFyIikgKyB5bGFiKCJGQlMtUHVibGljYXRpb25zLUNEIChhbGwpIikrCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxMDAwLCAyMDAwLCBieSA9IDUpKSsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkrCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTkwLGhqdXN0PTEsdmp1c3Q9MC41KSkKYGBgCiMgRkJTIGdlbnJlcyBieSB5ZWFyIChsaW5rcyBvZiBpbnRlcmVzdCkuCiMgVGhlIGJlbG93IHBsb3QgZGVwaWN0cyB0aGUgdG9wIGdlbnJlIG9mIEZCUyBwdWJsaWNhdGlvbnMgYnkgeWVhciBmb3IgbGlua3Mgb2YgaW50ZXJlc3QuCmBgYHtyfQpnZW5yZXNfZmJzIDwtIGZic19saW5rc19vZl9pbnRlcmVzdF9sb2NhbCAlPiUKICBsZWZ0X2pvaW4odmQxN19ub3JtYWxpemVkX3llYXJzX2xvY2FsLCBieSA9IGMoInJlY29yZF9udW1iZXIiKSkgJT4lCiAgZmlsdGVyKG5vcm1hbGl6ZWRfeWVhciA+PSAxNjAwLCBub3JtYWxpemVkX3llYXIgPD0gMTcwMCkgJT4lCiAgZmlsdGVyKG5jaGFyKG5vcm1hbGl6ZWRfeWVhcik9PTQpJT4lCiAgbGVmdF9qb2luKHZkMTdfZ2VucmVzX2xvY2FsLCBieSA9IGMoInJlY29yZF9udW1iZXIiKSklPiUKICBzZWxlY3QgKHJlY29yZF9udW1iZXIsbm9ybWFsaXplZF95ZWFyLHZkMTdfaWQsdGl0bGUsTWVtYmVyX251bWJlcl9uZXcsRmlyc3RfbmFtZV9uZXcsTGFzdF9uYW1lX25ldyxTb2NpZXR5X25hbWUsRXN0aW1hdGVkX2FkbWlzc2lvbl95ZWFyLEVzdGltYXRlZF9ET0QsR05ELHJvbGUyLGZpZWxkX2NvZGUsZ2VucmUpCgpnZW5yZV9mYnNfbGlua3Nfb2ZfaW50ZXJlc3QgPC0gZ3M0X2NyZWF0ZSgKICAic2hlZXRzLWdlbnJlX2Zic19saW5rc19vZl9pbnRlcmVzdCIsCiAgc2hlZXRzID0gZ2VucmVzX2ZicykKCmdlbnJlX2Zic19saW5rc19vZl9pbnRlcmVzdAoKcGhhc2VfZ2VucmVzX2ZicyA8LSBnZW5yZXNfZmJzJT4lCiAgc2VsZWN0KHJlY29yZF9udW1iZXIsbm9ybWFsaXplZF95ZWFyLGdlbnJlKSU+JQogIGRpc3RpbmN0KHJlY29yZF9udW1iZXIsbm9ybWFsaXplZF95ZWFyLGdlbnJlKSU+JQogIG5hLm9taXQoZ2VucmVzX2ZicyklPiUKICBncm91cF9ieShub3JtYWxpemVkX3llYXIpICU+JQogIGNvdW50KGdlbnJlKSU+JQogIGFycmFuZ2UoZGVzYyhuKSklPiUKICBtdXRhdGUocGhhc2UgPSBjYXNlX3doZW4oCiAgICBub3JtYWxpemVkX3llYXIgPCAxNjE3IH4gIjwgMTYxNyIsCiAgICBub3JtYWxpemVkX3llYXIgPj0gMTYxNyAmIG5vcm1hbGl6ZWRfeWVhciA8PSAxNjUwIH4gInBoYXNlIDEiLAogICAgbm9ybWFsaXplZF95ZWFyID49IDE2NTEgJiBub3JtYWxpemVkX3llYXIgPD0gMTY2NyB+ICJwaGFzZSAyIiwKICAgIG5vcm1hbGl6ZWRfeWVhciA+PSAxNjY4ICYgbm9ybWFsaXplZF95ZWFyIDw9IDE2ODIgfiAicGhhc2UgMyIsCiAgICBub3JtYWxpemVkX3llYXIgPiAxNjgyIH4gIj4gMTY4MiIKICApKQoKCnBoYXNlX2dlbnJlc19mYnMlPiUKICBzbGljZSgxOjEpJT4lCiAgZ2dwbG90KGFlcyh4PW5vcm1hbGl6ZWRfeWVhcix5PW4sZmlsbD1nZW5yZSkpKwogIGdlb21fY29sKCkrCiAgeGxhYigiWWVhciIpICsgeWxhYigiRkJTLVRvcCBHZW5yZV9saW5rc19vZl9pbnRlcmVzdCIpKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMTAwMCwgMjAwMCwgYnkgPSA1KSkrCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT05MCxoanVzdD0xLHZqdXN0PTAuNSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0icmlnaHQiLAogICAgICAgIGxlZ2VuZC5rZXkud2lkdGg9dW5pdCgwLjE1LCAiY20iKSkrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAxLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC45KSkgCmBgYAoKIyBGQlMgZ2VucmVzIGJ5IHllYXIgKGFsbCkuCiMgVGhlIGJlbG93IHBsb3QgZGVwaWN0cyB0aGUgdG9wIGdlbnJlIG9mIHdob2xlIEZCUyBwdWJsaWNhdGlvbnMgYnkgeWVhci4KYGBge3J9CmdlbnJlc19mYnNfYWxsIDwtIGZic19hbGxfbGlua3NfbG9jYWwgJT4lCiAgbGVmdF9qb2luKHZkMTdfbm9ybWFsaXplZF95ZWFyc19sb2NhbCwgYnkgPSBjKCJyZWNvcmRfbnVtYmVyIikpICU+JQogIGZpbHRlcihub3JtYWxpemVkX3llYXIgPj0gMTYwMCwgbm9ybWFsaXplZF95ZWFyIDw9IDE3MDApICU+JQogIGZpbHRlcihuY2hhcihub3JtYWxpemVkX3llYXIpPT00KSU+JQogIGxlZnRfam9pbih2ZDE3X2dlbnJlc19sb2NhbCwgYnkgPSBjKCJyZWNvcmRfbnVtYmVyIikpJT4lCiAgc2VsZWN0IChyZWNvcmRfbnVtYmVyLG5vcm1hbGl6ZWRfeWVhcix2ZDE3X2lkLHRpdGxlLE1lbWJlcl9udW1iZXJfbmV3LEZpcnN0X25hbWVfbmV3LExhc3RfbmFtZV9uZXcsU29jaWV0eV9uYW1lLEVzdGltYXRlZF9hZG1pc3Npb25feWVhcixFc3RpbWF0ZWRfRE9ELEdORCxyb2xlMixmaWVsZF9jb2RlLGdlbnJlKQoKZ2VucmVfZmJzX2FsbCA8LSBnczRfY3JlYXRlKAogICJzaGVldHMtZ2VucmVfZmJzX2FsbCIsCiAgc2hlZXRzID0gZ2VucmVzX2Zic19hbGwpCgpnZW5yZV9mYnNfYWxsCgpwaGFzZV9nZW5yZXNfZmJzX2FsbCA8LSBnZW5yZXNfZmJzX2FsbCU+JQogIHNlbGVjdChyZWNvcmRfbnVtYmVyLG5vcm1hbGl6ZWRfeWVhcixnZW5yZSklPiUKICBkaXN0aW5jdChyZWNvcmRfbnVtYmVyLG5vcm1hbGl6ZWRfeWVhcixnZW5yZSklPiUKICBuYS5vbWl0KGdlbnJlc19mYnNfYWxsKSU+JQogIGdyb3VwX2J5KG5vcm1hbGl6ZWRfeWVhcikgJT4lCiAgY291bnQoZ2VucmUpJT4lCiAgYXJyYW5nZShkZXNjKG4pKSU+JQogIG11dGF0ZShwaGFzZSA9IGNhc2Vfd2hlbigKICAgIG5vcm1hbGl6ZWRfeWVhciA8IDE2MTcgfiAiPCAxNjE3IiwKICAgIG5vcm1hbGl6ZWRfeWVhciA+PSAxNjE3ICYgbm9ybWFsaXplZF95ZWFyIDw9IDE2NTAgfiAicGhhc2UgMSIsCiAgICBub3JtYWxpemVkX3llYXIgPj0gMTY1MSAmIG5vcm1hbGl6ZWRfeWVhciA8PSAxNjY3IH4gInBoYXNlIDIiLAogICAgbm9ybWFsaXplZF95ZWFyID49IDE2NjggJiBub3JtYWxpemVkX3llYXIgPD0gMTY4MiB+ICJwaGFzZSAzIiwKICAgIG5vcm1hbGl6ZWRfeWVhciA+IDE2ODIgfiAiPiAxNjgyIgogICkpCgpwaGFzZV9nZW5yZXNfZmJzX2FsbCU+JQogIHNsaWNlKDE6MSklPiUKICBnZ3Bsb3QoYWVzKHg9bm9ybWFsaXplZF95ZWFyLHk9bixmaWxsPWdlbnJlKSkrCiAgZ2VvbV9jb2woKSsKICB4bGFiKCJZZWFyIikgKyB5bGFiKCJGQlMtVG9wIEdlbnJlX2FsbCIpKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMTAwMCwgMjAwMCwgYnkgPSA1KSkrCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT05MCxoanVzdD0xLHZqdXN0PTAuNSkpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0icmlnaHQiLAogICAgICAgIGxlZ2VuZC5rZXkud2lkdGg9dW5pdCgwLjE1LCAiY20iKSkrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSAxLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC45KSkgCmBgYAojIFRoZSBiZWxvdyBjb2RlLCBzaG93cyB0aGUga2V5d29yZHMgcmVsYXRlZCB0byB0cmFuc2xhdGlvbnMgYXZhaWxhYmxlIGluIG5vdGVzLCB0aXRsZXMgYW5kIHN1YnRpdGxlcyBvZiBwdWJsaWNhdGlvbnMgKGluIGEgY2FzZSB0aGF0IHRoZWlyIG9yaWdpbmFsIGxhbmd1YWdlIGlzIE5BKQoKYGBge3J9Cmxpc3QxIDwtIGMoIsOcYmVydHJhZyIsIsOcYmVyc2V0eiIsIkdldGV1dHNjaCIsIkdlZG9sbWV0c2NoIiwiRG9sbWV0c2NoIiwiVmVyZGXDvHRzY2giLCJWZXJkZXV0c2NoIiwiVmVydGV1dHNjaCIsIsOcYmVyZ2VzZXR6IiwiVmVyc2V0enQiLCJHZWdlbsO8YmVyc2V0eiIsIlViZXJnZXNhdHoiLCJVYmVyYnJhY2h0Iiwiw5xiZXJicmFjaHQiLCJUZXV0c2NoIiwiRGV1dHNjaCIsIkdlYnJhY2h0Iiwiw7xiZXJ0cmFnIiwiw7xiZXJzZXR6IiwiZ2V0ZXV0c2NoIiwiZ2Vkb2xtZXRzY2giLCJkb2xtZXRzY2giLCJ2ZXJkZcO8dHNjaCIsInZlcmRldXRzY2giLCJ2ZXJ0ZXV0c2NoIiwiw7xiZXJnZXNldHoiLCJ2ZXJzZXR6dCIsImdlZ2Vuw7xiZXJzZXR6IiwidWJlcmdlc2F0eiIsInViZXJicmFjaHQiLCLDvGJlcmJyYWNodCIsInRldXRzY2giLCJkZXV0c2NoIiwiZ2VicmFjaHQiKQpsaXN0MiA8LSBjKCLDnGJlcnMiLCLDvGJlcnMiKQoKdmQxN19hX3RyYW5zbGF0aW9uc19saW5rMSA8LSB2ZDE3X2EgJT4lIAogIG11dGF0ZSh2YWx1ZSA9IHN0cl9yZXBsYWNlX2FsbCh2YWx1ZSwgc3FsKCJDSFIoMCkiKSwgIl8iKSkgJT4lCiAgY29sbGVjdCgpJT4lCiAgZmlsdGVyKGZpZWxkX2NvZGUgJWluJSBjKCIwMjFBIiwiMDIxRyIsIjAyMU0iLCIwMjFOIiksZ3JlcGwocGFzdGUobGlzdDEsIGNvbGxhcHNlPSJ8IiksIHZhbHVlKSklPiUKICBtdXRhdGUodHJhbnNsYXRpb25zX3ZhbHVlMT12YWx1ZSklPiUKICBzZWxlY3QocmVjb3JkX251bWJlcix0cmFuc2xhdGlvbnNfdmFsdWUxKSU+JQogIGRpc3RpbmN0KCkKCnZkMTdfYV90cmFuc2xhdGlvbnNfbGluazIgPC0gdmQxN19hICU+JSAKICBtdXRhdGUodmFsdWUgPSBzdHJfcmVwbGFjZV9hbGwodmFsdWUsIHNxbCgiQ0hSKDApIiksICJfIikpICU+JQogIGNvbGxlY3QoKSU+JQogIGZpbHRlcihmaWVsZF9jb2RlICVpbiUgYygiMDM3QSIsIjA0NkwiKSxncmVwbChwYXN0ZShsaXN0MiwgY29sbGFwc2U9InwiKSwgdmFsdWUpKSU+JQogIG11dGF0ZSh0cmFuc2xhdGlvbnNfdmFsdWUyPXZhbHVlKSU+JQogIHNlbGVjdChyZWNvcmRfbnVtYmVyLHRyYW5zbGF0aW9uc192YWx1ZTIpJT4lCiAgZGlzdGluY3QoKQoKdmQxN19hX3RyYW5zbGF0aW9uc19saW5rIDwtIG1lcmdlKHZkMTdfYV90cmFuc2xhdGlvbnNfbGluazEsIHZkMTdfYV90cmFuc2xhdGlvbnNfbGluazIsYnk9YygicmVjb3JkX251bWJlciIpLGFsbD1UUlVFKQp2ZDE3X2FfdHJhbnNsYXRpb25zX2xpbmsgPC0gdmQxN19hX3RyYW5zbGF0aW9uc19saW5rICU+JQogIGRpc3RpbmN0KCkKCnZkMTdfaWRfdHJhbnNsYXRpb25zX2xpbmsgPC0gdmQxN19hX3RyYW5zbGF0aW9uc19saW5rICU+JQogIGlubmVyX2pvaW4odmQxN19pZF9sb2NhbCxieT1jKCJyZWNvcmRfbnVtYmVyIikpCgp2ZDE3X3NwZWNpZmljX2xpbmtfdHJhbnNsYXRpb25zIDwtIGdzNF9jcmVhdGUoCiAgInNoZWV0cy12ZDE3X3NwZWNpZmljX2xpbmtfdHJhbnNsYXRpb25zX2ZicyIsCiAgc2hlZXRzID0gdmQxN19pZF90cmFuc2xhdGlvbnNfbGluaykKdmQxN19zcGVjaWZpY19saW5rX3RyYW5zbGF0aW9ucwpgYGAKYGBge3J9CnZkMTdfaWRfdHJhbnNsYXRpb25zX2xpbmtfMiA9IHN1YnNldCh2ZDE3X2lkX3RyYW5zbGF0aW9uc19saW5rLCBzZWxlY3QgPSAtYyh0cmFuc2xhdGlvbnNfdmFsdWUxLHRyYW5zbGF0aW9uc192YWx1ZTIsdmQxN19pZCkpCmBgYAoKYGBge3J9CiMgRkJTIHRyYW5zbGF0aW9ucyAobGlua3Mgb2YgaW50ZXJlc3QpIChJdCBpbmNsdWRlcyBhbGwgdHJhbnNsYXRpb25zIG5vdCBvbmx5IEdlcm1hbiBvbmUgd2hpY2ggdGhlaXIgb3JpZ2luYWwgbGFuZ3VhZ2UgaXMgbm90IE5BKS4KCmZic190cmFuc2xhdGlvbiA8LSBmYnNfbGlua3Nfb2ZfaW50ZXJlc3RfbG9jYWwgJT4lCiAgbGVmdF9qb2luKHZkMTdfbm9ybWFsaXplZF95ZWFyc19sb2NhbCwgYnkgPSBjKCJyZWNvcmRfbnVtYmVyIikpICU+JQogIGZpbHRlcihub3JtYWxpemVkX3llYXIgPj0gMTYwMCwgbm9ybWFsaXplZF95ZWFyIDw9IDE3MDApICU+JQogIGZpbHRlcihuY2hhcihub3JtYWxpemVkX3llYXIpPT00KSU+JQogIGxlZnRfam9pbih2ZDE3X25vcm1hbGl6ZWRfbGFuZ3NfbG9jYWwsIGJ5ID0gYygicmVjb3JkX251bWJlciIpKSU+JQogIGZpbHRlcighaXMubmEob3JpZ2luYWxfbGFuZ3VhZ2UpKSU+JQogIGxlZnRfam9pbih2ZDE3X2dlbnJlc19sb2NhbCwgYnkgPSBjKCJyZWNvcmRfbnVtYmVyIikpJT4lCiAgc2VsZWN0IChyZWNvcmRfbnVtYmVyLG5vcm1hbGl6ZWRfeWVhcix2ZDE3X2lkLHRpdGxlLE1lbWJlcl9udW1iZXJfbmV3LEZpcnN0X25hbWVfbmV3LExhc3RfbmFtZV9uZXcsU29jaWV0eV9uYW1lLEVzdGltYXRlZF9hZG1pc3Npb25feWVhcixFc3RpbWF0ZWRfRE9ELEdORCxyb2xlMixmaWVsZF9jb2RlLG9yaWdpbmFsX2xhbmd1YWdlLGludGVybWVkaWFyeV9sYW5ndWFnZSxwdWJsaWNhdGlvbl9sYW5ndWFnZSxnZW5yZSklPiUKICBkaXN0aW5jdCgpCgojIEpvaW5pbmcgdGhlIHZkMTcgdHJhbnNsYXRpb25zICh3aGljaCBleHRyYWN0ZWQgYnkgdGhlIGtleXdvcmRzIGluIHRoZWlyIG5vdGVzLCB0aXRsZXMsIHN1YnRpdGxlcykgd2l0aCBmYnMgcHVibGljYXRpb25zLCB0byBleHRyYWN0IG1vcmUgdHJhbnNsYXRpb25zIChpbiBhIGNhc2UgdGhhdCB0aGVpciBvcmlnaW5hbCBsYW5ndWFnZSBpcyBOQSkuCnNwZWNpZmllZF90cmFuc2xhdGlvbl9mYnMgPC0gZmJzX2xpbmtzX29mX2ludGVyZXN0X2xvY2FsICU+JQogIGlubmVyX2pvaW4odmQxN19pZF90cmFuc2xhdGlvbnNfbGlua18yLCBieSA9IGMoInJlY29yZF9udW1iZXIiKSklPiUKICBsZWZ0X2pvaW4odmQxN19ub3JtYWxpemVkX3llYXJzX2xvY2FsLCBieSA9IGMoInJlY29yZF9udW1iZXIiKSkgJT4lCiAgZmlsdGVyKG5vcm1hbGl6ZWRfeWVhciA+PSAxNjAwLCBub3JtYWxpemVkX3llYXIgPD0gMTcwMCkgJT4lCiAgZmlsdGVyKG5jaGFyKG5vcm1hbGl6ZWRfeWVhcik9PTQpJT4lCiAgbGVmdF9qb2luKHZkMTdfbm9ybWFsaXplZF9sYW5nc19sb2NhbCwgYnkgPSBjKCJyZWNvcmRfbnVtYmVyIikpJT4lCiAgbGVmdF9qb2luKHZkMTdfZ2VucmVzX2xvY2FsLCBieSA9IGMoInJlY29yZF9udW1iZXIiKSklPiUKICBzZWxlY3QgKHJlY29yZF9udW1iZXIsbm9ybWFsaXplZF95ZWFyLHZkMTdfaWQsdGl0bGUsTWVtYmVyX251bWJlcl9uZXcsRmlyc3RfbmFtZV9uZXcsTGFzdF9uYW1lX25ldyxTb2NpZXR5X25hbWUsRXN0aW1hdGVkX2FkbWlzc2lvbl95ZWFyLEVzdGltYXRlZF9ET0QsR05ELHJvbGUyLGZpZWxkX2NvZGUsb3JpZ2luYWxfbGFuZ3VhZ2UsaW50ZXJtZWRpYXJ5X2xhbmd1YWdlLHB1YmxpY2F0aW9uX2xhbmd1YWdlLGdlbnJlKSU+JQogIGRpc3RpbmN0KCkKCiMgRmluZGluZyB0aGUgcmVjb3JkcyBvZiBvZiB0cmFuc2xhdGlvbnMgd2l0aCBrZXl3b3Jkcywgd2hpY2ggYXJlIG5vdCBhdmFpbGFibGUgaW4gRkJTIHRyYW5zbGF0aW9ucyAoYnkgb3JpZ2luYWwgbGFuZ3VhZ2UpLgpuZWVkZWRfdHJhbnNsYXRpb25fZmJzIDwtIHNwZWNpZmllZF90cmFuc2xhdGlvbl9mYnNbIXNwZWNpZmllZF90cmFuc2xhdGlvbl9mYnMkcmVjb3JkX251bWJlciAlaW4lIGZic190cmFuc2xhdGlvbiRyZWNvcmRfbnVtYmVyLCAsIGRyb3AgPSBGQUxTRV0KCgpuZWVkZWRfdHJhbnNsYXRpb25zX29mX2ZicyA8LSBnczRfY3JlYXRlKAogICJzaGVldHMtdHJhbnNsYXRpb25zX29mX2ZicyIsCiAgc2hlZXRzID0gbmVlZGVkX3RyYW5zbGF0aW9uX2ZicykKbmVlZGVkX3RyYW5zbGF0aW9uc19vZl9mYnMKYGBgCgojIEdlbnJlIG9mIEZCUyAobGlua3Mgb2YgaW50ZXJlc3QpIChmb3IgR2VybWFuIHRyYW5zbGF0aW9ucykuCiMgVGhlIGJlbG93IHdvcmRjbG91ZCBkZXBpY3RzIHRoZSBmcmVxdWVuY3kgb2YgZ2VucmVzIG9mIEZCUyB0cmFuc2xhdGlvbnMgZm9yIGxpbmtzIG9mIGludGVyZXN0LgpgYGB7cn0KbGlicmFyeSh3b3JkY2xvdWQpCmdlbnJlX3RyYW5zbGF0aW9uX2ZicyA8LSBmYnNfdHJhbnNsYXRpb24lPiUKICBmaWx0ZXIocHVibGljYXRpb25fbGFuZ3VhZ2U9PSJnZXIiKSU+JQogIHNlbGVjdChyZWNvcmRfbnVtYmVyLG5vcm1hbGl6ZWRfeWVhcixnZW5yZSklPiUKICBkaXN0aW5jdChyZWNvcmRfbnVtYmVyLG5vcm1hbGl6ZWRfeWVhcixnZW5yZSklPiUKICBuYS5vbWl0KHRyYW5zbGF0aW9uX2ZicyklPiUKICBncm91cF9ieShnZW5yZSkgJT4lCiAgY291bnQoZ2VucmUpJT4lCiAgYXJyYW5nZShkZXNjKG4pKQoKd29yZGNsb3VkKHdvcmRzID0gZ2VucmVfdHJhbnNsYXRpb25fZmJzJGdlbnJlLCBmcmVxID0gZ2VucmVfdHJhbnNsYXRpb25fZmJzJG4sIG1pbi5mcmVxID0gMSwKICAgICAgICAgIGNvbG9ycyA9IGJyZXdlci5wYWwoMjAsIlBhaXJlZCIpLCByYW5kb20ub3JkZXI9RkFMU0UsIHNjYWxlID0gYygxLCAwLjQpKQpgYGAKCiMgT3JpZ2luYWwgbGFuZ3VhZ2Ugb2YgRkJTIHRyYW5zbGF0aW9ucyAobGlua3Mgb2YgaW50ZXJlc3QpKEl0IGluY2x1ZGVzIGFsbCB0cmFuc2xhdGlvbnMgbm90IG9ubHkgR2VybWFuIG9uZSkuIAojIFRoZSBiZWxvdyB3b3JkY2xvdWQgZGVwaWN0cyB0aGUgZnJlcXVlbmN5IG9mIG9yaWdpbmFsX2xhbmd1YWdlIG9mIEZCUyB0cmFuc2xhdGlvbnMgZm9yIGxpbmtzIG9mIGludGVyZXN0LgpgYGB7cn0Kb19sYW5ndWFnZV90cmFuc2xhdGlvbl9mYnMgPC0gZmJzX3RyYW5zbGF0aW9uJT4lCiAgc2VsZWN0KHJlY29yZF9udW1iZXIsbm9ybWFsaXplZF95ZWFyLG9yaWdpbmFsX2xhbmd1YWdlKSU+JQogIGRpc3RpbmN0KHJlY29yZF9udW1iZXIsbm9ybWFsaXplZF95ZWFyLG9yaWdpbmFsX2xhbmd1YWdlKSU+JQogIG5hLm9taXQoZ2VyX3RyYW5zbGF0aW9uX2Zic19hbGwpJT4lCiAgZ3JvdXBfYnkob3JpZ2luYWxfbGFuZ3VhZ2UpICU+JQogIGNvdW50KG9yaWdpbmFsX2xhbmd1YWdlKSU+JQogIGFycmFuZ2UoZGVzYyhuKSkKCndvcmRjbG91ZCh3b3JkcyA9IG9fbGFuZ3VhZ2VfdHJhbnNsYXRpb25fZmJzJG9yaWdpbmFsX2xhbmd1YWdlLCBmcmVxID0gb19sYW5ndWFnZV90cmFuc2xhdGlvbl9mYnMkbiwgbWluLmZyZXEgPSAxLAogICAgICAgICAgY29sb3JzID0gYnJld2VyLnBhbCgyMCwiUGFpcmVkIiksIHJhbmRvbS5vcmRlcj1GQUxTRSwgc2NhbGUgPSBjKDEsIDAuNCkpCmBgYAojIFByaW1hcnkgYXV0aG9ycyBhbmQgVHJhbnNsYXRvcnMgb2YgRkJTIHRyYW5zbGF0aW9ucyAobGlua3Mgb2YgaW50ZXJlc3QpKEl0IGluY2x1ZGVzIGFsbCB0cmFuc2xhdGlvbnMgbm90IG9ubHkgR2VybWFuIG9uZSkuCmBgYHtyfQpwcmltYXJ5X2F1dGhvcnNfbGlua3Nfb2ZfaW50ZXJlc3RzIDwtIGZic190cmFuc2xhdGlvbiU+JSAKICBmaWx0ZXIoZmllbGRfY29kZT09IjAyOEEiKQoKcHJpbWFyeV9hdXRob3JzIDwtIGdzNF9jcmVhdGUoCiAgInNoZWV0cy1wcmltYXJ5X2F1dGhvcnNfdHJhbnNsYXRpb25zX2Zic19saW5rc19vZl9pbnRlcmVzdCIsCiAgc2hlZXRzID0gcHJpbWFyeV9hdXRob3JzX2xpbmtzX29mX2ludGVyZXN0cykKcHJpbWFyeV9hdXRob3JzCiAgICAKdHJhbnNsYXRvcnNfdHJhbnNsYXRpb25fbGlua3Nfb2ZfaW50ZXJlc3QgPC0gZmJzX3RyYW5zbGF0aW9uICU+JSAKICBmaWx0ZXIoZmllbGRfY29kZT09IjAyOEMiLChncmVwbChwYXN0ZShjKCLDnGJlcnMiKSwgY29sbGFwc2U9InwiKSwgcm9sZTIpfHJvbGUyICVpbiUoTkEpKSkgIAoKdHJhbnNsYXRvcnNfdHJhbnNsYXRpb24gPC0gZ3M0X2NyZWF0ZSgKICAic2hlZXRzLXRyYW5zbGF0b3JfdHJhbnNsYXRpb25zX2ZicyIsCiAgc2hlZXRzID0gdHJhbnNsYXRvcnNfdHJhbnNsYXRpb25fbGlua3Nfb2ZfaW50ZXJlc3QpCnRyYW5zbGF0b3JzX3RyYW5zbGF0aW9uCmBgYAoKIyBUcmFuc2xhdGVkIHZzIE5vbi1UcmFuc2xhdGVkIG1lbWJlciBwdWJsaWNhdGlvbnNfZmJzIChhbGwpLgojIFRoZSBiZWxvdyBwbG90IGRlcGljdHMgdGhlIFRyYW5zbGF0ZWQgdnMgTm9uLVRyYW5zbGF0ZWQgbWVtYmVyIHB1YmxpY2F0aW9ucyBvZiBGQlMuCmBgYHtyfQp0cmFuc192c19ub25fdHJhbnMgPC0gZmJzX2FsbF9saW5rc19sb2NhbCAlPiUKICBsZWZ0X2pvaW4odmQxN19ub3JtYWxpemVkX3llYXJzX2xvY2FsLCBieSA9IGMoInJlY29yZF9udW1iZXIiKSkgJT4lCiAgZmlsdGVyKG5vcm1hbGl6ZWRfeWVhciA+PSAxNjAwLCBub3JtYWxpemVkX3llYXIgPD0gMTcwMCkgJT4lCiAgZmlsdGVyKG5jaGFyKG5vcm1hbGl6ZWRfeWVhcik9PTQpJT4lCiAgbGVmdF9qb2luKHZkMTdfbm9ybWFsaXplZF9sYW5nc19sb2NhbCwgYnkgPSBjKCJyZWNvcmRfbnVtYmVyIikpJT4lCiAgc2VsZWN0IChyZWNvcmRfbnVtYmVyLG5vcm1hbGl6ZWRfeWVhcix2ZDE3X2lkLHRpdGxlLE1lbWJlcl9udW1iZXJfbmV3LEZpcnN0X25hbWVfbmV3LExhc3RfbmFtZV9uZXcsU29jaWV0eV9uYW1lLEVzdGltYXRlZF9hZG1pc3Npb25feWVhcixFc3RpbWF0ZWRfRE9ELEdORCxyb2xlMixmaWVsZF9jb2RlLG9yaWdpbmFsX2xhbmd1YWdlLHB1YmxpY2F0aW9uX2xhbmd1YWdlKQoKCnRyYW5zX3ZzX25vbl90cmFucyR0eXBlIDwtIGlzLm5hKHRyYW5zX3ZzX25vbl90cmFucyRvcmlnaW5hbF9sYW5ndWFnZSkKCnRyYW5zX3ZzX25vbl90cmFucyR0eXBlW3RyYW5zX3ZzX25vbl90cmFucyR0eXBlID09ICJGQUxTRSJdIDwtICJUcmFuc2xhdGVkIgp0cmFuc192c19ub25fdHJhbnMkdHlwZVt0cmFuc192c19ub25fdHJhbnMkdHlwZSA9PSAiVFJVRSJdIDwtICJOb24tVHJhbnNsYXRlZCIKCnRyYW5zbGF0ZWRfdnNfbm9uX3RyYW5zbGF0ZWQgPC0gZ3M0X2NyZWF0ZSgKICAic2hlZXRzLXRyYW5zbGF0ZWRfdnNfbm9uX3RyYW5zbGF0ZWRfZmJzIiwKICBzaGVldHMgPSB0cmFuc192c19ub25fdHJhbnMpCnRyYW5zbGF0ZWRfdnNfbm9uX3RyYW5zbGF0ZWQKCnRyYW5zX3ZzX25vbl90cmFucyU+JQpkaXN0aW5jdChyZWNvcmRfbnVtYmVyLG5vcm1hbGl6ZWRfeWVhcix0eXBlKSU+JQpzZWxlY3Qobm9ybWFsaXplZF95ZWFyLHR5cGUpJT4lCmdyb3VwX2J5KG5vcm1hbGl6ZWRfeWVhciklPiUKY291bnQodHlwZSklPiUKYXJyYW5nZShkZXNjKG4pKSU+JQpnZ3Bsb3QoYWVzKHg9bm9ybWFsaXplZF95ZWFyLHk9biwgZmlsbD10eXBlKSkgKyAKZ2VvbV9jb2woKSsKbGFicyh5ID0gIlRyYW5zbGF0ZWQgdnMgTm9uLVRyYW5zbGF0ZWQgRkJTIiwgeD0gIlllYXJzIikrCnNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMTAwMCwgMjAwMCwgYnkgPSA1KSkrCnRoZW1lX2hzY2lfZGlzY3JldGUoKSsKdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTkwLGhqdXN0PTEsdmp1c3Q9MC41KSkrCnRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwKICAgICAgICBsZWdlbmQua2V5LndpZHRoPXVuaXQoMC4xNSwgImNtIikpKwpnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIGNvbG9yID0gImdyZWVuIiwgc2l6ZSA9IDEuOCwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuOSkpIApgYGAKIyBUcmFuc2xhdGVkIHZzIE5vbi1UcmFuc2xhdGVkIG1lbWJlciBwdWJsaWNhdGlvbnNfZmJzIChhbGwpIChQZXJjZW50YWdlIGJ5IHllYXIpLgpgYGB7cn0KdHJhbnNfbm9uX3RyYW5zX3BlcmNlbnRhZ2UgPC0gdHJhbnNfdnNfbm9uX3RyYW5zJT4lCiAgZGlzdGluY3QocmVjb3JkX251bWJlcixub3JtYWxpemVkX3llYXIsdHlwZSklPiUKICBzZWxlY3Qobm9ybWFsaXplZF95ZWFyLHR5cGUpJT4lCiAgbXV0YXRlKHR5cGUgPSBmYWN0b3IodHlwZSkpICU+JQogIGNvdW50KG5vcm1hbGl6ZWRfeWVhciwgdHlwZSwgLmRyb3AgPSBGQUxTRSwgbmFtZSA9ICdQZXJjZW50YWdlJykgJT4lCiAgZ3JvdXBfYnkobm9ybWFsaXplZF95ZWFyKSAlPiUKICBtdXRhdGUoUGVyY2VudGFnZSA9IHJvdW5kKFBlcmNlbnRhZ2Uvc3VtKFBlcmNlbnRhZ2UpICogMTAwKSwyKQoKdHJhbnNsYXRlZF9ub25fdHJhbnNsYXRlZF9wZXJjZW50YWdlIDwtIGdzNF9jcmVhdGUoCiAgInNoZWV0cy10cmFuc2xhdGVkX25vbl90cmFuc2xhdGVkX3BlcmNlbnRhZ2VfZmJzIiwKICBzaGVldHMgPSB0cmFuc19ub25fdHJhbnNfcGVyY2VudGFnZSkKdHJhbnNsYXRlZF9ub25fdHJhbnNsYXRlZF9wZXJjZW50YWdlCmBgYAoKIyBUcmFuc2xhdGVkIHZzIE5vbi1UcmFuc2xhdGVkIG1lbWJlciBwdWJsaWNhdGlvbnNfZmJzIChhbGwpIChQZXJjZW50YWdlIGJ5IHdob2xlKS4KYGBge3J9CnByaW50KGMoIlRyYW5zbGF0ZWQiLHJvdW5kKHN1bSh0cmFuc192c19ub25fdHJhbnMkdHlwZT09IlRyYW5zbGF0ZWQiKS9sZW5ndGgodHJhbnNfdnNfbm9uX3RyYW5zJHR5cGUpKjEwMCwyKSkpCnByaW50KGMoIk5vbi1UcmFuc2xhdGVkIixyb3VuZChzdW0odHJhbnNfdnNfbm9uX3RyYW5zJHR5cGU9PSJOb24tVHJhbnNsYXRlZCIpL2xlbmd0aCh0cmFuc192c19ub25fdHJhbnMkdHlwZSkqMTAwLDIpKSkKYGBg