Changelog
- 202406: Adding a neat experiment from the Scott lab which I had
sitting in my tree but somehow forgot about.
- 202308: Moved preprocessing material from the datastructures file to
here.
Introduction
This document outlines in some detail the tasks performed in order to
process the ‘raw’ data.
Sequence
preprocessing
All of the preprocessing tasks were performed with CYOA ((ElsayedlabCYOA?)) and included
the following:
- All samples were trimmed with trimomatic
- using options to remove adapters using a supplemented copy of the
default adapter database (ILLUMINACLIP:2:30:10:2:keepBothReads), reads
with fewer than 40 nucleotides remaining were discarded (MINLEN:40), and
a mean quality >= 25 over 4 nucleotide window was used for trimming
(SLIDINGWINDOW:4:25). When paired end reads were available, only the
properly paired were used for the tasks that follow. The generated
scripts for each sample which performed this trimming have the prefix
‘05trim’.
- Reads were passed to fastqc (Andrews
(n.d.)) using the default parameters to query read quality,
remaining adapter content, and as an initial survey for contaminants.
The generated scripts which performed this have the prefix
‘06fastqc’
- Every sample was passed to kraken2 ((luMetagenomeAnalysisUsing2022?))
against its comprehensive ‘standard’ and ‘virus’ databases, updated
2021/06 in order to query for putative contaminants and potentially
interesting viral sequences. The scripts which performed this have the
prefix ‘11kraken’.
- Samples were passed to hisat2 (Kim et al.
(2019)) against the hg38 release 100 human genome ((HomoSapiensEnsembl?)) with the
default options as well as the Leishmania panamensis MHOM/COL release 46
- in serial. The scripts which performed these operations have the
prefixes ‘15hisat2_hg38_100’ and ‘15hisat2_lpanamensis_v46’
respectively.
- The resulting alignments were converted to the binary, sorted,
compressed, and indexed format via samtools ((bonfieldHTSlibLibraryReading2021?)).
Additional filters were performed to extract only the non-variant
alignments . The scripts which performed this have the prefix
‘19s2b_{genome}’.
- These were cross referenced against the relevant feature databases
in order to generate count tables by gene via htseq (Putri et al. (2022)). These scripts have the
prefix ‘21hts’.
- Each sample was passed to salmon (Patro et
al. (2017)) against the transcript databases for hg38 release
100, L. panamensis release 46, and a concatenation of the two. These
scripts have the suffix ‘30sal_{genome}’.
- A regular expression search was performed for the observed set of
spliced leader sequences. The sequence ‘AGTTTCTGTACTTTATTGG’ rather than
the entire SL sequence was searched to avoid potential SL variants. The
relevant scripts have the prefix ‘50slsearch’. I later set up a
fastp-based ((chenFastpUltrafastAllinone2018?))
search, but I do not think it is included.
- When sufficient coverage was observed against the parasite,
freebayes (Garrison and Marth (2012)) was
used to quantify variants vs. the reference genome and infer the most
likely parasite subtype.
(if anyone ever reads this (no one will ever read this), can you tell
me how in the flying hell the fancy single quotes appeared in my text
document? I am writing this in emacs using markdown-mode and when I am
typing I see normal person quotes, but when I save it…. oooohhh I added
a text-mode hook and forgot it, I think?)
Given the fact that these tasks were performed over the course of 4
years, during which time we changed sequencing platforms and
computational infrastructure, the actual prefixes/suffixes of the
various scripts and outputs are not as consistent as I would like.
Trimming raw
reads
With the above caveat in mind, I am copy/pasting the little shell
fragments I used when trimming the samples:
## trim.sh, this assumes one will manually cd into the new sample's directory and run ../tmrc_trim.sh
## In addition, it assumes that the new data files will reside in the directory 'unprocessed/'.
input=$(/bin/ls -d unprocessed | tr '\n' ':' | sed 's/:$//g')
echo "Running trimomatic on ${input}"
cmd="cyoa --method trim --input ${input} 2>>cyoa_trim.out 1>&2 &"
echo "${cmd}" > cyoa_trim.out
${cmd}
The following is a script which is generated by the above,
arbitrarily chosen from sample TMRC30140. If anyone reads it carefully,
one might note that this sample is from before I started depositing new
raw reads into the ‘unprocessed’ directory, as a result the input reads
were in the cwd.
#!/usr/bin/env bash
#SBATCH --export=ALL
#SBATCH --mail-type=NONE
#SBATCH --chdir=/fs/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019/preprocessing/TMRC30140
#SBATCH --partition=dpart
#SBATCH --qos=workstation --nice=10
#SBATCH --nodes=1 --requeue
#SBATCH --time=10:00:00
#SBATCH --job-name=01trim_TMRC30140_S3_R1_001
#SBATCH --mem=40G
#SBATCH --cpus-per-task=3
#SBATCH --output=outputs/logs/trim_TMRC30140_S3_R1_001.sbatchout
echo "## Started /fs/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019/preprocessing/TMRC30140/scripts/01trim_TMRC30140_S3_R1_001.sh at $(date) on $(hostname) with id ${SLURM_JOBID}." >> outputs/log.txt
module add trimomatic
## This call to trimomatic removes illumina and epicentre adapters from TMRC30140_S3_R1_001.fastq.gz:TMRC30140_S3_R2_001.fastq.gz.
## It also performs a sliding window removal of anything with quality <25;
## cutadapt provides an alternative to this tool.
## The original sequence data is recompressed and saved in the sequences/ directory.
mkdir -p outputs/01trimomatic
## Note that trimomatic prints all output and errors to STDERR, so send both to output
trimmomatic PE \
-threads 1 \
-phred33 \
TMRC30140_S3_R1_001.fastq.gz TMRC30140_S3_R2_001.fastq.gz \
TMRC30140_S3_R1_001-trimmed_paired.fastq TMRC30140_S3_R1_001-trimmed_unpaired.fastq \
TMRC30140_S3_R2_001-trimmed_paired.fastq TMRC30140_S3_R2_001-trimmed_unpaired.fastq \
ILLUMINACLIP:/cbcb/sw/RedHat-7-x86_64/common/local/perl/5.34/lib/site_perl/5.34.0/auto/share/dist/Bio-Adventure/genome/adapters.fa:2:20:10:2:keepBothReads \
SLIDINGWINDOW:4:20 MINLEN:40 \
1>outputs/01trimomatic/TMRC30140_S3_R1_001-trimomatic.out 2>&1
excepted=$(grep "Exception" outputs/TMRC30140_S3_R1_001-trimomatic.out)
## The following is in case the illumina clipping fails, which it does if this has already been run I think.
if [[ "${excepted}" != "" ]]; then
trimmomatic PE \
-threads 1 \
-phred33 \
TMRC30140_S3_R1_001.fastq.gz TMRC30140_S3_R2_001.fastq.gz \
TMRC30140_S3_R1_001-trimmed_paired.fastq TMRC30140_S3_R1_001-trimmed_unpaired.fastq \
TMRC30140_S3_R2_001-trimmed_paired.fastq TMRC30140_S3_R2_001-trimmed_unpaired.fastq \
SLIDINGWINDOW:4:25 MINLEN:50\
1>outputs/01trimomatic/TMRC30140_S3_R1_001-trimomatic.out 2>&1
fi
sleep 10
mv TMRC30140_S3_R1_001-trimmed_paired.fastq TMRC30140_S3_R1_001-trimmed.fastq
mv TMRC30140_S3_R2_001-trimmed_paired.fastq TMRC30140_S3_R2_001-trimmed.fastq
## Recompress the unpaired reads, this should not take long.
xz -9e -f TMRC30140_S3_R1_001-trimmed_unpaired.fastq
xz -9e -f TMRC30140_S3_R2_001-trimmed_unpaired.fastq
## Recompress the paired reads.
xz -9e -f TMRC30140_S3_R1_001-trimmed.fastq
xz -9e -f TMRC30140_S3_R2_001-trimmed.fastq
ln -sf TMRC30140_S3_R1_001-trimmed.fastq.xz r1_trimmed.fastq.xz
ln -sf TMRC30140_S3_R2_001-trimmed.fastq.xz r2_trimmed.fastq.xz
## The following lines give status codes and some logging
echo "## Job status: $? " >> outputs/log.txt
echo "## $(hostname) Finished ${SLURM_JOBID} 01trim_TMRC30140_S3_R1_001.sh at $(date), it took $(( SECONDS / 60 )) minutes." >> outputs/log.txt
walltime=$(scontrol show job "${SLURM_JOBID}" | grep RunTime | perl -F'/\s+|=/' -lane '{print $F[2]}')
echo "#### walltime used by ${SLURM_JOBID} was: ${walltime:-null}" >> outputs/log.txt
maxmem=$(sstat --format=MaxVMSize -n "${SLURM_JOBID}.batch")
echo "#### maximum memory used by ${SLURM_JOBID} was: ${maxmem:-null}" >> outputs/log.txt
avecpu=$(sstat --format=AveCPU -n "${SLURM_JOBID}.batch")
echo "#### average cpu used by ${SLURM_JOBID} was: ${avecpu:-null}" >> outputs/log.txt
Mapping the trimmed
reads
There is a similar shell fragment used to map these trimmed reads
against the hg38_100 genome/transcriptome along with the panamensis
genome:
#!/usr/bin/env bash
input=$(/bin/ls *_trimmed.fastq.xz | tr '\n' ':' | sed 's/:$//g')
cyoa --task map --method hisat --species hg38_100 --gff_type gene --gff_tag gene_id \
--input ${input} 2>tmrc3_map.out 1>&2 &
cyoa --task map --method hisat --species lpanamensis_v36 --gff_type gene --gff_tag ID \
--input ${input} 2>>tmrc3_map.out 1>&2 &
cyoa --task map --method salmon --species hg38_100 \
--input ${input} 2>tmrc3_salmon.out 1>&2 &
The following is the resulting mapping script taken arbitrarily from
sample TMRC30205. There are a few aspects of this script which changed
from the beginning to end of the project: the prefix # changed, I added
some logic to check if the requisite software (in this case
hisat2/samtools/htseq) is already in the path, and load it if not. I
also changed the htseq output filenames slightly over time to try to
make certain that they are consistent and that it is easy to identify
the important parameters just from the output filename.
#!/usr/bin/env bash
#SBATCH --chdir=/fs/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019/preprocessing/TMRC30205
#SBATCH --partition=dpart
#SBATCH --qos=workstation --nice=10
#SBATCH --nodes=1 --requeue
#SBATCH --time=10:00:00
#SBATCH --job-name=40hisat2_hg38_100_genome
#SBATCH --mem=48G
#SBATCH --cpus-per-task=4
#SBATCH --output=outputs/logs/hisat2_hg38_100_genome.sbatchout
echo "## Started /fs/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019/preprocessing/TMRC30205/scripts/40hisat2_hg38_100_genome.sh at $(date) on $(hostname) with id ${SLURM_JOBID}." >> outputs/log.txt
module add hisat2 samtools htseq
## This is a hisat2 alignment of -1 <(less /fs/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019/preprocessing/TMRC30205/r1_trimmed.fastq.xz) -2 <(less /fs/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019/preprocessing/TMRC30205/r2_trimmed.fastq.xz) against /cbcbhomes/abelew/libraries/genome/indexes/hg38_100
mkdir -p outputs/40hisat2_hg38_100
sleep 3
hisat2 -x /cbcbhomes/abelew/libraries/genome/indexes/hg38_100 \
-p 4 \
-q -1 <(less /fs/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019/preprocessing/TMRC30205/r1_trimmed.fastq.xz) -2 <(less /fs/cbcb-lab/nelsayed/scratch/atb/rnaseq/lpanamensis_tmrc_2019/preprocessing/TMRC30205/r2_trimmed.fastq.xz) \
--phred33 \
--un-gz outputs/40hisat2_hg38_100/TMRC30205_unaldis_hg38_100_genome.fastq \
--al-gz outputs/40hisat2_hg38_100/TMRC30205_aldis_hg38_100_genome.fastq \
--un-conc-gz outputs/40hisat2_hg38_100/TMRC30205_unalcon_hg38_100_genome.fastq \
--al-conc-gz outputs/40hisat2_hg38_100/TMRC30205_alcon_hg38_100_genome.fastq \
-S outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.sam \
2>outputs/40hisat2_hg38_100/hisat2_hg38_100_genome_TMRC30205.err \
1>outputs/40hisat2_hg38_100/hisat2_hg38_100_genome_TMRC30205.out
## The following lines give status codes and some logging
echo "## Job status: $? " >> outputs/log.txt
echo "## $(hostname) Finished ${SLURM_JOBID} 40hisat2_hg38_100_genome.sh at $(date), it took $(( SECONDS / 60 )) minutes." >> outputs/log.txt
walltime=$(scontrol show job "${SLURM_JOBID}" | grep RunTime | perl -F'/\s+|=/' -lane '{print $F[2]}')
echo "#### walltime used by ${SLURM_JOBID} was: ${walltime:-null}" >> outputs/log.txt
maxmem=$(sstat --format=MaxVMSize -n "${SLURM_JOBID}.batch")
echo "#### maximum memory used by ${SLURM_JOBID} was: ${maxmem:-null}" >> outputs/log.txt
avecpu=$(sstat --format=AveCPU -n "${SLURM_JOBID}.batch")
echo "#### average cpu used by ${SLURM_JOBID} was: ${avecpu:-null}" >> outputs/log.txt
From here on I will remove the suffix of the script. Here is the sam
to bam conversion script which was created by cyoa.
module add samtools bamtools
## Converting the text sam to a compressed, sorted, indexed bamfile.
## Also printing alignment statistics to outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.bam.stats
## This job depended on: 133995
echo "Starting samtools"
if $(test ! -r outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.sam); then
echo "Could not find the samtools input file."
exit 1
fi
samtools view -u -t /cbcbhomes/abelew/libraries/genome/hg38_100.fasta \
-S outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.sam -o outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.bam \
2>outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.bam.err 1>outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.bam.out && \
samtools sort -l 9 outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.bam -o outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-sorted.bam \
2>outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-sorted.err 1>outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-sorted.out && \
rm outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.bam && \
rm outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.sam && \
mv outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-sorted.bam outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.bam && samtools index outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.bam
bamtools stats -in outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.bam 2>outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.bam.stats 1>&2
## The following will fail if this is single-ended.
samtools view -b -f 2 -o outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-paired.bam outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome.bam && samtools index outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-paired.bam
bamtools stats -in outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-paired.bam 2>outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-paired.stats 1>&2
And the counting script for htseq. I changed the output filename for
this step on multiple occasions over the course of sample
collection.
module add htseq
## Counting the number of hits in outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-paired.bam for each feature found in /cbcbhomes/abelew/libraries/genome/hg38_100.gff
## Is this stranded? no. The defaults of htseq are:
## --order=name --idattr=gene_id --minaqual=10 --type=exon --stranded=yes --mode=union
htseq-count \
-q -f bam -s no --type gene --idattr gene_id \
outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-paired.bam \
/cbcbhomes/abelew/libraries/genome/hg38_100.gff \
2>outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-paired_all_hg38_100_sno_gene_gene_id.err \
1>outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-paired_all_hg38_100_sno_gene_gene_id.count && \
xz -f -9e outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-paired_all_hg38_100_sno_gene_gene_id.count 2>outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-paired_all_hg38_100_sno_gene_gene_id.err.xz 1>outputs/40hisat2_hg38_100/TMRC30205_hg38_100_genome-paired_all_hg38_100_sno_gene_gene_id.count.xz
The same cyoa invocation produced a series of scripts to aggressively
compress the (un)mapped reads from hisat2 and print out some summary
statistics of the runs.
Conversely, here is a salmon script which was used for sample
TMRC30124 (without the slurm prefix/suffix):
mkdir -p outputs/salmon_hg38_100 && sleep 3 && \
salmon quant -i /cbcbhomes/abelew/libraries/genome/indexes/hg38_100_salmon_index \
-l A --gcBias --validateMappings \
-r <(less r1_trimmed.fastq.gz) \
-o outputs/salmon_hg38_100 \
2>outputs/salmon_hg38_100/salmon.err 1>outputs/salmon_hg38_100/salmon.out
Preprocessing data from
Dr. Scott’s lab
One potentially obvious comparison I neglected to make was against a
newer data set from the Scott lab. (hmm zotero cannot seem to suck in
the author names!? Did science somehow sanitize the pdf or is zotero
just being a doofus? Nope it is definitely science, I asked zotero to
index a fresh copy I downloaded from pubmed and it worked fine, that
sucks, I kind of wish we would collectively refuse to engage with the
for-profit journals.) ((amorimVariableGeneExpression2019?))
In any event, the bioproject accession for this experiment is:
PRJNA525604 which is handy for me, because cyoa has a target named
‘sradownload’ which will, if it sees a PRJNA, do a little web-scraping,
download the metadata.csv from SRA run finder and then download the data
for every run into separate directories.
I have since started (but not finished) the implementation of a
–iterate target which will do what it says on the tin: iterate over
every directory in a tree and invoke the same pipeline on it; but until
I finish that, bash for loops for everyone!
Here is what I did:
mkdir -p preprocessing/PRJNA525604/
module add cyoa
cd preprocessing/PRJNA525604
start=$(pwd)
cyoa --method sra --input PRJNA525604
## wait a while, I got a coffee! and listened to the first song from Olarfur Arnaulds via Cercle:
## https://www.youtube.com/watch?v=bMCiAKNUpTY
## I then realized my script has an error where it leaves the job log
## for this, it created another preprocessing directory with the log.
## Run the processing pipeling
for i in $(/bin/ls -d SRR*); do
cd $i
cyoa --method prnaseq --species hg38_11 \
--input $(/bin/ls *.fastq.gz | tr '\n' ':')
cd $start
done
## The Process_RNASeq target (prna) handles all the stuff above.
The scott lab followed this work up with an examination of the
interaction between microbial buren of the skin and its connection to
increased unpredictability in clinical outcome as well as increased
inflammation during infection ((fariasamorimMultiomicProfilingCutaneous2023?)).
I completely missed this paper until quite recently (202404); in
addition, as I was finishing my quick first-pass read through, I found
the bioproject accession, and upon reading the metadata at SRA realized
they also followed that work up with another piece of intriguing work
((sacramentoCCR5PromotesMigration2024?)).
So, with that in mind:
ac=PRJNA885131
mkdir -p preprocessing/${ac}
module add cyoa/202404
cd preprocessing/${ac}
start=$(pwd)
cyoa --method sra --input $ac
ac=PRJNA682985
mkdir -p preprocessing/${ac}
cd preprocessing/${ac}
start=$(pwd)
cyoa --method sra --input $ac
for i in $(/bin/ls -d SRR*); do
cd $i
cyoa --method prnaseq --species hg38_11 \
--input $(/bin/ls *.fastq.gz | tr '\n' ':')
cd $start
done
## Note, I only asked it to do hg38 for now, but I could/should change it to
## hg38_11:lbraziliensis_2904_v46:saureus_8325
## once I verify those are the appropriate genomes -- and I should
## probably grab fresh copies, I haven't updated them in a while.
Oh yeah, my Staphylococcus assembly is stupidly old, I cannot even
tell where I downloaded it (oh, I checked the fasta file, it is current,
I just manually downloaded everything like a doofus and it is hard to
tell the version) I am just going to redownload it via cyoa so I have
the full accession on hand:
cd ~/libraries/genome/genbank
cyoa --method ncbidownload --input GCF_000013425
## --download downloads whatever ncbi accession I feed it, maybe I
## should change that to something like --ncbidown (I did!) and make one for
## ensembl and microbesonline and friends. Thing is, I like having an
## archive of the gbk file so I can later extract stuff, ensembl/etc
## do not give me that, so it is often easier to just download
## manually, but then again, if I add it to cyoa I do not have to
## scroll around and accidently download some rando chromosome instead
## of the full assembly; and I can add a year or release ID and have
## it go to the appropriate archive server. yeah, I like that.
## maybe I should change --input to --accession for stuff like this?
ls -ltr
ln -s GCF_000013425.gbff saureus_8325.gbk
cyoa --method gb2gff --input saureus_8325.gbk
ls -ltr
mv saureus_8325.fsa ../fasta/
mv saureus_8325_all.gff ../gff/saureus_8325.gff
mv saureus_8325.faa ../../amino_acid/
mv saureus_8325.ffn ../../CDS/fasta/
mv saureus_8325_cds.gff ../../CDS/fasta/saureus_8325.gff
mv saureus_8325_interCDS.gff ../../interCDS/gff/saureus_8325.gff
mv saureus_8325_rrna.gff ../../rRNA/gff/saureus_8325.gff
mv saureus_8325_rrna.fasta ../../rRNA/fasta/saureus_8325.gasta
cd ../fasta
cyoa --method indexhisat --species saureus_8325 \
--input saureus_8325.fsa \
--genome saureus_8325
My favorite part of the above: I can provide the csv downloaded from
SRA to my hpgltools::gather_preprocessing_metadata() function along with
the root directory of the downloaded data (preprocessing/$ac) and it
will suck up all the numbers for me automagically, so I do not have to
worry any more about collecting mapping statistics and potentially
messing them up. One caveat: the rRNA collector still sometimes grabs
genomic numbers because I forgot to add the genome variable somewhere in
the last version… Nonetheless, I think that is awesome (I even made it
smrt enough to handle a colon separated list of species). Oh, this
reminds me, I should check that my S. aureus and braziliensis assemblies
are the same as the ones they used.
Bibliography
Andrews, Simon. n.d. “FastQC: A Quality Control
Tool for High Throughput Sequence Data.”
Garrison, Erik, and Gabor Marth. 2012.
“Haplotype-Based Variant
Detection from Short-Read Sequencing.” arXiv.
https://doi.org/10.48550/arXiv.1207.3907.
Kim, Daehwan, Joseph M. Paggi, Chanhee Park, Christopher Bennett, and
Steven L. Salzberg. 2019.
“Graph-Based Genome Alignment and
Genotyping with Hisat2 and HISAT-genotype.” Nature
Biotechnology 37 (8): 907–15.
https://doi.org/10.1038/s41587-019-0201-4.
Patro, Rob, Geet Duggal, Michael I. Love, Rafael A. Irizarry, and Carl
Kingsford. 2017.
“Salmon Provides Fast and Bias-Aware
Quantification of Transcript Expression.” Nature Methods
14 (4): 417–19.
https://doi.org/10.1038/nmeth.4197.
Putri, Givanna H, Simon Anders, Paul Theodor Pyl, John E Pimanda, and
Fabio Zanini. 2022.
“Analysing High-Throughput Sequencing Data in
Python with HTSeq 2.0.”
Bioinformatics 38 (10): 2943–45.
https://doi.org/10.1093/bioinformatics/btac166.
LS0tCnRpdGxlOiAiVE1SQzMgMjAyMzA4OiBDcmVhdGluZyBEYXRhIFN0cnVjdHVyZXMiCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCmJpYmxpb2dyYXBoeTogYXRiLmJpYgpvdXRwdXQ6CiBodG1sX2RvY3VtZW50OgogIGNvZGVfZG93bmxvYWQ6IHRydWUKICBjb2RlX2ZvbGRpbmc6IHNob3cKICBmaWdfY2FwdGlvbjogdHJ1ZQogIGZpZ19oZWlnaHQ6IDcKICBmaWdfd2lkdGg6IDcKICBoaWdobGlnaHQ6IGRlZmF1bHQKICBrZWVwX21kOiBmYWxzZQogIG1vZGU6IHNlbGZjb250YWluZWQKICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogIHRoZW1lOiByZWFkYWJsZQogIHRvYzogdHJ1ZQogIHRvY19mbG9hdDoKICAgY29sbGFwc2VkOiBmYWxzZQogICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCjxzdHlsZT4KICBib2R5IC5tYWluLWNvbnRhaW5lciB7CiAgICBtYXgtd2lkdGg6IDE2MDBweDsKICB9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGhwZ2x0b29scykKbGlicmFyeShkcGx5cikKbGlicmFyeShmb3JjYXRzKQpsaWJyYXJ5KGdsdWUpCmxpYnJhcnkoRXVQYXRoREIpCgp0dCA8LSB0cnkoZGV2dG9vbHM6OmxvYWRfYWxsKCJ+L2hwZ2x0b29scyIpKQprbml0cjo6b3B0c19rbml0JHNldCgKICBwcm9ncmVzcyA9IFRSVUUsIHZlcmJvc2UgPSBUUlVFLCB3aWR0aCA9IDkwLCBlY2hvID0gVFJVRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVycm9yID0gVFJVRSwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDgsIGZpZy5yZXRpbmEgPSAyLAogIGZpZy5wb3MgPSAidCIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiLCBkcGkgPSBpZiAoa25pdHI6OmlzX2xhdGV4X291dHB1dCgpKSA3MiBlbHNlIDMwMCwKICBvdXQud2lkdGggPSAiMTAwJSIsIGRldiA9ICJzdmciLAogIGRldi5hcmdzID0gbGlzdChwbmcgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpKQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKAogIGRpZ2l0cyA9IDQsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwga25pdHIuZHVwbGljYXRlLmxhYmVsID0gImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDEyKSkKdmVyIDwtIFN5cy5nZXRlbnYoIlZFUlNJT04iKQpwcmV2aW91c19maWxlIDwtICIiCnJ1bmRhdGUgPC0gZm9ybWF0KFN5cy5EYXRlKCksIGZvcm1hdCA9ICIlWSVtJWQiKQoKIyN0bXAgPC0gdHJ5KHNtKGxvYWRtZShmaWxlbmFtZT1nc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IlxcLnJkYVxcLnh6IiwgeD1wcmV2aW91c19maWxlKSkpKQpybWRfZmlsZSA8LSBnbHVlKCJ0bXJjM19kYXRhc2V0c197dmVyfS5SbWQiKQpzYXZlZmlsZSA8LSBnc3ViKHBhdHRlcm4gPSAiXFwuUm1kIiwgcmVwbGFjZSA9ICJcXC5yZGFcXC54eiIsIHggPSBybWRfZmlsZSkKZGF0YV9zdHJ1Y3R1cmVzIDwtIGMoKQpgYGAKCiMgQ2hhbmdlbG9nCgoqIDIwMjQwNjogQWRkaW5nIGEgbmVhdCBleHBlcmltZW50IGZyb20gdGhlIFNjb3R0IGxhYiB3aGljaCBJIGhhZAogIHNpdHRpbmcgaW4gbXkgdHJlZSBidXQgc29tZWhvdyBmb3Jnb3QgYWJvdXQuCiogMjAyMzA4OiBNb3ZlZCBwcmVwcm9jZXNzaW5nIG1hdGVyaWFsIGZyb20gdGhlIGRhdGFzdHJ1Y3R1cmVzIGZpbGUgdG8gaGVyZS4KCiMgSW50cm9kdWN0aW9uCgpUaGlzIGRvY3VtZW50IG91dGxpbmVzIGluIHNvbWUgZGV0YWlsIHRoZSB0YXNrcyBwZXJmb3JtZWQgaW4gb3JkZXIgdG8KcHJvY2VzcyB0aGUgJ3JhdycgZGF0YS4KCiMgU2VxdWVuY2UgcHJlcHJvY2Vzc2luZwoKQWxsIG9mIHRoZSBwcmVwcm9jZXNzaW5nIHRhc2tzIHdlcmUgcGVyZm9ybWVkIHdpdGggQ1lPQSAoQEVsc2F5ZWRsYWJDWU9BKSBhbmQgaW5jbHVkZWQKdGhlIGZvbGxvd2luZzoKCjEuIEFsbCBzYW1wbGVzIHdlcmUgdHJpbW1lZCB3aXRoIHRyaW1vbWF0aWMKICAgKEBib2xnZXJUcmltbW9tYXRpY0ZsZXhpYmxlVHJpbW1lcjIwMTRhKSB1c2luZyBvcHRpb25zIHRvIHJlbW92ZQogICBhZGFwdGVycyB1c2luZyBhIHN1cHBsZW1lbnRlZCBjb3B5IG9mIHRoZSBkZWZhdWx0IGFkYXB0ZXIgZGF0YWJhc2UKICAgKElMTFVNSU5BQ0xJUDoyOjMwOjEwOjI6a2VlcEJvdGhSZWFkcyksIHJlYWRzIHdpdGggZmV3ZXIgdGhhbiA0MAogICBudWNsZW90aWRlcyByZW1haW5pbmcgd2VyZSBkaXNjYXJkZWQgKE1JTkxFTjo0MCksIGFuZCBhIG1lYW4gcXVhbGl0eQogICA+PSAyNSBvdmVyIDQgbnVjbGVvdGlkZSB3aW5kb3cgd2FzIHVzZWQgZm9yIHRyaW1taW5nCiAgIChTTElESU5HV0lORE9XOjQ6MjUpLiAgV2hlbiBwYWlyZWQgZW5kIHJlYWRzIHdlcmUgYXZhaWxhYmxlLCBvbmx5IHRoZQogICBwcm9wZXJseSBwYWlyZWQgd2VyZSB1c2VkIGZvciB0aGUgdGFza3MgdGhhdCBmb2xsb3cuICBUaGUgZ2VuZXJhdGVkCiAgIHNjcmlwdHMgZm9yIGVhY2ggc2FtcGxlIHdoaWNoIHBlcmZvcm1lZCB0aGlzIHRyaW1taW5nIGhhdmUgdGhlIHByZWZpeAogICDigJgwNXRyaW3igJkuCjIuIFJlYWRzIHdlcmUgcGFzc2VkIHRvIGZhc3RxYyAoQGFuZHJld3NGYXN0UUNRdWFsaXR5Q29udHJvbCkgdXNpbmcKICAgdGhlIGRlZmF1bHQgcGFyYW1ldGVycyB0byBxdWVyeSByZWFkIHF1YWxpdHksIHJlbWFpbmluZyBhZGFwdGVyCiAgIGNvbnRlbnQsIGFuZCBhcyBhbiBpbml0aWFsIHN1cnZleSBmb3IgY29udGFtaW5hbnRzLiAgVGhlIGdlbmVyYXRlZAogICBzY3JpcHRzIHdoaWNoIHBlcmZvcm1lZCB0aGlzIGhhdmUgdGhlIHByZWZpeCDigJgwNmZhc3RxY+KAmQozLiBFdmVyeSBzYW1wbGUgd2FzIHBhc3NlZCB0byBrcmFrZW4yIChAbHVNZXRhZ2Vub21lQW5hbHlzaXNVc2luZzIwMjIpCiAgIGFnYWluc3QgaXRzIGNvbXByZWhlbnNpdmUg4oCYc3RhbmRhcmTigJkgYW5kIOKAmHZpcnVz4oCZIGRhdGFiYXNlcywgdXBkYXRlZAogICAyMDIxLzA2IGluIG9yZGVyIHRvIHF1ZXJ5IGZvciBwdXRhdGl2ZSBjb250YW1pbmFudHMgYW5kIHBvdGVudGlhbGx5CiAgIGludGVyZXN0aW5nIHZpcmFsIHNlcXVlbmNlcy4gIFRoZSBzY3JpcHRzIHdoaWNoIHBlcmZvcm1lZCB0aGlzIGhhdmUKICAgdGhlIHByZWZpeCDigJgxMWtyYWtlbuKAmS4KNC4gU2FtcGxlcyB3ZXJlIHBhc3NlZCB0byBoaXNhdDIgKEBraW1HcmFwaGJhc2VkR2Vub21lQWxpZ25tZW50MjAxOSkKICAgYWdhaW5zdCB0aGUgaGczOCByZWxlYXNlIDEwMCBodW1hbiBnZW5vbWUgKEBIb21vU2FwaWVuc0Vuc2VtYmwpCiAgIHdpdGggdGhlIGRlZmF1bHQgb3B0aW9ucyBhcyB3ZWxsIGFzIHRoZSBMZWlzaG1hbmlhIHBhbmFtZW5zaXMKICAgTUhPTS9DT0wgcmVsZWFzZSA0NgogICAoQHNoYW5tdWdhc3VuZHJhbVRyaVRyeXBEQkludGVncmF0ZWRGdW5jdGlvbmFsMjAyMykgaW4gc2VyaWFsLiBUaGUKICAgc2NyaXB0cyB3aGljaCBwZXJmb3JtZWQgdGhlc2Ugb3BlcmF0aW9ucyBoYXZlIHRoZSBwcmVmaXhlcwogICDigJgxNWhpc2F0Ml9oZzM4XzEwMOKAmSBhbmQg4oCYMTVoaXNhdDJfbHBhbmFtZW5zaXNfdjQ24oCZIHJlc3BlY3RpdmVseS4KNS4gVGhlIHJlc3VsdGluZyBhbGlnbm1lbnRzIHdlcmUgY29udmVydGVkIHRvIHRoZSBiaW5hcnksIHNvcnRlZCwKICAgY29tcHJlc3NlZCwgYW5kIGluZGV4ZWQgZm9ybWF0IHZpYSBzYW10b29scwogICAoQGJvbmZpZWxkSFRTbGliTGlicmFyeVJlYWRpbmcyMDIxKS4gIEFkZGl0aW9uYWwgZmlsdGVycyB3ZXJlCiAgIHBlcmZvcm1lZCB0byBleHRyYWN0IG9ubHkgdGhlIG5vbi12YXJpYW50IGFsaWdubWVudHMgLiAgVGhlIHNjcmlwdHMKICAgd2hpY2ggcGVyZm9ybWVkIHRoaXMgaGF2ZSB0aGUgcHJlZml4IOKAmDE5czJiX3tnZW5vbWV94oCZLgo2LiBUaGVzZSB3ZXJlIGNyb3NzIHJlZmVyZW5jZWQgYWdhaW5zdCB0aGUgcmVsZXZhbnQgZmVhdHVyZSBkYXRhYmFzZXMgaW4KICAgb3JkZXIgdG8gZ2VuZXJhdGUgY291bnQgdGFibGVzIGJ5IGdlbmUgdmlhIGh0c2VxCiAgIChAcHV0cmlBbmFseXNpbmdIaWdodGhyb3VnaHB1dFNlcXVlbmNpbmcyMDIyKS4gIFRoZXNlIHNjcmlwdHMgaGF2ZQogICB0aGUgcHJlZml4IOKAmDIxaHRz4oCZLgo3LiBFYWNoIHNhbXBsZSB3YXMgcGFzc2VkIHRvIHNhbG1vbiAoQHBhdHJvU2FsbW9uUHJvdmlkZXNGYXN0MjAxNykKICAgYWdhaW5zdCB0aGUgdHJhbnNjcmlwdCBkYXRhYmFzZXMgZm9yIGhnMzggcmVsZWFzZSAxMDAsCiAgIEwuIHBhbmFtZW5zaXMgcmVsZWFzZSA0NiwgYW5kIGEgY29uY2F0ZW5hdGlvbiBvZiB0aGUgdHdvLiAgVGhlc2UKICAgc2NyaXB0cyBoYXZlIHRoZSBzdWZmaXgg4oCYMzBzYWxfe2dlbm9tZX3igJkuCjguIEEgcmVndWxhciBleHByZXNzaW9uIHNlYXJjaCB3YXMgcGVyZm9ybWVkIGZvciB0aGUgb2JzZXJ2ZWQgc2V0IG9mCiAgIHNwbGljZWQgbGVhZGVyIHNlcXVlbmNlcy4gIFRoZSBzZXF1ZW5jZSDigJhBR1RUVENUR1RBQ1RUVEFUVEdH4oCZIHJhdGhlcgogICB0aGFuIHRoZSBlbnRpcmUgU0wgc2VxdWVuY2Ugd2FzIHNlYXJjaGVkIHRvIGF2b2lkIHBvdGVudGlhbCBTTAogICB2YXJpYW50cy4gIFRoZSByZWxldmFudCBzY3JpcHRzIGhhdmUgdGhlIHByZWZpeCDigJg1MHNsc2VhcmNo4oCZLiAgSQogICBsYXRlciBzZXQgdXAgYSBmYXN0cC1iYXNlZCAoQGNoZW5GYXN0cFVsdHJhZmFzdEFsbGlub25lMjAxOCkKICAgc2VhcmNoLCBidXQgSSBkbyBub3QgdGhpbmsgaXQgaXMgaW5jbHVkZWQuCjkuIFdoZW4gc3VmZmljaWVudCBjb3ZlcmFnZSB3YXMgb2JzZXJ2ZWQgYWdhaW5zdCB0aGUgcGFyYXNpdGUsCiAgIGZyZWViYXllcyAoQGdhcnJpc29uSGFwbG90eXBlYmFzZWRWYXJpYW50RGV0ZWN0aW9uMjAxMikgd2FzIHVzZWQgdG8KICAgcXVhbnRpZnkgdmFyaWFudHMgdnMuIHRoZSByZWZlcmVuY2UgZ2Vub21lIGFuZCBpbmZlciB0aGUgbW9zdAogICBsaWtlbHkgcGFyYXNpdGUgc3VidHlwZS4KCihpZiBhbnlvbmUgZXZlciByZWFkcyB0aGlzIChubyBvbmUgd2lsbCBldmVyIHJlYWQgdGhpcyksIGNhbiB5b3UgdGVsbAptZSBob3cgaW4gdGhlIGZseWluZyBoZWxsIHRoZSBmYW5jeSBzaW5nbGUgcXVvdGVzIGFwcGVhcmVkIGluIG15IHRleHQKZG9jdW1lbnQ/ICBJIGFtIHdyaXRpbmcgdGhpcyBpbiBlbWFjcyB1c2luZyBtYXJrZG93bi1tb2RlIGFuZCB3aGVuIEkKYW0gdHlwaW5nIEkgc2VlIG5vcm1hbCBwZXJzb24gcXVvdGVzLCBidXQgd2hlbiBJIHNhdmUgaXQuLi4uIG9vb29oaGggSQphZGRlZCBhIHRleHQtbW9kZSBob29rIGFuZCBmb3Jnb3QgaXQsIEkgdGhpbms/KQoKR2l2ZW4gdGhlIGZhY3QgdGhhdCB0aGVzZSB0YXNrcyB3ZXJlIHBlcmZvcm1lZCBvdmVyIHRoZSBjb3Vyc2Ugb2YgNAp5ZWFycywgZHVyaW5nIHdoaWNoIHRpbWUgd2UgY2hhbmdlZCBzZXF1ZW5jaW5nIHBsYXRmb3JtcyBhbmQKY29tcHV0YXRpb25hbCBpbmZyYXN0cnVjdHVyZSwgdGhlIGFjdHVhbCBwcmVmaXhlcy9zdWZmaXhlcyBvZiB0aGUKdmFyaW91cyBzY3JpcHRzIGFuZCBvdXRwdXRzIGFyZSBub3QgYXMgY29uc2lzdGVudCBhcyBJIHdvdWxkIGxpa2UuCgojIyMgVHJpbW1pbmcgcmF3IHJlYWRzCgpXaXRoIHRoZSBhYm92ZSBjYXZlYXQgaW4gbWluZCwgSSBhbSBjb3B5L3Bhc3RpbmcgdGhlIGxpdHRsZSBzaGVsbCBmcmFnbWVudHMgSQp1c2VkIHdoZW4gdHJpbW1pbmcgdGhlIHNhbXBsZXM6CgpgYGB7YmFzaCBwcmVwcm9jZXNzX2ZyYWdtZW50LCBldmFsPUZBTFNFfQojIyB0cmltLnNoLCB0aGlzIGFzc3VtZXMgb25lIHdpbGwgbWFudWFsbHkgY2QgaW50byB0aGUgbmV3IHNhbXBsZSdzIGRpcmVjdG9yeSBhbmQgcnVuIC4uL3RtcmNfdHJpbS5zaAojIyBJbiBhZGRpdGlvbiwgaXQgYXNzdW1lcyB0aGF0IHRoZSBuZXcgZGF0YSBmaWxlcyB3aWxsIHJlc2lkZSBpbiB0aGUgZGlyZWN0b3J5ICd1bnByb2Nlc3NlZC8nLgppbnB1dD0kKC9iaW4vbHMgLWQgdW5wcm9jZXNzZWQgfCB0ciAnXG4nICc6JyB8IHNlZCAncy86JC8vZycpCmVjaG8gIlJ1bm5pbmcgdHJpbW9tYXRpYyBvbiAke2lucHV0fSIKY21kPSJjeW9hIC0tbWV0aG9kIHRyaW0gLS1pbnB1dCAke2lucHV0fSAyPj5jeW9hX3RyaW0ub3V0IDE+JjIgJiIKZWNobyAiJHtjbWR9IiA+IGN5b2FfdHJpbS5vdXQKJHtjbWR9CmBgYAoKVGhlIGZvbGxvd2luZyBpcyBhIHNjcmlwdCB3aGljaCBpcyBnZW5lcmF0ZWQgYnkgdGhlIGFib3ZlLCBhcmJpdHJhcmlseQpjaG9zZW4gZnJvbSBzYW1wbGUgVE1SQzMwMTQwLiAgSWYgYW55b25lIHJlYWRzIGl0IGNhcmVmdWxseSwgb25lIG1pZ2h0Cm5vdGUgdGhhdCB0aGlzIHNhbXBsZSBpcyBmcm9tIGJlZm9yZSBJIHN0YXJ0ZWQgZGVwb3NpdGluZyBuZXcgcmF3CnJlYWRzIGludG8gdGhlICd1bnByb2Nlc3NlZCcgZGlyZWN0b3J5LCBhcyBhIHJlc3VsdCB0aGUgaW5wdXQgcmVhZHMKd2VyZSBpbiB0aGUgY3dkLgoKYGBge2Jhc2ggdHJpbV9zZXF1ZW5jZV9zY3JpcHQsIGV2YWw9RkFMU0V9CiMhL3Vzci9iaW4vZW52IGJhc2gKI1NCQVRDSCAtLWV4cG9ydD1BTEwKI1NCQVRDSCAtLW1haWwtdHlwZT1OT05FCiNTQkFUQ0ggLS1jaGRpcj0vZnMvY2JjYi1sYWIvbmVsc2F5ZWQvc2NyYXRjaC9hdGIvcm5hc2VxL2xwYW5hbWVuc2lzX3RtcmNfMjAxOS9wcmVwcm9jZXNzaW5nL1RNUkMzMDE0MAojU0JBVENIIC0tcGFydGl0aW9uPWRwYXJ0CiNTQkFUQ0ggLS1xb3M9d29ya3N0YXRpb24gLS1uaWNlPTEwCiNTQkFUQ0ggLS1ub2Rlcz0xIC0tcmVxdWV1ZQojU0JBVENIIC0tdGltZT0xMDowMDowMAojU0JBVENIIC0tam9iLW5hbWU9MDF0cmltX1RNUkMzMDE0MF9TM19SMV8wMDEKI1NCQVRDSCAtLW1lbT00MEcKI1NCQVRDSCAtLWNwdXMtcGVyLXRhc2s9MwojU0JBVENIIC0tb3V0cHV0PW91dHB1dHMvbG9ncy90cmltX1RNUkMzMDE0MF9TM19SMV8wMDEuc2JhdGNob3V0CgplY2hvICIjIyBTdGFydGVkIC9mcy9jYmNiLWxhYi9uZWxzYXllZC9zY3JhdGNoL2F0Yi9ybmFzZXEvbHBhbmFtZW5zaXNfdG1yY18yMDE5L3ByZXByb2Nlc3NpbmcvVE1SQzMwMTQwL3NjcmlwdHMvMDF0cmltX1RNUkMzMDE0MF9TM19SMV8wMDEuc2ggYXQgJChkYXRlKSBvbiAkKGhvc3RuYW1lKSB3aXRoIGlkICR7U0xVUk1fSk9CSUR9LiIgPj4gb3V0cHV0cy9sb2cudHh0Cgptb2R1bGUgYWRkIHRyaW1vbWF0aWMKCiMjIFRoaXMgY2FsbCB0byB0cmltb21hdGljIHJlbW92ZXMgaWxsdW1pbmEgYW5kIGVwaWNlbnRyZSBhZGFwdGVycyBmcm9tIFRNUkMzMDE0MF9TM19SMV8wMDEuZmFzdHEuZ3o6VE1SQzMwMTQwX1MzX1IyXzAwMS5mYXN0cS5nei4KIyMgSXQgYWxzbyBwZXJmb3JtcyBhIHNsaWRpbmcgd2luZG93IHJlbW92YWwgb2YgYW55dGhpbmcgd2l0aCBxdWFsaXR5IDwyNTsKIyMgY3V0YWRhcHQgcHJvdmlkZXMgYW4gYWx0ZXJuYXRpdmUgdG8gdGhpcyB0b29sLgojIyBUaGUgb3JpZ2luYWwgc2VxdWVuY2UgZGF0YSBpcyByZWNvbXByZXNzZWQgYW5kIHNhdmVkIGluIHRoZSBzZXF1ZW5jZXMvIGRpcmVjdG9yeS4KbWtkaXIgLXAgb3V0cHV0cy8wMXRyaW1vbWF0aWMKIyMgTm90ZSB0aGF0IHRyaW1vbWF0aWMgcHJpbnRzIGFsbCBvdXRwdXQgYW5kIGVycm9ycyB0byBTVERFUlIsIHNvIHNlbmQgYm90aCB0byBvdXRwdXQKdHJpbW1vbWF0aWMgUEUgXAogIC10aHJlYWRzIDEgXAogIC1waHJlZDMzIFwKICBUTVJDMzAxNDBfUzNfUjFfMDAxLmZhc3RxLmd6IFRNUkMzMDE0MF9TM19SMl8wMDEuZmFzdHEuZ3ogXAogIFRNUkMzMDE0MF9TM19SMV8wMDEtdHJpbW1lZF9wYWlyZWQuZmFzdHEgVE1SQzMwMTQwX1MzX1IxXzAwMS10cmltbWVkX3VucGFpcmVkLmZhc3RxIFwKICBUTVJDMzAxNDBfUzNfUjJfMDAxLXRyaW1tZWRfcGFpcmVkLmZhc3RxIFRNUkMzMDE0MF9TM19SMl8wMDEtdHJpbW1lZF91bnBhaXJlZC5mYXN0cSBcCiAgIElMTFVNSU5BQ0xJUDovY2JjYi9zdy9SZWRIYXQtNy14ODZfNjQvY29tbW9uL2xvY2FsL3BlcmwvNS4zNC9saWIvc2l0ZV9wZXJsLzUuMzQuMC9hdXRvL3NoYXJlL2Rpc3QvQmlvLUFkdmVudHVyZS9nZW5vbWUvYWRhcHRlcnMuZmE6MjoyMDoxMDoyOmtlZXBCb3RoUmVhZHMgXAogIFNMSURJTkdXSU5ET1c6NDoyMCBNSU5MRU46NDAgXAogIDE+b3V0cHV0cy8wMXRyaW1vbWF0aWMvVE1SQzMwMTQwX1MzX1IxXzAwMS10cmltb21hdGljLm91dCAyPiYxCmV4Y2VwdGVkPSQoZ3JlcCAiRXhjZXB0aW9uIiBvdXRwdXRzL1RNUkMzMDE0MF9TM19SMV8wMDEtdHJpbW9tYXRpYy5vdXQpCiMjIFRoZSBmb2xsb3dpbmcgaXMgaW4gY2FzZSB0aGUgaWxsdW1pbmEgY2xpcHBpbmcgZmFpbHMsIHdoaWNoIGl0IGRvZXMgaWYgdGhpcyBoYXMgYWxyZWFkeSBiZWVuIHJ1biBJIHRoaW5rLgppZiBbWyAiJHtleGNlcHRlZH0iICE9ICIiIF1dOyB0aGVuCiAgdHJpbW1vbWF0aWMgUEUgXAogICAgLXRocmVhZHMgMSBcCiAgICAtcGhyZWQzMyBcCiAgICBUTVJDMzAxNDBfUzNfUjFfMDAxLmZhc3RxLmd6IFRNUkMzMDE0MF9TM19SMl8wMDEuZmFzdHEuZ3ogXAogICAgVE1SQzMwMTQwX1MzX1IxXzAwMS10cmltbWVkX3BhaXJlZC5mYXN0cSBUTVJDMzAxNDBfUzNfUjFfMDAxLXRyaW1tZWRfdW5wYWlyZWQuZmFzdHEgXAogICAgVE1SQzMwMTQwX1MzX1IyXzAwMS10cmltbWVkX3BhaXJlZC5mYXN0cSBUTVJDMzAxNDBfUzNfUjJfMDAxLXRyaW1tZWRfdW5wYWlyZWQuZmFzdHEgXAogICAgIFNMSURJTkdXSU5ET1c6NDoyNSBNSU5MRU46NTBcCiAgICAxPm91dHB1dHMvMDF0cmltb21hdGljL1RNUkMzMDE0MF9TM19SMV8wMDEtdHJpbW9tYXRpYy5vdXQgMj4mMQpmaQpzbGVlcCAxMAptdiBUTVJDMzAxNDBfUzNfUjFfMDAxLXRyaW1tZWRfcGFpcmVkLmZhc3RxIFRNUkMzMDE0MF9TM19SMV8wMDEtdHJpbW1lZC5mYXN0cQptdiBUTVJDMzAxNDBfUzNfUjJfMDAxLXRyaW1tZWRfcGFpcmVkLmZhc3RxIFRNUkMzMDE0MF9TM19SMl8wMDEtdHJpbW1lZC5mYXN0cQoKIyMgUmVjb21wcmVzcyB0aGUgdW5wYWlyZWQgcmVhZHMsIHRoaXMgc2hvdWxkIG5vdCB0YWtlIGxvbmcuCnh6IC05ZSAtZiBUTVJDMzAxNDBfUzNfUjFfMDAxLXRyaW1tZWRfdW5wYWlyZWQuZmFzdHEKeHogLTllIC1mIFRNUkMzMDE0MF9TM19SMl8wMDEtdHJpbW1lZF91bnBhaXJlZC5mYXN0cQojIyBSZWNvbXByZXNzIHRoZSBwYWlyZWQgcmVhZHMuCnh6IC05ZSAtZiBUTVJDMzAxNDBfUzNfUjFfMDAxLXRyaW1tZWQuZmFzdHEKeHogLTllIC1mIFRNUkMzMDE0MF9TM19SMl8wMDEtdHJpbW1lZC5mYXN0cQpsbiAtc2YgVE1SQzMwMTQwX1MzX1IxXzAwMS10cmltbWVkLmZhc3RxLnh6IHIxX3RyaW1tZWQuZmFzdHEueHoKbG4gLXNmIFRNUkMzMDE0MF9TM19SMl8wMDEtdHJpbW1lZC5mYXN0cS54eiByMl90cmltbWVkLmZhc3RxLnh6CgoKIyMgVGhlIGZvbGxvd2luZyBsaW5lcyBnaXZlIHN0YXR1cyBjb2RlcyBhbmQgc29tZSBsb2dnaW5nCmVjaG8gIiMjIEpvYiBzdGF0dXM6ICQ/ICIgPj4gb3V0cHV0cy9sb2cudHh0CmVjaG8gIiMjICQoaG9zdG5hbWUpIEZpbmlzaGVkICR7U0xVUk1fSk9CSUR9IDAxdHJpbV9UTVJDMzAxNDBfUzNfUjFfMDAxLnNoIGF0ICQoZGF0ZSksIGl0IHRvb2sgJCgoIFNFQ09ORFMgLyA2MCApKSBtaW51dGVzLiIgPj4gb3V0cHV0cy9sb2cudHh0Cgp3YWxsdGltZT0kKHNjb250cm9sIHNob3cgam9iICIke1NMVVJNX0pPQklEfSIgfCBncmVwIFJ1blRpbWUgfCBwZXJsIC1GJy9ccyt8PS8nIC1sYW5lICd7cHJpbnQgJEZbMl19JykKZWNobyAiIyMjIyB3YWxsdGltZSB1c2VkIGJ5ICR7U0xVUk1fSk9CSUR9IHdhczogJHt3YWxsdGltZTotbnVsbH0iID4+IG91dHB1dHMvbG9nLnR4dAptYXhtZW09JChzc3RhdCAtLWZvcm1hdD1NYXhWTVNpemUgLW4gIiR7U0xVUk1fSk9CSUR9LmJhdGNoIikKZWNobyAiIyMjIyBtYXhpbXVtIG1lbW9yeSB1c2VkIGJ5ICR7U0xVUk1fSk9CSUR9IHdhczogJHttYXhtZW06LW51bGx9IiA+PiBvdXRwdXRzL2xvZy50eHQKYXZlY3B1PSQoc3N0YXQgLS1mb3JtYXQ9QXZlQ1BVIC1uICIke1NMVVJNX0pPQklEfS5iYXRjaCIpCmVjaG8gIiMjIyMgYXZlcmFnZSBjcHUgdXNlZCBieSAke1NMVVJNX0pPQklEfSB3YXM6ICR7YXZlY3B1Oi1udWxsfSIgPj4gb3V0cHV0cy9sb2cudHh0CmBgYAoKIyMjIE1hcHBpbmcgdGhlIHRyaW1tZWQgcmVhZHMKClRoZXJlIGlzIGEgc2ltaWxhciBzaGVsbCBmcmFnbWVudCB1c2VkIHRvIG1hcCB0aGVzZSB0cmltbWVkIHJlYWRzCmFnYWluc3QgdGhlIGhnMzhfMTAwIGdlbm9tZS90cmFuc2NyaXB0b21lIGFsb25nIHdpdGggdGhlIHBhbmFtZW5zaXMKZ2Vub21lOgoKYGBge2Jhc2ggbWFwX2ZyYWdtZW50LCBldmFsPUZBTFNFfQojIS91c3IvYmluL2VudiBiYXNoCmlucHV0PSQoL2Jpbi9scyAqX3RyaW1tZWQuZmFzdHEueHogfCB0ciAnXG4nICc6JyB8IHNlZCAncy86JC8vZycpCmN5b2EgLS10YXNrIG1hcCAtLW1ldGhvZCBoaXNhdCAtLXNwZWNpZXMgaGczOF8xMDAgLS1nZmZfdHlwZSBnZW5lIC0tZ2ZmX3RhZyBnZW5lX2lkICBcCiAgLS1pbnB1dCAke2lucHV0fSAyPnRtcmMzX21hcC5vdXQgMT4mMiAmCmN5b2EgLS10YXNrIG1hcCAtLW1ldGhvZCBoaXNhdCAtLXNwZWNpZXMgbHBhbmFtZW5zaXNfdjM2IC0tZ2ZmX3R5cGUgZ2VuZSAtLWdmZl90YWcgSUQgXAogIC0taW5wdXQgJHtpbnB1dH0gMj4+dG1yYzNfbWFwLm91dCAxPiYyICYKY3lvYSAtLXRhc2sgbWFwIC0tbWV0aG9kIHNhbG1vbiAtLXNwZWNpZXMgaGczOF8xMDAgXAogICAgIC0taW5wdXQgJHtpbnB1dH0gMj50bXJjM19zYWxtb24ub3V0IDE+JjIgJgpgYGAKClRoZSBmb2xsb3dpbmcgaXMgdGhlIHJlc3VsdGluZyBtYXBwaW5nIHNjcmlwdCB0YWtlbiBhcmJpdHJhcmlseSBmcm9tCnNhbXBsZSBUTVJDMzAyMDUuICBUaGVyZSBhcmUgYSBmZXcgYXNwZWN0cyBvZiB0aGlzIHNjcmlwdCB3aGljaApjaGFuZ2VkIGZyb20gdGhlIGJlZ2lubmluZyB0byBlbmQgb2YgdGhlIHByb2plY3Q6IHRoZSBwcmVmaXggIwpjaGFuZ2VkLCBJIGFkZGVkIHNvbWUgbG9naWMgdG8gY2hlY2sgaWYgdGhlIHJlcXVpc2l0ZSBzb2Z0d2FyZSAoaW4KdGhpcyBjYXNlIGhpc2F0Mi9zYW10b29scy9odHNlcSkgaXMgYWxyZWFkeSBpbiB0aGUgcGF0aCwgYW5kIGxvYWQgaXQKaWYgbm90LiAgSSBhbHNvIGNoYW5nZWQgdGhlIGh0c2VxIG91dHB1dCBmaWxlbmFtZXMgc2xpZ2h0bHkgb3ZlciB0aW1lCnRvIHRyeSB0byBtYWtlIGNlcnRhaW4gdGhhdCB0aGV5IGFyZSBjb25zaXN0ZW50IGFuZCB0aGF0IGl0IGlzIGVhc3kgdG8KaWRlbnRpZnkgdGhlIGltcG9ydGFudCBwYXJhbWV0ZXJzIGp1c3QgZnJvbSB0aGUgb3V0cHV0IGZpbGVuYW1lLgoKYGBge2Jhc2ggaGlzYXRfbWFwX3NjcmlwdCwgZXZhbD1GQUxTRX0KIyEvdXNyL2Jpbi9lbnYgYmFzaAojU0JBVENIIC0tY2hkaXI9L2ZzL2NiY2ItbGFiL25lbHNheWVkL3NjcmF0Y2gvYXRiL3JuYXNlcS9scGFuYW1lbnNpc190bXJjXzIwMTkvcHJlcHJvY2Vzc2luZy9UTVJDMzAyMDUKI1NCQVRDSCAtLXBhcnRpdGlvbj1kcGFydAojU0JBVENIIC0tcW9zPXdvcmtzdGF0aW9uIC0tbmljZT0xMAojU0JBVENIIC0tbm9kZXM9MSAtLXJlcXVldWUKI1NCQVRDSCAtLXRpbWU9MTA6MDA6MDAKI1NCQVRDSCAtLWpvYi1uYW1lPTQwaGlzYXQyX2hnMzhfMTAwX2dlbm9tZQojU0JBVENIIC0tbWVtPTQ4RwojU0JBVENIIC0tY3B1cy1wZXItdGFzaz00CiNTQkFUQ0ggLS1vdXRwdXQ9b3V0cHV0cy9sb2dzL2hpc2F0Ml9oZzM4XzEwMF9nZW5vbWUuc2JhdGNob3V0CgplY2hvICIjIyBTdGFydGVkIC9mcy9jYmNiLWxhYi9uZWxzYXllZC9zY3JhdGNoL2F0Yi9ybmFzZXEvbHBhbmFtZW5zaXNfdG1yY18yMDE5L3ByZXByb2Nlc3NpbmcvVE1SQzMwMjA1L3NjcmlwdHMvNDBoaXNhdDJfaGczOF8xMDBfZ2Vub21lLnNoIGF0ICQoZGF0ZSkgb24gJChob3N0bmFtZSkgd2l0aCBpZCAke1NMVVJNX0pPQklEfS4iID4+IG91dHB1dHMvbG9nLnR4dAoKbW9kdWxlIGFkZCBoaXNhdDIgc2FtdG9vbHMgaHRzZXEKCiMjIFRoaXMgaXMgYSBoaXNhdDIgYWxpZ25tZW50IG9mICAtMSA8KGxlc3MgL2ZzL2NiY2ItbGFiL25lbHNheWVkL3NjcmF0Y2gvYXRiL3JuYXNlcS9scGFuYW1lbnNpc190bXJjXzIwMTkvcHJlcHJvY2Vzc2luZy9UTVJDMzAyMDUvcjFfdHJpbW1lZC5mYXN0cS54eikgLTIgPChsZXNzIC9mcy9jYmNiLWxhYi9uZWxzYXllZC9zY3JhdGNoL2F0Yi9ybmFzZXEvbHBhbmFtZW5zaXNfdG1yY18yMDE5L3ByZXByb2Nlc3NpbmcvVE1SQzMwMjA1L3IyX3RyaW1tZWQuZmFzdHEueHopICBhZ2FpbnN0IC9jYmNiaG9tZXMvYWJlbGV3L2xpYnJhcmllcy9nZW5vbWUvaW5kZXhlcy9oZzM4XzEwMAoKbWtkaXIgLXAgb3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMApzbGVlcCAzCmhpc2F0MiAteCAvY2JjYmhvbWVzL2FiZWxldy9saWJyYXJpZXMvZ2Vub21lL2luZGV4ZXMvaGczOF8xMDAgIFwKICAtcCA0IFwKICAtcSAgIC0xIDwobGVzcyAvZnMvY2JjYi1sYWIvbmVsc2F5ZWQvc2NyYXRjaC9hdGIvcm5hc2VxL2xwYW5hbWVuc2lzX3RtcmNfMjAxOS9wcmVwcm9jZXNzaW5nL1RNUkMzMDIwNS9yMV90cmltbWVkLmZhc3RxLnh6KSAtMiA8KGxlc3MgL2ZzL2NiY2ItbGFiL25lbHNheWVkL3NjcmF0Y2gvYXRiL3JuYXNlcS9scGFuYW1lbnNpc190bXJjXzIwMTkvcHJlcHJvY2Vzc2luZy9UTVJDMzAyMDUvcjJfdHJpbW1lZC5mYXN0cS54eikgIFwKICAtLXBocmVkMzMgXAogIC0tdW4tZ3ogb3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9UTVJDMzAyMDVfdW5hbGRpc19oZzM4XzEwMF9nZW5vbWUuZmFzdHEgXAogIC0tYWwtZ3ogb3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9UTVJDMzAyMDVfYWxkaXNfaGczOF8xMDBfZ2Vub21lLmZhc3RxIFwKICAtLXVuLWNvbmMtZ3ogb3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9UTVJDMzAyMDVfdW5hbGNvbl9oZzM4XzEwMF9nZW5vbWUuZmFzdHEgXAogIC0tYWwtY29uYy1neiBvdXRwdXRzLzQwaGlzYXQyX2hnMzhfMTAwL1RNUkMzMDIwNV9hbGNvbl9oZzM4XzEwMF9nZW5vbWUuZmFzdHEgXAogIC1TIG91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS5zYW0gXAogIDI+b3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9oaXNhdDJfaGczOF8xMDBfZ2Vub21lX1RNUkMzMDIwNS5lcnIgXAogIDE+b3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9oaXNhdDJfaGczOF8xMDBfZ2Vub21lX1RNUkMzMDIwNS5vdXQKCgojIyBUaGUgZm9sbG93aW5nIGxpbmVzIGdpdmUgc3RhdHVzIGNvZGVzIGFuZCBzb21lIGxvZ2dpbmcKZWNobyAiIyMgSm9iIHN0YXR1czogJD8gIiA+PiBvdXRwdXRzL2xvZy50eHQKZWNobyAiIyMgJChob3N0bmFtZSkgRmluaXNoZWQgJHtTTFVSTV9KT0JJRH0gNDBoaXNhdDJfaGczOF8xMDBfZ2Vub21lLnNoIGF0ICQoZGF0ZSksIGl0IHRvb2sgJCgoIFNFQ09ORFMgLyA2MCApKSBtaW51dGVzLiIgPj4gb3V0cHV0cy9sb2cudHh0Cgp3YWxsdGltZT0kKHNjb250cm9sIHNob3cgam9iICIke1NMVVJNX0pPQklEfSIgfCBncmVwIFJ1blRpbWUgfCBwZXJsIC1GJy9ccyt8PS8nIC1sYW5lICd7cHJpbnQgJEZbMl19JykKZWNobyAiIyMjIyB3YWxsdGltZSB1c2VkIGJ5ICR7U0xVUk1fSk9CSUR9IHdhczogJHt3YWxsdGltZTotbnVsbH0iID4+IG91dHB1dHMvbG9nLnR4dAptYXhtZW09JChzc3RhdCAtLWZvcm1hdD1NYXhWTVNpemUgLW4gIiR7U0xVUk1fSk9CSUR9LmJhdGNoIikKZWNobyAiIyMjIyBtYXhpbXVtIG1lbW9yeSB1c2VkIGJ5ICR7U0xVUk1fSk9CSUR9IHdhczogJHttYXhtZW06LW51bGx9IiA+PiBvdXRwdXRzL2xvZy50eHQKYXZlY3B1PSQoc3N0YXQgLS1mb3JtYXQ9QXZlQ1BVIC1uICIke1NMVVJNX0pPQklEfS5iYXRjaCIpCmVjaG8gIiMjIyMgYXZlcmFnZSBjcHUgdXNlZCBieSAke1NMVVJNX0pPQklEfSB3YXM6ICR7YXZlY3B1Oi1udWxsfSIgPj4gb3V0cHV0cy9sb2cudHh0CmBgYAoKRnJvbSBoZXJlIG9uIEkgd2lsbCByZW1vdmUgdGhlIHN1ZmZpeCBvZiB0aGUgc2NyaXB0LiAgSGVyZSBpcyB0aGUgc2FtCnRvIGJhbSBjb252ZXJzaW9uIHNjcmlwdCB3aGljaCB3YXMgY3JlYXRlZCBieSBjeW9hLgoKYGBge2Jhc2ggc2FtMmJhbV9zY3JpcHQsIGV2YWw9RkFMU0V9Cm1vZHVsZSBhZGQgc2FtdG9vbHMgYmFtdG9vbHMKCiMjIENvbnZlcnRpbmcgdGhlIHRleHQgc2FtIHRvIGEgY29tcHJlc3NlZCwgc29ydGVkLCBpbmRleGVkIGJhbWZpbGUuCiMjIEFsc28gcHJpbnRpbmcgYWxpZ25tZW50IHN0YXRpc3RpY3MgdG8gb3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9UTVJDMzAyMDVfaGczOF8xMDBfZ2Vub21lLmJhbS5zdGF0cwojIyBUaGlzIGpvYiBkZXBlbmRlZCBvbjogMTMzOTk1CgplY2hvICJTdGFydGluZyBzYW10b29scyIKaWYgJCh0ZXN0ICEgLXIgb3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9UTVJDMzAyMDVfaGczOF8xMDBfZ2Vub21lLnNhbSk7IHRoZW4KICAgIGVjaG8gIkNvdWxkIG5vdCBmaW5kIHRoZSBzYW10b29scyBpbnB1dCBmaWxlLiIKICAgIGV4aXQgMQpmaQpzYW10b29scyB2aWV3IC11IC10IC9jYmNiaG9tZXMvYWJlbGV3L2xpYnJhcmllcy9nZW5vbWUvaGczOF8xMDAuZmFzdGEgXAogIC1TIG91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS5zYW0gLW8gb3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9UTVJDMzAyMDVfaGczOF8xMDBfZ2Vub21lLmJhbSAgXAogIDI+b3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9UTVJDMzAyMDVfaGczOF8xMDBfZ2Vub21lLmJhbS5lcnIgMT5vdXRwdXRzLzQwaGlzYXQyX2hnMzhfMTAwL1RNUkMzMDIwNV9oZzM4XzEwMF9nZW5vbWUuYmFtLm91dCAmJiBcCgogIHNhbXRvb2xzIHNvcnQgLWwgOSBvdXRwdXRzLzQwaGlzYXQyX2hnMzhfMTAwL1RNUkMzMDIwNV9oZzM4XzEwMF9nZW5vbWUuYmFtIC1vIG91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS1zb3J0ZWQuYmFtIFwKICAyPm91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS1zb3J0ZWQuZXJyIDE+b3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9UTVJDMzAyMDVfaGczOF8xMDBfZ2Vub21lLXNvcnRlZC5vdXQgJiYgXAogIHJtIG91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS5iYW0gJiYgXAogIHJtIG91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS5zYW0gJiYgXAogIG12IG91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS1zb3J0ZWQuYmFtIG91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS5iYW0gJiYgIHNhbXRvb2xzIGluZGV4IG91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS5iYW0KCmJhbXRvb2xzIHN0YXRzIC1pbiBvdXRwdXRzLzQwaGlzYXQyX2hnMzhfMTAwL1RNUkMzMDIwNV9oZzM4XzEwMF9nZW5vbWUuYmFtIDI+b3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9UTVJDMzAyMDVfaGczOF8xMDBfZ2Vub21lLmJhbS5zdGF0cyAxPiYyCgojIyBUaGUgZm9sbG93aW5nIHdpbGwgZmFpbCBpZiB0aGlzIGlzIHNpbmdsZS1lbmRlZC4Kc2FtdG9vbHMgdmlldyAtYiAtZiAyIC1vIG91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS1wYWlyZWQuYmFtIG91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS5iYW0gJiYgc2FtdG9vbHMgaW5kZXggb3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9UTVJDMzAyMDVfaGczOF8xMDBfZ2Vub21lLXBhaXJlZC5iYW0KYmFtdG9vbHMgc3RhdHMgLWluIG91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS1wYWlyZWQuYmFtIDI+b3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9UTVJDMzAyMDVfaGczOF8xMDBfZ2Vub21lLXBhaXJlZC5zdGF0cyAxPiYyCmBgYAoKQW5kIHRoZSBjb3VudGluZyBzY3JpcHQgZm9yIGh0c2VxLiAgSSBjaGFuZ2VkIHRoZSBvdXRwdXQgZmlsZW5hbWUgZm9yCnRoaXMgc3RlcCBvbiBtdWx0aXBsZSBvY2Nhc2lvbnMgb3ZlciB0aGUgY291cnNlIG9mIHNhbXBsZSBjb2xsZWN0aW9uLgoKYGBge2Jhc2ggaHRzZXFfaGczOF8xMDAsIGV2YWw9RkFMU0V9Cm1vZHVsZSBhZGQgaHRzZXEKCiMjIENvdW50aW5nIHRoZSBudW1iZXIgb2YgaGl0cyBpbiBvdXRwdXRzLzQwaGlzYXQyX2hnMzhfMTAwL1RNUkMzMDIwNV9oZzM4XzEwMF9nZW5vbWUtcGFpcmVkLmJhbSBmb3IgZWFjaCBmZWF0dXJlIGZvdW5kIGluIC9jYmNiaG9tZXMvYWJlbGV3L2xpYnJhcmllcy9nZW5vbWUvaGczOF8xMDAuZ2ZmCiMjIElzIHRoaXMgc3RyYW5kZWQ/IG5vLiAgVGhlIGRlZmF1bHRzIG9mIGh0c2VxIGFyZToKIyMgIC0tb3JkZXI9bmFtZSAtLWlkYXR0cj1nZW5lX2lkIC0tbWluYXF1YWw9MTAgLS10eXBlPWV4b24gLS1zdHJhbmRlZD15ZXMgLS1tb2RlPXVuaW9uCgpodHNlcS1jb3VudCBcCiAgLXEgLWYgYmFtIC1zIG5vICAtLXR5cGUgZ2VuZSAgLS1pZGF0dHIgZ2VuZV9pZCBcCiAgb3V0cHV0cy80MGhpc2F0Ml9oZzM4XzEwMC9UTVJDMzAyMDVfaGczOF8xMDBfZ2Vub21lLXBhaXJlZC5iYW0gXAogIC9jYmNiaG9tZXMvYWJlbGV3L2xpYnJhcmllcy9nZW5vbWUvaGczOF8xMDAuZ2ZmIFwKICAyPm91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS1wYWlyZWRfYWxsX2hnMzhfMTAwX3Nub19nZW5lX2dlbmVfaWQuZXJyIFwKICAxPm91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS1wYWlyZWRfYWxsX2hnMzhfMTAwX3Nub19nZW5lX2dlbmVfaWQuY291bnQgJiYgXAogICAgeHogLWYgLTllIG91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS1wYWlyZWRfYWxsX2hnMzhfMTAwX3Nub19nZW5lX2dlbmVfaWQuY291bnQgMj5vdXRwdXRzLzQwaGlzYXQyX2hnMzhfMTAwL1RNUkMzMDIwNV9oZzM4XzEwMF9nZW5vbWUtcGFpcmVkX2FsbF9oZzM4XzEwMF9zbm9fZ2VuZV9nZW5lX2lkLmVyci54eiAxPm91dHB1dHMvNDBoaXNhdDJfaGczOF8xMDAvVE1SQzMwMjA1X2hnMzhfMTAwX2dlbm9tZS1wYWlyZWRfYWxsX2hnMzhfMTAwX3Nub19nZW5lX2dlbmVfaWQuY291bnQueHoKYGBgCgpUaGUgc2FtZSBjeW9hIGludm9jYXRpb24gcHJvZHVjZWQgYSBzZXJpZXMgb2Ygc2NyaXB0cyB0byBhZ2dyZXNzaXZlbHkKY29tcHJlc3MgdGhlICh1biltYXBwZWQgcmVhZHMgZnJvbSBoaXNhdDIgYW5kIHByaW50IG91dCBzb21lIHN1bW1hcnkKc3RhdGlzdGljcyBvZiB0aGUgcnVucy4KCkNvbnZlcnNlbHksIGhlcmUgaXMgYSBzYWxtb24gc2NyaXB0IHdoaWNoIHdhcyB1c2VkIGZvciBzYW1wbGUKVE1SQzMwMTI0ICh3aXRob3V0IHRoZSBzbHVybSBwcmVmaXgvc3VmZml4KToKCmBgYHtiYXNoIHNhbG1vbl9zY3JpcHQsIGV2YWw9RkFMU0V9Cm1rZGlyIC1wIG91dHB1dHMvc2FsbW9uX2hnMzhfMTAwICYmIHNsZWVwIDMgJiYgXApzYWxtb24gcXVhbnQgLWkgL2NiY2Job21lcy9hYmVsZXcvbGlicmFyaWVzL2dlbm9tZS9pbmRleGVzL2hnMzhfMTAwX3NhbG1vbl9pbmRleCBcCiAgLWwgQSAtLWdjQmlhcyAtLXZhbGlkYXRlTWFwcGluZ3MgIFwKICAgLXIgPChsZXNzIHIxX3RyaW1tZWQuZmFzdHEuZ3opICBcCiAgLW8gb3V0cHV0cy9zYWxtb25faGczOF8xMDAgXAogIDI+b3V0cHV0cy9zYWxtb25faGczOF8xMDAvc2FsbW9uLmVyciAxPm91dHB1dHMvc2FsbW9uX2hnMzhfMTAwL3NhbG1vbi5vdXQKYGBgCgojIFByZXByb2Nlc3NpbmcgZGF0YSBmcm9tIERyLiBTY290dCdzIGxhYgoKT25lIHBvdGVudGlhbGx5IG9idmlvdXMgY29tcGFyaXNvbiBJIG5lZ2xlY3RlZCB0byBtYWtlIHdhcyBhZ2FpbnN0IGEKbmV3ZXIgZGF0YSBzZXQgZnJvbSB0aGUgU2NvdHQgbGFiLiAgKGhtbSB6b3Rlcm8gY2Fubm90IHNlZW0gdG8gc3VjayBpbgp0aGUgYXV0aG9yIG5hbWVzIT8gIERpZCBzY2llbmNlIHNvbWVob3cgc2FuaXRpemUgdGhlIHBkZiBvciBpcyB6b3Rlcm8KanVzdCBiZWluZyBhIGRvb2Z1cz8gIE5vcGUgaXQgaXMgZGVmaW5pdGVseSBzY2llbmNlLCBJIGFza2VkIHpvdGVybyB0bwppbmRleCBhIGZyZXNoIGNvcHkgSSBkb3dubG9hZGVkIGZyb20gcHVibWVkIGFuZCBpdCB3b3JrZWQgZmluZSwgdGhhdApzdWNrcywgSSBraW5kIG9mIHdpc2ggd2Ugd291bGQgY29sbGVjdGl2ZWx5IHJlZnVzZSB0byBlbmdhZ2Ugd2l0aCB0aGUKZm9yLXByb2ZpdCBqb3VybmFscy4pICAoQGFtb3JpbVZhcmlhYmxlR2VuZUV4cHJlc3Npb24yMDE5KQoKSW4gYW55IGV2ZW50LCB0aGUgYmlvcHJvamVjdCBhY2Nlc3Npb24gZm9yIHRoaXMgZXhwZXJpbWVudCBpczoKUFJKTkE1MjU2MDQgd2hpY2ggaXMgaGFuZHkgZm9yIG1lLCBiZWNhdXNlIGN5b2EgaGFzIGEgdGFyZ2V0IG5hbWVkCidzcmFkb3dubG9hZCcgd2hpY2ggd2lsbCwgaWYgaXQgc2VlcyBhIFBSSk5BLCBkbyBhIGxpdHRsZQp3ZWItc2NyYXBpbmcsIGRvd25sb2FkIHRoZSBtZXRhZGF0YS5jc3YgZnJvbSBTUkEgcnVuIGZpbmRlciBhbmQgdGhlbgpkb3dubG9hZCB0aGUgZGF0YSBmb3IgZXZlcnkgcnVuIGludG8gc2VwYXJhdGUgZGlyZWN0b3JpZXMuCgpJIGhhdmUgc2luY2Ugc3RhcnRlZCAoYnV0IG5vdCBmaW5pc2hlZCkgdGhlIGltcGxlbWVudGF0aW9uIG9mIGEKLS1pdGVyYXRlIHRhcmdldCB3aGljaCB3aWxsIGRvIHdoYXQgaXQgc2F5cyBvbiB0aGUgdGluOiBpdGVyYXRlIG92ZXIKZXZlcnkgZGlyZWN0b3J5IGluIGEgdHJlZSBhbmQgaW52b2tlIHRoZSBzYW1lIHBpcGVsaW5lIG9uIGl0OyBidXQKdW50aWwgSSBmaW5pc2ggdGhhdCwgYmFzaCBmb3IgbG9vcHMgZm9yIGV2ZXJ5b25lIQoKSGVyZSBpcyB3aGF0IEkgZGlkOgoKYGBge2Jhc2gsIGV2YWw9RkFMU0V9Cm1rZGlyIC1wIHByZXByb2Nlc3NpbmcvUFJKTkE1MjU2MDQvCm1vZHVsZSBhZGQgY3lvYQpjZCBwcmVwcm9jZXNzaW5nL1BSSk5BNTI1NjA0CnN0YXJ0PSQocHdkKQpjeW9hIC0tbWV0aG9kIHNyYSAtLWlucHV0IFBSSk5BNTI1NjA0CiMjIHdhaXQgYSB3aGlsZSwgSSBnb3QgYSBjb2ZmZWUhIGFuZCBsaXN0ZW5lZCB0byB0aGUgZmlyc3Qgc29uZyBmcm9tIE9sYXJmdXIgQXJuYXVsZHMgdmlhIENlcmNsZToKIyMgaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1iTUNpQUtOVXBUWQojIyBJIHRoZW4gcmVhbGl6ZWQgbXkgc2NyaXB0IGhhcyBhbiBlcnJvciB3aGVyZSBpdCBsZWF2ZXMgdGhlIGpvYiBsb2cKIyMgZm9yIHRoaXMsIGl0IGNyZWF0ZWQgYW5vdGhlciBwcmVwcm9jZXNzaW5nIGRpcmVjdG9yeSB3aXRoIHRoZSBsb2cuCgojIyBSdW4gdGhlIHByb2Nlc3NpbmcgcGlwZWxpbmcKZm9yIGkgaW4gJCgvYmluL2xzIC1kIFNSUiopOyBkbwogICAgY2QgJGkKICAgIGN5b2EgLS1tZXRob2QgcHJuYXNlcSAtLXNwZWNpZXMgaGczOF8xMSBcCiAgICAgICAgIC0taW5wdXQgJCgvYmluL2xzICouZmFzdHEuZ3ogfCB0ciAnXG4nICc6JykKICAgIGNkICRzdGFydApkb25lCiMjIFRoZSBQcm9jZXNzX1JOQVNlcSB0YXJnZXQgKHBybmEpIGhhbmRsZXMgYWxsIHRoZSBzdHVmZiBhYm92ZS4KYGBgCgpUaGUgc2NvdHQgbGFiIGZvbGxvd2VkIHRoaXMgd29yayB1cCB3aXRoIGFuIGV4YW1pbmF0aW9uIG9mIHRoZQppbnRlcmFjdGlvbiBiZXR3ZWVuIG1pY3JvYmlhbCBidXJlbiBvZiB0aGUgc2tpbiBhbmQgaXRzIGNvbm5lY3Rpb24gdG8KaW5jcmVhc2VkIHVucHJlZGljdGFiaWxpdHkgaW4gY2xpbmljYWwgb3V0Y29tZSBhcyB3ZWxsIGFzIGluY3JlYXNlZAppbmZsYW1tYXRpb24gZHVyaW5nCmluZmVjdGlvbiAoQGZhcmlhc2Ftb3JpbU11bHRpb21pY1Byb2ZpbGluZ0N1dGFuZW91czIwMjMpLiAgSQpjb21wbGV0ZWx5IG1pc3NlZCB0aGlzIHBhcGVyIHVudGlsIHF1aXRlIHJlY2VudGx5ICgyMDI0MDQpOyBpbgphZGRpdGlvbiwgYXMgSSB3YXMgZmluaXNoaW5nIG15IHF1aWNrIGZpcnN0LXBhc3MgcmVhZCB0aHJvdWdoLCBJIGZvdW5kCnRoZSBiaW9wcm9qZWN0IGFjY2Vzc2lvbiwgYW5kIHVwb24gcmVhZGluZyB0aGUgbWV0YWRhdGEgYXQgU1JBCnJlYWxpemVkIHRoZXkgYWxzbyBmb2xsb3dlZCB0aGF0IHdvcmsgdXAgd2l0aCBhbm90aGVyIHBpZWNlIG9mCmludHJpZ3Vpbmcgd29yayAoQHNhY3JhbWVudG9DQ1I1UHJvbW90ZXNNaWdyYXRpb24yMDI0KS4KClNvLCB3aXRoIHRoYXQgaW4gbWluZDoKCmBgYHtiYXNoLCBldmFsPUZBTFNFfQphYz1QUkpOQTg4NTEzMQpta2RpciAtcCBwcmVwcm9jZXNzaW5nLyR7YWN9Cm1vZHVsZSBhZGQgY3lvYS8yMDI0MDQKY2QgcHJlcHJvY2Vzc2luZy8ke2FjfQpzdGFydD0kKHB3ZCkKY3lvYSAtLW1ldGhvZCBzcmEgLS1pbnB1dCAkYWMKYWM9UFJKTkE2ODI5ODUKbWtkaXIgLXAgcHJlcHJvY2Vzc2luZy8ke2FjfQpjZCBwcmVwcm9jZXNzaW5nLyR7YWN9CnN0YXJ0PSQocHdkKQpjeW9hIC0tbWV0aG9kIHNyYSAtLWlucHV0ICRhYwoKZm9yIGkgaW4gJCgvYmluL2xzIC1kIFNSUiopOyBkbwogICAgY2QgJGkKICAgIGN5b2EgLS1tZXRob2QgcHJuYXNlcSAtLXNwZWNpZXMgaGczOF8xMSBcCiAgICAgICAgIC0taW5wdXQgJCgvYmluL2xzICouZmFzdHEuZ3ogfCB0ciAnXG4nICc6JykKICAgIGNkICRzdGFydApkb25lCiMjIE5vdGUsIEkgb25seSBhc2tlZCBpdCB0byBkbyBoZzM4IGZvciBub3csIGJ1dCBJIGNvdWxkL3Nob3VsZCBjaGFuZ2UgaXQgdG8KIyMgaGczOF8xMTpsYnJhemlsaWVuc2lzXzI5MDRfdjQ2OnNhdXJldXNfODMyNQojIyBvbmNlIEkgdmVyaWZ5IHRob3NlIGFyZSB0aGUgYXBwcm9wcmlhdGUgZ2Vub21lcyAtLSBhbmQgSSBzaG91bGQKIyMgcHJvYmFibHkgZ3JhYiBmcmVzaCBjb3BpZXMsIEkgaGF2ZW4ndCB1cGRhdGVkIHRoZW0gaW4gYSB3aGlsZS4KYGBgCgpPaCB5ZWFoLCBteSBTdGFwaHlsb2NvY2N1cyBhc3NlbWJseSBpcyBzdHVwaWRseSBvbGQsIEkgY2Fubm90IGV2ZW4KdGVsbCB3aGVyZSBJIGRvd25sb2FkZWQgaXQgKG9oLCBJIGNoZWNrZWQgdGhlIGZhc3RhIGZpbGUsIGl0IGlzCmN1cnJlbnQsIEkganVzdCBtYW51YWxseSBkb3dubG9hZGVkIGV2ZXJ5dGhpbmcgbGlrZSBhIGRvb2Z1cyBhbmQgaXQgaXMKaGFyZCB0byB0ZWxsIHRoZSB2ZXJzaW9uKSAgSSBhbSBqdXN0IGdvaW5nIHRvIHJlZG93bmxvYWQgaXQgdmlhIGN5b2EKc28gSSBoYXZlIHRoZSBmdWxsIGFjY2Vzc2lvbiBvbiBoYW5kOgoKYGBge2Jhc2gsIGV2YWw9RkFMU0V9CmNkIH4vbGlicmFyaWVzL2dlbm9tZS9nZW5iYW5rCmN5b2EgLS1tZXRob2QgbmNiaWRvd25sb2FkIC0taW5wdXQgR0NGXzAwMDAxMzQyNQojIyAtLWRvd25sb2FkIGRvd25sb2FkcyB3aGF0ZXZlciBuY2JpIGFjY2Vzc2lvbiBJIGZlZWQgaXQsIG1heWJlIEkKIyMgc2hvdWxkIGNoYW5nZSB0aGF0IHRvIHNvbWV0aGluZyBsaWtlIC0tbmNiaWRvd24gKEkgZGlkISkgYW5kIG1ha2Ugb25lIGZvcgojIyBlbnNlbWJsIGFuZCBtaWNyb2Jlc29ubGluZSBhbmQgZnJpZW5kcy4gIFRoaW5nIGlzLCBJIGxpa2UgaGF2aW5nIGFuCiMjIGFyY2hpdmUgb2YgdGhlIGdiayBmaWxlIHNvIEkgY2FuIGxhdGVyIGV4dHJhY3Qgc3R1ZmYsIGVuc2VtYmwvZXRjCiMjIGRvIG5vdCBnaXZlIG1lIHRoYXQsIHNvIGl0IGlzIG9mdGVuIGVhc2llciB0byBqdXN0IGRvd25sb2FkCiMjIG1hbnVhbGx5LCBidXQgdGhlbiBhZ2FpbiwgaWYgSSBhZGQgaXQgdG8gY3lvYSBJIGRvIG5vdCBoYXZlIHRvCiMjIHNjcm9sbCBhcm91bmQgYW5kIGFjY2lkZW50bHkgZG93bmxvYWQgc29tZSByYW5kbyBjaHJvbW9zb21lIGluc3RlYWQKIyMgb2YgdGhlIGZ1bGwgYXNzZW1ibHk7IGFuZCBJIGNhbiBhZGQgYSB5ZWFyIG9yIHJlbGVhc2UgSUQgYW5kIGhhdmUKIyMgaXQgZ28gdG8gdGhlIGFwcHJvcHJpYXRlIGFyY2hpdmUgc2VydmVyLiAgeWVhaCwgSSBsaWtlIHRoYXQuCiMjIG1heWJlIEkgc2hvdWxkIGNoYW5nZSAtLWlucHV0IHRvIC0tYWNjZXNzaW9uIGZvciBzdHVmZiBsaWtlIHRoaXM/CmxzIC1sdHIKbG4gLXMgR0NGXzAwMDAxMzQyNS5nYmZmIHNhdXJldXNfODMyNS5nYmsKY3lvYSAtLW1ldGhvZCBnYjJnZmYgLS1pbnB1dCBzYXVyZXVzXzgzMjUuZ2JrCmxzIC1sdHIKbXYgc2F1cmV1c184MzI1LmZzYSAuLi9mYXN0YS8KbXYgc2F1cmV1c184MzI1X2FsbC5nZmYgLi4vZ2ZmL3NhdXJldXNfODMyNS5nZmYKbXYgc2F1cmV1c184MzI1LmZhYSAuLi8uLi9hbWlub19hY2lkLwptdiBzYXVyZXVzXzgzMjUuZmZuIC4uLy4uL0NEUy9mYXN0YS8KbXYgc2F1cmV1c184MzI1X2Nkcy5nZmYgLi4vLi4vQ0RTL2Zhc3RhL3NhdXJldXNfODMyNS5nZmYKbXYgc2F1cmV1c184MzI1X2ludGVyQ0RTLmdmZiAuLi8uLi9pbnRlckNEUy9nZmYvc2F1cmV1c184MzI1LmdmZgptdiBzYXVyZXVzXzgzMjVfcnJuYS5nZmYgLi4vLi4vclJOQS9nZmYvc2F1cmV1c184MzI1LmdmZgptdiBzYXVyZXVzXzgzMjVfcnJuYS5mYXN0YSAuLi8uLi9yUk5BL2Zhc3RhL3NhdXJldXNfODMyNS5nYXN0YQpjZCAuLi9mYXN0YQpjeW9hIC0tbWV0aG9kIGluZGV4aGlzYXQgLS1zcGVjaWVzIHNhdXJldXNfODMyNSBcCiAgICAgLS1pbnB1dCBzYXVyZXVzXzgzMjUuZnNhIFwKICAgICAtLWdlbm9tZSBzYXVyZXVzXzgzMjUKCmBgYAoKCk15IGZhdm9yaXRlIHBhcnQgb2YgdGhlIGFib3ZlOiBJIGNhbiBwcm92aWRlIHRoZSBjc3YgZG93bmxvYWRlZCBmcm9tClNSQSB0byBteSBocGdsdG9vbHM6OmdhdGhlcl9wcmVwcm9jZXNzaW5nX21ldGFkYXRhKCkgZnVuY3Rpb24gYWxvbmcKd2l0aCB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhlIGRvd25sb2FkZWQgZGF0YSAocHJlcHJvY2Vzc2luZy8kYWMpIGFuZAppdCB3aWxsIHN1Y2sgdXAgYWxsIHRoZSBudW1iZXJzIGZvciBtZSBhdXRvbWFnaWNhbGx5LCBzbyBJIGRvIG5vdCBoYXZlCnRvIHdvcnJ5IGFueSBtb3JlIGFib3V0IGNvbGxlY3RpbmcgbWFwcGluZyBzdGF0aXN0aWNzIGFuZCBwb3RlbnRpYWxseQptZXNzaW5nIHRoZW0gdXAuICBPbmUgY2F2ZWF0OiB0aGUgclJOQSBjb2xsZWN0b3Igc3RpbGwgc29tZXRpbWVzIGdyYWJzCmdlbm9taWMgbnVtYmVycyBiZWNhdXNlIEkgZm9yZ290IHRvIGFkZCB0aGUgZ2Vub21lIHZhcmlhYmxlIHNvbWV3aGVyZQppbiB0aGUgbGFzdCB2ZXJzaW9uLi4uICBOb25ldGhlbGVzcywgSSB0aGluayB0aGF0IGlzIGF3ZXNvbWUgKEkgZXZlbgptYWRlIGl0IHNtcnQgZW5vdWdoIHRvIGhhbmRsZSBhIGNvbG9uIHNlcGFyYXRlZCBsaXN0IG9mIHNwZWNpZXMpLiAgT2gsCnRoaXMgcmVtaW5kcyBtZSwgSSBzaG91bGQgY2hlY2sgdGhhdCBteSBTLiBhdXJldXMgYW5kIGJyYXppbGllbnNpcwphc3NlbWJsaWVzIGFyZSB0aGUgc2FtZSBhcyB0aGUgb25lcyB0aGV5IHVzZWQuCgojIEJpYmxpb2dyYXBoeQo=