Load libraries for anlyisis

try http:// if https:// URLs are not supported

Randomization housekeeping

set.seed(100)

Visually check the quality of the reads

plotQualityProfile(fnFs)

plotQualityProfile(fnFs[1])

Everything looks good for forward read quality. The first few bp will be trimmed off during primer removal and the reads will be truncated to remove the low quality reads at the end. I had to play with the truncation length to preserve reads while maintaining good quality and taxonomic fit.

Create new files for filtered reads and then trim and filter

filt_path <- file.path(miseq_path, "filtered")
if(!file_test("-d",filt_path)) dir.create(filt_path)
filtFs <- file.path(filt_path, paste0(sampleNames, "_filt.fastq.gz"))
out <- filterAndTrim(fnFs, filtFs, 
                     maxLen = 600, #Removes reads greater than 600bp, since the whole ITS region should be this long
                     maxN=0, #After truncation, sequences with more than 0 Ns will be discarded
                     maxEE=3, #reads with higher than 30% 'expected errors' will be discareded EE=sum(10^(-Q/10))
                     truncQ=2, #Truncate reads at the first instance of a quality score less than or equal to 2
                     compress=TRUE, #makes it into a .zip file
                     trimLeft=24, #Removes the primers from the forward reads
                     truncLen = 200) #Cuts the reads to the desired length, discards all smaller reads
head(out) #preview headers for filtFs
                 reads.in reads.out
Faye01_049.fastq    47558     13085
Faye02_050.fastq    61547     11467
Faye03_051.fastq   144848     48407
Faye04_052.fastq   111871     25153
Faye05_053.fastq    46491      6615
Faye06_054.fastq   144300     31242

View plot of post-filtered sequence quality

plotQualityProfile(filtFs)

plotQualityProfile(filtFs[1])

The quality and reads look great. We dont have that dip in quality at the end after truncation and it appears that the primers have been sucessfully removed. Onwards!

Dereplication

Combining identical reads into ‘unique sequences’ with a corresponding ‘abundance’

drepFs <- derepFastq(filtFs, verbose=TRUE)
Dereplicating sequence entries in Fastq file: C:/Users/faysmith/Desktop/seq/filtered/Faye01_filt.fastq.gz
Encountered 3573 unique sequences from 13085 total sequences read.
Dereplicating sequence entries in Fastq file: C:/Users/faysmith/Desktop/seq/filtered/Faye02_filt.fastq.gz
Encountered 3672 unique sequences from 11467 total sequences read.
Dereplicating sequence entries in Fastq file: C:/Users/faysmith/Desktop/seq/filtered/Faye03_filt.fastq.gz
Encountered 20463 unique sequences from 48407 total sequences read.
Dereplicating sequence entries in Fastq file: C:/Users/faysmith/Desktop/seq/filtered/Faye04_filt.fastq.gz
Encountered 10300 unique sequences from 25153 total sequences read.
Dereplicating sequence entries in Fastq file: C:/Users/faysmith/Desktop/seq/filtered/Faye05_filt.fastq.gz
Encountered 3535 unique sequences from 6615 total sequences read.
Dereplicating sequence entries in Fastq file: C:/Users/faysmith/Desktop/seq/filtered/Faye06_filt.fastq.gz
Encountered 11500 unique sequences from 31242 total sequences read.
Dereplicating sequence entries in Fastq file: C:/Users/faysmith/Desktop/seq/filtered/Faye07_filt.fastq.gz
Encountered 3360 unique sequences from 14306 total sequences read.
Dereplicating sequence entries in Fastq file: C:/Users/faysmith/Desktop/seq/filtered/Faye08_filt.fastq.gz
Encountered 2059 unique sequences from 5515 total sequences read.
Dereplicating sequence entries in Fastq file: C:/Users/faysmith/Desktop/seq/filtered/Faye09_filt.fastq.gz
Encountered 2933 unique sequences from 4894 total sequences read.
Dereplicating sequence entries in Fastq file: C:/Users/faysmith/Desktop/seq/filtered/Faye10_filt.fastq.gz
Encountered 4384 unique sequences from 8144 total sequences read.
names(drepFs) <- sampleNames

This is a long list where we see how many unique sequences are in each sample. It looks like we just about halved each of the total sequences by clustering (dont worry, the associated abundance of each cluster is still kept for future analyses.)

Learn the error rates

Uses a statistical test for the notion that a specific sequence was seen too many times to have been caused by amplicon errors. Overly-abundant sequences are used as the seeds of new clusters. It uses estimated error rates that are inferred from the data. Error rates are leaned by alternating between sample inference and error rate estimation until convergence. After applying the learned error rates and then plotting:

errF <- learnErrors(filtFs, nreads=1e8)
Initializing error rates to maximum possible estimate.
Sample 1 - 13085 reads in 3573 unique sequences.
Sample 2 - 11467 reads in 3672 unique sequences.
Sample 3 - 48407 reads in 20463 unique sequences.
Sample 4 - 25153 reads in 10300 unique sequences.
Sample 5 - 6615 reads in 3535 unique sequences.
Sample 6 - 31242 reads in 11500 unique sequences.
Sample 7 - 14306 reads in 3360 unique sequences.
Sample 8 - 5515 reads in 2059 unique sequences.
Sample 9 - 4894 reads in 2933 unique sequences.
Sample 10 - 8144 reads in 4384 unique sequences.
   selfConsist step 2 
NA

Points are the observed error rates for each consensus quality score. The black line shows the estimated error rates after the learnError function converges. The red line is the error rates expected under the nominal definition of the Q-value. The black line with estimated rates fits well.

Infer the sequence variaents in each sample

Apply the sequence-barient inference algorithm to the dereplicated data

The algorithm inferred 30 real variants from the 3573 unique sequences in the first sample. The dada function removes sequencing error to reveal the members of the sequenced community.

Construct sequence table, a OTU table

fraction of chimeric sequences detected

Only around 3% chimeras in the de-replicated and filtered dataset - removed for further analysis

Make a data frame

Assign taxonomy

Assign taxonomy using local BLAST against the UNITE general FASTA release for Fungi

Seems to have worked well. All sequences have been named to at least the kingdom. I was getting much stranger results before.

Assign a phylogenetic tree to the amplicon sequences

Final data manipulation to run diversity analyses with

Create a file with all the treatment data included

Create the phyloseq object for futher analysis

save the phyloseq object for further anlysis

LS0tDQp0aXRsZTogIlByb2Nlc3Mgc2VxdWVuY2VzIGRhdGEgZm9yIG1ldGFiYXJjb2RpbmciDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCi0tLQ0KDQojTG9hZCBsaWJyYXJpZXMgZm9yIGFubHlpc2lzIA0KIyMgdHJ5IGh0dHA6Ly8gaWYgaHR0cHM6Ly8gVVJMcyBhcmUgbm90IHN1cHBvcnRlZA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0NCiMgc291cmNlKCJodHRwczovL2Jpb2NvbmR1Y3Rvci5vcmcvYmlvY0xpdGUuUiIpDQojIGJpb2NMaXRlKCkNCiMgDQojIGJpb2NMaXRlKCJwaGFuZ29ybiIpDQojIGJpb2NMaXRlKCJrbml0ciIpDQojIGJpb2NMaXRlKCJCaW9jU3R5bGUiKQ0KIyBiaW9jTGl0ZSgiREVDSVBIRVIiKQ0KIyBiaW9jTGl0ZSgiZGFkYTIiKQ0KDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShCaW9jU3R5bGUpDQpsaWJyYXJ5KERFQ0lQSEVSKQ0KbGlicmFyeShzdXJ2aXZhbCkNCmxpYnJhcnkocGh5bG9zZXEpDQpsaWJyYXJ5KGRhZGEyKQ0KbGlicmFyeShwaGFuZ29ybikNCmxpYnJhcnkobXNhKQ0KYGBgDQoNClJhbmRvbWl6YXRpb24gaG91c2VrZWVwaW5nDQpgYGB7cn0NCnNldC5zZWVkKDEwMCkNCmBgYA0KDQojTmF2aWdhdGUgdG8gZmlsZXMgYW5kIGxpc3QgZmlsZSBuYW1lcw0KDQpgYGB7cn0NCm1pc2VxX3BhdGggPC0gIkM6L1VzZXJzL2ZheXNtaXRoL0Rlc2t0b3Avc2VxIg0KZm5GcyA8LSBsaXN0LmZpbGVzKG1pc2VxX3BhdGgsIHBhdHRlcm49Ii5mYXN0cSIpDQpzYW1wbGVOYW1lcyA8LSBzYXBwbHkoc3Ryc3BsaXQoZm5GcywgIl8iKSwgJ1snLCAxKQ0KDQpmbkZzIDwtIGZpbGUucGF0aChtaXNlcV9wYXRoLCBmbkZzKQ0KYGBgDQoNCiNWaXN1YWxseSBjaGVjayB0aGUgcXVhbGl0eSBvZiB0aGUgcmVhZHMNCg0KYGBge3J9DQpwbG90UXVhbGl0eVByb2ZpbGUoZm5GcykNCnBsb3RRdWFsaXR5UHJvZmlsZShmbkZzWzFdKQ0KDQpgYGANCkV2ZXJ5dGhpbmcgbG9va3MgZ29vZCBmb3IgZm9yd2FyZCByZWFkIHF1YWxpdHkuIFRoZSBmaXJzdCBmZXcgYnAgd2lsbCBiZSB0cmltbWVkIG9mZiBkdXJpbmcgcHJpbWVyIHJlbW92YWwgYW5kIHRoZSByZWFkcyB3aWxsIGJlIHRydW5jYXRlZCB0byByZW1vdmUgdGhlIGxvdyBxdWFsaXR5IHJlYWRzIGF0IHRoZSBlbmQuIEkgaGFkIHRvIHBsYXkgd2l0aCB0aGUgdHJ1bmNhdGlvbiBsZW5ndGggdG8gcHJlc2VydmUgcmVhZHMgd2hpbGUgbWFpbnRhaW5pbmcgZ29vZCBxdWFsaXR5IGFuZCB0YXhvbm9taWMgZml0LiANCg0KIyNDcmVhdGUgbmV3IGZpbGVzIGZvciBmaWx0ZXJlZCByZWFkcyBhbmQgdGhlbiB0cmltIGFuZCBmaWx0ZXINCg0KYGBge3J9DQpmaWx0X3BhdGggPC0gZmlsZS5wYXRoKG1pc2VxX3BhdGgsICJmaWx0ZXJlZCIpDQppZighZmlsZV90ZXN0KCItZCIsZmlsdF9wYXRoKSkgZGlyLmNyZWF0ZShmaWx0X3BhdGgpDQpmaWx0RnMgPC0gZmlsZS5wYXRoKGZpbHRfcGF0aCwgcGFzdGUwKHNhbXBsZU5hbWVzLCAiX2ZpbHQuZmFzdHEuZ3oiKSkNCg0Kb3V0IDwtIGZpbHRlckFuZFRyaW0oZm5GcywgZmlsdEZzLCANCiAgICAgICAgICAgICAgICAgICAgIG1heExlbiA9IDYwMCwgI1JlbW92ZXMgcmVhZHMgZ3JlYXRlciB0aGFuIDYwMGJwLCBzaW5jZSB0aGUgd2hvbGUgSVRTIHJlZ2lvbiBzaG91bGQgYmUgdGhpcyBsb25nDQogICAgICAgICAgICAgICAgICAgICBtYXhOPTAsICNBZnRlciB0cnVuY2F0aW9uLCBzZXF1ZW5jZXMgd2l0aCBtb3JlIHRoYW4gMCBOcyB3aWxsIGJlIGRpc2NhcmRlZA0KICAgICAgICAgICAgICAgICAgICAgbWF4RUU9MywgI3JlYWRzIHdpdGggaGlnaGVyIHRoYW4gMzAlICdleHBlY3RlZCBlcnJvcnMnIHdpbGwgYmUgZGlzY2FyZWRlZCBFRT1zdW0oMTBeKC1RLzEwKSkNCiAgICAgICAgICAgICAgICAgICAgIHRydW5jUT0yLCAjVHJ1bmNhdGUgcmVhZHMgYXQgdGhlIGZpcnN0IGluc3RhbmNlIG9mIGEgcXVhbGl0eSBzY29yZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMg0KICAgICAgICAgICAgICAgICAgICAgY29tcHJlc3M9VFJVRSwgI21ha2VzIGl0IGludG8gYSAuemlwIGZpbGUNCiAgICAgICAgICAgICAgICAgICAgIHRyaW1MZWZ0PTI0LCAjUmVtb3ZlcyB0aGUgcHJpbWVycyBmcm9tIHRoZSBmb3J3YXJkIHJlYWRzDQogICAgICAgICAgICAgICAgICAgICB0cnVuY0xlbiA9IDIwMCkgI0N1dHMgdGhlIHJlYWRzIHRvIHRoZSBkZXNpcmVkIGxlbmd0aCwgZGlzY2FyZHMgYWxsIHNtYWxsZXIgcmVhZHMNCg0KaGVhZChvdXQpICNwcmV2aWV3IGhlYWRlcnMgZm9yIGZpbHRGcw0KYGBgDQoNCg0KI1ZpZXcgcGxvdCBvZiBwb3N0LWZpbHRlcmVkIHNlcXVlbmNlIHF1YWxpdHkNCmBgYHtyfQ0KcGxvdFF1YWxpdHlQcm9maWxlKGZpbHRGcykNCnBsb3RRdWFsaXR5UHJvZmlsZShmaWx0RnNbMV0pDQpgYGANCg0KVGhlIHF1YWxpdHkgYW5kIHJlYWRzIGxvb2sgZ3JlYXQuIFdlIGRvbnQgaGF2ZSB0aGF0IGRpcCBpbiBxdWFsaXR5IGF0IHRoZSBlbmQgYWZ0ZXIgdHJ1bmNhdGlvbiBhbmQgaXQgYXBwZWFycyB0aGF0IHRoZSBwcmltZXJzIGhhdmUgYmVlbiBzdWNlc3NmdWxseSByZW1vdmVkLiBPbndhcmRzIQ0KDQojRGVyZXBsaWNhdGlvbg0KQ29tYmluaW5nIGlkZW50aWNhbCByZWFkcyBpbnRvICd1bmlxdWUgc2VxdWVuY2VzJyB3aXRoIGEgY29ycmVzcG9uZGluZyAnYWJ1bmRhbmNlJw0KDQpgYGB7cn0NCmRyZXBGcyA8LSBkZXJlcEZhc3RxKGZpbHRGcywgdmVyYm9zZT1UUlVFKQ0KbmFtZXMoZHJlcEZzKSA8LSBzYW1wbGVOYW1lcw0KYGBgDQpUaGlzIGlzIGEgbG9uZyBsaXN0IHdoZXJlIHdlIHNlZSBob3cgbWFueSB1bmlxdWUgc2VxdWVuY2VzIGFyZSBpbiBlYWNoIHNhbXBsZS4gSXQgbG9va3MgbGlrZSB3ZSBqdXN0IGFib3V0IGhhbHZlZCBlYWNoIG9mIHRoZSB0b3RhbCBzZXF1ZW5jZXMgYnkgY2x1c3RlcmluZyAoZG9udCB3b3JyeSwgdGhlIGFzc29jaWF0ZWQgYWJ1bmRhbmNlIG9mIGVhY2ggY2x1c3RlciBpcyBzdGlsbCBrZXB0IGZvciBmdXR1cmUgYW5hbHlzZXMuKQ0KDQojTGVhcm4gdGhlIGVycm9yIHJhdGVzDQpVc2VzIGEgc3RhdGlzdGljYWwgdGVzdCBmb3IgdGhlIG5vdGlvbiB0aGF0IGEgc3BlY2lmaWMgc2VxdWVuY2Ugd2FzIHNlZW4gdG9vIG1hbnkgdGltZXMgdG8gaGF2ZSBiZWVuIGNhdXNlZCBieSBhbXBsaWNvbiBlcnJvcnMuIE92ZXJseS1hYnVuZGFudCBzZXF1ZW5jZXMgYXJlIHVzZWQgYXMgdGhlIHNlZWRzIG9mIG5ldyBjbHVzdGVycy4gSXQgdXNlcyBlc3RpbWF0ZWQgZXJyb3IgcmF0ZXMgdGhhdCBhcmUgaW5mZXJyZWQgZnJvbSB0aGUgZGF0YS4gRXJyb3IgcmF0ZXMgYXJlIGxlYW5lZCBieSBhbHRlcm5hdGluZyBiZXR3ZWVuIHNhbXBsZSBpbmZlcmVuY2UgYW5kIGVycm9yIHJhdGUgZXN0aW1hdGlvbiB1bnRpbCBjb252ZXJnZW5jZS4gDQpBZnRlciBhcHBseWluZyB0aGUgbGVhcm5lZCBlcnJvciByYXRlcyBhbmQgdGhlbiBwbG90dGluZzoNCg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZXJyRiA8LSBsZWFybkVycm9ycyhmaWx0RnMsIG5yZWFkcz0xZTgpDQpwbG90RXJyb3JzKGVyckYsIG5vbWluYWxRPVRSVUUpDQoNCmBgYA0KDQpQb2ludHMgYXJlIHRoZSBvYnNlcnZlZCBlcnJvciByYXRlcyBmb3IgZWFjaCBjb25zZW5zdXMgcXVhbGl0eSBzY29yZS4gVGhlIGJsYWNrIGxpbmUgc2hvd3MgdGhlIGVzdGltYXRlZCBlcnJvciByYXRlcyBhZnRlciB0aGUgbGVhcm5FcnJvciBmdW5jdGlvbiBjb252ZXJnZXMuIFRoZSByZWQgbGluZSBpcyB0aGUgZXJyb3IgcmF0ZXMgZXhwZWN0ZWQgdW5kZXIgdGhlIG5vbWluYWwgZGVmaW5pdGlvbiBvZiB0aGUgUS12YWx1ZS4gVGhlIGJsYWNrIGxpbmUgd2l0aCBlc3RpbWF0ZWQgcmF0ZXMgZml0cyB3ZWxsLiANCg0KI0luZmVyIHRoZSBzZXF1ZW5jZSB2YXJpYWVudHMgaW4gZWFjaCBzYW1wbGUNCkFwcGx5IHRoZSBzZXF1ZW5jZS1iYXJpZW50IGluZmVyZW5jZSBhbGdvcml0aG0gdG8gdGhlIGRlcmVwbGljYXRlZCBkYXRhDQpgYGB7cn0NCmRhZGFGcyA8LSBkYWRhKGRyZXBGcywgZXJyPWVyckYpDQpkYWRhRnNbWzFdXQ0KYGBgDQpUaGUgYWxnb3JpdGhtIGluZmVycmVkIDMwIHJlYWwgdmFyaWFudHMgZnJvbSB0aGUgMzU3MyB1bmlxdWUgc2VxdWVuY2VzIGluIHRoZSBmaXJzdCBzYW1wbGUuIA0KVGhlIGRhZGEgZnVuY3Rpb24gcmVtb3ZlcyBzZXF1ZW5jaW5nIGVycm9yIHRvIHJldmVhbCB0aGUgbWVtYmVycyBvZiB0aGUgc2VxdWVuY2VkIGNvbW11bml0eS4gDQoNCg0KI0NvbnN0cnVjdCBzZXF1ZW5jZSB0YWJsZSwgYSBPVFUgdGFibGUNCmBgYHtyfQ0Kc2VxdGFiIDwtIG1ha2VTZXF1ZW5jZVRhYmxlKGRhZGFGcykNCmBgYA0KDQojZnJhY3Rpb24gb2YgY2hpbWVyaWMgc2VxdWVuY2VzIGRldGVjdGVkDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kc2VxdGFiLm5vY2hpbWVyYSA8LSByZW1vdmVCaW1lcmFEZW5vdm8oc2VxdGFiKQ0KY2hpbWVyYXMgPSAxLShzdW0oc2VxdGFiLm5vY2hpbWVyYSkvc3VtKHNlcXRhYikpDQpjaGltZXJhcw0KYGBgDQpPbmx5IGFyb3VuZCAzJSBjaGltZXJhcyBpbiB0aGUgZGUtcmVwbGljYXRlZCBhbmQgZmlsdGVyZWQgZGF0YXNldCAtIHJlbW92ZWQgZm9yIGZ1cnRoZXIgYW5hbHlzaXMNCg0KI01ha2UgYSBkYXRhIGZyYW1lDQpgYGB7cn0NCmRmX3NlcSA9IGFzLmRhdGEuZnJhbWUoc2VxdGFiLm5vY2hpbWVyYSkNCmBgYA0KDQojQXNzaWduIHRheG9ub215IA0KQXNzaWduIHRheG9ub215IHVzaW5nIGxvY2FsIEJMQVNUIGFnYWluc3QgdGhlIFVOSVRFIGdlbmVyYWwgRkFTVEEgcmVsZWFzZSBmb3IgRnVuZ2kNCg0KYGBge3J9DQp0YXhhIDwtIGFzc2lnblRheG9ub215KHNlcXRhYi5ub2NoaW1lcmEsICJDOi9Vc2Vycy9mYXlzbWl0aC9EZXNrdG9wL3NlcS9zaF9nZW5lcmFsX3JlbGVhc2VfZHluYW1pY18wMS4xMi4yMDE3LmZhc3RhIikNCnRheGEucHJpbnQgPC0gdGF4YSAjcmVtb3Zpbmcgc2VxdWVuY2Ugcm93bmFtZXMgZm9yIGRpc3BsYXkgb25seQ0Kcm93bmFtZXModGF4YS5wcmludCkgPC0gTlVMTA0KaGVhZCh0YXhhLnByaW50KQ0KYGBgDQpTZWVtcyB0byBoYXZlIHdvcmtlZCB3ZWxsLiBBbGwgc2VxdWVuY2VzIGhhdmUgYmVlbiBuYW1lZCB0byBhdCBsZWFzdCB0aGUga2luZ2RvbS4gSSB3YXMgZ2V0dGluZyBtdWNoIHN0cmFuZ2VyIHJlc3VsdHMgYmVmb3JlLg0KDQojQXNzaWduIGEgcGh5bG9nZW5ldGljIHRyZWUgdG8gdGhlIGFtcGxpY29uIHNlcXVlbmNlcw0KYGBge3J9DQpzZXFzIDwtIGdldFNlcXVlbmNlcyhzZXF0YWIubm9jaGltZXJhKQ0KbmFtZXMoc2VxcykgPC0gc2Vxcw0KbXVsdCA8LSBtc2Eoc2VxcywgbWV0aG9kPSJDbHVzdGFsVyIsIHR5cGU9ImRuYSIsIG9yZGVyPSJpbnB1dCIpDQoNCnBoYW5nLmFsaWduIDwtIGFzLnBoeURhdChtdWx0LCB0eXBlPSJETkEiLCBuYW1lcz1nZXRTZXF1ZW5jZShzZXF0YWIpKQ0KZG0gPC0gZGlzdC5tbChwaGFuZy5hbGlnbikNCnRyZWVOSiA8LSBOSihkbSkgIyBOb3RlLCB0aXAgb3JkZXIgIT0gc2VxdWVuY2Ugb3JkZXINCmZpdCA9IHBtbCh0cmVlTkosIGRhdGE9cGhhbmcuYWxpZ24pDQoNCiMjIG5lZ2F0aXZlIGVkZ2VzIGxlbmd0aCBjaGFuZ2VkIHRvIDAhDQoNCmZpdEdUUiA8LSB1cGRhdGUoZml0LCBrPTQsIGludj0wLjIpDQpmaXRHVFIgPC0gb3B0aW0ucG1sKGZpdEdUUiwgbW9kZWw9IkdUUiIsIG9wdEludj1UUlVFLCBvcHRHYW1tYT1UUlVFLA0KICAgICAgICAgICAgICAgICAgICByZWFycmFuZ2VtZW50ID0gInN0b2NoYXN0aWMiLCBjb250cm9sID0gcG1sLmNvbnRyb2wodHJhY2UgPSAwKSkNCmRldGFjaCgicGFja2FnZTpwaGFuZ29ybiIsIHVubG9hZD1UUlVFKQ0KDQpgYGANCg0KDQojI0ZpbmFsIGRhdGEgbWFuaXB1bGF0aW9uIHRvIHJ1biBkaXZlcnNpdHkgYW5hbHlzZXMgd2l0aA0KI0NyZWF0ZSBhIGZpbGUgd2l0aCBhbGwgdGhlIHRyZWF0bWVudCBkYXRhIGluY2x1ZGVkDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kc2FtcGxlcy5vdXQgPC0gcm93bmFtZXMoc2VxdGFiLm5vY2hpbWVyYSkNCnNhbXBsZSA8LSBzYXBwbHkoc3Ryc3BsaXQoc2FtcGxlcy5vdXQsICJEIiksIGBbYCwgMSkNCnNhbV9yZXAgPC0gYygiMSIsIjEiLCIyIiwiMiIsIjEiLCIxIiwiMiIsIjIiLCIxIiwiMSIpDQpkZXB0aCA8LSBjKCIxIiwiMiIsIjEiLCIyIiwiMSIsIjIiLCIxIiwiMiIsIjEiLCIyIikNCmFyZWEgPC0gYyhyZXAoIk1vdW5kIiw0KSxyZXAoIkRlcHJlc3Npb24iLDQpLHJlcCgiUGFzdHVyZSIsMikpDQpzYW1kZiA8LSBkYXRhLmZyYW1lKFNhbXBsZUlEPXNhbXBsZSwgRGVwdGg9ZGVwdGgsIEFyZWE9YXJlYSwgUmVwbGljYXRpb24gPSBzYW1fcmVwKQ0Kcm93bmFtZXMoc2FtZGYpIDwtIHNhbXBsZXMub3V0DQoNCmBgYA0KDQojI0NyZWF0ZSB0aGUgcGh5bG9zZXEgb2JqZWN0IGZvciBmdXRoZXIgYW5hbHlzaXMNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpwcyA8LSBwaHlsb3NlcShvdHVfdGFibGUoc2VxdGFiLm5vY2hpbWVyYSwgdGF4YV9hcmVfcm93cz1GQUxTRSksDQogICAgICAgICAgICAgICBzYW1wbGVfZGF0YShzYW1kZiksDQogICAgICAgICAgICAgICB0YXhfdGFibGUodGF4YSkNCiAgICAgICAgICAgICAgICxwaHlfdHJlZShmaXRHVFIkdHJlZSkNCiAgICAgICAgICAgICAgICkNCnBzDQoNCmBgYA0KDQojc2F2ZSB0aGUgcGh5bG9zZXEgb2JqZWN0IGZvciBmdXJ0aGVyIGFubHlzaXMNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpzYXZlUkRTKHBzLCAiQzovVXNlcnMvZmF5c21pdGgvRGVza3RvcC9zZXEvcHMucmRzIikNCg0KYGBgDQoNCg==