1 TODO

1.1 202603

  1. Remove the problematic replicate and compare ko/wt: we can likely ignore AB
  2. Check for plasmid reads (sequence incoming), perhaps modify genome to put CAS9 in its appropriate location.
  3. Check for C-terminal SAPA sequence reads, expected that they will not be found in the ko samples.

1.2 202512

  1. Define a set of consistent colors. I think have darker shades for the human, but the same colors for both.
  2. Define a dataset which includes our previous CL-Brener/CL-14 data.
  3. We should receive some metadata including infection numbers (particularly for experiment #3), make use of this.
  4. Define a consistent naming scheme. (condition_batch perhaps)
  5. Define some expected numbers of expressed genes for different human/mammalian cell types. This experiment is HeLa, but I think it would be a nice bit of context to explicitly see how it compares to other organisms/cell types.
  6. Add an outlier gene labeler for boxplots and/or print a table of outliers in plot_boxplot().
  7. Figure out some good metrics to see if the number of not-observed genes is relevant to the other results. (plot_prepost is one possibility)
  8. Plot coefficient of variance vs. batch/condition/etc.
  9. Run variance partition
  10. Note: 16 specific genes were knocked out via the addition of PTCs, make use of our freebayes/etc tools to find/quantify them.
  11. Once we have the combined experiment, check batch #3 for how it looks with respect to other timepoints.
  12. Make sure the Cas samples are gone after early plot(s).
  13. Perform DE with BiM/sva/combat, compare the results.
  14. Check/clean multigene families.
  15. Consider with/out batch #3
  16. On the way to that, perform comparisons of batch 3 vs. batch 1/2; perhaps the results will tell us about the batch.
  17. Use kraken to see if there are reads which explain the difference between batch 3 and 1/2. E.g. is there any contamination? We can mostly assume there is not because of the change in human reads.
  18. To that end, provide an explicit ratio of reads/readsmapped/etc for hs/tc or tc/hs

2 Introduction

Let us check out some new cruzi infections following the deletion of a specific gene.

I thought I also did the interrogation of the CLBrener transcriptome, but that appears untrue. I think I may have forgotten to copy the genome in place…

3 Notes about the introduction of CAS9

a pROCK plasmid containing CAS9 followed by GFP and GAPDH waws linearized in order to integrate the CAS9 into a specific location in the cruzi genome. Tc tubulin is flanking a NotI RE site, so I would assume the integration is at one of the tubulin loci. This plasmid has both M13 fwd and M13 rev; M13 rev is pointing toward the GAPDH and m13 forward is pointing to the bacterial origin of replication and AmpR. (This is a streptococcus CAS9)

4 Trans-sialidase genes which were modified

We received an email flagging the following genes as CRISPR/Cas9 targets for the knockouts. I therefore would like to have screenshots of each of these regions to show what differences are observable between the three strains. Note that the lower coverage of the last few samples may mean that we need to stick to the first group.

  • TcCLB.508173.120 Has putative GPI signal (TcChr27-P:822,539..823,681(+))
  • TcCLB.509495.30 Has putative GPI and SAPA repeat (TcChr32-P:789,835..790,509(-))
  • TcCLB.510055.20 GPI (TcChr17-S:526,427..527,035(+))
  • TcCLB.506961.25 GPI ‘repeats but might not be sapa’ (TcChr18-S:3,813..6,947(-))
  • TcCLB.510787.10 GPI ‘sapa repeats’ (TcChr33-P:265,769..269,383(+))
  • TcCLB.511667.30 gpi (TcChr30-P:805,953..806,291(+))
  • TcCLB.507085.30 gpi, highlighted green tyrosine, ‘sapa repeats’ (TcChr33-P:334,656..337,334(+))
  • TcCLB.507427.10 gpi (Tcruzi_7332:137..2,623(+))
  • TcCLB.508913.25 gpi (TcChr17-P:528,683..529,294(-))
  • TcCLB.508857.30 gpi (TcChr11-P:120,891..123,047(-))
  • TcCLB.503993.10 gpi (TcChr30-P:68,612..70,687(-))
  • TcCLB.511323.10 gpi ‘sapa repeats’ (TcChr17-P:560,036..562,504(+))
  • TcCLB.508089.10 gpi (TcChr11-S:239,192..241,345(+))
  • TcCLB.508717.60 gpi (TcChr37-S:483,214..485,571(+))
  • TcCLB.506975.80 gpi (TcChr16-P:552,945..555,065(+))
  • TcCLB.505931.30 gpi (TcChr30-S:68,468..70,552(-))
  • TcCLB.507979.30 gpi (TcChr17-S:559,901..562,405(+))
  • TcCLB.509817.50 gpi (TcChr16-S:553,397..555,544(+))
  • TcCLB.506841.20 gpi (TcChr37-P:483,214..485,571(+))
expected_lower <- c("TcCLB.508173.120", "TcCLB.509495.30", "TcCLB.510055.20", "TcCLB.506961.25",
                    "TcCLB.510787.10", "TcCLB.511667.30", "TcCLB.507085.30",
                    "TcCLB.507427.10", "TcCLB.508913.25", "TcCLB.508857.30",
                    "TcCLB.503993.10", "TcCLB.511323.10", "TcCLB.508089.10",
                    "TcCLB.508717.60", "TcCLB.506975.80", "TcCLB.505931.30",
                    "TcCLB.507979.30", "TcCLB.509817.50", "TcCLB.506841.20")

4.1 Observations in IGV

Note: I am remapping these samples with slightly different parameters which may make this more sensitive for multi gene families, but I do not think it will change anything.

  1. TcCLB.508173.120: No differences observed in samples 06(ko), 36(wt), 23(ab)
  2. TcCLB.509495.30: NDO (no difference observed)
  3. TcCLB.510055.20: Found ko-specific mutations at the very 3’ end of the gene, seems unlikely to induce a change in function nor NMD
  4. TcCLB.506961.25: Insignificant coverage in the wt. Good coverage in ko/ab; 65% G->A in ko to make synoymous codon
  5. TcCLB.510787.10: Inconsistent coverage in all samples, NDO.
  6. TcCLB.511667.30: Low coverage in all samples: NDO
  7. TcCLB.507427.10: Low coverage in wt, T->C 5’ of ko
  8. TcCLB.508913.25: Low coverage in all, NDO
  9. TcCLB.508857.30: Low coverage in wt, NDO
  10. TcCLB.503993.10: NDO
  11. TcCLB.511323.10: NDO, took screenshot
  12. TcCLB.508089.10: NDO
  13. TcCLB.508717.60: NDO low coverage in wt
  14. TcCLB.506975.80: low coverage in all samples.
  15. TcCLB.505931.30: low coverage, NDO, next gene has tremendous coverage
  16. TcCLB.507979.30: NDO
  17. TcCLB.509817.50: low coverage
  18. TcCLB.506841.20: nice coverage, NDO

I therefore opened up the freebayes output sorted by CDS and looked for nonsense mutations introduced in one ko and one AB sample.

I found 43 in the KO and 79 in the AB.

5 Human annotation information

I have a pretty new genome downloaded (202509), so I will (for now) just let my annotation function grab whatever it thinks is reasonable. It chose the 202410 set. Seems good to me.

hs_annot <- load_biomart_annotations()
## The biomart annotations file already exists, loading from it.
tc_annot <- load_gff_annotations("~/libraries/genome/gff/tcruzi_all.gff",
                                 type = "mRNA", id_col = "Parent")
## Returning a df with 24 columns and 23305 rows.
rownames(tc_annot) <- gsub(x = make.names(tc_annot[["Name"]], unique = TRUE),
                           pattern = "\\.\\d+$", replacement = "")
esmer_db <- "org.Tcruzi.CL.Brener.Esmeraldo.like.v68.eg.db"
library(esmer_db, character.only = TRUE)
## Loading required package: AnnotationDbi
## Loading required package: stats4
## Loading required package: BiocGenerics
## Loading required package: generics
## 
## Attaching package: 'generics'
## The following object is masked from 'package:dplyr':
## 
##     explain
## The following objects are masked from 'package:base':
## 
##     as.difftime, as.factor, as.ordered, intersect, is.element, setdiff,
##     setequal, union
## 
## Attaching package: 'BiocGenerics'
## The following objects are masked from 'package:hpgltools':
## 
##     conditions, conditions<-, IQR, mad, sd, var
## The following object is masked from 'package:dplyr':
## 
##     combine
## The following objects are masked from 'package:stats':
## 
##     IQR, mad, sd, var, xtabs
## The following objects are masked from 'package:base':
## 
##     anyDuplicated, aperm, append, as.data.frame, basename, cbind,
##     colnames, dirname, do.call, duplicated, eval, evalq, Filter, Find,
##     get, grep, grepl, is.unsorted, lapply, Map, mapply, match, mget,
##     order, paste, pmax, pmax.int, pmin, pmin.int, Position, rank,
##     rbind, Reduce, rownames, sapply, saveRDS, table, tapply, unique,
##     unsplit, which.max, which.min
## Loading required package: Biobase
## Welcome to Bioconductor
## 
##     Vignettes contain introductory material; view with
##     'browseVignettes()'. To cite Bioconductor, see
##     'citation("Biobase")', and for packages 'citation("pkgname")'.
## 
## Attaching package: 'Biobase'
## The following objects are masked from 'package:hpgltools':
## 
##     exprs<-, notes, pData<-, sampleNames<-
## Loading required package: IRanges
## Loading required package: S4Vectors
## 
## Attaching package: 'S4Vectors'
## The following object is masked from 'package:tidyr':
## 
##     expand
## The following objects are masked from 'package:dplyr':
## 
##     first, rename
## The following object is masked from 'package:utils':
## 
##     findMatches
## The following objects are masked from 'package:base':
## 
##     expand.grid, I, unname
## 
## Attaching package: 'IRanges'
## The following object is masked from 'package:glue':
## 
##     trim
## The following objects are masked from 'package:dplyr':
## 
##     collapse, desc, slice
## 
## Attaching package: 'AnnotationDbi'
## The following object is masked from 'package:dplyr':
## 
##     select
## 
esmer_db <- get0(esmer_db)
all_keytypes <- keytypes(esmer_db)
wanted_idx <- grepl(x = all_keytypes, pattern = "^ANNOT_")
wanted_fields <- all_keytypes[wanted_idx]
nonesmer_db <- "org.Tcruzi.CL.Brener.Non.Esmeraldo.like.v68.eg.db"
unas_db <- "org.Tcruzi.CL.Brener.v68.eg.db"

tc_esmer <- load_orgdb_annotations(esmer_db, keytype = "gid", fields = wanted_fields)
## Unable to find CDSNAME, setting it to ANNOT_EXTERNAL_DB_NAME.
## Unable to find CDSCHROM in the db, removing it.
## Unable to find CDSSTRAND in the db, removing it.
## Unable to find CDSSTART in the db, removing it.
## Unable to find CDSEND in the db, removing it.
## Extracted all gene ids.
## Attempting to select: ANNOT_EXTERNAL_DB_NAME, GENE_TYPE, ANNOT_AA_SEQUENCE_ID, ANNOT_ANNOTATED_GO_COMPONENT, ANNOT_ANNOTATED_GO_FUNCTION, ANNOT_ANNOTATED_GO_ID_COMPONENT, ANNOT_ANNOTATED_GO_ID_FUNCTION, ANNOT_ANNOTATED_GO_ID_PROCESS, ANNOT_ANNOTATED_GO_PROCESS, ANNOT_ANTICODON, ANNOT_APOLLO_LINK_OUT, ANNOT_APOLLO_TRANSCRIPT_DESCRIPTION, ANNOT_CDS, ANNOT_CDS_LENGTH, ANNOT_CHROMOSOME, ANNOT_CODING_END, ANNOT_CODING_START, ANNOT_EC_NUMBERS, ANNOT_EC_NUMBERS_DERIVED, ANNOT_END_MAX, ANNOT_EXON_COUNT, ANNOT_EXTERNAL_DB_NAME, ANNOT_EXTERNAL_DB_VERSION, ANNOT_FIVE_PRIME_UTR_LENGTH, ANNOT_GENE_CONTEXT_END, ANNOT_GENE_CONTEXT_START, ANNOT_GENE_END_MAX, ANNOT_GENE_END_MAX_TEXT, ANNOT_GENE_ENTREZ_ID, ANNOT_GENE_ENTREZ_LINK_DISPLAYTEXT, ANNOT_GENE_ENTREZ_LINK_URL, ANNOT_GENE_EXON_COUNT, ANNOT_GENE_HTS_NONCODING_SNPS, ANNOT_GENE_HTS_NONSYN_SYN_RATIO, ANNOT_GENE_HTS_NONSYNONYMOUS_SNPS, ANNOT_GENE_HTS_STOP_CODON_SNPS, ANNOT_GENE_HTS_SYNONYMOUS_SNPS, ANNOT_GENE_LOCATION_TEXT, ANNOT_GENE_NAME, ANNOT_GENE_ORTHOLOG_NUMBER, ANNOT_GENE_ORTHOMCL_NAME, ANNOT_GENE_PARALOG_NUMBER, ANNOT_GENE_PREVIOUS_IDS, ANNOT_GENE_PRODUCT, ANNOT_GENE_START_MIN, ANNOT_GENE_START_MIN_TEXT, ANNOT_GENE_TOTAL_HTS_SNPS, ANNOT_GENE_TRANSCRIPT_COUNT, ANNOT_GENE_TYPE, ANNOT_GENOMIC_SEQUENCE_LENGTH, ANNOT_GENUS_SPECIES, ANNOT_HAS_MISSING_TRANSCRIPTS, ANNOT_INTERPRO_DESCRIPTION, ANNOT_INTERPRO_ID, ANNOT_IS_DEPRECATED, ANNOT_IS_PSEUDO, ANNOT_ISOELECTRIC_POINT, ANNOT_LOCATION_TEXT, ANNOT_MAP_LOCATION, ANNOT_MCMC_LOCATION, ANNOT_MOLECULAR_WEIGHT, ANNOT_NCBI_TAX_ID, ANNOT_ORTHOMCL_LINK, ANNOT_OVERVIEW, ANNOT_PFAM_DESCRIPTION, ANNOT_PFAM_ID, ANNOT_PIRSF_DESCRIPTION, ANNOT_PIRSF_ID, ANNOT_PREDICTED_GO_COMPONENT, ANNOT_PREDICTED_GO_FUNCTION, ANNOT_PREDICTED_GO_ID_COMPONENT, ANNOT_PREDICTED_GO_ID_FUNCTION, ANNOT_PREDICTED_GO_ID_PROCESS, ANNOT_PREDICTED_GO_PROCESS, ANNOT_PRIMARY_KEY, ANNOT_PROB_MAP, ANNOT_PROB_MCMC, ANNOT_PROSITEPROFILES_DESCRIPTION, ANNOT_PROSITEPROFILES_ID, ANNOT_PROTEIN_LENGTH, ANNOT_PROTEIN_SEQUENCE, ANNOT_PROTEIN_SOURCE_ID, ANNOT_PSEUDO_STRING, ANNOT_SEQUENCE_DATABASE_NAME, ANNOT_SEQUENCE_ID, ANNOT_SIGNALP_PEPTIDE, ANNOT_SMART_DESCRIPTION, ANNOT_SMART_ID, ANNOT_SNPOVERVIEW, ANNOT_SO_ID, ANNOT_SO_TERM_DEFINITION, ANNOT_SO_TERM_NAME, ANNOT_SO_VERSION, ANNOT_START_MIN, ANNOT_STRAND, ANNOT_STRAND_PLUS_MINUS, ANNOT_SUPERFAMILY_DESCRIPTION, ANNOT_SUPERFAMILY_ID, ANNOT_THREE_PRIME_UTR_LENGTH, ANNOT_TIGRFAM_DESCRIPTION, ANNOT_TIGRFAM_ID, ANNOT_TM_COUNT, ANNOT_TRANS_FOUND_PER_GENE_INTERNAL, ANNOT_TRANSCRIPT_INDEX_PER_GENE, ANNOT_TRANSCRIPT_LENGTH, ANNOT_TRANSCRIPT_LINK, ANNOT_TRANSCRIPT_PRODUCT, ANNOT_TRANSCRIPT_SEQUENCE, ANNOT_TRANSCRIPTS_FOUND_PER_GENE, ANNOT_UNIPROT_IDS, ANNOT_UNIPROT_LINKS
## 'select()' returned 1:1 mapping between keys and columns
tc_nonesmer <- load_orgdb_annotations(nonesmer_db, keytype = "gid", fields = wanted_fields)
## 
## Unable to find CDSNAME, setting it to ANNOT_EXTERNAL_DB_NAME.
## Unable to find CDSCHROM in the db, removing it.
## Unable to find CDSSTRAND in the db, removing it.
## Unable to find CDSSTART in the db, removing it.
## Unable to find CDSEND in the db, removing it.
## Extracted all gene ids.
## Attempting to select: ANNOT_EXTERNAL_DB_NAME, GENE_TYPE, ANNOT_AA_SEQUENCE_ID, ANNOT_ANNOTATED_GO_COMPONENT, ANNOT_ANNOTATED_GO_FUNCTION, ANNOT_ANNOTATED_GO_ID_COMPONENT, ANNOT_ANNOTATED_GO_ID_FUNCTION, ANNOT_ANNOTATED_GO_ID_PROCESS, ANNOT_ANNOTATED_GO_PROCESS, ANNOT_ANTICODON, ANNOT_APOLLO_LINK_OUT, ANNOT_APOLLO_TRANSCRIPT_DESCRIPTION, ANNOT_CDS, ANNOT_CDS_LENGTH, ANNOT_CHROMOSOME, ANNOT_CODING_END, ANNOT_CODING_START, ANNOT_EC_NUMBERS, ANNOT_EC_NUMBERS_DERIVED, ANNOT_END_MAX, ANNOT_EXON_COUNT, ANNOT_EXTERNAL_DB_NAME, ANNOT_EXTERNAL_DB_VERSION, ANNOT_FIVE_PRIME_UTR_LENGTH, ANNOT_GENE_CONTEXT_END, ANNOT_GENE_CONTEXT_START, ANNOT_GENE_END_MAX, ANNOT_GENE_END_MAX_TEXT, ANNOT_GENE_ENTREZ_ID, ANNOT_GENE_ENTREZ_LINK_DISPLAYTEXT, ANNOT_GENE_ENTREZ_LINK_URL, ANNOT_GENE_EXON_COUNT, ANNOT_GENE_HTS_NONCODING_SNPS, ANNOT_GENE_HTS_NONSYN_SYN_RATIO, ANNOT_GENE_HTS_NONSYNONYMOUS_SNPS, ANNOT_GENE_HTS_STOP_CODON_SNPS, ANNOT_GENE_HTS_SYNONYMOUS_SNPS, ANNOT_GENE_LOCATION_TEXT, ANNOT_GENE_NAME, ANNOT_GENE_ORTHOLOG_NUMBER, ANNOT_GENE_ORTHOMCL_NAME, ANNOT_GENE_PARALOG_NUMBER, ANNOT_GENE_PREVIOUS_IDS, ANNOT_GENE_PRODUCT, ANNOT_GENE_START_MIN, ANNOT_GENE_START_MIN_TEXT, ANNOT_GENE_TOTAL_HTS_SNPS, ANNOT_GENE_TRANSCRIPT_COUNT, ANNOT_GENE_TYPE, ANNOT_GENOMIC_SEQUENCE_LENGTH, ANNOT_GENUS_SPECIES, ANNOT_HAS_MISSING_TRANSCRIPTS, ANNOT_INTERPRO_DESCRIPTION, ANNOT_INTERPRO_ID, ANNOT_IS_DEPRECATED, ANNOT_IS_PSEUDO, ANNOT_ISOELECTRIC_POINT, ANNOT_LOCATION_TEXT, ANNOT_MAP_LOCATION, ANNOT_MCMC_LOCATION, ANNOT_MOLECULAR_WEIGHT, ANNOT_NCBI_TAX_ID, ANNOT_ORTHOMCL_LINK, ANNOT_OVERVIEW, ANNOT_PFAM_DESCRIPTION, ANNOT_PFAM_ID, ANNOT_PIRSF_DESCRIPTION, ANNOT_PIRSF_ID, ANNOT_PREDICTED_GO_COMPONENT, ANNOT_PREDICTED_GO_FUNCTION, ANNOT_PREDICTED_GO_ID_COMPONENT, ANNOT_PREDICTED_GO_ID_FUNCTION, ANNOT_PREDICTED_GO_ID_PROCESS, ANNOT_PREDICTED_GO_PROCESS, ANNOT_PRIMARY_KEY, ANNOT_PROB_MAP, ANNOT_PROB_MCMC, ANNOT_PROSITEPROFILES_DESCRIPTION, ANNOT_PROSITEPROFILES_ID, ANNOT_PROTEIN_LENGTH, ANNOT_PROTEIN_SEQUENCE, ANNOT_PROTEIN_SOURCE_ID, ANNOT_PSEUDO_STRING, ANNOT_SEQUENCE_DATABASE_NAME, ANNOT_SEQUENCE_ID, ANNOT_SIGNALP_PEPTIDE, ANNOT_SMART_DESCRIPTION, ANNOT_SMART_ID, ANNOT_SNPOVERVIEW, ANNOT_SO_ID, ANNOT_SO_TERM_DEFINITION, ANNOT_SO_TERM_NAME, ANNOT_SO_VERSION, ANNOT_START_MIN, ANNOT_STRAND, ANNOT_STRAND_PLUS_MINUS, ANNOT_SUPERFAMILY_DESCRIPTION, ANNOT_SUPERFAMILY_ID, ANNOT_THREE_PRIME_UTR_LENGTH, ANNOT_TIGRFAM_DESCRIPTION, ANNOT_TIGRFAM_ID, ANNOT_TM_COUNT, ANNOT_TRANS_FOUND_PER_GENE_INTERNAL, ANNOT_TRANSCRIPT_INDEX_PER_GENE, ANNOT_TRANSCRIPT_LENGTH, ANNOT_TRANSCRIPT_LINK, ANNOT_TRANSCRIPT_PRODUCT, ANNOT_TRANSCRIPT_SEQUENCE, ANNOT_TRANSCRIPTS_FOUND_PER_GENE, ANNOT_UNIPROT_IDS, ANNOT_UNIPROT_LINKS
## 'select()' returned 1:1 mapping between keys and columns
tc_unas <- load_orgdb_annotations(unas_db, keytype = "gid", fields = wanted_fields)
## 
## Unable to find CDSNAME, setting it to ANNOT_EXTERNAL_DB_NAME.
## Unable to find CDSCHROM in the db, removing it.
## Unable to find CDSSTRAND in the db, removing it.
## Unable to find CDSSTART in the db, removing it.
## Unable to find CDSEND in the db, removing it.
## Extracted all gene ids.
## Attempting to select: ANNOT_EXTERNAL_DB_NAME, GENE_TYPE, ANNOT_AA_SEQUENCE_ID, ANNOT_ANNOTATED_GO_COMPONENT, ANNOT_ANNOTATED_GO_FUNCTION, ANNOT_ANNOTATED_GO_ID_COMPONENT, ANNOT_ANNOTATED_GO_ID_FUNCTION, ANNOT_ANNOTATED_GO_ID_PROCESS, ANNOT_ANNOTATED_GO_PROCESS, ANNOT_ANTICODON, ANNOT_APOLLO_LINK_OUT, ANNOT_APOLLO_TRANSCRIPT_DESCRIPTION, ANNOT_CDS, ANNOT_CDS_LENGTH, ANNOT_CHROMOSOME, ANNOT_CODING_END, ANNOT_CODING_START, ANNOT_EC_NUMBERS, ANNOT_EC_NUMBERS_DERIVED, ANNOT_END_MAX, ANNOT_EXON_COUNT, ANNOT_EXTERNAL_DB_NAME, ANNOT_EXTERNAL_DB_VERSION, ANNOT_FIVE_PRIME_UTR_LENGTH, ANNOT_GENE_CONTEXT_END, ANNOT_GENE_CONTEXT_START, ANNOT_GENE_END_MAX, ANNOT_GENE_END_MAX_TEXT, ANNOT_GENE_ENTREZ_ID, ANNOT_GENE_ENTREZ_LINK_DISPLAYTEXT, ANNOT_GENE_ENTREZ_LINK_URL, ANNOT_GENE_EXON_COUNT, ANNOT_GENE_HTS_NONCODING_SNPS, ANNOT_GENE_HTS_NONSYN_SYN_RATIO, ANNOT_GENE_HTS_NONSYNONYMOUS_SNPS, ANNOT_GENE_HTS_STOP_CODON_SNPS, ANNOT_GENE_HTS_SYNONYMOUS_SNPS, ANNOT_GENE_LOCATION_TEXT, ANNOT_GENE_NAME, ANNOT_GENE_ORTHOLOG_NUMBER, ANNOT_GENE_ORTHOMCL_NAME, ANNOT_GENE_PARALOG_NUMBER, ANNOT_GENE_PREVIOUS_IDS, ANNOT_GENE_PRODUCT, ANNOT_GENE_START_MIN, ANNOT_GENE_START_MIN_TEXT, ANNOT_GENE_TOTAL_HTS_SNPS, ANNOT_GENE_TRANSCRIPT_COUNT, ANNOT_GENE_TYPE, ANNOT_GENOMIC_SEQUENCE_LENGTH, ANNOT_GENUS_SPECIES, ANNOT_HAS_MISSING_TRANSCRIPTS, ANNOT_INTERPRO_DESCRIPTION, ANNOT_INTERPRO_ID, ANNOT_IS_DEPRECATED, ANNOT_IS_PSEUDO, ANNOT_ISOELECTRIC_POINT, ANNOT_LOCATION_TEXT, ANNOT_MAP_LOCATION, ANNOT_MCMC_LOCATION, ANNOT_MOLECULAR_WEIGHT, ANNOT_NCBI_TAX_ID, ANNOT_ORTHOMCL_LINK, ANNOT_OVERVIEW, ANNOT_PFAM_DESCRIPTION, ANNOT_PFAM_ID, ANNOT_PIRSF_DESCRIPTION, ANNOT_PIRSF_ID, ANNOT_PREDICTED_GO_COMPONENT, ANNOT_PREDICTED_GO_FUNCTION, ANNOT_PREDICTED_GO_ID_COMPONENT, ANNOT_PREDICTED_GO_ID_FUNCTION, ANNOT_PREDICTED_GO_ID_PROCESS, ANNOT_PREDICTED_GO_PROCESS, ANNOT_PRIMARY_KEY, ANNOT_PROB_MAP, ANNOT_PROB_MCMC, ANNOT_PROSITEPROFILES_DESCRIPTION, ANNOT_PROSITEPROFILES_ID, ANNOT_PROTEIN_LENGTH, ANNOT_PROTEIN_SEQUENCE, ANNOT_PROTEIN_SOURCE_ID, ANNOT_PSEUDO_STRING, ANNOT_SEQUENCE_DATABASE_NAME, ANNOT_SEQUENCE_ID, ANNOT_SIGNALP_PEPTIDE, ANNOT_SMART_DESCRIPTION, ANNOT_SMART_ID, ANNOT_SNPOVERVIEW, ANNOT_SO_ID, ANNOT_SO_TERM_DEFINITION, ANNOT_SO_TERM_NAME, ANNOT_SO_VERSION, ANNOT_START_MIN, ANNOT_STRAND, ANNOT_STRAND_PLUS_MINUS, ANNOT_SUPERFAMILY_DESCRIPTION, ANNOT_SUPERFAMILY_ID, ANNOT_THREE_PRIME_UTR_LENGTH, ANNOT_TIGRFAM_DESCRIPTION, ANNOT_TIGRFAM_ID, ANNOT_TM_COUNT, ANNOT_TRANS_FOUND_PER_GENE_INTERNAL, ANNOT_TRANSCRIPT_INDEX_PER_GENE, ANNOT_TRANSCRIPT_LENGTH, ANNOT_TRANSCRIPT_LINK, ANNOT_TRANSCRIPT_PRODUCT, ANNOT_TRANSCRIPT_SEQUENCE, ANNOT_TRANSCRIPTS_FOUND_PER_GENE, ANNOT_UNIPROT_IDS, ANNOT_UNIPROT_LINKS
## 'select()' returned 1:1 mapping between keys and columns
tc_more <- rbind(tc_esmer$genes, tc_nonesmer$genes, tc_unas$genes)
tc_annot <- merge(tc_annot, tc_more, by = "row.names")
rownames(tc_annot) <- tc_annot[["gid"]]
tc_annot[["gid"]] <- NULL
dim(tc_annot)
## [1] 23304   135

5.1 Load cruzi GO data similarly

tc_esmer_go <- load_orgdb_go(esmer_db, keytype = "GID")
## This is an orgdb, good.
## 'select()' returned 1:many mapping between keys and columns
## 'select()' returned 1:many mapping between keys and columns
tc_nonesmer_go <- load_orgdb_go(nonesmer_db, keytype = "GID")
## This is an orgdb, good.
## 'select()' returned 1:many mapping between keys and columns
## 'select()' returned 1:many mapping between keys and columns
tc_unas_go <- load_orgdb_go(unas_db, keytype = "GID")
## This is an orgdb, good.
## 'select()' returned 1:many mapping between keys and columns
## 'select()' returned 1:many mapping between keys and columns
tc_go <- rbind(tc_esmer_go, tc_nonesmer_go, tc_unas_go)
tc_go <- tc_go[, c("GO", "GID")]
colnames(tc_go) <- c("GO", "ID")

tc_length <- tc_annot[, c("Parent", "annot_transcript_length")]
colnames(tc_length) <- c("ID", "length")

6 Sample sheet

I asked for one from Najib/Amalie but unless I am mistaken it has not arrived. That is not a problem, given two helpful things: April provides one, I also named the directories so that the sample IDs are built in; so I will just make a fake one for now and then merge in whatever I get from them…

sample_sheet <- "sample_sheets/all_samples.xlsx"

meta_sankey <- plot_meta_sankey(as.data.frame(extract_metadata(sample_sheet)),
                                factors = c("background", "exp_number"))
## Did not find the condition column in the sample sheet.
## Filling it in as undefined.
## Did not find the batch column in the sample sheet.
## Filling it in as undefined.
## Checking the state of the condition column.
## Checking the state of the batch column.
## Checking the condition factor.
## Warning: attributes are not identical across measure variables; they will be
## dropped
## Warning: The `size` argument of `element_rect()` is deprecated as of ggplot2 3.4.0.
## ℹ Please use the `linewidth` argument instead.
## ℹ The deprecated feature was likely used in the ggsankey package.
##   Please report the issue at
##   <https://github.com/davidsjoberg/ggsankey/issues>.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
pp(file = "images/meta_sankey.png", image = meta_sankey[["plot"]])

meta_sankey[["plot"]]

7 Adding some metadata

Let us see how well my preprocess gatherer does…

new_meta <- gather_preprocessing_metadata(sample_sheet, species = c("hg38_115", "tcruzi_all"))
## Did not find the condition column in the sample sheet.
## Filling it in as undefined.
## Did not find the batch column in the sample sheet.
## Filling it in as undefined.
## Checking the state of the condition column.
## Checking the state of the batch column.
## Checking the condition factor.
## Warning in readLines(input_handle): incomplete final line found on
## 'preprocessing/38_HeLa_KO7_60hpi/outputs/06kraken_bacteria/kraken.stderr'
## Warning in readLines(input_handle): incomplete final line found on
## 'preprocessing/pos_ctrl/outputs/06kraken_bacteria/kraken.stderr'
## Warning in readLines(input_handle): incomplete final line found on
## 'preprocessing/38_HeLa_KO7_60hpi/outputs/06kraken_bacteria/kraken.stderr'
## Warning in readLines(input_handle): incomplete final line found on
## 'preprocessing/pos_ctrl/outputs/06kraken_bacteria/kraken.stderr'
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(input_df[[column]], na.rm = TRUE): argument is not
## numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in mean.default(sort(x, partial = half + 0L:1L)[half + 0L:1L]):
## argument is not numeric or logical: returning NA
## Warning in dispatch_regex_search(meta, search, replace, input_file_spec, : NAs
## introduced by coercion
## Warning in dispatch_regex_search(meta, search, replace, input_file_spec, : NAs
## introduced by coercion
## Writing new metadata to: sample_sheets/all_samples_modified.xlsx
## Deleting the file sample_sheets/all_samples_modified.xlsx before writing the tables.
head(new_meta[["new_meta"]])
##                                 sampleid short_sampleid samplenumber celltype
## X02_HeLa_control_60h 02_HeLa_control_60h            s01            2     HeLa
## X04_HeLa_WT_60hpi       04_HeLa_WT_60hpi            s02            4     HeLa
## X06_HeLa_KO7_60hpi     06_HeLa_KO7_60hpi            s03            6     HeLa
## X08_HeLa_Cas_60hpi     08_HeLa_Cas_60hpi            s04            8     HeLa
## X18_HeLa_control_60h 18_HeLa_control_60h            s05           18     HeLa
## X20_HeLa_WT_60hpi       20_HeLa_WT_60hpi            s06           20     HeLa
##                      background  hpi morphology          geno_type
## X02_HeLa_control_60h    control t60h amastigote control_amastigote
## X04_HeLa_WT_60hpi            wt t60h amastigote      wt_amastigote
## X06_HeLa_KO7_60hpi          ko7 t60h amastigote     ko7_amastigote
## X08_HeLa_Cas_60hpi          cas t60h amastigote     cas_amastigote
## X18_HeLa_control_60h    control t60h amastigote control_amastigote
## X20_HeLa_WT_60hpi            wt t60h amastigote      wt_amastigote
##                      myco_relative porphyrobacter_relative exp_number round
## X02_HeLa_control_60h           low                    high         e1    r1
## X04_HeLa_WT_60hpi           medium                  medium         e1    r1
## X06_HeLa_KO7_60hpi            high                     low         e1    r1
## X08_HeLa_Cas_60hpi          medium                     low         e1    r1
## X18_HeLa_control_60h           low                    high         e2    r2
## X20_HeLa_WT_60hpi              low                     low         e2    r2
##                      amount_in_10ul amount_fact
## X02_HeLa_control_60h            183         low
## X04_HeLa_WT_60hpi               304         mid
## X06_HeLa_KO7_60hpi              298         mid
## X08_HeLa_Cas_60hpi              284         mid
## X18_HeLa_control_60h             62         low
## X20_HeLa_WT_60hpi               228         mid
##                                                                                                                                 freebayes_table
## X02_HeLa_control_60h preprocessing/02_HeLa_control_60h/outputs/20251031freebayes_tcruzi_all/all_tags_q-10_c-2_m0.5_M-1.0_ctag-DP_mtag-AB.txt.xz
## X04_HeLa_WT_60hpi       preprocessing/04_HeLa_WT_60hpi/outputs/20251031freebayes_tcruzi_all/all_tags_q-10_c-2_m0.5_M-1.0_ctag-DP_mtag-AB.txt.xz
## X06_HeLa_KO7_60hpi     preprocessing/06_HeLa_KO7_60hpi/outputs/20251031freebayes_tcruzi_all/all_tags_q-10_c-2_m0.5_M-1.0_ctag-DP_mtag-AB.txt.xz
## X08_HeLa_Cas_60hpi     preprocessing/08_HeLa_Cas_60hpi/outputs/20251031freebayes_tcruzi_all/all_tags_q-10_c-2_m0.5_M-1.0_ctag-DP_mtag-AB.txt.xz
## X18_HeLa_control_60h preprocessing/18_HeLa_control_60h/outputs/20251031freebayes_tcruzi_all/all_tags_q-10_c-2_m0.5_M-1.0_ctag-DP_mtag-AB.txt.xz
## X20_HeLa_WT_60hpi       preprocessing/20_HeLa_WT_60hpi/outputs/20251031freebayes_tcruzi_all/all_tags_q-10_c-2_m0.5_M-1.0_ctag-DP_mtag-AB.txt.xz
##                      condition     batch     sampleid_backup trimomatic_input
## X02_HeLa_control_60h undefined undefined 02_HeLa_control_60h         34421670
## X04_HeLa_WT_60hpi    undefined undefined    04_HeLa_WT_60hpi         33338315
## X06_HeLa_KO7_60hpi   undefined undefined   06_HeLa_KO7_60hpi         36904955
## X08_HeLa_Cas_60hpi   undefined undefined   08_HeLa_Cas_60hpi         34230672
## X18_HeLa_control_60h undefined undefined 18_HeLa_control_60h         31154298
## X20_HeLa_WT_60hpi    undefined undefined    20_HeLa_WT_60hpi         35726918
##                      trimomatic_output trimomatic_percent fastqc_pct_gc
## X02_HeLa_control_60h          31723102              0.922            52
## X04_HeLa_WT_60hpi             30831462              0.925            50
## X06_HeLa_KO7_60hpi            34168992              0.926            50
## X08_HeLa_Cas_60hpi            30953413              0.904            50
## X18_HeLa_control_60h          28104898              0.902            51
## X20_HeLa_WT_60hpi             32916331              0.921            50
##                      fastp_stats_fastp_version
## X02_HeLa_control_60h                    0.26.0
## X04_HeLa_WT_60hpi                       0.26.0
## X06_HeLa_KO7_60hpi                      0.26.0
## X08_HeLa_Cas_60hpi                      0.26.0
## X18_HeLa_control_60h                    0.26.0
## X20_HeLa_WT_60hpi                       0.26.0
##                                  fastp_stats_sequencing
## X02_HeLa_control_60h paired end (59 cycles + 59 cycles)
## X04_HeLa_WT_60hpi    paired end (59 cycles + 59 cycles)
## X06_HeLa_KO7_60hpi   paired end (59 cycles + 59 cycles)
## X08_HeLa_Cas_60hpi   paired end (59 cycles + 59 cycles)
## X18_HeLa_control_60h paired end (59 cycles + 59 cycles)
## X20_HeLa_WT_60hpi    paired end (59 cycles + 59 cycles)
##                      fastp_stats_before_filtering.total_reads
## X02_HeLa_control_60h                                 68843340
## X04_HeLa_WT_60hpi                                    66676630
## X06_HeLa_KO7_60hpi                                   73809910
## X08_HeLa_Cas_60hpi                                   68461344
## X18_HeLa_control_60h                                 62308596
## X20_HeLa_WT_60hpi                                    71453836
##                      fastp_stats_before_filtering.total_bases
## X02_HeLa_control_60h                               4032438711
## X04_HeLa_WT_60hpi                                  3905253130
## X06_HeLa_KO7_60hpi                                 4322818564
## X08_HeLa_Cas_60hpi                                 4009508185
## X18_HeLa_control_60h                               3648984176
## X20_HeLa_WT_60hpi                                  4184598285
##                      fastp_stats_before_filtering.q20_bases
## X02_HeLa_control_60h                             3971967352
## X04_HeLa_WT_60hpi                                3847921520
## X06_HeLa_KO7_60hpi                               4259801599
## X08_HeLa_Cas_60hpi                               3935631820
## X18_HeLa_control_60h                             3589429778
## X20_HeLa_WT_60hpi                                4119866024
##                      fastp_stats_before_filtering.q30_bases
## X02_HeLa_control_60h                             3798910362
## X04_HeLa_WT_60hpi                                3681104917
## X06_HeLa_KO7_60hpi                               4074665666
## X08_HeLa_Cas_60hpi                               3738468097
## X18_HeLa_control_60h                             3428031267
## X20_HeLa_WT_60hpi                                3940157035
##                      fastp_stats_before_filtering.q20_rate
## X02_HeLa_control_60h                              0.985004
## X04_HeLa_WT_60hpi                                 0.985319
## X06_HeLa_KO7_60hpi                                0.985422
## X08_HeLa_Cas_60hpi                                0.981575
## X18_HeLa_control_60h                              0.983679
## X20_HeLa_WT_60hpi                                 0.984531
##                      fastp_stats_before_filtering.q30_rate
## X02_HeLa_control_60h                              0.942088
## X04_HeLa_WT_60hpi                                 0.942603
## X06_HeLa_KO7_60hpi                                0.942595
## X08_HeLa_Cas_60hpi                                0.932401
## X18_HeLa_control_60h                              0.939448
## X20_HeLa_WT_60hpi                                 0.941585
##                      fastp_stats_before_filtering.read1_mean_length
## X02_HeLa_control_60h                                             58
## X04_HeLa_WT_60hpi                                                58
## X06_HeLa_KO7_60hpi                                               58
## X08_HeLa_Cas_60hpi                                               58
## X18_HeLa_control_60h                                             58
## X20_HeLa_WT_60hpi                                                58
##                      fastp_stats_before_filtering.read2_mean_length
## X02_HeLa_control_60h                                             58
## X04_HeLa_WT_60hpi                                                58
## X06_HeLa_KO7_60hpi                                               58
## X08_HeLa_Cas_60hpi                                               58
## X18_HeLa_control_60h                                             58
## X20_HeLa_WT_60hpi                                                58
##                      fastp_stats_before_filtering.gc_content
## X02_HeLa_control_60h                                0.525368
## X04_HeLa_WT_60hpi                                   0.512197
## X06_HeLa_KO7_60hpi                                  0.510167
## X08_HeLa_Cas_60hpi                                  0.509927
## X18_HeLa_control_60h                                0.514831
## X20_HeLa_WT_60hpi                                   0.508481
##                      fastp_stats_after_filtering.total_reads
## X02_HeLa_control_60h                                50023976
## X04_HeLa_WT_60hpi                                   51079586
## X06_HeLa_KO7_60hpi                                  57016038
## X08_HeLa_Cas_60hpi                                  52796020
## X18_HeLa_control_60h                                46538496
## X20_HeLa_WT_60hpi                                   54571358
##                      fastp_stats_after_filtering.total_bases
## X02_HeLa_control_60h                              2928864162
## X04_HeLa_WT_60hpi                                 2990442996
## X06_HeLa_KO7_60hpi                                3337905820
## X08_HeLa_Cas_60hpi                                3090736187
## X18_HeLa_control_60h                              2724402414
## X20_HeLa_WT_60hpi                                 3194553292
##                      fastp_stats_after_filtering.q20_bases
## X02_HeLa_control_60h                            2889102040
## X04_HeLa_WT_60hpi                               2950732070
## X06_HeLa_KO7_60hpi                              3293911781
## X08_HeLa_Cas_60hpi                              3040765340
## X18_HeLa_control_60h                            2686786383
## X20_HeLa_WT_60hpi                               3151784222
##                      fastp_stats_after_filtering.q30_bases
## X02_HeLa_control_60h                            2763235169
## X04_HeLa_WT_60hpi                               2823526482
## X06_HeLa_KO7_60hpi                              3151259663
## X08_HeLa_Cas_60hpi                              2891036118
## X18_HeLa_control_60h                            2568102572
## X20_HeLa_WT_60hpi                               3014558279
##                      fastp_stats_after_filtering.q20_rate
## X02_HeLa_control_60h                             0.986424
## X04_HeLa_WT_60hpi                                0.986721
## X06_HeLa_KO7_60hpi                                0.98682
## X08_HeLa_Cas_60hpi                               0.983832
## X18_HeLa_control_60h                             0.986193
## X20_HeLa_WT_60hpi                                0.986612
##                      fastp_stats_after_filtering.q30_rate
## X02_HeLa_control_60h                             0.943449
## X04_HeLa_WT_60hpi                                0.944183
## X06_HeLa_KO7_60hpi                               0.944083
## X08_HeLa_Cas_60hpi                               0.935388
## X18_HeLa_control_60h                              0.94263
## X20_HeLa_WT_60hpi                                0.943656
##                      fastp_stats_after_filtering.read1_mean_length
## X02_HeLa_control_60h                                            58
## X04_HeLa_WT_60hpi                                               58
## X06_HeLa_KO7_60hpi                                              58
## X08_HeLa_Cas_60hpi                                              58
## X18_HeLa_control_60h                                            58
## X20_HeLa_WT_60hpi                                               58
##                      fastp_stats_after_filtering.read2_mean_length
## X02_HeLa_control_60h                                            58
## X04_HeLa_WT_60hpi                                               58
## X06_HeLa_KO7_60hpi                                              58
## X08_HeLa_Cas_60hpi                                              58
## X18_HeLa_control_60h                                            58
## X20_HeLa_WT_60hpi                                               58
##                      fastp_stats_after_filtering.gc_content
## X02_HeLa_control_60h                               0.506822
## X04_HeLa_WT_60hpi                                  0.500148
## X06_HeLa_KO7_60hpi                                 0.499098
## X08_HeLa_Cas_60hpi                                  0.49879
## X18_HeLa_control_60h                               0.498932
## X20_HeLa_WT_60hpi                                  0.498286
##                      fastp_stats_passed_filter_reads
## X02_HeLa_control_60h                        68064372
## X04_HeLa_WT_60hpi                           65880840
## X06_HeLa_KO7_60hpi                          72928510
## X08_HeLa_Cas_60hpi                          67437148
## X18_HeLa_control_60h                        61543884
## X20_HeLa_WT_60hpi                           70576476
##                      fastp_stats_corrected_reads fastp_stats_corrected_bases
## X02_HeLa_control_60h                       96838                      141661
## X04_HeLa_WT_60hpi                          91263                      129441
## X06_HeLa_KO7_60hpi                         99688                      142186
## X08_HeLa_Cas_60hpi                        111619                      163729
## X18_HeLa_control_60h                       82422                      119676
## X20_HeLa_WT_60hpi                          95456                      134927
##                      fastp_stats_low_quality_reads fastp_stats_too_many_N_reads
## X02_HeLa_control_60h                        542670                         5932
## X04_HeLa_WT_60hpi                           494250                         3950
## X06_HeLa_KO7_60hpi                          569432                         4328
## X08_HeLa_Cas_60hpi                          743868                         4240
## X18_HeLa_control_60h                        492054                         6650
## X20_HeLa_WT_60hpi                           540998                         4804
##                      fastp_stats_low_complexity_reads
## X02_HeLa_control_60h                           230366
## X04_HeLa_WT_60hpi                              297590
## X06_HeLa_KO7_60hpi                             307640
## X08_HeLa_Cas_60hpi                             276088
## X18_HeLa_control_60h                           266008
## X20_HeLa_WT_60hpi                              331558
##                      fastp_stats_too_short_reads fastp_stats_too_long_reads
## X02_HeLa_control_60h                           0                          0
## X04_HeLa_WT_60hpi                              0                          0
## X06_HeLa_KO7_60hpi                             0                          0
## X08_HeLa_Cas_60hpi                             0                          0
## X18_HeLa_control_60h                           0                          0
## X20_HeLa_WT_60hpi                              0                          0
##                      fastp_stats_rate fastp_stats_adapter_trimmed_reads
## X02_HeLa_control_60h         0.262849                             43668
## X04_HeLa_WT_60hpi            0.222915                             59572
## X06_HeLa_KO7_60hpi            0.21628                             66038
## X08_HeLa_Cas_60hpi           0.214465                             62666
## X18_HeLa_control_60h         0.242019                             49912
## X20_HeLa_WT_60hpi            0.224839                             74688
##                      fastp_stats_adapter_trimmed_bases
## X02_HeLa_control_60h                            536787
## X04_HeLa_WT_60hpi                               785873
## X06_HeLa_KO7_60hpi                              863332
## X08_HeLa_Cas_60hpi                              803282
## X18_HeLa_control_60h                            601356
## X20_HeLa_WT_60hpi                               980748
##                      fastp_stats_read1_adapter_sequence
## X02_HeLa_control_60h                        unspecified
## X04_HeLa_WT_60hpi                           unspecified
## X06_HeLa_KO7_60hpi                          unspecified
## X08_HeLa_Cas_60hpi                          unspecified
## X18_HeLa_control_60h                        unspecified
## X20_HeLa_WT_60hpi                           unspecified
##                      fastp_stats_read2_adapter_sequence
## X02_HeLa_control_60h                        unspecified
## X04_HeLa_WT_60hpi                           unspecified
## X06_HeLa_KO7_60hpi                          unspecified
## X08_HeLa_Cas_60hpi                          unspecified
## X18_HeLa_control_60h                        unspecified
## X20_HeLa_WT_60hpi                           unspecified
##                      fastp_stats_read1_adapter_counts.N
## X02_HeLa_control_60h                                970
## X04_HeLa_WT_60hpi                                   726
## X06_HeLa_KO7_60hpi                                  858
## X08_HeLa_Cas_60hpi                                  854
## X18_HeLa_control_60h                               1213
## X20_HeLa_WT_60hpi                                   878
##                      fastp_stats_read1_adapter_counts.NN
## X02_HeLa_control_60h                                1318
## X04_HeLa_WT_60hpi                                   1058
## X06_HeLa_KO7_60hpi                                  1236
## X08_HeLa_Cas_60hpi                                  1156
## X18_HeLa_control_60h                                1801
## X20_HeLa_WT_60hpi                                   1305
##                      fastp_stats_read1_adapter_counts.NNN
## X02_HeLa_control_60h                                 1269
## X04_HeLa_WT_60hpi                                     998
## X06_HeLa_KO7_60hpi                                   1240
## X08_HeLa_Cas_60hpi                                   1203
## X18_HeLa_control_60h                                 1732
## X20_HeLa_WT_60hpi                                    1253
##                      fastp_stats_read1_adapter_counts.NNNN
## X02_HeLa_control_60h                                   767
## X04_HeLa_WT_60hpi                                      609
## X06_HeLa_KO7_60hpi                                     644
## X08_HeLa_Cas_60hpi                                     653
## X18_HeLa_control_60h                                   889
## X20_HeLa_WT_60hpi                                      677
##                      fastp_stats_read1_adapter_counts.others
## X02_HeLa_control_60h                                   15524
## X04_HeLa_WT_60hpi                                      24468
## X06_HeLa_KO7_60hpi                                     26861
## X08_HeLa_Cas_60hpi                                     25180
## X18_HeLa_control_60h                                   17192
## X20_HeLa_WT_60hpi                                      30774
##                      fastp_stats_read2_adapter_counts.C
## X02_HeLa_control_60h                                329
## X04_HeLa_WT_60hpi                                   453
## X06_HeLa_KO7_60hpi                                  464
## X08_HeLa_Cas_60hpi                                  425
## X18_HeLa_control_60h                                319
## X20_HeLa_WT_60hpi                                   506
##                      fastp_stats_read2_adapter_counts.N
## X02_HeLa_control_60h                                951
## X04_HeLa_WT_60hpi                                   720
## X06_HeLa_KO7_60hpi                                  856
## X08_HeLa_Cas_60hpi                                  848
## X18_HeLa_control_60h                               1202
## X20_HeLa_WT_60hpi                                   864
##                      fastp_stats_read2_adapter_counts.NN
## X02_HeLa_control_60h                                1293
## X04_HeLa_WT_60hpi                                   1038
## X06_HeLa_KO7_60hpi                                  1215
## X08_HeLa_Cas_60hpi                                  1133
## X18_HeLa_control_60h                                1758
## X20_HeLa_WT_60hpi                                   1280
##                      fastp_stats_read2_adapter_counts.NNN
## X02_HeLa_control_60h                                 1248
## X04_HeLa_WT_60hpi                                     980
## X06_HeLa_KO7_60hpi                                   1225
## X08_HeLa_Cas_60hpi                                   1177
## X18_HeLa_control_60h                                 1700
## X20_HeLa_WT_60hpi                                    1231
##                      fastp_stats_read2_adapter_counts.NNNN
## X02_HeLa_control_60h                                   746
## X04_HeLa_WT_60hpi                                      598
## X06_HeLa_KO7_60hpi                                     634
## X08_HeLa_Cas_60hpi                                     641
## X18_HeLa_control_60h                                   864
## X20_HeLa_WT_60hpi                                      663
##                      fastp_stats_read2_adapter_counts.others
## X02_HeLa_control_60h                                   17267
## X04_HeLa_WT_60hpi                                      25152
## X06_HeLa_KO7_60hpi                                     27486
## X08_HeLa_Cas_60hpi                                     26228
## X18_HeLa_control_60h                                   19097
## X20_HeLa_WT_60hpi                                      31483
##                      fastp_stats_read2_adapter_counts.G
## X02_HeLa_control_60h                              undef
## X04_HeLa_WT_60hpi                                   293
## X06_HeLa_KO7_60hpi                                  359
## X08_HeLa_Cas_60hpi                                  327
## X18_HeLa_control_60h                              undef
## X20_HeLa_WT_60hpi                                   405
##                      fastp_stats_read2_adapter_counts.T
## X02_HeLa_control_60h                              undef
## X04_HeLa_WT_60hpi                                 undef
## X06_HeLa_KO7_60hpi                                undef
## X08_HeLa_Cas_60hpi                                undef
## X18_HeLa_control_60h                              undef
## X20_HeLa_WT_60hpi                                 undef
##                      kraken_bacterial_classified kraken_bacterial_unclassified
## X02_HeLa_control_60h                      147699                        418871
## X04_HeLa_WT_60hpi                         285754                       6263711
## X06_HeLa_KO7_60hpi                        420912                       8241513
## X08_HeLa_Cas_60hpi                        309973                       7277804
## X18_HeLa_control_60h                      147359                        374703
## X20_HeLa_WT_60hpi                         323491                       8424975
##                      kraken_first_bacterial_species
## X02_HeLa_control_60h        Porphyrobacter sp. GA68
## X04_HeLa_WT_60hpi           Mycoplasmopsis arginini
## X06_HeLa_KO7_60hpi          Mycoplasmopsis arginini
## X08_HeLa_Cas_60hpi          Mycoplasmopsis arginini
## X18_HeLa_control_60h        Porphyrobacter sp. GA68
## X20_HeLa_WT_60hpi             Klebsiella pneumoniae
##                      kraken_first_bacterial_species_reads
## X02_HeLa_control_60h                                34515
## X04_HeLa_WT_60hpi                                   20649
## X06_HeLa_KO7_60hpi                                  97034
## X08_HeLa_Cas_60hpi                                  22086
## X18_HeLa_control_60h                                22324
## X20_HeLa_WT_60hpi                                    4599
##                                                                                         kraken_matrix_bacterial
## X02_HeLa_control_60h       preprocessing/02_HeLa_control_60h/outputs/06kraken_bacteria/kraken_report_matrix.tsv
## X04_HeLa_WT_60hpi       preprocessing/04_HeLa_WT_60hpi/outputs/20251031kraken_bacteria/kraken_report_matrix.tsv
## X06_HeLa_KO7_60hpi           preprocessing/06_HeLa_KO7_60hpi/outputs/06kraken_bacteria/kraken_report_matrix.tsv
## X08_HeLa_Cas_60hpi           preprocessing/08_HeLa_Cas_60hpi/outputs/06kraken_bacteria/kraken_report_matrix.tsv
## X18_HeLa_control_60h preprocessing/18_HeLa_control_60h/outputs/20251031kraken_bacteria/kraken_report_matrix.tsv
## X20_HeLa_WT_60hpi       preprocessing/20_HeLa_WT_60hpi/outputs/20251031kraken_bacteria/kraken_report_matrix.tsv
##                      hisat_rrna_input_reads_hg38_115
## X02_HeLa_control_60h                              NA
## X04_HeLa_WT_60hpi                                 NA
## X06_HeLa_KO7_60hpi                                NA
## X08_HeLa_Cas_60hpi                                NA
## X18_HeLa_control_60h                              NA
## X20_HeLa_WT_60hpi                                 NA
##                      hisat_rrna_input_reads_tcruzi_all
## X02_HeLa_control_60h                          31723102
## X04_HeLa_WT_60hpi                             30831462
## X06_HeLa_KO7_60hpi                                  NA
## X08_HeLa_Cas_60hpi                            30953413
## X18_HeLa_control_60h                          28104898
## X20_HeLa_WT_60hpi                             32916331
##                      hisat_rrna_single_concordant_hg38_115
## X02_HeLa_control_60h                                    NA
## X04_HeLa_WT_60hpi                                       NA
## X06_HeLa_KO7_60hpi                                      NA
## X08_HeLa_Cas_60hpi                                      NA
## X18_HeLa_control_60h                                    NA
## X20_HeLa_WT_60hpi                                       NA
##                      hisat_rrna_single_concordant_tcruzi_all
## X02_HeLa_control_60h                                     265
## X04_HeLa_WT_60hpi                                      13746
## X06_HeLa_KO7_60hpi                                        NA
## X08_HeLa_Cas_60hpi                                     21602
## X18_HeLa_control_60h                                     215
## X20_HeLa_WT_60hpi                                      25929
##                      hisat_rrna_multi_concordant_hg38_115
## X02_HeLa_control_60h                                   NA
## X04_HeLa_WT_60hpi                                      NA
## X06_HeLa_KO7_60hpi                                     NA
## X08_HeLa_Cas_60hpi                                     NA
## X18_HeLa_control_60h                                   NA
## X20_HeLa_WT_60hpi                                      NA
##                      hisat_rrna_multi_concordant_tcruzi_all
## X02_HeLa_control_60h                                     23
## X04_HeLa_WT_60hpi                                      8745
## X06_HeLa_KO7_60hpi                                       NA
## X08_HeLa_Cas_60hpi                                    13293
## X18_HeLa_control_60h                                     26
## X20_HeLa_WT_60hpi                                     15864
##                      hisat_rrna_percent_log_hg38_115
## X02_HeLa_control_60h                              NA
## X04_HeLa_WT_60hpi                                 NA
## X06_HeLa_KO7_60hpi                                NA
## X08_HeLa_Cas_60hpi                                NA
## X18_HeLa_control_60h                              NA
## X20_HeLa_WT_60hpi                                 NA
##                      hisat_rrna_percent_log_tcruzi_all
## X02_HeLa_control_60h                              0.01
## X04_HeLa_WT_60hpi                                 0.09
## X06_HeLa_KO7_60hpi                                  NA
## X08_HeLa_Cas_60hpi                                0.13
## X18_HeLa_control_60h                              0.01
## X20_HeLa_WT_60hpi                                 0.14
##                      hisat_genome_input_reads_hg38_115
## X02_HeLa_control_60h                          31723102
## X04_HeLa_WT_60hpi                             30831462
## X06_HeLa_KO7_60hpi                            34168992
## X08_HeLa_Cas_60hpi                            30953413
## X18_HeLa_control_60h                          28104898
## X20_HeLa_WT_60hpi                             32916331
##                      hisat_genome_input_reads_tcruzi_all
## X02_HeLa_control_60h                            31723102
## X04_HeLa_WT_60hpi                               30831462
## X06_HeLa_KO7_60hpi                                    NA
## X08_HeLa_Cas_60hpi                              30953413
## X18_HeLa_control_60h                            28104898
## X20_HeLa_WT_60hpi                               32916331
##                      hisat_genome_single_concordant_hg38_115
## X02_HeLa_control_60h                                27374698
## X04_HeLa_WT_60hpi                                   21550886
## X06_HeLa_KO7_60hpi                                  22809478
## X08_HeLa_Cas_60hpi                                  20831115
## X18_HeLa_control_60h                                24646849
## X20_HeLa_WT_60hpi                                   21560373
##                      hisat_genome_single_concordant_tcruzi_all
## X02_HeLa_control_60h                                      5363
## X04_HeLa_WT_60hpi                                      3984432
## X06_HeLa_KO7_60hpi                                          NA
## X08_HeLa_Cas_60hpi                                     4602984
## X18_HeLa_control_60h                                      9351
## X20_HeLa_WT_60hpi                                      5394425
##                      hisat_genome_multi_concordant_hg38_115
## X02_HeLa_control_60h                                3781834
## X04_HeLa_WT_60hpi                                   2731111
## X06_HeLa_KO7_60hpi                                  2697089
## X08_HeLa_Cas_60hpi                                  2534521
## X18_HeLa_control_60h                                2935987
## X20_HeLa_WT_60hpi                                   2607492
##                      hisat_genome_multi_concordant_tcruzi_all
## X02_HeLa_control_60h                                     3176
## X04_HeLa_WT_60hpi                                     1739149
## X06_HeLa_KO7_60hpi                                         NA
## X08_HeLa_Cas_60hpi                                    2063574
## X18_HeLa_control_60h                                     6690
## X20_HeLa_WT_60hpi                                     2363417
##                      hisat_genome_single_all_hg38_115
## X02_HeLa_control_60h                           393579
## X04_HeLa_WT_60hpi                              386791
## X06_HeLa_KO7_60hpi                             404039
## X08_HeLa_Cas_60hpi                             370232
## X18_HeLa_control_60h                           371885
## X20_HeLa_WT_60hpi                              394781
##                      hisat_genome_single_all_tcruzi_all
## X02_HeLa_control_60h                              66941
## X04_HeLa_WT_60hpi                                223361
## X06_HeLa_KO7_60hpi                                   NA
## X08_HeLa_Cas_60hpi                               232208
## X18_HeLa_control_60h                              77290
## X20_HeLa_WT_60hpi                                288620
##                      hisat_genome_multi_all_hg38_115
## X02_HeLa_control_60h                          147888
## X04_HeLa_WT_60hpi                             125185
## X06_HeLa_KO7_60hpi                            135313
## X08_HeLa_Cas_60hpi                            118754
## X18_HeLa_control_60h                          118560
## X20_HeLa_WT_60hpi                             124747
##                      hisat_genome_multi_all_tcruzi_all hisat_unmapped_hg38_115
## X02_HeLa_control_60h                             41174                  485321
## X04_HeLa_WT_60hpi                               110555                12501300
## X06_HeLa_KO7_60hpi                                  NA                16692890
## X08_HeLa_Cas_60hpi                              116543                14599664
## X18_HeLa_control_60h                             38204                  474391
## X20_HeLa_WT_60hpi                               132039                16893802
##                      hisat_unmapped_tcruzi_all
## X02_HeLa_control_60h                  63320953
## X04_HeLa_WT_60hpi                     49859944
## X06_HeLa_KO7_60hpi                          NA
## X08_HeLa_Cas_60hpi                    48200809
## X18_HeLa_control_60h                  56062102
## X20_HeLa_WT_60hpi                     49864471
##                      hisat_genome_percent_log_hg38_115
## X02_HeLa_control_60h                             99.24
## X04_HeLa_WT_60hpi                                79.73
## X06_HeLa_KO7_60hpi                               75.57
## X08_HeLa_Cas_60hpi                               76.42
## X18_HeLa_control_60h                             99.16
## X20_HeLa_WT_60hpi                                74.34
##                      hisat_genome_percent_log_tcruzi_all
## X02_HeLa_control_60h                                0.20
## X04_HeLa_WT_60hpi                                  19.14
## X06_HeLa_KO7_60hpi                                    NA
## X08_HeLa_Cas_60hpi                                 22.14
## X18_HeLa_control_60h                                0.26
## X20_HeLa_WT_60hpi                                  24.26
##                      hisat_observed_genes_hg38_115
## X02_HeLa_control_60h                         15212
## X04_HeLa_WT_60hpi                            15335
## X06_HeLa_KO7_60hpi                           15426
## X08_HeLa_Cas_60hpi                           15346
## X18_HeLa_control_60h                         15533
## X20_HeLa_WT_60hpi                            15803
##                      hisat_observed_genes_tcruzi_all
## X02_HeLa_control_60h                              82
## X04_HeLa_WT_60hpi                              22472
## X06_HeLa_KO7_60hpi                             22538
## X08_HeLa_Cas_60hpi                             22482
## X18_HeLa_control_60h                             531
## X20_HeLa_WT_60hpi                              22802
##                                             hisat_observed_median_exprs_hg38_115
## X02_HeLa_control_60h                                                        <NA>
## X04_HeLa_WT_60hpi    gene:ENSG00000163297\t4\t79901146\t80125454\t-\t224309\t139
## X06_HeLa_KO7_60hpi                                                          <NA>
## X08_HeLa_Cas_60hpi                                                          <NA>
## X18_HeLa_control_60h                                                        <NA>
## X20_HeLa_WT_60hpi                                                           <NA>
##                                  hisat_observed_median_exprs_tcruzi_all
## X02_HeLa_control_60h TcCLB.508203.29\tTcChr2-S\t31170\t31472\t-\t303\t0
## X04_HeLa_WT_60hpi    TcCLB.508203.29\tTcChr2-S\t31170\t31472\t-\t303\t1
## X06_HeLa_KO7_60hpi   TcCLB.508203.29\tTcChr2-S\t31170\t31472\t-\t303\t0
## X08_HeLa_Cas_60hpi   TcCLB.508203.29\tTcChr2-S\t31170\t31472\t-\t303\t0
## X18_HeLa_control_60h TcCLB.508203.29\tTcChr2-S\t31170\t31472\t-\t303\t0
## X20_HeLa_WT_60hpi    TcCLB.508203.29\tTcChr2-S\t31170\t31472\t-\t303\t2
##                                                                            hisat_alignment_hg38_115
## X02_HeLa_control_60h preprocessing/02_HeLa_control_60h/outputs/04hisat_hg38_115/hg38_115_genome.bam
## X04_HeLa_WT_60hpi       preprocessing/04_HeLa_WT_60hpi/outputs/04hisat_hg38_115/hg38_115_genome.bam
## X06_HeLa_KO7_60hpi     preprocessing/06_HeLa_KO7_60hpi/outputs/04hisat_hg38_115/hg38_115_genome.bam
## X08_HeLa_Cas_60hpi     preprocessing/08_HeLa_Cas_60hpi/outputs/04hisat_hg38_115/hg38_115_genome.bam
## X18_HeLa_control_60h preprocessing/18_HeLa_control_60h/outputs/04hisat_hg38_115/hg38_115_genome.bam
## X20_HeLa_WT_60hpi       preprocessing/20_HeLa_WT_60hpi/outputs/04hisat_hg38_115/hg38_115_genome.bam
##                                                                                    hisat_alignment_tcruzi_all
## X02_HeLa_control_60h preprocessing/02_HeLa_control_60h/outputs/20251031hisat_tcruzi_all/tcruzi_all_genome.bam
## X04_HeLa_WT_60hpi       preprocessing/04_HeLa_WT_60hpi/outputs/20251031hisat_tcruzi_all/tcruzi_all_genome.bam
## X06_HeLa_KO7_60hpi     preprocessing/06_HeLa_KO7_60hpi/outputs/20251031hisat_tcruzi_all/tcruzi_all_genome.bam
## X08_HeLa_Cas_60hpi     preprocessing/08_HeLa_Cas_60hpi/outputs/20251031hisat_tcruzi_all/tcruzi_all_genome.bam
## X18_HeLa_control_60h preprocessing/18_HeLa_control_60h/outputs/20251031hisat_tcruzi_all/tcruzi_all_genome.bam
## X20_HeLa_WT_60hpi       preprocessing/20_HeLa_WT_60hpi/outputs/20251031hisat_tcruzi_all/tcruzi_all_genome.bam
##                      salmon_percent_hg38_115 salmon_percent_tcruzi_all
## X02_HeLa_control_60h                      NA                  0.008861
## X04_HeLa_WT_60hpi                         NA                  9.584910
## X06_HeLa_KO7_60hpi                     33.15                 11.219200
## X08_HeLa_Cas_60hpi                     33.47                 10.873800
## X18_HeLa_control_60h                      NA                  0.009966
## X20_HeLa_WT_60hpi                      34.33                 12.117900
##                      salmon_observed_genes_hg38_115
## X02_HeLa_control_60h                          47839
## X04_HeLa_WT_60hpi                             46509
## X06_HeLa_KO7_60hpi                            48117
## X08_HeLa_Cas_60hpi                            46291
## X18_HeLa_control_60h                          47978
## X20_HeLa_WT_60hpi                             47985
##                      salmon_observed_genes_tcruzi_all
## X02_HeLa_control_60h                              121
## X04_HeLa_WT_60hpi                               19145
## X06_HeLa_KO7_60hpi                              19177
## X08_HeLa_Cas_60hpi                              19153
## X18_HeLa_control_60h                              654
## X20_HeLa_WT_60hpi                               19270
##                                                                  input_r1
## X02_HeLa_control_60h unprocessed/02_HeLa_control_60h_2_S1_R1_001.fastq.gz
## X04_HeLa_WT_60hpi       unprocessed/04_HeLa_WT_60hpi_2_S2_R1_001.fastq.gz
## X06_HeLa_KO7_60hpi     unprocessed/06_HeLa_KO7_60hpi_2_S3_R1_001.fastq.gz
## X08_HeLa_Cas_60hpi     unprocessed/08_HeLa_Cas_60hpi_2_S4_R1_001.fastq.gz
## X18_HeLa_control_60h unprocessed/18_HeLa_control_60h_2_S5_R1_001.fastq.gz
## X20_HeLa_WT_60hpi       unprocessed/20_HeLa_WT_60hpi_2_S6_R1_001.fastq.gz
##                                                                  input_r2
## X02_HeLa_control_60h unprocessed/02_HeLa_control_60h_2_S1_R2_001.fastq.gz
## X04_HeLa_WT_60hpi       unprocessed/04_HeLa_WT_60hpi_2_S2_R2_001.fastq.gz
## X06_HeLa_KO7_60hpi     unprocessed/06_HeLa_KO7_60hpi_2_S3_R2_001.fastq.gz
## X08_HeLa_Cas_60hpi     unprocessed/08_HeLa_Cas_60hpi_2_S4_R2_001.fastq.gz
## X18_HeLa_control_60h unprocessed/18_HeLa_control_60h_2_S5_R2_001.fastq.gz
## X20_HeLa_WT_60hpi       unprocessed/20_HeLa_WT_60hpi_2_S6_R2_001.fastq.gz
##                                                                                                       hisat_count_table_hg38_115
## X02_HeLa_control_60h preprocessing/02_HeLa_control_60h/outputs/04hisat_hg38_115/hg38_115_genome-paired_s2_gene_ID_fcounts.csv.xz
## X04_HeLa_WT_60hpi       preprocessing/04_HeLa_WT_60hpi/outputs/04hisat_hg38_115/hg38_115_genome-paired_s2_gene_ID_fcounts.csv.xz
## X06_HeLa_KO7_60hpi     preprocessing/06_HeLa_KO7_60hpi/outputs/04hisat_hg38_115/hg38_115_genome-paired_s2_gene_ID_fcounts.csv.xz
## X08_HeLa_Cas_60hpi     preprocessing/08_HeLa_Cas_60hpi/outputs/04hisat_hg38_115/hg38_115_genome-paired_s2_gene_ID_fcounts.csv.xz
## X18_HeLa_control_60h preprocessing/18_HeLa_control_60h/outputs/04hisat_hg38_115/hg38_115_genome-paired_s2_gene_ID_fcounts.csv.xz
## X20_HeLa_WT_60hpi       preprocessing/20_HeLa_WT_60hpi/outputs/04hisat_hg38_115/hg38_115_genome-paired_s2_gene_ID_fcounts.csv.xz
##                                                                                                               hisat_count_table_tcruzi_all
## X02_HeLa_control_60h preprocessing/02_HeLa_control_60h/outputs/20251031hisat_tcruzi_all/tcruzi_all_genome-paired_s2_gene_ID_fcounts.csv.xz
## X04_HeLa_WT_60hpi       preprocessing/04_HeLa_WT_60hpi/outputs/20251031hisat_tcruzi_all/tcruzi_all_genome-paired_s2_gene_ID_fcounts.csv.xz
## X06_HeLa_KO7_60hpi     preprocessing/06_HeLa_KO7_60hpi/outputs/20251031hisat_tcruzi_all/tcruzi_all_genome-paired_s2_gene_ID_fcounts.csv.xz
## X08_HeLa_Cas_60hpi     preprocessing/08_HeLa_Cas_60hpi/outputs/20251031hisat_tcruzi_all/tcruzi_all_genome-paired_s2_gene_ID_fcounts.csv.xz
## X18_HeLa_control_60h preprocessing/18_HeLa_control_60h/outputs/20251031hisat_tcruzi_all/tcruzi_all_genome-paired_s2_gene_ID_fcounts.csv.xz
## X20_HeLa_WT_60hpi       preprocessing/20_HeLa_WT_60hpi/outputs/20251031hisat_tcruzi_all/tcruzi_all_genome-paired_s2_gene_ID_fcounts.csv.xz
##                                                                         salmon_count_table_hg38_115
## X02_HeLa_control_60h preprocessing/02_HeLa_control_60h/outputs/20251031salmon_hg38_115_CDS/quant.sf
## X04_HeLa_WT_60hpi       preprocessing/04_HeLa_WT_60hpi/outputs/20251031salmon_hg38_115_CDS/quant.sf
## X06_HeLa_KO7_60hpi     preprocessing/06_HeLa_KO7_60hpi/outputs/20251031salmon_hg38_115_CDS/quant.sf
## X08_HeLa_Cas_60hpi           preprocessing/08_HeLa_Cas_60hpi/outputs/05salmon_hg38_115_CDS/quant.sf
## X18_HeLa_control_60h preprocessing/18_HeLa_control_60h/outputs/20251031salmon_hg38_115_CDS/quant.sf
## X20_HeLa_WT_60hpi       preprocessing/20_HeLa_WT_60hpi/outputs/20251031salmon_hg38_115_CDS/quant.sf
##                                                                         salmon_count_table_tcruzi_all
## X02_HeLa_control_60h preprocessing/02_HeLa_control_60h/outputs/20251031salmon_tcruzi_all_CDS/quant.sf
## X04_HeLa_WT_60hpi       preprocessing/04_HeLa_WT_60hpi/outputs/20251031salmon_tcruzi_all_CDS/quant.sf
## X06_HeLa_KO7_60hpi     preprocessing/06_HeLa_KO7_60hpi/outputs/20251031salmon_tcruzi_all_CDS/quant.sf
## X08_HeLa_Cas_60hpi     preprocessing/08_HeLa_Cas_60hpi/outputs/20251031salmon_tcruzi_all_CDS/quant.sf
## X18_HeLa_control_60h preprocessing/18_HeLa_control_60h/outputs/20251031salmon_tcruzi_all_CDS/quant.sf
## X20_HeLa_WT_60hpi       preprocessing/20_HeLa_WT_60hpi/outputs/20251031salmon_tcruzi_all_CDS/quant.sf

Strangely, this did not pick up the freebayes outputs. I will add them manually to the original sheet. Possibly because I ran it twice with different parameters, my code gets confused when multiple files match the same rule.

8 Define colors

color_choices <- list(
  "hs" = list(
    "AB10" = "#086448",
    "cas" = "#702601",
    "control" = "#454178",
    "ko7" = "#870649",
    "positive" = "#46060E",
    "wt" = "#785C01"),
  "tc" = list(
    "AB10" = "#0DA877",
    "cas" = "#BA3F01",
    "control" = "#7771D1",
    "ko7" = "#BF086A",
    "positive" = "#8F0C1E",
    "wt" = "#AF8401"))

These colors are bad, the human are too dark and lose their contrast with respect to each other. I should get Najib/April/Amalie to help define better.

9 The primary data structure

hs_se <- create_se(new_meta[["new_meta"]], gene_info = hs_annot[["gene_annotations"]],
                   file_column = "hisat_count_table_hg38_115") %>%
  set_conditions(fact = "background") %>%
  set_batches(fact = "exp_number") %>%
  set_colors(color_choices[["hs"]])
## Reading the sample metadata.
## Checking the state of the condition column.
## Checking the state of the batch column.
## Checking the condition factor.
## The sample definitions comprises: 20 rows(samples) and 107 columns(metadata fields).
## Warning in create_se(new_meta[["new_meta"]], gene_info =
## hs_annot[["gene_annotations"]], : Some samples were removed when cross
## referencing the samples against the count data.
## Matched 21562 annotations and counts.
## Some annotations were lost in merging, setting them to 'undefined'.
## Saving the summarized experiment to 'se.rda'.
## The final summarized experiment has 21571 rows and 107 columns.
## The numbers of samples by condition are:
## 
##     AB10      cas  control      ko7 positive       wt 
##        3        1        3        5        1        5
## This function is intended to set the colors of a dataset.
## It was passed an object of type data.frame and does not know what to do.
## The number of samples by batch are:
## 
##    e1    e2    e3    e4 undef 
##     4     4     5     4     1
## Error in `names(old_colors) <- rownames(exp)`:
## ! 'names' attribute [18] must be the same length as the vector [0]
hs_written <- write_se(hs_se, excel = "excel/hs_expression_data.xlsx")
## Deleting the file excel/hs_expression_data.xlsx before writing the tables.
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'ncol': error in evaluating the argument 'x' in selecting a method for function 'assay': object 'hs_se' not found
tc_se <- create_se(new_meta[["new_meta"]], gene_info = tc_annot,
                   file_column = "hisat_count_table_tcruzi_all") %>%
  set_conditions(fact = "background") %>%
  set_batches(fact = "exp_number") %>%
  set_colors(color_choices[["tc"]])
## Reading the sample metadata.
## Checking the state of the condition column.
## Checking the state of the batch column.
## Checking the condition factor.
## The sample definitions comprises: 20 rows(samples) and 107 columns(metadata fields).
## Matched 23304 annotations and counts.
## Some annotations were lost in merging, setting them to 'undefined'.
## Saving the summarized experiment to 'se.rda'.
## The final summarized experiment has 25100 rows and 107 columns.
## The numbers of samples by condition are:
## 
##     AB10      cas  control      ko7 positive       wt 
##        3        1        3        6        1        6
## This function is intended to set the colors of a dataset.
## It was passed an object of type data.frame and does not know what to do.
## The number of samples by batch are:
## 
##    e1    e2    e3    e4 undef 
##     4     4     5     6     1
## Error in `names(old_colors) <- rownames(exp)`:
## ! 'names' attribute [20] must be the same length as the vector [0]
tc_written <- write_se(tc_se, excel = "excel/tc_expression_data.xlsx")
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'ncol': error in evaluating the argument 'x' in selecting a method for function 'assay': object 'tc_se' not found

One of my concerns surrounds the fate of the various trans-sialidase genes and the ability to discern the efficaciousness of adding stop codons to them. I therefore quantified the samples with salmon which I think is more sensitive to multi gene families.

salmon_annot <- tc_annot
rownames(salmon_annot) <- paste0(rownames(salmon_annot), ":mRNA")
tc_salmon <- create_se(new_meta[["new_meta"]], gene_info = salmon_annot,
                       file_column = "salmon_count_table_tcruzi_all") %>%
  set_conditions(fact = "background") %>%
  set_batches(fact = "exp_number") %>%
  set_colors(color_choices[["tc"]])
## Reading the sample metadata.
## Checking the state of the condition column.
## Checking the state of the batch column.
## Checking the condition factor.
## The sample definitions comprises: 20 rows(samples) and 107 columns(metadata fields).
## Warning in create_se(new_meta[["new_meta"]], gene_info = salmon_annot,
## file_column = "salmon_count_table_tcruzi_all"): Some samples were removed when
## cross referencing the samples against the count data.
## Matched 19476 annotations and counts.
## Some annotations were lost in merging, setting them to 'undefined'.
## Saving the summarized experiment to 'se.rda'.
## The final summarized experiment has 19533 rows and 107 columns.
## The numbers of samples by condition are:
## 
##     AB10      cas  control      ko7 positive       wt 
##        3        1        3        3        1        3
## This function is intended to set the colors of a dataset.
## It was passed an object of type data.frame and does not know what to do.
## The number of samples by batch are:
## 
##    e1    e2    e3 undef 
##     4     4     5     1
## Error in `names(old_colors) <- rownames(exp)`:
## ! 'names' attribute [14] must be the same length as the vector [0]

10 Check metadata vs mapping statistics

hs_mapped <- plot_metadata_factors(hs_se, column = "hisat_genome_percent_log_hg38_115")
## Error in `plot_metadata_factors()`:
## ! could not find function "plot_metadata_factors"
pp(file = "images/hs_hisat_mapping_percent.png", image = hs_mapped)
## Error:
## ! object 'hs_mapped' not found
hs_genes <- plot_metadata_factors(hs_se, column = "salmon_observed_genes_hg38_115")
## Error in `plot_metadata_factors()`:
## ! could not find function "plot_metadata_factors"
hs_genes
## Error:
## ! object 'hs_genes' not found
tc_mapped <- plot_metadata_factors(tc_se, column = "hisat_genome_percent_log_tcruzi_all")
## Error in `plot_metadata_factors()`:
## ! could not find function "plot_metadata_factors"
pp(file = "images/tc_hisat_mapping_percent.png", image = tc_mapped)
## Error:
## ! object 'tc_mapped' not found

11 A Few initial plots

I picked off another TODO in here, I changed plot_nonzero to more intelligently set the text annotation.

tc_nz <- plot_nonzero(tc_se)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_nonzero': object 'tc_se' not found
pp(file = "images/tc_nonzero.png", image = tc_nz)
## Error:
## ! object 'tc_nz' not found
tc_se <- subset_se(tc_se, nonzero = 5000)
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tc_se' not found
tc_filt_nz <- plot_nonzero(tc_se, y_intercept = 0.9)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_nonzero': object 'tc_se' not found
pp(file = "images/tc_nonzero_filtered.png", image = tc_filt_nz)
## Error:
## ! object 'tc_filt_nz' not found
hs_libsize <- plot_libsize(hs_se)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_quantreads': object 'hs_se' not found
pp(file = "images/hs_libsize.png", image = hs_libsize)
## Error:
## ! object 'hs_libsize' not found
hs_nz <- plot_nonzero(hs_se)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_nonzero': object 'hs_se' not found
pp(file = "images/hs_nz.png", image = hs_nz)
## Error:
## ! object 'hs_nz' not found
plot_boxplot(hs_se)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_boxplot': object 'hs_se' not found
tc_libsize <- plot_libsize(tc_se)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_quantreads': object 'tc_se' not found
pp(file = "images/tc_libsize.png", image = tc_libsize)
## Error:
## ! object 'tc_libsize' not found
hs_replicated <- subset_se(hs_se, min_replicates = 3, fact = "condition")
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'hs_se' not found
tc_replicated <- subset_se(tc_se, min_replicates = 3, fact = "condition") %>%
  subset_se(nonzero = 10000)
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tc_se' not found
tcsal_replicated <- subset_se(tc_salmon, min_replicates = 3, fact = "condition") %>%
  subset_se(nonzero = 10000)
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tc_salmon' not found

11.1 Poke at the variants briefly

tc_variants <- count_snps(tc_replicated, annot_column = "freebayes_table", snp_column = "PAIRED")
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tc_replicated' not found

Reminder to self: count_snps reads the freebayes table, pass that to get_snp_sets() to cross reference against the experimental design, then pass that to snps_intersections() and snps_vs_genes(). I should change that to be able to directly take the output from count_snps()

var_norm <- normalize(tc_variants, convert = "cpm", norm = "quant",
                      filter = TRUE, transform = "log2")
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'tc_variants' not found
tc_variant_pca <- plot_pca(var_norm)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_pca': object 'var_norm' not found
pp(file = "images/tc_variant_pca.png", image = tc_variant_pca[["plot"]])
## Error:
## ! object 'tc_variant_pca' not found
tc_sets <- get_snp_sets(tc_variants, factor = "condition", proportion = 0.75)
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tc_variants' not found
tc_sets
## Error:
## ! object 'tc_sets' not found
snp_intersections <- snps_intersections(tc_se, tc_sets, start_column = "start",
                                        end_column = "end", chr_column = "annot_sequence_id")
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'rowData': object 'tc_se' not found
snp_intersections
## Error:
## ! object 'snp_intersections' not found
snps_vs_genes <- snps_vs_genes(tc_se, tc_sets, start_column = "start",
                               end_column = "end", chr_column = "seqnames")
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'rowData': object 'tc_se' not found
snps_vs_genes
## function(exp, snp_result, start_column = "start", end_column = "end",
##                           snp_name_column = "seqnames", observed_in = NULL,
##                           more_than = 0, chr_column = "chromosome", ignore_strand = TRUE) {
##   seqnames <- .N <- NULL  ## .N is a read-only symbol in data.table
##   ## I am not sure if there is a way to programmatically use it without
##   ## triggering an alert from R CMD CHECK and/or flycheck.
##   ## https://www.rdocumentation.org/packages/data.table/versions/1.10.0/topics/special-symbols
## 
##   features <- rowData(exp)
##   if (is.null(features[[start_column]])) {
##     stop("Unable to find the ", start_column, " column in the annotation data.")
##   }
##   if (is.null(features[[end_column]])) {
##     stop("Unable to find the ", end_column, " column in the annotation data.")
##   }
##   features[[start_column]] <- sm(as.numeric(features[[start_column]]))
##   na_starts <- is.na(features[[start_column]])
##   features <- features[!na_starts, ]
##   features[[end_column]] <- as.numeric(features[[end_column]])
##   ## Keep in mind that when creating the snp_exp, I removed '_' from
##   ## the chromosome names and replaced them with '-'.
##   ## Therefore, in order to cross reference, I need to do the same here.
##   ## I don't quite want 5'/3' UTRs, I just want the coordinates starting with
##   ## (either 1 or) the end of the last gene and ending with the beginning of the
##   ## current gene with respect to the beginning of each chromosome.
##   ## That is a weirdly difficult problem for creatures with more than 1 chromosome.
##   ## inter_features <- features[, c("start", "end", "seqnames")]
##   ## inter_features[["chr_start"]] <- paste0(inter_features[["seqnames"]], "_",
##   ##                                         inter_features[["start"]])
##   ## inter_feature_order <- order(inter_features[["chr_start"]])
##   ## inter_features <- inter_features[inter_feature_order, ]
## 
##   ## In this invocation, I need the seqnames to be the chromosome of each gene.
##   exp_granges <- GenomicRanges::makeGRangesFromDataFrame(
##     features, seqnames.field = chr_column,
##     start.field = start_column, end.field = end_column,
##     ignore.strand = ignore_strand)
##   ## keep.extra.columns = FALSE
##   ## ignore.strand = FALSE
##   ## seqinfo = NULL
##   ## seqnames.field = c("seqnames","chromosome", "chr", "seqid")
##   ## start.field = "start"
##   ## end.field = "end"
##   ## strand.field = "strand"
## 
##   snp_positions <- snp_result[["observations"]]
##   observations <- data.frame()
##   if (!is.null(observed_in)) {
##     observed_idx <- snp_positions[[observed_in]] > 0
##     message("variants were observed at ", sum(observed_idx),
##             " positions in group ", observed_in, ".")
##     observations <- data.frame(row.names = rownames(snp_positions))
##     observations[[observed_in]] <- 0
##     observations[observed_idx, observed_in] <- 1
##   }
##   snp_positions[[snp_name_column]] <- gsub(
##     pattern = "^chr_(.+)_pos_.+_ref.+_alt.+$",
##     replacement = "\\1", x = rownames(snp_positions))
##   snp_positions[[start_column]] <- as.numeric(
##     gsub(pattern = "^chr_.+_pos_(.+)_ref.+_alt.+$",
##          replacement = "\\1", x = rownames(snp_positions)))
##   snp_positions[[end_column]] <- snp_positions[[start_column]]
##   snp_positions[["strand"]] <- "+"
##   snp_positions <- snp_positions[, c(snp_name_column, start_column, end_column, "strand")]
##   ## Keep in mind that when creating the snp_exp, I removed '_' from
##   ## the chromosome names and replaced them with '-'.
##   snp_positions[[snp_name_column]] <- gsub(pattern = "-", replacement = "_",
##                                            x = snp_positions[[snp_name_column]])
##   snp_granges <- GenomicRanges::makeGRangesFromDataFrame(
##     snp_positions, seqnames.field = snp_name_column,
##     start.field = start_column, end.field = end_column)
## 
##   ## Faking out r cmd check with a couple empty variables which will be used by data.table
##   ## This is how one sets the metadata for a GRanges thing.
##   ## When doing mergeByOverlaps, countOverlaps, etc, this is useful.
##   ## mcols(object)$column_name <- some data column
##   mcols(exp_granges)[, "gene_name"] <- names(exp_granges)
## 
##   ## Lets add metadata columns for each column for the medians table
##   ## This will let us find the positions unique to a condition.
##   mcols(snp_granges)[, "snp_name"] <- names(snp_granges)
##   snp_columns <- colnames(snp_result[["observations"]])
##   for (count in seq_along(snp_columns)) {
##     colname <- snp_columns[count]
##     mcols(snp_granges)[, colname] <- snp_result[["observations"]][[colname]]
##   }
##   message("The snp grange data has ", length(snp_granges), " elements.")
##   if (!is.null(observed_in)) {
##     observed_snp_idx <- mcols(snp_granges)[[observed_in]] > 0
##     message("The set observed in ", observed_in, " comprises ",
##             sum(observed_snp_idx), " elements.")
##     snp_granges <- snp_granges[observed_snp_idx, ]
##   }
##   ## This is a place of confusion, some gene annotation databases (TriTrypDB)
##   ## have multiple chromosome columns with different ways of writing the chromosomes.
##   first_snp_chr <- as.character(head(levels(GenomeInfoDb::seqnames(snp_granges))))
##   first_exp_chr <- as.character(head(levels(GenomeInfoDb::seqnames(exp_granges))))
##   message("The first few snp chromosomes are: ", toString(first_snp_chr))
##   message("The first few exp chromosomes are: ", toString(first_exp_chr))
##   snps_by_chr <- suppressWarnings(
##     IRanges::subsetByOverlaps(snp_granges, exp_granges,
##                               type = "within", ignore.strand = ignore_strand))
##   message("There are ", length(snps_by_chr), " overlapping variants and genes.")
## 
##   summarized_by_chr <- data.table::as.data.table(snps_by_chr)
##   summarized_by_chr[, count := .N, by = list(seqnames)]
## 
##   ## I think I can replace this data table invocation with countOverlaps...
##   ## Ahh no, the following invocation merely counts which snps are found in name,
##   ## which is sort of the opposite of what I want.
##   ## test <- IRanges::countOverlaps(query = snp_granges, subject = exp_granges,
##   ##                               type = "within", ignore.strand = TRUE)
##   summarized_by_chr <- unique(summarized_by_chr[, c("seqnames", "count"), with = FALSE])
##   ## The ignore.strand is super important for this task.
##   merged_grange <- suppressWarnings(
##     IRanges::mergeByOverlaps(query = snp_granges, subject = exp_granges,
##                              ignore.strand = ignore_strand))
## 
##   count_by_gene_irange <- suppressWarnings(
##     IRanges::countOverlaps(query = exp_granges, subject = snp_granges,
##                            type = "any", ignore.strand = ignore_strand))
## 
##   ## I am getting odd results using countOverlaps,
##   ## lets get a second opinion using dplyr and tally()
##   second_opinion <- data.frame("gene" = merged_grange[["gene_name"]],
##                                "snp" = merged_grange[["snp_name"]])
##   count_by_gene_dplyr <- second_opinion %>%
##     group_by(.data[["gene"]]) %>%
##     dplyr::tally()
##   count_by_gene_dplyr_names <- count_by_gene_dplyr[["gene"]]
##   count_by_gene_dplyr <- count_by_gene_dplyr[["n"]]
##   names(count_by_gene_dplyr) <- count_by_gene_dplyr_names
##   summarized_idx <- order(count_by_gene_irange, decreasing = TRUE)
##   count_by_gene_irange <- count_by_gene_irange[summarized_idx]
##   summarized_idx <- order(count_by_gene_dplyr, decreasing = TRUE)
##   count_by_gene_dplyr <- count_by_gene_dplyr[summarized_idx]
##   retlist <- list(
##     "exp_granges" = exp_granges,
##     "snp_granges" = snp_granges,
##     "snps_by_chr" = snps_by_chr,
##     "merged_by_gene" = merged_grange,
##     "count_by_gene" = count_by_gene_irange,
##     "count_by_gene_dplyr" = count_by_gene_dplyr,
##     "summary" = summarized_by_chr)
##   class(retlist) <- c("hpgltools::snps_vs_genes", "list")
##   return(retlist)
## }
## <environment: namespace:hpgltools>

12 Variance Partition

Here are a couple of variance partition invocations. Once we have other metadata, this will be more useful. Note, this will only work once the non-replicated conditions are removed (control and cas).

hs_varpart <- simple_varpart(hs_replicated)
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'hs_replicated' not found
pp(file = "images/hs_varpart_violin.png", image = hs_varpart[["partition_plot"]])
## Error:
## ! object 'hs_varpart' not found
pp(file = "images/hs_varpart_percent.png", image = hs_varpart[["percent_plot"]])
## Error:
## ! object 'hs_varpart' not found
tc_varpart <- simple_varpart(tc_replicated)
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tc_replicated' not found
pp(file = "images/tc_varpart_violin.png", image = tc_varpart[["partition_plot"]])
## Error:
## ! object 'tc_varpart' not found
pp(file = "images/tc_varpart_percent.png", image = tc_varpart[["percent_plot"]])
## Error:
## ! object 'tc_varpart' not found

I think we probably should not be surprised at the amount of variance attributed to the batch due to the very large difference in coverage between experiment #3 and 1/2.

13 Sample clustering

13.1 Human

Perform our default PCA plot along with a combat version.

hs_norm <- normalize(hs_replicated, transform = "log2", convert = "cpm",
                     norm = "quant", filter = TRUE)
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'hs_replicated' not found
hs_disheat <- plot_disheat(hs_norm)
## Error in `h()`:
## ! error in evaluating the argument 'input_data' in selecting a method for function 'plot_heatmap': object 'hs_norm' not found
pp(file = "images/hs_distance_heatmap.png", image = hs_disheat2)
## Error:
## ! object 'hs_disheat2' not found
hs_corheat <- plot_corheat(hs_norm)
## Error in `h()`:
## ! error in evaluating the argument 'input_data' in selecting a method for function 'plot_heatmap': object 'hs_norm' not found
pp(file = "images/hs_correlation_heatmap.png", image = hs_corheat[["plot"]])
## Error:
## ! object 'hs_corheat' not found
hs_norm_pca <- plot_pca(hs_norm, plot_labels = TRUE)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_pca': object 'hs_norm' not found
pp(file = "images/hs_norm_pca.png", image = hs_norm_pca[["plot"]])
## Error:
## ! object 'hs_norm_pca' not found
hs_nb <- normalize(hs_replicated, transform = "log2", convert = "cpm",
                   filter = TRUE, batch = "svaseq")
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'hs_replicated' not found
hs_nb_pca <- plot_pca(hs_nb)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_pca': object 'hs_nb' not found
pp(file = "images/hs_norm_sva_pca.png", image = hs_nb_pca[["plot"]])
## Error:
## ! object 'hs_nb_pca' not found
hs_cb <- normalize(hs_replicated, transform = "log2", convert = "cpm",
                   filter = TRUE, batch = "combat")
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'hs_replicated' not found
hs_combat_pca <- plot_pca(hs_cb)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_pca': object 'hs_cb' not found
pp(file = "images/hs_norm_combat_pca.png", image = hs_combat_pca[["plot"]])
## Error:
## ! object 'hs_combat_pca' not found

13.2 Parasite

tc_norm <- normalize(tc_se, transform = "log2", convert = "cpm",
                     norm = "quant", filter = TRUE)
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'tc_se' not found
tc_disheat <- plot_disheat(tc_norm)
## Error in `h()`:
## ! error in evaluating the argument 'input_data' in selecting a method for function 'plot_heatmap': object 'tc_norm' not found
pp(file = "images/tc_distance_heatmap.png", image = tc_disheat)
## Error:
## ! object 'tc_disheat' not found
tc_corheat <- plot_corheat(tc_norm)
## Error in `h()`:
## ! error in evaluating the argument 'input_data' in selecting a method for function 'plot_heatmap': object 'tc_norm' not found
pp(file = "images/tc_correlation_heatmap.png", image = tc_corheat)
## Error:
## ! object 'tc_corheat' not found

A little bit of fun, extract the genes which are high-outliers in each sample and print what they are.

norm_boxplot <- plot_boxplot(tc_norm)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_boxplot': object 'tc_norm' not found
norm_boxplot[["plot"]]
## Error:
## ! object 'norm_boxplot' not found
high_genes <- unique(as.character(unlist(norm_boxplot[["high_outlier_genes"]])))
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'unique': object 'norm_boxplot' not found
unique(rowData(tc_se)[high_genes, ][["annot_transcript_product"]])
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'unique': error in evaluating the argument 'x' in selecting a method for function 'rowData': object 'tc_se' not found
tc_norm_pca <- plot_pca(tc_norm, plot_labels = TRUE)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_pca': object 'tc_norm' not found
pp(file = "images/tc_norm_pca.png", image = tc_norm_pca)
## Error:
## ! object 'tc_norm_pca' not found
tc_rnorm <- normalize(tc_replicated, transform = "log2", convert = "cpm",
                     norm = "quant", filter = TRUE)
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'tc_replicated' not found
tc_rnorm_disheat <- plot_disheat(tc_rnorm)
## Error in `h()`:
## ! error in evaluating the argument 'input_data' in selecting a method for function 'plot_heatmap': object 'tc_rnorm' not found
pp(file = "images/tc_rnorm_disheat.png", image = tc_rnorm_disheat)
## Error:
## ! object 'tc_rnorm_disheat' not found
tc_rnorm_pca <- plot_pca(tc_rnorm)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_pca': object 'tc_rnorm' not found
pp(file = "images/tc_rnorm_pca.png", image = tc_rnorm_pca)
## Error:
## ! object 'tc_rnorm_pca' not found
tc_rbnorm <- normalize(tc_replicated, transform = "log2", convert = "cpm",
                       filter = TRUE, batch = "svaseq")
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'tc_replicated' not found
tc_sva_pca <- plot_pca(tc_rbnorm)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_pca': object 'tc_rbnorm' not found
pp(file = "images/tc_sva_pca.png", image = tc_sva_pca)
## Error:
## ! object 'tc_sva_pca' not found
tc_cbnorm <- normalize(tc_replicated, transform = "log2", convert = "cpm",
                       filter = TRUE, batch = "combat")
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'tc_replicated' not found
tc_combat_pca <- plot_pca(tc_cbnorm)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_pca': object 'tc_cbnorm' not found
pp(file = "images/tc_combat_pca.png", image = tc_combat_pca)
## Error:
## ! object 'tc_combat_pca' not found

14 Differential Expression

I am not thinking we will see many genes of interest.

hs_keepers <- list(
  "ab_vs_control" = c("AB10", "control"),
  "ko_vs_control" = c("ko7", "control"),
  "ko_vs_wt" = c("ko7", "wt"),
  "ab_vs_wt" = c("AB10", "wt"),
  "ab_vs_ko" = c("AB10", "ko7"))
hs_de <- all_pairwise(hs_replicated, filter = TRUE, model_fstring = "~ 0 + condition",
                      model_svs = "svaseq")
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'hs_replicated' not found
hs_de
## Error:
## ! object 'hs_de' not found
hs_tables <- combine_de_tables(hs_de, keepers = hs_keepers, excel = "excel/hs_tables.xlsx")
## Deleting the file excel/hs_tables.xlsx before writing the tables.
## Error:
## ! object 'hs_de' not found
hs_tables
## Error:
## ! object 'hs_tables' not found
hs_sig <- extract_significant_genes(hs_tables, excel = "excel/hs_sig.xlsx")
## Deleting the file excel/hs_sig.xlsx before writing the tables.
## Error:
## ! object 'hs_tables' not found
hs_sig
## Error:
## ! object 'hs_sig' not found

While it is true there are not a tremendous number of genes, at least some of the groups are interesting.

hs_gp <- all_gprofiler(hs_sig)
## Error:
## ! object 'hs_sig' not found
hs_gp
## Error:
## ! object 'hs_gp' not found
conditions(tc_replicated)
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'conditions': object 'tc_replicated' not found
tc_keepers <- list(
  "ab_vs_wt" = c("AB10", "wt"),
  "ko_vs_wt" = c("ko7", "wt"),
  "ab_vs_ko" = c("AB10", "ko7"))
tc_de <- all_pairwise(tc_replicated, filter = TRUE, model_fstring = "~ 0 + condition",
                      model_svs = "svaseq")
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tc_replicated' not found
tc_de
## Error:
## ! object 'tc_de' not found
tc_tables <- combine_de_tables(tc_de, keepers = tc_keepers, excel = "excel/tc_tables.xlsx")
## Deleting the file excel/tc_tables.xlsx before writing the tables.
## Error:
## ! object 'tc_de' not found
tc_tables
## Error:
## ! object 'tc_tables' not found
tc_sig <- extract_significant_genes(tc_tables, excel = "excel/tc_sig.xlsx")
## Deleting the file excel/tc_sig.xlsx before writing the tables.
## Error:
## ! object 'tc_tables' not found
tc_sig
## Error:
## ! object 'tc_sig' not found

14.1 Drop the labels by cheating

remove_geom <- function(ggplot2_object, geom_type) {
  # Delete layers that match the requested type.
  layers <- lapply(ggplot2_object$layers, function(x) {
    if (class(x$geom)[1] == geom_type) {
      NULL
    } else {
      x
    }
  })
  # Delete the unwanted layers.
  layers <- layers[!sapply(layers, is.null)]
  ggplot2_object$layers <- layers
  ggplot2_object
}

starter <- tc_tables$plots[[2]]$deseq_vol_plots
## Error:
## ! object 'tc_tables' not found
after <- remove_geom(starter, "GeomTextRepel")
## Error in `h()`:
## ! error in evaluating the argument 'X' in selecting a method for function 'lapply': object 'starter' not found
after
## Error:
## ! object 'after' not found

14.2 Extract trans-sialidase and look

I ought to be able to use my semantic filter to extract anything with sialidase and/or trans-sialidase group I and look directly at the expression of these genes. My hypothesis is that if the CRISPR experiment worked as intended, these genes should all have decreased expression.

all_ts <- semantic_filter(tc_replicated, invert = TRUE, semantic = c("trans-sialidase"),
                          semantic_column = "annot_transcript_product")
## Error in `h()`:
## ! error in evaluating the argument 'input' in selecting a method for function 'semantic_filter': object 'tc_replicated' not found
all_ts_norm <- normalize(all_ts, transform = "log2", convert = "cpm")
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'all_ts' not found
all_ts_norm_heat <- plot_sample_heatmap(all_ts_norm)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_sample_heatmap': object 'all_ts_norm' not found
pp(file = "images/all_ts_norm_hisat_heatmap.png")
all_ts_norm_heat
## Error:
## ! object 'all_ts_norm_heat' not found
dev.off()
## png 
##   2
all_ts_norm_heat
## Error:
## ! object 'all_ts_norm_heat' not found
all_ts_sal <- semantic_filter(tcsal_replicated, invert = TRUE, semantic = c("trans-sialidase"),
                          semantic_column = "annot_transcript_product")
## Error in `h()`:
## ! error in evaluating the argument 'input' in selecting a method for function 'semantic_filter': object 'tcsal_replicated' not found
all_ts_sal_norm <- normalize(all_ts_sal, transform = "log2", convert = "cpm")
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'all_ts_sal' not found
all_ts_sal_norm_heat <- plot_sample_heatmap(all_ts_sal_norm)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_sample_heatmap': object 'all_ts_sal_norm' not found
pp(file = "images/all_ts_norm_salmon_heatmap.png")
all_ts_sal_norm_heat
## Error:
## ! object 'all_ts_sal_norm_heat' not found
dev.off()
## png 
##   2
all_ts_sal_norm_heat
## Error:
## ! object 'all_ts_sal_norm_heat' not found

The group-I TS genes are not obvious in this group, let us yank them out explicitly and see.

Note, the following is a little bit wrong in thinking because searching for ‘Group I’ will pick up all genes from Group I, II, III, and IV. The next stanza will extract just the IDs of interest.

g1_ts <- semantic_filter(all_ts, invert = TRUE, semantic = c("Group I"),
                         semantic_column = "annot_transcript_product")
## Error in `h()`:
## ! error in evaluating the argument 'input' in selecting a method for function 'semantic_filter': object 'all_ts' not found
g1_ts_sal <- semantic_filter(all_ts_sal, invert = TRUE, semantic = c("Group I"),
                             semantic_column = "annot_transcript_product")
## Error in `h()`:
## ! error in evaluating the argument 'input' in selecting a method for function 'semantic_filter': object 'all_ts_sal' not found

There is a pretty significant increase in a few AB samples, perhaps those are in the list of 19 specific genes? Let us find out.

expected_ts <- subset_genes(g1_ts, ids = expected_lower, method = "keep")
## Error in `h()`:
## ! error in evaluating the argument 'input' in selecting a method for function 'subset_genes': object 'g1_ts' not found
expected_norm <- normalize(expected_ts, transform = "log2", convert = "cpm")
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'expected_ts' not found
g1_ts_hisat_norm_heat <- plot_sample_heatmap(expected_norm)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_sample_heatmap': object 'expected_norm' not found
pp(file = "images/g1_ts_hisat_norm_heat.png")
g1_ts_hisat_norm_heat
## Error:
## ! object 'g1_ts_hisat_norm_heat' not found
dev.off()
## png 
##   2
g1_ts_hisat_norm_heat
## Error:
## ! object 'g1_ts_hisat_norm_heat' not found
sal_expected <- paste0(expected_lower, ":mRNA")
expected_ts_sal <- subset_genes(g1_ts_sal, ids = sal_expected, method = "keep")
## Error in `h()`:
## ! error in evaluating the argument 'input' in selecting a method for function 'subset_genes': object 'g1_ts_sal' not found
expected_sal_norm <- normalize(expected_ts_sal, transform = "log2", convert = "cpm")
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'expected_ts_sal' not found
g1_ts_salmon_norm_heat <- plot_sample_heatmap(expected_sal_norm)
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_sample_heatmap': object 'expected_sal_norm' not found
pp(file = "images/g1_ts_salmon_norm_heat.png")
g1_ts_salmon_norm_heat
## Error:
## ! object 'g1_ts_salmon_norm_heat' not found
dev.off()
## png 
##   2
g1_ts_salmon_norm_heat
## Error:
## ! object 'g1_ts_salmon_norm_heat' not found

15 Try some ontology searching via clusterProfiler

We cannot use gProfiler2 with the parasite because it is not a reference species; but other ontology methods are not constrained thus. In the case of clusterProfiler, there is another constraint, I do not have a single orgDB object which comprises Esmer/NonEsmer/Unassigned; as a result I must attempt the ontology search on the haplotypes separately.

ko_wt_up <- tc_sig[["deseq"]][["ups"]][["ko_vs_wt"]]
## Error:
## ! object 'tc_sig' not found
ko_wt_down <- tc_sig[["deseq"]][["downs"]][["ko_vs_wt"]]
## Error:
## ! object 'tc_sig' not found
ko_wt_all <- tc_tables[["data"]][["ko_vs_wt"]]
## Error:
## ! object 'tc_tables' not found
ab_ko_up <- tc_sig[["deseq"]][["ups"]][["ab_vs_ko"]]
## Error:
## ! object 'tc_sig' not found
ab_ko_down <- tc_sig[["deseq"]][["downs"]][["ab_vs_ko"]]
## Error:
## ! object 'tc_sig' not found
ab_ko_all <- tc_tables[["data"]][["ab_vs_ko"]]
## Error:
## ! object 'tc_tables' not found
tc_esmer_up_cp <- simple_clusterprofiler(
  ko_wt_up, de_table = ko_wt_all, orgdb = esmer_db, orgdb_to = "GID",
  organism = "tcruzi", excel = "excel/ko_wt_up_cp_esmer.xlsx")
## Error:
## ! object 'ko_wt_up' not found
tc_esmer_up_cp
## Error:
## ! object 'tc_esmer_up_cp' not found
pp(file = "images/tc_esmer_up_cp_mf_dotplot.png",
   image = enrichplot::dotplot(tc_esmer_up_cp$go_data$MF_enrich))
## Error in `h()`:
## ! error in evaluating the argument 'object' in selecting a method for function 'dotplot': object 'tc_esmer_up_cp' not found
tc_nonesmer_up_cp <- simple_clusterprofiler(
  ko_wt_up, de_table = ko_wt_all, orgdb = nonesmer_db, orgdb_to = "GID",
  organism = "tcruzi", excel = "excel/ko_wt_up_cp_nonesmer.xlsx")
## Error:
## ! object 'ko_wt_up' not found
tc_unas_up_cp <- simple_clusterprofiler(
  ko_wt_up, de_table = ko_wt_all, orgdb = unas_db, orgdb_to = "GID",
  organism = "tcruzi")
## Error:
## ! object 'ko_wt_up' not found
tc_esmer_up_cp
## Error:
## ! object 'tc_esmer_up_cp' not found
tc_esmer_down_cp <- simple_clusterprofiler(
  ko_wt_down, de_table = ko_wt_all, orgdb = esmer_db, orgdb_to = "GID",
  organism = "tcruzi", excel = "excel/ko_wt_down_cp_esmer.xlsx")
## Error:
## ! object 'ko_wt_down' not found
tc_unas_down_cp <- simple_clusterprofiler(
  ko_wt_down, de_table = ko_wt_all, orgdb = unas_db, orgdb_to = "GID",
  organism = "tcruzi")
## Error:
## ! object 'ko_wt_down' not found
tc_esmer_down_cp
## Error:
## ! object 'tc_esmer_down_cp' not found
length_db <- as.data.frame(rowData(tc_se))
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'as.data.frame': error in evaluating the argument 'x' in selecting a method for function 'rowData': object 'tc_se' not found
length_db[["gid"]] <- rownames(length_db)
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'rownames': object 'length_db' not found
length_db <- length_db[, c("gid", "width")]
## Error:
## ! object 'length_db' not found
tc_up_gs <- simple_goseq(ko_wt_up, go_db = tc_go, length_db = length_db, min_xref = 10)
## Error:
## ! object 'ko_wt_up' not found
mf_enr <- tc_up_gs[["mf_enrich"]]
## Error:
## ! object 'tc_up_gs' not found
mf_plots <- plot_enrichresult(mf_enr)
## Error:
## ! object 'mf_enr' not found
mf_plots[["tree"]]
## Error:
## ! object 'mf_plots' not found
pp(file = "images/higher_ko_goseq_mf.png", image = mf_plots[["tree"]], height = 9, width = 18)
## Error:
## ! object 'mf_plots' not found
pp(file = "images/higher_ko_goseq_mf_dot.png", image = mf_plots[["dot"]])
## Error:
## ! object 'mf_plots' not found
bp_enr <- tc_up_gs[["bp_enrich"]]
## Error:
## ! object 'tc_up_gs' not found
bp_plots <- plot_enrichresult(bp_enr)
## Error:
## ! object 'bp_enr' not found
bp_plots[["dot"]]
## Error:
## ! object 'bp_plots' not found

Now check the position of the expected lower expression genes in the context of all genes compared to wt.

message("Pull the ko_wt_all table and see where expected_lower compares.")
## Pull the ko_wt_all table and see where expected_lower compares.

16 Try without round 3

hs_duplicate <- subset_se(hs_replicated, subset = "round!='r3'")
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'hs_replicated' not found
tc_duplicate <- subset_se(tc_replicated, subset = "round!='r3'")
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tc_replicated' not found
hs_dup_de <- all_pairwise(hs_duplicate, filter = TRUE,
                          model_fstring = "~ 0 + condition + batch", model_svs = FALSE)
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'hs_duplicate' not found
hs_dup_de
## Error:
## ! object 'hs_dup_de' not found
hs_dup_table <- combine_de_tables(hs_dup_de, excel = glue("excel/hs_dup_de_table-v{ver}.xlsx"))
## Deleting the file excel/hs_dup_de_table-v202604.xlsx before writing the tables.
## Error:
## ! object 'hs_dup_de' not found
hs_dup_sig <- extract_significant_genes(hs_dup_table, excel = glue("excel/hs_dup_de_sig-v{ver}.xlsx"))
## Deleting the file excel/hs_dup_de_sig-v202604.xlsx before writing the tables.
## Error:
## ! object 'hs_dup_table' not found
hs_dup_sig
## Error:
## ! object 'hs_dup_sig' not found
tc_dup_de <- all_pairwise(tc_duplicate, filter = TRUE,
                          model_fstring = "~ 0 + condition", model_svs = "svaseq")
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tc_duplicate' not found
tc_dup_de
## Error:
## ! object 'tc_dup_de' not found
tc_dup_table <- combine_de_tables(tc_dup_de, excel = glue("excel/tc_dup_de_table-v{ver}.xlsx"))
## Deleting the file excel/tc_dup_de_table-v202604.xlsx before writing the tables.
## Error:
## ! object 'tc_dup_de' not found
tc_dup_table
## Error:
## ! object 'tc_dup_table' not found
tc_dup_sig <- extract_significant_genes(tc_dup_table, excel = glue("excel/tc_dup_de_sig-v{ver}.xlsx"))
## Deleting the file excel/tc_dup_de_sig-v202604.xlsx before writing the tables.
## Error:
## ! object 'tc_dup_table' not found
tc_dup_sig
## Error:
## ! object 'tc_dup_sig' not found

Invoke goseq/clusterprofiler on these genes.

tc_goseq <- all_goseq(tc_dup_sig, go_db = tc_go, length_db = tc_length)
## Error:
## ! object 'tc_dup_sig' not found
hs_gp <- all_gprofiler(tc_dup_sig)
## Error:
## ! object 'tc_dup_sig' not found

Check expression of genes expected to be lower

expected_se <- subset_se(tc_se, ids = expected_lower)
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tc_se' not found

17 M13 was used to mark the CRISPR PTCs

A nice detail came out today, the PTCs introduced by CRISPR included M13; I unfortunately did not think to ask which primer, but I should be able to figure that out trivially:

  • M13 forward -20: GTAAAACGACGGCCAGTG
  • M13 forward -41: GGTTTTCCCAGTCACGAC
  • M13 reverse -27: GGAAACAGCTATGACCATG
  • M13 reverse -48: AGCGGATAACAATTTCACAC

Start by checking an arbitrary ko sample, I should see a bunch of reads with at least one of the above.

cd preprocessing/06_HeLa_KO7_60hpi
xzgrep GTAAAACGACGGCCAGTG outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R1_001-trimmed.fastq.xz | wc
## M13 forward -20 vs. R1: 0 hits
xzgrep CACTGGCCGTCGTTTTAC outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R1_001-trimmed.fastq.xz | wc
## M13 forward -20 RC vs. R1: 20 hits

xzgrep GTAAAACGACGGCCAGTG outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R2_001-trimmed.fastq.xz | wc
## M13 forward -20 vs R2: 75 hits
xzgrep CACTGGCCGTCGTTTTAC outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R2_001-trimmed.fastq.xz | wc
## M13 forward -20 RC vs R2: 0 hits



xzgrep GGTTTTCCCAGTCACGAC outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R1_001-trimmed.fastq.xz | wc
## M13 forward -41 vs R1: 11 hits
xzgrep GTCGTGACTGGGAAAACC outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R1_001-trimmed.fastq.xz | wc
## M13 forward RC -41 vs R1:

xzgrep GGTTTTCCCAGTCACGAC outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R2_001-trimmed.fastq.xz | wc
## M13 forward -41 vs R2: 12
xzgrep GTCGTGACTGGGAAAACC outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R2_001-trimmed.fastq.xz | wc
## M13 forward -41 RC vs R2: 8



xzgrep GGAAACAGCTATGACCATG outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R1_001-trimmed.fastq.xz | wc
##  M13 reverse -27 vs R1: 54
xzgrep CATGGTCATAGCTGTTTCC outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R1_001-trimmed.fastq.xz | wc
## M13 reverse -27 RC vs R1: 0

xzgrep GGAAACAGCTATGACCATG outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R2_001-trimmed.fastq.xz | wc
##  M13 reverse -27 vs R1: 0
xzgrep CATGGTCATAGCTGTTTCC outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R2_001-trimmed.fastq.xz | wc
## M13 reverse -27 RC vs R1: 104



xzgrep AGCGGATAACAATTTCACAC  outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R1_001-trimmed.fastq.xz | wc
## M13 reverse -48 vs R1: 286
xzgrep GTGTGAAATTGTTATCCGCT  outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R1_001-trimmed.fastq.xz | wc
## M13 reverse -48 RC vs R1: 0

xzgrep AGCGGATAACAATTTCACAC  outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R2_001-trimmed.fastq.xz | wc
## M13 reverse -48 vs R2: 0
xzgrep GTGTGAAATTGTTATCCGCT  outputs/20251031trimomatic/06_HeLa_KO7_60hpi_2_S3_R2_001-trimmed.fastq.xz | wc
## M13 reverse -48 RC vs R2: 90 hits

Codify the above: I wrote a quick target in cyoa to seek out these sequences and extract the other read, e.g. if R1 has one of these sequences, it will pull out R2 and write it to a separate fastq file.

sequences="GTAAAACGACGGCCAGTG:GGTTTTCCCAGTCACGAC:GGAAACAGCTATGACCATG:AGCGGATAACAATTTCACAC"
samples=$(/bin/ls -d [0-9]*)
for s in ${samples}; do
    pushd $s
    input=$(/bin/ls outputs/*trimomatic/*_R1*-trimmed.fastq.xz)
    library=$(/bin/ls outputs/*trimomatic/*_R2*-trimmed.fastq.xz)
    cyoa --method getother --input $input --library $library --query $sequences
    popd
done

I ran the above and was pleased to see that only the KO and AB samples contain any M13 sequence. I then did a little arbitrary BLASTing of the other reads. Weirdly, most of the hits were to GAPDH, but the second read I pulled aligned to Tc00.1047053509065.50, which is a synonym for TcCLB.509065.50 (~ 800,000 on TcChr32-P)

I then started searching through the set of reads extracted to see if I can find where the M13 sequences live. I have a screenshot from IGV suggesting that many/most/all of them are adjacent to GAPDH on chromosome 32P.

18 Multi gene families

I decided to check and see the degree to which these genes should(not) be expected to map cleanly due to being members of a sprawling multi-gene family. I therefore extracted all genes annotated with ‘sialidase’ and from them extracted the group I members. In images/groupI_sialidase_phyML_tree.svg resides the resulting tree. They are not so similar as I feared.

Let us take a moment and look at a kmer tree of the 1524 groupx trans-sialidase genes.

ts_kmers <- CDS_kmer_dist(directory = "kmer")
## Reading kmer/sialidase.fasta

19 Only Tissue Culture Trypomastigotes

Let us also do a quick comparison of the two genotypes among the tissue culture trypomastigote samples.

tct_se <- subset_se(tc_replicated, subset = "celltype=='Parasite'")
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tc_replicated' not found
colData(tct_se)[["sample_replicate"]] <- paste0("sr",
                                                gsub(x = colData(tct_se)[["sampleid_backup"]],
                                                     pattern = "^.*_(\\d{1})$", replacement = "\\1"))
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'gsub': error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tct_se' not found
tct_se <- set_batches(tct_se, fact = "sample_replicate")
## Error in `h()`:
## ! error in evaluating the argument 'exp' in selecting a method for function 'set_batches': object 'tct_se' not found
plot_pca(normalize(tct_se, filter = TRUE, transform = "log2", convert = "cpm", norm = "tmm"))
## Error in `h()`:
## ! error in evaluating the argument 'data' in selecting a method for function 'plot_pca': error in evaluating the argument 'object' in selecting a method for function 'normalize': object 'tct_se' not found
tct_de <- all_pairwise(tct_se, filter = TRUE, model_fstring = "~ 0 + condition + batch")
## Error in `h()`:
## ! error in evaluating the argument 'x' in selecting a method for function 'colData': object 'tct_se' not found
tct_table <- combine_de_tables(tct_de, excel = "excel/tct_wt_vs_deletion-table.xlsx")
## Deleting the file excel/tct_wt_vs_deletion-table.xlsx before writing the tables.
## Error:
## ! object 'tct_de' not found
tct_sig <- extract_significant_genes(tct_table, excel = "excel/tct_wt_vs_deletion-sig.xlsx")
## Deleting the file excel/tct_wt_vs_deletion-sig.xlsx before writing the tables.
## Error:
## ! object 'tct_table' not found
pander::pander(sessionInfo())
message(paste0("This is hpgltools commit: ", get_git_commit()))
message(paste0("Saving to ", savefile))
tmp <- sm(saveme(filename = savefile))
tmp <- loadme(filename = savefile)
LS0tCnRpdGxlOiAiRXhhbWluaW5nIHNvbWUgY3J1emkgaW5mZWN0ZWQgSGVMYSBjZWxscy4iCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgojIyBiaWJsaW9ncmFwaHk6IC9ob21lL3RyZXkvRG9jdW1lbnRzL2JpYnRleC9hdGIuYmliCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogemVuYnVybgogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgIHRoZW1lOiByZWFkYWJsZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKLS0tCgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlID0gRkFMU0V9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZm9yY2F0cykKbGlicmFyeShnbHVlKQpsaWJyYXJ5KGhwZ2x0b29scykKbGlicmFyeSh0aWR5cikKCmRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKQprbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFLCB3aWR0aCA9IDkwLCBlY2hvID0gVFJVRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVycm9yID0gVFJVRSwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDgsIGZpZy5yZXRpbmEgPSAyLAogIG91dC53aWR0aCA9ICIxMDAlIiwgZGV2ID0gInBuZyIsCiAgZGV2LmFyZ3MgPSBsaXN0KHBuZyA9IGxpc3QodHlwZSA9ICJjYWlyby1wbmciKSkpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzID0gNCwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLCBrbml0ci5kdXBsaWNhdGUubGFiZWwgPSAiYWxsb3ciKQpnZ3Bsb3QyOjp0aGVtZV9zZXQoZ2dwbG90Mjo6dGhlbWVfYncoYmFzZV9zaXplID0gMTIpKQogdmVyIDwtIFN5cy5nZXRlbnYoIlZFUlNJT04iKQpydW5kYXRlIDwtIGZvcm1hdChTeXMuRGF0ZSgpLCBmb3JtYXQgPSAiJVklbSVkIikKCnJtZF9maWxlIDwtICJpbmRleC5SbWQiCnNhdmVmaWxlIDwtIGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLCByZXBsYWNlID0gIlxcLnJkYVxcLnh6IiwgeCA9IHJtZF9maWxlKQpgYGAKCiMgVE9ETwoKIyMgMjAyNjAzCgoxLiAgUmVtb3ZlIHRoZSBwcm9ibGVtYXRpYyByZXBsaWNhdGUgYW5kIGNvbXBhcmUga28vd3Q6IHdlIGNhbiBsaWtlbHkgaWdub3JlIEFCCjIuICBDaGVjayBmb3IgcGxhc21pZCByZWFkcyAoc2VxdWVuY2UgaW5jb21pbmcpLCBwZXJoYXBzIG1vZGlmeSBnZW5vbWUKICAgIHRvIHB1dCBDQVM5IGluIGl0cyBhcHByb3ByaWF0ZSBsb2NhdGlvbi4KMy4gIENoZWNrIGZvciBDLXRlcm1pbmFsIFNBUEEgc2VxdWVuY2UgcmVhZHMsIGV4cGVjdGVkIHRoYXQgdGhleSB3aWxsCiAgICBub3QgYmUgZm91bmQgaW4gdGhlIGtvIHNhbXBsZXMuCgoKIyMgMjAyNTEyCgoxLiAgRGVmaW5lIGEgc2V0IG9mIGNvbnNpc3RlbnQgY29sb3JzLiAgSSB0aGluayBoYXZlIGRhcmtlciBzaGFkZXMgZm9yCiAgICB0aGUgaHVtYW4sIGJ1dCB0aGUgc2FtZSBjb2xvcnMgZm9yIGJvdGguCjIuICBEZWZpbmUgYSBkYXRhc2V0IHdoaWNoIGluY2x1ZGVzIG91ciBwcmV2aW91cyBDTC1CcmVuZXIvQ0wtMTQgZGF0YS4KMy4gIFdlIHNob3VsZCByZWNlaXZlIHNvbWUgbWV0YWRhdGEgaW5jbHVkaW5nIGluZmVjdGlvbiBudW1iZXJzCiAgICAocGFydGljdWxhcmx5IGZvciBleHBlcmltZW50ICMzKSwgbWFrZSB1c2Ugb2YgdGhpcy4KNC4gIERlZmluZSBhIGNvbnNpc3RlbnQgbmFtaW5nIHNjaGVtZS4gKGNvbmRpdGlvbl9iYXRjaCBwZXJoYXBzKQo1LiAgRGVmaW5lIHNvbWUgZXhwZWN0ZWQgbnVtYmVycyBvZiBleHByZXNzZWQgZ2VuZXMgZm9yIGRpZmZlcmVudAogICAgaHVtYW4vbWFtbWFsaWFuIGNlbGwgdHlwZXMuICBUaGlzIGV4cGVyaW1lbnQgaXMgSGVMYSwgYnV0IEkgdGhpbmsKICAgIGl0IHdvdWxkIGJlIGEgbmljZSBiaXQgb2YgY29udGV4dCB0byBleHBsaWNpdGx5IHNlZSBob3cgaXQKICAgIGNvbXBhcmVzIHRvIG90aGVyIG9yZ2FuaXNtcy9jZWxsIHR5cGVzLgo2LiAgQWRkIGFuIG91dGxpZXIgZ2VuZSBsYWJlbGVyIGZvciBib3hwbG90cyBhbmQvb3IgcHJpbnQgYSB0YWJsZSBvZgogICAgb3V0bGllcnMgaW4gcGxvdF9ib3hwbG90KCkuCjcuICBGaWd1cmUgb3V0IHNvbWUgZ29vZCBtZXRyaWNzIHRvIHNlZSBpZiB0aGUgbnVtYmVyIG9mIG5vdC1vYnNlcnZlZAogICAgZ2VuZXMgaXMgcmVsZXZhbnQgdG8gdGhlIG90aGVyIHJlc3VsdHMuIChwbG90X3ByZXBvc3QgaXMgb25lCiAgICBwb3NzaWJpbGl0eSkKOC4gIFBsb3QgY29lZmZpY2llbnQgb2YgdmFyaWFuY2UgdnMuIGJhdGNoL2NvbmRpdGlvbi9ldGMuCjkuICBSdW4gdmFyaWFuY2UgcGFydGl0aW9uCjEwLiBOb3RlOiAxNiBzcGVjaWZpYyBnZW5lcyB3ZXJlIGtub2NrZWQgb3V0IHZpYSB0aGUgYWRkaXRpb24gb2YgUFRDcywKICAgIG1ha2UgdXNlIG9mIG91ciBmcmVlYmF5ZXMvZXRjIHRvb2xzIHRvIGZpbmQvcXVhbnRpZnkgdGhlbS4KMTEuIE9uY2Ugd2UgaGF2ZSB0aGUgY29tYmluZWQgZXhwZXJpbWVudCwgY2hlY2sgYmF0Y2ggIzMgZm9yIGhvdyBpdAogICAgbG9va3Mgd2l0aCByZXNwZWN0IHRvIG90aGVyIHRpbWVwb2ludHMuCjEyLiBNYWtlIHN1cmUgdGhlIENhcyBzYW1wbGVzIGFyZSBnb25lIGFmdGVyIGVhcmx5IHBsb3QocykuCjEzLiBQZXJmb3JtIERFIHdpdGggQmlNL3N2YS9jb21iYXQsIGNvbXBhcmUgdGhlIHJlc3VsdHMuCjE0LiBDaGVjay9jbGVhbiBtdWx0aWdlbmUgZmFtaWxpZXMuCjE1LiBDb25zaWRlciB3aXRoL291dCBiYXRjaCAjMwoxNi4gT24gdGhlIHdheSB0byB0aGF0LCBwZXJmb3JtIGNvbXBhcmlzb25zIG9mIGJhdGNoIDMgdnMuIGJhdGNoIDEvMjsKICAgIHBlcmhhcHMgdGhlIHJlc3VsdHMgd2lsbCB0ZWxsIHVzIGFib3V0IHRoZSBiYXRjaC4KMTcuIFVzZSBrcmFrZW4gdG8gc2VlIGlmIHRoZXJlIGFyZSByZWFkcyB3aGljaCBleHBsYWluIHRoZSBkaWZmZXJlbmNlCiAgICBiZXR3ZWVuIGJhdGNoIDMgYW5kIDEvMi4gIEUuZy4gaXMgdGhlcmUgYW55IGNvbnRhbWluYXRpb24/ICBXZSBjYW4KICAgIG1vc3RseSBhc3N1bWUgdGhlcmUgaXMgbm90IGJlY2F1c2Ugb2YgdGhlIGNoYW5nZSBpbiBodW1hbiByZWFkcy4KMTguIFRvIHRoYXQgZW5kLCBwcm92aWRlIGFuIGV4cGxpY2l0IHJhdGlvIG9mIHJlYWRzL3JlYWRzbWFwcGVkL2V0YwogICAgZm9yIGhzL3RjIG9yIHRjL2hzCgojIEludHJvZHVjdGlvbgoKTGV0IHVzIGNoZWNrIG91dCBzb21lIG5ldyBjcnV6aSBpbmZlY3Rpb25zIGZvbGxvd2luZyB0aGUgZGVsZXRpb24gb2YgYSBzcGVjaWZpYyBnZW5lLgoKSSB0aG91Z2h0IEkgYWxzbyBkaWQgdGhlIGludGVycm9nYXRpb24gb2YgdGhlIENMQnJlbmVyIHRyYW5zY3JpcHRvbWUsCmJ1dCB0aGF0IGFwcGVhcnMgdW50cnVlLiAgSSB0aGluayBJIG1heSBoYXZlIGZvcmdvdHRlbiB0byBjb3B5IHRoZQpnZW5vbWUgaW4gcGxhY2UuLi4KCiMgTm90ZXMgYWJvdXQgdGhlIGludHJvZHVjdGlvbiBvZiBDQVM5CgphIHBST0NLIHBsYXNtaWQgY29udGFpbmluZyBDQVM5IGZvbGxvd2VkIGJ5IEdGUCBhbmQgR0FQREggd2F3cwpsaW5lYXJpemVkIGluIG9yZGVyIHRvIGludGVncmF0ZSB0aGUgQ0FTOSBpbnRvIGEgc3BlY2lmaWMgbG9jYXRpb24gaW4KdGhlIGNydXppIGdlbm9tZS4gIFRjIHR1YnVsaW4gaXMgZmxhbmtpbmcgYSBOb3RJIFJFIHNpdGUsIHNvIEkgd291bGQKYXNzdW1lIHRoZSBpbnRlZ3JhdGlvbiBpcyBhdCBvbmUgb2YgdGhlIHR1YnVsaW4gbG9jaS4gIFRoaXMgcGxhc21pZApoYXMgYm90aCBNMTMgZndkIGFuZCBNMTMgcmV2OyBNMTMgcmV2IGlzIHBvaW50aW5nIHRvd2FyZCB0aGUgR0FQREggYW5kCm0xMyBmb3J3YXJkIGlzIHBvaW50aW5nIHRvIHRoZSBiYWN0ZXJpYWwgb3JpZ2luIG9mIHJlcGxpY2F0aW9uIGFuZApBbXBSLiAgKFRoaXMgaXMgYSBzdHJlcHRvY29jY3VzIENBUzkpCgojIFRyYW5zLXNpYWxpZGFzZSBnZW5lcyB3aGljaCB3ZXJlIG1vZGlmaWVkCgpXZSByZWNlaXZlZCBhbiBlbWFpbCBmbGFnZ2luZyB0aGUgZm9sbG93aW5nIGdlbmVzIGFzIENSSVNQUi9DYXM5CnRhcmdldHMgZm9yIHRoZSBrbm9ja291dHMuICBJIHRoZXJlZm9yZSB3b3VsZCBsaWtlIHRvIGhhdmUgc2NyZWVuc2hvdHMKb2YgZWFjaCBvZiB0aGVzZSByZWdpb25zIHRvIHNob3cgd2hhdCBkaWZmZXJlbmNlcyBhcmUgb2JzZXJ2YWJsZQpiZXR3ZWVuIHRoZSB0aHJlZSBzdHJhaW5zLiAgTm90ZSB0aGF0IHRoZSBsb3dlciBjb3ZlcmFnZSBvZiB0aGUgbGFzdApmZXcgc2FtcGxlcyBtYXkgbWVhbiB0aGF0IHdlIG5lZWQgdG8gc3RpY2sgdG8gdGhlIGZpcnN0IGdyb3VwLgoKKiBUY0NMQi41MDgxNzMuMTIwICAgSGFzIHB1dGF0aXZlIEdQSSBzaWduYWwgKFRjQ2hyMjctUDo4MjIsNTM5Li44MjMsNjgxKCspKQoqIFRjQ0xCLjUwOTQ5NS4zMCAgICBIYXMgcHV0YXRpdmUgR1BJIGFuZCBTQVBBIHJlcGVhdCAoVGNDaHIzMi1QOjc4OSw4MzUuLjc5MCw1MDkoLSkpCiogVGNDTEIuNTEwMDU1LjIwICAgIEdQSSAgKFRjQ2hyMTctUzo1MjYsNDI3Li41MjcsMDM1KCspKQoqIFRjQ0xCLjUwNjk2MS4yNSAgICBHUEkgJ3JlcGVhdHMgYnV0IG1pZ2h0IG5vdCBiZSBzYXBhJyAoVGNDaHIxOC1TOjMsODEzLi42LDk0NygtKSkKKiBUY0NMQi41MTA3ODcuMTAgICAgR1BJICdzYXBhIHJlcGVhdHMnIChUY0NocjMzLVA6MjY1LDc2OS4uMjY5LDM4MygrKSkKKiBUY0NMQi41MTE2NjcuMzAgICAgZ3BpIChUY0NocjMwLVA6ODA1LDk1My4uODA2LDI5MSgrKSkKKiBUY0NMQi41MDcwODUuMzAgICAgZ3BpLCBoaWdobGlnaHRlZCBncmVlbiB0eXJvc2luZSwgJ3NhcGEgcmVwZWF0cycgKFRjQ2hyMzMtUDozMzQsNjU2Li4zMzcsMzM0KCspKQoqIFRjQ0xCLjUwNzQyNy4xMCAgICBncGkgKFRjcnV6aV83MzMyOjEzNy4uMiw2MjMoKykpCiogVGNDTEIuNTA4OTEzLjI1ICAgIGdwaSAoVGNDaHIxNy1QOjUyOCw2ODMuLjUyOSwyOTQoLSkpCiogVGNDTEIuNTA4ODU3LjMwICAgIGdwaSAoVGNDaHIxMS1QOjEyMCw4OTEuLjEyMywwNDcoLSkpCiogVGNDTEIuNTAzOTkzLjEwICAgIGdwaSAoVGNDaHIzMC1QOjY4LDYxMi4uNzAsNjg3KC0pKQoqIFRjQ0xCLjUxMTMyMy4xMCAgICBncGkgJ3NhcGEgcmVwZWF0cycgKFRjQ2hyMTctUDo1NjAsMDM2Li41NjIsNTA0KCspKQoqIFRjQ0xCLjUwODA4OS4xMCAgICBncGkgKFRjQ2hyMTEtUzoyMzksMTkyLi4yNDEsMzQ1KCspKQoqIFRjQ0xCLjUwODcxNy42MCAgICBncGkgKFRjQ2hyMzctUzo0ODMsMjE0Li40ODUsNTcxKCspKQoqIFRjQ0xCLjUwNjk3NS44MCAgICBncGkgKFRjQ2hyMTYtUDo1NTIsOTQ1Li41NTUsMDY1KCspKQoqIFRjQ0xCLjUwNTkzMS4zMCAgICBncGkgKFRjQ2hyMzAtUzo2OCw0NjguLjcwLDU1MigtKSkKKiBUY0NMQi41MDc5NzkuMzAgICAgZ3BpIChUY0NocjE3LVM6NTU5LDkwMS4uNTYyLDQwNSgrKSkKKiBUY0NMQi41MDk4MTcuNTAgICAgZ3BpIChUY0NocjE2LVM6NTUzLDM5Ny4uNTU1LDU0NCgrKSkKKiBUY0NMQi41MDY4NDEuMjAgICAgZ3BpIChUY0NocjM3LVA6NDgzLDIxNC4uNDg1LDU3MSgrKSkKCmBgYHtyfQpleHBlY3RlZF9sb3dlciA8LSBjKCJUY0NMQi41MDgxNzMuMTIwIiwgIlRjQ0xCLjUwOTQ5NS4zMCIsICJUY0NMQi41MTAwNTUuMjAiLCAiVGNDTEIuNTA2OTYxLjI1IiwKICAgICAgICAgICAgICAgICAgICAiVGNDTEIuNTEwNzg3LjEwIiwgIlRjQ0xCLjUxMTY2Ny4zMCIsICJUY0NMQi41MDcwODUuMzAiLAogICAgICAgICAgICAgICAgICAgICJUY0NMQi41MDc0MjcuMTAiLCAiVGNDTEIuNTA4OTEzLjI1IiwgIlRjQ0xCLjUwODg1Ny4zMCIsCiAgICAgICAgICAgICAgICAgICAgIlRjQ0xCLjUwMzk5My4xMCIsICJUY0NMQi41MTEzMjMuMTAiLCAiVGNDTEIuNTA4MDg5LjEwIiwKICAgICAgICAgICAgICAgICAgICAiVGNDTEIuNTA4NzE3LjYwIiwgIlRjQ0xCLjUwNjk3NS44MCIsICJUY0NMQi41MDU5MzEuMzAiLAogICAgICAgICAgICAgICAgICAgICJUY0NMQi41MDc5NzkuMzAiLCAiVGNDTEIuNTA5ODE3LjUwIiwgIlRjQ0xCLjUwNjg0MS4yMCIpCmBgYAoKIyMgT2JzZXJ2YXRpb25zIGluIElHVgoKTm90ZTogSSBhbSByZW1hcHBpbmcgdGhlc2Ugc2FtcGxlcyB3aXRoIHNsaWdodGx5IGRpZmZlcmVudCBwYXJhbWV0ZXJzCndoaWNoIG1heSBtYWtlIHRoaXMgbW9yZSBzZW5zaXRpdmUgZm9yIG11bHRpIGdlbmUgZmFtaWxpZXMsIGJ1dCBJIGRvCm5vdCB0aGluayBpdCB3aWxsIGNoYW5nZSBhbnl0aGluZy4KCjEuICBUY0NMQi41MDgxNzMuMTIwOiBObyBkaWZmZXJlbmNlcyBvYnNlcnZlZCBpbiBzYW1wbGVzIDA2KGtvKSwKICAgIDM2KHd0KSwgMjMoYWIpCjIuICBUY0NMQi41MDk0OTUuMzA6IE5ETyAobm8gZGlmZmVyZW5jZSBvYnNlcnZlZCkKMy4gIFRjQ0xCLjUxMDA1NS4yMDogRm91bmQga28tc3BlY2lmaWMgbXV0YXRpb25zIGF0IHRoZSB2ZXJ5IDMnIGVuZCBvZgogICAgdGhlIGdlbmUsIHNlZW1zIHVubGlrZWx5IHRvIGluZHVjZSBhIGNoYW5nZSBpbiBmdW5jdGlvbiBub3IgTk1ECjQuICBUY0NMQi41MDY5NjEuMjU6IEluc2lnbmlmaWNhbnQgY292ZXJhZ2UgaW4gdGhlIHd0LiAgR29vZCBjb3ZlcmFnZQogICAgaW4ga28vYWI7IDY1JSBHLT5BIGluIGtvIHRvIG1ha2Ugc3lub3ltb3VzIGNvZG9uCjUuICBUY0NMQi41MTA3ODcuMTA6IEluY29uc2lzdGVudCBjb3ZlcmFnZSBpbiBhbGwgc2FtcGxlcywgTkRPLgo2LiAgVGNDTEIuNTExNjY3LjMwOiBMb3cgY292ZXJhZ2UgaW4gYWxsIHNhbXBsZXM6IE5ETwo3LiAgVGNDTEIuNTA3NDI3LjEwOiBMb3cgY292ZXJhZ2UgaW4gd3QsIFQtPkMgNScgb2Yga28KOC4gIFRjQ0xCLjUwODkxMy4yNTogTG93IGNvdmVyYWdlIGluIGFsbCwgTkRPCjkuICBUY0NMQi41MDg4NTcuMzA6IExvdyBjb3ZlcmFnZSBpbiB3dCwgTkRPCjEwLiBUY0NMQi41MDM5OTMuMTA6IE5ETwoxMS4gVGNDTEIuNTExMzIzLjEwOiBORE8sIHRvb2sgc2NyZWVuc2hvdAoxMi4gVGNDTEIuNTA4MDg5LjEwOiBORE8KMTMuIFRjQ0xCLjUwODcxNy42MDogTkRPIGxvdyBjb3ZlcmFnZSBpbiB3dAoxNC4gVGNDTEIuNTA2OTc1LjgwOiBsb3cgY292ZXJhZ2UgaW4gYWxsIHNhbXBsZXMuCjE1LiBUY0NMQi41MDU5MzEuMzA6IGxvdyBjb3ZlcmFnZSwgTkRPLCBuZXh0IGdlbmUgaGFzIHRyZW1lbmRvdXMgY292ZXJhZ2UKMTYuIFRjQ0xCLjUwNzk3OS4zMDogTkRPCjE3LiBUY0NMQi41MDk4MTcuNTA6IGxvdyBjb3ZlcmFnZQoxOC4gVGNDTEIuNTA2ODQxLjIwOiBuaWNlIGNvdmVyYWdlLCBORE8KCkkgdGhlcmVmb3JlIG9wZW5lZCB1cCB0aGUgZnJlZWJheWVzIG91dHB1dCBzb3J0ZWQgYnkgQ0RTIGFuZCBsb29rZWQKZm9yIG5vbnNlbnNlIG11dGF0aW9ucyBpbnRyb2R1Y2VkIGluIG9uZSBrbyBhbmQgb25lIEFCIHNhbXBsZS4KCkkgZm91bmQgNDMgaW4gdGhlIEtPIGFuZCA3OSBpbiB0aGUgQUIuCgojIEh1bWFuIGFubm90YXRpb24gaW5mb3JtYXRpb24KCkkgaGF2ZSBhIHByZXR0eSBuZXcgZ2Vub21lIGRvd25sb2FkZWQgKDIwMjUwOSksIHNvIEkgd2lsbCAoZm9yIG5vdykKanVzdCBsZXQgbXkgYW5ub3RhdGlvbiBmdW5jdGlvbiBncmFiIHdoYXRldmVyIGl0IHRoaW5rcyBpcyByZWFzb25hYmxlLgpJdCBjaG9zZSB0aGUgMjAyNDEwIHNldC4gIFNlZW1zIGdvb2QgdG8gbWUuCgpgYGB7cn0KaHNfYW5ub3QgPC0gbG9hZF9iaW9tYXJ0X2Fubm90YXRpb25zKCkKCnRjX2Fubm90IDwtIGxvYWRfZ2ZmX2Fubm90YXRpb25zKCJ+L2xpYnJhcmllcy9nZW5vbWUvZ2ZmL3RjcnV6aV9hbGwuZ2ZmIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICJtUk5BIiwgaWRfY29sID0gIlBhcmVudCIpCnJvd25hbWVzKHRjX2Fubm90KSA8LSBnc3ViKHggPSBtYWtlLm5hbWVzKHRjX2Fubm90W1siTmFtZSJdXSwgdW5pcXVlID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiXFwuXFxkKyQiLCByZXBsYWNlbWVudCA9ICIiKQplc21lcl9kYiA8LSAib3JnLlRjcnV6aS5DTC5CcmVuZXIuRXNtZXJhbGRvLmxpa2UudjY4LmVnLmRiIgpsaWJyYXJ5KGVzbWVyX2RiLCBjaGFyYWN0ZXIub25seSA9IFRSVUUpCmVzbWVyX2RiIDwtIGdldDAoZXNtZXJfZGIpCmFsbF9rZXl0eXBlcyA8LSBrZXl0eXBlcyhlc21lcl9kYikKd2FudGVkX2lkeCA8LSBncmVwbCh4ID0gYWxsX2tleXR5cGVzLCBwYXR0ZXJuID0gIl5BTk5PVF8iKQp3YW50ZWRfZmllbGRzIDwtIGFsbF9rZXl0eXBlc1t3YW50ZWRfaWR4XQpub25lc21lcl9kYiA8LSAib3JnLlRjcnV6aS5DTC5CcmVuZXIuTm9uLkVzbWVyYWxkby5saWtlLnY2OC5lZy5kYiIKdW5hc19kYiA8LSAib3JnLlRjcnV6aS5DTC5CcmVuZXIudjY4LmVnLmRiIgoKdGNfZXNtZXIgPC0gbG9hZF9vcmdkYl9hbm5vdGF0aW9ucyhlc21lcl9kYiwga2V5dHlwZSA9ICJnaWQiLCBmaWVsZHMgPSB3YW50ZWRfZmllbGRzKQp0Y19ub25lc21lciA8LSBsb2FkX29yZ2RiX2Fubm90YXRpb25zKG5vbmVzbWVyX2RiLCBrZXl0eXBlID0gImdpZCIsIGZpZWxkcyA9IHdhbnRlZF9maWVsZHMpCnRjX3VuYXMgPC0gbG9hZF9vcmdkYl9hbm5vdGF0aW9ucyh1bmFzX2RiLCBrZXl0eXBlID0gImdpZCIsIGZpZWxkcyA9IHdhbnRlZF9maWVsZHMpCnRjX21vcmUgPC0gcmJpbmQodGNfZXNtZXIkZ2VuZXMsIHRjX25vbmVzbWVyJGdlbmVzLCB0Y191bmFzJGdlbmVzKQp0Y19hbm5vdCA8LSBtZXJnZSh0Y19hbm5vdCwgdGNfbW9yZSwgYnkgPSAicm93Lm5hbWVzIikKcm93bmFtZXModGNfYW5ub3QpIDwtIHRjX2Fubm90W1siZ2lkIl1dCnRjX2Fubm90W1siZ2lkIl1dIDwtIE5VTEwKZGltKHRjX2Fubm90KQpgYGAKCiMjIExvYWQgY3J1emkgR08gZGF0YSBzaW1pbGFybHkKCmBgYHtyfQp0Y19lc21lcl9nbyA8LSBsb2FkX29yZ2RiX2dvKGVzbWVyX2RiLCBrZXl0eXBlID0gIkdJRCIpCnRjX25vbmVzbWVyX2dvIDwtIGxvYWRfb3JnZGJfZ28obm9uZXNtZXJfZGIsIGtleXR5cGUgPSAiR0lEIikKdGNfdW5hc19nbyA8LSBsb2FkX29yZ2RiX2dvKHVuYXNfZGIsIGtleXR5cGUgPSAiR0lEIikKCnRjX2dvIDwtIHJiaW5kKHRjX2VzbWVyX2dvLCB0Y19ub25lc21lcl9nbywgdGNfdW5hc19nbykKdGNfZ28gPC0gdGNfZ29bLCBjKCJHTyIsICJHSUQiKV0KY29sbmFtZXModGNfZ28pIDwtIGMoIkdPIiwgIklEIikKCnRjX2xlbmd0aCA8LSB0Y19hbm5vdFssIGMoIlBhcmVudCIsICJhbm5vdF90cmFuc2NyaXB0X2xlbmd0aCIpXQpjb2xuYW1lcyh0Y19sZW5ndGgpIDwtIGMoIklEIiwgImxlbmd0aCIpCmBgYAoKIyBTYW1wbGUgc2hlZXQKCkkgYXNrZWQgZm9yIG9uZSBmcm9tIE5hamliL0FtYWxpZSBidXQgdW5sZXNzIEkgYW0gbWlzdGFrZW4gaXQgaGFzIG5vdAphcnJpdmVkLiAgVGhhdCBpcyBub3QgYSBwcm9ibGVtLCBnaXZlbiB0d28gaGVscGZ1bCB0aGluZ3M6IEFwcmlsCnByb3ZpZGVzIG9uZSwgSSBhbHNvIG5hbWVkIHRoZSBkaXJlY3RvcmllcyBzbyB0aGF0IHRoZSBzYW1wbGUgSURzIGFyZQpidWlsdCBpbjsgc28gSSB3aWxsIGp1c3QgbWFrZSBhIGZha2Ugb25lIGZvciBub3cgYW5kIHRoZW4gbWVyZ2UgaW4Kd2hhdGV2ZXIgSSBnZXQgZnJvbSB0aGVtLi4uCgpgYGB7cn0Kc2FtcGxlX3NoZWV0IDwtICJzYW1wbGVfc2hlZXRzL2FsbF9zYW1wbGVzLnhsc3giCgptZXRhX3NhbmtleSA8LSBwbG90X21ldGFfc2Fua2V5KGFzLmRhdGEuZnJhbWUoZXh0cmFjdF9tZXRhZGF0YShzYW1wbGVfc2hlZXQpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWN0b3JzID0gYygiYmFja2dyb3VuZCIsICJleHBfbnVtYmVyIikpCnBwKGZpbGUgPSAiaW1hZ2VzL21ldGFfc2Fua2V5LnBuZyIsIGltYWdlID0gbWV0YV9zYW5rZXlbWyJwbG90Il1dKQptZXRhX3NhbmtleVtbInBsb3QiXV0KYGBgCgojIEFkZGluZyBzb21lIG1ldGFkYXRhCgpMZXQgdXMgc2VlIGhvdyB3ZWxsIG15IHByZXByb2Nlc3MgZ2F0aGVyZXIgZG9lcy4uLgoKYGBge3J9Cm5ld19tZXRhIDwtIGdhdGhlcl9wcmVwcm9jZXNzaW5nX21ldGFkYXRhKHNhbXBsZV9zaGVldCwgc3BlY2llcyA9IGMoImhnMzhfMTE1IiwgInRjcnV6aV9hbGwiKSkKaGVhZChuZXdfbWV0YVtbIm5ld19tZXRhIl1dKQpgYGAKClN0cmFuZ2VseSwgdGhpcyBkaWQgbm90IHBpY2sgdXAgdGhlIGZyZWViYXllcyBvdXRwdXRzLiAgSSB3aWxsIGFkZAp0aGVtIG1hbnVhbGx5IHRvIHRoZSBvcmlnaW5hbCBzaGVldC4gIFBvc3NpYmx5IGJlY2F1c2UgSSByYW4gaXQgdHdpY2UKd2l0aCBkaWZmZXJlbnQgcGFyYW1ldGVycywgbXkgY29kZSBnZXRzIGNvbmZ1c2VkIHdoZW4gbXVsdGlwbGUgZmlsZXMKbWF0Y2ggdGhlIHNhbWUgcnVsZS4KCiMgRGVmaW5lIGNvbG9ycwoKYGBge3J9CmNvbG9yX2Nob2ljZXMgPC0gbGlzdCgKICAiaHMiID0gbGlzdCgKICAgICJBQjEwIiA9ICIjMDg2NDQ4IiwKICAgICJjYXMiID0gIiM3MDI2MDEiLAogICAgImNvbnRyb2wiID0gIiM0NTQxNzgiLAogICAgImtvNyIgPSAiIzg3MDY0OSIsCiAgICAicG9zaXRpdmUiID0gIiM0NjA2MEUiLAogICAgInd0IiA9ICIjNzg1QzAxIiksCiAgInRjIiA9IGxpc3QoCiAgICAiQUIxMCIgPSAiIzBEQTg3NyIsCiAgICAiY2FzIiA9ICIjQkEzRjAxIiwKICAgICJjb250cm9sIiA9ICIjNzc3MUQxIiwKICAgICJrbzciID0gIiNCRjA4NkEiLAogICAgInBvc2l0aXZlIiA9ICIjOEYwQzFFIiwKICAgICJ3dCIgPSAiI0FGODQwMSIpKQpgYGAKClRoZXNlIGNvbG9ycyBhcmUgYmFkLCB0aGUgaHVtYW4gYXJlIHRvbyBkYXJrIGFuZCBsb3NlIHRoZWlyIGNvbnRyYXN0CndpdGggcmVzcGVjdCB0byBlYWNoIG90aGVyLiAgSSBzaG91bGQgZ2V0IE5hamliL0FwcmlsL0FtYWxpZSB0byBoZWxwCmRlZmluZSBiZXR0ZXIuCgojIFRoZSBwcmltYXJ5IGRhdGEgc3RydWN0dXJlCgpgYGB7cn0KaHNfc2UgPC0gY3JlYXRlX3NlKG5ld19tZXRhW1sibmV3X21ldGEiXV0sIGdlbmVfaW5mbyA9IGhzX2Fubm90W1siZ2VuZV9hbm5vdGF0aW9ucyJdXSwKICAgICAgICAgICAgICAgICAgIGZpbGVfY29sdW1uID0gImhpc2F0X2NvdW50X3RhYmxlX2hnMzhfMTE1IikgJT4lCiAgc2V0X2NvbmRpdGlvbnMoZmFjdCA9ICJiYWNrZ3JvdW5kIikgJT4lCiAgc2V0X2JhdGNoZXMoZmFjdCA9ICJleHBfbnVtYmVyIikgJT4lCiAgc2V0X2NvbG9ycyhjb2xvcl9jaG9pY2VzW1siaHMiXV0pCmhzX3dyaXR0ZW4gPC0gd3JpdGVfc2UoaHNfc2UsIGV4Y2VsID0gImV4Y2VsL2hzX2V4cHJlc3Npb25fZGF0YS54bHN4IikKCnRjX3NlIDwtIGNyZWF0ZV9zZShuZXdfbWV0YVtbIm5ld19tZXRhIl1dLCBnZW5lX2luZm8gPSB0Y19hbm5vdCwKICAgICAgICAgICAgICAgICAgIGZpbGVfY29sdW1uID0gImhpc2F0X2NvdW50X3RhYmxlX3RjcnV6aV9hbGwiKSAlPiUKICBzZXRfY29uZGl0aW9ucyhmYWN0ID0gImJhY2tncm91bmQiKSAlPiUKICBzZXRfYmF0Y2hlcyhmYWN0ID0gImV4cF9udW1iZXIiKSAlPiUKICBzZXRfY29sb3JzKGNvbG9yX2Nob2ljZXNbWyJ0YyJdXSkKdGNfd3JpdHRlbiA8LSB3cml0ZV9zZSh0Y19zZSwgZXhjZWwgPSAiZXhjZWwvdGNfZXhwcmVzc2lvbl9kYXRhLnhsc3giKQpgYGAKCk9uZSBvZiBteSBjb25jZXJucyBzdXJyb3VuZHMgdGhlIGZhdGUgb2YgdGhlIHZhcmlvdXMgdHJhbnMtc2lhbGlkYXNlCmdlbmVzIGFuZCB0aGUgYWJpbGl0eSB0byBkaXNjZXJuIHRoZSBlZmZpY2FjaW91c25lc3Mgb2YgYWRkaW5nIHN0b3AKY29kb25zIHRvIHRoZW0uICBJIHRoZXJlZm9yZSBxdWFudGlmaWVkIHRoZSBzYW1wbGVzIHdpdGggc2FsbW9uIHdoaWNoCkkgdGhpbmsgaXMgbW9yZSBzZW5zaXRpdmUgdG8gbXVsdGkgZ2VuZSBmYW1pbGllcy4KCmBgYHtyfQpzYWxtb25fYW5ub3QgPC0gdGNfYW5ub3QKcm93bmFtZXMoc2FsbW9uX2Fubm90KSA8LSBwYXN0ZTAocm93bmFtZXMoc2FsbW9uX2Fubm90KSwgIjptUk5BIikKdGNfc2FsbW9uIDwtIGNyZWF0ZV9zZShuZXdfbWV0YVtbIm5ld19tZXRhIl1dLCBnZW5lX2luZm8gPSBzYWxtb25fYW5ub3QsCiAgICAgICAgICAgICAgICAgICAgICAgZmlsZV9jb2x1bW4gPSAic2FsbW9uX2NvdW50X3RhYmxlX3RjcnV6aV9hbGwiKSAlPiUKICBzZXRfY29uZGl0aW9ucyhmYWN0ID0gImJhY2tncm91bmQiKSAlPiUKICBzZXRfYmF0Y2hlcyhmYWN0ID0gImV4cF9udW1iZXIiKSAlPiUKICBzZXRfY29sb3JzKGNvbG9yX2Nob2ljZXNbWyJ0YyJdXSkKYGBgCgojIENoZWNrIG1ldGFkYXRhIHZzIG1hcHBpbmcgc3RhdGlzdGljcwoKYGBge3J9CmhzX21hcHBlZCA8LSBwbG90X21ldGFkYXRhX2ZhY3RvcnMoaHNfc2UsIGNvbHVtbiA9ICJoaXNhdF9nZW5vbWVfcGVyY2VudF9sb2dfaGczOF8xMTUiKQpwcChmaWxlID0gImltYWdlcy9oc19oaXNhdF9tYXBwaW5nX3BlcmNlbnQucG5nIiwgaW1hZ2UgPSBoc19tYXBwZWQpCgpoc19nZW5lcyA8LSBwbG90X21ldGFkYXRhX2ZhY3RvcnMoaHNfc2UsIGNvbHVtbiA9ICJzYWxtb25fb2JzZXJ2ZWRfZ2VuZXNfaGczOF8xMTUiKQpoc19nZW5lcwoKdGNfbWFwcGVkIDwtIHBsb3RfbWV0YWRhdGFfZmFjdG9ycyh0Y19zZSwgY29sdW1uID0gImhpc2F0X2dlbm9tZV9wZXJjZW50X2xvZ190Y3J1emlfYWxsIikKcHAoZmlsZSA9ICJpbWFnZXMvdGNfaGlzYXRfbWFwcGluZ19wZXJjZW50LnBuZyIsIGltYWdlID0gdGNfbWFwcGVkKQpgYGAKCiMgQSBGZXcgaW5pdGlhbCBwbG90cwoKSSBwaWNrZWQgb2ZmIGFub3RoZXIgVE9ETyBpbiBoZXJlLCBJIGNoYW5nZWQgcGxvdF9ub256ZXJvIHRvIG1vcmUKaW50ZWxsaWdlbnRseSBzZXQgdGhlIHRleHQgYW5ub3RhdGlvbi4KCmBgYHtyfQp0Y19ueiA8LSBwbG90X25vbnplcm8odGNfc2UpCnBwKGZpbGUgPSAiaW1hZ2VzL3RjX25vbnplcm8ucG5nIiwgaW1hZ2UgPSB0Y19ueikKCnRjX3NlIDwtIHN1YnNldF9zZSh0Y19zZSwgbm9uemVybyA9IDUwMDApCnRjX2ZpbHRfbnogPC0gcGxvdF9ub256ZXJvKHRjX3NlLCB5X2ludGVyY2VwdCA9IDAuOSkKcHAoZmlsZSA9ICJpbWFnZXMvdGNfbm9uemVyb19maWx0ZXJlZC5wbmciLCBpbWFnZSA9IHRjX2ZpbHRfbnopCgpoc19saWJzaXplIDwtIHBsb3RfbGlic2l6ZShoc19zZSkKcHAoZmlsZSA9ICJpbWFnZXMvaHNfbGlic2l6ZS5wbmciLCBpbWFnZSA9IGhzX2xpYnNpemUpCmhzX256IDwtIHBsb3Rfbm9uemVybyhoc19zZSkKcHAoZmlsZSA9ICJpbWFnZXMvaHNfbnoucG5nIiwgaW1hZ2UgPSBoc19ueikKcGxvdF9ib3hwbG90KGhzX3NlKQoKdGNfbGlic2l6ZSA8LSBwbG90X2xpYnNpemUodGNfc2UpCnBwKGZpbGUgPSAiaW1hZ2VzL3RjX2xpYnNpemUucG5nIiwgaW1hZ2UgPSB0Y19saWJzaXplKQoKaHNfcmVwbGljYXRlZCA8LSBzdWJzZXRfc2UoaHNfc2UsIG1pbl9yZXBsaWNhdGVzID0gMywgZmFjdCA9ICJjb25kaXRpb24iKQp0Y19yZXBsaWNhdGVkIDwtIHN1YnNldF9zZSh0Y19zZSwgbWluX3JlcGxpY2F0ZXMgPSAzLCBmYWN0ID0gImNvbmRpdGlvbiIpICU+JQogIHN1YnNldF9zZShub256ZXJvID0gMTAwMDApCnRjc2FsX3JlcGxpY2F0ZWQgPC0gc3Vic2V0X3NlKHRjX3NhbG1vbiwgbWluX3JlcGxpY2F0ZXMgPSAzLCBmYWN0ID0gImNvbmRpdGlvbiIpICU+JQogIHN1YnNldF9zZShub256ZXJvID0gMTAwMDApCmBgYAoKIyMgUG9rZSBhdCB0aGUgdmFyaWFudHMgYnJpZWZseQoKYGBge3J9CnRjX3ZhcmlhbnRzIDwtIGNvdW50X3NucHModGNfcmVwbGljYXRlZCwgYW5ub3RfY29sdW1uID0gImZyZWViYXllc190YWJsZSIsIHNucF9jb2x1bW4gPSAiUEFJUkVEIikKYGBgCgpSZW1pbmRlciB0byBzZWxmOiAgY291bnRfc25wcyByZWFkcyB0aGUgZnJlZWJheWVzIHRhYmxlLCBwYXNzIHRoYXQgdG8KZ2V0X3NucF9zZXRzKCkgdG8gY3Jvc3MgcmVmZXJlbmNlIGFnYWluc3QgdGhlIGV4cGVyaW1lbnRhbCBkZXNpZ24sCnRoZW4gcGFzcyB0aGF0IHRvIHNucHNfaW50ZXJzZWN0aW9ucygpIGFuZCBzbnBzX3ZzX2dlbmVzKCkuICBJIHNob3VsZApjaGFuZ2UgdGhhdCB0byBiZSBhYmxlIHRvIGRpcmVjdGx5IHRha2UgdGhlIG91dHB1dCBmcm9tIGNvdW50X3NucHMoKQoKYGBge3J9CnZhcl9ub3JtIDwtIG5vcm1hbGl6ZSh0Y192YXJpYW50cywgY29udmVydCA9ICJjcG0iLCBub3JtID0gInF1YW50IiwKICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIHRyYW5zZm9ybSA9ICJsb2cyIikKdGNfdmFyaWFudF9wY2EgPC0gcGxvdF9wY2EodmFyX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL3RjX3ZhcmlhbnRfcGNhLnBuZyIsIGltYWdlID0gdGNfdmFyaWFudF9wY2FbWyJwbG90Il1dKQoKdGNfc2V0cyA8LSBnZXRfc25wX3NldHModGNfdmFyaWFudHMsIGZhY3RvciA9ICJjb25kaXRpb24iLCBwcm9wb3J0aW9uID0gMC43NSkKdGNfc2V0cwoKc25wX2ludGVyc2VjdGlvbnMgPC0gc25wc19pbnRlcnNlY3Rpb25zKHRjX3NlLCB0Y19zZXRzLCBzdGFydF9jb2x1bW4gPSAic3RhcnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kX2NvbHVtbiA9ICJlbmQiLCBjaHJfY29sdW1uID0gImFubm90X3NlcXVlbmNlX2lkIikKc25wX2ludGVyc2VjdGlvbnMKCnNucHNfdnNfZ2VuZXMgPC0gc25wc192c19nZW5lcyh0Y19zZSwgdGNfc2V0cywgc3RhcnRfY29sdW1uID0gInN0YXJ0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZF9jb2x1bW4gPSAiZW5kIiwgY2hyX2NvbHVtbiA9ICJzZXFuYW1lcyIpCnNucHNfdnNfZ2VuZXMKYGBgCgojIFZhcmlhbmNlIFBhcnRpdGlvbgoKSGVyZSBhcmUgYSBjb3VwbGUgb2YgdmFyaWFuY2UgcGFydGl0aW9uIGludm9jYXRpb25zLiAgT25jZSB3ZSBoYXZlCm90aGVyIG1ldGFkYXRhLCB0aGlzIHdpbGwgYmUgbW9yZSB1c2VmdWwuICBOb3RlLCB0aGlzIHdpbGwgb25seSB3b3JrCm9uY2UgdGhlIG5vbi1yZXBsaWNhdGVkIGNvbmRpdGlvbnMgYXJlIHJlbW92ZWQgKGNvbnRyb2wgYW5kIGNhcykuCgpgYGB7cn0KaHNfdmFycGFydCA8LSBzaW1wbGVfdmFycGFydChoc19yZXBsaWNhdGVkKQpwcChmaWxlID0gImltYWdlcy9oc192YXJwYXJ0X3Zpb2xpbi5wbmciLCBpbWFnZSA9IGhzX3ZhcnBhcnRbWyJwYXJ0aXRpb25fcGxvdCJdXSkKcHAoZmlsZSA9ICJpbWFnZXMvaHNfdmFycGFydF9wZXJjZW50LnBuZyIsIGltYWdlID0gaHNfdmFycGFydFtbInBlcmNlbnRfcGxvdCJdXSkKCnRjX3ZhcnBhcnQgPC0gc2ltcGxlX3ZhcnBhcnQodGNfcmVwbGljYXRlZCkKcHAoZmlsZSA9ICJpbWFnZXMvdGNfdmFycGFydF92aW9saW4ucG5nIiwgaW1hZ2UgPSB0Y192YXJwYXJ0W1sicGFydGl0aW9uX3Bsb3QiXV0pCnBwKGZpbGUgPSAiaW1hZ2VzL3RjX3ZhcnBhcnRfcGVyY2VudC5wbmciLCBpbWFnZSA9IHRjX3ZhcnBhcnRbWyJwZXJjZW50X3Bsb3QiXV0pCmBgYAoKSSB0aGluayB3ZSBwcm9iYWJseSBzaG91bGQgbm90IGJlIHN1cnByaXNlZCBhdCB0aGUgYW1vdW50IG9mIHZhcmlhbmNlCmF0dHJpYnV0ZWQgdG8gdGhlIGJhdGNoIGR1ZSB0byB0aGUgdmVyeSBsYXJnZSBkaWZmZXJlbmNlIGluIGNvdmVyYWdlCmJldHdlZW4gZXhwZXJpbWVudCAjMyBhbmQgMS8yLgoKIyBTYW1wbGUgY2x1c3RlcmluZwoKIyMgSHVtYW4KClBlcmZvcm0gb3VyIGRlZmF1bHQgUENBIHBsb3QgYWxvbmcgd2l0aCBhIGNvbWJhdCB2ZXJzaW9uLgoKYGBge3J9CmhzX25vcm0gPC0gbm9ybWFsaXplKGhzX3JlcGxpY2F0ZWQsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKaHNfZGlzaGVhdCA8LSBwbG90X2Rpc2hlYXQoaHNfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvaHNfZGlzdGFuY2VfaGVhdG1hcC5wbmciLCBpbWFnZSA9IGhzX2Rpc2hlYXQyKQoKaHNfY29yaGVhdCA8LSBwbG90X2NvcmhlYXQoaHNfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvaHNfY29ycmVsYXRpb25faGVhdG1hcC5wbmciLCBpbWFnZSA9IGhzX2NvcmhlYXRbWyJwbG90Il1dKQpoc19ub3JtX3BjYSA8LSBwbG90X3BjYShoc19ub3JtLCBwbG90X2xhYmVscyA9IFRSVUUpCnBwKGZpbGUgPSAiaW1hZ2VzL2hzX25vcm1fcGNhLnBuZyIsIGltYWdlID0gaHNfbm9ybV9wY2FbWyJwbG90Il1dKQoKaHNfbmIgPC0gbm9ybWFsaXplKGhzX3JlcGxpY2F0ZWQsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAic3Zhc2VxIikKaHNfbmJfcGNhIDwtIHBsb3RfcGNhKGhzX25iKQpwcChmaWxlID0gImltYWdlcy9oc19ub3JtX3N2YV9wY2EucG5nIiwgaW1hZ2UgPSBoc19uYl9wY2FbWyJwbG90Il1dKQoKCmhzX2NiIDwtIG5vcm1hbGl6ZShoc19yZXBsaWNhdGVkLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gImNvbWJhdCIpCmhzX2NvbWJhdF9wY2EgPC0gcGxvdF9wY2EoaHNfY2IpCnBwKGZpbGUgPSAiaW1hZ2VzL2hzX25vcm1fY29tYmF0X3BjYS5wbmciLCBpbWFnZSA9IGhzX2NvbWJhdF9wY2FbWyJwbG90Il1dKQpgYGAKCiMjIFBhcmFzaXRlCgpgYGB7cn0KdGNfbm9ybSA8LSBub3JtYWxpemUodGNfc2UsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICBub3JtID0gInF1YW50IiwgZmlsdGVyID0gVFJVRSkKdGNfZGlzaGVhdCA8LSBwbG90X2Rpc2hlYXQodGNfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvdGNfZGlzdGFuY2VfaGVhdG1hcC5wbmciLCBpbWFnZSA9IHRjX2Rpc2hlYXQpCgp0Y19jb3JoZWF0IDwtIHBsb3RfY29yaGVhdCh0Y19ub3JtKQpwcChmaWxlID0gImltYWdlcy90Y19jb3JyZWxhdGlvbl9oZWF0bWFwLnBuZyIsIGltYWdlID0gdGNfY29yaGVhdCkKYGBgCgpBIGxpdHRsZSBiaXQgb2YgZnVuLCBleHRyYWN0IHRoZSBnZW5lcyB3aGljaCBhcmUgaGlnaC1vdXRsaWVycyBpbiBlYWNoCnNhbXBsZSBhbmQgcHJpbnQgd2hhdCB0aGV5IGFyZS4KCmBgYHtyfQpub3JtX2JveHBsb3QgPC0gcGxvdF9ib3hwbG90KHRjX25vcm0pCm5vcm1fYm94cGxvdFtbInBsb3QiXV0KaGlnaF9nZW5lcyA8LSB1bmlxdWUoYXMuY2hhcmFjdGVyKHVubGlzdChub3JtX2JveHBsb3RbWyJoaWdoX291dGxpZXJfZ2VuZXMiXV0pKSkKdW5pcXVlKHJvd0RhdGEodGNfc2UpW2hpZ2hfZ2VuZXMsIF1bWyJhbm5vdF90cmFuc2NyaXB0X3Byb2R1Y3QiXV0pCmBgYAoKYGBge3J9CnRjX25vcm1fcGNhIDwtIHBsb3RfcGNhKHRjX25vcm0sIHBsb3RfbGFiZWxzID0gVFJVRSkKcHAoZmlsZSA9ICJpbWFnZXMvdGNfbm9ybV9wY2EucG5nIiwgaW1hZ2UgPSB0Y19ub3JtX3BjYSkKCnRjX3Jub3JtIDwtIG5vcm1hbGl6ZSh0Y19yZXBsaWNhdGVkLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwKICAgICAgICAgICAgICAgICAgICAgbm9ybSA9ICJxdWFudCIsIGZpbHRlciA9IFRSVUUpCnRjX3Jub3JtX2Rpc2hlYXQgPC0gcGxvdF9kaXNoZWF0KHRjX3Jub3JtKQpwcChmaWxlID0gImltYWdlcy90Y19ybm9ybV9kaXNoZWF0LnBuZyIsIGltYWdlID0gdGNfcm5vcm1fZGlzaGVhdCkKdGNfcm5vcm1fcGNhIDwtIHBsb3RfcGNhKHRjX3Jub3JtKQpwcChmaWxlID0gImltYWdlcy90Y19ybm9ybV9wY2EucG5nIiwgaW1hZ2UgPSB0Y19ybm9ybV9wY2EpCgp0Y19yYm5vcm0gPC0gbm9ybWFsaXplKHRjX3JlcGxpY2F0ZWQsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgIGZpbHRlciA9IFRSVUUsIGJhdGNoID0gInN2YXNlcSIpCnRjX3N2YV9wY2EgPC0gcGxvdF9wY2EodGNfcmJub3JtKQpwcChmaWxlID0gImltYWdlcy90Y19zdmFfcGNhLnBuZyIsIGltYWdlID0gdGNfc3ZhX3BjYSkKCnRjX2Nibm9ybSA8LSBub3JtYWxpemUodGNfcmVwbGljYXRlZCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSwgYmF0Y2ggPSAiY29tYmF0IikKdGNfY29tYmF0X3BjYSA8LSBwbG90X3BjYSh0Y19jYm5vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL3RjX2NvbWJhdF9wY2EucG5nIiwgaW1hZ2UgPSB0Y19jb21iYXRfcGNhKQpgYGAKCiMgRGlmZmVyZW50aWFsIEV4cHJlc3Npb24KCkkgYW0gbm90IHRoaW5raW5nIHdlIHdpbGwgc2VlIG1hbnkgZ2VuZXMgb2YgaW50ZXJlc3QuCgpgYGB7cn0KaHNfa2VlcGVycyA8LSBsaXN0KAogICJhYl92c19jb250cm9sIiA9IGMoIkFCMTAiLCAiY29udHJvbCIpLAogICJrb192c19jb250cm9sIiA9IGMoImtvNyIsICJjb250cm9sIiksCiAgImtvX3ZzX3d0IiA9IGMoImtvNyIsICJ3dCIpLAogICJhYl92c193dCIgPSBjKCJBQjEwIiwgInd0IiksCiAgImFiX3ZzX2tvIiA9IGMoIkFCMTAiLCAia283IikpCmhzX2RlIDwtIGFsbF9wYWlyd2lzZShoc19yZXBsaWNhdGVkLCBmaWx0ZXIgPSBUUlVFLCBtb2RlbF9mc3RyaW5nID0gIn4gMCArIGNvbmRpdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICBtb2RlbF9zdnMgPSAic3Zhc2VxIikKaHNfZGUKCmhzX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcyhoc19kZSwga2VlcGVycyA9IGhzX2tlZXBlcnMsIGV4Y2VsID0gImV4Y2VsL2hzX3RhYmxlcy54bHN4IikKaHNfdGFibGVzCgpoc19zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhoc190YWJsZXMsIGV4Y2VsID0gImV4Y2VsL2hzX3NpZy54bHN4IikKaHNfc2lnCmBgYAoKV2hpbGUgaXQgaXMgdHJ1ZSB0aGVyZSBhcmUgbm90IGEgdHJlbWVuZG91cyBudW1iZXIgb2YgZ2VuZXMsIGF0IGxlYXN0CnNvbWUgb2YgdGhlIGdyb3VwcyBhcmUgaW50ZXJlc3RpbmcuCgpgYGB7cn0KaHNfZ3AgPC0gYWxsX2dwcm9maWxlcihoc19zaWcpCmhzX2dwCmBgYAoKYGBge3J9CmNvbmRpdGlvbnModGNfcmVwbGljYXRlZCkKdGNfa2VlcGVycyA8LSBsaXN0KAogICJhYl92c193dCIgPSBjKCJBQjEwIiwgInd0IiksCiAgImtvX3ZzX3d0IiA9IGMoImtvNyIsICJ3dCIpLAogICJhYl92c19rbyIgPSBjKCJBQjEwIiwgImtvNyIpKQp0Y19kZSA8LSBhbGxfcGFpcndpc2UodGNfcmVwbGljYXRlZCwgZmlsdGVyID0gVFJVRSwgbW9kZWxfZnN0cmluZyA9ICJ+IDAgKyBjb25kaXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgbW9kZWxfc3ZzID0gInN2YXNlcSIpCnRjX2RlCnRjX3RhYmxlcyA8LSBjb21iaW5lX2RlX3RhYmxlcyh0Y19kZSwga2VlcGVycyA9IHRjX2tlZXBlcnMsIGV4Y2VsID0gImV4Y2VsL3RjX3RhYmxlcy54bHN4IikKdGNfdGFibGVzCnRjX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKHRjX3RhYmxlcywgZXhjZWwgPSAiZXhjZWwvdGNfc2lnLnhsc3giKQp0Y19zaWcKYGBgCgojIyBEcm9wIHRoZSBsYWJlbHMgYnkgY2hlYXRpbmcKCmBgYHtyfQpyZW1vdmVfZ2VvbSA8LSBmdW5jdGlvbihnZ3Bsb3QyX29iamVjdCwgZ2VvbV90eXBlKSB7CiAgIyBEZWxldGUgbGF5ZXJzIHRoYXQgbWF0Y2ggdGhlIHJlcXVlc3RlZCB0eXBlLgogIGxheWVycyA8LSBsYXBwbHkoZ2dwbG90Ml9vYmplY3QkbGF5ZXJzLCBmdW5jdGlvbih4KSB7CiAgICBpZiAoY2xhc3MoeCRnZW9tKVsxXSA9PSBnZW9tX3R5cGUpIHsKICAgICAgTlVMTAogICAgfSBlbHNlIHsKICAgICAgeAogICAgfQogIH0pCiAgIyBEZWxldGUgdGhlIHVud2FudGVkIGxheWVycy4KICBsYXllcnMgPC0gbGF5ZXJzWyFzYXBwbHkobGF5ZXJzLCBpcy5udWxsKV0KICBnZ3Bsb3QyX29iamVjdCRsYXllcnMgPC0gbGF5ZXJzCiAgZ2dwbG90Ml9vYmplY3QKfQoKc3RhcnRlciA8LSB0Y190YWJsZXMkcGxvdHNbWzJdXSRkZXNlcV92b2xfcGxvdHMKYWZ0ZXIgPC0gcmVtb3ZlX2dlb20oc3RhcnRlciwgIkdlb21UZXh0UmVwZWwiKQphZnRlcgpgYGAKCiMjIEV4dHJhY3QgdHJhbnMtc2lhbGlkYXNlIGFuZCBsb29rCgpJIG91Z2h0IHRvIGJlIGFibGUgdG8gdXNlIG15IHNlbWFudGljIGZpbHRlciB0byBleHRyYWN0IGFueXRoaW5nIHdpdGgKc2lhbGlkYXNlIGFuZC9vciB0cmFucy1zaWFsaWRhc2UgZ3JvdXAgSSBhbmQgbG9vayBkaXJlY3RseSBhdCB0aGUKZXhwcmVzc2lvbiBvZiB0aGVzZSBnZW5lcy4gIE15IGh5cG90aGVzaXMgaXMgdGhhdCBpZiB0aGUgQ1JJU1BSCmV4cGVyaW1lbnQgd29ya2VkIGFzIGludGVuZGVkLCB0aGVzZSBnZW5lcyBzaG91bGQgYWxsIGhhdmUgZGVjcmVhc2VkCmV4cHJlc3Npb24uCgpgYGB7cn0KYWxsX3RzIDwtIHNlbWFudGljX2ZpbHRlcih0Y19yZXBsaWNhdGVkLCBpbnZlcnQgPSBUUlVFLCBzZW1hbnRpYyA9IGMoInRyYW5zLXNpYWxpZGFzZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNlbWFudGljX2NvbHVtbiA9ICJhbm5vdF90cmFuc2NyaXB0X3Byb2R1Y3QiKQphbGxfdHNfbm9ybSA8LSBub3JtYWxpemUoYWxsX3RzLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIikKYWxsX3RzX25vcm1faGVhdCA8LSBwbG90X3NhbXBsZV9oZWF0bWFwKGFsbF90c19ub3JtKQpwcChmaWxlID0gImltYWdlcy9hbGxfdHNfbm9ybV9oaXNhdF9oZWF0bWFwLnBuZyIpCmFsbF90c19ub3JtX2hlYXQKZGV2Lm9mZigpCmFsbF90c19ub3JtX2hlYXQKCmFsbF90c19zYWwgPC0gc2VtYW50aWNfZmlsdGVyKHRjc2FsX3JlcGxpY2F0ZWQsIGludmVydCA9IFRSVUUsIHNlbWFudGljID0gYygidHJhbnMtc2lhbGlkYXNlIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VtYW50aWNfY29sdW1uID0gImFubm90X3RyYW5zY3JpcHRfcHJvZHVjdCIpCmFsbF90c19zYWxfbm9ybSA8LSBub3JtYWxpemUoYWxsX3RzX3NhbCwgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIpCmFsbF90c19zYWxfbm9ybV9oZWF0IDwtIHBsb3Rfc2FtcGxlX2hlYXRtYXAoYWxsX3RzX3NhbF9ub3JtKQpwcChmaWxlID0gImltYWdlcy9hbGxfdHNfbm9ybV9zYWxtb25faGVhdG1hcC5wbmciKQphbGxfdHNfc2FsX25vcm1faGVhdApkZXYub2ZmKCkKYWxsX3RzX3NhbF9ub3JtX2hlYXQKYGBgCgpUaGUgZ3JvdXAtSSBUUyBnZW5lcyBhcmUgbm90IG9idmlvdXMgaW4gdGhpcyBncm91cCwgbGV0IHVzIHlhbmsgdGhlbQpvdXQgZXhwbGljaXRseSBhbmQgc2VlLgoKTm90ZSwgdGhlIGZvbGxvd2luZyBpcyBhIGxpdHRsZSBiaXQgd3JvbmcgaW4gdGhpbmtpbmcgYmVjYXVzZQpzZWFyY2hpbmcgZm9yICdHcm91cCBJJyB3aWxsIHBpY2sgdXAgYWxsIGdlbmVzIGZyb20gR3JvdXAgSSwgSUksIElJSSwKYW5kIElWLiAgVGhlIG5leHQgc3RhbnphIHdpbGwgZXh0cmFjdCBqdXN0IHRoZSBJRHMgb2YgaW50ZXJlc3QuCgpgYGB7cn0KZzFfdHMgPC0gc2VtYW50aWNfZmlsdGVyKGFsbF90cywgaW52ZXJ0ID0gVFJVRSwgc2VtYW50aWMgPSBjKCJHcm91cCBJIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBzZW1hbnRpY19jb2x1bW4gPSAiYW5ub3RfdHJhbnNjcmlwdF9wcm9kdWN0IikKZzFfdHNfc2FsIDwtIHNlbWFudGljX2ZpbHRlcihhbGxfdHNfc2FsLCBpbnZlcnQgPSBUUlVFLCBzZW1hbnRpYyA9IGMoIkdyb3VwIEkiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW1hbnRpY19jb2x1bW4gPSAiYW5ub3RfdHJhbnNjcmlwdF9wcm9kdWN0IikKYGBgCgpUaGVyZSBpcyBhIHByZXR0eSBzaWduaWZpY2FudCBpbmNyZWFzZSBpbiBhIGZldyBBQiBzYW1wbGVzLCBwZXJoYXBzCnRob3NlIGFyZSBpbiB0aGUgbGlzdCBvZiAxOSBzcGVjaWZpYyBnZW5lcz8gIExldCB1cyBmaW5kIG91dC4KCmBgYHtyfQpleHBlY3RlZF90cyA8LSBzdWJzZXRfZ2VuZXMoZzFfdHMsIGlkcyA9IGV4cGVjdGVkX2xvd2VyLCBtZXRob2QgPSAia2VlcCIpCmV4cGVjdGVkX25vcm0gPC0gbm9ybWFsaXplKGV4cGVjdGVkX3RzLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIikKZzFfdHNfaGlzYXRfbm9ybV9oZWF0IDwtIHBsb3Rfc2FtcGxlX2hlYXRtYXAoZXhwZWN0ZWRfbm9ybSkKcHAoZmlsZSA9ICJpbWFnZXMvZzFfdHNfaGlzYXRfbm9ybV9oZWF0LnBuZyIpCmcxX3RzX2hpc2F0X25vcm1faGVhdApkZXYub2ZmKCkKZzFfdHNfaGlzYXRfbm9ybV9oZWF0CgpzYWxfZXhwZWN0ZWQgPC0gcGFzdGUwKGV4cGVjdGVkX2xvd2VyLCAiOm1STkEiKQpleHBlY3RlZF90c19zYWwgPC0gc3Vic2V0X2dlbmVzKGcxX3RzX3NhbCwgaWRzID0gc2FsX2V4cGVjdGVkLCBtZXRob2QgPSAia2VlcCIpCmV4cGVjdGVkX3NhbF9ub3JtIDwtIG5vcm1hbGl6ZShleHBlY3RlZF90c19zYWwsIHRyYW5zZm9ybSA9ICJsb2cyIiwgY29udmVydCA9ICJjcG0iKQpnMV90c19zYWxtb25fbm9ybV9oZWF0IDwtIHBsb3Rfc2FtcGxlX2hlYXRtYXAoZXhwZWN0ZWRfc2FsX25vcm0pCnBwKGZpbGUgPSAiaW1hZ2VzL2cxX3RzX3NhbG1vbl9ub3JtX2hlYXQucG5nIikKZzFfdHNfc2FsbW9uX25vcm1faGVhdApkZXYub2ZmKCkKZzFfdHNfc2FsbW9uX25vcm1faGVhdApgYGAKCiMgVHJ5IHNvbWUgb250b2xvZ3kgc2VhcmNoaW5nIHZpYSBjbHVzdGVyUHJvZmlsZXIKCldlIGNhbm5vdCB1c2UgZ1Byb2ZpbGVyMiB3aXRoIHRoZSBwYXJhc2l0ZSBiZWNhdXNlIGl0IGlzIG5vdCBhCnJlZmVyZW5jZSBzcGVjaWVzOyBidXQgb3RoZXIgb250b2xvZ3kgbWV0aG9kcyBhcmUgbm90IGNvbnN0cmFpbmVkCnRodXMuICBJbiB0aGUgY2FzZSBvZiBjbHVzdGVyUHJvZmlsZXIsIHRoZXJlIGlzIGFub3RoZXIgY29uc3RyYWludCwgSQpkbyBub3QgaGF2ZSBhIHNpbmdsZSBvcmdEQiBvYmplY3Qgd2hpY2ggY29tcHJpc2VzCkVzbWVyL05vbkVzbWVyL1VuYXNzaWduZWQ7IGFzIGEgcmVzdWx0IEkgbXVzdCBhdHRlbXB0IHRoZSBvbnRvbG9neQpzZWFyY2ggb24gdGhlIGhhcGxvdHlwZXMgc2VwYXJhdGVseS4KCmBgYHtyfQprb193dF91cCA8LSB0Y19zaWdbWyJkZXNlcSJdXVtbInVwcyJdXVtbImtvX3ZzX3d0Il1dCmtvX3d0X2Rvd24gPC0gdGNfc2lnW1siZGVzZXEiXV1bWyJkb3ducyJdXVtbImtvX3ZzX3d0Il1dCmtvX3d0X2FsbCA8LSB0Y190YWJsZXNbWyJkYXRhIl1dW1sia29fdnNfd3QiXV0KYWJfa29fdXAgPC0gdGNfc2lnW1siZGVzZXEiXV1bWyJ1cHMiXV1bWyJhYl92c19rbyJdXQphYl9rb19kb3duIDwtIHRjX3NpZ1tbImRlc2VxIl1dW1siZG93bnMiXV1bWyJhYl92c19rbyJdXQphYl9rb19hbGwgPC0gdGNfdGFibGVzW1siZGF0YSJdXVtbImFiX3ZzX2tvIl1dCgp0Y19lc21lcl91cF9jcCA8LSBzaW1wbGVfY2x1c3RlcnByb2ZpbGVyKAogIGtvX3d0X3VwLCBkZV90YWJsZSA9IGtvX3d0X2FsbCwgb3JnZGIgPSBlc21lcl9kYiwgb3JnZGJfdG8gPSAiR0lEIiwKICBvcmdhbmlzbSA9ICJ0Y3J1emkiLCBleGNlbCA9ICJleGNlbC9rb193dF91cF9jcF9lc21lci54bHN4IikKdGNfZXNtZXJfdXBfY3AKcHAoZmlsZSA9ICJpbWFnZXMvdGNfZXNtZXJfdXBfY3BfbWZfZG90cGxvdC5wbmciLAogICBpbWFnZSA9IGVucmljaHBsb3Q6OmRvdHBsb3QodGNfZXNtZXJfdXBfY3AkZ29fZGF0YSRNRl9lbnJpY2gpKQoKdGNfbm9uZXNtZXJfdXBfY3AgPC0gc2ltcGxlX2NsdXN0ZXJwcm9maWxlcigKICBrb193dF91cCwgZGVfdGFibGUgPSBrb193dF9hbGwsIG9yZ2RiID0gbm9uZXNtZXJfZGIsIG9yZ2RiX3RvID0gIkdJRCIsCiAgb3JnYW5pc20gPSAidGNydXppIiwgZXhjZWwgPSAiZXhjZWwva29fd3RfdXBfY3Bfbm9uZXNtZXIueGxzeCIpCgp0Y191bmFzX3VwX2NwIDwtIHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoCiAga29fd3RfdXAsIGRlX3RhYmxlID0ga29fd3RfYWxsLCBvcmdkYiA9IHVuYXNfZGIsIG9yZ2RiX3RvID0gIkdJRCIsCiAgb3JnYW5pc20gPSAidGNydXppIikKdGNfZXNtZXJfdXBfY3AKCgp0Y19lc21lcl9kb3duX2NwIDwtIHNpbXBsZV9jbHVzdGVycHJvZmlsZXIoCiAga29fd3RfZG93biwgZGVfdGFibGUgPSBrb193dF9hbGwsIG9yZ2RiID0gZXNtZXJfZGIsIG9yZ2RiX3RvID0gIkdJRCIsCiAgb3JnYW5pc20gPSAidGNydXppIiwgZXhjZWwgPSAiZXhjZWwva29fd3RfZG93bl9jcF9lc21lci54bHN4IikKCnRjX3VuYXNfZG93bl9jcCA8LSBzaW1wbGVfY2x1c3RlcnByb2ZpbGVyKAogIGtvX3d0X2Rvd24sIGRlX3RhYmxlID0ga29fd3RfYWxsLCBvcmdkYiA9IHVuYXNfZGIsIG9yZ2RiX3RvID0gIkdJRCIsCiAgb3JnYW5pc20gPSAidGNydXppIikKdGNfZXNtZXJfZG93bl9jcAoKbGVuZ3RoX2RiIDwtIGFzLmRhdGEuZnJhbWUocm93RGF0YSh0Y19zZSkpCmxlbmd0aF9kYltbImdpZCJdXSA8LSByb3duYW1lcyhsZW5ndGhfZGIpCmxlbmd0aF9kYiA8LSBsZW5ndGhfZGJbLCBjKCJnaWQiLCAid2lkdGgiKV0KdGNfdXBfZ3MgPC0gc2ltcGxlX2dvc2VxKGtvX3d0X3VwLCBnb19kYiA9IHRjX2dvLCBsZW5ndGhfZGIgPSBsZW5ndGhfZGIsIG1pbl94cmVmID0gMTApCm1mX2VuciA8LSB0Y191cF9nc1tbIm1mX2VucmljaCJdXQptZl9wbG90cyA8LSBwbG90X2VucmljaHJlc3VsdChtZl9lbnIpCm1mX3Bsb3RzW1sidHJlZSJdXQpwcChmaWxlID0gImltYWdlcy9oaWdoZXJfa29fZ29zZXFfbWYucG5nIiwgaW1hZ2UgPSBtZl9wbG90c1tbInRyZWUiXV0sIGhlaWdodCA9IDksIHdpZHRoID0gMTgpCnBwKGZpbGUgPSAiaW1hZ2VzL2hpZ2hlcl9rb19nb3NlcV9tZl9kb3QucG5nIiwgaW1hZ2UgPSBtZl9wbG90c1tbImRvdCJdXSkKYnBfZW5yIDwtIHRjX3VwX2dzW1siYnBfZW5yaWNoIl1dCmJwX3Bsb3RzIDwtIHBsb3RfZW5yaWNocmVzdWx0KGJwX2VucikKYnBfcGxvdHNbWyJkb3QiXV0KYGBgCgpOb3cgY2hlY2sgdGhlIHBvc2l0aW9uIG9mIHRoZSBleHBlY3RlZCBsb3dlciBleHByZXNzaW9uIGdlbmVzIGluIHRoZQpjb250ZXh0IG9mIGFsbCBnZW5lcyBjb21wYXJlZCB0byB3dC4KCmBgYHtyfQptZXNzYWdlKCJQdWxsIHRoZSBrb193dF9hbGwgdGFibGUgYW5kIHNlZSB3aGVyZSBleHBlY3RlZF9sb3dlciBjb21wYXJlcy4iKQpgYGAKCiMgVHJ5IHdpdGhvdXQgcm91bmQgMwoKYGBge3J9CmhzX2R1cGxpY2F0ZSA8LSBzdWJzZXRfc2UoaHNfcmVwbGljYXRlZCwgc3Vic2V0ID0gInJvdW5kIT0ncjMnIikKdGNfZHVwbGljYXRlIDwtIHN1YnNldF9zZSh0Y19yZXBsaWNhdGVkLCBzdWJzZXQgPSAicm91bmQhPSdyMyciKQoKaHNfZHVwX2RlIDwtIGFsbF9wYWlyd2lzZShoc19kdXBsaWNhdGUsIGZpbHRlciA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWxfZnN0cmluZyA9ICJ+IDAgKyBjb25kaXRpb24gKyBiYXRjaCIsIG1vZGVsX3N2cyA9IEZBTFNFKQpoc19kdXBfZGUKaHNfZHVwX3RhYmxlIDwtIGNvbWJpbmVfZGVfdGFibGVzKGhzX2R1cF9kZSwgZXhjZWwgPSBnbHVlKCJleGNlbC9oc19kdXBfZGVfdGFibGUtdnt2ZXJ9Lnhsc3giKSkKaHNfZHVwX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKGhzX2R1cF90YWJsZSwgZXhjZWwgPSBnbHVlKCJleGNlbC9oc19kdXBfZGVfc2lnLXZ7dmVyfS54bHN4IikpCmhzX2R1cF9zaWcKCnRjX2R1cF9kZSA8LSBhbGxfcGFpcndpc2UodGNfZHVwbGljYXRlLCBmaWx0ZXIgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsX2ZzdHJpbmcgPSAifiAwICsgY29uZGl0aW9uIiwgbW9kZWxfc3ZzID0gInN2YXNlcSIpCnRjX2R1cF9kZQp0Y19kdXBfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXModGNfZHVwX2RlLCBleGNlbCA9IGdsdWUoImV4Y2VsL3RjX2R1cF9kZV90YWJsZS12e3Zlcn0ueGxzeCIpKQp0Y19kdXBfdGFibGUKdGNfZHVwX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKHRjX2R1cF90YWJsZSwgZXhjZWwgPSBnbHVlKCJleGNlbC90Y19kdXBfZGVfc2lnLXZ7dmVyfS54bHN4IikpCnRjX2R1cF9zaWcKYGBgCgpJbnZva2UgZ29zZXEvY2x1c3RlcnByb2ZpbGVyIG9uIHRoZXNlIGdlbmVzLgoKYGBge3J9CnRjX2dvc2VxIDwtIGFsbF9nb3NlcSh0Y19kdXBfc2lnLCBnb19kYiA9IHRjX2dvLCBsZW5ndGhfZGIgPSB0Y19sZW5ndGgpCmhzX2dwIDwtIGFsbF9ncHJvZmlsZXIodGNfZHVwX3NpZykKYGBgCgpDaGVjayBleHByZXNzaW9uIG9mIGdlbmVzIGV4cGVjdGVkIHRvIGJlIGxvd2VyCgpgYGB7cn0KZXhwZWN0ZWRfc2UgPC0gc3Vic2V0X3NlKHRjX3NlLCBpZHMgPSBleHBlY3RlZF9sb3dlcikKYGBgCgojIE0xMyB3YXMgdXNlZCB0byBtYXJrIHRoZSBDUklTUFIgUFRDcwoKQSBuaWNlIGRldGFpbCBjYW1lIG91dCB0b2RheSwgdGhlIFBUQ3MgaW50cm9kdWNlZCBieSBDUklTUFIgaW5jbHVkZWQKTTEzOyBJIHVuZm9ydHVuYXRlbHkgZGlkIG5vdCB0aGluayB0byBhc2sgd2hpY2ggcHJpbWVyLCBidXQgSSBzaG91bGQKYmUgYWJsZSB0byBmaWd1cmUgdGhhdCBvdXQgdHJpdmlhbGx5OgoKKiBNMTMgZm9yd2FyZCAtMjA6IEdUQUFBQUNHQUNHR0NDQUdURwoqIE0xMyBmb3J3YXJkIC00MTogR0dUVFRUQ0NDQUdUQ0FDR0FDCiogTTEzIHJldmVyc2UgLTI3OiBHR0FBQUNBR0NUQVRHQUNDQVRHCiogTTEzIHJldmVyc2UgLTQ4OiBBR0NHR0FUQUFDQUFUVFRDQUNBQwoKU3RhcnQgYnkgY2hlY2tpbmcgYW4gYXJiaXRyYXJ5IGtvIHNhbXBsZSwgSSBzaG91bGQgc2VlIGEgYnVuY2ggb2YKcmVhZHMgd2l0aCBhdCBsZWFzdCBvbmUgb2YgdGhlIGFib3ZlLgoKYGBge2Jhc2gsIGV2YWw9RkFMU0V9CmNkIHByZXByb2Nlc3NpbmcvMDZfSGVMYV9LTzdfNjBocGkKeHpncmVwIEdUQUFBQUNHQUNHR0NDQUdURyBvdXRwdXRzLzIwMjUxMDMxdHJpbW9tYXRpYy8wNl9IZUxhX0tPN182MGhwaV8yX1MzX1IxXzAwMS10cmltbWVkLmZhc3RxLnh6IHwgd2MKIyMgTTEzIGZvcndhcmQgLTIwIHZzLiBSMTogMCBoaXRzCnh6Z3JlcCBDQUNUR0dDQ0dUQ0dUVFRUQUMgb3V0cHV0cy8yMDI1MTAzMXRyaW1vbWF0aWMvMDZfSGVMYV9LTzdfNjBocGlfMl9TM19SMV8wMDEtdHJpbW1lZC5mYXN0cS54eiB8IHdjCiMjIE0xMyBmb3J3YXJkIC0yMCBSQyB2cy4gUjE6IDIwIGhpdHMKCnh6Z3JlcCBHVEFBQUFDR0FDR0dDQ0FHVEcgb3V0cHV0cy8yMDI1MTAzMXRyaW1vbWF0aWMvMDZfSGVMYV9LTzdfNjBocGlfMl9TM19SMl8wMDEtdHJpbW1lZC5mYXN0cS54eiB8IHdjCiMjIE0xMyBmb3J3YXJkIC0yMCB2cyBSMjogNzUgaGl0cwp4emdyZXAgQ0FDVEdHQ0NHVENHVFRUVEFDIG91dHB1dHMvMjAyNTEwMzF0cmltb21hdGljLzA2X0hlTGFfS083XzYwaHBpXzJfUzNfUjJfMDAxLXRyaW1tZWQuZmFzdHEueHogfCB3YwojIyBNMTMgZm9yd2FyZCAtMjAgUkMgdnMgUjI6IDAgaGl0cwoKCgp4emdyZXAgR0dUVFRUQ0NDQUdUQ0FDR0FDIG91dHB1dHMvMjAyNTEwMzF0cmltb21hdGljLzA2X0hlTGFfS083XzYwaHBpXzJfUzNfUjFfMDAxLXRyaW1tZWQuZmFzdHEueHogfCB3YwojIyBNMTMgZm9yd2FyZCAtNDEgdnMgUjE6IDExIGhpdHMKeHpncmVwIEdUQ0dUR0FDVEdHR0FBQUFDQyBvdXRwdXRzLzIwMjUxMDMxdHJpbW9tYXRpYy8wNl9IZUxhX0tPN182MGhwaV8yX1MzX1IxXzAwMS10cmltbWVkLmZhc3RxLnh6IHwgd2MKIyMgTTEzIGZvcndhcmQgUkMgLTQxIHZzIFIxOgoKeHpncmVwIEdHVFRUVENDQ0FHVENBQ0dBQyBvdXRwdXRzLzIwMjUxMDMxdHJpbW9tYXRpYy8wNl9IZUxhX0tPN182MGhwaV8yX1MzX1IyXzAwMS10cmltbWVkLmZhc3RxLnh6IHwgd2MKIyMgTTEzIGZvcndhcmQgLTQxIHZzIFIyOiAxMgp4emdyZXAgR1RDR1RHQUNUR0dHQUFBQUNDIG91dHB1dHMvMjAyNTEwMzF0cmltb21hdGljLzA2X0hlTGFfS083XzYwaHBpXzJfUzNfUjJfMDAxLXRyaW1tZWQuZmFzdHEueHogfCB3YwojIyBNMTMgZm9yd2FyZCAtNDEgUkMgdnMgUjI6IDgKCgoKeHpncmVwIEdHQUFBQ0FHQ1RBVEdBQ0NBVEcgb3V0cHV0cy8yMDI1MTAzMXRyaW1vbWF0aWMvMDZfSGVMYV9LTzdfNjBocGlfMl9TM19SMV8wMDEtdHJpbW1lZC5mYXN0cS54eiB8IHdjCiMjICBNMTMgcmV2ZXJzZSAtMjcgdnMgUjE6IDU0Cnh6Z3JlcCBDQVRHR1RDQVRBR0NUR1RUVENDIG91dHB1dHMvMjAyNTEwMzF0cmltb21hdGljLzA2X0hlTGFfS083XzYwaHBpXzJfUzNfUjFfMDAxLXRyaW1tZWQuZmFzdHEueHogfCB3YwojIyBNMTMgcmV2ZXJzZSAtMjcgUkMgdnMgUjE6IDAKCnh6Z3JlcCBHR0FBQUNBR0NUQVRHQUNDQVRHIG91dHB1dHMvMjAyNTEwMzF0cmltb21hdGljLzA2X0hlTGFfS083XzYwaHBpXzJfUzNfUjJfMDAxLXRyaW1tZWQuZmFzdHEueHogfCB3YwojIyAgTTEzIHJldmVyc2UgLTI3IHZzIFIxOiAwCnh6Z3JlcCBDQVRHR1RDQVRBR0NUR1RUVENDIG91dHB1dHMvMjAyNTEwMzF0cmltb21hdGljLzA2X0hlTGFfS083XzYwaHBpXzJfUzNfUjJfMDAxLXRyaW1tZWQuZmFzdHEueHogfCB3YwojIyBNMTMgcmV2ZXJzZSAtMjcgUkMgdnMgUjE6IDEwNAoKCgp4emdyZXAgQUdDR0dBVEFBQ0FBVFRUQ0FDQUMgIG91dHB1dHMvMjAyNTEwMzF0cmltb21hdGljLzA2X0hlTGFfS083XzYwaHBpXzJfUzNfUjFfMDAxLXRyaW1tZWQuZmFzdHEueHogfCB3YwojIyBNMTMgcmV2ZXJzZSAtNDggdnMgUjE6IDI4Ngp4emdyZXAgR1RHVEdBQUFUVEdUVEFUQ0NHQ1QgIG91dHB1dHMvMjAyNTEwMzF0cmltb21hdGljLzA2X0hlTGFfS083XzYwaHBpXzJfUzNfUjFfMDAxLXRyaW1tZWQuZmFzdHEueHogfCB3YwojIyBNMTMgcmV2ZXJzZSAtNDggUkMgdnMgUjE6IDAKCnh6Z3JlcCBBR0NHR0FUQUFDQUFUVFRDQUNBQyAgb3V0cHV0cy8yMDI1MTAzMXRyaW1vbWF0aWMvMDZfSGVMYV9LTzdfNjBocGlfMl9TM19SMl8wMDEtdHJpbW1lZC5mYXN0cS54eiB8IHdjCiMjIE0xMyByZXZlcnNlIC00OCB2cyBSMjogMAp4emdyZXAgR1RHVEdBQUFUVEdUVEFUQ0NHQ1QgIG91dHB1dHMvMjAyNTEwMzF0cmltb21hdGljLzA2X0hlTGFfS083XzYwaHBpXzJfUzNfUjJfMDAxLXRyaW1tZWQuZmFzdHEueHogfCB3YwojIyBNMTMgcmV2ZXJzZSAtNDggUkMgdnMgUjI6IDkwIGhpdHMKYGBgCgpDb2RpZnkgdGhlIGFib3ZlOiBJIHdyb3RlIGEgcXVpY2sgdGFyZ2V0IGluIGN5b2EgdG8gc2VlayBvdXQgdGhlc2UKc2VxdWVuY2VzIGFuZCBleHRyYWN0IHRoZSBvdGhlciByZWFkLCBlLmcuIGlmIFIxIGhhcyBvbmUgb2YgdGhlc2UKc2VxdWVuY2VzLCBpdCB3aWxsIHB1bGwgb3V0IFIyIGFuZCB3cml0ZSBpdCB0byBhIHNlcGFyYXRlIGZhc3RxIGZpbGUuCgpgYGB7YmFzaCwgZXZhbD1GQUxTRX0Kc2VxdWVuY2VzPSJHVEFBQUFDR0FDR0dDQ0FHVEc6R0dUVFRUQ0NDQUdUQ0FDR0FDOkdHQUFBQ0FHQ1RBVEdBQ0NBVEc6QUdDR0dBVEFBQ0FBVFRUQ0FDQUMiCnNhbXBsZXM9JCgvYmluL2xzIC1kIFswLTldKikKZm9yIHMgaW4gJHtzYW1wbGVzfTsgZG8KICAgIHB1c2hkICRzCiAgICBpbnB1dD0kKC9iaW4vbHMgb3V0cHV0cy8qdHJpbW9tYXRpYy8qX1IxKi10cmltbWVkLmZhc3RxLnh6KQogICAgbGlicmFyeT0kKC9iaW4vbHMgb3V0cHV0cy8qdHJpbW9tYXRpYy8qX1IyKi10cmltbWVkLmZhc3RxLnh6KQogICAgY3lvYSAtLW1ldGhvZCBnZXRvdGhlciAtLWlucHV0ICRpbnB1dCAtLWxpYnJhcnkgJGxpYnJhcnkgLS1xdWVyeSAkc2VxdWVuY2VzCiAgICBwb3BkCmRvbmUKYGBgCgpJIHJhbiB0aGUgYWJvdmUgYW5kIHdhcyBwbGVhc2VkIHRvIHNlZSB0aGF0IG9ubHkgdGhlIEtPIGFuZCBBQiBzYW1wbGVzCmNvbnRhaW4gYW55IE0xMyBzZXF1ZW5jZS4gIEkgdGhlbiBkaWQgYSBsaXR0bGUgYXJiaXRyYXJ5IEJMQVNUaW5nIG9mCnRoZSBvdGhlciByZWFkcy4gIFdlaXJkbHksIG1vc3Qgb2YgdGhlIGhpdHMgd2VyZSB0byBHQVBESCwgYnV0IHRoZQpzZWNvbmQgcmVhZCBJIHB1bGxlZCBhbGlnbmVkIHRvIFRjMDAuMTA0NzA1MzUwOTA2NS41MCwgd2hpY2ggaXMgYQpzeW5vbnltIGZvciBUY0NMQi41MDkwNjUuNTAgKH4gODAwLDAwMCBvbiBUY0NocjMyLVApCgpJIHRoZW4gc3RhcnRlZCBzZWFyY2hpbmcgdGhyb3VnaCB0aGUgc2V0IG9mIHJlYWRzIGV4dHJhY3RlZCB0byBzZWUgaWYKSSBjYW4gZmluZCB3aGVyZSB0aGUgTTEzIHNlcXVlbmNlcyBsaXZlLiAgSSBoYXZlIGEgc2NyZWVuc2hvdCBmcm9tIElHVgpzdWdnZXN0aW5nIHRoYXQgbWFueS9tb3N0L2FsbCBvZiB0aGVtIGFyZSBhZGphY2VudCB0byBHQVBESCBvbgpjaHJvbW9zb21lIDMyUC4KCiMgTXVsdGkgZ2VuZSBmYW1pbGllcwoKSSBkZWNpZGVkIHRvIGNoZWNrIGFuZCBzZWUgdGhlIGRlZ3JlZSB0byB3aGljaCB0aGVzZSBnZW5lcyBzaG91bGQobm90KQpiZSBleHBlY3RlZCB0byBtYXAgY2xlYW5seSBkdWUgdG8gYmVpbmcgbWVtYmVycyBvZiBhIHNwcmF3bGluZwptdWx0aS1nZW5lIGZhbWlseS4gIEkgdGhlcmVmb3JlIGV4dHJhY3RlZCBhbGwgZ2VuZXMgYW5ub3RhdGVkIHdpdGgKJ3NpYWxpZGFzZScgYW5kIGZyb20gdGhlbSBleHRyYWN0ZWQgdGhlIGdyb3VwIEkgbWVtYmVycy4gIEluCmltYWdlcy9ncm91cElfc2lhbGlkYXNlX3BoeU1MX3RyZWUuc3ZnIHJlc2lkZXMgdGhlIHJlc3VsdGluZyB0cmVlLgpUaGV5IGFyZSBub3Qgc28gc2ltaWxhciBhcyBJIGZlYXJlZC4KCkxldCB1cyB0YWtlIGEgbW9tZW50IGFuZCBsb29rIGF0IGEga21lciB0cmVlIG9mIHRoZSAxNTI0IGdyb3VweAp0cmFucy1zaWFsaWRhc2UgZ2VuZXMuCgpgYGB7cn0KdHNfa21lcnMgPC0gQ0RTX2ttZXJfZGlzdChkaXJlY3RvcnkgPSAia21lciIpCmBgYAoKIyBPbmx5IFRpc3N1ZSBDdWx0dXJlIFRyeXBvbWFzdGlnb3RlcwoKTGV0IHVzIGFsc28gZG8gYSBxdWljayBjb21wYXJpc29uIG9mIHRoZSB0d28gZ2Vub3R5cGVzIGFtb25nIHRoZQp0aXNzdWUgY3VsdHVyZSB0cnlwb21hc3RpZ290ZSBzYW1wbGVzLgoKYGBge3J9CnRjdF9zZSA8LSBzdWJzZXRfc2UodGNfcmVwbGljYXRlZCwgc3Vic2V0ID0gImNlbGx0eXBlPT0nUGFyYXNpdGUnIikKY29sRGF0YSh0Y3Rfc2UpW1sic2FtcGxlX3JlcGxpY2F0ZSJdXSA8LSBwYXN0ZTAoInNyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3N1Yih4ID0gY29sRGF0YSh0Y3Rfc2UpW1sic2FtcGxlaWRfYmFja3VwIl1dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiXi4qXyhcXGR7MX0pJCIsIHJlcGxhY2VtZW50ID0gIlxcMSIpKQp0Y3Rfc2UgPC0gc2V0X2JhdGNoZXModGN0X3NlLCBmYWN0ID0gInNhbXBsZV9yZXBsaWNhdGUiKQpwbG90X3BjYShub3JtYWxpemUodGN0X3NlLCBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIsIGNvbnZlcnQgPSAiY3BtIiwgbm9ybSA9ICJ0bW0iKSkKdGN0X2RlIDwtIGFsbF9wYWlyd2lzZSh0Y3Rfc2UsIGZpbHRlciA9IFRSVUUsIG1vZGVsX2ZzdHJpbmcgPSAifiAwICsgY29uZGl0aW9uICsgYmF0Y2giKQp0Y3RfdGFibGUgPC0gY29tYmluZV9kZV90YWJsZXModGN0X2RlLCBleGNlbCA9ICJleGNlbC90Y3Rfd3RfdnNfZGVsZXRpb24tdGFibGUueGxzeCIpCnRjdF9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyh0Y3RfdGFibGUsIGV4Y2VsID0gImV4Y2VsL3RjdF93dF92c19kZWxldGlvbi1zaWcueGxzeCIpCmBgYAoKCmBgYHtyIHNhdmVtZSwgZXZhbD1GQUxTRX0KcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSkKbWVzc2FnZShwYXN0ZTAoIlRoaXMgaXMgaHBnbHRvb2xzIGNvbW1pdDogIiwgZ2V0X2dpdF9jb21taXQoKSkpCm1lc3NhZ2UocGFzdGUwKCJTYXZpbmcgdG8gIiwgc2F2ZWZpbGUpKQp0bXAgPC0gc20oc2F2ZW1lKGZpbGVuYW1lID0gc2F2ZWZpbGUpKQpgYGAKCmBgYHtyIGxvYWRtZV9hZnRlciwgZXZhbD1GQUxTRX0KdG1wIDwtIGxvYWRtZShmaWxlbmFtZSA9IHNhdmVmaWxlKQpgYGAK