library(ggbeeswarm)
Loading required package: ggplot2
library(gt)
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
library(tictoc)
source(here::here("src/common_basis.R"))
here() starts at /Users/jiemakel/tyo/disc-analysis
── Attaching core tidyverse packages ────────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.2     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ lubridate 1.9.2     ✔ tibble    3.2.1
✔ purrr     1.0.1     ✔ tidyr     1.3.0── Conflicts ──────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errorsRegistered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
centiles <- seq(0,1,by=0.1)
percentiles <- seq(0,1,by=0.01)

Fetal personhood

abortion_tweets_c %>% 
  count(reply_count) %>%
  ggplot(aes(x=reply_count,y=n)) +
  geom_point(size=0.5) +
  scale_y_log10() +
  scale_x_log10() +
  theme_hsci_discrete() +
  ggtitle("Reply count distribution")

abortion_tweets_c %>% 
  count(retweet_count) %>%
  ggplot(aes(x=retweet_count,y=n)) +
  geom_point(size=0.5) +
  scale_y_log10() +
  scale_x_log10() +
  theme_hsci_discrete() +
  ggtitle("Retweet count distribution")

abortion_tweets_c %>% 
  count(like_count) %>%
  ggplot(aes(x=like_count,y=n)) +
  geom_point(size=0.5) +
  scale_y_log10() +
  scale_x_log10() +
  theme_hsci_discrete() +
  ggtitle("Like count distribution")

Incels

incel_threads_c %>% 
  count(thread_label, posts) %>%
  group_by(thread_label) %>%
  mutate(prop=n/sum(n)) %>%
  ungroup() %>%
  ggplot(aes(x=posts,y=prop, color=thread_label)) +
  geom_line() +
  scale_y_log10() +
  scale_x_log10() +
  theme_hsci_discrete() +
  ggtitle("Thread length distribution by label")

incel_quotes_c %>% 
  filter(quoted_post_id != 0, quoted_post_id!=quoting_post_id) %>%
  count(quoted_post_id) %>%
  count(n) %>%
  arrange(desc(nn)) %>%
  ggplot(aes(x=n,y=nn)) + 
  geom_point() +
  theme_hsci_discrete() +
  scale_y_log10() +
  ggtitle("Distribution of the number of times a message has been quoted")
Storing counts in nn, as n already present in input
ℹ Use `name = "new_name"` to pick a new name.

incel_quote_tree_a <- incel_quotes_a %>%
  inner_join(incel_posts_a %>% select(quoting_post_id=post_id,quoting_post_poster_id=poster_id)) %>%
    inner_join(incel_posts_a %>% select(quoted_post_id=post_id,quoted_post_poster_id=poster_id)) %>%
  distinct(quoting_post_id,quoted_post_id,quoting_post_poster_id,quoted_post_poster_id) %>%
  filter(quoted_post_id!=0,quoted_post_id!=quoting_post_id) %>%
  compute_a(name="incel_quote_tree_a", unique_indexes=list(c("quoting_post_id","quoted_post_id"),c("quoted_post_id","quoting_post_id")), temporary=FALSE, overwrite=TRUE)
ancestors_q <- tbl(con,sql('
WITH RECURSIVE ancestors AS ( 
  SELECT quoting_post_id AS descendant_post_id, quoted_post_id AS ancestor_post_id, 1 AS length
  FROM incel_quote_tree_a
  UNION 
  SELECT a.descendant_post_id, qt.quoted_post_id AS ancestor_post_id, length+1 AS length
  FROM incel_quote_tree_a qt, ancestors a
  WHERE qt.quoting_post_id = a.ancestor_post_id
) 
SELECT * FROM ancestors'))
descendants_q <- tbl(con,sql('
WITH RECURSIVE descendants AS ( 
  SELECT quoting_post_id AS descendant_post_id, quoted_post_id AS ancestor_post_id, 1 AS length
  FROM incel_quote_tree_a
  UNION 
  SELECT qt.quoting_post_id AS descendant_post_id, ancestor_post_id, length+1 AS length
  FROM incel_quote_tree_a qt, descendants d
  WHERE qt.quoted_post_id = d.descendant_post_id
) 
SELECT * FROM descendants'))
tic()
reply_depth_a <- descendants_q %>% 
  group_by(descendant_post_id) %>%
  filter(length==max(length)) %>%
  ungroup() %>%
  compute_a(name="reply_depth_a",unique_indexes=list(c("descendant_post_id","ancestor_post_id"),c("ancestor_post_id","descendant_post_id")),temporary=FALSE,overwrite=TRUE)
toc()
reply_depth_a %>% 
  group_by(ancestor_post_id) %>%
  filter(length==max(length)) %>%
  ungroup() %>%
  count(length) %>% 
  ggplot(aes(x=length,y=n)) + 
  geom_point(size=0.5) +
  scale_y_log10() +
  theme_hsci_discrete() +
  ggtitle("Quote chain (~discussion) length distribution")

grandparent_q <- tbl(con,sql("
WITH three_posts AS (
  SELECT DISTINCT q1.quoting_post_id AS child_post_id, p1.poster_id AS child_user_id, q2.quoting_post_id AS parent_post_id, p2.poster_id AS parent_user_id, q2.quoted_post_id AS grandparent_post_id, p3.poster_id AS grandparent_user_id
  FROM incel_quotes_a q1
  INNER JOIN incel_quotes_a q2 ON (q1.quoted_post_id=q2.quoting_post_id)
  INNER JOIN incel_posts_a p1 ON (q1.quoting_post_id=p1.post_id)
  INNER JOIN incel_posts_a p2 ON (q1.quoted_post_id=p2.post_id)
  INNER JOIN incel_posts_a p3 ON (q2.quoted_post_id=p3.post_id)
  WHERE
   q2.quoted_post_id!=0 AND
   q2.quoting_post_id!=q2.quoted_post_id
)
SELECT * FROM three_posts"))
incel_quote_triplets_a <- grandparent_q %>%
  compute_a("incel_quote_triplets_a", temporary=FALSE, overwrite=TRUE)
ifqtriplets_a <- incel_quote_triplets_a %>%
  filter(child_user_id==grandparent_user_id) %>%
  compute_a("ifqtriplets_a", temporary=FALSE, overwrite=TRUE, unique_indexes=list(c("child_post_id","grandparent_post_id", "parent_post_id")))
paired_tree_q <- tbl(con,sql("
WITH RECURSIVE ancestors AS ( 
  SELECT child_post_id, child_user_id, parent_post_id AS ancestor_post_id, parent_user_id AS ancestor_user_id, 1 AS length
  FROM ifqtriplets_a
  UNION 
  SELECT a.child_post_id, a.child_user_id, t.parent_post_id AS ancestor_post_id, t.parent_user_id AS ancestor_user_id, length + 1 AS length
  FROM ancestors a, ifqtriplets_a t
  WHERE a.ancestor_post_id = t.child_post_id
)
SELECT * FROM ancestors
"))
tic()
paired_depth_a <- paired_tree_q %>% 
  group_by(child_post_id) %>%
  filter(length==max(length)) %>%
  ungroup() %>%
  compute_a(name="reply_depth_a",unique_indexes=list(c("child_post_id","ancestor_post_id"),c("ancestor_post_id","child_post_id")),temporary=FALSE,overwrite=TRUE)
toc()
paired_depth_a %>% 
  group_by(ancestor_post_id) %>%
  filter(length==max(length)) %>%
  ungroup() %>%
  count(length) %>% 
  ggplot(aes(x=length,y=n)) + 
  geom_point(size=0.5) +
  scale_y_log10() +
  theme_hsci_discrete() +
  ggtitle("Distribution of the length of discussion between two participants")

Sample threads by their lengths

paired_depth_a %>% 
  group_by(ancestor_post_id) %>%
  filter(length==max(length)) %>%
  ungroup() %>%
  mutate(bucket=floor(length/10)*10) %>%
  group_by(bucket) %>%
  slice_sample(n=5) %>%
  ungroup() %>%
  select(bucket, post_id=child_post_id, length) %>%
  inner_join(incel_posts_a, join_by(post_id)) %>%
  mutate(url=str_c("https://incels.is/goto/post?id=",str_sub(post_id_str,6))) %>%
  select(bucket, length, url) %>%
  arrange(bucket, length) %>%
  gt(groupname_col = "bucket",rowname_col="length") %>%
  fmt_url(url)
url
0
1 https://incels.is/goto/post?id=3369722
1 https://incels.is/goto/post?id=10417884
1 https://incels.is/goto/post?id=7698942
2 https://incels.is/goto/post?id=3980004
3 https://incels.is/goto/post?id=3491876
10
10 https://incels.is/goto/post?id=4207410
10 https://incels.is/goto/post?id=9106503
10 https://incels.is/goto/post?id=7922193
12 https://incels.is/goto/post?id=8998392
15 https://incels.is/goto/post?id=8234518
20
20 https://incels.is/goto/post?id=9439584
21 https://incels.is/goto/post?id=4025155
22 https://incels.is/goto/post?id=2945100
26 https://incels.is/goto/post?id=5481855
29 https://incels.is/goto/post?id=5987153
30
32 https://incels.is/goto/post?id=7638989
32 https://incels.is/goto/post?id=2991510
33 https://incels.is/goto/post?id=10716178
35 https://incels.is/goto/post?id=4228065
39 https://incels.is/goto/post?id=8141248
40
41 https://incels.is/goto/post?id=4482117
42 https://incels.is/goto/post?id=2589974
42 https://incels.is/goto/post?id=4646038
46 https://incels.is/goto/post?id=4568851
46 https://incels.is/goto/post?id=8094813
50
50 https://incels.is/goto/post?id=4297704
52 https://incels.is/goto/post?id=4314325
56 https://incels.is/goto/post?id=4492521
58 https://incels.is/goto/post?id=5204098
59 https://incels.is/goto/post?id=3741803
60
60 https://incels.is/goto/post?id=3835178
62 https://incels.is/goto/post?id=3835539
64 https://incels.is/goto/post?id=3836220
70
76 https://incels.is/goto/post?id=4409632
77 https://incels.is/goto/post?id=8057762
77 https://incels.is/goto/post?id=4761723
80
82 https://incels.is/goto/post?id=8171674
90
94 https://incels.is/goto/post?id=8057817
130
132 https://incels.is/goto/post?id=6344676
260
260 https://incels.is/goto/post?id=7145998
LS0tCnRpdGxlOiAiRGlzY3Vzc2lvbiBzdHJ1Y3R1cmUgYW5hbHlzaXMiCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIGNvZGVfZm9sZGluZzogaGlkZQotLS0KCmBgYHtyIHNldHVwfQpsaWJyYXJ5KGdnYmVlc3dhcm0pCmxpYnJhcnkoZ3QpCmxpYnJhcnkodGljdG9jKQpzb3VyY2UoaGVyZTo6aGVyZSgic3JjL2NvbW1vbl9iYXNpcy5SIikpCmBgYAoKYGBge3J9CmNlbnRpbGVzIDwtIHNlcSgwLDEsYnk9MC4xKQpwZXJjZW50aWxlcyA8LSBzZXEoMCwxLGJ5PTAuMDEpCmBgYAoKIyBGZXRhbCBwZXJzb25ob29kCgpgYGB7cn0KYWJvcnRpb25fdHdlZXRzX2MgJT4lIAogIGNvdW50KHJlcGx5X2NvdW50KSAlPiUKICBnZ3Bsb3QoYWVzKHg9cmVwbHlfY291bnQseT1uKSkgKwogIGdlb21fcG9pbnQoc2l6ZT0wLjUpICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX3hfbG9nMTAoKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICBnZ3RpdGxlKCJSZXBseSBjb3VudCBkaXN0cmlidXRpb24iKQpgYGAKCmBgYHtyfQphYm9ydGlvbl90d2VldHNfYyAlPiUgCiAgY291bnQocmV0d2VldF9jb3VudCkgJT4lCiAgZ2dwbG90KGFlcyh4PXJldHdlZXRfY291bnQseT1uKSkgKwogIGdlb21fcG9pbnQoc2l6ZT0wLjUpICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX3hfbG9nMTAoKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICBnZ3RpdGxlKCJSZXR3ZWV0IGNvdW50IGRpc3RyaWJ1dGlvbiIpCmBgYAoKYGBge3J9CmFib3J0aW9uX3R3ZWV0c19jICU+JSAKICBjb3VudChsaWtlX2NvdW50KSAlPiUKICBnZ3Bsb3QoYWVzKHg9bGlrZV9jb3VudCx5PW4pKSArCiAgZ2VvbV9wb2ludChzaXplPTAuNSkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgc2NhbGVfeF9sb2cxMCgpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkgKwogIGdndGl0bGUoIkxpa2UgY291bnQgZGlzdHJpYnV0aW9uIikKYGBgCgojIEluY2VscwoKYGBge3J9CmluY2VsX3RocmVhZHNfYyAlPiUgCiAgY291bnQodGhyZWFkX2xhYmVsLCBwb3N0cykgJT4lCiAgZ3JvdXBfYnkodGhyZWFkX2xhYmVsKSAlPiUKICBtdXRhdGUocHJvcD1uL3N1bShuKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGdncGxvdChhZXMoeD1wb3N0cyx5PXByb3AsIGNvbG9yPXRocmVhZF9sYWJlbCkpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV94X2xvZzEwKCkgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKSArCiAgZ2d0aXRsZSgiVGhyZWFkIGxlbmd0aCBkaXN0cmlidXRpb24gYnkgbGFiZWwiKQpgYGAKCmBgYHtyfQppbmNlbF9xdW90ZXNfYyAlPiUgCiAgZmlsdGVyKHF1b3RlZF9wb3N0X2lkICE9IDAsIHF1b3RlZF9wb3N0X2lkIT1xdW90aW5nX3Bvc3RfaWQpICU+JQogIGNvdW50KHF1b3RlZF9wb3N0X2lkKSAlPiUKICBjb3VudChuKSAlPiUKICBhcnJhbmdlKGRlc2Mobm4pKSAlPiUKICBnZ3Bsb3QoYWVzKHg9bix5PW5uKSkgKyAKICBnZW9tX3BvaW50KCkgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBnZ3RpdGxlKCJEaXN0cmlidXRpb24gb2YgdGhlIG51bWJlciBvZiB0aW1lcyBhIG1lc3NhZ2UgaGFzIGJlZW4gcXVvdGVkIikKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KaW5jZWxfcXVvdGVfdHJlZV9hIDwtIGluY2VsX3F1b3Rlc19hICU+JQogIGlubmVyX2pvaW4oaW5jZWxfcG9zdHNfYSAlPiUgc2VsZWN0KHF1b3RpbmdfcG9zdF9pZD1wb3N0X2lkLHF1b3RpbmdfcG9zdF9wb3N0ZXJfaWQ9cG9zdGVyX2lkKSkgJT4lCiAgICBpbm5lcl9qb2luKGluY2VsX3Bvc3RzX2EgJT4lIHNlbGVjdChxdW90ZWRfcG9zdF9pZD1wb3N0X2lkLHF1b3RlZF9wb3N0X3Bvc3Rlcl9pZD1wb3N0ZXJfaWQpKSAlPiUKICBkaXN0aW5jdChxdW90aW5nX3Bvc3RfaWQscXVvdGVkX3Bvc3RfaWQscXVvdGluZ19wb3N0X3Bvc3Rlcl9pZCxxdW90ZWRfcG9zdF9wb3N0ZXJfaWQpICU+JQogIGZpbHRlcihxdW90ZWRfcG9zdF9pZCE9MCxxdW90ZWRfcG9zdF9pZCE9cXVvdGluZ19wb3N0X2lkKSAlPiUKICBjb21wdXRlX2EobmFtZT0iaW5jZWxfcXVvdGVfdHJlZV9hIiwgdW5pcXVlX2luZGV4ZXM9bGlzdChjKCJxdW90aW5nX3Bvc3RfaWQiLCJxdW90ZWRfcG9zdF9pZCIpLGMoInF1b3RlZF9wb3N0X2lkIiwicXVvdGluZ19wb3N0X2lkIikpLCB0ZW1wb3Jhcnk9RkFMU0UsIG92ZXJ3cml0ZT1UUlVFKQpgYGAKCmBgYHtyfQphbmNlc3RvcnNfcSA8LSB0YmwoY29uLHNxbCgnCldJVEggUkVDVVJTSVZFIGFuY2VzdG9ycyBBUyAoIAogIFNFTEVDVCBxdW90aW5nX3Bvc3RfaWQgQVMgZGVzY2VuZGFudF9wb3N0X2lkLCBxdW90ZWRfcG9zdF9pZCBBUyBhbmNlc3Rvcl9wb3N0X2lkLCAxIEFTIGxlbmd0aAogIEZST00gaW5jZWxfcXVvdGVfdHJlZV9hCiAgVU5JT04gCiAgU0VMRUNUIGEuZGVzY2VuZGFudF9wb3N0X2lkLCBxdC5xdW90ZWRfcG9zdF9pZCBBUyBhbmNlc3Rvcl9wb3N0X2lkLCBsZW5ndGgrMSBBUyBsZW5ndGgKICBGUk9NIGluY2VsX3F1b3RlX3RyZWVfYSBxdCwgYW5jZXN0b3JzIGEKICBXSEVSRSBxdC5xdW90aW5nX3Bvc3RfaWQgPSBhLmFuY2VzdG9yX3Bvc3RfaWQKKSAKU0VMRUNUICogRlJPTSBhbmNlc3RvcnMnKSkKZGVzY2VuZGFudHNfcSA8LSB0YmwoY29uLHNxbCgnCldJVEggUkVDVVJTSVZFIGRlc2NlbmRhbnRzIEFTICggCiAgU0VMRUNUIHF1b3RpbmdfcG9zdF9pZCBBUyBkZXNjZW5kYW50X3Bvc3RfaWQsIHF1b3RlZF9wb3N0X2lkIEFTIGFuY2VzdG9yX3Bvc3RfaWQsIDEgQVMgbGVuZ3RoCiAgRlJPTSBpbmNlbF9xdW90ZV90cmVlX2EKICBVTklPTiAKICBTRUxFQ1QgcXQucXVvdGluZ19wb3N0X2lkIEFTIGRlc2NlbmRhbnRfcG9zdF9pZCwgYW5jZXN0b3JfcG9zdF9pZCwgbGVuZ3RoKzEgQVMgbGVuZ3RoCiAgRlJPTSBpbmNlbF9xdW90ZV90cmVlX2EgcXQsIGRlc2NlbmRhbnRzIGQKICBXSEVSRSBxdC5xdW90ZWRfcG9zdF9pZCA9IGQuZGVzY2VuZGFudF9wb3N0X2lkCikgClNFTEVDVCAqIEZST00gZGVzY2VuZGFudHMnKSkKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KdGljKCkKcmVwbHlfZGVwdGhfYSA8LSBkZXNjZW5kYW50c19xICU+JSAKICBncm91cF9ieShkZXNjZW5kYW50X3Bvc3RfaWQpICU+JQogIGZpbHRlcihsZW5ndGg9PW1heChsZW5ndGgpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgY29tcHV0ZV9hKG5hbWU9InJlcGx5X2RlcHRoX2EiLHVuaXF1ZV9pbmRleGVzPWxpc3QoYygiZGVzY2VuZGFudF9wb3N0X2lkIiwiYW5jZXN0b3JfcG9zdF9pZCIpLGMoImFuY2VzdG9yX3Bvc3RfaWQiLCJkZXNjZW5kYW50X3Bvc3RfaWQiKSksdGVtcG9yYXJ5PUZBTFNFLG92ZXJ3cml0ZT1UUlVFKQp0b2MoKQpgYGAKCmBgYHtyfQpyZXBseV9kZXB0aF9hICU+JSAKICBncm91cF9ieShhbmNlc3Rvcl9wb3N0X2lkKSAlPiUKICBmaWx0ZXIobGVuZ3RoPT1tYXgobGVuZ3RoKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGNvdW50KGxlbmd0aCkgJT4lIAogIGdncGxvdChhZXMoeD1sZW5ndGgseT1uKSkgKyAKICBnZW9tX3BvaW50KHNpemU9MC41KSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkgKwogIGdndGl0bGUoIlF1b3RlIGNoYWluICh+ZGlzY3Vzc2lvbikgbGVuZ3RoIGRpc3RyaWJ1dGlvbiIpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CmdyYW5kcGFyZW50X3EgPC0gdGJsKGNvbixzcWwoIgpXSVRIIHRocmVlX3Bvc3RzIEFTICgKICBTRUxFQ1QgRElTVElOQ1QgcTEucXVvdGluZ19wb3N0X2lkIEFTIGNoaWxkX3Bvc3RfaWQsIHAxLnBvc3Rlcl9pZCBBUyBjaGlsZF91c2VyX2lkLCBxMi5xdW90aW5nX3Bvc3RfaWQgQVMgcGFyZW50X3Bvc3RfaWQsIHAyLnBvc3Rlcl9pZCBBUyBwYXJlbnRfdXNlcl9pZCwgcTIucXVvdGVkX3Bvc3RfaWQgQVMgZ3JhbmRwYXJlbnRfcG9zdF9pZCwgcDMucG9zdGVyX2lkIEFTIGdyYW5kcGFyZW50X3VzZXJfaWQKICBGUk9NIGluY2VsX3F1b3Rlc19hIHExCiAgSU5ORVIgSk9JTiBpbmNlbF9xdW90ZXNfYSBxMiBPTiAocTEucXVvdGVkX3Bvc3RfaWQ9cTIucXVvdGluZ19wb3N0X2lkKQogIElOTkVSIEpPSU4gaW5jZWxfcG9zdHNfYSBwMSBPTiAocTEucXVvdGluZ19wb3N0X2lkPXAxLnBvc3RfaWQpCiAgSU5ORVIgSk9JTiBpbmNlbF9wb3N0c19hIHAyIE9OIChxMS5xdW90ZWRfcG9zdF9pZD1wMi5wb3N0X2lkKQogIElOTkVSIEpPSU4gaW5jZWxfcG9zdHNfYSBwMyBPTiAocTIucXVvdGVkX3Bvc3RfaWQ9cDMucG9zdF9pZCkKICBXSEVSRQogICBxMi5xdW90ZWRfcG9zdF9pZCE9MCBBTkQKICAgcTIucXVvdGluZ19wb3N0X2lkIT1xMi5xdW90ZWRfcG9zdF9pZAopClNFTEVDVCAqIEZST00gdGhyZWVfcG9zdHMiKSkKaW5jZWxfcXVvdGVfdHJpcGxldHNfYSA8LSBncmFuZHBhcmVudF9xICU+JQogIGNvbXB1dGVfYSgiaW5jZWxfcXVvdGVfdHJpcGxldHNfYSIsIHRlbXBvcmFyeT1GQUxTRSwgb3ZlcndyaXRlPVRSVUUpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CmlmcXRyaXBsZXRzX2EgPC0gaW5jZWxfcXVvdGVfdHJpcGxldHNfYSAlPiUKICBmaWx0ZXIoY2hpbGRfdXNlcl9pZD09Z3JhbmRwYXJlbnRfdXNlcl9pZCkgJT4lCiAgY29tcHV0ZV9hKCJpZnF0cmlwbGV0c19hIiwgdGVtcG9yYXJ5PUZBTFNFLCBvdmVyd3JpdGU9VFJVRSwgdW5pcXVlX2luZGV4ZXM9bGlzdChjKCJjaGlsZF9wb3N0X2lkIiwiZ3JhbmRwYXJlbnRfcG9zdF9pZCIsICJwYXJlbnRfcG9zdF9pZCIpKSkKYGBgCgoKYGBge3IsIGV2YWw9RkFMU0V9CnBhaXJlZF90cmVlX3EgPC0gdGJsKGNvbixzcWwoIgpXSVRIIFJFQ1VSU0lWRSBhbmNlc3RvcnMgQVMgKCAKICBTRUxFQ1QgY2hpbGRfcG9zdF9pZCwgY2hpbGRfdXNlcl9pZCwgcGFyZW50X3Bvc3RfaWQgQVMgYW5jZXN0b3JfcG9zdF9pZCwgcGFyZW50X3VzZXJfaWQgQVMgYW5jZXN0b3JfdXNlcl9pZCwgMSBBUyBsZW5ndGgKICBGUk9NIGlmcXRyaXBsZXRzX2EKICBVTklPTiAKICBTRUxFQ1QgYS5jaGlsZF9wb3N0X2lkLCBhLmNoaWxkX3VzZXJfaWQsIHQucGFyZW50X3Bvc3RfaWQgQVMgYW5jZXN0b3JfcG9zdF9pZCwgdC5wYXJlbnRfdXNlcl9pZCBBUyBhbmNlc3Rvcl91c2VyX2lkLCBsZW5ndGggKyAxIEFTIGxlbmd0aAogIEZST00gYW5jZXN0b3JzIGEsIGlmcXRyaXBsZXRzX2EgdAogIFdIRVJFIGEuYW5jZXN0b3JfcG9zdF9pZCA9IHQuY2hpbGRfcG9zdF9pZAopClNFTEVDVCAqIEZST00gYW5jZXN0b3JzCiIpKQp0aWMoKQpwYWlyZWRfZGVwdGhfYSA8LSBwYWlyZWRfdHJlZV9xICU+JSAKICBncm91cF9ieShjaGlsZF9wb3N0X2lkKSAlPiUKICBmaWx0ZXIobGVuZ3RoPT1tYXgobGVuZ3RoKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGNvbXB1dGVfYShuYW1lPSJyZXBseV9kZXB0aF9hIix1bmlxdWVfaW5kZXhlcz1saXN0KGMoImNoaWxkX3Bvc3RfaWQiLCJhbmNlc3Rvcl9wb3N0X2lkIiksYygiYW5jZXN0b3JfcG9zdF9pZCIsImNoaWxkX3Bvc3RfaWQiKSksdGVtcG9yYXJ5PUZBTFNFLG92ZXJ3cml0ZT1UUlVFKQp0b2MoKQpgYGAKCmBgYHtyfQpwYWlyZWRfZGVwdGhfYSAlPiUgCiAgZ3JvdXBfYnkoYW5jZXN0b3JfcG9zdF9pZCkgJT4lCiAgZmlsdGVyKGxlbmd0aD09bWF4KGxlbmd0aCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBjb3VudChsZW5ndGgpICU+JSAKICBnZ3Bsb3QoYWVzKHg9bGVuZ3RoLHk9bikpICsgCiAgZ2VvbV9wb2ludChzaXplPTAuNSkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICBnZ3RpdGxlKCJEaXN0cmlidXRpb24gb2YgdGhlIGxlbmd0aCBvZiBkaXNjdXNzaW9uIGJldHdlZW4gdHdvIHBhcnRpY2lwYW50cyIpCmBgYAoKIyMgU2FtcGxlIHRocmVhZHMgYnkgdGhlaXIgbGVuZ3RocwoKYGBge3J9CnBhaXJlZF9kZXB0aF9hICU+JSAKICBncm91cF9ieShhbmNlc3Rvcl9wb3N0X2lkKSAlPiUKICBmaWx0ZXIobGVuZ3RoPT1tYXgobGVuZ3RoKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZShidWNrZXQ9Zmxvb3IobGVuZ3RoLzEwKSoxMCkgJT4lCiAgZ3JvdXBfYnkoYnVja2V0KSAlPiUKICBzbGljZV9zYW1wbGUobj01KSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgc2VsZWN0KGJ1Y2tldCwgcG9zdF9pZD1jaGlsZF9wb3N0X2lkLCBsZW5ndGgpICU+JQogIGlubmVyX2pvaW4oaW5jZWxfcG9zdHNfYSwgam9pbl9ieShwb3N0X2lkKSkgJT4lCiAgbXV0YXRlKHVybD1zdHJfYygiaHR0cHM6Ly9pbmNlbHMuaXMvZ290by9wb3N0P2lkPSIsc3RyX3N1Yihwb3N0X2lkX3N0ciw2KSkpICU+JQogIHNlbGVjdChidWNrZXQsIGxlbmd0aCwgdXJsKSAlPiUKICBhcnJhbmdlKGJ1Y2tldCwgbGVuZ3RoKSAlPiUKICBndChncm91cG5hbWVfY29sID0gImJ1Y2tldCIscm93bmFtZV9jb2w9Imxlbmd0aCIpICU+JQogIGZtdF91cmwodXJsKQpgYGAKCg==