1 Introduction

This document is intended to provide a general overview of the TMRC2 samples which have thus far been sequenced. In some cases, this includes only those samples starting in 2019; in other instances I am including our previous (2015-2016) samples.

In all cases the processing performed was:

  1. Default trimming was performed.
  2. Hisat2 was used to map the remaining reads against the Leishmania panamensis genome revision 36.
  3. The alignments from hisat2 were used to count reads/gene against the revision 36 annotations with htseq.
  4. These alignments were also passed to the pileup functionality of samtools and the vcf/bcf utilities in order to make a matrix of all observed differences between each sample with respect to the reference.

The analyses in this document use the matrices of counts/gene from #3 and variants/position from #4 in order to provide some images and metrics describing the samples we have sequenced so far.

2 Annotations

Everything which follows depends on the Existing TriTrypDB annotations revision 46, circa 2019. The following block loads a database of these annotations and turns it into a matrix where the rows are genes and columns are all the annotation types provided by TriTrypDB.

The same database was used to create a matrix of orthologous genes between L.panamensis and all of the other species in the TriTrypDB.

tt <- sm(library(EuPathDB))
tt <- sm(library(org.Lpanamensis.MHOMCOL81L13.v46.eg.db))
pan_db <- org.Lpanamensis.MHOMCOL81L13.v46.eg.db
all_fields <- columns(pan_db)

all_lp_annot <- sm(load_orgdb_annotations(
    pan_db,
    keytype = "gid",
    fields = c("annot_gene_entrez_id", "annot_gene_name",
               "annot_strand", "annot_chromosome", "annot_cds_length",
               "annot_gene_product")))$genes

lp_go <- sm(load_orgdb_go(pan_db))
lp_lengths <- all_lp_annot[, c("gid", "annot_cds_length")]
colnames(lp_lengths)  <- c("ID", "length")

orthos <- sm(EuPathDB::extract_eupath_orthologs(db = pan_db))

hisat_annot <- all_lp_annot
## rownames(hisat_annot) <- paste0("exon_", rownames(hisat_annot), ".E1")

3 TODO:

Resequence samples: TMRC20002, TMRC20006, TMRC20004 (maybe TMRC20008 and TMRC20029)

3.1 Generate expressionsets

The first lines of the following block create the Expressionset. All of the following lines perform various normalizations and generate plots from it.

sample_sheet <- glue::glue("sample_sheets/tmrc2_samples_20210512.xlsx")

lp_expt <- sm(create_expt(sample_sheet,
                          gene_info = hisat_annot,
                          id_column = "hpglidentifier",
                          file_column = "lpanamensisv36hisatfile")) %>%
  set_expt_conditions(fact = "zymodemecategorical") %>%
  subset_expt(nonzero = 8550)
## The samples (and read coverage) removed when filtering 8550 non-zero genes are:
## TMRC20002 TMRC20006 
##  11681227   6670348
## There were 36, now there are 34 samples.
libsizes <- plot_libsize(lp_expt)
libsizes$plot

## I think samples 7,10 should be removed at minimum, probably also 9,11
nonzero <- plot_nonzero(lp_expt)
nonzero$plot
## Warning: ggrepel: 5 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

plot_boxplot(lp_expt)
## 2520 entries are 0.  We are on a log scale, adding 1 to the data.

3.2 Distribution Visualization

Najib’s favorite plots are of course the PCA/TNSE. These are nice to look at in order to get a sense of the relationships between samples. They also provide a good opportunity to see what happens when one applies different normalizations, surrogate analyses, filters, etc. In addition, one may set different experimental factors as the primary ‘condition’ (usually the color of plots) and surrogate ‘batches’.

3.3 Susceptilibity

Column ‘Q’ in the sample sheet, make a categorical version of it with these parameters:

  • 0 <= x <= 35 is resistant
  • 36 <= x <= 48 is ambiguous
  • 49 <= x is sensitive
starting <- as.numeric(pData(lp_expt)[["susceptibilityinfectionreduction32ugmlsbvhistoricaldata"]])
sus_categorical <- starting
na_idx <- is.na(starting)
sus_categorical[na_idx] <- "unknown"

resist_idx <- starting <= 0.35
sus_categorical[resist_idx] <- "resistant"
indeterminant_idx <- starting >= 0.36 & starting <= 0.48
sus_categorical[indeterminant_idx] <- "ambiguous"
susceptible_idx <- starting >= 0.49
sus_categorical[susceptible_idx] <- "sensitive"

pData(lp_expt$expressionset)[["sus_category"]] <- sus_categorical
clinical_samples <- lp_expt %>%
  set_expt_batches(fact = sus_categorical)

clinical_norm <- sm(normalize_expt(clinical_samples, norm = "quant", transform = "log2",
                                   convert = "cpm", batch = FALSE, filter = TRUE))
zymo_pca <- plot_pca(clinical_norm, plot_title = "PCA of parasite expression values")
pp(file = "images/zymo_pca_sus_shape.png", image = zymo_pca$plot)
## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure

## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure

## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure

## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure

zymo_3dpca <- plot_3d_pca(zymo_pca)
zymo_3dpca$plot
zymo_tsne <- plot_tsne(clinical_norm, plot_title = "TSNE of parasite expression values")
zymo_tsne$plot

clinical_nb <- normalize_expt(clinical_samples, convert = "cpm", transform = "log2",
                         filter = TRUE, batch = "svaseq")
## Removing 142 low-count genes (8636 remaining).
## batch_counts: Before batch/surrogate estimation, 616 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 1614 entries are 0<x<1: 1%.
## Setting 158 low elements to zero.
## transform_counts: Found 158 values equal to 0, adding 1 to the matrix.
clinical_nb_pca <- plot_pca(clinical_nb, plot_title = TRUE)
pp(file = "images/clinical_nb_pca_sus_shape.png", image = clinical_nb_pca$plot)

clinical_nb_tsne <- plot_tsne(clinical_nb)
clinical_nb_tsne$plot
## Warning: ggrepel: 11 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

corheat <- plot_corheat(clinical_norm, title = "Correlation heatmap of parasite expression values
(Same legend as above)")
corheat$plot

plot_sm(clinical_norm)$plot
## Performing correlation.

3.4 Cure/Fail status

cf_expt <- set_expt_conditions(lp_expt, fact = "clinicalcategorical") %>%
  set_expt_batches(fact = sus_categorical)

cf_norm <- normalize_expt(cf_expt, convert = "cpm", transform = "log2",
                          norm = "quant", filter = TRUE)
## Removing 142 low-count genes (8636 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
start_cf <- plot_pca(cf_norm)
pp(file = "images/cf_sus_shape.png", image = start_cf$plot)

cf_nb <- normalize_expt(cf_expt, convert = "cpm", transform = "log2",
                        norm = "quant", filter = TRUE, batch = "svaseq")
## Warning in normalize_expt(cf_expt, convert = "cpm", transform = "log2", :
## Quantile normalization and sva do not always play well together.
## Removing 142 low-count genes (8636 remaining).
## batch_counts: Before batch/surrogate estimation, 2 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 2074 entries are 0<x<1: 1%.
## Setting 48 low elements to zero.
## transform_counts: Found 48 values equal to 0, adding 1 to the matrix.
cf_nb_pca <- plot_pca(cf_nb)
pp(file = "images/cf_sus_share_nb.png", image = cf_nb_pca$plot)

cf_norm <- normalize_expt(cf_expt, transform = "log2", convert = "cpm",
                          filter = TRUE, norm = "quant")
## Removing 142 low-count genes (8636 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
test <- pca_information(cf_norm,
                        expt_factors = c("clinicalcategorical", "zymodemecategorical",
                                         "pathogenstrain", "passagenumber"),
                        num_components = 6, plot_pcas = TRUE)
## More shallow curves in these plots suggest more genes in this principle component.
sus_expt <- set_expt_conditions(lp_expt, fact = "sus_category") %>%
  set_expt_batches(fact = "zymodemecategorical")
sus_norm <- normalize_expt(sus_expt, transform = "log2", convert = "cpm",
                           norm = "quant", filter = TRUE)
## Removing 142 low-count genes (8636 remaining).
## transform_counts: Found 2 values equal to 0, adding 1 to the matrix.
sus_pca <- plot_pca(sus_norm)
sus_pca$plot

sus_nb <- normalize_expt(sus_expt, transform = "log2", convert = "cpm",
                         batch = "svaseq", filter = TRUE)
## Removing 142 low-count genes (8636 remaining).
## batch_counts: Before batch/surrogate estimation, 616 entries are x==0: 0%.
## batch_counts: Before batch/surrogate estimation, 1614 entries are 0<x<1: 1%.
## Setting 103 low elements to zero.
## transform_counts: Found 103 values equal to 0, adding 1 to the matrix.
sus_nb_pca <- plot_pca(sus_nb)
pp(file = "images/sus_nb_pca.png", image = sus_nb_pca$plot)

3.4.1 Notes

The following samples are much lower coverage:

  • TMRC20002
  • TMRC20006
  • TMRC20007
  • TMRC20008

At this time, we do not have very many samples, so the set of metrics/plots is fairly limited. There is really only one factor in the metadata which we can use for performing differential expression analyses, the ‘zymodeme’.

4 Sample Estimation

The process of sample estimation takes two primary inputs:

  1. The sample sheet, which contains all the metadata we currently have on hand, including filenames for the outputs of #3 and #4 above.
  2. The gene annotations.

An expressionset is primary data structure used in R to examine RNASeq data. It is comprised of annotations, metadata, and expression data. In the case of our processing pipeline, the location of the expression data is provided by the filenames in the metadata.

5 Zymodeme analyses

The following sections perform a series of analyses which seek to elucidate differences between the zymodemes 2.2 and 2.3 either through differential expression or variant profiles.

5.1 Differential expression

5.1.1 With respect to zymodeme attribution

TODO: Do this with and without sva and compare the results.

zy_expt <- subset_expt(lp_expt, subset = "condition=='z2.2'|condition=='z2.3'")
## There were 34, now there are 19 samples.
zy_norm <- normalize_expt(zy_expt, filter = TRUE, convert = "cpm", norm = "quant")
## Removing 168 low-count genes (8610 remaining).
zy_de_nobatch <- sm(all_pairwise(zy_expt, filter = TRUE, model_batch = "svaseq"))
zy_de <- sm(all_pairwise(zy_expt, filter = TRUE, model_batch = "svaseq"))
zy_table <- sm(combine_de_tables(zy_de, excel = glue::glue("excel/zy_tables-v{ver}.xlsx")))
zy_sig <- sm(extract_significant_genes(zy_table, excel = glue::glue("excel/zy_sig-v{ver}.xlsx")))

5.1.2 Images of zymodeme DE

zy_table[["plots"]][["z23_vs_z22"]][["deseq_ma_plots"]][["plot"]]

5.2 With respect to cure/failure

cf_de <- sm(all_pairwise(cf_expt, filter = TRUE, model_batch = "svaseq"))
cf_table <- sm(combine_de_tables(cf_de, excel = glue::glue("excel/cf_tables-v{ver}.xlsx")))
cf_sig <- sm(extract_significant_genes(cf_table, excel = glue::glue("excel/cf_sig-v{ver}.xlsx")))

5.3 With respect to susceptibility

sus_de <- sm(all_pairwise(sus_expt, filter = TRUE, model_batch = "svaseq"))
sus_table <- sm(combine_de_tables(sus_de, excel = glue::glue("excel/sus_tables-v{ver}.xlsx")))
sus_sig <- sm(extract_significant_genes(sus_table, excel = glue::glue("excel/sus_sig-v{ver}.xlsx")))
## Error: Sheet 'down_limma_sensitive_vs_ambiguous' does not exist.

5.4 Ontology searches

## Gene categories more represented in the 2.3 group.
zy_go_up <- sm(simple_goseq(sig_genes = zy_sig[["deseq"]][["ups"]][[1]],
                            go_db = lp_go, length_db = lp_lengths))

## Gene categories more represented in the 2.2 group.
zy_go_down <- sm(simple_goseq(sig_genes = zy_sig[["deseq"]][["downs"]][[1]],
                              go_db = lp_go, length_db = lp_lengths))

5.4.1 A couple plots from the differential expression

5.4.1.1 Number of genes in agreement among DE methods, 2.3 more than 2.2

zy_table[["venns"]][[1]][["p_lfc1"]][["up_noweight"]]

5.4.1.2 Number of genes in agreement among DE methods, 2.2 more than 2.3

zy_table[["venns"]][[1]][["p_lfc1"]][["down_noweight"]]

5.4.1.3 MA plot of the differential expression between the zymodemes.

zy_table$plots[[1]][["deseq_ma_plots"]][["plot"]]

5.4.1.4 goseq ontology plots of groups of genes, 2.3 more than 2.2

zy_go_up$pvalue_plots$bpp_plot_over

5.4.1.5 goseq ontology plots of groups of genes, 2.2 more than 2.3

zy_go_down$pvalue_plots$bpp_plot_over

5.5 Zymodeme enzyme gene IDs

Najib read me an email listing off the gene names associated with the zymodeme classification. I took those names and cross referenced them against the Leishmania panamensis gene annotations and found the following:

They are:

  1. ALAT: LPAL13_120010900 – alanine aminotransferase
  2. ASAT: LPAL13_340013000 – aspartate aminotransferase
  3. G6PD: LPAL13_000054100 – glucase-6-phosphate 1-dehydrogenase
  4. NH: LPAL13_14006100, LPAL13_180018500 – inosine-guanine nucleoside hydrolase
  5. MPI: LPAL13_320022300 (maybe) – mannose phosphate isomerase (I chose phosphomannose isomerase)

Given these 6 gene IDs (NH has two gene IDs associated with it), I can do some looking for specific differences among the various samples.

5.5.1 Expression levels of zymodeme genes

The following creates a colorspace (red to green) heatmap showing the observed expression of these genes in every sample.

my_genes <- c("LPAL13_120010900", "LPAL13_340013000", "LPAL13_000054100",
              "LPAL13_140006100", "LPAL13_180018500", "LPAL13_320022300",
              "other")
my_names <- c("ALAT", "ASAT", "G6PD", "NHv1", "NHv2", "MPI", "other")

zymo_expt <- exclude_genes_expt(zy_norm, ids = my_genes, method = "keep")
## Before removal, there were 8610 genes, now there are 6.
## There are 19 samples which kept less than 90 percent counts.
## TMRC20001 TMRC20004 TMRC20005 TMRC20009 TMRC20010 TMRC20011 TMRC20012 TMRC20013 
##    0.1284    0.1179    0.1289    0.1106    0.1078    0.1076    0.1180    0.1181 
## TMRC20014 TMRC20015 TMRC20016 TMRC20017 TMRC20018 TMRC20021 TMRC20022 TMRC20037 
##    0.1065    0.1124    0.1040    0.1039    0.1119    0.1043    0.1273    0.1077 
## TMRC20038 TMRC20039 TMRC20041 
##    0.1104    0.1265    0.1149
test <- plot_sample_heatmap(zymo_expt, row_label = my_names)

5.6 Empirically observed Zymodeme genes from differential expression analysis

In contrast, the following plots take the set of genes which are shared among all differential expression methods (|lfc| >= 1.0 and adjp <= 0.05) and use them to make categories of genes which are increased in 2.3 or 2.2.

shared_zymo <- intersect_significant(zy_table)
## Deleting the file excel/intersect_significant.xlsx before writing the tables.
## The png file name did not exist: /tmp/RtmpluwWvL/figureImage2686111d05598.png
## The png file name did not exist: /tmp/RtmpluwWvL/figureImage268611e04d22c.png
up_shared <- shared_zymo[["ups"]][[1]][["data"]][["all"]]
rownames(up_shared)
##  [1] "LPAL13_000033300" "LPAL13_000012000" "LPAL13_310031300" "LPAL13_000038400"
##  [5] "LPAL13_000038500" "LPAL13_340039600" "LPAL13_000012100" "LPAL13_050005000"
##  [9] "LPAL13_310039200" "LPAL13_310031000" "LPAL13_210015500" "LPAL13_270034100"
## [13] "LPAL13_250006300" "LPAL13_200013000" "LPAL13_180013900" "LPAL13_340039700"
## [17] "LPAL13_240009700" "LPAL13_000041000" "LPAL13_170015400" "LPAL13_330021800"
## [21] "LPAL13_140019300" "LPAL13_000052700" "LPAL13_350044000" "LPAL13_140019100"
## [25] "LPAL13_230011200" "LPAL13_210005000" "LPAL13_350073200" "LPAL13_320038700"
## [29] "LPAL13_000045100" "LPAL13_140019200" "LPAL13_250025700" "LPAL13_110015700"
## [33] "LPAL13_310028500" "LPAL13_230011500" "LPAL13_000010600" "LPAL13_300031600"
## [37] "LPAL13_230011400" "LPAL13_290016200" "LPAL13_230011300" "LPAL13_160014500"
upshared_expt <- exclude_genes_expt(zy_norm, ids = rownames(up_shared), method = "keep")
## Before removal, there were 8610 genes, now there are 40.
## There are 19 samples which kept less than 90 percent counts.
## TMRC20001 TMRC20004 TMRC20005 TMRC20009 TMRC20010 TMRC20011 TMRC20012 TMRC20013 
##    0.5356    0.1920    0.1769    0.2296    0.5546    0.2145    0.1687    0.5566 
## TMRC20014 TMRC20015 TMRC20016 TMRC20017 TMRC20018 TMRC20021 TMRC20022 TMRC20037 
##    0.2280    0.6536    0.4918    0.2996    0.6599    0.6270    0.1976    0.7428 
## TMRC20038 TMRC20039 TMRC20041 
##    0.8350    0.2498    0.2058

5.6.1 Heatmap of zymodeme gene expression increased in 2.3 vs. 2.2

test <- plot_sample_heatmap(upshared_expt, row_label = rownames(up_shared))

5.6.2 Heatmap of zymodeme gene expression increased in 2.2 vs. 2.3

down_shared <- shared_zymo[["downs"]][[1]][["data"]][["all"]]
downshared_expt <- exclude_genes_expt(zy_norm, ids = rownames(down_shared), method = "keep")
## Before removal, there were 8610 genes, now there are 80.
## There are 19 samples which kept less than 90 percent counts.
## TMRC20001 TMRC20004 TMRC20005 TMRC20009 TMRC20010 TMRC20011 TMRC20012 TMRC20013 
##    0.3529    1.3024    1.3099    1.4313    0.2267    1.2342    1.0394    0.2470 
## TMRC20014 TMRC20015 TMRC20016 TMRC20017 TMRC20018 TMRC20021 TMRC20022 TMRC20037 
##    1.3079    0.2921    0.2820    1.3420    0.3103    0.2909    1.5385    0.3659 
## TMRC20038 TMRC20039 TMRC20041 
##    0.3413    1.4869    1.4842
test <- plot_sample_heatmap(downshared_expt, row_label = rownames(down_shared))

6 SNP profiles

In this block, I am combining our previous samples and our new samples in the hopes of finding variant positions which help elucidate aspects of either the new or old samples. In other words, we do not know the zymodeme annotations for the old samples nor the strain identities (or the shortcut ‘chronic vs. self-healing’) for the new samples. We may be able to make educated guesses given the variant profiles. There are some differences in how the previous and current data sets were analyzed (though I have since redone the old samples so it should be trivial to remove those differences now).

old_expt <- sm(create_expt("sample_sheets/tmrc2_samples_20191203.xlsx",
                           file_column = "tophat2file"))

tt <- lp_expt$expressionset
rownames(tt) <- gsub(pattern = "^exon_", replacement = "", x = rownames(tt))
rownames(tt) <- gsub(pattern = "\\.E1$", replacement = "", x = rownames(tt))
lp_expt$expressionset <- tt

tt <- old_expt$expressionset
rownames(tt) <- gsub(pattern = "^exon_", replacement = "", x = rownames(tt))
rownames(tt) <- gsub(pattern = "\\.1$", replacement = "", x = rownames(tt))
old_expt$expressionset <- tt

lp_snp <- subset_expt(lp_expt, subset="!is.na(pData(lp_expt)[['bcftable']])")
## There were 34, now there are 28 samples.
new_snps <- sm(count_expt_snps(lp_snp, annot_column = "bcftable"))
old_snps <- sm(count_expt_snps(old_expt, annot_column = "bcftable", snp_column = 2))

both_snps <- combine_expts(new_snps, old_snps)
both_norm <- sm(normalize_expt(both_snps, transform = "log2", convert = "cpm", filter = TRUE))

## strains <- both_norm[["design"]][["strain"]]
both_norm <- set_expt_conditions(both_norm, fact = "strain")

6.1 Plot of SNP profiles for zymodemes

The following plot shows the SNP profiles of all samples (old and new) where the colors at the top show either the 2.2 strains (orange), 2.3 strains (green), the previous samples (purple), or the various lab strains (pink etc).

tt <- plot_disheat(both_norm)
pp(file = "images/raw_snp_disheat.png", image = tt, height = 12, width = 12)

snp_sets <- get_snp_sets(both_snps, factor = "condition")
## The factor z2.3 has 7 rows.
## The factor z2.2 has 8 rows.
## The factor unknown has 13 rows.
## The factor sh has 13 rows.
## The factor chr has 14 rows.
## The factor inf has 6 rows.
## Iterating over 727 elements.
both_expt <- combine_expts(lp_expt, old_expt)
snp_genes <- sm(snps_vs_genes(both_expt, snp_sets, expt_name_col = "chromosome"))

summary(snp_sets$medians)
##       z2.3           z2.2         unknown           sh        
##  Min.   :   0   Min.   :   0   Min.   :   0   Min.   :   0.0  
##  1st Qu.:   0   1st Qu.:   0   1st Qu.:   0   1st Qu.:   0.0  
##  Median :   0   Median :   0   Median :   0   Median :   0.0  
##  Mean   :  15   Mean   :   0   Mean   :   0   Mean   :   0.1  
##  3rd Qu.:   0   3rd Qu.:   0   3rd Qu.:   0   3rd Qu.:   0.0  
##  Max.   :6407   Max.   :4868   Max.   :6539   Max.   :1229.0  
##      chr                 inf        
##  Length:635506      Min.   :  0.00  
##  Class :character   1st Qu.:  0.00  
##  Mode  :character   Median :  0.00  
##                     Mean   :  0.01  
##                     3rd Qu.:  0.00  
##                     Max.   :151.00
head(snp_sets$medians, n=100)
##                                             z2.3 z2.2 unknown  sh
## chr_LPAL13-SCAF000001_pos_1019_ref_G_alt_A    95    0       0   0
## chr_LPAL13-SCAF000001_pos_106_ref_A_alt_G      0    0       0   0
## chr_LPAL13-SCAF000001_pos_1092_ref_A_alt_G    93    0       0   0
## chr_LPAL13-SCAF000001_pos_111_ref_A_alt_G      0    0       0   0
## chr_LPAL13-SCAF000001_pos_1138_ref_C_alt_A     0    0       0   0
## chr_LPAL13-SCAF000001_pos_1147_ref_C_alt_A     0    0       0   0
## chr_LPAL13-SCAF000001_pos_1290_ref_A_alt_G    92    0       0   0
## chr_LPAL13-SCAF000001_pos_1394_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000001_pos_1424_ref_A_alt_C     0    0       0   0
## chr_LPAL13-SCAF000001_pos_1477_ref_T_alt_C     0    0       0   0
## chr_LPAL13-SCAF000001_pos_148_ref_T_alt_A      0    0       0   0
## chr_LPAL13-SCAF000001_pos_1502_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000001_pos_1507_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000001_pos_1535_ref_A_alt_G     0    0       0   0
## chr_LPAL13-SCAF000001_pos_1622_ref_C_alt_T     0    0       0   0
## chr_LPAL13-SCAF000001_pos_1647_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000001_pos_1672_ref_A_alt_G     0    0       0   0
## chr_LPAL13-SCAF000001_pos_179_ref_G_alt_A      0    0       0   0
## chr_LPAL13-SCAF000001_pos_188_ref_T_alt_C      0    0       0   0
## chr_LPAL13-SCAF000001_pos_261_ref_G_alt_A     14    0       0   0
## chr_LPAL13-SCAF000001_pos_56_ref_T_alt_C       0    0       0   0
## chr_LPAL13-SCAF000001_pos_583_ref_C_alt_T      0    0       0   0
## chr_LPAL13-SCAF000001_pos_81_ref_A_alt_T       0    0       0   0
## chr_LPAL13-SCAF000001_pos_870_ref_T_alt_C      0    0       0   0
## chr_LPAL13-SCAF000001_pos_874_ref_T_alt_C    169    0       0   0
## chr_LPAL13-SCAF000001_pos_887_ref_G_alt_C      0    0       0   0
## chr_LPAL13-SCAF000001_pos_931_ref_T_alt_C      0    0       0   0
## chr_LPAL13-SCAF000002_pos_1125_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000002_pos_1135_ref_A_alt_G     0    0       0   0
## chr_LPAL13-SCAF000002_pos_1159_ref_C_alt_T     0    0       0   0
## chr_LPAL13-SCAF000002_pos_1189_ref_C_alt_T     0    0       0   0
## chr_LPAL13-SCAF000002_pos_133_ref_C_alt_T      0    0       0   0
## chr_LPAL13-SCAF000002_pos_1504_ref_A_alt_G     0    0       0   0
## chr_LPAL13-SCAF000002_pos_1549_ref_C_alt_T     0    0       0   0
## chr_LPAL13-SCAF000002_pos_157_ref_G_alt_A      0    0       0   0
## chr_LPAL13-SCAF000002_pos_1596_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000002_pos_1630_ref_C_alt_T     0    0       0   0
## chr_LPAL13-SCAF000002_pos_1660_ref_C_alt_T     0    0       0   0
## chr_LPAL13-SCAF000002_pos_175_ref_C_alt_T      0    0       0   0
## chr_LPAL13-SCAF000002_pos_1803_ref_C_alt_T     0    0       0   0
## chr_LPAL13-SCAF000002_pos_1837_ref_A_alt_G     0    0       0   0
## chr_LPAL13-SCAF000002_pos_231_ref_G_alt_A      0    0       0   0
## chr_LPAL13-SCAF000002_pos_275_ref_A_alt_G      0    0       0   0
## chr_LPAL13-SCAF000002_pos_297_ref_A_alt_G      0    0       0   0
## chr_LPAL13-SCAF000002_pos_302_ref_T_alt_C      0    0       0   0
## chr_LPAL13-SCAF000002_pos_389_ref_T_alt_A      0    0       0   0
## chr_LPAL13-SCAF000002_pos_415_ref_A_alt_G      0    0       0   0
## chr_LPAL13-SCAF000002_pos_422_ref_C_alt_T      0    0       0   0
## chr_LPAL13-SCAF000002_pos_521_ref_C_alt_G      0    0       0   0
## chr_LPAL13-SCAF000002_pos_62_ref_A_alt_G       0    0       0   0
## chr_LPAL13-SCAF000002_pos_762_ref_A_alt_C      0    0       0   0
## chr_LPAL13-SCAF000002_pos_977_ref_T_alt_C     11    0       0   0
## chr_LPAL13-SCAF000003_pos_10002_ref_G_alt_A   15    0       0   0
## chr_LPAL13-SCAF000003_pos_1132_ref_T_alt_C     0    0       0   0
## chr_LPAL13-SCAF000003_pos_1170_ref_C_alt_T     0    0       0   0
## chr_LPAL13-SCAF000003_pos_123_ref_T_alt_C     30    0       0   0
## chr_LPAL13-SCAF000003_pos_124_ref_T_alt_G     30    0       0   0
## chr_LPAL13-SCAF000003_pos_1310_ref_C_alt_T     0    0       0   0
## chr_LPAL13-SCAF000003_pos_1392_ref_C_alt_G     0    0       0   0
## chr_LPAL13-SCAF000003_pos_1488_ref_A_alt_G     0    0       0   0
## chr_LPAL13-SCAF000003_pos_1501_ref_C_alt_G     0    0       0   0
## chr_LPAL13-SCAF000003_pos_1518_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000003_pos_177_ref_G_alt_A      0    0       0   0
## chr_LPAL13-SCAF000003_pos_19_ref_T_alt_C       0    0       0   0
## chr_LPAL13-SCAF000003_pos_2560_ref_T_alt_C     0    0       0   0
## chr_LPAL13-SCAF000003_pos_281_ref_G_alt_A      0    0       0   0
## chr_LPAL13-SCAF000003_pos_2964_ref_T_alt_C  6061 4095    6045 453
## chr_LPAL13-SCAF000003_pos_3409_ref_A_alt_G     0    0       0   0
## chr_LPAL13-SCAF000003_pos_4517_ref_T_alt_C     0    0       0   0
## chr_LPAL13-SCAF000003_pos_530_ref_C_alt_T      0    0       0   0
## chr_LPAL13-SCAF000003_pos_5637_ref_A_alt_G     0    0       0   0
## chr_LPAL13-SCAF000003_pos_5646_ref_A_alt_G   343    0       0   0
## chr_LPAL13-SCAF000003_pos_5653_ref_A_alt_G     0    0       0   0
## chr_LPAL13-SCAF000003_pos_5810_ref_T_alt_C     0    0       0   0
## chr_LPAL13-SCAF000003_pos_5882_ref_C_alt_T     0    0       0   0
## chr_LPAL13-SCAF000003_pos_6037_ref_G_alt_T     0    0       0   0
## chr_LPAL13-SCAF000003_pos_6360_ref_C_alt_T     0    0       0   0
## chr_LPAL13-SCAF000003_pos_8678_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000003_pos_8776_ref_A_alt_C     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9085_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9096_ref_G_alt_C     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9189_ref_C_alt_A     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9313_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9512_ref_C_alt_T  1115    0       0   0
## chr_LPAL13-SCAF000003_pos_9562_ref_T_alt_C     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9563_ref_A_alt_C   791    0       0   0
## chr_LPAL13-SCAF000003_pos_9589_ref_T_alt_C     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9618_ref_G_alt_T     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9633_ref_C_alt_T     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9644_ref_T_alt_C   134    0       0   0
## chr_LPAL13-SCAF000003_pos_9697_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9703_ref_A_alt_G    17    0       0   0
## chr_LPAL13-SCAF000003_pos_9732_ref_T_alt_A    12    0       0   0
## chr_LPAL13-SCAF000003_pos_9779_ref_T_alt_C     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9781_ref_A_alt_G     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9880_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9903_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9919_ref_A_alt_C     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9964_ref_G_alt_A     0    0       0   0
## chr_LPAL13-SCAF000003_pos_9980_ref_A_alt_C     0    0       0   0
##                                                           chr inf
## chr_LPAL13-SCAF000001_pos_1019_ref_G_alt_A  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_106_ref_A_alt_G   LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1092_ref_A_alt_G  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_111_ref_A_alt_G   LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1138_ref_C_alt_A  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1147_ref_C_alt_A  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1290_ref_A_alt_G  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1394_ref_G_alt_A  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1424_ref_A_alt_C  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1477_ref_T_alt_C  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_148_ref_T_alt_A   LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1502_ref_G_alt_A  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1507_ref_G_alt_A  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1535_ref_A_alt_G  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1622_ref_C_alt_T  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1647_ref_G_alt_A  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_1672_ref_A_alt_G  LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_179_ref_G_alt_A   LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_188_ref_T_alt_C   LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_261_ref_G_alt_A   LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_56_ref_T_alt_C    LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_583_ref_C_alt_T   LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_81_ref_A_alt_T    LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_870_ref_T_alt_C   LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_874_ref_T_alt_C   LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_887_ref_G_alt_C   LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000001_pos_931_ref_T_alt_C   LPAL13-SCAF000001   0
## chr_LPAL13-SCAF000002_pos_1125_ref_G_alt_A  LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_1135_ref_A_alt_G  LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_1159_ref_C_alt_T  LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_1189_ref_C_alt_T  LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_133_ref_C_alt_T   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_1504_ref_A_alt_G  LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_1549_ref_C_alt_T  LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_157_ref_G_alt_A   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_1596_ref_G_alt_A  LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_1630_ref_C_alt_T  LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_1660_ref_C_alt_T  LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_175_ref_C_alt_T   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_1803_ref_C_alt_T  LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_1837_ref_A_alt_G  LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_231_ref_G_alt_A   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_275_ref_A_alt_G   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_297_ref_A_alt_G   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_302_ref_T_alt_C   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_389_ref_T_alt_A   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_415_ref_A_alt_G   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_422_ref_C_alt_T   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_521_ref_C_alt_G   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_62_ref_A_alt_G    LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_762_ref_A_alt_C   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000002_pos_977_ref_T_alt_C   LPAL13-SCAF000002   0
## chr_LPAL13-SCAF000003_pos_10002_ref_G_alt_A LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_1132_ref_T_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_1170_ref_C_alt_T  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_123_ref_T_alt_C   LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_124_ref_T_alt_G   LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_1310_ref_C_alt_T  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_1392_ref_C_alt_G  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_1488_ref_A_alt_G  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_1501_ref_C_alt_G  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_1518_ref_G_alt_A  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_177_ref_G_alt_A   LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_19_ref_T_alt_C    LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_2560_ref_T_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_281_ref_G_alt_A   LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_2964_ref_T_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_3409_ref_A_alt_G  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_4517_ref_T_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_530_ref_C_alt_T   LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_5637_ref_A_alt_G  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_5646_ref_A_alt_G  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_5653_ref_A_alt_G  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_5810_ref_T_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_5882_ref_C_alt_T  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_6037_ref_G_alt_T  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_6360_ref_C_alt_T  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_8678_ref_G_alt_A  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_8776_ref_A_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9085_ref_G_alt_A  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9096_ref_G_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9189_ref_C_alt_A  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9313_ref_G_alt_A  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9512_ref_C_alt_T  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9562_ref_T_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9563_ref_A_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9589_ref_T_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9618_ref_G_alt_T  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9633_ref_C_alt_T  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9644_ref_T_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9697_ref_G_alt_A  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9703_ref_A_alt_G  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9732_ref_T_alt_A  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9779_ref_T_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9781_ref_A_alt_G  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9880_ref_G_alt_A  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9903_ref_G_alt_A  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9919_ref_A_alt_C  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9964_ref_G_alt_A  LPAL13-SCAF000003   0
## chr_LPAL13-SCAF000003_pos_9980_ref_A_alt_C  LPAL13-SCAF000003   0
snp_subset <- sm(snp_subset_genes(
  both_expt, both_snps,
  genes = c("LPAL13_120010900", "LPAL13_340013000", "LPAL13_000054100",
          "LPAL13_140006100", "LPAL13_180018500", "LPAL13_320022300")))
## zymo_heat <- plot_sample_heatmap(snp_subset, row_label = rownames(exprs(snp_subset)))

7 Clinical response for new samples

clinical_sets <- get_snp_sets(new_snps, factor = "clinicalresponse")
## The factor Cure has 9 rows.
## The factor Failure has 12 rows.
## The factor Laboratory line has 2 rows.
## The factor Laboratory line miltefosine resistant  has only 1 row.
## The factor ND has only 1 row.
## The factor Reference strain has 3 rows.
## Iterating over 686 elements.
clinical_genes <- sm(snps_vs_genes(lp_expt, clinical_sets, expt_name_col = "chromosome"))
clinical_snps <- snps_intersections(lp_expt, clinical_sets, chr_column = "chromosome")
head(as.data.frame(clinical_snps$inters[["Failure"]]))
##                                       seqnames  start    end width strand
## chr_LpaL13-02_pos_205839_ref_C_alt_T LpaL13-02 205839 205840     2      +
## chr_LpaL13-03_pos_107522_ref_T_alt_C LpaL13-03 107522 107523     2      +
## chr_LpaL13-05_pos_161416_ref_T_alt_C LpaL13-05 161416 161417     2      +
## chr_LpaL13-06_pos_342394_ref_G_alt_C LpaL13-06 342394 342395     2      +
## chr_LpaL13-07_pos_280944_ref_A_alt_G LpaL13-07 280944 280945     2      +
## chr_LpaL13-07_pos_387049_ref_C_alt_T LpaL13-07 387049 387050     2      +
head(as.data.frame(clinical_snps$inters[["Cure"]]))
##                                       seqnames  start    end width strand
## chr_LpaL13-03_pos_189630_ref_C_alt_A LpaL13-03 189630 189631     2      +
## chr_LpaL13-04_pos_37865_ref_G_alt_A  LpaL13-04  37865  37866     2      +
## chr_LpaL13-04_pos_37867_ref_A_alt_G  LpaL13-04  37867  37868     2      +
## chr_LpaL13-05_pos_340999_ref_G_alt_A LpaL13-05 340999 341000     2      +
## chr_LpaL13-06_pos_288177_ref_C_alt_G LpaL13-06 288177 288178     2      +
## chr_LpaL13-10_pos_203841_ref_C_alt_T LpaL13-10 203841 203842     2      +
head(clinical_snps$gene_summaries$Failure)
## LPAL13_300019900 LPAL13_000017900 LPAL13_100008800 LPAL13_200008500 
##                3                2                2                2 
## LPAL13_200014300 LPAL13_200021200 
##                2                2
head(clinical_snps$gene_summaries$Cure)
## LPAL13_040006400 LPAL13_200013000 LPAL13_200014600 LPAL13_200015100 
##                2                2                2                2 
## LPAL13_200017900 LPAL13_200019500 
##                2                2
annot <- fData(lp_expt)
clinical_interest <- as.data.frame(clinical_snps[["gene_summaries"]][["Cure"]])
clinical_interest <- merge(clinical_interest, as.data.frame(clinical_snps[["gene_summaries"]][["Failure"]]), by = "row.names")
rownames(clinical_interest) <- clinical_interest[["Row.names"]]
clinical_interest[["Row.names"]] <- NULL
colnames(clinical_interest) <- c("cure_snps","fail_snps")
annot <- merge(annot, clinical_interest, by = "row.names")
rownames(annot) <- annot[["Row.names"]]
annot[["Row.names"]] <- NULL
fData(lp_expt$expressionset) <- annot

8 Zymodeme for new samples

The heatmap produced here should show the variants only for the zymodeme genes.

8.1 Hunt for snp clusters

I am thinking that if we find clusters of locations which are variant, that might provide some PCR testing possibilities.

new_sets <- get_snp_sets(new_snps, factor = "phenotypiccharacteristics")
## The factor 2.2 has 8 rows.
## The factor 2.3 has 7 rows.
## The factor Laboratory line has 2 rows.
## The factor Laboratory line miltefosine resistant  has only 1 row.
## The factor Reference strain has 3 rows.
## The factor unknown has 7 rows.
## Iterating over 686 elements.
summary(new_sets)
##               Length Class      Mode     
## medians         7    data.frame list     
## possibilities   6    -none-     character
## intersections  61    -none-     list     
## chr_data      686    -none-     list     
## set_names      64    -none-     list     
## invert_names   64    -none-     list     
## density       686    -none-     numeric
## 1000000: 2.2
## 0100000: 2.3

summary(new_sets[["intersections"]][["100000"]])
##    Length     Class      Mode 
##       562 character character
dim(new_sets$intersections[["100000"]])
## NULL
sequential_variants <- function(snp_sets, conditions = NULL, minimum = 3, maximum_separation = 3) {
  if (is.null(conditions)) {
    conditions <- 1
  }
  intersection_sets <- snp_sets[["intersections"]]
  intersection_names <- snp_sets[["set_names"]]
  chosen_intersection <- 1
  if (is.numeric(conditions)) {
    chosen_intersection <- conditions
  } else {
    intersection_idx <- intersection_names == conditions
    chosen_intersection <- names(intersection_names)[intersection_idx]
  }

  possible_positions <- intersection_sets[[chosen_intersection]]
  position_table <- data.frame(row.names = possible_positions)
  pat <- "^chr_(.+)_pos_(.+)_ref_.*$"
  position_table[["chr"]] <- gsub(pattern = pat, replacement = "\\1", x = rownames(position_table))
  position_table[["pos"]] <- as.numeric(gsub(pattern = pat, replacement = "\\2", x = rownames(position_table)))
  position_idx <- order(position_table[, "chr"], position_table[, "pos"])
  position_table <- position_table[position_idx, ]
  position_table[["dist"]] <- 0

  last_chr <- ""
  for (r in 1:nrow(position_table)) {
    this_chr <- position_table[r, "chr"]
    if (r == 1) {
      position_table[r, "dist"] <- position_table[r, "pos"]
      last_chr <- this_chr
      next
    }
    if (this_chr == last_chr) {
      position_table[r, "dist"] <- position_table[r, "pos"] - position_table[r - 1, "pos"]
    } else {
      position_table[r, "dist"] <- position_table[r, "pos"]
    }
    last_chr <- this_chr
  }

  sequentials <- position_table[["dist"]] <= maximum_separation

  ## The following can tell me how many runs of each length occurred, that is not quite what I want.
  ## Now use run length encoding to find the set of sequential sequentials!
  rle_result <- rle(sequentials)
  rle_values <- rle_result[["values"]]
  ## The following line is equivalent to just leaving values alone:
  ## true_values <- rle_result[["values"]] == TRUE
  rle_lengths <- rle_result[["lengths"]]
  true_sequentials <- rle_lengths[rle_values]
  rle_idx <- cumsum(rle_lengths)[which(rle_values)]

  position_table[["last_sequential"]] <- 0
  count <- 0
  for (r in rle_idx) {
    count <- count + 1
    position_table[r, "last_sequential"] <- true_sequentials[count]
  }

  wanted_idx <- position_table[["last_sequential"]] >= minimum
  wanted <- position_table[wanted_idx, c("chr", "pos")]
  return(wanted)
}

zymo22_sequentials <- sequential_variants(new_sets, conditions = "2.2")
zymo23_sequentials <- sequential_variants(new_sets, conditions = "2.3")
snp_genes <- sm(snps_vs_genes(lp_expt, new_sets, expt_name_col = "chromosome"))
new_zymo_norm  <- normalize_expt(new_snps, filter = TRUE, convert = "cpm", norm = "quant", transform = TRUE)
## Removing 0 low-count genes (517279 remaining).
## transform_counts: Found 3658406 values equal to 0, adding 1 to the matrix.
new_zymo_norm <- set_expt_conditions(new_zymo_norm, fact = "phenotypiccharacteristics")
zymo_heat <- plot_disheat(new_zymo_norm)

zymo_subset <- snp_subset_genes(lp_expt, new_snps,
                                genes = c("LPAL13_120010900", "LPAL13_340013000", "LPAL13_000054100",
                                        "LPAL13_140006100", "LPAL13_180018500", "LPAL13_320022300"))
## Warning in .Seqinfo.mergexy(x, y): Each of the 2 combined objects has sequence levels not in the other:
##   - in 'x': LPAL13-SCAF000002, LPAL13-SCAF000003, LPAL13-SCAF000004, LPAL13-SCAF000005, LPAL13-SCAF000009, LPAL13-SCAF000013, LPAL13-SCAF000014, LPAL13-SCAF000015, LPAL13-SCAF000018, LPAL13-SCAF000019, LPAL13-SCAF000020, LPAL13-SCAF000022, LPAL13-SCAF000023, LPAL13-SCAF000026, LPAL13-SCAF000029, LPAL13-SCAF000030, LPAL13-SCAF000031, LPAL13-SCAF000032, LPAL13-SCAF000035, LPAL13-SCAF000036, LPAL13-SCAF000037, LPAL13-SCAF000038, LPAL13-SCAF000042, LPAL13-SCAF000043, LPAL13-SCAF000045, LPAL13-SCAF000047, LPAL13-SCAF000049, LPAL13-SCAF000050, LPAL13-SCAF000052, LPAL13-SCAF000054, LPAL13-SCAF000056, LPAL13-SCAF000057, LPAL13-SCAF000058, LPAL13-SCAF000060, LPAL13-SCAF000066, LPAL13-SCAF000067, LPAL13-SCAF000069, LPAL13-SCAF000070, LPAL13-SCAF000073, LPAL13-SCAF000081, LPAL13-SCAF000082, LPAL13-SCAF000083, LPAL13-SCAF000085, LPAL13-SCAF000086, LPAL13-SCAF000088, LPAL13-SCAF000090, LPAL13-SCAF000091, LPAL13-SCAF000092, LPAL13-SCAF000095, LPAL13-SCAF000098, LPAL13-SCAF000101, LPAL13-SCAF000103, LPAL13-SCAF000106, LPAL13-SCAF000109, LPAL13-SCAF000111, LPAL13-SCAF000112, LPAL13-SCAF000113, LPAL13-SCAF000118, LPAL13-SCAF000125, LPAL13-SCAF000126, LPAL13-SCAF000138, LPAL13-SCAF000139, LPAL13-SCAF000140, LPAL13-SCAF000141, LPAL13-SCAF000144, LPAL13-SCAF000145, LPAL13-SCAF000147, LPAL13-SCAF000148, LPAL13-SCAF000150, LPAL13-SCAF000151, LPAL13-SCAF000152, LPAL13-SCAF000154, LPAL13-SCAF000155, LPAL13-SCAF000156, LPAL13-SCAF000157, LPAL13-SCAF000158, LPAL13-SCAF000159, LPAL13-SCAF000160, LPAL13-SCAF000161, LPAL13-SCAF000163, LPAL13-SCAF000164, LPAL13-SCAF000167, LPAL13-SCAF000168, LPAL13-SCAF000169, LPAL13-SCAF000170, LPAL13-SCAF000175, LPAL13-SCAF000177, LPAL13-SCAF000178, LPAL13-SCAF000179, LPAL13-SCAF000180, LPAL13-SCAF000183, LPAL13-SCAF000184, LPAL13-SCAF000185, LPAL13-SCAF000189, LPAL13-SCAF000190, LPAL13-SCAF000192, LPAL13-SCAF000195, LPAL13-SCAF000196, LPAL13-SCAF000198, LPAL13-SCAF000199, LPAL13-SCAF000204, LPAL13-SCAF000207, LPAL13-SCAF000208, LPAL13-SCAF000210, LPAL13-SCAF000212, LPAL13-SCAF000213, LPAL13-SCAF000214, LPAL13-SCAF000215, LPAL13-SCAF000216, LPAL13-SCAF000218, LPAL13-SCAF000219, LPAL13-SCAF000221, LPAL13-SCAF000222, LPAL13-SCAF000223, LPAL13-SCAF000224, LPAL13-SCAF000225, LPAL13-SCAF000226, LPAL13-SCAF000228, LPAL13-SCAF000234, LPAL13-SCAF000236, LPAL13-SCAF000238, LPAL13-SCAF000240, LPAL13-SCAF000241, LPAL13-SCAF000242, LPAL13-SCAF000243, LPAL13-SCAF000244, LPAL13-SCAF000246, LPAL13-SCAF000247, LPAL13-SCAF000251, LPAL13-SCAF000252, LPAL13-SCAF000254, LPAL13-SCAF000255, LPAL13-SCAF000257, LPAL13-SCAF000258, LPAL13-SCAF000260, LPAL13-SCAF000262, LPAL13-SCAF000263, LPAL13-SCAF000268, LPAL13-SCAF000269, LPAL13-SCAF000270, LPAL13-SCAF000272, LPAL13-SCAF000273, LPAL13-SCAF000274, LPAL13-SCAF000275, LPAL13-SCAF000276, LPAL13-SCAF000277, LPAL13-SCAF000278, LPAL13-SCAF000279, LPAL13-SCAF000280, LPAL13-SCAF000282, LPAL13-SCAF000283, LPAL13-SCAF000284, LPAL13-SCAF000289, LPAL13-SCAF000290, LPAL13-SCAF000293, LPAL13-SCAF000294, LPAL13-SCAF000297, LPAL13-SCAF000298, LPAL13-SCAF000299, LPAL13-SCAF000304, LPAL13-SCAF000305, LPAL13-SCAF000306, LPAL13-SCAF000307, LPAL13-SCAF000308, LPAL13-SCAF000311, LPAL13-SCAF000312, LPAL13-SCAF000315, LPAL13-SCAF000318, LPAL13-SCAF000323, LPAL13-SCAF000324, LPAL13-SCAF000325, LPAL13-SCAF000327, LPAL13-SCAF000329, LPAL13-SCAF000331, LPAL13-SCAF000332, LPAL13-SCAF000333, LPAL13-SCAF000334, LPAL13-SCAF000336, LPAL13-SCAF000341, LPAL13-SCAF000342, LPAL13-SCAF000343, LPAL13-SCAF000344, LPAL13-SCAF000345, LPAL13-SCAF000346, LPAL13-SCAF000348, LPAL13-SCAF000349, LPAL13-SCAF000350, LPAL13-SCAF000351, LPAL13-SCAF000352, LPAL13-SCAF000353, LPAL13-SCAF000354, LPAL13-SCAF000355, LPAL13-SCAF000356, LPAL13-SCAF000357, LPAL13-SCAF000359, LPAL13-SCAF000360, LPAL13-SCAF000361, LPAL13-SCAF000362, LPAL13-SCAF000365, LPAL13-SCAF000366, LPAL13-SCAF000369, LPAL13-SCAF000371, LPAL13-SCAF000372, LPAL13-SCAF000373, LPAL13-SCAF000375, LPAL13-SCAF000376, LPAL13-SCAF000377, LPAL13-SCAF000378, LPAL13-SCAF000379, LPAL13-SCAF000380, LPAL13-SCAF000381, LPAL13-SCAF000382, LPAL13-SCAF000383, LPAL13-SCAF000384, LPAL13-SCAF000385, LPAL13-SCAF000386, LPAL13-SCAF000387, LPAL13-SCAF000389, LPAL13-SCAF000390, LPAL13-SCAF000392, LPAL13-SCAF000393, LPAL13-SCAF000394, LPAL13-SCAF000395, LPAL13-SCAF000396, LPAL13-SCAF000398, LPAL13-SCAF000399, LPAL13-SCAF000402, LPAL13-SCAF000404, LPAL13-SCAF000406, LPAL13-SCAF000407, LPAL13-SCAF000408, LPAL13-SCAF000409, LPAL13-SCAF000410, LPAL13-SCAF000411, LPAL13-SCAF000412, LPAL13-SCAF000413, LPAL13-SCAF000414, LPAL13-SCAF000416, LPAL13-SCAF000418, LPAL13-SCAF000422, LPAL13-SCAF000423, LPAL13-SCAF000425, LPAL13-SCAF000427, LPAL13-SCAF000428, LPAL13-SCAF000429, LPAL13-SCAF000431, LPAL13-SCAF000433, LPAL13-SCAF000435, LPAL13-SCAF000437, LPAL13-SCAF000438, LPAL13-SCAF000439, LPAL13-SCAF000441, LPAL13-SCAF000442, LPAL13-SCAF000443, LPAL13-SCAF000444, LPAL13-SCAF000445, LPAL13-SCAF000449, LPAL13-SCAF000450, LPAL13-SCAF000451, LPAL13-SCAF000452, LPAL13-SCAF000454, LPAL13-SCAF000455, LPAL13-SCAF000457, LPAL13-SCAF000458, LPAL13-SCAF000462, LPAL13-SCAF000464, LPAL13-SCAF000466, LPAL13-SCAF000467, LPAL13-SCAF000472, LPAL13-SCAF000473, LPAL13-SCAF000474, LPAL13-SCAF000475, LPAL13-SCAF000476, LPAL13-SCAF000478, LPAL13-SCAF000479, LPAL13-SCAF000480, LPAL13-SCAF000481, LPAL13-SCAF000482, LPAL13-SCAF000485, LPAL13-SCAF000487, LPAL13-SCAF000489, LPAL13-SCAF000493, LPAL13-SCAF000494, LPAL13-SCAF000497, LPAL13-SCAF000498, LPAL13-SCAF000499, LPAL13-SCAF000501, LPAL13-SCAF000502, LPAL13-SCAF000504, LPAL13-SCAF000506, LPAL13-SCAF000509, LPAL13-SCAF000510, LPAL13-SCAF000513, LPAL13-SCAF000514, LPAL13-SCAF000516, LPAL13-SCAF000517, LPAL13-SCAF000518, LPAL13-SCAF000519, LPAL13-SCAF000520, LPAL13-SCAF000521, LPAL13-SCAF000523, LPAL13-SCAF000524, LPAL13-SCAF000525, LPAL13-SCAF000526, LPAL13-SCAF000530, LPAL13-SCAF000531, LPAL13-SCAF000534, LPAL13-SCAF000545, LPAL13-SCAF000546, LPAL13-SCAF000550, LPAL13-SCAF000551, LPAL13-SCAF000557, LPAL13-SCAF000561, LPAL13-SCAF000565, LPAL13-SCAF000571, LPAL13-SCAF000579, LPAL13-SCAF000581, LPAL13-SCAF000584, LPAL13-SCAF000589, LPAL13-SCAF000592, LPAL13-SCAF000594, LPAL13-SCAF000595, LPAL13-SCAF000596, LPAL13-SCAF000597, LPAL13-SCAF000602, LPAL13-SCAF000604, LPAL13-SCAF000606, LPAL13-SCAF000608, LPAL13-SCAF000609, LPAL13-SCAF000612, LPAL13-SCAF000613, LPAL13-SCAF000615, LPAL13-SCAF000620, LPAL13-SCAF000621, LPAL13-SCAF000623, LPAL13-SCAF000624, LPAL13-SCAF000629, LPAL13-SCAF000630, LPAL13-SCAF000631, LPAL13-SCAF000632, LPAL13-SCAF000633, LPAL13-SCAF000634, LPAL13-SCAF000635, LPAL13-SCAF000638, LPAL13-SCAF000640, LPAL13-SCAF000642, LPAL13-SCAF000647, LPAL13-SCAF000648, LPAL13-SCAF000657, LPAL13-SCAF000658, LPAL13-SCAF000660, LPAL13-SCAF000662, LPAL13-SCAF000663, LPAL13-SCAF000664, LPAL13-SCAF000665, LPAL13-SCAF000667, LPAL13-SCAF000669, LPAL13-SCAF000670, LPAL13-SCAF000671, LPAL13-SCAF000674, LPAL13-SCAF000675, LPAL13-SCAF000676, LPAL13-SCAF000677, LPAL13-SCAF000678, LPAL13-SCAF000683, LPAL13-SCAF000684, LPAL13-SCAF000685, LPAL13-SCAF000686, LPAL13-SCAF000687, LPAL13-SCAF000689, LPAL13-SCAF000690, LPAL13-SCAF000691, LPAL13-SCAF000692, LPAL13-SCAF000693, LPAL13-SCAF000694, LPAL13-SCAF000699, LPAL13-SCAF000701, LPAL13-SCAF000702, LPAL13-SCAF000703, LPAL13-SCAF000705, LPAL13-SCAF000706, LPAL13-SCAF000708, LPAL13-SCAF000709, LPAL13-SCAF000710, LPAL13-SCAF000712, LPAL13-SCAF000715, LPAL13-SCAF000718, LPAL13-SCAF000721, LPAL13-SCAF000725, LPAL13-SCAF000728, LPAL13-SCAF000729, LPAL13-SCAF000730, LPAL13-SCAF000731, LPAL13-SCAF000733, LPAL13-SCAF000736, LPAL13-SCAF000739, LPAL13-SCAF000740, LPAL13-SCAF000741, LPAL13-SCAF000742, LPAL13-SCAF000743, LPAL13-SCAF000745, LPAL13-SCAF000746, LPAL13-SCAF000747, LPAL13-SCAF000749, LPAL13-SCAF000750, LPAL13-SCAF000751, LPAL13-SCAF000752, LPAL13-SCAF000753, LPAL13-SCAF000754, LPAL13-SCAF000755, LPAL13-SCAF000756, LPAL13-SCAF000757, LPAL13-SCAF000758, LPAL13-SCAF000759, LPAL13-SCAF000763, LPAL13-SCAF000764, LPAL13-SCAF000765, LPAL13-SCAF000766, LPAL13-SCAF000767, LPAL13-SCAF000768, LPAL13-SCAF000769, LPAL13-SCAF000770, LPAL13-SCAF000771, LPAL13-SCAF000773, LPAL13-SCAF000774, LPAL13-SCAF000775, LPAL13-SCAF0007
## Before removal, there were 517279 genes, now there are 82.
## There are 28 samples which kept less than 90 percent counts.
## tmrc20001 tmrc20004 tmrc20005 tmrc20007 tmrc20008 tmrc20009 tmrc20010 tmrc20011 
##   0.03704   0.00000   0.04172   0.05308   0.04589   0.00000   0.02772   0.02499 
## tmrc20012 tmrc20013 tmrc20014 tmrc20015 tmrc20016 tmrc20017 tmrc20018 tmrc20019 
##   0.00000   0.02938   0.01836   0.02622   0.02636   0.02029   0.03281   0.07991 
## tmrc20020 tmrc20021 tmrc20022 tmrc20024 tmrc20025 tmrc20026 tmrc20027 tmrc20028 
##   0.07243   0.03243   0.00000   0.04054   0.06334   0.08188   0.05991   0.07737 
## tmrc20029 tmrc20031 tmrc20032 tmrc20033 
##   0.00000   0.04589   0.03713   0.00000
zymo_subset <- set_expt_conditions(zymo_subset, fact = "phenotypiccharacteristics")
## zymo_heat <- plot_sample_heatmap(zymo_subset, row_label = rownames(exprs(snp_subset)))

des <- both_norm$design
undef_idx <- is.na(des[["strain"]])
des[undef_idx, "strain"] <- "unknown"

##hmcols <- colorRampPalette(c("yellow","black","darkblue"))(256)
correlations <- hpgl_cor(exprs(both_norm))

zymo_missing_idx <- is.na(des[["phenotypiccharacteristics"]])
des[zymo_missing_idx, "phenotypiccharacteristics"] <- "unknown"
mydendro <- list(
  "clustfun" = hclust,
  "lwd" = 2.0)
col_data <- as.data.frame(des[, c("phenotypiccharacteristics", "clinicalcategorical")])
unknown_clinical <- is.na(col_data[["clinicalcategorical"]])
row_data <- as.data.frame(des[, c("strain")])
colnames(col_data) <- c("zymodeme", "outcome")
col_data[unknown_clinical, "outcome"] <- "undefined"

colnames(row_data) <- c("strain")
myannot <- list(
  "Col" = list("data" = col_data),
  "Row" = list("data" = row_data))
myclust <- list("cuth" = 1.0,
                "col" = BrewerClusterCol)
mylabs <- list(
  "Row" = list("nrow" = 4),
  "Col" = list("nrow" = 4))
hmcols <- colorRampPalette(c("darkblue", "beige"))(240)
map1 <- annHeatmap2(
  correlations,
  dendrogram = mydendro,
  annotation = myannot,
  cluster = myclust,
  labels = mylabs,
  ## The following controls if the picture is symmetric
  scale = "none",
  col = hmcols)
## Warning in breakColors(breaks, col): more colors than classes: ignoring 27 last
## colors
plot(map1)

9 Using Variant profiles to make guesses about strains and chronic/self-healing

The following uses the same information to make some guesses about the strains used in the new samples.

des <- both_norm$design
undef_idx <- is.na(des[["strain"]])
des[undef_idx, "strain"] <- "unknown"
##hmcols <- colorRampPalette(c("yellow","black","darkblue"))(256)
correlations <- hpgl_cor(exprs(both_norm))

mydendro <- list(
  "clustfun" = hclust,
  "lwd" = 2.0)
col_data <- as.data.frame(des[, c("condition")])
row_data <- as.data.frame(des[, c("strain")])
colnames(col_data) <- c("condition")
colnames(row_data) <- c("strain")
myannot <- list(
  "Col" = list("data" = col_data),
  "Row" = list("data" = row_data))
myclust <- list("cuth" = 1.0,
                "col" = BrewerClusterCol)
mylabs <- list(
  "Row" = list("nrow" = 4),
  "Col" = list("nrow" = 4))
hmcols <- colorRampPalette(c("darkblue", "beige"))(170)
map1 <- annHeatmap2(
  correlations,
  dendrogram = mydendro,
  annotation = myannot,
  cluster = myclust,
  labels = mylabs)
##  col = hmcols)
plot(map1)

pheno <- subset_expt(lp_expt, subset = "condition=='z2.2'|condition=='z2.3'")
## There were 34, now there are 19 samples.
pheno_snps <- sm(count_expt_snps(pheno, annot_column = "bcftable"))
## Error : 'NA' does not exist in current working directory ('/fs01/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019').
## Error : 'NA' does not exist in current working directory ('/fs01/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019').
## Error : 'NA' does not exist in current working directory ('/fs01/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019').
## Error : 'NA' does not exist in current working directory ('/fs01/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019').
## Error : 'NA' does not exist in current working directory ('/fs01/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019').
## Error : 'NA' does not exist in current working directory ('/fs01/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019').
## Error : 'NA' does not exist in current working directory ('/fs01/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019').
## Error : 'NA' does not exist in current working directory ('/fs01/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019').
## Error in Biobase::`sampleNames<-`(`*tmp*`, value = colnames(snp_exprs)): number of new names (15) should equal number of rows in AnnotatedDataFrame (19)
xref_prop <- table(pheno_snps$conditions)
## Error in eval(quote(list(...)), env): object 'pheno_snps' not found
pheno_snps$conditions
## Error in eval(expr, envir, enclos): object 'pheno_snps' not found
idx_tbl <- exprs(pheno_snps) > 5
## Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'exprs': object 'pheno_snps' not found
new_tbl <- data.frame(row.names = rownames(exprs(pheno_snps)))
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'rownames': error in evaluating the argument 'object' in selecting a method for function 'exprs': object 'pheno_snps' not found
for (n in names(xref_prop)) {
  new_tbl[[n]] <- 0
  idx_cols <- which(pheno_snps[["conditions"]] == n)
  prop_col <- rowSums(idx_tbl[, idx_cols]) / xref_prop[n]
  new_tbl[n] <- prop_col
}
## Error in eval(expr, envir, enclos): object 'xref_prop' not found
new_tbl[["ratio"]] <- (new_tbl[["z2.2"]] - new_tbl[["z2.3"]])
## Error in eval(expr, envir, enclos): object 'new_tbl' not found
keepers <- grepl(x = rownames(new_tbl), pattern = "LpaL13")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'grepl': error in evaluating the argument 'x' in selecting a method for function 'rownames': object 'new_tbl' not found
new_tbl <- new_tbl[keepers, ]
## Error in eval(expr, envir, enclos): object 'new_tbl' not found
new_tbl[["SNP"]] <- rownames(new_tbl)
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'rownames': object 'new_tbl' not found
new_tbl[["Chromosome"]] <- gsub(x = new_tbl[["SNP"]], pattern = "chr_(.*)_pos_.*", replacement = "\\1")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'gsub': object 'new_tbl' not found
new_tbl[["Position"]] <- gsub(x = new_tbl[["SNP"]], pattern = ".*_pos_(\\d+)_.*", replacement = "\\1")
## Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'gsub': object 'new_tbl' not found
new_tbl <- new_tbl[, c("SNP", "Chromosome", "Position", "ratio")]
## Error in eval(expr, envir, enclos): object 'new_tbl' not found
library(CMplot)
## Much appreciate for using CMplot.
## Full description, Bug report, Suggestion and the latest codes:
## https://github.com/YinLiLin/CMplot
CMplot(new_tbl)
## Error in is.data.frame(x): object 'new_tbl' not found
if (!isTRUE(get0("skip_load"))) {
  pander::pander(sessionInfo())
  message(paste0("This is hpgltools commit: ", get_git_commit()))
  message(paste0("Saving to ", savefile))
  tmp <- sm(saveme(filename = savefile))
}
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 53433f808ad055552025c90161db331405085a9e
## This is hpgltools commit: Tue May 4 12:44:03 2021 -0400: 53433f808ad055552025c90161db331405085a9e
## Saving to tmrc2_02sample_estimation_v202104.rda.xz
tmp <- loadme(filename = savefile)
LS0tCnRpdGxlOiAiVE1SQzIgQ29tcHJlaGVuc2l2ZSBEYXRhIEFuYWx5c2lzOiAyMDIxMDQiCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKIGh0bWxfZG9jdW1lbnQ6CiAgY29kZV9kb3dubG9hZDogdHJ1ZQogIGNvZGVfZm9sZGluZzogc2hvdwogIGZpZ19jYXB0aW9uOiB0cnVlCiAgZmlnX2hlaWdodDogNwogIGZpZ193aWR0aDogNwogIGhpZ2hsaWdodDogZGVmYXVsdAogIGtlZXBfbWQ6IGZhbHNlCiAgbW9kZTogc2VsZmNvbnRhaW5lZAogIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgdGhlbWU6IHJlYWRhYmxlCiAgdG9jOiB0cnVlCiAgdG9jX2Zsb2F0OgogICBjb2xsYXBzZWQ6IGZhbHNlCiAgIHNtb290aF9zY3JvbGw6IGZhbHNlCi0tLQoKPHN0eWxlPgogIGJvZHkgLm1haW4tY29udGFpbmVyIHsKICAgIG1heC13aWR0aDogMTYwMHB4OwogIH0KPC9zdHlsZT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGUgPSBGQUxTRX0KbGlicmFyeShocGdsdG9vbHMpCnR0IDwtIHNtKGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKSkKa25pdHI6Om9wdHNfa25pdCRzZXQocHJvZ3Jlc3MgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSA5MCwKICAgICAgICAgICAgICAgICAgICAgZWNobyA9IFRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvciA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGggPSA4LAogICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodCA9IDgsCiAgICAgICAgICAgICAgICAgICAgICBkcGkgPSA5NikKb2xkX29wdGlvbnMgPC0gb3B0aW9ucyhkaWdpdHMgPSA0LAogICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWwgPSAiYWxsb3ciKQpnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplID0gMTIpKQp2ZXIgPC0gIjIwMjEwNCIKcnVuZGF0ZSA8LSBmb3JtYXQoU3lzLkRhdGUoKSwgZm9ybWF0ID0gIiVZJW0lZCIpCgojIyB0bXAgPC0gdHJ5KHNtKGxvYWRtZShmaWxlbmFtZSA9IGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLCByZXBsYWNlID0gIlxcLnJkYVxcLnh6IiwgeCA9IHByZXZpb3VzX2ZpbGUpKSkpCnJtZF9maWxlIDwtICJ0bXJjMl8wMnNhbXBsZV9lc3RpbWF0aW9uX3YyMDIxMDQuUm1kIgpzYXZlZmlsZSA8LSBnc3ViKHBhdHRlcm4gPSAiXFwuUm1kIiwgcmVwbGFjZSA9ICJcXC5yZGFcXC54eiIsIHggPSBybWRfZmlsZSkKCmxpYnJhcnkoSGVhdHBsdXMpCmBgYAoKIyBJbnRyb2R1Y3Rpb24KClRoaXMgZG9jdW1lbnQgaXMgaW50ZW5kZWQgdG8gcHJvdmlkZSBhIGdlbmVyYWwgb3ZlcnZpZXcgb2YgdGhlIFRNUkMyIHNhbXBsZXMKd2hpY2ggaGF2ZSB0aHVzIGZhciBiZWVuIHNlcXVlbmNlZC4gIEluIHNvbWUgY2FzZXMsIHRoaXMgaW5jbHVkZXMgb25seSB0aG9zZQpzYW1wbGVzIHN0YXJ0aW5nIGluIDIwMTk7IGluIG90aGVyIGluc3RhbmNlcyBJIGFtIGluY2x1ZGluZyBvdXIgcHJldmlvdXMKKDIwMTUtMjAxNikgc2FtcGxlcy4KCkluIGFsbCBjYXNlcyB0aGUgcHJvY2Vzc2luZyBwZXJmb3JtZWQgd2FzOgoKMS4gIERlZmF1bHQgdHJpbW1pbmcgd2FzIHBlcmZvcm1lZC4KMi4gIEhpc2F0MiB3YXMgdXNlZCB0byBtYXAgdGhlIHJlbWFpbmluZyByZWFkcyBhZ2FpbnN0IHRoZSBMZWlzaG1hbmlhCiAgICBwYW5hbWVuc2lzIGdlbm9tZSByZXZpc2lvbiAzNi4KMy4gIFRoZSBhbGlnbm1lbnRzIGZyb20gaGlzYXQyIHdlcmUgdXNlZCB0byBjb3VudCByZWFkcy9nZW5lIGFnYWluc3QgdGhlCiAgICByZXZpc2lvbiAzNiBhbm5vdGF0aW9ucyB3aXRoIGh0c2VxLgo0LiAgVGhlc2UgYWxpZ25tZW50cyB3ZXJlIGFsc28gcGFzc2VkIHRvIHRoZSBwaWxldXAgZnVuY3Rpb25hbGl0eSBvZiBzYW10b29scwogICAgYW5kIHRoZSB2Y2YvYmNmIHV0aWxpdGllcyBpbiBvcmRlciB0byBtYWtlIGEgbWF0cml4IG9mIGFsbCBvYnNlcnZlZAogICAgZGlmZmVyZW5jZXMgYmV0d2VlbiBlYWNoIHNhbXBsZSB3aXRoIHJlc3BlY3QgdG8gdGhlIHJlZmVyZW5jZS4KClRoZSBhbmFseXNlcyBpbiB0aGlzIGRvY3VtZW50IHVzZSB0aGUgbWF0cmljZXMgb2YgY291bnRzL2dlbmUgZnJvbSAjMyBhbmQKdmFyaWFudHMvcG9zaXRpb24gZnJvbSAjNCBpbiBvcmRlciB0byBwcm92aWRlIHNvbWUgaW1hZ2VzIGFuZCBtZXRyaWNzIGRlc2NyaWJpbmcKdGhlIHNhbXBsZXMgd2UgaGF2ZSBzZXF1ZW5jZWQgc28gZmFyLgoKIyBBbm5vdGF0aW9ucwoKRXZlcnl0aGluZyB3aGljaCBmb2xsb3dzIGRlcGVuZHMgb24gdGhlIEV4aXN0aW5nIFRyaVRyeXBEQiBhbm5vdGF0aW9ucyByZXZpc2lvbgo0NiwgY2lyY2EgMjAxOS4gIFRoZSBmb2xsb3dpbmcgYmxvY2sgbG9hZHMgYSBkYXRhYmFzZSBvZiB0aGVzZSBhbm5vdGF0aW9ucyBhbmQKdHVybnMgaXQgaW50byBhIG1hdHJpeCB3aGVyZSB0aGUgcm93cyBhcmUgZ2VuZXMgYW5kIGNvbHVtbnMgYXJlIGFsbCB0aGUKYW5ub3RhdGlvbiB0eXBlcyBwcm92aWRlZCBieSBUcmlUcnlwREIuCgpUaGUgc2FtZSBkYXRhYmFzZSB3YXMgdXNlZCB0byBjcmVhdGUgYSBtYXRyaXggb2Ygb3J0aG9sb2dvdXMgZ2VuZXMgYmV0d2VlbgpMLnBhbmFtZW5zaXMgYW5kIGFsbCBvZiB0aGUgb3RoZXIgc3BlY2llcyBpbiB0aGUgVHJpVHJ5cERCLgoKYGBge3IgYW5ub3R9CnR0IDwtIHNtKGxpYnJhcnkoRXVQYXRoREIpKQp0dCA8LSBzbShsaWJyYXJ5KG9yZy5McGFuYW1lbnNpcy5NSE9NQ09MODFMMTMudjQ2LmVnLmRiKSkKcGFuX2RiIDwtIG9yZy5McGFuYW1lbnNpcy5NSE9NQ09MODFMMTMudjQ2LmVnLmRiCmFsbF9maWVsZHMgPC0gY29sdW1ucyhwYW5fZGIpCgphbGxfbHBfYW5ub3QgPC0gc20obG9hZF9vcmdkYl9hbm5vdGF0aW9ucygKICAgIHBhbl9kYiwKICAgIGtleXR5cGUgPSAiZ2lkIiwKICAgIGZpZWxkcyA9IGMoImFubm90X2dlbmVfZW50cmV6X2lkIiwgImFubm90X2dlbmVfbmFtZSIsCiAgICAgICAgICAgICAgICJhbm5vdF9zdHJhbmQiLCAiYW5ub3RfY2hyb21vc29tZSIsICJhbm5vdF9jZHNfbGVuZ3RoIiwKICAgICAgICAgICAgICAgImFubm90X2dlbmVfcHJvZHVjdCIpKSkkZ2VuZXMKCmxwX2dvIDwtIHNtKGxvYWRfb3JnZGJfZ28ocGFuX2RiKSkKbHBfbGVuZ3RocyA8LSBhbGxfbHBfYW5ub3RbLCBjKCJnaWQiLCAiYW5ub3RfY2RzX2xlbmd0aCIpXQpjb2xuYW1lcyhscF9sZW5ndGhzKSAgPC0gYygiSUQiLCAibGVuZ3RoIikKCm9ydGhvcyA8LSBzbShFdVBhdGhEQjo6ZXh0cmFjdF9ldXBhdGhfb3J0aG9sb2dzKGRiID0gcGFuX2RiKSkKCmhpc2F0X2Fubm90IDwtIGFsbF9scF9hbm5vdAojIyByb3duYW1lcyhoaXNhdF9hbm5vdCkgPC0gcGFzdGUwKCJleG9uXyIsIHJvd25hbWVzKGhpc2F0X2Fubm90KSwgIi5FMSIpCmBgYAoKIyBUT0RPOgoKUmVzZXF1ZW5jZSBzYW1wbGVzOiBUTVJDMjAwMDIsIFRNUkMyMDAwNiwgVE1SQzIwMDA0IChtYXliZSBUTVJDMjAwMDggYW5kIFRNUkMyMDAyOSkKCiMjIEdlbmVyYXRlIGV4cHJlc3Npb25zZXRzCgpUaGUgZmlyc3QgbGluZXMgb2YgdGhlIGZvbGxvd2luZyBibG9jayBjcmVhdGUgdGhlIEV4cHJlc3Npb25zZXQuICBBbGwgb2YgdGhlCmZvbGxvd2luZyBsaW5lcyBwZXJmb3JtIHZhcmlvdXMgbm9ybWFsaXphdGlvbnMgYW5kIGdlbmVyYXRlIHBsb3RzIGZyb20gaXQuCgpgYGB7ciBuZXdfc2FtcGxlc19oaXNhdH0Kc2FtcGxlX3NoZWV0IDwtIGdsdWU6OmdsdWUoInNhbXBsZV9zaGVldHMvdG1yYzJfc2FtcGxlc18yMDIxMDUxMi54bHN4IikKCmxwX2V4cHQgPC0gc20oY3JlYXRlX2V4cHQoc2FtcGxlX3NoZWV0LAogICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVfaW5mbyA9IGhpc2F0X2Fubm90LAogICAgICAgICAgICAgICAgICAgICAgICAgIGlkX2NvbHVtbiA9ICJocGdsaWRlbnRpZmllciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV9jb2x1bW4gPSAibHBhbmFtZW5zaXN2MzZoaXNhdGZpbGUiKSkgJT4lCiAgc2V0X2V4cHRfY29uZGl0aW9ucyhmYWN0ID0gInp5bW9kZW1lY2F0ZWdvcmljYWwiKSAlPiUKICBzdWJzZXRfZXhwdChub256ZXJvID0gODU1MCkKCmxpYnNpemVzIDwtIHBsb3RfbGlic2l6ZShscF9leHB0KQpsaWJzaXplcyRwbG90CiMjIEkgdGhpbmsgc2FtcGxlcyA3LDEwIHNob3VsZCBiZSByZW1vdmVkIGF0IG1pbmltdW0sIHByb2JhYmx5IGFsc28gOSwxMQpub256ZXJvIDwtIHBsb3Rfbm9uemVybyhscF9leHB0KQpub256ZXJvJHBsb3QKcGxvdF9ib3hwbG90KGxwX2V4cHQpCmBgYAoKIyMgRGlzdHJpYnV0aW9uIFZpc3VhbGl6YXRpb24KCk5hamliJ3MgZmF2b3JpdGUgcGxvdHMgYXJlIG9mIGNvdXJzZSB0aGUgUENBL1ROU0UuICBUaGVzZSBhcmUgbmljZSB0byBsb29rIGF0IGluCm9yZGVyIHRvIGdldCBhIHNlbnNlIG9mIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gc2FtcGxlcy4gIFRoZXkgYWxzbyBwcm92aWRlIGEKZ29vZCBvcHBvcnR1bml0eSB0byBzZWUgd2hhdCBoYXBwZW5zIHdoZW4gb25lIGFwcGxpZXMgZGlmZmVyZW50IG5vcm1hbGl6YXRpb25zLApzdXJyb2dhdGUgYW5hbHlzZXMsIGZpbHRlcnMsIGV0Yy4gIEluIGFkZGl0aW9uLCBvbmUgbWF5IHNldCBkaWZmZXJlbnQKZXhwZXJpbWVudGFsIGZhY3RvcnMgYXMgdGhlIHByaW1hcnkgJ2NvbmRpdGlvbicgKHVzdWFsbHkgdGhlIGNvbG9yIG9mIHBsb3RzKSBhbmQKc3Vycm9nYXRlICdiYXRjaGVzJy4KCiMjIFN1c2NlcHRpbGliaXR5CgpDb2x1bW4gJ1EnIGluIHRoZSBzYW1wbGUgc2hlZXQsIG1ha2UgYSBjYXRlZ29yaWNhbCB2ZXJzaW9uIG9mIGl0IHdpdGggdGhlc2UgcGFyYW1ldGVyczoKCiogMCA8PSB4IDw9IDM1IGlzIHJlc2lzdGFudAoqIDM2IDw9IHggPD0gNDggaXMgYW1iaWd1b3VzCiogNDkgPD0geCBpcyBzZW5zaXRpdmUKCmBgYHtyIHN1c2NlcHRpYmlsaXR5fQpzdGFydGluZyA8LSBhcy5udW1lcmljKHBEYXRhKGxwX2V4cHQpW1sic3VzY2VwdGliaWxpdHlpbmZlY3Rpb25yZWR1Y3Rpb24zMnVnbWxzYnZoaXN0b3JpY2FsZGF0YSJdXSkKc3VzX2NhdGVnb3JpY2FsIDwtIHN0YXJ0aW5nCm5hX2lkeCA8LSBpcy5uYShzdGFydGluZykKc3VzX2NhdGVnb3JpY2FsW25hX2lkeF0gPC0gInVua25vd24iCgpyZXNpc3RfaWR4IDwtIHN0YXJ0aW5nIDw9IDAuMzUKc3VzX2NhdGVnb3JpY2FsW3Jlc2lzdF9pZHhdIDwtICJyZXNpc3RhbnQiCmluZGV0ZXJtaW5hbnRfaWR4IDwtIHN0YXJ0aW5nID49IDAuMzYgJiBzdGFydGluZyA8PSAwLjQ4CnN1c19jYXRlZ29yaWNhbFtpbmRldGVybWluYW50X2lkeF0gPC0gImFtYmlndW91cyIKc3VzY2VwdGlibGVfaWR4IDwtIHN0YXJ0aW5nID49IDAuNDkKc3VzX2NhdGVnb3JpY2FsW3N1c2NlcHRpYmxlX2lkeF0gPC0gInNlbnNpdGl2ZSIKCnBEYXRhKGxwX2V4cHQkZXhwcmVzc2lvbnNldClbWyJzdXNfY2F0ZWdvcnkiXV0gPC0gc3VzX2NhdGVnb3JpY2FsCmBgYAoKYGBge3IgcHJlX3F1ZXN0aW9uc30KY2xpbmljYWxfc2FtcGxlcyA8LSBscF9leHB0ICU+JQogIHNldF9leHB0X2JhdGNoZXMoZmFjdCA9IHN1c19jYXRlZ29yaWNhbCkKCmNsaW5pY2FsX25vcm0gPC0gc20obm9ybWFsaXplX2V4cHQoY2xpbmljYWxfc2FtcGxlcywgbm9ybSA9ICJxdWFudCIsIHRyYW5zZm9ybSA9ICJsb2cyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJ0ID0gImNwbSIsIGJhdGNoID0gRkFMU0UsIGZpbHRlciA9IFRSVUUpKQp6eW1vX3BjYSA8LSBwbG90X3BjYShjbGluaWNhbF9ub3JtLCBwbG90X3RpdGxlID0gIlBDQSBvZiBwYXJhc2l0ZSBleHByZXNzaW9uIHZhbHVlcyIpCnBwKGZpbGUgPSAiaW1hZ2VzL3p5bW9fcGNhX3N1c19zaGFwZS5wbmciLCBpbWFnZSA9IHp5bW9fcGNhJHBsb3QpCgp6eW1vXzNkcGNhIDwtIHBsb3RfM2RfcGNhKHp5bW9fcGNhKQp6eW1vXzNkcGNhJHBsb3QKCnp5bW9fdHNuZSA8LSBwbG90X3RzbmUoY2xpbmljYWxfbm9ybSwgcGxvdF90aXRsZSA9ICJUU05FIG9mIHBhcmFzaXRlIGV4cHJlc3Npb24gdmFsdWVzIikKenltb190c25lJHBsb3QKCmNsaW5pY2FsX25iIDwtIG5vcm1hbGl6ZV9leHB0KGNsaW5pY2FsX3NhbXBsZXMsIGNvbnZlcnQgPSAiY3BtIiwgdHJhbnNmb3JtID0gImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKY2xpbmljYWxfbmJfcGNhIDwtIHBsb3RfcGNhKGNsaW5pY2FsX25iLCBwbG90X3RpdGxlID0gVFJVRSkKcHAoZmlsZSA9ICJpbWFnZXMvY2xpbmljYWxfbmJfcGNhX3N1c19zaGFwZS5wbmciLCBpbWFnZSA9IGNsaW5pY2FsX25iX3BjYSRwbG90KQoKY2xpbmljYWxfbmJfdHNuZSA8LSBwbG90X3RzbmUoY2xpbmljYWxfbmIpCmNsaW5pY2FsX25iX3RzbmUkcGxvdAoKY29yaGVhdCA8LSBwbG90X2NvcmhlYXQoY2xpbmljYWxfbm9ybSwgdGl0bGUgPSAiQ29ycmVsYXRpb24gaGVhdG1hcCBvZiBwYXJhc2l0ZSBleHByZXNzaW9uIHZhbHVlcwooU2FtZSBsZWdlbmQgYXMgYWJvdmUpIikKY29yaGVhdCRwbG90CgpwbG90X3NtKGNsaW5pY2FsX25vcm0pJHBsb3QKYGBgCgojIyBDdXJlL0ZhaWwgc3RhdHVzCgpgYGB7ciBjZl9zdGF0dXN9CmNmX2V4cHQgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyhscF9leHB0LCBmYWN0ID0gImNsaW5pY2FsY2F0ZWdvcmljYWwiKSAlPiUKICBzZXRfZXhwdF9iYXRjaGVzKGZhY3QgPSBzdXNfY2F0ZWdvcmljYWwpCgpjZl9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGNmX2V4cHQsIGNvbnZlcnQgPSAiY3BtIiwgdHJhbnNmb3JtID0gImxvZzIiLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQpzdGFydF9jZiA8LSBwbG90X3BjYShjZl9ub3JtKQpwcChmaWxlID0gImltYWdlcy9jZl9zdXNfc2hhcGUucG5nIiwgaW1hZ2UgPSBzdGFydF9jZiRwbG90KQoKY2ZfbmIgPC0gbm9ybWFsaXplX2V4cHQoY2ZfZXhwdCwgY29udmVydCA9ICJjcG0iLCB0cmFuc2Zvcm0gPSAibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFLCBiYXRjaCA9ICJzdmFzZXEiKQpjZl9uYl9wY2EgPC0gcGxvdF9wY2EoY2ZfbmIpCnBwKGZpbGUgPSAiaW1hZ2VzL2NmX3N1c19zaGFyZV9uYi5wbmciLCBpbWFnZSA9IGNmX25iX3BjYSRwbG90KQoKY2Zfbm9ybSA8LSBub3JtYWxpemVfZXhwdChjZl9leHB0LCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCBub3JtID0gInF1YW50IikKdGVzdCA8LSBwY2FfaW5mb3JtYXRpb24oY2Zfbm9ybSwKICAgICAgICAgICAgICAgICAgICAgICAgZXhwdF9mYWN0b3JzID0gYygiY2xpbmljYWxjYXRlZ29yaWNhbCIsICJ6eW1vZGVtZWNhdGVnb3JpY2FsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGF0aG9nZW5zdHJhaW4iLCAicGFzc2FnZW51bWJlciIpLAogICAgICAgICAgICAgICAgICAgICAgICBudW1fY29tcG9uZW50cyA9IDYsIHBsb3RfcGNhcyA9IFRSVUUpCmBgYAoKYGBge3Igc3VzY2VwdGliaWxpdHlfcGNhfQpzdXNfZXhwdCA8LSBzZXRfZXhwdF9jb25kaXRpb25zKGxwX2V4cHQsIGZhY3QgPSAic3VzX2NhdGVnb3J5IikgJT4lCiAgc2V0X2V4cHRfYmF0Y2hlcyhmYWN0ID0gInp5bW9kZW1lY2F0ZWdvcmljYWwiKQpzdXNfbm9ybSA8LSBub3JtYWxpemVfZXhwdChzdXNfZXhwdCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQpzdXNfcGNhIDwtIHBsb3RfcGNhKHN1c19ub3JtKQpzdXNfcGNhJHBsb3QKCnN1c19uYiA8LSBub3JtYWxpemVfZXhwdChzdXNfZXhwdCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9ICJzdmFzZXEiLCBmaWx0ZXIgPSBUUlVFKQpzdXNfbmJfcGNhIDwtIHBsb3RfcGNhKHN1c19uYikKcHAoZmlsZSA9ICJpbWFnZXMvc3VzX25iX3BjYS5wbmciLCBpbWFnZSA9IHN1c19uYl9wY2EkcGxvdCkKYGBgCgojIyMgTm90ZXMKClRoZSBmb2xsb3dpbmcgc2FtcGxlcyBhcmUgbXVjaCBsb3dlciBjb3ZlcmFnZToKCiogVE1SQzIwMDAyCiogVE1SQzIwMDA2CiogVE1SQzIwMDA3CiogVE1SQzIwMDA4CgpBdCB0aGlzIHRpbWUsIHdlIGRvIG5vdCBoYXZlIHZlcnkgbWFueSBzYW1wbGVzLCBzbyB0aGUgc2V0IG9mIG1ldHJpY3MvcGxvdHMgaXMKZmFpcmx5IGxpbWl0ZWQuICBUaGVyZSBpcyByZWFsbHkgb25seSBvbmUgZmFjdG9yIGluIHRoZSBtZXRhZGF0YSB3aGljaCB3ZSBjYW4KdXNlIGZvciBwZXJmb3JtaW5nIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2VzLCB0aGUgJ3p5bW9kZW1lJy4KCiMgU2FtcGxlIEVzdGltYXRpb24KClRoZSBwcm9jZXNzIG9mIHNhbXBsZSBlc3RpbWF0aW9uIHRha2VzIHR3byBwcmltYXJ5IGlucHV0czoKCjEuICBUaGUgc2FtcGxlIHNoZWV0LCB3aGljaCBjb250YWlucyBhbGwgdGhlIG1ldGFkYXRhIHdlIGN1cnJlbnRseSBoYXZlIG9uIGhhbmQsCiAgICBpbmNsdWRpbmcgZmlsZW5hbWVzIGZvciB0aGUgb3V0cHV0cyBvZiAjMyBhbmQgIzQgYWJvdmUuCjIuICBUaGUgZ2VuZSBhbm5vdGF0aW9ucy4KCkFuIGV4cHJlc3Npb25zZXQgaXMgcHJpbWFyeSBkYXRhIHN0cnVjdHVyZSB1c2VkIGluIFIgdG8gZXhhbWluZSBSTkFTZXEgZGF0YS4gIEl0CmlzIGNvbXByaXNlZCBvZiBhbm5vdGF0aW9ucywgbWV0YWRhdGEsIGFuZCBleHByZXNzaW9uIGRhdGEuICBJbiB0aGUgY2FzZSBvZiBvdXIKcHJvY2Vzc2luZyBwaXBlbGluZSwgdGhlIGxvY2F0aW9uIG9mIHRoZSBleHByZXNzaW9uIGRhdGEgaXMgcHJvdmlkZWQgYnkgdGhlCmZpbGVuYW1lcyBpbiB0aGUgbWV0YWRhdGEuCgoKIyBaeW1vZGVtZSBhbmFseXNlcwoKVGhlIGZvbGxvd2luZyBzZWN0aW9ucyBwZXJmb3JtIGEgc2VyaWVzIG9mIGFuYWx5c2VzIHdoaWNoIHNlZWsgdG8gZWx1Y2lkYXRlCmRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIHp5bW9kZW1lcyAyLjIgYW5kIDIuMyBlaXRoZXIgdGhyb3VnaCBkaWZmZXJlbnRpYWwKZXhwcmVzc2lvbiBvciB2YXJpYW50IHByb2ZpbGVzLgoKIyMgRGlmZmVyZW50aWFsIGV4cHJlc3Npb24KCiMjIyBXaXRoIHJlc3BlY3QgdG8genltb2RlbWUgYXR0cmlidXRpb24KClRPRE86IERvIHRoaXMgd2l0aCBhbmQgd2l0aG91dCBzdmEgYW5kIGNvbXBhcmUgdGhlIHJlc3VsdHMuCgpgYGB7ciB6eW1vX2RlLCBmaWcuc2hvdyA9ICJoaWRlIn0KenlfZXhwdCA8LSBzdWJzZXRfZXhwdChscF9leHB0LCBzdWJzZXQgPSAiY29uZGl0aW9uPT0nejIuMid8Y29uZGl0aW9uPT0nejIuMyciKQp6eV9ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KHp5X2V4cHQsIGZpbHRlciA9IFRSVUUsIGNvbnZlcnQgPSAiY3BtIiwgbm9ybSA9ICJxdWFudCIpCnp5X2RlX25vYmF0Y2ggPC0gc20oYWxsX3BhaXJ3aXNlKHp5X2V4cHQsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIpKQp6eV9kZSA8LSBzbShhbGxfcGFpcndpc2UoenlfZXhwdCwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikpCnp5X3RhYmxlIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKHp5X2RlLCBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL3p5X3RhYmxlcy12e3Zlcn0ueGxzeCIpKSkKenlfc2lnIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMoenlfdGFibGUsIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvenlfc2lnLXZ7dmVyfS54bHN4IikpKQpgYGAKCiMjIyBJbWFnZXMgb2Ygenltb2RlbWUgREUKCmBgYHtyIHp5bW9kX2RlX3BpY3R1cmVzfQp6eV90YWJsZVtbInBsb3RzIl1dW1siejIzX3ZzX3oyMiJdXVtbImRlc2VxX21hX3Bsb3RzIl1dW1sicGxvdCJdXQpgYGAKCiMjIFdpdGggcmVzcGVjdCB0byBjdXJlL2ZhaWx1cmUKCmBgYHtyIGN1cmVmYWlsX2RlLCBmaWcuc2hvdyA9ICJoaWRlIn0KY2ZfZGUgPC0gc20oYWxsX3BhaXJ3aXNlKGNmX2V4cHQsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2JhdGNoID0gInN2YXNlcSIpKQpjZl90YWJsZSA8LSBzbShjb21iaW5lX2RlX3RhYmxlcyhjZl9kZSwgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9jZl90YWJsZXMtdnt2ZXJ9Lnhsc3giKSkpCmNmX3NpZyA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKGNmX3RhYmxlLCBleGNlbCA9IGdsdWU6OmdsdWUoImV4Y2VsL2NmX3NpZy12e3Zlcn0ueGxzeCIpKSkKYGBgCgojIyBXaXRoIHJlc3BlY3QgdG8gc3VzY2VwdGliaWxpdHkKCmBgYHtyIGN1cmVmYWlsX2RlLCBmaWcuc2hvdyA9ICJoaWRlIn0Kc3VzX2RlIDwtIHNtKGFsbF9wYWlyd2lzZShzdXNfZXhwdCwgZmlsdGVyID0gVFJVRSwgbW9kZWxfYmF0Y2ggPSAic3Zhc2VxIikpCnN1c190YWJsZSA8LSBzbShjb21iaW5lX2RlX3RhYmxlcyhzdXNfZGUsIGV4Y2VsID0gZ2x1ZTo6Z2x1ZSgiZXhjZWwvc3VzX3RhYmxlcy12e3Zlcn0ueGxzeCIpKSkKc3VzX3NpZyA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKHN1c190YWJsZSwgZXhjZWwgPSBnbHVlOjpnbHVlKCJleGNlbC9zdXNfc2lnLXZ7dmVyfS54bHN4IikpKQpgYGAKCiMjIE9udG9sb2d5IHNlYXJjaGVzCgpgYGB7ciBnbywgc2lnLnNob3cgPSAiaGlkZSJ9CiMjIEdlbmUgY2F0ZWdvcmllcyBtb3JlIHJlcHJlc2VudGVkIGluIHRoZSAyLjMgZ3JvdXAuCnp5X2dvX3VwIDwtIHNtKHNpbXBsZV9nb3NlcShzaWdfZ2VuZXMgPSB6eV9zaWdbWyJkZXNlcSJdXVtbInVwcyJdXVtbMV1dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ29fZGIgPSBscF9nbywgbGVuZ3RoX2RiID0gbHBfbGVuZ3RocykpCgojIyBHZW5lIGNhdGVnb3JpZXMgbW9yZSByZXByZXNlbnRlZCBpbiB0aGUgMi4yIGdyb3VwLgp6eV9nb19kb3duIDwtIHNtKHNpbXBsZV9nb3NlcShzaWdfZ2VuZXMgPSB6eV9zaWdbWyJkZXNlcSJdXVtbImRvd25zIl1dW1sxXV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvX2RiID0gbHBfZ28sIGxlbmd0aF9kYiA9IGxwX2xlbmd0aHMpKQpgYGAKCiMjIyBBIGNvdXBsZSBwbG90cyBmcm9tIHRoZSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbgoKIyMjIyBOdW1iZXIgb2YgZ2VuZXMgaW4gYWdyZWVtZW50IGFtb25nIERFIG1ldGhvZHMsIDIuMyBtb3JlIHRoYW4gMi4yCgpgYGB7ciBkZV9wbG90c30KenlfdGFibGVbWyJ2ZW5ucyJdXVtbMV1dW1sicF9sZmMxIl1dW1sidXBfbm93ZWlnaHQiXV0KYGBgCgojIyMjIE51bWJlciBvZiBnZW5lcyBpbiBhZ3JlZW1lbnQgYW1vbmcgREUgbWV0aG9kcywgMi4yIG1vcmUgdGhhbiAyLjMKCmBgYHtyIGRlX3Bsb3RzfQp6eV90YWJsZVtbInZlbm5zIl1dW1sxXV1bWyJwX2xmYzEiXV1bWyJkb3duX25vd2VpZ2h0Il1dCmBgYAoKIyMjIyBNQSBwbG90IG9mIHRoZSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBiZXR3ZWVuIHRoZSB6eW1vZGVtZXMuCgpgYGB7ciBvdGhlcl9wbG90c30KenlfdGFibGUkcGxvdHNbWzFdXVtbImRlc2VxX21hX3Bsb3RzIl1dW1sicGxvdCJdXQpgYGAKCiMjIyMgZ29zZXEgb250b2xvZ3kgcGxvdHMgb2YgZ3JvdXBzIG9mIGdlbmVzLCAyLjMgbW9yZSB0aGFuIDIuMgoKYGBge3IgZ29zZXFfdXB9Cnp5X2dvX3VwJHB2YWx1ZV9wbG90cyRicHBfcGxvdF9vdmVyCmBgYAoKIyMjIyBnb3NlcSBvbnRvbG9neSBwbG90cyBvZiBncm91cHMgb2YgZ2VuZXMsIDIuMiBtb3JlIHRoYW4gMi4zCgpgYGB7ciBnb3NlcV9kb3dufQp6eV9nb19kb3duJHB2YWx1ZV9wbG90cyRicHBfcGxvdF9vdmVyCmBgYAoKIyMgWnltb2RlbWUgZW56eW1lIGdlbmUgSURzCgpOYWppYiByZWFkIG1lIGFuIGVtYWlsIGxpc3Rpbmcgb2ZmIHRoZSBnZW5lIG5hbWVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgenltb2RlbWUKY2xhc3NpZmljYXRpb24uICBJIHRvb2sgdGhvc2UgbmFtZXMgYW5kIGNyb3NzIHJlZmVyZW5jZWQgdGhlbSBhZ2FpbnN0IHRoZQpMZWlzaG1hbmlhIHBhbmFtZW5zaXMgZ2VuZSBhbm5vdGF0aW9ucyBhbmQgZm91bmQgdGhlIGZvbGxvd2luZzoKClRoZXkgYXJlOgoKMS4gQUxBVDogTFBBTDEzXzEyMDAxMDkwMCAtLSBhbGFuaW5lIGFtaW5vdHJhbnNmZXJhc2UKMi4gQVNBVDogTFBBTDEzXzM0MDAxMzAwMCAtLSBhc3BhcnRhdGUgYW1pbm90cmFuc2ZlcmFzZQozLiBHNlBEOiBMUEFMMTNfMDAwMDU0MTAwIC0tIGdsdWNhc2UtNi1waG9zcGhhdGUgMS1kZWh5ZHJvZ2VuYXNlCjQuIE5IOiBMUEFMMTNfMTQwMDYxMDAsIExQQUwxM18xODAwMTg1MDAgLS0gaW5vc2luZS1ndWFuaW5lIG51Y2xlb3NpZGUgaHlkcm9sYXNlCjUuIE1QSTogTFBBTDEzXzMyMDAyMjMwMCAobWF5YmUpIC0tIG1hbm5vc2UgcGhvc3BoYXRlIGlzb21lcmFzZSAoSSBjaG9zZSBwaG9zcGhvbWFubm9zZSBpc29tZXJhc2UpCgpHaXZlbiB0aGVzZSA2IGdlbmUgSURzIChOSCBoYXMgdHdvIGdlbmUgSURzIGFzc29jaWF0ZWQgd2l0aCBpdCksIEkgY2FuIGRvIHNvbWUKbG9va2luZyBmb3Igc3BlY2lmaWMgZGlmZmVyZW5jZXMgYW1vbmcgdGhlIHZhcmlvdXMgc2FtcGxlcy4KCiMjIyBFeHByZXNzaW9uIGxldmVscyBvZiB6eW1vZGVtZSBnZW5lcwoKVGhlIGZvbGxvd2luZyBjcmVhdGVzIGEgY29sb3JzcGFjZSAocmVkIHRvIGdyZWVuKSBoZWF0bWFwIHNob3dpbmcgdGhlIG9ic2VydmVkCmV4cHJlc3Npb24gb2YgdGhlc2UgZ2VuZXMgaW4gZXZlcnkgc2FtcGxlLgoKYGBge3Igenltb2RlbWVzfQpteV9nZW5lcyA8LSBjKCJMUEFMMTNfMTIwMDEwOTAwIiwgIkxQQUwxM18zNDAwMTMwMDAiLCAiTFBBTDEzXzAwMDA1NDEwMCIsCiAgICAgICAgICAgICAgIkxQQUwxM18xNDAwMDYxMDAiLCAiTFBBTDEzXzE4MDAxODUwMCIsICJMUEFMMTNfMzIwMDIyMzAwIiwKICAgICAgICAgICAgICAib3RoZXIiKQpteV9uYW1lcyA8LSBjKCJBTEFUIiwgIkFTQVQiLCAiRzZQRCIsICJOSHYxIiwgIk5IdjIiLCAiTVBJIiwgIm90aGVyIikKCnp5bW9fZXhwdCA8LSBleGNsdWRlX2dlbmVzX2V4cHQoenlfbm9ybSwgaWRzID0gbXlfZ2VuZXMsIG1ldGhvZCA9ICJrZWVwIikKdGVzdCA8LSBwbG90X3NhbXBsZV9oZWF0bWFwKHp5bW9fZXhwdCwgcm93X2xhYmVsID0gbXlfbmFtZXMpCmBgYAoKIyMgRW1waXJpY2FsbHkgb2JzZXJ2ZWQgWnltb2RlbWUgZ2VuZXMgZnJvbSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNpcwoKSW4gY29udHJhc3QsIHRoZSBmb2xsb3dpbmcgcGxvdHMgdGFrZSB0aGUgc2V0IG9mIGdlbmVzIHdoaWNoIGFyZSBzaGFyZWQgYW1vbmcKYWxsIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIG1ldGhvZHMgKHxsZmN8ID49IDEuMCBhbmQgYWRqcCA8PSAwLjA1KSBhbmQgdXNlIHRoZW0KdG8gbWFrZSBjYXRlZ29yaWVzIG9mIGdlbmVzIHdoaWNoIGFyZSBpbmNyZWFzZWQgaW4gMi4zIG9yIDIuMi4KCmBgYHtyIHp5bW9kZW1lX2dlbmVzX2VtcGlyaWNhbH0Kc2hhcmVkX3p5bW8gPC0gaW50ZXJzZWN0X3NpZ25pZmljYW50KHp5X3RhYmxlKQp1cF9zaGFyZWQgPC0gc2hhcmVkX3p5bW9bWyJ1cHMiXV1bWzFdXVtbImRhdGEiXV1bWyJhbGwiXV0Kcm93bmFtZXModXBfc2hhcmVkKQp1cHNoYXJlZF9leHB0IDwtIGV4Y2x1ZGVfZ2VuZXNfZXhwdCh6eV9ub3JtLCBpZHMgPSByb3duYW1lcyh1cF9zaGFyZWQpLCBtZXRob2QgPSAia2VlcCIpCmBgYAoKIyMjIEhlYXRtYXAgb2Ygenltb2RlbWUgZ2VuZSBleHByZXNzaW9uIGluY3JlYXNlZCBpbiAyLjMgdnMuIDIuMgoKYGBge3Igenltb2VtcHVwfQp0ZXN0IDwtIHBsb3Rfc2FtcGxlX2hlYXRtYXAodXBzaGFyZWRfZXhwdCwgcm93X2xhYmVsID0gcm93bmFtZXModXBfc2hhcmVkKSkKYGBgCgojIyMgSGVhdG1hcCBvZiB6eW1vZGVtZSBnZW5lIGV4cHJlc3Npb24gaW5jcmVhc2VkIGluIDIuMiB2cy4gMi4zCgpgYGB7ciB6eW1vZW1kb3dufQpkb3duX3NoYXJlZCA8LSBzaGFyZWRfenltb1tbImRvd25zIl1dW1sxXV1bWyJkYXRhIl1dW1siYWxsIl1dCmRvd25zaGFyZWRfZXhwdCA8LSBleGNsdWRlX2dlbmVzX2V4cHQoenlfbm9ybSwgaWRzID0gcm93bmFtZXMoZG93bl9zaGFyZWQpLCBtZXRob2QgPSAia2VlcCIpCnRlc3QgPC0gcGxvdF9zYW1wbGVfaGVhdG1hcChkb3duc2hhcmVkX2V4cHQsIHJvd19sYWJlbCA9IHJvd25hbWVzKGRvd25fc2hhcmVkKSkKYGBgCgojIFNOUCBwcm9maWxlcwoKSW4gdGhpcyBibG9jaywgSSBhbSBjb21iaW5pbmcgb3VyIHByZXZpb3VzIHNhbXBsZXMgYW5kIG91ciBuZXcgc2FtcGxlcyBpbiB0aGUKaG9wZXMgb2YgZmluZGluZyB2YXJpYW50IHBvc2l0aW9ucyB3aGljaCBoZWxwIGVsdWNpZGF0ZSBhc3BlY3RzIG9mIGVpdGhlciB0aGUKbmV3IG9yIG9sZCBzYW1wbGVzLiAgSW4gb3RoZXIgd29yZHMsIHdlIGRvIG5vdCBrbm93IHRoZSB6eW1vZGVtZSBhbm5vdGF0aW9ucyBmb3IKdGhlIG9sZCBzYW1wbGVzIG5vciB0aGUgc3RyYWluIGlkZW50aXRpZXMgKG9yIHRoZSBzaG9ydGN1dCAnY2hyb25pYwp2cy4gc2VsZi1oZWFsaW5nJykgZm9yIHRoZSBuZXcgc2FtcGxlcy4gIFdlIG1heSBiZSBhYmxlIHRvIG1ha2UgZWR1Y2F0ZWQgZ3Vlc3NlcwpnaXZlbiB0aGUgdmFyaWFudCBwcm9maWxlcy4gIFRoZXJlIGFyZSBzb21lIGRpZmZlcmVuY2VzIGluIGhvdyB0aGUgcHJldmlvdXMgYW5kCmN1cnJlbnQgZGF0YSBzZXRzIHdlcmUgYW5hbHl6ZWQgKHRob3VnaCBJIGhhdmUgc2luY2UgcmVkb25lIHRoZSBvbGQgc2FtcGxlcyBzbwppdCBzaG91bGQgYmUgdHJpdmlhbCB0byByZW1vdmUgdGhvc2UgZGlmZmVyZW5jZXMgbm93KS4KCmBgYHtyIG9sZG5ld192YXJpYW50c30Kb2xkX2V4cHQgPC0gc20oY3JlYXRlX2V4cHQoInNhbXBsZV9zaGVldHMvdG1yYzJfc2FtcGxlc18yMDE5MTIwMy54bHN4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZV9jb2x1bW4gPSAidG9waGF0MmZpbGUiKSkKCnR0IDwtIGxwX2V4cHQkZXhwcmVzc2lvbnNldApyb3duYW1lcyh0dCkgPC0gZ3N1YihwYXR0ZXJuID0gIl5leG9uXyIsIHJlcGxhY2VtZW50ID0gIiIsIHggPSByb3duYW1lcyh0dCkpCnJvd25hbWVzKHR0KSA8LSBnc3ViKHBhdHRlcm4gPSAiXFwuRTEkIiwgcmVwbGFjZW1lbnQgPSAiIiwgeCA9IHJvd25hbWVzKHR0KSkKbHBfZXhwdCRleHByZXNzaW9uc2V0IDwtIHR0Cgp0dCA8LSBvbGRfZXhwdCRleHByZXNzaW9uc2V0CnJvd25hbWVzKHR0KSA8LSBnc3ViKHBhdHRlcm4gPSAiXmV4b25fIiwgcmVwbGFjZW1lbnQgPSAiIiwgeCA9IHJvd25hbWVzKHR0KSkKcm93bmFtZXModHQpIDwtIGdzdWIocGF0dGVybiA9ICJcXC4xJCIsIHJlcGxhY2VtZW50ID0gIiIsIHggPSByb3duYW1lcyh0dCkpCm9sZF9leHB0JGV4cHJlc3Npb25zZXQgPC0gdHQKCmxwX3NucCA8LSBzdWJzZXRfZXhwdChscF9leHB0LCBzdWJzZXQ9IiFpcy5uYShwRGF0YShscF9leHB0KVtbJ2JjZnRhYmxlJ11dKSIpCm5ld19zbnBzIDwtIHNtKGNvdW50X2V4cHRfc25wcyhscF9zbnAsIGFubm90X2NvbHVtbiA9ICJiY2Z0YWJsZSIpKQpvbGRfc25wcyA8LSBzbShjb3VudF9leHB0X3NucHMob2xkX2V4cHQsIGFubm90X2NvbHVtbiA9ICJiY2Z0YWJsZSIsIHNucF9jb2x1bW4gPSAyKSkKCmJvdGhfc25wcyA8LSBjb21iaW5lX2V4cHRzKG5ld19zbnBzLCBvbGRfc25wcykKYm90aF9ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KGJvdGhfc25wcywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsIGZpbHRlciA9IFRSVUUpKQoKIyMgc3RyYWlucyA8LSBib3RoX25vcm1bWyJkZXNpZ24iXV1bWyJzdHJhaW4iXV0KYm90aF9ub3JtIDwtIHNldF9leHB0X2NvbmRpdGlvbnMoYm90aF9ub3JtLCBmYWN0ID0gInN0cmFpbiIpCmBgYAoKIyMgUGxvdCBvZiBTTlAgcHJvZmlsZXMgZm9yIHp5bW9kZW1lcwoKVGhlIGZvbGxvd2luZyBwbG90IHNob3dzIHRoZSBTTlAgcHJvZmlsZXMgb2YgYWxsIHNhbXBsZXMgKG9sZCBhbmQgbmV3KSB3aGVyZSB0aGUKY29sb3JzIGF0IHRoZSB0b3Agc2hvdyBlaXRoZXIgdGhlIDIuMiBzdHJhaW5zIChvcmFuZ2UpLCAyLjMgc3RyYWlucyAoZ3JlZW4pLCB0aGUKcHJldmlvdXMgc2FtcGxlcyAocHVycGxlKSwgb3IgdGhlIHZhcmlvdXMgbGFiIHN0cmFpbnMgKHBpbmsgZXRjKS4KCmBgYHtyIHBsb3R0aW5nX3ZhcmlhbnRzfQp0dCA8LSBwbG90X2Rpc2hlYXQoYm90aF9ub3JtKQpwcChmaWxlID0gImltYWdlcy9yYXdfc25wX2Rpc2hlYXQucG5nIiwgaW1hZ2UgPSB0dCwgaGVpZ2h0ID0gMTIsIHdpZHRoID0gMTIpCgpzbnBfc2V0cyA8LSBnZXRfc25wX3NldHMoYm90aF9zbnBzLCBmYWN0b3IgPSAiY29uZGl0aW9uIikKYm90aF9leHB0IDwtIGNvbWJpbmVfZXhwdHMobHBfZXhwdCwgb2xkX2V4cHQpCnNucF9nZW5lcyA8LSBzbShzbnBzX3ZzX2dlbmVzKGJvdGhfZXhwdCwgc25wX3NldHMsIGV4cHRfbmFtZV9jb2wgPSAiY2hyb21vc29tZSIpKQoKc3VtbWFyeShzbnBfc2V0cyRtZWRpYW5zKQpoZWFkKHNucF9zZXRzJG1lZGlhbnMsIG49MTAwKQoKc25wX3N1YnNldCA8LSBzbShzbnBfc3Vic2V0X2dlbmVzKAogIGJvdGhfZXhwdCwgYm90aF9zbnBzLAogIGdlbmVzID0gYygiTFBBTDEzXzEyMDAxMDkwMCIsICJMUEFMMTNfMzQwMDEzMDAwIiwgIkxQQUwxM18wMDAwNTQxMDAiLAogICAgICAgICAgIkxQQUwxM18xNDAwMDYxMDAiLCAiTFBBTDEzXzE4MDAxODUwMCIsICJMUEFMMTNfMzIwMDIyMzAwIikpKQojIyB6eW1vX2hlYXQgPC0gcGxvdF9zYW1wbGVfaGVhdG1hcChzbnBfc3Vic2V0LCByb3dfbGFiZWwgPSByb3duYW1lcyhleHBycyhzbnBfc3Vic2V0KSkpCmBgYAoKIyBDbGluaWNhbCByZXNwb25zZSBmb3IgbmV3IHNhbXBsZXMKCmBgYHtyIHNucF9jbGluaWNhbH0KY2xpbmljYWxfc2V0cyA8LSBnZXRfc25wX3NldHMobmV3X3NucHMsIGZhY3RvciA9ICJjbGluaWNhbHJlc3BvbnNlIikKY2xpbmljYWxfZ2VuZXMgPC0gc20oc25wc192c19nZW5lcyhscF9leHB0LCBjbGluaWNhbF9zZXRzLCBleHB0X25hbWVfY29sID0gImNocm9tb3NvbWUiKSkKY2xpbmljYWxfc25wcyA8LSBzbnBzX2ludGVyc2VjdGlvbnMobHBfZXhwdCwgY2xpbmljYWxfc2V0cywgY2hyX2NvbHVtbiA9ICJjaHJvbW9zb21lIikKaGVhZChhcy5kYXRhLmZyYW1lKGNsaW5pY2FsX3NucHMkaW50ZXJzW1siRmFpbHVyZSJdXSkpCmhlYWQoYXMuZGF0YS5mcmFtZShjbGluaWNhbF9zbnBzJGludGVyc1tbIkN1cmUiXV0pKQoKaGVhZChjbGluaWNhbF9zbnBzJGdlbmVfc3VtbWFyaWVzJEZhaWx1cmUpCmhlYWQoY2xpbmljYWxfc25wcyRnZW5lX3N1bW1hcmllcyRDdXJlKQoKYW5ub3QgPC0gZkRhdGEobHBfZXhwdCkKY2xpbmljYWxfaW50ZXJlc3QgPC0gYXMuZGF0YS5mcmFtZShjbGluaWNhbF9zbnBzW1siZ2VuZV9zdW1tYXJpZXMiXV1bWyJDdXJlIl1dKQpjbGluaWNhbF9pbnRlcmVzdCA8LSBtZXJnZShjbGluaWNhbF9pbnRlcmVzdCwgYXMuZGF0YS5mcmFtZShjbGluaWNhbF9zbnBzW1siZ2VuZV9zdW1tYXJpZXMiXV1bWyJGYWlsdXJlIl1dKSwgYnkgPSAicm93Lm5hbWVzIikKcm93bmFtZXMoY2xpbmljYWxfaW50ZXJlc3QpIDwtIGNsaW5pY2FsX2ludGVyZXN0W1siUm93Lm5hbWVzIl1dCmNsaW5pY2FsX2ludGVyZXN0W1siUm93Lm5hbWVzIl1dIDwtIE5VTEwKY29sbmFtZXMoY2xpbmljYWxfaW50ZXJlc3QpIDwtIGMoImN1cmVfc25wcyIsImZhaWxfc25wcyIpCmFubm90IDwtIG1lcmdlKGFubm90LCBjbGluaWNhbF9pbnRlcmVzdCwgYnkgPSAicm93Lm5hbWVzIikKcm93bmFtZXMoYW5ub3QpIDwtIGFubm90W1siUm93Lm5hbWVzIl1dCmFubm90W1siUm93Lm5hbWVzIl1dIDwtIE5VTEwKZkRhdGEobHBfZXhwdCRleHByZXNzaW9uc2V0KSA8LSBhbm5vdApgYGAKCiMgWnltb2RlbWUgZm9yIG5ldyBzYW1wbGVzCgpUaGUgaGVhdG1hcCBwcm9kdWNlZCBoZXJlIHNob3VsZCBzaG93IHRoZSB2YXJpYW50cyBvbmx5IGZvciB0aGUgenltb2RlbWUgZ2VuZXMuCgojIyBIdW50IGZvciBzbnAgY2x1c3RlcnMKCkkgYW0gdGhpbmtpbmcgdGhhdCBpZiB3ZSBmaW5kIGNsdXN0ZXJzIG9mIGxvY2F0aW9ucyB3aGljaCBhcmUgdmFyaWFudCwgdGhhdAptaWdodCBwcm92aWRlIHNvbWUgUENSIHRlc3RpbmcgcG9zc2liaWxpdGllcy4KCmBgYHtyIG5ld196eW1vfQpuZXdfc2V0cyA8LSBnZXRfc25wX3NldHMobmV3X3NucHMsIGZhY3RvciA9ICJwaGVub3R5cGljY2hhcmFjdGVyaXN0aWNzIikKc3VtbWFyeShuZXdfc2V0cykKIyMgMTAwMDAwMDogMi4yCiMjIDAxMDAwMDA6IDIuMwoKc3VtbWFyeShuZXdfc2V0c1tbImludGVyc2VjdGlvbnMiXV1bWyIxMDAwMDAiXV0pCmRpbShuZXdfc2V0cyRpbnRlcnNlY3Rpb25zW1siMTAwMDAwIl1dKQoKc2VxdWVudGlhbF92YXJpYW50cyA8LSBmdW5jdGlvbihzbnBfc2V0cywgY29uZGl0aW9ucyA9IE5VTEwsIG1pbmltdW0gPSAzLCBtYXhpbXVtX3NlcGFyYXRpb24gPSAzKSB7CiAgaWYgKGlzLm51bGwoY29uZGl0aW9ucykpIHsKICAgIGNvbmRpdGlvbnMgPC0gMQogIH0KICBpbnRlcnNlY3Rpb25fc2V0cyA8LSBzbnBfc2V0c1tbImludGVyc2VjdGlvbnMiXV0KICBpbnRlcnNlY3Rpb25fbmFtZXMgPC0gc25wX3NldHNbWyJzZXRfbmFtZXMiXV0KICBjaG9zZW5faW50ZXJzZWN0aW9uIDwtIDEKICBpZiAoaXMubnVtZXJpYyhjb25kaXRpb25zKSkgewogICAgY2hvc2VuX2ludGVyc2VjdGlvbiA8LSBjb25kaXRpb25zCiAgfSBlbHNlIHsKICAgIGludGVyc2VjdGlvbl9pZHggPC0gaW50ZXJzZWN0aW9uX25hbWVzID09IGNvbmRpdGlvbnMKICAgIGNob3Nlbl9pbnRlcnNlY3Rpb24gPC0gbmFtZXMoaW50ZXJzZWN0aW9uX25hbWVzKVtpbnRlcnNlY3Rpb25faWR4XQogIH0KCiAgcG9zc2libGVfcG9zaXRpb25zIDwtIGludGVyc2VjdGlvbl9zZXRzW1tjaG9zZW5faW50ZXJzZWN0aW9uXV0KICBwb3NpdGlvbl90YWJsZSA8LSBkYXRhLmZyYW1lKHJvdy5uYW1lcyA9IHBvc3NpYmxlX3Bvc2l0aW9ucykKICBwYXQgPC0gIl5jaHJfKC4rKV9wb3NfKC4rKV9yZWZfLiokIgogIHBvc2l0aW9uX3RhYmxlW1siY2hyIl1dIDwtIGdzdWIocGF0dGVybiA9IHBhdCwgcmVwbGFjZW1lbnQgPSAiXFwxIiwgeCA9IHJvd25hbWVzKHBvc2l0aW9uX3RhYmxlKSkKICBwb3NpdGlvbl90YWJsZVtbInBvcyJdXSA8LSBhcy5udW1lcmljKGdzdWIocGF0dGVybiA9IHBhdCwgcmVwbGFjZW1lbnQgPSAiXFwyIiwgeCA9IHJvd25hbWVzKHBvc2l0aW9uX3RhYmxlKSkpCiAgcG9zaXRpb25faWR4IDwtIG9yZGVyKHBvc2l0aW9uX3RhYmxlWywgImNociJdLCBwb3NpdGlvbl90YWJsZVssICJwb3MiXSkKICBwb3NpdGlvbl90YWJsZSA8LSBwb3NpdGlvbl90YWJsZVtwb3NpdGlvbl9pZHgsIF0KICBwb3NpdGlvbl90YWJsZVtbImRpc3QiXV0gPC0gMAoKICBsYXN0X2NociA8LSAiIgogIGZvciAociBpbiAxOm5yb3cocG9zaXRpb25fdGFibGUpKSB7CiAgICB0aGlzX2NociA8LSBwb3NpdGlvbl90YWJsZVtyLCAiY2hyIl0KICAgIGlmIChyID09IDEpIHsKICAgICAgcG9zaXRpb25fdGFibGVbciwgImRpc3QiXSA8LSBwb3NpdGlvbl90YWJsZVtyLCAicG9zIl0KICAgICAgbGFzdF9jaHIgPC0gdGhpc19jaHIKICAgICAgbmV4dAogICAgfQogICAgaWYgKHRoaXNfY2hyID09IGxhc3RfY2hyKSB7CiAgICAgIHBvc2l0aW9uX3RhYmxlW3IsICJkaXN0Il0gPC0gcG9zaXRpb25fdGFibGVbciwgInBvcyJdIC0gcG9zaXRpb25fdGFibGVbciAtIDEsICJwb3MiXQogICAgfSBlbHNlIHsKICAgICAgcG9zaXRpb25fdGFibGVbciwgImRpc3QiXSA8LSBwb3NpdGlvbl90YWJsZVtyLCAicG9zIl0KICAgIH0KICAgIGxhc3RfY2hyIDwtIHRoaXNfY2hyCiAgfQoKICBzZXF1ZW50aWFscyA8LSBwb3NpdGlvbl90YWJsZVtbImRpc3QiXV0gPD0gbWF4aW11bV9zZXBhcmF0aW9uCgogICMjIFRoZSBmb2xsb3dpbmcgY2FuIHRlbGwgbWUgaG93IG1hbnkgcnVucyBvZiBlYWNoIGxlbmd0aCBvY2N1cnJlZCwgdGhhdCBpcyBub3QgcXVpdGUgd2hhdCBJIHdhbnQuCiAgIyMgTm93IHVzZSBydW4gbGVuZ3RoIGVuY29kaW5nIHRvIGZpbmQgdGhlIHNldCBvZiBzZXF1ZW50aWFsIHNlcXVlbnRpYWxzIQogIHJsZV9yZXN1bHQgPC0gcmxlKHNlcXVlbnRpYWxzKQogIHJsZV92YWx1ZXMgPC0gcmxlX3Jlc3VsdFtbInZhbHVlcyJdXQogICMjIFRoZSBmb2xsb3dpbmcgbGluZSBpcyBlcXVpdmFsZW50IHRvIGp1c3QgbGVhdmluZyB2YWx1ZXMgYWxvbmU6CiAgIyMgdHJ1ZV92YWx1ZXMgPC0gcmxlX3Jlc3VsdFtbInZhbHVlcyJdXSA9PSBUUlVFCiAgcmxlX2xlbmd0aHMgPC0gcmxlX3Jlc3VsdFtbImxlbmd0aHMiXV0KICB0cnVlX3NlcXVlbnRpYWxzIDwtIHJsZV9sZW5ndGhzW3JsZV92YWx1ZXNdCiAgcmxlX2lkeCA8LSBjdW1zdW0ocmxlX2xlbmd0aHMpW3doaWNoKHJsZV92YWx1ZXMpXQoKICBwb3NpdGlvbl90YWJsZVtbImxhc3Rfc2VxdWVudGlhbCJdXSA8LSAwCiAgY291bnQgPC0gMAogIGZvciAociBpbiBybGVfaWR4KSB7CiAgICBjb3VudCA8LSBjb3VudCArIDEKICAgIHBvc2l0aW9uX3RhYmxlW3IsICJsYXN0X3NlcXVlbnRpYWwiXSA8LSB0cnVlX3NlcXVlbnRpYWxzW2NvdW50XQogIH0KCiAgd2FudGVkX2lkeCA8LSBwb3NpdGlvbl90YWJsZVtbImxhc3Rfc2VxdWVudGlhbCJdXSA+PSBtaW5pbXVtCiAgd2FudGVkIDwtIHBvc2l0aW9uX3RhYmxlW3dhbnRlZF9pZHgsIGMoImNociIsICJwb3MiKV0KICByZXR1cm4od2FudGVkKQp9Cgp6eW1vMjJfc2VxdWVudGlhbHMgPC0gc2VxdWVudGlhbF92YXJpYW50cyhuZXdfc2V0cywgY29uZGl0aW9ucyA9ICIyLjIiKQp6eW1vMjNfc2VxdWVudGlhbHMgPC0gc2VxdWVudGlhbF92YXJpYW50cyhuZXdfc2V0cywgY29uZGl0aW9ucyA9ICIyLjMiKQpgYGAKCmBgYHtyIHp5bW9faGVhdG1hcHN9CnNucF9nZW5lcyA8LSBzbShzbnBzX3ZzX2dlbmVzKGxwX2V4cHQsIG5ld19zZXRzLCBleHB0X25hbWVfY29sID0gImNocm9tb3NvbWUiKSkKbmV3X3p5bW9fbm9ybSAgPC0gbm9ybWFsaXplX2V4cHQobmV3X3NucHMsIGZpbHRlciA9IFRSVUUsIGNvbnZlcnQgPSAiY3BtIiwgbm9ybSA9ICJxdWFudCIsIHRyYW5zZm9ybSA9IFRSVUUpCm5ld196eW1vX25vcm0gPC0gc2V0X2V4cHRfY29uZGl0aW9ucyhuZXdfenltb19ub3JtLCBmYWN0ID0gInBoZW5vdHlwaWNjaGFyYWN0ZXJpc3RpY3MiKQp6eW1vX2hlYXQgPC0gcGxvdF9kaXNoZWF0KG5ld196eW1vX25vcm0pCgp6eW1vX3N1YnNldCA8LSBzbnBfc3Vic2V0X2dlbmVzKGxwX2V4cHQsIG5ld19zbnBzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVzID0gYygiTFBBTDEzXzEyMDAxMDkwMCIsICJMUEFMMTNfMzQwMDEzMDAwIiwgIkxQQUwxM18wMDAwNTQxMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxQQUwxM18xNDAwMDYxMDAiLCAiTFBBTDEzXzE4MDAxODUwMCIsICJMUEFMMTNfMzIwMDIyMzAwIikpCgp6eW1vX3N1YnNldCA8LSBzZXRfZXhwdF9jb25kaXRpb25zKHp5bW9fc3Vic2V0LCBmYWN0ID0gInBoZW5vdHlwaWNjaGFyYWN0ZXJpc3RpY3MiKQojIyB6eW1vX2hlYXQgPC0gcGxvdF9zYW1wbGVfaGVhdG1hcCh6eW1vX3N1YnNldCwgcm93X2xhYmVsID0gcm93bmFtZXMoZXhwcnMoc25wX3N1YnNldCkpKQoKZGVzIDwtIGJvdGhfbm9ybSRkZXNpZ24KdW5kZWZfaWR4IDwtIGlzLm5hKGRlc1tbInN0cmFpbiJdXSkKZGVzW3VuZGVmX2lkeCwgInN0cmFpbiJdIDwtICJ1bmtub3duIgoKIyNobWNvbHMgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCJ5ZWxsb3ciLCJibGFjayIsImRhcmtibHVlIikpKDI1NikKY29ycmVsYXRpb25zIDwtIGhwZ2xfY29yKGV4cHJzKGJvdGhfbm9ybSkpCgp6eW1vX21pc3NpbmdfaWR4IDwtIGlzLm5hKGRlc1tbInBoZW5vdHlwaWNjaGFyYWN0ZXJpc3RpY3MiXV0pCmRlc1t6eW1vX21pc3NpbmdfaWR4LCAicGhlbm90eXBpY2NoYXJhY3RlcmlzdGljcyJdIDwtICJ1bmtub3duIgpteWRlbmRybyA8LSBsaXN0KAogICJjbHVzdGZ1biIgPSBoY2x1c3QsCiAgImx3ZCIgPSAyLjApCmNvbF9kYXRhIDwtIGFzLmRhdGEuZnJhbWUoZGVzWywgYygicGhlbm90eXBpY2NoYXJhY3RlcmlzdGljcyIsICJjbGluaWNhbGNhdGVnb3JpY2FsIildKQp1bmtub3duX2NsaW5pY2FsIDwtIGlzLm5hKGNvbF9kYXRhW1siY2xpbmljYWxjYXRlZ29yaWNhbCJdXSkKcm93X2RhdGEgPC0gYXMuZGF0YS5mcmFtZShkZXNbLCBjKCJzdHJhaW4iKV0pCmNvbG5hbWVzKGNvbF9kYXRhKSA8LSBjKCJ6eW1vZGVtZSIsICJvdXRjb21lIikKY29sX2RhdGFbdW5rbm93bl9jbGluaWNhbCwgIm91dGNvbWUiXSA8LSAidW5kZWZpbmVkIgoKY29sbmFtZXMocm93X2RhdGEpIDwtIGMoInN0cmFpbiIpCm15YW5ub3QgPC0gbGlzdCgKICAiQ29sIiA9IGxpc3QoImRhdGEiID0gY29sX2RhdGEpLAogICJSb3ciID0gbGlzdCgiZGF0YSIgPSByb3dfZGF0YSkpCm15Y2x1c3QgPC0gbGlzdCgiY3V0aCIgPSAxLjAsCiAgICAgICAgICAgICAgICAiY29sIiA9IEJyZXdlckNsdXN0ZXJDb2wpCm15bGFicyA8LSBsaXN0KAogICJSb3ciID0gbGlzdCgibnJvdyIgPSA0KSwKICAiQ29sIiA9IGxpc3QoIm5yb3ciID0gNCkpCmhtY29scyA8LSBjb2xvclJhbXBQYWxldHRlKGMoImRhcmtibHVlIiwgImJlaWdlIikpKDI0MCkKbWFwMSA8LSBhbm5IZWF0bWFwMigKICBjb3JyZWxhdGlvbnMsCiAgZGVuZHJvZ3JhbSA9IG15ZGVuZHJvLAogIGFubm90YXRpb24gPSBteWFubm90LAogIGNsdXN0ZXIgPSBteWNsdXN0LAogIGxhYmVscyA9IG15bGFicywKICAjIyBUaGUgZm9sbG93aW5nIGNvbnRyb2xzIGlmIHRoZSBwaWN0dXJlIGlzIHN5bW1ldHJpYwogIHNjYWxlID0gIm5vbmUiLAogIGNvbCA9IGhtY29scykKcGxvdChtYXAxKQpgYGAKCiMgVXNpbmcgVmFyaWFudCBwcm9maWxlcyB0byBtYWtlIGd1ZXNzZXMgYWJvdXQgc3RyYWlucyBhbmQgY2hyb25pYy9zZWxmLWhlYWxpbmcKClRoZSBmb2xsb3dpbmcgdXNlcyB0aGUgc2FtZSBpbmZvcm1hdGlvbiB0byBtYWtlIHNvbWUgZ3Vlc3NlcyBhYm91dCB0aGUgc3RyYWlucwp1c2VkIGluIHRoZSBuZXcgc2FtcGxlcy4KCmBgYHtyIG9sZF9hbmRfbmV3X2Nocm9uaWN9CmRlcyA8LSBib3RoX25vcm0kZGVzaWduCnVuZGVmX2lkeCA8LSBpcy5uYShkZXNbWyJzdHJhaW4iXV0pCmRlc1t1bmRlZl9pZHgsICJzdHJhaW4iXSA8LSAidW5rbm93biIKIyNobWNvbHMgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCJ5ZWxsb3ciLCJibGFjayIsImRhcmtibHVlIikpKDI1NikKY29ycmVsYXRpb25zIDwtIGhwZ2xfY29yKGV4cHJzKGJvdGhfbm9ybSkpCgpteWRlbmRybyA8LSBsaXN0KAogICJjbHVzdGZ1biIgPSBoY2x1c3QsCiAgImx3ZCIgPSAyLjApCmNvbF9kYXRhIDwtIGFzLmRhdGEuZnJhbWUoZGVzWywgYygiY29uZGl0aW9uIildKQpyb3dfZGF0YSA8LSBhcy5kYXRhLmZyYW1lKGRlc1ssIGMoInN0cmFpbiIpXSkKY29sbmFtZXMoY29sX2RhdGEpIDwtIGMoImNvbmRpdGlvbiIpCmNvbG5hbWVzKHJvd19kYXRhKSA8LSBjKCJzdHJhaW4iKQpteWFubm90IDwtIGxpc3QoCiAgIkNvbCIgPSBsaXN0KCJkYXRhIiA9IGNvbF9kYXRhKSwKICAiUm93IiA9IGxpc3QoImRhdGEiID0gcm93X2RhdGEpKQpteWNsdXN0IDwtIGxpc3QoImN1dGgiID0gMS4wLAogICAgICAgICAgICAgICAgImNvbCIgPSBCcmV3ZXJDbHVzdGVyQ29sKQpteWxhYnMgPC0gbGlzdCgKICAiUm93IiA9IGxpc3QoIm5yb3ciID0gNCksCiAgIkNvbCIgPSBsaXN0KCJucm93IiA9IDQpKQpobWNvbHMgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCJkYXJrYmx1ZSIsICJiZWlnZSIpKSgxNzApCm1hcDEgPC0gYW5uSGVhdG1hcDIoCiAgY29ycmVsYXRpb25zLAogIGRlbmRyb2dyYW0gPSBteWRlbmRybywKICBhbm5vdGF0aW9uID0gbXlhbm5vdCwKICBjbHVzdGVyID0gbXljbHVzdCwKICBsYWJlbHMgPSBteWxhYnMpCiMjICBjb2wgPSBobWNvbHMpCnBsb3QobWFwMSkKYGBgCgpgYGB7ciB0aGVyZXNhX2lkZWF9CnBoZW5vIDwtIHN1YnNldF9leHB0KGxwX2V4cHQsIHN1YnNldCA9ICJjb25kaXRpb249PSd6Mi4yJ3xjb25kaXRpb249PSd6Mi4zJyIpCnBoZW5vX3NucHMgPC0gc20oY291bnRfZXhwdF9zbnBzKHBoZW5vLCBhbm5vdF9jb2x1bW4gPSAiYmNmdGFibGUiKSkKCnhyZWZfcHJvcCA8LSB0YWJsZShwaGVub19zbnBzJGNvbmRpdGlvbnMpCnBoZW5vX3NucHMkY29uZGl0aW9ucwppZHhfdGJsIDwtIGV4cHJzKHBoZW5vX3NucHMpID4gNQpuZXdfdGJsIDwtIGRhdGEuZnJhbWUocm93Lm5hbWVzID0gcm93bmFtZXMoZXhwcnMocGhlbm9fc25wcykpKQpmb3IgKG4gaW4gbmFtZXMoeHJlZl9wcm9wKSkgewogIG5ld190YmxbW25dXSA8LSAwCiAgaWR4X2NvbHMgPC0gd2hpY2gocGhlbm9fc25wc1tbImNvbmRpdGlvbnMiXV0gPT0gbikKICBwcm9wX2NvbCA8LSByb3dTdW1zKGlkeF90YmxbLCBpZHhfY29sc10pIC8geHJlZl9wcm9wW25dCiAgbmV3X3RibFtuXSA8LSBwcm9wX2NvbAp9Cm5ld190YmxbWyJyYXRpbyJdXSA8LSAobmV3X3RibFtbInoyLjIiXV0gLSBuZXdfdGJsW1siejIuMyJdXSkKa2VlcGVycyA8LSBncmVwbCh4ID0gcm93bmFtZXMobmV3X3RibCksIHBhdHRlcm4gPSAiTHBhTDEzIikKbmV3X3RibCA8LSBuZXdfdGJsW2tlZXBlcnMsIF0KbmV3X3RibFtbIlNOUCJdXSA8LSByb3duYW1lcyhuZXdfdGJsKQpuZXdfdGJsW1siQ2hyb21vc29tZSJdXSA8LSBnc3ViKHggPSBuZXdfdGJsW1siU05QIl1dLCBwYXR0ZXJuID0gImNocl8oLiopX3Bvc18uKiIsIHJlcGxhY2VtZW50ID0gIlxcMSIpCm5ld190YmxbWyJQb3NpdGlvbiJdXSA8LSBnc3ViKHggPSBuZXdfdGJsW1siU05QIl1dLCBwYXR0ZXJuID0gIi4qX3Bvc18oXFxkKylfLioiLCByZXBsYWNlbWVudCA9ICJcXDEiKQpuZXdfdGJsIDwtIG5ld190YmxbLCBjKCJTTlAiLCAiQ2hyb21vc29tZSIsICJQb3NpdGlvbiIsICJyYXRpbyIpXQpsaWJyYXJ5KENNcGxvdCkKQ01wbG90KG5ld190YmwpCmBgYAoKYGBge3Igc2F2ZW1lfQppZiAoIWlzVFJVRShnZXQwKCJza2lwX2xvYWQiKSkpIHsKICBwYW5kZXI6OnBhbmRlcihzZXNzaW9uSW5mbygpKQogIG1lc3NhZ2UocGFzdGUwKCJUaGlzIGlzIGhwZ2x0b29scyBjb21taXQ6ICIsIGdldF9naXRfY29tbWl0KCkpKQogIG1lc3NhZ2UocGFzdGUwKCJTYXZpbmcgdG8gIiwgc2F2ZWZpbGUpKQogIHRtcCA8LSBzbShzYXZlbWUoZmlsZW5hbWUgPSBzYXZlZmlsZSkpCn0KYGBgCgpgYGB7ciBsb2FkbWVfYWZ0ZXIsIGV2YWwgPSBGQUxTRX0KdG1wIDwtIGxvYWRtZShmaWxlbmFtZSA9IHNhdmVmaWxlKQpgYGAK