1 - Methods

1.1 - State of analytical code in ecology

We randomly sampled articles published in ecological journals for which code-sharing has been either mandatory or encouraged since June 2015 at the latest. Sampling within these journals maximizes the code available for quality assessment (see below), and also helps us to understand where other ecological journals will likely be in the near future, as code archiving policies proliferate (Stodden, Guo, and Ma 2013). The sample of journals was obtained from Mislan et al. (2016), who identified 14 out of 96 (15%) ecological journals with mandatory or encouraging code-sharing policies in place since at least the 1st of June 2015 (Table S3). We sampled all the articles published in these 14 journals using the Web of Science Core Collection (search performed at the Netherlands Institute of Ecology) for two distinct temporal periods: 1st of June 2015 to 9th of December 2016 (2015/16 dataset, N= 4,366 records), and 1st of January 2018 to 21st of May 2019 (2018/19 dataset, N=4,291). A random sample of 200 articles from each period was then selected using the function “sample” in R v. 3.3.2 (R Core Team 2018).

For each of the 400 articles, we determined whether the article was relevant to our survey by screening all titles and abstracts using the software Rayyan (Ouzzani et al. 2016). Reviews, opinion pieces, and commentaries were excluded, whereas articles that conducted some kind of statistical analysis and/or simulations were kept for further screening. All the articles were double screened at this stage (2015/16 by AC and IvB; and 2018/19 by AST and SE). As a result, 195 of the 200 articles in 2015/16 dataset, and 187 of the 200 articles in 2018/19 dataset were kept for further evaluation. The full list of these articles, with the results of the screening is provided (see file data/code_availability_full_and_clean.csv).

In the next steps (summarized in Figure S1) AC evaluated 195 articles from 2015/16, and AST evaluated 187 articles from 2018/19. First, each article was read in detail to determine if it was a purely bioinformatical (i.e. molecular) study with solely bioinformatical analyses. Only studies that conducted at least some statistical analyses other than bioinformatics (including simulations) were considered further (hereafter referred to as ‘non-molecular’). These non-molecular articles (172 in 2015/16; 174 in 2018/19) were then evaluated based on the following (and as shown in Figure S1):

  1. Was the analytical code published? (‘yes’, ‘no’, ‘some’). This was done by checking both the article’s main text, data accessibly statements, and the supplementary materials, including archived data, if any. If no code (‘code’, ‘script’, ‘syntax’) was mentioned in any of these sections, then all links to archived data, and all supplementary materials were searched.

  2. What software was used in the analysis? (e.g. R, Python, SAS…)

  3. Were there data used in the analysis (‘yes’, ‘no’)? If yes, were the data published (‘yes’, ‘no’, ‘some’)?

For those articles that had published seemingly all or at least some of their code (40 in 2015/16; 52 in 2018/19), we evaluated the following:

  1. Where was the code published (‘repository’, ‘supplementary material’, ‘version control platform’, ‘webpage’)?

  2. Was the existence of code clearly mentioned (‘yes’, ‘no’), and if so, how (‘code’, ‘script’, ‘other’)?

  3. Where was the reference to the code made, if at all (‘methods section’, ‘data accessibility statement’, ‘supplementary material’, ‘other’)?

  4. Did the code include some kind of documentation such as README or HowTo files (‘yes’, ‘no’ or ‘with some comments’)?

  5. Were there inline comments within the code (‘yes’, ‘no’)?

Figure S1. Diagram of number of studies for each category.

Figure S1. Diagram of number of studies for each category.

To ensure data reliability, we randomly selected and double-checked data extraction (two observers: AST and AC) for 16% of all the articles that had passed the title-and-abstract screening (29 out of 195 articles from 2015/16, and 32 out of 187 from 2018/19 dataset). The decision overlap between observers was very high (please see file data/code_availability_full_and_clean.csv for changes and explanations made to the table after the double screening). Some additional articles were further intentionally double-checked whenever the original screener was not sure about the assignment of some scores (42 articles) or when the original screener could not find any reference to the software used for the analyses (34 articles; more details in file data/code_availability_full_and_clean.csv).

1.2 - Journals’ code-sharing policies

We explored if the number of ecological journals with code-sharing policies has increased since 2015, when only 14 out of 96 (15%) had code-sharing policies (Mislan, Heer, and White 2016). In March 2020 we investigated the code-sharing policies for all the 96 ecological journals identified by Mislan et al. [(2016); Table S3]. One observer (AC) read the ‘Authors Instructions’ and ‘Editorial Policies’ of each journal, and a second observer (AST) did so but only for the 14 journals reviewed in this study and for those journals scored as ‘No’ (see below) by the first observer - unclear cases were discussed together. If none of these sections explicitly mentioned data and/or code, we also checked other sections of the journal’s website, whenever possible. Based on the information collected, we scored the journals’ code-sharing policies as: ‘encouraged’ (publication of the code is explicitly encouraged, but not required), ‘mandatory’ (code must be published together with the article), or ‘encouraged/mandatory’ (when the wording made it difficult to judge if code publication is encouraged or required). If a journal did not explicitly encourage code-sharing (i.e. even when it mentioned research artefacts, but not ‘code’ or ‘script’ explicitly: 10 out of 96, 10%), the journal’s code-sharing policy was scored as ‘No’ (i.e. code-sharing is not mentioned explicitly; see comments in file data/Updated_Table_Mislan_2020_v2.xlsx).

Table S1. List of 96 ecological journals and their code-sharing policies in June 2015 (Mislan, Heer, and White 2016) and in March 2020 (this study).

# printing Table S1
journal.policies %>% select(Full.Journal.Title,Require.computer.code.with.publication_2015,Require.computer.code.with.publication_2020) %>%
  rename(Journal=Full.Journal.Title,'Code-sharing policy 2015'=Require.computer.code.with.publication_2015,'Code-sharing policy 2020'=Require.computer.code.with.publication_2020) %>% arrange(Journal) %>%
  kable("html") %>% kable_styling() %>%
  scroll_box(width = "100%", height = "500px")
Journal Code-sharing policy 2015 Code-sharing policy 2020
Acta Oecologica-International Journal of Ecology No Encouraged
Agriculture Ecosystems & Environment No Encouraged
American Naturalist Yes Encouraged
Animal Conservation No Encouraged/Mandatory
Annual Review of Ecology Evolution and Systematics No No
Applied Vegetation Science No Encouraged/Mandatory
Aquatic Ecology No Encouraged
Aquatic Microbial Ecology No No
Austral Ecology No Encouraged
Basic and Applied Ecology No No
Behavioral Ecology No No
Behavioral Ecology and Sociobiology No No
Biodiversity and Conservation No Encouraged
Biogeosciences No Encouraged
Biological Conservation No Encouraged
Biological Invasions No Encouraged
Biology Letters No Mandatory
Biotropica No Encouraged
Chemoecology No Encouraged
Community Ecology No Encouraged
Conservation Biology No Encouraged
Diversity and Distributions No Encouraged/Mandatory
Ecography No Mandatory
Ecohydrology No Encouraged
Ecological Applications Yes Mandatory
Ecological Complexity No Encouraged
Ecological Economics No Encouraged
Ecological Engineering No Encouraged
Ecological Informatics No Encouraged
Ecological Modelling No Encouraged
Ecological Monographs Yes Mandatory
Ecological Research No Encouraged
Ecology Yes Mandatory
Ecology and Evolution No No
Ecology and Society No Mandatory
Ecology Letters No Encouraged/Mandatory
Ecosphere Yes Mandatory
Ecosystems No No
Ecotoxicology No Encouraged
Environmental Biology of Fishes No Encouraged
European Journal of Soil Biology No Encouraged
European Journal of Wildlife Research No Encouraged
Evolution No Mandatory
Evolutionary Ecology No Encouraged
Flora No Encouraged
Freshwater Science No No
Frontiers in Ecology and the Environment No No
Functional Ecology Yes Encouraged/Mandatory
Fungal Ecology No Encouraged
Global Change Biology No No
Global Ecology and Biogeography No Encouraged/Mandatory
Heredity Yes Encouraged/Mandatory
International Journal of Sustainable Development and World Ecology No No
ISME Journal No Encouraged
Journal for Nature Conservation No Encouraged
Journal of Animal Ecology Yes Encouraged/Mandatory
Journal of Applied Ecology Yes Encouraged/Mandatory
Journal of Arid Environments No Encouraged
Journal of Biogeography No Encouraged/Mandatory
Journal of Ecology Yes Encouraged/Mandatory
Journal of Evolutionary Biology No Mandatory
Journal of Experimental Marine Biology and Ecology No Encouraged
Journal of Plant Ecology No No
Journal of Soil and Water Conservation No No
Journal of the North American Benthological Society No No
Journal of Tropical Ecology No Encouraged
Journal of Vegetation Science No Encouraged/Mandatory
Journal of Wildlife Management No Encouraged
Landscape and Urban Planning No Encouraged
Landscape Ecology No No
Marine Ecology Progress Series No No
Methods in Ecology and Evolution Yes Encouraged/Mandatory
Microbial Ecology No No
Molecular Ecology Yes Encouraged
Molecular Ecology Resources Yes Encouraged
Oecologia No No
Oikos No No
Oryx No No
Paleobiology No No
Pedobiologia No Encouraged
Perspectives in Plant Ecology Evolution and Systematics No Encouraged
Plant Ecology No Encouraged
Plant Species Biology No Encouraged
Polar Biology No Encouraged
Polar Research No No
Population Ecology No Encouraged
Proceedings of the Royal Society B-Biological Sciences Yes Mandatory
Rangeland Ecology & Management No Encouraged
Restoration Ecology No Encouraged
Theoretical Ecology No Encouraged
Theoretical Population Biology No Encouraged
Trends in Ecology & Evolution No No
Urban Ecosystems No Encouraged
Wetlands No Encouraged
Wildlife Monographs No Encouraged
Wildlife Research No No

2 - Results

2.1 - Percentages calculations

# number of eligible articles
eligible.articles.code <- as.numeric(data.full %>% 
                                       filter(!(is.na(statistical.analysis.and.or.simulations.2))) %>% 
                                       summarise(eligible_articles = sum(statistical.analysis.and.or.simulations.2 == "yes")))

# number of eligible articles
eligible.articles.code.year <- data.full %>% 
  filter(!(is.na(statistical.analysis.and.or.simulations.2))) %>% 
  group_by(Publication_year.2) %>% 
  summarise(eligible_articles = sum(statistical.analysis.and.or.simulations.2 == "yes"))

# number of articles that published at least some code
at.least.some.code <- as.numeric(data.full %>% 
                                   filter(!(is.na(CodePublished.3))) %>% 
                                   summarise(code_published = sum(CodePublished.3 == "yes")))

# number of articles per year that published at least some code
at.least.some.code.year <- data.full %>% 
  filter(!(is.na(CodePublished.3))) %>% 
  group_by(Publication_year.2) %>% 
  summarise(code_published = sum(CodePublished.3 == "yes"))

# number of articles that published seemingly all code
seemingly.all.code <- as.numeric(data.full %>% 
                                   filter(!(is.na(CodePublished.2))) %>% 
                                   summarise(code_published = sum(CodePublished.2 == "yes")))

# number of articles that published only somecode
only.some.code <- as.numeric(data.full %>% 
                               filter(!(is.na(CodePublished.2))) %>% 
                               summarise(code_published = sum(CodePublished.2 == "some")))

# number of eligible articles that used data
eligible.articles.data <- as.numeric(data.full %>% 
                                       filter(!(is.na(statistical.analysis.and.or.simulations.2)) & !(is.na(DataUsed))) %>% 
                                       summarise(eligible_articles = sum(statistical.analysis.and.or.simulations.2 == "yes" & DataUsed == "yes")))

# number of articles that published at least some data
at.least.some.data <- as.numeric(data.full %>% 
                                   filter(!(is.na(DataShared.3))) %>% 
                                   summarise(data_published = sum(DataShared.3 == "yes")))

# number of articles that published seemingly all code and data (if any used)
seemingly.all.code.and.data <- as.numeric(data.full %>% 
                                            filter(!(is.na(CodePublished.2))) %>% 
                                            summarise(code_and_data_published = sum(CodePublished.2 == "yes" & (DataShared.2 == "yes" | is.na(DataShared.2)))))

# number of articles that published seemingly all code and data (if any used)
seemingly.all.code.and.data.year <-data.full %>% 
  filter(!(is.na(CodePublished.2))) %>% 
  group_by(Publication_year.2) %>% 
  summarise(code_and_data_published = sum(CodePublished.2 == "yes" & (DataShared.2 == "yes" | is.na(DataShared.2))))


# number of journals with some type of code-sharing policy in 2015
journals.with.policy.2015 <- as.numeric(table(journal.policies$Require.computer.code.with.publication_2015)['Yes'])

# number of journals reviewed in 2015
journals.2015 <- nrow(journal.policies)

# number of journals with some type of code-sharing policy in 2020
journals.with.policy.2020 <- nrow(journal.policies[!(is.na(journal.policies$Require.computer.code.with.publication_2020)) & 
                                                     journal.policies$Require.computer.code.with.publication_2020!="No",])

# number of journals reviewed in 2015 that were still active in 2020
journals.2020 <- nrow(journal.policies[!(is.na(journal.policies$Require.computer.code.with.publication_2020)),])

# # number of journals covered each year
# number.journals.covered <- as.data.frame(data.full %>% group_by(Publication_year.2,Journal) %>% summarise(count = n_distinct(CodePublished.2)) %>% summarise(n = n()))

# counting number of articles per journal
articles.per.journal <- as.data.frame(data.full %>% group_by(Journal) %>% summarise(total = n()))

# counting number of articles with at least some code per journal
code.published.per.journal <- as.data.frame(data.full %>% filter(CodePublished.3=="yes") %>% group_by(Journal) %>% summarise(codepublished = n()))

# merging dataframes together
full.journal <- merge(code.published.per.journal,articles.per.journal)
full.journal$percentage <- round((full.journal$codepublished/full.journal$total)*100,0)

# saving journal percentages information to be used in script 004_plotting.R
write.csv(full.journal,"data/journal_percentages.csv",row.names=FALSE)

# number of articles mentioning that code was published
code.mentioned <- as.numeric(table(data.full$CodeMentioned.2)["yes"])

# number of articles not mentioning that code was published
code.not.mentioned <- as.numeric(table(data.full$CodeMentioned.2)["no"])

# number of articles mentioning that code was published
code.mentioned.code.script <- as.numeric(sum(table(data.full$CodeMentioned)["yes, code"],
                                             table(data.full$CodeMentioned)["yes, code and script"],
                                             table(data.full$CodeMentioned)["yes, script"]))

# number of articles mentioning code availability in the data accessibility and/or materials and methods
code.mentioned.section.dataacc.methods <- as.numeric(sum(table(data.full$Location_CodeMentioned)["dataaccessibility"],
                                                         table(data.full$Location_CodeMentioned)["dataaccessibility and methods"],
                                                         table(data.full$Location_CodeMentioned)["dataaccessibility and methods and supplement"],
                                                         table(data.full$Location_CodeMentioned)["dataaccessibility and supplement"],
                                                         table(data.full$Location_CodeMentioned)["methods"],
                                                         table(data.full$Location_CodeMentioned)["methods and supplement"]))

# number of articles mentioning code availability only in the supplements
code.mentioned.section.supplements <- as.numeric(sum(table(data.full$Location_CodeMentioned)["supplement"],
                                                     table(data.full$Location_CodeMentioned)["supplementary files descriptions"]))

# number of articles using permanent repositories to host their data
code.hosted.repository <- as.numeric(table(data.full$LocationShared.2)["repository"])-as.numeric(table(data.full$LocationShared)["version control platform"])

# number of articles using only non-permanent repositories (i.e. version controlled  plaform = GitHub)to host their data
code.hosted.github.only <- as.numeric(table(data.full$LocationShared)["version control platform"])

# number of articles using repositories to host their data in 2015/2016
code.hosted.repository.2015.16 <- as.numeric(table(data.full[data.full$Publication_year<2018,"LocationShared.2"])["repository"])

# number of articles using repositories to host their data in 2018/2019
code.hosted.repository.2018.19 <- as.numeric(table(data.full[data.full$Publication_year>2016,"LocationShared.2"])["repository"])

# number of articles using only the supplements to host their data
code.hosted.supplements <- as.numeric(table(data.full$LocationShared.2)["supplementary file"])

# number of articles using exclusively free software
free.software <- as.numeric(table(data.full$FreeSoftware)["yes"])

# number of articles using R in combination with other software
R.and.others <- as.numeric(table(str_detect(data.full$Stat_analysis_software, "R "))["TRUE"])

# number of articles using only R
R.only <- nrow(data.full[data.full$Stat_analysis_software=="R" & !(is.na(data.full$Stat_analysis_software)),])

# number of articles reporting the software used
eligible.articles.code.reporting.software.used <- as.numeric(data.full %>% 
                                                               filter(!(is.na(statistical.analysis.and.or.simulations.2))) %>% 
                                                               summarise(eligible_articles = sum(statistical.analysis.and.or.simulations.2 == "yes" & Stat_analysis_software != "Not Stated")))

# number of articles reporting the software used
eligible.articles.code.not.reporting.software.used <- as.numeric(data.full %>% 
                                                                   filter(!(is.na(statistical.analysis.and.or.simulations.2))) %>% 
                                                                   summarise(eligible_articles = sum(statistical.analysis.and.or.simulations.2 == "yes" & Stat_analysis_software == "Not Stated")))

# creating vectors to build the data frame with

# vector with a name for each percentage
all.names <- c("articles sharing at least some code",
               "articles sharing at least some data",
               "journals with code-sharing policies in 2015",
               "journals with code-sharing policies in 2020",
               "articles sharing seemingly all code",
               "articles sharing only some code",
               "articles sharing at least some code in 2015/2016",
               "articles sharing at least some code in 2018/2019",
               "articles sharing at least some code per journal (min)",
               "articles sharing at least some code per journal (max)",
               "articles sharing at least some code per journal (median)",
               "articles sharing at least some code per journal (mean)",
               "articles sharing at least some code and highlighting code availability",
               "articles sharing at least some code and highlighting code availability using code and/or script",
               "articles sharing at least some code and highlighting code availability in data accessibility and/or methods section",
               "articles sharing at least some code and highlighting code availability only in the supplements",
               "articles sharing at least some code and not highlighting code availability",
               "articles sharing at least some code and hosting it in a permanent repository",
               "articles sharing at least some code and hosting it in GitHub only",
               "articles sharing at least some code and hosting it only in the supplements",
               "articles sharing at least some code and hosting it in a repository in 2015/2016",
               "articles sharing at least some code and hosting it in a repository in 2018/2019",
               "articles with the potential to be computationally reproducible",
               "articles with the potential to be computationally reproducible in 2015/2016",
               "articles with the potential to be computationally reproducible in 2018/2019",
               "articles using free (non-proprietary) software",
               "articles using R",
               "articles not reporting the software used")

# vector with all percentages
all.percentages <- round(
  c((at.least.some.code/eligible.articles.code)*100,
    (at.least.some.data/eligible.articles.data)*100,
    (journals.with.policy.2015/journals.2015)*100,
    (journals.with.policy.2020/journals.2020)*100,
    (seemingly.all.code/eligible.articles.code)*100,
    (only.some.code/eligible.articles.code)*100,
    (at.least.some.code.year$code_published[1]/eligible.articles.code.year$eligible_articles[1])*100,
    (at.least.some.code.year$code_published[2]/eligible.articles.code.year$eligible_articles[2])*100,
    as.numeric(summary(full.journal$percentage)["Min."]),
    as.numeric(summary(full.journal$percentage)["Max."]),
    as.numeric(summary(full.journal$percentage)["Median"]),
    as.numeric(summary(full.journal$percentage)["Mean"]),
    (code.mentioned/at.least.some.code)*100,
    (code.mentioned.code.script/code.mentioned)*100,
    (code.mentioned.section.dataacc.methods/code.mentioned)*100,
    (code.mentioned.section.supplements/code.mentioned)*100,
    (code.not.mentioned/at.least.some.code)*100,
    (code.hosted.repository/at.least.some.code)*100,
    (code.hosted.github.only/at.least.some.code)*100,
    (code.hosted.supplements/at.least.some.code)*100,
    (code.hosted.repository.2015.16/at.least.some.code.year$code_published[1])*100,
    (code.hosted.repository.2018.19/at.least.some.code.year$code_published[2])*100,
    (seemingly.all.code.and.data/eligible.articles.code)*100,
    (seemingly.all.code.and.data.year$code_and_data_published[1]/eligible.articles.code.year$eligible_articles[1])*100,
    (seemingly.all.code.and.data.year$code_and_data_published[2]/eligible.articles.code.year$eligible_articles[2])*100,
    (free.software/eligible.articles.code.reporting.software.used)*100,
    ((R.and.others+R.only)/eligible.articles.code.reporting.software.used)*100,
    (eligible.articles.code.not.reporting.software.used/eligible.articles.code)*100),0)

# vector with all numerators for calculating the percentage
all.numerators <- c("#eligible articles sharing at least some code",
                    "#eligible articles sharing at least some data",
                    "#journals with code-sharing policies in 2015",
                    "#journals with code-sharing policies in 2020",
                    "#eligible articles sharing seemingly all code",
                    "#eligible articles sharing only some code",
                    "#eligible articles sharing at least some code in 2015/2016",
                    "#eligible articles sharing at least some code in 2018/2019",
                    "#eligible articles per journal sharing at least some code",
                    "#eligible articles per journal sharing at least some code",
                    "#eligible articles per journal sharing at least some code",
                    "#eligible articles per journal sharing at least some code",
                    "#eligible articles sharing at least some code that highlighted code availability",
                    "#eligible articles sharing at least some code that highlighted code availability using code and/or script",
                    "#eligible articles sharing at least some code that highlighted code availability in data accessibility and/or methods section",
                    "#eligible articles sharing at least some code that highlighted code availability only in the supplements",
                    "#eligible articles sharing at least some code that did not highlighted code availability",
                    "#eligible articles sharing at least some code and hosting it in a repository",
                    "#eligible articles sharing at least some code and hosting it in GitHub only",
                    "#eligible articles sharing at least some code and hosting it only in the supplements",
                    "#eligible articles sharing at least some code and hosting it in a repository or GitHub only in 2015/2016",
                    "#eligible articles sharing at least some code and hosting it in a repository or GitHub only in 2018/2019",
                    "#eligible articles sharing seemingly all code and data (if any used)",
                    "#eligible articles with the potential to be computationally reproducible in 2015/2016",
                    "#eligible articles with the potential to be computationally reproducible in 2018/2019",
                    "#eligible articles using free (non-proprietary) software",
                    "#eligible articles using R alone or together with other software",
                    "#eligible articles not reporting the software used")

# vector with all denominators for calculating the percentage
all.denominators <- c("#eligible articles",
                      "#eligible articles that used data",
                      "#journals reviewed in 2015",
                      "#journals reviewed and still existing in 2020",
                      "#eligible articles",
                      "#eligible articles",
                      "#eligible articles in 2015/2016",
                      "#eligible articles in 2018/2019",
                      "#eligible articles per journal",
                      "#eligible articles per journal",
                      "#eligible articles per journal",
                      "#eligible articles per journal",
                      "#eligible articles sharing at least some code",
                      "#eligible articles sharing at least some code that highlighted code availability",
                      "#eligible articles sharing at least some code that highlighted code availability",
                      "#eligible articles sharing at least some code that highlighted code availability",
                      "#eligible articles sharing at least some code",
                      "#eligible articles sharing at least some code",
                      "#eligible articles sharing at least some code",
                      "#eligible articles sharing at least some code",
                      "#eligible articles sharing at least some code in 2015/2016",
                      "#eligible articles sharing at least some code in 2018/2019",
                      "#eligible articles",
                      "#eligible articles in 2015/2016",
                      "#eligible articles in 2018/2019",
                      "#eligible articles reporting software used",
                      "#eligible articles reporting software used",
                      "#eligible articles")

# putting together tableS2 and renaming columns
tableS2 <- as.data.frame(cbind(all.names,all.percentages,all.numerators,all.denominators))
names(tableS2) <- c("Name","%","Numerator","Denominator")

Table S2. List of all percentages that we calculated from our data, and presented in the main manuscript, and how they were calculated to avoid any misunderstanding. Values sorted by the order of appearance in the main manuscript (including the abstract).

# printing Table S2
tableS2 %>% kable("html") %>% kable_styling() %>% scroll_box(width = "100%", height = "500px")
Name % Numerator Denominator
articles sharing at least some code 27 #eligible articles sharing at least some code #eligible articles
articles sharing at least some data 79 #eligible articles sharing at least some data #eligible articles that used data
journals with code-sharing policies in 2015 15 #journals with code-sharing policies in 2015 #journals reviewed in 2015
journals with code-sharing policies in 2020 75 #journals with code-sharing policies in 2020 #journals reviewed and still existing in 2020
articles sharing seemingly all code 22 #eligible articles sharing seemingly all code #eligible articles
articles sharing only some code 5 #eligible articles sharing only some code #eligible articles
articles sharing at least some code in 2015/2016 23 #eligible articles sharing at least some code in 2015/2016 #eligible articles in 2015/2016
articles sharing at least some code in 2018/2019 30 #eligible articles sharing at least some code in 2018/2019 #eligible articles in 2018/2019
articles sharing at least some code per journal (min) 7 #eligible articles per journal sharing at least some code #eligible articles per journal
articles sharing at least some code per journal (max) 53 #eligible articles per journal sharing at least some code #eligible articles per journal
articles sharing at least some code per journal (median) 22 #eligible articles per journal sharing at least some code #eligible articles per journal
articles sharing at least some code per journal (mean) 25 #eligible articles per journal sharing at least some code #eligible articles per journal
articles sharing at least some code and highlighting code availability 76 #eligible articles sharing at least some code that highlighted code availability #eligible articles sharing at least some code
articles sharing at least some code and highlighting code availability using code and/or script 96 #eligible articles sharing at least some code that highlighted code availability using code and/or script #eligible articles sharing at least some code that highlighted code availability
articles sharing at least some code and highlighting code availability in data accessibility and/or methods section 94 #eligible articles sharing at least some code that highlighted code availability in data accessibility and/or methods section #eligible articles sharing at least some code that highlighted code availability
articles sharing at least some code and highlighting code availability only in the supplements 4 #eligible articles sharing at least some code that highlighted code availability only in the supplements #eligible articles sharing at least some code that highlighted code availability
articles sharing at least some code and not highlighting code availability 24 #eligible articles sharing at least some code that did not highlighted code availability #eligible articles sharing at least some code
articles sharing at least some code and hosting it in a permanent repository 51 #eligible articles sharing at least some code and hosting it in a repository #eligible articles sharing at least some code
articles sharing at least some code and hosting it in GitHub only 12 #eligible articles sharing at least some code and hosting it in GitHub only #eligible articles sharing at least some code
articles sharing at least some code and hosting it only in the supplements 34 #eligible articles sharing at least some code and hosting it only in the supplements #eligible articles sharing at least some code
articles sharing at least some code and hosting it in a repository in 2015/2016 52 #eligible articles sharing at least some code and hosting it in a repository or GitHub only in 2015/2016 #eligible articles sharing at least some code in 2015/2016
articles sharing at least some code and hosting it in a repository in 2018/2019 71 #eligible articles sharing at least some code and hosting it in a repository or GitHub only in 2018/2019 #eligible articles sharing at least some code in 2018/2019
articles with the potential to be computationally reproducible 21 #eligible articles sharing seemingly all code and data (if any used) #eligible articles
articles with the potential to be computationally reproducible in 2015/2016 20 #eligible articles with the potential to be computationally reproducible in 2015/2016 #eligible articles in 2015/2016
articles with the potential to be computationally reproducible in 2018/2019 21 #eligible articles with the potential to be computationally reproducible in 2018/2019 #eligible articles in 2018/2019
articles using free (non-proprietary) software 74 #eligible articles using free (non-proprietary) software #eligible articles reporting software used
articles using R 79 #eligible articles using R alone or together with other software #eligible articles reporting software used
articles not reporting the software used 10 #eligible articles not reporting the software used #eligible articles

2.2 - Journals’ code-sharing compliance

Table S3. List of 14 ecological journals reviewed in this study and their code-sharing policies (updated in March 2020), number of articles we reviewed, number of articles sharing at least some code, and the percentage of articles sharing at least some code (see also Figure 2 in the main text).

# import journal information and abbreviations
journal.info <- read.table("data/journals_info_v2.csv",header=T,sep=",")

# merging journal info to percentages
full.journal.info <- merge(full.journal,journal.info)

# removing full capitalization of journal names using the following function
# which was obtained from: https://stackoverflow.com/questions/6364783/capitalize-the-first-letter-of-both-words-in-a-two-word-string
simpleCap <- function(x) {
  s <- strsplit(x, " ")[[1]]
  paste(toupper(substring(s, 1,1)), substring(s, 2),
        sep="", collapse=" ")
}

full.journal.info$Journal<- sapply(tolower(full.journal.info$Journal),simpleCap)

full.journal.info$Journal <- ifelse(full.journal.info$Journal=="Proceedings Of The Royal Society B-biological Sciences",
                                    "Proceedings Of The Royal Society B-Biological Sciences",
                                    full.journal.info$Journal)

# printing table S3
full.journal.info %>% select(Journal,Policy,total,codepublished,percentage) %>% rename('Code-sharing policy'=Policy,'#articles reviewed'=total,'#articles sharing code'=codepublished, '% articles sharing code'=percentage) %>% arrange(Journal) %>% kable("html") %>% kable_styling() %>% scroll_box(width = "100%", height = "500px")
Journal Code-sharing policy #articles reviewed #articles sharing code % articles sharing code
American Naturalist Encouraged 24 7 29
Ecological Applications Mandatory 14 2 14
Ecological Monographs Mandatory 6 3 50
Ecology Mandatory 32 5 16
Ecosphere Mandatory 44 6 14
Functional Ecology Encouraged/Mandatory 28 2 7
Heredity Encouraged/Mandatory 21 6 29
Journal Of Animal Ecology Encouraged/Mandatory 21 5 24
Journal Of Applied Ecology Encouraged/Mandatory 27 5 19
Journal Of Ecology Encouraged/Mandatory 21 3 14
Methods In Ecology And Evolution Encouraged/Mandatory 19 10 53
Molecular Ecology Encouraged 48 18 38
Molecular Ecology Resources Encouraged 18 4 22
Proceedings Of The Royal Society B-Biological Sciences Mandatory 77 16 21

R Session Information

R session information detailing the versions and packages used in this script for reproducibility purposes.

sessionInfo() %>% pander()

R version 3.5.1 (2018-07-02)

Platform: x86_64-w64-mingw32/x64 (64-bit)

locale: LC_COLLATE=English_United States.1252, LC_CTYPE=English_United States.1252, LC_MONETARY=English_United States.1252, LC_NUMERIC=C and LC_TIME=English_United States.1252

attached base packages: stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: kableExtra(v.1.0.0), knitr(v.1.21), ggpubr(v.0.2.3.999), magrittr(v.1.5), pander(v.0.6.3), forcats(v.0.3.0), stringr(v.1.4.0), purrr(v.0.3.2), readr(v.1.3.1), tidyr(v.0.8.3), tibble(v.2.1.1), tidyverse(v.1.2.1), ggplot2(v.3.1.0), dplyr(v.0.8.5) and openxlsx(v.4.1.0)

loaded via a namespace (and not attached): tidyselect(v.0.2.5), xfun(v.0.5), haven(v.2.0.0), lattice(v.0.20-35), colorspace(v.1.3-2), viridisLite(v.0.3.0), htmltools(v.0.3.6), yaml(v.2.2.0), base64enc(v.0.1-3), rlang(v.0.4.0), pillar(v.1.3.1), glue(v.1.3.1), withr(v.2.1.2), modelr(v.0.1.2), readxl(v.1.2.0), plyr(v.1.8.4), ggsignif(v.0.5.0), munsell(v.0.5.0), gtable(v.0.2.0), cellranger(v.1.1.0), rvest(v.0.3.2), zip(v.2.0.1), evaluate(v.0.12), highr(v.0.7), broom(v.0.5.0), Rcpp(v.1.0.1), scales(v.1.0.0), backports(v.1.1.2), webshot(v.0.5.1), jsonlite(v.1.6), hms(v.0.4.2), digest(v.0.6.18), stringi(v.1.4.3), grid(v.3.5.1), cli(v.1.1.0), tools(v.3.5.1), lazyeval(v.0.2.1), pacman(v.0.5.0), crayon(v.1.3.4), pkgconfig(v.2.0.2), xml2(v.1.2.0), lubridate(v.1.7.4), assertthat(v.0.2.1), rmarkdown(v.1.11), httr(v.1.4.0), rstudioapi(v.0.8), R6(v.2.4.0), nlme(v.3.1-137) and compiler(v.3.5.1)

References

Mislan, K. A. S., Jeffrey M. Heer, and Ethan P. White. 2016. “Elevating the Status of Code in Ecology.” Trends in Ecology & Evolution 31 (1): 4–7. https://doi.org/10.1016/j.tree.2015.11.006.

Ouzzani, Mourad, Hossam Hammady, Zbys Fedorowicz, and Ahmed Elmagarmid. 2016. “Rayyana Web and Mobile App for Systematic Reviews.” Systematic Reviews 5 (1): 210. https://doi.org/10.1186/s13643-016-0384-4.

Stodden, Victoria, Peixuan Guo, and Zhaokun Ma. 2013. “Toward Reproducible Computational Research: An Empirical Analysis of Data and Code Policy Adoption by Journals.” PLOS ONE 8 (6): e67111. https://doi.org/10.1371/journal.pone.0067111.

Team, R Core. 2018. “R: A Language and Environment for Statistical Computing.” Vienna, Austria: R Foundation for Statistical Computing.

LS0tDQp0aXRsZTogTG93IGF2YWlsYWJpbGl0eSBvZiBjb2RlIGluIGVjb2xvZ3kmIzU4OyBhIGNhbGwgZm9yIHVyZ2VudCBhY3Rpb24NCmF1dGhvcjogQW50aWNhIEN1bGluYSwgSWxvbmEgdmFuIGRlbiBCZXJnLCBTaW1vbiBFdmFucywgQWxmcmVkbyBTYW5jaGV6LVRvamFyDQpkYXRlOiAnTGFzdCB1cGRhdGVkOiBgciBmb3JtYXQoU3lzLnRpbWUoKSwgIiVkICVCLCAlWSIpYCcNCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQogIHBkZl9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQpiaWJsaW9ncmFwaHk6IEN1bGluYV9ldF9hbC5iaWINCnN1YnRpdGxlOiBTdXBwb3J0aW5nIEluZm9ybWF0aW9uDQotLS0NCg0KYGBge3IsZWNobz1GQUxTRSwgY2FjaGU9RkFMU0V9DQojIyBudW1iZXJzID49IDEwXjUgd2lsbCBiZSBkZW5vdGVkIGluIHNjaWVudGlmaWMgbm90YXRpb24sIGFuZCByb3VuZGVkIHRvIDIgZGlnaXRzDQpvcHRpb25zKGRpZ2l0cz0zKQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0Kcm0obGlzdD1scygpKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIGV2YWwgPSBUUlVFKQ0KcGFjbWFuOjpwX2xvYWQob3Blbnhsc3gsZHBseXIsZ2dwbG90Mix0aWR5dmVyc2UscGFuZGVyLGdncHVicixrbml0cixrYWJsZUV4dHJhKQ0KDQojIGltcG9ydGluZyBkYXRhc2V0cw0KZGF0YS5mdWxsIDwtIHJlYWQudGFibGUoImRhdGEvY29kZV9hdmFpbGFiaWxpdHlfZnVsbF9hbmRfY2xlYW4uY3N2IixoZWFkZXI9VFJVRSxzZXA9IiwiKQ0Kam91cm5hbC5wb2xpY2llcyA8LSByZWFkLnhsc3goImRhdGEvVXBkYXRlZF9UYWJsZV9NaXNsYW5fMjAyMF92Mi54bHN4Iixjb2xOYW1lcz1ULHNoZWV0PTEpDQoNCiMgQ29kZXIncyBpbmZvcm1hdGlvbjogDQojIEFsZnJlZG8gU2FuY2hlei1Ub2phciAoQEFTYW5jaGV6X1RvamFyKQ0KIyBQcm9maWxlOiBodHRwczovL2dvby5nbC9QbXBQRUINCiMgRGVwYXJ0bWVudCBvZiBFdm9sdXRpb25hcnkgQmlvbG9neSwgQmllbGVmZWxkIFVuaXZlcnNpdHkgKEdFUikgDQojIEVtYWlsOiBhbGZyZWRvLnRvamFyQGdtYWlsLmNvbQ0KIyBTY3JpcHQgZmlyc3QgY3JlYXRlZCBvbiB0aGUgMm5kIG9mIEFwcmlsIDIwMjANCmBgYA0KDQojIyAxIC0gTWV0aG9kcw0KDQojIyMgMS4xIC0gU3RhdGUgb2YgYW5hbHl0aWNhbCBjb2RlIGluIGVjb2xvZ3kNCg0KV2UgcmFuZG9tbHkgc2FtcGxlZCBhcnRpY2xlcyBwdWJsaXNoZWQgaW4gZWNvbG9naWNhbCBqb3VybmFscyBmb3Igd2hpY2ggY29kZS1zaGFyaW5nIGhhcyBiZWVuIGVpdGhlciBtYW5kYXRvcnkgb3IgZW5jb3VyYWdlZCBzaW5jZSBKdW5lIDIwMTUgYXQgdGhlIGxhdGVzdC4gU2FtcGxpbmcgd2l0aGluIHRoZXNlIGpvdXJuYWxzIG1heGltaXplcyB0aGUgY29kZSBhdmFpbGFibGUgZm9yIHF1YWxpdHkgYXNzZXNzbWVudCAoc2VlIGJlbG93KSwgYW5kIGFsc28gaGVscHMgdXMgdG8gdW5kZXJzdGFuZCB3aGVyZSBvdGhlciBlY29sb2dpY2FsIGpvdXJuYWxzIHdpbGwgbGlrZWx5IGJlIGluIHRoZSBuZWFyIGZ1dHVyZSwgYXMgY29kZSBhcmNoaXZpbmcgcG9saWNpZXMgcHJvbGlmZXJhdGUgW0BzdG9kZGVuMjAxM10uIFRoZSBzYW1wbGUgb2Ygam91cm5hbHMgd2FzIG9idGFpbmVkIGZyb20gTWlzbGFuIGV0IGFsLiBbLUBtaXNsYW4yMDE2XSwgd2hvIGlkZW50aWZpZWQgYHIgdGFibGUoam91cm5hbC5wb2xpY2llcyRSZXF1aXJlLmNvbXB1dGVyLmNvZGUud2l0aC5wdWJsaWNhdGlvbl8yMDE1KVsnWWVzJ11gIG91dCBvZiBgciBucm93KGpvdXJuYWwucG9saWNpZXMpYCAoYHIgcm91bmQoKHRhYmxlKGpvdXJuYWwucG9saWNpZXMkUmVxdWlyZS5jb21wdXRlci5jb2RlLndpdGgucHVibGljYXRpb25fMjAxNSlbJ1llcyddL25yb3coam91cm5hbC5wb2xpY2llcykpKjEwMCwwKWAlKSBlY29sb2dpY2FsIGpvdXJuYWxzIHdpdGggbWFuZGF0b3J5IG9yIGVuY291cmFnaW5nIGNvZGUtc2hhcmluZyBwb2xpY2llcyBpbiBwbGFjZSBzaW5jZSBhdCBsZWFzdCB0aGUgMXN0IG9mIEp1bmUgMjAxNSAoVGFibGUgUzMpLiBXZSBzYW1wbGVkIGFsbCB0aGUgYXJ0aWNsZXMgcHVibGlzaGVkIGluIHRoZXNlIGByIHRhYmxlKGpvdXJuYWwucG9saWNpZXMkUmVxdWlyZS5jb21wdXRlci5jb2RlLndpdGgucHVibGljYXRpb25fMjAxNSlbJ1llcyddYCBqb3VybmFscyB1c2luZyB0aGUgV2ViIG9mIFNjaWVuY2UgQ29yZSBDb2xsZWN0aW9uIChzZWFyY2ggcGVyZm9ybWVkIGF0IHRoZSBOZXRoZXJsYW5kcyBJbnN0aXR1dGUgb2YgRWNvbG9neSkgZm9yIHR3byBkaXN0aW5jdCB0ZW1wb3JhbCBwZXJpb2RzOiAxc3Qgb2YgSnVuZSAyMDE1IHRvIDl0aCBvZiBEZWNlbWJlciAyMDE2ICgyMDE1LzE2IGRhdGFzZXQsIE49IDQsMzY2IHJlY29yZHMpLCBhbmQgMXN0IG9mIEphbnVhcnkgMjAxOCB0byAyMXN0IG9mIE1heSAyMDE5ICgyMDE4LzE5IGRhdGFzZXQsIE49NCwyOTEpLiBBIHJhbmRvbSBzYW1wbGUgb2YgMjAwIGFydGljbGVzIGZyb20gZWFjaCBwZXJpb2Qgd2FzIHRoZW4gc2VsZWN0ZWQgdXNpbmcgdGhlIGZ1bmN0aW9uIOKAnHNhbXBsZeKAnSBpbiBSIHYuIDMuMy4yIFtSIENvcmUgVGVhbSAtQHJjb3JldGVhbTIwMThdLg0KDQpGb3IgZWFjaCBvZiB0aGUgNDAwIGFydGljbGVzLCB3ZSBkZXRlcm1pbmVkIHdoZXRoZXIgdGhlIGFydGljbGUgd2FzIHJlbGV2YW50IHRvIG91ciBzdXJ2ZXkgYnkgc2NyZWVuaW5nIGFsbCB0aXRsZXMgYW5kIGFic3RyYWN0cyB1c2luZyB0aGUgc29mdHdhcmUgUmF5eWFuIFtAb3V6emFuaTIwMTZdLiBSZXZpZXdzLCBvcGluaW9uIHBpZWNlcywgYW5kIGNvbW1lbnRhcmllcyB3ZXJlIGV4Y2x1ZGVkLCB3aGVyZWFzIGFydGljbGVzIHRoYXQgY29uZHVjdGVkIHNvbWUga2luZCBvZiBzdGF0aXN0aWNhbCBhbmFseXNpcyBhbmQvb3Igc2ltdWxhdGlvbnMgd2VyZSBrZXB0IGZvciBmdXJ0aGVyIHNjcmVlbmluZy4gQWxsIHRoZSBhcnRpY2xlcyB3ZXJlIGRvdWJsZSBzY3JlZW5lZCBhdCB0aGlzIHN0YWdlICgyMDE1LzE2IGJ5IEFDIGFuZCBJdkI7IGFuZCAyMDE4LzE5IGJ5IEFTVCBhbmQgU0UpLiBBcyBhIHJlc3VsdCwgYHIgdGFibGUoZGF0YS5mdWxsW2RhdGEuZnVsbCRQdWJsaWNhdGlvbl95ZWFyLjI9PScyMDE1LTIwMTYnLCdFeGNsdWRlZC5hYnN0cmFjdC5zY3JlZW5pbmcnXSlbIm5vIl1gIG9mIHRoZSBgciBucm93KGRhdGEuZnVsbFtkYXRhLmZ1bGwkUHVibGljYXRpb25feWVhci4yPT0nMjAxNS0yMDE2JyxdKWAgYXJ0aWNsZXMgaW4gMjAxNS8xNiBkYXRhc2V0LCBhbmQgYHIgdGFibGUoZGF0YS5mdWxsW2RhdGEuZnVsbCRQdWJsaWNhdGlvbl95ZWFyLjI9PScyMDE4LTIwMTknLCdFeGNsdWRlZC5hYnN0cmFjdC5zY3JlZW5pbmcnXSlbIm5vIl1gIG9mIHRoZSBgciBucm93KGRhdGEuZnVsbFtkYXRhLmZ1bGwkUHVibGljYXRpb25feWVhci4yPT0nMjAxOC0yMDE5JyxdKWAgYXJ0aWNsZXMgaW4gMjAxOC8xOSBkYXRhc2V0IHdlcmUga2VwdCBmb3IgZnVydGhlciBldmFsdWF0aW9uLiBUaGUgZnVsbCBsaXN0IG9mIHRoZXNlIGFydGljbGVzLCB3aXRoIHRoZSByZXN1bHRzIG9mIHRoZSBzY3JlZW5pbmcgaXMgcHJvdmlkZWQgKHNlZSBmaWxlIGBkYXRhL2NvZGVfYXZhaWxhYmlsaXR5X2Z1bGxfYW5kX2NsZWFuLmNzdmApLg0KDQpJbiB0aGUgbmV4dCBzdGVwcyAoc3VtbWFyaXplZCBpbiBGaWd1cmUgUzEpIEFDIGV2YWx1YXRlZCBgciB0YWJsZShkYXRhLmZ1bGxbZGF0YS5mdWxsJFB1YmxpY2F0aW9uX3llYXIuMj09JzIwMTUtMjAxNicsJ0V4Y2x1ZGVkLmFic3RyYWN0LnNjcmVlbmluZyddKVsibm8iXWAgYXJ0aWNsZXMgZnJvbSAyMDE1LzE2LCBhbmQgQVNUIGV2YWx1YXRlZCBgciB0YWJsZShkYXRhLmZ1bGxbZGF0YS5mdWxsJFB1YmxpY2F0aW9uX3llYXIuMj09JzIwMTgtMjAxOScsJ0V4Y2x1ZGVkLmFic3RyYWN0LnNjcmVlbmluZyddKVsibm8iXWAgYXJ0aWNsZXMgZnJvbSAyMDE4LzE5LiBGaXJzdCwgZWFjaCBhcnRpY2xlIHdhcyByZWFkIGluIGRldGFpbCB0byBkZXRlcm1pbmUgaWYgaXQgd2FzIGEgcHVyZWx5IGJpb2luZm9ybWF0aWNhbCAoaS5lLiBtb2xlY3VsYXIpIHN0dWR5IHdpdGggc29sZWx5IGJpb2luZm9ybWF0aWNhbCBhbmFseXNlcy4gT25seSBzdHVkaWVzIHRoYXQgY29uZHVjdGVkIGF0IGxlYXN0IHNvbWUgc3RhdGlzdGljYWwgYW5hbHlzZXMgb3RoZXIgdGhhbiBiaW9pbmZvcm1hdGljcyAoaW5jbHVkaW5nIHNpbXVsYXRpb25zKSB3ZXJlIGNvbnNpZGVyZWQgZnVydGhlciAoaGVyZWFmdGVyIHJlZmVycmVkIHRvIGFzICdub24tbW9sZWN1bGFyJykuIFRoZXNlIG5vbi1tb2xlY3VsYXIgYXJ0aWNsZXMgKGByIHRhYmxlKGRhdGEuZnVsbFtkYXRhLmZ1bGwkUHVibGljYXRpb25feWVhci4yPT0nMjAxNS0yMDE2Jywnc3RhdGlzdGljYWwuYW5hbHlzaXMuYW5kLm9yLnNpbXVsYXRpb25zLjInXSlbInllcyJdYCBpbiAyMDE1LzE2OyBgciB0YWJsZShkYXRhLmZ1bGxbZGF0YS5mdWxsJFB1YmxpY2F0aW9uX3llYXIuMj09JzIwMTgtMjAxOScsJ3N0YXRpc3RpY2FsLmFuYWx5c2lzLmFuZC5vci5zaW11bGF0aW9ucy4yJ10pWyJ5ZXMiXWAgaW4gMjAxOC8xOSkgd2VyZSB0aGVuIGV2YWx1YXRlZCBiYXNlZCBvbiB0aGUgZm9sbG93aW5nIChhbmQgYXMgc2hvd24gaW4gRmlndXJlIFMxKToNCg0KMSkJV2FzIHRoZSBhbmFseXRpY2FsIGNvZGUgcHVibGlzaGVkPyAo4oCYeWVz4oCZLCDigJhub+KAmSwg4oCYc29tZeKAmSkuIFRoaXMgd2FzIGRvbmUgYnkgY2hlY2tpbmcgYm90aCB0aGUgYXJ0aWNsZeKAmXMgbWFpbiB0ZXh0LCBkYXRhIGFjY2Vzc2libHkgc3RhdGVtZW50cywgYW5kIHRoZSBzdXBwbGVtZW50YXJ5IG1hdGVyaWFscywgaW5jbHVkaW5nIGFyY2hpdmVkIGRhdGEsIGlmIGFueS4gSWYgbm8gY29kZSAo4oCYY29kZeKAmSwg4oCYc2NyaXB04oCZLCDigJhzeW50YXjigJkpIHdhcyBtZW50aW9uZWQgaW4gYW55IG9mIHRoZXNlIHNlY3Rpb25zLCB0aGVuIGFsbCBsaW5rcyB0byBhcmNoaXZlZCBkYXRhLCBhbmQgYWxsIHN1cHBsZW1lbnRhcnkgbWF0ZXJpYWxzIHdlcmUgc2VhcmNoZWQuIA0KDQoyKQlXaGF0IHNvZnR3YXJlIHdhcyB1c2VkIGluIHRoZSBhbmFseXNpcz8gKGUuZy4gUiwgUHl0aG9uLCBTQVMuLi4pDQoNCjMpCVdlcmUgdGhlcmUgZGF0YSB1c2VkIGluIHRoZSBhbmFseXNpcyAo4oCYeWVz4oCZLCDigJhub+KAmSk/IElmIHllcywgd2VyZSB0aGUgZGF0YSBwdWJsaXNoZWQgKOKAmHllc+KAmSwg4oCYbm/igJksIOKAmHNvbWXigJkpPw0KDQpGb3IgdGhvc2UgYXJ0aWNsZXMgdGhhdCBoYWQgcHVibGlzaGVkIHNlZW1pbmdseSBhbGwgb3IgYXQgbGVhc3Qgc29tZSBvZiB0aGVpciBjb2RlIChgciB0YWJsZShkYXRhLmZ1bGxbZGF0YS5mdWxsJFB1YmxpY2F0aW9uX3llYXIuMj09JzIwMTUtMjAxNicsJ0NvZGVQdWJsaXNoZWQuMyddKVsieWVzIl1gIGluIDIwMTUvMTY7IGByIHRhYmxlKGRhdGEuZnVsbFtkYXRhLmZ1bGwkUHVibGljYXRpb25feWVhci4yPT0nMjAxOC0yMDE5JywnQ29kZVB1Ymxpc2hlZC4zJ10pWyJ5ZXMiXWAgaW4gMjAxOC8xOSksIHdlIGV2YWx1YXRlZCB0aGUgZm9sbG93aW5nOg0KDQo0KQlXaGVyZSB3YXMgdGhlIGNvZGUgcHVibGlzaGVkICjigJhyZXBvc2l0b3J54oCZLCDigJhzdXBwbGVtZW50YXJ5IG1hdGVyaWFs4oCZLCAndmVyc2lvbiBjb250cm9sIHBsYXRmb3JtJywg4oCYd2VicGFnZeKAmSk/DQoNCjUpCVdhcyB0aGUgZXhpc3RlbmNlIG9mIGNvZGUgY2xlYXJseSBtZW50aW9uZWQgKOKAmHllc+KAmSwg4oCYbm/igJkpLCBhbmQgaWYgc28sIGhvdyAo4oCYY29kZeKAmSwg4oCYc2NyaXB04oCZLCDigJhvdGhlcuKAmSk/DQoNCjYpCVdoZXJlIHdhcyB0aGUgcmVmZXJlbmNlIHRvIHRoZSBjb2RlIG1hZGUsIGlmIGF0IGFsbCAo4oCYbWV0aG9kcyBzZWN0aW9u4oCZLCDigJhkYXRhIGFjY2Vzc2liaWxpdHkgc3RhdGVtZW504oCZLCDigJhzdXBwbGVtZW50YXJ5IG1hdGVyaWFs4oCZLCDigJhvdGhlcuKAmSk/DQoNCjcpCURpZCB0aGUgY29kZSBpbmNsdWRlIHNvbWUga2luZCBvZiBkb2N1bWVudGF0aW9uIHN1Y2ggYXMgUkVBRE1FIG9yIEhvd1RvIGZpbGVzICjigJh5ZXPigJksIOKAmG5v4oCZIG9yIOKAmHdpdGggc29tZSBjb21tZW50c+KAmSk/DQoNCjgpCVdlcmUgdGhlcmUgaW5saW5lIGNvbW1lbnRzIHdpdGhpbiB0aGUgY29kZSAo4oCYeWVz4oCZLCDigJhub+KAmSk/DQoNCjxjZW50ZXI+DQoNCiFbKipGaWd1cmUgUzEqKi4gRGlhZ3JhbSBvZiBudW1iZXIgb2Ygc3R1ZGllcyBmb3IgZWFjaCBjYXRlZ29yeS5dKHBsb3RzL0ZpZ3VyZVMxLnBuZykNCg0KPC9jZW50ZXI+DQoNClRvIGVuc3VyZSBkYXRhIHJlbGlhYmlsaXR5LCB3ZSByYW5kb21seSBzZWxlY3RlZCBhbmQgZG91YmxlLWNoZWNrZWQgZGF0YSBleHRyYWN0aW9uICh0d28gb2JzZXJ2ZXJzOiBBU1QgYW5kIEFDKSBmb3IgYHIgcm91bmQoKG5yb3coZGF0YS5mdWxsWyhkYXRhLmZ1bGwkU2Vjb25kX3NjcmVlbmVyPT0iQVNUIiB8IGRhdGEuZnVsbCRTZWNvbmRfc2NyZWVuZXI9PSJBQyIpICYgIShpcy5uYShkYXRhLmZ1bGwkU2Vjb25kX3NjcmVlbmVyKSksXSkvdGFibGUoZGF0YS5mdWxsJEV4Y2x1ZGVkLmFic3RyYWN0LnNjcmVlbmluZylbIm5vIl0pKjEwMCwwKWAlIG9mIGFsbCB0aGUgYXJ0aWNsZXMgdGhhdCBoYWQgcGFzc2VkIHRoZSB0aXRsZS1hbmQtYWJzdHJhY3Qgc2NyZWVuaW5nIChgciBucm93KGRhdGEuZnVsbFtkYXRhLmZ1bGwkU2Vjb25kX3NjcmVlbmVyPT0iQVNUIiAmICEoaXMubmEoZGF0YS5mdWxsJFNlY29uZF9zY3JlZW5lcikpLF0pYCBvdXQgb2YgYHIgdGFibGUoZGF0YS5mdWxsW2RhdGEuZnVsbCRQdWJsaWNhdGlvbl95ZWFyLjI9PScyMDE1LTIwMTYnLCdFeGNsdWRlZC5hYnN0cmFjdC5zY3JlZW5pbmcnXSlbIm5vIl1gIGFydGljbGVzIGZyb20gMjAxNS8xNiwgYW5kIGByIG5yb3coZGF0YS5mdWxsW2RhdGEuZnVsbCRTZWNvbmRfc2NyZWVuZXI9PSJBQyIgJiAhKGlzLm5hKGRhdGEuZnVsbCRTZWNvbmRfc2NyZWVuZXIpKSxdKWAgb3V0IG9mIGByIHRhYmxlKGRhdGEuZnVsbFtkYXRhLmZ1bGwkUHVibGljYXRpb25feWVhci4yPT0nMjAxOC0yMDE5JywnRXhjbHVkZWQuYWJzdHJhY3Quc2NyZWVuaW5nJ10pWyJubyJdYCBmcm9tIDIwMTgvMTkgZGF0YXNldCkuIFRoZSBkZWNpc2lvbiBvdmVybGFwIGJldHdlZW4gb2JzZXJ2ZXJzIHdhcyB2ZXJ5IGhpZ2ggKHBsZWFzZSBzZWUgZmlsZSBgZGF0YS9jb2RlX2F2YWlsYWJpbGl0eV9mdWxsX2FuZF9jbGVhbi5jc3ZgIGZvciBjaGFuZ2VzIGFuZCBleHBsYW5hdGlvbnMgbWFkZSB0byB0aGUgdGFibGUgYWZ0ZXIgdGhlIGRvdWJsZSBzY3JlZW5pbmcpLiBTb21lIGFkZGl0aW9uYWwgYXJ0aWNsZXMgd2VyZSBmdXJ0aGVyIGludGVudGlvbmFsbHkgZG91YmxlLWNoZWNrZWQgd2hlbmV2ZXIgdGhlIG9yaWdpbmFsIHNjcmVlbmVyIHdhcyBub3Qgc3VyZSBhYm91dCB0aGUgYXNzaWdubWVudCBvZiBzb21lIHNjb3JlcyAoYHIgbnJvdyhkYXRhLmZ1bGxbKGRhdGEuZnVsbCRTZWNvbmRfc2NyZWVuZXI9PSJBU1QtcXVpY2siIHwgZGF0YS5mdWxsJFNlY29uZF9zY3JlZW5lcj09IkFDLXF1aWNrIikgJiAhKGlzLm5hKGRhdGEuZnVsbCRTZWNvbmRfc2NyZWVuZXIpKSxdKWAgYXJ0aWNsZXMpIG9yIHdoZW4gdGhlIG9yaWdpbmFsIHNjcmVlbmVyIGNvdWxkIG5vdCBmaW5kIGFueSByZWZlcmVuY2UgdG8gdGhlIHNvZnR3YXJlIHVzZWQgZm9yIHRoZSBhbmFseXNlcyAoYHIgbnJvdyhkYXRhLmZ1bGxbZGF0YS5mdWxsJFN0YXRfYW5hbHlzaXNfc29mdHdhcmU9PSJOb3QgU3RhdGVkIiAmICEoaXMubmEoZGF0YS5mdWxsJFN0YXRfYW5hbHlzaXNfc29mdHdhcmUpKSxdKWAgYXJ0aWNsZXM7IG1vcmUgZGV0YWlscyBpbiBmaWxlIGBkYXRhL2NvZGVfYXZhaWxhYmlsaXR5X2Z1bGxfYW5kX2NsZWFuLmNzdmApLg0KDQojIyMgMS4yIC0gSm91cm5hbHMnIGNvZGUtc2hhcmluZyBwb2xpY2llcw0KDQpXZSBleHBsb3JlZCBpZiB0aGUgbnVtYmVyIG9mIGVjb2xvZ2ljYWwgam91cm5hbHMgd2l0aCBjb2RlLXNoYXJpbmcgcG9saWNpZXMgaGFzIGluY3JlYXNlZCBzaW5jZSAyMDE1LCB3aGVuIG9ubHkgYHIgdGFibGUoam91cm5hbC5wb2xpY2llcyRSZXF1aXJlLmNvbXB1dGVyLmNvZGUud2l0aC5wdWJsaWNhdGlvbl8yMDE1KVsnWWVzJ11gIG91dCBvZiBgciBucm93KGpvdXJuYWwucG9saWNpZXMpYCAoYHIgcm91bmQoKHRhYmxlKGpvdXJuYWwucG9saWNpZXMkUmVxdWlyZS5jb21wdXRlci5jb2RlLndpdGgucHVibGljYXRpb25fMjAxNSlbJ1llcyddL25yb3coam91cm5hbC5wb2xpY2llcykpKjEwMCwwKWAlKSBoYWQgY29kZS1zaGFyaW5nIHBvbGljaWVzIFtAbWlzbGFuMjAxNl0uIEluIE1hcmNoIDIwMjAgd2UgaW52ZXN0aWdhdGVkIHRoZSBjb2RlLXNoYXJpbmcgcG9saWNpZXMgZm9yIGFsbCB0aGUgYHIgbnJvdyhqb3VybmFsLnBvbGljaWVzKWAgZWNvbG9naWNhbCBqb3VybmFscyBpZGVudGlmaWVkIGJ5IE1pc2xhbiBldCBhbC4gWy1AbWlzbGFuMjAxNjsgVGFibGUgUzNdLiBPbmUgb2JzZXJ2ZXIgKEFDKSByZWFkIHRoZSAnQXV0aG9ycyBJbnN0cnVjdGlvbnMnIGFuZCAnRWRpdG9yaWFsIFBvbGljaWVzJyBvZiBlYWNoIGpvdXJuYWwsIGFuZCBhIHNlY29uZCBvYnNlcnZlciAoQVNUKSBkaWQgc28gYnV0IG9ubHkgZm9yIHRoZSBgciB0YWJsZShqb3VybmFsLnBvbGljaWVzJFJlcXVpcmUuY29tcHV0ZXIuY29kZS53aXRoLnB1YmxpY2F0aW9uXzIwMTUpWydZZXMnXWAgam91cm5hbHMgcmV2aWV3ZWQgaW4gdGhpcyBzdHVkeSBhbmQgZm9yIHRob3NlIGpvdXJuYWxzIHNjb3JlZCBhcyAnTm8nIChzZWUgYmVsb3cpIGJ5IHRoZSBmaXJzdCBvYnNlcnZlciAtIHVuY2xlYXIgY2FzZXMgd2VyZSBkaXNjdXNzZWQgdG9nZXRoZXIuIElmIG5vbmUgb2YgdGhlc2Ugc2VjdGlvbnMgZXhwbGljaXRseSBtZW50aW9uZWQgZGF0YSBhbmQvb3IgY29kZSwgd2UgYWxzbyBjaGVja2VkIG90aGVyIHNlY3Rpb25zIG9mIHRoZSBqb3VybmFsJ3Mgd2Vic2l0ZSwgd2hlbmV2ZXIgcG9zc2libGUuIEJhc2VkIG9uIHRoZSBpbmZvcm1hdGlvbiBjb2xsZWN0ZWQsIHdlIHNjb3JlZCB0aGUgam91cm5hbHMnIGNvZGUtc2hhcmluZyBwb2xpY2llcyBhczog4oCYZW5jb3VyYWdlZOKAmSAocHVibGljYXRpb24gb2YgdGhlIGNvZGUgaXMgZXhwbGljaXRseSBlbmNvdXJhZ2VkLCBidXQgbm90IHJlcXVpcmVkKSwg4oCYbWFuZGF0b3J54oCZIChjb2RlIG11c3QgYmUgcHVibGlzaGVkIHRvZ2V0aGVyIHdpdGggdGhlIGFydGljbGUpLCBvciAnZW5jb3VyYWdlZC9tYW5kYXRvcnknICh3aGVuIHRoZSB3b3JkaW5nIG1hZGUgaXQgZGlmZmljdWx0IHRvIGp1ZGdlIGlmIGNvZGUgcHVibGljYXRpb24gaXMgZW5jb3VyYWdlZCBvciByZXF1aXJlZCkuIElmIGEgam91cm5hbCBkaWQgbm90IGV4cGxpY2l0bHkgZW5jb3VyYWdlIGNvZGUtc2hhcmluZyAoaS5lLiBldmVuIHdoZW4gaXQgbWVudGlvbmVkIHJlc2VhcmNoIGFydGVmYWN0cywgYnV0IG5vdCAnY29kZScgb3IgJ3NjcmlwdCcgZXhwbGljaXRseTogYHIgbnJvdyhqb3VybmFsLnBvbGljaWVzW2pvdXJuYWwucG9saWNpZXMkUmVxdWlyZS5jb21wdXRlci5jb2RlLndpdGgucHVibGljYXRpb25fMjAyMD09Ik5vIiAmICEoaXMubmEoam91cm5hbC5wb2xpY2llcyRSZXF1aXJlLmNvbXB1dGVyLmNvZGUud2l0aC5wdWJsaWNhdGlvbl8yMDIwKSkgJiAhKGlzLm5hKGpvdXJuYWwucG9saWNpZXMkQ29tbWVudF9vbl8yMDIwKSksXSlgIG91dCBvZiBgciBucm93KGpvdXJuYWwucG9saWNpZXNbIShpcy5uYShqb3VybmFsLnBvbGljaWVzJFJlcXVpcmUuY29tcHV0ZXIuY29kZS53aXRoLnB1YmxpY2F0aW9uXzIwMjApKSxdKWAsIGByIHJvdW5kKChucm93KGpvdXJuYWwucG9saWNpZXNbam91cm5hbC5wb2xpY2llcyRSZXF1aXJlLmNvbXB1dGVyLmNvZGUud2l0aC5wdWJsaWNhdGlvbl8yMDIwPT0iTm8iICYgIShpcy5uYShqb3VybmFsLnBvbGljaWVzJFJlcXVpcmUuY29tcHV0ZXIuY29kZS53aXRoLnB1YmxpY2F0aW9uXzIwMjApKSAmICEoaXMubmEoam91cm5hbC5wb2xpY2llcyRDb21tZW50X29uXzIwMjApKSxdKS9ucm93KGpvdXJuYWwucG9saWNpZXNbIShpcy5uYShqb3VybmFsLnBvbGljaWVzJFJlcXVpcmUuY29tcHV0ZXIuY29kZS53aXRoLnB1YmxpY2F0aW9uXzIwMjApKSxdKSkqMTAwLDApYCUpLCB0aGUgam91cm5hbCdzIGNvZGUtc2hhcmluZyBwb2xpY3kgd2FzIHNjb3JlZCBhcyDigJhOb+KAmSAoaS5lLiBjb2RlLXNoYXJpbmcgaXMgbm90IG1lbnRpb25lZCBleHBsaWNpdGx5OyBzZWUgY29tbWVudHMgaW4gZmlsZSBgZGF0YS9VcGRhdGVkX1RhYmxlX01pc2xhbl8yMDIwX3YyLnhsc3hgKS4NCg0KKipUYWJsZSBTMSoqLiBMaXN0IG9mIGByIG5yb3coam91cm5hbC5wb2xpY2llcylgIGVjb2xvZ2ljYWwgam91cm5hbHMgYW5kIHRoZWlyIGNvZGUtc2hhcmluZyBwb2xpY2llcyBpbiBKdW5lIDIwMTUgW0BtaXNsYW4yMDE2XSBhbmQgaW4gTWFyY2ggMjAyMCAodGhpcyBzdHVkeSkuDQpgYGB7cn0NCiMgcHJpbnRpbmcgVGFibGUgUzENCmpvdXJuYWwucG9saWNpZXMgJT4lIHNlbGVjdChGdWxsLkpvdXJuYWwuVGl0bGUsUmVxdWlyZS5jb21wdXRlci5jb2RlLndpdGgucHVibGljYXRpb25fMjAxNSxSZXF1aXJlLmNvbXB1dGVyLmNvZGUud2l0aC5wdWJsaWNhdGlvbl8yMDIwKSAlPiUNCiAgcmVuYW1lKEpvdXJuYWw9RnVsbC5Kb3VybmFsLlRpdGxlLCdDb2RlLXNoYXJpbmcgcG9saWN5IDIwMTUnPVJlcXVpcmUuY29tcHV0ZXIuY29kZS53aXRoLnB1YmxpY2F0aW9uXzIwMTUsJ0NvZGUtc2hhcmluZyBwb2xpY3kgMjAyMCc9UmVxdWlyZS5jb21wdXRlci5jb2RlLndpdGgucHVibGljYXRpb25fMjAyMCkgJT4lIGFycmFuZ2UoSm91cm5hbCkgJT4lDQogIGthYmxlKCJodG1sIikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUNCiAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjUwMHB4IikNCmBgYA0KDQojIyAyIC0gUmVzdWx0cw0KDQojIyMgMi4xIC0gUGVyY2VudGFnZXMgY2FsY3VsYXRpb25zDQoNCmBgYHtyfQ0KIyBudW1iZXIgb2YgZWxpZ2libGUgYXJ0aWNsZXMNCmVsaWdpYmxlLmFydGljbGVzLmNvZGUgPC0gYXMubnVtZXJpYyhkYXRhLmZ1bGwgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKCEoaXMubmEoc3RhdGlzdGljYWwuYW5hbHlzaXMuYW5kLm9yLnNpbXVsYXRpb25zLjIpKSkgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXNlKGVsaWdpYmxlX2FydGljbGVzID0gc3VtKHN0YXRpc3RpY2FsLmFuYWx5c2lzLmFuZC5vci5zaW11bGF0aW9ucy4yID09ICJ5ZXMiKSkpDQoNCiMgbnVtYmVyIG9mIGVsaWdpYmxlIGFydGljbGVzDQplbGlnaWJsZS5hcnRpY2xlcy5jb2RlLnllYXIgPC0gZGF0YS5mdWxsICU+JSANCiAgZmlsdGVyKCEoaXMubmEoc3RhdGlzdGljYWwuYW5hbHlzaXMuYW5kLm9yLnNpbXVsYXRpb25zLjIpKSkgJT4lIA0KICBncm91cF9ieShQdWJsaWNhdGlvbl95ZWFyLjIpICU+JSANCiAgc3VtbWFyaXNlKGVsaWdpYmxlX2FydGljbGVzID0gc3VtKHN0YXRpc3RpY2FsLmFuYWx5c2lzLmFuZC5vci5zaW11bGF0aW9ucy4yID09ICJ5ZXMiKSkNCg0KIyBudW1iZXIgb2YgYXJ0aWNsZXMgdGhhdCBwdWJsaXNoZWQgYXQgbGVhc3Qgc29tZSBjb2RlDQphdC5sZWFzdC5zb21lLmNvZGUgPC0gYXMubnVtZXJpYyhkYXRhLmZ1bGwgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIShpcy5uYShDb2RlUHVibGlzaGVkLjMpKSkgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJpc2UoY29kZV9wdWJsaXNoZWQgPSBzdW0oQ29kZVB1Ymxpc2hlZC4zID09ICJ5ZXMiKSkpDQoNCiMgbnVtYmVyIG9mIGFydGljbGVzIHBlciB5ZWFyIHRoYXQgcHVibGlzaGVkIGF0IGxlYXN0IHNvbWUgY29kZQ0KYXQubGVhc3Quc29tZS5jb2RlLnllYXIgPC0gZGF0YS5mdWxsICU+JSANCiAgZmlsdGVyKCEoaXMubmEoQ29kZVB1Ymxpc2hlZC4zKSkpICU+JSANCiAgZ3JvdXBfYnkoUHVibGljYXRpb25feWVhci4yKSAlPiUgDQogIHN1bW1hcmlzZShjb2RlX3B1Ymxpc2hlZCA9IHN1bShDb2RlUHVibGlzaGVkLjMgPT0gInllcyIpKQ0KDQojIG51bWJlciBvZiBhcnRpY2xlcyB0aGF0IHB1Ymxpc2hlZCBzZWVtaW5nbHkgYWxsIGNvZGUNCnNlZW1pbmdseS5hbGwuY29kZSA8LSBhcy5udW1lcmljKGRhdGEuZnVsbCAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcighKGlzLm5hKENvZGVQdWJsaXNoZWQuMikpKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcmlzZShjb2RlX3B1Ymxpc2hlZCA9IHN1bShDb2RlUHVibGlzaGVkLjIgPT0gInllcyIpKSkNCg0KIyBudW1iZXIgb2YgYXJ0aWNsZXMgdGhhdCBwdWJsaXNoZWQgb25seSBzb21lY29kZQ0Kb25seS5zb21lLmNvZGUgPC0gYXMubnVtZXJpYyhkYXRhLmZ1bGwgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcighKGlzLm5hKENvZGVQdWJsaXNoZWQuMikpKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXNlKGNvZGVfcHVibGlzaGVkID0gc3VtKENvZGVQdWJsaXNoZWQuMiA9PSAic29tZSIpKSkNCg0KIyBudW1iZXIgb2YgZWxpZ2libGUgYXJ0aWNsZXMgdGhhdCB1c2VkIGRhdGENCmVsaWdpYmxlLmFydGljbGVzLmRhdGEgPC0gYXMubnVtZXJpYyhkYXRhLmZ1bGwgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKCEoaXMubmEoc3RhdGlzdGljYWwuYW5hbHlzaXMuYW5kLm9yLnNpbXVsYXRpb25zLjIpKSAmICEoaXMubmEoRGF0YVVzZWQpKSkgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXNlKGVsaWdpYmxlX2FydGljbGVzID0gc3VtKHN0YXRpc3RpY2FsLmFuYWx5c2lzLmFuZC5vci5zaW11bGF0aW9ucy4yID09ICJ5ZXMiICYgRGF0YVVzZWQgPT0gInllcyIpKSkNCg0KIyBudW1iZXIgb2YgYXJ0aWNsZXMgdGhhdCBwdWJsaXNoZWQgYXQgbGVhc3Qgc29tZSBkYXRhDQphdC5sZWFzdC5zb21lLmRhdGEgPC0gYXMubnVtZXJpYyhkYXRhLmZ1bGwgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIShpcy5uYShEYXRhU2hhcmVkLjMpKSkgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJpc2UoZGF0YV9wdWJsaXNoZWQgPSBzdW0oRGF0YVNoYXJlZC4zID09ICJ5ZXMiKSkpDQoNCiMgbnVtYmVyIG9mIGFydGljbGVzIHRoYXQgcHVibGlzaGVkIHNlZW1pbmdseSBhbGwgY29kZSBhbmQgZGF0YSAoaWYgYW55IHVzZWQpDQpzZWVtaW5nbHkuYWxsLmNvZGUuYW5kLmRhdGEgPC0gYXMubnVtZXJpYyhkYXRhLmZ1bGwgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIShpcy5uYShDb2RlUHVibGlzaGVkLjIpKSkgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJpc2UoY29kZV9hbmRfZGF0YV9wdWJsaXNoZWQgPSBzdW0oQ29kZVB1Ymxpc2hlZC4yID09ICJ5ZXMiICYgKERhdGFTaGFyZWQuMiA9PSAieWVzIiB8IGlzLm5hKERhdGFTaGFyZWQuMikpKSkpDQoNCiMgbnVtYmVyIG9mIGFydGljbGVzIHRoYXQgcHVibGlzaGVkIHNlZW1pbmdseSBhbGwgY29kZSBhbmQgZGF0YSAoaWYgYW55IHVzZWQpDQpzZWVtaW5nbHkuYWxsLmNvZGUuYW5kLmRhdGEueWVhciA8LWRhdGEuZnVsbCAlPiUgDQogIGZpbHRlcighKGlzLm5hKENvZGVQdWJsaXNoZWQuMikpKSAlPiUgDQogIGdyb3VwX2J5KFB1YmxpY2F0aW9uX3llYXIuMikgJT4lIA0KICBzdW1tYXJpc2UoY29kZV9hbmRfZGF0YV9wdWJsaXNoZWQgPSBzdW0oQ29kZVB1Ymxpc2hlZC4yID09ICJ5ZXMiICYgKERhdGFTaGFyZWQuMiA9PSAieWVzIiB8IGlzLm5hKERhdGFTaGFyZWQuMikpKSkNCg0KDQojIG51bWJlciBvZiBqb3VybmFscyB3aXRoIHNvbWUgdHlwZSBvZiBjb2RlLXNoYXJpbmcgcG9saWN5IGluIDIwMTUNCmpvdXJuYWxzLndpdGgucG9saWN5LjIwMTUgPC0gYXMubnVtZXJpYyh0YWJsZShqb3VybmFsLnBvbGljaWVzJFJlcXVpcmUuY29tcHV0ZXIuY29kZS53aXRoLnB1YmxpY2F0aW9uXzIwMTUpWydZZXMnXSkNCg0KIyBudW1iZXIgb2Ygam91cm5hbHMgcmV2aWV3ZWQgaW4gMjAxNQ0Kam91cm5hbHMuMjAxNSA8LSBucm93KGpvdXJuYWwucG9saWNpZXMpDQoNCiMgbnVtYmVyIG9mIGpvdXJuYWxzIHdpdGggc29tZSB0eXBlIG9mIGNvZGUtc2hhcmluZyBwb2xpY3kgaW4gMjAyMA0Kam91cm5hbHMud2l0aC5wb2xpY3kuMjAyMCA8LSBucm93KGpvdXJuYWwucG9saWNpZXNbIShpcy5uYShqb3VybmFsLnBvbGljaWVzJFJlcXVpcmUuY29tcHV0ZXIuY29kZS53aXRoLnB1YmxpY2F0aW9uXzIwMjApKSAmIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb3VybmFsLnBvbGljaWVzJFJlcXVpcmUuY29tcHV0ZXIuY29kZS53aXRoLnB1YmxpY2F0aW9uXzIwMjAhPSJObyIsXSkNCg0KIyBudW1iZXIgb2Ygam91cm5hbHMgcmV2aWV3ZWQgaW4gMjAxNSB0aGF0IHdlcmUgc3RpbGwgYWN0aXZlIGluIDIwMjANCmpvdXJuYWxzLjIwMjAgPC0gbnJvdyhqb3VybmFsLnBvbGljaWVzWyEoaXMubmEoam91cm5hbC5wb2xpY2llcyRSZXF1aXJlLmNvbXB1dGVyLmNvZGUud2l0aC5wdWJsaWNhdGlvbl8yMDIwKSksXSkNCg0KIyAjIG51bWJlciBvZiBqb3VybmFscyBjb3ZlcmVkIGVhY2ggeWVhcg0KIyBudW1iZXIuam91cm5hbHMuY292ZXJlZCA8LSBhcy5kYXRhLmZyYW1lKGRhdGEuZnVsbCAlPiUgZ3JvdXBfYnkoUHVibGljYXRpb25feWVhci4yLEpvdXJuYWwpICU+JSBzdW1tYXJpc2UoY291bnQgPSBuX2Rpc3RpbmN0KENvZGVQdWJsaXNoZWQuMikpICU+JSBzdW1tYXJpc2UobiA9IG4oKSkpDQoNCiMgY291bnRpbmcgbnVtYmVyIG9mIGFydGljbGVzIHBlciBqb3VybmFsDQphcnRpY2xlcy5wZXIuam91cm5hbCA8LSBhcy5kYXRhLmZyYW1lKGRhdGEuZnVsbCAlPiUgZ3JvdXBfYnkoSm91cm5hbCkgJT4lIHN1bW1hcmlzZSh0b3RhbCA9IG4oKSkpDQoNCiMgY291bnRpbmcgbnVtYmVyIG9mIGFydGljbGVzIHdpdGggYXQgbGVhc3Qgc29tZSBjb2RlIHBlciBqb3VybmFsDQpjb2RlLnB1Ymxpc2hlZC5wZXIuam91cm5hbCA8LSBhcy5kYXRhLmZyYW1lKGRhdGEuZnVsbCAlPiUgZmlsdGVyKENvZGVQdWJsaXNoZWQuMz09InllcyIpICU+JSBncm91cF9ieShKb3VybmFsKSAlPiUgc3VtbWFyaXNlKGNvZGVwdWJsaXNoZWQgPSBuKCkpKQ0KDQojIG1lcmdpbmcgZGF0YWZyYW1lcyB0b2dldGhlcg0KZnVsbC5qb3VybmFsIDwtIG1lcmdlKGNvZGUucHVibGlzaGVkLnBlci5qb3VybmFsLGFydGljbGVzLnBlci5qb3VybmFsKQ0KZnVsbC5qb3VybmFsJHBlcmNlbnRhZ2UgPC0gcm91bmQoKGZ1bGwuam91cm5hbCRjb2RlcHVibGlzaGVkL2Z1bGwuam91cm5hbCR0b3RhbCkqMTAwLDApDQoNCiMgc2F2aW5nIGpvdXJuYWwgcGVyY2VudGFnZXMgaW5mb3JtYXRpb24gdG8gYmUgdXNlZCBpbiBzY3JpcHQgMDA0X3Bsb3R0aW5nLlINCndyaXRlLmNzdihmdWxsLmpvdXJuYWwsImRhdGEvam91cm5hbF9wZXJjZW50YWdlcy5jc3YiLHJvdy5uYW1lcz1GQUxTRSkNCg0KIyBudW1iZXIgb2YgYXJ0aWNsZXMgbWVudGlvbmluZyB0aGF0IGNvZGUgd2FzIHB1Ymxpc2hlZA0KY29kZS5tZW50aW9uZWQgPC0gYXMubnVtZXJpYyh0YWJsZShkYXRhLmZ1bGwkQ29kZU1lbnRpb25lZC4yKVsieWVzIl0pDQoNCiMgbnVtYmVyIG9mIGFydGljbGVzIG5vdCBtZW50aW9uaW5nIHRoYXQgY29kZSB3YXMgcHVibGlzaGVkDQpjb2RlLm5vdC5tZW50aW9uZWQgPC0gYXMubnVtZXJpYyh0YWJsZShkYXRhLmZ1bGwkQ29kZU1lbnRpb25lZC4yKVsibm8iXSkNCg0KIyBudW1iZXIgb2YgYXJ0aWNsZXMgbWVudGlvbmluZyB0aGF0IGNvZGUgd2FzIHB1Ymxpc2hlZA0KY29kZS5tZW50aW9uZWQuY29kZS5zY3JpcHQgPC0gYXMubnVtZXJpYyhzdW0odGFibGUoZGF0YS5mdWxsJENvZGVNZW50aW9uZWQpWyJ5ZXMsIGNvZGUiXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlKGRhdGEuZnVsbCRDb2RlTWVudGlvbmVkKVsieWVzLCBjb2RlIGFuZCBzY3JpcHQiXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlKGRhdGEuZnVsbCRDb2RlTWVudGlvbmVkKVsieWVzLCBzY3JpcHQiXSkpDQoNCiMgbnVtYmVyIG9mIGFydGljbGVzIG1lbnRpb25pbmcgY29kZSBhdmFpbGFiaWxpdHkgaW4gdGhlIGRhdGEgYWNjZXNzaWJpbGl0eSBhbmQvb3IgbWF0ZXJpYWxzIGFuZCBtZXRob2RzDQpjb2RlLm1lbnRpb25lZC5zZWN0aW9uLmRhdGFhY2MubWV0aG9kcyA8LSBhcy5udW1lcmljKHN1bSh0YWJsZShkYXRhLmZ1bGwkTG9jYXRpb25fQ29kZU1lbnRpb25lZClbImRhdGFhY2Nlc3NpYmlsaXR5Il0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZShkYXRhLmZ1bGwkTG9jYXRpb25fQ29kZU1lbnRpb25lZClbImRhdGFhY2Nlc3NpYmlsaXR5IGFuZCBtZXRob2RzIl0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZShkYXRhLmZ1bGwkTG9jYXRpb25fQ29kZU1lbnRpb25lZClbImRhdGFhY2Nlc3NpYmlsaXR5IGFuZCBtZXRob2RzIGFuZCBzdXBwbGVtZW50Il0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZShkYXRhLmZ1bGwkTG9jYXRpb25fQ29kZU1lbnRpb25lZClbImRhdGFhY2Nlc3NpYmlsaXR5IGFuZCBzdXBwbGVtZW50Il0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZShkYXRhLmZ1bGwkTG9jYXRpb25fQ29kZU1lbnRpb25lZClbIm1ldGhvZHMiXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlKGRhdGEuZnVsbCRMb2NhdGlvbl9Db2RlTWVudGlvbmVkKVsibWV0aG9kcyBhbmQgc3VwcGxlbWVudCJdKSkNCg0KIyBudW1iZXIgb2YgYXJ0aWNsZXMgbWVudGlvbmluZyBjb2RlIGF2YWlsYWJpbGl0eSBvbmx5IGluIHRoZSBzdXBwbGVtZW50cw0KY29kZS5tZW50aW9uZWQuc2VjdGlvbi5zdXBwbGVtZW50cyA8LSBhcy5udW1lcmljKHN1bSh0YWJsZShkYXRhLmZ1bGwkTG9jYXRpb25fQ29kZU1lbnRpb25lZClbInN1cHBsZW1lbnQiXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFibGUoZGF0YS5mdWxsJExvY2F0aW9uX0NvZGVNZW50aW9uZWQpWyJzdXBwbGVtZW50YXJ5IGZpbGVzIGRlc2NyaXB0aW9ucyJdKSkNCg0KIyBudW1iZXIgb2YgYXJ0aWNsZXMgdXNpbmcgcGVybWFuZW50IHJlcG9zaXRvcmllcyB0byBob3N0IHRoZWlyIGRhdGENCmNvZGUuaG9zdGVkLnJlcG9zaXRvcnkgPC0gYXMubnVtZXJpYyh0YWJsZShkYXRhLmZ1bGwkTG9jYXRpb25TaGFyZWQuMilbInJlcG9zaXRvcnkiXSktYXMubnVtZXJpYyh0YWJsZShkYXRhLmZ1bGwkTG9jYXRpb25TaGFyZWQpWyJ2ZXJzaW9uIGNvbnRyb2wgcGxhdGZvcm0iXSkNCg0KIyBudW1iZXIgb2YgYXJ0aWNsZXMgdXNpbmcgb25seSBub24tcGVybWFuZW50IHJlcG9zaXRvcmllcyAoaS5lLiB2ZXJzaW9uIGNvbnRyb2xsZWQgIHBsYWZvcm0gPSBHaXRIdWIpdG8gaG9zdCB0aGVpciBkYXRhDQpjb2RlLmhvc3RlZC5naXRodWIub25seSA8LSBhcy5udW1lcmljKHRhYmxlKGRhdGEuZnVsbCRMb2NhdGlvblNoYXJlZClbInZlcnNpb24gY29udHJvbCBwbGF0Zm9ybSJdKQ0KDQojIG51bWJlciBvZiBhcnRpY2xlcyB1c2luZyByZXBvc2l0b3JpZXMgdG8gaG9zdCB0aGVpciBkYXRhIGluIDIwMTUvMjAxNg0KY29kZS5ob3N0ZWQucmVwb3NpdG9yeS4yMDE1LjE2IDwtIGFzLm51bWVyaWModGFibGUoZGF0YS5mdWxsW2RhdGEuZnVsbCRQdWJsaWNhdGlvbl95ZWFyPDIwMTgsIkxvY2F0aW9uU2hhcmVkLjIiXSlbInJlcG9zaXRvcnkiXSkNCg0KIyBudW1iZXIgb2YgYXJ0aWNsZXMgdXNpbmcgcmVwb3NpdG9yaWVzIHRvIGhvc3QgdGhlaXIgZGF0YSBpbiAyMDE4LzIwMTkNCmNvZGUuaG9zdGVkLnJlcG9zaXRvcnkuMjAxOC4xOSA8LSBhcy5udW1lcmljKHRhYmxlKGRhdGEuZnVsbFtkYXRhLmZ1bGwkUHVibGljYXRpb25feWVhcj4yMDE2LCJMb2NhdGlvblNoYXJlZC4yIl0pWyJyZXBvc2l0b3J5Il0pDQoNCiMgbnVtYmVyIG9mIGFydGljbGVzIHVzaW5nIG9ubHkgdGhlIHN1cHBsZW1lbnRzIHRvIGhvc3QgdGhlaXIgZGF0YQ0KY29kZS5ob3N0ZWQuc3VwcGxlbWVudHMgPC0gYXMubnVtZXJpYyh0YWJsZShkYXRhLmZ1bGwkTG9jYXRpb25TaGFyZWQuMilbInN1cHBsZW1lbnRhcnkgZmlsZSJdKQ0KDQojIG51bWJlciBvZiBhcnRpY2xlcyB1c2luZyBleGNsdXNpdmVseSBmcmVlIHNvZnR3YXJlDQpmcmVlLnNvZnR3YXJlIDwtIGFzLm51bWVyaWModGFibGUoZGF0YS5mdWxsJEZyZWVTb2Z0d2FyZSlbInllcyJdKQ0KDQojIG51bWJlciBvZiBhcnRpY2xlcyB1c2luZyBSIGluIGNvbWJpbmF0aW9uIHdpdGggb3RoZXIgc29mdHdhcmUNClIuYW5kLm90aGVycyA8LSBhcy5udW1lcmljKHRhYmxlKHN0cl9kZXRlY3QoZGF0YS5mdWxsJFN0YXRfYW5hbHlzaXNfc29mdHdhcmUsICJSICIpKVsiVFJVRSJdKQ0KDQojIG51bWJlciBvZiBhcnRpY2xlcyB1c2luZyBvbmx5IFINClIub25seSA8LSBucm93KGRhdGEuZnVsbFtkYXRhLmZ1bGwkU3RhdF9hbmFseXNpc19zb2Z0d2FyZT09IlIiICYgIShpcy5uYShkYXRhLmZ1bGwkU3RhdF9hbmFseXNpc19zb2Z0d2FyZSkpLF0pDQoNCiMgbnVtYmVyIG9mIGFydGljbGVzIHJlcG9ydGluZyB0aGUgc29mdHdhcmUgdXNlZA0KZWxpZ2libGUuYXJ0aWNsZXMuY29kZS5yZXBvcnRpbmcuc29mdHdhcmUudXNlZCA8LSBhcy5udW1lcmljKGRhdGEuZnVsbCAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIShpcy5uYShzdGF0aXN0aWNhbC5hbmFseXNpcy5hbmQub3Iuc2ltdWxhdGlvbnMuMikpKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJpc2UoZWxpZ2libGVfYXJ0aWNsZXMgPSBzdW0oc3RhdGlzdGljYWwuYW5hbHlzaXMuYW5kLm9yLnNpbXVsYXRpb25zLjIgPT0gInllcyIgJiBTdGF0X2FuYWx5c2lzX3NvZnR3YXJlICE9ICJOb3QgU3RhdGVkIikpKQ0KDQojIG51bWJlciBvZiBhcnRpY2xlcyByZXBvcnRpbmcgdGhlIHNvZnR3YXJlIHVzZWQNCmVsaWdpYmxlLmFydGljbGVzLmNvZGUubm90LnJlcG9ydGluZy5zb2Z0d2FyZS51c2VkIDwtIGFzLm51bWVyaWMoZGF0YS5mdWxsICU+JSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIShpcy5uYShzdGF0aXN0aWNhbC5hbmFseXNpcy5hbmQub3Iuc2ltdWxhdGlvbnMuMikpKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXNlKGVsaWdpYmxlX2FydGljbGVzID0gc3VtKHN0YXRpc3RpY2FsLmFuYWx5c2lzLmFuZC5vci5zaW11bGF0aW9ucy4yID09ICJ5ZXMiICYgU3RhdF9hbmFseXNpc19zb2Z0d2FyZSA9PSAiTm90IFN0YXRlZCIpKSkNCg0KIyBjcmVhdGluZyB2ZWN0b3JzIHRvIGJ1aWxkIHRoZSBkYXRhIGZyYW1lIHdpdGgNCg0KIyB2ZWN0b3Igd2l0aCBhIG5hbWUgZm9yIGVhY2ggcGVyY2VudGFnZQ0KYWxsLm5hbWVzIDwtIGMoImFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIiwNCiAgICAgICAgICAgICAgICJhcnRpY2xlcyBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgZGF0YSIsDQogICAgICAgICAgICAgICAiam91cm5hbHMgd2l0aCBjb2RlLXNoYXJpbmcgcG9saWNpZXMgaW4gMjAxNSIsDQogICAgICAgICAgICAgICAiam91cm5hbHMgd2l0aCBjb2RlLXNoYXJpbmcgcG9saWNpZXMgaW4gMjAyMCIsDQogICAgICAgICAgICAgICAiYXJ0aWNsZXMgc2hhcmluZyBzZWVtaW5nbHkgYWxsIGNvZGUiLA0KICAgICAgICAgICAgICAgImFydGljbGVzIHNoYXJpbmcgb25seSBzb21lIGNvZGUiLA0KICAgICAgICAgICAgICAgImFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIGluIDIwMTUvMjAxNiIsDQogICAgICAgICAgICAgICAiYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUgaW4gMjAxOC8yMDE5IiwNCiAgICAgICAgICAgICAgICJhcnRpY2xlcyBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgY29kZSBwZXIgam91cm5hbCAobWluKSIsDQogICAgICAgICAgICAgICAiYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUgcGVyIGpvdXJuYWwgKG1heCkiLA0KICAgICAgICAgICAgICAgImFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIHBlciBqb3VybmFsIChtZWRpYW4pIiwNCiAgICAgICAgICAgICAgICJhcnRpY2xlcyBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgY29kZSBwZXIgam91cm5hbCAobWVhbikiLA0KICAgICAgICAgICAgICAgImFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIGFuZCBoaWdobGlnaHRpbmcgY29kZSBhdmFpbGFiaWxpdHkiLA0KICAgICAgICAgICAgICAgImFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIGFuZCBoaWdobGlnaHRpbmcgY29kZSBhdmFpbGFiaWxpdHkgdXNpbmcgY29kZSBhbmQvb3Igc2NyaXB0IiwNCiAgICAgICAgICAgICAgICJhcnRpY2xlcyBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgY29kZSBhbmQgaGlnaGxpZ2h0aW5nIGNvZGUgYXZhaWxhYmlsaXR5IGluIGRhdGEgYWNjZXNzaWJpbGl0eSBhbmQvb3IgbWV0aG9kcyBzZWN0aW9uIiwNCiAgICAgICAgICAgICAgICJhcnRpY2xlcyBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgY29kZSBhbmQgaGlnaGxpZ2h0aW5nIGNvZGUgYXZhaWxhYmlsaXR5IG9ubHkgaW4gdGhlIHN1cHBsZW1lbnRzIiwNCiAgICAgICAgICAgICAgICJhcnRpY2xlcyBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgY29kZSBhbmQgbm90IGhpZ2hsaWdodGluZyBjb2RlIGF2YWlsYWJpbGl0eSIsDQogICAgICAgICAgICAgICAiYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUgYW5kIGhvc3RpbmcgaXQgaW4gYSBwZXJtYW5lbnQgcmVwb3NpdG9yeSIsDQogICAgICAgICAgICAgICAiYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUgYW5kIGhvc3RpbmcgaXQgaW4gR2l0SHViIG9ubHkiLA0KICAgICAgICAgICAgICAgImFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIGFuZCBob3N0aW5nIGl0IG9ubHkgaW4gdGhlIHN1cHBsZW1lbnRzIiwNCiAgICAgICAgICAgICAgICJhcnRpY2xlcyBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgY29kZSBhbmQgaG9zdGluZyBpdCBpbiBhIHJlcG9zaXRvcnkgaW4gMjAxNS8yMDE2IiwNCiAgICAgICAgICAgICAgICJhcnRpY2xlcyBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgY29kZSBhbmQgaG9zdGluZyBpdCBpbiBhIHJlcG9zaXRvcnkgaW4gMjAxOC8yMDE5IiwNCiAgICAgICAgICAgICAgICJhcnRpY2xlcyB3aXRoIHRoZSBwb3RlbnRpYWwgdG8gYmUgY29tcHV0YXRpb25hbGx5IHJlcHJvZHVjaWJsZSIsDQogICAgICAgICAgICAgICAiYXJ0aWNsZXMgd2l0aCB0aGUgcG90ZW50aWFsIHRvIGJlIGNvbXB1dGF0aW9uYWxseSByZXByb2R1Y2libGUgaW4gMjAxNS8yMDE2IiwNCiAgICAgICAgICAgICAgICJhcnRpY2xlcyB3aXRoIHRoZSBwb3RlbnRpYWwgdG8gYmUgY29tcHV0YXRpb25hbGx5IHJlcHJvZHVjaWJsZSBpbiAyMDE4LzIwMTkiLA0KICAgICAgICAgICAgICAgImFydGljbGVzIHVzaW5nIGZyZWUgKG5vbi1wcm9wcmlldGFyeSkgc29mdHdhcmUiLA0KICAgICAgICAgICAgICAgImFydGljbGVzIHVzaW5nIFIiLA0KICAgICAgICAgICAgICAgImFydGljbGVzIG5vdCByZXBvcnRpbmcgdGhlIHNvZnR3YXJlIHVzZWQiKQ0KDQojIHZlY3RvciB3aXRoIGFsbCBwZXJjZW50YWdlcw0KYWxsLnBlcmNlbnRhZ2VzIDwtIHJvdW5kKA0KICBjKChhdC5sZWFzdC5zb21lLmNvZGUvZWxpZ2libGUuYXJ0aWNsZXMuY29kZSkqMTAwLA0KICAgIChhdC5sZWFzdC5zb21lLmRhdGEvZWxpZ2libGUuYXJ0aWNsZXMuZGF0YSkqMTAwLA0KICAgIChqb3VybmFscy53aXRoLnBvbGljeS4yMDE1L2pvdXJuYWxzLjIwMTUpKjEwMCwNCiAgICAoam91cm5hbHMud2l0aC5wb2xpY3kuMjAyMC9qb3VybmFscy4yMDIwKSoxMDAsDQogICAgKHNlZW1pbmdseS5hbGwuY29kZS9lbGlnaWJsZS5hcnRpY2xlcy5jb2RlKSoxMDAsDQogICAgKG9ubHkuc29tZS5jb2RlL2VsaWdpYmxlLmFydGljbGVzLmNvZGUpKjEwMCwNCiAgICAoYXQubGVhc3Quc29tZS5jb2RlLnllYXIkY29kZV9wdWJsaXNoZWRbMV0vZWxpZ2libGUuYXJ0aWNsZXMuY29kZS55ZWFyJGVsaWdpYmxlX2FydGljbGVzWzFdKSoxMDAsDQogICAgKGF0LmxlYXN0LnNvbWUuY29kZS55ZWFyJGNvZGVfcHVibGlzaGVkWzJdL2VsaWdpYmxlLmFydGljbGVzLmNvZGUueWVhciRlbGlnaWJsZV9hcnRpY2xlc1syXSkqMTAwLA0KICAgIGFzLm51bWVyaWMoc3VtbWFyeShmdWxsLmpvdXJuYWwkcGVyY2VudGFnZSlbIk1pbi4iXSksDQogICAgYXMubnVtZXJpYyhzdW1tYXJ5KGZ1bGwuam91cm5hbCRwZXJjZW50YWdlKVsiTWF4LiJdKSwNCiAgICBhcy5udW1lcmljKHN1bW1hcnkoZnVsbC5qb3VybmFsJHBlcmNlbnRhZ2UpWyJNZWRpYW4iXSksDQogICAgYXMubnVtZXJpYyhzdW1tYXJ5KGZ1bGwuam91cm5hbCRwZXJjZW50YWdlKVsiTWVhbiJdKSwNCiAgICAoY29kZS5tZW50aW9uZWQvYXQubGVhc3Quc29tZS5jb2RlKSoxMDAsDQogICAgKGNvZGUubWVudGlvbmVkLmNvZGUuc2NyaXB0L2NvZGUubWVudGlvbmVkKSoxMDAsDQogICAgKGNvZGUubWVudGlvbmVkLnNlY3Rpb24uZGF0YWFjYy5tZXRob2RzL2NvZGUubWVudGlvbmVkKSoxMDAsDQogICAgKGNvZGUubWVudGlvbmVkLnNlY3Rpb24uc3VwcGxlbWVudHMvY29kZS5tZW50aW9uZWQpKjEwMCwNCiAgICAoY29kZS5ub3QubWVudGlvbmVkL2F0LmxlYXN0LnNvbWUuY29kZSkqMTAwLA0KICAgIChjb2RlLmhvc3RlZC5yZXBvc2l0b3J5L2F0LmxlYXN0LnNvbWUuY29kZSkqMTAwLA0KICAgIChjb2RlLmhvc3RlZC5naXRodWIub25seS9hdC5sZWFzdC5zb21lLmNvZGUpKjEwMCwNCiAgICAoY29kZS5ob3N0ZWQuc3VwcGxlbWVudHMvYXQubGVhc3Quc29tZS5jb2RlKSoxMDAsDQogICAgKGNvZGUuaG9zdGVkLnJlcG9zaXRvcnkuMjAxNS4xNi9hdC5sZWFzdC5zb21lLmNvZGUueWVhciRjb2RlX3B1Ymxpc2hlZFsxXSkqMTAwLA0KICAgIChjb2RlLmhvc3RlZC5yZXBvc2l0b3J5LjIwMTguMTkvYXQubGVhc3Quc29tZS5jb2RlLnllYXIkY29kZV9wdWJsaXNoZWRbMl0pKjEwMCwNCiAgICAoc2VlbWluZ2x5LmFsbC5jb2RlLmFuZC5kYXRhL2VsaWdpYmxlLmFydGljbGVzLmNvZGUpKjEwMCwNCiAgICAoc2VlbWluZ2x5LmFsbC5jb2RlLmFuZC5kYXRhLnllYXIkY29kZV9hbmRfZGF0YV9wdWJsaXNoZWRbMV0vZWxpZ2libGUuYXJ0aWNsZXMuY29kZS55ZWFyJGVsaWdpYmxlX2FydGljbGVzWzFdKSoxMDAsDQogICAgKHNlZW1pbmdseS5hbGwuY29kZS5hbmQuZGF0YS55ZWFyJGNvZGVfYW5kX2RhdGFfcHVibGlzaGVkWzJdL2VsaWdpYmxlLmFydGljbGVzLmNvZGUueWVhciRlbGlnaWJsZV9hcnRpY2xlc1syXSkqMTAwLA0KICAgIChmcmVlLnNvZnR3YXJlL2VsaWdpYmxlLmFydGljbGVzLmNvZGUucmVwb3J0aW5nLnNvZnR3YXJlLnVzZWQpKjEwMCwNCiAgICAoKFIuYW5kLm90aGVycytSLm9ubHkpL2VsaWdpYmxlLmFydGljbGVzLmNvZGUucmVwb3J0aW5nLnNvZnR3YXJlLnVzZWQpKjEwMCwNCiAgICAoZWxpZ2libGUuYXJ0aWNsZXMuY29kZS5ub3QucmVwb3J0aW5nLnNvZnR3YXJlLnVzZWQvZWxpZ2libGUuYXJ0aWNsZXMuY29kZSkqMTAwKSwwKQ0KDQojIHZlY3RvciB3aXRoIGFsbCBudW1lcmF0b3JzIGZvciBjYWxjdWxhdGluZyB0aGUgcGVyY2VudGFnZQ0KYWxsLm51bWVyYXRvcnMgPC0gYygiI2VsaWdpYmxlIGFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIiwNCiAgICAgICAgICAgICAgICAgICAgIiNlbGlnaWJsZSBhcnRpY2xlcyBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgZGF0YSIsDQogICAgICAgICAgICAgICAgICAgICIjam91cm5hbHMgd2l0aCBjb2RlLXNoYXJpbmcgcG9saWNpZXMgaW4gMjAxNSIsDQogICAgICAgICAgICAgICAgICAgICIjam91cm5hbHMgd2l0aCBjb2RlLXNoYXJpbmcgcG9saWNpZXMgaW4gMjAyMCIsDQogICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBzZWVtaW5nbHkgYWxsIGNvZGUiLA0KICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHNoYXJpbmcgb25seSBzb21lIGNvZGUiLA0KICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIGluIDIwMTUvMjAxNiIsDQogICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUgaW4gMjAxOC8yMDE5IiwNCiAgICAgICAgICAgICAgICAgICAgIiNlbGlnaWJsZSBhcnRpY2xlcyBwZXIgam91cm5hbCBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgY29kZSIsDQogICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgcGVyIGpvdXJuYWwgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUiLA0KICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHBlciBqb3VybmFsIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIiwNCiAgICAgICAgICAgICAgICAgICAgIiNlbGlnaWJsZSBhcnRpY2xlcyBwZXIgam91cm5hbCBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgY29kZSIsDQogICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUgdGhhdCBoaWdobGlnaHRlZCBjb2RlIGF2YWlsYWJpbGl0eSIsDQogICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUgdGhhdCBoaWdobGlnaHRlZCBjb2RlIGF2YWlsYWJpbGl0eSB1c2luZyBjb2RlIGFuZC9vciBzY3JpcHQiLA0KICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIHRoYXQgaGlnaGxpZ2h0ZWQgY29kZSBhdmFpbGFiaWxpdHkgaW4gZGF0YSBhY2Nlc3NpYmlsaXR5IGFuZC9vciBtZXRob2RzIHNlY3Rpb24iLA0KICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIHRoYXQgaGlnaGxpZ2h0ZWQgY29kZSBhdmFpbGFiaWxpdHkgb25seSBpbiB0aGUgc3VwcGxlbWVudHMiLA0KICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIHRoYXQgZGlkIG5vdCBoaWdobGlnaHRlZCBjb2RlIGF2YWlsYWJpbGl0eSIsDQogICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUgYW5kIGhvc3RpbmcgaXQgaW4gYSByZXBvc2l0b3J5IiwNCiAgICAgICAgICAgICAgICAgICAgIiNlbGlnaWJsZSBhcnRpY2xlcyBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgY29kZSBhbmQgaG9zdGluZyBpdCBpbiBHaXRIdWIgb25seSIsDQogICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUgYW5kIGhvc3RpbmcgaXQgb25seSBpbiB0aGUgc3VwcGxlbWVudHMiLA0KICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIGFuZCBob3N0aW5nIGl0IGluIGEgcmVwb3NpdG9yeSBvciBHaXRIdWIgb25seSBpbiAyMDE1LzIwMTYiLA0KICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIGFuZCBob3N0aW5nIGl0IGluIGEgcmVwb3NpdG9yeSBvciBHaXRIdWIgb25seSBpbiAyMDE4LzIwMTkiLA0KICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHNoYXJpbmcgc2VlbWluZ2x5IGFsbCBjb2RlIGFuZCBkYXRhIChpZiBhbnkgdXNlZCkiLA0KICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHdpdGggdGhlIHBvdGVudGlhbCB0byBiZSBjb21wdXRhdGlvbmFsbHkgcmVwcm9kdWNpYmxlIGluIDIwMTUvMjAxNiIsDQogICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgd2l0aCB0aGUgcG90ZW50aWFsIHRvIGJlIGNvbXB1dGF0aW9uYWxseSByZXByb2R1Y2libGUgaW4gMjAxOC8yMDE5IiwNCiAgICAgICAgICAgICAgICAgICAgIiNlbGlnaWJsZSBhcnRpY2xlcyB1c2luZyBmcmVlIChub24tcHJvcHJpZXRhcnkpIHNvZnR3YXJlIiwNCiAgICAgICAgICAgICAgICAgICAgIiNlbGlnaWJsZSBhcnRpY2xlcyB1c2luZyBSIGFsb25lIG9yIHRvZ2V0aGVyIHdpdGggb3RoZXIgc29mdHdhcmUiLA0KICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIG5vdCByZXBvcnRpbmcgdGhlIHNvZnR3YXJlIHVzZWQiKQ0KDQojIHZlY3RvciB3aXRoIGFsbCBkZW5vbWluYXRvcnMgZm9yIGNhbGN1bGF0aW5nIHRoZSBwZXJjZW50YWdlDQphbGwuZGVub21pbmF0b3JzIDwtIGMoIiNlbGlnaWJsZSBhcnRpY2xlcyIsDQogICAgICAgICAgICAgICAgICAgICAgIiNlbGlnaWJsZSBhcnRpY2xlcyB0aGF0IHVzZWQgZGF0YSIsDQogICAgICAgICAgICAgICAgICAgICAgIiNqb3VybmFscyByZXZpZXdlZCBpbiAyMDE1IiwNCiAgICAgICAgICAgICAgICAgICAgICAiI2pvdXJuYWxzIHJldmlld2VkIGFuZCBzdGlsbCBleGlzdGluZyBpbiAyMDIwIiwNCiAgICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIGluIDIwMTUvMjAxNiIsDQogICAgICAgICAgICAgICAgICAgICAgIiNlbGlnaWJsZSBhcnRpY2xlcyBpbiAyMDE4LzIwMTkiLA0KICAgICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgcGVyIGpvdXJuYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgcGVyIGpvdXJuYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgcGVyIGpvdXJuYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgcGVyIGpvdXJuYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUiLA0KICAgICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUgdGhhdCBoaWdobGlnaHRlZCBjb2RlIGF2YWlsYWJpbGl0eSIsDQogICAgICAgICAgICAgICAgICAgICAgIiNlbGlnaWJsZSBhcnRpY2xlcyBzaGFyaW5nIGF0IGxlYXN0IHNvbWUgY29kZSB0aGF0IGhpZ2hsaWdodGVkIGNvZGUgYXZhaWxhYmlsaXR5IiwNCiAgICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIHRoYXQgaGlnaGxpZ2h0ZWQgY29kZSBhdmFpbGFiaWxpdHkiLA0KICAgICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUiLA0KICAgICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUiLA0KICAgICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUiLA0KICAgICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUiLA0KICAgICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUgaW4gMjAxNS8yMDE2IiwNCiAgICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlIGluIDIwMTgvMjAxOSIsDQogICAgICAgICAgICAgICAgICAgICAgIiNlbGlnaWJsZSBhcnRpY2xlcyIsDQogICAgICAgICAgICAgICAgICAgICAgIiNlbGlnaWJsZSBhcnRpY2xlcyBpbiAyMDE1LzIwMTYiLA0KICAgICAgICAgICAgICAgICAgICAgICIjZWxpZ2libGUgYXJ0aWNsZXMgaW4gMjAxOC8yMDE5IiwNCiAgICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHJlcG9ydGluZyBzb2Z0d2FyZSB1c2VkIiwNCiAgICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIHJlcG9ydGluZyBzb2Z0d2FyZSB1c2VkIiwNCiAgICAgICAgICAgICAgICAgICAgICAiI2VsaWdpYmxlIGFydGljbGVzIikNCg0KIyBwdXR0aW5nIHRvZ2V0aGVyIHRhYmxlUzIgYW5kIHJlbmFtaW5nIGNvbHVtbnMNCnRhYmxlUzIgPC0gYXMuZGF0YS5mcmFtZShjYmluZChhbGwubmFtZXMsYWxsLnBlcmNlbnRhZ2VzLGFsbC5udW1lcmF0b3JzLGFsbC5kZW5vbWluYXRvcnMpKQ0KbmFtZXModGFibGVTMikgPC0gYygiTmFtZSIsIiUiLCJOdW1lcmF0b3IiLCJEZW5vbWluYXRvciIpDQpgYGANCg0KKipUYWJsZSBTMioqLiBMaXN0IG9mIGFsbCBwZXJjZW50YWdlcyB0aGF0IHdlIGNhbGN1bGF0ZWQgZnJvbSBvdXIgZGF0YSwgYW5kIHByZXNlbnRlZCBpbiB0aGUgbWFpbiBtYW51c2NyaXB0LCBhbmQgaG93IHRoZXkgd2VyZSBjYWxjdWxhdGVkIHRvIGF2b2lkIGFueSBtaXN1bmRlcnN0YW5kaW5nLiBWYWx1ZXMgc29ydGVkIGJ5IHRoZSBvcmRlciBvZiBhcHBlYXJhbmNlIGluIHRoZSBtYWluIG1hbnVzY3JpcHQgKGluY2x1ZGluZyB0aGUgYWJzdHJhY3QpLg0KDQpgYGB7cn0NCiMgcHJpbnRpbmcgVGFibGUgUzINCnRhYmxlUzIgJT4lIGthYmxlKCJodG1sIikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjUwMHB4IikNCmBgYA0KDQojIyMgMi4yIC0gSm91cm5hbHMnIGNvZGUtc2hhcmluZyBjb21wbGlhbmNlDQoNCioqVGFibGUgUzMqKi4gTGlzdCBvZiBgciB0YWJsZShqb3VybmFsLnBvbGljaWVzJFJlcXVpcmUuY29tcHV0ZXIuY29kZS53aXRoLnB1YmxpY2F0aW9uXzIwMTUpWydZZXMnXWAgZWNvbG9naWNhbCBqb3VybmFscyByZXZpZXdlZCBpbiB0aGlzIHN0dWR5IGFuZCB0aGVpciBjb2RlLXNoYXJpbmcgcG9saWNpZXMgKHVwZGF0ZWQgaW4gTWFyY2ggMjAyMCksIG51bWJlciBvZiBhcnRpY2xlcyB3ZSByZXZpZXdlZCwgbnVtYmVyIG9mIGFydGljbGVzIHNoYXJpbmcgYXQgbGVhc3Qgc29tZSBjb2RlLCBhbmQgdGhlIHBlcmNlbnRhZ2Ugb2YgYXJ0aWNsZXMgc2hhcmluZyBhdCBsZWFzdCBzb21lIGNvZGUgKHNlZSBhbHNvIEZpZ3VyZSAyIGluIHRoZSBtYWluIHRleHQpLg0KYGBge3J9DQojIGltcG9ydCBqb3VybmFsIGluZm9ybWF0aW9uIGFuZCBhYmJyZXZpYXRpb25zDQpqb3VybmFsLmluZm8gPC0gcmVhZC50YWJsZSgiZGF0YS9qb3VybmFsc19pbmZvX3YyLmNzdiIsaGVhZGVyPVQsc2VwPSIsIikNCg0KIyBtZXJnaW5nIGpvdXJuYWwgaW5mbyB0byBwZXJjZW50YWdlcw0KZnVsbC5qb3VybmFsLmluZm8gPC0gbWVyZ2UoZnVsbC5qb3VybmFsLGpvdXJuYWwuaW5mbykNCg0KIyByZW1vdmluZyBmdWxsIGNhcGl0YWxpemF0aW9uIG9mIGpvdXJuYWwgbmFtZXMgdXNpbmcgdGhlIGZvbGxvd2luZyBmdW5jdGlvbg0KIyB3aGljaCB3YXMgb2J0YWluZWQgZnJvbTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNjM2NDc4My9jYXBpdGFsaXplLXRoZS1maXJzdC1sZXR0ZXItb2YtYm90aC13b3Jkcy1pbi1hLXR3by13b3JkLXN0cmluZw0Kc2ltcGxlQ2FwIDwtIGZ1bmN0aW9uKHgpIHsNCiAgcyA8LSBzdHJzcGxpdCh4LCAiICIpW1sxXV0NCiAgcGFzdGUodG91cHBlcihzdWJzdHJpbmcocywgMSwxKSksIHN1YnN0cmluZyhzLCAyKSwNCiAgICAgICAgc2VwPSIiLCBjb2xsYXBzZT0iICIpDQp9DQoNCmZ1bGwuam91cm5hbC5pbmZvJEpvdXJuYWw8LSBzYXBwbHkodG9sb3dlcihmdWxsLmpvdXJuYWwuaW5mbyRKb3VybmFsKSxzaW1wbGVDYXApDQoNCmZ1bGwuam91cm5hbC5pbmZvJEpvdXJuYWwgPC0gaWZlbHNlKGZ1bGwuam91cm5hbC5pbmZvJEpvdXJuYWw9PSJQcm9jZWVkaW5ncyBPZiBUaGUgUm95YWwgU29jaWV0eSBCLWJpb2xvZ2ljYWwgU2NpZW5jZXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlByb2NlZWRpbmdzIE9mIFRoZSBSb3lhbCBTb2NpZXR5IEItQmlvbG9naWNhbCBTY2llbmNlcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdWxsLmpvdXJuYWwuaW5mbyRKb3VybmFsKQ0KDQojIHByaW50aW5nIHRhYmxlIFMzDQpmdWxsLmpvdXJuYWwuaW5mbyAlPiUgc2VsZWN0KEpvdXJuYWwsUG9saWN5LHRvdGFsLGNvZGVwdWJsaXNoZWQscGVyY2VudGFnZSkgJT4lIHJlbmFtZSgnQ29kZS1zaGFyaW5nIHBvbGljeSc9UG9saWN5LCcjYXJ0aWNsZXMgcmV2aWV3ZWQnPXRvdGFsLCcjYXJ0aWNsZXMgc2hhcmluZyBjb2RlJz1jb2RlcHVibGlzaGVkLCAnJSBhcnRpY2xlcyBzaGFyaW5nIGNvZGUnPXBlcmNlbnRhZ2UpICU+JSBhcnJhbmdlKEpvdXJuYWwpICU+JSBrYWJsZSgiaHRtbCIpICU+JSBrYWJsZV9zdHlsaW5nKCkgJT4lIHNjcm9sbF9ib3god2lkdGggPSAiMTAwJSIsIGhlaWdodCA9ICI1MDBweCIpDQpgYGANCg0KIyMgUiBTZXNzaW9uIEluZm9ybWF0aW9uDQoNClIgc2Vzc2lvbiBpbmZvcm1hdGlvbiBkZXRhaWxpbmcgdGhlIHZlcnNpb25zIGFuZCBwYWNrYWdlcyB1c2VkIGluIHRoaXMgc2NyaXB0IGZvciByZXByb2R1Y2liaWxpdHkgcHVycG9zZXMuDQoNCmBgYHtyfQ0Kc2Vzc2lvbkluZm8oKSAlPiUgcGFuZGVyKCkNCmBgYA0KDQojIyBSZWZlcmVuY2Vz