Extract mature miRNAs identified with matches to miRBase by ShortStack in 13.2.1-Apul-sRNAseq-ShortStack-31bp-fastp-merged-cnidarian_miRBase.Rmd to FastA.


1 Create a Bash variables file

This allows usage of Bash variables across R Markdown chunks.

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

echo "# Trimmed FastQ naming pattern"

echo "# Data directories"
echo 'export deep_dive_dir=/home/shared/8TB_HDD_01/sam/gitrepos/deep-dive'
echo 'export shortstack_dir="${deep_dive_dir}/D-Apul/output/13.2.1-Apul-sRNAseq-ShortStack-31bp-fastp-merged-cnidarian_miRBase/ShortStack_out"'
echo 'export output_dir_top=${deep_dive_dir}/D-Apul/output/13.2.1.1-Apul-sRNAseq-ShortStack-FastA-extraction'
echo ""

echo "# Input/Output files"
echo 'export output_fasta="mature-miRBase-matches.fasta"'
echo 'export shortstack_fasta="mir.fasta"'
echo 'export shortstack_fasta_index="mir.fasta.fai"'
echo 'export shortstack_fixed_fasta="mir-coords-fixed.fasta"'
echo 'export shortstack_fixed_fasta_index="mir-coords-fixed.fasta.fai"'

echo 'export shortstack_results_file="Results.txt"'
echo 'export regions="mature-miRBase-regions.txt"'

echo ""

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

echo "# Programs"
echo 'export samtools=/home/shared/samtools-1.12/samtools'


} > .bashvars

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

# Trimmed FastQ naming pattern
# Data directories
export deep_dive_dir=/home/shared/8TB_HDD_01/sam/gitrepos/deep-dive
export shortstack_dir="${deep_dive_dir}/D-Apul/output/13.2.1-Apul-sRNAseq-ShortStack-31bp-fastp-merged-cnidarian_miRBase/ShortStack_out"
export output_dir_top=${deep_dive_dir}/D-Apul/output/13.2.1.1-Apul-sRNAseq-ShortStack-FastA-extraction

# Input/Output files
export output_fasta="mature-miRBase-matches.fasta"
export shortstack_fasta="mir.fasta"
export shortstack_fasta_index="mir.fasta.fai"
export shortstack_fixed_fasta="mir-coords-fixed.fasta"
export shortstack_fixed_fasta_index="mir-coords-fixed.fasta.fai"
export shortstack_results_file="Results.txt"
export regions="mature-miRBase-regions.txt"

# Set number of CPUs to use
export threads=40

# Programs
export samtools=/home/shared/samtools-1.12/samtools

2 Examine Results.txt

2.2 Columns of interest

Column 1: Region of miRNA match

Column 20: ShortStack miRNA? Y/N

Column 21: Match to miRBase? NA or miRBase match

# Load bash variables into memory
source .bashvars

awk '{print $1"\t"$20"\t"$21}' "${shortstack_dir}/${shortstack_results_file}" | head | column -t
Locus                      MIRNA  known_miRNAs
NC_058066.1:152483-152910  N      NA
NC_058066.1:161064-161674  N      NA
NC_058066.1:172073-172496  N      NA
NC_058066.1:203242-203651  N      NA
NC_058066.1:204535-205150  N      NA
NC_058066.1:205745-206966  N      NA
NC_058066.1:210841-211344  N      NA
NC_058066.1:349655-351297  N      NA
NC_058066.1:351491-353439  N      NA

2.3 miRNAs of interest

# Load bash variables into memory
source .bashvars

awk '$20 == "Y" && $21 != "NA" {print $1"\t"$20"\t"$21}' "${shortstack_dir}/${shortstack_results_file}" | head | column -t

echo ""
echo "------------------------------------------"
echo ""
echo "Number of miRNAs matching miRBase:"

awk '$20 == "Y" && $21 != "NA" {print $1"\t"$20"\t"$21}' "${shortstack_dir}/${shortstack_results_file}" | wc -l 
NC_058066.1:12757125-12757218  Y  ami-miR-P-novel-3-3p_Acropora_millepora_Praher_et_al._2021_NA;adi-ami-miR-P-novel-3-3p_Acropora_digitifera__Praher_et_al._2021_NA
NC_058066.1:20346227-20346321  Y  ami-miR-P-novel-1-3p_Acropora_millepora_Praher_et_al._2021_NA;Adi-Mir-Novel-1_3p_Acropora_digitifera_Gajigan_&_Conaco_2017_nve-miR-9437;adi-miR-P-novel-1-3p_Acropora_digitifera__Praher_et_al._2021_NA
NC_058067.1:5656192-5656286    Y  spi-mir-temp-25_Stylophora_pistillata_Liew_et_al._2014_Considered_bona_fideas_close_match_to_nve-_and_hma-miR-2022.;eca-nve-F-miR-2022_Edwardsiella_carnea_Praher_et_al._2021_Transcriptome-level;Adi-Mir-2022_3p_Acropora_digitifera_Gajigan_&_Conaco_2017_nve-miR-2022-3p;_nve-miR-2022-3p;_spi-miR-temp-25;ami-nve-F-miR-2022-3p_Acropora_millepora_Praher_et_al._2021_NA
NC_058067.1:16118215-16118311  Y  ami-miR-P-novel-4-5p_Acropora_millepora_Praher_et_al._2021_NA
NC_058067.1:25838831-25838927  Y  ami-miR-P-novel-5-5p_Acropora_millepora_Praher_et_al._2021_NA
NC_058068.1:3756500-3756594    Y  ami-Adi-MiR-G-Novel-5-3p_Acropora_millepora_Praher_et_al._2021_NA;Adi-Mir-Novel-5_3p_Acropora_digitifera_Gajigan_&_Conaco_2017_NA;Adi-MiR-G-Novel-5_3p_Acropora_digitifera__Praher_et_al._2021_NA
NC_058069.1:1868134-1868229    Y  adi-miR-P-novel-4-3p_Acropora_digitifera__Praher_et_al._2021_NA
NC_058069.1:2018489-2018586    Y  ami-miR-P-novel-17-3p_Acropora_millepora_Praher_et_al._2021_NA
NC_058069.1:21012147-21012242  Y  ami-nve-F-miR-2025-3p_Acropora_millepora_Praher_et_al._2021_NA;Adi-Mir-2025_3p_Acropora_digitifera_Gajigan_&_Conaco_2017_nve-miR-2025-3p;_nve-miR-2025-3p;adi-nve-F-miR-2025_Acropora_digitifera__Praher_et_al._2021_NA
NC_058070.1:2184956-2185050    Y  Adi-Mir-9425_5p_Acropora_digitifera_Gajigan_&_Conaco_2017_nve-miR-9425;_nve-miR-9425;ami-nve-F-miR-9425-5p_Acropora_millepora_Praher_et_al._2021_NA;nve-miR-9425;miR-9425_Nematostella_vectensis_Moran_et_al._2014_NA

------------------------------------------

Number of miRNAs matching miRBase:
24

3 Examine ShortStack miRNA FastA

3.1 Head FastA

# Load bash variables into memory
source .bashvars

grep "^>" "${shortstack_dir}/${shortstack_fasta}" | head
>Cluster_316::NC_058066.1:12757124-12757218(-)
>Cluster_316.mature::NC_058066.1:12757146-12757168(-)
>Cluster_316.star::NC_058066.1:12757176-12757198(-)
>Cluster_514::NC_058066.1:20088629-20088720(+)
>Cluster_514.mature::NC_058066.1:20088678-20088700(+)
>Cluster_514.star::NC_058066.1:20088649-20088671(+)
>Cluster_548::NC_058066.1:20346226-20346321(-)
>Cluster_548.mature::NC_058066.1:20346248-20346271(-)
>Cluster_548.star::NC_058066.1:20346278-20346301(-)
>Cluster_1506::NC_058067.1:5656191-5656286(-)

4 Fix FastA description starting coordinates

Needed, due to bug in code (GitHub Issue) which incorrectly calculates the starting coordinates in the FastA output. All other files where start/stop coordinates are conveyed are correct.

The incorrect starting coordinates cause an issue in downstream manipulation, because the FastA headers need to match the ShortStack results file.

# Load bash variables into memory
source .bashvars

awk '
/^>/ {
    # Split the line into main parts based on "::" delimiter
    split($0, main_parts, "::")
    
    # Extract the coordinate part and strand information separately
    coordinates_strand = main_parts[2]
    split(coordinates_strand, coord_parts, "[:-]")
    
    # Determine if the strand information is present and extract it
    strand = ""
    if (substr(coordinates_strand, length(coordinates_strand)) ~ /[\(\)\-\+]/) {
        strand = substr(coordinates_strand, length(coordinates_strand) - 1)
        coordinates_strand = substr(coordinates_strand, 1, length(coordinates_strand) - 2)
        split(coordinates_strand, coord_parts, "[:-]")
    }
    
    # Increment the starting coordinate by 1
    new_start = coord_parts[2] + 1
    
    # Reconstruct the description line with the new starting coordinate
    new_description = main_parts[1] "::" coord_parts[1] ":" new_start "-" coord_parts[3] strand
    
    # Print the modified description line
    print new_description
    
    # Skip to the next line to process the sequence line
    next
}

# For sequence lines, print them as-is
{
    print
}
' "${shortstack_dir}/${shortstack_fasta}" \
> "${shortstack_dir}/${shortstack_fixed_fasta}"

diff "${shortstack_dir}/${shortstack_fasta}" \
"${shortstack_dir}/${shortstack_fixed_fasta}" \
| head
1c1
< >Cluster_316::NC_058066.1:12757124-12757218(-)
---
> >Cluster_316::NC_058066.1:12757125-12757218(-)
3c3
< >Cluster_316.mature::NC_058066.1:12757146-12757168(-)
---
> >Cluster_316.mature::NC_058066.1:12757147-12757168(-)
5c5
< >Cluster_316.star::NC_058066.1:12757176-12757198(-)

5 Create regions file for use with samtools

5.1 Make FastA index

# Load bash variables into memory
source .bashvars

${samtools} faidx "${shortstack_dir}/${shortstack_fixed_fasta}"


head "${shortstack_dir}/${shortstack_fixed_fasta_index}"
Cluster_316::NC_058066.1:12757125-12757218(-)   94  47  94  95
Cluster_316.mature::NC_058066.1:12757147-12757168(-)    22  196 22  23
Cluster_316.star::NC_058066.1:12757177-12757198(-)  22  271 22  23
Cluster_514::NC_058066.1:20088630-20088720(+)   91  341 91  92
Cluster_514.mature::NC_058066.1:20088679-20088700(+)    22  487 22  23
Cluster_514.star::NC_058066.1:20088650-20088671(+)  22  562 22  23
Cluster_548::NC_058066.1:20346227-20346321(-)   95  632 95  96
Cluster_548.mature::NC_058066.1:20346249-20346271(-)    23  782 23  24
Cluster_548.star::NC_058066.1:20346279-20346301(-)  23  858 23  24
Cluster_1506::NC_058067.1:5656192-5656286(-)    95  928 95  96

5.2 Construct regions of miRBase matches for FastA index

# Load bash variables into memory
source .bashvars

# Make output directory, if it doesn't exist
mkdir --parents "${output_dir_top}"

{
   awk '$20 == "Y" && $21 != "NA" {print $2}' "${shortstack_dir}/${shortstack_results_file}" \
   | grep --fixed-strings --file - "${shortstack_dir}/${shortstack_fixed_fasta_index}" \
   | awk '{print $1}'
} \
> "${output_dir_top}/${regions}"

head "${output_dir_top}/${regions}"
Cluster_316::NC_058066.1:12757125-12757218(-)
Cluster_316.mature::NC_058066.1:12757147-12757168(-)
Cluster_316.star::NC_058066.1:12757177-12757198(-)
Cluster_548::NC_058066.1:20346227-20346321(-)
Cluster_548.mature::NC_058066.1:20346249-20346271(-)
Cluster_548.star::NC_058066.1:20346279-20346301(-)
Cluster_1506::NC_058067.1:5656192-5656286(-)
Cluster_1506.mature::NC_058067.1:5656214-5656236(-)
Cluster_1506.star::NC_058067.1:5656244-5656266(-)
Cluster_1900::NC_058067.1:16118215-16118311(-)

6 Extract FastAs

# Load bash variables into memory
source .bashvars

${samtools} faidx "${shortstack_dir}/${shortstack_fixed_fasta}" \
--region-file "${output_dir_top}/${regions}" \
> "${output_dir_top}/${output_fasta}"

head "${output_dir_top}/${output_fasta}"

echo ""
echo ""
echo ""
echo "Number of FastA sequences:"
grep "^>" --count "${output_dir_top}/${output_fasta}"
>Cluster_316::NC_058066.1:12757125-12757218(-)
ATGCTTTACTCCTTTGGGAGGGAGGTTAGTGCAGAGGTCATCGTTATTGATGATCTCTGC
AATAGCCTGCCTCCCAAAGGAGTTCTACTAGTCC
>Cluster_316.mature::NC_058066.1:12757147-12757168(-)
TGATCTCTGCAATAGCCTGCCT
>Cluster_316.star::NC_058066.1:12757177-12757198(-)
GGAGGTTAGTGCAGAGGTCATC
>Cluster_548::NC_058066.1:20346227-20346321(-)
TCATAAGGAAGGTACGGTTTCTTCGTTTATTCACTCGTTCATATTTATTATTAACGAGTA
GATAAATGAAGAGATCTTATCTTTGTTGGAAAAGA



Number of FastA sequences:
72
LS0tCnRpdGxlOiAiMTMuMi4xLjEtQXB1bC1zUk5Bc2VxLVNob3J0U3RhY2stRmFzdEEtZXh0cmFjdGlvbiIKYXV0aG9yOiAiU2FtIFdoaXRlIgpkYXRlOiAiMjAyNC0wNS0yMiIKb3V0cHV0OiAKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICB0aGVtZTogY29zbW8KICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogIGdpdGh1Yl9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiBjb3NtbwogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCmJpYmxpb2dyYXBoeTogcmVmZXJlbmNlcy5iaWIKbGluay1jaXRhdGlvbnM6IHRydWUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShrbml0cikKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBUUlVFLCAgICAgICAgICMgRGlzcGxheSBjb2RlIGNodW5rcwogIGV2YWwgPSBGQUxTRSwgICAgICAgICMgRXZhbHVhdGUgY29kZSBjaHVua3MKICB3YXJuaW5nID0gRkFMU0UsICAgICAjIEhpZGUgd2FybmluZ3MKICBtZXNzYWdlID0gRkFMU0UsICAgICAjIEhpZGUgbWVzc2FnZXMKICBjb21tZW50ID0gIiIgICAgICAgICAjIFByZXZlbnRzIGFwcGVuZGluZyAnIyMnIHRvIGJlZ2lubmluZyBvZiBsaW5lcyBpbiBjb2RlIG91dHB1dAopCmBgYAoKRXh0cmFjdCBtYXR1cmUgbWlSTkFzIGlkZW50aWZpZWQgd2l0aCBtYXRjaGVzIHRvIG1pUkJhc2UgYnkgU2hvcnRTdGFjayBpbiBbMTMuMi4xLUFwdWwtc1JOQXNlcS1TaG9ydFN0YWNrLTMxYnAtZmFzdHAtbWVyZ2VkLWNuaWRhcmlhbl9taVJCYXNlLlJtZF0oLi8xMy4yLjEtQXB1bC1zUk5Bc2VxLVNob3J0U3RhY2stMzFicC1mYXN0cC1tZXJnZWQtY25pZGFyaWFuX21pUkJhc2UuUm1kKSB0byBGYXN0QS4KCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgojIENyZWF0ZSBhIEJhc2ggdmFyaWFibGVzIGZpbGUKClRoaXMgYWxsb3dzIHVzYWdlIG9mIEJhc2ggdmFyaWFibGVzIGFjcm9zcyBSIE1hcmtkb3duIGNodW5rcy4KCmBgYHtyIHNhdmUtYmFzaC12YXJpYWJsZXMtdG8tcnZhcnMtZmlsZSwgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQp7CmVjaG8gIiMjIyMgQXNzaWduIFZhcmlhYmxlcyAjIyMjIgplY2hvICIiCgplY2hvICIjIFRyaW1tZWQgRmFzdFEgbmFtaW5nIHBhdHRlcm4iCgplY2hvICIjIERhdGEgZGlyZWN0b3JpZXMiCmVjaG8gJ2V4cG9ydCBkZWVwX2RpdmVfZGlyPS9ob21lL3NoYXJlZC84VEJfSEREXzAxL3NhbS9naXRyZXBvcy9kZWVwLWRpdmUnCmVjaG8gJ2V4cG9ydCBzaG9ydHN0YWNrX2Rpcj0iJHtkZWVwX2RpdmVfZGlyfS9ELUFwdWwvb3V0cHV0LzEzLjIuMS1BcHVsLXNSTkFzZXEtU2hvcnRTdGFjay0zMWJwLWZhc3RwLW1lcmdlZC1jbmlkYXJpYW5fbWlSQmFzZS9TaG9ydFN0YWNrX291dCInCmVjaG8gJ2V4cG9ydCBvdXRwdXRfZGlyX3RvcD0ke2RlZXBfZGl2ZV9kaXJ9L0QtQXB1bC9vdXRwdXQvMTMuMi4xLjEtQXB1bC1zUk5Bc2VxLVNob3J0U3RhY2stRmFzdEEtZXh0cmFjdGlvbicKZWNobyAiIgoKZWNobyAiIyBJbnB1dC9PdXRwdXQgZmlsZXMiCmVjaG8gJ2V4cG9ydCBvdXRwdXRfZmFzdGE9Im1hdHVyZS1taVJCYXNlLW1hdGNoZXMuZmFzdGEiJwplY2hvICdleHBvcnQgc2hvcnRzdGFja19mYXN0YT0ibWlyLmZhc3RhIicKZWNobyAnZXhwb3J0IHNob3J0c3RhY2tfZmFzdGFfaW5kZXg9Im1pci5mYXN0YS5mYWkiJwplY2hvICdleHBvcnQgc2hvcnRzdGFja19maXhlZF9mYXN0YT0ibWlyLWNvb3Jkcy1maXhlZC5mYXN0YSInCmVjaG8gJ2V4cG9ydCBzaG9ydHN0YWNrX2ZpeGVkX2Zhc3RhX2luZGV4PSJtaXItY29vcmRzLWZpeGVkLmZhc3RhLmZhaSInCgplY2hvICdleHBvcnQgc2hvcnRzdGFja19yZXN1bHRzX2ZpbGU9IlJlc3VsdHMudHh0IicKZWNobyAnZXhwb3J0IHJlZ2lvbnM9Im1hdHVyZS1taVJCYXNlLXJlZ2lvbnMudHh0IicKCmVjaG8gIiIKCmVjaG8gIiMgU2V0IG51bWJlciBvZiBDUFVzIHRvIHVzZSIKZWNobyAnZXhwb3J0IHRocmVhZHM9NDAnCmVjaG8gIiIKCmVjaG8gIiMgUHJvZ3JhbXMiCmVjaG8gJ2V4cG9ydCBzYW10b29scz0vaG9tZS9zaGFyZWQvc2FtdG9vbHMtMS4xMi9zYW10b29scycKCgp9ID4gLmJhc2h2YXJzCgpjYXQgLmJhc2h2YXJzCmBgYAoKIyBFeGFtaW5lIGBSZXN1bHRzLnR4dGAKCiMjIEhlYWQKYGBge3IgaGVhZC1yZXN1bHRzLnR4dCwgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKaGVhZCAiJHtzaG9ydHN0YWNrX2Rpcn0vJHtzaG9ydHN0YWNrX3Jlc3VsdHNfZmlsZX0iIHwgY29sdW1uIC10CmBgYAoKIyMgQ29sdW1ucyBvZiBpbnRlcmVzdAoKQ29sdW1uIDE6IFJlZ2lvbiBvZiBtaVJOQSBtYXRjaAoKQ29sdW1uIDIwOiBTaG9ydFN0YWNrIG1pUk5BPyBZL04KCkNvbHVtbiAyMTogTWF0Y2ggdG8gbWlSQmFzZT8gTkEgb3IgbWlSQmFzZSBtYXRjaAoKYGBge3IgY29scy1vZi1pbnRlcmVzdCwgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKYXdrICd7cHJpbnQgJDEiXHQiJDIwIlx0IiQyMX0nICIke3Nob3J0c3RhY2tfZGlyfS8ke3Nob3J0c3RhY2tfcmVzdWx0c19maWxlfSIgfCBoZWFkIHwgY29sdW1uIC10CmBgYAoKIyMgbWlSTkFzIG9mIGludGVyZXN0CmBgYHtyIG1pUk5Bcy1vZi1pbnRlcmVzdCwgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKYXdrICckMjAgPT0gIlkiICYmICQyMSAhPSAiTkEiIHtwcmludCAkMSJcdCIkMjAiXHQiJDIxfScgIiR7c2hvcnRzdGFja19kaXJ9LyR7c2hvcnRzdGFja19yZXN1bHRzX2ZpbGV9IiB8IGhlYWQgfCBjb2x1bW4gLXQKCmVjaG8gIiIKZWNobyAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIgplY2hvICIiCmVjaG8gIk51bWJlciBvZiBtaVJOQXMgbWF0Y2hpbmcgbWlSQmFzZToiCgphd2sgJyQyMCA9PSAiWSIgJiYgJDIxICE9ICJOQSIge3ByaW50ICQxIlx0IiQyMCJcdCIkMjF9JyAiJHtzaG9ydHN0YWNrX2Rpcn0vJHtzaG9ydHN0YWNrX3Jlc3VsdHNfZmlsZX0iIHwgd2MgLWwgCmBgYAoKIyBFeGFtaW5lIFNob3J0U3RhY2sgbWlSTkEgRmFzdEEKCiMjIEhlYWQgRmFzdEEKCmBgYHtyIGhlYWQtRmFzdEEsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCmdyZXAgIl4+IiAiJHtzaG9ydHN0YWNrX2Rpcn0vJHtzaG9ydHN0YWNrX2Zhc3RhfSIgfCBoZWFkCmBgYAoKIyBGaXggRmFzdEEgZGVzY3JpcHRpb24gc3RhcnRpbmcgY29vcmRpbmF0ZXMKCk5lZWRlZCwgZHVlIHRvIFtidWcgaW4gY29kZV0oaHR0cHM6Ly9naXRodWIuY29tL01pa2VBeHRlbGwvU2hvcnRTdGFjay9pc3N1ZXMvMTUzI2lzc3VlY29tbWVudC0yMTIyODk3NDg2KSAoR2l0SHViIElzc3VlKSB3aGljaCBpbmNvcnJlY3RseSBjYWxjdWxhdGVzIHRoZSBzdGFydGluZyBjb29yZGluYXRlcyBpbiB0aGUgRmFzdEEgb3V0cHV0LiBBbGwgb3RoZXIgZmlsZXMgd2hlcmUgc3RhcnQvc3RvcCBjb29yZGluYXRlcyBhcmUgY29udmV5ZWQgYXJlIGNvcnJlY3QuCgpUaGUgaW5jb3JyZWN0IHN0YXJ0aW5nIGNvb3JkaW5hdGVzIGNhdXNlIGFuIGlzc3VlIGluIGRvd25zdHJlYW0gbWFuaXB1bGF0aW9uLCBiZWNhdXNlIHRoZSBGYXN0QSBoZWFkZXJzIG5lZWQgdG8gbWF0Y2ggdGhlIFNob3J0U3RhY2sgcmVzdWx0cyBmaWxlLgoKYGBge3IgZml4LUZhc3RBLWNvb3JkaW5hdGVzLCBlbmdpbmU9J2Jhc2gnLCBldmFsPVRSVUV9CiMgTG9hZCBiYXNoIHZhcmlhYmxlcyBpbnRvIG1lbW9yeQpzb3VyY2UgLmJhc2h2YXJzCgphd2sgJwovXj4vIHsKICAgICMgU3BsaXQgdGhlIGxpbmUgaW50byBtYWluIHBhcnRzIGJhc2VkIG9uICI6OiIgZGVsaW1pdGVyCiAgICBzcGxpdCgkMCwgbWFpbl9wYXJ0cywgIjo6IikKICAgIAogICAgIyBFeHRyYWN0IHRoZSBjb29yZGluYXRlIHBhcnQgYW5kIHN0cmFuZCBpbmZvcm1hdGlvbiBzZXBhcmF0ZWx5CiAgICBjb29yZGluYXRlc19zdHJhbmQgPSBtYWluX3BhcnRzWzJdCiAgICBzcGxpdChjb29yZGluYXRlc19zdHJhbmQsIGNvb3JkX3BhcnRzLCAiWzotXSIpCiAgICAKICAgICMgRGV0ZXJtaW5lIGlmIHRoZSBzdHJhbmQgaW5mb3JtYXRpb24gaXMgcHJlc2VudCBhbmQgZXh0cmFjdCBpdAogICAgc3RyYW5kID0gIiIKICAgIGlmIChzdWJzdHIoY29vcmRpbmF0ZXNfc3RyYW5kLCBsZW5ndGgoY29vcmRpbmF0ZXNfc3RyYW5kKSkgfiAvW1woXClcLVwrXS8pIHsKICAgICAgICBzdHJhbmQgPSBzdWJzdHIoY29vcmRpbmF0ZXNfc3RyYW5kLCBsZW5ndGgoY29vcmRpbmF0ZXNfc3RyYW5kKSAtIDEpCiAgICAgICAgY29vcmRpbmF0ZXNfc3RyYW5kID0gc3Vic3RyKGNvb3JkaW5hdGVzX3N0cmFuZCwgMSwgbGVuZ3RoKGNvb3JkaW5hdGVzX3N0cmFuZCkgLSAyKQogICAgICAgIHNwbGl0KGNvb3JkaW5hdGVzX3N0cmFuZCwgY29vcmRfcGFydHMsICJbOi1dIikKICAgIH0KICAgIAogICAgIyBJbmNyZW1lbnQgdGhlIHN0YXJ0aW5nIGNvb3JkaW5hdGUgYnkgMQogICAgbmV3X3N0YXJ0ID0gY29vcmRfcGFydHNbMl0gKyAxCiAgICAKICAgICMgUmVjb25zdHJ1Y3QgdGhlIGRlc2NyaXB0aW9uIGxpbmUgd2l0aCB0aGUgbmV3IHN0YXJ0aW5nIGNvb3JkaW5hdGUKICAgIG5ld19kZXNjcmlwdGlvbiA9IG1haW5fcGFydHNbMV0gIjo6IiBjb29yZF9wYXJ0c1sxXSAiOiIgbmV3X3N0YXJ0ICItIiBjb29yZF9wYXJ0c1szXSBzdHJhbmQKICAgIAogICAgIyBQcmludCB0aGUgbW9kaWZpZWQgZGVzY3JpcHRpb24gbGluZQogICAgcHJpbnQgbmV3X2Rlc2NyaXB0aW9uCiAgICAKICAgICMgU2tpcCB0byB0aGUgbmV4dCBsaW5lIHRvIHByb2Nlc3MgdGhlIHNlcXVlbmNlIGxpbmUKICAgIG5leHQKfQoKIyBGb3Igc2VxdWVuY2UgbGluZXMsIHByaW50IHRoZW0gYXMtaXMKewogICAgcHJpbnQKfQonICIke3Nob3J0c3RhY2tfZGlyfS8ke3Nob3J0c3RhY2tfZmFzdGF9IiBcCj4gIiR7c2hvcnRzdGFja19kaXJ9LyR7c2hvcnRzdGFja19maXhlZF9mYXN0YX0iCgpkaWZmICIke3Nob3J0c3RhY2tfZGlyfS8ke3Nob3J0c3RhY2tfZmFzdGF9IiBcCiIke3Nob3J0c3RhY2tfZGlyfS8ke3Nob3J0c3RhY2tfZml4ZWRfZmFzdGF9IiBcCnwgaGVhZAoKCmBgYAoKIyBDcmVhdGUgcmVnaW9ucyBmaWxlIGZvciB1c2Ugd2l0aCBgc2FtdG9vbHNgCgojIyBNYWtlIEZhc3RBIGluZGV4CgpgYGB7ciBGYXN0QS1pbmRleCwgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKJHtzYW10b29sc30gZmFpZHggIiR7c2hvcnRzdGFja19kaXJ9LyR7c2hvcnRzdGFja19maXhlZF9mYXN0YX0iCgoKaGVhZCAiJHtzaG9ydHN0YWNrX2Rpcn0vJHtzaG9ydHN0YWNrX2ZpeGVkX2Zhc3RhX2luZGV4fSIKYGBgCgojIyBDb25zdHJ1Y3QgcmVnaW9ucyBvZiBtaVJCYXNlIG1hdGNoZXMgZm9yIEZhc3RBIGluZGV4CgoKYGBge3IgY29udHJzdWN0LXJlZ2lvbnMtZmlsZSwgZW5naW5lPSdiYXNoJywgZXZhbD1UUlVFfQojIExvYWQgYmFzaCB2YXJpYWJsZXMgaW50byBtZW1vcnkKc291cmNlIC5iYXNodmFycwoKIyBNYWtlIG91dHB1dCBkaXJlY3RvcnksIGlmIGl0IGRvZXNuJ3QgZXhpc3QKbWtkaXIgLS1wYXJlbnRzICIke291dHB1dF9kaXJfdG9wfSIKCnsKICAgYXdrICckMjAgPT0gIlkiICYmICQyMSAhPSAiTkEiIHtwcmludCAkMn0nICIke3Nob3J0c3RhY2tfZGlyfS8ke3Nob3J0c3RhY2tfcmVzdWx0c19maWxlfSIgXAogICB8IGdyZXAgLS1maXhlZC1zdHJpbmdzIC0tZmlsZSAtICIke3Nob3J0c3RhY2tfZGlyfS8ke3Nob3J0c3RhY2tfZml4ZWRfZmFzdGFfaW5kZXh9IiBcCiAgIHwgYXdrICd7cHJpbnQgJDF9Jwp9IFwKPiAiJHtvdXRwdXRfZGlyX3RvcH0vJHtyZWdpb25zfSIKCmhlYWQgIiR7b3V0cHV0X2Rpcl90b3B9LyR7cmVnaW9uc30iCgpgYGAKCgoKIyBFeHRyYWN0IEZhc3RBcwoKYGBge3IgZXh0cmFjdC1GYXN0QXMsIGVuZ2luZT0nYmFzaCcsIGV2YWw9VFJVRX0KIyBMb2FkIGJhc2ggdmFyaWFibGVzIGludG8gbWVtb3J5CnNvdXJjZSAuYmFzaHZhcnMKCiR7c2FtdG9vbHN9IGZhaWR4ICIke3Nob3J0c3RhY2tfZGlyfS8ke3Nob3J0c3RhY2tfZml4ZWRfZmFzdGF9IiBcCi0tcmVnaW9uLWZpbGUgIiR7b3V0cHV0X2Rpcl90b3B9LyR7cmVnaW9uc30iIFwKPiAiJHtvdXRwdXRfZGlyX3RvcH0vJHtvdXRwdXRfZmFzdGF9IgoKaGVhZCAiJHtvdXRwdXRfZGlyX3RvcH0vJHtvdXRwdXRfZmFzdGF9IgoKZWNobyAiIgplY2hvICIiCmVjaG8gIiIKZWNobyAiTnVtYmVyIG9mIEZhc3RBIHNlcXVlbmNlczoiCmdyZXAgIl4+IiAtLWNvdW50ICIke291dHB1dF9kaXJfdG9wfS8ke291dHB1dF9mYXN0YX0iCgpgYGA=