Prepare analysis workflow

Set filepaths and parameters

set.seed(42)
knitr::opts_knit$set(root.dir = rprojroot::find_rstudio_root_file())
options(
  readr.show_progress = FALSE,
  digits = 2
)

Load packages

suppressPackageStartupMessages({
  library(scater)
  library(scran)
  library(tidyverse)
  library(DESeq2)
  library(EnhancedVolcano)
  library(BiocParallel)
  library(zinbwave)
  theme_set(theme_bw())
})

Define file paths

data_dir <- "./data"
figures_dir <- file.path("./figures")
get_counts_stats <- function(sce10x_stem, cluster_to_remove) {
  gene_counts_by_cluster <-
    t(assay(sce10x_stem)) %>%
    as.matrix() %>%
    as_tibble() %>%
    group_by(cluster = colData(sce10x_stem)$clusters_condition) %>%
    summarise_all(list(~ mean(.)))

  umi_counts_max_1 <-
    gene_counts_by_cluster[c(2, 4, 5), -1] %>%
    summarize_all(list(~ max(.))) %>%
    mutate(dummy = "dummy") %>%
    pivot_longer(-dummy, names_to = "gene_name", values_to = "max_yng") %>%
    select(-dummy)

  umi_counts_max_2 <-
    gene_counts_by_cluster[-5, -1] %>%
    summarize_all(list(~ max(.))) %>%
    mutate(dummy = "dummy") %>%
    pivot_longer(-dummy, names_to = "gene_name", values_to = "max_stem12") %>%
    select(-dummy, -gene_name)



  stats <-
    perFeatureQCMetrics(sce10x_stem,
      exprs_values = c("counts"),
      flatten = TRUE
    ) %>%
    as_tibble() %>%
    bind_cols(., rowData(sce10x_stem) %>%
      as_tibble()) %>%
    bind_cols(., umi_counts_max_1, umi_counts_max_2)

  return(stats)
}

get_lfc <- function(contrast, name, dds) {
  lfcShrink(dds,
    contrast = contrast,
    type = "ashr",
    svalue = T
  ) %>%
    as_tibble() %>%
    dplyr::select(-baseMean) %>%
    mutate(svalue = abs(svalue)) %>%
    set_names(paste(c("lfc", "lfc_se", "svalue"), name, sep = "_"))
}

plot_expression <- function(gene) {
  plotExpression(sce10x_stem,
    features = gene,
    x = "sample",
    exprs_values = "logcounts",
    colour_by = "condition",
    point_size = 1
  ) +
    facet_wrap(~ colData(sce10x_stem)$clusters, ncol = 1)
}
plot_volcano <- function(var_name, lfc_thresh, svalue_thresh, lfc) {
  EnhancedVolcano(lfc,
    lab = lfc %>% pull(gene_id),
    x = paste0("lfc_", var_name),
    xlim = c(-4, 4),
    y = paste0("svalue_", var_name),
    xlab = bquote(~ italic(Moderated) ~ Log[2] ~ FC),
    ylab = bquote(~ -Log[10] ~ italic(svalue)),
    col = c("grey30", "forestgreen", "red2", "royalblue"),
    pCutoff = svalue_thresh,
    FCcutoff = lfc_thresh,
    legendLabels = c(
      "NS",
      expression(Log[2] ~ FC),
      "s-value",
      expression(s - value ~ and ~ log[2] ~ FC)
    )
  )
}

Load data

sce10x <-
  readRDS(file.path(
    data_dir,
    "preprocessed",
    "sce10x_filtered_final.rds"
  ))
sce10x_stem <- sce10x[, colData(sce10x)$celltype == "stem"]
rm(sce10x)
table(colData(sce10x_stem)$clusters, colData(sce10x_stem)$sample)
        
         yng1 yng2 yng3 aged1 aged2 aged3 aged4
  stem_1  397  661  541   370   404   185   435
  stem_2  549 1030  379   151   278   141   304
  stem_3  253  222  129     0     0     0     0

Discard low counts genes

n_exprs_genes <-
  nexprs(sce10x_stem,
    detection_limit = 5,
    byrow = TRUE
  )
keep <- n_exprs_genes >= 10
table(keep)
keep
FALSE  TRUE 
30184  3290 
sce10x_stem <- sce10x_stem[keep, ]
batch_genes_remove <- c("Gm12918", "Rps23-ps1", "Diaph3", "Top2a", "Ecrg4", "Rpl9-ps6")
map(batch_genes_remove, plot_expression)
[[1]]

[[2]]

[[3]]

[[4]]

[[5]]

[[6]]

sce10x_stem <- sce10x_stem[!(rowData(sce10x_stem)$external_gene_name %in% batch_genes_remove), ]

Discard low cluster mean expression genes

stats <- get_counts_stats(sce10x_stem)
stats
max_thresh <- .3
stats <-
  stats %>%
  mutate(
    highexpr_yng = max_yng > max_thresh,
    highexpr_stem12 = max_stem12 > max_thresh,
    genes_stem3 = highexpr_yng & !highexpr_stem12,
    genes_stem12 = !highexpr_yng & highexpr_stem12,
    genes_neither = !highexpr_yng & !highexpr_stem12,
    genes_both = highexpr_yng & highexpr_stem12
  )
stats %>%
  count(highexpr_yng, highexpr_stem12)
ggplot(stats) +
  geom_histogram(aes(max_yng), bins = 100) +
  scale_x_log10() +
  facet_wrap(~top_hvg_stem) +
  geom_vline(xintercept = max_thresh)

genes_to_plot <-
  stats %>%
  filter(genes_stem3) %>%
  pull(gene_name) %>%
  sort()
genes_to_plot
 [1] "Adam12"  "Atp2a3"  "Bcl2l11" "Ccnb2"   "Cd24a"   "Cdh20"   "Cdkn1c"  "Cenpa"   "Cenpp"   "Ckap2"   "Cks2"    "Ctnna2"  "Dlk1"    "Dpp6"   
[15] "Efna5"   "Ehd4"    "Epb41"   "Fgd4"    "Gm28653" "Gm49397" "H1f10"   "H1f2"    "Hmox1"   "Igfbp3"  "Il1rap"  "Jpx"     "Khdrbs3" "L3mbtl4"
[29] "Lmnb1"   "Lmnb2"   "Lockd"   "Lrrn1"   "Mcm3"    "Mcm5"    "Mcm6"    "Mcm7"    "Mitf"    "Mthfd1l" "Myog"    "Nes"     "Nr2f2"   "Oca2"   
[43] "Ophn1"   "Pak3"    "Pclaf"   "Pola1"   "Prune2"  "Rrm2"    "Sdk1"    "Slc12a2" "Smc2"    "Stmn1"   "Whrn"    "Ypel2"  
map(genes_to_plot[1:5], plot_expression)
[[1]]

[[2]]

[[3]]

[[4]]

[[5]]

genes_to_plot <-
  stats %>%
  filter(genes_stem12) %>%
  pull(gene_name) %>%
  sort()
genes_to_plot
 [1] "0610043K17Rik"         "AL954352.1"            "Atxn1"                 "Cadps2"                "Ccl11"                 "Ccn2"                 
 [7] "Cdh4"                  "Col8a1"                "Cped1"                 "Cyp26a1"               "Dab2"                  "ENSMUSG00000031842.14"
[13] "Eya2"                  "Frmpd4"                "Gm10288"               "Gm26834"               "Gm29216"               "Gm6225"               
[19] "Gm7536"                "Grid2"                 "Iigp1"                 "Macrod2"               "Matn4"                 "Mbd1"                 
[25] "Mkx"                   "Myo1d"                 "Nap1l5"                "Nr4a2"                 "P2ry14"                "Pak1"                 
[31] "Parp14"                "Pid1"                  "Rnf180"                "Rnf213"                "Samhd1"                "Sgip1"                
[37] "Slpi"                  "Spock3"                "Thsd7a"                "Tshr"                 
map(genes_to_plot[1:5], plot_expression)
[[1]]

[[2]]

[[3]]

[[4]]

[[5]]

genes_keep <-
  stats %>%
  filter(!genes_neither) %>%
  pull(gene_name)
length(genes_keep)
[1] 3196
sce10x_stem <- sce10x_stem[genes_keep, ]
ggplot(
  stats,
  aes(
    mean,
    detected
  )
) +
  scale_x_log10() +
  geom_point(size = 0.3, aes(color = top_hvg_stem)) +
  geom_text(aes(
    label = gene_name
  ),
  check_overlap = TRUE, nudge_y = -0.1, size = 2.5
  )

Create Design Matrix

design_stem <-
  model.matrix(~ -1 + clusters_condition + sample,
    data = colData(sce10x_stem)
  )[, -c(8)]
colnames(design_stem) <- str_replace(colnames(design_stem), "clusters_condition|sample", "")
# colnames(design_stem) <- str_replace(colnames(design_stem), ":condition", "")

design_stem[1:3, ]
                    stem_1_aged stem_1_yng stem_2_aged stem_2_yng stem_3_yng yng2 yng3 aged2 aged3 aged4
CTACAGAGTGGCCCAT_d1           1          0           0          0          0    0    0     0     0     0
CTAACCCCACACCTGG_d1           1          0           0          0          0    0    0     0     0     0
AGGAGGTCACAGGATG_d1           1          0           0          0          0    0    0     0     0     0

Compute Observational Weights

assay(sce10x_stem, "counts") <- round(assay(sce10x_stem, "counts"))
system.time({
  zinb <-
    zinbFit(sce10x_stem,
      K = 0,
      X = design_stem,
      verbose = TRUE,
      BPPARAM = MulticoreParam(3),
      epsilon = 1e12
    )
})
Create model:
ok
Initialize parameters:
ok
Optimize parameters:
Iteration 1
penalized log-likelihood = -39143625.26738
After dispersion optimization = -71576744.1786462
   user  system elapsed 
  203.0     2.7   105.7 
After right optimization = -71574036.0998483
After orthogonalization = -71574036.0998483
   user  system elapsed 
  122.9     1.5    76.8 
After left optimization = -64813825.7211657
After orthogonalization = -64813825.7211657
Iteration 2
penalized log-likelihood = -64813825.7211657
After dispersion optimization = -64813825.7667293
   user  system elapsed 
  277.5     3.2   141.0 
After right optimization = -64813722.3999213
After orthogonalization = -64813722.3999213
   user  system elapsed 
   27.5     1.3    15.2 
After left optimization = -64813722.2901419
After orthogonalization = -64813722.2901419
Iteration 3
penalized log-likelihood = -64813722.2901419
ok
   user  system elapsed 
   1412      62     669 
weights <- computeObservationalWeights(zinb, as.matrix(assay(sce10x_stem)))
dimnames(weights) <- dimnames(sce10x_stem)
assay(sce10x_stem, "weights") <- weights

convert to SCE to DESeqDataSet object

dds_stem <-
  convertTo(sce10x_stem, type = c("DESeq2"))
converting counts to integer mode
design(dds_stem) <- design_stem
assay(dds_stem, "weights") <- assay(sce10x_stem, "weights")
dds_stem <- estimateSizeFactors(dds_stem, type = "poscounts")
dds_stem <-
  DESeq(dds_stem,
    test = "LRT",
    useT = TRUE,
    reduced = design_stem[, 1:5],
    minmu = 1e-6,
    parallel = TRUE,
    BPPARAM = MulticoreParam(3),
    minRep = Inf
  )
using supplied model matrix
using pre-existing size factors
estimating dispersions
gene-wise dispersion estimates: 3 workers
mean-dispersion relationship
final dispersion estimates, fitting model and testing: 3 workers
plotDispEsts(dds_stem)

resultsNames(dds_stem)
 [1] "stem_1_aged" "stem_1_yng"  "stem_2_aged" "stem_2_yng"  "stem_3_yng"  "yng2"        "yng3"        "aged2"       "aged3"       "aged4"      

Plot batch effects

batch_dt <-
  rowData(dds_stem) %>%
  as_tibble(rownames = "gene_id") %>%
  select("gene_id", "yng2":"aged4")
ggplot(
  batch_dt,
  aes(
    x = yng2,
    y = yng3
  )
) +
  geom_point(
    size = .2,
    alpha = 0.3
  ) +
  geom_text(aes(
    label = gene_id
  ),
  check_overlap = TRUE, nudge_y = -0.15, size = 3
  )

ggplot(
  batch_dt,
  aes(
    x = aged2,
    y = aged3
  )
) +
  geom_point(
    size = .2,
    alpha = 0.3
  ) +
  geom_text(aes(
    label = gene_id
  ),
  check_overlap = TRUE, nudge_y = -0.15, size = 3
  )

ggplot(
  batch_dt,
  aes(
    x = aged2,
    y = aged4
  )
) +
  geom_point(
    size = .2,
    alpha = 0.3
  ) +
  geom_text(aes(
    label = gene_id
  ),
  check_overlap = TRUE, nudge_y = -0.15, size = 3
  )

batch_genes <- c(
  "Cyp26a1", "Cenpa", "Dgkg", "Sorbs2",
  "Gm28653", "Pclaf", "Myog", "Prune2"
)
map(batch_genes, plot_expression)
[[1]]

[[2]]

[[3]]

[[4]]

[[5]]

[[6]]

[[7]]

[[8]]

Test contrasts

c1 <- c(1, -1, 1, -1, 0, 0, 0, 0, 0, 0) / 2
c2 <- c(-1, -1, 1, 1, 0, 0, 0, 0, 0, 0) / 2
c3 <- c(1, -1, 0, 0, 0, 0, 0, 0, 0, 0)
c4 <- c(0, 0, 1, -1, 0, 0, 0, 0, 0, 0)
c5 <- c(-1, 0, 1, 0, 0, 0, 0, 0, 0, 0)
c6 <- c(0, -1, 0, 1, 0, 0, 0, 0, 0, 0)
c7 <- c(0, -1 / 2, 0, -1 / 2, 1, 0, 0, 0, 0, 0)
c8 <- c(0, -1, 0, 0, 1, 0, 0, 0, 0, 0)
c9 <- c(0, 0, 0, -1, 1, 0, 0, 0, 0, 0)


aged_yng_contrast_vec <- list(
  stem_aging = c1,
  stem2_1 = c2,
  stem1_aging = c3,
  stem2_aging = c4,
  stem2_1a = c5,
  stem2_1y = c6
)

stem3_contrast_vec <- list(
  stem3_12y = c7,
  stem3_1y = c8,
  stem3_2y = c9
)
genes_stem3_contrasts <-
  stats %>%
  filter(genes_stem3 | genes_both) %>%
  pull(gene_name)

genes_aged_yng_contrasts <-
  stats %>%
  filter(genes_stem12 | genes_both) %>%
  pull(gene_name)
lfc_stem3 <-
  imap_dfc(stem3_contrast_vec,
    get_lfc,
    dds = dds_stem[genes_stem3_contrasts, ]
  ) %>%
  bind_cols(
    gene_id = rownames(dds_stem[genes_stem3_contrasts, ]),
    .
  )
using 'ashr' for LFC shrinkage. If used in published research, please cite:
    Stephens, M. (2016) False discovery rates: a new deal. Biostatistics, 18:2.
    https://doi.org/10.1093/biostatistics/kxw041
using 'ashr' for LFC shrinkage. If used in published research, please cite:
    Stephens, M. (2016) False discovery rates: a new deal. Biostatistics, 18:2.
    https://doi.org/10.1093/biostatistics/kxw041
using 'ashr' for LFC shrinkage. If used in published research, please cite:
    Stephens, M. (2016) False discovery rates: a new deal. Biostatistics, 18:2.
    https://doi.org/10.1093/biostatistics/kxw041
lfc_aged_yng <-
  imap_dfc(aged_yng_contrast_vec,
    get_lfc,
    dds = dds_stem[genes_aged_yng_contrasts, ]
  ) %>%
  bind_cols(
    gene_id = rownames(dds_stem[genes_aged_yng_contrasts, ]),
    .
  )
using 'ashr' for LFC shrinkage. If used in published research, please cite:
    Stephens, M. (2016) False discovery rates: a new deal. Biostatistics, 18:2.
    https://doi.org/10.1093/biostatistics/kxw041
using 'ashr' for LFC shrinkage. If used in published research, please cite:
    Stephens, M. (2016) False discovery rates: a new deal. Biostatistics, 18:2.
    https://doi.org/10.1093/biostatistics/kxw041
using 'ashr' for LFC shrinkage. If used in published research, please cite:
    Stephens, M. (2016) False discovery rates: a new deal. Biostatistics, 18:2.
    https://doi.org/10.1093/biostatistics/kxw041
using 'ashr' for LFC shrinkage. If used in published research, please cite:
    Stephens, M. (2016) False discovery rates: a new deal. Biostatistics, 18:2.
    https://doi.org/10.1093/biostatistics/kxw041
using 'ashr' for LFC shrinkage. If used in published research, please cite:
    Stephens, M. (2016) False discovery rates: a new deal. Biostatistics, 18:2.
    https://doi.org/10.1093/biostatistics/kxw041
using 'ashr' for LFC shrinkage. If used in published research, please cite:
    Stephens, M. (2016) False discovery rates: a new deal. Biostatistics, 18:2.
    https://doi.org/10.1093/biostatistics/kxw041
lfc <- full_join(lfc_aged_yng, lfc_stem3, by = "gene_id")
lfc <-
  left_join(lfc,
    rowData(dds_stem) %>%
      as_tibble(rownames = "gene_id"),
    by = "gene_id"
  )
lfc

Make volcano plots

lfc_thresh <- 1
Warning messages:
1: In readChar(file, size, TRUE) : truncating string with embedded nuls
2: In readChar(file, size, TRUE) : truncating string with embedded nuls
3: In readChar(file, size, TRUE) : truncating string with embedded nuls
4: In readChar(file, size, TRUE) : truncating string with embedded nuls
5: In readChar(file, size, TRUE) : truncating string with embedded nuls
svalue_thresh <- 10e-8
volcano_plots <-
  map(names(c(aged_yng_contrast_vec, stem3_contrast_vec)),
    plot_volcano,
    lfc_thresh = lfc_thresh,
    svalue_thresh = svalue_thresh,
    lfc = lfc
  )
One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...
volcano_plots
[[1]]

[[2]]

[[3]]

[[4]]

[[5]]

[[6]]

[[7]]

[[8]]

[[9]]

ggsave(file.path(figures_dir, "volcano_stem_aging_effect.pdf"), volcano_plots[[1]])
Saving 7 x 7 in image
ggsave(file.path(figures_dir, "volcano_stem_cluster2vs1.pdf"), volcano_plots[[2]])
ggsave(file.path(figures_dir, "volcano_stem_cluster3vs1_2.pdf"), volcano_plots[[7]])

Make scatterplots

aging_high_de <- c("Dgkg", "Sorbs2")
map(aging_high_de, plot_expression)
[[1]]

[[2]]

p1 <-
  ggplot(
    lfc %>% filter(!(gene_id %in% aging_high_de)),
    aes(
      x = lfc_stem_aging,
      y = lfc_stem2_1,
      color = lfc_stem3_12y
    )
  ) +
  geom_point(
    size = .8,
    alpha = 0.8
  ) +
  geom_text(aes(
    label = gene_id
  ),
  check_overlap = TRUE, nudge_y = -0.15, size = 3
  ) +
  scale_color_gradient2(
    midpoint = 0,
    low = "yellow",
    mid = "black",
    high = "blue"
  ) +
  theme_classic() +
  xlim(c(-6, 3))
p1

ggsave(file.path(figures_dir, "scatterplot_stem_aging_vs_cluster_effect.pdf"), p1)
Saving 7 x 7 in image
p2 <-
  ggplot(
    lfc,
    aes(
      x = lfc_stem2_1,
      y = lfc_stem3_12y,
      color = lfc_stem_aging
    )
  ) +
  geom_point(
    size = .8,
    alpha = 0.8
  ) +
  geom_text(aes(
    label = gene_id
  ),
  check_overlap = TRUE, nudge_y = -0.15, size = 3
  ) +
  scale_color_gradient2(
    midpoint = 0,
    limits = c(-3, 2),
    low = "yellow",
    mid = "black",
    high = "blue"
  ) +
  ylim(c(-2.2, 1.8)) +
  theme_classic()
p2

ggsave(file.path(figures_dir, "scatterplot_stem3_vs_stem21_cluster_effect.pdf"), p2)
Saving 7 x 7 in image
p3 <-
  ggplot(
    lfc %>% filter(!(gene_id %in% aging_high_de)),
    aes(
      x = lfc_stem1_aging,
      y = lfc_stem2_aging
    )
  ) +
  geom_point(
    size = .8,
    alpha = 0.8
  ) +
  geom_text(aes(
    label = gene_id
  ),
  check_overlap = TRUE, nudge_y = -0.15, size = 4
  ) +
  theme_classic()
p3

ggsave(file.path(figures_dir, "scatterplot_stem_1vs2_aging_effect.pdf"), p3)
Saving 7 x 7 in image

Save data

write_tsv(
  lfc,
  file.path(
    data_dir,
    "preprocessed",
    "stem_scrnaseq_moderated_lfc.txt"
  )
)
rowData(sce10x_stem) <-
  left_join(rowData(sce10x_stem) %>%
    as_tibble(rownames = "gene_id") %>%
    select(gene_id), lfc, by = "gene_id") %>%
  DataFrame(.)

rownames(rowData(sce10x_stem)) <- rowData(sce10x_stem)$gene_id
saveRDS(
  sce10x_stem,
  file.path(
    data_dir,
    "preprocessed",
    "sce10x_stem_filtered_final.rds"
  )
)
sessionInfo()
R version 4.0.2 (2020-06-22)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.04.5 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.7.1

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8   
 [6] LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] parallel  stats4    stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] zinbwave_1.10.0             BiocParallel_1.22.0         EnhancedVolcano_1.6.0       ggrepel_0.8.2               DESeq2_1.28.1              
 [6] forcats_0.5.0               stringr_1.4.0               dplyr_1.0.2                 purrr_0.3.4                 readr_1.3.1                
[11] tidyr_1.1.2                 tibble_3.0.3                tidyverse_1.3.0             scran_1.16.0                scater_1.16.2              
[16] ggplot2_3.3.2               SingleCellExperiment_1.10.1 SummarizedExperiment_1.18.2 DelayedArray_0.14.1         matrixStats_0.56.0         
[21] Biobase_2.48.0              GenomicRanges_1.40.0        GenomeInfoDb_1.24.2         IRanges_2.22.2              S4Vectors_0.26.1           
[26] BiocGenerics_0.34.0        

loaded via a namespace (and not attached):
 [1] ggbeeswarm_0.6.0          colorspace_1.4-1          ellipsis_0.3.1            rprojroot_1.3-2           XVector_0.28.0           
 [6] BiocNeighbors_1.6.0       fs_1.5.0                  rstudioapi_0.11           farver_2.0.3              bit64_4.0.5              
[11] AnnotationDbi_1.50.3      fansi_0.4.1               lubridate_1.7.9           xml2_1.3.2                splines_4.0.2            
[16] geneplotter_1.66.0        knitr_1.29                jsonlite_1.7.1            packrat_0.5.0             broom_0.7.0              
[21] annotate_1.66.0           ashr_2.2-47               dbplyr_1.4.4              compiler_4.0.2            httr_1.4.2               
[26] dqrng_0.2.1               backports_1.1.9           assertthat_0.2.1          Matrix_1.2-18             limma_3.44.3             
[31] cli_2.0.2                 BiocSingular_1.4.0        tools_4.0.2               rsvd_1.0.3                igraph_1.2.5             
[36] gtable_0.3.0              glue_1.4.2                GenomeInfoDbData_1.2.3    Rcpp_1.0.5                softImpute_1.4           
[41] cellranger_1.1.0          vctrs_0.3.4               DelayedMatrixStats_1.10.1 xfun_0.17                 rvest_0.3.6              
[46] lifecycle_0.2.0           irlba_2.3.3               statmod_1.4.34            XML_3.99-0.5              edgeR_3.30.3             
[51] zlibbioc_1.34.0           scales_1.1.1              hms_0.5.3                 RColorBrewer_1.1-2        memoise_1.1.0            
[56] gridExtra_2.3             SQUAREM_2020.4            stringi_1.5.3             RSQLite_2.2.0             genefilter_1.70.0        
[61] truncnorm_1.0-8           rlang_0.4.7               pkgconfig_2.0.3           bitops_1.0-6              invgamma_1.1             
[66] lattice_0.20-41           labeling_0.3              cowplot_1.1.0             bit_4.0.4                 tidyselect_1.1.0         
[71] magrittr_1.5              R6_2.4.1                  generics_0.0.2            DBI_1.1.0                 pillar_1.4.6             
[76] haven_2.3.1               withr_2.2.0               mixsqp_0.3-43             survival_3.1-12           RCurl_1.98-1.2           
[81] modelr_0.1.8              crayon_1.3.4              viridis_0.5.1             locfit_1.5-9.4            grid_4.0.2               
[86] readxl_1.3.1              blob_1.2.1                reprex_0.3.0              digest_0.6.25             xtable_1.8-4             
[91] munsell_0.5.0             beeswarm_0.2.3            viridisLite_0.3.0         vipor_0.4.5              
LS0tCnRpdGxlOiAiTW91c2UgTXVzY2xlIFN0ZW0gQ2VsbCBQcm9qZWN0ICIKc3VidGl0bGU6ICJQYXJ0IDVhOiBydW4gZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYW5hbHlzaXMgb24gc3RlbSBjZWxscyIKYXV0aG9yOiAKLSBuYW1lOiBSaWNrIEZhcm91bmkKICBhZmZpbGlhdGlvbjoKICAtICZjcnVrIEfDqW5vbWUgUXXDqWJlYyBJbm5vdmF0aW9uIENlbnRyZSwgTWNHaWxsIFVuaXZlcnNpdHksIE1vbnRyZWFsLCBDYW5hZGEKZGF0ZTogJ2ByIGZvcm1hdChTeXMuRGF0ZSgpLCAiJVktJUItJWQiKWAnCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIHRvYzogbm8KICAgIHRvY19mbG9hdDogCiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKLS0tCgoKIyBQcmVwYXJlIGFuYWx5c2lzIHdvcmtmbG93CgojIyBTZXQgZmlsZXBhdGhzIGFuZCBwYXJhbWV0ZXJzCgpgYGB7ciBzZXR1cH0Kc2V0LnNlZWQoNDIpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gcnByb2pyb290OjpmaW5kX3JzdHVkaW9fcm9vdF9maWxlKCkpCm9wdGlvbnMoCiAgcmVhZHIuc2hvd19wcm9ncmVzcyA9IEZBTFNFLAogIGRpZ2l0cyA9IDIKKQpgYGAKCiMjIExvYWQgcGFja2FnZXMKYGBge3J9CnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyh7CiAgbGlicmFyeShzY2F0ZXIpCiAgbGlicmFyeShzY3JhbikKICBsaWJyYXJ5KHRpZHl2ZXJzZSkKICBsaWJyYXJ5KERFU2VxMikKICBsaWJyYXJ5KEVuaGFuY2VkVm9sY2FubykKICBsaWJyYXJ5KEJpb2NQYXJhbGxlbCkKICBsaWJyYXJ5KHppbmJ3YXZlKQogIHRoZW1lX3NldCh0aGVtZV9idygpKQp9KQpgYGAKCiMjIERlZmluZSBmaWxlIHBhdGhzCgpgYGB7cn0KZGF0YV9kaXIgPC0gIi4vZGF0YSIKZmlndXJlc19kaXIgPC0gZmlsZS5wYXRoKCIuL2ZpZ3VyZXMiKQpgYGAKCmBgYHtyfQpnZXRfY291bnRzX3N0YXRzIDwtIGZ1bmN0aW9uKHNjZTEweF9zdGVtLCBjbHVzdGVyX3RvX3JlbW92ZSkgewogIGdlbmVfY291bnRzX2J5X2NsdXN0ZXIgPC0KICAgIHQoYXNzYXkoc2NlMTB4X3N0ZW0pKSAlPiUKICAgIGFzLm1hdHJpeCgpICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBncm91cF9ieShjbHVzdGVyID0gY29sRGF0YShzY2UxMHhfc3RlbSkkY2x1c3RlcnNfY29uZGl0aW9uKSAlPiUKICAgIHN1bW1hcmlzZV9hbGwobGlzdCh+IG1lYW4oLikpKQoKICB1bWlfY291bnRzX21heF8xIDwtCiAgICBnZW5lX2NvdW50c19ieV9jbHVzdGVyW2MoMiwgNCwgNSksIC0xXSAlPiUKICAgIHN1bW1hcml6ZV9hbGwobGlzdCh+IG1heCguKSkpICU+JQogICAgbXV0YXRlKGR1bW15ID0gImR1bW15IikgJT4lCiAgICBwaXZvdF9sb25nZXIoLWR1bW15LCBuYW1lc190byA9ICJnZW5lX25hbWUiLCB2YWx1ZXNfdG8gPSAibWF4X3luZyIpICU+JQogICAgc2VsZWN0KC1kdW1teSkKCiAgdW1pX2NvdW50c19tYXhfMiA8LQogICAgZ2VuZV9jb3VudHNfYnlfY2x1c3RlclstNSwgLTFdICU+JQogICAgc3VtbWFyaXplX2FsbChsaXN0KH4gbWF4KC4pKSkgJT4lCiAgICBtdXRhdGUoZHVtbXkgPSAiZHVtbXkiKSAlPiUKICAgIHBpdm90X2xvbmdlcigtZHVtbXksIG5hbWVzX3RvID0gImdlbmVfbmFtZSIsIHZhbHVlc190byA9ICJtYXhfc3RlbTEyIikgJT4lCiAgICBzZWxlY3QoLWR1bW15LCAtZ2VuZV9uYW1lKQoKCgogIHN0YXRzIDwtCiAgICBwZXJGZWF0dXJlUUNNZXRyaWNzKHNjZTEweF9zdGVtLAogICAgICBleHByc192YWx1ZXMgPSBjKCJjb3VudHMiKSwKICAgICAgZmxhdHRlbiA9IFRSVUUKICAgICkgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIGJpbmRfY29scyguLCByb3dEYXRhKHNjZTEweF9zdGVtKSAlPiUKICAgICAgYXNfdGliYmxlKCkpICU+JQogICAgYmluZF9jb2xzKC4sIHVtaV9jb3VudHNfbWF4XzEsIHVtaV9jb3VudHNfbWF4XzIpCgogIHJldHVybihzdGF0cykKfQoKZ2V0X2xmYyA8LSBmdW5jdGlvbihjb250cmFzdCwgbmFtZSwgZGRzKSB7CiAgbGZjU2hyaW5rKGRkcywKICAgIGNvbnRyYXN0ID0gY29udHJhc3QsCiAgICB0eXBlID0gImFzaHIiLAogICAgc3ZhbHVlID0gVAogICkgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIGRwbHlyOjpzZWxlY3QoLWJhc2VNZWFuKSAlPiUKICAgIG11dGF0ZShzdmFsdWUgPSBhYnMoc3ZhbHVlKSkgJT4lCiAgICBzZXRfbmFtZXMocGFzdGUoYygibGZjIiwgImxmY19zZSIsICJzdmFsdWUiKSwgbmFtZSwgc2VwID0gIl8iKSkKfQoKcGxvdF9leHByZXNzaW9uIDwtIGZ1bmN0aW9uKGdlbmUpIHsKICBwbG90RXhwcmVzc2lvbihzY2UxMHhfc3RlbSwKICAgIGZlYXR1cmVzID0gZ2VuZSwKICAgIHggPSAic2FtcGxlIiwKICAgIGV4cHJzX3ZhbHVlcyA9ICJsb2djb3VudHMiLAogICAgY29sb3VyX2J5ID0gImNvbmRpdGlvbiIsCiAgICBwb2ludF9zaXplID0gMQogICkgKwogICAgZmFjZXRfd3JhcCh+IGNvbERhdGEoc2NlMTB4X3N0ZW0pJGNsdXN0ZXJzLCBuY29sID0gMSkKfQpwbG90X3ZvbGNhbm8gPC0gZnVuY3Rpb24odmFyX25hbWUsIGxmY190aHJlc2gsIHN2YWx1ZV90aHJlc2gsIGxmYykgewogIEVuaGFuY2VkVm9sY2FubyhsZmMsCiAgICBsYWIgPSBsZmMgJT4lIHB1bGwoZ2VuZV9pZCksCiAgICB4ID0gcGFzdGUwKCJsZmNfIiwgdmFyX25hbWUpLAogICAgeGxpbSA9IGMoLTQsIDQpLAogICAgeSA9IHBhc3RlMCgic3ZhbHVlXyIsIHZhcl9uYW1lKSwKICAgIHhsYWIgPSBicXVvdGUofiBpdGFsaWMoTW9kZXJhdGVkKSB+IExvZ1syXSB+IEZDKSwKICAgIHlsYWIgPSBicXVvdGUofiAtTG9nWzEwXSB+IGl0YWxpYyhzdmFsdWUpKSwKICAgIGNvbCA9IGMoImdyZXkzMCIsICJmb3Jlc3RncmVlbiIsICJyZWQyIiwgInJveWFsYmx1ZSIpLAogICAgcEN1dG9mZiA9IHN2YWx1ZV90aHJlc2gsCiAgICBGQ2N1dG9mZiA9IGxmY190aHJlc2gsCiAgICBsZWdlbmRMYWJlbHMgPSBjKAogICAgICAiTlMiLAogICAgICBleHByZXNzaW9uKExvZ1syXSB+IEZDKSwKICAgICAgInMtdmFsdWUiLAogICAgICBleHByZXNzaW9uKHMgLSB2YWx1ZSB+IGFuZCB+IGxvZ1syXSB+IEZDKQogICAgKQogICkKfQpgYGAKCgoKIyMgTG9hZCBkYXRhCgoKYGBge3J9CnNjZTEweCA8LQogIHJlYWRSRFMoZmlsZS5wYXRoKAogICAgZGF0YV9kaXIsCiAgICAicHJlcHJvY2Vzc2VkIiwKICAgICJzY2UxMHhfZmlsdGVyZWRfZmluYWwucmRzIgogICkpCmBgYAoKCmBgYHtyfQpzY2UxMHhfc3RlbSA8LSBzY2UxMHhbLCBjb2xEYXRhKHNjZTEweCkkY2VsbHR5cGUgPT0gInN0ZW0iXQpybShzY2UxMHgpCmBgYAoKYGBge3J9CnRhYmxlKGNvbERhdGEoc2NlMTB4X3N0ZW0pJGNsdXN0ZXJzLCBjb2xEYXRhKHNjZTEweF9zdGVtKSRzYW1wbGUpCmBgYAoKCgojIyBEaXNjYXJkIGxvdyBjb3VudHMgZ2VuZXMKCmBgYHtyfQpuX2V4cHJzX2dlbmVzIDwtCiAgbmV4cHJzKHNjZTEweF9zdGVtLAogICAgZGV0ZWN0aW9uX2xpbWl0ID0gNSwKICAgIGJ5cm93ID0gVFJVRQogICkKa2VlcCA8LSBuX2V4cHJzX2dlbmVzID49IDEwCnRhYmxlKGtlZXApCmBgYAoKYGBge3J9CnNjZTEweF9zdGVtIDwtIHNjZTEweF9zdGVtW2tlZXAsIF0KYGBgCgpgYGB7cn0KYmF0Y2hfZ2VuZXNfcmVtb3ZlIDwtIGMoIkdtMTI5MTgiLCAiUnBzMjMtcHMxIiwgIkRpYXBoMyIsICJUb3AyYSIsICJFY3JnNCIsICJScGw5LXBzNiIpCmBgYAoKYGBge3J9Cm1hcChiYXRjaF9nZW5lc19yZW1vdmUsIHBsb3RfZXhwcmVzc2lvbikKYGBgCgpgYGB7cn0Kc2NlMTB4X3N0ZW0gPC0gc2NlMTB4X3N0ZW1bIShyb3dEYXRhKHNjZTEweF9zdGVtKSRleHRlcm5hbF9nZW5lX25hbWUgJWluJSBiYXRjaF9nZW5lc19yZW1vdmUpLCBdCmBgYAoKCiMjICBEaXNjYXJkIGxvdyBjbHVzdGVyIG1lYW4gZXhwcmVzc2lvbiBnZW5lcwoKYGBge3J9CnN0YXRzIDwtIGdldF9jb3VudHNfc3RhdHMoc2NlMTB4X3N0ZW0pCnN0YXRzCmBgYAoKCmBgYHtyfQptYXhfdGhyZXNoIDwtIC4zCnN0YXRzIDwtCiAgc3RhdHMgJT4lCiAgbXV0YXRlKAogICAgaGlnaGV4cHJfeW5nID0gbWF4X3luZyA+IG1heF90aHJlc2gsCiAgICBoaWdoZXhwcl9zdGVtMTIgPSBtYXhfc3RlbTEyID4gbWF4X3RocmVzaCwKICAgIGdlbmVzX3N0ZW0zID0gaGlnaGV4cHJfeW5nICYgIWhpZ2hleHByX3N0ZW0xMiwKICAgIGdlbmVzX3N0ZW0xMiA9ICFoaWdoZXhwcl95bmcgJiBoaWdoZXhwcl9zdGVtMTIsCiAgICBnZW5lc19uZWl0aGVyID0gIWhpZ2hleHByX3luZyAmICFoaWdoZXhwcl9zdGVtMTIsCiAgICBnZW5lc19ib3RoID0gaGlnaGV4cHJfeW5nICYgaGlnaGV4cHJfc3RlbTEyCiAgKQpgYGAKCgoKCmBgYHtyfQpzdGF0cyAlPiUKICBjb3VudChoaWdoZXhwcl95bmcsIGhpZ2hleHByX3N0ZW0xMikKYGBgCgoKCgpgYGB7ciBmaWcud2lkdGg9N30KZ2dwbG90KHN0YXRzKSArCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKG1heF95bmcpLCBiaW5zID0gMTAwKSArCiAgc2NhbGVfeF9sb2cxMCgpICsKICBmYWNldF93cmFwKH50b3BfaHZnX3N0ZW0pICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBtYXhfdGhyZXNoKQpgYGAKCgoKYGBge3J9CmdlbmVzX3RvX3Bsb3QgPC0KICBzdGF0cyAlPiUKICBmaWx0ZXIoZ2VuZXNfc3RlbTMpICU+JQogIHB1bGwoZ2VuZV9uYW1lKSAlPiUKICBzb3J0KCkKZ2VuZXNfdG9fcGxvdApgYGAKCmBgYHtyfQptYXAoZ2VuZXNfdG9fcGxvdFsxOjVdLCBwbG90X2V4cHJlc3Npb24pCmBgYAoKYGBge3J9CmdlbmVzX3RvX3Bsb3QgPC0KICBzdGF0cyAlPiUKICBmaWx0ZXIoZ2VuZXNfc3RlbTEyKSAlPiUKICBwdWxsKGdlbmVfbmFtZSkgJT4lCiAgc29ydCgpCmdlbmVzX3RvX3Bsb3QKYGBgCgpgYGB7cn0KbWFwKGdlbmVzX3RvX3Bsb3RbMTo1XSwgcGxvdF9leHByZXNzaW9uKQpgYGAKCgoKCmBgYHtyfQpnZW5lc19rZWVwIDwtCiAgc3RhdHMgJT4lCiAgZmlsdGVyKCFnZW5lc19uZWl0aGVyKSAlPiUKICBwdWxsKGdlbmVfbmFtZSkKbGVuZ3RoKGdlbmVzX2tlZXApCmBgYAoKYGBge3J9CnNjZTEweF9zdGVtIDwtIHNjZTEweF9zdGVtW2dlbmVzX2tlZXAsIF0KYGBgCgpgYGB7ciBmaWcud2lkdGg9MTJ9CmdncGxvdCgKICBzdGF0cywKICBhZXMoCiAgICBtZWFuLAogICAgZGV0ZWN0ZWQKICApCikgKwogIHNjYWxlX3hfbG9nMTAoKSArCiAgZ2VvbV9wb2ludChzaXplID0gMC4zLCBhZXMoY29sb3IgPSB0b3BfaHZnX3N0ZW0pKSArCiAgZ2VvbV90ZXh0KGFlcygKICAgIGxhYmVsID0gZ2VuZV9uYW1lCiAgKSwKICBjaGVja19vdmVybGFwID0gVFJVRSwgbnVkZ2VfeSA9IC0wLjEsIHNpemUgPSAyLjUKICApCmBgYAojIyBDcmVhdGUgRGVzaWduIE1hdHJpeAoKYGBge3J9CmRlc2lnbl9zdGVtIDwtCiAgbW9kZWwubWF0cml4KH4gLTEgKyBjbHVzdGVyc19jb25kaXRpb24gKyBzYW1wbGUsCiAgICBkYXRhID0gY29sRGF0YShzY2UxMHhfc3RlbSkKICApWywgLWMoOCldCmNvbG5hbWVzKGRlc2lnbl9zdGVtKSA8LSBzdHJfcmVwbGFjZShjb2xuYW1lcyhkZXNpZ25fc3RlbSksICJjbHVzdGVyc19jb25kaXRpb258c2FtcGxlIiwgIiIpCiMgY29sbmFtZXMoZGVzaWduX3N0ZW0pIDwtIHN0cl9yZXBsYWNlKGNvbG5hbWVzKGRlc2lnbl9zdGVtKSwgIjpjb25kaXRpb24iLCAiIikKCmRlc2lnbl9zdGVtWzE6MywgXQpgYGAKIyMgQ29tcHV0ZSBPYnNlcnZhdGlvbmFsIFdlaWdodHMKCmBgYHtyfQphc3NheShzY2UxMHhfc3RlbSwgImNvdW50cyIpIDwtIHJvdW5kKGFzc2F5KHNjZTEweF9zdGVtLCAiY291bnRzIikpCmBgYAoKYGBge3J9CnN5c3RlbS50aW1lKHsKICB6aW5iIDwtCiAgICB6aW5iRml0KHNjZTEweF9zdGVtLAogICAgICBLID0gMCwKICAgICAgWCA9IGRlc2lnbl9zdGVtLAogICAgICB2ZXJib3NlID0gVFJVRSwKICAgICAgQlBQQVJBTSA9IE11bHRpY29yZVBhcmFtKDMpLAogICAgICBlcHNpbG9uID0gMWUxMgogICAgKQp9KQpgYGAKCgpgYGB7cn0Kd2VpZ2h0cyA8LSBjb21wdXRlT2JzZXJ2YXRpb25hbFdlaWdodHMoemluYiwgYXMubWF0cml4KGFzc2F5KHNjZTEweF9zdGVtKSkpCmRpbW5hbWVzKHdlaWdodHMpIDwtIGRpbW5hbWVzKHNjZTEweF9zdGVtKQphc3NheShzY2UxMHhfc3RlbSwgIndlaWdodHMiKSA8LSB3ZWlnaHRzCmBgYAoKIyMgY29udmVydCB0byBTQ0UgdG8gREVTZXFEYXRhU2V0IG9iamVjdAoKYGBge3J9CmRkc19zdGVtIDwtCiAgY29udmVydFRvKHNjZTEweF9zdGVtLCB0eXBlID0gYygiREVTZXEyIikpCmRlc2lnbihkZHNfc3RlbSkgPC0gZGVzaWduX3N0ZW0KYXNzYXkoZGRzX3N0ZW0sICJ3ZWlnaHRzIikgPC0gYXNzYXkoc2NlMTB4X3N0ZW0sICJ3ZWlnaHRzIikKYGBgCgoKCmBgYHtyfQpkZHNfc3RlbSA8LSBlc3RpbWF0ZVNpemVGYWN0b3JzKGRkc19zdGVtLCB0eXBlID0gInBvc2NvdW50cyIpCmRkc19zdGVtIDwtCiAgREVTZXEoZGRzX3N0ZW0sCiAgICB0ZXN0ID0gIkxSVCIsCiAgICB1c2VUID0gVFJVRSwKICAgIHJlZHVjZWQgPSBkZXNpZ25fc3RlbVssIDE6NV0sCiAgICBtaW5tdSA9IDFlLTYsCiAgICBwYXJhbGxlbCA9IFRSVUUsCiAgICBCUFBBUkFNID0gTXVsdGljb3JlUGFyYW0oMyksCiAgICBtaW5SZXAgPSBJbmYKICApCmBgYAoKYGBge3J9CnBsb3REaXNwRXN0cyhkZHNfc3RlbSkKYGBgCmBgYHtyfQpyZXN1bHRzTmFtZXMoZGRzX3N0ZW0pCmBgYAoKCiMjIyBQbG90IGJhdGNoIGVmZmVjdHMKCmBgYHtyfQpiYXRjaF9kdCA8LQogIHJvd0RhdGEoZGRzX3N0ZW0pICU+JQogIGFzX3RpYmJsZShyb3duYW1lcyA9ICJnZW5lX2lkIikgJT4lCiAgc2VsZWN0KCJnZW5lX2lkIiwgInluZzIiOiJhZ2VkNCIpCmBgYAoKCmBgYHtyIGZpZy53aWR0aD0xMn0KZ2dwbG90KAogIGJhdGNoX2R0LAogIGFlcygKICAgIHggPSB5bmcyLAogICAgeSA9IHluZzMKICApCikgKwogIGdlb21fcG9pbnQoCiAgICBzaXplID0gLjIsCiAgICBhbHBoYSA9IDAuMwogICkgKwogIGdlb21fdGV4dChhZXMoCiAgICBsYWJlbCA9IGdlbmVfaWQKICApLAogIGNoZWNrX292ZXJsYXAgPSBUUlVFLCBudWRnZV95ID0gLTAuMTUsIHNpemUgPSAzCiAgKQpgYGAKCgoKCmBgYHtyIGZpZy53aWR0aD0xMn0KZ2dwbG90KAogIGJhdGNoX2R0LAogIGFlcygKICAgIHggPSBhZ2VkMiwKICAgIHkgPSBhZ2VkMwogICkKKSArCiAgZ2VvbV9wb2ludCgKICAgIHNpemUgPSAuMiwKICAgIGFscGhhID0gMC4zCiAgKSArCiAgZ2VvbV90ZXh0KGFlcygKICAgIGxhYmVsID0gZ2VuZV9pZAogICksCiAgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIG51ZGdlX3kgPSAtMC4xNSwgc2l6ZSA9IDMKICApCmBgYAoKCmBgYHtyIGZpZy53aWR0aD0xMn0KZ2dwbG90KAogIGJhdGNoX2R0LAogIGFlcygKICAgIHggPSBhZ2VkMiwKICAgIHkgPSBhZ2VkNAogICkKKSArCiAgZ2VvbV9wb2ludCgKICAgIHNpemUgPSAuMiwKICAgIGFscGhhID0gMC4zCiAgKSArCiAgZ2VvbV90ZXh0KGFlcygKICAgIGxhYmVsID0gZ2VuZV9pZAogICksCiAgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIG51ZGdlX3kgPSAtMC4xNSwgc2l6ZSA9IDMKICApCmBgYAoKCgpgYGB7cn0KYmF0Y2hfZ2VuZXMgPC0gYygKICAiQ3lwMjZhMSIsICJDZW5wYSIsICJEZ2tnIiwgIlNvcmJzMiIsCiAgIkdtMjg2NTMiLCAiUGNsYWYiLCAiTXlvZyIsICJQcnVuZTIiCikKbWFwKGJhdGNoX2dlbmVzLCBwbG90X2V4cHJlc3Npb24pCmBgYAoKIyMgVGVzdCBjb250cmFzdHMgCgpgYGB7cn0KYzEgPC0gYygxLCAtMSwgMSwgLTEsIDAsIDAsIDAsIDAsIDAsIDApIC8gMgpjMiA8LSBjKC0xLCAtMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCkgLyAyCmMzIDwtIGMoMSwgLTEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDApCmM0IDwtIGMoMCwgMCwgMSwgLTEsIDAsIDAsIDAsIDAsIDAsIDApCmM1IDwtIGMoLTEsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDApCmM2IDwtIGMoMCwgLTEsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDApCmM3IDwtIGMoMCwgLTEgLyAyLCAwLCAtMSAvIDIsIDEsIDAsIDAsIDAsIDAsIDApCmM4IDwtIGMoMCwgLTEsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDApCmM5IDwtIGMoMCwgMCwgMCwgLTEsIDEsIDAsIDAsIDAsIDAsIDApCgoKYWdlZF95bmdfY29udHJhc3RfdmVjIDwtIGxpc3QoCiAgc3RlbV9hZ2luZyA9IGMxLAogIHN0ZW0yXzEgPSBjMiwKICBzdGVtMV9hZ2luZyA9IGMzLAogIHN0ZW0yX2FnaW5nID0gYzQsCiAgc3RlbTJfMWEgPSBjNSwKICBzdGVtMl8xeSA9IGM2CikKCnN0ZW0zX2NvbnRyYXN0X3ZlYyA8LSBsaXN0KAogIHN0ZW0zXzEyeSA9IGM3LAogIHN0ZW0zXzF5ID0gYzgsCiAgc3RlbTNfMnkgPSBjOQopCmBgYAoKYGBge3J9CmdlbmVzX3N0ZW0zX2NvbnRyYXN0cyA8LQogIHN0YXRzICU+JQogIGZpbHRlcihnZW5lc19zdGVtMyB8IGdlbmVzX2JvdGgpICU+JQogIHB1bGwoZ2VuZV9uYW1lKQoKZ2VuZXNfYWdlZF95bmdfY29udHJhc3RzIDwtCiAgc3RhdHMgJT4lCiAgZmlsdGVyKGdlbmVzX3N0ZW0xMiB8IGdlbmVzX2JvdGgpICU+JQogIHB1bGwoZ2VuZV9uYW1lKQpgYGAKCgpgYGB7cn0KbGZjX3N0ZW0zIDwtCiAgaW1hcF9kZmMoc3RlbTNfY29udHJhc3RfdmVjLAogICAgZ2V0X2xmYywKICAgIGRkcyA9IGRkc19zdGVtW2dlbmVzX3N0ZW0zX2NvbnRyYXN0cywgXQogICkgJT4lCiAgYmluZF9jb2xzKAogICAgZ2VuZV9pZCA9IHJvd25hbWVzKGRkc19zdGVtW2dlbmVzX3N0ZW0zX2NvbnRyYXN0cywgXSksCiAgICAuCiAgKQpgYGAKCmBgYHtyfQpsZmNfYWdlZF95bmcgPC0KICBpbWFwX2RmYyhhZ2VkX3luZ19jb250cmFzdF92ZWMsCiAgICBnZXRfbGZjLAogICAgZGRzID0gZGRzX3N0ZW1bZ2VuZXNfYWdlZF95bmdfY29udHJhc3RzLCBdCiAgKSAlPiUKICBiaW5kX2NvbHMoCiAgICBnZW5lX2lkID0gcm93bmFtZXMoZGRzX3N0ZW1bZ2VuZXNfYWdlZF95bmdfY29udHJhc3RzLCBdKSwKICAgIC4KICApCmBgYAoKYGBge3J9CmxmYyA8LSBmdWxsX2pvaW4obGZjX2FnZWRfeW5nLCBsZmNfc3RlbTMsIGJ5ID0gImdlbmVfaWQiKQpgYGAKCmBgYHtyfQpsZmMgPC0KICBsZWZ0X2pvaW4obGZjLAogICAgcm93RGF0YShkZHNfc3RlbSkgJT4lCiAgICAgIGFzX3RpYmJsZShyb3duYW1lcyA9ICJnZW5lX2lkIiksCiAgICBieSA9ICJnZW5lX2lkIgogICkKYGBgCgpgYGB7cn0KbGZjCmBgYAoKCiMjIyBNYWtlIHZvbGNhbm8gcGxvdHMKCgpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTR9CmxmY190aHJlc2ggPC0gMQpzdmFsdWVfdGhyZXNoIDwtIDEwZS04CnZvbGNhbm9fcGxvdHMgPC0KICBtYXAobmFtZXMoYyhhZ2VkX3luZ19jb250cmFzdF92ZWMsIHN0ZW0zX2NvbnRyYXN0X3ZlYykpLAogICAgcGxvdF92b2xjYW5vLAogICAgbGZjX3RocmVzaCA9IGxmY190aHJlc2gsCiAgICBzdmFsdWVfdGhyZXNoID0gc3ZhbHVlX3RocmVzaCwKICAgIGxmYyA9IGxmYwogICkKdm9sY2Fub19wbG90cwpgYGAKCgpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTR9Cmdnc2F2ZShmaWxlLnBhdGgoZmlndXJlc19kaXIsICJ2b2xjYW5vX3N0ZW1fYWdpbmdfZWZmZWN0LnBkZiIpLCB2b2xjYW5vX3Bsb3RzW1sxXV0pCmdnc2F2ZShmaWxlLnBhdGgoZmlndXJlc19kaXIsICJ2b2xjYW5vX3N0ZW1fY2x1c3RlcjJ2czEucGRmIiksIHZvbGNhbm9fcGxvdHNbWzJdXSkKZ2dzYXZlKGZpbGUucGF0aChmaWd1cmVzX2RpciwgInZvbGNhbm9fc3RlbV9jbHVzdGVyM3ZzMV8yLnBkZiIpLCB2b2xjYW5vX3Bsb3RzW1s3XV0pCmBgYAoKCiMjIE1ha2Ugc2NhdHRlcnBsb3RzCgpgYGB7cn0KYWdpbmdfaGlnaF9kZSA8LSBjKCJEZ2tnIiwgIlNvcmJzMiIpCmBgYAoKCmBgYHtyIGZpZy53aWR0aD0xMn0KbWFwKGFnaW5nX2hpZ2hfZGUsIHBsb3RfZXhwcmVzc2lvbikKYGBgCgoKCmBgYHtyIGZpZy53aWR0aD0xMn0KcDEgPC0KICBnZ3Bsb3QoCiAgICBsZmMgJT4lIGZpbHRlcighKGdlbmVfaWQgJWluJSBhZ2luZ19oaWdoX2RlKSksCiAgICBhZXMoCiAgICAgIHggPSBsZmNfc3RlbV9hZ2luZywKICAgICAgeSA9IGxmY19zdGVtMl8xLAogICAgICBjb2xvciA9IGxmY19zdGVtM18xMnkKICAgICkKICApICsKICBnZW9tX3BvaW50KAogICAgc2l6ZSA9IC44LAogICAgYWxwaGEgPSAwLjgKICApICsKICBnZW9tX3RleHQoYWVzKAogICAgbGFiZWwgPSBnZW5lX2lkCiAgKSwKICBjaGVja19vdmVybGFwID0gVFJVRSwgbnVkZ2VfeSA9IC0wLjE1LCBzaXplID0gMwogICkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50MigKICAgIG1pZHBvaW50ID0gMCwKICAgIGxvdyA9ICJ5ZWxsb3ciLAogICAgbWlkID0gImJsYWNrIiwKICAgIGhpZ2ggPSAiYmx1ZSIKICApICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHhsaW0oYygtNiwgMykpCnAxCmBgYCAKCgpgYGB7cn0KZ2dzYXZlKGZpbGUucGF0aChmaWd1cmVzX2RpciwgInNjYXR0ZXJwbG90X3N0ZW1fYWdpbmdfdnNfY2x1c3Rlcl9lZmZlY3QucGRmIiksIHAxKQpgYGAKCgpgYGB7ciBmaWcud2lkdGg9MTJ9CnAyIDwtCiAgZ2dwbG90KAogICAgbGZjLAogICAgYWVzKAogICAgICB4ID0gbGZjX3N0ZW0yXzEsCiAgICAgIHkgPSBsZmNfc3RlbTNfMTJ5LAogICAgICBjb2xvciA9IGxmY19zdGVtX2FnaW5nCiAgICApCiAgKSArCiAgZ2VvbV9wb2ludCgKICAgIHNpemUgPSAuOCwKICAgIGFscGhhID0gMC44CiAgKSArCiAgZ2VvbV90ZXh0KGFlcygKICAgIGxhYmVsID0gZ2VuZV9pZAogICksCiAgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIG51ZGdlX3kgPSAtMC4xNSwgc2l6ZSA9IDMKICApICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudDIoCiAgICBtaWRwb2ludCA9IDAsCiAgICBsaW1pdHMgPSBjKC0zLCAyKSwKICAgIGxvdyA9ICJ5ZWxsb3ciLAogICAgbWlkID0gImJsYWNrIiwKICAgIGhpZ2ggPSAiYmx1ZSIKICApICsKICB5bGltKGMoLTIuMiwgMS44KSkgKwogIHRoZW1lX2NsYXNzaWMoKQpwMgpgYGAKCmBgYHtyfQpnZ3NhdmUoZmlsZS5wYXRoKGZpZ3VyZXNfZGlyLCAic2NhdHRlcnBsb3Rfc3RlbTNfdnNfc3RlbTIxX2NsdXN0ZXJfZWZmZWN0LnBkZiIpLCBwMikKYGBgCmBgYHtyIGZpZy53aWR0aD0xMn0KcDMgPC0KICBnZ3Bsb3QoCiAgICBsZmMgJT4lIGZpbHRlcighKGdlbmVfaWQgJWluJSBhZ2luZ19oaWdoX2RlKSksCiAgICBhZXMoCiAgICAgIHggPSBsZmNfc3RlbTFfYWdpbmcsCiAgICAgIHkgPSBsZmNfc3RlbTJfYWdpbmcKICAgICkKICApICsKICBnZW9tX3BvaW50KAogICAgc2l6ZSA9IC44LAogICAgYWxwaGEgPSAwLjgKICApICsKICBnZW9tX3RleHQoYWVzKAogICAgbGFiZWwgPSBnZW5lX2lkCiAgKSwKICBjaGVja19vdmVybGFwID0gVFJVRSwgbnVkZ2VfeSA9IC0wLjE1LCBzaXplID0gNAogICkgKwogIHRoZW1lX2NsYXNzaWMoKQpwMwpgYGAKCmBgYHtyfQpnZ3NhdmUoZmlsZS5wYXRoKGZpZ3VyZXNfZGlyLCAic2NhdHRlcnBsb3Rfc3RlbV8xdnMyX2FnaW5nX2VmZmVjdC5wZGYiKSwgcDMpCmBgYAoKCiMjIFNhdmUgZGF0YQoKYGBge3J9CndyaXRlX3RzdigKICBsZmMsCiAgZmlsZS5wYXRoKAogICAgZGF0YV9kaXIsCiAgICAicHJlcHJvY2Vzc2VkIiwKICAgICJzdGVtX3Njcm5hc2VxX21vZGVyYXRlZF9sZmMudHh0IgogICkKKQpgYGAKCgpgYGB7cn0Kcm93RGF0YShzY2UxMHhfc3RlbSkgPC0KICBsZWZ0X2pvaW4ocm93RGF0YShzY2UxMHhfc3RlbSkgJT4lCiAgICBhc190aWJibGUocm93bmFtZXMgPSAiZ2VuZV9pZCIpICU+JQogICAgc2VsZWN0KGdlbmVfaWQpLCBsZmMsIGJ5ID0gImdlbmVfaWQiKSAlPiUKICBEYXRhRnJhbWUoLikKCnJvd25hbWVzKHJvd0RhdGEoc2NlMTB4X3N0ZW0pKSA8LSByb3dEYXRhKHNjZTEweF9zdGVtKSRnZW5lX2lkCmBgYAoKYGBge3J9CnNhdmVSRFMoCiAgc2NlMTB4X3N0ZW0sCiAgZmlsZS5wYXRoKAogICAgZGF0YV9kaXIsCiAgICAicHJlcHJvY2Vzc2VkIiwKICAgICJzY2UxMHhfc3RlbV9maWx0ZXJlZF9maW5hbC5yZHMiCiAgKQopCmBgYAoKCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAo=