1 Introduction

The set of analyses performed in tmrc3 sample estimation has become unorganized and difficult to follow. This is intended to start at the level of broad organization before stepping into the analyses.

2 Goals

These samples are from patients who either successfully cleared a Leishmania panamensis infection following treatment, or did not. They include biopsies from each patient along with purifications for Monocytes, Neutrophils, and Eosinophils. When possible, this process was repeated over three visits; but some patients did not return for the second or third visit.

The over-arching goal is to look for attributes(most likely genes) which distinguish patients who do and do not cure the infection after treatment. If possible, these will be apparent on the first visit.

2.1 Relevant Metadata

The metadata factors (in no particular order) of the experiment are:

  1. Visit. 1, 2, or 3.
  2. Patient.
  3. Clinical outcome: cure or fail. This includes the population of patients who did not return and are labeled ‘lost’. This is, by definition, confounded with patient.
  4. Drug treatment. Most of the patients were treated with an antimonial, but a few were treated with miltefosine.
  5. Cell type or biopsy.

Metadata was also collected for the patients and there are many factors which have potential to affect the outcome. These analyses will generally remain agnostic for these factors, which include (among other things):

  1. sex
  2. ethnicity
  3. age
  4. ulcer/lesion attributes (by visit)
  5. amount of time spent with infection

2.2 Libraries, sequencing, mapping, quantification

The samples used in these analyses were all collected, purified, and libraries generated by the scientists/doctors at CIDEIM. The sequencing libraries were generated via the TruSeq non-stranded library kit and sequenced either at JHU or UMD; earlier samples were single-ended, but most were paired.

All samples were trimmed with trimomatic using the same set of parameters. All mapping was performed with hisat2 version 2.2.1. Quantifications were also performed with salmon version 1.2.0. The reference genome used was hg38 100 (released 202004). When samples were mapped against L.panamensis, the TriTrypDB version 36 reference was used. The set of annotations were therefore limited to ensembl’s 2020 release. The early samples were actually first mapped with hg38 91 and later redone.

2.3 Types of analyses included

This document will limit itself to a set of canonical RNAseq analyses. It must therefore create files containing the raw data to facilitate sharing the data. It will plot metrics of the data to demonstrate the sequencing quality and clustering of the samples under the various conditions examined and normalizations employed. It will perform differential expression analyses for the metadata factors of interest alongside likelihood ratio tests for factors like celltype and time. Given the sets of over/under expressed genes observed in the various DE methods, it will perform the likely gene set tests for over represented gene ontology groups, reactome, etc. Simultaneously, the raw data will be passed to gene set variance analyses to see if there are groups of genes overrepresented in other experiments.

3 Metadata collection

There are two metadata sources:

  1. The online sample sheet, which I periodically update and download into the ‘sample_sheets/’ directory.
  2. The crf metadata, describing the individual patients.
samplesheet <- "sample_sheets/tmrc3_samples_20211223.xlsx"
crf_metadata <- "sample_sheets/20210825_EXP_ESPECIAL_TMRC3_VERSION_2.xlsx"

4 Annotation Collection

The primary annotation sources are:

  1. Ensembl’s biomart archive from 2020 for human annotations.
  2. The TriTrypDB release 36 for parasite annotations.

Both provide GO data. They also provide helpful links to other data sources. For the moment, we are focusing on the human annotations.

4.1 Gene annotations

These analyses have focused on gene-level abundances/differences. Thus, when htseq-count was invoked against the hisat2-based mappings, parameters were chosen to count genes rather than transcripts. Similarly, when salmon counts were used via tximport, a mapping of genes to transcripts was used to collapse the matrix to gene-level abundances. This decision may be revisited.

hs_annot <- sm(load_biomart_annotations(year="2020"))
hs_annot <- hs_annot[["annotation"]]
hs_annot[["transcript"]] <- paste0(rownames(hs_annot), ".", hs_annot[["version"]])
rownames(hs_annot) <- make.names(hs_annot[["ensembl_gene_id"]], unique=TRUE)
tx_gene_map <- hs_annot[, c("transcript", "ensembl_gene_id")]
summary(hs_annot)
##  ensembl_transcript_id ensembl_gene_id       version     transcript_version
##  Length:227921         Length:227921      Min.   : 1.0   Min.   : 1.00     
##  Class :character      Class :character   1st Qu.: 6.0   1st Qu.: 1.00     
##  Mode  :character      Mode  :character   Median :12.0   Median : 1.00     
##                                           Mean   :10.7   Mean   : 3.08     
##                                           3rd Qu.:16.0   3rd Qu.: 5.00     
##                                           Max.   :29.0   Max.   :17.00     
##                                                                            
##  hgnc_symbol        description        gene_biotype         cds_length    
##  Length:227921      Length:227921      Length:227921      Min.   :     3  
##  Class :character   Class :character   Class :character   1st Qu.:   357  
##  Mode  :character   Mode  :character   Mode  :character   Median :   694  
##                                                           Mean   :  1139  
##                                                           3rd Qu.:  1446  
##                                                           Max.   :107976  
##                                                           NA's   :127343  
##  chromosome_name       strand          start_position      end_position     
##  Length:227921      Length:227921      Min.   :5.77e+02   Min.   :6.47e+02  
##  Class :character   Class :character   1st Qu.:3.11e+07   1st Qu.:3.12e+07  
##  Mode  :character   Mode  :character   Median :6.04e+07   Median :6.06e+07  
##                                        Mean   :7.41e+07   Mean   :7.42e+07  
##                                        3rd Qu.:1.09e+08   3rd Qu.:1.09e+08  
##                                        Max.   :2.49e+08   Max.   :2.49e+08  
##                                                                             
##   transcript       
##  Length:227921     
##  Class :character  
##  Mode  :character  
##                    
##                    
##                    
## 

4.2 Gene ontology data

The set of GO categories has not been limited to the 2020 data at the time of this writing.

hs_go <- sm(load_biomart_go()[["go"]])
hs_length <- hs_annot[, c("ensembl_gene_id", "cds_length")]
colnames(hs_length) <- c("ID", "length")

5 The complete set of data

Before we do any of the following subsets/analyses of the data, we need to collect it all in one place. Let’s do that here and name it ‘hs_valid’ meaning it is the set of valid data for Homo sapiens.

sanitize_columns <- c("visitnumber", "clinicaloutcome", "donor",
                      "typeofcells", "clinicalpresentation",
                      "condition", "batch")
hs_expt <- create_expt(samplesheet,
                       file_column="hg38100hisatfile",
                       savefile=glue::glue("rda/hs_expt_all-v{ver}.rda"),
                       gene_info=hs_annot) %>%
  exclude_genes_expt(column="gene_biotype", method="keep",
                     pattern="protein_coding", meta_column="ncrna_lost") %>%
  sanitize_expt_metadata(columns=sanitize_columns) %>%
  set_expt_factors(columns=sanitize_columns, class="factor") %>%
  set_expt_conditions(fact="clinicaloutcome") %>%
  set_expt_batches(fact="visitnumber")
## Reading the sample metadata.
## Dropped 68 rows from the sample metadata because they were blank.
## The sample definitions comprises: 238 rows(samples) and 82 columns(metadata fields).
## Warning in create_expt(samplesheet, file_column = "hg38100hisatfile", savefile =
## glue::glue("rda/hs_expt_all-v{ver}.rda"), : Some samples were removed when cross
## referencing the samples against the count data.
## Matched 21452 annotations and counts.
## Bringing together the count matrix and gene information.
## Some annotations were lost in merging, setting them to 'undefined'.
## The final expressionset has 21481 rows and 224 columns.
## Before removal, there were 21481 genes, now there are 19941.
## There are 19 samples which kept less than 90 percent counts.
## TMRC30015 TMRC30017 TMRC30019 TMRC30044 TMRC30045 TMRC30154 TMRC30097 TMRC30075 
##     79.24     85.72     89.75     80.34     73.33     83.20     89.90     86.97 
## TMRC30087 TMRC30101 TMRC30104 TMRC30114 TMRC30126 TMRC30127 TMRC30120 TMRC30128 
##     83.63     88.41     80.29     87.62     84.52     89.49     79.16     82.53 
## TMRC30141 TMRC30131 TMRC30073 
##     89.40     86.82     89.26
levels(pData(hs_expt[["expressionset"]])[["visitnumber"]]) <- list(
    '0'="notapplicable", '1'=1, '2'=2, '3'=3)

5.1 Add the CRF patient metadata

Let us also merge in the clinician’s metadata. I worry a little that this might not be allowed for dbGap data, but if it is a problem I suspect we can just remove the bad columns from it. Also note that I rarely use the join function, but it is somewhat required here because I do not want to risk shuffling the metadata when I add the new metadata, which comes from a spreadsheet sorted by patient, not sample. In doing this I therefore just created a new column ‘join’ which contains the shared information, e.g. the patient ID from the existing metadata and the same ID from the CRF file which has been coerced into lowercase.

hs_pd <- pData(hs_expt)
start <- rownames(hs_pd)
hs_crf <- openxlsx::read.xlsx(crf_metadata)
hs_crf[["join"]] <- tolower(hs_crf[["codigo_paciente"]])
hs_pd[["join"]] <- hs_pd[["tubelabelorigin"]]
test <- plyr::join(hs_pd, hs_crf, by="join")
test[["join"]] <- NULL
rownames(test) <- rownames(hs_pd)
na_idx <- is.na(test)
test[na_idx] <- "undefined"
pData(hs_expt) <- test

5.2 Set our initial coverage goal

There exists a baseline coverage below which we do not wish to fall. One likely way to approach it heuristically is to assume we should observe some number of genes. With that in mind, I arbitrarily chose 11,000 non-zero genes as the minimum.

hs_valid <- subset_expt(hs_expt, nonzero=11000)
## The samples (and read coverage) removed when filtering 11000 non-zero genes are:
## TMRC30010 TMRC30050 TMRC30052 
##     52471    808149   3087347
## subset_expt(): There were 224, now there are 221 samples.

5.3 Set up initial data subsets of interest

One of the first global metrics I would like to provide is the set of library sizes. Unfortunately, we have too many samples to fit on a screen now. Therefore, I am going to do an early split of the data by cell type in the hopes that doing so will make it possible to visualize the library sizes/nonzero genes.

The initial factor for this is ‘typeofcells’.

table(pData(hs_valid)[["typeofcells"]])
## 
##      biopsy eosinophils macrophages   monocytes neutrophils       pbmcs 
##          52          35          14          58          56           6
biopsy_samples <- subset_expt(hs_valid, subset="typeofcells=='biopsy'")
## subset_expt(): There were 221, now there are 52 samples.
eosinophil_samples <- subset_expt(hs_valid, subset="typeofcells=='eosinophils'")
## subset_expt(): There were 221, now there are 35 samples.
macrophage_samples <- subset_expt(hs_valid, subset="typeofcells=='macrophages'")
## subset_expt(): There were 221, now there are 14 samples.
monocyte_samples <- subset_expt(hs_valid, subset="typeofcells=='monocytes'")
## subset_expt(): There were 221, now there are 58 samples.
neutrophil_samples <- subset_expt(hs_valid, subset="typeofcells=='neutrophils'")
## subset_expt(): There were 221, now there are 56 samples.
pbmc_samples <- subset_expt(hs_valid, subset="typeofcells=='pbmcs'")
## subset_expt(): There were 221, now there are 6 samples.
## Currently, these are not used, but instead I pulled the samples from the hs_clinical
## which means the biopsies are not included.
v1_samples <- subset_expt(hs_valid, subset="visitnumber=='1'")
## subset_expt(): There were 221, now there are 88 samples.
v1_biopsies <- subset_expt(v1_samples, subset="typeofcells=='biopsy'")
## subset_expt(): There were 88, now there are 28 samples.
v1_monocytes <- subset_expt(v1_samples, subset="typeofcells=='monocytes'")
## subset_expt(): There were 88, now there are 21 samples.
v1_neutrophils <- subset_expt(v1_samples, subset="typeofcells=='neutrophils'")
## subset_expt(): There were 88, now there are 21 samples.
v1_eosinophils <- subset_expt(v1_samples, subset="typeofcells=='eosinophils'")
## subset_expt(): There were 88, now there are 12 samples.
v2_samples <- subset_expt(hs_valid, subset="visitnumber=='2'")
## subset_expt(): There were 221, now there are 60 samples.
v2_biopsies <- subset_expt(v2_samples, subset="typeofcells=='biopsy'")
## subset_expt(): There were 60, now there are 12 samples.
v2_monocytes <- subset_expt(v2_samples, subset="typeofcells=='monocytes'")
## subset_expt(): There were 60, now there are 19 samples.
v2_neutrophils <- subset_expt(v2_samples, subset="typeofcells=='neutrophils'")
## subset_expt(): There were 60, now there are 18 samples.
v2_eosinophils <- subset_expt(v2_samples, subset="typeofcells=='eosinophils'")
## subset_expt(): There were 60, now there are 11 samples.
v3_samples <- subset_expt(hs_valid, subset="visitnumber=='3'")
## subset_expt(): There were 221, now there are 59 samples.
v3_biopsies <- subset_expt(v3_samples, subset="typeofcells=='biopsy'")
## subset_expt(): There were 59, now there are 12 samples.
v3_monocytes <- subset_expt(v3_samples, subset="typeofcells=='monocytes'")
## subset_expt(): There were 59, now there are 18 samples.
v3_neutrophils <- subset_expt(v3_samples, subset="typeofcells=='neutrophils'")
## subset_expt(): There were 59, now there are 17 samples.
v3_eosinophils <- subset_expt(v3_samples, subset="typeofcells=='eosinophils'")
## subset_expt(): There were 59, now there are 12 samples.

6 Contrasts of interest

This might be a bit early to consider the contrasts, but I think we should consider this question immediately. The main thing we will be comparing is of course cure vs. fail; but we may also look at the visits and compare cell types.

cf_contrasts <- list(
    "fail_vs_cure" = c("failure", "cure"))
visit_contrasts <- list(
    "v2v1" = c("c2", "c1"),
    "v3v1" = c("c3", "c1"),
    "v3v2" = c("c3", "c2"))
type_contrasts <- list(
    "mono_biopsy" = c("monocytes", "biopsy"),
    "eosinophil_biopsy" = c("eosinophils", "biopsy"),
    "neutrophil_biopsy" = c("neutrophils", "biopsy"))

7 Parasite reads

Let us see if we can make an expressionset of the parasite reads in the TMRC3 samples and distinguish between the faux and real reads. E.g: Are there samples which definitively contain parasites?

lp_expt <- create_expt("sample_sheets/tmrc3_samples_20211207.xlsx",
                       file_column="lpanamensisv36hisatfile", gene_info = NULL) %>%
  subset_expt(coverage=20) %>%
  set_expt_conditions(fact="typeofcells")
## Reading the sample metadata.
## Dropped 68 rows from the sample metadata because they were blank.
## The sample definitions comprises: 238 rows(samples) and 75 columns(metadata fields).
## Warning in create_expt("sample_sheets/tmrc3_samples_20211207.xlsx", file_column
## = "lpanamensisv36hisatfile", : Some samples were removed when cross referencing
## the samples against the count data.
## Matched 8778 annotations and counts.
## Bringing together the count matrix and gene information.
## Warning in create_expt("sample_sheets/tmrc3_samples_20211207.xlsx", file_column
## = "lpanamensisv36hisatfile", : The following samples have no counts!
## TMRC30010TMRC30144TMRC30145TMRC30146TMRC30185TMRC30207TMRC30217TMRC30219TMRC30220TMRC30209TMRC30210TMRC30211TMRC30212TMRC30213TMRC30214TMRC30216TMRC30221TMRC30222TMRC30223TMRC30225TMRC30226TMRC30227TMRC30229TMRC30230TMRC30231TMRC30233TMRC30234TMRC30235
## Saving the expressionset to 'expt.rda'.
## The final expressionset has 8778 rows and 223 columns.
## The samples removed (and read coverage) when filtering samples with less than 20 reads are:
## TMRC30001 TMRC30002 TMRC30003 TMRC30004 TMRC30007 TMRC30008 TMRC30009 TMRC30010 
##        12         8         9        16         3        16        16         0 
## TMRC30011 TMRC30012 TMRC30013 TMRC30014 TMRC30030 TMRC30031 TMRC30037 TMRC30036 
##         5         9        13         4         3         8         9        11 
## TMRC30142 TMRC30143 TMRC30144 TMRC30145 TMRC30146 TMRC30147 TMRC30185 TMRC30124 
##         4         1         0         0         0         1         0         3 
## TMRC30207 TMRC30208 TMRC30217 TMRC30218 TMRC30219 TMRC30220 TMRC30209 TMRC30210 
##         0         1         0         2         0         0         0         0 
## TMRC30211 TMRC30212 TMRC30213 TMRC30214 TMRC30215 TMRC30216 TMRC30221 TMRC30222 
##         0         0         0         0         1         0         0         0 
## TMRC30223 TMRC30224 TMRC30225 TMRC30226 TMRC30227 TMRC30229 TMRC30230 TMRC30231 
##         0         2         0         0         0         0         0         0 
## TMRC30232 TMRC30233 TMRC30234 TMRC30235 
##         1         0         0         0
## subset_expt(): There were 223, now there are 171 samples.
visit_fact <- pData(lp_expt)[["visitnumber"]]
batch_na <- is.na(visit_fact)
visit_fact[batch_na] <- "undefined"
lp_expt <- set_expt_batches(lp_expt, fact = visit_fact)

lp_norm <- normalize_expt(lp_expt, filter="simple", norm="quant",
                          convert="cpm", transform="log2")
## Removing 75 low-count genes (8703 remaining).
## transform_counts: Found 200 values equal to 0, adding 1 to the matrix.
plotted <- plot_pca(lp_norm, plot_labels=FALSE)
plotted$plot

plotted_3d <- plot_3d_pca(plotted)

8 Distributions/Visualizations of interest

The sets of samples used to visualize the data will also comprise the sets used when later performing the various differential expression analyses.

8.1 Global metrics

Start out with some initial metrics of all samples. The most obvious are plots of the numbers of non-zero genes observed, heatmaps showing the relative relationships among the samples, the relative library sizes, and some PCA. It might be smart to split the library sizes up across subsets of the data, because they have expanded too far to see well on a computer screen.

The most likely factors to query when considering the entire dataset are cure/fail, visit, and cell type. This is the level at which we will choose samples to exclude from future analyses.

plot_legend(biopsy_samples)$plot

plot_libsize(biopsy_samples)$plot

plot_nonzero(biopsy_samples)$plot
## Warning: ggrepel: 32 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## Minimum number of biopsy genes: ~ 14,000

plot_libsize(eosinophil_samples)$plot

plot_nonzero(eosinophil_samples)$plot
## Warning: ggrepel: 11 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## Minimum number of eosinophil genes: ~ 13,500

plot_libsize(macrophage_samples)$plot

plot_nonzero(macrophage_samples)$plot

## Minimum number of macrophage genes: ~ 14,000

plot_libsize(monocyte_samples)$plot

plot_nonzero(monocyte_samples)$plot
## Warning: ggrepel: 44 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## Minimum number of monocyte genes: ~ 7,500 before setting the minimum.

plot_libsize(neutrophil_samples)$plot

plot_nonzero(neutrophil_samples)$plot
## Warning: ggrepel: 34 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## Minimum number of neutrophil genes: ~ 10,000 before setting minimum coverage.

plot_libsize(pbmc_samples)$plot

plot_nonzero(pbmc_samples)$plot

## Minimum number of pbmc genes: ~ 14,800

Now that those ‘global’ metrics are out of the way, lets look at some global metrics of the data following normalization; the most likely plots are of course PCA but also a couple of heatmaps.

type_valid <- set_expt_conditions(hs_valid, fact="typeofcells")
all_norm <- sm(normalize_expt(type_valid, transform="log2", norm="quant",
                              convert="cpm", filter=TRUE))

all_pca <- plot_pca(all_norm, plot_labels=FALSE,
                    plot_title="PCA - Cell type", size_column="visitnumber")
pp(file=glue("images/tmrc3_pca_nolabels-v{ver}.png"), image=all_pca$plot)

write.csv(all_pca$table, file="coords/hs_donor_pca_coords.csv")
plot_corheat(all_norm, plot_title="Heirarchical clustering:
         cell types")$plot

Continue looking, but switch the conditions/colors so that the clinical outcome becomes the focus and get rid of a few samples which are not actually a part of the TMRC3 focus (e.g. the PBMC and macrophage samples, which are all from the Wellcome Trust).

8.1.1 Clinically relevant samples

Included in this group will be the samples from patients who were lost.

hs_clinical <- hs_valid %>%
  set_expt_conditions(fact="clinicaloutcome") %>%
  set_expt_batches(fact="typeofcells") %>%
  subset_expt(subset="typeofcells!='pbmcs'&typeofcells!='macrophages'")
## subset_expt(): There were 221, now there are 201 samples.
chosen_colors <- c("#D95F02", "#7570B3", "#1B9E77", "#FF0000", "#FF0000")
names(chosen_colors) <- c("cure", "failure", "lost", "null", "notapplicable")
hs_clinical <- set_expt_colors(hs_clinical, colors=chosen_colors)
## Warning in set_expt_colors(hs_clinical, colors = chosen_colors): Colors for the
## following categories are not being used: null.
newnames <- make.names(pData(hs_clinical)[["samplename"]], unique=TRUE)
hs_clinical <- set_expt_samplenames(hs_clinical, newnames=newnames)

hs_clinical_norm <- sm(normalize_expt(hs_clinical, filter=TRUE, transform="log2",
                                      convert="cpm", norm="quant"))
clinical_pca <- plot_pca(hs_clinical_norm, plot_labels=FALSE,
                         size_column="visitnumber", cis=NULL,
                         plot_title="PCA - clinical samples")
pp(file=glue("images/all_clinical_nobatch_pca-v{ver}.png"),
   image=clinical_pca$plot, height=8, width=20)

table(pData(hs_clinical)[["condition"]])
## 
##          cure       failure          lost notapplicable 
##           106            78            15             2

8.1.1.1 Remove the lost samples

Now let us focus purely on the cures and fails.

clinical_nolost <- subset_expt(hs_clinical,
                               subset="condition!='lost'&condition!='notapplicable'")
## subset_expt(): There were 201, now there are 184 samples.

The biopsy samples are a bit peculiar, therefore let us repeat this without them.

8.1.2 Repeat without biopsy samples

hs_clinical_nobiop <- hs_clinical %>%
  subset_expt(subset="typeofcells!='biopsy'") %>%
  subset_expt(subset="condition=='lost'|condition=='cure'|condition=='failure'")
## subset_expt(): There were 201, now there are 149 samples.
## subset_expt(): There were 149, now there are 147 samples.
hs_clinical_nobiop_norm <- sm(normalize_expt(hs_clinical_nobiop, filter=TRUE, transform="log2",
                                             convert="cpm", norm="quant"))
clinical_nobiop_pca <- plot_pca(hs_clinical_nobiop_norm, plot_labels=FALSE, cis=NULL,
                                plot_title="PCA - clinical samples without biopsies")
pp(file=glue("images/all_clinical_nobiop_nobatch_pca-v{ver}.png"),
   image=clinical_nobiop_pca$plot)

8.1.3 Visualize again with sva

hs_clinical_nb <- normalize_expt(hs_clinical, filter=TRUE, batch="svaseq",
                                 transform="log2", convert="cpm")
## Removing 5207 low-count genes (14734 remaining).
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## batch_counts: Before batch/surrogate estimation, 590592 entries are 0<x<1: 20%.
## Setting 30774 low elements to zero.
## transform_counts: Found 30774 values equal to 0, adding 1 to the matrix.
clinical_batch_pca <- plot_pca(hs_clinical_nb, plot_labels=FALSE, cis=NULL,
                               size_column="visitnumber", plot_title="PCA - clinical samples")
clinical_batch_pca$plot

hs_clinical_nobiop_nb <- sm(normalize_expt(hs_clinical_nobiop, filter=TRUE, batch="svaseq",
                                           transform="log2", convert="cpm"))
clinical_nobiop_batch_pca <- plot_pca(hs_clinical_nobiop_nb,
                                      plot_title="PCA - clinical samples without biopsies",
                                      plot_labels=FALSE)
pp(file="images/clinical_batch.png", image=clinical_nobiop_batch_pca$plot)

test <- plot_pca(hs_clinical_nobiop_nb, size_column="visitnumber",
                 plot_title="PCA - clinical samples without biopsies",
                 plot_labels=FALSE)
test$plot

clinical_nobiop_batch_tsne <- plot_tsne(hs_clinical_nobiop_nb,
                                        plot_title="tSNE - clinical samples without biopsies",
                                        plot_labels=FALSE)
clinical_nobiop_batch_tsne$plot

8.1.4 Samples separated by visit

Separate the samples by visit in order to more easily see what patterns emerge across cell type and clinical outcome.

I have a couple of likely starting points for this. The data sets: hs_clinical and clinical_nolost are the most likely. Given that this, at least in theory, the lost samples are not relevant.

8.1.4.1 All visits together

visit_expt <- set_expt_conditions(hs_clinical, fact = "visitnumber") %>%
  set_expt_batches(fact = "clinicaloutcome")

visit_nb <- normalize_expt(visit_expt, transform = "log2", convert="cpm",
                           filter = TRUE, batch = "svaseq")
## Removing 5207 low-count genes (14734 remaining).
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## batch_counts: Before batch/surrogate estimation, 590592 entries are 0<x<1: 20%.
## Setting 35107 low elements to zero.
## transform_counts: Found 35107 values equal to 0, adding 1 to the matrix.
plot_pca(visit_nb)$plot
## plot labels was not set and there are more than 100 samples, disabling it.

8.1.4.2 All visits, separated by cell type

visit_biopsy <- subset_expt(visit_expt, subset = "typeofcells=='biopsy'")
## subset_expt(): There were 201, now there are 52 samples.
visit_monocyte <- subset_expt(visit_expt, subset = "typeofcells=='monocytes'")
## subset_expt(): There were 201, now there are 58 samples.
visit_neutrophil <- subset_expt(visit_expt, subset = "typeofcells=='neutrophils'")
## subset_expt(): There were 201, now there are 56 samples.
visit_eosinophil <- subset_expt(visit_expt, subset = "typeofcells=='eosinophils'")
## subset_expt(): There were 201, now there are 35 samples.

8.1.4.3 Visit 1 alone

v1_clinical <- subset_expt(visit_expt, subset = "visitnumber=='1'") %>%
  set_expt_conditions(fact = "clinicaloutcome") %>%
  set_expt_batches(fact = "typeofcells")
## subset_expt(): There were 201, now there are 82 samples.
v1_nb <- normalize_expt(v1_clinical, transform = "log2", convert = "cpm",
                        filter = TRUE, batch = "svaseq")
## Removing 5627 low-count genes (14314 remaining).
## batch_counts: Before batch/surrogate estimation, 75537 entries are x==0: 6%.
## batch_counts: Before batch/surrogate estimation, 205468 entries are 0<x<1: 18%.
## Setting 10928 low elements to zero.
## transform_counts: Found 10928 values equal to 0, adding 1 to the matrix.
plot_pca(v1_nb)$plot
## Warning: ggrepel: 42 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

8.1.4.4 Visit 2 alone

v2_clinical <- subset_expt(visit_expt, subset="visitnumber=='2'") %>%
  set_expt_conditions(fact = "clinicaloutcome") %>%
  set_expt_batches(fact = "typeofcells")
## subset_expt(): There were 201, now there are 60 samples.
v2_nb <- normalize_expt(v2_clinical, transform = "log2", convert = "cpm", norm = "quant",
                        filter = TRUE, batch = "svaseq")
## Warning in normalize_expt(v2_clinical, transform = "log2", convert = "cpm", :
## Quantile normalization and sva do not always play well together.
## Removing 5839 low-count genes (14102 remaining).
## batch_counts: Before batch/surrogate estimation, 526 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 180742 entries are 0<x<1: 21%.
## Setting 6254 low elements to zero.
## transform_counts: Found 6254 values equal to 0, adding 1 to the matrix.
plot_pca(v2_nb)$plot

8.1.4.5 Visit 3 alone

v3_clinical <- subset_expt(visit_expt, subset="visitnumber=='3'") %>%
  set_expt_conditions(fact = "clinicaloutcome") %>%
  set_expt_batches(fact = "typeofcells")
## subset_expt(): There were 201, now there are 59 samples.
v3_nb <- normalize_expt(v3_clinical, transform = "log2", convert = "cpm", norm = "quant",
                        filter = TRUE, batch = "svaseq")
## Warning in normalize_expt(v3_clinical, transform = "log2", convert = "cpm", :
## Quantile normalization and sva do not always play well together.
## Removing 5774 low-count genes (14167 remaining).
## batch_counts: Before batch/surrogate estimation, 74 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 132981 entries are 0<x<1: 16%.
## Setting 2511 low elements to zero.
## transform_counts: Found 2511 values equal to 0, adding 1 to the matrix.
plot_pca(v3_nb)$plot
## Warning: ggrepel: 6 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

8.1.5 Samples separated by cell type

Separate the samples by cell type in order to more easily observe patterns with respect to visit and clinical outcome.

8.1.5.1 Biopsies

biopsy_norm <- normalize_expt(biopsy_samples, norm = "quant", convert = "cpm",
                              transform = "log2", filter = TRUE)
## Removing 5738 low-count genes (14203 remaining).
## transform_counts: Found 16 values equal to 0, adding 1 to the matrix.
plot_pca(biopsy_norm)$plot

biopsy_nb <- normalize_expt(biopsy_samples, convert = "cpm",
                            transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 5738 low-count genes (14203 remaining).
## batch_counts: Before batch/surrogate estimation, 5504 entries are x==0: 1%.
## batch_counts: Before batch/surrogate estimation, 44637 entries are 0<x<1: 6%.
## Setting 1876 low elements to zero.
## transform_counts: Found 1876 values equal to 0, adding 1 to the matrix.
plot_pca(biopsy_nb)$plot

8.1.5.2 Monocytes

monocyte_norm <- normalize_expt(monocyte_samples, norm = "quant", convert = "cpm",
                                transform = "log2", filter = TRUE)
## Removing 8744 low-count genes (11197 remaining).
## transform_counts: Found 11 values equal to 0, adding 1 to the matrix.
plot_pca(monocyte_norm, plot_labels = FALSE)$plot

monocyte_nb <- normalize_expt(monocyte_samples, convert = "cpm",
                            transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 8744 low-count genes (11197 remaining).
## batch_counts: Before batch/surrogate estimation, 2764 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 42938 entries are 0<x<1: 7%.
## Setting 1470 low elements to zero.
## transform_counts: Found 1470 values equal to 0, adding 1 to the matrix.
plot_pca(monocyte_nb, plot_labels = FALSE)$plot

8.1.5.3 Neutrophils

neutrophil_norm <- normalize_expt(neutrophil_samples, norm = "quant", convert = "cpm",
                                transform = "log2", filter = TRUE)
## Removing 10575 low-count genes (9366 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
plot_pca(neutrophil_norm, plot_labels = FALSE)$plot

neutrophil_nb <- normalize_expt(neutrophil_samples, convert = "cpm",
                            transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 10575 low-count genes (9366 remaining).
## batch_counts: Before batch/surrogate estimation, 1959 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 49180 entries are 0<x<1: 9%.
## Setting 1336 low elements to zero.
## transform_counts: Found 1336 values equal to 0, adding 1 to the matrix.
plot_pca(neutrophil_nb, plot_labels = FALSE)$plot

8.1.5.4 Eosinophils

eosinophil_norm <- normalize_expt(eosinophil_samples, norm = "quant", convert = "cpm",
                                transform = "log2", filter = TRUE)
## Removing 9113 low-count genes (10828 remaining).
## transform_counts: Found 5 values equal to 0, adding 1 to the matrix.
plot_pca(eosinophil_norm, plot_labels = FALSE)$plot

eosinophil_nb <- normalize_expt(eosinophil_samples, convert = "cpm",
                            transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 9113 low-count genes (10828 remaining).
## batch_counts: Before batch/surrogate estimation, 973 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 23479 entries are 0<x<1: 6%.
## Setting 689 low elements to zero.
## transform_counts: Found 689 values equal to 0, adding 1 to the matrix.
plot_pca(eosinophil_nb, plot_labels = FALSE)$plot

8.1.5.5 Monocytes, Neutrophils, and Eosinophils

9 Differential expression analyses

The primary goal is to learn about cure vs. fail.

9.1 Cure/Fail all samples

cf_clinical_de <- all_pairwise(hs_clinical, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (14734 remaining).
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## batch_counts: Before batch/surrogate estimation, 590592 entries are 0<x<1: 20%.
## Setting 30774 low elements to zero.
## transform_counts: Found 30774 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

cf_clinical_tables <- combine_de_tables(
    cf_clinical_de,
    keepers = cf_contrasts,
    excel = glue::glue("excel/cf_clinical_tables-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/cf_clinical_sig-v{ver}.xlsx"))
## Deleting the file excel/cf_clinical_tables-v202011.xlsx before writing the tables.
## Deleting the file excel/cf_clinical_sig-v202011.xlsx before writing the tables.

9.1.1 By cell type

9.1.1.1 Cure/Fail Biopsies

cf_biopsy_de <- all_pairwise(biopsy_samples, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 5504 entries are x==0: 1%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (14203 remaining).
## batch_counts: Before batch/surrogate estimation, 5504 entries are x==0: 1%.
## batch_counts: Before batch/surrogate estimation, 44637 entries are 0<x<1: 6%.
## Setting 1876 low elements to zero.
## transform_counts: Found 1876 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

cf_biopsy_tables <- combine_de_tables(
    cf_biopsy_de,
    keepers = cf_contrasts,
    excel = glue::glue("excel/cf_biopsy_tables-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/cf_biopsy_sig-v{ver}.xlsx"))
## Deleting the file excel/cf_biopsy_tables-v202011.xlsx before writing the tables.

9.1.1.2 Cure/Fail Monocytes

cf_monocyte_de <- all_pairwise(monocyte_samples, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 2764 entries are x==0: 0%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (11197 remaining).
## batch_counts: Before batch/surrogate estimation, 2764 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 42938 entries are 0<x<1: 7%.
## Setting 1470 low elements to zero.
## transform_counts: Found 1470 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

cf_monocyte_tables <- combine_de_tables(
    cf_monocyte_de,
    keepers = cf_contrasts,
    excel = glue::glue("excel/cf_monocyte_tables-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/cf_monocyte_sig-v{ver}.xlsx"))
## Deleting the file excel/cf_monocyte_tables-v202011.xlsx before writing the tables.
## Deleting the file excel/cf_monocyte_sig-v202011.xlsx before writing the tables.

9.1.1.3 Cure/Fail Neutrophils

cf_neutrophil_de <- all_pairwise(neutrophil_samples, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 1959 entries are x==0: 0%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (9366 remaining).
## batch_counts: Before batch/surrogate estimation, 1959 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 49180 entries are 0<x<1: 9%.
## Setting 1336 low elements to zero.
## transform_counts: Found 1336 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

cf_neutrophil_tables <- combine_de_tables(
    cf_neutrophil_de,
    keepers = cf_contrasts,
    excel = glue::glue("excel/cf_neutrophil_tables-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/cf_neutrophil_sig-v{ver}.xlsx"))
## Deleting the file excel/cf_neutrophil_tables-v202011.xlsx before writing the tables.
## Deleting the file excel/cf_neutrophil_sig-v202011.xlsx before writing the tables.

9.1.1.4 Cure/Fail Eosinophils

cf_eosinophil_de <- all_pairwise(eosinophil_samples, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 973 entries are x==0: 0%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (10828 remaining).
## batch_counts: Before batch/surrogate estimation, 973 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 23479 entries are 0<x<1: 6%.
## Setting 689 low elements to zero.
## transform_counts: Found 689 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

cf_eosinophil_tables <- combine_de_tables(
    cf_eosinophil_de,
    keepers = cf_contrasts,
    excel = glue::glue("excel/cf_eosinophil_tables-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/cf_eosinophil_sig-v{ver}.xlsx"))
## Deleting the file excel/cf_eosinophil_tables-v202011.xlsx before writing the tables.
## Deleting the file excel/cf_eosinophil_sig-v202011.xlsx before writing the tables.

9.1.1.5 Cure/Fail clinical (Not biopsies)

cf_nobiopsy_de <- all_pairwise(hs_clinical_nobiop, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 46091 entries are x==0: 3%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (12168 remaining).
## batch_counts: Before batch/surrogate estimation, 46091 entries are x==0: 3%.
## batch_counts: Before batch/surrogate estimation, 317724 entries are 0<x<1: 18%.
## Setting 14152 low elements to zero.
## transform_counts: Found 14152 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

cf_nobiopsy_tables <- combine_de_tables(
    cf_nobiopsy_de,
    keepers = cf_contrasts,
    excel = glue::glue("excel/cf_nobiopsy_tables-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/cf_nobiopsy_sig-v{ver}.xlsx"))
## Deleting the file excel/cf_nobiopsy_tables-v202011.xlsx before writing the tables.
## Deleting the file excel/cf_nobiopsy_sig-v202011.xlsx before writing the tables.

9.1.2 By visit

For these contrasts, we want to see fail_v1 vs. cure_v1, fail_v2 vs. cure_v2 etc. As a result, we will need to juggle the data slightly and add another set of contrasts.

9.1.3 Setting up

visit_cf_contrasts <- list(
    "v1fail_vs_cure" = c("v1failure", "v1cure"),
    "v2fail_vs_cure" = c("v2failure", "v2cure"),
    "v3fail_vs_cure" = c("v3failure", "v3cure"))
visit_cf_expt_factor <- paste0("v", pData(hs_clinical)[["visitnumber"]],
                               pData(hs_clinical)[["condition"]])
visit_cf_expt <- set_expt_conditions(hs_clinical, fact = visit_cf_expt_factor)

visit_cf_biopsy <- subset_expt(visit_cf_expt, subset="typeofcells=='biopsy'")
## subset_expt(): There were 201, now there are 52 samples.
visit_cf_eosinophil <- subset_expt(visit_cf_expt, subset="typeofcells=='eosinophils'")
## subset_expt(): There were 201, now there are 35 samples.
visit_cf_monocyte <- subset_expt(visit_cf_expt, subset="typeofcells=='monocytes'")
## subset_expt(): There were 201, now there are 58 samples.
visit_cf_neutrophil <- subset_expt(visit_cf_expt, subset="typeofcells=='neutrophils'")
## subset_expt(): There were 201, now there are 56 samples.

9.1.3.1 Cure/Fail by visits, all cell types

visit_cf_all_de <- all_pairwise(visit_cf_expt, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (14734 remaining).
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## batch_counts: Before batch/surrogate estimation, 590592 entries are 0<x<1: 20%.
## Setting 32744 low elements to zero.
## transform_counts: Found 32744 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_cf_all_tables <- combine_de_tables(
    visit_cf_all_de,
    keepers = visit_cf_contrasts,
    excel = glue::glue("excel/visit_cf_all_tables-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_cf_all_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_cf_all_tables-v202011.xlsx before writing the tables.

9.1.3.2 Cure/Fail by visit, Biopsies

visit_cf_biopsy_de <- all_pairwise(visit_cf_expt, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (14734 remaining).
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## batch_counts: Before batch/surrogate estimation, 590592 entries are 0<x<1: 20%.
## Setting 32744 low elements to zero.
## transform_counts: Found 32744 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_cf_biopsy_tables <- combine_de_tables(
    visit_cf_biopsy_de,
    keepers = visit_cf_contrasts,
    excel = glue::glue("excel/visit_cf_biopsy_tables-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_cf_biopsy_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_cf_biopsy_tables-v202011.xlsx before writing the tables.

9.1.3.3 Cure/Fail by visit, Monocytes

visit_cf_monocyte_de <- all_pairwise(visit_cf_expt, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (14734 remaining).
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## batch_counts: Before batch/surrogate estimation, 590592 entries are 0<x<1: 20%.
## Setting 32744 low elements to zero.
## transform_counts: Found 32744 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_cf_monocyte_tables <- combine_de_tables(
    visit_cf_monocyte_de,
    keepers = visit_cf_contrasts,
    excel = glue::glue("excel/visit_cf_monocyte_tables-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_cf_monocyte_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_cf_monocyte_tables-v202011.xlsx before writing the tables.

9.1.3.4 Cure/Fail by visit, Neutrophils

visit_cf_neutrophil_de <- all_pairwise(visit_cf_expt, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (14734 remaining).
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## batch_counts: Before batch/surrogate estimation, 590592 entries are 0<x<1: 20%.
## Setting 32744 low elements to zero.
## transform_counts: Found 32744 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_cf_neutrophil_tables <- combine_de_tables(
    visit_cf_neutrophil_de,
    keepers = visit_cf_contrasts,
    excel = glue::glue("excel/visit_cf_neutrophil_tables-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_cf_neutrophil_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_cf_neutrophil_tables-v202011.xlsx before writing the tables.

9.1.3.5 Cure/Fail by visit, Eosinophils

visit_cf_eosinophil_de <- all_pairwise(visit_cf_expt, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (14734 remaining).
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## batch_counts: Before batch/surrogate estimation, 590592 entries are 0<x<1: 20%.
## Setting 32744 low elements to zero.
## transform_counts: Found 32744 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_cf_eosinophil_tables <- combine_de_tables(
    visit_cf_eosinophil_de,
    keepers = visit_cf_contrasts,
    excel = glue::glue("excel/visit_cf_eosinophil_tables-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_cf_eosinophil_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_cf_eosinophil_tables-v202011.xlsx before writing the tables.

9.2 Persistence in visit 3

Having put some SL read mapping information in the sample sheet, Maria Adelaida added a new column using it with the putative persistence state on a per-sample basis. One question which arised from that: what differences are observable between the persistent yes vs. no samples on a per-cell-type basis among the visit 3 samples.

9.2.1 Setting up

First things first, create the datasets.

persistence_expt <- subset_expt(hs_clinical, subset = "persistence=='Y'|persistence=='N'") %>%
  subset_expt(subset = 'visitnumber==3') %>%
  set_expt_conditions(fact = 'persistence')
## subset_expt(): There were 201, now there are 148 samples.
## subset_expt(): There were 148, now there are 49 samples.
persistence_biopsy <- subset_expt(persistence_expt, subset = "typeofcells=='biopsy'")
## subset_expt(): There were 49, now there are 9 samples.
persistence_monocyte <- subset_expt(persistence_expt, subset = "typeofcells=='monocytes'")
## subset_expt(): There were 49, now there are 16 samples.
persistence_neutrophil <- subset_expt(persistence_expt, subset = "typeofcells=='neutrophils'")
## subset_expt(): There were 49, now there are 14 samples.
persistence_eosinophil <- subset_expt(persistence_expt, subset = "typeofcells=='eosinophils'")
## subset_expt(): There were 49, now there are 10 samples.

9.2.2 Take a look

See if there are any patterns which look usable.

## All
persistence_norm <- normalize_expt(persistence_expt, transform = "log2", convert = "cpm",
                                   norm = "quant", filter = TRUE)
## Removing 5891 low-count genes (14050 remaining).
## transform_counts: Found 45 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_norm)$plot
## Warning: ggrepel: 30 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

persistence_nb <- normalize_expt(persistence_expt, transform = "log2", convert = "cpm",
                                 batch = "svaseq", filter = TRUE)
## Removing 5891 low-count genes (14050 remaining).
## batch_counts: Before batch/surrogate estimation, 45545 entries are x==0: 7%.
## batch_counts: Before batch/surrogate estimation, 134692 entries are 0<x<1: 20%.
## Setting 4937 low elements to zero.
## transform_counts: Found 4937 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_nb)$plot

## Biopsies
persistence_biopsy_norm <- normalize_expt(persistence_biopsy, transform = "log2", convert = "cpm",
                                   norm = "quant", filter = TRUE)
## Removing 6483 low-count genes (13458 remaining).
plot_pca(persistence_biopsy_norm)$plot

## Insufficient data

## Monocytes
persistence_monocyte_norm <- normalize_expt(persistence_monocyte, transform = "log2", convert = "cpm",
                                   norm = "quant", filter = TRUE)
## Removing 9403 low-count genes (10538 remaining).
## transform_counts: Found 17 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_monocyte_norm)$plot

persistence_monocyte_nb <- normalize_expt(persistence_monocyte, transform = "log2", convert = "cpm",
                                 batch = "svaseq", filter = TRUE)
## Removing 9403 low-count genes (10538 remaining).
## batch_counts: Before batch/surrogate estimation, 92 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 4831 entries are 0<x<1: 3%.
## Setting 106 low elements to zero.
## transform_counts: Found 106 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_monocyte_nb)$plot

## Neutrophils
persistence_neutrophil_norm <- normalize_expt(persistence_neutrophil, transform = "log2", convert = "cpm",
                                   norm = "quant", filter = TRUE)
## Removing 11381 low-count genes (8560 remaining).
## transform_counts: Found 1 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_neutrophil_norm)$plot

persistence_neutrophil_nb <- normalize_expt(persistence_neutrophil, transform = "log2", convert = "cpm",
                                 batch = "svaseq", filter = TRUE)
## Removing 11381 low-count genes (8560 remaining).
## batch_counts: Before batch/surrogate estimation, 92 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 5236 entries are 0<x<1: 4%.
## Setting 136 low elements to zero.
## transform_counts: Found 136 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_neutrophil_nb)$plot

## Eosinophils
persistence_eosinophil_norm <- normalize_expt(persistence_eosinophil, transform = "log2", convert = "cpm",
                                   norm = "quant", filter = TRUE)
## Removing 9766 low-count genes (10175 remaining).
## transform_counts: Found 7 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_eosinophil_norm)$plot

persistence_eosinophil_nb <- normalize_expt(persistence_eosinophil, transform = "log2", convert = "cpm",
                                 batch = "svaseq", filter = TRUE)
## Removing 9766 low-count genes (10175 remaining).
## batch_counts: Before batch/surrogate estimation, 88 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 2664 entries are 0<x<1: 3%.
## Setting 60 low elements to zero.
## transform_counts: Found 60 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_eosinophil_nb)$plot

I think this is a bust. But, I can do the de anyhow and see what happens…

9.2.3 persistence DE

persistence_de <- all_pairwise(persistence_expt, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 45545 entries are x==0: 7%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (14050 remaining).
## batch_counts: Before batch/surrogate estimation, 45545 entries are x==0: 7%.
## batch_counts: Before batch/surrogate estimation, 134692 entries are 0<x<1: 20%.
## Setting 4937 low elements to zero.
## transform_counts: Found 4937 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.
persistence_table <- combine_de_tables(
    persistence_de,
    excel = glue::glue("excel/persistence_all_de-v{ver}.xlsx"))
## Deleting the file excel/persistence_all_de-v202011.xlsx before writing the tables.
persistence_monocyte_de <- all_pairwise(persistence_monocyte, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 92 entries are x==0: 0%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (10538 remaining).
## batch_counts: Before batch/surrogate estimation, 92 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 4831 entries are 0<x<1: 3%.
## Setting 106 low elements to zero.
## transform_counts: Found 106 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.
persistence_monocyte_table <- combine_de_tables(
    persistence_monocyte_de,
    excel = glue::glue("excel/persistence_monocyte_de-v{ver}.xlsx"))
## Deleting the file excel/persistence_monocyte_de-v202011.xlsx before writing the tables.
persistence_neutrophil_de <- all_pairwise(persistence_neutrophil, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 92 entries are x==0: 0%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (8560 remaining).
## batch_counts: Before batch/surrogate estimation, 92 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 5236 entries are 0<x<1: 4%.
## Setting 136 low elements to zero.
## transform_counts: Found 136 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.
persistence_neutrophil_table <- combine_de_tables(
    persistence_neutrophil_de,
    excel = glue::glue("excel/persistence_neutrophil_de-v{ver}.xlsx"))
## Deleting the file excel/persistence_neutrophil_de-v202011.xlsx before writing the tables.
persistence_eosinophil_de <- all_pairwise(persistence_eosinophil, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 88 entries are x==0: 0%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (10175 remaining).
## batch_counts: Before batch/surrogate estimation, 88 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 2664 entries are 0<x<1: 3%.
## Setting 60 low elements to zero.
## transform_counts: Found 60 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.
persistence_eosinophil_table <- combine_de_tables(
    persistence_eosinophil_de,
    excel = glue::glue("excel/persistence_eosinophil_de-v{ver}.xlsx"))
## Deleting the file excel/persistence_eosinophil_de-v202011.xlsx before writing the tables.

9.3 Comparing visits without regard to cure/fail

9.3.1 All cell types

visit_all_de <- all_pairwise(visit_expt, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (14734 remaining).
## batch_counts: Before batch/surrogate estimation, 230036 entries are x==0: 8%.
## batch_counts: Before batch/surrogate estimation, 590592 entries are 0<x<1: 20%.
## Setting 35107 low elements to zero.
## transform_counts: Found 35107 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_all_table <- combine_de_tables(
    visit_all_de,
    excel = glue::glue("excel/visit_all_de-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_all_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_all_de-v202011.xlsx before writing the tables.
## Deleting the file excel/visit_all_sig-v202011.xlsx before writing the tables.

9.3.2 Biopsy samples

visit_biopsy_de <- all_pairwise(visit_biopsy, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 5504 entries are x==0: 1%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (14203 remaining).
## batch_counts: Before batch/surrogate estimation, 5504 entries are x==0: 1%.
## batch_counts: Before batch/surrogate estimation, 44637 entries are 0<x<1: 6%.
## Setting 1749 low elements to zero.
## transform_counts: Found 1749 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_biopsy_table <- combine_de_tables(
    visit_biopsy_de,
    keepers = visit_contrasts,
    excel = glue::glue("excel/visit_biopsy_de-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_biopsy_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_biopsy_de-v202011.xlsx before writing the tables.
## Deleting the file excel/visit_biopsy_sig-v202011.xlsx before writing the tables.

9.3.3 Monocyte samples

visit_monocyte_de <- all_pairwise(visit_monocyte, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 2764 entries are x==0: 0%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (11197 remaining).
## batch_counts: Before batch/surrogate estimation, 2764 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 42938 entries are 0<x<1: 7%.
## Setting 1162 low elements to zero.
## transform_counts: Found 1162 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_monocyte_table <- combine_de_tables(
    visit_monocyte_de,
    keepers = visit_contrasts,
    excel = glue::glue("excel/visit_monocyte_de-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_monocyte_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_monocyte_de-v202011.xlsx before writing the tables.
## Deleting the file excel/visit_monocyte_sig-v202011.xlsx before writing the tables.

9.3.4 Neutrophil samples

visit_neutrophil_de <- all_pairwise(visit_neutrophil, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 1959 entries are x==0: 0%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (9366 remaining).
## batch_counts: Before batch/surrogate estimation, 1959 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 49180 entries are 0<x<1: 9%.
## Setting 992 low elements to zero.
## transform_counts: Found 992 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_neutrophil_table <- combine_de_tables(
    visit_neutrophil_de,
    keepers = visit_contrasts,
    excel = glue::glue("excel/visit_neutrophil_de-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_neutrophil_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_neutrophil_de-v202011.xlsx before writing the tables.

9.3.5 Eosinophil samples

visit_eosinophil_de <- all_pairwise(visit_eosinophil, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 973 entries are x==0: 0%.
## Plotting a PCA before surrogate/batch inclusion.
## Using svaseq to visualize before/after batch inclusion.
## Performing a test normalization with: raw
## Removing 0 low-count genes (10828 remaining).
## batch_counts: Before batch/surrogate estimation, 973 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 23479 entries are 0<x<1: 6%.
## Setting 490 low elements to zero.
## transform_counts: Found 490 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_eosinophil_table <- combine_de_tables(
    visit_eosinophil_de,
    keepers = visit_contrasts,
    excel = glue::glue("excel/visit_eosinophil_de-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_eosinophil_sig-v{ver}.xlsx"))

10 Likelihood Ratio Testing

10.1 Shared patterns across visits

lrt_visit <- deseq_lrt(hs_clinical, transform = "vst",
                       interactor_column = "visitnumber",
                       interest_column = "clinicaloutcome")
## converting counts to integer mode
## Error in checkFullRank(modelMatrix): the model matrix is not full rank, so the model cannot be fit as specified.
##   Levels or combinations of levels without any samples have resulted in
##   column(s) of zeros in the model matrix.
## 
##   Please read the vignette section 'Model matrix not full rank':
## 
##   vignette('DESeq2')

10.2 Shared patterns across cell types

11 Gene Set Analyses

11.1 GSEA

11.1.1 Cure/Fail groups

11.1.2 Cell type groups

11.1.3 Visit groups

11.2 GSVA

LS0tCnRpdGxlOiAiTC4gcGFuYW1lbnNpcyAyMDIwMTE6IFJlb3JnYW5pemluZyBUTVJDMyBBbmFseXNlcyIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogaHRtbF9kb2N1bWVudDoKICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgY29kZV9mb2xkaW5nOiBzaG93CiAgZmlnX2NhcHRpb246IHRydWUKICBmaWdfaGVpZ2h0OiA3CiAgZmlnX3dpZHRoOiA3CiAgaGlnaGxpZ2h0OiBkZWZhdWx0CiAga2VlcF9tZDogZmFsc2UKICBtb2RlOiBzZWxmY29udGFpbmVkCiAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgc2VsZl9jb250YWluZWQ6IHRydWUKICB0aGVtZTogcmVhZGFibGUKICB0b2M6IHRydWUKICB0b2NfZmxvYXQ6CiAgIGNvbGxhcHNlZDogZmFsc2UKICAgc21vb3RoX3Njcm9sbDogZmFsc2UKLS0tCgo8c3R5bGU+CiAgYm9keSAubWFpbi1jb250YWluZXIgewogICAgbWF4LXdpZHRoOiAxNjAwcHg7CiAgfQo8L3N0eWxlPgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShocGdsdG9vbHMpCnR0IDwtIHNtKGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKSkKa25pdHI6Om9wdHNfa25pdCRzZXQocHJvZ3Jlc3M9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZT1UUlVFLAogICAgICAgICAgICAgICAgICAgICB3aWR0aD05MCwKICAgICAgICAgICAgICAgICAgICAgZWNobz1UUlVFKQprbml0cjo6b3B0c19jaHVuayRzZXQoZXJyb3I9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aD04LAogICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodD04LAogICAgICAgICAgICAgICAgICAgICAgZHBpPTk2KQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cz00LAogICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAga25pdHIuZHVwbGljYXRlLmxhYmVsPSJhbGxvdyIpCmdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTIpKQp2ZXIgPC0gIjIwMjAxMSIKcHJldmlvdXNfZmlsZSA8LSBwYXN0ZTAoIjAxX2Fubm90YXRpb25fdiIsIHZlciwgIi5SbWQiKQpydW5kYXRlIDwtIGZvcm1hdChTeXMuRGF0ZSgpLCBmb3JtYXQ9IiVZJW0lZCIpCgojI3RtcCA8LSB0cnkoc20obG9hZG1lKGZpbGVuYW1lPWdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iXFwucmRhXFwueHoiLCB4PXByZXZpb3VzX2ZpbGUpKSkpCnJtZF9maWxlIDwtICJ0bXJjM19yZW9yZ2FuaXplZF8yMDIxMTEuUm1kIgpzYXZlZmlsZSA8LSBnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IlxcLnJkYVxcLnh6IiwgeD1ybWRfZmlsZSkKYGBgCgojIEludHJvZHVjdGlvbgoKVGhlIHNldCBvZiBhbmFseXNlcyBwZXJmb3JtZWQgaW4gdG1yYzMgc2FtcGxlIGVzdGltYXRpb24gaGFzIGJlY29tZQp1bm9yZ2FuaXplZCBhbmQgZGlmZmljdWx0IHRvIGZvbGxvdy4gIFRoaXMgaXMgaW50ZW5kZWQgdG8gc3RhcnQgYXQgdGhlCmxldmVsIG9mIGJyb2FkIG9yZ2FuaXphdGlvbiBiZWZvcmUgc3RlcHBpbmcgaW50byB0aGUgYW5hbHlzZXMuCgojIEdvYWxzCgpUaGVzZSBzYW1wbGVzIGFyZSBmcm9tIHBhdGllbnRzIHdobyBlaXRoZXIgc3VjY2Vzc2Z1bGx5IGNsZWFyZWQgYQpMZWlzaG1hbmlhIHBhbmFtZW5zaXMgaW5mZWN0aW9uIGZvbGxvd2luZyB0cmVhdG1lbnQsIG9yIGRpZCBub3QuICBUaGV5CmluY2x1ZGUgYmlvcHNpZXMgZnJvbSBlYWNoIHBhdGllbnQgYWxvbmcgd2l0aCBwdXJpZmljYXRpb25zIGZvcgpNb25vY3l0ZXMsIE5ldXRyb3BoaWxzLCBhbmQgRW9zaW5vcGhpbHMuICBXaGVuIHBvc3NpYmxlLCB0aGlzIHByb2Nlc3MKd2FzIHJlcGVhdGVkIG92ZXIgdGhyZWUgdmlzaXRzOyBidXQgc29tZSBwYXRpZW50cyBkaWQgbm90IHJldHVybgpmb3IgdGhlIHNlY29uZCBvciB0aGlyZCB2aXNpdC4KClRoZSBvdmVyLWFyY2hpbmcgZ29hbCBpcyB0byBsb29rIGZvciBhdHRyaWJ1dGVzKG1vc3QgbGlrZWx5IGdlbmVzKQp3aGljaCBkaXN0aW5ndWlzaCBwYXRpZW50cyB3aG8gZG8gYW5kIGRvIG5vdCBjdXJlIHRoZSBpbmZlY3Rpb24gYWZ0ZXIKdHJlYXRtZW50LiAgSWYgcG9zc2libGUsIHRoZXNlIHdpbGwgYmUgYXBwYXJlbnQgb24gdGhlIGZpcnN0IHZpc2l0LgoKIyMgUmVsZXZhbnQgTWV0YWRhdGEKClRoZSBtZXRhZGF0YSBmYWN0b3JzIChpbiBubyBwYXJ0aWN1bGFyIG9yZGVyKSBvZiB0aGUgZXhwZXJpbWVudCBhcmU6CgoxLiAgVmlzaXQuICAxLCAyLCBvciAzLgoyLiAgUGF0aWVudC4KMy4gIENsaW5pY2FsIG91dGNvbWU6IGN1cmUgb3IgZmFpbC4gIFRoaXMgaW5jbHVkZXMgdGhlIHBvcHVsYXRpb24gb2YKICAgIHBhdGllbnRzIHdobyBkaWQgbm90IHJldHVybiBhbmQgYXJlIGxhYmVsZWQgJ2xvc3QnLiAgVGhpcyBpcywgYnkKICAgIGRlZmluaXRpb24sIGNvbmZvdW5kZWQgd2l0aCBwYXRpZW50Lgo0LiAgRHJ1ZyB0cmVhdG1lbnQuICBNb3N0IG9mIHRoZSBwYXRpZW50cyB3ZXJlIHRyZWF0ZWQgd2l0aCBhbgogICAgYW50aW1vbmlhbCwgYnV0IGEgZmV3IHdlcmUgdHJlYXRlZCB3aXRoIG1pbHRlZm9zaW5lLgo1LiAgQ2VsbCB0eXBlIG9yIGJpb3BzeS4KCk1ldGFkYXRhIHdhcyBhbHNvIGNvbGxlY3RlZCBmb3IgdGhlIHBhdGllbnRzIGFuZCB0aGVyZSBhcmUgbWFueQpmYWN0b3JzIHdoaWNoIGhhdmUgcG90ZW50aWFsIHRvIGFmZmVjdCB0aGUgb3V0Y29tZS4gIFRoZXNlIGFuYWx5c2VzCndpbGwgZ2VuZXJhbGx5IHJlbWFpbiBhZ25vc3RpYyBmb3IgdGhlc2UgZmFjdG9ycywgd2hpY2ggaW5jbHVkZSAoYW1vbmcKb3RoZXIgdGhpbmdzKToKCjEuICBzZXgKMi4gIGV0aG5pY2l0eQo0LiAgYWdlCjUuICB1bGNlci9sZXNpb24gYXR0cmlidXRlcyAoYnkgdmlzaXQpCjYuICBhbW91bnQgb2YgdGltZSBzcGVudCB3aXRoIGluZmVjdGlvbgoKIyMgTGlicmFyaWVzLCBzZXF1ZW5jaW5nLCBtYXBwaW5nLCBxdWFudGlmaWNhdGlvbgoKVGhlIHNhbXBsZXMgdXNlZCBpbiB0aGVzZSBhbmFseXNlcyB3ZXJlIGFsbCBjb2xsZWN0ZWQsIHB1cmlmaWVkLCBhbmQKbGlicmFyaWVzIGdlbmVyYXRlZCBieSB0aGUgc2NpZW50aXN0cy9kb2N0b3JzIGF0IENJREVJTS4gIFRoZQpzZXF1ZW5jaW5nIGxpYnJhcmllcyB3ZXJlIGdlbmVyYXRlZCB2aWEgdGhlIFRydVNlcSBub24tc3RyYW5kZWQKbGlicmFyeSBraXQgYW5kIHNlcXVlbmNlZCBlaXRoZXIgYXQgSkhVIG9yIFVNRDsgZWFybGllciBzYW1wbGVzIHdlcmUKc2luZ2xlLWVuZGVkLCBidXQgbW9zdCB3ZXJlIHBhaXJlZC4KCkFsbCBzYW1wbGVzIHdlcmUgdHJpbW1lZCB3aXRoIHRyaW1vbWF0aWMgdXNpbmcgdGhlIHNhbWUgc2V0IG9mCnBhcmFtZXRlcnMuICBBbGwgbWFwcGluZyB3YXMgcGVyZm9ybWVkIHdpdGggaGlzYXQyIHZlcnNpb24gMi4yLjEuClF1YW50aWZpY2F0aW9ucyB3ZXJlIGFsc28gcGVyZm9ybWVkIHdpdGggc2FsbW9uIHZlcnNpb24gMS4yLjAuICBUaGUKcmVmZXJlbmNlIGdlbm9tZSB1c2VkIHdhcyBoZzM4IDEwMCAocmVsZWFzZWQgMjAyMDA0KS4gIFdoZW4gc2FtcGxlcwp3ZXJlIG1hcHBlZCBhZ2FpbnN0IEwucGFuYW1lbnNpcywgdGhlIFRyaVRyeXBEQiB2ZXJzaW9uIDM2IHJlZmVyZW5jZQp3YXMgdXNlZC4gIFRoZSBzZXQgb2YgYW5ub3RhdGlvbnMgd2VyZSB0aGVyZWZvcmUgbGltaXRlZCB0byBlbnNlbWJsJ3MKMjAyMCByZWxlYXNlLiAgVGhlIGVhcmx5IHNhbXBsZXMgd2VyZSBhY3R1YWxseSBmaXJzdCBtYXBwZWQgd2l0aApoZzM4IDkxIGFuZCBsYXRlciByZWRvbmUuCgojIyBUeXBlcyBvZiBhbmFseXNlcyBpbmNsdWRlZAoKVGhpcyBkb2N1bWVudCB3aWxsIGxpbWl0IGl0c2VsZiB0byBhIHNldCBvZiBjYW5vbmljYWwgUk5Bc2VxCmFuYWx5c2VzLiAgSXQgbXVzdCB0aGVyZWZvcmUgY3JlYXRlIGZpbGVzIGNvbnRhaW5pbmcgdGhlIHJhdyBkYXRhIHRvCmZhY2lsaXRhdGUgc2hhcmluZyB0aGUgZGF0YS4gIEl0IHdpbGwgcGxvdCBtZXRyaWNzIG9mIHRoZSBkYXRhIHRvCmRlbW9uc3RyYXRlIHRoZSBzZXF1ZW5jaW5nIHF1YWxpdHkgYW5kIGNsdXN0ZXJpbmcgb2YgdGhlIHNhbXBsZXMgdW5kZXIKdGhlIHZhcmlvdXMgY29uZGl0aW9ucyBleGFtaW5lZCBhbmQgbm9ybWFsaXphdGlvbnMgZW1wbG95ZWQuICBJdCB3aWxsCnBlcmZvcm0gZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYW5hbHlzZXMgZm9yIHRoZSBtZXRhZGF0YSBmYWN0b3JzIG9mCmludGVyZXN0IGFsb25nc2lkZSBsaWtlbGlob29kIHJhdGlvIHRlc3RzIGZvciBmYWN0b3JzIGxpa2UgY2VsbHR5cGUKYW5kIHRpbWUuICBHaXZlbiB0aGUgc2V0cyBvZiBvdmVyL3VuZGVyIGV4cHJlc3NlZCBnZW5lcyBvYnNlcnZlZCBpbgp0aGUgdmFyaW91cyBERSBtZXRob2RzLCBpdCB3aWxsIHBlcmZvcm0gdGhlIGxpa2VseSBnZW5lIHNldCB0ZXN0cyBmb3IKb3ZlciByZXByZXNlbnRlZCBnZW5lIG9udG9sb2d5IGdyb3VwcywgcmVhY3RvbWUsIGV0Yy4gIFNpbXVsdGFuZW91c2x5LAp0aGUgcmF3IGRhdGEgd2lsbCBiZSBwYXNzZWQgdG8gZ2VuZSBzZXQgdmFyaWFuY2UgYW5hbHlzZXMgdG8gc2VlIGlmCnRoZXJlIGFyZSBncm91cHMgb2YgZ2VuZXMgb3ZlcnJlcHJlc2VudGVkIGluIG90aGVyIGV4cGVyaW1lbnRzLgoKIyBNZXRhZGF0YSBjb2xsZWN0aW9uCgpUaGVyZSBhcmUgdHdvIG1ldGFkYXRhIHNvdXJjZXM6CgoxLiAgVGhlIG9ubGluZSBzYW1wbGUgc2hlZXQsIHdoaWNoIEkgcGVyaW9kaWNhbGx5IHVwZGF0ZSBhbmQgZG93bmxvYWQKICAgIGludG8gdGhlICdzYW1wbGVfc2hlZXRzLycgZGlyZWN0b3J5LgoyLiAgVGhlIGNyZiBtZXRhZGF0YSwgZGVzY3JpYmluZyB0aGUgaW5kaXZpZHVhbCBwYXRpZW50cy4KCmBgYHtyIG1ldGFkYXRhX3NvdXJjZXN9CnNhbXBsZXNoZWV0IDwtICJzYW1wbGVfc2hlZXRzL3RtcmMzX3NhbXBsZXNfMjAyMTEyMjMueGxzeCIKY3JmX21ldGFkYXRhIDwtICJzYW1wbGVfc2hlZXRzLzIwMjEwODI1X0VYUF9FU1BFQ0lBTF9UTVJDM19WRVJTSU9OXzIueGxzeCIKYGBgCgojIEFubm90YXRpb24gQ29sbGVjdGlvbgoKVGhlIHByaW1hcnkgYW5ub3RhdGlvbiBzb3VyY2VzIGFyZToKCjEuICBFbnNlbWJsJ3MgYmlvbWFydCBhcmNoaXZlIGZyb20gMjAyMCBmb3IgaHVtYW4gYW5ub3RhdGlvbnMuCjIuICBUaGUgVHJpVHJ5cERCIHJlbGVhc2UgMzYgZm9yIHBhcmFzaXRlIGFubm90YXRpb25zLgoKQm90aCBwcm92aWRlIEdPIGRhdGEuICBUaGV5IGFsc28gcHJvdmlkZSBoZWxwZnVsIGxpbmtzIHRvIG90aGVyIGRhdGEKc291cmNlcy4gIEZvciB0aGUgbW9tZW50LCB3ZSBhcmUgZm9jdXNpbmcgb24gdGhlIGh1bWFuIGFubm90YXRpb25zLgoKIyMgR2VuZSBhbm5vdGF0aW9ucwoKVGhlc2UgYW5hbHlzZXMgaGF2ZSBmb2N1c2VkIG9uIGdlbmUtbGV2ZWwgYWJ1bmRhbmNlcy9kaWZmZXJlbmNlcy4KVGh1cywgd2hlbiBodHNlcS1jb3VudCB3YXMgaW52b2tlZCBhZ2FpbnN0IHRoZSBoaXNhdDItYmFzZWQgbWFwcGluZ3MsCnBhcmFtZXRlcnMgd2VyZSBjaG9zZW4gdG8gY291bnQgZ2VuZXMgcmF0aGVyIHRoYW4gdHJhbnNjcmlwdHMuClNpbWlsYXJseSwgd2hlbiBzYWxtb24gY291bnRzIHdlcmUgdXNlZCB2aWEgdHhpbXBvcnQsIGEgbWFwcGluZyBvZgpnZW5lcyB0byB0cmFuc2NyaXB0cyB3YXMgdXNlZCB0byBjb2xsYXBzZSB0aGUgbWF0cml4IHRvIGdlbmUtbGV2ZWwKYWJ1bmRhbmNlcy4gIFRoaXMgZGVjaXNpb24gbWF5IGJlIHJldmlzaXRlZC4KCmBgYHtyIGNvbGxlY3RfYW5ub3RhdGlvbnN9CmhzX2Fubm90IDwtIHNtKGxvYWRfYmlvbWFydF9hbm5vdGF0aW9ucyh5ZWFyPSIyMDIwIikpCmhzX2Fubm90IDwtIGhzX2Fubm90W1siYW5ub3RhdGlvbiJdXQpoc19hbm5vdFtbInRyYW5zY3JpcHQiXV0gPC0gcGFzdGUwKHJvd25hbWVzKGhzX2Fubm90KSwgIi4iLCBoc19hbm5vdFtbInZlcnNpb24iXV0pCnJvd25hbWVzKGhzX2Fubm90KSA8LSBtYWtlLm5hbWVzKGhzX2Fubm90W1siZW5zZW1ibF9nZW5lX2lkIl1dLCB1bmlxdWU9VFJVRSkKdHhfZ2VuZV9tYXAgPC0gaHNfYW5ub3RbLCBjKCJ0cmFuc2NyaXB0IiwgImVuc2VtYmxfZ2VuZV9pZCIpXQpzdW1tYXJ5KGhzX2Fubm90KQpgYGAKCiMjIEdlbmUgb250b2xvZ3kgZGF0YQoKVGhlIHNldCBvZiBHTyBjYXRlZ29yaWVzIGhhcyBub3QgYmVlbiBsaW1pdGVkIHRvIHRoZSAyMDIwIGRhdGEgYXQgdGhlCnRpbWUgb2YgdGhpcyB3cml0aW5nLgoKYGBge3IgaHNfZ299CmhzX2dvIDwtIHNtKGxvYWRfYmlvbWFydF9nbygpW1siZ28iXV0pCmhzX2xlbmd0aCA8LSBoc19hbm5vdFssIGMoImVuc2VtYmxfZ2VuZV9pZCIsICJjZHNfbGVuZ3RoIildCmNvbG5hbWVzKGhzX2xlbmd0aCkgPC0gYygiSUQiLCAibGVuZ3RoIikKYGBgCgojIFRoZSBjb21wbGV0ZSBzZXQgb2YgZGF0YQoKQmVmb3JlIHdlIGRvIGFueSBvZiB0aGUgZm9sbG93aW5nIHN1YnNldHMvYW5hbHlzZXMgb2YgdGhlIGRhdGEsIHdlCm5lZWQgdG8gY29sbGVjdCBpdCBhbGwgaW4gb25lIHBsYWNlLiAgTGV0J3MgZG8gdGhhdCBoZXJlIGFuZCBuYW1lIGl0Cidoc192YWxpZCcgbWVhbmluZyBpdCBpcyB0aGUgc2V0IG9mIHZhbGlkIGRhdGEgZm9yIEhvbW8gc2FwaWVucy4KCmBgYHtyIGFsbF9kYXRhfQpzYW5pdGl6ZV9jb2x1bW5zIDwtIGMoInZpc2l0bnVtYmVyIiwgImNsaW5pY2Fsb3V0Y29tZSIsICJkb25vciIsCiAgICAgICAgICAgICAgICAgICAgICAidHlwZW9mY2VsbHMiLCAiY2xpbmljYWxwcmVzZW50YXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgImNvbmRpdGlvbiIsICJiYXRjaCIpCmhzX2V4cHQgPC0gY3JlYXRlX2V4cHQoc2FtcGxlc2hlZXQsCiAgICAgICAgICAgICAgICAgICAgICAgZmlsZV9jb2x1bW49ImhnMzgxMDBoaXNhdGZpbGUiLAogICAgICAgICAgICAgICAgICAgICAgIHNhdmVmaWxlPWdsdWU6OmdsdWUoInJkYS9oc19leHB0X2FsbC12e3Zlcn0ucmRhIiksCiAgICAgICAgICAgICAgICAgICAgICAgZ2VuZV9pbmZvPWhzX2Fubm90KSAlPiUKICBleGNsdWRlX2dlbmVzX2V4cHQoY29sdW1uPSJnZW5lX2Jpb3R5cGUiLCBtZXRob2Q9ImtlZXAiLAogICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuPSJwcm90ZWluX2NvZGluZyIsIG1ldGFfY29sdW1uPSJuY3JuYV9sb3N0IikgJT4lCiAgc2FuaXRpemVfZXhwdF9tZXRhZGF0YShjb2x1bW5zPXNhbml0aXplX2NvbHVtbnMpICU+JQogIHNldF9leHB0X2ZhY3RvcnMoY29sdW1ucz1zYW5pdGl6ZV9jb2x1bW5zLCBjbGFzcz0iZmFjdG9yIikgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0PSJjbGluaWNhbG91dGNvbWUiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3Q9InZpc2l0bnVtYmVyIikKCmxldmVscyhwRGF0YShoc19leHB0W1siZXhwcmVzc2lvbnNldCJdXSlbWyJ2aXNpdG51bWJlciJdXSkgPC0gbGlzdCgKICAgICcwJz0ibm90YXBwbGljYWJsZSIsICcxJz0xLCAnMic9MiwgJzMnPTMpCmBgYAoKIyMgQWRkIHRoZSBDUkYgcGF0aWVudCBtZXRhZGF0YQoKTGV0IHVzIGFsc28gbWVyZ2UgaW4gdGhlIGNsaW5pY2lhbidzIG1ldGFkYXRhLiAgSSB3b3JyeSBhIGxpdHRsZSB0aGF0CnRoaXMgbWlnaHQgbm90IGJlIGFsbG93ZWQgZm9yIGRiR2FwIGRhdGEsIGJ1dCBpZiBpdCBpcyBhIHByb2JsZW0gSQpzdXNwZWN0IHdlIGNhbiBqdXN0IHJlbW92ZSB0aGUgYmFkIGNvbHVtbnMgZnJvbSBpdC4gIEFsc28gbm90ZSB0aGF0IEkKcmFyZWx5IHVzZSB0aGUgam9pbiBmdW5jdGlvbiwgYnV0IGl0IGlzIHNvbWV3aGF0IHJlcXVpcmVkIGhlcmUgYmVjYXVzZQpJIGRvIG5vdCB3YW50IHRvIHJpc2sgc2h1ZmZsaW5nIHRoZSBtZXRhZGF0YSB3aGVuIEkgYWRkIHRoZSBuZXcKbWV0YWRhdGEsIHdoaWNoIGNvbWVzIGZyb20gYSBzcHJlYWRzaGVldCBzb3J0ZWQgYnkgcGF0aWVudCwgbm90CnNhbXBsZS4gIEluIGRvaW5nIHRoaXMgSSB0aGVyZWZvcmUganVzdCBjcmVhdGVkIGEgbmV3IGNvbHVtbiAnam9pbicKd2hpY2ggY29udGFpbnMgdGhlIHNoYXJlZCBpbmZvcm1hdGlvbiwgZS5nLiB0aGUgcGF0aWVudCBJRApmcm9tIHRoZSBleGlzdGluZyBtZXRhZGF0YSBhbmQgdGhlIHNhbWUgSUQgZnJvbSB0aGUgQ1JGIGZpbGUgd2hpY2ggaGFzCmJlZW4gY29lcmNlZCBpbnRvIGxvd2VyY2FzZS4KCmBgYHtyIG1lcmdlX2NyZn0KaHNfcGQgPC0gcERhdGEoaHNfZXhwdCkKc3RhcnQgPC0gcm93bmFtZXMoaHNfcGQpCmhzX2NyZiA8LSBvcGVueGxzeDo6cmVhZC54bHN4KGNyZl9tZXRhZGF0YSkKaHNfY3JmW1siam9pbiJdXSA8LSB0b2xvd2VyKGhzX2NyZltbImNvZGlnb19wYWNpZW50ZSJdXSkKaHNfcGRbWyJqb2luIl1dIDwtIGhzX3BkW1sidHViZWxhYmVsb3JpZ2luIl1dCnRlc3QgPC0gcGx5cjo6am9pbihoc19wZCwgaHNfY3JmLCBieT0iam9pbiIpCnRlc3RbWyJqb2luIl1dIDwtIE5VTEwKcm93bmFtZXModGVzdCkgPC0gcm93bmFtZXMoaHNfcGQpCm5hX2lkeCA8LSBpcy5uYSh0ZXN0KQp0ZXN0W25hX2lkeF0gPC0gInVuZGVmaW5lZCIKcERhdGEoaHNfZXhwdCkgPC0gdGVzdApgYGAKCiMjIFNldCBvdXIgaW5pdGlhbCBjb3ZlcmFnZSBnb2FsCgpUaGVyZSBleGlzdHMgYSBiYXNlbGluZSBjb3ZlcmFnZSBiZWxvdyB3aGljaCB3ZSBkbyBub3Qgd2lzaCB0byBmYWxsLgpPbmUgbGlrZWx5IHdheSB0byBhcHByb2FjaCBpdCBoZXVyaXN0aWNhbGx5IGlzIHRvIGFzc3VtZSB3ZSBzaG91bGQKb2JzZXJ2ZSBzb21lIG51bWJlciBvZiBnZW5lcy4gIFdpdGggdGhhdCBpbiBtaW5kLCBJIGFyYml0cmFyaWx5IGNob3NlCjExLDAwMCBub24temVybyBnZW5lcyBhcyB0aGUgbWluaW11bS4KCmBgYHtyIGhzX3ZhbGlkfQpoc192YWxpZCA8LSBzdWJzZXRfZXhwdChoc19leHB0LCBub256ZXJvPTExMDAwKQpgYGAKCiMjIFNldCB1cCBpbml0aWFsIGRhdGEgc3Vic2V0cyBvZiBpbnRlcmVzdAoKT25lIG9mIHRoZSBmaXJzdCBnbG9iYWwgbWV0cmljcyBJIHdvdWxkIGxpa2UgdG8gcHJvdmlkZSBpcyB0aGUgc2V0IG9mCmxpYnJhcnkgc2l6ZXMuICBVbmZvcnR1bmF0ZWx5LCB3ZSBoYXZlIHRvbyBtYW55IHNhbXBsZXMgdG8gZml0IG9uIGEKc2NyZWVuIG5vdy4gIFRoZXJlZm9yZSwgSSBhbSBnb2luZyB0byBkbyBhbiBlYXJseSBzcGxpdCBvZiB0aGUgZGF0YSBieQpjZWxsIHR5cGUgaW4gdGhlIGhvcGVzIHRoYXQgZG9pbmcgc28gd2lsbCBtYWtlIGl0IHBvc3NpYmxlIHRvCnZpc3VhbGl6ZSB0aGUgbGlicmFyeSBzaXplcy9ub256ZXJvIGdlbmVzLgoKVGhlIGluaXRpYWwgZmFjdG9yIGZvciB0aGlzIGlzICd0eXBlb2ZjZWxscycuCgpgYGB7ciBpbml0aWFsX3N1YnNldHN9CnRhYmxlKHBEYXRhKGhzX3ZhbGlkKVtbInR5cGVvZmNlbGxzIl1dKQpiaW9wc3lfc2FtcGxlcyA8LSBzdWJzZXRfZXhwdChoc192YWxpZCwgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J2Jpb3BzeSciKQplb3Npbm9waGlsX3NhbXBsZXMgPC0gc3Vic2V0X2V4cHQoaHNfdmFsaWQsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdlb3Npbm9waGlscyciKQptYWNyb3BoYWdlX3NhbXBsZXMgPC0gc3Vic2V0X2V4cHQoaHNfdmFsaWQsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdtYWNyb3BoYWdlcyciKQptb25vY3l0ZV9zYW1wbGVzIDwtIHN1YnNldF9leHB0KGhzX3ZhbGlkLCBzdWJzZXQ9InR5cGVvZmNlbGxzPT0nbW9ub2N5dGVzJyIpCm5ldXRyb3BoaWxfc2FtcGxlcyA8LSBzdWJzZXRfZXhwdChoc192YWxpZCwgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J25ldXRyb3BoaWxzJyIpCnBibWNfc2FtcGxlcyA8LSBzdWJzZXRfZXhwdChoc192YWxpZCwgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J3BibWNzJyIpCgojIyBDdXJyZW50bHksIHRoZXNlIGFyZSBub3QgdXNlZCwgYnV0IGluc3RlYWQgSSBwdWxsZWQgdGhlIHNhbXBsZXMgZnJvbSB0aGUgaHNfY2xpbmljYWwKIyMgd2hpY2ggbWVhbnMgdGhlIGJpb3BzaWVzIGFyZSBub3QgaW5jbHVkZWQuCnYxX3NhbXBsZXMgPC0gc3Vic2V0X2V4cHQoaHNfdmFsaWQsIHN1YnNldD0idmlzaXRudW1iZXI9PScxJyIpCnYxX2Jpb3BzaWVzIDwtIHN1YnNldF9leHB0KHYxX3NhbXBsZXMsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdiaW9wc3knIikKdjFfbW9ub2N5dGVzIDwtIHN1YnNldF9leHB0KHYxX3NhbXBsZXMsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdtb25vY3l0ZXMnIikKdjFfbmV1dHJvcGhpbHMgPC0gc3Vic2V0X2V4cHQodjFfc2FtcGxlcywgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J25ldXRyb3BoaWxzJyIpCnYxX2Vvc2lub3BoaWxzIDwtIHN1YnNldF9leHB0KHYxX3NhbXBsZXMsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdlb3Npbm9waGlscyciKQoKdjJfc2FtcGxlcyA8LSBzdWJzZXRfZXhwdChoc192YWxpZCwgc3Vic2V0PSJ2aXNpdG51bWJlcj09JzInIikKdjJfYmlvcHNpZXMgPC0gc3Vic2V0X2V4cHQodjJfc2FtcGxlcywgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J2Jpb3BzeSciKQp2Ml9tb25vY3l0ZXMgPC0gc3Vic2V0X2V4cHQodjJfc2FtcGxlcywgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J21vbm9jeXRlcyciKQp2Ml9uZXV0cm9waGlscyA8LSBzdWJzZXRfZXhwdCh2Ml9zYW1wbGVzLCBzdWJzZXQ9InR5cGVvZmNlbGxzPT0nbmV1dHJvcGhpbHMnIikKdjJfZW9zaW5vcGhpbHMgPC0gc3Vic2V0X2V4cHQodjJfc2FtcGxlcywgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J2Vvc2lub3BoaWxzJyIpCgp2M19zYW1wbGVzIDwtIHN1YnNldF9leHB0KGhzX3ZhbGlkLCBzdWJzZXQ9InZpc2l0bnVtYmVyPT0nMyciKQp2M19iaW9wc2llcyA8LSBzdWJzZXRfZXhwdCh2M19zYW1wbGVzLCBzdWJzZXQ9InR5cGVvZmNlbGxzPT0nYmlvcHN5JyIpCnYzX21vbm9jeXRlcyA8LSBzdWJzZXRfZXhwdCh2M19zYW1wbGVzLCBzdWJzZXQ9InR5cGVvZmNlbGxzPT0nbW9ub2N5dGVzJyIpCnYzX25ldXRyb3BoaWxzIDwtIHN1YnNldF9leHB0KHYzX3NhbXBsZXMsIHN1YnNldD0idHlwZW9mY2VsbHM9PSduZXV0cm9waGlscyciKQp2M19lb3Npbm9waGlscyA8LSBzdWJzZXRfZXhwdCh2M19zYW1wbGVzLCBzdWJzZXQ9InR5cGVvZmNlbGxzPT0nZW9zaW5vcGhpbHMnIikKYGBgCgojIENvbnRyYXN0cyBvZiBpbnRlcmVzdAoKVGhpcyBtaWdodCBiZSBhIGJpdCBlYXJseSB0byBjb25zaWRlciB0aGUgY29udHJhc3RzLCBidXQgSSB0aGluayB3ZQpzaG91bGQgY29uc2lkZXIgdGhpcyBxdWVzdGlvbiBpbW1lZGlhdGVseS4gIFRoZSBtYWluIHRoaW5nIHdlIHdpbGwgYmUKY29tcGFyaW5nIGlzIG9mIGNvdXJzZSBjdXJlIHZzLiBmYWlsOyBidXQgd2UgbWF5IGFsc28gbG9vayBhdCB0aGUKdmlzaXRzIGFuZCBjb21wYXJlIGNlbGwgdHlwZXMuCgpgYGB7ciBkZWZpbmVfY29udHJhc3RzfQpjZl9jb250cmFzdHMgPC0gbGlzdCgKICAgICJmYWlsX3ZzX2N1cmUiID0gYygiZmFpbHVyZSIsICJjdXJlIikpCnZpc2l0X2NvbnRyYXN0cyA8LSBsaXN0KAogICAgInYydjEiID0gYygiYzIiLCAiYzEiKSwKICAgICJ2M3YxIiA9IGMoImMzIiwgImMxIiksCiAgICAidjN2MiIgPSBjKCJjMyIsICJjMiIpKQp0eXBlX2NvbnRyYXN0cyA8LSBsaXN0KAogICAgIm1vbm9fYmlvcHN5IiA9IGMoIm1vbm9jeXRlcyIsICJiaW9wc3kiKSwKICAgICJlb3Npbm9waGlsX2Jpb3BzeSIgPSBjKCJlb3Npbm9waGlscyIsICJiaW9wc3kiKSwKICAgICJuZXV0cm9waGlsX2Jpb3BzeSIgPSBjKCJuZXV0cm9waGlscyIsICJiaW9wc3kiKSkKYGBgCgojIFBhcmFzaXRlIHJlYWRzCgpMZXQgdXMgc2VlIGlmIHdlIGNhbiBtYWtlIGFuIGV4cHJlc3Npb25zZXQgb2YgdGhlIHBhcmFzaXRlIHJlYWRzIGluCnRoZSBUTVJDMyBzYW1wbGVzIGFuZCBkaXN0aW5ndWlzaCBiZXR3ZWVuIHRoZSBmYXV4IGFuZCByZWFsIHJlYWRzLgpFLmc6IEFyZSB0aGVyZSBzYW1wbGVzIHdoaWNoIGRlZmluaXRpdmVseSBjb250YWluIHBhcmFzaXRlcz8KCmBgYHtyIHBhcmFzaXRlX2V4cHR9CmxwX2V4cHQgPC0gY3JlYXRlX2V4cHQoInNhbXBsZV9zaGVldHMvdG1yYzNfc2FtcGxlc18yMDIxMTIwNy54bHN4IiwKICAgICAgICAgICAgICAgICAgICAgICBmaWxlX2NvbHVtbj0ibHBhbmFtZW5zaXN2MzZoaXNhdGZpbGUiLCBnZW5lX2luZm8gPSBOVUxMKSAlPiUKICBzdWJzZXRfZXhwdChjb3ZlcmFnZT0yMCkgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0PSJ0eXBlb2ZjZWxscyIpCnZpc2l0X2ZhY3QgPC0gcERhdGEobHBfZXhwdClbWyJ2aXNpdG51bWJlciJdXQpiYXRjaF9uYSA8LSBpcy5uYSh2aXNpdF9mYWN0KQp2aXNpdF9mYWN0W2JhdGNoX25hXSA8LSAidW5kZWZpbmVkIgpscF9leHB0IDwtIHNldF9leHB0X2JhdGNoZXMobHBfZXhwdCwgZmFjdCA9IHZpc2l0X2ZhY3QpCgpscF9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGxwX2V4cHQsIGZpbHRlcj0ic2ltcGxlIiwgbm9ybT0icXVhbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQ9ImNwbSIsIHRyYW5zZm9ybT0ibG9nMiIpCnBsb3R0ZWQgPC0gcGxvdF9wY2EobHBfbm9ybSwgcGxvdF9sYWJlbHM9RkFMU0UpCnBsb3R0ZWQkcGxvdApwbG90dGVkXzNkIDwtIHBsb3RfM2RfcGNhKHBsb3R0ZWQpCmBgYAoKIyBEaXN0cmlidXRpb25zL1Zpc3VhbGl6YXRpb25zIG9mIGludGVyZXN0CgpUaGUgc2V0cyBvZiBzYW1wbGVzIHVzZWQgdG8gdmlzdWFsaXplIHRoZSBkYXRhIHdpbGwgYWxzbyBjb21wcmlzZSB0aGUKc2V0cyB1c2VkIHdoZW4gbGF0ZXIgcGVyZm9ybWluZyB0aGUgdmFyaW91cyBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbgphbmFseXNlcy4KCiMjIEdsb2JhbCBtZXRyaWNzCgpTdGFydCBvdXQgd2l0aCBzb21lIGluaXRpYWwgbWV0cmljcyBvZiBhbGwgc2FtcGxlcy4gIFRoZSBtb3N0IG9idmlvdXMKYXJlIHBsb3RzIG9mIHRoZSBudW1iZXJzIG9mIG5vbi16ZXJvIGdlbmVzIG9ic2VydmVkLCBoZWF0bWFwcyBzaG93aW5nCnRoZSByZWxhdGl2ZSByZWxhdGlvbnNoaXBzIGFtb25nIHRoZSBzYW1wbGVzLCB0aGUgcmVsYXRpdmUgbGlicmFyeQpzaXplcywgYW5kIHNvbWUgUENBLiAgSXQgbWlnaHQgYmUgc21hcnQgdG8gc3BsaXQgdGhlIGxpYnJhcnkgc2l6ZXMgdXAKYWNyb3NzIHN1YnNldHMgb2YgdGhlIGRhdGEsIGJlY2F1c2UgdGhleSBoYXZlIGV4cGFuZGVkIHRvbyBmYXIgdG8gc2VlCndlbGwgb24gYSBjb21wdXRlciBzY3JlZW4uCgpUaGUgbW9zdCBsaWtlbHkgZmFjdG9ycyB0byBxdWVyeSB3aGVuIGNvbnNpZGVyaW5nIHRoZSBlbnRpcmUgZGF0YXNldAphcmUgY3VyZS9mYWlsLCB2aXNpdCwgYW5kIGNlbGwgdHlwZS4gIFRoaXMgaXMgdGhlIGxldmVsIGF0IHdoaWNoIHdlCndpbGwgY2hvb3NlIHNhbXBsZXMgdG8gZXhjbHVkZSBmcm9tIGZ1dHVyZSBhbmFseXNlcy4KCmBgYHtyIGdsb2JhbF9kaXN0cmlidXRpb25zfQpwbG90X2xlZ2VuZChiaW9wc3lfc2FtcGxlcykkcGxvdApwbG90X2xpYnNpemUoYmlvcHN5X3NhbXBsZXMpJHBsb3QKcGxvdF9ub256ZXJvKGJpb3BzeV9zYW1wbGVzKSRwbG90CiMjIE1pbmltdW0gbnVtYmVyIG9mIGJpb3BzeSBnZW5lczogfiAxNCwwMDAKCnBsb3RfbGlic2l6ZShlb3Npbm9waGlsX3NhbXBsZXMpJHBsb3QKcGxvdF9ub256ZXJvKGVvc2lub3BoaWxfc2FtcGxlcykkcGxvdAojIyBNaW5pbXVtIG51bWJlciBvZiBlb3Npbm9waGlsIGdlbmVzOiB+IDEzLDUwMAoKcGxvdF9saWJzaXplKG1hY3JvcGhhZ2Vfc2FtcGxlcykkcGxvdApwbG90X25vbnplcm8obWFjcm9waGFnZV9zYW1wbGVzKSRwbG90CiMjIE1pbmltdW0gbnVtYmVyIG9mIG1hY3JvcGhhZ2UgZ2VuZXM6IH4gMTQsMDAwCgpwbG90X2xpYnNpemUobW9ub2N5dGVfc2FtcGxlcykkcGxvdApwbG90X25vbnplcm8obW9ub2N5dGVfc2FtcGxlcykkcGxvdAojIyBNaW5pbXVtIG51bWJlciBvZiBtb25vY3l0ZSBnZW5lczogfiA3LDUwMCBiZWZvcmUgc2V0dGluZyB0aGUgbWluaW11bS4KCnBsb3RfbGlic2l6ZShuZXV0cm9waGlsX3NhbXBsZXMpJHBsb3QKcGxvdF9ub256ZXJvKG5ldXRyb3BoaWxfc2FtcGxlcykkcGxvdAojIyBNaW5pbXVtIG51bWJlciBvZiBuZXV0cm9waGlsIGdlbmVzOiB+IDEwLDAwMCBiZWZvcmUgc2V0dGluZyBtaW5pbXVtIGNvdmVyYWdlLgoKcGxvdF9saWJzaXplKHBibWNfc2FtcGxlcykkcGxvdApwbG90X25vbnplcm8ocGJtY19zYW1wbGVzKSRwbG90CiMjIE1pbmltdW0gbnVtYmVyIG9mIHBibWMgZ2VuZXM6IH4gMTQsODAwCmBgYAoKTm93IHRoYXQgdGhvc2UgJ2dsb2JhbCcgbWV0cmljcyBhcmUgb3V0IG9mIHRoZSB3YXksIGxldHMgbG9vayBhdCBzb21lCmdsb2JhbCBtZXRyaWNzIG9mIHRoZSBkYXRhIGZvbGxvd2luZyBub3JtYWxpemF0aW9uOyB0aGUgbW9zdCBsaWtlbHkKcGxvdHMgYXJlIG9mIGNvdXJzZSBQQ0EgYnV0IGFsc28gYSBjb3VwbGUgb2YgaGVhdG1hcHMuCgpgYGB7ciBnbG9iYWxfcGNhfQp0eXBlX3ZhbGlkIDwtIHNldF9leHB0X2NvbmRpdGlvbnMoaHNfdmFsaWQsIGZhY3Q9InR5cGVvZmNlbGxzIikKYWxsX25vcm0gPC0gc20obm9ybWFsaXplX2V4cHQodHlwZV92YWxpZCwgdHJhbnNmb3JtPSJsb2cyIiwgbm9ybT0icXVhbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0PSJjcG0iLCBmaWx0ZXI9VFJVRSkpCgphbGxfcGNhIDwtIHBsb3RfcGNhKGFsbF9ub3JtLCBwbG90X2xhYmVscz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICBwbG90X3RpdGxlPSJQQ0EgLSBDZWxsIHR5cGUiLCBzaXplX2NvbHVtbj0idmlzaXRudW1iZXIiKQpwcChmaWxlPWdsdWUoImltYWdlcy90bXJjM19wY2Ffbm9sYWJlbHMtdnt2ZXJ9LnBuZyIpLCBpbWFnZT1hbGxfcGNhJHBsb3QpCgp3cml0ZS5jc3YoYWxsX3BjYSR0YWJsZSwgZmlsZT0iY29vcmRzL2hzX2Rvbm9yX3BjYV9jb29yZHMuY3N2IikKcGxvdF9jb3JoZWF0KGFsbF9ub3JtLCBwbG90X3RpdGxlPSJIZWlyYXJjaGljYWwgY2x1c3RlcmluZzoKICAgICAgICAgY2VsbCB0eXBlcyIpJHBsb3QKYGBgCgpDb250aW51ZSBsb29raW5nLCBidXQgc3dpdGNoIHRoZSBjb25kaXRpb25zL2NvbG9ycyBzbyB0aGF0IHRoZQpjbGluaWNhbCBvdXRjb21lIGJlY29tZXMgdGhlIGZvY3VzIGFuZCBnZXQgcmlkIG9mIGEgZmV3IHNhbXBsZXMgd2hpY2gKYXJlIG5vdCBhY3R1YWxseSBhIHBhcnQgb2YgdGhlIFRNUkMzIGZvY3VzIChlLmcuIHRoZSBQQk1DIGFuZAptYWNyb3BoYWdlIHNhbXBsZXMsIHdoaWNoIGFyZSBhbGwgZnJvbSB0aGUgV2VsbGNvbWUgVHJ1c3QpLgoKIyMjIENsaW5pY2FsbHkgcmVsZXZhbnQgc2FtcGxlcwoKSW5jbHVkZWQgaW4gdGhpcyBncm91cCB3aWxsIGJlIHRoZSBzYW1wbGVzIGZyb20gcGF0aWVudHMgd2hvIHdlcmUgbG9zdC4KCmBgYHtyIGNsaW5pY2FsX2hzfQpoc19jbGluaWNhbCA8LSBoc192YWxpZCAlPiUKICBzZXRfZXhwdF9jb25kaXRpb25zKGZhY3Q9ImNsaW5pY2Fsb3V0Y29tZSIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdD0idHlwZW9mY2VsbHMiKSAlPiUKICBzdWJzZXRfZXhwdChzdWJzZXQ9InR5cGVvZmNlbGxzIT0ncGJtY3MnJnR5cGVvZmNlbGxzIT0nbWFjcm9waGFnZXMnIikKCmNob3Nlbl9jb2xvcnMgPC0gYygiI0Q5NUYwMiIsICIjNzU3MEIzIiwgIiMxQjlFNzciLCAiI0ZGMDAwMCIsICIjRkYwMDAwIikKbmFtZXMoY2hvc2VuX2NvbG9ycykgPC0gYygiY3VyZSIsICJmYWlsdXJlIiwgImxvc3QiLCAibnVsbCIsICJub3RhcHBsaWNhYmxlIikKaHNfY2xpbmljYWwgPC0gc2V0X2V4cHRfY29sb3JzKGhzX2NsaW5pY2FsLCBjb2xvcnM9Y2hvc2VuX2NvbG9ycykKCm5ld25hbWVzIDwtIG1ha2UubmFtZXMocERhdGEoaHNfY2xpbmljYWwpW1sic2FtcGxlbmFtZSJdXSwgdW5pcXVlPVRSVUUpCmhzX2NsaW5pY2FsIDwtIHNldF9leHB0X3NhbXBsZW5hbWVzKGhzX2NsaW5pY2FsLCBuZXduYW1lcz1uZXduYW1lcykKCmhzX2NsaW5pY2FsX25vcm0gPC0gc20obm9ybWFsaXplX2V4cHQoaHNfY2xpbmljYWwsIGZpbHRlcj1UUlVFLCB0cmFuc2Zvcm09ImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IikpCmNsaW5pY2FsX3BjYSA8LSBwbG90X3BjYShoc19jbGluaWNhbF9ub3JtLCBwbG90X2xhYmVscz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfY29sdW1uPSJ2aXNpdG51bWJlciIsIGNpcz1OVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgcGxvdF90aXRsZT0iUENBIC0gY2xpbmljYWwgc2FtcGxlcyIpCnBwKGZpbGU9Z2x1ZSgiaW1hZ2VzL2FsbF9jbGluaWNhbF9ub2JhdGNoX3BjYS12e3Zlcn0ucG5nIiksCiAgIGltYWdlPWNsaW5pY2FsX3BjYSRwbG90LCBoZWlnaHQ9OCwgd2lkdGg9MjApCgp0YWJsZShwRGF0YShoc19jbGluaWNhbClbWyJjb25kaXRpb24iXV0pCmBgYAoKIyMjIyBSZW1vdmUgdGhlIGxvc3Qgc2FtcGxlcwoKTm93IGxldCB1cyBmb2N1cyBwdXJlbHkgb24gdGhlIGN1cmVzIGFuZCBmYWlscy4KCmBgYHtyIHJlbW92ZV9sb3N0X3NhbXBsZXN9CmNsaW5pY2FsX25vbG9zdCA8LSBzdWJzZXRfZXhwdChoc19jbGluaWNhbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNldD0iY29uZGl0aW9uIT0nbG9zdCcmY29uZGl0aW9uIT0nbm90YXBwbGljYWJsZSciKQpgYGAKClRoZSBiaW9wc3kgc2FtcGxlcyBhcmUgYSBiaXQgcGVjdWxpYXIsIHRoZXJlZm9yZSBsZXQgdXMgcmVwZWF0IHRoaXMKd2l0aG91dCB0aGVtLgoKIyMjIFJlcGVhdCB3aXRob3V0IGJpb3BzeSBzYW1wbGVzCgpgYGB7ciBpYmlkX25vYmlvcHN5fQpoc19jbGluaWNhbF9ub2Jpb3AgPC0gaHNfY2xpbmljYWwgJT4lCiAgc3Vic2V0X2V4cHQoc3Vic2V0PSJ0eXBlb2ZjZWxscyE9J2Jpb3BzeSciKSAlPiUKICBzdWJzZXRfZXhwdChzdWJzZXQ9ImNvbmRpdGlvbj09J2xvc3QnfGNvbmRpdGlvbj09J2N1cmUnfGNvbmRpdGlvbj09J2ZhaWx1cmUnIikKCmhzX2NsaW5pY2FsX25vYmlvcF9ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KGhzX2NsaW5pY2FsX25vYmlvcCwgZmlsdGVyPVRSVUUsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IikpCmNsaW5pY2FsX25vYmlvcF9wY2EgPC0gcGxvdF9wY2EoaHNfY2xpbmljYWxfbm9iaW9wX25vcm0sIHBsb3RfbGFiZWxzPUZBTFNFLCBjaXM9TlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90X3RpdGxlPSJQQ0EgLSBjbGluaWNhbCBzYW1wbGVzIHdpdGhvdXQgYmlvcHNpZXMiKQpwcChmaWxlPWdsdWUoImltYWdlcy9hbGxfY2xpbmljYWxfbm9iaW9wX25vYmF0Y2hfcGNhLXZ7dmVyfS5wbmciKSwKICAgaW1hZ2U9Y2xpbmljYWxfbm9iaW9wX3BjYSRwbG90KQpgYGAKCiMjIyBWaXN1YWxpemUgYWdhaW4gd2l0aCBzdmEKCmBgYHtyIGNsaW5pY2FsX3N2YX0KaHNfY2xpbmljYWxfbmIgPC0gbm9ybWFsaXplX2V4cHQoaHNfY2xpbmljYWwsIGZpbHRlcj1UUlVFLCBiYXRjaD0ic3Zhc2VxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtPSJsb2cyIiwgY29udmVydD0iY3BtIikKY2xpbmljYWxfYmF0Y2hfcGNhIDwtIHBsb3RfcGNhKGhzX2NsaW5pY2FsX25iLCBwbG90X2xhYmVscz1GQUxTRSwgY2lzPU5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX2NvbHVtbj0idmlzaXRudW1iZXIiLCBwbG90X3RpdGxlPSJQQ0EgLSBjbGluaWNhbCBzYW1wbGVzIikKY2xpbmljYWxfYmF0Y2hfcGNhJHBsb3QKCmhzX2NsaW5pY2FsX25vYmlvcF9uYiA8LSBzbShub3JtYWxpemVfZXhwdChoc19jbGluaWNhbF9ub2Jpb3AsIGZpbHRlcj1UUlVFLCBiYXRjaD0ic3Zhc2VxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIpKQpjbGluaWNhbF9ub2Jpb3BfYmF0Y2hfcGNhIDwtIHBsb3RfcGNhKGhzX2NsaW5pY2FsX25vYmlvcF9uYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90X3RpdGxlPSJQQ0EgLSBjbGluaWNhbCBzYW1wbGVzIHdpdGhvdXQgYmlvcHNpZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3RfbGFiZWxzPUZBTFNFKQpwcChmaWxlPSJpbWFnZXMvY2xpbmljYWxfYmF0Y2gucG5nIiwgaW1hZ2U9Y2xpbmljYWxfbm9iaW9wX2JhdGNoX3BjYSRwbG90KQp0ZXN0IDwtIHBsb3RfcGNhKGhzX2NsaW5pY2FsX25vYmlvcF9uYiwgc2l6ZV9jb2x1bW49InZpc2l0bnVtYmVyIiwKICAgICAgICAgICAgICAgICBwbG90X3RpdGxlPSJQQ0EgLSBjbGluaWNhbCBzYW1wbGVzIHdpdGhvdXQgYmlvcHNpZXMiLAogICAgICAgICAgICAgICAgIHBsb3RfbGFiZWxzPUZBTFNFKQp0ZXN0JHBsb3QKCmNsaW5pY2FsX25vYmlvcF9iYXRjaF90c25lIDwtIHBsb3RfdHNuZShoc19jbGluaWNhbF9ub2Jpb3BfbmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90X3RpdGxlPSJ0U05FIC0gY2xpbmljYWwgc2FtcGxlcyB3aXRob3V0IGJpb3BzaWVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3RfbGFiZWxzPUZBTFNFKQpjbGluaWNhbF9ub2Jpb3BfYmF0Y2hfdHNuZSRwbG90CmBgYAoKIyMjIFNhbXBsZXMgc2VwYXJhdGVkIGJ5IHZpc2l0CgpTZXBhcmF0ZSB0aGUgc2FtcGxlcyBieSB2aXNpdCBpbiBvcmRlciB0byBtb3JlIGVhc2lseSBzZWUgd2hhdApwYXR0ZXJucyBlbWVyZ2UgYWNyb3NzIGNlbGwgdHlwZSBhbmQgY2xpbmljYWwgb3V0Y29tZS4KCkkgaGF2ZSBhIGNvdXBsZSBvZiBsaWtlbHkgc3RhcnRpbmcgcG9pbnRzIGZvciB0aGlzLiAgVGhlIGRhdGEgc2V0czogaHNfY2xpbmljYWwgYW5kCmNsaW5pY2FsX25vbG9zdCBhcmUgdGhlIG1vc3QgbGlrZWx5LiAgR2l2ZW4gdGhhdCB0aGlzLCBhdCBsZWFzdCBpbgp0aGVvcnksIHRoZSBsb3N0IHNhbXBsZXMgYXJlIG5vdCByZWxldmFudC4KCiMjIyMgQWxsIHZpc2l0cyB0b2dldGhlcgoKYGBge3IgY29tcGFyZV9hbGxfdmlzaXRzfQp2aXNpdF9leHB0IDwtIHNldF9leHB0X2NvbmRpdGlvbnMoaHNfY2xpbmljYWwsIGZhY3QgPSAidmlzaXRudW1iZXIiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAiY2xpbmljYWxvdXRjb21lIikKCnZpc2l0X25iIDwtIG5vcm1hbGl6ZV9leHB0KHZpc2l0X2V4cHQsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydD0iY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKcGxvdF9wY2EodmlzaXRfbmIpJHBsb3QKYGBgCgojIyMjIEFsbCB2aXNpdHMsIHNlcGFyYXRlZCBieSBjZWxsIHR5cGUKCmBgYHtyIGNlbGxfdHlwZV92aXNpdHN9CnZpc2l0X2Jpb3BzeSA8LSBzdWJzZXRfZXhwdCh2aXNpdF9leHB0LCBzdWJzZXQgPSAidHlwZW9mY2VsbHM9PSdiaW9wc3knIikKdmlzaXRfbW9ub2N5dGUgPC0gc3Vic2V0X2V4cHQodmlzaXRfZXhwdCwgc3Vic2V0ID0gInR5cGVvZmNlbGxzPT0nbW9ub2N5dGVzJyIpCnZpc2l0X25ldXRyb3BoaWwgPC0gc3Vic2V0X2V4cHQodmlzaXRfZXhwdCwgc3Vic2V0ID0gInR5cGVvZmNlbGxzPT0nbmV1dHJvcGhpbHMnIikKdmlzaXRfZW9zaW5vcGhpbCA8LSBzdWJzZXRfZXhwdCh2aXNpdF9leHB0LCBzdWJzZXQgPSAidHlwZW9mY2VsbHM9PSdlb3Npbm9waGlscyciKQpgYGAKCiMjIyMgVmlzaXQgMSBhbG9uZQoKYGBge3IgdmlzaXQxX2RhdGF9CnYxX2NsaW5pY2FsIDwtIHN1YnNldF9leHB0KHZpc2l0X2V4cHQsIHN1YnNldCA9ICJ2aXNpdG51bWJlcj09JzEnIikgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0ID0gImNsaW5pY2Fsb3V0Y29tZSIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJ0eXBlb2ZjZWxscyIpCgp2MV9uYiA8LSBub3JtYWxpemVfZXhwdCh2MV9jbGluaWNhbCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnBsb3RfcGNhKHYxX25iKSRwbG90CmBgYAoKIyMjIyBWaXNpdCAyIGFsb25lCgpgYGB7ciB2aXNpdDJfZGF0YX0KdjJfY2xpbmljYWwgPC0gc3Vic2V0X2V4cHQodmlzaXRfZXhwdCwgc3Vic2V0PSJ2aXNpdG51bWJlcj09JzInIikgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0ID0gImNsaW5pY2Fsb3V0Y29tZSIpICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9ICJ0eXBlb2ZjZWxscyIpCgp2Ml9uYiA8LSBub3JtYWxpemVfZXhwdCh2Ml9jbGluaWNhbCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsIG5vcm0gPSAicXVhbnQiLAogICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQpwbG90X3BjYSh2Ml9uYikkcGxvdApgYGAKCiMjIyMgVmlzaXQgMyBhbG9uZQoKYGBge3IgdmlzaXQzX2RhdGF9CnYzX2NsaW5pY2FsIDwtIHN1YnNldF9leHB0KHZpc2l0X2V4cHQsIHN1YnNldD0idmlzaXRudW1iZXI9PSczJyIpICU+JQogIHNldF9leHB0X2NvbmRpdGlvbnMoZmFjdCA9ICJjbGluaWNhbG91dGNvbWUiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidHlwZW9mY2VsbHMiKQoKdjNfbmIgPC0gbm9ybWFsaXplX2V4cHQodjNfY2xpbmljYWwsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLCBub3JtID0gInF1YW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKcGxvdF9wY2EodjNfbmIpJHBsb3QKYGBgCgojIyMgU2FtcGxlcyBzZXBhcmF0ZWQgYnkgY2VsbCB0eXBlCgpTZXBhcmF0ZSB0aGUgc2FtcGxlcyBieSBjZWxsIHR5cGUgaW4gb3JkZXIgdG8gbW9yZSBlYXNpbHkgb2JzZXJ2ZQpwYXR0ZXJucyB3aXRoIHJlc3BlY3QgdG8gdmlzaXQgYW5kIGNsaW5pY2FsIG91dGNvbWUuCgojIyMjIEJpb3BzaWVzCgpgYGB7ciBiaW9wc3lfc2VwYXJhdGV9CmJpb3BzeV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGJpb3BzeV9zYW1wbGVzLCBub3JtID0gInF1YW50IiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKGJpb3BzeV9ub3JtKSRwbG90CgpiaW9wc3lfbmIgPC0gbm9ybWFsaXplX2V4cHQoYmlvcHN5X3NhbXBsZXMsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKcGxvdF9wY2EoYmlvcHN5X25iKSRwbG90CmBgYAoKIyMjIyBNb25vY3l0ZXMKCmBgYHtyIG1vbm9jeXRlX3NlcGFyYXRlfQptb25vY3l0ZV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KG1vbm9jeXRlX3NhbXBsZXMsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShtb25vY3l0ZV9ub3JtLCBwbG90X2xhYmVscyA9IEZBTFNFKSRwbG90Cgptb25vY3l0ZV9uYiA8LSBub3JtYWxpemVfZXhwdChtb25vY3l0ZV9zYW1wbGVzLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnBsb3RfcGNhKG1vbm9jeXRlX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKSRwbG90CmBgYAoKIyMjIyBOZXV0cm9waGlscwoKYGBge3IgbmV1dHJvcGhpbF9zZXBhcmF0ZX0KbmV1dHJvcGhpbF9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KG5ldXRyb3BoaWxfc2FtcGxlcywgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKG5ldXRyb3BoaWxfbm9ybSwgcGxvdF9sYWJlbHMgPSBGQUxTRSkkcGxvdAoKbmV1dHJvcGhpbF9uYiA8LSBub3JtYWxpemVfZXhwdChuZXV0cm9waGlsX3NhbXBsZXMsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKcGxvdF9wY2EobmV1dHJvcGhpbF9uYiwgcGxvdF9sYWJlbHMgPSBGQUxTRSkkcGxvdApgYGAKCiMjIyMgRW9zaW5vcGhpbHMKCmBgYHtyIGVvc2lub3BoaWxfc2VwYXJhdGV9CmVvc2lub3BoaWxfbm9ybSA8LSBub3JtYWxpemVfZXhwdChlb3Npbm9waGlsX3NhbXBsZXMsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShlb3Npbm9waGlsX25vcm0sIHBsb3RfbGFiZWxzID0gRkFMU0UpJHBsb3QKCmVvc2lub3BoaWxfbmIgPC0gbm9ybWFsaXplX2V4cHQoZW9zaW5vcGhpbF9zYW1wbGVzLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnBsb3RfcGNhKGVvc2lub3BoaWxfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpJHBsb3QKYGBgCgojIyMjIE1vbm9jeXRlcywgTmV1dHJvcGhpbHMsIGFuZCBFb3Npbm9waGlscwoKIyBEaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNlcwoKVGhlIHByaW1hcnkgZ29hbCBpcyB0byBsZWFybiBhYm91dCBjdXJlIHZzLiBmYWlsLgoKIyMgQ3VyZS9GYWlsIGFsbCBzYW1wbGVzCgpgYGB7ciBjZl9hbGxfZGV9CmNmX2NsaW5pY2FsX2RlIDwtIGFsbF9wYWlyd2lzZShoc19jbGluaWNhbCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKY2ZfY2xpbmljYWxfdGFibGVzIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgY2ZfY2xpbmljYWxfZGUsCiAgICBrZWVwZXJzID0gY2ZfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9jZl9jbGluaWNhbF90YWJsZXMtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL2NmX2NsaW5pY2FsX3NpZy12e3Zlcn0ueGxzeCIpKQpgYGAKCiMjIyBCeSBjZWxsIHR5cGUKCiMjIyMgQ3VyZS9GYWlsIEJpb3BzaWVzCgpgYGB7ciBjZl9iaW9wc3lfZGV9CmNmX2Jpb3BzeV9kZSA8LSBhbGxfcGFpcndpc2UoYmlvcHN5X3NhbXBsZXMsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCmNmX2Jpb3BzeV90YWJsZXMgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBjZl9iaW9wc3lfZGUsCiAgICBrZWVwZXJzID0gY2ZfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9jZl9iaW9wc3lfdGFibGVzLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9jZl9iaW9wc3lfc2lnLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMjIyBDdXJlL0ZhaWwgTW9ub2N5dGVzCgpgYGB7ciBjZl9tb25vY3l0ZV9kZX0KY2ZfbW9ub2N5dGVfZGUgPC0gYWxsX3BhaXJ3aXNlKG1vbm9jeXRlX3NhbXBsZXMsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCmNmX21vbm9jeXRlX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIGNmX21vbm9jeXRlX2RlLAogICAga2VlcGVycyA9IGNmX2NvbnRyYXN0cywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvY2ZfbW9ub2N5dGVfdGFibGVzLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9jZl9tb25vY3l0ZV9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMjIEN1cmUvRmFpbCBOZXV0cm9waGlscwoKYGBge3IgY2ZfbmV1dHJvcGhpbF9kZX0KY2ZfbmV1dHJvcGhpbF9kZSA8LSBhbGxfcGFpcndpc2UobmV1dHJvcGhpbF9zYW1wbGVzLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpjZl9uZXV0cm9waGlsX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIGNmX25ldXRyb3BoaWxfZGUsCiAgICBrZWVwZXJzID0gY2ZfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9jZl9uZXV0cm9waGlsX3RhYmxlcy12e3Zlcn0ueGxzeCIpLAogICAgc2lnX2V4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvY2ZfbmV1dHJvcGhpbF9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMjIEN1cmUvRmFpbCBFb3Npbm9waGlscwoKYGBge3IgY2ZfZW9zaW5vcGhpbF9kZX0KY2ZfZW9zaW5vcGhpbF9kZSA8LSBhbGxfcGFpcndpc2UoZW9zaW5vcGhpbF9zYW1wbGVzLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpjZl9lb3Npbm9waGlsX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIGNmX2Vvc2lub3BoaWxfZGUsCiAgICBrZWVwZXJzID0gY2ZfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9jZl9lb3Npbm9waGlsX3RhYmxlcy12e3Zlcn0ueGxzeCIpLAogICAgc2lnX2V4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvY2ZfZW9zaW5vcGhpbF9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMjIEN1cmUvRmFpbCBjbGluaWNhbCAoTm90IGJpb3BzaWVzKQoKYGBge3IgY2Zfbm9iaW9wc3lfZGV9CmNmX25vYmlvcHN5X2RlIDwtIGFsbF9wYWlyd2lzZShoc19jbGluaWNhbF9ub2Jpb3AsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCmNmX25vYmlvcHN5X3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIGNmX25vYmlvcHN5X2RlLAogICAga2VlcGVycyA9IGNmX2NvbnRyYXN0cywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvY2Zfbm9iaW9wc3lfdGFibGVzLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9jZl9ub2Jpb3BzeV9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMgQnkgdmlzaXQKCkZvciB0aGVzZSBjb250cmFzdHMsIHdlIHdhbnQgdG8gc2VlIGZhaWxfdjEgdnMuIGN1cmVfdjEsIGZhaWxfdjIKdnMuIGN1cmVfdjIgZXRjLiAgQXMgYSByZXN1bHQsIHdlIHdpbGwgbmVlZCB0byBqdWdnbGUgdGhlIGRhdGEKc2xpZ2h0bHkgYW5kIGFkZCBhbm90aGVyIHNldCBvZiBjb250cmFzdHMuCgojIyMgU2V0dGluZyB1cAoKYGBge3Igc2V0dXBfdmlzaXRfY2ZfZGF0YV9jb250cmFzdHN9CnZpc2l0X2NmX2NvbnRyYXN0cyA8LSBsaXN0KAogICAgInYxZmFpbF92c19jdXJlIiA9IGMoInYxZmFpbHVyZSIsICJ2MWN1cmUiKSwKICAgICJ2MmZhaWxfdnNfY3VyZSIgPSBjKCJ2MmZhaWx1cmUiLCAidjJjdXJlIiksCiAgICAidjNmYWlsX3ZzX2N1cmUiID0gYygidjNmYWlsdXJlIiwgInYzY3VyZSIpKQp2aXNpdF9jZl9leHB0X2ZhY3RvciA8LSBwYXN0ZTAoInYiLCBwRGF0YShoc19jbGluaWNhbClbWyJ2aXNpdG51bWJlciJdXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBEYXRhKGhzX2NsaW5pY2FsKVtbImNvbmRpdGlvbiJdXSkKdmlzaXRfY2ZfZXhwdCA8LSBzZXRfZXhwdF9jb25kaXRpb25zKGhzX2NsaW5pY2FsLCBmYWN0ID0gdmlzaXRfY2ZfZXhwdF9mYWN0b3IpCgp2aXNpdF9jZl9iaW9wc3kgPC0gc3Vic2V0X2V4cHQodmlzaXRfY2ZfZXhwdCwgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J2Jpb3BzeSciKQp2aXNpdF9jZl9lb3Npbm9waGlsIDwtIHN1YnNldF9leHB0KHZpc2l0X2NmX2V4cHQsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdlb3Npbm9waGlscyciKQp2aXNpdF9jZl9tb25vY3l0ZSA8LSBzdWJzZXRfZXhwdCh2aXNpdF9jZl9leHB0LCBzdWJzZXQ9InR5cGVvZmNlbGxzPT0nbW9ub2N5dGVzJyIpCnZpc2l0X2NmX25ldXRyb3BoaWwgPC0gc3Vic2V0X2V4cHQodmlzaXRfY2ZfZXhwdCwgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J25ldXRyb3BoaWxzJyIpCmBgYAoKIyMjIyBDdXJlL0ZhaWwgYnkgdmlzaXRzLCBhbGwgY2VsbCB0eXBlcwoKYGBge3IgdmlzaXRfY2ZfYWxsX2RlfQp2aXNpdF9jZl9hbGxfZGUgPC0gYWxsX3BhaXJ3aXNlKHZpc2l0X2NmX2V4cHQsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnZpc2l0X2NmX2FsbF90YWJsZXMgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICB2aXNpdF9jZl9hbGxfZGUsCiAgICBrZWVwZXJzID0gdmlzaXRfY2ZfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9jZl9hbGxfdGFibGVzLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9jZl9hbGxfc2lnLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMjIyBDdXJlL0ZhaWwgYnkgdmlzaXQsIEJpb3BzaWVzCgpgYGB7ciB2aXNpdF9jZl9iaW9wc3lfZGV9CnZpc2l0X2NmX2Jpb3BzeV9kZSA8LSBhbGxfcGFpcndpc2UodmlzaXRfY2ZfZXhwdCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdmlzaXRfY2ZfYmlvcHN5X3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIHZpc2l0X2NmX2Jpb3BzeV9kZSwKICAgIGtlZXBlcnMgPSB2aXNpdF9jZl9jb250cmFzdHMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X2NmX2Jpb3BzeV90YWJsZXMtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X2NmX2Jpb3BzeV9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMjIEN1cmUvRmFpbCBieSB2aXNpdCwgTW9ub2N5dGVzCgpgYGB7ciB2aXNpdF9jZl9tb25vY3l0ZV9kZX0KdmlzaXRfY2ZfbW9ub2N5dGVfZGUgPC0gYWxsX3BhaXJ3aXNlKHZpc2l0X2NmX2V4cHQsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnZpc2l0X2NmX21vbm9jeXRlX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIHZpc2l0X2NmX21vbm9jeXRlX2RlLAogICAga2VlcGVycyA9IHZpc2l0X2NmX2NvbnRyYXN0cywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvdmlzaXRfY2ZfbW9ub2N5dGVfdGFibGVzLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9jZl9tb25vY3l0ZV9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMjIEN1cmUvRmFpbCBieSB2aXNpdCwgTmV1dHJvcGhpbHMKCmBgYHtyIHZpc2l0X2NmX25ldXRyb3BoaWxfZGV9CnZpc2l0X2NmX25ldXRyb3BoaWxfZGUgPC0gYWxsX3BhaXJ3aXNlKHZpc2l0X2NmX2V4cHQsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnZpc2l0X2NmX25ldXRyb3BoaWxfdGFibGVzIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgdmlzaXRfY2ZfbmV1dHJvcGhpbF9kZSwKICAgIGtlZXBlcnMgPSB2aXNpdF9jZl9jb250cmFzdHMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X2NmX25ldXRyb3BoaWxfdGFibGVzLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9jZl9uZXV0cm9waGlsX3NpZy12e3Zlcn0ueGxzeCIpKQpgYGAKCiMjIyMgQ3VyZS9GYWlsIGJ5IHZpc2l0LCBFb3Npbm9waGlscwoKYGBge3IgdmlzaXRfY2ZfZW9zaW5vcGhpbF9kZX0KdmlzaXRfY2ZfZW9zaW5vcGhpbF9kZSA8LSBhbGxfcGFpcndpc2UodmlzaXRfY2ZfZXhwdCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdmlzaXRfY2ZfZW9zaW5vcGhpbF90YWJsZXMgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICB2aXNpdF9jZl9lb3Npbm9waGlsX2RlLAogICAga2VlcGVycyA9IHZpc2l0X2NmX2NvbnRyYXN0cywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvdmlzaXRfY2ZfZW9zaW5vcGhpbF90YWJsZXMtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X2NmX2Vvc2lub3BoaWxfc2lnLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMgUGVyc2lzdGVuY2UgaW4gdmlzaXQgMwoKSGF2aW5nIHB1dCBzb21lIFNMIHJlYWQgbWFwcGluZyBpbmZvcm1hdGlvbiBpbiB0aGUgc2FtcGxlIHNoZWV0LCBNYXJpYQpBZGVsYWlkYSBhZGRlZCBhIG5ldyBjb2x1bW4gdXNpbmcgaXQgd2l0aCB0aGUgcHV0YXRpdmUgcGVyc2lzdGVuY2UKc3RhdGUgb24gYSBwZXItc2FtcGxlIGJhc2lzLiAgT25lIHF1ZXN0aW9uIHdoaWNoIGFyaXNlZCBmcm9tIHRoYXQ6CndoYXQgZGlmZmVyZW5jZXMgYXJlIG9ic2VydmFibGUgYmV0d2VlbiB0aGUgcGVyc2lzdGVudCB5ZXMgdnMuIG5vCnNhbXBsZXMgb24gYSBwZXItY2VsbC10eXBlIGJhc2lzIGFtb25nIHRoZSB2aXNpdCAzIHNhbXBsZXMuCgojIyMgU2V0dGluZyB1cAoKRmlyc3QgdGhpbmdzIGZpcnN0LCBjcmVhdGUgdGhlIGRhdGFzZXRzLgoKYGBge3IgcGVyc2lzdGVuY2Vfc2V0dXB9CnBlcnNpc3RlbmNlX2V4cHQgPC0gc3Vic2V0X2V4cHQoaHNfY2xpbmljYWwsIHN1YnNldCA9ICJwZXJzaXN0ZW5jZT09J1knfHBlcnNpc3RlbmNlPT0nTiciKSAlPiUKICBzdWJzZXRfZXhwdChzdWJzZXQgPSAndmlzaXRudW1iZXI9PTMnKSAlPiUKICBzZXRfZXhwdF9jb25kaXRpb25zKGZhY3QgPSAncGVyc2lzdGVuY2UnKQoKcGVyc2lzdGVuY2VfYmlvcHN5IDwtIHN1YnNldF9leHB0KHBlcnNpc3RlbmNlX2V4cHQsIHN1YnNldCA9ICJ0eXBlb2ZjZWxscz09J2Jpb3BzeSciKQpwZXJzaXN0ZW5jZV9tb25vY3l0ZSA8LSBzdWJzZXRfZXhwdChwZXJzaXN0ZW5jZV9leHB0LCBzdWJzZXQgPSAidHlwZW9mY2VsbHM9PSdtb25vY3l0ZXMnIikKcGVyc2lzdGVuY2VfbmV1dHJvcGhpbCA8LSBzdWJzZXRfZXhwdChwZXJzaXN0ZW5jZV9leHB0LCBzdWJzZXQgPSAidHlwZW9mY2VsbHM9PSduZXV0cm9waGlscyciKQpwZXJzaXN0ZW5jZV9lb3Npbm9waGlsIDwtIHN1YnNldF9leHB0KHBlcnNpc3RlbmNlX2V4cHQsIHN1YnNldCA9ICJ0eXBlb2ZjZWxscz09J2Vvc2lub3BoaWxzJyIpCmBgYAoKIyMjIFRha2UgYSBsb29rCgpTZWUgaWYgdGhlcmUgYXJlIGFueSBwYXR0ZXJucyB3aGljaCBsb29rIHVzYWJsZS4KCmBgYHtyIHBlcnNpc3RlbmNlX3Bsb3R9CiMjIEFsbApwZXJzaXN0ZW5jZV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHBlcnNpc3RlbmNlX2V4cHQsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShwZXJzaXN0ZW5jZV9ub3JtKSRwbG90CnBlcnNpc3RlbmNlX25iIDwtIG5vcm1hbGl6ZV9leHB0KHBlcnNpc3RlbmNlX2V4cHQsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShwZXJzaXN0ZW5jZV9uYikkcGxvdAoKIyMgQmlvcHNpZXMKcGVyc2lzdGVuY2VfYmlvcHN5X25vcm0gPC0gbm9ybWFsaXplX2V4cHQocGVyc2lzdGVuY2VfYmlvcHN5LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EocGVyc2lzdGVuY2VfYmlvcHN5X25vcm0pJHBsb3QKIyMgSW5zdWZmaWNpZW50IGRhdGEKCiMjIE1vbm9jeXRlcwpwZXJzaXN0ZW5jZV9tb25vY3l0ZV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHBlcnNpc3RlbmNlX21vbm9jeXRlLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EocGVyc2lzdGVuY2VfbW9ub2N5dGVfbm9ybSkkcGxvdApwZXJzaXN0ZW5jZV9tb25vY3l0ZV9uYiA8LSBub3JtYWxpemVfZXhwdChwZXJzaXN0ZW5jZV9tb25vY3l0ZSwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHBlcnNpc3RlbmNlX21vbm9jeXRlX25iKSRwbG90CgojIyBOZXV0cm9waGlscwpwZXJzaXN0ZW5jZV9uZXV0cm9waGlsX25vcm0gPC0gbm9ybWFsaXplX2V4cHQocGVyc2lzdGVuY2VfbmV1dHJvcGhpbCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHBlcnNpc3RlbmNlX25ldXRyb3BoaWxfbm9ybSkkcGxvdApwZXJzaXN0ZW5jZV9uZXV0cm9waGlsX25iIDwtIG5vcm1hbGl6ZV9leHB0KHBlcnNpc3RlbmNlX25ldXRyb3BoaWwsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShwZXJzaXN0ZW5jZV9uZXV0cm9waGlsX25iKSRwbG90CgojIyBFb3Npbm9waGlscwpwZXJzaXN0ZW5jZV9lb3Npbm9waGlsX25vcm0gPC0gbm9ybWFsaXplX2V4cHQocGVyc2lzdGVuY2VfZW9zaW5vcGhpbCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHBlcnNpc3RlbmNlX2Vvc2lub3BoaWxfbm9ybSkkcGxvdApwZXJzaXN0ZW5jZV9lb3Npbm9waGlsX25iIDwtIG5vcm1hbGl6ZV9leHB0KHBlcnNpc3RlbmNlX2Vvc2lub3BoaWwsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShwZXJzaXN0ZW5jZV9lb3Npbm9waGlsX25iKSRwbG90CmBgYAoKSSB0aGluayB0aGlzIGlzIGEgYnVzdC4gIEJ1dCwgSSBjYW4gZG8gdGhlIGRlIGFueWhvdyBhbmQgc2VlIHdoYXQKaGFwcGVucy4uLgoKIyMjIHBlcnNpc3RlbmNlIERFCgpgYGB7ciBwZXJzaXN0ZW5jZV9kZX0KcGVyc2lzdGVuY2VfZGUgPC0gYWxsX3BhaXJ3aXNlKHBlcnNpc3RlbmNlX2V4cHQsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIpCnBlcnNpc3RlbmNlX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgcGVyc2lzdGVuY2VfZGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3BlcnNpc3RlbmNlX2FsbF9kZS12e3Zlcn0ueGxzeCIpKQpwZXJzaXN0ZW5jZV9tb25vY3l0ZV9kZSA8LSBhbGxfcGFpcndpc2UocGVyc2lzdGVuY2VfbW9ub2N5dGUsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIpCnBlcnNpc3RlbmNlX21vbm9jeXRlX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgcGVyc2lzdGVuY2VfbW9ub2N5dGVfZGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3BlcnNpc3RlbmNlX21vbm9jeXRlX2RlLXZ7dmVyfS54bHN4IikpCnBlcnNpc3RlbmNlX25ldXRyb3BoaWxfZGUgPC0gYWxsX3BhaXJ3aXNlKHBlcnNpc3RlbmNlX25ldXRyb3BoaWwsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIpCnBlcnNpc3RlbmNlX25ldXRyb3BoaWxfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBwZXJzaXN0ZW5jZV9uZXV0cm9waGlsX2RlLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9wZXJzaXN0ZW5jZV9uZXV0cm9waGlsX2RlLXZ7dmVyfS54bHN4IikpCnBlcnNpc3RlbmNlX2Vvc2lub3BoaWxfZGUgPC0gYWxsX3BhaXJ3aXNlKHBlcnNpc3RlbmNlX2Vvc2lub3BoaWwsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIpCnBlcnNpc3RlbmNlX2Vvc2lub3BoaWxfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBwZXJzaXN0ZW5jZV9lb3Npbm9waGlsX2RlLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9wZXJzaXN0ZW5jZV9lb3Npbm9waGlsX2RlLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMgQ29tcGFyaW5nIHZpc2l0cyB3aXRob3V0IHJlZ2FyZCB0byBjdXJlL2ZhaWwKCiMjIyBBbGwgY2VsbCB0eXBlcwoKYGBge3IgZGVfY2ZfdmlzaXRfYWxsfQp2aXNpdF9hbGxfZGUgPC0gYWxsX3BhaXJ3aXNlKHZpc2l0X2V4cHQsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIpCnZpc2l0X2FsbF90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIHZpc2l0X2FsbF9kZSwKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvdmlzaXRfYWxsX2RlLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9hbGxfc2lnLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMjIEJpb3BzeSBzYW1wbGVzCgpgYGB7ciBkZV9jZl92aXNpdF9iaW9wc3l9CnZpc2l0X2Jpb3BzeV9kZSA8LSBhbGxfcGFpcndpc2UodmlzaXRfYmlvcHN5LCBmaWx0ZXIgPSBUUlVFLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiKQp2aXNpdF9iaW9wc3lfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICB2aXNpdF9iaW9wc3lfZGUsCiAgICBrZWVwZXJzID0gdmlzaXRfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9iaW9wc3lfZGUtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X2Jpb3BzeV9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMgTW9ub2N5dGUgc2FtcGxlcwoKYGBge3IgZGVfY2ZfdmlzaXRfbW9ub2N5dGV9CnZpc2l0X21vbm9jeXRlX2RlIDwtIGFsbF9wYWlyd2lzZSh2aXNpdF9tb25vY3l0ZSwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKdmlzaXRfbW9ub2N5dGVfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICB2aXNpdF9tb25vY3l0ZV9kZSwKICAgIGtlZXBlcnMgPSB2aXNpdF9jb250cmFzdHMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X21vbm9jeXRlX2RlLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9tb25vY3l0ZV9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMgTmV1dHJvcGhpbCBzYW1wbGVzCgpgYGB7ciBkZV9jZl92aXNpdF9uZXV0cm9waGlsfQp2aXNpdF9uZXV0cm9waGlsX2RlIDwtIGFsbF9wYWlyd2lzZSh2aXNpdF9uZXV0cm9waGlsLCBmaWx0ZXIgPSBUUlVFLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiKQp2aXNpdF9uZXV0cm9waGlsX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgdmlzaXRfbmV1dHJvcGhpbF9kZSwKICAgIGtlZXBlcnMgPSB2aXNpdF9jb250cmFzdHMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X25ldXRyb3BoaWxfZGUtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X25ldXRyb3BoaWxfc2lnLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMjIEVvc2lub3BoaWwgc2FtcGxlcwoKYGBge3IgZGVfY2ZfdmlzaXRfZW9zaW5vcGhpbH0KdmlzaXRfZW9zaW5vcGhpbF9kZSA8LSBhbGxfcGFpcndpc2UodmlzaXRfZW9zaW5vcGhpbCwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKdmlzaXRfZW9zaW5vcGhpbF90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIHZpc2l0X2Vvc2lub3BoaWxfZGUsCiAgICBrZWVwZXJzID0gdmlzaXRfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9lb3Npbm9waGlsX2RlLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9lb3Npbm9waGlsX3NpZy12e3Zlcn0ueGxzeCIpKQpgYGAKCiMgTGlrZWxpaG9vZCBSYXRpbyBUZXN0aW5nCgojIyBTaGFyZWQgcGF0dGVybnMgYWNyb3NzIHZpc2l0cwoKYGBge3IgbHJ0X3Zpc2l0fQpscnRfdmlzaXQgPC0gZGVzZXFfbHJ0KGhzX2NsaW5pY2FsLCB0cmFuc2Zvcm0gPSAidnN0IiwKICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmFjdG9yX2NvbHVtbiA9ICJ2aXNpdG51bWJlciIsCiAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJlc3RfY29sdW1uID0gImNsaW5pY2Fsb3V0Y29tZSIpCmBgYAoKIyMgU2hhcmVkIHBhdHRlcm5zIGFjcm9zcyBjZWxsIHR5cGVzCgojIEdlbmUgU2V0IEFuYWx5c2VzCgojIyBHU0VBCgojIyMgQ3VyZS9GYWlsIGdyb3VwcwoKIyMjIENlbGwgdHlwZSBncm91cHMKCiMjIyBWaXNpdCBncm91cHMKCiMjIEdTVkEK