1 Annotation version: 20180410

2 Leishmania major annotation data

There are a few methods of importing annotation data into R. I will attempt some of them in preparation for loading them into the L.major RNASeq data.

3 AnnotationHub: loading OrgDb

AnnotationHub is a newer service and has promise to be an excellent top-level resource for gathering annotation data.

tmp <- sm(library(AnnotationHub))
ah = sm(AnnotationHub())
orgdbs <- sm(query(ah, "OrgDb"))
lm_orgdb <- sm(query(ah, c("OrgDB", "Leishmania")))
lm_orgdb
## AnnotationHub with 4 records
## # snapshotDate(): 2017-10-27 
## # $dataprovider: ftp://ftp.ncbi.nlm.nih.gov/gene/DATA/
## # $species: Leishmania donovani, Leishmania major_strain_Friedlin, Leis...
## # $rdataclass: OrgDb
## # additional mcols(): taxonomyid, genome, description,
## #   coordinate_1_based, maintainer, rdatadateadded, preparerclass,
## #   tags, rdatapath, sourceurl, sourcetype 
## # retrieve records with, e.g., 'object[["AH59612"]]' 
## 
##             title                                               
##   AH59612 | org.Leishmania_major_strain_Friedlin.eg.sqlite      
##   AH59675 | org.Leishmania_mexicana_MHOM|GT|2001|U1103.eg.sqlite
##   AH59676 | org.Leishmania_donovani.eg.sqlite                   
##   AH59684 | org.Leishmania_panamensis.eg.sqlite
lm_orgdb <- ah[["AH59612"]]
## loading from cache '/home/trey//.AnnotationHub/66358'
## Loading required package: AnnotationDbi
## Loading required package: stats4
## 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 object is masked from 'package:AnnotationHub':
## 
##     cache
## Loading required package: IRanges
## Loading required package: S4Vectors
## 
## Attaching package: 'S4Vectors'
## The following object is masked from 'package:base':
## 
##     expand.grid
lm_orgdb
## OrgDb object:
## | DBSCHEMAVERSION: 2.1
## | DBSCHEMA: NOSCHEMA_DB
## | ORGANISM: Leishmania major_strain_Friedlin
## | SPECIES: Leishmania major_strain_Friedlin
## | CENTRALID: GID
## | Taxonomy ID: 347515
## | Db type: OrgDb
## | Supporting package: AnnotationDbi
## 
## Please see: help('select') for usage information
## Holy crap it worked!
lm_annotv1 <- load_orgdb_annotations(lm_orgdb,
                                     keytype="entrezid",
                                     fields=c("entrezid", "alias", "genename", "refseq", "symbol"))
## Unable to find TYPE in the db, removing it.
## Unable to find TXSTRAND in the db, removing it.
## Unable to find TXSTART in the db, removing it.
## Unable to find TXEND in the db, removing it.
## Extracted all gene ids.
## 'select()' returned 1:many mapping between keys and columns
summary(lm_annotv1)
##             Length Class      Mode
## genes       6      data.frame list
## transcripts 0      -none-     NULL
lm_annotv1 <- lm_annotv1[["genes"]]
head(lm_annotv1)
##             entrezid genename chr              alias         refseq
## X12980396   12980396    ncRNA  20 LMJF_20_snoRNA0211 XR_002460236.1
## X12980396.1 12980396    ncRNA  20 LMJF_20_snoRNA0211 XR_002460237.1
## X12980396.2 12980396    ncRNA  20        LM20Cs1C1.1 XR_002460236.1
## X12980396.3 12980396    ncRNA  20        LM20Cs1C1.1 XR_002460237.1
## X12980397   12980397    ncRNA  20 LMJF_20_snoRNA0220 XR_002460308.1
## X12980397.1 12980397    ncRNA  20 LMJF_20_snoRNA0220 XR_002460309.1
##                   symbol
## X12980396    LM20Cs1C1.1
## X12980396.1  LM20Cs1C1.1
## X12980396.2  LM20Cs1C1.1
## X12980396.3  LM20Cs1C1.1
## X12980397   LM20Cs1C1.10
## X12980397.1 LM20Cs1C1.10

4 Loading from biomart

A completely separate and competing annotation source is biomart.

lm_annotv2 <- sm(load_biomart_annotations(species="lmajor", host="protists.ensembl.org"))$annotation
head(lm_annotv2)
##                        transcriptID       geneID
## LmjF.01.0010.mRNA LmjF.01.0010:mRNA LmjF.01.0010
## LmjF.01.0020.mRNA LmjF.01.0020:mRNA LmjF.01.0020
## LmjF.01.0030.mRNA LmjF.01.0030:mRNA LmjF.01.0030
## LmjF.01.0040.mRNA LmjF.01.0040:mRNA LmjF.01.0040
## LmjF.01.0050.mRNA LmjF.01.0050:mRNA LmjF.01.0050
## LmjF.01.0060.mRNA LmjF.01.0060:mRNA LmjF.01.0060
##                                                                               Description
## LmjF.01.0010.mRNA hypothetical protein, unknown function.[Source:GeneDB;Acc:LmjF.01.0010]
## LmjF.01.0020.mRNA        hypothetical protein, conserved.[Source:GeneDB;Acc:LmjF.01.0020]
## LmjF.01.0030.mRNA            MCAK-like kinesin, putative.[Source:GeneDB;Acc:LmjF.01.0030]
## LmjF.01.0040.mRNA hypothetical protein, unknown function.[Source:GeneDB;Acc:LmjF.01.0040]
## LmjF.01.0050.mRNA                  carboxylase, putative.[Source:GeneDB;Acc:LmjF.01.0050]
## LmjF.01.0060.mRNA        hypothetical protein, conserved.[Source:GeneDB;Acc:LmjF.01.0060]
##                             Type length chromosome strand start   end
## LmjF.01.0010.mRNA protein_coding    999          1     -1  3704  4702
## LmjF.01.0020.mRNA protein_coding   1650          1     -1  5790  7439
## LmjF.01.0030.mRNA protein_coding   2007          1     -1  9061 11067
## LmjF.01.0040.mRNA protein_coding    570          1     -1 12073 12642
## LmjF.01.0050.mRNA protein_coding   1998          1     -1 15025 17022
## LmjF.01.0060.mRNA protein_coding    750          1     -1 18137 18886
lm_ontology <- sm(load_biomart_go("lmajor", host="protists.ensembl.org"))

5 Load from the tritrypdb

The hpgltools package has some improved methods for collecting annotation information directly from the eupathdb webservices api. It does this by first downloading all the available data for a given species and then creating a sqlite orgdb instance from them.

5.1 Example orgdb creation

The creation of orgdbs takes a long time, so here is an example invocation.

testing_major <- make_eupath_organismdbi("major")

Assuming the above packages got created, we may load them and extract the annotation data.

major_names <- get_eupath_pkgnames("major")
## Starting metadata download.
## Finished metadata download.
## Found the following hits: Leishmania major strain Friedlin, Leishmania major strain LV39c5, Leishmania major strain SD 75.1, choosing the first.
major_names$orgdb
## [1] "org.Lmajor.Friedlin.v36.eg.db"
wanted_fields <- c("cds_length", "chromosome", "entrez_gene_id" , "gene_name_or_symbol",
                   "gene_strand", "gid", "go_go_id", "go_go_term_name", "go_ontology",
                   "interpro_description" ,"interpro_e_value", "type_gene_type")
lm_org <- load_orgdb_annotations("org.Lmajor.Friedlin.v36.eg.db", keytype="gid", fields=wanted_fields)$genes
## 
## Unable to find GENENAME, setting it to GENE_NAME_OR_SYMBOL.
## Unable to find TYPE in the db, removing it.
## Unable to find CHR in the db, removing it.
## Unable to find TXSTRAND in the db, removing it.
## Unable to find TXSTART in the db, removing it.
## Unable to find TXEND in the db, removing it.
## Extracted all gene ids.
## 'select()' returned 1:many mapping between keys and columns
knitr::kable(head(lm_org))
gid gene_name_or_symbol cds_length chromosome entrez_gene_id gene_strand go_go_id go_go_term_name go_ontology interpro_description interpro_e_value type_gene_type
LmjF.01.0010 LmjF.01.0010 999.0 1 reverse NA NA NA Protein of unknown function (DUF2946) 7.7e-18 protein coding
LmjF.01.0010.1 LmjF.01.0010 999.0 1 reverse NA NA NA Prokaryotic membrane lipoprotein lipid attachment site profile 5.0 protein coding
LmjF.01.0020 LmjF.01.0020 1650.0 1 reverse NA NA NA Endonuclease/Exonuclease/phosphatase family 1.3e-10 protein coding
LmjF.01.0020.1 LmjF.01.0020 1650.0 1 reverse NA NA NA DNase I-like 7.9e-21 protein coding
LmjF.01.0030 LmjF.01.0030 KIN13-1 2007.0 1 reverse GO:0007018 microtubule-based movement Biological Process Kinesin motor domain 1.2e-94 protein coding
LmjF.01.0030.1 LmjF.01.0030 KIN13-1 2007.0 1 reverse GO:0007018 microtubule-based movement Biological Process Kinesin motor domain profile 43.0 protein coding

6 Read a gff file

In contrast, it is possible to load most annotations of interest directly from the gff files used in the alignments.

## The old way of getting genome/annotation data
lm_gff <- "reference/lmajor.gff.gz"
lm_gff_annotations <- load_gff_annotations(lm_gff, type="gene")
## Trying attempt: rtracklayer::import.gff3(gff, sequenceRegionsAsSeqinfo=TRUE)
## Had a successful gff import with rtracklayer::import.gff3(gff, sequenceRegionsAsSeqinfo=TRUE)
## Returning a df with 24 columns and 9379 rows.
rownames(lm_gff_annotations) <- make.names(lm_gff_annotations$Name, unique=TRUE)
head(lm_gff_annotations)
##              seqnames start   end width strand    source type score phase
## LmjF.01.0010  LmjF.01  3704  4702   999      - TriTrypDB gene    NA    NA
## LmjF.01.0020  LmjF.01  5790  7439  1650      - TriTrypDB gene    NA    NA
## LmjF.01.0030  LmjF.01  9061 11067  2007      - TriTrypDB gene    NA    NA
## LmjF.01.0040  LmjF.01 12073 12642   570      - TriTrypDB gene    NA    NA
## LmjF.01.0050  LmjF.01 15025 17022  1998      - TriTrypDB gene    NA    NA
## LmjF.01.0060  LmjF.01 18137 18886   750      - TriTrypDB gene    NA    NA
##                        ID         Name
## LmjF.01.0010 LmjF.01.0010 LmjF.01.0010
## LmjF.01.0020 LmjF.01.0020 LmjF.01.0020
## LmjF.01.0030 LmjF.01.0030 LmjF.01.0030
## LmjF.01.0040 LmjF.01.0040 LmjF.01.0040
## LmjF.01.0050 LmjF.01.0050 LmjF.01.0050
## LmjF.01.0060 LmjF.01.0060 LmjF.01.0060
##                                         description size       web_id
## LmjF.01.0010 hypothetical+protein,+unknown+function  999 LmjF.01.0010
## LmjF.01.0020        hypothetical+protein,+conserved 1650 LmjF.01.0020
## LmjF.01.0030       Kinesin-13+1,+putative+(KIN13-1) 2007 LmjF.01.0030
## LmjF.01.0040 hypothetical+protein,+unknown+function  570 LmjF.01.0040
## LmjF.01.0050                  carboxylase,+putative 1998 LmjF.01.0050
## LmjF.01.0060        hypothetical+protein,+conserved  750 LmjF.01.0060
##              molecule_type organism_name translation_table topology
## LmjF.01.0010          <NA>          <NA>              <NA>     <NA>
## LmjF.01.0020          <NA>          <NA>              <NA>     <NA>
## LmjF.01.0030          <NA>          <NA>              <NA>     <NA>
## LmjF.01.0040          <NA>          <NA>              <NA>     <NA>
## LmjF.01.0050          <NA>          <NA>              <NA>     <NA>
## LmjF.01.0060          <NA>          <NA>              <NA>     <NA>
##              localization Dbxref    locus_tag
## LmjF.01.0010         <NA>        LmjF.01.0010
## LmjF.01.0020         <NA>        LmjF.01.0020
## LmjF.01.0030         <NA>        LmjF.01.0030
## LmjF.01.0040         <NA>        LmjF.01.0040
## LmjF.01.0050         <NA>        LmjF.01.0050
## LmjF.01.0060         <NA>        LmjF.01.0060
##                                                                                                                          Alias
## LmjF.01.0010                    321438052, 389592307, LmjF1.0010, LmjF01.0010, LmjF.01.0010, LmjF01.0010:pep, LmjF01.0010:mRNA
## LmjF.01.0020                    321438053, 389592309, LmjF1.0020, LmjF01.0020, LmjF.01.0020, LmjF01.0020:pep, LmjF01.0020:mRNA
## LmjF.01.0030 KIN13-1, Kif-13-1, 321438054, 389592311, LmjF1.0030, LmjF01.0030, LmjF.01.0030, LmjF01.0030:pep, LmjF01.0030:mRNA
## LmjF.01.0040                    321438055, 389592313, LmjF1.0040, LmjF01.0040, LmjF.01.0040, LmjF01.0040:pep, LmjF01.0040:mRNA
## LmjF.01.0050                    321438056, 389592315, LmjF1.0050, LmjF01.0050, LmjF.01.0050, LmjF01.0050:pep, LmjF01.0050:mRNA
## LmjF.01.0060                    321438057, 389592317, LmjF1.0060, LmjF01.0060, LmjF.01.0060, LmjF01.0060:pep, LmjF01.0060:mRNA
##              Parent Ontology_term
## LmjF.01.0010                     
## LmjF.01.0020                     
## LmjF.01.0030                     
## LmjF.01.0040                     
## LmjF.01.0050                     
## LmjF.01.0060

7 Putting the pieces together

In the following block we create an expressionset using the sample sheet and the annotations.

Annoyingly, the gff annotations are keyed in a peculiar fashion. Therefore I need to do a little work to merge them.

if (!isTRUE(get0("skip_load"))) {
  pander::pander(sessionInfo())
  message(paste0("This is hpgltools commit: ", get_git_commit()))
  this_save <- paste0(gsub(pattern="\\.Rmd", replace="", x=rmd_file), "-v", ver, ".rda.xz")
  message(paste0("Saving to ", this_save))
  tmp <- sm(saveme(filename=this_save))
}
## If you wish to reproduce this exact build of hpgltools, invoke the following:
## > git clone http://github.com/abelew/hpgltools.git
## > git reset 7de4503f6bb5724c28cce24af5dbee22bb1c0cae
## R> packrat::restore()
## This is hpgltools commit: Thu Apr 12 22:08:53 2018 -0400: 7de4503f6bb5724c28cce24af5dbee22bb1c0cae
## Saving to 01_annotation_lmajor_201804-v20180410.rda.xz
LS0tCnRpdGxlOiAiTC5tYWpvciAyMDE4OiBNb3VzZSBQTU4gaW5mZWN0aW9uIGFubm90YXRpb25zICgyMDE4MDQpLiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogaHRtbF9kb2N1bWVudDoKICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgY29kZV9mb2xkaW5nOiBzaG93CiAgZmlnX2NhcHRpb246IHRydWUKICBmaWdfaGVpZ2h0OiA3CiAgZmlnX3dpZHRoOiA3CiAgaGlnaGxpZ2h0OiBkZWZhdWx0CiAga2VlcF9tZDogZmFsc2UKICBtb2RlOiBzZWxmY29udGFpbmVkCiAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgc2VsZl9jb250YWluZWQ6IHRydWUKICB0aGVtZTogcmVhZGFibGUKICB0b2M6IHRydWUKICB0b2NfZmxvYXQ6CiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZT4KICBib2R5IC5tYWluLWNvbnRhaW5lciB7CiAgICBtYXgtd2lkdGg6IDE2MDBweDsKICB9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQppZiAoIWlzVFJVRShnZXQwKCJza2lwX2xvYWQiKSkpIHsKICBsaWJyYXJ5KGhwZ2x0b29scykKICB0dCA8LSBkZXZ0b29sczo6bG9hZF9hbGwoIn4vaHBnbHRvb2xzIikKICBrbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICB3aWR0aD05MCwKICAgICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCiAga25pdHI6Om9wdHNfY2h1bmskc2V0KGVycm9yPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aD04LAogICAgICAgICAgICAgICAgICAgICAgICBmaWcuaGVpZ2h0PTgsCiAgICAgICAgICAgICAgICAgICAgICAgIGRwaT05NikKICBvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cz00LAogICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIGtuaXRyLmR1cGxpY2F0ZS5sYWJlbD0iYWxsb3ciKQogIGdncGxvdDI6OnRoZW1lX3NldChnZ3Bsb3QyOjp0aGVtZV9idyhiYXNlX3NpemU9MTApKQogIHZlciA8LSAiMjAxODA0MTAiCiAgcHJldmlvdXNfZmlsZSA8LSAiaW5kZXguUm1kIgoKICB0bXAgPC0gdHJ5KHNtKGxvYWRtZShmaWxlbmFtZT1wYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikpKSkKICBybWRfZmlsZSA8LSAiMDFfYW5ub3RhdGlvbl9sbWFqb3JfMjAxODA0LlJtZCIKfQpgYGAKCiMgQW5ub3RhdGlvbiB2ZXJzaW9uOiBgciB2ZXJgCgpMZWlzaG1hbmlhIG1ham9yIGFubm90YXRpb24gZGF0YQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKVGhlcmUgYXJlIGEgZmV3IG1ldGhvZHMgb2YgaW1wb3J0aW5nIGFubm90YXRpb24gZGF0YSBpbnRvIFIuICBJIHdpbGwgYXR0ZW1wdApzb21lIG9mIHRoZW0gaW4gcHJlcGFyYXRpb24gZm9yIGxvYWRpbmcgdGhlbSBpbnRvIHRoZSBMLm1ham9yIFJOQVNlcSBkYXRhLgoKIyBBbm5vdGF0aW9uSHViOiBsb2FkaW5nIE9yZ0RiCgpBbm5vdGF0aW9uSHViIGlzIGEgbmV3ZXIgc2VydmljZSBhbmQgaGFzIHByb21pc2UgdG8gYmUgYW4gZXhjZWxsZW50IHRvcC1sZXZlbCByZXNvdXJjZSBmb3IgZ2F0aGVyaW5nCmFubm90YXRpb24gZGF0YS4KCmBgYHtyIGRhdGFfaW5wdXRfZ2Vub21lfQp0bXAgPC0gc20obGlicmFyeShBbm5vdGF0aW9uSHViKSkKYWggPSBzbShBbm5vdGF0aW9uSHViKCkpCm9yZ2RicyA8LSBzbShxdWVyeShhaCwgIk9yZ0RiIikpCmxtX29yZ2RiIDwtIHNtKHF1ZXJ5KGFoLCBjKCJPcmdEQiIsICJMZWlzaG1hbmlhIikpKQpsbV9vcmdkYgpsbV9vcmdkYiA8LSBhaFtbIkFINTk2MTIiXV0KCmxtX29yZ2RiCiMjIEhvbHkgY3JhcCBpdCB3b3JrZWQhCmxtX2Fubm90djEgPC0gbG9hZF9vcmdkYl9hbm5vdGF0aW9ucyhsbV9vcmdkYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleXR5cGU9ImVudHJlemlkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkcz1jKCJlbnRyZXppZCIsICJhbGlhcyIsICJnZW5lbmFtZSIsICJyZWZzZXEiLCAic3ltYm9sIikpCnN1bW1hcnkobG1fYW5ub3R2MSkKbG1fYW5ub3R2MSA8LSBsbV9hbm5vdHYxW1siZ2VuZXMiXV0KaGVhZChsbV9hbm5vdHYxKQpgYGAKCiMgTG9hZGluZyBmcm9tIGJpb21hcnQKCkEgY29tcGxldGVseSBzZXBhcmF0ZSBhbmQgY29tcGV0aW5nIGFubm90YXRpb24gc291cmNlIGlzIGJpb21hcnQuCgpgYGB7ciBsbWFqb3JfYmlvbWFydH0KbG1fYW5ub3R2MiA8LSBzbShsb2FkX2Jpb21hcnRfYW5ub3RhdGlvbnMoc3BlY2llcz0ibG1ham9yIiwgaG9zdD0icHJvdGlzdHMuZW5zZW1ibC5vcmciKSkkYW5ub3RhdGlvbgpoZWFkKGxtX2Fubm90djIpCmxtX29udG9sb2d5IDwtIHNtKGxvYWRfYmlvbWFydF9nbygibG1ham9yIiwgaG9zdD0icHJvdGlzdHMuZW5zZW1ibC5vcmciKSkKYGBgCgojIExvYWQgZnJvbSB0aGUgdHJpdHJ5cGRiCgpUaGUgaHBnbHRvb2xzIHBhY2thZ2UgaGFzIHNvbWUgaW1wcm92ZWQgbWV0aG9kcyBmb3IgY29sbGVjdGluZyBhbm5vdGF0aW9uCmluZm9ybWF0aW9uIGRpcmVjdGx5IGZyb20gdGhlIGV1cGF0aGRiIHdlYnNlcnZpY2VzIGFwaS4gIEl0IGRvZXMgdGhpcyBieSBmaXJzdApkb3dubG9hZGluZyBhbGwgdGhlIGF2YWlsYWJsZSBkYXRhIGZvciBhIGdpdmVuIHNwZWNpZXMgYW5kIHRoZW4gY3JlYXRpbmcgYQpzcWxpdGUgb3JnZGIgaW5zdGFuY2UgZnJvbSB0aGVtLgoKIyMgRXhhbXBsZSBvcmdkYiBjcmVhdGlvbgoKVGhlIGNyZWF0aW9uIG9mIG9yZ2RicyB0YWtlcyBhIGxvbmcgdGltZSwgc28gaGVyZSBpcyBhbiBleGFtcGxlIGludm9jYXRpb24uCgpgYGB7ciB0cml0cnlwZGIsIGV2YWw9RkFMU0V9CnRlc3RpbmdfbWFqb3IgPC0gbWFrZV9ldXBhdGhfb3JnYW5pc21kYmkoIm1ham9yIikKYGBgCgpBc3N1bWluZyB0aGUgYWJvdmUgcGFja2FnZXMgZ290IGNyZWF0ZWQsIHdlIG1heSBsb2FkIHRoZW0gYW5kIGV4dHJhY3QgdGhlIGFubm90YXRpb24gZGF0YS4KCmBgYHtyIGxtYWpvcl9vcmdkYn0KbWFqb3JfbmFtZXMgPC0gZ2V0X2V1cGF0aF9wa2duYW1lcygibWFqb3IiKQptYWpvcl9uYW1lcyRvcmdkYgoKd2FudGVkX2ZpZWxkcyA8LSBjKCJjZHNfbGVuZ3RoIiwgImNocm9tb3NvbWUiLCAiZW50cmV6X2dlbmVfaWQiICwgImdlbmVfbmFtZV9vcl9zeW1ib2wiLAogICAgICAgICAgICAgICAgICAgImdlbmVfc3RyYW5kIiwgImdpZCIsICJnb19nb19pZCIsICJnb19nb190ZXJtX25hbWUiLCAiZ29fb250b2xvZ3kiLAogICAgICAgICAgICAgICAgICAgImludGVycHJvX2Rlc2NyaXB0aW9uIiAsImludGVycHJvX2VfdmFsdWUiLCAidHlwZV9nZW5lX3R5cGUiKQpsbV9vcmcgPC0gbG9hZF9vcmdkYl9hbm5vdGF0aW9ucygib3JnLkxtYWpvci5GcmllZGxpbi52MzYuZWcuZGIiLCBrZXl0eXBlPSJnaWQiLCBmaWVsZHM9d2FudGVkX2ZpZWxkcykkZ2VuZXMKa25pdHI6OmthYmxlKGhlYWQobG1fb3JnKSkKYGBgCgojIFJlYWQgYSBnZmYgZmlsZQoKSW4gY29udHJhc3QsIGl0IGlzIHBvc3NpYmxlIHRvIGxvYWQgbW9zdCBhbm5vdGF0aW9ucyBvZiBpbnRlcmVzdCBkaXJlY3RseSBmcm9tIHRoZSBnZmYgZmlsZXMgdXNlZCBpbgp0aGUgYWxpZ25tZW50cy4KCmBgYHtyIGdlbm9tZV9pbnB1dH0KIyMgVGhlIG9sZCB3YXkgb2YgZ2V0dGluZyBnZW5vbWUvYW5ub3RhdGlvbiBkYXRhCmxtX2dmZiA8LSAicmVmZXJlbmNlL2xtYWpvci5nZmYuZ3oiCmxtX2dmZl9hbm5vdGF0aW9ucyA8LSBsb2FkX2dmZl9hbm5vdGF0aW9ucyhsbV9nZmYsIHR5cGU9ImdlbmUiKQpyb3duYW1lcyhsbV9nZmZfYW5ub3RhdGlvbnMpIDwtIG1ha2UubmFtZXMobG1fZ2ZmX2Fubm90YXRpb25zJE5hbWUsIHVuaXF1ZT1UUlVFKQpoZWFkKGxtX2dmZl9hbm5vdGF0aW9ucykKYGBgCgojIFB1dHRpbmcgdGhlIHBpZWNlcyB0b2dldGhlcgoKSW4gdGhlIGZvbGxvd2luZyBibG9jayB3ZSBjcmVhdGUgYW4gZXhwcmVzc2lvbnNldCB1c2luZyB0aGUgc2FtcGxlIHNoZWV0IGFuZCB0aGUKYW5ub3RhdGlvbnMuCgpBbm5veWluZ2x5LCB0aGUgZ2ZmIGFubm90YXRpb25zIGFyZSBrZXllZCBpbiBhIHBlY3VsaWFyIGZhc2hpb24uICBUaGVyZWZvcmUgSQpuZWVkIHRvIGRvIGEgbGl0dGxlIHdvcmsgdG8gbWVyZ2UgdGhlbS4KCmBgYHtyIHNhdmVtZX0KaWYgKCFpc1RSVUUoZ2V0MCgic2tpcF9sb2FkIikpKSB7CiAgcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSkKICBtZXNzYWdlKHBhc3RlMCgiVGhpcyBpcyBocGdsdG9vbHMgY29tbWl0OiAiLCBnZXRfZ2l0X2NvbW1pdCgpKSkKICB0aGlzX3NhdmUgPC0gcGFzdGUwKGdzdWIocGF0dGVybj0iXFwuUm1kIiwgcmVwbGFjZT0iIiwgeD1ybWRfZmlsZSksICItdiIsIHZlciwgIi5yZGEueHoiKQogIG1lc3NhZ2UocGFzdGUwKCJTYXZpbmcgdG8gIiwgdGhpc19zYXZlKSkKICB0bXAgPC0gc20oc2F2ZW1lKGZpbGVuYW1lPXRoaXNfc2F2ZSkpCn0KYGBgCg==