Code for trimming and QCing RNAseq data, to be used on Porites evermanni.

For now I’m just going to QC the raw reads and the trimmed reads generated as a part of the deep-dive project. If additional/different trimming needs to be done for this expression work, it will be performed here.

Inputs:

  • RNA-seq gzipped FastQs (e.g. *.fastq.gz)

Outputs:

  • FastQC HTML reports for raw and trimmed reads.

  • MultiQC HTML summaries of FastQC for raw and trimmed reads.

Sequencing report Trimming details


1 Create a Bash variables file

This allows usage of Bash variables (e.g. paths to common directories) across R Markdown chunks.

{
echo "#### Assign Variables ####"
echo ""

echo "# Data directories"
echo 'export expression_dir=/home/shared/8TB_HDD_02/shedurkin/expression'
echo 'export output_dir_top=${expression_dir}/E-Peve/output/01-Peve-RNA-trimming-FastQC'
echo 'export raw_fastqc_dir=${output_dir_top}/raw-fastqc'
echo 'export raw_reads_dir=${expression_dir}/E-Peve/data/01-Peve-RNA-trimming-FastQC/raw-reads'
echo 'export raw_reads_url="https://owl.fish.washington.edu/nightingales/P_evermanni/30-789513166/"'
echo 'export trimmed_fastqc_dir=${output_dir_top}/trimmed-fastqc'
echo 'export trimmed_reads_dir=${expression_dir}/E-Peve/data/01-Peve-RNA-trimming-FastQC/trimmed-reads'
echo 'export trimmed_reads_url="https://gannet.fish.washington.edu/Atumefaciens/20230519-E5_coral-fastqc-fastp-multiqc-RNAseq/P_evermanni/trimmed/"'
echo ""

echo "# Paths to programs"
echo 'export fastqc=/home/shared/FastQC-0.12.1/fastqc'
echo 'export multiqc=/home/sam/programs/mambaforge/bin/multiqc'
echo 'export flexbar=/home/shared/flexbar-3.5.0-linux/flexbar'
echo ""

echo "# Set FastQ filename patterns"
echo "export fastq_pattern='*.fastq.gz'"
echo "export R1_fastq_pattern='*_R1_*.fastq.gz'"
echo "export R2_fastq_pattern='*_R2_*.fastq.gz'"
echo ""

echo "# Set number of CPUs to use"
echo 'export threads=20'
echo ""

echo "# Input/output files"
echo 'export raw_checksums=checksums.md5'
echo 'export trimmed_checksums=trimmed_fastq_checksums.md5'
echo ""



echo "## Inititalize arrays"
echo 'export fastq_array_R1=()'
echo 'export fastq_array_R2=()'
echo 'export raw_fastqs_array=()'
echo 'export R1_names_array=()'
echo 'export R2_names_array=()'
echo 'export trimmed_fastqs_array=()'
echo ""

echo "# Programs associative array"
echo "declare -A programs_array"
echo "programs_array=("
echo '[fastqc]="${fastqc}" \'
echo '[multiqc]="${multiqc}" \'
echo '[flexbar]="${flexbar}"'
echo ")"
} > .bashvars

cat .bashvars
#### Assign Variables ####

# Data directories
export expression_dir=/home/shared/8TB_HDD_02/shedurkin/expression
export output_dir_top=${expression_dir}/E-Peve/output/01-Peve-RNA-trimming-FastQC
export raw_fastqc_dir=${output_dir_top}/raw-fastqc
export raw_reads_dir=${expression_dir}/E-Peve/data/01-Peve-RNA-trimming-FastQC/raw-reads
export raw_reads_url="https://owl.fish.washington.edu/nightingales/P_evermanni/30-789513166/"
export trimmed_fastqc_dir=${output_dir_top}/trimmed-fastqc
export trimmed_reads_dir=${expression_dir}/E-Peve/data/01-Peve-RNA-trimming-FastQC/trimmed-reads
export trimmed_reads_url="https://gannet.fish.washington.edu/Atumefaciens/20230519-E5_coral-fastqc-fastp-multiqc-RNAseq/P_evermanni/trimmed/"

# Paths to programs
export fastqc=/home/shared/FastQC-0.12.1/fastqc
export multiqc=/home/sam/programs/mambaforge/bin/multiqc
export flexbar=/home/shared/flexbar-3.5.0-linux/flexbar

# Set FastQ filename patterns
export fastq_pattern='*.fastq.gz'
export R1_fastq_pattern='*_R1_*.fastq.gz'
export R2_fastq_pattern='*_R2_*.fastq.gz'

# Set number of CPUs to use
export threads=20

# Input/output files
export raw_checksums=checksums.md5
export trimmed_checksums=trimmed_fastq_checksums.md5

## Inititalize arrays
export fastq_array_R1=()
export fastq_array_R2=()
export raw_fastqs_array=()
export R1_names_array=()
export R2_names_array=()
export trimmed_fastqs_array=()

# Programs associative array
declare -A programs_array
programs_array=(
[fastqc]="${fastqc}" \
[multiqc]="${multiqc}" \
[flexbar]="${flexbar}"
)

2 Raw reads

2.1 Download raw RNA-seq reads

Reads are downloaded from: https://owl.fish.washington.edu/nightingales/P_evermanni/30-789513166/

The --cut-dirs 3 command cuts the preceding directory structure (i.e. nightingales/P_evermanni/30-789513166/) so that we just end up with the reads.

# Load bash variables into memory
source .bashvars

wget \
--directory-prefix ${raw_reads_dir} \
--recursive \
--no-check-certificate \
--continue \
--cut-dirs 3 \
--no-host-directories \
--no-parent \
--quiet \
--accept ${fastq_pattern} ${raw_reads_url}
# Load bash variables into memory
source .bashvars

ls -lh "${raw_reads_dir}"
total 69G
-rw-r--r-- 1 shedurkin labmembers 1.3K May 17  2023 checksums.md5
-rw-r--r-- 1 shedurkin labmembers 3.5G May 16  2023 POR-71-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.6G May 16  2023 POR-71-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.4G May 16  2023 POR-73-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.5G May 16  2023 POR-73-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.4G May 16  2023 POR-76-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.5G May 16  2023 POR-76-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.3G May 16  2023 POR-79-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.4G May 16  2023 POR-79-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.4G May 16  2023 POR-82-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.6G May 16  2023 POR-82-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.5G May 17  2023 RNA-POR-71-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.6G May 17  2023 RNA-POR-71-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.4G May 17  2023 RNA-POR-73-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.5G May 17  2023 RNA-POR-73-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.4G May 17  2023 RNA-POR-76-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.5G May 17  2023 RNA-POR-76-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.3G May 17  2023 RNA-POR-79-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.4G May 17  2023 RNA-POR-79-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.4G May 17  2023 RNA-POR-82-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.6G May 17  2023 RNA-POR-82-S1-TP2_R2_001.fastq.gz

2.2 Verify raw read checksums

# Load bash variables into memory
source .bashvars

wget \
--directory-prefix ${raw_reads_dir} \
--recursive \
--no-check-certificate \
--continue \
--cut-dirs 3 \
--no-host-directories \
--no-parent \
--quiet \
--accept checksums.md5 ${raw_reads_url}

cd "${raw_reads_dir}"

md5sum checksums.md5 --check

2.3 FastQC/MultiQC on raw reads

# Load bash variables into memory
source .bashvars

############ RUN FASTQC ############


# Create array of raw FastQs
raw_fastqs_array=(${raw_reads_dir}/${fastq_pattern})

# Pass array contents to new variable as space-delimited list
raw_fastqc_list=$(echo "${raw_fastqs_array[*]}")

echo "Beginning FastQC on raw reads..."
echo ""

# Run FastQC
### NOTE: Do NOT quote raw_fastqc_list
${programs_array[fastqc]} \
--threads ${threads} \
--outdir ${raw_fastqc_dir} \
--quiet \
${raw_fastqc_list}

echo "FastQC on raw reads complete!"
echo ""

############ END FASTQC ############

############ RUN MULTIQC ############
echo "Beginning MultiQC on raw FastQC..."
echo ""

${programs_array[multiqc]} ${raw_fastqc_dir} -o ${raw_fastqc_dir}

echo ""
echo "MultiQC on raw FastQs complete."
echo ""

############ END MULTIQC ############

echo "Removing FastQC zip files."
echo ""
rm ${raw_fastqc_dir}/*.zip
echo "FastQC zip files removed."
echo ""
# Load bash variables into memory
source .bashvars

# View directory contents
ls -lh ${raw_fastqc_dir}
total 14M
drwxr-xr-x 2 shedurkin labmembers 4.0K Aug 20 15:08 multiqc_data
-rw-r--r-- 1 shedurkin labmembers 1.4M Aug 20 15:08 multiqc_report.html
-rw-r--r-- 1 shedurkin labmembers 603K Aug 20 15:07 POR-71-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 603K Aug 20 15:08 POR-71-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 613K Aug 20 15:08 POR-73-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 610K Aug 20 15:08 POR-73-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 609K Aug 20 15:07 POR-76-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 611K Aug 20 15:07 POR-76-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 617K Aug 20 15:07 POR-79-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 609K Aug 20 15:07 POR-79-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 605K Aug 20 15:07 POR-82-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 600K Aug 20 15:07 POR-82-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 603K Aug 20 15:08 RNA-POR-71-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 603K Aug 20 15:08 RNA-POR-71-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 613K Aug 20 15:08 RNA-POR-73-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 610K Aug 20 15:08 RNA-POR-73-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 609K Aug 20 15:07 RNA-POR-76-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 611K Aug 20 15:08 RNA-POR-76-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 617K Aug 20 15:07 RNA-POR-79-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 609K Aug 20 15:08 RNA-POR-79-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 605K Aug 20 15:07 RNA-POR-82-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 600K Aug 20 15:07 RNA-POR-82-S1-TP2_R2_001_fastqc.html

3 Trimmed reads

3.1 Download trimmed RNA-seq reads

Reads are downloaded from: https://gannet.fish.washington.edu/Atumefaciens/20230519-E5_coral-fastqc-fastp-multiqc-RNAseq/P_evermanni/trimmed/

# Load bash variables into memory
source .bashvars

wget \
--directory-prefix ${trimmed_reads_dir} \
--recursive \
--no-check-certificate \
--continue \
--cut-dirs 4 \
--no-host-directories \
--no-parent \
--quiet \
--accept ${fastq_pattern} ${trimmed_reads_url}
# Load bash variables into memory
source .bashvars

ls -lh "${trimmed_reads_dir}"
total 24G
drwxr-xr-x 2 shedurkin labmembers 4.0K Aug 20 15:09 multiqc_data
-rw-r--r-- 1 shedurkin labmembers 2.5G May 19  2023 RNA-POR-71-S1-TP2_R1_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.6G May 19  2023 RNA-POR-71-S1-TP2_R2_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.2G May 19  2023 RNA-POR-73-S1-TP2_R1_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.4G May 19  2023 RNA-POR-73-S1-TP2_R2_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.4G May 19  2023 RNA-POR-76-S1-TP2_R1_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.5G May 19  2023 RNA-POR-76-S1-TP2_R2_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.1G May 19  2023 RNA-POR-79-S1-TP2_R1_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.3G May 19  2023 RNA-POR-79-S1-TP2_R2_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.6G May 19  2023 RNA-POR-82-S1-TP2_R1_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.7G May 19  2023 RNA-POR-82-S1-TP2_R2_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers  880 May 19  2023 trimmed_fastq_checksums.md5

3.2 Verify raw read checksums

# Load bash variables into memory
source .bashvars

wget \
--directory-prefix ${trimmed_reads_dir} \
--recursive \
--no-check-certificate \
--continue \
--cut-dirs 4 \
--no-host-directories \
--no-parent \
--quiet \
--accept trimmed_fastq_checksums.md5 ${trimmed_reads_url}

cd "${trimmed_reads_dir}"

md5sum trimmed_fastq_checksums.md5 --check

3.3 FastQC/MultiQC on trimmed reads

# Load bash variables into memory
source .bashvars

############ RUN FASTQC ############

### NOTE: Do NOT quote raw_fastqc_list
# Create array of trimmed FastQs
trimmed_fastqs_array=(${trimmed_reads_dir}/${fastq_pattern})

# Pass array contents to new variable as space-delimited list
trimmed_fastqc_list=$(echo "${trimmed_fastqs_array[*]}")

echo "Beginning FastQC on raw reads..."
echo ""

# Run FastQC
${programs_array[fastqc]} \
--threads ${threads} \
--outdir ${trimmed_fastqc_dir} \
--quiet \
${trimmed_fastqc_list}

echo "FastQC on trimmed reads complete!"
echo ""

############ END FASTQC ############

############ RUN MULTIQC ############
echo "Beginning MultiQC on raw FastQC..."
echo ""

${programs_array[multiqc]} ${trimmed_fastqc_dir} -o ${trimmed_fastqc_dir}

echo ""
echo "MultiQC on trimmed FastQs complete."
echo ""

############ END MULTIQC ############

echo "Removing FastQC zip files."
echo ""
rm ${trimmed_fastqc_dir}/*.zip
echo "FastQC zip files removed."
echo ""
# Load bash variables into memory
source .bashvars

# View directory contents
ls -lh ${trimmed_fastqc_dir}
total 8.1M
drwxr-xr-x 2 shedurkin labmembers 4.0K Aug 20 15:19 multiqc_data
-rw-r--r-- 1 shedurkin labmembers 1.3M Aug 20 15:19 multiqc_report.html
-rw-r--r-- 1 shedurkin labmembers 685K Aug 20 15:19 RNA-POR-71-S1-TP2_R1_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 689K Aug 20 15:19 RNA-POR-71-S1-TP2_R2_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 701K Aug 20 15:19 RNA-POR-73-S1-TP2_R1_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 694K Aug 20 15:19 RNA-POR-73-S1-TP2_R2_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 696K Aug 20 15:19 RNA-POR-76-S1-TP2_R1_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 695K Aug 20 15:19 RNA-POR-76-S1-TP2_R2_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 704K Aug 20 15:19 RNA-POR-79-S1-TP2_R1_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 692K Aug 20 15:19 RNA-POR-79-S1-TP2_R2_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 687K Aug 20 15:19 RNA-POR-82-S1-TP2_R1_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 681K Aug 20 15:19 RNA-POR-82-S1-TP2_R2_001.fastp-trim.20230519_fastqc.html

4 Summary

LS0tCnRpdGxlOiAiMDEtUGV2ZS1STkEtdHJpbW1pbmctRmFzdFFDIgphdXRob3I6ICJLYXRobGVlbiBEdXJraW4iCmRhdGU6ICIyMDI0LTA4LTIwIgphbHdheXNfYWxsb3dfaHRtbDogdHJ1ZQpvdXRwdXQ6IAogIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjoKICAgIHRoZW1lOiBjb3NtbwogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgZ2l0aHViX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgaHRtbF9wcmV2aWV3OiB0cnVlIAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IFRSVUUsICAgICAgICAgIyBEaXNwbGF5IGNvZGUgY2h1bmtzCiAgZXZhbCA9IEZBTFNFLCAgICAgICAgIyBFdmFsdWF0ZSBjb2RlIGNodW5rcwogIHdhcm5pbmcgPSBGQUxTRSwgICAgICMgSGlkZSB3YXJuaW5ncwogIG1lc3NhZ2UgPSBGQUxTRSwgICAgICMgSGlkZSBtZXNzYWdlcwogIGNvbW1lbnQgPSAiIiAgICAgICAgICMgUHJldmVudHMgYXBwZW5kaW5nICcjIycgdG8gYmVnaW5uaW5nIG9mIGxpbmVzIGluIGNvZGUgb3V0cHV0CikKYGBgCgpDb2RlIGZvciB0cmltbWluZyBhbmQgUUNpbmcgUk5Bc2VxIGRhdGEsIHRvIGJlIHVzZWQgb24gKlBvcml0ZXMgZXZlcm1hbm5pKi4KCgpGb3Igbm93IEknbSBqdXN0IGdvaW5nIHRvIFFDIHRoZSBbcmF3IHJlYWRzXShodHRwczovL293bC5maXNoLndhc2hpbmd0b24uZWR1L25pZ2h0aW5nYWxlcy9QX2V2ZXJtYW5uaS8zMC03ODk1MTMxNjYvKSBhbmQgdGhlIFt0cmltbWVkIHJlYWRzXShodHRwczovL2dhbm5ldC5maXNoLndhc2hpbmd0b24uZWR1L0F0dW1lZmFjaWVucy8yMDIzMDUxOS1FNV9jb3JhbC1mYXN0cWMtZmFzdHAtbXVsdGlxYy1STkFzZXEvUF9ldmVybWFubmkvdHJpbW1lZC8pIGdlbmVyYXRlZCBhcyBhIHBhcnQgb2YgdGhlIFtkZWVwLWRpdmVdKGh0dHBzOi8vZ2l0aHViLmNvbS91cm9sLWU1L2RlZXAtZGl2ZS90cmVlL21haW4pIHByb2plY3QuIElmIGFkZGl0aW9uYWwvZGlmZmVyZW50IHRyaW1taW5nIG5lZWRzIHRvIGJlIGRvbmUgZm9yIHRoaXMgZXhwcmVzc2lvbiB3b3JrLCBpdCB3aWxsIGJlIHBlcmZvcm1lZCBoZXJlLgoKCklucHV0czoKCi0gUk5BLXNlcSBnemlwcGVkIEZhc3RRcyAoZS5nLiBgKi5mYXN0cS5nemApCgpPdXRwdXRzOgoKLSBbYEZhc3RRQ2BdKGh0dHBzOi8vd3d3LmJpb2luZm9ybWF0aWNzLmJhYnJhaGFtLmFjLnVrL3Byb2plY3RzL2Zhc3RxYy8pIEhUTUwgcmVwb3J0cyBmb3IgcmF3IGFuZCB0cmltbWVkIHJlYWRzLgoKLSBbYE11bHRpUUNgXShodHRwczovL211bHRpcWMuaW5mby8pIEhUTUwgc3VtbWFyaWVzIG9mIFtgRmFzdFFDYF0oaHR0cHM6Ly93d3cuYmlvaW5mb3JtYXRpY3MuYmFicmFoYW0uYWMudWsvcHJvamVjdHMvZmFzdHFjLykgZm9yIHJhdyBhbmQgdHJpbW1lZCByZWFkcy4KCgpbU2VxdWVuY2luZyByZXBvcnRdKGh0dHBzOi8vZ2l0aHViLmNvbS91cm9sLWU1L2RlZXAtZGl2ZS93aWtpL0F6ZW50YV8zMC03ODk1MTMxNjZfRGF0YV9SZXBvcnQuaHRtbCkKW1RyaW1taW5nIGRldGFpbHNdKGh0dHBzOi8vcm9iZXJ0c2xhYi5naXRodWIuaW8vc2Ftcy1ub3RlYm9vay9wb3N0cy8yMDIzLzIwMjMtMDUtMTktRmFzdFEtUUMtYW5kLVRyaW1taW5nLS0tRTUtQ29yYWwtUk5BLXNlcS1EYXRhLWZvci1BLnB1bGNocmEtUC5ldmVybWFubmktYW5kLVAubWVhbmRyaW5hLVVzaW5nLUZhc3RRQy1mYXN0cC1hbmQtTXVsdGlRQy1vbi1Nb3gvKQoKLS0tCgojIENyZWF0ZSBhIEJhc2ggdmFyaWFibGVzIGZpbGUKClRoaXMgYWxsb3dzIHVzYWdlIG9mIEJhc2ggdmFyaWFibGVzIChlLmcuIHBhdGhzIHRvIGNvbW1vbiBkaXJlY3RvcmllcykgYWNyb3NzIFIgTWFya2Rvd24gY2h1bmtzLgpgYGB7ciBzYXZlLWJhc2gtdmFyaWFibGVzLXRvLXJ2YXJzLWZpbGUsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KewplY2hvICIjIyMjIEFzc2lnbiBWYXJpYWJsZXMgIyMjIyIKZWNobyAiIgoKZWNobyAiIyBEYXRhIGRpcmVjdG9yaWVzIgplY2hvICdleHBvcnQgZXhwcmVzc2lvbl9kaXI9L2hvbWUvc2hhcmVkLzhUQl9IRERfMDIvc2hlZHVya2luL2V4cHJlc3Npb24nCmVjaG8gJ2V4cG9ydCBvdXRwdXRfZGlyX3RvcD0ke2V4cHJlc3Npb25fZGlyfS9FLVBldmUvb3V0cHV0LzAxLVBldmUtUk5BLXRyaW1taW5nLUZhc3RRQycKZWNobyAnZXhwb3J0IHJhd19mYXN0cWNfZGlyPSR7b3V0cHV0X2Rpcl90b3B9L3Jhdy1mYXN0cWMnCmVjaG8gJ2V4cG9ydCByYXdfcmVhZHNfZGlyPSR7ZXhwcmVzc2lvbl9kaXJ9L0UtUGV2ZS9kYXRhLzAxLVBldmUtUk5BLXRyaW1taW5nLUZhc3RRQy9yYXctcmVhZHMnCmVjaG8gJ2V4cG9ydCByYXdfcmVhZHNfdXJsPSJodHRwczovL293bC5maXNoLndhc2hpbmd0b24uZWR1L25pZ2h0aW5nYWxlcy9QX2V2ZXJtYW5uaS8zMC03ODk1MTMxNjYvIicKZWNobyAnZXhwb3J0IHRyaW1tZWRfZmFzdHFjX2Rpcj0ke291dHB1dF9kaXJfdG9wfS90cmltbWVkLWZhc3RxYycKZWNobyAnZXhwb3J0IHRyaW1tZWRfcmVhZHNfZGlyPSR7ZXhwcmVzc2lvbl9kaXJ9L0UtUGV2ZS9kYXRhLzAxLVBldmUtUk5BLXRyaW1taW5nLUZhc3RRQy90cmltbWVkLXJlYWRzJwplY2hvICdleHBvcnQgdHJpbW1lZF9yZWFkc191cmw9Imh0dHBzOi8vZ2FubmV0LmZpc2gud2FzaGluZ3Rvbi5lZHUvQXR1bWVmYWNpZW5zLzIwMjMwNTE5LUU1X2NvcmFsLWZhc3RxYy1mYXN0cC1tdWx0aXFjLVJOQXNlcS9QX2V2ZXJtYW5uaS90cmltbWVkLyInCmVjaG8gIiIKCmVjaG8gIiMgUGF0aHMgdG8gcHJvZ3JhbXMiCmVjaG8gJ2V4cG9ydCBmYXN0cWM9L2hvbWUvc2hhcmVkL0Zhc3RRQy0wLjEyLjEvZmFzdHFjJwplY2hvICdleHBvcnQgbXVsdGlxYz0vaG9tZS9zYW0vcHJvZ3JhbXMvbWFtYmFmb3JnZS9iaW4vbXVsdGlxYycKZWNobyAnZXhwb3J0IGZsZXhiYXI9L2hvbWUvc2hhcmVkL2ZsZXhiYXItMy41LjAtbGludXgvZmxleGJhcicKZWNobyAiIgoKZWNobyAiIyBTZXQgRmFzdFEgZmlsZW5hbWUgcGF0dGVybnMiCmVjaG8gImV4cG9ydCBmYXN0cV9wYXR0ZXJuPScqLmZhc3RxLmd6JyIKZWNobyAiZXhwb3J0IFIxX2Zhc3RxX3BhdHRlcm49JypfUjFfKi5mYXN0cS5neiciCmVjaG8gImV4cG9ydCBSMl9mYXN0cV9wYXR0ZXJuPScqX1IyXyouZmFzdHEuZ3onIgplY2hvICIiCgplY2hvICIjIFNldCBudW1iZXIgb2YgQ1BVcyB0byB1c2UiCmVjaG8gJ2V4cG9ydCB0aHJlYWRzPTIwJwplY2hvICIiCgplY2hvICIjIElucHV0L291dHB1dCBmaWxlcyIKZWNobyAnZXhwb3J0IHJhd19jaGVja3N1bXM9Y2hlY2tzdW1zLm1kNScKZWNobyAnZXhwb3J0IHRyaW1tZWRfY2hlY2tzdW1zPXRyaW1tZWRfZmFzdHFfY2hlY2tzdW1zLm1kNScKZWNobyAiIgoKCgplY2hvICIjIyBJbml0aXRhbGl6ZSBhcnJheXMiCmVjaG8gJ2V4cG9ydCBmYXN0cV9hcnJheV9SMT0oKScKZWNobyAnZXhwb3J0IGZhc3RxX2FycmF5X1IyPSgpJwplY2hvICdleHBvcnQgcmF3X2Zhc3Rxc19hcnJheT0oKScKZWNobyAnZXhwb3J0IFIxX25hbWVzX2FycmF5PSgpJwplY2hvICdleHBvcnQgUjJfbmFtZXNfYXJyYXk9KCknCmVjaG8gJ2V4cG9ydCB0cmltbWVkX2Zhc3Rxc19hcnJheT0oKScKZWNobyAiIgoKZWNobyAiIyBQcm9ncmFtcyBhc3NvY2lhdGl2ZSBhcnJheSIKZWNobyAiZGVjbGFyZSAtQSBwcm9ncmFtc19hcnJheSIKZWNobyAicHJvZ3JhbXNfYXJyYXk9KCIKZWNobyAnW2Zhc3RxY109IiR7ZmFzdHFjfSIgXCcKZWNobyAnW211bHRpcWNdPSIke211bHRpcWN9IiBcJwplY2hvICdbZmxleGJhcl09IiR7ZmxleGJhcn0iJwplY2hvICIpIgp9ID4gLmJhc2h2YXJzCgpjYXQgLmJhc2h2YXJzCmBgYAoKCiMgUmF3IHJlYWRzCiMjIERvd25sb2FkIHJhdyBSTkEtc2VxIHJlYWRzCgpSZWFkcyBhcmUgZG93bmxvYWRlZCBmcm9tOiBodHRwczovL293bC5maXNoLndhc2hpbmd0b24uZWR1L25pZ2h0aW5nYWxlcy9QX2V2ZXJtYW5uaS8zMC03ODk1MTMxNjYvCgpUaGUgYC0tY3V0LWRpcnMgM2AgY29tbWFuZCBjdXRzIHRoZSBwcmVjZWRpbmcgZGlyZWN0b3J5IHN0cnVjdHVyZSAoaS5lLiBgbmlnaHRpbmdhbGVzL1BfZXZlcm1hbm5pLzMwLTc4OTUxMzE2Ni9gKSBzbyB0aGF0IHdlIGp1c3QgZW5kIHVwIHdpdGggdGhlIHJlYWRzLgoKYGBge3IgZG93bmxvYWQtcmF3LXJlYWRzLCBlbmdpbmU9J2Jhc2gnfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKd2dldCBcCi0tZGlyZWN0b3J5LXByZWZpeCAke3Jhd19yZWFkc19kaXJ9IFwKLS1yZWN1cnNpdmUgXAotLW5vLWNoZWNrLWNlcnRpZmljYXRlIFwKLS1jb250aW51ZSBcCi0tY3V0LWRpcnMgMyBcCi0tbm8taG9zdC1kaXJlY3RvcmllcyBcCi0tbm8tcGFyZW50IFwKLS1xdWlldCBcCi0tYWNjZXB0ICR7ZmFzdHFfcGF0dGVybn0gJHtyYXdfcmVhZHNfdXJsfQpgYGAKCmBgYHtyIGNoZWNrLXJhdy1yZWFkcywgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKbHMgLWxoICIke3Jhd19yZWFkc19kaXJ9IgpgYGAKCiMjIFZlcmlmeSByYXcgcmVhZCBjaGVja3N1bXMKYGBge3IgdmVyaWZ5LXJhdy1yZWFkLWNoZWNrc3VtcywgZW5naW5lPSdiYXNoJ30KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCndnZXQgXAotLWRpcmVjdG9yeS1wcmVmaXggJHtyYXdfcmVhZHNfZGlyfSBcCi0tcmVjdXJzaXZlIFwKLS1uby1jaGVjay1jZXJ0aWZpY2F0ZSBcCi0tY29udGludWUgXAotLWN1dC1kaXJzIDMgXAotLW5vLWhvc3QtZGlyZWN0b3JpZXMgXAotLW5vLXBhcmVudCBcCi0tcXVpZXQgXAotLWFjY2VwdCBjaGVja3N1bXMubWQ1ICR7cmF3X3JlYWRzX3VybH0KCmNkICIke3Jhd19yZWFkc19kaXJ9IgoKbWQ1c3VtIGNoZWNrc3Vtcy5tZDUgLS1jaGVjawpgYGAKCgojIyBGYXN0UUMvTXVsdGlRQyBvbiByYXcgcmVhZHMKYGBge3IgcmF3LWZhc3RxYy1tdWx0aXFjLCBlbmdpbmU9J2Jhc2gnfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKIyMjIyMjIyMjIyMjIFJVTiBGQVNUUUMgIyMjIyMjIyMjIyMjCgoKIyBDcmVhdGUgYXJyYXkgb2YgcmF3IEZhc3RRcwpyYXdfZmFzdHFzX2FycmF5PSgke3Jhd19yZWFkc19kaXJ9LyR7ZmFzdHFfcGF0dGVybn0pCgojIFBhc3MgYXJyYXkgY29udGVudHMgdG8gbmV3IHZhcmlhYmxlIGFzIHNwYWNlLWRlbGltaXRlZCBsaXN0CnJhd19mYXN0cWNfbGlzdD0kKGVjaG8gIiR7cmF3X2Zhc3Rxc19hcnJheVsqXX0iKQoKZWNobyAiQmVnaW5uaW5nIEZhc3RRQyBvbiByYXcgcmVhZHMuLi4iCmVjaG8gIiIKCiMgUnVuIEZhc3RRQwojIyMgTk9URTogRG8gTk9UIHF1b3RlIHJhd19mYXN0cWNfbGlzdAoke3Byb2dyYW1zX2FycmF5W2Zhc3RxY119IFwKLS10aHJlYWRzICR7dGhyZWFkc30gXAotLW91dGRpciAke3Jhd19mYXN0cWNfZGlyfSBcCi0tcXVpZXQgXAoke3Jhd19mYXN0cWNfbGlzdH0KCmVjaG8gIkZhc3RRQyBvbiByYXcgcmVhZHMgY29tcGxldGUhIgplY2hvICIiCgojIyMjIyMjIyMjIyMgRU5EIEZBU1RRQyAjIyMjIyMjIyMjIyMKCiMjIyMjIyMjIyMjIyBSVU4gTVVMVElRQyAjIyMjIyMjIyMjIyMKZWNobyAiQmVnaW5uaW5nIE11bHRpUUMgb24gcmF3IEZhc3RRQy4uLiIKZWNobyAiIgoKJHtwcm9ncmFtc19hcnJheVttdWx0aXFjXX0gJHtyYXdfZmFzdHFjX2Rpcn0gLW8gJHtyYXdfZmFzdHFjX2Rpcn0KCmVjaG8gIiIKZWNobyAiTXVsdGlRQyBvbiByYXcgRmFzdFFzIGNvbXBsZXRlLiIKZWNobyAiIgoKIyMjIyMjIyMjIyMjIEVORCBNVUxUSVFDICMjIyMjIyMjIyMjIwoKZWNobyAiUmVtb3ZpbmcgRmFzdFFDIHppcCBmaWxlcy4iCmVjaG8gIiIKcm0gJHtyYXdfZmFzdHFjX2Rpcn0vKi56aXAKZWNobyAiRmFzdFFDIHppcCBmaWxlcyByZW1vdmVkLiIKZWNobyAiIgpgYGAKCgpgYGB7ciBjaGVjay1yYXctcmVhZHMtUUMtZmlsZXMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCiMgVmlldyBkaXJlY3RvcnkgY29udGVudHMKbHMgLWxoICR7cmF3X2Zhc3RxY19kaXJ9CmBgYAoKCiMgVHJpbW1lZCByZWFkcwojIyBEb3dubG9hZCB0cmltbWVkIFJOQS1zZXEgcmVhZHMKClJlYWRzIGFyZSBkb3dubG9hZGVkIGZyb206IGh0dHBzOi8vZ2FubmV0LmZpc2gud2FzaGluZ3Rvbi5lZHUvQXR1bWVmYWNpZW5zLzIwMjMwNTE5LUU1X2NvcmFsLWZhc3RxYy1mYXN0cC1tdWx0aXFjLVJOQXNlcS9QX2V2ZXJtYW5uaS90cmltbWVkLwoKYGBge3IgZG93bmxvYWQtdHJpbW1lZC1yZWFkcywgZW5naW5lPSdiYXNoJ30KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCndnZXQgXAotLWRpcmVjdG9yeS1wcmVmaXggJHt0cmltbWVkX3JlYWRzX2Rpcn0gXAotLXJlY3Vyc2l2ZSBcCi0tbm8tY2hlY2stY2VydGlmaWNhdGUgXAotLWNvbnRpbnVlIFwKLS1jdXQtZGlycyA0IFwKLS1uby1ob3N0LWRpcmVjdG9yaWVzIFwKLS1uby1wYXJlbnQgXAotLXF1aWV0IFwKLS1hY2NlcHQgJHtmYXN0cV9wYXR0ZXJufSAke3RyaW1tZWRfcmVhZHNfdXJsfQpgYGAKCmBgYHtyIGNoZWNrLXRyaW1tZWQtcmVhZHMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCmxzIC1saCAiJHt0cmltbWVkX3JlYWRzX2Rpcn0iCmBgYAoKIyMgVmVyaWZ5IHJhdyByZWFkIGNoZWNrc3VtcwpgYGB7ciB2ZXJpZnktdHJpbW1lZC1yZWFkLWNoZWNrc3VtcywgZW5naW5lPSdiYXNoJ30KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCndnZXQgXAotLWRpcmVjdG9yeS1wcmVmaXggJHt0cmltbWVkX3JlYWRzX2Rpcn0gXAotLXJlY3Vyc2l2ZSBcCi0tbm8tY2hlY2stY2VydGlmaWNhdGUgXAotLWNvbnRpbnVlIFwKLS1jdXQtZGlycyA0IFwKLS1uby1ob3N0LWRpcmVjdG9yaWVzIFwKLS1uby1wYXJlbnQgXAotLXF1aWV0IFwKLS1hY2NlcHQgdHJpbW1lZF9mYXN0cV9jaGVja3N1bXMubWQ1ICR7dHJpbW1lZF9yZWFkc191cmx9CgpjZCAiJHt0cmltbWVkX3JlYWRzX2Rpcn0iCgptZDVzdW0gdHJpbW1lZF9mYXN0cV9jaGVja3N1bXMubWQ1IC0tY2hlY2sKYGBgCgoKIyMgRmFzdFFDL011bHRpUUMgb24gdHJpbW1lZCByZWFkcwoKYGBge3IgRmFzdFFDLU11bHRpUUMtdHJpbW1lZC1yZWFkcywgZW5naW5lPSdiYXNoJ30KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCiMjIyMjIyMjIyMjIyBSVU4gRkFTVFFDICMjIyMjIyMjIyMjIwoKIyMjIE5PVEU6IERvIE5PVCBxdW90ZSByYXdfZmFzdHFjX2xpc3QKIyBDcmVhdGUgYXJyYXkgb2YgdHJpbW1lZCBGYXN0UXMKdHJpbW1lZF9mYXN0cXNfYXJyYXk9KCR7dHJpbW1lZF9yZWFkc19kaXJ9LyR7ZmFzdHFfcGF0dGVybn0pCgojIFBhc3MgYXJyYXkgY29udGVudHMgdG8gbmV3IHZhcmlhYmxlIGFzIHNwYWNlLWRlbGltaXRlZCBsaXN0CnRyaW1tZWRfZmFzdHFjX2xpc3Q9JChlY2hvICIke3RyaW1tZWRfZmFzdHFzX2FycmF5WypdfSIpCgplY2hvICJCZWdpbm5pbmcgRmFzdFFDIG9uIHJhdyByZWFkcy4uLiIKZWNobyAiIgoKIyBSdW4gRmFzdFFDCiR7cHJvZ3JhbXNfYXJyYXlbZmFzdHFjXX0gXAotLXRocmVhZHMgJHt0aHJlYWRzfSBcCi0tb3V0ZGlyICR7dHJpbW1lZF9mYXN0cWNfZGlyfSBcCi0tcXVpZXQgXAoke3RyaW1tZWRfZmFzdHFjX2xpc3R9CgplY2hvICJGYXN0UUMgb24gdHJpbW1lZCByZWFkcyBjb21wbGV0ZSEiCmVjaG8gIiIKCiMjIyMjIyMjIyMjIyBFTkQgRkFTVFFDICMjIyMjIyMjIyMjIwoKIyMjIyMjIyMjIyMjIFJVTiBNVUxUSVFDICMjIyMjIyMjIyMjIwplY2hvICJCZWdpbm5pbmcgTXVsdGlRQyBvbiByYXcgRmFzdFFDLi4uIgplY2hvICIiCgoke3Byb2dyYW1zX2FycmF5W211bHRpcWNdfSAke3RyaW1tZWRfZmFzdHFjX2Rpcn0gLW8gJHt0cmltbWVkX2Zhc3RxY19kaXJ9CgplY2hvICIiCmVjaG8gIk11bHRpUUMgb24gdHJpbW1lZCBGYXN0UXMgY29tcGxldGUuIgplY2hvICIiCgojIyMjIyMjIyMjIyMgRU5EIE1VTFRJUUMgIyMjIyMjIyMjIyMjCgplY2hvICJSZW1vdmluZyBGYXN0UUMgemlwIGZpbGVzLiIKZWNobyAiIgpybSAke3RyaW1tZWRfZmFzdHFjX2Rpcn0vKi56aXAKZWNobyAiRmFzdFFDIHppcCBmaWxlcyByZW1vdmVkLiIKZWNobyAiIgpgYGAKCmBgYHtyIHZpZXctdHJpbW1lZC1yZWFkcy1RQy1maWxlcywgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKIyBWaWV3IGRpcmVjdG9yeSBjb250ZW50cwpscyAtbGggJHt0cmltbWVkX2Zhc3RxY19kaXJ9CmBgYAoKIyBTdW1tYXJ5