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.

As of 20220224, this document is attempting to synchronize with the google doc named ‘TMRC3_Aug18_2021’. I am hoping therefore to have blocks named according to the figures/etc in that document.

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_202202.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", "drug",
                      "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 121 rows from the sample metadata because they were blank.
## The sample definitions comprises: 202 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 188 columns.
## Before removal, there were 21481 genes, now there are 19941.
## There are 6 samples which kept less than 90 percent counts.
## TMRC30015 TMRC30017 TMRC30019 TMRC30044 TMRC30045 TMRC30154 
##     79.24     85.72     89.75     80.34     73.33     83.20
## The following should make visit 1 the largest if one uses that column as a size factor when plotting.
meta <- pData(hs_expt) %>%
  mutate(visitnumber = fct_relevel(visitnumber, c("notapplicable", "3", "2", "1")))
pData(hs_expt) <- meta

The above block does the following:

  1. Creates an expressionset using the ‘hg38100hisatfile’ column from the most recently downloaded sample sheet (the column’s name has any puctuation/spaces/capitals/etc removed) and the set of human annotations downloaded above.
  2. This expressionset is passed to a filter which pulls out only the protein_coding genes and uses the information from that process to add a new metadata column called ‘ncrna_lost’. Thus it keeps a tally of the number of reads lost in the filter and adds it to the sample sheet.
  3. It is passed again to a function which sanitizes the metadata (there were a couple of entries which said ‘cure’ instead of ‘Cure’ or vice versa) and similarly removes problematic characters.
  4. Passed to a function which sets some columns explicitly to factors instead of characters.
  5. Sets the experimental ‘condition’ to the factor of cure vs. fail.
  6. Sets the experimental ‘batch’ to visit number.
  7. Resets the levels of the visit number so that the samples which were ‘notapplicable’ are logically before visit 1 which is before 2 before 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

The above block does the following:

  1. Extracts the metadata and makes a character vector of the rownames (e.g. the sample IDs).
  2. Creates a table of the clinical metadata from the file I downloaded.
  3. Creates a ‘join’ column from both the existing metadata and the clinical metadata which is the patient code, using whatever the column names were in each sheet.
  4. Joins the two tables using this information. The join function is explicitly used in this context to make sure that the row-order of the entries does not change.
  5. Gets rid of any entries in the new table which are NA.
  6. Replaces the metadata of the expressionset with this new, larger table.

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.

5.3 Define desired colors for the various subsets

There are lots of ways which we will categorize the data, here are some potential color choices for them.

cf_colors <- list(
    "cure" = "#998EC3",
    "failure" = "#F1A340")
type_visit_colors <- list(
    "monocytes_v1" = "#DD1C77",
    "monocytes_v2" = "#C994C7",
    "monocytes_v3" = "#E7E1EF",
    "eosinophils_v1" = "#31A354",
    "eosinophils_v2" = "#ADDD8E",
    "eosinophils_v3" = "#F7FCD9",
    "neutrophils_v1" = "#3182BD",
    "neutrophils_v2" = "#9ECAE1",
    "neutrophils_v3" = "#DEEBF7",
    "biopsy_v1" = "#D95F0E")
type_colors <- list(
    "monocytes" = "#DD1C77",
    "eosinophils" = "#31A354",
    "neutrophils" = "#3182BD",
    "biopsy" = "#D95F0E")
visit_colors <- list()
cf_type_colors <- list(
    cure_biopsy = "#D95F0E",
    failure_biopsy = "#FEC44F",
    cure_monocytes = "#DD1C77",
    failure_monocytes = "#C994C7",
    cure_eosinophils = "#31A354",
    failure_eosinophils = "#ADDD8E",
    cure_neutrophils = "#3182BD",
    failure_neutrophils = "#9ECAE1")

5.4 Define the starting data

The following block contains the primary dataset which is the parent of everything which follows.

hs_valid <- subset_expt(hs_expt, nonzero=11000) %>%
  subset_expt(subset="clinicaloutcome!='lost'") %>%
  subset_expt(subset="clinicaloutcome!='notapplicable'") %>%
  subset_expt(subset="clinicaloutcome!='null'") %>%
  set_expt_colors(cf_colors)
## The samples (and read coverage) removed when filtering 11000 non-zero genes are:
## TMRC30010 TMRC30050 TMRC30052 
##     52471    808149   3087347
## subset_expt(): There were 188, now there are 185 samples.
## subset_expt(): There were 185, now there are 170 samples.
## subset_expt(): There were 170, now there are 148 samples.
## subset_expt(): There were 148, now there are 148 samples.

5.5 Count up sample types

I recently convinced myself that there is a difference between the data when it does and does not include the miltefosine treated patients.

However, when I actually counted up the samples by a few criteria I immediately relized this is spurious.

table(pData(hs_valid)$drug)
## 
## antimony 
##      148
table(pData(hs_valid)$clinicaloutcome)
## 
##    cure failure 
##      91      57
table(pData(hs_valid)$typeofcells)
## 
##      biopsy eosinophils   monocytes neutrophils 
##          14          32          52          50
table(pData(hs_valid)$visit)
## 
##  3  2  1 
## 44 42 62
summary(as.numeric(pData(hs_valid)$eb_lc_tiempo_evolucion))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    2.00    4.00    5.00    6.89    8.00   21.00
summary(as.numeric(pData(hs_valid)$eb_lc_tto_mcto_glucan_dosis))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    13.0    15.0    19.0    17.6    20.0    20.0
summary(as.numeric(pData(hs_valid)$v3_lc_ejey_lesion_mm_1))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     0.0     4.6    32.7   336.6   999.0   999.0
summary(as.numeric(pData(hs_valid)$v3_lc_lesion_area_1))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0     112     999    1868    1376   11487
summary(as.numeric(pData(hs_valid)$v3_lc_ejex_ulcera_mm_1))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0      35     333     999     999
table(pData(hs_valid)$eb_lc_sexo)
## 
##   1   2 
## 128  20
table(pData(hs_valid)$eb_lc_etnia)
## 
##  1  2  3 
## 85 36 27
summary(as.numeric(pData(hs_valid)$edad))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    18.0    25.0    28.0    29.5    35.0    51.0
table(pData(hs_valid)$eb_lc_peso)
## 
## 53.9 58.1 58.3 58.6   59 59.6   62   63   67 69.4 76.5   77   78 79.2   82 83.3 
##    9    4   10    1    8    1    6    6    6   10    2   18   10   10    8    4 
## 83.4 86.4   87   89 93.3 
##   10    9    2    8    6
table(pData(hs_valid)$eb_lc_estatura)
## 
## 152 154 158 160 163 164 165 166 167 172 173 174 176 177 182 183 
##   1  10  15   2   9  12  10  18   2  10   4  29   1   6   9  10

The above block does what it says on the tin, subsets the data to exclude any sample with less than 11,000 observed genes.

5.6 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   monocytes neutrophils 
##          14          32          52          50
biopsy_samples <- subset_expt(hs_valid, subset="typeofcells=='biopsy'")
## subset_expt(): There were 148, now there are 14 samples.
eosinophil_samples <- subset_expt(hs_valid, subset="typeofcells=='eosinophils'")
## subset_expt(): There were 148, now there are 32 samples.
monocyte_samples <- subset_expt(hs_valid, subset="typeofcells=='monocytes'")
## subset_expt(): There were 148, now there are 52 samples.
neutrophil_samples <- subset_expt(hs_valid, subset="typeofcells=='neutrophils'")
## subset_expt(): There were 148, now there are 50 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 148, now there are 62 samples.
v1_biopsies <- subset_expt(v1_samples, subset="typeofcells=='biopsy'")
## subset_expt(): There were 62, now there are 14 samples.
v1_monocytes <- subset_expt(v1_samples, subset="typeofcells=='monocytes'")
## subset_expt(): There were 62, now there are 19 samples.
v1_neutrophils <- subset_expt(v1_samples, subset="typeofcells=='neutrophils'")
## subset_expt(): There were 62, now there are 18 samples.
v1_eosinophils <- subset_expt(v1_samples, subset="typeofcells=='eosinophils'")
## subset_expt(): There were 62, now there are 11 samples.
v2_samples <- subset_expt(hs_valid, subset="visitnumber=='2'")
## subset_expt(): There were 148, now there are 42 samples.
v2_monocytes <- subset_expt(v2_samples, subset="typeofcells=='monocytes'")
## subset_expt(): There were 42, now there are 16 samples.
v2_neutrophils <- subset_expt(v2_samples, subset="typeofcells=='neutrophils'")
## subset_expt(): There were 42, now there are 16 samples.
v2_eosinophils <- subset_expt(v2_samples, subset="typeofcells=='eosinophils'")
## subset_expt(): There were 42, now there are 10 samples.
v3_samples <- subset_expt(hs_valid, subset="visitnumber=='3'")
## subset_expt(): There were 148, now there are 44 samples.
v3_monocytes <- subset_expt(v3_samples, subset="typeofcells=='monocytes'")
## subset_expt(): There were 44, now there are 17 samples.
v3_neutrophils <- subset_expt(v3_samples, subset="typeofcells=='neutrophils'")
## subset_expt(): There were 44, now there are 16 samples.
v3_eosinophils <- subset_expt(v3_samples, subset="typeofcells=='eosinophils'")
## subset_expt(): There were 44, now there are 11 samples.

The above block does a lot of subset operations to create separate data structures on a per-celltype and per-visit basis. Ergo, our large data structure is now joined by ~21 new, smaller data structures.

6 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=1000) %>%
  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 1000 reads are:
## TMRC30001 TMRC30002 TMRC30003 TMRC30004 TMRC30005 TMRC30006 TMRC30007 TMRC30008 
##        12         8         9        16        25        29         3        16 
## TMRC30009 TMRC30010 TMRC30011 TMRC30012 TMRC30013 TMRC30050 TMRC30018 TMRC30118 
##        16         0         5         9        13       345       110       747 
## TMRC30119 TMRC30014 TMRC30021 TMRC30038 TMRC30023 TMRC30025 TMRC30165 TMRC30166 
##       419         4        88       208       120       954       433       496 
## TMRC30030 TMRC30031 TMRC30032 TMRC30024 TMRC30040 TMRC30033 TMRC30164 TMRC30037 
##         3         8        22        49       896        36       424         9 
## TMRC30027 TMRC30028 TMRC30034 TMRC30035 TMRC30036 TMRC30041 TMRC30042 TMRC30043 
##       108        93        21       153        11       264       545       571 
## TMRC30045 TMRC30171 TMRC30158 TMRC30159 TMRC30139 TMRC30160 TMRC30161 TMRC30152 
##       334       370       284       405       140       296       300       495 
## TMRC30123 TMRC30181 TMRC30182 TMRC30155 TMRC30129 TMRC30137 TMRC30174 TMRC30154 
##       304       613       468       508       353       389       644       398 
## TMRC30172 TMRC30173 TMRC30142 TMRC30143 TMRC30144 TMRC30145 TMRC30146 TMRC30147 
##       383       898         4         1         0         0         0         1 
## TMRC30185 TMRC30141 TMRC30130 TMRC30124 TMRC30131 TMRC30109 TMRC30110 TMRC30111 
##         0       135        27         3        24       881       142       224 
## TMRC30112 TMRC30163 TMRC30148 TMRC30138 TMRC30150 TMRC30140 TMRC30151 TMRC30178 
##       996       255       706       156       470       153       480       420 
## TMRC30179 TMRC30197 TMRC30198 TMRC30200 TMRC30201 TMRC30202 TMRC30203 TMRC30205 
##       515       202       158        96       149       145       104       169 
## TMRC30206 TMRC30207 TMRC30208 TMRC30217 TMRC30218 TMRC30219 TMRC30220 TMRC30209 
##       125         0         1         0         2         0         0         0 
## TMRC30210 TMRC30211 TMRC30212 TMRC30213 TMRC30214 TMRC30215 TMRC30216 TMRC30221 
##         0         0         0         0         0         1         0         0 
## TMRC30222 TMRC30223 TMRC30224 TMRC30225 TMRC30226 TMRC30227 TMRC30229 TMRC30230 
##         0         0         2         0         0         0         0         0 
## TMRC30231 TMRC30232 TMRC30233 TMRC30234 TMRC30235 
##         0         1         0         0         0
## subset_expt(): There were 223, now there are 106 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)

The above block is similar in concept to the previous expressionset creation. It uses a different column and currently ignores the gene annotations. Given that many of the samples have essentially 0 reads, I set a cutoff of only 20 observed genes. Finally, I did a quick and dirty PCA plot of this peculiar data structure in the hopes of being able to ‘see’ the difference between what are assumed to be ‘real’ samples with a significant number of ‘real’ parasite reads vs. those samples which just have a couple of potentially spurious reads.

7 Contrasts and colors 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"))

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

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

plot_libsize(eosinophil_samples)$plot

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

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

plot_libsize(monocyte_samples)$plot

plot_nonzero(monocyte_samples)$plot
## Warning: ggrepel: 39 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: 27 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

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

The above block just repeats the same two plots on a per-celltype basis: the number of reads observed / sample and a plot of observed genes with respect to coverage. I made some comments with my observations about the number of genes.

8.2 Global PCA

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.

8.2.1 Figure 1

In the google doc TMRC3_Aug18_2021, there is an example of an image for the first figure:

“Transcriptomic profiles of primary innate cells of CL patients show unique transcriptional signatures - Remove PBMCs and M0, maybe biopsies as well (but Remove WT samples)”

While we were talking in a meeting however, it sounded like there was some desire to keep all cell types. Therefore the following block will have one image with everything and one following the above.

type_valid <- set_expt_conditions(hs_valid, fact="typeofcells") %>%
  set_expt_batches(fact="clinicaloutcome") %>%
  set_expt_colors(type_colors)

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)
## Error in if (which == 1) stop("cannot shut down device 1 (the null device)"): argument is of length zero
all_pca_nosize <- plot_pca(all_norm, plot_labels=FALSE)
all_pca_nosize$plot

write.csv(all_pca$table, file="coords/hs_donor_pca_coords.csv")
all_cf_norm <- set_expt_batches(all_norm,
                                fact="visitnumber")
pp(file=glue("images/tmrc3_corheat_cf-v{ver}.png"),
   image=plot_corheat(all_cf_norm, plot_title="Heirarchical clustering:
         cell types")$plot)
## Error in if (which == 1) stop("cannot shut down device 1 (the null device)"): argument is of length zero
pp(file=glue("images/tmrc3_disheat_cf-v{ver}.png"),
   image=plot_disheat(all_cf_norm, plot_title="Heirarchical clustering:
         cell types")$plot)
## Error in if (which == 1) stop("cannot shut down device 1 (the null device)"): argument is of length zero

all_cf_disheat <- plot_disheat(all_cf_norm)
all_cf_disheat$plot

8.3 Figure 1B: Transcriptomic profiles of primary innate

The biggest caveat for this is to ensure that there are no Wellcome Trust samples.

A potential figure legend for the following images might include:

The observed counts per gene for all of the clinical samples were filtered, log transformed, cpm converted, and quantile normalized. The colors were defined by cell types and shapes by patient visit. When the first two principle components were plotted, clustering was observed by cell type. The biopsy samples were significantly different from the innate immune cell types.

fig1v2_norm <- normalize_expt(type_valid, transform="log2",
                              convert="cpm", norm="quant", filter=TRUE)
## Removing 5748 low-count genes (14193 remaining).
## transform_counts: Found 311 values equal to 0, adding 1 to the matrix.
fig1v2_pca <- plot_pca(fig1v2_norm, cis=FALSE)
## plot labels was not set and there are more than 100 samples, disabling it.
pp(file=glue("images/tmrc3_fig1v2.png"), image=fig1v2_pca$plot)
## Error in if (which == 1) stop("cannot shut down device 1 (the null device)"): argument is of length zero
fig1v3_samples <- subset_expt(type_valid, subset="condition!='biopsy'")
## subset_expt(): There were 148, now there are 134 samples.
fig1v3_norm <- normalize_expt(fig1v3_samples, transform="log2",
                              convert="cpm", norm="quant", filter=TRUE)
## Removing 7907 low-count genes (12034 remaining).
## transform_counts: Found 108 values equal to 0, adding 1 to the matrix.
fig1v3_pca <- plot_pca(fig1v3_norm, cis=FALSE)
## plot labels was not set and there are more than 100 samples, disabling it.
pp(file="images/tmrc3_fig1v3.png", image=fig1v3_pca$plot)
## Error in if (which == 1) stop("cannot shut down device 1 (the null device)"): argument is of length zero

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.3.1 Clinically relevant samples

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

8.3.1.1 Remove the lost samples

In our 20220218 meeting, it was decided that we would focus explicitly on the cure and fail samples, ignoring lost/NA/null samples.

Thus I am adding explicit filters right at the top to exclude them.

hs_clinical <- hs_valid %>%
  set_expt_conditions(fact="clinicaloutcome") %>%
  set_expt_batches(fact="typeofcells") %>%
  set_expt_colors(cf_colors)

hs_clinical_nobiop <- subset_expt(hs_clinical, subset="typeofcells!='biopsy'")
## subset_expt(): There were 148, now there are 134 samples.

8.3.2 Plot the clinical samples

Let us recolor the same plot by cure/fail followed by a concatenation of the cell type and cure/fail. In the following block, the clinical samples are plotted once with the most common normalization (log,cpm,quant,filtered) method followed by a plot of the data using svaseq adjusted values and without quantile normalization.

Thus, the following block switches the colors of the groups to the clinical state (cure/fail) and shapes by cell type.

hs_clinical_norm <- sm(normalize_expt(hs_clinical, filter="simple", transform="log2",
                                      norm="quant", convert="cpm"))
clinical_pca <- plot_pca(hs_clinical_norm, plot_labels=FALSE,
                         cis=NULL,
                         plot_title="PCA - clinical samples")
clinical_pca$plot

pp(file=glue("images/all_clinical_nobatch_pca-v{ver}.png"),
   image=clinical_pca$plot, height=8, width=16)
## Error in if (which == 1) stop("cannot shut down device 1 (the null device)"): argument is of length zero
hs_clinical_nb <- normalize_expt(hs_clinical, filter="simple", transform="log2",
                                 batch="svaseq", convert="cpm")
## Removing 1916 low-count genes (18025 remaining).
## batch_counts: Before batch/surrogate estimation, 505502 entries are x==0: 19%.
## batch_counts: Before batch/surrogate estimation, 675288 entries are 0<x<1: 25%.
## Setting 124701 low elements to zero.
## transform_counts: Found 124701 values equal to 0, adding 1 to the matrix.
hs_clinical_nb_pca <- plot_pca(hs_clinical_nb)
## plot labels was not set and there are more than 100 samples, disabling it.
hs_clinical_nb_pca$plot
pp(file=glue("images/all_clinical_svaseqbatch_pca-v{ver}.png"),
   image=hs_clinical_nb_pca$plot, height=6, width=8)
## Error in if (which == 1) stop("cannot shut down device 1 (the null device)"): argument is of length zero
table(pData(hs_clinical)[["condition"]])
## 
##    cure failure 
##      91      57
test <- pca_information(
    hs_clinical_norm, plot_pcas=TRUE,
    expt_factors=c("visitnumber", "typeofcells", "clinicaloutcome", "eb_lc_estatura", "drug"))
## plot labels was not set and there are more than 100 samples, disabling it.
## The standard deviation was 0 for drug and pc_1.
## The standard deviation was 0 for drug and pc_2.
## The standard deviation was 0 for drug and pc_3.
## The standard deviation was 0 for drug and pc_4.
## The standard deviation was 0 for drug and pc_5.

8.3.3 Concatenate cure/fail and cell type

In the following block the experimental condition was reset to the concatenation of clinical outcome and type of cells. There are an insufficient number of biopsy samples for them to be useful in this visualization, so they are ignored.

new_fact <- factor(
    paste0(pData(hs_clinical)[["condition"]], "_",
           pData(hs_clinical)[["batch"]]),
    levels=c("cure_biopsy", "failure_biopsy", "cure_eosinophils", "failure_eosinophils",
             "cure_monocytes", "failure_monocytes", "cure_neutrophils", "failure_neutrophils"))
hs_clinical_concat <- set_expt_conditions(hs_clinical, fact = new_fact) %>%
  set_expt_batches(fact = "visitnumber") %>%
  set_expt_colors(cf_type_colors) %>%
  subset_expt(subset="typeofcells!='biopsy'")
## subset_expt(): There were 148, now there are 134 samples.
clinical_concat_norm <- normalize_expt(hs_clinical_concat, transform = "log2", convert = "cpm",
                                       norm = "quant", filter = TRUE)
## Removing 7907 low-count genes (12034 remaining).
## transform_counts: Found 108 values equal to 0, adding 1 to the matrix.
clinical_concat_norm_pca <- plot_pca(clinical_concat_norm)
## plot labels was not set and there are more than 100 samples, disabling it.
pp(file=glue("images/clinical_concatenated_normalized_pca-v{ver}.png"),
   image=clinical_concat_norm_pca$plot, height=6, width=10)
## Error in if (which == 1) stop("cannot shut down device 1 (the null device)"): argument is of length zero
clinical_concat_nb <- normalize_expt(hs_clinical_concat, transform = "log2", convert = "cpm",
                                     batch = "svaseq", filter = TRUE)
## Removing 7907 low-count genes (12034 remaining).
## batch_counts: Before batch/surrogate estimation, 38492 entries are x==0: 2%.
## batch_counts: Before batch/surrogate estimation, 280504 entries are 0<x<1: 17%.
## Setting 40423 low elements to zero.
## transform_counts: Found 40423 values equal to 0, adding 1 to the matrix.
clinical_concat_nb_pca <- plot_pca(clinical_concat_nb)
## plot labels was not set and there are more than 100 samples, disabling it.
pp(file=glue("images/clinical_concatenated_svaseqbatch_pca-v{ver}.png"),
   image=clinical_concat_nb_pca$plot, height=6, width=12)
## Error in if (which == 1) stop("cannot shut down device 1 (the null device)"): argument is of length zero

8.3.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.3.4.1 All visits together

Now let us shift the view slightly to focus on changes observed over time.

visit_expt <- set_expt_conditions(hs_clinical, fact = "visitnumber") %>%
  set_expt_batches(fact = "clinicaloutcome") %>%
  subset_expt(subset="typeofcells!='biopsy'")
## subset_expt(): There were 148, now there are 134 samples.
visit_norm <- normalize_expt(visit_expt, transform="log2", convert="cpm",
                             norm="quant", filter=TRUE)
## Removing 7907 low-count genes (12034 remaining).
## transform_counts: Found 108 values equal to 0, adding 1 to the matrix.
plot_pca(visit_norm)$plot
## plot labels was not set and there are more than 100 samples, disabling it.

visit_nb <- normalize_expt(visit_expt, transform = "log2", convert="cpm",
                           filter = TRUE, batch = "svaseq")
## Removing 7907 low-count genes (12034 remaining).
## batch_counts: Before batch/surrogate estimation, 38492 entries are x==0: 2%.
## batch_counts: Before batch/surrogate estimation, 280504 entries are 0<x<1: 17%.
## Setting 12511 low elements to zero.
## transform_counts: Found 12511 values equal to 0, adding 1 to the matrix.
visit_nb_pca <- plot_pca(visit_nb)
## plot labels was not set and there are more than 100 samples, disabling it.
pp(file=glue("images/visit_svaseqbatch_pca-v{ver}.png"),
   image=visit_nb_pca$plot, height=7, width=9)
## Error in if (which == 1) stop("cannot shut down device 1 (the null device)"): argument is of length zero

8.4 Top 1000 genes

repeat with only the most expressed genes from one cell type.

rpkm_values <- normalize_expt(type_valid, transform="log2", convert="rpkm",
                              filter=TRUE, column="cds_length")
## Removing 5748 low-count genes (14193 remaining).
## transform_counts: Found 156563 values equal to 0, adding 1 to the matrix.
rpkm_median <- median_by_factor(rpkm_values)
## The factor biopsy has 14 rows.
## The factor eosinophils has 32 rows.
## The factor monocytes has 52 rows.
## The factor neutrophils has 50 rows.
monocyte_most <- order(rpkm_median[["medians"]][["monocytes"]], decreasing=TRUE)
rpkm_most_monocytes <- rpkm_median[["medians"]][monocyte_most, ]
most_monocyte_genes <- head(rownames(rpkm_most_monocytes), n=1000)

subset <- exclude_genes_expt(visit_glucv2, method="keep", ids=most_monocyte_genes)
## Error in exclude_genes_expt(visit_glucv2, method = "keep", ids = most_monocyte_genes): object 'visit_glucv2' not found
subset_norm <- normalize_expt(subset, transform="log2", convert="cpm", batch="svaseq", filter=TRUE)
## Error in expt[["state"]]: object of type 'closure' is not subsettable

8.4.0.1 All visits, separated by cell type

Now separate the visits by cell type and whether or not the drug used was the antimonial.

visit_monocyte <- subset_expt(visit_expt, subset = "typeofcells=='monocytes'")
## subset_expt(): There were 134, now there are 52 samples.
visit_monocyte_glucantime <- subset_expt(visit_monocyte, subset = "drug=='antimony'")
## subset_expt(): There were 52, now there are 52 samples.
visit_neutrophil <- subset_expt(visit_expt, subset = "typeofcells=='neutrophils'")
## subset_expt(): There were 134, now there are 50 samples.
visit_neutrophil_glucantime <- subset_expt(visit_neutrophil, subset = "drug=='antimony'")
## subset_expt(): There were 50, now there are 50 samples.
visit_eosinophil <- subset_expt(visit_expt, subset = "typeofcells=='eosinophils'")
## subset_expt(): There were 134, now there are 32 samples.
visit_eosinophil_glucantime <- subset_expt(visit_eosinophil, subset = "drug=='antimony'")
## subset_expt(): There were 32, now there are 32 samples.

8.4.0.2 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 134, now there are 48 samples.
v1_norm <- normalize_expt(v1_clinical, transform="log2", convert="cpm", norm="quant", filter=TRUE)
## Removing 8295 low-count genes (11646 remaining).
## transform_counts: Found 52 values equal to 0, adding 1 to the matrix.
plot_pca(v1_norm)$plot
## Warning: ggrepel: 45 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

v1_nb <- normalize_expt(v1_clinical, transform = "log2", convert = "cpm",
                        filter = TRUE, batch = "svaseq")
## Removing 8295 low-count genes (11646 remaining).
## batch_counts: Before batch/surrogate estimation, 10019 entries are x==0: 2%.
## batch_counts: Before batch/surrogate estimation, 86647 entries are 0<x<1: 16%.
## Setting 3113 low elements to zero.
## transform_counts: Found 3113 values equal to 0, adding 1 to the matrix.
plot_pca(v1_nb, plot_labels = FALSE)$plot

So, given the data on hand, there is little or no ability to discern cure and fail among the visit 1 samples.

8.4.0.3 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 134, now there are 42 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 8282 low-count genes (11659 remaining).
## batch_counts: Before batch/surrogate estimation, 15 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 67993 entries are 0<x<1: 14%.
## Setting 2252 low elements to zero.
## transform_counts: Found 2252 values equal to 0, adding 1 to the matrix.
plot_pca(v2_nb, plot_labels = FALSE)$plot

There might be some variance among the visit 2 samples which are cure/fail-ish.

8.4.0.4 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 134, now there are 44 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 8340 low-count genes (11601 remaining).
## batch_counts: Before batch/surrogate estimation, 43 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 71138 entries are 0<x<1: 14%.
## Setting 2015 low elements to zero.
## transform_counts: Found 2015 values equal to 0, adding 1 to the matrix.
plot_pca(v3_nb, plot_labels = FALSE)$plot

In a similar fashion, it seems that the visit 3 samples are not particularly informative.

8.4.1 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.4.1.1 Biopsies

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

biopsy_nb <- normalize_expt(biopsy_samples, convert = "cpm",
                            transform = "log2", filter = TRUE, batch = "svaseq")
## Removing 6438 low-count genes (13503 remaining).
## batch_counts: Before batch/surrogate estimation, 640 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 6191 entries are 0<x<1: 3%.
## Setting 182 low elements to zero.
## transform_counts: Found 182 values equal to 0, adding 1 to the matrix.
plot_pca(biopsy_nb, plot_labels = FALSE)$plot

Ouch, it really looks like the biopies are not very informative.

8.4.1.2 Monocytes

monocyte_norm <- normalize_expt(monocyte_samples, norm = "quant", convert = "cpm",
                                transform = "log2", filter = TRUE)
## Removing 8909 low-count genes (11032 remaining).
## transform_counts: Found 5 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 8909 low-count genes (11032 remaining).
## batch_counts: Before batch/surrogate estimation, 2022 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 33432 entries are 0<x<1: 6%.
## Setting 1168 low elements to zero.
## transform_counts: Found 1168 values equal to 0, adding 1 to the matrix.
plot_pca(monocyte_nb, plot_labels = FALSE)$plot

The monocytes, on the other hand, appear to have some real information lurking in them.

8.4.1.3 Neutrophils

neutrophil_norm <- normalize_expt(neutrophil_samples, norm = "quant", convert = "cpm",
                                transform = "log2", filter = TRUE)
## Removing 10749 low-count genes (9192 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 10749 low-count genes (9192 remaining).
## batch_counts: Before batch/surrogate estimation, 1373 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 38536 entries are 0<x<1: 8%.
## Setting 892 low elements to zero.
## transform_counts: Found 892 values equal to 0, adding 1 to the matrix.
plot_pca(neutrophil_nb, plot_labels = FALSE)$plot

This appears also to be the case for the neutrophil samples.

8.4.1.4 Eosinophils

eosinophil_norm <- normalize_expt(eosinophil_samples, norm = "quant", convert = "cpm",
                                transform = "log2", filter = TRUE)
## Removing 9262 low-count genes (10679 remaining).
## transform_counts: Found 4 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 9262 low-count genes (10679 remaining).
## batch_counts: Before batch/surrogate estimation, 729 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 18897 entries are 0<x<1: 6%.
## Setting 521 low elements to zero.
## transform_counts: Found 521 values equal to 0, adding 1 to the matrix.
plot_pca(eosinophil_nb, plot_labels = FALSE)$plot

We have fewer eosinophil samples currently, but they appear to have some real differences.

8.4.1.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

Now let us start performing the various differential expression analyses, starting with the set of all/most clinical samples.

cf_clinical_de <- all_pairwise(hs_clinical, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 160760 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 (14193 remaining).
## batch_counts: Before batch/surrogate estimation, 160760 entries are x==0: 8%.
## batch_counts: Before batch/surrogate estimation, 457814 entries are 0<x<1: 22%.
## Setting 20566 low elements to zero.
## transform_counts: Found 20566 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-v202202.xlsx before writing the tables.
## Deleting the file excel/cf_clinical_sig-v202202.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, 640 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 (13503 remaining).
## batch_counts: Before batch/surrogate estimation, 640 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 6191 entries are 0<x<1: 3%.
## Setting 182 low elements to zero.
## transform_counts: Found 182 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-v202202.xlsx before writing the tables.
## Deleting the file excel/cf_biopsy_sig-v202202.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, 2022 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 (11032 remaining).
## batch_counts: Before batch/surrogate estimation, 2022 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 33432 entries are 0<x<1: 6%.
## Setting 1168 low elements to zero.
## transform_counts: Found 1168 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-v202202.xlsx before writing the tables.
## Deleting the file excel/cf_monocyte_sig-v202202.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, 1373 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 (9192 remaining).
## batch_counts: Before batch/surrogate estimation, 1373 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 38536 entries are 0<x<1: 8%.
## Setting 892 low elements to zero.
## transform_counts: Found 892 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-v202202.xlsx before writing the tables.
## Deleting the file excel/cf_neutrophil_sig-v202202.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, 729 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 (10679 remaining).
## batch_counts: Before batch/surrogate estimation, 729 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 18897 entries are 0<x<1: 6%.
## Setting 521 low elements to zero.
## transform_counts: Found 521 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-v202202.xlsx before writing the tables.
## Deleting the file excel/cf_eosinophil_sig-v202202.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, 38492 entries are x==0: 2%.
## 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 (12034 remaining).
## batch_counts: Before batch/surrogate estimation, 38492 entries are x==0: 2%.
## batch_counts: Before batch/surrogate estimation, 280504 entries are 0<x<1: 17%.
## Setting 12468 low elements to zero.
## transform_counts: Found 12468 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"))

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 148, now there are 14 samples.
visit_cf_eosinophil <- subset_expt(visit_cf_expt, subset="typeofcells=='eosinophils'")
## subset_expt(): There were 148, now there are 32 samples.
visit_cf_monocyte <- subset_expt(visit_cf_expt, subset="typeofcells=='monocytes'")
## subset_expt(): There were 148, now there are 52 samples.
visit_cf_neutrophil <- subset_expt(visit_cf_expt, subset="typeofcells=='neutrophils'")
## subset_expt(): There were 148, now there are 50 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, 160760 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 (14193 remaining).
## batch_counts: Before batch/surrogate estimation, 160760 entries are x==0: 8%.
## batch_counts: Before batch/surrogate estimation, 457814 entries are 0<x<1: 22%.
## Setting 20201 low elements to zero.
## transform_counts: Found 20201 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-v202202.xlsx before writing the tables.
## Deleting the file excel/visit_cf_all_sig-v202202.xlsx before writing the tables.

9.1.3.2 Cure/Fail by visit, Biopsies

visit_cf_biopsy_de <- all_pairwise(visit_cf_biopsy, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 640 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 (13503 remaining).
## batch_counts: Before batch/surrogate estimation, 640 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 6191 entries are 0<x<1: 3%.
## Setting 182 low elements to zero.
## transform_counts: Found 182 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-v202202.xlsx before writing the tables.
## Warning in extract_keepers_lst(extracted, keepers, legend[["table_names"]], :
## FOUND NEITHER v2failure_vs_v2cure NOR v2cure_vs_v2failure!
## Deleting the file excel/visit_cf_biopsy_sig-v202202.xlsx before writing the tables.

9.1.3.3 Cure/Fail by visit, Monocytes

visit_cf_monocyte_de <- all_pairwise(visit_cf_monocyte, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 2022 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 (11032 remaining).
## batch_counts: Before batch/surrogate estimation, 2022 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 33432 entries are 0<x<1: 6%.
## Setting 1070 low elements to zero.
## transform_counts: Found 1070 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-v202202.xlsx before writing the tables.
## Deleting the file excel/visit_cf_monocyte_sig-v202202.xlsx before writing the tables.

9.1.3.4 Cure/Fail by visit, Neutrophils

visit_cf_neutrophil_de <- all_pairwise(visit_cf_neutrophil, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 1373 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 (9192 remaining).
## batch_counts: Before batch/surrogate estimation, 1373 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 38536 entries are 0<x<1: 8%.
## Setting 924 low elements to zero.
## transform_counts: Found 924 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-v202202.xlsx before writing the tables.
## Deleting the file excel/visit_cf_neutrophil_sig-v202202.xlsx before writing the tables.

9.1.3.5 Cure/Fail by visit, Eosinophils

visit_cf_eosinophil_de <- all_pairwise(visit_cf_eosinophil, model_batch = "svaseq", filter = TRUE)
## batch_counts: Before batch/surrogate estimation, 729 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 (10679 remaining).
## batch_counts: Before batch/surrogate estimation, 729 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 18897 entries are 0<x<1: 6%.
## Setting 514 low elements to zero.
## transform_counts: Found 514 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-v202202.xlsx before writing the tables.
## Deleting the file excel/visit_cf_eosinophil_sig-v202202.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 148, now there are 118 samples.
## subset_expt(): There were 118, now there are 40 samples.
## persistence_biopsy <- subset_expt(persistence_expt, subset = "typeofcells=='biopsy'")
persistence_monocyte <- subset_expt(persistence_expt, subset = "typeofcells=='monocytes'")
## subset_expt(): There were 40, now there are 16 samples.
persistence_neutrophil <- subset_expt(persistence_expt, subset = "typeofcells=='neutrophils'")
## subset_expt(): There were 40, now there are 14 samples.
persistence_eosinophil <- subset_expt(persistence_expt, subset = "typeofcells=='eosinophils'")
## subset_expt(): There were 40, 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 8389 low-count genes (11552 remaining).
## transform_counts: Found 19 values equal to 0, adding 1 to the matrix.
plot_pca(persistence_norm)$plot
## Warning: ggrepel: 29 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 8389 low-count genes (11552 remaining).
## batch_counts: Before batch/surrogate estimation, 7042 entries are x==0: 2%.
## batch_counts: Before batch/surrogate estimation, 69272 entries are 0<x<1: 15%.
## Setting 2388 low elements to zero.
## transform_counts: Found 2388 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)
##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

9.2.3 persistence DE

persistence_de <- all_pairwise(persistence_expt, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 7042 entries are x==0: 2%.
## 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 (11552 remaining).
## batch_counts: Before batch/surrogate estimation, 7042 entries are x==0: 2%.
## batch_counts: Before batch/surrogate estimation, 69272 entries are 0<x<1: 15%.
## Setting 2388 low elements to zero.
## transform_counts: Found 2388 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-v202202.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-v202202.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-v202202.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-v202202.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, 38492 entries are x==0: 2%.
## 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 (12034 remaining).
## batch_counts: Before batch/surrogate estimation, 38492 entries are x==0: 2%.
## batch_counts: Before batch/surrogate estimation, 280504 entries are 0<x<1: 17%.
## Setting 12511 low elements to zero.
## transform_counts: Found 12511 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,
    keepers = visit_contrasts,
    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-v202202.xlsx before writing the tables.
## Deleting the file excel/visit_all_sig-v202202.xlsx before writing the tables.
visit_all_saved <- save(list = "visit_all_table",
                        file = glue::glue("rda/visit_all_table-v{ver}.rda"))

visit_all_gluc_de <- all_pairwise(visit_glucantime, filter = TRUE, model_batch = "svaseq")
## Error in normalize_expt(input, filter = filter): object 'visit_glucantime' not found
visit_all_gluc_table <- combine_de_tables(
    visit_all_gluc_de,
    keepers = visit_contrasts,
    excel = glue::glue("excel/visit_all_gluc_de-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_all_gluc_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_all_gluc_de-v202202.xlsx before writing the tables.
## Error in combine_de_tables(visit_all_gluc_de, keepers = visit_contrasts, : object 'visit_all_gluc_de' not found
visit_all_gluc_saved <- save(list = "visit_all_gluc_table",
                             file = glue::glue("rda/visit_all_gluc_table-v{ver}.rda"))
## Error in save(list = "visit_all_gluc_table", file = glue::glue("rda/visit_all_gluc_table-v{ver}.rda")): object 'visit_all_gluc_table' not found

9.3.2 Biopsy samples

visit_biopsy_de <- all_pairwise(visit_biopsy, filter = TRUE, model_batch = "svaseq")
## Error in normalize_expt(input, filter = filter): object 'visit_biopsy' not found
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"))
## Error in combine_de_tables(visit_biopsy_de, keepers = visit_contrasts, : object 'visit_biopsy_de' not found
visit_biopsy_saved <- save(list = "visit_biopsy_table",
                           file = glue::glue("rda/visit_biopsy_table-v{ver}.rda"))
## Error in save(list = "visit_biopsy_table", file = glue::glue("rda/visit_biopsy_table-v{ver}.rda")): object 'visit_biopsy_table' not found
visit_biopsy_gluc_de <- all_pairwise(visit_biopsy_glucantime, filter = TRUE, model_batch = "svaseq")
## Error in normalize_expt(input, filter = filter): object 'visit_biopsy_glucantime' not found
visit_biopsy_gluc_table <- combine_de_tables(
    visit_biopsy_gluc_de,
    keepers = visit_contrasts,
    excel = glue::glue("excel/visit_biopsy_gluc_de-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_biopsy_gluc_sig-v{ver}.xlsx"))
## Error in combine_de_tables(visit_biopsy_gluc_de, keepers = visit_contrasts, : object 'visit_biopsy_gluc_de' not found
visit_biopsy_gluc_saved <- save(list = "visit_biopsy_gluc_table",
                                file = glue::glue("rda/visit_biopsy_gluc_table-v{ver}.rda"))
## Error in save(list = "visit_biopsy_gluc_table", file = glue::glue("rda/visit_biopsy_gluc_table-v{ver}.rda")): object 'visit_biopsy_gluc_table' not found

9.3.3 Monocyte samples

visit_monocyte_de <- all_pairwise(visit_monocyte, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 2022 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 (11032 remaining).
## batch_counts: Before batch/surrogate estimation, 2022 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 33432 entries are 0<x<1: 6%.
## Setting 982 low elements to zero.
## transform_counts: Found 982 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-v202202.xlsx before writing the tables.
## Deleting the file excel/visit_monocyte_sig-v202202.xlsx before writing the tables.
visit_monocyte_gluc_de <- all_pairwise(visit_monocyte_glucantime, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 2022 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 (11032 remaining).
## batch_counts: Before batch/surrogate estimation, 2022 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 33432 entries are 0<x<1: 6%.
## Setting 982 low elements to zero.
## transform_counts: Found 982 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_monocyte_gluc_table <- combine_de_tables(
    visit_monocyte_gluc_de,
    keepers = visit_contrasts,
    excel = glue::glue("excel/visit_monocyte_gluc_de-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_monocyte_gluc_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_monocyte_gluc_de-v202202.xlsx before writing the tables.
## Deleting the file excel/visit_monocyte_gluc_sig-v202202.xlsx before writing the tables.
visit_monocyte_gluc_saved <- save(list = "visit_monocyte_gluc_table",
                             file = glue::glue("rda/visit_monocyte_gluc_table-v{ver}.rda"))

9.3.4 Neutrophil samples

visit_neutrophil_de <- all_pairwise(visit_neutrophil, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 1373 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 (9192 remaining).
## batch_counts: Before batch/surrogate estimation, 1373 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 38536 entries are 0<x<1: 8%.
## Setting 865 low elements to zero.
## transform_counts: Found 865 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-v202202.xlsx before writing the tables.
## Deleting the file excel/visit_neutrophil_sig-v202202.xlsx before writing the tables.
visit_neutrophil_saved <- save(list = "visit_neutrophil_table",
                               file = glue::glue("rda/visit_neutrophil_table-v{ver}.rda"))

visit_neutrophil_gluc_de <- all_pairwise(visit_neutrophil_glucantime, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 1373 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 (9192 remaining).
## batch_counts: Before batch/surrogate estimation, 1373 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 38536 entries are 0<x<1: 8%.
## Setting 865 low elements to zero.
## transform_counts: Found 865 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_neutrophil_gluc_table <- combine_de_tables(
    visit_neutrophil_gluc_de,
    keepers = visit_contrasts,
    excel = glue::glue("excel/visit_neutrophil_gluc_de-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_neutrophil_gluc_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_neutrophil_gluc_de-v202202.xlsx before writing the tables.
## Deleting the file excel/visit_neutrophil_gluc_sig-v202202.xlsx before writing the tables.
visit_neutrophil_gluc_saved <- save(list = "visit_neutrophil_gluc_table",
                             file = glue::glue("rda/visit_neutrophil_gluc_table-v{ver}.rda"))

9.3.5 Eosinophil samples

visit_eosinophil_de <- all_pairwise(visit_eosinophil, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 729 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 (10679 remaining).
## batch_counts: Before batch/surrogate estimation, 729 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 18897 entries are 0<x<1: 6%.
## Setting 396 low elements to zero.
## transform_counts: Found 396 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"))
## Deleting the file excel/visit_eosinophil_de-v202202.xlsx before writing the tables.
## Deleting the file excel/visit_eosinophil_sig-v202202.xlsx before writing the tables.
visit_eosinophil_saved <- save(list = "visit_eosinophil_table",
                               file = glue::glue("rda/visit_eosinophil_table-v{ver}.rda"))

visit_eosinophil_gluc_de <- all_pairwise(visit_eosinophil_glucantime, filter = TRUE, model_batch = "svaseq")
## batch_counts: Before batch/surrogate estimation, 729 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 (10679 remaining).
## batch_counts: Before batch/surrogate estimation, 729 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 18897 entries are 0<x<1: 6%.
## Setting 396 low elements to zero.
## transform_counts: Found 396 values equal to 0, adding 1 to the matrix.
## Finished running DE analyses, collecting outputs.
## Comparing analyses.

visit_eosinophil_gluc_table <- combine_de_tables(
    visit_eosinophil_gluc_de,
    keepers = visit_contrasts,
    excel = glue::glue("excel/visit_eosinophil_gluc_de-v{ver}.xlsx"),
    sig_excel = glue::glue("excel/visit_eosinophil_gluc_sig-v{ver}.xlsx"))
## Deleting the file excel/visit_eosinophil_gluc_de-v202202.xlsx before writing the tables.
## Deleting the file excel/visit_eosinophil_gluc_sig-v202202.xlsx before writing the tables.
visit_eosinophil_gluc_saved <- save(list = "visit_eosinophil_gluc_table",
                             file = glue::glue("rda/visit_eosinophil_gluc_table-v{ver}.rda"))

10 Likelihood Ratio Testing (LRT)

10.1 Shared patterns across visits

clinical_filt <- normalize_expt(hs_clinical, filter = TRUE)
## Removing 5748 low-count genes (14193 remaining).
lrt_visit <- deseq_lrt(clinical_filt, transform = "vst", interaction = FALSE,
                       interactor_column = "visitnumber",
                       interest_column = "clinicaloutcome")
## converting counts to integer mode
## estimating size factors
## estimating dispersions
## gene-wise dispersion estimates
## mean-dispersion relationship
## final dispersion estimates
## fitting model and testing
## -- replacing outliers and refitting for 156 genes
## -- DESeq argument 'minReplicatesForReplace' = 7 
## -- original counts are preserved in counts(dds)
## estimating dispersions
## fitting model and testing
## A large number of genes was given-- please, make sure this is not an error. Normally, only DE genes will be useful for this function.
## Working with 5464 genes.
## Working with 5464 genes after filtering: minc > 3
## Joining, by = "merge"
## Joining, by = "merge"
## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.

summary(lrt_visit[["favorite_genes"]])
##     genes              cluster     
##  Length:5464        Min.   : 1.00  
##  Class :character   1st Qu.: 1.00  
##  Mode  :character   Median : 2.00  
##                     Mean   : 3.04  
##                     3rd Qu.: 4.00  
##                     Max.   :10.00
written <- write_xlsx(data=as.data.frame(lrt_visit[["deseq_table"]]),
                      excel=glue::glue("excel/lrt_clinical_visit-v{ver}.xlsx"))

10.2 Shared patterns across cell types

lrt_celltype_clinical_test <- deseq_lrt(nolost_filt, transform = "vst",
                                           interactor_column = "typeofcells",
                                           interest_column = "clinicaloutcome")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'pData': object 'nolost_filt' not found
summary(lrt_celltype_clinical_test[["favorite_genes"]])
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'summary': object 'lrt_celltype_clinical_test' not found
favorite_lrt_df <- merge(hs_annot, lrt_celltype_clinical_test[["favorite_genes"]],
                         all.y = TRUE, by = "row.names")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'y' in selecting a method for function 'merge': object 'lrt_celltype_clinical_test' not found
rownames(favorite_lrt_df) <- favorite_lrt_df[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'favorite_lrt_df' not found
favorite_lrt_df[["Row.names"]] <- NULL
## Error in favorite_lrt_df[["Row.names"]] <- NULL: object 'favorite_lrt_df' not found
written <- write_xlsx(data=favorite_lrt_df,
                      excel=glue::glue("excel/lrt_clinical_celltype_favorites-v{ver}.xlsx"))
## Error in write_xlsx(data = favorite_lrt_df, excel = glue::glue("excel/lrt_clinical_celltype_favorites-v{ver}.xlsx")): object 'favorite_lrt_df' not found
deseq_lrt_df <- merge(hs_annot, as.data.frame(lrt_celltype_clinical_test[["deseq_table"]]), all.y=TRUE,
                      by="row.names")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'y' in selecting a method for function 'merge': error in evaluating the argument 'x' in selecting a method for function 'as.data.frame': object 'lrt_celltype_clinical_test' not found
rownames(deseq_lrt_df) <- deseq_lrt_df[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'deseq_lrt_df' not found
deseq_lrt_df[["Row.names"]] <- NULL
## Error in deseq_lrt_df[["Row.names"]] <- NULL: object 'deseq_lrt_df' not found
written <- write_xlsx(data=deseq_lrt_df,
                      excel=glue::glue("excel/lrt_clinical_celltype-v{ver}.xlsx"))
## Error in write_xlsx(data = deseq_lrt_df, excel = glue::glue("excel/lrt_clinical_celltype-v{ver}.xlsx")): object 'deseq_lrt_df' not found
lrt_celltype_clinical_test$cluster_data$plot
## Error in eval(expr, envir, enclos): object 'lrt_celltype_clinical_test' not found

11 Gene Set Analyses

The gene sets we are most likely to consider are the results of the various preceding differential expression analyses.

11.1 GSEA

11.1.1 Cure/Fail groups

In the context of cure vs. fail, we have mixed and matched the data in quite a few different ways.

11.1.1.1 Cure/Fail, all samples

For the moment, let us assume that the default definition of ‘significant’ is sufficient for these analyses, with the knowledge that is not likely to remain true. For each of the differential expression analyses, I used the ‘sig_excel’ argument; this extracts by default the set of genes which are up/down by >= logFC 1.0 with an adjusted pvalue 0.05 as defined by deseq2.

The resulting data structures are organized as:

thing[[“significant”]][[“deseq”]][[ups"]][[contrast]]

In addition, we have a few ontology-esque tools available, so let us mix and match and see what pops out.

cf_all_up <- cf_clinical_tables[["significant"]][["deseq"]][["ups"]][["fail_vs_cure"]]
dim(cf_all_up)
## [1] 114  58
cf_all_down <- cf_clinical_tables[["significant"]][["deseq"]][["downs"]][["fail_vs_cure"]]
dim(cf_all_down)
## [1] 45 58
cf_all_up_gp <- simple_gprofiler(cf_all_up)
## Performing gProfiler GO search of 114 genes against hsapiens.
## GO search found 87 hits.
## Performing gProfiler KEGG search of 114 genes against hsapiens.
## KEGG search found 11 hits.
## Performing gProfiler REAC search of 114 genes against hsapiens.
## REAC search found 5 hits.
## Performing gProfiler MI search of 114 genes against hsapiens.
## MI search found 0 hits.
## Performing gProfiler TF search of 114 genes against hsapiens.
## TF search found 8 hits.
## Performing gProfiler CORUM search of 114 genes against hsapiens.
## CORUM search found 0 hits.
## Performing gProfiler HP search of 114 genes against hsapiens.
## HP search found 0 hits.
cf_all_up_gp[["pvalue_plots"]][["reactome_plot_over"]]

cf_all_up_gp[["pvalue_plots"]][["kegg_plot_over"]]

cf_all_up_gp[["pvalue_plots"]][["mfp_plot_over"]]
## NULL
cf_all_up_gp[["pvalue_plots"]][["bpp_plot_over"]]

cf_all_down_gp <- simple_gprofiler(cf_all_down)
## Performing gProfiler GO search of 45 genes against hsapiens.
## GO search found 5 hits.
## Performing gProfiler KEGG search of 45 genes against hsapiens.
## KEGG search found 4 hits.
## Performing gProfiler REAC search of 45 genes against hsapiens.
## REAC search found 0 hits.
## Performing gProfiler MI search of 45 genes against hsapiens.
## MI search found 0 hits.
## Performing gProfiler TF search of 45 genes against hsapiens.
## TF search found 4 hits.
## Performing gProfiler CORUM search of 45 genes against hsapiens.
## CORUM search found 4 hits.
## Performing gProfiler HP search of 45 genes against hsapiens.
## HP search found 18 hits.
cf_all_down_gp[["pvalue_plots"]][["reactome_plot_over"]]
## NULL
cf_all_down_gp[["pvalue_plots"]][["kegg_plot_over"]]

cf_all_down_gp[["pvalue_plots"]][["mfp_plot_over"]]
## NULL
cf_all_down_gp[["pvalue_plots"]][["bpp_plot_over"]]

11.1.1.2 Cure/Fail, Biopsies

There are no genes deemed significant in the biopsy comparisons of cure/fail. Oddly, when I looked manually, I thought I saw one candidate gene. In addition, when I stepped through the function manually I got the same gene…

11.1.1.3 Cure/Fail, Monocytes

Try again with monocytes.

cf_monocyte_up <- cf_monocyte_tables[["significant"]][["deseq"]][["ups"]][["fail_vs_cure"]]
dim(cf_monocyte_up)
## [1] 30 58
cf_monocyte_down <- cf_monocyte_tables[["significant"]][["deseq"]][["downs"]][["fail_vs_cure"]]
dim(cf_monocyte_down)
## [1] 22 58
cf_monocyte_up_gp <- simple_gprofiler(cf_monocyte_up)
## Performing gProfiler GO search of 30 genes against hsapiens.
## GO search found 14 hits.
## Performing gProfiler KEGG search of 30 genes against hsapiens.
## KEGG search found 3 hits.
## Performing gProfiler REAC search of 30 genes against hsapiens.
## REAC search found 7 hits.
## Performing gProfiler MI search of 30 genes against hsapiens.
## MI search found 0 hits.
## Performing gProfiler TF search of 30 genes against hsapiens.
## TF search found 2 hits.
## Performing gProfiler CORUM search of 30 genes against hsapiens.
## CORUM search found 0 hits.
## Performing gProfiler HP search of 30 genes against hsapiens.
## HP search found 2 hits.
cf_monocyte_up_gp[["pvalue_plots"]][["reactome_plot_over"]]

cf_monocyte_up_gp[["pvalue_plots"]][["kegg_plot_over"]]

cf_monocyte_up_gp[["pvalue_plots"]][["bpp_plot_over"]]

cf_monocyte_down_gp <- simple_gprofiler(cf_monocyte_down)
## Performing gProfiler GO search of 22 genes against hsapiens.
## GO search found 0 hits.
## Performing gProfiler KEGG search of 22 genes against hsapiens.
## KEGG search found 0 hits.
## Performing gProfiler REAC search of 22 genes against hsapiens.
## REAC search found 1 hits.
## Performing gProfiler MI search of 22 genes against hsapiens.
## MI search found 0 hits.
## Performing gProfiler TF search of 22 genes against hsapiens.
## TF search found 0 hits.
## Performing gProfiler CORUM search of 22 genes against hsapiens.
## CORUM search found 2 hits.
## Performing gProfiler HP search of 22 genes against hsapiens.
## HP search found 0 hits.
cf_monocyte_down_gp[["pvalue_plots"]][["reactome_plot_over"]]

cf_monocyte_down_gp[["pvalue_plots"]][["kegg_plot_over"]]
## NULL

11.1.1.4 Cure/Fail, Neutrophils

cf_neutrophil_up <- cf_neutrophil_tables[["significant"]][["deseq"]][["ups"]][["fail_vs_cure"]]
dim(cf_neutrophil_up)
## [1] 19 58
cf_neutrophil_down <- cf_neutrophil_tables[["significant"]][["deseq"]][["downs"]][["fail_vs_cure"]]
dim(cf_neutrophil_down)
## [1] 15 58
cf_neutrophil_up_gp <- simple_gprofiler(cf_neutrophil_up)
## Performing gProfiler GO search of 19 genes against hsapiens.
## GO search found 0 hits.
## Performing gProfiler KEGG search of 19 genes against hsapiens.
## KEGG search found 0 hits.
## Performing gProfiler REAC search of 19 genes against hsapiens.
## REAC search found 0 hits.
## Performing gProfiler MI search of 19 genes against hsapiens.
## MI search found 0 hits.
## Performing gProfiler TF search of 19 genes against hsapiens.
## TF search found 9 hits.
## Performing gProfiler CORUM search of 19 genes against hsapiens.
## CORUM search found 1 hits.
## Performing gProfiler HP search of 19 genes against hsapiens.
## HP search found 0 hits.
cf_neutrophil_down_gp <- simple_gprofiler(cf_neutrophil_down)
## Performing gProfiler GO search of 15 genes against hsapiens.
## GO search found 0 hits.
## Performing gProfiler KEGG search of 15 genes against hsapiens.
## KEGG search found 0 hits.
## Performing gProfiler REAC search of 15 genes against hsapiens.
## REAC search found 0 hits.
## Performing gProfiler MI search of 15 genes against hsapiens.
## MI search found 0 hits.
## Performing gProfiler TF search of 15 genes against hsapiens.
## TF search found 0 hits.
## Performing gProfiler CORUM search of 15 genes against hsapiens.
## CORUM search found 0 hits.
## Performing gProfiler HP search of 15 genes against hsapiens.
## HP search found 0 hits.
cf_neutrophil_down_gp[["pvalue_plots"]][["kegg_plot_over"]]
## NULL

11.1.1.5 Cure/Fail, Eosinophils

cf_eosinophil_up <- cf_eosinophil_tables[["significant"]][["deseq"]][["ups"]][["fail_vs_cure"]]
dim(cf_eosinophil_up)
## [1] 118  58
cf_eosinophil_down <- cf_eosinophil_tables[["significant"]][["deseq"]][["downs"]][["fail_vs_cure"]]
dim(cf_eosinophil_down)
## [1] 68 58
cf_eosinophil_up_gp <- simple_gprofiler(cf_eosinophil_up)
## Performing gProfiler GO search of 118 genes against hsapiens.
## GO search found 150 hits.
## Performing gProfiler KEGG search of 118 genes against hsapiens.
## KEGG search found 8 hits.
## Performing gProfiler REAC search of 118 genes against hsapiens.
## REAC search found 8 hits.
## Performing gProfiler MI search of 118 genes against hsapiens.
## MI search found 0 hits.
## Performing gProfiler TF search of 118 genes against hsapiens.
## TF search found 27 hits.
## Performing gProfiler CORUM search of 118 genes against hsapiens.
## CORUM search found 5 hits.
## Performing gProfiler HP search of 118 genes against hsapiens.
## HP search found 0 hits.
cf_eosinophil_up_gp[["pvalue_plots"]][["kegg_plot_over"]]

cf_eosinophil_up_gp[["pvalue_plots"]][["reactome_plot_over"]]

cf_eosinophil_up_gp[["pvalue_plots"]][["mfp_plot_over"]]

cf_eosinophil_up_gp[["pvalue_plots"]][["bpp_plot_over"]]

cf_eosinophil_down_gp <- simple_gprofiler(cf_eosinophil_down)
## Performing gProfiler GO search of 68 genes against hsapiens.
## GO search found 7 hits.
## Performing gProfiler KEGG search of 68 genes against hsapiens.
## KEGG search found 1 hits.
## Performing gProfiler REAC search of 68 genes against hsapiens.
## REAC search found 2 hits.
## Performing gProfiler MI search of 68 genes against hsapiens.
## MI search found 0 hits.
## Performing gProfiler TF search of 68 genes against hsapiens.
## TF search found 2 hits.
## Performing gProfiler CORUM search of 68 genes against hsapiens.
## CORUM search found 0 hits.
## Performing gProfiler HP search of 68 genes against hsapiens.
## HP search found 0 hits.
cf_eosinophil_down_gp[["pvalue_plots"]][["reactome_plot_over"]]

cf_eosinophil_down_gp[["pvalue_plots"]][["mfp_plot_over"]]

cf_eosinophil_down_gp[["pvalue_plots"]][["bpp_plot_over"]]

11.1.1.6 Clinical samples

cf_nobiopsy_up <- cf_nobiopsy_tables[["significant"]][["deseq"]][["ups"]][["fail_vs_cure"]]
dim(cf_nobiopsy_up)
## [1] 122  58
cf_nobiopsy_down <- cf_nobiopsy_tables[["significant"]][["deseq"]][["downs"]][["fail_vs_cure"]]
dim(cf_nobiopsy_down)
## [1] 79 58
cf_nobiopsy_up_gp <- simple_gprofiler(cf_nobiopsy_up)
## Performing gProfiler GO search of 122 genes against hsapiens.
## GO search found 163 hits.
## Performing gProfiler KEGG search of 122 genes against hsapiens.
## KEGG search found 13 hits.
## Performing gProfiler REAC search of 122 genes against hsapiens.
## REAC search found 5 hits.
## Performing gProfiler MI search of 122 genes against hsapiens.
## MI search found 0 hits.
## Performing gProfiler TF search of 122 genes against hsapiens.
## TF search found 6 hits.
## Performing gProfiler CORUM search of 122 genes against hsapiens.
## CORUM search found 0 hits.
## Performing gProfiler HP search of 122 genes against hsapiens.
## HP search found 0 hits.
cf_nobiopsy_up_gp[["pvalue_plots"]][["kegg_plot_over"]]

cf_nobiopsy_up_gp[["pvalue_plots"]][["reactome_plot_over"]]

cf_nobiopsy_up_gp[["pvalue_plots"]][["mfp_plot_over"]]

cf_nobiopsy_up_gp[["pvalue_plots"]][["bpp_plot_over"]]

cf_nobiopsy_down_gp <- simple_gprofiler(cf_nobiopsy_down)
## Performing gProfiler GO search of 79 genes against hsapiens.
## GO search found 1 hits.
## Performing gProfiler KEGG search of 79 genes against hsapiens.
## KEGG search found 2 hits.
## Performing gProfiler REAC search of 79 genes against hsapiens.
## REAC search found 0 hits.
## Performing gProfiler MI search of 79 genes against hsapiens.
## MI search found 0 hits.
## Performing gProfiler TF search of 79 genes against hsapiens.
## TF search found 0 hits.
## Performing gProfiler CORUM search of 79 genes against hsapiens.
## CORUM search found 0 hits.
## Performing gProfiler HP search of 79 genes against hsapiens.
## HP search found 0 hits.
cf_nobiopsy_down_gp[["pvalue_plots"]][["reactome_plot_over"]]
## NULL
cf_nobiopsy_down_gp[["pvalue_plots"]][["mfp_plot_over"]]
## NULL
cf_nobiopsy_down_gp[["pvalue_plots"]][["bpp_plot_over"]]
## NULL

11.1.2 Cell type groups

11.1.3 Visit groups

11.2 GSVA

11.2.1 Clinical samples

hs_celltype_gsva_c2 <- sm(simple_gsva(hs_valid))
hs_celltype_gsva_c2_sig <- sm(get_sig_gsva_categories(
    hs_celltype_gsva_c2,
    excel="excel/individual_celltypes_gsva_c2.xlsx"))
## broad_c7 <- GSEABase::getGmt("reference/msigdb/c7.all.v7.2.entrez.gmt",
##                              collectionType=GSEABase::BroadCollection(category="c7"),
##                              geneIdType=GSEABase::EntrezIdentifier())
## hs_celltype_gsva_c7 <- sm(simple_gsva(individual_celltypes, signatures=broad_c7,
##                                       msig_xml="reference/msigdb_v7.2.xml", cores=10))
hs_celltype_gsva_c7 <- simple_gsva(individual_celltypes,
                                   signatures="reference/msigdb/c7.all.v7.2.entrez.gmt",
                                   signature_category="c7",
                                   msig_xml="reference/msigdb_v7.2.xml",
                                   cores=10)
## Error in simple_gsva(individual_celltypes, signatures = "reference/msigdb/c7.all.v7.2.entrez.gmt", : object 'individual_celltypes' not found
hs_celltype_gsva_c7_sig <- sm(get_sig_gsva_categories(
    hs_celltype_gsva_c7,
    excel="excel/individual_celltypes_gsva_c7.xlsx"))
## Error in get_sig_gsva_categories(hs_celltype_gsva_c7, excel = "excel/individual_celltypes_gsva_c7.xlsx"): object 'hs_celltype_gsva_c7' not found
LS0tCnRpdGxlOiAiTC4gcGFuYW1lbnNpcyAyMDIyMDI6IFJlb3JnYW5pemluZyBUTVJDMyBBbmFseXNlcyIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogaHRtbF9kb2N1bWVudDoKICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgY29kZV9mb2xkaW5nOiBzaG93CiAgZmlnX2NhcHRpb246IHRydWUKICBmaWdfaGVpZ2h0OiA3CiAgZmlnX3dpZHRoOiA3CiAgaGlnaGxpZ2h0OiBkZWZhdWx0CiAga2VlcF9tZDogZmFsc2UKICBtb2RlOiBzZWxmY29udGFpbmVkCiAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgc2VsZl9jb250YWluZWQ6IHRydWUKICB0aGVtZTogcmVhZGFibGUKICB0b2M6IHRydWUKICB0b2NfZmxvYXQ6CiAgIGNvbGxhcHNlZDogZmFsc2UKICAgc21vb3RoX3Njcm9sbDogZmFsc2UKLS0tCgo8c3R5bGU+CiAgYm9keSAubWFpbi1jb250YWluZXIgewogICAgbWF4LXdpZHRoOiAxNjAwcHg7CiAgfQo8L3N0eWxlPgoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShocGdsdG9vbHMpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZm9yY2F0cykKdHQgPC0gc20oZGV2dG9vbHM6OmxvYWRfYWxsKCJ+L2hwZ2x0b29scyIpKQprbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgICB2ZXJib3NlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHdpZHRoPTkwLAogICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgZmlnLndpZHRoPTgsCiAgICAgICAgICAgICAgICAgICAgICBmaWcuaGVpZ2h0PTgsCiAgICAgICAgICAgICAgICAgICAgICBkcGk9OTYpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzPTQsCiAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWw9ImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZT0xMikpCnZlciA8LSAiMjAyMjAyIgpwcmV2aW91c19maWxlIDwtIHBhc3RlMCgiMDFfYW5ub3RhdGlvbl92IiwgdmVyLCAiLlJtZCIpCnJ1bmRhdGUgPC0gZm9ybWF0KFN5cy5EYXRlKCksIGZvcm1hdD0iJVklbSVkIikKCiMjdG1wIDwtIHRyeShzbShsb2FkbWUoZmlsZW5hbWU9Z3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSJcXC5yZGFcXC54eiIsIHg9cHJldmlvdXNfZmlsZSkpKSkKcm1kX2ZpbGUgPC0gInRtcmMzX3Jlb3JnYW5pemVkXzIwMjIwMi5SbWQiCnNhdmVmaWxlIDwtIGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iXFwucmRhXFwueHoiLCB4PXJtZF9maWxlKQpgYGAKCiMgSW50cm9kdWN0aW9uCgpUaGUgc2V0IG9mIGFuYWx5c2VzIHBlcmZvcm1lZCBpbiB0bXJjMyBzYW1wbGUgZXN0aW1hdGlvbiBoYXMgYmVjb21lCnVub3JnYW5pemVkIGFuZCBkaWZmaWN1bHQgdG8gZm9sbG93LiAgVGhpcyBpcyBpbnRlbmRlZCB0byBzdGFydCBhdCB0aGUKbGV2ZWwgb2YgYnJvYWQgb3JnYW5pemF0aW9uIGJlZm9yZSBzdGVwcGluZyBpbnRvIHRoZSBhbmFseXNlcy4KCkFzIG9mIDIwMjIwMjI0LCB0aGlzIGRvY3VtZW50IGlzIGF0dGVtcHRpbmcgdG8gc3luY2hyb25pemUgd2l0aCB0aGUKZ29vZ2xlIGRvYyBuYW1lZCAnVE1SQzNfQXVnMThfMjAyMScuICBJIGFtIGhvcGluZyB0aGVyZWZvcmUgdG8gaGF2ZQpibG9ja3MgbmFtZWQgYWNjb3JkaW5nIHRvIHRoZSBmaWd1cmVzL2V0YyBpbiB0aGF0IGRvY3VtZW50LgoKIyBHb2FscwoKVGhlc2Ugc2FtcGxlcyBhcmUgZnJvbSBwYXRpZW50cyB3aG8gZWl0aGVyIHN1Y2Nlc3NmdWxseSBjbGVhcmVkIGEKTGVpc2htYW5pYSBwYW5hbWVuc2lzIGluZmVjdGlvbiBmb2xsb3dpbmcgdHJlYXRtZW50LCBvciBkaWQgbm90LiAgVGhleQppbmNsdWRlIGJpb3BzaWVzIGZyb20gZWFjaCBwYXRpZW50IGFsb25nIHdpdGggcHVyaWZpY2F0aW9ucyBmb3IKTW9ub2N5dGVzLCBOZXV0cm9waGlscywgYW5kIEVvc2lub3BoaWxzLiAgV2hlbiBwb3NzaWJsZSwgdGhpcyBwcm9jZXNzCndhcyByZXBlYXRlZCBvdmVyIHRocmVlIHZpc2l0czsgYnV0IHNvbWUgcGF0aWVudHMgZGlkIG5vdCByZXR1cm4KZm9yIHRoZSBzZWNvbmQgb3IgdGhpcmQgdmlzaXQuCgpUaGUgb3Zlci1hcmNoaW5nIGdvYWwgaXMgdG8gbG9vayBmb3IgYXR0cmlidXRlcyhtb3N0IGxpa2VseSBnZW5lcykKd2hpY2ggZGlzdGluZ3Vpc2ggcGF0aWVudHMgd2hvIGRvIGFuZCBkbyBub3QgY3VyZSB0aGUgaW5mZWN0aW9uIGFmdGVyCnRyZWF0bWVudC4gIElmIHBvc3NpYmxlLCB0aGVzZSB3aWxsIGJlIGFwcGFyZW50IG9uIHRoZSBmaXJzdCB2aXNpdC4KCiMjIFJlbGV2YW50IE1ldGFkYXRhCgpUaGUgbWV0YWRhdGEgZmFjdG9ycyAoaW4gbm8gcGFydGljdWxhciBvcmRlcikgb2YgdGhlIGV4cGVyaW1lbnQgYXJlOgoKMS4gIFZpc2l0LiAgMSwgMiwgb3IgMy4KMi4gIFBhdGllbnQuCjMuICBDbGluaWNhbCBvdXRjb21lOiBjdXJlIG9yIGZhaWwuICBUaGlzIGluY2x1ZGVzIHRoZSBwb3B1bGF0aW9uIG9mCiAgICBwYXRpZW50cyB3aG8gZGlkIG5vdCByZXR1cm4gYW5kIGFyZSBsYWJlbGVkICdsb3N0Jy4gIFRoaXMgaXMsIGJ5CiAgICBkZWZpbml0aW9uLCBjb25mb3VuZGVkIHdpdGggcGF0aWVudC4KNC4gIERydWcgdHJlYXRtZW50LiAgTW9zdCBvZiB0aGUgcGF0aWVudHMgd2VyZSB0cmVhdGVkIHdpdGggYW4KICAgIGFudGltb25pYWwsIGJ1dCBhIGZldyB3ZXJlIHRyZWF0ZWQgd2l0aCBtaWx0ZWZvc2luZS4KNS4gIENlbGwgdHlwZSBvciBiaW9wc3kuCgpNZXRhZGF0YSB3YXMgYWxzbyBjb2xsZWN0ZWQgZm9yIHRoZSBwYXRpZW50cyBhbmQgdGhlcmUgYXJlIG1hbnkKZmFjdG9ycyB3aGljaCBoYXZlIHBvdGVudGlhbCB0byBhZmZlY3QgdGhlIG91dGNvbWUuICBUaGVzZSBhbmFseXNlcwp3aWxsIGdlbmVyYWxseSByZW1haW4gYWdub3N0aWMgZm9yIHRoZXNlIGZhY3RvcnMsIHdoaWNoIGluY2x1ZGUgKGFtb25nCm90aGVyIHRoaW5ncyk6CgoxLiAgc2V4CjIuICBldGhuaWNpdHkKNC4gIGFnZQo1LiAgdWxjZXIvbGVzaW9uIGF0dHJpYnV0ZXMgKGJ5IHZpc2l0KQo2LiAgYW1vdW50IG9mIHRpbWUgc3BlbnQgd2l0aCBpbmZlY3Rpb24KCiMjIExpYnJhcmllcywgc2VxdWVuY2luZywgbWFwcGluZywgcXVhbnRpZmljYXRpb24KClRoZSBzYW1wbGVzIHVzZWQgaW4gdGhlc2UgYW5hbHlzZXMgd2VyZSBhbGwgY29sbGVjdGVkLCBwdXJpZmllZCwgYW5kCmxpYnJhcmllcyBnZW5lcmF0ZWQgYnkgdGhlIHNjaWVudGlzdHMvZG9jdG9ycyBhdCBDSURFSU0uICBUaGUKc2VxdWVuY2luZyBsaWJyYXJpZXMgd2VyZSBnZW5lcmF0ZWQgdmlhIHRoZSBUcnVTZXEgbm9uLXN0cmFuZGVkCmxpYnJhcnkga2l0IGFuZCBzZXF1ZW5jZWQgZWl0aGVyIGF0IEpIVSBvciBVTUQ7IGVhcmxpZXIgc2FtcGxlcyB3ZXJlCnNpbmdsZS1lbmRlZCwgYnV0IG1vc3Qgd2VyZSBwYWlyZWQuCgpBbGwgc2FtcGxlcyB3ZXJlIHRyaW1tZWQgd2l0aCB0cmltb21hdGljIHVzaW5nIHRoZSBzYW1lIHNldCBvZgpwYXJhbWV0ZXJzLiAgQWxsIG1hcHBpbmcgd2FzIHBlcmZvcm1lZCB3aXRoIGhpc2F0MiB2ZXJzaW9uIDIuMi4xLgpRdWFudGlmaWNhdGlvbnMgd2VyZSBhbHNvIHBlcmZvcm1lZCB3aXRoIHNhbG1vbiB2ZXJzaW9uIDEuMi4wLiAgVGhlCnJlZmVyZW5jZSBnZW5vbWUgdXNlZCB3YXMgaGczOCAxMDAgKHJlbGVhc2VkIDIwMjAwNCkuICBXaGVuIHNhbXBsZXMKd2VyZSBtYXBwZWQgYWdhaW5zdCBMLnBhbmFtZW5zaXMsIHRoZSBUcmlUcnlwREIgdmVyc2lvbiAzNiByZWZlcmVuY2UKd2FzIHVzZWQuICBUaGUgc2V0IG9mIGFubm90YXRpb25zIHdlcmUgdGhlcmVmb3JlIGxpbWl0ZWQgdG8gZW5zZW1ibCdzCjIwMjAgcmVsZWFzZS4gIFRoZSBlYXJseSBzYW1wbGVzIHdlcmUgYWN0dWFsbHkgZmlyc3QgbWFwcGVkIHdpdGgKaGczOCA5MSBhbmQgbGF0ZXIgcmVkb25lLgoKIyMgVHlwZXMgb2YgYW5hbHlzZXMgaW5jbHVkZWQKClRoaXMgZG9jdW1lbnQgd2lsbCBsaW1pdCBpdHNlbGYgdG8gYSBzZXQgb2YgY2Fub25pY2FsIFJOQXNlcQphbmFseXNlcy4gIEl0IG11c3QgdGhlcmVmb3JlIGNyZWF0ZSBmaWxlcyBjb250YWluaW5nIHRoZSByYXcgZGF0YSB0bwpmYWNpbGl0YXRlIHNoYXJpbmcgdGhlIGRhdGEuICBJdCB3aWxsIHBsb3QgbWV0cmljcyBvZiB0aGUgZGF0YSB0bwpkZW1vbnN0cmF0ZSB0aGUgc2VxdWVuY2luZyBxdWFsaXR5IGFuZCBjbHVzdGVyaW5nIG9mIHRoZSBzYW1wbGVzIHVuZGVyCnRoZSB2YXJpb3VzIGNvbmRpdGlvbnMgZXhhbWluZWQgYW5kIG5vcm1hbGl6YXRpb25zIGVtcGxveWVkLiAgSXQgd2lsbApwZXJmb3JtIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2VzIGZvciB0aGUgbWV0YWRhdGEgZmFjdG9ycyBvZgppbnRlcmVzdCBhbG9uZ3NpZGUgbGlrZWxpaG9vZCByYXRpbyB0ZXN0cyBmb3IgZmFjdG9ycyBsaWtlIGNlbGx0eXBlCmFuZCB0aW1lLiAgR2l2ZW4gdGhlIHNldHMgb2Ygb3Zlci91bmRlciBleHByZXNzZWQgZ2VuZXMgb2JzZXJ2ZWQgaW4KdGhlIHZhcmlvdXMgREUgbWV0aG9kcywgaXQgd2lsbCBwZXJmb3JtIHRoZSBsaWtlbHkgZ2VuZSBzZXQgdGVzdHMgZm9yCm92ZXIgcmVwcmVzZW50ZWQgZ2VuZSBvbnRvbG9neSBncm91cHMsIHJlYWN0b21lLCBldGMuICBTaW11bHRhbmVvdXNseSwKdGhlIHJhdyBkYXRhIHdpbGwgYmUgcGFzc2VkIHRvIGdlbmUgc2V0IHZhcmlhbmNlIGFuYWx5c2VzIHRvIHNlZSBpZgp0aGVyZSBhcmUgZ3JvdXBzIG9mIGdlbmVzIG92ZXJyZXByZXNlbnRlZCBpbiBvdGhlciBleHBlcmltZW50cy4KCiMgTWV0YWRhdGEgY29sbGVjdGlvbgoKVGhlcmUgYXJlIHR3byBtZXRhZGF0YSBzb3VyY2VzOgoKMS4gIFRoZSBvbmxpbmUgc2FtcGxlIHNoZWV0LCB3aGljaCBJIHBlcmlvZGljYWxseSB1cGRhdGUgYW5kIGRvd25sb2FkCiAgICBpbnRvIHRoZSAnc2FtcGxlX3NoZWV0cy8nIGRpcmVjdG9yeS4KMi4gIFRoZSBjcmYgbWV0YWRhdGEsIGRlc2NyaWJpbmcgdGhlIGluZGl2aWR1YWwgcGF0aWVudHMuCgpgYGB7ciBtZXRhZGF0YV9zb3VyY2VzfQpzYW1wbGVzaGVldCA8LSAic2FtcGxlX3NoZWV0cy90bXJjM19zYW1wbGVzXzIwMjIwMi54bHN4IgpjcmZfbWV0YWRhdGEgPC0gInNhbXBsZV9zaGVldHMvMjAyMTA4MjVfRVhQX0VTUEVDSUFMX1RNUkMzX1ZFUlNJT05fMi54bHN4IgpgYGAKCiMgQW5ub3RhdGlvbiBDb2xsZWN0aW9uCgpUaGUgcHJpbWFyeSBhbm5vdGF0aW9uIHNvdXJjZXMgYXJlOgoKMS4gIEVuc2VtYmwncyBiaW9tYXJ0IGFyY2hpdmUgZnJvbSAyMDIwIGZvciBodW1hbiBhbm5vdGF0aW9ucy4KMi4gIFRoZSBUcmlUcnlwREIgcmVsZWFzZSAzNiBmb3IgcGFyYXNpdGUgYW5ub3RhdGlvbnMuCgpCb3RoIHByb3ZpZGUgR08gZGF0YS4gIFRoZXkgYWxzbyBwcm92aWRlIGhlbHBmdWwgbGlua3MgdG8gb3RoZXIgZGF0YQpzb3VyY2VzLiAgRm9yIHRoZSBtb21lbnQsIHdlIGFyZSBmb2N1c2luZyBvbiB0aGUgaHVtYW4gYW5ub3RhdGlvbnMuCgojIyBHZW5lIGFubm90YXRpb25zCgpUaGVzZSBhbmFseXNlcyBoYXZlIGZvY3VzZWQgb24gZ2VuZS1sZXZlbCBhYnVuZGFuY2VzL2RpZmZlcmVuY2VzLgpUaHVzLCB3aGVuIGh0c2VxLWNvdW50IHdhcyBpbnZva2VkIGFnYWluc3QgdGhlIGhpc2F0Mi1iYXNlZCBtYXBwaW5ncywKcGFyYW1ldGVycyB3ZXJlIGNob3NlbiB0byBjb3VudCBnZW5lcyByYXRoZXIgdGhhbiB0cmFuc2NyaXB0cy4KU2ltaWxhcmx5LCB3aGVuIHNhbG1vbiBjb3VudHMgd2VyZSB1c2VkIHZpYSB0eGltcG9ydCwgYSBtYXBwaW5nIG9mCmdlbmVzIHRvIHRyYW5zY3JpcHRzIHdhcyB1c2VkIHRvIGNvbGxhcHNlIHRoZSBtYXRyaXggdG8gZ2VuZS1sZXZlbAphYnVuZGFuY2VzLiAgVGhpcyBkZWNpc2lvbiBtYXkgYmUgcmV2aXNpdGVkLgoKYGBge3IgY29sbGVjdF9hbm5vdGF0aW9uc30KaHNfYW5ub3QgPC0gc20obG9hZF9iaW9tYXJ0X2Fubm90YXRpb25zKHllYXI9IjIwMjAiKSkKaHNfYW5ub3QgPC0gaHNfYW5ub3RbWyJhbm5vdGF0aW9uIl1dCmhzX2Fubm90W1sidHJhbnNjcmlwdCJdXSA8LSBwYXN0ZTAocm93bmFtZXMoaHNfYW5ub3QpLCAiLiIsIGhzX2Fubm90W1sidmVyc2lvbiJdXSkKcm93bmFtZXMoaHNfYW5ub3QpIDwtIG1ha2UubmFtZXMoaHNfYW5ub3RbWyJlbnNlbWJsX2dlbmVfaWQiXV0sIHVuaXF1ZT1UUlVFKQp0eF9nZW5lX21hcCA8LSBoc19hbm5vdFssIGMoInRyYW5zY3JpcHQiLCAiZW5zZW1ibF9nZW5lX2lkIildCnN1bW1hcnkoaHNfYW5ub3QpCmBgYAoKIyMgR2VuZSBvbnRvbG9neSBkYXRhCgpUaGUgc2V0IG9mIEdPIGNhdGVnb3JpZXMgaGFzIG5vdCBiZWVuIGxpbWl0ZWQgdG8gdGhlIDIwMjAgZGF0YSBhdCB0aGUKdGltZSBvZiB0aGlzIHdyaXRpbmcuCgpgYGB7ciBoc19nb30KaHNfZ28gPC0gc20obG9hZF9iaW9tYXJ0X2dvKClbWyJnbyJdXSkKaHNfbGVuZ3RoIDwtIGhzX2Fubm90WywgYygiZW5zZW1ibF9nZW5lX2lkIiwgImNkc19sZW5ndGgiKV0KY29sbmFtZXMoaHNfbGVuZ3RoKSA8LSBjKCJJRCIsICJsZW5ndGgiKQpgYGAKCiMgVGhlIGNvbXBsZXRlIHNldCBvZiBkYXRhCgpCZWZvcmUgd2UgZG8gYW55IG9mIHRoZSBmb2xsb3dpbmcgc3Vic2V0cy9hbmFseXNlcyBvZiB0aGUgZGF0YSwgd2UKbmVlZCB0byBjb2xsZWN0IGl0IGFsbCBpbiBvbmUgcGxhY2UuICBMZXQncyBkbyB0aGF0IGhlcmUgYW5kIG5hbWUgaXQKJ2hzX3ZhbGlkJyBtZWFuaW5nIGl0IGlzIHRoZSBzZXQgb2YgdmFsaWQgZGF0YSBmb3IgSG9tbyBzYXBpZW5zLgoKYGBge3IgYWxsX2RhdGF9CnNhbml0aXplX2NvbHVtbnMgPC0gYygidmlzaXRudW1iZXIiLCAiY2xpbmljYWxvdXRjb21lIiwgImRvbm9yIiwKICAgICAgICAgICAgICAgICAgICAgICJ0eXBlb2ZjZWxscyIsICJjbGluaWNhbHByZXNlbnRhdGlvbiIsICJkcnVnIiwKICAgICAgICAgICAgICAgICAgICAgICJjb25kaXRpb24iLCAiYmF0Y2giKQpoc19leHB0IDwtIGNyZWF0ZV9leHB0KHNhbXBsZXNoZWV0LAogICAgICAgICAgICAgICAgICAgICAgIGZpbGVfY29sdW1uPSJoZzM4MTAwaGlzYXRmaWxlIiwKICAgICAgICAgICAgICAgICAgICAgICBzYXZlZmlsZT1nbHVlOjpnbHVlKCJyZGEvaHNfZXhwdF9hbGwtdnt2ZXJ9LnJkYSIpLAogICAgICAgICAgICAgICAgICAgICAgIGdlbmVfaW5mbz1oc19hbm5vdCkgJT4lCiAgZXhjbHVkZV9nZW5lc19leHB0KGNvbHVtbj0iZ2VuZV9iaW90eXBlIiwgbWV0aG9kPSJrZWVwIiwKICAgICAgICAgICAgICAgICAgICAgcGF0dGVybj0icHJvdGVpbl9jb2RpbmciLCBtZXRhX2NvbHVtbj0ibmNybmFfbG9zdCIpICU+JQogIHNhbml0aXplX2V4cHRfbWV0YWRhdGEoY29sdW1ucz1zYW5pdGl6ZV9jb2x1bW5zKSAlPiUKICBzZXRfZXhwdF9mYWN0b3JzKGNvbHVtbnM9c2FuaXRpemVfY29sdW1ucywgY2xhc3M9ImZhY3RvciIpICU+JQogIHNldF9leHB0X2NvbmRpdGlvbnMoZmFjdD0iY2xpbmljYWxvdXRjb21lIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0PSJ2aXNpdG51bWJlciIpCgojIyBUaGUgZm9sbG93aW5nIHNob3VsZCBtYWtlIHZpc2l0IDEgdGhlIGxhcmdlc3QgaWYgb25lIHVzZXMgdGhhdCBjb2x1bW4gYXMgYSBzaXplIGZhY3RvciB3aGVuIHBsb3R0aW5nLgptZXRhIDwtIHBEYXRhKGhzX2V4cHQpICU+JQogIG11dGF0ZSh2aXNpdG51bWJlciA9IGZjdF9yZWxldmVsKHZpc2l0bnVtYmVyLCBjKCJub3RhcHBsaWNhYmxlIiwgIjMiLCAiMiIsICIxIikpKQpwRGF0YShoc19leHB0KSA8LSBtZXRhCmBgYAoKVGhlIGFib3ZlIGJsb2NrIGRvZXMgdGhlIGZvbGxvd2luZzoKCjEuICBDcmVhdGVzIGFuIGV4cHJlc3Npb25zZXQgdXNpbmcgdGhlICdoZzM4MTAwaGlzYXRmaWxlJyBjb2x1bW4gZnJvbQogICAgdGhlIG1vc3QgcmVjZW50bHkgZG93bmxvYWRlZCBzYW1wbGUgc2hlZXQgKHRoZSBjb2x1bW4ncyBuYW1lIGhhcwogICAgYW55IHB1Y3R1YXRpb24vc3BhY2VzL2NhcGl0YWxzL2V0YyByZW1vdmVkKSBhbmQgdGhlIHNldCBvZiBodW1hbgogICAgYW5ub3RhdGlvbnMgZG93bmxvYWRlZCBhYm92ZS4KMi4gIFRoaXMgZXhwcmVzc2lvbnNldCBpcyBwYXNzZWQgdG8gYSBmaWx0ZXIgd2hpY2ggcHVsbHMgb3V0IG9ubHkgdGhlCiAgICBwcm90ZWluX2NvZGluZyBnZW5lcyBhbmQgdXNlcyB0aGUgaW5mb3JtYXRpb24gZnJvbSB0aGF0IHByb2Nlc3MgdG8KICAgIGFkZCBhIG5ldyBtZXRhZGF0YSBjb2x1bW4gY2FsbGVkICduY3JuYV9sb3N0Jy4gVGh1cyBpdCBrZWVwcyBhCiAgICB0YWxseSBvZiB0aGUgbnVtYmVyIG9mIHJlYWRzIGxvc3QgaW4gdGhlIGZpbHRlciBhbmQgYWRkcyBpdCB0byB0aGUKICAgIHNhbXBsZSBzaGVldC4KMy4gIEl0IGlzIHBhc3NlZCBhZ2FpbiB0byBhIGZ1bmN0aW9uIHdoaWNoIHNhbml0aXplcyB0aGUgbWV0YWRhdGEKICAgICh0aGVyZSB3ZXJlIGEgY291cGxlIG9mIGVudHJpZXMgd2hpY2ggc2FpZCAnY3VyZScgaW5zdGVhZCBvZgogICAgJ0N1cmUnIG9yIHZpY2UgdmVyc2EpIGFuZCBzaW1pbGFybHkgcmVtb3ZlcyBwcm9ibGVtYXRpYwogICAgY2hhcmFjdGVycy4KNC4gIFBhc3NlZCB0byBhIGZ1bmN0aW9uIHdoaWNoIHNldHMgc29tZSBjb2x1bW5zIGV4cGxpY2l0bHkgdG8gZmFjdG9ycwogICAgaW5zdGVhZCBvZiBjaGFyYWN0ZXJzLgo1LiAgU2V0cyB0aGUgZXhwZXJpbWVudGFsICdjb25kaXRpb24nIHRvIHRoZSBmYWN0b3Igb2YgY3VyZSB2cy4gZmFpbC4KNi4gIFNldHMgdGhlIGV4cGVyaW1lbnRhbCAnYmF0Y2gnIHRvIHZpc2l0IG51bWJlci4KNy4gIFJlc2V0cyB0aGUgbGV2ZWxzIG9mIHRoZSB2aXNpdCBudW1iZXIgc28gdGhhdCB0aGUgc2FtcGxlcyB3aGljaAogICAgd2VyZSAnbm90YXBwbGljYWJsZScgYXJlIGxvZ2ljYWxseSBiZWZvcmUgdmlzaXQgMSB3aGljaCBpcyBiZWZvcmUKICAgIDIgYmVmb3JlIDMuCgojIyBBZGQgdGhlIENSRiBwYXRpZW50IG1ldGFkYXRhCgpMZXQgdXMgYWxzbyBtZXJnZSBpbiB0aGUgY2xpbmljaWFuJ3MgbWV0YWRhdGEuICBJIHdvcnJ5IGEgbGl0dGxlIHRoYXQKdGhpcyBtaWdodCBub3QgYmUgYWxsb3dlZCBmb3IgZGJHYXAgZGF0YSwgYnV0IGlmIGl0IGlzIGEgcHJvYmxlbSBJCnN1c3BlY3Qgd2UgY2FuIGp1c3QgcmVtb3ZlIHRoZSBiYWQgY29sdW1ucyBmcm9tIGl0LiAgQWxzbyBub3RlIHRoYXQgSQpyYXJlbHkgdXNlIHRoZSBqb2luIGZ1bmN0aW9uLCBidXQgaXQgaXMgc29tZXdoYXQgcmVxdWlyZWQgaGVyZSBiZWNhdXNlCkkgZG8gbm90IHdhbnQgdG8gcmlzayBzaHVmZmxpbmcgdGhlIG1ldGFkYXRhIHdoZW4gSSBhZGQgdGhlIG5ldwptZXRhZGF0YSwgd2hpY2ggY29tZXMgZnJvbSBhIHNwcmVhZHNoZWV0IHNvcnRlZCBieSBwYXRpZW50LCBub3QKc2FtcGxlLiAgSW4gZG9pbmcgdGhpcyBJIHRoZXJlZm9yZSBqdXN0IGNyZWF0ZWQgYSBuZXcgY29sdW1uICdqb2luJwp3aGljaCBjb250YWlucyB0aGUgc2hhcmVkIGluZm9ybWF0aW9uLCBlLmcuIHRoZSBwYXRpZW50IElECmZyb20gdGhlIGV4aXN0aW5nIG1ldGFkYXRhIGFuZCB0aGUgc2FtZSBJRCBmcm9tIHRoZSBDUkYgZmlsZSB3aGljaCBoYXMKYmVlbiBjb2VyY2VkIGludG8gbG93ZXJjYXNlLgoKYGBge3IgbWVyZ2VfY3JmfQpoc19wZCA8LSBwRGF0YShoc19leHB0KQpzdGFydCA8LSByb3duYW1lcyhoc19wZCkKaHNfY3JmIDwtIG9wZW54bHN4OjpyZWFkLnhsc3goY3JmX21ldGFkYXRhKQpoc19jcmZbWyJqb2luIl1dIDwtIHRvbG93ZXIoaHNfY3JmW1siY29kaWdvX3BhY2llbnRlIl1dKQpoc19wZFtbImpvaW4iXV0gPC0gaHNfcGRbWyJ0dWJlbGFiZWxvcmlnaW4iXV0KdGVzdCA8LSBwbHlyOjpqb2luKGhzX3BkLCBoc19jcmYsIGJ5PSJqb2luIikKdGVzdFtbImpvaW4iXV0gPC0gTlVMTApyb3duYW1lcyh0ZXN0KSA8LSByb3duYW1lcyhoc19wZCkKbmFfaWR4IDwtIGlzLm5hKHRlc3QpCnRlc3RbbmFfaWR4XSA8LSAidW5kZWZpbmVkIgpwRGF0YShoc19leHB0KSA8LSB0ZXN0CmBgYAoKVGhlIGFib3ZlIGJsb2NrIGRvZXMgdGhlIGZvbGxvd2luZzoKCjEuICBFeHRyYWN0cyB0aGUgbWV0YWRhdGEgYW5kIG1ha2VzIGEgY2hhcmFjdGVyIHZlY3RvciBvZiB0aGUgcm93bmFtZXMKICAgIChlLmcuIHRoZSBzYW1wbGUgSURzKS4KMi4gIENyZWF0ZXMgYSB0YWJsZSBvZiB0aGUgY2xpbmljYWwgbWV0YWRhdGEgZnJvbSB0aGUgZmlsZSBJCiAgICBkb3dubG9hZGVkLgozLiAgQ3JlYXRlcyBhICdqb2luJyBjb2x1bW4gZnJvbSBib3RoIHRoZSBleGlzdGluZyBtZXRhZGF0YSBhbmQgdGhlIGNsaW5pY2FsCiAgICBtZXRhZGF0YSB3aGljaCBpcyB0aGUgcGF0aWVudCBjb2RlLCB1c2luZyB3aGF0ZXZlciB0aGUgY29sdW1uCiAgICBuYW1lcyB3ZXJlIGluIGVhY2ggc2hlZXQuCjQuICBKb2lucyB0aGUgdHdvIHRhYmxlcyB1c2luZyB0aGlzIGluZm9ybWF0aW9uLiAgVGhlIGpvaW4gZnVuY3Rpb24gaXMKICAgIGV4cGxpY2l0bHkgdXNlZCBpbiB0aGlzIGNvbnRleHQgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIHJvdy1vcmRlciBvZgogICAgdGhlIGVudHJpZXMgZG9lcyBub3QgY2hhbmdlLgo1LiAgR2V0cyByaWQgb2YgYW55IGVudHJpZXMgaW4gdGhlIG5ldyB0YWJsZSB3aGljaCBhcmUgTkEuCjYuICBSZXBsYWNlcyB0aGUgbWV0YWRhdGEgb2YgdGhlIGV4cHJlc3Npb25zZXQgd2l0aCB0aGlzIG5ldywgbGFyZ2VyIHRhYmxlLgoKIyMgU2V0IG91ciBpbml0aWFsIGNvdmVyYWdlIGdvYWwKClRoZXJlIGV4aXN0cyBhIGJhc2VsaW5lIGNvdmVyYWdlIGJlbG93IHdoaWNoIHdlIGRvIG5vdCB3aXNoIHRvIGZhbGwuCk9uZSBsaWtlbHkgd2F5IHRvIGFwcHJvYWNoIGl0IGhldXJpc3RpY2FsbHkgaXMgdG8gYXNzdW1lIHdlIHNob3VsZApvYnNlcnZlIHNvbWUgbnVtYmVyIG9mIGdlbmVzLiAgV2l0aCB0aGF0IGluIG1pbmQsIEkgYXJiaXRyYXJpbHkgY2hvc2UKMTEsMDAwIG5vbi16ZXJvIGdlbmVzIGFzIHRoZSBtaW5pbXVtLgoKIyMgRGVmaW5lIGRlc2lyZWQgY29sb3JzIGZvciB0aGUgdmFyaW91cyBzdWJzZXRzCgpUaGVyZSBhcmUgbG90cyBvZiB3YXlzIHdoaWNoIHdlIHdpbGwgY2F0ZWdvcml6ZSB0aGUgZGF0YSwgaGVyZSBhcmUKc29tZSBwb3RlbnRpYWwgY29sb3IgY2hvaWNlcyBmb3IgdGhlbS4KCmBgYHtyIGNvbG9yX2Nob2ljZXN9CmNmX2NvbG9ycyA8LSBsaXN0KAogICAgImN1cmUiID0gIiM5OThFQzMiLAogICAgImZhaWx1cmUiID0gIiNGMUEzNDAiKQp0eXBlX3Zpc2l0X2NvbG9ycyA8LSBsaXN0KAogICAgIm1vbm9jeXRlc192MSIgPSAiI0REMUM3NyIsCiAgICAibW9ub2N5dGVzX3YyIiA9ICIjQzk5NEM3IiwKICAgICJtb25vY3l0ZXNfdjMiID0gIiNFN0UxRUYiLAogICAgImVvc2lub3BoaWxzX3YxIiA9ICIjMzFBMzU0IiwKICAgICJlb3Npbm9waGlsc192MiIgPSAiI0FEREQ4RSIsCiAgICAiZW9zaW5vcGhpbHNfdjMiID0gIiNGN0ZDRDkiLAogICAgIm5ldXRyb3BoaWxzX3YxIiA9ICIjMzE4MkJEIiwKICAgICJuZXV0cm9waGlsc192MiIgPSAiIzlFQ0FFMSIsCiAgICAibmV1dHJvcGhpbHNfdjMiID0gIiNERUVCRjciLAogICAgImJpb3BzeV92MSIgPSAiI0Q5NUYwRSIpCnR5cGVfY29sb3JzIDwtIGxpc3QoCiAgICAibW9ub2N5dGVzIiA9ICIjREQxQzc3IiwKICAgICJlb3Npbm9waGlscyIgPSAiIzMxQTM1NCIsCiAgICAibmV1dHJvcGhpbHMiID0gIiMzMTgyQkQiLAogICAgImJpb3BzeSIgPSAiI0Q5NUYwRSIpCnZpc2l0X2NvbG9ycyA8LSBsaXN0KCkKY2ZfdHlwZV9jb2xvcnMgPC0gbGlzdCgKICAgIGN1cmVfYmlvcHN5ID0gIiNEOTVGMEUiLAogICAgZmFpbHVyZV9iaW9wc3kgPSAiI0ZFQzQ0RiIsCiAgICBjdXJlX21vbm9jeXRlcyA9ICIjREQxQzc3IiwKICAgIGZhaWx1cmVfbW9ub2N5dGVzID0gIiNDOTk0QzciLAogICAgY3VyZV9lb3Npbm9waGlscyA9ICIjMzFBMzU0IiwKICAgIGZhaWx1cmVfZW9zaW5vcGhpbHMgPSAiI0FEREQ4RSIsCiAgICBjdXJlX25ldXRyb3BoaWxzID0gIiMzMTgyQkQiLAogICAgZmFpbHVyZV9uZXV0cm9waGlscyA9ICIjOUVDQUUxIikKYGBgCgojIyBEZWZpbmUgdGhlIHN0YXJ0aW5nIGRhdGEKClRoZSBmb2xsb3dpbmcgYmxvY2sgY29udGFpbnMgdGhlIHByaW1hcnkgZGF0YXNldCB3aGljaCBpcyB0aGUgcGFyZW50Cm9mIGV2ZXJ5dGhpbmcgd2hpY2ggZm9sbG93cy4KCmBgYHtyIGhzX3ZhbGlkfQpoc192YWxpZCA8LSBzdWJzZXRfZXhwdChoc19leHB0LCBub256ZXJvPTExMDAwKSAlPiUKICBzdWJzZXRfZXhwdChzdWJzZXQ9ImNsaW5pY2Fsb3V0Y29tZSE9J2xvc3QnIikgJT4lCiAgc3Vic2V0X2V4cHQoc3Vic2V0PSJjbGluaWNhbG91dGNvbWUhPSdub3RhcHBsaWNhYmxlJyIpICU+JQogIHN1YnNldF9leHB0KHN1YnNldD0iY2xpbmljYWxvdXRjb21lIT0nbnVsbCciKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY2ZfY29sb3JzKQpgYGAKCiMjIENvdW50IHVwIHNhbXBsZSB0eXBlcwoKSSByZWNlbnRseSBjb252aW5jZWQgbXlzZWxmIHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlCmRhdGEgd2hlbiBpdCBkb2VzIGFuZCBkb2VzIG5vdCBpbmNsdWRlIHRoZSBtaWx0ZWZvc2luZSB0cmVhdGVkCnBhdGllbnRzLgoKSG93ZXZlciwgd2hlbiBJIGFjdHVhbGx5IGNvdW50ZWQgdXAgdGhlIHNhbXBsZXMgYnkgYSBmZXcgY3JpdGVyaWEgSQppbW1lZGlhdGVseSByZWxpemVkIHRoaXMgaXMgc3B1cmlvdXMuCgpgYGB7ciB0YWJsZV92YWxpZH0KdGFibGUocERhdGEoaHNfdmFsaWQpJGRydWcpCnRhYmxlKHBEYXRhKGhzX3ZhbGlkKSRjbGluaWNhbG91dGNvbWUpCnRhYmxlKHBEYXRhKGhzX3ZhbGlkKSR0eXBlb2ZjZWxscykKdGFibGUocERhdGEoaHNfdmFsaWQpJHZpc2l0KQpzdW1tYXJ5KGFzLm51bWVyaWMocERhdGEoaHNfdmFsaWQpJGViX2xjX3RpZW1wb19ldm9sdWNpb24pKQpzdW1tYXJ5KGFzLm51bWVyaWMocERhdGEoaHNfdmFsaWQpJGViX2xjX3R0b19tY3RvX2dsdWNhbl9kb3NpcykpCnN1bW1hcnkoYXMubnVtZXJpYyhwRGF0YShoc192YWxpZCkkdjNfbGNfZWpleV9sZXNpb25fbW1fMSkpCnN1bW1hcnkoYXMubnVtZXJpYyhwRGF0YShoc192YWxpZCkkdjNfbGNfbGVzaW9uX2FyZWFfMSkpCnN1bW1hcnkoYXMubnVtZXJpYyhwRGF0YShoc192YWxpZCkkdjNfbGNfZWpleF91bGNlcmFfbW1fMSkpCnRhYmxlKHBEYXRhKGhzX3ZhbGlkKSRlYl9sY19zZXhvKQp0YWJsZShwRGF0YShoc192YWxpZCkkZWJfbGNfZXRuaWEpCnN1bW1hcnkoYXMubnVtZXJpYyhwRGF0YShoc192YWxpZCkkZWRhZCkpCnRhYmxlKHBEYXRhKGhzX3ZhbGlkKSRlYl9sY19wZXNvKQp0YWJsZShwRGF0YShoc192YWxpZCkkZWJfbGNfZXN0YXR1cmEpCmBgYAoKVGhlIGFib3ZlIGJsb2NrIGRvZXMgd2hhdCBpdCBzYXlzIG9uIHRoZSB0aW4sIHN1YnNldHMgdGhlIGRhdGEgdG8KZXhjbHVkZSBhbnkgc2FtcGxlIHdpdGggbGVzcyB0aGFuIDExLDAwMCBvYnNlcnZlZCBnZW5lcy4KCiMjIFNldCB1cCBpbml0aWFsIGRhdGEgc3Vic2V0cyBvZiBpbnRlcmVzdAoKT25lIG9mIHRoZSBmaXJzdCBnbG9iYWwgbWV0cmljcyBJIHdvdWxkIGxpa2UgdG8gcHJvdmlkZSBpcyB0aGUgc2V0IG9mCmxpYnJhcnkgc2l6ZXMuICBVbmZvcnR1bmF0ZWx5LCB3ZSBoYXZlIHRvbyBtYW55IHNhbXBsZXMgdG8gZml0IG9uIGEKc2NyZWVuIG5vdy4gIFRoZXJlZm9yZSwgSSBhbSBnb2luZyB0byBkbyBhbiBlYXJseSBzcGxpdCBvZiB0aGUgZGF0YSBieQpjZWxsIHR5cGUgaW4gdGhlIGhvcGVzIHRoYXQgZG9pbmcgc28gd2lsbCBtYWtlIGl0IHBvc3NpYmxlIHRvCnZpc3VhbGl6ZSB0aGUgbGlicmFyeSBzaXplcy9ub256ZXJvIGdlbmVzLgoKVGhlIGluaXRpYWwgZmFjdG9yIGZvciB0aGlzIGlzICd0eXBlb2ZjZWxscycuCgpgYGB7ciBpbml0aWFsX3N1YnNldHN9CnRhYmxlKHBEYXRhKGhzX3ZhbGlkKVtbInR5cGVvZmNlbGxzIl1dKQpiaW9wc3lfc2FtcGxlcyA8LSBzdWJzZXRfZXhwdChoc192YWxpZCwgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J2Jpb3BzeSciKQplb3Npbm9waGlsX3NhbXBsZXMgPC0gc3Vic2V0X2V4cHQoaHNfdmFsaWQsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdlb3Npbm9waGlscyciKQptb25vY3l0ZV9zYW1wbGVzIDwtIHN1YnNldF9leHB0KGhzX3ZhbGlkLCBzdWJzZXQ9InR5cGVvZmNlbGxzPT0nbW9ub2N5dGVzJyIpCm5ldXRyb3BoaWxfc2FtcGxlcyA8LSBzdWJzZXRfZXhwdChoc192YWxpZCwgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J25ldXRyb3BoaWxzJyIpCgojIyBDdXJyZW50bHksIHRoZXNlIGFyZSBub3QgdXNlZCwgYnV0IGluc3RlYWQgSSBwdWxsZWQgdGhlIHNhbXBsZXMgZnJvbSB0aGUgaHNfY2xpbmljYWwKIyMgd2hpY2ggbWVhbnMgdGhlIGJpb3BzaWVzIGFyZSBub3QgaW5jbHVkZWQuCnYxX3NhbXBsZXMgPC0gc3Vic2V0X2V4cHQoaHNfdmFsaWQsIHN1YnNldD0idmlzaXRudW1iZXI9PScxJyIpCnYxX2Jpb3BzaWVzIDwtIHN1YnNldF9leHB0KHYxX3NhbXBsZXMsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdiaW9wc3knIikKdjFfbW9ub2N5dGVzIDwtIHN1YnNldF9leHB0KHYxX3NhbXBsZXMsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdtb25vY3l0ZXMnIikKdjFfbmV1dHJvcGhpbHMgPC0gc3Vic2V0X2V4cHQodjFfc2FtcGxlcywgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J25ldXRyb3BoaWxzJyIpCnYxX2Vvc2lub3BoaWxzIDwtIHN1YnNldF9leHB0KHYxX3NhbXBsZXMsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdlb3Npbm9waGlscyciKQoKdjJfc2FtcGxlcyA8LSBzdWJzZXRfZXhwdChoc192YWxpZCwgc3Vic2V0PSJ2aXNpdG51bWJlcj09JzInIikKdjJfbW9ub2N5dGVzIDwtIHN1YnNldF9leHB0KHYyX3NhbXBsZXMsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdtb25vY3l0ZXMnIikKdjJfbmV1dHJvcGhpbHMgPC0gc3Vic2V0X2V4cHQodjJfc2FtcGxlcywgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J25ldXRyb3BoaWxzJyIpCnYyX2Vvc2lub3BoaWxzIDwtIHN1YnNldF9leHB0KHYyX3NhbXBsZXMsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdlb3Npbm9waGlscyciKQoKdjNfc2FtcGxlcyA8LSBzdWJzZXRfZXhwdChoc192YWxpZCwgc3Vic2V0PSJ2aXNpdG51bWJlcj09JzMnIikKdjNfbW9ub2N5dGVzIDwtIHN1YnNldF9leHB0KHYzX3NhbXBsZXMsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdtb25vY3l0ZXMnIikKdjNfbmV1dHJvcGhpbHMgPC0gc3Vic2V0X2V4cHQodjNfc2FtcGxlcywgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J25ldXRyb3BoaWxzJyIpCnYzX2Vvc2lub3BoaWxzIDwtIHN1YnNldF9leHB0KHYzX3NhbXBsZXMsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdlb3Npbm9waGlscyciKQpgYGAKClRoZSBhYm92ZSBibG9jayBkb2VzIGEgbG90IG9mIHN1YnNldCBvcGVyYXRpb25zIHRvIGNyZWF0ZSBzZXBhcmF0ZQpkYXRhIHN0cnVjdHVyZXMgb24gYSBwZXItY2VsbHR5cGUgYW5kIHBlci12aXNpdCBiYXNpcy4gIEVyZ28sIG91cgpsYXJnZSBkYXRhIHN0cnVjdHVyZSBpcyBub3cgam9pbmVkIGJ5IH4yMSBuZXcsIHNtYWxsZXIgZGF0YQpzdHJ1Y3R1cmVzLgoKIyBQYXJhc2l0ZSByZWFkcwoKTGV0IHVzIHNlZSBpZiB3ZSBjYW4gbWFrZSBhbiBleHByZXNzaW9uc2V0IG9mIHRoZSBwYXJhc2l0ZSByZWFkcyBpbgp0aGUgVE1SQzMgc2FtcGxlcyBhbmQgZGlzdGluZ3Vpc2ggYmV0d2VlbiB0aGUgZmF1eCBhbmQgcmVhbCByZWFkcy4KRS5nOiBBcmUgdGhlcmUgc2FtcGxlcyB3aGljaCBkZWZpbml0aXZlbHkgY29udGFpbiBwYXJhc2l0ZXM/CgpgYGB7ciBwYXJhc2l0ZV9leHB0fQpscF9leHB0IDwtIGNyZWF0ZV9leHB0KCJzYW1wbGVfc2hlZXRzL3RtcmMzX3NhbXBsZXNfMjAyMTEyMDcueGxzeCIsCiAgICAgICAgICAgICAgICAgICAgICAgZmlsZV9jb2x1bW49ImxwYW5hbWVuc2lzdjM2aGlzYXRmaWxlIiwgZ2VuZV9pbmZvID0gTlVMTCkgJT4lCiAgc3Vic2V0X2V4cHQoY292ZXJhZ2U9MTAwMCkgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0PSJ0eXBlb2ZjZWxscyIpCnZpc2l0X2ZhY3QgPC0gcERhdGEobHBfZXhwdClbWyJ2aXNpdG51bWJlciJdXQpiYXRjaF9uYSA8LSBpcy5uYSh2aXNpdF9mYWN0KQp2aXNpdF9mYWN0W2JhdGNoX25hXSA8LSAidW5kZWZpbmVkIgpscF9leHB0IDwtIHNldF9leHB0X2JhdGNoZXMobHBfZXhwdCwgZmFjdCA9IHZpc2l0X2ZhY3QpCgpscF9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGxwX2V4cHQsIGZpbHRlcj0ic2ltcGxlIiwgbm9ybT0icXVhbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQ9ImNwbSIsIHRyYW5zZm9ybT0ibG9nMiIpCnBsb3R0ZWQgPC0gcGxvdF9wY2EobHBfbm9ybSwgcGxvdF9sYWJlbHM9RkFMU0UpCnBsb3R0ZWQkcGxvdApwbG90dGVkXzNkIDwtIHBsb3RfM2RfcGNhKHBsb3R0ZWQpCmBgYAoKVGhlIGFib3ZlIGJsb2NrIGlzIHNpbWlsYXIgaW4gY29uY2VwdCB0byB0aGUgcHJldmlvdXMgZXhwcmVzc2lvbnNldApjcmVhdGlvbi4gIEl0IHVzZXMgYSBkaWZmZXJlbnQgY29sdW1uIGFuZCBjdXJyZW50bHkgaWdub3JlcyB0aGUgZ2VuZQphbm5vdGF0aW9ucy4gIEdpdmVuIHRoYXQgbWFueSBvZiB0aGUgc2FtcGxlcyBoYXZlIGVzc2VudGlhbGx5IDAgcmVhZHMsCkkgc2V0IGEgY3V0b2ZmIG9mIG9ubHkgMjAgb2JzZXJ2ZWQgZ2VuZXMuICBGaW5hbGx5LCBJIGRpZCBhIHF1aWNrIGFuZApkaXJ0eSBQQ0EgcGxvdCBvZiB0aGlzIHBlY3VsaWFyIGRhdGEgc3RydWN0dXJlIGluIHRoZSBob3BlcyBvZiBiZWluZwphYmxlIHRvICdzZWUnIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gd2hhdCBhcmUgYXNzdW1lZCB0byBiZSAncmVhbCcKc2FtcGxlcyB3aXRoIGEgc2lnbmlmaWNhbnQgbnVtYmVyIG9mICdyZWFsJyBwYXJhc2l0ZSByZWFkcyB2cy4gdGhvc2UKc2FtcGxlcyB3aGljaCBqdXN0IGhhdmUgYSBjb3VwbGUgb2YgcG90ZW50aWFsbHkgc3B1cmlvdXMgcmVhZHMuCgojIENvbnRyYXN0cyBhbmQgY29sb3JzIG9mIGludGVyZXN0CgpUaGlzIG1pZ2h0IGJlIGEgYml0IGVhcmx5IHRvIGNvbnNpZGVyIHRoZSBjb250cmFzdHMsIGJ1dCBJIHRoaW5rIHdlCnNob3VsZCBjb25zaWRlciB0aGlzIHF1ZXN0aW9uIGltbWVkaWF0ZWx5LiAgVGhlIG1haW4gdGhpbmcgd2Ugd2lsbCBiZQpjb21wYXJpbmcgaXMgb2YgY291cnNlIGN1cmUgdnMuIGZhaWw7IGJ1dCB3ZSBtYXkgYWxzbyBsb29rIGF0IHRoZQp2aXNpdHMgYW5kIGNvbXBhcmUgY2VsbCB0eXBlcy4KCmBgYHtyIGRlZmluZV9jb250cmFzdHN9CmNmX2NvbnRyYXN0cyA8LSBsaXN0KAogICAgImZhaWxfdnNfY3VyZSIgPSBjKCJmYWlsdXJlIiwgImN1cmUiKSkKdmlzaXRfY29udHJhc3RzIDwtIGxpc3QoCiAgICAidjJ2MSIgPSBjKCJjMiIsICJjMSIpLAogICAgInYzdjEiID0gYygiYzMiLCAiYzEiKSwKICAgICJ2M3YyIiA9IGMoImMzIiwgImMyIikpCnR5cGVfY29udHJhc3RzIDwtIGxpc3QoCiAgICAibW9ub19iaW9wc3kiID0gYygibW9ub2N5dGVzIiwgImJpb3BzeSIpLAogICAgImVvc2lub3BoaWxfYmlvcHN5IiA9IGMoImVvc2lub3BoaWxzIiwgImJpb3BzeSIpLAogICAgIm5ldXRyb3BoaWxfYmlvcHN5IiA9IGMoIm5ldXRyb3BoaWxzIiwgImJpb3BzeSIpKQpgYGAKCiMgRGlzdHJpYnV0aW9ucy9WaXN1YWxpemF0aW9ucyBvZiBpbnRlcmVzdAoKVGhlIHNldHMgb2Ygc2FtcGxlcyB1c2VkIHRvIHZpc3VhbGl6ZSB0aGUgZGF0YSB3aWxsIGFsc28gY29tcHJpc2UgdGhlCnNldHMgdXNlZCB3aGVuIGxhdGVyIHBlcmZvcm1pbmcgdGhlIHZhcmlvdXMgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24KYW5hbHlzZXMuCgojIyBHbG9iYWwgbWV0cmljcwoKU3RhcnQgb3V0IHdpdGggc29tZSBpbml0aWFsIG1ldHJpY3Mgb2YgYWxsIHNhbXBsZXMuICBUaGUgbW9zdCBvYnZpb3VzCmFyZSBwbG90cyBvZiB0aGUgbnVtYmVycyBvZiBub24temVybyBnZW5lcyBvYnNlcnZlZCwgaGVhdG1hcHMgc2hvd2luZwp0aGUgcmVsYXRpdmUgcmVsYXRpb25zaGlwcyBhbW9uZyB0aGUgc2FtcGxlcywgdGhlIHJlbGF0aXZlIGxpYnJhcnkKc2l6ZXMsIGFuZCBzb21lIFBDQS4gIEl0IG1pZ2h0IGJlIHNtYXJ0IHRvIHNwbGl0IHRoZSBsaWJyYXJ5IHNpemVzIHVwCmFjcm9zcyBzdWJzZXRzIG9mIHRoZSBkYXRhLCBiZWNhdXNlIHRoZXkgaGF2ZSBleHBhbmRlZCB0b28gZmFyIHRvIHNlZQp3ZWxsIG9uIGEgY29tcHV0ZXIgc2NyZWVuLgoKVGhlIG1vc3QgbGlrZWx5IGZhY3RvcnMgdG8gcXVlcnkgd2hlbiBjb25zaWRlcmluZyB0aGUgZW50aXJlIGRhdGFzZXQKYXJlIGN1cmUvZmFpbCwgdmlzaXQsIGFuZCBjZWxsIHR5cGUuICBUaGlzIGlzIHRoZSBsZXZlbCBhdCB3aGljaCB3ZQp3aWxsIGNob29zZSBzYW1wbGVzIHRvIGV4Y2x1ZGUgZnJvbSBmdXR1cmUgYW5hbHlzZXMuCgpgYGB7ciBnbG9iYWxfZGlzdHJpYnV0aW9uc30KcGxvdF9sZWdlbmQoYmlvcHN5X3NhbXBsZXMpJHBsb3QKcGxvdF9saWJzaXplKGJpb3BzeV9zYW1wbGVzKSRwbG90CnBsb3Rfbm9uemVybyhiaW9wc3lfc2FtcGxlcykkcGxvdAojIyBNaW5pbXVtIG51bWJlciBvZiBiaW9wc3kgZ2VuZXM6IH4gMTQsMDAwCgpwbG90X2xpYnNpemUoZW9zaW5vcGhpbF9zYW1wbGVzKSRwbG90CnBsb3Rfbm9uemVybyhlb3Npbm9waGlsX3NhbXBsZXMpJHBsb3QKIyMgTWluaW11bSBudW1iZXIgb2YgZW9zaW5vcGhpbCBnZW5lczogfiAxMyw1MDAKCnBsb3RfbGlic2l6ZShtb25vY3l0ZV9zYW1wbGVzKSRwbG90CnBsb3Rfbm9uemVybyhtb25vY3l0ZV9zYW1wbGVzKSRwbG90CiMjIE1pbmltdW0gbnVtYmVyIG9mIG1vbm9jeXRlIGdlbmVzOiB+IDcsNTAwIGJlZm9yZSBzZXR0aW5nIHRoZSBtaW5pbXVtLgoKcGxvdF9saWJzaXplKG5ldXRyb3BoaWxfc2FtcGxlcykkcGxvdApwbG90X25vbnplcm8obmV1dHJvcGhpbF9zYW1wbGVzKSRwbG90CiMjIE1pbmltdW0gbnVtYmVyIG9mIG5ldXRyb3BoaWwgZ2VuZXM6IH4gMTAsMDAwIGJlZm9yZSBzZXR0aW5nIG1pbmltdW0gY292ZXJhZ2UuCmBgYAoKVGhlIGFib3ZlIGJsb2NrIGp1c3QgcmVwZWF0cyB0aGUgc2FtZSB0d28gcGxvdHMgb24gYSBwZXItY2VsbHR5cGUKYmFzaXM6IHRoZSBudW1iZXIgb2YgcmVhZHMgb2JzZXJ2ZWQgLyBzYW1wbGUgYW5kIGEgcGxvdCBvZiBvYnNlcnZlZApnZW5lcyB3aXRoIHJlc3BlY3QgdG8gY292ZXJhZ2UuICBJIG1hZGUgc29tZSBjb21tZW50cyB3aXRoIG15Cm9ic2VydmF0aW9ucyBhYm91dCB0aGUgbnVtYmVyIG9mIGdlbmVzLgoKIyMgR2xvYmFsIFBDQQoKTm93IHRoYXQgdGhvc2UgJ2dsb2JhbCcgbWV0cmljcyBhcmUgb3V0IG9mIHRoZSB3YXksIGxldHMgbG9vayBhdCBzb21lCmdsb2JhbCBtZXRyaWNzIG9mIHRoZSBkYXRhIGZvbGxvd2luZyBub3JtYWxpemF0aW9uOyB0aGUgbW9zdCBsaWtlbHkKcGxvdHMgYXJlIG9mIGNvdXJzZSBQQ0EgYnV0IGFsc28gYSBjb3VwbGUgb2YgaGVhdG1hcHMuCgojIyMgRmlndXJlIDEKCkluIHRoZSBnb29nbGUgZG9jIFRNUkMzX0F1ZzE4XzIwMjEsIHRoZXJlIGlzIGFuIGV4YW1wbGUgb2YgYW4gaW1hZ2UKZm9yIHRoZSBmaXJzdCBmaWd1cmU6CgoiVHJhbnNjcmlwdG9taWMgcHJvZmlsZXMgb2YgcHJpbWFyeSBpbm5hdGUgY2VsbHMgb2YgQ0wgcGF0aWVudHMgc2hvdwp1bmlxdWUgdHJhbnNjcmlwdGlvbmFsIHNpZ25hdHVyZXMgLSBSZW1vdmUgUEJNQ3MgYW5kIE0wLCBtYXliZQpiaW9wc2llcyBhcyB3ZWxsIChidXQgUmVtb3ZlIFdUIHNhbXBsZXMpIgoKV2hpbGUgd2Ugd2VyZSB0YWxraW5nIGluIGEgbWVldGluZyBob3dldmVyLCBpdCBzb3VuZGVkIGxpa2UgdGhlcmUgd2FzCnNvbWUgZGVzaXJlIHRvIGtlZXAgYWxsIGNlbGwgdHlwZXMuICBUaGVyZWZvcmUgdGhlIGZvbGxvd2luZyBibG9jawp3aWxsIGhhdmUgb25lIGltYWdlIHdpdGggZXZlcnl0aGluZyBhbmQgb25lIGZvbGxvd2luZyB0aGUgYWJvdmUuCgpgYGB7ciBnbG9iYWxfcGNhfQp0eXBlX3ZhbGlkIDwtIHNldF9leHB0X2NvbmRpdGlvbnMoaHNfdmFsaWQsIGZhY3Q9InR5cGVvZmNlbGxzIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0PSJjbGluaWNhbG91dGNvbWUiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnModHlwZV9jb2xvcnMpCgphbGxfbm9ybSA8LSBzbShub3JtYWxpemVfZXhwdCh0eXBlX3ZhbGlkLCB0cmFuc2Zvcm09ImxvZzIiLCBub3JtPSJxdWFudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQ9ImNwbSIsIGZpbHRlcj1UUlVFKSkKCmFsbF9wY2EgPC0gcGxvdF9wY2EoYWxsX25vcm0sIHBsb3RfbGFiZWxzPUZBTFNFLAogICAgICAgICAgICAgICAgICAgIHBsb3RfdGl0bGU9IlBDQSAtIENlbGwgdHlwZSIsIHNpemVfY29sdW1uPSJ2aXNpdG51bWJlciIpCnBwKGZpbGU9Z2x1ZSgiaW1hZ2VzL3RtcmMzX3BjYV9ub2xhYmVscy12e3Zlcn0ucG5nIiksIGltYWdlPWFsbF9wY2EkcGxvdCkKYWxsX3BjYV9ub3NpemUgPC0gcGxvdF9wY2EoYWxsX25vcm0sIHBsb3RfbGFiZWxzPUZBTFNFKQphbGxfcGNhX25vc2l6ZSRwbG90Cgp3cml0ZS5jc3YoYWxsX3BjYSR0YWJsZSwgZmlsZT0iY29vcmRzL2hzX2Rvbm9yX3BjYV9jb29yZHMuY3N2IikKYWxsX2NmX25vcm0gPC0gc2V0X2V4cHRfYmF0Y2hlcyhhbGxfbm9ybSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWN0PSJ2aXNpdG51bWJlciIpCnBwKGZpbGU9Z2x1ZSgiaW1hZ2VzL3RtcmMzX2NvcmhlYXRfY2Ytdnt2ZXJ9LnBuZyIpLAogICBpbWFnZT1wbG90X2NvcmhlYXQoYWxsX2NmX25vcm0sIHBsb3RfdGl0bGU9IkhlaXJhcmNoaWNhbCBjbHVzdGVyaW5nOgogICAgICAgICBjZWxsIHR5cGVzIikkcGxvdCkKCnBwKGZpbGU9Z2x1ZSgiaW1hZ2VzL3RtcmMzX2Rpc2hlYXRfY2Ytdnt2ZXJ9LnBuZyIpLAogICBpbWFnZT1wbG90X2Rpc2hlYXQoYWxsX2NmX25vcm0sIHBsb3RfdGl0bGU9IkhlaXJhcmNoaWNhbCBjbHVzdGVyaW5nOgogICAgICAgICBjZWxsIHR5cGVzIikkcGxvdCkKYWxsX2NmX2Rpc2hlYXQgPC0gcGxvdF9kaXNoZWF0KGFsbF9jZl9ub3JtKQphbGxfY2ZfZGlzaGVhdCRwbG90CmBgYAoKIyMgRmlndXJlIDFCOiBUcmFuc2NyaXB0b21pYyBwcm9maWxlcyBvZiBwcmltYXJ5IGlubmF0ZQoKVGhlIGJpZ2dlc3QgY2F2ZWF0IGZvciB0aGlzIGlzIHRvIGVuc3VyZSB0aGF0IHRoZXJlIGFyZSBubyBXZWxsY29tZQpUcnVzdCBzYW1wbGVzLgoKQSBwb3RlbnRpYWwgZmlndXJlIGxlZ2VuZCBmb3IgdGhlIGZvbGxvd2luZyBpbWFnZXMgbWlnaHQgaW5jbHVkZToKClRoZSBvYnNlcnZlZCBjb3VudHMgcGVyIGdlbmUgZm9yIGFsbCBvZiB0aGUgY2xpbmljYWwgc2FtcGxlcyB3ZXJlCmZpbHRlcmVkLCBsb2cgdHJhbnNmb3JtZWQsIGNwbSBjb252ZXJ0ZWQsIGFuZCBxdWFudGlsZSBub3JtYWxpemVkLgpUaGUgY29sb3JzIHdlcmUgZGVmaW5lZCBieSBjZWxsIHR5cGVzIGFuZCBzaGFwZXMgYnkgcGF0aWVudCB2aXNpdC4KV2hlbiB0aGUgZmlyc3QgdHdvIHByaW5jaXBsZSBjb21wb25lbnRzIHdlcmUgcGxvdHRlZCwgY2x1c3RlcmluZyB3YXMKb2JzZXJ2ZWQgYnkgY2VsbCB0eXBlLiAgVGhlIGJpb3BzeSBzYW1wbGVzIHdlcmUgc2lnbmlmaWNhbnRseQpkaWZmZXJlbnQgZnJvbSB0aGUgaW5uYXRlIGltbXVuZSBjZWxsIHR5cGVzLgoKYGBge3IgZmlnMWJfdHJhbnNjcmlwdG9taWNfcHJvZmlsZXN9CmZpZzF2Ml9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHR5cGVfdmFsaWQsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnZlcnQ9ImNwbSIsIG5vcm09InF1YW50IiwgZmlsdGVyPVRSVUUpCmZpZzF2Ml9wY2EgPC0gcGxvdF9wY2EoZmlnMXYyX25vcm0sIGNpcz1GQUxTRSkKcHAoZmlsZT1nbHVlKCJpbWFnZXMvdG1yYzNfZmlnMXYyLnBuZyIpLCBpbWFnZT1maWcxdjJfcGNhJHBsb3QpCgpmaWcxdjNfc2FtcGxlcyA8LSBzdWJzZXRfZXhwdCh0eXBlX3ZhbGlkLCBzdWJzZXQ9ImNvbmRpdGlvbiE9J2Jpb3BzeSciKQpmaWcxdjNfbm9ybSA8LSBub3JtYWxpemVfZXhwdChmaWcxdjNfc2FtcGxlcywgdHJhbnNmb3JtPSJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydD0iY3BtIiwgbm9ybT0icXVhbnQiLCBmaWx0ZXI9VFJVRSkKZmlnMXYzX3BjYSA8LSBwbG90X3BjYShmaWcxdjNfbm9ybSwgY2lzPUZBTFNFKQpwcChmaWxlPSJpbWFnZXMvdG1yYzNfZmlnMXYzLnBuZyIsIGltYWdlPWZpZzF2M19wY2EkcGxvdCkKYGBgCgpDb250aW51ZSBsb29raW5nLCBidXQgc3dpdGNoIHRoZSBjb25kaXRpb25zL2NvbG9ycyBzbyB0aGF0IHRoZQpjbGluaWNhbCBvdXRjb21lIGJlY29tZXMgdGhlIGZvY3VzIGFuZCBnZXQgcmlkIG9mIGEgZmV3IHNhbXBsZXMgd2hpY2gKYXJlIG5vdCBhY3R1YWxseSBhIHBhcnQgb2YgdGhlIFRNUkMzIGZvY3VzIChlLmcuIHRoZSBQQk1DIGFuZAptYWNyb3BoYWdlIHNhbXBsZXMsIHdoaWNoIGFyZSBhbGwgZnJvbSB0aGUgV2VsbGNvbWUgVHJ1c3QpLgoKIyMjIENsaW5pY2FsbHkgcmVsZXZhbnQgc2FtcGxlcwoKSW5jbHVkZWQgaW4gdGhpcyBncm91cCB3aWxsIGJlIHRoZSBzYW1wbGVzIGZyb20gcGF0aWVudHMgd2hvIHdlcmUgbG9zdC4KCiMjIyMgUmVtb3ZlIHRoZSBsb3N0IHNhbXBsZXMKCkluIG91ciAyMDIyMDIxOCBtZWV0aW5nLCBpdCB3YXMgZGVjaWRlZCB0aGF0IHdlIHdvdWxkIGZvY3VzIGV4cGxpY2l0bHkKb24gdGhlIGN1cmUgYW5kIGZhaWwgc2FtcGxlcywgaWdub3JpbmcgbG9zdC9OQS9udWxsIHNhbXBsZXMuCgpUaHVzIEkgYW0gYWRkaW5nIGV4cGxpY2l0IGZpbHRlcnMgcmlnaHQgYXQgdGhlIHRvcCB0byBleGNsdWRlIHRoZW0uCgpgYGB7ciBjbGluaWNhbF9oc30KaHNfY2xpbmljYWwgPC0gaHNfdmFsaWQgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0PSJjbGluaWNhbG91dGNvbWUiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3Q9InR5cGVvZmNlbGxzIikgJT4lCiAgc2V0X2V4cHRfY29sb3JzKGNmX2NvbG9ycykKCmhzX2NsaW5pY2FsX25vYmlvcCA8LSBzdWJzZXRfZXhwdChoc19jbGluaWNhbCwgc3Vic2V0PSJ0eXBlb2ZjZWxscyE9J2Jpb3BzeSciKQpgYGAKCiMjIyBQbG90IHRoZSBjbGluaWNhbCBzYW1wbGVzCgpMZXQgdXMgcmVjb2xvciB0aGUgc2FtZSBwbG90IGJ5IGN1cmUvZmFpbCBmb2xsb3dlZCBieSBhIGNvbmNhdGVuYXRpb24Kb2YgdGhlIGNlbGwgdHlwZSBhbmQgY3VyZS9mYWlsLiAgSW4gdGhlIGZvbGxvd2luZyBibG9jaywgdGhlIGNsaW5pY2FsCnNhbXBsZXMgYXJlIHBsb3R0ZWQgb25jZSB3aXRoIHRoZSBtb3N0IGNvbW1vbiBub3JtYWxpemF0aW9uCihsb2csY3BtLHF1YW50LGZpbHRlcmVkKSBtZXRob2QgZm9sbG93ZWQgYnkgYSBwbG90IG9mIHRoZSBkYXRhIHVzaW5nCnN2YXNlcSBhZGp1c3RlZCB2YWx1ZXMgYW5kIHdpdGhvdXQgcXVhbnRpbGUgbm9ybWFsaXphdGlvbi4KClRodXMsIHRoZSBmb2xsb3dpbmcgYmxvY2sgc3dpdGNoZXMgdGhlIGNvbG9ycyBvZiB0aGUgZ3JvdXBzIHRvIHRoZSBjbGluaWNhbApzdGF0ZSAoY3VyZS9mYWlsKSBhbmQgc2hhcGVzIGJ5IGNlbGwgdHlwZS4KCmBgYHtyIGhzX2NsaW5pY2FsX3Bsb3R9CmhzX2NsaW5pY2FsX25vcm0gPC0gc20obm9ybWFsaXplX2V4cHQoaHNfY2xpbmljYWwsIGZpbHRlcj0ic2ltcGxlIiwgdHJhbnNmb3JtPSJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtPSJxdWFudCIsIGNvbnZlcnQ9ImNwbSIpKQpjbGluaWNhbF9wY2EgPC0gcGxvdF9wY2EoaHNfY2xpbmljYWxfbm9ybSwgcGxvdF9sYWJlbHM9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBjaXM9TlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3RfdGl0bGU9IlBDQSAtIGNsaW5pY2FsIHNhbXBsZXMiKQpjbGluaWNhbF9wY2EkcGxvdApwcChmaWxlPWdsdWUoImltYWdlcy9hbGxfY2xpbmljYWxfbm9iYXRjaF9wY2Etdnt2ZXJ9LnBuZyIpLAogICBpbWFnZT1jbGluaWNhbF9wY2EkcGxvdCwgaGVpZ2h0PTgsIHdpZHRoPTE2KQoKaHNfY2xpbmljYWxfbmIgPC0gbm9ybWFsaXplX2V4cHQoaHNfY2xpbmljYWwsIGZpbHRlcj0ic2ltcGxlIiwgdHJhbnNmb3JtPSJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2g9InN2YXNlcSIsIGNvbnZlcnQ9ImNwbSIpCmhzX2NsaW5pY2FsX25iX3BjYSA8LSBwbG90X3BjYShoc19jbGluaWNhbF9uYikKaHNfY2xpbmljYWxfbmJfcGNhJHBsb3QKcHAoZmlsZT1nbHVlKCJpbWFnZXMvYWxsX2NsaW5pY2FsX3N2YXNlcWJhdGNoX3BjYS12e3Zlcn0ucG5nIiksCiAgIGltYWdlPWhzX2NsaW5pY2FsX25iX3BjYSRwbG90LCBoZWlnaHQ9Niwgd2lkdGg9OCkKCnRhYmxlKHBEYXRhKGhzX2NsaW5pY2FsKVtbImNvbmRpdGlvbiJdXSkKdGVzdCA8LSBwY2FfaW5mb3JtYXRpb24oCiAgICBoc19jbGluaWNhbF9ub3JtLCBwbG90X3BjYXM9VFJVRSwKICAgIGV4cHRfZmFjdG9ycz1jKCJ2aXNpdG51bWJlciIsICJ0eXBlb2ZjZWxscyIsICJjbGluaWNhbG91dGNvbWUiLCAiZWJfbGNfZXN0YXR1cmEiLCAiZHJ1ZyIpKQpgYGAKCiMjIyBDb25jYXRlbmF0ZSBjdXJlL2ZhaWwgYW5kIGNlbGwgdHlwZQoKSW4gdGhlIGZvbGxvd2luZyBibG9jayB0aGUgZXhwZXJpbWVudGFsIGNvbmRpdGlvbiB3YXMgcmVzZXQgdG8gdGhlCmNvbmNhdGVuYXRpb24gb2YgY2xpbmljYWwgb3V0Y29tZSBhbmQgdHlwZSBvZiBjZWxscy4gIFRoZXJlIGFyZSBhbgppbnN1ZmZpY2llbnQgbnVtYmVyIG9mIGJpb3BzeSBzYW1wbGVzIGZvciB0aGVtIHRvIGJlIHVzZWZ1bCBpbiB0aGlzCnZpc3VhbGl6YXRpb24sIHNvIHRoZXkgYXJlIGlnbm9yZWQuCgpgYGB7ciBjZl9hbmRfdHlwZX0KbmV3X2ZhY3QgPC0gZmFjdG9yKAogICAgcGFzdGUwKHBEYXRhKGhzX2NsaW5pY2FsKVtbImNvbmRpdGlvbiJdXSwgIl8iLAogICAgICAgICAgIHBEYXRhKGhzX2NsaW5pY2FsKVtbImJhdGNoIl1dKSwKICAgIGxldmVscz1jKCJjdXJlX2Jpb3BzeSIsICJmYWlsdXJlX2Jpb3BzeSIsICJjdXJlX2Vvc2lub3BoaWxzIiwgImZhaWx1cmVfZW9zaW5vcGhpbHMiLAogICAgICAgICAgICAgImN1cmVfbW9ub2N5dGVzIiwgImZhaWx1cmVfbW9ub2N5dGVzIiwgImN1cmVfbmV1dHJvcGhpbHMiLCAiZmFpbHVyZV9uZXV0cm9waGlscyIpKQpoc19jbGluaWNhbF9jb25jYXQgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyhoc19jbGluaWNhbCwgZmFjdCA9IG5ld19mYWN0KSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidmlzaXRudW1iZXIiKSAlPiUKICBzZXRfZXhwdF9jb2xvcnMoY2ZfdHlwZV9jb2xvcnMpICU+JQogIHN1YnNldF9leHB0KHN1YnNldD0idHlwZW9mY2VsbHMhPSdiaW9wc3knIikKY2xpbmljYWxfY29uY2F0X25vcm0gPC0gbm9ybWFsaXplX2V4cHQoaHNfY2xpbmljYWxfY29uY2F0LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCmNsaW5pY2FsX2NvbmNhdF9ub3JtX3BjYSA8LSBwbG90X3BjYShjbGluaWNhbF9jb25jYXRfbm9ybSkKcHAoZmlsZT1nbHVlKCJpbWFnZXMvY2xpbmljYWxfY29uY2F0ZW5hdGVkX25vcm1hbGl6ZWRfcGNhLXZ7dmVyfS5wbmciKSwKICAgaW1hZ2U9Y2xpbmljYWxfY29uY2F0X25vcm1fcGNhJHBsb3QsIGhlaWdodD02LCB3aWR0aD0xMCkKCmNsaW5pY2FsX2NvbmNhdF9uYiA8LSBub3JtYWxpemVfZXhwdChoc19jbGluaWNhbF9jb25jYXQsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKY2xpbmljYWxfY29uY2F0X25iX3BjYSA8LSBwbG90X3BjYShjbGluaWNhbF9jb25jYXRfbmIpCnBwKGZpbGU9Z2x1ZSgiaW1hZ2VzL2NsaW5pY2FsX2NvbmNhdGVuYXRlZF9zdmFzZXFiYXRjaF9wY2Etdnt2ZXJ9LnBuZyIpLAogICBpbWFnZT1jbGluaWNhbF9jb25jYXRfbmJfcGNhJHBsb3QsIGhlaWdodD02LCB3aWR0aD0xMikKYGBgCgojIyMgU2FtcGxlcyBzZXBhcmF0ZWQgYnkgdmlzaXQKClNlcGFyYXRlIHRoZSBzYW1wbGVzIGJ5IHZpc2l0IGluIG9yZGVyIHRvIG1vcmUgZWFzaWx5IHNlZSB3aGF0CnBhdHRlcm5zIGVtZXJnZSBhY3Jvc3MgY2VsbCB0eXBlIGFuZCBjbGluaWNhbCBvdXRjb21lLgoKSSBoYXZlIGEgY291cGxlIG9mIGxpa2VseSBzdGFydGluZyBwb2ludHMgZm9yIHRoaXMuICBUaGUgZGF0YSBzZXRzOiBoc19jbGluaWNhbCBhbmQKY2xpbmljYWxfbm9sb3N0IGFyZSB0aGUgbW9zdCBsaWtlbHkuICBHaXZlbiB0aGF0IHRoaXMsIGF0IGxlYXN0IGluCnRoZW9yeSwgdGhlIGxvc3Qgc2FtcGxlcyBhcmUgbm90IHJlbGV2YW50LgoKIyMjIyBBbGwgdmlzaXRzIHRvZ2V0aGVyCgpOb3cgbGV0IHVzIHNoaWZ0IHRoZSB2aWV3IHNsaWdodGx5IHRvIGZvY3VzIG9uIGNoYW5nZXMgb2JzZXJ2ZWQgb3ZlciB0aW1lLgoKYGBge3IgY29tcGFyZV9hbGxfdmlzaXRzfQp2aXNpdF9leHB0IDwtIHNldF9leHB0X2NvbmRpdGlvbnMoaHNfY2xpbmljYWwsIGZhY3QgPSAidmlzaXRudW1iZXIiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAiY2xpbmljYWxvdXRjb21lIikgJT4lCiAgc3Vic2V0X2V4cHQoc3Vic2V0PSJ0eXBlb2ZjZWxscyE9J2Jpb3BzeSciKQoKdmlzaXRfbm9ybSA8LSBub3JtYWxpemVfZXhwdCh2aXNpdF9leHB0LCB0cmFuc2Zvcm09ImxvZzIiLCBjb252ZXJ0PSJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm09InF1YW50IiwgZmlsdGVyPVRSVUUpCnBsb3RfcGNhKHZpc2l0X25vcm0pJHBsb3QKdmlzaXRfbmIgPC0gbm9ybWFsaXplX2V4cHQodmlzaXRfZXhwdCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0PSJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQp2aXNpdF9uYl9wY2EgPC0gcGxvdF9wY2EodmlzaXRfbmIpCnBwKGZpbGU9Z2x1ZSgiaW1hZ2VzL3Zpc2l0X3N2YXNlcWJhdGNoX3BjYS12e3Zlcn0ucG5nIiksCiAgIGltYWdlPXZpc2l0X25iX3BjYSRwbG90LCBoZWlnaHQ9Nywgd2lkdGg9OSkKYGBgCgojIyBUb3AgMTAwMCBnZW5lcwoKcmVwZWF0IHdpdGggb25seSB0aGUgbW9zdCBleHByZXNzZWQgZ2VuZXMgZnJvbSBvbmUgY2VsbCB0eXBlLgoKYGBge3IgdG9wMTAwMH0KcnBrbV92YWx1ZXMgPC0gbm9ybWFsaXplX2V4cHQodHlwZV92YWxpZCwgdHJhbnNmb3JtPSJsb2cyIiwgY29udmVydD0icnBrbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcj1UUlVFLCBjb2x1bW49ImNkc19sZW5ndGgiKQpycGttX21lZGlhbiA8LSBtZWRpYW5fYnlfZmFjdG9yKHJwa21fdmFsdWVzKQptb25vY3l0ZV9tb3N0IDwtIG9yZGVyKHJwa21fbWVkaWFuW1sibWVkaWFucyJdXVtbIm1vbm9jeXRlcyJdXSwgZGVjcmVhc2luZz1UUlVFKQpycGttX21vc3RfbW9ub2N5dGVzIDwtIHJwa21fbWVkaWFuW1sibWVkaWFucyJdXVttb25vY3l0ZV9tb3N0LCBdCm1vc3RfbW9ub2N5dGVfZ2VuZXMgPC0gaGVhZChyb3duYW1lcyhycGttX21vc3RfbW9ub2N5dGVzKSwgbj0xMDAwKQoKc3Vic2V0IDwtIGV4Y2x1ZGVfZ2VuZXNfZXhwdCh2aXNpdF9nbHVjdjIsIG1ldGhvZD0ia2VlcCIsIGlkcz1tb3N0X21vbm9jeXRlX2dlbmVzKQpzdWJzZXRfbm9ybSA8LSBub3JtYWxpemVfZXhwdChzdWJzZXQsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsIGJhdGNoPSJzdmFzZXEiLCBmaWx0ZXI9VFJVRSkKYGBgCgojIyMjIEFsbCB2aXNpdHMsIHNlcGFyYXRlZCBieSBjZWxsIHR5cGUKCk5vdyBzZXBhcmF0ZSB0aGUgdmlzaXRzIGJ5IGNlbGwgdHlwZSBhbmQgd2hldGhlciBvciBub3QgdGhlIGRydWcgdXNlZAp3YXMgdGhlIGFudGltb25pYWwuCgpgYGB7ciBjZWxsX3R5cGVfdmlzaXRzfQp2aXNpdF9tb25vY3l0ZSA8LSBzdWJzZXRfZXhwdCh2aXNpdF9leHB0LCBzdWJzZXQgPSAidHlwZW9mY2VsbHM9PSdtb25vY3l0ZXMnIikKdmlzaXRfbW9ub2N5dGVfZ2x1Y2FudGltZSA8LSBzdWJzZXRfZXhwdCh2aXNpdF9tb25vY3l0ZSwgc3Vic2V0ID0gImRydWc9PSdhbnRpbW9ueSciKQp2aXNpdF9uZXV0cm9waGlsIDwtIHN1YnNldF9leHB0KHZpc2l0X2V4cHQsIHN1YnNldCA9ICJ0eXBlb2ZjZWxscz09J25ldXRyb3BoaWxzJyIpCnZpc2l0X25ldXRyb3BoaWxfZ2x1Y2FudGltZSA8LSBzdWJzZXRfZXhwdCh2aXNpdF9uZXV0cm9waGlsLCBzdWJzZXQgPSAiZHJ1Zz09J2FudGltb255JyIpCnZpc2l0X2Vvc2lub3BoaWwgPC0gc3Vic2V0X2V4cHQodmlzaXRfZXhwdCwgc3Vic2V0ID0gInR5cGVvZmNlbGxzPT0nZW9zaW5vcGhpbHMnIikKdmlzaXRfZW9zaW5vcGhpbF9nbHVjYW50aW1lIDwtIHN1YnNldF9leHB0KHZpc2l0X2Vvc2lub3BoaWwsIHN1YnNldCA9ICJkcnVnPT0nYW50aW1vbnknIikKYGBgCgojIyMjIFZpc2l0IDEgYWxvbmUKCmBgYHtyIHZpc2l0MV9kYXRhfQp2MV9jbGluaWNhbCA8LSBzdWJzZXRfZXhwdCh2aXNpdF9leHB0LCBzdWJzZXQgPSAidmlzaXRudW1iZXI9PScxJyIpICU+JQogIHNldF9leHB0X2NvbmRpdGlvbnMoZmFjdCA9ICJjbGluaWNhbG91dGNvbWUiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSAidHlwZW9mY2VsbHMiKQp2MV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHYxX2NsaW5pY2FsLCB0cmFuc2Zvcm09ImxvZzIiLCBjb252ZXJ0PSJjcG0iLCBub3JtPSJxdWFudCIsIGZpbHRlcj1UUlVFKQpwbG90X3BjYSh2MV9ub3JtKSRwbG90CnYxX25iIDwtIG5vcm1hbGl6ZV9leHB0KHYxX2NsaW5pY2FsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKcGxvdF9wY2EodjFfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpJHBsb3QKYGBgCgpTbywgZ2l2ZW4gdGhlIGRhdGEgb24gaGFuZCwgdGhlcmUgaXMgbGl0dGxlIG9yIG5vIGFiaWxpdHkgdG8gZGlzY2VybgpjdXJlIGFuZCBmYWlsIGFtb25nIHRoZSB2aXNpdCAxIHNhbXBsZXMuCgojIyMjIFZpc2l0IDIgYWxvbmUKCmBgYHtyIHZpc2l0Ml9kYXRhfQp2Ml9jbGluaWNhbCA8LSBzdWJzZXRfZXhwdCh2aXNpdF9leHB0LCBzdWJzZXQ9InZpc2l0bnVtYmVyPT0nMiciKSAlPiUKICBzZXRfZXhwdF9jb25kaXRpb25zKGZhY3QgPSAiY2xpbmljYWxvdXRjb21lIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gInR5cGVvZmNlbGxzIikKCnYyX25iIDwtIG5vcm1hbGl6ZV9leHB0KHYyX2NsaW5pY2FsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwgbm9ybSA9ICJxdWFudCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnBsb3RfcGNhKHYyX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKSRwbG90CmBgYAoKVGhlcmUgX21pZ2h0XyBiZSBzb21lIHZhcmlhbmNlIGFtb25nIHRoZSB2aXNpdCAyIHNhbXBsZXMgd2hpY2ggYXJlIGN1cmUvZmFpbC1pc2guCgojIyMjIFZpc2l0IDMgYWxvbmUKCmBgYHtyIHZpc2l0M19kYXRhfQp2M19jbGluaWNhbCA8LSBzdWJzZXRfZXhwdCh2aXNpdF9leHB0LCBzdWJzZXQ9InZpc2l0bnVtYmVyPT0nMyciKSAlPiUKICBzZXRfZXhwdF9jb25kaXRpb25zKGZhY3QgPSAiY2xpbmljYWxvdXRjb21lIikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gInR5cGVvZmNlbGxzIikKCnYzX25iIDwtIG5vcm1hbGl6ZV9leHB0KHYzX2NsaW5pY2FsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwgbm9ybSA9ICJxdWFudCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnBsb3RfcGNhKHYzX25iLCBwbG90X2xhYmVscyA9IEZBTFNFKSRwbG90CmBgYAoKSW4gYSBzaW1pbGFyIGZhc2hpb24sIGl0IHNlZW1zIHRoYXQgdGhlIHZpc2l0IDMgc2FtcGxlcyBhcmUgbm90CnBhcnRpY3VsYXJseSBpbmZvcm1hdGl2ZS4KCiMjIyBTYW1wbGVzIHNlcGFyYXRlZCBieSBjZWxsIHR5cGUKClNlcGFyYXRlIHRoZSBzYW1wbGVzIGJ5IGNlbGwgdHlwZSBpbiBvcmRlciB0byBtb3JlIGVhc2lseSBvYnNlcnZlCnBhdHRlcm5zIHdpdGggcmVzcGVjdCB0byB2aXNpdCBhbmQgY2xpbmljYWwgb3V0Y29tZS4KCiMjIyMgQmlvcHNpZXMKCmBgYHtyIGJpb3BzeV9zZXBhcmF0ZX0KYmlvcHN5X25vcm0gPC0gbm9ybWFsaXplX2V4cHQoYmlvcHN5X3NhbXBsZXMsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EoYmlvcHN5X25vcm0sIHBsb3RfbGFiZWxzID0gRkFMU0UpJHBsb3QKCmJpb3BzeV9uYiA8LSBub3JtYWxpemVfZXhwdChiaW9wc3lfc2FtcGxlcywgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQpwbG90X3BjYShiaW9wc3lfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpJHBsb3QKYGBgCgpPdWNoLCBpdCByZWFsbHkgbG9va3MgbGlrZSB0aGUgYmlvcGllcyBhcmUgbm90IHZlcnkgaW5mb3JtYXRpdmUuCgojIyMjIE1vbm9jeXRlcwoKYGBge3IgbW9ub2N5dGVfc2VwYXJhdGV9Cm1vbm9jeXRlX25vcm0gPC0gbm9ybWFsaXplX2V4cHQobW9ub2N5dGVfc2FtcGxlcywgbm9ybSA9ICJxdWFudCIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKG1vbm9jeXRlX25vcm0sIHBsb3RfbGFiZWxzID0gRkFMU0UpJHBsb3QKCm1vbm9jeXRlX25iIDwtIG5vcm1hbGl6ZV9leHB0KG1vbm9jeXRlX3NhbXBsZXMsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9ICJsb2cyIiwgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKcGxvdF9wY2EobW9ub2N5dGVfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpJHBsb3QKYGBgCgpUaGUgbW9ub2N5dGVzLCBvbiB0aGUgb3RoZXIgaGFuZCwgYXBwZWFyIHRvIGhhdmUgc29tZSByZWFsIGluZm9ybWF0aW9uCmx1cmtpbmcgaW4gdGhlbS4KCiMjIyMgTmV1dHJvcGhpbHMKCmBgYHtyIG5ldXRyb3BoaWxfc2VwYXJhdGV9Cm5ldXRyb3BoaWxfbm9ybSA8LSBub3JtYWxpemVfZXhwdChuZXV0cm9waGlsX3NhbXBsZXMsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShuZXV0cm9waGlsX25vcm0sIHBsb3RfbGFiZWxzID0gRkFMU0UpJHBsb3QKCm5ldXRyb3BoaWxfbmIgPC0gbm9ybWFsaXplX2V4cHQobmV1dHJvcGhpbF9zYW1wbGVzLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnBsb3RfcGNhKG5ldXRyb3BoaWxfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpJHBsb3QKYGBgCgpUaGlzIGFwcGVhcnMgYWxzbyB0byBiZSB0aGUgY2FzZSBmb3IgdGhlIG5ldXRyb3BoaWwgc2FtcGxlcy4KCiMjIyMgRW9zaW5vcGhpbHMKCmBgYHtyIGVvc2lub3BoaWxfc2VwYXJhdGV9CmVvc2lub3BoaWxfbm9ybSA8LSBub3JtYWxpemVfZXhwdChlb3Npbm9waGlsX3NhbXBsZXMsIG5vcm0gPSAicXVhbnQiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtID0gImxvZzIiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShlb3Npbm9waGlsX25vcm0sIHBsb3RfbGFiZWxzID0gRkFMU0UpJHBsb3QKCmVvc2lub3BoaWxfbmIgPC0gbm9ybWFsaXplX2V4cHQoZW9zaW5vcGhpbF9zYW1wbGVzLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnBsb3RfcGNhKGVvc2lub3BoaWxfbmIsIHBsb3RfbGFiZWxzID0gRkFMU0UpJHBsb3QKYGBgCgpXZSBoYXZlIGZld2VyIGVvc2lub3BoaWwgc2FtcGxlcyBjdXJyZW50bHksIGJ1dCB0aGV5IGFwcGVhciB0byBoYXZlCnNvbWUgcmVhbCBkaWZmZXJlbmNlcy4KCiMjIyMgTW9ub2N5dGVzLCBOZXV0cm9waGlscywgYW5kIEVvc2lub3BoaWxzCgojIERpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2VzCgpUaGUgcHJpbWFyeSBnb2FsIGlzIHRvIGxlYXJuIGFib3V0IGN1cmUgdnMuIGZhaWwuCgojIyBDdXJlL0ZhaWwsIGFsbCBzYW1wbGVzCgpOb3cgbGV0IHVzIHN0YXJ0IHBlcmZvcm1pbmcgdGhlIHZhcmlvdXMgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24KYW5hbHlzZXMsIHN0YXJ0aW5nIHdpdGggdGhlIHNldCBvZiBhbGwvbW9zdCBjbGluaWNhbCBzYW1wbGVzLgoKYGBge3IgY2ZfYWxsX2RlfQpjZl9jbGluaWNhbF9kZSA8LSBhbGxfcGFpcndpc2UoaHNfY2xpbmljYWwsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCmNmX2NsaW5pY2FsX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIGNmX2NsaW5pY2FsX2RlLAogICAga2VlcGVycyA9IGNmX2NvbnRyYXN0cywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvY2ZfY2xpbmljYWxfdGFibGVzLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9jZl9jbGluaWNhbF9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMgQnkgY2VsbCB0eXBlCgojIyMjIEN1cmUvRmFpbCwgQmlvcHNpZXMKCmBgYHtyIGNmX2Jpb3BzeV9kZX0KY2ZfYmlvcHN5X2RlIDwtIGFsbF9wYWlyd2lzZShiaW9wc3lfc2FtcGxlcywgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKY2ZfYmlvcHN5X3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIGNmX2Jpb3BzeV9kZSwKICAgIGtlZXBlcnMgPSBjZl9jb250cmFzdHMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL2NmX2Jpb3BzeV90YWJsZXMtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL2NmX2Jpb3BzeV9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMjIEN1cmUvRmFpbCwgTW9ub2N5dGVzCgpgYGB7ciBjZl9tb25vY3l0ZV9kZX0KY2ZfbW9ub2N5dGVfZGUgPC0gYWxsX3BhaXJ3aXNlKG1vbm9jeXRlX3NhbXBsZXMsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCmNmX21vbm9jeXRlX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIGNmX21vbm9jeXRlX2RlLAogICAga2VlcGVycyA9IGNmX2NvbnRyYXN0cywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvY2ZfbW9ub2N5dGVfdGFibGVzLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9jZl9tb25vY3l0ZV9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMjIEN1cmUvRmFpbCwgTmV1dHJvcGhpbHMKCmBgYHtyIGNmX25ldXRyb3BoaWxfZGV9CmNmX25ldXRyb3BoaWxfZGUgPC0gYWxsX3BhaXJ3aXNlKG5ldXRyb3BoaWxfc2FtcGxlcywgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKY2ZfbmV1dHJvcGhpbF90YWJsZXMgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBjZl9uZXV0cm9waGlsX2RlLAogICAga2VlcGVycyA9IGNmX2NvbnRyYXN0cywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvY2ZfbmV1dHJvcGhpbF90YWJsZXMtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL2NmX25ldXRyb3BoaWxfc2lnLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMjIyBDdXJlL0ZhaWwsIEVvc2lub3BoaWxzCgpgYGB7ciBjZl9lb3Npbm9waGlsX2RlfQpjZl9lb3Npbm9waGlsX2RlIDwtIGFsbF9wYWlyd2lzZShlb3Npbm9waGlsX3NhbXBsZXMsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCmNmX2Vvc2lub3BoaWxfdGFibGVzIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgY2ZfZW9zaW5vcGhpbF9kZSwKICAgIGtlZXBlcnMgPSBjZl9jb250cmFzdHMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL2NmX2Vvc2lub3BoaWxfdGFibGVzLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9jZl9lb3Npbm9waGlsX3NpZy12e3Zlcn0ueGxzeCIpKQpgYGAKCiMjIyMgQ3VyZS9GYWlsIGNsaW5pY2FsIChOb3QgYmlvcHNpZXMpCgpgYGB7ciBjZl9ub2Jpb3BzeV9kZX0KY2Zfbm9iaW9wc3lfZGUgPC0gYWxsX3BhaXJ3aXNlKGhzX2NsaW5pY2FsX25vYmlvcCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKY2Zfbm9iaW9wc3lfdGFibGVzIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgY2Zfbm9iaW9wc3lfZGUsCiAgICBrZWVwZXJzID0gY2ZfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9jZl9ub2Jpb3BzeV90YWJsZXMtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL2NmX25vYmlvcHN5X3NpZy12e3Zlcn0ueGxzeCIpKQpgYGAKCiMjIyBCeSB2aXNpdAoKRm9yIHRoZXNlIGNvbnRyYXN0cywgd2Ugd2FudCB0byBzZWUgZmFpbF92MSB2cy4gY3VyZV92MSwgZmFpbF92Mgp2cy4gY3VyZV92MiBldGMuICBBcyBhIHJlc3VsdCwgd2Ugd2lsbCBuZWVkIHRvIGp1Z2dsZSB0aGUgZGF0YQpzbGlnaHRseSBhbmQgYWRkIGFub3RoZXIgc2V0IG9mIGNvbnRyYXN0cy4KCiMjIyBTZXR0aW5nIHVwCgpgYGB7ciBzZXR1cF92aXNpdF9jZl9kYXRhX2NvbnRyYXN0c30KdmlzaXRfY2ZfY29udHJhc3RzIDwtIGxpc3QoCiAgICAidjFmYWlsX3ZzX2N1cmUiID0gYygidjFmYWlsdXJlIiwgInYxY3VyZSIpLAogICAgInYyZmFpbF92c19jdXJlIiA9IGMoInYyZmFpbHVyZSIsICJ2MmN1cmUiKSwKICAgICJ2M2ZhaWxfdnNfY3VyZSIgPSBjKCJ2M2ZhaWx1cmUiLCAidjNjdXJlIikpCnZpc2l0X2NmX2V4cHRfZmFjdG9yIDwtIHBhc3RlMCgidiIsIHBEYXRhKGhzX2NsaW5pY2FsKVtbInZpc2l0bnVtYmVyIl1dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcERhdGEoaHNfY2xpbmljYWwpW1siY29uZGl0aW9uIl1dKQp2aXNpdF9jZl9leHB0IDwtIHNldF9leHB0X2NvbmRpdGlvbnMoaHNfY2xpbmljYWwsIGZhY3QgPSB2aXNpdF9jZl9leHB0X2ZhY3RvcikKCnZpc2l0X2NmX2Jpb3BzeSA8LSBzdWJzZXRfZXhwdCh2aXNpdF9jZl9leHB0LCBzdWJzZXQ9InR5cGVvZmNlbGxzPT0nYmlvcHN5JyIpCnZpc2l0X2NmX2Vvc2lub3BoaWwgPC0gc3Vic2V0X2V4cHQodmlzaXRfY2ZfZXhwdCwgc3Vic2V0PSJ0eXBlb2ZjZWxscz09J2Vvc2lub3BoaWxzJyIpCnZpc2l0X2NmX21vbm9jeXRlIDwtIHN1YnNldF9leHB0KHZpc2l0X2NmX2V4cHQsIHN1YnNldD0idHlwZW9mY2VsbHM9PSdtb25vY3l0ZXMnIikKdmlzaXRfY2ZfbmV1dHJvcGhpbCA8LSBzdWJzZXRfZXhwdCh2aXNpdF9jZl9leHB0LCBzdWJzZXQ9InR5cGVvZmNlbGxzPT0nbmV1dHJvcGhpbHMnIikKYGBgCgojIyMjIEN1cmUvRmFpbCBieSB2aXNpdHMsIGFsbCBjZWxsIHR5cGVzCgpgYGB7ciB2aXNpdF9jZl9hbGxfZGV9CnZpc2l0X2NmX2FsbF9kZSA8LSBhbGxfcGFpcndpc2UodmlzaXRfY2ZfZXhwdCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdmlzaXRfY2ZfYWxsX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIHZpc2l0X2NmX2FsbF9kZSwKICAgIGtlZXBlcnMgPSB2aXNpdF9jZl9jb250cmFzdHMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X2NmX2FsbF90YWJsZXMtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X2NmX2FsbF9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyMjIEN1cmUvRmFpbCBieSB2aXNpdCwgQmlvcHNpZXMKCmBgYHtyIHZpc2l0X2NmX2Jpb3BzeV9kZX0KdmlzaXRfY2ZfYmlvcHN5X2RlIDwtIGFsbF9wYWlyd2lzZSh2aXNpdF9jZl9iaW9wc3ksIG1vZGVsX2JhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnZpc2l0X2NmX2Jpb3BzeV90YWJsZXMgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICB2aXNpdF9jZl9iaW9wc3lfZGUsCiAgICBrZWVwZXJzID0gdmlzaXRfY2ZfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9jZl9iaW9wc3lfdGFibGVzLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9jZl9iaW9wc3lfc2lnLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMjIyBDdXJlL0ZhaWwgYnkgdmlzaXQsIE1vbm9jeXRlcwoKYGBge3IgdmlzaXRfY2ZfbW9ub2N5dGVfZGV9CnZpc2l0X2NmX21vbm9jeXRlX2RlIDwtIGFsbF9wYWlyd2lzZSh2aXNpdF9jZl9tb25vY3l0ZSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdmlzaXRfY2ZfbW9ub2N5dGVfdGFibGVzIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgdmlzaXRfY2ZfbW9ub2N5dGVfZGUsCiAgICBrZWVwZXJzID0gdmlzaXRfY2ZfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9jZl9tb25vY3l0ZV90YWJsZXMtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X2NmX21vbm9jeXRlX3NpZy12e3Zlcn0ueGxzeCIpKQpgYGAKCiMjIyMgQ3VyZS9GYWlsIGJ5IHZpc2l0LCBOZXV0cm9waGlscwoKYGBge3IgdmlzaXRfY2ZfbmV1dHJvcGhpbF9kZX0KdmlzaXRfY2ZfbmV1dHJvcGhpbF9kZSA8LSBhbGxfcGFpcndpc2UodmlzaXRfY2ZfbmV1dHJvcGhpbCwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKdmlzaXRfY2ZfbmV1dHJvcGhpbF90YWJsZXMgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICB2aXNpdF9jZl9uZXV0cm9waGlsX2RlLAogICAga2VlcGVycyA9IHZpc2l0X2NmX2NvbnRyYXN0cywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvdmlzaXRfY2ZfbmV1dHJvcGhpbF90YWJsZXMtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X2NmX25ldXRyb3BoaWxfc2lnLXZ7dmVyfS54bHN4IikpCmBgYAoKIyMjIyBDdXJlL0ZhaWwgYnkgdmlzaXQsIEVvc2lub3BoaWxzCgpgYGB7ciB2aXNpdF9jZl9lb3Npbm9waGlsX2RlfQp2aXNpdF9jZl9lb3Npbm9waGlsX2RlIDwtIGFsbF9wYWlyd2lzZSh2aXNpdF9jZl9lb3Npbm9waGlsLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQp2aXNpdF9jZl9lb3Npbm9waGlsX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIHZpc2l0X2NmX2Vvc2lub3BoaWxfZGUsCiAgICBrZWVwZXJzID0gdmlzaXRfY2ZfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9jZl9lb3Npbm9waGlsX3RhYmxlcy12e3Zlcn0ueGxzeCIpLAogICAgc2lnX2V4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvdmlzaXRfY2ZfZW9zaW5vcGhpbF9zaWctdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyBQZXJzaXN0ZW5jZSBpbiB2aXNpdCAzCgpIYXZpbmcgcHV0IHNvbWUgU0wgcmVhZCBtYXBwaW5nIGluZm9ybWF0aW9uIGluIHRoZSBzYW1wbGUgc2hlZXQsIE1hcmlhCkFkZWxhaWRhIGFkZGVkIGEgbmV3IGNvbHVtbiB1c2luZyBpdCB3aXRoIHRoZSBwdXRhdGl2ZSBwZXJzaXN0ZW5jZQpzdGF0ZSBvbiBhIHBlci1zYW1wbGUgYmFzaXMuICBPbmUgcXVlc3Rpb24gd2hpY2ggYXJpc2VkIGZyb20gdGhhdDoKd2hhdCBkaWZmZXJlbmNlcyBhcmUgb2JzZXJ2YWJsZSBiZXR3ZWVuIHRoZSBwZXJzaXN0ZW50IHllcyB2cy4gbm8Kc2FtcGxlcyBvbiBhIHBlci1jZWxsLXR5cGUgYmFzaXMgYW1vbmcgdGhlIHZpc2l0IDMgc2FtcGxlcy4KCiMjIyBTZXR0aW5nIHVwCgpGaXJzdCB0aGluZ3MgZmlyc3QsIGNyZWF0ZSB0aGUgZGF0YXNldHMuCgpgYGB7ciBwZXJzaXN0ZW5jZV9zZXR1cH0KcGVyc2lzdGVuY2VfZXhwdCA8LSBzdWJzZXRfZXhwdChoc19jbGluaWNhbCwgc3Vic2V0ID0gInBlcnNpc3RlbmNlPT0nWSd8cGVyc2lzdGVuY2U9PSdOJyIpICU+JQogIHN1YnNldF9leHB0KHN1YnNldCA9ICd2aXNpdG51bWJlcj09MycpICU+JQogIHNldF9leHB0X2NvbmRpdGlvbnMoZmFjdCA9ICdwZXJzaXN0ZW5jZScpCgojIyBwZXJzaXN0ZW5jZV9iaW9wc3kgPC0gc3Vic2V0X2V4cHQocGVyc2lzdGVuY2VfZXhwdCwgc3Vic2V0ID0gInR5cGVvZmNlbGxzPT0nYmlvcHN5JyIpCnBlcnNpc3RlbmNlX21vbm9jeXRlIDwtIHN1YnNldF9leHB0KHBlcnNpc3RlbmNlX2V4cHQsIHN1YnNldCA9ICJ0eXBlb2ZjZWxscz09J21vbm9jeXRlcyciKQpwZXJzaXN0ZW5jZV9uZXV0cm9waGlsIDwtIHN1YnNldF9leHB0KHBlcnNpc3RlbmNlX2V4cHQsIHN1YnNldCA9ICJ0eXBlb2ZjZWxscz09J25ldXRyb3BoaWxzJyIpCnBlcnNpc3RlbmNlX2Vvc2lub3BoaWwgPC0gc3Vic2V0X2V4cHQocGVyc2lzdGVuY2VfZXhwdCwgc3Vic2V0ID0gInR5cGVvZmNlbGxzPT0nZW9zaW5vcGhpbHMnIikKYGBgCgojIyMgVGFrZSBhIGxvb2sKClNlZSBpZiB0aGVyZSBhcmUgYW55IHBhdHRlcm5zIHdoaWNoIGxvb2sgdXNhYmxlLgoKYGBge3IgcGVyc2lzdGVuY2VfcGxvdH0KIyMgQWxsCnBlcnNpc3RlbmNlX25vcm0gPC0gbm9ybWFsaXplX2V4cHQocGVyc2lzdGVuY2VfZXhwdCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHBlcnNpc3RlbmNlX25vcm0pJHBsb3QKcGVyc2lzdGVuY2VfbmIgPC0gbm9ybWFsaXplX2V4cHQocGVyc2lzdGVuY2VfZXhwdCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHBlcnNpc3RlbmNlX25iKSRwbG90CgojIyBCaW9wc2llcwojI3BlcnNpc3RlbmNlX2Jpb3BzeV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHBlcnNpc3RlbmNlX2Jpb3BzeSwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiMjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKIyNwbG90X3BjYShwZXJzaXN0ZW5jZV9iaW9wc3lfbm9ybSkkcGxvdAojIyBJbnN1ZmZpY2llbnQgZGF0YQoKIyMgTW9ub2N5dGVzCnBlcnNpc3RlbmNlX21vbm9jeXRlX25vcm0gPC0gbm9ybWFsaXplX2V4cHQocGVyc2lzdGVuY2VfbW9ub2N5dGUsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShwZXJzaXN0ZW5jZV9tb25vY3l0ZV9ub3JtKSRwbG90CnBlcnNpc3RlbmNlX21vbm9jeXRlX25iIDwtIG5vcm1hbGl6ZV9leHB0KHBlcnNpc3RlbmNlX21vbm9jeXRlLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmF0Y2ggPSAic3Zhc2VxIiwgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EocGVyc2lzdGVuY2VfbW9ub2N5dGVfbmIpJHBsb3QKCiMjIE5ldXRyb3BoaWxzCnBlcnNpc3RlbmNlX25ldXRyb3BoaWxfbm9ybSA8LSBub3JtYWxpemVfZXhwdChwZXJzaXN0ZW5jZV9uZXV0cm9waGlsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EocGVyc2lzdGVuY2VfbmV1dHJvcGhpbF9ub3JtKSRwbG90CnBlcnNpc3RlbmNlX25ldXRyb3BoaWxfbmIgPC0gbm9ybWFsaXplX2V4cHQocGVyc2lzdGVuY2VfbmV1dHJvcGhpbCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHBlcnNpc3RlbmNlX25ldXRyb3BoaWxfbmIpJHBsb3QKCiMjIEVvc2lub3BoaWxzCnBlcnNpc3RlbmNlX2Vvc2lub3BoaWxfbm9ybSA8LSBub3JtYWxpemVfZXhwdChwZXJzaXN0ZW5jZV9lb3Npbm9waGlsLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKcGxvdF9wY2EocGVyc2lzdGVuY2VfZW9zaW5vcGhpbF9ub3JtKSRwbG90CnBlcnNpc3RlbmNlX2Vvc2lub3BoaWxfbmIgPC0gbm9ybWFsaXplX2V4cHQocGVyc2lzdGVuY2VfZW9zaW5vcGhpbCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJhdGNoID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCnBsb3RfcGNhKHBlcnNpc3RlbmNlX2Vvc2lub3BoaWxfbmIpJHBsb3QKYGBgCgojIyMgcGVyc2lzdGVuY2UgREUKCmBgYHtyIHBlcnNpc3RlbmNlX2RlfQpwZXJzaXN0ZW5jZV9kZSA8LSBhbGxfcGFpcndpc2UocGVyc2lzdGVuY2VfZXhwdCwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKcGVyc2lzdGVuY2VfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBwZXJzaXN0ZW5jZV9kZSwKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvcGVyc2lzdGVuY2VfYWxsX2RlLXZ7dmVyfS54bHN4IikpCnBlcnNpc3RlbmNlX21vbm9jeXRlX2RlIDwtIGFsbF9wYWlyd2lzZShwZXJzaXN0ZW5jZV9tb25vY3l0ZSwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKcGVyc2lzdGVuY2VfbW9ub2N5dGVfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICBwZXJzaXN0ZW5jZV9tb25vY3l0ZV9kZSwKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvcGVyc2lzdGVuY2VfbW9ub2N5dGVfZGUtdnt2ZXJ9Lnhsc3giKSkKcGVyc2lzdGVuY2VfbmV1dHJvcGhpbF9kZSA8LSBhbGxfcGFpcndpc2UocGVyc2lzdGVuY2VfbmV1dHJvcGhpbCwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKcGVyc2lzdGVuY2VfbmV1dHJvcGhpbF90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIHBlcnNpc3RlbmNlX25ldXRyb3BoaWxfZGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3BlcnNpc3RlbmNlX25ldXRyb3BoaWxfZGUtdnt2ZXJ9Lnhsc3giKSkKcGVyc2lzdGVuY2VfZW9zaW5vcGhpbF9kZSA8LSBhbGxfcGFpcndpc2UocGVyc2lzdGVuY2VfZW9zaW5vcGhpbCwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKcGVyc2lzdGVuY2VfZW9zaW5vcGhpbF90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIHBlcnNpc3RlbmNlX2Vvc2lub3BoaWxfZGUsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3BlcnNpc3RlbmNlX2Vvc2lub3BoaWxfZGUtdnt2ZXJ9Lnhsc3giKSkKYGBgCgojIyBDb21wYXJpbmcgdmlzaXRzIHdpdGhvdXQgcmVnYXJkIHRvIGN1cmUvZmFpbAoKIyMjIEFsbCBjZWxsIHR5cGVzCgpgYGB7ciBkZV9jZl92aXNpdF9hbGx9CnZpc2l0X2FsbF9kZSA8LSBhbGxfcGFpcndpc2UodmlzaXRfZXhwdCwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKdmlzaXRfYWxsX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgdmlzaXRfYWxsX2RlLAogICAga2VlcGVycyA9IHZpc2l0X2NvbnRyYXN0cywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvdmlzaXRfYWxsX2RlLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9hbGxfc2lnLXZ7dmVyfS54bHN4IikpCnZpc2l0X2FsbF9zYXZlZCA8LSBzYXZlKGxpc3QgPSAidmlzaXRfYWxsX3RhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSA9IGdsdWU6OmdsdWUoInJkYS92aXNpdF9hbGxfdGFibGUtdnt2ZXJ9LnJkYSIpKQoKdmlzaXRfYWxsX2dsdWNfZGUgPC0gYWxsX3BhaXJ3aXNlKHZpc2l0X2dsdWNhbnRpbWUsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIpCnZpc2l0X2FsbF9nbHVjX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgdmlzaXRfYWxsX2dsdWNfZGUsCiAgICBrZWVwZXJzID0gdmlzaXRfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9hbGxfZ2x1Y19kZS12e3Zlcn0ueGxzeCIpLAogICAgc2lnX2V4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvdmlzaXRfYWxsX2dsdWNfc2lnLXZ7dmVyfS54bHN4IikpCnZpc2l0X2FsbF9nbHVjX3NhdmVkIDwtIHNhdmUobGlzdCA9ICJ2aXNpdF9hbGxfZ2x1Y190YWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSA9IGdsdWU6OmdsdWUoInJkYS92aXNpdF9hbGxfZ2x1Y190YWJsZS12e3Zlcn0ucmRhIikpCmBgYAoKIyMjIEJpb3BzeSBzYW1wbGVzCgpgYGB7ciBkZV9jZl92aXNpdF9iaW9wc3l9CnZpc2l0X2Jpb3BzeV9kZSA8LSBhbGxfcGFpcndpc2UodmlzaXRfYmlvcHN5LCBmaWx0ZXIgPSBUUlVFLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiKQp2aXNpdF9iaW9wc3lfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXMoCiAgICB2aXNpdF9iaW9wc3lfZGUsCiAgICBrZWVwZXJzID0gdmlzaXRfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9iaW9wc3lfZGUtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X2Jpb3BzeV9zaWctdnt2ZXJ9Lnhsc3giKSkKdmlzaXRfYmlvcHN5X3NhdmVkIDwtIHNhdmUobGlzdCA9ICJ2aXNpdF9iaW9wc3lfdGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlID0gZ2x1ZTo6Z2x1ZSgicmRhL3Zpc2l0X2Jpb3BzeV90YWJsZS12e3Zlcn0ucmRhIikpCgp2aXNpdF9iaW9wc3lfZ2x1Y19kZSA8LSBhbGxfcGFpcndpc2UodmlzaXRfYmlvcHN5X2dsdWNhbnRpbWUsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIpCnZpc2l0X2Jpb3BzeV9nbHVjX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgdmlzaXRfYmlvcHN5X2dsdWNfZGUsCiAgICBrZWVwZXJzID0gdmlzaXRfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9iaW9wc3lfZ2x1Y19kZS12e3Zlcn0ueGxzeCIpLAogICAgc2lnX2V4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvdmlzaXRfYmlvcHN5X2dsdWNfc2lnLXZ7dmVyfS54bHN4IikpCnZpc2l0X2Jpb3BzeV9nbHVjX3NhdmVkIDwtIHNhdmUobGlzdCA9ICJ2aXNpdF9iaW9wc3lfZ2x1Y190YWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSA9IGdsdWU6OmdsdWUoInJkYS92aXNpdF9iaW9wc3lfZ2x1Y190YWJsZS12e3Zlcn0ucmRhIikpCmBgYAoKIyMjIE1vbm9jeXRlIHNhbXBsZXMKCmBgYHtyIGRlX2NmX3Zpc2l0X21vbm9jeXRlfQp2aXNpdF9tb25vY3l0ZV9kZSA8LSBhbGxfcGFpcndpc2UodmlzaXRfbW9ub2N5dGUsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIpCnZpc2l0X21vbm9jeXRlX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgdmlzaXRfbW9ub2N5dGVfZGUsCiAgICBrZWVwZXJzID0gdmlzaXRfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9tb25vY3l0ZV9kZS12e3Zlcn0ueGxzeCIpLAogICAgc2lnX2V4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvdmlzaXRfbW9ub2N5dGVfc2lnLXZ7dmVyfS54bHN4IikpCgp2aXNpdF9tb25vY3l0ZV9nbHVjX2RlIDwtIGFsbF9wYWlyd2lzZSh2aXNpdF9tb25vY3l0ZV9nbHVjYW50aW1lLCBmaWx0ZXIgPSBUUlVFLCBtb2RlbF9iYXRjaCA9ICJzdmFzZXEiKQp2aXNpdF9tb25vY3l0ZV9nbHVjX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgdmlzaXRfbW9ub2N5dGVfZ2x1Y19kZSwKICAgIGtlZXBlcnMgPSB2aXNpdF9jb250cmFzdHMsCiAgICBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X21vbm9jeXRlX2dsdWNfZGUtdnt2ZXJ9Lnhsc3giKSwKICAgIHNpZ19leGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3Zpc2l0X21vbm9jeXRlX2dsdWNfc2lnLXZ7dmVyfS54bHN4IikpCnZpc2l0X21vbm9jeXRlX2dsdWNfc2F2ZWQgPC0gc2F2ZShsaXN0ID0gInZpc2l0X21vbm9jeXRlX2dsdWNfdGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUgPSBnbHVlOjpnbHVlKCJyZGEvdmlzaXRfbW9ub2N5dGVfZ2x1Y190YWJsZS12e3Zlcn0ucmRhIikpCmBgYAoKIyMjIE5ldXRyb3BoaWwgc2FtcGxlcwoKYGBge3IgZGVfY2ZfdmlzaXRfbmV1dHJvcGhpbH0KdmlzaXRfbmV1dHJvcGhpbF9kZSA8LSBhbGxfcGFpcndpc2UodmlzaXRfbmV1dHJvcGhpbCwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKdmlzaXRfbmV1dHJvcGhpbF90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIHZpc2l0X25ldXRyb3BoaWxfZGUsCiAgICBrZWVwZXJzID0gdmlzaXRfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9uZXV0cm9waGlsX2RlLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9uZXV0cm9waGlsX3NpZy12e3Zlcn0ueGxzeCIpKQp2aXNpdF9uZXV0cm9waGlsX3NhdmVkIDwtIHNhdmUobGlzdCA9ICJ2aXNpdF9uZXV0cm9waGlsX3RhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUgPSBnbHVlOjpnbHVlKCJyZGEvdmlzaXRfbmV1dHJvcGhpbF90YWJsZS12e3Zlcn0ucmRhIikpCgp2aXNpdF9uZXV0cm9waGlsX2dsdWNfZGUgPC0gYWxsX3BhaXJ3aXNlKHZpc2l0X25ldXRyb3BoaWxfZ2x1Y2FudGltZSwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKdmlzaXRfbmV1dHJvcGhpbF9nbHVjX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgdmlzaXRfbmV1dHJvcGhpbF9nbHVjX2RlLAogICAga2VlcGVycyA9IHZpc2l0X2NvbnRyYXN0cywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvdmlzaXRfbmV1dHJvcGhpbF9nbHVjX2RlLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9uZXV0cm9waGlsX2dsdWNfc2lnLXZ7dmVyfS54bHN4IikpCnZpc2l0X25ldXRyb3BoaWxfZ2x1Y19zYXZlZCA8LSBzYXZlKGxpc3QgPSAidmlzaXRfbmV1dHJvcGhpbF9nbHVjX3RhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlID0gZ2x1ZTo6Z2x1ZSgicmRhL3Zpc2l0X25ldXRyb3BoaWxfZ2x1Y190YWJsZS12e3Zlcn0ucmRhIikpCmBgYAoKIyMjIEVvc2lub3BoaWwgc2FtcGxlcwoKYGBge3IgZGVfY2ZfdmlzaXRfZW9zaW5vcGhpbH0KdmlzaXRfZW9zaW5vcGhpbF9kZSA8LSBhbGxfcGFpcndpc2UodmlzaXRfZW9zaW5vcGhpbCwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKdmlzaXRfZW9zaW5vcGhpbF90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcygKICAgIHZpc2l0X2Vvc2lub3BoaWxfZGUsCiAgICBrZWVwZXJzID0gdmlzaXRfY29udHJhc3RzLAogICAgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9lb3Npbm9waGlsX2RlLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9lb3Npbm9waGlsX3NpZy12e3Zlcn0ueGxzeCIpKQp2aXNpdF9lb3Npbm9waGlsX3NhdmVkIDwtIHNhdmUobGlzdCA9ICJ2aXNpdF9lb3Npbm9waGlsX3RhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUgPSBnbHVlOjpnbHVlKCJyZGEvdmlzaXRfZW9zaW5vcGhpbF90YWJsZS12e3Zlcn0ucmRhIikpCgp2aXNpdF9lb3Npbm9waGlsX2dsdWNfZGUgPC0gYWxsX3BhaXJ3aXNlKHZpc2l0X2Vvc2lub3BoaWxfZ2x1Y2FudGltZSwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikKdmlzaXRfZW9zaW5vcGhpbF9nbHVjX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKAogICAgdmlzaXRfZW9zaW5vcGhpbF9nbHVjX2RlLAogICAga2VlcGVycyA9IHZpc2l0X2NvbnRyYXN0cywKICAgIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvdmlzaXRfZW9zaW5vcGhpbF9nbHVjX2RlLXZ7dmVyfS54bHN4IiksCiAgICBzaWdfZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC92aXNpdF9lb3Npbm9waGlsX2dsdWNfc2lnLXZ7dmVyfS54bHN4IikpCnZpc2l0X2Vvc2lub3BoaWxfZ2x1Y19zYXZlZCA8LSBzYXZlKGxpc3QgPSAidmlzaXRfZW9zaW5vcGhpbF9nbHVjX3RhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlID0gZ2x1ZTo6Z2x1ZSgicmRhL3Zpc2l0X2Vvc2lub3BoaWxfZ2x1Y190YWJsZS12e3Zlcn0ucmRhIikpCmBgYAoKIyBMaWtlbGlob29kIFJhdGlvIFRlc3RpbmcgKExSVCkKCiMjIFNoYXJlZCBwYXR0ZXJucyBhY3Jvc3MgdmlzaXRzCgpgYGB7ciBscnRfdmlzaXR9CmNsaW5pY2FsX2ZpbHQgPC0gbm9ybWFsaXplX2V4cHQoaHNfY2xpbmljYWwsIGZpbHRlciA9IFRSVUUpCmxydF92aXNpdCA8LSBkZXNlcV9scnQoY2xpbmljYWxfZmlsdCwgdHJhbnNmb3JtID0gInZzdCIsIGludGVyYWN0aW9uID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3Rvcl9jb2x1bW4gPSAidmlzaXRudW1iZXIiLAogICAgICAgICAgICAgICAgICAgICAgIGludGVyZXN0X2NvbHVtbiA9ICJjbGluaWNhbG91dGNvbWUiKQpzdW1tYXJ5KGxydF92aXNpdFtbImZhdm9yaXRlX2dlbmVzIl1dKQp3cml0dGVuIDwtIHdyaXRlX3hsc3goZGF0YT1hcy5kYXRhLmZyYW1lKGxydF92aXNpdFtbImRlc2VxX3RhYmxlIl1dKSwKICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPWdsdWU6OmdsdWUoImV4Y2VsL2xydF9jbGluaWNhbF92aXNpdC12e3Zlcn0ueGxzeCIpKQpgYGAKCiMjIFNoYXJlZCBwYXR0ZXJucyBhY3Jvc3MgY2VsbCB0eXBlcwoKYGBge3IgbHJ0X2NlbGx0eXBlfQpscnRfY2VsbHR5cGVfY2xpbmljYWxfdGVzdCA8LSBkZXNlcV9scnQobm9sb3N0X2ZpbHQsIHRyYW5zZm9ybSA9ICJ2c3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3Rvcl9jb2x1bW4gPSAidHlwZW9mY2VsbHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJlc3RfY29sdW1uID0gImNsaW5pY2Fsb3V0Y29tZSIpCnN1bW1hcnkobHJ0X2NlbGx0eXBlX2NsaW5pY2FsX3Rlc3RbWyJmYXZvcml0ZV9nZW5lcyJdXSkKZmF2b3JpdGVfbHJ0X2RmIDwtIG1lcmdlKGhzX2Fubm90LCBscnRfY2VsbHR5cGVfY2xpbmljYWxfdGVzdFtbImZhdm9yaXRlX2dlbmVzIl1dLAogICAgICAgICAgICAgICAgICAgICAgICAgYWxsLnkgPSBUUlVFLCBieSA9ICJyb3cubmFtZXMiKQpyb3duYW1lcyhmYXZvcml0ZV9scnRfZGYpIDwtIGZhdm9yaXRlX2xydF9kZltbIlJvdy5uYW1lcyJdXQpmYXZvcml0ZV9scnRfZGZbWyJSb3cubmFtZXMiXV0gPC0gTlVMTAp3cml0dGVuIDwtIHdyaXRlX3hsc3goZGF0YT1mYXZvcml0ZV9scnRfZGYsCiAgICAgICAgICAgICAgICAgICAgICBleGNlbD1nbHVlOjpnbHVlKCJleGNlbC9scnRfY2xpbmljYWxfY2VsbHR5cGVfZmF2b3JpdGVzLXZ7dmVyfS54bHN4IikpCgpkZXNlcV9scnRfZGYgPC0gbWVyZ2UoaHNfYW5ub3QsIGFzLmRhdGEuZnJhbWUobHJ0X2NlbGx0eXBlX2NsaW5pY2FsX3Rlc3RbWyJkZXNlcV90YWJsZSJdXSksIGFsbC55PVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICBieT0icm93Lm5hbWVzIikKcm93bmFtZXMoZGVzZXFfbHJ0X2RmKSA8LSBkZXNlcV9scnRfZGZbWyJSb3cubmFtZXMiXV0KZGVzZXFfbHJ0X2RmW1siUm93Lm5hbWVzIl1dIDwtIE5VTEwKd3JpdHRlbiA8LSB3cml0ZV94bHN4KGRhdGE9ZGVzZXFfbHJ0X2RmLAogICAgICAgICAgICAgICAgICAgICAgZXhjZWw9Z2x1ZTo6Z2x1ZSgiZXhjZWwvbHJ0X2NsaW5pY2FsX2NlbGx0eXBlLXZ7dmVyfS54bHN4IikpCmxydF9jZWxsdHlwZV9jbGluaWNhbF90ZXN0JGNsdXN0ZXJfZGF0YSRwbG90CmBgYAoKIyBHZW5lIFNldCBBbmFseXNlcwoKVGhlIGdlbmUgc2V0cyB3ZSBhcmUgbW9zdCBsaWtlbHkgdG8gY29uc2lkZXIgYXJlIHRoZSByZXN1bHRzIG9mIHRoZQp2YXJpb3VzIHByZWNlZGluZyBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNlcy4KCiMjIEdTRUEKCiMjIyBDdXJlL0ZhaWwgZ3JvdXBzCgpJbiB0aGUgY29udGV4dCBvZiBjdXJlIHZzLiBmYWlsLCB3ZSBoYXZlIG1peGVkIGFuZCBtYXRjaGVkIHRoZSBkYXRhIGluCnF1aXRlIGEgZmV3IGRpZmZlcmVudCB3YXlzLgoKIyMjIyBDdXJlL0ZhaWwsIGFsbCBzYW1wbGVzCgpGb3IgdGhlIG1vbWVudCwgbGV0IHVzIGFzc3VtZSB0aGF0IHRoZSBkZWZhdWx0IGRlZmluaXRpb24gb2YKJ3NpZ25pZmljYW50JyBpcyBzdWZmaWNpZW50IGZvciB0aGVzZSBhbmFseXNlcywgd2l0aCB0aGUga25vd2xlZGdlCnRoYXQgaXMgbm90IGxpa2VseSB0byByZW1haW4gdHJ1ZS4gIEZvciBlYWNoIG9mIHRoZSBkaWZmZXJlbnRpYWwKZXhwcmVzc2lvbiBhbmFseXNlcywgSSB1c2VkIHRoZSAnc2lnX2V4Y2VsJyBhcmd1bWVudDsgdGhpcyBleHRyYWN0cyBieQpkZWZhdWx0IHRoZSBzZXQgb2YgZ2VuZXMgd2hpY2ggYXJlIHVwL2Rvd24gYnkgPj0gbG9nRkMgMS4wIHdpdGggYW4KYWRqdXN0ZWQgcHZhbHVlIDAuMDUgYXMgZGVmaW5lZCBieSBkZXNlcTIuCgpUaGUgcmVzdWx0aW5nIGRhdGEgc3RydWN0dXJlcyBhcmUgb3JnYW5pemVkIGFzOgoKdGhpbmdbWyJzaWduaWZpY2FudCJdXVtbImRlc2VxIl1dW1t1cHMiXV1bW2NvbnRyYXN0XV0KCkluIGFkZGl0aW9uLCB3ZSBoYXZlIGEgZmV3IG9udG9sb2d5LWVzcXVlIHRvb2xzIGF2YWlsYWJsZSwgc28gbGV0IHVzCm1peCBhbmQgbWF0Y2ggYW5kIHNlZSB3aGF0IHBvcHMgb3V0LgoKYGBge3IgZ3NlYV9jZl9hbGx9CmNmX2FsbF91cCA8LSBjZl9jbGluaWNhbF90YWJsZXNbWyJzaWduaWZpY2FudCJdXVtbImRlc2VxIl1dW1sidXBzIl1dW1siZmFpbF92c19jdXJlIl1dCmRpbShjZl9hbGxfdXApCmNmX2FsbF9kb3duIDwtIGNmX2NsaW5pY2FsX3RhYmxlc1tbInNpZ25pZmljYW50Il1dW1siZGVzZXEiXV1bWyJkb3ducyJdXVtbImZhaWxfdnNfY3VyZSJdXQpkaW0oY2ZfYWxsX2Rvd24pCgpjZl9hbGxfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcihjZl9hbGxfdXApCmNmX2FsbF91cF9ncFtbInB2YWx1ZV9wbG90cyJdXVtbInJlYWN0b21lX3Bsb3Rfb3ZlciJdXQpjZl9hbGxfdXBfZ3BbWyJwdmFsdWVfcGxvdHMiXV1bWyJrZWdnX3Bsb3Rfb3ZlciJdXQpjZl9hbGxfdXBfZ3BbWyJwdmFsdWVfcGxvdHMiXV1bWyJtZnBfcGxvdF9vdmVyIl1dCmNmX2FsbF91cF9ncFtbInB2YWx1ZV9wbG90cyJdXVtbImJwcF9wbG90X292ZXIiXV0KCmNmX2FsbF9kb3duX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoY2ZfYWxsX2Rvd24pCmNmX2FsbF9kb3duX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1sicmVhY3RvbWVfcGxvdF9vdmVyIl1dCmNmX2FsbF9kb3duX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1sia2VnZ19wbG90X292ZXIiXV0KY2ZfYWxsX2Rvd25fZ3BbWyJwdmFsdWVfcGxvdHMiXV1bWyJtZnBfcGxvdF9vdmVyIl1dCmNmX2FsbF9kb3duX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1siYnBwX3Bsb3Rfb3ZlciJdXQpgYGAKCiMjIyMgQ3VyZS9GYWlsLCBCaW9wc2llcwoKVGhlcmUgYXJlIG5vIGdlbmVzIGRlZW1lZCBzaWduaWZpY2FudCBpbiB0aGUgYmlvcHN5IGNvbXBhcmlzb25zIG9mCmN1cmUvZmFpbC4gIE9kZGx5LCB3aGVuIEkgbG9va2VkIG1hbnVhbGx5LCBJIHRob3VnaHQgSSBzYXcgb25lCmNhbmRpZGF0ZSBnZW5lLiAgSW4gYWRkaXRpb24sIHdoZW4gSSBzdGVwcGVkIHRocm91Z2ggdGhlIGZ1bmN0aW9uCm1hbnVhbGx5IEkgZ290IHRoZSBzYW1lIGdlbmUuLi4KCiMjIyMgQ3VyZS9GYWlsLCBNb25vY3l0ZXMKClRyeSBhZ2FpbiB3aXRoIG1vbm9jeXRlcy4KCmBgYHtyIGdzZWFfY2ZfbW9ub2N5dGV9CmNmX21vbm9jeXRlX3VwIDwtIGNmX21vbm9jeXRlX3RhYmxlc1tbInNpZ25pZmljYW50Il1dW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJmYWlsX3ZzX2N1cmUiXV0KZGltKGNmX21vbm9jeXRlX3VwKQpjZl9tb25vY3l0ZV9kb3duIDwtIGNmX21vbm9jeXRlX3RhYmxlc1tbInNpZ25pZmljYW50Il1dW1siZGVzZXEiXV1bWyJkb3ducyJdXVtbImZhaWxfdnNfY3VyZSJdXQpkaW0oY2ZfbW9ub2N5dGVfZG93bikKCmNmX21vbm9jeXRlX3VwX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoY2ZfbW9ub2N5dGVfdXApCmNmX21vbm9jeXRlX3VwX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1sicmVhY3RvbWVfcGxvdF9vdmVyIl1dCmNmX21vbm9jeXRlX3VwX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1sia2VnZ19wbG90X292ZXIiXV0KY2ZfbW9ub2N5dGVfdXBfZ3BbWyJwdmFsdWVfcGxvdHMiXV1bWyJicHBfcGxvdF9vdmVyIl1dCgpjZl9tb25vY3l0ZV9kb3duX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoY2ZfbW9ub2N5dGVfZG93bikKY2ZfbW9ub2N5dGVfZG93bl9ncFtbInB2YWx1ZV9wbG90cyJdXVtbInJlYWN0b21lX3Bsb3Rfb3ZlciJdXQpjZl9tb25vY3l0ZV9kb3duX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1sia2VnZ19wbG90X292ZXIiXV0KYGBgCgojIyMjIEN1cmUvRmFpbCwgTmV1dHJvcGhpbHMKCmBgYHtyIGdzZWFfY2ZfbmV1dHJvcGhpbH0KY2ZfbmV1dHJvcGhpbF91cCA8LSBjZl9uZXV0cm9waGlsX3RhYmxlc1tbInNpZ25pZmljYW50Il1dW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJmYWlsX3ZzX2N1cmUiXV0KZGltKGNmX25ldXRyb3BoaWxfdXApCmNmX25ldXRyb3BoaWxfZG93biA8LSBjZl9uZXV0cm9waGlsX3RhYmxlc1tbInNpZ25pZmljYW50Il1dW1siZGVzZXEiXV1bWyJkb3ducyJdXVtbImZhaWxfdnNfY3VyZSJdXQpkaW0oY2ZfbmV1dHJvcGhpbF9kb3duKQoKY2ZfbmV1dHJvcGhpbF91cF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKGNmX25ldXRyb3BoaWxfdXApCgpjZl9uZXV0cm9waGlsX2Rvd25fZ3AgPC0gc2ltcGxlX2dwcm9maWxlcihjZl9uZXV0cm9waGlsX2Rvd24pCmNmX25ldXRyb3BoaWxfZG93bl9ncFtbInB2YWx1ZV9wbG90cyJdXVtbImtlZ2dfcGxvdF9vdmVyIl1dCmBgYAoKIyMjIyBDdXJlL0ZhaWwsIEVvc2lub3BoaWxzCgpgYGB7ciBnc2VhX2NmX2Vvc2lub3BoaWx9CmNmX2Vvc2lub3BoaWxfdXAgPC0gY2ZfZW9zaW5vcGhpbF90YWJsZXNbWyJzaWduaWZpY2FudCJdXVtbImRlc2VxIl1dW1sidXBzIl1dW1siZmFpbF92c19jdXJlIl1dCmRpbShjZl9lb3Npbm9waGlsX3VwKQpjZl9lb3Npbm9waGlsX2Rvd24gPC0gY2ZfZW9zaW5vcGhpbF90YWJsZXNbWyJzaWduaWZpY2FudCJdXVtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJmYWlsX3ZzX2N1cmUiXV0KZGltKGNmX2Vvc2lub3BoaWxfZG93bikKCmNmX2Vvc2lub3BoaWxfdXBfZ3AgPC0gc2ltcGxlX2dwcm9maWxlcihjZl9lb3Npbm9waGlsX3VwKQpjZl9lb3Npbm9waGlsX3VwX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1sia2VnZ19wbG90X292ZXIiXV0KY2ZfZW9zaW5vcGhpbF91cF9ncFtbInB2YWx1ZV9wbG90cyJdXVtbInJlYWN0b21lX3Bsb3Rfb3ZlciJdXQpjZl9lb3Npbm9waGlsX3VwX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1sibWZwX3Bsb3Rfb3ZlciJdXQpjZl9lb3Npbm9waGlsX3VwX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1siYnBwX3Bsb3Rfb3ZlciJdXQoKY2ZfZW9zaW5vcGhpbF9kb3duX2dwIDwtIHNpbXBsZV9ncHJvZmlsZXIoY2ZfZW9zaW5vcGhpbF9kb3duKQpjZl9lb3Npbm9waGlsX2Rvd25fZ3BbWyJwdmFsdWVfcGxvdHMiXV1bWyJyZWFjdG9tZV9wbG90X292ZXIiXV0KY2ZfZW9zaW5vcGhpbF9kb3duX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1sibWZwX3Bsb3Rfb3ZlciJdXQpjZl9lb3Npbm9waGlsX2Rvd25fZ3BbWyJwdmFsdWVfcGxvdHMiXV1bWyJicHBfcGxvdF9vdmVyIl1dCmBgYAoKIyMjIyBDbGluaWNhbCBzYW1wbGVzCgpgYGB7ciBnc2VhX2NmX2NsaW5pY2FsfQpjZl9ub2Jpb3BzeV91cCA8LSBjZl9ub2Jpb3BzeV90YWJsZXNbWyJzaWduaWZpY2FudCJdXVtbImRlc2VxIl1dW1sidXBzIl1dW1siZmFpbF92c19jdXJlIl1dCmRpbShjZl9ub2Jpb3BzeV91cCkKY2Zfbm9iaW9wc3lfZG93biA8LSBjZl9ub2Jpb3BzeV90YWJsZXNbWyJzaWduaWZpY2FudCJdXVtbImRlc2VxIl1dW1siZG93bnMiXV1bWyJmYWlsX3ZzX2N1cmUiXV0KZGltKGNmX25vYmlvcHN5X2Rvd24pCgpjZl9ub2Jpb3BzeV91cF9ncCA8LSBzaW1wbGVfZ3Byb2ZpbGVyKGNmX25vYmlvcHN5X3VwKQpjZl9ub2Jpb3BzeV91cF9ncFtbInB2YWx1ZV9wbG90cyJdXVtbImtlZ2dfcGxvdF9vdmVyIl1dCmNmX25vYmlvcHN5X3VwX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1sicmVhY3RvbWVfcGxvdF9vdmVyIl1dCmNmX25vYmlvcHN5X3VwX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1sibWZwX3Bsb3Rfb3ZlciJdXQpjZl9ub2Jpb3BzeV91cF9ncFtbInB2YWx1ZV9wbG90cyJdXVtbImJwcF9wbG90X292ZXIiXV0KCmNmX25vYmlvcHN5X2Rvd25fZ3AgPC0gc2ltcGxlX2dwcm9maWxlcihjZl9ub2Jpb3BzeV9kb3duKQpjZl9ub2Jpb3BzeV9kb3duX2dwW1sicHZhbHVlX3Bsb3RzIl1dW1sicmVhY3RvbWVfcGxvdF9vdmVyIl1dCmNmX25vYmlvcHN5X2Rvd25fZ3BbWyJwdmFsdWVfcGxvdHMiXV1bWyJtZnBfcGxvdF9vdmVyIl1dCmNmX25vYmlvcHN5X2Rvd25fZ3BbWyJwdmFsdWVfcGxvdHMiXV1bWyJicHBfcGxvdF9vdmVyIl1dCmBgYAoKCgojIyMgQ2VsbCB0eXBlIGdyb3VwcwoKIyMjIFZpc2l0IGdyb3VwcwoKIyMgR1NWQQoKIyMjIENsaW5pY2FsIHNhbXBsZXMKCmBgYHtyIGdzdmEsIGZpZy5zaG93PSJoaWRlIn0KaHNfY2VsbHR5cGVfZ3N2YV9jMiA8LSBzbShzaW1wbGVfZ3N2YShoc192YWxpZCkpCmhzX2NlbGx0eXBlX2dzdmFfYzJfc2lnIDwtIHNtKGdldF9zaWdfZ3N2YV9jYXRlZ29yaWVzKAogICAgaHNfY2VsbHR5cGVfZ3N2YV9jMiwKICAgIGV4Y2VsPSJleGNlbC9pbmRpdmlkdWFsX2NlbGx0eXBlc19nc3ZhX2MyLnhsc3giKSkKIyMgYnJvYWRfYzcgPC0gR1NFQUJhc2U6OmdldEdtdCgicmVmZXJlbmNlL21zaWdkYi9jNy5hbGwudjcuMi5lbnRyZXouZ210IiwKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xsZWN0aW9uVHlwZT1HU0VBQmFzZTo6QnJvYWRDb2xsZWN0aW9uKGNhdGVnb3J5PSJjNyIpLAojIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVJZFR5cGU9R1NFQUJhc2U6OkVudHJleklkZW50aWZpZXIoKSkKIyMgaHNfY2VsbHR5cGVfZ3N2YV9jNyA8LSBzbShzaW1wbGVfZ3N2YShpbmRpdmlkdWFsX2NlbGx0eXBlcywgc2lnbmF0dXJlcz1icm9hZF9jNywKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2lnX3htbD0icmVmZXJlbmNlL21zaWdkYl92Ny4yLnhtbCIsIGNvcmVzPTEwKSkKaHNfY2VsbHR5cGVfZ3N2YV9jNyA8LSBzaW1wbGVfZ3N2YShpbmRpdmlkdWFsX2NlbGx0eXBlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduYXR1cmVzPSJyZWZlcmVuY2UvbXNpZ2RiL2M3LmFsbC52Ny4yLmVudHJlei5nbXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25hdHVyZV9jYXRlZ29yeT0iYzciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zaWdfeG1sPSJyZWZlcmVuY2UvbXNpZ2RiX3Y3LjIueG1sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3Jlcz0xMCkKCmhzX2NlbGx0eXBlX2dzdmFfYzdfc2lnIDwtIHNtKGdldF9zaWdfZ3N2YV9jYXRlZ29yaWVzKAogICAgaHNfY2VsbHR5cGVfZ3N2YV9jNywKICAgIGV4Y2VsPSJleGNlbC9pbmRpdmlkdWFsX2NlbGx0eXBlc19nc3ZhX2M3Lnhsc3giKSkKYGBgCgojIyMgUHJpbnQgc29tZSBwbG90cyBvZiB0aGUgR1NWQSBvdXRwdXRzCgpgYGB7ciBnc3ZhX3Bsb3RzfQojIyBUaGUgcmF3IGhlYXRtYXAgb2YgdGhlIEMyIHZhbHVlcwpoc19jZWxsdHlwZV9nc3ZhX2MyX3NpZ1tbInJhd19wbG90Il1dCiMjIFRoZSAnc2lnbmlmaWNhbmNlJyBzY29yZXMgb2YgdGhlIEMyIHZhbHVlcwpoc19jZWxsdHlwZV9nc3ZhX2MyX3NpZ1tbInNjb3JlX3Bsb3QiXV0KIyMgVGhlIHN1YnNldCBvZiBzY29yZXMgZm9yIGNhdGVnb3JpZXMgZGVlbWVkIHNpZ25pZmljYW50bHkgZGlmZmVyZW50Lgpoc19jZWxsdHlwZV9nc3ZhX2MyX3NpZ1tbInN1YnNldF9wbG90Il1dCgojIyBUaGUgcmF3IGhlYXRtYXAgb2YgdGhlIEM3IHZhbHVlcwpoc19jZWxsdHlwZV9nc3ZhX2M3X3NpZ1tbInJhd19wbG90Il1dCiMjIFRoZSAnc2lnbmlmaWNhbmNlJyBzY29yZXMgb2YgdGhlIEM3IHZhbHVlcwpoc19jZWxsdHlwZV9nc3ZhX2M3X3NpZ1tbInNjb3JlX3Bsb3QiXV0KIyMgVGhlIHN1YnNldCBvZiBzY29yZXMgZm9yIGNhdGVnb3JpZXMgZGVlbWVkIHNpZ25pZmljYW50bHkgZGlmZmVyZW50Lgpoc19jZWxsdHlwZV9nc3ZhX2M3X3NpZ1tbInN1YnNldF9wbG90Il1dCmBgYAo=