1 Main libraries and configuration

library(dplyr)
library(ExperimentHub)
library(GenomicRanges)
library(coMethDMR)

2 Meta-analysis of Genomic Regions

2.1 Paths

dir.result <- "meta_analysis_region_results/"
dir.result.meta.analysis <- file.path(dir.result, "step1_meta_analysis/")
dir.result.smoking_crosshyb <- file.path(dir.result, "step2_smoking_cross_anotation/")
dir.result.comp <- file.path(dir.result, "step3_comp/")
dir.result.cpg.vs.dmr <- file.path(dir.result, "step4_dmr_vs_cpgs/")
dir.result.lola <- file.path(dir.result, "step5_lola/")
dir.result.enrichment <- file.path(dir.result, "step6_enrichment/")
dir.result.pathway <- file.path(dir.result, "step7_pathway/")
data.final <- "meta_analysis_single_cpg_results/"
for(p in grep("dir",ls(),value = T)) dir.create(get(p),recursive = TRUE,showWarnings = FALSE)

2.2 Import datasets and pre-process for each cohort

library(dplyr)
library(tidyr)
preMeta <- function(cohort){
  
  ### Load data
  file <- dir(pattern = paste0(cohort,"_linear_df"),
              path =  "DATASETS/",
              recursive = TRUE,
              full.names = TRUE,
              ignore.case = TRUE)
  message("Reading file: ", file)
  linear.results.final <- readRDS(file)
  
  ### select the most sig cometh region for each input region
  pva.col <- grep("_pVal",colnames(linear.results.final),value = TRUE)
  colnames(linear.results.final)[grep("inputRegion",colnames(linear.results.final))] <- "inputRegion"
  
  # !! is used to unquote an input 
  # https://dplyr.tidyverse.org/articles/programming.html
  result_sig <- linear.results.final %>%
    group_by(inputRegion) %>%
    filter((!!as.symbol(pva.col)) == min(!!as.symbol(pva.col)))
  
  data.frame(result_sig, stringsAsFactors = FALSE)
}

Gasparoni <- preMeta(cohort = "Gasparoni") #dim: 39605  8
London_PFC <- preMeta(cohort = "London") #dim: 40000 8
MtSinai <- preMeta(cohort = "MtSinai") #dim:  38619 8
ROSMAP <- preMeta(cohort = "ROSMAP") #dim: 38562 8

2.3 Merge cohorts

### merge datasets
cohort_ls <- list(
  Gasparoni = Gasparoni,
  London_PFC = London_PFC,
  MtSinai = MtSinai,
  ROSMAP = ROSMAP
)

### outer join input region
multi_cohorts <- Reduce(
  function(x,y, ...) merge(x, y, by = "inputRegion", all = TRUE, ...),
  cohort_ls
)

2.4 Meta analysis

library(meta)

doParallel::registerDoParallel(cores = parallel::detectCores()/2)
meta_df <- plyr::adply(.data = multi_cohorts, 
                       .margins = 1, 
                       .fun =  function(rowOne_df){
                         
                         est <- rowOne_df[grep("estimate",colnames(rowOne_df))] %>% as.numeric
                         
                         direction <-  paste(ifelse(
                           is.na(est), ".",
                           ifelse(est > 0, "+", "-")
                         ),collapse = "")
                         
                         se <- rowOne_df[grep("se",colnames(rowOne_df))] %>% as.numeric
                         cohort <- gsub("_se","",grep("se",colnames(rowOne_df),value = T))
                         rowOne_reform_df <- data.frame(
                           cohort = cohort,
                           est = est,
                           se = se,
                           stringsAsFactors = FALSE
                         )
                         
                         f <- metagen(
                           TE = est,
                           seTE = se,
                           data = rowOne_reform_df
                         )
                         
                         tibble::tibble(
                           inputRegion = rowOne_df$inputRegion,
                           estimate = f$TE.fixed,
                           se = f$seTE.fixed,
                           pVal.fixed = f$pval.fixed,
                           pVal.random = f$pval.random,
                           pValQ = f$pval.Q,
                           direction = direction
                         )
                       }  , .progress = "time",
                       .parallel = TRUE,
                       .id = NULL
)

### create final pVal
meta_df$pVal.final <- ifelse(
  meta_df$pValQ > 0.05, meta_df$pVal.fixed, meta_df$pVal.random
)

### calculate fdr
meta_df$fdr <- p.adjust(meta_df$pVal.final, method = "fdr")

### order meta_df
meta_final_df <- meta_df[, c(grep("_",colnames(meta_df),invert = T),
                             grep("_",colnames(meta_df),invert = F))]
meta_final_ordered_df <- meta_final_df[order(meta_final_df$pVal.final),]

2.5 Add annotation to input regions

### find annotations
library(coMethDMR)

splited_input <- meta_final_ordered_df %>% 
  tidyr::separate(col = inputRegion,into =  c("chrom", "start", "end"),remove = FALSE)
splited_input_annot <- AnnotateResults(splited_input[,c("chrom", "start", "end")],nCores_int = 10) 

### merge annotation with meta analysis data
meta_ordered_withAnnot_df <- cbind(
  meta_final_ordered_df, splited_input_annot[, 4:7]
)

### order columns
meta_ordered_withAnnot_df <- meta_ordered_withAnnot_df %>% 
  dplyr::select(c(1,
                  (ncol(meta_ordered_withAnnot_df) - 3):ncol(meta_ordered_withAnnot_df),
                  2:(ncol(meta_ordered_withAnnot_df) - 4))
  )
### save dataset
write.csv(
  meta_ordered_withAnnot_df,
  paste0(dir.result.meta.analysis, "meta_analysis_ALL_df.csv"),
  row.names = FALSE
)

meta_all_sig <- meta_ordered_withAnnot_df[
  !is.na(meta_ordered_withAnnot_df$fdr) &
    (meta_ordered_withAnnot_df$fdr < 0.05), 
  ] #dim: 478 41
row.names(meta_all_sig) <- NULL

write.csv(
  meta_all_sig,
  paste0(dir.result.meta.analysis, "meta_analysis_ALL_sig_df.csv"),
  row.names = FALSE
)

2.6 Filtering coMethDMRs

2.6.1 Annotate coMethDMRs with crosshybrdizing probes chen et al. (2013) & smoking probes

2.6.1.1 Get crosshybrdizing probes

### call in all cross hybridizing probes
eh = ExperimentHub()
## snapshotDate(): 2020-04-03
query(eh, "DMRcate")
## ExperimentHub with 9 records
## # snapshotDate(): 2020-04-03
## # $dataprovider: Ensembl, Springer, SickKids, Springer, Bioconductor
## # $species: Homo sapiens, Mus musculus
## # $rdataclass: GeneRegionTrack, GRanges, character, data.frame
## # additional mcols(): taxonomyid, genome, description,
## #   coordinate_1_based, maintainer, rdatadateadded, preparerclass, tags,
## #   rdatapath, sourceurl, sourcetype 
## # retrieve records with, e.g., 'object[["EH3129"]]' 
## 
##            title          
##   EH3129 | crosshyb       
##   EH3130 | snpsall        
##   EH3131 | XY.probes      
##   EH3132 | hg19.generanges
##   EH3133 | hg19.grt       
##   EH3134 | hg38.generanges
##   EH3135 | hg38.grt       
##   EH3136 | mm10.generanges
##   EH3137 | mm10.grt
crosshyb <- eh[["EH3129"]]
## see ?DMRcatedata and browseVignettes('DMRcatedata') for documentation
## loading from cache

2.6.1.2 Get significant smoking probes

smoking.file <- "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5267325/bin/NIHMS817273-supplement-001506_-_Supplemental_Tables.xlsx"

if(!file.exists(basename(smoking.file))) downloader::download(smoking.file,basename(smoking.file))

smoking <- readxl::read_xlsx(
  basename(smoking.file),
  sheet = "02",
  skip = 2
)
smoking.sig.probes <- smoking %>% dplyr::filter(`P-value` < 1*10^(-7)) %>% pull("Probe ID") 
length(smoking.sig.probes)
## [1] 2623

2.6.1.3 Load significant coMethDMRs identified in meta-analaysis

# Call in meta analysis final results
meta_all <- readr::read_csv(
  dir(dir.result.meta.analysis, pattern = "meta_analysis_ALL_sig_df.csv",full.names = TRUE),
  col_types = readr::cols()
)

# Find files with regions and probes
files <- dir(pattern = paste0(".*_residuals_cometh_input_ls.rds"),
             recursive = T,
             full.names = TRUE,
             ignore.case = T)
files <- grep("GASPARONI|LONDON_PFC|MtSinai|ROSMAP",files,value = TRUE,ignore.case = TRUE)

# Read files and Limit the cohort_ls to cohort_coMethRegion in meta_all 
cometh.probes.list <- lapply(files, function (f){
  print(f)
  all.clusters <- readRDS(f)$coMeth_ls # Read files
  cohort <- f %>% dirname %>% dirname %>% basename # get cohort from folder name
  
  col <- grep(paste0(cohort,"_coMethRegion"),
              colnames(meta_all),
              ignore.case = TRUE,
              value = TRUE) # get column with cohort sig regions
  
  # keep sig regions only
  all.clusters[names(all.clusters) %in% meta_all[[col]]]
})
## [1] "./DATASETS/GASPARONI/step10_residuals/Gasparoni_residuals_cometh_input_ls.RDS"
## [1] "./DATASETS/LONDON/step10_residuals/London_PFC_residuals_cometh_input_ls.RDS"
## [1] "./DATASETS/MtSinai/step10_residuals/MtSinai_residuals_cometh_input_ls.RDS"
## [1] "./DATASETS/ROSMAP/step10_residuals/ROSMAP_residuals_cometh_input_ls.RDS"
names(cometh.probes.list) <-  files %>% dirname %>% dirname %>% basename

lapply(cometh.probes.list,length)
## $GASPARONI
## [1] 476
## 
## $LONDON
## [1] 478
## 
## $MtSinai
## [1] 469
## 
## $ROSMAP
## [1] 474

2.6.1.4 Map probes in each region to smoking and crosshybrdizing

extractCrosHybridization <- function(probes.list){
  crosshyb.extracted <- plyr::laply(probes.list,function(probes){
    paste(intersect(probes, crosshyb), 
          collapse = ", "
    )
  })
  smoking.extracted <- plyr::laply(probes.list,function(probes){
    paste(intersect(probes, smoking.sig.probes), 
          collapse = ", "
    )
  })
  tibble::tibble(
    "coMethRegion" = names(probes.list),
    "crossHyb" = crosshyb.extracted, 
    "crossHyb_bi" = ifelse(crosshyb.extracted == "",0,1),
    "smoke" = smoking.extracted,
    "smoke_bi" = ifelse(smoking.extracted == "",0,1)
  )
}

Gasparoni_crossHyb_df <- extractCrosHybridization(cometh.probes.list$GASPARONI)
colnames(Gasparoni_crossHyb_df) <- paste0("GASPARONI_",colnames(Gasparoni_crossHyb_df))
plyr::count(Gasparoni_crossHyb_df, vars = grep("_bi",colnames(Gasparoni_crossHyb_df),value = TRUE))
London_PFC_crossHyb_df <- extractCrosHybridization(cometh.probes.list$LONDON)
colnames(London_PFC_crossHyb_df) <- paste0("London_",colnames(London_PFC_crossHyb_df))
plyr::count(London_PFC_crossHyb_df, vars = grep("_bi",colnames(London_PFC_crossHyb_df),value = TRUE))
MtSinai_crossHyb_df <- extractCrosHybridization(cometh.probes.list$MtSinai)
colnames(MtSinai_crossHyb_df) <- paste0("MtSinai_",colnames(MtSinai_crossHyb_df))
plyr::count(MtSinai_crossHyb_df, vars = grep("_bi",colnames(MtSinai_crossHyb_df),value = TRUE))
ROSMAP_crossHyb_df <- extractCrosHybridization(cometh.probes.list$ROSMAP)
colnames(ROSMAP_crossHyb_df) <- paste0("ROSMAP_",colnames(ROSMAP_crossHyb_df))
plyr::count(ROSMAP_crossHyb_df, vars = grep("_bi",colnames(ROSMAP_crossHyb_df),value = TRUE))

2.6.1.5 Merge smoking and crossHyb probes information with meta analysis results

meta_all_final <- meta_all %>% left_join(Gasparoni_crossHyb_df)  %>% 
  left_join(London_PFC_crossHyb_df) %>% 
  left_join(MtSinai_crossHyb_df) %>% 
  left_join(ROSMAP_crossHyb_df)
## Joining, by = "GASPARONI_coMethRegion"
## Joining, by = "London_coMethRegion"
## Joining, by = "MtSinai_coMethRegion"
## Joining, by = "ROSMAP_coMethRegion"
### Add information with input regions with any cross hybridization in cohorts 
meta_all_final$crossHyb_bi <- rowSums(meta_all_final[,grep("crossHyb_bi",colnames(meta_all_final))],na.rm = TRUE) > 0
meta_all_final$smoke_bi <- rowSums(meta_all_final[,grep("smoke_bi",colnames(meta_all_final))],na.rm = TRUE) > 0

# Sort by region meta analysis FDR
# Cluster columns of the projects together
meta_all_final <- meta_all_final[
  order(meta_all_final$fdr),
  c(
    grep("Gasparoni|MtSinai|London|ROSMAP",colnames(meta_all_final),ignore.case = TRUE,invert = TRUE),
    grep("Gasparoni",colnames(meta_all_final),ignore.case = TRUE),
    grep("MtSinai",colnames(meta_all_final),ignore.case = TRUE),
    grep("London",colnames(meta_all_final),ignore.case = TRUE),
    grep("ROSMAP",colnames(meta_all_final),ignore.case = TRUE)
  )
  ]
str(meta_all_final)
## tibble [478 × 59] (S3: tbl_df/tbl/data.frame)
##  $ inputRegion            : chr [1:478] "chr19:49220102-49220485" "chr7:27153580-27153944" "chr7:27146237-27146445" "chr7:27154262-27155548" ...
##  $ UCSC_RefGene_Group     : chr [1:478] "1stExon;5'UTR;Body;TSS1500;TSS200" "1stExon;5'UTR;TSS1500;TSS200" "3'UTR" "5'UTR;TSS1500" ...
##  $ UCSC_RefGene_Accession : chr [1:478] "NM_001130915;NM_182574" "NM_030661;NM_153631;NM_153632" "NM_030661;NM_153631;NM_153632" "NM_030661;NM_153631;NM_153632" ...
##  $ UCSC_RefGene_Name      : chr [1:478] "MAMSTR" "HOXA3" "HOXA3" "HOXA3" ...
##  $ Relation_to_Island     : chr [1:478] "N_Shelf" "Island;N_Shore" "Island" "Island;N_Shore;S_Shore" ...
##  $ estimate               : num [1:478] 0.0607 0.0838 0.0659 0.0472 0.0449 ...
##  $ se                     : num [1:478] 0.00751 0.01085 0.00862 0.00619 0.00634 ...
##  $ pVal.fixed             : num [1:478] 6.02e-16 1.16e-14 2.23e-14 2.37e-14 1.35e-12 ...
##  $ pVal.random            : num [1:478] 4.24e-14 1.45e-11 3.03e-11 4.09e-10 1.35e-12 ...
##  $ pValQ                  : num [1:478] 0.341 0.286 0.291 0.237 0.741 ...
##  $ direction              : chr [1:478] "++++" "++++" "++++" "++++" ...
##  $ pVal.final             : num [1:478] 6.02e-16 1.16e-14 2.23e-14 2.37e-14 1.35e-12 ...
##  $ fdr                    : num [1:478] 2.41e-11 2.32e-10 2.37e-10 2.37e-10 1.08e-08 ...
##  $ crossHyb_bi            : logi [1:478] FALSE FALSE FALSE FALSE FALSE FALSE ...
##  $ smoke_bi               : logi [1:478] FALSE FALSE FALSE FALSE FALSE FALSE ...
##  $ GASPARONI_nCoMethRegion: num [1:478] 1 1 1 1 1 0 1 1 1 1 ...
##  $ GASPARONI_coMethRegion : chr [1:478] "chr19:49220102-49220235" "chr7:27153580-27153847" "chr7:27146237-27146445" "chr7:27154387-27155548" ...
##  $ GASPARONI_nCpGs        : num [1:478] 4 6 4 14 4 3 4 5 3 8 ...
##  $ Gasparoni_estimate     : num [1:478] 0.0409 0.0664 0.0559 0.0261 0.0487 ...
##  $ Gasparoni_se           : num [1:478] 0.0264 0.0336 0.0345 0.0189 0.0218 ...
##  $ Gasparoni_pVal         : num [1:478] 0.1289 0.054 0.1121 0.1723 0.0306 ...
##  $ Gasparoni_fdr          : num [1:478] 0.996 0.996 0.996 0.996 0.996 ...
##  $ GASPARONI_crossHyb     : chr [1:478] "" "" "" "" ...
##  $ GASPARONI_crossHyb_bi  : num [1:478] 0 0 0 0 0 0 0 0 0 0 ...
##  $ GASPARONI_smoke        : chr [1:478] "" "" "" "" ...
##  $ GASPARONI_smoke_bi     : num [1:478] 0 0 0 0 0 0 0 0 1 0 ...
##  $ MtSinai_nCoMethRegion  : num [1:478] 1 1 1 1 1 0 1 1 1 1 ...
##  $ MtSinai_coMethRegion   : chr [1:478] "chr19:49220102-49220235" "chr7:27153580-27153847" "chr7:27146237-27146445" "chr7:27154720-27155548" ...
##  $ MtSinai_nCpGs          : num [1:478] 4 6 4 10 4 3 4 5 3 7 ...
##  $ MtSinai_estimate       : num [1:478] 0.0846 0.118 0.1051 0.0662 0.0604 ...
##  $ MtSinai_se             : num [1:478] 0.0167 0.027 0.0225 0.0131 0.0158 ...
##  $ MtSinai_pVal           : num [1:478] 1.45e-06 2.57e-05 7.49e-06 1.45e-06 2.08e-04 ...
##  $ MtSinai_fdr            : num [1:478] 0.0188 0.0499 0.0322 0.0188 0.1232 ...
##  $ MtSinai_crossHyb       : chr [1:478] "" "" "" "" ...
##  $ MtSinai_crossHyb_bi    : num [1:478] 0 0 0 0 0 0 0 0 0 0 ...
##  $ MtSinai_smoke          : chr [1:478] "" "" "" "" ...
##  $ MtSinai_smoke_bi       : num [1:478] 0 0 0 0 0 0 0 0 1 0 ...
##  $ London_nCoMethRegion   : num [1:478] 1 1 1 2 1 1 1 1 1 1 ...
##  $ London_coMethRegion    : chr [1:478] "chr19:49220102-49220235" "chr7:27153580-27153847" "chr7:27146237-27146445" "chr7:27154262-27154387" ...
##  $ London_nCpGs           : num [1:478] 4 6 4 4 4 3 3 5 3 7 ...
##  $ London_estimate        : num [1:478] 0.0497 0.099 0.0632 0.0526 0.0415 ...
##  $ London_se              : num [1:478] 0.01287 0.01991 0.0137 0.01241 0.00945 ...
##  $ London_pVal            : num [1:478] 2.07e-04 3.10e-06 1.31e-05 5.41e-05 3.05e-05 ...
##  $ London_fdr             : num [1:478] 0.0958 0.0297 0.0439 0.0631 0.0474 ...
##  $ London_crossHyb        : chr [1:478] "" "" "" "" ...
##  $ London_crossHyb_bi     : num [1:478] 0 0 0 0 0 0 0 0 0 0 ...
##  $ London_smoke           : chr [1:478] "" "" "" "" ...
##  $ London_smoke_bi        : num [1:478] 0 0 0 0 0 0 0 0 1 0 ...
##  $ ROSMAP_nCoMethRegion   : num [1:478] 1 1 1 1 1 0 1 1 1 1 ...
##  $ ROSMAP_coMethRegion    : chr [1:478] "chr19:49220102-49220235" "chr7:27153580-27153847" "chr7:27146237-27146445" "chr7:27154720-27155548" ...
##  $ ROSMAP_nCpGs           : num [1:478] 4 6 4 10 3 3 3 5 3 7 ...
##  $ ROSMAP_estimate        : num [1:478] 0.0622 0.0649 0.0555 0.0393 0.0408 ...
##  $ ROSMAP_se              : num [1:478] 0.01224 0.01641 0.01374 0.00955 0.01147 ...
##  $ ROSMAP_pVal            : num [1:478] 4.94e-07 8.51e-05 6.00e-05 4.39e-05 4.03e-04 ...
##  $ ROSMAP_fdr             : num [1:478] 0.00955 0.12481 0.10655 0.10456 0.23625 ...
##  $ ROSMAP_crossHyb        : chr [1:478] "" "" "" "" ...
##  $ ROSMAP_crossHyb_bi     : num [1:478] 0 0 0 0 0 0 0 0 0 0 ...
##  $ ROSMAP_smoke           : chr [1:478] "" "" "" "" ...
##  $ ROSMAP_smoke_bi        : num [1:478] 0 0 0 0 0 0 0 0 1 0 ...

2.6.1.6 Save

write.csv(
  meta_all_final,
  paste0(dir.result.smoking_crosshyb, "meta_analysis_ALL_sig_add_crossHyb_df.csv"),
  row.names = FALSE
)

meta_all_final %>% 
  dplyr::filter(smoke_bi == 0 & crossHyb_bi == 0)  %>% 
  DT::datatable(filter = 'top',
                style = "bootstrap",
                extensions = 'Buttons',
                options = list(scrollX = TRUE, 
                               dom = 'Bfrtip',
                               buttons = I('colvis'),
                               keys = TRUE, 
                               pageLength = 10), 
                rownames = FALSE,
                caption = "meta-analysis results")

2.6.2 Overlap with comb-p DMRs

2.6.2.1 Import datasets

library(GenomicRanges)
linear_sig <- readr::read_csv(
  dir(dir.result.smoking_crosshyb, pattern = "meta_analysis_ALL_sig_add_crossHyb_df.csv",full.names = TRUE),
  col_types = readr::cols()
)
linear_sig_input_gr <- linear_sig %>% 
  tidyr::separate("inputRegion",c("chrom","start","end")) %>%
  makeGRangesFromDataFrame()
linear_sig_input_gr
## GRanges object with 478 ranges and 0 metadata columns:
##         seqnames              ranges strand
##            <Rle>           <IRanges>  <Rle>
##     [1]    chr19   49220102-49220485      *
##     [2]     chr7   27153580-27153944      *
##     [3]     chr7   27146237-27146445      *
##     [4]     chr7   27154262-27155548      *
##     [5]     chr7   27179161-27179432      *
##     ...      ...                 ...    ...
##   [474]    chr16   87886871-87886933      *
##   [475]    chr13 113422497-113422671      *
##   [476]    chr12 121476549-121476792      *
##   [477]    chr19       836606-836898      *
##   [478]     chr1   22978556-22978660      *
##   -------
##   seqinfo: 22 sequences from an unspecified genome; no seqlengths
combp <- readxl::read_xlsx("../../Michael/1_7_2020_001-200/1_7_2020_001-200/combp_results.xlsx") # get comb-p results
colnames(combp)[1] <- "chrom"
combp$chrom <- paste0("chr",combp$chrom)
combp_sig <- combp %>% filter(z_sidak_p < 0.05 & n_probes > 2)

combp_sig %>% 
  DT::datatable(filter = 'top',
                style = "bootstrap",
                extensions = 'Buttons',
                options = list(scrollX = TRUE, 
                               dom = 'Bfrtip',
                               buttons = I('colvis'),
                               keys = TRUE, 
                               pageLength = 10), 
                rownames = FALSE,
                caption = "comb-p results")
combp_sig_gr <- makeGRangesFromDataFrame(combp_sig)
combp_sig_gr
## GRanges object with 187 ranges and 0 metadata columns:
##         seqnames              ranges strand
##            <Rle>           <IRanges>  <Rle>
##     [1]     chr7   27153580-27153848      *
##     [2]    chr19   10736006-10736356      *
##     [3]     chr7   27146237-27146446      *
##     [4]     chr7   27170313-27171402      *
##     [5]    chr19   49220102-49220236      *
##     ...      ...                 ...    ...
##   [183]     chr6 149806077-149806132      *
##   [184]     chr6 152702330-152702388      *
##   [185]    chr19   46999224-46999290      *
##   [186]     chr4   24797140-24797177      *
##   [187]     chr6   28984234-28984270      *
##   -------
##   seqinfo: 22 sequences from an unspecified genome; no seqlengths

2.6.2.2 Save overlapping results

overlapping.results <- linear_sig[
  queryHits(findOverlaps(linear_sig_input_gr,combp_sig_gr)),
  ] # nrow: 146

overlapping.combp <- combp_sig[
  subjectHits(findOverlaps(linear_sig_input_gr,combp_sig_gr)),
  ]
colnames(overlapping.combp) <- paste0("combp_", colnames(overlapping.combp))

overlapping.results <- cbind(
  overlapping.results, overlapping.combp
)

overlapping.results.unique <- overlapping.results %>%
  group_by(inputRegion) %>%
  filter(combp_z_sidak_p == min(combp_z_sidak_p))


write.csv(
  overlapping.results.unique,
  paste0(dir.result.comp, "meta_analysis_ov_comb_p.csv"),
  row.names = FALSE
)


write.csv(
  overlapping.results.unique %>% dplyr::filter(smoke_bi == 0 & crossHyb_bi == 0),
  paste0(dir.result.comp, "meta_analysis_no_crossHyb_smoking_ov_comb_p.csv"),
  row.names = FALSE
)


linear_sig_input_no_crossHyb_smoking_gr <- linear_sig %>% 
  dplyr::filter(smoke_bi == 0 & crossHyb_bi == 0) %>% 
  tidyr::separate("inputRegion",c("chrom","start","end")) %>%
  makeGRangesFromDataFrame()
linear_sig_input_no_crossHyb_smoking_gr
## GRanges object with 421 ranges and 0 metadata columns:
##         seqnames              ranges strand
##            <Rle>           <IRanges>  <Rle>
##     [1]    chr19   49220102-49220485      *
##     [2]     chr7   27153580-27153944      *
##     [3]     chr7   27146237-27146445      *
##     [4]     chr7   27154262-27155548      *
##     [5]     chr7   27179161-27179432      *
##     ...      ...                 ...    ...
##   [417]    chr16   87886871-87886933      *
##   [418]    chr13 113422497-113422671      *
##   [419]    chr12 121476549-121476792      *
##   [420]    chr19       836606-836898      *
##   [421]     chr1   22978556-22978660      *
##   -------
##   seqinfo: 22 sequences from an unspecified genome; no seqlengths

2.6.2.3 Create Venn Diagram

library(ChIPpeakAnno)
library(ggplot2)
methods      <- c("linear", "combp")
methodsLabel <- c("coMethDMR linear", "combp")


n <- length(methods)

gg_color_hue <- function(n){
  hues = seq(15, 375, length = n + 1)
  hcl(h = hues, l = 65, c = 100)[1:n]
}

cols = gg_color_hue(n)

ranges.list <- list(linear_sig_input_no_crossHyb_smoking_gr, combp_sig_gr) 

# overlap for 1 repetition
p <- makeVennDiagram(
  ranges.list,
  NameOfPeaks = methodsLabel[1:n],
  totalTest = 37159, 
  by = "region",
  main = paste0(" "),
  col = c("#440154ff", '#21908dff'),
  fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3)),
  cex = 1,
  fontfamily = "sans",
  cat.cex = 1,
  cat.default.pos = "outer",
  cat.pos = c(180, 180),
  cat.dist = c(-0.055, -0.055),
  cat.fontfamily = "sans",
  cat.col = c("#440154ff", '#21908dff'))

print(p)
## $p.value
##      coMethDMR.linear combp          pval
## [1,]                1     1 2.491331e-189
## 
## $vennCounts
##      coMethDMR.linear combp Counts
## [1,]                0     0  36672
## [2,]                0     1     66
## [3,]                1     0    302
## [4,]                1     1    119
## attr(,"class")
## [1] "VennCounts"
pdf(
  file = paste0(dir.result.comp,"venn_coMethDMR_linear_vs_combp.pdf"),
  width = 5, height = 5
) 
makeVennDiagram(
  ranges.list,
  NameOfPeaks = methodsLabel[1:n],
  totalTest = 37159, 
  by = "region",
  main = paste0(" "),
  col = c("#440154ff", '#21908dff'),
  fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3)),
  cex = 1,
  fontfamily = "sans",
  cat.cex = 1,
  cat.default.pos = "outer",
  cat.pos = c(180, 180),
  cat.dist = c(-0.055, -0.055),
  cat.fontfamily = "sans",
  cat.col = c("#440154ff", '#21908dff'))
dev.off()

3 Meta-analysis Single-cpgs

3.1 Import datasets and pre-process for each cohort

library(dplyr)
dir.create(data.final,recursive = TRUE,showWarnings = FALSE)
results.files <- dir("DATASETS/",
                     pattern = "single_cpg_pVal_df.csv",
                     recursive = TRUE,
                     full.names = TRUE,
                     ignore.case = TRUE)

for(i in results.files){
  data <- readr::read_csv(i)
  dataset <- unlist(stringr::str_split(i,"//|/"))[2]  %>% as.character()
  aux <- paste0(dataset,c("_estimate", "_se", "_pValue", "_fdr"))
  colnames(data) <- c("cpg", aux)
  assign(dataset,data)
}

3.2 Create a merged final dataset

cohort_ls <- list(
  Gasparoni = GASPARONI,
  London_PFC = LONDON,
  MtSinai = MtSinai,
  ROSMAP = ROSMAP
)

### outer join input region
multi_cohorts <- Reduce(
  function(x,y, ...) merge(x, y, by = "cpg", all = TRUE, ...),
  cohort_ls
) #dim: 437713 17
dim(multi_cohorts)

3.3 Meta analysis

### calculate meta analysis z scores and p values
library(meta)

doParallel::registerDoParallel(cores = parallel::detectCores()/2)
meta_df <- plyr::adply(.data = multi_cohorts, 
                       .margins = 1, 
                       .fun =  function(rowOne_df){
                         
                         est <- rowOne_df[grep("estimate",colnames(rowOne_df))] %>% as.numeric
                         
                         direction <-  paste(ifelse(
                           is.na(est), ".",
                           ifelse(est > 0, "+", "-")
                         ),collapse = "")
                         
                         se <- rowOne_df[grep("se",colnames(rowOne_df))] %>% as.numeric
                         cohort <- gsub("_se","",grep("se",colnames(rowOne_df),value = T))
                         rowOne_reform_df <- data.frame(
                           cohort = cohort,
                           est = est,
                           se = se,
                           stringsAsFactors = FALSE
                         )
                         
                         f <- metagen(
                           TE = est,
                           seTE = se,
                           data = rowOne_reform_df
                         )
                         
                         tibble::tibble(
                           cpg = rowOne_df$cpg,
                           estimate = f$TE.fixed,
                           se = f$seTE.fixed,
                           pVal.fixed = f$pval.fixed,
                           pVal.random = f$pval.random,
                           pValQ = f$pval.Q,
                           direction = direction
                         )
                       }  , .progress = "time",
                       .parallel = TRUE,
                       .id = NULL
)

### create final pVal
meta_df$pVal.final <- ifelse(
  meta_df$pValQ > 0.05, meta_df$pVal.fixed, meta_df$pVal.random
)

### calculate fdr
meta_df$fdr <- p.adjust(meta_df$pVal.final, method = "fdr")

### order meta_df
meta_final_df <- meta_df[, c(grep("_",colnames(meta_df),invert = T),
                             grep("_",colnames(meta_df),invert = F))]
meta_final_ordered_df <- meta_final_df[order(meta_final_df$pVal.final),]

3.4 Add annotation to input cpgs

library(sesame)
probes.info <- sesameDataGet("HM450.hg19.manifest")
probes.info <- probes.info[meta_final_ordered_df$cpg %>% as.character()] %>% as.data.frame %>% dplyr::select(c("seqnames","start","end"))

result_annot_df <- merge(
  y = meta_final_ordered_df,
  x = probes.info,
  by.y = "cpg",
  by.x = "row.names",
  all.y = TRUE,
  sort = FALSE
)

colnames(result_annot_df)[1] <- "cpg"
### final raw data
write.csv(
  result_annot_df  %>% as.data.frame(),
  paste0(data.final, "meta_analysis_single_cpg_df.csv"),
  row.names = FALSE
)

3.5 Delete cross-hybridizing and smoking probes from sig probes

### Exclude non-significant probes
result_annot_sig_df <- result_annot_df %>% filter(fdr < 0.05) #dim:3979 24

write.csv(
    result_annot_sig_df %>% as.data.frame(),
    paste0(data.final, "meta_analysis_single_cpg_sig_df.csv"),
    row.names = FALSE
)

### Get crosshybrdizing probes
library(ExperimentHub)

eh = ExperimentHub()
query(eh, "DMRcate")
crosshyb <- eh[["EH3129"]]


### Get significant smoking probes
smoking.file <- "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5267325/bin/NIHMS817273-supplement-001506_-_Supplemental_Tables.xlsx"

if(!file.exists(basename(smoking.file))) downloader::download(smoking.file,basename(smoking.file))

smoking <- readxl::read_xlsx(
    basename(smoking.file),
    sheet = "02",
    skip = 2
)
smoking.sig.probes <- smoking %>% dplyr::filter(`P-value` < 1*10^(-7)) %>% pull("Probe ID")


### Exclude cross-hybridizing and smoking probes
result_annot_sig_df$cpg <- as.character(result_annot_sig_df$cpg)

result_annot_sig_no_crossHyb_smoking_df <- result_annot_sig_df[
    !(result_annot_sig_df$cpg %in% c(crosshyb, smoking.sig.probes)),
] #dim: 3751 28

### Add annotation
library(coMethDMR)

result_annot_sig_no_crossHyb_smoking_df$chrom <- as.character(
    result_annot_sig_no_crossHyb_smoking_df$seqnames
)

result_final <- AnnotateResults(result_annot_sig_no_crossHyb_smoking_df)

result_final_ordered <- result_final[
    ,c(
        1:4, 30:33, 5:12,
        grep("GASPARONI", colnames(result_final), ignore.case = TRUE, invert = FALSE),
        grep("LONDON", colnames(result_final), ignore.case = TRUE, invert = FALSE),
        grep("MTSINAI", colnames(result_final), ignore.case = TRUE, invert = FALSE),
        grep("ROSMAP", colnames(result_final), ignore.case = TRUE, invert = FALSE)
    )
]

write.csv(
    result_final_ordered %>% as.data.frame(),
    paste0(data.final, "meta_analysis_single_cpg_sig_no_crossHyb_smoking_df.csv"),
    row.names = FALSE
)
readr::read_csv(
  paste0(data.final, "meta_analysis_single_cpg_sig_no_crossHyb_smoking_df.csv"),
  col_types = readr::cols()
)

4 Results from single CPG analysis and DMR analysis

readr::read_csv(
  paste0(dir.result.cpg.vs.dmr, "meta_analysis_sig_no_crossHyb_smoking_ov_comb_p_with_sig_single_cpgs.csv"),
  col_types = readr::cols()
)

4.1 Venn plot of single cpg sig vs. probes in DMRs

overlapping.results <-  readr::read_csv(paste0(dir.result.comp, "meta_analysis_no_crossHyb_smoking_ov_comb_p.csv"),
                                        col_types = readr::cols())
probes.in.all.regions <- coMethDMR::GetCpGsInAllRegion(overlapping.results$inputRegion)
probes.in.all.regions <- probes.in.all.regions %>% unique %>% unlist 

single.cpg.results <- readr::read_csv(
  "meta_analysis_single_cpg_results/meta_analysis_single_cpg_sig_no_crossHyb_smoking_df.csv",
  col_types = readr::cols()
) 

single.cpg.results.probes <- single.cpg.results %>% pull(cpg) %>% as.character 

# library
library(VennDiagram)
## Loading required package: grid
## Loading required package: futile.logger
library(ggplot2)

# Make the plot
venn <- venn.diagram(
  x = list(
    probes.in.all.regions %>% unique ,    
    single.cpg.results.probes %>% unique  
  ), 
  category.names = c("DMR analysis probes" , "Single cpg analysis probes" ),
  filename = file.path(dir.result.cpg.vs.dmr, '/venn_DMR_cpg.png'),
  output = TRUE ,
  imagetype = "png" ,
  height = 700 ,
  width = 700 ,
  resolution = 300,
  compression = "lzw",
  lwd = 1,
  col = c("#440154ff", '#21908dff'),
  fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3)),
  cex = 0.5,
  cat.cex = 0.3,
  cat.default.pos = "outer",
  cat.pos = c(0, 180),
  cat.dist = c(0.01, 0.01)
)
 venn.diagram(
  x = list(
    probes.in.all.regions %>% unique ,    
    single.cpg.results.probes %>% unique  
  ), 
  category.names = c("DMR analysis probes" , "Single cpg analysis probes" ),
  filename = NULL,
  output = TRUE ,
  imagetype = "png" ,
  height = 700 ,
  width = 700 ,
  resolution = 300,
  compression = "lzw",
  lwd = 1,
  col = c("#440154ff", '#21908dff'),
  fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3)),
  cex = 1,
  cat.cex = 1,
  cat.default.pos = "outer",
  cat.pos = c(0, 180),
  cat.dist = c(0.01, 0.01)
) %>% grid.draw()

5 Session information

devtools::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────
##  setting  value                                             
##  version  R Under development (unstable) (2020-02-25 r77857)
##  os       macOS Catalina 10.15.3                            
##  system   x86_64, darwin15.6.0                              
##  ui       X11                                               
##  language (EN)                                              
##  collate  en_US.UTF-8                                       
##  ctype    en_US.UTF-8                                       
##  tz       America/New_York                                  
##  date     2020-04-26                                        
## 
## ─ Packages ───────────────────────────────────────────────────────────────────
##  package                                       * version     date       lib
##  acepack                                         1.4.1       2016-10-29 [1]
##  ade4                                            1.7-15      2020-02-13 [1]
##  annotate                                        1.65.1      2020-01-27 [1]
##  AnnotationDbi                                   1.49.1      2020-01-25 [1]
##  AnnotationFilter                                1.11.0      2019-11-06 [1]
##  AnnotationHub                                 * 2.19.11     2020-04-16 [1]
##  askpass                                         1.1         2019-01-13 [1]
##  assertthat                                      0.2.1       2019-03-21 [1]
##  backports                                       1.1.6       2020-04-05 [1]
##  base64                                          2.0         2016-05-10 [1]
##  base64enc                                       0.1-3       2015-07-28 [1]
##  beanplot                                        1.2         2014-09-19 [1]
##  Biobase                                         2.47.3      2020-03-16 [1]
##  BiocFileCache                                 * 1.11.6      2020-04-16 [1]
##  BiocGenerics                                  * 0.33.3      2020-03-23 [1]
##  BiocManager                                     1.30.10     2019-11-16 [1]
##  BiocParallel                                    1.21.2      2019-12-21 [1]
##  BiocVersion                                     3.11.1      2019-11-13 [1]
##  biomaRt                                         2.43.5      2020-04-02 [1]
##  Biostrings                                    * 2.55.7      2020-03-24 [1]
##  biovizBase                                      1.35.1      2019-12-03 [1]
##  bit                                             1.1-15.2    2020-02-10 [1]
##  bit64                                           0.9-7       2017-05-08 [1]
##  bitops                                          1.0-6       2013-08-17 [1]
##  blob                                            1.2.1       2020-01-20 [1]
##  boot                                            1.3-24      2019-12-20 [1]
##  BSgenome                                        1.55.4      2020-03-19 [1]
##  bumphunter                                      1.29.0      2019-11-07 [1]
##  callr                                           3.4.3       2020-03-28 [1]
##  cellranger                                      1.1.0       2016-07-27 [1]
##  checkmate                                       2.0.0       2020-02-06 [1]
##  ChIPpeakAnno                                  * 3.21.6      2020-03-13 [1]
##  cli                                             2.0.2       2020-02-28 [1]
##  cluster                                         2.1.0       2019-06-19 [1]
##  codetools                                       0.2-16      2018-12-24 [1]
##  colorspace                                      1.4-1       2019-03-18 [1]
##  coMethDMR                                     * 0.0.0.9001  2020-03-24 [1]
##  crayon                                          1.3.4       2017-09-16 [1]
##  crosstalk                                       1.1.0.1     2020-03-13 [1]
##  curl                                            4.3         2019-12-02 [1]
##  data.table                                      1.12.9      2020-02-26 [1]
##  DBI                                             1.1.0       2019-12-15 [1]
##  dbplyr                                        * 1.4.3       2020-04-19 [1]
##  DelayedArray                                    0.13.12     2020-04-10 [1]
##  DelayedMatrixStats                              1.9.1       2020-03-30 [1]
##  desc                                            1.2.0       2018-05-01 [1]
##  devtools                                        2.3.0       2020-04-10 [1]
##  dichromat                                       2.0-0       2013-01-24 [1]
##  digest                                          0.6.25      2020-02-23 [1]
##  DMRcatedata                                   * 2.5.0       2019-10-31 [1]
##  doRNG                                           1.8.2       2020-01-27 [1]
##  dplyr                                         * 0.8.99.9002 2020-04-02 [1]
##  DT                                              0.13        2020-03-23 [1]
##  ellipsis                                        0.3.0       2019-09-20 [1]
##  ensembldb                                       2.11.4      2020-04-17 [1]
##  evaluate                                        0.14        2019-05-28 [1]
##  ExperimentHub                                 * 1.13.7      2020-04-16 [1]
##  fansi                                           0.4.1       2020-01-08 [1]
##  farver                                          2.0.3       2020-01-16 [1]
##  fastmap                                         1.0.1       2019-10-08 [1]
##  foreach                                         1.5.0       2020-03-30 [1]
##  foreign                                         0.8-78      2020-04-13 [1]
##  formatR                                         1.7         2019-06-11 [1]
##  Formula                                         1.2-3       2018-05-03 [1]
##  fs                                              1.4.1       2020-04-04 [1]
##  futile.logger                                 * 1.4.3       2016-07-10 [1]
##  futile.options                                  1.0.1       2018-04-20 [1]
##  genefilter                                      1.69.0      2019-11-06 [1]
##  generics                                        0.0.2       2018-11-29 [1]
##  GenomeInfoDb                                  * 1.23.17     2020-04-13 [1]
##  GenomeInfoDbData                                1.2.3       2020-04-20 [1]
##  GenomicAlignments                               1.23.2      2020-03-24 [1]
##  GenomicFeatures                                 1.39.7      2020-03-19 [1]
##  GenomicRanges                                 * 1.39.3      2020-04-08 [1]
##  GEOquery                                        2.55.1      2019-11-18 [1]
##  ggplot2                                       * 3.3.0       2020-03-05 [1]
##  ggpubr                                          0.2.5       2020-02-13 [1]
##  ggsignif                                        0.6.0       2019-08-08 [1]
##  glue                                            1.4.0       2020-04-03 [1]
##  GO.db                                           3.10.0      2020-03-30 [1]
##  graph                                           1.65.3      2020-04-14 [1]
##  gridExtra                                       2.3         2017-09-09 [1]
##  gtable                                          0.3.0       2019-03-25 [1]
##  Gviz                                            1.31.12     2020-03-05 [1]
##  HDF5Array                                       1.15.18     2020-04-10 [1]
##  Hmisc                                           4.4-0       2020-03-23 [1]
##  hms                                             0.5.3       2020-01-08 [1]
##  htmlTable                                       1.13.3      2019-12-04 [1]
##  htmltools                                       0.4.0       2019-10-04 [1]
##  htmlwidgets                                     1.5.1       2019-10-08 [1]
##  httpuv                                          1.5.2       2019-09-11 [1]
##  httr                                            1.4.1       2019-08-05 [1]
##  idr                                             1.2         2014-09-04 [1]
##  IlluminaHumanMethylation450kanno.ilmn12.hg19    0.6.0       2020-03-24 [1]
##  IlluminaHumanMethylationEPICanno.ilm10b2.hg19   0.6.0       2020-03-24 [1]
##  IlluminaHumanMethylationEPICanno.ilm10b4.hg19   0.6.0       2020-04-09 [1]
##  illuminaio                                      0.29.0      2019-11-06 [1]
##  interactiveDisplayBase                          1.25.0      2019-11-06 [1]
##  IRanges                                       * 2.21.8      2020-03-25 [1]
##  iterators                                       1.0.12      2019-07-26 [1]
##  jpeg                                            0.1-8.1     2019-10-24 [1]
##  jsonlite                                        1.6.1       2020-02-02 [1]
##  knitr                                           1.28        2020-02-06 [1]
##  lambda.r                                        1.2.4       2019-09-18 [1]
##  later                                           1.0.0       2019-10-04 [1]
##  lattice                                         0.20-41     2020-04-02 [1]
##  latticeExtra                                    0.6-29      2019-12-19 [1]
##  lazyeval                                        0.2.2       2019-03-15 [1]
##  lifecycle                                       0.2.0       2020-03-06 [1]
##  limma                                           3.43.8      2020-04-14 [1]
##  lme4                                            1.1-23      2020-04-07 [1]
##  lmerTest                                        3.1-2       2020-04-08 [1]
##  locfit                                          1.5-9.4     2020-03-25 [1]
##  magrittr                                        1.5         2014-11-22 [1]
##  MASS                                            7.3-51.5    2019-12-20 [1]
##  Matrix                                          1.2-18      2019-11-27 [1]
##  matrixStats                                     0.56.0      2020-03-13 [1]
##  mclust                                          5.4.6       2020-04-11 [1]
##  memoise                                         1.1.0       2017-04-21 [1]
##  mime                                            0.9         2020-02-04 [1]
##  minfi                                           1.33.1      2020-03-05 [1]
##  minqa                                           1.2.4       2014-10-09 [1]
##  multtest                                        2.43.1      2020-03-12 [1]
##  munsell                                         0.5.0       2018-06-12 [1]
##  nlme                                            3.1-147     2020-04-13 [1]
##  nloptr                                          1.2.2.1     2020-03-11 [1]
##  nnet                                            7.3-13      2020-02-25 [1]
##  nor1mix                                         1.3-0       2019-06-13 [1]
##  numDeriv                                        2016.8-1.1  2019-06-06 [1]
##  openssl                                         1.4.1       2019-07-18 [1]
##  pillar                                          1.4.3       2019-12-20 [1]
##  pkgbuild                                        1.0.6       2019-10-09 [1]
##  pkgconfig                                       2.0.3       2019-09-22 [1]
##  pkgload                                         1.0.2       2018-10-29 [1]
##  plyr                                            1.8.6       2020-03-03 [1]
##  png                                             0.1-7       2013-12-03 [1]
##  preprocessCore                                  1.49.2      2020-02-01 [1]
##  prettyunits                                     1.1.1       2020-01-24 [1]
##  processx                                        3.4.2       2020-02-09 [1]
##  progress                                        1.2.2       2019-05-16 [1]
##  promises                                        1.1.0       2019-10-04 [1]
##  ProtGenerics                                    1.19.3      2019-12-25 [1]
##  ps                                              1.3.2       2020-02-13 [1]
##  purrr                                           0.3.4       2020-04-17 [1]
##  quadprog                                        1.5-8       2019-11-20 [1]
##  R6                                              2.4.1       2019-11-12 [1]
##  rappdirs                                        0.3.1       2016-03-28 [1]
##  RBGL                                            1.63.1      2019-11-06 [1]
##  RColorBrewer                                    1.1-2       2014-12-07 [1]
##  Rcpp                                            1.0.4.6     2020-04-09 [1]
##  RcppZiggurat                                    0.1.5       2018-06-10 [1]
##  RCurl                                           1.98-1.2    2020-04-18 [1]
##  readr                                           1.3.1       2018-12-21 [1]
##  readxl                                          1.3.1       2019-03-13 [1]
##  regioneR                                        1.19.2      2020-03-28 [1]
##  remotes                                         2.1.1       2020-02-15 [1]
##  reshape                                         0.8.8       2018-10-23 [1]
##  reshape2                                        1.4.4       2020-04-09 [1]
##  Rfast                                           1.9.9       2020-03-08 [1]
##  rhdf5                                           2.31.10     2020-04-02 [1]
##  Rhdf5lib                                        1.9.3       2020-04-15 [1]
##  rlang                                           0.4.5.9000  2020-03-20 [1]
##  rmarkdown                                       2.1         2020-01-20 [1]
##  rngtools                                        1.5         2020-01-23 [1]
##  rpart                                           4.1-15      2019-04-12 [1]
##  rprojroot                                       1.3-2       2018-01-03 [1]
##  Rsamtools                                       2.3.7       2020-03-18 [1]
##  RSQLite                                         2.2.0       2020-01-07 [1]
##  rstudioapi                                      0.11        2020-02-07 [1]
##  rtracklayer                                     1.47.0      2019-11-06 [1]
##  S4Vectors                                     * 0.25.15     2020-04-04 [1]
##  scales                                          1.1.0       2019-11-18 [1]
##  scrime                                          1.3.5       2018-12-01 [1]
##  seqinr                                          3.6-1       2019-09-07 [1]
##  sessioninfo                                     1.1.1       2018-11-05 [1]
##  shiny                                           1.4.0.2     2020-03-13 [1]
##  siggenes                                        1.61.0      2019-11-06 [1]
##  statmod                                         1.4.34      2020-02-17 [1]
##  stringi                                         1.4.6       2020-02-17 [1]
##  stringr                                         1.4.0       2019-02-10 [1]
##  SummarizedExperiment                            1.17.5      2020-03-27 [1]
##  survival                                        3.1-12      2020-04-10 [1]
##  testthat                                        2.3.2       2020-03-02 [1]
##  tibble                                          3.0.1       2020-04-20 [1]
##  tidyr                                           1.0.2       2020-01-24 [1]
##  tidyselect                                      1.0.0       2020-01-27 [1]
##  usethis                                         1.6.0       2020-04-09 [1]
##  VariantAnnotation                               1.33.4      2020-04-09 [1]
##  vctrs                                           0.2.99.9010 2020-04-02 [1]
##  VennDiagram                                   * 1.6.20      2018-03-28 [1]
##  withr                                           2.1.2       2018-03-15 [1]
##  xfun                                            0.13        2020-04-13 [1]
##  XML                                             3.99-0.3    2020-01-20 [1]
##  xml2                                            1.3.1       2020-04-09 [1]
##  xtable                                          1.8-4       2019-04-21 [1]
##  XVector                                       * 0.27.2      2020-03-24 [1]
##  yaml                                            2.2.1       2020-02-01 [1]
##  zlibbioc                                        1.33.1      2020-01-24 [1]
##  source                                     
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  local                                      
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Github (tidyverse/dplyr@affb977)           
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Github (Bioconductor/GenomicRanges@70e6e69)
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  Github (r-lib/rlang@a90b04b)               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  Github (r-lib/vctrs@fd24927)               
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
##  CRAN (R 4.0.0)                             
##  Bioconductor                               
## 
## [1] /Library/Frameworks/R.framework/Versions/4.0/Resources/library
LS0tCnRpdGxlOiAiTWV0YS1hbmFseXNpcyBkYXRhc2V0IgphdXRob3I6ICJMYW55dSBaaGFuZywgVGlhZ28gQy4gU2lsdmEsIExpbHkgV2FuZyIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgcm1hcmtkb3duOjpodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IGx1bWVuCiAgICB0b2M6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogeWVzCiAgICB0b2NfZGVwdGg6IDMKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZSAgICAKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UpCmBgYAoKCiMgTWFpbiBsaWJyYXJpZXMgYW5kIGNvbmZpZ3VyYXRpb24KCmBgYHtSLCBtZXNzYWdlID0gRkFMU0UsIHJlc3VsdHMgPSAnaGlkZSd9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoRXhwZXJpbWVudEh1YikKbGlicmFyeShHZW5vbWljUmFuZ2VzKQpsaWJyYXJ5KGNvTWV0aERNUikKYGBgCgojIE1ldGEtYW5hbHlzaXMgb2YgR2Vub21pYyBSZWdpb25zCgojIyBQYXRocwpgYGB7Un0KZGlyLnJlc3VsdCA8LSAibWV0YV9hbmFseXNpc19yZWdpb25fcmVzdWx0cy8iCmRpci5yZXN1bHQubWV0YS5hbmFseXNpcyA8LSBmaWxlLnBhdGgoZGlyLnJlc3VsdCwgInN0ZXAxX21ldGFfYW5hbHlzaXMvIikKZGlyLnJlc3VsdC5zbW9raW5nX2Nyb3NzaHliIDwtIGZpbGUucGF0aChkaXIucmVzdWx0LCAic3RlcDJfc21va2luZ19jcm9zc19hbm90YXRpb24vIikKZGlyLnJlc3VsdC5jb21wIDwtIGZpbGUucGF0aChkaXIucmVzdWx0LCAic3RlcDNfY29tcC8iKQpkaXIucmVzdWx0LmNwZy52cy5kbXIgPC0gZmlsZS5wYXRoKGRpci5yZXN1bHQsICJzdGVwNF9kbXJfdnNfY3Bncy8iKQpkaXIucmVzdWx0LmxvbGEgPC0gZmlsZS5wYXRoKGRpci5yZXN1bHQsICJzdGVwNV9sb2xhLyIpCmRpci5yZXN1bHQuZW5yaWNobWVudCA8LSBmaWxlLnBhdGgoZGlyLnJlc3VsdCwgInN0ZXA2X2VucmljaG1lbnQvIikKZGlyLnJlc3VsdC5wYXRod2F5IDwtIGZpbGUucGF0aChkaXIucmVzdWx0LCAic3RlcDdfcGF0aHdheS8iKQpkYXRhLmZpbmFsIDwtICJtZXRhX2FuYWx5c2lzX3NpbmdsZV9jcGdfcmVzdWx0cy8iCmZvcihwIGluIGdyZXAoImRpciIsbHMoKSx2YWx1ZSA9IFQpKSBkaXIuY3JlYXRlKGdldChwKSxyZWN1cnNpdmUgPSBUUlVFLHNob3dXYXJuaW5ncyA9IEZBTFNFKQpgYGAKCiMjIEltcG9ydCBkYXRhc2V0cyBhbmQgcHJlLXByb2Nlc3MgZm9yIGVhY2ggY29ob3J0IAoKYGBge1IsIGV2YWwgPSBGQUxTRX0KbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKcHJlTWV0YSA8LSBmdW5jdGlvbihjb2hvcnQpewogIAogICMjIyBMb2FkIGRhdGEKICBmaWxlIDwtIGRpcihwYXR0ZXJuID0gcGFzdGUwKGNvaG9ydCwiX2xpbmVhcl9kZiIpLAogICAgICAgICAgICAgIHBhdGggPSAgIkRBVEFTRVRTLyIsCiAgICAgICAgICAgICAgcmVjdXJzaXZlID0gVFJVRSwKICAgICAgICAgICAgICBmdWxsLm5hbWVzID0gVFJVRSwKICAgICAgICAgICAgICBpZ25vcmUuY2FzZSA9IFRSVUUpCiAgbWVzc2FnZSgiUmVhZGluZyBmaWxlOiAiLCBmaWxlKQogIGxpbmVhci5yZXN1bHRzLmZpbmFsIDwtIHJlYWRSRFMoZmlsZSkKICAKICAjIyMgc2VsZWN0IHRoZSBtb3N0IHNpZyBjb21ldGggcmVnaW9uIGZvciBlYWNoIGlucHV0IHJlZ2lvbgogIHB2YS5jb2wgPC0gZ3JlcCgiX3BWYWwiLGNvbG5hbWVzKGxpbmVhci5yZXN1bHRzLmZpbmFsKSx2YWx1ZSA9IFRSVUUpCiAgY29sbmFtZXMobGluZWFyLnJlc3VsdHMuZmluYWwpW2dyZXAoImlucHV0UmVnaW9uIixjb2xuYW1lcyhsaW5lYXIucmVzdWx0cy5maW5hbCkpXSA8LSAiaW5wdXRSZWdpb24iCiAgCiAgIyAhISBpcyB1c2VkIHRvIHVucXVvdGUgYW4gaW5wdXQgCiAgIyBodHRwczovL2RwbHlyLnRpZHl2ZXJzZS5vcmcvYXJ0aWNsZXMvcHJvZ3JhbW1pbmcuaHRtbAogIHJlc3VsdF9zaWcgPC0gbGluZWFyLnJlc3VsdHMuZmluYWwgJT4lCiAgICBncm91cF9ieShpbnB1dFJlZ2lvbikgJT4lCiAgICBmaWx0ZXIoKCEhYXMuc3ltYm9sKHB2YS5jb2wpKSA9PSBtaW4oISFhcy5zeW1ib2wocHZhLmNvbCkpKQogIAogIGRhdGEuZnJhbWUocmVzdWx0X3NpZywgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQp9CgpHYXNwYXJvbmkgPC0gcHJlTWV0YShjb2hvcnQgPSAiR2FzcGFyb25pIikgI2RpbTogMzk2MDUgIDgKTG9uZG9uX1BGQyA8LSBwcmVNZXRhKGNvaG9ydCA9ICJMb25kb24iKSAjZGltOiA0MDAwMCA4Ck10U2luYWkgPC0gcHJlTWV0YShjb2hvcnQgPSAiTXRTaW5haSIpICNkaW06ICAzODYxOSA4ClJPU01BUCA8LSBwcmVNZXRhKGNvaG9ydCA9ICJST1NNQVAiKSAjZGltOiAzODU2MiA4CmBgYAoKCiMjIE1lcmdlIGNvaG9ydHMgCgpgYGB7UiwgZXZhbCA9IEZBTFNFfQojIyMgbWVyZ2UgZGF0YXNldHMKY29ob3J0X2xzIDwtIGxpc3QoCiAgR2FzcGFyb25pID0gR2FzcGFyb25pLAogIExvbmRvbl9QRkMgPSBMb25kb25fUEZDLAogIE10U2luYWkgPSBNdFNpbmFpLAogIFJPU01BUCA9IFJPU01BUAopCgojIyMgb3V0ZXIgam9pbiBpbnB1dCByZWdpb24KbXVsdGlfY29ob3J0cyA8LSBSZWR1Y2UoCiAgZnVuY3Rpb24oeCx5LCAuLi4pIG1lcmdlKHgsIHksIGJ5ID0gImlucHV0UmVnaW9uIiwgYWxsID0gVFJVRSwgLi4uKSwKICBjb2hvcnRfbHMKKQpgYGAKCgojIyBNZXRhIGFuYWx5c2lzCmBgYHtSLCBldmFsID0gRkFMU0V9CmxpYnJhcnkobWV0YSkKCmRvUGFyYWxsZWw6OnJlZ2lzdGVyRG9QYXJhbGxlbChjb3JlcyA9IHBhcmFsbGVsOjpkZXRlY3RDb3JlcygpLzIpCm1ldGFfZGYgPC0gcGx5cjo6YWRwbHkoLmRhdGEgPSBtdWx0aV9jb2hvcnRzLCAKICAgICAgICAgICAgICAgICAgICAgICAubWFyZ2lucyA9IDEsIAogICAgICAgICAgICAgICAgICAgICAgIC5mdW4gPSAgZnVuY3Rpb24ocm93T25lX2RmKXsKICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgZXN0IDwtIHJvd09uZV9kZltncmVwKCJlc3RpbWF0ZSIsY29sbmFtZXMocm93T25lX2RmKSldICU+JSBhcy5udW1lcmljCiAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA8LSAgcGFzdGUoaWZlbHNlKAogICAgICAgICAgICAgICAgICAgICAgICAgICBpcy5uYShlc3QpLCAiLiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlc3QgPiAwLCAiKyIsICItIikKICAgICAgICAgICAgICAgICAgICAgICAgICksY29sbGFwc2UgPSAiIikKICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgc2UgPC0gcm93T25lX2RmW2dyZXAoInNlIixjb2xuYW1lcyhyb3dPbmVfZGYpKV0gJT4lIGFzLm51bWVyaWMKICAgICAgICAgICAgICAgICAgICAgICAgIGNvaG9ydCA8LSBnc3ViKCJfc2UiLCIiLGdyZXAoInNlIixjb2xuYW1lcyhyb3dPbmVfZGYpLHZhbHVlID0gVCkpCiAgICAgICAgICAgICAgICAgICAgICAgICByb3dPbmVfcmVmb3JtX2RmIDwtIGRhdGEuZnJhbWUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvaG9ydCA9IGNvaG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZXN0ID0gZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZSA9IHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UKICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgZiA8LSBtZXRhZ2VuKAogICAgICAgICAgICAgICAgICAgICAgICAgICBURSA9IGVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VURSA9IHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gcm93T25lX3JlZm9ybV9kZgogICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICB0aWJibGU6OnRpYmJsZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRSZWdpb24gPSByb3dPbmVfZGYkaW5wdXRSZWdpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzdGltYXRlID0gZiRURS5maXhlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2UgPSBmJHNlVEUuZml4ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBWYWwuZml4ZWQgPSBmJHB2YWwuZml4ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBWYWwucmFuZG9tID0gZiRwdmFsLnJhbmRvbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcFZhbFEgPSBmJHB2YWwuUSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uID0gZGlyZWN0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgICAgfSAgLCAucHJvZ3Jlc3MgPSAidGltZSIsCiAgICAgICAgICAgICAgICAgICAgICAgLnBhcmFsbGVsID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAuaWQgPSBOVUxMCikKCiMjIyBjcmVhdGUgZmluYWwgcFZhbAptZXRhX2RmJHBWYWwuZmluYWwgPC0gaWZlbHNlKAogIG1ldGFfZGYkcFZhbFEgPiAwLjA1LCBtZXRhX2RmJHBWYWwuZml4ZWQsIG1ldGFfZGYkcFZhbC5yYW5kb20KKQoKIyMjIGNhbGN1bGF0ZSBmZHIKbWV0YV9kZiRmZHIgPC0gcC5hZGp1c3QobWV0YV9kZiRwVmFsLmZpbmFsLCBtZXRob2QgPSAiZmRyIikKCiMjIyBvcmRlciBtZXRhX2RmCm1ldGFfZmluYWxfZGYgPC0gbWV0YV9kZlssIGMoZ3JlcCgiXyIsY29sbmFtZXMobWV0YV9kZiksaW52ZXJ0ID0gVCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcCgiXyIsY29sbmFtZXMobWV0YV9kZiksaW52ZXJ0ID0gRikpXQptZXRhX2ZpbmFsX29yZGVyZWRfZGYgPC0gbWV0YV9maW5hbF9kZltvcmRlcihtZXRhX2ZpbmFsX2RmJHBWYWwuZmluYWwpLF0KYGBgCgoKIyMgQWRkIGFubm90YXRpb24gdG8gaW5wdXQgcmVnaW9ucyAKYGBge1IsIGV2YWwgPSBGQUxTRX0KIyMjIGZpbmQgYW5ub3RhdGlvbnMKbGlicmFyeShjb01ldGhETVIpCgpzcGxpdGVkX2lucHV0IDwtIG1ldGFfZmluYWxfb3JkZXJlZF9kZiAlPiUgCiAgdGlkeXI6OnNlcGFyYXRlKGNvbCA9IGlucHV0UmVnaW9uLGludG8gPSAgYygiY2hyb20iLCAic3RhcnQiLCAiZW5kIikscmVtb3ZlID0gRkFMU0UpCnNwbGl0ZWRfaW5wdXRfYW5ub3QgPC0gQW5ub3RhdGVSZXN1bHRzKHNwbGl0ZWRfaW5wdXRbLGMoImNocm9tIiwgInN0YXJ0IiwgImVuZCIpXSxuQ29yZXNfaW50ID0gMTApIAoKIyMjIG1lcmdlIGFubm90YXRpb24gd2l0aCBtZXRhIGFuYWx5c2lzIGRhdGEKbWV0YV9vcmRlcmVkX3dpdGhBbm5vdF9kZiA8LSBjYmluZCgKICBtZXRhX2ZpbmFsX29yZGVyZWRfZGYsIHNwbGl0ZWRfaW5wdXRfYW5ub3RbLCA0OjddCikKCiMjIyBvcmRlciBjb2x1bW5zCm1ldGFfb3JkZXJlZF93aXRoQW5ub3RfZGYgPC0gbWV0YV9vcmRlcmVkX3dpdGhBbm5vdF9kZiAlPiUgCiAgZHBseXI6OnNlbGVjdChjKDEsCiAgICAgICAgICAgICAgICAgIChuY29sKG1ldGFfb3JkZXJlZF93aXRoQW5ub3RfZGYpIC0gMyk6bmNvbChtZXRhX29yZGVyZWRfd2l0aEFubm90X2RmKSwKICAgICAgICAgICAgICAgICAgMjoobmNvbChtZXRhX29yZGVyZWRfd2l0aEFubm90X2RmKSAtIDQpKQogICkKIyMjIHNhdmUgZGF0YXNldAp3cml0ZS5jc3YoCiAgbWV0YV9vcmRlcmVkX3dpdGhBbm5vdF9kZiwKICBwYXN0ZTAoZGlyLnJlc3VsdC5tZXRhLmFuYWx5c2lzLCAibWV0YV9hbmFseXNpc19BTExfZGYuY3N2IiksCiAgcm93Lm5hbWVzID0gRkFMU0UKKQoKbWV0YV9hbGxfc2lnIDwtIG1ldGFfb3JkZXJlZF93aXRoQW5ub3RfZGZbCiAgIWlzLm5hKG1ldGFfb3JkZXJlZF93aXRoQW5ub3RfZGYkZmRyKSAmCiAgICAobWV0YV9vcmRlcmVkX3dpdGhBbm5vdF9kZiRmZHIgPCAwLjA1KSwgCiAgXSAjZGltOiA0NzggNDEKcm93Lm5hbWVzKG1ldGFfYWxsX3NpZykgPC0gTlVMTAoKd3JpdGUuY3N2KAogIG1ldGFfYWxsX3NpZywKICBwYXN0ZTAoZGlyLnJlc3VsdC5tZXRhLmFuYWx5c2lzLCAibWV0YV9hbmFseXNpc19BTExfc2lnX2RmLmNzdiIpLAogIHJvdy5uYW1lcyA9IEZBTFNFCikKCmBgYAoKIyMgRmlsdGVyaW5nIGNvTWV0aERNUnMKCiMjIyBBbm5vdGF0ZSBjb01ldGhETVJzIHdpdGggY3Jvc3NoeWJyZGl6aW5nIHByb2JlcyBjaGVuIGV0IGFsLiAoMjAxMykgICYgc21va2luZyBwcm9iZXMgCgojIyMjIEdldCBjcm9zc2h5YnJkaXppbmcgcHJvYmVzCmBgYHtSfQojIyMgY2FsbCBpbiBhbGwgY3Jvc3MgaHlicmlkaXppbmcgcHJvYmVzCmVoID0gRXhwZXJpbWVudEh1YigpCnF1ZXJ5KGVoLCAiRE1SY2F0ZSIpCmNyb3NzaHliIDwtIGVoW1siRUgzMTI5Il1dCmBgYAoKCiMjIyMgR2V0IHNpZ25pZmljYW50IHNtb2tpbmcgcHJvYmVzCgpgYGB7Un0Kc21va2luZy5maWxlIDwtICJodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L3BtYy9hcnRpY2xlcy9QTUM1MjY3MzI1L2Jpbi9OSUhNUzgxNzI3My1zdXBwbGVtZW50LTAwMTUwNl8tX1N1cHBsZW1lbnRhbF9UYWJsZXMueGxzeCIKCmlmKCFmaWxlLmV4aXN0cyhiYXNlbmFtZShzbW9raW5nLmZpbGUpKSkgZG93bmxvYWRlcjo6ZG93bmxvYWQoc21va2luZy5maWxlLGJhc2VuYW1lKHNtb2tpbmcuZmlsZSkpCgpzbW9raW5nIDwtIHJlYWR4bDo6cmVhZF94bHN4KAogIGJhc2VuYW1lKHNtb2tpbmcuZmlsZSksCiAgc2hlZXQgPSAiMDIiLAogIHNraXAgPSAyCikKc21va2luZy5zaWcucHJvYmVzIDwtIHNtb2tpbmcgJT4lIGRwbHlyOjpmaWx0ZXIoYFAtdmFsdWVgIDwgMSoxMF4oLTcpKSAlPiUgcHVsbCgiUHJvYmUgSUQiKSAKbGVuZ3RoKHNtb2tpbmcuc2lnLnByb2JlcykKYGBgCgojIyMjIExvYWQgc2lnbmlmaWNhbnQgY29NZXRoRE1ScyBpZGVudGlmaWVkIGluIG1ldGEtYW5hbGF5c2lzCmBgYHtSfQojIENhbGwgaW4gbWV0YSBhbmFseXNpcyBmaW5hbCByZXN1bHRzCm1ldGFfYWxsIDwtIHJlYWRyOjpyZWFkX2NzdigKICBkaXIoZGlyLnJlc3VsdC5tZXRhLmFuYWx5c2lzLCBwYXR0ZXJuID0gIm1ldGFfYW5hbHlzaXNfQUxMX3NpZ19kZi5jc3YiLGZ1bGwubmFtZXMgPSBUUlVFKSwKICBjb2xfdHlwZXMgPSByZWFkcjo6Y29scygpCikKCiMgRmluZCBmaWxlcyB3aXRoIHJlZ2lvbnMgYW5kIHByb2JlcwpmaWxlcyA8LSBkaXIocGF0dGVybiA9IHBhc3RlMCgiLipfcmVzaWR1YWxzX2NvbWV0aF9pbnB1dF9scy5yZHMiKSwKICAgICAgICAgICAgIHJlY3Vyc2l2ZSA9IFQsCiAgICAgICAgICAgICBmdWxsLm5hbWVzID0gVFJVRSwKICAgICAgICAgICAgIGlnbm9yZS5jYXNlID0gVCkKZmlsZXMgPC0gZ3JlcCgiR0FTUEFST05JfExPTkRPTl9QRkN8TXRTaW5haXxST1NNQVAiLGZpbGVzLHZhbHVlID0gVFJVRSxpZ25vcmUuY2FzZSA9IFRSVUUpCgojIFJlYWQgZmlsZXMgYW5kIExpbWl0IHRoZSBjb2hvcnRfbHMgdG8gY29ob3J0X2NvTWV0aFJlZ2lvbiBpbiBtZXRhX2FsbCAKY29tZXRoLnByb2Jlcy5saXN0IDwtIGxhcHBseShmaWxlcywgZnVuY3Rpb24gKGYpewogIHByaW50KGYpCiAgYWxsLmNsdXN0ZXJzIDwtIHJlYWRSRFMoZikkY29NZXRoX2xzICMgUmVhZCBmaWxlcwogIGNvaG9ydCA8LSBmICU+JSBkaXJuYW1lICU+JSBkaXJuYW1lICU+JSBiYXNlbmFtZSAjIGdldCBjb2hvcnQgZnJvbSBmb2xkZXIgbmFtZQogIAogIGNvbCA8LSBncmVwKHBhc3RlMChjb2hvcnQsIl9jb01ldGhSZWdpb24iKSwKICAgICAgICAgICAgICBjb2xuYW1lcyhtZXRhX2FsbCksCiAgICAgICAgICAgICAgaWdub3JlLmNhc2UgPSBUUlVFLAogICAgICAgICAgICAgIHZhbHVlID0gVFJVRSkgIyBnZXQgY29sdW1uIHdpdGggY29ob3J0IHNpZyByZWdpb25zCiAgCiAgIyBrZWVwIHNpZyByZWdpb25zIG9ubHkKICBhbGwuY2x1c3RlcnNbbmFtZXMoYWxsLmNsdXN0ZXJzKSAlaW4lIG1ldGFfYWxsW1tjb2xdXV0KfSkKbmFtZXMoY29tZXRoLnByb2Jlcy5saXN0KSA8LSAgZmlsZXMgJT4lIGRpcm5hbWUgJT4lIGRpcm5hbWUgJT4lIGJhc2VuYW1lCgpsYXBwbHkoY29tZXRoLnByb2Jlcy5saXN0LGxlbmd0aCkKYGBgCgojIyMjIE1hcCBwcm9iZXMgaW4gZWFjaCByZWdpb24gdG8gc21va2luZyBhbmQgY3Jvc3NoeWJyZGl6aW5nIAoKYGBge1J9CmV4dHJhY3RDcm9zSHlicmlkaXphdGlvbiA8LSBmdW5jdGlvbihwcm9iZXMubGlzdCl7CiAgY3Jvc3NoeWIuZXh0cmFjdGVkIDwtIHBseXI6OmxhcGx5KHByb2Jlcy5saXN0LGZ1bmN0aW9uKHByb2Jlcyl7CiAgICBwYXN0ZShpbnRlcnNlY3QocHJvYmVzLCBjcm9zc2h5YiksIAogICAgICAgICAgY29sbGFwc2UgPSAiLCAiCiAgICApCiAgfSkKICBzbW9raW5nLmV4dHJhY3RlZCA8LSBwbHlyOjpsYXBseShwcm9iZXMubGlzdCxmdW5jdGlvbihwcm9iZXMpewogICAgcGFzdGUoaW50ZXJzZWN0KHByb2Jlcywgc21va2luZy5zaWcucHJvYmVzKSwgCiAgICAgICAgICBjb2xsYXBzZSA9ICIsICIKICAgICkKICB9KQogIHRpYmJsZTo6dGliYmxlKAogICAgImNvTWV0aFJlZ2lvbiIgPSBuYW1lcyhwcm9iZXMubGlzdCksCiAgICAiY3Jvc3NIeWIiID0gY3Jvc3NoeWIuZXh0cmFjdGVkLCAKICAgICJjcm9zc0h5Yl9iaSIgPSBpZmVsc2UoY3Jvc3NoeWIuZXh0cmFjdGVkID09ICIiLDAsMSksCiAgICAic21va2UiID0gc21va2luZy5leHRyYWN0ZWQsCiAgICAic21va2VfYmkiID0gaWZlbHNlKHNtb2tpbmcuZXh0cmFjdGVkID09ICIiLDAsMSkKICApCn0KCkdhc3Bhcm9uaV9jcm9zc0h5Yl9kZiA8LSBleHRyYWN0Q3Jvc0h5YnJpZGl6YXRpb24oY29tZXRoLnByb2Jlcy5saXN0JEdBU1BBUk9OSSkKY29sbmFtZXMoR2FzcGFyb25pX2Nyb3NzSHliX2RmKSA8LSBwYXN0ZTAoIkdBU1BBUk9OSV8iLGNvbG5hbWVzKEdhc3Bhcm9uaV9jcm9zc0h5Yl9kZikpCnBseXI6OmNvdW50KEdhc3Bhcm9uaV9jcm9zc0h5Yl9kZiwgdmFycyA9IGdyZXAoIl9iaSIsY29sbmFtZXMoR2FzcGFyb25pX2Nyb3NzSHliX2RmKSx2YWx1ZSA9IFRSVUUpKQoKTG9uZG9uX1BGQ19jcm9zc0h5Yl9kZiA8LSBleHRyYWN0Q3Jvc0h5YnJpZGl6YXRpb24oY29tZXRoLnByb2Jlcy5saXN0JExPTkRPTikKY29sbmFtZXMoTG9uZG9uX1BGQ19jcm9zc0h5Yl9kZikgPC0gcGFzdGUwKCJMb25kb25fIixjb2xuYW1lcyhMb25kb25fUEZDX2Nyb3NzSHliX2RmKSkKcGx5cjo6Y291bnQoTG9uZG9uX1BGQ19jcm9zc0h5Yl9kZiwgdmFycyA9IGdyZXAoIl9iaSIsY29sbmFtZXMoTG9uZG9uX1BGQ19jcm9zc0h5Yl9kZiksdmFsdWUgPSBUUlVFKSkKCk10U2luYWlfY3Jvc3NIeWJfZGYgPC0gZXh0cmFjdENyb3NIeWJyaWRpemF0aW9uKGNvbWV0aC5wcm9iZXMubGlzdCRNdFNpbmFpKQpjb2xuYW1lcyhNdFNpbmFpX2Nyb3NzSHliX2RmKSA8LSBwYXN0ZTAoIk10U2luYWlfIixjb2xuYW1lcyhNdFNpbmFpX2Nyb3NzSHliX2RmKSkKcGx5cjo6Y291bnQoTXRTaW5haV9jcm9zc0h5Yl9kZiwgdmFycyA9IGdyZXAoIl9iaSIsY29sbmFtZXMoTXRTaW5haV9jcm9zc0h5Yl9kZiksdmFsdWUgPSBUUlVFKSkKClJPU01BUF9jcm9zc0h5Yl9kZiA8LSBleHRyYWN0Q3Jvc0h5YnJpZGl6YXRpb24oY29tZXRoLnByb2Jlcy5saXN0JFJPU01BUCkKY29sbmFtZXMoUk9TTUFQX2Nyb3NzSHliX2RmKSA8LSBwYXN0ZTAoIlJPU01BUF8iLGNvbG5hbWVzKFJPU01BUF9jcm9zc0h5Yl9kZikpCnBseXI6OmNvdW50KFJPU01BUF9jcm9zc0h5Yl9kZiwgdmFycyA9IGdyZXAoIl9iaSIsY29sbmFtZXMoUk9TTUFQX2Nyb3NzSHliX2RmKSx2YWx1ZSA9IFRSVUUpKQoKYGBgCgojIyMjIE1lcmdlIHNtb2tpbmcgYW5kIGNyb3NzSHliIHByb2JlcyAgaW5mb3JtYXRpb24gd2l0aCBtZXRhIGFuYWx5c2lzIHJlc3VsdHMgCgpgYGB7Un0KbWV0YV9hbGxfZmluYWwgPC0gbWV0YV9hbGwgJT4lIGxlZnRfam9pbihHYXNwYXJvbmlfY3Jvc3NIeWJfZGYpICAlPiUgCiAgbGVmdF9qb2luKExvbmRvbl9QRkNfY3Jvc3NIeWJfZGYpICU+JSAKICBsZWZ0X2pvaW4oTXRTaW5haV9jcm9zc0h5Yl9kZikgJT4lIAogIGxlZnRfam9pbihST1NNQVBfY3Jvc3NIeWJfZGYpCgojIyMgQWRkIGluZm9ybWF0aW9uIHdpdGggaW5wdXQgcmVnaW9ucyB3aXRoIGFueSBjcm9zcyBoeWJyaWRpemF0aW9uIGluIGNvaG9ydHMgCm1ldGFfYWxsX2ZpbmFsJGNyb3NzSHliX2JpIDwtIHJvd1N1bXMobWV0YV9hbGxfZmluYWxbLGdyZXAoImNyb3NzSHliX2JpIixjb2xuYW1lcyhtZXRhX2FsbF9maW5hbCkpXSxuYS5ybSA9IFRSVUUpID4gMAptZXRhX2FsbF9maW5hbCRzbW9rZV9iaSA8LSByb3dTdW1zKG1ldGFfYWxsX2ZpbmFsWyxncmVwKCJzbW9rZV9iaSIsY29sbmFtZXMobWV0YV9hbGxfZmluYWwpKV0sbmEucm0gPSBUUlVFKSA+IDAKCiMgU29ydCBieSByZWdpb24gbWV0YSBhbmFseXNpcyBGRFIKIyBDbHVzdGVyIGNvbHVtbnMgb2YgdGhlIHByb2plY3RzIHRvZ2V0aGVyCm1ldGFfYWxsX2ZpbmFsIDwtIG1ldGFfYWxsX2ZpbmFsWwogIG9yZGVyKG1ldGFfYWxsX2ZpbmFsJGZkciksCiAgYygKICAgIGdyZXAoIkdhc3Bhcm9uaXxNdFNpbmFpfExvbmRvbnxST1NNQVAiLGNvbG5hbWVzKG1ldGFfYWxsX2ZpbmFsKSxpZ25vcmUuY2FzZSA9IFRSVUUsaW52ZXJ0ID0gVFJVRSksCiAgICBncmVwKCJHYXNwYXJvbmkiLGNvbG5hbWVzKG1ldGFfYWxsX2ZpbmFsKSxpZ25vcmUuY2FzZSA9IFRSVUUpLAogICAgZ3JlcCgiTXRTaW5haSIsY29sbmFtZXMobWV0YV9hbGxfZmluYWwpLGlnbm9yZS5jYXNlID0gVFJVRSksCiAgICBncmVwKCJMb25kb24iLGNvbG5hbWVzKG1ldGFfYWxsX2ZpbmFsKSxpZ25vcmUuY2FzZSA9IFRSVUUpLAogICAgZ3JlcCgiUk9TTUFQIixjb2xuYW1lcyhtZXRhX2FsbF9maW5hbCksaWdub3JlLmNhc2UgPSBUUlVFKQogICkKICBdCnN0cihtZXRhX2FsbF9maW5hbCkKYGBgCgojIyMjIFNhdmUKCmBgYHtSfQp3cml0ZS5jc3YoCiAgbWV0YV9hbGxfZmluYWwsCiAgcGFzdGUwKGRpci5yZXN1bHQuc21va2luZ19jcm9zc2h5YiwgIm1ldGFfYW5hbHlzaXNfQUxMX3NpZ19hZGRfY3Jvc3NIeWJfZGYuY3N2IiksCiAgcm93Lm5hbWVzID0gRkFMU0UKKQoKbWV0YV9hbGxfZmluYWwgJT4lIAogIGRwbHlyOjpmaWx0ZXIoc21va2VfYmkgPT0gMCAmIGNyb3NzSHliX2JpID09IDApICAlPiUgCiAgRFQ6OmRhdGF0YWJsZShmaWx0ZXIgPSAndG9wJywKICAgICAgICAgICAgICAgIHN0eWxlID0gImJvb3RzdHJhcCIsCiAgICAgICAgICAgICAgICBleHRlbnNpb25zID0gJ0J1dHRvbnMnLAogICAgICAgICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2Nyb2xsWCA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tID0gJ0JmcnRpcCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25zID0gSSgnY29sdmlzJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlzID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gMTApLCAKICAgICAgICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICAgICAgICBjYXB0aW9uID0gIm1ldGEtYW5hbHlzaXMgcmVzdWx0cyIpCgpgYGAKCgojIyMgT3ZlcmxhcCB3aXRoIGNvbWItcCBETVJzIAoKIyMjIyBJbXBvcnQgZGF0YXNldHMKCmBgYHtSfQpsaWJyYXJ5KEdlbm9taWNSYW5nZXMpCmBgYAoKYGBge1IgY29tYnB9CmxpbmVhcl9zaWcgPC0gcmVhZHI6OnJlYWRfY3N2KAogIGRpcihkaXIucmVzdWx0LnNtb2tpbmdfY3Jvc3NoeWIsIHBhdHRlcm4gPSAibWV0YV9hbmFseXNpc19BTExfc2lnX2FkZF9jcm9zc0h5Yl9kZi5jc3YiLGZ1bGwubmFtZXMgPSBUUlVFKSwKICBjb2xfdHlwZXMgPSByZWFkcjo6Y29scygpCikKbGluZWFyX3NpZ19pbnB1dF9nciA8LSBsaW5lYXJfc2lnICU+JSAKICB0aWR5cjo6c2VwYXJhdGUoImlucHV0UmVnaW9uIixjKCJjaHJvbSIsInN0YXJ0IiwiZW5kIikpICU+JQogIG1ha2VHUmFuZ2VzRnJvbURhdGFGcmFtZSgpCmxpbmVhcl9zaWdfaW5wdXRfZ3IKCmNvbWJwIDwtIHJlYWR4bDo6cmVhZF94bHN4KCIuLi8uLi9NaWNoYWVsLzFfN18yMDIwXzAwMS0yMDAvMV83XzIwMjBfMDAxLTIwMC9jb21icF9yZXN1bHRzLnhsc3giKSAjIGdldCBjb21iLXAgcmVzdWx0cwpjb2xuYW1lcyhjb21icClbMV0gPC0gImNocm9tIgpjb21icCRjaHJvbSA8LSBwYXN0ZTAoImNociIsY29tYnAkY2hyb20pCmNvbWJwX3NpZyA8LSBjb21icCAlPiUgZmlsdGVyKHpfc2lkYWtfcCA8IDAuMDUgJiBuX3Byb2JlcyA+IDIpCgpjb21icF9zaWcgJT4lIAogIERUOjpkYXRhdGFibGUoZmlsdGVyID0gJ3RvcCcsCiAgICAgICAgICAgICAgICBzdHlsZSA9ICJib290c3RyYXAiLAogICAgICAgICAgICAgICAgZXh0ZW5zaW9ucyA9ICdCdXR0b25zJywKICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNjcm9sbFggPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbSA9ICdCZnJ0aXAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IEkoJ2NvbHZpcycpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5cyA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwKSwgCiAgICAgICAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgY2FwdGlvbiA9ICJjb21iLXAgcmVzdWx0cyIpCgpjb21icF9zaWdfZ3IgPC0gbWFrZUdSYW5nZXNGcm9tRGF0YUZyYW1lKGNvbWJwX3NpZykKY29tYnBfc2lnX2dyCmBgYAoKIyMjIyBTYXZlIG92ZXJsYXBwaW5nIHJlc3VsdHMKCmBgYHtSfQpvdmVybGFwcGluZy5yZXN1bHRzIDwtIGxpbmVhcl9zaWdbCiAgcXVlcnlIaXRzKGZpbmRPdmVybGFwcyhsaW5lYXJfc2lnX2lucHV0X2dyLGNvbWJwX3NpZ19ncikpLAogIF0gIyBucm93OiAxNDYKCm92ZXJsYXBwaW5nLmNvbWJwIDwtIGNvbWJwX3NpZ1sKICBzdWJqZWN0SGl0cyhmaW5kT3ZlcmxhcHMobGluZWFyX3NpZ19pbnB1dF9ncixjb21icF9zaWdfZ3IpKSwKICBdCmNvbG5hbWVzKG92ZXJsYXBwaW5nLmNvbWJwKSA8LSBwYXN0ZTAoImNvbWJwXyIsIGNvbG5hbWVzKG92ZXJsYXBwaW5nLmNvbWJwKSkKCm92ZXJsYXBwaW5nLnJlc3VsdHMgPC0gY2JpbmQoCiAgb3ZlcmxhcHBpbmcucmVzdWx0cywgb3ZlcmxhcHBpbmcuY29tYnAKKQoKb3ZlcmxhcHBpbmcucmVzdWx0cy51bmlxdWUgPC0gb3ZlcmxhcHBpbmcucmVzdWx0cyAlPiUKICBncm91cF9ieShpbnB1dFJlZ2lvbikgJT4lCiAgZmlsdGVyKGNvbWJwX3pfc2lkYWtfcCA9PSBtaW4oY29tYnBfel9zaWRha19wKSkKCgp3cml0ZS5jc3YoCiAgb3ZlcmxhcHBpbmcucmVzdWx0cy51bmlxdWUsCiAgcGFzdGUwKGRpci5yZXN1bHQuY29tcCwgIm1ldGFfYW5hbHlzaXNfb3ZfY29tYl9wLmNzdiIpLAogIHJvdy5uYW1lcyA9IEZBTFNFCikKCgp3cml0ZS5jc3YoCiAgb3ZlcmxhcHBpbmcucmVzdWx0cy51bmlxdWUgJT4lIGRwbHlyOjpmaWx0ZXIoc21va2VfYmkgPT0gMCAmIGNyb3NzSHliX2JpID09IDApLAogIHBhc3RlMChkaXIucmVzdWx0LmNvbXAsICJtZXRhX2FuYWx5c2lzX25vX2Nyb3NzSHliX3Ntb2tpbmdfb3ZfY29tYl9wLmNzdiIpLAogIHJvdy5uYW1lcyA9IEZBTFNFCikKCgpsaW5lYXJfc2lnX2lucHV0X25vX2Nyb3NzSHliX3Ntb2tpbmdfZ3IgPC0gbGluZWFyX3NpZyAlPiUgCiAgZHBseXI6OmZpbHRlcihzbW9rZV9iaSA9PSAwICYgY3Jvc3NIeWJfYmkgPT0gMCkgJT4lIAogIHRpZHlyOjpzZXBhcmF0ZSgiaW5wdXRSZWdpb24iLGMoImNocm9tIiwic3RhcnQiLCJlbmQiKSkgJT4lCiAgbWFrZUdSYW5nZXNGcm9tRGF0YUZyYW1lKCkKbGluZWFyX3NpZ19pbnB1dF9ub19jcm9zc0h5Yl9zbW9raW5nX2dyCmBgYAoKIyMjIyBDcmVhdGUgVmVubiBEaWFncmFtCgpgYGB7UiBDaElQcGVha0Fubm9fbGliLCBtZXNzYWdlID0gRkFMU0UsIHJlc3VsdHMgPSAiaGlkZSJ9CmxpYnJhcnkoQ2hJUHBlYWtBbm5vKQpsaWJyYXJ5KGdncGxvdDIpCmBgYAoKYGBge1IgQ2hJUHBlYWtBbm5vfQptZXRob2RzICAgICAgPC0gYygibGluZWFyIiwgImNvbWJwIikKbWV0aG9kc0xhYmVsIDwtIGMoImNvTWV0aERNUiBsaW5lYXIiLCAiY29tYnAiKQoKCm4gPC0gbGVuZ3RoKG1ldGhvZHMpCgpnZ19jb2xvcl9odWUgPC0gZnVuY3Rpb24obil7CiAgaHVlcyA9IHNlcSgxNSwgMzc1LCBsZW5ndGggPSBuICsgMSkKICBoY2woaCA9IGh1ZXMsIGwgPSA2NSwgYyA9IDEwMClbMTpuXQp9Cgpjb2xzID0gZ2dfY29sb3JfaHVlKG4pCgpyYW5nZXMubGlzdCA8LSBsaXN0KGxpbmVhcl9zaWdfaW5wdXRfbm9fY3Jvc3NIeWJfc21va2luZ19nciwgY29tYnBfc2lnX2dyKSAKCiMgb3ZlcmxhcCBmb3IgMSByZXBldGl0aW9uCnAgPC0gbWFrZVZlbm5EaWFncmFtKAogIHJhbmdlcy5saXN0LAogIE5hbWVPZlBlYWtzID0gbWV0aG9kc0xhYmVsWzE6bl0sCiAgdG90YWxUZXN0ID0gMzcxNTksIAogIGJ5ID0gInJlZ2lvbiIsCiAgbWFpbiA9IHBhc3RlMCgiICIpLAogIGNvbCA9IGMoIiM0NDAxNTRmZiIsICcjMjE5MDhkZmYnKSwKICBmaWxsID0gYyhhbHBoYSgiIzQ0MDE1NGZmIiwwLjMpLCBhbHBoYSgnIzIxOTA4ZGZmJywwLjMpKSwKICBjZXggPSAxLAogIGZvbnRmYW1pbHkgPSAic2FucyIsCiAgY2F0LmNleCA9IDEsCiAgY2F0LmRlZmF1bHQucG9zID0gIm91dGVyIiwKICBjYXQucG9zID0gYygxODAsIDE4MCksCiAgY2F0LmRpc3QgPSBjKC0wLjA1NSwgLTAuMDU1KSwKICBjYXQuZm9udGZhbWlseSA9ICJzYW5zIiwKICBjYXQuY29sID0gYygiIzQ0MDE1NGZmIiwgJyMyMTkwOGRmZicpKQpwcmludChwKQpgYGAKCmBgYHtSLCBtZXNzYWdlID0gRkFMU0UsIHJlc3VsdHMgPSAiaGlkZSJ9CnBkZigKICBmaWxlID0gcGFzdGUwKGRpci5yZXN1bHQuY29tcCwidmVubl9jb01ldGhETVJfbGluZWFyX3ZzX2NvbWJwLnBkZiIpLAogIHdpZHRoID0gNSwgaGVpZ2h0ID0gNQopIAptYWtlVmVubkRpYWdyYW0oCiAgcmFuZ2VzLmxpc3QsCiAgTmFtZU9mUGVha3MgPSBtZXRob2RzTGFiZWxbMTpuXSwKICB0b3RhbFRlc3QgPSAzNzE1OSwgCiAgYnkgPSAicmVnaW9uIiwKICBtYWluID0gcGFzdGUwKCIgIiksCiAgY29sID0gYygiIzQ0MDE1NGZmIiwgJyMyMTkwOGRmZicpLAogIGZpbGwgPSBjKGFscGhhKCIjNDQwMTU0ZmYiLDAuMyksIGFscGhhKCcjMjE5MDhkZmYnLDAuMykpLAogIGNleCA9IDEsCiAgZm9udGZhbWlseSA9ICJzYW5zIiwKICBjYXQuY2V4ID0gMSwKICBjYXQuZGVmYXVsdC5wb3MgPSAib3V0ZXIiLAogIGNhdC5wb3MgPSBjKDE4MCwgMTgwKSwKICBjYXQuZGlzdCA9IGMoLTAuMDU1LCAtMC4wNTUpLAogIGNhdC5mb250ZmFtaWx5ID0gInNhbnMiLAogIGNhdC5jb2wgPSBjKCIjNDQwMTU0ZmYiLCAnIzIxOTA4ZGZmJykpCmRldi5vZmYoKQpgYGAKCiMgTWV0YS1hbmFseXNpcyBTaW5nbGUtY3BncwoKIyMgSW1wb3J0IGRhdGFzZXRzIGFuZCBwcmUtcHJvY2VzcyBmb3IgZWFjaCBjb2hvcnQgCgpgYGB7UiwgZXZhbCA9IEZBTFNFfQpsaWJyYXJ5KGRwbHlyKQpkaXIuY3JlYXRlKGRhdGEuZmluYWwscmVjdXJzaXZlID0gVFJVRSxzaG93V2FybmluZ3MgPSBGQUxTRSkKcmVzdWx0cy5maWxlcyA8LSBkaXIoIkRBVEFTRVRTLyIsCiAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAic2luZ2xlX2NwZ19wVmFsX2RmLmNzdiIsCiAgICAgICAgICAgICAgICAgICAgIHJlY3Vyc2l2ZSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgIGZ1bGwubmFtZXMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICBpZ25vcmUuY2FzZSA9IFRSVUUpCgpmb3IoaSBpbiByZXN1bHRzLmZpbGVzKXsKICBkYXRhIDwtIHJlYWRyOjpyZWFkX2NzdihpKQogIGRhdGFzZXQgPC0gdW5saXN0KHN0cmluZ3I6OnN0cl9zcGxpdChpLCIvL3wvIikpWzJdICAlPiUgYXMuY2hhcmFjdGVyKCkKICBhdXggPC0gcGFzdGUwKGRhdGFzZXQsYygiX2VzdGltYXRlIiwgIl9zZSIsICJfcFZhbHVlIiwgIl9mZHIiKSkKICBjb2xuYW1lcyhkYXRhKSA8LSBjKCJjcGciLCBhdXgpCiAgYXNzaWduKGRhdGFzZXQsZGF0YSkKfQpgYGAKCiMjIENyZWF0ZSBhIG1lcmdlZCBmaW5hbCBkYXRhc2V0IApgYGB7UiwgZXZhbCA9IEZBTFNFfQpjb2hvcnRfbHMgPC0gbGlzdCgKICBHYXNwYXJvbmkgPSBHQVNQQVJPTkksCiAgTG9uZG9uX1BGQyA9IExPTkRPTiwKICBNdFNpbmFpID0gTXRTaW5haSwKICBST1NNQVAgPSBST1NNQVAKKQoKIyMjIG91dGVyIGpvaW4gaW5wdXQgcmVnaW9uCm11bHRpX2NvaG9ydHMgPC0gUmVkdWNlKAogIGZ1bmN0aW9uKHgseSwgLi4uKSBtZXJnZSh4LCB5LCBieSA9ICJjcGciLCBhbGwgPSBUUlVFLCAuLi4pLAogIGNvaG9ydF9scwopICNkaW06IDQzNzcxMyAxNwpkaW0obXVsdGlfY29ob3J0cykKYGBgCgojIyBNZXRhIGFuYWx5c2lzIApgYGB7UiwgZXZhbCA9IEZBTFNFfQojIyMgY2FsY3VsYXRlIG1ldGEgYW5hbHlzaXMgeiBzY29yZXMgYW5kIHAgdmFsdWVzCmxpYnJhcnkobWV0YSkKCmRvUGFyYWxsZWw6OnJlZ2lzdGVyRG9QYXJhbGxlbChjb3JlcyA9IHBhcmFsbGVsOjpkZXRlY3RDb3JlcygpLzIpCm1ldGFfZGYgPC0gcGx5cjo6YWRwbHkoLmRhdGEgPSBtdWx0aV9jb2hvcnRzLCAKICAgICAgICAgICAgICAgICAgICAgICAubWFyZ2lucyA9IDEsIAogICAgICAgICAgICAgICAgICAgICAgIC5mdW4gPSAgZnVuY3Rpb24ocm93T25lX2RmKXsKICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgZXN0IDwtIHJvd09uZV9kZltncmVwKCJlc3RpbWF0ZSIsY29sbmFtZXMocm93T25lX2RmKSldICU+JSBhcy5udW1lcmljCiAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA8LSAgcGFzdGUoaWZlbHNlKAogICAgICAgICAgICAgICAgICAgICAgICAgICBpcy5uYShlc3QpLCAiLiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShlc3QgPiAwLCAiKyIsICItIikKICAgICAgICAgICAgICAgICAgICAgICAgICksY29sbGFwc2UgPSAiIikKICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgc2UgPC0gcm93T25lX2RmW2dyZXAoInNlIixjb2xuYW1lcyhyb3dPbmVfZGYpKV0gJT4lIGFzLm51bWVyaWMKICAgICAgICAgICAgICAgICAgICAgICAgIGNvaG9ydCA8LSBnc3ViKCJfc2UiLCIiLGdyZXAoInNlIixjb2xuYW1lcyhyb3dPbmVfZGYpLHZhbHVlID0gVCkpCiAgICAgICAgICAgICAgICAgICAgICAgICByb3dPbmVfcmVmb3JtX2RmIDwtIGRhdGEuZnJhbWUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvaG9ydCA9IGNvaG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZXN0ID0gZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZSA9IHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UKICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgZiA8LSBtZXRhZ2VuKAogICAgICAgICAgICAgICAgICAgICAgICAgICBURSA9IGVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VURSA9IHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gcm93T25lX3JlZm9ybV9kZgogICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICB0aWJibGU6OnRpYmJsZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgY3BnID0gcm93T25lX2RmJGNwZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgZXN0aW1hdGUgPSBmJFRFLmZpeGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZSA9IGYkc2VURS5maXhlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcFZhbC5maXhlZCA9IGYkcHZhbC5maXhlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcFZhbC5yYW5kb20gPSBmJHB2YWwucmFuZG9tLAogICAgICAgICAgICAgICAgICAgICAgICAgICBwVmFsUSA9IGYkcHZhbC5RLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSBkaXJlY3Rpb24KICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICB9ICAsIC5wcm9ncmVzcyA9ICJ0aW1lIiwKICAgICAgICAgICAgICAgICAgICAgICAucGFyYWxsZWwgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgIC5pZCA9IE5VTEwKKQoKIyMjIGNyZWF0ZSBmaW5hbCBwVmFsCm1ldGFfZGYkcFZhbC5maW5hbCA8LSBpZmVsc2UoCiAgbWV0YV9kZiRwVmFsUSA+IDAuMDUsIG1ldGFfZGYkcFZhbC5maXhlZCwgbWV0YV9kZiRwVmFsLnJhbmRvbQopCgojIyMgY2FsY3VsYXRlIGZkcgptZXRhX2RmJGZkciA8LSBwLmFkanVzdChtZXRhX2RmJHBWYWwuZmluYWwsIG1ldGhvZCA9ICJmZHIiKQoKIyMjIG9yZGVyIG1ldGFfZGYKbWV0YV9maW5hbF9kZiA8LSBtZXRhX2RmWywgYyhncmVwKCJfIixjb2xuYW1lcyhtZXRhX2RmKSxpbnZlcnQgPSBUKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwKCJfIixjb2xuYW1lcyhtZXRhX2RmKSxpbnZlcnQgPSBGKSldCm1ldGFfZmluYWxfb3JkZXJlZF9kZiA8LSBtZXRhX2ZpbmFsX2RmW29yZGVyKG1ldGFfZmluYWxfZGYkcFZhbC5maW5hbCksXQpgYGAKCiMjIEFkZCBhbm5vdGF0aW9uIHRvIGlucHV0IGNwZ3MKYGBge1IsIGV2YWwgPSBGQUxTRX0KbGlicmFyeShzZXNhbWUpCnByb2Jlcy5pbmZvIDwtIHNlc2FtZURhdGFHZXQoIkhNNDUwLmhnMTkubWFuaWZlc3QiKQpwcm9iZXMuaW5mbyA8LSBwcm9iZXMuaW5mb1ttZXRhX2ZpbmFsX29yZGVyZWRfZGYkY3BnICU+JSBhcy5jaGFyYWN0ZXIoKV0gJT4lIGFzLmRhdGEuZnJhbWUgJT4lIGRwbHlyOjpzZWxlY3QoYygic2VxbmFtZXMiLCJzdGFydCIsImVuZCIpKQoKcmVzdWx0X2Fubm90X2RmIDwtIG1lcmdlKAogIHkgPSBtZXRhX2ZpbmFsX29yZGVyZWRfZGYsCiAgeCA9IHByb2Jlcy5pbmZvLAogIGJ5LnkgPSAiY3BnIiwKICBieS54ID0gInJvdy5uYW1lcyIsCiAgYWxsLnkgPSBUUlVFLAogIHNvcnQgPSBGQUxTRQopCgpjb2xuYW1lcyhyZXN1bHRfYW5ub3RfZGYpWzFdIDwtICJjcGciCiMjIyBmaW5hbCByYXcgZGF0YQp3cml0ZS5jc3YoCiAgcmVzdWx0X2Fubm90X2RmICAlPiUgYXMuZGF0YS5mcmFtZSgpLAogIHBhc3RlMChkYXRhLmZpbmFsLCAibWV0YV9hbmFseXNpc19zaW5nbGVfY3BnX2RmLmNzdiIpLAogIHJvdy5uYW1lcyA9IEZBTFNFCikKYGBgCgoKYGBge1IsIGV2YWwgPSBGQUxTRSwgaW5jbHVkZSA9IEZBTFNFfQoKIyMgUHJlcGFyZSBkYXRhc2V0IGZvciBjb21iLXAKcmVzdWx0X2Zvcl9jb21icF9kZiA8LSByZXN1bHRfYW5ub3RfZGZbCiAgLCBjKCJzZXFuYW1lcyIsICJzdGFydCIsICJlbmQiLCAicFZhbC5maW5hbCIpCl0KY29sbmFtZXMocmVzdWx0X2Zvcl9jb21icF9kZilbNF0gPC0gInBWYWx1ZSIKY29sbmFtZXMocmVzdWx0X2Zvcl9jb21icF9kZilbMV0gPC0gImNociIKCgp3cml0ZS5jc3YoCiAgcmVzdWx0X2Zvcl9jb21icF9kZiAlPiUgYXMuZGF0YS5mcmFtZSgpLAogIHBhc3RlMChkYXRhLmZpbmFsLCAibWV0YV9hbmFseXNpc19zaW5nbGVfY3BnX2RmX2Zvcl9jb21icC5jc3YiKSwKICByb3cubmFtZXMgPSBGQUxTRQopCmBgYAoKCgpgYGB7UiwgZXZhbCA9IEZBTFNFLCBpbmNsdWRlID0gRkFMU0V9CgojIyBDb21wYXJlIHJlc3VsdHMgd2l0aCBzbWl0aCB0b3AgMTAKc21pdGhUb3AxMCA8LSBjKAogICJjZzIyODY3ODE2IiwgImNnMDY5NzcyODUiLCAiY2cwNTc4MzM4NCIsICJjZzA3MzQ5ODE1IiwgImNnMjE4MDYyNDIiLAogICJjZzAzODM0NzY3IiwgImNnMTM5MzU1NzciLCAiY2cyNzA3ODg5MCIsICJjZzIyOTYyMTIzIiwgImNnMjYxOTk4NTciCikKCmNvbG5hbWVzKHJlc3VsdF9hbm5vdF9kZilbMV0gPC0gImNwZyIKCnJlc3VsdF9zbWl0aFRvcDEwIDwtIHJlc3VsdF9hbm5vdF9kZlttYXRjaChzbWl0aFRvcDEwLCByZXN1bHRfYW5ub3RfZGYkY3BnKSxdCnJlc3VsdF9zbWl0aFRvcDEwIDwtIHJlc3VsdF9zbWl0aFRvcDEwW2NvbXBsZXRlLmNhc2VzKHJlc3VsdF9zbWl0aFRvcDEwJGNwZyksXQoKd3JpdGUuY3N2KAogIHJlc3VsdF9zbWl0aFRvcDEwICU+JSBhcy5kYXRhLmZyYW1lKCksCiAgcGFzdGUwKGRhdGEuZmluYWwsICJtZXRhX2FuYWx5c2lzX3NpbmdsZV9jcGdfZGZfc21pdGhUb3AxMC5jc3YiKSwKICByb3cubmFtZXMgPSBGQUxTRQopCmBgYAoKCiMjIERlbGV0ZSBjcm9zcy1oeWJyaWRpemluZyBhbmQgc21va2luZyBwcm9iZXMgZnJvbSBzaWcgcHJvYmVzIApgYGB7UiwgZXZhbCA9IEZBTFNFfQojIyMgRXhjbHVkZSBub24tc2lnbmlmaWNhbnQgcHJvYmVzCnJlc3VsdF9hbm5vdF9zaWdfZGYgPC0gcmVzdWx0X2Fubm90X2RmICU+JSBmaWx0ZXIoZmRyIDwgMC4wNSkgI2RpbTozOTc5IDI0Cgp3cml0ZS5jc3YoCiAgICByZXN1bHRfYW5ub3Rfc2lnX2RmICU+JSBhcy5kYXRhLmZyYW1lKCksCiAgICBwYXN0ZTAoZGF0YS5maW5hbCwgIm1ldGFfYW5hbHlzaXNfc2luZ2xlX2NwZ19zaWdfZGYuY3N2IiksCiAgICByb3cubmFtZXMgPSBGQUxTRQopCgojIyMgR2V0IGNyb3NzaHlicmRpemluZyBwcm9iZXMKbGlicmFyeShFeHBlcmltZW50SHViKQoKZWggPSBFeHBlcmltZW50SHViKCkKcXVlcnkoZWgsICJETVJjYXRlIikKY3Jvc3NoeWIgPC0gZWhbWyJFSDMxMjkiXV0KCgojIyMgR2V0IHNpZ25pZmljYW50IHNtb2tpbmcgcHJvYmVzCnNtb2tpbmcuZmlsZSA8LSAiaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wbWMvYXJ0aWNsZXMvUE1DNTI2NzMyNS9iaW4vTklITVM4MTcyNzMtc3VwcGxlbWVudC0wMDE1MDZfLV9TdXBwbGVtZW50YWxfVGFibGVzLnhsc3giCgppZighZmlsZS5leGlzdHMoYmFzZW5hbWUoc21va2luZy5maWxlKSkpIGRvd25sb2FkZXI6OmRvd25sb2FkKHNtb2tpbmcuZmlsZSxiYXNlbmFtZShzbW9raW5nLmZpbGUpKQoKc21va2luZyA8LSByZWFkeGw6OnJlYWRfeGxzeCgKICAgIGJhc2VuYW1lKHNtb2tpbmcuZmlsZSksCiAgICBzaGVldCA9ICIwMiIsCiAgICBza2lwID0gMgopCnNtb2tpbmcuc2lnLnByb2JlcyA8LSBzbW9raW5nICU+JSBkcGx5cjo6ZmlsdGVyKGBQLXZhbHVlYCA8IDEqMTBeKC03KSkgJT4lIHB1bGwoIlByb2JlIElEIikKCgojIyMgRXhjbHVkZSBjcm9zcy1oeWJyaWRpemluZyBhbmQgc21va2luZyBwcm9iZXMKcmVzdWx0X2Fubm90X3NpZ19kZiRjcGcgPC0gYXMuY2hhcmFjdGVyKHJlc3VsdF9hbm5vdF9zaWdfZGYkY3BnKQoKcmVzdWx0X2Fubm90X3NpZ19ub19jcm9zc0h5Yl9zbW9raW5nX2RmIDwtIHJlc3VsdF9hbm5vdF9zaWdfZGZbCiAgICAhKHJlc3VsdF9hbm5vdF9zaWdfZGYkY3BnICVpbiUgYyhjcm9zc2h5Yiwgc21va2luZy5zaWcucHJvYmVzKSksCl0gI2RpbTogMzc1MSAyOAoKIyMjIEFkZCBhbm5vdGF0aW9uCmxpYnJhcnkoY29NZXRoRE1SKQoKcmVzdWx0X2Fubm90X3NpZ19ub19jcm9zc0h5Yl9zbW9raW5nX2RmJGNocm9tIDwtIGFzLmNoYXJhY3RlcigKICAgIHJlc3VsdF9hbm5vdF9zaWdfbm9fY3Jvc3NIeWJfc21va2luZ19kZiRzZXFuYW1lcwopCgpyZXN1bHRfZmluYWwgPC0gQW5ub3RhdGVSZXN1bHRzKHJlc3VsdF9hbm5vdF9zaWdfbm9fY3Jvc3NIeWJfc21va2luZ19kZikKCnJlc3VsdF9maW5hbF9vcmRlcmVkIDwtIHJlc3VsdF9maW5hbFsKICAgICxjKAogICAgICAgIDE6NCwgMzA6MzMsIDU6MTIsCiAgICAgICAgZ3JlcCgiR0FTUEFST05JIiwgY29sbmFtZXMocmVzdWx0X2ZpbmFsKSwgaWdub3JlLmNhc2UgPSBUUlVFLCBpbnZlcnQgPSBGQUxTRSksCiAgICAgICAgZ3JlcCgiTE9ORE9OIiwgY29sbmFtZXMocmVzdWx0X2ZpbmFsKSwgaWdub3JlLmNhc2UgPSBUUlVFLCBpbnZlcnQgPSBGQUxTRSksCiAgICAgICAgZ3JlcCgiTVRTSU5BSSIsIGNvbG5hbWVzKHJlc3VsdF9maW5hbCksIGlnbm9yZS5jYXNlID0gVFJVRSwgaW52ZXJ0ID0gRkFMU0UpLAogICAgICAgIGdyZXAoIlJPU01BUCIsIGNvbG5hbWVzKHJlc3VsdF9maW5hbCksIGlnbm9yZS5jYXNlID0gVFJVRSwgaW52ZXJ0ID0gRkFMU0UpCiAgICApCl0KCndyaXRlLmNzdigKICAgIHJlc3VsdF9maW5hbF9vcmRlcmVkICU+JSBhcy5kYXRhLmZyYW1lKCksCiAgICBwYXN0ZTAoZGF0YS5maW5hbCwgIm1ldGFfYW5hbHlzaXNfc2luZ2xlX2NwZ19zaWdfbm9fY3Jvc3NIeWJfc21va2luZ19kZi5jc3YiKSwKICAgIHJvdy5uYW1lcyA9IEZBTFNFCikKCmBgYAoKYGBge1J9CnJlYWRyOjpyZWFkX2NzdigKICBwYXN0ZTAoZGF0YS5maW5hbCwgIm1ldGFfYW5hbHlzaXNfc2luZ2xlX2NwZ19zaWdfbm9fY3Jvc3NIeWJfc21va2luZ19kZi5jc3YiKSwKICBjb2xfdHlwZXMgPSByZWFkcjo6Y29scygpCikKYGBgCgojIFJlc3VsdHMgZnJvbSBzaW5nbGUgQ1BHIGFuYWx5c2lzIGFuZCBETVIgYW5hbHlzaXMKCgpgYGB7UiwgaW5jbHVkZSA9IEZBTFNFLCBldmFsID0gRkFMU0V9CgojIyBBZGRpbmcgc2lnbmlmaWNhbnQgcHJvYmVzIGZyb20gc2luZ2xlIGNwZyBhbmFseXNpcyB0byBETVIgYW5hbHlzaXMKCm92ZXJsYXBwaW5nLnJlc3VsdHMgPC0gIHJlYWRyOjpyZWFkX2NzdigKICBwYXN0ZTAoZGlyLnJlc3VsdC5jb21wLCAibWV0YV9hbmFseXNpc19vdl9jb21iX3AuY3N2IiksCiAgY29sX3R5cGVzID0gcmVhZHI6OmNvbHMoKQopCnByb2Jlcy5pbi5hbGwucmVnaW9ucyA8LSBjb01ldGhETVI6OkdldENwR3NJbkFsbFJlZ2lvbigKICBvdmVybGFwcGluZy5yZXN1bHRzJGlucHV0UmVnaW9uCikKCnNpbmdsZS5jcGcucmVzdWx0cyA8LSByZWFkcjo6cmVhZF9jc3YoCiAgIm1ldGFfYW5hbHlzaXNfc2luZ2xlX2NwZ19yZXN1bHRzL21ldGFfYW5hbHlzaXNfc2luZ2xlX2NwZ19zaWdfbm9fY3Jvc3NIeWJfc21va2luZ19kZi5jc3YiLAogIGNvbF90eXBlcyA9IHJlYWRyOjpjb2xzKCkKICApCnNpbmdsZS5jcGcucmVzdWx0cy5wcm9iZXMgPC0gc2luZ2xlLmNwZy5yZXN1bHRzICU+JSBwdWxsKGNwZykgJT4lIGFzLmNoYXJhY3RlcgoKb3ZlcmxhcHBpbmcucmVzdWx0cyRQcm9iZXNfc2luZ2xlX2NwZ19hbmFseXNpc19mZHJfMF8wNSA8LSBsYXBwbHkocHJvYmVzLmluLmFsbC5yZWdpb25zLCBmdW5jdGlvbih4KXsKICBwYXN0ZSh4W3ggJWluJSBzaW5nbGUuY3BnLnJlc3VsdHMucHJvYmVzXSxjb2xsYXBzZSA9ICI7IikKfSkgJT4lIHVubGlzdAoKd3JpdGUuY3N2KAogIG92ZXJsYXBwaW5nLnJlc3VsdHMsCiAgcGFzdGUwKGRpci5yZXN1bHQuY3BnLnZzLmRtciwgIm1ldGFfYW5hbHlzaXNfc2lnX2FkZF9jcm9zc0h5Yl9vdl9jb21iX3Bfd2l0aF9zaWdfc2luZ2xlX2NwZ3MuY3N2IiksCiAgcm93Lm5hbWVzID0gRkFMU0UKKQoKd3JpdGUuY3N2KAogIG92ZXJsYXBwaW5nLnJlc3VsdHMgJT4lIGRwbHlyOjpmaWx0ZXIoc21va2VfYmkgPT0gMCAmIGNyb3NzSHliX2JpID09IDApLAogIHBhc3RlMChkaXIucmVzdWx0LmNwZy52cy5kbXIsICJtZXRhX2FuYWx5c2lzX3NpZ19ub19jcm9zc0h5Yl9zbW9raW5nX292X2NvbWJfcF93aXRoX3NpZ19zaW5nbGVfY3Bncy5jc3YiKSwKICByb3cubmFtZXMgPSBGQUxTRQopCmBgYAoKYGBge1J9CnJlYWRyOjpyZWFkX2NzdigKICBwYXN0ZTAoZGlyLnJlc3VsdC5jcGcudnMuZG1yLCAibWV0YV9hbmFseXNpc19zaWdfbm9fY3Jvc3NIeWJfc21va2luZ19vdl9jb21iX3Bfd2l0aF9zaWdfc2luZ2xlX2NwZ3MuY3N2IiksCiAgY29sX3R5cGVzID0gcmVhZHI6OmNvbHMoKQopCmBgYAoKIyMgVmVubiBwbG90IG9mIHNpbmdsZSBjcGcgc2lnIHZzLiBwcm9iZXMgaW4gRE1ScwoKYGBge1J9Cm92ZXJsYXBwaW5nLnJlc3VsdHMgPC0gIHJlYWRyOjpyZWFkX2NzdihwYXN0ZTAoZGlyLnJlc3VsdC5jb21wLCAibWV0YV9hbmFseXNpc19ub19jcm9zc0h5Yl9zbW9raW5nX292X2NvbWJfcC5jc3YiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF90eXBlcyA9IHJlYWRyOjpjb2xzKCkpCnByb2Jlcy5pbi5hbGwucmVnaW9ucyA8LSBjb01ldGhETVI6OkdldENwR3NJbkFsbFJlZ2lvbihvdmVybGFwcGluZy5yZXN1bHRzJGlucHV0UmVnaW9uKQpwcm9iZXMuaW4uYWxsLnJlZ2lvbnMgPC0gcHJvYmVzLmluLmFsbC5yZWdpb25zICU+JSB1bmlxdWUgJT4lIHVubGlzdCAKCnNpbmdsZS5jcGcucmVzdWx0cyA8LSByZWFkcjo6cmVhZF9jc3YoCiAgIm1ldGFfYW5hbHlzaXNfc2luZ2xlX2NwZ19yZXN1bHRzL21ldGFfYW5hbHlzaXNfc2luZ2xlX2NwZ19zaWdfbm9fY3Jvc3NIeWJfc21va2luZ19kZi5jc3YiLAogIGNvbF90eXBlcyA9IHJlYWRyOjpjb2xzKCkKKSAKCnNpbmdsZS5jcGcucmVzdWx0cy5wcm9iZXMgPC0gc2luZ2xlLmNwZy5yZXN1bHRzICU+JSBwdWxsKGNwZykgJT4lIGFzLmNoYXJhY3RlciAKCiMgbGlicmFyeQpsaWJyYXJ5KFZlbm5EaWFncmFtKQpsaWJyYXJ5KGdncGxvdDIpCgojIE1ha2UgdGhlIHBsb3QKdmVubiA8LSB2ZW5uLmRpYWdyYW0oCiAgeCA9IGxpc3QoCiAgICBwcm9iZXMuaW4uYWxsLnJlZ2lvbnMgJT4lIHVuaXF1ZSAsICAgIAogICAgc2luZ2xlLmNwZy5yZXN1bHRzLnByb2JlcyAlPiUgdW5pcXVlICAKICApLCAKICBjYXRlZ29yeS5uYW1lcyA9IGMoIkRNUiBhbmFseXNpcyBwcm9iZXMiICwgIlNpbmdsZSBjcGcgYW5hbHlzaXMgcHJvYmVzIiApLAogIGZpbGVuYW1lID0gZmlsZS5wYXRoKGRpci5yZXN1bHQuY3BnLnZzLmRtciwgJy92ZW5uX0RNUl9jcGcucG5nJyksCiAgb3V0cHV0ID0gVFJVRSAsCiAgaW1hZ2V0eXBlID0gInBuZyIgLAogIGhlaWdodCA9IDcwMCAsCiAgd2lkdGggPSA3MDAgLAogIHJlc29sdXRpb24gPSAzMDAsCiAgY29tcHJlc3Npb24gPSAibHp3IiwKICBsd2QgPSAxLAogIGNvbCA9IGMoIiM0NDAxNTRmZiIsICcjMjE5MDhkZmYnKSwKICBmaWxsID0gYyhhbHBoYSgiIzQ0MDE1NGZmIiwwLjMpLCBhbHBoYSgnIzIxOTA4ZGZmJywwLjMpKSwKICBjZXggPSAwLjUsCiAgY2F0LmNleCA9IDAuMywKICBjYXQuZGVmYXVsdC5wb3MgPSAib3V0ZXIiLAogIGNhdC5wb3MgPSBjKDAsIDE4MCksCiAgY2F0LmRpc3QgPSBjKDAuMDEsIDAuMDEpCikKYGBgCgpgYGB7UixzaG93ID0gRkFMU0UsIGZpZy53aWR0aCA9IDUsIGZpZy5oZWlnaHQ9IDV9CiB2ZW5uLmRpYWdyYW0oCiAgeCA9IGxpc3QoCiAgICBwcm9iZXMuaW4uYWxsLnJlZ2lvbnMgJT4lIHVuaXF1ZSAsICAgIAogICAgc2luZ2xlLmNwZy5yZXN1bHRzLnByb2JlcyAlPiUgdW5pcXVlICAKICApLCAKICBjYXRlZ29yeS5uYW1lcyA9IGMoIkRNUiBhbmFseXNpcyBwcm9iZXMiICwgIlNpbmdsZSBjcGcgYW5hbHlzaXMgcHJvYmVzIiApLAogIGZpbGVuYW1lID0gTlVMTCwKICBvdXRwdXQgPSBUUlVFICwKICBpbWFnZXR5cGUgPSAicG5nIiAsCiAgaGVpZ2h0ID0gNzAwICwKICB3aWR0aCA9IDcwMCAsCiAgcmVzb2x1dGlvbiA9IDMwMCwKICBjb21wcmVzc2lvbiA9ICJsenciLAogIGx3ZCA9IDEsCiAgY29sID0gYygiIzQ0MDE1NGZmIiwgJyMyMTkwOGRmZicpLAogIGZpbGwgPSBjKGFscGhhKCIjNDQwMTU0ZmYiLDAuMyksIGFscGhhKCcjMjE5MDhkZmYnLDAuMykpLAogIGNleCA9IDEsCiAgY2F0LmNleCA9IDEsCiAgY2F0LmRlZmF1bHQucG9zID0gIm91dGVyIiwKICBjYXQucG9zID0gYygwLCAxODApLAogIGNhdC5kaXN0ID0gYygwLjAxLCAwLjAxKQopICU+JSBncmlkLmRyYXcoKQpgYGAKCiMgU2Vzc2lvbiBpbmZvcm1hdGlvbgpgYGB7Un0KZGV2dG9vbHM6OnNlc3Npb25faW5mbygpCmBgYAoKCg==