Introduction
Metagenomic analysis was conducted on our oral biofilm model to
assess the viability of the model as a proxy for dental calculus.
Materials
A total of 35 biofilm model samples were taken throughout the course
of the experiment and includes saliva inoculate, media from the wells,
and the biofilm end-product. DNA extraction was performed at the
archaeogenetic facility at the Max Planck Institute for the Science of
Human History (Jena, Germany).
Extractions were performed in duplicates. A total of
DNA extracts.
DNeasy PowerSoil Kit from QIAGEN. C2 inhibitor removal step skipped,
going directly to C3 step.
were paired-end sequenced on a NextSeq (2 color chemistry) to
150bp
Methods
Preprocessing
Processing of the raw DNA reads was conducted using the
nf-core/eager, v2.4.4 pipeline [@yatesEAGER2020]. Adapter removal and read
merging was performed using AdapterRemoval, v2.3.2 [@AdapterRemovalv2]. Merged reads were mapped to
the human reference genome, GRCh38, using BWA, v0.7.17-r1188 [@BWA] with default settings (-n 0.01; -l 32),
and unmapped reads were extracted using Samtools, v1.12.
Metagenomic classification was conducted in kraken, v2.1.2 using the
Standard database (https://benlangmead.github.io/aws-indexes/k2).
Kraken output reports were combined and converted to OTU tables, and
only species-level assignments were selected for downstream analysis 02-scripts/00-comb-kraken-reports.R.
The OTU tables were further filtered by removing species with relative
abundance lower than 0.001%.
Authentication
SourceTracker [@knightsSourceTracker2011] was used to estimate
source composition of the oral biofilm model samples using a Bayesian
framework. Samples were compared with oral and environmental controls to
detect potential external contamination.
Potential contaminants were identified using the frequency and
prevalence method in the decontam v1.16.0 [@R-decontam] R package. 02-scripts/02-authentication.R.
Samples from indoor_air, skin, and sediment
were used as negative controls for the prevalence method with a
probability threshold of 0.01. DNA
concentrations were used for the ‘frequency’ method with a
probability threshold of 0.99 and negative controls.
Putative contaminants were filtered out of the OTU tables for all
downstream analyses.
See 06-reports/metagen-authentication.Rmd
for more details.
Differential abundance analysis
Results
Authentication
SourceTracker
Results from SourceTracker indicated a large portion of species from
most samples are from an oral origin (plaque, saliva, or calculus). Some
samples contained a large proportion of species from potential
contaminants (indoor air) and of unknown origin. Potential contaminants
were compared to a database of oral bacteria to see the proportion of
known oral species were present in the samples. Many of the species
assigned to indoor_air
are known oral species (Figure
@ref(fig:st-plot)).
Based on these results, samples SYN015.F0101, SYN015.G0101,
SYN015.H0101, SYN017.F0101, SYN017.G0101, SYN018.H0101, SYN013.I0101,
SYN016.I0101 were removed from further analysis. The removed samples
were all sampled late in the experiment (day 18+).
decontam
A total of 5424 potential contaminants were removed. Remaining counts
of species in the biofilm samples ranged between 88 and 284 with a mean
of 181.59.
LS0tCnRpdGxlOiAiU3VtbWFyeSBvZiBtZXRhZ2Vub21pYyBhbmFseXNpcyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CiN8IGxhYmVsOiBzZXR1cAojfCBpbmNsdWRlOiBmYWxzZQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGN1cGVyZGVjKQpsaWJyYXJ5KHBhdGNod29yaykKbGlicmFyeShtaXhPbWljcykKIyBzZXQgZG9jdW1lbnQgY2h1bmsgb3B0aW9ucwprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IEZBTFNFLAogIHdhcm5pbmcgPSBGQUxTRSwKICBtZXNzYWdlID0gRkFMU0UKKQojIG1ldGFkYXRhCm1ldGFkYXRhIDwtIHJlYWRfdHN2KGhlcmUoIjAxLWRvY3VtZW50YXRpb24vbWV0YWRhdGEudHN2IikpCmV4cGVyaW1lbnRfbWV0YWRhdGEgPC0gcmVhZF90c3YoaGVyZSgiMDEtZG9jdW1lbnRhdGlvbi9leHBlcmltZW50LW1ldGFkYXRhLnRzdiIpKQphbmFseXNpc19tZXRhZGF0YSA8LSByZWFkX3RzdihoZXJlKCIwMS1kb2N1bWVudGF0aW9uL2FuYWx5c2lzLW1ldGFkYXRhLnRzdiIpKQpzb2Z0d2FyZSA8LSByZWFkX3RzdihoZXJlKCIwMS1kb2N1bWVudGF0aW9uL3NvZnR3YXJlX3ZlcnNpb25zLmNzdiIpLCBjb2xfbmFtZXMgPSBjKCJzb2Z0d2FyZSIsICJ2ZXJzaW9uIikpCmNvbmRhX2VudiA8LSByZWFkX3RzdihoZXJlKCIwMS1kb2N1bWVudGF0aW9uL2NvbmRhX3ZlcnNpb25zLnRzdiIpLCBza2lwID0gMikKbGliX2NvbmMgPC0gcmVhZF90c3YoaGVyZSgiMDEtZG9jdW1lbnRhdGlvbi9TWU5fRE5BX2NvbmNlbnRyYXRpb25zLnRzdiIpKQojIGFuYWx5c2lzIHJlc3VsdHMKc291cmNldHJhY2tlcjIgPC0gcmVhZF90c3YoaGVyZSgiMDQtYW5hbHlzaXMvc291cmNldHJhY2tlci9zb3VyY2V0cmFja2VyMl9vdXRwdXQvbWl4aW5nX3Byb3BvcnRpb25zLnR4dCIpKQphbGxfZGF0YV9sb25nIDwtIHJlYWRfdHN2KGhlcmUoIjA0LWFuYWx5c2lzL3NvdXJjZXRyYWNrZXIvc291cmNlLWNvbWJfbG9uZy50c3YiKSkKbGlzdF9vZl9jb250YW1pbmFudHMgPC0gcmVhZF90c3YoaGVyZSgiMDQtYW5hbHlzaXMvZGVjb250YW0vbGlzdC1vZi1jb250YW1pbmFudHMudHh0IiksIGNvbF9uYW1lcyA9IEYpCm9yYWxfdGF4YSA8LSBjdXBlcmRlY19kYXRhYmFzZV9leCAlPiUKICBmaWx0ZXIoaXNvbGF0aW9uX3NvdXJjZSA9PSAib3JhbCIpCmJhY19wcm9wZXJ0aWVzIDwtIHJlYWRfdHN2KGhlcmUoIjAxLWRvY3VtZW50YXRpb24vc3BlY2llcy1wcm9wZXJ0aWVzLnRzdiIpKQpvdHVfdGFibGUgPC0gcmVhZF90c3YoaGVyZSgiMDUtcmVzdWx0cy9wb3N0LWRlY29udGFtX3RheGF0YWJsZS50c3YiKSkKYWxwaGFfZGl2IDwtIHJlYWRfdHN2KGhlcmUoIjA1LXJlc3VsdHMvYWxwaGEtZGl2ZXJzaXR5LnRzdiIpKQpsb2FkKGhlcmUoIjA1LXJlc3VsdHMvc3BjYV9ieW9jLnJkYSIpKQpsb2FkKGhlcmUoIjA1LXJlc3VsdHMvc3BjYV9zcGVjaWVzLnJkYSIpKQoKIyBjb252ZXJ0IHBvc3QtZGVjb250YW0gT1RVIHRhYmxlIHRvIGxvbmcgZm9ybWF0IGZvciBlYXNpZXIgd3JhbmdsaW5nCnNwZWNpZXNfY291bnRzX2xvbmcgPC0gb3R1X3RhYmxlICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gd2hlcmUoaXMubnVtZXJpYyksIG5hbWVzX3RvID0gInNhbXBsZSIsIHZhbHVlc190byA9ICJjb3VudCIpCgojIEhlbHBlciBvYmplY3RzCmRheV9vcmRlciA8LSBleHBlcmltZW50X21ldGFkYXRhICU+JQogIG11dGF0ZShFbnYgPSBmYWN0b3IoCiAgICBFbnYsIAogICAgbGV2ZWxzID0gYygic2FsaXZhIiwgIm1lZGl1bSIsICJieW9jX2NhbGN1bHVzIikgIyBmb3JjZSBsZXZlbCBvcmRlciBzbyBpdCBkb2Vzbid0IG9yZGVyIGFscGhhYmV0aWNhbGx5CiAgICApIAogICkgJT4lIAogIGdyb3VwX2J5KEVudikgJT4lCiAgYXJyYW5nZShkYXksIC5ieV9ncm91cCA9IFQpICU+JQogIGZpbHRlcihgI1NhbXBsZUlEYCAlaW4lIGNvbG5hbWVzKHNvdXJjZXRyYWNrZXIyKSkgJT4lCiAgbXV0YXRlKHJtID0gaWZfZWxzZShgI1NhbXBsZUlEYCAlaW4lIGFuYWx5c2lzX21ldGFkYXRhJGAjU2FtcGxlSURgLCBGLCBUKSwKICAgICAgICAgY29sID0gY2FzZV93aGVuKHJtID09IFQgfiAicmVkIiwgIyBleGNsdWRlZCBzYW1wbGVzIGNvbG91cmVkIHJlZAogICAgICAgICAgICAgICAgICAgICAgICAgcm0gPT0gRiB+ICJibGFjayIpKQp0cmVhdG1lbnRfY29sb3VycyA8LSB2aXJpZGlzTGl0ZTo6aW5mZXJubyhuID0gbGVuZ3RoKHVuaXF1ZShleHBlcmltZW50X21ldGFkYXRhJHRyZWF0bWVudCkpKSAjIGRlZmluZSBwYWxsZXR0ZSBhbmQgbnVtYmVyIG9mIGNvbG91cnMKZW52X2NvbG91cnMgPC0gdmlyaWRpc0xpdGU6Om1hZ21hKG4gPSBsZW5ndGgodW5pcXVlKGFuYWx5c2lzX21ldGFkYXRhJEVudikpKSAjIGRlZmluZSBwYWxsZXR0ZSBhbmQgbnVtYmVyIG9mIGNvbG91cnMKCmV4cGVyaW1lbnRfY29sb3VycyA8LSBleHBlcmltZW50X21ldGFkYXRhICU+JQogIGFycmFuZ2UoZGVzYyhkYXkpKSAlPiUgCiAgbXV0YXRlKHRyZWF0X2NvbCA9IGNhc2Vfd2hlbigKICAgICAgICAgICB0cmVhdG1lbnQgPT0gInBvdGF0byIgfiB0cmVhdG1lbnRfY29sb3Vyc1sxXSwKICAgICAgICAgICB0cmVhdG1lbnQgPT0gIndoZWF0IiB+IHRyZWF0bWVudF9jb2xvdXJzWzJdLAogICAgICAgICAgIHRyZWF0bWVudCA9PSAibWl4IiB+IHRyZWF0bWVudF9jb2xvdXJzWzNdLAogICAgICAgICAgIHRyZWF0bWVudCA9PSAiY29udHJvbCIgfiB0cmVhdG1lbnRfY29sb3Vyc1s0XSwKICAgICAgICAgICBpcy5uYSh0cmVhdG1lbnQpIH4gImdyZXkiKSwKICAgICAgICAgZW52X2NvbCA9IGNhc2Vfd2hlbigKICAgICAgICAgICBFbnYgPT0gInNhbGl2YSIgfiBlbnZfY29sb3Vyc1s1XSwKICAgICAgICAgICBFbnYgPT0gImJ5b2NfY2FsY3VsdXMiIH4gZW52X2NvbG91cnNbMV0sCiAgICAgICAgICAgRW52ID09ICJtZWRpdW0iIH4gZW52X2NvbG91cnNbOF0KICAgICAgICAgKSkKYW5hbHlzaXNfY29sb3VycyA8LSBhbmFseXNpc19tZXRhZGF0YSAlPiUKICBtdXRhdGUoZW52X2NvbCA9IGNhc2Vfd2hlbigKICAgIEVudiA9PSAic2FsaXZhIiB+IGVudl9jb2xvdXJzWzVdLAogICAgRW52ID09ICJieW9jX2NhbGN1bHVzIiB+IGVudl9jb2xvdXJzWzFdLAogICAgRW52ID09ICJtZWRpdW0iIH4gZW52X2NvbG91cnNbOF0sCiAgICBFbnYgPT0gImJ1Y2NhbF9tdWNvc2EiIH4gZW52X2NvbG91cnNbNl0sCiAgICBFbnYgPT0gInN1YmdpbmdpdmFsX3BsYXF1ZSIgfiBlbnZfY29sb3Vyc1syXSwKICAgIEVudiA9PSAic3VwcmFnaW5naXZhbF9wbGFxdWUiIH4gZW52X2NvbG91cnNbM10sCiAgICBFbnYgPT0gIm1vZGVybl9jYWxjdWx1cyIgfiBlbnZfY29sb3Vyc1s0XSwKICAgIEVudiA9PSAidml0cm9fYmlvZmlsbSIgfiBlbnZfY29sb3Vyc1s3XQogICAgICAgICApKQpgYGAKCgojIyBJbnRyb2R1Y3Rpb24KCk1ldGFnZW5vbWljIGFuYWx5c2lzIHdhcyBjb25kdWN0ZWQgb24gb3VyIG9yYWwgYmlvZmlsbSBtb2RlbCB0byBhc3Nlc3MgdGhlCnZpYWJpbGl0eSBvZiB0aGUgbW9kZWwgYXMgYSBwcm94eSBmb3IgZGVudGFsIGNhbGN1bHVzLgoKIyMgTWF0ZXJpYWxzCgpgYGB7cn0KbWV0YWRhdGEgJT4lCiAgZmlsdGVyKFN0dWR5ID09ICJ0aGlzX3N0dWR5IikKCmJ5b2Nfc2FtcGxlcyA8LSBtZXRhZGF0YSAlPiUgCiAgZmlsdGVyKHN0cl9kZXRlY3QoYCNTYW1wbGVJRGAsICJTWU4iKSkKYGBgCgpBIHRvdGFsIG9mIGByIG5yb3coYnlvY19zYW1wbGVzKWAgYmlvZmlsbSBtb2RlbCBzYW1wbGVzIHdlcmUgdGFrZW4gdGhyb3VnaG91dCB0aGUKY291cnNlIG9mIHRoZQpleHBlcmltZW50IGFuZCBpbmNsdWRlcyBzYWxpdmEgaW5vY3VsYXRlLCBtZWRpYSBmcm9tIHRoZSB3ZWxscywgYW5kIHRoZSBiaW9maWxtCmVuZC1wcm9kdWN0LiBETkEgZXh0cmFjdGlvbiB3YXMgcGVyZm9ybWVkIGF0IHRoZSBhcmNoYWVvZ2VuZXRpYyBmYWNpbGl0eSBhdCB0aGUKTWF4IFBsYW5jayBJbnN0aXR1dGUgZm9yIHRoZSBTY2llbmNlIG9mIEh1bWFuIEhpc3RvcnkgKEplbmEsIEdlcm1hbnkpLiAKCkV4dHJhY3Rpb25zIHdlcmUKcGVyZm9ybWVkIGluIGR1cGxpY2F0ZXM8IS0tID8/IC0tPi4gQSB0b3RhbCBvZiA8IS0tIHNhbXBsZSBzaXplIC0tPiBETkEgZXh0cmFjdHMuCgpETmVhc3kgUG93ZXJTb2lsIEtpdCBmcm9tIFFJQUdFTi4gQzIgaW5oaWJpdG9yIHJlbW92YWwgc3RlcCBza2lwcGVkLCBnb2luZyBkaXJlY3RseQp0byBDMyBzdGVwLgoKd2VyZSBwYWlyZWQtZW5kIHNlcXVlbmNlZCBvbiBhIE5leHRTZXEgKDIgY29sb3IgY2hlbWlzdHJ5KSB0byAxNTBicAoKIyMjIENvbXBhcmF0aXZlIHNhbXBsZXMKCmBgYHtyfQpjb21wX3NhbXBsZXMgPC0gbWV0YWRhdGEgJT4lCiAgZmlsdGVyKFByb2plY3QgIT0gInRoaXNfc3R1ZHkiKQoKY29tcF9zYW1wbGVzCmBgYAoKIyMgTWV0aG9kcwoKIyMjIFByZXByb2Nlc3NpbmcKClByb2Nlc3Npbmcgb2YgdGhlIHJhdyBETkEgcmVhZHMgd2FzIGNvbmR1Y3RlZCB1c2luZyB0aGUKYHIgcGFzdGUoZmlsdGVyKHNvZnR3YXJlLCBzdHJfZGV0ZWN0KHNvZnR3YXJlLCAiZWFnZXIiKSkpYApwaXBlbGluZSBbQHlhdGVzRUFHRVIyMDIwXS4KQWRhcHRlciByZW1vdmFsIGFuZCByZWFkIG1lcmdpbmcgd2FzIHBlcmZvcm1lZCB1c2luZwpgciBwYXN0ZShmaWx0ZXIoc29mdHdhcmUsIHN0cl9kZXRlY3Qoc29mdHdhcmUsIHJlZ2V4KCJhZGFwdGVycmVtb3ZhbCIsIGlnbm9yZV9jYXNlID0gVCkpKSlgCltAQWRhcHRlclJlbW92YWx2Ml0uIE1lcmdlZCByZWFkcyB3ZXJlIG1hcHBlZCB0byB0aGUgaHVtYW4gcmVmZXJlbmNlIGdlbm9tZSwKR1JDaDM4LCB1c2luZwpgciBwYXN0ZShmaWx0ZXIoc29mdHdhcmUsIHN0cl9kZXRlY3Qoc29mdHdhcmUsIHJlZ2V4KCJid2EiLCBpZ25vcmVfY2FzZSA9IFQpKSkpYApbQEJXQV0gd2l0aCBkZWZhdWx0IHNldHRpbmdzICgtbiAwLjAxOyAtbCAzMiksIGFuZCB1bm1hcHBlZCByZWFkcyB3ZXJlIGV4dHJhY3RlZAp1c2luZwpgciBwYXN0ZShmaWx0ZXIoc29mdHdhcmUsIHN0cl9kZXRlY3Qoc29mdHdhcmUsIHJlZ2V4KCJzYW10b29scyIsIGlnbm9yZV9jYXNlID0gVCkpKSlgLgoKTWV0YWdlbm9taWMgY2xhc3NpZmljYXRpb24gd2FzIGNvbmR1Y3RlZCBpbgpgciBwYXN0ZShmaWx0ZXIoc29mdHdhcmUsIHN0cl9kZXRlY3Qoc29mdHdhcmUsIHJlZ2V4KCJrcmFrZW4iLCBpZ25vcmVfY2FzZSA9IFQpKSkpYAp1c2luZyB0aGUgU3RhbmRhcmQgZGF0YWJhc2UgKGh0dHBzOi8vYmVubGFuZ21lYWQuZ2l0aHViLmlvL2F3cy1pbmRleGVzL2syKS4KCktyYWtlbiBvdXRwdXQgcmVwb3J0cyB3ZXJlIGNvbWJpbmVkIGFuZCBjb252ZXJ0ZWQgdG8gT1RVIHRhYmxlcywgYW5kIG9ubHkKc3BlY2llcy1sZXZlbCBhc3NpZ25tZW50cyB3ZXJlIHNlbGVjdGVkIGZvciBkb3duc3RyZWFtIGFuYWx5c2lzClswMi1zY3JpcHRzLzAwLWNvbWIta3Jha2VuLXJlcG9ydHMuUl0oMDItc2NyaXB0cy8wMC1jb21iLWtyYWtlbi1yZXBvcnRzLlIpLgpUaGUgT1RVIHRhYmxlcyB3ZXJlIGZ1cnRoZXIgZmlsdGVyZWQgYnkgcmVtb3Zpbmcgc3BlY2llcyB3aXRoIHJlbGF0aXZlIGFidW5kYW5jZQpsb3dlciB0aGFuIDAuMDAxJS4KCiMjIyBBdXRoZW50aWNhdGlvbgoKYGBge3J9CiN8IGxhYmVsOiBsaWItY29uYy10YWJsZQpsaWJfY29uYyAlPiUKICBrbml0cjo6a2FibGUoKQpgYGAKClNvdXJjZVRyYWNrZXIgW0BrbmlnaHRzU291cmNlVHJhY2tlcjIwMTFdIHdhcyB1c2VkIHRvIGVzdGltYXRlIHNvdXJjZSBjb21wb3NpdGlvbgpvZiB0aGUgb3JhbCBiaW9maWxtIG1vZGVsIHNhbXBsZXMgdXNpbmcgYSBCYXllc2lhbiBmcmFtZXdvcmsuIFNhbXBsZXMgd2VyZSBjb21wYXJlZAp3aXRoIG9yYWwgYW5kIGVudmlyb25tZW50YWwgY29udHJvbHMgdG8gZGV0ZWN0IHBvdGVudGlhbCBleHRlcm5hbCBjb250YW1pbmF0aW9uLgoKUG90ZW50aWFsIGNvbnRhbWluYW50cyB3ZXJlIGlkZW50aWZpZWQgdXNpbmcgdGhlIGZyZXF1ZW5jeSBhbmQgcHJldmFsZW5jZSBtZXRob2QKaW4gdGhlICoqZGVjb250YW0qKiB2YHIgcGFja2FnZVZlcnNpb24oImRlY29udGFtIilgIFtAUi1kZWNvbnRhbV0gUiBwYWNrYWdlLgpbMDItc2NyaXB0cy8wMi1hdXRoZW50aWNhdGlvbi5SXSguLi8wMi1zY3JpcHRzLzAyLWF1dGhlbnRpY2F0aW9uLlIpLiBTYW1wbGVzCmZyb20gKmluZG9vcl9haXIqLCAqc2tpbiosIGFuZCAqc2VkaW1lbnQqIHdlcmUgdXNlZCBhcyBuZWdhdGl2ZSBjb250cm9scyBmb3IKdGhlIHByZXZhbGVuY2UgbWV0aG9kIHdpdGggYSBwcm9iYWJpbGl0eSB0aHJlc2hvbGQgb2YgMC4wMS4gCltETkEgY29uY2VudHJhdGlvbnNdKC4uLzAxLWRvY3VtZW50YXRpb24vU1lOX0ROQV9jb25jZW50cmF0aW9ucy50c3YpIHdlcmUgdXNlZApmb3IgdGhlICdmcmVxdWVuY3knIG1ldGhvZCB3aXRoIGEgcHJvYmFiaWxpdHkgdGhyZXNob2xkIG9mIDAuOTkKYW5kIG5lZ2F0aXZlIGNvbnRyb2xzLiAKClB1dGF0aXZlIGNvbnRhbWluYW50cyB3ZXJlIGZpbHRlcmVkIG91dCBvZiB0aGUKW09UVSB0YWJsZXNdKC4uLzA1LXJlc3VsdHMvcG9zdC1kZWNvbnRhbV90YXhhdGFibGUudHN2KSBmb3IgYWxsIGRvd25zdHJlYW0gYW5hbHlzZXMuCgpTZWUgWzA2LXJlcG9ydHMvbWV0YWdlbi1hdXRoZW50aWNhdGlvbi5SbWRdKC4uLzA2LXJlcG9ydHMvbWV0YWdlbi1hdXRoZW50aWNhdGlvbi5SbWQpCmZvciBtb3JlIGRldGFpbHMuCjwhLS0gY3VwZXJkZWMgW0B5YXRlc09yYWxNaWNyb2Jpb21lMjAyMV0tLT4KCiMjIyBDb21tdW5pdHkgY29tcG9zaXRpb24KCkdlbnVzLSBhbmQgc3BlY2llcy1sZXZlbCBPVFUgdGFibGVzIHdlcmUgcHJlcGFyZWQgZnJvbSB0aGUgZGVjb250YW1pbmF0ZWQgT1RVCnRhYmxlLCBhbmQgcmVsYXRpdmUgYWJ1bmRhbmNlIG9mIHNwZWNpZXMgaW4gYSBzYW1wbGUgd2FzIGNhbGN1bGF0ZWQgYXMgcmVjb21tZW5kZWQKZm9yIGNvbXBvc2l0aW9uYWwgZGF0YSBbQGdsb29yTWljcm9iaW9tZURhdGFzZXRzMjAxN10uCgpJbmZvcm1hdGlvbiBvbiB0aGUgb3h5Z2VuIHRvbGVyYW5jZSBvZiBiYWN0ZXJpYWwgc3BlY2llcyB3YXMgZG93bmxvYWRlZCBmcm9tIApbQmFjRGl2ZV0oaHR0cHM6Ly9iYWNkaXZlLmRzbXouZGUpIG9uCmByIHN0cl9leHRyYWN0KGxpc3QuZmlsZXMoIi4uLzAzLWRhdGEvIiwgcGF0dGVybiA9ICJiYWNkaXZlIiksICJcXGR7NH0tXFxkezJ9LVxcZHsyfSIpYC4KQSBsaXN0IG9mIGFteWxhc2UtYmluZGluZyBzdHJlcHRvY29jY2kgKEFCUykgd2FzIGNyZWF0ZWQgYmFzZWQgb24KW0BuaWtpdGtvdmFTdGFyY2hCaW9maWxtczIwMTNdLgoKQWxwaGEtZGl2ZXJzaXR5LCBzcGVjaWZpY2FsbHkgdGhlIFNoYW5ub24gSW5kZXgsIHdhcyBjYWxjdWxhdGVkIHRvIGNvbXBhcmUgc3BlY2llcwpyaWNobmVzcyBhbmQgZGl2ZXJzaXR5IGFjcm9zcyBleHBlcmltZW50YWwgYW5kIGNvbXBhcmF0aXZlIG9yYWwgc2FtcGxlcy4gU2hhbm5vbgpJbmRleCB3YXMgY2FsY3VsYXRlZCB1c2luZyB0aGUgUiBwYWNrYWdlICoqdmVnYW4qKiB2YHIgcGFja2FnZVZlcnNpb24oInZlZ2FuIilgCltAUnZlZ2FuXS4KClNwYXJzZSBwcmluY2lwYWwgY29tcG9uZW50cyBhbmFseXNpcyAoc1BDQSkgd2FzIGNvbmR1Y3RlZCBvbiBjZW50ZXJlZC1sb2ctcmF0aW8KKENMUikgdHJhbnNmb3JtZWQgc3BlY2llcy1sZXZlbCBjb3VudHMgdXNpbmcgdGhlIFIgcGFja2FnZSAqKm1peE9taWNzKioKdmByIHBhY2thZ2VWZXJzaW9uKCJtaXhPbWljcyIpYCBbQFJtaXhPbWljc10uIFRoZSAqKm1peE9taWNzKiogaW1wbGVtZW50YXRpb24gb2YKc1BDQSB1c2VzIGEgTEFTU08gcGVuYWxpc2F0aW9uIHRvIGVsaW1pbmF0ZSB1bmltcG9ydGFudCB2YXJpYWJsZXMuClR3byBzZXBhcmF0ZSBhbmFseXNlcyB3ZXJlIGNvbmR1Y3RlZDogMSkgb24gZXhwZXJpbWVudCBzYW1wbGVzIHRvIGFzc2VzcyB0aGUKZGlmZmVyZW5jZSBpbiBzYW1wbGUgdHlwZXMgYW5kIGJpb2ZpbG0gYWdlOyBhbmQgMikgb24gb3JhbCBjb21wYXJhdGl2ZSBzYW1wbGVzCmFuZCBiaW9maWxtIG1vZGVsIGVuZC1wcm9kdWN0cyB0byBleHBsb3JlIGNvbW11bml0eSBkaWZmZXJlbmNlcyBiZXR3ZWVuICppbiB2aXRybyoKYW5kICppbiB2aXZvKiBiaW9maWxtcy4KCkxvYWRpbmdzIG9idGFpbmVkIGZyb20gdGhlIHNQQ0EgYW5hbHlzZXMgd2VyZSB1c2VkIGluIGNvbWJpbmF0aW9uIHdpdGgKQ0xSLXRyYW5zZm9ybWVkIGNvdW50cyB0byBjcmVhdGUgaGVhdG1hcHMgb2Ygc3BlY2llcy0gYW5kIGdlbnVzLWxldmVsIGNvdW50cwp3aXRoaW4gdGhlIGV4cGVyaW1lbnQgYW5kIGFjcm9zcyBjb21wYXJhdGl2ZSBzYW1wbGVzLgoKQmV0YS1kaXZlcnNpdHksIEJyYXkgQ3VydGlzIGRpc3NpbWlsYXJpdHkuCgojIyMgRGlmZmVyZW50aWFsIGFidW5kYW5jZSBhbmFseXNpcwoKIyMgUmVzdWx0cwoKYGBge3J9CiN8IGxhYmVsOiByZXN1bHRzLXNldHVwCnNvdXJjZXRyYWNrZXIyX2xvbmcgPC0gc291cmNldHJhY2tlcjIgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSB3aGVyZShpcy5udW1lcmljKSwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJwcm9wb3J0aW9uIiwgCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIlNhbXBsZUlEIikgJT4lCiAgcmVuYW1lKHNvdXJjZSA9IC4uLjEpCgpyZW1vdmVkX3NhbXBsZXMgPC0gbWV0YWRhdGEgJT4lCiAgYW50aV9qb2luKGFuYWx5c2lzX21ldGFkYXRhKSAlPiUKICByZW5hbWUoc2FtcGxlcyA9IGAjU2FtcGxlSURgKQpgYGAKCiMjIyBBdXRoZW50aWNhdGlvbgoKIyMjIyBTb3VyY2VUcmFja2VyCgpSZXN1bHRzIGZyb20gU291cmNlVHJhY2tlciBpbmRpY2F0ZWQgYSBsYXJnZSBwb3J0aW9uIG9mIHNwZWNpZXMgZnJvbSBtb3N0IHNhbXBsZXMKYXJlIGZyb20gYW4gb3JhbCBvcmlnaW4gKHBsYXF1ZSwgc2FsaXZhLCBvciBjYWxjdWx1cykuIFNvbWUgc2FtcGxlcyBjb250YWluZWQgYQpsYXJnZSBwcm9wb3J0aW9uIG9mIHNwZWNpZXMgZnJvbSBwb3RlbnRpYWwgY29udGFtaW5hbnRzIChpbmRvb3IgYWlyKSBhbmQgb2YKdW5rbm93biBvcmlnaW4uIFBvdGVudGlhbCBjb250YW1pbmFudHMgd2VyZSBjb21wYXJlZCB0byBhIGRhdGFiYXNlIG9mIG9yYWwKYmFjdGVyaWEgdG8gc2VlIHRoZSBwcm9wb3J0aW9uIG9mIGtub3duIG9yYWwgc3BlY2llcyB3ZXJlIHByZXNlbnQgaW4gdGhlIHNhbXBsZXMuCk1hbnkgb2YgdGhlIHNwZWNpZXMgYXNzaWduZWQgdG8gYGluZG9vcl9haXJgIGFyZSBrbm93biBvcmFsIHNwZWNpZXMKKEZpZ3VyZSBcQHJlZihmaWc6c3QtcGxvdCkpLgoKYGBge3J9CiN8IGxhYmVsOiBzdC1wbG90CiN8IGZpZy1jYXA6ICJQbG90IG9mIGVzdGltYXRlZCBjb250cmlidXRpb25zIG9mIHZhcmlvdXMgc291cmNlcyB0byB0aGUgYXJ0aWZpY2lhbCBjYWxjdWx1cyBhbmQgYXJ0aWZpY2lhbCBzYWxpdmEgc2FtcGxlcy4gU2FtcGxlcyBhcmUgYXJyYW5nZWQgZnJvbSB0b3AgdG8gYm90dG9tIGJ5IGhvdyBsYXRlIGluIHRoZSBleHBlcmltZW50IHRoZXkgd2VyZSBzYW1wbGVkLCB3aXRoIGJvdHRvbSBiZWluZyB0aGUgZWFybGllc3Qgc2FtcGxlcy4gU2FtcGxlIG5hbWVzIGluIHJlZCBpbmRpY2F0ZSBzYW1wbGVzIHRoYXQgd2VyZSByZW1vdmVkIGZyb20gZnVydGhlciBhbmFseXNpcyBkdWUgdG8gY29udGFtaW5hdGlvbi4iCnN0X3Bsb3QgPC0gc291cmNldHJhY2tlcjJfbG9uZyAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gU2FtcGxlSUQsIHg9IHByb3BvcnRpb24sIGZpbGwgPSBzb3VyY2UpKSArCiAgICBnZW9tX2NvbCgpICsKICAgIHRoZW1lX21pbmltYWwoKSArCiAgICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cyA9IGRheV9vcmRlciRgI1NhbXBsZUlEYCkgKwogICAgc2NhbGVfZmlsbF92aXJpZGlzX2Qob3B0aW9uID0gIkMiKSArCiAgICB0aGVtZSgKICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDAuNSwgaGp1c3QgPSAwLjUsIGNvbG91ciA9IGRheV9vcmRlciRjb2wpLAogICAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIgogICAgICApCgpvcmFsX3Bsb3QgPC0gYWxsX2RhdGFfbG9uZyAlPiUgCiAgZmlsdGVyKGNvdW50ID4gMCkgJT4lIAogIG11dGF0ZShvcmFsX3NvdXJjZSA9IGlmX2Vsc2UodGF4b24gJWluJSBvcmFsX3RheGEkc3BlY2llcywgIm9yYWwiLCAib3RoZXIiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gU2FtcGxlSUQsIHggPSBjb3VudCwgZmlsbCA9IG9yYWxfc291cmNlKSkgKwogICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsKICAgIHNjYWxlX3lfZGlzY3JldGUobGltaXRzID0gZGF5X29yZGVyJGAjU2FtcGxlSURgKSArICAKICAgIHNjYWxlX2ZpbGxfdmlyaWRpc19kKG9wdGlvbiA9ICJDIikgKwogICAgdGhlbWVfbWluaW1hbCgpICsKICAgIHRoZW1lKAogICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAjYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3VyID0gZGF5X29yZGVyJGNvbCksCiAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiCiAgICAgICkKCnN0X3Bsb3QgKyBvcmFsX3Bsb3QgKyBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICJBIikKYGBgCgpCYXNlZCBvbiB0aGVzZSByZXN1bHRzLCBzYW1wbGVzCmByIHBhc3RlKHJlbW92ZWRfc2FtcGxlcyRzYW1wbGVzLCBjb2xsYXBzZSA9ICIsICIpYAp3ZXJlIHJlbW92ZWQgZnJvbSBmdXJ0aGVyIGFuYWx5c2lzLiBUaGUgcmVtb3ZlZCBzYW1wbGVzIHdlcmUgYWxsIHNhbXBsZWQgbGF0ZSBpbgp0aGUgZXhwZXJpbWVudCAoZGF5IDE4KykuCgpgYGB7cn0KcmVtb3ZlZF9zYW1wbGVzICU+JQogIGxlZnRfam9pbihleHBlcmltZW50X21ldGFkYXRhLCBieSA9IGMoInNhbXBsZXMiID0gIiNTYW1wbGVJRCIsICJFbnYiKSkgJT4lCiAgZHBseXI6OnNlbGVjdChzYW1wbGVzLCBFbnYsIGRheSkgJT4lCiAgYXJyYW5nZShkYXkpCmBgYAoKCiMjIyMgZGVjb250YW0KCmBgYHtyfQojfCBsYWJlbDogZGVjb250YW0tYnlvYy1zdW1tCiN8IGluY2x1ZGU6IGZhbHNlCmJ5b2Nfc3VtbSA8LSBzcGVjaWVzX2NvdW50c19sb25nICU+JQogIGZpbHRlcihzdHJfZGV0ZWN0KHNhbXBsZSwgIlNZTiIpLAogICAgICAgICBjb3VudCA+IDApICU+JQogIGdyb3VwX2J5KHNhbXBsZSkgJT4lCiAgY291bnQoYCNPVFUgSURgKSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBzdW0obikpCmBgYAoKQSB0b3RhbCBvZiBgciBucm93KGxpc3Rfb2ZfY29udGFtaW5hbnRzKWAgcG90ZW50aWFsIGNvbnRhbWluYW50cyB3ZXJlIHJlbW92ZWQuClJlbWFpbmluZyBjb3VudHMgb2Ygc3BlY2llcyBpbiB0aGUgYmlvZmlsbSBzYW1wbGVzIHJhbmdlZCBiZXR3ZWVuCmByIHBhc3RlKHJhbmdlKGJ5b2Nfc3VtbSRjb3VudCksIGNvbGxhcHNlID0gIiBhbmQgIilgCndpdGggYSBtZWFuIG9mCmByIHBhc3RlKHJvdW5kKG1lYW4oYnlvY19zdW1tJGNvdW50KSwgMikpYC4KCmBgYHtyfQojfCBsYWJlbDogZGVjb250YW0tcGxvdAojfCBmaWctY2FwOiAiUmVtYWluaW5nIG51bWJlciBvZiBzcGVjaWVzIHBlciBzYW1wbGUgZm9sbG93aW5nIHJlbW92YWwgb2YgY29udGFtaW5hbnRzLiIKYnlvY19zdW1tICU+JQogIGdncGxvdChhZXMoeCA9IGNvdW50LCB5ID0gc2FtcGxlKSkgKwogICAgZ2VvbV9jb2woKSArCiAgICB0aGVtZV9taW5pbWFsKCkgKwogICAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCiMjIyBDb21tdW5pdHkgY29tcG9zaXRpb24KCkFscGhhLWRpdmVyc2l0eS4gRGF5cyBhcmUgZ3JvdXBlZCB0byBpbmNyZWFzZSBzYW1wbGUgc2l6ZXM6CgotIElub2N1bGF0aW9uIChgaW5vY2ApID0gZGF5cyAwLDMsNQotIFRyZWF0bWVudCAoYHRyZWF0bWApID0gZGF5cyA3LDksMTIsMTUKLSBFbmQtcHJvZHVjdCAoYGZpbmFsYCkgPSBkYXkgMjQKCmBgYHtyfQojfCBsYWJlbDogY29tcC1zZXR1cAphbHBoYV9kaXZfbG9uZyA8LSBhbHBoYV9kaXYgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSB3aGVyZShpcy5udW1lcmljKSwgbmFtZXNfdG8gPSAiaW5kZXgiKSAlPiUKICBsZWZ0X2pvaW4obWV0YWRhdGEsIGJ5ID0gYygic2FtcGxlIiA9ICIjU2FtcGxlSUQiKSkgJT4lCiAgbGVmdF9qb2luKGV4cGVyaW1lbnRfbWV0YWRhdGEsIGJ5ID0gYygic2FtcGxlIiA9ICIjU2FtcGxlSUQiLCAiRW52IikpICU+JQogIG11dGF0ZShkYXlfZ3JvdXBlZCA9IGNhc2Vfd2hlbiggIyBncm91cCBkYXlzIHRvIGluY3JlYXNlIHNhbXBsZSBzaXplCiAgICBkYXkgPCA2IH4gImlub2MiLAogICAgZGF5ID4gNiAmIGRheSA8IDI0IH4gInRyZWF0bSIsCiAgICBkYXkgPT0gMjQgfiAiZmluYWwiKSwKICAgIGRheV9ncm91cGVkID0gZmFjdG9yKGRheV9ncm91cGVkLCBsZXZlbHMgPSBjKCJpbm9jIiwgInRyZWF0bSIsICJmaW5hbCIpKQogICAgKQpgYGAKICAKYGBge3J9CiN8IGxhYmVsOiBhbHBoYS1leHBlcmltZW50LXBsb3QKI3wgZmlnLWNhcDogIlBsb3Qgb2YgYWxwaGEtZGl2ZXJzaXR5IGluZGljZXMgYWNyb3NzIGV4cGVyaW1lbnQgc2FtcGxlcyBncm91cGVkIGJ5IHNhbXBsaW5nIHRpbWUuIgoKYWxwaGFfZGl2X2xvbmcgJT4lCiAgZmlsdGVyKHN0cl9kZXRlY3Qoc2FtcGxlLCAiU1lOIikpICU+JQogICNtdXRhdGUoZGF5ID0gYXMuZmFjdG9yKGRheSkpICU+JQogIGdncGxvdChhZXMoeCA9IGRheV9ncm91cGVkLCB5ID0gdmFsdWUpKSArCiAgICBnZW9tX3Zpb2xpbihhZXMoY29sID0gZGF5X2dyb3VwZWQpKSArCiAgICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjEyKSArCiAgICBmYWNldF93cmFwKH4gaW5kZXgsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgICB0aGVtZV9idygpICsKICAgIHRoZW1lKAogICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpCiAgICApCmBgYAoKYGBge3J9CiN8IGxhYmVsOiBhbHBoYS1jb21wYXItcGxvdAphbHBoYV9kaXZfbG9uZyAlPiUKICBmaWx0ZXIoRW52ICE9ICJza2luIiwKICAgICAgICAgRW52ICE9ICJzZWRpbWVudCIsCiAgICAgICAgIEVudiAhPSAic3Rvb2wiLAogICAgICAgICBFbnYgIT0gImluZG9vcl9haXIiKSAlPiUKICBtdXRhdGUoRW52ID0gY2FzZV93aGVuKHN0cl9kZXRlY3QoRW52LCAicGxhcXVlIikgfiAicGxhcXVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiBFbnYpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBFbnYsIHkgPSB2YWx1ZSkpICsKICAgIGdlb21fdmlvbGluKGFlcyhjb2wgPSBFbnYpKSArCiAgICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjEpICsKICAgIGZhY2V0X3dyYXAofiBpbmRleCwgc2NhbGVzID0gImZyZWVfeSIpICsKICAgIHRoZW1lX2J3KCkgKwogICAgdGhlbWUoCiAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCkKICAgICkKYGBgCgpgYGB7cn0KI3wgbGFiZWw6IGFscGhhLWRpdi10YmwKYWxwaGFfZGl2X2xvbmcgJT4lCiAgZmlsdGVyKAogICAgRW52ICE9ICJza2luIiwKICAgIEVudiAhPSAic2VkaW1lbnQiLAogICAgRW52ICE9ICJzdG9vbCIsCiAgICBFbnYgIT0gImluZG9vcl9haXIiKSAlPiUKICBncm91cF9ieShpbmRleCwgRW52KSAlPiUKICBzdW1tYXJpc2UobWVhbiA9IG1lYW4odmFsdWUpLAogICAgICAgICAgICBzZCA9IHNkKHZhbHVlKSkgJT4lCiAga25pdHI6OmthYmxlKCkKYGBgCgoKQWxwaGEtZGl2ZXJzaXR5IHNlZXMgYSBzbGlnaHQgZGVjcmVhc2Ugb3ZlciB0aGUgY291cnNlIG9mIHRoZSBleHBlcmltZW50LiBUaGUKbW9kZWwgY2FsY3VsdXMgaXMgbGVzcyB2YXJpYWJsZSB0aGFuIHRoZSBpbml0aWFsIGFuZCBtaWRkbGUgYmlvZmlsbSBzYW1wbGVzLgpDb21wYXJlZCB0byBvdGhlciBvcmFsIHNhbXBsZXMsIHRoZXJlIGlzIGxvd2VyIHNwZWNpZXMgZGl2ZXJzaXR5IGFuZCByaWNobmVzcwppbiB0aGUgbWVkaXVtIGFuZCBtb2RlbCBjYWxjdWx1cy4KCmBgYHtyfQojfCBsYWJlbDogc3BjYS1zZXR1cAojfCBpbmNsdWRlOiBmYWxzZQojIGV4cGxhaW5lZCB2YXJpYW5jZQpieW9jX2V4cGxhaW5fdmFyIDwtIHNwY2FfYnlvYyRwcm9wX2V4cGxfdmFyJFgKIyBsb2FkaW5ncyBvZiBzYW1wbGVzCmJ5b2NfcHJpbmNvbXAgPC0gc3BjYV9ieW9jJHggJT4lCiAgYXNfdGliYmxlKHJvd25hbWVzID0gInNhbXBsZSIpICU+JQogIGxlZnRfam9pbihleHBlcmltZW50X21ldGFkYXRhLCBieSA9IGMoInNhbXBsZSIgPSAiI1NhbXBsZUlEIikpCiMgbG9hZGluZ3Mgb2Ygc3BlY2llcwpleHBfcGNhX2xvYWRpbmdzIDwtIHNwY2FfYnlvYyRsb2FkaW5ncyRYICU+JQogIGFzX3RpYmJsZShyb3duYW1lcyA9ICJzcGVjaWVzIikgJT4lCiAgbGVmdF9qb2luKGJhY19wcm9wZXJ0aWVzLCBieSA9ICJzcGVjaWVzIikgJT4lIAogIGRwbHlyOjpzZWxlY3Qoc3BlY2llcyxQQzEsUEMyLCBgT3h5Z2VuIHRvbGVyYW5jZWApICU+JQogIGFycmFuZ2UoZGVzYyhhYnMoUEMxKSkpCmV4cF9wY2FfbG9hZGluZ3MKIyBzZXQgY29tbW9uIGdncGxvdCB0aGVtZSBmb3IgbG9hZGluZyBwbG90cwpsb2FkaW5nX3RoZW1lIDwtICB0aGVtZV9taW5pbWFsKCkgKwogICAgdGhlbWUoCiAgICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIGF4aXMudGlja3MueC5ib3R0b20gPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDEpLAogICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCgpLAogICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IC0wLjIpLAogICAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZSgpLAogICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIgogICAgICAgICAgKQpgYGAKCgpgYGB7cn0KI3wgbGFiZWw6IHNjcmVlLWJ5b2MKI3wgZmlnLWNhcDogIlNjcmVlIHBsb3Qgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMgZnJvbSB0aGUgc1BDQSBvbiBleHBlcmltZW50IHNhbXBsZXMuIgpwbG90KHNwY2FfYnlvYywgdHlwZSA9ICJsIikKYGBgCgpgYGB7cn0KI3wgbGFiZWw6IGJ5b2Mtc3BjYS1wbG90CiN8IGZpZy1jYXA6ICJzUENBIG9uIHNwZWNpZXMtbGV2ZWwgY291bnRzIGZyb20gZXhwZXJpbWVudCBzYW1wbGVzIG9ubHkuIgpieW9jX3NwY2FfcGxvdCA8LSBieW9jX3ByaW5jb21wICU+JQogIGdncGxvdChhZXMoCiAgICB4ID0gUEMxLCB5ID0gUEMyLCAKICAgIGNvbCA9IGFzX2ZhY3RvcihkYXkpLAogICAgc2hhcGUgPSBFbnYKICAgICkKICApICsKICAgIGdlb21fcG9pbnQoc2l6ZSA9IDQsIHN0cm9rZSA9IDEpICsKICAgIGxhYnMoCiAgICAgIHggPSBwYXN0ZSgKICAgICAgICAiUEMxIiwgCiAgICAgICAgc2NhbGVzOjpwZXJjZW50KGJ5b2NfZXhwbGFpbl92YXJbWzFdXSwgYWNjdXJhY3kgPSAwLjEpKSwKICAgICAgeSA9IHBhc3RlKAogICAgICAgICJQQzIiLCAKICAgICAgICBzY2FsZXM6OnBlcmNlbnQoYnlvY19leHBsYWluX3ZhcltbMl1dLCBhY2N1cmFjeSA9IDAuMSkpLAogICAgICBjb2wgPSAiU2FtcGxpbmcgZGF5IiwKICAgICAgc2hhcGUgPSAiU2FtcGxlIHR5cGUiCiAgICAgICkgKwogICAgdGhlbWVfYncoKSArCiAgICBzY2FsZV9zaGFwZV9kaXNjcmV0ZShzb2xpZCA9IEYpICsKICAgIHNjYWxlX2NvbG91cl92aXJpZGlzX2QoKQoKZXhwX3BjYV9sb2FkaW5ncyAlPiUKICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2MoYWJzKFBDMSkpKSkgJT4lCiAgc2xpY2VfaGVhZChuID0gMjApICU+JQogIGdncGxvdChhZXMoeCA9IFBDMSwgeSA9IHNwZWNpZXMsIGZpbGwgPSBgT3h5Z2VuIHRvbGVyYW5jZWApKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjgpICsKICAgIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0wLjIsMC4yKSkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICAgIHZhbHVlcyA9IHZpcmlkaXNMaXRlOjp0dXJibyhuID0gbGVuZ3RoKGxldmVscyhhcy5mYWN0b3IoYmFjX3Byb3BlcnRpZXMkYE94eWdlbiB0b2xlcmFuY2VgKSkpKSkgKwogICAgbGFicyh0aXRsZSA9ICJjb21wb25lbnQgMSIsIHggPSAiIikgKwogICAgbG9hZGluZ190aGVtZQoKZXhwX3BjYV9sb2FkaW5ncyAlPiUKICBhcnJhbmdlKGRlc2MoYWJzKFBDMikpKSAlPiUKICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2MoYWJzKFBDMikpKSkgJT4lCiAgc2xpY2VfaGVhZChuID0gMjApICU+JQogIGdncGxvdChhZXMoeCA9IFBDMiwgeSA9IHNwZWNpZXMsIGZpbGwgPSBgT3h5Z2VuIHRvbGVyYW5jZWApKSArCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjgpICsKICAgIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0wLjE4LDAuMTgpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICAgIHZhbHVlcyA9IHZpcmlkaXNMaXRlOjp0dXJibygKICAgICAgICBuID0gbGVuZ3RoKGxldmVscyhhcy5mYWN0b3IoYmFjX3Byb3BlcnRpZXMkYE94eWdlbiB0b2xlcmFuY2VgKSkpCiAgICAgICAgKQogICAgICApICsKICAgIGxhYnModGl0bGUgPSAiY29tcG9uZW50IDIiLCB4ID0gIiIpICsKICAgIGxvYWRpbmdfdGhlbWUKYGBgCgoKCgoKCgoK