1 xCell attempt, Biopsy: 20170820

Caveat: xCell asks for gene Symbols.

ls()
##   [1] "adjusts"                       "ah"                           
##   [3] "annot_lm"                      "annot_lp"                     
##   [5] "chosen_colors"                 "fig_s1"                       
##   [7] "fig_s1_cds"                    "hs"                           
##   [9] "hs_adjusted"                   "hs_adjusted_fcqsl"            
##  [11] "hs_adjusted_fcqsl_metr"        "hs_annotations"               
##  [13] "hs_cds_expt"                   "hs_cds_macr"                  
##  [15] "hs_expt"                       "hs_fasta"                     
##  [17] "hs_final_annotations"          "hs_gff"                       
##  [19] "hs_gff_annot"                  "hs_go_biomart"                
##  [21] "hs_lengths"                    "hs_macr"                      
##  [23] "hs_macr_batchnorm_metrics"     "hs_macr_cpmlow"               
##  [25] "hs_macr_cpmlow_pca"            "hs_macr_cpmlowcbcb"           
##  [27] "hs_macr_cpmlowcbcb_pca"        "hs_macr_cpmrlelow"            
##  [29] "hs_macr_cpmrlelow_pca"         "hs_macr_filt"                 
##  [31] "hs_macr_l2cpmlow"              "hs_macr_l2cpmlow_pca"         
##  [33] "hs_macr_l2cpmlowcom"           "hs_macr_l2cpmlowcom_pca"      
##  [35] "hs_macr_l2cpmpofa"             "hs_macr_l2cpmpofa_pca"        
##  [37] "hs_macr_l2cpmquantlowcmod"     "hs_macr_l2cpmquantlowcmod_pca"
##  [39] "hs_macr_l2cpmquantlowcom"      "hs_macr_l2cpmquantlowfsva"    
##  [41] "hs_macr_l2cpmquantlowfsva_pca" "hs_macr_l2cpmquantlowruv"     
##  [43] "hs_macr_l2cpmquantlowsva"      "hs_macr_l2cpmrlelow"          
##  [45] "hs_macr_l2cpmrlelow_pca"       "hs_macr_l2cpmrlelowcom"       
##  [47] "hs_macr_l2cpmrlelowcom_pca"    "hs_macr_metrics"              
##  [49] "hs_macr_nonil"                 "hs_macr_pca"                  
##  [51] "hs_macr_pca_info"              "hs_macr_se"                   
##  [53] "hs_macr_vp_cb"                 "hs_macr_vp_cbs3"              
##  [55] "hs_sv_adjusted"                "hs_sv_adjusted_fcqsl"         
##  [57] "hs_sv_adjusted_fcqsl_metr"     "labels"                       
##  [59] "lb_annotations"                "lb_fasta"                     
##  [61] "lb_gff"                        "lb_goids"                     
##  [63] "lb_lengths"                    "lb_tooltips"                  
##  [65] "lp_annotations"                "lp_fasta"                     
##  [67] "lp_gff"                        "lp_goids"                     
##  [69] "lp_lengths"                    "lp_macr"                      
##  [71] "lp_macr_fcqcl"                 "lp_macr_fcqcl_metr"           
##  [73] "lp_macr_fcqfl"                 "lp_macr_fcqfl_metr"           
##  [75] "lp_macr_fcqrr"                 "lp_macr_fcqrr_metr"           
##  [77] "lp_macr_fcrfl"                 "lp_macr_fcrfl_metr"           
##  [79] "lp_macr_limma_fcqlr"           "lp_macr_lpqcf"                
##  [81] "lp_macr_lpqcf_metr"            "lp_macr_rprrf"                
##  [83] "lp_macr_rrrrr_metr"            "lp_macr_sva"                  
##  [85] "lp_macr_sva_norm"              "lp_macr_sva_norm_metr"        
##  [87] "lp_macr_vp_cb"                 "lp_macr_vp_hsfcqsl"           
##  [89] "lp_macr_vp_lpqcf"              "lp_testing"                   
##  [91] "lp_tooltips"                   "lpan"                         
##  [93] "lpan_ah"                       "lpan_org"                     
##  [95] "new_adjusts"                   "new_colors"                   
##  [97] "note"                          "old_options"                  
##  [99] "orgdbs"                        "parasite_expt"                
## [101] "pretty_pca"                    "previous_file"                
## [103] "rmd_file"                      "sv_adjusted"                  
## [105] "test_adjusted"                 "this_save"                    
## [107] "tmp"                           "tt"                           
## [109] "txtdbs"                        "ver"                          
## [111] "written"
xcell_input <- normalize_expt(hs_expt, norm="quant", convert="cpm", transform="log2")
## This function will replace the expt$expressionset slot with:
## log2(cpm(quant(data)))
## It backs up the current data into a slot named:
##  expt$backup_expressionset. It will also save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep the libsizes in mind
##  when invoking limma.  The appropriate libsize is the non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Filter is false, this should likely be set to something, good
##  choices include cbcb, kofa, pofa (anything but FALSE).  If you want this to
##  stay FALSE, keep in mind that if other normalizations are performed, then the
##  resulting libsizes are likely to be strange (potentially negative!)
## Not correcting the count-data for batch effects.  If batch is
##  included in EdgerR/limma's model, then this is probably wise; but in extreme
##  batch effects this is a good parameter to play with.
## Step 1: not doing count filtering.
## Step 2: normalizing the data with quant.
## Using normalize.quantiles.robust due to a thread error in preprocessCore.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 1447108 values equal to 0, adding 1 to the matrix.
## Step 5: not doing batch correction.
xcell_input <- exprs(xcell_input)

testing <- load_biomart_annotations()
## The biomart annotations file already exists, loading from it.
xref <- testing[["annotation"]][, c("ensembl_gene_id", "hgnc_symbol")]
## Lets get the full set of downloadable attributes
xcell_test <- merge(xcell_input, xref, by.x="row.names", by.y="ensembl_gene_id")
rownames(xcell_test) <- make.names(xcell_test[["hgnc_symbol"]], unique=TRUE)
xcell_test[["Row.names"]] <- NULL
xcell_test[["hgnc_symbol"]] <- NULL

library(xCell)
data("xCell.data", package="xCell")
summary(xCell.data)
##             Length Class             Mode     
## spill           3  -none-            list     
## spill.array     3  -none-            list     
## signatures    489  GeneSetCollection list     
## genes       10808  -none-            character
library(GSEABase)
## Loading required package: annotate
## Loading required package: AnnotationDbi
## Loading required package: stats4
## Loading required package: IRanges
## Loading required package: S4Vectors
## 
## Attaching package: 'S4Vectors'
## The following object is masked from 'package:base':
## 
##     expand.grid
## Loading required package: XML
## Loading required package: graph
## 
## Attaching package: 'graph'
## The following object is masked from 'package:XML':
## 
##     addNode
details(xCell.data$signatures[[1]])
## setName: aDC%HPCA%1.txt 
## geneIds: C1QA, C1QB, ..., CCL22 (total: 8)
## geneIdType: Null
## collectionType: Null 
## setIdentifier: PEDS-092FVH8-LT:623:Tue Jun  6 14:36:33 2017:2
## description: 
## organism: 
## pubMedIds: 
## urls: 
## contributor: 
## setVersion: 0.0.1
## creationDate:
result <- xCellAnalysis(xcell_test)
## [1] "Num. of genes: 10658"
## Estimating ssGSEA scores for 489 gene sets.
## 
  |                                                                       
  |                                                                 |   0%Using parallel with 4 cores
## 
  |                                                                       
  |=                                                                |   2%
  |                                                                       
  |===                                                              |   4%
  |                                                                       
  |====                                                             |   6%
  |                                                                       
  |=====                                                            |   8%
  |                                                                       
  |======                                                           |  10%
  |                                                                       
  |========                                                         |  12%
  |                                                                       
  |=========                                                        |  14%
  |                                                                       
  |==========                                                       |  16%
  |                                                                       
  |============                                                     |  18%
  |                                                                       
  |=============                                                    |  20%
  |                                                                       
  |==============                                                   |  22%
  |                                                                       
  |================                                                 |  24%
  |                                                                       
  |=================                                                |  26%
  |                                                                       
  |==================                                               |  28%
  |                                                                       
  |====================                                             |  30%
  |                                                                       
  |=====================                                            |  32%
  |                                                                       
  |======================                                           |  34%
  |                                                                       
  |=======================                                          |  36%
  |                                                                       
  |=========================                                        |  38%
  |                                                                       
  |==========================                                       |  40%
  |                                                                       
  |===========================                                      |  42%
  |                                                                       
  |=============================                                    |  44%
  |                                                                       
  |==============================                                   |  46%
  |                                                                       
  |===============================                                  |  48%
  |                                                                       
  |================================                                 |  50%
  |                                                                       
  |==================================                               |  52%
  |                                                                       
  |===================================                              |  54%
  |                                                                       
  |====================================                             |  56%
  |                                                                       
  |======================================                           |  58%
  |                                                                       
  |=======================================                          |  60%
  |                                                                       
  |========================================                         |  62%
  |                                                                       
  |==========================================                       |  64%
  |                                                                       
  |===========================================                      |  66%
  |                                                                       
  |============================================                     |  68%
  |                                                                       
  |==============================================                   |  70%
  |                                                                       
  |===============================================                  |  72%
  |                                                                       
  |================================================                 |  74%
  |                                                                       
  |=================================================                |  76%
  |                                                                       
  |===================================================              |  78%
  |                                                                       
  |====================================================             |  80%
  |                                                                       
  |=====================================================            |  82%
  |                                                                       
  |=======================================================          |  84%
  |                                                                       
  |========================================================         |  86%
  |                                                                       
  |=========================================================        |  88%
  |                                                                       
  |==========================================================       |  90%
  |                                                                       
  |============================================================     |  92%
  |                                                                       
  |=============================================================    |  94%
  |                                                                       
  |==============================================================   |  96%
  |                                                                       
  |================================================================ |  98%
  |                                                                       
  |=================================================================| 100%
pp(file="images/xcell_signatures.png")
## Going to write the image to: images/xcell_signatures.png when dev.off() is called.
heatmap.3(result, trace="none")
dev.off()
## png 
##   2
pp(file="images/xcell_boxplot.png", image=hpgltools::plot_boxplot(t(result)))
## Writing the image to: images/xcell_boxplot.png and calling dev.off().

1.1 Figure out gsva

Taken from the gsva vignette…

The calculation of GSVA enrichment scores is performed in one single call to the gsva() function. However, one should take into account that this function performs further non-specific filtering steps prior to the actual calculations. On the one hand, it matches gene identifiers between gene sets and gene expression values. On the other hand, it discards gene sets that do not meet minimum and maximum gene set size requirements specified with the arguments min.sz and max.sz, respectively, which, in the call below, are set to 10 and 500 genes. Because we want to use limma on the resulting GSVA enrichment scores, we leave deliberately unchanged the default argument mx.diff=TRUE to obtain approximately normally distributed ES.

test_table <- hs_macr_sva$limma$all_tables$sh_vs_chr
## Error in eval(expr, envir, enclos): object 'hs_macr_sva' not found
library(GSEABase)
library(GSVA)
library(GSVAdata)
## Loading required package: hgu95a.db
## Loading required package: org.Hs.eg.db
## 
## 
data(c2BroadSets)

##leukemia_es <- gsva(leukemia_filtered_eset, c2BroadSets,
##                    min.sz=10, max.sz=500, verbose=TRUE)
eset <- hs_expt$expressionset
ensembl_to_entrez <- sm(select(x=hs, keys=rownames(exprs(eset)), keytype="ENSEMBL", columns=c("ENTREZID")))
## Error in get(str): object 'GO.db' not found
## The broad IDs are all Entrez, but mine are Ensembl.
old_ids <- exprs(eset)
new_ids <- merge(old_ids, ensembl_to_entrez, by.x="row.names", by.y="ENSEMBL")
## Error in merge(old_ids, ensembl_to_entrez, by.x = "row.names", by.y = "ENSEMBL"): object 'ensembl_to_entrez' not found
remaining_ids <- new_ids[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'new_ids' not found
new_eset <- eset[remaining_ids, ]
## Error in eset[remaining_ids, ]: object 'remaining_ids' not found
rownames(new_eset) <- make.names(new_ids[["ENTREZID"]], unique=TRUE)
## Error in make.names(new_ids[["ENTREZID"]], unique = TRUE): object 'new_ids' not found
rownames(new_eset) <- gsub(pattern="^X", replacement="", x=rownames(new_eset))
## Error in rownames(new_eset): object 'new_eset' not found
eset <- new_eset
## Error in eval(expr, envir, enclos): object 'new_eset' not found
fData(eset)$ENTREZID <- rownames(fData(eset))
annotation(eset) <- "org.Hs.eg.db"


geneset_test <- GeneSet(eset, setName="annoying")
filtered_eset <- genefilter::nsFilter(eset, require.entrez=TRUE, remove.dupEntrez=FALSE,
                                      var.func=IQR, var.filter=TRUE, var.cutoff=0.5, filterByQuantile=TRUE,
                                      feature.exclude="^AFFX")
gsva_test <- gsva(eset, c2BroadSets, verbose=TRUE)
## Warning in .local(expr, gset.idx.list, ...): 14510 genes with constant
## expression values throuhgout the samples.
## Warning in .local(expr, gset.idx.list, ...): Since argument method!
## ="ssgsea", genes with constant expression values are discarded.
## Mapping identifiers between gene sets and feature names
## Error in .gsva(exprs(expr), mapped.gset.idx.list, method, kcdf, rnaseq, : The gene set list is empty!  Filter may be too stringent.
tsne_test <- plot_tsne(gsva_test)
## Error in plot_pca(..., pc_method = "tsne"): object 'gsva_test' not found
## Testing obnoxious gsva examples which are unbelievably unhelpful
leuk_test <- genefilter::nsFilter(leukemia_eset, require.entrez=TRUE)
## Error in genefilter::nsFilter(leukemia_eset, require.entrez = TRUE): object 'leukemia_eset' not found
data(sample.ExpressionSet) # from Biobase
egs <- GeneSet(sample.ExpressionSet[201:250,], setName="Sample")
gsva_test <- gsva(egs, c2BroadSets, verbose=TRUE)
## Error in (function (classes, fdef, mtable) : unable to find an inherited method for function 'gsva' for signature '"GeneSet", "GeneSetCollection"'
all_gsva_categories <- names(c2BroadSets)
all_prefixes <- gsub(pattern="^(.*?)_.*", replacement="\\1", x=all_gsva_categories)
unique_prefixes <- unique(sort(all_prefixes))

reactome_subset <- grepl(x=rownames(gsva_test), pattern="^REACTOME")
## Error in rownames(gsva_test): object 'gsva_test' not found
reactome_gsva <- gsva_test[reactome_subset, ]
## Error in eval(expr, envir, enclos): object 'gsva_test' not found
pp("/tmp/testing.svg")
## Going to write the image to: /tmp/testing.svg when dev.off() is called.
##tt <- heatmap.3(exprs(reactome_gsva), trace="none", cexRow=0.1, cexCol=0.5)
tt <- heatmap.3(exprs(reactome_gsva), cexRow=0.1, cexCol=0.5)
## Error in exprs(reactome_gsva): object 'reactome_gsva' not found
dev.off()
## png 
##   2
original <- exprs(reactome_gsva)
## Error in exprs(reactome_gsva): object 'reactome_gsva' not found
new_order <- tt$rowInd
new <- original[new_order, ]
## Error in eval(expr, envir, enclos): object 'original' not found

1.2 Side note

I was certain that I made a simplified version of this.

gsva_result <- simple_gsva(hs_expt)
## Error in if (length(annotation(eset)) == 0 | grep(pattern = "Fill me in", : argument is of length zero
new_expt <- gsva_result[["expt"]]
## Error in eval(expr, envir, enclos): object 'gsva_result' not found
gsva_dis <- plot_disheat(new_expt)
## Error in plot_heatmap(expt_data, expt_colors = expt_colors, expt_design = expt_design, : object 'new_expt' not found
pp(file="images/gsva_all.png")
## Going to write the image to: images/gsva_all.png when dev.off() is called.
tt <- heatmap.3(exprs(new_expt), cexRow=0.1, trace="none", cexCol=0.5)
## Error in exprs(new_expt): object 'new_expt' not found
dev.off()
## png 
##   2
all_gsva_categories <- names(c2BroadSets)
all_prefixes <- gsub(pattern="^(.*?)_.*", replacement="\\1", x=all_gsva_categories)
unique_prefixes <- unique(sort(all_prefixes))

reactome_subset <- grepl(x=rownames(new_expt$expressionset), pattern="^REACTOME")
## Error in rownames(new_expt$expressionset): object 'new_expt' not found
reactome_gsva <- new_expt$expressionset[reactome_subset, ]
## Error in eval(expr, envir, enclos): object 'new_expt' not found
pp("images/reactome_gsva.png")
## Going to write the image to: images/reactome_gsva.png when dev.off() is called.
tt <- heatmap.3(exprs(reactome_gsva), cexRow=0.1, cexCol=0.5, trace="none")
## Error in exprs(reactome_gsva): object 'reactome_gsva' not found
dev.off()
## png 
##   2
if (!isTRUE(get0("skip_load"))) {
  pander::pander(sessionInfo())
  message(paste0("This is hpgltools commit: ", get_git_commit()))
  this_save <- paste0(gsub(pattern="\\.Rmd", replace="", x=rmd_file), "-v", ver, ".rda.xz")
  message(paste0("Saving to ", this_save))
  tmp <- sm(saveme(filename=this_save))
}
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 3bc454f6c7093e2716d7a9bc1a01f9c15eb49101
## This is hpgltools commit: Wed Jan 2 16:23:19 2019 -0500: 3bc454f6c7093e2716d7a9bc1a01f9c15eb49101
## Saving to 02_expression_macrophage-v20170820.rda.xz
LS0tCnRpdGxlOiAiUk5Bc2VxIG9mIEwucGFuYW1lbnNpczogVGVzdGluZyBvdXQgR1NWQSIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogaHRtbF9kb2N1bWVudDoKICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgY29kZV9mb2xkaW5nOiBzaG93CiAgZmlnX2NhcHRpb246IHRydWUKICBmaWdfaGVpZ2h0OiA3CiAgZmlnX3dpZHRoOiA3CiAgaGlnaGxpZ2h0OiBkZWZhdWx0CiAga2VlcF9tZDogZmFsc2UKICBtb2RlOiBzZWxmY29udGFpbmVkCiAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgc2VsZl9jb250YWluZWQ6IHRydWUKICB0aGVtZTogcmVhZGFibGUKICB0b2M6IHRydWUKICB0b2NfZmxvYXQ6CiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZT4KICBib2R5IC5tYWluLWNvbnRhaW5lciB7CiAgICBtYXgtd2lkdGg6IDE2MDBweDsKICB9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQppZiAoIWlzVFJVRShnZXQwKCJza2lwX2xvYWQiKSkpIHsKICBsaWJyYXJ5KGhwZ2x0b29scykKICB0dCA8LSBkZXZ0b29sczo6bG9hZF9hbGwoIn4vaHBnbHRvb2xzIikKICBrbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICB3aWR0aD05MCwKICAgICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCiAga25pdHI6Om9wdHNfY2h1bmskc2V0KGVycm9yPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aD04LAogICAgICAgICAgICAgICAgICAgICAgICBmaWcuaGVpZ2h0PTgsCiAgICAgICAgICAgICAgICAgICAgICAgIGRwaT05NikKICBvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cz00LAogICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbD0iYWxsb3ciKQogIGdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQogIHZlciA8LSAiMjAxNzA4MjAiCiAgcHJldmlvdXNfZmlsZSA8LSAiMDJfZXN0aW1hdGlvbl9tYWNyb3BoYWdlLlJtZCIKCiAgdG1wIDwtIHRyeShzbShsb2FkbWUoZmlsZW5hbWU9cGFzdGUwKGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iIiwgeD1wcmV2aW91c19maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpKSkpCiAgcm1kX2ZpbGUgPC0gIjAyX2V4cHJlc3Npb25fbWFjcm9waGFnZS5SbWQiCn0KYGBgCgojIHhDZWxsIGF0dGVtcHQsIEJpb3BzeTogYHIgdmVyYAoKQ2F2ZWF0OiB4Q2VsbCBhc2tzIGZvciBnZW5lIFN5bWJvbHMuCgpgYGB7ciBmaWx0ZXJ9CmxzKCkKeGNlbGxfaW5wdXQgPC0gbm9ybWFsaXplX2V4cHQoaHNfZXhwdCwgbm9ybT0icXVhbnQiLCBjb252ZXJ0PSJjcG0iLCB0cmFuc2Zvcm09ImxvZzIiKQp4Y2VsbF9pbnB1dCA8LSBleHBycyh4Y2VsbF9pbnB1dCkKCnRlc3RpbmcgPC0gbG9hZF9iaW9tYXJ0X2Fubm90YXRpb25zKCkKeHJlZiA8LSB0ZXN0aW5nW1siYW5ub3RhdGlvbiJdXVssIGMoImVuc2VtYmxfZ2VuZV9pZCIsICJoZ25jX3N5bWJvbCIpXQojIyBMZXRzIGdldCB0aGUgZnVsbCBzZXQgb2YgZG93bmxvYWRhYmxlIGF0dHJpYnV0ZXMKeGNlbGxfdGVzdCA8LSBtZXJnZSh4Y2VsbF9pbnB1dCwgeHJlZiwgYnkueD0icm93Lm5hbWVzIiwgYnkueT0iZW5zZW1ibF9nZW5lX2lkIikKcm93bmFtZXMoeGNlbGxfdGVzdCkgPC0gbWFrZS5uYW1lcyh4Y2VsbF90ZXN0W1siaGduY19zeW1ib2wiXV0sIHVuaXF1ZT1UUlVFKQp4Y2VsbF90ZXN0W1siUm93Lm5hbWVzIl1dIDwtIE5VTEwKeGNlbGxfdGVzdFtbImhnbmNfc3ltYm9sIl1dIDwtIE5VTEwKCmxpYnJhcnkoeENlbGwpCmRhdGEoInhDZWxsLmRhdGEiLCBwYWNrYWdlPSJ4Q2VsbCIpCnN1bW1hcnkoeENlbGwuZGF0YSkKbGlicmFyeShHU0VBQmFzZSkKZGV0YWlscyh4Q2VsbC5kYXRhJHNpZ25hdHVyZXNbWzFdXSkKCgpyZXN1bHQgPC0geENlbGxBbmFseXNpcyh4Y2VsbF90ZXN0KQpwcChmaWxlPSJpbWFnZXMveGNlbGxfc2lnbmF0dXJlcy5wbmciKQpoZWF0bWFwLjMocmVzdWx0LCB0cmFjZT0ibm9uZSIpCmRldi5vZmYoKQpwcChmaWxlPSJpbWFnZXMveGNlbGxfYm94cGxvdC5wbmciLCBpbWFnZT1ocGdsdG9vbHM6OnBsb3RfYm94cGxvdCh0KHJlc3VsdCkpKQpgYGAKCiMjIEZpZ3VyZSBvdXQgZ3N2YQoKVGFrZW4gZnJvbSB0aGUgZ3N2YSB2aWduZXR0ZS4uLgoKVGhlIGNhbGN1bGF0aW9uIG9mIEdTVkEgZW5yaWNobWVudCBzY29yZXMgaXMgcGVyZm9ybWVkIGluIG9uZSBzaW5nbGUgY2FsbCB0byB0aGUKZ3N2YSgpIGZ1bmN0aW9uLiBIb3dldmVyLCAgb25lICBzaG91bGQgIHRha2UgIGludG8gIGFjY291bnQgIHRoYXQgIHRoaXMKZnVuY3Rpb24gIHBlcmZvcm1zICBmdXJ0aGVyICBub24tc3BlY2lmaWMgIGZpbHRlcmluZyAgc3RlcHMgcHJpb3IgdG8gdGhlIGFjdHVhbApjYWxjdWxhdGlvbnMuICBPbiB0aGUgb25lIGhhbmQsIGl0IG1hdGNoZXMgZ2VuZSBpZGVudGlmaWVycyBiZXR3ZWVuIGdlbmUgc2V0cwphbmQgZ2VuZSBleHByZXNzaW9uIHZhbHVlcy4gIE9uIHRoZSBvdGhlciBoYW5kLCBpdCBkaXNjYXJkcyBnZW5lIHNldHMgdGhhdCBkbwpub3QgbWVldCBtaW5pbXVtIGFuZCBtYXhpbXVtIGdlbmUgc2V0IHNpemUgcmVxdWlyZW1lbnRzIHNwZWNpZmllZCB3aXRoIHRoZQphcmd1bWVudHMgbWluLnN6IGFuZCBtYXguc3osIHJlc3BlY3RpdmVseSwgd2hpY2gsIGluIHRoZSBjYWxsIGJlbG93LCBhcmUgc2V0IHRvCjEwIGFuZCA1MDAgZ2VuZXMuICBCZWNhdXNlIHdlIHdhbnQgdG8gdXNlIGxpbW1hIG9uIHRoZSByZXN1bHRpbmcgR1NWQSBlbnJpY2htZW50CnNjb3JlcywgIHdlICBsZWF2ZSAgZGVsaWJlcmF0ZWx5ICB1bmNoYW5nZWQgIHRoZSAgZGVmYXVsdCAgYXJndW1lbnQgbXguZGlmZj1UUlVFCnRvICBvYnRhaW4gIGFwcHJveGltYXRlbHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgRVMuCgpgYGB7ciBnc3ZhX2Z1bn0KdGVzdF90YWJsZSA8LSBoc19tYWNyX3N2YSRsaW1tYSRhbGxfdGFibGVzJHNoX3ZzX2NocgoKbGlicmFyeShHU0VBQmFzZSkKbGlicmFyeShHU1ZBKQpsaWJyYXJ5KEdTVkFkYXRhKQpkYXRhKGMyQnJvYWRTZXRzKQoKIyNsZXVrZW1pYV9lcyA8LSBnc3ZhKGxldWtlbWlhX2ZpbHRlcmVkX2VzZXQsIGMyQnJvYWRTZXRzLAojIyAgICAgICAgICAgICAgICAgICAgbWluLnN6PTEwLCBtYXguc3o9NTAwLCB2ZXJib3NlPVRSVUUpCmVzZXQgPC0gaHNfZXhwdCRleHByZXNzaW9uc2V0CmVuc2VtYmxfdG9fZW50cmV6IDwtIHNtKHNlbGVjdCh4PWhzLCBrZXlzPXJvd25hbWVzKGV4cHJzKGVzZXQpKSwga2V5dHlwZT0iRU5TRU1CTCIsIGNvbHVtbnM9YygiRU5UUkVaSUQiKSkpCgojIyBUaGUgYnJvYWQgSURzIGFyZSBhbGwgRW50cmV6LCBidXQgbWluZSBhcmUgRW5zZW1ibC4Kb2xkX2lkcyA8LSBleHBycyhlc2V0KQpuZXdfaWRzIDwtIG1lcmdlKG9sZF9pZHMsIGVuc2VtYmxfdG9fZW50cmV6LCBieS54PSJyb3cubmFtZXMiLCBieS55PSJFTlNFTUJMIikKcmVtYWluaW5nX2lkcyA8LSBuZXdfaWRzW1siUm93Lm5hbWVzIl1dCgpuZXdfZXNldCA8LSBlc2V0W3JlbWFpbmluZ19pZHMsIF0Kcm93bmFtZXMobmV3X2VzZXQpIDwtIG1ha2UubmFtZXMobmV3X2lkc1tbIkVOVFJFWklEIl1dLCB1bmlxdWU9VFJVRSkKcm93bmFtZXMobmV3X2VzZXQpIDwtIGdzdWIocGF0dGVybj0iXlgiLCByZXBsYWNlbWVudD0iIiwgeD1yb3duYW1lcyhuZXdfZXNldCkpCmVzZXQgPC0gbmV3X2VzZXQKZkRhdGEoZXNldCkkRU5UUkVaSUQgPC0gcm93bmFtZXMoZkRhdGEoZXNldCkpCmFubm90YXRpb24oZXNldCkgPC0gIm9yZy5Icy5lZy5kYiIKCgpnZW5lc2V0X3Rlc3QgPC0gR2VuZVNldChlc2V0LCBzZXROYW1lPSJhbm5veWluZyIpCmZpbHRlcmVkX2VzZXQgPC0gZ2VuZWZpbHRlcjo6bnNGaWx0ZXIoZXNldCwgcmVxdWlyZS5lbnRyZXo9VFJVRSwgcmVtb3ZlLmR1cEVudHJlej1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIuZnVuYz1JUVIsIHZhci5maWx0ZXI9VFJVRSwgdmFyLmN1dG9mZj0wLjUsIGZpbHRlckJ5UXVhbnRpbGU9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlLmV4Y2x1ZGU9Il5BRkZYIikKZ3N2YV90ZXN0IDwtIGdzdmEoZXNldCwgYzJCcm9hZFNldHMsIHZlcmJvc2U9VFJVRSkKCnRzbmVfdGVzdCA8LSBwbG90X3RzbmUoZ3N2YV90ZXN0KQoKCiMjIFRlc3Rpbmcgb2Jub3hpb3VzIGdzdmEgZXhhbXBsZXMgd2hpY2ggYXJlIHVuYmVsaWV2YWJseSB1bmhlbHBmdWwKbGV1a190ZXN0IDwtIGdlbmVmaWx0ZXI6Om5zRmlsdGVyKGxldWtlbWlhX2VzZXQsIHJlcXVpcmUuZW50cmV6PVRSVUUpCmRhdGEoc2FtcGxlLkV4cHJlc3Npb25TZXQpICMgZnJvbSBCaW9iYXNlCmVncyA8LSBHZW5lU2V0KHNhbXBsZS5FeHByZXNzaW9uU2V0WzIwMToyNTAsXSwgc2V0TmFtZT0iU2FtcGxlIikKZ3N2YV90ZXN0IDwtIGdzdmEoZWdzLCBjMkJyb2FkU2V0cywgdmVyYm9zZT1UUlVFKQpgYGAKCmBgYHtyIGdzdmFfY2xhcmlmaWNhdGlvbnN9CmFsbF9nc3ZhX2NhdGVnb3JpZXMgPC0gbmFtZXMoYzJCcm9hZFNldHMpCmFsbF9wcmVmaXhlcyA8LSBnc3ViKHBhdHRlcm49Il4oLio/KV8uKiIsIHJlcGxhY2VtZW50PSJcXDEiLCB4PWFsbF9nc3ZhX2NhdGVnb3JpZXMpCnVuaXF1ZV9wcmVmaXhlcyA8LSB1bmlxdWUoc29ydChhbGxfcHJlZml4ZXMpKQoKcmVhY3RvbWVfc3Vic2V0IDwtIGdyZXBsKHg9cm93bmFtZXMoZ3N2YV90ZXN0KSwgcGF0dGVybj0iXlJFQUNUT01FIikKcmVhY3RvbWVfZ3N2YSA8LSBnc3ZhX3Rlc3RbcmVhY3RvbWVfc3Vic2V0LCBdCnBwKCIvdG1wL3Rlc3Rpbmcuc3ZnIikKIyN0dCA8LSBoZWF0bWFwLjMoZXhwcnMocmVhY3RvbWVfZ3N2YSksIHRyYWNlPSJub25lIiwgY2V4Um93PTAuMSwgY2V4Q29sPTAuNSkKdHQgPC0gaGVhdG1hcC4zKGV4cHJzKHJlYWN0b21lX2dzdmEpLCBjZXhSb3c9MC4xLCBjZXhDb2w9MC41KQpkZXYub2ZmKCkKCm9yaWdpbmFsIDwtIGV4cHJzKHJlYWN0b21lX2dzdmEpCm5ld19vcmRlciA8LSB0dCRyb3dJbmQKbmV3IDwtIG9yaWdpbmFsW25ld19vcmRlciwgXQpgYGAKCiMjIFNpZGUgbm90ZQoKSSB3YXMgY2VydGFpbiB0aGF0IEkgbWFkZSBhIHNpbXBsaWZpZWQgdmVyc2lvbiBvZiB0aGlzLgoKYGBge3Igc2ltcGxlX2dzdmF9CmdzdmFfcmVzdWx0IDwtIHNpbXBsZV9nc3ZhKGhzX2V4cHQpCm5ld19leHB0IDwtIGdzdmFfcmVzdWx0W1siZXhwdCJdXQpnc3ZhX2RpcyA8LSBwbG90X2Rpc2hlYXQobmV3X2V4cHQpCgpwcChmaWxlPSJpbWFnZXMvZ3N2YV9hbGwucG5nIikKdHQgPC0gaGVhdG1hcC4zKGV4cHJzKG5ld19leHB0KSwgY2V4Um93PTAuMSwgdHJhY2U9Im5vbmUiLCBjZXhDb2w9MC41KQpkZXYub2ZmKCkKCmFsbF9nc3ZhX2NhdGVnb3JpZXMgPC0gbmFtZXMoYzJCcm9hZFNldHMpCmFsbF9wcmVmaXhlcyA8LSBnc3ViKHBhdHRlcm49Il4oLio/KV8uKiIsIHJlcGxhY2VtZW50PSJcXDEiLCB4PWFsbF9nc3ZhX2NhdGVnb3JpZXMpCnVuaXF1ZV9wcmVmaXhlcyA8LSB1bmlxdWUoc29ydChhbGxfcHJlZml4ZXMpKQoKcmVhY3RvbWVfc3Vic2V0IDwtIGdyZXBsKHg9cm93bmFtZXMobmV3X2V4cHQkZXhwcmVzc2lvbnNldCksIHBhdHRlcm49Il5SRUFDVE9NRSIpCnJlYWN0b21lX2dzdmEgPC0gbmV3X2V4cHQkZXhwcmVzc2lvbnNldFtyZWFjdG9tZV9zdWJzZXQsIF0KcHAoImltYWdlcy9yZWFjdG9tZV9nc3ZhLnBuZyIpCnR0IDwtIGhlYXRtYXAuMyhleHBycyhyZWFjdG9tZV9nc3ZhKSwgY2V4Um93PTAuMSwgY2V4Q29sPTAuNSwgdHJhY2U9Im5vbmUiKQpkZXYub2ZmKCkKYGBgCgoKYGBge3Igc2F2ZW1lfQppZiAoIWlzVFJVRShnZXQwKCJza2lwX2xvYWQiKSkpIHsKICBwYW5kZXI6OnBhbmRlcihzZXNzaW9uSW5mbygpKQogIG1lc3NhZ2UocGFzdGUwKCJUaGlzIGlzIGhwZ2x0b29scyBjb21taXQ6ICIsIGdldF9naXRfY29tbWl0KCkpKQogIHRoaXNfc2F2ZSA8LSBwYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXJtZF9maWxlKSwgIi12IiwgdmVyLCAiLnJkYS54eiIpCiAgbWVzc2FnZShwYXN0ZTAoIlNhdmluZyB0byAiLCB0aGlzX3NhdmUpKQogIHRtcCA8LSBzbShzYXZlbWUoZmlsZW5hbWU9dGhpc19zYXZlKSkKfQpgYGAK