Intro

This Workflow

This workflow takes an excerpt from the microbiome_new_data script with instructions for constructing a representative phylogenetic tree from your 16S sequencing results and expands on that to increase the flexibility of your phylogenetic tree data for downstream processing.

Phylo Trees and ONT Data

Some of the standard microbiome profiling metrics rely on on an OTU approach developed for the more traditional short-read sequences produced by Illumina and other nextgen platforms. Constructing representative sequences for each OTU enables phylogenetic analyses that can be particularly useful in visualizations.

ONT Reads are generally still too messy and long to smoothly produce consensus sequences for each taxon. I use a workaround to enable us to still generate some phylogenetic estimates and graphics, though we will really be visualizing the relationships between the reference sequences for each taxon that our reads align to. The first step of this will use Entrez Direct to source a reference fasta for each of the taxids from our minimap2 results.

The Data Used Here

I am writing this script with a version of our lab’s pygmy loris microbiome data. If you are working on one of our other microbiome projects, it should be fairly simple to adapt the original .Rmd script you are reading to a different dataset, especially if you make use of the params settings in the yaml header at the top.

The Workflow

Fetch Reference FASTA Sequences

Taxonomy List

First, we will read in our raw alignment data gathered from the wf-16s output.

alignments <- read_tsv("microeco/loris/alignments.tsv")
refseqs <- distinct(alignments, ref, taxid)
write_tsv(refseqs, "microeco/loris/fetch_references.txt")

Transfer the fetch_references.txt file from your local directory to the proper directory on Swan and then run the script below.

Tip

I create a mirror of my repository/directory on Swan so that I can just keep updating repositories as I move between swan and my local R consol.


Fetch New References Using Entrez Direct

Now you need to switch to the terminal and log into the HCC. We will use the entrez-direct package to interface with NCBI’s databases adn fetch our reference sequences. If you have not used the HCC before, then refer to the readprocessing_multiplex_16s script for more details.

Note: I recently discovered the R package taxreturn which looks like an appealing alternative to do this straight from the R console, so feel free to experiment with it if you are feeling adventurous.

Batch Script

#!/bin/bash
#SBATCH --time=1:00:00
#SBATCH --job-name=fetch_refs
#SBATCH --error=/work/richlab/aliciarich/bioinformatics_stats/logs/fetch_refs_%A_%a.err
#SBATCH --output=/work/richlab/aliciarich/bioinformatics_stats/logs/fetch_refs_%A_%a.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --mem=100GB
#SBATCH --partition=guest

module purge
module load entrez-direct
module load seqkit 

uid_file="/work/richlab/aliciarich/bioinformatics_stats/microeco/loris/fetch_references.txt"
accessions_file="/work/richlab/aliciarich/bioinformatics_stats/microeco/loris/accessions.txt"
fasta_file="/work/richlab/aliciarich/bioinformatics_stats/microeco/loris/refs_unaligned.fasta"


> "$fasta_file"

cut -f1 "$uid_file" > "$accessions_file"

if efetch -db nuccore -input "$accessions_file" -format fasta -email "aliciarich@unomaha.edu" > "$fasta_file"; then
    echo "Sequences fetched successfully."
else
    echo "Error fetching sequences." >&2
    exit 1
fi

Submit Batch Script

cd "/work/richlab/aliciarich/bioinformatics_stats/batch_scripts"
sbatch "fetch_refs.sh"

Once the script finishes running, transfer the refs_unaligned.fasta file from the directory on Swan to the local matching directory to run the next step in R.


Relabel Sequences

refs_unaligned <- treeio::read.fasta("microeco/loris/refs_unaligned.fasta")

refs_labels <- enframe(labels(refs_unaligned), name = NULL, value = "label") %>%
  mutate(accession = str_extract(label, "^\\w{2}_\\d+\\.\\d(?=\\s.+)")) %>%
  left_join(select(alignments, superkingdom:taxid), by = join_by(accession == ref)) %>%
  mutate(taxid = as.character(str_glue("txid{taxid}"))) %>%
  arrange(superkingdom,
          phylum,
          class,
          order,
          family,
          genus,
          species,
          accession) %>%
  select(
    superkingdom:species,
    taxid,
    accession,
    label
  )
write_tsv(refs_labels, "microeco/loris/reference_key.tsv")
refs_rename <- refs_labels %>%
  select(label, taxid)

rename.fasta("microeco/loris/refs_unaligned.fasta", refs_rename, "microeco/loris/refs_renamed.fasta")
microeco/loris/refs_renamed.fasta has been saved to  /Users/aliciamrich/GitRepos/richlab_main/bioinformatics_stats 

Align Sequences and Build ML Tree

Batch Script

#!/bin/bash
#SBATCH --job-name=mafft_iqtree
#SBATCH --error=/work/richlab/aliciarich/bioinformatics_stats/logs/mafft_iqtree_%A.err
#SBATCH --output=/work/richlab/aliciarich/bioinformatics_stats/logs/mafft_iqtree_%A.out
#SBATCH --partition=guest
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=8         
#SBATCH --mem=64G                 
#SBATCH --time=6:00:00            

module purge
module load mafft/7.526
module load iqtree/2.3


input_fasta="/work/richlab/aliciarich/bioinformatics_stats/microeco/loris/refs_renamed.fasta"
aligned_fasta="/work/richlab/aliciarich/bioinformatics_stats/microeco/loris/refs_aligned_mafft.fasta"
out_prefix="/work/richlab/aliciarich/bioinformatics_stats/microeco/loris/refs_tree"

mafft \
  --thread 8 \
  --retree 2 \
  --maxiterate 1000 \
  "$input_fasta" > "$aligned_fasta"
  

iqtree -s $aligned_fasta \
        -m MFP+MERGE \
        -B 1000 \
        -T $SLURM_CPUS_PER_TASK \
        -pre "$out_prefix" \
        -redo
  

Submit Batch Script

cd "/work/richlab/aliciarich/bioinformatics_stats/batch_scripts"
sbatch "mafft_iqtree.sh"

Once the script finishes running, transfer the refs_aligned_mafft.fasta and refs_tree.treefile files from the directory on Swan to the local matching directory to run the next step in R.

Note the Final Model Used

I also like to extract the bottom of the log file produced to keep this note on the alignment model that the MAFFT algorithm selected. It just makes it easier for copying and pasting into manuscripts later.

alg=A, model=DNA200 (2), 1.53 (4.59), -0.00 (-0.00), noshift, amax=0.0
8 thread(s)

Strategy:
 FFT-NS-i (Accurate but slow)
 Iterative refinement method (max. 16 iterations)

Next Steps

Proceed to the microbiome_preprocessing tutorial to merge these with your other microbiome results before cleaning and filtering your dataset.

LS0tCnRpdGxlOiAiV29ya2luZyB3aXRoIDE2UyBEYXRhIGFuZCBSZWZlcmVuY2UgU2VxdWVuY2VzIgphdXRob3I6ICJBbGljaWEgTS4gUmljaCwgUGguRC4iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZToKICAgICAgYnNsaWI6IHRydWUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiAzCiAgICBkZl9wcmludDogcGFnZWQKICAgIGNzczogam91cm5hbC5jc3MKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShjb25mbGljdGVkKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShic2xpYikKbGlicmFyeShodG1sdG9vbHMpCmxpYnJhcnkobWljcm9lY28pCmxpYnJhcnkoc2VxaW5yKQpsaWJyYXJ5KGFwZSkKbGlicmFyeShndEV4dHJhcykKbGlicmFyeShnZ3RyZWUpCmxpYnJhcnkodHJlZWRhdGF2ZXJzZSkKbGlicmFyeShwaHlsb3Rvb2xzKQpsaWJyYXJ5KFRyZWVUb29scykKCgpzb3VyY2UoInNldHVwL2tuaXRfZW5naW5lc19zaW1wbGUuUiIpCnNvdXJjZSgic2V0dXAvY29uZmxpY3RlZC5SIikKCmBgYAoKIyBJbnRybwoKIyMgVGhpcyBXb3JrZmxvdwoKVGhpcyB3b3JrZmxvdyB0YWtlcyBhbiBleGNlcnB0IGZyb20gdGhlIGBtaWNyb2Jpb21lX25ld19kYXRhYCBzY3JpcHQgd2l0aCBpbnN0cnVjdGlvbnMgZm9yIGNvbnN0cnVjdGluZyBhIHJlcHJlc2VudGF0aXZlIHBoeWxvZ2VuZXRpYyB0cmVlIGZyb20geW91ciAxNlMgc2VxdWVuY2luZyByZXN1bHRzIGFuZCBleHBhbmRzIG9uIHRoYXQgdG8gaW5jcmVhc2UgdGhlIGZsZXhpYmlsaXR5IG9mIHlvdXIgcGh5bG9nZW5ldGljIHRyZWUgZGF0YSBmb3IgZG93bnN0cmVhbSBwcm9jZXNzaW5nLiAKCiMjIFBoeWxvIFRyZWVzIGFuZCBPTlQgRGF0YQoKU29tZSBvZiB0aGUgc3RhbmRhcmQgbWljcm9iaW9tZSBwcm9maWxpbmcgbWV0cmljcyByZWx5IG9uIG9uIGFuIE9UVSBhcHByb2FjaCBkZXZlbG9wZWQgZm9yIHRoZSBtb3JlIHRyYWRpdGlvbmFsIHNob3J0LXJlYWQgc2VxdWVuY2VzIHByb2R1Y2VkIGJ5IElsbHVtaW5hIGFuZCBvdGhlciBuZXh0Z2VuIHBsYXRmb3Jtcy4gQ29uc3RydWN0aW5nIHJlcHJlc2VudGF0aXZlIHNlcXVlbmNlcyBmb3IgZWFjaCBPVFUgZW5hYmxlcyBwaHlsb2dlbmV0aWMgYW5hbHlzZXMgdGhhdCBjYW4gYmUgcGFydGljdWxhcmx5IHVzZWZ1bCBpbiB2aXN1YWxpemF0aW9ucy4gIAogIApPTlQgUmVhZHMgYXJlIGdlbmVyYWxseSBzdGlsbCB0b28gbWVzc3kgYW5kIGxvbmcgdG8gc21vb3RobHkgcHJvZHVjZSBjb25zZW5zdXMgc2VxdWVuY2VzIGZvciBlYWNoIHRheG9uLiBJIHVzZSBhIHdvcmthcm91bmQgdG8gZW5hYmxlIHVzIHRvIHN0aWxsIGdlbmVyYXRlIHNvbWUgcGh5bG9nZW5ldGljIGVzdGltYXRlcyBhbmQgZ3JhcGhpY3MsIHRob3VnaCB3ZSB3aWxsIHJlYWxseSBiZSB2aXN1YWxpemluZyB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSByZWZlcmVuY2Ugc2VxdWVuY2VzIGZvciBlYWNoIHRheG9uIHRoYXQgb3VyIHJlYWRzIGFsaWduIHRvLiBUaGUgZmlyc3Qgc3RlcCBvZiB0aGlzIHdpbGwgdXNlIEVudHJleiBEaXJlY3QgdG8gc291cmNlIGEgcmVmZXJlbmNlIGZhc3RhIGZvciBlYWNoIG9mIHRoZSB0YXhpZHMgZnJvbSBvdXIgbWluaW1hcDIgcmVzdWx0cy4gIAoKCiMjIFRoZSBEYXRhIFVzZWQgSGVyZQoKSSBhbSB3cml0aW5nIHRoaXMgc2NyaXB0IHdpdGggYSB2ZXJzaW9uIG9mIG91ciBsYWIncyBweWdteSBsb3JpcyBtaWNyb2Jpb21lIGRhdGEuIElmIHlvdSBhcmUgd29ya2luZyBvbiBvbmUgb2Ygb3VyIG90aGVyIG1pY3JvYmlvbWUgcHJvamVjdHMsIGl0IHNob3VsZCBiZSBmYWlybHkgc2ltcGxlIHRvIGFkYXB0IHRoZSBvcmlnaW5hbCAuUm1kIHNjcmlwdCB5b3UgYXJlIHJlYWRpbmcgdG8gYSBkaWZmZXJlbnQgZGF0YXNldCwgZXNwZWNpYWxseSBpZiB5b3UgbWFrZSB1c2Ugb2YgdGhlIHBhcmFtcyBzZXR0aW5ncyBpbiB0aGUgeWFtbCBoZWFkZXIgYXQgdGhlIHRvcC4KCiMjIFJlY29tbWVuZGVkIFJlYWRpbmcKCkZvciBhIGhlbHBmdWwgZ3VpZGUsIEkgcmVjb21tZW5kIHlvdSBsb29rIGF0IHRoaXMgb25saW5lIGJvb2s6IFtEYXRhIEludGVncmF0aW9uLCBNYW5pcHVsYXRpb24gYW5kIFZpc3VhbGl6YXRpb24gb2YgUGh5bG9nZW5ldGljIFRyZWVzXShodHRwczovL3l1bGFiLXNtdS50b3AvdHJlZWRhdGEtYm9vay9pbmRleC5odG1sKS4KCiMgVGhlIFdvcmtmbG93CgojIyBGZXRjaCBSZWZlcmVuY2UgRkFTVEEgU2VxdWVuY2VzCgojIyMgVGF4b25vbXkgTGlzdAoKRmlyc3QsIHdlIHdpbGwgcmVhZCBpbiBvdXIgcmF3IGFsaWdubWVudCBkYXRhIGdhdGhlcmVkIGZyb20gdGhlIHdmLTE2cyBvdXRwdXQuCgpgYGB7cn0KYWxpZ25tZW50cyA8LSByZWFkX3RzdigibWljcm9lY28vbG9yaXMvYWxpZ25tZW50cy50c3YiKQpyZWZzZXFzIDwtIGRpc3RpbmN0KGFsaWdubWVudHMsIHJlZiwgdGF4aWQpCndyaXRlX3RzdihyZWZzZXFzLCAibWljcm9lY28vbG9yaXMvZmV0Y2hfcmVmZXJlbmNlcy50eHQiKQpgYGAKCgpUcmFuc2ZlciB0aGUgZmV0Y2hfcmVmZXJlbmNlcy50eHQgZmlsZSBmcm9tIHlvdXIgbG9jYWwgZGlyZWN0b3J5IHRvIHRoZSBwcm9wZXIgZGlyZWN0b3J5IG9uIFN3YW4gYW5kIHRoZW4gcnVuIHRoZSBzY3JpcHQgYmVsb3cuICAKICAKPGRldGFpbHM+CjxzdW1tYXJ5PioqKlRpcCoqKjwvc3VtbWFyeT4KPHA+SSBjcmVhdGUgYSBtaXJyb3Igb2YgbXkgcmVwb3NpdG9yeS9kaXJlY3Rvcnkgb24gU3dhbiBzbyB0aGF0IEkgY2FuIGp1c3Qga2VlcCB1cGRhdGluZyByZXBvc2l0b3JpZXMgYXMgSSBtb3ZlIGJldHdlZW4gc3dhbiBhbmQgbXkgbG9jYWwgUiBjb25zb2wuPC9wPgo8L2RldGFpbHM+CgotLS0KCiMjIEZldGNoIE5ldyBSZWZlcmVuY2VzIFVzaW5nIEVudHJleiBEaXJlY3QKCk5vdyB5b3UgbmVlZCB0byBzd2l0Y2ggdG8gdGhlIHRlcm1pbmFsIGFuZCBsb2cgaW50byB0aGUgSENDLiBXZSB3aWxsIHVzZSB0aGUgZW50cmV6LWRpcmVjdCBwYWNrYWdlIHRvIGludGVyZmFjZSB3aXRoIE5DQkkncyBkYXRhYmFzZXMgYWRuIGZldGNoIG91ciByZWZlcmVuY2Ugc2VxdWVuY2VzLiBJZiB5b3UgaGF2ZSBub3QgdXNlZCB0aGUgSENDIGJlZm9yZSwgdGhlbiByZWZlciB0byB0aGUgW3JlYWRwcm9jZXNzaW5nX211bHRpcGxleF8xNnNdKGh0dHBzOi8vcmljaC1tb2xlY3VsYXItaGVhbHRoLWxhYi5naXRodWIuaW8vdHV0b3JpYWxzL3JlYWRwcm9jZXNzaW5nX211bHRpcGxleF8xNnMuaHRtbCkgc2NyaXB0IGZvciBtb3JlIGRldGFpbHMuCgo+Kk5vdGU6IEkgcmVjZW50bHkgZGlzY292ZXJlZCB0aGUgUiBwYWNrYWdlIFtgdGF4cmV0dXJuYF0oaHR0cHM6Ly9hbGV4cGlwZXIuZ2l0aHViLmlvL3RheHJldHVybi9pbmRleC5odG1sKSB3aGljaCBsb29rcyBsaWtlIGFuIGFwcGVhbGluZyBhbHRlcm5hdGl2ZSB0byBkbyB0aGlzIHN0cmFpZ2h0IGZyb20gdGhlIFIgY29uc29sZSwgc28gZmVlbCBmcmVlIHRvIGV4cGVyaW1lbnQgd2l0aCBpdCBpZiB5b3UgYXJlIGZlZWxpbmcgYWR2ZW50dXJvdXMuKgoKIyMjIEJhdGNoIFNjcmlwdAoKYGBge3Rlcm1pbmFsLCB3YXJuaW5nID0gRkFMU0UsIGVjaG8gPSBGQUxTRX0KIyEvYmluL2Jhc2gKI1NCQVRDSCAtLXRpbWU9MTowMDowMAojU0JBVENIIC0tam9iLW5hbWU9ZmV0Y2hfcmVmcwojU0JBVENIIC0tZXJyb3I9L3dvcmsvcmljaGxhYi9hbGljaWFyaWNoL2Jpb2luZm9ybWF0aWNzX3N0YXRzL2xvZ3MvZmV0Y2hfcmVmc18lQV8lYS5lcnIKI1NCQVRDSCAtLW91dHB1dD0vd29yay9yaWNobGFiL2FsaWNpYXJpY2gvYmlvaW5mb3JtYXRpY3Nfc3RhdHMvbG9ncy9mZXRjaF9yZWZzXyVBXyVhLm91dAojU0JBVENIIC0tbm9kZXM9MQojU0JBVENIIC0tbnRhc2tzLXBlci1ub2RlPTEKI1NCQVRDSCAtLW1lbT0xMDBHQgojU0JBVENIIC0tcGFydGl0aW9uPWd1ZXN0Cgptb2R1bGUgcHVyZ2UKbW9kdWxlIGxvYWQgZW50cmV6LWRpcmVjdAptb2R1bGUgbG9hZCBzZXFraXQgCgp1aWRfZmlsZT0iL3dvcmsvcmljaGxhYi9hbGljaWFyaWNoL2Jpb2luZm9ybWF0aWNzX3N0YXRzL21pY3JvZWNvL2xvcmlzL2ZldGNoX3JlZmVyZW5jZXMudHh0IgphY2Nlc3Npb25zX2ZpbGU9Ii93b3JrL3JpY2hsYWIvYWxpY2lhcmljaC9iaW9pbmZvcm1hdGljc19zdGF0cy9taWNyb2Vjby9sb3Jpcy9hY2Nlc3Npb25zLnR4dCIKZmFzdGFfZmlsZT0iL3dvcmsvcmljaGxhYi9hbGljaWFyaWNoL2Jpb2luZm9ybWF0aWNzX3N0YXRzL21pY3JvZWNvL2xvcmlzL3JlZnNfdW5hbGlnbmVkLmZhc3RhIgoKCj4gIiRmYXN0YV9maWxlIgoKY3V0IC1mMSAiJHVpZF9maWxlIiA+ICIkYWNjZXNzaW9uc19maWxlIgoKaWYgZWZldGNoIC1kYiBudWNjb3JlIC1pbnB1dCAiJGFjY2Vzc2lvbnNfZmlsZSIgLWZvcm1hdCBmYXN0YSAtZW1haWwgImFsaWNpYXJpY2hAdW5vbWFoYS5lZHUiID4gIiRmYXN0YV9maWxlIjsgdGhlbgogICAgZWNobyAiU2VxdWVuY2VzIGZldGNoZWQgc3VjY2Vzc2Z1bGx5LiIKZWxzZQogICAgZWNobyAiRXJyb3IgZmV0Y2hpbmcgc2VxdWVuY2VzLiIgPiYyCiAgICBleGl0IDEKZmkKCmBgYAoKIyMjIFN1Ym1pdCBCYXRjaCBTY3JpcHQKCmBgYHt0ZXJtaW5hbCwgd2FybmluZyA9IEZBTFNFLCBlY2hvID0gRkFMU0V9CmNkICIvd29yay9yaWNobGFiL2FsaWNpYXJpY2gvYmlvaW5mb3JtYXRpY3Nfc3RhdHMvYmF0Y2hfc2NyaXB0cyIKc2JhdGNoICJmZXRjaF9yZWZzLnNoIgpgYGAKCk9uY2UgdGhlIHNjcmlwdCBmaW5pc2hlcyBydW5uaW5nLCB0cmFuc2ZlciB0aGUgYHJlZnNfdW5hbGlnbmVkLmZhc3RhYCBmaWxlIGZyb20gdGhlIGRpcmVjdG9yeSBvbiBTd2FuIHRvIHRoZSBsb2NhbCBtYXRjaGluZyBkaXJlY3RvcnkgdG8gcnVuIHRoZSBuZXh0IHN0ZXAgaW4gUi4KCi0tLQoKIyMgUmVsYWJlbCBTZXF1ZW5jZXMKCmBgYHtyfQpyZWZzX3VuYWxpZ25lZCA8LSB0cmVlaW86OnJlYWQuZmFzdGEoIm1pY3JvZWNvL2xvcmlzL3JlZnNfdW5hbGlnbmVkLmZhc3RhIikKCnJlZnNfbGFiZWxzIDwtIGVuZnJhbWUobGFiZWxzKHJlZnNfdW5hbGlnbmVkKSwgbmFtZSA9IE5VTEwsIHZhbHVlID0gImxhYmVsIikgJT4lCiAgbXV0YXRlKGFjY2Vzc2lvbiA9IHN0cl9leHRyYWN0KGxhYmVsLCAiXlxcd3syfV9cXGQrXFwuXFxkKD89XFxzLispIikpICU+JQogIGxlZnRfam9pbihzZWxlY3QoYWxpZ25tZW50cywgc3VwZXJraW5nZG9tOnRheGlkKSwgYnkgPSBqb2luX2J5KGFjY2Vzc2lvbiA9PSByZWYpKSAlPiUKICBtdXRhdGUodGF4aWQgPSBhcy5jaGFyYWN0ZXIoc3RyX2dsdWUoInR4aWR7dGF4aWR9IikpKSAlPiUKICBhcnJhbmdlKHN1cGVya2luZ2RvbSwKICAgICAgICAgIHBoeWx1bSwKICAgICAgICAgIGNsYXNzLAogICAgICAgICAgb3JkZXIsCiAgICAgICAgICBmYW1pbHksCiAgICAgICAgICBnZW51cywKICAgICAgICAgIHNwZWNpZXMsCiAgICAgICAgICBhY2Nlc3Npb24pICU+JQogIHNlbGVjdCgKICAgIHN1cGVya2luZ2RvbTpzcGVjaWVzLAogICAgdGF4aWQsCiAgICBhY2Nlc3Npb24sCiAgICBsYWJlbAogICkKd3JpdGVfdHN2KHJlZnNfbGFiZWxzLCAibWljcm9lY28vbG9yaXMvcmVmZXJlbmNlX2tleS50c3YiKQpgYGAKCmBgYHtyfQpyZWZzX3JlbmFtZSA8LSByZWZzX2xhYmVscyAlPiUKICBzZWxlY3QobGFiZWwsIHRheGlkKQoKcmVuYW1lLmZhc3RhKCJtaWNyb2Vjby9sb3Jpcy9yZWZzX3VuYWxpZ25lZC5mYXN0YSIsIHJlZnNfcmVuYW1lLCAibWljcm9lY28vbG9yaXMvcmVmc19yZW5hbWVkLmZhc3RhIikKYGBgCgotLS0KCiMjIEFsaWduIFNlcXVlbmNlcyBhbmQgQnVpbGQgTUwgVHJlZQoKIyMjIEJhdGNoIFNjcmlwdAoKYGBge3Rlcm1pbmFsLCB3YXJuaW5nID0gRkFMU0UsIGVjaG8gPSBGQUxTRX0KIyEvYmluL2Jhc2gKI1NCQVRDSCAtLWpvYi1uYW1lPW1hZmZ0X2lxdHJlZQojU0JBVENIIC0tZXJyb3I9L3dvcmsvcmljaGxhYi9hbGljaWFyaWNoL2Jpb2luZm9ybWF0aWNzX3N0YXRzL2xvZ3MvbWFmZnRfaXF0cmVlXyVBLmVycgojU0JBVENIIC0tb3V0cHV0PS93b3JrL3JpY2hsYWIvYWxpY2lhcmljaC9iaW9pbmZvcm1hdGljc19zdGF0cy9sb2dzL21hZmZ0X2lxdHJlZV8lQS5vdXQKI1NCQVRDSCAtLXBhcnRpdGlvbj1ndWVzdAojU0JBVENIIC0tbm9kZXM9MQojU0JBVENIIC0tbnRhc2tzPTEKI1NCQVRDSCAtLWNwdXMtcGVyLXRhc2s9OCAgICAgICAgIAojU0JBVENIIC0tbWVtPTY0RyAgICAgICAgICAgICAgICAgCiNTQkFUQ0ggLS10aW1lPTY6MDA6MDAgICAgICAgICAgICAKCm1vZHVsZSBwdXJnZQptb2R1bGUgbG9hZCBtYWZmdC83LjUyNgptb2R1bGUgbG9hZCBpcXRyZWUvMi4zCgoKaW5wdXRfZmFzdGE9Ii93b3JrL3JpY2hsYWIvYWxpY2lhcmljaC9iaW9pbmZvcm1hdGljc19zdGF0cy9taWNyb2Vjby9sb3Jpcy9yZWZzX3JlbmFtZWQuZmFzdGEiCmFsaWduZWRfZmFzdGE9Ii93b3JrL3JpY2hsYWIvYWxpY2lhcmljaC9iaW9pbmZvcm1hdGljc19zdGF0cy9taWNyb2Vjby9sb3Jpcy9yZWZzX2FsaWduZWRfbWFmZnQuZmFzdGEiCm91dF9wcmVmaXg9Ii93b3JrL3JpY2hsYWIvYWxpY2lhcmljaC9iaW9pbmZvcm1hdGljc19zdGF0cy9taWNyb2Vjby9sb3Jpcy9yZWZzX3RyZWUiCgptYWZmdCBcCiAgLS10aHJlYWQgOCBcCiAgLS1yZXRyZWUgMiBcCiAgLS1tYXhpdGVyYXRlIDEwMDAgXAogICIkaW5wdXRfZmFzdGEiID4gIiRhbGlnbmVkX2Zhc3RhIgogIAoKaXF0cmVlIC1zICRhbGlnbmVkX2Zhc3RhIFwKICAgICAgICAtbSBNRlArTUVSR0UgXAogICAgICAgIC1CIDEwMDAgXAogICAgICAgIC1UICRTTFVSTV9DUFVTX1BFUl9UQVNLIFwKICAgICAgICAtcHJlICIkb3V0X3ByZWZpeCIgXAogICAgICAgIC1yZWRvCiAgCmBgYAoKIyMjIFN1Ym1pdCBCYXRjaCBTY3JpcHQKCmBgYHt0ZXJtaW5hbCwgd2FybmluZyA9IEZBTFNFLCBlY2hvID0gRkFMU0V9CmNkICIvd29yay9yaWNobGFiL2FsaWNpYXJpY2gvYmlvaW5mb3JtYXRpY3Nfc3RhdHMvYmF0Y2hfc2NyaXB0cyIKc2JhdGNoICJtYWZmdF9pcXRyZWUuc2giCmBgYAoKT25jZSB0aGUgc2NyaXB0IGZpbmlzaGVzIHJ1bm5pbmcsIHRyYW5zZmVyIHRoZSBgcmVmc19hbGlnbmVkX21hZmZ0LmZhc3RhYCBhbmQgYHJlZnNfdHJlZS50cmVlZmlsZWAgZmlsZXMgZnJvbSB0aGUgZGlyZWN0b3J5IG9uIFN3YW4gdG8gdGhlIGxvY2FsIG1hdGNoaW5nIGRpcmVjdG9yeSB0byBydW4gdGhlIG5leHQgc3RlcCBpbiBSLgoKIyMjIyBOb3RlIHRoZSBGaW5hbCBNb2RlbCBVc2VkCgpJIGFsc28gbGlrZSB0byBleHRyYWN0IHRoZSBib3R0b20gb2YgdGhlIGxvZyBmaWxlIHByb2R1Y2VkIHRvIGtlZXAgdGhpcyBub3RlIG9uIHRoZSBhbGlnbm1lbnQgbW9kZWwgdGhhdCB0aGUgTUFGRlQgYWxnb3JpdGhtIHNlbGVjdGVkLiBJdCBqdXN0IG1ha2VzIGl0IGVhc2llciBmb3IgY29weWluZyBhbmQgcGFzdGluZyBpbnRvIG1hbnVzY3JpcHRzIGxhdGVyLgoKYGBgCmFsZz1BLCBtb2RlbD1ETkEyMDAgKDIpLCAxLjUzICg0LjU5KSwgLTAuMDAgKC0wLjAwKSwgbm9zaGlmdCwgYW1heD0wLjAKOCB0aHJlYWQocykKClN0cmF0ZWd5OgogRkZULU5TLWkgKEFjY3VyYXRlIGJ1dCBzbG93KQogSXRlcmF0aXZlIHJlZmluZW1lbnQgbWV0aG9kIChtYXguIDE2IGl0ZXJhdGlvbnMpCmBgYAoKLS0tCgojIE5leHQgU3RlcHMKClByb2NlZWQgdG8gdGhlIFtgbWljcm9iaW9tZV9wcmVwcm9jZXNzaW5nYCB0dXRvcmlhbF0oaHR0cHM6Ly9yaWNoLW1vbGVjdWxhci1oZWFsdGgtbGFiLmdpdGh1Yi5pby90dXRvcmlhbHMvbWljcm9iaW9tZV9wcmVwcm9jZXNzaW5nLmh0bWwpIHRvIG1lcmdlIHRoZXNlIHdpdGggeW91ciBvdGhlciBtaWNyb2Jpb21lIHJlc3VsdHMgYmVmb3JlIGNsZWFuaW5nIGFuZCBmaWx0ZXJpbmcgeW91ciBkYXRhc2V0Lgo=