Causal Impact
Number of total users:
neda_liwc %>%
select(id) %>%
distinct() %>%
nrow()
## [1] 1746
|
Word Category
|
Relative Eff.(%)
|
P Value
|
|
Female
|
17.418
|
0.001
|
|
Anx
|
7.566
|
0.002
|
|
Family
|
6.452
|
0.005
|
|
Money
|
5.991
|
0.002
|
|
Relig
|
5.209
|
0.045
|
|
Achiev
|
3.813
|
0.011
|
|
They
|
3.397
|
0.034
|
|
Negate
|
2.889
|
0.003
|
|
Health
|
2.526
|
0.004
|
|
Power
|
2.458
|
0.010
|
|
Negemo
|
2.066
|
0.037
|
|
Informal
|
1.116
|
0.038
|
|
Ipron
|
-1.476
|
0.015
|
|
See
|
-2.036
|
0.025
|
|
You
|
-2.238
|
0.034
|
|
Differ
|
-2.694
|
0.006
|
|
Posemo
|
-3.277
|
0.001
|
|
Tentat
|
-3.347
|
0.001
|
|
Shehe
|
-7.042
|
0.020
|
|
Affiliation
|
-7.167
|
0.003
|
|
Friend
|
-16.459
|
0.041
|
CAUSAL IMPACT BY GENDER
Number of users by gender (1746 total):
neda_liwc_gender %>%
select(id, gender) %>%
distinct() %>%
count(gender)
## # A tibble: 3 x 2
## gender n
## <chr> <int>
## 1 f 762
## 2 m 313
## 3 u 671
Number of users in the baseline (2991 total):
baseline_liwc_gender %>%
select(id, gender) %>%
distinct() %>%
count(gender)
## # A tibble: 3 x 2
## gender n
## <chr> <int>
## 1 f 855
## 2 m 748
## 3 u 1388
baseline_liwc_gender %>%
select(-text, -created_at, -id_tweet, -name) %>%
group_by(gender, id, days_tweet) %>%
summarise_all(mean) %>%
ungroup() %>%
select(-id) %>%
group_by(gender, days_tweet) %>%
summarise_all(mean) %>%
ungroup() %>%
pivot_longer(cols = fun:filler, names_to = "categ", values_to = "values_baseline") -> ci_baseline
neda_liwc_gender %>%
select(-id_tweet, -name, -name_proc) %>%
group_by(gender, id, days_tweet) %>%
summarise_all(mean) %>%
ungroup() %>%
select(-id) %>%
group_by(gender, days_tweet) %>%
summarise_all(mean) %>%
ungroup() %>%
pivot_longer(fun:filler, names_to = "categ",
values_to = "values_neda") -> ci_neda_liwc
pre_period <- c(1, 16)
post_period <- c(17, 31)
ci_baseline %>%
full_join(ci_neda_liwc) -> d_second
d_second %>%
# count(gender, days_tweet) %>%
# view()
# view()
# select(categ, values_neda, values_baseline) %>%
# nest(data = - categ) %>%
select(gender, categ, values_neda, values_baseline) %>%
# filter(gender == "m") %>% view()
group_by(categ, gender) %>%
nest() %>%
ungroup() %>%
select(gender, categ, data) %>%
mutate(mod = map(data, ~CausalImpact::CausalImpact(.,
pre_period,
post_period))) -> ci
ci %>%
mutate(summary_mod = map(mod, "summary")) %>%
filter(!map_lgl(summary_mod, is.null)) -> ci_resul
ci_resul %>%
mutate(p = map(summary_mod, "p")) %>%
mutate(p = map_dbl(p, 1)) %>%
filter(categ %in% categories_in_gender) %>%
mutate(relative_effect = map(summary_mod, "RelEffect")) %>%
mutate(relative_effect = map_dbl(relative_effect, 2))-> sig_cat
# sig_cat %>%
# filter(categ %in% sel_cat) -> sig_cat
sig_cat %>%
arrange(gender, desc(relative_effect)) %>%
select(gender, categ,
second_relative_effect = relative_effect, p_second = p) -> second_ap
second_ap %>%
pivot_wider(id_cols = categ,
values_from = c(second_relative_effect, p_second),
names_from = gender) %>%
mutate(categ = str_to_title(categ)) %>%
mutate_at(vars(starts_with("second")), ~.*100) %>%
mutate_if(is.numeric, ~round(., digits = 3)) %>%
mutate_at(vars(starts_with("second")), function(x){
cell_spec(x, "html", color = spec_color(x), bold = T)
}) %>%
kable("html", escape = F,
align = "lrr",
col.names = c("Word Category", "FEMALE Relative Eff.(%)",
"MALE Relative Eff.(%)",
"UNKNOWN Relative Eff.(%)",
"FEMALE P Value",
"MALE P Value",
"UNKNOWN P Value")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE)
|
Word Category
|
FEMALE Relative Eff.(%)
|
MALE Relative Eff.(%)
|
UNKNOWN Relative Eff.(%)
|
FEMALE P Value
|
MALE P Value
|
UNKNOWN P Value
|
|
Female
|
13.112
|
24.294
|
23.987
|
0.001
|
0.001
|
0.001
|
|
Anx
|
13.005
|
-2.704
|
10.903
|
0.001
|
0.283
|
0.001
|
|
Family
|
6.994
|
4.204
|
15.167
|
0.003
|
0.092
|
0.001
|
|
They
|
5.827
|
1.555
|
0.672
|
0.010
|
0.330
|
0.415
|
|
Achiev
|
5.153
|
-2.931
|
4.033
|
0.018
|
0.078
|
0.030
|
|
Money
|
4.866
|
14.027
|
4.088
|
0.002
|
0.002
|
0.104
|
|
Negate
|
4.449
|
-6.645
|
6.511
|
0.001
|
0.025
|
0.008
|
|
Health
|
4.246
|
9.044
|
-2.452
|
0.010
|
0.001
|
0.132
|
|
Negemo
|
3.94
|
-3.356
|
0.572
|
0.001
|
0.055
|
0.388
|
|
See
|
2.013
|
0.151
|
-7.928
|
0.146
|
0.485
|
0.001
|
|
Power
|
1.014
|
1.295
|
4.504
|
0.253
|
0.213
|
0.001
|
|
Relig
|
0.745
|
8.26
|
12.547
|
0.426
|
0.079
|
0.012
|
|
Informal
|
-0.048
|
3.212
|
0.702
|
0.473
|
0.006
|
0.192
|
|
Ipron
|
-0.233
|
-3.002
|
-1.231
|
0.401
|
0.026
|
0.111
|
|
Differ
|
-0.539
|
-5.58
|
-0.83
|
0.340
|
0.006
|
0.224
|
|
Tentat
|
-0.93
|
-3.098
|
-5.979
|
0.233
|
0.050
|
0.001
|
|
You
|
-3.067
|
1.011
|
-2.898
|
0.014
|
0.249
|
0.046
|
|
Posemo
|
-3.119
|
-7.538
|
-1.434
|
0.001
|
0.001
|
0.099
|
|
Affiliation
|
-5.861
|
-8.878
|
-6.936
|
0.003
|
0.001
|
0.011
|
|
Shehe
|
-7.875
|
-1.764
|
-4.549
|
0.038
|
0.384
|
0.096
|
|
Friend
|
-11.06
|
-19.113
|
-19.873
|
0.135
|
0.002
|
0.054
|
Words inside categ:
The tables below contain the changes for the 4 most changed words (positive and negative) within each of the categories. The first column is the specific word. Changes_total is the difference between the “before” and “after” frequency of all users. Changes_f same as Changes_total but for female users, Changes_m for male users and Changes_u for unknown users.
library(tidyverse)
read_delim(here::here("data", "liwc", "LIWC2015_English_Flat.dic"),
delim = "\t", skip = 1, col_names = c("number", "name"),
n_max = 73) -> categories_name
read_tsv(here::here("data", "liwc", "LIWC2015_English_Flat.dic"),
skip = 75, col_names = paste0(c("x"), c("_"), 1:11),
guess_max = 6000, col_types = "ccccccccccc") %>%
mutate(x_1 = str_remove(x_1, "\\*")) -> words_dic
categories_name %>%
filter(name %in% c("female", "family", "anx", "shehe", "affiliation", "friend")) %>%
pull(number) -> number_top_categ
words_dic %>%
filter_at(vars(-x_1), any_vars(. %in% number_top_categ)) %>%
pull(x_1) -> words_cat
# neda_timelapse ----------------------------------------------------------
library(lubridate)
neda_hist <- read_rds(here::here("data", "NEDA_historical.rds")) %>%
distinct() %>%
filter(created_at_tweet >= ymd("2018-03-01")) %>%
mutate(text = str_to_lower(text),
neda_related = str_detect(text,
pattern = "#nedawareness|#comeasyouare|@nedastaff"))
gender_output <- read_tsv(here::here("data", "gender_extractor",
"neda_liwc_gender_output.tsv"),
col_names = c("id", "name", "name_proc", "gender"))
first_tweet <- neda_hist %>%
select(created_at_tweet, text, id, id_tweet, neda_related) %>%
filter(neda_related) %>%
arrange(created_at_tweet) %>%
group_by(id) %>%
slice(1) %>%
ungroup() %>%
select(cero_date = created_at_tweet, id) %>%
filter(cero_date >= ymd("2019-01-01"))
neda_change <- neda_hist %>%
select(id_tweet, text, created_at_tweet, id) %>%
inner_join(first_tweet) %>%
mutate(days_tweet = interval(start = cero_date, end = created_at_tweet),
days_tweet = round(time_length(days_tweet, unit = "days"))) %>%
select(-cero_date) %>%
filter(days_tweet >= -15, days_tweet <= 15)
neda_timelapse <- neda_change %>%
count(id, before_after = sign(days_tweet), sort = T) %>%
mutate(before_after = case_when(before_after == -1 ~ "before",
before_after == 1 ~ "after",
TRUE ~ "cero")) %>%
pivot_wider(values_from = n, names_from = before_after) %>%
filter(before >= 15 & after >= 15) %>%
select(-cero) %>%
semi_join(x = neda_change, y = .)
neda_timelapse %>%
inner_join(gender_output) -> neda_timelapse
library(tidytext)
replace_reg1 <- "https://t.co/[A-Za-z]\\d]+|"
replace_reg2 <- "https://t.co/[A-Za-z]\\d]+|&|<|>|RT|https"
replace_reg <- paste0(replace_reg1, replace_reg2)
unnest_reg <- "([^A-Za-z_\\d#@']|'(?![A-Za-z_\\d#@]))"
tidy_tweets <- neda_timelapse %>%
mutate(text = str_to_lower(text)) %>%
mutate(text = str_replace_all(text, replace_reg, "")) %>%
unnest_tokens(word, text, token = "regex", pattern = unnest_reg)
tidy_tweets %>%
filter(word %in% words_cat) %>%
mutate(days_tweet = case_when(days_tweet < 0 ~ "before",
days_tweet > 0 ~ "after",
TRUE ~ "cero")) %>%
filter(days_tweet != "cero") -> tidy_words
neda_liwc <- read_rds(here::here("data", "neda_liwc.rds")) %>%
select(-created_at_tweet) %>%
filter(abs(days_tweet) <= 15)
FEMALE CATEGORY
# female ------------------------------------------------------------------
# female -> 43
words_dic %>%
filter_at(vars(-x_1), any_vars(. == 43)) %>%
pull(x_1) -> words_female
tidy_words %>%
filter(word %in% words_female) %>%
count(days_tweet, word) %>%
mutate(gender = "t") %>%
bind_rows(tidy_words %>%
filter(word %in% words_female) %>%
count(gender, days_tweet, word)) %>%
pivot_wider(names_from = c(days_tweet, gender), values_from = n) %>%
mutate_if(is.numeric, ~replace_na(., 0)) %>%
mutate(changes_total = after_t - before_t,
changes_f = after_f - before_f,
changes_m = after_m - before_m,
changes_u = after_u - before_u) %>%
select(word, starts_with("changes")) %>%
arrange(desc(changes_total)) -> f
f_top <- f %>% top_n(4, wt = changes_total)
f_bottom <- f %>% top_n(-4, wt = changes_total)
f_top %>%
bind_rows(f_bottom) %>%
gt::gt()
| word |
changes_total |
changes_f |
changes_m |
changes_u |
| women |
2117 |
903 |
403 |
811 |
| her |
320 |
251 |
-18 |
87 |
| she |
228 |
296 |
-30 |
-38 |
| woman |
207 |
90 |
37 |
80 |
| gf |
-30 |
-20 |
-8 |
-2 |
| wife |
-78 |
-37 |
-43 |
2 |
| queen |
-96 |
1 |
-32 |
-65 |
| lady |
-158 |
-115 |
-22 |
-21 |
FAMILY
words_dic %>%
filter_at(vars(-x_1), any_vars(. == 41)) %>%
pull(x_1) -> words_family
tidy_words %>%
filter(word %in% words_family) %>%
count(days_tweet, word) %>%
mutate(gender = "t") %>%
bind_rows(tidy_words %>%
filter(word %in% words_family) %>%
count(gender, days_tweet, word)) %>%
pivot_wider(names_from = c(days_tweet, gender), values_from = n) %>%
mutate_if(is.numeric, ~replace_na(., 0)) %>%
mutate(changes_total = after_t - before_t,
changes_f = after_f - before_f,
changes_m = after_m - before_m,
changes_u = after_u - before_u) %>%
select(word, starts_with("changes")) %>%
arrange(desc(changes_total)) -> f
f_top <- f %>% top_n(4, wt = changes_total)
f_bottom <- f %>% top_n(-4, wt = changes_total)
f_top %>%
bind_rows(f_bottom) %>%
gt::gt()
| word |
changes_total |
changes_f |
changes_m |
changes_u |
| ma |
132 |
52 |
49 |
31 |
| family |
122 |
97 |
11 |
14 |
| daughter |
115 |
36 |
26 |
53 |
| families |
88 |
47 |
21 |
20 |
| mama |
-19 |
-24 |
-2 |
7 |
| pa |
-19 |
-10 |
7 |
-16 |
| daddy |
-23 |
-10 |
-6 |
-7 |
| bro |
-63 |
7 |
30 |
-100 |
| wife |
-78 |
-37 |
-43 |
2 |
ANXIETY
# anxiety -----------------------------------------------------------------
# anxiety -> 33
words_dic %>%
filter_at(vars(-x_1), any_vars(. == 33)) %>%
pull(x_1) -> words_anxiety
tidy_words %>%
filter(word %in% words_anxiety) %>%
count(days_tweet, word) %>%
mutate(gender = "t") %>%
bind_rows(tidy_words %>%
filter(word %in% words_anxiety) %>%
count(gender, days_tweet, word)) %>%
pivot_wider(names_from = c(days_tweet, gender), values_from = n) %>%
mutate_if(is.numeric, ~replace_na(., 0)) %>%
mutate(changes_total = after_t - before_t,
changes_f = after_f - before_f,
changes_m = after_m - before_m,
changes_u = after_u - before_u) %>%
select(word, starts_with("changes")) %>%
arrange(desc(changes_total)) -> f
f_top <- f %>% top_n(4, wt = changes_total)
f_bottom <- f %>% top_n(-4, wt = changes_total)
f_top %>%
bind_rows(f_bottom) %>%
gt::gt()
| word |
changes_total |
changes_f |
changes_m |
changes_u |
| risk |
190 |
16 |
117 |
57 |
| stress |
78 |
40 |
12 |
26 |
| upset |
73 |
32 |
13 |
28 |
| worried |
70 |
33 |
14 |
23 |
| confuse |
-10 |
-6 |
1 |
-5 |
| horrible |
-11 |
-5 |
3 |
-9 |
| doubt |
-21 |
-11 |
-1 |
-9 |
| scared |
-31 |
16 |
-13 |
-34 |
LS0tCnRpdGxlOiAiQ2F1c2FsIEltcGFjdCIgCmNsZWFuOiB0cnVlCm91dHB1dDoKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogZmFsc2UKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkKCnhmdW46OnBrZ19hdHRhY2goInRpZHl2ZXJzZSIsICJsdWJyaWRhdGUiLCAia2FibGVFeHRyYSIpCgp0aGVtZV9zZXQodGhlbWVfbGluZWRyYXcoKSkKYGBgCgojIyBDYXVzYWwgSW1wYWN0IAoKYGBge3IgZWNobz1GQUxTRX0KYmFzZWxpbmVfbGl3YyA8LSByZWFkX3JkcyhoZXJlOjpoZXJlKCJkYXRhIiwgImJhc2VsaW5lX2xpd2MucmRzIikpCgpuZWRhX2xpd2MgPC0gcmVhZF9yZHMoaGVyZTo6aGVyZSgiZGF0YSIsICJuZWRhX2xpd2MucmRzIikpICU+JSAKICBzZWxlY3QoLXRleHQsIC1jcmVhdGVkX2F0X3R3ZWV0KSAlPiUgCiAgZmlsdGVyKGFicyhkYXlzX3R3ZWV0KSA8PSAxNSkKICAKCnNlbF9jYXQgPC0gYygKICAiaSIsIndlIiwieW91Iiwic2hlaGUiLCJ0aGV5IiwiaXByb24iLCJuZWdhdGUiLCJjb21wYXJlIiwicG9zZW1vIiwibmVnZW1vIiwiYW54IiwiYW5nZXIiLCJzYWQiLCJzb2NpYWwiLCJmYW1pbHkiLCJmcmllbmQiLCJmZW1hbGUiLCJtYWxlIiwiaW5zaWdodCIsImNhdXNlIiwiZGlzY3JlcCIsInRlbnRhdCIsImNlcnRhaW4iLCJkaWZmZXIiLCJzZWUiLCJoZWFyIiwiZmVlbCIsImJvZHkiLCJoZWFsdGgiLCJzZXh1YWwiLCJpbmdlc3QiLCJhZmZpbGlhdGlvbiIsImFjaGlldiIsInBvd2VyIiwicmV3YXJkIiwicmlzayIsImZvY3VzcGFzdCIsImZvY3VzcHJlc2VudCIsImZvY3VzZnV0dXJlIiwicmVsYXRpdiIsIndvcmsiLCJsZWlzdXJlIiwiaG9tZSIsIm1vbmV5IiwicmVsaWciLCJkZWF0aCIsImluZm9ybWFsIiwic3dlYXIiLCJhc3NlbnQiLCJub25mbHUiLCJmaWxsZXIiCikKYGBgCgpOdW1iZXIgb2YgdG90YWwgdXNlcnM6CmBgYHtyfQpuZWRhX2xpd2MgJT4lIAogIHNlbGVjdChpZCkgJT4lIAogIGRpc3RpbmN0KCkgJT4lIAogIG5yb3coKQpgYGAKCmBgYHtyIGVjaG89RkFMU0V9CmJhc2VsaW5lX2xpd2MgJT4lIAogIHNlbGVjdCgtdGV4dCwgLWNyZWF0ZWRfYXQsIC1pZF90d2VldCkgJT4lIAogIGdyb3VwX2J5KGRheXNfdHdlZXQsIGlkKSAlPiUgCiAgc3VtbWFyaXNlX2FsbChtZWFuKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3QoLWlkKSAlPiUgCiAgZ3JvdXBfYnkoZGF5c190d2VldCkgJT4lIAogIHN1bW1hcmlzZV9hbGwobWVhbikgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBmdW46ZmlsbGVyLCBuYW1lc190byA9ICJjYXRlZyIsIHZhbHVlc190byA9ICJ2YWx1ZXNfYmFzZWxpbmUiKSAtPiBjaV9iYXNlbGluZQoKbmVkYV9saXdjICU+JSAKICBzZWxlY3QoLWlkX3R3ZWV0KSAlPiUgCiAgZ3JvdXBfYnkoZGF5c190d2VldCwgaWQpICU+JSAKICBzdW1tYXJpc2VfYWxsKG1lYW4pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdCgtaWQpICU+JSAKICBncm91cF9ieShkYXlzX3R3ZWV0KSAlPiUgCiAgc3VtbWFyaXNlX2FsbChtZWFuKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBwaXZvdF9sb25nZXIoLWRheXNfdHdlZXQsIG5hbWVzX3RvID0gImNhdGVnIiwgdmFsdWVzX3RvID0gInZhbHVlc19uZWRhIikgLT4gY2lfbmVkYV9saXdjIAogIApwcmVfcGVyaW9kIDwtIGMoMSwgMTYpCnBvc3RfcGVyaW9kIDwtIGMoMTcsIDMxKQoKY2lfYmFzZWxpbmUgJT4lIAogIGlubmVyX2pvaW4oY2lfbmVkYV9saXdjKSAtPiBkX3NlY29uZAoKZF9zZWNvbmQgJT4lIAogIHNlbGVjdChjYXRlZywgdmFsdWVzX25lZGEsIHZhbHVlc19iYXNlbGluZSkgJT4lIAogIG5lc3QoZGF0YSA9IC0gY2F0ZWcpICU+JSAKICBtdXRhdGUobW9kID0gbWFwKGRhdGEsIH5DYXVzYWxJbXBhY3Q6OkNhdXNhbEltcGFjdCguLCBwcmVfcGVyaW9kLCBwb3N0X3BlcmlvZCkpKSAtPiBjaQogIApjaSAlPiUgCiAgbXV0YXRlKHN1bW1hcnlfbW9kID0gbWFwKG1vZCwgInN1bW1hcnkiKSkgJT4lIAogIGZpbHRlcighbWFwX2xnbChzdW1tYXJ5X21vZCwgaXMubnVsbCkpIC0+IGNpX3Jlc3VsIAoKY2lfcmVzdWwgJT4lIAogIG11dGF0ZShwID0gbWFwKHN1bW1hcnlfbW9kLCAicCIpKSAlPiUgCiAgbXV0YXRlKHAgPSBtYXBfZGJsKHAsIDEpKSAlPiUgCiAgZmlsdGVyKHAgPCAwLjA1KSAlPiUgCiAgbXV0YXRlKHJlbGF0aXZlX2VmZmVjdCA9IG1hcChzdW1tYXJ5X21vZCwgIlJlbEVmZmVjdCIpKSAlPiUgCiAgbXV0YXRlKHJlbGF0aXZlX2VmZmVjdCA9IG1hcF9kYmwocmVsYXRpdmVfZWZmZWN0LCAyKSktPiBzaWdfY2F0CgpzaWdfY2F0ICU+JSAKICBmaWx0ZXIoY2F0ZWcgJWluJSBzZWxfY2F0KSAtPiBzaWdfY2F0CgpjYXRlZ29yaWVzX2luX2dlbmRlciA8LSBzaWdfY2F0ICU+JSBwdWxsKGNhdGVnKQoKc2lnX2NhdCAlPiUgCiAgYXJyYW5nZShkZXNjKHJlbGF0aXZlX2VmZmVjdCkpICU+JSAKICBzZWxlY3QoY2F0ZWcsIHNlY29uZF9yZWxhdGl2ZV9lZmZlY3QgPSByZWxhdGl2ZV9lZmZlY3QsIHBfc2Vjb25kID0gcCkgLT4gc2Vjb25kX2FwCgpzZWNvbmRfYXAgJT4lIAogIG11dGF0ZShjYXRlZyA9IHN0cl90b190aXRsZShjYXRlZykpICU+JSAKICBtdXRhdGVfYXQodmFycyhzZWNvbmRfcmVsYXRpdmVfZWZmZWN0KSwgfi4qMTAwKSAlPiUgCiAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIH5yb3VuZCguLCBkaWdpdHMgPSAzKSkgJT4lIAogIG11dGF0ZV9hdCh2YXJzKHNlY29uZF9yZWxhdGl2ZV9lZmZlY3QpLCBmdW5jdGlvbih4KXsKICAgIGNlbGxfc3BlYyh4LCAiaHRtbCIsIGNvbG9yID0gc3BlY19jb2xvcih4KSwgYm9sZCA9IFQpCiAgfSkgJT4lIAogIGthYmxlKCJodG1sIiwgZXNjYXBlID0gRiwKICAgICAgICBhbGlnbiA9ICJscnIiLAogICAgICAgIGNvbC5uYW1lcyA9IGMoIldvcmQgQ2F0ZWdvcnkiLCAiUmVsYXRpdmUgRWZmLiglKSIsCiAgICAgICAgICAgICAgICAgICAgICAiUCBWYWx1ZSIpKSAlPiUgCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIiksCiAgICAgICAgICAgICAgICBmdWxsX3dpZHRoID0gRkFMU0UpCmBgYAoKIyMgQ0FVU0FMIElNUEFDVCBCWSBHRU5ERVIKCmBgYHtyIGVjaG89RkFMU0V9CmJhc2VsaW5lX2xpd2NfZ2VuZGVyIDwtIHJlYWRfcmRzKGhlcmU6OmhlcmUoImRhdGEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiYXNlbGluZV9saXdjX2dlbmRlci5yZHMiKSkKCm5lZGFfbGl3Y19nZW5kZXIgPC0gcmVhZF9yZHMoaGVyZTo6aGVyZSgiZGF0YSIsICJuZWRhX2xpd2NfZ2VuZGVyLnJkcyIpKSAlPiUgCiAgIyBzZWxlY3QoLXRleHQsIC1jcmVhdGVkX2F0X3R3ZWV0KSAlPiUgCiAgZmlsdGVyKGFicyhkYXlzX3R3ZWV0KSA8PSAxNSkKCnNlbF9jYXQgPC0gYygKICAiaSIsIndlIiwieW91Iiwic2hlaGUiLCJ0aGV5IiwiaXByb24iLCJuZWdhdGUiLCJjb21wYXJlIiwicG9zZW1vIiwibmVnZW1vIiwiYW54IiwiYW5nZXIiLCJzYWQiLCJzb2NpYWwiLCJmYW1pbHkiLCJmcmllbmQiLCJmZW1hbGUiLCJtYWxlIiwiaW5zaWdodCIsImNhdXNlIiwiZGlzY3JlcCIsInRlbnRhdCIsImNlcnRhaW4iLCJkaWZmZXIiLCJzZWUiLCJoZWFyIiwiZmVlbCIsImJvZHkiLCJoZWFsdGgiLCJzZXh1YWwiLCJpbmdlc3QiLCJhZmZpbGlhdGlvbiIsImFjaGlldiIsInBvd2VyIiwicmV3YXJkIiwicmlzayIsImZvY3VzcGFzdCIsImZvY3VzcHJlc2VudCIsImZvY3VzZnV0dXJlIiwicmVsYXRpdiIsIndvcmsiLCJsZWlzdXJlIiwiaG9tZSIsIm1vbmV5IiwicmVsaWciLCJkZWF0aCIsImluZm9ybWFsIiwic3dlYXIiLCJhc3NlbnQiLCJub25mbHUiLCJmaWxsZXIiCikKYGBgCgpOdW1iZXIgb2YgdXNlcnMgYnkgZ2VuZGVyICgxNzQ2IHRvdGFsKToKYGBge3J9Cm5lZGFfbGl3Y19nZW5kZXIgJT4lIAogIHNlbGVjdChpZCwgZ2VuZGVyKSAlPiUgCiAgZGlzdGluY3QoKSAlPiUgCiAgY291bnQoZ2VuZGVyKQpgYGAKCk51bWJlciBvZiB1c2VycyBpbiB0aGUgYmFzZWxpbmUgKDI5OTEgdG90YWwpOgpgYGB7cn0KYmFzZWxpbmVfbGl3Y19nZW5kZXIgJT4lIAogIHNlbGVjdChpZCwgZ2VuZGVyKSAlPiUgCiAgZGlzdGluY3QoKSAlPiUgCiAgY291bnQoZ2VuZGVyKQpgYGAKCmBgYHtyIH0KYmFzZWxpbmVfbGl3Y19nZW5kZXIgJT4lIAogIHNlbGVjdCgtdGV4dCwgLWNyZWF0ZWRfYXQsIC1pZF90d2VldCwgLW5hbWUpICU+JSAKICBncm91cF9ieShnZW5kZXIsIGlkLCBkYXlzX3R3ZWV0KSAlPiUgCiAgc3VtbWFyaXNlX2FsbChtZWFuKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3QoLWlkKSAlPiUgCiAgZ3JvdXBfYnkoZ2VuZGVyLCBkYXlzX3R3ZWV0KSAlPiUgCiAgc3VtbWFyaXNlX2FsbChtZWFuKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGZ1bjpmaWxsZXIsIG5hbWVzX3RvID0gImNhdGVnIiwgdmFsdWVzX3RvID0gInZhbHVlc19iYXNlbGluZSIpIC0+IGNpX2Jhc2VsaW5lCgpuZWRhX2xpd2NfZ2VuZGVyICU+JSAKICBzZWxlY3QoLWlkX3R3ZWV0LCAtbmFtZSwgLW5hbWVfcHJvYykgJT4lIAogIGdyb3VwX2J5KGdlbmRlciwgaWQsIGRheXNfdHdlZXQpICU+JSAKICBzdW1tYXJpc2VfYWxsKG1lYW4pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdCgtaWQpICU+JSAKICBncm91cF9ieShnZW5kZXIsIGRheXNfdHdlZXQpICU+JSAKICBzdW1tYXJpc2VfYWxsKG1lYW4pICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHBpdm90X2xvbmdlcihmdW46ZmlsbGVyLCBuYW1lc190byA9ICJjYXRlZyIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsdWVzX25lZGEiKSAtPiBjaV9uZWRhX2xpd2MgCgpwcmVfcGVyaW9kIDwtIGMoMSwgMTYpCnBvc3RfcGVyaW9kIDwtIGMoMTcsIDMxKQoKY2lfYmFzZWxpbmUgJT4lIAogIGZ1bGxfam9pbihjaV9uZWRhX2xpd2MpIC0+IGRfc2Vjb25kCgpkX3NlY29uZCAlPiUgCiAgIyBjb3VudChnZW5kZXIsIGRheXNfdHdlZXQpICU+JSAKICAjIHZpZXcoKQogICMgdmlldygpCiAgIyBzZWxlY3QoY2F0ZWcsIHZhbHVlc19uZWRhLCB2YWx1ZXNfYmFzZWxpbmUpICU+JSAKICAjIG5lc3QoZGF0YSA9IC0gY2F0ZWcpICU+JSAKICBzZWxlY3QoZ2VuZGVyLCBjYXRlZywgdmFsdWVzX25lZGEsIHZhbHVlc19iYXNlbGluZSkgJT4lCiAgIyBmaWx0ZXIoZ2VuZGVyID09ICJtIikgJT4lIHZpZXcoKQogIGdyb3VwX2J5KGNhdGVnLCBnZW5kZXIpICU+JSAKICBuZXN0KCkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgc2VsZWN0KGdlbmRlciwgY2F0ZWcsIGRhdGEpICU+JSAKICBtdXRhdGUobW9kID0gbWFwKGRhdGEsIH5DYXVzYWxJbXBhY3Q6OkNhdXNhbEltcGFjdCguLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVfcGVyaW9kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc3RfcGVyaW9kKSkpIC0+IGNpCiAgCmNpICU+JSAKICBtdXRhdGUoc3VtbWFyeV9tb2QgPSBtYXAobW9kLCAic3VtbWFyeSIpKSAlPiUgCiAgZmlsdGVyKCFtYXBfbGdsKHN1bW1hcnlfbW9kLCBpcy5udWxsKSkgLT4gY2lfcmVzdWwgCgpjaV9yZXN1bCAlPiUgCiAgbXV0YXRlKHAgPSBtYXAoc3VtbWFyeV9tb2QsICJwIikpICU+JSAKICBtdXRhdGUocCA9IG1hcF9kYmwocCwgMSkpICU+JSAKICBmaWx0ZXIoY2F0ZWcgJWluJSBjYXRlZ29yaWVzX2luX2dlbmRlcikgJT4lIAogIG11dGF0ZShyZWxhdGl2ZV9lZmZlY3QgPSBtYXAoc3VtbWFyeV9tb2QsICJSZWxFZmZlY3QiKSkgJT4lIAogIG11dGF0ZShyZWxhdGl2ZV9lZmZlY3QgPSBtYXBfZGJsKHJlbGF0aXZlX2VmZmVjdCwgMikpLT4gc2lnX2NhdAoKIyBzaWdfY2F0ICU+JSAKIyAgIGZpbHRlcihjYXRlZyAlaW4lIHNlbF9jYXQpIC0+IHNpZ19jYXQKCnNpZ19jYXQgJT4lIAogIGFycmFuZ2UoZ2VuZGVyLCBkZXNjKHJlbGF0aXZlX2VmZmVjdCkpICU+JSAKICBzZWxlY3QoZ2VuZGVyLCBjYXRlZywgCiAgICAgICAgIHNlY29uZF9yZWxhdGl2ZV9lZmZlY3QgPSByZWxhdGl2ZV9lZmZlY3QsIHBfc2Vjb25kID0gcCkgLT4gc2Vjb25kX2FwCgpzZWNvbmRfYXAgJT4lIAogIHBpdm90X3dpZGVyKGlkX2NvbHMgPSBjYXRlZywgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBjKHNlY29uZF9yZWxhdGl2ZV9lZmZlY3QsIHBfc2Vjb25kKSwKICAgICAgICAgICAgICBuYW1lc19mcm9tID0gZ2VuZGVyKSAlPiUgCiAgbXV0YXRlKGNhdGVnID0gc3RyX3RvX3RpdGxlKGNhdGVnKSkgJT4lIAogIG11dGF0ZV9hdCh2YXJzKHN0YXJ0c193aXRoKCJzZWNvbmQiKSksIH4uKjEwMCkgJT4lIAogIG11dGF0ZV9pZihpcy5udW1lcmljLCB+cm91bmQoLiwgZGlnaXRzID0gMykpICU+JSAKICBtdXRhdGVfYXQodmFycyhzdGFydHNfd2l0aCgic2Vjb25kIikpLCBmdW5jdGlvbih4KXsKICAgIGNlbGxfc3BlYyh4LCAiaHRtbCIsIGNvbG9yID0gc3BlY19jb2xvcih4KSwgYm9sZCA9IFQpCiAgfSkgJT4lIAogIGthYmxlKCJodG1sIiwgZXNjYXBlID0gRiwKICAgICAgICBhbGlnbiA9ICJscnIiLAogICAgICAgIGNvbC5uYW1lcyA9IGMoIldvcmQgQ2F0ZWdvcnkiLCAiRkVNQUxFIFJlbGF0aXZlIEVmZi4oJSkiLAogICAgICAgICAgICAgICAgICAgICAgIk1BTEUgUmVsYXRpdmUgRWZmLiglKSIsCiAgICAgICAgICAgICAgICAgICAgICAiVU5LTk9XTiBSZWxhdGl2ZSBFZmYuKCUpIiwKICAgICAgICAgICAgICAgICAgICAgICJGRU1BTEUgUCBWYWx1ZSIsCiAgICAgICAgICAgICAgICAgICAgICAiTUFMRSBQIFZhbHVlIiwKICAgICAgICAgICAgICAgICAgICAgICJVTktOT1dOIFAgVmFsdWUiKSkgJT4lICAKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiKSwKICAgICAgICAgICAgICAgIGZ1bGxfd2lkdGggPSBGQUxTRSkKYGBgCgojIyBXb3JkcyBpbnNpZGUgY2F0ZWc6CgpUaGUgdGFibGVzIGJlbG93IGNvbnRhaW4gdGhlIGNoYW5nZXMgZm9yIHRoZSA0IG1vc3QgY2hhbmdlZCB3b3JkcyAocG9zaXRpdmUgYW5kIG5lZ2F0aXZlKSB3aXRoaW4gZWFjaCBvZiB0aGUgY2F0ZWdvcmllcy4gVGhlIGZpcnN0IGNvbHVtbiBpcyB0aGUgc3BlY2lmaWMgd29yZC4gQ2hhbmdlc190b3RhbCBpcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSAiYmVmb3JlIiBhbmQgImFmdGVyIiBmcmVxdWVuY3kgb2YgYWxsIHVzZXJzLiBDaGFuZ2VzX2Ygc2FtZSBhcyBDaGFuZ2VzX3RvdGFsIGJ1dCBmb3IgZmVtYWxlIHVzZXJzLCBDaGFuZ2VzX20gZm9yIG1hbGUgdXNlcnMgYW5kIENoYW5nZXNfdSBmb3IgdW5rbm93biB1c2Vycy4KCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKCnJlYWRfZGVsaW0oaGVyZTo6aGVyZSgiZGF0YSIsICJsaXdjIiwgIkxJV0MyMDE1X0VuZ2xpc2hfRmxhdC5kaWMiKSwKICAgICAgICAgICBkZWxpbSA9ICJcdCIsIHNraXAgPSAxLCBjb2xfbmFtZXMgPSBjKCJudW1iZXIiLCAibmFtZSIpLCAKICAgICAgICAgICBuX21heCA9IDczKSAtPiBjYXRlZ29yaWVzX25hbWUgCgpyZWFkX3RzdihoZXJlOjpoZXJlKCJkYXRhIiwgImxpd2MiLCAiTElXQzIwMTVfRW5nbGlzaF9GbGF0LmRpYyIpLAogICAgICAgICBza2lwID0gNzUsIGNvbF9uYW1lcyA9IHBhc3RlMChjKCJ4IiksIGMoIl8iKSwgMToxMSksCiAgICAgICAgIGd1ZXNzX21heCA9IDYwMDAsIGNvbF90eXBlcyA9ICJjY2NjY2NjY2NjYyIpICU+JSAKICBtdXRhdGUoeF8xID0gc3RyX3JlbW92ZSh4XzEsICJcXCoiKSkgLT4gd29yZHNfZGljCgpjYXRlZ29yaWVzX25hbWUgJT4lIAogIGZpbHRlcihuYW1lICVpbiUgYygiZmVtYWxlIiwgImZhbWlseSIsICJhbngiLCAic2hlaGUiLCAiYWZmaWxpYXRpb24iLCAiZnJpZW5kIikpICU+JSAKICBwdWxsKG51bWJlcikgLT4gbnVtYmVyX3RvcF9jYXRlZwoKd29yZHNfZGljICU+JSAKICBmaWx0ZXJfYXQodmFycygteF8xKSwgYW55X3ZhcnMoLiAlaW4lIG51bWJlcl90b3BfY2F0ZWcpKSAlPiUgIAogIHB1bGwoeF8xKSAtPiB3b3Jkc19jYXQKCgojIG5lZGFfdGltZWxhcHNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmxpYnJhcnkobHVicmlkYXRlKQoKbmVkYV9oaXN0IDwtIHJlYWRfcmRzKGhlcmU6OmhlcmUoImRhdGEiLCAiTkVEQV9oaXN0b3JpY2FsLnJkcyIpKSAlPiUgCiAgZGlzdGluY3QoKSAlPiUgCiAgZmlsdGVyKGNyZWF0ZWRfYXRfdHdlZXQgPj0geW1kKCIyMDE4LTAzLTAxIikpICU+JSAKICBtdXRhdGUodGV4dCA9IHN0cl90b19sb3dlcih0ZXh0KSwKICAgICAgICAgbmVkYV9yZWxhdGVkID0gc3RyX2RldGVjdCh0ZXh0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuID0gIiNuZWRhd2FyZW5lc3N8I2NvbWVhc3lvdWFyZXxAbmVkYXN0YWZmIikpIAoKZ2VuZGVyX291dHB1dCA8LSByZWFkX3RzdihoZXJlOjpoZXJlKCJkYXRhIiwgImdlbmRlcl9leHRyYWN0b3IiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJuZWRhX2xpd2NfZ2VuZGVyX291dHB1dC50c3YiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfbmFtZXMgPSBjKCJpZCIsICJuYW1lIiwgIm5hbWVfcHJvYyIsICJnZW5kZXIiKSkKCmZpcnN0X3R3ZWV0IDwtIG5lZGFfaGlzdCAlPiUgCiAgc2VsZWN0KGNyZWF0ZWRfYXRfdHdlZXQsIHRleHQsIGlkLCBpZF90d2VldCwgbmVkYV9yZWxhdGVkKSAlPiUgCiAgZmlsdGVyKG5lZGFfcmVsYXRlZCkgJT4lIAogIGFycmFuZ2UoY3JlYXRlZF9hdF90d2VldCkgJT4lIAogIGdyb3VwX2J5KGlkKSAlPiUgCiAgc2xpY2UoMSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgc2VsZWN0KGNlcm9fZGF0ZSA9IGNyZWF0ZWRfYXRfdHdlZXQsIGlkKSAlPiUgCiAgZmlsdGVyKGNlcm9fZGF0ZSA+PSB5bWQoIjIwMTktMDEtMDEiKSkKCm5lZGFfY2hhbmdlIDwtIG5lZGFfaGlzdCAlPiUgCiAgc2VsZWN0KGlkX3R3ZWV0LCB0ZXh0LCBjcmVhdGVkX2F0X3R3ZWV0LCBpZCkgJT4lIAogIGlubmVyX2pvaW4oZmlyc3RfdHdlZXQpICU+JSAKICBtdXRhdGUoZGF5c190d2VldCA9IGludGVydmFsKHN0YXJ0ID0gY2Vyb19kYXRlLCBlbmQgPSBjcmVhdGVkX2F0X3R3ZWV0KSwKICAgICAgICAgZGF5c190d2VldCA9IHJvdW5kKHRpbWVfbGVuZ3RoKGRheXNfdHdlZXQsIHVuaXQgPSAiZGF5cyIpKSkgJT4lIAogIHNlbGVjdCgtY2Vyb19kYXRlKSAlPiUgCiAgZmlsdGVyKGRheXNfdHdlZXQgPj0gLTE1LCBkYXlzX3R3ZWV0IDw9IDE1KQoKbmVkYV90aW1lbGFwc2UgPC0gbmVkYV9jaGFuZ2UgJT4lCiAgY291bnQoaWQsIGJlZm9yZV9hZnRlciA9IHNpZ24oZGF5c190d2VldCksIHNvcnQgPSBUKSAlPiUgCiAgbXV0YXRlKGJlZm9yZV9hZnRlciA9IGNhc2Vfd2hlbihiZWZvcmVfYWZ0ZXIgPT0gLTEgfiAiYmVmb3JlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlZm9yZV9hZnRlciA9PSAxIH4gImFmdGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAiY2VybyIpKSAlPiUgCiAgcGl2b3Rfd2lkZXIodmFsdWVzX2Zyb20gPSBuLCBuYW1lc19mcm9tID0gYmVmb3JlX2FmdGVyKSAlPiUgCiAgZmlsdGVyKGJlZm9yZSA+PSAxNSAmIGFmdGVyID49IDE1KSAlPiUgCiAgc2VsZWN0KC1jZXJvKSAlPiUgCiAgc2VtaV9qb2luKHggPSBuZWRhX2NoYW5nZSwgeSA9IC4pCgpuZWRhX3RpbWVsYXBzZSAlPiUgCiAgaW5uZXJfam9pbihnZW5kZXJfb3V0cHV0KSAtPiBuZWRhX3RpbWVsYXBzZQoKbGlicmFyeSh0aWR5dGV4dCkKCnJlcGxhY2VfcmVnMSA8LSAiaHR0cHM6Ly90LmNvL1tBLVphLXpdXFxkXSt8IgpyZXBsYWNlX3JlZzIgPC0gImh0dHBzOi8vdC5jby9bQS1aYS16XVxcZF0rfCZhbXA7fCZsdDt8Jmd0O3xSVHxodHRwcyIKcmVwbGFjZV9yZWcgPC0gcGFzdGUwKHJlcGxhY2VfcmVnMSwgcmVwbGFjZV9yZWcyKQp1bm5lc3RfcmVnIDwtICIoW15BLVphLXpfXFxkI0AnXXwnKD8hW0EtWmEtel9cXGQjQF0pKSIKCnRpZHlfdHdlZXRzIDwtIG5lZGFfdGltZWxhcHNlICU+JQogIG11dGF0ZSh0ZXh0ID0gc3RyX3RvX2xvd2VyKHRleHQpKSAlPiUgCiAgbXV0YXRlKHRleHQgPSBzdHJfcmVwbGFjZV9hbGwodGV4dCwgcmVwbGFjZV9yZWcsICIiKSkgJT4lIAogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCwgdG9rZW4gPSAicmVnZXgiLCBwYXR0ZXJuID0gdW5uZXN0X3JlZykKCnRpZHlfdHdlZXRzICU+JSAKICBmaWx0ZXIod29yZCAlaW4lIHdvcmRzX2NhdCkgJT4lIAogIG11dGF0ZShkYXlzX3R3ZWV0ID0gY2FzZV93aGVuKGRheXNfdHdlZXQgPCAwIH4gImJlZm9yZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF5c190d2VldCA+IDAgfiAiYWZ0ZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAiY2VybyIpKSAlPiUgCiAgZmlsdGVyKGRheXNfdHdlZXQgIT0gImNlcm8iKSAtPiB0aWR5X3dvcmRzCgpuZWRhX2xpd2MgPC0gcmVhZF9yZHMoaGVyZTo6aGVyZSgiZGF0YSIsICJuZWRhX2xpd2MucmRzIikpICU+JSAKICBzZWxlY3QoLWNyZWF0ZWRfYXRfdHdlZXQpICU+JSAKICBmaWx0ZXIoYWJzKGRheXNfdHdlZXQpIDw9IDE1KQoKYGBgCgojIyMgRkVNQUxFIENBVEVHT1JZCgpgYGB7cn0KIyBmZW1hbGUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgZmVtYWxlIC0+IDQzCgp3b3Jkc19kaWMgJT4lIAogIGZpbHRlcl9hdCh2YXJzKC14XzEpLCBhbnlfdmFycyguID09IDQzKSkgJT4lIAogIHB1bGwoeF8xKSAtPiB3b3Jkc19mZW1hbGUKCnRpZHlfd29yZHMgJT4lIAogIGZpbHRlcih3b3JkICVpbiUgd29yZHNfZmVtYWxlKSAlPiUgCiAgY291bnQoZGF5c190d2VldCwgd29yZCkgJT4lIAogIG11dGF0ZShnZW5kZXIgPSAidCIpICU+JSAKICBiaW5kX3Jvd3ModGlkeV93b3JkcyAlPiUgCiAgICAgICAgICAgICAgZmlsdGVyKHdvcmQgJWluJSB3b3Jkc19mZW1hbGUpICU+JSAKICAgICAgICAgICAgICBjb3VudChnZW5kZXIsIGRheXNfdHdlZXQsIHdvcmQpKSAlPiUgCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGMoZGF5c190d2VldCwgZ2VuZGVyKSwgdmFsdWVzX2Zyb20gPSBuKSAlPiUgCiAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIH5yZXBsYWNlX25hKC4sIDApKSAlPiUgCiAgbXV0YXRlKGNoYW5nZXNfdG90YWwgPSBhZnRlcl90IC0gYmVmb3JlX3QsCiAgICAgICAgIGNoYW5nZXNfZiA9IGFmdGVyX2YgLSBiZWZvcmVfZiwKICAgICAgICAgY2hhbmdlc19tID0gYWZ0ZXJfbSAtIGJlZm9yZV9tLAogICAgICAgICBjaGFuZ2VzX3UgPSBhZnRlcl91IC0gYmVmb3JlX3UpICU+JSAKICBzZWxlY3Qod29yZCwgc3RhcnRzX3dpdGgoImNoYW5nZXMiKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhjaGFuZ2VzX3RvdGFsKSkgLT4gZiAKCmZfdG9wIDwtIGYgJT4lIHRvcF9uKDQsIHd0ID0gY2hhbmdlc190b3RhbCkKZl9ib3R0b20gPC0gZiAlPiUgdG9wX24oLTQsIHd0ID0gY2hhbmdlc190b3RhbCkKCmZfdG9wICU+JSAKICBiaW5kX3Jvd3MoZl9ib3R0b20pICU+JSAKICBndDo6Z3QoKQpgYGAKCiMjIyBGQU1JTFkKCmBgYHtyfQp3b3Jkc19kaWMgJT4lIAogIGZpbHRlcl9hdCh2YXJzKC14XzEpLCBhbnlfdmFycyguID09IDQxKSkgJT4lIAogIHB1bGwoeF8xKSAtPiB3b3Jkc19mYW1pbHkKCnRpZHlfd29yZHMgJT4lIAogIGZpbHRlcih3b3JkICVpbiUgd29yZHNfZmFtaWx5KSAlPiUgCiAgY291bnQoZGF5c190d2VldCwgd29yZCkgJT4lIAogIG11dGF0ZShnZW5kZXIgPSAidCIpICU+JSAKICBiaW5kX3Jvd3ModGlkeV93b3JkcyAlPiUgCiAgICAgICAgICAgICAgZmlsdGVyKHdvcmQgJWluJSB3b3Jkc19mYW1pbHkpICU+JSAKICAgICAgICAgICAgICBjb3VudChnZW5kZXIsIGRheXNfdHdlZXQsIHdvcmQpKSAlPiUgCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGMoZGF5c190d2VldCwgZ2VuZGVyKSwgdmFsdWVzX2Zyb20gPSBuKSAlPiUgCiAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIH5yZXBsYWNlX25hKC4sIDApKSAlPiUgCiAgbXV0YXRlKGNoYW5nZXNfdG90YWwgPSBhZnRlcl90IC0gYmVmb3JlX3QsCiAgICAgICAgIGNoYW5nZXNfZiA9IGFmdGVyX2YgLSBiZWZvcmVfZiwKICAgICAgICAgY2hhbmdlc19tID0gYWZ0ZXJfbSAtIGJlZm9yZV9tLAogICAgICAgICBjaGFuZ2VzX3UgPSBhZnRlcl91IC0gYmVmb3JlX3UpICU+JSAKICBzZWxlY3Qod29yZCwgc3RhcnRzX3dpdGgoImNoYW5nZXMiKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhjaGFuZ2VzX3RvdGFsKSkgIC0+IGYgCgpmX3RvcCA8LSBmICU+JSB0b3Bfbig0LCB3dCA9IGNoYW5nZXNfdG90YWwpCmZfYm90dG9tIDwtIGYgJT4lIHRvcF9uKC00LCB3dCA9IGNoYW5nZXNfdG90YWwpCgpmX3RvcCAlPiUgCiAgYmluZF9yb3dzKGZfYm90dG9tKSAlPiUgCiAgZ3Q6Omd0KCkKYGBgCgojIyMgQU5YSUVUWQoKYGBge3J9CiMgYW54aWV0eSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIGFueGlldHkgLT4gMzMKCndvcmRzX2RpYyAlPiUgCiAgZmlsdGVyX2F0KHZhcnMoLXhfMSksIGFueV92YXJzKC4gPT0gMzMpKSAlPiUgCiAgcHVsbCh4XzEpIC0+IHdvcmRzX2FueGlldHkKCnRpZHlfd29yZHMgJT4lIAogIGZpbHRlcih3b3JkICVpbiUgd29yZHNfYW54aWV0eSkgJT4lIAogIGNvdW50KGRheXNfdHdlZXQsIHdvcmQpICU+JSAKICBtdXRhdGUoZ2VuZGVyID0gInQiKSAlPiUgCiAgYmluZF9yb3dzKHRpZHlfd29yZHMgJT4lIAogICAgICAgICAgICAgIGZpbHRlcih3b3JkICVpbiUgd29yZHNfYW54aWV0eSkgJT4lIAogICAgICAgICAgICAgIGNvdW50KGdlbmRlciwgZGF5c190d2VldCwgd29yZCkpICU+JSAKICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gYyhkYXlzX3R3ZWV0LCBnZW5kZXIpLCB2YWx1ZXNfZnJvbSA9IG4pICU+JSAKICBtdXRhdGVfaWYoaXMubnVtZXJpYywgfnJlcGxhY2VfbmEoLiwgMCkpICU+JSAKICBtdXRhdGUoY2hhbmdlc190b3RhbCA9IGFmdGVyX3QgLSBiZWZvcmVfdCwKICAgICAgICAgY2hhbmdlc19mID0gYWZ0ZXJfZiAtIGJlZm9yZV9mLAogICAgICAgICBjaGFuZ2VzX20gPSBhZnRlcl9tIC0gYmVmb3JlX20sCiAgICAgICAgIGNoYW5nZXNfdSA9IGFmdGVyX3UgLSBiZWZvcmVfdSkgJT4lIAogIHNlbGVjdCh3b3JkLCBzdGFydHNfd2l0aCgiY2hhbmdlcyIpKSAlPiUgCiAgYXJyYW5nZShkZXNjKGNoYW5nZXNfdG90YWwpKSAgLT4gZiAKCmZfdG9wIDwtIGYgJT4lIHRvcF9uKDQsIHd0ID0gY2hhbmdlc190b3RhbCkKZl9ib3R0b20gPC0gZiAlPiUgdG9wX24oLTQsIHd0ID0gY2hhbmdlc190b3RhbCkKCmZfdG9wICU+JSAKICBiaW5kX3Jvd3MoZl9ib3R0b20pICU+JSAKICBndDo6Z3QoKQpgYGAKCiMjIENPTU1PTiBXT1JEUyBJTiBUV0VFVFMgQlkgV09SRFMgQ0FURUdPUlk6CgpgYGB7cn0KbmVkYV9saXdjX2dlbmRlciAlPiUgCiAgZmlsdGVyKGRheXNfdHdlZXQgPj0gMCkgJT4lIAogIHNlbGVjdChpZF90d2VldCwgaWQsIGdlbmRlciwgZmFtaWx5LCBmZW1hbGUsIGFueCkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gZmFtaWx5OmFueCkgJT4lIAogIGZpbHRlcih2YWx1ZSA+IDApICU+JSAKICBsZWZ0X2pvaW4obmVkYV9saXdjICU+JSAKICAgICAgICAgICAgICBzZWxlY3QoaWQsIGlkX3R3ZWV0LCB0ZXh0KSkgJT4lICAKICByZW5hbWUoImNhdGVnb3J5IiA9IG5hbWUpICU+JSAKICBtdXRhdGUodGV4dCA9IHN0cl9yZW1vdmVfYWxsKHRleHQsIHBhdHRlcm4gPSAiWzpncmFwaDpdKyjigKYpIikpICU+JSAKICB1bm5lc3RfdG9rZW5zKHdvcmQsIHRleHQsIHRva2VuID0gInR3ZWV0cyIpICU+JSAgCiAgZmlsdGVyKCF3b3JkICVpbiUgc3RvcF93b3JkcyR3b3JkLAogICAgICAgICAhd29yZCAlaW4lIGMoImRlIiwgNCwgImRhIiwgImxhIiwgImVuIiwgImxlIiwgImxvcyIsIDMpLAogICAgICAgICB3b3JkICE9ICJydCIsCiAgICAgICAgICF3b3JkICVpbiUgc3RyX3JlbW92ZV9hbGwoc3RvcF93b3JkcyR3b3JkLCAiJyIpKSAlPiUgCiAgbXV0YXRlKHdvcmQgPSBjYXNlX3doZW4oY2F0ZWdvcnkgPT0gImZlbWFsZSIgJiB3b3JkICVpbiUgYyh3b3Jkc19mZW1hbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid29tZW5zIikgfiBOQV9jaGFyYWN0ZXJfLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGVnb3J5ID09ICJmYW1pbHkiICYgd29yZCAlaW4lIGMod29yZHNfZmFtaWx5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBhcmVudHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJyb3RoZXJzIil+IE5BX2NoYXJhY3Rlcl8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0ZWdvcnkgPT0gImFueCIgJiB3b3JkICVpbiUgd29yZHNfYW54aWV0eSB+IE5BX2NoYXJhY3Rlcl8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IHdvcmQpKSAlPiUgCiAgZmlsdGVyKCFpcy5uYSh3b3JkKSwKICAgICAgICAgd29yZCAhPSAiYW1wIikgJT4lIAogIGNvdW50KGNhdGVnb3J5LCBnZW5kZXIsIHdvcmQsIHNvcnQgPSBUKSAlPiUKICBncm91cF9ieShnZW5kZXIsIGNhdGVnb3J5KSAlPiUgCiAgdG9wX24oMTAsIHd0ID0gbikgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGMoY2F0ZWdvcnksIHdvcmQpLCBuYW1lc19mcm9tID0gZ2VuZGVyLCB2YWx1ZXNfZnJvbSA9IG4pICU+JSAKICBtdXRhdGUoY2F0ZWdvcnkgPSBzdHJfdG9fdGl0bGUoY2F0ZWdvcnkpKSAlPiUgCiAgZ3Q6Omd0KGdyb3VwbmFtZV9jb2wgPSAiY2F0ZWdvcnkiLAogICAgICAgICByb3duYW1lX2NvbCA9ICJ3b3JkIikgICAKICAKYGBgCgo=