Introduction
This document is an exploratory analysis of all accepted full papers, and posters at the GIScience conference series. The analysis is based on the text analysis published in “Reproducible research and GIScience: an evaluation using AGILE conference papers” (https://doi.org/10.7717/peerj.5072).
library("here")
library("pdftools")
library("stringr")
library("tidyverse")
library("tidytext")
library("wordcloud")
library("RColorBrewer")
library("grid")
library("gridBase")
library("gridExtra")
library("kableExtra")
library("quanteda")
# for deterministic cloud rendering
set.seed(nchar("International Conference on Geographic Information Science"))
Load data
List of proceedings
- Proceedings 10th International Conference on Geographic Information Science (GIScience 2018). 2018. Winter, S., Griffin, A., Sester, M. (Eds.), LIPICS Vol. 114. ISBN 978-3-95977-083-5. http://www.dagstuhl.de/dagpub/978-3-95977-083-5
- Geographic Information Science. 2016. J. A. Miller, D. O’Sullivan, & N. Wiegand (Eds.), Lecture Notes in Computer Science. Springer International Publishing. https://doi.org/10.1007/978-3-319-45738-3
- Geographic Information Science. 2014. M. Duckham, E. Pebesma, K. Stewart, & A. U. Frank (Eds.), Lecture Notes in Computer Science. Springer International Publishing. https://doi.org/10.1007/978-3-319-11593-1
- Geographic Information Science. 2012. N. Xiao, M.-P. Kwan, M. F. Goodchild, & S. Shekhar (Eds.), Lecture Notes in Computer Science. Springer Berlin Heidelberg. https://doi.org/10.1007/978-3-642-33024-7
- Geographic Information Science. 2010. Fabrikant, S.I., Reichenbacher, T., Kreveld, M. van, Schlieder, C. (Eds.), Lecture Notes in Computer Science. Springer Berlin Heidelberg. https://doi.org/10.1007/978-3-642-15300-6
- Geographic Information Science. 2008. In Cova, T.J., Miller, H.J., Beard, K., Frank, A.U., Goodchild, M.F. (Eds.), Lecture Notes in Computer Science. Springer Berlin Heidelberg. https://doi.org/10.1007/978-3-540-87473-7
- Geographic Information Science. 2004. Egenhofer, M.J., Freksa, C., Miller, H.J. (Eds.), Lecture Notes in Computer Science. Springer Berlin Heidelberg. https://doi.org/10.1007/b101397
- Geographic Information Science. 2002. Egenhofer, M.J., Mark, D.M. (Eds.), Lecture Notes in Computer Science. Springer Berlin Heidelberg. https://doi.org/10.1007/3-540-45799-2
- Geographic Information Science. 2006. Raubal, M., Miller, H.J., Frank, A.U., Goodchild, M.F. (Eds.), Lecture Notes in Computer Science. Springer Berlin Heidelberg. https://doi.org/10.1007/11863939
LNCS proceedings are available at the publisher website: https://link.springer.com/conference/giscience.
Note: The 2018 proceedings include the short papers in the same document. For comparability, only the full papers are taken into account for the analysis below.
data_path <- here::here("proceedings")
proceedings <- c(
"2002" = "geographic-information-science-2002.pdf",
"2004" = "geographic-information-science-2004.pdf",
"2006" = "geographic-information-science-2006.pdf",
"2008" = "geographic-information-science-2008.pdf",
"2010" = "geographic-information-science-2010.pdf",
"2012" = "10.1007_978-3-642-33024-7.pdf",
"2014" = "10.1007_978-3-319-11593-1.pdf",
"2016" = "10.1007_978-3-319-45738-3.pdf",
"2018" = "lipics-vol114-giscience2018-complete.pdf"
)
proceedings_files <- file.path(data_path, proceedings)
names(proceedings_files) <- names(proceedings)
Add the PDFs to a directory called /home/rstudio/proceedings
next to the file giscience-historic-text-analysis.Rmd
(this file). The proceedings of the papers are not openly available for the years 2012 to 2016. You can contact the original paper authors and ask for the test dataset to reproduce the full analysis. Alternatively, you can download the 2018 proceedings from the LIPIcs website (Open Access; direct PDF link) and conduct the analysis with that subset of the data. For the analysis below the following input files were used:
knitr::kable(tibble(year = names(proceedings), file = proceedings)) %>%
kableExtra::kable_styling("striped", full_width = FALSE)
year
|
file
|
2002
|
geographic-information-science-2002.pdf
|
2004
|
geographic-information-science-2004.pdf
|
2006
|
geographic-information-science-2006.pdf
|
2008
|
geographic-information-science-2008.pdf
|
2010
|
geographic-information-science-2010.pdf
|
2012
|
10.1007_978-3-642-33024-7.pdf
|
2014
|
10.1007_978-3-319-11593-1.pdf
|
2016
|
10.1007_978-3-319-45738-3.pdf
|
2018
|
lipics-vol114-giscience2018-complete.pdf
|
# Code not evaluated when document is rendered!
dir.create(data_path, showWarnings = FALSE)
library("googledrive")
drive_dir <- googledrive::drive_get("https://drive.google.com/drive/folders/17EUtM_zCx1gQMea1MHN_5XSVrssxv9GA")
drive_dir_contents <- googledrive::drive_ls(drive_dir)
for (i in rownames(drive_dir_contents)) {
current <- drive_dir_contents[i,]
if(endsWith(current$name, ".pdf"))
googledrive::drive_download(as_id(current$id), file.path(data_path, current$name))
}
The text is extracted from PDFs and it is processed to create a tidy data structure without stop words. The stop words include specific words, such as university
, which is included in many pages, abbreviations such as e.g.
, and terms particular to scientific articles, such as figure
. Also all numeric literas are removed from the word list.
texts <- lapply(proceedings_files, pdftools::pdf_text)
if(params$with_sp) {
texts[["2018-sp"]] <- texts[["2018"]][c(283:length(texts[["2018"]]))]
proceedings_files <- c(proceedings_files, `2018-sp` = proceedings_files[[4]])
}
# don't include short papers in 2018 year
texts[["2018"]] <- texts[["2018"]][c(1:282)]
texts <- unlist(lapply(texts, stringr::str_c, collapse = TRUE))
tidy_texts <- tibble::tibble(year = names(texts),
path = proceedings_files,
text = texts)
# create a table of all words
all_words <- tidy_texts %>%
dplyr::select(year, text) %>%
tidytext::unnest_tokens(word, text)
# remove stop words and remove numbers
my_stop_words <- tibble::tibble(
word = c(
"et",
"al",
"fig",
"e.g",
"i.e",
"http",
"ing",
"pp",
"figure",
"based",
"conference",
"university",
"table"
),
lexicon = "giscience"
)
all_stop_words <- stop_words %>%
dplyr::bind_rows(my_stop_words)
suppressWarnings({
no_numbers <- all_words %>%
dplyr::filter(is.na(as.numeric(word)))
})
no_stop_words <- no_numbers %>%
dplyr::anti_join(all_stop_words, by = "word")
total_words = nrow(no_numbers)
after_cleanup = nrow(no_stop_words)
About 50 % of the words are considered stop words. The following tables shows how many non-stop words each conference year has, sorted by number of non-stop words (descending).
nonstopwords_per_year <- no_stop_words %>%
dplyr::group_by(year) %>%
dplyr::summarise(words = n()) %>%
dplyr::arrange(desc(words)) %>%
dplyr::rename(`non-stop words` = words)
words_per_year <- no_numbers %>%
dplyr::group_by(year) %>%
dplyr::summarise(words = n()) %>%
dplyr::arrange(desc(words)) %>%
dplyr::rename(`all words` = words)
dplyr::inner_join(nonstopwords_per_year, words_per_year, by = "year") %>%
dplyr::bind_rows(tibble(year = "Total",
`non-stop words` = sum(nonstopwords_per_year$`non-stop words`),
`all words` = sum(words_per_year$`all words`))) %>%
knitr::kable() %>%
kableExtra::kable_styling("striped", full_width = FALSE) %>%
kableExtra::row_spec(nrow(nonstopwords_per_year) + 1, bold = TRUE)
year
|
non-stop words
|
all words
|
2006
|
80336
|
168616
|
2014
|
74995
|
149063
|
2012
|
73440
|
141769
|
2004
|
68060
|
134234
|
2016
|
66642
|
130669
|
2008
|
64056
|
131032
|
2018
|
62111
|
121388
|
2002
|
58636
|
117016
|
2010
|
55408
|
110342
|
Total
|
603684
|
1204129
|
Top wordstems and wordstem clouds
# chosen manually
minimum_occurence <- 99
max_words <- 100
The following table shows the number of occurence for the 100 most occuring wordstems across all proceedings.
wordstems <- no_stop_words %>%
dplyr::mutate(wordstem = quanteda::char_wordstem(no_stop_words$word))
countYearsUsingWordstem <- function(the_word) {
sapply(the_word, function(w) {
wordstems %>%
dplyr::filter(wordstem == w) %>%
dplyr::group_by(year) %>%
dplyr::count() %>%
nrow
})
}
top_wordstems <- wordstems %>%
dplyr::group_by(wordstem) %>%
dplyr::tally() %>%
dplyr::arrange(desc(n)) %>%
head(n = max_words) %>%
dplyr::mutate(`years w/ wordstem` = countYearsUsingWordstem(wordstem)) %>%
tibble::add_column(place = c(1:nrow(.)), .before = 0)
write.csv(top_wordstems, here::here("results/text_analysis_topwordstems.csv"), row.names = FALSE)
top_wordstems %>%
knitr::kable() %>%
kableExtra::kable_styling("striped", full_width = FALSE) %>%
kableExtra::scroll_box(height = "300px")
place
|
wordstem
|
n
|
years w/ wordstem
|
1
|
data
|
7087
|
9
|
2
|
spatial
|
5442
|
9
|
3
|
model
|
4249
|
9
|
4
|
relat
|
4063
|
9
|
5
|
time
|
3547
|
9
|
6
|
inform
|
3419
|
9
|
7
|
set
|
3334
|
9
|
8
|
map
|
3331
|
9
|
9
|
object
|
2962
|
9
|
10
|
network
|
2653
|
9
|
11
|
locat
|
2642
|
9
|
12
|
region
|
2560
|
9
|
13
|
geograph
|
2553
|
9
|
14
|
comput
|
2347
|
9
|
15
|
result
|
2301
|
9
|
16
|
space
|
2267
|
9
|
17
|
algorithm
|
2234
|
9
|
18
|
node
|
2191
|
9
|
19
|
approach
|
1957
|
9
|
20
|
system
|
1938
|
9
|
21
|
rout
|
1904
|
9
|
22
|
true
|
1901
|
9
|
23
|
type
|
1890
|
9
|
24
|
method
|
1886
|
9
|
25
|
distanc
|
1824
|
9
|
26
|
edg
|
1824
|
9
|
27
|
queri
|
1721
|
9
|
28
|
process
|
1683
|
9
|
29
|
similar
|
1678
|
9
|
30
|
user
|
1600
|
9
|
31
|
repres
|
1560
|
9
|
32
|
intersect
|
1521
|
9
|
33
|
section
|
1521
|
9
|
34
|
analysi
|
1499
|
9
|
35
|
line
|
1487
|
9
|
36
|
road
|
1458
|
9
|
37
|
ontolog
|
1442
|
9
|
38
|
direct
|
1431
|
9
|
39
|
structur
|
1429
|
9
|
40
|
featur
|
1331
|
9
|
41
|
graph
|
1331
|
9
|
42
|
function
|
1319
|
9
|
43
|
measur
|
1315
|
9
|
44
|
pattern
|
1307
|
9
|
45
|
label
|
1293
|
9
|
46
|
research
|
1278
|
9
|
47
|
tempor
|
1276
|
9
|
48
|
paper
|
1224
|
9
|
49
|
event
|
1202
|
9
|
50
|
studi
|
1201
|
9
|
51
|
ed
|
1198
|
9
|
52
|
refer
|
1175
|
9
|
53
|
concept
|
1151
|
9
|
54
|
level
|
1148
|
9
|
55
|
path
|
1142
|
9
|
56
|
cell
|
1097
|
9
|
57
|
semant
|
1097
|
9
|
58
|
generat
|
1091
|
9
|
59
|
applic
|
1078
|
9
|
60
|
topolog
|
1048
|
9
|
61
|
provid
|
1036
|
9
|
62
|
class
|
1024
|
9
|
63
|
scienc
|
1009
|
9
|
64
|
intern
|
1008
|
9
|
65
|
oper
|
1003
|
9
|
66
|
requir
|
1000
|
9
|
67
|
boundari
|
992
|
9
|
68
|
term
|
988
|
9
|
69
|
local
|
978
|
9
|
70
|
develop
|
977
|
9
|
71
|
includ
|
966
|
9
|
72
|
defin
|
953
|
9
|
73
|
sensor
|
945
|
9
|
74
|
valu
|
923
|
9
|
75
|
chang
|
922
|
9
|
76
|
step
|
922
|
9
|
77
|
appli
|
915
|
9
|
78
|
gis
|
912
|
9
|
79
|
select
|
906
|
9
|
80
|
instanc
|
901
|
9
|
81
|
complex
|
900
|
9
|
82
|
scale
|
898
|
9
|
83
|
segment
|
891
|
9
|
84
|
environ
|
885
|
9
|
85
|
dataset
|
881
|
9
|
86
|
databas
|
876
|
9
|
87
|
connect
|
872
|
9
|
88
|
φ
|
872
|
5
|
89
|
represent
|
862
|
9
|
90
|
differ
|
857
|
8
|
91
|
size
|
845
|
9
|
92
|
cluster
|
843
|
9
|
93
|
decis
|
843
|
9
|
94
|
attribut
|
841
|
9
|
95
|
search
|
839
|
9
|
96
|
perform
|
830
|
9
|
97
|
properti
|
828
|
9
|
98
|
support
|
824
|
9
|
99
|
experi
|
820
|
9
|
100
|
distribut
|
813
|
9
|
The following clouds and table are based on word stems extracted with a stemming algorithm from package quanteda
. Words must occur at least 99 times to be included in the cloud. Each cloud has a maximum of 100 words.
cloud_wordstems <- wordstems %>%
dplyr::group_by(year, wordstem) %>%
dplyr::tally() %>%
dplyr::arrange(desc(n))
# plot is created to file to fit more words to a specific pixel size
png(filename = here::here("results/text_analysis_wordstemclouds.png"),
width = 1000,
height = 1000)
par(mfrow = c(3,3))
for (the_year in names(proceedings)) {
year_cloud_wordstems <- cloud_wordstems %>%
dplyr::filter(year == the_year) %>%
dplyr::filter(n >= minimum_occurence) %>%
head(n = max_words)
#cat(str(year_cloud_wordstems))
wordcloud::wordcloud(words = year_cloud_wordstems$wordstem,
freq = year_cloud_wordstems$n,
min.freq = 1,
random.order = FALSE,
fixed.asp = FALSE,
rot.per = 0,
color = brewer.pal(8, "Dark2"))
}
dev.off()
## png
## 2
file.copy(from = here::here("results/text_analysis_wordstemclouds.png"),
to = here::here("docs/text_analysis_wordstemclouds.png"),
overwrite = TRUE)
## [1] TRUE
World clouds of full papers per conference year (rowwise, starting top left, from 2002 to 2018).
Reproducible research-related keywordstems in GIScience papers
The following tables lists how often wordstems of terms related to reproducible research appear in each document. The detection matches full words using regex option \b
.
- reproduc (
reproduc.*
, reproducibility, reproducible, reproduce, reproduction)
- replic (
replicat.*
, i.e. replication, replicate)
- repeatab (
repeatab.*
, i.e. repeatability, repeatable)
- software
- (pseudo) code/script(s) [column name code]
- algorithm (
algorithm.*
, i.e. algorithms, algorithmic)
- process (
process.*
, i.e. processing, processes, preprocessing)
- data (
data.*
, i.e. dataset(s), database(s))
- result(s) (
results?
)
- repository(ies) (
repositor(y|ies)
)
- collaboration platforms (
git(hub|lab)
)
tidy_texts_lower <- stringr::str_to_lower(tidy_texts$text)
word_counts <- tibble::tibble(
year = tidy_texts$year,
`words` = str_count(tidy_texts_lower, "\\b.*\\b"),
`reproduc..` = str_count(tidy_texts_lower, "\\breproduc.*\\b"),
`replic..` = str_count(tidy_texts_lower, "\\breplicat.*\\b"),
`repeatab..` = str_count(tidy_texts_lower, "\\brepeatab.*\\b"),
`code` = str_count(tidy_texts_lower,
"(\\bcode\\b|\\bscript.*\\b|\\bpseudo\ code\\b)"),
software = str_count(tidy_texts_lower, "\\bsoftware\\b"),
`algorithm(s)` = str_count(tidy_texts_lower, "\\balgorithm.*\\b"),
`(pre)process..` = str_count(tidy_texts_lower,
"(\\bprocess.*\\b|\\bpreprocess.*\\b|\\bpre-process.*\\b)"),
`data.*` = str_count(tidy_texts_lower, "\\bdata.*\\b"),
`result(s)` = str_count(tidy_texts_lower, "\\bresults?\\b"),
`repository/ies` = str_count(tidy_texts_lower, "\\brepositor(y|ies)\\b"),
#`repos` = str_count(tidy_texts_lower, "\\bzenodo|figshare|osf|dryad\\b"),
`github/lab` = str_count(tidy_texts_lower, "\\bgit(hub|lab)\\b")
)
word_counts_sums <- rbind(word_counts,
word_counts %>%
dplyr::summarise_if(is.numeric, funs(sum)) %>%
tibble::add_column(year = "Total", .before = 0))
write.csv(word_counts_sums, here::here("results/text_analysis_keywordstems.csv"), row.names = FALSE)
word_counts_sums %>%
knitr::kable() %>%
kableExtra::kable_styling("striped", font_size = 10, bootstrap_options = "condensed") %>%
kableExtra::row_spec(0, font_size = "x-small", bold = T) %>%
kableExtra::row_spec(nrow(word_counts_sums), bold = T)
year
|
words
|
reproduc..
|
replic..
|
repeatab..
|
code
|
software
|
algorithm(s)
|
(pre)process..
|
data.*
|
result(s)
|
repository/ies
|
github/lab
|
2002
|
23782
|
6
|
2
|
0
|
11
|
61
|
191
|
150
|
897
|
129
|
62
|
0
|
2004
|
26728
|
4
|
1
|
0
|
34
|
50
|
138
|
258
|
849
|
263
|
4
|
0
|
2006
|
32758
|
6
|
0
|
0
|
12
|
32
|
335
|
250
|
856
|
164
|
0
|
0
|
2008
|
27356
|
3
|
6
|
1
|
3
|
11
|
331
|
146
|
854
|
218
|
17
|
0
|
2010
|
23004
|
3
|
1
|
0
|
8
|
16
|
164
|
276
|
650
|
162
|
0
|
0
|
2012
|
28860
|
2
|
0
|
0
|
101
|
27
|
238
|
190
|
1048
|
311
|
3
|
0
|
2014
|
29534
|
3
|
4
|
1
|
12
|
18
|
255
|
159
|
1070
|
228
|
3
|
0
|
2016
|
24838
|
2
|
0
|
0
|
23
|
21
|
333
|
150
|
1007
|
202
|
4
|
1
|
2018
|
23318
|
3
|
10
|
0
|
15
|
15
|
201
|
160
|
891
|
294
|
6
|
6
|
Total
|
240178
|
32
|
24
|
2
|
219
|
251
|
2186
|
1739
|
8122
|
1971
|
99
|
7
|
Note: The high number for “code” in 2012 is largely due to a single paper about “land use codes”.
Colophon
This document is licensed under a Creative Commons Attribution 4.0 International License. All contained code is licensed under the Apache License 2.0. This document is versioned in a public git repository, https://github.com/nuest/reproducible-research-at-giscience, and archived on Zenodo at https://doi.org/10.5281/zenodo.4032875.
Runtime environment description:
## ─ Session info ───────────────────────────────────────────────────────────────
## setting value
## version R version 3.6.3 (2020-02-29)
## os Debian GNU/Linux 10 (buster)
## system x86_64, linux-gnu
## ui X11
## language (EN)
## collate en_US.UTF-8
## ctype en_US.UTF-8
## tz Etc/UTC
## date 2021-06-01
##
## ─ Packages ───────────────────────────────────────────────────────────────────
## package * version date lib source
## askpass 1.1 2019-01-13 [1] CRAN (R 3.6.3)
## assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.6.3)
## backports 1.1.6 2020-04-05 [1] CRAN (R 3.6.3)
## base * 3.6.3 2020-05-14 [2] local
## broom 0.5.6 2020-04-20 [1] CRAN (R 3.6.3)
## callr 3.4.3 2020-03-28 [1] CRAN (R 3.6.3)
## cellranger 1.1.0 2016-07-27 [1] CRAN (R 3.6.3)
## cli 2.0.2 2020-02-28 [1] CRAN (R 3.6.3)
## colorspace 1.4-1 2019-03-18 [1] CRAN (R 3.6.3)
## compiler 3.6.3 2020-05-14 [2] local
## crayon 1.3.4 2017-09-16 [1] CRAN (R 3.6.3)
## data.table 1.12.8 2019-12-09 [1] CRAN (R 3.6.3)
## datasets * 3.6.3 2020-05-14 [2] local
## DBI 1.1.0 2019-12-15 [1] CRAN (R 3.6.3)
## dbplyr 1.4.3 2020-04-19 [1] CRAN (R 3.6.3)
## desc 1.2.0 2018-05-01 [1] CRAN (R 3.6.3)
## devtools 2.3.0 2020-04-10 [1] CRAN (R 3.6.3)
## digest 0.6.25 2020-02-23 [1] CRAN (R 3.6.3)
## dplyr * 0.8.5 2020-03-07 [1] CRAN (R 3.6.3)
## ellipsis 0.3.0 2019-09-20 [1] CRAN (R 3.6.3)
## evaluate 0.14 2019-05-28 [1] CRAN (R 3.6.3)
## fansi 0.4.1 2020-01-08 [1] CRAN (R 3.6.3)
## fastmatch 1.1-0 2017-01-28 [1] CRAN (R 3.6.3)
## forcats * 0.5.0 2020-03-01 [1] CRAN (R 3.6.3)
## fs 1.4.1 2020-04-04 [1] CRAN (R 3.6.3)
## generics 0.0.2 2018-11-29 [1] CRAN (R 3.6.3)
## ggplot2 * 3.3.0 2020-03-05 [1] CRAN (R 3.6.3)
## glue 1.4.0 2020-04-03 [1] CRAN (R 3.6.3)
## graphics * 3.6.3 2020-05-14 [2] local
## grDevices * 3.6.3 2020-05-14 [2] local
## grid * 3.6.3 2020-05-14 [2] local
## gridBase * 0.4-7 2014-02-24 [1] CRAN (R 3.6.3)
## gridExtra * 2.3 2017-09-09 [1] CRAN (R 3.6.3)
## gtable 0.3.0 2019-03-25 [1] CRAN (R 3.6.3)
## haven 2.2.0 2019-11-08 [1] CRAN (R 3.6.3)
## here * 0.1 2017-05-28 [1] CRAN (R 3.6.3)
## highr 0.8 2019-03-20 [1] CRAN (R 3.6.3)
## hms 0.5.3 2020-01-08 [1] CRAN (R 3.6.3)
## htmltools 0.4.0 2019-10-04 [1] CRAN (R 3.6.3)
## httr 1.4.1 2019-08-05 [1] CRAN (R 3.6.3)
## janeaustenr 0.1.5 2017-06-10 [1] CRAN (R 3.6.3)
## jsonlite 1.6.1 2020-02-02 [1] CRAN (R 3.6.3)
## kableExtra * 1.1.0 2019-03-16 [1] CRAN (R 3.6.3)
## knitr 1.28 2020-02-06 [1] CRAN (R 3.6.3)
## lattice 0.20-38 2018-11-04 [2] CRAN (R 3.6.3)
## lifecycle 0.2.0 2020-03-06 [1] CRAN (R 3.6.3)
## lubridate 1.7.8 2020-04-06 [1] CRAN (R 3.6.3)
## magrittr 1.5 2014-11-22 [1] CRAN (R 3.6.3)
## Matrix 1.2-18 2019-11-27 [2] CRAN (R 3.6.3)
## memoise 1.1.0 2017-04-21 [1] CRAN (R 3.6.3)
## methods * 3.6.3 2020-05-14 [2] local
## modelr 0.1.6 2020-02-22 [1] CRAN (R 3.6.3)
## munsell 0.5.0 2018-06-12 [1] CRAN (R 3.6.3)
## nlme 3.1-144 2020-02-06 [2] CRAN (R 3.6.3)
## pdftools * 2.3 2019-11-10 [1] CRAN (R 3.6.3)
## pillar 1.4.3 2019-12-20 [1] CRAN (R 3.6.3)
## pkgbuild 1.0.6 2019-10-09 [1] CRAN (R 3.6.3)
## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 3.6.3)
## pkgload 1.0.2 2018-10-29 [1] CRAN (R 3.6.3)
## prettyunits 1.1.1 2020-01-24 [1] CRAN (R 3.6.3)
## processx 3.4.2 2020-02-09 [1] CRAN (R 3.6.3)
## ps 1.3.2 2020-02-13 [1] CRAN (R 3.6.3)
## purrr * 0.3.4 2020-04-17 [1] CRAN (R 3.6.3)
## qpdf 1.1 2019-03-07 [1] CRAN (R 3.6.3)
## quanteda * 2.0.1 2020-03-18 [1] CRAN (R 3.6.3)
## R6 2.4.1 2019-11-12 [1] CRAN (R 3.6.3)
## RColorBrewer * 1.1-2 2014-12-07 [1] CRAN (R 3.6.3)
## Rcpp 1.0.4.6 2020-04-09 [1] CRAN (R 3.6.3)
## RcppParallel 5.0.0 2020-03-11 [1] CRAN (R 3.6.3)
## readr * 1.3.1 2018-12-21 [1] CRAN (R 3.6.3)
## readxl 1.3.1 2019-03-13 [1] CRAN (R 3.6.3)
## remotes 2.1.1 2020-02-15 [1] CRAN (R 3.6.3)
## reprex 0.3.0 2019-05-16 [1] CRAN (R 3.6.3)
## rlang 0.4.5 2020-03-01 [1] CRAN (R 3.6.3)
## rmarkdown 2.5 2021-06-01 [1] Github (rstudio/rmarkdown@4ff2093)
## rprojroot 1.3-2 2018-01-03 [1] CRAN (R 3.6.3)
## rstudioapi 0.11 2020-02-07 [1] CRAN (R 3.6.3)
## rvest 0.3.5 2019-11-08 [1] CRAN (R 3.6.3)
## scales 1.1.0 2019-11-18 [1] CRAN (R 3.6.3)
## sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.6.3)
## SnowballC 0.7.0 2020-04-01 [1] CRAN (R 3.6.3)
## stats * 3.6.3 2020-05-14 [2] local
## stopwords 2.0 2020-04-14 [1] CRAN (R 3.6.3)
## stringi 1.4.6 2020-02-17 [1] CRAN (R 3.6.3)
## stringr * 1.4.0 2019-02-10 [1] CRAN (R 3.6.3)
## testthat 2.3.2 2020-03-02 [1] CRAN (R 3.6.3)
## tibble * 3.0.1 2020-04-20 [1] CRAN (R 3.6.3)
## tidyr * 1.0.2 2020-01-24 [1] CRAN (R 3.6.3)
## tidyselect 1.0.0 2020-01-27 [1] CRAN (R 3.6.3)
## tidytext * 0.2.4 2020-04-17 [1] CRAN (R 3.6.3)
## tidyverse * 1.3.0 2019-11-21 [1] CRAN (R 3.6.3)
## tokenizers 0.2.1 2018-03-29 [1] CRAN (R 3.6.3)
## tools 3.6.3 2020-05-14 [2] local
## usethis 1.6.0 2020-04-09 [1] CRAN (R 3.6.3)
## utils * 3.6.3 2020-05-14 [2] local
## vctrs 0.2.4 2020-03-10 [1] CRAN (R 3.6.3)
## viridisLite 0.3.0 2018-02-01 [1] CRAN (R 3.6.3)
## webshot 0.5.2 2019-11-22 [1] CRAN (R 3.6.3)
## withr 2.2.0 2020-04-20 [1] CRAN (R 3.6.3)
## wordcloud * 2.6 2018-08-24 [1] CRAN (R 3.6.3)
## xfun 0.15 2021-06-01 [1] Github (yihui/xfun@06e86a6)
## xml2 1.3.2 2020-04-23 [1] CRAN (R 3.6.3)
## yaml 2.2.1 2020-02-01 [1] CRAN (R 3.6.3)
##
## [1] /usr/local/lib/R/site-library
## [2] /usr/local/lib/R/library
LS0tCnRpdGxlOiAiVGV4dCBhbmFseXNpcyBvZiBhY2NlcHRlZCBmdWxsIHBhcGVycyBhdCBoaXN0b3JpYyBHSVNjaWVuY2UgY29uZmVyZW5jZXMiCmF1dGhvcjogRGFuaWVsIE7DvHN0LCBPcGVuaW5nIFJlcHJvZHVjaWJsZSBSZXNlYXJjaCAobzJyKSwgSW5zdGl0dXRlIGZvciBHZW9pbmZvcm1hdGljcywKICBVbml2ZXJzaXR5IG9mIE3DvG5zdGVyCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBzZWxmX2NvbnRhaW5lZDogZmFsc2UKICAgIGxpYl9kaXI6IGxpYnMKcGFyYW1zOgogIHdpdGhfc3A6IG5vCi0tLQoKYGBge2NzcywgZWNobz1GQUxTRX0KcHJlIHsKICBmb250LXNpemU6IDEycHg7CiAgb3ZlcmZsb3cteDogYXV0bzsKfQpwcmUgY29kZSB7CiAgd29yZC13cmFwOiBub3JtYWw7CiAgd2hpdGUtc3BhY2U6IHByZTsKfQpgYGAKCiMjIEludHJvZHVjdGlvbgoKVGhpcyBkb2N1bWVudCBpcyBhbiBleHBsb3JhdG9yeSBhbmFseXNpcyBvZiBhbGwgYWNjZXB0ZWQgZnVsbCBwYXBlcnMsIGFuZCBwb3N0ZXJzIGF0IHRoZSBbR0lTY2llbmNlIGNvbmZlcmVuY2Ugc2VyaWVzXShodHRwczovL3d3dy5naXNjaWVuY2Uub3JnLykuClRoZSBhbmFseXNpcyBpcyBiYXNlZCBvbiB0aGUgdGV4dCBhbmFseXNpcyBwdWJsaXNoZWQgaW4gXyJSZXByb2R1Y2libGUgcmVzZWFyY2ggYW5kIEdJU2NpZW5jZTogYW4gZXZhbHVhdGlvbiB1c2luZyBBR0lMRSBjb25mZXJlbmNlIHBhcGVycyJfIChbaHR0cHM6Ly9kb2kub3JnLzEwLjc3MTcvcGVlcmouNTA3Ml0oaHR0cHM6Ly9kb2kub3JnLzEwLjc3MTcvcGVlcmouNTA3MikpLgoKYGBge3IgbG9hZF9saWJyYXJpZXMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoImhlcmUiKQpsaWJyYXJ5KCJwZGZ0b29scyIpCmxpYnJhcnkoInN0cmluZ3IiKQpsaWJyYXJ5KCJ0aWR5dmVyc2UiKQpsaWJyYXJ5KCJ0aWR5dGV4dCIpCmxpYnJhcnkoIndvcmRjbG91ZCIpCmxpYnJhcnkoIlJDb2xvckJyZXdlciIpCmxpYnJhcnkoImdyaWQiKQpsaWJyYXJ5KCJncmlkQmFzZSIpCmxpYnJhcnkoImdyaWRFeHRyYSIpCmxpYnJhcnkoImthYmxlRXh0cmEiKQpsaWJyYXJ5KCJxdWFudGVkYSIpCgojIGZvciBkZXRlcm1pbmlzdGljIGNsb3VkIHJlbmRlcmluZwpzZXQuc2VlZChuY2hhcigiSW50ZXJuYXRpb25hbCBDb25mZXJlbmNlIG9uIEdlb2dyYXBoaWMgSW5mb3JtYXRpb24gU2NpZW5jZSIpKQpgYGAKCiMjIExvYWQgZGF0YQoKKipMaXN0IG9mIHByb2NlZWRpbmdzKioKCi0gUHJvY2VlZGluZ3MgMTB0aCBJbnRlcm5hdGlvbmFsIENvbmZlcmVuY2Ugb24gR2VvZ3JhcGhpYyBJbmZvcm1hdGlvbiBTY2llbmNlIChHSVNjaWVuY2UgMjAxOCkuIDIwMTguIFdpbnRlciwgUy4sIEdyaWZmaW4sIEEuLCBTZXN0ZXIsIE0uIChFZHMuKSwgTElQSUNTIFZvbC4gMTE0LiBJU0JOIDk3OC0zLTk1OTc3LTA4My01LiBodHRwOi8vd3d3LmRhZ3N0dWhsLmRlL2RhZ3B1Yi85NzgtMy05NTk3Ny0wODMtNQotIEdlb2dyYXBoaWMgSW5mb3JtYXRpb24gU2NpZW5jZS4gMjAxNi4gSi4gQS4gTWlsbGVyLCBELiBP4oCZU3VsbGl2YW4sICYgTi4gV2llZ2FuZCAoRWRzLiksIExlY3R1cmUgTm90ZXMgaW4gQ29tcHV0ZXIgU2NpZW5jZS4gU3ByaW5nZXIgSW50ZXJuYXRpb25hbCBQdWJsaXNoaW5nLiBodHRwczovL2RvaS5vcmcvMTAuMTAwNy85NzgtMy0zMTktNDU3MzgtMwotIEdlb2dyYXBoaWMgSW5mb3JtYXRpb24gU2NpZW5jZS4gMjAxNC4gTS4gRHVja2hhbSwgRS4gUGViZXNtYSwgSy4gU3Rld2FydCwgJiBBLiBVLiBGcmFuayAoRWRzLiksIExlY3R1cmUgTm90ZXMgaW4gQ29tcHV0ZXIgU2NpZW5jZS4gU3ByaW5nZXIgSW50ZXJuYXRpb25hbCBQdWJsaXNoaW5nLiBodHRwczovL2RvaS5vcmcvMTAuMTAwNy85NzgtMy0zMTktMTE1OTMtMQotIEdlb2dyYXBoaWMgSW5mb3JtYXRpb24gU2NpZW5jZS4gMjAxMi4gTi4gWGlhbywgTS4tUC4gS3dhbiwgTS4gRi4gR29vZGNoaWxkLCAmIFMuIFNoZWtoYXIgKEVkcy4pLCBMZWN0dXJlIE5vdGVzIGluIENvbXB1dGVyIFNjaWVuY2UuIFNwcmluZ2VyIEJlcmxpbiBIZWlkZWxiZXJnLiBodHRwczovL2RvaS5vcmcvMTAuMTAwNy85NzgtMy02NDItMzMwMjQtNwotIEdlb2dyYXBoaWMgSW5mb3JtYXRpb24gU2NpZW5jZS4gMjAxMC4gRmFicmlrYW50LCBTLkkuLCBSZWljaGVuYmFjaGVyLCBULiwgS3JldmVsZCwgTS4gdmFuLCBTY2hsaWVkZXIsIEMuIChFZHMuKSwgTGVjdHVyZSBOb3RlcyBpbiBDb21wdXRlciBTY2llbmNlLiBTcHJpbmdlciBCZXJsaW4gSGVpZGVsYmVyZy4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwMDcvOTc4LTMtNjQyLTE1MzAwLTYKLSBHZW9ncmFwaGljIEluZm9ybWF0aW9uIFNjaWVuY2UuIDIwMDguIEluIENvdmEsIFQuSi4sIE1pbGxlciwgSC5KLiwgQmVhcmQsIEsuLCBGcmFuaywgQS5VLiwgR29vZGNoaWxkLCBNLkYuIChFZHMuKSwgTGVjdHVyZSBOb3RlcyBpbiBDb21wdXRlciBTY2llbmNlLiBTcHJpbmdlciBCZXJsaW4gSGVpZGVsYmVyZy4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwMDcvOTc4LTMtNTQwLTg3NDczLTcKLSBHZW9ncmFwaGljIEluZm9ybWF0aW9uIFNjaWVuY2UuIDIwMDQuIEVnZW5ob2ZlciwgTS5KLiwgRnJla3NhLCBDLiwgTWlsbGVyLCBILkouIChFZHMuKSwgTGVjdHVyZSBOb3RlcyBpbiBDb21wdXRlciBTY2llbmNlLiBTcHJpbmdlciBCZXJsaW4gSGVpZGVsYmVyZy4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwMDcvYjEwMTM5NwotIEdlb2dyYXBoaWMgSW5mb3JtYXRpb24gU2NpZW5jZS4gMjAwMi4gRWdlbmhvZmVyLCBNLkouLCBNYXJrLCBELk0uIChFZHMuKSwgTGVjdHVyZSBOb3RlcyBpbiBDb21wdXRlciBTY2llbmNlLiBTcHJpbmdlciBCZXJsaW4gSGVpZGVsYmVyZy4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwMDcvMy01NDAtNDU3OTktMgotIEdlb2dyYXBoaWMgSW5mb3JtYXRpb24gU2NpZW5jZS4gMjAwNi4gUmF1YmFsLCBNLiwgTWlsbGVyLCBILkouLCBGcmFuaywgQS5VLiwgR29vZGNoaWxkLCBNLkYuIChFZHMuKSwgTGVjdHVyZSBOb3RlcyBpbiBDb21wdXRlciBTY2llbmNlLiBTcHJpbmdlciBCZXJsaW4gSGVpZGVsYmVyZy4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwMDcvMTE4NjM5MzkKCkxOQ1MgcHJvY2VlZGluZ3MgYXJlIGF2YWlsYWJsZSBhdCB0aGUgcHVibGlzaGVyIHdlYnNpdGU6IFtodHRwczovL2xpbmsuc3ByaW5nZXIuY29tL2NvbmZlcmVuY2UvZ2lzY2llbmNlXShodHRwczovL2xpbmsuc3ByaW5nZXIuY29tL2NvbmZlcmVuY2UvZ2lzY2llbmNlKS4KCioqTm90ZToqKiBUaGUgMjAxOCBwcm9jZWVkaW5ncyBpbmNsdWRlIHRoZSBzaG9ydCBwYXBlcnMgaW4gdGhlIHNhbWUgZG9jdW1lbnQuCkZvciBjb21wYXJhYmlsaXR5LCBvbmx5IHRoZSBmdWxsIHBhcGVycyBhcmUgdGFrZW4gaW50byBhY2NvdW50IGZvciB0aGUgYW5hbHlzaXMgYmVsb3cuCgpgYGB7ciBpbnB1dF9maWxlc30KZGF0YV9wYXRoIDwtIGhlcmU6OmhlcmUoInByb2NlZWRpbmdzIikKcHJvY2VlZGluZ3MgPC0gYygKICAiMjAwMiIgPSAiZ2VvZ3JhcGhpYy1pbmZvcm1hdGlvbi1zY2llbmNlLTIwMDIucGRmIiwKICAiMjAwNCIgPSAiZ2VvZ3JhcGhpYy1pbmZvcm1hdGlvbi1zY2llbmNlLTIwMDQucGRmIiwKICAiMjAwNiIgPSAiZ2VvZ3JhcGhpYy1pbmZvcm1hdGlvbi1zY2llbmNlLTIwMDYucGRmIiwKICAiMjAwOCIgPSAiZ2VvZ3JhcGhpYy1pbmZvcm1hdGlvbi1zY2llbmNlLTIwMDgucGRmIiwKICAiMjAxMCIgPSAiZ2VvZ3JhcGhpYy1pbmZvcm1hdGlvbi1zY2llbmNlLTIwMTAucGRmIiwKICAiMjAxMiIgPSAiMTAuMTAwN185NzgtMy02NDItMzMwMjQtNy5wZGYiLAogICIyMDE0IiA9ICIxMC4xMDA3Xzk3OC0zLTMxOS0xMTU5My0xLnBkZiIsCiAgIjIwMTYiID0gIjEwLjEwMDdfOTc4LTMtMzE5LTQ1NzM4LTMucGRmIiwKICAiMjAxOCIgPSAibGlwaWNzLXZvbDExNC1naXNjaWVuY2UyMDE4LWNvbXBsZXRlLnBkZiIKKQpwcm9jZWVkaW5nc19maWxlcyA8LSBmaWxlLnBhdGgoZGF0YV9wYXRoLCBwcm9jZWVkaW5ncykKbmFtZXMocHJvY2VlZGluZ3NfZmlsZXMpIDwtIG5hbWVzKHByb2NlZWRpbmdzKQpgYGAKCkFkZCB0aGUgUERGcyB0byBhIGRpcmVjdG9yeSBjYWxsZWQgYCBgciBkYXRhX3BhdGhgIGAgbmV4dCB0byB0aGUgZmlsZSBgZ2lzY2llbmNlLWhpc3RvcmljLXRleHQtYW5hbHlzaXMuUm1kYCAodGhpcyBmaWxlKS4KVGhlIHByb2NlZWRpbmdzIG9mIHRoZSBwYXBlcnMgYXJlIG5vdCBvcGVubHkgYXZhaWxhYmxlIGZvciB0aGUgeWVhcnMgMjAxMiB0byAyMDE2LgpZb3UgY2FuIGNvbnRhY3QgdGhlIG9yaWdpbmFsIHBhcGVyIGF1dGhvcnMgYW5kIGFzayBmb3IgdGhlIHRlc3QgZGF0YXNldCB0byByZXByb2R1Y2UgdGhlIGZ1bGwgYW5hbHlzaXMuCkFsdGVybmF0aXZlbHksIHlvdSBjYW4gZG93bmxvYWQgdGhlIDIwMTggcHJvY2VlZGluZ3MgZnJvbSB0aGUgTElQSWNzIHdlYnNpdGUgKE9wZW4gQWNjZXNzOyBbZGlyZWN0IFBERiBsaW5rXShodHRwczovL2Ryb3BzLmRhZ3N0dWhsLmRlL29wdXMvdm9sbHRleHRlL2xpcGljcy1jb21wbGV0ZS9saXBpY3Mtdm9sMTE0LWdpc2NpZW5jZTIwMTgtY29tcGxldGUucGRmKSkgYW5kIGNvbmR1Y3QgdGhlIGFuYWx5c2lzIHdpdGggdGhhdCBzdWJzZXQgb2YgdGhlIGRhdGEuCkZvciB0aGUgYW5hbHlzaXMgYmVsb3cgdGhlIGZvbGxvd2luZyBpbnB1dCBmaWxlcyB3ZXJlIHVzZWQ6CgpgYGB7ciBsaXN0X2ZpbGVzfQprbml0cjo6a2FibGUodGliYmxlKHllYXIgPSBuYW1lcyhwcm9jZWVkaW5ncyksIGZpbGUgPSBwcm9jZWVkaW5ncykpICU+JQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRkFMU0UpCmBgYAoKYGBge3IgZGF0YV9kb3dubG9hZF9kcml2ZSwgZXZhbD1GQUxTRX0KIyBDb2RlIG5vdCBldmFsdWF0ZWQgd2hlbiBkb2N1bWVudCBpcyByZW5kZXJlZCEKZGlyLmNyZWF0ZShkYXRhX3BhdGgsIHNob3dXYXJuaW5ncyA9IEZBTFNFKQoKbGlicmFyeSgiZ29vZ2xlZHJpdmUiKQpkcml2ZV9kaXIgPC0gZ29vZ2xlZHJpdmU6OmRyaXZlX2dldCgiaHR0cHM6Ly9kcml2ZS5nb29nbGUuY29tL2RyaXZlL2ZvbGRlcnMvMTdFVXRNX3pDeDFnUU1lYTFNSE5fNVhTVnJzc3h2OUdBIikKZHJpdmVfZGlyX2NvbnRlbnRzIDwtIGdvb2dsZWRyaXZlOjpkcml2ZV9scyhkcml2ZV9kaXIpCmZvciAoaSBpbiByb3duYW1lcyhkcml2ZV9kaXJfY29udGVudHMpKSB7CiAgY3VycmVudCA8LSBkcml2ZV9kaXJfY29udGVudHNbaSxdCiAgaWYoZW5kc1dpdGgoY3VycmVudCRuYW1lLCAiLnBkZiIpKQogICAgZ29vZ2xlZHJpdmU6OmRyaXZlX2Rvd25sb2FkKGFzX2lkKGN1cnJlbnQkaWQpLCBmaWxlLnBhdGgoZGF0YV9wYXRoLCBjdXJyZW50JG5hbWUpKQp9CmBgYAoKVGhlIHRleHQgaXMgZXh0cmFjdGVkIGZyb20gUERGcyBhbmQgaXQgaXMgcHJvY2Vzc2VkIHRvIGNyZWF0ZSBhIFt0aWR5XShodHRwczovL3d3dy5qc3RhdHNvZnQub3JnL2FydGljbGUvdmlldy92MDU5aTEwKSBkYXRhIHN0cnVjdHVyZSB3aXRob3V0IFtzdG9wIHdvcmRzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TdG9wX3dvcmRzKS4KVGhlIHN0b3Agd29yZHMgaW5jbHVkZSBzcGVjaWZpYyB3b3Jkcywgc3VjaCBhcyBgdW5pdmVyc2l0eWAsIHdoaWNoIGlzIGluY2x1ZGVkIGluIG1hbnkgcGFnZXMsIGFiYnJldmlhdGlvbnMgc3VjaCBhcyBgZS5nLmAsIGFuZCB0ZXJtcyBwYXJ0aWN1bGFyIHRvIHNjaWVudGlmaWMgYXJ0aWNsZXMsIHN1Y2ggYXMgYGZpZ3VyZWAuCkFsc28gYWxsIG51bWVyaWMgbGl0ZXJhcyBhcmUgcmVtb3ZlZCBmcm9tIHRoZSB3b3JkIGxpc3QuCgpgYGB7ciBsb2FkX2ZpbGVzLCBjYWNoZT1UUlVFfQp0ZXh0cyA8LSBsYXBwbHkocHJvY2VlZGluZ3NfZmlsZXMsIHBkZnRvb2xzOjpwZGZfdGV4dCkKCmlmKHBhcmFtcyR3aXRoX3NwKSB7CiAgdGV4dHNbWyIyMDE4LXNwIl1dIDwtIHRleHRzW1siMjAxOCJdXVtjKDI4MzpsZW5ndGgodGV4dHNbWyIyMDE4Il1dKSldCiAgcHJvY2VlZGluZ3NfZmlsZXMgPC0gYyhwcm9jZWVkaW5nc19maWxlcywgYDIwMTgtc3BgID0gcHJvY2VlZGluZ3NfZmlsZXNbWzRdXSkKfQoKIyBkb24ndCBpbmNsdWRlIHNob3J0IHBhcGVycyBpbiAyMDE4IHllYXIKdGV4dHNbWyIyMDE4Il1dIDwtIHRleHRzW1siMjAxOCJdXVtjKDE6MjgyKV0KCnRleHRzIDwtIHVubGlzdChsYXBwbHkodGV4dHMsIHN0cmluZ3I6OnN0cl9jLCBjb2xsYXBzZSA9IFRSVUUpKQoKdGlkeV90ZXh0cyA8LSB0aWJibGU6OnRpYmJsZSh5ZWFyID0gbmFtZXModGV4dHMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwcm9jZWVkaW5nc19maWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gdGV4dHMpCgojIGNyZWF0ZSBhIHRhYmxlIG9mIGFsbCB3b3JkcwphbGxfd29yZHMgPC0gdGlkeV90ZXh0cyAlPiUKICBkcGx5cjo6c2VsZWN0KHllYXIsIHRleHQpICU+JQogIHRpZHl0ZXh0Ojp1bm5lc3RfdG9rZW5zKHdvcmQsIHRleHQpCgojIHJlbW92ZSBzdG9wIHdvcmRzIGFuZCByZW1vdmUgbnVtYmVycwpteV9zdG9wX3dvcmRzIDwtIHRpYmJsZTo6dGliYmxlKAogIHdvcmQgPSBjKAogICAgImV0IiwKICAgICJhbCIsCiAgICAiZmlnIiwKICAgICJlLmciLAogICAgImkuZSIsCiAgICAiaHR0cCIsCiAgICAiaW5nIiwKICAgICJwcCIsCiAgICAiZmlndXJlIiwKICAgICJiYXNlZCIsCiAgICAiY29uZmVyZW5jZSIsCiAgICAidW5pdmVyc2l0eSIsCiAgICAidGFibGUiCiAgKSwKICBsZXhpY29uID0gImdpc2NpZW5jZSIKKQoKYWxsX3N0b3Bfd29yZHMgPC0gc3RvcF93b3JkcyAlPiUKICBkcGx5cjo6YmluZF9yb3dzKG15X3N0b3Bfd29yZHMpCnN1cHByZXNzV2FybmluZ3MoewogIG5vX251bWJlcnMgPC0gYWxsX3dvcmRzICU+JQogICAgZHBseXI6OmZpbHRlcihpcy5uYShhcy5udW1lcmljKHdvcmQpKSkKfSkKCm5vX3N0b3Bfd29yZHMgPC0gbm9fbnVtYmVycyAlPiUKICBkcGx5cjo6YW50aV9qb2luKGFsbF9zdG9wX3dvcmRzLCBieSA9ICJ3b3JkIikKCnRvdGFsX3dvcmRzID0gbnJvdyhub19udW1iZXJzKQphZnRlcl9jbGVhbnVwID0gbnJvdyhub19zdG9wX3dvcmRzKQpgYGAKCkFib3V0IGByIHJvdW5kKGFmdGVyX2NsZWFudXAvdG90YWxfd29yZHMgKiAxMDApYCZuYnNwOyUgb2YgdGhlIHdvcmRzIGFyZSBjb25zaWRlcmVkIHN0b3Agd29yZHMuClRoZSBmb2xsb3dpbmcgdGFibGVzIHNob3dzIGhvdyBtYW55IG5vbi1zdG9wIHdvcmRzIGVhY2ggY29uZmVyZW5jZSB5ZWFyIGhhcywgc29ydGVkIGJ5IG51bWJlciBvZiBub24tc3RvcCB3b3JkcyAoZGVzY2VuZGluZykuCgpgYGB7ciBzdG9wX3dvcmRzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpub25zdG9wd29yZHNfcGVyX3llYXIgPC0gbm9fc3RvcF93b3JkcyAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoeWVhcikgJT4lCiAgZHBseXI6OnN1bW1hcmlzZSh3b3JkcyA9IG4oKSkgJT4lCiAgZHBseXI6OmFycmFuZ2UoZGVzYyh3b3JkcykpICU+JQogIGRwbHlyOjpyZW5hbWUoYG5vbi1zdG9wIHdvcmRzYCA9IHdvcmRzKQoKd29yZHNfcGVyX3llYXIgPC0gbm9fbnVtYmVycyAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoeWVhcikgJT4lCiAgZHBseXI6OnN1bW1hcmlzZSh3b3JkcyA9IG4oKSkgJT4lCiAgZHBseXI6OmFycmFuZ2UoZGVzYyh3b3JkcykpICU+JQogIGRwbHlyOjpyZW5hbWUoYGFsbCB3b3Jkc2AgPSB3b3JkcykKCmRwbHlyOjppbm5lcl9qb2luKG5vbnN0b3B3b3Jkc19wZXJfeWVhciwgd29yZHNfcGVyX3llYXIsIGJ5ID0gInllYXIiKSAlPiUKICBkcGx5cjo6YmluZF9yb3dzKHRpYmJsZSh5ZWFyID0gIlRvdGFsIiwKICAgICAgICAgICAgICAgICAgIGBub24tc3RvcCB3b3Jkc2AgPSBzdW0obm9uc3RvcHdvcmRzX3Blcl95ZWFyJGBub24tc3RvcCB3b3Jkc2ApLAogICAgICAgICAgICAgICAgICAgYGFsbCB3b3Jkc2AgPSBzdW0od29yZHNfcGVyX3llYXIkYGFsbCB3b3Jkc2ApKSkgJT4lCiAga25pdHI6OmthYmxlKCkgJT4lCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGQUxTRSkgJT4lCiAga2FibGVFeHRyYTo6cm93X3NwZWMobnJvdyhub25zdG9wd29yZHNfcGVyX3llYXIpICsgMSwgYm9sZCA9IFRSVUUpCmBgYAoKIyMgVG9wIHdvcmRzdGVtcyBhbmQgd29yZHN0ZW0gY2xvdWRzCgpgYGB7ciBwYXJhbXN9CiMgY2hvc2VuIG1hbnVhbGx5Cm1pbmltdW1fb2NjdXJlbmNlIDwtIDk5Cm1heF93b3JkcyA8LSAxMDAKYGBgCgpUaGUgZm9sbG93aW5nIHRhYmxlIHNob3dzIHRoZSBudW1iZXIgb2Ygb2NjdXJlbmNlIGZvciB0aGUgYHIgbWF4X3dvcmRzYCBtb3N0IG9jY3VyaW5nIHdvcmRzdGVtcyBhY3Jvc3MgYWxsIHByb2NlZWRpbmdzLgoKYGBge3IgdG9wX3dvcmRzdGVtc30Kd29yZHN0ZW1zIDwtIG5vX3N0b3Bfd29yZHMgJT4lCiAgZHBseXI6Om11dGF0ZSh3b3Jkc3RlbSA9IHF1YW50ZWRhOjpjaGFyX3dvcmRzdGVtKG5vX3N0b3Bfd29yZHMkd29yZCkpCgpjb3VudFllYXJzVXNpbmdXb3Jkc3RlbSA8LSBmdW5jdGlvbih0aGVfd29yZCkgewogIHNhcHBseSh0aGVfd29yZCwgZnVuY3Rpb24odykgewogICAgd29yZHN0ZW1zICU+JQogICAgICBkcGx5cjo6ZmlsdGVyKHdvcmRzdGVtID09IHcpICU+JQogICAgICBkcGx5cjo6Z3JvdXBfYnkoeWVhcikgJT4lCiAgICAgIGRwbHlyOjpjb3VudCgpICU+JQogICAgICBucm93CiAgfSkKfQoKdG9wX3dvcmRzdGVtcyA8LSB3b3Jkc3RlbXMgJT4lCiAgZHBseXI6Omdyb3VwX2J5KHdvcmRzdGVtKSAlPiUKICBkcGx5cjo6dGFsbHkoKSAlPiUKICBkcGx5cjo6YXJyYW5nZShkZXNjKG4pKSAlPiUKICBoZWFkKG4gPSBtYXhfd29yZHMpICU+JQogIGRwbHlyOjptdXRhdGUoYHllYXJzIHcvIHdvcmRzdGVtYCA9IGNvdW50WWVhcnNVc2luZ1dvcmRzdGVtKHdvcmRzdGVtKSkgJT4lCiAgdGliYmxlOjphZGRfY29sdW1uKHBsYWNlID0gYygxOm5yb3coLikpLCAuYmVmb3JlID0gMCkKCndyaXRlLmNzdih0b3Bfd29yZHN0ZW1zLCBoZXJlOjpoZXJlKCJyZXN1bHRzL3RleHRfYW5hbHlzaXNfdG9wd29yZHN0ZW1zLmNzdiIpLCByb3cubmFtZXMgPSBGQUxTRSkKCnRvcF93b3Jkc3RlbXMgJT4lCiAga25pdHI6OmthYmxlKCkgJT4lCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGQUxTRSkgJT4lCiAga2FibGVFeHRyYTo6c2Nyb2xsX2JveChoZWlnaHQgPSAiMzAwcHgiKQpgYGAKClRoZSBmb2xsb3dpbmcgY2xvdWRzIGFuZCB0YWJsZSBhcmUgYmFzZWQgb24gd29yZCBzdGVtcyBleHRyYWN0ZWQgd2l0aCBhIHN0ZW1taW5nIGFsZ29yaXRobSBmcm9tIHBhY2thZ2UgW2BxdWFudGVkYWBdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3BhY2thZ2U9cXVhbnRlZGEpLgpXb3JkcyBtdXN0IG9jY3VyIGF0IGxlYXN0IGByIG1pbmltdW1fb2NjdXJlbmNlYCB0aW1lcyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgY2xvdWQuCkVhY2ggY2xvdWQgaGFzIGEgbWF4aW11bSBvZiBgciBtYXhfd29yZHNgIHdvcmRzLgoKYGBge3IgY2xvdWRfd29yZHN0ZW1zLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpjbG91ZF93b3Jkc3RlbXMgPC0gd29yZHN0ZW1zICU+JQogIGRwbHlyOjpncm91cF9ieSh5ZWFyLCB3b3Jkc3RlbSkgJT4lCiAgZHBseXI6OnRhbGx5KCkgJT4lCiAgZHBseXI6OmFycmFuZ2UoZGVzYyhuKSkKYGBgCgpgYGB7ciB3b3JkY2xvdWRzX2NyZWF0ZV9wbG90LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIHBsb3QgaXMgY3JlYXRlZCB0byBmaWxlIHRvIGZpdCBtb3JlIHdvcmRzIHRvIGEgc3BlY2lmaWMgcGl4ZWwgc2l6ZQpwbmcoZmlsZW5hbWUgPSBoZXJlOjpoZXJlKCJyZXN1bHRzL3RleHRfYW5hbHlzaXNfd29yZHN0ZW1jbG91ZHMucG5nIiksCiAgICB3aWR0aCA9IDEwMDAsCiAgICBoZWlnaHQgPSAxMDAwKQoKcGFyKG1mcm93ID0gYygzLDMpKQpmb3IgKHRoZV95ZWFyIGluIG5hbWVzKHByb2NlZWRpbmdzKSkgewogIHllYXJfY2xvdWRfd29yZHN0ZW1zIDwtIGNsb3VkX3dvcmRzdGVtcyAlPiUKICAgIGRwbHlyOjpmaWx0ZXIoeWVhciA9PSB0aGVfeWVhcikgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKG4gPj0gbWluaW11bV9vY2N1cmVuY2UpICU+JQogICAgaGVhZChuID0gbWF4X3dvcmRzKQogICNjYXQoc3RyKHllYXJfY2xvdWRfd29yZHN0ZW1zKSkKICAKICB3b3JkY2xvdWQ6OndvcmRjbG91ZCh3b3JkcyA9IHllYXJfY2xvdWRfd29yZHN0ZW1zJHdvcmRzdGVtLAogICAgICAgICAgICAgICAgICAgICAgIGZyZXEgPSB5ZWFyX2Nsb3VkX3dvcmRzdGVtcyRuLAogICAgICAgICAgICAgICAgICAgICAgIG1pbi5mcmVxID0gMSwKICAgICAgICAgICAgICAgICAgICAgICByYW5kb20ub3JkZXIgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBmaXhlZC5hc3AgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICByb3QucGVyID0gMCwKICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGJyZXdlci5wYWwoOCwgIkRhcmsyIikpCn0KZGV2Lm9mZigpCgpmaWxlLmNvcHkoZnJvbSA9IGhlcmU6OmhlcmUoInJlc3VsdHMvdGV4dF9hbmFseXNpc193b3Jkc3RlbWNsb3Vkcy5wbmciKSwKICAgICAgICAgIHRvID0gaGVyZTo6aGVyZSgiZG9jcy90ZXh0X2FuYWx5c2lzX3dvcmRzdGVtY2xvdWRzLnBuZyIpLAogICAgICAgICAgb3ZlcndyaXRlID0gVFJVRSkKYGBgCgo8IS0tIHBhdGggZml4ZWQgdG8gb3V0cHV0IGluIGRvY3MvIGRpcmVjdG9yeSAtIHNlZSBNYWtlZmlsZSAtLT4KIVtdKHRleHRfYW5hbHlzaXNfd29yZHN0ZW1jbG91ZHMucG5nKQoKX2ByIHBhc3RlMCgiV29ybGQgY2xvdWRzIG9mIGZ1bGwgcGFwZXJzIHBlciBjb25mZXJlbmNlIHllYXIgKHJvd3dpc2UsIHN0YXJ0aW5nIHRvcCBsZWZ0LCBmcm9tICIsIGhlYWQobmFtZXMocHJvY2VlZGluZ3NfZmlsZXMpLCBuID0gMSksICIgdG8gIiwgdGFpbChuYW1lcyhwcm9jZWVkaW5nc19maWxlcyksIG4gPSAxKSwgIikuIilgXwoKIyMgUmVwcm9kdWNpYmxlIHJlc2VhcmNoLXJlbGF0ZWQga2V5d29yZHN0ZW1zIGluIEdJU2NpZW5jZSBwYXBlcnMKClRoZSBmb2xsb3dpbmcgdGFibGVzIGxpc3RzIGhvdyBvZnRlbiB3b3Jkc3RlbXMgb2YgdGVybXMgcmVsYXRlZCB0byByZXByb2R1Y2libGUgcmVzZWFyY2ggYXBwZWFyIGluIGVhY2ggZG9jdW1lbnQuClRoZSBkZXRlY3Rpb24gbWF0Y2hlcyBmdWxsIHdvcmRzIHVzaW5nIHJlZ2V4IG9wdGlvbiBgXGJgLgoKLSByZXByb2R1YyAoYHJlcHJvZHVjLipgLCByZXByb2R1Y2liaWxpdHksIHJlcHJvZHVjaWJsZSwgcmVwcm9kdWNlLCByZXByb2R1Y3Rpb24pCi0gcmVwbGljIChgcmVwbGljYXQuKmAsIGkuZS4gcmVwbGljYXRpb24sIHJlcGxpY2F0ZSkKLSByZXBlYXRhYiAoYHJlcGVhdGFiLipgLCBpLmUuIHJlcGVhdGFiaWxpdHksIHJlcGVhdGFibGUpCi0gc29mdHdhcmUKLSAocHNldWRvKSBjb2RlL3NjcmlwdChzKSBbY29sdW1uIG5hbWUgX2NvZGVfXQotIGFsZ29yaXRobSAoYGFsZ29yaXRobS4qYCwgaS5lLiBhbGdvcml0aG1zLCBhbGdvcml0aG1pYykKLSBwcm9jZXNzIChgcHJvY2Vzcy4qYCwgaS5lLiBwcm9jZXNzaW5nLCBwcm9jZXNzZXMsIHByZXByb2Nlc3NpbmcpCi0gZGF0YSAoYGRhdGEuKmAsIGkuZS4gZGF0YXNldChzKSwgZGF0YWJhc2UocykpCi0gcmVzdWx0KHMpIChgcmVzdWx0cz9gKQotIHJlcG9zaXRvcnkoaWVzKSAoYHJlcG9zaXRvcih5fGllcylgKQotIGNvbGxhYm9yYXRpb24gcGxhdGZvcm1zIChgZ2l0KGh1YnxsYWIpYCkKCmBgYHtyIGtleXdvcmRzX3Blcl95ZWFyLCB3YXJuaW5nPUZBTFNFfQp0aWR5X3RleHRzX2xvd2VyIDwtIHN0cmluZ3I6OnN0cl90b19sb3dlcih0aWR5X3RleHRzJHRleHQpCndvcmRfY291bnRzIDwtIHRpYmJsZTo6dGliYmxlKAogIHllYXIgPSB0aWR5X3RleHRzJHllYXIsCiAgYHdvcmRzYCA9IHN0cl9jb3VudCh0aWR5X3RleHRzX2xvd2VyLCAiXFxiLipcXGIiKSwKICBgcmVwcm9kdWMuLmAgPSBzdHJfY291bnQodGlkeV90ZXh0c19sb3dlciwgIlxcYnJlcHJvZHVjLipcXGIiKSwKICBgcmVwbGljLi5gID0gc3RyX2NvdW50KHRpZHlfdGV4dHNfbG93ZXIsICJcXGJyZXBsaWNhdC4qXFxiIiksCiAgYHJlcGVhdGFiLi5gID0gc3RyX2NvdW50KHRpZHlfdGV4dHNfbG93ZXIsICJcXGJyZXBlYXRhYi4qXFxiIiksCiAgYGNvZGVgID0gc3RyX2NvdW50KHRpZHlfdGV4dHNfbG93ZXIsCiAgICAiKFxcYmNvZGVcXGJ8XFxic2NyaXB0LipcXGJ8XFxicHNldWRvXCBjb2RlXFxiKSIpLAogIHNvZnR3YXJlID0gc3RyX2NvdW50KHRpZHlfdGV4dHNfbG93ZXIsICJcXGJzb2Z0d2FyZVxcYiIpLAogIGBhbGdvcml0aG0ocylgID0gc3RyX2NvdW50KHRpZHlfdGV4dHNfbG93ZXIsICJcXGJhbGdvcml0aG0uKlxcYiIpLAogIGAocHJlKXByb2Nlc3MuLmAgPSBzdHJfY291bnQodGlkeV90ZXh0c19sb3dlciwgCiAgICAgICAgICAgICAgICAiKFxcYnByb2Nlc3MuKlxcYnxcXGJwcmVwcm9jZXNzLipcXGJ8XFxicHJlLXByb2Nlc3MuKlxcYikiKSwKICBgZGF0YS4qYCA9IHN0cl9jb3VudCh0aWR5X3RleHRzX2xvd2VyLCAiXFxiZGF0YS4qXFxiIiksCiAgYHJlc3VsdChzKWAgPSBzdHJfY291bnQodGlkeV90ZXh0c19sb3dlciwgIlxcYnJlc3VsdHM/XFxiIiksCiAgYHJlcG9zaXRvcnkvaWVzYCA9IHN0cl9jb3VudCh0aWR5X3RleHRzX2xvd2VyLCAiXFxicmVwb3NpdG9yKHl8aWVzKVxcYiIpLAogICNgcmVwb3NgID0gc3RyX2NvdW50KHRpZHlfdGV4dHNfbG93ZXIsICJcXGJ6ZW5vZG98Zmlnc2hhcmV8b3NmfGRyeWFkXFxiIiksCiAgYGdpdGh1Yi9sYWJgID0gc3RyX2NvdW50KHRpZHlfdGV4dHNfbG93ZXIsICJcXGJnaXQoaHVifGxhYilcXGIiKQopCgp3b3JkX2NvdW50c19zdW1zIDwtIHJiaW5kKHdvcmRfY291bnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmRfY291bnRzICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgZnVucyhzdW0pKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpYmJsZTo6YWRkX2NvbHVtbih5ZWFyID0gIlRvdGFsIiwgLmJlZm9yZSA9IDApKQoKd3JpdGUuY3N2KHdvcmRfY291bnRzX3N1bXMsIGhlcmU6OmhlcmUoInJlc3VsdHMvdGV4dF9hbmFseXNpc19rZXl3b3Jkc3RlbXMuY3N2IiksIHJvdy5uYW1lcyA9IEZBTFNFKQoKd29yZF9jb3VudHNfc3VtcyAlPiUKICBrbml0cjo6a2FibGUoKSAlPiUKICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZm9udF9zaXplID0gMTAsIGJvb3RzdHJhcF9vcHRpb25zID0gImNvbmRlbnNlZCIpICAlPiUKICBrYWJsZUV4dHJhOjpyb3dfc3BlYygwLCBmb250X3NpemUgPSAieC1zbWFsbCIsIGJvbGQgPSBUKSAgJT4lCiAga2FibGVFeHRyYTo6cm93X3NwZWMobnJvdyh3b3JkX2NvdW50c19zdW1zKSwgYm9sZCA9IFQpCmBgYAoKKipOb3RlKio6IFRoZSBoaWdoIG51bWJlciBmb3IgImNvZGUiIGluIDIwMTIgaXMgbGFyZ2VseSBkdWUgdG8gYSBzaW5nbGUgcGFwZXIgYWJvdXQgImxhbmQgdXNlIGNvZGVzIi4KCiMjIENvbG9waG9uCgpUaGlzIGRvY3VtZW50IGlzIGxpY2Vuc2VkIHVuZGVyIGEgW0NyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24gNC4wIEludGVybmF0aW9uYWwgTGljZW5zZV0oaHR0cHM6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LzQuMC8pLgpBbGwgY29udGFpbmVkIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIFtBcGFjaGUgTGljZW5zZSAyLjBdKGh0dHBzOi8vY2hvb3NlYWxpY2Vuc2UuY29tL2xpY2Vuc2VzL2FwYWNoZS0yLjAvKS4KVGhpcyBkb2N1bWVudCBpcyB2ZXJzaW9uZWQgaW4gYSBwdWJsaWMgW2dpdF0oaHR0cHM6Ly9naXQtc2NtLmNvbS8pIHJlcG9zaXRvcnksIFtodHRwczovL2dpdGh1Yi5jb20vbnVlc3QvcmVwcm9kdWNpYmxlLXJlc2VhcmNoLWF0LWdpc2NpZW5jZV0oaHR0cHM6Ly9naXRodWIuY29tL251ZXN0L3JlcHJvZHVjaWJsZS1yZXNlYXJjaC1hdC1naXNjaWVuY2UpLCBhbmQgYXJjaGl2ZWQgb24gWmVub2RvIGF0IFtodHRwczovL2RvaS5vcmcvMTAuNTI4MS96ZW5vZG8uNDAzMjg3NV0oaHR0cHM6Ly9kb2kub3JnLzEwLjUyODEvemVub2RvLjQwMzI4NzUpLgoKKipSdW50aW1lIGVudmlyb25tZW50IGRlc2NyaXB0aW9uOioqCgpgYGB7ciBzZXNzaW9uX2luZm8sIGVjaG89RkFMU0V9CmRldnRvb2xzOjpzZXNzaW9uX2luZm8oaW5jbHVkZV9iYXNlID0gVFJVRSkKYGBgCgpgYGB7ciB1cGxvYWRfdG9fZHJpdmUsIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMgdXBsb2FkIHRoZSBIVE1MIGFuZCBSbWQgZmlsZSB0byB0aGUgYXV0aG9yaW5nIHRlYW0ncyBzaGFyZWQgZm9sZGVyCmxpYnJhcnkoImdvb2dsZWRyaXZlIikKZ29vZ2xlZHJpdmU6OmRyaXZlX2F1dGgodXNlX29vYiA9IFRSVUUpCmdvb2dsZWRyaXZlOjpkcml2ZV9wdXQoImdpc2NpZW5jZS1oaXN0b3JpYy10ZXh0LWFuYWx5c2lzLlJtZCIsIHBhdGggPSAiaHR0cHM6Ly9kcml2ZS5nb29nbGUuY29tL2RyaXZlL2ZvbGRlcnMvMTdFVXRNX3pDeDFnUU1lYTFNSE5fNVhTVnJzc3h2OUdBLyIpCmdvb2dsZWRyaXZlOjpkcml2ZV9wdXQoImdpc2NpZW5jZS1oaXN0b3JpYy10ZXh0LWFuYWx5c2lzLmh0bWwiLCBwYXRoID0gImh0dHBzOi8vZHJpdmUuZ29vZ2xlLmNvbS9kcml2ZS9mb2xkZXJzLzE3RVV0TV96Q3gxZ1FNZWExTUhOXzVYU1Zyc3N4djlHQS8iKQpgYGAK