Load libraries for anlyisis
try http:// if https:// URLs are not supported
Randomization housekeeping
set.seed(100)
Navigate to files and list file names
miseq_path <- "C:/Users/faysmith/Desktop/seq"
fnFs <- list.files(miseq_path, pattern=".fastq")
sampleNames <- sapply(strsplit(fnFs, "_"), '[', 1)
fnFs <- file.path(miseq_path, fnFs)
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==