Contents

1 Setup and data

source("../utils/utils.R")
   ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
   ✔ dplyr     1.1.0     ✔ readr     2.1.4
   ✔ forcats   1.0.0     ✔ stringr   1.5.0
   ✔ ggplot2   3.4.1     ✔ tibble    3.2.0
   ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
   ✔ purrr     1.0.1     
   ── 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 errors
   
   Attaching package: 'magrittr'
   
   
   The following object is masked from 'package:purrr':
   
       set_names
   
   
   The following object is masked from 'package:tidyr':
   
       extract
   
   
   Loading required package: GenomicRanges
   
   Loading required package: stats4
   
   Loading required package: BiocGenerics
   
   
   Attaching package: 'BiocGenerics'
   
   
   The following objects are masked from 'package:lubridate':
   
       intersect, setdiff, union
   
   
   The following objects are masked from 'package:dplyr':
   
       combine, intersect, setdiff, union
   
   
   The following objects are masked from 'package:stats':
   
       IQR, mad, sd, var, xtabs
   
   
   The following objects are masked from 'package:base':
   
       anyDuplicated, aperm, append, as.data.frame, basename, cbind,
       colnames, dirname, do.call, duplicated, eval, evalq, Filter, Find,
       get, grep, grepl, intersect, is.unsorted, lapply, Map, mapply,
       match, mget, order, paste, pmax, pmax.int, pmin, pmin.int,
       Position, rank, rbind, Reduce, rownames, sapply, setdiff, sort,
       table, tapply, union, unique, unsplit, which.max, which.min
   
   
   Loading required package: S4Vectors
   
   
   Attaching package: 'S4Vectors'
   
   
   The following objects are masked from 'package:lubridate':
   
       second, second<-
   
   
   The following objects are masked from 'package:dplyr':
   
       first, rename
   
   
   The following object is masked from 'package:tidyr':
   
       expand
   
   
   The following objects are masked from 'package:base':
   
       expand.grid, I, unname
   
   
   Loading required package: IRanges
   
   
   Attaching package: 'IRanges'
   
   
   The following object is masked from 'package:lubridate':
   
       %within%
   
   
   The following objects are masked from 'package:dplyr':
   
       collapse, desc, slice
   
   
   The following object is masked from 'package:purrr':
   
       reduce
   
   
   Loading required package: GenomeInfoDb
   
   
   Attaching package: 'GenomicRanges'
   
   
   The following object is masked from 'package:magrittr':
   
       subtract
   
   
   Loading required package: grid
   
   Loading required package: Biostrings
   
   Loading required package: XVector
   
   
   Attaching package: 'XVector'
   
   
   The following object is masked from 'package:purrr':
   
       compact
   
   
   
   Attaching package: 'Biostrings'
   
   
   The following object is masked from 'package:grid':
   
       pattern
   
   
   The following object is masked from 'package:base':
   
       strsplit
   
   
   
   Attaching package: 'gridExtra'
   
   
   The following object is masked from 'package:BiocGenerics':
   
       combine
   
   
   The following object is masked from 'package:dplyr':
   
       combine
   
   
   
   Attaching package: 'data.table'
   
   
   The following object is masked from 'package:GenomicRanges':
   
       shift
   
   
   The following object is masked from 'package:IRanges':
   
       shift
   
   
   The following objects are masked from 'package:S4Vectors':
   
       first, second
   
   
   The following objects are masked from 'package:lubridate':
   
       hour, isoweek, mday, minute, month, quarter, second, wday, week,
       yday, year
   
   
   The following objects are masked from 'package:dplyr':
   
       between, first, last
   
   
   The following object is masked from 'package:purrr':
   
       transpose
   
   
   Loading required package: AnnotationDbi
   
   Loading required package: Biobase
   
   Welcome to Bioconductor
   
       Vignettes contain introductory material; view with
       'browseVignettes()'. To cite Bioconductor, see
       'citation("Biobase")', and for packages 'citation("pkgname")'.
   
   
   
   Attaching package: 'AnnotationDbi'
   
   
   The following object is masked from 'package:dplyr':
   
       select
   
   
   
   
   
   
   Registered S3 method overwritten by 'gplots':
     method         from 
     reorder.factor gdata
   
   ChIPseeker v1.34.1  For help: https://guangchuangyu.github.io/software/ChIPseeker
   
   If you use ChIPseeker in published research, please cite:
   Qianwen Wang, Ming Li, Tianzhi Wu, Li Zhan, Lin Li, Meijun Chen, Wenqin Xie, Zijing Xie, Erqiang Hu, Shuangbin Xu, Guangchuang Yu. Exploring epigenomic datasets by ChIPseeker. Current Protocols 2022, 2(10): e585
   
   Loading required package: graph
   
   
   Attaching package: 'graph'
   
   
   The following object is masked from 'package:Biostrings':
   
       complement
   
   
   The following object is masked from 'package:stringr':
   
       boundary
   
   
   Loading required package: GO.db
   
   Loading required package: SparseM
   
   
   Attaching package: 'SparseM'
   
   
   The following object is masked from 'package:base':
   
       backsolve
   
   
   
   groupGOTerms:    GOBPTerm, GOMFTerm, GOCCTerm environments built.
   
   
   Attaching package: 'topGO'
   
   
   The following object is masked from 'package:grid':
   
       depth
   
   
   The following object is masked from 'package:IRanges':
   
       members
   
   
   Loading required package: GenomicFeatures
   
   
   Attaching package: 'GenomicFeatures'
   
   
   The following object is masked from 'package:topGO':
   
       genes
config = load_config()

# load CHT results
cht_full = lapply(ab_tp_list, function(ab_tp) load_cht_results(ab_tp, remove_chr = F)) %>% bind_rows()
cht = cht_full %>% filter(!TEST.SNP.CHROM %in% c("chrX", "chrY", "chrM"))
cht_sign = cht %>% filter(signif_strongAI) 

# genes and promoters
genes = load_genes()
promoters = resize(genes, width = 1000, fix = "start")

# combined motif set (all TFs, peaks + alleles)
fimo = get_full_motif_sets(cht, ab_tp_list)
# only alleles
fimo_alleles  = lapply(ab_tp_list, function(ab_tp) parse_motifs_in_two_alleles(ab_tp, cht)) %>% bind_rows() 

2 Figure S3B: Indels length

cht_sel = cht %>%
  filter(signif_strongAI) %>%
  group_by(peak_id) %>%
  #mutate(min_pval = min(P.VALUE)) %>%
  #filter(P.VALUE == min_pval) %>%
  mutate(max_indel = max(indel_length), min_indel = min(indel_length)) %>%
  filter(indel_length == max_indel) %>%
#  mutate(max_AI = max(AI_abs)) %>%
#  filter(AI_abs == max_AI) %>%
  select(condition, peak_id, indel_length, AI_abs) %>%
  unique() %>%
  mutate(bin_indel = cut(indel_length, breaks = c(0, 1, 10, Inf), labels = c("SNP", "2-10", ">10"), include.lowest = T))


cht_sel$label = factor(ab_tp_labels[cht_sel$condition], levels = ab_tp_labels)


p = ggplot(cht_sel, aes(x = bin_indel, y = AI_abs, fill = bin_indel)) + 
  geom_boxplot(width = 0.6, outlier.size = 0.1) +
  scale_fill_manual(values = cbPalette, name = "Indel length") +
  scale_y_continuous(trans = "log2", limits = c(0.1, 0.7)) +
  stat_compare_means(comparisons = list(c("SNP", ">10"), c("SNP", "2-10"))) +
  stat_compare_means() +
  xlab("") +
  ylab("Allele imbalance") +
  theme_bw() +
  facet_grid(~label) +
  stat_summary(fun.data = function(x) c(y = median(x) + 0.1, label = length(x)), geom = "text", size = 4) +
  theme(axis.text.x = element_blank(), 
        #axis.text.x = element_text(size=16, angle = 45, hjust = 1, color = TFcols), 
        axis.text.y = element_text(size=16), 
        axis.title.x = element_text(size=18), axis.title.y = element_text(size=16),
        strip.text.x = element_text(size = 14), strip.text.y = element_text(size = 14),
        legend.text=element_text(size=16), legend.title=element_text(size=16))


cht_sel %>% 
  group_by(condition) %>%
  mutate(N = n()) %>%
  group_by(condition, bin_indel) %>%
  dplyr::summarize(n = n(), share = n / mean(N), res_share = 1 - share)
   `summarise()` has grouped output by 'condition'. You can override using the
   `.groups` argument.
p

outf = file.path(outdir_fig_suppl, paste0("FigS3B_indels_AI.pdf"))
ggsave(outf, p, width = 18, height = 5)

3 Figure S3C: Indels length

cht = lapply(ab_tp_list, function(ab_tp) load_cht_results(ab_tp)) %>% bind_rows()
cht_gr = cht %>% mutate(chr = TEST.SNP.CHROM, start = TEST.SNP.POS, end = TEST.SNP.POS) %>% GRanges()

# F1 ATAC-seq results

# coordinates of ATAC peaks
atac_regions_path = "/g/furlong/project/68_F1_cisreg_ichip/data/F1_paper_multiom/ATAC_feature_location_dm6.bed"
atac_regions = import(atac_regions_path, format = "bed")

# imbalance info for ATAC peaks
atac_ai_path = "/g/furlong/project/68_F1_cisreg_ichip/data/F1_paper_multiom/ATAC_all_peaks_atac_X.txt"
atac_ai = read.delim(atac_ai_path)

# additional annotations for allele imbalance
atac_ai_sum = atac_ai %>% 
  mutate(AI = padj < 0.01 & abs(0.5 - meanprop) > 0.1) %>%
  group_by(feature, time) %>% 
  summarize(n_AI = sum(AI), 
            AI_peak = any(AI),
            mean_AI = abs(0.5 - mean(meanprop)), 
            max_AI = max(abs(0.5 - meanprop)),
            n_het_lines =n())
   `summarise()` has grouped output by 'feature'. You can override using the
   `.groups` argument.
# combine AII info with peak coordinates
atac_f1_df = merge(data.frame(atac_regions), atac_ai_sum, by.x = "name", by.y = "feature") %>% filter(!seqnames %in% c("chrX", "chrY"))
atac_ai_gr = GRanges(atac_f1_df)


# Do the analysis per TF and ATAC time-point


df = data.frame()

for (ab_tp in ab_tp_list) {
  
  tp = gsub("-", "", timepoints[ab_tp])
  
  # get TF peaks
  AI_peaks = get_peaks_from_cht(ab_tp, cht)
  names(mcols(AI_peaks)) = paste0(names(mcols(AI_peaks)), ".tf")
  
  # get ATAC peaks for selected time-point
  AI_atac = atac_ai_gr[atac_ai_gr$time == tp]
  names(mcols(AI_atac)) = paste0(names(mcols(AI_atac)), ".atac")
  
  ov = findOverlaps(AI_peaks, AI_atac)
  
  
  res = cbind.data.frame(mcols(AI_peaks[queryHits(ov)]), mcols(AI_atac[subjectHits(ov)]))
  
  print(ab_tp)
  wt = wilcox.test(mean_AI.atac ~ AI_peak.tf, res, alternative = "less")
  print(wt)
  wt = wilcox.test(max_AI.atac ~ AI_peak.tf, res, alternative = "less")
  print(wt)
  
  df = rbind.data.frame(df, res)
  
}
   `summarise()` has grouped output by 'peak_id', 'condition', 'chr', 'start'. You
   can override using the `.groups` argument.
   [1] "twi/24"
   
    Wilcoxon rank sum test with continuity correction
   
   data:  mean_AI.atac by AI_peak.tf
   W = 1408786, p-value <2e-16
   alternative hypothesis: true location shift is less than 0
   
   
    Wilcoxon rank sum test with continuity correction
   
   data:  max_AI.atac by AI_peak.tf
   W = 1317170, p-value <2e-16
   alternative hypothesis: true location shift is less than 0
   `summarise()` has grouped output by 'peak_id', 'condition', 'chr', 'start'. You
   can override using the `.groups` argument.
   [1] "ctcf/68"
   
    Wilcoxon rank sum test with continuity correction
   
   data:  mean_AI.atac by AI_peak.tf
   W = 493598, p-value = 1.2e-11
   alternative hypothesis: true location shift is less than 0
   
   
    Wilcoxon rank sum test with continuity correction
   
   data:  max_AI.atac by AI_peak.tf
   W = 444450, p-value <2e-16
   alternative hypothesis: true location shift is less than 0
   `summarise()` has grouped output by 'peak_id', 'condition', 'chr', 'start'. You
   can override using the `.groups` argument.
   [1] "mef2/68"
   
    Wilcoxon rank sum test with continuity correction
   
   data:  mean_AI.atac by AI_peak.tf
   W = 947570, p-value <2e-16
   alternative hypothesis: true location shift is less than 0
   
   
    Wilcoxon rank sum test with continuity correction
   
   data:  max_AI.atac by AI_peak.tf
   W = 879208, p-value <2e-16
   alternative hypothesis: true location shift is less than 0
   `summarise()` has grouped output by 'peak_id', 'condition', 'chr', 'start'. You
   can override using the `.groups` argument.
   [1] "mef2/1012"
   
    Wilcoxon rank sum test with continuity correction
   
   data:  mean_AI.atac by AI_peak.tf
   W = 1304888, p-value <2e-16
   alternative hypothesis: true location shift is less than 0
   
   
    Wilcoxon rank sum test with continuity correction
   
   data:  max_AI.atac by AI_peak.tf
   W = 1237730, p-value <2e-16
   alternative hypothesis: true location shift is less than 0
   `summarise()` has grouped output by 'peak_id', 'condition', 'chr', 'start'. You
   can override using the `.groups` argument.
   [1] "bin/68"
   
    Wilcoxon rank sum test with continuity correction
   
   data:  mean_AI.atac by AI_peak.tf
   W = 416654, p-value <2e-16
   alternative hypothesis: true location shift is less than 0
   
   
    Wilcoxon rank sum test with continuity correction
   
   data:  max_AI.atac by AI_peak.tf
   W = 417385, p-value <2e-16
   alternative hypothesis: true location shift is less than 0
   `summarise()` has grouped output by 'peak_id', 'condition', 'chr', 'start'. You
   can override using the `.groups` argument.
   [1] "bin/1012"
   
    Wilcoxon rank sum test with continuity correction
   
   data:  mean_AI.atac by AI_peak.tf
   W = 397406, p-value = 3.2e-07
   alternative hypothesis: true location shift is less than 0
   
   
    Wilcoxon rank sum test with continuity correction
   
   data:  max_AI.atac by AI_peak.tf
   W = 369466, p-value = 1.5e-11
   alternative hypothesis: true location shift is less than 0
df %<>% 
  mutate(label = factor(ab_tp_labels[condition.tf], levels = ab_tp_labels))

df %>% group_by(condition.tf, AI_peak.tf) %>%
  summarize(mean(mean_AI.atac, mean(max_AI.atac)))
   `summarise()` has grouped output by 'condition.tf'. You can override using the
   `.groups` argument.
p = ggplot(df, aes(x = AI_peak.tf,  y = max_AI.atac)) +
  geom_violin(fill = "darkblue", alpha = 0.3) +
  geom_boxplot(width = 0.4, outlier.size = 0.1, fill = "darkblue", alpha = 0.7) +
  facet_wrap(~ label, ncol = 3) +
  theme_bw() +
  stat_compare_means() +
  xlab("AI TF peaks (F1)") +
  ylab("Allele imbalance of ATAC peaks (F1)") +
  theme(axis.text.y = element_text(size=12), axis.text.x = element_text(size=12), 
        axis.title.x = element_text(size=16), axis.title.y = element_text(size=16),
        strip.text.x = element_text(size = 14), strip.text.y = element_text(size = 14))

print(p)

ggsave(file.path(outdir_fig_suppl, "FigS3C_AI_ATAC_by_TF.pdf"), p, width = 9, height = 6)

4 Figure S3D

# only quantified peaks for CHT
#peaks = lapply(ab_tp_list, function(ab_tp) get_peaks_from_cht(ab_tp, cht, as_granges = T))
#names(peaks) = ab_tp_list

peaks = get_consensus_peaksets_with_AI(ab_tp_list, cht, filter = F)

dhs = load_dhs() %>% GRanges()
dhs$DHScond = cut(dhs$num_conditions, breaks = c(1, 2, 17, 19), include.lowest = T)
dhs$DHS_modERN = cut(dhs$num_modERN,breaks = c(0, 9, 251), include.lowest = T)


res = lapply(c("distal", "proximal"), function(TSS_type) {

  dhs_gr = dhs %>% as.data.frame() %>% filter(TSS == TSS_type) %>% GRanges()
  
  # DHS conditions
  df = lapply(peaks, function(x) {ov = findOverlaps(x, dhs_gr);
                                  cbind.data.frame(as.data.frame(x[queryHits(ov)]), as.data.frame(dhs_gr[subjectHits(ov)])) }) %>%
            bind_rows()
  
  fts1 = lapply(ab_tp_list, function(ab_tp) {fisher_test_two_groups(df, ab_tp,
                                                                    group1 = "isAI", group1_val = c(TRUE, FALSE), 
                                                                    group2 = "DHScond", group2_val = c("[1,2]", "(17,19]"))}) %>%
            bind_rows() %>% mutate(comp = "DHS conditions\n(1-2 vs. 18-19)", labels = ab_tp_labels)
  
  # modERN TFs
  fts2 = lapply(ab_tp_list, function(ab_tp) {fisher_test_two_groups(df, ab_tp,
                                                                    group1 = "isAI", group1_val = c(TRUE, FALSE), 
                                                                    group2 = "DHS_modERN", group2_val = c("(9,251]", "[0,9]"))}) %>%
            bind_rows() %>% mutate(comp = "modERN TFs\n(31-251 vs. 0-5)", labels = ab_tp_labels)
  
  
  res = rbind.data.frame(fts1, fts2) %>% mutate(TSS_type = paste("TSS", TSS_type)) 
  
  
}) %>% bind_rows()
   New names:
   New names:
   New names:
   New names:
   New names:
   New names:
   New names:
   New names:
   New names:
   New names:
   New names:
   New names:
   • `seqnames` -> `seqnames...1`
   • `start` -> `start...2`
   • `end` -> `end...3`
   • `width` -> `width...4`
   • `strand` -> `strand...5`
   • `score` -> `score...7`
   • `seqnames` -> `seqnames...13`
   • `start` -> `start...14`
   • `end` -> `end...15`
   • `width` -> `width...16`
   • `strand` -> `strand...17`
   • `score` -> `score...21`
# ModERN TFs

df = res %>% filter(comp2 == "DHS_modERN_(9,251]_vs_[0,9]") 
df$label = ab_tp_labels
df$label = factor(df$label, levels = ab_tp_labels)

p = ggplot(df, aes(x = label, y = odds_ratio)) +
  facet_wrap(~TSS_type) +
  geom_hline(yintercept = 1, color = "darkred") +
  geom_bar(aes(fill = -log10(pval)), color = "darkblue", stat = "identity", position = "dodge", width = 0.5) +
  #scale_fill_manual(name = "", values = c("darkblue", "darkgrey"), labels = c("AI peaks", "non-AI peaks")) +
  geom_text(aes(label = round(r1, 2), x = label, y = odds_ratio + 0.05), data = df, size = 6) +
  ylab("Depletioin in ubiquitously bound regions (>10 modERN TFs) \nFisher's Test Odds Ratio") +
  theme_bw() +
  theme(axis.text.x = element_text(size = 14, angle = 45, hjust = 1, colour = TFcols),
        axis.text.y = element_text(size = 12), 
        axis.title.x = element_blank(),
        axis.title.y = element_text(size = 14),
        legend.text = element_text(size=14),
        legend.title = element_text(size=14))
   Warning: Vectorized input to `element_text()` is not officially supported.
   ℹ Results may be unexpected or may change in future versions of ggplot2.
p

outf = file.path(outdir_fig_suppl, paste0("FigS3D_modERN_fisher.pdf"))
ggsave(outf, p, width = 10, height = 6)

5 Figure S3E

df = res %>% filter(comp2 == "DHScond_[1,2]_vs_(17,19]") 
df$label = ab_tp_labels
df$label = factor(df$label, levels = ab_tp_labels)



p = ggplot(df, aes(x = label, y = odds_ratio)) +
  facet_wrap(~TSS_type) +
  geom_hline(yintercept = 1, color = "darkred") +
  geom_bar(aes(fill = -log10(pval)), color = "darkblue", stat = "identity", position = "dodge", width = 0.5) +
  #scale_fill_manual(name = "", values = c("darkblue", "darkgrey"), labels = c("AI peaks", "non-AI peaks")) +
  geom_text(aes(label = round(r1, 2), x = label, y = odds_ratio + 0.07), data = df, size = 6) +
  ylab("Enrichment in condition-specific DHS \nFisher's Test Odds Ratio") +
  theme_bw() +
  theme(axis.text.x = element_text(size = 14, angle = 45, hjust = 1, colour = TFcols),
        axis.text.y = element_text(size = 12), 
        axis.title.x = element_blank(),
        axis.title.y = element_text(size = 16),
        legend.text = element_text(size=14),
        legend.title = element_text(size=14))
   Warning: Vectorized input to `element_text()` is not officially supported.
   ℹ Results may be unexpected or may change in future versions of ggplot2.
p

outf = file.path(outdir_fig_suppl, paste0("FigS3E_nonubiqDHS_fisher.pdf"))
ggsave(outf, p, width = 10, height = 6)

6 Figure S3F - GO Enrichment for AI peaks

for (cond in c(ab_tp_list, list(ab_tp_list))) {
  
    test_geneID = get_test_geneID(cht, cond, 1000)
    background_geneID = get_background_geneID(cht, cond, 1000, test_geneID)

    out = create_GOdata(test_geneID, background_geneID, "BP")
    GOdata = out[[1]]
    test = out[[2]]
    n_nodes = length(attributes(GOdata)$graph@nodes)

    # Classic Fisher test
    test.stat <- new("classicCount", testStatistic = GOFisherTest, name = "Fisher test")
    resultFisher <- getSigGroups(GOdata, test.stat)

    # KS test
    test.stat <- new("classicScore", testStatistic = GOKSTest, name = "KS tests")
    resultKS <- getSigGroups(GOdata, test.stat)

    # Weight algorithm
    test.stat <- new("weightCount", testStatistic = GOFisherTest, name = "Fisher test", sigRatio = "ratio")
    resultWeight <- getSigGroups(GOdata, test.stat)
    
    allRes <- GenTable(GOdata, classic = resultFisher, 
           KS = resultKS, weight = resultWeight,
           orderBy = "weight", ranksOf = "classic", topNodes = n_nodes)
    allRes$Fold_Enrichment = allRes$Significant / allRes$Expected
    allRes$FDR = allRes$weight
    
    top_results = select_top_GO(allRes, 500, 10, 0.05, 10) 

    p = ggplot_GO_enrichment(top_results, nrow(as.data.frame(test)), length(as.data.frame(test)[as.data.frame(test)[,1] == 1, ]), cond)
    print(p)
    out_filename = paste0("FigS3F_GO_enrichment_AI_peaks_", gsub("/", "_", paste(cond, collapse = '_')) ,".pdf")
    ggsave(file.path(outdir_fig_suppl, out_filename), p, width = 6, height = 6)
}
   >> preparing features information...      2024-11-29 01:49:24 PM 
   >> identifying nearest features...        2024-11-29 01:49:24 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:49:24 PM 
   >> assigning genomic annotation...        2024-11-29 01:49:24 PM 
   >> adding gene annotation...          2024-11-29 01:49:29 PM
   'select()' returned 1:1 mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:49:29 PM 
   >> done...                    2024-11-29 01:49:29 PM 
   >> preparing features information...      2024-11-29 01:49:30 PM 
   >> identifying nearest features...        2024-11-29 01:49:30 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:49:30 PM 
   >> assigning genomic annotation...        2024-11-29 01:49:30 PM 
   >> adding gene annotation...          2024-11-29 01:49:31 PM
   'select()' returned 1:many mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:49:31 PM 
   >> done...                    2024-11-29 01:49:31 PM
   'select()' returned 1:1 mapping between keys and columns
   'select()' returned 1:many mapping between keys and columns
   
   Building most specific GOs .....
    ( 3583 GO terms found. )
   
   Build GO DAG topology ..........
    ( 6174 GO terms and 13460 relations. )
   
   Annotating nodes ...............
    ( 3270 genes annotated to the GO terms. )
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 3229 nontrivial nodes
         parameters: 
             test statistic: Fisher test
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 6174 nontrivial nodes
         parameters: 
             test statistic: KS tests
             score order: increasing
   
             -- Weight Algorithm -- 
   
         The algorithm is scoring 3229 nontrivial nodes
         parameters: 
             test statistic: Fisher test : ratio
   
     Level 17:  4 nodes to be scored.
   
     Level 16:  11 nodes to be scored.
   
     Level 15:  20 nodes to be scored.
   
     Level 14:  37 nodes to be scored.
   
     Level 13:  74 nodes to be scored.
   
     Level 12:  130 nodes to be scored.
   
     Level 11:  226 nodes to be scored.
   
     Level 10:  319 nodes to be scored.
   
     Level 9:   452 nodes to be scored.
   
     Level 8:   450 nodes to be scored.
   
     Level 7:   494 nodes to be scored.
   
     Level 6:   449 nodes to be scored.
   
     Level 5:   312 nodes to be scored.
   
     Level 4:   162 nodes to be scored.
   
     Level 3:   72 nodes to be scored.
   
     Level 2:   16 nodes to be scored.
   
     Level 1:   1 nodes to be scored.
   Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
   ℹ Please use `linewidth` instead.
   This warning is displayed once every 8 hours.
   Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
   generated.
   Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
   ℹ Please use the `linewidth` argument instead.
   This warning is displayed once every 8 hours.
   Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
   generated.
   >> preparing features information...      2024-11-29 01:51:02 PM 
   >> identifying nearest features...        2024-11-29 01:51:02 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:51:02 PM 
   >> assigning genomic annotation...        2024-11-29 01:51:02 PM 
   >> adding gene annotation...          2024-11-29 01:51:03 PM
   'select()' returned 1:1 mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:51:03 PM 
   >> done...                    2024-11-29 01:51:03 PM 
   >> preparing features information...      2024-11-29 01:51:04 PM 
   >> identifying nearest features...        2024-11-29 01:51:04 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:51:04 PM 
   >> assigning genomic annotation...        2024-11-29 01:51:04 PM 
   >> adding gene annotation...          2024-11-29 01:51:05 PM
   'select()' returned 1:many mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:51:05 PM 
   >> done...                    2024-11-29 01:51:05 PM
   'select()' returned 1:1 mapping between keys and columns
   'select()' returned 1:many mapping between keys and columns
   
   Building most specific GOs .....
    ( 3072 GO terms found. )
   
   Build GO DAG topology ..........
    ( 5653 GO terms and 12291 relations. )
   
   Annotating nodes ...............
    ( 2339 genes annotated to the GO terms. )
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 2911 nontrivial nodes
         parameters: 
             test statistic: Fisher test
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 5653 nontrivial nodes
         parameters: 
             test statistic: KS tests
             score order: increasing
   
             -- Weight Algorithm -- 
   
         The algorithm is scoring 2911 nontrivial nodes
         parameters: 
             test statistic: Fisher test : ratio
   
     Level 17:  1 nodes to be scored.
   
     Level 16:  7 nodes to be scored.
   
     Level 15:  17 nodes to be scored.
   
     Level 14:  25 nodes to be scored.
   
     Level 13:  58 nodes to be scored.
   
     Level 12:  102 nodes to be scored.
   
     Level 11:  193 nodes to be scored.
   
     Level 10:  272 nodes to be scored.
   
     Level 9:   384 nodes to be scored.
   
     Level 8:   408 nodes to be scored.
   
     Level 7:   467 nodes to be scored.
   
     Level 6:   425 nodes to be scored.
   
     Level 5:   297 nodes to be scored.
   
     Level 4:   164 nodes to be scored.
   
     Level 3:   74 nodes to be scored.
   
     Level 2:   16 nodes to be scored.
   
     Level 1:   1 nodes to be scored.

   >> preparing features information...      2024-11-29 01:52:18 PM 
   >> identifying nearest features...        2024-11-29 01:52:18 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:52:19 PM 
   >> assigning genomic annotation...        2024-11-29 01:52:19 PM 
   >> adding gene annotation...          2024-11-29 01:52:20 PM
   'select()' returned 1:many mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:52:20 PM 
   >> done...                    2024-11-29 01:52:20 PM 
   >> preparing features information...      2024-11-29 01:52:20 PM 
   >> identifying nearest features...        2024-11-29 01:52:20 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:52:21 PM 
   >> assigning genomic annotation...        2024-11-29 01:52:21 PM 
   >> adding gene annotation...          2024-11-29 01:52:22 PM
   'select()' returned 1:many mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:52:22 PM 
   >> done...                    2024-11-29 01:52:22 PM
   'select()' returned 1:many mapping between keys and columns
   'select()' returned 1:many mapping between keys and columns
   
   Building most specific GOs .....
    ( 3547 GO terms found. )
   
   Build GO DAG topology ..........
    ( 6132 GO terms and 13320 relations. )
   
   Annotating nodes ...............
    ( 3147 genes annotated to the GO terms. )
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 3047 nontrivial nodes
         parameters: 
             test statistic: Fisher test
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 6132 nontrivial nodes
         parameters: 
             test statistic: KS tests
             score order: increasing
   
             -- Weight Algorithm -- 
   
         The algorithm is scoring 3047 nontrivial nodes
         parameters: 
             test statistic: Fisher test : ratio
   
     Level 17:  2 nodes to be scored.
   
     Level 16:  11 nodes to be scored.
   
     Level 15:  20 nodes to be scored.
   
     Level 14:  44 nodes to be scored.
   
     Level 13:  60 nodes to be scored.
   
     Level 12:  108 nodes to be scored.
   
     Level 11:  202 nodes to be scored.
   
     Level 10:  290 nodes to be scored.
   
     Level 9:   417 nodes to be scored.
   
     Level 8:   431 nodes to be scored.
   
     Level 7:   480 nodes to be scored.
   
     Level 6:   422 nodes to be scored.
   
     Level 5:   306 nodes to be scored.
   
     Level 4:   165 nodes to be scored.
   
     Level 3:   71 nodes to be scored.
   
     Level 2:   17 nodes to be scored.
   
     Level 1:   1 nodes to be scored.

   >> preparing features information...      2024-11-29 01:53:49 PM 
   >> identifying nearest features...        2024-11-29 01:53:49 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:53:49 PM 
   >> assigning genomic annotation...        2024-11-29 01:53:49 PM 
   >> adding gene annotation...          2024-11-29 01:53:50 PM
   'select()' returned 1:1 mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:53:50 PM 
   >> done...                    2024-11-29 01:53:50 PM 
   >> preparing features information...      2024-11-29 01:53:51 PM 
   >> identifying nearest features...        2024-11-29 01:53:51 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:53:52 PM 
   >> assigning genomic annotation...        2024-11-29 01:53:52 PM 
   >> adding gene annotation...          2024-11-29 01:53:53 PM
   'select()' returned 1:many mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:53:53 PM 
   >> done...                    2024-11-29 01:53:53 PM
   'select()' returned 1:1 mapping between keys and columns
   'select()' returned 1:many mapping between keys and columns
   
   Building most specific GOs .....
    ( 3712 GO terms found. )
   
   Build GO DAG topology ..........
    ( 6316 GO terms and 13779 relations. )
   
   Annotating nodes ...............
    ( 3568 genes annotated to the GO terms. )
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 3142 nontrivial nodes
         parameters: 
             test statistic: Fisher test
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 6316 nontrivial nodes
         parameters: 
             test statistic: KS tests
             score order: increasing
   
             -- Weight Algorithm -- 
   
         The algorithm is scoring 3142 nontrivial nodes
         parameters: 
             test statistic: Fisher test : ratio
   
     Level 18:  2 nodes to be scored.
   
     Level 17:  4 nodes to be scored.
   
     Level 16:  9 nodes to be scored.
   
     Level 15:  20 nodes to be scored.
   
     Level 14:  40 nodes to be scored.
   
     Level 13:  58 nodes to be scored.
   
     Level 12:  108 nodes to be scored.
   
     Level 11:  202 nodes to be scored.
   
     Level 10:  291 nodes to be scored.
   
     Level 9:   418 nodes to be scored.
   
     Level 8:   466 nodes to be scored.
   
     Level 7:   523 nodes to be scored.
   
     Level 6:   445 nodes to be scored.
   
     Level 5:   303 nodes to be scored.
   
     Level 4:   164 nodes to be scored.
   
     Level 3:   72 nodes to be scored.
   
     Level 2:   16 nodes to be scored.
   
     Level 1:   1 nodes to be scored.

   >> preparing features information...      2024-11-29 01:55:21 PM 
   >> identifying nearest features...        2024-11-29 01:55:21 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:55:21 PM 
   >> assigning genomic annotation...        2024-11-29 01:55:21 PM 
   >> adding gene annotation...          2024-11-29 01:55:22 PM
   'select()' returned 1:1 mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:55:22 PM 
   >> done...                    2024-11-29 01:55:22 PM 
   >> preparing features information...      2024-11-29 01:55:22 PM 
   >> identifying nearest features...        2024-11-29 01:55:22 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:55:23 PM 
   >> assigning genomic annotation...        2024-11-29 01:55:23 PM 
   >> adding gene annotation...          2024-11-29 01:55:24 PM
   'select()' returned 1:many mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:55:24 PM 
   >> done...                    2024-11-29 01:55:24 PM
   'select()' returned 1:1 mapping between keys and columns
   'select()' returned 1:many mapping between keys and columns
   
   Building most specific GOs .....
    ( 3159 GO terms found. )
   
   Build GO DAG topology ..........
    ( 5697 GO terms and 12408 relations. )
   
   Annotating nodes ...............
    ( 2450 genes annotated to the GO terms. )
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 2594 nontrivial nodes
         parameters: 
             test statistic: Fisher test
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 5697 nontrivial nodes
         parameters: 
             test statistic: KS tests
             score order: increasing
   
             -- Weight Algorithm -- 
   
         The algorithm is scoring 2594 nontrivial nodes
         parameters: 
             test statistic: Fisher test : ratio
   
     Level 18:  1 nodes to be scored.
   
     Level 17:  2 nodes to be scored.
   
     Level 16:  5 nodes to be scored.
   
     Level 15:  17 nodes to be scored.
   
     Level 14:  35 nodes to be scored.
   
     Level 13:  55 nodes to be scored.
   
     Level 12:  87 nodes to be scored.
   
     Level 11:  153 nodes to be scored.
   
     Level 10:  240 nodes to be scored.
   
     Level 9:   341 nodes to be scored.
   
     Level 8:   369 nodes to be scored.
   
     Level 7:   409 nodes to be scored.
   
     Level 6:   374 nodes to be scored.
   
     Level 5:   275 nodes to be scored.
   
     Level 4:   150 nodes to be scored.
   
     Level 3:   66 nodes to be scored.
   
     Level 2:   14 nodes to be scored.
   
     Level 1:   1 nodes to be scored.

   >> preparing features information...      2024-11-29 01:56:38 PM 
   >> identifying nearest features...        2024-11-29 01:56:38 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:56:38 PM 
   >> assigning genomic annotation...        2024-11-29 01:56:38 PM 
   >> adding gene annotation...          2024-11-29 01:56:39 PM
   'select()' returned 1:1 mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:56:39 PM 
   >> done...                    2024-11-29 01:56:39 PM 
   >> preparing features information...      2024-11-29 01:56:39 PM 
   >> identifying nearest features...        2024-11-29 01:56:39 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:56:40 PM 
   >> assigning genomic annotation...        2024-11-29 01:56:40 PM 
   >> adding gene annotation...          2024-11-29 01:56:40 PM
   'select()' returned 1:many mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:56:41 PM 
   >> done...                    2024-11-29 01:56:41 PM
   'select()' returned 1:1 mapping between keys and columns
   'select()' returned 1:many mapping between keys and columns
   
   Building most specific GOs .....
    ( 3202 GO terms found. )
   
   Build GO DAG topology ..........
    ( 5756 GO terms and 12564 relations. )
   
   Annotating nodes ...............
    ( 2358 genes annotated to the GO terms. )
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 2484 nontrivial nodes
         parameters: 
             test statistic: Fisher test
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 5756 nontrivial nodes
         parameters: 
             test statistic: KS tests
             score order: increasing
   
             -- Weight Algorithm -- 
   
         The algorithm is scoring 2484 nontrivial nodes
         parameters: 
             test statistic: Fisher test : ratio
   
     Level 18:  1 nodes to be scored.
   
     Level 17:  3 nodes to be scored.
   
     Level 16:  7 nodes to be scored.
   
     Level 15:  14 nodes to be scored.
   
     Level 14:  24 nodes to be scored.
   
     Level 13:  42 nodes to be scored.
   
     Level 12:  71 nodes to be scored.
   
     Level 11:  131 nodes to be scored.
   
     Level 10:  223 nodes to be scored.
   
     Level 9:   327 nodes to be scored.
   
     Level 8:   365 nodes to be scored.
   
     Level 7:   408 nodes to be scored.
   
     Level 6:   370 nodes to be scored.
   
     Level 5:   267 nodes to be scored.
   
     Level 4:   144 nodes to be scored.
   
     Level 3:   70 nodes to be scored.
   
     Level 2:   16 nodes to be scored.
   
     Level 1:   1 nodes to be scored.

   >> preparing features information...      2024-11-29 01:57:55 PM 
   >> identifying nearest features...        2024-11-29 01:57:55 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:57:55 PM 
   >> assigning genomic annotation...        2024-11-29 01:57:55 PM 
   >> adding gene annotation...          2024-11-29 01:57:56 PM
   'select()' returned 1:many mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:57:56 PM 
   >> done...                    2024-11-29 01:57:56 PM 
   >> preparing features information...      2024-11-29 01:58:01 PM 
   >> identifying nearest features...        2024-11-29 01:58:01 PM 
   >> calculating distance from peak to TSS...   2024-11-29 01:58:02 PM 
   >> assigning genomic annotation...        2024-11-29 01:58:02 PM 
   >> adding gene annotation...          2024-11-29 01:58:04 PM
   'select()' returned 1:many mapping between keys and columns
   >> assigning chromosome lengths           2024-11-29 01:58:05 PM 
   >> done...                    2024-11-29 01:58:05 PM
   'select()' returned 1:many mapping between keys and columns
   'select()' returned 1:many mapping between keys and columns
   
   Building most specific GOs .....
    ( 4188 GO terms found. )
   
   Build GO DAG topology ..........
    ( 6851 GO terms and 14972 relations. )
   
   Annotating nodes ...............
    ( 5165 genes annotated to the GO terms. )
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 4850 nontrivial nodes
         parameters: 
             test statistic: Fisher test
   
             -- Classic Algorithm -- 
   
         the algorithm is scoring 6851 nontrivial nodes
         parameters: 
             test statistic: KS tests
             score order: increasing
   
             -- Weight Algorithm -- 
   
         The algorithm is scoring 4850 nontrivial nodes
         parameters: 
             test statistic: Fisher test : ratio
   
     Level 18:  2 nodes to be scored.
   
     Level 17:  6 nodes to be scored.
   
     Level 16:  15 nodes to be scored.
   
     Level 15:  34 nodes to be scored.
   
     Level 14:  73 nodes to be scored.
   
     Level 13:  121 nodes to be scored.
   
     Level 12:  221 nodes to be scored.
   
     Level 11:  388 nodes to be scored.
   
     Level 10:  552 nodes to be scored.
   
     Level 9:   700 nodes to be scored.
   
     Level 8:   714 nodes to be scored.
   
     Level 7:   733 nodes to be scored.
   
     Level 6:   598 nodes to be scored.
   
     Level 5:   387 nodes to be scored.
   
     Level 4:   204 nodes to be scored.
   
     Level 3:   84 nodes to be scored.
   
     Level 2:   17 nodes to be scored.
   
     Level 1:   1 nodes to be scored.

7 Figure S3G - PhyloP enrichment

phyloP = import.bw(config$data$genome$dm6$phyloP124)
peaks_cht = unique(data.frame("chr"=cht$TEST.SNP.CHROM, "start"=cht$REGION.START, "end"=cht$REGION.END, "seqinfo"=cht$peak_id, "signif"=cht$signif_strongAI, "cond"=cht$cond))
peaks_cht_GRange = GRanges(peaks_cht)
ov = findOverlaps(peaks_cht_GRange, phyloP)
cht_peaks_phylo =  cbind(as.data.frame(peaks_cht_GRange)[as.data.frame(ov)$queryHits, ], as.data.frame(phyloP)[as.data.frame(ov)$subjectHits, ])
colnames(cht_peaks_phylo) = c("peak_chr", "peaks_start", "peak_end", "peaks_width", "peak_strand", "seqinfo",  "signif", "cond", "seqnames", "start",  "end", "width", "strand", "score")

cht_peaks_phylo_mean = cht_peaks_phylo %>%
  dplyr::mutate(weighted_phylop = score * width) %>%
  dplyr::select(seqinfo, score, weighted_phylop, peaks_width, signif, cond) %>%
  dplyr::group_by(seqinfo, signif, cond) %>%
  dplyr::summarize(phylop = sum(weighted_phylop) / mean(peaks_width))
   `summarise()` has grouped output by 'seqinfo', 'signif'. You can override using
   the `.groups` argument.
cht_peaks_phylo_mean$signif = factor(gsub(TRUE, "AI peak", gsub(FALSE, "no AI", cht_peaks_phylo_mean$signif)), levels=c("AI peak", "no AI"))
cht_peaks_phylo_mean$cond = factor(cht_peaks_phylo_mean$cond, levels=c("twi/24", "ctcf/68", "mef2/68", "mef2/1012", "bin/68",  "bin/1012"))

Summary_data = cht_peaks_phylo_mean %>%  group_by(signif) %>% summarise(n=n()) 

p = ggplot(cht_peaks_phylo_mean, aes(x=signif, y=phylop, fill=signif)) +
    geom_violin() +
    geom_boxplot(width=0.1, fill="white", alpha=0.5) +
    scale_fill_manual(values = c("orange2", "grey40")) +
    stat_compare_means(comparisons = list(c("AI peak", "no AI")), label.y=5) +
    geom_text(data=Summary_data ,aes(x = signif, y = -0.6, label=n),color="grey25", fontface = 2, size = 3.5) +
    ylim(-1,6) +
    xlab("AI Peaks vs non AI peaks") +
    ylab("PhyloP average score on peak") +
    theme_bw() + 
    theme(legend.position="none") +
    theme(panel.grid = element_line(colour = "grey80", linewidth = 1), axis.text = element_text(size = 9)) +
    theme(axis.title = element_text(size = 9), plot.title = element_text(size=9)) +
    theme(strip.text = element_text(size=9)) +
    theme(panel.grid.minor = element_line(linewidth = 0.25), panel.grid.major = element_line(linewidth = 0.5)) 
#     facet_wrap(~cond)+

print(p)
   Warning: Removed 101 rows containing non-finite values (`stat_ydensity()`).
   Warning: Removed 101 rows containing non-finite values (`stat_boxplot()`).
   Warning: Removed 101 rows containing non-finite values (`stat_signif()`).

ggsave(file.path(outdir_fig_suppl, "FigS3G_phyloP_conservation_sign_peaks.pdf"), p, width = 6, height = 6)
   Warning: Removed 101 rows containing non-finite values (`stat_ydensity()`).
   Warning: Removed 101 rows containing non-finite values (`stat_boxplot()`).
   Warning: Removed 101 rows containing non-finite values (`stat_signif()`).
LS0tCnRpdGxlOiAiRmlndXJlX1MzIgpvdXRwdXQ6CiAgIEJpb2NTdHlsZTo6aHRtbF9kb2N1bWVudDoKICAgICAgdG9jOiB0cnVlCiAgICAgIGRmX3ByaW50OiBwYWdlZAogICAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICAgIGhpZ2hsaWdodDogdGFuZ28KI2JpYmxpb2dyYXBoeToga25uX21sX2ludHJvLmJpYgplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCmBgYHtyIHN0eWxlLCBlY2hvPUZBTFNFLCByZXN1bHRzPSJhc2lzIn0KbGlicmFyeSgia25pdHIiKQpvcHRpb25zKGRpZ2l0cyA9IDIsIHdpZHRoID0gODApCm9wdGlvbnMoYml0bWFwVHlwZSA9ICdjYWlybycpCmdvbGRlbl9yYXRpbyA8LSAoMSArIHNxcnQoNSkpIC8gMgpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgdGlkeSA9IEZBTFNFLCBpbmNsdWRlID0gVFJVRSwgY2FjaGUgPSBGQUxTRSwKICAgICAgICAgICAgICAgZGV2PWMoJ3BuZycsICdwZGYnKSwgY29tbWVudCA9ICcgICcsIGRwaSA9IDMwMCkKCm9wdGlvbnMoc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQprbml0cjo6b3B0c19jaHVuayRzZXQoY2FjaGU9RkFMU0UpCm9wdGlvbnMoZGlnaXRzID0gNSkgICAgICAgICAKYGBgCgojIFNldHVwIGFuZCBkYXRhCgpgYGB7cn0Kc291cmNlKCIuLi91dGlscy91dGlscy5SIikKY29uZmlnID0gbG9hZF9jb25maWcoKQoKIyBsb2FkIENIVCByZXN1bHRzCmNodF9mdWxsID0gbGFwcGx5KGFiX3RwX2xpc3QsIGZ1bmN0aW9uKGFiX3RwKSBsb2FkX2NodF9yZXN1bHRzKGFiX3RwLCByZW1vdmVfY2hyID0gRikpICU+JSBiaW5kX3Jvd3MoKQpjaHQgPSBjaHRfZnVsbCAlPiUgZmlsdGVyKCFURVNULlNOUC5DSFJPTSAlaW4lIGMoImNoclgiLCAiY2hyWSIsICJjaHJNIikpCmNodF9zaWduID0gY2h0ICU+JSBmaWx0ZXIoc2lnbmlmX3N0cm9uZ0FJKSAKCiMgZ2VuZXMgYW5kIHByb21vdGVycwpnZW5lcyA9IGxvYWRfZ2VuZXMoKQpwcm9tb3RlcnMgPSByZXNpemUoZ2VuZXMsIHdpZHRoID0gMTAwMCwgZml4ID0gInN0YXJ0IikKCiMgY29tYmluZWQgbW90aWYgc2V0IChhbGwgVEZzLCBwZWFrcyArIGFsbGVsZXMpCmZpbW8gPSBnZXRfZnVsbF9tb3RpZl9zZXRzKGNodCwgYWJfdHBfbGlzdCkKIyBvbmx5IGFsbGVsZXMKZmltb19hbGxlbGVzICA9IGxhcHBseShhYl90cF9saXN0LCBmdW5jdGlvbihhYl90cCkgcGFyc2VfbW90aWZzX2luX3R3b19hbGxlbGVzKGFiX3RwLCBjaHQpKSAlPiUgYmluZF9yb3dzKCkgCgpgYGAKCiMgRmlndXJlIFMzQjogSW5kZWxzIGxlbmd0aAoKYGBge3J9CmNodF9zZWwgPSBjaHQgJT4lCiAgZmlsdGVyKHNpZ25pZl9zdHJvbmdBSSkgJT4lCiAgZ3JvdXBfYnkocGVha19pZCkgJT4lCiAgI211dGF0ZShtaW5fcHZhbCA9IG1pbihQLlZBTFVFKSkgJT4lCiAgI2ZpbHRlcihQLlZBTFVFID09IG1pbl9wdmFsKSAlPiUKICBtdXRhdGUobWF4X2luZGVsID0gbWF4KGluZGVsX2xlbmd0aCksIG1pbl9pbmRlbCA9IG1pbihpbmRlbF9sZW5ndGgpKSAlPiUKICBmaWx0ZXIoaW5kZWxfbGVuZ3RoID09IG1heF9pbmRlbCkgJT4lCiMgIG11dGF0ZShtYXhfQUkgPSBtYXgoQUlfYWJzKSkgJT4lCiMgIGZpbHRlcihBSV9hYnMgPT0gbWF4X0FJKSAlPiUKICBzZWxlY3QoY29uZGl0aW9uLCBwZWFrX2lkLCBpbmRlbF9sZW5ndGgsIEFJX2FicykgJT4lCiAgdW5pcXVlKCkgJT4lCiAgbXV0YXRlKGJpbl9pbmRlbCA9IGN1dChpbmRlbF9sZW5ndGgsIGJyZWFrcyA9IGMoMCwgMSwgMTAsIEluZiksIGxhYmVscyA9IGMoIlNOUCIsICIyLTEwIiwgIj4xMCIpLCBpbmNsdWRlLmxvd2VzdCA9IFQpKQoKCmNodF9zZWwkbGFiZWwgPSBmYWN0b3IoYWJfdHBfbGFiZWxzW2NodF9zZWwkY29uZGl0aW9uXSwgbGV2ZWxzID0gYWJfdHBfbGFiZWxzKQoKCnAgPSBnZ3Bsb3QoY2h0X3NlbCwgYWVzKHggPSBiaW5faW5kZWwsIHkgPSBBSV9hYnMsIGZpbGwgPSBiaW5faW5kZWwpKSArIAogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNiwgb3V0bGllci5zaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY2JQYWxldHRlLCBuYW1lID0gIkluZGVsIGxlbmd0aCIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMiIsIGxpbWl0cyA9IGMoMC4xLCAwLjcpKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zID0gbGlzdChjKCJTTlAiLCAiPjEwIiksIGMoIlNOUCIsICIyLTEwIikpKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKCkgKwogIHhsYWIoIiIpICsKICB5bGFiKCJBbGxlbGUgaW1iYWxhbmNlIikgKwogIHRoZW1lX2J3KCkgKwogIGZhY2V0X2dyaWQofmxhYmVsKSArCiAgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gZnVuY3Rpb24oeCkgYyh5ID0gbWVkaWFuKHgpICsgMC4xLCBsYWJlbCA9IGxlbmd0aCh4KSksIGdlb20gPSAidGV4dCIsIHNpemUgPSA0KSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgICNheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTE2LCBhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIGNvbG9yID0gVEZjb2xzKSwgCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xNiksIAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplPTE4KSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9MTYpLAogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLCBzdHJpcC50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xNiksIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xNikpCgoKY2h0X3NlbCAlPiUgCiAgZ3JvdXBfYnkoY29uZGl0aW9uKSAlPiUKICBtdXRhdGUoTiA9IG4oKSkgJT4lCiAgZ3JvdXBfYnkoY29uZGl0aW9uLCBiaW5faW5kZWwpICU+JQogIGRwbHlyOjpzdW1tYXJpemUobiA9IG4oKSwgc2hhcmUgPSBuIC8gbWVhbihOKSwgcmVzX3NoYXJlID0gMSAtIHNoYXJlKQoKcAoKb3V0ZiA9IGZpbGUucGF0aChvdXRkaXJfZmlnX3N1cHBsLCBwYXN0ZTAoIkZpZ1MzQl9pbmRlbHNfQUkucGRmIikpCmdnc2F2ZShvdXRmLCBwLCB3aWR0aCA9IDE4LCBoZWlnaHQgPSA1KQoKCmBgYAoKCiMgRmlndXJlIFMzQzogSW5kZWxzIGxlbmd0aAoKYGBge3J9CgpjaHQgPSBsYXBwbHkoYWJfdHBfbGlzdCwgZnVuY3Rpb24oYWJfdHApIGxvYWRfY2h0X3Jlc3VsdHMoYWJfdHApKSAlPiUgYmluZF9yb3dzKCkKY2h0X2dyID0gY2h0ICU+JSBtdXRhdGUoY2hyID0gVEVTVC5TTlAuQ0hST00sIHN0YXJ0ID0gVEVTVC5TTlAuUE9TLCBlbmQgPSBURVNULlNOUC5QT1MpICU+JSBHUmFuZ2VzKCkKCiMgRjEgQVRBQy1zZXEgcmVzdWx0cwoKIyBjb29yZGluYXRlcyBvZiBBVEFDIHBlYWtzCmF0YWNfcmVnaW9uc19wYXRoID0gIi9nL2Z1cmxvbmcvcHJvamVjdC82OF9GMV9jaXNyZWdfaWNoaXAvZGF0YS9GMV9wYXBlcl9tdWx0aW9tL0FUQUNfZmVhdHVyZV9sb2NhdGlvbl9kbTYuYmVkIgphdGFjX3JlZ2lvbnMgPSBpbXBvcnQoYXRhY19yZWdpb25zX3BhdGgsIGZvcm1hdCA9ICJiZWQiKQoKIyBpbWJhbGFuY2UgaW5mbyBmb3IgQVRBQyBwZWFrcwphdGFjX2FpX3BhdGggPSAiL2cvZnVybG9uZy9wcm9qZWN0LzY4X0YxX2Npc3JlZ19pY2hpcC9kYXRhL0YxX3BhcGVyX211bHRpb20vQVRBQ19hbGxfcGVha3NfYXRhY19YLnR4dCIKYXRhY19haSA9IHJlYWQuZGVsaW0oYXRhY19haV9wYXRoKQoKIyBhZGRpdGlvbmFsIGFubm90YXRpb25zIGZvciBhbGxlbGUgaW1iYWxhbmNlCmF0YWNfYWlfc3VtID0gYXRhY19haSAlPiUgCiAgbXV0YXRlKEFJID0gcGFkaiA8IDAuMDEgJiBhYnMoMC41IC0gbWVhbnByb3ApID4gMC4xKSAlPiUKICBncm91cF9ieShmZWF0dXJlLCB0aW1lKSAlPiUgCiAgc3VtbWFyaXplKG5fQUkgPSBzdW0oQUkpLCAKICAgICAgICAgICAgQUlfcGVhayA9IGFueShBSSksCiAgICAgICAgICAgIG1lYW5fQUkgPSBhYnMoMC41IC0gbWVhbihtZWFucHJvcCkpLCAKICAgICAgICAgICAgbWF4X0FJID0gbWF4KGFicygwLjUgLSBtZWFucHJvcCkpLAogICAgICAgICAgICBuX2hldF9saW5lcyA9bigpKQoKIyBjb21iaW5lIEFJSSBpbmZvIHdpdGggcGVhayBjb29yZGluYXRlcwphdGFjX2YxX2RmID0gbWVyZ2UoZGF0YS5mcmFtZShhdGFjX3JlZ2lvbnMpLCBhdGFjX2FpX3N1bSwgYnkueCA9ICJuYW1lIiwgYnkueSA9ICJmZWF0dXJlIikgJT4lIGZpbHRlcighc2VxbmFtZXMgJWluJSBjKCJjaHJYIiwgImNoclkiKSkKYXRhY19haV9nciA9IEdSYW5nZXMoYXRhY19mMV9kZikKCgojIERvIHRoZSBhbmFseXNpcyBwZXIgVEYgYW5kIEFUQUMgdGltZS1wb2ludAoKCmRmID0gZGF0YS5mcmFtZSgpCgpmb3IgKGFiX3RwIGluIGFiX3RwX2xpc3QpIHsKICAKICB0cCA9IGdzdWIoIi0iLCAiIiwgdGltZXBvaW50c1thYl90cF0pCiAgCiAgIyBnZXQgVEYgcGVha3MKICBBSV9wZWFrcyA9IGdldF9wZWFrc19mcm9tX2NodChhYl90cCwgY2h0KQogIG5hbWVzKG1jb2xzKEFJX3BlYWtzKSkgPSBwYXN0ZTAobmFtZXMobWNvbHMoQUlfcGVha3MpKSwgIi50ZiIpCiAgCiAgIyBnZXQgQVRBQyBwZWFrcyBmb3Igc2VsZWN0ZWQgdGltZS1wb2ludAogIEFJX2F0YWMgPSBhdGFjX2FpX2dyW2F0YWNfYWlfZ3IkdGltZSA9PSB0cF0KICBuYW1lcyhtY29scyhBSV9hdGFjKSkgPSBwYXN0ZTAobmFtZXMobWNvbHMoQUlfYXRhYykpLCAiLmF0YWMiKQogIAogIG92ID0gZmluZE92ZXJsYXBzKEFJX3BlYWtzLCBBSV9hdGFjKQogIAogIAogIHJlcyA9IGNiaW5kLmRhdGEuZnJhbWUobWNvbHMoQUlfcGVha3NbcXVlcnlIaXRzKG92KV0pLCBtY29scyhBSV9hdGFjW3N1YmplY3RIaXRzKG92KV0pKQogIAogIHByaW50KGFiX3RwKQogIHd0ID0gd2lsY294LnRlc3QobWVhbl9BSS5hdGFjIH4gQUlfcGVhay50ZiwgcmVzLCBhbHRlcm5hdGl2ZSA9ICJsZXNzIikKICBwcmludCh3dCkKICB3dCA9IHdpbGNveC50ZXN0KG1heF9BSS5hdGFjIH4gQUlfcGVhay50ZiwgcmVzLCBhbHRlcm5hdGl2ZSA9ICJsZXNzIikKICBwcmludCh3dCkKICAKICBkZiA9IHJiaW5kLmRhdGEuZnJhbWUoZGYsIHJlcykKICAKfQoKZGYgJTw+JSAKICBtdXRhdGUobGFiZWwgPSBmYWN0b3IoYWJfdHBfbGFiZWxzW2NvbmRpdGlvbi50Zl0sIGxldmVscyA9IGFiX3RwX2xhYmVscykpCgpkZiAlPiUgZ3JvdXBfYnkoY29uZGl0aW9uLnRmLCBBSV9wZWFrLnRmKSAlPiUKICBzdW1tYXJpemUobWVhbihtZWFuX0FJLmF0YWMsIG1lYW4obWF4X0FJLmF0YWMpKSkKCnAgPSBnZ3Bsb3QoZGYsIGFlcyh4ID0gQUlfcGVhay50ZiwgIHkgPSBtYXhfQUkuYXRhYykpICsKICBnZW9tX3Zpb2xpbihmaWxsID0gImRhcmtibHVlIiwgYWxwaGEgPSAwLjMpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjQsIG91dGxpZXIuc2l6ZSA9IDAuMSwgZmlsbCA9ICJkYXJrYmx1ZSIsIGFscGhhID0gMC43KSArCiAgZmFjZXRfd3JhcCh+IGxhYmVsLCBuY29sID0gMykgKwogIHRoZW1lX2J3KCkgKwogIHN0YXRfY29tcGFyZV9tZWFucygpICsKICB4bGFiKCJBSSBURiBwZWFrcyAoRjEpIikgKwogIHlsYWIoIkFsbGVsZSBpbWJhbGFuY2Ugb2YgQVRBQyBwZWFrcyAoRjEpIikgKwogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSwgCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemU9MTYpLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xNiksCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksIHN0cmlwLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpKQoKcHJpbnQocCkKZ2dzYXZlKGZpbGUucGF0aChvdXRkaXJfZmlnX3N1cHBsLCAiRmlnUzNDX0FJX0FUQUNfYnlfVEYucGRmIiksIHAsIHdpZHRoID0gOSwgaGVpZ2h0ID0gNikKCmBgYAoKCgoKIyBGaWd1cmUgUzNECgpgYGB7cn0KCiMgb25seSBxdWFudGlmaWVkIHBlYWtzIGZvciBDSFQKI3BlYWtzID0gbGFwcGx5KGFiX3RwX2xpc3QsIGZ1bmN0aW9uKGFiX3RwKSBnZXRfcGVha3NfZnJvbV9jaHQoYWJfdHAsIGNodCwgYXNfZ3JhbmdlcyA9IFQpKQojbmFtZXMocGVha3MpID0gYWJfdHBfbGlzdAoKcGVha3MgPSBnZXRfY29uc2Vuc3VzX3BlYWtzZXRzX3dpdGhfQUkoYWJfdHBfbGlzdCwgY2h0LCBmaWx0ZXIgPSBGKQoKZGhzID0gbG9hZF9kaHMoKSAlPiUgR1JhbmdlcygpCmRocyRESFNjb25kID0gY3V0KGRocyRudW1fY29uZGl0aW9ucywgYnJlYWtzID0gYygxLCAyLCAxNywgMTkpLCBpbmNsdWRlLmxvd2VzdCA9IFQpCmRocyRESFNfbW9kRVJOID0gY3V0KGRocyRudW1fbW9kRVJOLGJyZWFrcyA9IGMoMCwgOSwgMjUxKSwgaW5jbHVkZS5sb3dlc3QgPSBUKQoKCnJlcyA9IGxhcHBseShjKCJkaXN0YWwiLCAicHJveGltYWwiKSwgZnVuY3Rpb24oVFNTX3R5cGUpIHsKCiAgZGhzX2dyID0gZGhzICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGZpbHRlcihUU1MgPT0gVFNTX3R5cGUpICU+JSBHUmFuZ2VzKCkKICAKICAjIERIUyBjb25kaXRpb25zCiAgZGYgPSBsYXBwbHkocGVha3MsIGZ1bmN0aW9uKHgpIHtvdiA9IGZpbmRPdmVybGFwcyh4LCBkaHNfZ3IpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2JpbmQuZGF0YS5mcmFtZShhcy5kYXRhLmZyYW1lKHhbcXVlcnlIaXRzKG92KV0pLCBhcy5kYXRhLmZyYW1lKGRoc19ncltzdWJqZWN0SGl0cyhvdildKSkgfSkgJT4lCiAgICAgICAgICAgIGJpbmRfcm93cygpCiAgCiAgZnRzMSA9IGxhcHBseShhYl90cF9saXN0LCBmdW5jdGlvbihhYl90cCkge2Zpc2hlcl90ZXN0X3R3b19ncm91cHMoZGYsIGFiX3RwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwMSA9ICJpc0FJIiwgZ3JvdXAxX3ZhbCA9IGMoVFJVRSwgRkFMU0UpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cDIgPSAiREhTY29uZCIsIGdyb3VwMl92YWwgPSBjKCJbMSwyXSIsICIoMTcsMTldIikpfSkgJT4lCiAgICAgICAgICAgIGJpbmRfcm93cygpICU+JSBtdXRhdGUoY29tcCA9ICJESFMgY29uZGl0aW9uc1xuKDEtMiB2cy4gMTgtMTkpIiwgbGFiZWxzID0gYWJfdHBfbGFiZWxzKQogIAogICMgbW9kRVJOIFRGcwogIGZ0czIgPSBsYXBwbHkoYWJfdHBfbGlzdCwgZnVuY3Rpb24oYWJfdHApIHtmaXNoZXJfdGVzdF90d29fZ3JvdXBzKGRmLCBhYl90cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cDEgPSAiaXNBSSIsIGdyb3VwMV92YWwgPSBjKFRSVUUsIEZBTFNFKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAyID0gIkRIU19tb2RFUk4iLCBncm91cDJfdmFsID0gYygiKDksMjUxXSIsICJbMCw5XSIpKX0pICU+JQogICAgICAgICAgICBiaW5kX3Jvd3MoKSAlPiUgbXV0YXRlKGNvbXAgPSAibW9kRVJOIFRGc1xuKDMxLTI1MSB2cy4gMC01KSIsIGxhYmVscyA9IGFiX3RwX2xhYmVscykKICAKICAKICByZXMgPSByYmluZC5kYXRhLmZyYW1lKGZ0czEsIGZ0czIpICU+JSBtdXRhdGUoVFNTX3R5cGUgPSBwYXN0ZSgiVFNTIiwgVFNTX3R5cGUpKSAKICAKICAKfSkgJT4lIGJpbmRfcm93cygpCgoKIyBNb2RFUk4gVEZzCgpkZiA9IHJlcyAlPiUgZmlsdGVyKGNvbXAyID09ICJESFNfbW9kRVJOXyg5LDI1MV1fdnNfWzAsOV0iKSAKZGYkbGFiZWwgPSBhYl90cF9sYWJlbHMKZGYkbGFiZWwgPSBmYWN0b3IoZGYkbGFiZWwsIGxldmVscyA9IGFiX3RwX2xhYmVscykKCnAgPSBnZ3Bsb3QoZGYsIGFlcyh4ID0gbGFiZWwsIHkgPSBvZGRzX3JhdGlvKSkgKwogIGZhY2V0X3dyYXAoflRTU190eXBlKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMSwgY29sb3IgPSAiZGFya3JlZCIpICsKICBnZW9tX2JhcihhZXMoZmlsbCA9IC1sb2cxMChwdmFsKSksIGNvbG9yID0gImRhcmtibHVlIiwgc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgd2lkdGggPSAwLjUpICsKICAjc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICIiLCB2YWx1ZXMgPSBjKCJkYXJrYmx1ZSIsICJkYXJrZ3JleSIpLCBsYWJlbHMgPSBjKCJBSSBwZWFrcyIsICJub24tQUkgcGVha3MiKSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChyMSwgMiksIHggPSBsYWJlbCwgeSA9IG9kZHNfcmF0aW8gKyAwLjA1KSwgZGF0YSA9IGRmLCBzaXplID0gNikgKwogIHlsYWIoIkRlcGxldGlvaW4gaW4gdWJpcXVpdG91c2x5IGJvdW5kIHJlZ2lvbnMgKD4xMCBtb2RFUk4gVEZzKSBcbkZpc2hlcidzIFRlc3QgT2RkcyBSYXRpbyIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgY29sb3VyID0gVEZjb2xzKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLCAKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKQoKCnAKCm91dGYgPSBmaWxlLnBhdGgob3V0ZGlyX2ZpZ19zdXBwbCwgcGFzdGUwKCJGaWdTM0RfbW9kRVJOX2Zpc2hlci5wZGYiKSkKZ2dzYXZlKG91dGYsIHAsIHdpZHRoID0gMTAsIGhlaWdodCA9IDYpCgpgYGAKCgoKIyBGaWd1cmUgUzNFCgoKYGBge3J9CmRmID0gcmVzICU+JSBmaWx0ZXIoY29tcDIgPT0gIkRIU2NvbmRfWzEsMl1fdnNfKDE3LDE5XSIpIApkZiRsYWJlbCA9IGFiX3RwX2xhYmVscwpkZiRsYWJlbCA9IGZhY3RvcihkZiRsYWJlbCwgbGV2ZWxzID0gYWJfdHBfbGFiZWxzKQoKCgpwID0gZ2dwbG90KGRmLCBhZXMoeCA9IGxhYmVsLCB5ID0gb2Rkc19yYXRpbykpICsKICBmYWNldF93cmFwKH5UU1NfdHlwZSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEsIGNvbG9yID0gImRhcmtyZWQiKSArCiAgZ2VvbV9iYXIoYWVzKGZpbGwgPSAtbG9nMTAocHZhbCkpLCBjb2xvciA9ICJkYXJrYmx1ZSIsIHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIHdpZHRoID0gMC41KSArCiAgI3NjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiIiwgdmFsdWVzID0gYygiZGFya2JsdWUiLCAiZGFya2dyZXkiKSwgbGFiZWxzID0gYygiQUkgcGVha3MiLCAibm9uLUFJIHBlYWtzIikpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQocjEsIDIpLCB4ID0gbGFiZWwsIHkgPSBvZGRzX3JhdGlvICsgMC4wNyksIGRhdGEgPSBkZiwgc2l6ZSA9IDYpICsKICB5bGFiKCJFbnJpY2htZW50IGluIGNvbmRpdGlvbi1zcGVjaWZpYyBESFMgXG5GaXNoZXIncyBUZXN0IE9kZHMgUmF0aW8iKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIGNvbG91ciA9IFRGY29scyksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwgCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSkKCgpwCgpvdXRmID0gZmlsZS5wYXRoKG91dGRpcl9maWdfc3VwcGwsIHBhc3RlMCgiRmlnUzNFX25vbnViaXFESFNfZmlzaGVyLnBkZiIpKQpnZ3NhdmUob3V0ZiwgcCwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNikKCgoKYGBgCgoKCiMgRmlndXJlIFMzRiAtIEdPIEVucmljaG1lbnQgZm9yIEFJIHBlYWtzCgpgYGB7cn0KZm9yIChjb25kIGluIGMoYWJfdHBfbGlzdCwgbGlzdChhYl90cF9saXN0KSkpIHsKICAKICAgIHRlc3RfZ2VuZUlEID0gZ2V0X3Rlc3RfZ2VuZUlEKGNodCwgY29uZCwgMTAwMCkKICAgIGJhY2tncm91bmRfZ2VuZUlEID0gZ2V0X2JhY2tncm91bmRfZ2VuZUlEKGNodCwgY29uZCwgMTAwMCwgdGVzdF9nZW5lSUQpCgogICAgb3V0ID0gY3JlYXRlX0dPZGF0YSh0ZXN0X2dlbmVJRCwgYmFja2dyb3VuZF9nZW5lSUQsICJCUCIpCiAgICBHT2RhdGEgPSBvdXRbWzFdXQogICAgdGVzdCA9IG91dFtbMl1dCiAgICBuX25vZGVzID0gbGVuZ3RoKGF0dHJpYnV0ZXMoR09kYXRhKSRncmFwaEBub2RlcykKCiAgICAjIENsYXNzaWMgRmlzaGVyIHRlc3QKICAgIHRlc3Quc3RhdCA8LSBuZXcoImNsYXNzaWNDb3VudCIsIHRlc3RTdGF0aXN0aWMgPSBHT0Zpc2hlclRlc3QsIG5hbWUgPSAiRmlzaGVyIHRlc3QiKQogICAgcmVzdWx0RmlzaGVyIDwtIGdldFNpZ0dyb3VwcyhHT2RhdGEsIHRlc3Quc3RhdCkKCiAgICAjIEtTIHRlc3QKICAgIHRlc3Quc3RhdCA8LSBuZXcoImNsYXNzaWNTY29yZSIsIHRlc3RTdGF0aXN0aWMgPSBHT0tTVGVzdCwgbmFtZSA9ICJLUyB0ZXN0cyIpCiAgICByZXN1bHRLUyA8LSBnZXRTaWdHcm91cHMoR09kYXRhLCB0ZXN0LnN0YXQpCgogICAgIyBXZWlnaHQgYWxnb3JpdGhtCiAgICB0ZXN0LnN0YXQgPC0gbmV3KCJ3ZWlnaHRDb3VudCIsIHRlc3RTdGF0aXN0aWMgPSBHT0Zpc2hlclRlc3QsIG5hbWUgPSAiRmlzaGVyIHRlc3QiLCBzaWdSYXRpbyA9ICJyYXRpbyIpCiAgICByZXN1bHRXZWlnaHQgPC0gZ2V0U2lnR3JvdXBzKEdPZGF0YSwgdGVzdC5zdGF0KQogICAgCiAgICBhbGxSZXMgPC0gR2VuVGFibGUoR09kYXRhLCBjbGFzc2ljID0gcmVzdWx0RmlzaGVyLCAKICAgICAgICAgICBLUyA9IHJlc3VsdEtTLCB3ZWlnaHQgPSByZXN1bHRXZWlnaHQsCiAgICAgICAgICAgb3JkZXJCeSA9ICJ3ZWlnaHQiLCByYW5rc09mID0gImNsYXNzaWMiLCB0b3BOb2RlcyA9IG5fbm9kZXMpCiAgICBhbGxSZXMkRm9sZF9FbnJpY2htZW50ID0gYWxsUmVzJFNpZ25pZmljYW50IC8gYWxsUmVzJEV4cGVjdGVkCiAgICBhbGxSZXMkRkRSID0gYWxsUmVzJHdlaWdodAogICAgCiAgICB0b3BfcmVzdWx0cyA9IHNlbGVjdF90b3BfR08oYWxsUmVzLCA1MDAsIDEwLCAwLjA1LCAxMCkgCgogICAgcCA9IGdncGxvdF9HT19lbnJpY2htZW50KHRvcF9yZXN1bHRzLCBucm93KGFzLmRhdGEuZnJhbWUodGVzdCkpLCBsZW5ndGgoYXMuZGF0YS5mcmFtZSh0ZXN0KVthcy5kYXRhLmZyYW1lKHRlc3QpWywxXSA9PSAxLCBdKSwgY29uZCkKICAgIHByaW50KHApCiAgICBvdXRfZmlsZW5hbWUgPSBwYXN0ZTAoIkZpZ1MzRl9HT19lbnJpY2htZW50X0FJX3BlYWtzXyIsIGdzdWIoIi8iLCAiXyIsIHBhc3RlKGNvbmQsIGNvbGxhcHNlID0gJ18nKSkgLCIucGRmIikKICAgIGdnc2F2ZShmaWxlLnBhdGgob3V0ZGlyX2ZpZ19zdXBwbCwgb3V0X2ZpbGVuYW1lKSwgcCwgd2lkdGggPSA2LCBoZWlnaHQgPSA2KQp9CmBgYAoKCiMgRmlndXJlIFMzRyAtIFBoeWxvUCBlbnJpY2htZW50IAoKCmBgYHtyfQoKcGh5bG9QID0gaW1wb3J0LmJ3KGNvbmZpZyRkYXRhJGdlbm9tZSRkbTYkcGh5bG9QMTI0KQpwZWFrc19jaHQgPSB1bmlxdWUoZGF0YS5mcmFtZSgiY2hyIj1jaHQkVEVTVC5TTlAuQ0hST00sICJzdGFydCI9Y2h0JFJFR0lPTi5TVEFSVCwgImVuZCI9Y2h0JFJFR0lPTi5FTkQsICJzZXFpbmZvIj1jaHQkcGVha19pZCwgInNpZ25pZiI9Y2h0JHNpZ25pZl9zdHJvbmdBSSwgImNvbmQiPWNodCRjb25kKSkKcGVha3NfY2h0X0dSYW5nZSA9IEdSYW5nZXMocGVha3NfY2h0KQpvdiA9IGZpbmRPdmVybGFwcyhwZWFrc19jaHRfR1JhbmdlLCBwaHlsb1ApCmNodF9wZWFrc19waHlsbyA9ICBjYmluZChhcy5kYXRhLmZyYW1lKHBlYWtzX2NodF9HUmFuZ2UpW2FzLmRhdGEuZnJhbWUob3YpJHF1ZXJ5SGl0cywgXSwgYXMuZGF0YS5mcmFtZShwaHlsb1ApW2FzLmRhdGEuZnJhbWUob3YpJHN1YmplY3RIaXRzLCBdKQpjb2xuYW1lcyhjaHRfcGVha3NfcGh5bG8pID0gYygicGVha19jaHIiLCAicGVha3Nfc3RhcnQiLCAicGVha19lbmQiLCAicGVha3Nfd2lkdGgiLCAicGVha19zdHJhbmQiLCAic2VxaW5mbyIsICAic2lnbmlmIiwgImNvbmQiLCAic2VxbmFtZXMiLCAic3RhcnQiLCAgImVuZCIsICJ3aWR0aCIsICJzdHJhbmQiLCAic2NvcmUiKQoKY2h0X3BlYWtzX3BoeWxvX21lYW4gPSBjaHRfcGVha3NfcGh5bG8gJT4lCiAgZHBseXI6Om11dGF0ZSh3ZWlnaHRlZF9waHlsb3AgPSBzY29yZSAqIHdpZHRoKSAlPiUKICBkcGx5cjo6c2VsZWN0KHNlcWluZm8sIHNjb3JlLCB3ZWlnaHRlZF9waHlsb3AsIHBlYWtzX3dpZHRoLCBzaWduaWYsIGNvbmQpICU+JQogIGRwbHlyOjpncm91cF9ieShzZXFpbmZvLCBzaWduaWYsIGNvbmQpICU+JQogIGRwbHlyOjpzdW1tYXJpemUocGh5bG9wID0gc3VtKHdlaWdodGVkX3BoeWxvcCkgLyBtZWFuKHBlYWtzX3dpZHRoKSkKICAgICAgICAgICAgICAKCmNodF9wZWFrc19waHlsb19tZWFuJHNpZ25pZiA9IGZhY3Rvcihnc3ViKFRSVUUsICJBSSBwZWFrIiwgZ3N1YihGQUxTRSwgIm5vIEFJIiwgY2h0X3BlYWtzX3BoeWxvX21lYW4kc2lnbmlmKSksIGxldmVscz1jKCJBSSBwZWFrIiwgIm5vIEFJIikpCmNodF9wZWFrc19waHlsb19tZWFuJGNvbmQgPSBmYWN0b3IoY2h0X3BlYWtzX3BoeWxvX21lYW4kY29uZCwgbGV2ZWxzPWMoInR3aS8yNCIsICJjdGNmLzY4IiwgIm1lZjIvNjgiLCAibWVmMi8xMDEyIiwgImJpbi82OCIsICAiYmluLzEwMTIiKSkKClN1bW1hcnlfZGF0YSA9IGNodF9wZWFrc19waHlsb19tZWFuICU+JSAgZ3JvdXBfYnkoc2lnbmlmKSAlPiUgc3VtbWFyaXNlKG49bigpKSAKCnAgPSBnZ3Bsb3QoY2h0X3BlYWtzX3BoeWxvX21lYW4sIGFlcyh4PXNpZ25pZiwgeT1waHlsb3AsIGZpbGw9c2lnbmlmKSkgKwogICAgZ2VvbV92aW9saW4oKSArCiAgICBnZW9tX2JveHBsb3Qod2lkdGg9MC4xLCBmaWxsPSJ3aGl0ZSIsIGFscGhhPTAuNSkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygib3JhbmdlMiIsICJncmV5NDAiKSkgKwogICAgc3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zID0gbGlzdChjKCJBSSBwZWFrIiwgIm5vIEFJIikpLCBsYWJlbC55PTUpICsKICAgIGdlb21fdGV4dChkYXRhPVN1bW1hcnlfZGF0YSAsYWVzKHggPSBzaWduaWYsIHkgPSAtMC42LCBsYWJlbD1uKSxjb2xvcj0iZ3JleTI1IiwgZm9udGZhY2UgPSAyLCBzaXplID0gMy41KSArCiAgICB5bGltKC0xLDYpICsKICAgIHhsYWIoIkFJIFBlYWtzIHZzIG5vbiBBSSBwZWFrcyIpICsKICAgIHlsYWIoIlBoeWxvUCBhdmVyYWdlIHNjb3JlIG9uIHBlYWsiKSArCiAgICB0aGVtZV9idygpICsgCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJncmV5ODAiLCBsaW5ld2lkdGggPSAxKSwgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA5KSkgKwogICAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOSksIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT05KSkgKwogICAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTkpKSArCiAgICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMjUpLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuNSkpIAojICAgICBmYWNldF93cmFwKH5jb25kKSsKCnByaW50KHApCmdnc2F2ZShmaWxlLnBhdGgob3V0ZGlyX2ZpZ19zdXBwbCwgIkZpZ1MzR19waHlsb1BfY29uc2VydmF0aW9uX3NpZ25fcGVha3MucGRmIiksIHAsIHdpZHRoID0gNiwgaGVpZ2h0ID0gNikKYGBgCgoKCgoKCg==