Introduction

This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

First, I process the raw data are processed using QIIME and UPARSE (https://www.drive5.com/uparse/). I usually run the below outside of a Markdown notebook, but for clarity and simplicity I’ve included them below. Depending on your computer you may have problems running more memory intensive steps, e.g. taxonomy assignment and sequence alignment. For QIIME and UPARSE we used a 16 core (2x 8 core Intel Xeon) / 128 GB RAM workstation, running Ubuntu 16.10.

You will need the initial mapping file for QC, as well as the mapping (Both included in the github repository as well as supplemental data) file to recreate this analysis.

Software used: - QIIME 1.9.1 (http://qiime.org/) - UPARSE (https://www.drive5.com/uparse/) - PEAR (https://bioconda.github.io/recipes/pear/README.html) - All dependencies for the above software

Initial Pre-Processing

I keep QIIME in a virtual environment to keep everyone else happy on the workstation

bashbash source activate qiime1

The first block will extract sequence data from the R1 and R2 FASTQ files, ready for input into split_libraries_fastq. Our sequencing approach is non-directional, thus the need for checking both R1 and R2 files. Post extraction, we’ll concatenate togther (cat) the barcode and read files so we only have to run split_libraries_fastq one time.

bashbash pear -f seq/ngs-9y64x548t1_S1_L001_R1_001.fastq -r seq/ngs-9y64x548t1_S1_L001_R2_001.fastq -o seq/ML -p 0.001 -v 50 -m 450 -n 250 -y 500m -j 16

bashbash cat seq/ML.unassembled.* > seq/ML.Un.fastq

extract_barcodes.py -a -m map.txt -f seq/ML.assembled.fastq -a -m map.txt -l 12 -o seq/PrepJoin/

extract_barcodes.py -f seq/ML.Un.fastq -l 12 -o seq/PrepUn/

Onto demultiplexing. A minimum q-score of 20 was set to limit erronous basecalling as an issue downstream with deblur. Post split libraries the histograms were inspected, and a trim length of 210 bp was chosen for deblur. This length is a tradeoff for sequencing depth and taxonomic resolution. Greater than 90 percent of all reads were recovered post QC for entry into the deblur workflow.

bashbash split_libraries_fastq.py –barcode_type 12 -i seq/PrepJoin/reads.fastq -b seq/PrepJoin/barcodes.fastq -m map.txt –phred_quality_threshold 0 –store_demultiplexed_fastq -o seq/SlOutJoin/

split_libraries_fastq.py –barcode_type 12 -i seq/PrepUn/reads.fastq -b seq/PrepUn/barcodes.fastq -m map.txt –phred_quality_threshold 0 –store_demultiplexed_fastq -o seq/SlOutUn/

OTU Clustering and Taxonomy Assignment

bashbash mkdir UPARSE mkdir UPARSE/Join/ usearch64 -fastq_stats seq/SlOutJoin/seqs.fastq -log UPARSE/Join/seqs.stats.log usearch64 -fastq_filter seq/SlOutJoin/seqs.fastq -fastaout UPARSE/Join/seqs.filtered.fasta -fastq_maxee 1 -threads 16 usearch64 -derep_fulllength UPARSE/Join/seqs.filtered.fasta -fastaout UPARSE/Join/seqs.filtered.derep.fasta -sizeout -threads 16 usearch64 -sortbysize UPARSE/Join/seqs.filtered.derep.fasta -minsize 3 -fastaout UPARSE/Join/seqs.filtered.derep.mc2.fasta usearch64 -cluster_otus UPARSE/Join/seqs.filtered.derep.mc2.fasta -otus UPARSE/Join/seqs.filtered.derep.mc2.repset.fasta usearch64 -uchime_ref UPARSE/Join/seqs.filtered.derep.mc2.repset.fasta -db /media/analyses/DB/gold.fasta -strand plus -nonchimeras UPARSE/Join/seqs.filtered.derep.mc2.repset.nochimeras.fasta -threads 16 fasta_number.py UPARSE/Join/seqs.filtered.derep.mc2.repset.nochimeras.fasta OTU_ > UPARSE/Join/seqs.filtered.derep.mc2.repset.nochimeras.OTUs.fasta cp UPARSE/Join/seqs.filtered.derep.mc2.repset.nochimeras.OTUs.fasta UPARSE/Join/RepSet.fna usearch64 -usearch_global seq/SlOutJoin/seqs.fna -db UPARSE/Join/seqs.filtered.derep.mc2.repset.nochimeras.OTUs.fasta -strand plus -id 0.97 -uc UPARSE/Join/otu.map.uc -threads 16 python /home/lab/.conda/envs/qiime1/bin/uc2otutab.py UPARSE/Join/otu.map.uc > UPARSE/Join/seqs.filtered.derep.mc2.repset.nochimeras.OTU-table.txt assign_taxonomy.py -m mothur -t /media/analyses/DB/silva.nr_v128.tax -r /media/analyses/DB/silva.nr_v128.align -o UPARSE/Join/mothur_taxonomy/ -i UPARSE/Join/RepSet.fna biom convert –table-type=table -i UPARSE/Join/seqs.filtered.derep.mc2.repset.nochimeras.OTU-table.txt -o UPARSE/Join/UPARSE.biom –to-json biom add-metadata –sc-separated taxonomy –observation-header OTUID,taxonomy –observation-metadata-fp UPARSE/Join/mothur_taxonomy/RepSet_tax_assignments.txt -i UPARSE/Join/UPARSE.biom -o UPARSE/Join/UPARSE_w_tax.biom biom add-metadata -i UPARSE/Join/UPARSE_w_tax.biom -o UPARSE/Join/UPARSE.w_md.biom –sample-metadata-fp map.txt filter_samples_from_otu_table.py -m map.txt -s ‘SampleType:Control’ -n 200 -o UPARSE/Join/Control.biom -i UPARSE/Join/UPARSE.w_md.biom compute_core_microbiome.py –min_fraction_for_core 0.25 –max_fraction_for_core 0.95 -i UPARSE/Join/Control.biom -o UPARSE/Join/ControlCore/

bashbash mkdir UPARSE/Un/ usearch64 -fastq_stats seq/SlOutUn/seqs.fastq -log UPARSE/Un/seqs.stats.log usearch64 -fastq_filter seq/SlOutUn/seqs.fastq -fastaout UPARSE/Un/seqs.filtered.fasta -fastq_maxee 1 -threads 16 usearch64 -derep_fulllength UPARSE/Un/seqs.filtered.fasta -fastaout UPARSE/Un/seqs.filtered.derep.fasta -sizeout -threads 16 usearch64 -sortbysize UPARSE/Un/seqs.filtered.derep.fasta -minsize 3 -fastaout UPARSE/Un/seqs.filtered.derep.mc2.fasta usearch64 -cluster_otus UPARSE/Un/seqs.filtered.derep.mc2.fasta -otus UPARSE/Un/seqs.filtered.derep.mc2.repset.fasta usearch64 -uchime_ref UPARSE/Un/seqs.filtered.derep.mc2.repset.fasta -db /media/analyses/DB/gold.fasta -strand plus -nonchimeras UPARSE/Un/seqs.filtered.derep.mc2.repset.nochimeras.fasta -threads 16 fasta_number.py UPARSE/Un/seqs.filtered.derep.mc2.repset.nochimeras.fasta OTU_ > UPARSE/Un/seqs.filtered.derep.mc2.repset.nochimeras.OTUs.fasta cp UPARSE/Un/seqs.filtered.derep.mc2.repset.nochimeras.OTUs.fasta UPARSE/Un/RepSet.fna usearch64 -usearch_global seq/SlOutUn/seqs.fna -db UPARSE/Un/seqs.filtered.derep.mc2.repset.nochimeras.OTUs.fasta -strand plus -id 0.97 -uc UPARSE/Un/otu.map.uc -threads 16 python /home/lab/.conda/envs/qiime1/bin/uc2otutab.py UPARSE/Un/otu.map.uc > UPARSE/Un/seqs.filtered.derep.mc2.repset.nochimeras.OTU-table.txt assign_taxonomy.py -m mothur -t /media/analyses/DB/silva.nr_v128.tax -r /media/analyses/DB/silva.nr_v128.align -o UPARSE/Un/mothur_taxonomy/ -i UPARSE/Un/RepSet.fna biom convert –table-type=table -i UPARSE/Un/seqs.filtered.derep.mc2.repset.nochimeras.OTU-table.txt -o UPARSE/Un/UPARSE.biom –to-json biom add-metadata –sc-separated taxonomy –observation-header OTUID,taxonomy –observation-metadata-fp UPARSE/Un/mothur_taxonomy/RepSet_tax_assignments.txt -i UPARSE/Un/UPARSE.biom -o UPARSE/Un/UPARSE_w_tax.biom biom add-metadata -i UPARSE/Un/UPARSE_w_tax.biom -o UPARSE/Un/UPARSE.w_md.biom –sample-metadata-fp map.txt filter_samples_from_otu_table.py -m map.txt -s ‘SampleType:Control’ -n 500 -o UPARSE/Un/Control.biom -i UPARSE/Un/UPARSE.w_md.biom compute_core_microbiome.py –min_fraction_for_core 0.25 –max_fraction_for_core 0.75 -i UPARSE/Un/Control.biom -o UPARSE/Un/ControlCore/

Contamination Screening

A filter file was created from the OTUs found to be in 75 percent of my controls. This should be a pretty conservative filter of the most abundant contaminants found across my samples.

bashbash filter_otus_from_otu_table.py -e UPARSE/Join/ControlCore/core_otus_95.txt -s 3 -n 1 -i UPARSE/Join/UPARSE_w_tax.biom -o UPARSE/Join/PostControlFilter.biom filter_samples_from_otu_table.py –sample_id_fp AnalysisMap.txt -n 500 -i UPARSE/Join/PostControlFilter.biom -o UPARSE/Join/Analysis.biom filter_taxa_from_otu_table.py -n Eukaryota -i UPARSE/Join/Analysis.biom -o UPARSE/Analysis_BacArc.biom

filter_samples_from_otu_table.py –sample_id_fp AnalysisMap.txt -n 500 -i UPARSE/Un/UPARSE_w_tax.biom -o UPARSE/Un/Analysis.biom filter_taxa_from_otu_table.py -p Eukaryota -i UPARSE/Un/Analysis.biom -o UPARSE/Analysis_Euk.biom

Before moving on, I want to generate some summaries to see how many sequences I have left overall, and how many SVs were retained/removed after filtering.

bashbash biom summarize-table -i UPARSE/Join/UPARSE_w_tax.biom -o Join_all_w_tax_summary.txt biom summarize-table -i UPARSE/Join/PostControlFilter.biom -o Join_PostControlFilter_summary.txt biom summarize-table -i UPARSE/Join/Analysis.biom -o Join_Analysis_summary.txt biom summarize-table -i UPARSE/Analysis_BacArc.biom -o Analysis_BacArc_summary.txt

biom summarize-table -i UPARSE/Un/UPARSE_w_tax.biom -o Un_all_w_tax_summary.txt biom summarize-table -i UPARSE/Un/Analysis.biom -o Un_Analysis_summary.txt biom summarize-table -i UPARSE/Analysis_Euk.biom -o Analysis_Euk_summary.txt

What does this look like?

Unfiltered BIOM, post clustering: 601 OTUs, 724155 Sequences Post contaminant filtration: 569 OTUs, 634641 Sequences Post removal of control samples: 569 OTUs, 615813 Sequences Excluding Eukaryotic Sequence: 566 OTUs, 615518 Sequences

Counts/sample summary: Min: 1735.0 Max: 25105.0 Median: 7987.500 Mean: 8230.212 Std. dev.: 3413.020

Unfiltered BIOM, post clustering: 317 OTUs, 82062 Sequences Post removal of control samples: 317 OTUs, 81281 Sequences Excluding Bacterial and Archaeal Sequence: 265 OTUs, 79430 Sequences

Counts/sample summary: Min: 480.0 Max: 3333.0 Median: 1338.500 Mean: 1527.500 Std. dev.: 742.038

So, the vast majority of my sequence is non-eukarytoic. Otherwise, roughly 20 percent of the clustered OTUs were removed during contaminant filtering, but the vast majority (> 90 %) of seqeunce was retained.

Next, I’ll add sample metadata to each file, and then convert my two analysis BIOM files to JSON format for use in Phyloseq/R

bashbash biom add-metadata -i UPARSE/Analysis_BacArc.biom -o UPARSE/Analysis_BacArc.w_md.biom –sample-metadata-fp R_metadata.txt biom convert -i UPARSE/Analysis_BacArc.w_md.biom -o UPARSE/BacArc.w_md.json.biom –table-type=table –to-json

biom add-metadata -i UPARSE/Analysis_Euk.biom -o UPARSE/Analysis_Euk.w_md.biom –sample-metadata-fp R_metadata.txt biom convert -i UPARSE/Analysis_Euk.w_md.biom -o UPARSE/Euk.w_md.json.biom –table-type=table –to-json

Tree Building and Final BIOM File Generation

Last step before moving into R. Generation of phylogenetic trees for use in Phyloseq, as needed.

bashbash filter_fasta.py -b UPARSE/Analysis_BacArc.biom -f UPARSE/Join/RepSet.fna -o UPARSE/Analysis_BacArc.seqs.fa

filter_fasta.py -b UPARSE/Analysis_Euk.biom -f UPARSE/Un/RepSet.fna -o UPARSE/Analysis_Euk.seqs.fa

bashbash align_seqs.py -i UPARSE/Analysis_BacArc.seqs.fa -t /media/analyses/DB/SILVA_128_QIIME_release/rep_set_aligned/97/97_otus_aligned.fasta -o UPARSE/Analysis_BacArc_RepSet_Aligned/ align_seqs.py -i UPARSE/Analysis_Euk.seqs.fa -t /media/analyses/DB/SILVA_128_QIIME_release/rep_set_aligned/97/97_otus_aligned.fasta -o UPARSE/Analysis_Euk_RepSet_Aligned/

filter_alignment.py -i UPARSE/Analysis_BacArc_RepSet_Aligned/Analysis_BacArc.seqs_aligned.fasta -o UPARSE/Analysis_BacArc_RepSet_Aligned/ -e 0.001 filter_alignment.py -i UPARSE/Analysis_Euk_RepSet_Aligned/Analysis_Euk.seqs_aligned.fasta -o UPARSE/Analysis_Euk_RepSet_Aligned/ -e 0.001

make_phylogeny.py -i UPARSE/Analysis_BacArc_RepSet_Aligned/Analysis_BacArc.seqs_aligned_pfiltered.fasta -o UPARSE/BacArc.tre make_phylogeny.py -i UPARSE/Analysis_Euk_RepSet_Aligned/Analysis_Euk.seqs_aligned_pfiltered.fasta -o UPARSE/Euk.tre

Analysis in R

=====

Onto R. This can be run on (almost) any desktop/laptop without issue. In my case, I downloaded the above output files (.biom, .tre. and .fa) from my workstation onto my laptop to run the below.

Load Needed Libraries

rr library(phyloseq) library(ampvis) library(cowplot)

First, I’m going to import the my BIOM files, and format the taxonomy string to behave with Phyloseq and AmpVis.

rr ML.BacArc <- import_biom(.w_md.json.biom, .tre, _BacArc.seqs.fa, parseFunction=parse_taxonomy_default) ML.Euk <- import_biom(.w_md.json.biom, .tre, _Euk.seqs.fa, parseFunction=parse_taxonomy_default) colnames(tax_table(ML.BacArc)) = c(, , , , , ) colnames(tax_table(ML.Euk)) = c(, , , , , )

Next, I’ll subset my Phyloseq objects to exclude incubation samples. You can see the results of the incubations in supplementary data.

rr ML.wChloroplast.BacArc <- subset_samples(ML.BacArc, SampleName %in% c(.SurfaceWater, .2m, .10m, .20m,.25m, .Sed.10m, .Water, .RiverWater, .RiverWater, .RiverWater, .RiverWater)) ML.RA.wChloroplast.BacArc <- transform_sample_counts(ML.wChloroplast.BacArc, function(x) x / sum(x) * 100)

As a small step, chloroplast and mitochondial sequence need to be removed from the Bacterial/Archaeal phyloseq object- we’ll see them in the Eukaryotic dataset (Or at least the owners of those mitochondria and chloroplast…)

rr ML.BacArc.Filter <- ML.BacArc %>% subset_taxa( Family !=  & Class != )

I’m going to convert to relative abundances for some chart types. RA standing for “Relative Abundance”

rr ML.RA.BacArc <- transform_sample_counts(ML.BacArc.Filter, function(x) x / sum(x) * 100) ML.RA.Euk <- transform_sample_counts(ML.Euk, function(x) x / sum(x) * 100)

Next, I’m going to rarefy the table for later use. I set the rarefaction depth to include all samples.

rr ML.Rare.BacArc <- rarefy_even_depth(ML.BacArc.Filter, sample.size = 1500, rngseed = 712)

`set.seed(712)` was used to initialize repeatable random subsampling.
Please record this for your records so others can reproduce.
Try `set.seed(712); .Random.seed` for the full vector
...
6OTUs were removed because they are no longer 
present in any sample after random subsampling

...

rr ML.Rare.Euk <- rarefy_even_depth(ML.Euk, sample.size = 400, rngseed = 712)

`set.seed(712)` was used to initialize repeatable random subsampling.
Please record this for your records so others can reproduce.
Try `set.seed(712); .Random.seed` for the full vector
...
6OTUs were removed because they are no longer 
present in any sample after random subsampling

...

I need to subset the primary table to remove the incubations before proceeding. Also, I’ll go ahead and make a heatmap for the incubations, and show that there was no significant difference between treatments.

rr ML.RA.WaterOnly <- subset_samples(ML.RA.BacArc, SampleName %in% c(.SurfaceWater, .2m, .10m, .20m,.25m)) ML.And.Rivers.BA.RA <- subset_samples(ML.RA.BacArc, SampleName %in% c(.SurfaceWater, .2m, .10m, .20m,.25m, .Sed.10m, .Water, .RiverWater, .RiverWater, .RiverWater, .RiverWater)) ML.And.Rivers.Euk.RA <- subset_samples(ML.RA.Euk, SampleName %in% c(.SurfaceWater, .2m, .10m, .20m,.25m, .Sed.10m, .Water, .RiverWater, .RiverWater, .RiverWater, .RiverWater))

I’m going to define a color set to use throughout the script.

rr ML.cols <- c(.2m = , .10m = , .20m = , .25m = )

First up, figure 3- a heatmap of the top 25 taxa of either the Bacteria and Archaea (A), or the Eukarya (B) across the sampled depth transect at Mono, or the nearby streams and well.

rr Heatmap.BA<- amp_heatmap(data = ML.And.Rivers.BA.RA, tax.aggregate = , tax.add = , group = c(), tax.show = 25, tax.empty = , plot.numbers = F, plot.breaks = c(1.0,10.0,50.0), max.abundance = 50, min.abundance = 1, order.x = c(.SurfaceWater, .2m, .10m, .20m,.25m, .Sed.10m, .Water, .RiverWater, .RiverWater, .RiverWater, .RiverWater), scale.seq = 100) + scale_x_discrete(labels = c(,2 m,10 m,20 m,25 m,.10m,, , , , )) + theme(axis.text.x = element_text(size =8, color = , hjust = 0.4, angle = 0, family=New Roman, face=)) + theme(axis.text.y = element_text(size =8, color = , angle = 0, family=New Roman, face=)) Heatmap.E<-amp_heatmap(data = ML.And.Rivers.Euk.RA, tax.aggregate = , tax.add = , group = c(), tax.show = 25, tax.empty = , plot.numbers = F, plot.breaks = c(1.0,10.0,50.0), max.abundance = 50, min.abundance = 1, order.x = c(.SurfaceWater, .2m, .10m, .20m,.25m, .Sed.10m, .Water, .RiverWater, .RiverWater, .RiverWater, .RiverWater), scale.seq = 100) + scale_x_discrete(labels = c(,2 m,10 m,20 m,25 m,.10m,, , , , )) + theme(axis.text.x = element_text(size =8, color = , hjust = 0.4, angle = 0, family=New Roman, face=)) + theme(axis.text.y = element_text(size =8, color = , angle = 0, family=New Roman, face=)) plot_grid(Heatmap.BA,Heatmap.E, labels = c(, ), rel_widths = c(1,1),nrow = 2, align =

Transformation introduced infinite values in discrete y-axisTransformation introduced infinite values in discrete y-axis

Now, figure 4. Again, I’ll subset my dataset to now only include water samples from 2 to 25 m depth.

rr ML.BA.Rare.Transect <- subset_samples(ML.Rare.BacArc, SampleName %in% c(.2m, .10m, .20m,.25m)) ML.Euk.Rare.Transect <- subset_samples(ML.Rare.Euk, SampleName %in% c(.2m, .10m, .20m,.25m))

Figure 4 A) Bacteria/Archaea, and B) Eukarya

rr ML.BA.PCA <- ordinate(ML.BA.Rare.Transect, method = , distance = )

Randomly assigning root as -- OTU_543 -- in the phylogenetic tree in the data you provided.

rr ML.BA.PCA <- plot_ordination(ML.BA.Rare.Transect, ML.BA.PCA, color=) Transect.PCA.BA<-ML.BA.PCA + scale_colour_manual(values = ML.cols) + scale_fill_manual(values = ML.cols) + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = )) ML.Euk.PCA <- ordinate(ML.Euk.Rare.Transect, method = , distance = )

Randomly assigning root as -- OTU_119 -- in the phylogenetic tree in the data you provided.

rr ML.Euk.PCA <- plot_ordination(ML.Euk.Rare.Transect, ML.Euk.PCA, color=) Transect.PCA.E<- ML.Euk.PCA + scale_colour_manual(values = ML.cols) + scale_fill_manual(values = ML.cols) + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = )) plot_grid(Transect.PCA.BA,Transect.PCA.E, labels = c(, ), rel_widths = c(1,1),nrow = 2, align =

OK, so a clear separation between the deep (Red/Orange) samples and the more shallow (Blue) samples. We’ll confirm by ADONIS in a little bit.

rr ML.BA.Rare.Data = as(sample_data(ML.BA.Rare.Transect), .frame) BA.d = phyloseq::distance(ML.BA.Rare.Transect, )

Randomly assigning root as -- OTU_141 -- in the phylogenetic tree in the data you provided.

rr ML.Euk.Rare.Data = as(sample_data(ML.Euk.Rare.Transect), .frame) Euk.d = phyloseq::distance(ML.Euk.Rare.Transect, )

Randomly assigning root as -- OTU_192 -- in the phylogenetic tree in the data you provided.

rr adonis(BA.d ~ SampleName, ML.BA.Rare.Data)


Call:
adonis(formula = BA.d ~ SampleName, data = ML.BA.Rare.Data) 

Permutation: free
Number of permutations: 999

Terms added sequentially (first to last)

           Df SumsOfSqs  MeanSqs F.Model      R2 Pr(>F)   
SampleName  3  0.079328 0.026443  26.417 0.90831  0.002 **
Residuals   8  0.008008 0.001001         0.09169          
Total      11  0.087335                  1.00000          
---
Signif. codes:  
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Overall, highly significant with very high (> 0.90) R2 value.

rr adonis(Euk.d ~ SampleName, ML.Euk.Rare.Data)


Call:
adonis(formula = Euk.d ~ SampleName, data = ML.Euk.Rare.Data) 

Permutation: free
Number of permutations: 999

Terms added sequentially (first to last)

           Df SumsOfSqs    MeanSqs F.Model      R2 Pr(>F)  
SampleName  3 0.0028041 0.00093469  4.2684 0.61548  0.017 *
Residuals   8 0.0017518 0.00021898         0.38452         
Total      11 0.0045559                    1.00000         
---
Signif. codes:  
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

The Eukarya produce a significant, but much weaker difference between depths. This is likely driven by the high relative abundance of an OTU most closely related to Picocystis sp.

——SUPPLEMENTAL——

Let’s see what the samples look like with chloroplast included

rr amp_heatmap(data = ML.RA.wChloroplast.BacArc, tax.aggregate = , tax.add = , group = c(), tax.show = 25, tax.empty = , plot.numbers = T, plot.breaks = c(1.0,10.0,50.0), max.abundance = 50, min.abundance = 1, order.x = c(.SurfaceWater, .2m, .10m, .20m,.25m, .Sed.10m, .Water, .RiverWater, .RiverWater, .RiverWater, .RiverWater), scale.seq = 100) + scale_x_discrete(labels = c(,2 m,10 m,20 m,25 m,.10m,, , , , )) + theme(axis.text.x = element_text(size =8, color = , hjust = 0.4, angle = 0, family=New Roman, face=)) + theme(axis.text.y = element_text(size =8, color = , angle = 0, family=New Roman, face=))

rr ML.BA.RA.Incubation <- subset_samples(ML.RA.BacArc, SampleName %in% c(..CC.Zero, .CC.MeOH, .CC.B, .CC.NH4, .CC.No, .CC.G, .2m)) ML.Euk.RA.Incubation <- subset_samples(ML.RA.Euk, SampleName %in% c(..CC.Zero, .CC.MeOH, .CC.B, .CC.NH4, .CC.No, .CC.G, .2m)) ML.BA.Rare.Incubation <- subset_samples(ML.Rare.BacArc, SampleName %in% c(..CC.Zero, .CC.MeOH, .CC.B, .CC.NH4, .CC.No, .CC.G, .2m)) ML.Euk.Rare.Incubation <- subset_samples(ML.Rare.Euk, SampleName %in% c(..CC.Zero, .CC.MeOH, .CC.B, .CC.NH4, .CC.No, .CC.G, .2m))

rr inc.cols <- c(..CC.Zero = 1, .CC.MeOH = , .CC.B = 1, .CC.NH4 = , .CC.No = , .CC.G = 2, .2m = )

First I’d like to look at any differences caused by our incubations.

rr Rabund.BA<-amp_rabund(data = ML.BA.RA.Incubation, tax.aggregate = , tax.add = , group = c(), tax.show = 15, tax.empty = ) + scale_colour_manual(values = inc.cols) + scale_fill_manual(values = inc.cols)

Rabund.E<- amp_rabund(data = ML.Euk.RA.Incubation, tax.aggregate = , tax.add = , group = c(), tax.show = 5, tax.empty = ) + scale_colour_manual(values = inc.cols) + scale_fill_manual(values = inc.cols)

plot_grid(Rabund.BA,Rabund.E, labels = c(, ), rel_widths = c(1,1),nrow = 2, align =

rr ML.BA.Rare.Incubation.Data = as(sample_data(ML.BA.Rare.Incubation), .frame) Incubation.BA.d = phyloseq::distance(ML.BA.Rare.Incubation, ) adonis(Incubation.BA.d ~ SampleName, ML.BA.Rare.Incubation.Data)

rr Incubation.Euk.Rare.Data = as(sample_data(ML.Euk.Rare.Incubation), .frame) Incubation.Euk.d = phyloseq::distance(ML.Euk.Rare.Incubation, ) adonis(Incubation.Euk.d ~ SampleName, Incubation.Euk.Rare.Data)

rr Incubation.BA.Rare.Data = as(sample_data(ML.BA.Rare.Incubation), .frame) Incubation.BA.d = phyloseq::distance(ML.BA.Rare.Incubation, ) adonis(Incubation.BA.d ~ SampleName, Incubation.BA.Rare.Data)

Nonsignificant- not totally suprising, but we need to confirm this. Moving onto the primary data in the manuscript now. Looking at the lake itself, and the rivers that surround it. An aside from the topic of the paper, but, potentially of interest to readers- what about the rivers? Are they different?

rr Stream.BA.Rare <- subset_samples(ML.Rare.BacArc, SampleName %in% c(.RiverWater, .RiverWater, .RiverWater, .RiverWater)) Stream.Euk.Rare <- subset_samples(ML.Rare.Euk, SampleName %in% c(.RiverWater, .RiverWater, .RiverWater, .RiverWater))

rr river.cols <- c(.RiverWater = 1, .RiverWater = 4, .RiverWater = , .RiverWater = )

rr Stream.BA.PCA <- ordinate(Stream.BA.Rare, method = , distance = ) Stream.BA.PCA <- plot_ordination(Stream.BA.Rare, Stream.BA.PCA, color=) Stream.BA.PCA + scale_colour_manual(values = river.cols) + scale_fill_manual(values = river.cols) + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = ))

The Eukaryotic communities could not be processed for the streams due to low sequence count. So, let’s contiute with the bacterial/archaeal samples.

rr Stream.BA.Rare.Data = as(sample_data(Stream.BA.Rare), .frame) Stream.BA.d = phyloseq::distance(Stream.BA.Rare, ) adonis(Stream.BA.d ~ SampleName, Stream.BA.Rare.Data)

Highly significant, with a strong effect size.

Finally, I’m going to produce a heatmap that was useful to see the percentages of Picocystis.

rr Heatmap.BA<- amp_heatmap(data = ML.And.Rivers.BA.RA, tax.aggregate = , tax.add = , group = c(), tax.show = 25, tax.empty = , plot.numbers = F, plot.breaks = c(1.0,10.0,50.0), max.abundance = 50, min.abundance = 1, order.x = c(.SurfaceWater, .2m, .10m, .20m,.25m, .Sed.10m, .Water, .RiverWater, .RiverWater, .RiverWater, .RiverWater), scale.seq = 100) + scale_x_discrete(labels = c(,2 m,10 m,20 m,25 m,.10m,, , , , )) + theme(axis.text.x = element_text(size =8, color = , hjust = 0.4, angle = 0, family=New Roman, face=)) + theme(axis.text.y = element_text(size =8, color = , angle = 0, family=New Roman, face=)) Heatmap.E<-amp_heatmap(data = ML.And.Rivers.Euk.RA, tax.aggregate = , tax.add = , group = c(), tax.show = 25, tax.empty = , plot.numbers = T, plot.breaks = c(1.0,10.0,50.0), max.abundance = 50, min.abundance = 1, order.x = c(.SurfaceWater, .2m, .10m, .20m,.25m, .Sed.10m, .Water, .RiverWater, .RiverWater, .RiverWater, .RiverWater), scale.seq = 100) + scale_x_discrete(labels = c(,2 m,10 m,20 m,25 m,.10m,, , , , )) + theme(axis.text.x = element_text(size =8, color = , hjust = 0.4, angle = 0, family=New Roman, face=)) + theme(axis.text.y = element_text(size =8, color = , angle = 0, family=New Roman, face=)) plot_grid(Heatmap.BA,Heatmap.E, labels = c(, ), rel_widths = c(1,1),nrow = 2, align =

Transformation introduced infinite values in discrete y-axisTransformation introduced infinite values in discrete y-axis

LS0tCnRpdGxlOiAiVGhlIE1ldGFib2xpYyBDYXBhYmlsaXR5IGFuZCBQaHlsb2dlbmV0aWMgRGl2ZXJzaXR5IG9mIE1vbm8gTGFrZSBEdXJpbmcgYSBCbG9vbSBvZiBQaWNvY3lzdGlzIHN0cmFpbiBNTCAiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCkludHJvZHVjdGlvbgo9PT09PT0KClRoaXMgaXMgYW4gW1IgTWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pIE5vdGVib29rLiBXaGVuIHlvdSBleGVjdXRlIGNvZGUgd2l0aGluIHRoZSBub3RlYm9vaywgdGhlIHJlc3VsdHMgYXBwZWFyIGJlbmVhdGggdGhlIGNvZGUuCgoKRmlyc3QsIEkgcHJvY2VzcyB0aGUgcmF3IGRhdGEgYXJlIHByb2Nlc3NlZCB1c2luZyBRSUlNRSBhbmQgVVBBUlNFIChodHRwczovL3d3dy5kcml2ZTUuY29tL3VwYXJzZS8pLiBJIHVzdWFsbHkgcnVuIHRoZSBiZWxvdyBvdXRzaWRlIG9mIGEgTWFya2Rvd24gbm90ZWJvb2ssIGJ1dCBmb3IgY2xhcml0eSBhbmQgc2ltcGxpY2l0eSBJJ3ZlIGluY2x1ZGVkIHRoZW0gYmVsb3cuIERlcGVuZGluZyBvbiB5b3VyIGNvbXB1dGVyIHlvdSBtYXkgaGF2ZSBwcm9ibGVtcyBydW5uaW5nIG1vcmUgbWVtb3J5IGludGVuc2l2ZSBzdGVwcywgZS5nLiB0YXhvbm9teSBhc3NpZ25tZW50IGFuZCBzZXF1ZW5jZSBhbGlnbm1lbnQuIEZvciBRSUlNRSBhbmQgVVBBUlNFIHdlIHVzZWQgYSAxNiBjb3JlICgyeCA4IGNvcmUgSW50ZWwgWGVvbikgLyAxMjggR0IgUkFNIHdvcmtzdGF0aW9uLCBydW5uaW5nIFVidW50dSAxNi4xMC4gCgpZb3Ugd2lsbCBuZWVkIHRoZSBpbml0aWFsIG1hcHBpbmcgZmlsZSBmb3IgUUMsIGFzIHdlbGwgYXMgdGhlIG1hcHBpbmcgKEJvdGggaW5jbHVkZWQgaW4gdGhlIGdpdGh1YiByZXBvc2l0b3J5IGFzIHdlbGwgYXMgc3VwcGxlbWVudGFsIGRhdGEpIGZpbGUgdG8gcmVjcmVhdGUgdGhpcyBhbmFseXNpcy4KClNvZnR3YXJlIHVzZWQ6IAotIFFJSU1FIDEuOS4xIChodHRwOi8vcWlpbWUub3JnLykKLSBVUEFSU0UgKGh0dHBzOi8vd3d3LmRyaXZlNS5jb20vdXBhcnNlLykKLSBQRUFSIChodHRwczovL2Jpb2NvbmRhLmdpdGh1Yi5pby9yZWNpcGVzL3BlYXIvUkVBRE1FLmh0bWwpCi0gQWxsIGRlcGVuZGVuY2llcyBmb3IgdGhlIGFib3ZlIHNvZnR3YXJlCgpJbml0aWFsIFByZS1Qcm9jZXNzaW5nCj09PT0KCkkga2VlcCBRSUlNRSBpbiBhIHZpcnR1YWwgZW52aXJvbm1lbnQgdG8ga2VlcCBldmVyeW9uZSBlbHNlIGhhcHB5IG9uIHRoZSB3b3Jrc3RhdGlvbiAKCmBgYHtiYXNofQpzb3VyY2UgYWN0aXZhdGUgcWlpbWUxCmBgYAoKVGhlIGZpcnN0IGJsb2NrIHdpbGwgZXh0cmFjdCBzZXF1ZW5jZSBkYXRhIGZyb20gdGhlIFIxIGFuZCBSMiBGQVNUUSBmaWxlcywgcmVhZHkgZm9yIGlucHV0IGludG8gc3BsaXRfbGlicmFyaWVzX2Zhc3RxLiBPdXIgc2VxdWVuY2luZyBhcHByb2FjaCBpcyBub24tZGlyZWN0aW9uYWwsIHRodXMgdGhlIG5lZWQgZm9yIGNoZWNraW5nIGJvdGggUjEgYW5kIFIyIGZpbGVzLiBQb3N0IGV4dHJhY3Rpb24sIHdlJ2xsIGNvbmNhdGVuYXRlIHRvZ3RoZXIgKGNhdCkgdGhlIGJhcmNvZGUgYW5kIHJlYWQgZmlsZXMgc28gd2Ugb25seSBoYXZlIHRvIHJ1biBzcGxpdF9saWJyYXJpZXNfZmFzdHEgb25lIHRpbWUuCgpgYGB7YmFzaH0KcGVhciAtZiBzZXEvbmdzLTl5NjR4NTQ4dDFfUzFfTDAwMV9SMV8wMDEuZmFzdHEgLXIgc2VxL25ncy05eTY0eDU0OHQxX1MxX0wwMDFfUjJfMDAxLmZhc3RxIC1vIHNlcS9NTCAtcCAwLjAwMSAtdiA1MCAtbSA0NTAgLW4gMjUwIC15IDUwMG0gLWogMTYKYGBgCgpgYGB7YmFzaH0KY2F0IHNlcS9NTC51bmFzc2VtYmxlZC4qID4gc2VxL01MLlVuLmZhc3RxCgpleHRyYWN0X2JhcmNvZGVzLnB5IC1hIC1tIG1hcC50eHQgLWYgc2VxL01MLmFzc2VtYmxlZC5mYXN0cSAtYSAtbSBtYXAudHh0IC1sIDEyIC1vIHNlcS9QcmVwSm9pbi8KCmV4dHJhY3RfYmFyY29kZXMucHkgLWYgc2VxL01MLlVuLmZhc3RxIC1sIDEyIC1vIHNlcS9QcmVwVW4vCgpgYGAKCk9udG8gZGVtdWx0aXBsZXhpbmcuIEEgbWluaW11bSBxLXNjb3JlIG9mIDIwIHdhcyBzZXQgdG8gbGltaXQgZXJyb25vdXMgYmFzZWNhbGxpbmcgYXMgYW4gaXNzdWUgZG93bnN0cmVhbSB3aXRoIGRlYmx1ci4gUG9zdCBzcGxpdCBsaWJyYXJpZXMgdGhlIGhpc3RvZ3JhbXMgd2VyZSBpbnNwZWN0ZWQsIGFuZCBhIHRyaW0gbGVuZ3RoIG9mIDIxMCBicCB3YXMgY2hvc2VuIGZvciBkZWJsdXIuIFRoaXMgbGVuZ3RoIGlzIGEgdHJhZGVvZmYgZm9yIHNlcXVlbmNpbmcgZGVwdGggYW5kIHRheG9ub21pYyByZXNvbHV0aW9uLiBHcmVhdGVyIHRoYW4gOTAgcGVyY2VudCBvZiBhbGwgcmVhZHMgd2VyZSByZWNvdmVyZWQgcG9zdCBRQyBmb3IgZW50cnkgaW50byB0aGUgZGVibHVyIHdvcmtmbG93LgpgYGB7YmFzaH0Kc3BsaXRfbGlicmFyaWVzX2Zhc3RxLnB5IC0tYmFyY29kZV90eXBlIDEyIC1pIHNlcS9QcmVwSm9pbi9yZWFkcy5mYXN0cSAtYiBzZXEvUHJlcEpvaW4vYmFyY29kZXMuZmFzdHEgLW0gbWFwLnR4dCAtLXBocmVkX3F1YWxpdHlfdGhyZXNob2xkIDAgLS1zdG9yZV9kZW11bHRpcGxleGVkX2Zhc3RxIC1vIHNlcS9TbE91dEpvaW4vCgpzcGxpdF9saWJyYXJpZXNfZmFzdHEucHkgLS1iYXJjb2RlX3R5cGUgMTIgLWkgc2VxL1ByZXBVbi9yZWFkcy5mYXN0cSAtYiBzZXEvUHJlcFVuL2JhcmNvZGVzLmZhc3RxIC1tIG1hcC50eHQgLS1waHJlZF9xdWFsaXR5X3RocmVzaG9sZCAwIC0tc3RvcmVfZGVtdWx0aXBsZXhlZF9mYXN0cSAtbyBzZXEvU2xPdXRVbi8KYGBgCgpPVFUgQ2x1c3RlcmluZyBhbmQgVGF4b25vbXkgQXNzaWdubWVudAo9PT09PQoKCmBgYHtiYXNofQpta2RpciBVUEFSU0UKbWtkaXIgVVBBUlNFL0pvaW4vCnVzZWFyY2g2NCAtZmFzdHFfc3RhdHMgc2VxL1NsT3V0Sm9pbi9zZXFzLmZhc3RxIC1sb2cgVVBBUlNFL0pvaW4vc2Vxcy5zdGF0cy5sb2cKdXNlYXJjaDY0IC1mYXN0cV9maWx0ZXIgc2VxL1NsT3V0Sm9pbi9zZXFzLmZhc3RxIC1mYXN0YW91dCBVUEFSU0UvSm9pbi9zZXFzLmZpbHRlcmVkLmZhc3RhIC1mYXN0cV9tYXhlZSAxIC10aHJlYWRzIDE2CnVzZWFyY2g2NCAtZGVyZXBfZnVsbGxlbmd0aCBVUEFSU0UvSm9pbi9zZXFzLmZpbHRlcmVkLmZhc3RhICAtZmFzdGFvdXQgVVBBUlNFL0pvaW4vc2Vxcy5maWx0ZXJlZC5kZXJlcC5mYXN0YSAtc2l6ZW91dCAtdGhyZWFkcyAxNgp1c2VhcmNoNjQgLXNvcnRieXNpemUgVVBBUlNFL0pvaW4vc2Vxcy5maWx0ZXJlZC5kZXJlcC5mYXN0YSAtbWluc2l6ZSAzIC1mYXN0YW91dCBVUEFSU0UvSm9pbi9zZXFzLmZpbHRlcmVkLmRlcmVwLm1jMi5mYXN0YQp1c2VhcmNoNjQgLWNsdXN0ZXJfb3R1cyBVUEFSU0UvSm9pbi9zZXFzLmZpbHRlcmVkLmRlcmVwLm1jMi5mYXN0YSAtb3R1cyBVUEFSU0UvSm9pbi9zZXFzLmZpbHRlcmVkLmRlcmVwLm1jMi5yZXBzZXQuZmFzdGEKdXNlYXJjaDY0IC11Y2hpbWVfcmVmIFVQQVJTRS9Kb2luL3NlcXMuZmlsdGVyZWQuZGVyZXAubWMyLnJlcHNldC5mYXN0YSAtZGIgL21lZGlhL2FuYWx5c2VzL0RCL2dvbGQuZmFzdGEgIC1zdHJhbmQgcGx1cyAtbm9uY2hpbWVyYXMgVVBBUlNFL0pvaW4vc2Vxcy5maWx0ZXJlZC5kZXJlcC5tYzIucmVwc2V0Lm5vY2hpbWVyYXMuZmFzdGEgLXRocmVhZHMgMTYKZmFzdGFfbnVtYmVyLnB5IFVQQVJTRS9Kb2luL3NlcXMuZmlsdGVyZWQuZGVyZXAubWMyLnJlcHNldC5ub2NoaW1lcmFzLmZhc3RhIE9UVV8gPiBVUEFSU0UvSm9pbi9zZXFzLmZpbHRlcmVkLmRlcmVwLm1jMi5yZXBzZXQubm9jaGltZXJhcy5PVFVzLmZhc3RhCmNwIFVQQVJTRS9Kb2luL3NlcXMuZmlsdGVyZWQuZGVyZXAubWMyLnJlcHNldC5ub2NoaW1lcmFzLk9UVXMuZmFzdGEgVVBBUlNFL0pvaW4vUmVwU2V0LmZuYQp1c2VhcmNoNjQgLXVzZWFyY2hfZ2xvYmFsIHNlcS9TbE91dEpvaW4vc2Vxcy5mbmEgLWRiIFVQQVJTRS9Kb2luL3NlcXMuZmlsdGVyZWQuZGVyZXAubWMyLnJlcHNldC5ub2NoaW1lcmFzLk9UVXMuZmFzdGEgLXN0cmFuZCBwbHVzIC1pZCAwLjk3IC11YyBVUEFSU0UvSm9pbi9vdHUubWFwLnVjIC10aHJlYWRzIDE2CnB5dGhvbiAvaG9tZS9sYWIvLmNvbmRhL2VudnMvcWlpbWUxL2Jpbi91YzJvdHV0YWIucHkgVVBBUlNFL0pvaW4vb3R1Lm1hcC51YyA+IFVQQVJTRS9Kb2luL3NlcXMuZmlsdGVyZWQuZGVyZXAubWMyLnJlcHNldC5ub2NoaW1lcmFzLk9UVS10YWJsZS50eHQKYXNzaWduX3RheG9ub215LnB5IC1tIG1vdGh1ciAtdCAvbWVkaWEvYW5hbHlzZXMvREIvc2lsdmEubnJfdjEyOC50YXggLXIgL21lZGlhL2FuYWx5c2VzL0RCL3NpbHZhLm5yX3YxMjguYWxpZ24gLW8gVVBBUlNFL0pvaW4vbW90aHVyX3RheG9ub215LyAtaSBVUEFSU0UvSm9pbi9SZXBTZXQuZm5hCmJpb20gY29udmVydCAtLXRhYmxlLXR5cGU9Ik9UVSB0YWJsZSIgLWkgVVBBUlNFL0pvaW4vc2Vxcy5maWx0ZXJlZC5kZXJlcC5tYzIucmVwc2V0Lm5vY2hpbWVyYXMuT1RVLXRhYmxlLnR4dCAtbyBVUEFSU0UvSm9pbi9VUEFSU0UuYmlvbSAtLXRvLWpzb24KYmlvbSBhZGQtbWV0YWRhdGEgLS1zYy1zZXBhcmF0ZWQgdGF4b25vbXkgLS1vYnNlcnZhdGlvbi1oZWFkZXIgT1RVSUQsdGF4b25vbXkgLS1vYnNlcnZhdGlvbi1tZXRhZGF0YS1mcCBVUEFSU0UvSm9pbi9tb3RodXJfdGF4b25vbXkvUmVwU2V0X3RheF9hc3NpZ25tZW50cy50eHQgLWkgVVBBUlNFL0pvaW4vVVBBUlNFLmJpb20gLW8gVVBBUlNFL0pvaW4vVVBBUlNFX3dfdGF4LmJpb20gCmJpb20gYWRkLW1ldGFkYXRhIC1pIFVQQVJTRS9Kb2luL1VQQVJTRV93X3RheC5iaW9tIC1vIFVQQVJTRS9Kb2luL1VQQVJTRS53X21kLmJpb20gLS1zYW1wbGUtbWV0YWRhdGEtZnAgbWFwLnR4dApmaWx0ZXJfc2FtcGxlc19mcm9tX290dV90YWJsZS5weSAtbSBtYXAudHh0IC1zICdTYW1wbGVUeXBlOkNvbnRyb2wnIC1uIDIwMCAtbyBVUEFSU0UvSm9pbi9Db250cm9sLmJpb20gLWkgVVBBUlNFL0pvaW4vVVBBUlNFLndfbWQuYmlvbQpjb21wdXRlX2NvcmVfbWljcm9iaW9tZS5weSAtLW1pbl9mcmFjdGlvbl9mb3JfY29yZSAwLjI1IC0tbWF4X2ZyYWN0aW9uX2Zvcl9jb3JlIDAuOTUgLWkgVVBBUlNFL0pvaW4vQ29udHJvbC5iaW9tIC1vIFVQQVJTRS9Kb2luL0NvbnRyb2xDb3JlLwpgYGAKCmBgYHtiYXNofQpta2RpciBVUEFSU0UvVW4vCnVzZWFyY2g2NCAtZmFzdHFfc3RhdHMgc2VxL1NsT3V0VW4vc2Vxcy5mYXN0cSAtbG9nIFVQQVJTRS9Vbi9zZXFzLnN0YXRzLmxvZwp1c2VhcmNoNjQgLWZhc3RxX2ZpbHRlciBzZXEvU2xPdXRVbi9zZXFzLmZhc3RxIC1mYXN0YW91dCBVUEFSU0UvVW4vc2Vxcy5maWx0ZXJlZC5mYXN0YSAtZmFzdHFfbWF4ZWUgMSAtdGhyZWFkcyAxNgp1c2VhcmNoNjQgLWRlcmVwX2Z1bGxsZW5ndGggVVBBUlNFL1VuL3NlcXMuZmlsdGVyZWQuZmFzdGEgIC1mYXN0YW91dCBVUEFSU0UvVW4vc2Vxcy5maWx0ZXJlZC5kZXJlcC5mYXN0YSAtc2l6ZW91dCAtdGhyZWFkcyAxNgp1c2VhcmNoNjQgLXNvcnRieXNpemUgVVBBUlNFL1VuL3NlcXMuZmlsdGVyZWQuZGVyZXAuZmFzdGEgLW1pbnNpemUgMyAtZmFzdGFvdXQgVVBBUlNFL1VuL3NlcXMuZmlsdGVyZWQuZGVyZXAubWMyLmZhc3RhCnVzZWFyY2g2NCAtY2x1c3Rlcl9vdHVzIFVQQVJTRS9Vbi9zZXFzLmZpbHRlcmVkLmRlcmVwLm1jMi5mYXN0YSAtb3R1cyBVUEFSU0UvVW4vc2Vxcy5maWx0ZXJlZC5kZXJlcC5tYzIucmVwc2V0LmZhc3RhCnVzZWFyY2g2NCAtdWNoaW1lX3JlZiBVUEFSU0UvVW4vc2Vxcy5maWx0ZXJlZC5kZXJlcC5tYzIucmVwc2V0LmZhc3RhIC1kYiAvbWVkaWEvYW5hbHlzZXMvREIvZ29sZC5mYXN0YSAgLXN0cmFuZCBwbHVzIC1ub25jaGltZXJhcyBVUEFSU0UvVW4vc2Vxcy5maWx0ZXJlZC5kZXJlcC5tYzIucmVwc2V0Lm5vY2hpbWVyYXMuZmFzdGEgLXRocmVhZHMgMTYKZmFzdGFfbnVtYmVyLnB5IFVQQVJTRS9Vbi9zZXFzLmZpbHRlcmVkLmRlcmVwLm1jMi5yZXBzZXQubm9jaGltZXJhcy5mYXN0YSBPVFVfID4gVVBBUlNFL1VuL3NlcXMuZmlsdGVyZWQuZGVyZXAubWMyLnJlcHNldC5ub2NoaW1lcmFzLk9UVXMuZmFzdGEKY3AgVVBBUlNFL1VuL3NlcXMuZmlsdGVyZWQuZGVyZXAubWMyLnJlcHNldC5ub2NoaW1lcmFzLk9UVXMuZmFzdGEgVVBBUlNFL1VuL1JlcFNldC5mbmEKdXNlYXJjaDY0IC11c2VhcmNoX2dsb2JhbCBzZXEvU2xPdXRVbi9zZXFzLmZuYSAtZGIgVVBBUlNFL1VuL3NlcXMuZmlsdGVyZWQuZGVyZXAubWMyLnJlcHNldC5ub2NoaW1lcmFzLk9UVXMuZmFzdGEgLXN0cmFuZCBwbHVzIC1pZCAwLjk3IC11YyBVUEFSU0UvVW4vb3R1Lm1hcC51YyAtdGhyZWFkcyAxNgpweXRob24gL2hvbWUvbGFiLy5jb25kYS9lbnZzL3FpaW1lMS9iaW4vdWMyb3R1dGFiLnB5IFVQQVJTRS9Vbi9vdHUubWFwLnVjID4gVVBBUlNFL1VuL3NlcXMuZmlsdGVyZWQuZGVyZXAubWMyLnJlcHNldC5ub2NoaW1lcmFzLk9UVS10YWJsZS50eHQKYXNzaWduX3RheG9ub215LnB5IC1tIG1vdGh1ciAtdCAvbWVkaWEvYW5hbHlzZXMvREIvc2lsdmEubnJfdjEyOC50YXggLXIgL21lZGlhL2FuYWx5c2VzL0RCL3NpbHZhLm5yX3YxMjguYWxpZ24gLW8gVVBBUlNFL1VuL21vdGh1cl90YXhvbm9teS8gLWkgVVBBUlNFL1VuL1JlcFNldC5mbmEKYmlvbSBjb252ZXJ0IC0tdGFibGUtdHlwZT0iT1RVIHRhYmxlIiAtaSBVUEFSU0UvVW4vc2Vxcy5maWx0ZXJlZC5kZXJlcC5tYzIucmVwc2V0Lm5vY2hpbWVyYXMuT1RVLXRhYmxlLnR4dCAtbyBVUEFSU0UvVW4vVVBBUlNFLmJpb20gLS10by1qc29uCmJpb20gYWRkLW1ldGFkYXRhIC0tc2Mtc2VwYXJhdGVkIHRheG9ub215IC0tb2JzZXJ2YXRpb24taGVhZGVyIE9UVUlELHRheG9ub215IC0tb2JzZXJ2YXRpb24tbWV0YWRhdGEtZnAgVVBBUlNFL1VuL21vdGh1cl90YXhvbm9teS9SZXBTZXRfdGF4X2Fzc2lnbm1lbnRzLnR4dCAtaSBVUEFSU0UvVW4vVVBBUlNFLmJpb20gLW8gVVBBUlNFL1VuL1VQQVJTRV93X3RheC5iaW9tIApiaW9tIGFkZC1tZXRhZGF0YSAtaSBVUEFSU0UvVW4vVVBBUlNFX3dfdGF4LmJpb20gLW8gVVBBUlNFL1VuL1VQQVJTRS53X21kLmJpb20gLS1zYW1wbGUtbWV0YWRhdGEtZnAgbWFwLnR4dApmaWx0ZXJfc2FtcGxlc19mcm9tX290dV90YWJsZS5weSAtbSBtYXAudHh0IC1zICdTYW1wbGVUeXBlOkNvbnRyb2wnIC1uIDUwMCAtbyBVUEFSU0UvVW4vQ29udHJvbC5iaW9tIC1pIFVQQVJTRS9Vbi9VUEFSU0Uud19tZC5iaW9tCmNvbXB1dGVfY29yZV9taWNyb2Jpb21lLnB5IC0tbWluX2ZyYWN0aW9uX2Zvcl9jb3JlIDAuMjUgLS1tYXhfZnJhY3Rpb25fZm9yX2NvcmUgMC43NSAtaSBVUEFSU0UvVW4vQ29udHJvbC5iaW9tIC1vIFVQQVJTRS9Vbi9Db250cm9sQ29yZS8KYGBgCgpDb250YW1pbmF0aW9uIFNjcmVlbmluZwo9PT09CgpBIGZpbHRlciBmaWxlIHdhcyBjcmVhdGVkIGZyb20gdGhlIE9UVXMgZm91bmQgdG8gYmUgaW4gNzUgcGVyY2VudCBvZiBteSBjb250cm9scy4gVGhpcyBzaG91bGQgYmUgYSBwcmV0dHkgY29uc2VydmF0aXZlIGZpbHRlciBvZiB0aGUgbW9zdCBhYnVuZGFudCBjb250YW1pbmFudHMgZm91bmQgYWNyb3NzIG15IHNhbXBsZXMuIApgYGB7YmFzaH0KZmlsdGVyX290dXNfZnJvbV9vdHVfdGFibGUucHkgLWUgVVBBUlNFL0pvaW4vQ29udHJvbENvcmUvY29yZV9vdHVzXzk1LnR4dCAtcyAzIC1uIDEgLWkgVVBBUlNFL0pvaW4vVVBBUlNFX3dfdGF4LmJpb20gIC1vIFVQQVJTRS9Kb2luL1Bvc3RDb250cm9sRmlsdGVyLmJpb20KZmlsdGVyX3NhbXBsZXNfZnJvbV9vdHVfdGFibGUucHkgLS1zYW1wbGVfaWRfZnAgQW5hbHlzaXNNYXAudHh0IC1uIDUwMCAtaSBVUEFSU0UvSm9pbi9Qb3N0Q29udHJvbEZpbHRlci5iaW9tIC1vIFVQQVJTRS9Kb2luL0FuYWx5c2lzLmJpb20KZmlsdGVyX3RheGFfZnJvbV9vdHVfdGFibGUucHkgLW4gRXVrYXJ5b3RhIC1pIFVQQVJTRS9Kb2luL0FuYWx5c2lzLmJpb20gLW8gVVBBUlNFL0FuYWx5c2lzX0JhY0FyYy5iaW9tCgpmaWx0ZXJfc2FtcGxlc19mcm9tX290dV90YWJsZS5weSAtLXNhbXBsZV9pZF9mcCBBbmFseXNpc01hcC50eHQgLW4gNTAwIC1pIFVQQVJTRS9Vbi9VUEFSU0Vfd190YXguYmlvbSAtbyBVUEFSU0UvVW4vQW5hbHlzaXMuYmlvbQpmaWx0ZXJfdGF4YV9mcm9tX290dV90YWJsZS5weSAtcCBFdWthcnlvdGEgLWkgVVBBUlNFL1VuL0FuYWx5c2lzLmJpb20gLW8gVVBBUlNFL0FuYWx5c2lzX0V1ay5iaW9tCmBgYAoKQmVmb3JlIG1vdmluZyBvbiwgSSB3YW50IHRvIGdlbmVyYXRlIHNvbWUgc3VtbWFyaWVzIHRvIHNlZSBob3cgbWFueSBzZXF1ZW5jZXMgSSBoYXZlIGxlZnQgb3ZlcmFsbCwgYW5kIGhvdyBtYW55IFNWcyB3ZXJlIHJldGFpbmVkL3JlbW92ZWQgYWZ0ZXIgZmlsdGVyaW5nLgoKYGBge2Jhc2h9CmJpb20gc3VtbWFyaXplLXRhYmxlIC1pIFVQQVJTRS9Kb2luL1VQQVJTRV93X3RheC5iaW9tIC1vIEpvaW5fYWxsX3dfdGF4X3N1bW1hcnkudHh0CmJpb20gc3VtbWFyaXplLXRhYmxlIC1pIFVQQVJTRS9Kb2luL1Bvc3RDb250cm9sRmlsdGVyLmJpb20gLW8gSm9pbl9Qb3N0Q29udHJvbEZpbHRlcl9zdW1tYXJ5LnR4dApiaW9tIHN1bW1hcml6ZS10YWJsZSAtaSBVUEFSU0UvSm9pbi9BbmFseXNpcy5iaW9tIC1vIEpvaW5fQW5hbHlzaXNfc3VtbWFyeS50eHQKYmlvbSBzdW1tYXJpemUtdGFibGUgLWkgVVBBUlNFL0FuYWx5c2lzX0JhY0FyYy5iaW9tIC1vIEFuYWx5c2lzX0JhY0FyY19zdW1tYXJ5LnR4dAoKYmlvbSBzdW1tYXJpemUtdGFibGUgLWkgVVBBUlNFL1VuL1VQQVJTRV93X3RheC5iaW9tIC1vIFVuX2FsbF93X3RheF9zdW1tYXJ5LnR4dApiaW9tIHN1bW1hcml6ZS10YWJsZSAtaSBVUEFSU0UvVW4vQW5hbHlzaXMuYmlvbSAtbyBVbl9BbmFseXNpc19zdW1tYXJ5LnR4dApiaW9tIHN1bW1hcml6ZS10YWJsZSAtaSBVUEFSU0UvQW5hbHlzaXNfRXVrLmJpb20gLW8gQW5hbHlzaXNfRXVrX3N1bW1hcnkudHh0CmBgYAoKV2hhdCBkb2VzIHRoaXMgbG9vayBsaWtlPyAKClVuZmlsdGVyZWQgQklPTSwgcG9zdCBjbHVzdGVyaW5nOiA2MDEgT1RVcywgNzI0MTU1IFNlcXVlbmNlcwpQb3N0IGNvbnRhbWluYW50IGZpbHRyYXRpb246IDU2OSBPVFVzLCA2MzQ2NDEgU2VxdWVuY2VzIApQb3N0IHJlbW92YWwgb2YgY29udHJvbCBzYW1wbGVzOiA1NjkgT1RVcywgNjE1ODEzIFNlcXVlbmNlcwpFeGNsdWRpbmcgRXVrYXJ5b3RpYyBTZXF1ZW5jZTogNTY2IE9UVXMsIDYxNTUxOCBTZXF1ZW5jZXMKCkNvdW50cy9zYW1wbGUgc3VtbWFyeToKIE1pbjogMTczNS4wCiBNYXg6IDI1MTA1LjAKIE1lZGlhbjogNzk4Ny41MDAKIE1lYW46IDgyMzAuMjEyCiBTdGQuIGRldi46IDM0MTMuMDIwCiAKVW5maWx0ZXJlZCBCSU9NLCBwb3N0IGNsdXN0ZXJpbmc6IDMxNyBPVFVzLCA4MjA2MiBTZXF1ZW5jZXMKUG9zdCByZW1vdmFsIG9mIGNvbnRyb2wgc2FtcGxlczogMzE3IE9UVXMsIDgxMjgxIFNlcXVlbmNlcwpFeGNsdWRpbmcgQmFjdGVyaWFsIGFuZCBBcmNoYWVhbCBTZXF1ZW5jZTogMjY1IE9UVXMsIDc5NDMwIFNlcXVlbmNlcwoKQ291bnRzL3NhbXBsZSBzdW1tYXJ5OgogTWluOiA0ODAuMAogTWF4OiAzMzMzLjAKIE1lZGlhbjogMTMzOC41MDAKIE1lYW46IDE1MjcuNTAwCiBTdGQuIGRldi46IDc0Mi4wMzgKCgpTbywgdGhlIHZhc3QgbWFqb3JpdHkgb2YgbXkgc2VxdWVuY2UgaXMgbm9uLWV1a2FyeXRvaWMuIE90aGVyd2lzZSwgcm91Z2hseSAyMCBwZXJjZW50IG9mIHRoZSBjbHVzdGVyZWQgT1RVcyB3ZXJlIHJlbW92ZWQgZHVyaW5nIGNvbnRhbWluYW50IGZpbHRlcmluZywgYnV0IHRoZSB2YXN0IG1ham9yaXR5ICg+IDkwICUpIG9mIHNlcWV1bmNlIHdhcyByZXRhaW5lZC4gCgpOZXh0LCBJJ2xsIGFkZCBzYW1wbGUgbWV0YWRhdGEgdG8gZWFjaCBmaWxlLCBhbmQgdGhlbiBjb252ZXJ0IG15IHR3byBhbmFseXNpcyBCSU9NIGZpbGVzIHRvIEpTT04gZm9ybWF0IGZvciB1c2UgaW4gUGh5bG9zZXEvUgoKYGBge2Jhc2h9CmJpb20gYWRkLW1ldGFkYXRhIC1pIFVQQVJTRS9BbmFseXNpc19CYWNBcmMuYmlvbSAtbyBVUEFSU0UvQW5hbHlzaXNfQmFjQXJjLndfbWQuYmlvbSAtLXNhbXBsZS1tZXRhZGF0YS1mcCBSX21ldGFkYXRhLnR4dApiaW9tIGNvbnZlcnQgLWkgVVBBUlNFL0FuYWx5c2lzX0JhY0FyYy53X21kLmJpb20gLW8gVVBBUlNFL0JhY0FyYy53X21kLmpzb24uYmlvbSAtLXRhYmxlLXR5cGU9Ik9UVSB0YWJsZSIgLS10by1qc29uCgpiaW9tIGFkZC1tZXRhZGF0YSAtaSBVUEFSU0UvQW5hbHlzaXNfRXVrLmJpb20gLW8gVVBBUlNFL0FuYWx5c2lzX0V1ay53X21kLmJpb20gLS1zYW1wbGUtbWV0YWRhdGEtZnAgUl9tZXRhZGF0YS50eHQKYmlvbSBjb252ZXJ0IC1pIFVQQVJTRS9BbmFseXNpc19FdWsud19tZC5iaW9tIC1vIFVQQVJTRS9FdWsud19tZC5qc29uLmJpb20gLS10YWJsZS10eXBlPSJPVFUgdGFibGUiIC0tdG8tanNvbgpgYGAKClRyZWUgQnVpbGRpbmcgYW5kIEZpbmFsIEJJT00gRmlsZSBHZW5lcmF0aW9uCj09PT09CgpMYXN0IHN0ZXAgYmVmb3JlIG1vdmluZyBpbnRvIFIuIEdlbmVyYXRpb24gb2YgcGh5bG9nZW5ldGljIHRyZWVzIGZvciB1c2UgaW4gUGh5bG9zZXEsIGFzIG5lZWRlZC4gCgpgYGB7YmFzaH0KZmlsdGVyX2Zhc3RhLnB5IC1iIFVQQVJTRS9BbmFseXNpc19CYWNBcmMuYmlvbSAtZiBVUEFSU0UvSm9pbi9SZXBTZXQuZm5hIC1vIFVQQVJTRS9BbmFseXNpc19CYWNBcmMuc2Vxcy5mYSAKCmZpbHRlcl9mYXN0YS5weSAtYiBVUEFSU0UvQW5hbHlzaXNfRXVrLmJpb20gLWYgVVBBUlNFL1VuL1JlcFNldC5mbmEgLW8gVVBBUlNFL0FuYWx5c2lzX0V1ay5zZXFzLmZhCmBgYAoKYGBge2Jhc2h9CmFsaWduX3NlcXMucHkgLWkgVVBBUlNFL0FuYWx5c2lzX0JhY0FyYy5zZXFzLmZhIC10IC9tZWRpYS9hbmFseXNlcy9EQi9TSUxWQV8xMjhfUUlJTUVfcmVsZWFzZS9yZXBfc2V0X2FsaWduZWQvOTcvOTdfb3R1c19hbGlnbmVkLmZhc3RhIC1vIFVQQVJTRS9BbmFseXNpc19CYWNBcmNfUmVwU2V0X0FsaWduZWQvCmFsaWduX3NlcXMucHkgLWkgVVBBUlNFL0FuYWx5c2lzX0V1ay5zZXFzLmZhICAtdCAvbWVkaWEvYW5hbHlzZXMvREIvU0lMVkFfMTI4X1FJSU1FX3JlbGVhc2UvcmVwX3NldF9hbGlnbmVkLzk3Lzk3X290dXNfYWxpZ25lZC5mYXN0YSAtbyBVUEFSU0UvQW5hbHlzaXNfRXVrX1JlcFNldF9BbGlnbmVkLwoKZmlsdGVyX2FsaWdubWVudC5weSAtaSBVUEFSU0UvQW5hbHlzaXNfQmFjQXJjX1JlcFNldF9BbGlnbmVkL0FuYWx5c2lzX0JhY0FyYy5zZXFzX2FsaWduZWQuZmFzdGEgLW8gVVBBUlNFL0FuYWx5c2lzX0JhY0FyY19SZXBTZXRfQWxpZ25lZC8gLWUgMC4wMDEKZmlsdGVyX2FsaWdubWVudC5weSAtaSBVUEFSU0UvQW5hbHlzaXNfRXVrX1JlcFNldF9BbGlnbmVkL0FuYWx5c2lzX0V1ay5zZXFzX2FsaWduZWQuZmFzdGEgLW8gVVBBUlNFL0FuYWx5c2lzX0V1a19SZXBTZXRfQWxpZ25lZC8gLWUgMC4wMDEKCm1ha2VfcGh5bG9nZW55LnB5IC1pIFVQQVJTRS9BbmFseXNpc19CYWNBcmNfUmVwU2V0X0FsaWduZWQvQW5hbHlzaXNfQmFjQXJjLnNlcXNfYWxpZ25lZF9wZmlsdGVyZWQuZmFzdGEgLW8gVVBBUlNFL0JhY0FyYy50cmUKbWFrZV9waHlsb2dlbnkucHkgLWkgVVBBUlNFL0FuYWx5c2lzX0V1a19SZXBTZXRfQWxpZ25lZC9BbmFseXNpc19FdWsuc2Vxc19hbGlnbmVkX3BmaWx0ZXJlZC5mYXN0YSAtbyBVUEFSU0UvRXVrLnRyZQpgYGAKCkFuYWx5c2lzIGluIFIKCj09PT09CgpPbnRvIFIuIFRoaXMgY2FuIGJlIHJ1biBvbiAoYWxtb3N0KSBhbnkgZGVza3RvcC9sYXB0b3Agd2l0aG91dCBpc3N1ZS4gSW4gbXkgY2FzZSwgSSBkb3dubG9hZGVkIHRoZSBhYm92ZSBvdXRwdXQgZmlsZXMgKC5iaW9tLCAudHJlLiBhbmQgLmZhKSBmcm9tIG15IHdvcmtzdGF0aW9uIG9udG8gbXkgbGFwdG9wIHRvIHJ1biB0aGUgYmVsb3cuIAoKTG9hZCBOZWVkZWQgTGlicmFyaWVzCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHBoeWxvc2VxKQpsaWJyYXJ5KGFtcHZpcykKbGlicmFyeShjb3dwbG90KQpgYGAKCkZpcnN0LCBJJ20gZ29pbmcgdG8gaW1wb3J0IHRoZSBteSBCSU9NIGZpbGVzLCBhbmQgZm9ybWF0IHRoZSB0YXhvbm9teSBzdHJpbmcgdG8gYmVoYXZlIHdpdGggUGh5bG9zZXEgYW5kIEFtcFZpcy4KCmBgYHtyfQpNTC5CYWNBcmMgPC0gaW1wb3J0X2Jpb20oIkJhY0FyYy53X21kLmpzb24uYmlvbSIsICJCYWNBcmMudHJlIiwgIkFuYWx5c2lzX0JhY0FyYy5zZXFzLmZhIiwgcGFyc2VGdW5jdGlvbj1wYXJzZV90YXhvbm9teV9kZWZhdWx0KQpNTC5FdWsgPC0gaW1wb3J0X2Jpb20oIkV1ay53X21kLmpzb24uYmlvbSIsICJFdWsudHJlIiwgIkFuYWx5c2lzX0V1ay5zZXFzLmZhIiwgcGFyc2VGdW5jdGlvbj1wYXJzZV90YXhvbm9teV9kZWZhdWx0KQoKY29sbmFtZXModGF4X3RhYmxlKE1MLkJhY0FyYykpID0gYygiS2luZ2RvbSIsICJQaHlsdW0iLCAiQ2xhc3MiLCAiT3JkZXIiLCAiRmFtaWx5IiwgIkdlbnVzIikKY29sbmFtZXModGF4X3RhYmxlKE1MLkV1aykpID0gYygiS2luZ2RvbSIsICJQaHlsdW0iLCAiQ2xhc3MiLCAiT3JkZXIiLCAiRmFtaWx5IiwgIkdlbnVzIikKYGBgCgpOZXh0LCBJJ2xsIHN1YnNldCBteSBQaHlsb3NlcSBvYmplY3RzIHRvIGV4Y2x1ZGUgaW5jdWJhdGlvbiBzYW1wbGVzLiBZb3UgY2FuIHNlZSB0aGUgcmVzdWx0cyBvZiB0aGUgaW5jdWJhdGlvbnMgaW4gc3VwcGxlbWVudGFyeSBkYXRhLgpgYGB7cn0KTUwud0NobG9yb3BsYXN0LkJhY0FyYyA8LSBzdWJzZXRfc2FtcGxlcyhNTC5CYWNBcmMsIFNhbXBsZU5hbWUgJWluJSBjKCJNb25vTGFrZS5TdXJmYWNlV2F0ZXIiLCAiTW9ub0xha2UuMm0iLCAiTW9ub0xha2UuMTBtIiwgIk1vbm9MYWtlLjIwbSIsIk1vbm9MYWtlLjI1bSIsICJNb25vTGFrZS5TZWQuMTBtIiwgIlRvbXNXZWxsLldhdGVyIiwgIkxlZVZpbmluZ0NyZWVrLlJpdmVyV2F0ZXIiLCAiTWlsbENyZWVrLlJpdmVyV2F0ZXIiLCAiUnVzaENyZWVrLlJpdmVyV2F0ZXIiLCAiV2lsc29uQ3JlZWsuUml2ZXJXYXRlciIpKQoKTUwuUkEud0NobG9yb3BsYXN0LkJhY0FyYyA8LSB0cmFuc2Zvcm1fc2FtcGxlX2NvdW50cyhNTC53Q2hsb3JvcGxhc3QuQmFjQXJjLCBmdW5jdGlvbih4KSB4IC8gc3VtKHgpICogMTAwKQpgYGAKCkFzIGEgc21hbGwgc3RlcCwgY2hsb3JvcGxhc3QgYW5kIG1pdG9jaG9uZGlhbCBzZXF1ZW5jZSBuZWVkIHRvIGJlIHJlbW92ZWQgZnJvbSB0aGUgQmFjdGVyaWFsL0FyY2hhZWFsIHBoeWxvc2VxIG9iamVjdC0gd2UnbGwgc2VlIHRoZW0gaW4gdGhlIEV1a2FyeW90aWMgZGF0YXNldCAoT3IgYXQgbGVhc3QgdGhlIG93bmVycyBvZiB0aG9zZSBtaXRvY2hvbmRyaWEgYW5kIGNobG9yb3BsYXN0Li4uKQoKYGBge3J9Ck1MLkJhY0FyYy5GaWx0ZXIgPC0gTUwuQmFjQXJjICU+JQogICAgc3Vic2V0X3RheGEoCiAgICAgICAgICAgIEZhbWlseSAgIT0gIk1pdG9jaG9uZHJpYSIgJgogICAgICAgICAgICBDbGFzcyAgICE9ICJDaGxvcm9wbGFzdCIpCmBgYAoKSSdtIGdvaW5nIHRvIGNvbnZlcnQgdG8gcmVsYXRpdmUgYWJ1bmRhbmNlcyBmb3Igc29tZSBjaGFydCB0eXBlcy4gUkEgc3RhbmRpbmcgZm9yICJSZWxhdGl2ZSBBYnVuZGFuY2UiCmBgYHtyfQpNTC5SQS5CYWNBcmMgPC0gdHJhbnNmb3JtX3NhbXBsZV9jb3VudHMoTUwuQmFjQXJjLkZpbHRlciwgZnVuY3Rpb24oeCkgeCAvIHN1bSh4KSAqIDEwMCkKTUwuUkEuRXVrIDwtIHRyYW5zZm9ybV9zYW1wbGVfY291bnRzKE1MLkV1aywgZnVuY3Rpb24oeCkgeCAvIHN1bSh4KSAqIDEwMCkKYGBgCgpOZXh0LCBJJ20gZ29pbmcgdG8gcmFyZWZ5IHRoZSB0YWJsZSBmb3IgbGF0ZXIgdXNlLiBJIHNldCB0aGUgcmFyZWZhY3Rpb24gZGVwdGggdG8gaW5jbHVkZSBhbGwgc2FtcGxlcy4gCgpgYGB7cn0KTUwuUmFyZS5CYWNBcmMgPC0gcmFyZWZ5X2V2ZW5fZGVwdGgoTUwuQmFjQXJjLkZpbHRlciwgc2FtcGxlLnNpemUgPSAxNTAwLCBybmdzZWVkID0gNzEyKQpNTC5SYXJlLkV1ayA8LSByYXJlZnlfZXZlbl9kZXB0aChNTC5FdWssIHNhbXBsZS5zaXplID0gNDAwLCBybmdzZWVkID0gNzEyKQpgYGAKSSBuZWVkIHRvIHN1YnNldCB0aGUgcHJpbWFyeSB0YWJsZSB0byByZW1vdmUgdGhlIGluY3ViYXRpb25zIGJlZm9yZSBwcm9jZWVkaW5nLiBBbHNvLCBJJ2xsIGdvIGFoZWFkIGFuZCBtYWtlIGEgaGVhdG1hcCBmb3IgdGhlIGluY3ViYXRpb25zLCBhbmQgc2hvdyB0aGF0IHRoZXJlIHdhcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGJldHdlZW4gdHJlYXRtZW50cy4gCgpgYGB7cn0KTUwuUkEuV2F0ZXJPbmx5IDwtIHN1YnNldF9zYW1wbGVzKE1MLlJBLkJhY0FyYywgU2FtcGxlTmFtZSAlaW4lIGMoIk1vbm9MYWtlLlN1cmZhY2VXYXRlciIsICJNb25vTGFrZS4ybSIsICJNb25vTGFrZS4xMG0iLCAiTW9ub0xha2UuMjBtIiwiTW9ub0xha2UuMjVtIikpCgpNTC5BbmQuUml2ZXJzLkJBLlJBIDwtIHN1YnNldF9zYW1wbGVzKE1MLlJBLkJhY0FyYywgU2FtcGxlTmFtZSAlaW4lIGMoIk1vbm9MYWtlLlN1cmZhY2VXYXRlciIsICJNb25vTGFrZS4ybSIsICJNb25vTGFrZS4xMG0iLCAiTW9ub0xha2UuMjBtIiwiTW9ub0xha2UuMjVtIiwgIk1vbm9MYWtlLlNlZC4xMG0iLCAiVG9tc1dlbGwuV2F0ZXIiLCAiTGVlVmluaW5nQ3JlZWsuUml2ZXJXYXRlciIsICJNaWxsQ3JlZWsuUml2ZXJXYXRlciIsICJSdXNoQ3JlZWsuUml2ZXJXYXRlciIsICJXaWxzb25DcmVlay5SaXZlcldhdGVyIikpCgpNTC5BbmQuUml2ZXJzLkV1ay5SQSA8LSBzdWJzZXRfc2FtcGxlcyhNTC5SQS5FdWssIFNhbXBsZU5hbWUgJWluJSBjKCJNb25vTGFrZS5TdXJmYWNlV2F0ZXIiLCAiTW9ub0xha2UuMm0iLCAiTW9ub0xha2UuMTBtIiwgIk1vbm9MYWtlLjIwbSIsIk1vbm9MYWtlLjI1bSIsICJNb25vTGFrZS5TZWQuMTBtIiwgIlRvbXNXZWxsLldhdGVyIiwgIkxlZVZpbmluZ0NyZWVrLlJpdmVyV2F0ZXIiLCAiTWlsbENyZWVrLlJpdmVyV2F0ZXIiLCAiUnVzaENyZWVrLlJpdmVyV2F0ZXIiLCAiV2lsc29uQ3JlZWsuUml2ZXJXYXRlciIpKQpgYGAKCkknbSBnb2luZyB0byBkZWZpbmUgYSBjb2xvciBzZXQgdG8gdXNlIHRocm91Z2hvdXQgdGhlIHNjcmlwdC4KCmBgYHtyfQpNTC5jb2xzIDwtIGMoIk1vbm9MYWtlLjJtIiA9ICJibHVlIiwgIk1vbm9MYWtlLjEwbSIgPSAiZGFya2JsdWUiLCAiTW9ub0xha2UuMjBtIiA9ICJyZWQiLCAiTW9ub0xha2UuMjVtIiA9ICJPcmFuZ2UiKQpgYGAKCkZpcnN0IHVwLCBmaWd1cmUgMy0gYSBoZWF0bWFwIG9mIHRoZSB0b3AgMjUgdGF4YSBvZiBlaXRoZXIgdGhlIEJhY3RlcmlhIGFuZCBBcmNoYWVhIChBKSwgb3IgdGhlIEV1a2FyeWEgKEIpIGFjcm9zcyB0aGUgc2FtcGxlZCBkZXB0aCB0cmFuc2VjdCBhdCBNb25vLCBvciB0aGUgbmVhcmJ5IHN0cmVhbXMgYW5kIHdlbGwuCmBgYHtyLCAgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9NX0KSGVhdG1hcC5CQTwtIGFtcF9oZWF0bWFwKGRhdGEgPSBNTC5BbmQuUml2ZXJzLkJBLlJBLAogICAgICAgICAgICB0YXguYWdncmVnYXRlID0gIkdlbnVzIiwKICAgICAgICAgICB0YXguYWRkID0gIlBoeWx1bSIsCiAgICAgICAgICAgIGdyb3VwID0gYygiU2FtcGxlTmFtZSIpLAogICAgICAgICAgICB0YXguc2hvdyA9IDI1LAogICAgICAgICAgICB0YXguZW1wdHkgPSAicmVtb3ZlIiwKICAgICAgICAgICAgcGxvdC5udW1iZXJzID0gRiwKICAgICAgICAgICAgcGxvdC5icmVha3MgPSBjKDEuMCwxMC4wLDUwLjApLAogICAgICAgICAgICBtYXguYWJ1bmRhbmNlID0gNTAsCiAgICAgICAgICAgIG1pbi5hYnVuZGFuY2UgPSAxLAogICAgICAgICAgICBvcmRlci54ID0gYygiTW9ub0xha2UuU3VyZmFjZVdhdGVyIiwgIk1vbm9MYWtlLjJtIiwgIk1vbm9MYWtlLjEwbSIsICJNb25vTGFrZS4yMG0iLCJNb25vTGFrZS4yNW0iLCAiTW9ub0xha2UuU2VkLjEwbSIsICJUb21zV2VsbC5XYXRlciIsICJMZWVWaW5pbmdDcmVlay5SaXZlcldhdGVyIiwgIk1pbGxDcmVlay5SaXZlcldhdGVyIiwgIlJ1c2hDcmVlay5SaXZlcldhdGVyIiwgIldpbHNvbkNyZWVrLlJpdmVyV2F0ZXIiKSwKICAgICAgICAgICAgc2NhbGUuc2VxID0gMTAwKSArIAogICAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKCJNb25vXG5TdXJmYWNlIiwiTW9ub1xuMiBtIiwiTW9ub1xuMTAgbSIsIk1vbm9cbjIwIG0iLCJNb25vXG4yNSBtIiwiU2VkLlxuMTBtIiwiV2VsbFxuV2F0ZXIiLCAiTGVlIFxuVmluaW5nIiwgIk1pbGwiLCAiUnVzaCIsICJXaWxzb24iKSkgKwogICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID04LCBjb2xvciA9ICJibGFjayIsIGhqdXN0ID0gMC40LCBhbmdsZSA9IDAsIGZhbWlseT0iVGltZXMgTmV3IFJvbWFuIiwgZmFjZT0iYm9sZCIpKSArIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPTgsIGNvbG9yID0gImJsYWNrIiwgYW5nbGUgPSAwLCBmYW1pbHk9IlRpbWVzIE5ldyBSb21hbiIsIGZhY2U9ImJvbGQiKSkKCkhlYXRtYXAuRTwtYW1wX2hlYXRtYXAoZGF0YSA9IE1MLkFuZC5SaXZlcnMuRXVrLlJBLAogICAgICAgICAgICB0YXguYWdncmVnYXRlID0gIkdlbnVzIiwKICAgICAgICAgICAgdGF4LmFkZCA9ICJDbGFzcyIsCiAgICAgICAgICAgIGdyb3VwID0gYygiU2FtcGxlTmFtZSIpLAogICAgICAgICAgICB0YXguc2hvdyA9IDI1LAogICAgICAgICAgICB0YXguZW1wdHkgPSAicmVtb3ZlIiwKICAgICAgICAgICAgcGxvdC5udW1iZXJzID0gRiwKICAgICAgICAgICAgcGxvdC5icmVha3MgPSBjKDEuMCwxMC4wLDUwLjApLAogICAgICAgICAgICBtYXguYWJ1bmRhbmNlID0gNTAsCiAgICAgICAgICAgIG1pbi5hYnVuZGFuY2UgPSAxLAogICAgICAgICAgICBvcmRlci54ID0gYygiTW9ub0xha2UuU3VyZmFjZVdhdGVyIiwgIk1vbm9MYWtlLjJtIiwgIk1vbm9MYWtlLjEwbSIsICJNb25vTGFrZS4yMG0iLCJNb25vTGFrZS4yNW0iLCAiTW9ub0xha2UuU2VkLjEwbSIsICJUb21zV2VsbC5XYXRlciIsICJMZWVWaW5pbmdDcmVlay5SaXZlcldhdGVyIiwgIk1pbGxDcmVlay5SaXZlcldhdGVyIiwgIlJ1c2hDcmVlay5SaXZlcldhdGVyIiwgIldpbHNvbkNyZWVrLlJpdmVyV2F0ZXIiKSwKICAgICAgICAgICAgc2NhbGUuc2VxID0gMTAwKSArIAogICAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKCJNb25vXG5TdXJmYWNlIiwiTW9ub1xuMiBtIiwiTW9ub1xuMTAgbSIsIk1vbm9cbjIwIG0iLCJNb25vXG4yNSBtIiwiU2VkLlxuMTBtIiwiV2VsbFxuV2F0ZXIiLCAiTGVlIFxuVmluaW5nIiwgIk1pbGwiLCAiUnVzaCIsICJXaWxzb24iKSkgKwogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9OCwgY29sb3IgPSAiYmxhY2siLCBoanVzdCA9IDAuNCwgYW5nbGUgPSAwLCBmYW1pbHk9IlRpbWVzIE5ldyBSb21hbiIsIGZhY2U9ImJvbGQiKSkgKyB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID04LCBjb2xvciA9ICJibGFjayIsIGFuZ2xlID0gMCwgZmFtaWx5PSJUaW1lcyBOZXcgUm9tYW4iLCBmYWNlPSJib2xkIikpCgpwbG90X2dyaWQoSGVhdG1hcC5CQSxIZWF0bWFwLkUsIGxhYmVscyA9IGMoIkEiLCAiQiIpLCByZWxfd2lkdGhzID0gYygxLDEpLG5yb3cgPSAyLCBhbGlnbiA9ICJ2IikKYGBgCgpOb3csIGZpZ3VyZSA0LiBBZ2FpbiwgSSdsbCBzdWJzZXQgbXkgZGF0YXNldCB0byBub3cgb25seSBpbmNsdWRlIHdhdGVyIHNhbXBsZXMgZnJvbSAyIHRvIDI1IG0gZGVwdGguIAoKYGBge3J9Ck1MLkJBLlJhcmUuVHJhbnNlY3QgPC0gc3Vic2V0X3NhbXBsZXMoTUwuUmFyZS5CYWNBcmMsIFNhbXBsZU5hbWUgJWluJSBjKCJNb25vTGFrZS4ybSIsICJNb25vTGFrZS4xMG0iLCAiTW9ub0xha2UuMjBtIiwiTW9ub0xha2UuMjVtIikpCk1MLkV1ay5SYXJlLlRyYW5zZWN0IDwtIHN1YnNldF9zYW1wbGVzKE1MLlJhcmUuRXVrLCBTYW1wbGVOYW1lICVpbiUgYygiTW9ub0xha2UuMm0iLCAiTW9ub0xha2UuMTBtIiwgIk1vbm9MYWtlLjIwbSIsIk1vbm9MYWtlLjI1bSIpKQpgYGAKCkZpZ3VyZSA0IEEpIEJhY3RlcmlhL0FyY2hhZWEsIGFuZCBCKSBFdWthcnlhCmBgYHtyLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD01fQpNTC5CQS5QQ0EgPC0gb3JkaW5hdGUoTUwuQkEuUmFyZS5UcmFuc2VjdCwgbWV0aG9kID0gIlBDb0EiLCBkaXN0YW5jZSA9ICJ3dW5pZnJhYyIpCk1MLkJBLlBDQSA8LSBwbG90X29yZGluYXRpb24oTUwuQkEuUmFyZS5UcmFuc2VjdCwgTUwuQkEuUENBLCBjb2xvcj0iU2FtcGxlTmFtZSIpClRyYW5zZWN0LlBDQS5CQTwtTUwuQkEuUENBICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBNTC5jb2xzKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IE1MLmNvbHMpICsgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKQoKTUwuRXVrLlBDQSA8LSBvcmRpbmF0ZShNTC5FdWsuUmFyZS5UcmFuc2VjdCwgbWV0aG9kID0gIlBDb0EiLCBkaXN0YW5jZSA9ICJ3dW5pZnJhYyIpCk1MLkV1ay5QQ0EgPC0gcGxvdF9vcmRpbmF0aW9uKE1MLkV1ay5SYXJlLlRyYW5zZWN0LCBNTC5FdWsuUENBLCBjb2xvcj0iU2FtcGxlTmFtZSIpClRyYW5zZWN0LlBDQS5FPC0gTUwuRXVrLlBDQSArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gTUwuY29scykgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBNTC5jb2xzKSArIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkKCnBsb3RfZ3JpZChUcmFuc2VjdC5QQ0EuQkEsVHJhbnNlY3QuUENBLkUsIGxhYmVscyA9IGMoIkEiLCAiQiIpLCByZWxfd2lkdGhzID0gYygxLDEpLG5yb3cgPSAyLCBhbGlnbiA9ICJ2IikKYGBgCgpPSywgc28gYSBjbGVhciBzZXBhcmF0aW9uIGJldHdlZW4gdGhlIGRlZXAgKFJlZC9PcmFuZ2UpIHNhbXBsZXMgYW5kIHRoZSBtb3JlIHNoYWxsb3cgKEJsdWUpIHNhbXBsZXMuIFdlJ2xsIGNvbmZpcm0gYnkgQURPTklTIGluIGEgbGl0dGxlIGJpdC4gCgpgYGB7cn0KTUwuQkEuUmFyZS5EYXRhID0gYXMoc2FtcGxlX2RhdGEoTUwuQkEuUmFyZS5UcmFuc2VjdCksICJkYXRhLmZyYW1lIikKQkEuZCA9IHBoeWxvc2VxOjpkaXN0YW5jZShNTC5CQS5SYXJlLlRyYW5zZWN0LCAid3VuaWZyYWMiKQpNTC5FdWsuUmFyZS5EYXRhID0gYXMoc2FtcGxlX2RhdGEoTUwuRXVrLlJhcmUuVHJhbnNlY3QpLCAiZGF0YS5mcmFtZSIpCkV1ay5kID0gcGh5bG9zZXE6OmRpc3RhbmNlKE1MLkV1ay5SYXJlLlRyYW5zZWN0LCAid3VuaWZyYWMiKQoKYGBgYAoKCmBgYHtyfQphZG9uaXMoQkEuZCB+IFNhbXBsZU5hbWUsIE1MLkJBLlJhcmUuRGF0YSkKYGBgCk92ZXJhbGwsIGhpZ2hseSBzaWduaWZpY2FudCB3aXRoIHZlcnkgaGlnaCAoPiAwLjkwKSBSMiB2YWx1ZS4KYGBge3J9CmFkb25pcyhFdWsuZCB+IFNhbXBsZU5hbWUsIE1MLkV1ay5SYXJlLkRhdGEpCmBgYAoKVGhlIEV1a2FyeWEgcHJvZHVjZSBhIHNpZ25pZmljYW50LCBidXQgbXVjaCB3ZWFrZXIgZGlmZmVyZW5jZSBiZXR3ZWVuIGRlcHRocy4gVGhpcyBpcyBsaWtlbHkgZHJpdmVuIGJ5IHRoZSBoaWdoIHJlbGF0aXZlIGFidW5kYW5jZSBvZiBhbiBPVFUgbW9zdCBjbG9zZWx5IHJlbGF0ZWQgdG8gUGljb2N5c3RpcyBzcC4KCi0tLS0tLVNVUFBMRU1FTlRBTC0tLS0tLQoKTGV0J3Mgc2VlIHdoYXQgdGhlIHNhbXBsZXMgbG9vayBsaWtlIHdpdGggY2hsb3JvcGxhc3QgaW5jbHVkZWQKYGBge3IsICBmaWcuaGVpZ2h0PTMsIGZpZy53aWR0aD01fQphbXBfaGVhdG1hcChkYXRhID0gTUwuUkEud0NobG9yb3BsYXN0LkJhY0FyYywKICAgICAgICAgICAgdGF4LmFnZ3JlZ2F0ZSA9ICJHZW51cyIsCiAgICAgICAgICAgIHRheC5hZGQgPSAiQ2xhc3MiLAogICAgICAgICAgICBncm91cCA9IGMoIlNhbXBsZU5hbWUiKSwKICAgICAgICAgICAgdGF4LnNob3cgPSAyNSwKICAgICAgICAgICAgdGF4LmVtcHR5ID0gInJlbW92ZSIsCiAgICAgICAgICAgIHBsb3QubnVtYmVycyA9IFQsCiAgICAgICAgICAgIHBsb3QuYnJlYWtzID0gYygxLjAsMTAuMCw1MC4wKSwKICAgICAgICAgICAgbWF4LmFidW5kYW5jZSA9IDUwLAogICAgICAgICAgICBtaW4uYWJ1bmRhbmNlID0gMSwKICAgICAgICAgICAgb3JkZXIueCA9IGMoIk1vbm9MYWtlLlN1cmZhY2VXYXRlciIsICJNb25vTGFrZS4ybSIsICJNb25vTGFrZS4xMG0iLCAiTW9ub0xha2UuMjBtIiwiTW9ub0xha2UuMjVtIiwgIk1vbm9MYWtlLlNlZC4xMG0iLCAiVG9tc1dlbGwuV2F0ZXIiLCAiTGVlVmluaW5nQ3JlZWsuUml2ZXJXYXRlciIsICJNaWxsQ3JlZWsuUml2ZXJXYXRlciIsICJSdXNoQ3JlZWsuUml2ZXJXYXRlciIsICJXaWxzb25DcmVlay5SaXZlcldhdGVyIiksCiAgICAgICAgICAgIHNjYWxlLnNlcSA9IDEwMCkgKyAKICAgIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYygiTW9ub1xuU3VyZmFjZSIsIk1vbm9cbjIgbSIsIk1vbm9cbjEwIG0iLCJNb25vXG4yMCBtIiwiTW9ub1xuMjUgbSIsIlNlZC5cbjEwbSIsIldlbGxcbldhdGVyIiwgIkxlZSBcblZpbmluZyIsICJNaWxsIiwgIlJ1c2giLCAiV2lsc29uIikpICsKICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPTgsIGNvbG9yID0gImJsYWNrIiwgaGp1c3QgPSAwLjQsIGFuZ2xlID0gMCwgZmFtaWx5PSJUaW1lcyBOZXcgUm9tYW4iLCBmYWNlPSJib2xkIikpICsgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9OCwgY29sb3IgPSAiYmxhY2siLCBhbmdsZSA9IDAsIGZhbWlseT0iVGltZXMgTmV3IFJvbWFuIiwgZmFjZT0iYm9sZCIpKQpgYGAKCgpgYGB7cn0KTUwuQkEuUkEuSW5jdWJhdGlvbiA8LSBzdWJzZXRfc2FtcGxlcyhNTC5SQS5CYWNBcmMsIFNhbXBsZU5hbWUgJWluJSBjKCJNTC4uQ0MuWmVybyIsICJNTC5DQy5NZU9IIiwgIk1MLkNDLkIiLCAiTUwuQ0MuTkg0IiwgIk1MLkNDLk5vIiwgIk1MLkNDLkciLCAiTW9ub0xha2UuMm0iKSkKTUwuRXVrLlJBLkluY3ViYXRpb24gPC0gc3Vic2V0X3NhbXBsZXMoTUwuUkEuRXVrLCBTYW1wbGVOYW1lICVpbiUgYygiTUwuLkNDLlplcm8iLCAiTUwuQ0MuTWVPSCIsICJNTC5DQy5CIiwgIk1MLkNDLk5INCIsICJNTC5DQy5ObyIsICJNTC5DQy5HIiwgIk1vbm9MYWtlLjJtIikpCk1MLkJBLlJhcmUuSW5jdWJhdGlvbiA8LSBzdWJzZXRfc2FtcGxlcyhNTC5SYXJlLkJhY0FyYywgU2FtcGxlTmFtZSAlaW4lIGMoIk1MLi5DQy5aZXJvIiwgIk1MLkNDLk1lT0giLCAiTUwuQ0MuQiIsICJNTC5DQy5OSDQiLCAiTUwuQ0MuTm8iLCAiTUwuQ0MuRyIsICJNb25vTGFrZS4ybSIpKQpNTC5FdWsuUmFyZS5JbmN1YmF0aW9uIDwtIHN1YnNldF9zYW1wbGVzKE1MLlJhcmUuRXVrLCBTYW1wbGVOYW1lICVpbiUgYygiTUwuLkNDLlplcm8iLCAiTUwuQ0MuTWVPSCIsICJNTC5DQy5CIiwgIk1MLkNDLk5INCIsICJNTC5DQy5ObyIsICJNTC5DQy5HIiwgIk1vbm9MYWtlLjJtIikpCmBgYAoKYGBge3J9CmluYy5jb2xzIDwtIGMoIk1MLi5DQy5aZXJvIiA9ICJncmV5MSIsICJNTC5DQy5NZU9IIiA9ICJyZWQiLCAiTUwuQ0MuQiIgPSAicmVkMSIsICJNTC5DQy5OSDQiID0gIm9yYW5nZSIsICJNTC5DQy5ObyIgPSAiYmxhY2siLCAiTUwuQ0MuRyIgPSAiYmx1ZTIiLCAiTW9ub0xha2UuMm0iID0gInB1cnBsZSIpCmBgYAoKCkZpcnN0IEknZCBsaWtlIHRvIGxvb2sgYXQgYW55IGRpZmZlcmVuY2VzIGNhdXNlZCBieSBvdXIgaW5jdWJhdGlvbnMuIApgYGB7ciwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9NX0KUmFidW5kLkJBPC1hbXBfcmFidW5kKGRhdGEgPSBNTC5CQS5SQS5JbmN1YmF0aW9uLAogICAgICAgICAgICB0YXguYWdncmVnYXRlID0gIkdlbnVzIiwKICAgICAgICAgICAgdGF4LmFkZCA9ICJDbGFzcyIsCiAgICAgICAgICAgIGdyb3VwID0gYygiU2FtcGxlTmFtZSIpLAogICAgICAgICAgICB0YXguc2hvdyA9IDE1LAogICAgICAgICAgICB0YXguZW1wdHkgPSAicmVtb3ZlIikgKyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGluYy5jb2xzKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGluYy5jb2xzKQoKUmFidW5kLkU8LSBhbXBfcmFidW5kKGRhdGEgPSBNTC5FdWsuUkEuSW5jdWJhdGlvbiwKICAgICAgICAgICAgdGF4LmFnZ3JlZ2F0ZSA9ICJHZW51cyIsCiAgICAgICAgICAgIHRheC5hZGQgPSAiQ2xhc3MiLAogICAgICAgICAgICBncm91cCA9IGMoIlNhbXBsZU5hbWUiKSwKICAgICAgICAgICAgdGF4LnNob3cgPSA1LAogICAgICAgICAgICB0YXguZW1wdHkgPSAicmVtb3ZlIikgKyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGluYy5jb2xzKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGluYy5jb2xzKQogICAgICAgICAgIAoKcGxvdF9ncmlkKFJhYnVuZC5CQSxSYWJ1bmQuRSwgbGFiZWxzID0gYygiQSIsICJCIiksIHJlbF93aWR0aHMgPSBjKDEsMSksbnJvdyA9IDIsIGFsaWduID0gInYiKQpgYGAKCgoKYGBge3J9Ck1MLkJBLlJhcmUuSW5jdWJhdGlvbi5EYXRhID0gYXMoc2FtcGxlX2RhdGEoTUwuQkEuUmFyZS5JbmN1YmF0aW9uKSwgImRhdGEuZnJhbWUiKQpJbmN1YmF0aW9uLkJBLmQgPSBwaHlsb3NlcTo6ZGlzdGFuY2UoTUwuQkEuUmFyZS5JbmN1YmF0aW9uLCAid3VuaWZyYWMiKQphZG9uaXMoSW5jdWJhdGlvbi5CQS5kIH4gU2FtcGxlTmFtZSwgTUwuQkEuUmFyZS5JbmN1YmF0aW9uLkRhdGEpCmBgYAoKCmBgYHtyfQpJbmN1YmF0aW9uLkV1ay5SYXJlLkRhdGEgPSBhcyhzYW1wbGVfZGF0YShNTC5FdWsuUmFyZS5JbmN1YmF0aW9uKSwgImRhdGEuZnJhbWUiKQpJbmN1YmF0aW9uLkV1ay5kID0gcGh5bG9zZXE6OmRpc3RhbmNlKE1MLkV1ay5SYXJlLkluY3ViYXRpb24sICJ3dW5pZnJhYyIpCmFkb25pcyhJbmN1YmF0aW9uLkV1ay5kIH4gU2FtcGxlTmFtZSwgSW5jdWJhdGlvbi5FdWsuUmFyZS5EYXRhKQpgYGAKCgpgYGB7cn0KSW5jdWJhdGlvbi5CQS5SYXJlLkRhdGEgPSBhcyhzYW1wbGVfZGF0YShNTC5CQS5SYXJlLkluY3ViYXRpb24pLCAiZGF0YS5mcmFtZSIpCkluY3ViYXRpb24uQkEuZCA9IHBoeWxvc2VxOjpkaXN0YW5jZShNTC5CQS5SYXJlLkluY3ViYXRpb24sICJ3dW5pZnJhYyIpCmFkb25pcyhJbmN1YmF0aW9uLkJBLmQgfiBTYW1wbGVOYW1lLCBJbmN1YmF0aW9uLkJBLlJhcmUuRGF0YSkKYGBgCgpOb25zaWduaWZpY2FudC0gbm90IHRvdGFsbHkgc3VwcmlzaW5nLCBidXQgd2UgbmVlZCB0byBjb25maXJtIHRoaXMuIE1vdmluZyBvbnRvIHRoZSBwcmltYXJ5IGRhdGEgaW4gdGhlIG1hbnVzY3JpcHQgbm93LiBMb29raW5nIGF0IHRoZSBsYWtlIGl0c2VsZiwgYW5kIHRoZSByaXZlcnMgdGhhdCBzdXJyb3VuZCBpdC4gQW4gYXNpZGUgZnJvbSB0aGUgdG9waWMgb2YgdGhlIHBhcGVyLCBidXQsIHBvdGVudGlhbGx5IG9mIGludGVyZXN0IHRvIHJlYWRlcnMtIHdoYXQgYWJvdXQgdGhlIHJpdmVycz8gQXJlIHRoZXkgZGlmZmVyZW50PyAKCgpgYGB7cn0KU3RyZWFtLkJBLlJhcmUgPC0gc3Vic2V0X3NhbXBsZXMoTUwuUmFyZS5CYWNBcmMsIFNhbXBsZU5hbWUgJWluJSBjKCJMZWVWaW5pbmdDcmVlay5SaXZlcldhdGVyIiwgIk1pbGxDcmVlay5SaXZlcldhdGVyIiwgIlJ1c2hDcmVlay5SaXZlcldhdGVyIiwgIldpbHNvbkNyZWVrLlJpdmVyV2F0ZXIiKSkKU3RyZWFtLkV1ay5SYXJlIDwtIHN1YnNldF9zYW1wbGVzKE1MLlJhcmUuRXVrLCBTYW1wbGVOYW1lICVpbiUgYygiTGVlVmluaW5nQ3JlZWsuUml2ZXJXYXRlciIsICJNaWxsQ3JlZWsuUml2ZXJXYXRlciIsICJSdXNoQ3JlZWsuUml2ZXJXYXRlciIsICJXaWxzb25DcmVlay5SaXZlcldhdGVyIikpCmBgYAoKYGBge3J9CnJpdmVyLmNvbHMgPC0gYygiTGVlVmluaW5nQ3JlZWsuUml2ZXJXYXRlciIgPSAiZ3JleTEiLCAiTWlsbENyZWVrLlJpdmVyV2F0ZXIiID0gImdyZXk0IiwgIlJ1c2hDcmVlay5SaXZlcldhdGVyIiA9ICJibHVlIiwgIldpbHNvbkNyZWVrLlJpdmVyV2F0ZXIiID0gIm9yYW5nZSIpCmBgYAoKYGBge3J9ClN0cmVhbS5CQS5QQ0EgPC0gb3JkaW5hdGUoU3RyZWFtLkJBLlJhcmUsIG1ldGhvZCA9ICJQQ29BIiwgZGlzdGFuY2UgPSAid3VuaWZyYWMiKQpTdHJlYW0uQkEuUENBIDwtIHBsb3Rfb3JkaW5hdGlvbihTdHJlYW0uQkEuUmFyZSwgU3RyZWFtLkJBLlBDQSwgY29sb3I9IlNhbXBsZU5hbWUiKQpTdHJlYW0uQkEuUENBICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSByaXZlci5jb2xzKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHJpdmVyLmNvbHMpICsgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKQpgYGAKClRoZSBFdWthcnlvdGljIGNvbW11bml0aWVzIGNvdWxkIG5vdCBiZSBwcm9jZXNzZWQgZm9yIHRoZSBzdHJlYW1zIGR1ZSB0byBsb3cgc2VxdWVuY2UgY291bnQuIFNvLCBsZXQncyBjb250aXV0ZSB3aXRoIHRoZSBiYWN0ZXJpYWwvYXJjaGFlYWwgc2FtcGxlcy4gCgoKYGBge3J9ClN0cmVhbS5CQS5SYXJlLkRhdGEgPSBhcyhzYW1wbGVfZGF0YShTdHJlYW0uQkEuUmFyZSksICJkYXRhLmZyYW1lIikKU3RyZWFtLkJBLmQgPSBwaHlsb3NlcTo6ZGlzdGFuY2UoU3RyZWFtLkJBLlJhcmUsICJ3dW5pZnJhYyIpCmFkb25pcyhTdHJlYW0uQkEuZCB+IFNhbXBsZU5hbWUsIFN0cmVhbS5CQS5SYXJlLkRhdGEpCmBgYAoKSGlnaGx5IHNpZ25pZmljYW50LCB3aXRoIGEgc3Ryb25nIGVmZmVjdCBzaXplLiAKCkZpbmFsbHksIEknbSBnb2luZyB0byBwcm9kdWNlIGEgaGVhdG1hcCB0aGF0IHdhcyB1c2VmdWwgdG8gc2VlIHRoZSBwZXJjZW50YWdlcyBvZiBQaWNvY3lzdGlzLiAKCmBgYHtyLCAgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9NX0KSGVhdG1hcC5CQTwtIGFtcF9oZWF0bWFwKGRhdGEgPSBNTC5BbmQuUml2ZXJzLkJBLlJBLAogICAgICAgICAgICB0YXguYWdncmVnYXRlID0gIkdlbnVzIiwKICAgICAgICAgICB0YXguYWRkID0gIlBoeWx1bSIsCiAgICAgICAgICAgIGdyb3VwID0gYygiU2FtcGxlTmFtZSIpLAogICAgICAgICAgICB0YXguc2hvdyA9IDI1LAogICAgICAgICAgICB0YXguZW1wdHkgPSAicmVtb3ZlIiwKICAgICAgICAgICAgcGxvdC5udW1iZXJzID0gRiwKICAgICAgICAgICAgcGxvdC5icmVha3MgPSBjKDEuMCwxMC4wLDUwLjApLAogICAgICAgICAgICBtYXguYWJ1bmRhbmNlID0gNTAsCiAgICAgICAgICAgIG1pbi5hYnVuZGFuY2UgPSAxLAogICAgICAgICAgICBvcmRlci54ID0gYygiTW9ub0xha2UuU3VyZmFjZVdhdGVyIiwgIk1vbm9MYWtlLjJtIiwgIk1vbm9MYWtlLjEwbSIsICJNb25vTGFrZS4yMG0iLCJNb25vTGFrZS4yNW0iLCAiTW9ub0xha2UuU2VkLjEwbSIsICJUb21zV2VsbC5XYXRlciIsICJMZWVWaW5pbmdDcmVlay5SaXZlcldhdGVyIiwgIk1pbGxDcmVlay5SaXZlcldhdGVyIiwgIlJ1c2hDcmVlay5SaXZlcldhdGVyIiwgIldpbHNvbkNyZWVrLlJpdmVyV2F0ZXIiKSwKICAgICAgICAgICAgc2NhbGUuc2VxID0gMTAwKSArIAogICAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKCJNb25vXG5TdXJmYWNlIiwiTW9ub1xuMiBtIiwiTW9ub1xuMTAgbSIsIk1vbm9cbjIwIG0iLCJNb25vXG4yNSBtIiwiU2VkLlxuMTBtIiwiV2VsbFxuV2F0ZXIiLCAiTGVlIFxuVmluaW5nIiwgIk1pbGwiLCAiUnVzaCIsICJXaWxzb24iKSkgKwogICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID04LCBjb2xvciA9ICJibGFjayIsIGhqdXN0ID0gMC40LCBhbmdsZSA9IDAsIGZhbWlseT0iVGltZXMgTmV3IFJvbWFuIiwgZmFjZT0iYm9sZCIpKSArIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPTgsIGNvbG9yID0gImJsYWNrIiwgYW5nbGUgPSAwLCBmYW1pbHk9IlRpbWVzIE5ldyBSb21hbiIsIGZhY2U9ImJvbGQiKSkKCkhlYXRtYXAuRTwtYW1wX2hlYXRtYXAoZGF0YSA9IE1MLkFuZC5SaXZlcnMuRXVrLlJBLAogICAgICAgICAgICB0YXguYWdncmVnYXRlID0gIkdlbnVzIiwKICAgICAgICAgICAgdGF4LmFkZCA9ICJDbGFzcyIsCiAgICAgICAgICAgIGdyb3VwID0gYygiU2FtcGxlTmFtZSIpLAogICAgICAgICAgICB0YXguc2hvdyA9IDI1LAogICAgICAgICAgICB0YXguZW1wdHkgPSAicmVtb3ZlIiwKICAgICAgICAgICAgcGxvdC5udW1iZXJzID0gVCwKICAgICAgICAgICAgcGxvdC5icmVha3MgPSBjKDEuMCwxMC4wLDUwLjApLAogICAgICAgICAgICBtYXguYWJ1bmRhbmNlID0gNTAsCiAgICAgICAgICAgIG1pbi5hYnVuZGFuY2UgPSAxLAogICAgICAgICAgICBvcmRlci54ID0gYygiTW9ub0xha2UuU3VyZmFjZVdhdGVyIiwgIk1vbm9MYWtlLjJtIiwgIk1vbm9MYWtlLjEwbSIsICJNb25vTGFrZS4yMG0iLCJNb25vTGFrZS4yNW0iLCAiTW9ub0xha2UuU2VkLjEwbSIsICJUb21zV2VsbC5XYXRlciIsICJMZWVWaW5pbmdDcmVlay5SaXZlcldhdGVyIiwgIk1pbGxDcmVlay5SaXZlcldhdGVyIiwgIlJ1c2hDcmVlay5SaXZlcldhdGVyIiwgIldpbHNvbkNyZWVrLlJpdmVyV2F0ZXIiKSwKICAgICAgICAgICAgc2NhbGUuc2VxID0gMTAwKSArIAogICAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKCJNb25vXG5TdXJmYWNlIiwiTW9ub1xuMiBtIiwiTW9ub1xuMTAgbSIsIk1vbm9cbjIwIG0iLCJNb25vXG4yNSBtIiwiU2VkLlxuMTBtIiwiV2VsbFxuV2F0ZXIiLCAiTGVlIFxuVmluaW5nIiwgIk1pbGwiLCAiUnVzaCIsICJXaWxzb24iKSkgKwogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9OCwgY29sb3IgPSAiYmxhY2siLCBoanVzdCA9IDAuNCwgYW5nbGUgPSAwLCBmYW1pbHk9IlRpbWVzIE5ldyBSb21hbiIsIGZhY2U9ImJvbGQiKSkgKyB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID04LCBjb2xvciA9ICJibGFjayIsIGFuZ2xlID0gMCwgZmFtaWx5PSJUaW1lcyBOZXcgUm9tYW4iLCBmYWNlPSJib2xkIikpCgpwbG90X2dyaWQoSGVhdG1hcC5CQSxIZWF0bWFwLkUsIGxhYmVscyA9IGMoIkEiLCAiQiIpLCByZWxfd2lkdGhzID0gYygxLDEpLG5yb3cgPSAyLCBhbGlnbiA9ICJ2IikKYGBgCg==