Acquiring TCGA ATAC-seq and RNA-seq data and importing into R data environment

Benjamin P. Berman, Tiago C. Silva

2020-12-08

Loading R libraries

library(readxl)
library(TCGAbiolinks)
library(SummarizedExperiment)
library(dplyr) # for pipe operator ("%>%") https://r4ds.had.co.nz/pipes.html
library(MultiAssayExperiment) # Version 1.17.2, version 1.14.0 is not working

To install the most updated version of MultiAssayExperiment run the code below

BiocManager::install("waldronlab/MultiAssayExperiment")

ATAC-Seq data

Check available files

readr::read_tsv(
  "https://gdc.cancer.gov/files/public/file/ATACseq-AWG_Open_GDC-Manifest.txt",
  col_types = readr::cols() # just to hide columns type information
)
## # A tibble: 47 x 4
##    id                  filename                         md5                 size
##    <chr>               <chr>                            <chr>              <dbl>
##  1 116ebba2-d284-485b… TCGA-ATAC_PanCancer_PeakSet.txt  dbcaa696c62a99c…  3.75e7
##  2 148b8d1e-a132-48f6… TCGA-ATAC_DataS1_DonorsAndStats… f424a4aa2184de6…  2.52e5
##  3 165a6103-8d8b-4e1e… MESO_bigWigs.tgz                 acd81af5c7ddbbc…  1.51e9
##  4 17bdb321-45cf-4476… TCGA-ATAC_DataS5_GWAS_v2.xlsx    2a8196fbda1736d…  1.00e6
##  5 26b96cd9-dce0-4340… COAD_bigWigs.tgz                 ef6a3e7f1a86e19…  8.94e9
##  6 26f78bd9-45f3-4468… TCGA-ATAC_PanCan_Raw_Counts.txt  f1270f619894cda…  1.24e9
##  7 2f27b5c3-73ce-4ddc… TGCT_bigWigs.tgz                 b31098961708e66…  2.06e9
##  8 340e5b6c-991f-42c2… TCGA-ATAC_DataS6_Footprinting_v… 62a823f620a4ddf…  1.95e7
##  9 3443e515-69b8-413d… TCGA-ATAC_DataS10_WGS-ATAC_v2_O… ed5836348d58b50…  8.93e5
## 10 38b8f311-f3a4-4746… TCGA-ATAC_Cancer_Type-specific_… c31893739baa05a…  6.33e8
## # … with 37 more rows

Get ESCA log2 norm counts and create a Summarized Experiment object

file <- "TCGA-ATAC_Cancer_Type-specific_Count_Matrices_log2norm_counts.zip"
query <- GDCquery_ATAC_seq(file.type = file)
GDCdownload(query,directory = "data") # 632 MB
zipfile <- dir(path = "data", recursive = TRUE, pattern = file, full.names = TRUE)
# which files are available ?
unzip(zipfile = zipfile,list = TRUE)
##                 Name    Length                Date
## 1   ACC_log2norm.txt  32638919 2018-09-13 14:17:00
## 2  BLCA_log2norm.txt  42768110 2018-09-13 14:17:00
## 3  BRCA_log2norm.txt 545044026 2018-09-13 14:18:00
## 4  CESC_log2norm.txt   9533539 2018-09-13 14:18:00
## 5  CHOL_log2norm.txt  15036030 2018-09-13 14:18:00
## 6  COAD_log2norm.txt 176995185 2018-09-13 14:18:00
## 7  ESCA_log2norm.txt  78072830 2018-09-13 14:18:00
## 8   GBM_log2norm.txt  27525009 2018-09-13 14:18:00
## 9  HNSC_log2norm.txt  30111019 2018-09-13 14:18:00
## 10 KIRC_log2norm.txt  56797520 2018-09-13 14:19:00
## 11 KIRP_log2norm.txt 169455430 2018-09-13 14:19:00
## 12  LGG_log2norm.txt  37244137 2018-09-13 14:19:00
## 13 LIHC_log2norm.txt  77559343 2018-09-13 14:19:00
## 14 LUAD_log2norm.txt 112606540 2018-09-13 14:19:00
## 15 LUSC_log2norm.txt  70292345 2018-09-13 14:19:00
## 16 MESO_log2norm.txt  21383986 2018-09-13 14:19:00
## 17 PCPG_log2norm.txt  31508947 2018-09-13 14:19:00
## 18 PRAD_log2norm.txt 105177572 2018-09-13 14:20:00
## 19 SKCM_log2norm.txt  47557119 2018-09-13 14:20:00
## 20 STAD_log2norm.txt  91832376 2018-09-13 14:20:00
## 21 TGCT_log2norm.txt  26620808 2018-09-13 14:20:00
## 22 THCA_log2norm.txt  49659622 2018-09-13 14:20:00
## 23 UCEC_log2norm.txt  48213655 2018-09-13 14:20:00
# Unzip file in the data folder
unzip(zipfile = zipfile, files = "ESCA_log2norm.txt",exdir = "data")

# read file
esca.peaks <- readr::read_tsv(
  file = "data/ESCA_log2norm.txt",
  col_types = readr::cols() # hide columns type inferred
) 

# create Summarized Experiment object
esca.peaks.se <- esca.peaks %>% 
  dplyr::select(-c("score","name")) %>% # Remove columns score and name
  makeSummarizedExperimentFromDataFrame()
rowRanges(esca.peaks.se)$score <- esca.peaks$score
rowRanges(esca.peaks.se)$name <- esca.peaks$name

# Map the ATAC-seq IDs ("ESCA_1E6AC686_96C2_46C...) to TCGA barcodes ("TCGA-IG-A51D-01A-31-A616-42")
gdc.file <- "https://api.gdc.cancer.gov/data/7a3d7067-09d6-4acf-82c8-a1a81febf72c"
samples.ids <- readr::read_tsv(gdc.file, col_types = readr::cols())
samples.ids$sample <- substr(samples.ids$Case_ID,1,16)
head(samples.ids)
## # A tibble: 6 x 6
##   bam_prefix        stanfordUUID    aliquot_id    Case_UUID    Case_ID   sample 
##   <chr>             <chr>           <chr>         <chr>        <chr>     <chr>  
## 1 BRCA-000CFD9F-AD… 000CFD9F-ADDF-… TCGA-A7-A13F… 2cf68894-16… TCGA-A7-… TCGA-A…
## 2 BRCA-000CFD9F-AD… 000CFD9F-ADDF-… TCGA-A7-A13F… 2cf68894-16… TCGA-A7-… TCGA-A…
## 3 PCPG-007124EC-1F… 007124EC-1F9B-… TCGA-RM-A68W… 1a1cf490-8b… TCGA-RM-… TCGA-R…
## 4 PCPG-007124EC-1F… 007124EC-1F9B-… TCGA-RM-A68W… 1a1cf490-8b… TCGA-RM-… TCGA-R…
## 5 STAD-00DFAA4D-DE… 00DFAA4D-DE64-… TCGA-BR-A4J1… e9a98a44-83… TCGA-BR-… TCGA-B…
## 6 STAD-00DFAA4D-DE… 00DFAA4D-DE64-… TCGA-BR-A4J1… e9a98a44-83… TCGA-BR-… TCGA-B…
colnames(esca.peaks.se) <- samples.ids$Case_ID[match(gsub("_","-",colnames(esca.peaks.se)),samples.ids$bam_prefix)]

# Since we have technical replicates we keep one of them
esca.peaks.se <- esca.peaks.se[,!duplicated(colnames(esca.peaks.se))]
esca.peaks.se
## class: RangedSummarizedExperiment 
## dim: 126935 18 
## metadata(0):
## assays(1): ''
## rownames: NULL
## rowData names(2): score name
## colnames(18): TCGA-IG-A51D-01A-31-A616-42 TCGA-LN-A9FQ-01A-11-A617-42
##   ... TCGA-IC-A6RE-01A-31-A616-42 TCGA-M9-A5M8-01A-31-A616-42
## colData names(0):

RNA-seq data

query.exp.hg38 <- GDCquery(
  project = "TCGA-ESCA", 
  data.category = "Transcriptome Profiling", 
  data.type = "Gene Expression Quantification", 
  workflow.type = "HTSeq - FPKM-UQ",
  sample.type = "Primary Tumor"
)
GDCdownload(query.exp.hg38, directory = "data") # 99 Mb

esca.rna <- GDCprepare(
  query = query.exp.hg38,
  directory = "data"
)
rownames(esca.rna) <- values(esca.rna)$external_gene_name
esca.rna
## class: RangedSummarizedExperiment 
## dim: 56602 161 
## metadata(1): data_release
## assays(1): HTSeq - FPKM-UQ
## rownames(56602): TSPAN6 TNMD ... LINC01144 AC007389.5
## rowData names(3): ensembl_gene_id external_gene_name
##   original_ensembl_gene_id
## colnames(161): TCGA-L5-A4OM-01A-11R-A260-31
##   TCGA-L5-A4OU-01A-11R-A28J-31 ... TCGA-JY-A93D-01A-11R-A38D-31
##   TCGA-JY-A93E-01A-11R-A37I-31
## colData names(141): barcode patient ... paper_GEA-CIN Integrated
##   Cluster - MKL-KNN-4 paper_GEA-CIN Integrated Cluster - MKL-KNN-7

Create a multiAssayExperiment object with all samples

Sample mapping table

# We need a table mapping each sample name (complete barcode - 28 characters) 
# in both datasets (RNA, ATAC) to the same patient (first 16 characters)
sampleMap <- S4Vectors::DataFrame(
  assay = factor(x = c(rep("RNA", ncol(esca.rna)),rep("ATAC", ncol(esca.peaks.se))),levels = c("RNA","ATAC")), 
  primary = c(colnames(esca.rna), colnames(esca.peaks.se)) %>% substr(1,16), 
  colname = c(colnames(esca.rna), colnames(esca.peaks.se))
)
sampleMap %>% as.data.frame %>% DT::datatable(options = list(scrollX = TRUE))

Samples metadata

colData <-  sampleMap$primary %>% unique %>% TCGAbiolinks:::colDataPrepare()
colData %>% as.data.frame %>% DT::datatable(options = list(scrollX = TRUE))
plyr::count(colData, c("primary_diagnosis","definition"))
##                            primary_diagnosis          definition freq
## 1                        Adenocarcinoma, NOS Primary solid Tumor   78
## 2           Basaloid squamous cell carcinoma Primary solid Tumor    1
## 3                    Mucinous adenocarcinoma Primary solid Tumor    1
## 4 Squamous cell carcinoma, keratinizing, NOS Primary solid Tumor    4
## 5               Squamous cell carcinoma, NOS Primary solid Tumor   78
## 6                     Tubular adenocarcinoma Primary solid Tumor    1
mae <- MultiAssayExperiment(
  experiments = ExperimentList(list(RNA = esca.rna,ATAC = esca.peaks.se)),
  colData = colData,
  sampleMap = sampleMap,
  metadata = list(),
  drops = list()
)
mae
## A MultiAssayExperiment object of 2 listed
##  experiments with user-defined names and respective classes.
##  Containing an ExperimentList class object of length 2:
##  [1] RNA: RangedSummarizedExperiment with 56602 rows and 161 columns
##  [2] ATAC: RangedSummarizedExperiment with 126935 rows and 18 columns
## Functionality:
##  experiments() - obtain the ExperimentList instance
##  colData() - the primary/phenotype DataFrame
##  sampleMap() - the sample coordination DataFrame
##  `$`, `[`, `[[` - extract colData columns, subset, or experiment
##  *Format() - convert into a long or wide DataFrame
##  assays() - convert ExperimentList to a SimpleList of matrices
##  exportClass() - save all data to files

Create a multiAssayExperiment object with matched samples

Sample mapping table

matched.samples <- intersect(colnames(esca.rna) %>% substr(1,16), colnames(esca.peaks.se) %>% substr(1,16))

# We need a table mapping each sample name (complete barcode - 28 characters) 
# in both datasets (RNA, ATAC) to the same patient (first 16 characters)
sampleMap <- S4Vectors::DataFrame(
  assay = factor(x = c(rep("RNA", ncol(esca.rna)),rep("ATAC", ncol(esca.peaks.se))),levels = c("RNA","ATAC")), 
  primary = c(colnames(esca.rna), colnames(esca.peaks.se)) %>% substr(1,16), 
  colname = c(colnames(esca.rna), colnames(esca.peaks.se))
)
sampleMap %>% as.data.frame %>% DT::datatable(options = list(scrollX = TRUE))

Samples metadata

colData <-  matched.samples %>% unique %>% TCGAbiolinks:::colDataPrepare()
colData %>% as.data.frame %>% DT::datatable(options = list(scrollX = TRUE))
plyr::count(colData, c("primary_diagnosis","definition"))
##              primary_diagnosis          definition freq
## 1          Adenocarcinoma, NOS Primary solid Tumor    6
## 2 Squamous cell carcinoma, NOS Primary solid Tumor   10
mae.matched <- MultiAssayExperiment(
  experiments = ExperimentList(list(
    RNA = esca.rna[,match(matched.samples,  colnames(esca.rna) %>% substr(1,16))],
    ATAC = esca.peaks.se[,match(matched.samples,  colnames(esca.peaks.se) %>% substr(1,16))]
    )
    ),
  colData = colData,
  sampleMap = sampleMap,
  metadata = list(),
  drops = list()
)
## harmonizing input:
##   removing 147 sampleMap rows with 'colname' not in colnames of experiments
mae.matched
## A MultiAssayExperiment object of 2 listed
##  experiments with user-defined names and respective classes.
##  Containing an ExperimentList class object of length 2:
##  [1] RNA: RangedSummarizedExperiment with 56602 rows and 16 columns
##  [2] ATAC: RangedSummarizedExperiment with 126935 rows and 16 columns
## Functionality:
##  experiments() - obtain the ExperimentList instance
##  colData() - the primary/phenotype DataFrame
##  sampleMap() - the sample coordination DataFrame
##  `$`, `[`, `[[` - extract colData columns, subset, or experiment
##  *Format() - convert into a long or wide DataFrame
##  assays() - convert ExperimentList to a SimpleList of matrices
##  exportClass() - save all data to files
# check samples are in the same order
assay(mae.matched,"RNA") %>% colnames() %>% substr(1,16) == assay(mae.matched,"ATAC") %>% colnames() %>% substr(1,16)
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [16] TRUE

Plot ATAC-seq and RNA-seq for linked enhancers-genes

Find enhancer overlapping ATAC-seq peaks

# we don't have RNA expression for all genes, let's remove them first
peak.to.gene.links.merged.gr <- peak.to.gene.links.merged.gr[peak.to.gene.links.merged.gr$Linked_Gene %in% rownames(assay(mae.matched,"RNA"))]
hits.enhancer.atac.peaks <- findOverlaps(peak.to.gene.links.merged.gr,mae.matched[["ATAC"]])

Heatmap plot

library(ComplexHeatmap)
## Loading required package: grid
## ========================================
## ComplexHeatmap version 2.4.3
## Bioconductor page: http://bioconductor.org/packages/ComplexHeatmap/
## Github page: https://github.com/jokergoo/ComplexHeatmap
## Documentation: http://jokergoo.github.io/ComplexHeatmap-reference
## 
## If you use it in published research, please cite:
## Gu, Z. Complex heatmaps reveal patterns and correlations in multidimensional 
##   genomic data. Bioinformatics 2016.
## 
## This message can be suppressed by:
##   suppressPackageStartupMessages(library(ComplexHeatmap))
## ========================================
library(circlize)
## ========================================
## circlize version 0.4.11
## CRAN page: https://cran.r-project.org/package=circlize
## Github page: https://github.com/jokergoo/circlize
## Documentation: https://jokergoo.github.io/circlize_book/book/
## 
## If you use it in published research, please cite:
## Gu, Z. circlize implements and enhances circular visualization
##   in R. Bioinformatics 2014.
## 
## This message can be suppressed by:
##   suppressPackageStartupMessages(library(circlize))
## ========================================

Heatmap ATAC-seq

# colors of the atac-seq data
pal_atac <- colorRampPalette(
  c(
    '#3361A5', '#248AF3', '#14B3FF', 
    '#88CEEF', '#C1D5DC', '#EAD397', 
    '#FDB31A','#E42A2A', '#A31D1D'
  )
)(100)

# Samples annotation
ha = HeatmapAnnotation(
  df = data.frame("Group" = mae.matched$primary_diagnosis),
  show_annotation_name = TRUE,
  col = list(
    Group = c(
      "Squamous cell carcinoma, NOS" =  "red", 
      "Adenocarcinoma, NOS" = "blue"
    )
  ),
  show_legend = TRUE,
  annotation_name_side = "left",
  annotation_name_gp = gpar(fontsize = 6)
)

# row z-score
# the scale function is applied over columns so we need to transpose the data
atac.mat.row.z.score <- atac.mat %>% t %>% scale %>% t 
col.zscore <- colorRamp2(seq(-2, 2, by = 4/99), pal_atac)

# rows.annot <- rowAnnotation(foo = anno_mark(at = c(1,18), labels = rownames(plot.atac)[c(1,18)]))

ht_atac <- Heatmap(
  matrix = atac.mat.row.z.score[1:1000,],
  name ="ATAC-seq log2(counts)\nz-score rowwise", 
  col = col.zscore,
  heatmap_legend_param = list(
    legend_width  = unit(3, "cm"),
    legend_direction = "horizontal",
    labels_gp = gpar(fontsize = 12), 
    title_gp = gpar(fontsize = 12)
  ),
  show_column_names = FALSE,
  cluster_columns = TRUE,
  show_row_names = FALSE,
  cluster_rows = TRUE, # cluster will be based on ATAC-seq
  row_title = " ATAC-seq peaks",
  top_annotation = ha,
  column_names_gp = gpar(fontsize = 8),
  row_names_gp = gpar(fontsize = 4),
  column_title_gp = gpar(fontsize = 12), 
  row_title_gp = gpar(fontsize = 12),
  use_raster = TRUE,
  raster_device = c("png"),
  raster_quality = 2
) 

Heatmap RNA-seq

# colors of the RNA-seq data

pal_rna <- colorRampPalette(
  c(
    "#352A86","#343DAE","#0262E0","#1389D2",
    "#2DB7A3","#A5BE6A","#F8BA43","#F6DA23","#F8FA0D"
  )
)(100)

# row z-score
# the scale function is applied over columns so we need to transpose the data
exp.mat.row.z.score <- exp.mat %>% t %>% scale %>% t 
col.zscore <- colorRamp2(seq(-2, 2, by = 4/99), pal_rna)

# Samples annotation
ha = HeatmapAnnotation(
  df = data.frame("Group" = mae.matched$primary_diagnosis),
  show_annotation_name = FALSE,
  col = list(
    Group = c(
      "Squamous cell carcinoma, NOS" =  "red", 
      "Adenocarcinoma, NOS" = "blue"
    )
  ),
  show_legend = TRUE,
  annotation_name_side = "right",
  annotation_name_gp = gpar(fontsize = 6)
)


# rows.annot <- rowAnnotation(foo = anno_mark(at = c(1,18), labels = rownames(plot.atac)[c(1,18)]))

ht_exp <- Heatmap(
  matrix = exp.mat.row.z.score[1:1000,],
  name ="RNA-seq FPKM-UQ\nz-score rowwise", 
  col = col.zscore,
  column_names_gp = gpar(fontsize = 8),
  show_column_names = F,
  heatmap_legend_param = list(
    legend_width  = unit(3, "cm"),
    legend_direction = "horizontal",
    labels_gp = gpar(fontsize = 12), 
    title_gp = gpar(fontsize = 12)
  ),
  show_row_names = FALSE,
  cluster_columns = FALSE,
  use_raster = TRUE,
  raster_device = c("png"),
  raster_quality = 2,
  cluster_rows = FALSE,
  row_title = "RNA-seq linked genes",
  row_title_side = "right",
  column_order = column_order(ht_atac),
  row_names_gp = gpar(fontsize = 4),
  top_annotation = ha,
  #width = unit(15, "cm"),
  column_title_gp = gpar(fontsize = 12), 
  row_title_gp = gpar(fontsize = 12)
) 

Draw Heatmap

draw(
  object = ht_atac + ht_exp,
  newpage = TRUE, 
  merge_legends = TRUE,
  column_title_gp = gpar(fontsize = 12, fontface = "bold"),
  heatmap_legend_side = "bottom",
  annotation_legend_side = "bottom"
)

Complete R code

#-------------------------------------------------------------------------------
# Libraries
#-------------------------------------------------------------------------------
library(readxl)
library(TCGAbiolinks)
library(SummarizedExperiment)
library(dplyr) # for pipe operator ("%>%") https://r4ds.had.co.nz/pipes.html
library(MultiAssayExperiment) # Version 1.17.2, version 1.14.0 is not working

# To install the most updated version of MultiAssayExperiment run the code below
# BiocManager::install("waldronlab/MultiAssayExperiment")


#-------------------------------------------------------------------------------
# o ATAC-Seq data
#   Available files 
#   https://gdc.cancer.gov/files/public/file/ATACseq-AWG_Open_GDC-Manifest.txt
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
# oo Get enhancer-to-gene link prediction
#-------------------------------------------------------------------------------
query.links <- GDCquery_ATAC_seq(file.type = "TCGA-ATAC_DataS7_PeakToGeneLinks_v2.xlsx")
GDCdownload(query.links,directory = "data")

links.file <- dir(path = "data",recursive = TRUE,pattern = "TCGA-ATAC_DataS7_PeakToGeneLinks_v2.xlsx",full.names = TRUE)
# Sheet1: This page of the table shows the information for all peak-to-gene
# links identified in the pan-cancer analysis. These links have already been 
# filtered to exclude (i) peaks that overlap gene promoters and 
# (ii) "diffuse" regions of correlation (see methods).
# Each row represents an individual enhancer-to-gene link predicted from the 
# pan-cancer peak set. "Enhancers" are groups of nearby peaks 
# that are predicted to regulate the same gene. See methods.
peak.to.gene.links <- readxl::read_xlsx(path = links.file,sheet = 1,skip = 30)
peak.to.gene.links.esca <- peak.to.gene.links %>% dplyr::filter(grepl("ESCA",peak.to.gene.links$Peak_Name))
head(peak.to.gene.links.esca)
peak.to.gene.links.gr <- peak.to.gene.links.esca %>% makeGRangesFromDataFrame(keep.extra.columns = TRUE)
peak.to.gene.links.gr

# Sheet 3:
# This page of the table shows the information related to merging of the nearby 
# pan-cancer peak-to-gene links into larger enhancer units (see methods).
peak.to.gene.links.merged <- readxl::read_xlsx(path = links.file, sheet = 3, skip = 23)
peak.to.gene.links.merged.gr <- peak.to.gene.links.merged %>% makeGRangesFromDataFrame(keep.extra.columns = TRUE)
peak.to.gene.links.merged.gr
#-------------------------------------------------------------------------------
# oo Get ESCA log2 norm counts and create a Summarized Experiment object
#-------------------------------------------------------------------------------
file <- "TCGA-ATAC_Cancer_Type-specific_Count_Matrices_log2norm_counts.zip"
query <- GDCquery_ATAC_seq(file.type = file)
GDCdownload(query,directory = "data") # 632 MB
zipfile <- dir(path = "data", recursive = TRUE, pattern = file, full.names = TRUE)

# which files are available ?
unzip(zipfile = zipfile,list = TRUE)

# Unzip file in the data folder
unzip(zipfile = zipfile, files = "ESCA_log2norm.txt",exdir = "data")

# read file
esca.peaks <- readr::read_tsv("data/ESCA_log2norm.txt")

# create Summarized Experiment object
esca.peaks.se <- esca.peaks %>% 
  dplyr::select(-c("score","name")) %>% # Remove columns score and name
  makeSummarizedExperimentFromDataFrame()
rowRanges(esca.peaks.se)$score <- esca.peaks$score
rowRanges(esca.peaks.se)$name <- esca.peaks$name

# Map the ATAC-seq IDs ("ESCA_1E6AC686_96C2_46C...) to TCGA barcodes ("TCGA-IG-A51D-01A-31-A616-42")
gdc.file <- "https://api.gdc.cancer.gov/data/7a3d7067-09d6-4acf-82c8-a1a81febf72c"
samples.ids <- readr::read_tsv(gdc.file, col_types = readr::cols())
samples.ids$sample <- substr(samples.ids$Case_ID,1,16)
head(samples.ids)
colnames(esca.peaks.se) <- samples.ids$Case_ID[match(gsub("_","-",colnames(esca.peaks.se)),samples.ids$bam_prefix)]

# Since we have technical replicates we keep one of them
esca.peaks.se <- esca.peaks.se[,!duplicated(colnames(esca.peaks.se))]

#-------------------------------------------------------------------------------
# o RNA-seq data
#-------------------------------------------------------------------------------
query.exp.hg38 <- GDCquery(
  project = "TCGA-ESCA", 
  data.category = "Transcriptome Profiling", 
  data.type = "Gene Expression Quantification", 
  workflow.type = "HTSeq - FPKM-UQ",
  sample.type = "Primary Tumor"
)
GDCdownload(query.exp.hg38, directory = "data") # 99 Mb
esca.rna <- GDCprepare(
  query = query.exp.hg38,
  directory = "data"
)




#-------------------------------------------------------------------------------
# o Create a multiAssayExperiment object with all samples
#-------------------------------------------------------------------------------
# We need a table mapping each sample name (complete barcode - 28 characters) 
# in both datasets (RNA, ATAC) to the same patient (first 16 characters)
sampleMap <- S4Vectors::DataFrame(
  assay = factor(x = c(rep("RNA", ncol(esca.rna)),rep("ATAC", ncol(esca.peaks.se))),levels = c("RNA","ATAC")), 
  primary = c(colnames(esca.rna), colnames(esca.peaks.se)) %>% substr(1,16), 
  colname = c(colnames(esca.rna), colnames(esca.peaks.se))
)
sampleMap

colData <-  sampleMap$primary %>% unique %>% TCGAbiolinks:::colDataPrepare()

head(colData)
plyr::count(colData, c("primary_diagnosis","definition"))

mae <- MultiAssayExperiment(
  experiments = ExperimentList(list(RNA = esca.rna,ATAC = esca.peaks.se)),
  colData = colData,
  sampleMap = sampleMap,
  metadata = list(),
  drops = list()
)


#-------------------------------------------------------------------------------
# o Create a multiAssayExperiment object with matched samples
#-------------------------------------------------------------------------------
# We need a table mapping each sample name (complete barcode - 28 characters) 
# in both datasets (RNA, ATAC) to the same patient (first 16 characters)
matched.samples <- intersect(colnames(esca.rna) %>% substr(1,16), colnames(esca.peaks.se) %>% substr(1,16))

# We need a table mapping each sample name (complete barcode - 28 characters) 
# in both datasets (RNA, ATAC) to the same patient (first 16 characters)
sampleMap <- S4Vectors::DataFrame(
  assay = factor(x = c(rep("RNA", ncol(esca.rna)),rep("ATAC", ncol(esca.peaks.se))),levels = c("RNA","ATAC")), 
  primary = c(colnames(esca.rna), colnames(esca.peaks.se)) %>% substr(1,16), 
  colname = c(colnames(esca.rna), colnames(esca.peaks.se))
)
colData <-  matched.samples %>% unique %>% TCGAbiolinks:::colDataPrepare()

head(colData)
plyr::count(colData, c("primary_diagnosis","definition"))
plyr::count(colData, c("primary_diagnosis","definition"))

mae.matched <- MultiAssayExperiment(
  experiments = ExperimentList(list(
    RNA = esca.rna[,match(matched.samples,  colnames(esca.rna) %>% substr(1,16))],
    ATAC = esca.peaks.se[,match(matched.samples,  colnames(esca.peaks.se) %>% substr(1,16))]
  )
  ),
  colData = colData,
  sampleMap = sampleMap,
  metadata = list(),
  drops = list()
)
mae.matched
# check samples are in the same order
assay(mae.matched,"RNA") %>% colnames() %>% substr(1,16) == assay(mae.matched,"ATAC") %>% colnames() %>% substr(1,16)


#-------------------------------------------------------------------------------
# o Plot ATAC-seq and RNA-seq for linked enhancers-genes
#-------------------------------------------------------------------------------
# we don't have RNA expression for all genes, let's remove them first
peak.to.gene.links.merged.gr <- peak.to.gene.links.merged.gr[peak.to.gene.links.merged.gr$Linked_Gene %in% rownames(assay(mae.matched,"RNA"))]
hits.enhancer.atac.peaks <- findOverlaps(peak.to.gene.links.merged.gr,mae.matched[["ATAC"]])

genes <- peak.to.gene.links.merged.gr$Linked_Gene[queryHits(hits.enhancer.atac.peaks)]
exp.mat <- assay(mae.matched,"RNA")[genes,]
atac.mat <- assay(mae.matched,"ATAC")[subjectHits(hits.enhancer.atac.peaks),]

library(ComplexHeatmap)
library(circlize)

### Heatmap ATAC-seq 
# colors of the atac-seq data
pal_atac <- colorRampPalette(
  c(
    '#3361A5', '#248AF3', '#14B3FF', 
    '#88CEEF', '#C1D5DC', '#EAD397', 
    '#FDB31A','#E42A2A', '#A31D1D'
  )
)(100)

# Samples annotation
ha = HeatmapAnnotation(
  df = data.frame("Group" = mae.matched$primary_diagnosis),
  show_annotation_name = TRUE,
  col = list(
    Group = c(
      "Squamous cell carcinoma, NOS" =  "red", 
      "Adenocarcinoma, NOS" = "blue"
    )
  ),
  show_legend = TRUE,
  annotation_name_side = "left",
  annotation_name_gp = gpar(fontsize = 6)
)

# row z-score
# the scale function is applied over columns so we need to transpose the data
atac.mat.row.z.score <- atac.mat %>% t %>% scale %>% t 
col.zscore <- colorRamp2(seq(-2, 2, by = 4/99), pal_atac)

# rows.annot <- rowAnnotation(foo = anno_mark(at = c(1,18), labels = rownames(plot.atac)[c(1,18)]))

ht_atac <- Heatmap(
  matrix = atac.mat.row.z.score[1:1000,],
  name ="ATAC-seq log2(counts)\nz-score rowwise", 
  col = col.zscore,
  heatmap_legend_param = list(
    legend_width  = unit(3, "cm"),
    legend_direction = "horizontal",
    labels_gp = gpar(fontsize = 12), 
    title_gp = gpar(fontsize = 12)
  ),
  show_column_names = FALSE,
  cluster_columns = TRUE,
  show_row_names = FALSE,
  cluster_rows = TRUE, # cluster will be based on ATAC-seq
  row_title = " ATAC-seq peaks",
  top_annotation = ha,
  column_names_gp = gpar(fontsize = 8),
  row_names_gp = gpar(fontsize = 4),
  column_title_gp = gpar(fontsize = 12), 
  row_title_gp = gpar(fontsize = 12),
  use_raster = TRUE,
  raster_device = c("png"),
  raster_quality = 2
) 

### Heatmap RNA-seq
# colors of the RNA-seq data

pal_rna <- colorRampPalette(
  c(
    "#352A86","#343DAE","#0262E0","#1389D2",
    "#2DB7A3","#A5BE6A","#F8BA43","#F6DA23","#F8FA0D"
  )
)(100)

# row z-score
# the scale function is applied over columns so we need to transpose the data
exp.mat.row.z.score <- exp.mat %>% t %>% scale %>% t 
col.zscore <- colorRamp2(seq(-2, 2, by = 4/99), pal_rna)

# Samples annotation
ha = HeatmapAnnotation(
  df = data.frame("Group" = mae.matched$primary_diagnosis),
  show_annotation_name = FALSE,
  col = list(
    Group = c(
      "Squamous cell carcinoma, NOS" =  "red", 
      "Adenocarcinoma, NOS" = "blue"
    )
  ),
  show_legend = TRUE,
  annotation_name_side = "right",
  annotation_name_gp = gpar(fontsize = 6)
)


# rows.annot <- rowAnnotation(foo = anno_mark(at = c(1,18), labels = rownames(plot.atac)[c(1,18)]))

ht_exp <- Heatmap(
  matrix = exp.mat.row.z.score[1:1000,],
  name ="RNA-seq FPKM-UQ\nz-score rowwise", 
  col = col.zscore,
  column_names_gp = gpar(fontsize = 8),
  show_column_names = F,
  heatmap_legend_param = list(
    legend_width  = unit(3, "cm"),
    legend_direction = "horizontal",
    labels_gp = gpar(fontsize = 12), 
    title_gp = gpar(fontsize = 12)
  ),
  show_row_names = FALSE,
  cluster_columns = FALSE,
  use_raster = TRUE,
  raster_device = c("png"),
  raster_quality = 2,
  cluster_rows = FALSE,
  row_title = "RNA-seq linked genes",
  row_title_side = "right",
  column_order = column_order(ht_atac),
  row_names_gp = gpar(fontsize = 4),
  top_annotation = ha,
  #width = unit(15, "cm"),
  column_title_gp = gpar(fontsize = 12), 
  row_title_gp = gpar(fontsize = 12)
) 

### Draw Heatmap 
draw(
  object = ht_atac + ht_exp,
  newpage = TRUE, 
  merge_legends = TRUE,
  column_title_gp = gpar(fontsize = 12, fontface = "bold"),
  heatmap_legend_side = "bottom",
  annotation_legend_side = "bottom"
)

Session information

devtools::session_info(include_base = FALSE)
## ─ Session info ───────────────────────────────────────────────────────────────
##  setting  value                       
##  version  R version 4.0.3 (2020-10-10)
##  os       Ubuntu 20.04.1 LTS          
##  system   x86_64, linux-gnu           
##  ui       X11                         
##  language (EN)                        
##  collate  en_US.UTF-8                 
##  ctype    en_US.UTF-8                 
##  tz       America/New_York            
##  date     2020-12-08                  
## 
## ─ Packages ───────────────────────────────────────────────────────────────────
##  package              * version  date       lib
##  AnnotationDbi          1.52.0   2020-10-27 [2]
##  askpass                1.1      2019-01-13 [3]
##  assertthat             0.2.1    2019-03-21 [3]
##  Biobase              * 2.50.0   2020-10-27 [2]
##  BiocFileCache          1.14.0   2020-10-27 [2]
##  BiocGenerics         * 0.36.0   2020-10-27 [2]
##  biomaRt                2.46.0   2020-10-27 [2]
##  bit                    4.0.4    2020-08-04 [3]
##  bit64                  4.0.5    2020-08-30 [1]
##  bitops                 1.0-6    2013-08-17 [3]
##  blob                   1.2.1    2020-01-20 [3]
##  bookdown               0.21     2020-10-13 [3]
##  callr                  3.5.1    2020-10-13 [1]
##  cellranger             1.1.0    2016-07-27 [3]
##  circlize             * 0.4.11   2020-10-31 [3]
##  cli                    2.1.0    2020-10-12 [1]
##  clue                   0.3-57   2019-02-25 [3]
##  cluster                2.1.0    2019-06-19 [4]
##  colorspace             2.0-0    2020-11-11 [1]
##  ComplexHeatmap       * 2.4.3    2020-07-25 [2]
##  crayon                 1.3.4    2017-09-16 [3]
##  crosstalk              1.1.0.1  2020-03-13 [3]
##  curl                   4.3      2019-12-02 [3]
##  data.table             1.13.2   2020-10-19 [1]
##  DBI                    1.1.0    2019-12-15 [3]
##  dbplyr                 2.0.0    2020-11-03 [1]
##  DelayedArray           0.16.0   2020-10-27 [2]
##  desc                   1.2.0    2018-05-01 [3]
##  devtools               2.3.2    2020-09-18 [3]
##  digest                 0.6.27   2020-10-24 [1]
##  downloader             0.4      2015-07-09 [3]
##  dplyr                * 1.0.2    2020-08-18 [3]
##  DT                     0.16     2020-10-13 [1]
##  ellipsis               0.3.1    2020-05-15 [3]
##  evaluate               0.14     2019-05-28 [3]
##  fansi                  0.4.1    2020-01-08 [3]
##  fs                     1.5.0    2020-07-31 [3]
##  generics               0.1.0    2020-10-31 [1]
##  GenomeInfoDb         * 1.26.1   2020-11-20 [2]
##  GenomeInfoDbData       1.2.4    2020-10-30 [2]
##  GenomicRanges        * 1.42.0   2020-10-27 [2]
##  GetoptLong             1.0.4    2020-10-19 [3]
##  ggplot2                3.3.2    2020-06-19 [1]
##  GlobalOptions          0.1.2    2020-06-10 [3]
##  glue                   1.4.2    2020-08-27 [1]
##  gtable                 0.3.0    2019-03-25 [3]
##  hms                    0.5.3    2020-01-08 [3]
##  htmltools              0.5.0    2020-06-16 [3]
##  htmlwidgets            1.5.2    2020-10-03 [1]
##  httr                   1.4.2    2020-07-20 [3]
##  IRanges              * 2.24.0   2020-10-27 [2]
##  jsonlite               1.7.1    2020-09-07 [3]
##  knitr                  1.30     2020-09-22 [3]
##  lattice                0.20-41  2020-04-02 [4]
##  lifecycle              0.2.0    2020-03-06 [3]
##  magrittr               2.0.1    2020-11-17 [3]
##  Matrix                 1.2-18   2019-11-27 [4]
##  MatrixGenerics       * 1.2.0    2020-10-27 [2]
##  matrixStats          * 0.57.0   2020-09-25 [1]
##  memoise                1.1.0    2017-04-21 [3]
##  MultiAssayExperiment * 1.17.2   2020-12-08 [2]
##  munsell                0.5.0    2018-06-12 [3]
##  openssl                1.4.3    2020-09-18 [3]
##  pillar                 1.4.7    2020-11-20 [3]
##  pkgbuild               1.1.0    2020-07-13 [3]
##  pkgconfig              2.0.3    2019-09-22 [3]
##  pkgload                1.1.0    2020-05-29 [3]
##  plyr                   1.8.6    2020-03-03 [3]
##  png                    0.1-7    2013-12-03 [3]
##  prettyunits            1.1.1    2020-01-24 [3]
##  processx               3.4.4    2020-09-03 [1]
##  progress               1.2.2    2019-05-16 [3]
##  ps                     1.4.0    2020-10-07 [3]
##  purrr                  0.3.4    2020-04-17 [3]
##  R.methodsS3            1.8.1    2020-08-26 [3]
##  R.oo                   1.24.0   2020-08-26 [3]
##  R.utils                2.10.1   2020-08-26 [3]
##  R6                     2.5.0    2020-10-28 [2]
##  rappdirs               0.3.1    2016-03-28 [3]
##  RColorBrewer           1.1-2    2014-12-07 [3]
##  Rcpp                   1.0.5    2020-07-06 [3]
##  RCurl                  1.98-1.2 2020-04-18 [3]
##  readr                  1.4.0    2020-10-05 [1]
##  readxl               * 1.3.1    2019-03-13 [3]
##  remotes                2.2.0    2020-07-21 [3]
##  rjson                  0.2.20   2018-06-08 [3]
##  rlang                  0.4.9    2020-11-26 [3]
##  rmarkdown              2.5      2020-10-21 [3]
##  rmdformats             1.0.1    2020-12-08 [2]
##  rprojroot              2.0.2    2020-11-15 [3]
##  RSQLite                2.2.1    2020-09-30 [1]
##  rstudioapi             0.12     2020-11-10 [1]
##  rvest                  0.3.6    2020-07-25 [3]
##  S4Vectors            * 0.28.0   2020-10-27 [2]
##  scales                 1.1.1    2020-05-11 [3]
##  sessioninfo            1.1.1    2018-11-05 [3]
##  shape                  1.4.5    2020-09-13 [3]
##  stringi                1.5.3    2020-09-09 [3]
##  stringr                1.4.0    2019-02-10 [3]
##  SummarizedExperiment * 1.20.0   2020-10-27 [1]
##  TCGAbiolinks         * 2.19.0   2020-11-12 [1]
##  TCGAbiolinksGUI.data   1.9.2    2020-10-30 [2]
##  testthat               3.0.0    2020-10-31 [1]
##  tibble                 3.0.4    2020-10-12 [1]
##  tidyr                  1.1.2    2020-08-27 [1]
##  tidyselect             1.1.0    2020-05-11 [3]
##  usethis                1.6.3    2020-09-17 [3]
##  utf8                   1.1.4    2018-05-24 [3]
##  vctrs                  0.3.4    2020-08-29 [1]
##  withr                  2.3.0    2020-09-22 [3]
##  xfun                   0.19     2020-10-30 [1]
##  XML                    3.99-0.5 2020-07-23 [3]
##  xml2                   1.3.2    2020-04-23 [3]
##  XVector                0.30.0   2020-10-27 [2]
##  yaml                   2.2.1    2020-02-01 [3]
##  zlibbioc               1.36.0   2020-10-27 [2]
##  source                                                  
##  Bioconductor                                            
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  Bioconductor                                            
##  Bioconductor                                            
##  Bioconductor                                            
##  Bioconductor                                            
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.0)                                          
##  CRAN (R 4.0.3)                                          
##  Bioconductor                                            
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  Bioconductor                                            
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  Bioconductor                                            
##  Bioconductor                                            
##  Bioconductor                                            
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  Bioconductor                                            
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.0)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.0)                                          
##  Bioconductor                                            
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  Github (waldronlab/MultiAssayExperiment@e7cb3c4)        
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.3)                                          
##  Github (juba/rmdformats@72fb1df)                        
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.2)                                          
##  Bioconductor                                            
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  Bioconductor                                            
##  Bioconductor                                            
##  Github (BioinformaticsFMRP/TCGAbiolinksGUI.data@928bc18)
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.3)                                          
##  CRAN (R 4.0.2)                                          
##  CRAN (R 4.0.2)                                          
##  Bioconductor                                            
##  CRAN (R 4.0.2)                                          
##  Bioconductor                                            
## 
## [1] /home/tiagochst/R/x86_64-pc-linux-gnu-library/4.0
## [2] /usr/local/lib/R/site-library
## [3] /usr/lib/R/site-library
## [4] /usr/lib/R/library
LS0tCnRpdGxlOiAiQWNxdWlyaW5nIFRDR0EgQVRBQy1zZXEgYW5kIFJOQS1zZXEgZGF0YSBhbmQgaW1wb3J0aW5nIGludG8gUiBkYXRhIGVudmlyb25tZW50IgphdXRob3I6ICJCZW5qYW1pbiBQLiBCZXJtYW4sIFRpYWdvIEMuIFNpbHZhIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKIHJtZGZvcm1hdHM6OmRvd25jdXRlOgogICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgIHRodW1ibmFpbHM6IGZhbHNlCiAgICBsaWdodGJveDogdHJ1ZQogICAgZ2FsbGVyeTogdHJ1ZQogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Ci5tYWluLWNvbnRhaW5lciB7CiAgbWF4LXdpZHRoOiAxODAwcHg7CiAgbWFyZ2luLWxlZnQ6IGF1dG87CiAgbWFyZ2luLXJpZ2h0OiBhdXRvOwp9Ci5wYWdlLWNvbnRlbnQgLmNvZGUtbWFzayBjb2RlLCAucGFnZS1jb250ZW50IHByZSBjb2RlIHsKICAgIGZvbnQtc2l6ZTogMTJweDsKfQouU2lkZWJhciB7CiAgICBwYWRkaW5nOiA1MHB4IDAgMzBweDsKfQpoMS50aXRsZSB7CiAgICBmb250LXNpemU6IDIuNXJlbTsKICAgIG1hcmdpbjogMWNtIDAgMS40cmVtOwogICAgZm9udC13ZWlnaHQ6IDMwMDsKICAgIGxpbmUtaGVpZ2h0OiAxLjE7Cn0KPC9zdHlsZT4KCmBgYHtyIHNldHVwLCBpbmNsdWRlID0gRkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChkcGkgPSAzMDAsd2FybmluZyA9IEZBTFNFKQpgYGAKCiMgTG9hZGluZyBSIGxpYnJhcmllcwpgYGB7ciwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeShyZWFkeGwpCmxpYnJhcnkoVENHQWJpb2xpbmtzKQpsaWJyYXJ5KFN1bW1hcml6ZWRFeHBlcmltZW50KQpsaWJyYXJ5KGRwbHlyKSAjIGZvciBwaXBlIG9wZXJhdG9yICgiJT4lIikgaHR0cHM6Ly9yNGRzLmhhZC5jby5uei9waXBlcy5odG1sCmxpYnJhcnkoTXVsdGlBc3NheUV4cGVyaW1lbnQpICMgVmVyc2lvbiAxLjE3LjIsIHZlcnNpb24gMS4xNC4wIGlzIG5vdCB3b3JraW5nCmBgYAoKVG8gaW5zdGFsbCB0aGUgbW9zdCB1cGRhdGVkIHZlcnNpb24gb2YgTXVsdGlBc3NheUV4cGVyaW1lbnQgcnVuIHRoZSBjb2RlIGJlbG93CmBgYHtSLCBldmFsID0gRkFMU0V9CkJpb2NNYW5hZ2VyOjppbnN0YWxsKCJ3YWxkcm9ubGFiL011bHRpQXNzYXlFeHBlcmltZW50IikKYGBgCgojIEFUQUMtU2VxIGRhdGEKCiMjIENoZWNrIGF2YWlsYWJsZSBmaWxlcwpgYGB7Un0KcmVhZHI6OnJlYWRfdHN2KAogICJodHRwczovL2dkYy5jYW5jZXIuZ292L2ZpbGVzL3B1YmxpYy9maWxlL0FUQUNzZXEtQVdHX09wZW5fR0RDLU1hbmlmZXN0LnR4dCIsCiAgY29sX3R5cGVzID0gcmVhZHI6OmNvbHMoKSAjIGp1c3QgdG8gaGlkZSBjb2x1bW5zIHR5cGUgaW5mb3JtYXRpb24KKQpgYGAKCiMjIEdldCBlbmhhbmNlci10by1nZW5lIGxpbmsgcHJlZGljdGlvbgoKYGBge1IsIG1lc3NhZ2UgPSBGQUxTRSwgcmVzdWx0cyA9ICJoaWRlIn0KcXVlcnkubGlua3MgPC0gR0RDcXVlcnlfQVRBQ19zZXEoZmlsZS50eXBlID0gIlRDR0EtQVRBQ19EYXRhUzdfUGVha1RvR2VuZUxpbmtzX3YyLnhsc3giKQpHRENkb3dubG9hZChxdWVyeS5saW5rcywgZGlyZWN0b3J5ID0gImRhdGEiKQpgYGAKCmBgYHtSfQpsaW5rcy5maWxlIDwtIGRpcihwYXRoID0gImRhdGEiLHJlY3Vyc2l2ZSA9IFRSVUUscGF0dGVybiA9ICJUQ0dBLUFUQUNfRGF0YVM3X1BlYWtUb0dlbmVMaW5rc192Mi54bHN4IixmdWxsLm5hbWVzID0gVFJVRSkKYGBgCgpTaGVldDE6IFRoaXMgcGFnZSBvZiB0aGUgdGFibGUgc2hvd3MgdGhlIGluZm9ybWF0aW9uIGZvciBhbGwgcGVhay10by1nZW5lCmxpbmtzIGlkZW50aWZpZWQgaW4gdGhlIHBhbi1jYW5jZXIgYW5hbHlzaXMuIFRoZXNlIGxpbmtzIGhhdmUgYWxyZWFkeSBiZWVuIApmaWx0ZXJlZCB0byBleGNsdWRlIChpKSBwZWFrcyB0aGF0IG92ZXJsYXAgZ2VuZSBwcm9tb3RlcnMgYW5kIAooaWkpICJkaWZmdXNlIiByZWdpb25zIG9mIGNvcnJlbGF0aW9uIChzZWUgbWV0aG9kcykuCgpFYWNoIHJvdyByZXByZXNlbnRzIGFuIGluZGl2aWR1YWwgZW5oYW5jZXItdG8tZ2VuZSBsaW5rIHByZWRpY3RlZCBmcm9tIHRoZSAKcGFuLWNhbmNlciBwZWFrIHNldC4gIkVuaGFuY2VycyIgYXJlIGdyb3VwcyBvZiBuZWFyYnkgcGVha3MgCnRoYXQgYXJlIHByZWRpY3RlZCB0byByZWd1bGF0ZSB0aGUgc2FtZSBnZW5lLgoKYGBge1J9CnBlYWsudG8uZ2VuZS5saW5rcyA8LSByZWFkeGw6OnJlYWRfeGxzeChwYXRoID0gbGlua3MuZmlsZSxzaGVldCA9IDEsc2tpcCA9IDMwKQpwZWFrLnRvLmdlbmUubGlua3MuZXNjYSA8LSBwZWFrLnRvLmdlbmUubGlua3MgJT4lIGRwbHlyOjpmaWx0ZXIoZ3JlcGwoIkVTQ0EiLHBlYWsudG8uZ2VuZS5saW5rcyRQZWFrX05hbWUpKQpoZWFkKHBlYWsudG8uZ2VuZS5saW5rcy5lc2NhKQoKIyB0cmFuc2Zvcm0gdG8gR2Vub21pY1JhbmdlcyBvYmplY3QKcGVhay50by5nZW5lLmxpbmtzLmdyIDwtIHBlYWsudG8uZ2VuZS5saW5rcy5lc2NhICU+JSBtYWtlR1Jhbmdlc0Zyb21EYXRhRnJhbWUoa2VlcC5leHRyYS5jb2x1bW5zID0gVFJVRSkKcGVhay50by5nZW5lLmxpbmtzLmdyCmBgYAoKU2hlZXQgMzogVGhpcyBwYWdlIG9mIHRoZSB0YWJsZSBzaG93cyB0aGUgaW5mb3JtYXRpb24gcmVsYXRlZCB0byBtZXJnaW5nIG9mIHRoZSBuZWFyYnkgCnBhbi1jYW5jZXIgcGVhay10by1nZW5lIGxpbmtzIGludG8gbGFyZ2VyIGVuaGFuY2VyIHVuaXRzLgoKYGBge1J9CnBlYWsudG8uZ2VuZS5saW5rcy5tZXJnZWQgPC0gcmVhZHhsOjpyZWFkX3hsc3gocGF0aCA9IGxpbmtzLmZpbGUsIHNoZWV0ID0gMywgc2tpcCA9IDIzKQpwZWFrLnRvLmdlbmUubGlua3MubWVyZ2VkLmdyIDwtIHBlYWsudG8uZ2VuZS5saW5rcy5tZXJnZWQgJT4lIG1ha2VHUmFuZ2VzRnJvbURhdGFGcmFtZShrZWVwLmV4dHJhLmNvbHVtbnMgPSBUUlVFKQpwZWFrLnRvLmdlbmUubGlua3MubWVyZ2VkLmdyCmBgYAoKIyMgR2V0IEVTQ0EgbG9nMiBub3JtIGNvdW50cyBhbmQgY3JlYXRlIGEgU3VtbWFyaXplZCBFeHBlcmltZW50IG9iamVjdApgYGB7UiwgbWVzc2FnZSA9IEZBTFNFLCByZXN1bHRzID0gImhpZGUifQpmaWxlIDwtICJUQ0dBLUFUQUNfQ2FuY2VyX1R5cGUtc3BlY2lmaWNfQ291bnRfTWF0cmljZXNfbG9nMm5vcm1fY291bnRzLnppcCIKcXVlcnkgPC0gR0RDcXVlcnlfQVRBQ19zZXEoZmlsZS50eXBlID0gZmlsZSkKR0RDZG93bmxvYWQocXVlcnksZGlyZWN0b3J5ID0gImRhdGEiKSAjIDYzMiBNQgp6aXBmaWxlIDwtIGRpcihwYXRoID0gImRhdGEiLCByZWN1cnNpdmUgPSBUUlVFLCBwYXR0ZXJuID0gZmlsZSwgZnVsbC5uYW1lcyA9IFRSVUUpCmBgYAoKYGBge1J9CiMgd2hpY2ggZmlsZXMgYXJlIGF2YWlsYWJsZSA/CnVuemlwKHppcGZpbGUgPSB6aXBmaWxlLGxpc3QgPSBUUlVFKQoKIyBVbnppcCBmaWxlIGluIHRoZSBkYXRhIGZvbGRlcgp1bnppcCh6aXBmaWxlID0gemlwZmlsZSwgZmlsZXMgPSAiRVNDQV9sb2cybm9ybS50eHQiLGV4ZGlyID0gImRhdGEiKQoKIyByZWFkIGZpbGUKZXNjYS5wZWFrcyA8LSByZWFkcjo6cmVhZF90c3YoCiAgZmlsZSA9ICJkYXRhL0VTQ0FfbG9nMm5vcm0udHh0IiwKICBjb2xfdHlwZXMgPSByZWFkcjo6Y29scygpICMgaGlkZSBjb2x1bW5zIHR5cGUgaW5mZXJyZWQKKSAKCiMgY3JlYXRlIFN1bW1hcml6ZWQgRXhwZXJpbWVudCBvYmplY3QKZXNjYS5wZWFrcy5zZSA8LSBlc2NhLnBlYWtzICU+JSAKICBkcGx5cjo6c2VsZWN0KC1jKCJzY29yZSIsIm5hbWUiKSkgJT4lICMgUmVtb3ZlIGNvbHVtbnMgc2NvcmUgYW5kIG5hbWUKICBtYWtlU3VtbWFyaXplZEV4cGVyaW1lbnRGcm9tRGF0YUZyYW1lKCkKcm93UmFuZ2VzKGVzY2EucGVha3Muc2UpJHNjb3JlIDwtIGVzY2EucGVha3Mkc2NvcmUKcm93UmFuZ2VzKGVzY2EucGVha3Muc2UpJG5hbWUgPC0gZXNjYS5wZWFrcyRuYW1lCgojIE1hcCB0aGUgQVRBQy1zZXEgSURzICgiRVNDQV8xRTZBQzY4Nl85NkMyXzQ2Qy4uLikgdG8gVENHQSBiYXJjb2RlcyAoIlRDR0EtSUctQTUxRC0wMUEtMzEtQTYxNi00MiIpCmdkYy5maWxlIDwtICJodHRwczovL2FwaS5nZGMuY2FuY2VyLmdvdi9kYXRhLzdhM2Q3MDY3LTA5ZDYtNGFjZi04MmM4LWExYTgxZmViZjcyYyIKc2FtcGxlcy5pZHMgPC0gcmVhZHI6OnJlYWRfdHN2KGdkYy5maWxlLCBjb2xfdHlwZXMgPSByZWFkcjo6Y29scygpKQpzYW1wbGVzLmlkcyRzYW1wbGUgPC0gc3Vic3RyKHNhbXBsZXMuaWRzJENhc2VfSUQsMSwxNikKaGVhZChzYW1wbGVzLmlkcykKY29sbmFtZXMoZXNjYS5wZWFrcy5zZSkgPC0gc2FtcGxlcy5pZHMkQ2FzZV9JRFttYXRjaChnc3ViKCJfIiwiLSIsY29sbmFtZXMoZXNjYS5wZWFrcy5zZSkpLHNhbXBsZXMuaWRzJGJhbV9wcmVmaXgpXQoKIyBTaW5jZSB3ZSBoYXZlIHRlY2huaWNhbCByZXBsaWNhdGVzIHdlIGtlZXAgb25lIG9mIHRoZW0KZXNjYS5wZWFrcy5zZSA8LSBlc2NhLnBlYWtzLnNlWywhZHVwbGljYXRlZChjb2xuYW1lcyhlc2NhLnBlYWtzLnNlKSldCmBgYAoKYGBge1J9CmVzY2EucGVha3Muc2UKYGBgCgojIFJOQS1zZXEgZGF0YQoKYGBge1IsIG1lc3NhZ2UgPSBGQUxTRSwgcmVzdWx0cyA9ICJoaWRlIn0KcXVlcnkuZXhwLmhnMzggPC0gR0RDcXVlcnkoCiAgcHJvamVjdCA9ICJUQ0dBLUVTQ0EiLCAKICBkYXRhLmNhdGVnb3J5ID0gIlRyYW5zY3JpcHRvbWUgUHJvZmlsaW5nIiwgCiAgZGF0YS50eXBlID0gIkdlbmUgRXhwcmVzc2lvbiBRdWFudGlmaWNhdGlvbiIsIAogIHdvcmtmbG93LnR5cGUgPSAiSFRTZXEgLSBGUEtNLVVRIiwKICBzYW1wbGUudHlwZSA9ICJQcmltYXJ5IFR1bW9yIgopCkdEQ2Rvd25sb2FkKHF1ZXJ5LmV4cC5oZzM4LCBkaXJlY3RvcnkgPSAiZGF0YSIpICMgOTkgTWIKCmVzY2Eucm5hIDwtIEdEQ3ByZXBhcmUoCiAgcXVlcnkgPSBxdWVyeS5leHAuaGczOCwKICBkaXJlY3RvcnkgPSAiZGF0YSIKKQpyb3duYW1lcyhlc2NhLnJuYSkgPC0gdmFsdWVzKGVzY2Eucm5hKSRleHRlcm5hbF9nZW5lX25hbWUKYGBgCgpgYGB7Un0KZXNjYS5ybmEKYGBgCgoKIyBDcmVhdGUgYSBtdWx0aUFzc2F5RXhwZXJpbWVudCBvYmplY3Qgd2l0aCBhbGwgc2FtcGxlcwoKIyMgU2FtcGxlIG1hcHBpbmcgdGFibGUKYGBge1J9CiMgV2UgbmVlZCBhIHRhYmxlIG1hcHBpbmcgZWFjaCBzYW1wbGUgbmFtZSAoY29tcGxldGUgYmFyY29kZSAtIDI4IGNoYXJhY3RlcnMpIAojIGluIGJvdGggZGF0YXNldHMgKFJOQSwgQVRBQykgdG8gdGhlIHNhbWUgcGF0aWVudCAoZmlyc3QgMTYgY2hhcmFjdGVycykKc2FtcGxlTWFwIDwtIFM0VmVjdG9yczo6RGF0YUZyYW1lKAogIGFzc2F5ID0gZmFjdG9yKHggPSBjKHJlcCgiUk5BIiwgbmNvbChlc2NhLnJuYSkpLHJlcCgiQVRBQyIsIG5jb2woZXNjYS5wZWFrcy5zZSkpKSxsZXZlbHMgPSBjKCJSTkEiLCJBVEFDIikpLCAKICBwcmltYXJ5ID0gYyhjb2xuYW1lcyhlc2NhLnJuYSksIGNvbG5hbWVzKGVzY2EucGVha3Muc2UpKSAlPiUgc3Vic3RyKDEsMTYpLCAKICBjb2xuYW1lID0gYyhjb2xuYW1lcyhlc2NhLnJuYSksIGNvbG5hbWVzKGVzY2EucGVha3Muc2UpKQopCnNhbXBsZU1hcCAlPiUgYXMuZGF0YS5mcmFtZSAlPiUgRFQ6OmRhdGF0YWJsZShvcHRpb25zID0gbGlzdChzY3JvbGxYID0gVFJVRSkpCmBgYAoKIyMgU2FtcGxlcyBtZXRhZGF0YQpgYGB7UiwgbWVzc2FnZSA9IEZBTFNFLCByZXN1bHRzID0gImhpZGUifQpjb2xEYXRhIDwtICBzYW1wbGVNYXAkcHJpbWFyeSAlPiUgdW5pcXVlICU+JSBUQ0dBYmlvbGlua3M6Ojpjb2xEYXRhUHJlcGFyZSgpCmBgYAoKYGBge1J9CmNvbERhdGEgJT4lIGFzLmRhdGEuZnJhbWUgJT4lIERUOjpkYXRhdGFibGUob3B0aW9ucyA9IGxpc3Qoc2Nyb2xsWCA9IFRSVUUpKQpwbHlyOjpjb3VudChjb2xEYXRhLCBjKCJwcmltYXJ5X2RpYWdub3NpcyIsImRlZmluaXRpb24iKSkKCm1hZSA8LSBNdWx0aUFzc2F5RXhwZXJpbWVudCgKICBleHBlcmltZW50cyA9IEV4cGVyaW1lbnRMaXN0KGxpc3QoUk5BID0gZXNjYS5ybmEsQVRBQyA9IGVzY2EucGVha3Muc2UpKSwKICBjb2xEYXRhID0gY29sRGF0YSwKICBzYW1wbGVNYXAgPSBzYW1wbGVNYXAsCiAgbWV0YWRhdGEgPSBsaXN0KCksCiAgZHJvcHMgPSBsaXN0KCkKKQptYWUKYGBgCgojIENyZWF0ZSBhIG11bHRpQXNzYXlFeHBlcmltZW50IG9iamVjdCB3aXRoIG1hdGNoZWQgc2FtcGxlcwoKIyMgU2FtcGxlIG1hcHBpbmcgdGFibGUKYGBge1J9Cm1hdGNoZWQuc2FtcGxlcyA8LSBpbnRlcnNlY3QoY29sbmFtZXMoZXNjYS5ybmEpICU+JSBzdWJzdHIoMSwxNiksIGNvbG5hbWVzKGVzY2EucGVha3Muc2UpICU+JSBzdWJzdHIoMSwxNikpCgojIFdlIG5lZWQgYSB0YWJsZSBtYXBwaW5nIGVhY2ggc2FtcGxlIG5hbWUgKGNvbXBsZXRlIGJhcmNvZGUgLSAyOCBjaGFyYWN0ZXJzKSAKIyBpbiBib3RoIGRhdGFzZXRzIChSTkEsIEFUQUMpIHRvIHRoZSBzYW1lIHBhdGllbnQgKGZpcnN0IDE2IGNoYXJhY3RlcnMpCnNhbXBsZU1hcCA8LSBTNFZlY3RvcnM6OkRhdGFGcmFtZSgKICBhc3NheSA9IGZhY3Rvcih4ID0gYyhyZXAoIlJOQSIsIG5jb2woZXNjYS5ybmEpKSxyZXAoIkFUQUMiLCBuY29sKGVzY2EucGVha3Muc2UpKSksbGV2ZWxzID0gYygiUk5BIiwiQVRBQyIpKSwgCiAgcHJpbWFyeSA9IGMoY29sbmFtZXMoZXNjYS5ybmEpLCBjb2xuYW1lcyhlc2NhLnBlYWtzLnNlKSkgJT4lIHN1YnN0cigxLDE2KSwgCiAgY29sbmFtZSA9IGMoY29sbmFtZXMoZXNjYS5ybmEpLCBjb2xuYW1lcyhlc2NhLnBlYWtzLnNlKSkKKQpzYW1wbGVNYXAgJT4lIGFzLmRhdGEuZnJhbWUgJT4lIERUOjpkYXRhdGFibGUob3B0aW9ucyA9IGxpc3Qoc2Nyb2xsWCA9IFRSVUUpKQpgYGAKCiMjIFNhbXBsZXMgbWV0YWRhdGEKYGBge1IsIG1lc3NhZ2UgPSBGQUxTRSwgcmVzdWx0cyA9ICJoaWRlIn0KY29sRGF0YSA8LSAgbWF0Y2hlZC5zYW1wbGVzICU+JSB1bmlxdWUgJT4lIFRDR0FiaW9saW5rczo6OmNvbERhdGFQcmVwYXJlKCkKYGBgCgpgYGB7Un0KY29sRGF0YSAlPiUgYXMuZGF0YS5mcmFtZSAlPiUgRFQ6OmRhdGF0YWJsZShvcHRpb25zID0gbGlzdChzY3JvbGxYID0gVFJVRSkpCnBseXI6OmNvdW50KGNvbERhdGEsIGMoInByaW1hcnlfZGlhZ25vc2lzIiwiZGVmaW5pdGlvbiIpKQoKbWFlLm1hdGNoZWQgPC0gTXVsdGlBc3NheUV4cGVyaW1lbnQoCiAgZXhwZXJpbWVudHMgPSBFeHBlcmltZW50TGlzdChsaXN0KAogICAgUk5BID0gZXNjYS5ybmFbLG1hdGNoKG1hdGNoZWQuc2FtcGxlcywgIGNvbG5hbWVzKGVzY2Eucm5hKSAlPiUgc3Vic3RyKDEsMTYpKV0sCiAgICBBVEFDID0gZXNjYS5wZWFrcy5zZVssbWF0Y2gobWF0Y2hlZC5zYW1wbGVzLCAgY29sbmFtZXMoZXNjYS5wZWFrcy5zZSkgJT4lIHN1YnN0cigxLDE2KSldCiAgICApCiAgICApLAogIGNvbERhdGEgPSBjb2xEYXRhLAogIHNhbXBsZU1hcCA9IHNhbXBsZU1hcCwKICBtZXRhZGF0YSA9IGxpc3QoKSwKICBkcm9wcyA9IGxpc3QoKQopCm1hZS5tYXRjaGVkCiMgY2hlY2sgc2FtcGxlcyBhcmUgaW4gdGhlIHNhbWUgb3JkZXIKYXNzYXkobWFlLm1hdGNoZWQsIlJOQSIpICU+JSBjb2xuYW1lcygpICU+JSBzdWJzdHIoMSwxNikgPT0gYXNzYXkobWFlLm1hdGNoZWQsIkFUQUMiKSAlPiUgY29sbmFtZXMoKSAlPiUgc3Vic3RyKDEsMTYpCmBgYAoKIyBQbG90IEFUQUMtc2VxIGFuZCBSTkEtc2VxIGZvciBsaW5rZWQgZW5oYW5jZXJzLWdlbmVzCgojIyBGaW5kIGVuaGFuY2VyIG92ZXJsYXBwaW5nIEFUQUMtc2VxIHBlYWtzICAKYGBge1J9CiMgd2UgZG9uJ3QgaGF2ZSBSTkEgZXhwcmVzc2lvbiBmb3IgYWxsIGdlbmVzLCBsZXQncyByZW1vdmUgdGhlbSBmaXJzdApwZWFrLnRvLmdlbmUubGlua3MubWVyZ2VkLmdyIDwtIHBlYWsudG8uZ2VuZS5saW5rcy5tZXJnZWQuZ3JbcGVhay50by5nZW5lLmxpbmtzLm1lcmdlZC5nciRMaW5rZWRfR2VuZSAlaW4lIHJvd25hbWVzKGFzc2F5KG1hZS5tYXRjaGVkLCJSTkEiKSldCmhpdHMuZW5oYW5jZXIuYXRhYy5wZWFrcyA8LSBmaW5kT3ZlcmxhcHMocGVhay50by5nZW5lLmxpbmtzLm1lcmdlZC5ncixtYWUubWF0Y2hlZFtbIkFUQUMiXV0pCmBgYAoKIyMgU2VsZWN0aW5nIG1hcHBlZCBsaW5rcyAgCmBgYHtSfQpnZW5lcyA8LSBwZWFrLnRvLmdlbmUubGlua3MubWVyZ2VkLmdyJExpbmtlZF9HZW5lW3F1ZXJ5SGl0cyhoaXRzLmVuaGFuY2VyLmF0YWMucGVha3MpXQpleHAubWF0IDwtIGFzc2F5KG1hZS5tYXRjaGVkLCJSTkEiKVtnZW5lcyxdCmF0YWMubWF0IDwtIGFzc2F5KG1hZS5tYXRjaGVkLCJBVEFDIilbc3ViamVjdEhpdHMoaGl0cy5lbmhhbmNlci5hdGFjLnBlYWtzKSxdCmBgYAoKIyMgSGVhdG1hcCBwbG90IAoKYGBge1J9CmxpYnJhcnkoQ29tcGxleEhlYXRtYXApCmxpYnJhcnkoY2lyY2xpemUpCmBgYAoKIyMjIEhlYXRtYXAgQVRBQy1zZXEgCmBgYHtyLGZpZy53aWR0aCA9IDEwLGZpZy5oZWlnaHQgPSA2fQojIGNvbG9ycyBvZiB0aGUgYXRhYy1zZXEgZGF0YQpwYWxfYXRhYyA8LSBjb2xvclJhbXBQYWxldHRlKAogIGMoCiAgICAnIzMzNjFBNScsICcjMjQ4QUYzJywgJyMxNEIzRkYnLCAKICAgICcjODhDRUVGJywgJyNDMUQ1REMnLCAnI0VBRDM5NycsIAogICAgJyNGREIzMUEnLCcjRTQyQTJBJywgJyNBMzFEMUQnCiAgKQopKDEwMCkKCiMgU2FtcGxlcyBhbm5vdGF0aW9uCmhhID0gSGVhdG1hcEFubm90YXRpb24oCiAgZGYgPSBkYXRhLmZyYW1lKCJHcm91cCIgPSBtYWUubWF0Y2hlZCRwcmltYXJ5X2RpYWdub3NpcyksCiAgc2hvd19hbm5vdGF0aW9uX25hbWUgPSBUUlVFLAogIGNvbCA9IGxpc3QoCiAgICBHcm91cCA9IGMoCiAgICAgICJTcXVhbW91cyBjZWxsIGNhcmNpbm9tYSwgTk9TIiA9ICAicmVkIiwgCiAgICAgICJBZGVub2NhcmNpbm9tYSwgTk9TIiA9ICJibHVlIgogICAgKQogICksCiAgc2hvd19sZWdlbmQgPSBUUlVFLAogIGFubm90YXRpb25fbmFtZV9zaWRlID0gImxlZnQiLAogIGFubm90YXRpb25fbmFtZV9ncCA9IGdwYXIoZm9udHNpemUgPSA2KQopCgojIHJvdyB6LXNjb3JlCiMgdGhlIHNjYWxlIGZ1bmN0aW9uIGlzIGFwcGxpZWQgb3ZlciBjb2x1bW5zIHNvIHdlIG5lZWQgdG8gdHJhbnNwb3NlIHRoZSBkYXRhCmF0YWMubWF0LnJvdy56LnNjb3JlIDwtIGF0YWMubWF0ICU+JSB0ICU+JSBzY2FsZSAlPiUgdCAKY29sLnpzY29yZSA8LSBjb2xvclJhbXAyKHNlcSgtMiwgMiwgYnkgPSA0Lzk5KSwgcGFsX2F0YWMpCgojIHJvd3MuYW5ub3QgPC0gcm93QW5ub3RhdGlvbihmb28gPSBhbm5vX21hcmsoYXQgPSBjKDEsMTgpLCBsYWJlbHMgPSByb3duYW1lcyhwbG90LmF0YWMpW2MoMSwxOCldKSkKCmh0X2F0YWMgPC0gSGVhdG1hcCgKICBtYXRyaXggPSBhdGFjLm1hdC5yb3cuei5zY29yZVsxOjEwMDAsXSwKICBuYW1lID0iQVRBQy1zZXEgbG9nMihjb3VudHMpXG56LXNjb3JlIHJvd3dpc2UiLCAKICBjb2wgPSBjb2wuenNjb3JlLAogIGhlYXRtYXBfbGVnZW5kX3BhcmFtID0gbGlzdCgKICAgIGxlZ2VuZF93aWR0aCAgPSB1bml0KDMsICJjbSIpLAogICAgbGVnZW5kX2RpcmVjdGlvbiA9ICJob3Jpem9udGFsIiwKICAgIGxhYmVsc19ncCA9IGdwYXIoZm9udHNpemUgPSAxMiksIAogICAgdGl0bGVfZ3AgPSBncGFyKGZvbnRzaXplID0gMTIpCiAgKSwKICBzaG93X2NvbHVtbl9uYW1lcyA9IEZBTFNFLAogIGNsdXN0ZXJfY29sdW1ucyA9IFRSVUUsCiAgc2hvd19yb3dfbmFtZXMgPSBGQUxTRSwKICBjbHVzdGVyX3Jvd3MgPSBUUlVFLCAjIGNsdXN0ZXIgd2lsbCBiZSBiYXNlZCBvbiBBVEFDLXNlcQogIHJvd190aXRsZSA9ICIgQVRBQy1zZXEgcGVha3MiLAogIHRvcF9hbm5vdGF0aW9uID0gaGEsCiAgY29sdW1uX25hbWVzX2dwID0gZ3Bhcihmb250c2l6ZSA9IDgpLAogIHJvd19uYW1lc19ncCA9IGdwYXIoZm9udHNpemUgPSA0KSwKICBjb2x1bW5fdGl0bGVfZ3AgPSBncGFyKGZvbnRzaXplID0gMTIpLCAKICByb3dfdGl0bGVfZ3AgPSBncGFyKGZvbnRzaXplID0gMTIpLAogIHVzZV9yYXN0ZXIgPSBUUlVFLAogIHJhc3Rlcl9kZXZpY2UgPSBjKCJwbmciKSwKICByYXN0ZXJfcXVhbGl0eSA9IDIKKSAKYGBgCgojIyMgSGVhdG1hcCBSTkEtc2VxCmBgYHtyLGZpZy53aWR0aCA9IDEwLGZpZy5oZWlnaHQgPSA2fQojIGNvbG9ycyBvZiB0aGUgUk5BLXNlcSBkYXRhCgpwYWxfcm5hIDwtIGNvbG9yUmFtcFBhbGV0dGUoCiAgYygKICAgICIjMzUyQTg2IiwiIzM0M0RBRSIsIiMwMjYyRTAiLCIjMTM4OUQyIiwKICAgICIjMkRCN0EzIiwiI0E1QkU2QSIsIiNGOEJBNDMiLCIjRjZEQTIzIiwiI0Y4RkEwRCIKICApCikoMTAwKQoKIyByb3cgei1zY29yZQojIHRoZSBzY2FsZSBmdW5jdGlvbiBpcyBhcHBsaWVkIG92ZXIgY29sdW1ucyBzbyB3ZSBuZWVkIHRvIHRyYW5zcG9zZSB0aGUgZGF0YQpleHAubWF0LnJvdy56LnNjb3JlIDwtIGV4cC5tYXQgJT4lIHQgJT4lIHNjYWxlICU+JSB0IApjb2wuenNjb3JlIDwtIGNvbG9yUmFtcDIoc2VxKC0yLCAyLCBieSA9IDQvOTkpLCBwYWxfcm5hKQoKIyBTYW1wbGVzIGFubm90YXRpb24KaGEgPSBIZWF0bWFwQW5ub3RhdGlvbigKICBkZiA9IGRhdGEuZnJhbWUoIkdyb3VwIiA9IG1hZS5tYXRjaGVkJHByaW1hcnlfZGlhZ25vc2lzKSwKICBzaG93X2Fubm90YXRpb25fbmFtZSA9IEZBTFNFLAogIGNvbCA9IGxpc3QoCiAgICBHcm91cCA9IGMoCiAgICAgICJTcXVhbW91cyBjZWxsIGNhcmNpbm9tYSwgTk9TIiA9ICAicmVkIiwgCiAgICAgICJBZGVub2NhcmNpbm9tYSwgTk9TIiA9ICJibHVlIgogICAgKQogICksCiAgc2hvd19sZWdlbmQgPSBUUlVFLAogIGFubm90YXRpb25fbmFtZV9zaWRlID0gInJpZ2h0IiwKICBhbm5vdGF0aW9uX25hbWVfZ3AgPSBncGFyKGZvbnRzaXplID0gNikKKQoKCiMgcm93cy5hbm5vdCA8LSByb3dBbm5vdGF0aW9uKGZvbyA9IGFubm9fbWFyayhhdCA9IGMoMSwxOCksIGxhYmVscyA9IHJvd25hbWVzKHBsb3QuYXRhYylbYygxLDE4KV0pKQoKaHRfZXhwIDwtIEhlYXRtYXAoCiAgbWF0cml4ID0gZXhwLm1hdC5yb3cuei5zY29yZVsxOjEwMDAsXSwKICBuYW1lID0iUk5BLXNlcSBGUEtNLVVRXG56LXNjb3JlIHJvd3dpc2UiLCAKICBjb2wgPSBjb2wuenNjb3JlLAogIGNvbHVtbl9uYW1lc19ncCA9IGdwYXIoZm9udHNpemUgPSA4KSwKICBzaG93X2NvbHVtbl9uYW1lcyA9IEYsCiAgaGVhdG1hcF9sZWdlbmRfcGFyYW0gPSBsaXN0KAogICAgbGVnZW5kX3dpZHRoICA9IHVuaXQoMywgImNtIiksCiAgICBsZWdlbmRfZGlyZWN0aW9uID0gImhvcml6b250YWwiLAogICAgbGFiZWxzX2dwID0gZ3Bhcihmb250c2l6ZSA9IDEyKSwgCiAgICB0aXRsZV9ncCA9IGdwYXIoZm9udHNpemUgPSAxMikKICApLAogIHNob3dfcm93X25hbWVzID0gRkFMU0UsCiAgY2x1c3Rlcl9jb2x1bW5zID0gRkFMU0UsCiAgdXNlX3Jhc3RlciA9IFRSVUUsCiAgcmFzdGVyX2RldmljZSA9IGMoInBuZyIpLAogIHJhc3Rlcl9xdWFsaXR5ID0gMiwKICBjbHVzdGVyX3Jvd3MgPSBGQUxTRSwKICByb3dfdGl0bGUgPSAiUk5BLXNlcSBsaW5rZWQgZ2VuZXMiLAogIHJvd190aXRsZV9zaWRlID0gInJpZ2h0IiwKICBjb2x1bW5fb3JkZXIgPSBjb2x1bW5fb3JkZXIoaHRfYXRhYyksCiAgcm93X25hbWVzX2dwID0gZ3Bhcihmb250c2l6ZSA9IDQpLAogIHRvcF9hbm5vdGF0aW9uID0gaGEsCiAgI3dpZHRoID0gdW5pdCgxNSwgImNtIiksCiAgY29sdW1uX3RpdGxlX2dwID0gZ3Bhcihmb250c2l6ZSA9IDEyKSwgCiAgcm93X3RpdGxlX2dwID0gZ3Bhcihmb250c2l6ZSA9IDEyKQopIApgYGAKCiMjIyBEcmF3IEhlYXRtYXAgCmBgYHtSfQpkcmF3KAogIG9iamVjdCA9IGh0X2F0YWMgKyBodF9leHAsCiAgbmV3cGFnZSA9IFRSVUUsIAogIG1lcmdlX2xlZ2VuZHMgPSBUUlVFLAogIGNvbHVtbl90aXRsZV9ncCA9IGdwYXIoZm9udHNpemUgPSAxMiwgZm9udGZhY2UgPSAiYm9sZCIpLAogIGhlYXRtYXBfbGVnZW5kX3NpZGUgPSAiYm90dG9tIiwKICBhbm5vdGF0aW9uX2xlZ2VuZF9zaWRlID0gImJvdHRvbSIKKQpgYGAKCiMgQ29tcGxldGUgUiBjb2RlCgpgYGB7UiwgY29kZT1yZWFkTGluZXMoImRhdGEuUiIpLCBpbmNsdWRlPVRSVUUsZXZhbCA9IEZBTFNFfQpgYGAKIyBTZXNzaW9uIGluZm9ybWF0aW9uCgpgYGB7Uiwgc2hvdyA9IEZBTFNFfQpkZXZ0b29sczo6c2Vzc2lvbl9pbmZvKGluY2x1ZGVfYmFzZSA9IEZBTFNFKQpgYGA=