Code for trimming and QCing RNAseq data, to be used on Acropora pulchra.

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}/D-Apul/output/01-Apul-RNA-trimming-FastQC'
echo 'export raw_fastqc_dir=${output_dir_top}/raw-fastqc'
echo 'export raw_reads_dir=${expression_dir}/D-Apul/data/01-Apul-RNA-trimming-FastQC/raw-reads'
echo 'export raw_reads_url="https://owl.fish.washington.edu/nightingales/A_pulchra/30-789513166/"'
echo 'export trimmed_fastqc_dir=${output_dir_top}/trimmed-fastqc'
echo 'export trimmed_reads_dir=${expression_dir}/D-Apul/data/01-Apul-RNA-trimming-FastQC/trimmed-reads'
echo 'export trimmed_reads_url="https://gannet.fish.washington.edu/Atumefaciens/20230519-E5_coral-fastqc-fastp-multiqc-RNAseq/A_pulchra/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}/D-Apul/output/01-Apul-RNA-trimming-FastQC
export raw_fastqc_dir=${output_dir_top}/raw-fastqc
export raw_reads_dir=${expression_dir}/D-Apul/data/01-Apul-RNA-trimming-FastQC/raw-reads
export raw_reads_url="https://owl.fish.washington.edu/nightingales/A_pulchra/30-789513166/"
export trimmed_fastqc_dir=${output_dir_top}/trimmed-fastqc
export trimmed_reads_dir=${expression_dir}/D-Apul/data/01-Apul-RNA-trimming-FastQC/trimmed-reads
export trimmed_reads_url="https://gannet.fish.washington.edu/Atumefaciens/20230519-E5_coral-fastqc-fastp-multiqc-RNAseq/A_pulchra/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/A_pulchra/30-789513166/

The --cut-dirs 3 command cuts the preceding directory structure (i.e. nightingales/A_pulchra/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 66G
-rw-r--r-- 1 shedurkin labmembers 3.5G May 16  2023 ACR-140-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.6G May 16  2023 ACR-140-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.1G May 16  2023 ACR-145-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.2G May 16  2023 ACR-145-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.2G May 16  2023 ACR-150-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.3G May 16  2023 ACR-150-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.5G May 16  2023 ACR-173-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.6G May 16  2023 ACR-173-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.1G May 16  2023 ACR-178-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.2G May 16  2023 ACR-178-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 1.4K May 17  2023 checksums.md5
-rw-r--r-- 1 shedurkin labmembers 3.5G May 17  2023 RNA-ACR-140-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.6G May 17  2023 RNA-ACR-140-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.1G May 17  2023 RNA-ACR-145-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.2G May 17  2023 RNA-ACR-145-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.2G May 17  2023 RNA-ACR-150-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.3G May 17  2023 RNA-ACR-150-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.5G May 17  2023 RNA-ACR-173-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.6G May 17  2023 RNA-ACR-173-S1-TP2_R2_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.1G May 17  2023 RNA-ACR-178-S1-TP2_R1_001.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.2G May 17  2023 RNA-ACR-178-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 13M
-rw-r--r-- 1 shedurkin labmembers 593K Aug 19 15:17 ACR-140-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 593K Aug 19 15:17 ACR-140-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 595K Aug 19 15:16 ACR-145-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 594K Aug 19 15:16 ACR-145-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 597K Aug 19 15:16 ACR-150-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 597K Aug 19 15:16 ACR-150-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 597K Aug 19 15:17 ACR-173-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 596K Aug 19 15:17 ACR-173-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 592K Aug 19 15:16 ACR-178-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 598K Aug 19 15:16 ACR-178-S1-TP2_R2_001_fastqc.html
drwxr-xr-x 2 shedurkin labmembers 4.0K Aug 19 15:17 multiqc_data
-rw-r--r-- 1 shedurkin labmembers 1.4M Aug 19 15:17 multiqc_report.html
-rw-r--r-- 1 shedurkin labmembers 593K Aug 19 15:17 RNA-ACR-140-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 593K Aug 19 15:17 RNA-ACR-140-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 595K Aug 19 15:16 RNA-ACR-145-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 594K Aug 19 15:16 RNA-ACR-145-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 597K Aug 19 15:16 RNA-ACR-150-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 597K Aug 19 15:17 RNA-ACR-150-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 597K Aug 19 15:17 RNA-ACR-173-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 596K Aug 19 15:17 RNA-ACR-173-S1-TP2_R2_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 592K Aug 19 15:16 RNA-ACR-178-S1-TP2_R1_001_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 598K Aug 19 15:16 RNA-ACR-178-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/A_pulchra/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 27G
-rw-r--r-- 1 shedurkin labmembers 2.9G May 19  2023 RNA-ACR-140-S1-TP2_R1_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.0G May 19  2023 RNA-ACR-140-S1-TP2_R2_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.6G May 19  2023 RNA-ACR-145-S1-TP2_R1_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.6G May 19  2023 RNA-ACR-145-S1-TP2_R2_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.6G May 19  2023 RNA-ACR-150-S1-TP2_R1_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.7G May 19  2023 RNA-ACR-150-S1-TP2_R2_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.9G May 19  2023 RNA-ACR-173-S1-TP2_R1_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 3.0G May 19  2023 RNA-ACR-173-S1-TP2_R2_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.6G May 19  2023 RNA-ACR-178-S1-TP2_R1_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers 2.7G May 19  2023 RNA-ACR-178-S1-TP2_R2_001.fastp-trim.20230519.fastq.gz
-rw-r--r-- 1 shedurkin labmembers  890 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 7.9M
drwxr-xr-x 2 shedurkin labmembers 4.0K Aug 19 16:50 multiqc_data
-rw-r--r-- 1 shedurkin labmembers 1.3M Aug 19 16:50 multiqc_report.html
-rw-r--r-- 1 shedurkin labmembers 666K Aug 19 16:50 RNA-ACR-140-S1-TP2_R1_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 671K Aug 19 16:50 RNA-ACR-140-S1-TP2_R2_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 671K Aug 19 16:50 RNA-ACR-145-S1-TP2_R1_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 668K Aug 19 16:50 RNA-ACR-145-S1-TP2_R2_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 676K Aug 19 16:50 RNA-ACR-150-S1-TP2_R1_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 674K Aug 19 16:50 RNA-ACR-150-S1-TP2_R2_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 671K Aug 19 16:50 RNA-ACR-173-S1-TP2_R1_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 669K Aug 19 16:50 RNA-ACR-173-S1-TP2_R2_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 669K Aug 19 16:50 RNA-ACR-178-S1-TP2_R1_001.fastp-trim.20230519_fastqc.html
-rw-r--r-- 1 shedurkin labmembers 675K Aug 19 16:50 RNA-ACR-178-S1-TP2_R2_001.fastp-trim.20230519_fastqc.html

4 Summary

LS0tCnRpdGxlOiAiMDEtQXB1bC1STkEtdHJpbW1pbmctRmFzdFFDIgphdXRob3I6ICJLYXRobGVlbiBEdXJraW4iCmRhdGU6ICIyMDI0LTA4LTE5IgphbHdheXNfYWxsb3dfaHRtbDogdHJ1ZQpvdXRwdXQ6IAogIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjoKICAgIHRoZW1lOiBjb3NtbwogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgZ2l0aHViX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgaHRtbF9wcmV2aWV3OiB0cnVlIAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IFRSVUUsICAgICAgICAgIyBEaXNwbGF5IGNvZGUgY2h1bmtzCiAgZXZhbCA9IEZBTFNFLCAgICAgICAgIyBFdmFsdWF0ZSBjb2RlIGNodW5rcwogIHdhcm5pbmcgPSBGQUxTRSwgICAgICMgSGlkZSB3YXJuaW5ncwogIG1lc3NhZ2UgPSBGQUxTRSwgICAgICMgSGlkZSBtZXNzYWdlcwogIGNvbW1lbnQgPSAiIiAgICAgICAgICMgUHJldmVudHMgYXBwZW5kaW5nICcjIycgdG8gYmVnaW5uaW5nIG9mIGxpbmVzIGluIGNvZGUgb3V0cHV0CikKYGBgCgpDb2RlIGZvciB0cmltbWluZyBhbmQgUUNpbmcgUk5Bc2VxIGRhdGEsIHRvIGJlIHVzZWQgb24gKkFjcm9wb3JhIHB1bGNocmEqLgoKCkZvciBub3cgSSdtIGp1c3QgZ29pbmcgdG8gUUMgdGhlIFtyYXcgcmVhZHNdKGh0dHBzOi8vb3dsLmZpc2gud2FzaGluZ3Rvbi5lZHUvbmlnaHRpbmdhbGVzL0FfcHVsY2hyYS8zMC03ODk1MTMxNjYvKSBhbmQgdGhlIFt0cmltbWVkIHJlYWRzXShodHRwczovL2dhbm5ldC5maXNoLndhc2hpbmd0b24uZWR1L0F0dW1lZmFjaWVucy8yMDIzMDUxOS1FNV9jb3JhbC1mYXN0cWMtZmFzdHAtbXVsdGlxYy1STkFzZXEvQV9wdWxjaHJhL3RyaW1tZWQvKSBnZW5lcmF0ZWQgYXMgYSBwYXJ0IG9mIHRoZSBbZGVlcC1kaXZlXShodHRwczovL2dpdGh1Yi5jb20vdXJvbC1lNS9kZWVwLWRpdmUvdHJlZS9tYWluKSBwcm9qZWN0LiBJZiBhZGRpdGlvbmFsL2RpZmZlcmVudCB0cmltbWluZyBuZWVkcyB0byBiZSBkb25lIGZvciB0aGlzIGV4cHJlc3Npb24gd29yaywgaXQgd2lsbCBiZSBwZXJmb3JtZWQgaGVyZS4KCgpJbnB1dHM6CgotIFJOQS1zZXEgZ3ppcHBlZCBGYXN0UXMgKGUuZy4gYCouZmFzdHEuZ3pgKQoKT3V0cHV0czoKCi0gW2BGYXN0UUNgXShodHRwczovL3d3dy5iaW9pbmZvcm1hdGljcy5iYWJyYWhhbS5hYy51ay9wcm9qZWN0cy9mYXN0cWMvKSBIVE1MIHJlcG9ydHMgZm9yIHJhdyBhbmQgdHJpbW1lZCByZWFkcy4KCi0gW2BNdWx0aVFDYF0oaHR0cHM6Ly9tdWx0aXFjLmluZm8vKSBIVE1MIHN1bW1hcmllcyBvZiBbYEZhc3RRQ2BdKGh0dHBzOi8vd3d3LmJpb2luZm9ybWF0aWNzLmJhYnJhaGFtLmFjLnVrL3Byb2plY3RzL2Zhc3RxYy8pIGZvciByYXcgYW5kIHRyaW1tZWQgcmVhZHMuCgoKW1NlcXVlbmNpbmcgcmVwb3J0XShodHRwczovL293bC5maXNoLndhc2hpbmd0b24uZWR1L25pZ2h0aW5nYWxlcy9QX2V2ZXJtYW5uaS8zMC03ODk1MTMxNjYvQXplbnRhXzMwLTc4OTUxMzE2Nl9EYXRhX1JlcG9ydC5odG1sKQpbVHJpbW1pbmcgZGV0YWlsc10oaHR0cHM6Ly9yb2JlcnRzbGFiLmdpdGh1Yi5pby9zYW1zLW5vdGVib29rL3Bvc3RzLzIwMjMvMjAyMy0wNS0xOS1GYXN0US1RQy1hbmQtVHJpbW1pbmctLS1FNS1Db3JhbC1STkEtc2VxLURhdGEtZm9yLUEucHVsY2hyYS1QLmV2ZXJtYW5uaS1hbmQtUC5tZWFuZHJpbmEtVXNpbmctRmFzdFFDLWZhc3RwLWFuZC1NdWx0aVFDLW9uLU1veC8pCgotLS0KCiMgQ3JlYXRlIGEgQmFzaCB2YXJpYWJsZXMgZmlsZQoKVGhpcyBhbGxvd3MgdXNhZ2Ugb2YgQmFzaCB2YXJpYWJsZXMgKGUuZy4gcGF0aHMgdG8gY29tbW9uIGRpcmVjdG9yaWVzKSBhY3Jvc3MgUiBNYXJrZG93biBjaHVua3MuCmBgYHtyIHNhdmUtYmFzaC12YXJpYWJsZXMtdG8tcnZhcnMtZmlsZSwgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQp7CmVjaG8gIiMjIyMgQXNzaWduIFZhcmlhYmxlcyAjIyMjIgplY2hvICIiCgplY2hvICIjIERhdGEgZGlyZWN0b3JpZXMiCmVjaG8gJ2V4cG9ydCBleHByZXNzaW9uX2Rpcj0vaG9tZS9zaGFyZWQvOFRCX0hERF8wMi9zaGVkdXJraW4vZXhwcmVzc2lvbicKZWNobyAnZXhwb3J0IG91dHB1dF9kaXJfdG9wPSR7ZXhwcmVzc2lvbl9kaXJ9L0QtQXB1bC9vdXRwdXQvMDEtQXB1bC1STkEtdHJpbW1pbmctRmFzdFFDJwplY2hvICdleHBvcnQgcmF3X2Zhc3RxY19kaXI9JHtvdXRwdXRfZGlyX3RvcH0vcmF3LWZhc3RxYycKZWNobyAnZXhwb3J0IHJhd19yZWFkc19kaXI9JHtleHByZXNzaW9uX2Rpcn0vRC1BcHVsL2RhdGEvMDEtQXB1bC1STkEtdHJpbW1pbmctRmFzdFFDL3Jhdy1yZWFkcycKZWNobyAnZXhwb3J0IHJhd19yZWFkc191cmw9Imh0dHBzOi8vb3dsLmZpc2gud2FzaGluZ3Rvbi5lZHUvbmlnaHRpbmdhbGVzL0FfcHVsY2hyYS8zMC03ODk1MTMxNjYvIicKZWNobyAnZXhwb3J0IHRyaW1tZWRfZmFzdHFjX2Rpcj0ke291dHB1dF9kaXJfdG9wfS90cmltbWVkLWZhc3RxYycKZWNobyAnZXhwb3J0IHRyaW1tZWRfcmVhZHNfZGlyPSR7ZXhwcmVzc2lvbl9kaXJ9L0QtQXB1bC9kYXRhLzAxLUFwdWwtUk5BLXRyaW1taW5nLUZhc3RRQy90cmltbWVkLXJlYWRzJwplY2hvICdleHBvcnQgdHJpbW1lZF9yZWFkc191cmw9Imh0dHBzOi8vZ2FubmV0LmZpc2gud2FzaGluZ3Rvbi5lZHUvQXR1bWVmYWNpZW5zLzIwMjMwNTE5LUU1X2NvcmFsLWZhc3RxYy1mYXN0cC1tdWx0aXFjLVJOQXNlcS9BX3B1bGNocmEvdHJpbW1lZC8iJwplY2hvICIiCgplY2hvICIjIFBhdGhzIHRvIHByb2dyYW1zIgplY2hvICdleHBvcnQgZmFzdHFjPS9ob21lL3NoYXJlZC9GYXN0UUMtMC4xMi4xL2Zhc3RxYycKZWNobyAnZXhwb3J0IG11bHRpcWM9L2hvbWUvc2FtL3Byb2dyYW1zL21hbWJhZm9yZ2UvYmluL211bHRpcWMnCmVjaG8gJ2V4cG9ydCBmbGV4YmFyPS9ob21lL3NoYXJlZC9mbGV4YmFyLTMuNS4wLWxpbnV4L2ZsZXhiYXInCmVjaG8gIiIKCmVjaG8gIiMgU2V0IEZhc3RRIGZpbGVuYW1lIHBhdHRlcm5zIgplY2hvICJleHBvcnQgZmFzdHFfcGF0dGVybj0nKi5mYXN0cS5neiciCmVjaG8gImV4cG9ydCBSMV9mYXN0cV9wYXR0ZXJuPScqX1IxXyouZmFzdHEuZ3onIgplY2hvICJleHBvcnQgUjJfZmFzdHFfcGF0dGVybj0nKl9SMl8qLmZhc3RxLmd6JyIKZWNobyAiIgoKZWNobyAiIyBTZXQgbnVtYmVyIG9mIENQVXMgdG8gdXNlIgplY2hvICdleHBvcnQgdGhyZWFkcz0yMCcKZWNobyAiIgoKZWNobyAiIyBJbnB1dC9vdXRwdXQgZmlsZXMiCmVjaG8gJ2V4cG9ydCByYXdfY2hlY2tzdW1zPWNoZWNrc3Vtcy5tZDUnCmVjaG8gJ2V4cG9ydCB0cmltbWVkX2NoZWNrc3Vtcz10cmltbWVkX2Zhc3RxX2NoZWNrc3Vtcy5tZDUnCmVjaG8gIiIKCgoKZWNobyAiIyMgSW5pdGl0YWxpemUgYXJyYXlzIgplY2hvICdleHBvcnQgZmFzdHFfYXJyYXlfUjE9KCknCmVjaG8gJ2V4cG9ydCBmYXN0cV9hcnJheV9SMj0oKScKZWNobyAnZXhwb3J0IHJhd19mYXN0cXNfYXJyYXk9KCknCmVjaG8gJ2V4cG9ydCBSMV9uYW1lc19hcnJheT0oKScKZWNobyAnZXhwb3J0IFIyX25hbWVzX2FycmF5PSgpJwplY2hvICdleHBvcnQgdHJpbW1lZF9mYXN0cXNfYXJyYXk9KCknCmVjaG8gIiIKCmVjaG8gIiMgUHJvZ3JhbXMgYXNzb2NpYXRpdmUgYXJyYXkiCmVjaG8gImRlY2xhcmUgLUEgcHJvZ3JhbXNfYXJyYXkiCmVjaG8gInByb2dyYW1zX2FycmF5PSgiCmVjaG8gJ1tmYXN0cWNdPSIke2Zhc3RxY30iIFwnCmVjaG8gJ1ttdWx0aXFjXT0iJHttdWx0aXFjfSIgXCcKZWNobyAnW2ZsZXhiYXJdPSIke2ZsZXhiYXJ9IicKZWNobyAiKSIKfSA+IC5iYXNodmFycwoKY2F0IC5iYXNodmFycwpgYGAKCgojIFJhdyByZWFkcwojIyBEb3dubG9hZCByYXcgUk5BLXNlcSByZWFkcwoKUmVhZHMgYXJlIGRvd25sb2FkZWQgZnJvbTogaHR0cHM6Ly9vd2wuZmlzaC53YXNoaW5ndG9uLmVkdS9uaWdodGluZ2FsZXMvQV9wdWxjaHJhLzMwLTc4OTUxMzE2Ni8KClRoZSBgLS1jdXQtZGlycyAzYCBjb21tYW5kIGN1dHMgdGhlIHByZWNlZGluZyBkaXJlY3Rvcnkgc3RydWN0dXJlIChpLmUuIGBuaWdodGluZ2FsZXMvQV9wdWxjaHJhLzMwLTc4OTUxMzE2Ni9gKSBzbyB0aGF0IHdlIGp1c3QgZW5kIHVwIHdpdGggCnRoZSByZWFkcy4KCmBgYHtyIGRvd25sb2FkLXJhdy1yZWFkcywgZW5naW5lPSdiYXNoJ30KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCndnZXQgXAotLWRpcmVjdG9yeS1wcmVmaXggJHtyYXdfcmVhZHNfZGlyfSBcCi0tcmVjdXJzaXZlIFwKLS1uby1jaGVjay1jZXJ0aWZpY2F0ZSBcCi0tY29udGludWUgXAotLWN1dC1kaXJzIDMgXAotLW5vLWhvc3QtZGlyZWN0b3JpZXMgXAotLW5vLXBhcmVudCBcCi0tcXVpZXQgXAotLWFjY2VwdCAke2Zhc3RxX3BhdHRlcm59ICR7cmF3X3JlYWRzX3VybH0KYGBgCgpgYGB7ciBjaGVjay1yYXctcmVhZHMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCmxzIC1saCAiJHtyYXdfcmVhZHNfZGlyfSIKYGBgCgojIyBWZXJpZnkgcmF3IHJlYWQgY2hlY2tzdW1zCmBgYHtyIHZlcmlmeS1yYXctcmVhZC1jaGVja3N1bXMsIGVuZ2luZT0nYmFzaCd9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgp3Z2V0IFwKLS1kaXJlY3RvcnktcHJlZml4ICR7cmF3X3JlYWRzX2Rpcn0gXAotLXJlY3Vyc2l2ZSBcCi0tbm8tY2hlY2stY2VydGlmaWNhdGUgXAotLWNvbnRpbnVlIFwKLS1jdXQtZGlycyAzIFwKLS1uby1ob3N0LWRpcmVjdG9yaWVzIFwKLS1uby1wYXJlbnQgXAotLXF1aWV0IFwKLS1hY2NlcHQgY2hlY2tzdW1zLm1kNSAke3Jhd19yZWFkc191cmx9CgpjZCAiJHtyYXdfcmVhZHNfZGlyfSIKCm1kNXN1bSBjaGVja3N1bXMubWQ1IC0tY2hlY2sKYGBgCgoKIyMgRmFzdFFDL011bHRpUUMgb24gcmF3IHJlYWRzCmBgYHtyIHJhdy1mYXN0cWMtbXVsdGlxYywgZW5naW5lPSdiYXNoJ30KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCiMjIyMjIyMjIyMjIyBSVU4gRkFTVFFDICMjIyMjIyMjIyMjIwoKCiMgQ3JlYXRlIGFycmF5IG9mIHJhdyBGYXN0UXMKcmF3X2Zhc3Rxc19hcnJheT0oJHtyYXdfcmVhZHNfZGlyfS8ke2Zhc3RxX3BhdHRlcm59KQoKIyBQYXNzIGFycmF5IGNvbnRlbnRzIHRvIG5ldyB2YXJpYWJsZSBhcyBzcGFjZS1kZWxpbWl0ZWQgbGlzdApyYXdfZmFzdHFjX2xpc3Q9JChlY2hvICIke3Jhd19mYXN0cXNfYXJyYXlbKl19IikKCmVjaG8gIkJlZ2lubmluZyBGYXN0UUMgb24gcmF3IHJlYWRzLi4uIgplY2hvICIiCgojIFJ1biBGYXN0UUMKIyMjIE5PVEU6IERvIE5PVCBxdW90ZSByYXdfZmFzdHFjX2xpc3QKJHtwcm9ncmFtc19hcnJheVtmYXN0cWNdfSBcCi0tdGhyZWFkcyAke3RocmVhZHN9IFwKLS1vdXRkaXIgJHtyYXdfZmFzdHFjX2Rpcn0gXAotLXF1aWV0IFwKJHtyYXdfZmFzdHFjX2xpc3R9CgplY2hvICJGYXN0UUMgb24gcmF3IHJlYWRzIGNvbXBsZXRlISIKZWNobyAiIgoKIyMjIyMjIyMjIyMjIEVORCBGQVNUUUMgIyMjIyMjIyMjIyMjCgojIyMjIyMjIyMjIyMgUlVOIE1VTFRJUUMgIyMjIyMjIyMjIyMjCmVjaG8gIkJlZ2lubmluZyBNdWx0aVFDIG9uIHJhdyBGYXN0UUMuLi4iCmVjaG8gIiIKCiR7cHJvZ3JhbXNfYXJyYXlbbXVsdGlxY119ICR7cmF3X2Zhc3RxY19kaXJ9IC1vICR7cmF3X2Zhc3RxY19kaXJ9CgplY2hvICIiCmVjaG8gIk11bHRpUUMgb24gcmF3IEZhc3RRcyBjb21wbGV0ZS4iCmVjaG8gIiIKCiMjIyMjIyMjIyMjIyBFTkQgTVVMVElRQyAjIyMjIyMjIyMjIyMKCmVjaG8gIlJlbW92aW5nIEZhc3RRQyB6aXAgZmlsZXMuIgplY2hvICIiCnJtICR7cmF3X2Zhc3RxY19kaXJ9LyouemlwCmVjaG8gIkZhc3RRQyB6aXAgZmlsZXMgcmVtb3ZlZC4iCmVjaG8gIiIKYGBgCgpgYGB7ciBjaGVjay1yYXctcmVhZHMtUUMtZmlsZXMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCiMgVmlldyBkaXJlY3RvcnkgY29udGVudHMKbHMgLWxoICR7cmF3X2Zhc3RxY19kaXJ9CmBgYAoKCiMgVHJpbW1lZCByZWFkcwojIyBEb3dubG9hZCB0cmltbWVkIFJOQS1zZXEgcmVhZHMKClJlYWRzIGFyZSBkb3dubG9hZGVkIGZyb206IGh0dHBzOi8vZ2FubmV0LmZpc2gud2FzaGluZ3Rvbi5lZHUvQXR1bWVmYWNpZW5zLzIwMjMwNTE5LUU1X2NvcmFsLWZhc3RxYy1mYXN0cC1tdWx0aXFjLVJOQXNlcS9BX3B1bGNocmEvdHJpbW1lZC8KCmBgYHtyIGRvd25sb2FkLXRyaW1tZWQtcmVhZHMsIGVuZ2luZT0nYmFzaCd9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgp3Z2V0IFwKLS1kaXJlY3RvcnktcHJlZml4ICR7dHJpbW1lZF9yZWFkc19kaXJ9IFwKLS1yZWN1cnNpdmUgXAotLW5vLWNoZWNrLWNlcnRpZmljYXRlIFwKLS1jb250aW51ZSBcCi0tY3V0LWRpcnMgNCBcCi0tbm8taG9zdC1kaXJlY3RvcmllcyBcCi0tbm8tcGFyZW50IFwKLS1xdWlldCBcCi0tYWNjZXB0ICR7ZmFzdHFfcGF0dGVybn0gJHt0cmltbWVkX3JlYWRzX3VybH0KYGBgCgpgYGB7ciBjaGVjay10cmltbWVkLXJlYWRzLCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgpscyAtbGggIiR7dHJpbW1lZF9yZWFkc19kaXJ9IgpgYGAKCiMjIFZlcmlmeSByYXcgcmVhZCBjaGVja3N1bXMKYGBge3IgdmVyaWZ5LXRyaW1tZWQtcmVhZC1jaGVja3N1bXMsIGVuZ2luZT0nYmFzaCd9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgp3Z2V0IFwKLS1kaXJlY3RvcnktcHJlZml4ICR7dHJpbW1lZF9yZWFkc19kaXJ9IFwKLS1yZWN1cnNpdmUgXAotLW5vLWNoZWNrLWNlcnRpZmljYXRlIFwKLS1jb250aW51ZSBcCi0tY3V0LWRpcnMgNCBcCi0tbm8taG9zdC1kaXJlY3RvcmllcyBcCi0tbm8tcGFyZW50IFwKLS1xdWlldCBcCi0tYWNjZXB0IHRyaW1tZWRfZmFzdHFfY2hlY2tzdW1zLm1kNSAke3RyaW1tZWRfcmVhZHNfdXJsfQoKY2QgIiR7dHJpbW1lZF9yZWFkc19kaXJ9IgoKbWQ1c3VtIHRyaW1tZWRfZmFzdHFfY2hlY2tzdW1zLm1kNSAtLWNoZWNrCmBgYAoKCiMjIEZhc3RRQy9NdWx0aVFDIG9uIHRyaW1tZWQgcmVhZHMKCmBgYHtyIEZhc3RRQy1NdWx0aVFDLXRyaW1tZWQtcmVhZHMsIGVuZ2luZT0nYmFzaCd9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgojIyMjIyMjIyMjIyMgUlVOIEZBU1RRQyAjIyMjIyMjIyMjIyMKCiMjIyBOT1RFOiBEbyBOT1QgcXVvdGUgcmF3X2Zhc3RxY19saXN0CiMgQ3JlYXRlIGFycmF5IG9mIHRyaW1tZWQgRmFzdFFzCnRyaW1tZWRfZmFzdHFzX2FycmF5PSgke3RyaW1tZWRfcmVhZHNfZGlyfS8ke2Zhc3RxX3BhdHRlcm59KQoKIyBQYXNzIGFycmF5IGNvbnRlbnRzIHRvIG5ldyB2YXJpYWJsZSBhcyBzcGFjZS1kZWxpbWl0ZWQgbGlzdAp0cmltbWVkX2Zhc3RxY19saXN0PSQoZWNobyAiJHt0cmltbWVkX2Zhc3Rxc19hcnJheVsqXX0iKQoKZWNobyAiQmVnaW5uaW5nIEZhc3RRQyBvbiByYXcgcmVhZHMuLi4iCmVjaG8gIiIKCiMgUnVuIEZhc3RRQwoke3Byb2dyYW1zX2FycmF5W2Zhc3RxY119IFwKLS10aHJlYWRzICR7dGhyZWFkc30gXAotLW91dGRpciAke3RyaW1tZWRfZmFzdHFjX2Rpcn0gXAotLXF1aWV0IFwKJHt0cmltbWVkX2Zhc3RxY19saXN0fQoKZWNobyAiRmFzdFFDIG9uIHRyaW1tZWQgcmVhZHMgY29tcGxldGUhIgplY2hvICIiCgojIyMjIyMjIyMjIyMgRU5EIEZBU1RRQyAjIyMjIyMjIyMjIyMKCiMjIyMjIyMjIyMjIyBSVU4gTVVMVElRQyAjIyMjIyMjIyMjIyMKZWNobyAiQmVnaW5uaW5nIE11bHRpUUMgb24gcmF3IEZhc3RRQy4uLiIKZWNobyAiIgoKJHtwcm9ncmFtc19hcnJheVttdWx0aXFjXX0gJHt0cmltbWVkX2Zhc3RxY19kaXJ9IC1vICR7dHJpbW1lZF9mYXN0cWNfZGlyfQoKZWNobyAiIgplY2hvICJNdWx0aVFDIG9uIHRyaW1tZWQgRmFzdFFzIGNvbXBsZXRlLiIKZWNobyAiIgoKIyMjIyMjIyMjIyMjIEVORCBNVUxUSVFDICMjIyMjIyMjIyMjIwoKZWNobyAiUmVtb3ZpbmcgRmFzdFFDIHppcCBmaWxlcy4iCmVjaG8gIiIKcm0gJHt0cmltbWVkX2Zhc3RxY19kaXJ9LyouemlwCmVjaG8gIkZhc3RRQyB6aXAgZmlsZXMgcmVtb3ZlZC4iCmVjaG8gIiIKYGBgCgpgYGB7ciB2aWV3LXRyaW1tZWQtcmVhZHMtUUMtZmlsZXMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCiMgVmlldyBkaXJlY3RvcnkgY29udGVudHMKbHMgLWxoICR7dHJpbW1lZF9mYXN0cWNfZGlyfQpgYGAKCiMgU3VtbWFyeQo=