R Notebook: Provides reproducible analysis for metatranscriptome (MT) data in the following manuscript:

Citation: Romanowicz, KJ, Crump, BC, Kling, GW. (2021) Rainfall alters permafrost soil redox conditions, but meta-omics show divergent microbial community responses by tundra type in the arctic. Soil Systems 5(1): 17. https://doi.org/10.3390/soilsystems5010017

GitHub Repository: https://github.com/kromanowicz/2021-Romanowicz-SoilSystems

NCBI BioProject: https://www.ncbi.nlm.nih.gov/bioproject/PRJNA666429

Accepted for Publication: Soil Systems 10 March 2021

Experiment

This R Notebook provides complete reproducibility of the data analysis in “Rainfall alters permafrost soil redox conditions, but meta-omics show divergent microbial community responses by tundra type in the Arctic” by Romanowicz, Crump, and Kling. In this experiment, mesocosms containing soil from the active layer of two dominant tundra types were subjected to simulated rainfall to alter redox conditions. The microbial functional potential (metagenomics) and gene expression (metatranscriptomics) patterns were measured during saturated anoxic redox conditions prior to rainfall and at multiple time points following the simulated rainfall event. Other measurements include soil properties as well as microbial respiration (CO2) and methane (CH4) production from soil subsamples collected at each sampling time point. The purpose was to determine if rainfall, as a form of soil oxidation, is sufficient to alter the anoxic redox conditions in arctic tundra and enhance the microbial degradation of organic carbon and CH4 to CO2.

Conceptual Figure. A total of 12 tundra mesocosms (3 replicates x 2 tundra types x 2 sets of response cores) were acclimated initially under anoxic redox conditions to mimic field conditions (T0). Dissolved oxygen was supplied to soils through the downward flow of oxygenated water during a simulated rainfall event. Dissolved oxygen will likely change the redox gradient directly following rainfall (T4) as a short-term effect. Anoxic conditions will likely be re-established after 24 hours (T24) as the pulse of oxygen is consumed through abiotic and biotic soil processes. Under anoxic redox conditions (T0), microorganisms likely degrade organic carbon through anaerobic and fermentation pathways, producing CH4 and reducing Fe(III) to Fe(II). Rainfall-induced soil oxidation (T4) should stimulate heterotrophic microorganisms that degrade organic carbon and CH4 through aerobic metabolic pathways, releasing CO2. Soil oxidation should also stimulate aerobic autotrophic iron oxidizing bacteria that oxidize Fe(II) to Fe(III) and convert CO2 into microbial biomass. The long-term response (T24) will likely be a combination of aerobic and anaerobic metabolism as well as a combination of reduction and oxidation iron reactions as dissolved oxygen is consumed. The predicted redox conditions and predicted redox reactions for coupled Fe(II)/Fe(III) cycling, as well as the microbial-induced release of CO2 or CH4 at each time point are based on the predicted availability of dissolved oxygen entering tundra soils through simulated rainfall.

Soil Sampling for Microbial Gene Expression

An initial soil sampling event for microbial activity was conducted at the end of the anoxic acclimation period (4-7 days) in all mesocosm replicates, representing sampling time point T0. Mesocosms were then flushed to simulate a rainfall event. Additional soil sampling events were conducted at T4 (4-hrs) and T24 (24-hrs) following the rainfall event to determine the temporal extent of microbial gene expression. Soil cores (2.54 cm diameter, 30 cm length) were extracted in duplicate from each mesocosm replicate at each sampling time point and homogenized by depth in 10-cm increments. The 10-20 cm soil increment, composed of organic soil in all mesocosm replicates, was chosen for microbial gene expression analysis and preserved in RNAlater Stabilization Reagent in sterile tubes at 4°C for 18 hours and then stored at -80°C until extraction.

Field Experiment. Tundra soil cores were collected from field sites in August 2017 (top left) and placed in buckets to establish the mesocosm experiment (bottom left). Tussock tundra cores were composed of an organic soil layer overlying a mineral soil layer (top middle) while wet sedge tundra cores were composed entirely of organic soil (bottom middle). Soil subsampling for microbial activity was taken from the 10-20 cm depth of duplicate soil cores in Tussock (top right) and Wet Sedge (bottom right).

# Make a vector of required packages
required.packages <- c("ape","cowplot","data.table","devtools","dplyr","DT","ggplot2","ggpubr","grid","gridExtra","kableExtra","knitr","pheatmap","png","RColorBrewer","reshape","rstatix","statmod","stringr","tibble","tidyr","tidyverse","vegan","yaml")

# Load required packages
lapply(required.packages, library, character.only = TRUE)

Metatranscriptomes

1. RNA Sequencing

Total RNA was extracted from soil samples and treated with RiboZERO rRNA removal (leaving mRNA as the bulk of the total RNA pool). The mRNA pool was sequenced on the Illumina HiSeq 4000 platform (150bp paired-end reads) at the University of Michigan Advanced Genomics Core.

SeqCore RNA sample submission to Illumina HiSeq platform
ID Sample Concentration (ng/uL) Vol (uL) 260/280 260/230 RIN
S108379 WS1-T0 36.5 50 1.60 0.90 5.0
S108381 WS3-T0 33.1 50 1.78 0.97 4.4
S108382 Tuss1-T0 61.9 50 1.90 1.25 4.9
S108383 Tuss2-T0 52.0 50 1.84 1.13 4.7
S108385 WS1-T4 45.1 50 1.69 0.98 5.7
S108386 WS2-T4 58.6 50 1.70 1.10 6.2
S108388 WS1-T24 59.9 42 1.63 0.96 4.1
S108390 WS3-T24 79.3 43 1.97 1.61 3.3
S108391 Tuss1-T4 32.9 44 1.75 1.14 4.8
S108392 Tuss2-T4 68.7 50 1.88 1.41 4.7
S108394 Tuss1-T24 114.0 50 1.69 1.25 2.5
S108396 Tuss3-T24 143.0 50 1.84 1.47 1.8
S108380 WS2-T0 10.3 40 1.44 0.91 0.0
S108384 Tuss3-T0 93.3 50 1.94 1.48 3.4
S108387 WS3-T4 31.9 45 1.48 0.71 5.4
S108389 WS2-T24 122.0 50 1.76 1.26 3.2
S108393 Tuss3-T4 69.3 50 1.84 1.22 4.4
S108395 Tuss2-T24 103.0 50 1.90 1.58 1.7

NOTE: RNA Samples in RED were excluded from sequencing

2. RNA Bionformatics

2.1. Raw Reads

Prep and QC the Raw Reads (Hein: Comics – Omics Prep)

Raw RNA sequence reads (metatranscriptomics) were processed initially with the same Geomicro Omics container commands as for the raw DNA sequence reads (metagenomics), with several exceptions noted below: - This prep step assumes the raw data to be available in uncompressed FASTQ format, one file per read direction and each sample’s data in its own directory - The omics prep script will decompress and (if needed) concatenate split fastq files and put them into appropriately names directories

  • The omics qc script was run for each sample but this command differs from the metagenome workflow by NOT dereplicating the RNA reads
  • We want to KEEP all copies of identical reads to determine the abundance of transcribed functional genes from mRNA
{Terminal}
cd /RNA_data/work
comics -- omics prep /RNA_data/1083*
comics -- omics qc --no-dereplicate 1083*

RNA.data.prep.qc.pbs (“/RNA_data/work/”) 00:15 (hr:min)

  • Rename the .fastq files within each sample folder in the “RNA_data/work” directory as “Sample_108379_fwd.fastq”, “Sample_108379_rev.fastq”, etc.
  • Create a “/RNA_data/work/mapping” directory and move over all of the renamed .fastq files (“Sample_108379_fwd.fastq”, “Sample_108379_rev.fastq”, etc.)

2.2. Export Nucleotide Seqs

****Export the nucleotide sequences of the Metagenome Anvi’o gene calls (for mapping MT reads to the MG genes)***

  • First, export the nucleotide sequences of the MG Anvi’o gene calls:
{Terminal}
cd /DNA_data/work/co_assembly
anvi-get-sequences-for-gene-calls -c DNA_data_bbnorm_anvio_contigs.db -o DNA_data_bbnorm_anvio_gene_calls.fna

DNA.data.bbnorm.anvio.export.gene.seqs.pbs (“/RNA_data/work/”) 0:16 (hr:min)

  • Move the “DNA_data_bbnorm_anvio_gene_calls.fna” file to the “/RNA_data/work/mapping” directory

2.2.1 Add the prefix “genecall” to all nucleotide sequences in the “DNA_data_bbnorm_anvio_gene_calls.fna” file

{Terminal}
cd /RNA_data/work/mapping
sed 's/>/>genecall_/g' DNA_data_bbnorm_anvio_gene_calls.fna > DNA_data_bbnorm_anvio_gene_calls_edited.fna
mv DNA_data_bbnorm_anvio_gene_calls_edited.fna DNA_data_bbnorm_anvio_gene_calls.fna

2.2.2 Use the following script to remove all empty sequences from the “DNA_data_bbnorm_anvio_gene_calls.fna” file

{Terminal}
cd /RNA_data/work/mapping
sed '/^>/ {N; /\n$/d}' DNA_data_bbnorm_anvio_gene_calls.fna > DNA_data_bbnorm_anvio_gene_calls_clean.fna
mv DNA_data_bbnorm_anvio_gene_calls_clean.fna DNA_data_bbnorm_anvio_gene_calls.fna

2.3. Index MG Genes

Index the MG Genes and Map Back the MT Reads (Hein: Omics Mapping)

  • Once the sequence headers in the MG genes file were cleaned up, they were indexed as follows:
{Terminal}
cd /RNA_data/work/mapping
comics -- omics mapping -a DNA_data_bbnorm_anvio_gene_calls.fna --index-only

DNA.data.bbnorm.index.MG.genes.pbs (“/RNA_data/work/”) 00:26 (hr:min)

  • The output was in a directory called “/bowtie2-index”
  • Rename as “/bowtie2-index_bbnorm_MG_genes”

2.3.1 Mapping MT QC’d Reads from Each Sample to the Indexed MG Genes

  • Individually map the MT QC’d reads from each sample to the indexed MG genes, which will create separate output directories for each sample containing the mapping result files
{Terminal}
cd /RNA_data/work/mapping
comics -- omics mapping --index-dir /RNA_data/work/mapping/bowtie2-index_bbnorm_MG_genes/ -a DNA_data_bbnorm_anvio_gene_calls.fna -f Sample_108379_fwd.good.fastq -r Sample_108379_rev.good.fastq -o 108379_MT_mapped_reads
comics -- omics mapping --index-dir /RNA_data/work/mapping/bowtie2-index_bbnorm_MG_genes/ -a DNA_data_bbnorm_anvio_gene_calls.fna -f Sample_108381_fwd.good.fastq -r Sample_108381_rev.good.fastq -o 108381_MT_mapped_reads
comics -- omics mapping --index-dir /RNA_data/work/mapping/bowtie2-index_bbnorm_MG_genes/ -a DNA_data_bbnorm_anvio_gene_calls.fna -f Sample_108382_fwd.good.fastq -r Sample_108382_rev.good.fastq -o 108382_MT_mapped_reads
comics -- omics mapping --index-dir /RNA_data/work/mapping/bowtie2-index_bbnorm_MG_genes/ -a DNA_data_bbnorm_anvio_gene_calls.fna -f Sample_108383_fwd.good.fastq -r Sample_108383_rev.good.fastq -o 108383_MT_mapped_reads
comics -- omics mapping --index-dir /RNA_data/work/mapping/bowtie2-index_bbnorm_MG_genes/ -a DNA_data_bbnorm_anvio_gene_calls.fna -f Sample_108385_fwd.good.fastq -r Sample_108385_rev.good.fastq -o 108385_MT_mapped_reads
comics -- omics mapping --index-dir /RNA_data/work/mapping/bowtie2-index_bbnorm_MG_genes/ -a DNA_data_bbnorm_anvio_gene_calls.fna -f Sample_108386_fwd.good.fastq -r Sample_108386_rev.good.fastq -o 108386_MT_mapped_reads
comics -- omics mapping --index-dir /RNA_data/work/mapping/bowtie2-index_bbnorm_MG_genes/ -a DNA_data_bbnorm_anvio_gene_calls.fna -f Sample_108388_fwd.good.fastq -r Sample_108388_rev.good.fastq -o 108388_MT_mapped_reads
comics -- omics mapping --index-dir /RNA_data/work/mapping/bowtie2-index_bbnorm_MG_genes/ -a DNA_data_bbnorm_anvio_gene_calls.fna -f Sample_108390_fwd.good.fastq -r Sample_108390_rev.good.fastq -o 108390_MT_mapped_reads
comics -- omics mapping --index-dir /RNA_data/work/mapping/bowtie2-index_bbnorm_MG_genes/ -a DNA_data_bbnorm_anvio_gene_calls.fna -f Sample_108391_fwd.good.fastq -r Sample_108391_rev.good.fastq -o 108391_MT_mapped_reads
comics -- omics mapping --index-dir /RNA_data/work/mapping/bowtie2-index_bbnorm_MG_genes/ -a DNA_data_bbnorm_anvio_gene_calls.fna -f Sample_108392_fwd.good.fastq -r Sample_108392_rev.good.fastq -o 108392_MT_mapped_reads
comics -- omics mapping --index-dir /RNA_data/work/mapping/bowtie2-index_bbnorm_MG_genes/ -a DNA_data_bbnorm_anvio_gene_calls.fna -f Sample_108394_fwd.good.fastq -r Sample_108394_rev.good.fastq -o 108394_MT_mapped_reads
comics -- omics mapping --index-dir /RNA_data/work/mapping/bowtie2-index_bbnorm_MG_genes/ -a DNA_data_bbnorm_anvio_gene_calls.fna -f Sample_108396_fwd.good.fastq -r Sample_108396_rev.good.fastq -o 108396_MT_mapped_reads

RNA.data.read.mapping.DNA.data.bbnorm.MG.genes.pbs (“/RNA_data/work/”) 12:12 (hr:min)

The results for each individual sample included a mapping directory containing the following files: "/RNA_data/work/mapping/*_MT_mapped_reads" (replace * with SampleID)

  • Sample_RNA_data_bbnorm_anvio_gene_calls.cov tab-delimited file of the average coverage of each contig in the assembly
  • Sample_RNA_data_bbnorm_anvio_gene_calls.sorted.bam contains the mapping information sorted by position
  • Sample_RNA_data_bbnorm_anvio_gene_calls.sorted.bam.bai companion file to the sorted.bam file, which contains the index

2.4. Convert MT .bam Files

Convert the MT .bam Files to count tables to be processed statistically

  • Make pile-up file (average read depth per gene)
  • BBMap (pileup.sh) “final.contigs.fixed.bbnorm.sorted.bam”
{Terminal}
cd /RNA_data/work/mapping/108379_MT_mapped_reads
pileup.sh in=Sample_108379_RNA_data_bbnorm_anvio_gene_calls.sorted.bam out=Sample_108379_RNA_data_bbnorm_anvio_gene_calls.pileup

#Output
head Sample_108379_RNA_data_bbnorm_anvio_gene_calls.pileup
#ID Avg_fold    Length  Ref_GC  Covered_percent Covered_bases   Plus_reads  Minus_reads Read_GC Median_fold Std_Dev
genecall_0  0.0000  300 0.0000  0.0000  0   0   0   0.0000  0   0.00
genecall_1  0.0000  318 0.0000  0.0000  0   0   0   0.0000  0   0.00
genecall_2  0.0000  648 0.0000  0.0000  0   0   0   0.0000  0   0.00
genecall_3  0.0000  375 0.0000  0.0000  0   0   0   0.0000  0   0.00
genecall_4  0.0000  339 0.0000  0.0000  0   0   0   0.0000  0   0.00
genecall_5  0.0000  141 0.0000  0.0000  0   0   0   0.0000  0   0.00
genecall_6  0.0000  132 0.0000  0.0000  0   0   0   0.0000  0   0.00
genecall_7  1.9642  363 0.0000  92.8375 337 4   1   0.7149  1   1.39
genecall_8  0.0000  402 0.0000  0.0000  0   0   0   0.0000  0   0.00
  • This was done for each Sample sorted.bam file to get a table of genes and their counts
{Terminal}
cd /RNA_data/work/mapping/108381_MT_mapped_reads
pileup.sh in=Sample_108381_RNA_data_bbnorm_anvio_gene_calls.sorted.bam out=Sample_108381_RNA_data_bbnorm_anvio_gene_calls.pileup
cd /RNA_data/work/mapping/108382_MT_mapped_reads
pileup.sh in=Sample_108382_RNA_data_bbnorm_anvio_gene_calls.sorted.bam out=Sample_108382_RNA_data_bbnorm_anvio_gene_calls.pileup
cd /RNA_data/work/mapping/108383_MT_mapped_reads
pileup.sh in=Sample_108383_RNA_data_bbnorm_anvio_gene_calls.sorted.bam out=Sample_108383_RNA_data_bbnorm_anvio_gene_calls.pileup
cd /RNA_data/work/mapping/108385_MT_mapped_reads
pileup.sh in=Sample_108385_RNA_data_bbnorm_anvio_gene_calls.sorted.bam out=Sample_108385_RNA_data_bbnorm_anvio_gene_calls.pileup
cd /RNA_data/work/mapping/108386_MT_mapped_reads
pileup.sh in=Sample_108386_RNA_data_bbnorm_anvio_gene_calls.sorted.bam out=Sample_108386_RNA_data_bbnorm_anvio_gene_calls.pileup
cd /RNA_data/work/mapping/108388_MT_mapped_reads
pileup.sh in=Sample_108388_RNA_data_bbnorm_anvio_gene_calls.sorted.bam out=Sample_108388_RNA_data_bbnorm_anvio_gene_calls.pileup
cd /RNA_data/work/mapping/108390_MT_mapped_reads
pileup.sh in=Sample_108390_RNA_data_bbnorm_anvio_gene_calls.sorted.bam out=Sample_108390_RNA_data_bbnorm_anvio_gene_calls.pileup
cd /RNA_data/work/mapping/108391_MT_mapped_reads
pileup.sh in=Sample_108391_RNA_data_bbnorm_anvio_gene_calls.sorted.bam out=Sample_108391_RNA_data_bbnorm_anvio_gene_calls.pileup
cd /RNA_data/work/mapping/108392_MT_mapped_reads
pileup.sh in=Sample_108392_RNA_data_bbnorm_anvio_gene_calls.sorted.bam out=Sample_108392_RNA_data_bbnorm_anvio_gene_calls.pileup
cd /RNA_data/work/mapping/108394_MT_mapped_reads
pileup.sh in=Sample_108394_RNA_data_bbnorm_anvio_gene_calls.sorted.bam out=Sample_108394_RNA_data_bbnorm_anvio_gene_calls.pileup
cd /RNA_data/work/mapping/108396_MT_mapped_reads
pileup.sh in=Sample_108396_RNA_data_bbnorm_anvio_gene_calls.sorted.bam out=Sample_108396_RNA_data_bbnorm_anvio_gene_calls.pileup

RNA.data.bam.to.pile.up.pbs (“/RNA_data/work/”) 00:01 (hr:min)

  • Move all of the **"Sample_*_RNA_data_bbnorm_anvio_gene_calls.pileup“** files to the ”/RNA_data/work/mapping/Pile_Up" directory
  • Import these tables into R and add up the “plus read” and “minus read” values for each gene (= total reads of that particular gene)

2.5. MT Read Summary

The following table is a summary of the RNA reads by sample and includes QC Reads, Mapped Reads, and Average Read Length (bp). All values were derived from the “Sample_*.final.contigs.fixed.bbnorm.sorted.bam” files using samtools stats.

Summary statistics for RNA-based metatranscriptome sequencing dataset
ID Tundra Time Replicate QC Reads Mapped Reads Average Length (bp)
S108382 Tussock T0 1 58,295,400 9,229,059 127
S108383 Tussock T0 2 50,118,466 6,982,871 127
S108391 Tussock T4 1 53,553,208 8,338,151 125
S108392 Tussock T4 2 50,890,114 7,387,851 128
S108394 Tussock T24 1 57,109,114 7,271,424 127
S108396 Tussock T24 3 41,558,870 5,280,460 129
S108379 Wet Sedge T0 1 64,669,902 15,825,372 118
S108381 Wet Sedge T0 3 57,835,184 10,696,764 129
S108385 Wet Sedge T4 1 53,169,696 11,952,373 129
S108386 Wet Sedge T4 2 53,512,234 12,152,652 130
S108388 Wet Sedge T24 1 47,583,386 8,193,077 130
S108390 Wet Sedge T24 3 43,063,128 6,787,536 129

3. Gene Annotations

Following all Data Bioinformatics steps above, quality-controlled metatranscriptome reads were mapped to KEGG-annotated coding sequences (CDS) indexed from the metagenome assembly using BBMap to generate pile-up files (average read depth per gene), and SAMtools was used to extract counts and CDS lengths from the BBMap output.

3.1. Import Gene Counts

In this section, all RNA.pileup files are imported into the R environment and combined into the first FULL dataset to be further formatted for downstream statistical analysis.

3.1.1. RNA PileUp Files

The following RNA.pileup files (average read depth per gene) for each metatranscriptome sample were generated via the BBMap module.

#S108379 -- WS_T0_R1
pileup_108379<-read.table("Pileup.Data/RNA.Pileup/Sample_108379_RNA_data_bbnorm_anvio_gene_calls.pileup", header = TRUE)
pileup_108379$S108379 <- pileup_108379$Plus_reads + pileup_108379$Minus_reads

#S108381 -- WS_T0_R3
pileup_108381<-read.table("Pileup.Data/RNA.Pileup/Sample_108381_RNA_data_bbnorm_anvio_gene_calls.pileup", header = TRUE)
pileup_108381$S108381 <- pileup_108381$Plus_reads + pileup_108381$Minus_reads

#S108385 -- WS_T4_R1
pileup_108385<-read.table("Pileup.Data/RNA.Pileup/Sample_108385_RNA_data_bbnorm_anvio_gene_calls.pileup", header = TRUE)
pileup_108385$S108385 <- pileup_108385$Plus_reads + pileup_108385$Minus_reads

#S108386 -- WS_T4_R2
pileup_108386<-read.table("Pileup.Data/RNA.Pileup/Sample_108386_RNA_data_bbnorm_anvio_gene_calls.pileup", header = TRUE)
pileup_108386$S108386 <- pileup_108386$Plus_reads + pileup_108386$Minus_reads

#S108388 -- WS_T24_R1
pileup_108388<-read.table("Pileup.Data/RNA.Pileup/Sample_108388_RNA_data_bbnorm_anvio_gene_calls.pileup", header = TRUE)
pileup_108388$S108388 <- pileup_108388$Plus_reads + pileup_108388$Minus_reads

#S108390 -- WS_T24_R3
pileup_108390<-read.table("Pileup.Data/RNA.Pileup/Sample_108390_RNA_data_bbnorm_anvio_gene_calls.pileup", header = TRUE)
pileup_108390$S108390 <- pileup_108390$Plus_reads + pileup_108390$Minus_reads

#S108382 -- TUSS_T0_R1
pileup_108382<-read.table("Pileup.Data/RNA.Pileup/Sample_108382_RNA_data_bbnorm_anvio_gene_calls.pileup", header = TRUE)
pileup_108382$S108382 <- pileup_108382$Plus_reads + pileup_108382$Minus_reads

#S108383 -- TUSS_T0_R2
pileup_108383<-read.table("Pileup.Data/RNA.Pileup/Sample_108383_RNA_data_bbnorm_anvio_gene_calls.pileup", header = TRUE)
pileup_108383$S108383 <- pileup_108383$Plus_reads + pileup_108383$Minus_reads

#S108391 -- TUSS_T4_R1
pileup_108391<-read.table("Pileup.Data/RNA.Pileup/Sample_108391_RNA_data_bbnorm_anvio_gene_calls.pileup", header = TRUE)
pileup_108391$S108391 <- pileup_108391$Plus_reads + pileup_108391$Minus_reads

#S108392 -- TUSS_T4_R2
pileup_108392<-read.table("Pileup.Data/RNA.Pileup/Sample_108392_RNA_data_bbnorm_anvio_gene_calls.pileup", header = TRUE)
pileup_108392$S108392 <- pileup_108392$Plus_reads + pileup_108392$Minus_reads

#S108394 -- TUSS_T24_R1
pileup_108394<-read.table("Pileup.Data/RNA.Pileup/Sample_108394_RNA_data_bbnorm_anvio_gene_calls.pileup", header = TRUE)
pileup_108394$S108394 <- pileup_108394$Plus_reads + pileup_108394$Minus_reads

#S108396 -- TUSS_T24_R3
pileup_108396<-read.table("Pileup.Data/RNA.Pileup/Sample_108396_RNA_data_bbnorm_anvio_gene_calls.pileup", header = TRUE)
pileup_108396$S108396 <- pileup_108396$Plus_reads + pileup_108396$Minus_reads

3.1.2. Full RNA Dataset

In the previous step, each RNA.pileup file was imported and an additional column was added that summed the “Plus_reads” and the Minus_reads. The sum column in each RNA.pileup file was named after the RNA.pileup sample name (e.g. “S108379”). All RNA.pileup files contain identical genecalls in an identical order allowing us to extract the genecall ID and genecall Length columns from a single sample (S108379), along with the summed count column of each sample, to create a new dataframe that represents the initial, FULL RNA dataset for downstream analyses:

cts_rna_all <- data.frame(pileup_108379$ID, pileup_108379$Length, pileup_108379$S108379, pileup_108381$S108381, pileup_108382$S108382, pileup_108383$S108383, pileup_108385$S108385, pileup_108386$S108386, pileup_108388$S108388, pileup_108390$S108390, pileup_108391$S108391, pileup_108392$S108392, pileup_108394$S108394, pileup_108396$S108396)

names(cts_rna_all) <- c("ID", "Length", "S108379", "S108381", "S108382", "S108383", "S108385", "S108386", "S108388", "S108390", "S108391", "S108392", "S108394", "S108396")

3.2. Import Gene Annotations

The KEGG Functions file (GhostKoala) and KEGG Taxonomy file (GhostKoala) were imported and the functional and taxonomic annotations were matched to their corresponding genecall ID.

3.2.1. KEGG Reference

First, a KEGG reference file was imported with additional KEGG Tier pathways that provide additional, useful, functional categories for downstream analyses. The Tier II, III, and IV categories were merged to the GhostKoala KEGG functional annotations in subsequent steps.

# Import KO_Orthology.txt reference file
KO_ref<-read.table(file='Annotations.Data/KO_Orthology.txt', sep='\t', quote="", fill=TRUE, header = FALSE)

# Rename column headers
names(KO_ref)<-c("Tier_II","Tier_III","Tier_IV","KEGG")

# Separate "KEGG" column into "KO" and "Annotation" columns
KO_ref<-KO_ref %>% separate(KEGG, c("KO_Accession","Annotation"), " ", extra="merge")

# Further separatae "Annotation" column into "Symbol" and "Function" columns
KO_ref<-KO_ref %>% separate(Annotation, c("KO_Symbol","KO_Function"), "; ", extra="merge")

3.2.2. KEGG Functions

There are 3,917,616 total unique DNA-based genecalls in the metagenomic dataset. The GhostKOALA KEGG functional annotations file (“DNA_data_bbnorm_anvio_contigs_annotations.tsv”) contains annotations for 1,389,518 unique DNA-based genecalls. This indicates that 35.5% of the total unique DNA-based genecalls can be functionally annotated. That also means that 64.5% of unique DNA-based genecalls cannot be annotated and will not be included in downstream analyses. Here, the unique genecall functional annotations will be matched to the same unique genecalls in the DNA-based metagenomic dataset.

# Import the KEGG Functional Annotations file that was exported from the Anvi'o DNA contigs database
KeggAnvio<-read.table(file='Annotations.Data/DNA_data_bbnorm_anvio_contigs_annotations.tsv', sep='\t', quote = "", fill = TRUE, header = TRUE)

# Rename column headers
names(KeggAnvio)<-c("ID","Source","Accession","Function","e-value")

# Separate "Function" column into "Symbol" and "Function" columns
KeggAnvio<-KeggAnvio %>% separate(Function, c("Symbol","Function"), "; ", extra="merge")

# Add "genecall_" to the beginning of each gene ID value to match with downstream analyses
KeggAnvio$ID <- paste("genecall", KeggAnvio$ID, sep="_")

# Add "KO_Symbol" category to the dataset, matched by KO's between the KO_ref file and KeggAnvio
KeggAnvio$KO_Symbol = KO_ref[match(KeggAnvio$Accession, KO_ref$KO_Accession), "KO_Symbol"]

# Add "KO_Function" category to the dataset, matched by KO's between the KO_ref file and KeggAnvio
KeggAnvio$KO_Function = KO_ref[match(KeggAnvio$Accession, KO_ref$KO_Accession), "KO_Function"]

# Add "Tier_II" category to the dataset, matched by KO's between the KO_ref file and KeggAnvio
KeggAnvio$Tier_II = KO_ref[match(KeggAnvio$Accession, KO_ref$KO_Accession), "Tier_II"]

# Add "Tier_III" category to the dataset, matched by KO's between the KO_ref file and KeggAnvio
KeggAnvio$Tier_III = KO_ref[match(KeggAnvio$Accession, KO_ref$KO_Accession), "Tier_III"]

# Add "Tier_IV" category to the dataset, matched by KO's between the KO_ref file and KeggAnvio
KeggAnvio$Tier_IV = KO_ref[match(KeggAnvio$Accession, KO_ref$KO_Accession), "Tier_IV"]

# Keep the Function category from the KO Reference file to potentially fill in gaps in KeggAnvio annotations (many KO's labeled as "None", but the KO should match a known function from the reference file).
KeggFunction<-data.frame(KeggAnvio$ID,KeggAnvio$Accession,KeggAnvio$Symbol,KeggAnvio$KO_Function,KeggAnvio$Tier_II,KeggAnvio$Tier_III,KeggAnvio$Tier_IV)
names(KeggFunction)<-c("ID","KO","Symbol","Function","Tier_II","Tier_III","Tier_IV")
  
# Merge the KO, Symbol, Function, and all Tier columns into single "Combined" column for some downstream analyses
KeggFunction$Combined<-paste(KeggFunction$KO, ":", KeggFunction$Symbol, ":", KeggFunction$Function, ":", KeggFunction$Tier_II, ":", KeggFunction$Tier_III, ":", KeggFunction$Tier_IV)

# Keep just "ID" and "Combined" columns for use with some downstream analyses
KeggData<-data.frame(KeggFunction$ID, KeggFunction$Combined)
names(KeggData)<-c("ID","KEGG")

3.2.3. KEGG Taxonomy

There are 3,917,616 total unique DNA-based genecalls in the metagenomic dataset. The GhostKoala KEGG taxonomy file (“KeggTaxonomy.txt”) contains annotations for 3,912,253 unique DNA-based genecalls. This indicates that 99.9% of the total unique DNA-based genecalls can be taxonomically annotated. Here, the unique genecall taxonomic annotations will be matched to the same unique genecalls in the DNA-based metagenomic dataset.

#Import KeggTaxonomy.txt from GhostKoala
KeggTaxa<-read.table("Annotations.Data/KeggTaxonomy.txt", header = TRUE, fill = TRUE)
names(KeggTaxa)<-c("ID","Domain","Phylum","Class","Order","Family","Genus","Species")

# Merge the taxonomic classes into a single column
KeggTaxa$Taxonomy <- paste(KeggTaxa$Domain, ":", KeggTaxa$Phylum, ":", KeggTaxa$Class, ":", KeggTaxa$Order, ":", KeggTaxa$Family, ":", KeggTaxa$Genus, ":", KeggTaxa$Species)

# Now keep just "ID" and "Taxonomy"
KeggTaxa <- data.frame(KeggTaxa$ID, KeggTaxa$Taxonomy)
names(KeggTaxa)<-c("ID","Taxonomy")

# Add "genecall_" to the beginning of each gene ID value to match with downstream analyses
KeggTaxa$ID<-paste("genecall", KeggTaxa$ID, sep="_")

4. Gene Filtering

The FULL RNA CTS dataset was assembled as a single dataframe (columns: [1] genecall, [2] length, [3-14] metatranscriptome Samples; rows: 3,917,616 unique “genecalls”), and subsequently subsampled into two new dataframes:

  1. cts_rna_expressed: retains only those unique genecalls with a value greater than zero in any single sample
    • Indicates that these genes were expressed under at least ONE treatment in the experiment (i.e., actual expression)
    • The count data from these expressed genes will undergo TPM normalization for only those unique genecalls that can be annotated from KEGG
  2. cts_rna_zero: retains only those unique genecalls that had a value equal to zero in ALL samples
    • Indicates that these genes were NOT expressed at any point in the experiment (i.e., potential expression only)
    • We retain only those unique genecalls that can be annotated from KEGG to look at which genes were present but not expressed during the experiment

4.1. Expressed Genes

Subsample the unique genecalls that have greater than zero raw read counts (“Expressed Genes”) across all samples.

#cts_rna_expressed
cts_rna_expressed <- subset(cts_rna_all, S108379 > 0 | S108381 > 0 | S108382 > 0 | S108383 > 0 | S108385 > 0 | S108386 > 0 | S108388 > 0 | S108390 > 0 | S108391 > 0 | S108392 > 0 | S108394 > 0 | S108396 > 0, select=c(ID,Length,S108379,S108381,S108382,S108383,S108385,S108386,S108388,S108390,S108391,S108392,S108394,S108396))

Add functional and taxonomic annotations to each unique genecall within the “Expressed” subdata.

# Expressed Functional and Taxonomic Annotations
cts_rna_expressed$KEGG = KeggData[match(cts_rna_expressed$ID, KeggData$ID), "KEGG"]
cts_rna_expressed$Taxonomy = KeggTaxa[match(cts_rna_expressed$ID, KeggTaxa$ID), "Taxonomy"]

# Expressed Annotated Genes
cts_rna_exp_annotated<-na.omit(cts_rna_expressed, cols="KEGG")

4.2. Non-Expressed Genes

Also subsample the unique genecalls that have only zero raw read counts (“Non-expressed Genes”) across all samples.

#cts_rna_zero
cts_rna_zero <- subset(cts_rna_all, S108379 == 0 & S108381 == 0 & S108382 == 0 & S108383 == 0 & S108385 == 0 & S108386 == 0 & S108388 == 0 & S108390 == 0 & S108391 == 0 & S108392 == 0 & S108394 == 0 & S108396 == 0, select=c(ID,Length,S108379,S108381,S108382,S108383,S108385,S108386,S108388,S108390,S108391,S108392,S108394,S108396))

Add functional and taxonomic annotations to each unique genecall within the “Non-Expressed” subdata.

# Non-Expressed Functional and Taxonomic Annotations
cts_rna_zero$KEGG = KeggData[match(cts_rna_zero$ID, KeggData$ID), "KEGG"]
cts_rna_zero$Taxonomy = KeggTaxa[match(cts_rna_zero$ID, KeggTaxa$ID), "Taxonomy"]

# Non-Expressed Annotated Genes
cts_rna_zero_annotated<-na.omit(cts_rna_zero, cols="KEGG")

4.3. Expressed Annotated Genes

From this point, we retain only those genecalls that were expressed and have a KEGG functional annotation. All remaining genecalls (64.5% of total dataset) are exempt from downstream analyses. Start by separating the KEGG categories into unique columns. Remove any genecall whose symbol annotation is “None”. Further remove any genecall annotated as Tier II “Organismal Systems” or “Human Diseases”.

# Separate "KEGG" column into "KO", "Symbol", "Function", "Tier_II", "Tier_III", and "Tier_IV" columns
cts_rna_exp_annotated<-cts_rna_exp_annotated %>% separate(KEGG, c("KO","Symbol","Function","Tier_II","Tier_III","Tier_IV"), ": ", extra="merge")

# Remove KO's with "None" as the "Symbol" annotation
cts_rna_exp_annotated<-cts_rna_exp_annotated[!grepl("None", cts_rna_exp_annotated$Symbol),]

# Remove KO's with Tier II category "Organismal Systems"
cts_rna_exp_annotated<-cts_rna_exp_annotated[!grepl("Organismal Systems ", cts_rna_exp_annotated$Tier_II),]

# Remove KO's with Tier II category "Human Diseases"
cts_rna_exp_annotated<-cts_rna_exp_annotated[!grepl("Human Diseases ", cts_rna_exp_annotated$Tier_II),]

Separate the Taxonomy categories into unique columns. Remove any genecall whose taxonomy is outside of “Archaea”, “Bacteria”, or “Fungi”.

# Separate "Taxonomy" column into "Kingdom", "Phylum", "Class", "Order", "Family", "Genus", and "Species" columns
cts_rna_exp_annotated<-cts_rna_exp_annotated %>% separate(Taxonomy, c("Kingdom","Phylum","Class","Order","Family","Genus","Species"), ": ", extra="merge")

# Remove KO's with "ag" as the "Kingdom" annotation
cts_rna_exp_annotated<-cts_rna_exp_annotated[!grepl("ag", cts_rna_exp_annotated$Kingdom),]

# Remove KO's with "Animals" as the "Kingdom" annotation
cts_rna_exp_annotated<-cts_rna_exp_annotated[!grepl("Animals", cts_rna_exp_annotated$Kingdom),]

# Remove KO's with "Plants" as the "Kingdom" annotation
cts_rna_exp_annotated<-cts_rna_exp_annotated[!grepl("Plants", cts_rna_exp_annotated$Kingdom),]

# Remove KO's with "Protists" as the "Kingdom" annotation
cts_rna_exp_annotated<-cts_rna_exp_annotated[!grepl("Protists", cts_rna_exp_annotated$Kingdom),]

#Re-merge the Taxonomy columns for downstream analysis
cts_rna_exp_annotated$Taxonomy <- paste(cts_rna_exp_annotated$Kingdom, ":", cts_rna_exp_annotated$Phylum, ":", cts_rna_exp_annotated$Class, ":", cts_rna_exp_annotated$Order, ":", cts_rna_exp_annotated$Family, ":", cts_rna_exp_annotated$Genus, ":", cts_rna_exp_annotated$Species)

5. Gene Normalization

TPM Normalization: Converts raw gene counts to Transcripts per Million. TPM normalization is based on methods described by Wagner et al. 2012 to normalize transcript abundance data and requires the following two steps:

  1. Calculate Tg: Tg = Read Count x Average Read Length / Gene Length
    • Read Count: number of reads mapped to each unique genecall
    • Average Read Length: Average read length (between 120-140 bp) within each sample from sequences that passed QC
    • Gene Length: Length of each unique genecall
  2. Convert Tg into TPM by sample: TPM = Tg x 1e+06 / sum(Tg)
    • The sum of TPM values in each sample will equal 1,000,000

At this point, we move forward with only the expressed annotated genecall data for downstream statistical analyses.

5.1. Calculate Tg Values

Calculate Tg values by multiplying the read count of each genecall by the average read length within each sample, then divide by the gene length of each genecall.

cts_rna_exp_annotated$S108379_Tg<-(cts_rna_exp_annotated$S108379 * 118) / cts_rna_exp_annotated$Length
cts_rna_exp_annotated$S108381_Tg<-(cts_rna_exp_annotated$S108381 * 129) / cts_rna_exp_annotated$Length
cts_rna_exp_annotated$S108382_Tg<-(cts_rna_exp_annotated$S108382 * 127) / cts_rna_exp_annotated$Length
cts_rna_exp_annotated$S108383_Tg<-(cts_rna_exp_annotated$S108383 * 127) / cts_rna_exp_annotated$Length
cts_rna_exp_annotated$S108385_Tg<-(cts_rna_exp_annotated$S108385 * 129) / cts_rna_exp_annotated$Length
cts_rna_exp_annotated$S108386_Tg<-(cts_rna_exp_annotated$S108386 * 130) / cts_rna_exp_annotated$Length
cts_rna_exp_annotated$S108388_Tg<-(cts_rna_exp_annotated$S108388 * 130) / cts_rna_exp_annotated$Length
cts_rna_exp_annotated$S108390_Tg<-(cts_rna_exp_annotated$S108390 * 129) / cts_rna_exp_annotated$Length
cts_rna_exp_annotated$S108391_Tg<-(cts_rna_exp_annotated$S108391 * 125) / cts_rna_exp_annotated$Length
cts_rna_exp_annotated$S108392_Tg<-(cts_rna_exp_annotated$S108392 * 128) / cts_rna_exp_annotated$Length
cts_rna_exp_annotated$S108394_Tg<-(cts_rna_exp_annotated$S108394 * 127) / cts_rna_exp_annotated$Length
cts_rna_exp_annotated$S108396_Tg<-(cts_rna_exp_annotated$S108396 * 129) / cts_rna_exp_annotated$Length

5.2. Calculate TPM Values

Now multiple each Tg value within a sample by 1e+06 and divide by the sum of Tg values for that sample to determine TPM.

cts_rna_exp_annotated$S108379_TPM<-(cts_rna_exp_annotated$S108379_Tg * 1000000) / sum(cts_rna_exp_annotated$S108379_Tg,na.rm=TRUE)
cts_rna_exp_annotated$S108381_TPM<-(cts_rna_exp_annotated$S108381_Tg * 1000000) / sum(cts_rna_exp_annotated$S108381_Tg,na.rm=TRUE)
cts_rna_exp_annotated$S108382_TPM<-(cts_rna_exp_annotated$S108382_Tg * 1000000) / sum(cts_rna_exp_annotated$S108382_Tg,na.rm=TRUE)
cts_rna_exp_annotated$S108383_TPM<-(cts_rna_exp_annotated$S108383_Tg * 1000000) / sum(cts_rna_exp_annotated$S108383_Tg,na.rm=TRUE)
cts_rna_exp_annotated$S108385_TPM<-(cts_rna_exp_annotated$S108385_Tg * 1000000) / sum(cts_rna_exp_annotated$S108385_Tg,na.rm=TRUE)
cts_rna_exp_annotated$S108386_TPM<-(cts_rna_exp_annotated$S108386_Tg * 1000000) / sum(cts_rna_exp_annotated$S108386_Tg,na.rm=TRUE)
cts_rna_exp_annotated$S108388_TPM<-(cts_rna_exp_annotated$S108388_Tg * 1000000) / sum(cts_rna_exp_annotated$S108388_Tg,na.rm=TRUE)
cts_rna_exp_annotated$S108390_TPM<-(cts_rna_exp_annotated$S108390_Tg * 1000000) / sum(cts_rna_exp_annotated$S108390_Tg,na.rm=TRUE)
cts_rna_exp_annotated$S108391_TPM<-(cts_rna_exp_annotated$S108391_Tg * 1000000) / sum(cts_rna_exp_annotated$S108391_Tg,na.rm=TRUE)
cts_rna_exp_annotated$S108392_TPM<-(cts_rna_exp_annotated$S108392_Tg * 1000000) / sum(cts_rna_exp_annotated$S108392_Tg,na.rm=TRUE)
cts_rna_exp_annotated$S108394_TPM<-(cts_rna_exp_annotated$S108394_Tg * 1000000) / sum(cts_rna_exp_annotated$S108394_Tg,na.rm=TRUE)
cts_rna_exp_annotated$S108396_TPM<-(cts_rna_exp_annotated$S108396_Tg * 1000000) / sum(cts_rna_exp_annotated$S108396_Tg,na.rm=TRUE)

5.3. Create TPM Dataframe

Create the TPM dataframe by subsetting columns of interest from the cts_exp_annotated dataframe.

tpm_all<-data.frame(cts_rna_exp_annotated$ID,cts_rna_exp_annotated$S108379_TPM,cts_rna_exp_annotated$S108381_TPM,cts_rna_exp_annotated$S108382_TPM,cts_rna_exp_annotated$S108383_TPM,cts_rna_exp_annotated$S108385_TPM,cts_rna_exp_annotated$S108386_TPM,cts_rna_exp_annotated$S108388_TPM,cts_rna_exp_annotated$S108390_TPM,cts_rna_exp_annotated$S108391_TPM,cts_rna_exp_annotated$S108392_TPM,cts_rna_exp_annotated$S108394_TPM,cts_rna_exp_annotated$S108396_TPM,cts_rna_exp_annotated$KO,cts_rna_exp_annotated$Symbol,cts_rna_exp_annotated$Function,cts_rna_exp_annotated$Tier_II,cts_rna_exp_annotated$Tier_III,cts_rna_exp_annotated$Tier_IV,cts_rna_exp_annotated$Taxonomy)

names(tpm_all)<-c("ID","S108379_TPM","S108381_TPM","S108382_TPM","S108383_TPM","S108385_TPM","S108386_TPM","S108388_TPM","S108390_TPM","S108391_TPM","S108392_TPM","S108394_TPM","S108396_TPM","KO","Symbol","Function","Tier_II","Tier_III","Tier_IV","Taxonomy")

6. Gene Datasets

At this point, the FULL RNA dataset (cts_rna_all) was separated into Expressed (cts_rna_expressed) and Non-Expressed (cts_rna_zero) subdata. Then the functional and taxonomic annotations were imported and the Expressed and Non-Expressed subdata were further separated into Expressed Annotated (cts_rna_exp_annotated) and Non-Expressed Annotated (cts_rna_zero_annotated) subdata. The Non-Expressed Annotated subdata will be summarized as a list of genes that were NOT expressed at any point during our experiment. Then we moved forward with only the Expressed Annotated subdata and normalized the raw read counts using the Transcripts per Million (TPM) normalization parameters.

Now, we further separate the normalized expressed annotated subdata into their experimental treatments in order to analyze statistical differences in gene expression patterns and differential gene expression between experimental treatments. Pairwise similarities among metatranscriptomes will be calculated using Bray-Curtis similarity values, with differences between treatments assessed via PERMANOVA. Differential gene expresison will be calculated using the EdgeR package.

6.1. Tussock Gene Data

Separate the Tussock samples into their own dataset. Keep only those unique genecalls that have expression in at least 1 Tuss sample.

# Subset the TUSS TPM Normalized Expressed Annotated subdata
tpm_tuss <- subset(tpm_all, select=c(ID,S108382_TPM,S108383_TPM,S108391_TPM,S108392_TPM,S108394_TPM,S108396_TPM,KO,Symbol,Function,Tier_II,Tier_III,Tier_IV, Taxonomy))

names(tpm_tuss)<-c("ID","Tuss1_T0","Tuss2_T0","Tuss1_T4","Tuss2_T4","Tuss1_T24","Tuss3_T24","KO","Symbol","Function","Tier_II","Tier_III","Tier_IV","Taxonomy")

# Remove any non-expressed genes from the Tussock samples
tpm_tuss_expressed <- subset(tpm_tuss, Tuss1_T0 > 0 | Tuss2_T0 > 0 | Tuss1_T4 > 0 | Tuss2_T4 > 0 | Tuss1_T24 > 0 | Tuss3_T24 > 0, select=c(ID,Tuss1_T0,Tuss2_T0,Tuss1_T4,Tuss2_T4,Tuss1_T24,Tuss3_T24,KO,Symbol,Function,Tier_II,Tier_III,Tier_IV,Taxonomy))

6.2. Wet Sedge Gene Data

Separate the Wet Sedge samples into their own dataset. Keep only those unique genecalls that have expression in at least 1 WS sample.

# Subset the WS TPM Normalized Expressed Annotated subdata (that's a mouthful...)
tpm_ws <- subset(tpm_all, select=c(ID,S108379_TPM,S108381_TPM,S108385_TPM,S108386_TPM,S108388_TPM,S108390_TPM,KO,Symbol,Function,Tier_II,Tier_III,Tier_IV,Taxonomy))
names(tpm_ws)<-c("ID","WS1_T0","WS3_T0","WS1_T4","WS2_T4","WS1_T24","WS3_T24","KO","Symbol","Function","Tier_II","Tier_III","Tier_IV","Taxonomy")

# Remove any non-expressed genes from the Wet Sedge samples
tpm_ws_expressed <- subset(tpm_ws, WS1_T0 > 0 | WS3_T0 > 0 | WS1_T4 > 0 | WS2_T4 > 0 | WS1_T24 > 0 | WS3_T24 > 0, select=c(ID,WS1_T0,WS3_T0,WS1_T4,WS2_T4,WS1_T24,WS3_T24,KO,Symbol,Function,Tier_II,Tier_III,Tier_IV,Taxonomy))

6.3. All Gene Data

We also need the full TUSS and WS Expressed Annotated data together to make comparisons between ecosystems within each sampling timepoint. Reformat the tpm_all table and separate the “KEGG” column into all of its functional categories for downstream use.

# Make a new object for the tpm_all table so that you don't overwrite the original
tpm_all_exp_ann<-tpm_all

names(tpm_all_exp_ann)<-c("ID","S108379","S108381","S108382","S108383","S108385","S108386","S108388","S108390","S108391","S108392","S108394","S108396","KO","Symbol","Function","Tier_II","Tier_III","Tier_IV","Taxonomy")

7. Gene Analysis

7.1. Taxonomy

Here, we determine the taxonomic composition of the microbial community by analyzing the relative abundance of gene expression for KEGG tier IV “Ribosomes” (03010 Ribosome PATH: ko03010). Within the “Ribosome” category, there are annotations for “small subunit ribosomal protein” (ssu) and “large subunit ribosomal protein” (lsu). For Bacteria and Archaea, we use on the ssu annotations (similar to 16S ssu rRNA targeted analysis). For Fungi, we use both the ssu (18S ssu rRNA) and lsu (28S lsu rRNA) annotations.

7.1.1. Bacteria/Archaea SSU

The first analysis pulls out all gene expression for “Ribosomes” and removes lsu annotations such that only ssu annotations are used for determining relative expression of Bacteria and Archaea at each sampling time point in both tussock and wet sedge tundra.

# Subset all unique genecalls whose annotation matches "Ribosomes"
taxa_ribo_all<- tpm_all_exp_ann[ which(tpm_all_exp_ann$Tier_IV=='03010 Ribosome [PATH:ko03010]'),]
# Make copy of Ribosome dataset to manipulate
taxa_ribo_ssu<-taxa_ribo_all

# Remove "large subunit ribosomal protein" from dataset
taxa_ribo_ssu<-taxa_ribo_ssu[!grepl("large subunit ribosomal protein", taxa_ribo_ssu$Function),]

# Write dataset to file
write.csv(taxa_ribo_ssu, 'Ribo.Results/ALPHA.taxa.rna.ssu.csv')

# Remove "Fungi" from dataset
taxa_ribo_ssu<-taxa_ribo_ssu[!grepl("Fungi", taxa_ribo_ssu$Taxonomy),]

# Separate "Taxonomy" column into all subdivisions
taxa_ribo_ssu<-taxa_ribo_ssu %>% separate(Taxonomy, c("Kingdom","Phylum","Class","Order","Family","Genus","Species"), ": ", extra="merge")

# Keep "Kingdom" and "Phylum"
taxa_ribo_ssu <- data.frame(taxa_ribo_ssu$Kingdom,taxa_ribo_ssu$Phylum, taxa_ribo_ssu$S108379, taxa_ribo_ssu$S108381,taxa_ribo_ssu$S108385,taxa_ribo_ssu$S108386,taxa_ribo_ssu$S108388,taxa_ribo_ssu$S108390,taxa_ribo_ssu$S108382,taxa_ribo_ssu$S108383,taxa_ribo_ssu$S108391,taxa_ribo_ssu$S108392,taxa_ribo_ssu$S108394,taxa_ribo_ssu$S108396)
names(taxa_ribo_ssu)<-c("Kingdom","Phylum","ws1-T0","ws3-T0","ws1-T4","ws2-T4","ws1-T24","ws3-T24","tuss1-T0","tuss2-T0","tuss1-T4","tuss2-T4","tuss1-T24","tuss3-T24")

# Remove "Unclassified" taxa otherwise it will clump unclassified Archaea with unclassified Bacteria (not what we want)
taxa_ribo_ssu<-taxa_ribo_ssu[!grepl("Unclassified", taxa_ribo_ssu$Phylum),]

# Remove "Other" taxa otherwise it will clump "other" Archaea with "other" Bacteria (not what we want)
taxa_ribo_ssu<-taxa_ribo_ssu[!grepl("Other", taxa_ribo_ssu$Phylum),]

# Sort data by Kingdom alphabetically
taxa_ribo_ssu<-taxa_ribo_ssu[order(taxa_ribo_ssu$Kingdom,taxa_ribo_ssu$Phylum),]

# Sum each column by unique Phylum
taxa_ribo_ssu_sum<-taxa_ribo_ssu %>% group_by(Phylum) %>% summarise_at(vars("ws1-T0","ws3-T0","ws1-T4","ws2-T4","ws1-T24","ws3-T24","tuss1-T0","tuss2-T0","tuss1-T4","tuss2-T4","tuss1-T24","tuss3-T24"), sum)
taxa_ribo_ssu_sum<-taxa_ribo_ssu_sum %>% mutate_at(vars('ws1-T0','ws3-T0','ws1-T4','ws2-T4','ws1-T24','ws3-T24','tuss1-T0','tuss2-T0','tuss1-T4','tuss2-T4','tuss1-T24','tuss3-T24'), funs(round(., 0)))
taxa_ribo_ssu_sum<-as.data.frame(taxa_ribo_ssu_sum)

taxa_ribo_ssu_sum

Repeat the same “Ribosome” analysis as above (at Phylum level), but this time keep all the taxonomy information.

# Make copy of taxa_ribo_all to manipulate
taxa_ribo_ssu2<-taxa_ribo_all

# Keep "Taxonomy" column
taxa_ribo_ssu2 <- data.frame(taxa_ribo_ssu2$Function,taxa_ribo_ssu2$Taxonomy,taxa_ribo_ssu2$S108379, taxa_ribo_ssu2$S108381,taxa_ribo_ssu2$S108385,taxa_ribo_ssu2$S108386,taxa_ribo_ssu2$S108388,taxa_ribo_ssu2$S108390,taxa_ribo_ssu2$S108382,taxa_ribo_ssu2$S108383,taxa_ribo_ssu2$S108391,taxa_ribo_ssu2$S108392,taxa_ribo_ssu2$S108394,taxa_ribo_ssu2$S108396)
names(taxa_ribo_ssu2)<-c("Function","Taxonomy","ws1-T0","ws3-T0","ws1-T4","ws2-T4","ws1-T24","ws3-T24","tuss1-T0","tuss2-T0","tuss1-T4","tuss2-T4","tuss1-T24","tuss3-T24")

# Remove "large subunit ribosomal protein" from dataset
taxa_ribo_ssu2<-taxa_ribo_ssu2[!grepl("large subunit ribosomal protein", taxa_ribo_ssu2$Function),]

# Remove "Fungi" from dataset
taxa_ribo_ssu2<-taxa_ribo_ssu2[!grepl("Fungi", taxa_ribo_ssu2$Taxonomy),]
# Sort data by Kingdom alphabetically
taxa_ribo_ssu2<-taxa_ribo_ssu2[order(taxa_ribo_ssu2$Function,taxa_ribo_ssu2$Taxonomy),]

# Sum each column by unique Taxonomy
taxa_ribo_ssu2_sum<-taxa_ribo_ssu2 %>% group_by(Taxonomy) %>% summarise_at(vars("ws1-T0","ws3-T0","ws1-T4","ws2-T4","ws1-T24","ws3-T24","tuss1-T0","tuss2-T0","tuss1-T4","tuss2-T4","tuss1-T24","tuss3-T24"), sum)
taxa_ribo_ssu2_sum<-taxa_ribo_ssu2_sum %>% mutate_at(vars('ws1-T0','ws3-T0','ws1-T4','ws2-T4','ws1-T24','ws3-T24','tuss1-T0','tuss2-T0','tuss1-T4','tuss2-T4','tuss1-T24','tuss3-T24'), funs(round(., 0)))
taxa_ribo_ssu2_sum<-as.data.frame(taxa_ribo_ssu2_sum)

taxa_ribo_ssu2_sum

7.1.2. Fungi SSU/LSU

The second analysis pulls out all gene expression for “Ribosomes” and removes Bacteria and Archaea annotations while retaining just Fungi with both ssu and lsu annotations to determine relative expression of Fungi at each sampling time point in both tussock and wet sedge tundra.

# Make copy of Ribosome dataset to manipulate
taxa_ribo_fungi<-taxa_ribo_all

# Remove "Bacteria" from dataset
taxa_ribo_fungi<-taxa_ribo_fungi[!grepl("Bacteria", taxa_ribo_fungi$Taxonomy),]

# Remove "Archaea" from dataset
taxa_ribo_fungi<-taxa_ribo_fungi[!grepl("Archaea", taxa_ribo_fungi$Taxonomy),]

# Separate "Taxonomy" column into all subdivisions
taxa_ribo_fungi<-taxa_ribo_fungi %>% separate(Taxonomy, c("Kingdom","Phylum","Class","Order","Family","Genus","Species"), ": ", extra="merge")

# Keep "Kingdom" and "Phylum"
taxa_ribo_fungi <- data.frame(taxa_ribo_fungi$Kingdom,taxa_ribo_fungi$Phylum, taxa_ribo_fungi$S108379, taxa_ribo_fungi$S108381,taxa_ribo_fungi$S108385,taxa_ribo_fungi$S108386,taxa_ribo_fungi$S108388,taxa_ribo_fungi$S108390,taxa_ribo_fungi$S108382,taxa_ribo_fungi$S108383,taxa_ribo_fungi$S108391,taxa_ribo_fungi$S108392,taxa_ribo_fungi$S108394,taxa_ribo_fungi$S108396)
names(taxa_ribo_fungi)<-c("Kingdom","Phylum","ws1-T0","ws3-T0","ws1-T4","ws2-T4","ws1-T24","ws3-T24","tuss1-T0","tuss2-T0","tuss1-T4","tuss2-T4","tuss1-T24","tuss3-T24")

# Remove "Unclassified" taxa
taxa_ribo_fungi<-taxa_ribo_fungi[!grepl("Unclassified", taxa_ribo_fungi$Phylum),]

# Remove "Other" taxa
taxa_ribo_fungi<-taxa_ribo_fungi[!grepl("Other", taxa_ribo_fungi$Phylum),]

# Sort data by Kingdom alphabetically
taxa_ribo_fungi<-taxa_ribo_fungi[order(taxa_ribo_fungi$Kingdom,taxa_ribo_fungi$Phylum),]

# Sum each column by unique Phylum
taxa_ribo_fungi_sum<-taxa_ribo_fungi %>% group_by(Phylum) %>% summarise_at(vars("ws1-T0","ws3-T0","ws1-T4","ws2-T4","ws1-T24","ws3-T24","tuss1-T0","tuss2-T0","tuss1-T4","tuss2-T4","tuss1-T24","tuss3-T24"), sum)
taxa_ribo_fungi_sum<-taxa_ribo_fungi_sum %>% mutate_at(vars('ws1-T0','ws3-T0','ws1-T4','ws2-T4','ws1-T24','ws3-T24','tuss1-T0','tuss2-T0','tuss1-T4','tuss2-T4','tuss1-T24','tuss3-T24'), funs(round(., 0)))
taxa_ribo_fungi_sum<-as.data.frame(taxa_ribo_fungi_sum)

taxa_ribo_fungi_sum

Repeat the same “Ribosome” analysis as above (at Phylum level), but this time keep all the taxonomy information.

# Make copy of taxa_ribo_all to manipulate
taxa_ribo_fungi2<-taxa_ribo_all

# Keep "Taxonomy" column
taxa_ribo_fungi2 <- data.frame(taxa_ribo_fungi2$Function,taxa_ribo_fungi2$Taxonomy,taxa_ribo_fungi2$S108379, taxa_ribo_fungi2$S108381,taxa_ribo_fungi2$S108385,taxa_ribo_fungi2$S108386,taxa_ribo_fungi2$S108388,taxa_ribo_fungi2$S108390,taxa_ribo_fungi2$S108382,taxa_ribo_fungi2$S108383,taxa_ribo_fungi2$S108391,taxa_ribo_fungi2$S108392,taxa_ribo_fungi2$S108394,taxa_ribo_fungi2$S108396)
names(taxa_ribo_fungi2)<-c("Function","Taxonomy","ws1-T0","ws3-T0","ws1-T4","ws2-T4","ws1-T24","ws3-T24","tuss1-T0","tuss2-T0","tuss1-T4","tuss2-T4","tuss1-T24","tuss3-T24")

# Remove "Bacteria" from dataset
taxa_ribo_fungi2<-taxa_ribo_fungi2[!grepl("Bacteria", taxa_ribo_fungi2$Taxonomy),]

# Remove "Archaea" from dataset
taxa_ribo_fungi2<-taxa_ribo_fungi2[!grepl("Archaea", taxa_ribo_fungi2$Taxonomy),]
# Sort data by Kingdom alphabetically
taxa_ribo_fungi2<-taxa_ribo_fungi2[order(taxa_ribo_fungi2$Function,taxa_ribo_fungi2$Taxonomy),]

# Sum each column by unique Taxonomy
taxa_ribo_fungi2_sum<-taxa_ribo_fungi2 %>% group_by(Taxonomy) %>% summarise_at(vars("ws1-T0","ws3-T0","ws1-T4","ws2-T4","ws1-T24","ws3-T24","tuss1-T0","tuss2-T0","tuss1-T4","tuss2-T4","tuss1-T24","tuss3-T24"), sum)
taxa_ribo_fungi2_sum<-taxa_ribo_fungi2_sum %>% mutate_at(vars('ws1-T0','ws3-T0','ws1-T4','ws2-T4','ws1-T24','ws3-T24','tuss1-T0','tuss2-T0','tuss1-T4','tuss2-T4','tuss1-T24','tuss3-T24'), funs(round(., 0)))
taxa_ribo_fungi2_sum<-as.data.frame(taxa_ribo_fungi2_sum)

taxa_ribo_fungi2_sum

7.1.3. Plotting Taxonomy

Plot the relative abundance of taxa by all replicates within tussock and wet sedge tundra as a stackplot.

# Place taxa in order for plotting
taxa.MT.all.chart$Species<-factor(taxa.MT.all.chart$Species,levels = c("Acidobacteria","Actinobacteria","Alphaproteobacteria","Betaproteobacteria","Deltaproteobacteria","Gammaproteobacteria","Proteobacteria Unclassified","Bacteroidetes","Chloroflexi","Firmicutes","Planctomycetes","Verrucomicrobia","Bacteria Unclassified","Bacteria Other","Archaea","Fungi"))

taxa.MT.all.chart$Species<-fct_rev(taxa.MT.all.chart$Species)

taxa.MT.all.chart$Sample<-factor(taxa.MT.all.chart$Sample,levels = c("Tuss1-MT-T0","Tuss2-MT-T0","Tuss1-MT-T4","Tuss2-MT-T4","Tuss1-MT-T24","Tuss3-MT-T24","WS1-MT-T0","WS3-MT-T0","WS1-MT-T4","WS2-MT-T4","WS1-MT-T24","WS3-MT-T24"))
colourCount = length(unique(taxa.MT.all.chart$Species))
getPalette = colorRampPalette(brewer.pal(12, "Paired"))

taxa.MT.all.plot<-ggplot(taxa.MT.all.chart, aes(fill=Species, y=Value, x=Sample)) + geom_bar(position = "stack", stat="identity", color="black") + ylab(expression(atop("Relative Taxon", paste("Expression (%)")))) + theme_minimal() + theme(axis.text=element_text(size=10),axis.title=element_text(size=12),axis.title.x=element_blank()) + theme(legend.position = "right", legend.title=element_blank(), legend.text=element_text(size=8), legend.key.size = unit(0.75,"line"), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_blank(), panel.border = element_blank()) + scale_x_discrete(labels = function(Sample) str_wrap(Sample, width = 8)) + scale_size(guide=FALSE) + scale_fill_manual(values = rev(getPalette(colourCount))) + scale_x_discrete(labels = function(Sample) str_wrap(Sample, width = 15)) + theme(axis.text.x = element_text(angle = 270, hjust=0)) 
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing
scale.
taxa.MT.all.plot

4.2.2 Mean Time Point

Plot the mean relative abundance of taxa by sampling time point within tussock and wet sedge tundra as a stackplot.

# Place taxa in order for plotting
taxa.MT.time.mean.chart$Species<-factor(taxa.MT.time.mean.chart$Species,levels = c("Acidobacteria","Actinobacteria","Alphaproteobacteria","Betaproteobacteria","Deltaproteobacteria","Gammaproteobacteria","Proteobacteria Unclassified","Bacteroidetes","Chloroflexi","Firmicutes","Planctomycetes","Verrucomicrobia","Bacteria Unclassified","Bacteria Other","Archaea","Fungi"))

taxa.MT.time.mean.chart$Species<-fct_rev(taxa.MT.time.mean.chart$Species)

taxa.MT.time.mean.chart$Sample<-factor(taxa.MT.time.mean.chart$Sample,levels = c("Tuss-MT-T0","Tuss-MT-T4","Tuss-MT-T24","WS-MT-T0","WS-MT-T4","WS-MT-T24"))
colourCount = length(unique(taxa.MT.time.mean.chart$Species))
getPalette = colorRampPalette(brewer.pal(12, "Paired"))

taxa.MT.time.mean.plot<-ggplot(taxa.MT.time.mean.chart, aes(fill=Species, y=Value, x=Sample)) + geom_bar(position = "stack", stat="identity", color="black") + ylab(expression(atop("Relative Taxon", paste("Expression (%)")))) + theme_minimal() + theme(axis.text=element_text(size=10),axis.title=element_text(size=12),axis.title.x=element_blank()) + theme(legend.position = "right", legend.title=element_blank(), legend.text=element_text(size=8), legend.key.size = unit(0.75,"line"), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_blank(), panel.border = element_blank()) + scale_x_discrete(labels = function(Sample) str_wrap(Sample, width = 8)) + scale_size(guide=FALSE) + scale_fill_manual(values = rev(getPalette(colourCount))) + scale_x_discrete(labels = function(Sample) str_wrap(Sample, width = 15)) + theme(axis.text.x = element_text(angle = 270, hjust=0)) 
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing
scale.
taxa.MT.time.mean.plot

4.2.3 Mean Tundra

Plot the mean relative abundance of taxa by within tussock and wet sedge tundra as a stackplot.

# Place taxa in order for plotting
taxa.MT.tundra.mean.chart$Species<-factor(taxa.MT.tundra.mean.chart$Species,levels = c("Acidobacteria","Actinobacteria","Alphaproteobacteria","Betaproteobacteria","Deltaproteobacteria","Gammaproteobacteria","Proteobacteria Unclassified","Bacteroidetes","Chloroflexi","Firmicutes","Planctomycetes","Verrucomicrobia","Bacteria Unclassified","Bacteria Other","Archaea","Fungi"))

taxa.MT.tundra.mean.chart$Species<-fct_rev(taxa.MT.tundra.mean.chart$Species)

taxa.MT.tundra.mean.chart$Sample<-factor(taxa.MT.tundra.mean.chart$Sample,levels = c("Tuss-MT","WS-MT"))
colourCount = length(unique(taxa.MT.tundra.mean.chart$Species))
getPalette = colorRampPalette(brewer.pal(12, "Paired"))

taxa.MT.tundra.mean.plot<-ggplot(taxa.MT.tundra.mean.chart, aes(fill=Species, y=Value, x=Sample)) + geom_bar(position = "stack", stat="identity", color="black") + ylab(expression(atop("Relative Taxon", paste("Expression (%)")))) + theme_minimal() + theme(axis.text=element_text(size=10),axis.title=element_text(size=12),axis.title.x=element_blank()) + theme(legend.position = "right", legend.title=element_blank(), legend.text=element_text(size=8), legend.key.size = unit(0.75,"line"), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_blank(), panel.border = element_blank()) + scale_x_discrete(labels = function(Sample) str_wrap(Sample, width = 8)) + scale_size(guide=FALSE) + scale_fill_manual(values = rev(getPalette(colourCount))) + scale_x_discrete(labels = function(Sample) str_wrap(Sample, width = 15)) + theme(axis.text.x = element_text(angle = 270, hjust=0)) 
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing
scale.
taxa.MT.tundra.mean.plot

Plot the relative expression of ribosomes as a stackplot with the MEAN of samples by time point

# Place taxa in order for plotting
taxa.mean.ribo.chart$Species<-factor(taxa.mean.ribo.chart$Species,levels = c("Acidobacteria","Actinobacteria","Alphaproteobacteria","Betaproteobacteria","Deltaproteobacteria","Gammaproteobacteria","Proteobacteria Unclassified","Bacteroidetes","Chloroflexi","Firmicutes","Planctomycetes","Verrucomicrobia","Bacteria Other","Archaea","Fungi"))

taxa.mean.ribo.chart$Species<-fct_rev(taxa.mean.ribo.chart$Species)

taxa.mean.ribo.chart$Sample<-factor(taxa.mean.ribo.chart$Sample,levels = c("Tuss-16S","Tuss-MG","Tuss-MT-T0","Tuss-MT-T4","Tuss-MT-T24","WS-16S","WS-MG","WS-MT-T0","WS-MT-T4","WS-MT-T24"))
colourCount = length(unique(taxa.mean.ribo.chart$Species))
getPalette = colorRampPalette(brewer.pal(12, "Paired"))

taxa.mean.ribo.plot<-ggplot(taxa.mean.ribo.chart, aes(fill=Species, y=Value, x=Sample)) + geom_bar(position = "stack", stat="identity", color="black") + ylab(" ") + theme_minimal() + theme(axis.text=element_text(size=10),axis.title=element_text(size=12),axis.title.x=element_blank()) + theme(legend.position = "right", legend.title=element_blank(), legend.text=element_text(size=8), legend.key.size = unit(0.75,"line"), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_blank(), panel.border = element_blank()) + scale_x_discrete(labels = function(Sample) str_wrap(Sample, width = 8)) + scale_size(guide=FALSE) + guides(shape = guide_legend(override.aes = list(size = 1))) + scale_fill_manual(values = rev(getPalette(colourCount)), guide=guide_legend(reverse=FALSE)) + scale_x_discrete(labels = function(Sample) str_wrap(Sample, width = 15)) + theme(axis.text.x = element_text(angle = 270, hjust=0))
taxa.mean.ribo.plot

Plot the relative expression of TUSS ribosomes as a stackplot by MEAN of TIMEPOINT

# Place taxa in order for plotting
taxa.tuss.mean.ribo.chart$Species<-factor(taxa.tuss.mean.ribo.chart$Species,levels = c("Acidobacteria","Actinobacteria","Alphaproteobacteria","Betaproteobacteria","Deltaproteobacteria","Gammaproteobacteria","Proteobacteria Unclassified","Bacteroidetes","Chloroflexi","Firmicutes","Planctomycetes","Verrucomicrobia","Bacteria Other","Archaea","Fungi"))

taxa.tuss.mean.ribo.chart$Species<-fct_rev(taxa.tuss.mean.ribo.chart$Species)

taxa.tuss.mean.ribo.chart$Sample<-factor(taxa.tuss.mean.ribo.chart$Sample,levels = c("Tuss-16S","Tuss-MG","Tuss-MT-T0","Tuss-MT-T4","Tuss-MT-T24"))
colourCount = length(unique(taxa.tuss.mean.ribo.chart$Species))
getPalette = colorRampPalette(brewer.pal(12, "Paired"))

taxa.tuss.mean.ribo.plot<-ggplot(taxa.tuss.mean.ribo.chart, aes(fill=Species, y=Value, x=Sample)) + geom_bar(position = "stack", stat="identity", color="black") + ylab(expression(atop("Community Composition", paste("Relative Abundance (%)")))) + scale_fill_manual(values = rev(getPalette(colourCount)), guide=guide_legend(reverse=FALSE)) + theme_classic() + theme(axis.title.x=element_blank(), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank(), axis.ticks = element_blank(), axis.text.x = element_text(angle = 270, hjust=0), axis.text=element_text(size=10), axis.title=element_text(size=12), legend.position = "none", legend.title=element_blank(), legend.text=element_text(size=10), legend.key.size = unit(0.75,"line")) + scale_y_continuous(expand = c(0, 0), limits = c(0, 101))
taxa.tuss.mean.ribo.plot

Plot the relative expression of WS ribosomes as a stackplot by MEAN of TIMEPOINT

# Place taxa in order for plotting
taxa.ws.mean.ribo.chart$Species<-factor(taxa.ws.mean.ribo.chart$Species,levels = c("Acidobacteria","Actinobacteria","Alphaproteobacteria","Betaproteobacteria","Deltaproteobacteria","Gammaproteobacteria","Proteobacteria Unclassified","Bacteroidetes","Chloroflexi","Firmicutes","Planctomycetes","Verrucomicrobia","Bacteria Other","Archaea","Fungi"))

taxa.ws.mean.ribo.chart$Species<-fct_rev(taxa.ws.mean.ribo.chart$Species)

taxa.ws.mean.ribo.chart$Sample<-factor(taxa.ws.mean.ribo.chart$Sample,levels = c("WS-16S","WS-MG","WS-MT-T0","WS-MT-T4","WS-MT-T24"))
colourCount = length(unique(taxa.ws.mean.ribo.chart$Species))
getPalette = colorRampPalette(brewer.pal(12, "Paired"))

taxa.ws.mean.ribo.plot<-ggplot(taxa.ws.mean.ribo.chart, aes(fill=Species, y=Value, x=Sample)) + geom_bar(position = "stack", stat="identity", color="black ") + ylab(expression(atop("Community Composition", paste("Relative Abundance (%)")))) + scale_fill_manual(values = rev(getPalette(colourCount)), guide=guide_legend(reverse=FALSE)) + theme_classic() + theme(axis.title.x=element_blank(), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank(), axis.ticks = element_blank(), axis.text.x = element_text(angle = 270, hjust=0), axis.text=element_text(size=10), axis.title=element_text(size=12), legend.position = "right", legend.title=element_blank(), legend.text=element_text(size=10), legend.key.size = unit(0.75,"line")) + scale_y_continuous(expand = c(0, 0), limits = c(0, 101))
taxa.ws.mean.ribo.plot

7.1.4. Taxonomy Statistics

To determine if there are significant differences in mean relative abundance of dominant taxa between tundra ecosystems, we calculate the mean (SD) of each phylum (dominant phylum; >1%) within tussock tundra and within wet sedge tundra throughout the experiment and compare to each other.

Relative abundance (mean (SD)) of microbial taxa within tussock tundra and wet sedge tundra with mean difference (%) and significance (p-value).
Taxonomy Tuss Relative Abundance (%) WS Relative Abundance (%) Mean Difference Paired t-test (p-value)
Acidobacteria 41 (11.8) 8 (1.4) +33% 0.001
Actinobacteria 42 (12.3) 40 (3.3) N.S. 0.681
Alphaproteobacteria 4 (1.8) 3 (1.9) +1% 0.004
Betaproteobacteria 1 (0.6) 4 (1.8) -3% 0.008
Deltaproteobacteria 3 (0.8) 13 (1.3) -10% < 0.001
Gammaproteobacteria 3 (0.9) 1 (0.5) +2% 0.003
Bacteroidetes 1 (0.3) 2 (0.8) -1% 0.024
Chloroflexi 0 (0.1) 8 (2.1) -8% < 0.001
Firmicutes 2 (0.2) 10 (2.0) -9% < 0.001
Euryarchaeota 0 (0.1) 7 (5.7) -6% 0.039
Ascomycetes 1 (1.0) 0 (0) +1% 0.017

Test for differences in mean relative abundance of dominant phyla between tundra ecosystems.

# Pairwise comparisons between tundra ecosystems for each microbial taxonomic class
taxa.phylum.t.test.stats <- taxa.phylum.t.test %>%
  group_by(Phylum) %>%
  pairwise_t_test(
    Abundance ~ Tundra, paired = TRUE, 
    p.adjust.method = "bonferroni"
    ) %>%
  select(-.y., -n1, -n2, -df, -statistic, -p) # Remove details
taxa.phylum.t.test.stats

To determine if there are significant differences in mean relative abundance of dominant taxa between sampling time points within each tundra ecosystem, we calculate the mean (SD) of each phylum (dominant phylum; >1%) at each time point within tussock tundra or within wet sedge tundra throughout the experiment and compare to each other.

Click on the Show/Hide button to see the statistics.

Tussock Tundra Taxonomy (Phylum) ANOVA

# Subset response variables for MANOVA
tuss_mt_taxa_stats$response <- as.matrix(tuss_mt_taxa_stats[, 2:12])
# MANOVA test
tuss_mt_taxa_stats_manova <- manova(response ~ Timepoint, data=tuss_mt_taxa_stats)
summary.aov(tuss_mt_taxa_stats_manova)
 Response Acidobacteria :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 569.68 284.839  6.7411 0.07765 .
Residuals    3 126.76  42.254                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Actinobacteria :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 515.87 257.937  3.1701  0.182
Residuals    3 244.10  81.366               

 Response Alphaproteobacteria :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  3.3093  1.6546  0.3964 0.7034
Residuals    3 12.5209  4.1736               

 Response Betaproteobacteria :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.49775 0.24887  0.5572 0.6226
Residuals    3 1.33995 0.44665               

 Response Deltaproteobacteria :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1.0768 0.53840  0.7706 0.5369
Residuals    3 2.0960 0.69867               

 Response Gammaproteobacteria :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.9972  0.4986  0.4557 0.6717
Residuals    3 3.2823  1.0941               

 Response Bacteroidetes :
            Df  Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.28561 0.142805  2.7536 0.2094
Residuals    3 0.15558 0.051861               

 Response Chloroflexi :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.0110193 0.0055097  2.7275 0.2114
Residuals    3 0.0060601 0.0020200               

 Response Firmicutes :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.072658 0.036329  0.5627 0.6201
Residuals    3 0.193699 0.064566               

 Response Archaea :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.0187581 0.0093790  4.6782 0.1196
Residuals    3 0.0060146 0.0020049               

 Response Fungi :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3.7024 1.85119  4.4145 0.1277
Residuals    3 1.2580 0.41935               
## Run ANOVA for each category of interest (significant in MANOVA)

# Acidobacteria
tuss_mt_taxa_stats1<-aov(Acidobacteria~Timepoint,data=tuss_mt_taxa_stats)
summary.aov(tuss_mt_taxa_stats1)
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2  569.7  284.84   6.741 0.0777 .
Residuals    3  126.8   42.25                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_mt_taxa_stats1)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Acidobacteria ~ Timepoint, data = tuss_mt_taxa_stats)

$Timepoint
                      diff       lwr       upr     p adj
Tuss-T24-Tuss-T0 -18.71302 -45.87623  8.450194 0.1238258
Tuss-T4-Tuss-T0  -22.18715 -49.35037  4.976064 0.0831148
Tuss-T4-Tuss-T24  -3.47413 -30.63734 23.689084 0.8610312
# Actinobacteria
tuss_mt_taxa_stats2<-aov(Actinobacteria~Timepoint,data=tuss_mt_taxa_stats)
summary.aov(tuss_mt_taxa_stats2)
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  515.9  257.94    3.17  0.182
Residuals    3  244.1   81.37               
TukeyHSD(tuss_mt_taxa_stats2)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Actinobacteria ~ Timepoint, data = tuss_mt_taxa_stats)

$Timepoint
                      diff       lwr      upr     p adj
Tuss-T24-Tuss-T0 17.371869 -20.32181 55.06555 0.2765246
Tuss-T4-Tuss-T0  21.357505 -16.33618 59.05119 0.1879342
Tuss-T4-Tuss-T24  3.985636 -33.70805 41.67932 0.9013272

Wet Sedge Tundra Taxonomy (Phylum) ANOVA

# Subset response variables for MANOVA
ws_mt_taxa_stats$response <- as.matrix(ws_mt_taxa_stats[, 2:12])
# MANOVA test
ws_mt_taxa_stats_manova <- manova(response ~ Timepoint, data=ws_mt_taxa_stats)
summary.aov(ws_mt_taxa_stats_manova)
 Response Acidobacteria :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 7.6994  3.8497  5.9254 0.09079 .
Residuals    3 1.9491  0.6497                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Actinobacteria :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 18.633  9.3167  0.7441 0.5465
Residuals    3 37.562 12.5206               

 Response Alphaproteobacteria :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  6.768  3.3840  0.8942 0.4959
Residuals    3 11.353  3.7845               

 Response Betaproteobacteria :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 9.6474  4.8237  1.9898 0.2818
Residuals    3 7.2726  2.4242               

 Response Deltaproteobacteria :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1.5414 0.77068  0.3253  0.745
Residuals    3 7.1082 2.36941               

 Response Gammaproteobacteria :
            Df  Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.07757 0.038786  0.1239 0.8878
Residuals    3 0.93904 0.313013               

 Response Bacteroidetes :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1.8059 0.90295  1.8932 0.2939
Residuals    3 1.4308 0.47694               

 Response Chloroflexi :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  7.0221  3.5111   0.752 0.5436
Residuals    3 14.0064  4.6688               

 Response Firmicutes :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 9.3700  4.6850  1.4066 0.3707
Residuals    3 9.9923  3.3308               

 Response Archaea :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  38.139  19.069   0.453 0.6731
Residuals    3 126.299  42.100               

 Response Fungi :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.0133818 0.0066909  3.5538 0.1617
Residuals    3 0.0056483 0.0018828               
## Run ANOVA for each category of interest (significant in MANOVA)

# Acidobacteria
ws_mt_taxa_stats1<-aov(Acidobacteria~Timepoint,data=ws_mt_taxa_stats)
summary.aov(ws_mt_taxa_stats1)
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2  7.699    3.85   5.925 0.0908 .
Residuals    3  1.949    0.65                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(ws_mt_taxa_stats1)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Acidobacteria ~ Timepoint, data = ws_mt_taxa_stats)

$Timepoint
                  diff        lwr      upr     p adj
WS-T24-WS-T0  2.761829 -0.6064279 6.130085 0.0823421
WS-T4-WS-T0   1.148958 -2.2192980 4.517215 0.4342459
WS-T4-WS-T24 -1.612870 -4.9811265 1.755386 0.2586085

We further investigate which classes of taxa are driving these significant differences in relative taxon abundance observed at the phylum level (see above). We retain only those classes of each dominant phylum where at least 1 sample (out of 12) had > 1.0% relative abundance (to make biologically-relevant statistical comparisons of the data).

Here, we test for differences in mean relative abundance of biologically-relevant microbial classes within each dominant phylum (identified above) between tundra ecosystems.

# Pairwise comparisons between tundra ecosystems for each microbial taxonomic class
taxa.class.t.test.stats <- taxa.class.t.test %>%
  group_by(Class) %>%
  pairwise_t_test(
    Abundance ~ Tundra, paired = TRUE, 
    p.adjust.method = "bonferroni"
    ) %>%
  select(-.y., -group1, -group2, -n1, -n2, -df, -statistic, -p)
taxa.class.t.test.stats

Here, we separate these taxa by tundra ecosystem and look for differences between sampling time point over the course of the study.

Click on the Show/Hide button to see the statistics.

Tussock Tundra Taxonomy (All Levels) ANOVA

# Subset response variables for MANOVA
tuss_mt_all_taxa_stats$response <- as.matrix(tuss_mt_all_taxa_stats[, 2:44])
# MANOVA test
tuss_mt_all_taxa_stats_manova <- manova(response ~ Timepoint, data=tuss_mt_all_taxa_stats)
summary.aov(tuss_mt_all_taxa_stats_manova)
 Response Archaea.Euryarchaeota.Methanosarcina. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 0.00041968 2.0984e-04   3.615 0.1588
Residuals    3 0.00017414 5.8047e-05               

 Response Archaea.Euryarchaeota.Methanothrix. :
            Df    Sum Sq    Mean Sq F value  Pr(>F)  
Timepoint    2 0.0053763 0.00268814  9.1616 0.05277 .
Residuals    3 0.0008802 0.00029342                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Acidobacteria.Acidobacteriaceae.bacterium :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 94.457  47.229    14.2 0.02953 *
Residuals    3  9.978   3.326                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Acidobacteria.Acidobacterium. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 220.017 110.008  20.884 0.01735 *
Residuals    3  15.803   5.268                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Acidobacteria.Candidatus.Koribacter :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.35203 0.17602  0.2211 0.8136
Residuals    3 2.38840 0.79613               

 Response Bacteria.Acidobacteria.Candidatus.Solibacter :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 129.70  64.848  1.0011 0.4645
Residuals    3 194.34  64.778               

 Response Bacteria.Acidobacteria.Granulicella. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 12.1780  6.0890  22.003 0.01612 *
Residuals    3  0.8302  0.2767                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Acidobacteria.Luteitalea. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1.49718 0.74859  3.1823 0.1813
Residuals    3 0.70571 0.23524               

 Response Bacteria.Acidobacteria.Terriglobus. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 7.2228  3.6114  29.342 0.01073 *
Residuals    3 0.3692  0.1231                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Actinobacteria.Blastococcus. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 1.9275e-04 9.6374e-05  5.0224 0.1103
Residuals    3 5.7566e-05 1.9189e-05               

 Response Bacteria.Actinobacteria.Conexibacter. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2.8091 1.40455  1.8927  0.294
Residuals    3 2.2263 0.74211               

 Response Bacteria.Actinobacteria.Geodermatophilus. :
            Df    Sum Sq   Mean Sq F value  Pr(>F)  
Timepoint    2 0.0199709 0.0099855  22.676 0.01545 *
Residuals    3 0.0013211 0.0004404                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Actinobacteria.Kineococcus. :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.0082458 0.0041229   2.853 0.2023
Residuals    3 0.0043354 0.0014451               

 Response Bacteria.Actinobacteria.Kribbella. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 26.2973 13.1487  10.732 0.04294 *
Residuals    3  3.6754  1.2251                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Actinobacteria.Microlunatus. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 4.3734 2.18670  5.9499 0.09035 .
Residuals    3 1.1026 0.36752                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Actinobacteria.Nakamurella. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 0.00037268 0.00018634  0.2557 0.7897
Residuals    3 0.00218594 0.00072865               

 Response Bacteria.Actinobacteria.Nonomuraea. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2.9087  1.4544  1.2228 0.4089
Residuals    3 3.5682  1.1894               

 Response Bacteria.Actinobacteria.Plantactinospora. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 4.0666 2.03330  3.0722 0.1879
Residuals    3 1.9855 0.66184               

 Response Bacteria.Actinobacteria.Streptacidiphilus. :
            Df    Sum Sq   Mean Sq F value   Pr(>F)   
Timepoint    2 0.0173011 0.0086505  34.392 0.008544 **
Residuals    3 0.0007546 0.0002515                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Actinobacteria.Streptosporangium. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 13.0525  6.5262  2.1061 0.2683
Residuals    3  9.2963  3.0988               

 Response Bacteria.Actinobacteria.Thermobifida. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2.3270  1.1635  0.4948 0.6521
Residuals    3 7.0547  2.3516               

 Response Bacteria.Actinobacteria.Thermomonospora. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 14.363  7.1816  0.7836 0.5324
Residuals    3 27.496  9.1652               

 Response Bacteria.Alphaproteobacteria.Rhodoplanes. :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.0051514 0.0025757  0.9459 0.4803
Residuals    3 0.0081691 0.0027230               

 Response Bacteria.Bacteroidetes.Alkalitalea. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 6.3370e-07 3.1684e-07   0.143 0.8723
Residuals    3 6.6457e-06 2.2153e-06               

 Response Bacteria.Bacteroidetes.Niastella. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.081536 0.040768  2.8037 0.2058
Residuals    3 0.043622 0.014541               

 Response Bacteria.Betaproteobacteria.Rhizobacter. :
            Df  Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.24174 0.120871   1.475  0.358
Residuals    3 0.24584 0.081945               

 Response Bacteria.Chloroflexi.Anaerolinea. :
            Df     Sum Sq    Mean Sq F value  Pr(>F)  
Timepoint    2 0.00293452 0.00146726  25.417 0.01315 *
Residuals    3 0.00017318 0.00005773                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Chloroflexi.Herpetosiphon. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 0.00194723 0.00097361  3.4429 0.1672
Residuals    3 0.00084837 0.00028279               

 Response Bacteria.Chloroflexi.Pelolinea. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 0.00014633 7.3166e-05  0.4076 0.6973
Residuals    3 0.00053852 1.7951e-04               

 Response Bacteria.Chloroflexi.Roseiflexus. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 0.00052666 0.00026333   0.866 0.5048
Residuals    3 0.00091221 0.00030407               

 Response Bacteria.Chloroflexi.Sphaerobacter. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 0.00011227 5.6135e-05  0.1874 0.8381
Residuals    3 0.00089878 2.9959e-04               

 Response Bacteria.Deltaproteobacteria.Desulfobacca. :
            Df    Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.0034481 0.001724    0.27 0.7802
Residuals    3 0.0191579 0.006386               

 Response Bacteria.Deltaproteobacteria.Desulfobacula. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.29888 0.14944   0.868 0.5041
Residuals    3 0.51649 0.17216               

 Response Bacteria.Deltaproteobacteria.Geobacter. :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.0076615 0.0038308  4.4611 0.1262
Residuals    3 0.0025761 0.0008587               

 Response Bacteria.Deltaproteobacteria.Labilithrix. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.078762 0.039381  1.4636 0.3601
Residuals    3 0.080719 0.026906               

 Response Bacteria.Deltaproteobacteria.Stigmatella. :
            Df   Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.010184 0.0050920  0.7782 0.5343
Residuals    3 0.019631 0.0065436               

 Response Bacteria.Deltaproteobacteria.Syntrophobacter. :
            Df    Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 0.0011929 0.00059646   0.243 0.7984
Residuals    3 0.0073643 0.00245476               

 Response Bacteria.Deltaproteobacteria.Syntrophus. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 0.00036673 0.00018336  0.5656 0.6188
Residuals    3 0.00097259 0.00032420               

 Response Bacteria.Deltaproteobacteria.Vulgatibacter. :
            Df   Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.012272 0.0061362  1.0175 0.4599
Residuals    3 0.018091 0.0060304               

 Response Bacteria.Firmicutes.Clostridia.Anoxybacter :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 0.00028314 1.4157e-04  3.8365  0.149
Residuals    3 0.00011070 3.6901e-05               

 Response Bacteria.Firmicutes.Clostridia.Carboxydocella :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 3.3545e-05 1.6773e-05  1.4618 0.3604
Residuals    3 3.4421e-05 1.1474e-05               

 Response Bacteria.Firmicutes.Clostridia.Pelotomaculum :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 5.5852e-05 2.7926e-05  0.7025  0.562
Residuals    3 1.1925e-04 3.9749e-05               

 Response Bacteria.Gammaproteobacteria.Others.Steroidobacter :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.57626 0.28813  0.4499 0.6747
Residuals    3 1.92116 0.64039               
## Run ANOVA for each category of interest (significant in MANOVA)

# Acidobacteria
#tuss_mt_taxa_stats1<-aov(Acidobacteria~Timepoint,data=tuss_mt_taxa_stats)
#summary.aov(tuss_mt_taxa_stats1)
#TukeyHSD(tuss_mt_taxa_stats1)

# Actinobacteria
#tuss_mt_taxa_stats2<-aov(Actinobacteria~Timepoint,data=tuss_mt_taxa_stats)
#summary.aov(tuss_mt_taxa_stats2)
#TukeyHSD(tuss_mt_taxa_stats2)

Wet Sedge Tundra Taxonomy (Phylum) ANOVA

# Subset response variables for MANOVA
ws_mt_all_taxa_stats$response <- as.matrix(ws_mt_all_taxa_stats[, 2:44])
# MANOVA test
ws_mt_all_taxa_stats_manova <- manova(response ~ Timepoint, data=ws_mt_all_taxa_stats)
summary.aov(ws_mt_all_taxa_stats_manova)
 Response Archaea.Euryarchaeota.Methanosarcina. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1.8501 0.92505  1.0121 0.4614
Residuals    3 2.7419 0.91397               

 Response Archaea.Euryarchaeota.Methanothrix. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 14.176  7.0882  0.3716 0.7175
Residuals    3 57.220 19.0733               

 Response Bacteria.Acidobacteria.Acidobacteriaceae.bacterium :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.0043835 0.0021918  0.4829 0.6579
Residuals    3 0.0136150 0.0045383               

 Response Bacteria.Acidobacteria.Acidobacterium. :
            Df   Sum Sq   Mean Sq F value  Pr(>F)  
Timepoint    2 0.048155 0.0240775  7.7823 0.06496 .
Residuals    3 0.009282 0.0030939                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Acidobacteria.Candidatus.Koribacter :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.011145 0.005573  0.1597 0.8592
Residuals    3 0.104671 0.034890               

 Response Bacteria.Acidobacteria.Candidatus.Solibacter :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 2.69114 1.34557  13.316 0.03221 *
Residuals    3 0.30315 0.10105                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Acidobacteria.Granulicella. :
            Df    Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 0.0015815 0.00079076  1.6458 0.3293
Residuals    3 0.0014414 0.00048046               

 Response Bacteria.Acidobacteria.Luteitalea. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2.9628 1.48141  2.8681 0.2012
Residuals    3 1.5495 0.51651               

 Response Bacteria.Acidobacteria.Terriglobus. :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.0046043 0.0023022  1.3363 0.3846
Residuals    3 0.0051683 0.0017228               

 Response Bacteria.Actinobacteria.Blastococcus. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1.1122 0.55613  1.1742 0.4201
Residuals    3 1.4208 0.47362               

 Response Bacteria.Actinobacteria.Conexibacter. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1.4254 0.71268  0.5785 0.6131
Residuals    3 3.6960 1.23198               

 Response Bacteria.Actinobacteria.Geodermatophilus. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.47042 0.23521  0.5817 0.6116
Residuals    3 1.21299 0.40433               

 Response Bacteria.Actinobacteria.Kineococcus. :
            Df  Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 1.74335 0.87167  20.501 0.0178 *
Residuals    3 0.12755 0.04252                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Actinobacteria.Kribbella. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.41550 0.20775  1.3161 0.3887
Residuals    3 0.47354 0.15785               

 Response Bacteria.Actinobacteria.Microlunatus. :
            Df  Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.11411 0.057054   1.103 0.4374
Residuals    3 0.15518 0.051727               

 Response Bacteria.Actinobacteria.Nakamurella. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.6900 0.34502  0.2527 0.7917
Residuals    3 4.0954 1.36514               

 Response Bacteria.Actinobacteria.Nonomuraea. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.022272 0.011136  0.7401 0.5479
Residuals    3 0.045139 0.015046               

 Response Bacteria.Actinobacteria.Plantactinospora. :
            Df    Sum Sq    Mean Sq F value  Pr(>F)   
Timepoint    2 2.177e-03 0.00108850  35.329 0.00822 **
Residuals    3 9.243e-05 0.00003081                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Actinobacteria.Streptacidiphilus. :
            Df   Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.004291 0.0021454  0.1442 0.8713
Residuals    3 0.044621 0.0148737               

 Response Bacteria.Actinobacteria.Streptosporangium. :
            Df    Sum Sq   Mean Sq F value  Pr(>F)  
Timepoint    2 0.0137733 0.0068867  27.703 0.01164 *
Residuals    3 0.0007458 0.0002486                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Actinobacteria.Thermobifida. :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.0087797 0.0043898  1.9496 0.2867
Residuals    3 0.0067552 0.0022517               

 Response Bacteria.Actinobacteria.Thermomonospora. :
            Df  Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.00903 0.004515  0.1292 0.8834
Residuals    3 0.10485 0.034951               

 Response Bacteria.Alphaproteobacteria.Rhodoplanes. :
            Df  Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.20097 0.100483  1.4023 0.3716
Residuals    3 0.21497 0.071656               

 Response Bacteria.Bacteroidetes.Alkalitalea. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.078465 0.039233  1.0123 0.4614
Residuals    3 0.116269 0.038756               

 Response Bacteria.Bacteroidetes.Niastella. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 7.7860e-05 3.8930e-05  1.3679 0.3783
Residuals    3 8.5376e-05 2.8459e-05               

 Response Bacteria.Betaproteobacteria.Rhizobacter. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.097226 0.048613  1.1257 0.4318
Residuals    3 0.129554 0.043185               

 Response Bacteria.Chloroflexi.Anaerolinea. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1.1939 0.59694  0.5768 0.6138
Residuals    3 3.1047 1.03489               

 Response Bacteria.Chloroflexi.Herpetosiphon. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.073961 0.036980  0.5227 0.6386
Residuals    3 0.212246 0.070749               

 Response Bacteria.Chloroflexi.Pelolinea. :
            Df   Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.011915 0.0059574  0.2224 0.8127
Residuals    3 0.080355 0.0267852               

 Response Bacteria.Chloroflexi.Roseiflexus. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.25570 0.12785  0.7113 0.5587
Residuals    3 0.53921 0.17974               

 Response Bacteria.Chloroflexi.Sphaerobacter. :
            Df  Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.14094 0.070470  2.0791 0.2713
Residuals    3 0.10168 0.033895               

 Response Bacteria.Deltaproteobacteria.Desulfobacca. :
            Df  Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.26282 0.131412  1.7055 0.3201
Residuals    3 0.23115 0.077051               

 Response Bacteria.Deltaproteobacteria.Desulfobacula. :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.0042796 0.0021398  0.7241 0.5539
Residuals    3 0.0088652 0.0029551               

 Response Bacteria.Deltaproteobacteria.Geobacter. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2.0399 1.01997  1.0622 0.4479
Residuals    3 2.8807 0.96022               

 Response Bacteria.Deltaproteobacteria.Labilithrix. :
            Df  Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.23870 0.119349  4.4329 0.1271
Residuals    3 0.08077 0.026923               

 Response Bacteria.Deltaproteobacteria.Stigmatella. :
            Df   Sum Sq  Mean Sq F value  Pr(>F)  
Timepoint    2 0.269432 0.134716  9.4202 0.05091 .
Residuals    3 0.042902 0.014301                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Bacteria.Deltaproteobacteria.Syntrophobacter. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.049322 0.024661  0.3472 0.7318
Residuals    3 0.213107 0.071036               

 Response Bacteria.Deltaproteobacteria.Syntrophus. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.57317 0.28658  1.6773 0.3244
Residuals    3 0.51258 0.17086               

 Response Bacteria.Deltaproteobacteria.Vulgatibacter. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.100681 0.050340  3.2288 0.1787
Residuals    3 0.046773 0.015591               

 Response Bacteria.Firmicutes.Clostridia.Anoxybacter :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.055540 0.027770  1.5626 0.3428
Residuals    3 0.053316 0.017772               

 Response Bacteria.Firmicutes.Clostridia.Carboxydocella :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.023846 0.011923  0.6326 0.5899
Residuals    3 0.056540 0.018847               

 Response Bacteria.Firmicutes.Clostridia.Pelotomaculum :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 0.045009 0.022505  1.8354 0.3016
Residuals    3 0.036784 0.012261               

 Response Bacteria.Gammaproteobacteria.Others.Steroidobacter :
            Df   Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.010112 0.0050558  1.2535 0.4021
Residuals    3 0.012100 0.0040334               
## Run ANOVA for each category of interest (significant in MANOVA)

# Acidobacteria
#ws_mt_taxa_stats1<-aov(Acidobacteria~Timepoint,data=ws_mt_taxa_stats)
#summary.aov(ws_mt_taxa_stats1)
#TukeyHSD(ws_mt_taxa_stats1)

Alpha Diversity

# Richness: Sum up the number of non-zero entries per row
alpha.rna.taxa.rich <- apply(alpha.rna.taxa>0,1,sum)
write.csv(alpha.rna.taxa.rich, 'Ribo.Results/alpha.rna.taxa.rich.csv')

# Abundance: sum up the number of non-zero entries per row (1)
alpha.rna.taxa.abund <- apply(alpha.rna.taxa,1,sum)
write.csv(alpha.rna.taxa.abund, 'Ribo.Results/alpha.rna.taxa.abund.csv')

# Diversity: Shannon-Wiener Index (H')
alpha.rna.taxa.div <- diversity(alpha.rna.taxa, index="shannon")
write.csv(alpha.rna.taxa.div, 'Ribo.Results/alpha.rna.taxa.div.csv')

Run paired t-test to determine significance.

t.test(alpha.rna.taxa.t.test$Tuss,alpha.rna.taxa.t.test$WS,paired=TRUE)

    Paired t-test

data:  alpha.rna.taxa.t.test$Tuss and alpha.rna.taxa.t.test$WS
t = -29.477, df = 5, p-value = 8.425e-07
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.8021059 -0.6734298
sample estimates:
mean of the differences 
             -0.7377679 

Beta Diversity

Calculate the Bray-Curtis dissimilarity matrix to use with adonis

# Make tpm_all_groups object
beta.rna.taxa_sample<-c("ws1-T0","ws3-T0","tuss1-T0","tuss2-T0","ws1-T4","ws2-T4","ws1-T24","ws3-T24","tuss1-T4","tuss2-T4","tuss1-T24","tuss3-T24")
beta.rna.taxa_veg<-c("WS","WS","TUSS","TUSS","WS","WS","WS","WS","TUSS","TUSS","TUSS","TUSS")
beta.rna.taxa_time<-c("T0","T0","T0","T0","T4","T4","T24","T24","T4","T4","T24","T24")
beta.rna.taxa_groups<-data.frame(beta.rna.taxa_sample,beta.rna.taxa_veg,beta.rna.taxa_time)

# Convert the values in Column 1 ("tpm_sample") into row names
rownames(beta.rna.taxa_groups)<-beta.rna.taxa_groups[,1]
beta.rna.taxa_groups<-beta.rna.taxa_groups[,-1]
# Bray-Curtis Dissimilarity Matrix for tpm_all_taxa_beta
rna.tpm.taxa.bc.dist<-vegdist(beta.rna.taxa, method = "bray")

Run PERMANOVA using adonis function of the Vegan package

PERMANOVA - MT-TPM-Taxa - Bray-Curtis

adonis(rna.tpm.taxa.bc.dist~beta.rna.taxa_veg*beta.rna.taxa_time, data=beta.rna.taxa_groups)

Call:
adonis(formula = rna.tpm.taxa.bc.dist ~ beta.rna.taxa_veg * beta.rna.taxa_time,      data = beta.rna.taxa_groups) 

Permutation: free
Number of permutations: 999

Terms added sequentially (first to last)

                                     Df SumsOfSqs MeanSqs F.Model      R2 Pr(>F)    
beta.rna.taxa_veg                     1    2.1184 2.11837 21.8967 0.63221  0.001 ***
beta.rna.taxa_time                    2    0.3436 0.17179  1.7758 0.10254  0.154    
beta.rna.taxa_veg:beta.rna.taxa_time  2    0.3083 0.15415  1.5934 0.09201  0.211    
Residuals                             6    0.5805 0.09674         0.17324           
Total                                11    3.3507                 1.00000           
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

7.2. Gene Diversity

Alpha diversity of each expressed, annotated metatranscriptome was assessed by the Shannon index. For beta diversity, pairwise similarities among metatranscriptomes were calculated using Bray-Curtis similarity values and visualized with principle coordinates analysis. The difference between treatments was assessed with PERMANOVA.

7.2.1. Alpha Diversity

We calculated alpha diversity based on raw gene counts. Measurements include Richness, Abundance, and Shannon-Wiener Diversity Index (H’).

# Subset the tpm_all_exp_ann file to prepare for beta diversity analysis
cts_rna_all_alpha<-subset(cts_rna_exp_annotated, select=c(S108379,S108381,S108382,S108383,S108385,S108386,S108388,S108390,S108391,S108392,S108394,S108396))
names(cts_rna_all_alpha)<-c("WS1-T0","WS3-T0","Tuss1-T0","Tuss2-T0","WS1-T4","WS2-T4","WS1-T24","WS3-T24","Tuss1-T4","Tuss2-T4","Tuss1-T24","Tuss3-T24")

# Transpose all but the first column ("ID")
cts_rna_all_alpha<-as.data.frame(t(cts_rna_all_alpha))

Richness: Determine the number of unique genecalls that have more than one count recorded within each sample.

# Sum up the number of non-zero entries per row
apply(cts_rna_all_alpha>0,1,sum)
   WS1-T0    WS3-T0  Tuss1-T0  Tuss2-T0    WS1-T4    WS2-T4   WS1-T24   WS3-T24  Tuss1-T4  Tuss2-T4 
   265016    238163    147445    130228    250164    236363    189178    152912    144608    123479 
Tuss1-T24 Tuss3-T24 
   122748    108902 

Abundance: Determine the total abundance of individual genecalls

# sum up the number of non-zero entries per row (1)
apply(cts_rna_all_alpha,1,sum)
   WS1-T0    WS3-T0  Tuss1-T0  Tuss2-T0    WS1-T4    WS2-T4   WS1-T24   WS3-T24  Tuss1-T4  Tuss2-T4 
  3676101   2970625   2182064   1558718   3277106   3780598   1816840   1097027   2447254   2395566 
Tuss1-T24 Tuss3-T24 
  1828558   1205803 

Shannon-Wiener Diversity Index (H’): An information index that quantifies the uncertainty associated with predicting the identity of a new genecall given the total number of genecalls and the evenness in count abundances within each genecall.

diversity(cts_rna_all_alpha, index="shannon")
   WS1-T0    WS3-T0  Tuss1-T0  Tuss2-T0    WS1-T4    WS2-T4   WS1-T24   WS3-T24  Tuss1-T4  Tuss2-T4 
10.912618 10.786026  9.418039  9.541670 10.828631 10.545861 10.745632 10.759326  9.678131  9.297989 
Tuss1-T24 Tuss3-T24 
 9.577669  9.371202 

The following table is a summary of the Alpha Diversity on the raw gene counts for the Expressed Annotated Genes (expressed annotated genes for downstream analyses) by sample.

Alpha Diversity for Expressed Annotated Genecalls in the RNA-based metatranscriptome sequencing dataset
ID Tundra Time Replicate Gene Richness Gene Abundance Gene Diversity (H')
S108379 Tussock T0 1 147,445 2,182,064 9.418
S108381 Tussock T0 2 130,228 1,558,718 9.542
S108382 Tussock T4 1 144,608 2,447,254 9.678
S108383 Tussock T4 2 123,479 2,395,566 9.298
S108385 Tussock T24 1 122,748 1,828,558 9.578
S108386 Tussock T24 3 108,902 1,205,803 9.371
S108388 Wet Sedge T0 1 265,016 3,676,101 10.913
S108390 Wet Sedge T0 3 238,163 2,970,625 10.786
S108391 Wet Sedge T4 1 250,164 3,277,106 10.829
S108392 Wet Sedge T4 2 236,363 3,780,598 10.546
S108394 Wet Sedge T24 1 189,178 1,816,840 10.746
S108396 Wet Sedge T24 3 152,912 1,097,027 10.759

Run paired t-test to determine significance.

t.test(alpha.t.test$Tuss,alpha.t.test$WS,paired=TRUE)

    Paired t-test

data:  alpha.t.test$Tuss and alpha.t.test$WS
t = -23.496, df = 5, p-value = 2.6e-06
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1.422629 -1.142037
sample estimates:
mean of the differences 
              -1.282333 

Plot the Alpha Diversity summary.

# Re-arrange samples for plotting PCoA
alpha$Tundra <- factor(alpha$Tundra, levels=c("Tuss-MT-T0","Tuss-MT-T4","Tuss-MT-T24","WS-MT-T0","WS-MT-T4","WS-MT-T24"))

alpha.boxplot<-ggplot(alpha, aes(x=Tundra, y=H, fill=Tundra)) + 
    geom_boxplot() + ylab(expression(atop("Shannon-Wiener", paste("Diversity Index (H')")))) + theme_classic() + theme(axis.title.x=element_blank(), axis.text=element_text(size=10), axis.text.x = element_text(angle = 270, hjust=0, vjust=0.5), axis.title=element_text(size=12), legend.position = "none", legend.title=element_blank(), legend.text=element_text(size=10)) + ylim(9,12) + annotate(geom="text", x=3.5, y=11.9, label="Paired t-test") + annotate("text", x=3.5, y=11.7, size=3, label = "Tundra~(italic(p) < 0.001)", parse = TRUE) + scale_fill_manual(values=c("palegreen", "green3", "darkgreen", "lightskyblue1", "dodgerblue1", "midnightblue"), breaks=c("Tuss-MG-T0", "WS-MG-T0", "Tuss-MG-T4", "WS-MG-T4", "Tuss-MG-T24", "WS-MG-T24"), labels=c("Tuss-MG-T0", "WS-MG-T0", "Tuss-MG-T4", "WS-MG-T4", "Tuss-MG-T24", "WS-MG-T24"))
alpha.boxplot

7.2.2. Beta Diversity

We calculated beta diversity as the variation in gene expression between our two tundra ecosystems using Bray-Curtis similarity values.

7.2.2.1. Subset Data

First, subset the columns of interest from the tpm_all_exp_ann object (ID and all samples) to analyze the beta diversity of both ecosystems together. Create a tpm_groups object with columns for sample ID, vegetation type, and timepoint to be used for calculating pairwise similiarities among samples via PERMANOVA (adonis from Vegan package)

# Subset the tpm_all_exp_ann file to prepare for beta diversity analysis
tpm_all_beta<-subset(tpm_all_exp_ann, select=c(ID,S108379,S108381,S108382,S108383,S108385,S108386,S108388,S108390,S108391,S108392,S108394,S108396))
names(tpm_all_beta)<-c("ID","WS1-T0","WS3-T0","Tuss1-T0","Tuss2-T0","WS1-T4","WS2-T4","WS1-T24","WS3-T24","Tuss1-T4","Tuss2-T4","Tuss1-T24","Tuss3-T24")

# Remember "ID" column as non-numeric values
tpm_all_beta_ID<-tpm_all_beta$ID

# Transpose all but the first column ("ID")
tpm_all_beta<-as.data.frame(t(tpm_all_beta[,-1]))
colnames(tpm_all_beta)<-tpm_all_beta_ID

# Make tpm_all_groups object
tpm_all_sample<-c("WS1-T0","WS3-T0","Tuss1-T0","Tuss2-T0","WS1-T4","WS2-T4","WS1-T24","WS3-T24","Tuss1-T4","Tuss2-T4","Tuss1-T24","Tuss3-T24")
tpm_all_veg<-c("WS","WS","TUSS","TUSS","WS","WS","WS","WS","TUSS","TUSS","TUSS","TUSS")
tpm_all_time<-c("T0","T0","T0","T0","T4","T4","T24","T24","T4","T4","T24","T24")
tpm_all_groups<-data.frame(tpm_all_sample,tpm_all_veg,tpm_all_time)

# Convert the values in Column 1 ("tpm_sample") into row names
rownames(tpm_all_groups)<-tpm_all_groups[,1]
tpm_all_groups<-tpm_all_groups[,-1]

Second, subset the columns of interest from the tpm_ws_exp_ann object (ID and all samples) to analyze the beta diversity of the Wet Sedge ecosystem

# Subset the tpm_ws_exp_ann file to prepare for beta diversity analysis
tpm_ws_beta<-subset(tpm_all_exp_ann, select=c(ID,S108379,S108381,S108385,S108386,S108388,S108390))
names(tpm_ws_beta)<-c("ID","WS1-T0","WS3-T0","WS1-T4","WS2-T4","WS1-T24","WS3-T24")

# Remember "ID" column as non-numeric values
tpm_ws_beta_ID<-tpm_ws_beta$ID

# Transpose all but the first column ("ID")
tpm_ws_beta<-as.data.frame(t(tpm_ws_beta[,-1]))
colnames(tpm_ws_beta)<-tpm_ws_beta_ID

# Make tpm_ws_groups object
tpm_ws_sample<-c("WS1-T0","WS3-T0","WS1-T4","WS2-T4","WS1-T24","WS3-T24")
tpm_ws_veg<-c("WS","WS","WS","WS","WS","WS")
tpm_ws_time<-c("T0","T0","T4","T4","T24","T24")
tpm_ws_groups<-data.frame(tpm_ws_sample,tpm_ws_veg,tpm_ws_time)

# Convert the values in Column 1 ("tpm_sample") into row names
rownames(tpm_ws_groups)<-tpm_ws_groups[,1]
tpm_ws_groups<-tpm_ws_groups[,-1]

Third, subset the columns of interest from the tpm_tuss_exp_ann object (ID and all samples) to analyze the beta diversity of the Tussock ecosystem

# Subset the tpm_tuss_exp_ann file to prepare for beta diversity analysis
tpm_tuss_beta<-subset(tpm_all_exp_ann, select=c(ID,S108382,S108383,S108391,S108392,S108394,S108396))
names(tpm_tuss_beta)<-c("ID","Tuss1-T0","Tuss2-T0","Tuss1-T4","Tuss2-T4","Tuss1-T24","Tuss3-T24")

# Remember "ID" column as non-numeric values
tpm_tuss_beta_ID<-tpm_tuss_beta$ID

# Transpose all but the first column ("ID")
tpm_tuss_beta<-as.data.frame(t(tpm_tuss_beta[,-1]))
colnames(tpm_tuss_beta)<-tpm_tuss_beta_ID

# Make tpm_tuss_groups object
tpm_tuss_sample<-c("Tuss1-T0","Tuss2-T0","Tuss1-T4","Tuss2-T4","Tuss1-T24","Tuss3-T24")
tpm_tuss_veg<-c("TUSS","TUSS","TUSS","TUSS","TUSS","TUSS")
tpm_tuss_time<-c("T0","T0","T4","T4","T24","T24")
tpm_tuss_groups<-data.frame(tpm_tuss_sample,tpm_tuss_veg,tpm_tuss_time)

# Convert the values in Column 1 ("tpm_sample") into row names
rownames(tpm_tuss_groups)<-tpm_tuss_groups[,1]
tpm_tuss_groups<-tpm_tuss_groups[,-1]
7.2.2.2. Bray-Curtis

Calculate the Bray-Curtis dissimilarity matrix to use with adonis

# Bray-Curtis Dissimilarity Matrix for tpm_all_beta
tpm.all.bc.dist<-vegdist(tpm_all_beta, method = "bray")

# Bray-Curtis Dissimilarity Matrix for tpm_ws_beta
tpm.ws.bc.dist<-vegdist(tpm_ws_beta, method = "bray")

# Bray-Curtis Dissimilarity Matrix for tpm_tuss_beta
tpm.tuss.bc.dist<-vegdist(tpm_tuss_beta, method = "bray")
7.2.2.3. PCoA Plots

Principal coordinates analysis (PCoA, also known as metric multidimensional scaling) attempts to represent the distances between samples in a low-dimensional, Euclidean space. In particular, it maximizes the linear correlation between the distances in the distance matrix, and the distances in a space of low dimension (typically, 2 or 3 axes are selected).

The first step of a PCoA is the construction of a (dis)similarity matrix. While PCA (principal component analysis) is based on Euclidean distances, PCoA can handle (dis)similarity matrices calculated from quantitative, semi-quantitative, qualitative, and mixed variables. As always, the choice of (dis)similarity measure is critical and must be suitable to the data in question. For count data, Bray-Curtis distance is recommended. You can use Jaccard index for presence/absence data. When the distance metric is Euclidean, PCoA is equivalent to PCA.

The first PCoA compares similarity between tundra ecosystems by incorporating the combined dataset.

# Run PCoA analysis on the Bray-Curtis dissimilarity matrix
tpm.all.bc.pcoa<-pcoa(tpm.all.bc.dist)

Extract the eigenvalues and calculate the variation explained by each axis.

pcoa.all<-cmdscale(tpm.all.bc.dist, eig=TRUE, k=2)
pcoa.all
$points
                [,1]         [,2]
WS1-T0    -0.4377394  0.030397881
WS3-T0    -0.4160635  0.023158270
Tuss1-T0   0.3951114  0.297624418
Tuss2-T0   0.3946852  0.305317523
WS1-T4    -0.4423050  0.012303942
WS2-T4    -0.4164105  0.028136246
WS1-T24   -0.4327351  0.009686452
WS3-T24   -0.3001615 -0.107702022
Tuss1-T4   0.4351273 -0.142104048
Tuss2-T4   0.4364641 -0.014062350
Tuss1-T24  0.4482202 -0.084366006
Tuss3-T24  0.3358067 -0.358390306

$eig
 [1] 2.016506e+00 3.518486e-01 2.784335e-01 2.155332e-01 1.530410e-01 1.220625e-01 1.103878e-01
 [8] 8.587274e-02 7.453914e-02 6.800370e-02 5.258858e-02 5.170945e-17

$x
NULL

$ac
[1] 0

$GOF
[1] 0.671147 0.671147
# Calculate the percent variation explained by Axis 1
pcoa.all.exp.var1<-round(pcoa.all$eig[1] / sum(pcoa.all$eig), 2) * 100
pcoa.all.exp.var1
[1] 57
# Calculate the percent variation explained by Axis 2
pcoa.all.exp.var2<-round(pcoa.all$eig[2] / sum(pcoa.all$eig), 2) * 100
pcoa.all.exp.var2
[1] 10
# Sum the percent variation explained by both axes
pcoa.all.sum.eig<-sum(pcoa.all.exp.var1, pcoa.all.exp.var2)
pcoa.all.sum.eig
[1] 67

Plot the PCoA.

# Extract the plot scores from first two PCoA axes
tpm.all.bc.pcoa.axes <- tpm.all.bc.pcoa$vectors[,c(1,2)]

# Create new object with PCoA axes
all.bc.pcoa<-data.frame(tpm.all.bc.pcoa.axes)

# Add Timepoint variable to the dataframe
all.timepoint<-c('WS-MT-T0','WS-MT-T0','Tuss-MT-T0','Tuss-MT-T0','WS-MT-T4','WS-MT-T4','WS-MT-T24','WS-MT-T24','Tuss-MT-T4','Tuss-MT-T4','Tuss-MT-T24','Tuss-MT-T24')
all.pcoa.1<-all.bc.pcoa$Axis.1
all.pcoa.2<-all.bc.pcoa$Axis.2
all.bc.pcoa<-data.frame(all.timepoint,all.pcoa.1,all.pcoa.2)

# Rename column headings
colnames(all.bc.pcoa)<-c("Timepoint","PCoA_1","PCoA_2")

# Re-arrange samples for plotting PCoA
all.bc.pcoa$Timepoint <- factor(all.bc.pcoa$Timepoint, levels=c("Tuss-MT-T0","WS-MT-T0","Tuss-MT-T4","WS-MT-T4","Tuss-MT-T24","WS-MT-T24"))

# Plot the PCoA
all.pcoa<-ggplot(data=all.bc.pcoa, aes(x=PCoA_1, y=PCoA_2, group=Timepoint, color=Timepoint)) + geom_point(aes(shape=Timepoint, size=0.75, fill=Timepoint)) + scale_fill_manual(values=c("palegreen","lightskyblue1","green3","dodgerblue1","darkgreen","midnightblue")) + scale_shape_manual(values=c(21,21,22,22,24,24)) + scale_color_manual(values=c("black","black","black","black","black","black")) + xlab("PCoA 1 (57%)") + ylab("PCoA 2 (10%)") + theme_classic() + theme(axis.text=element_text(size=10), axis.title=element_text(size=12), legend.position = "bottom", legend.title=element_blank(), legend.text=element_text(size=10)) + guides(shape = guide_legend(override.aes = list(size = 3))) + scale_size(guide="none") + geom_hline(aes(yintercept = 0), color="gray", linetype="dashed") + geom_vline(aes(xintercept=0), color="gray", linetype="dashed") + ylim(-0.6,0.6) + xlim(-0.6,0.6) + annotate(geom="text", x=0.0, y=0.59, label="PERMANOVA")   + annotate("text", x = 0, y = 0.52, size=3, label = "Tundra~(italic(p) == 0.001)", parse = TRUE) + annotate("text", x = 0, y = 0.45, size=3, label = "Time~Point~(italic(p) == 0.171)", parse = TRUE) + annotate("text", x = 0, y = 0.38, size=3, label = "Tundra:Time~Point~(italic(p) == 0.226)", parse = TRUE)
all.pcoa

The second PCoA compares similarity between sampling time points within the Tussock tundra ecosystem.

# Run PCoA analysis on the Bray-Curtis dissimilarity matrix
tpm.tuss.bc.pcoa<-pcoa(tpm.tuss.bc.dist)

Extract the eigenvalues and calculate the variation explained by each axis.

pcoa.tuss<-cmdscale(tpm.tuss.bc.dist, eig=TRUE, k=2)
pcoa.tuss
$points
                 [,1]        [,2]
Tuss1-T0  -0.30365268  0.11026379
Tuss2-T0  -0.31292950  0.10833684
Tuss1-T4   0.15076219 -0.20670711
Tuss2-T4   0.01964313 -0.24828600
Tuss1-T24  0.08858266 -0.07022686
Tuss3-T24  0.35759420  0.30661935

$eig
[1] 3.489654e-01 2.272160e-01 1.534762e-01 8.675773e-02 6.818989e-02 2.949487e-17

$x
NULL

$ac
[1] 0

$GOF
[1] 0.651343 0.651343
# Calculate the percent variation explained by Axis 1
pcoa.tuss.exp.var1<-round(pcoa.tuss$eig[1] / sum(pcoa.tuss$eig), 2) * 100
pcoa.tuss.exp.var1
[1] 39
# Calculate the percent variation explained by Axis 2
pcoa.tuss.exp.var2<-round(pcoa.tuss$eig[2] / sum(pcoa.tuss$eig), 2) * 100
pcoa.tuss.exp.var2
[1] 26
# Sum the percent variation explained by both axes
pcoa.tuss.sum.eig<-sum(pcoa.tuss.exp.var1, pcoa.tuss.exp.var2)
pcoa.tuss.sum.eig
[1] 65

Plot the PCoA.

# Extract the plot scores from first two PCoA axes
tpm.tuss.bc.pcoa.axes <- tpm.tuss.bc.pcoa$vectors[,c(1,2)]

# Create new object with PCoA axes
tuss.bc.pcoa<-data.frame(tpm.tuss.bc.pcoa.axes)

# Add Timepoint variable to the dataframe
tuss.timepoint<-c('Tuss-T0','Tuss-T0','Tuss-T4','Tuss-T4','Tuss-T24','Tuss-T24')
tuss.pcoa.1<-tuss.bc.pcoa$Axis.1
tuss.pcoa.2<-tuss.bc.pcoa$Axis.2
tuss.bc.pcoa<-data.frame(tuss.timepoint,tuss.pcoa.1,tuss.pcoa.2)

# Rename column headings
colnames(tuss.bc.pcoa)<-c("Timepoint","PCoA_1","PCoA_2")
#tuss.bc.pcoa

# Re-arrange samples for plotting PCoA
tuss.bc.pcoa$Timepoint<-factor(tuss.bc.pcoa$Timepoint, levels=c("Tuss-T0","Tuss-T4","Tuss-T24"))

# Plot the PCoA
tuss.pcoa<-ggplot(data=tuss.bc.pcoa, aes(x=PCoA_1, y=PCoA_2, group=Timepoint, color=Timepoint)) + geom_point(aes(shape=Timepoint, size=0.75, fill=Timepoint)) + scale_fill_manual(values=c("palegreen","green3","darkgreen")) + scale_shape_manual(values=c(21,24,22)) + scale_color_manual(values=c("black","black","black")) + xlab("PCoA 1 (39%)") + ylab("PCoA 2 (26%)") + theme_minimal() + theme(axis.text=element_text(size=12),axis.title=element_text(size=14))+ theme(legend.position = "bottom", legend.title=element_blank(), legend.text=element_text(size=12), panel.background = element_blank(), panel.grid.major=element_blank(), panel.grid.minor = element_blank(), axis.line = element_line(colour = "gray"), panel.border = element_rect(colour = "gray", fill=NA, size=1)) + scale_size(guide=FALSE) + guides(shape = guide_legend(override.aes = list(size = 3))) + geom_hline(aes(yintercept = 0), color="gray", linetype="dashed") + geom_vline(aes(xintercept=0), color="gray", linetype="dashed") + ylim(-0.5,0.5) + xlim(-0.5,0.5) + annotate(geom="text", x=0.0, y=0.49, label="PERMANOVA") + annotate("text", x = 0, y = 0.42, size=3, label = "Time~Point~(italic(p) == 0.067)", parse = TRUE)
tuss.pcoa

The third PCoA compares similarity between sampling time points within the Wet Sedge tundra ecosystem.

# Run PCoA analysis on the Bray-Curtis dissimilarity matrix
tpm.ws.bc.pcoa<-pcoa(tpm.ws.bc.dist)

Extract the eigenvalues and calculate the variation explained by each axis.

pcoa.ws<-cmdscale(tpm.ws.bc.dist, eig=TRUE, k=2)
pcoa.ws
$points
               [,1]        [,2]
WS1-T0   0.12542270  0.13122361
WS3-T0   0.08716127 -0.16515464
WS1-T4   0.06687703  0.16211299
WS2-T4   0.14921322 -0.20414083
WS1-T24  0.05526330  0.10073221
WS3-T24 -0.48393753 -0.02477334

$eig
[1]  2.873146e-01  1.232105e-01  1.105396e-01  7.457974e-02  5.269727e-02 -3.869650e-17

$x
NULL

$ac
[1] 0

$GOF
[1] 0.6331925 0.6331925
# Calculate the percent variation explained by Axis 1
pcoa.ws.exp.var1<-round(pcoa.ws$eig[1] / sum(pcoa.ws$eig), 2) * 100
pcoa.ws.exp.var1
[1] 44
# Calculate the percent variation explained by Axis 2
pcoa.ws.exp.var2<-round(pcoa.ws$eig[2] / sum(pcoa.ws$eig), 2) * 100
pcoa.ws.exp.var2
[1] 19
# Sum the percent variation explained by both axes
pcoa.ws.sum.eig<-sum(pcoa.ws.exp.var1, pcoa.ws.exp.var2)
pcoa.ws.sum.eig
[1] 63

Plot the PCoA.

# Extract the plot scores from first two PCoA axes
tpm.ws.bc.pcoa.axes <- tpm.ws.bc.pcoa$vectors[,c(1,2)]

# Create new object with PCoA axes
ws.bc.pcoa<-data.frame(tpm.ws.bc.pcoa.axes)

# Add Timepoint variable to the dataframe
ws.timepoint<-c('WS-T0','WS-T0','WS-T4','WS-T4','WS-T24','WS-T24')
ws.pcoa.1<-ws.bc.pcoa$Axis.1
ws.pcoa.2<-ws.bc.pcoa$Axis.2
ws.bc.pcoa<-data.frame(ws.timepoint,ws.pcoa.1,ws.pcoa.2)

# Rename column headings
colnames(ws.bc.pcoa)<-c("Timepoint","PCoA_1","PCoA_2")
#ws.bc.pcoa

# Re-arrange samples for plotting PCoA
ws.bc.pcoa$Timepoint<-factor(ws.bc.pcoa$Timepoint, levels=c("WS-T0","WS-T4","WS-T24"))

# Plot the PCoA
ws.pcoa<-ggplot(data=ws.bc.pcoa, aes(x=PCoA_1, y=PCoA_2, group=Timepoint, color=Timepoint)) + geom_point(aes(shape=Timepoint, size=0.75, fill=Timepoint)) + scale_fill_manual(values=c("lightskyblue1","dodgerblue1","midnightblue")) + scale_shape_manual(values=c(21,24,22)) + scale_color_manual(values=c("black","black","black")) + xlab("PCoA 1 (44%)") + ylab("PCoA 2 (19%)") + theme_minimal() + theme(axis.text=element_text(size=12),axis.title=element_text(size=14))+ theme(legend.position = "bottom", legend.title=element_blank(), legend.text=element_text(size=12), panel.background = element_blank(), panel.grid.major=element_blank(), panel.grid.minor = element_blank(), axis.line = element_line(colour = "gray"), panel.border = element_rect(colour = "gray", fill=NA, size=1)) + scale_size(guide=FALSE) + guides(shape = guide_legend(override.aes = list(size = 3))) + geom_hline(aes(yintercept = 0), color="gray", linetype="dashed") + geom_vline(aes(xintercept=0), color="gray", linetype="dashed") + ylim(-0.5,0.5) + xlim(-0.5,0.5) + annotate(geom="text", x=0.0, y=0.49, label="PERMANOVA") + annotate("text", x = 0, y = 0.42, size=3, label = "Time~Point~(italic(p) == 0.333)", parse = TRUE)
ws.pcoa

7.2.2.4. PERMANOVA
  • Run PERMANOVA using adonis function of the Vegan package

PERMANOVA - TPM-All - Bray-Curtis

adonis(tpm.all.bc.dist~tpm_all_veg*tpm_all_time, data=tpm_all_groups)

Call:
adonis(formula = tpm.all.bc.dist ~ tpm_all_veg * tpm_all_time,      data = tpm_all_groups) 

Permutation: free
Number of permutations: 999

Terms added sequentially (first to last)

                         Df SumsOfSqs MeanSqs F.Model      R2 Pr(>F)    
tpm_all_veg               1    1.9959 1.99587 15.5588 0.56559  0.001 ***
tpm_all_time              2    0.3920 0.19602  1.5281 0.11109  0.158    
tpm_all_veg:tpm_all_time  2    0.3712 0.18562  1.4470 0.10520  0.225    
Residuals                 6    0.7697 0.12828         0.21811           
Total                    11    3.5288                 1.00000           
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

PERMANOVA - TPM-Tuss - Bray-Curtis

adonis(tpm.tuss.bc.dist~tpm_tuss_time, data=tpm_tuss_groups)
'nperm' >= set of all permutations: complete enumeration.
Set of permutations < 'minperm'. Generating entire set.

Call:
adonis(formula = tpm.tuss.bc.dist ~ tpm_tuss_time, data = tpm_tuss_groups) 

Permutation: free
Number of permutations: 719

Terms added sequentially (first to last)

              Df SumsOfSqs MeanSqs F.Model      R2  Pr(>F)  
tpm_tuss_time  2   0.49733 0.24867  1.9263 0.56221 0.06667 .
Residuals      3   0.38727 0.12909         0.43779          
Total          5   0.88461                 1.00000          
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

PERMANOVA - TPM-WS - Bray-Curtis

adonis(tpm.ws.bc.dist~tpm_ws_time, data=tpm_ws_groups)
'nperm' >= set of all permutations: complete enumeration.
Set of permutations < 'minperm'. Generating entire set.

Call:
adonis(formula = tpm.ws.bc.dist ~ tpm_ws_time, data = tpm_ws_groups) 

Permutation: free
Number of permutations: 719

Terms added sequentially (first to last)

            Df SumsOfSqs MeanSqs F.Model      R2 Pr(>F)
tpm_ws_time  2   0.26594 0.13297  1.0432 0.41018 0.3333
Residuals    3   0.38240 0.12747         0.58982       
Total        5   0.64834                 1.00000       

7.3. KEGG Tier Patterns

Look for differences in gene expression at multiple KEGG tier levels (II-IV) using TPM-normalized values.

7.3.1. Tussock Tundra

Look at differences in gene expression patterns for multiple Tier levels within the Tussock tundra between sampling time points.

7.3.1.1. Tier II Expression
# Calculate TPM-normalized gene count sums for each Tuss sample in each Tier II category
tuss_tII_sum<-tpm_all_exp_ann %>% group_by(Tier_II) %>% summarise_at(vars("S108382","S108383","S108391","S108392","S108394","S108396"), sum)

tuss_tII_sum<-tuss_tII_sum %>% mutate_at(vars(S108382,S108383,S108391,S108392,S108394,S108396), funs(round(., 0)))

tuss_tII_sum<-as.data.frame(tuss_tII_sum)

tuss_tII_sum<-tuss_tII_sum[order(-tuss_tII_sum$S108382),]

Heatmap for Tier II categories by sampling timepoints

# Create copy of "ws_tII_sum" object to prep for heatmap
tuss_tII_heatmap<-tuss_tII_sum

# Convert the first column (Tier categories) into rownames
rownames(tuss_tII_heatmap) <- tuss_tII_heatmap$Tier_II
tuss_tII_heatmap<-as.data.frame(tuss_tII_heatmap[-1])

# Rename columns to sample IDs
colnames(tuss_tII_heatmap)<-c("Tuss1-T0","Tuss2-T0","Tuss1-T4","Tuss2-T4","Tuss1-T24","Tuss3-T24")

# Remove rotuss for "Organismal Systems" and "Human Diseases"
#tuss_tII_heatmap <- tuss_tII_heatmap[-c(5,6),]

# Convert dataframe into a matrix for heatmap
tuss_tII_heatmap<-as.matrix(tuss_tII_heatmap)

# Scale matrix values to generate Z-scores
tuss_tII_heatmap<-scale(t(tuss_tII_heatmap))

tuss_tII_heatmap<-t(tuss_tII_heatmap)

# Specify RColorBrewer custom color palette
col <- colorRampPalette(brewer.pal(10, "RdYlBu"))(256)

# Pheatmap
pheatmap(tuss_tII_heatmap, treeheight_row = 0, treeheight_col = 0,cluster_rows = FALSE, cluster_cols = FALSE)

Summed values by replicate for each KEGG tier II category.

Tussock Tier II KEGG category summary by sample.
Tier_II S108382 S108383 S108391 S108392 S108394 S108396
4 Metabolism 674,830 630,044 400,527 364,021 412,576 389,480
3 Genetic Information Processing 236,019 273,627 464,898 522,501 494,641 481,859
2 Environmental Information Processing 55,429 61,322 44,986 37,602 41,299 73,752
1 Cellular Processes 33,722 35,007 89,589 75,876 51,484 54,909

Calculate mean values from the replicate sums

# Calculate mean values from the replicate sums
tuss_tII_sum$meantuss_T0<-apply(tuss_tII_sum[,2:3], 1, mean)
tuss_tII_sum$meantuss_T4<-apply(tuss_tII_sum[,4:5], 1, mean)
tuss_tII_sum$meantuss_T24<-apply(tuss_tII_sum[,6:7], 1, mean)
tuss_tII_sum<-tuss_tII_sum %>% mutate_at(vars(meantuss_T0,meantuss_T4,meantuss_T24), funs(round(., 0)))

# Calculate sd values from the replicate sums
tuss_tII_sum$sdtuss_T0<-apply(tuss_tII_sum[,2:3], 1, sd)
tuss_tII_sum$sdtuss_T4<-apply(tuss_tII_sum[,4:5], 1, sd)
tuss_tII_sum$sdtuss_T24<-apply(tuss_tII_sum[,6:7], 1, sd)
tuss_tII_sum<-tuss_tII_sum %>% mutate_at(vars(sdtuss_T0,sdtuss_T4,sdtuss_T24), funs(round(., 0)))

# Subset Mean values
tuss_tII_mean<-subset(tuss_tII_sum, select=c(Tier_II,meantuss_T0,meantuss_T4,meantuss_T24))
names(tuss_tII_mean)<-c("Tier II", "Tuss-T0", "Tuss-T4", "Tuss-T24")

# Subset SD values
tuss_tII_sd<-subset(tuss_tII_sum, select=c(Tier_II,sdtuss_T0,sdtuss_T4,sdtuss_T24))
names(tuss_tII_sd)<-c("Tier II", "Tuss-T0", "Tuss-T4", "Tuss-T24")

# Remember "Tier II" as non-numeric values
tuss_tII_mean_TierII<-tuss_tII_mean$`Tier II`
tuss_tII_sd_TierII<-tuss_tII_sd$`Tier II`

# Transpose all but first column (Tier II)
tuss_tII_mean<-as.data.frame(t(tuss_tII_mean[,-1]))
colnames(tuss_tII_mean)<-tuss_tII_mean_TierII
tuss_tII_sd<-as.data.frame(t(tuss_tII_sd[,-1]))
colnames(tuss_tII_sd)<-tuss_tII_sd_TierII

# Combine mean and sd into single column with ± divider
tuss_tII_table<-as.data.frame(do.call(cbind, lapply(1:ncol(tuss_tII_mean), function(i) paste0(tuss_tII_mean[ , i], " ± ", tuss_tII_sd[ , i]))))

# Transpose the table back
tuss_tII_table<-t(tuss_tII_table)

# Rename columns to Sites
colnames(tuss_tII_table)<-c("Tussock (T0)", "Tussock (T4)", "Tussock (T24)")

rownames(tuss_tII_table)<-tuss_tII_mean_TierII

kable(tuss_tII_table, caption = "Tussock Tier II KEGG category averages (± standard deviation) by sample.", format.args = list(big.mark=","), align = "l") %>% kable_styling(bootstrap_options = c("striped","hover","condensed"))
Tussock Tier II KEGG category averages (± standard deviation) by sample.
Tussock (T0) Tussock (T4) Tussock (T24)
Metabolism 652437 ± 31668 382274 ± 25814 401028 ± 16331
Genetic Information Processing 254823 ± 26593 493700 ± 40731 488250 ± 9038
Environmental Information Processing 58376 ± 4167 41294 ± 5221 57526 ± 22948
Cellular Processes 34364 ± 909 82732 ± 9697 53196 ± 2422

Run statistical tests to determine if significant differences exist between sampling timepoints for each Tier KEGG category. Click on the Show/Hide button to see the statistics.

# Subset the "sum" values for each sample
tuss_tII_stats<-subset(tuss_tII_sum, select=c(Tier_II,S108382,S108383,S108391,S108392,S108394,S108396))

rownames(tuss_tII_stats) <- tuss_tII_stats$Tier_II
tuss_tII_stats<-as.data.frame(t(tuss_tII_stats[-1]))

# Create a column with timepoint variable names
Timepoint<-c("T0","T0","T4","T4","T24","T24")
Timepoint<-data.frame(Timepoint)

# Add the timepoint column to the sum table
tuss_tII_stats<-data.frame(Timepoint,tuss_tII_stats)

# Subset response variables for MANOVA
tuss_tII_stats$response <- as.matrix(tuss_tII_stats[, 2:5])

# MANOVA test
tuss_tII_manova <- manova(response ~ Timepoint, data=tuss_tII_stats)
summary.aov(tuss_tII_manova)
 Response Metabolism. :
            Df     Sum Sq    Mean Sq F value   Pr(>F)   
Timepoint    2 9.1031e+10 4.5515e+10  70.532 0.003005 **
Residuals    3 1.9359e+09 6.4532e+08                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Genetic.Information.Processing. :
            Df     Sum Sq    Mean Sq F value   Pr(>F)   
Timepoint    2 7.4387e+10 3.7193e+10  45.581 0.005687 **
Residuals    3 2.4479e+09 8.1597e+08                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Environmental.Information.Processing. :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 370641156 185320578  0.9733 0.4723
Residuals    3 571224057 190408019               

 Response Cellular.Processes. :
            Df     Sum Sq    Mean Sq F value   Pr(>F)   
Timepoint    2 2377655296 1188827648  35.412 0.008192 **
Residuals    3  100714109   33571370                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Run ANOVA for each category of interest (significant in MANOVA)

# Metabolism
tuss_tII_aov1<-aov(Metabolism.~Timepoint,data=tuss_tII_stats)
summary.aov(tuss_tII_aov1)
            Df    Sum Sq   Mean Sq F value  Pr(>F)   
Timepoint    2 9.103e+10 4.552e+10   70.53 0.00301 **
Residuals    3 1.936e+09 6.453e+08                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tII_aov1)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Metabolism. ~ Timepoint, data = tuss_tII_stats)

$Timepoint
          diff       lwr        upr     p adj
T24-T0 -251409 -357562.5 -145255.55 0.0045100
T4-T0  -270163 -376316.5 -164009.55 0.0036586
T4-T24  -18754 -124907.5   87399.45 0.7607178
# Genetic Information Processing
tuss_tII_aov2<-aov(Genetic.Information.Processing.~Timepoint,data=tuss_tII_stats)
summary.aov(tuss_tII_aov2)
            Df    Sum Sq   Mean Sq F value  Pr(>F)   
Timepoint    2 7.439e+10 3.719e+10   45.58 0.00569 **
Residuals    3 2.448e+09 8.160e+08                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tII_aov2)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Genetic.Information.Processing. ~ Timepoint, data = tuss_tII_stats)

$Timepoint
           diff       lwr      upr     p adj
T24-T0 233427.0  114059.5 352794.5 0.0078490
T4-T0  238876.5  119509.0 358244.0 0.0073444
T4-T24   5449.5 -113918.0 124817.0 0.9802674
# Environmental Information Processing
tuss_tII_aov3<-aov(Environmental.Information.Processing.~Timepoint,data=tuss_tII_stats)
summary.aov(tuss_tII_aov3)
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 370641156 185320578   0.973  0.472
Residuals    3 571224057 190408019               
TukeyHSD(tuss_tII_aov3)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Environmental.Information.Processing. ~ Timepoint, data = tuss_tII_stats)

$Timepoint
           diff       lwr      upr     p adj
T24-T0   -850.0 -58512.09 56812.09 0.9979117
T4-T0  -17081.5 -74743.59 40580.59 0.5125718
T4-T24 -16231.5 -73893.59 41430.59 0.5405595
# Cellular Processing
tuss_tII_aov4<-aov(Cellular.Processes.~Timepoint,data=tuss_tII_stats)
summary.aov(tuss_tII_aov4)
            Df    Sum Sq   Mean Sq F value  Pr(>F)   
Timepoint    2 2.378e+09 1.189e+09   35.41 0.00819 **
Residuals    3 1.007e+08 3.357e+07                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tII_aov4)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Cellular.Processes. ~ Timepoint, data = tuss_tII_stats)

$Timepoint
        diff       lwr      upr     p adj
T24-T0 18832 -5380.089 43044.09 0.0934848
T4-T0  48368 24155.911 72580.09 0.0073816
T4-T24 29536  5323.911 53748.09 0.0295052

Plot the KEGG tier II categories as a barchart.

# Place the KEGG tier II categories in the preferred order for plotting
tuss_tII_bardata$Tier.II <- factor(tuss_tII_bardata$Tier.II,levels = c("Metabolism", "Genetic Information Processing", "Environmental Information Processing", "Cellular Processes"))

tuss_tII_bardata$Sample <- factor(tuss_tII_bardata$Sample,levels=c("Tuss-T0","Tuss-T4","Tuss-T24"))

tuss_tII_barplot<-ggplot(tuss_tII_bardata, aes(x = Tier.II, y = Mean, fill = Sample)) + geom_bar(stat = "identity", position = "dodge", color="black") + geom_errorbar(aes(ymin = Mean - SD, ymax = Mean + SD), width = 0.2, position = position_dodge(0.9)) + ylab(expression(atop("KEGG Tier II Categories", paste("Transcript Counts (TPM)")))) + theme_classic() + theme(axis.text=element_text(size=10), axis.title=element_text(size=12), axis.title.x=element_blank()) + theme(legend.position = "bottom", legend.title=element_blank(), legend.text=element_text(size=8), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank()) + scale_size(guide=FALSE) + scale_fill_manual(values=c("palegreen", "green3", "darkgreen")) + scale_x_discrete(labels = function(Tier.II) str_wrap(Tier.II, width = 10)) + scale_y_continuous(expand = c(0, 0), limits = c(0, 800000)) + annotate(geom="text", x=0.70, y=750000, label="a") + annotate(geom="text", x=1.0, y=475000, label="b") + annotate(geom="text", x=1.3, y=475000, label="b") + annotate(geom="text", x=1.7, y=350000, label="a") + annotate(geom="text", x=2.0, y=600000, label="b") + annotate(geom="text", x=2.3, y=600000, label="b") + annotate(geom="text", x=3.0, y=150000, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=3.7, y=100000, label="a") + annotate(geom="text", x=4.0, y=150000, label="b") + annotate(geom="text", x=4.3, y=120000, label="a")
tuss_tII_barplot

Plot the combined METAGENOME and METATRANSCRIPTOME KEGG tier II categories as a barchart.

# Place the KEGG tier II categories in the preferred order for plotting
tuss_mg_mt_tII_bardata$Tier.II <- factor(tuss_mg_mt_tII_bardata$Tier.II,levels = c("Metabolism", "Genetic Information Processing", "Environmental Information Processing", "Cellular Processes"))

tuss_mg_mt_tII_bardata$Sample <- factor(tuss_mg_mt_tII_bardata$Sample,levels=c("Tuss-MG","Tuss-MT-T0","Tuss-MT-T4","Tuss-MT-T24"))

tuss_mg_mt_tII_barplot<-ggplot(tuss_mg_mt_tII_bardata, aes(x = Tier.II, y = Mean, fill = Sample)) + geom_bar(stat = "identity", position = "dodge", color="black") + geom_errorbar(aes(ymin = Mean - SD, ymax = Mean + SD), width = 0.2, position = position_dodge(0.9)) + ylab(expression(atop("KEGG Tier II Categories", paste("Gene Counts")))) + theme_classic() + theme(axis.text=element_text(size=10), axis.title=element_text(size=12), axis.title.x=element_blank()) + theme(legend.position = "bottom", legend.title=element_blank(), legend.text=element_text(size=8), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank()) + scale_size(guide=FALSE) + scale_fill_manual(values=c("gray83","palegreen", "green3", "darkgreen")) + scale_x_discrete(labels = function(Tier.II) str_wrap(Tier.II, width = 10)) + scale_y_continuous(expand = c(0, 0), limits = c(0, 800000)) + annotate(geom="text", x=0.90, y=750000, label="a") + annotate(geom="text", x=1.12, y=475000, label="b") + annotate(geom="text", x=1.35, y=475000, label="b") + annotate(geom="text", x=1.9, y=350000, label="a") + annotate(geom="text", x=2.12, y=600000, label="b") + annotate(geom="text", x=2.35, y=600000, label="b") + annotate(geom="text", x=3.12, y=150000, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=3.9, y=100000, label="a") + annotate(geom="text", x=4.12, y=150000, label="b") + annotate(geom="text", x=4.35, y=120000, label="a")
tuss_mg_mt_tII_barplot

7.3.1.2. Tier III Expression

Calculate TPM-normalized gene count sums for each Tuss sample in each Tier III category.

# Calculate TPM-normalized gene count sums for each Tuss sample in each Tier III category
tuss_tIII_sum<-tpm_all_exp_ann %>% group_by(Tier_III) %>% summarise_at(vars("S108382","S108383","S108391","S108392","S108394","S108396"), sum)
tuss_tIII_sum<-tuss_tIII_sum %>% mutate_at(vars(S108382,S108383,S108391,S108392,S108394,S108396), funs(round(., 0)))
tuss_tIII_sum<-as.data.frame(tuss_tIII_sum)
tuss_tIII_sum<-tuss_tIII_sum[order(-tuss_tIII_sum$S108382),]
# Calculate mean values from the replicate sums
tuss_tIII_sum$meantuss_T0<-apply(tuss_tIII_sum[,2:3], 1, mean)
tuss_tIII_sum$meantuss_T4<-apply(tuss_tIII_sum[,4:5], 1, mean)
tuss_tIII_sum$meantuss_T24<-apply(tuss_tIII_sum[,6:7], 1, mean)
tuss_tIII_sum<-tuss_tIII_sum %>% mutate_at(vars(meantuss_T0,meantuss_T4,meantuss_T24), funs(round(., 0)))

# Calculate sd values from the replicate sums
tuss_tIII_sum$sdtuss_T0<-apply(tuss_tIII_sum[,2:3], 1, sd)
tuss_tIII_sum$sdtuss_T4<-apply(tuss_tIII_sum[,4:5], 1, sd)
tuss_tIII_sum$sdtuss_T24<-apply(tuss_tIII_sum[,6:7], 1, sd)
tuss_tIII_sum<-tuss_tIII_sum %>% mutate_at(vars(sdtuss_T0,sdtuss_T4,sdtuss_T24), funs(round(., 0)))

# Write data to .csv file
write.csv(tuss_tIII_sum, 'Norm.Results/tuss.rna.tIII.mean.sd.csv')

# Subset Mean values
tuss_tIII_mean<-subset(tuss_tIII_sum, select=c(Tier_III,meantuss_T0,meantuss_T4,meantuss_T24))
names(tuss_tIII_mean)<-c("Tier III", "Tuss-T0", "Tuss-T4", "Tuss-T24")

# Subset SD values
tuss_tIII_sd<-subset(tuss_tIII_sum, select=c(Tier_III,sdtuss_T0,sdtuss_T4,sdtuss_T24))
names(tuss_tIII_sd)<-c("Tier III", "Tuss-T0", "Tuss-T4", "Tuss-T24")

# Remember "Tier III" as non-numeric values
tuss_tIII_mean_TierIII<-tuss_tIII_mean$`Tier III`
tuss_tIII_sd_TierIII<-tuss_tIII_sd$`Tier III`

# Transpose all but first column (Tier II)
tuss_tIII_mean<-as.data.frame(t(tuss_tIII_mean[,-1]))
colnames(tuss_tIII_mean)<-tuss_tIII_mean_TierIII
tuss_tIII_sd<-as.data.frame(t(tuss_tIII_sd[,-1]))
colnames(tuss_tIII_sd)<-tuss_tIII_sd_TierIII

# Combine mean and sd into single column with ± divider
tuss_tIII_table<-as.data.frame(do.call(cbind, lapply(1:ncol(tuss_tIII_mean), function(i) paste0(tuss_tIII_mean[ , i], " ± ", tuss_tIII_sd[ , i]))))

# Transpose the table back
tuss_tIII_table<-t(tuss_tIII_table)

# Rename columns to Sites
colnames(tuss_tIII_table)<-c("Tussock (T0)", "Tussock (T4)", "Tussock (T24)")

rownames(tuss_tIII_table)<-tuss_tIII_mean_TierIII

Run statistical tests to determine if significant differences exist between sampling timepoints for each Tier KEGG category. Click on the Show/Hide button to see the statistics.

# Subset the "sum" values for each sample
tuss_tIII_stats<-subset(tuss_tIII_sum, select=c(Tier_III,S108382,S108383,S108391,S108392,S108394,S108396))

rownames(tuss_tIII_stats) <- tuss_tIII_stats$Tier_III
tuss_tIII_stats<-as.data.frame(t(tuss_tIII_stats[-1]))

# Add the timepoint column to the sum table
tuss_tIII_stats<-data.frame(Timepoint,tuss_tIII_stats)

# Subset response variables for MANOVA
tuss_tIII_stats$response <- as.matrix(tuss_tIII_stats[, 2:26])

# MANOVA test
tuss_tIII_manova <- manova(response ~ Timepoint, data=tuss_tIII_stats)
summary.aov(tuss_tIII_manova)
 Response Overview. :
            Df     Sum Sq    Mean Sq F value   Pr(>F)   
Timepoint    2 3.0956e+10 1.5478e+10  42.322 0.006333 **
Residuals    3 1.0971e+09 3.6571e+08                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Carbohydrate.metabolism. :
            Df     Sum Sq    Mean Sq F value   Pr(>F)   
Timepoint    2 9211461944 4605730972  50.218 0.004939 **
Residuals    3  275146619   91715540                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Translation. :
            Df     Sum Sq    Mean Sq F value  Pr(>F)  
Timepoint    2 1.3171e+10 6585386784  16.987 0.02311 *
Residuals    3 1.1630e+09  387668201                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Folding..sorting.and.degradation. :
            Df     Sum Sq    Mean Sq F value   Pr(>F)   
Timepoint    2 2.9725e+10 1.4863e+10  95.521 0.001922 **
Residuals    3 4.6678e+08 1.5559e+08                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Nucleotide.metabolism. :
            Df     Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 1001591105 500795553  4.8863 0.1138
Residuals    3  307466450 102488817               

 Response Energy.metabolism. :
            Df    Sum Sq   Mean Sq F value  Pr(>F)  
Timepoint    2 334756291 167378146  5.7208 0.09468 .
Residuals    3  87772887  29257629                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Metabolism.of.cofactors.and.vitamins. :
            Df    Sum Sq   Mean Sq F value  Pr(>F)  
Timepoint    2 340207504 170103752  20.105 0.01829 *
Residuals    3  25382865   8460955                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Signal.transduction. :
            Df    Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2  58507486 29253743  0.5767 0.6139
Residuals    3 152167277 50722426               

 Response Amino.acid.metabolism. :
            Df   Sum Sq  Mean Sq F value  Pr(>F)  
Timepoint    2 83140879 41570440  14.132 0.02972 *
Residuals    3  8824805  2941602                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Membrane.transport. :
            Df    Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 138011900 69005950  1.4682 0.3593
Residuals    3 141004838 47001613               

 Response Cell.growth.and.death. :
            Df     Sum Sq    Mean Sq F value   Pr(>F)   
Timepoint    2 2564348544 1282174272  44.207 0.005945 **
Residuals    3   87011512   29003837                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Replication.and.repair. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 9060508 4530254  2.5246 0.2275
Residuals    3 5383349 1794450               

 Response Lipid.metabolism. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 20559886 10279943  4.8843 0.1139
Residuals    3  6314115  2104705               

 Response Metabolism.of.terpenoids.and.polyketides. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3301072 1650536  2.6472 0.2175
Residuals    3 1870532  623511               

 Response Cellular.community...prokaryotes. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 11953342  5976671  0.5268 0.6367
Residuals    3 34034581 11344860               

 Response Xenobiotics.biodegradation.and.metabolism. :
            Df   Sum Sq  Mean Sq F value    Pr(>F)    
Timepoint    2 37538224 18769112  165.82 0.0008488 ***
Residuals    3   339574   113191                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Metabolism.of.other.amino.acids. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  159070   79535  0.0646 0.9387
Residuals    3 3692780 1230927               

 Response Glycan.biosynthesis.and.metabolism. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2773070 1386535  1.5981 0.3369
Residuals    3 2602910  867637               

 Response Transport.and.catabolism. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3005564 1502782  2.8822 0.2003
Residuals    3 1564177  521392               

 Response Cell.motility. :
            Df   Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  4645112 2322556  0.6376 0.5878
Residuals    3 10927437 3642479               

 Response Biosynthesis.of.other.secondary.metabolites. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2  85154   42577  8.4733 0.05833 .
Residuals    3  15074    5025                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Transcription. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 2665852 1332926  5.9012 0.09124 .
Residuals    3  677626  225875                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Cellular.community...eukaryotes. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 292483  146242  3.9738 0.1435
Residuals    3 110404   36801               

 Response Signaling.molecules.and.interaction. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1912.3  956.17  0.8034 0.5255
Residuals    3 3570.5 1190.17               

 Response Enzyme.families. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

Run ANOVA for each category of interest (significant in MANOVA)

# Overview
tuss_tIII_aov1<-aov(Overview.~Timepoint,data=tuss_tIII_stats)
summary.aov(tuss_tIII_aov1)
            Df    Sum Sq   Mean Sq F value  Pr(>F)   
Timepoint    2 3.096e+10 1.548e+10   42.32 0.00633 **
Residuals    3 1.097e+09 3.657e+08                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIII_aov1)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Overview. ~ Timepoint, data = tuss_tIII_stats)

$Timepoint
            diff        lwr       upr     p adj
T24-T0 -146654.5 -226567.44 -66741.56 0.0094184
T4-T0  -157506.0 -237418.94 -77593.06 0.0076734
T4-T24  -10851.5  -90764.44  69061.44 0.8456760
# Carbohydrate Metabolism
tuss_tIII_aov2<-aov(Carbohydrate.metabolism.~Timepoint,data=tuss_tIII_stats)
summary.aov(tuss_tIII_aov2)
            Df    Sum Sq   Mean Sq F value  Pr(>F)   
Timepoint    2 9.211e+09 4.606e+09   50.22 0.00494 **
Residuals    3 2.751e+08 9.172e+07                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIII_aov2)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Carbohydrate.metabolism. ~ Timepoint, data = tuss_tIII_stats)

$Timepoint
           diff        lwr       upr     p adj
T24-T0 -80739.5 -120758.77 -40720.23 0.0071744
T4-T0  -85308.0 -125327.27 -45288.73 0.0061201
T4-T24  -4568.5  -44587.77  35450.77 0.8865603
# Translation
tuss_tIII_aov3<-aov(Translation.~Timepoint,data=tuss_tIII_stats)
summary.aov(tuss_tIII_aov3)
            Df    Sum Sq   Mean Sq F value Pr(>F)  
Timepoint    2 1.317e+10 6.585e+09   16.99 0.0231 *
Residuals    3 1.163e+09 3.877e+08                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIII_aov3)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Translation. ~ Timepoint, data = tuss_tIII_stats)

$Timepoint
           diff         lwr       upr     p adj
T24-T0 112973.5   30696.618 195250.38 0.0213363
T4-T0   73974.5   -8302.382 156251.38 0.0655840
T4-T24 -38999.0 -121275.882  43277.88 0.2633108
# Folding, Sorting, and Degradation
tuss_tIII_aov4<-aov(Folding..sorting.and.degradation.~Timepoint,data=tuss_tIII_stats)
summary.aov(tuss_tIII_aov4)
            Df    Sum Sq   Mean Sq F value  Pr(>F)   
Timepoint    2 2.973e+10 1.486e+10   95.52 0.00192 **
Residuals    3 4.668e+08 1.556e+08                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIII_aov4)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Folding..sorting.and.degradation. ~ Timepoint, data = tuss_tIII_stats)

$Timepoint
           diff        lwr       upr     p adj
T24-T0 122733.5  70608.732 174858.27 0.0045869
T4-T0  166229.5 114104.732 218354.27 0.0019021
T4-T24  43496.0  -8628.768  95620.77 0.0788983
# Metabolism of Cofactors and Vitamins
tuss_tIII_aov5<-aov(Metabolism.of.cofactors.and.vitamins.~Timepoint,data=tuss_tIII_stats)
summary.aov(tuss_tIII_aov5)
            Df    Sum Sq   Mean Sq F value Pr(>F)  
Timepoint    2 340207504 170103752   20.11 0.0183 *
Residuals    3  25382865   8460955                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIII_aov5)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Metabolism.of.cofactors.and.vitamins. ~ Timepoint, data = tuss_tIII_stats)

$Timepoint
           diff        lwr       upr     p adj
T24-T0 -17234.5 -29389.569 -5079.431 0.0195185
T4-T0  -14308.0 -26463.069 -2152.931 0.0324916
T4-T24   2926.5  -9228.569 15081.569 0.6228689
# Amino Acid Metabolism
tuss_tIII_aov6<-aov(Amino.acid.metabolism.~Timepoint,data=tuss_tIII_stats)
summary.aov(tuss_tIII_aov6)
            Df   Sum Sq  Mean Sq F value Pr(>F)  
Timepoint    2 83140879 41570440   14.13 0.0297 *
Residuals    3  8824805  2941602                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIII_aov6)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Amino.acid.metabolism. ~ Timepoint, data = tuss_tIII_stats)

$Timepoint
          diff        lwr       upr     p adj
T24-T0 -9046.0 -16213.037 -1878.963 0.0268937
T4-T0  -5514.5 -12681.537  1652.537 0.0959158
T4-T24  3531.5  -3635.537 10698.537 0.2456345
# Cell Growth and Death
tuss_tIII_aov7<-aov(Cell.growth.and.death.~Timepoint,data=tuss_tIII_stats)
summary.aov(tuss_tIII_aov7)
            Df    Sum Sq   Mean Sq F value  Pr(>F)   
Timepoint    2 2.564e+09 1.282e+09   44.21 0.00595 **
Residuals    3 8.701e+07 2.900e+07                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIII_aov7)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Cell.growth.and.death. ~ Timepoint, data = tuss_tIII_stats)

$Timepoint
          diff       lwr      upr     p adj
T24-T0 16444.5 -6060.316 38949.32 0.1082421
T4-T0  49700.5 27195.684 72205.32 0.0055243
T4-T24 33256.0 10751.184 55760.82 0.0173935
# Xenobiotics Biodegradation and Metabolism
tuss_tIII_aov8<-aov(Xenobiotics.biodegradation.and.metabolism.~Timepoint,data=tuss_tIII_stats)
summary.aov(tuss_tIII_aov8)
            Df   Sum Sq  Mean Sq F value   Pr(>F)    
Timepoint    2 37538224 18769112   165.8 0.000849 ***
Residuals    3   339574   113191                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIII_aov8)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Xenobiotics.biodegradation.and.metabolism. ~ Timepoint, data = tuss_tIII_stats)

$Timepoint
        diff     lwr     upr     p adj
T24-T0 -5434 -6839.9 -4028.1 0.0011070
T4-T0  -5168 -6573.9 -3762.1 0.0012720
T4-T24   266 -1139.9  1671.9 0.7336445
7.3.1.3. Tier IV Expression

Calculate TPM-normalized gene count sums for each Tuss sample in each Tier IV category.

# Calculate TPM-normalized gene count sums for each Tuss sample in each Tier IV category
tuss_tIV_sum<-tpm_all_exp_ann %>% group_by(Tier_IV) %>% summarise_at(vars("S108382","S108383","S108391","S108392","S108394","S108396"), sum)
tuss_tIV_sum<-tuss_tIV_sum %>% mutate_at(vars(S108382,S108383,S108391,S108392,S108394,S108396), funs(round(., 0)))
tuss_tIV_sum<-as.data.frame(tuss_tIV_sum)
tuss_tIV_sum<-tuss_tIV_sum[order(-tuss_tIV_sum$S108382),]
# Calculate mean values from the replicate sums
tuss_tIV_sum$meantuss_T0<-apply(tuss_tIV_sum[,2:3], 1, mean)
tuss_tIV_sum$meantuss_T4<-apply(tuss_tIV_sum[,4:5], 1, mean)
tuss_tIV_sum$meantuss_T24<-apply(tuss_tIV_sum[,6:7], 1, mean)
tuss_tIV_sum<-tuss_tIV_sum %>% mutate_at(vars(meantuss_T0,meantuss_T4,meantuss_T24), funs(round(., 0)))

# Calculate sd values from the replicate sums
tuss_tIV_sum$sdtuss_T0<-apply(tuss_tIV_sum[,2:3], 1, sd)
tuss_tIV_sum$sdtuss_T4<-apply(tuss_tIV_sum[,4:5], 1, sd)
tuss_tIV_sum$sdtuss_T24<-apply(tuss_tIV_sum[,6:7], 1, sd)
tuss_tIV_sum<-tuss_tIV_sum %>% mutate_at(vars(sdtuss_T0,sdtuss_T4,sdtuss_T24), funs(round(., 0)))

# Write data to .csv file
write.csv(tuss_tIV_sum, 'Norm.Results/tuss.rna.tIV.mean.sd.csv')

# Subset Mean values
tuss_tIV_mean<-subset(tuss_tIV_sum, select=c(Tier_IV,meantuss_T0,meantuss_T4,meantuss_T24))
names(tuss_tIV_mean)<-c("Tier IV", "Tuss-T0", "Tuss-T4", "Tuss-T24")

# Subset SD values
tuss_tIV_sd<-subset(tuss_tIV_sum, select=c(Tier_IV,sdtuss_T0,sdtuss_T4,sdtuss_T24))
names(tuss_tIV_sd)<-c("Tier IV", "Tuss-T0", "Tuss-T4", "Tuss-T24")

# Remember "Tier IV" as non-numeric values
tuss_tIV_mean_TierIV<-tuss_tIV_mean$`Tier IV`
tuss_tIV_sd_TierIV<-tuss_tIV_sd$`Tier IV`

# Transpose all but first column (Tier IV)
tuss_tIV_mean<-as.data.frame(t(tuss_tIV_mean[,-1]))
colnames(tuss_tIV_mean)<-tuss_tIV_mean_TierIV
tuss_tIV_sd<-as.data.frame(t(tuss_tIV_sd[,-1]))
colnames(tuss_tIV_sd)<-tuss_tIV_sd_TierIV

# Combine mean and sd into single column with ± divider
tuss_tIV_table<-as.data.frame(do.call(cbind, lapply(1:ncol(tuss_tIV_mean), function(i) paste0(tuss_tIV_mean[ , i], " ± ", tuss_tIV_sd[ , i]))))

# Transpose the table back
tuss_tIV_table<-t(tuss_tIV_table)

# Rename columns to Sites
colnames(tuss_tIV_table)<-c("Tussock (T0)", "Tussock (T4)", "Tussock (T24)")

rownames(tuss_tIV_table)<-tuss_tIV_mean_TierIV

#tuss_tIV_table

Run statistical tests to determine if significant differences exist between sampling timepoints for each Tier KEGG category. Click on the Show/Hide button to see the statistics.

# Subset the "sum" values for each sample
tuss_tIV_stats<-subset(tuss_tIV_sum, select=c(Tier_IV,S108382,S108383,S108391,S108392,S108394,S108396))

rownames(tuss_tIV_stats) <- tuss_tIV_stats$Tier_IV
tuss_tIV_stats<-as.data.frame(t(tuss_tIV_stats[-1]))

# Add the timepoint column to the sum table
tuss_tIV_stats<-data.frame(Timepoint,tuss_tIV_stats)

# Subset response variables for MANOVA
tuss_tIV_stats$response <- as.matrix(tuss_tIV_stats[, 2:227])

# MANOVA test
tuss_tIV_manova <- manova(response ~ Timepoint, data=tuss_tIV_stats)
summary.aov(tuss_tIV_manova)
 Response X01200.Carbon.metabolism..PATH.ko01200. :
            Df     Sum Sq    Mean Sq F value Pr(>F)  
Timepoint    2 1.7153e+10 8576404278   17.66 0.0219 *
Residuals    3 1.4569e+09  485639564                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X03010.Ribosome..PATH.ko03010. :
            Df     Sum Sq    Mean Sq F value  Pr(>F)  
Timepoint    2 1.3250e+10 6625221176  17.078 0.02294 *
Residuals    3 1.1638e+09  387927821                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X03018.RNA.degradation..PATH.ko03018. :
            Df     Sum Sq    Mean Sq F value   Pr(>F)   
Timepoint    2 2.4580e+10 1.2290e+10  116.53 0.001433 **
Residuals    3 3.1639e+08 1.0546e+08                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00230.Purine.metabolism..PATH.ko00230. :
            Df     Sum Sq   Mean Sq F value  Pr(>F)  
Timepoint    2 1194233024 597116512  5.7324 0.09445 .
Residuals    3  312493039 104164346                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X01212.Fatty.acid.metabolism..PATH.ko01212. :
            Df     Sum Sq   Mean Sq F value    Pr(>F)    
Timepoint    2 1400417305 700208653  166.61 0.0008428 ***
Residuals    3   12607908   4202636                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00190.Oxidative.phosphorylation..PATH.ko00190. :
            Df    Sum Sq   Mean Sq F value  Pr(>F)  
Timepoint    2 294927542 147463771  6.4145 0.08251 .
Residuals    3  68967675  22989225                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00650.Butanoate.metabolism..PATH.ko00650. :
            Df    Sum Sq   Mean Sq F value  Pr(>F)  
Timepoint    2 916283691 458141846  11.478 0.03929 *
Residuals    3 119745259  39915086                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00010.Glycolysis...Gluconeogenesis..PATH.ko00010. :
            Df    Sum Sq   Mean Sq F value  Pr(>F)  
Timepoint    2 646115961 323057980  29.342 0.01073 *
Residuals    3  33029853  11009951                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00640.Propanoate.metabolism..PATH.ko00640. :
            Df    Sum Sq   Mean Sq F value  Pr(>F)  
Timepoint    2 276630866 138315433  8.5361 0.05778 .
Residuals    3  48610475  16203492                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X02020.Two.component.system..PATH.ko02020. :
            Df    Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 100862431 50431216   0.878  0.501
Residuals    3 172323860 57441287               

 Response X02010.ABC.transporters..PATH.ko02010. :
            Df    Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 136666543 68333271  1.9745 0.2837
Residuals    3 103823155 34607718               

 Response X01230.Biosynthesis.of.amino.acids..PATH.ko01230. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 14513158  7256579  0.4641 0.6674
Residuals    3 46906381 15635460               

 Response X04112.Cell.cycle...Caulobacter..PATH.ko04112. :
            Df     Sum Sq    Mean Sq F value  Pr(>F)   
Timepoint    2 2484296210 1242148105   41.97 0.00641 **
Residuals    3   88788203   29596068                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00760.Nicotinate.and.nicotinamide.metabolism..PATH.ko00760. :
            Df    Sum Sq  Mean Sq F value  Pr(>F)  
Timepoint    2 140469145 70234573  14.447 0.02885 *
Residuals    3  14584946  4861649                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X01220.Degradation.of.aromatic.compounds..PATH.ko01220. :
            Df   Sum Sq  Mean Sq F value  Pr(>F)  
Timepoint    2 92377264 46188632  27.224 0.01193 *
Residuals    3  5089767  1696589                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X03060.Protein.export..PATH.ko03060. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 80425936 40212968  2.1311 0.2655
Residuals    3 56609754 18869918               

 Response X00240.Pyrimidine.metabolism..PATH.ko00240. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 9523084 4761542  7.8297 0.06447 .
Residuals    3 1824413  608138                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X01210.2.Oxocarboxylic.acid.metabolism..PATH.ko01210. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 40780169 20390085  1.1247  0.432
Residuals    3 54389012 18129671               

 Response X00500.Starch.and.sucrose.metabolism..PATH.ko00500. :
            Df   Sum Sq  Mean Sq F value   Pr(>F)   
Timepoint    2 28026154 14013077  37.804 0.007456 **
Residuals    3  1112040   370680                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00970.Aminoacyl.tRNA.biosynthesis..PATH.ko00970. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2042336 1021168  0.9365  0.483
Residuals    3 3271196 1090399               

 Response X00860.Porphyrin.and.chlorophyll.metabolism..PATH.ko00860. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 8406391 4203196  12.153 0.03642 *
Residuals    3 1037565  345855                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00360.Phenylalanine.metabolism..PATH.ko00360. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 6182910 3091455  6.9891 0.07428 .
Residuals    3 1326983  442328                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00620.Pyruvate.metabolism..PATH.ko00620. :
            Df   Sum Sq  Mean Sq F value   Pr(>F)   
Timepoint    2 35362292 17681146  49.721 0.005011 **
Residuals    3  1066810   355603                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00900.Terpenoid.backbone.biosynthesis..PATH.ko00900. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 2878816 1439408  8.8448 0.05521 .
Residuals    3  488223  162741                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00030.Pentose.phosphate.pathway..PATH.ko00030. :
            Df   Sum Sq  Mean Sq F value Pr(>F)  
Timepoint    2 41610937 20805469  9.3783 0.0512 .
Residuals    3  6655378  2218459                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X02024.Quorum.sensing..PATH.ko02024. :
            Df   Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 16585121 8292561  0.9498 0.4791
Residuals    3 26191390 8730463               

 Response X00520.Amino.sugar.and.nucleotide.sugar.metabolism..PATH.ko00520. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1978704  989352  1.6001 0.3366
Residuals    3 1854922  618307               

 Response X00633.Nitrotoluene.degradation..PATH.ko00633. :
            Df   Sum Sq Mean Sq F value   Pr(>F)   
Timepoint    2 18660459 9330230  50.543 0.004893 **
Residuals    3   553800  184600                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00270.Cysteine.and.methionine.metabolism..PATH.ko00270. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  425956  212978  0.3666 0.7204
Residuals    3 1743004  581001               

 Response X04141.Protein.processing.in.endoplasmic.reticulum..PATH.ko04141. :
            Df    Sum Sq   Mean Sq F value  Pr(>F)  
Timepoint    2 239695658 119847829  6.8827 0.07569 .
Residuals    3  52238944  17412982                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00920.Sulfur.metabolism..PATH.ko00920. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  406171  203085  0.1629 0.8567
Residuals    3 3740157 1246719               

 Response X03440.Homologous.recombination..PATH.ko03440. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 1976508  988254  8.0369 0.06238 .
Residuals    3  368893  122964                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00790.Folate.biosynthesis..PATH.ko00790. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 614946  307473  3.6404 0.1576
Residuals    3 253385   84462               

 Response X00730.Thiamine.metabolism..PATH.ko00730. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 5096584 2548292  15.984 0.02513 *
Residuals    3  478274  159425                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00450.Selenocompound.metabolism..PATH.ko00450. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2495094 1247547  2.0526 0.2744
Residuals    3 1823373  607791               

 Response X00770.Pantothenate.and.CoA.biosynthesis..PATH.ko00770. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 4813879 2406940   27.17 0.01197 *
Residuals    3  265765   88588                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00561.Glycerolipid.metabolism..PATH.ko00561. :
            Df  Sum Sq Mean Sq F value   Pr(>F)   
Timepoint    2 6715964 3357982  33.389 0.008915 **
Residuals    3  301717  100572                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00350.Tyrosine.metabolism..PATH.ko00350. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3144017 1572009   3.076 0.1877
Residuals    3 1533150  511050               

 Response X00040.Pentose.and.glucuronate.interconversions..PATH.ko00040. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1252446  626223  1.1849 0.4176
Residuals    3 1585547  528516               

 Response X00052.Galactose.metabolism..PATH.ko00052. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 2924805 1462403  8.4382 0.05864 .
Residuals    3  519922  173307                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X03420.Nucleotide.excision.repair..PATH.ko03420. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 389281  194640  1.0022 0.4641
Residuals    3 582640  194213               

 Response X00910.Nitrogen.metabolism..PATH.ko00910. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2357742 1178871  3.3036 0.1745
Residuals    3 1070537  356846               

 Response X00330.Arginine.and.proline.metabolism..PATH.ko00330. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 3117270 1558635   11.93 0.03733 *
Residuals    3  391951  130650                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00562.Inositol.phosphate.metabolism..PATH.ko00562. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1228842  614421  2.3246 0.2456
Residuals    3  792937  264312               

 Response X03050.Proteasome..PATH.ko03050. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  210967  105484   0.164 0.8559
Residuals    3 1929687  643229               

 Response X00750.Vitamin.B6.metabolism..PATH.ko00750. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1285060  642530  1.1552 0.4246
Residuals    3 1668555  556185               

 Response X00630.Glyoxylate.and.dicarboxylate.metabolism..PATH.ko00630. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 2325257 1162629  8.2637 0.06022 .
Residuals    3  422074  140691                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00564.Glycerophospholipid.metabolism..PATH.ko00564. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 833920  416960  5.8203 0.09276 .
Residuals    3 214915   71638                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X03030.DNA.replication..PATH.ko03030. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  83106   41553  0.9344 0.4837
Residuals    3 133406   44469               

 Response X00051.Fructose.and.mannose.metabolism..PATH.ko00051. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 1024591  512296  7.9101 0.06364 .
Residuals    3  194295   64765                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00550.Peptidoglycan.biosynthesis..PATH.ko00550. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 845777  422889  1.8328 0.3019
Residuals    3 692217  230739               

 Response X02026.Biofilm.formation...Escherichia.coli..PATH.ko02026. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 822904  411452  1.3682 0.3782
Residuals    3 902181  300727               

 Response X00740.Riboflavin.metabolism..PATH.ko00740. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 698724  349362  4.3672 0.1293
Residuals    3 239990   79997               

 Response X03410.Base.excision.repair..PATH.ko03410. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 361081  180541  5.4685 0.09987 .
Residuals    3  99043   33014                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00540.Lipopolysaccharide.biosynthesis..PATH.ko00540. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 298510  149255  0.8302 0.5165
Residuals    3 539317  179772               

 Response X03430.Mismatch.repair..PATH.ko03430. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 919129  459565  3.2975 0.1748
Residuals    3 418102  139367               

 Response X00130.Ubiquinone.and.other.terpenoid.quinone.biosynthesis..PATH.ko00130. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 227911  113956  0.9201  0.488
Residuals    3 371551  123850               

 Response X04013.MAPK.signaling.pathway...fly..PATH.ko04013. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 632136  316068  2.8613 0.2017
Residuals    3 331384  110461               

 Response X04122.Sulfur.relay.system..PATH.ko04122. :
            Df  Sum Sq Mean Sq F value   Pr(>F)   
Timepoint    2 3894102 1947051  53.011 0.004565 **
Residuals    3  110186   36729                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00250.Alanine..aspartate.and.glutamate.metabolism..PATH.ko00250. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 206572  103286  9.3945 0.05109 .
Residuals    3  32983   10994                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X03070.Bacterial.secretion.system..PATH.ko03070. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1125234  562617  0.6321 0.5901
Residuals    3 2670247  890082               

 Response X00260.Glycine..serine.and.threonine.metabolism..PATH.ko00260. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 561206  280603  3.5254 0.1631
Residuals    3 238786   79595               

 Response X00480.Glutathione.metabolism..PATH.ko00480. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 177609   88805  4.7798 0.1167
Residuals    3  55738   18579               

 Response X00340.Histidine.metabolism..PATH.ko00340. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 398749  199375  11.112 0.04101 *
Residuals    3  53825   17942                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X03450.Non.homologous.end.joining..PATH.ko03450. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 166980   83490  0.6421  0.586
Residuals    3 390054  130018               

 Response X00600.Sphingolipid.metabolism..PATH.ko00600. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 1354564  677282  7.8244 0.06452 .
Residuals    3  259682   86561                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00280.Valine..leucine.and.isoleucine.degradation..PATH.ko00280. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 286025  143013  4.2494 0.1333
Residuals    3 100966   33655               

 Response X00061.Fatty.acid.biosynthesis..PATH.ko00061. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 614841  307421  1.4654 0.3598
Residuals    3 629357  209786               

 Response X00785.Lipoic.acid.metabolism..PATH.ko00785. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 246846  123423   5.728 0.09454 .
Residuals    3  64643   21548                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00364.Fluorobenzoate.degradation..PATH.ko00364. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 153292   76646  0.7662 0.5385
Residuals    3 300086  100029               

 Response X02040.Flagellar.assembly..PATH.ko02040. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3574937 1787469  0.6611 0.5783
Residuals    3 8111394 2703798               

 Response X00680.Methane.metabolism..PATH.ko00680. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 253881  126941  8.8822 0.05492 .
Residuals    3  42875   14292                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00627.Aminobenzoate.degradation..PATH.ko00627. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 203000  101500  1.4442 0.3637
Residuals    3 210847   70282               

 Response X00523.Polyketide.sugar.unit.biosynthesis..PATH.ko00523. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 120529   60265  3.0489 0.1894
Residuals    3  59298   19766               

 Response X00140.Steroid.hormone.biosynthesis..PATH.ko00140. :
            Df Sum Sq Mean Sq F value   Pr(>F)   
Timepoint    2 305292  152646   78.14 0.002585 **
Residuals    3   5861    1954                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00511.Other.glycan.degradation..PATH.ko00511. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 339283  169642  3.9783 0.1433
Residuals    3 127924   42641               

 Response X00909.Sesquiterpenoid.and.triterpenoid.biosynthesis..PATH.ko00909. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 446971  223485  18.667 0.02029 *
Residuals    3  35917   11972                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04120.Ubiquitin.mediated.proteolysis..PATH.ko04120. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 334361  167181  1.6172 0.3338
Residuals    3 310134  103378               

 Response X00310.Lysine.degradation..PATH.ko00310. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  36486 18243.2    2.83 0.2039
Residuals    3  19339  6446.3               

 Response X00362.Benzoate.degradation..PATH.ko00362. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 165859   82930  10.698 0.04312 *
Residuals    3  23257    7752                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X02025.Biofilm.formation...Pseudomonas.aeruginosa..PATH.ko02025. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 133802   66901   5.389 0.1016
Residuals    3  37243   12414               

 Response X00380.Tryptophan.metabolism..PATH.ko00380. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 123036   61518  4.9122 0.1131
Residuals    3  37570   12523               

 Response X03013.RNA.transport..PATH.ko03013. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 3685232 1842616  5.8254 0.09266 .
Residuals    3  948927  316309                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X05111.Biofilm.formation...Vibrio.cholerae..PATH.ko05111. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  40287   20143  0.2678 0.7816
Residuals    3 225661   75220               

 Response X00625.Chloroalkane.and.chloroalkene.degradation..PATH.ko00625. :
            Df Sum Sq Mean Sq F value   Pr(>F)   
Timepoint    2 163596   81798  80.457 0.002476 **
Residuals    3   3050    1017                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00430.Taurine.and.hypotaurine.metabolism..PATH.ko00430. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  95412   47706  1.2927 0.3936
Residuals    3 110709   36903               

 Response X00071.Fatty.acid.degradation..PATH.ko00071. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  33124   16562  0.6734 0.5733
Residuals    3  73781   24594               

 Response X00473.D.Alanine.metabolism..PATH.ko00473. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  87416   43708  3.3182 0.1737
Residuals    3  39516   13172               

 Response X00670.One.carbon.pool.by.folate..PATH.ko00670. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2  80656   40328  7.7353 0.06546 .
Residuals    3  15641    5214                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00053.Ascorbate.and.aldarate.metabolism..PATH.ko00053. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 150033   75017  4.6531 0.1204
Residuals    3  48365   16122               

 Response X04217.Necroptosis..PATH.ko04217. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 114410   57205  1.5744 0.3408
Residuals    3 109005   36335               

 Response X00510.N.Glycan.biosynthesis..PATH.ko00510. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  85234   42617  0.7549 0.5426
Residuals    3 169371   56457               

 Response X04146.Peroxisome..PATH.ko04146. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 312706  156353   6.307 0.08422 .
Residuals    3  74371   24790                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X03008.Ribosome.biogenesis.in.eukaryotes..PATH.ko03008. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 923361  461681   8.901 0.05477 .
Residuals    3 155606   51868                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00590.Arachidonic.acid.metabolism..PATH.ko00590. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 142922   71461  0.9314 0.4846
Residuals    3 230167   76722               

 Response X04138.Autophagy...yeast..PATH.ko04138. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  92794   46397  0.9571  0.477
Residuals    3 145425   48475               

 Response X00780.Biotin.metabolism..PATH.ko00780. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2  52292   26146    23.2 0.01497 *
Residuals    3   3381    1127                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00300.Lysine.biosynthesis..PATH.ko00300. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2  41825   20913  28.491 0.01119 *
Residuals    3   2202     734                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04016.MAPK.signaling.pathway...plant..PATH.ko04016. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2  44417 22208.7  10.905 0.04205 *
Residuals    3   6110  2036.5                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04011.MAPK.signaling.pathway...yeast..PATH.ko04011. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 275731  137865  1.7076 0.3198
Residuals    3 242203   80734               

 Response X00471.D.Glutamine.and.D.glutamate.metabolism..PATH.ko00471. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  26700 13350.2  3.2182 0.1793
Residuals    3  12445  4148.3               

 Response X03040.Spliceosome..PATH.ko03040. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 2166601 1083301  6.9166 0.07524 .
Residuals    3  469867  156622                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00410.beta.Alanine.metabolism..PATH.ko00410. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2  15905  7952.7  7.1818 0.07182 .
Residuals    3   3322  1107.3                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X02030.Bacterial.chemotaxis..PATH.ko02030. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  90307   45154  0.5377 0.6316
Residuals    3 251932   83977               

 Response X00906.Carotenoid.biosynthesis..PATH.ko00906. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  57100   28550  0.8548 0.5084
Residuals    3 100203   33401               

 Response X00440.Phosphonate.and.phosphinate.metabolism..PATH.ko00440. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 19605.3  9802.7  7.9022 0.06372 .
Residuals    3  3721.5  1240.5                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00660.C5.Branched.dibasic.acid.metabolism..PATH.ko00660. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 207499  103750  1.4874 0.3558
Residuals    3 209252   69751               

 Response X01059.Biosynthesis.of.enediyne.antibiotics..PATH.ko01059. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  12600  6300.2  1.2642 0.3997
Residuals    3  14950  4983.5               

 Response X00311.Penicillin.and.cephalosporin.biosynthesis..PATH.ko00311. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 13213.0  6606.5  8.9418 0.05445 .
Residuals    3  2216.5   738.8                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00984.Steroid.degradation..PATH.ko00984. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   8221  4110.5  3.6473 0.1573
Residuals    3   3381  1127.0               

 Response X00405.Phenazine.biosynthesis..PATH.ko00405. :
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 9930.3  4965.2  7.7219 0.0656 .
Residuals    3 1929.0   643.0                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00930.Caprolactam.degradation..PATH.ko00930. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 15745.3  7872.7  6.4716 0.08162 .
Residuals    3  3649.5  1216.5                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X03022.Basal.transcription.factors..PATH.ko03022. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  32493 16246.5  2.2043 0.2577
Residuals    3  22111  7370.3               

 Response X00220.Arginine.biosynthesis..PATH.ko00220. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 23081.3 11540.7  13.709 0.03097 *
Residuals    3  2525.5   841.8                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00908.Zeatin.biosynthesis..PATH.ko00908. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  2622.3  1311.2  0.1432 0.8722
Residuals    3 27474.5  9158.2               

 Response X04144.Endocytosis..PATH.ko04144. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 359824  179912  4.4662 0.1261
Residuals    3 120849   40283               

 Response X04142.Lysosome..PATH.ko04142. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  2892.3  1446.2  0.2646 0.7838
Residuals    3 16398.5  5466.2               

 Response X02060.Phosphotransferase.system..PTS...PATH.ko02060. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1304.3  652.17  0.3375 0.7376
Residuals    3 5797.0 1932.33               

 Response X04014.Ras.signaling.pathway..PATH.ko04014. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 139030   69515    7.21 0.07147 .
Residuals    3  28924    9642                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00565.Ether.lipid.metabolism..PATH.ko00565. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 12825.3  6412.7   7.841 0.06435 .
Residuals    3  2453.5   817.8                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00903.Limonene.and.pinene.degradation..PATH.ko00903. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3172.3  1586.2  1.5188 0.3503
Residuals    3 3133.0  1044.3               

 Response X04145.Phagosome..PATH.ko04145. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   9943  4971.5  1.4806  0.357
Residuals    3  10073  3357.7               

 Response X00100.Steroid.biosynthesis..PATH.ko00100. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2060.3  1030.2  0.5772 0.6137
Residuals    3 5354.5  1784.8               

 Response X03015.mRNA.surveillance.pathway..PATH.ko03015. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  60908   30454   2.388 0.2396
Residuals    3  38259   12753               

 Response X00515.Mannose.type.O.glycan.biosyntheis..PATH.ko00515. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  212.3  106.17  0.0634 0.9398
Residuals    3 5025.0 1675.00               

 Response X01055.Biosynthesis.of.vancomycin.group.antibiotics..PATH.ko01055. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2133.3  1066.7  0.7089 0.5596
Residuals    3 4514.0  1504.7               

 Response X04214.Apoptosis...fly..PATH.ko04214. :
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 635265  317633  24.822 0.0136 *
Residuals    3  38390   12797                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00120.Primary.bile.acid.biosynthesis..PATH.ko00120. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1456.0   728.0  1.7313 0.3163
Residuals    3 1261.5   420.5               

 Response X01040.Biosynthesis.of.unsaturated.fatty.acids..PATH.ko01040. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 7769.3  3884.7  2.5401 0.2262
Residuals    3 4588.0  1529.3               

 Response X00281.Geraniol.degradation..PATH.ko00281. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  114.3   57.17  0.0304 0.9704
Residuals    3 5644.5 1881.50               

 Response X00195.Photosynthesis..PATH.ko00195. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   4984  2492.2  0.1836  0.841
Residuals    3  40729 13576.3               

 Response X00514.Other.types.of.O.glycan.biosynthesis..PATH.ko00514. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2   4863  2431.5  6.7355 0.07773 .
Residuals    3   1083   361.0                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04371.Apelin.signaling.pathway..PATH.ko04371. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  38184   19092   1.242 0.4046
Residuals    3  46114   15372               

 Response X04139.Mitophagy...yeast..PATH.ko04139. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  21052 10526.0  2.0772 0.2715
Residuals    3  15202  5067.3               

 Response X04150.mTOR.signaling.pathway..PATH.ko04150. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3058.3 1529.17  3.2933 0.1751
Residuals    3 1393.0  464.33               

 Response X00261.Monobactam.biosynthesis..PATH.ko00261. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   977.3   488.7  0.0864 0.9194
Residuals    3 16969.5  5656.5               

 Response X04110.Cell.cycle..PATH.ko04110. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  13402  6701.2  0.3759  0.715
Residuals    3  53475 17825.0               

 Response X00965.Betalain.biosynthesis..PATH.ko00965. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2344.3 1172.17   2.662 0.2164
Residuals    3 1321.0  440.33               

 Response X04015.Rap1.signaling.pathway..PATH.ko04015. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  10108  5054.0  1.3021 0.3917
Residuals    3  11644  3881.3               

 Response X04530.Tight.junction..PATH.ko04530. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 300037  150019   4.512 0.1246
Residuals    3  99747   33249               

 Response X00960.Tropane..piperidine.and.pyridine.alkaloid.biosynthesis..PATH.ko00960. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    603   301.5  3.7222 0.1539
Residuals    3    243    81.0               

 Response X04024.cAMP.signaling.pathway..PATH.ko04024. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2004.3 1002.17  1.8166 0.3042
Residuals    3 1655.0  551.67               

 Response X03460.Fanconi.anemia.pathway..PATH.ko03460. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1047.0   523.5  0.3693 0.7188
Residuals    3 4252.5  1417.5               

 Response X04012.ErbB.signaling.pathway..PATH.ko04012. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  14481  7240.5  3.8061 0.1503
Residuals    3   5707  1902.3               

 Response X04152.AMPK.signaling.pathway..PATH.ko04152. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  10850  5425.2  0.9714 0.4728
Residuals    3  16754  5584.8               

 Response X04137.Mitophagy...animal..PATH.ko04137. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  45697 22848.5  5.4527 0.1002
Residuals    3  12571  4190.3               

 Response X04810.Regulation.of.actin.cytoskeleton..PATH.ko04810. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1202.3  601.17  0.6738 0.5732
Residuals    3 2676.5  892.17               

 Response X04151.PI3K.Akt.signaling.pathway..PATH.ko04151. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1002.3  501.17  0.4803 0.6592
Residuals    3 3130.5 1043.50               

 Response X04020.Calcium.signaling.pathway..PATH.ko04020. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 1414.3  707.17  7.7853 0.06493 .
Residuals    3  272.5   90.83                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00591.Linoleic.acid.metabolism..PATH.ko00591. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 336.33  168.17  0.7101 0.5592
Residuals    3 710.50  236.83               

 Response X01056.Biosynthesis.of.type.II.polyketide.backbone..PATH.ko01056. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  481.0  240.50  1.2344 0.4063
Residuals    3  584.5  194.83               

 Response X00643.Styrene.degradation..PATH.ko00643. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1849.3  924.67  4.0467 0.1406
Residuals    3  685.5  228.50               

 Response X00623.Toluene.degradation..PATH.ko00623. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1484.3  742.17  1.1654 0.4222
Residuals    3 1910.5  636.83               

 Response X00830.Retinol.metabolism..PATH.ko00830. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1677.0  838.50  2.1345 0.2651
Residuals    3 1178.5  392.83               

 Response X00020.Citrate.cycle..TCA.cycle...PATH.ko00020. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 8881.3  4440.7  7.3521 0.06975 .
Residuals    3 1812.0   604.0                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00563.Glycosylphosphatidylinositol.GPI..anchor.biosynthesis..PATH.ko00563. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 10249.0  5124.5  2.4834 0.2311
Residuals    3  6190.5  2063.5               

 Response X04010.MAPK.signaling.pathway..PATH.ko04010. :
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 6974.3  3487.2  9.1848 0.0526 .
Residuals    3 1139.0   379.7                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04068.FoxO.signaling.pathway..PATH.ko04068. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  732.0  366.00  0.6163 0.5967
Residuals    3 1781.5  593.83               

 Response X00363.Bisphenol.degradation..PATH.ko00363. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 566.33 283.167  6.0463 0.08862 .
Residuals    3 140.50  46.833                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04113.Meiosis...yeast..PATH.ko04113. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1480.3  740.17  0.6777 0.5717
Residuals    3 3276.5 1092.17               

 Response X04111.Cell.cycle...yeast..PATH.ko04111. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 8233.3  4116.7  5.7995 0.09315 .
Residuals    3 2129.5   709.8                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04140.Autophagy...animal..PATH.ko04140. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 13589.3  6794.7  2.7525 0.2095
Residuals    3  7405.5  2468.5               

 Response X01057.Biosynthesis.of.type.II.polyketide.products..PATH.ko01057. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 306.33 153.167  1.6237 0.3328
Residuals    3 283.00  94.333               

 Response X00365.Furfural.degradation..PATH.ko00365. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    273  136.50  0.9371 0.4829
Residuals    3    437  145.67               

 Response X04350.TGF.beta.signaling.pathway..PATH.ko04350. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 112.33  56.167  0.6673 0.5758
Residuals    3 252.50  84.167               

 Response X04391.Hippo.signaling.pathway..fly..PATH.ko04391. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   1461  730.50  4.1427 0.1371
Residuals    3    529  176.33               

 Response X04080.Neuroactive.ligand.receptor.interaction..PATH.ko04080. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2     13     6.5  0.4333 0.6834
Residuals    3     45    15.0               

 Response X04310.Wnt.signaling.pathway..PATH.ko04310. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 1264.0  632.00   6.126 0.08724 .
Residuals    3  309.5  103.17                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00404.Staurosporine.biosynthesis..PATH.ko00404. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 357.33 178.667      16 0.02509 *
Residuals    3  33.50  11.167                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00943.Isoflavonoid.biosynthesis..PATH.ko00943. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 294.33 147.167  6.0897 0.08786 .
Residuals    3  72.50  24.167                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04550.Signaling.pathways.regulating.pluripotency.of.stem.cells..PATH.ko04550. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  74.333  37.167  0.5138 0.6428
Residuals    3 217.000  72.333               

 Response X00073.Cutin..suberine.and.wax.biosynthesis..PATH.ko00073. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  86.333  43.167  0.9317 0.4845
Residuals    3 139.000  46.333               

 Response X04130.SNARE.interactions.in.vesicular.transport..PATH.ko04130. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1110.3  555.17  0.6444  0.585
Residuals    3 2584.5  861.50               

 Response X00531.Glycosaminoglycan.degradation..PATH.ko00531. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  826.33  413.17  0.9783 0.4709
Residuals    3 1267.00  422.33               

 Response X00791.Atrazine.degradation..PATH.ko00791. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 240.33 120.167  3.0944 0.1865
Residuals    3 116.50  38.833               

 Response X04070.Phosphatidylinositol.signaling.system..PATH.ko04070. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1842.3  921.17  1.2579 0.4011
Residuals    3 2197.0  732.33               

 Response X01053.Biosynthesis.of.siderophore.group.nonribosomal.peptides..PATH.ko01053. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    307   153.5  0.8977 0.4948
Residuals    3    513   171.0               

 Response X00400.Phenylalanine..tyrosine.and.tryptophan.biosynthesis..PATH.ko00400. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  2.3333  1.1667  0.1556 0.8624
Residuals    3 22.5000  7.5000               

 Response X00624.Polycyclic.aromatic.hydrocarbon.degradation..PATH.ko00624. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   52.0  26.000  0.7393 0.5482
Residuals    3  105.5  35.167               

 Response X04072.Phospholipase.D.signaling.pathway..PATH.ko04072. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  90.33  45.167  0.2326 0.8055
Residuals    3 582.50 194.167               

 Response X00121.Secondary.bile.acid.biosynthesis..PATH.ko00121. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 44.333  22.167  7.3889 0.06932 .
Residuals    3  9.000   3.000                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00513.Various.types.of.N.glycan.biosynthesis..PATH.ko00513. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1290.3  645.17  3.7293 0.1536
Residuals    3  519.0  173.00               

 Response X00532.Glycosaminoglycan.biosynthesis...chondroitin.sulfate...dermatan.sulfate..PATH.ko00532. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    103  51.500  0.5578 0.6224
Residuals    3    277  92.333               

 Response X00472.D.Arginine.and.D.ornithine.metabolism..PATH.ko00472. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      3     1.5  0.2143 0.8185
Residuals    3     21     7.0               

 Response X00361.Chlorocyclohexane.and.chlorobenzene.degradation..PATH.ko00361. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 16.333  8.1667  0.7903   0.53
Residuals    3 31.000 10.3333               

 Response X04066.HIF.1.signaling.pathway..PATH.ko04066. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  14.333   7.167  0.0964 0.9108
Residuals    3 223.000  74.333               

 Response X04668.TNF.signaling.pathway..PATH.ko04668. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 6489.0  3244.5  5.6442 0.09621 .
Residuals    3 1724.5   574.8                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00290.Valine..leucine.and.isoleucine.biosynthesis..PATH.ko00290. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2   39.0 19.5000       9 0.05399 .
Residuals    3    6.5  2.1667                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00534.Glycosaminoglycan.biosynthesis...heparan.sulfate...heparin..PATH.ko00534. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  112.0  56.000  0.8337 0.5153
Residuals    3  201.5  67.167               

 Response X00626.Naphthalene.degradation..PATH.ko00626. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  1.3333  0.6667  0.1111 0.8984
Residuals    3 18.0000  6.0000               

 Response X00062.Fatty.acid.elongation..PATH.ko00062. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 26.333  13.167  1.1286 0.4311
Residuals    3 35.000  11.667               

 Response X00512.Mucin.type.O.glycan.biosynthesis..PATH.ko00512. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    156  78.000    2.34 0.2441
Residuals    3    100  33.333               

 Response X04022.cGMP...PKG.signaling.pathway..PATH.ko04022. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 4.3333  2.1667       1 0.4648
Residuals    3 6.5000  2.1667               

 Response X04218.Cellular.senescence..PATH.ko04218. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  69.333  34.667  0.7536  0.543
Residuals    3 138.000  46.000               

 Response X00196.Photosynthesis...antenna.proteins..PATH.ko00196. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  2.3333  1.1667  0.2692 0.7807
Residuals    3 13.0000  4.3333               

 Response X00980.Metabolism.of.xenobiotics.by.cytochrome.P450..PATH.ko00980. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 5.3333  2.6667       2 0.2806
Residuals    3 4.0000  1.3333               

 Response X04210.Apoptosis..PATH.ko04210. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   43.0 21.5000   2.434 0.2354
Residuals    3   26.5  8.8333               

 Response X04216.Ferroptosis..PATH.ko04216. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2    273 136.500  24.088 0.01419 *
Residuals    3     17   5.667                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04630.Jak.STAT.signaling.pathway..PATH.ko04630. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 233.33 116.667  3.8043 0.1504
Residuals    3  92.00  30.667               

 Response X00981.Insect.hormone.biosynthesis..PATH.ko00981. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1.3333 0.66667       1 0.4648
Residuals    3 2.0000 0.66667               

 Response X04390.Hippo.signaling.pathway..PATH.ko04390. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   13.0     6.5  1.8571 0.2987
Residuals    3   10.5     3.5               

 Response X04392.Hippo.signaling.pathway...multiple.species..PATH.ko04392. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2.3333  1.1667  1.1667 0.4219
Residuals    3 3.0000  1.0000               

 Response X04510.Focal.adhesion..PATH.ko04510. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  50.333  25.167  0.5945 0.6061
Residuals    3 127.000  42.333               

 Response X04514.Cell.adhesion.molecules..CAMs...PATH.ko04514. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2044.3  1022.2  0.8881 0.4978
Residuals    3 3453.0  1151.0               

 Response X04064.NF.kappa.B.signaling.pathway..PATH.ko04064. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 4.3333 2.16667     2.6 0.2213
Residuals    3 2.5000 0.83333               

 Response X04330.Notch.signaling.pathway..PATH.ko04330. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 972.33  486.17  3.8331 0.1492
Residuals    3 380.50  126.83               

 Response X04340.Hedgehog.signaling.pathway..PATH.ko04340. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2.3333  1.1667  0.3889 0.7077
Residuals    3 9.0000  3.0000               

 Response X04520.Adherens.junction..PATH.ko04520. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  181.0   90.50  0.6519  0.582
Residuals    3  416.5  138.83               

 Response X00004.KEGG.modules.in.global.maps.only :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X00460.Cyanoamino.acid.metabolism..PATH.ko00460. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X00525.Acarbose.and.validamycin.biosynthesis..PATH.ko00525. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X00533.Glycosaminoglycan.biosynthesis...keratan.sulfate..PATH.ko00533. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X00601.Glycosphingolipid.biosynthesis...lacto.and.neolacto.series..PATH.ko00601. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X00604.Glycosphingolipid.biosynthesis...ganglio.series..PATH.ko00604. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 21.333  10.667  1.7778 0.3096
Residuals    3 18.000   6.000               

 Response X00720.Carbon.fixation.pathways.in.prokaryotes..PATH.ko00720. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667     0.5 0.6495
Residuals    3 1.00000 0.33333               

 Response X00904.Diterpenoid.biosynthesis..PATH.ko00904. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X00940.Phenylpropanoid.biosynthesis..PATH.ko00940. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1.3333 0.66667       1 0.4648
Residuals    3 2.0000 0.66667               

 Response X00941.Flavonoid.biosynthesis..PATH.ko00941. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X00982.Drug.metabolism...cytochrome.P450..PATH.ko00982. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667       1 0.4648
Residuals    3 0.50000 0.16667               

 Response X00983.Drug.metabolism...other.enzymes..PATH.ko00983. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1.3333 0.66667     0.5 0.6495
Residuals    3 4.0000 1.33333               

 Response X01051.Biosynthesis.of.ansamycins..PATH.ko01051. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  8.3333  4.1667       1 0.4648
Residuals    3 12.5000  4.1667               

 Response X04075.Plant.hormone.signal.transduction..PATH.ko04075. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667       1 0.4648
Residuals    3 0.50000 0.16667               

 Response X04114.Oocyte.meiosis..PATH.ko04114. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X04115.p53.signaling.pathway..PATH.ko04115. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X04341.Hedgehog.signaling.pathway...fly..PATH.ko04341. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  9.3333  4.6667  0.7778 0.5344
Residuals    3 18.0000  6.0000               

 Response X04512.ECM.receptor.interaction..PATH.ko04512. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

Run ANOVA for each category of interest (significant in MANOVA)

# Carbon Metabolism
tuss_tIV_aov1<-aov(X01200.Carbon.metabolism..PATH.ko01200.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov1)
            Df    Sum Sq   Mean Sq F value Pr(>F)  
Timepoint    2 1.715e+10 8.576e+09   17.66 0.0219 *
Residuals    3 1.457e+09 4.856e+08                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov1)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X01200.Carbon.metabolism..PATH.ko01200. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
          diff        lwr       upr     p adj
T24-T0 -111816 -203904.37 -19727.63 0.0298795
T4-T0  -114963 -207051.37 -22874.63 0.0277099
T4-T24   -3147  -95235.37  88941.37 0.9888620
# Ribosome
tuss_tIV_aov2<-aov(X03010.Ribosome..PATH.ko03010.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov2)
            Df    Sum Sq   Mean Sq F value Pr(>F)  
Timepoint    2 1.325e+10 6.625e+09   17.08 0.0229 *
Residuals    3 1.164e+09 3.879e+08                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov2)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X03010.Ribosome..PATH.ko03010. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
           diff         lwr       upr     p adj
T24-T0 113712.0   31407.572 196016.43 0.0209743
T4-T0   72348.5   -9955.928 154652.93 0.0693890
T4-T24 -41363.5 -123667.928  40940.93 0.2369013
# RNA Degradation
tuss_tIV_aov3<-aov(X03018.RNA.degradation..PATH.ko03018.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov3)
            Df    Sum Sq   Mean Sq F value  Pr(>F)   
Timepoint    2 2.458e+10 1.229e+10   116.5 0.00143 **
Residuals    3 3.164e+08 1.055e+08                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov3)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X03018.RNA.degradation..PATH.ko03018. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
         diff        lwr       upr     p adj
T24-T0 114012  71097.852 156926.15 0.0032286
T4-T0  150206 107291.852 193120.15 0.0014592
T4-T24  36194  -6720.148  79108.15 0.0768641
# Fatty Acid Metabolism
tuss_tIV_aov4<-aov(X01212.Fatty.acid.metabolism..PATH.ko01212.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov4)
            Df    Sum Sq   Mean Sq F value   Pr(>F)    
Timepoint    2 1.400e+09 700208653   166.6 0.000843 ***
Residuals    3 1.261e+07   4202636                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov4)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X01212.Fatty.acid.metabolism..PATH.ko01212. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
         diff        lwr        upr     p adj
T24-T0 -32382 -40948.603 -23815.397 0.0011771
T4-T0  -32435 -41001.603 -23868.397 0.0011718
T4-T24    -53  -8619.603   8513.603 0.9996316
# Butonaote Metabolism
tuss_tIV_aov5<-aov(X00650.Butanoate.metabolism..PATH.ko00650.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov5)
            Df    Sum Sq   Mean Sq F value Pr(>F)  
Timepoint    2 916283691 458141846   11.48 0.0393 *
Residuals    3 119745259  39915086                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov5)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00650.Butanoate.metabolism..PATH.ko00650. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
           diff       lwr         upr     p adj
T24-T0 -26410.5 -52811.25    -9.74956 0.0499522
T4-T0  -26014.5 -52415.25   386.25044 0.0519416
T4-T24    396.0 -26004.75 26796.75044 0.9978379
# Glycolysis Gluconeogenesis
tuss_tIV_aov6<-aov(X00010.Glycolysis...Gluconeogenesis..PATH.ko00010.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov6)
            Df    Sum Sq   Mean Sq F value Pr(>F)  
Timepoint    2 646115961 323057980   29.34 0.0107 *
Residuals    3  33029853  11009951                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov6)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00010.Glycolysis...Gluconeogenesis..PATH.ko00010. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
           diff       lwr       upr     p adj
T24-T0 -21193.5 -35059.16 -7327.844 0.0158228
T4-T0  -22750.5 -36616.16 -8884.844 0.0129554
T4-T24  -1557.0 -15422.66 12308.656 0.8898939
# Caulobacter Cell Cycle
tuss_tIV_aov7<-aov(X04112.Cell.cycle...Caulobacter..PATH.ko04112.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov7)
            Df    Sum Sq   Mean Sq F value  Pr(>F)   
Timepoint    2 2.484e+09 1.242e+09   41.97 0.00641 **
Residuals    3 8.879e+07 2.960e+07                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov7)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X04112.Cell.cycle...Caulobacter..PATH.ko04112. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
          diff       lwr      upr     p adj
T24-T0 16215.0 -6518.418 38948.42 0.1144336
T4-T0  48924.5 26191.082 71657.92 0.0059536
T4-T24 32709.5  9976.082 55442.92 0.0187381
# Nicotinate and Nicotinamide Metabolism
tuss_tIV_aov8<-aov(X00760.Nicotinate.and.nicotinamide.metabolism..PATH.ko00760.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov8)
            Df    Sum Sq  Mean Sq F value Pr(>F)  
Timepoint    2 140469145 70234573   14.45 0.0288 *
Residuals    3  14584946  4861649                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov8)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00760.Nicotinate.and.nicotinamide.metabolism..PATH.ko00760. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
         diff        lwr        upr     p adj
T24-T0 -10082 -19295.816  -868.1844 0.0394901
T4-T0  -10437 -19650.816 -1223.1844 0.0360172
T4-T24   -355  -9568.816  8858.8156 0.9858779
# Degradation of Aromatic Compounds
tuss_tIV_aov9<-aov(X01220.Degradation.of.aromatic.compounds..PATH.ko01220.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov9)
            Df   Sum Sq  Mean Sq F value Pr(>F)  
Timepoint    2 92377264 46188632   27.22 0.0119 *
Residuals    3  5089767  1696589                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov9)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X01220.Degradation.of.aromatic.compounds..PATH.ko01220. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
          diff        lwr       upr     p adj
T24-T0 -8712.0 -14154.971 -3269.029 0.0138964
T4-T0  -7871.5 -13314.471 -2428.529 0.0184739
T4-T24   840.5  -4602.471  6283.471 0.8078666
# Starch and Sucrose Metabolism
tuss_tIV_aov10<-aov(X00500.Starch.and.sucrose.metabolism..PATH.ko00500.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov10)
            Df   Sum Sq  Mean Sq F value  Pr(>F)   
Timepoint    2 28026154 14013077    37.8 0.00746 **
Residuals    3  1112040   370680                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov10)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00500.Starch.and.sucrose.metabolism..PATH.ko00500. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
          diff       lwr       upr     p adj
T24-T0 -4423.5 -6967.678 -1879.322 0.0109892
T4-T0  -4730.5 -7274.678 -2186.322 0.0090720
T4-T24  -307.0 -2851.178  2237.178 0.8746709
# Porphyrin and Chlorophyll Metabolism
tuss_tIV_aov11<-aov(X00860.Porphyrin.and.chlorophyll.metabolism..PATH.ko00860.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov11)
            Df  Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 8406391 4203196   12.15 0.0364 *
Residuals    3 1037565  345855                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov11)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00860.Porphyrin.and.chlorophyll.metabolism..PATH.ko00860. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
          diff       lwr      upr     p adj
T24-T0 -1869.5 -4327.007  588.007 0.0985258
T4-T0  -2854.0 -5311.507 -396.493 0.0336923
T4-T24  -984.5 -3442.007 1473.007 0.3469692
# Pyruvate Metabolism
tuss_tIV_aov12<-aov(X00620.Pyruvate.metabolism..PATH.ko00620.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov12)
            Df   Sum Sq  Mean Sq F value  Pr(>F)   
Timepoint    2 35362292 17681146   49.72 0.00501 **
Residuals    3  1066810   355603                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov12)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00620.Pyruvate.metabolism..PATH.ko00620. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
          diff       lwr       upr     p adj
T24-T0 -5278.0 -7769.901 -2786.099 0.0062345
T4-T0  -5011.5 -7503.401 -2519.599 0.0072404
T4-T24   266.5 -2225.401  2758.401 0.8992519
# Nitrotoluene Degradation
tuss_tIV_aov13<-aov(X00633.Nitrotoluene.degradation..PATH.ko00633.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov13)
            Df   Sum Sq Mean Sq F value  Pr(>F)   
Timepoint    2 18660459 9330230   50.54 0.00489 **
Residuals    3   553800  184600                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov13)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00633.Nitrotoluene.degradation..PATH.ko00633. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
          diff       lwr       upr     p adj
T24-T0 -3784.5 -5579.911 -1989.089 0.0063220
T4-T0  -3696.0 -5491.411 -1900.589 0.0067693
T4-T24    88.5 -1706.911  1883.911 0.9770593
# Thiamine Metabolism
tuss_tIV_aov14<-aov(X00730.Thiamine.metabolism..PATH.ko00730.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov14)
            Df  Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 5096584 2548292   15.98 0.0251 *
Residuals    3  478274  159425                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov14)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00730.Thiamine.metabolism..PATH.ko00730. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
         diff         lwr      upr     p adj
T24-T0  399.5 -1268.99812 2067.998 0.6256537
T4-T0  2124.0   455.50188 3792.498 0.0262734
T4-T24 1724.5    56.00188 3392.998 0.0458849
# Pantothenate and CoA Biosynthesis
tuss_tIV_aov15<-aov(X00770.Pantothenate.and.CoA.biosynthesis..PATH.ko00770.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov15)
            Df  Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 4813879 2406940   27.17  0.012 *
Residuals    3  265765   88588                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov15)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00770.Pantothenate.and.CoA.biosynthesis..PATH.ko00770. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
          diff        lwr       upr     p adj
T24-T0 -2018.5 -3262.2583 -774.7417 0.0133633
T4-T0  -1754.0 -2997.7583 -510.2417 0.0198140
T4-T24   264.5  -979.2583 1508.2583 0.6827983
# Glycerolipid Metabolism
tuss_tIV_aov16<-aov(X00561.Glycerolipid.metabolism..PATH.ko00561.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov16)
            Df  Sum Sq Mean Sq F value  Pr(>F)   
Timepoint    2 6715964 3357982   33.39 0.00891 **
Residuals    3  301717  100572                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov16)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00561.Glycerolipid.metabolism..PATH.ko00561. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
          diff       lwr      upr     p adj
T24-T0 -2234.0 -3559.217 -908.783 0.0119989
T4-T0  -2254.5 -3579.717 -929.283 0.0116915
T4-T24   -20.5 -1345.717 1304.717 0.9977007
# Arginine and Proline Metabolism
tuss_tIV_aov17<-aov(X00330.Arginine.and.proline.metabolism..PATH.ko00330.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov17)
            Df  Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 3117270 1558635   11.93 0.0373 *
Residuals    3  391951  130650                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov17)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00330.Arginine.and.proline.metabolism..PATH.ko00330. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
          diff       lwr       upr     p adj
T24-T0 -1695.0 -3205.438 -184.5617 0.0369289
T4-T0  -1275.5 -2785.938  234.9383 0.0766292
T4-T24   419.5 -1090.938 1929.9383 0.5478638
# Sulfur Relay System
tuss_tIV_aov19<-aov(X04122.Sulfur.relay.system..PATH.ko04122.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov19)
            Df  Sum Sq Mean Sq F value  Pr(>F)   
Timepoint    2 3894102 1947051   53.01 0.00456 **
Residuals    3  110186   36729                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov19)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X04122.Sulfur.relay.system..PATH.ko04122. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
         diff       lwr     upr     p adj
T24-T0  443.5 -357.3502 1244.35 0.1967214
T4-T0  1887.0 1086.1498 2687.85 0.0045776
T4-T24 1443.5  642.6498 2244.35 0.0099157
# Histidine Metabolism
tuss_tIV_aov20<-aov(X00340.Histidine.metabolism..PATH.ko00340.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov20)
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 398749  199375   11.11  0.041 *
Residuals    3  53825   17942                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov20)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00340.Histidine.metabolism..PATH.ko00340. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
         diff        lwr      upr     p adj
T24-T0 -631.0 -1190.7307 -71.2693 0.0364819
T4-T0  -336.5  -896.2307 223.2307 0.1664416
T4-T24  294.5  -265.2307 854.2307 0.2173393
# Steroid Hormone Biosynthesis
tuss_tIV_aov23<-aov(X00140.Steroid.hormone.biosynthesis..PATH.ko00140.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov23)
            Df Sum Sq Mean Sq F value  Pr(>F)   
Timepoint    2 305292  152646   78.14 0.00258 **
Residuals    3   5861    1954                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov23)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00140.Steroid.hormone.biosynthesis..PATH.ko00140. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
         diff       lwr       upr     p adj
T24-T0 -409.5 -594.1947 -224.8053 0.0054615
T4-T0  -526.0 -710.6947 -341.3053 0.0026379
T4-T24 -116.5 -301.1947   68.1947 0.1503351
# Sesquiterpenoid and Triterpenoid Biosynthesis
tuss_tIV_aov24<-aov(X00909.Sesquiterpenoid.and.triterpenoid.biosynthesis..PATH.ko00909.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov24)
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 446971  223485   18.67 0.0203 *
Residuals    3  35917   11972                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov24)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00909.Sesquiterpenoid.and.triterpenoid.biosynthesis..PATH.ko00909. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
        diff        lwr       upr     p adj
T24-T0 264.5 -192.73255  721.7325 0.1802036
T4-T0  664.0  206.76745 1121.2325 0.0182605
T4-T24 399.5  -57.73255  856.7325 0.0704410
# Benzoate Degradation
tuss_tIV_aov25<-aov(X00362.Benzoate.degradation..PATH.ko00362.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov25)
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 165859   82930    10.7 0.0431 *
Residuals    3  23257    7752                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov25)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00362.Benzoate.degradation..PATH.ko00362. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
         diff      lwr       upr     p adj
T24-T0 -384.5 -752.425 -16.57501 0.0445771
T4-T0  -308.5 -676.425  59.42499 0.0779744
T4-T24   76.0 -291.925 443.92499 0.6959900
# Chloroalkane and Chloroalkene Degradation
tuss_tIV_aov26<-aov(X00625.Chloroalkane.and.chloroalkene.degradation..PATH.ko00625.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov26)
            Df Sum Sq Mean Sq F value  Pr(>F)   
Timepoint    2 163596   81798   80.46 0.00248 **
Residuals    3   3050    1017                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov26)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00625.Chloroalkane.and.chloroalkene.degradation..PATH.ko00625. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
       diff       lwr       upr     p adj
T24-T0 -336 -469.2407 -202.7593 0.0037577
T4-T0  -363 -496.2407 -229.7593 0.0030009
T4-T24  -27 -160.2407  106.2407 0.7044936
# Biotin Metabolism
tuss_tIV_aov27<-aov(X00780.Biotin.metabolism..PATH.ko00780.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov27)
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2  52292   26146    23.2  0.015 *
Residuals    3   3381    1127                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov27)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00780.Biotin.metabolism..PATH.ko00780. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
         diff       lwr      upr     p adj
T24-T0 -174.0 -314.2845 -33.7155 0.0282028
T4-T0  -215.5 -355.7845 -75.2155 0.0156017
T4-T24  -41.5 -181.7845  98.7845 0.5133303
# Lysine Biosynthesis
tuss_tIV_aov28<-aov(X00300.Lysine.biosynthesis..PATH.ko00300.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov28)
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2  41825   20913   28.49 0.0112 *
Residuals    3   2202     734                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov28)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00300.Lysine.biosynthesis..PATH.ko00300. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
       diff       lwr        upr     p adj
T24-T0 -123 -236.2129  -9.787139 0.0402429
T4-T0  -203 -316.2129 -89.787139 0.0100645
T4-T24  -80 -193.2129  33.212861 0.1169023
# MAPK Signaling Pathway
tuss_tIV_aov29<-aov(X04016.MAPK.signaling.pathway...plant..PATH.ko04016.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov29)
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2  44417   22209    10.9  0.042 *
Residuals    3   6110    2037                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov29)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X04016.MAPK.signaling.pathway...plant..PATH.ko04016. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
       diff       lwr       upr     p adj
T24-T0 -209 -397.5775 -20.42247 0.0381737
T4-T0  -128 -316.5775  60.57753 0.1280147
T4-T24   81 -107.5775 269.57753 0.3110593
# Arginine Biosynthesis
tuss_tIV_aov30<-aov(X00220.Arginine.biosynthesis..PATH.ko00220.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov30)
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2  23081   11541   13.71  0.031 *
Residuals    3   2525     842                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov30)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00220.Arginine.biosynthesis..PATH.ko00220. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
       diff       lwr        upr     p adj
T24-T0 -129 -250.2442  -7.755849 0.0425255
T4-T0  -134 -255.2442 -12.755849 0.0384578
T4-T24   -5 -126.2442 116.244151 0.9838494
# Staurosporine Biosynthesis
tuss_tIV_aov32<-aov(X00404.Staurosporine.biosynthesis..PATH.ko00404.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov32)
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2  357.3  178.67      16 0.0251 *
Residuals    3   33.5   11.17                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov32)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X00404.Staurosporine.biosynthesis..PATH.ko00404. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
       diff        lwr         upr     p adj
T24-T0  -18 -31.963989 -4.03601054 0.0253892
T4-T0   -14 -27.963989 -0.03601054 0.0496675
T4-T24    4  -9.963989 17.96398946 0.5310290
# Ferroptosis
tuss_tIV_aov33<-aov(X04216.Ferroptosis..PATH.ko04216.~Timepoint,data=tuss_tIV_stats)
summary.aov(tuss_tIV_aov33)
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2    273  136.50   24.09 0.0142 *
Residuals    3     17    5.67                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_tIV_aov33)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = X04216.Ferroptosis..PATH.ko04216. ~ Timepoint, data = tuss_tIV_stats)

$Timepoint
       diff        lwr       upr     p adj
T24-T0 -1.5 -11.447446  8.447446 0.8153751
T4-T0  13.5   3.552554 23.447446 0.0220370
T4-T24 15.0   5.052554 24.947446 0.0164358

Plot the significant Tuss-MT KEGG tier IV categories by timepoint as a single barchart.

tuss_tIV_sub_bardata$Sample <- factor(tuss_tIV_sub_bardata$Sample, levels=c("Tuss-MT-T24","Tuss-MT-T4","Tuss-MT-T0"))

tuss_tIV_sub_bardata$Tier.IV <- factor (tuss_tIV_sub_bardata$Tier.IV, levels=c("Cell cycle - Caulobacter (K04112)","RNA degradation (K03018)","Ribosome (K03010)","Degradation of aromatic compounds (K01220)","Fatty acid metabolism (K01212)","Carbon metabolism (K01200)","Nicotinate and nicotinamide metabolism (K00760)","Butanoate metabolism (K006650)","Glycolysis-Gluconeogenesis (K00010)"))

tuss_tIV_sub_MT_barplot<-ggplot(tuss_tIV_sub_bardata, aes(x = Tier.IV, y=Mean, fill=Sample)) + geom_bar(stat = "identity", position = "dodge", color = "black") + geom_errorbar(aes(ymin = Mean - SD, ymax = Mean +SD), width = 0.2, position = position_dodge(0.9)) + coord_flip() + scale_y_continuous(expand = c(0, 0), limits = c(0, 30), position="bottom") + ylab ("Relative Abundance") + theme_classic() + theme(axis.title.y=element_blank(), axis.text.y=element_blank(), plot.margin = margin(10, 20, 10, 10), legend.position = "bottom", legend.title=element_blank(), legend.text=element_text(size=8)) + scale_fill_manual(values=c("darkgreen","green3","palegreen"), guide=guide_legend(reverse=TRUE))

### Saving as .eps file with R Viewer
# Re-size the viewer to the following dimensions before saving as .eps file
# In Console, type "tuss_ws_dna_tIII_pheatmap"
# In Plot Viewer, click "Export" --> "Save as Image"
# Width: 600  Height: 600
# Click "Update Preview" --> save as "EPS" file type --> rename as Fig.4.Bar
tuss_tIV_sub_MT_barplot

Plot the combined Tuss-MG and WS-MG KEGG tier III categories as a single barchart.

Heatmap for Tier IV categories by sampling timepoints

# Create copy of "tuss_tIV_sum" object to prep for heatmap
tuss_tIV_sub_heatmap<-tuss_tIV_sum

# Keep the first 7 columns
tuss_tIV_sub_heatmap <- tuss_tIV_sub_heatmap[,c(1,8,9,10)]  #This code uses the means of timepoint

# Keep only those categories with significant differences (from ANOVA)

tuss_tIV_sub_heatmap <- subset(tuss_tIV_sub_heatmap, Tier_IV=="00010 Glycolysis / Gluconeogenesis [PATH:ko00010]" | Tier_IV=="00650 Butanoate metabolism [PATH:ko00650]" | Tier_IV=="00760 Nicotinate and nicotinamide metabolism [PATH:ko00760]" | Tier_IV=="01200 Carbon metabolism [PATH:ko01200]" | Tier_IV=="01212 Fatty acid metabolism [PATH:ko01212]" | Tier_IV=="01220 Degradation of aromatic compounds [PATH:ko01220]" | Tier_IV=="03018 RNA degradation [PATH:ko03018]" | Tier_IV=="03010 Ribosome [PATH:ko03010]" | Tier_IV=="04112 Cell cycle - Caulobacter [PATH:ko04112]", select=Tier_IV:meantuss_T24)

colnames(tuss_tIV_sub_heatmap)<-c("Tier_IV","Tuss-MT-T0","Tuss-MT-T4","Tuss-MT-T24")

# Create a vector with categores in the desired order
tuss_tIV_sub_x <- c("00010 Glycolysis / Gluconeogenesis [PATH:ko00010]",
"00650 Butanoate metabolism [PATH:ko00650]",
"00760 Nicotinate and nicotinamide metabolism [PATH:ko00760]",
"01200 Carbon metabolism [PATH:ko01200]",
"01212 Fatty acid metabolism [PATH:ko01212]",
"01220 Degradation of aromatic compounds [PATH:ko01220]",
"03010 Ribosome [PATH:ko03010]",
"03018 RNA degradation [PATH:ko03018]",
"04112 Cell cycle - Caulobacter [PATH:ko04112]")

# Re-sort the data in the desired order
tuss_tIV_sub_heatmap<-tuss_tIV_sub_heatmap %>%
  slice(match(tuss_tIV_sub_x, Tier_IV))

# Convert the first column (Tier categories) into rownames
rownames(tuss_tIV_sub_heatmap) <- tuss_tIV_sub_heatmap$Tier_IV
tuss_tIV_sub_heatmap<-as.data.frame(tuss_tIV_sub_heatmap[-1])

# Rename columns to sample IDs
colnames(tuss_tIV_sub_heatmap)<-c("Tuss-MT-T0","Tuss-MT-T4","Tuss-MT-T24")

# Convert dataframe into a matrix for heatmap
tuss_tIV_sub_heatmap<-as.matrix(tuss_tIV_sub_heatmap)

# Scale matrix values to generate Z-scores
tuss_tIV_sub_heatmap<-scale(t(tuss_tIV_sub_heatmap))

tuss_tIV_sub_heatmap<-t(tuss_tIV_sub_heatmap)

# Specify RColorBrewer custom color palette
col <- colorRampPalette(brewer.pal(10, "RdYlBu"))(256)

### Saving as .eps file with R Viewer
# Re-size the viewer to the following dimensions before saving as .eps file
# In Console, type "tuss_tIV_pheatmap"
# In Plot Viewer, click "Export" --> "Save as Image"
# Width: 600  Height: 600
# Click "Update Preview" --> save as "EPS" file type --> rename as Fig.2.2.Tuss.MT.Heatmap

# Pheatmap
tuss_tIV_sub_pheatmap<-pheatmap(tuss_tIV_sub_heatmap, treeheight_row = 0, treeheight_col = 0,cluster_rows = FALSE, cluster_cols = FALSE)

7.3.2. Wet Sedge Tundra

Look at differences in gene expression patterns for multiple Tier levels within the Wet Sedge tundra between sampling time points.

7.3.2.1. Tier II Expression

Calculate TPM-normalized gene count sums for each WS sample in each Tier II category.

# Calculate TPM-normalized gene count sums for each WS sample in each Tier II category
ws_tII_sum<-tpm_all_exp_ann %>% group_by(Tier_II) %>% summarise_at(vars("S108379","S108381","S108385","S108386","S108388","S108390"), sum)

ws_tII_sum<-ws_tII_sum %>% mutate_at(vars(S108379,S108381,S108385,S108386,S108388,S108390), funs(round(., 0)))

ws_tII_sum<-as.data.frame(ws_tII_sum)

ws_tII_sum<-ws_tII_sum[order(-ws_tII_sum$S108379),]
Wet Sedge Tier II KEGG category summary by sample.
Tier_II S108379 S108381 S108385 S108386 S108388 S108390
4 Metabolism 608,540 617,976 598,817 612,340 581,565 519,432
3 Genetic Information Processing 191,747 201,174 207,020 217,116 234,300 298,547
2 Environmental Information Processing 154,282 134,776 147,488 132,095 138,677 128,939
1 Cellular Processes 45,430 46,073 46,675 38,449 45,457 53,082

Heatmap for Tier II categories by sampling timepoints

# Create copy of "ws_tII_sum" object to prep for heatmap
ws_tII_heatmap<-ws_tII_sum

# Convert the first column (Tier categories) into rownames
rownames(ws_tII_heatmap) <- ws_tII_heatmap$Tier_II
ws_tII_heatmap<-as.data.frame(ws_tII_heatmap[-1])

# Rename columns to sample IDs
colnames(ws_tII_heatmap)<-c("WS1-T0","WS3-T0","WS1-T4","WS2-T4","WS1-T24","WS3-T24")

# Remove rows for "Organismal Systems" and "Human Diseases"
#ws_tII_heatmap <- ws_tII_heatmap[-c(5,6),]

# Convert dataframe into a matrix for heatmap
ws_tII_heatmap<-as.matrix(ws_tII_heatmap)

# Scale matrix values to generate Z-scores
ws_tII_heatmap<-scale(t(ws_tII_heatmap))

ws_tII_heatmap<-t(ws_tII_heatmap)

# Specify RColorBrewer custom color palette
col <- colorRampPalette(brewer.pal(10, "RdYlBu"))(256)

# Pheatmap
pheatmap(ws_tII_heatmap, treeheight_row = 0, treeheight_col = 0,cluster_rows = FALSE, cluster_cols = FALSE)

Calculate mean values from the replicate sums.

# Calculate mean values from the replicate sums
ws_tII_sum$meanWS_T0<-apply(ws_tII_sum[,2:3], 1, mean)
ws_tII_sum$meanWS_T4<-apply(ws_tII_sum[,4:5], 1, mean)
ws_tII_sum$meanWS_T24<-apply(ws_tII_sum[,6:7], 1, mean)
ws_tII_sum<-ws_tII_sum %>% mutate_at(vars(meanWS_T0,meanWS_T4,meanWS_T24), funs(round(., 0)))

# Calculate sd values from the replicate sums
ws_tII_sum$sdWS_T0<-apply(ws_tII_sum[,2:3], 1, sd)
ws_tII_sum$sdWS_T4<-apply(ws_tII_sum[,4:5], 1, sd)
ws_tII_sum$sdWS_T24<-apply(ws_tII_sum[,6:7], 1, sd)
ws_tII_sum<-ws_tII_sum %>% mutate_at(vars(sdWS_T0,sdWS_T4,sdWS_T24), funs(round(., 0)))

# Subset Mean values
ws_tII_mean<-subset(ws_tII_sum, select=c(Tier_II,meanWS_T0,meanWS_T4,meanWS_T24))
names(ws_tII_mean)<-c("Tier II", "WS - T0", "WS - T4", "WS - T24")

# Subset SD values
ws_tII_sd<-subset(ws_tII_sum, select=c(Tier_II,sdWS_T0,sdWS_T4,sdWS_T24))
names(ws_tII_sd)<-c("Tier II", "WS - T0", "WS - T4", "WS - T24")

# Remember "Tier II" as non-numeric values
ws_tII_mean_TierII<-ws_tII_mean$`Tier II`
ws_tII_sd_TierII<-ws_tII_sd$`Tier II`

# Transpose all but first column (Tier II)
ws_tII_mean<-as.data.frame(t(ws_tII_mean[,-1]))
colnames(ws_tII_mean)<-ws_tII_mean_TierII
ws_tII_sd<-as.data.frame(t(ws_tII_sd[,-1]))
colnames(ws_tII_sd)<-ws_tII_sd_TierII

# Combine mean and sd into single column with ± divider
ws_tII_table<-as.data.frame(do.call(cbind, lapply(1:ncol(ws_tII_mean), function(i) paste0(ws_tII_mean[ , i], " ± ", ws_tII_sd[ , i]))))

# Transpose the table back
ws_tII_table<-t(ws_tII_table)

# Rename columns to Sites
colnames(ws_tII_table)<-c("Wet Sedge (T0)", "Wet Sedge (T4)", "Wet Sedge (T24)")

rownames(ws_tII_table)<-ws_tII_mean_TierII

kable(ws_tII_table, caption = "Wet Sedge Tier II KEGG category averages (± standard deviation) by sample.", format.args = list(big.mark=","), align = "l") %>% kable_styling(bootstrap_options = c("striped","hover","condensed"))
Wet Sedge Tier II KEGG category averages (± standard deviation) by sample.
Wet Sedge (T0) Wet Sedge (T4) Wet Sedge (T24)
Metabolism 613258 ± 6672 605578 ± 9562 550498 ± 43935
Genetic Information Processing 196460 ± 6666 212068 ± 7139 266424 ± 45429
Environmental Information Processing 144529 ± 13793 139792 ± 10884 133808 ± 6886
Cellular Processes 45752 ± 455 42562 ± 5817 49270 ± 5392

Run statistical tests to determine if significant differences exist between sampling timepoints for each Tier KEGG category. Click on the Show/Hide button to see the statistics.

# Subset the "sum" values for each sample
ws_tII_stats<-subset(ws_tII_sum, select=c(Tier_II,S108379,S108381,S108385,S108386,S108388,S108390))

rownames(ws_tII_stats) <- ws_tII_stats$Tier_II
ws_tII_stats<-as.data.frame(t(ws_tII_stats[-1]))

# Add the timepoint column to the sum table
ws_tII_stats<-data.frame(Timepoint,ws_tII_stats)

# Subset response variables for MANOVA
ws_tII_stats$response <- as.matrix(ws_tII_stats[, 2:5])

# MANOVA test
ws_tII_manova <- manova(response ~ Timepoint, data=ws_tII_stats)
summary.aov(ws_tII_manova)
 Response Metabolism. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 4687690640 2343845320  3.4031 0.1692
Residuals    3 2066209657  688736552               

 Response Genetic.Information.Processing. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 5395290537 2697645268  3.7481 0.1528
Residuals    3 2159237277  719745759               

 Response Environmental.Information.Processing. :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 115457346  57728673  0.4863 0.6562
Residuals    3 356128565 118709522               

 Response Cellular.Processes. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 45026527 22513264  1.0702 0.4459
Residuals    3 63110575 21036858               

Plot a barchart for Tier II categories by sampling timepoints.

# Place Tier II categories in the preferred order for plotting
ws_tII_bardata$Tier.II <- factor(ws_tII_bardata$Tier.II,levels = c("Metabolism", "Genetic Information Processing", "Environmental Information Processing", "Cellular Processes"))

ws_tII_bardata$Sample <- factor(ws_tII_bardata$Sample,levels=c("WS-T0","WS-T4","WS-T24"))

ws_tII_barplot<-ggplot(ws_tII_bardata, aes(x = Tier.II, y = Mean, fill = Sample)) + geom_bar(stat = "identity", position = "dodge", color="black") + geom_errorbar(aes(ymin = Mean - SD, ymax = Mean + SD), width = 0.2, position = position_dodge(0.9)) + ylab(expression(atop("KEGG Tier II Categories", paste("Transcript Counts (TPM)")))) + theme_classic() + theme(axis.text=element_text(size=10), axis.title=element_text(size=12), axis.title.x=element_blank()) + theme(legend.position = "bottom", legend.title=element_blank(), legend.text=element_text(size=8), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank()) + scale_size(guide=FALSE) + scale_fill_manual(values=c("lightskyblue1", "dodgerblue1", "midnightblue")) + scale_x_discrete(labels = function(Tier.II) str_wrap(Tier.II, width = 10)) + scale_y_continuous(expand = c(0, 0), limits = c(0, 800000)) + annotate(geom="text", x=1.0, y=700000, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=2.0, y=400000, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=3.0, y=250000, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=4.0, y=150000, label="italic(N.S.)", parse=TRUE)
ws_tII_barplot

# Place Tier II categories in the preferred order for plotting
ws_mg_mt_tII_bardata$Tier.II <- factor(ws_mg_mt_tII_bardata$Tier.II,levels = c("Metabolism", "Genetic Information Processing", "Environmental Information Processing", "Cellular Processes"))

# Place Samples in the preferred order for plotting
ws_mg_mt_tII_bardata$Sample <- factor(ws_mg_mt_tII_bardata$Sample,levels=c("WS-MG","WS-MT-T0","WS-MT-T4","WS-MT-T24"))

ws_mg_mt_tII_barplot<-ggplot(ws_mg_mt_tII_bardata, aes(x = Tier.II, y = Mean, fill = Sample)) + geom_bar(stat = "identity", position = "dodge", color="black") + geom_errorbar(aes(ymin = Mean - SD, ymax = Mean + SD), width = 0.2, position = position_dodge(0.9)) + ylab(expression(atop("KEGG Tier II Categories", paste("Gene Counts")))) + theme_classic() + theme(axis.text=element_text(size=10), axis.title=element_text(size=12), axis.title.x=element_blank()) + theme(legend.position = "bottom", legend.title=element_blank(), legend.text=element_text(size=8), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank()) + scale_size(guide=FALSE) + scale_fill_manual(values=c("black", "lightskyblue1", "dodgerblue1", "midnightblue")) + scale_x_discrete(labels = function(Tier.II) str_wrap(Tier.II, width = 10)) + scale_y_continuous(expand = c(0, 0), limits = c(0, 800000)) + annotate(geom="text", x=1.12, y=700000, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=2.12, y=400000, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=3.12, y=250000, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=4.12, y=150000, label="italic(N.S.)", parse=TRUE)
ws_mg_mt_tII_barplot

7.3.2.2. Tier III Expression

Calculate TPM-normalized gene count sums for each WS sample in each Tier III category.

# Calculate TPM-normalized gene count sums for each WS sample in each Tier III category
ws_tIII_sum<-tpm_all_exp_ann %>% group_by(Tier_III) %>% summarise_at(vars("S108379","S108381","S108385","S108386","S108388","S108390"), sum)
ws_tIII_sum<-ws_tIII_sum %>% mutate_at(vars(S108379,S108381,S108385,S108386,S108388,S108390), funs(round(., 0)))
ws_tIII_sum<-as.data.frame(ws_tIII_sum)
ws_tIII_sum<-ws_tIII_sum[order(-ws_tIII_sum$S108379),]
# Calculate mean values from the replicate sums
ws_tIII_sum$meanWS_T0<-apply(ws_tIII_sum[,2:3], 1, mean)
ws_tIII_sum$meanWS_T4<-apply(ws_tIII_sum[,4:5], 1, mean)
ws_tIII_sum$meanWS_T24<-apply(ws_tIII_sum[,6:7], 1, mean)
ws_tIII_sum<-ws_tIII_sum %>% mutate_at(vars(meanWS_T0,meanWS_T4,meanWS_T24), funs(round(., 0)))

# Calculate sd values from the replicate sums
ws_tIII_sum$sdWS_T0<-apply(ws_tIII_sum[,2:3], 1, sd)
ws_tIII_sum$sdWS_T4<-apply(ws_tIII_sum[,4:5], 1, sd)
ws_tIII_sum$sdWS_T24<-apply(ws_tIII_sum[,6:7], 1, sd)
ws_tIII_sum<-ws_tIII_sum %>% mutate_at(vars(sdWS_T0,sdWS_T4,sdWS_T24), funs(round(., 0)))

# Write data to .csv file
write.csv(ws_tIII_sum, 'Norm.Results/ws.rna.tIII.mean.sd.csv')

# Subset Mean values
ws_tIII_mean<-subset(ws_tIII_sum, select=c(Tier_III,meanWS_T0,meanWS_T4,meanWS_T24))
names(ws_tIII_mean)<-c("Tier III", "WS - T0", "WS - T4", "WS - T24")

# Subset SD values
ws_tIII_sd<-subset(ws_tIII_sum, select=c(Tier_III,sdWS_T0,sdWS_T4,sdWS_T24))
names(ws_tIII_sd)<-c("Tier III", "WS - T0", "WS - T4", "WS - T24")

# Remember "Tier III" as non-numeric values
ws_tIII_mean_TierIII<-ws_tIII_mean$`Tier III`
ws_tIII_sd_TierIII<-ws_tIII_sd$`Tier III`

# Transpose all but first column (Tier II)
ws_tIII_mean<-as.data.frame(t(ws_tIII_mean[,-1]))
colnames(ws_tIII_mean)<-ws_tIII_mean_TierIII
ws_tIII_sd<-as.data.frame(t(ws_tIII_sd[,-1]))
colnames(ws_tIII_sd)<-ws_tIII_sd_TierIII

# Combine mean and sd into single column with ± divider
ws_tIII_table<-as.data.frame(do.call(cbind, lapply(1:ncol(ws_tIII_mean), function(i) paste0(ws_tIII_mean[ , i], " ± ", ws_tIII_sd[ , i]))))

# Transpose the table back
ws_tIII_table<-t(ws_tIII_table)

# Rename columns to Sites
colnames(ws_tIII_table)<-c("Wet Sedge (T0)", "Wet Sedge (T4)", "Wet Sedge (T24)")

rownames(ws_tIII_table)<-ws_tIII_mean_TierIII

Run statistical tests to determine if significant differences exist between sampling timepoints for each Tier KEGG category. Click on the Show/Hide button to see the statistics.

# Subset the "sum" values for each sample
ws_tIII_stats<-subset(ws_tIII_sum, select=c(Tier_III,S108379,S108381,S108385,S108386,S108388,S108390))

rownames(ws_tIII_stats) <- ws_tIII_stats$Tier_III
ws_tIII_stats<-as.data.frame(t(ws_tIII_stats[-1]))

# Add the timepoint column to the sum table
ws_tIII_stats<-data.frame(Timepoint,ws_tIII_stats)

# Subset response variables for MANOVA
ws_tIII_stats$response <- as.matrix(ws_tIII_stats[, 2:26])

# MANOVA test
ws_tIII_manova <- manova(response ~ Timepoint, data=ws_tIII_stats)
summary.aov(ws_tIII_manova)
 Response Overview. :
            Df    Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 3.229e+09 1614478885  3.4671  0.166
Residuals    3 1.397e+09  465658621               

 Response Translation. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 3848660653 1924330326  4.1167  0.138
Residuals    3 1402321521  467440507               

 Response Membrane.transport. :
            Df    Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2  84881827 42440914  0.7249 0.5536
Residuals    3 175650477 58550159               

 Response Carbohydrate.metabolism. :
            Df    Sum Sq   Mean Sq F value  Pr(>F)  
Timepoint    2 263005410 131502705  15.884 0.02535 *
Residuals    3  24836953   8278984                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Energy.metabolism. :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2  80135239  40067619  0.3088 0.7552
Residuals    3 389251884 129750628               

 Response Nucleotide.metabolism. :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 744581304 372290652  1.8933 0.2939
Residuals    3 589917974 196639325               

 Response Folding..sorting.and.degradation. :
            Df    Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 199525327 99762663  1.6966 0.3214
Residuals    3 176399661 58799887               

 Response Metabolism.of.cofactors.and.vitamins. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 17685344  8842672  0.5937 0.6064
Residuals    3 44681521 14893840               

 Response Signal.transduction. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 74629272 37314636  1.1404 0.4282
Residuals    3 98166071 32722024               

 Response Lipid.metabolism. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 47142823 23571412  3.2784 0.1759
Residuals    3 21569597  7189866               

 Response Cellular.community...prokaryotes. :
            Df   Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 11370262 5685131   1.032  0.456
Residuals    3 16527253 5509084               

 Response Amino.acid.metabolism. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2557696 1278848   1.138 0.4288
Residuals    3 3371439 1123813               

 Response Replication.and.repair. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2159985 1079993  0.3516 0.7292
Residuals    3 9215090 3071697               

 Response Cell.growth.and.death. :
            Df   Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 13096993 6548496  1.9885  0.282
Residuals    3  9879495 3293165               

 Response Xenobiotics.biodegradation.and.metabolism. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 44485707 22242854  3.9947 0.1426
Residuals    3 16704091  5568030               

 Response Glycan.biosynthesis.and.metabolism. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2557750 1278875  0.8335 0.5154
Residuals    3 4603221 1534407               

 Response Metabolism.of.other.amino.acids. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1212988  606494  1.0782 0.4438
Residuals    3 1687578  562526               

 Response Metabolism.of.terpenoids.and.polyketides. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  314281  157141  0.3303 0.7419
Residuals    3 1427130  475710               

 Response Transport.and.catabolism. :
            Df   Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 11956880 5978440  4.8021 0.1161
Residuals    3  3734878 1244960               

 Response Transcription. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 347953  173977  0.9065 0.4921
Residuals    3 575736  191912               

 Response Cell.motility. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  47612   23806  2.1884 0.2593
Residuals    3  32635   10878               

 Response Biosynthesis.of.other.secondary.metabolites. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  18747  9373.5  1.2568 0.4014
Residuals    3  22374  7458.2               

 Response Cellular.community...eukaryotes. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2074.3 1037.17  1.9939 0.2813
Residuals    3 1560.5  520.17               

 Response Signaling.molecules.and.interaction. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 1336.3  668.17  26.906 0.01213 *
Residuals    3   74.5   24.83                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Enzyme.families. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667       1 0.4648
Residuals    3 0.50000 0.16667               

Run ANOVA for each category of interest (significant in MANOVA)

# Carbohydrate.metabolism.
ws_tIII_aov_carbs<-aov(Carbohydrate.metabolism.~Timepoint,data=ws_tIII_stats)
TukeyHSD(ws_tIII_aov_carbs)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Carbohydrate.metabolism. ~ Timepoint, data = ws_tIII_stats)

$Timepoint
           diff        lwr       upr     p adj
T24-T0 -13645.5 -25669.148 -1621.852 0.0358367
T4-T0     767.0 -11256.648 12790.648 0.9620737
T4-T24  14412.5   2388.852 26436.148 0.0309395
# Signaling Molecules and Interactions
ws_tIII_aov_trans<-aov(Signaling.molecules.and.interaction.~Timepoint,data=ws_tIII_stats)
TukeyHSD(ws_tIII_aov_trans)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Signaling.molecules.and.interaction. ~ Timepoint, data = ws_tIII_stats)

$Timepoint
        diff        lwr         upr     p adj
T24-T0 -36.5 -57.324052 -15.6759477 0.0107391
T4-T0  -20.0 -40.824052   0.8240523 0.0554797
T4-T24  16.5  -4.324052  37.3240523 0.0894354
7.3.2.3. Tier IV Expression

Calculate TPM-normalized gene count sums for each WS sample in each Tier III category.

# Calculate TPM-normalized gene count sums for each WS sample in each Tier III category
ws_tIV_sum<-tpm_all_exp_ann %>% group_by(Tier_IV) %>% summarise_at(vars("S108379","S108381","S108385","S108386","S108388","S108390"), sum)
ws_tIV_sum<-ws_tIV_sum %>% mutate_at(vars(S108379,S108381,S108385,S108386,S108388,S108390), funs(round(., 0)))
ws_tIV_sum<-as.data.frame(ws_tIV_sum)
ws_tIV_sum<-ws_tIV_sum[order(-ws_tIV_sum$S108379),]
# Calculate mean values from the replicate sums
ws_tIV_sum$meanWS_T0<-apply(ws_tIV_sum[,2:3], 1, mean)
ws_tIV_sum$meanWS_T4<-apply(ws_tIV_sum[,4:5], 1, mean)
ws_tIV_sum$meanWS_T24<-apply(ws_tIV_sum[,6:7], 1, mean)
ws_tIV_sum<-ws_tIV_sum %>% mutate_at(vars(meanWS_T0,meanWS_T4,meanWS_T24), funs(round(., 0)))

# Calculate sd values from the replicate sums
ws_tIV_sum$sdWS_T0<-apply(ws_tIV_sum[,2:3], 1, sd)
ws_tIV_sum$sdWS_T4<-apply(ws_tIV_sum[,4:5], 1, sd)
ws_tIV_sum$sdWS_T24<-apply(ws_tIV_sum[,6:7], 1, sd)
ws_tIV_sum<-ws_tIV_sum %>% mutate_at(vars(sdWS_T0,sdWS_T4,sdWS_T24), funs(round(., 0)))

# Write data to .csv file
write.csv(ws_tIV_sum, 'Norm.Results/ws.rna.tIV.mean.sd.csv')

# Subset Mean values
ws_tIV_mean<-subset(ws_tIV_sum, select=c(Tier_IV,meanWS_T0,meanWS_T4,meanWS_T24))
names(ws_tIV_mean)<-c("Tier IV", "WS - T0", "WS - T4", "WS - T24")

# Subset SD values
ws_tIV_sd<-subset(ws_tIV_sum, select=c(Tier_IV,sdWS_T0,sdWS_T4,sdWS_T24))
names(ws_tIV_sd)<-c("Tier IV", "WS - T0", "WS - T4", "WS - T24")

# Remember "Tier IV" as non-numeric values
ws_tIV_mean_TierIV<-ws_tIV_mean$`Tier IV`
ws_tIV_sd_TierIV<-ws_tIV_sd$`Tier IV`

# Transpose all but first column (Tier IV)
ws_tIV_mean<-as.data.frame(t(ws_tIV_mean[,-1]))
colnames(ws_tIV_mean)<-ws_tIV_mean_TierIV
ws_tIV_sd<-as.data.frame(t(ws_tIV_sd[,-1]))
colnames(ws_tIV_sd)<-ws_tIV_sd_TierIV

# Combine mean and sd into single column with ± divider
ws_tIV_table<-as.data.frame(do.call(cbind, lapply(1:ncol(ws_tIV_mean), function(i) paste0(ws_tIV_mean[ , i], " ± ", ws_tIV_sd[ , i]))))

# Transpose the table back
ws_tIV_table<-t(ws_tIV_table)

# Rename columns to Sites
colnames(ws_tIV_table)<-c("Wet Sedge (T0)", "Wet Sedge (T4)", "Wet Sedge (T24)")

rownames(ws_tIV_table)<-ws_tIV_mean_TierIV

#ws_tIV_table

Run statistical tests to determine if significant differences exist between sampling timepoints for each Tier KEGG category. Click on the Show/Hide button to see the statistics.

# Subset the "sum" values for each sample
ws_tIV_stats<-subset(ws_tIV_sum, select=c(Tier_IV,S108379,S108381,S108385,S108386,S108388,S108390))

rownames(ws_tIV_stats) <- ws_tIV_stats$Tier_IV
ws_tIV_stats<-as.data.frame(t(ws_tIV_stats[-1]))

# Add the timepoint column to the sum table
ws_tIV_stats<-data.frame(Timepoint,ws_tIV_stats)

# Subset response variables for MANOVA
ws_tIV_stats$response <- as.matrix(ws_tIV_stats[, 2:227])

# MANOVA test
ws_tIV_manova <- manova(response ~ Timepoint, data=ws_tIV_stats)
summary.aov(ws_tIV_manova)
 Response X01200.Carbon.metabolism..PATH.ko01200. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 2709213926 1354606963  3.1096 0.1856
Residuals    3 1306856322  435618774               

 Response X02010.ABC.transporters..PATH.ko02010. :
            Df    Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2  88690296 44345148  0.9494 0.4792
Residuals    3 140132277 46710759               

 Response X03010.Ribosome..PATH.ko03010. :
            Df     Sum Sq    Mean Sq F value Pr(>F)
Timepoint    2 4196962380 2098481190  3.7537 0.1526
Residuals    3 1677142543  559047514               

 Response X00230.Purine.metabolism..PATH.ko00230. :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 721205942 360602971   1.891 0.2942
Residuals    3 572076112 190692037               

 Response X00190.Oxidative.phosphorylation..PATH.ko00190. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 26780164 13390082  0.6318 0.5902
Residuals    3 63579871 21193290               

 Response X01230.Biosynthesis.of.amino.acids..PATH.ko01230. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 64891137 32445568  1.6422 0.3298
Residuals    3 59273857 19757952               

 Response X02020.Two.component.system..PATH.ko02020. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 71470119 35735060  1.2758 0.3972
Residuals    3 84029147 28009716               

 Response X03018.RNA.degradation..PATH.ko03018. :
            Df    Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 370553612 185276806  2.4979 0.2298
Residuals    3 222521614  74173871               

 Response X02024.Quorum.sensing..PATH.ko02024. :
            Df   Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 17660261 8830131  1.8917 0.2941
Residuals    3 14003388 4667796               

 Response X00010.Glycolysis...Gluconeogenesis..PATH.ko00010. :
            Df   Sum Sq  Mean Sq F value  Pr(>F)  
Timepoint    2 72839132 36419566  17.818 0.02164 *
Residuals    3  6131975  2043992                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00561.Glycerolipid.metabolism..PATH.ko00561. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 48735574 24367787  2.6402 0.2181
Residuals    3 27688564  9229521               

 Response X01210.2.Oxocarboxylic.acid.metabolism..PATH.ko01210. :
            Df   Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 18602361 9301180  3.3251 0.1733
Residuals    3  8391785 2797262               

 Response X04112.Cell.cycle...Caulobacter..PATH.ko04112. :
            Df   Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 11462476 5731238  1.6995  0.321
Residuals    3 10116639 3372213               

 Response X00970.Aminoacyl.tRNA.biosynthesis..PATH.ko00970. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1635331  817665  0.5034 0.6479
Residuals    3 4873087 1624362               

 Response X01212.Fatty.acid.metabolism..PATH.ko01212. :
            Df  Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 4306430 2153215  16.403 0.02425 *
Residuals    3  393813  131271                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00240.Pyrimidine.metabolism..PATH.ko00240. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  903233  451617  0.4385 0.6807
Residuals    3 3090018 1030006               

 Response X03060.Protein.export..PATH.ko03060. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3896580 1948290  1.4619 0.3604
Residuals    3 3998117 1332706               

 Response X00500.Starch.and.sucrose.metabolism..PATH.ko00500. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1007050  503525  0.3963 0.7035
Residuals    3 3811757 1270586               

 Response X00860.Porphyrin.and.chlorophyll.metabolism..PATH.ko00860. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3057000 1528500  0.5861 0.6097
Residuals    3 7823557 2607852               

 Response X00640.Propanoate.metabolism..PATH.ko00640. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3036497 1518249  5.1179 0.1079
Residuals    3  889956  296652               

 Response X00920.Sulfur.metabolism..PATH.ko00920. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3352000 1676000  3.7358 0.1533
Residuals    3 1345903  448634               

 Response X04141.Protein.processing.in.endoplasmic.reticulum..PATH.ko04141. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 64395394 32197697  2.1084  0.268
Residuals    3 45814095 15271365               

 Response X00633.Nitrotoluene.degradation..PATH.ko00633. :
            Df   Sum Sq  Mean Sq F value  Pr(>F)  
Timepoint    2 38234969 19117485  6.7296 0.07782 .
Residuals    3  8522406  2840802                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00520.Amino.sugar.and.nucleotide.sugar.metabolism..PATH.ko00520. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1936987  968494  1.5732  0.341
Residuals    3 1846855  615618               

 Response X00650.Butanoate.metabolism..PATH.ko00650. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2146224 1073112  1.6542  0.328
Residuals    3 1946188  648729               

 Response X00910.Nitrogen.metabolism..PATH.ko00910. :
            Df   Sum Sq  Mean Sq F value Pr(>F)
Timepoint    2 63792093 31896046   1.024 0.4581
Residuals    3 93446501 31148834               

 Response X01220.Degradation.of.aromatic.compounds..PATH.ko01220. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 865365  432683  3.2303 0.1786
Residuals    3 401833  133944               

 Response X00760.Nicotinate.and.nicotinamide.metabolism..PATH.ko00760. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  947060  473530  0.8559 0.5081
Residuals    3 1659803  553268               

 Response X03440.Homologous.recombination..PATH.ko03440. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  128497   64248  0.1669 0.8536
Residuals    3 1154517  384839               

 Response X03030.DNA.replication..PATH.ko03030. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   2533    1267  0.0103 0.9898
Residuals    3 369378  123126               

 Response X00270.Cysteine.and.methionine.metabolism..PATH.ko00270. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 384680  192340  1.2152 0.4106
Residuals    3 474837  158279               

 Response X00550.Peptidoglycan.biosynthesis..PATH.ko00550. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  441252  220626  0.6179 0.5961
Residuals    3 1071261  357087               

 Response X00730.Thiamine.metabolism..PATH.ko00730. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 504147  252073  1.2055 0.4128
Residuals    3 627333  209111               

 Response X00051.Fructose.and.mannose.metabolism..PATH.ko00051. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1539151  769576  3.1536  0.183
Residuals    3  732091  244030               

 Response X00790.Folate.biosynthesis..PATH.ko00790. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 206796  103398  0.8427 0.5123
Residuals    3 368078  122693               

 Response X00900.Terpenoid.backbone.biosynthesis..PATH.ko00900. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 146524   73262  0.4836 0.6576
Residuals    3 454491  151497               

 Response X00040.Pentose.and.glucuronate.interconversions..PATH.ko00040. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 828841  414421  10.344 0.04507 *
Residuals    3 120189   40063                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00360.Phenylalanine.metabolism..PATH.ko00360. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  91534   45767  1.1848 0.4176
Residuals    3 115889   38630               

 Response X03420.Nucleotide.excision.repair..PATH.ko03420. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 487881  243941  4.4508 0.1266
Residuals    3 164426   54809               

 Response X03050.Proteasome..PATH.ko03050. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1222808  611404  0.9031 0.4932
Residuals    3 2031067  677022               

 Response X00630.Glyoxylate.and.dicarboxylate.metabolism..PATH.ko00630. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 758757  379379  1.6011 0.3364
Residuals    3 710837  236946               

 Response X00330.Arginine.and.proline.metabolism..PATH.ko00330. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  98540   49270  0.3567 0.7261
Residuals    3 414365  138122               

 Response X00564.Glycerophospholipid.metabolism..PATH.ko00564. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 273100  136550    1.79 0.3078
Residuals    3 228851   76284               

 Response X00052.Galactose.metabolism..PATH.ko00052. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 377854  188927  3.2718 0.1762
Residuals    3 173232   57744               

 Response X00540.Lipopolysaccharide.biosynthesis..PATH.ko00540. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   97134   48567  0.1289 0.8837
Residuals    3 1130335  376778               

 Response X00450.Selenocompound.metabolism..PATH.ko00450. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1112960  556480  3.3508  0.172
Residuals    3  498217  166072               

 Response X03070.Bacterial.secretion.system..PATH.ko03070. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  119642   59821  0.1185 0.8922
Residuals    3 1513997  504666               

 Response X00130.Ubiquinone.and.other.terpenoid.quinone.biosynthesis..PATH.ko00130. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 447456  223728  1.1255 0.4318
Residuals    3 596365  198788               

 Response X00770.Pantothenate.and.CoA.biosynthesis..PATH.ko00770. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  98052   49026  2.2371 0.2543
Residuals    3  65745   21915               

 Response X00250.Alanine..aspartate.and.glutamate.metabolism..PATH.ko00250. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 557416  278708  2.3603 0.2422
Residuals    3 354249  118083               

 Response X00680.Methane.metabolism..PATH.ko00680. :
            Df   Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  3998761 1999381   0.261 0.7861
Residuals    3 22978387 7659462               

 Response X00620.Pyruvate.metabolism..PATH.ko00620. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 663644  331822   4.993  0.111
Residuals    3 199371   66457               

 Response X03410.Base.excision.repair..PATH.ko03410. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 177752   88876  1.5661 0.3422
Residuals    3 170249   56750               

 Response X04013.MAPK.signaling.pathway...fly..PATH.ko04013. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 179574   89787   0.364 0.7219
Residuals    3 739975  246658               

 Response X00562.Inositol.phosphate.metabolism..PATH.ko00562. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 229433  114717  1.3639  0.379
Residuals    3 252322   84107               

 Response X00030.Pentose.phosphate.pathway..PATH.ko00030. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 260780  130390  3.9724 0.1435
Residuals    3  98473   32824               

 Response X00627.Aminobenzoate.degradation..PATH.ko00627. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  272965  136483  0.2956 0.7635
Residuals    3 1384916  461639               

 Response X00740.Riboflavin.metabolism..PATH.ko00740. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  33408   16704  0.4729 0.6629
Residuals    3 105965   35322               

 Response X00523.Polyketide.sugar.unit.biosynthesis..PATH.ko00523. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  50890   25445  0.4981 0.6504
Residuals    3 153253   51084               

 Response X00061.Fatty.acid.biosynthesis..PATH.ko00061. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 529861  264931  1.1605 0.4234
Residuals    3 684894  228298               

 Response X00750.Vitamin.B6.metabolism..PATH.ko00750. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  37452 18726.0  2.1669 0.2616
Residuals    3  25926  8641.8               

 Response X04122.Sulfur.relay.system..PATH.ko04122. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  35877   17938  0.2862 0.7696
Residuals    3 188067   62689               

 Response X03430.Mismatch.repair..PATH.ko03430. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  88831   44416  0.5677 0.6179
Residuals    3 234697   78232               

 Response X03013.RNA.transport..PATH.ko03013. :
            Df   Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  1968627  984314  0.2746 0.7771
Residuals    3 10754348 3584783               

 Response X03450.Non.homologous.end.joining..PATH.ko03450. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   1261     630  0.0115 0.9887
Residuals    3 165121   55040               

 Response X00473.D.Alanine.metabolism..PATH.ko00473. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  51103   25552  1.6643 0.3264
Residuals    3  46059   15353               

 Response X04016.MAPK.signaling.pathway...plant..PATH.ko04016. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 236853  118427  1.9585 0.2856
Residuals    3 181403   60468               

 Response X02026.Biofilm.formation...Escherichia.coli..PATH.ko02026. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  65821   32910  0.6617  0.578
Residuals    3 149211   49737               

 Response X00480.Glutathione.metabolism..PATH.ko00480. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 188211   94105  1.2248 0.4084
Residuals    3 230503   76834               

 Response X00785.Lipoic.acid.metabolism..PATH.ko00785. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  47701   23851  0.7615 0.5402
Residuals    3  93966   31322               

 Response X00471.D.Glutamine.and.D.glutamate.metabolism..PATH.ko00471. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  57802   28901  1.2402  0.405
Residuals    3  69913   23304               

 Response X00260.Glycine..serine.and.threonine.metabolism..PATH.ko00260. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  35407 17703.5  2.6704 0.2157
Residuals    3  19888  6629.5               

 Response X00364.Fluorobenzoate.degradation..PATH.ko00364. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  55921   27961  1.5364 0.3472
Residuals    3  54598   18199               

 Response X04145.Phagosome..PATH.ko04145. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 9613824 4806912  2.7485 0.2098
Residuals    3 5246671 1748890               

 Response X02025.Biofilm.formation...Pseudomonas.aeruginosa..PATH.ko02025. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 281524  140762  1.1975 0.4147
Residuals    3 352638  117546               

 Response X02060.Phosphotransferase.system..PTS...PATH.ko02060. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  29505   14753  0.9232  0.487
Residuals    3  47938   15979               

 Response X00780.Biotin.metabolism..PATH.ko00780. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 110557   55278  2.1687 0.2614
Residuals    3  76469   25490               

 Response X03008.Ribosome.biogenesis.in.eukaryotes..PATH.ko03008. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  39557   19779  0.1953 0.8323
Residuals    3 303884  101295               

 Response X03022.Basal.transcription.factors..PATH.ko03022. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 350532  175266   1.157 0.4242
Residuals    3 454441  151480               

 Response X00300.Lysine.biosynthesis..PATH.ko00300. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  35329   17664   1.083 0.4425
Residuals    3  48931   16310               

 Response X00340.Histidine.metabolism..PATH.ko00340. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  19927  9963.5  0.9461 0.4802
Residuals    3  31595 10531.7               

 Response X00280.Valine..leucine.and.isoleucine.degradation..PATH.ko00280. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 123456   61728  5.7053 0.09498 .
Residuals    3  32458   10819                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00350.Tyrosine.metabolism..PATH.ko00350. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  16405  8202.7  0.4015 0.7006
Residuals    3  61284 20428.0               

 Response X00511.Other.glycan.degradation..PATH.ko00511. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 164257   82129  2.6534  0.217
Residuals    3  92857   30952               

 Response X00310.Lysine.degradation..PATH.ko00310. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   8161  4080.5  0.8363 0.5145
Residuals    3  14638  4879.5               

 Response X00670.One.carbon.pool.by.folate..PATH.ko00670. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  26904 13452.2  1.7547 0.3129
Residuals    3  22999  7666.3               

 Response X00140.Steroid.hormone.biosynthesis..PATH.ko00140. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 329305  164653  1.1727 0.4204
Residuals    3 421210  140403               

 Response X00410.beta.Alanine.metabolism..PATH.ko00410. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  20149 10074.5    1.16 0.4235
Residuals    3  26054  8684.8               

 Response X00984.Steroid.degradation..PATH.ko00984. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 229724  114862  20.226 0.01814 *
Residuals    3  17037    5679                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00053.Ascorbate.and.aldarate.metabolism..PATH.ko00053. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   9417  4708.5  1.3673 0.3784
Residuals    3  10331  3443.7               

 Response X00430.Taurine.and.hypotaurine.metabolism..PATH.ko00430. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   1236   618.0  0.1105 0.8989
Residuals    3  16780  5593.3               

 Response X04217.Necroptosis..PATH.ko04217. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  42853   21426  1.3352 0.3848
Residuals    3  48141   16047               

 Response X02040.Flagellar.assembly..PATH.ko02040. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  70724   35362  2.1096 0.2679
Residuals    3  50287   16762               

 Response X05111.Biofilm.formation...Vibrio.cholerae..PATH.ko05111. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  78082   39041    0.99 0.4676
Residuals    3 118308   39436               

 Response X00510.N.Glycan.biosynthesis..PATH.ko00510. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  26342   13171  1.1505 0.4257
Residuals    3  34344   11448               

 Response X00071.Fatty.acid.degradation..PATH.ko00071. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  4300.3  2150.2  0.2839  0.771
Residuals    3 22720.5  7573.5               

 Response X00380.Tryptophan.metabolism..PATH.ko00380. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   9997  4998.5  1.3769 0.3765
Residuals    3  10890  3630.2               

 Response X04214.Apoptosis...fly..PATH.ko04214. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2  72441   36220  6.2013 0.08596 .
Residuals    3  17523    5841                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04146.Peroxisome..PATH.ko04146. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  22770 11385.2  1.3664 0.3786
Residuals    3  24997  8332.3               

 Response X00195.Photosynthesis..PATH.ko00195. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  8814.3  4407.2  0.4961 0.6514
Residuals    3 26651.0  8883.7               

 Response X02030.Bacterial.chemotaxis..PATH.ko02030. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2  15409  7704.7  10.574 0.04379 *
Residuals    3   2186   728.7                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X01040.Biosynthesis.of.unsaturated.fatty.acids..PATH.ko01040. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  31370   15685  3.0713  0.188
Residuals    3  15321    5107               

 Response X00600.Sphingolipid.metabolism..PATH.ko00600. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  15967  7983.5  5.0095 0.1106
Residuals    3   4781  1593.7               

 Response X00311.Penicillin.and.cephalosporin.biosynthesis..PATH.ko00311. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3661.0  1830.5  0.5576 0.6224
Residuals    3 9848.5  3282.8               

 Response X00220.Arginine.biosynthesis..PATH.ko00220. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 21097.3 10548.7  5.4586 0.1001
Residuals    3  5797.5  1932.5               

 Response X00362.Benzoate.degradation..PATH.ko00362. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3960.3  1980.2  1.1173 0.4339
Residuals    3 5317.0  1772.3               

 Response X00906.Carotenoid.biosynthesis..PATH.ko00906. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   6057  3028.5  0.9632 0.4752
Residuals    3   9433  3144.3               

 Response X00625.Chloroalkane.and.chloroalkene.degradation..PATH.ko00625. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2096.3 1048.17   2.325 0.2456
Residuals    3 1352.5  450.83               

 Response X00908.Zeatin.biosynthesis..PATH.ko00908. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2209.0 1104.50  1.4157  0.369
Residuals    3 2340.5  780.17               

 Response X00400.Phenylalanine..tyrosine.and.tryptophan.biosynthesis..PATH.ko00400. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  14583  7291.5  0.7523 0.5435
Residuals    3  29077  9692.3               

 Response X00440.Phosphonate.and.phosphinate.metabolism..PATH.ko00440. :
            Df  Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 11575.0  5787.5   13.05 0.0331 *
Residuals    3  1330.5   443.5                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00965.Betalain.biosynthesis..PATH.ko00965. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   4243 2121.50  2.5799 0.2229
Residuals    3   2467  822.33               

 Response X03040.Spliceosome..PATH.ko03040. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    844     422  0.1375 0.8767
Residuals    3   9204    3068               

 Response X04152.AMPK.signaling.pathway..PATH.ko04152. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  44100   22050  0.3013 0.7599
Residuals    3 219555   73185               

 Response X00909.Sesquiterpenoid.and.triterpenoid.biosynthesis..PATH.ko00909. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   24.33   12.17  0.0158 0.9844
Residuals    3 2314.50  771.50               

 Response X04144.Endocytosis..PATH.ko04144. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  74892   37446  0.7119 0.5585
Residuals    3 157808   52603               

 Response X00120.Primary.bile.acid.biosynthesis..PATH.ko00120. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  54.33  27.167  0.2571 0.7888
Residuals    3 317.00 105.667               

 Response X04015.Rap1.signaling.pathway..PATH.ko04015. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 8220.3  4110.2  6.7141 0.07804 .
Residuals    3 1836.5   612.2                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00515.Mannose.type.O.glycan.biosyntheis..PATH.ko00515. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2524.0 1262.00  5.2185 0.1055
Residuals    3  725.5  241.83               

 Response X01055.Biosynthesis.of.vancomycin.group.antibiotics..PATH.ko01055. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2  20443 10221.5  6.4354 0.08218 .
Residuals    3   4765  1588.3                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X03015.mRNA.surveillance.pathway..PATH.ko03015. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 3752.3  1876.2  0.7245 0.5537
Residuals    3 7769.0  2589.7               

 Response X04510.Focal.adhesion..PATH.ko04510. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   3067 1533.50  3.1148 0.1853
Residuals    3   1477  492.33               

 Response X00565.Ether.lipid.metabolism..PATH.ko00565. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 2212.0 1106.00  7.1896 0.07172 .
Residuals    3  461.5  153.83                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04142.Lysosome..PATH.ko04142. :
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 1070.3  535.17  6.2593  0.085 .
Residuals    3  256.5   85.50                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00281.Geraniol.degradation..PATH.ko00281. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1577.3  788.67  1.1069 0.4365
Residuals    3 2137.5  712.50               

 Response X04138.Autophagy...yeast..PATH.ko04138. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1157.3  578.67  1.4991 0.3537
Residuals    3 1158.0  386.00               

 Response X00405.Phenazine.biosynthesis..PATH.ko00405. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    133  66.500  5.3919 0.1015
Residuals    3     37  12.333               

 Response X00590.Arachidonic.acid.metabolism..PATH.ko00590. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 4566.3  2283.2  2.8719  0.201
Residuals    3 2385.0   795.0               

 Response X00514.Other.types.of.O.glycan.biosynthesis..PATH.ko00514. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  763.0   381.5  1.8038 0.3059
Residuals    3  634.5   211.5               

 Response X01057.Biosynthesis.of.type.II.polyketide.products..PATH.ko01057. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1561.3  780.67  5.1191 0.1079
Residuals    3  457.5  152.50               

 Response X04120.Ubiquitin.mediated.proteolysis..PATH.ko04120. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  817.0  408.50  1.9624 0.2852
Residuals    3  624.5  208.17               

 Response X04151.PI3K.Akt.signaling.pathway..PATH.ko04151. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  234.33  117.17  0.2055 0.8248
Residuals    3 1710.50  570.17               

 Response X04530.Tight.junction..PATH.ko04530. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  89.333  44.667  0.4497 0.6748
Residuals    3 298.000  99.333               

 Response X00660.C5.Branched.dibasic.acid.metabolism..PATH.ko00660. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2     67   33.50  0.0554  0.947
Residuals    3   1813  604.33               

 Response X03460.Fanconi.anemia.pathway..PATH.ko03460. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   3153 1576.50  1.9698 0.2842
Residuals    3   2401  800.33               

 Response X01059.Biosynthesis.of.enediyne.antibiotics..PATH.ko01059. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 242.33  121.17  0.9811 0.4701
Residuals    3 370.50  123.50               

 Response X00960.Tropane..piperidine.and.pyridine.alkaloid.biosynthesis..PATH.ko00960. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 120.33  60.167  0.9093 0.4912
Residuals    3 198.50  66.167               

 Response X04140.Autophagy...animal..PATH.ko04140. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1456.0  728.00  1.2927 0.3936
Residuals    3 1689.5  563.17               

 Response X00830.Retinol.metabolism..PATH.ko00830. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 180.33  90.167  0.9927 0.4668
Residuals    3 272.50  90.833               

 Response X04080.Neuroactive.ligand.receptor.interaction..PATH.ko04080. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 394.33 197.167  3.1973 0.1805
Residuals    3 185.00  61.667               

 Response X04014.Ras.signaling.pathway..PATH.ko04014. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 177.33  88.667   4.972 0.1116
Residuals    3  53.50  17.833               

 Response X00100.Steroid.biosynthesis..PATH.ko00100. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    1.0   0.500  0.0073 0.9927
Residuals    3  204.5  68.167               

 Response X04371.Apelin.signaling.pathway..PATH.ko04371. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    444 222.000   2.664 0.2162
Residuals    3    250  83.333               

 Response X00591.Linoleic.acid.metabolism..PATH.ko00591. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2734.3 1367.17  4.3219 0.1308
Residuals    3  949.0  316.33               

 Response X04012.ErbB.signaling.pathway..PATH.ko04012. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 1446.3  723.17  1.2023 0.4136
Residuals    3 1804.5  601.50               

 Response X00020.Citrate.cycle..TCA.cycle...PATH.ko00020. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   6416  3208.2  0.2767 0.7757
Residuals    3  34780 11593.5               

 Response X01053.Biosynthesis.of.siderophore.group.nonribosomal.peptides..PATH.ko01053. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 281.33 140.667  5.4452 0.1004
Residuals    3  77.50  25.833               

 Response X04514.Cell.adhesion.molecules..CAMs...PATH.ko04514. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 394.33 197.167  2.7258 0.2115
Residuals    3 217.00  72.333               

 Response X04010.MAPK.signaling.pathway..PATH.ko04010. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 185.33  92.667  3.5871 0.1601
Residuals    3  77.50  25.833               

 Response X04310.Wnt.signaling.pathway..PATH.ko04310. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 550.33 275.167    5.08 0.1088
Residuals    3 162.50  54.167               

 Response X04210.Apoptosis..PATH.ko04210. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  52.333  26.167  0.4198 0.6906
Residuals    3 187.000  62.333               

 Response X00365.Furfural.degradation..PATH.ko00365. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  169.0    84.5  4.3333 0.1304
Residuals    3   58.5    19.5               

 Response X00472.D.Arginine.and.D.ornithine.metabolism..PATH.ko00472. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 265.33  132.67  1.3007  0.392
Residuals    3 306.00  102.00               

 Response X00903.Limonene.and.pinene.degradation..PATH.ko00903. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  890.33  445.17  0.8658 0.5049
Residuals    3 1542.50  514.17               

 Response X00943.Isoflavonoid.biosynthesis..PATH.ko00943. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 120.33  60.167  1.8325  0.302
Residuals    3  98.50  32.833               

 Response X04810.Regulation.of.actin.cytoskeleton..PATH.ko04810. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  57.333  28.667  0.5911 0.6076
Residuals    3 145.500  48.500               

 Response X00532.Glycosaminoglycan.biosynthesis...chondroitin.sulfate...dermatan.sulfate..PATH.ko00532. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 617.33  308.67  2.8103 0.2053
Residuals    3 329.50  109.83               

 Response X00624.Polycyclic.aromatic.hydrocarbon.degradation..PATH.ko00624. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   2.333   1.167  0.0246 0.9759
Residuals    3 142.500  47.500               

 Response X04330.Notch.signaling.pathway..PATH.ko04330. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 102.33  51.167  2.6239 0.2194
Residuals    3  58.50  19.500               

 Response X04350.TGF.beta.signaling.pathway..PATH.ko04350. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  26.333  13.167  0.2651 0.7834
Residuals    3 149.000  49.667               

 Response X04340.Hedgehog.signaling.pathway..PATH.ko04340. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 30.333  15.167  0.7054 0.5609
Residuals    3 64.500  21.500               

 Response X04630.Jak.STAT.signaling.pathway..PATH.ko04630. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 261.33 130.667  4.1925 0.1353
Residuals    3  93.50  31.167               

 Response X04020.Calcium.signaling.pathway..PATH.ko04020. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 133.33  66.667  5.9701 0.08998 .
Residuals    3  33.50  11.167                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04137.Mitophagy...animal..PATH.ko04137. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   75.0   37.50   0.252 0.7922
Residuals    3  446.5  148.83               

 Response X00531.Glycosaminoglycan.degradation..PATH.ko00531. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  74.333  37.167  1.0619  0.448
Residuals    3 105.000  35.000               

 Response X04011.MAPK.signaling.pathway...yeast..PATH.ko04011. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 69.333  34.667  1.7333  0.316
Residuals    3 60.000  20.000               

 Response X04520.Adherens.junction..PATH.ko04520. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 54.333  27.167  9.0556 0.05357 .
Residuals    3  9.000   3.000                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00073.Cutin..suberine.and.wax.biosynthesis..PATH.ko00073. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 30.333  15.167  1.0581  0.449
Residuals    3 43.000  14.333               

 Response X00363.Bisphenol.degradation..PATH.ko00363. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2     19     9.5  3.1667 0.1822
Residuals    3      9     3.0               

 Response X04024.cAMP.signaling.pathway..PATH.ko04024. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 14.333  7.1667  0.4257 0.6874
Residuals    3 50.500 16.8333               

 Response X00121.Secondary.bile.acid.biosynthesis..PATH.ko00121. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    772     386  1.1029 0.4375
Residuals    3   1050     350               

 Response X04150.mTOR.signaling.pathway..PATH.ko04150. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2     31    15.5  5.1667 0.1067
Residuals    3      9     3.0               

 Response X00643.Styrene.degradation..PATH.ko00643. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2     13  6.5000  2.7857 0.2071
Residuals    3      7  2.3333               

 Response X00930.Caprolactam.degradation..PATH.ko00930. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2   16.0   8.000  0.5275 0.6364
Residuals    3   45.5  15.167               

 Response X04391.Hippo.signaling.pathway..fly..PATH.ko04391. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  127.0  63.500  1.0438 0.4528
Residuals    3  182.5  60.833               

 Response X00563.Glycosylphosphatidylinositol.GPI..anchor.biosynthesis..PATH.ko00563. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2     19   9.500  0.5182 0.6408
Residuals    3     55  18.333               

 Response X00720.Carbon.fixation.pathways.in.prokaryotes..PATH.ko00720. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2     49 24.5000    10.5 0.04419 *
Residuals    3      7  2.3333                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00261.Monobactam.biosynthesis..PATH.ko00261. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 25.333 12.6667  1.3571 0.3804
Residuals    3 28.000  9.3333               

 Response X00623.Toluene.degradation..PATH.ko00623. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  8.333  4.1667  0.2778  0.775
Residuals    3 45.000 15.0000               

 Response X00940.Phenylpropanoid.biosynthesis..PATH.ko00940. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 17.333  8.6667  0.7647  0.539
Residuals    3 34.000 11.3333               

 Response X04111.Cell.cycle...yeast..PATH.ko04111. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 36.333 18.1667  2.8684 0.2012
Residuals    3 19.000  6.3333               

 Response X00534.Glycosaminoglycan.biosynthesis...heparan.sulfate...heparin..PATH.ko00534. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      9   4.500  0.3649 0.7214
Residuals    3     37  12.333               

 Response X04068.FoxO.signaling.pathway..PATH.ko04068. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 42.333  21.167  1.7162 0.3185
Residuals    3 37.000  12.333               

 Response X04668.TNF.signaling.pathway..PATH.ko04668. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  5.3333  2.6667  0.3636 0.7221
Residuals    3 22.0000  7.3333               

 Response X00626.Naphthalene.degradation..PATH.ko00626. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 16.333  8.1667  3.7692 0.1519
Residuals    3  6.500  2.1667               

 Response X01056.Biosynthesis.of.type.II.polyketide.backbone..PATH.ko01056. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 30.333  15.167  1.3788 0.3761
Residuals    3 33.000  11.000               

 Response X04064.NF.kappa.B.signaling.pathway..PATH.ko04064. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 16.333  8.1667  1.6897 0.3225
Residuals    3 14.500  4.8333               

 Response X04070.Phosphatidylinositol.signaling.system..PATH.ko04070. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 6.3333  3.1667  1.4615 0.3605
Residuals    3 6.5000  2.1667               

 Response X04390.Hippo.signaling.pathway..PATH.ko04390. :
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2 30.333  15.167  15.167  0.027 *
Residuals    3  3.000   1.000                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04022.cGMP...PKG.signaling.pathway..PATH.ko04022. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      7     3.5     0.1 0.9077
Residuals    3    105    35.0               

 Response X04110.Cell.cycle..PATH.ko04110. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2   76.0    38.0  8.4444 0.05858 .
Residuals    3   13.5     4.5                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X04550.Signaling.pathways.regulating.pluripotency.of.stem.cells..PATH.ko04550. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2     19  9.5000  2.1923 0.2589
Residuals    3     13  4.3333               

 Response X00062.Fatty.acid.elongation..PATH.ko00062. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 44.333  22.167  1.3571 0.3804
Residuals    3 49.000  16.333               

 Response X00941.Flavonoid.biosynthesis..PATH.ko00941. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      4  2.0000     0.6 0.6037
Residuals    3     10  3.3333               

 Response X00983.Drug.metabolism...other.enzymes..PATH.ko00983. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    1.0 0.50000     0.6 0.6037
Residuals    3    2.5 0.83333               

 Response X04075.Plant.hormone.signal.transduction..PATH.ko04075. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  20.333  10.167  0.1584 0.8602
Residuals    3 192.500  64.167               

 Response X04114.Oocyte.meiosis..PATH.ko04114. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  0.3333  0.1667  0.0455 0.9562
Residuals    3 11.0000  3.6667               

 Response X04130.SNARE.interactions.in.vesicular.transport..PATH.ko04130. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 5.3333  2.6667  5.3333 0.1028
Residuals    3 1.5000  0.5000               

 Response X04139.Mitophagy...yeast..PATH.ko04139. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2.3333  1.1667  1.1667 0.4219
Residuals    3 3.0000  1.0000               

 Response X04512.ECM.receptor.interaction..PATH.ko04512. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.3333 0.16667  0.1111 0.8984
Residuals    3 4.5000 1.50000               

 Response X00004.KEGG.modules.in.global.maps.only :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667       1 0.4648
Residuals    3 0.50000 0.16667               

 Response X00512.Mucin.type.O.glycan.biosynthesis..PATH.ko00512. :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2 40.333  20.167  20.167 0.01822 *
Residuals    3  3.000   1.000                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response X00513.Various.types.of.N.glycan.biosynthesis..PATH.ko00513. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      7  3.5000  0.8077  0.524
Residuals    3     13  4.3333               

 Response X00525.Acarbose.and.validamycin.biosynthesis..PATH.ko00525. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      4 2.00000       3 0.1925
Residuals    3      2 0.66667               

 Response X00791.Atrazine.degradation..PATH.ko00791. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 9.3333  4.6667    1.75 0.3136
Residuals    3 8.0000  2.6667               

 Response X04072.Phospholipase.D.signaling.pathway..PATH.ko04072. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 2.3333  1.1667     0.5 0.6495
Residuals    3 7.0000  2.3333               

 Response X04115.p53.signaling.pathway..PATH.ko04115. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      4  2.0000    0.75 0.5443
Residuals    3      8  2.6667               

 Response X04216.Ferroptosis..PATH.ko04216. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    4.0  2.0000  1.0909 0.4405
Residuals    3    5.5  1.8333               

 Response X00196.Photosynthesis...antenna.proteins..PATH.ko00196. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X00290.Valine..leucine.and.isoleucine.biosynthesis..PATH.ko00290. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667     0.5 0.6495
Residuals    3 1.00000 0.33333               

 Response X00361.Chlorocyclohexane.and.chlorobenzene.degradation..PATH.ko00361. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X00404.Staurosporine.biosynthesis..PATH.ko00404. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  8.3333  4.1667  0.5435 0.6289
Residuals    3 23.0000  7.6667               

 Response X00460.Cyanoamino.acid.metabolism..PATH.ko00460. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    1.0 0.50000       3 0.1925
Residuals    3    0.5 0.16667               

 Response X00533.Glycosaminoglycan.biosynthesis...keratan.sulfate..PATH.ko00533. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667       1 0.4648
Residuals    3 0.50000 0.16667               

 Response X00601.Glycosphingolipid.biosynthesis...lacto.and.neolacto.series..PATH.ko00601. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667       1 0.4648
Residuals    3 0.50000 0.16667               

 Response X00604.Glycosphingolipid.biosynthesis...ganglio.series..PATH.ko00604. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X00904.Diterpenoid.biosynthesis..PATH.ko00904. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      3     1.5     0.5 0.6495
Residuals    3      9     3.0               

 Response X00980.Metabolism.of.xenobiotics.by.cytochrome.P450..PATH.ko00980. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667       1 0.4648
Residuals    3 0.50000 0.16667               

 Response X00981.Insect.hormone.biosynthesis..PATH.ko00981. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2    1.0 0.50000     0.6 0.6037
Residuals    3    2.5 0.83333               

 Response X00982.Drug.metabolism...cytochrome.P450..PATH.ko00982. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667       1 0.4648
Residuals    3 0.50000 0.16667               

 Response X01051.Biosynthesis.of.ansamycins..PATH.ko01051. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667     0.2 0.8288
Residuals    3 2.50000 0.83333               

 Response X04066.HIF.1.signaling.pathway..PATH.ko04066. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667       1 0.4648
Residuals    3 0.50000 0.16667               

 Response X04113.Meiosis...yeast..PATH.ko04113. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X04218.Cellular.senescence..PATH.ko04218. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 21.333  10.667  2.6667  0.216
Residuals    3 12.000   4.000               

 Response X04341.Hedgehog.signaling.pathway...fly..PATH.ko04341. :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2      0       0     NaN    NaN
Residuals    3      0       0               

 Response X04392.Hippo.signaling.pathway...multiple.species..PATH.ko04392. :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 0.33333 0.16667       1 0.4648
Residuals    3 0.50000 0.16667               

Run ANOVA for each category of interest (significant in MANOVA)

## Glycolysis
ws_tIV_stat1<-aov(X00010.Glycolysis...Gluconeogenesis..PATH.ko00010.~Timepoint,data=ws_tIV_stats)
summary.aov(ws_tIV_stat1)
TukeyHSD(ws_tIV_stat1)

## Fatty Acid Metabolism
ws_tIV_stat2<-aov(X01212.Fatty.acid.metabolism..PATH.ko01212.~Timepoint,data=ws_tIV_stats)
summary.aov(ws_tIV_stat2)
TukeyHSD(ws_tIV_stat2)

## Pentose and Glucuronate Interconversions
ws_tIV_stat3<-aov(X00040.Pentose.and.glucuronate.interconversions..PATH.ko00040.~Timepoint,data=ws_tIV_stats)
summary.aov(ws_tIV_stat3)
TukeyHSD(ws_tIV_stat3)

## Steroid Degradation
ws_tIV_stat4<-aov(X00984.Steroid.degradation..PATH.ko00984.~Timepoint,data=ws_tIV_stats)
summary.aov(ws_tIV_stat4)
TukeyHSD(ws_tIV_stat4)

## Bacterial Chemotaxis
ws_tIV_stat5<-aov(X02030.Bacterial.chemotaxis..PATH.ko02030.~Timepoint,data=ws_tIV_stats)
summary.aov(ws_tIV_stat5)
TukeyHSD(ws_tIV_stat5)

## Phosphonate and Phoshinate Metabolism
ws_tIV_stat6<-aov(X00440.Phosphonate.and.phosphinate.metabolism..PATH.ko00440.~Timepoint,data=ws_tIV_stats)
summary.aov(ws_tIV_stat6)
TukeyHSD(ws_tIV_stat6)

## Carbon Fixation Pathways in Prokaryotes
ws_tIV_stat7<-aov(X00720.Carbon.fixation.pathways.in.prokaryotes..PATH.ko00720.~Timepoint,data=ws_tIV_stats)
summary.aov(ws_tIV_stat7)
TukeyHSD(ws_tIV_stat7)

## Mucin Type O Glycan Biosynthesis
ws_tIV_stat8<-aov(X00512.Mucin.type.O.glycan.biosynthesis..PATH.ko00512.~Timepoint,data=ws_tIV_stats)
summary.aov(ws_tIV_stat8)
TukeyHSD(ws_tIV_stat8)

7.4. Differential Expression

Determine which genes were differentially expressed between experimental treatments using the Bioconductor package edgeR for differential expression analysis on TPM-normalized read counts. The edgeR package implements statistical methods based on generalized linear models (glms), suitable for multifactor experiments of any complexity. A particular feature of edgeR functionality are empirical Bayes methods that permit the estimation of gene-specific biological variation, even for experiments with minimal levels of biological replication.

7.4.1. DGE Objective

We have two objectives for our differential expression analysis.

  1. Detect genes that are differentially expressed between experimental timepoints, adjusting for any differences between mesocosms that were sampled, within Wet Sedge or Tussock mesocosms.
    • Determine how gene expression changed between anoxic (T0) to oxic (T4) to mixed-redox (T24) timepoints, specific to the Wet Sedge ecosystem or the Tussock ecosystem
  2. Detect genes that are differentially expressed between ecosystems at similar timepoints (similar redox conditions).
    • Determine if the same (or different) genes were expressed between ecosystems when the soil redox conditions were similar

It is possible (and likely) that there are unique genecall ID’s that share identical annotations to KO and Taxonomy, but are still treated as unique entries with separate count values that are factored into DE analysis improperly. + Here, we aggregate (sum) genecall ID counts by shared KO and Taxonomy to reduce duplicates in the dataset and improve the DE analysis results to be biologically relevant.

7.4.2. DGE Within Tundra

Our first set of DE analyses focus on determining significant differentially expressed genes between sampling timepoints within Tussock or Wet Sedge mesocosms.

7.4.2.1. Tuss T4vsT0

Subset data from the full tpm_expressed dataset. Click on the Show/Hide button to see the steps.

# Subset data from the full tpm_expressed dataset
tuss_T4vsT0<-tpm_tuss_expressed[,c(2:5,8:14)]

# Aggregate (sum) genecall ID counts by shared KO and Taxonomy to reduce duplicates in the dataset and improve the DE analysis results to be biologically relevant.
tuss_T4vsT0<-aggregate(. ~ KO + Symbol + Function + Tier_II + Tier_III + Tier_IV + Taxonomy, data=tuss_T4vsT0,FUN=sum)

## Reading in the data
# Create DGEList for Tuss T4 vs T0 subdata
tuss_T4vsT0<-DGEList(counts=tuss_T4vsT0[,8:11], genes=tuss_T4vsT0[,1:7])
rownames(tuss_T4vsT0$counts)<-rownames(tuss_T4vsT0$genes)<-tuss_T4vsT0$genes$ID
tuss_T4vsT0$genes$ID<-NULL

## Normalization
# Tell edgeR that you don't want to normalize the subdata (already TPM normalized)
tuss_T4vsT0<-calcNormFactors(tuss_T4vsT0, method="none")
tuss_T4vsT0$samples

## Data Exploration
# The plotMDS function produces a plot in which distances between samples correspond to leading biological coefficient of variation (BCV) between those samples
plotMDS(tuss_T4vsT0, col=rep(1:2, each=2))


## The Design Matrix
# Before we fit negative binomial GLMs, we need to define our design matrix based on the experimental design. Here, we want to test for differential expression between T4 and T0 timepoints within mesocosms, i.e., adjusting for differences between mesocosms. In statistics, this is an additive linear model with mesocosm as the blocking factor.
Mesocosm_tuss_T4vsT0<-factor(c(1,2,1,2))
Timepoint_tuss_T4vsT0<-factor(c("T0","T0","T4","T4"))
data.frame(Sample_tuss_T4vsT0=colnames(tuss_T4vsT0),Mesocosm_tuss_T4vsT0,Timepoint_tuss_T4vsT0)
tuss_T4vsT0_design<-model.matrix(~Mesocosm_tuss_T4vsT0+Timepoint_tuss_T4vsT0)
rownames(tuss_T4vsT0_design)<-colnames(tuss_T4vsT0)
tuss_T4vsT0_design
         (Intercept) Mesocosm_tuss_T4vsT02 Timepoint_tuss_T4vsT0T4
Tuss1_T0           1                     0                       0
Tuss2_T0           1                     1                       0
Tuss1_T4           1                     0                       1
Tuss2_T4           1                     1                       1
attr(,"assign")
[1] 0 1 2
attr(,"contrasts")
attr(,"contrasts")$Mesocosm_tuss_T4vsT0
[1] "contr.treatment"

attr(,"contrasts")$Timepoint_tuss_T4vsT0
[1] "contr.treatment"
## Estimating Dispersion
# We estimate the NB dispersion for the dataset
tuss_T4vsT0<-estimateDisp(tuss_T4vsT0,tuss_T4vsT0_design,robust=TRUE)
tuss_T4vsT0$common.dispersion
[1] 0.236728
# The square root of the common dispersion gives the coefficient of variation of biological variation.
sqrt(tuss_T4vsT0$common.dispersion)
[1] 0.486547
# View the dispersion estimates in a BCV plot
plotBCV(tuss_T4vsT0)


## Differential Expression
# Now we proceed to determine differentially expressed genes by fitting genewise glms
tuss_T4vsT0_fit<-glmFit(tuss_T4vsT0,tuss_T4vsT0_design)

# Conduct likelihood ratio tests for T4 vs T0 differences and show the top genes. The genewise tests are for T4 vs T0 differential expression, adjusting for baseline differences between the two mesocosms.  The tests can be viewed as analogous to paired t-tests. The top DE tags have tiny p-values and FDR values, as well as large fold changes.
tuss_T4vsT0_lrt<-glmLRT(tuss_T4vsT0_fit)
tuss_T4vsT0_topTags<-topTags(tuss_T4vsT0_lrt,n=25)
tuss_T4vsT0_topTags
Coefficient:  Timepoint_tuss_T4vsT0T4 
## Here's the TPM-normalized values in individual samples for all significant genes.
# We see that all the significant genes have consistent T4 vs T0 changes for the two mesocosms.
tuss_T4vsT0_pvalue<-order(tuss_T4vsT0_lrt$table$PValue)
cpm(tuss_T4vsT0)[tuss_T4vsT0_pvalue[1:25],]
         Tuss1_T0    Tuss2_T0    Tuss1_T4    Tuss2_T4
 [1,] 1048.152018 1774.305826   1.2689433  65.9270105
 [2,]  491.062982  974.471374   3.6118199  20.2399628
 [3,]  151.179465   96.610305   0.0000000   0.0000000
 [4,]  472.155603  666.441032   3.7921111  22.4112348
 [5,]  327.422538  480.914542   2.3328049  14.5438981
 [6,]   50.649133  135.863538   0.0000000   0.0000000
 [7,]  643.602116  384.955662  13.5353953  11.3111135
 [8,]    2.581553    4.114011 173.7320520 257.2741995
 [9,]  110.027568  104.546640   0.0000000   0.9614356
[10,]  141.029067   72.092588   0.4209765   0.4374304
[11,] 1444.859709 1919.924360  30.4546395  90.9792745
[12,]  689.459434  854.779215  22.5192757  24.6994152
[13,]  493.675976  276.418040   4.8411986  13.4155275
[14,]   89.129180  418.186558   4.4145468   1.0858566
[15,]  372.564861  858.111261   2.1339780  52.7189038
[16,]  182.135619  761.371698  12.1623908   4.6519282
[17,]  546.497859  303.658138   9.4792423  13.0406336
[18,]  282.348034  150.179706   2.1903303   6.0432310
[19,]    0.000000    0.000000  91.4427222  52.9218229
[20,]  585.713144  336.433517   5.1643042  24.6842993
[21,]    0.000000    7.137799 152.0557650 161.6181304
[22,]  241.604764  349.070365   3.7028266  16.1795628
[23,]    3.028716    6.272798 118.4347090 271.9708940
[24,]   17.789144    3.778794 238.6530733 464.0529017
[25,]  212.526367  375.417478  12.1126407   6.2930328

Plotting significant KOs in DGE analysis.

# The total number of differentially expressed genes at 5% FDR is given by:
tuss_T4vsT0_FDR<-p.adjust(tuss_T4vsT0_lrt$table$PValue, method="BH")
sum(tuss_T4vsT0_FDR<0.05)
[1] 1255
summary(decideTests(tuss_T4vsT0_lrt))
       Timepoint_tuss_T4vsT0T4
Down                       588
NotSig                  100055
Up                         667
# Plot the log-fold change against log-transcripts per million, with DE genes highlighted.
tuss_T4vsT0_MDplot<-plotMD(tuss_T4vsT0_lrt, hl.col=c("green3","palegreen1"), main = NULL, xlab="Average log TPM") + abline(h=0,col="gray", lty="dashed")

tuss_T4vsT0_MDplot
integer(0)
7.4.2.2. Tuss T24vsT4

Now analyze the differentially expressed genes in the Tussock dataset between timepoints T24 (mixed redox) and T4 (oxic redox). Click on the Show/Hide button to see the steps.

# Subset data from the full tpm_expressed dataset
tuss_T24vsT4<-tpm_tuss_expressed[,c(4:7,8:14)]

# Aggregate (sum) genecall ID counts by shared KO and Taxonomy to reduce duplicates in the dataset and improve the DE analysis results to be biologically relevant.
tuss_T24vsT4<-aggregate(. ~ KO + Symbol + Function + Tier_II + Tier_III + Tier_IV + Taxonomy, data=tuss_T24vsT4, FUN=sum)

## Reading in the data
# Create DGEList for WS T4 vs T0 subdata
tuss_T24vsT4<-DGEList(counts=tuss_T24vsT4[,8:11], genes=tuss_T24vsT4[,1:7])
rownames(tuss_T24vsT4$counts)<-rownames(tuss_T24vsT4$genes)<-tuss_T24vsT4$genes$ID
tuss_T24vsT4$genes$ID<-NULL

## Normalization
# Tell edgeR that you don't want to normalize the subdata (already TPM normalized)
tuss_T24vsT4<-calcNormFactors(tuss_T24vsT4, method="none")
tuss_T24vsT4$samples

## Data Exploration
# The plotMDS function produces a plot in which distances between samples correspond to leading biological coefficient of variation (BCV) between those samples
plotMDS(tuss_T24vsT4, col=rep(1:2, each=2))


## The Design Matrix
# Before we fit negative binomial GLMs, we need to define our design matrix based on the experimental design. Here, we want to test for differential expression between T4 and T0 timepoints within mesocosms, i.e., adjusting for differences between mesocosms. In statistics, this is an additive linear model with mesocosm as the blocking factor.
Mesocosm_tuss_T24vsT4<-factor(c(1,2,1,2))
Timepoint_tuss_T24vsT4<-factor(c("T4","T4","T24","T24"))
data.frame(Sample_tuss_T24vsT4=colnames(tuss_T24vsT4),Mesocosm_tuss_T24vsT4,Timepoint_tuss_T24vsT4)
tuss_T24vsT4_design<-model.matrix(~Mesocosm_tuss_T24vsT4+Timepoint_tuss_T24vsT4)
rownames(tuss_T24vsT4_design)<-colnames(tuss_T24vsT4)
tuss_T24vsT4_design
          (Intercept) Mesocosm_tuss_T24vsT42 Timepoint_tuss_T24vsT4T4
Tuss1_T4            1                      0                        1
Tuss2_T4            1                      1                        1
Tuss1_T24           1                      0                        0
Tuss3_T24           1                      1                        0
attr(,"assign")
[1] 0 1 2
attr(,"contrasts")
attr(,"contrasts")$Mesocosm_tuss_T24vsT4
[1] "contr.treatment"

attr(,"contrasts")$Timepoint_tuss_T24vsT4
[1] "contr.treatment"
## Estimating Dispersion
# We estimate the NB dispersion for the dataset
tuss_T24vsT4<-estimateDisp(tuss_T24vsT4,tuss_T24vsT4_design,robust=TRUE)
tuss_T24vsT4$common.dispersion
[1] 0.5193338
# The square root of the common dispersion gives the coefficient of variation of biological variation.
sqrt(tuss_T24vsT4$common.dispersion)
[1] 0.7206482
# View the dispersion estimates in a BCV plot
plotBCV(tuss_T24vsT4)


## Differential Expression
# Now we proceed to determine differentially expressed genes by fitting genewise glms
tuss_T24vsT4_fit<-glmFit(tuss_T24vsT4,tuss_T24vsT4_design)

# Conduct likelihood ratio tests for T4 vs T0 differences and show the top genes. The genewise tests are for T4 vs T0 differential expression, adjusting for baseline differences between the two mesocosms.  The tests can be viewed as analogous to paired t-tests. The top DE tags have tiny p-values and FDR values, as well as large fold changes.
tuss_T24vsT4_lrt<-glmLRT(tuss_T24vsT4_fit)
topTags(tuss_T24vsT4_lrt,n=25)
Coefficient:  Timepoint_tuss_T24vsT4T4 
# Here's the TPM-normalized values in individual samples.
# We see that all the genes have consistent changes between replicates within each timepoint.
tuss_T24vsT4_pvalue<-order(tuss_T24vsT4_lrt$table$PValue)
cpm(tuss_T24vsT4)[tuss_T24vsT4_pvalue[1:25],]
        Tuss1_T4   Tuss2_T4 Tuss1_T24  Tuss3_T24
 [1,]  0.0000000  0.0000000 10.215879  722.38388
 [2,]  0.0000000  0.0000000  0.000000 1963.01758
 [3,] 35.3894190 73.2291623  0.000000    0.00000
 [4,] 31.5396779 58.8565775  0.000000    0.00000
 [5,]  0.0000000  1.9431119  3.958524 1163.51858
 [6,]  0.0000000  3.9783541 14.748411  733.37655
 [7,]  0.0000000  0.0000000 15.192393   88.88862
 [8,]  0.0000000  0.5099327 21.189145  114.56599
 [9,]  1.3062652  0.0000000 14.100129 1553.90747
[10,]  0.0000000  0.0000000  7.102287  104.18310
[11,] 14.5022093 56.5088661  0.000000    0.00000
[12,]  0.5843818  0.0000000 13.404399  215.90577
[13,]  0.0000000  0.0000000  8.125498   88.63034
[14,] 26.8856979 31.6024982  0.000000    0.00000
[15,]  0.0000000  0.0000000  0.000000  321.59614
[16,]  0.0000000  0.0000000  0.000000  288.87218
[17,]  0.0000000  0.0000000  0.000000  284.71091
[18,] 36.4821202 18.1299279  0.000000    0.00000
[19,]  0.0000000  0.0000000  6.784024   78.25073
[20,]  0.0000000  0.0000000  3.436922  114.02166
[21,] 11.1032540 51.0934331  0.000000    0.00000
[22,]  0.0000000  0.0000000  8.225075   63.64126
[23,] 31.1615468 20.0268843  0.000000    0.00000
[24,]  0.4332977  0.0000000  1.169279  745.12664
[25,]  0.0000000  5.3661520 25.967738  225.39614

Plotting significant KOs in DGE analysis.

# The total number of differentially expressed genes at 5% FDR is given by:
tuss_T24vsT4_FDR<-p.adjust(tuss_T24vsT4_lrt$table$PValue, method="BH")
sum(tuss_T24vsT4_FDR<0.05)
[1] 7
summary(decideTests(tuss_T24vsT4_lrt))
       Timepoint_tuss_T24vsT4T4
Down                          5
NotSig                   101303
Up                            2
# Plot the log-fold change against log-transcripts per million, with DE genes highlighted.
tuss_T24vsT4_MDplot<-plotMD(tuss_T24vsT4_lrt, hl.col=c("darkgreen","green3"), main = NULL, xlab="Average log TPM") + abline(h=0,col="gray", lty="dashed")

tuss_T24vsT4_MDplot
integer(0)
7.4.2.3. Tuss T24vsT0

Finally, analyze the differentially expressed genes in the Tussock dataset between timepoints T24 (mixed redox) and T0 (anoxic redox). Click on the Show/Hide button to see the steps.

# Subset data from the full tpm_expressed dataset
tuss_T24vsT0<-tpm_tuss_expressed[,c(2:3,6:14)]

# Aggregate (sum) genecall ID counts by shared KO and Taxonomy to reduce duplicates in the dataset and improve the DE analysis results to be biologically relevant.
tuss_T24vsT0<-aggregate(. ~ KO + Symbol + Function + Tier_II + Tier_III + Tier_IV + Taxonomy, data=tuss_T24vsT0, FUN=sum)

## Reading in the data
# Create DGEList for Tuss T24 vs T0 subdata
tuss_T24vsT0<-DGEList(counts=tuss_T24vsT0[,8:11], genes=tuss_T24vsT0[,1:7])
rownames(tuss_T24vsT0$counts)<-rownames(tuss_T24vsT0$genes)<-tuss_T24vsT0$genes$ID
tuss_T24vsT0$genes$ID<-NULL

## Normalization
# Tell edgeR that you don't want to normalize the subdata (already TPM normalized)
tuss_T24vsT0<-calcNormFactors(tuss_T24vsT0, method="none")
tuss_T24vsT0$samples

## Data Exploration
# The plotMDS function produces a plot in which distances between samples correspond to leading biological coefficient of variation (BCV) between those samples
plotMDS(tuss_T24vsT0, col=rep(1:2, each=2))


## The Design Matrix
# Before we fit negative binomial GLMs, we need to define our design matrix based on the experimental design. Here, we want to test for differential expression between T4 and T0 timepoints within mesocosms, i.e., adjusting for differences between mesocosms. In statistics, this is an additive linear model with mesocosm as the blocking factor.
Mesocosm_tuss_T24vsT0<-factor(c(1,2,1,2))
Timepoint_tuss_T24vsT0<-factor(c("T0","T0","T24","T24"))
data.frame(Sample_tuss_T24vsT0=colnames(tuss_T24vsT0),Mesocosm_tuss_T24vsT0,Timepoint_tuss_T24vsT0)
tuss_T24vsT0_design<-model.matrix(~Mesocosm_tuss_T24vsT0+Timepoint_tuss_T24vsT0)
rownames(tuss_T24vsT0_design)<-colnames(tuss_T24vsT0)
tuss_T24vsT0_design
          (Intercept) Mesocosm_tuss_T24vsT02 Timepoint_tuss_T24vsT0T24
Tuss1_T0            1                      0                         0
Tuss2_T0            1                      1                         0
Tuss1_T24           1                      0                         1
Tuss3_T24           1                      1                         1
attr(,"assign")
[1] 0 1 2
attr(,"contrasts")
attr(,"contrasts")$Mesocosm_tuss_T24vsT0
[1] "contr.treatment"

attr(,"contrasts")$Timepoint_tuss_T24vsT0
[1] "contr.treatment"
## Estimating Dispersion
# We estimate the NB dispersion for the dataset
tuss_T24vsT0<-estimateDisp(tuss_T24vsT0,tuss_T24vsT0_design,robust=TRUE)
tuss_T24vsT0$common.dispersion
[1] 0.4882395
# The square root of the common dispersion gives the coefficient of variation of biological variation.
sqrt(tuss_T24vsT0$common.dispersion)
[1] 0.6987414
# View the dispersion estimates in a BCV plot
plotBCV(tuss_T24vsT0)


## Differential Expression
# Now we proceed to determine differentially expressed genes by fitting genewise glms
tuss_T24vsT0_fit<-glmFit(tuss_T24vsT0,tuss_T24vsT0_design)

# Conduct likelihood ratio tests for T4 vs T0 differences and show the top genes. The genewise tests are for T4 vs T0 differential expression, adjusting for baseline differences between the two mesocosms.  The tests can be viewed as analogous to paired t-tests. The top DE tags have tiny p-values and FDR values, as well as large fold changes.
tuss_T24vsT0_lrt<-glmLRT(tuss_T24vsT0_fit)
topTags(tuss_T24vsT0_lrt,n=25)
Coefficient:  Timepoint_tuss_T24vsT0T24 
## Here's the TPM-normalized values in individual samples.
# We see that all the genes have consistent changes between replicates within each timepoint.
tuss_T24vsT0_pvalue<-order(tuss_T24vsT0_lrt$table$PValue)
cpm(tuss_T24vsT0)[tuss_T24vsT0_pvalue[1:25],]
         Tuss1_T0   Tuss2_T0   Tuss1_T24    Tuss3_T24
 [1,]   0.0000000   0.000000  92.4565621   56.6710283
 [2,] 337.7932001 381.234729   7.2323939    0.0000000
 [3,]   0.0000000   0.000000 108.7021596   23.0637906
 [4,]   0.0000000   1.650736   3.9585235 1163.5185752
 [5,]   0.0000000   0.000000   9.2108401  133.6818168
 [6,]  15.2509805  86.918297   0.0000000    0.0000000
 [7,] 585.7131436 336.433517  26.4787312    0.0000000
 [8,]  49.9500257 191.303929   1.8824780    0.0000000
 [9,]  96.7699731 162.191889   3.0698703    0.7513205
[10,]   0.0000000   0.000000  41.8527647   31.4839046
[11,] 126.2657034 433.131040   7.3045031    0.0000000
[12,]   0.0000000   0.000000  35.6699699   36.4927076
[13,]   0.0000000   1.438715   2.1991027  807.2903774
[14,] 315.6567717 155.948737  14.4759443    0.0000000
[15,]   0.0000000   0.000000   7.6305073  105.7030151
[16,]   0.0000000   0.000000  89.1200480    9.2470209
[17,]   0.0000000   0.000000   0.0000000  321.5961350
[18,]   0.0000000   0.000000   7.1022873  104.1831024
[19,]   0.0000000   0.000000   0.0000000  284.7109075
[20,]   0.7472161   0.000000  13.4043992  215.9057715
[21,]   0.0000000   0.000000   6.5671835   98.8037852
[22,] 151.1794651  96.610305   6.9144865    0.0000000
[23,]   0.0000000   0.000000  44.8298004   20.6469742
[24,] 119.5226404  15.710050   1.0995514    0.0000000
[25,]  57.6711436  29.251391   0.6209902    0.0000000

Plotting significant KOs in DGE analysis.

# The total number of differentially expressed genes at 5% FDR is given by:
tuss_T24vsT0_FDR<-p.adjust(tuss_T24vsT0_lrt$table$PValue, method="BH")
sum(tuss_T24vsT0_FDR<0.05)
[1] 142
summary(decideTests(tuss_T24vsT0_lrt))
       Timepoint_tuss_T24vsT0T24
Down                          67
NotSig                    101168
Up                            75
# Plot the log-fold change against log-transcripts per million, with DE genes highlighted.
tuss_T24vsT0_MDplot<-plotMD(tuss_T24vsT0_lrt, hl.col=c("darkgreen","palegreen1"), main = NULL, xlab="Average log TPM") + abline(h=0,col="gray", lty="dashed")

tuss_T24vsT0_MDplot
integer(0)
7.4.2.4. WS T4vsT0

Start by analysing differentially expressed genes in the Wet Sedge dataset between timepoints T4 (oxic redox) and T0 (anoxic redox). Click on the Show/Hide button to see the steps.

# Subset data from the full tpm_expressed dataset
ws_T4vsT0<-tpm_ws_expressed[,c(2:5,8:14)]

# Aggregate (sum) genecall ID counts by shared KO and Taxonomy to reduce duplicates in the dataset and improve the DE analysis results to be biologically relevant.
ws_T4vsT0<-aggregate(. ~ KO + Symbol + Function + Tier_II + Tier_III + Tier_IV + Taxonomy, data=ws_T4vsT0, FUN=sum)

## Reading in the data
# Create DGEList for WS T4 vs T0 subdata
ws_T4vsT0<-DGEList(counts=ws_T4vsT0[,8:11], genes=ws_T4vsT0[,1:7])
rownames(ws_T4vsT0$counts)<-rownames(ws_T4vsT0$genes)<-ws_T4vsT0$genes$ID
ws_T4vsT0$genes$ID<-NULL

## Normalization
# Tell edgeR that you don't want to normalize the subdata (already TPM normalized)
ws_T4vsT0<-calcNormFactors(ws_T4vsT0, method="none")
ws_T4vsT0$samples

## Data Exploration
# The plotMDS function produces a plot in which distances between samples correspond to leading biological coefficient of variation (BCV) between those samples
plotMDS(ws_T4vsT0, col=rep(1:2, each=2))


## The Design Matrix
# Before we fit negative binomial GLMs, we need to define our design matrix based on the experimental design. Here, we want to test for differential expression between T4 and T0 timepoints within mesocosms, i.e., adjusting for differences between mesocosms. In statistics, this is an additive linear model with mesocosm as the blocking factor.
Mesocosm_ws_T4vsT0<-factor(c(1,2,1,2))
Timepoint_ws_T4vsT0<-factor(c("T0","T0","T4","T4"))
data.frame(Sample_ws_T4vsT0=colnames(ws_T4vsT0),Mesocosm_ws_T4vsT0,Timepoint_ws_T4vsT0)
ws_T4vsT0_design<-model.matrix(~Mesocosm_ws_T4vsT0+Timepoint_ws_T4vsT0)
rownames(ws_T4vsT0_design)<-colnames(ws_T4vsT0)
ws_T4vsT0_design
       (Intercept) Mesocosm_ws_T4vsT02 Timepoint_ws_T4vsT0T4
WS1_T0           1                   0                     0
WS3_T0           1                   1                     0
WS1_T4           1                   0                     1
WS2_T4           1                   1                     1
attr(,"assign")
[1] 0 1 2
attr(,"contrasts")
attr(,"contrasts")$Mesocosm_ws_T4vsT0
[1] "contr.treatment"

attr(,"contrasts")$Timepoint_ws_T4vsT0
[1] "contr.treatment"
## Estimating Dispersion
# We estimate the NB dispersion for the dataset
ws_T4vsT0<-estimateDisp(ws_T4vsT0,ws_T4vsT0_design,robust=TRUE)
ws_T4vsT0$common.dispersion
[1] 0.1691577
# The square root of the common dispersion gives the coefficient of variation of biological variation.
sqrt(ws_T4vsT0$common.dispersion)
[1] 0.4112878
# View the dispersion estimates in a BCV plot
plotBCV(ws_T4vsT0)


## Differential Expression
# Now we proceed to determine differentially expressed genes by fitting genewise glms
ws_T4vsT0_fit<-glmFit(ws_T4vsT0,ws_T4vsT0_design)

# Conduct likelihood ratio tests for T4 vs T0 differences and show the top genes. The genewise tests are for T4 vs T0 differential expression, adjusting for baseline differences between the two mesocosms.  The tests can be viewed as analogous to paired t-tests. The top DE tags have tiny p-values and FDR values, as well as large fold changes.
ws_T4vsT0_lrt<-glmLRT(ws_T4vsT0_fit)
ws_T4vsT0_topTags<-topTags(ws_T4vsT0_lrt,n=25)
ws_T4vsT0_topTags
Coefficient:  Timepoint_ws_T4vsT0T4 
## Here's the TPM-normalized values in individual samples.
# We see that all the significant genes have consistent T4 vs T0 changes for the two mesocosms.
ws_T4vsT0_pvalue<-order(ws_T4vsT0_lrt$table$PValue)
ws_T4vsT0_cpm<-cpm(ws_T4vsT0)[ws_T4vsT0_pvalue[1:25],]
ws_T4vsT0_cpm
          WS1_T0     WS3_T0     WS1_T4    WS2_T4
 [1,] 10.8192790   5.438542  850.46554 731.47651
 [2,]  0.0000000   0.000000  118.55017  89.97818
 [3,]  6.9056096   6.464740  475.57345 363.29120
 [4,]  5.7694309   5.730429  422.62086 272.59995
 [5,] 15.1291717  17.965751  874.04336 490.04976
 [6,]  0.8681561   0.000000  105.27061  67.14878
 [7,] 29.2836105  51.861640 1381.44762 995.31097
 [8,] 10.5554705   4.117992  213.40063 288.12586
 [9,]  7.4930143  15.995405  299.82503 298.78618
[10,]  7.1355300   5.585100  175.21433 172.58804
[11,]  0.0000000   0.000000   41.01244  42.20746
[12,] 24.6197776  18.997054  621.69712 336.14915
[13,]  3.7564449   1.690089  135.21129  70.08873
[14,]  2.5720938   1.941487  117.80967  65.52927
[15,]  1.1226157   0.401687   32.32747 106.03918
[16,]  2.8464136   3.119110  171.84005  46.07958
[17,] 23.4717067  23.143571  248.77496 519.14558
[18,]  1.4310266 110.216730    0.00000   0.00000
[19,]  0.2292666   1.122721   59.81417  27.64980
[20,]  3.6832384   5.816958  117.74292  77.78665
[21,]  5.1724528   6.607292  142.89813  83.19582
[22,]  0.4970360   1.867385   65.49113  31.31506
[23,]  6.3790717   6.574605  128.60327  95.40070
[24,]  0.4120994   1.548275   16.93296  82.74532
[25,] 26.1490232  14.909863  293.77502 245.33748

Plotting significant KOs in DGE analysis.

# The total number of differentially expressed genes at 5% FDR is given by:
ws_T4vsT0_FDR<-p.adjust(ws_T4vsT0_lrt$table$PValue, method="BH")
sum(ws_T4vsT0_FDR<0.05)
[1] 91
summary(decideTests(ws_T4vsT0_lrt))
       Timepoint_ws_T4vsT0T4
Down                      13
NotSig                139939
Up                        78
# Plot the log-fold change against log-transcripts per million, with DE genes highlighted.
ws_T4vsT0_MDplot<-plotMD(ws_T4vsT0_lrt, hl.col=c("dodgerblue1","lightskyblue1"), main = NULL, xlab="Average log TPM") + abline(h=0,col="gray", lty="dashed")

ws_T4vsT0_MDplot
integer(0)
7.4.2.5. WS T24vsT4

Now analyze the differentially expressed genes in the Wet Sedge dataset between timepoints T24 (mixed redox) and T4 (oxic redox). Click on the Show/Hide button to see the steps.

# Subset data from the full tpm_expressed dataset
ws_T24vsT4<-tpm_ws_expressed[,c(4:7,8:14)]

# Aggregate (sum) genecall ID counts by shared KO and Taxonomy to reduce duplicates in the dataset and improve the DE analysis results to be biologically relevant.
ws_T24vsT4<-aggregate(. ~ KO + Symbol + Function + Tier_II + Tier_III + Tier_IV + Taxonomy, data=ws_T24vsT4, FUN=sum)

## Reading in the data
# Create DGEList for WS T24 vs T4 subdata
ws_T24vsT4<-DGEList(counts=ws_T24vsT4[,8:11], genes=ws_T24vsT4[,1:7])
rownames(ws_T24vsT4$counts)<-rownames(ws_T24vsT4$genes)<-ws_T24vsT4$genes$ID
ws_T24vsT4$genes$ID<-NULL

## Normalization
# Tell edgeR that you don't want to normalize the subdata (already TPM normalized)
ws_T24vsT4<-calcNormFactors(ws_T24vsT4, method="none")
ws_T24vsT4$samples

## Data Exploration
# The plotMDS function produces a plot in which distances between samples correspond to leading biological coefficient of variation (BCV) between those samples
plotMDS(ws_T24vsT4, col=rep(1:2, each=2))


## The Design Matrix
# Before we fit negative binomial GLMs, we need to define our design matrix based on the experimental design. Here, we want to test for differential expression between T4 and T0 timepoints within mesocosms, i.e., adjusting for differences between mesocosms. In statistics, this is an additive linear model with mesocosm as the blocking factor.
Mesocosm_ws_T24vsT4<-factor(c(1,2,1,2))
Timepoint_ws_T24vsT4<-factor(c("T4","T4","T24","T24"))
data.frame(Sample_ws_T24vsT4=colnames(ws_T24vsT4),Mesocosm_ws_T24vsT4,Timepoint_ws_T24vsT4)
ws_T24vsT4_design<-model.matrix(~Mesocosm_ws_T24vsT4+Timepoint_ws_T24vsT4)
rownames(ws_T24vsT4_design)<-colnames(ws_T24vsT4)
ws_T24vsT4_design
        (Intercept) Mesocosm_ws_T24vsT42 Timepoint_ws_T24vsT4T4
WS1_T4            1                    0                      1
WS2_T4            1                    1                      1
WS1_T24           1                    0                      0
WS3_T24           1                    1                      0
attr(,"assign")
[1] 0 1 2
attr(,"contrasts")
attr(,"contrasts")$Mesocosm_ws_T24vsT4
[1] "contr.treatment"

attr(,"contrasts")$Timepoint_ws_T24vsT4
[1] "contr.treatment"
## Estimating Dispersion
# We estimate the NB dispersion for the dataset
ws_T24vsT4<-estimateDisp(ws_T24vsT4,ws_T24vsT4_design,robust=TRUE)
ws_T24vsT4$common.dispersion
[1] 0.6092723
# The square root of the common dispersion gives the coefficient of variation of biological variation.
sqrt(ws_T24vsT4$common.dispersion)
[1] 0.780559
# View the dispersion estimates in a BCV plot
plotBCV(ws_T24vsT4)


## Differential Expression
# Now we proceed to determine differentially expressed genes by fitting genewise glms
ws_T24vsT4_fit<-glmFit(ws_T24vsT4,ws_T24vsT4_design)

# Conduct likelihood ratio tests for T4 vs T0 differences and show the top genes. The genewise tests are for T4 vs T0 differential expression, adjusting for baseline differences between the two mesocosms.  The tests can be viewed as analogous to paired t-tests. The top DE tags have tiny p-values and FDR values, as well as large fold changes.
ws_T24vsT4_lrt<-glmLRT(ws_T24vsT4_fit)
ws_T24vsT4_topTags<-topTags(ws_T24vsT4_lrt,n=25)
ws_T24vsT4_topTags
Coefficient:  Timepoint_ws_T24vsT4T4 
## Here's the TPM-normalized values in individual samples.
# We see that all the genes have consistent changes between replicates within each timepoint.
ws_T24vsT4_pvalue<-order(ws_T24vsT4_lrt$table$PValue)
ws_T24vsT4_cpm<-cpm(ws_T24vsT4)[ws_T24vsT4_pvalue[1:25],]
ws_T24vsT4_cpm
          WS1_T4      WS2_T4   WS1_T24   WS3_T24
 [1,]  0.0000000   0.0000000 12.159331  82.77885
 [2,]  0.0000000   0.0000000  4.111889 162.13060
 [3,]  0.0000000   0.0000000 22.147203  37.69657
 [4,]  0.0000000   0.0000000 18.978543  37.77894
 [5,]  0.0000000   0.0000000  2.268628 151.83192
 [6,]  1.8015202 161.9678928  0.000000   0.00000
 [7,]  0.0000000   0.0000000  2.860444 122.43272
 [8,]  0.0000000   0.0000000  2.436675 125.71781
 [9,]  4.2492077  73.8630558  0.000000   0.00000
[10,]  0.3962099   0.0000000 15.973034  55.79849
[11,]  0.0000000   0.0000000  6.265735  52.01182
[12,]  0.0000000   0.0000000  0.000000 170.39072
[13,]  0.0000000   0.0000000  2.328857  82.99674
[14,]  0.0000000   0.0000000  4.090584  60.48395
[15,]  0.0000000   0.0000000  4.337817  56.26279
[16,] 12.1054398  28.3149820  0.000000   0.00000
[17,]  0.0000000   0.0000000  0.000000 144.85609
[18,]  0.0000000   0.0000000  0.000000 136.53103
[19,]  1.0779240   2.7133367 35.319373 135.32165
[20,]  0.0000000   0.0000000  0.000000 128.18747
[21,]  0.0000000   0.0000000 11.783323  24.45332
[22,] 37.4142554   6.2216186  0.000000   0.00000
[23,]  0.0000000   0.0000000  2.741259  55.46573
[24,]  0.0000000   0.6881651  1.430222 164.56122
[25,]  2.3518342   0.0000000 24.815653 142.61101

Plotting significant KOs in DGE analysis.

# The total number of differentially expressed genes at 5% FDR is given by:
ws_T24vsT4_FDR<-p.adjust(ws_T24vsT4_lrt$table$PValue, method="BH")
sum(ws_T24vsT4_FDR<0.05)
[1] 0
summary(decideTests(ws_T24vsT4_lrt))
       Timepoint_ws_T24vsT4T4
Down                        0
NotSig                 140030
Up                          0
# Plot the log-fold change against log-transcripts per million, with DE genes highlighted.
ws_T24vsT4_MDplot<-plotMD(ws_T24vsT4_lrt, hl.col=c("midnightblue","dodgerblue1"), main = NULL, xlab="Average log TPM") + abline(h=0,col="gray", lty="dashed")

ws_T24vsT4_MDplot
integer(0)
7.4.2.6. WS T24vsT0

Finally, analyze the differentially expressed genes in the Wet Sedge dataset between timepoints T24 (mixed redox) and T0 (anoxic redox). Click on the Show/Hide button to see the steps.

# Subset data from the full tpm_expressed dataset
ws_T24vsT0<-tpm_ws_expressed[,c(2:3,6:14)]

# Aggregate (sum) genecall ID counts by shared KO and Taxonomy to reduce duplicates in the dataset and improve the DE analysis results to be biologically relevant.
ws_T24vsT0<-aggregate(. ~ KO + Symbol + Function + Tier_II + Tier_III + Tier_IV + Taxonomy, data=ws_T24vsT0, FUN=sum)

## Reading in the data
# Create DGEList for WS T24 vs T0 subdata
ws_T24vsT0<-DGEList(counts=ws_T24vsT0[,8:11], genes=ws_T24vsT0[,1:7])
rownames(ws_T24vsT0$counts)<-rownames(ws_T24vsT0$genes)<-ws_T24vsT0$genes$ID
ws_T24vsT0$genes$ID<-NULL

## Normalization
# Tell edgeR that you don't want to normalize the subdata (already TPM normalized)
ws_T24vsT0<-calcNormFactors(ws_T24vsT0, method="none")
ws_T24vsT0$samples

## Data Exploration
# The plotMDS function produces a plot in which distances between samples correspond to leading biological coefficient of variation (BCV) between those samples
plotMDS(ws_T24vsT0, col=rep(1:2, each=2))


## The Design Matrix
# Before we fit negative binomial GLMs, we need to define our design matrix based on the experimental design. Here, we want to test for differential expression between T4 and T0 timepoints within mesocosms, i.e., adjusting for differences between mesocosms. In statistics, this is an additive linear model with mesocosm as the blocking factor.
Mesocosm_ws_T24vsT0<-factor(c(1,2,1,2))
Timepoint_ws_T24vsT0<-factor(c("T0","T0","T24","T24"))
data.frame(Sample_ws_T24vsT0=colnames(ws_T24vsT0),Mesocosm_ws_T24vsT0,Timepoint_ws_T24vsT0)
ws_T24vsT0_design<-model.matrix(~Mesocosm_ws_T24vsT0+Timepoint_ws_T24vsT0)
rownames(ws_T24vsT0_design)<-colnames(ws_T24vsT0)
ws_T24vsT0_design
        (Intercept) Mesocosm_ws_T24vsT02 Timepoint_ws_T24vsT0T24
WS1_T0            1                    0                       0
WS3_T0            1                    1                       0
WS1_T24           1                    0                       1
WS3_T24           1                    1                       1
attr(,"assign")
[1] 0 1 2
attr(,"contrasts")
attr(,"contrasts")$Mesocosm_ws_T24vsT0
[1] "contr.treatment"

attr(,"contrasts")$Timepoint_ws_T24vsT0
[1] "contr.treatment"
## Estimating Dispersion
# We estimate the NB dispersion for the dataset
ws_T24vsT0<-estimateDisp(ws_T24vsT0,ws_T24vsT0_design,robust=TRUE)
ws_T24vsT0$common.dispersion
[1] 0.4789872
# The square root of the common dispersion gives the coefficient of variation of biological variation.
sqrt(ws_T24vsT0$common.dispersion)
[1] 0.692089
# View the dispersion estimates in a BCV plot
plotBCV(ws_T24vsT0)


## Differential Expression
# Now we proceed to determine differentially expressed genes by fitting genewise glms
ws_T24vsT0_fit<-glmFit(ws_T24vsT0,ws_T24vsT0_design)

# Conduct likelihood ratio tests for T4 vs T0 differences and show the top genes. The genewise tests are for T4 vs T0 differential expression, adjusting for baseline differences between the two mesocosms.  The tests can be viewed as analogous to paired t-tests. The top DE tags have tiny p-values and FDR values, as well as large fold changes.
ws_T24vsT0_lrt<-glmLRT(ws_T24vsT0_fit)
topTags(ws_T24vsT0_lrt,n=25)
Coefficient:  Timepoint_ws_T24vsT0T24 
## Here's the TPM-normalized values in individual samples.
# We see that all the genes have consistent changes between replicates within each timepoint.
ws_T24vsT0_pvalue<-order(ws_T24vsT0_lrt$table$PValue)
cpm(ws_T24vsT0)[ws_T24vsT0_pvalue[1:25],]
          WS1_T0     WS3_T0     WS1_T24   WS3_T24
 [1,]  6.9056096  6.4647402  475.223925 409.34166
 [2,]  0.0000000  0.0000000  108.604055  12.79978
 [3,]  0.0000000  0.0000000   16.945966  65.16254
 [4,]  0.0000000  0.0000000   12.159331  82.77885
 [5,] 36.8022714 29.0716593    0.000000   0.00000
 [6,]  0.0000000  0.0000000   17.230772  57.06411
 [7,]  0.0000000  0.0000000   87.413579  10.02501
 [8,]  3.6818737  3.0701332  273.763785 121.50411
 [9,]  0.7155133  0.0000000  143.576377  13.62810
[10,] 18.8100498 48.0194480    0.000000   0.00000
[11,]  0.0000000  0.0000000    1.445939 221.80304
[12,]  0.6576940  0.8236612   71.106601  39.30439
[13,]  0.0000000  0.0000000   14.446244  38.72049
[14,]  7.1733241  1.7275945  136.991697 185.44980
[15,]  0.0000000  0.0000000    7.926532  56.75085
[16,]  1.7337742  4.3296881  621.071942  52.58268
[17,] 24.6197776 18.9970545 1192.944780 428.00608
[18,]  0.0000000  1.1648923   18.797206  73.14162
[19,]  0.0000000  0.0000000    0.000000 170.39072
[20,]  0.0000000  0.8494006    4.111889 162.13060
[21,]  0.0000000  0.0000000    0.000000 153.59741
[22,] 14.7213851 30.0492822    0.000000   0.00000
[23,]  0.0000000  0.0000000    2.328857  82.99674
[24,]  0.0000000  0.0000000   19.493398  22.75517
[25,]  1.9533513  0.0000000   50.000567  36.86338

Plotting significant KOs in DGE analysis.

# The total number of differentially expressed genes at 5% FDR is given by:
ws_T24vsT0_FDR<-p.adjust(ws_T24vsT0_lrt$table$PValue, method="BH")
sum(ws_T24vsT0_FDR<0.05)
[1] 11
summary(decideTests(ws_T24vsT0_lrt))
       Timepoint_ws_T24vsT0T24
Down                         2
NotSig                  140019
Up                           9
# Plot the log-fold change against log-transcripts per million, with DE genes highlighted.
ws_T24vsT0_MDplot<-plotMD(ws_T24vsT0_lrt, hl.col=c("midnightblue","lightskyblue1"), main = NULL, xlab="Average log TPM") + abline(h=0,col="gray", lty="dashed")

ws_T24vsT0_MDplot
integer(0)

7.4.3. DGE Between Tundra

Now switch perspectives and determine which expressed genes were significantly differentially expressed between ecosystems (i.e., vegetation types) at the same sampling timepoint.

7.4.3.1. WSvsTuss T0

Compare gene expression under anoxic conditions (T0) between Wet Sedge and Tussocks. Click on the Show/Hide button to see the steps.

# Subset data from the full tpm_expressed dataset
ws_tuss_T0<-tpm_all_exp_ann[,c(2:5,14:20)]

# Aggregate (sum) genecall ID counts by shared KO and Taxonomy to reduce duplicates in the dataset and improve the DE analysis results to be biologically relevant.
ws_tuss_T0<-aggregate(. ~ KO + Symbol + Function + Tier_II + Tier_III + Tier_IV + Taxonomy, data=ws_tuss_T0, FUN=sum)

## Reading in the data
# Create DGEList for Tuss vs WS at T4 subdata
ws_tuss_T0<-DGEList(counts=ws_tuss_T0[,8:11], genes=ws_tuss_T0[,1:7])
rownames(ws_tuss_T0$counts)<-rownames(ws_tuss_T0$genes)<-ws_tuss_T0$genes$ID
ws_tuss_T0$genes$ID<-NULL

## Normalization
# Tell edgeR that you don't want to normalize the subdata (already TPM normalized)
ws_tuss_T0<-calcNormFactors(ws_tuss_T0, method="none")
ws_tuss_T0$samples

## Data Exploration
# The plotMDS function produces a plot in which distances between samples correspond to leading biological coefficient of variation (BCV) between those samples
plotMDS(ws_tuss_T0, col=rep(1:2, each=2))


## The Design Matrix
# Before we fit negative binomial GLMs, we need to define our design matrix based on the experimental design. Here, we want to test for differential expression between T4 and T0 timepoints within mesocosms, i.e., adjusting for differences between mesocosms. In statistics, this is an additive linear model with mesocosm as the blocking factor.
Mesocosm_ws_tuss_T0<-factor(c(1,2,1,2))
Vegetation_ws_tuss_T0<-factor(c("WS","WS","TUSS","TUSS"))
data.frame(Sample_ws_tuss_T0=colnames(ws_tuss_T0),Mesocosm_ws_tuss_T0,Vegetation_ws_tuss_T0)
ws_tuss_T0_design<-model.matrix(~Mesocosm_ws_tuss_T0+Vegetation_ws_tuss_T0)
rownames(ws_tuss_T0_design)<-colnames(ws_tuss_T0)
ws_tuss_T0_design
        (Intercept) Mesocosm_ws_tuss_T02 Vegetation_ws_tuss_T0WS
S108379           1                    0                       1
S108381           1                    1                       1
S108382           1                    0                       0
S108383           1                    1                       0
attr(,"assign")
[1] 0 1 2
attr(,"contrasts")
attr(,"contrasts")$Mesocosm_ws_tuss_T0
[1] "contr.treatment"

attr(,"contrasts")$Vegetation_ws_tuss_T0
[1] "contr.treatment"
## Estimating Dispersion
# We estimate the NB dispersion for the dataset
ws_tuss_T0<-estimateDisp(ws_tuss_T0,ws_tuss_T0_design,robust=TRUE)
ws_tuss_T0$common.dispersion
[1] 0.2095678
# The square root of the common dispersion gives the coefficient of variation of biological variation.
sqrt(ws_tuss_T0$common.dispersion)
[1] 0.4577857
# View the dispersion estimates in a BCV plot
plotBCV(ws_tuss_T0)


## Differential Expression
# Now we proceed to determine differentially expressed genes by fitting genewise glms
ws_tuss_T0_fit<-glmFit(ws_tuss_T0,ws_tuss_T0_design)

# Conduct likelihood ratio tests for WS T0 vs TUSS T0 differences and show the top genes. The genewise tests are for WS T0 vs TUSS T0 differential expression, adjusting for baseline differences between the replicate mesocosms.  The tests can be viewed as analogous to paired t-tests. The top DE tags have tiny p-values and FDR values, as well as large fold changes.
ws_tuss_T0_lrt<-glmLRT(ws_tuss_T0_fit)
ws_tuss_T0_topTags<-topTags(ws_tuss_T0_lrt,n=25)
ws_tuss_T0_topTags
Coefficient:  Vegetation_ws_tuss_T0WS 
## Here's the TPM-normalized values in individual samples.
# We see that all the genes have consistent changes between replicates within each timepoint.
ws_tuss_T0_pvalue<-order(ws_tuss_T0_lrt$table$PValue)
cpm(ws_tuss_T0)[ws_tuss_T0_pvalue[1:25],]
         S108379    S108381    S108382    S108383
 [1,]   2.790502  2.1715893  1048.1520  1774.3058
 [2,]  18.653991 23.3768187  3862.5422  9060.6678
 [3,]   5.547236 10.5136483  1725.5008  3661.3731
 [4,] 101.482342 81.4146821 19971.3520 20238.9159
 [5,]  14.824705  5.9177545  3183.2604  2395.2434
 [6,]  15.373237 15.9541956  3304.4782  3840.8938
 [7,]   7.525094  9.3787376  1925.8803  2408.4338
 [8,]   3.152842  1.8611792   683.5328  1448.8869
 [9,]   1.834133  1.1484853   689.4594   854.7792
[10,]  17.040372 14.6767472  2870.1227  3780.1996
[11,]   3.263535  1.7826727   758.9130  1170.5083
[12,]  39.649128 47.6659745  8597.7390  6883.0791
[13,]   9.459767  7.6660223  1982.6558  1768.8644
[14,]   0.856733  2.4062734   491.0630   974.4714
[15,]   1.683924  0.7029522   616.0448   636.6969
[16,]  18.868062 23.7007072  5166.4870  2892.4947
[17,]  11.381785 15.3112141  2097.0478  2773.9525
[18,]  12.079508 11.6498504  1405.6115  3292.7357
[19,]   2.187497  3.0415660   711.5607   809.4788
[20,]   1.559618  0.9765914   372.5649   858.1113
[21,]   0.000000  0.0000000   222.6106   442.2323
[22,]  12.077353  7.3032488  1947.3882  1437.6220
[23,]   8.087159  9.5441367  1672.4565  1490.1581
[24,]   3.405617  3.7638208   721.9555  1044.8854
[25,]  32.748134 28.6056476  4359.9140  4150.2631

Plotting significant KOs in DGE analysis.

# The total number of differentially expressed genes at 5% FDR is given by:
ws_tuss_T0_FDR<-p.adjust(ws_tuss_T0_lrt$table$PValue, method="BH")
sum(ws_tuss_T0_FDR<0.05)
[1] 39971
summary(decideTests(ws_tuss_T0_lrt))
       Vegetation_ws_tuss_T0WS
Down                     12732
NotSig                  126783
Up                       27239
# Plot the log-fold change against log-transcripts per million, with DE genes highlighted.
ws_tuss_T0_MDplot<-plotMD(ws_tuss_T0_lrt, hl.col=c("palegreen2","lightskyblue2"), main = NULL, xlab="Average log TPM") + abline(h=0,col="gray", lty="dashed")

ws_tuss_T0_MDplot
integer(0)
7.4.3.2. WSvsTuss T4

Next, compare gene expression under oxic conditions (T4) between Wet Sedge and Tussocks. Click on the Show/Hide button to see the steps.

# Subset data from the full tpm_expressed dataset
ws_tuss_T4<-tpm_all_exp_ann[,c(6:7,10:11,14:20)]

# Aggregate (sum) genecall ID counts by shared KO and Taxonomy to reduce duplicates in the dataset and improve the DE analysis results to be biologically relevant.
ws_tuss_T4<-aggregate(. ~ KO + Symbol + Function + Tier_II + Tier_III + Tier_IV + Taxonomy, data=ws_tuss_T4, FUN=sum)

## Reading in the data
# Create DGEList for Tuss vs WS at T4 subdata
ws_tuss_T4<-DGEList(counts=ws_tuss_T4[,8:11], genes=ws_tuss_T4[,1:7])
rownames(ws_tuss_T4$counts)<-rownames(ws_tuss_T4$genes)<-ws_tuss_T4$genes$ID
ws_tuss_T4$genes$ID<-NULL

## Normalization
# Tell edgeR that you don't want to normalize the subdata (already TPM normalized)
ws_tuss_T4<-calcNormFactors(ws_tuss_T4, method="none")
ws_tuss_T4$samples

## Data Exploration
# The plotMDS function produces a plot in which distances between samples correspond to leading biological coefficient of variation (BCV) between those samples
plotMDS(ws_tuss_T4, col=rep(1:2, each=2))


## The Design Matrix
# Before we fit negative binomial GLMs, we need to define our design matrix based on the experimental design. Here, we want to test for differential expression between T4 and T0 timepoints within mesocosms, i.e., adjusting for differences between mesocosms. In statistics, this is an additive linear model with mesocosm as the blocking factor.
Mesocosm_ws_tuss_T4<-factor(c(1,2,1,2))
Vegetation_ws_tuss_T4<-factor(c("WS","WS","TUSS","TUSS"))
data.frame(Sample_ws_tuss_T4=colnames(ws_tuss_T4),Mesocosm_ws_tuss_T4,Vegetation_ws_tuss_T4)
ws_tuss_T4_design<-model.matrix(~Mesocosm_ws_tuss_T4+Vegetation_ws_tuss_T4)
rownames(ws_tuss_T4_design)<-colnames(ws_tuss_T4)
ws_tuss_T4_design
        (Intercept) Mesocosm_ws_tuss_T42 Vegetation_ws_tuss_T4WS
S108385           1                    0                       1
S108386           1                    1                       1
S108391           1                    0                       0
S108392           1                    1                       0
attr(,"assign")
[1] 0 1 2
attr(,"contrasts")
attr(,"contrasts")$Mesocosm_ws_tuss_T4
[1] "contr.treatment"

attr(,"contrasts")$Vegetation_ws_tuss_T4
[1] "contr.treatment"
## Estimating Dispersion
# We estimate the NB dispersion for the dataset
ws_tuss_T4<-estimateDisp(ws_tuss_T4,ws_tuss_T4_design,robust=TRUE)
ws_tuss_T4$common.dispersion
[1] 0.1823877
# The square root of the common dispersion gives the coefficient of variation of biological variation.
sqrt(ws_tuss_T4$common.dispersion)
[1] 0.4270688
# View the dispersion estimates in a BCV plot
plotBCV(ws_tuss_T4)


## Differential Expression
# Now we proceed to determine differentially expressed genes by fitting genewise glms
ws_tuss_T4_fit<-glmFit(ws_tuss_T4,ws_tuss_T4_design)

# Conduct likelihood ratio tests for WS T4 vs TUSS T4 differences and show the top genes. The genewise tests are for WS T4 vs TUSS T4 differential expression, adjusting for baseline differences between the replicate mesocosms.  The tests can be viewed as analogous to paired t-tests. The top DE tags have tiny p-values and FDR values, as well as large fold changes.
ws_tuss_T4_lrt<-glmLRT(ws_tuss_T4_fit)
topTags(ws_tuss_T4_lrt,n=25)
Coefficient:  Vegetation_ws_tuss_T4WS 
## Here's the TPM-normalized values in individual samples.
# We see that all the genes have consistent changes between replicates within each timepoint.
ws_tuss_T4_pvalue<-order(ws_tuss_T4_lrt$table$PValue)
cpm(ws_tuss_T4)[ws_tuss_T4_pvalue[1:25],]
         S108385    S108386    S108391    S108392
 [1,]  8.0274233  11.651619  4175.2141  3827.0926
 [2,]  2.8435944   3.267810  2432.0822  1366.7868
 [3,]  5.7799711   8.972472  2681.1172  3047.4687
 [4,]  8.1131950   9.058751  1997.5411  4226.8287
 [5,] 61.5662670 104.047069 15987.8386 22081.8476
 [6,] 21.1933255  24.981156  4987.9826  7030.0079
 [7,] 13.0324201  28.054604  4664.0350  5636.6829
 [8,]  4.6609588   2.597162  1415.1183  1593.5747
 [9,]  2.0592362   2.492567  1311.6065  1042.3992
[10,]  0.0000000   1.546245   540.8269  1020.3616
[11,] 12.0780470  23.350111  6073.1910  3583.9212
[12,]  0.0000000   4.455884   636.2206  1453.9601
[13,]  5.6855278   4.648439  1648.6917  1757.2707
[14,] 15.7567944  24.984147  3412.5304  6198.6897
[15,]  2.6816646   5.463272  1435.1464  1415.1327
[16,]  3.4957521  15.027355  2096.7399  2581.4026
[17,]  9.3862380  19.792247  4673.4838  2830.0177
[18,]  1.4146780   2.082176   937.8244   910.3646
[19,]  6.0806606   4.212434  1488.4907  1718.9066
[20,]  0.8329413   4.461367   868.1466  1191.5025
[21,]  0.0000000   0.000000   331.1166   532.6308
[22,]  2.4356977   4.586270  1546.3077   951.6303
[23,]  8.6697544  10.885006  1721.0323  3019.0001
[24,]  5.1404376   8.433296  1438.6632  2061.2372
[25,]  5.9714493   7.283721  1646.3021  1654.2275

Plotting significant KOs in DGE analysis.

# The total number of differentially expressed genes at 5% FDR is given by:
ws_tuss_T4_FDR<-p.adjust(ws_tuss_T4_lrt$table$PValue, method="BH")
sum(ws_tuss_T4_FDR<0.05)
[1] 45878
summary(decideTests(ws_tuss_T4_lrt))
       Vegetation_ws_tuss_T4WS
Down                     13512
NotSig                  120876
Up                       32366
# Plot the log-fold change against log-transcripts per million, with DE genes highlighted.
ws_tuss_T4_MDplot<-plotMD(ws_tuss_T4_lrt, hl.col=c("green3","dodgerblue1"), main = NULL, xlab="Average log TPM") + abline(h=0,col="gray", lty="dashed")

ws_tuss_T4_MDplot
integer(0)
7.4.3.3. WSvsTuss T24

Finally, compare gene expression under mixed-redox conditions (T24) between Wet Sedge and Tussocks. Click on the Show/Hide button to see the steps.

# Subset data from the full tpm_expressed dataset
ws_tuss_T24<-tpm_all_exp_ann[,c(8:9,12:20)]

# Aggregate (sum) genecall ID counts by shared KO and Taxonomy to reduce duplicates in the dataset and improve the DE analysis results to be biologically relevant.
ws_tuss_T24<-aggregate(. ~ KO + Symbol + Function + Tier_II + Tier_III + Tier_IV + Taxonomy, data=ws_tuss_T24, FUN=sum)

## Reading in the data
# Create DGEList for Tuss vs WS at T24 subdata
ws_tuss_T24<-DGEList(counts=ws_tuss_T24[,8:11], genes=ws_tuss_T24[,1:7])
rownames(ws_tuss_T24$counts)<-rownames(ws_tuss_T24$genes)<-ws_tuss_T24$genes$ID
ws_tuss_T24$genes$ID<-NULL

## Normalization
# Tell edgeR that you don't want to normalize the subdata (already TPM normalized)
ws_tuss_T24<-calcNormFactors(ws_tuss_T24, method="none")
ws_tuss_T24$samples

## Data Exploration
# The plotMDS function produces a plot in which distances between samples correspond to leading biological coefficient of variation (BCV) between those samples
plotMDS(ws_tuss_T24, col=rep(1:2, each=2))


## The Design Matrix
# Before we fit negative binomial GLMs, we need to define our design matrix based on the experimental design. Here, we want to test for differential expression between T4 and T0 timepoints within mesocosms, i.e., adjusting for differences between mesocosms. In statistics, this is an additive linear model with mesocosm as the blocking factor.
Mesocosm_ws_tuss_T24<-factor(c(1,2,1,2))
Vegetation_ws_tuss_T24<-factor(c("WS","WS","TUSS","TUSS"))
data.frame(Sample_ws_tuss_T24=colnames(ws_tuss_T24),Mesocosm_ws_tuss_T24,Vegetation_ws_tuss_T24)
ws_tuss_T24_design<-model.matrix(~Mesocosm_ws_tuss_T24+Vegetation_ws_tuss_T24)
rownames(ws_tuss_T24_design)<-colnames(ws_tuss_T24)
ws_tuss_T24_design
        (Intercept) Mesocosm_ws_tuss_T242 Vegetation_ws_tuss_T24WS
S108388           1                     0                        1
S108390           1                     1                        1
S108394           1                     0                        0
S108396           1                     1                        0
attr(,"assign")
[1] 0 1 2
attr(,"contrasts")
attr(,"contrasts")$Mesocosm_ws_tuss_T24
[1] "contr.treatment"

attr(,"contrasts")$Vegetation_ws_tuss_T24
[1] "contr.treatment"
## Estimating Dispersion
# We estimate the NB dispersion for the dataset
ws_tuss_T24<-estimateDisp(ws_tuss_T24,ws_tuss_T24_design,robust=TRUE)
ws_tuss_T24$common.dispersion
[1] 0.5676736
# The square root of the common dispersion gives the coefficient of variation of biological variation.
sqrt(ws_tuss_T24$common.dispersion)
[1] 0.7534412
# View the dispersion estimates in a BCV plot
plotBCV(ws_tuss_T24)


## Differential Expression
# Now we proceed to determine differentially expressed genes by fitting genewise glms
ws_tuss_T24_fit<-glmFit(ws_tuss_T24,ws_tuss_T24_design)

# Conduct likelihood ratio tests for WS T24 vs TUSS T24 differences and show the top genes. The genewise tests are for WS T24 vs TUSS T24 differential expression, adjusting for baseline differences between the replicate mesocosms.  The tests can be viewed as analogous to paired t-tests. The top DE tags have tiny p-values and FDR values, as well as large fold changes.
ws_tuss_T24_lrt<-glmLRT(ws_tuss_T24_fit)
topTags(ws_tuss_T24_lrt,n=25)
Coefficient:  Vegetation_ws_tuss_T24WS 
## Here's the TPM-normalized values in individual samples.
# We see that all the genes have consistent changes between replicates within each timepoint.
ws_tuss_T24_pvalue<-order(ws_tuss_T24_lrt$table$PValue)
cpm(ws_tuss_T24)[ws_tuss_T24_pvalue[1:25],]
         S108388    S108390     S108394   S108396
 [1,]   0.000000   0.000000  589.963445  417.5307
 [2,] 371.013698 453.238248    0.000000    0.0000
 [3,] 372.594535 214.590235    0.000000    0.0000
 [4,]   1.920882   1.473356 1515.990843  629.6368
 [5,]   1.775575   0.000000 1016.728192  250.2307
 [6,] 687.952160 263.727529    1.216762    0.0000
 [7,]   8.464239   0.000000 1238.236744 1321.0873
 [8,] 165.797499 290.508099    0.000000    0.0000
 [9,] 190.033341 240.415378    0.000000    0.0000
[10,]   0.000000   0.000000  183.228218  237.4590
[11,]   2.429625   1.845014 1412.637638  463.0927
[12,]  90.292033 413.736153    0.000000    0.0000
[13,]   8.489061   3.303170 2882.225623  878.3178
[14,]   0.000000   0.000000  310.311819  117.3602
[15,]   2.240023   1.576596  853.834799  573.3462
[16,] 188.544098 185.919975    0.000000    0.0000
[17,]   0.000000   0.000000  119.142851  278.1357
[18,]   0.000000   0.000000  167.062660  190.7137
[19,]   0.000000   0.000000  265.492941  118.6896
[20,]   6.723088   1.494865  916.987096 1529.7441
[21,]   0.000000   2.275517  894.839757  317.0247
[22,]   0.000000   0.000000  215.026006  136.0775
[23,]   0.000000   0.000000  239.182819  109.0986
[24,] 136.991697 185.449796    0.000000    0.0000
[25,]   3.556228   3.150716  810.327981  947.9758

Plotting significant KOs in DGE analysis.

# The total number of differentially expressed genes at 5% FDR is given by:
ws_tuss_T24_FDR<-p.adjust(ws_tuss_T24_lrt$table$PValue, method="BH")
sum(ws_tuss_T24_FDR<0.05)
[1] 16897
summary(decideTests(ws_tuss_T24_lrt))
       Vegetation_ws_tuss_T24WS
Down                       4774
NotSig                   149857
Up                        12123
# Plot the log-fold change against log-transcripts per million, with DE genes highlighted.
ws_tuss_T24_MDplot<-plotMD(ws_tuss_T24_lrt, hl.col=c("darkgreen","midnightblue"), main = NULL, xlab="Average log TPM") + abline(h=0,col="gray", lty="dashed")

ws_tuss_T24_MDplot
integer(0)

7.5. Fe Gene Expression

Gene expression related to iron acquisition, iron redox cycling, and iron storage were determined using FeGenie (Garber et al. 2020). FeGenie provides a comprehensive database of hidden Markov models (HMMs) based on genes related to iron acquisition, storage, and oxidation/reduction in Bacteria and Archaea, which are generally not annotated as such by established gene annotation pipelines, such as GhostKOALA, which was used to annotate the metatranscriptomes presented in this study.

Here, the quality-controlled sequencing reads for each metatranscriptome sample were assembled separately using MEGAHIT to generate a sample-specific contigs file. The metatranscriptome contigs files were used as input for FeGenie, which first predicted open-reading frames (ORFs) using Prodigal and then queried them against a custom library of HMMs using hmmsearch, with custom bit score cutoffs for each HMM. Results from FeGenie included all identified putative iron-related genes, their functional category, bit score, number of canonical heme-binding motifs, amino acid sequence, and closest homolog. Counts within each iron gene category were summarized as their relative expression against all identified iron genes.

Assemble each QC’d metatranscriptome sample for use in FeGenie

{Terminal}
module load Bioinformatics megahit/1.2.8
megahit --k-min 21 --k-max 141 --k-step 12 -1 Sample_108379_fwd.good.fastq -2 Sample_108379_rev.good.fastq -o ./megahit_108379_out
megahit --k-min 21 --k-max 141 --k-step 12 -1 Sample_108381_fwd.good.fastq -2 Sample_108381_rev.good.fastq -o ./megahit_108381_out
megahit --k-min 21 --k-max 141 --k-step 12 -1 Sample_108382_fwd.good.fastq -2 Sample_108382_rev.good.fastq -o ./megahit_108382_out
megahit --k-min 21 --k-max 141 --k-step 12 -1 Sample_108383_fwd.good.fastq -2 Sample_108383_rev.good.fastq -o ./megahit_108383_out
megahit --k-min 21 --k-max 141 --k-step 12 -1 Sample_108385_fwd.good.fastq -2 Sample_108385_rev.good.fastq -o ./megahit_108385_out
megahit --k-min 21 --k-max 141 --k-step 12 -1 Sample_108386_fwd.good.fastq -2 Sample_108386_rev.good.fastq -o ./megahit_108386_out
megahit --k-min 21 --k-max 141 --k-step 12 -1 Sample_108388_fwd.good.fastq -2 Sample_108388_rev.good.fastq -o ./megahit_108388_out
megahit --k-min 21 --k-max 141 --k-step 12 -1 Sample_108390_fwd.good.fastq -2 Sample_108390_rev.good.fastq -o ./megahit_108390_out
megahit --k-min 21 --k-max 141 --k-step 12 -1 Sample_108391_fwd.good.fastq -2 Sample_108391_rev.good.fastq -o ./megahit_108391_out
megahit --k-min 21 --k-max 141 --k-step 12 -1 Sample_108392_fwd.good.fastq -2 Sample_108392_rev.good.fastq -o ./megahit_108392_out
megahit --k-min 21 --k-max 141 --k-step 12 -1 Sample_108394_fwd.good.fastq -2 Sample_108394_rev.good.fastq -o ./megahit_108394_out
megahit --k-min 21 --k-max 141 --k-step 12 -1 Sample_108396_fwd.good.fastq -2 Sample_108396_rev.good.fastq -o ./megahit_108396_out

7.5.1. FeGenie Summary

FeGenie is a python script with dependencies that can be downloaded from Arkadiy-Garber GitHub.

Start by loading prerequisite modules

{Terminal}
module load python3.6-anaconda Bioinformatics hmmer prodigal ncbi-blast R

Run the FeGenie python script

{Terminal}
FeGenie_rna.sh

# This is what's inside the "FeGenie_rna.sh" script
FeGenie.py -bin_dir /Path/To/assembly_fasta -bin_ext fa -out FeGenie_rna_out

Results from FeGenie analysis using Garber et al. 2020 R-scripts.

l = length(FeGenie_heatmap_data_organized)
fegenie.t <- t(FeGenie_heatmap_data_organized[,3:l-1])
fegenie.matrix = as.matrix(fegenie.t)

colnames(fegenie.t) <- as.vector(FeGenie_heatmap_data_organized$V1)
FeGenie <- fegenie.t

#-------------data preparation
# convert to data frame
FeGenie.data <- as.data.frame(FeGenie)
#FeGenie.data<-FeGenie.data[1,]
#class(FeGenie.data)
#(FeGenie.data)

# ----------- melt data
FeGenie.data.melt <- melt(FeGenie.data, id.vars = 1:1)

# rename columns
colnames(FeGenie.data.melt)[colnames(FeGenie.data.melt)=="variable"] <- "Iron_category"
colnames(FeGenie.data.melt)[colnames(FeGenie.data.melt)=="value"] <- "Normalized_gene_abundance"

# ----------------- output files

FeGenie.data.melt$Normalized_gene_abundance = as.character(FeGenie.data.melt$Normalized_gene_abundance)
FeGenie.data.melt$Normalized_gene_abundance = as.numeric(FeGenie.data.melt$Normalized_gene_abundance)

FeGenie.meta.plot <- ggplot(FeGenie.data.melt, aes(x = X, y = Iron_category, size = Normalized_gene_abundance), alpha=0.7) +
  geom_point(aes(color=Iron_category)) +
  scale_size_area(max_size = 10) +
  labs(x="", y="Iron Category") +
  scale_y_discrete(labels=c("iron_aquisition-iron_transport" = "Iron Transport",
                            "iron_aquisition-heme_transport" = "Heme Transport",
                            "iron_aquisition-heme_oxygenase" = "Heme Oxygenase",
                            "iron_aquisition-siderophore_synthesis" = "Siderophore Synthesis",
                            "iron_aquisition-siderophore_transport" = "Siderophore Transport",
                            "iron_gene_regulation" = "Iron Gene Regulation",
                            "iron_oxidation" = "Iron Oxidation",
                            "possible_iron_oxidation_and_possible_iron_reduction" = "Probable Iron Oxidation",
                            "probable_iron_reduction" = "Probable Iron Reduction",
                            "iron_reduction" = "Iron Reduction",
                            "iron_storage" = "Iron Storage",
                            "magnetosome_formation" = "Magnetosome Formation",
                            "iron_aquisition-iron_uptake" = "Iron Uptake", 
                            "iron_aquisition-heme_uptake" = "Heme Uptake", 
                            "iron_aquisition-heme_lyase" = "Heme Lyase", 
                            "iron_aquisition-siderophore_uptake" = "Siderophore Uptake")) +
  theme(panel.background = element_rect(fill = "white", colour = "black", size = 1, linetype = "solid"),
        panel.border = element_rect(colour="black", size=1, fill=NA),
        strip.background=element_rect(fill='white', colour='white'),
        strip.text = element_text(face="bold", size=10),
        panel.grid.major = element_line(size = 0.1, colour = "gray"),
        panel.grid.minor = element_line(size = 0.1, colour = "gray"),
        axis.text = element_text(size=12, colour="black"),
        axis.title.y = element_blank(),
        axis.text.x = element_text(vjust = 1, angle = 270, color = "black", size = 12, hjust=1), legend.position="right") + guides(color = FALSE) + labs(size="Normalized\nGene Abundance")
FeGenie.meta.plot

7.5.2. Tuss FeGenie

Plot the relative iron gene abundance data from the Metagenomes (MG) and Metatranscriptomes (MT) within Tuss.

# Place categories in the preferred order for plotting
tuss_dna_fegenie_bardata$Iron <- factor(tuss_dna_fegenie_bardata$Iron,levels = c("Iron Oxidation", "Iron Reduction", "Siderophore Transport", "Iron Storage"))

tuss_dna_fegenie_bardata$Sample <- factor(tuss_dna_fegenie_bardata$Sample,levels=c("Tuss-MG","Tuss-MT-T0","Tuss-MT-T4","Tuss-MT-T24"))

tuss_dna_fegenie_barplot<-ggplot(tuss_dna_fegenie_bardata, aes(x = Iron, y = Mean, fill = Sample)) + geom_bar(stat = "identity", position = "dodge", color="black") + geom_errorbar(aes(ymin = Mean - SD, ymax = Mean + SD), width = 0.2, position = position_dodge(0.9)) + ylab(expression(atop("Microbial Iron Genes", paste("Relative Abundance (%)")))) + theme_classic() + theme(axis.text=element_text(size=10), axis.title=element_text(size=12), axis.title.x=element_blank()) + theme(legend.position = "bottom", legend.title=element_blank(), legend.text=element_text(size=8), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank()) + scale_size(guide=FALSE) + scale_fill_manual(values=c("black", "palegreen", "green3", "darkgreen")) + scale_x_discrete(labels = function(Iron) str_wrap(Iron, width = 10)) + scale_y_continuous(expand = c(0, 0), limits = c(0, 100)) + annotate(geom="text", x=0.9, y=12, label="a") + annotate(geom="text", x=1.12, y=22, label="b") + annotate(geom="text", x=1.35, y=18, label="ab") + annotate(geom="text", x=2.12, y=12, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=3.12, y=70, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=4.12, y=50, label="italic(N.S.)", parse=TRUE) + geom_segment(aes(x = 1.12, y = 35, xend = 1.12, yend = 50)) + geom_segment(aes(x = 1.12, y = 50, xend = 2.12, yend = 50)) + geom_segment(aes(x = 2.12, y = 50, xend = 2.12, yend = 20)) + annotate("text", x = 1.635, y = 54, size=3, label = "Paired~t-test~(italic(p) == 0.004)", parse = TRUE) + annotate("text", x = 1.635, y = 61, size=4, label = "Mean MT Difference (8%)")
tuss_dna_fegenie_barplot

# Place categories in the preferred order for plotting
tuss_dna_fegenie_redox_bardata$Iron <- factor(tuss_dna_fegenie_redox_bardata$Iron,levels = c("Iron Oxidation", "Iron Reduction"))

tuss_dna_fegenie_redox_bardata$Sample <- factor(tuss_dna_fegenie_redox_bardata$Sample,levels=c("Tuss-MG","Tuss-MT-T0","Tuss-MT-T4","Tuss-MT-T24"))

tuss_dna_fegenie_redox_barplot<-ggplot(tuss_dna_fegenie_redox_bardata, aes(x = Iron, y = Mean, fill = Sample)) + geom_bar(stat = "identity", position = "dodge", color="black") + geom_errorbar(aes(ymin = Mean - SD, ymax = Mean + SD), width = 0.2, position = position_dodge(0.9)) + ylab(expression(atop("Iron Redox Cycling Genes", paste("Relative Abundance (%)")))) + theme_classic() + theme(axis.text=element_text(size=10), axis.title=element_text(size=12), axis.title.x=element_blank()) + theme(legend.position = "bottom", legend.title=element_blank(), legend.text=element_text(size=8), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank()) + scale_size(guide=FALSE) + scale_fill_manual(values=c("gray83", "palegreen", "green3", "darkgreen")) + scale_x_discrete(labels = function(Iron) str_wrap(Iron, width = 10)) + scale_y_continuous(expand = c(0, 0), limits = c(0, 40)) + annotate(geom="text", x=0.89, y=8, label="a") + annotate(geom="text", x=1.12, y=18, label="b") + annotate(geom="text", x=1.35, y=13, label="ab") + annotate(geom="text", x=2.12, y=4, label="italic(N.S.)", parse=TRUE) + geom_segment(aes(x = 1.12, y = 22, xend = 1.12, yend = 30)) + geom_segment(aes(x = 1.12, y = 30, xend = 2.12, yend = 30)) + geom_segment(aes(x = 2.12, y = 30, xend = 2.12, yend = 7)) + annotate("text", x = 1.635, y = 32, size=3, label = "Paired~t-test~(italic(p) == 0.004)", parse = TRUE) + annotate("text", x = 1.635, y = 34, size=4, label = "Mean MT Difference (43x)")
tuss_dna_fegenie_redox_barplot

Run statistical tests on the METATRANSCRIPTOMES to determine if significant differences exist between sampling timepoints for each iron gene category .

# Subset response variables for MANOVA
tuss_fegenie_stats$response <- as.matrix(tuss_fegenie_stats[, 2:5])
# MANOVA test
tuss_fegenie_manova <- manova(response ~ Timepoint, data=tuss_fegenie_stats)
summary.aov(tuss_fegenie_manova)
 Response Iron.Oxidation :
            Df Sum Sq Mean Sq F value  Pr(>F)  
Timepoint    2  67.60  33.800  11.317 0.04004 *
Residuals    3   8.96   2.987                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

 Response Iron.Reduction :
            Df   Sum Sq   Mean Sq F value Pr(>F)
Timepoint    2 0.031826 0.0159132  2.0863 0.2705
Residuals    3 0.022882 0.0076273               

 Response Siderophore.Transport :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 48.840   24.42  1.1401 0.4283
Residuals    3 64.259   21.42               

 Response Iron.Storage :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 37.739  18.869  0.8012 0.5263
Residuals    3 70.655  23.552               
## Run ANOVA for each category of interest (significant in MANOVA)

# Iron Oxidation
tuss_fegenie_stat1<-aov(Iron.Oxidation~Timepoint,data=tuss_fegenie_stats)
summary.aov(tuss_fegenie_stat1)
            Df Sum Sq Mean Sq F value Pr(>F)  
Timepoint    2  67.60   33.80   11.32   0.04 *
Residuals    3   8.96    2.99                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
TukeyHSD(tuss_fegenie_stat1)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Iron.Oxidation ~ Timepoint, data = tuss_fegenie_stats)

$Timepoint
           diff        lwr       upr     p adj
T24-T0 2.001337 -5.2204727  9.223146 0.5490550
T4-T0  7.906886  0.6850767 15.128696 0.0394294
T4-T24 5.905549 -1.3162602 13.127359 0.0828858
# t-test for differences between reduction and oxidation averaged across experiment
t.test(tuss_fegenie_stats$Iron.Oxidation,tuss_fegenie_stats$Iron.Reduction,paired=TRUE)

    Paired t-test

data:  tuss_fegenie_stats$Iron.Oxidation and tuss_fegenie_stats$Iron.Reduction
t = 5.2033, df = 5, p-value = 0.003458
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
  4.138735 12.220977
sample estimates:
mean of the differences 
               8.179856 

7.5.3. WS FeGenie

Plot the relative iron gene abundance data from the Metagenomes (MG) and Metatranscriptomes (MT) within WS.

# Place categories in the preferred order for plotting
ws_dna_fegenie_bardata$Iron <- factor(ws_dna_fegenie_bardata$Iron,levels = c("Iron Oxidation", "Iron Reduction", "Siderophore Transport", "Iron Storage"))

ws_dna_fegenie_bardata$Sample <- factor(ws_dna_fegenie_bardata$Sample,levels=c("WS-MG","WS-MT-T0","WS-MT-T4","WS-MT-T24"))

ws_dna_fegenie_barplot<-ggplot(ws_dna_fegenie_bardata, aes(x = Iron, y = Mean, fill = Sample)) + geom_bar(stat = "identity", position = "dodge") + geom_errorbar(aes(ymin = Mean - SD, ymax = Mean + SD), width = 0.2, position = position_dodge(0.9)) + ylab(expression(atop("Microbial Iron Genes", paste("Relative Abundance (%)")))) + theme_classic() + theme(axis.text=element_text(size=10), axis.title=element_text(size=12), axis.title.x=element_blank()) + theme(legend.position = "bottom", legend.title=element_blank(), legend.text=element_text(size=8), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank()) + scale_size(guide=FALSE) + scale_fill_manual(values=c("black","lightskyblue1", "dodgerblue1", "midnightblue")) + scale_x_discrete(labels = function(Iron) str_wrap(Iron, width = 10)) + scale_y_continuous(expand = c(0, 0), limits = c(0, 100)) + annotate(geom="text", x=1.12, y=20, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=2.12, y=30, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=3.12, y=60, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=4.12, y=60, label="italic(N.S.)", parse=TRUE) + geom_segment(aes(x = 1.12, y = 30, xend = 1.12, yend = 50)) + geom_segment(aes(x = 1.12, y = 50, xend = 2.12, yend = 50)) + geom_segment(aes(x = 2.12, y = 50, xend = 2.12, yend = 45)) + annotate("text", x = 1.635, y = 54, size=3, label = "Paired~t-test~(italic(p) == 0.005)", parse = TRUE) + annotate("text", x = 1.635, y = 61, size=4, label = "Mean MT Difference (14%)")

# Place categories in the preferred order for plotting
ws_dna_fegenie_redox_bardata$Iron <- factor(ws_dna_fegenie_redox_bardata$Iron,levels = c("Iron Oxidation", "Iron Reduction"))

ws_dna_fegenie_redox_bardata$Sample <- factor(ws_dna_fegenie_redox_bardata$Sample,levels=c("WS-MG","WS-MT-T0","WS-MT-T4","WS-MT-T24"))

ws_dna_fegenie_redox_barplot<-ggplot(ws_dna_fegenie_redox_bardata, aes(x = Iron, y = Mean, fill = Sample)) + geom_bar(stat = "identity", position = "dodge", color = "black") + geom_errorbar(aes(ymin = Mean - SD, ymax = Mean + SD), width = 0.2, position = position_dodge(0.9)) + ylab(expression(atop("Iron Redox Cycling Genes", paste("Relative Abundance (%)")))) + theme_classic() + theme(axis.text=element_text(size=10), axis.title=element_text(size=12), axis.title.x=element_blank()) + theme(legend.position = "bottom", legend.title=element_blank(), legend.text=element_text(size=8), panel.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank()) + scale_size(guide=FALSE) + scale_fill_manual(values=c("black","lightskyblue1", "dodgerblue1", "midnightblue")) + scale_x_discrete(labels = function(Iron) str_wrap(Iron, width = 10)) + scale_y_continuous(expand = c(0, 0), limits = c(0, 40)) + annotate(geom="text", x=1.12, y=8.5, label="italic(N.S.)", parse=TRUE) + annotate(geom="text", x=2.12, y=25, label="italic(N.S.)", parse=TRUE) + geom_segment(aes(x = 1.12, y = 10, xend = 1.12, yend = 30)) + geom_segment(aes(x = 1.12, y = 30, xend = 2.12, yend = 30)) + geom_segment(aes(x = 2.12, y = 30, xend = 2.12, yend = 27)) + annotate("text", x = 1.635, y = 32, size=3, label = "Paired~t-test~(italic(p) == 0.005)", parse = TRUE) + annotate("text", x = 1.635, y = 34, size=4, label = "Mean MT Difference (4x)")
ws_dna_fegenie_redox_barplot

Run statistical tests on the METATRANSCRIPTOMES to determine if significant differences exist between sampling timepoints for each iron gene category.

# Subset response variables for MANOVA
ws_fegenie_stats$response <- as.matrix(ws_fegenie_stats[, 2:5])

# MANOVA test
ws_fegenie_manova <- manova(response ~ Timepoint, data=ws_fegenie_stats)
summary.aov(ws_fegenie_manova)
 Response Iron.Oxidation :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 6.0375 3.01876  3.2344 0.1783
Residuals    3 2.8000 0.93333               

 Response Iron.Reduction :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2 47.435 23.7177  3.8592 0.1481
Residuals    3 18.437  6.1457               

 Response Siderophore.Transport :
            Df  Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  80.866  40.433  0.5203 0.6397
Residuals    3 233.115  77.705               

 Response Iron.Storage :
            Df Sum Sq Mean Sq F value Pr(>F)
Timepoint    2  11.59   5.795  0.1468 0.8693
Residuals    3 118.38  39.461               
# t-test for differences between reduction and oxidation averaged across experiment
t.test(ws_fegenie_stats$Iron.Oxidation,ws_fegenie_stats$Iron.Reduction,paired=TRUE)

    Paired t-test

data:  ws_fegenie_stats$Iron.Oxidation and ws_fegenie_stats$Iron.Reduction
t = -9.9638, df = 5, p-value = 0.0001739
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -17.76968 -10.48120
sample estimates:
mean of the differences 
              -14.12544 

7.5.4. Ferroptosis

Ferroptosis is a form of regulated cell death that results from the iron-dependent accumulation of lipid peroxides associated with reactive oxygen species such as hydroxyl radical. Here, it is likely that gene expression for ferroptosis is directly linked with the overproduction of hydroxyl radical given that hydroxyl radical production associated with the geochemical oxidation of Fe(II) has been shown to increase in tussock tundra following rainfall. However, little is known about the regulation of ferroptosis in soil environments or even how it is regulated within microbial cells regardless of environment. More studies need to be done to determine any direct link between hydroxyl radical production and ferroptosis gene expression following rainfall.

tuss_ferroptosis<-tpm_all_exp_ann

tuss_ferroptosis<-subset(tuss_ferroptosis, Tier_IV=="04216 Ferroptosis [PATH:ko04216]",
select=ID:Taxonomy)
tuss_ferroptosis

Reproducibility

The session information is provided for full reproducibility.

devtools::session_info()
─ Session info ─────────────────────────────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.1.2 (2021-11-01)
 os       macOS Big Sur 10.16
 system   x86_64, darwin17.0
 ui       RStudio
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       America/Los_Angeles
 date     2022-01-24
 rstudio  1.4.1106 Tiger Daylily (desktop)
 pandoc   2.11.4 @ /Applications/RStudio.app/Contents/MacOS/pandoc/ (via rmarkdown)

─ Packages ─────────────────────────────────────────────────────────────────────────────────────────
 ! package      * version date (UTC) lib source
   abind          1.4-5   2016-07-21 [1] CRAN (R 4.1.0)
   ape          * 5.6-1   2022-01-07 [1] CRAN (R 4.1.2)
   assertthat     0.2.1   2019-03-21 [1] CRAN (R 4.1.0)
   backports      1.4.1   2021-12-13 [1] CRAN (R 4.1.0)
   BiocManager    1.30.16 2021-06-15 [1] CRAN (R 4.1.0)
   brio           1.1.3   2021-11-30 [1] CRAN (R 4.1.0)
   broom          0.7.11  2022-01-03 [1] CRAN (R 4.1.2)
   cachem         1.0.6   2021-08-19 [1] CRAN (R 4.1.0)
   callr          3.7.0   2021-04-20 [1] CRAN (R 4.1.0)
   car            3.0-12  2021-11-06 [1] CRAN (R 4.1.0)
   carData        3.0-5   2022-01-06 [1] CRAN (R 4.1.2)
   cellranger     1.1.0   2016-07-27 [1] CRAN (R 4.1.0)
   cli            3.1.1   2022-01-20 [1] CRAN (R 4.1.2)
   cluster        2.1.2   2021-04-17 [1] CRAN (R 4.1.2)
   colorspace     2.0-2   2021-06-24 [1] CRAN (R 4.1.0)
   cowplot      * 1.1.1   2020-12-30 [1] CRAN (R 4.1.0)
   crayon         1.4.2   2021-10-29 [1] CRAN (R 4.1.0)
   data.table   * 1.14.2  2021-09-27 [1] CRAN (R 4.1.0)
   DBI            1.1.2   2021-12-20 [1] CRAN (R 4.1.0)
   dbplyr         2.1.1   2021-04-06 [1] CRAN (R 4.1.0)
   desc           1.4.0   2021-09-28 [1] CRAN (R 4.1.0)
   devtools     * 2.4.3   2021-11-30 [1] CRAN (R 4.1.0)
   digest         0.6.29  2021-12-01 [1] CRAN (R 4.1.0)
   dplyr        * 1.0.7   2021-06-18 [1] CRAN (R 4.1.0)
   DT           * 0.20    2021-11-15 [1] CRAN (R 4.1.0)
   edgeR        * 3.36.0  2021-10-26 [1] Bioconductor
   ellipsis       0.3.2   2021-04-29 [1] CRAN (R 4.1.0)
   evaluate       0.14    2019-05-28 [1] CRAN (R 4.1.0)
   fansi          1.0.2   2022-01-14 [1] CRAN (R 4.1.2)
   farver         2.1.0   2021-02-28 [1] CRAN (R 4.1.0)
   fastmap        1.1.0   2021-01-25 [1] CRAN (R 4.1.0)
   forcats      * 0.5.1   2021-01-27 [1] CRAN (R 4.1.0)
   fs             1.5.2   2021-12-08 [1] CRAN (R 4.1.0)
   generics       0.1.1   2021-10-25 [1] CRAN (R 4.1.0)
   ggplot2      * 3.3.5   2021-06-25 [1] CRAN (R 4.1.0)
   ggpubr       * 0.4.0   2020-06-27 [1] CRAN (R 4.1.0)
   ggsignif       0.6.3   2021-09-09 [1] CRAN (R 4.1.0)
 V glue           1.6.0   2022-01-22 [1] CRAN (R 4.1.2) (on disk 1.6.1)
   gridExtra    * 2.3     2017-09-09 [1] CRAN (R 4.1.0)
   gtable         0.3.0   2019-03-25 [1] CRAN (R 4.1.0)
   haven          2.4.3   2021-08-04 [1] CRAN (R 4.1.0)
   highr          0.9     2021-04-16 [1] CRAN (R 4.1.0)
   hms            1.1.1   2021-09-26 [1] CRAN (R 4.1.0)
   htmltools      0.5.2   2021-08-25 [1] CRAN (R 4.1.0)
   htmlwidgets    1.5.4   2021-09-08 [1] CRAN (R 4.1.0)
   httr           1.4.2   2020-07-20 [1] CRAN (R 4.1.0)
   jquerylib      0.1.4   2021-04-26 [1] CRAN (R 4.1.0)
   jsonlite       1.7.3   2022-01-17 [1] CRAN (R 4.1.2)
   kableExtra   * 1.3.4   2021-02-20 [1] CRAN (R 4.1.0)
   knitr        * 1.37    2021-12-16 [1] CRAN (R 4.1.0)
   labeling       0.4.2   2020-10-20 [1] CRAN (R 4.1.0)
   lattice      * 0.20-45 2021-09-22 [1] CRAN (R 4.1.2)
   lifecycle      1.0.1   2021-09-24 [1] CRAN (R 4.1.0)
   limma        * 3.50.0  2021-10-26 [1] Bioconductor
   locfit         1.5-9.4 2020-03-25 [1] CRAN (R 4.1.0)
   lubridate      1.8.0   2021-10-07 [1] CRAN (R 4.1.0)
   magrittr       2.0.1   2020-11-17 [1] CRAN (R 4.1.0)
   MASS           7.3-55  2022-01-13 [1] CRAN (R 4.1.2)
   Matrix         1.4-0   2021-12-08 [1] CRAN (R 4.1.0)
   memoise        2.0.1   2021-11-26 [1] CRAN (R 4.1.0)
   mgcv           1.8-38  2021-10-06 [1] CRAN (R 4.1.2)
   modelr         0.1.8   2020-05-19 [1] CRAN (R 4.1.0)
   munsell        0.5.0   2018-06-12 [1] CRAN (R 4.1.0)
   nlme           3.1-155 2022-01-13 [1] CRAN (R 4.1.2)
   permute      * 0.9-5   2019-03-12 [1] CRAN (R 4.1.0)
   pheatmap     * 1.0.12  2019-01-04 [1] CRAN (R 4.1.0)
   pillar         1.6.4   2021-10-18 [1] CRAN (R 4.1.0)
   pkgbuild       1.3.1   2021-12-20 [1] CRAN (R 4.1.0)
   pkgconfig      2.0.3   2019-09-22 [1] CRAN (R 4.1.0)
   pkgload        1.2.4   2021-11-30 [1] CRAN (R 4.1.0)
   plyr           1.8.6   2020-03-03 [1] CRAN (R 4.1.0)
   png          * 0.1-7   2013-12-03 [1] CRAN (R 4.1.0)
   prettyunits    1.1.1   2020-01-24 [1] CRAN (R 4.1.0)
   processx       3.5.2   2021-04-30 [1] CRAN (R 4.1.0)
   ps             1.6.0   2021-02-28 [1] CRAN (R 4.1.0)
   purrr        * 0.3.4   2020-04-17 [1] CRAN (R 4.1.0)
   R6             2.5.1   2021-08-19 [1] CRAN (R 4.1.0)
   RColorBrewer * 1.1-2   2014-12-07 [1] CRAN (R 4.1.0)
   Rcpp           1.0.8   2022-01-13 [1] CRAN (R 4.1.2)
   readr        * 2.1.1   2021-11-30 [1] CRAN (R 4.1.0)
   readxl         1.3.1   2019-03-13 [1] CRAN (R 4.1.0)
   remotes        2.4.2   2021-11-30 [1] CRAN (R 4.1.0)
   reprex         2.0.1   2021-08-05 [1] CRAN (R 4.1.0)
   reshape      * 0.8.8   2018-10-23 [1] CRAN (R 4.1.0)
   rlang          0.4.12  2021-10-18 [1] CRAN (R 4.1.0)
   rmarkdown      2.11    2021-09-14 [1] CRAN (R 4.1.0)
   rprojroot      2.0.2   2020-11-15 [1] CRAN (R 4.1.0)
   rsconnect      0.8.25  2021-11-19 [1] CRAN (R 4.1.0)
   rstatix      * 0.7.0   2021-02-13 [1] CRAN (R 4.1.0)
   rstudioapi     0.13    2020-11-12 [1] CRAN (R 4.1.0)
   rvest          1.0.2   2021-10-16 [1] CRAN (R 4.1.0)
   scales         1.1.1   2020-05-11 [1] CRAN (R 4.1.0)
   sessioninfo    1.2.2   2021-12-06 [1] CRAN (R 4.1.0)
   statmod      * 1.4.36  2021-05-10 [1] CRAN (R 4.1.0)
   stringi        1.7.6   2021-11-29 [1] CRAN (R 4.1.0)
   stringr      * 1.4.0   2019-02-10 [1] CRAN (R 4.1.0)
   svglite        2.0.0   2021-02-20 [1] CRAN (R 4.1.0)
   systemfonts    1.0.3   2021-10-13 [1] CRAN (R 4.1.2)
   testthat       3.1.2   2022-01-20 [1] CRAN (R 4.1.2)
   tibble       * 3.1.6   2021-11-07 [1] CRAN (R 4.1.0)
   tidyr        * 1.1.4   2021-09-27 [1] CRAN (R 4.1.0)
   tidyselect     1.1.1   2021-04-30 [1] CRAN (R 4.1.0)
   tidyverse    * 1.3.1   2021-04-15 [1] CRAN (R 4.1.0)
   tinytex        0.36    2021-12-19 [1] CRAN (R 4.1.0)
   tzdb           0.2.0   2021-10-27 [1] CRAN (R 4.1.0)
   usethis      * 2.1.5   2021-12-09 [1] CRAN (R 4.1.0)
   utf8           1.2.2   2021-07-24 [1] CRAN (R 4.1.0)
   vctrs          0.3.8   2021-04-29 [1] CRAN (R 4.1.0)
   vegan        * 2.5-7   2020-11-28 [1] CRAN (R 4.1.0)
   viridisLite    0.4.0   2021-04-13 [1] CRAN (R 4.1.0)
   webshot        0.5.2   2019-11-22 [1] CRAN (R 4.1.0)
   withr          2.4.3   2021-11-30 [1] CRAN (R 4.1.0)
   xfun           0.29    2021-12-14 [1] CRAN (R 4.1.0)
   xml2           1.3.3   2021-11-30 [1] CRAN (R 4.1.0)
   yaml         * 2.2.1   2020-02-01 [1] CRAN (R 4.1.0)

 [1] /Library/Frameworks/R.framework/Versions/4.1/Resources/library

 V ── Loaded and on-disk version mismatch.

────────────────────────────────────────────────────────────────────────────────────────────────────
LS0tCnRpdGxlOiAiTWljcm9iaWFsIFJlc3BvbnNlIHRvIFJhaW5mYWxsIC0tIE1ldGF0cmFuc2NyaXB0b21lIEFuYWx5c2lzIgphdXRob3I6ICdBdXRob3JzOiBbS2FybCBKLiBSb21hbm93aWN6XShodHRwczovL2xzYS51bWljaC5lZHUvZWViL3Blb3BsZS9ncmFkdWF0ZS1zdHVkZW50cy9ranJvbWFuby5odG1sKSwKICBCeXJvbiBDLiBDcnVtcCwgR2VvcmdlIFcuIEtsaW5nJwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRoZW1lOiBzcGFjZWxhYgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHllcwogICAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzUnCiAgICBkZl9wcmludDogcGFnZWQKICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAnNScKLS0tCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwoKKipSIE5vdGVib29rOioqIFByb3ZpZGVzIHJlcHJvZHVjaWJsZSBhbmFseXNpcyBmb3IgbWV0YXRyYW5zY3JpcHRvbWUgKE1UKSBkYXRhIGluIHRoZSBmb2xsb3dpbmcgbWFudXNjcmlwdDoKCioqQ2l0YXRpb246KiogUm9tYW5vd2ljeiwgS0osIENydW1wLCBCQywgS2xpbmcsIEdXLiAoMjAyMSkgUmFpbmZhbGwgYWx0ZXJzIHBlcm1hZnJvc3Qgc29pbCByZWRveCBjb25kaXRpb25zLCBidXQgbWV0YS1vbWljcyBzaG93IGRpdmVyZ2VudCBtaWNyb2JpYWwgY29tbXVuaXR5IHJlc3BvbnNlcyBieSB0dW5kcmEgdHlwZSBpbiB0aGUgYXJjdGljLiBTb2lsIFN5c3RlbXMgNSgxKTogMTcuIFtodHRwczovL2RvaS5vcmcvMTAuMzM5MC9zb2lsc3lzdGVtczUwMTAwMTddKGh0dHBzOi8vZG9pLm9yZy8xMC4zMzkwL3NvaWxzeXN0ZW1zNTAxMDAxNykKCioqR2l0SHViIFJlcG9zaXRvcnk6KiogW2h0dHBzOi8vZ2l0aHViLmNvbS9rcm9tYW5vd2ljei8yMDIxLVJvbWFub3dpY3otU29pbFN5c3RlbXNdKGh0dHBzOi8vZ2l0aHViLmNvbS9rcm9tYW5vd2ljei8yMDIxLVJvbWFub3dpY3otU29pbFN5c3RlbXMpCgoqKk5DQkkgQmlvUHJvamVjdDoqKiBbaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9iaW9wcm9qZWN0L1BSSk5BNjY2NDI5XShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L2Jpb3Byb2plY3QvUFJKTkE2NjY0MjkpCgoqKkFjY2VwdGVkIGZvciBQdWJsaWNhdGlvbjoqKiAqU29pbCBTeXN0ZW1zKiAxMCBNYXJjaCAyMDIxCgojIEV4cGVyaW1lbnQKClRoaXMgUiBOb3RlYm9vayBwcm92aWRlcyBjb21wbGV0ZSByZXByb2R1Y2liaWxpdHkgb2YgdGhlIGRhdGEgYW5hbHlzaXMgaW4gKioqIlJhaW5mYWxsIGFsdGVycyBwZXJtYWZyb3N0IHNvaWwgcmVkb3ggY29uZGl0aW9ucywgYnV0IG1ldGEtb21pY3Mgc2hvdyBkaXZlcmdlbnQgbWljcm9iaWFsIGNvbW11bml0eSByZXNwb25zZXMgYnkgdHVuZHJhIHR5cGUgaW4gdGhlIEFyY3RpYyAiKioqIGJ5IFJvbWFub3dpY3osIENydW1wLCBhbmQgS2xpbmcuIEluIHRoaXMgZXhwZXJpbWVudCwgbWVzb2Nvc21zIGNvbnRhaW5pbmcgc29pbCBmcm9tIHRoZSBhY3RpdmUgbGF5ZXIgb2YgdHdvIGRvbWluYW50IHR1bmRyYSB0eXBlcyB3ZXJlIHN1YmplY3RlZCB0byBzaW11bGF0ZWQgcmFpbmZhbGwgdG8gYWx0ZXIgcmVkb3ggY29uZGl0aW9ucy4gIFRoZSBtaWNyb2JpYWwgZnVuY3Rpb25hbCBwb3RlbnRpYWwgKG1ldGFnZW5vbWljcykgYW5kIGdlbmUgZXhwcmVzc2lvbiAobWV0YXRyYW5zY3JpcHRvbWljcykgcGF0dGVybnMgd2VyZSBtZWFzdXJlZCBkdXJpbmcgc2F0dXJhdGVkIGFub3hpYyByZWRveCBjb25kaXRpb25zIHByaW9yIHRvIHJhaW5mYWxsIGFuZCBhdCBtdWx0aXBsZSB0aW1lIHBvaW50cyBmb2xsb3dpbmcgdGhlIHNpbXVsYXRlZCByYWluZmFsbCBldmVudC4gT3RoZXIgbWVhc3VyZW1lbnRzIGluY2x1ZGUgc29pbCBwcm9wZXJ0aWVzIGFzIHdlbGwgYXMgbWljcm9iaWFsIHJlc3BpcmF0aW9uIChDT34yfikgYW5kIG1ldGhhbmUgKENIfjR+KSBwcm9kdWN0aW9uIGZyb20gc29pbCBzdWJzYW1wbGVzIGNvbGxlY3RlZCBhdCBlYWNoIHNhbXBsaW5nIHRpbWUgcG9pbnQuIFRoZSBwdXJwb3NlIHdhcyB0byBkZXRlcm1pbmUgaWYgcmFpbmZhbGwsIGFzIGEgZm9ybSBvZiBzb2lsIG94aWRhdGlvbiwgaXMgc3VmZmljaWVudCB0byBhbHRlciB0aGUgYW5veGljIHJlZG94IGNvbmRpdGlvbnMgaW4gYXJjdGljIHR1bmRyYSBhbmQgZW5oYW5jZSB0aGUgbWljcm9iaWFsIGRlZ3JhZGF0aW9uIG9mIG9yZ2FuaWMgY2FyYm9uIGFuZCBDSH40fiB0byBDT34yfi4KCjwhLS0gRGlzcGxheSBGaWd1cmUgMSAtLT4KIVtdKFIuSW1hZ2VzL0NvbmNlcHQxLnBuZykKKipDb25jZXB0dWFsIEZpZ3VyZS4qKiAgQSB0b3RhbCBvZiAxMiB0dW5kcmEgbWVzb2Nvc21zICgzIHJlcGxpY2F0ZXMgeCAyIHR1bmRyYSB0eXBlcyB4IDIgc2V0cyBvZiByZXNwb25zZSBjb3Jlcykgd2VyZSBhY2NsaW1hdGVkIGluaXRpYWxseSB1bmRlciBhbm94aWMgcmVkb3ggY29uZGl0aW9ucyB0byBtaW1pYyBmaWVsZCBjb25kaXRpb25zIChUMCkuICBEaXNzb2x2ZWQgb3h5Z2VuIHdhcyBzdXBwbGllZCB0byBzb2lscyB0aHJvdWdoIHRoZSBkb3dud2FyZCBmbG93IG9mIG94eWdlbmF0ZWQgd2F0ZXIgZHVyaW5nIGEgc2ltdWxhdGVkIHJhaW5mYWxsIGV2ZW50LiAgRGlzc29sdmVkIG94eWdlbiB3aWxsIGxpa2VseSBjaGFuZ2UgdGhlIHJlZG94IGdyYWRpZW50IGRpcmVjdGx5IGZvbGxvd2luZyByYWluZmFsbCAoVDQpIGFzIGEgc2hvcnQtdGVybSBlZmZlY3QuICBBbm94aWMgY29uZGl0aW9ucyB3aWxsIGxpa2VseSBiZSByZS1lc3RhYmxpc2hlZCBhZnRlciAyNCBob3VycyAoVDI0KSBhcyB0aGUgcHVsc2Ugb2Ygb3h5Z2VuIGlzIGNvbnN1bWVkIHRocm91Z2ggYWJpb3RpYyBhbmQgYmlvdGljIHNvaWwgcHJvY2Vzc2VzLiAgVW5kZXIgYW5veGljIHJlZG94IGNvbmRpdGlvbnMgKFQwKSwgbWljcm9vcmdhbmlzbXMgbGlrZWx5IGRlZ3JhZGUgb3JnYW5pYyBjYXJib24gdGhyb3VnaCBhbmFlcm9iaWMgYW5kIGZlcm1lbnRhdGlvbiBwYXRod2F5cywgcHJvZHVjaW5nIENIfjR+IGFuZCByZWR1Y2luZyBGZShJSUkpIHRvIEZlKElJKS4gIFJhaW5mYWxsLWluZHVjZWQgc29pbCBveGlkYXRpb24gKFQ0KSBzaG91bGQgc3RpbXVsYXRlIGhldGVyb3Ryb3BoaWMgbWljcm9vcmdhbmlzbXMgdGhhdCBkZWdyYWRlIG9yZ2FuaWMgY2FyYm9uIGFuZCBDSH40fiB0aHJvdWdoIGFlcm9iaWMgbWV0YWJvbGljIHBhdGh3YXlzLCByZWxlYXNpbmcgQ09+Mn4uIFNvaWwgb3hpZGF0aW9uIHNob3VsZCBhbHNvIHN0aW11bGF0ZSBhZXJvYmljIGF1dG90cm9waGljIGlyb24gb3hpZGl6aW5nIGJhY3RlcmlhIHRoYXQgb3hpZGl6ZSBGZShJSSkgdG8gRmUoSUlJKSBhbmQgY29udmVydCBDT34yfiBpbnRvIG1pY3JvYmlhbCBiaW9tYXNzLiAgVGhlIGxvbmctdGVybSByZXNwb25zZSAoVDI0KSB3aWxsIGxpa2VseSBiZSBhIGNvbWJpbmF0aW9uIG9mIGFlcm9iaWMgYW5kIGFuYWVyb2JpYyBtZXRhYm9saXNtIGFzIHdlbGwgYXMgYSBjb21iaW5hdGlvbiBvZiByZWR1Y3Rpb24gYW5kIG94aWRhdGlvbiBpcm9uIHJlYWN0aW9ucyBhcyBkaXNzb2x2ZWQgb3h5Z2VuIGlzIGNvbnN1bWVkLiAgVGhlIHByZWRpY3RlZCByZWRveCBjb25kaXRpb25zIGFuZCBwcmVkaWN0ZWQgcmVkb3ggcmVhY3Rpb25zIGZvciBjb3VwbGVkIEZlKElJKS9GZShJSUkpIGN5Y2xpbmcsIGFzIHdlbGwgYXMgdGhlIG1pY3JvYmlhbC1pbmR1Y2VkIHJlbGVhc2Ugb2YgQ09+Mn4gb3IgQ0h+NH4gYXQgZWFjaCB0aW1lIHBvaW50IGFyZSBiYXNlZCBvbiB0aGUgcHJlZGljdGVkIGF2YWlsYWJpbGl0eSBvZiBkaXNzb2x2ZWQgb3h5Z2VuIGVudGVyaW5nIHR1bmRyYSBzb2lscyB0aHJvdWdoIHNpbXVsYXRlZCByYWluZmFsbC4KCjxmb250IGNvbG9yPSJibHVlIj4qKlNvaWwgU2FtcGxpbmcgZm9yIE1pY3JvYmlhbCBHZW5lIEV4cHJlc3Npb24qKjwvZm9udD4KCkFuIGluaXRpYWwgc29pbCBzYW1wbGluZyBldmVudCBmb3IgbWljcm9iaWFsIGFjdGl2aXR5IHdhcyBjb25kdWN0ZWQgYXQgdGhlIGVuZCBvZiB0aGUgYW5veGljIGFjY2xpbWF0aW9uIHBlcmlvZCAoNC03IGRheXMpIGluIGFsbCBtZXNvY29zbSByZXBsaWNhdGVzLCByZXByZXNlbnRpbmcgc2FtcGxpbmcgdGltZSBwb2ludCAqKlQwKiouICBNZXNvY29zbXMgd2VyZSB0aGVuIGZsdXNoZWQgdG8gc2ltdWxhdGUgYSByYWluZmFsbCBldmVudC4gIEFkZGl0aW9uYWwgc29pbCBzYW1wbGluZyBldmVudHMgd2VyZSBjb25kdWN0ZWQgYXQgKipUNCoqICg0LWhycykgYW5kICoqVDI0KiogKDI0LWhycykgZm9sbG93aW5nIHRoZSByYWluZmFsbCBldmVudCB0byBkZXRlcm1pbmUgdGhlIHRlbXBvcmFsIGV4dGVudCBvZiBtaWNyb2JpYWwgZ2VuZSBleHByZXNzaW9uLiAgU29pbCBjb3JlcyAoMi41NCBjbSBkaWFtZXRlciwgMzAgY20gbGVuZ3RoKSB3ZXJlIGV4dHJhY3RlZCBpbiBkdXBsaWNhdGUgZnJvbSBlYWNoIG1lc29jb3NtIHJlcGxpY2F0ZSBhdCBlYWNoIHNhbXBsaW5nIHRpbWUgcG9pbnQgYW5kIGhvbW9nZW5pemVkIGJ5IGRlcHRoIGluIDEwLWNtIGluY3JlbWVudHMuICBUaGUgMTAtMjAgY20gc29pbCBpbmNyZW1lbnQsIGNvbXBvc2VkIG9mIG9yZ2FuaWMgc29pbCBpbiBhbGwgbWVzb2Nvc20gcmVwbGljYXRlcywgd2FzIGNob3NlbiBmb3IgbWljcm9iaWFsIGdlbmUgZXhwcmVzc2lvbiBhbmFseXNpcyBhbmQgcHJlc2VydmVkIGluIFJOQWxhdGVyIFN0YWJpbGl6YXRpb24gUmVhZ2VudCBpbiBzdGVyaWxlIHR1YmVzIGF0IDQmZGVnO0MgZm9yIDE4IGhvdXJzIGFuZCB0aGVuIHN0b3JlZCBhdCAtODAmZGVnO0MgdW50aWwgZXh0cmFjdGlvbi4KCiFbXShSLkltYWdlcy9CdWNrZXRzLnBuZykKCioqRmllbGQgRXhwZXJpbWVudC4qKiBUdW5kcmEgc29pbCBjb3JlcyB3ZXJlIGNvbGxlY3RlZCBmcm9tIGZpZWxkIHNpdGVzIGluIEF1Z3VzdCAyMDE3ICh0b3AgbGVmdCkgYW5kIHBsYWNlZCBpbiBidWNrZXRzIHRvIGVzdGFibGlzaCB0aGUgbWVzb2Nvc20gZXhwZXJpbWVudCAoYm90dG9tIGxlZnQpLiAgVHVzc29jayB0dW5kcmEgY29yZXMgd2VyZSBjb21wb3NlZCBvZiBhbiBvcmdhbmljIHNvaWwgbGF5ZXIgb3Zlcmx5aW5nIGEgbWluZXJhbCBzb2lsIGxheWVyICh0b3AgbWlkZGxlKSB3aGlsZSB3ZXQgc2VkZ2UgdHVuZHJhIGNvcmVzIHdlcmUgY29tcG9zZWQgZW50aXJlbHkgb2Ygb3JnYW5pYyBzb2lsIChib3R0b20gbWlkZGxlKS4gIFNvaWwgc3Vic2FtcGxpbmcgZm9yIG1pY3JvYmlhbCBhY3Rpdml0eSB3YXMgdGFrZW4gZnJvbSB0aGUgMTAtMjAgY20gZGVwdGggb2YgZHVwbGljYXRlIHNvaWwgY29yZXMgaW4gVHVzc29jayAodG9wIHJpZ2h0KSBhbmQgV2V0IFNlZGdlIChib3R0b20gcmlnaHQpLgoKYGBge3IgZWNobz1GQUxTRX0KIyBTZXQgZ2xvYmFsIG9wdGlvbnMgZm9yIG5vdGVib29rCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gbm9ybWFsaXplUGF0aCgifi9EZXNrdG9wL1JhaW5TaW0yMDE3IikpCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9OCwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSkKYGBgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgd2FybmluZz1GQUxTRX0KIyBNYWtlIGEgdmVjdG9yIG9mIHJlcXVpcmVkIHBhY2thZ2VzCnJlcXVpcmVkLnBhY2thZ2VzIDwtIGMoImFwZSIsImNvd3Bsb3QiLCJkYXRhLnRhYmxlIiwiZGV2dG9vbHMiLCJkcGx5ciIsIkRUIiwiZWRnZVIiLCJnZ3Bsb3QyIiwiZ2dwdWJyIiwiZ3JpZCIsImdyaWRFeHRyYSIsImthYmxlRXh0cmEiLCJrbml0ciIsInBoZWF0bWFwIiwicG5nIiwiUkNvbG9yQnJld2VyIiwicmVzaGFwZSIsInJzdGF0aXgiLCJzdGF0bW9kIiwic3RyaW5nciIsInRpYmJsZSIsInRpZHlyIiwidGlkeXZlcnNlIiwidmVnYW4iLCJ5YW1sIikKCiMgTG9hZCByZXF1aXJlZCBwYWNrYWdlcwpsYXBwbHkocmVxdWlyZWQucGFja2FnZXMsIGxpYnJhcnksIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkKYGBgCgojIE1ldGF0cmFuc2NyaXB0b21lcwoKIyMgMS4gUk5BIFNlcXVlbmNpbmcKClRvdGFsIFJOQSB3YXMgZXh0cmFjdGVkIGZyb20gc29pbCBzYW1wbGVzIGFuZCB0cmVhdGVkIHdpdGggUmlib1pFUk8gclJOQSByZW1vdmFsICgqbGVhdmluZyBtUk5BIGFzIHRoZSBidWxrIG9mIHRoZSB0b3RhbCBSTkEgcG9vbCopLiAgVGhlIG1STkEgcG9vbCB3YXMgc2VxdWVuY2VkIG9uIHRoZSBJbGx1bWluYSBIaVNlcSA0MDAwIHBsYXRmb3JtICgxNTBicCBwYWlyZWQtZW5kIHJlYWRzKSBhdCB0aGUgVW5pdmVyc2l0eSBvZiBNaWNoaWdhbiBBZHZhbmNlZCBHZW5vbWljcyBDb3JlLgoKYGBge3IgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9CnJuYS5zZXFjb3JlIDwtcmVhZC50YWJsZSgiVGFibGUuRGF0YS9ybmEuc2VxY29yZS5hbGwudGFibGUudHh0IixzZXA9J1x0JywgcXVvdGU9IiIsIGZpbGw9VFJVRSxoZWFkZXIgPSBUUlVFKQpuYW1lcyhybmEuc2VxY29yZSk8LSBjKCJJRCIsICJTYW1wbGUiLCAiQ29uY2VudHJhdGlvbiAobmcvdUwpIiwgIlZvbCAodUwpIiwgIjI2MC8yODAiLCAiMjYwLzIzMCIsICJSSU4iKQprYWJsZShybmEuc2VxY29yZSwgY2FwdGlvbiA9ICJTZXFDb3JlIFJOQSBzYW1wbGUgc3VibWlzc2lvbiB0byBJbGx1bWluYSBIaVNlcSBwbGF0Zm9ybSIsIGFsaWduID0gImMiKSAlPiUga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIikpICU+JSByb3dfc3BlYygxMzoxOCwgYm9sZCA9IFQsIGNvbG9yID0gIndoaXRlIiwgYmFja2dyb3VuZCA9ICIjRDcyNjFFIikKYGBgCgoqKk5PVEU6KiogUk5BIFNhbXBsZXMgaW4gPGZvbnQgY29sb3I9InJlZCI+UkVEPC9mb250PiB3ZXJlIGV4Y2x1ZGVkIGZyb20gc2VxdWVuY2luZwoKIyMgMi4gUk5BIEJpb25mb3JtYXRpY3MKCiMjIyAyLjEuIFJhdyBSZWFkcwoKKioqUHJlcCBhbmQgUUMgdGhlIFJhdyBSZWFkcyAoSGVpbjogQ29taWNzIC0tIE9taWNzIFByZXApKioqCgpSYXcgUk5BIHNlcXVlbmNlIHJlYWRzIChtZXRhdHJhbnNjcmlwdG9taWNzKSB3ZXJlIHByb2Nlc3NlZCBpbml0aWFsbHkgd2l0aCB0aGUgc2FtZSBHZW9taWNybyBPbWljcyBjb250YWluZXIgY29tbWFuZHMgYXMgZm9yIHRoZSByYXcgRE5BIHNlcXVlbmNlIHJlYWRzIChtZXRhZ2Vub21pY3MpLCB3aXRoIHNldmVyYWwgZXhjZXB0aW9ucyBub3RlZCBiZWxvdzoKLSBUaGlzIHByZXAgc3RlcCBhc3N1bWVzIHRoZSByYXcgZGF0YSB0byBiZSBhdmFpbGFibGUgaW4gdW5jb21wcmVzc2VkIEZBU1RRIGZvcm1hdCwgb25lIGZpbGUgcGVyIHJlYWQgZGlyZWN0aW9uIGFuZCBlYWNoIHNhbXBsZSdzIGRhdGEgaW4gaXRzIG93biBkaXJlY3RvcnkKLSBUaGUgb21pY3MgcHJlcCBzY3JpcHQgd2lsbCBkZWNvbXByZXNzIGFuZCAoaWYgbmVlZGVkKSBjb25jYXRlbmF0ZSBzcGxpdCBmYXN0cSBmaWxlcyBhbmQgcHV0IHRoZW0gaW50byBhcHByb3ByaWF0ZWx5IG5hbWVzIGRpcmVjdG9yaWVzCgotIFRoZSBgb21pY3MgcWNgIHNjcmlwdCB3YXMgcnVuIGZvciBlYWNoIHNhbXBsZSBidXQgdGhpcyBjb21tYW5kIGRpZmZlcnMgZnJvbSB0aGUgbWV0YWdlbm9tZSB3b3JrZmxvdyBieSAqKk5PVCoqIGRlcmVwbGljYXRpbmcgdGhlIFJOQSByZWFkcwotIFdlIHdhbnQgdG8gKipLRUVQKiogYWxsIGNvcGllcyBvZiBpZGVudGljYWwgcmVhZHMgdG8gZGV0ZXJtaW5lIHRoZSBhYnVuZGFuY2Ugb2YgdHJhbnNjcmliZWQgZnVuY3Rpb25hbCBnZW5lcyBmcm9tIG1STkEKCmBgYGBtYXJrZG93bgpgciAnJ2B7VGVybWluYWx9CmNkIC9STkFfZGF0YS93b3JrCmNvbWljcyAtLSBvbWljcyBwcmVwIC9STkFfZGF0YS8xMDgzKgpjb21pY3MgLS0gb21pY3MgcWMgLS1uby1kZXJlcGxpY2F0ZSAxMDgzKgpgYGBgCgoqKlJOQS5kYXRhLnByZXAucWMucGJzKiogPGZvbnQgY29sb3I9ImdyZWVuIj4oIi9STkFfZGF0YS93b3JrLyIpPC9mb250PiAwMDoxNSAoaHI6bWluKQoKLSBSZW5hbWUgdGhlIGAuZmFzdHFgIGZpbGVzIHdpdGhpbiBlYWNoIHNhbXBsZSBmb2xkZXIgaW4gdGhlIDxmb250IGNvbG9yPSJncmVlbiI+IlJOQV9kYXRhL3dvcmsiPC9mb250PiBkaXJlY3RvcnkgYXMgIioqU2FtcGxlXzEwODM3OV9md2QuZmFzdHEqKiIsICIqKlNhbXBsZV8xMDgzNzlfcmV2LmZhc3RxKioiLCBldGMuCi0gQ3JlYXRlIGEgPGZvbnQgY29sb3I9ImdyZWVuIj4iL1JOQV9kYXRhL3dvcmsvbWFwcGluZyI8L2ZvbnQ+IGRpcmVjdG9yeSBhbmQgbW92ZSBvdmVyIGFsbCBvZiB0aGUgcmVuYW1lZCBgLmZhc3RxYCBmaWxlcyAoIioqU2FtcGxlXzEwODM3OV9md2QuZmFzdHEqKiIsICIqKlNhbXBsZV8xMDgzNzlfcmV2LmZhc3RxKioiLCBldGMuKQoKIyMjIDIuMi4gRXhwb3J0IE51Y2xlb3RpZGUgU2VxcwoKKioqKkV4cG9ydCB0aGUgbnVjbGVvdGlkZSBzZXF1ZW5jZXMgb2YgdGhlIE1ldGFnZW5vbWUgQW52aSdvIGdlbmUgY2FsbHMgKGZvciBtYXBwaW5nIE1UIHJlYWRzIHRvIHRoZSBNRyBnZW5lcykqKioKCi0gRmlyc3QsIGV4cG9ydCB0aGUgbnVjbGVvdGlkZSBzZXF1ZW5jZXMgb2YgdGhlIE1HIEFudmknbyBnZW5lIGNhbGxzOgoKYGBgYG1hcmtkb3duCmByICcnYHtUZXJtaW5hbH0KY2QgL0ROQV9kYXRhL3dvcmsvY29fYXNzZW1ibHkKYW52aS1nZXQtc2VxdWVuY2VzLWZvci1nZW5lLWNhbGxzIC1jIEROQV9kYXRhX2Jibm9ybV9hbnZpb19jb250aWdzLmRiIC1vIEROQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLmZuYQpgYGBgCioqRE5BLmRhdGEuYmJub3JtLmFudmlvLmV4cG9ydC5nZW5lLnNlcXMucGJzKiogPGZvbnQgY29sb3I9ImdyZWVuIj4oIi9STkFfZGF0YS93b3JrLyIpPC9mb250PiAwOjE2IChocjptaW4pCgotIE1vdmUgdGhlICoqIkROQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLmZuYSIqKiBmaWxlIHRvIHRoZSA8Zm9udCBjb2xvcj0iZ3JlZW4iPiIvUk5BX2RhdGEvd29yay9tYXBwaW5nIjwvZm9udD4gZGlyZWN0b3J5ICAKCjxmb250IGNvbG9yPSJibHVlIj4qKjIuMi4xKio8L2ZvbnQ+IEFkZCB0aGUgcHJlZml4ICJnZW5lY2FsbCIgdG8gYWxsIG51Y2xlb3RpZGUgc2VxdWVuY2VzIGluIHRoZSAqKiJETkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5mbmEiKiogZmlsZQpgYGBgbWFya2Rvd24KYHIgJydge1Rlcm1pbmFsfQpjZCAvUk5BX2RhdGEvd29yay9tYXBwaW5nCnNlZCAncy8+Lz5nZW5lY2FsbF8vZycgRE5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuZm5hID4gRE5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHNfZWRpdGVkLmZuYQptdiBETkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxsc19lZGl0ZWQuZm5hIEROQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLmZuYQpgYGBgCgo8Zm9udCBjb2xvcj0iYmx1ZSI+KioyLjIuMioqPC9mb250PiBVc2UgdGhlIGZvbGxvd2luZyBzY3JpcHQgdG8gcmVtb3ZlIGFsbCBlbXB0eSBzZXF1ZW5jZXMgZnJvbSB0aGUgKioiRE5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuZm5hIioqIGZpbGUKYGBgYG1hcmtkb3duCmByICcnYHtUZXJtaW5hbH0KY2QgL1JOQV9kYXRhL3dvcmsvbWFwcGluZwpzZWQgJy9ePi8ge047IC9cbiQvZH0nIEROQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLmZuYSA+IEROQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzX2NsZWFuLmZuYQptdiBETkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxsc19jbGVhbi5mbmEgRE5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuZm5hCmBgYGAKCiMjIyAyLjMuIEluZGV4IE1HIEdlbmVzCgoqKipJbmRleCB0aGUgTUcgR2VuZXMgYW5kIE1hcCBCYWNrIHRoZSBNVCBSZWFkcyAoSGVpbjogT21pY3MgTWFwcGluZykqKioKCi0gT25jZSB0aGUgc2VxdWVuY2UgaGVhZGVycyBpbiB0aGUgTUcgZ2VuZXMgZmlsZSB3ZXJlIGNsZWFuZWQgdXAsIHRoZXkgd2VyZSBpbmRleGVkIGFzIGZvbGxvd3M6CmBgYGBtYXJrZG93bgpgciAnJ2B7VGVybWluYWx9CmNkIC9STkFfZGF0YS93b3JrL21hcHBpbmcKY29taWNzIC0tIG9taWNzIG1hcHBpbmcgLWEgRE5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuZm5hIC0taW5kZXgtb25seQpgYGBgCioqRE5BLmRhdGEuYmJub3JtLmluZGV4Lk1HLmdlbmVzLnBicyoqIDxmb250IGNvbG9yPSJncmVlbiI+KCIvUk5BX2RhdGEvd29yay8iKTwvZm9udD4gMDA6MjYgKGhyOm1pbikKCi0gVGhlIG91dHB1dCB3YXMgaW4gYSBkaXJlY3RvcnkgY2FsbGVkIDxmb250IGNvbG9yPSJncmVlbiI+Ii9ib3d0aWUyLWluZGV4IjwvZm9udD4KLSBSZW5hbWUgYXMgPGZvbnQgY29sb3I9ImdyZWVuIj4iL2Jvd3RpZTItaW5kZXhfYmJub3JtX01HX2dlbmVzIjwvZm9udD4KCgo8Zm9udCBjb2xvcj0iYmx1ZSI+KioyLjMuMSoqPC9mb250PiBNYXBwaW5nIE1UIFFDJ2QgUmVhZHMgZnJvbSBFYWNoIFNhbXBsZSB0byB0aGUgSW5kZXhlZCBNRyBHZW5lcwoKLSBJbmRpdmlkdWFsbHkgbWFwIHRoZSBNVCBRQydkIHJlYWRzIGZyb20gZWFjaCBzYW1wbGUgdG8gdGhlIGluZGV4ZWQgTUcgZ2VuZXMsIHdoaWNoIHdpbGwgY3JlYXRlIHNlcGFyYXRlIG91dHB1dCBkaXJlY3RvcmllcyBmb3IgZWFjaCBzYW1wbGUgY29udGFpbmluZyB0aGUgbWFwcGluZyByZXN1bHQgZmlsZXMKCmBgYGBtYXJrZG93bgpgciAnJ2B7VGVybWluYWx9CmNkIC9STkFfZGF0YS93b3JrL21hcHBpbmcKY29taWNzIC0tIG9taWNzIG1hcHBpbmcgLS1pbmRleC1kaXIgL1JOQV9kYXRhL3dvcmsvbWFwcGluZy9ib3d0aWUyLWluZGV4X2Jibm9ybV9NR19nZW5lcy8gLWEgRE5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuZm5hIC1mIFNhbXBsZV8xMDgzNzlfZndkLmdvb2QuZmFzdHEgLXIgU2FtcGxlXzEwODM3OV9yZXYuZ29vZC5mYXN0cSAtbyAxMDgzNzlfTVRfbWFwcGVkX3JlYWRzCmNvbWljcyAtLSBvbWljcyBtYXBwaW5nIC0taW5kZXgtZGlyIC9STkFfZGF0YS93b3JrL21hcHBpbmcvYm93dGllMi1pbmRleF9iYm5vcm1fTUdfZ2VuZXMvIC1hIEROQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLmZuYSAtZiBTYW1wbGVfMTA4MzgxX2Z3ZC5nb29kLmZhc3RxIC1yIFNhbXBsZV8xMDgzODFfcmV2Lmdvb2QuZmFzdHEgLW8gMTA4MzgxX01UX21hcHBlZF9yZWFkcwpjb21pY3MgLS0gb21pY3MgbWFwcGluZyAtLWluZGV4LWRpciAvUk5BX2RhdGEvd29yay9tYXBwaW5nL2Jvd3RpZTItaW5kZXhfYmJub3JtX01HX2dlbmVzLyAtYSBETkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5mbmEgLWYgU2FtcGxlXzEwODM4Ml9md2QuZ29vZC5mYXN0cSAtciBTYW1wbGVfMTA4MzgyX3Jldi5nb29kLmZhc3RxIC1vIDEwODM4Ml9NVF9tYXBwZWRfcmVhZHMKY29taWNzIC0tIG9taWNzIG1hcHBpbmcgLS1pbmRleC1kaXIgL1JOQV9kYXRhL3dvcmsvbWFwcGluZy9ib3d0aWUyLWluZGV4X2Jibm9ybV9NR19nZW5lcy8gLWEgRE5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuZm5hIC1mIFNhbXBsZV8xMDgzODNfZndkLmdvb2QuZmFzdHEgLXIgU2FtcGxlXzEwODM4M19yZXYuZ29vZC5mYXN0cSAtbyAxMDgzODNfTVRfbWFwcGVkX3JlYWRzCmNvbWljcyAtLSBvbWljcyBtYXBwaW5nIC0taW5kZXgtZGlyIC9STkFfZGF0YS93b3JrL21hcHBpbmcvYm93dGllMi1pbmRleF9iYm5vcm1fTUdfZ2VuZXMvIC1hIEROQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLmZuYSAtZiBTYW1wbGVfMTA4Mzg1X2Z3ZC5nb29kLmZhc3RxIC1yIFNhbXBsZV8xMDgzODVfcmV2Lmdvb2QuZmFzdHEgLW8gMTA4Mzg1X01UX21hcHBlZF9yZWFkcwpjb21pY3MgLS0gb21pY3MgbWFwcGluZyAtLWluZGV4LWRpciAvUk5BX2RhdGEvd29yay9tYXBwaW5nL2Jvd3RpZTItaW5kZXhfYmJub3JtX01HX2dlbmVzLyAtYSBETkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5mbmEgLWYgU2FtcGxlXzEwODM4Nl9md2QuZ29vZC5mYXN0cSAtciBTYW1wbGVfMTA4Mzg2X3Jldi5nb29kLmZhc3RxIC1vIDEwODM4Nl9NVF9tYXBwZWRfcmVhZHMKY29taWNzIC0tIG9taWNzIG1hcHBpbmcgLS1pbmRleC1kaXIgL1JOQV9kYXRhL3dvcmsvbWFwcGluZy9ib3d0aWUyLWluZGV4X2Jibm9ybV9NR19nZW5lcy8gLWEgRE5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuZm5hIC1mIFNhbXBsZV8xMDgzODhfZndkLmdvb2QuZmFzdHEgLXIgU2FtcGxlXzEwODM4OF9yZXYuZ29vZC5mYXN0cSAtbyAxMDgzODhfTVRfbWFwcGVkX3JlYWRzCmNvbWljcyAtLSBvbWljcyBtYXBwaW5nIC0taW5kZXgtZGlyIC9STkFfZGF0YS93b3JrL21hcHBpbmcvYm93dGllMi1pbmRleF9iYm5vcm1fTUdfZ2VuZXMvIC1hIEROQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLmZuYSAtZiBTYW1wbGVfMTA4MzkwX2Z3ZC5nb29kLmZhc3RxIC1yIFNhbXBsZV8xMDgzOTBfcmV2Lmdvb2QuZmFzdHEgLW8gMTA4MzkwX01UX21hcHBlZF9yZWFkcwpjb21pY3MgLS0gb21pY3MgbWFwcGluZyAtLWluZGV4LWRpciAvUk5BX2RhdGEvd29yay9tYXBwaW5nL2Jvd3RpZTItaW5kZXhfYmJub3JtX01HX2dlbmVzLyAtYSBETkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5mbmEgLWYgU2FtcGxlXzEwODM5MV9md2QuZ29vZC5mYXN0cSAtciBTYW1wbGVfMTA4MzkxX3Jldi5nb29kLmZhc3RxIC1vIDEwODM5MV9NVF9tYXBwZWRfcmVhZHMKY29taWNzIC0tIG9taWNzIG1hcHBpbmcgLS1pbmRleC1kaXIgL1JOQV9kYXRhL3dvcmsvbWFwcGluZy9ib3d0aWUyLWluZGV4X2Jibm9ybV9NR19nZW5lcy8gLWEgRE5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuZm5hIC1mIFNhbXBsZV8xMDgzOTJfZndkLmdvb2QuZmFzdHEgLXIgU2FtcGxlXzEwODM5Ml9yZXYuZ29vZC5mYXN0cSAtbyAxMDgzOTJfTVRfbWFwcGVkX3JlYWRzCmNvbWljcyAtLSBvbWljcyBtYXBwaW5nIC0taW5kZXgtZGlyIC9STkFfZGF0YS93b3JrL21hcHBpbmcvYm93dGllMi1pbmRleF9iYm5vcm1fTUdfZ2VuZXMvIC1hIEROQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLmZuYSAtZiBTYW1wbGVfMTA4Mzk0X2Z3ZC5nb29kLmZhc3RxIC1yIFNhbXBsZV8xMDgzOTRfcmV2Lmdvb2QuZmFzdHEgLW8gMTA4Mzk0X01UX21hcHBlZF9yZWFkcwpjb21pY3MgLS0gb21pY3MgbWFwcGluZyAtLWluZGV4LWRpciAvUk5BX2RhdGEvd29yay9tYXBwaW5nL2Jvd3RpZTItaW5kZXhfYmJub3JtX01HX2dlbmVzLyAtYSBETkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5mbmEgLWYgU2FtcGxlXzEwODM5Nl9md2QuZ29vZC5mYXN0cSAtciBTYW1wbGVfMTA4Mzk2X3Jldi5nb29kLmZhc3RxIC1vIDEwODM5Nl9NVF9tYXBwZWRfcmVhZHMKYGBgYAoqKlJOQS5kYXRhLnJlYWQubWFwcGluZy5ETkEuZGF0YS5iYm5vcm0uTUcuZ2VuZXMucGJzKiogPGZvbnQgY29sb3I9ImdyZWVuIj4oIi9STkFfZGF0YS93b3JrLyIpPC9mb250PiAxMjoxMiAoaHI6bWluKSAgCgpUaGUgcmVzdWx0cyBmb3IgZWFjaCBpbmRpdmlkdWFsIHNhbXBsZSBpbmNsdWRlZCBhIG1hcHBpbmcgZGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhlIGZvbGxvd2luZyBmaWxlczoKPGZvbnQgY29sb3I9ImdyZWVuIj4iL1JOQV9kYXRhL3dvcmsvbWFwcGluZy9cKl9NVF9tYXBwZWRfcmVhZHMiPC9mb250PiAqKHJlcGxhY2UgXCogd2l0aCBTYW1wbGVJRCkqICAKCi0gKipTYW1wbGVfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuY292KiogdGFiLWRlbGltaXRlZCBmaWxlIG9mIHRoZSBhdmVyYWdlIGNvdmVyYWdlIG9mIGVhY2ggY29udGlnIGluIHRoZSBhc3NlbWJseQotICoqU2FtcGxlX1JOQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLnNvcnRlZC5iYW0qKiBjb250YWlucyB0aGUgbWFwcGluZyBpbmZvcm1hdGlvbiBzb3J0ZWQgYnkgcG9zaXRpb24KLSAqKlNhbXBsZV9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5zb3J0ZWQuYmFtLmJhaSoqIGNvbXBhbmlvbiBmaWxlIHRvIHRoZSBgc29ydGVkLmJhbWAgZmlsZSwgd2hpY2ggY29udGFpbnMgdGhlIGluZGV4CgojIyMgMi40LiBDb252ZXJ0IE1UIC5iYW0gRmlsZXMKCioqKkNvbnZlcnQgdGhlIE1UIC5iYW0gRmlsZXMgdG8gY291bnQgdGFibGVzIHRvIGJlIHByb2Nlc3NlZCBzdGF0aXN0aWNhbGx5KioqCgotIE1ha2UgcGlsZS11cCBmaWxlIChhdmVyYWdlIHJlYWQgZGVwdGggcGVyIGdlbmUpCi0gQkJNYXAgKHBpbGV1cC5zaCkgKioiZmluYWwuY29udGlncy5maXhlZC5iYm5vcm0uc29ydGVkLmJhbSIqKgoKYGBgYG1hcmtkb3duCmByICcnYHtUZXJtaW5hbH0KY2QgL1JOQV9kYXRhL3dvcmsvbWFwcGluZy8xMDgzNzlfTVRfbWFwcGVkX3JlYWRzCnBpbGV1cC5zaCBpbj1TYW1wbGVfMTA4Mzc5X1JOQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLnNvcnRlZC5iYW0gb3V0PVNhbXBsZV8xMDgzNzlfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMucGlsZXVwCgojT3V0cHV0CmhlYWQgU2FtcGxlXzEwODM3OV9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5waWxldXAKI0lECUF2Z19mb2xkCUxlbmd0aAlSZWZfR0MJQ292ZXJlZF9wZXJjZW50CUNvdmVyZWRfYmFzZXMJUGx1c19yZWFkcwlNaW51c19yZWFkcwlSZWFkX0dDCU1lZGlhbl9mb2xkCVN0ZF9EZXYKZ2VuZWNhbGxfMAkwLjAwMDAJMzAwCTAuMDAwMAkwLjAwMDAJMAkwCTAJMC4wMDAwCTAJMC4wMApnZW5lY2FsbF8xCTAuMDAwMAkzMTgJMC4wMDAwCTAuMDAwMAkwCTAJMAkwLjAwMDAJMAkwLjAwCmdlbmVjYWxsXzIJMC4wMDAwCTY0OAkwLjAwMDAJMC4wMDAwCTAJMAkwCTAuMDAwMAkwCTAuMDAKZ2VuZWNhbGxfMwkwLjAwMDAJMzc1CTAuMDAwMAkwLjAwMDAJMAkwCTAJMC4wMDAwCTAJMC4wMApnZW5lY2FsbF80CTAuMDAwMAkzMzkJMC4wMDAwCTAuMDAwMAkwCTAJMAkwLjAwMDAJMAkwLjAwCmdlbmVjYWxsXzUJMC4wMDAwCTE0MQkwLjAwMDAJMC4wMDAwCTAJMAkwCTAuMDAwMAkwCTAuMDAKZ2VuZWNhbGxfNgkwLjAwMDAJMTMyCTAuMDAwMAkwLjAwMDAJMAkwCTAJMC4wMDAwCTAJMC4wMApnZW5lY2FsbF83CTEuOTY0MgkzNjMJMC4wMDAwCTkyLjgzNzUJMzM3CTQJMQkwLjcxNDkJMQkxLjM5CmdlbmVjYWxsXzgJMC4wMDAwCTQwMgkwLjAwMDAJMC4wMDAwCTAJMAkwCTAuMDAwMAkwCTAuMDAKYGBgYAoKLSBUaGlzIHdhcyBkb25lIGZvciBlYWNoIFNhbXBsZSBgc29ydGVkLmJhbWAgZmlsZSB0byBnZXQgYSB0YWJsZSBvZiBnZW5lcyBhbmQgdGhlaXIgY291bnRzICAKCmBgYGBtYXJrZG93bgpgciAnJ2B7VGVybWluYWx9CmNkIC9STkFfZGF0YS93b3JrL21hcHBpbmcvMTA4MzgxX01UX21hcHBlZF9yZWFkcwpwaWxldXAuc2ggaW49U2FtcGxlXzEwODM4MV9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5zb3J0ZWQuYmFtIG91dD1TYW1wbGVfMTA4MzgxX1JOQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLnBpbGV1cApjZCAvUk5BX2RhdGEvd29yay9tYXBwaW5nLzEwODM4Ml9NVF9tYXBwZWRfcmVhZHMKcGlsZXVwLnNoIGluPVNhbXBsZV8xMDgzODJfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuc29ydGVkLmJhbSBvdXQ9U2FtcGxlXzEwODM4Ml9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5waWxldXAKY2QgL1JOQV9kYXRhL3dvcmsvbWFwcGluZy8xMDgzODNfTVRfbWFwcGVkX3JlYWRzCnBpbGV1cC5zaCBpbj1TYW1wbGVfMTA4MzgzX1JOQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLnNvcnRlZC5iYW0gb3V0PVNhbXBsZV8xMDgzODNfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMucGlsZXVwCmNkIC9STkFfZGF0YS93b3JrL21hcHBpbmcvMTA4Mzg1X01UX21hcHBlZF9yZWFkcwpwaWxldXAuc2ggaW49U2FtcGxlXzEwODM4NV9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5zb3J0ZWQuYmFtIG91dD1TYW1wbGVfMTA4Mzg1X1JOQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLnBpbGV1cApjZCAvUk5BX2RhdGEvd29yay9tYXBwaW5nLzEwODM4Nl9NVF9tYXBwZWRfcmVhZHMKcGlsZXVwLnNoIGluPVNhbXBsZV8xMDgzODZfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuc29ydGVkLmJhbSBvdXQ9U2FtcGxlXzEwODM4Nl9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5waWxldXAKY2QgL1JOQV9kYXRhL3dvcmsvbWFwcGluZy8xMDgzODhfTVRfbWFwcGVkX3JlYWRzCnBpbGV1cC5zaCBpbj1TYW1wbGVfMTA4Mzg4X1JOQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLnNvcnRlZC5iYW0gb3V0PVNhbXBsZV8xMDgzODhfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMucGlsZXVwCmNkIC9STkFfZGF0YS93b3JrL21hcHBpbmcvMTA4MzkwX01UX21hcHBlZF9yZWFkcwpwaWxldXAuc2ggaW49U2FtcGxlXzEwODM5MF9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5zb3J0ZWQuYmFtIG91dD1TYW1wbGVfMTA4MzkwX1JOQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLnBpbGV1cApjZCAvUk5BX2RhdGEvd29yay9tYXBwaW5nLzEwODM5MV9NVF9tYXBwZWRfcmVhZHMKcGlsZXVwLnNoIGluPVNhbXBsZV8xMDgzOTFfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuc29ydGVkLmJhbSBvdXQ9U2FtcGxlXzEwODM5MV9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5waWxldXAKY2QgL1JOQV9kYXRhL3dvcmsvbWFwcGluZy8xMDgzOTJfTVRfbWFwcGVkX3JlYWRzCnBpbGV1cC5zaCBpbj1TYW1wbGVfMTA4MzkyX1JOQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLnNvcnRlZC5iYW0gb3V0PVNhbXBsZV8xMDgzOTJfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMucGlsZXVwCmNkIC9STkFfZGF0YS93b3JrL21hcHBpbmcvMTA4Mzk0X01UX21hcHBlZF9yZWFkcwpwaWxldXAuc2ggaW49U2FtcGxlXzEwODM5NF9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5zb3J0ZWQuYmFtIG91dD1TYW1wbGVfMTA4Mzk0X1JOQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLnBpbGV1cApjZCAvUk5BX2RhdGEvd29yay9tYXBwaW5nLzEwODM5Nl9NVF9tYXBwZWRfcmVhZHMKcGlsZXVwLnNoIGluPVNhbXBsZV8xMDgzOTZfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMuc29ydGVkLmJhbSBvdXQ9U2FtcGxlXzEwODM5Nl9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5waWxldXAKYGBgYAoqKlJOQS5kYXRhLmJhbS50by5waWxlLnVwLnBicyoqIDxmb250IGNvbG9yPSJncmVlbiI+KCIvUk5BX2RhdGEvd29yay8iKTwvZm9udD4gMDA6MDEgKGhyOm1pbikKCi0gTW92ZSBhbGwgb2YgdGhlICoqIlNhbXBsZV9cKl9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5waWxldXAiKiogZmlsZXMgdG8gdGhlIDxmb250IGNvbG9yPSJncmVlbiI+Ii9STkFfZGF0YS93b3JrL21hcHBpbmcvUGlsZV9VcCI8L2ZvbnQ+IGRpcmVjdG9yeQotIEltcG9ydCB0aGVzZSB0YWJsZXMgaW50byAqKlIqKiBhbmQgYWRkIHVwIHRoZSAqKiJwbHVzIHJlYWQiKiogYW5kICoqIm1pbnVzIHJlYWQiKiogdmFsdWVzIGZvciBlYWNoIGdlbmUgKD0gdG90YWwgcmVhZHMgb2YgdGhhdCBwYXJ0aWN1bGFyIGdlbmUpCgojIyMgMi41LiBNVCBSZWFkIFN1bW1hcnkKClRoZSBmb2xsb3dpbmcgdGFibGUgaXMgYSBzdW1tYXJ5IG9mIHRoZSBSTkEgcmVhZHMgYnkgc2FtcGxlIGFuZCBpbmNsdWRlcyAqKlFDIFJlYWRzKiosICoqTWFwcGVkIFJlYWRzKiosIGFuZCAqKkF2ZXJhZ2UgUmVhZCBMZW5ndGggKGJwKSoqLiAgQWxsIHZhbHVlcyB3ZXJlIGRlcml2ZWQgZnJvbSB0aGUgIioqU2FtcGxlX1wqLmZpbmFsLmNvbnRpZ3MuZml4ZWQuYmJub3JtLnNvcnRlZC5iYW0qKiIgZmlsZXMgdXNpbmcgYHNhbXRvb2xzIHN0YXRzYC4KYGBge3IgZWNobz1GQUxTRX0Kcm5hLmluZm9ybWF0aWNzPC1yZWFkLnRhYmxlKCJUYWJsZS5EYXRhL3JuYS5iaW9pbmZvcm1hdGljcy50YWJsZS50eHQiLHNlcD0nXHQnLCBxdW90ZT0iIiwgZmlsbD1UUlVFLGhlYWRlciA9IFRSVUUpCm5hbWVzKHJuYS5pbmZvcm1hdGljcyk8LWMoIklEIiwgIlR1bmRyYSIsICJUaW1lIiwgIlJlcGxpY2F0ZSIsICJRQyBSZWFkcyIsICJNYXBwZWQgUmVhZHMiLCAiQXZlcmFnZSBMZW5ndGggKGJwKSIpCmthYmxlKHJuYS5pbmZvcm1hdGljcywgY2FwdGlvbiA9ICJTdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIFJOQS1iYXNlZCBtZXRhdHJhbnNjcmlwdG9tZSBzZXF1ZW5jaW5nIGRhdGFzZXQiLCBmb3JtYXQuYXJncyA9IGxpc3QoYmlnLm1hcmsgPSAiLCIpLCBhbGlnbiA9ICJjIikgJT4lIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpKQpgYGAKCiMjIDMuIEdlbmUgQW5ub3RhdGlvbnMKCkZvbGxvd2luZyBhbGwgKipEYXRhIEJpb2luZm9ybWF0aWNzKiogc3RlcHMgYWJvdmUsIHF1YWxpdHktY29udHJvbGxlZCBtZXRhdHJhbnNjcmlwdG9tZSByZWFkcyB3ZXJlIG1hcHBlZCB0byBLRUdHLWFubm90YXRlZCBjb2Rpbmcgc2VxdWVuY2VzIChDRFMpIGluZGV4ZWQgZnJvbSB0aGUgbWV0YWdlbm9tZSBhc3NlbWJseSB1c2luZyBCQk1hcCB0byBnZW5lcmF0ZSBwaWxlLXVwIGZpbGVzIChhdmVyYWdlIHJlYWQgZGVwdGggcGVyIGdlbmUpLCBhbmQgU0FNdG9vbHMgd2FzIHVzZWQgdG8gZXh0cmFjdCBjb3VudHMgYW5kIENEUyBsZW5ndGhzIGZyb20gdGhlIEJCTWFwIG91dHB1dC4KCiMjIyAzLjEuIEltcG9ydCBHZW5lIENvdW50cwpJbiB0aGlzIHNlY3Rpb24sIGFsbCBgUk5BLnBpbGV1cGAgZmlsZXMgYXJlIGltcG9ydGVkIGludG8gdGhlIFIgZW52aXJvbm1lbnQgYW5kIGNvbWJpbmVkIGludG8gdGhlIGZpcnN0ICoqRlVMTCoqIGRhdGFzZXQgdG8gYmUgZnVydGhlciBmb3JtYXR0ZWQgZm9yIGRvd25zdHJlYW0gc3RhdGlzdGljYWwgYW5hbHlzaXMuCgojIyMjIDMuMS4xLiBSTkEgUGlsZVVwIEZpbGVzClRoZSBmb2xsb3dpbmcgYFJOQS5waWxldXBgIGZpbGVzIChhdmVyYWdlIHJlYWQgZGVwdGggcGVyIGdlbmUpIGZvciBlYWNoIG1ldGF0cmFuc2NyaXB0b21lIHNhbXBsZSB3ZXJlIGdlbmVyYXRlZCB2aWEgdGhlIEJCTWFwIG1vZHVsZS4KCmBgYHtyfQojUzEwODM3OSAtLSBXU19UMF9SMQpwaWxldXBfMTA4Mzc5PC1yZWFkLnRhYmxlKCJQaWxldXAuRGF0YS9STkEuUGlsZXVwL1NhbXBsZV8xMDgzNzlfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMucGlsZXVwIiwgaGVhZGVyID0gVFJVRSkKcGlsZXVwXzEwODM3OSRTMTA4Mzc5IDwtIHBpbGV1cF8xMDgzNzkkUGx1c19yZWFkcyArIHBpbGV1cF8xMDgzNzkkTWludXNfcmVhZHMKCiNTMTA4MzgxIC0tIFdTX1QwX1IzCnBpbGV1cF8xMDgzODE8LXJlYWQudGFibGUoIlBpbGV1cC5EYXRhL1JOQS5QaWxldXAvU2FtcGxlXzEwODM4MV9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5waWxldXAiLCBoZWFkZXIgPSBUUlVFKQpwaWxldXBfMTA4MzgxJFMxMDgzODEgPC0gcGlsZXVwXzEwODM4MSRQbHVzX3JlYWRzICsgcGlsZXVwXzEwODM4MSRNaW51c19yZWFkcwoKI1MxMDgzODUgLS0gV1NfVDRfUjEKcGlsZXVwXzEwODM4NTwtcmVhZC50YWJsZSgiUGlsZXVwLkRhdGEvUk5BLlBpbGV1cC9TYW1wbGVfMTA4Mzg1X1JOQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLnBpbGV1cCIsIGhlYWRlciA9IFRSVUUpCnBpbGV1cF8xMDgzODUkUzEwODM4NSA8LSBwaWxldXBfMTA4Mzg1JFBsdXNfcmVhZHMgKyBwaWxldXBfMTA4Mzg1JE1pbnVzX3JlYWRzCgojUzEwODM4NiAtLSBXU19UNF9SMgpwaWxldXBfMTA4Mzg2PC1yZWFkLnRhYmxlKCJQaWxldXAuRGF0YS9STkEuUGlsZXVwL1NhbXBsZV8xMDgzODZfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMucGlsZXVwIiwgaGVhZGVyID0gVFJVRSkKcGlsZXVwXzEwODM4NiRTMTA4Mzg2IDwtIHBpbGV1cF8xMDgzODYkUGx1c19yZWFkcyArIHBpbGV1cF8xMDgzODYkTWludXNfcmVhZHMKCiNTMTA4Mzg4IC0tIFdTX1QyNF9SMQpwaWxldXBfMTA4Mzg4PC1yZWFkLnRhYmxlKCJQaWxldXAuRGF0YS9STkEuUGlsZXVwL1NhbXBsZV8xMDgzODhfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMucGlsZXVwIiwgaGVhZGVyID0gVFJVRSkKcGlsZXVwXzEwODM4OCRTMTA4Mzg4IDwtIHBpbGV1cF8xMDgzODgkUGx1c19yZWFkcyArIHBpbGV1cF8xMDgzODgkTWludXNfcmVhZHMKCiNTMTA4MzkwIC0tIFdTX1QyNF9SMwpwaWxldXBfMTA4MzkwPC1yZWFkLnRhYmxlKCJQaWxldXAuRGF0YS9STkEuUGlsZXVwL1NhbXBsZV8xMDgzOTBfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMucGlsZXVwIiwgaGVhZGVyID0gVFJVRSkKcGlsZXVwXzEwODM5MCRTMTA4MzkwIDwtIHBpbGV1cF8xMDgzOTAkUGx1c19yZWFkcyArIHBpbGV1cF8xMDgzOTAkTWludXNfcmVhZHMKCiNTMTA4MzgyIC0tIFRVU1NfVDBfUjEKcGlsZXVwXzEwODM4MjwtcmVhZC50YWJsZSgiUGlsZXVwLkRhdGEvUk5BLlBpbGV1cC9TYW1wbGVfMTA4MzgyX1JOQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLnBpbGV1cCIsIGhlYWRlciA9IFRSVUUpCnBpbGV1cF8xMDgzODIkUzEwODM4MiA8LSBwaWxldXBfMTA4MzgyJFBsdXNfcmVhZHMgKyBwaWxldXBfMTA4MzgyJE1pbnVzX3JlYWRzCgojUzEwODM4MyAtLSBUVVNTX1QwX1IyCnBpbGV1cF8xMDgzODM8LXJlYWQudGFibGUoIlBpbGV1cC5EYXRhL1JOQS5QaWxldXAvU2FtcGxlXzEwODM4M19STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5waWxldXAiLCBoZWFkZXIgPSBUUlVFKQpwaWxldXBfMTA4MzgzJFMxMDgzODMgPC0gcGlsZXVwXzEwODM4MyRQbHVzX3JlYWRzICsgcGlsZXVwXzEwODM4MyRNaW51c19yZWFkcwoKI1MxMDgzOTEgLS0gVFVTU19UNF9SMQpwaWxldXBfMTA4MzkxPC1yZWFkLnRhYmxlKCJQaWxldXAuRGF0YS9STkEuUGlsZXVwL1NhbXBsZV8xMDgzOTFfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMucGlsZXVwIiwgaGVhZGVyID0gVFJVRSkKcGlsZXVwXzEwODM5MSRTMTA4MzkxIDwtIHBpbGV1cF8xMDgzOTEkUGx1c19yZWFkcyArIHBpbGV1cF8xMDgzOTEkTWludXNfcmVhZHMKCiNTMTA4MzkyIC0tIFRVU1NfVDRfUjIKcGlsZXVwXzEwODM5MjwtcmVhZC50YWJsZSgiUGlsZXVwLkRhdGEvUk5BLlBpbGV1cC9TYW1wbGVfMTA4MzkyX1JOQV9kYXRhX2Jibm9ybV9hbnZpb19nZW5lX2NhbGxzLnBpbGV1cCIsIGhlYWRlciA9IFRSVUUpCnBpbGV1cF8xMDgzOTIkUzEwODM5MiA8LSBwaWxldXBfMTA4MzkyJFBsdXNfcmVhZHMgKyBwaWxldXBfMTA4MzkyJE1pbnVzX3JlYWRzCgojUzEwODM5NCAtLSBUVVNTX1QyNF9SMQpwaWxldXBfMTA4Mzk0PC1yZWFkLnRhYmxlKCJQaWxldXAuRGF0YS9STkEuUGlsZXVwL1NhbXBsZV8xMDgzOTRfUk5BX2RhdGFfYmJub3JtX2FudmlvX2dlbmVfY2FsbHMucGlsZXVwIiwgaGVhZGVyID0gVFJVRSkKcGlsZXVwXzEwODM5NCRTMTA4Mzk0IDwtIHBpbGV1cF8xMDgzOTQkUGx1c19yZWFkcyArIHBpbGV1cF8xMDgzOTQkTWludXNfcmVhZHMKCiNTMTA4Mzk2IC0tIFRVU1NfVDI0X1IzCnBpbGV1cF8xMDgzOTY8LXJlYWQudGFibGUoIlBpbGV1cC5EYXRhL1JOQS5QaWxldXAvU2FtcGxlXzEwODM5Nl9STkFfZGF0YV9iYm5vcm1fYW52aW9fZ2VuZV9jYWxscy5waWxldXAiLCBoZWFkZXIgPSBUUlVFKQpwaWxldXBfMTA4Mzk2JFMxMDgzOTYgPC0gcGlsZXVwXzEwODM5NiRQbHVzX3JlYWRzICsgcGlsZXVwXzEwODM5NiRNaW51c19yZWFkcwpgYGAKCiMjIyMgMy4xLjIuIEZ1bGwgUk5BIERhdGFzZXQKCkluIHRoZSBwcmV2aW91cyBzdGVwLCBlYWNoIGBSTkEucGlsZXVwYCBmaWxlIHdhcyBpbXBvcnRlZCBhbmQgYW4gYWRkaXRpb25hbCBjb2x1bW4gd2FzIGFkZGVkIHRoYXQgc3VtbWVkIHRoZSAqKiJQbHVzX3JlYWRzIioqIGFuZCB0aGUgKipNaW51c19yZWFkcyoqLiBUaGUgc3VtIGNvbHVtbiBpbiBlYWNoIGBSTkEucGlsZXVwYCBmaWxlIHdhcyBuYW1lZCBhZnRlciB0aGUgYFJOQS5waWxldXBgIHNhbXBsZSBuYW1lIChlLmcuICoqIlMxMDgzNzkiKiopLiBBbGwgYFJOQS5waWxldXBgIGZpbGVzIGNvbnRhaW4gaWRlbnRpY2FsIGdlbmVjYWxscyBpbiBhbiBpZGVudGljYWwgb3JkZXIgYWxsb3dpbmcgdXMgdG8gZXh0cmFjdCB0aGUgZ2VuZWNhbGwgSUQgYW5kIGdlbmVjYWxsIExlbmd0aCBjb2x1bW5zIGZyb20gYSBzaW5nbGUgc2FtcGxlICgqKlMxMDgzNzkqKiksIGFsb25nIHdpdGggdGhlIHN1bW1lZCBjb3VudCBjb2x1bW4gb2YgZWFjaCBzYW1wbGUsIHRvIGNyZWF0ZSBhIG5ldyBkYXRhZnJhbWUgdGhhdCByZXByZXNlbnRzIHRoZSBpbml0aWFsLCAqKkZVTEwqKiBSTkEgZGF0YXNldCBmb3IgZG93bnN0cmVhbSBhbmFseXNlczoKCmBgYHtyfQpjdHNfcm5hX2FsbCA8LSBkYXRhLmZyYW1lKHBpbGV1cF8xMDgzNzkkSUQsIHBpbGV1cF8xMDgzNzkkTGVuZ3RoLCBwaWxldXBfMTA4Mzc5JFMxMDgzNzksIHBpbGV1cF8xMDgzODEkUzEwODM4MSwgcGlsZXVwXzEwODM4MiRTMTA4MzgyLCBwaWxldXBfMTA4MzgzJFMxMDgzODMsIHBpbGV1cF8xMDgzODUkUzEwODM4NSwgcGlsZXVwXzEwODM4NiRTMTA4Mzg2LCBwaWxldXBfMTA4Mzg4JFMxMDgzODgsIHBpbGV1cF8xMDgzOTAkUzEwODM5MCwgcGlsZXVwXzEwODM5MSRTMTA4MzkxLCBwaWxldXBfMTA4MzkyJFMxMDgzOTIsIHBpbGV1cF8xMDgzOTQkUzEwODM5NCwgcGlsZXVwXzEwODM5NiRTMTA4Mzk2KQoKbmFtZXMoY3RzX3JuYV9hbGwpIDwtIGMoIklEIiwgIkxlbmd0aCIsICJTMTA4Mzc5IiwgIlMxMDgzODEiLCAiUzEwODM4MiIsICJTMTA4MzgzIiwgIlMxMDgzODUiLCAiUzEwODM4NiIsICJTMTA4Mzg4IiwgIlMxMDgzOTAiLCAiUzEwODM5MSIsICJTMTA4MzkyIiwgIlMxMDgzOTQiLCAiUzEwODM5NiIpCmBgYAoKIyMjIDMuMi4gSW1wb3J0IEdlbmUgQW5ub3RhdGlvbnMKVGhlIEtFR0cgRnVuY3Rpb25zIGZpbGUgKEdob3N0S29hbGEpIGFuZCBLRUdHIFRheG9ub215IGZpbGUgKEdob3N0S29hbGEpIHdlcmUgaW1wb3J0ZWQgYW5kIHRoZSBmdW5jdGlvbmFsIGFuZCB0YXhvbm9taWMgYW5ub3RhdGlvbnMgd2VyZSBtYXRjaGVkIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgZ2VuZWNhbGwgSUQuCgojIyMjIDMuMi4xLiBLRUdHIFJlZmVyZW5jZQpGaXJzdCwgYSBLRUdHIHJlZmVyZW5jZSBmaWxlIHdhcyBpbXBvcnRlZCB3aXRoIGFkZGl0aW9uYWwgS0VHRyBUaWVyIHBhdGh3YXlzIHRoYXQgcHJvdmlkZSBhZGRpdGlvbmFsLCB1c2VmdWwsIGZ1bmN0aW9uYWwgY2F0ZWdvcmllcyBmb3IgZG93bnN0cmVhbSBhbmFseXNlcy4gIFRoZSBUaWVyIElJLCBJSUksIGFuZCBJViBjYXRlZ29yaWVzIHdlcmUgbWVyZ2VkIHRvIHRoZSBHaG9zdEtvYWxhIEtFR0cgZnVuY3Rpb25hbCBhbm5vdGF0aW9ucyBpbiBzdWJzZXF1ZW50IHN0ZXBzLgoKYGBge3J9CiMgSW1wb3J0IEtPX09ydGhvbG9neS50eHQgcmVmZXJlbmNlIGZpbGUKS09fcmVmPC1yZWFkLnRhYmxlKGZpbGU9J0Fubm90YXRpb25zLkRhdGEvS09fT3J0aG9sb2d5LnR4dCcsIHNlcD0nXHQnLCBxdW90ZT0iIiwgZmlsbD1UUlVFLCBoZWFkZXIgPSBGQUxTRSkKCiMgUmVuYW1lIGNvbHVtbiBoZWFkZXJzCm5hbWVzKEtPX3JlZik8LWMoIlRpZXJfSUkiLCJUaWVyX0lJSSIsIlRpZXJfSVYiLCJLRUdHIikKCiMgU2VwYXJhdGUgIktFR0ciIGNvbHVtbiBpbnRvICJLTyIgYW5kICJBbm5vdGF0aW9uIiBjb2x1bW5zCktPX3JlZjwtS09fcmVmICU+JSBzZXBhcmF0ZShLRUdHLCBjKCJLT19BY2Nlc3Npb24iLCJBbm5vdGF0aW9uIiksICIgIiwgZXh0cmE9Im1lcmdlIikKCiMgRnVydGhlciBzZXBhcmF0YWUgIkFubm90YXRpb24iIGNvbHVtbiBpbnRvICJTeW1ib2wiIGFuZCAiRnVuY3Rpb24iIGNvbHVtbnMKS09fcmVmPC1LT19yZWYgJT4lIHNlcGFyYXRlKEFubm90YXRpb24sIGMoIktPX1N5bWJvbCIsIktPX0Z1bmN0aW9uIiksICI7ICIsIGV4dHJhPSJtZXJnZSIpCmBgYAoKIyMjIyAzLjIuMi4gS0VHRyBGdW5jdGlvbnMKClRoZXJlIGFyZSAzLDkxNyw2MTYgdG90YWwgdW5pcXVlIEROQS1iYXNlZCBnZW5lY2FsbHMgaW4gdGhlIG1ldGFnZW5vbWljIGRhdGFzZXQuICBUaGUgR2hvc3RLT0FMQSBLRUdHIGZ1bmN0aW9uYWwgYW5ub3RhdGlvbnMgZmlsZSAgKCIqKkROQV9kYXRhX2Jibm9ybV9hbnZpb19jb250aWdzX2Fubm90YXRpb25zLnRzdioqIikgY29udGFpbnMgYW5ub3RhdGlvbnMgZm9yIDEsMzg5LDUxOCB1bmlxdWUgRE5BLWJhc2VkIGdlbmVjYWxscy4gIFRoaXMgaW5kaWNhdGVzIHRoYXQgKiozNS41JSoqIG9mIHRoZSB0b3RhbCB1bmlxdWUgRE5BLWJhc2VkIGdlbmVjYWxscyBjYW4gYmUgZnVuY3Rpb25hbGx5IGFubm90YXRlZC4gIFRoYXQgYWxzbyBtZWFucyB0aGF0ICoqNjQuNSUqKiBvZiB1bmlxdWUgRE5BLWJhc2VkIGdlbmVjYWxscyBjYW5ub3QgYmUgYW5ub3RhdGVkIGFuZCB3aWxsIG5vdCBiZSBpbmNsdWRlZCBpbiBkb3duc3RyZWFtIGFuYWx5c2VzLiBIZXJlLCB0aGUgdW5pcXVlIGdlbmVjYWxsIGZ1bmN0aW9uYWwgYW5ub3RhdGlvbnMgd2lsbCBiZSBtYXRjaGVkIHRvIHRoZSBzYW1lIHVuaXF1ZSBnZW5lY2FsbHMgaW4gdGhlIEROQS1iYXNlZCBtZXRhZ2Vub21pYyBkYXRhc2V0LgoKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBJbXBvcnQgdGhlIEtFR0cgRnVuY3Rpb25hbCBBbm5vdGF0aW9ucyBmaWxlIHRoYXQgd2FzIGV4cG9ydGVkIGZyb20gdGhlIEFudmknbyBETkEgY29udGlncyBkYXRhYmFzZQpLZWdnQW52aW88LXJlYWQudGFibGUoZmlsZT0nQW5ub3RhdGlvbnMuRGF0YS9ETkFfZGF0YV9iYm5vcm1fYW52aW9fY29udGlnc19hbm5vdGF0aW9ucy50c3YnLCBzZXA9J1x0JywgcXVvdGUgPSAiIiwgZmlsbCA9IFRSVUUsIGhlYWRlciA9IFRSVUUpCgojIFJlbmFtZSBjb2x1bW4gaGVhZGVycwpuYW1lcyhLZWdnQW52aW8pPC1jKCJJRCIsIlNvdXJjZSIsIkFjY2Vzc2lvbiIsIkZ1bmN0aW9uIiwiZS12YWx1ZSIpCgojIFNlcGFyYXRlICJGdW5jdGlvbiIgY29sdW1uIGludG8gIlN5bWJvbCIgYW5kICJGdW5jdGlvbiIgY29sdW1ucwpLZWdnQW52aW88LUtlZ2dBbnZpbyAlPiUgc2VwYXJhdGUoRnVuY3Rpb24sIGMoIlN5bWJvbCIsIkZ1bmN0aW9uIiksICI7ICIsIGV4dHJhPSJtZXJnZSIpCgojIEFkZCAiZ2VuZWNhbGxfIiB0byB0aGUgYmVnaW5uaW5nIG9mIGVhY2ggZ2VuZSBJRCB2YWx1ZSB0byBtYXRjaCB3aXRoIGRvd25zdHJlYW0gYW5hbHlzZXMKS2VnZ0FudmlvJElEIDwtIHBhc3RlKCJnZW5lY2FsbCIsIEtlZ2dBbnZpbyRJRCwgc2VwPSJfIikKCiMgQWRkICJLT19TeW1ib2wiIGNhdGVnb3J5IHRvIHRoZSBkYXRhc2V0LCBtYXRjaGVkIGJ5IEtPJ3MgYmV0d2VlbiB0aGUgS09fcmVmIGZpbGUgYW5kIEtlZ2dBbnZpbwpLZWdnQW52aW8kS09fU3ltYm9sID0gS09fcmVmW21hdGNoKEtlZ2dBbnZpbyRBY2Nlc3Npb24sIEtPX3JlZiRLT19BY2Nlc3Npb24pLCAiS09fU3ltYm9sIl0KCiMgQWRkICJLT19GdW5jdGlvbiIgY2F0ZWdvcnkgdG8gdGhlIGRhdGFzZXQsIG1hdGNoZWQgYnkgS08ncyBiZXR3ZWVuIHRoZSBLT19yZWYgZmlsZSBhbmQgS2VnZ0FudmlvCktlZ2dBbnZpbyRLT19GdW5jdGlvbiA9IEtPX3JlZlttYXRjaChLZWdnQW52aW8kQWNjZXNzaW9uLCBLT19yZWYkS09fQWNjZXNzaW9uKSwgIktPX0Z1bmN0aW9uIl0KCiMgQWRkICJUaWVyX0lJIiBjYXRlZ29yeSB0byB0aGUgZGF0YXNldCwgbWF0Y2hlZCBieSBLTydzIGJldHdlZW4gdGhlIEtPX3JlZiBmaWxlIGFuZCBLZWdnQW52aW8KS2VnZ0FudmlvJFRpZXJfSUkgPSBLT19yZWZbbWF0Y2goS2VnZ0FudmlvJEFjY2Vzc2lvbiwgS09fcmVmJEtPX0FjY2Vzc2lvbiksICJUaWVyX0lJIl0KCiMgQWRkICJUaWVyX0lJSSIgY2F0ZWdvcnkgdG8gdGhlIGRhdGFzZXQsIG1hdGNoZWQgYnkgS08ncyBiZXR3ZWVuIHRoZSBLT19yZWYgZmlsZSBhbmQgS2VnZ0FudmlvCktlZ2dBbnZpbyRUaWVyX0lJSSA9IEtPX3JlZlttYXRjaChLZWdnQW52aW8kQWNjZXNzaW9uLCBLT19yZWYkS09fQWNjZXNzaW9uKSwgIlRpZXJfSUlJIl0KCiMgQWRkICJUaWVyX0lWIiBjYXRlZ29yeSB0byB0aGUgZGF0YXNldCwgbWF0Y2hlZCBieSBLTydzIGJldHdlZW4gdGhlIEtPX3JlZiBmaWxlIGFuZCBLZWdnQW52aW8KS2VnZ0FudmlvJFRpZXJfSVYgPSBLT19yZWZbbWF0Y2goS2VnZ0FudmlvJEFjY2Vzc2lvbiwgS09fcmVmJEtPX0FjY2Vzc2lvbiksICJUaWVyX0lWIl0KCiMgS2VlcCB0aGUgRnVuY3Rpb24gY2F0ZWdvcnkgZnJvbSB0aGUgS08gUmVmZXJlbmNlIGZpbGUgdG8gcG90ZW50aWFsbHkgZmlsbCBpbiBnYXBzIGluIEtlZ2dBbnZpbyBhbm5vdGF0aW9ucyAobWFueSBLTydzIGxhYmVsZWQgYXMgIk5vbmUiLCBidXQgdGhlIEtPIHNob3VsZCBtYXRjaCBhIGtub3duIGZ1bmN0aW9uIGZyb20gdGhlIHJlZmVyZW5jZSBmaWxlKS4KS2VnZ0Z1bmN0aW9uPC1kYXRhLmZyYW1lKEtlZ2dBbnZpbyRJRCxLZWdnQW52aW8kQWNjZXNzaW9uLEtlZ2dBbnZpbyRTeW1ib2wsS2VnZ0FudmlvJEtPX0Z1bmN0aW9uLEtlZ2dBbnZpbyRUaWVyX0lJLEtlZ2dBbnZpbyRUaWVyX0lJSSxLZWdnQW52aW8kVGllcl9JVikKbmFtZXMoS2VnZ0Z1bmN0aW9uKTwtYygiSUQiLCJLTyIsIlN5bWJvbCIsIkZ1bmN0aW9uIiwiVGllcl9JSSIsIlRpZXJfSUlJIiwiVGllcl9JViIpCiAgCiMgTWVyZ2UgdGhlIEtPLCBTeW1ib2wsIEZ1bmN0aW9uLCBhbmQgYWxsIFRpZXIgY29sdW1ucyBpbnRvIHNpbmdsZSAiQ29tYmluZWQiIGNvbHVtbiBmb3Igc29tZSBkb3duc3RyZWFtIGFuYWx5c2VzCktlZ2dGdW5jdGlvbiRDb21iaW5lZDwtcGFzdGUoS2VnZ0Z1bmN0aW9uJEtPLCAiOiIsIEtlZ2dGdW5jdGlvbiRTeW1ib2wsICI6IiwgS2VnZ0Z1bmN0aW9uJEZ1bmN0aW9uLCAiOiIsIEtlZ2dGdW5jdGlvbiRUaWVyX0lJLCAiOiIsIEtlZ2dGdW5jdGlvbiRUaWVyX0lJSSwgIjoiLCBLZWdnRnVuY3Rpb24kVGllcl9JVikKCiMgS2VlcCBqdXN0ICJJRCIgYW5kICJDb21iaW5lZCIgY29sdW1ucyBmb3IgdXNlIHdpdGggc29tZSBkb3duc3RyZWFtIGFuYWx5c2VzCktlZ2dEYXRhPC1kYXRhLmZyYW1lKEtlZ2dGdW5jdGlvbiRJRCwgS2VnZ0Z1bmN0aW9uJENvbWJpbmVkKQpuYW1lcyhLZWdnRGF0YSk8LWMoIklEIiwiS0VHRyIpCmBgYAoKIyMjIyAzLjIuMy4gS0VHRyBUYXhvbm9teQoKVGhlcmUgYXJlIDMsOTE3LDYxNiB0b3RhbCB1bmlxdWUgRE5BLWJhc2VkIGdlbmVjYWxscyBpbiB0aGUgbWV0YWdlbm9taWMgZGF0YXNldC4gVGhlIEdob3N0S29hbGEgS0VHRyB0YXhvbm9teSBmaWxlICgiKipLZWdnVGF4b25vbXkudHh0KioiKSBjb250YWlucyBhbm5vdGF0aW9ucyBmb3IgMyw5MTIsMjUzIHVuaXF1ZSBETkEtYmFzZWQgZ2VuZWNhbGxzLiAgVGhpcyBpbmRpY2F0ZXMgdGhhdCAqKjk5LjklKiogb2YgdGhlIHRvdGFsIHVuaXF1ZSBETkEtYmFzZWQgZ2VuZWNhbGxzIGNhbiBiZSB0YXhvbm9taWNhbGx5IGFubm90YXRlZC4gSGVyZSwgdGhlIHVuaXF1ZSBnZW5lY2FsbCB0YXhvbm9taWMgYW5ub3RhdGlvbnMgd2lsbCBiZSBtYXRjaGVkIHRvIHRoZSBzYW1lIHVuaXF1ZSBnZW5lY2FsbHMgaW4gdGhlIEROQS1iYXNlZCBtZXRhZ2Vub21pYyBkYXRhc2V0LgoKYGBge3J9CiNJbXBvcnQgS2VnZ1RheG9ub215LnR4dCBmcm9tIEdob3N0S29hbGEKS2VnZ1RheGE8LXJlYWQudGFibGUoIkFubm90YXRpb25zLkRhdGEvS2VnZ1RheG9ub215LnR4dCIsIGhlYWRlciA9IFRSVUUsIGZpbGwgPSBUUlVFKQpuYW1lcyhLZWdnVGF4YSk8LWMoIklEIiwiRG9tYWluIiwiUGh5bHVtIiwiQ2xhc3MiLCJPcmRlciIsIkZhbWlseSIsIkdlbnVzIiwiU3BlY2llcyIpCgojIE1lcmdlIHRoZSB0YXhvbm9taWMgY2xhc3NlcyBpbnRvIGEgc2luZ2xlIGNvbHVtbgpLZWdnVGF4YSRUYXhvbm9teSA8LSBwYXN0ZShLZWdnVGF4YSREb21haW4sICI6IiwgS2VnZ1RheGEkUGh5bHVtLCAiOiIsIEtlZ2dUYXhhJENsYXNzLCAiOiIsIEtlZ2dUYXhhJE9yZGVyLCAiOiIsIEtlZ2dUYXhhJEZhbWlseSwgIjoiLCBLZWdnVGF4YSRHZW51cywgIjoiLCBLZWdnVGF4YSRTcGVjaWVzKQoKIyBOb3cga2VlcCBqdXN0ICJJRCIgYW5kICJUYXhvbm9teSIKS2VnZ1RheGEgPC0gZGF0YS5mcmFtZShLZWdnVGF4YSRJRCwgS2VnZ1RheGEkVGF4b25vbXkpCm5hbWVzKEtlZ2dUYXhhKTwtYygiSUQiLCJUYXhvbm9teSIpCgojIEFkZCAiZ2VuZWNhbGxfIiB0byB0aGUgYmVnaW5uaW5nIG9mIGVhY2ggZ2VuZSBJRCB2YWx1ZSB0byBtYXRjaCB3aXRoIGRvd25zdHJlYW0gYW5hbHlzZXMKS2VnZ1RheGEkSUQ8LXBhc3RlKCJnZW5lY2FsbCIsIEtlZ2dUYXhhJElELCBzZXA9Il8iKQpgYGAKCiMjIDQuIEdlbmUgRmlsdGVyaW5nCgpUaGUgKipGVUxMKiogUk5BIENUUyBkYXRhc2V0IHdhcyBhc3NlbWJsZWQgYXMgYSBzaW5nbGUgZGF0YWZyYW1lIChjb2x1bW5zOiBbMV0gZ2VuZWNhbGwsIFsyXSBsZW5ndGgsIFszLTE0XSBtZXRhdHJhbnNjcmlwdG9tZSBTYW1wbGVzOyByb3dzOiAzLDkxNyw2MTYgdW5pcXVlICJnZW5lY2FsbHMiKSwgYW5kIHN1YnNlcXVlbnRseSBzdWJzYW1wbGVkIGludG8gdHdvIG5ldyBkYXRhZnJhbWVzOgoKMS4gKipjdHNfcm5hX2V4cHJlc3NlZCoqOiByZXRhaW5zIG9ubHkgdGhvc2UgdW5pcXVlIGdlbmVjYWxscyB3aXRoIGEgdmFsdWUgZ3JlYXRlciB0aGFuIHplcm8gaW4gYW55IHNpbmdsZSBzYW1wbGUKICAgICsgSW5kaWNhdGVzIHRoYXQgdGhlc2UgZ2VuZXMgd2VyZSBleHByZXNzZWQgdW5kZXIgYXQgbGVhc3QgT05FIHRyZWF0bWVudCBpbiB0aGUgZXhwZXJpbWVudCAoaS5lLiwgYWN0dWFsIGV4cHJlc3Npb24pCiAgICArIFRoZSBjb3VudCBkYXRhIGZyb20gdGhlc2UgZXhwcmVzc2VkIGdlbmVzIHdpbGwgdW5kZXJnbyBUUE0gbm9ybWFsaXphdGlvbiBmb3Igb25seSB0aG9zZSB1bmlxdWUgZ2VuZWNhbGxzIHRoYXQgY2FuIGJlIGFubm90YXRlZCBmcm9tIEtFR0cKMi4gKipjdHNfcm5hX3plcm8qKjogcmV0YWlucyBvbmx5IHRob3NlIHVuaXF1ZSBnZW5lY2FsbHMgdGhhdCBoYWQgYSB2YWx1ZSBlcXVhbCB0byB6ZXJvIGluICoqQUxMKiogc2FtcGxlcwogICAgKyBJbmRpY2F0ZXMgdGhhdCB0aGVzZSBnZW5lcyB3ZXJlICoqTk9UKiogZXhwcmVzc2VkIGF0IGFueSBwb2ludCBpbiB0aGUgZXhwZXJpbWVudCAoaS5lLiwgcG90ZW50aWFsIGV4cHJlc3Npb24gb25seSkKICAgICsgV2UgcmV0YWluIG9ubHkgdGhvc2UgdW5pcXVlIGdlbmVjYWxscyB0aGF0IGNhbiBiZSBhbm5vdGF0ZWQgZnJvbSBLRUdHIHRvIGxvb2sgYXQgd2hpY2ggZ2VuZXMgd2VyZSBwcmVzZW50IGJ1dCBub3QgZXhwcmVzc2VkIGR1cmluZyB0aGUgZXhwZXJpbWVudAoKIyMjIDQuMS4gRXhwcmVzc2VkIEdlbmVzCgpTdWJzYW1wbGUgdGhlIHVuaXF1ZSBnZW5lY2FsbHMgdGhhdCBoYXZlIGdyZWF0ZXIgdGhhbiB6ZXJvIHJhdyByZWFkIGNvdW50cyAoIkV4cHJlc3NlZCBHZW5lcyIpIGFjcm9zcyBhbGwgc2FtcGxlcy4KCmBgYHtyfQojY3RzX3JuYV9leHByZXNzZWQKY3RzX3JuYV9leHByZXNzZWQgPC0gc3Vic2V0KGN0c19ybmFfYWxsLCBTMTA4Mzc5ID4gMCB8IFMxMDgzODEgPiAwIHwgUzEwODM4MiA+IDAgfCBTMTA4MzgzID4gMCB8IFMxMDgzODUgPiAwIHwgUzEwODM4NiA+IDAgfCBTMTA4Mzg4ID4gMCB8IFMxMDgzOTAgPiAwIHwgUzEwODM5MSA+IDAgfCBTMTA4MzkyID4gMCB8IFMxMDgzOTQgPiAwIHwgUzEwODM5NiA+IDAsIHNlbGVjdD1jKElELExlbmd0aCxTMTA4Mzc5LFMxMDgzODEsUzEwODM4MixTMTA4MzgzLFMxMDgzODUsUzEwODM4NixTMTA4Mzg4LFMxMDgzOTAsUzEwODM5MSxTMTA4MzkyLFMxMDgzOTQsUzEwODM5NikpCmBgYAoKQWRkIGZ1bmN0aW9uYWwgYW5kIHRheG9ub21pYyBhbm5vdGF0aW9ucyB0byBlYWNoIHVuaXF1ZSBnZW5lY2FsbCB3aXRoaW4gdGhlICJFeHByZXNzZWQiIHN1YmRhdGEuCgpgYGB7cn0KIyBFeHByZXNzZWQgRnVuY3Rpb25hbCBhbmQgVGF4b25vbWljIEFubm90YXRpb25zCmN0c19ybmFfZXhwcmVzc2VkJEtFR0cgPSBLZWdnRGF0YVttYXRjaChjdHNfcm5hX2V4cHJlc3NlZCRJRCwgS2VnZ0RhdGEkSUQpLCAiS0VHRyJdCmN0c19ybmFfZXhwcmVzc2VkJFRheG9ub215ID0gS2VnZ1RheGFbbWF0Y2goY3RzX3JuYV9leHByZXNzZWQkSUQsIEtlZ2dUYXhhJElEKSwgIlRheG9ub215Il0KCiMgRXhwcmVzc2VkIEFubm90YXRlZCBHZW5lcwpjdHNfcm5hX2V4cF9hbm5vdGF0ZWQ8LW5hLm9taXQoY3RzX3JuYV9leHByZXNzZWQsIGNvbHM9IktFR0ciKQpgYGAKCiMjIyA0LjIuIE5vbi1FeHByZXNzZWQgR2VuZXMKCkFsc28gc3Vic2FtcGxlIHRoZSB1bmlxdWUgZ2VuZWNhbGxzIHRoYXQgaGF2ZSBvbmx5IHplcm8gcmF3IHJlYWQgY291bnRzICgiTm9uLWV4cHJlc3NlZCBHZW5lcyIpIGFjcm9zcyBhbGwgc2FtcGxlcy4KCmBgYHtyfQojY3RzX3JuYV96ZXJvCmN0c19ybmFfemVybyA8LSBzdWJzZXQoY3RzX3JuYV9hbGwsIFMxMDgzNzkgPT0gMCAmIFMxMDgzODEgPT0gMCAmIFMxMDgzODIgPT0gMCAmIFMxMDgzODMgPT0gMCAmIFMxMDgzODUgPT0gMCAmIFMxMDgzODYgPT0gMCAmIFMxMDgzODggPT0gMCAmIFMxMDgzOTAgPT0gMCAmIFMxMDgzOTEgPT0gMCAmIFMxMDgzOTIgPT0gMCAmIFMxMDgzOTQgPT0gMCAmIFMxMDgzOTYgPT0gMCwgc2VsZWN0PWMoSUQsTGVuZ3RoLFMxMDgzNzksUzEwODM4MSxTMTA4MzgyLFMxMDgzODMsUzEwODM4NSxTMTA4Mzg2LFMxMDgzODgsUzEwODM5MCxTMTA4MzkxLFMxMDgzOTIsUzEwODM5NCxTMTA4Mzk2KSkKYGBgCgpBZGQgZnVuY3Rpb25hbCBhbmQgdGF4b25vbWljIGFubm90YXRpb25zIHRvIGVhY2ggdW5pcXVlIGdlbmVjYWxsIHdpdGhpbiB0aGUgIk5vbi1FeHByZXNzZWQiIHN1YmRhdGEuCgpgYGB7cn0KIyBOb24tRXhwcmVzc2VkIEZ1bmN0aW9uYWwgYW5kIFRheG9ub21pYyBBbm5vdGF0aW9ucwpjdHNfcm5hX3plcm8kS0VHRyA9IEtlZ2dEYXRhW21hdGNoKGN0c19ybmFfemVybyRJRCwgS2VnZ0RhdGEkSUQpLCAiS0VHRyJdCmN0c19ybmFfemVybyRUYXhvbm9teSA9IEtlZ2dUYXhhW21hdGNoKGN0c19ybmFfemVybyRJRCwgS2VnZ1RheGEkSUQpLCAiVGF4b25vbXkiXQoKIyBOb24tRXhwcmVzc2VkIEFubm90YXRlZCBHZW5lcwpjdHNfcm5hX3plcm9fYW5ub3RhdGVkPC1uYS5vbWl0KGN0c19ybmFfemVybywgY29scz0iS0VHRyIpCmBgYAoKIyMjIDQuMy4gRXhwcmVzc2VkIEFubm90YXRlZCBHZW5lcwoKKioqRnJvbSB0aGlzIHBvaW50KioqLCB3ZSAgcmV0YWluIG9ubHkgdGhvc2UgZ2VuZWNhbGxzIHRoYXQgd2VyZSBleHByZXNzZWQgKioqYW5kKioqIGhhdmUgYSBLRUdHIGZ1bmN0aW9uYWwgYW5ub3RhdGlvbi4gIEFsbCByZW1haW5pbmcgZ2VuZWNhbGxzICg2NC41JSBvZiB0b3RhbCBkYXRhc2V0KSBhcmUgZXhlbXB0IGZyb20gZG93bnN0cmVhbSBhbmFseXNlcy4gIFN0YXJ0IGJ5IHNlcGFyYXRpbmcgdGhlIEtFR0cgY2F0ZWdvcmllcyBpbnRvIHVuaXF1ZSBjb2x1bW5zLiBSZW1vdmUgYW55IGdlbmVjYWxsIHdob3NlIHN5bWJvbCBhbm5vdGF0aW9uIGlzICJOb25lIi4gRnVydGhlciByZW1vdmUgYW55IGdlbmVjYWxsIGFubm90YXRlZCBhcyBUaWVyIElJICJPcmdhbmlzbWFsIFN5c3RlbXMiIG9yICJIdW1hbiBEaXNlYXNlcyIuCgpgYGB7cn0KIyBTZXBhcmF0ZSAiS0VHRyIgY29sdW1uIGludG8gIktPIiwgIlN5bWJvbCIsICJGdW5jdGlvbiIsICJUaWVyX0lJIiwgIlRpZXJfSUlJIiwgYW5kICJUaWVyX0lWIiBjb2x1bW5zCmN0c19ybmFfZXhwX2Fubm90YXRlZDwtY3RzX3JuYV9leHBfYW5ub3RhdGVkICU+JSBzZXBhcmF0ZShLRUdHLCBjKCJLTyIsIlN5bWJvbCIsIkZ1bmN0aW9uIiwiVGllcl9JSSIsIlRpZXJfSUlJIiwiVGllcl9JViIpLCAiOiAiLCBleHRyYT0ibWVyZ2UiKQoKIyBSZW1vdmUgS08ncyB3aXRoICJOb25lIiBhcyB0aGUgIlN5bWJvbCIgYW5ub3RhdGlvbgpjdHNfcm5hX2V4cF9hbm5vdGF0ZWQ8LWN0c19ybmFfZXhwX2Fubm90YXRlZFshZ3JlcGwoIk5vbmUiLCBjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkU3ltYm9sKSxdCgojIFJlbW92ZSBLTydzIHdpdGggVGllciBJSSBjYXRlZ29yeSAiT3JnYW5pc21hbCBTeXN0ZW1zIgpjdHNfcm5hX2V4cF9hbm5vdGF0ZWQ8LWN0c19ybmFfZXhwX2Fubm90YXRlZFshZ3JlcGwoIk9yZ2FuaXNtYWwgU3lzdGVtcyAiLCBjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkVGllcl9JSSksXQoKIyBSZW1vdmUgS08ncyB3aXRoIFRpZXIgSUkgY2F0ZWdvcnkgIkh1bWFuIERpc2Vhc2VzIgpjdHNfcm5hX2V4cF9hbm5vdGF0ZWQ8LWN0c19ybmFfZXhwX2Fubm90YXRlZFshZ3JlcGwoIkh1bWFuIERpc2Vhc2VzICIsIGN0c19ybmFfZXhwX2Fubm90YXRlZCRUaWVyX0lJKSxdCmBgYAoKU2VwYXJhdGUgdGhlIFRheG9ub215IGNhdGVnb3JpZXMgaW50byB1bmlxdWUgY29sdW1ucy4gUmVtb3ZlIGFueSBnZW5lY2FsbCB3aG9zZSB0YXhvbm9teSBpcyBvdXRzaWRlIG9mICJBcmNoYWVhIiwgIkJhY3RlcmlhIiwgb3IgIkZ1bmdpIi4KCmBgYHtyfQojIFNlcGFyYXRlICJUYXhvbm9teSIgY29sdW1uIGludG8gIktpbmdkb20iLCAiUGh5bHVtIiwgIkNsYXNzIiwgIk9yZGVyIiwgIkZhbWlseSIsICJHZW51cyIsIGFuZCAiU3BlY2llcyIgY29sdW1ucwpjdHNfcm5hX2V4cF9hbm5vdGF0ZWQ8LWN0c19ybmFfZXhwX2Fubm90YXRlZCAlPiUgc2VwYXJhdGUoVGF4b25vbXksIGMoIktpbmdkb20iLCJQaHlsdW0iLCJDbGFzcyIsIk9yZGVyIiwiRmFtaWx5IiwiR2VudXMiLCJTcGVjaWVzIiksICI6ICIsIGV4dHJhPSJtZXJnZSIpCgojIFJlbW92ZSBLTydzIHdpdGggImFnIiBhcyB0aGUgIktpbmdkb20iIGFubm90YXRpb24KY3RzX3JuYV9leHBfYW5ub3RhdGVkPC1jdHNfcm5hX2V4cF9hbm5vdGF0ZWRbIWdyZXBsKCJhZyIsIGN0c19ybmFfZXhwX2Fubm90YXRlZCRLaW5nZG9tKSxdCgojIFJlbW92ZSBLTydzIHdpdGggIkFuaW1hbHMiIGFzIHRoZSAiS2luZ2RvbSIgYW5ub3RhdGlvbgpjdHNfcm5hX2V4cF9hbm5vdGF0ZWQ8LWN0c19ybmFfZXhwX2Fubm90YXRlZFshZ3JlcGwoIkFuaW1hbHMiLCBjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkS2luZ2RvbSksXQoKIyBSZW1vdmUgS08ncyB3aXRoICJQbGFudHMiIGFzIHRoZSAiS2luZ2RvbSIgYW5ub3RhdGlvbgpjdHNfcm5hX2V4cF9hbm5vdGF0ZWQ8LWN0c19ybmFfZXhwX2Fubm90YXRlZFshZ3JlcGwoIlBsYW50cyIsIGN0c19ybmFfZXhwX2Fubm90YXRlZCRLaW5nZG9tKSxdCgojIFJlbW92ZSBLTydzIHdpdGggIlByb3Rpc3RzIiBhcyB0aGUgIktpbmdkb20iIGFubm90YXRpb24KY3RzX3JuYV9leHBfYW5ub3RhdGVkPC1jdHNfcm5hX2V4cF9hbm5vdGF0ZWRbIWdyZXBsKCJQcm90aXN0cyIsIGN0c19ybmFfZXhwX2Fubm90YXRlZCRLaW5nZG9tKSxdCgojUmUtbWVyZ2UgdGhlIFRheG9ub215IGNvbHVtbnMgZm9yIGRvd25zdHJlYW0gYW5hbHlzaXMKY3RzX3JuYV9leHBfYW5ub3RhdGVkJFRheG9ub215IDwtIHBhc3RlKGN0c19ybmFfZXhwX2Fubm90YXRlZCRLaW5nZG9tLCAiOiIsIGN0c19ybmFfZXhwX2Fubm90YXRlZCRQaHlsdW0sICI6IiwgY3RzX3JuYV9leHBfYW5ub3RhdGVkJENsYXNzLCAiOiIsIGN0c19ybmFfZXhwX2Fubm90YXRlZCRPcmRlciwgIjoiLCBjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkRmFtaWx5LCAiOiIsIGN0c19ybmFfZXhwX2Fubm90YXRlZCRHZW51cywgIjoiLCBjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkU3BlY2llcykKYGBgCgojIyA1LiBHZW5lIE5vcm1hbGl6YXRpb24KCioqVFBNIE5vcm1hbGl6YXRpb246KiogQ29udmVydHMgcmF3IGdlbmUgY291bnRzIHRvICoqKlRyYW5zY3JpcHRzIHBlciBNaWxsaW9uKioqLiAgVFBNIG5vcm1hbGl6YXRpb24gaXMgYmFzZWQgb24gbWV0aG9kcyBkZXNjcmliZWQgYnkgW1dhZ25lciBldCBhbC4gMjAxMl0oaHR0cHM6Ly9saW5rLnNwcmluZ2VyLmNvbS9hcnRpY2xlLzEwLjEwMDcvczEyMDY0LTAxMi0wMTYyLTMpIHRvIG5vcm1hbGl6ZSB0cmFuc2NyaXB0IGFidW5kYW5jZSBkYXRhIGFuZCByZXF1aXJlcyB0aGUgZm9sbG93aW5nIHR3byBzdGVwczoKCjEuICoqQ2FsY3VsYXRlIFRnKio6IFRnID0gUmVhZCBDb3VudCB4IEF2ZXJhZ2UgUmVhZCBMZW5ndGggIC8gR2VuZSBMZW5ndGgKICAgICsgKioqUmVhZCBDb3VudCoqKjogKm51bWJlciBvZiByZWFkcyBtYXBwZWQgdG8gZWFjaCB1bmlxdWUgZ2VuZWNhbGwqCiAgICArICoqKkF2ZXJhZ2UgUmVhZCBMZW5ndGgqKio6ICpBdmVyYWdlIHJlYWQgbGVuZ3RoIChiZXR3ZWVuIDEyMC0xNDAgYnApIHdpdGhpbiBlYWNoIHNhbXBsZSBmcm9tIHNlcXVlbmNlcyB0aGF0IHBhc3NlZCBRQyoKICAgICsgKioqR2VuZSBMZW5ndGgqKio6ICpMZW5ndGggb2YgZWFjaCB1bmlxdWUgZ2VuZWNhbGwqCjIuICoqQ29udmVydCBUZyBpbnRvIFRQTSBieSBzYW1wbGUqKjogVFBNID0gVGcgeCAxZSswNiAvIHN1bShUZykKICAgICsgKioqVGhlIHN1bSBvZiBUUE0gdmFsdWVzIGluIGVhY2ggc2FtcGxlIHdpbGwgZXF1YWwgMSwwMDAsMDAwKioqCgoqKkF0IHRoaXMgcG9pbnQsIHdlIG1vdmUgZm9yd2FyZCB3aXRoIG9ubHkgdGhlIGV4cHJlc3NlZCBhbm5vdGF0ZWQgZ2VuZWNhbGwgZGF0YSBmb3IgZG93bnN0cmVhbSBzdGF0aXN0aWNhbCBhbmFseXNlcy4qKgoKIyMjIDUuMS4gQ2FsY3VsYXRlIFRnIFZhbHVlcwoKQ2FsY3VsYXRlIFRnIHZhbHVlcyBieSBtdWx0aXBseWluZyB0aGUgcmVhZCBjb3VudCBvZiBlYWNoIGdlbmVjYWxsIGJ5IHRoZSBhdmVyYWdlIHJlYWQgbGVuZ3RoIHdpdGhpbiBlYWNoIHNhbXBsZSwgdGhlbiBkaXZpZGUgYnkgdGhlIGdlbmUgbGVuZ3RoIG9mIGVhY2ggZ2VuZWNhbGwuCgpgYGB7cn0KY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzNzlfVGc8LShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM3OSAqIDExOCkgLyBjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkTGVuZ3RoCmN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4MzgxX1RnPC0oY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzODEgKiAxMjkpIC8gY3RzX3JuYV9leHBfYW5ub3RhdGVkJExlbmd0aApjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM4Ml9UZzwtKGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4MzgyICogMTI3KSAvIGN0c19ybmFfZXhwX2Fubm90YXRlZCRMZW5ndGgKY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzODNfVGc8LShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM4MyAqIDEyNykgLyBjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkTGVuZ3RoCmN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4Mzg1X1RnPC0oY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzODUgKiAxMjkpIC8gY3RzX3JuYV9leHBfYW5ub3RhdGVkJExlbmd0aApjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM4Nl9UZzwtKGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4Mzg2ICogMTMwKSAvIGN0c19ybmFfZXhwX2Fubm90YXRlZCRMZW5ndGgKY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzODhfVGc8LShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM4OCAqIDEzMCkgLyBjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkTGVuZ3RoCmN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4MzkwX1RnPC0oY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzOTAgKiAxMjkpIC8gY3RzX3JuYV9leHBfYW5ub3RhdGVkJExlbmd0aApjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM5MV9UZzwtKGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4MzkxICogMTI1KSAvIGN0c19ybmFfZXhwX2Fubm90YXRlZCRMZW5ndGgKY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzOTJfVGc8LShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM5MiAqIDEyOCkgLyBjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkTGVuZ3RoCmN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4Mzk0X1RnPC0oY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzOTQgKiAxMjcpIC8gY3RzX3JuYV9leHBfYW5ub3RhdGVkJExlbmd0aApjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM5Nl9UZzwtKGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4Mzk2ICogMTI5KSAvIGN0c19ybmFfZXhwX2Fubm90YXRlZCRMZW5ndGgKYGBgCgojIyMgNS4yLiBDYWxjdWxhdGUgVFBNIFZhbHVlcwoKTm93IG11bHRpcGxlIGVhY2ggVGcgdmFsdWUgd2l0aGluIGEgc2FtcGxlIGJ5IDFlKzA2IGFuZCBkaXZpZGUgYnkgdGhlIHN1bSBvZiBUZyB2YWx1ZXMgZm9yIHRoYXQgc2FtcGxlIHRvIGRldGVybWluZSBUUE0uCgpgYGB7cn0KY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzNzlfVFBNPC0oY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzNzlfVGcgKiAxMDAwMDAwKSAvIHN1bShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM3OV9UZyxuYS5ybT1UUlVFKQpjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM4MV9UUE08LShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM4MV9UZyAqIDEwMDAwMDApIC8gc3VtKGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4MzgxX1RnLG5hLnJtPVRSVUUpCmN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4MzgyX1RQTTwtKGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4MzgyX1RnICogMTAwMDAwMCkgLyBzdW0oY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzODJfVGcsbmEucm09VFJVRSkKY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzODNfVFBNPC0oY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzODNfVGcgKiAxMDAwMDAwKSAvIHN1bShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM4M19UZyxuYS5ybT1UUlVFKQpjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM4NV9UUE08LShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM4NV9UZyAqIDEwMDAwMDApIC8gc3VtKGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4Mzg1X1RnLG5hLnJtPVRSVUUpCmN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4Mzg2X1RQTTwtKGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4Mzg2X1RnICogMTAwMDAwMCkgLyBzdW0oY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzODZfVGcsbmEucm09VFJVRSkKY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzODhfVFBNPC0oY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzODhfVGcgKiAxMDAwMDAwKSAvIHN1bShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM4OF9UZyxuYS5ybT1UUlVFKQpjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM5MF9UUE08LShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM5MF9UZyAqIDEwMDAwMDApIC8gc3VtKGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4MzkwX1RnLG5hLnJtPVRSVUUpCmN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4MzkxX1RQTTwtKGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4MzkxX1RnICogMTAwMDAwMCkgLyBzdW0oY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzOTFfVGcsbmEucm09VFJVRSkKY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzOTJfVFBNPC0oY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzOTJfVGcgKiAxMDAwMDAwKSAvIHN1bShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM5Ml9UZyxuYS5ybT1UUlVFKQpjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM5NF9UUE08LShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM5NF9UZyAqIDEwMDAwMDApIC8gc3VtKGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4Mzk0X1RnLG5hLnJtPVRSVUUpCmN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4Mzk2X1RQTTwtKGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4Mzk2X1RnICogMTAwMDAwMCkgLyBzdW0oY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzOTZfVGcsbmEucm09VFJVRSkKYGBgCgojIyMgNS4zLiBDcmVhdGUgVFBNIERhdGFmcmFtZQoKQ3JlYXRlIHRoZSBUUE0gZGF0YWZyYW1lIGJ5IHN1YnNldHRpbmcgY29sdW1ucyBvZiBpbnRlcmVzdCBmcm9tIHRoZSBjdHNfZXhwX2Fubm90YXRlZCBkYXRhZnJhbWUuCgpgYGB7cn0KdHBtX2FsbDwtZGF0YS5mcmFtZShjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkSUQsY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzNzlfVFBNLGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4MzgxX1RQTSxjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM4Ml9UUE0sY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzODNfVFBNLGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4Mzg1X1RQTSxjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM4Nl9UUE0sY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzODhfVFBNLGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4MzkwX1RQTSxjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM5MV9UUE0sY3RzX3JuYV9leHBfYW5ub3RhdGVkJFMxMDgzOTJfVFBNLGN0c19ybmFfZXhwX2Fubm90YXRlZCRTMTA4Mzk0X1RQTSxjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkUzEwODM5Nl9UUE0sY3RzX3JuYV9leHBfYW5ub3RhdGVkJEtPLGN0c19ybmFfZXhwX2Fubm90YXRlZCRTeW1ib2wsY3RzX3JuYV9leHBfYW5ub3RhdGVkJEZ1bmN0aW9uLGN0c19ybmFfZXhwX2Fubm90YXRlZCRUaWVyX0lJLGN0c19ybmFfZXhwX2Fubm90YXRlZCRUaWVyX0lJSSxjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkVGllcl9JVixjdHNfcm5hX2V4cF9hbm5vdGF0ZWQkVGF4b25vbXkpCgpuYW1lcyh0cG1fYWxsKTwtYygiSUQiLCJTMTA4Mzc5X1RQTSIsIlMxMDgzODFfVFBNIiwiUzEwODM4Ml9UUE0iLCJTMTA4MzgzX1RQTSIsIlMxMDgzODVfVFBNIiwiUzEwODM4Nl9UUE0iLCJTMTA4Mzg4X1RQTSIsIlMxMDgzOTBfVFBNIiwiUzEwODM5MV9UUE0iLCJTMTA4MzkyX1RQTSIsIlMxMDgzOTRfVFBNIiwiUzEwODM5Nl9UUE0iLCJLTyIsIlN5bWJvbCIsIkZ1bmN0aW9uIiwiVGllcl9JSSIsIlRpZXJfSUlJIiwiVGllcl9JViIsIlRheG9ub215IikKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQp3cml0ZS5jc3YodHBtX2FsbCwgJ05vcm0uUmVzdWx0cy90cG0uYWxsLmRhdGEuY3N2JykKYGBgCgojIyA2LiBHZW5lIERhdGFzZXRzCgpBdCB0aGlzIHBvaW50LCB0aGUgKipGVUxMKiogUk5BIGRhdGFzZXQgKGBjdHNfcm5hX2FsbGApIHdhcyBzZXBhcmF0ZWQgaW50byAqKkV4cHJlc3NlZCoqIChgY3RzX3JuYV9leHByZXNzZWRgKSBhbmQgKipOb24tRXhwcmVzc2VkKiogKGBjdHNfcm5hX3plcm9gKSBzdWJkYXRhLiBUaGVuIHRoZSBmdW5jdGlvbmFsIGFuZCB0YXhvbm9taWMgYW5ub3RhdGlvbnMgd2VyZSBpbXBvcnRlZCBhbmQgdGhlICoqRXhwcmVzc2VkKiogYW5kICoqTm9uLUV4cHJlc3NlZCoqIHN1YmRhdGEgd2VyZSBmdXJ0aGVyIHNlcGFyYXRlZCBpbnRvICoqRXhwcmVzc2VkIEFubm90YXRlZCoqIChgY3RzX3JuYV9leHBfYW5ub3RhdGVkYCkgYW5kICoqTm9uLUV4cHJlc3NlZCBBbm5vdGF0ZWQqKiAoYGN0c19ybmFfemVyb19hbm5vdGF0ZWRgKSBzdWJkYXRhLiBUaGUgKipOb24tRXhwcmVzc2VkIEFubm90YXRlZCoqIHN1YmRhdGEgd2lsbCBiZSBzdW1tYXJpemVkIGFzIGEgbGlzdCBvZiBnZW5lcyB0aGF0IHdlcmUgTk9UIGV4cHJlc3NlZCBhdCBhbnkgcG9pbnQgZHVyaW5nIG91ciBleHBlcmltZW50LiBUaGVuIHdlIG1vdmVkIGZvcndhcmQgd2l0aCBvbmx5IHRoZSAqKkV4cHJlc3NlZCBBbm5vdGF0ZWQqKiBzdWJkYXRhIGFuZCBub3JtYWxpemVkIHRoZSByYXcgcmVhZCBjb3VudHMgdXNpbmcgdGhlICoqKlRyYW5zY3JpcHRzIHBlciBNaWxsaW9uKioqIChUUE0pIG5vcm1hbGl6YXRpb24gcGFyYW1ldGVycy4KCgpOb3csIHdlIGZ1cnRoZXIgc2VwYXJhdGUgdGhlIG5vcm1hbGl6ZWQgZXhwcmVzc2VkIGFubm90YXRlZCBzdWJkYXRhIGludG8gdGhlaXIgZXhwZXJpbWVudGFsIHRyZWF0bWVudHMgaW4gb3JkZXIgdG8gYW5hbHl6ZSBzdGF0aXN0aWNhbCBkaWZmZXJlbmNlcyBpbiBnZW5lIGV4cHJlc3Npb24gcGF0dGVybnMgYW5kIGRpZmZlcmVudGlhbCBnZW5lIGV4cHJlc3Npb24gYmV0d2VlbiBleHBlcmltZW50YWwgdHJlYXRtZW50cy4gUGFpcndpc2Ugc2ltaWxhcml0aWVzIGFtb25nIG1ldGF0cmFuc2NyaXB0b21lcyB3aWxsIGJlIGNhbGN1bGF0ZWQgdXNpbmcgQnJheS1DdXJ0aXMgc2ltaWxhcml0eSB2YWx1ZXMsIHdpdGggZGlmZmVyZW5jZXMgYmV0d2VlbiB0cmVhdG1lbnRzIGFzc2Vzc2VkIHZpYSBQRVJNQU5PVkEuIERpZmZlcmVudGlhbCBnZW5lIGV4cHJlc2lzb24gd2lsbCBiZSBjYWxjdWxhdGVkIHVzaW5nIHRoZSBgRWRnZVJgIHBhY2thZ2UuCgojIyMgNi4xLiBUdXNzb2NrIEdlbmUgRGF0YQoKU2VwYXJhdGUgdGhlICoqVHVzc29jayoqIHNhbXBsZXMgaW50byB0aGVpciBvd24gZGF0YXNldC4gICoqKktlZXAgb25seSB0aG9zZSB1bmlxdWUgZ2VuZWNhbGxzIHRoYXQgaGF2ZSBleHByZXNzaW9uIGluIGF0IGxlYXN0IDEgVHVzcyBzYW1wbGUuKioqCgpgYGB7cn0KIyBTdWJzZXQgdGhlIFRVU1MgVFBNIE5vcm1hbGl6ZWQgRXhwcmVzc2VkIEFubm90YXRlZCBzdWJkYXRhCnRwbV90dXNzIDwtIHN1YnNldCh0cG1fYWxsLCBzZWxlY3Q9YyhJRCxTMTA4MzgyX1RQTSxTMTA4MzgzX1RQTSxTMTA4MzkxX1RQTSxTMTA4MzkyX1RQTSxTMTA4Mzk0X1RQTSxTMTA4Mzk2X1RQTSxLTyxTeW1ib2wsRnVuY3Rpb24sVGllcl9JSSxUaWVyX0lJSSxUaWVyX0lWLCBUYXhvbm9teSkpCgpuYW1lcyh0cG1fdHVzcyk8LWMoIklEIiwiVHVzczFfVDAiLCJUdXNzMl9UMCIsIlR1c3MxX1Q0IiwiVHVzczJfVDQiLCJUdXNzMV9UMjQiLCJUdXNzM19UMjQiLCJLTyIsIlN5bWJvbCIsIkZ1bmN0aW9uIiwiVGllcl9JSSIsIlRpZXJfSUlJIiwiVGllcl9JViIsIlRheG9ub215IikKCiMgUmVtb3ZlIGFueSBub24tZXhwcmVzc2VkIGdlbmVzIGZyb20gdGhlIFR1c3NvY2sgc2FtcGxlcwp0cG1fdHVzc19leHByZXNzZWQgPC0gc3Vic2V0KHRwbV90dXNzLCBUdXNzMV9UMCA+IDAgfCBUdXNzMl9UMCA+IDAgfCBUdXNzMV9UNCA+IDAgfCBUdXNzMl9UNCA+IDAgfCBUdXNzMV9UMjQgPiAwIHwgVHVzczNfVDI0ID4gMCwgc2VsZWN0PWMoSUQsVHVzczFfVDAsVHVzczJfVDAsVHVzczFfVDQsVHVzczJfVDQsVHVzczFfVDI0LFR1c3MzX1QyNCxLTyxTeW1ib2wsRnVuY3Rpb24sVGllcl9JSSxUaWVyX0lJSSxUaWVyX0lWLFRheG9ub215KSkKYGBgCgojIyMgNi4yLiBXZXQgU2VkZ2UgR2VuZSBEYXRhCgpTZXBhcmF0ZSB0aGUgKipXZXQgU2VkZ2UqKiBzYW1wbGVzIGludG8gdGhlaXIgb3duIGRhdGFzZXQuICAqKipLZWVwIG9ubHkgdGhvc2UgdW5pcXVlIGdlbmVjYWxscyB0aGF0IGhhdmUgZXhwcmVzc2lvbiBpbiBhdCBsZWFzdCAxIFdTIHNhbXBsZS4qKioKCmBgYHtyfQojIFN1YnNldCB0aGUgV1MgVFBNIE5vcm1hbGl6ZWQgRXhwcmVzc2VkIEFubm90YXRlZCBzdWJkYXRhICh0aGF0J3MgYSBtb3V0aGZ1bC4uLikKdHBtX3dzIDwtIHN1YnNldCh0cG1fYWxsLCBzZWxlY3Q9YyhJRCxTMTA4Mzc5X1RQTSxTMTA4MzgxX1RQTSxTMTA4Mzg1X1RQTSxTMTA4Mzg2X1RQTSxTMTA4Mzg4X1RQTSxTMTA4MzkwX1RQTSxLTyxTeW1ib2wsRnVuY3Rpb24sVGllcl9JSSxUaWVyX0lJSSxUaWVyX0lWLFRheG9ub215KSkKbmFtZXModHBtX3dzKTwtYygiSUQiLCJXUzFfVDAiLCJXUzNfVDAiLCJXUzFfVDQiLCJXUzJfVDQiLCJXUzFfVDI0IiwiV1MzX1QyNCIsIktPIiwiU3ltYm9sIiwiRnVuY3Rpb24iLCJUaWVyX0lJIiwiVGllcl9JSUkiLCJUaWVyX0lWIiwiVGF4b25vbXkiKQoKIyBSZW1vdmUgYW55IG5vbi1leHByZXNzZWQgZ2VuZXMgZnJvbSB0aGUgV2V0IFNlZGdlIHNhbXBsZXMKdHBtX3dzX2V4cHJlc3NlZCA8LSBzdWJzZXQodHBtX3dzLCBXUzFfVDAgPiAwIHwgV1MzX1QwID4gMCB8IFdTMV9UNCA+IDAgfCBXUzJfVDQgPiAwIHwgV1MxX1QyNCA+IDAgfCBXUzNfVDI0ID4gMCwgc2VsZWN0PWMoSUQsV1MxX1QwLFdTM19UMCxXUzFfVDQsV1MyX1Q0LFdTMV9UMjQsV1MzX1QyNCxLTyxTeW1ib2wsRnVuY3Rpb24sVGllcl9JSSxUaWVyX0lJSSxUaWVyX0lWLFRheG9ub215KSkKYGBgCgojIyMgNi4zLiBBbGwgR2VuZSBEYXRhCgpXZSBhbHNvIG5lZWQgdGhlIGZ1bGwgVFVTUyBhbmQgV1MgRXhwcmVzc2VkIEFubm90YXRlZCBkYXRhIHRvZ2V0aGVyIHRvIG1ha2UgY29tcGFyaXNvbnMgYmV0d2VlbiBlY29zeXN0ZW1zIHdpdGhpbiBlYWNoIHNhbXBsaW5nIHRpbWVwb2ludC4gIFJlZm9ybWF0IHRoZSBgdHBtX2FsbGAgdGFibGUgYW5kIHNlcGFyYXRlIHRoZSAiS0VHRyIgY29sdW1uIGludG8gYWxsIG9mIGl0cyBmdW5jdGlvbmFsIGNhdGVnb3JpZXMgZm9yIGRvd25zdHJlYW0gdXNlLgoKYGBge3J9CiMgTWFrZSBhIG5ldyBvYmplY3QgZm9yIHRoZSB0cG1fYWxsIHRhYmxlIHNvIHRoYXQgeW91IGRvbid0IG92ZXJ3cml0ZSB0aGUgb3JpZ2luYWwKdHBtX2FsbF9leHBfYW5uPC10cG1fYWxsCgpuYW1lcyh0cG1fYWxsX2V4cF9hbm4pPC1jKCJJRCIsIlMxMDgzNzkiLCJTMTA4MzgxIiwiUzEwODM4MiIsIlMxMDgzODMiLCJTMTA4Mzg1IiwiUzEwODM4NiIsIlMxMDgzODgiLCJTMTA4MzkwIiwiUzEwODM5MSIsIlMxMDgzOTIiLCJTMTA4Mzk0IiwiUzEwODM5NiIsIktPIiwiU3ltYm9sIiwiRnVuY3Rpb24iLCJUaWVyX0lJIiwiVGllcl9JSUkiLCJUaWVyX0lWIiwiVGF4b25vbXkiKQpgYGAKCiMjIDcuIEdlbmUgQW5hbHlzaXMKCiMjIyA3LjEuIFRheG9ub215CkhlcmUsIHdlIGRldGVybWluZSB0aGUgdGF4b25vbWljIGNvbXBvc2l0aW9uIG9mIHRoZSBtaWNyb2JpYWwgY29tbXVuaXR5IGJ5IGFuYWx5emluZyB0aGUgcmVsYXRpdmUgYWJ1bmRhbmNlIG9mIGdlbmUgZXhwcmVzc2lvbiBmb3IgS0VHRyB0aWVyIElWICJSaWJvc29tZXMiICgwMzAxMCBSaWJvc29tZSBQQVRIOiBrbzAzMDEwKS4gIFdpdGhpbiB0aGUgIlJpYm9zb21lIiBjYXRlZ29yeSwgdGhlcmUgYXJlIGFubm90YXRpb25zIGZvciAic21hbGwgc3VidW5pdCByaWJvc29tYWwgcHJvdGVpbiIgKHNzdSkgYW5kICJsYXJnZSBzdWJ1bml0IHJpYm9zb21hbCBwcm90ZWluIiAobHN1KS4gRm9yIEJhY3RlcmlhIGFuZCBBcmNoYWVhLCB3ZSB1c2Ugb24gdGhlIHNzdSBhbm5vdGF0aW9ucyAoc2ltaWxhciB0byAxNlMgc3N1IHJSTkEgdGFyZ2V0ZWQgYW5hbHlzaXMpLiBGb3IgRnVuZ2ksIHdlIHVzZSBib3RoIHRoZSBzc3UgKDE4UyBzc3UgclJOQSkgYW5kIGxzdSAoMjhTIGxzdSByUk5BKSBhbm5vdGF0aW9ucy4KCiMjIyMgNy4xLjEuIEJhY3RlcmlhL0FyY2hhZWEgU1NVClRoZSBmaXJzdCBhbmFseXNpcyBwdWxscyBvdXQgYWxsIGdlbmUgZXhwcmVzc2lvbiBmb3IgIlJpYm9zb21lcyIgYW5kIHJlbW92ZXMgbHN1IGFubm90YXRpb25zIHN1Y2ggdGhhdCBvbmx5IHNzdSBhbm5vdGF0aW9ucyBhcmUgdXNlZCBmb3IgZGV0ZXJtaW5pbmcgcmVsYXRpdmUgZXhwcmVzc2lvbiBvZiBCYWN0ZXJpYSBhbmQgQXJjaGFlYSBhdCBlYWNoIHNhbXBsaW5nIHRpbWUgcG9pbnQgaW4gYm90aCB0dXNzb2NrIGFuZCB3ZXQgc2VkZ2UgdHVuZHJhLgoKYGBge3J9CiMgU3Vic2V0IGFsbCB1bmlxdWUgZ2VuZWNhbGxzIHdob3NlIGFubm90YXRpb24gbWF0Y2hlcyAiUmlib3NvbWVzIgp0YXhhX3JpYm9fYWxsPC0gdHBtX2FsbF9leHBfYW5uWyB3aGljaCh0cG1fYWxsX2V4cF9hbm4kVGllcl9JVj09JzAzMDEwIFJpYm9zb21lIFtQQVRIOmtvMDMwMTBdJyksXQpgYGAKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CiMgTWFrZSBjb3B5IG9mIFJpYm9zb21lIGRhdGFzZXQgdG8gbWFuaXB1bGF0ZQp0YXhhX3JpYm9fc3N1PC10YXhhX3JpYm9fYWxsCgojIFJlbW92ZSAibGFyZ2Ugc3VidW5pdCByaWJvc29tYWwgcHJvdGVpbiIgZnJvbSBkYXRhc2V0CnRheGFfcmlib19zc3U8LXRheGFfcmlib19zc3VbIWdyZXBsKCJsYXJnZSBzdWJ1bml0IHJpYm9zb21hbCBwcm90ZWluIiwgdGF4YV9yaWJvX3NzdSRGdW5jdGlvbiksXQoKIyBXcml0ZSBkYXRhc2V0IHRvIGZpbGUKd3JpdGUuY3N2KHRheGFfcmlib19zc3UsICdSaWJvLlJlc3VsdHMvQUxQSEEudGF4YS5ybmEuc3N1LmNzdicpCgojIFJlbW92ZSAiRnVuZ2kiIGZyb20gZGF0YXNldAp0YXhhX3JpYm9fc3N1PC10YXhhX3JpYm9fc3N1WyFncmVwbCgiRnVuZ2kiLCB0YXhhX3JpYm9fc3N1JFRheG9ub215KSxdCgojIFNlcGFyYXRlICJUYXhvbm9teSIgY29sdW1uIGludG8gYWxsIHN1YmRpdmlzaW9ucwp0YXhhX3JpYm9fc3N1PC10YXhhX3JpYm9fc3N1ICU+JSBzZXBhcmF0ZShUYXhvbm9teSwgYygiS2luZ2RvbSIsIlBoeWx1bSIsIkNsYXNzIiwiT3JkZXIiLCJGYW1pbHkiLCJHZW51cyIsIlNwZWNpZXMiKSwgIjogIiwgZXh0cmE9Im1lcmdlIikKCiMgS2VlcCAiS2luZ2RvbSIgYW5kICJQaHlsdW0iCnRheGFfcmlib19zc3UgPC0gZGF0YS5mcmFtZSh0YXhhX3JpYm9fc3N1JEtpbmdkb20sdGF4YV9yaWJvX3NzdSRQaHlsdW0sIHRheGFfcmlib19zc3UkUzEwODM3OSwgdGF4YV9yaWJvX3NzdSRTMTA4MzgxLHRheGFfcmlib19zc3UkUzEwODM4NSx0YXhhX3JpYm9fc3N1JFMxMDgzODYsdGF4YV9yaWJvX3NzdSRTMTA4Mzg4LHRheGFfcmlib19zc3UkUzEwODM5MCx0YXhhX3JpYm9fc3N1JFMxMDgzODIsdGF4YV9yaWJvX3NzdSRTMTA4MzgzLHRheGFfcmlib19zc3UkUzEwODM5MSx0YXhhX3JpYm9fc3N1JFMxMDgzOTIsdGF4YV9yaWJvX3NzdSRTMTA4Mzk0LHRheGFfcmlib19zc3UkUzEwODM5NikKbmFtZXModGF4YV9yaWJvX3NzdSk8LWMoIktpbmdkb20iLCJQaHlsdW0iLCJ3czEtVDAiLCJ3czMtVDAiLCJ3czEtVDQiLCJ3czItVDQiLCJ3czEtVDI0Iiwid3MzLVQyNCIsInR1c3MxLVQwIiwidHVzczItVDAiLCJ0dXNzMS1UNCIsInR1c3MyLVQ0IiwidHVzczEtVDI0IiwidHVzczMtVDI0IikKCiMgUmVtb3ZlICJVbmNsYXNzaWZpZWQiIHRheGEgb3RoZXJ3aXNlIGl0IHdpbGwgY2x1bXAgdW5jbGFzc2lmaWVkIEFyY2hhZWEgd2l0aCB1bmNsYXNzaWZpZWQgQmFjdGVyaWEgKG5vdCB3aGF0IHdlIHdhbnQpCnRheGFfcmlib19zc3U8LXRheGFfcmlib19zc3VbIWdyZXBsKCJVbmNsYXNzaWZpZWQiLCB0YXhhX3JpYm9fc3N1JFBoeWx1bSksXQoKIyBSZW1vdmUgIk90aGVyIiB0YXhhIG90aGVyd2lzZSBpdCB3aWxsIGNsdW1wICJvdGhlciIgQXJjaGFlYSB3aXRoICJvdGhlciIgQmFjdGVyaWEgKG5vdCB3aGF0IHdlIHdhbnQpCnRheGFfcmlib19zc3U8LXRheGFfcmlib19zc3VbIWdyZXBsKCJPdGhlciIsIHRheGFfcmlib19zc3UkUGh5bHVtKSxdCgojIFNvcnQgZGF0YSBieSBLaW5nZG9tIGFscGhhYmV0aWNhbGx5CnRheGFfcmlib19zc3U8LXRheGFfcmlib19zc3Vbb3JkZXIodGF4YV9yaWJvX3NzdSRLaW5nZG9tLHRheGFfcmlib19zc3UkUGh5bHVtKSxdCgojIFN1bSBlYWNoIGNvbHVtbiBieSB1bmlxdWUgUGh5bHVtCnRheGFfcmlib19zc3Vfc3VtPC10YXhhX3JpYm9fc3N1ICU+JSBncm91cF9ieShQaHlsdW0pICU+JSBzdW1tYXJpc2VfYXQodmFycygid3MxLVQwIiwid3MzLVQwIiwid3MxLVQ0Iiwid3MyLVQ0Iiwid3MxLVQyNCIsIndzMy1UMjQiLCJ0dXNzMS1UMCIsInR1c3MyLVQwIiwidHVzczEtVDQiLCJ0dXNzMi1UNCIsInR1c3MxLVQyNCIsInR1c3MzLVQyNCIpLCBzdW0pCnRheGFfcmlib19zc3Vfc3VtPC10YXhhX3JpYm9fc3N1X3N1bSAlPiUgbXV0YXRlX2F0KHZhcnMoJ3dzMS1UMCcsJ3dzMy1UMCcsJ3dzMS1UNCcsJ3dzMi1UNCcsJ3dzMS1UMjQnLCd3czMtVDI0JywndHVzczEtVDAnLCd0dXNzMi1UMCcsJ3R1c3MxLVQ0JywndHVzczItVDQnLCd0dXNzMS1UMjQnLCd0dXNzMy1UMjQnKSwgZnVucyhyb3VuZCguLCAwKSkpCnRheGFfcmlib19zc3Vfc3VtPC1hcy5kYXRhLmZyYW1lKHRheGFfcmlib19zc3Vfc3VtKQoKdGF4YV9yaWJvX3NzdV9zdW0KYGBgCgpgYGB7ciBlY2hvPUZBTFNFfQojIFNhdmUgdGF4YV9yaWJvX3NzdV9zdW0gYXMgLmNzdiBmaWxlCndyaXRlLmNzdih0YXhhX3JpYm9fc3N1X3N1bSwgJ1JpYm8uUmVzdWx0cy90YXhhLnJpYm8uc3N1LnN1bS5jc3YnKQpgYGAKClJlcGVhdCB0aGUgc2FtZSAiUmlib3NvbWUiIGFuYWx5c2lzIGFzIGFib3ZlIChhdCBQaHlsdW0gbGV2ZWwpLCBidXQgdGhpcyB0aW1lIGtlZXAgYWxsIHRoZSB0YXhvbm9teSBpbmZvcm1hdGlvbi4KYGBge3J9CiMgTWFrZSBjb3B5IG9mIHRheGFfcmlib19hbGwgdG8gbWFuaXB1bGF0ZQp0YXhhX3JpYm9fc3N1MjwtdGF4YV9yaWJvX2FsbAoKIyBLZWVwICJUYXhvbm9teSIgY29sdW1uCnRheGFfcmlib19zc3UyIDwtIGRhdGEuZnJhbWUodGF4YV9yaWJvX3NzdTIkRnVuY3Rpb24sdGF4YV9yaWJvX3NzdTIkVGF4b25vbXksdGF4YV9yaWJvX3NzdTIkUzEwODM3OSwgdGF4YV9yaWJvX3NzdTIkUzEwODM4MSx0YXhhX3JpYm9fc3N1MiRTMTA4Mzg1LHRheGFfcmlib19zc3UyJFMxMDgzODYsdGF4YV9yaWJvX3NzdTIkUzEwODM4OCx0YXhhX3JpYm9fc3N1MiRTMTA4MzkwLHRheGFfcmlib19zc3UyJFMxMDgzODIsdGF4YV9yaWJvX3NzdTIkUzEwODM4Myx0YXhhX3JpYm9fc3N1MiRTMTA4MzkxLHRheGFfcmlib19zc3UyJFMxMDgzOTIsdGF4YV9yaWJvX3NzdTIkUzEwODM5NCx0YXhhX3JpYm9fc3N1MiRTMTA4Mzk2KQpuYW1lcyh0YXhhX3JpYm9fc3N1Mik8LWMoIkZ1bmN0aW9uIiwiVGF4b25vbXkiLCJ3czEtVDAiLCJ3czMtVDAiLCJ3czEtVDQiLCJ3czItVDQiLCJ3czEtVDI0Iiwid3MzLVQyNCIsInR1c3MxLVQwIiwidHVzczItVDAiLCJ0dXNzMS1UNCIsInR1c3MyLVQ0IiwidHVzczEtVDI0IiwidHVzczMtVDI0IikKCiMgUmVtb3ZlICJsYXJnZSBzdWJ1bml0IHJpYm9zb21hbCBwcm90ZWluIiBmcm9tIGRhdGFzZXQKdGF4YV9yaWJvX3NzdTI8LXRheGFfcmlib19zc3UyWyFncmVwbCgibGFyZ2Ugc3VidW5pdCByaWJvc29tYWwgcHJvdGVpbiIsIHRheGFfcmlib19zc3UyJEZ1bmN0aW9uKSxdCgojIFJlbW92ZSAiRnVuZ2kiIGZyb20gZGF0YXNldAp0YXhhX3JpYm9fc3N1MjwtdGF4YV9yaWJvX3NzdTJbIWdyZXBsKCJGdW5naSIsIHRheGFfcmlib19zc3UyJFRheG9ub215KSxdCmBgYAoKYGBge3J9CiMgU29ydCBkYXRhIGJ5IEtpbmdkb20gYWxwaGFiZXRpY2FsbHkKdGF4YV9yaWJvX3NzdTI8LXRheGFfcmlib19zc3UyW29yZGVyKHRheGFfcmlib19zc3UyJEZ1bmN0aW9uLHRheGFfcmlib19zc3UyJFRheG9ub215KSxdCgojIFN1bSBlYWNoIGNvbHVtbiBieSB1bmlxdWUgVGF4b25vbXkKdGF4YV9yaWJvX3NzdTJfc3VtPC10YXhhX3JpYm9fc3N1MiAlPiUgZ3JvdXBfYnkoVGF4b25vbXkpICU+JSBzdW1tYXJpc2VfYXQodmFycygid3MxLVQwIiwid3MzLVQwIiwid3MxLVQ0Iiwid3MyLVQ0Iiwid3MxLVQyNCIsIndzMy1UMjQiLCJ0dXNzMS1UMCIsInR1c3MyLVQwIiwidHVzczEtVDQiLCJ0dXNzMi1UNCIsInR1c3MxLVQyNCIsInR1c3MzLVQyNCIpLCBzdW0pCnRheGFfcmlib19zc3UyX3N1bTwtdGF4YV9yaWJvX3NzdTJfc3VtICU+JSBtdXRhdGVfYXQodmFycygnd3MxLVQwJywnd3MzLVQwJywnd3MxLVQ0Jywnd3MyLVQ0Jywnd3MxLVQyNCcsJ3dzMy1UMjQnLCd0dXNzMS1UMCcsJ3R1c3MyLVQwJywndHVzczEtVDQnLCd0dXNzMi1UNCcsJ3R1c3MxLVQyNCcsJ3R1c3MzLVQyNCcpLCBmdW5zKHJvdW5kKC4sIDApKSkKdGF4YV9yaWJvX3NzdTJfc3VtPC1hcy5kYXRhLmZyYW1lKHRheGFfcmlib19zc3UyX3N1bSkKCnRheGFfcmlib19zc3UyX3N1bQpgYGAKCmBgYHtyIGVjaG89RkFMU0V9CiMgU2F2ZSB0YXhhX3JpYm9fYWxsX3N1bSBhcyAuY3N2IGZpbGUKd3JpdGUuY3N2KHRheGFfcmlib19zc3UyX3N1bSwgJ1JpYm8uUmVzdWx0cy90YXhhX3JpYm9fc3N1Ml9zdW0uY3N2JykKYGBgCgojIyMjIDcuMS4yLiBGdW5naSBTU1UvTFNVClRoZSBzZWNvbmQgYW5hbHlzaXMgcHVsbHMgb3V0IGFsbCBnZW5lIGV4cHJlc3Npb24gZm9yICJSaWJvc29tZXMiIGFuZCByZW1vdmVzIEJhY3RlcmlhIGFuZCBBcmNoYWVhIGFubm90YXRpb25zIHdoaWxlIHJldGFpbmluZyBqdXN0IEZ1bmdpIHdpdGggYm90aCBzc3UgYW5kIGxzdSBhbm5vdGF0aW9ucyB0byBkZXRlcm1pbmUgcmVsYXRpdmUgZXhwcmVzc2lvbiBvZiBGdW5naSBhdCBlYWNoIHNhbXBsaW5nIHRpbWUgcG9pbnQgaW4gYm90aCB0dXNzb2NrIGFuZCB3ZXQgc2VkZ2UgdHVuZHJhLgoKYGBge3J9CiMgTWFrZSBjb3B5IG9mIFJpYm9zb21lIGRhdGFzZXQgdG8gbWFuaXB1bGF0ZQp0YXhhX3JpYm9fZnVuZ2k8LXRheGFfcmlib19hbGwKCiMgUmVtb3ZlICJCYWN0ZXJpYSIgZnJvbSBkYXRhc2V0CnRheGFfcmlib19mdW5naTwtdGF4YV9yaWJvX2Z1bmdpWyFncmVwbCgiQmFjdGVyaWEiLCB0YXhhX3JpYm9fZnVuZ2kkVGF4b25vbXkpLF0KCiMgUmVtb3ZlICJBcmNoYWVhIiBmcm9tIGRhdGFzZXQKdGF4YV9yaWJvX2Z1bmdpPC10YXhhX3JpYm9fZnVuZ2lbIWdyZXBsKCJBcmNoYWVhIiwgdGF4YV9yaWJvX2Z1bmdpJFRheG9ub215KSxdCgojIFNlcGFyYXRlICJUYXhvbm9teSIgY29sdW1uIGludG8gYWxsIHN1YmRpdmlzaW9ucwp0YXhhX3JpYm9fZnVuZ2k8LXRheGFfcmlib19mdW5naSAlPiUgc2VwYXJhdGUoVGF4b25vbXksIGMoIktpbmdkb20iLCJQaHlsdW0iLCJDbGFzcyIsIk9yZGVyIiwiRmFtaWx5IiwiR2VudXMiLCJTcGVjaWVzIiksICI6ICIsIGV4dHJhPSJtZXJnZSIpCgojIEtlZXAgIktpbmdkb20iIGFuZCAiUGh5bHVtIgp0YXhhX3JpYm9fZnVuZ2kgPC0gZGF0YS5mcmFtZSh0YXhhX3JpYm9fZnVuZ2kkS2luZ2RvbSx0YXhhX3JpYm9fZnVuZ2kkUGh5bHVtLCB0YXhhX3JpYm9fZnVuZ2kkUzEwODM3OSwgdGF4YV9yaWJvX2Z1bmdpJFMxMDgzODEsdGF4YV9yaWJvX2Z1bmdpJFMxMDgzODUsdGF4YV9yaWJvX2Z1bmdpJFMxMDgzODYsdGF4YV9yaWJvX2Z1bmdpJFMxMDgzODgsdGF4YV9yaWJvX2Z1bmdpJFMxMDgzOTAsdGF4YV9yaWJvX2Z1bmdpJFMxMDgzODIsdGF4YV9yaWJvX2Z1bmdpJFMxMDgzODMsdGF4YV9yaWJvX2Z1bmdpJFMxMDgzOTEsdGF4YV9yaWJvX2Z1bmdpJFMxMDgzOTIsdGF4YV9yaWJvX2Z1bmdpJFMxMDgzOTQsdGF4YV9yaWJvX2Z1bmdpJFMxMDgzOTYpCm5hbWVzKHRheGFfcmlib19mdW5naSk8LWMoIktpbmdkb20iLCJQaHlsdW0iLCJ3czEtVDAiLCJ3czMtVDAiLCJ3czEtVDQiLCJ3czItVDQiLCJ3czEtVDI0Iiwid3MzLVQyNCIsInR1c3MxLVQwIiwidHVzczItVDAiLCJ0dXNzMS1UNCIsInR1c3MyLVQ0IiwidHVzczEtVDI0IiwidHVzczMtVDI0IikKCiMgUmVtb3ZlICJVbmNsYXNzaWZpZWQiIHRheGEKdGF4YV9yaWJvX2Z1bmdpPC10YXhhX3JpYm9fZnVuZ2lbIWdyZXBsKCJVbmNsYXNzaWZpZWQiLCB0YXhhX3JpYm9fZnVuZ2kkUGh5bHVtKSxdCgojIFJlbW92ZSAiT3RoZXIiIHRheGEKdGF4YV9yaWJvX2Z1bmdpPC10YXhhX3JpYm9fZnVuZ2lbIWdyZXBsKCJPdGhlciIsIHRheGFfcmlib19mdW5naSRQaHlsdW0pLF0KCiMgU29ydCBkYXRhIGJ5IEtpbmdkb20gYWxwaGFiZXRpY2FsbHkKdGF4YV9yaWJvX2Z1bmdpPC10YXhhX3JpYm9fZnVuZ2lbb3JkZXIodGF4YV9yaWJvX2Z1bmdpJEtpbmdkb20sdGF4YV9yaWJvX2Z1bmdpJFBoeWx1bSksXQoKIyBTdW0gZWFjaCBjb2x1bW4gYnkgdW5pcXVlIFBoeWx1bQp0YXhhX3JpYm9fZnVuZ2lfc3VtPC10YXhhX3JpYm9fZnVuZ2kgJT4lIGdyb3VwX2J5KFBoeWx1bSkgJT4lIHN1bW1hcmlzZV9hdCh2YXJzKCJ3czEtVDAiLCJ3czMtVDAiLCJ3czEtVDQiLCJ3czItVDQiLCJ3czEtVDI0Iiwid3MzLVQyNCIsInR1c3MxLVQwIiwidHVzczItVDAiLCJ0dXNzMS1UNCIsInR1c3MyLVQ0IiwidHVzczEtVDI0IiwidHVzczMtVDI0IiksIHN1bSkKdGF4YV9yaWJvX2Z1bmdpX3N1bTwtdGF4YV9yaWJvX2Z1bmdpX3N1bSAlPiUgbXV0YXRlX2F0KHZhcnMoJ3dzMS1UMCcsJ3dzMy1UMCcsJ3dzMS1UNCcsJ3dzMi1UNCcsJ3dzMS1UMjQnLCd3czMtVDI0JywndHVzczEtVDAnLCd0dXNzMi1UMCcsJ3R1c3MxLVQ0JywndHVzczItVDQnLCd0dXNzMS1UMjQnLCd0dXNzMy1UMjQnKSwgZnVucyhyb3VuZCguLCAwKSkpCnRheGFfcmlib19mdW5naV9zdW08LWFzLmRhdGEuZnJhbWUodGF4YV9yaWJvX2Z1bmdpX3N1bSkKCnRheGFfcmlib19mdW5naV9zdW0KYGBgCgpgYGB7ciBlY2hvPUZBTFNFfQojIFNhdmUgdGF4YV9yaWJvX3NzdV9zdW0gYXMgLmNzdiBmaWxlCndyaXRlLmNzdih0YXhhX3JpYm9fZnVuZ2lfc3VtLCAnUmliby5SZXN1bHRzL3RheGEucmliby5mdW5naS5zdW0uY3N2JykKYGBgCgpSZXBlYXQgdGhlIHNhbWUgIlJpYm9zb21lIiBhbmFseXNpcyBhcyBhYm92ZSAoYXQgUGh5bHVtIGxldmVsKSwgYnV0IHRoaXMgdGltZSBrZWVwIGFsbCB0aGUgdGF4b25vbXkgaW5mb3JtYXRpb24uCmBgYHtyfQojIE1ha2UgY29weSBvZiB0YXhhX3JpYm9fYWxsIHRvIG1hbmlwdWxhdGUKdGF4YV9yaWJvX2Z1bmdpMjwtdGF4YV9yaWJvX2FsbAoKIyBLZWVwICJUYXhvbm9teSIgY29sdW1uCnRheGFfcmlib19mdW5naTIgPC0gZGF0YS5mcmFtZSh0YXhhX3JpYm9fZnVuZ2kyJEZ1bmN0aW9uLHRheGFfcmlib19mdW5naTIkVGF4b25vbXksdGF4YV9yaWJvX2Z1bmdpMiRTMTA4Mzc5LCB0YXhhX3JpYm9fZnVuZ2kyJFMxMDgzODEsdGF4YV9yaWJvX2Z1bmdpMiRTMTA4Mzg1LHRheGFfcmlib19mdW5naTIkUzEwODM4Nix0YXhhX3JpYm9fZnVuZ2kyJFMxMDgzODgsdGF4YV9yaWJvX2Z1bmdpMiRTMTA4MzkwLHRheGFfcmlib19mdW5naTIkUzEwODM4Mix0YXhhX3JpYm9fZnVuZ2kyJFMxMDgzODMsdGF4YV9yaWJvX2Z1bmdpMiRTMTA4MzkxLHRheGFfcmlib19mdW5naTIkUzEwODM5Mix0YXhhX3JpYm9fZnVuZ2kyJFMxMDgzOTQsdGF4YV9yaWJvX2Z1bmdpMiRTMTA4Mzk2KQpuYW1lcyh0YXhhX3JpYm9fZnVuZ2kyKTwtYygiRnVuY3Rpb24iLCJUYXhvbm9teSIsIndzMS1UMCIsIndzMy1UMCIsIndzMS1UNCIsIndzMi1UNCIsIndzMS1UMjQiLCJ3czMtVDI0IiwidHVzczEtVDAiLCJ0dXNzMi1UMCIsInR1c3MxLVQ0IiwidHVzczItVDQiLCJ0dXNzMS1UMjQiLCJ0dXNzMy1UMjQiKQoKIyBSZW1vdmUgIkJhY3RlcmlhIiBmcm9tIGRhdGFzZXQKdGF4YV9yaWJvX2Z1bmdpMjwtdGF4YV9yaWJvX2Z1bmdpMlshZ3JlcGwoIkJhY3RlcmlhIiwgdGF4YV9yaWJvX2Z1bmdpMiRUYXhvbm9teSksXQoKIyBSZW1vdmUgIkFyY2hhZWEiIGZyb20gZGF0YXNldAp0YXhhX3JpYm9fZnVuZ2kyPC10YXhhX3JpYm9fZnVuZ2kyWyFncmVwbCgiQXJjaGFlYSIsIHRheGFfcmlib19mdW5naTIkVGF4b25vbXkpLF0KCmBgYAoKYGBge3J9CiMgU29ydCBkYXRhIGJ5IEtpbmdkb20gYWxwaGFiZXRpY2FsbHkKdGF4YV9yaWJvX2Z1bmdpMjwtdGF4YV9yaWJvX2Z1bmdpMltvcmRlcih0YXhhX3JpYm9fZnVuZ2kyJEZ1bmN0aW9uLHRheGFfcmlib19mdW5naTIkVGF4b25vbXkpLF0KCiMgU3VtIGVhY2ggY29sdW1uIGJ5IHVuaXF1ZSBUYXhvbm9teQp0YXhhX3JpYm9fZnVuZ2kyX3N1bTwtdGF4YV9yaWJvX2Z1bmdpMiAlPiUgZ3JvdXBfYnkoVGF4b25vbXkpICU+JSBzdW1tYXJpc2VfYXQodmFycygid3MxLVQwIiwid3MzLVQwIiwid3MxLVQ0Iiwid3MyLVQ0Iiwid3MxLVQyNCIsIndzMy1UMjQiLCJ0dXNzMS1UMCIsInR1c3MyLVQwIiwidHVzczEtVDQiLCJ0dXNzMi1UNCIsInR1c3MxLVQyNCIsInR1c3MzLVQyNCIpLCBzdW0pCnRheGFfcmlib19mdW5naTJfc3VtPC10YXhhX3JpYm9fZnVuZ2kyX3N1bSAlPiUgbXV0YXRlX2F0KHZhcnMoJ3dzMS1UMCcsJ3dzMy1UMCcsJ3dzMS1UNCcsJ3dzMi1UNCcsJ3dzMS1UMjQnLCd3czMtVDI0JywndHVzczEtVDAnLCd0dXNzMi1UMCcsJ3R1c3MxLVQ0JywndHVzczItVDQnLCd0dXNzMS1UMjQnLCd0dXNzMy1UMjQnKSwgZnVucyhyb3VuZCguLCAwKSkpCnRheGFfcmlib19mdW5naTJfc3VtPC1hcy5kYXRhLmZyYW1lKHRheGFfcmlib19mdW5naTJfc3VtKQoKdGF4YV9yaWJvX2Z1bmdpMl9zdW0KYGBgCgpgYGB7ciBlY2hvPUZBTFNFfQojIFNhdmUgdGF4YV9yaWJvX2FsbF9zdW0gYXMgLmNzdiBmaWxlCndyaXRlLmNzdih0YXhhX3JpYm9fZnVuZ2kyX3N1bSwgJ1JpYm8uUmVzdWx0cy90YXhhLnJpYm8uZnVuZ2kyLnN1bS5jc3YnKQpgYGAKCiMjIyMgNy4xLjMuIFBsb3R0aW5nIFRheG9ub215CgpQbG90IHRoZSByZWxhdGl2ZSBhYnVuZGFuY2Ugb2YgdGF4YSBieSBhbGwgcmVwbGljYXRlcyB3aXRoaW4gdHVzc29jayBhbmQgd2V0IHNlZGdlIHR1bmRyYSBhcyBhIHN0YWNrcGxvdC4KYGBge3IgZWNobz1GQUxTRX0KdGF4YS5NVC5hbGwuY2hhcnQ8LXJlYWQuY3N2KCJQbG90LkRhdGEvdGF4YS5NVC5hbGwuc3RhY2twbG90LmNzdiIpCmBgYAoKYGBge3J9CiMgUGxhY2UgdGF4YSBpbiBvcmRlciBmb3IgcGxvdHRpbmcKdGF4YS5NVC5hbGwuY2hhcnQkU3BlY2llczwtZmFjdG9yKHRheGEuTVQuYWxsLmNoYXJ0JFNwZWNpZXMsbGV2ZWxzID0gYygiQWNpZG9iYWN0ZXJpYSIsIkFjdGlub2JhY3RlcmlhIiwiQWxwaGFwcm90ZW9iYWN0ZXJpYSIsIkJldGFwcm90ZW9iYWN0ZXJpYSIsIkRlbHRhcHJvdGVvYmFjdGVyaWEiLCJHYW1tYXByb3Rlb2JhY3RlcmlhIiwiUHJvdGVvYmFjdGVyaWEgVW5jbGFzc2lmaWVkIiwiQmFjdGVyb2lkZXRlcyIsIkNobG9yb2ZsZXhpIiwiRmlybWljdXRlcyIsIlBsYW5jdG9teWNldGVzIiwiVmVycnVjb21pY3JvYmlhIiwiQmFjdGVyaWEgVW5jbGFzc2lmaWVkIiwiQmFjdGVyaWEgT3RoZXIiLCJBcmNoYWVhIiwiRnVuZ2kiKSkKCnRheGEuTVQuYWxsLmNoYXJ0JFNwZWNpZXM8LWZjdF9yZXYodGF4YS5NVC5hbGwuY2hhcnQkU3BlY2llcykKCnRheGEuTVQuYWxsLmNoYXJ0JFNhbXBsZTwtZmFjdG9yKHRheGEuTVQuYWxsLmNoYXJ0JFNhbXBsZSxsZXZlbHMgPSBjKCJUdXNzMS1NVC1UMCIsIlR1c3MyLU1ULVQwIiwiVHVzczEtTVQtVDQiLCJUdXNzMi1NVC1UNCIsIlR1c3MxLU1ULVQyNCIsIlR1c3MzLU1ULVQyNCIsIldTMS1NVC1UMCIsIldTMy1NVC1UMCIsIldTMS1NVC1UNCIsIldTMi1NVC1UNCIsIldTMS1NVC1UMjQiLCJXUzMtTVQtVDI0IikpCmBgYAoKYGBge3J9CmNvbG91ckNvdW50ID0gbGVuZ3RoKHVuaXF1ZSh0YXhhLk1ULmFsbC5jaGFydCRTcGVjaWVzKSkKZ2V0UGFsZXR0ZSA9IGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbCgxMiwgIlBhaXJlZCIpKQoKdGF4YS5NVC5hbGwucGxvdDwtZ2dwbG90KHRheGEuTVQuYWxsLmNoYXJ0LCBhZXMoZmlsbD1TcGVjaWVzLCB5PVZhbHVlLCB4PVNhbXBsZSkpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSJpZGVudGl0eSIsIGNvbG9yPSJibGFjayIpICsgeWxhYihleHByZXNzaW9uKGF0b3AoIlJlbGF0aXZlIFRheG9uIiwgcGFzdGUoIkV4cHJlc3Npb24gKCUpIikpKSkgKyB0aGVtZV9taW5pbWFsKCkgKyB0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTIpLGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCkpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9OCksIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC43NSwibGluZSIpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSkgKyBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGZ1bmN0aW9uKFNhbXBsZSkgc3RyX3dyYXAoU2FtcGxlLCB3aWR0aCA9IDgpKSArIHNjYWxlX3NpemUoZ3VpZGU9RkFMU0UpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcmV2KGdldFBhbGV0dGUoY29sb3VyQ291bnQpKSkgKyBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGZ1bmN0aW9uKFNhbXBsZSkgc3RyX3dyYXAoU2FtcGxlLCB3aWR0aCA9IDE1KSkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDI3MCwgaGp1c3Q9MCkpIApgYGAKCmBgYHtyfQp0YXhhLk1ULmFsbC5wbG90CmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9CiMgU2F2ZSB0aGUgUmlib3NvbWUgVGF4b25vbXkgcGxvdCBhcyBhbiBpbmRpdmlkdWFsIGZpZ3VyZQpzZXRFUFMoKQpwb3N0c2NyaXB0KCJGaWcuUzIuUmliby5TdGFja3Bsb3QuZXBzIiwgd2lkdGg9NywgaGVpZ2h0ID0gNS4wKQpnZ2FycmFuZ2UodGF4YS5yaWJvLnBsb3QsIGhlaWdodHM9YygzLDMpLAogICAgICAgICAgbmNvbCA9IDEsIG5yb3cgPSAxKQpkZXYub2ZmKCkKYGBgCgojIyMjIDQuMi4yIE1lYW4gVGltZSBQb2ludAoKUGxvdCB0aGUgbWVhbiByZWxhdGl2ZSBhYnVuZGFuY2Ugb2YgdGF4YSBieSBzYW1wbGluZyB0aW1lIHBvaW50IHdpdGhpbiB0dXNzb2NrIGFuZCB3ZXQgc2VkZ2UgdHVuZHJhIGFzIGEgc3RhY2twbG90LgpgYGB7ciBlY2hvPUZBTFNFfQp0YXhhLk1ULnRpbWUubWVhbi5jaGFydDwtcmVhZC5jc3YoIlBsb3QuRGF0YS90YXhhLk1ULnRpbWUubWVhbi5zdGFja3Bsb3QuY3N2IikKYGBgCgpgYGB7cn0KIyBQbGFjZSB0YXhhIGluIG9yZGVyIGZvciBwbG90dGluZwp0YXhhLk1ULnRpbWUubWVhbi5jaGFydCRTcGVjaWVzPC1mYWN0b3IodGF4YS5NVC50aW1lLm1lYW4uY2hhcnQkU3BlY2llcyxsZXZlbHMgPSBjKCJBY2lkb2JhY3RlcmlhIiwiQWN0aW5vYmFjdGVyaWEiLCJBbHBoYXByb3Rlb2JhY3RlcmlhIiwiQmV0YXByb3Rlb2JhY3RlcmlhIiwiRGVsdGFwcm90ZW9iYWN0ZXJpYSIsIkdhbW1hcHJvdGVvYmFjdGVyaWEiLCJQcm90ZW9iYWN0ZXJpYSBVbmNsYXNzaWZpZWQiLCJCYWN0ZXJvaWRldGVzIiwiQ2hsb3JvZmxleGkiLCJGaXJtaWN1dGVzIiwiUGxhbmN0b215Y2V0ZXMiLCJWZXJydWNvbWljcm9iaWEiLCJCYWN0ZXJpYSBVbmNsYXNzaWZpZWQiLCJCYWN0ZXJpYSBPdGhlciIsIkFyY2hhZWEiLCJGdW5naSIpKQoKdGF4YS5NVC50aW1lLm1lYW4uY2hhcnQkU3BlY2llczwtZmN0X3Jldih0YXhhLk1ULnRpbWUubWVhbi5jaGFydCRTcGVjaWVzKQoKdGF4YS5NVC50aW1lLm1lYW4uY2hhcnQkU2FtcGxlPC1mYWN0b3IodGF4YS5NVC50aW1lLm1lYW4uY2hhcnQkU2FtcGxlLGxldmVscyA9IGMoIlR1c3MtTVQtVDAiLCJUdXNzLU1ULVQ0IiwiVHVzcy1NVC1UMjQiLCJXUy1NVC1UMCIsIldTLU1ULVQ0IiwiV1MtTVQtVDI0IikpCmBgYAoKYGBge3J9CmNvbG91ckNvdW50ID0gbGVuZ3RoKHVuaXF1ZSh0YXhhLk1ULnRpbWUubWVhbi5jaGFydCRTcGVjaWVzKSkKZ2V0UGFsZXR0ZSA9IGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbCgxMiwgIlBhaXJlZCIpKQoKdGF4YS5NVC50aW1lLm1lYW4ucGxvdDwtZ2dwbG90KHRheGEuTVQudGltZS5tZWFuLmNoYXJ0LCBhZXMoZmlsbD1TcGVjaWVzLCB5PVZhbHVlLCB4PVNhbXBsZSkpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSJpZGVudGl0eSIsIGNvbG9yPSJibGFjayIpICsgeWxhYihleHByZXNzaW9uKGF0b3AoIlJlbGF0aXZlIFRheG9uIiwgcGFzdGUoIkV4cHJlc3Npb24gKCUpIikpKSkgKyB0aGVtZV9taW5pbWFsKCkgKyB0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTIpLGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCkpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9OCksIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC43NSwibGluZSIpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSkgKyBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGZ1bmN0aW9uKFNhbXBsZSkgc3RyX3dyYXAoU2FtcGxlLCB3aWR0aCA9IDgpKSArIHNjYWxlX3NpemUoZ3VpZGU9RkFMU0UpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcmV2KGdldFBhbGV0dGUoY29sb3VyQ291bnQpKSkgKyBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGZ1bmN0aW9uKFNhbXBsZSkgc3RyX3dyYXAoU2FtcGxlLCB3aWR0aCA9IDE1KSkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDI3MCwgaGp1c3Q9MCkpIApgYGAKCmBgYHtyfQp0YXhhLk1ULnRpbWUubWVhbi5wbG90CmBgYAoKIyMjIyA0LjIuMyBNZWFuIFR1bmRyYQoKUGxvdCB0aGUgbWVhbiByZWxhdGl2ZSBhYnVuZGFuY2Ugb2YgdGF4YSBieSB3aXRoaW4gdHVzc29jayBhbmQgd2V0IHNlZGdlIHR1bmRyYSBhcyBhIHN0YWNrcGxvdC4KYGBge3IgZWNobz1GQUxTRX0KdGF4YS5NVC50dW5kcmEubWVhbi5jaGFydDwtcmVhZC5jc3YoIlBsb3QuRGF0YS90YXhhLk1ULnR1bmRyYS5tZWFuLnN0YWNrcGxvdC5jc3YiKQpgYGAKCmBgYHtyfQojIFBsYWNlIHRheGEgaW4gb3JkZXIgZm9yIHBsb3R0aW5nCnRheGEuTVQudHVuZHJhLm1lYW4uY2hhcnQkU3BlY2llczwtZmFjdG9yKHRheGEuTVQudHVuZHJhLm1lYW4uY2hhcnQkU3BlY2llcyxsZXZlbHMgPSBjKCJBY2lkb2JhY3RlcmlhIiwiQWN0aW5vYmFjdGVyaWEiLCJBbHBoYXByb3Rlb2JhY3RlcmlhIiwiQmV0YXByb3Rlb2JhY3RlcmlhIiwiRGVsdGFwcm90ZW9iYWN0ZXJpYSIsIkdhbW1hcHJvdGVvYmFjdGVyaWEiLCJQcm90ZW9iYWN0ZXJpYSBVbmNsYXNzaWZpZWQiLCJCYWN0ZXJvaWRldGVzIiwiQ2hsb3JvZmxleGkiLCJGaXJtaWN1dGVzIiwiUGxhbmN0b215Y2V0ZXMiLCJWZXJydWNvbWljcm9iaWEiLCJCYWN0ZXJpYSBVbmNsYXNzaWZpZWQiLCJCYWN0ZXJpYSBPdGhlciIsIkFyY2hhZWEiLCJGdW5naSIpKQoKdGF4YS5NVC50dW5kcmEubWVhbi5jaGFydCRTcGVjaWVzPC1mY3RfcmV2KHRheGEuTVQudHVuZHJhLm1lYW4uY2hhcnQkU3BlY2llcykKCnRheGEuTVQudHVuZHJhLm1lYW4uY2hhcnQkU2FtcGxlPC1mYWN0b3IodGF4YS5NVC50dW5kcmEubWVhbi5jaGFydCRTYW1wbGUsbGV2ZWxzID0gYygiVHVzcy1NVCIsIldTLU1UIikpCmBgYAoKYGBge3J9CmNvbG91ckNvdW50ID0gbGVuZ3RoKHVuaXF1ZSh0YXhhLk1ULnR1bmRyYS5tZWFuLmNoYXJ0JFNwZWNpZXMpKQpnZXRQYWxldHRlID0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKDEyLCAiUGFpcmVkIikpCgp0YXhhLk1ULnR1bmRyYS5tZWFuLnBsb3Q8LWdncGxvdCh0YXhhLk1ULnR1bmRyYS5tZWFuLmNoYXJ0LCBhZXMoZmlsbD1TcGVjaWVzLCB5PVZhbHVlLCB4PVNhbXBsZSkpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSJpZGVudGl0eSIsIGNvbG9yPSJibGFjayIpICsgeWxhYihleHByZXNzaW9uKGF0b3AoIlJlbGF0aXZlIFRheG9uIiwgcGFzdGUoIkV4cHJlc3Npb24gKCUpIikpKSkgKyB0aGVtZV9taW5pbWFsKCkgKyB0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTIpLGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCkpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9OCksIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC43NSwibGluZSIpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSkgKyBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGZ1bmN0aW9uKFNhbXBsZSkgc3RyX3dyYXAoU2FtcGxlLCB3aWR0aCA9IDgpKSArIHNjYWxlX3NpemUoZ3VpZGU9RkFMU0UpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcmV2KGdldFBhbGV0dGUoY29sb3VyQ291bnQpKSkgKyBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGZ1bmN0aW9uKFNhbXBsZSkgc3RyX3dyYXAoU2FtcGxlLCB3aWR0aCA9IDE1KSkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDI3MCwgaGp1c3Q9MCkpIApgYGAKCmBgYHtyfQp0YXhhLk1ULnR1bmRyYS5tZWFuLnBsb3QKYGBgCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKUGxvdCB0aGUgcmVsYXRpdmUgZXhwcmVzc2lvbiBvZiByaWJvc29tZXMgYXMgYSBzdGFja3Bsb3Qgd2l0aCB0aGUgTUVBTiBvZiBzYW1wbGVzIGJ5IHRpbWUgcG9pbnQKYGBge3IgZWNobz1GQUxTRX0KdGF4YS5tZWFuLnJpYm8uY2hhcnQ8LXJlYWQuY3N2KCJQbG90LkRhdGEvdGF4YS5tZWFuLnJpYm8uc3RhY2twbG90LmNzdiIpCmBgYAoKYGBge3J9CiMgUGxhY2UgdGF4YSBpbiBvcmRlciBmb3IgcGxvdHRpbmcKdGF4YS5tZWFuLnJpYm8uY2hhcnQkU3BlY2llczwtZmFjdG9yKHRheGEubWVhbi5yaWJvLmNoYXJ0JFNwZWNpZXMsbGV2ZWxzID0gYygiQWNpZG9iYWN0ZXJpYSIsIkFjdGlub2JhY3RlcmlhIiwiQWxwaGFwcm90ZW9iYWN0ZXJpYSIsIkJldGFwcm90ZW9iYWN0ZXJpYSIsIkRlbHRhcHJvdGVvYmFjdGVyaWEiLCJHYW1tYXByb3Rlb2JhY3RlcmlhIiwiUHJvdGVvYmFjdGVyaWEgVW5jbGFzc2lmaWVkIiwiQmFjdGVyb2lkZXRlcyIsIkNobG9yb2ZsZXhpIiwiRmlybWljdXRlcyIsIlBsYW5jdG9teWNldGVzIiwiVmVycnVjb21pY3JvYmlhIiwiQmFjdGVyaWEgT3RoZXIiLCJBcmNoYWVhIiwiRnVuZ2kiKSkKCnRheGEubWVhbi5yaWJvLmNoYXJ0JFNwZWNpZXM8LWZjdF9yZXYodGF4YS5tZWFuLnJpYm8uY2hhcnQkU3BlY2llcykKCnRheGEubWVhbi5yaWJvLmNoYXJ0JFNhbXBsZTwtZmFjdG9yKHRheGEubWVhbi5yaWJvLmNoYXJ0JFNhbXBsZSxsZXZlbHMgPSBjKCJUdXNzLTE2UyIsIlR1c3MtTUciLCJUdXNzLU1ULVQwIiwiVHVzcy1NVC1UNCIsIlR1c3MtTVQtVDI0IiwiV1MtMTZTIiwiV1MtTUciLCJXUy1NVC1UMCIsIldTLU1ULVQ0IiwiV1MtTVQtVDI0IikpCmBgYAoKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KY29sb3VyQ291bnQgPSBsZW5ndGgodW5pcXVlKHRheGEubWVhbi5yaWJvLmNoYXJ0JFNwZWNpZXMpKQpnZXRQYWxldHRlID0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKDEyLCAiUGFpcmVkIikpCgp0YXhhLm1lYW4ucmliby5wbG90PC1nZ3Bsb3QodGF4YS5tZWFuLnJpYm8uY2hhcnQsIGFlcyhmaWxsPVNwZWNpZXMsIHk9VmFsdWUsIHg9U2FtcGxlKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ImlkZW50aXR5IiwgY29sb3I9ImJsYWNrIikgKyB5bGFiKCIgIikgKyB0aGVtZV9taW5pbWFsKCkgKyB0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTIpLGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCkpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9OCksIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC43NSwibGluZSIpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSkgKyBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGZ1bmN0aW9uKFNhbXBsZSkgc3RyX3dyYXAoU2FtcGxlLCB3aWR0aCA9IDgpKSArIHNjYWxlX3NpemUoZ3VpZGU9RkFMU0UpICsgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDEpKSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSByZXYoZ2V0UGFsZXR0ZShjb2xvdXJDb3VudCkpLCBndWlkZT1ndWlkZV9sZWdlbmQocmV2ZXJzZT1GQUxTRSkpICsgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBmdW5jdGlvbihTYW1wbGUpIHN0cl93cmFwKFNhbXBsZSwgd2lkdGggPSAxNSkpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0PTApKQpgYGAKCmBgYHtyfQp0YXhhLm1lYW4ucmliby5wbG90CmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9CiMgU2F2ZSB0aGUgUmlib3NvbWUgVGF4b25vbXkgcGxvdCBhcyBhbiBpbmRpdmlkdWFsIGZpZ3VyZQpzZXRFUFMoKQpwb3N0c2NyaXB0KCJGaWcuMS5UYXhhLk1HLk1ULmVwcyIsIHdpZHRoPTgsIGhlaWdodCA9IDUuMCkKZ2dhcnJhbmdlKHRheGEubWVhbi5yaWJvLnBsb3QsIGhlaWdodHM9Yyg0LDQpLAogICAgICAgICAgbmNvbCA9IDEsIG5yb3cgPSAxKQpkZXYub2ZmKCkKYGBgCgpQbG90IHRoZSByZWxhdGl2ZSBleHByZXNzaW9uIG9mIFRVU1Mgcmlib3NvbWVzIGFzIGEgc3RhY2twbG90IGJ5IE1FQU4gb2YgVElNRVBPSU5UCmBgYHtyIGVjaG89RkFMU0V9CnRheGEudHVzcy5tZWFuLnJpYm8uY2hhcnQ8LXJlYWQuY3N2KCJQbG90LkRhdGEvdGF4YS50dXNzLm1lYW4ucmliby5zdGFja3Bsb3QuY3N2IikKYGBgCgpgYGB7cn0KIyBQbGFjZSB0YXhhIGluIG9yZGVyIGZvciBwbG90dGluZwp0YXhhLnR1c3MubWVhbi5yaWJvLmNoYXJ0JFNwZWNpZXM8LWZhY3Rvcih0YXhhLnR1c3MubWVhbi5yaWJvLmNoYXJ0JFNwZWNpZXMsbGV2ZWxzID0gYygiQWNpZG9iYWN0ZXJpYSIsIkFjdGlub2JhY3RlcmlhIiwiQWxwaGFwcm90ZW9iYWN0ZXJpYSIsIkJldGFwcm90ZW9iYWN0ZXJpYSIsIkRlbHRhcHJvdGVvYmFjdGVyaWEiLCJHYW1tYXByb3Rlb2JhY3RlcmlhIiwiUHJvdGVvYmFjdGVyaWEgVW5jbGFzc2lmaWVkIiwiQmFjdGVyb2lkZXRlcyIsIkNobG9yb2ZsZXhpIiwiRmlybWljdXRlcyIsIlBsYW5jdG9teWNldGVzIiwiVmVycnVjb21pY3JvYmlhIiwiQmFjdGVyaWEgT3RoZXIiLCJBcmNoYWVhIiwiRnVuZ2kiKSkKCnRheGEudHVzcy5tZWFuLnJpYm8uY2hhcnQkU3BlY2llczwtZmN0X3Jldih0YXhhLnR1c3MubWVhbi5yaWJvLmNoYXJ0JFNwZWNpZXMpCgp0YXhhLnR1c3MubWVhbi5yaWJvLmNoYXJ0JFNhbXBsZTwtZmFjdG9yKHRheGEudHVzcy5tZWFuLnJpYm8uY2hhcnQkU2FtcGxlLGxldmVscyA9IGMoIlR1c3MtMTZTIiwiVHVzcy1NRyIsIlR1c3MtTVQtVDAiLCJUdXNzLU1ULVQ0IiwiVHVzcy1NVC1UMjQiKSkKYGBgCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpjb2xvdXJDb3VudCA9IGxlbmd0aCh1bmlxdWUodGF4YS50dXNzLm1lYW4ucmliby5jaGFydCRTcGVjaWVzKSkKZ2V0UGFsZXR0ZSA9IGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbCgxMiwgIlBhaXJlZCIpKQoKdGF4YS50dXNzLm1lYW4ucmliby5wbG90PC1nZ3Bsb3QodGF4YS50dXNzLm1lYW4ucmliby5jaGFydCwgYWVzKGZpbGw9U3BlY2llcywgeT1WYWx1ZSwgeD1TYW1wbGUpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0iaWRlbnRpdHkiLCBjb2xvcj0iYmxhY2siKSArIHlsYWIoZXhwcmVzc2lvbihhdG9wKCJDb21tdW5pdHkgQ29tcG9zaXRpb24iLCBwYXN0ZSgiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpKSkpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gcmV2KGdldFBhbGV0dGUoY29sb3VyQ291bnQpKSwgZ3VpZGU9Z3VpZGVfbGVnZW5kKHJldmVyc2U9RkFMU0UpKSArIHRoZW1lX2NsYXNzaWMoKSArIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0PTApLCBheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApLCBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTEyKSwgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpLCBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xMCksIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC43NSwibGluZSIpKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIDEwMSkpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CnRheGEudHVzcy5tZWFuLnJpYm8ucGxvdApgYGAKClBsb3QgdGhlIHJlbGF0aXZlIGV4cHJlc3Npb24gb2YgV1Mgcmlib3NvbWVzIGFzIGEgc3RhY2twbG90IGJ5IE1FQU4gb2YgVElNRVBPSU5UCmBgYHtyIGVjaG89RkFMU0V9CnRheGEud3MubWVhbi5yaWJvLmNoYXJ0PC1yZWFkLmNzdigiUGxvdC5EYXRhL3RheGEud3MubWVhbi5yaWJvLnN0YWNrcGxvdC5jc3YiKQpgYGAKCmBgYHtyfQojIFBsYWNlIHRheGEgaW4gb3JkZXIgZm9yIHBsb3R0aW5nCnRheGEud3MubWVhbi5yaWJvLmNoYXJ0JFNwZWNpZXM8LWZhY3Rvcih0YXhhLndzLm1lYW4ucmliby5jaGFydCRTcGVjaWVzLGxldmVscyA9IGMoIkFjaWRvYmFjdGVyaWEiLCJBY3Rpbm9iYWN0ZXJpYSIsIkFscGhhcHJvdGVvYmFjdGVyaWEiLCJCZXRhcHJvdGVvYmFjdGVyaWEiLCJEZWx0YXByb3Rlb2JhY3RlcmlhIiwiR2FtbWFwcm90ZW9iYWN0ZXJpYSIsIlByb3Rlb2JhY3RlcmlhIFVuY2xhc3NpZmllZCIsIkJhY3Rlcm9pZGV0ZXMiLCJDaGxvcm9mbGV4aSIsIkZpcm1pY3V0ZXMiLCJQbGFuY3RvbXljZXRlcyIsIlZlcnJ1Y29taWNyb2JpYSIsIkJhY3RlcmlhIE90aGVyIiwiQXJjaGFlYSIsIkZ1bmdpIikpCgp0YXhhLndzLm1lYW4ucmliby5jaGFydCRTcGVjaWVzPC1mY3RfcmV2KHRheGEud3MubWVhbi5yaWJvLmNoYXJ0JFNwZWNpZXMpCgp0YXhhLndzLm1lYW4ucmliby5jaGFydCRTYW1wbGU8LWZhY3Rvcih0YXhhLndzLm1lYW4ucmliby5jaGFydCRTYW1wbGUsbGV2ZWxzID0gYygiV1MtMTZTIiwiV1MtTUciLCJXUy1NVC1UMCIsIldTLU1ULVQ0IiwiV1MtTVQtVDI0IikpCmBgYAoKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KY29sb3VyQ291bnQgPSBsZW5ndGgodW5pcXVlKHRheGEud3MubWVhbi5yaWJvLmNoYXJ0JFNwZWNpZXMpKQpnZXRQYWxldHRlID0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKDEyLCAiUGFpcmVkIikpCgp0YXhhLndzLm1lYW4ucmliby5wbG90PC1nZ3Bsb3QodGF4YS53cy5tZWFuLnJpYm8uY2hhcnQsIGFlcyhmaWxsPVNwZWNpZXMsIHk9VmFsdWUsIHg9U2FtcGxlKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ImlkZW50aXR5IiwgY29sb3I9ImJsYWNrICIpICsgeWxhYihleHByZXNzaW9uKGF0b3AoIkNvbW11bml0eSBDb21wb3NpdGlvbiIsIHBhc3RlKCJSZWxhdGl2ZSBBYnVuZGFuY2UgKCUpIikpKSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSByZXYoZ2V0UGFsZXR0ZShjb2xvdXJDb3VudCkpLCBndWlkZT1ndWlkZV9sZWdlbmQocmV2ZXJzZT1GQUxTRSkpICsgdGhlbWVfY2xhc3NpYygpICsgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDI3MCwgaGp1c3Q9MCksIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xMCksIGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTIpLCBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpLCBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xMCksIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC43NSwibGluZSIpKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIDEwMSkpCmBgYAoKYGBge3J9CnRheGEud3MubWVhbi5yaWJvLnBsb3QKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQojIFNhdmUgdGhlIFJpYm9zb21lIFRheG9ub215IHBsb3QgYXMgYW4gaW5kaXZpZHVhbCBmaWd1cmUKc2V0RVBTKCkKcG9zdHNjcmlwdCgiRmlnLjEuMTZTLk1HLk1ULlRheGEuZXBzIiwgd2lkdGg9MTAuMCwgaGVpZ2h0ID0gNS4wKQpkaXYucGxvdDwtcGxvdF9ncmlkKHRheGEudHVzcy5tZWFuLnJpYm8ucGxvdCwgdGF4YS53cy5tZWFuLnJpYm8ucGxvdCxyZWxfd2lkdGhzID0gYygyLDMpKQpwbG90X2dyaWQoZGl2LnBsb3QsbmNvbCA9IDEpCmRldi5vZmYoKQpgYGAKCiMjIyMgNy4xLjQuIFRheG9ub215IFN0YXRpc3RpY3MKClRvIGRldGVybWluZSBpZiB0aGVyZSBhcmUgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgaW4gbWVhbiByZWxhdGl2ZSBhYnVuZGFuY2Ugb2YgZG9taW5hbnQgdGF4YSBiZXR3ZWVuIHR1bmRyYSBlY29zeXN0ZW1zLCB3ZSBjYWxjdWxhdGUgdGhlIG1lYW4gKFNEKSBvZiBlYWNoIHBoeWx1bSAoZG9taW5hbnQgcGh5bHVtOyA+MSUpIHdpdGhpbiB0dXNzb2NrIHR1bmRyYSBhbmQgd2l0aGluIHdldCBzZWRnZSB0dW5kcmEgdGhyb3VnaG91dCB0aGUgZXhwZXJpbWVudCBhbmQgY29tcGFyZSB0byBlYWNoIG90aGVyLgoKYGBge3IgZWNobz1GQUxTRX0KdGF4YS50YWJsZTwtcmVhZC5jc3YoIlRhYmxlLkRhdGEvdGF4YS50YWJsZS5jc3YiKQoKIyBSZW5hbWUgY29sdW1uIGhlYWRpbmdzCmNvbG5hbWVzKHRheGEudGFibGUpPC1jKCJUYXhvbm9teSIsIlR1c3MgUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIsIldTIFJlbGF0aXZlIEFidW5kYW5jZSAoJSkiLCJNZWFuIERpZmZlcmVuY2UiLCAiUGFpcmVkIHQtdGVzdCAocC12YWx1ZSkiKQoKa2FibGUodGF4YS50YWJsZSwgY2FwdGlvbiA9ICJSZWxhdGl2ZSBhYnVuZGFuY2UgKG1lYW4gKFNEKSkgb2YgbWljcm9iaWFsIHRheGEgd2l0aGluIHR1c3NvY2sgdHVuZHJhIGFuZCB3ZXQgc2VkZ2UgdHVuZHJhIHdpdGggbWVhbiBkaWZmZXJlbmNlICglKSBhbmQgc2lnbmlmaWNhbmNlIChwLXZhbHVlKS4iLCBmb3JtYXQuYXJncyA9IGxpc3QoYmlnLm1hcmsgPSAiLCIpLCBhbGlnbiA9ICJsIikgJT4lIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpKQpgYGAKClRlc3QgZm9yIGRpZmZlcmVuY2VzIGluIG1lYW4gcmVsYXRpdmUgYWJ1bmRhbmNlIG9mIGRvbWluYW50IHBoeWxhIGJldHdlZW4gdHVuZHJhIGVjb3N5c3RlbXMuCgpgYGB7ciBlY2hvPUZBTFNFfQp0YXhhLnBoeWx1bS50LnRlc3Q8LXJlYWQuY3N2KCJTdGF0cy5EYXRhL3RheGEucGh5bHVtLnQudGVzdC5jc3YiKQpgYGAKCmBgYHtyfQojIFBhaXJ3aXNlIGNvbXBhcmlzb25zIGJldHdlZW4gdHVuZHJhIGVjb3N5c3RlbXMgZm9yIGVhY2ggbWljcm9iaWFsIHRheG9ub21pYyBjbGFzcwp0YXhhLnBoeWx1bS50LnRlc3Quc3RhdHMgPC0gdGF4YS5waHlsdW0udC50ZXN0ICU+JQogIGdyb3VwX2J5KFBoeWx1bSkgJT4lCiAgcGFpcndpc2VfdF90ZXN0KAogICAgQWJ1bmRhbmNlIH4gVHVuZHJhLCBwYWlyZWQgPSBUUlVFLCAKICAgIHAuYWRqdXN0Lm1ldGhvZCA9ICJib25mZXJyb25pIgogICAgKSAlPiUKICBzZWxlY3QoLS55LiwgLW4xLCAtbjIsIC1kZiwgLXN0YXRpc3RpYywgLXApICMgUmVtb3ZlIGRldGFpbHMKdGF4YS5waHlsdW0udC50ZXN0LnN0YXRzCmBgYAoKVG8gZGV0ZXJtaW5lIGlmIHRoZXJlIGFyZSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBpbiBtZWFuIHJlbGF0aXZlIGFidW5kYW5jZSBvZiBkb21pbmFudCB0YXhhIGJldHdlZW4gc2FtcGxpbmcgdGltZSBwb2ludHMgd2l0aGluIGVhY2ggdHVuZHJhIGVjb3N5c3RlbSwgd2UgY2FsY3VsYXRlIHRoZSBtZWFuIChTRCkgb2YgZWFjaCBwaHlsdW0gKGRvbWluYW50IHBoeWx1bTsgPjElKSBhdCBlYWNoIHRpbWUgcG9pbnQgd2l0aGluIHR1c3NvY2sgdHVuZHJhIG9yIHdpdGhpbiB3ZXQgc2VkZ2UgdHVuZHJhIHRocm91Z2hvdXQgdGhlIGV4cGVyaW1lbnQgYW5kIGNvbXBhcmUgdG8gZWFjaCBvdGhlci4KCkNsaWNrIG9uIHRoZSAqKlNob3cvSGlkZSoqIGJ1dHRvbiB0byBzZWUgdGhlIHN0YXRpc3RpY3MuCgo8YnV0dG9uIGNsYXNzPSJidG4gYnRuLXByaW1hcnkiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9IiNCbG9ja05hbWU5NiI+IFNob3cvSGlkZSA8L2J1dHRvbj4gIAo8ZGl2IGlkPSJCbG9ja05hbWU5NiIgY2xhc3M9ImNvbGxhcHNlIj4KClR1c3NvY2sgVHVuZHJhIFRheG9ub215IChQaHlsdW0pIEFOT1ZBCmBgYHtyIGVjaG89RkFMU0V9CnR1c3NfbXRfdGF4YV9zdGF0czwtcmVhZC5jc3YoIlN0YXRzLkRhdGEvdHVzcy5tdC50YXhhLmFub3ZhLnN0YXRzLmNzdiIpCmBgYAoKYGBge3J9CiMgU3Vic2V0IHJlc3BvbnNlIHZhcmlhYmxlcyBmb3IgTUFOT1ZBCnR1c3NfbXRfdGF4YV9zdGF0cyRyZXNwb25zZSA8LSBhcy5tYXRyaXgodHVzc19tdF90YXhhX3N0YXRzWywgMjoxMl0pCmBgYAoKYGBge3J9CiMgTUFOT1ZBIHRlc3QKdHVzc19tdF90YXhhX3N0YXRzX21hbm92YSA8LSBtYW5vdmEocmVzcG9uc2UgfiBUaW1lcG9pbnQsIGRhdGE9dHVzc19tdF90YXhhX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX210X3RheGFfc3RhdHNfbWFub3ZhKQoKIyMgUnVuIEFOT1ZBIGZvciBlYWNoIGNhdGVnb3J5IG9mIGludGVyZXN0IChzaWduaWZpY2FudCBpbiBNQU5PVkEpCgojIEFjaWRvYmFjdGVyaWEKdHVzc19tdF90YXhhX3N0YXRzMTwtYW92KEFjaWRvYmFjdGVyaWF+VGltZXBvaW50LGRhdGE9dHVzc19tdF90YXhhX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX210X3RheGFfc3RhdHMxKQpUdWtleUhTRCh0dXNzX210X3RheGFfc3RhdHMxKQoKIyBBY3Rpbm9iYWN0ZXJpYQp0dXNzX210X3RheGFfc3RhdHMyPC1hb3YoQWN0aW5vYmFjdGVyaWF+VGltZXBvaW50LGRhdGE9dHVzc19tdF90YXhhX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX210X3RheGFfc3RhdHMyKQpUdWtleUhTRCh0dXNzX210X3RheGFfc3RhdHMyKQpgYGAKCldldCBTZWRnZSBUdW5kcmEgVGF4b25vbXkgKFBoeWx1bSkgQU5PVkEKYGBge3IgZWNobz1GQUxTRX0Kd3NfbXRfdGF4YV9zdGF0czwtcmVhZC5jc3YoIlN0YXRzLkRhdGEvd3MubXQudGF4YS5hbm92YS5zdGF0cy5jc3YiKQpgYGAKCmBgYHtyfQojIFN1YnNldCByZXNwb25zZSB2YXJpYWJsZXMgZm9yIE1BTk9WQQp3c19tdF90YXhhX3N0YXRzJHJlc3BvbnNlIDwtIGFzLm1hdHJpeCh3c19tdF90YXhhX3N0YXRzWywgMjoxMl0pCmBgYAoKYGBge3J9CiMgTUFOT1ZBIHRlc3QKd3NfbXRfdGF4YV9zdGF0c19tYW5vdmEgPC0gbWFub3ZhKHJlc3BvbnNlIH4gVGltZXBvaW50LCBkYXRhPXdzX210X3RheGFfc3RhdHMpCnN1bW1hcnkuYW92KHdzX210X3RheGFfc3RhdHNfbWFub3ZhKQoKIyMgUnVuIEFOT1ZBIGZvciBlYWNoIGNhdGVnb3J5IG9mIGludGVyZXN0IChzaWduaWZpY2FudCBpbiBNQU5PVkEpCgojIEFjaWRvYmFjdGVyaWEKd3NfbXRfdGF4YV9zdGF0czE8LWFvdihBY2lkb2JhY3RlcmlhflRpbWVwb2ludCxkYXRhPXdzX210X3RheGFfc3RhdHMpCnN1bW1hcnkuYW92KHdzX210X3RheGFfc3RhdHMxKQpUdWtleUhTRCh3c19tdF90YXhhX3N0YXRzMSkKYGBgCjwvZGl2PgoKV2UgZnVydGhlciBpbnZlc3RpZ2F0ZSB3aGljaCBjbGFzc2VzIG9mIHRheGEgYXJlIGRyaXZpbmcgdGhlc2Ugc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgaW4gcmVsYXRpdmUgdGF4b24gYWJ1bmRhbmNlIG9ic2VydmVkIGF0IHRoZSBwaHlsdW0gbGV2ZWwgKHNlZSBhYm92ZSkuICBXZSByZXRhaW4gb25seSB0aG9zZSBjbGFzc2VzIG9mIGVhY2ggZG9taW5hbnQgcGh5bHVtIHdoZXJlIGF0IGxlYXN0IDEgc2FtcGxlIChvdXQgb2YgMTIpIGhhZCA+IDEuMCUgcmVsYXRpdmUgYWJ1bmRhbmNlICh0byBtYWtlIGJpb2xvZ2ljYWxseS1yZWxldmFudCBzdGF0aXN0aWNhbCBjb21wYXJpc29ucyBvZiB0aGUgZGF0YSkuCgpIZXJlLCB3ZSB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBtZWFuIHJlbGF0aXZlIGFidW5kYW5jZSBvZiBiaW9sb2dpY2FsbHktcmVsZXZhbnQgbWljcm9iaWFsIGNsYXNzZXMgd2l0aGluIGVhY2ggZG9taW5hbnQgcGh5bHVtIChpZGVudGlmaWVkIGFib3ZlKSBiZXR3ZWVuIHR1bmRyYSBlY29zeXN0ZW1zLgoKYGBge3IgZWNobz1GQUxTRX0KdGF4YS5jbGFzcy50LnRlc3Q8LXJlYWQuY3N2KCJTdGF0cy5EYXRhL3RheGEuY2xhc3MudC50ZXN0LmNzdiIpCmBgYAoKYGBge3J9CiMgUGFpcndpc2UgY29tcGFyaXNvbnMgYmV0d2VlbiB0dW5kcmEgZWNvc3lzdGVtcyBmb3IgZWFjaCBtaWNyb2JpYWwgdGF4b25vbWljIGNsYXNzCnRheGEuY2xhc3MudC50ZXN0LnN0YXRzIDwtIHRheGEuY2xhc3MudC50ZXN0ICU+JQogIGdyb3VwX2J5KENsYXNzKSAlPiUKICBwYWlyd2lzZV90X3Rlc3QoCiAgICBBYnVuZGFuY2UgfiBUdW5kcmEsIHBhaXJlZCA9IFRSVUUsIAogICAgcC5hZGp1c3QubWV0aG9kID0gImJvbmZlcnJvbmkiCiAgICApICU+JQogIHNlbGVjdCgtLnkuLCAtZ3JvdXAxLCAtZ3JvdXAyLCAtbjEsIC1uMiwgLWRmLCAtc3RhdGlzdGljLCAtcCkKdGF4YS5jbGFzcy50LnRlc3Quc3RhdHMKYGBgCgpIZXJlLCB3ZSBzZXBhcmF0ZSB0aGVzZSB0YXhhIGJ5IHR1bmRyYSBlY29zeXN0ZW0gYW5kIGxvb2sgZm9yIGRpZmZlcmVuY2VzIGJldHdlZW4gc2FtcGxpbmcgdGltZSBwb2ludCBvdmVyIHRoZSBjb3Vyc2Ugb2YgdGhlIHN0dWR5LgoKQ2xpY2sgb24gdGhlICoqU2hvdy9IaWRlKiogYnV0dG9uIHRvIHNlZSB0aGUgc3RhdGlzdGljcy4KCjxidXR0b24gY2xhc3M9ImJ0biBidG4tcHJpbWFyeSIgZGF0YS10b2dnbGU9ImNvbGxhcHNlIiBkYXRhLXRhcmdldD0iI0Jsb2NrTmFtZTk3Ij4gU2hvdy9IaWRlIDwvYnV0dG9uPiAgCjxkaXYgaWQ9IkJsb2NrTmFtZTk3IiBjbGFzcz0iY29sbGFwc2UiPgoKVHVzc29jayBUdW5kcmEgVGF4b25vbXkgKEFsbCBMZXZlbHMpIEFOT1ZBCmBgYHtyIGVjaG89RkFMU0V9CnR1c3NfbXRfYWxsX3RheGFfc3RhdHM8LXJlYWQuY3N2KCJTdGF0cy5EYXRhL3R1c3MubXQudGF4YS5hbGwuYW5vdmEuc3RhdHMuY3N2IikKYGBgCgpgYGB7cn0KIyBTdWJzZXQgcmVzcG9uc2UgdmFyaWFibGVzIGZvciBNQU5PVkEKdHVzc19tdF9hbGxfdGF4YV9zdGF0cyRyZXNwb25zZSA8LSBhcy5tYXRyaXgodHVzc19tdF9hbGxfdGF4YV9zdGF0c1ssIDI6NDRdKQpgYGAKCmBgYHtyfQojIE1BTk9WQSB0ZXN0CnR1c3NfbXRfYWxsX3RheGFfc3RhdHNfbWFub3ZhIDwtIG1hbm92YShyZXNwb25zZSB+IFRpbWVwb2ludCwgZGF0YT10dXNzX210X2FsbF90YXhhX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX210X2FsbF90YXhhX3N0YXRzX21hbm92YSkKCiMjIFJ1biBBTk9WQSBmb3IgZWFjaCBjYXRlZ29yeSBvZiBpbnRlcmVzdCAoc2lnbmlmaWNhbnQgaW4gTUFOT1ZBKQoKIyBBY2lkb2JhY3RlcmlhCiN0dXNzX210X3RheGFfc3RhdHMxPC1hb3YoQWNpZG9iYWN0ZXJpYX5UaW1lcG9pbnQsZGF0YT10dXNzX210X3RheGFfc3RhdHMpCiNzdW1tYXJ5LmFvdih0dXNzX210X3RheGFfc3RhdHMxKQojVHVrZXlIU0QodHVzc19tdF90YXhhX3N0YXRzMSkKCiMgQWN0aW5vYmFjdGVyaWEKI3R1c3NfbXRfdGF4YV9zdGF0czI8LWFvdihBY3Rpbm9iYWN0ZXJpYX5UaW1lcG9pbnQsZGF0YT10dXNzX210X3RheGFfc3RhdHMpCiNzdW1tYXJ5LmFvdih0dXNzX210X3RheGFfc3RhdHMyKQojVHVrZXlIU0QodHVzc19tdF90YXhhX3N0YXRzMikKYGBgCgpXZXQgU2VkZ2UgVHVuZHJhIFRheG9ub215IChQaHlsdW0pIEFOT1ZBCmBgYHtyIGVjaG89RkFMU0V9CndzX210X2FsbF90YXhhX3N0YXRzPC1yZWFkLmNzdigiU3RhdHMuRGF0YS93cy5tdC50YXhhLmFsbC5hbm92YS5zdGF0cy5jc3YiKQpgYGAKCmBgYHtyfQojIFN1YnNldCByZXNwb25zZSB2YXJpYWJsZXMgZm9yIE1BTk9WQQp3c19tdF9hbGxfdGF4YV9zdGF0cyRyZXNwb25zZSA8LSBhcy5tYXRyaXgod3NfbXRfYWxsX3RheGFfc3RhdHNbLCAyOjQ0XSkKYGBgCgpgYGB7cn0KIyBNQU5PVkEgdGVzdAp3c19tdF9hbGxfdGF4YV9zdGF0c19tYW5vdmEgPC0gbWFub3ZhKHJlc3BvbnNlIH4gVGltZXBvaW50LCBkYXRhPXdzX210X2FsbF90YXhhX3N0YXRzKQpzdW1tYXJ5LmFvdih3c19tdF9hbGxfdGF4YV9zdGF0c19tYW5vdmEpCgojIyBSdW4gQU5PVkEgZm9yIGVhY2ggY2F0ZWdvcnkgb2YgaW50ZXJlc3QgKHNpZ25pZmljYW50IGluIE1BTk9WQSkKCiMgQWNpZG9iYWN0ZXJpYQojd3NfbXRfdGF4YV9zdGF0czE8LWFvdihBY2lkb2JhY3RlcmlhflRpbWVwb2ludCxkYXRhPXdzX210X3RheGFfc3RhdHMpCiNzdW1tYXJ5LmFvdih3c19tdF90YXhhX3N0YXRzMSkKI1R1a2V5SFNEKHdzX210X3RheGFfc3RhdHMxKQpgYGAKPC9kaXY+CgpBbHBoYSBEaXZlcnNpdHkKYGBge3IgZWNobz1GQUxTRX0KYWxwaGEucm5hLnRheGE8LXJlYWQuY3N2KCJTdGF0cy5EYXRhL0FMUEhBLnRheGEucm5hLnNzdS5jc3YiKQoKcm93bmFtZXMoYWxwaGEucm5hLnRheGEpIDwtIGFscGhhLnJuYS50YXhhJElECmFscGhhLnJuYS50YXhhWzFdIDwtIE5VTEwKYGBgCgpgYGB7cn0KIyBSaWNobmVzczogU3VtIHVwIHRoZSBudW1iZXIgb2Ygbm9uLXplcm8gZW50cmllcyBwZXIgcm93CmFscGhhLnJuYS50YXhhLnJpY2ggPC0gYXBwbHkoYWxwaGEucm5hLnRheGE+MCwxLHN1bSkKd3JpdGUuY3N2KGFscGhhLnJuYS50YXhhLnJpY2gsICdSaWJvLlJlc3VsdHMvYWxwaGEucm5hLnRheGEucmljaC5jc3YnKQoKIyBBYnVuZGFuY2U6IHN1bSB1cCB0aGUgbnVtYmVyIG9mIG5vbi16ZXJvIGVudHJpZXMgcGVyIHJvdyAoMSkKYWxwaGEucm5hLnRheGEuYWJ1bmQgPC0gYXBwbHkoYWxwaGEucm5hLnRheGEsMSxzdW0pCndyaXRlLmNzdihhbHBoYS5ybmEudGF4YS5hYnVuZCwgJ1JpYm8uUmVzdWx0cy9hbHBoYS5ybmEudGF4YS5hYnVuZC5jc3YnKQoKIyBEaXZlcnNpdHk6IFNoYW5ub24tV2llbmVyIEluZGV4IChIJykKYWxwaGEucm5hLnRheGEuZGl2IDwtIGRpdmVyc2l0eShhbHBoYS5ybmEudGF4YSwgaW5kZXg9InNoYW5ub24iKQp3cml0ZS5jc3YoYWxwaGEucm5hLnRheGEuZGl2LCAnUmliby5SZXN1bHRzL2FscGhhLnJuYS50YXhhLmRpdi5jc3YnKQpgYGAKCmBgYHtyIGVjaG89RkFMU0V9CmFscGhhLnJuYS50YXhhLnQudGVzdDwtcmVhZC5jc3YoIlN0YXRzLkRhdGEvYWxwaGEucm5hLnRheGEudC50ZXN0LmNzdiIpCmBgYAoKUnVuIHBhaXJlZCB0LXRlc3QgdG8gZGV0ZXJtaW5lIHNpZ25pZmljYW5jZS4KYGBge3J9CnQudGVzdChhbHBoYS5ybmEudGF4YS50LnRlc3QkVHVzcyxhbHBoYS5ybmEudGF4YS50LnRlc3QkV1MscGFpcmVkPVRSVUUpCmBgYAoKQmV0YSBEaXZlcnNpdHkKCkNhbGN1bGF0ZSB0aGUgQnJheS1DdXJ0aXMgZGlzc2ltaWxhcml0eSBtYXRyaXggdG8gdXNlIHdpdGggYGFkb25pc2AKCmBgYHtyIGVjaG89RkFMU0V9CmJldGEucm5hLnRheGE8LXJlYWQuY3N2KCJTdGF0cy5EYXRhL0FMUEhBLnRheGEucm5hLnNzdS5jc3YiKQoKcm93bmFtZXMoYmV0YS5ybmEudGF4YSkgPC0gYmV0YS5ybmEudGF4YSRJRApiZXRhLnJuYS50YXhhWzFdIDwtIE5VTEwKYGBgCgpgYGB7cn0KIyBNYWtlIHRwbV9hbGxfZ3JvdXBzIG9iamVjdApiZXRhLnJuYS50YXhhX3NhbXBsZTwtYygid3MxLVQwIiwid3MzLVQwIiwidHVzczEtVDAiLCJ0dXNzMi1UMCIsIndzMS1UNCIsIndzMi1UNCIsIndzMS1UMjQiLCJ3czMtVDI0IiwidHVzczEtVDQiLCJ0dXNzMi1UNCIsInR1c3MxLVQyNCIsInR1c3MzLVQyNCIpCmJldGEucm5hLnRheGFfdmVnPC1jKCJXUyIsIldTIiwiVFVTUyIsIlRVU1MiLCJXUyIsIldTIiwiV1MiLCJXUyIsIlRVU1MiLCJUVVNTIiwiVFVTUyIsIlRVU1MiKQpiZXRhLnJuYS50YXhhX3RpbWU8LWMoIlQwIiwiVDAiLCJUMCIsIlQwIiwiVDQiLCJUNCIsIlQyNCIsIlQyNCIsIlQ0IiwiVDQiLCJUMjQiLCJUMjQiKQpiZXRhLnJuYS50YXhhX2dyb3VwczwtZGF0YS5mcmFtZShiZXRhLnJuYS50YXhhX3NhbXBsZSxiZXRhLnJuYS50YXhhX3ZlZyxiZXRhLnJuYS50YXhhX3RpbWUpCgojIENvbnZlcnQgdGhlIHZhbHVlcyBpbiBDb2x1bW4gMSAoInRwbV9zYW1wbGUiKSBpbnRvIHJvdyBuYW1lcwpyb3duYW1lcyhiZXRhLnJuYS50YXhhX2dyb3Vwcyk8LWJldGEucm5hLnRheGFfZ3JvdXBzWywxXQpiZXRhLnJuYS50YXhhX2dyb3VwczwtYmV0YS5ybmEudGF4YV9ncm91cHNbLC0xXQpgYGAKCmBgYHtyfQojIEJyYXktQ3VydGlzIERpc3NpbWlsYXJpdHkgTWF0cml4IGZvciB0cG1fYWxsX3RheGFfYmV0YQpybmEudHBtLnRheGEuYmMuZGlzdDwtdmVnZGlzdChiZXRhLnJuYS50YXhhLCBtZXRob2QgPSAiYnJheSIpCmBgYAoKUnVuIFBFUk1BTk9WQSB1c2luZyBgYWRvbmlzYCBmdW5jdGlvbiBvZiB0aGUgKipWZWdhbioqIHBhY2thZ2UKClBFUk1BTk9WQSAtIE1ULVRQTS1UYXhhIC0gQnJheS1DdXJ0aXMKYGBge3J9CmFkb25pcyhybmEudHBtLnRheGEuYmMuZGlzdH5iZXRhLnJuYS50YXhhX3ZlZypiZXRhLnJuYS50YXhhX3RpbWUsIGRhdGE9YmV0YS5ybmEudGF4YV9ncm91cHMpCmBgYAoKIyMjIDcuMi4gR2VuZSBEaXZlcnNpdHkKCkFscGhhIGRpdmVyc2l0eSBvZiBlYWNoIGV4cHJlc3NlZCwgYW5ub3RhdGVkIG1ldGF0cmFuc2NyaXB0b21lIHdhcyBhc3Nlc3NlZCBieSB0aGUgU2hhbm5vbiBpbmRleC4gRm9yIGJldGEgZGl2ZXJzaXR5LCBwYWlyd2lzZSBzaW1pbGFyaXRpZXMgYW1vbmcgbWV0YXRyYW5zY3JpcHRvbWVzIHdlcmUgY2FsY3VsYXRlZCB1c2luZyBCcmF5LUN1cnRpcyBzaW1pbGFyaXR5IHZhbHVlcyBhbmQgdmlzdWFsaXplZCB3aXRoIHByaW5jaXBsZSBjb29yZGluYXRlcyBhbmFseXNpcy4gVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0cmVhdG1lbnRzIHdhcyBhc3Nlc3NlZCB3aXRoIFBFUk1BTk9WQS4KCiMjIyMgNy4yLjEuIEFscGhhIERpdmVyc2l0eQoKV2UgY2FsY3VsYXRlZCBhbHBoYSBkaXZlcnNpdHkgYmFzZWQgb24gcmF3IGdlbmUgY291bnRzLiAgTWVhc3VyZW1lbnRzIGluY2x1ZGUgKipSaWNobmVzcyoqLCAqKkFidW5kYW5jZSoqLCBhbmQgKipTaGFubm9uLVdpZW5lciBEaXZlcnNpdHkgSW5kZXggKEgnKSoqLgoKYGBge3J9CiMgU3Vic2V0IHRoZSB0cG1fYWxsX2V4cF9hbm4gZmlsZSB0byBwcmVwYXJlIGZvciBiZXRhIGRpdmVyc2l0eSBhbmFseXNpcwpjdHNfcm5hX2FsbF9hbHBoYTwtc3Vic2V0KGN0c19ybmFfZXhwX2Fubm90YXRlZCwgc2VsZWN0PWMoUzEwODM3OSxTMTA4MzgxLFMxMDgzODIsUzEwODM4MyxTMTA4Mzg1LFMxMDgzODYsUzEwODM4OCxTMTA4MzkwLFMxMDgzOTEsUzEwODM5MixTMTA4Mzk0LFMxMDgzOTYpKQpuYW1lcyhjdHNfcm5hX2FsbF9hbHBoYSk8LWMoIldTMS1UMCIsIldTMy1UMCIsIlR1c3MxLVQwIiwiVHVzczItVDAiLCJXUzEtVDQiLCJXUzItVDQiLCJXUzEtVDI0IiwiV1MzLVQyNCIsIlR1c3MxLVQ0IiwiVHVzczItVDQiLCJUdXNzMS1UMjQiLCJUdXNzMy1UMjQiKQoKIyBUcmFuc3Bvc2UgYWxsIGJ1dCB0aGUgZmlyc3QgY29sdW1uICgiSUQiKQpjdHNfcm5hX2FsbF9hbHBoYTwtYXMuZGF0YS5mcmFtZSh0KGN0c19ybmFfYWxsX2FscGhhKSkKYGBgCgoqKlJpY2huZXNzOioqIERldGVybWluZSB0aGUgbnVtYmVyIG9mIHVuaXF1ZSBnZW5lY2FsbHMgdGhhdCBoYXZlIG1vcmUgdGhhbiBvbmUgY291bnQgcmVjb3JkZWQgd2l0aGluIGVhY2ggc2FtcGxlLgoKYGBge3J9CiMgU3VtIHVwIHRoZSBudW1iZXIgb2Ygbm9uLXplcm8gZW50cmllcyBwZXIgcm93CmFwcGx5KGN0c19ybmFfYWxsX2FscGhhPjAsMSxzdW0pCmBgYAoKKipBYnVuZGFuY2U6KiogRGV0ZXJtaW5lIHRoZSB0b3RhbCBhYnVuZGFuY2Ugb2YgaW5kaXZpZHVhbCBnZW5lY2FsbHMKCmBgYHtyfQojIHN1bSB1cCB0aGUgbnVtYmVyIG9mIG5vbi16ZXJvIGVudHJpZXMgcGVyIHJvdyAoMSkKYXBwbHkoY3RzX3JuYV9hbGxfYWxwaGEsMSxzdW0pCmBgYAoKKipTaGFubm9uLVdpZW5lciBEaXZlcnNpdHkgSW5kZXggKEgnKToqKiBBbiBpbmZvcm1hdGlvbiBpbmRleCB0aGF0IHF1YW50aWZpZXMgdGhlIHVuY2VydGFpbnR5IGFzc29jaWF0ZWQgd2l0aCBwcmVkaWN0aW5nIHRoZSBpZGVudGl0eSBvZiBhIG5ldyBnZW5lY2FsbCBnaXZlbiB0aGUgdG90YWwgbnVtYmVyIG9mIGdlbmVjYWxscyBhbmQgdGhlIGV2ZW5uZXNzIGluIGNvdW50IGFidW5kYW5jZXMgd2l0aGluIGVhY2ggZ2VuZWNhbGwuCgpgYGB7cn0KZGl2ZXJzaXR5KGN0c19ybmFfYWxsX2FscGhhLCBpbmRleD0ic2hhbm5vbiIpCmBgYAoKVGhlIGZvbGxvd2luZyB0YWJsZSBpcyBhIHN1bW1hcnkgb2YgdGhlICoqQWxwaGEgRGl2ZXJzaXR5Kiogb24gdGhlIHJhdyBnZW5lIGNvdW50cyBmb3IgdGhlICoqRXhwcmVzc2VkIEFubm90YXRlZCBHZW5lcyoqICgqZXhwcmVzc2VkIGFubm90YXRlZCBnZW5lcyBmb3IgZG93bnN0cmVhbSBhbmFseXNlcyopIGJ5IHNhbXBsZS4KCmBgYHtyIGVjaG89RkFMU0V9CnJuYS5leHBlcmltZW50PC1yZWFkLnRhYmxlKCJUYWJsZS5EYXRhL3JuYS5hbHBoYS5zdW1tYXJ5LnRhYmxlLnR4dCIsc2VwPSdcdCcsIHF1b3RlPSIiLCBmaWxsPVRSVUUsaGVhZGVyID0gVFJVRSkKbmFtZXMocm5hLmV4cGVyaW1lbnQpPC1jKCJJRCIsICJUdW5kcmEiLCAiVGltZSIsICJSZXBsaWNhdGUiLCAiR2VuZSBSaWNobmVzcyIsIkdlbmUgQWJ1bmRhbmNlIiwiR2VuZSBEaXZlcnNpdHkgKEgnKSIpCmthYmxlKHJuYS5leHBlcmltZW50LCBjYXB0aW9uID0gIkFscGhhIERpdmVyc2l0eSBmb3IgRXhwcmVzc2VkIEFubm90YXRlZCBHZW5lY2FsbHMgaW4gdGhlIFJOQS1iYXNlZCBtZXRhdHJhbnNjcmlwdG9tZSBzZXF1ZW5jaW5nIGRhdGFzZXQiLCBmb3JtYXQuYXJncyA9IGxpc3QoYmlnLm1hcmsgPSAiLCIpLCBhbGlnbiA9ICJjIikgJT4lIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpKQpgYGAKCmBgYHtyIGVjaG89RkFMU0V9CmFscGhhLnQudGVzdDwtcmVhZC5jc3YoIlN0YXRzLkRhdGEvYWxwaGEudC50ZXN0LmNzdiIpCmBgYAoKUnVuIHBhaXJlZCB0LXRlc3QgdG8gZGV0ZXJtaW5lIHNpZ25pZmljYW5jZS4KYGBge3J9CnQudGVzdChhbHBoYS50LnRlc3QkVHVzcyxhbHBoYS50LnRlc3QkV1MscGFpcmVkPVRSVUUpCmBgYAoKUGxvdCB0aGUgQWxwaGEgRGl2ZXJzaXR5IHN1bW1hcnkuCgpgYGB7ciBlY2hvPUZBTFNFfQphbHBoYTwtcmVhZC5jc3YoIlBsb3QuRGF0YS9hbHBoYS5ib3hwbG90LmNzdiIpCmBgYAoKYGBge3J9CiMgUmUtYXJyYW5nZSBzYW1wbGVzIGZvciBwbG90dGluZyBQQ29BCmFscGhhJFR1bmRyYSA8LSBmYWN0b3IoYWxwaGEkVHVuZHJhLCBsZXZlbHM9YygiVHVzcy1NVC1UMCIsIlR1c3MtTVQtVDQiLCJUdXNzLU1ULVQyNCIsIldTLU1ULVQwIiwiV1MtTVQtVDQiLCJXUy1NVC1UMjQiKSkKCmFscGhhLmJveHBsb3Q8LWdncGxvdChhbHBoYSwgYWVzKHg9VHVuZHJhLCB5PUgsIGZpbGw9VHVuZHJhKSkgKyAKICAgIGdlb21fYm94cGxvdCgpICsgeWxhYihleHByZXNzaW9uKGF0b3AoIlNoYW5ub24tV2llbmVyIiwgcGFzdGUoIkRpdmVyc2l0eSBJbmRleCAoSCcpIikpKSkgKyB0aGVtZV9jbGFzc2ljKCkgKyB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDI3MCwgaGp1c3Q9MCwgdmp1c3Q9MC41KSwgYXhpcy50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xMiksIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApKSArIHlsaW0oOSwxMikgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0zLjUsIHk9MTEuOSwgbGFiZWw9IlBhaXJlZCB0LXRlc3QiKSArIGFubm90YXRlKCJ0ZXh0IiwgeD0zLjUsIHk9MTEuNywgc2l6ZT0zLCBsYWJlbCA9ICJUdW5kcmF+KGl0YWxpYyhwKSA8IDAuMDAxKSIsIHBhcnNlID0gVFJVRSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygicGFsZWdyZWVuIiwgImdyZWVuMyIsICJkYXJrZ3JlZW4iLCAibGlnaHRza3libHVlMSIsICJkb2RnZXJibHVlMSIsICJtaWRuaWdodGJsdWUiKSwgYnJlYWtzPWMoIlR1c3MtTUctVDAiLCAiV1MtTUctVDAiLCAiVHVzcy1NRy1UNCIsICJXUy1NRy1UNCIsICJUdXNzLU1HLVQyNCIsICJXUy1NRy1UMjQiKSwgbGFiZWxzPWMoIlR1c3MtTUctVDAiLCAiV1MtTUctVDAiLCAiVHVzcy1NRy1UNCIsICJXUy1NRy1UNCIsICJUdXNzLU1HLVQyNCIsICJXUy1NRy1UMjQiKSkKYGBgCgpgYGB7cn0KYWxwaGEuYm94cGxvdApgYGAKCiMjIyMgNy4yLjIuIEJldGEgRGl2ZXJzaXR5CgpXZSBjYWxjdWxhdGVkIGJldGEgZGl2ZXJzaXR5IGFzIHRoZSB2YXJpYXRpb24gaW4gZ2VuZSBleHByZXNzaW9uIGJldHdlZW4gb3VyIHR3byB0dW5kcmEgZWNvc3lzdGVtcyB1c2luZyBCcmF5LUN1cnRpcyBzaW1pbGFyaXR5IHZhbHVlcy4KCiMjIyMjIDcuMi4yLjEuIFN1YnNldCBEYXRhCgpGaXJzdCwgc3Vic2V0IHRoZSBjb2x1bW5zIG9mIGludGVyZXN0IGZyb20gdGhlICoqdHBtX2FsbF9leHBfYW5uKiogb2JqZWN0IChJRCBhbmQgYWxsIHNhbXBsZXMpIHRvIGFuYWx5emUgdGhlIGJldGEgZGl2ZXJzaXR5IG9mIGJvdGggZWNvc3lzdGVtcyB0b2dldGhlci4gQ3JlYXRlIGEgKip0cG1fZ3JvdXBzKiogb2JqZWN0IHdpdGggY29sdW1ucyBmb3Igc2FtcGxlIElELCB2ZWdldGF0aW9uIHR5cGUsIGFuZCB0aW1lcG9pbnQgdG8gYmUgdXNlZCBmb3IgY2FsY3VsYXRpbmcgcGFpcndpc2Ugc2ltaWxpYXJpdGllcyBhbW9uZyBzYW1wbGVzIHZpYSBQRVJNQU5PVkEgKCpgYWRvbmlzYCBmcm9tICoqVmVnYW4qKiBwYWNrYWdlKikKCmBgYHtyfQojIFN1YnNldCB0aGUgdHBtX2FsbF9leHBfYW5uIGZpbGUgdG8gcHJlcGFyZSBmb3IgYmV0YSBkaXZlcnNpdHkgYW5hbHlzaXMKdHBtX2FsbF9iZXRhPC1zdWJzZXQodHBtX2FsbF9leHBfYW5uLCBzZWxlY3Q9YyhJRCxTMTA4Mzc5LFMxMDgzODEsUzEwODM4MixTMTA4MzgzLFMxMDgzODUsUzEwODM4NixTMTA4Mzg4LFMxMDgzOTAsUzEwODM5MSxTMTA4MzkyLFMxMDgzOTQsUzEwODM5NikpCm5hbWVzKHRwbV9hbGxfYmV0YSk8LWMoIklEIiwiV1MxLVQwIiwiV1MzLVQwIiwiVHVzczEtVDAiLCJUdXNzMi1UMCIsIldTMS1UNCIsIldTMi1UNCIsIldTMS1UMjQiLCJXUzMtVDI0IiwiVHVzczEtVDQiLCJUdXNzMi1UNCIsIlR1c3MxLVQyNCIsIlR1c3MzLVQyNCIpCgojIFJlbWVtYmVyICJJRCIgY29sdW1uIGFzIG5vbi1udW1lcmljIHZhbHVlcwp0cG1fYWxsX2JldGFfSUQ8LXRwbV9hbGxfYmV0YSRJRAoKIyBUcmFuc3Bvc2UgYWxsIGJ1dCB0aGUgZmlyc3QgY29sdW1uICgiSUQiKQp0cG1fYWxsX2JldGE8LWFzLmRhdGEuZnJhbWUodCh0cG1fYWxsX2JldGFbLC0xXSkpCmNvbG5hbWVzKHRwbV9hbGxfYmV0YSk8LXRwbV9hbGxfYmV0YV9JRAoKIyBNYWtlIHRwbV9hbGxfZ3JvdXBzIG9iamVjdAp0cG1fYWxsX3NhbXBsZTwtYygiV1MxLVQwIiwiV1MzLVQwIiwiVHVzczEtVDAiLCJUdXNzMi1UMCIsIldTMS1UNCIsIldTMi1UNCIsIldTMS1UMjQiLCJXUzMtVDI0IiwiVHVzczEtVDQiLCJUdXNzMi1UNCIsIlR1c3MxLVQyNCIsIlR1c3MzLVQyNCIpCnRwbV9hbGxfdmVnPC1jKCJXUyIsIldTIiwiVFVTUyIsIlRVU1MiLCJXUyIsIldTIiwiV1MiLCJXUyIsIlRVU1MiLCJUVVNTIiwiVFVTUyIsIlRVU1MiKQp0cG1fYWxsX3RpbWU8LWMoIlQwIiwiVDAiLCJUMCIsIlQwIiwiVDQiLCJUNCIsIlQyNCIsIlQyNCIsIlQ0IiwiVDQiLCJUMjQiLCJUMjQiKQp0cG1fYWxsX2dyb3VwczwtZGF0YS5mcmFtZSh0cG1fYWxsX3NhbXBsZSx0cG1fYWxsX3ZlZyx0cG1fYWxsX3RpbWUpCgojIENvbnZlcnQgdGhlIHZhbHVlcyBpbiBDb2x1bW4gMSAoInRwbV9zYW1wbGUiKSBpbnRvIHJvdyBuYW1lcwpyb3duYW1lcyh0cG1fYWxsX2dyb3Vwcyk8LXRwbV9hbGxfZ3JvdXBzWywxXQp0cG1fYWxsX2dyb3VwczwtdHBtX2FsbF9ncm91cHNbLC0xXQpgYGAKClNlY29uZCwgc3Vic2V0IHRoZSBjb2x1bW5zIG9mIGludGVyZXN0IGZyb20gdGhlICoqdHBtX3dzX2V4cF9hbm4qKiBvYmplY3QgKElEIGFuZCBhbGwgc2FtcGxlcykgdG8gYW5hbHl6ZSB0aGUgYmV0YSBkaXZlcnNpdHkgb2YgdGhlIFdldCBTZWRnZSBlY29zeXN0ZW0KCmBgYHtyfQojIFN1YnNldCB0aGUgdHBtX3dzX2V4cF9hbm4gZmlsZSB0byBwcmVwYXJlIGZvciBiZXRhIGRpdmVyc2l0eSBhbmFseXNpcwp0cG1fd3NfYmV0YTwtc3Vic2V0KHRwbV9hbGxfZXhwX2Fubiwgc2VsZWN0PWMoSUQsUzEwODM3OSxTMTA4MzgxLFMxMDgzODUsUzEwODM4NixTMTA4Mzg4LFMxMDgzOTApKQpuYW1lcyh0cG1fd3NfYmV0YSk8LWMoIklEIiwiV1MxLVQwIiwiV1MzLVQwIiwiV1MxLVQ0IiwiV1MyLVQ0IiwiV1MxLVQyNCIsIldTMy1UMjQiKQoKIyBSZW1lbWJlciAiSUQiIGNvbHVtbiBhcyBub24tbnVtZXJpYyB2YWx1ZXMKdHBtX3dzX2JldGFfSUQ8LXRwbV93c19iZXRhJElECgojIFRyYW5zcG9zZSBhbGwgYnV0IHRoZSBmaXJzdCBjb2x1bW4gKCJJRCIpCnRwbV93c19iZXRhPC1hcy5kYXRhLmZyYW1lKHQodHBtX3dzX2JldGFbLC0xXSkpCmNvbG5hbWVzKHRwbV93c19iZXRhKTwtdHBtX3dzX2JldGFfSUQKCiMgTWFrZSB0cG1fd3NfZ3JvdXBzIG9iamVjdAp0cG1fd3Nfc2FtcGxlPC1jKCJXUzEtVDAiLCJXUzMtVDAiLCJXUzEtVDQiLCJXUzItVDQiLCJXUzEtVDI0IiwiV1MzLVQyNCIpCnRwbV93c192ZWc8LWMoIldTIiwiV1MiLCJXUyIsIldTIiwiV1MiLCJXUyIpCnRwbV93c190aW1lPC1jKCJUMCIsIlQwIiwiVDQiLCJUNCIsIlQyNCIsIlQyNCIpCnRwbV93c19ncm91cHM8LWRhdGEuZnJhbWUodHBtX3dzX3NhbXBsZSx0cG1fd3NfdmVnLHRwbV93c190aW1lKQoKIyBDb252ZXJ0IHRoZSB2YWx1ZXMgaW4gQ29sdW1uIDEgKCJ0cG1fc2FtcGxlIikgaW50byByb3cgbmFtZXMKcm93bmFtZXModHBtX3dzX2dyb3Vwcyk8LXRwbV93c19ncm91cHNbLDFdCnRwbV93c19ncm91cHM8LXRwbV93c19ncm91cHNbLC0xXQpgYGAKClRoaXJkLCBzdWJzZXQgdGhlIGNvbHVtbnMgb2YgaW50ZXJlc3QgZnJvbSB0aGUgKip0cG1fdHVzc19leHBfYW5uKiogb2JqZWN0IChJRCBhbmQgYWxsIHNhbXBsZXMpIHRvIGFuYWx5emUgdGhlIGJldGEgZGl2ZXJzaXR5IG9mIHRoZSBUdXNzb2NrIGVjb3N5c3RlbQoKYGBge3J9CiMgU3Vic2V0IHRoZSB0cG1fdHVzc19leHBfYW5uIGZpbGUgdG8gcHJlcGFyZSBmb3IgYmV0YSBkaXZlcnNpdHkgYW5hbHlzaXMKdHBtX3R1c3NfYmV0YTwtc3Vic2V0KHRwbV9hbGxfZXhwX2Fubiwgc2VsZWN0PWMoSUQsUzEwODM4MixTMTA4MzgzLFMxMDgzOTEsUzEwODM5MixTMTA4Mzk0LFMxMDgzOTYpKQpuYW1lcyh0cG1fdHVzc19iZXRhKTwtYygiSUQiLCJUdXNzMS1UMCIsIlR1c3MyLVQwIiwiVHVzczEtVDQiLCJUdXNzMi1UNCIsIlR1c3MxLVQyNCIsIlR1c3MzLVQyNCIpCgojIFJlbWVtYmVyICJJRCIgY29sdW1uIGFzIG5vbi1udW1lcmljIHZhbHVlcwp0cG1fdHVzc19iZXRhX0lEPC10cG1fdHVzc19iZXRhJElECgojIFRyYW5zcG9zZSBhbGwgYnV0IHRoZSBmaXJzdCBjb2x1bW4gKCJJRCIpCnRwbV90dXNzX2JldGE8LWFzLmRhdGEuZnJhbWUodCh0cG1fdHVzc19iZXRhWywtMV0pKQpjb2xuYW1lcyh0cG1fdHVzc19iZXRhKTwtdHBtX3R1c3NfYmV0YV9JRAoKIyBNYWtlIHRwbV90dXNzX2dyb3VwcyBvYmplY3QKdHBtX3R1c3Nfc2FtcGxlPC1jKCJUdXNzMS1UMCIsIlR1c3MyLVQwIiwiVHVzczEtVDQiLCJUdXNzMi1UNCIsIlR1c3MxLVQyNCIsIlR1c3MzLVQyNCIpCnRwbV90dXNzX3ZlZzwtYygiVFVTUyIsIlRVU1MiLCJUVVNTIiwiVFVTUyIsIlRVU1MiLCJUVVNTIikKdHBtX3R1c3NfdGltZTwtYygiVDAiLCJUMCIsIlQ0IiwiVDQiLCJUMjQiLCJUMjQiKQp0cG1fdHVzc19ncm91cHM8LWRhdGEuZnJhbWUodHBtX3R1c3Nfc2FtcGxlLHRwbV90dXNzX3ZlZyx0cG1fdHVzc190aW1lKQoKIyBDb252ZXJ0IHRoZSB2YWx1ZXMgaW4gQ29sdW1uIDEgKCJ0cG1fc2FtcGxlIikgaW50byByb3cgbmFtZXMKcm93bmFtZXModHBtX3R1c3NfZ3JvdXBzKTwtdHBtX3R1c3NfZ3JvdXBzWywxXQp0cG1fdHVzc19ncm91cHM8LXRwbV90dXNzX2dyb3Vwc1ssLTFdCmBgYAoKIyMjIyMgNy4yLjIuMi4gQnJheS1DdXJ0aXMKCkNhbGN1bGF0ZSB0aGUgQnJheS1DdXJ0aXMgZGlzc2ltaWxhcml0eSBtYXRyaXggdG8gdXNlIHdpdGggYGFkb25pc2AKCmBgYHtyfQojIEJyYXktQ3VydGlzIERpc3NpbWlsYXJpdHkgTWF0cml4IGZvciB0cG1fYWxsX2JldGEKdHBtLmFsbC5iYy5kaXN0PC12ZWdkaXN0KHRwbV9hbGxfYmV0YSwgbWV0aG9kID0gImJyYXkiKQoKIyBCcmF5LUN1cnRpcyBEaXNzaW1pbGFyaXR5IE1hdHJpeCBmb3IgdHBtX3dzX2JldGEKdHBtLndzLmJjLmRpc3Q8LXZlZ2Rpc3QodHBtX3dzX2JldGEsIG1ldGhvZCA9ICJicmF5IikKCiMgQnJheS1DdXJ0aXMgRGlzc2ltaWxhcml0eSBNYXRyaXggZm9yIHRwbV90dXNzX2JldGEKdHBtLnR1c3MuYmMuZGlzdDwtdmVnZGlzdCh0cG1fdHVzc19iZXRhLCBtZXRob2QgPSAiYnJheSIpCmBgYAoKIyMjIyMgNy4yLjIuMy4gUENvQSBQbG90cwoKUHJpbmNpcGFsIGNvb3JkaW5hdGVzIGFuYWx5c2lzIChQQ29BLCBhbHNvIGtub3duIGFzIG1ldHJpYyBtdWx0aWRpbWVuc2lvbmFsIHNjYWxpbmcpIGF0dGVtcHRzIHRvIHJlcHJlc2VudCB0aGUgZGlzdGFuY2VzIGJldHdlZW4gc2FtcGxlcyBpbiBhIGxvdy1kaW1lbnNpb25hbCwgRXVjbGlkZWFuIHNwYWNlLiBJbiBwYXJ0aWN1bGFyLCBpdCBtYXhpbWl6ZXMgdGhlIGxpbmVhciBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSBkaXN0YW5jZXMgaW4gdGhlIGRpc3RhbmNlIG1hdHJpeCwgYW5kIHRoZSBkaXN0YW5jZXMgaW4gYSBzcGFjZSBvZiBsb3cgZGltZW5zaW9uICh0eXBpY2FsbHksIDIgb3IgMyBheGVzIGFyZSBzZWxlY3RlZCkuCgpUaGUgZmlyc3Qgc3RlcCBvZiBhIFBDb0EgaXMgdGhlIGNvbnN0cnVjdGlvbiBvZiBhIChkaXMpc2ltaWxhcml0eSBtYXRyaXguIFdoaWxlIFBDQSAocHJpbmNpcGFsIGNvbXBvbmVudCBhbmFseXNpcykgaXMgYmFzZWQgb24gRXVjbGlkZWFuIGRpc3RhbmNlcywgUENvQSBjYW4gaGFuZGxlIChkaXMpc2ltaWxhcml0eSBtYXRyaWNlcyBjYWxjdWxhdGVkIGZyb20gcXVhbnRpdGF0aXZlLCBzZW1pLXF1YW50aXRhdGl2ZSwgcXVhbGl0YXRpdmUsIGFuZCBtaXhlZCB2YXJpYWJsZXMuIEFzIGFsd2F5cywgdGhlIGNob2ljZSBvZiAoZGlzKXNpbWlsYXJpdHkgbWVhc3VyZSBpcyBjcml0aWNhbCBhbmQgbXVzdCBiZSBzdWl0YWJsZSB0byB0aGUgZGF0YSBpbiBxdWVzdGlvbi4gRm9yIGNvdW50IGRhdGEsIEJyYXktQ3VydGlzIGRpc3RhbmNlIGlzIHJlY29tbWVuZGVkLiBZb3UgY2FuIHVzZSBKYWNjYXJkIGluZGV4IGZvciBwcmVzZW5jZS9hYnNlbmNlIGRhdGEuIFdoZW4gdGhlIGRpc3RhbmNlIG1ldHJpYyBpcyBFdWNsaWRlYW4sIFBDb0EgaXMgZXF1aXZhbGVudCB0byBQQ0EuCgoqKlRoZSBmaXJzdCBQQ29BIGNvbXBhcmVzIHNpbWlsYXJpdHkgYmV0d2VlbiB0dW5kcmEgZWNvc3lzdGVtcyBieSBpbmNvcnBvcmF0aW5nIHRoZSBjb21iaW5lZCBkYXRhc2V0LioqCgpgYGB7cn0KIyBSdW4gUENvQSBhbmFseXNpcyBvbiB0aGUgQnJheS1DdXJ0aXMgZGlzc2ltaWxhcml0eSBtYXRyaXgKdHBtLmFsbC5iYy5wY29hPC1wY29hKHRwbS5hbGwuYmMuZGlzdCkKYGBgCgpFeHRyYWN0IHRoZSBlaWdlbnZhbHVlcyBhbmQgY2FsY3VsYXRlIHRoZSB2YXJpYXRpb24gZXhwbGFpbmVkIGJ5IGVhY2ggYXhpcy4KCmBgYHtyfQpwY29hLmFsbDwtY21kc2NhbGUodHBtLmFsbC5iYy5kaXN0LCBlaWc9VFJVRSwgaz0yKQpwY29hLmFsbAoKIyBDYWxjdWxhdGUgdGhlIHBlcmNlbnQgdmFyaWF0aW9uIGV4cGxhaW5lZCBieSBBeGlzIDEKcGNvYS5hbGwuZXhwLnZhcjE8LXJvdW5kKHBjb2EuYWxsJGVpZ1sxXSAvIHN1bShwY29hLmFsbCRlaWcpLCAyKSAqIDEwMApwY29hLmFsbC5leHAudmFyMQoKIyBDYWxjdWxhdGUgdGhlIHBlcmNlbnQgdmFyaWF0aW9uIGV4cGxhaW5lZCBieSBBeGlzIDIKcGNvYS5hbGwuZXhwLnZhcjI8LXJvdW5kKHBjb2EuYWxsJGVpZ1syXSAvIHN1bShwY29hLmFsbCRlaWcpLCAyKSAqIDEwMApwY29hLmFsbC5leHAudmFyMgoKIyBTdW0gdGhlIHBlcmNlbnQgdmFyaWF0aW9uIGV4cGxhaW5lZCBieSBib3RoIGF4ZXMKcGNvYS5hbGwuc3VtLmVpZzwtc3VtKHBjb2EuYWxsLmV4cC52YXIxLCBwY29hLmFsbC5leHAudmFyMikKcGNvYS5hbGwuc3VtLmVpZwpgYGAKClBsb3QgdGhlIFBDb0EuCgpgYGB7cn0KIyBFeHRyYWN0IHRoZSBwbG90IHNjb3JlcyBmcm9tIGZpcnN0IHR3byBQQ29BIGF4ZXMKdHBtLmFsbC5iYy5wY29hLmF4ZXMgPC0gdHBtLmFsbC5iYy5wY29hJHZlY3RvcnNbLGMoMSwyKV0KCiMgQ3JlYXRlIG5ldyBvYmplY3Qgd2l0aCBQQ29BIGF4ZXMKYWxsLmJjLnBjb2E8LWRhdGEuZnJhbWUodHBtLmFsbC5iYy5wY29hLmF4ZXMpCgojIEFkZCBUaW1lcG9pbnQgdmFyaWFibGUgdG8gdGhlIGRhdGFmcmFtZQphbGwudGltZXBvaW50PC1jKCdXUy1NVC1UMCcsJ1dTLU1ULVQwJywnVHVzcy1NVC1UMCcsJ1R1c3MtTVQtVDAnLCdXUy1NVC1UNCcsJ1dTLU1ULVQ0JywnV1MtTVQtVDI0JywnV1MtTVQtVDI0JywnVHVzcy1NVC1UNCcsJ1R1c3MtTVQtVDQnLCdUdXNzLU1ULVQyNCcsJ1R1c3MtTVQtVDI0JykKYWxsLnBjb2EuMTwtYWxsLmJjLnBjb2EkQXhpcy4xCmFsbC5wY29hLjI8LWFsbC5iYy5wY29hJEF4aXMuMgphbGwuYmMucGNvYTwtZGF0YS5mcmFtZShhbGwudGltZXBvaW50LGFsbC5wY29hLjEsYWxsLnBjb2EuMikKCiMgUmVuYW1lIGNvbHVtbiBoZWFkaW5ncwpjb2xuYW1lcyhhbGwuYmMucGNvYSk8LWMoIlRpbWVwb2ludCIsIlBDb0FfMSIsIlBDb0FfMiIpCgojIFJlLWFycmFuZ2Ugc2FtcGxlcyBmb3IgcGxvdHRpbmcgUENvQQphbGwuYmMucGNvYSRUaW1lcG9pbnQgPC0gZmFjdG9yKGFsbC5iYy5wY29hJFRpbWVwb2ludCwgbGV2ZWxzPWMoIlR1c3MtTVQtVDAiLCJXUy1NVC1UMCIsIlR1c3MtTVQtVDQiLCJXUy1NVC1UNCIsIlR1c3MtTVQtVDI0IiwiV1MtTVQtVDI0IikpCgojIFBsb3QgdGhlIFBDb0EKYWxsLnBjb2E8LWdncGxvdChkYXRhPWFsbC5iYy5wY29hLCBhZXMoeD1QQ29BXzEsIHk9UENvQV8yLCBncm91cD1UaW1lcG9pbnQsIGNvbG9yPVRpbWVwb2ludCkpICsgZ2VvbV9wb2ludChhZXMoc2hhcGU9VGltZXBvaW50LCBzaXplPTAuNzUsIGZpbGw9VGltZXBvaW50KSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygicGFsZWdyZWVuIiwibGlnaHRza3libHVlMSIsImdyZWVuMyIsImRvZGdlcmJsdWUxIiwiZGFya2dyZWVuIiwibWlkbmlnaHRibHVlIikpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcz1jKDIxLDIxLDIyLDIyLDI0LDI0KSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoImJsYWNrIiwiYmxhY2siLCJibGFjayIsImJsYWNrIiwiYmxhY2siLCJibGFjayIpKSArIHhsYWIoIlBDb0EgMSAoNTclKSIpICsgeWxhYigiUENvQSAyICgxMCUpIikgKyB0aGVtZV9jbGFzc2ljKCkgKyB0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApLCBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTEyKSwgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTEwKSkgKyBndWlkZXMoc2hhcGUgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gMykpKSArIHNjYWxlX3NpemUoZ3VpZGU9Im5vbmUiKSArIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSAwKSwgY29sb3I9ImdyYXkiLCBsaW5ldHlwZT0iZGFzaGVkIikgKyBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0PTApLCBjb2xvcj0iZ3JheSIsIGxpbmV0eXBlPSJkYXNoZWQiKSArIHlsaW0oLTAuNiwwLjYpICsgeGxpbSgtMC42LDAuNikgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0wLjAsIHk9MC41OSwgbGFiZWw9IlBFUk1BTk9WQSIpICAgKyBhbm5vdGF0ZSgidGV4dCIsIHggPSAwLCB5ID0gMC41Miwgc2l6ZT0zLCBsYWJlbCA9ICJUdW5kcmF+KGl0YWxpYyhwKSA9PSAwLjAwMSkiLCBwYXJzZSA9IFRSVUUpICsgYW5ub3RhdGUoInRleHQiLCB4ID0gMCwgeSA9IDAuNDUsIHNpemU9MywgbGFiZWwgPSAiVGltZX5Qb2ludH4oaXRhbGljKHApID09IDAuMTcxKSIsIHBhcnNlID0gVFJVRSkgKyBhbm5vdGF0ZSgidGV4dCIsIHggPSAwLCB5ID0gMC4zOCwgc2l6ZT0zLCBsYWJlbCA9ICJUdW5kcmE6VGltZX5Qb2ludH4oaXRhbGljKHApID09IDAuMjI2KSIsIHBhcnNlID0gVFJVRSkKYGBgCgpgYGB7cn0KYWxsLnBjb2EKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQojIFNhdmUgdGhlIEFMUEhBIERJVkVSU0lUWSBhbmQgQkVUQSBESVZFUlNJVFkgcGxvdHMgdG9nZXRoZXIKc2V0RVBTKCkKcG9zdHNjcmlwdCgiRmlnLlMyLk1ULkRpdmVyc2l0eS5lcHMiLCB3aWR0aD02LjAsIGhlaWdodCA9IDEwLjApCmdnYXJyYW5nZShhbHBoYS5ib3hwbG90LCBhbGwucGNvYSwgaGVpZ2h0cz1jKDMsMyksCiAgICAgICAgICBsYWJlbHMgPSBjKCJBIiwiQiIpLAogICAgICAgICAgbmNvbCA9IDEsIG5yb3cgPSAyLCBhbGlnbj0idiIpCmRldi5vZmYoKQpgYGAKCioqVGhlIHNlY29uZCBQQ29BIGNvbXBhcmVzIHNpbWlsYXJpdHkgYmV0d2VlbiBzYW1wbGluZyB0aW1lIHBvaW50cyB3aXRoaW4gdGhlIFR1c3NvY2sgdHVuZHJhIGVjb3N5c3RlbS4qKgoKYGBge3J9CiMgUnVuIFBDb0EgYW5hbHlzaXMgb24gdGhlIEJyYXktQ3VydGlzIGRpc3NpbWlsYXJpdHkgbWF0cml4CnRwbS50dXNzLmJjLnBjb2E8LXBjb2EodHBtLnR1c3MuYmMuZGlzdCkKYGBgCgpFeHRyYWN0IHRoZSBlaWdlbnZhbHVlcyBhbmQgY2FsY3VsYXRlIHRoZSB2YXJpYXRpb24gZXhwbGFpbmVkIGJ5IGVhY2ggYXhpcy4KCmBgYHtyfQpwY29hLnR1c3M8LWNtZHNjYWxlKHRwbS50dXNzLmJjLmRpc3QsIGVpZz1UUlVFLCBrPTIpCnBjb2EudHVzcwoKIyBDYWxjdWxhdGUgdGhlIHBlcmNlbnQgdmFyaWF0aW9uIGV4cGxhaW5lZCBieSBBeGlzIDEKcGNvYS50dXNzLmV4cC52YXIxPC1yb3VuZChwY29hLnR1c3MkZWlnWzFdIC8gc3VtKHBjb2EudHVzcyRlaWcpLCAyKSAqIDEwMApwY29hLnR1c3MuZXhwLnZhcjEKCiMgQ2FsY3VsYXRlIHRoZSBwZXJjZW50IHZhcmlhdGlvbiBleHBsYWluZWQgYnkgQXhpcyAyCnBjb2EudHVzcy5leHAudmFyMjwtcm91bmQocGNvYS50dXNzJGVpZ1syXSAvIHN1bShwY29hLnR1c3MkZWlnKSwgMikgKiAxMDAKcGNvYS50dXNzLmV4cC52YXIyCgojIFN1bSB0aGUgcGVyY2VudCB2YXJpYXRpb24gZXhwbGFpbmVkIGJ5IGJvdGggYXhlcwpwY29hLnR1c3Muc3VtLmVpZzwtc3VtKHBjb2EudHVzcy5leHAudmFyMSwgcGNvYS50dXNzLmV4cC52YXIyKQpwY29hLnR1c3Muc3VtLmVpZwpgYGAKClBsb3QgdGhlIFBDb0EuCgpgYGB7cn0KIyBFeHRyYWN0IHRoZSBwbG90IHNjb3JlcyBmcm9tIGZpcnN0IHR3byBQQ29BIGF4ZXMKdHBtLnR1c3MuYmMucGNvYS5heGVzIDwtIHRwbS50dXNzLmJjLnBjb2EkdmVjdG9yc1ssYygxLDIpXQoKIyBDcmVhdGUgbmV3IG9iamVjdCB3aXRoIFBDb0EgYXhlcwp0dXNzLmJjLnBjb2E8LWRhdGEuZnJhbWUodHBtLnR1c3MuYmMucGNvYS5heGVzKQoKIyBBZGQgVGltZXBvaW50IHZhcmlhYmxlIHRvIHRoZSBkYXRhZnJhbWUKdHVzcy50aW1lcG9pbnQ8LWMoJ1R1c3MtVDAnLCdUdXNzLVQwJywnVHVzcy1UNCcsJ1R1c3MtVDQnLCdUdXNzLVQyNCcsJ1R1c3MtVDI0JykKdHVzcy5wY29hLjE8LXR1c3MuYmMucGNvYSRBeGlzLjEKdHVzcy5wY29hLjI8LXR1c3MuYmMucGNvYSRBeGlzLjIKdHVzcy5iYy5wY29hPC1kYXRhLmZyYW1lKHR1c3MudGltZXBvaW50LHR1c3MucGNvYS4xLHR1c3MucGNvYS4yKQoKIyBSZW5hbWUgY29sdW1uIGhlYWRpbmdzCmNvbG5hbWVzKHR1c3MuYmMucGNvYSk8LWMoIlRpbWVwb2ludCIsIlBDb0FfMSIsIlBDb0FfMiIpCiN0dXNzLmJjLnBjb2EKCiMgUmUtYXJyYW5nZSBzYW1wbGVzIGZvciBwbG90dGluZyBQQ29BCnR1c3MuYmMucGNvYSRUaW1lcG9pbnQ8LWZhY3Rvcih0dXNzLmJjLnBjb2EkVGltZXBvaW50LCBsZXZlbHM9YygiVHVzcy1UMCIsIlR1c3MtVDQiLCJUdXNzLVQyNCIpKQoKIyBQbG90IHRoZSBQQ29BCnR1c3MucGNvYTwtZ2dwbG90KGRhdGE9dHVzcy5iYy5wY29hLCBhZXMoeD1QQ29BXzEsIHk9UENvQV8yLCBncm91cD1UaW1lcG9pbnQsIGNvbG9yPVRpbWVwb2ludCkpICsgZ2VvbV9wb2ludChhZXMoc2hhcGU9VGltZXBvaW50LCBzaXplPTAuNzUsIGZpbGw9VGltZXBvaW50KSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygicGFsZWdyZWVuIiwiZ3JlZW4zIiwiZGFya2dyZWVuIikpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcz1jKDIxLDI0LDIyKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoImJsYWNrIiwiYmxhY2siLCJibGFjayIpKSArIHhsYWIoIlBDb0EgMSAoMzklKSIpICsgeWxhYigiUENvQSAyICgyNiUpIikgKyB0aGVtZV9taW5pbWFsKCkgKyB0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTIpLGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTQpKSsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTEyKSwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5tYWpvcj1lbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiZ3JheSIpLCBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImdyYXkiLCBmaWxsPU5BLCBzaXplPTEpKSArIHNjYWxlX3NpemUoZ3VpZGU9RkFMU0UpICsgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMpKSkgKyBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gMCksIGNvbG9yPSJncmF5IiwgbGluZXR5cGU9ImRhc2hlZCIpICsgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD0wKSwgY29sb3I9ImdyYXkiLCBsaW5ldHlwZT0iZGFzaGVkIikgKyB5bGltKC0wLjUsMC41KSArIHhsaW0oLTAuNSwwLjUpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9MC4wLCB5PTAuNDksIGxhYmVsPSJQRVJNQU5PVkEiKSArIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDAsIHkgPSAwLjQyLCBzaXplPTMsIGxhYmVsID0gIlRpbWV+UG9pbnR+KGl0YWxpYyhwKSA9PSAwLjA2NykiLCBwYXJzZSA9IFRSVUUpCmBgYAoKYGBge3J9CnR1c3MucGNvYQpgYGAKCioqVGhlIHRoaXJkIFBDb0EgY29tcGFyZXMgc2ltaWxhcml0eSBiZXR3ZWVuIHNhbXBsaW5nIHRpbWUgcG9pbnRzIHdpdGhpbiB0aGUgV2V0IFNlZGdlIHR1bmRyYSBlY29zeXN0ZW0uKioKCmBgYHtyfQojIFJ1biBQQ29BIGFuYWx5c2lzIG9uIHRoZSBCcmF5LUN1cnRpcyBkaXNzaW1pbGFyaXR5IG1hdHJpeAp0cG0ud3MuYmMucGNvYTwtcGNvYSh0cG0ud3MuYmMuZGlzdCkKYGBgCgpFeHRyYWN0IHRoZSBlaWdlbnZhbHVlcyBhbmQgY2FsY3VsYXRlIHRoZSB2YXJpYXRpb24gZXhwbGFpbmVkIGJ5IGVhY2ggYXhpcy4KCmBgYHtyfQpwY29hLndzPC1jbWRzY2FsZSh0cG0ud3MuYmMuZGlzdCwgZWlnPVRSVUUsIGs9MikKcGNvYS53cwoKIyBDYWxjdWxhdGUgdGhlIHBlcmNlbnQgdmFyaWF0aW9uIGV4cGxhaW5lZCBieSBBeGlzIDEKcGNvYS53cy5leHAudmFyMTwtcm91bmQocGNvYS53cyRlaWdbMV0gLyBzdW0ocGNvYS53cyRlaWcpLCAyKSAqIDEwMApwY29hLndzLmV4cC52YXIxCgojIENhbGN1bGF0ZSB0aGUgcGVyY2VudCB2YXJpYXRpb24gZXhwbGFpbmVkIGJ5IEF4aXMgMgpwY29hLndzLmV4cC52YXIyPC1yb3VuZChwY29hLndzJGVpZ1syXSAvIHN1bShwY29hLndzJGVpZyksIDIpICogMTAwCnBjb2Eud3MuZXhwLnZhcjIKCiMgU3VtIHRoZSBwZXJjZW50IHZhcmlhdGlvbiBleHBsYWluZWQgYnkgYm90aCBheGVzCnBjb2Eud3Muc3VtLmVpZzwtc3VtKHBjb2Eud3MuZXhwLnZhcjEsIHBjb2Eud3MuZXhwLnZhcjIpCnBjb2Eud3Muc3VtLmVpZwpgYGAKClBsb3QgdGhlIFBDb0EuCgpgYGB7cn0KIyBFeHRyYWN0IHRoZSBwbG90IHNjb3JlcyBmcm9tIGZpcnN0IHR3byBQQ29BIGF4ZXMKdHBtLndzLmJjLnBjb2EuYXhlcyA8LSB0cG0ud3MuYmMucGNvYSR2ZWN0b3JzWyxjKDEsMildCgojIENyZWF0ZSBuZXcgb2JqZWN0IHdpdGggUENvQSBheGVzCndzLmJjLnBjb2E8LWRhdGEuZnJhbWUodHBtLndzLmJjLnBjb2EuYXhlcykKCiMgQWRkIFRpbWVwb2ludCB2YXJpYWJsZSB0byB0aGUgZGF0YWZyYW1lCndzLnRpbWVwb2ludDwtYygnV1MtVDAnLCdXUy1UMCcsJ1dTLVQ0JywnV1MtVDQnLCdXUy1UMjQnLCdXUy1UMjQnKQp3cy5wY29hLjE8LXdzLmJjLnBjb2EkQXhpcy4xCndzLnBjb2EuMjwtd3MuYmMucGNvYSRBeGlzLjIKd3MuYmMucGNvYTwtZGF0YS5mcmFtZSh3cy50aW1lcG9pbnQsd3MucGNvYS4xLHdzLnBjb2EuMikKCiMgUmVuYW1lIGNvbHVtbiBoZWFkaW5ncwpjb2xuYW1lcyh3cy5iYy5wY29hKTwtYygiVGltZXBvaW50IiwiUENvQV8xIiwiUENvQV8yIikKI3dzLmJjLnBjb2EKCiMgUmUtYXJyYW5nZSBzYW1wbGVzIGZvciBwbG90dGluZyBQQ29BCndzLmJjLnBjb2EkVGltZXBvaW50PC1mYWN0b3Iod3MuYmMucGNvYSRUaW1lcG9pbnQsIGxldmVscz1jKCJXUy1UMCIsIldTLVQ0IiwiV1MtVDI0IikpCgojIFBsb3QgdGhlIFBDb0EKd3MucGNvYTwtZ2dwbG90KGRhdGE9d3MuYmMucGNvYSwgYWVzKHg9UENvQV8xLCB5PVBDb0FfMiwgZ3JvdXA9VGltZXBvaW50LCBjb2xvcj1UaW1lcG9pbnQpKSArIGdlb21fcG9pbnQoYWVzKHNoYXBlPVRpbWVwb2ludCwgc2l6ZT0wLjc1LCBmaWxsPVRpbWVwb2ludCkpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoImxpZ2h0c2t5Ymx1ZTEiLCJkb2RnZXJibHVlMSIsIm1pZG5pZ2h0Ymx1ZSIpKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXM9YygyMSwyNCwyMikpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCJibGFjayIsImJsYWNrIiwiYmxhY2siKSkgKyB4bGFiKCJQQ29BIDEgKDQ0JSkiKSArIHlsYWIoIlBDb0EgMiAoMTklKSIpICsgdGhlbWVfbWluaW1hbCgpICsgdGhlbWUoYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTEyKSxheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTE0KSkrIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLCBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpLCBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xMiksIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWFqb3I9ZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImdyYXkiKSwgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJncmF5IiwgZmlsbD1OQSwgc2l6ZT0xKSkgKyBzY2FsZV9zaXplKGd1aWRlPUZBTFNFKSArIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzKSkpICsgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDApLCBjb2xvcj0iZ3JheSIsIGxpbmV0eXBlPSJkYXNoZWQiKSArIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQ9MCksIGNvbG9yPSJncmF5IiwgbGluZXR5cGU9ImRhc2hlZCIpICsgeWxpbSgtMC41LDAuNSkgKyB4bGltKC0wLjUsMC41KSArIGFubm90YXRlKGdlb209InRleHQiLCB4PTAuMCwgeT0wLjQ5LCBsYWJlbD0iUEVSTUFOT1ZBIikgKyBhbm5vdGF0ZSgidGV4dCIsIHggPSAwLCB5ID0gMC40Miwgc2l6ZT0zLCBsYWJlbCA9ICJUaW1lflBvaW50fihpdGFsaWMocCkgPT0gMC4zMzMpIiwgcGFyc2UgPSBUUlVFKQpgYGAKCmBgYHtyfQp3cy5wY29hCmBgYAoKYGBge3IgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0Kc2V0RVBTKCkKcG9zdHNjcmlwdCgiRmlnLjIuUENvQS5NRy5NVC5lcHMiLCB3aWR0aD04LjAsIGhlaWdodCA9IDguMCkKZ2dhcnJhbmdlKHR1c3MuZG5hLnBjb2EsIHR1c3MucGNvYSwgd3MuZG5hLnBjb2EsIHdzLnBjb2EsIGhlaWdodHM9Yyg0LDQpLAogICAgICAgICAgbGFiZWxzID0gYygiQSIsIkIiLCJDIiwiRCIpLAogICAgICAgICAgbmNvbCA9IDIsIG5yb3cgPSAyLCBhbGlnbj0idiIpCmRldi5vZmYoKQpgYGAKCiMjIyMjIDcuMi4yLjQuIFBFUk1BTk9WQQoKLSBSdW4gUEVSTUFOT1ZBIHVzaW5nIGBhZG9uaXNgIGZ1bmN0aW9uIG9mIHRoZSAqKlZlZ2FuKiogcGFja2FnZQoKUEVSTUFOT1ZBIC0gVFBNLUFsbCAtIEJyYXktQ3VydGlzCmBgYHtyfQphZG9uaXModHBtLmFsbC5iYy5kaXN0fnRwbV9hbGxfdmVnKnRwbV9hbGxfdGltZSwgZGF0YT10cG1fYWxsX2dyb3VwcykKYGBgCgpQRVJNQU5PVkEgLSBUUE0tVHVzcyAtIEJyYXktQ3VydGlzCmBgYHtyfQphZG9uaXModHBtLnR1c3MuYmMuZGlzdH50cG1fdHVzc190aW1lLCBkYXRhPXRwbV90dXNzX2dyb3VwcykKYGBgCgpQRVJNQU5PVkEgLSBUUE0tV1MgLSBCcmF5LUN1cnRpcwpgYGB7cn0KYWRvbmlzKHRwbS53cy5iYy5kaXN0fnRwbV93c190aW1lLCBkYXRhPXRwbV93c19ncm91cHMpCmBgYAoKIyMjIDcuMy4gS0VHRyBUaWVyIFBhdHRlcm5zCgpMb29rIGZvciBkaWZmZXJlbmNlcyBpbiBnZW5lIGV4cHJlc3Npb24gYXQgbXVsdGlwbGUgS0VHRyB0aWVyIGxldmVscyAoSUktSVYpIHVzaW5nIFRQTS1ub3JtYWxpemVkIHZhbHVlcy4KCiMjIyMgNy4zLjEuIFR1c3NvY2sgVHVuZHJhCgpMb29rIGF0IGRpZmZlcmVuY2VzIGluIGdlbmUgZXhwcmVzc2lvbiBwYXR0ZXJucyBmb3IgbXVsdGlwbGUgVGllciBsZXZlbHMgd2l0aGluIHRoZSBUdXNzb2NrIHR1bmRyYSBiZXR3ZWVuIHNhbXBsaW5nIHRpbWUgcG9pbnRzLgoKIyMjIyMgNy4zLjEuMS4gVGllciBJSSBFeHByZXNzaW9uCmBgYHtyfQojIENhbGN1bGF0ZSBUUE0tbm9ybWFsaXplZCBnZW5lIGNvdW50IHN1bXMgZm9yIGVhY2ggVHVzcyBzYW1wbGUgaW4gZWFjaCBUaWVyIElJIGNhdGVnb3J5CnR1c3NfdElJX3N1bTwtdHBtX2FsbF9leHBfYW5uICU+JSBncm91cF9ieShUaWVyX0lJKSAlPiUgc3VtbWFyaXNlX2F0KHZhcnMoIlMxMDgzODIiLCJTMTA4MzgzIiwiUzEwODM5MSIsIlMxMDgzOTIiLCJTMTA4Mzk0IiwiUzEwODM5NiIpLCBzdW0pCgp0dXNzX3RJSV9zdW08LXR1c3NfdElJX3N1bSAlPiUgbXV0YXRlX2F0KHZhcnMoUzEwODM4MixTMTA4MzgzLFMxMDgzOTEsUzEwODM5MixTMTA4Mzk0LFMxMDgzOTYpLCBmdW5zKHJvdW5kKC4sIDApKSkKCnR1c3NfdElJX3N1bTwtYXMuZGF0YS5mcmFtZSh0dXNzX3RJSV9zdW0pCgp0dXNzX3RJSV9zdW08LXR1c3NfdElJX3N1bVtvcmRlcigtdHVzc190SUlfc3VtJFMxMDgzODIpLF0KYGBgCgpIZWF0bWFwIGZvciBUaWVyIElJIGNhdGVnb3JpZXMgYnkgc2FtcGxpbmcgdGltZXBvaW50cwpgYGB7cn0KIyBDcmVhdGUgY29weSBvZiAid3NfdElJX3N1bSIgb2JqZWN0IHRvIHByZXAgZm9yIGhlYXRtYXAKdHVzc190SUlfaGVhdG1hcDwtdHVzc190SUlfc3VtCgojIENvbnZlcnQgdGhlIGZpcnN0IGNvbHVtbiAoVGllciBjYXRlZ29yaWVzKSBpbnRvIHJvd25hbWVzCnJvd25hbWVzKHR1c3NfdElJX2hlYXRtYXApIDwtIHR1c3NfdElJX2hlYXRtYXAkVGllcl9JSQp0dXNzX3RJSV9oZWF0bWFwPC1hcy5kYXRhLmZyYW1lKHR1c3NfdElJX2hlYXRtYXBbLTFdKQoKIyBSZW5hbWUgY29sdW1ucyB0byBzYW1wbGUgSURzCmNvbG5hbWVzKHR1c3NfdElJX2hlYXRtYXApPC1jKCJUdXNzMS1UMCIsIlR1c3MyLVQwIiwiVHVzczEtVDQiLCJUdXNzMi1UNCIsIlR1c3MxLVQyNCIsIlR1c3MzLVQyNCIpCgojIFJlbW92ZSByb3R1c3MgZm9yICJPcmdhbmlzbWFsIFN5c3RlbXMiIGFuZCAiSHVtYW4gRGlzZWFzZXMiCiN0dXNzX3RJSV9oZWF0bWFwIDwtIHR1c3NfdElJX2hlYXRtYXBbLWMoNSw2KSxdCgojIENvbnZlcnQgZGF0YWZyYW1lIGludG8gYSBtYXRyaXggZm9yIGhlYXRtYXAKdHVzc190SUlfaGVhdG1hcDwtYXMubWF0cml4KHR1c3NfdElJX2hlYXRtYXApCgojIFNjYWxlIG1hdHJpeCB2YWx1ZXMgdG8gZ2VuZXJhdGUgWi1zY29yZXMKdHVzc190SUlfaGVhdG1hcDwtc2NhbGUodCh0dXNzX3RJSV9oZWF0bWFwKSkKCnR1c3NfdElJX2hlYXRtYXA8LXQodHVzc190SUlfaGVhdG1hcCkKCiMgU3BlY2lmeSBSQ29sb3JCcmV3ZXIgY3VzdG9tIGNvbG9yIHBhbGV0dGUKY29sIDwtIGNvbG9yUmFtcFBhbGV0dGUoYnJld2VyLnBhbCgxMCwgIlJkWWxCdSIpKSgyNTYpCgojIFBoZWF0bWFwCnBoZWF0bWFwKHR1c3NfdElJX2hlYXRtYXAsIHRyZWVoZWlnaHRfcm93ID0gMCwgdHJlZWhlaWdodF9jb2wgPSAwLGNsdXN0ZXJfcm93cyA9IEZBTFNFLCBjbHVzdGVyX2NvbHMgPSBGQUxTRSkKYGBgCgpTdW1tZWQgdmFsdWVzIGJ5IHJlcGxpY2F0ZSBmb3IgZWFjaCBLRUdHIHRpZXIgSUkgY2F0ZWdvcnkuCmBgYHtyIGVjaG89RkFMU0V9CmthYmxlKHR1c3NfdElJX3N1bSwgY2FwdGlvbiA9ICJUdXNzb2NrIFRpZXIgSUkgS0VHRyBjYXRlZ29yeSBzdW1tYXJ5IGJ5IHNhbXBsZS4iLCBmb3JtYXQuYXJncyA9IGxpc3QoYmlnLm1hcms9IiwiKSkgJT4lIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiKSkKYGBgCgpDYWxjdWxhdGUgbWVhbiB2YWx1ZXMgZnJvbSB0aGUgcmVwbGljYXRlIHN1bXMKYGBge3J9CiMgQ2FsY3VsYXRlIG1lYW4gdmFsdWVzIGZyb20gdGhlIHJlcGxpY2F0ZSBzdW1zCnR1c3NfdElJX3N1bSRtZWFudHVzc19UMDwtYXBwbHkodHVzc190SUlfc3VtWywyOjNdLCAxLCBtZWFuKQp0dXNzX3RJSV9zdW0kbWVhbnR1c3NfVDQ8LWFwcGx5KHR1c3NfdElJX3N1bVssNDo1XSwgMSwgbWVhbikKdHVzc190SUlfc3VtJG1lYW50dXNzX1QyNDwtYXBwbHkodHVzc190SUlfc3VtWyw2OjddLCAxLCBtZWFuKQp0dXNzX3RJSV9zdW08LXR1c3NfdElJX3N1bSAlPiUgbXV0YXRlX2F0KHZhcnMobWVhbnR1c3NfVDAsbWVhbnR1c3NfVDQsbWVhbnR1c3NfVDI0KSwgZnVucyhyb3VuZCguLCAwKSkpCgojIENhbGN1bGF0ZSBzZCB2YWx1ZXMgZnJvbSB0aGUgcmVwbGljYXRlIHN1bXMKdHVzc190SUlfc3VtJHNkdHVzc19UMDwtYXBwbHkodHVzc190SUlfc3VtWywyOjNdLCAxLCBzZCkKdHVzc190SUlfc3VtJHNkdHVzc19UNDwtYXBwbHkodHVzc190SUlfc3VtWyw0OjVdLCAxLCBzZCkKdHVzc190SUlfc3VtJHNkdHVzc19UMjQ8LWFwcGx5KHR1c3NfdElJX3N1bVssNjo3XSwgMSwgc2QpCnR1c3NfdElJX3N1bTwtdHVzc190SUlfc3VtICU+JSBtdXRhdGVfYXQodmFycyhzZHR1c3NfVDAsc2R0dXNzX1Q0LHNkdHVzc19UMjQpLCBmdW5zKHJvdW5kKC4sIDApKSkKCiMgU3Vic2V0IE1lYW4gdmFsdWVzCnR1c3NfdElJX21lYW48LXN1YnNldCh0dXNzX3RJSV9zdW0sIHNlbGVjdD1jKFRpZXJfSUksbWVhbnR1c3NfVDAsbWVhbnR1c3NfVDQsbWVhbnR1c3NfVDI0KSkKbmFtZXModHVzc190SUlfbWVhbik8LWMoIlRpZXIgSUkiLCAiVHVzcy1UMCIsICJUdXNzLVQ0IiwgIlR1c3MtVDI0IikKCiMgU3Vic2V0IFNEIHZhbHVlcwp0dXNzX3RJSV9zZDwtc3Vic2V0KHR1c3NfdElJX3N1bSwgc2VsZWN0PWMoVGllcl9JSSxzZHR1c3NfVDAsc2R0dXNzX1Q0LHNkdHVzc19UMjQpKQpuYW1lcyh0dXNzX3RJSV9zZCk8LWMoIlRpZXIgSUkiLCAiVHVzcy1UMCIsICJUdXNzLVQ0IiwgIlR1c3MtVDI0IikKCiMgUmVtZW1iZXIgIlRpZXIgSUkiIGFzIG5vbi1udW1lcmljIHZhbHVlcwp0dXNzX3RJSV9tZWFuX1RpZXJJSTwtdHVzc190SUlfbWVhbiRgVGllciBJSWAKdHVzc190SUlfc2RfVGllcklJPC10dXNzX3RJSV9zZCRgVGllciBJSWAKCiMgVHJhbnNwb3NlIGFsbCBidXQgZmlyc3QgY29sdW1uIChUaWVyIElJKQp0dXNzX3RJSV9tZWFuPC1hcy5kYXRhLmZyYW1lKHQodHVzc190SUlfbWVhblssLTFdKSkKY29sbmFtZXModHVzc190SUlfbWVhbik8LXR1c3NfdElJX21lYW5fVGllcklJCnR1c3NfdElJX3NkPC1hcy5kYXRhLmZyYW1lKHQodHVzc190SUlfc2RbLC0xXSkpCmNvbG5hbWVzKHR1c3NfdElJX3NkKTwtdHVzc190SUlfc2RfVGllcklJCgojIENvbWJpbmUgbWVhbiBhbmQgc2QgaW50byBzaW5nbGUgY29sdW1uIHdpdGggwrEgZGl2aWRlcgp0dXNzX3RJSV90YWJsZTwtYXMuZGF0YS5mcmFtZShkby5jYWxsKGNiaW5kLCBsYXBwbHkoMTpuY29sKHR1c3NfdElJX21lYW4pLCBmdW5jdGlvbihpKSBwYXN0ZTAodHVzc190SUlfbWVhblsgLCBpXSwgIiDCsSAiLCB0dXNzX3RJSV9zZFsgLCBpXSkpKSkKCiMgVHJhbnNwb3NlIHRoZSB0YWJsZSBiYWNrCnR1c3NfdElJX3RhYmxlPC10KHR1c3NfdElJX3RhYmxlKQoKIyBSZW5hbWUgY29sdW1ucyB0byBTaXRlcwpjb2xuYW1lcyh0dXNzX3RJSV90YWJsZSk8LWMoIlR1c3NvY2sgKFQwKSIsICJUdXNzb2NrIChUNCkiLCAiVHVzc29jayAoVDI0KSIpCgpyb3duYW1lcyh0dXNzX3RJSV90YWJsZSk8LXR1c3NfdElJX21lYW5fVGllcklJCgprYWJsZSh0dXNzX3RJSV90YWJsZSwgY2FwdGlvbiA9ICJUdXNzb2NrIFRpZXIgSUkgS0VHRyBjYXRlZ29yeSBhdmVyYWdlcyAowrEgc3RhbmRhcmQgZGV2aWF0aW9uKSBieSBzYW1wbGUuIiwgZm9ybWF0LmFyZ3MgPSBsaXN0KGJpZy5tYXJrPSIsIiksIGFsaWduID0gImwiKSAlPiUga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCJob3ZlciIsImNvbmRlbnNlZCIpKQpgYGAKClJ1biBzdGF0aXN0aWNhbCB0ZXN0cyB0byBkZXRlcm1pbmUgaWYgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgZXhpc3QgYmV0d2VlbiBzYW1wbGluZyB0aW1lcG9pbnRzIGZvciBlYWNoIFRpZXIgS0VHRyBjYXRlZ29yeS4gQ2xpY2sgb24gdGhlICoqU2hvdy9IaWRlKiogYnV0dG9uIHRvIHNlZSB0aGUgc3RhdGlzdGljcy4KCjxidXR0b24gY2xhc3M9ImJ0biBidG4tcHJpbWFyeSIgZGF0YS10b2dnbGU9ImNvbGxhcHNlIiBkYXRhLXRhcmdldD0iI0Jsb2NrTmFtZTYiPiBTaG93L0hpZGUgPC9idXR0b24+ICAKPGRpdiBpZD0iQmxvY2tOYW1lNiIgY2xhc3M9ImNvbGxhcHNlIj4KYGBge3J9CiMgU3Vic2V0IHRoZSAic3VtIiB2YWx1ZXMgZm9yIGVhY2ggc2FtcGxlCnR1c3NfdElJX3N0YXRzPC1zdWJzZXQodHVzc190SUlfc3VtLCBzZWxlY3Q9YyhUaWVyX0lJLFMxMDgzODIsUzEwODM4MyxTMTA4MzkxLFMxMDgzOTIsUzEwODM5NCxTMTA4Mzk2KSkKCnJvd25hbWVzKHR1c3NfdElJX3N0YXRzKSA8LSB0dXNzX3RJSV9zdGF0cyRUaWVyX0lJCnR1c3NfdElJX3N0YXRzPC1hcy5kYXRhLmZyYW1lKHQodHVzc190SUlfc3RhdHNbLTFdKSkKCiMgQ3JlYXRlIGEgY29sdW1uIHdpdGggdGltZXBvaW50IHZhcmlhYmxlIG5hbWVzClRpbWVwb2ludDwtYygiVDAiLCJUMCIsIlQ0IiwiVDQiLCJUMjQiLCJUMjQiKQpUaW1lcG9pbnQ8LWRhdGEuZnJhbWUoVGltZXBvaW50KQoKIyBBZGQgdGhlIHRpbWVwb2ludCBjb2x1bW4gdG8gdGhlIHN1bSB0YWJsZQp0dXNzX3RJSV9zdGF0czwtZGF0YS5mcmFtZShUaW1lcG9pbnQsdHVzc190SUlfc3RhdHMpCgojIFN1YnNldCByZXNwb25zZSB2YXJpYWJsZXMgZm9yIE1BTk9WQQp0dXNzX3RJSV9zdGF0cyRyZXNwb25zZSA8LSBhcy5tYXRyaXgodHVzc190SUlfc3RhdHNbLCAyOjVdKQoKIyBNQU5PVkEgdGVzdAp0dXNzX3RJSV9tYW5vdmEgPC0gbWFub3ZhKHJlc3BvbnNlIH4gVGltZXBvaW50LCBkYXRhPXR1c3NfdElJX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJSV9tYW5vdmEpCmBgYAoKUnVuIEFOT1ZBIGZvciBlYWNoIGNhdGVnb3J5IG9mIGludGVyZXN0IChzaWduaWZpY2FudCBpbiBNQU5PVkEpCmBgYHtyfQojIE1ldGFib2xpc20KdHVzc190SUlfYW92MTwtYW92KE1ldGFib2xpc20uflRpbWVwb2ludCxkYXRhPXR1c3NfdElJX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJSV9hb3YxKQpUdWtleUhTRCh0dXNzX3RJSV9hb3YxKQoKIyBHZW5ldGljIEluZm9ybWF0aW9uIFByb2Nlc3NpbmcKdHVzc190SUlfYW92MjwtYW92KEdlbmV0aWMuSW5mb3JtYXRpb24uUHJvY2Vzc2luZy5+VGltZXBvaW50LGRhdGE9dHVzc190SUlfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElJX2FvdjIpClR1a2V5SFNEKHR1c3NfdElJX2FvdjIpCgojIEVudmlyb25tZW50YWwgSW5mb3JtYXRpb24gUHJvY2Vzc2luZwp0dXNzX3RJSV9hb3YzPC1hb3YoRW52aXJvbm1lbnRhbC5JbmZvcm1hdGlvbi5Qcm9jZXNzaW5nLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJSV9zdGF0cykKc3VtbWFyeS5hb3YodHVzc190SUlfYW92MykKVHVrZXlIU0QodHVzc190SUlfYW92MykKCiMgQ2VsbHVsYXIgUHJvY2Vzc2luZwp0dXNzX3RJSV9hb3Y0PC1hb3YoQ2VsbHVsYXIuUHJvY2Vzc2VzLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJSV9zdGF0cykKc3VtbWFyeS5hb3YodHVzc190SUlfYW92NCkKVHVrZXlIU0QodHVzc190SUlfYW92NCkKYGBgCjwvZGl2PgoKUGxvdCB0aGUgS0VHRyB0aWVyIElJIGNhdGVnb3JpZXMgYXMgYSBiYXJjaGFydC4KYGBge3IsIGVjaG89RkFMU0V9CnR1c3NfdElJX2JhcmRhdGE8LXJlYWQuY3N2KCJQbG90LkRhdGEvdHVzc190SUlfYmFycGxvdC5jc3YiKQpgYGAKCmBgYHtyfQojIFBsYWNlIHRoZSBLRUdHIHRpZXIgSUkgY2F0ZWdvcmllcyBpbiB0aGUgcHJlZmVycmVkIG9yZGVyIGZvciBwbG90dGluZwp0dXNzX3RJSV9iYXJkYXRhJFRpZXIuSUkgPC0gZmFjdG9yKHR1c3NfdElJX2JhcmRhdGEkVGllci5JSSxsZXZlbHMgPSBjKCJNZXRhYm9saXNtIiwgIkdlbmV0aWMgSW5mb3JtYXRpb24gUHJvY2Vzc2luZyIsICJFbnZpcm9ubWVudGFsIEluZm9ybWF0aW9uIFByb2Nlc3NpbmciLCAiQ2VsbHVsYXIgUHJvY2Vzc2VzIikpCgp0dXNzX3RJSV9iYXJkYXRhJFNhbXBsZSA8LSBmYWN0b3IodHVzc190SUlfYmFyZGF0YSRTYW1wbGUsbGV2ZWxzPWMoIlR1c3MtVDAiLCJUdXNzLVQ0IiwiVHVzcy1UMjQiKSkKCnR1c3NfdElJX2JhcnBsb3Q8LWdncGxvdCh0dXNzX3RJSV9iYXJkYXRhLCBhZXMoeCA9IFRpZXIuSUksIHkgPSBNZWFuLCBmaWxsID0gU2FtcGxlKSkgKyBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvcj0iYmxhY2siKSArIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBNZWFuIC0gU0QsIHltYXggPSBNZWFuICsgU0QpLCB3aWR0aCA9IDAuMiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpKSArIHlsYWIoZXhwcmVzc2lvbihhdG9wKCJLRUdHIFRpZXIgSUkgQ2F0ZWdvcmllcyIsIHBhc3RlKCJUcmFuc2NyaXB0IENvdW50cyAoVFBNKSIpKSkpICsgdGhlbWVfY2xhc3NpYygpICsgdGhlbWUoYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTEwKSwgYXhpcy50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xMiksIGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCkpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTgpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X2JsYW5rKCkpICsgc2NhbGVfc2l6ZShndWlkZT1GQUxTRSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygicGFsZWdyZWVuIiwgImdyZWVuMyIsICJkYXJrZ3JlZW4iKSkgKyBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGZ1bmN0aW9uKFRpZXIuSUkpIHN0cl93cmFwKFRpZXIuSUksIHdpZHRoID0gMTApKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIDgwMDAwMCkpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9MC43MCwgeT03NTAwMDAsIGxhYmVsPSJhIikgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0xLjAsIHk9NDc1MDAwLCBsYWJlbD0iYiIpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9MS4zLCB5PTQ3NTAwMCwgbGFiZWw9ImIiKSArIGFubm90YXRlKGdlb209InRleHQiLCB4PTEuNywgeT0zNTAwMDAsIGxhYmVsPSJhIikgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0yLjAsIHk9NjAwMDAwLCBsYWJlbD0iYiIpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9Mi4zLCB5PTYwMDAwMCwgbGFiZWw9ImIiKSArIGFubm90YXRlKGdlb209InRleHQiLCB4PTMuMCwgeT0xNTAwMDAsIGxhYmVsPSJpdGFsaWMoTi5TLikiLCBwYXJzZT1UUlVFKSArIGFubm90YXRlKGdlb209InRleHQiLCB4PTMuNywgeT0xMDAwMDAsIGxhYmVsPSJhIikgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD00LjAsIHk9MTUwMDAwLCBsYWJlbD0iYiIpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9NC4zLCB5PTEyMDAwMCwgbGFiZWw9ImEiKQpgYGAKCmBgYHtyfQp0dXNzX3RJSV9iYXJwbG90CmBgYAoKUGxvdCB0aGUgY29tYmluZWQgTUVUQUdFTk9NRSBhbmQgTUVUQVRSQU5TQ1JJUFRPTUUgS0VHRyB0aWVyIElJIGNhdGVnb3JpZXMgYXMgYSBiYXJjaGFydC4KYGBge3IsIGVjaG89RkFMU0V9CnR1c3NfbWdfbXRfdElJX2JhcmRhdGE8LXJlYWQuY3N2KCJQbG90LkRhdGEvdHVzc19tZ19tdF90SUlfYmFycGxvdC5jc3YiKQpgYGAKCmBgYHtyfQojIFBsYWNlIHRoZSBLRUdHIHRpZXIgSUkgY2F0ZWdvcmllcyBpbiB0aGUgcHJlZmVycmVkIG9yZGVyIGZvciBwbG90dGluZwp0dXNzX21nX210X3RJSV9iYXJkYXRhJFRpZXIuSUkgPC0gZmFjdG9yKHR1c3NfbWdfbXRfdElJX2JhcmRhdGEkVGllci5JSSxsZXZlbHMgPSBjKCJNZXRhYm9saXNtIiwgIkdlbmV0aWMgSW5mb3JtYXRpb24gUHJvY2Vzc2luZyIsICJFbnZpcm9ubWVudGFsIEluZm9ybWF0aW9uIFByb2Nlc3NpbmciLCAiQ2VsbHVsYXIgUHJvY2Vzc2VzIikpCgp0dXNzX21nX210X3RJSV9iYXJkYXRhJFNhbXBsZSA8LSBmYWN0b3IodHVzc19tZ19tdF90SUlfYmFyZGF0YSRTYW1wbGUsbGV2ZWxzPWMoIlR1c3MtTUciLCJUdXNzLU1ULVQwIiwiVHVzcy1NVC1UNCIsIlR1c3MtTVQtVDI0IikpCgp0dXNzX21nX210X3RJSV9iYXJwbG90PC1nZ3Bsb3QodHVzc19tZ19tdF90SUlfYmFyZGF0YSwgYWVzKHggPSBUaWVyLklJLCB5ID0gTWVhbiwgZmlsbCA9IFNhbXBsZSkpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3I9ImJsYWNrIikgKyBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbiAtIFNELCB5bWF4ID0gTWVhbiArIFNEKSwgd2lkdGggPSAwLjIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSkgKyB5bGFiKGV4cHJlc3Npb24oYXRvcCgiS0VHRyBUaWVyIElJIENhdGVnb3JpZXMiLCBwYXN0ZSgiR2VuZSBDb3VudHMiKSkpKSArIHRoZW1lX2NsYXNzaWMoKSArIHRoZW1lKGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xMCksIGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTIpLCBheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLCBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpLCBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT04KSwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpKSArIHNjYWxlX3NpemUoZ3VpZGU9RkFMU0UpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoImdyYXk4MyIsInBhbGVncmVlbiIsICJncmVlbjMiLCAiZGFya2dyZWVuIikpICsgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBmdW5jdGlvbihUaWVyLklJKSBzdHJfd3JhcChUaWVyLklJLCB3aWR0aCA9IDEwKSkgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSwgbGltaXRzID0gYygwLCA4MDAwMDApKSArIGFubm90YXRlKGdlb209InRleHQiLCB4PTAuOTAsIHk9NzUwMDAwLCBsYWJlbD0iYSIpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9MS4xMiwgeT00NzUwMDAsIGxhYmVsPSJiIikgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0xLjM1LCB5PTQ3NTAwMCwgbGFiZWw9ImIiKSArIGFubm90YXRlKGdlb209InRleHQiLCB4PTEuOSwgeT0zNTAwMDAsIGxhYmVsPSJhIikgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0yLjEyLCB5PTYwMDAwMCwgbGFiZWw9ImIiKSArIGFubm90YXRlKGdlb209InRleHQiLCB4PTIuMzUsIHk9NjAwMDAwLCBsYWJlbD0iYiIpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9My4xMiwgeT0xNTAwMDAsIGxhYmVsPSJpdGFsaWMoTi5TLikiLCBwYXJzZT1UUlVFKSArIGFubm90YXRlKGdlb209InRleHQiLCB4PTMuOSwgeT0xMDAwMDAsIGxhYmVsPSJhIikgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD00LjEyLCB5PTE1MDAwMCwgbGFiZWw9ImIiKSArIGFubm90YXRlKGdlb209InRleHQiLCB4PTQuMzUsIHk9MTIwMDAwLCBsYWJlbD0iYSIpCmBgYAoKYGBge3J9CnR1c3NfbWdfbXRfdElJX2JhcnBsb3QKYGBgCgojIyMjIyA3LjMuMS4yLiBUaWVyIElJSSBFeHByZXNzaW9uCgpDYWxjdWxhdGUgVFBNLW5vcm1hbGl6ZWQgZ2VuZSBjb3VudCBzdW1zIGZvciBlYWNoIFR1c3Mgc2FtcGxlIGluIGVhY2ggVGllciBJSUkgY2F0ZWdvcnkuCmBgYHtyfQojIENhbGN1bGF0ZSBUUE0tbm9ybWFsaXplZCBnZW5lIGNvdW50IHN1bXMgZm9yIGVhY2ggVHVzcyBzYW1wbGUgaW4gZWFjaCBUaWVyIElJSSBjYXRlZ29yeQp0dXNzX3RJSUlfc3VtPC10cG1fYWxsX2V4cF9hbm4gJT4lIGdyb3VwX2J5KFRpZXJfSUlJKSAlPiUgc3VtbWFyaXNlX2F0KHZhcnMoIlMxMDgzODIiLCJTMTA4MzgzIiwiUzEwODM5MSIsIlMxMDgzOTIiLCJTMTA4Mzk0IiwiUzEwODM5NiIpLCBzdW0pCnR1c3NfdElJSV9zdW08LXR1c3NfdElJSV9zdW0gJT4lIG11dGF0ZV9hdCh2YXJzKFMxMDgzODIsUzEwODM4MyxTMTA4MzkxLFMxMDgzOTIsUzEwODM5NCxTMTA4Mzk2KSwgZnVucyhyb3VuZCguLCAwKSkpCnR1c3NfdElJSV9zdW08LWFzLmRhdGEuZnJhbWUodHVzc190SUlJX3N1bSkKdHVzc190SUlJX3N1bTwtdHVzc190SUlJX3N1bVtvcmRlcigtdHVzc190SUlJX3N1bSRTMTA4MzgyKSxdCmBgYAoKYGBge3J9CiMgQ2FsY3VsYXRlIG1lYW4gdmFsdWVzIGZyb20gdGhlIHJlcGxpY2F0ZSBzdW1zCnR1c3NfdElJSV9zdW0kbWVhbnR1c3NfVDA8LWFwcGx5KHR1c3NfdElJSV9zdW1bLDI6M10sIDEsIG1lYW4pCnR1c3NfdElJSV9zdW0kbWVhbnR1c3NfVDQ8LWFwcGx5KHR1c3NfdElJSV9zdW1bLDQ6NV0sIDEsIG1lYW4pCnR1c3NfdElJSV9zdW0kbWVhbnR1c3NfVDI0PC1hcHBseSh0dXNzX3RJSUlfc3VtWyw2OjddLCAxLCBtZWFuKQp0dXNzX3RJSUlfc3VtPC10dXNzX3RJSUlfc3VtICU+JSBtdXRhdGVfYXQodmFycyhtZWFudHVzc19UMCxtZWFudHVzc19UNCxtZWFudHVzc19UMjQpLCBmdW5zKHJvdW5kKC4sIDApKSkKCiMgQ2FsY3VsYXRlIHNkIHZhbHVlcyBmcm9tIHRoZSByZXBsaWNhdGUgc3Vtcwp0dXNzX3RJSUlfc3VtJHNkdHVzc19UMDwtYXBwbHkodHVzc190SUlJX3N1bVssMjozXSwgMSwgc2QpCnR1c3NfdElJSV9zdW0kc2R0dXNzX1Q0PC1hcHBseSh0dXNzX3RJSUlfc3VtWyw0OjVdLCAxLCBzZCkKdHVzc190SUlJX3N1bSRzZHR1c3NfVDI0PC1hcHBseSh0dXNzX3RJSUlfc3VtWyw2OjddLCAxLCBzZCkKdHVzc190SUlJX3N1bTwtdHVzc190SUlJX3N1bSAlPiUgbXV0YXRlX2F0KHZhcnMoc2R0dXNzX1QwLHNkdHVzc19UNCxzZHR1c3NfVDI0KSwgZnVucyhyb3VuZCguLCAwKSkpCgojIFdyaXRlIGRhdGEgdG8gLmNzdiBmaWxlCndyaXRlLmNzdih0dXNzX3RJSUlfc3VtLCAnTm9ybS5SZXN1bHRzL3R1c3Mucm5hLnRJSUkubWVhbi5zZC5jc3YnKQoKIyBTdWJzZXQgTWVhbiB2YWx1ZXMKdHVzc190SUlJX21lYW48LXN1YnNldCh0dXNzX3RJSUlfc3VtLCBzZWxlY3Q9YyhUaWVyX0lJSSxtZWFudHVzc19UMCxtZWFudHVzc19UNCxtZWFudHVzc19UMjQpKQpuYW1lcyh0dXNzX3RJSUlfbWVhbik8LWMoIlRpZXIgSUlJIiwgIlR1c3MtVDAiLCAiVHVzcy1UNCIsICJUdXNzLVQyNCIpCgojIFN1YnNldCBTRCB2YWx1ZXMKdHVzc190SUlJX3NkPC1zdWJzZXQodHVzc190SUlJX3N1bSwgc2VsZWN0PWMoVGllcl9JSUksc2R0dXNzX1QwLHNkdHVzc19UNCxzZHR1c3NfVDI0KSkKbmFtZXModHVzc190SUlJX3NkKTwtYygiVGllciBJSUkiLCAiVHVzcy1UMCIsICJUdXNzLVQ0IiwgIlR1c3MtVDI0IikKCiMgUmVtZW1iZXIgIlRpZXIgSUlJIiBhcyBub24tbnVtZXJpYyB2YWx1ZXMKdHVzc190SUlJX21lYW5fVGllcklJSTwtdHVzc190SUlJX21lYW4kYFRpZXIgSUlJYAp0dXNzX3RJSUlfc2RfVGllcklJSTwtdHVzc190SUlJX3NkJGBUaWVyIElJSWAKCiMgVHJhbnNwb3NlIGFsbCBidXQgZmlyc3QgY29sdW1uIChUaWVyIElJKQp0dXNzX3RJSUlfbWVhbjwtYXMuZGF0YS5mcmFtZSh0KHR1c3NfdElJSV9tZWFuWywtMV0pKQpjb2xuYW1lcyh0dXNzX3RJSUlfbWVhbik8LXR1c3NfdElJSV9tZWFuX1RpZXJJSUkKdHVzc190SUlJX3NkPC1hcy5kYXRhLmZyYW1lKHQodHVzc190SUlJX3NkWywtMV0pKQpjb2xuYW1lcyh0dXNzX3RJSUlfc2QpPC10dXNzX3RJSUlfc2RfVGllcklJSQoKIyBDb21iaW5lIG1lYW4gYW5kIHNkIGludG8gc2luZ2xlIGNvbHVtbiB3aXRoIMKxIGRpdmlkZXIKdHVzc190SUlJX3RhYmxlPC1hcy5kYXRhLmZyYW1lKGRvLmNhbGwoY2JpbmQsIGxhcHBseSgxOm5jb2wodHVzc190SUlJX21lYW4pLCBmdW5jdGlvbihpKSBwYXN0ZTAodHVzc190SUlJX21lYW5bICwgaV0sICIgwrEgIiwgdHVzc190SUlJX3NkWyAsIGldKSkpKQoKIyBUcmFuc3Bvc2UgdGhlIHRhYmxlIGJhY2sKdHVzc190SUlJX3RhYmxlPC10KHR1c3NfdElJSV90YWJsZSkKCiMgUmVuYW1lIGNvbHVtbnMgdG8gU2l0ZXMKY29sbmFtZXModHVzc190SUlJX3RhYmxlKTwtYygiVHVzc29jayAoVDApIiwgIlR1c3NvY2sgKFQ0KSIsICJUdXNzb2NrIChUMjQpIikKCnJvd25hbWVzKHR1c3NfdElJSV90YWJsZSk8LXR1c3NfdElJSV9tZWFuX1RpZXJJSUkKYGBgCgpSdW4gc3RhdGlzdGljYWwgdGVzdHMgdG8gZGV0ZXJtaW5lIGlmIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGV4aXN0IGJldHdlZW4gc2FtcGxpbmcgdGltZXBvaW50cyBmb3IgZWFjaCBUaWVyIEtFR0cgY2F0ZWdvcnkuIENsaWNrIG9uIHRoZSAqKlNob3cvSGlkZSoqIGJ1dHRvbiB0byBzZWUgdGhlIHN0YXRpc3RpY3MuCgo8YnV0dG9uIGNsYXNzPSJidG4gYnRuLXByaW1hcnkiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9IiNCbG9ja05hbWU3Ij4gU2hvdy9IaWRlIDwvYnV0dG9uPiAgCjxkaXYgaWQ9IkJsb2NrTmFtZTciIGNsYXNzPSJjb2xsYXBzZSI+CmBgYHtyfQojIFN1YnNldCB0aGUgInN1bSIgdmFsdWVzIGZvciBlYWNoIHNhbXBsZQp0dXNzX3RJSUlfc3RhdHM8LXN1YnNldCh0dXNzX3RJSUlfc3VtLCBzZWxlY3Q9YyhUaWVyX0lJSSxTMTA4MzgyLFMxMDgzODMsUzEwODM5MSxTMTA4MzkyLFMxMDgzOTQsUzEwODM5NikpCgpyb3duYW1lcyh0dXNzX3RJSUlfc3RhdHMpIDwtIHR1c3NfdElJSV9zdGF0cyRUaWVyX0lJSQp0dXNzX3RJSUlfc3RhdHM8LWFzLmRhdGEuZnJhbWUodCh0dXNzX3RJSUlfc3RhdHNbLTFdKSkKCiMgQWRkIHRoZSB0aW1lcG9pbnQgY29sdW1uIHRvIHRoZSBzdW0gdGFibGUKdHVzc190SUlJX3N0YXRzPC1kYXRhLmZyYW1lKFRpbWVwb2ludCx0dXNzX3RJSUlfc3RhdHMpCgojIFN1YnNldCByZXNwb25zZSB2YXJpYWJsZXMgZm9yIE1BTk9WQQp0dXNzX3RJSUlfc3RhdHMkcmVzcG9uc2UgPC0gYXMubWF0cml4KHR1c3NfdElJSV9zdGF0c1ssIDI6MjZdKQoKIyBNQU5PVkEgdGVzdAp0dXNzX3RJSUlfbWFub3ZhIDwtIG1hbm92YShyZXNwb25zZSB+IFRpbWVwb2ludCwgZGF0YT10dXNzX3RJSUlfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElJSV9tYW5vdmEpCmBgYAoKUnVuIEFOT1ZBIGZvciBlYWNoIGNhdGVnb3J5IG9mIGludGVyZXN0IChzaWduaWZpY2FudCBpbiBNQU5PVkEpCmBgYHtyfQojIE92ZXJ2aWV3CnR1c3NfdElJSV9hb3YxPC1hb3YoT3ZlcnZpZXcuflRpbWVwb2ludCxkYXRhPXR1c3NfdElJSV9zdGF0cykKc3VtbWFyeS5hb3YodHVzc190SUlJX2FvdjEpClR1a2V5SFNEKHR1c3NfdElJSV9hb3YxKQoKIyBDYXJib2h5ZHJhdGUgTWV0YWJvbGlzbQp0dXNzX3RJSUlfYW92MjwtYW92KENhcmJvaHlkcmF0ZS5tZXRhYm9saXNtLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJSUlfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElJSV9hb3YyKQpUdWtleUhTRCh0dXNzX3RJSUlfYW92MikKCiMgVHJhbnNsYXRpb24KdHVzc190SUlJX2FvdjM8LWFvdihUcmFuc2xhdGlvbi5+VGltZXBvaW50LGRhdGE9dHVzc190SUlJX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJSUlfYW92MykKVHVrZXlIU0QodHVzc190SUlJX2FvdjMpCgojIEZvbGRpbmcsIFNvcnRpbmcsIGFuZCBEZWdyYWRhdGlvbgp0dXNzX3RJSUlfYW92NDwtYW92KEZvbGRpbmcuLnNvcnRpbmcuYW5kLmRlZ3JhZGF0aW9uLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJSUlfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElJSV9hb3Y0KQpUdWtleUhTRCh0dXNzX3RJSUlfYW92NCkKCiMgTWV0YWJvbGlzbSBvZiBDb2ZhY3RvcnMgYW5kIFZpdGFtaW5zCnR1c3NfdElJSV9hb3Y1PC1hb3YoTWV0YWJvbGlzbS5vZi5jb2ZhY3RvcnMuYW5kLnZpdGFtaW5zLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJSUlfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElJSV9hb3Y1KQpUdWtleUhTRCh0dXNzX3RJSUlfYW92NSkKCiMgQW1pbm8gQWNpZCBNZXRhYm9saXNtCnR1c3NfdElJSV9hb3Y2PC1hb3YoQW1pbm8uYWNpZC5tZXRhYm9saXNtLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJSUlfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElJSV9hb3Y2KQpUdWtleUhTRCh0dXNzX3RJSUlfYW92NikKCiMgQ2VsbCBHcm93dGggYW5kIERlYXRoCnR1c3NfdElJSV9hb3Y3PC1hb3YoQ2VsbC5ncm93dGguYW5kLmRlYXRoLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJSUlfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElJSV9hb3Y3KQpUdWtleUhTRCh0dXNzX3RJSUlfYW92NykKCiMgWGVub2Jpb3RpY3MgQmlvZGVncmFkYXRpb24gYW5kIE1ldGFib2xpc20KdHVzc190SUlJX2Fvdjg8LWFvdihYZW5vYmlvdGljcy5iaW9kZWdyYWRhdGlvbi5hbmQubWV0YWJvbGlzbS5+VGltZXBvaW50LGRhdGE9dHVzc190SUlJX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJSUlfYW92OCkKVHVrZXlIU0QodHVzc190SUlJX2FvdjgpCmBgYAo8L2Rpdj4KCiMjIyMjIDcuMy4xLjMuIFRpZXIgSVYgRXhwcmVzc2lvbgoKQ2FsY3VsYXRlIFRQTS1ub3JtYWxpemVkIGdlbmUgY291bnQgc3VtcyBmb3IgZWFjaCBUdXNzIHNhbXBsZSBpbiBlYWNoIFRpZXIgSVYgY2F0ZWdvcnkuCmBgYHtyfQojIENhbGN1bGF0ZSBUUE0tbm9ybWFsaXplZCBnZW5lIGNvdW50IHN1bXMgZm9yIGVhY2ggVHVzcyBzYW1wbGUgaW4gZWFjaCBUaWVyIElWIGNhdGVnb3J5CnR1c3NfdElWX3N1bTwtdHBtX2FsbF9leHBfYW5uICU+JSBncm91cF9ieShUaWVyX0lWKSAlPiUgc3VtbWFyaXNlX2F0KHZhcnMoIlMxMDgzODIiLCJTMTA4MzgzIiwiUzEwODM5MSIsIlMxMDgzOTIiLCJTMTA4Mzk0IiwiUzEwODM5NiIpLCBzdW0pCnR1c3NfdElWX3N1bTwtdHVzc190SVZfc3VtICU+JSBtdXRhdGVfYXQodmFycyhTMTA4MzgyLFMxMDgzODMsUzEwODM5MSxTMTA4MzkyLFMxMDgzOTQsUzEwODM5NiksIGZ1bnMocm91bmQoLiwgMCkpKQp0dXNzX3RJVl9zdW08LWFzLmRhdGEuZnJhbWUodHVzc190SVZfc3VtKQp0dXNzX3RJVl9zdW08LXR1c3NfdElWX3N1bVtvcmRlcigtdHVzc190SVZfc3VtJFMxMDgzODIpLF0KYGBgCgpgYGB7cn0KIyBDYWxjdWxhdGUgbWVhbiB2YWx1ZXMgZnJvbSB0aGUgcmVwbGljYXRlIHN1bXMKdHVzc190SVZfc3VtJG1lYW50dXNzX1QwPC1hcHBseSh0dXNzX3RJVl9zdW1bLDI6M10sIDEsIG1lYW4pCnR1c3NfdElWX3N1bSRtZWFudHVzc19UNDwtYXBwbHkodHVzc190SVZfc3VtWyw0OjVdLCAxLCBtZWFuKQp0dXNzX3RJVl9zdW0kbWVhbnR1c3NfVDI0PC1hcHBseSh0dXNzX3RJVl9zdW1bLDY6N10sIDEsIG1lYW4pCnR1c3NfdElWX3N1bTwtdHVzc190SVZfc3VtICU+JSBtdXRhdGVfYXQodmFycyhtZWFudHVzc19UMCxtZWFudHVzc19UNCxtZWFudHVzc19UMjQpLCBmdW5zKHJvdW5kKC4sIDApKSkKCiMgQ2FsY3VsYXRlIHNkIHZhbHVlcyBmcm9tIHRoZSByZXBsaWNhdGUgc3Vtcwp0dXNzX3RJVl9zdW0kc2R0dXNzX1QwPC1hcHBseSh0dXNzX3RJVl9zdW1bLDI6M10sIDEsIHNkKQp0dXNzX3RJVl9zdW0kc2R0dXNzX1Q0PC1hcHBseSh0dXNzX3RJVl9zdW1bLDQ6NV0sIDEsIHNkKQp0dXNzX3RJVl9zdW0kc2R0dXNzX1QyNDwtYXBwbHkodHVzc190SVZfc3VtWyw2OjddLCAxLCBzZCkKdHVzc190SVZfc3VtPC10dXNzX3RJVl9zdW0gJT4lIG11dGF0ZV9hdCh2YXJzKHNkdHVzc19UMCxzZHR1c3NfVDQsc2R0dXNzX1QyNCksIGZ1bnMocm91bmQoLiwgMCkpKQoKIyBXcml0ZSBkYXRhIHRvIC5jc3YgZmlsZQp3cml0ZS5jc3YodHVzc190SVZfc3VtLCAnTm9ybS5SZXN1bHRzL3R1c3Mucm5hLnRJVi5tZWFuLnNkLmNzdicpCgojIFN1YnNldCBNZWFuIHZhbHVlcwp0dXNzX3RJVl9tZWFuPC1zdWJzZXQodHVzc190SVZfc3VtLCBzZWxlY3Q9YyhUaWVyX0lWLG1lYW50dXNzX1QwLG1lYW50dXNzX1Q0LG1lYW50dXNzX1QyNCkpCm5hbWVzKHR1c3NfdElWX21lYW4pPC1jKCJUaWVyIElWIiwgIlR1c3MtVDAiLCAiVHVzcy1UNCIsICJUdXNzLVQyNCIpCgojIFN1YnNldCBTRCB2YWx1ZXMKdHVzc190SVZfc2Q8LXN1YnNldCh0dXNzX3RJVl9zdW0sIHNlbGVjdD1jKFRpZXJfSVYsc2R0dXNzX1QwLHNkdHVzc19UNCxzZHR1c3NfVDI0KSkKbmFtZXModHVzc190SVZfc2QpPC1jKCJUaWVyIElWIiwgIlR1c3MtVDAiLCAiVHVzcy1UNCIsICJUdXNzLVQyNCIpCgojIFJlbWVtYmVyICJUaWVyIElWIiBhcyBub24tbnVtZXJpYyB2YWx1ZXMKdHVzc190SVZfbWVhbl9UaWVySVY8LXR1c3NfdElWX21lYW4kYFRpZXIgSVZgCnR1c3NfdElWX3NkX1RpZXJJVjwtdHVzc190SVZfc2QkYFRpZXIgSVZgCgojIFRyYW5zcG9zZSBhbGwgYnV0IGZpcnN0IGNvbHVtbiAoVGllciBJVikKdHVzc190SVZfbWVhbjwtYXMuZGF0YS5mcmFtZSh0KHR1c3NfdElWX21lYW5bLC0xXSkpCmNvbG5hbWVzKHR1c3NfdElWX21lYW4pPC10dXNzX3RJVl9tZWFuX1RpZXJJVgp0dXNzX3RJVl9zZDwtYXMuZGF0YS5mcmFtZSh0KHR1c3NfdElWX3NkWywtMV0pKQpjb2xuYW1lcyh0dXNzX3RJVl9zZCk8LXR1c3NfdElWX3NkX1RpZXJJVgoKIyBDb21iaW5lIG1lYW4gYW5kIHNkIGludG8gc2luZ2xlIGNvbHVtbiB3aXRoIMKxIGRpdmlkZXIKdHVzc190SVZfdGFibGU8LWFzLmRhdGEuZnJhbWUoZG8uY2FsbChjYmluZCwgbGFwcGx5KDE6bmNvbCh0dXNzX3RJVl9tZWFuKSwgZnVuY3Rpb24oaSkgcGFzdGUwKHR1c3NfdElWX21lYW5bICwgaV0sICIgwrEgIiwgdHVzc190SVZfc2RbICwgaV0pKSkpCgojIFRyYW5zcG9zZSB0aGUgdGFibGUgYmFjawp0dXNzX3RJVl90YWJsZTwtdCh0dXNzX3RJVl90YWJsZSkKCiMgUmVuYW1lIGNvbHVtbnMgdG8gU2l0ZXMKY29sbmFtZXModHVzc190SVZfdGFibGUpPC1jKCJUdXNzb2NrIChUMCkiLCAiVHVzc29jayAoVDQpIiwgIlR1c3NvY2sgKFQyNCkiKQoKcm93bmFtZXModHVzc190SVZfdGFibGUpPC10dXNzX3RJVl9tZWFuX1RpZXJJVgoKI3R1c3NfdElWX3RhYmxlCmBgYAoKUnVuIHN0YXRpc3RpY2FsIHRlc3RzIHRvIGRldGVybWluZSBpZiBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBleGlzdCBiZXR3ZWVuIHNhbXBsaW5nIHRpbWVwb2ludHMgZm9yIGVhY2ggVGllciBLRUdHIGNhdGVnb3J5LiBDbGljayBvbiB0aGUgKipTaG93L0hpZGUqKiBidXR0b24gdG8gc2VlIHRoZSBzdGF0aXN0aWNzLgoKPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1wcmltYXJ5IiBkYXRhLXRvZ2dsZT0iY29sbGFwc2UiIGRhdGEtdGFyZ2V0PSIjQmxvY2tOYW1lOCI+IFNob3cvSGlkZSA8L2J1dHRvbj4gIAo8ZGl2IGlkPSJCbG9ja05hbWU4IiBjbGFzcz0iY29sbGFwc2UiPgpgYGB7cn0KIyBTdWJzZXQgdGhlICJzdW0iIHZhbHVlcyBmb3IgZWFjaCBzYW1wbGUKdHVzc190SVZfc3RhdHM8LXN1YnNldCh0dXNzX3RJVl9zdW0sIHNlbGVjdD1jKFRpZXJfSVYsUzEwODM4MixTMTA4MzgzLFMxMDgzOTEsUzEwODM5MixTMTA4Mzk0LFMxMDgzOTYpKQoKcm93bmFtZXModHVzc190SVZfc3RhdHMpIDwtIHR1c3NfdElWX3N0YXRzJFRpZXJfSVYKdHVzc190SVZfc3RhdHM8LWFzLmRhdGEuZnJhbWUodCh0dXNzX3RJVl9zdGF0c1stMV0pKQoKIyBBZGQgdGhlIHRpbWVwb2ludCBjb2x1bW4gdG8gdGhlIHN1bSB0YWJsZQp0dXNzX3RJVl9zdGF0czwtZGF0YS5mcmFtZShUaW1lcG9pbnQsdHVzc190SVZfc3RhdHMpCgojIFN1YnNldCByZXNwb25zZSB2YXJpYWJsZXMgZm9yIE1BTk9WQQp0dXNzX3RJVl9zdGF0cyRyZXNwb25zZSA8LSBhcy5tYXRyaXgodHVzc190SVZfc3RhdHNbLCAyOjIyN10pCgojIE1BTk9WQSB0ZXN0CnR1c3NfdElWX21hbm92YSA8LSBtYW5vdmEocmVzcG9uc2UgfiBUaW1lcG9pbnQsIGRhdGE9dHVzc190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElWX21hbm92YSkKYGBgCgpSdW4gQU5PVkEgZm9yIGVhY2ggY2F0ZWdvcnkgb2YgaW50ZXJlc3QgKHNpZ25pZmljYW50IGluIE1BTk9WQSkKYGBge3J9CiMgQ2FyYm9uIE1ldGFib2xpc20KdHVzc190SVZfYW92MTwtYW92KFgwMTIwMC5DYXJib24ubWV0YWJvbGlzbS4uUEFUSC5rbzAxMjAwLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3YodHVzc190SVZfYW92MSkKVHVrZXlIU0QodHVzc190SVZfYW92MSkKCiMgUmlib3NvbWUKdHVzc190SVZfYW92MjwtYW92KFgwMzAxMC5SaWJvc29tZS4uUEFUSC5rbzAzMDEwLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3YodHVzc190SVZfYW92MikKVHVrZXlIU0QodHVzc190SVZfYW92MikKCiMgUk5BIERlZ3JhZGF0aW9uCnR1c3NfdElWX2FvdjM8LWFvdihYMDMwMTguUk5BLmRlZ3JhZGF0aW9uLi5QQVRILmtvMDMwMTguflRpbWVwb2ludCxkYXRhPXR1c3NfdElWX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJVl9hb3YzKQpUdWtleUhTRCh0dXNzX3RJVl9hb3YzKQoKIyBGYXR0eSBBY2lkIE1ldGFib2xpc20KdHVzc190SVZfYW92NDwtYW92KFgwMTIxMi5GYXR0eS5hY2lkLm1ldGFib2xpc20uLlBBVEgua28wMTIxMi5+VGltZXBvaW50LGRhdGE9dHVzc190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElWX2FvdjQpClR1a2V5SFNEKHR1c3NfdElWX2FvdjQpCgojIEJ1dG9uYW90ZSBNZXRhYm9saXNtCnR1c3NfdElWX2FvdjU8LWFvdihYMDA2NTAuQnV0YW5vYXRlLm1ldGFib2xpc20uLlBBVEgua28wMDY1MC5+VGltZXBvaW50LGRhdGE9dHVzc190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElWX2FvdjUpClR1a2V5SFNEKHR1c3NfdElWX2FvdjUpCgojIEdseWNvbHlzaXMgR2x1Y29uZW9nZW5lc2lzCnR1c3NfdElWX2FvdjY8LWFvdihYMDAwMTAuR2x5Y29seXNpcy4uLkdsdWNvbmVvZ2VuZXNpcy4uUEFUSC5rbzAwMDEwLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3YodHVzc190SVZfYW92NikKVHVrZXlIU0QodHVzc190SVZfYW92NikKCiMgQ2F1bG9iYWN0ZXIgQ2VsbCBDeWNsZQp0dXNzX3RJVl9hb3Y3PC1hb3YoWDA0MTEyLkNlbGwuY3ljbGUuLi5DYXVsb2JhY3Rlci4uUEFUSC5rbzA0MTEyLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3YodHVzc190SVZfYW92NykKVHVrZXlIU0QodHVzc190SVZfYW92NykKCiMgTmljb3RpbmF0ZSBhbmQgTmljb3RpbmFtaWRlIE1ldGFib2xpc20KdHVzc190SVZfYW92ODwtYW92KFgwMDc2MC5OaWNvdGluYXRlLmFuZC5uaWNvdGluYW1pZGUubWV0YWJvbGlzbS4uUEFUSC5rbzAwNzYwLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3YodHVzc190SVZfYW92OCkKVHVrZXlIU0QodHVzc190SVZfYW92OCkKCiMgRGVncmFkYXRpb24gb2YgQXJvbWF0aWMgQ29tcG91bmRzCnR1c3NfdElWX2Fvdjk8LWFvdihYMDEyMjAuRGVncmFkYXRpb24ub2YuYXJvbWF0aWMuY29tcG91bmRzLi5QQVRILmtvMDEyMjAuflRpbWVwb2ludCxkYXRhPXR1c3NfdElWX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJVl9hb3Y5KQpUdWtleUhTRCh0dXNzX3RJVl9hb3Y5KQoKIyBTdGFyY2ggYW5kIFN1Y3Jvc2UgTWV0YWJvbGlzbQp0dXNzX3RJVl9hb3YxMDwtYW92KFgwMDUwMC5TdGFyY2guYW5kLnN1Y3Jvc2UubWV0YWJvbGlzbS4uUEFUSC5rbzAwNTAwLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3YodHVzc190SVZfYW92MTApClR1a2V5SFNEKHR1c3NfdElWX2FvdjEwKQoKIyBQb3JwaHlyaW4gYW5kIENobG9yb3BoeWxsIE1ldGFib2xpc20KdHVzc190SVZfYW92MTE8LWFvdihYMDA4NjAuUG9ycGh5cmluLmFuZC5jaGxvcm9waHlsbC5tZXRhYm9saXNtLi5QQVRILmtvMDA4NjAuflRpbWVwb2ludCxkYXRhPXR1c3NfdElWX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJVl9hb3YxMSkKVHVrZXlIU0QodHVzc190SVZfYW92MTEpCgojIFB5cnV2YXRlIE1ldGFib2xpc20KdHVzc190SVZfYW92MTI8LWFvdihYMDA2MjAuUHlydXZhdGUubWV0YWJvbGlzbS4uUEFUSC5rbzAwNjIwLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3YodHVzc190SVZfYW92MTIpClR1a2V5SFNEKHR1c3NfdElWX2FvdjEyKQoKIyBOaXRyb3RvbHVlbmUgRGVncmFkYXRpb24KdHVzc190SVZfYW92MTM8LWFvdihYMDA2MzMuTml0cm90b2x1ZW5lLmRlZ3JhZGF0aW9uLi5QQVRILmtvMDA2MzMuflRpbWVwb2ludCxkYXRhPXR1c3NfdElWX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJVl9hb3YxMykKVHVrZXlIU0QodHVzc190SVZfYW92MTMpCgojIFRoaWFtaW5lIE1ldGFib2xpc20KdHVzc190SVZfYW92MTQ8LWFvdihYMDA3MzAuVGhpYW1pbmUubWV0YWJvbGlzbS4uUEFUSC5rbzAwNzMwLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3YodHVzc190SVZfYW92MTQpClR1a2V5SFNEKHR1c3NfdElWX2FvdjE0KQoKIyBQYW50b3RoZW5hdGUgYW5kIENvQSBCaW9zeW50aGVzaXMKdHVzc190SVZfYW92MTU8LWFvdihYMDA3NzAuUGFudG90aGVuYXRlLmFuZC5Db0EuYmlvc3ludGhlc2lzLi5QQVRILmtvMDA3NzAuflRpbWVwb2ludCxkYXRhPXR1c3NfdElWX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJVl9hb3YxNSkKVHVrZXlIU0QodHVzc190SVZfYW92MTUpCgojIEdseWNlcm9saXBpZCBNZXRhYm9saXNtCnR1c3NfdElWX2FvdjE2PC1hb3YoWDAwNTYxLkdseWNlcm9saXBpZC5tZXRhYm9saXNtLi5QQVRILmtvMDA1NjEuflRpbWVwb2ludCxkYXRhPXR1c3NfdElWX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJVl9hb3YxNikKVHVrZXlIU0QodHVzc190SVZfYW92MTYpCgojIEFyZ2luaW5lIGFuZCBQcm9saW5lIE1ldGFib2xpc20KdHVzc190SVZfYW92MTc8LWFvdihYMDAzMzAuQXJnaW5pbmUuYW5kLnByb2xpbmUubWV0YWJvbGlzbS4uUEFUSC5rbzAwMzMwLn5UaW1lcG9pbnQsZGF0YT10dXNzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3YodHVzc190SVZfYW92MTcpClR1a2V5SFNEKHR1c3NfdElWX2FvdjE3KQoKIyBTdWxmdXIgUmVsYXkgU3lzdGVtCnR1c3NfdElWX2FvdjE5PC1hb3YoWDA0MTIyLlN1bGZ1ci5yZWxheS5zeXN0ZW0uLlBBVEgua28wNDEyMi5+VGltZXBvaW50LGRhdGE9dHVzc190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElWX2FvdjE5KQpUdWtleUhTRCh0dXNzX3RJVl9hb3YxOSkKCiMgSGlzdGlkaW5lIE1ldGFib2xpc20KdHVzc190SVZfYW92MjA8LWFvdihYMDAzNDAuSGlzdGlkaW5lLm1ldGFib2xpc20uLlBBVEgua28wMDM0MC5+VGltZXBvaW50LGRhdGE9dHVzc190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElWX2FvdjIwKQpUdWtleUhTRCh0dXNzX3RJVl9hb3YyMCkKCiMgU3Rlcm9pZCBIb3Jtb25lIEJpb3N5bnRoZXNpcwp0dXNzX3RJVl9hb3YyMzwtYW92KFgwMDE0MC5TdGVyb2lkLmhvcm1vbmUuYmlvc3ludGhlc2lzLi5QQVRILmtvMDAxNDAuflRpbWVwb2ludCxkYXRhPXR1c3NfdElWX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJVl9hb3YyMykKVHVrZXlIU0QodHVzc190SVZfYW92MjMpCgojIFNlc3F1aXRlcnBlbm9pZCBhbmQgVHJpdGVycGVub2lkIEJpb3N5bnRoZXNpcwp0dXNzX3RJVl9hb3YyNDwtYW92KFgwMDkwOS5TZXNxdWl0ZXJwZW5vaWQuYW5kLnRyaXRlcnBlbm9pZC5iaW9zeW50aGVzaXMuLlBBVEgua28wMDkwOS5+VGltZXBvaW50LGRhdGE9dHVzc190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElWX2FvdjI0KQpUdWtleUhTRCh0dXNzX3RJVl9hb3YyNCkKCiMgQmVuem9hdGUgRGVncmFkYXRpb24KdHVzc190SVZfYW92MjU8LWFvdihYMDAzNjIuQmVuem9hdGUuZGVncmFkYXRpb24uLlBBVEgua28wMDM2Mi5+VGltZXBvaW50LGRhdGE9dHVzc190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElWX2FvdjI1KQpUdWtleUhTRCh0dXNzX3RJVl9hb3YyNSkKCiMgQ2hsb3JvYWxrYW5lIGFuZCBDaGxvcm9hbGtlbmUgRGVncmFkYXRpb24KdHVzc190SVZfYW92MjY8LWFvdihYMDA2MjUuQ2hsb3JvYWxrYW5lLmFuZC5jaGxvcm9hbGtlbmUuZGVncmFkYXRpb24uLlBBVEgua28wMDYyNS5+VGltZXBvaW50LGRhdGE9dHVzc190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElWX2FvdjI2KQpUdWtleUhTRCh0dXNzX3RJVl9hb3YyNikKCiMgQmlvdGluIE1ldGFib2xpc20KdHVzc190SVZfYW92Mjc8LWFvdihYMDA3ODAuQmlvdGluLm1ldGFib2xpc20uLlBBVEgua28wMDc4MC5+VGltZXBvaW50LGRhdGE9dHVzc190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElWX2FvdjI3KQpUdWtleUhTRCh0dXNzX3RJVl9hb3YyNykKCiMgTHlzaW5lIEJpb3N5bnRoZXNpcwp0dXNzX3RJVl9hb3YyODwtYW92KFgwMDMwMC5MeXNpbmUuYmlvc3ludGhlc2lzLi5QQVRILmtvMDAzMDAuflRpbWVwb2ludCxkYXRhPXR1c3NfdElWX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJVl9hb3YyOCkKVHVrZXlIU0QodHVzc190SVZfYW92MjgpCgojIE1BUEsgU2lnbmFsaW5nIFBhdGh3YXkKdHVzc190SVZfYW92Mjk8LWFvdihYMDQwMTYuTUFQSy5zaWduYWxpbmcucGF0aHdheS4uLnBsYW50Li5QQVRILmtvMDQwMTYuflRpbWVwb2ludCxkYXRhPXR1c3NfdElWX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX3RJVl9hb3YyOSkKVHVrZXlIU0QodHVzc190SVZfYW92MjkpCgojIEFyZ2luaW5lIEJpb3N5bnRoZXNpcwp0dXNzX3RJVl9hb3YzMDwtYW92KFgwMDIyMC5BcmdpbmluZS5iaW9zeW50aGVzaXMuLlBBVEgua28wMDIyMC5+VGltZXBvaW50LGRhdGE9dHVzc190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElWX2FvdjMwKQpUdWtleUhTRCh0dXNzX3RJVl9hb3YzMCkKCiMgU3RhdXJvc3BvcmluZSBCaW9zeW50aGVzaXMKdHVzc190SVZfYW92MzI8LWFvdihYMDA0MDQuU3RhdXJvc3BvcmluZS5iaW9zeW50aGVzaXMuLlBBVEgua28wMDQwNC5+VGltZXBvaW50LGRhdGE9dHVzc190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElWX2FvdjMyKQpUdWtleUhTRCh0dXNzX3RJVl9hb3YzMikKCiMgRmVycm9wdG9zaXMKdHVzc190SVZfYW92MzM8LWFvdihYMDQyMTYuRmVycm9wdG9zaXMuLlBBVEgua28wNDIxNi5+VGltZXBvaW50LGRhdGE9dHVzc190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfdElWX2FvdjMzKQpUdWtleUhTRCh0dXNzX3RJVl9hb3YzMykKYGBgCjwvZGl2PgoKUGxvdCB0aGUgc2lnbmlmaWNhbnQgVHVzcy1NVCBLRUdHIHRpZXIgSVYgY2F0ZWdvcmllcyBieSB0aW1lcG9pbnQgYXMgYSBzaW5nbGUgYmFyY2hhcnQuCmBgYHtyLCBlY2hvPUZBTFNFfQp0dXNzX3RJVl9zdWJfYmFyZGF0YTwtcmVhZC5jc3YoIlBsb3QuRGF0YS90dXNzLnRJVi5zdWIuYmFyZGF0YS5jc3YiKQpgYGAKCmBgYHtyfQp0dXNzX3RJVl9zdWJfYmFyZGF0YSRTYW1wbGUgPC0gZmFjdG9yKHR1c3NfdElWX3N1Yl9iYXJkYXRhJFNhbXBsZSwgbGV2ZWxzPWMoIlR1c3MtTVQtVDI0IiwiVHVzcy1NVC1UNCIsIlR1c3MtTVQtVDAiKSkKCnR1c3NfdElWX3N1Yl9iYXJkYXRhJFRpZXIuSVYgPC0gZmFjdG9yICh0dXNzX3RJVl9zdWJfYmFyZGF0YSRUaWVyLklWLCBsZXZlbHM9YygiQ2VsbCBjeWNsZSAtIENhdWxvYmFjdGVyIChLMDQxMTIpIiwiUk5BIGRlZ3JhZGF0aW9uIChLMDMwMTgpIiwiUmlib3NvbWUgKEswMzAxMCkiLCJEZWdyYWRhdGlvbiBvZiBhcm9tYXRpYyBjb21wb3VuZHMgKEswMTIyMCkiLCJGYXR0eSBhY2lkIG1ldGFib2xpc20gKEswMTIxMikiLCJDYXJib24gbWV0YWJvbGlzbSAoSzAxMjAwKSIsIk5pY290aW5hdGUgYW5kIG5pY290aW5hbWlkZSBtZXRhYm9saXNtIChLMDA3NjApIiwiQnV0YW5vYXRlIG1ldGFib2xpc20gKEswMDY2NTApIiwiR2x5Y29seXNpcy1HbHVjb25lb2dlbmVzaXMgKEswMDAxMCkiKSkKCnR1c3NfdElWX3N1Yl9NVF9iYXJwbG90PC1nZ3Bsb3QodHVzc190SVZfc3ViX2JhcmRhdGEsIGFlcyh4ID0gVGllci5JViwgeT1NZWFuLCBmaWxsPVNhbXBsZSkpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siKSArIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBNZWFuIC0gU0QsIHltYXggPSBNZWFuICtTRCksIHdpZHRoID0gMC4yLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSkpICsgY29vcmRfZmxpcCgpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgMzApLCBwb3NpdGlvbj0iYm90dG9tIikgKyB5bGFiICgiUmVsYXRpdmUgQWJ1bmRhbmNlIikgKyB0aGVtZV9jbGFzc2ljKCkgKyB0aGVtZShheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksIHBsb3QubWFyZ2luID0gbWFyZ2luKDEwLCAyMCwgMTAsIDEwKSwgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTgpKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJkYXJrZ3JlZW4iLCJncmVlbjMiLCJwYWxlZ3JlZW4iKSwgZ3VpZGU9Z3VpZGVfbGVnZW5kKHJldmVyc2U9VFJVRSkpCgojIyMgU2F2aW5nIGFzIC5lcHMgZmlsZSB3aXRoIFIgVmlld2VyCiMgUmUtc2l6ZSB0aGUgdmlld2VyIHRvIHRoZSBmb2xsb3dpbmcgZGltZW5zaW9ucyBiZWZvcmUgc2F2aW5nIGFzIC5lcHMgZmlsZQojIEluIENvbnNvbGUsIHR5cGUgInR1c3Nfd3NfZG5hX3RJSUlfcGhlYXRtYXAiCiMgSW4gUGxvdCBWaWV3ZXIsIGNsaWNrICJFeHBvcnQiIC0tPiAiU2F2ZSBhcyBJbWFnZSIKIyBXaWR0aDogNjAwICBIZWlnaHQ6IDYwMAojIENsaWNrICJVcGRhdGUgUHJldmlldyIgLS0+IHNhdmUgYXMgIkVQUyIgZmlsZSB0eXBlIC0tPiByZW5hbWUgYXMgRmlnLjQuQmFyCmBgYAoKYGBge3J9CnR1c3NfdElWX3N1Yl9NVF9iYXJwbG90CmBgYAoKUGxvdCB0aGUgY29tYmluZWQgVHVzcy1NRyBhbmQgV1MtTUcgS0VHRyB0aWVyIElJSSBjYXRlZ29yaWVzIGFzIGEgc2luZ2xlIGJhcmNoYXJ0LgpgYGB7ciwgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0KdHVzc190SVZfYmFyZGF0YTwtcmVhZC5jc3YoIlBsb3QuRGF0YS90dXNzLnRJVi5iYXJkYXRhLmNzdiIpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9CnR1c3NfdElWX2JhcmRhdGEkU2FtcGxlIDwtIGZhY3Rvcih0dXNzX3RJVl9iYXJkYXRhJFNhbXBsZSwgbGV2ZWxzPWMoIlR1c3MtTVQtVDAiLCAiVHVzcy1NVC1UNCIsICJUdXNzLU1ULVQyNCIpKQoKdHVzc190SVZfYmFyZGF0YSRUaWVyLklWIDwtIGZhY3RvciAodHVzc190SVZfYmFyZGF0YSRUaWVyLklWLCBsZXZlbHM9YygiQXJnaW5pbmUgYmlvc3ludGhlc2lzIChLMDAyMjApIiwiTHlzaW5lIGJpb3N5bnRoZXNpcyAoSzAwMzAwKSIsIkFyZ2luaW5lIGFuZCBwcm9saW5lIG1ldGFib2xpc20gKEswMDMzMCkiLCJIaXN0aWRpbmUgbWV0YWJvbGlzbSAoSzAwMzQwKSIsIlN0YXVyb3Nwb3JpbmUgYmlvc3ludGhlc2lzIChLMDA0MDQpIiwiR2x5Y29seXNpcy1HbHVjb25lb2dlbmVzaXMgKEswMDAxMCkiLCJTdGFyY2ggYW5kIHN1Y3Jvc2UgbWV0YWJvbGlzbSAoSzAwNTAwKSIsIlB5cnV2YXRlIG1ldGFib2xpc20gKEswMDYyMCkiLCJCdXRhbm9hdGUgbWV0YWJvbGlzbSAoSzAwNjY1MCkiLCJTdGVyb2lkIGhvcm1vbmUgYmlvc3ludGhlc2lzIChLMDAxNDApIiwiR2x5Y2Vyb2xpcGlkIG1ldGFib2xpc20gKEswMDU2MSkiLCJUaGlhbWluZSBtZXRhYm9saXNtIChLMDA3MzApIiwiTmljb3RpbmF0ZSBhbmQgbmljb3RpbmFtaWRlIG1ldGFib2xpc20gKEswMDc2MCkiLCJQYW50b3RoZW5hdGUgYW5kIENvQSBiaW9zeW50aGVzaXMgKEswMDc3MCkiLCJCaW90aW4gbWV0YWJvbGlzbSAoSzAwNzgwKSIsIlBvcnBoeXJpbiBhbmQgY2hsb3JvcGh5bGwgbWV0YWJvbGlzbSAoSzAwODYwKSIsIlRlcnBlbm9pZCBiYWNrYm9uZSBiaW9zeW50aGVzaXMgKEswMDkwMCkiLCJTZXNxdWl0ZXJwZW5vaWQgYW5kIHRyaXRlcnBlbm9pZCBiaW9zeW50aGVzaXMgKEswMDkwOSkiLCJDYXJib24gbWV0YWJvbGlzbSAoSzAxMjAwKSIsIkZhdHR5IGFjaWQgbWV0YWJvbGlzbSAoSzAxMjEyKSIsIkRlZ3JhZGF0aW9uIG9mIGFyb21hdGljIGNvbXBvdW5kcyAoSzAxMjIwKSIsIkJlbnpvYXRlIGRlZ3JhZGF0aW9uIChLMDAzNjIpIiwiQ2hsb3JvYWxrYW5lIGFuZCBjaGxvcm9hbGtlbmUgZGVncmFkYXRpb24gKEswMDYyNSkiLCJOaXRyb3RvbHVlbmUgZGVncmFkYXRpb24gKEswMDYzMykiLCJSTkEgZGVncmFkYXRpb24gKEswMzAxOCkiLCJTdWxmdXIgcmVsYXkgc3lzdGVtIChLMDQxMjIpIiwiUmlib3NvbWUgKEswMzAxMCkiLCJDZWxsIGN5Y2xlIC0gQ2F1bG9iYWN0ZXIgKEswNDExMikiLCJGZXJyb3B0b3NpcyAoSzA0MjE2KSIpKQoKdHVzc190SVZfTVRfYmFycGxvdDwtZ2dwbG90KHR1c3NfdElWX2JhcmRhdGEsIGFlcyh4ID0gVGllci5JViwgeT1NZWFuLCBmaWxsPVNhbXBsZSkpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAiYmxhY2siKSArIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBNZWFuIC0gU0QsIHltYXggPSBNZWFuICtTRCksIHdpZHRoID0gMC4yLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSkpICsgY29vcmRfZmxpcCgpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgMzApLCBwb3NpdGlvbj0iYm90dG9tIikgKyB5bGFiICgiUmVsYXRpdmUgQWJ1bmRhbmNlIikgKyB0aGVtZV9jbGFzc2ljKCkgKyB0aGVtZShheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpLCBwbG90Lm1hcmdpbiA9IG1hcmdpbigxMCwgMjAsIDEwLCAxMCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLCBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpLCBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT04KSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygicGFsZWdyZWVuIiwgImdyZWVuMyIsICJkYXJrZ3JlZW4iKSwgZ3VpZGU9Z3VpZGVfbGVnZW5kKHJldmVyc2U9VFJVRSkpCgojIyMgU2F2aW5nIGFzIC5lcHMgZmlsZSB3aXRoIFIgVmlld2VyCiMgUmUtc2l6ZSB0aGUgdmlld2VyIHRvIHRoZSBmb2xsb3dpbmcgZGltZW5zaW9ucyBiZWZvcmUgc2F2aW5nIGFzIC5lcHMgZmlsZQojIEluIENvbnNvbGUsIHR5cGUgInR1c3Nfd3NfZG5hX3RJSUlfcGhlYXRtYXAiCiMgSW4gUGxvdCBWaWV3ZXIsIGNsaWNrICJFeHBvcnQiIC0tPiAiU2F2ZSBhcyBJbWFnZSIKIyBXaWR0aDogNTAwICBIZWlnaHQ6IDcwMAojIENsaWNrICJVcGRhdGUgUHJldmlldyIgLS0+IHNhdmUgYXMgIkVQUyIgZmlsZSB0eXBlIC0tPiByZW5hbWUgYXMgRmlnLjIuQmFyCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9CnR1c3NfdElWX01UX2JhcnBsb3QKYGBgCgpIZWF0bWFwIGZvciBUaWVyIElWIGNhdGVnb3JpZXMgYnkgc2FtcGxpbmcgdGltZXBvaW50cwpgYGB7cn0KIyBDcmVhdGUgY29weSBvZiAidHVzc190SVZfc3VtIiBvYmplY3QgdG8gcHJlcCBmb3IgaGVhdG1hcAp0dXNzX3RJVl9zdWJfaGVhdG1hcDwtdHVzc190SVZfc3VtCgojIEtlZXAgdGhlIGZpcnN0IDcgY29sdW1ucwp0dXNzX3RJVl9zdWJfaGVhdG1hcCA8LSB0dXNzX3RJVl9zdWJfaGVhdG1hcFssYygxLDgsOSwxMCldICAjVGhpcyBjb2RlIHVzZXMgdGhlIG1lYW5zIG9mIHRpbWVwb2ludAoKIyBLZWVwIG9ubHkgdGhvc2UgY2F0ZWdvcmllcyB3aXRoIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIChmcm9tIEFOT1ZBKQoKdHVzc190SVZfc3ViX2hlYXRtYXAgPC0gc3Vic2V0KHR1c3NfdElWX3N1Yl9oZWF0bWFwLCBUaWVyX0lWPT0iMDAwMTAgR2x5Y29seXNpcyAvIEdsdWNvbmVvZ2VuZXNpcyBbUEFUSDprbzAwMDEwXSIgfCBUaWVyX0lWPT0iMDA2NTAgQnV0YW5vYXRlIG1ldGFib2xpc20gW1BBVEg6a28wMDY1MF0iIHwgVGllcl9JVj09IjAwNzYwIE5pY290aW5hdGUgYW5kIG5pY290aW5hbWlkZSBtZXRhYm9saXNtIFtQQVRIOmtvMDA3NjBdIiB8IFRpZXJfSVY9PSIwMTIwMCBDYXJib24gbWV0YWJvbGlzbSBbUEFUSDprbzAxMjAwXSIgfCBUaWVyX0lWPT0iMDEyMTIgRmF0dHkgYWNpZCBtZXRhYm9saXNtIFtQQVRIOmtvMDEyMTJdIiB8IFRpZXJfSVY9PSIwMTIyMCBEZWdyYWRhdGlvbiBvZiBhcm9tYXRpYyBjb21wb3VuZHMgW1BBVEg6a28wMTIyMF0iIHwgVGllcl9JVj09IjAzMDE4IFJOQSBkZWdyYWRhdGlvbiBbUEFUSDprbzAzMDE4XSIgfCBUaWVyX0lWPT0iMDMwMTAgUmlib3NvbWUgW1BBVEg6a28wMzAxMF0iIHwgVGllcl9JVj09IjA0MTEyIENlbGwgY3ljbGUgLSBDYXVsb2JhY3RlciBbUEFUSDprbzA0MTEyXSIsIHNlbGVjdD1UaWVyX0lWOm1lYW50dXNzX1QyNCkKCmNvbG5hbWVzKHR1c3NfdElWX3N1Yl9oZWF0bWFwKTwtYygiVGllcl9JViIsIlR1c3MtTVQtVDAiLCJUdXNzLU1ULVQ0IiwiVHVzcy1NVC1UMjQiKQoKIyBDcmVhdGUgYSB2ZWN0b3Igd2l0aCBjYXRlZ29yZXMgaW4gdGhlIGRlc2lyZWQgb3JkZXIKdHVzc190SVZfc3ViX3ggPC0gYygiMDAwMTAgR2x5Y29seXNpcyAvIEdsdWNvbmVvZ2VuZXNpcyBbUEFUSDprbzAwMDEwXSIsCiIwMDY1MCBCdXRhbm9hdGUgbWV0YWJvbGlzbSBbUEFUSDprbzAwNjUwXSIsCiIwMDc2MCBOaWNvdGluYXRlIGFuZCBuaWNvdGluYW1pZGUgbWV0YWJvbGlzbSBbUEFUSDprbzAwNzYwXSIsCiIwMTIwMCBDYXJib24gbWV0YWJvbGlzbSBbUEFUSDprbzAxMjAwXSIsCiIwMTIxMiBGYXR0eSBhY2lkIG1ldGFib2xpc20gW1BBVEg6a28wMTIxMl0iLAoiMDEyMjAgRGVncmFkYXRpb24gb2YgYXJvbWF0aWMgY29tcG91bmRzIFtQQVRIOmtvMDEyMjBdIiwKIjAzMDEwIFJpYm9zb21lIFtQQVRIOmtvMDMwMTBdIiwKIjAzMDE4IFJOQSBkZWdyYWRhdGlvbiBbUEFUSDprbzAzMDE4XSIsCiIwNDExMiBDZWxsIGN5Y2xlIC0gQ2F1bG9iYWN0ZXIgW1BBVEg6a28wNDExMl0iKQoKIyBSZS1zb3J0IHRoZSBkYXRhIGluIHRoZSBkZXNpcmVkIG9yZGVyCnR1c3NfdElWX3N1Yl9oZWF0bWFwPC10dXNzX3RJVl9zdWJfaGVhdG1hcCAlPiUKICBzbGljZShtYXRjaCh0dXNzX3RJVl9zdWJfeCwgVGllcl9JVikpCgojIENvbnZlcnQgdGhlIGZpcnN0IGNvbHVtbiAoVGllciBjYXRlZ29yaWVzKSBpbnRvIHJvd25hbWVzCnJvd25hbWVzKHR1c3NfdElWX3N1Yl9oZWF0bWFwKSA8LSB0dXNzX3RJVl9zdWJfaGVhdG1hcCRUaWVyX0lWCnR1c3NfdElWX3N1Yl9oZWF0bWFwPC1hcy5kYXRhLmZyYW1lKHR1c3NfdElWX3N1Yl9oZWF0bWFwWy0xXSkKCiMgUmVuYW1lIGNvbHVtbnMgdG8gc2FtcGxlIElEcwpjb2xuYW1lcyh0dXNzX3RJVl9zdWJfaGVhdG1hcCk8LWMoIlR1c3MtTVQtVDAiLCJUdXNzLU1ULVQ0IiwiVHVzcy1NVC1UMjQiKQoKIyBDb252ZXJ0IGRhdGFmcmFtZSBpbnRvIGEgbWF0cml4IGZvciBoZWF0bWFwCnR1c3NfdElWX3N1Yl9oZWF0bWFwPC1hcy5tYXRyaXgodHVzc190SVZfc3ViX2hlYXRtYXApCgojIFNjYWxlIG1hdHJpeCB2YWx1ZXMgdG8gZ2VuZXJhdGUgWi1zY29yZXMKdHVzc190SVZfc3ViX2hlYXRtYXA8LXNjYWxlKHQodHVzc190SVZfc3ViX2hlYXRtYXApKQoKdHVzc190SVZfc3ViX2hlYXRtYXA8LXQodHVzc190SVZfc3ViX2hlYXRtYXApCgojIFNwZWNpZnkgUkNvbG9yQnJld2VyIGN1c3RvbSBjb2xvciBwYWxldHRlCmNvbCA8LSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwoMTAsICJSZFlsQnUiKSkoMjU2KQoKIyMjIFNhdmluZyBhcyAuZXBzIGZpbGUgd2l0aCBSIFZpZXdlcgojIFJlLXNpemUgdGhlIHZpZXdlciB0byB0aGUgZm9sbG93aW5nIGRpbWVuc2lvbnMgYmVmb3JlIHNhdmluZyBhcyAuZXBzIGZpbGUKIyBJbiBDb25zb2xlLCB0eXBlICJ0dXNzX3RJVl9waGVhdG1hcCIKIyBJbiBQbG90IFZpZXdlciwgY2xpY2sgIkV4cG9ydCIgLS0+ICJTYXZlIGFzIEltYWdlIgojIFdpZHRoOiA2MDAgIEhlaWdodDogNjAwCiMgQ2xpY2sgIlVwZGF0ZSBQcmV2aWV3IiAtLT4gc2F2ZSBhcyAiRVBTIiBmaWxlIHR5cGUgLS0+IHJlbmFtZSBhcyBGaWcuMi4yLlR1c3MuTVQuSGVhdG1hcAoKIyBQaGVhdG1hcAp0dXNzX3RJVl9zdWJfcGhlYXRtYXA8LXBoZWF0bWFwKHR1c3NfdElWX3N1Yl9oZWF0bWFwLCB0cmVlaGVpZ2h0X3JvdyA9IDAsIHRyZWVoZWlnaHRfY29sID0gMCxjbHVzdGVyX3Jvd3MgPSBGQUxTRSwgY2x1c3Rlcl9jb2xzID0gRkFMU0UpCmBgYAoKCgpgYGB7ciwgZXZhbD1GQUxTRSwgZWNobz1GQUxTRX0KIyBDcmVhdGUgY29weSBvZiAidHVzc190SVZfc3VtIiBvYmplY3QgdG8gcHJlcCBmb3IgaGVhdG1hcAp0dXNzX3RJVl9oZWF0bWFwPC10dXNzX3RJVl9zdW0KCiMgS2VlcCB0aGUgZmlyc3QgNyBjb2x1bW5zCnR1c3NfdElWX2hlYXRtYXAgPC0gdHVzc190SVZfaGVhdG1hcFssYygxLDgsOSwxMCldICAjVGhpcyBjb2RlIHVzZXMgdGhlIG1lYW5zIG9mIHRpbWVwb2ludAoKIyBLZWVwIG9ubHkgdGhvc2UgY2F0ZWdvcmllcyB3aXRoIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIChmcm9tIEFOT1ZBKQoKdHVzc190SVZfaGVhdG1hcCA8LSBzdWJzZXQodHVzc190SVZfaGVhdG1hcCwgVGllcl9JVj09IjAwMjIwIEFyZ2luaW5lIGJpb3N5bnRoZXNpcyBbUEFUSDprbzAwMjIwXSIgfCBUaWVyX0lWPT0iMDAzMDAgTHlzaW5lIGJpb3N5bnRoZXNpcyBbUEFUSDprbzAwMzAwXSIgfCBUaWVyX0lWPT0iMDAzMzAgQXJnaW5pbmUgYW5kIHByb2xpbmUgbWV0YWJvbGlzbSBbUEFUSDprbzAwMzMwXSIgfCBUaWVyX0lWPT0iMDAzNDAgSGlzdGlkaW5lIG1ldGFib2xpc20gW1BBVEg6a28wMDM0MF0iIHwgVGllcl9JVj09IjAwNDA0IFN0YXVyb3Nwb3JpbmUgYmlvc3ludGhlc2lzIFtQQVRIOmtvMDA0MDRdIiB8IFRpZXJfSVY9PSIwMDAxMCBHbHljb2x5c2lzIC8gR2x1Y29uZW9nZW5lc2lzIFtQQVRIOmtvMDAwMTBdIiB8IFRpZXJfSVY9PSIwMDUwMCBTdGFyY2ggYW5kIHN1Y3Jvc2UgbWV0YWJvbGlzbSBbUEFUSDprbzAwNTAwXSIgfCBUaWVyX0lWPT0iMDA2MjAgUHlydXZhdGUgbWV0YWJvbGlzbSBbUEFUSDprbzAwNjIwXSIgfCBUaWVyX0lWPT0iMDA2NTAgQnV0YW5vYXRlIG1ldGFib2xpc20gW1BBVEg6a28wMDY1MF0iIHwgVGllcl9JVj09IjAwMTQwIFN0ZXJvaWQgaG9ybW9uZSBiaW9zeW50aGVzaXMgW1BBVEg6a28wMDE0MF0iIHwgVGllcl9JVj09IjAwNTYxIEdseWNlcm9saXBpZCBtZXRhYm9saXNtIFtQQVRIOmtvMDA1NjFdIiB8IFRpZXJfSVY9PSIwMDczMCBUaGlhbWluZSBtZXRhYm9saXNtIFtQQVRIOmtvMDA3MzBdIiB8IFRpZXJfSVY9PSIwMDc2MCBOaWNvdGluYXRlIGFuZCBuaWNvdGluYW1pZGUgbWV0YWJvbGlzbSBbUEFUSDprbzAwNzYwXSIgfCBUaWVyX0lWPT0iMDA3NzAgUGFudG90aGVuYXRlIGFuZCBDb0EgYmlvc3ludGhlc2lzIFtQQVRIOmtvMDA3NzBdIiB8IFRpZXJfSVY9PSIwMDc4MCBCaW90aW4gbWV0YWJvbGlzbSBbUEFUSDprbzAwNzgwXSIgfCBUaWVyX0lWPT0iMDA4NjAgUG9ycGh5cmluIGFuZCBjaGxvcm9waHlsbCBtZXRhYm9saXNtIFtQQVRIOmtvMDA4NjBdIiB8IFRpZXJfSVY9PSIwMDkwMCBUZXJwZW5vaWQgYmFja2JvbmUgYmlvc3ludGhlc2lzIFtQQVRIOmtvMDA5MDBdIiB8IFRpZXJfSVY9PSIwMDkwOSBTZXNxdWl0ZXJwZW5vaWQgYW5kIHRyaXRlcnBlbm9pZCBiaW9zeW50aGVzaXMgW1BBVEg6a28wMDkwOV0iIHwgVGllcl9JVj09IjAxMjAwIENhcmJvbiBtZXRhYm9saXNtIFtQQVRIOmtvMDEyMDBdIiB8IFRpZXJfSVY9PSIwMTIxMiBGYXR0eSBhY2lkIG1ldGFib2xpc20gW1BBVEg6a28wMTIxMl0iIHwgVGllcl9JVj09IjAxMjIwIERlZ3JhZGF0aW9uIG9mIGFyb21hdGljIGNvbXBvdW5kcyBbUEFUSDprbzAxMjIwXSIgfCBUaWVyX0lWPT0iMDAzNjIgQmVuem9hdGUgZGVncmFkYXRpb24gW1BBVEg6a28wMDM2Ml0iIHwgVGllcl9JVj09IjAwNjI1IENobG9yb2Fsa2FuZSBhbmQgY2hsb3JvYWxrZW5lIGRlZ3JhZGF0aW9uIFtQQVRIOmtvMDA2MjVdIiB8IFRpZXJfSVY9PSIwMDYzMyBOaXRyb3RvbHVlbmUgZGVncmFkYXRpb24gW1BBVEg6a28wMDYzM10iIHwgVGllcl9JVj09IjAzMDE4IFJOQSBkZWdyYWRhdGlvbiBbUEFUSDprbzAzMDE4XSIgfCBUaWVyX0lWPT0iMDQxMjIgU3VsZnVyIHJlbGF5IHN5c3RlbSBbUEFUSDprbzA0MTIyXSIgfCBUaWVyX0lWPT0iMDMwMTAgUmlib3NvbWUgW1BBVEg6a28wMzAxMF0iIHwgVGllcl9JVj09IjA0MTEyIENlbGwgY3ljbGUgLSBDYXVsb2JhY3RlciBbUEFUSDprbzA0MTEyXSIgfCBUaWVyX0lWPT0iMDQyMTYgRmVycm9wdG9zaXMgW1BBVEg6a28wNDIxNl0iLCBzZWxlY3Q9VGllcl9JVjptZWFudHVzc19UMjQpCgpjb2xuYW1lcyh0dXNzX3RJVl9oZWF0bWFwKTwtYygiVGllcl9JViIsIlR1c3MtTVQtVDAiLCJUdXNzLU1ULVQ0IiwiVHVzcy1NVC1UMjQiKQoKIyBDcmVhdGUgYSB2ZWN0b3Igd2l0aCBjYXRlZ29yZXMgaW4gdGhlIGRlc2lyZWQgb3JkZXIKdHVzc190SVZfeCA8LSBjKCIwMDIyMCBBcmdpbmluZSBiaW9zeW50aGVzaXMgW1BBVEg6a28wMDIyMF0iLAoiMDAzMDAgTHlzaW5lIGJpb3N5bnRoZXNpcyBbUEFUSDprbzAwMzAwXSIsCiIwMDMzMCBBcmdpbmluZSBhbmQgcHJvbGluZSBtZXRhYm9saXNtIFtQQVRIOmtvMDAzMzBdIiwKIjAwMzQwIEhpc3RpZGluZSBtZXRhYm9saXNtIFtQQVRIOmtvMDAzNDBdIiwKIjAwNDA0IFN0YXVyb3Nwb3JpbmUgYmlvc3ludGhlc2lzIFtQQVRIOmtvMDA0MDRdIiwKIjAwMDEwIEdseWNvbHlzaXMgLyBHbHVjb25lb2dlbmVzaXMgW1BBVEg6a28wMDAxMF0iLAoiMDA1MDAgU3RhcmNoIGFuZCBzdWNyb3NlIG1ldGFib2xpc20gW1BBVEg6a28wMDUwMF0iLAoiMDA2MjAgUHlydXZhdGUgbWV0YWJvbGlzbSBbUEFUSDprbzAwNjIwXSIsCiIwMDY1MCBCdXRhbm9hdGUgbWV0YWJvbGlzbSBbUEFUSDprbzAwNjUwXSIsCiIwMDE0MCBTdGVyb2lkIGhvcm1vbmUgYmlvc3ludGhlc2lzIFtQQVRIOmtvMDAxNDBdIiwKIjAwNTYxIEdseWNlcm9saXBpZCBtZXRhYm9saXNtIFtQQVRIOmtvMDA1NjFdIiwKIjAwNzMwIFRoaWFtaW5lIG1ldGFib2xpc20gW1BBVEg6a28wMDczMF0iLAoiMDA3NjAgTmljb3RpbmF0ZSBhbmQgbmljb3RpbmFtaWRlIG1ldGFib2xpc20gW1BBVEg6a28wMDc2MF0iLAoiMDA3NzAgUGFudG90aGVuYXRlIGFuZCBDb0EgYmlvc3ludGhlc2lzIFtQQVRIOmtvMDA3NzBdIiwKIjAwNzgwIEJpb3RpbiBtZXRhYm9saXNtIFtQQVRIOmtvMDA3ODBdIiwKIjAwODYwIFBvcnBoeXJpbiBhbmQgY2hsb3JvcGh5bGwgbWV0YWJvbGlzbSBbUEFUSDprbzAwODYwXSIsCiIwMDkwMCBUZXJwZW5vaWQgYmFja2JvbmUgYmlvc3ludGhlc2lzIFtQQVRIOmtvMDA5MDBdIiwKIjAwOTA5IFNlc3F1aXRlcnBlbm9pZCBhbmQgdHJpdGVycGVub2lkIGJpb3N5bnRoZXNpcyBbUEFUSDprbzAwOTA5XSIsCiIwMTIwMCBDYXJib24gbWV0YWJvbGlzbSBbUEFUSDprbzAxMjAwXSIsCiIwMTIxMiBGYXR0eSBhY2lkIG1ldGFib2xpc20gW1BBVEg6a28wMTIxMl0iLAoiMDEyMjAgRGVncmFkYXRpb24gb2YgYXJvbWF0aWMgY29tcG91bmRzIFtQQVRIOmtvMDEyMjBdIiwKIjAwMzYyIEJlbnpvYXRlIGRlZ3JhZGF0aW9uIFtQQVRIOmtvMDAzNjJdIiwKIjAwNjI1IENobG9yb2Fsa2FuZSBhbmQgY2hsb3JvYWxrZW5lIGRlZ3JhZGF0aW9uIFtQQVRIOmtvMDA2MjVdIiwKIjAwNjMzIE5pdHJvdG9sdWVuZSBkZWdyYWRhdGlvbiBbUEFUSDprbzAwNjMzXSIsCiIwMzAxOCBSTkEgZGVncmFkYXRpb24gW1BBVEg6a28wMzAxOF0iLAoiMDQxMjIgU3VsZnVyIHJlbGF5IHN5c3RlbSBbUEFUSDprbzA0MTIyXSIsCiIwMzAxMCBSaWJvc29tZSBbUEFUSDprbzAzMDEwXSIsCiIwNDExMiBDZWxsIGN5Y2xlIC0gQ2F1bG9iYWN0ZXIgW1BBVEg6a28wNDExMl0iLAoiMDQyMTYgRmVycm9wdG9zaXMgW1BBVEg6a28wNDIxNl0iKQoKIyBSZS1zb3J0IHRoZSBkYXRhIGluIHRoZSBkZXNpcmVkIG9yZGVyCnR1c3NfdElWX2hlYXRtYXA8LXR1c3NfdElWX2hlYXRtYXAgJT4lCiAgc2xpY2UobWF0Y2godHVzc190SVZfeCwgVGllcl9JVikpCgojIENvbnZlcnQgdGhlIGZpcnN0IGNvbHVtbiAoVGllciBjYXRlZ29yaWVzKSBpbnRvIHJvd25hbWVzCnJvd25hbWVzKHR1c3NfdElWX2hlYXRtYXApIDwtIHR1c3NfdElWX2hlYXRtYXAkVGllcl9JVgp0dXNzX3RJVl9oZWF0bWFwPC1hcy5kYXRhLmZyYW1lKHR1c3NfdElWX2hlYXRtYXBbLTFdKQoKIyBSZW5hbWUgY29sdW1ucyB0byBzYW1wbGUgSURzCmNvbG5hbWVzKHR1c3NfdElWX2hlYXRtYXApPC1jKCJUdXNzLU1ULVQwIiwiVHVzcy1NVC1UNCIsIlR1c3MtTVQtVDI0IikKCiMgQ29udmVydCBkYXRhZnJhbWUgaW50byBhIG1hdHJpeCBmb3IgaGVhdG1hcAp0dXNzX3RJVl9oZWF0bWFwPC1hcy5tYXRyaXgodHVzc190SVZfaGVhdG1hcCkKCiMgU2NhbGUgbWF0cml4IHZhbHVlcyB0byBnZW5lcmF0ZSBaLXNjb3Jlcwp0dXNzX3RJVl9oZWF0bWFwPC1zY2FsZSh0KHR1c3NfdElWX2hlYXRtYXApKQoKdHVzc190SVZfaGVhdG1hcDwtdCh0dXNzX3RJVl9oZWF0bWFwKQoKIyBTcGVjaWZ5IFJDb2xvckJyZXdlciBjdXN0b20gY29sb3IgcGFsZXR0ZQpjb2wgPC0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKDEwLCAiUmRZbEJ1IikpKDI1NikKCiMjIyBTYXZpbmcgYXMgLmVwcyBmaWxlIHdpdGggUiBWaWV3ZXIKIyBSZS1zaXplIHRoZSB2aWV3ZXIgdG8gdGhlIGZvbGxvd2luZyBkaW1lbnNpb25zIGJlZm9yZSBzYXZpbmcgYXMgLmVwcyBmaWxlCiMgSW4gQ29uc29sZSwgdHlwZSAidHVzc190SVZfcGhlYXRtYXAiCiMgSW4gUGxvdCBWaWV3ZXIsIGNsaWNrICJFeHBvcnQiIC0tPiAiU2F2ZSBhcyBJbWFnZSIKIyBXaWR0aDogNjAwICBIZWlnaHQ6IDY1MAojIENsaWNrICJVcGRhdGUgUHJldmlldyIgLS0+IHNhdmUgYXMgIkVQUyIgZmlsZSB0eXBlIC0tPiByZW5hbWUgYXMgRmlnLjIuMi5UdXNzLk1ULkhlYXRtYXAKCiMgUGhlYXRtYXAKdHVzc190SVZfcGhlYXRtYXA8LXBoZWF0bWFwKHR1c3NfdElWX2hlYXRtYXAsIHRyZWVoZWlnaHRfcm93ID0gMCwgdHJlZWhlaWdodF9jb2wgPSAwLGNsdXN0ZXJfcm93cyA9IEZBTFNFLCBjbHVzdGVyX2NvbHMgPSBGQUxTRSkKYGBgCgojIyMjIDcuMy4yLiBXZXQgU2VkZ2UgVHVuZHJhCgpMb29rIGF0IGRpZmZlcmVuY2VzIGluIGdlbmUgZXhwcmVzc2lvbiBwYXR0ZXJucyBmb3IgbXVsdGlwbGUgVGllciBsZXZlbHMgd2l0aGluIHRoZSBXZXQgU2VkZ2UgdHVuZHJhIGJldHdlZW4gc2FtcGxpbmcgdGltZSBwb2ludHMuCgojIyMjIyA3LjMuMi4xLiBUaWVyIElJIEV4cHJlc3Npb24KCkNhbGN1bGF0ZSBUUE0tbm9ybWFsaXplZCBnZW5lIGNvdW50IHN1bXMgZm9yIGVhY2ggV1Mgc2FtcGxlIGluIGVhY2ggVGllciBJSSBjYXRlZ29yeS4KYGBge3J9CiMgQ2FsY3VsYXRlIFRQTS1ub3JtYWxpemVkIGdlbmUgY291bnQgc3VtcyBmb3IgZWFjaCBXUyBzYW1wbGUgaW4gZWFjaCBUaWVyIElJIGNhdGVnb3J5CndzX3RJSV9zdW08LXRwbV9hbGxfZXhwX2FubiAlPiUgZ3JvdXBfYnkoVGllcl9JSSkgJT4lIHN1bW1hcmlzZV9hdCh2YXJzKCJTMTA4Mzc5IiwiUzEwODM4MSIsIlMxMDgzODUiLCJTMTA4Mzg2IiwiUzEwODM4OCIsIlMxMDgzOTAiKSwgc3VtKQoKd3NfdElJX3N1bTwtd3NfdElJX3N1bSAlPiUgbXV0YXRlX2F0KHZhcnMoUzEwODM3OSxTMTA4MzgxLFMxMDgzODUsUzEwODM4NixTMTA4Mzg4LFMxMDgzOTApLCBmdW5zKHJvdW5kKC4sIDApKSkKCndzX3RJSV9zdW08LWFzLmRhdGEuZnJhbWUod3NfdElJX3N1bSkKCndzX3RJSV9zdW08LXdzX3RJSV9zdW1bb3JkZXIoLXdzX3RJSV9zdW0kUzEwODM3OSksXQpgYGAKCmBgYHtyIGVjaG89RkFMU0V9CmthYmxlKHdzX3RJSV9zdW0sIGNhcHRpb24gPSAiV2V0IFNlZGdlIFRpZXIgSUkgS0VHRyBjYXRlZ29yeSBzdW1tYXJ5IGJ5IHNhbXBsZS4iLCBmb3JtYXQuYXJncyA9IGxpc3QoYmlnLm1hcms9IiwiKSkgJT4lIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiKSkKYGBgCgpIZWF0bWFwIGZvciBUaWVyIElJIGNhdGVnb3JpZXMgYnkgc2FtcGxpbmcgdGltZXBvaW50cwpgYGB7cn0KIyBDcmVhdGUgY29weSBvZiAid3NfdElJX3N1bSIgb2JqZWN0IHRvIHByZXAgZm9yIGhlYXRtYXAKd3NfdElJX2hlYXRtYXA8LXdzX3RJSV9zdW0KCiMgQ29udmVydCB0aGUgZmlyc3QgY29sdW1uIChUaWVyIGNhdGVnb3JpZXMpIGludG8gcm93bmFtZXMKcm93bmFtZXMod3NfdElJX2hlYXRtYXApIDwtIHdzX3RJSV9oZWF0bWFwJFRpZXJfSUkKd3NfdElJX2hlYXRtYXA8LWFzLmRhdGEuZnJhbWUod3NfdElJX2hlYXRtYXBbLTFdKQoKIyBSZW5hbWUgY29sdW1ucyB0byBzYW1wbGUgSURzCmNvbG5hbWVzKHdzX3RJSV9oZWF0bWFwKTwtYygiV1MxLVQwIiwiV1MzLVQwIiwiV1MxLVQ0IiwiV1MyLVQ0IiwiV1MxLVQyNCIsIldTMy1UMjQiKQoKIyBSZW1vdmUgcm93cyBmb3IgIk9yZ2FuaXNtYWwgU3lzdGVtcyIgYW5kICJIdW1hbiBEaXNlYXNlcyIKI3dzX3RJSV9oZWF0bWFwIDwtIHdzX3RJSV9oZWF0bWFwWy1jKDUsNiksXQoKIyBDb252ZXJ0IGRhdGFmcmFtZSBpbnRvIGEgbWF0cml4IGZvciBoZWF0bWFwCndzX3RJSV9oZWF0bWFwPC1hcy5tYXRyaXgod3NfdElJX2hlYXRtYXApCgojIFNjYWxlIG1hdHJpeCB2YWx1ZXMgdG8gZ2VuZXJhdGUgWi1zY29yZXMKd3NfdElJX2hlYXRtYXA8LXNjYWxlKHQod3NfdElJX2hlYXRtYXApKQoKd3NfdElJX2hlYXRtYXA8LXQod3NfdElJX2hlYXRtYXApCgojIFNwZWNpZnkgUkNvbG9yQnJld2VyIGN1c3RvbSBjb2xvciBwYWxldHRlCmNvbCA8LSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwoMTAsICJSZFlsQnUiKSkoMjU2KQoKIyBQaGVhdG1hcApwaGVhdG1hcCh3c190SUlfaGVhdG1hcCwgdHJlZWhlaWdodF9yb3cgPSAwLCB0cmVlaGVpZ2h0X2NvbCA9IDAsY2x1c3Rlcl9yb3dzID0gRkFMU0UsIGNsdXN0ZXJfY29scyA9IEZBTFNFKQpgYGAKCkNhbGN1bGF0ZSBtZWFuIHZhbHVlcyBmcm9tIHRoZSByZXBsaWNhdGUgc3Vtcy4KYGBge3J9CiMgQ2FsY3VsYXRlIG1lYW4gdmFsdWVzIGZyb20gdGhlIHJlcGxpY2F0ZSBzdW1zCndzX3RJSV9zdW0kbWVhbldTX1QwPC1hcHBseSh3c190SUlfc3VtWywyOjNdLCAxLCBtZWFuKQp3c190SUlfc3VtJG1lYW5XU19UNDwtYXBwbHkod3NfdElJX3N1bVssNDo1XSwgMSwgbWVhbikKd3NfdElJX3N1bSRtZWFuV1NfVDI0PC1hcHBseSh3c190SUlfc3VtWyw2OjddLCAxLCBtZWFuKQp3c190SUlfc3VtPC13c190SUlfc3VtICU+JSBtdXRhdGVfYXQodmFycyhtZWFuV1NfVDAsbWVhbldTX1Q0LG1lYW5XU19UMjQpLCBmdW5zKHJvdW5kKC4sIDApKSkKCiMgQ2FsY3VsYXRlIHNkIHZhbHVlcyBmcm9tIHRoZSByZXBsaWNhdGUgc3Vtcwp3c190SUlfc3VtJHNkV1NfVDA8LWFwcGx5KHdzX3RJSV9zdW1bLDI6M10sIDEsIHNkKQp3c190SUlfc3VtJHNkV1NfVDQ8LWFwcGx5KHdzX3RJSV9zdW1bLDQ6NV0sIDEsIHNkKQp3c190SUlfc3VtJHNkV1NfVDI0PC1hcHBseSh3c190SUlfc3VtWyw2OjddLCAxLCBzZCkKd3NfdElJX3N1bTwtd3NfdElJX3N1bSAlPiUgbXV0YXRlX2F0KHZhcnMoc2RXU19UMCxzZFdTX1Q0LHNkV1NfVDI0KSwgZnVucyhyb3VuZCguLCAwKSkpCgojIFN1YnNldCBNZWFuIHZhbHVlcwp3c190SUlfbWVhbjwtc3Vic2V0KHdzX3RJSV9zdW0sIHNlbGVjdD1jKFRpZXJfSUksbWVhbldTX1QwLG1lYW5XU19UNCxtZWFuV1NfVDI0KSkKbmFtZXMod3NfdElJX21lYW4pPC1jKCJUaWVyIElJIiwgIldTIC0gVDAiLCAiV1MgLSBUNCIsICJXUyAtIFQyNCIpCgojIFN1YnNldCBTRCB2YWx1ZXMKd3NfdElJX3NkPC1zdWJzZXQod3NfdElJX3N1bSwgc2VsZWN0PWMoVGllcl9JSSxzZFdTX1QwLHNkV1NfVDQsc2RXU19UMjQpKQpuYW1lcyh3c190SUlfc2QpPC1jKCJUaWVyIElJIiwgIldTIC0gVDAiLCAiV1MgLSBUNCIsICJXUyAtIFQyNCIpCgojIFJlbWVtYmVyICJUaWVyIElJIiBhcyBub24tbnVtZXJpYyB2YWx1ZXMKd3NfdElJX21lYW5fVGllcklJPC13c190SUlfbWVhbiRgVGllciBJSWAKd3NfdElJX3NkX1RpZXJJSTwtd3NfdElJX3NkJGBUaWVyIElJYAoKIyBUcmFuc3Bvc2UgYWxsIGJ1dCBmaXJzdCBjb2x1bW4gKFRpZXIgSUkpCndzX3RJSV9tZWFuPC1hcy5kYXRhLmZyYW1lKHQod3NfdElJX21lYW5bLC0xXSkpCmNvbG5hbWVzKHdzX3RJSV9tZWFuKTwtd3NfdElJX21lYW5fVGllcklJCndzX3RJSV9zZDwtYXMuZGF0YS5mcmFtZSh0KHdzX3RJSV9zZFssLTFdKSkKY29sbmFtZXMod3NfdElJX3NkKTwtd3NfdElJX3NkX1RpZXJJSQoKIyBDb21iaW5lIG1lYW4gYW5kIHNkIGludG8gc2luZ2xlIGNvbHVtbiB3aXRoIMKxIGRpdmlkZXIKd3NfdElJX3RhYmxlPC1hcy5kYXRhLmZyYW1lKGRvLmNhbGwoY2JpbmQsIGxhcHBseSgxOm5jb2wod3NfdElJX21lYW4pLCBmdW5jdGlvbihpKSBwYXN0ZTAod3NfdElJX21lYW5bICwgaV0sICIgwrEgIiwgd3NfdElJX3NkWyAsIGldKSkpKQoKIyBUcmFuc3Bvc2UgdGhlIHRhYmxlIGJhY2sKd3NfdElJX3RhYmxlPC10KHdzX3RJSV90YWJsZSkKCiMgUmVuYW1lIGNvbHVtbnMgdG8gU2l0ZXMKY29sbmFtZXMod3NfdElJX3RhYmxlKTwtYygiV2V0IFNlZGdlIChUMCkiLCAiV2V0IFNlZGdlIChUNCkiLCAiV2V0IFNlZGdlIChUMjQpIikKCnJvd25hbWVzKHdzX3RJSV90YWJsZSk8LXdzX3RJSV9tZWFuX1RpZXJJSQoKa2FibGUod3NfdElJX3RhYmxlLCBjYXB0aW9uID0gIldldCBTZWRnZSBUaWVyIElJIEtFR0cgY2F0ZWdvcnkgYXZlcmFnZXMgKMKxIHN0YW5kYXJkIGRldmlhdGlvbikgYnkgc2FtcGxlLiIsIGZvcm1hdC5hcmdzID0gbGlzdChiaWcubWFyaz0iLCIpLCBhbGlnbiA9ICJsIikgJT4lIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiKSkKYGBgCgpSdW4gc3RhdGlzdGljYWwgdGVzdHMgdG8gZGV0ZXJtaW5lIGlmIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGV4aXN0IGJldHdlZW4gc2FtcGxpbmcgdGltZXBvaW50cyBmb3IgZWFjaCBUaWVyIEtFR0cgY2F0ZWdvcnkuIENsaWNrIG9uIHRoZSAqKlNob3cvSGlkZSoqIGJ1dHRvbiB0byBzZWUgdGhlIHN0YXRpc3RpY3MuCgo8YnV0dG9uIGNsYXNzPSJidG4gYnRuLXByaW1hcnkiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9IiNCbG9ja05hbWU5Ij4gU2hvdy9IaWRlIDwvYnV0dG9uPiAgCjxkaXYgaWQ9IkJsb2NrTmFtZTkiIGNsYXNzPSJjb2xsYXBzZSI+CmBgYHtyfQojIFN1YnNldCB0aGUgInN1bSIgdmFsdWVzIGZvciBlYWNoIHNhbXBsZQp3c190SUlfc3RhdHM8LXN1YnNldCh3c190SUlfc3VtLCBzZWxlY3Q9YyhUaWVyX0lJLFMxMDgzNzksUzEwODM4MSxTMTA4Mzg1LFMxMDgzODYsUzEwODM4OCxTMTA4MzkwKSkKCnJvd25hbWVzKHdzX3RJSV9zdGF0cykgPC0gd3NfdElJX3N0YXRzJFRpZXJfSUkKd3NfdElJX3N0YXRzPC1hcy5kYXRhLmZyYW1lKHQod3NfdElJX3N0YXRzWy0xXSkpCgojIEFkZCB0aGUgdGltZXBvaW50IGNvbHVtbiB0byB0aGUgc3VtIHRhYmxlCndzX3RJSV9zdGF0czwtZGF0YS5mcmFtZShUaW1lcG9pbnQsd3NfdElJX3N0YXRzKQoKIyBTdWJzZXQgcmVzcG9uc2UgdmFyaWFibGVzIGZvciBNQU5PVkEKd3NfdElJX3N0YXRzJHJlc3BvbnNlIDwtIGFzLm1hdHJpeCh3c190SUlfc3RhdHNbLCAyOjVdKQoKIyBNQU5PVkEgdGVzdAp3c190SUlfbWFub3ZhIDwtIG1hbm92YShyZXNwb25zZSB+IFRpbWVwb2ludCwgZGF0YT13c190SUlfc3RhdHMpCnN1bW1hcnkuYW92KHdzX3RJSV9tYW5vdmEpCmBgYAo8L2Rpdj4KClBsb3QgYSBiYXJjaGFydCBmb3IgVGllciBJSSBjYXRlZ29yaWVzIGJ5IHNhbXBsaW5nIHRpbWVwb2ludHMuCmBgYHtyIGVjaG89RkFMU0V9CndzX3RJSV9iYXJkYXRhPC1yZWFkLmNzdigiUGxvdC5EYXRhL3dzX3RJSV9iYXJwbG90LmNzdiIpCmBgYAoKYGBge3J9CiMgUGxhY2UgVGllciBJSSBjYXRlZ29yaWVzIGluIHRoZSBwcmVmZXJyZWQgb3JkZXIgZm9yIHBsb3R0aW5nCndzX3RJSV9iYXJkYXRhJFRpZXIuSUkgPC0gZmFjdG9yKHdzX3RJSV9iYXJkYXRhJFRpZXIuSUksbGV2ZWxzID0gYygiTWV0YWJvbGlzbSIsICJHZW5ldGljIEluZm9ybWF0aW9uIFByb2Nlc3NpbmciLCAiRW52aXJvbm1lbnRhbCBJbmZvcm1hdGlvbiBQcm9jZXNzaW5nIiwgIkNlbGx1bGFyIFByb2Nlc3NlcyIpKQoKd3NfdElJX2JhcmRhdGEkU2FtcGxlIDwtIGZhY3Rvcih3c190SUlfYmFyZGF0YSRTYW1wbGUsbGV2ZWxzPWMoIldTLVQwIiwiV1MtVDQiLCJXUy1UMjQiKSkKCndzX3RJSV9iYXJwbG90PC1nZ3Bsb3Qod3NfdElJX2JhcmRhdGEsIGFlcyh4ID0gVGllci5JSSwgeSA9IE1lYW4sIGZpbGwgPSBTYW1wbGUpKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yPSJibGFjayIpICsgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IE1lYW4gLSBTRCwgeW1heCA9IE1lYW4gKyBTRCksIHdpZHRoID0gMC4yLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSkpICsgeWxhYihleHByZXNzaW9uKGF0b3AoIktFR0cgVGllciBJSSBDYXRlZ29yaWVzIiwgcGFzdGUoIlRyYW5zY3JpcHQgQ291bnRzIChUUE0pIikpKSkgKyB0aGVtZV9jbGFzc2ljKCkgKyB0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApLCBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTEyKSwgYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9OCksIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSkgKyBzY2FsZV9zaXplKGd1aWRlPUZBTFNFKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJsaWdodHNreWJsdWUxIiwgImRvZGdlcmJsdWUxIiwgIm1pZG5pZ2h0Ymx1ZSIpKSArIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oVGllci5JSSkgc3RyX3dyYXAoVGllci5JSSwgd2lkdGggPSAxMCkpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgODAwMDAwKSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0xLjAsIHk9NzAwMDAwLCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0yLjAsIHk9NDAwMDAwLCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0zLjAsIHk9MjUwMDAwLCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD00LjAsIHk9MTUwMDAwLCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkKCgpgYGAKCmBgYHtyfQp3c190SUlfYmFycGxvdApgYGAKCmBgYHtyIGVjaG89RkFMU0V9CndzX21nX210X3RJSV9iYXJkYXRhPC1yZWFkLmNzdigiUGxvdC5EYXRhL3dzX21nX210X3RJSV9iYXJwbG90LmNzdiIpCmBgYAoKYGBge3J9CiMgUGxhY2UgVGllciBJSSBjYXRlZ29yaWVzIGluIHRoZSBwcmVmZXJyZWQgb3JkZXIgZm9yIHBsb3R0aW5nCndzX21nX210X3RJSV9iYXJkYXRhJFRpZXIuSUkgPC0gZmFjdG9yKHdzX21nX210X3RJSV9iYXJkYXRhJFRpZXIuSUksbGV2ZWxzID0gYygiTWV0YWJvbGlzbSIsICJHZW5ldGljIEluZm9ybWF0aW9uIFByb2Nlc3NpbmciLCAiRW52aXJvbm1lbnRhbCBJbmZvcm1hdGlvbiBQcm9jZXNzaW5nIiwgIkNlbGx1bGFyIFByb2Nlc3NlcyIpKQoKIyBQbGFjZSBTYW1wbGVzIGluIHRoZSBwcmVmZXJyZWQgb3JkZXIgZm9yIHBsb3R0aW5nCndzX21nX210X3RJSV9iYXJkYXRhJFNhbXBsZSA8LSBmYWN0b3Iod3NfbWdfbXRfdElJX2JhcmRhdGEkU2FtcGxlLGxldmVscz1jKCJXUy1NRyIsIldTLU1ULVQwIiwiV1MtTVQtVDQiLCJXUy1NVC1UMjQiKSkKCndzX21nX210X3RJSV9iYXJwbG90PC1nZ3Bsb3Qod3NfbWdfbXRfdElJX2JhcmRhdGEsIGFlcyh4ID0gVGllci5JSSwgeSA9IE1lYW4sIGZpbGwgPSBTYW1wbGUpKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yPSJibGFjayIpICsgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IE1lYW4gLSBTRCwgeW1heCA9IE1lYW4gKyBTRCksIHdpZHRoID0gMC4yLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSkpICsgeWxhYihleHByZXNzaW9uKGF0b3AoIktFR0cgVGllciBJSSBDYXRlZ29yaWVzIiwgcGFzdGUoIkdlbmUgQ291bnRzIikpKSkgKyB0aGVtZV9jbGFzc2ljKCkgKyB0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApLCBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTEyKSwgYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9OCksIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSkgKyBzY2FsZV9zaXplKGd1aWRlPUZBTFNFKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJibGFjayIsICJsaWdodHNreWJsdWUxIiwgImRvZGdlcmJsdWUxIiwgIm1pZG5pZ2h0Ymx1ZSIpKSArIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oVGllci5JSSkgc3RyX3dyYXAoVGllci5JSSwgd2lkdGggPSAxMCkpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgODAwMDAwKSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0xLjEyLCB5PTcwMDAwMCwgbGFiZWw9Iml0YWxpYyhOLlMuKSIsIHBhcnNlPVRSVUUpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9Mi4xMiwgeT00MDAwMDAsIGxhYmVsPSJpdGFsaWMoTi5TLikiLCBwYXJzZT1UUlVFKSArIGFubm90YXRlKGdlb209InRleHQiLCB4PTMuMTIsIHk9MjUwMDAwLCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD00LjEyLCB5PTE1MDAwMCwgbGFiZWw9Iml0YWxpYyhOLlMuKSIsIHBhcnNlPVRSVUUpCmBgYAoKYGBge3J9CndzX21nX210X3RJSV9iYXJwbG90CmBgYAoKYGBge3IgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0KIyBTYXZlIHRoZSBSaWJvc29tZSBUYXhvbm9teSBwbG90IGFzIGFuIGluZGl2aWR1YWwgZmlndXJlCnNldEVQUygpCnBvc3RzY3JpcHQoIkZpZy4yLk1ULlRheGEuS0VHRy5lcHMiLCB3aWR0aD0xMC4wLCBoZWlnaHQgPSAxMC4wKQpkaXYucGxvdDwtcGxvdF9ncmlkKHRheGEudHVzcy5tZWFuLnJpYm8ucGxvdCwgdGF4YS53cy5tZWFuLnJpYm8ucGxvdCxsYWJlbHM9YygnQScsJ0InKSxyZWxfd2lkdGhzID0gYyg0LjUsNikpCmRpdi5wbG90MjwtcGxvdF9ncmlkKHR1c3NfbWdfbXRfdElJX2JhcnBsb3QsIHdzX21nX210X3RJSV9iYXJwbG90LCBsYWJlbHM9YygnQycsJ0QnKSwgcmVsX3dpZHRocyA9IGMoNSw1KSkKcGxvdF9ncmlkKGRpdi5wbG90LGRpdi5wbG90MixuY29sID0gMSkKZGV2Lm9mZigpCmBgYAoKYGBge3IgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0KIyBQbG90IHRoZSBUVVNTIGFuZCBXUyBNRy1NVC1UaWVyLUlJLUJhcnBsb3RzCnNldEVQUygpCnBvc3RzY3JpcHQoIkZpZy4yLjEuMS5UdXNzLlRheGEuZXBzIiwgd2lkdGg9NS4wLCBoZWlnaHQgPSA1LjApCmdnYXJyYW5nZSh0YXhhLnR1c3MubWVhbi5yaWJvLnBsb3QsIG5jb2wgPSAxLCBucm93ID0gMSkKZGV2Lm9mZigpCmBgYAoKYGBge3IgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0KIyBQbG90IHRoZSBUVVNTIGFuZCBXUyBNRy1NVC1UaWVyLUlJLUJhcnBsb3RzCnNldEVQUygpCnBvc3RzY3JpcHQoIkZpZy4yLjEuMi5XUy5UYXhhLmVwcyIsIHdpZHRoPTcuMCwgaGVpZ2h0ID0gNS4wKQpnZ2FycmFuZ2UodGF4YS53cy5tZWFuLnJpYm8ucGxvdCwgbmNvbCA9IDEsIG5yb3cgPSAxKQpkZXYub2ZmKCkKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQojIFBsb3QgdGhlIFRVU1MgYW5kIFdTIE1HLU1ULVRpZXItSUktQmFycGxvdHMKc2V0RVBTKCkKcG9zdHNjcmlwdCgiRmlnLjIuMi5NVC5LRUdHLmVwcyIsIHdpZHRoPTEwLjAsIGhlaWdodCA9IDUuMCkKZ2dhcnJhbmdlKHR1c3NfbWdfbXRfdElJX2JhcnBsb3QsIHdzX21nX210X3RJSV9iYXJwbG90LCBuY29sID0gMiwgbnJvdyA9IDEsIGxhYmVscz1jKCdBJywnQicpLCBhbGlnbj0idiIpCmRldi5vZmYoKQpgYGAKCiMjIyMjIDcuMy4yLjIuIFRpZXIgSUlJIEV4cHJlc3Npb24KCkNhbGN1bGF0ZSBUUE0tbm9ybWFsaXplZCBnZW5lIGNvdW50IHN1bXMgZm9yIGVhY2ggV1Mgc2FtcGxlIGluIGVhY2ggVGllciBJSUkgY2F0ZWdvcnkuCmBgYHtyfQojIENhbGN1bGF0ZSBUUE0tbm9ybWFsaXplZCBnZW5lIGNvdW50IHN1bXMgZm9yIGVhY2ggV1Mgc2FtcGxlIGluIGVhY2ggVGllciBJSUkgY2F0ZWdvcnkKd3NfdElJSV9zdW08LXRwbV9hbGxfZXhwX2FubiAlPiUgZ3JvdXBfYnkoVGllcl9JSUkpICU+JSBzdW1tYXJpc2VfYXQodmFycygiUzEwODM3OSIsIlMxMDgzODEiLCJTMTA4Mzg1IiwiUzEwODM4NiIsIlMxMDgzODgiLCJTMTA4MzkwIiksIHN1bSkKd3NfdElJSV9zdW08LXdzX3RJSUlfc3VtICU+JSBtdXRhdGVfYXQodmFycyhTMTA4Mzc5LFMxMDgzODEsUzEwODM4NSxTMTA4Mzg2LFMxMDgzODgsUzEwODM5MCksIGZ1bnMocm91bmQoLiwgMCkpKQp3c190SUlJX3N1bTwtYXMuZGF0YS5mcmFtZSh3c190SUlJX3N1bSkKd3NfdElJSV9zdW08LXdzX3RJSUlfc3VtW29yZGVyKC13c190SUlJX3N1bSRTMTA4Mzc5KSxdCmBgYAoKYGBge3J9CiMgQ2FsY3VsYXRlIG1lYW4gdmFsdWVzIGZyb20gdGhlIHJlcGxpY2F0ZSBzdW1zCndzX3RJSUlfc3VtJG1lYW5XU19UMDwtYXBwbHkod3NfdElJSV9zdW1bLDI6M10sIDEsIG1lYW4pCndzX3RJSUlfc3VtJG1lYW5XU19UNDwtYXBwbHkod3NfdElJSV9zdW1bLDQ6NV0sIDEsIG1lYW4pCndzX3RJSUlfc3VtJG1lYW5XU19UMjQ8LWFwcGx5KHdzX3RJSUlfc3VtWyw2OjddLCAxLCBtZWFuKQp3c190SUlJX3N1bTwtd3NfdElJSV9zdW0gJT4lIG11dGF0ZV9hdCh2YXJzKG1lYW5XU19UMCxtZWFuV1NfVDQsbWVhbldTX1QyNCksIGZ1bnMocm91bmQoLiwgMCkpKQoKIyBDYWxjdWxhdGUgc2QgdmFsdWVzIGZyb20gdGhlIHJlcGxpY2F0ZSBzdW1zCndzX3RJSUlfc3VtJHNkV1NfVDA8LWFwcGx5KHdzX3RJSUlfc3VtWywyOjNdLCAxLCBzZCkKd3NfdElJSV9zdW0kc2RXU19UNDwtYXBwbHkod3NfdElJSV9zdW1bLDQ6NV0sIDEsIHNkKQp3c190SUlJX3N1bSRzZFdTX1QyNDwtYXBwbHkod3NfdElJSV9zdW1bLDY6N10sIDEsIHNkKQp3c190SUlJX3N1bTwtd3NfdElJSV9zdW0gJT4lIG11dGF0ZV9hdCh2YXJzKHNkV1NfVDAsc2RXU19UNCxzZFdTX1QyNCksIGZ1bnMocm91bmQoLiwgMCkpKQoKIyBXcml0ZSBkYXRhIHRvIC5jc3YgZmlsZQp3cml0ZS5jc3Yod3NfdElJSV9zdW0sICdOb3JtLlJlc3VsdHMvd3Mucm5hLnRJSUkubWVhbi5zZC5jc3YnKQoKIyBTdWJzZXQgTWVhbiB2YWx1ZXMKd3NfdElJSV9tZWFuPC1zdWJzZXQod3NfdElJSV9zdW0sIHNlbGVjdD1jKFRpZXJfSUlJLG1lYW5XU19UMCxtZWFuV1NfVDQsbWVhbldTX1QyNCkpCm5hbWVzKHdzX3RJSUlfbWVhbik8LWMoIlRpZXIgSUlJIiwgIldTIC0gVDAiLCAiV1MgLSBUNCIsICJXUyAtIFQyNCIpCgojIFN1YnNldCBTRCB2YWx1ZXMKd3NfdElJSV9zZDwtc3Vic2V0KHdzX3RJSUlfc3VtLCBzZWxlY3Q9YyhUaWVyX0lJSSxzZFdTX1QwLHNkV1NfVDQsc2RXU19UMjQpKQpuYW1lcyh3c190SUlJX3NkKTwtYygiVGllciBJSUkiLCAiV1MgLSBUMCIsICJXUyAtIFQ0IiwgIldTIC0gVDI0IikKCiMgUmVtZW1iZXIgIlRpZXIgSUlJIiBhcyBub24tbnVtZXJpYyB2YWx1ZXMKd3NfdElJSV9tZWFuX1RpZXJJSUk8LXdzX3RJSUlfbWVhbiRgVGllciBJSUlgCndzX3RJSUlfc2RfVGllcklJSTwtd3NfdElJSV9zZCRgVGllciBJSUlgCgojIFRyYW5zcG9zZSBhbGwgYnV0IGZpcnN0IGNvbHVtbiAoVGllciBJSSkKd3NfdElJSV9tZWFuPC1hcy5kYXRhLmZyYW1lKHQod3NfdElJSV9tZWFuWywtMV0pKQpjb2xuYW1lcyh3c190SUlJX21lYW4pPC13c190SUlJX21lYW5fVGllcklJSQp3c190SUlJX3NkPC1hcy5kYXRhLmZyYW1lKHQod3NfdElJSV9zZFssLTFdKSkKY29sbmFtZXMod3NfdElJSV9zZCk8LXdzX3RJSUlfc2RfVGllcklJSQoKIyBDb21iaW5lIG1lYW4gYW5kIHNkIGludG8gc2luZ2xlIGNvbHVtbiB3aXRoIMKxIGRpdmlkZXIKd3NfdElJSV90YWJsZTwtYXMuZGF0YS5mcmFtZShkby5jYWxsKGNiaW5kLCBsYXBwbHkoMTpuY29sKHdzX3RJSUlfbWVhbiksIGZ1bmN0aW9uKGkpIHBhc3RlMCh3c190SUlJX21lYW5bICwgaV0sICIgwrEgIiwgd3NfdElJSV9zZFsgLCBpXSkpKSkKCiMgVHJhbnNwb3NlIHRoZSB0YWJsZSBiYWNrCndzX3RJSUlfdGFibGU8LXQod3NfdElJSV90YWJsZSkKCiMgUmVuYW1lIGNvbHVtbnMgdG8gU2l0ZXMKY29sbmFtZXMod3NfdElJSV90YWJsZSk8LWMoIldldCBTZWRnZSAoVDApIiwgIldldCBTZWRnZSAoVDQpIiwgIldldCBTZWRnZSAoVDI0KSIpCgpyb3duYW1lcyh3c190SUlJX3RhYmxlKTwtd3NfdElJSV9tZWFuX1RpZXJJSUkKYGBgCgpSdW4gc3RhdGlzdGljYWwgdGVzdHMgdG8gZGV0ZXJtaW5lIGlmIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGV4aXN0IGJldHdlZW4gc2FtcGxpbmcgdGltZXBvaW50cyBmb3IgZWFjaCBUaWVyIEtFR0cgY2F0ZWdvcnkuIENsaWNrIG9uIHRoZSAqKlNob3cvSGlkZSoqIGJ1dHRvbiB0byBzZWUgdGhlIHN0YXRpc3RpY3MuCgo8YnV0dG9uIGNsYXNzPSJidG4gYnRuLXByaW1hcnkiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9IiNCbG9ja05hbWUxMCI+IFNob3cvSGlkZSA8L2J1dHRvbj4gIAo8ZGl2IGlkPSJCbG9ja05hbWUxMCIgY2xhc3M9ImNvbGxhcHNlIj4KYGBge3J9CiMgU3Vic2V0IHRoZSAic3VtIiB2YWx1ZXMgZm9yIGVhY2ggc2FtcGxlCndzX3RJSUlfc3RhdHM8LXN1YnNldCh3c190SUlJX3N1bSwgc2VsZWN0PWMoVGllcl9JSUksUzEwODM3OSxTMTA4MzgxLFMxMDgzODUsUzEwODM4NixTMTA4Mzg4LFMxMDgzOTApKQoKcm93bmFtZXMod3NfdElJSV9zdGF0cykgPC0gd3NfdElJSV9zdGF0cyRUaWVyX0lJSQp3c190SUlJX3N0YXRzPC1hcy5kYXRhLmZyYW1lKHQod3NfdElJSV9zdGF0c1stMV0pKQoKIyBBZGQgdGhlIHRpbWVwb2ludCBjb2x1bW4gdG8gdGhlIHN1bSB0YWJsZQp3c190SUlJX3N0YXRzPC1kYXRhLmZyYW1lKFRpbWVwb2ludCx3c190SUlJX3N0YXRzKQoKIyBTdWJzZXQgcmVzcG9uc2UgdmFyaWFibGVzIGZvciBNQU5PVkEKd3NfdElJSV9zdGF0cyRyZXNwb25zZSA8LSBhcy5tYXRyaXgod3NfdElJSV9zdGF0c1ssIDI6MjZdKQoKIyBNQU5PVkEgdGVzdAp3c190SUlJX21hbm92YSA8LSBtYW5vdmEocmVzcG9uc2UgfiBUaW1lcG9pbnQsIGRhdGE9d3NfdElJSV9zdGF0cykKc3VtbWFyeS5hb3Yod3NfdElJSV9tYW5vdmEpCmBgYAoKUnVuIEFOT1ZBIGZvciBlYWNoIGNhdGVnb3J5IG9mIGludGVyZXN0IChzaWduaWZpY2FudCBpbiBNQU5PVkEpCmBgYHtyfQojIENhcmJvaHlkcmF0ZS5tZXRhYm9saXNtLgp3c190SUlJX2Fvdl9jYXJiczwtYW92KENhcmJvaHlkcmF0ZS5tZXRhYm9saXNtLn5UaW1lcG9pbnQsZGF0YT13c190SUlJX3N0YXRzKQpUdWtleUhTRCh3c190SUlJX2Fvdl9jYXJicykKCiMgU2lnbmFsaW5nIE1vbGVjdWxlcyBhbmQgSW50ZXJhY3Rpb25zCndzX3RJSUlfYW92X3RyYW5zPC1hb3YoU2lnbmFsaW5nLm1vbGVjdWxlcy5hbmQuaW50ZXJhY3Rpb24uflRpbWVwb2ludCxkYXRhPXdzX3RJSUlfc3RhdHMpClR1a2V5SFNEKHdzX3RJSUlfYW92X3RyYW5zKQpgYGAKPC9kaXY+CgojIyMjIyA3LjMuMi4zLiBUaWVyIElWIEV4cHJlc3Npb24KQ2FsY3VsYXRlIFRQTS1ub3JtYWxpemVkIGdlbmUgY291bnQgc3VtcyBmb3IgZWFjaCBXUyBzYW1wbGUgaW4gZWFjaCBUaWVyIElJSSBjYXRlZ29yeS4KYGBge3J9CiMgQ2FsY3VsYXRlIFRQTS1ub3JtYWxpemVkIGdlbmUgY291bnQgc3VtcyBmb3IgZWFjaCBXUyBzYW1wbGUgaW4gZWFjaCBUaWVyIElJSSBjYXRlZ29yeQp3c190SVZfc3VtPC10cG1fYWxsX2V4cF9hbm4gJT4lIGdyb3VwX2J5KFRpZXJfSVYpICU+JSBzdW1tYXJpc2VfYXQodmFycygiUzEwODM3OSIsIlMxMDgzODEiLCJTMTA4Mzg1IiwiUzEwODM4NiIsIlMxMDgzODgiLCJTMTA4MzkwIiksIHN1bSkKd3NfdElWX3N1bTwtd3NfdElWX3N1bSAlPiUgbXV0YXRlX2F0KHZhcnMoUzEwODM3OSxTMTA4MzgxLFMxMDgzODUsUzEwODM4NixTMTA4Mzg4LFMxMDgzOTApLCBmdW5zKHJvdW5kKC4sIDApKSkKd3NfdElWX3N1bTwtYXMuZGF0YS5mcmFtZSh3c190SVZfc3VtKQp3c190SVZfc3VtPC13c190SVZfc3VtW29yZGVyKC13c190SVZfc3VtJFMxMDgzNzkpLF0KYGBgCgpgYGB7cn0KIyBDYWxjdWxhdGUgbWVhbiB2YWx1ZXMgZnJvbSB0aGUgcmVwbGljYXRlIHN1bXMKd3NfdElWX3N1bSRtZWFuV1NfVDA8LWFwcGx5KHdzX3RJVl9zdW1bLDI6M10sIDEsIG1lYW4pCndzX3RJVl9zdW0kbWVhbldTX1Q0PC1hcHBseSh3c190SVZfc3VtWyw0OjVdLCAxLCBtZWFuKQp3c190SVZfc3VtJG1lYW5XU19UMjQ8LWFwcGx5KHdzX3RJVl9zdW1bLDY6N10sIDEsIG1lYW4pCndzX3RJVl9zdW08LXdzX3RJVl9zdW0gJT4lIG11dGF0ZV9hdCh2YXJzKG1lYW5XU19UMCxtZWFuV1NfVDQsbWVhbldTX1QyNCksIGZ1bnMocm91bmQoLiwgMCkpKQoKIyBDYWxjdWxhdGUgc2QgdmFsdWVzIGZyb20gdGhlIHJlcGxpY2F0ZSBzdW1zCndzX3RJVl9zdW0kc2RXU19UMDwtYXBwbHkod3NfdElWX3N1bVssMjozXSwgMSwgc2QpCndzX3RJVl9zdW0kc2RXU19UNDwtYXBwbHkod3NfdElWX3N1bVssNDo1XSwgMSwgc2QpCndzX3RJVl9zdW0kc2RXU19UMjQ8LWFwcGx5KHdzX3RJVl9zdW1bLDY6N10sIDEsIHNkKQp3c190SVZfc3VtPC13c190SVZfc3VtICU+JSBtdXRhdGVfYXQodmFycyhzZFdTX1QwLHNkV1NfVDQsc2RXU19UMjQpLCBmdW5zKHJvdW5kKC4sIDApKSkKCiMgV3JpdGUgZGF0YSB0byAuY3N2IGZpbGUKd3JpdGUuY3N2KHdzX3RJVl9zdW0sICdOb3JtLlJlc3VsdHMvd3Mucm5hLnRJVi5tZWFuLnNkLmNzdicpCgojIFN1YnNldCBNZWFuIHZhbHVlcwp3c190SVZfbWVhbjwtc3Vic2V0KHdzX3RJVl9zdW0sIHNlbGVjdD1jKFRpZXJfSVYsbWVhbldTX1QwLG1lYW5XU19UNCxtZWFuV1NfVDI0KSkKbmFtZXMod3NfdElWX21lYW4pPC1jKCJUaWVyIElWIiwgIldTIC0gVDAiLCAiV1MgLSBUNCIsICJXUyAtIFQyNCIpCgojIFN1YnNldCBTRCB2YWx1ZXMKd3NfdElWX3NkPC1zdWJzZXQod3NfdElWX3N1bSwgc2VsZWN0PWMoVGllcl9JVixzZFdTX1QwLHNkV1NfVDQsc2RXU19UMjQpKQpuYW1lcyh3c190SVZfc2QpPC1jKCJUaWVyIElWIiwgIldTIC0gVDAiLCAiV1MgLSBUNCIsICJXUyAtIFQyNCIpCgojIFJlbWVtYmVyICJUaWVyIElWIiBhcyBub24tbnVtZXJpYyB2YWx1ZXMKd3NfdElWX21lYW5fVGllcklWPC13c190SVZfbWVhbiRgVGllciBJVmAKd3NfdElWX3NkX1RpZXJJVjwtd3NfdElWX3NkJGBUaWVyIElWYAoKIyBUcmFuc3Bvc2UgYWxsIGJ1dCBmaXJzdCBjb2x1bW4gKFRpZXIgSVYpCndzX3RJVl9tZWFuPC1hcy5kYXRhLmZyYW1lKHQod3NfdElWX21lYW5bLC0xXSkpCmNvbG5hbWVzKHdzX3RJVl9tZWFuKTwtd3NfdElWX21lYW5fVGllcklWCndzX3RJVl9zZDwtYXMuZGF0YS5mcmFtZSh0KHdzX3RJVl9zZFssLTFdKSkKY29sbmFtZXMod3NfdElWX3NkKTwtd3NfdElWX3NkX1RpZXJJVgoKIyBDb21iaW5lIG1lYW4gYW5kIHNkIGludG8gc2luZ2xlIGNvbHVtbiB3aXRoIMKxIGRpdmlkZXIKd3NfdElWX3RhYmxlPC1hcy5kYXRhLmZyYW1lKGRvLmNhbGwoY2JpbmQsIGxhcHBseSgxOm5jb2wod3NfdElWX21lYW4pLCBmdW5jdGlvbihpKSBwYXN0ZTAod3NfdElWX21lYW5bICwgaV0sICIgwrEgIiwgd3NfdElWX3NkWyAsIGldKSkpKQoKIyBUcmFuc3Bvc2UgdGhlIHRhYmxlIGJhY2sKd3NfdElWX3RhYmxlPC10KHdzX3RJVl90YWJsZSkKCiMgUmVuYW1lIGNvbHVtbnMgdG8gU2l0ZXMKY29sbmFtZXMod3NfdElWX3RhYmxlKTwtYygiV2V0IFNlZGdlIChUMCkiLCAiV2V0IFNlZGdlIChUNCkiLCAiV2V0IFNlZGdlIChUMjQpIikKCnJvd25hbWVzKHdzX3RJVl90YWJsZSk8LXdzX3RJVl9tZWFuX1RpZXJJVgoKI3dzX3RJVl90YWJsZQpgYGAKClJ1biBzdGF0aXN0aWNhbCB0ZXN0cyB0byBkZXRlcm1pbmUgaWYgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgZXhpc3QgYmV0d2VlbiBzYW1wbGluZyB0aW1lcG9pbnRzIGZvciBlYWNoIFRpZXIgS0VHRyBjYXRlZ29yeS4gQ2xpY2sgb24gdGhlICoqU2hvdy9IaWRlKiogYnV0dG9uIHRvIHNlZSB0aGUgc3RhdGlzdGljcy4KCjxidXR0b24gY2xhc3M9ImJ0biBidG4tcHJpbWFyeSIgZGF0YS10b2dnbGU9ImNvbGxhcHNlIiBkYXRhLXRhcmdldD0iI0Jsb2NrTmFtZTExIj4gU2hvdy9IaWRlIDwvYnV0dG9uPiAgCjxkaXYgaWQ9IkJsb2NrTmFtZTExIiBjbGFzcz0iY29sbGFwc2UiPgpgYGB7cn0KIyBTdWJzZXQgdGhlICJzdW0iIHZhbHVlcyBmb3IgZWFjaCBzYW1wbGUKd3NfdElWX3N0YXRzPC1zdWJzZXQod3NfdElWX3N1bSwgc2VsZWN0PWMoVGllcl9JVixTMTA4Mzc5LFMxMDgzODEsUzEwODM4NSxTMTA4Mzg2LFMxMDgzODgsUzEwODM5MCkpCgpyb3duYW1lcyh3c190SVZfc3RhdHMpIDwtIHdzX3RJVl9zdGF0cyRUaWVyX0lWCndzX3RJVl9zdGF0czwtYXMuZGF0YS5mcmFtZSh0KHdzX3RJVl9zdGF0c1stMV0pKQoKIyBBZGQgdGhlIHRpbWVwb2ludCBjb2x1bW4gdG8gdGhlIHN1bSB0YWJsZQp3c190SVZfc3RhdHM8LWRhdGEuZnJhbWUoVGltZXBvaW50LHdzX3RJVl9zdGF0cykKCiMgU3Vic2V0IHJlc3BvbnNlIHZhcmlhYmxlcyBmb3IgTUFOT1ZBCndzX3RJVl9zdGF0cyRyZXNwb25zZSA8LSBhcy5tYXRyaXgod3NfdElWX3N0YXRzWywgMjoyMjddKQoKIyBNQU5PVkEgdGVzdAp3c190SVZfbWFub3ZhIDwtIG1hbm92YShyZXNwb25zZSB+IFRpbWVwb2ludCwgZGF0YT13c190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHdzX3RJVl9tYW5vdmEpCmBgYAoKUnVuIEFOT1ZBIGZvciBlYWNoIGNhdGVnb3J5IG9mIGludGVyZXN0IChzaWduaWZpY2FudCBpbiBNQU5PVkEpCmBgYHtyIGV2YWw9RkFMU0V9CiMjIEdseWNvbHlzaXMKd3NfdElWX3N0YXQxPC1hb3YoWDAwMDEwLkdseWNvbHlzaXMuLi5HbHVjb25lb2dlbmVzaXMuLlBBVEgua28wMDAxMC5+VGltZXBvaW50LGRhdGE9d3NfdElWX3N0YXRzKQpzdW1tYXJ5LmFvdih3c190SVZfc3RhdDEpClR1a2V5SFNEKHdzX3RJVl9zdGF0MSkKCiMjIEZhdHR5IEFjaWQgTWV0YWJvbGlzbQp3c190SVZfc3RhdDI8LWFvdihYMDEyMTIuRmF0dHkuYWNpZC5tZXRhYm9saXNtLi5QQVRILmtvMDEyMTIuflRpbWVwb2ludCxkYXRhPXdzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3Yod3NfdElWX3N0YXQyKQpUdWtleUhTRCh3c190SVZfc3RhdDIpCgojIyBQZW50b3NlIGFuZCBHbHVjdXJvbmF0ZSBJbnRlcmNvbnZlcnNpb25zCndzX3RJVl9zdGF0MzwtYW92KFgwMDA0MC5QZW50b3NlLmFuZC5nbHVjdXJvbmF0ZS5pbnRlcmNvbnZlcnNpb25zLi5QQVRILmtvMDAwNDAuflRpbWVwb2ludCxkYXRhPXdzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3Yod3NfdElWX3N0YXQzKQpUdWtleUhTRCh3c190SVZfc3RhdDMpCgojIyBTdGVyb2lkIERlZ3JhZGF0aW9uCndzX3RJVl9zdGF0NDwtYW92KFgwMDk4NC5TdGVyb2lkLmRlZ3JhZGF0aW9uLi5QQVRILmtvMDA5ODQuflRpbWVwb2ludCxkYXRhPXdzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3Yod3NfdElWX3N0YXQ0KQpUdWtleUhTRCh3c190SVZfc3RhdDQpCgojIyBCYWN0ZXJpYWwgQ2hlbW90YXhpcwp3c190SVZfc3RhdDU8LWFvdihYMDIwMzAuQmFjdGVyaWFsLmNoZW1vdGF4aXMuLlBBVEgua28wMjAzMC5+VGltZXBvaW50LGRhdGE9d3NfdElWX3N0YXRzKQpzdW1tYXJ5LmFvdih3c190SVZfc3RhdDUpClR1a2V5SFNEKHdzX3RJVl9zdGF0NSkKCiMjIFBob3NwaG9uYXRlIGFuZCBQaG9zaGluYXRlIE1ldGFib2xpc20Kd3NfdElWX3N0YXQ2PC1hb3YoWDAwNDQwLlBob3NwaG9uYXRlLmFuZC5waG9zcGhpbmF0ZS5tZXRhYm9saXNtLi5QQVRILmtvMDA0NDAuflRpbWVwb2ludCxkYXRhPXdzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3Yod3NfdElWX3N0YXQ2KQpUdWtleUhTRCh3c190SVZfc3RhdDYpCgojIyBDYXJib24gRml4YXRpb24gUGF0aHdheXMgaW4gUHJva2FyeW90ZXMKd3NfdElWX3N0YXQ3PC1hb3YoWDAwNzIwLkNhcmJvbi5maXhhdGlvbi5wYXRod2F5cy5pbi5wcm9rYXJ5b3Rlcy4uUEFUSC5rbzAwNzIwLn5UaW1lcG9pbnQsZGF0YT13c190SVZfc3RhdHMpCnN1bW1hcnkuYW92KHdzX3RJVl9zdGF0NykKVHVrZXlIU0Qod3NfdElWX3N0YXQ3KQoKIyMgTXVjaW4gVHlwZSBPIEdseWNhbiBCaW9zeW50aGVzaXMKd3NfdElWX3N0YXQ4PC1hb3YoWDAwNTEyLk11Y2luLnR5cGUuTy5nbHljYW4uYmlvc3ludGhlc2lzLi5QQVRILmtvMDA1MTIuflRpbWVwb2ludCxkYXRhPXdzX3RJVl9zdGF0cykKc3VtbWFyeS5hb3Yod3NfdElWX3N0YXQ4KQpUdWtleUhTRCh3c190SVZfc3RhdDgpCmBgYAo8L2Rpdj4KCiMjIyA3LjQuIERpZmZlcmVudGlhbCBFeHByZXNzaW9uCgpEZXRlcm1pbmUgd2hpY2ggZ2VuZXMgd2VyZSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgYmV0d2VlbiBleHBlcmltZW50YWwgdHJlYXRtZW50cyB1c2luZyB0aGUgQmlvY29uZHVjdG9yIHBhY2thZ2UgKiplZGdlUioqIGZvciBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNpcyBvbiBUUE0tbm9ybWFsaXplZCByZWFkIGNvdW50cy4gIFRoZSAqKmVkZ2VSKiogcGFja2FnZSBpbXBsZW1lbnRzIHN0YXRpc3RpY2FsIG1ldGhvZHMgYmFzZWQgb24gZ2VuZXJhbGl6ZWQgbGluZWFyIG1vZGVscyAoZ2xtcyksIHN1aXRhYmxlIGZvciBtdWx0aWZhY3RvciBleHBlcmltZW50cyBvZiBhbnkgY29tcGxleGl0eS4gIEEgcGFydGljdWxhciBmZWF0dXJlIG9mICoqZWRnZVIqKiBmdW5jdGlvbmFsaXR5IGFyZSBlbXBpcmljYWwgQmF5ZXMgbWV0aG9kcyB0aGF0IHBlcm1pdCB0aGUgZXN0aW1hdGlvbiBvZiBnZW5lLXNwZWNpZmljIGJpb2xvZ2ljYWwgdmFyaWF0aW9uLCBldmVuIGZvciBleHBlcmltZW50cyB3aXRoIG1pbmltYWwgbGV2ZWxzIG9mIGJpb2xvZ2ljYWwgcmVwbGljYXRpb24uCgojIyMjIDcuNC4xLiBER0UgT2JqZWN0aXZlCgpXZSBoYXZlIHR3byBvYmplY3RpdmVzIGZvciBvdXIgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYW5hbHlzaXMuIAoKMS4gRGV0ZWN0IGdlbmVzIHRoYXQgYXJlIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBiZXR3ZWVuIGV4cGVyaW1lbnRhbCB0aW1lcG9pbnRzLCBhZGp1c3RpbmcgZm9yIGFueSBkaWZmZXJlbmNlcyBiZXR3ZWVuIG1lc29jb3NtcyB0aGF0IHdlcmUgc2FtcGxlZCwgd2l0aGluIFdldCBTZWRnZSBvciBUdXNzb2NrIG1lc29jb3Ntcy4KICAgICsgKkRldGVybWluZSBob3cgZ2VuZSBleHByZXNzaW9uIGNoYW5nZWQgYmV0d2VlbiBhbm94aWMgKFQwKSB0byBveGljIChUNCkgdG8gbWl4ZWQtcmVkb3ggKFQyNCkgdGltZXBvaW50cywgc3BlY2lmaWMgdG8gdGhlIFdldCBTZWRnZSBlY29zeXN0ZW0gb3IgdGhlIFR1c3NvY2sgZWNvc3lzdGVtKgoyLiBEZXRlY3QgZ2VuZXMgdGhhdCBhcmUgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGJldHdlZW4gZWNvc3lzdGVtcyBhdCBzaW1pbGFyIHRpbWVwb2ludHMgKHNpbWlsYXIgcmVkb3ggY29uZGl0aW9ucykuCiAgICArICpEZXRlcm1pbmUgaWYgdGhlIHNhbWUgKG9yIGRpZmZlcmVudCkgZ2VuZXMgd2VyZSBleHByZXNzZWQgYmV0d2VlbiBlY29zeXN0ZW1zIHdoZW4gdGhlIHNvaWwgcmVkb3ggY29uZGl0aW9ucyB3ZXJlIHNpbWlsYXIqCgpJdCBpcyBwb3NzaWJsZSAoYW5kIGxpa2VseSkgdGhhdCB0aGVyZSBhcmUgdW5pcXVlIGdlbmVjYWxsIElEJ3MgdGhhdCBzaGFyZSBpZGVudGljYWwgYW5ub3RhdGlvbnMgdG8gS08gYW5kIFRheG9ub215LCBidXQgYXJlIHN0aWxsIHRyZWF0ZWQgYXMgdW5pcXVlIGVudHJpZXMgd2l0aCBzZXBhcmF0ZSBjb3VudCB2YWx1ZXMgdGhhdCBhcmUgZmFjdG9yZWQgaW50byBERSBhbmFseXNpcyBpbXByb3Blcmx5LgogICAgKyAqSGVyZSwgd2UgYWdncmVnYXRlIChzdW0pIGdlbmVjYWxsIElEIGNvdW50cyBieSBzaGFyZWQgS08gYW5kIFRheG9ub215IHRvIHJlZHVjZSBkdXBsaWNhdGVzIGluIHRoZSBkYXRhc2V0IGFuZCBpbXByb3ZlIHRoZSBERSBhbmFseXNpcyByZXN1bHRzIHRvIGJlIGJpb2xvZ2ljYWxseSByZWxldmFudC4qCgojIyMjIDcuNC4yLiBER0UgV2l0aGluIFR1bmRyYQoKT3VyIGZpcnN0IHNldCBvZiBERSBhbmFseXNlcyBmb2N1cyBvbiBkZXRlcm1pbmluZyBzaWduaWZpY2FudCBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgYmV0d2VlbiBzYW1wbGluZyB0aW1lcG9pbnRzIHdpdGhpbiBUdXNzb2NrIG9yIFdldCBTZWRnZSBtZXNvY29zbXMuCgojIyMjIyA3LjQuMi4xLiBUdXNzIFQ0dnNUMAoKU3Vic2V0IGRhdGEgZnJvbSB0aGUgZnVsbCB0cG1fZXhwcmVzc2VkIGRhdGFzZXQuIENsaWNrIG9uIHRoZSAqKlNob3cvSGlkZSoqIGJ1dHRvbiB0byBzZWUgdGhlIHN0ZXBzLgoKPGJ1dHRvbiBjbGFzcz0iYnRuIGJ0bi1wcmltYXJ5IiBkYXRhLXRvZ2dsZT0iY29sbGFwc2UiIGRhdGEtdGFyZ2V0PSIjQmxvY2tOYW1lMTIiPiBTaG93L0hpZGUgPC9idXR0b24+ICAKPGRpdiBpZD0iQmxvY2tOYW1lMTIiIGNsYXNzPSJjb2xsYXBzZSI+CmBgYHtyfQojIFN1YnNldCBkYXRhIGZyb20gdGhlIGZ1bGwgdHBtX2V4cHJlc3NlZCBkYXRhc2V0CnR1c3NfVDR2c1QwPC10cG1fdHVzc19leHByZXNzZWRbLGMoMjo1LDg6MTQpXQoKIyBBZ2dyZWdhdGUgKHN1bSkgZ2VuZWNhbGwgSUQgY291bnRzIGJ5IHNoYXJlZCBLTyBhbmQgVGF4b25vbXkgdG8gcmVkdWNlIGR1cGxpY2F0ZXMgaW4gdGhlIGRhdGFzZXQgYW5kIGltcHJvdmUgdGhlIERFIGFuYWx5c2lzIHJlc3VsdHMgdG8gYmUgYmlvbG9naWNhbGx5IHJlbGV2YW50Lgp0dXNzX1Q0dnNUMDwtYWdncmVnYXRlKC4gfiBLTyArIFN5bWJvbCArIEZ1bmN0aW9uICsgVGllcl9JSSArIFRpZXJfSUlJICsgVGllcl9JViArIFRheG9ub215LCBkYXRhPXR1c3NfVDR2c1QwLEZVTj1zdW0pCgojIyBSZWFkaW5nIGluIHRoZSBkYXRhCiMgQ3JlYXRlIERHRUxpc3QgZm9yIFR1c3MgVDQgdnMgVDAgc3ViZGF0YQp0dXNzX1Q0dnNUMDwtREdFTGlzdChjb3VudHM9dHVzc19UNHZzVDBbLDg6MTFdLCBnZW5lcz10dXNzX1Q0dnNUMFssMTo3XSkKcm93bmFtZXModHVzc19UNHZzVDAkY291bnRzKTwtcm93bmFtZXModHVzc19UNHZzVDAkZ2VuZXMpPC10dXNzX1Q0dnNUMCRnZW5lcyRJRAp0dXNzX1Q0dnNUMCRnZW5lcyRJRDwtTlVMTAoKIyMgTm9ybWFsaXphdGlvbgojIFRlbGwgZWRnZVIgdGhhdCB5b3UgZG9uJ3Qgd2FudCB0byBub3JtYWxpemUgdGhlIHN1YmRhdGEgKGFscmVhZHkgVFBNIG5vcm1hbGl6ZWQpCnR1c3NfVDR2c1QwPC1jYWxjTm9ybUZhY3RvcnModHVzc19UNHZzVDAsIG1ldGhvZD0ibm9uZSIpCnR1c3NfVDR2c1QwJHNhbXBsZXMKCiMjIERhdGEgRXhwbG9yYXRpb24KIyBUaGUgcGxvdE1EUyBmdW5jdGlvbiBwcm9kdWNlcyBhIHBsb3QgaW4gd2hpY2ggZGlzdGFuY2VzIGJldHdlZW4gc2FtcGxlcyBjb3JyZXNwb25kIHRvIGxlYWRpbmcgYmlvbG9naWNhbCBjb2VmZmljaWVudCBvZiB2YXJpYXRpb24gKEJDVikgYmV0d2VlbiB0aG9zZSBzYW1wbGVzCnBsb3RNRFModHVzc19UNHZzVDAsIGNvbD1yZXAoMToyLCBlYWNoPTIpKQoKIyMgVGhlIERlc2lnbiBNYXRyaXgKIyBCZWZvcmUgd2UgZml0IG5lZ2F0aXZlIGJpbm9taWFsIEdMTXMsIHdlIG5lZWQgdG8gZGVmaW5lIG91ciBkZXNpZ24gbWF0cml4IGJhc2VkIG9uIHRoZSBleHBlcmltZW50YWwgZGVzaWduLiBIZXJlLCB3ZSB3YW50IHRvIHRlc3QgZm9yIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGJldHdlZW4gVDQgYW5kIFQwIHRpbWVwb2ludHMgd2l0aGluIG1lc29jb3NtcywgaS5lLiwgYWRqdXN0aW5nIGZvciBkaWZmZXJlbmNlcyBiZXR3ZWVuIG1lc29jb3Ntcy4gSW4gc3RhdGlzdGljcywgdGhpcyBpcyBhbiBhZGRpdGl2ZSBsaW5lYXIgbW9kZWwgd2l0aCBtZXNvY29zbSBhcyB0aGUgYmxvY2tpbmcgZmFjdG9yLgpNZXNvY29zbV90dXNzX1Q0dnNUMDwtZmFjdG9yKGMoMSwyLDEsMikpClRpbWVwb2ludF90dXNzX1Q0dnNUMDwtZmFjdG9yKGMoIlQwIiwiVDAiLCJUNCIsIlQ0IikpCmRhdGEuZnJhbWUoU2FtcGxlX3R1c3NfVDR2c1QwPWNvbG5hbWVzKHR1c3NfVDR2c1QwKSxNZXNvY29zbV90dXNzX1Q0dnNUMCxUaW1lcG9pbnRfdHVzc19UNHZzVDApCnR1c3NfVDR2c1QwX2Rlc2lnbjwtbW9kZWwubWF0cml4KH5NZXNvY29zbV90dXNzX1Q0dnNUMCtUaW1lcG9pbnRfdHVzc19UNHZzVDApCnJvd25hbWVzKHR1c3NfVDR2c1QwX2Rlc2lnbik8LWNvbG5hbWVzKHR1c3NfVDR2c1QwKQp0dXNzX1Q0dnNUMF9kZXNpZ24KCiMjIEVzdGltYXRpbmcgRGlzcGVyc2lvbgojIFdlIGVzdGltYXRlIHRoZSBOQiBkaXNwZXJzaW9uIGZvciB0aGUgZGF0YXNldAp0dXNzX1Q0dnNUMDwtZXN0aW1hdGVEaXNwKHR1c3NfVDR2c1QwLHR1c3NfVDR2c1QwX2Rlc2lnbixyb2J1c3Q9VFJVRSkKdHVzc19UNHZzVDAkY29tbW9uLmRpc3BlcnNpb24KCiMgVGhlIHNxdWFyZSByb290IG9mIHRoZSBjb21tb24gZGlzcGVyc2lvbiBnaXZlcyB0aGUgY29lZmZpY2llbnQgb2YgdmFyaWF0aW9uIG9mIGJpb2xvZ2ljYWwgdmFyaWF0aW9uLgpzcXJ0KHR1c3NfVDR2c1QwJGNvbW1vbi5kaXNwZXJzaW9uKQoKIyBWaWV3IHRoZSBkaXNwZXJzaW9uIGVzdGltYXRlcyBpbiBhIEJDViBwbG90CnBsb3RCQ1YodHVzc19UNHZzVDApCgojIyBEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbgojIE5vdyB3ZSBwcm9jZWVkIHRvIGRldGVybWluZSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgYnkgZml0dGluZyBnZW5ld2lzZSBnbG1zCnR1c3NfVDR2c1QwX2ZpdDwtZ2xtRml0KHR1c3NfVDR2c1QwLHR1c3NfVDR2c1QwX2Rlc2lnbikKCiMgQ29uZHVjdCBsaWtlbGlob29kIHJhdGlvIHRlc3RzIGZvciBUNCB2cyBUMCBkaWZmZXJlbmNlcyBhbmQgc2hvdyB0aGUgdG9wIGdlbmVzLiBUaGUgZ2VuZXdpc2UgdGVzdHMgYXJlIGZvciBUNCB2cyBUMCBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiwgYWRqdXN0aW5nIGZvciBiYXNlbGluZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSB0d28gbWVzb2Nvc21zLiAgVGhlIHRlc3RzIGNhbiBiZSB2aWV3ZWQgYXMgYW5hbG9nb3VzIHRvIHBhaXJlZCB0LXRlc3RzLiBUaGUgdG9wIERFIHRhZ3MgaGF2ZSB0aW55IHAtdmFsdWVzIGFuZCBGRFIgdmFsdWVzLCBhcyB3ZWxsIGFzIGxhcmdlIGZvbGQgY2hhbmdlcy4KdHVzc19UNHZzVDBfbHJ0PC1nbG1MUlQodHVzc19UNHZzVDBfZml0KQp0dXNzX1Q0dnNUMF90b3BUYWdzPC10b3BUYWdzKHR1c3NfVDR2c1QwX2xydCxuPTI1KQp0dXNzX1Q0dnNUMF90b3BUYWdzCgojIyBIZXJlJ3MgdGhlIFRQTS1ub3JtYWxpemVkIHZhbHVlcyBpbiBpbmRpdmlkdWFsIHNhbXBsZXMgZm9yIGFsbCBzaWduaWZpY2FudCBnZW5lcy4KIyBXZSBzZWUgdGhhdCBhbGwgdGhlIHNpZ25pZmljYW50IGdlbmVzIGhhdmUgY29uc2lzdGVudCBUNCB2cyBUMCBjaGFuZ2VzIGZvciB0aGUgdHdvIG1lc29jb3Ntcy4KdHVzc19UNHZzVDBfcHZhbHVlPC1vcmRlcih0dXNzX1Q0dnNUMF9scnQkdGFibGUkUFZhbHVlKQpjcG0odHVzc19UNHZzVDApW3R1c3NfVDR2c1QwX3B2YWx1ZVsxOjI1XSxdCmBgYAo8L2Rpdj4KClBsb3R0aW5nIHNpZ25pZmljYW50IEtPcyBpbiBER0UgYW5hbHlzaXMuCmBgYHtyfQojIFRoZSB0b3RhbCBudW1iZXIgb2YgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIGF0IDUlIEZEUiBpcyBnaXZlbiBieToKdHVzc19UNHZzVDBfRkRSPC1wLmFkanVzdCh0dXNzX1Q0dnNUMF9scnQkdGFibGUkUFZhbHVlLCBtZXRob2Q9IkJIIikKc3VtKHR1c3NfVDR2c1QwX0ZEUjwwLjA1KQpzdW1tYXJ5KGRlY2lkZVRlc3RzKHR1c3NfVDR2c1QwX2xydCkpCgojIFBsb3QgdGhlIGxvZy1mb2xkIGNoYW5nZSBhZ2FpbnN0IGxvZy10cmFuc2NyaXB0cyBwZXIgbWlsbGlvbiwgd2l0aCBERSBnZW5lcyBoaWdobGlnaHRlZC4KdHVzc19UNHZzVDBfTURwbG90PC1wbG90TUQodHVzc19UNHZzVDBfbHJ0LCBobC5jb2w9YygiZ3JlZW4zIiwicGFsZWdyZWVuMSIpLCBtYWluID0gTlVMTCwgeGxhYj0iQXZlcmFnZSBsb2cgVFBNIikgKyBhYmxpbmUoaD0wLGNvbD0iZ3JheSIsIGx0eT0iZGFzaGVkIikKdHVzc19UNHZzVDBfTURwbG90CmBgYAoKYGBge3IgZWNobz1GQUxTRX0KIyBXcml0ZSB0aGUgdG9wVGFncyByZXN1bHRzIHRvIC5jc3YgdGFibGUKdHVzc19UNHZzVDBfcmVzdWx0cyA8LSBhcy5kYXRhLmZyYW1lKHRvcFRhZ3ModHVzc19UNHZzVDBfbHJ0LG4gPSBJbmYpKQp3cml0ZS5jc3YodHVzc19UNHZzVDBfcmVzdWx0cywiREUuUmVzdWx0cy90dXNzX1Q0dnNUMF9yZXN1bHRzLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQpgYGAKCiMjIyMjIDcuNC4yLjIuIFR1c3MgVDI0dnNUNAoKTm93IGFuYWx5emUgdGhlIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcyBpbiB0aGUgVHVzc29jayBkYXRhc2V0IGJldHdlZW4gdGltZXBvaW50cyBUMjQgKG1peGVkIHJlZG94KSBhbmQgVDQgKG94aWMgcmVkb3gpLiBDbGljayBvbiB0aGUgKipTaG93L0hpZGUqKiBidXR0b24gdG8gc2VlIHRoZSBzdGVwcy4KCjxidXR0b24gY2xhc3M9ImJ0biBidG4tcHJpbWFyeSIgZGF0YS10b2dnbGU9ImNvbGxhcHNlIiBkYXRhLXRhcmdldD0iI0Jsb2NrTmFtZTEzIj4gU2hvdy9IaWRlIDwvYnV0dG9uPiAgCjxkaXYgaWQ9IkJsb2NrTmFtZTEzIiBjbGFzcz0iY29sbGFwc2UiPgpgYGB7cn0KIyBTdWJzZXQgZGF0YSBmcm9tIHRoZSBmdWxsIHRwbV9leHByZXNzZWQgZGF0YXNldAp0dXNzX1QyNHZzVDQ8LXRwbV90dXNzX2V4cHJlc3NlZFssYyg0OjcsODoxNCldCgojIEFnZ3JlZ2F0ZSAoc3VtKSBnZW5lY2FsbCBJRCBjb3VudHMgYnkgc2hhcmVkIEtPIGFuZCBUYXhvbm9teSB0byByZWR1Y2UgZHVwbGljYXRlcyBpbiB0aGUgZGF0YXNldCBhbmQgaW1wcm92ZSB0aGUgREUgYW5hbHlzaXMgcmVzdWx0cyB0byBiZSBiaW9sb2dpY2FsbHkgcmVsZXZhbnQuCnR1c3NfVDI0dnNUNDwtYWdncmVnYXRlKC4gfiBLTyArIFN5bWJvbCArIEZ1bmN0aW9uICsgVGllcl9JSSArIFRpZXJfSUlJICsgVGllcl9JViArIFRheG9ub215LCBkYXRhPXR1c3NfVDI0dnNUNCwgRlVOPXN1bSkKCiMjIFJlYWRpbmcgaW4gdGhlIGRhdGEKIyBDcmVhdGUgREdFTGlzdCBmb3IgV1MgVDQgdnMgVDAgc3ViZGF0YQp0dXNzX1QyNHZzVDQ8LURHRUxpc3QoY291bnRzPXR1c3NfVDI0dnNUNFssODoxMV0sIGdlbmVzPXR1c3NfVDI0dnNUNFssMTo3XSkKcm93bmFtZXModHVzc19UMjR2c1Q0JGNvdW50cyk8LXJvd25hbWVzKHR1c3NfVDI0dnNUNCRnZW5lcyk8LXR1c3NfVDI0dnNUNCRnZW5lcyRJRAp0dXNzX1QyNHZzVDQkZ2VuZXMkSUQ8LU5VTEwKCiMjIE5vcm1hbGl6YXRpb24KIyBUZWxsIGVkZ2VSIHRoYXQgeW91IGRvbid0IHdhbnQgdG8gbm9ybWFsaXplIHRoZSBzdWJkYXRhIChhbHJlYWR5IFRQTSBub3JtYWxpemVkKQp0dXNzX1QyNHZzVDQ8LWNhbGNOb3JtRmFjdG9ycyh0dXNzX1QyNHZzVDQsIG1ldGhvZD0ibm9uZSIpCnR1c3NfVDI0dnNUNCRzYW1wbGVzCgojIyBEYXRhIEV4cGxvcmF0aW9uCiMgVGhlIHBsb3RNRFMgZnVuY3Rpb24gcHJvZHVjZXMgYSBwbG90IGluIHdoaWNoIGRpc3RhbmNlcyBiZXR3ZWVuIHNhbXBsZXMgY29ycmVzcG9uZCB0byBsZWFkaW5nIGJpb2xvZ2ljYWwgY29lZmZpY2llbnQgb2YgdmFyaWF0aW9uIChCQ1YpIGJldHdlZW4gdGhvc2Ugc2FtcGxlcwpwbG90TURTKHR1c3NfVDI0dnNUNCwgY29sPXJlcCgxOjIsIGVhY2g9MikpCgojIyBUaGUgRGVzaWduIE1hdHJpeAojIEJlZm9yZSB3ZSBmaXQgbmVnYXRpdmUgYmlub21pYWwgR0xNcywgd2UgbmVlZCB0byBkZWZpbmUgb3VyIGRlc2lnbiBtYXRyaXggYmFzZWQgb24gdGhlIGV4cGVyaW1lbnRhbCBkZXNpZ24uIEhlcmUsIHdlIHdhbnQgdG8gdGVzdCBmb3IgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYmV0d2VlbiBUNCBhbmQgVDAgdGltZXBvaW50cyB3aXRoaW4gbWVzb2Nvc21zLCBpLmUuLCBhZGp1c3RpbmcgZm9yIGRpZmZlcmVuY2VzIGJldHdlZW4gbWVzb2Nvc21zLiBJbiBzdGF0aXN0aWNzLCB0aGlzIGlzIGFuIGFkZGl0aXZlIGxpbmVhciBtb2RlbCB3aXRoIG1lc29jb3NtIGFzIHRoZSBibG9ja2luZyBmYWN0b3IuCk1lc29jb3NtX3R1c3NfVDI0dnNUNDwtZmFjdG9yKGMoMSwyLDEsMikpClRpbWVwb2ludF90dXNzX1QyNHZzVDQ8LWZhY3RvcihjKCJUNCIsIlQ0IiwiVDI0IiwiVDI0IikpCmRhdGEuZnJhbWUoU2FtcGxlX3R1c3NfVDI0dnNUND1jb2xuYW1lcyh0dXNzX1QyNHZzVDQpLE1lc29jb3NtX3R1c3NfVDI0dnNUNCxUaW1lcG9pbnRfdHVzc19UMjR2c1Q0KQp0dXNzX1QyNHZzVDRfZGVzaWduPC1tb2RlbC5tYXRyaXgofk1lc29jb3NtX3R1c3NfVDI0dnNUNCtUaW1lcG9pbnRfdHVzc19UMjR2c1Q0KQpyb3duYW1lcyh0dXNzX1QyNHZzVDRfZGVzaWduKTwtY29sbmFtZXModHVzc19UMjR2c1Q0KQp0dXNzX1QyNHZzVDRfZGVzaWduCgojIyBFc3RpbWF0aW5nIERpc3BlcnNpb24KIyBXZSBlc3RpbWF0ZSB0aGUgTkIgZGlzcGVyc2lvbiBmb3IgdGhlIGRhdGFzZXQKdHVzc19UMjR2c1Q0PC1lc3RpbWF0ZURpc3AodHVzc19UMjR2c1Q0LHR1c3NfVDI0dnNUNF9kZXNpZ24scm9idXN0PVRSVUUpCnR1c3NfVDI0dnNUNCRjb21tb24uZGlzcGVyc2lvbgoKIyBUaGUgc3F1YXJlIHJvb3Qgb2YgdGhlIGNvbW1vbiBkaXNwZXJzaW9uIGdpdmVzIHRoZSBjb2VmZmljaWVudCBvZiB2YXJpYXRpb24gb2YgYmlvbG9naWNhbCB2YXJpYXRpb24uCnNxcnQodHVzc19UMjR2c1Q0JGNvbW1vbi5kaXNwZXJzaW9uKQoKIyBWaWV3IHRoZSBkaXNwZXJzaW9uIGVzdGltYXRlcyBpbiBhIEJDViBwbG90CnBsb3RCQ1YodHVzc19UMjR2c1Q0KQoKIyMgRGlmZmVyZW50aWFsIEV4cHJlc3Npb24KIyBOb3cgd2UgcHJvY2VlZCB0byBkZXRlcm1pbmUgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIGJ5IGZpdHRpbmcgZ2VuZXdpc2UgZ2xtcwp0dXNzX1QyNHZzVDRfZml0PC1nbG1GaXQodHVzc19UMjR2c1Q0LHR1c3NfVDI0dnNUNF9kZXNpZ24pCgojIENvbmR1Y3QgbGlrZWxpaG9vZCByYXRpbyB0ZXN0cyBmb3IgVDQgdnMgVDAgZGlmZmVyZW5jZXMgYW5kIHNob3cgdGhlIHRvcCBnZW5lcy4gVGhlIGdlbmV3aXNlIHRlc3RzIGFyZSBmb3IgVDQgdnMgVDAgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24sIGFkanVzdGluZyBmb3IgYmFzZWxpbmUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgdHdvIG1lc29jb3Ntcy4gIFRoZSB0ZXN0cyBjYW4gYmUgdmlld2VkIGFzIGFuYWxvZ291cyB0byBwYWlyZWQgdC10ZXN0cy4gVGhlIHRvcCBERSB0YWdzIGhhdmUgdGlueSBwLXZhbHVlcyBhbmQgRkRSIHZhbHVlcywgYXMgd2VsbCBhcyBsYXJnZSBmb2xkIGNoYW5nZXMuCnR1c3NfVDI0dnNUNF9scnQ8LWdsbUxSVCh0dXNzX1QyNHZzVDRfZml0KQp0b3BUYWdzKHR1c3NfVDI0dnNUNF9scnQsbj0yNSkKCiMgSGVyZSdzIHRoZSBUUE0tbm9ybWFsaXplZCB2YWx1ZXMgaW4gaW5kaXZpZHVhbCBzYW1wbGVzLgojIFdlIHNlZSB0aGF0IGFsbCB0aGUgZ2VuZXMgaGF2ZSBjb25zaXN0ZW50IGNoYW5nZXMgYmV0d2VlbiByZXBsaWNhdGVzIHdpdGhpbiBlYWNoIHRpbWVwb2ludC4KdHVzc19UMjR2c1Q0X3B2YWx1ZTwtb3JkZXIodHVzc19UMjR2c1Q0X2xydCR0YWJsZSRQVmFsdWUpCmNwbSh0dXNzX1QyNHZzVDQpW3R1c3NfVDI0dnNUNF9wdmFsdWVbMToyNV0sXQpgYGAKPC9kaXY+CgpQbG90dGluZyBzaWduaWZpY2FudCBLT3MgaW4gREdFIGFuYWx5c2lzLgpgYGB7cn0KIyBUaGUgdG90YWwgbnVtYmVyIG9mIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcyBhdCA1JSBGRFIgaXMgZ2l2ZW4gYnk6CnR1c3NfVDI0dnNUNF9GRFI8LXAuYWRqdXN0KHR1c3NfVDI0dnNUNF9scnQkdGFibGUkUFZhbHVlLCBtZXRob2Q9IkJIIikKc3VtKHR1c3NfVDI0dnNUNF9GRFI8MC4wNSkKc3VtbWFyeShkZWNpZGVUZXN0cyh0dXNzX1QyNHZzVDRfbHJ0KSkKCiMgUGxvdCB0aGUgbG9nLWZvbGQgY2hhbmdlIGFnYWluc3QgbG9nLXRyYW5zY3JpcHRzIHBlciBtaWxsaW9uLCB3aXRoIERFIGdlbmVzIGhpZ2hsaWdodGVkLgp0dXNzX1QyNHZzVDRfTURwbG90PC1wbG90TUQodHVzc19UMjR2c1Q0X2xydCwgaGwuY29sPWMoImRhcmtncmVlbiIsImdyZWVuMyIpLCBtYWluID0gTlVMTCwgeGxhYj0iQXZlcmFnZSBsb2cgVFBNIikgKyBhYmxpbmUoaD0wLGNvbD0iZ3JheSIsIGx0eT0iZGFzaGVkIikKdHVzc19UMjR2c1Q0X01EcGxvdApgYGAKCmBgYHtyIGVjaG89RkFMU0V9CiMgV3JpdGUgdGhlIHRvcFRhZ3MgcmVzdWx0cyB0byAuY3N2IHRhYmxlCnR1c3NfVDI0dnNUNF9yZXN1bHRzIDwtIGFzLmRhdGEuZnJhbWUodG9wVGFncyh0dXNzX1QyNHZzVDRfbHJ0LG4gPSBJbmYpKQp3cml0ZS5jc3YodHVzc19UMjR2c1Q0X3Jlc3VsdHMsIkRFLlJlc3VsdHMvdHVzc19UMjR2c1Q0X3Jlc3VsdHMuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoKIyMjIyMgNy40LjIuMy4gVHVzcyBUMjR2c1QwCgpGaW5hbGx5LCBhbmFseXplIHRoZSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgaW4gdGhlIFR1c3NvY2sgZGF0YXNldCBiZXR3ZWVuIHRpbWVwb2ludHMgVDI0IChtaXhlZCByZWRveCkgYW5kIFQwIChhbm94aWMgcmVkb3gpLiBDbGljayBvbiB0aGUgKipTaG93L0hpZGUqKiBidXR0b24gdG8gc2VlIHRoZSBzdGVwcy4KCjxidXR0b24gY2xhc3M9ImJ0biBidG4tcHJpbWFyeSIgZGF0YS10b2dnbGU9ImNvbGxhcHNlIiBkYXRhLXRhcmdldD0iI0Jsb2NrTmFtZTE0Ij4gU2hvdy9IaWRlIDwvYnV0dG9uPiAgCjxkaXYgaWQ9IkJsb2NrTmFtZTE0IiBjbGFzcz0iY29sbGFwc2UiPgpgYGB7cn0KIyBTdWJzZXQgZGF0YSBmcm9tIHRoZSBmdWxsIHRwbV9leHByZXNzZWQgZGF0YXNldAp0dXNzX1QyNHZzVDA8LXRwbV90dXNzX2V4cHJlc3NlZFssYygyOjMsNjoxNCldCgojIEFnZ3JlZ2F0ZSAoc3VtKSBnZW5lY2FsbCBJRCBjb3VudHMgYnkgc2hhcmVkIEtPIGFuZCBUYXhvbm9teSB0byByZWR1Y2UgZHVwbGljYXRlcyBpbiB0aGUgZGF0YXNldCBhbmQgaW1wcm92ZSB0aGUgREUgYW5hbHlzaXMgcmVzdWx0cyB0byBiZSBiaW9sb2dpY2FsbHkgcmVsZXZhbnQuCnR1c3NfVDI0dnNUMDwtYWdncmVnYXRlKC4gfiBLTyArIFN5bWJvbCArIEZ1bmN0aW9uICsgVGllcl9JSSArIFRpZXJfSUlJICsgVGllcl9JViArIFRheG9ub215LCBkYXRhPXR1c3NfVDI0dnNUMCwgRlVOPXN1bSkKCiMjIFJlYWRpbmcgaW4gdGhlIGRhdGEKIyBDcmVhdGUgREdFTGlzdCBmb3IgVHVzcyBUMjQgdnMgVDAgc3ViZGF0YQp0dXNzX1QyNHZzVDA8LURHRUxpc3QoY291bnRzPXR1c3NfVDI0dnNUMFssODoxMV0sIGdlbmVzPXR1c3NfVDI0dnNUMFssMTo3XSkKcm93bmFtZXModHVzc19UMjR2c1QwJGNvdW50cyk8LXJvd25hbWVzKHR1c3NfVDI0dnNUMCRnZW5lcyk8LXR1c3NfVDI0dnNUMCRnZW5lcyRJRAp0dXNzX1QyNHZzVDAkZ2VuZXMkSUQ8LU5VTEwKCiMjIE5vcm1hbGl6YXRpb24KIyBUZWxsIGVkZ2VSIHRoYXQgeW91IGRvbid0IHdhbnQgdG8gbm9ybWFsaXplIHRoZSBzdWJkYXRhIChhbHJlYWR5IFRQTSBub3JtYWxpemVkKQp0dXNzX1QyNHZzVDA8LWNhbGNOb3JtRmFjdG9ycyh0dXNzX1QyNHZzVDAsIG1ldGhvZD0ibm9uZSIpCnR1c3NfVDI0dnNUMCRzYW1wbGVzCgojIyBEYXRhIEV4cGxvcmF0aW9uCiMgVGhlIHBsb3RNRFMgZnVuY3Rpb24gcHJvZHVjZXMgYSBwbG90IGluIHdoaWNoIGRpc3RhbmNlcyBiZXR3ZWVuIHNhbXBsZXMgY29ycmVzcG9uZCB0byBsZWFkaW5nIGJpb2xvZ2ljYWwgY29lZmZpY2llbnQgb2YgdmFyaWF0aW9uIChCQ1YpIGJldHdlZW4gdGhvc2Ugc2FtcGxlcwpwbG90TURTKHR1c3NfVDI0dnNUMCwgY29sPXJlcCgxOjIsIGVhY2g9MikpCgojIyBUaGUgRGVzaWduIE1hdHJpeAojIEJlZm9yZSB3ZSBmaXQgbmVnYXRpdmUgYmlub21pYWwgR0xNcywgd2UgbmVlZCB0byBkZWZpbmUgb3VyIGRlc2lnbiBtYXRyaXggYmFzZWQgb24gdGhlIGV4cGVyaW1lbnRhbCBkZXNpZ24uIEhlcmUsIHdlIHdhbnQgdG8gdGVzdCBmb3IgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYmV0d2VlbiBUNCBhbmQgVDAgdGltZXBvaW50cyB3aXRoaW4gbWVzb2Nvc21zLCBpLmUuLCBhZGp1c3RpbmcgZm9yIGRpZmZlcmVuY2VzIGJldHdlZW4gbWVzb2Nvc21zLiBJbiBzdGF0aXN0aWNzLCB0aGlzIGlzIGFuIGFkZGl0aXZlIGxpbmVhciBtb2RlbCB3aXRoIG1lc29jb3NtIGFzIHRoZSBibG9ja2luZyBmYWN0b3IuCk1lc29jb3NtX3R1c3NfVDI0dnNUMDwtZmFjdG9yKGMoMSwyLDEsMikpClRpbWVwb2ludF90dXNzX1QyNHZzVDA8LWZhY3RvcihjKCJUMCIsIlQwIiwiVDI0IiwiVDI0IikpCmRhdGEuZnJhbWUoU2FtcGxlX3R1c3NfVDI0dnNUMD1jb2xuYW1lcyh0dXNzX1QyNHZzVDApLE1lc29jb3NtX3R1c3NfVDI0dnNUMCxUaW1lcG9pbnRfdHVzc19UMjR2c1QwKQp0dXNzX1QyNHZzVDBfZGVzaWduPC1tb2RlbC5tYXRyaXgofk1lc29jb3NtX3R1c3NfVDI0dnNUMCtUaW1lcG9pbnRfdHVzc19UMjR2c1QwKQpyb3duYW1lcyh0dXNzX1QyNHZzVDBfZGVzaWduKTwtY29sbmFtZXModHVzc19UMjR2c1QwKQp0dXNzX1QyNHZzVDBfZGVzaWduCgojIyBFc3RpbWF0aW5nIERpc3BlcnNpb24KIyBXZSBlc3RpbWF0ZSB0aGUgTkIgZGlzcGVyc2lvbiBmb3IgdGhlIGRhdGFzZXQKdHVzc19UMjR2c1QwPC1lc3RpbWF0ZURpc3AodHVzc19UMjR2c1QwLHR1c3NfVDI0dnNUMF9kZXNpZ24scm9idXN0PVRSVUUpCnR1c3NfVDI0dnNUMCRjb21tb24uZGlzcGVyc2lvbgoKIyBUaGUgc3F1YXJlIHJvb3Qgb2YgdGhlIGNvbW1vbiBkaXNwZXJzaW9uIGdpdmVzIHRoZSBjb2VmZmljaWVudCBvZiB2YXJpYXRpb24gb2YgYmlvbG9naWNhbCB2YXJpYXRpb24uCnNxcnQodHVzc19UMjR2c1QwJGNvbW1vbi5kaXNwZXJzaW9uKQoKIyBWaWV3IHRoZSBkaXNwZXJzaW9uIGVzdGltYXRlcyBpbiBhIEJDViBwbG90CnBsb3RCQ1YodHVzc19UMjR2c1QwKQoKIyMgRGlmZmVyZW50aWFsIEV4cHJlc3Npb24KIyBOb3cgd2UgcHJvY2VlZCB0byBkZXRlcm1pbmUgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIGJ5IGZpdHRpbmcgZ2VuZXdpc2UgZ2xtcwp0dXNzX1QyNHZzVDBfZml0PC1nbG1GaXQodHVzc19UMjR2c1QwLHR1c3NfVDI0dnNUMF9kZXNpZ24pCgojIENvbmR1Y3QgbGlrZWxpaG9vZCByYXRpbyB0ZXN0cyBmb3IgVDQgdnMgVDAgZGlmZmVyZW5jZXMgYW5kIHNob3cgdGhlIHRvcCBnZW5lcy4gVGhlIGdlbmV3aXNlIHRlc3RzIGFyZSBmb3IgVDQgdnMgVDAgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24sIGFkanVzdGluZyBmb3IgYmFzZWxpbmUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgdHdvIG1lc29jb3Ntcy4gIFRoZSB0ZXN0cyBjYW4gYmUgdmlld2VkIGFzIGFuYWxvZ291cyB0byBwYWlyZWQgdC10ZXN0cy4gVGhlIHRvcCBERSB0YWdzIGhhdmUgdGlueSBwLXZhbHVlcyBhbmQgRkRSIHZhbHVlcywgYXMgd2VsbCBhcyBsYXJnZSBmb2xkIGNoYW5nZXMuCnR1c3NfVDI0dnNUMF9scnQ8LWdsbUxSVCh0dXNzX1QyNHZzVDBfZml0KQp0b3BUYWdzKHR1c3NfVDI0dnNUMF9scnQsbj0yNSkKCiMjIEhlcmUncyB0aGUgVFBNLW5vcm1hbGl6ZWQgdmFsdWVzIGluIGluZGl2aWR1YWwgc2FtcGxlcy4KIyBXZSBzZWUgdGhhdCBhbGwgdGhlIGdlbmVzIGhhdmUgY29uc2lzdGVudCBjaGFuZ2VzIGJldHdlZW4gcmVwbGljYXRlcyB3aXRoaW4gZWFjaCB0aW1lcG9pbnQuCnR1c3NfVDI0dnNUMF9wdmFsdWU8LW9yZGVyKHR1c3NfVDI0dnNUMF9scnQkdGFibGUkUFZhbHVlKQpjcG0odHVzc19UMjR2c1QwKVt0dXNzX1QyNHZzVDBfcHZhbHVlWzE6MjVdLF0KYGBgCjwvZGl2PgoKUGxvdHRpbmcgc2lnbmlmaWNhbnQgS09zIGluIERHRSBhbmFseXNpcy4KYGBge3J9CiMgVGhlIHRvdGFsIG51bWJlciBvZiBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgYXQgNSUgRkRSIGlzIGdpdmVuIGJ5Ogp0dXNzX1QyNHZzVDBfRkRSPC1wLmFkanVzdCh0dXNzX1QyNHZzVDBfbHJ0JHRhYmxlJFBWYWx1ZSwgbWV0aG9kPSJCSCIpCnN1bSh0dXNzX1QyNHZzVDBfRkRSPDAuMDUpCnN1bW1hcnkoZGVjaWRlVGVzdHModHVzc19UMjR2c1QwX2xydCkpCgojIFBsb3QgdGhlIGxvZy1mb2xkIGNoYW5nZSBhZ2FpbnN0IGxvZy10cmFuc2NyaXB0cyBwZXIgbWlsbGlvbiwgd2l0aCBERSBnZW5lcyBoaWdobGlnaHRlZC4KdHVzc19UMjR2c1QwX01EcGxvdDwtcGxvdE1EKHR1c3NfVDI0dnNUMF9scnQsIGhsLmNvbD1jKCJkYXJrZ3JlZW4iLCJwYWxlZ3JlZW4xIiksIG1haW4gPSBOVUxMLCB4bGFiPSJBdmVyYWdlIGxvZyBUUE0iKSArIGFibGluZShoPTAsY29sPSJncmF5IiwgbHR5PSJkYXNoZWQiKQp0dXNzX1QyNHZzVDBfTURwbG90CmBgYAoKYGBge3IgZWNobz1GQUxTRX0KIyBXcml0ZSB0aGUgdG9wVGFncyByZXN1bHRzIHRvIC5jc3YgdGFibGUKdHVzc19UMjR2c1QwX3Jlc3VsdHMgPC0gYXMuZGF0YS5mcmFtZSh0b3BUYWdzKHR1c3NfVDI0dnNUMF9scnQsbiA9IEluZikpCndyaXRlLmNzdih0dXNzX1QyNHZzVDBfcmVzdWx0cywiREUuUmVzdWx0cy90dXNzX1QyNHZzVDBfcmVzdWx0cy5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkKYGBgCgojIyMjIyA3LjQuMi40LiBXUyBUNHZzVDAKClN0YXJ0IGJ5IGFuYWx5c2luZyBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgaW4gdGhlIFdldCBTZWRnZSBkYXRhc2V0IGJldHdlZW4gdGltZXBvaW50cyBUNCAob3hpYyByZWRveCkgYW5kIFQwIChhbm94aWMgcmVkb3gpLiBDbGljayBvbiB0aGUgKipTaG93L0hpZGUqKiBidXR0b24gdG8gc2VlIHRoZSBzdGVwcy4KCjxidXR0b24gY2xhc3M9ImJ0biBidG4tcHJpbWFyeSIgZGF0YS10b2dnbGU9ImNvbGxhcHNlIiBkYXRhLXRhcmdldD0iI0Jsb2NrTmFtZTE1Ij4gU2hvdy9IaWRlIDwvYnV0dG9uPiAgCjxkaXYgaWQ9IkJsb2NrTmFtZTE1IiBjbGFzcz0iY29sbGFwc2UiPgpgYGB7cn0KIyBTdWJzZXQgZGF0YSBmcm9tIHRoZSBmdWxsIHRwbV9leHByZXNzZWQgZGF0YXNldAp3c19UNHZzVDA8LXRwbV93c19leHByZXNzZWRbLGMoMjo1LDg6MTQpXQoKIyBBZ2dyZWdhdGUgKHN1bSkgZ2VuZWNhbGwgSUQgY291bnRzIGJ5IHNoYXJlZCBLTyBhbmQgVGF4b25vbXkgdG8gcmVkdWNlIGR1cGxpY2F0ZXMgaW4gdGhlIGRhdGFzZXQgYW5kIGltcHJvdmUgdGhlIERFIGFuYWx5c2lzIHJlc3VsdHMgdG8gYmUgYmlvbG9naWNhbGx5IHJlbGV2YW50Lgp3c19UNHZzVDA8LWFnZ3JlZ2F0ZSguIH4gS08gKyBTeW1ib2wgKyBGdW5jdGlvbiArIFRpZXJfSUkgKyBUaWVyX0lJSSArIFRpZXJfSVYgKyBUYXhvbm9teSwgZGF0YT13c19UNHZzVDAsIEZVTj1zdW0pCgojIyBSZWFkaW5nIGluIHRoZSBkYXRhCiMgQ3JlYXRlIERHRUxpc3QgZm9yIFdTIFQ0IHZzIFQwIHN1YmRhdGEKd3NfVDR2c1QwPC1ER0VMaXN0KGNvdW50cz13c19UNHZzVDBbLDg6MTFdLCBnZW5lcz13c19UNHZzVDBbLDE6N10pCnJvd25hbWVzKHdzX1Q0dnNUMCRjb3VudHMpPC1yb3duYW1lcyh3c19UNHZzVDAkZ2VuZXMpPC13c19UNHZzVDAkZ2VuZXMkSUQKd3NfVDR2c1QwJGdlbmVzJElEPC1OVUxMCgojIyBOb3JtYWxpemF0aW9uCiMgVGVsbCBlZGdlUiB0aGF0IHlvdSBkb24ndCB3YW50IHRvIG5vcm1hbGl6ZSB0aGUgc3ViZGF0YSAoYWxyZWFkeSBUUE0gbm9ybWFsaXplZCkKd3NfVDR2c1QwPC1jYWxjTm9ybUZhY3RvcnMod3NfVDR2c1QwLCBtZXRob2Q9Im5vbmUiKQp3c19UNHZzVDAkc2FtcGxlcwoKIyMgRGF0YSBFeHBsb3JhdGlvbgojIFRoZSBwbG90TURTIGZ1bmN0aW9uIHByb2R1Y2VzIGEgcGxvdCBpbiB3aGljaCBkaXN0YW5jZXMgYmV0d2VlbiBzYW1wbGVzIGNvcnJlc3BvbmQgdG8gbGVhZGluZyBiaW9sb2dpY2FsIGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbiAoQkNWKSBiZXR3ZWVuIHRob3NlIHNhbXBsZXMKcGxvdE1EUyh3c19UNHZzVDAsIGNvbD1yZXAoMToyLCBlYWNoPTIpKQoKIyMgVGhlIERlc2lnbiBNYXRyaXgKIyBCZWZvcmUgd2UgZml0IG5lZ2F0aXZlIGJpbm9taWFsIEdMTXMsIHdlIG5lZWQgdG8gZGVmaW5lIG91ciBkZXNpZ24gbWF0cml4IGJhc2VkIG9uIHRoZSBleHBlcmltZW50YWwgZGVzaWduLiBIZXJlLCB3ZSB3YW50IHRvIHRlc3QgZm9yIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGJldHdlZW4gVDQgYW5kIFQwIHRpbWVwb2ludHMgd2l0aGluIG1lc29jb3NtcywgaS5lLiwgYWRqdXN0aW5nIGZvciBkaWZmZXJlbmNlcyBiZXR3ZWVuIG1lc29jb3Ntcy4gSW4gc3RhdGlzdGljcywgdGhpcyBpcyBhbiBhZGRpdGl2ZSBsaW5lYXIgbW9kZWwgd2l0aCBtZXNvY29zbSBhcyB0aGUgYmxvY2tpbmcgZmFjdG9yLgpNZXNvY29zbV93c19UNHZzVDA8LWZhY3RvcihjKDEsMiwxLDIpKQpUaW1lcG9pbnRfd3NfVDR2c1QwPC1mYWN0b3IoYygiVDAiLCJUMCIsIlQ0IiwiVDQiKSkKZGF0YS5mcmFtZShTYW1wbGVfd3NfVDR2c1QwPWNvbG5hbWVzKHdzX1Q0dnNUMCksTWVzb2Nvc21fd3NfVDR2c1QwLFRpbWVwb2ludF93c19UNHZzVDApCndzX1Q0dnNUMF9kZXNpZ248LW1vZGVsLm1hdHJpeCh+TWVzb2Nvc21fd3NfVDR2c1QwK1RpbWVwb2ludF93c19UNHZzVDApCnJvd25hbWVzKHdzX1Q0dnNUMF9kZXNpZ24pPC1jb2xuYW1lcyh3c19UNHZzVDApCndzX1Q0dnNUMF9kZXNpZ24KCiMjIEVzdGltYXRpbmcgRGlzcGVyc2lvbgojIFdlIGVzdGltYXRlIHRoZSBOQiBkaXNwZXJzaW9uIGZvciB0aGUgZGF0YXNldAp3c19UNHZzVDA8LWVzdGltYXRlRGlzcCh3c19UNHZzVDAsd3NfVDR2c1QwX2Rlc2lnbixyb2J1c3Q9VFJVRSkKd3NfVDR2c1QwJGNvbW1vbi5kaXNwZXJzaW9uCgojIFRoZSBzcXVhcmUgcm9vdCBvZiB0aGUgY29tbW9uIGRpc3BlcnNpb24gZ2l2ZXMgdGhlIGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbiBvZiBiaW9sb2dpY2FsIHZhcmlhdGlvbi4Kc3FydCh3c19UNHZzVDAkY29tbW9uLmRpc3BlcnNpb24pCgojIFZpZXcgdGhlIGRpc3BlcnNpb24gZXN0aW1hdGVzIGluIGEgQkNWIHBsb3QKcGxvdEJDVih3c19UNHZzVDApCgojIyBEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbgojIE5vdyB3ZSBwcm9jZWVkIHRvIGRldGVybWluZSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgYnkgZml0dGluZyBnZW5ld2lzZSBnbG1zCndzX1Q0dnNUMF9maXQ8LWdsbUZpdCh3c19UNHZzVDAsd3NfVDR2c1QwX2Rlc2lnbikKCiMgQ29uZHVjdCBsaWtlbGlob29kIHJhdGlvIHRlc3RzIGZvciBUNCB2cyBUMCBkaWZmZXJlbmNlcyBhbmQgc2hvdyB0aGUgdG9wIGdlbmVzLiBUaGUgZ2VuZXdpc2UgdGVzdHMgYXJlIGZvciBUNCB2cyBUMCBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiwgYWRqdXN0aW5nIGZvciBiYXNlbGluZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSB0d28gbWVzb2Nvc21zLiAgVGhlIHRlc3RzIGNhbiBiZSB2aWV3ZWQgYXMgYW5hbG9nb3VzIHRvIHBhaXJlZCB0LXRlc3RzLiBUaGUgdG9wIERFIHRhZ3MgaGF2ZSB0aW55IHAtdmFsdWVzIGFuZCBGRFIgdmFsdWVzLCBhcyB3ZWxsIGFzIGxhcmdlIGZvbGQgY2hhbmdlcy4Kd3NfVDR2c1QwX2xydDwtZ2xtTFJUKHdzX1Q0dnNUMF9maXQpCndzX1Q0dnNUMF90b3BUYWdzPC10b3BUYWdzKHdzX1Q0dnNUMF9scnQsbj0yNSkKd3NfVDR2c1QwX3RvcFRhZ3MKCiMjIEhlcmUncyB0aGUgVFBNLW5vcm1hbGl6ZWQgdmFsdWVzIGluIGluZGl2aWR1YWwgc2FtcGxlcy4KIyBXZSBzZWUgdGhhdCBhbGwgdGhlIHNpZ25pZmljYW50IGdlbmVzIGhhdmUgY29uc2lzdGVudCBUNCB2cyBUMCBjaGFuZ2VzIGZvciB0aGUgdHdvIG1lc29jb3Ntcy4Kd3NfVDR2c1QwX3B2YWx1ZTwtb3JkZXIod3NfVDR2c1QwX2xydCR0YWJsZSRQVmFsdWUpCndzX1Q0dnNUMF9jcG08LWNwbSh3c19UNHZzVDApW3dzX1Q0dnNUMF9wdmFsdWVbMToyNV0sXQp3c19UNHZzVDBfY3BtCmBgYAo8L2Rpdj4KClBsb3R0aW5nIHNpZ25pZmljYW50IEtPcyBpbiBER0UgYW5hbHlzaXMuCmBgYHtyfQojIFRoZSB0b3RhbCBudW1iZXIgb2YgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIGF0IDUlIEZEUiBpcyBnaXZlbiBieToKd3NfVDR2c1QwX0ZEUjwtcC5hZGp1c3Qod3NfVDR2c1QwX2xydCR0YWJsZSRQVmFsdWUsIG1ldGhvZD0iQkgiKQpzdW0od3NfVDR2c1QwX0ZEUjwwLjA1KQpzdW1tYXJ5KGRlY2lkZVRlc3RzKHdzX1Q0dnNUMF9scnQpKQoKIyBQbG90IHRoZSBsb2ctZm9sZCBjaGFuZ2UgYWdhaW5zdCBsb2ctdHJhbnNjcmlwdHMgcGVyIG1pbGxpb24sIHdpdGggREUgZ2VuZXMgaGlnaGxpZ2h0ZWQuCndzX1Q0dnNUMF9NRHBsb3Q8LXBsb3RNRCh3c19UNHZzVDBfbHJ0LCBobC5jb2w9YygiZG9kZ2VyYmx1ZTEiLCJsaWdodHNreWJsdWUxIiksIG1haW4gPSBOVUxMLCB4bGFiPSJBdmVyYWdlIGxvZyBUUE0iKSArIGFibGluZShoPTAsY29sPSJncmF5IiwgbHR5PSJkYXNoZWQiKQp3c19UNHZzVDBfTURwbG90CmBgYAoKYGBge3IgZWNobz1GQUxTRX0KIyBXcml0ZSB0aGUgdG9wVGFncyByZXN1bHRzIHRvIC5jc3YgdGFibGUKd3NfVDR2c1QwX3Jlc3VsdHMgPC0gYXMuZGF0YS5mcmFtZSh0b3BUYWdzKHdzX1Q0dnNUMF9scnQsbiA9IEluZikpCndyaXRlLmNzdih3c19UNHZzVDBfcmVzdWx0cywiREUuUmVzdWx0cy93c19UNHZzVDBfcmVzdWx0cy5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkKYGBgCgojIyMjIyA3LjQuMi41LiBXUyBUMjR2c1Q0CgpOb3cgYW5hbHl6ZSB0aGUgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIGluIHRoZSBXZXQgU2VkZ2UgZGF0YXNldCBiZXR3ZWVuIHRpbWVwb2ludHMgVDI0IChtaXhlZCByZWRveCkgYW5kIFQ0IChveGljIHJlZG94KS4gQ2xpY2sgb24gdGhlICoqU2hvdy9IaWRlKiogYnV0dG9uIHRvIHNlZSB0aGUgc3RlcHMuCgo8YnV0dG9uIGNsYXNzPSJidG4gYnRuLXByaW1hcnkiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgZGF0YS10YXJnZXQ9IiNCbG9ja05hbWUxNiI+IFNob3cvSGlkZSA8L2J1dHRvbj4gIAo8ZGl2IGlkPSJCbG9ja05hbWUxNiIgY2xhc3M9ImNvbGxhcHNlIj4KYGBge3J9CiMgU3Vic2V0IGRhdGEgZnJvbSB0aGUgZnVsbCB0cG1fZXhwcmVzc2VkIGRhdGFzZXQKd3NfVDI0dnNUNDwtdHBtX3dzX2V4cHJlc3NlZFssYyg0OjcsODoxNCldCgojIEFnZ3JlZ2F0ZSAoc3VtKSBnZW5lY2FsbCBJRCBjb3VudHMgYnkgc2hhcmVkIEtPIGFuZCBUYXhvbm9teSB0byByZWR1Y2UgZHVwbGljYXRlcyBpbiB0aGUgZGF0YXNldCBhbmQgaW1wcm92ZSB0aGUgREUgYW5hbHlzaXMgcmVzdWx0cyB0byBiZSBiaW9sb2dpY2FsbHkgcmVsZXZhbnQuCndzX1QyNHZzVDQ8LWFnZ3JlZ2F0ZSguIH4gS08gKyBTeW1ib2wgKyBGdW5jdGlvbiArIFRpZXJfSUkgKyBUaWVyX0lJSSArIFRpZXJfSVYgKyBUYXhvbm9teSwgZGF0YT13c19UMjR2c1Q0LCBGVU49c3VtKQoKIyMgUmVhZGluZyBpbiB0aGUgZGF0YQojIENyZWF0ZSBER0VMaXN0IGZvciBXUyBUMjQgdnMgVDQgc3ViZGF0YQp3c19UMjR2c1Q0PC1ER0VMaXN0KGNvdW50cz13c19UMjR2c1Q0Wyw4OjExXSwgZ2VuZXM9d3NfVDI0dnNUNFssMTo3XSkKcm93bmFtZXMod3NfVDI0dnNUNCRjb3VudHMpPC1yb3duYW1lcyh3c19UMjR2c1Q0JGdlbmVzKTwtd3NfVDI0dnNUNCRnZW5lcyRJRAp3c19UMjR2c1Q0JGdlbmVzJElEPC1OVUxMCgojIyBOb3JtYWxpemF0aW9uCiMgVGVsbCBlZGdlUiB0aGF0IHlvdSBkb24ndCB3YW50IHRvIG5vcm1hbGl6ZSB0aGUgc3ViZGF0YSAoYWxyZWFkeSBUUE0gbm9ybWFsaXplZCkKd3NfVDI0dnNUNDwtY2FsY05vcm1GYWN0b3JzKHdzX1QyNHZzVDQsIG1ldGhvZD0ibm9uZSIpCndzX1QyNHZzVDQkc2FtcGxlcwoKIyMgRGF0YSBFeHBsb3JhdGlvbgojIFRoZSBwbG90TURTIGZ1bmN0aW9uIHByb2R1Y2VzIGEgcGxvdCBpbiB3aGljaCBkaXN0YW5jZXMgYmV0d2VlbiBzYW1wbGVzIGNvcnJlc3BvbmQgdG8gbGVhZGluZyBiaW9sb2dpY2FsIGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbiAoQkNWKSBiZXR3ZWVuIHRob3NlIHNhbXBsZXMKcGxvdE1EUyh3c19UMjR2c1Q0LCBjb2w9cmVwKDE6MiwgZWFjaD0yKSkKCiMjIFRoZSBEZXNpZ24gTWF0cml4CiMgQmVmb3JlIHdlIGZpdCBuZWdhdGl2ZSBiaW5vbWlhbCBHTE1zLCB3ZSBuZWVkIHRvIGRlZmluZSBvdXIgZGVzaWduIG1hdHJpeCBiYXNlZCBvbiB0aGUgZXhwZXJpbWVudGFsIGRlc2lnbi4gSGVyZSwgd2Ugd2FudCB0byB0ZXN0IGZvciBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBiZXR3ZWVuIFQ0IGFuZCBUMCB0aW1lcG9pbnRzIHdpdGhpbiBtZXNvY29zbXMsIGkuZS4sIGFkanVzdGluZyBmb3IgZGlmZmVyZW5jZXMgYmV0d2VlbiBtZXNvY29zbXMuIEluIHN0YXRpc3RpY3MsIHRoaXMgaXMgYW4gYWRkaXRpdmUgbGluZWFyIG1vZGVsIHdpdGggbWVzb2Nvc20gYXMgdGhlIGJsb2NraW5nIGZhY3Rvci4KTWVzb2Nvc21fd3NfVDI0dnNUNDwtZmFjdG9yKGMoMSwyLDEsMikpClRpbWVwb2ludF93c19UMjR2c1Q0PC1mYWN0b3IoYygiVDQiLCJUNCIsIlQyNCIsIlQyNCIpKQpkYXRhLmZyYW1lKFNhbXBsZV93c19UMjR2c1Q0PWNvbG5hbWVzKHdzX1QyNHZzVDQpLE1lc29jb3NtX3dzX1QyNHZzVDQsVGltZXBvaW50X3dzX1QyNHZzVDQpCndzX1QyNHZzVDRfZGVzaWduPC1tb2RlbC5tYXRyaXgofk1lc29jb3NtX3dzX1QyNHZzVDQrVGltZXBvaW50X3dzX1QyNHZzVDQpCnJvd25hbWVzKHdzX1QyNHZzVDRfZGVzaWduKTwtY29sbmFtZXMod3NfVDI0dnNUNCkKd3NfVDI0dnNUNF9kZXNpZ24KCiMjIEVzdGltYXRpbmcgRGlzcGVyc2lvbgojIFdlIGVzdGltYXRlIHRoZSBOQiBkaXNwZXJzaW9uIGZvciB0aGUgZGF0YXNldAp3c19UMjR2c1Q0PC1lc3RpbWF0ZURpc3Aod3NfVDI0dnNUNCx3c19UMjR2c1Q0X2Rlc2lnbixyb2J1c3Q9VFJVRSkKd3NfVDI0dnNUNCRjb21tb24uZGlzcGVyc2lvbgoKIyBUaGUgc3F1YXJlIHJvb3Qgb2YgdGhlIGNvbW1vbiBkaXNwZXJzaW9uIGdpdmVzIHRoZSBjb2VmZmljaWVudCBvZiB2YXJpYXRpb24gb2YgYmlvbG9naWNhbCB2YXJpYXRpb24uCnNxcnQod3NfVDI0dnNUNCRjb21tb24uZGlzcGVyc2lvbikKCiMgVmlldyB0aGUgZGlzcGVyc2lvbiBlc3RpbWF0ZXMgaW4gYSBCQ1YgcGxvdApwbG90QkNWKHdzX1QyNHZzVDQpCgojIyBEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbgojIE5vdyB3ZSBwcm9jZWVkIHRvIGRldGVybWluZSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgYnkgZml0dGluZyBnZW5ld2lzZSBnbG1zCndzX1QyNHZzVDRfZml0PC1nbG1GaXQod3NfVDI0dnNUNCx3c19UMjR2c1Q0X2Rlc2lnbikKCiMgQ29uZHVjdCBsaWtlbGlob29kIHJhdGlvIHRlc3RzIGZvciBUNCB2cyBUMCBkaWZmZXJlbmNlcyBhbmQgc2hvdyB0aGUgdG9wIGdlbmVzLiBUaGUgZ2VuZXdpc2UgdGVzdHMgYXJlIGZvciBUNCB2cyBUMCBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiwgYWRqdXN0aW5nIGZvciBiYXNlbGluZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSB0d28gbWVzb2Nvc21zLiAgVGhlIHRlc3RzIGNhbiBiZSB2aWV3ZWQgYXMgYW5hbG9nb3VzIHRvIHBhaXJlZCB0LXRlc3RzLiBUaGUgdG9wIERFIHRhZ3MgaGF2ZSB0aW55IHAtdmFsdWVzIGFuZCBGRFIgdmFsdWVzLCBhcyB3ZWxsIGFzIGxhcmdlIGZvbGQgY2hhbmdlcy4Kd3NfVDI0dnNUNF9scnQ8LWdsbUxSVCh3c19UMjR2c1Q0X2ZpdCkKd3NfVDI0dnNUNF90b3BUYWdzPC10b3BUYWdzKHdzX1QyNHZzVDRfbHJ0LG49MjUpCndzX1QyNHZzVDRfdG9wVGFncwoKIyMgSGVyZSdzIHRoZSBUUE0tbm9ybWFsaXplZCB2YWx1ZXMgaW4gaW5kaXZpZHVhbCBzYW1wbGVzLgojIFdlIHNlZSB0aGF0IGFsbCB0aGUgZ2VuZXMgaGF2ZSBjb25zaXN0ZW50IGNoYW5nZXMgYmV0d2VlbiByZXBsaWNhdGVzIHdpdGhpbiBlYWNoIHRpbWVwb2ludC4Kd3NfVDI0dnNUNF9wdmFsdWU8LW9yZGVyKHdzX1QyNHZzVDRfbHJ0JHRhYmxlJFBWYWx1ZSkKd3NfVDI0dnNUNF9jcG08LWNwbSh3c19UMjR2c1Q0KVt3c19UMjR2c1Q0X3B2YWx1ZVsxOjI1XSxdCndzX1QyNHZzVDRfY3BtCmBgYAo8L2Rpdj4KClBsb3R0aW5nIHNpZ25pZmljYW50IEtPcyBpbiBER0UgYW5hbHlzaXMuCmBgYHtyfQojIFRoZSB0b3RhbCBudW1iZXIgb2YgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIGF0IDUlIEZEUiBpcyBnaXZlbiBieToKd3NfVDI0dnNUNF9GRFI8LXAuYWRqdXN0KHdzX1QyNHZzVDRfbHJ0JHRhYmxlJFBWYWx1ZSwgbWV0aG9kPSJCSCIpCnN1bSh3c19UMjR2c1Q0X0ZEUjwwLjA1KQpzdW1tYXJ5KGRlY2lkZVRlc3RzKHdzX1QyNHZzVDRfbHJ0KSkKCiMgUGxvdCB0aGUgbG9nLWZvbGQgY2hhbmdlIGFnYWluc3QgbG9nLXRyYW5zY3JpcHRzIHBlciBtaWxsaW9uLCB3aXRoIERFIGdlbmVzIGhpZ2hsaWdodGVkLgp3c19UMjR2c1Q0X01EcGxvdDwtcGxvdE1EKHdzX1QyNHZzVDRfbHJ0LCBobC5jb2w9YygibWlkbmlnaHRibHVlIiwiZG9kZ2VyYmx1ZTEiKSwgbWFpbiA9IE5VTEwsIHhsYWI9IkF2ZXJhZ2UgbG9nIFRQTSIpICsgYWJsaW5lKGg9MCxjb2w9ImdyYXkiLCBsdHk9ImRhc2hlZCIpCndzX1QyNHZzVDRfTURwbG90CmBgYAoKYGBge3IgZWNobz1GQUxTRX0KIyBXcml0ZSB0aGUgdG9wVGFncyByZXN1bHRzIHRvIC5jc3YgdGFibGUKd3NfVDI0dnNUNF9yZXN1bHRzIDwtIGFzLmRhdGEuZnJhbWUodG9wVGFncyh3c19UMjR2c1Q0X2xydCxuID0gSW5mKSkKd3JpdGUuY3N2KHdzX1QyNHZzVDRfcmVzdWx0cywiREUuUmVzdWx0cy93c19UMjR2c1Q0X3Jlc3VsdHMuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoKIyMjIyMgNy40LjIuNi4gV1MgVDI0dnNUMAoKRmluYWxseSwgYW5hbHl6ZSB0aGUgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzIGluIHRoZSBXZXQgU2VkZ2UgZGF0YXNldCBiZXR3ZWVuIHRpbWVwb2ludHMgVDI0IChtaXhlZCByZWRveCkgYW5kIFQwIChhbm94aWMgcmVkb3gpLiBDbGljayBvbiB0aGUgKipTaG93L0hpZGUqKiBidXR0b24gdG8gc2VlIHRoZSBzdGVwcy4KCjxidXR0b24gY2xhc3M9ImJ0biBidG4tcHJpbWFyeSIgZGF0YS10b2dnbGU9ImNvbGxhcHNlIiBkYXRhLXRhcmdldD0iI0Jsb2NrTmFtZTE3Ij4gU2hvdy9IaWRlIDwvYnV0dG9uPiAgCjxkaXYgaWQ9IkJsb2NrTmFtZTE3IiBjbGFzcz0iY29sbGFwc2UiPgpgYGB7cn0KIyBTdWJzZXQgZGF0YSBmcm9tIHRoZSBmdWxsIHRwbV9leHByZXNzZWQgZGF0YXNldAp3c19UMjR2c1QwPC10cG1fd3NfZXhwcmVzc2VkWyxjKDI6Myw2OjE0KV0KCiMgQWdncmVnYXRlIChzdW0pIGdlbmVjYWxsIElEIGNvdW50cyBieSBzaGFyZWQgS08gYW5kIFRheG9ub215IHRvIHJlZHVjZSBkdXBsaWNhdGVzIGluIHRoZSBkYXRhc2V0IGFuZCBpbXByb3ZlIHRoZSBERSBhbmFseXNpcyByZXN1bHRzIHRvIGJlIGJpb2xvZ2ljYWxseSByZWxldmFudC4Kd3NfVDI0dnNUMDwtYWdncmVnYXRlKC4gfiBLTyArIFN5bWJvbCArIEZ1bmN0aW9uICsgVGllcl9JSSArIFRpZXJfSUlJICsgVGllcl9JViArIFRheG9ub215LCBkYXRhPXdzX1QyNHZzVDAsIEZVTj1zdW0pCgojIyBSZWFkaW5nIGluIHRoZSBkYXRhCiMgQ3JlYXRlIERHRUxpc3QgZm9yIFdTIFQyNCB2cyBUMCBzdWJkYXRhCndzX1QyNHZzVDA8LURHRUxpc3QoY291bnRzPXdzX1QyNHZzVDBbLDg6MTFdLCBnZW5lcz13c19UMjR2c1QwWywxOjddKQpyb3duYW1lcyh3c19UMjR2c1QwJGNvdW50cyk8LXJvd25hbWVzKHdzX1QyNHZzVDAkZ2VuZXMpPC13c19UMjR2c1QwJGdlbmVzJElECndzX1QyNHZzVDAkZ2VuZXMkSUQ8LU5VTEwKCiMjIE5vcm1hbGl6YXRpb24KIyBUZWxsIGVkZ2VSIHRoYXQgeW91IGRvbid0IHdhbnQgdG8gbm9ybWFsaXplIHRoZSBzdWJkYXRhIChhbHJlYWR5IFRQTSBub3JtYWxpemVkKQp3c19UMjR2c1QwPC1jYWxjTm9ybUZhY3RvcnMod3NfVDI0dnNUMCwgbWV0aG9kPSJub25lIikKd3NfVDI0dnNUMCRzYW1wbGVzCgojIyBEYXRhIEV4cGxvcmF0aW9uCiMgVGhlIHBsb3RNRFMgZnVuY3Rpb24gcHJvZHVjZXMgYSBwbG90IGluIHdoaWNoIGRpc3RhbmNlcyBiZXR3ZWVuIHNhbXBsZXMgY29ycmVzcG9uZCB0byBsZWFkaW5nIGJpb2xvZ2ljYWwgY29lZmZpY2llbnQgb2YgdmFyaWF0aW9uIChCQ1YpIGJldHdlZW4gdGhvc2Ugc2FtcGxlcwpwbG90TURTKHdzX1QyNHZzVDAsIGNvbD1yZXAoMToyLCBlYWNoPTIpKQoKIyMgVGhlIERlc2lnbiBNYXRyaXgKIyBCZWZvcmUgd2UgZml0IG5lZ2F0aXZlIGJpbm9taWFsIEdMTXMsIHdlIG5lZWQgdG8gZGVmaW5lIG91ciBkZXNpZ24gbWF0cml4IGJhc2VkIG9uIHRoZSBleHBlcmltZW50YWwgZGVzaWduLiBIZXJlLCB3ZSB3YW50IHRvIHRlc3QgZm9yIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGJldHdlZW4gVDQgYW5kIFQwIHRpbWVwb2ludHMgd2l0aGluIG1lc29jb3NtcywgaS5lLiwgYWRqdXN0aW5nIGZvciBkaWZmZXJlbmNlcyBiZXR3ZWVuIG1lc29jb3Ntcy4gSW4gc3RhdGlzdGljcywgdGhpcyBpcyBhbiBhZGRpdGl2ZSBsaW5lYXIgbW9kZWwgd2l0aCBtZXNvY29zbSBhcyB0aGUgYmxvY2tpbmcgZmFjdG9yLgpNZXNvY29zbV93c19UMjR2c1QwPC1mYWN0b3IoYygxLDIsMSwyKSkKVGltZXBvaW50X3dzX1QyNHZzVDA8LWZhY3RvcihjKCJUMCIsIlQwIiwiVDI0IiwiVDI0IikpCmRhdGEuZnJhbWUoU2FtcGxlX3dzX1QyNHZzVDA9Y29sbmFtZXMod3NfVDI0dnNUMCksTWVzb2Nvc21fd3NfVDI0dnNUMCxUaW1lcG9pbnRfd3NfVDI0dnNUMCkKd3NfVDI0dnNUMF9kZXNpZ248LW1vZGVsLm1hdHJpeCh+TWVzb2Nvc21fd3NfVDI0dnNUMCtUaW1lcG9pbnRfd3NfVDI0dnNUMCkKcm93bmFtZXMod3NfVDI0dnNUMF9kZXNpZ24pPC1jb2xuYW1lcyh3c19UMjR2c1QwKQp3c19UMjR2c1QwX2Rlc2lnbgoKIyMgRXN0aW1hdGluZyBEaXNwZXJzaW9uCiMgV2UgZXN0aW1hdGUgdGhlIE5CIGRpc3BlcnNpb24gZm9yIHRoZSBkYXRhc2V0CndzX1QyNHZzVDA8LWVzdGltYXRlRGlzcCh3c19UMjR2c1QwLHdzX1QyNHZzVDBfZGVzaWduLHJvYnVzdD1UUlVFKQp3c19UMjR2c1QwJGNvbW1vbi5kaXNwZXJzaW9uCgojIFRoZSBzcXVhcmUgcm9vdCBvZiB0aGUgY29tbW9uIGRpc3BlcnNpb24gZ2l2ZXMgdGhlIGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbiBvZiBiaW9sb2dpY2FsIHZhcmlhdGlvbi4Kc3FydCh3c19UMjR2c1QwJGNvbW1vbi5kaXNwZXJzaW9uKQoKIyBWaWV3IHRoZSBkaXNwZXJzaW9uIGVzdGltYXRlcyBpbiBhIEJDViBwbG90CnBsb3RCQ1Yod3NfVDI0dnNUMCkKCiMjIERpZmZlcmVudGlhbCBFeHByZXNzaW9uCiMgTm93IHdlIHByb2NlZWQgdG8gZGV0ZXJtaW5lIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcyBieSBmaXR0aW5nIGdlbmV3aXNlIGdsbXMKd3NfVDI0dnNUMF9maXQ8LWdsbUZpdCh3c19UMjR2c1QwLHdzX1QyNHZzVDBfZGVzaWduKQoKIyBDb25kdWN0IGxpa2VsaWhvb2QgcmF0aW8gdGVzdHMgZm9yIFQ0IHZzIFQwIGRpZmZlcmVuY2VzIGFuZCBzaG93IHRoZSB0b3AgZ2VuZXMuIFRoZSBnZW5ld2lzZSB0ZXN0cyBhcmUgZm9yIFQ0IHZzIFQwIGRpZmZlcmVudGlhbCBleHByZXNzaW9uLCBhZGp1c3RpbmcgZm9yIGJhc2VsaW5lIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIHR3byBtZXNvY29zbXMuICBUaGUgdGVzdHMgY2FuIGJlIHZpZXdlZCBhcyBhbmFsb2dvdXMgdG8gcGFpcmVkIHQtdGVzdHMuIFRoZSB0b3AgREUgdGFncyBoYXZlIHRpbnkgcC12YWx1ZXMgYW5kIEZEUiB2YWx1ZXMsIGFzIHdlbGwgYXMgbGFyZ2UgZm9sZCBjaGFuZ2VzLgp3c19UMjR2c1QwX2xydDwtZ2xtTFJUKHdzX1QyNHZzVDBfZml0KQp0b3BUYWdzKHdzX1QyNHZzVDBfbHJ0LG49MjUpCgojIyBIZXJlJ3MgdGhlIFRQTS1ub3JtYWxpemVkIHZhbHVlcyBpbiBpbmRpdmlkdWFsIHNhbXBsZXMuCiMgV2Ugc2VlIHRoYXQgYWxsIHRoZSBnZW5lcyBoYXZlIGNvbnNpc3RlbnQgY2hhbmdlcyBiZXR3ZWVuIHJlcGxpY2F0ZXMgd2l0aGluIGVhY2ggdGltZXBvaW50Lgp3c19UMjR2c1QwX3B2YWx1ZTwtb3JkZXIod3NfVDI0dnNUMF9scnQkdGFibGUkUFZhbHVlKQpjcG0od3NfVDI0dnNUMClbd3NfVDI0dnNUMF9wdmFsdWVbMToyNV0sXQpgYGAKPC9kaXY+CgpQbG90dGluZyBzaWduaWZpY2FudCBLT3MgaW4gREdFIGFuYWx5c2lzLgpgYGB7cn0KIyBUaGUgdG90YWwgbnVtYmVyIG9mIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcyBhdCA1JSBGRFIgaXMgZ2l2ZW4gYnk6CndzX1QyNHZzVDBfRkRSPC1wLmFkanVzdCh3c19UMjR2c1QwX2xydCR0YWJsZSRQVmFsdWUsIG1ldGhvZD0iQkgiKQpzdW0od3NfVDI0dnNUMF9GRFI8MC4wNSkKc3VtbWFyeShkZWNpZGVUZXN0cyh3c19UMjR2c1QwX2xydCkpCgojIFBsb3QgdGhlIGxvZy1mb2xkIGNoYW5nZSBhZ2FpbnN0IGxvZy10cmFuc2NyaXB0cyBwZXIgbWlsbGlvbiwgd2l0aCBERSBnZW5lcyBoaWdobGlnaHRlZC4Kd3NfVDI0dnNUMF9NRHBsb3Q8LXBsb3RNRCh3c19UMjR2c1QwX2xydCwgaGwuY29sPWMoIm1pZG5pZ2h0Ymx1ZSIsImxpZ2h0c2t5Ymx1ZTEiKSwgbWFpbiA9IE5VTEwsIHhsYWI9IkF2ZXJhZ2UgbG9nIFRQTSIpICsgYWJsaW5lKGg9MCxjb2w9ImdyYXkiLCBsdHk9ImRhc2hlZCIpCndzX1QyNHZzVDBfTURwbG90CmBgYAoKYGBge3IgZWNobz1GQUxTRX0KIyBXcml0ZSB0aGUgdG9wVGFncyByZXN1bHRzIHRvIC5jc3YgdGFibGUKd3NfVDI0dnNUMF9yZXN1bHRzIDwtIGFzLmRhdGEuZnJhbWUodG9wVGFncyh3c19UMjR2c1QwX2xydCxuID0gSW5mKSkKd3JpdGUuY3N2KHdzX1QyNHZzVDBfcmVzdWx0cywiREUuUmVzdWx0cy93c19UMjR2c1QwX3Jlc3VsdHMuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoKIyMjIyA3LjQuMy4gREdFIEJldHdlZW4gVHVuZHJhCgpOb3cgc3dpdGNoIHBlcnNwZWN0aXZlcyBhbmQgZGV0ZXJtaW5lIHdoaWNoIGV4cHJlc3NlZCBnZW5lcyB3ZXJlIHNpZ25pZmljYW50bHkgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGJldHdlZW4gZWNvc3lzdGVtcyAoKioqaS5lLiwgdmVnZXRhdGlvbiB0eXBlcyoqKikgYXQgdGhlIHNhbWUgc2FtcGxpbmcgdGltZXBvaW50LgoKIyMjIyMgNy40LjMuMS4gV1N2c1R1c3MgVDAKCkNvbXBhcmUgZ2VuZSBleHByZXNzaW9uIHVuZGVyIGFub3hpYyBjb25kaXRpb25zIChUMCkgYmV0d2VlbiBXZXQgU2VkZ2UgYW5kIFR1c3NvY2tzLiBDbGljayBvbiB0aGUgKipTaG93L0hpZGUqKiBidXR0b24gdG8gc2VlIHRoZSBzdGVwcy4KCjxidXR0b24gY2xhc3M9ImJ0biBidG4tcHJpbWFyeSIgZGF0YS10b2dnbGU9ImNvbGxhcHNlIiBkYXRhLXRhcmdldD0iI0Jsb2NrTmFtZTE4Ij4gU2hvdy9IaWRlIDwvYnV0dG9uPiAgCjxkaXYgaWQ9IkJsb2NrTmFtZTE4IiBjbGFzcz0iY29sbGFwc2UiPgpgYGB7cn0KIyBTdWJzZXQgZGF0YSBmcm9tIHRoZSBmdWxsIHRwbV9leHByZXNzZWQgZGF0YXNldAp3c190dXNzX1QwPC10cG1fYWxsX2V4cF9hbm5bLGMoMjo1LDE0OjIwKV0KCiMgQWdncmVnYXRlIChzdW0pIGdlbmVjYWxsIElEIGNvdW50cyBieSBzaGFyZWQgS08gYW5kIFRheG9ub215IHRvIHJlZHVjZSBkdXBsaWNhdGVzIGluIHRoZSBkYXRhc2V0IGFuZCBpbXByb3ZlIHRoZSBERSBhbmFseXNpcyByZXN1bHRzIHRvIGJlIGJpb2xvZ2ljYWxseSByZWxldmFudC4Kd3NfdHVzc19UMDwtYWdncmVnYXRlKC4gfiBLTyArIFN5bWJvbCArIEZ1bmN0aW9uICsgVGllcl9JSSArIFRpZXJfSUlJICsgVGllcl9JViArIFRheG9ub215LCBkYXRhPXdzX3R1c3NfVDAsIEZVTj1zdW0pCgojIyBSZWFkaW5nIGluIHRoZSBkYXRhCiMgQ3JlYXRlIERHRUxpc3QgZm9yIFR1c3MgdnMgV1MgYXQgVDQgc3ViZGF0YQp3c190dXNzX1QwPC1ER0VMaXN0KGNvdW50cz13c190dXNzX1QwWyw4OjExXSwgZ2VuZXM9d3NfdHVzc19UMFssMTo3XSkKcm93bmFtZXMod3NfdHVzc19UMCRjb3VudHMpPC1yb3duYW1lcyh3c190dXNzX1QwJGdlbmVzKTwtd3NfdHVzc19UMCRnZW5lcyRJRAp3c190dXNzX1QwJGdlbmVzJElEPC1OVUxMCgojIyBOb3JtYWxpemF0aW9uCiMgVGVsbCBlZGdlUiB0aGF0IHlvdSBkb24ndCB3YW50IHRvIG5vcm1hbGl6ZSB0aGUgc3ViZGF0YSAoYWxyZWFkeSBUUE0gbm9ybWFsaXplZCkKd3NfdHVzc19UMDwtY2FsY05vcm1GYWN0b3JzKHdzX3R1c3NfVDAsIG1ldGhvZD0ibm9uZSIpCndzX3R1c3NfVDAkc2FtcGxlcwoKIyMgRGF0YSBFeHBsb3JhdGlvbgojIFRoZSBwbG90TURTIGZ1bmN0aW9uIHByb2R1Y2VzIGEgcGxvdCBpbiB3aGljaCBkaXN0YW5jZXMgYmV0d2VlbiBzYW1wbGVzIGNvcnJlc3BvbmQgdG8gbGVhZGluZyBiaW9sb2dpY2FsIGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbiAoQkNWKSBiZXR3ZWVuIHRob3NlIHNhbXBsZXMKcGxvdE1EUyh3c190dXNzX1QwLCBjb2w9cmVwKDE6MiwgZWFjaD0yKSkKCiMjIFRoZSBEZXNpZ24gTWF0cml4CiMgQmVmb3JlIHdlIGZpdCBuZWdhdGl2ZSBiaW5vbWlhbCBHTE1zLCB3ZSBuZWVkIHRvIGRlZmluZSBvdXIgZGVzaWduIG1hdHJpeCBiYXNlZCBvbiB0aGUgZXhwZXJpbWVudGFsIGRlc2lnbi4gSGVyZSwgd2Ugd2FudCB0byB0ZXN0IGZvciBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBiZXR3ZWVuIFQ0IGFuZCBUMCB0aW1lcG9pbnRzIHdpdGhpbiBtZXNvY29zbXMsIGkuZS4sIGFkanVzdGluZyBmb3IgZGlmZmVyZW5jZXMgYmV0d2VlbiBtZXNvY29zbXMuIEluIHN0YXRpc3RpY3MsIHRoaXMgaXMgYW4gYWRkaXRpdmUgbGluZWFyIG1vZGVsIHdpdGggbWVzb2Nvc20gYXMgdGhlIGJsb2NraW5nIGZhY3Rvci4KTWVzb2Nvc21fd3NfdHVzc19UMDwtZmFjdG9yKGMoMSwyLDEsMikpClZlZ2V0YXRpb25fd3NfdHVzc19UMDwtZmFjdG9yKGMoIldTIiwiV1MiLCJUVVNTIiwiVFVTUyIpKQpkYXRhLmZyYW1lKFNhbXBsZV93c190dXNzX1QwPWNvbG5hbWVzKHdzX3R1c3NfVDApLE1lc29jb3NtX3dzX3R1c3NfVDAsVmVnZXRhdGlvbl93c190dXNzX1QwKQp3c190dXNzX1QwX2Rlc2lnbjwtbW9kZWwubWF0cml4KH5NZXNvY29zbV93c190dXNzX1QwK1ZlZ2V0YXRpb25fd3NfdHVzc19UMCkKcm93bmFtZXMod3NfdHVzc19UMF9kZXNpZ24pPC1jb2xuYW1lcyh3c190dXNzX1QwKQp3c190dXNzX1QwX2Rlc2lnbgoKIyMgRXN0aW1hdGluZyBEaXNwZXJzaW9uCiMgV2UgZXN0aW1hdGUgdGhlIE5CIGRpc3BlcnNpb24gZm9yIHRoZSBkYXRhc2V0CndzX3R1c3NfVDA8LWVzdGltYXRlRGlzcCh3c190dXNzX1QwLHdzX3R1c3NfVDBfZGVzaWduLHJvYnVzdD1UUlVFKQp3c190dXNzX1QwJGNvbW1vbi5kaXNwZXJzaW9uCgojIFRoZSBzcXVhcmUgcm9vdCBvZiB0aGUgY29tbW9uIGRpc3BlcnNpb24gZ2l2ZXMgdGhlIGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbiBvZiBiaW9sb2dpY2FsIHZhcmlhdGlvbi4Kc3FydCh3c190dXNzX1QwJGNvbW1vbi5kaXNwZXJzaW9uKQoKIyBWaWV3IHRoZSBkaXNwZXJzaW9uIGVzdGltYXRlcyBpbiBhIEJDViBwbG90CnBsb3RCQ1Yod3NfdHVzc19UMCkKCiMjIERpZmZlcmVudGlhbCBFeHByZXNzaW9uCiMgTm93IHdlIHByb2NlZWQgdG8gZGV0ZXJtaW5lIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcyBieSBmaXR0aW5nIGdlbmV3aXNlIGdsbXMKd3NfdHVzc19UMF9maXQ8LWdsbUZpdCh3c190dXNzX1QwLHdzX3R1c3NfVDBfZGVzaWduKQoKIyBDb25kdWN0IGxpa2VsaWhvb2QgcmF0aW8gdGVzdHMgZm9yIFdTIFQwIHZzIFRVU1MgVDAgZGlmZmVyZW5jZXMgYW5kIHNob3cgdGhlIHRvcCBnZW5lcy4gVGhlIGdlbmV3aXNlIHRlc3RzIGFyZSBmb3IgV1MgVDAgdnMgVFVTUyBUMCBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiwgYWRqdXN0aW5nIGZvciBiYXNlbGluZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSByZXBsaWNhdGUgbWVzb2Nvc21zLiAgVGhlIHRlc3RzIGNhbiBiZSB2aWV3ZWQgYXMgYW5hbG9nb3VzIHRvIHBhaXJlZCB0LXRlc3RzLiBUaGUgdG9wIERFIHRhZ3MgaGF2ZSB0aW55IHAtdmFsdWVzIGFuZCBGRFIgdmFsdWVzLCBhcyB3ZWxsIGFzIGxhcmdlIGZvbGQgY2hhbmdlcy4Kd3NfdHVzc19UMF9scnQ8LWdsbUxSVCh3c190dXNzX1QwX2ZpdCkKd3NfdHVzc19UMF90b3BUYWdzPC10b3BUYWdzKHdzX3R1c3NfVDBfbHJ0LG49MjUpCndzX3R1c3NfVDBfdG9wVGFncwoKIyMgSGVyZSdzIHRoZSBUUE0tbm9ybWFsaXplZCB2YWx1ZXMgaW4gaW5kaXZpZHVhbCBzYW1wbGVzLgojIFdlIHNlZSB0aGF0IGFsbCB0aGUgZ2VuZXMgaGF2ZSBjb25zaXN0ZW50IGNoYW5nZXMgYmV0d2VlbiByZXBsaWNhdGVzIHdpdGhpbiBlYWNoIHRpbWVwb2ludC4Kd3NfdHVzc19UMF9wdmFsdWU8LW9yZGVyKHdzX3R1c3NfVDBfbHJ0JHRhYmxlJFBWYWx1ZSkKY3BtKHdzX3R1c3NfVDApW3dzX3R1c3NfVDBfcHZhbHVlWzE6MjVdLF0KYGBgCjwvZGl2PgoKUGxvdHRpbmcgc2lnbmlmaWNhbnQgS09zIGluIERHRSBhbmFseXNpcy4KYGBge3J9CiMgVGhlIHRvdGFsIG51bWJlciBvZiBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgYXQgNSUgRkRSIGlzIGdpdmVuIGJ5Ogp3c190dXNzX1QwX0ZEUjwtcC5hZGp1c3Qod3NfdHVzc19UMF9scnQkdGFibGUkUFZhbHVlLCBtZXRob2Q9IkJIIikKc3VtKHdzX3R1c3NfVDBfRkRSPDAuMDUpCnN1bW1hcnkoZGVjaWRlVGVzdHMod3NfdHVzc19UMF9scnQpKQoKIyBQbG90IHRoZSBsb2ctZm9sZCBjaGFuZ2UgYWdhaW5zdCBsb2ctdHJhbnNjcmlwdHMgcGVyIG1pbGxpb24sIHdpdGggREUgZ2VuZXMgaGlnaGxpZ2h0ZWQuCndzX3R1c3NfVDBfTURwbG90PC1wbG90TUQod3NfdHVzc19UMF9scnQsIGhsLmNvbD1jKCJwYWxlZ3JlZW4yIiwibGlnaHRza3libHVlMiIpLCBtYWluID0gTlVMTCwgeGxhYj0iQXZlcmFnZSBsb2cgVFBNIikgKyBhYmxpbmUoaD0wLGNvbD0iZ3JheSIsIGx0eT0iZGFzaGVkIikKd3NfdHVzc19UMF9NRHBsb3QKYGBgCgpgYGB7ciBlY2hvPUZBTFNFfQojIFdyaXRlIHRoZSB0b3BUYWdzIHJlc3VsdHMgdG8gLmNzdiB0YWJsZQp3c190dXNzX1QwX3Jlc3VsdHMgPC0gYXMuZGF0YS5mcmFtZSh0b3BUYWdzKHdzX3R1c3NfVDBfbHJ0LG4gPSBJbmYpKQp3cml0ZS5jc3Yod3NfdHVzc19UMF9yZXN1bHRzLCJERS5SZXN1bHRzL3dzX3R1c3NfVDBfcmVzdWx0cy5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkKYGBgCgojIyMjIyA3LjQuMy4yLiBXU3ZzVHVzcyBUNAoKTmV4dCwgY29tcGFyZSBnZW5lIGV4cHJlc3Npb24gdW5kZXIgb3hpYyBjb25kaXRpb25zIChUNCkgYmV0d2VlbiBXZXQgU2VkZ2UgYW5kIFR1c3NvY2tzLiBDbGljayBvbiB0aGUgKipTaG93L0hpZGUqKiBidXR0b24gdG8gc2VlIHRoZSBzdGVwcy4KCjxidXR0b24gY2xhc3M9ImJ0biBidG4tcHJpbWFyeSIgZGF0YS10b2dnbGU9ImNvbGxhcHNlIiBkYXRhLXRhcmdldD0iI0Jsb2NrTmFtZTE5Ij4gU2hvdy9IaWRlIDwvYnV0dG9uPiAgCjxkaXYgaWQ9IkJsb2NrTmFtZTE5IiBjbGFzcz0iY29sbGFwc2UiPgpgYGB7cn0KIyBTdWJzZXQgZGF0YSBmcm9tIHRoZSBmdWxsIHRwbV9leHByZXNzZWQgZGF0YXNldAp3c190dXNzX1Q0PC10cG1fYWxsX2V4cF9hbm5bLGMoNjo3LDEwOjExLDE0OjIwKV0KCiMgQWdncmVnYXRlIChzdW0pIGdlbmVjYWxsIElEIGNvdW50cyBieSBzaGFyZWQgS08gYW5kIFRheG9ub215IHRvIHJlZHVjZSBkdXBsaWNhdGVzIGluIHRoZSBkYXRhc2V0IGFuZCBpbXByb3ZlIHRoZSBERSBhbmFseXNpcyByZXN1bHRzIHRvIGJlIGJpb2xvZ2ljYWxseSByZWxldmFudC4Kd3NfdHVzc19UNDwtYWdncmVnYXRlKC4gfiBLTyArIFN5bWJvbCArIEZ1bmN0aW9uICsgVGllcl9JSSArIFRpZXJfSUlJICsgVGllcl9JViArIFRheG9ub215LCBkYXRhPXdzX3R1c3NfVDQsIEZVTj1zdW0pCgojIyBSZWFkaW5nIGluIHRoZSBkYXRhCiMgQ3JlYXRlIERHRUxpc3QgZm9yIFR1c3MgdnMgV1MgYXQgVDQgc3ViZGF0YQp3c190dXNzX1Q0PC1ER0VMaXN0KGNvdW50cz13c190dXNzX1Q0Wyw4OjExXSwgZ2VuZXM9d3NfdHVzc19UNFssMTo3XSkKcm93bmFtZXMod3NfdHVzc19UNCRjb3VudHMpPC1yb3duYW1lcyh3c190dXNzX1Q0JGdlbmVzKTwtd3NfdHVzc19UNCRnZW5lcyRJRAp3c190dXNzX1Q0JGdlbmVzJElEPC1OVUxMCgojIyBOb3JtYWxpemF0aW9uCiMgVGVsbCBlZGdlUiB0aGF0IHlvdSBkb24ndCB3YW50IHRvIG5vcm1hbGl6ZSB0aGUgc3ViZGF0YSAoYWxyZWFkeSBUUE0gbm9ybWFsaXplZCkKd3NfdHVzc19UNDwtY2FsY05vcm1GYWN0b3JzKHdzX3R1c3NfVDQsIG1ldGhvZD0ibm9uZSIpCndzX3R1c3NfVDQkc2FtcGxlcwoKIyMgRGF0YSBFeHBsb3JhdGlvbgojIFRoZSBwbG90TURTIGZ1bmN0aW9uIHByb2R1Y2VzIGEgcGxvdCBpbiB3aGljaCBkaXN0YW5jZXMgYmV0d2VlbiBzYW1wbGVzIGNvcnJlc3BvbmQgdG8gbGVhZGluZyBiaW9sb2dpY2FsIGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbiAoQkNWKSBiZXR3ZWVuIHRob3NlIHNhbXBsZXMKcGxvdE1EUyh3c190dXNzX1Q0LCBjb2w9cmVwKDE6MiwgZWFjaD0yKSkKCiMjIFRoZSBEZXNpZ24gTWF0cml4CiMgQmVmb3JlIHdlIGZpdCBuZWdhdGl2ZSBiaW5vbWlhbCBHTE1zLCB3ZSBuZWVkIHRvIGRlZmluZSBvdXIgZGVzaWduIG1hdHJpeCBiYXNlZCBvbiB0aGUgZXhwZXJpbWVudGFsIGRlc2lnbi4gSGVyZSwgd2Ugd2FudCB0byB0ZXN0IGZvciBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBiZXR3ZWVuIFQ0IGFuZCBUMCB0aW1lcG9pbnRzIHdpdGhpbiBtZXNvY29zbXMsIGkuZS4sIGFkanVzdGluZyBmb3IgZGlmZmVyZW5jZXMgYmV0d2VlbiBtZXNvY29zbXMuIEluIHN0YXRpc3RpY3MsIHRoaXMgaXMgYW4gYWRkaXRpdmUgbGluZWFyIG1vZGVsIHdpdGggbWVzb2Nvc20gYXMgdGhlIGJsb2NraW5nIGZhY3Rvci4KTWVzb2Nvc21fd3NfdHVzc19UNDwtZmFjdG9yKGMoMSwyLDEsMikpClZlZ2V0YXRpb25fd3NfdHVzc19UNDwtZmFjdG9yKGMoIldTIiwiV1MiLCJUVVNTIiwiVFVTUyIpKQpkYXRhLmZyYW1lKFNhbXBsZV93c190dXNzX1Q0PWNvbG5hbWVzKHdzX3R1c3NfVDQpLE1lc29jb3NtX3dzX3R1c3NfVDQsVmVnZXRhdGlvbl93c190dXNzX1Q0KQp3c190dXNzX1Q0X2Rlc2lnbjwtbW9kZWwubWF0cml4KH5NZXNvY29zbV93c190dXNzX1Q0K1ZlZ2V0YXRpb25fd3NfdHVzc19UNCkKcm93bmFtZXMod3NfdHVzc19UNF9kZXNpZ24pPC1jb2xuYW1lcyh3c190dXNzX1Q0KQp3c190dXNzX1Q0X2Rlc2lnbgoKIyMgRXN0aW1hdGluZyBEaXNwZXJzaW9uCiMgV2UgZXN0aW1hdGUgdGhlIE5CIGRpc3BlcnNpb24gZm9yIHRoZSBkYXRhc2V0CndzX3R1c3NfVDQ8LWVzdGltYXRlRGlzcCh3c190dXNzX1Q0LHdzX3R1c3NfVDRfZGVzaWduLHJvYnVzdD1UUlVFKQp3c190dXNzX1Q0JGNvbW1vbi5kaXNwZXJzaW9uCgojIFRoZSBzcXVhcmUgcm9vdCBvZiB0aGUgY29tbW9uIGRpc3BlcnNpb24gZ2l2ZXMgdGhlIGNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbiBvZiBiaW9sb2dpY2FsIHZhcmlhdGlvbi4Kc3FydCh3c190dXNzX1Q0JGNvbW1vbi5kaXNwZXJzaW9uKQoKIyBWaWV3IHRoZSBkaXNwZXJzaW9uIGVzdGltYXRlcyBpbiBhIEJDViBwbG90CnBsb3RCQ1Yod3NfdHVzc19UNCkKCiMjIERpZmZlcmVudGlhbCBFeHByZXNzaW9uCiMgTm93IHdlIHByb2NlZWQgdG8gZGV0ZXJtaW5lIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcyBieSBmaXR0aW5nIGdlbmV3aXNlIGdsbXMKd3NfdHVzc19UNF9maXQ8LWdsbUZpdCh3c190dXNzX1Q0LHdzX3R1c3NfVDRfZGVzaWduKQoKIyBDb25kdWN0IGxpa2VsaWhvb2QgcmF0aW8gdGVzdHMgZm9yIFdTIFQ0IHZzIFRVU1MgVDQgZGlmZmVyZW5jZXMgYW5kIHNob3cgdGhlIHRvcCBnZW5lcy4gVGhlIGdlbmV3aXNlIHRlc3RzIGFyZSBmb3IgV1MgVDQgdnMgVFVTUyBUNCBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiwgYWRqdXN0aW5nIGZvciBiYXNlbGluZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSByZXBsaWNhdGUgbWVzb2Nvc21zLiAgVGhlIHRlc3RzIGNhbiBiZSB2aWV3ZWQgYXMgYW5hbG9nb3VzIHRvIHBhaXJlZCB0LXRlc3RzLiBUaGUgdG9wIERFIHRhZ3MgaGF2ZSB0aW55IHAtdmFsdWVzIGFuZCBGRFIgdmFsdWVzLCBhcyB3ZWxsIGFzIGxhcmdlIGZvbGQgY2hhbmdlcy4Kd3NfdHVzc19UNF9scnQ8LWdsbUxSVCh3c190dXNzX1Q0X2ZpdCkKdG9wVGFncyh3c190dXNzX1Q0X2xydCxuPTI1KQoKIyMgSGVyZSdzIHRoZSBUUE0tbm9ybWFsaXplZCB2YWx1ZXMgaW4gaW5kaXZpZHVhbCBzYW1wbGVzLgojIFdlIHNlZSB0aGF0IGFsbCB0aGUgZ2VuZXMgaGF2ZSBjb25zaXN0ZW50IGNoYW5nZXMgYmV0d2VlbiByZXBsaWNhdGVzIHdpdGhpbiBlYWNoIHRpbWVwb2ludC4Kd3NfdHVzc19UNF9wdmFsdWU8LW9yZGVyKHdzX3R1c3NfVDRfbHJ0JHRhYmxlJFBWYWx1ZSkKY3BtKHdzX3R1c3NfVDQpW3dzX3R1c3NfVDRfcHZhbHVlWzE6MjVdLF0KYGBgCjwvZGl2PgoKUGxvdHRpbmcgc2lnbmlmaWNhbnQgS09zIGluIERHRSBhbmFseXNpcy4KYGBge3J9CiMgVGhlIHRvdGFsIG51bWJlciBvZiBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgYXQgNSUgRkRSIGlzIGdpdmVuIGJ5Ogp3c190dXNzX1Q0X0ZEUjwtcC5hZGp1c3Qod3NfdHVzc19UNF9scnQkdGFibGUkUFZhbHVlLCBtZXRob2Q9IkJIIikKc3VtKHdzX3R1c3NfVDRfRkRSPDAuMDUpCnN1bW1hcnkoZGVjaWRlVGVzdHMod3NfdHVzc19UNF9scnQpKQoKIyBQbG90IHRoZSBsb2ctZm9sZCBjaGFuZ2UgYWdhaW5zdCBsb2ctdHJhbnNjcmlwdHMgcGVyIG1pbGxpb24sIHdpdGggREUgZ2VuZXMgaGlnaGxpZ2h0ZWQuCndzX3R1c3NfVDRfTURwbG90PC1wbG90TUQod3NfdHVzc19UNF9scnQsIGhsLmNvbD1jKCJncmVlbjMiLCJkb2RnZXJibHVlMSIpLCBtYWluID0gTlVMTCwgeGxhYj0iQXZlcmFnZSBsb2cgVFBNIikgKyBhYmxpbmUoaD0wLGNvbD0iZ3JheSIsIGx0eT0iZGFzaGVkIikKd3NfdHVzc19UNF9NRHBsb3QKYGBgCgpgYGB7ciBlY2hvPUZBTFNFfQojIFdyaXRlIHRoZSB0b3BUYWdzIHJlc3VsdHMgdG8gLmNzdiB0YWJsZQp3c190dXNzX1Q0X3Jlc3VsdHMgPC0gYXMuZGF0YS5mcmFtZSh0b3BUYWdzKHdzX3R1c3NfVDRfbHJ0LG4gPSBJbmYpKQp3cml0ZS5jc3Yod3NfdHVzc19UNF9yZXN1bHRzLCJERS5SZXN1bHRzL3dzX3R1c3NfVDRfcmVzdWx0cy5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkKYGBgCgojIyMjIyA3LjQuMy4zLiBXU3ZzVHVzcyBUMjQKCkZpbmFsbHksIGNvbXBhcmUgZ2VuZSBleHByZXNzaW9uIHVuZGVyIG1peGVkLXJlZG94IGNvbmRpdGlvbnMgKFQyNCkgYmV0d2VlbiBXZXQgU2VkZ2UgYW5kIFR1c3NvY2tzLiBDbGljayBvbiB0aGUgKipTaG93L0hpZGUqKiBidXR0b24gdG8gc2VlIHRoZSBzdGVwcy4KCjxidXR0b24gY2xhc3M9ImJ0biBidG4tcHJpbWFyeSIgZGF0YS10b2dnbGU9ImNvbGxhcHNlIiBkYXRhLXRhcmdldD0iI0Jsb2NrTmFtZTIwIj4gU2hvdy9IaWRlIDwvYnV0dG9uPiAgCjxkaXYgaWQ9IkJsb2NrTmFtZTIwIiBjbGFzcz0iY29sbGFwc2UiPgpgYGB7cn0KIyBTdWJzZXQgZGF0YSBmcm9tIHRoZSBmdWxsIHRwbV9leHByZXNzZWQgZGF0YXNldAp3c190dXNzX1QyNDwtdHBtX2FsbF9leHBfYW5uWyxjKDg6OSwxMjoyMCldCgojIEFnZ3JlZ2F0ZSAoc3VtKSBnZW5lY2FsbCBJRCBjb3VudHMgYnkgc2hhcmVkIEtPIGFuZCBUYXhvbm9teSB0byByZWR1Y2UgZHVwbGljYXRlcyBpbiB0aGUgZGF0YXNldCBhbmQgaW1wcm92ZSB0aGUgREUgYW5hbHlzaXMgcmVzdWx0cyB0byBiZSBiaW9sb2dpY2FsbHkgcmVsZXZhbnQuCndzX3R1c3NfVDI0PC1hZ2dyZWdhdGUoLiB+IEtPICsgU3ltYm9sICsgRnVuY3Rpb24gKyBUaWVyX0lJICsgVGllcl9JSUkgKyBUaWVyX0lWICsgVGF4b25vbXksIGRhdGE9d3NfdHVzc19UMjQsIEZVTj1zdW0pCgojIyBSZWFkaW5nIGluIHRoZSBkYXRhCiMgQ3JlYXRlIERHRUxpc3QgZm9yIFR1c3MgdnMgV1MgYXQgVDI0IHN1YmRhdGEKd3NfdHVzc19UMjQ8LURHRUxpc3QoY291bnRzPXdzX3R1c3NfVDI0Wyw4OjExXSwgZ2VuZXM9d3NfdHVzc19UMjRbLDE6N10pCnJvd25hbWVzKHdzX3R1c3NfVDI0JGNvdW50cyk8LXJvd25hbWVzKHdzX3R1c3NfVDI0JGdlbmVzKTwtd3NfdHVzc19UMjQkZ2VuZXMkSUQKd3NfdHVzc19UMjQkZ2VuZXMkSUQ8LU5VTEwKCiMjIE5vcm1hbGl6YXRpb24KIyBUZWxsIGVkZ2VSIHRoYXQgeW91IGRvbid0IHdhbnQgdG8gbm9ybWFsaXplIHRoZSBzdWJkYXRhIChhbHJlYWR5IFRQTSBub3JtYWxpemVkKQp3c190dXNzX1QyNDwtY2FsY05vcm1GYWN0b3JzKHdzX3R1c3NfVDI0LCBtZXRob2Q9Im5vbmUiKQp3c190dXNzX1QyNCRzYW1wbGVzCgojIyBEYXRhIEV4cGxvcmF0aW9uCiMgVGhlIHBsb3RNRFMgZnVuY3Rpb24gcHJvZHVjZXMgYSBwbG90IGluIHdoaWNoIGRpc3RhbmNlcyBiZXR3ZWVuIHNhbXBsZXMgY29ycmVzcG9uZCB0byBsZWFkaW5nIGJpb2xvZ2ljYWwgY29lZmZpY2llbnQgb2YgdmFyaWF0aW9uIChCQ1YpIGJldHdlZW4gdGhvc2Ugc2FtcGxlcwpwbG90TURTKHdzX3R1c3NfVDI0LCBjb2w9cmVwKDE6MiwgZWFjaD0yKSkKCiMjIFRoZSBEZXNpZ24gTWF0cml4CiMgQmVmb3JlIHdlIGZpdCBuZWdhdGl2ZSBiaW5vbWlhbCBHTE1zLCB3ZSBuZWVkIHRvIGRlZmluZSBvdXIgZGVzaWduIG1hdHJpeCBiYXNlZCBvbiB0aGUgZXhwZXJpbWVudGFsIGRlc2lnbi4gSGVyZSwgd2Ugd2FudCB0byB0ZXN0IGZvciBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBiZXR3ZWVuIFQ0IGFuZCBUMCB0aW1lcG9pbnRzIHdpdGhpbiBtZXNvY29zbXMsIGkuZS4sIGFkanVzdGluZyBmb3IgZGlmZmVyZW5jZXMgYmV0d2VlbiBtZXNvY29zbXMuIEluIHN0YXRpc3RpY3MsIHRoaXMgaXMgYW4gYWRkaXRpdmUgbGluZWFyIG1vZGVsIHdpdGggbWVzb2Nvc20gYXMgdGhlIGJsb2NraW5nIGZhY3Rvci4KTWVzb2Nvc21fd3NfdHVzc19UMjQ8LWZhY3RvcihjKDEsMiwxLDIpKQpWZWdldGF0aW9uX3dzX3R1c3NfVDI0PC1mYWN0b3IoYygiV1MiLCJXUyIsIlRVU1MiLCJUVVNTIikpCmRhdGEuZnJhbWUoU2FtcGxlX3dzX3R1c3NfVDI0PWNvbG5hbWVzKHdzX3R1c3NfVDI0KSxNZXNvY29zbV93c190dXNzX1QyNCxWZWdldGF0aW9uX3dzX3R1c3NfVDI0KQp3c190dXNzX1QyNF9kZXNpZ248LW1vZGVsLm1hdHJpeCh+TWVzb2Nvc21fd3NfdHVzc19UMjQrVmVnZXRhdGlvbl93c190dXNzX1QyNCkKcm93bmFtZXMod3NfdHVzc19UMjRfZGVzaWduKTwtY29sbmFtZXMod3NfdHVzc19UMjQpCndzX3R1c3NfVDI0X2Rlc2lnbgoKIyMgRXN0aW1hdGluZyBEaXNwZXJzaW9uCiMgV2UgZXN0aW1hdGUgdGhlIE5CIGRpc3BlcnNpb24gZm9yIHRoZSBkYXRhc2V0CndzX3R1c3NfVDI0PC1lc3RpbWF0ZURpc3Aod3NfdHVzc19UMjQsd3NfdHVzc19UMjRfZGVzaWduLHJvYnVzdD1UUlVFKQp3c190dXNzX1QyNCRjb21tb24uZGlzcGVyc2lvbgoKIyBUaGUgc3F1YXJlIHJvb3Qgb2YgdGhlIGNvbW1vbiBkaXNwZXJzaW9uIGdpdmVzIHRoZSBjb2VmZmljaWVudCBvZiB2YXJpYXRpb24gb2YgYmlvbG9naWNhbCB2YXJpYXRpb24uCnNxcnQod3NfdHVzc19UMjQkY29tbW9uLmRpc3BlcnNpb24pCgojIFZpZXcgdGhlIGRpc3BlcnNpb24gZXN0aW1hdGVzIGluIGEgQkNWIHBsb3QKcGxvdEJDVih3c190dXNzX1QyNCkKCiMjIERpZmZlcmVudGlhbCBFeHByZXNzaW9uCiMgTm93IHdlIHByb2NlZWQgdG8gZGV0ZXJtaW5lIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcyBieSBmaXR0aW5nIGdlbmV3aXNlIGdsbXMKd3NfdHVzc19UMjRfZml0PC1nbG1GaXQod3NfdHVzc19UMjQsd3NfdHVzc19UMjRfZGVzaWduKQoKIyBDb25kdWN0IGxpa2VsaWhvb2QgcmF0aW8gdGVzdHMgZm9yIFdTIFQyNCB2cyBUVVNTIFQyNCBkaWZmZXJlbmNlcyBhbmQgc2hvdyB0aGUgdG9wIGdlbmVzLiBUaGUgZ2VuZXdpc2UgdGVzdHMgYXJlIGZvciBXUyBUMjQgdnMgVFVTUyBUMjQgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24sIGFkanVzdGluZyBmb3IgYmFzZWxpbmUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgcmVwbGljYXRlIG1lc29jb3Ntcy4gIFRoZSB0ZXN0cyBjYW4gYmUgdmlld2VkIGFzIGFuYWxvZ291cyB0byBwYWlyZWQgdC10ZXN0cy4gVGhlIHRvcCBERSB0YWdzIGhhdmUgdGlueSBwLXZhbHVlcyBhbmQgRkRSIHZhbHVlcywgYXMgd2VsbCBhcyBsYXJnZSBmb2xkIGNoYW5nZXMuCndzX3R1c3NfVDI0X2xydDwtZ2xtTFJUKHdzX3R1c3NfVDI0X2ZpdCkKdG9wVGFncyh3c190dXNzX1QyNF9scnQsbj0yNSkKCiMjIEhlcmUncyB0aGUgVFBNLW5vcm1hbGl6ZWQgdmFsdWVzIGluIGluZGl2aWR1YWwgc2FtcGxlcy4KIyBXZSBzZWUgdGhhdCBhbGwgdGhlIGdlbmVzIGhhdmUgY29uc2lzdGVudCBjaGFuZ2VzIGJldHdlZW4gcmVwbGljYXRlcyB3aXRoaW4gZWFjaCB0aW1lcG9pbnQuCndzX3R1c3NfVDI0X3B2YWx1ZTwtb3JkZXIod3NfdHVzc19UMjRfbHJ0JHRhYmxlJFBWYWx1ZSkKY3BtKHdzX3R1c3NfVDI0KVt3c190dXNzX1QyNF9wdmFsdWVbMToyNV0sXQpgYGAKPC9kaXY+CgpQbG90dGluZyBzaWduaWZpY2FudCBLT3MgaW4gREdFIGFuYWx5c2lzLgpgYGB7cn0KIyBUaGUgdG90YWwgbnVtYmVyIG9mIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcyBhdCA1JSBGRFIgaXMgZ2l2ZW4gYnk6CndzX3R1c3NfVDI0X0ZEUjwtcC5hZGp1c3Qod3NfdHVzc19UMjRfbHJ0JHRhYmxlJFBWYWx1ZSwgbWV0aG9kPSJCSCIpCnN1bSh3c190dXNzX1QyNF9GRFI8MC4wNSkKc3VtbWFyeShkZWNpZGVUZXN0cyh3c190dXNzX1QyNF9scnQpKQoKIyBQbG90IHRoZSBsb2ctZm9sZCBjaGFuZ2UgYWdhaW5zdCBsb2ctdHJhbnNjcmlwdHMgcGVyIG1pbGxpb24sIHdpdGggREUgZ2VuZXMgaGlnaGxpZ2h0ZWQuCndzX3R1c3NfVDI0X01EcGxvdDwtcGxvdE1EKHdzX3R1c3NfVDI0X2xydCwgaGwuY29sPWMoImRhcmtncmVlbiIsIm1pZG5pZ2h0Ymx1ZSIpLCBtYWluID0gTlVMTCwgeGxhYj0iQXZlcmFnZSBsb2cgVFBNIikgKyBhYmxpbmUoaD0wLGNvbD0iZ3JheSIsIGx0eT0iZGFzaGVkIikKd3NfdHVzc19UMjRfTURwbG90CmBgYAoKYGBge3IgZWNobz1GQUxTRX0KIyBXcml0ZSB0aGUgdG9wVGFncyByZXN1bHRzIHRvIC5jc3YgdGFibGUKd3NfdHVzc19UMjRfcmVzdWx0cyA8LSBhcy5kYXRhLmZyYW1lKHRvcFRhZ3Mod3NfdHVzc19UMjRfbHJ0LG4gPSBJbmYpKQp3cml0ZS5jc3Yod3NfdHVzc19UMjRfcmVzdWx0cywiREUuUmVzdWx0cy93c190dXNzX1QyNF9yZXN1bHRzLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQpgYGAKCiMjIyA3LjUuIEZlIEdlbmUgRXhwcmVzc2lvbgoKR2VuZSBleHByZXNzaW9uIHJlbGF0ZWQgdG8gaXJvbiBhY3F1aXNpdGlvbiwgaXJvbiByZWRveCBjeWNsaW5nLCBhbmQgaXJvbiBzdG9yYWdlIHdlcmUgZGV0ZXJtaW5lZCB1c2luZyBGZUdlbmllIFsoR2FyYmVyIGV0IGFsLiAyMDIwKV0oaHR0cHM6Ly93d3cuZnJvbnRpZXJzaW4ub3JnL2FydGljbGVzLzEwLjMzODkvZm1pY2IuMjAyMC4wMDAzNy9mdWxsKS4gIEZlR2VuaWUgcHJvdmlkZXMgYSBjb21wcmVoZW5zaXZlIGRhdGFiYXNlIG9mIGhpZGRlbiBNYXJrb3YgbW9kZWxzIChITU1zKSBiYXNlZCBvbiBnZW5lcyByZWxhdGVkIHRvIGlyb24gYWNxdWlzaXRpb24sIHN0b3JhZ2UsIGFuZCBveGlkYXRpb24vcmVkdWN0aW9uIGluIEJhY3RlcmlhIGFuZCBBcmNoYWVhLCB3aGljaCBhcmUgZ2VuZXJhbGx5IG5vdCBhbm5vdGF0ZWQgYXMgc3VjaCBieSBlc3RhYmxpc2hlZCBnZW5lIGFubm90YXRpb24gcGlwZWxpbmVzLCBzdWNoIGFzIEdob3N0S09BTEEsIHdoaWNoIHdhcyB1c2VkIHRvIGFubm90YXRlIHRoZSBtZXRhdHJhbnNjcmlwdG9tZXMgcHJlc2VudGVkIGluIHRoaXMgc3R1ZHkuCgpIZXJlLCB0aGUgcXVhbGl0eS1jb250cm9sbGVkIHNlcXVlbmNpbmcgcmVhZHMgZm9yIGVhY2ggbWV0YXRyYW5zY3JpcHRvbWUgc2FtcGxlIHdlcmUgYXNzZW1ibGVkIHNlcGFyYXRlbHkgdXNpbmcgTUVHQUhJVCB0byBnZW5lcmF0ZSBhIHNhbXBsZS1zcGVjaWZpYyBjb250aWdzIGZpbGUuICBUaGUgbWV0YXRyYW5zY3JpcHRvbWUgY29udGlncyBmaWxlcyB3ZXJlIHVzZWQgYXMgaW5wdXQgZm9yIEZlR2VuaWUsIHdoaWNoIGZpcnN0IHByZWRpY3RlZCBvcGVuLXJlYWRpbmcgZnJhbWVzIChPUkZzKSB1c2luZyBQcm9kaWdhbCBhbmQgdGhlbiBxdWVyaWVkIHRoZW0gYWdhaW5zdCBhIGN1c3RvbSBsaWJyYXJ5IG9mIEhNTXMgdXNpbmcgaG1tc2VhcmNoLCB3aXRoIGN1c3RvbSBiaXQgc2NvcmUgY3V0b2ZmcyBmb3IgZWFjaCBITU0uICBSZXN1bHRzIGZyb20gRmVHZW5pZSBpbmNsdWRlZCBhbGwgaWRlbnRpZmllZCBwdXRhdGl2ZSBpcm9uLXJlbGF0ZWQgZ2VuZXMsIHRoZWlyIGZ1bmN0aW9uYWwgY2F0ZWdvcnksIGJpdCBzY29yZSwgbnVtYmVyIG9mIGNhbm9uaWNhbCBoZW1lLWJpbmRpbmcgbW90aWZzLCBhbWlubyBhY2lkIHNlcXVlbmNlLCBhbmQgY2xvc2VzdCBob21vbG9nLiAgQ291bnRzIHdpdGhpbiBlYWNoIGlyb24gZ2VuZSBjYXRlZ29yeSB3ZXJlIHN1bW1hcml6ZWQgYXMgdGhlaXIgcmVsYXRpdmUgZXhwcmVzc2lvbiBhZ2FpbnN0IGFsbCBpZGVudGlmaWVkIGlyb24gZ2VuZXMuCgpBc3NlbWJsZSBlYWNoIFFDJ2QgbWV0YXRyYW5zY3JpcHRvbWUgc2FtcGxlIGZvciB1c2UgaW4gRmVHZW5pZQpgYGBgbWFya2Rvd24KYHIgJydge1Rlcm1pbmFsfQptb2R1bGUgbG9hZCBCaW9pbmZvcm1hdGljcyBtZWdhaGl0LzEuMi44Cm1lZ2FoaXQgLS1rLW1pbiAyMSAtLWstbWF4IDE0MSAtLWstc3RlcCAxMiAtMSBTYW1wbGVfMTA4Mzc5X2Z3ZC5nb29kLmZhc3RxIC0yIFNhbXBsZV8xMDgzNzlfcmV2Lmdvb2QuZmFzdHEgLW8gLi9tZWdhaGl0XzEwODM3OV9vdXQKbWVnYWhpdCAtLWstbWluIDIxIC0tay1tYXggMTQxIC0tay1zdGVwIDEyIC0xIFNhbXBsZV8xMDgzODFfZndkLmdvb2QuZmFzdHEgLTIgU2FtcGxlXzEwODM4MV9yZXYuZ29vZC5mYXN0cSAtbyAuL21lZ2FoaXRfMTA4MzgxX291dAptZWdhaGl0IC0tay1taW4gMjEgLS1rLW1heCAxNDEgLS1rLXN0ZXAgMTIgLTEgU2FtcGxlXzEwODM4Ml9md2QuZ29vZC5mYXN0cSAtMiBTYW1wbGVfMTA4MzgyX3Jldi5nb29kLmZhc3RxIC1vIC4vbWVnYWhpdF8xMDgzODJfb3V0Cm1lZ2FoaXQgLS1rLW1pbiAyMSAtLWstbWF4IDE0MSAtLWstc3RlcCAxMiAtMSBTYW1wbGVfMTA4MzgzX2Z3ZC5nb29kLmZhc3RxIC0yIFNhbXBsZV8xMDgzODNfcmV2Lmdvb2QuZmFzdHEgLW8gLi9tZWdhaGl0XzEwODM4M19vdXQKbWVnYWhpdCAtLWstbWluIDIxIC0tay1tYXggMTQxIC0tay1zdGVwIDEyIC0xIFNhbXBsZV8xMDgzODVfZndkLmdvb2QuZmFzdHEgLTIgU2FtcGxlXzEwODM4NV9yZXYuZ29vZC5mYXN0cSAtbyAuL21lZ2FoaXRfMTA4Mzg1X291dAptZWdhaGl0IC0tay1taW4gMjEgLS1rLW1heCAxNDEgLS1rLXN0ZXAgMTIgLTEgU2FtcGxlXzEwODM4Nl9md2QuZ29vZC5mYXN0cSAtMiBTYW1wbGVfMTA4Mzg2X3Jldi5nb29kLmZhc3RxIC1vIC4vbWVnYWhpdF8xMDgzODZfb3V0Cm1lZ2FoaXQgLS1rLW1pbiAyMSAtLWstbWF4IDE0MSAtLWstc3RlcCAxMiAtMSBTYW1wbGVfMTA4Mzg4X2Z3ZC5nb29kLmZhc3RxIC0yIFNhbXBsZV8xMDgzODhfcmV2Lmdvb2QuZmFzdHEgLW8gLi9tZWdhaGl0XzEwODM4OF9vdXQKbWVnYWhpdCAtLWstbWluIDIxIC0tay1tYXggMTQxIC0tay1zdGVwIDEyIC0xIFNhbXBsZV8xMDgzOTBfZndkLmdvb2QuZmFzdHEgLTIgU2FtcGxlXzEwODM5MF9yZXYuZ29vZC5mYXN0cSAtbyAuL21lZ2FoaXRfMTA4MzkwX291dAptZWdhaGl0IC0tay1taW4gMjEgLS1rLW1heCAxNDEgLS1rLXN0ZXAgMTIgLTEgU2FtcGxlXzEwODM5MV9md2QuZ29vZC5mYXN0cSAtMiBTYW1wbGVfMTA4MzkxX3Jldi5nb29kLmZhc3RxIC1vIC4vbWVnYWhpdF8xMDgzOTFfb3V0Cm1lZ2FoaXQgLS1rLW1pbiAyMSAtLWstbWF4IDE0MSAtLWstc3RlcCAxMiAtMSBTYW1wbGVfMTA4MzkyX2Z3ZC5nb29kLmZhc3RxIC0yIFNhbXBsZV8xMDgzOTJfcmV2Lmdvb2QuZmFzdHEgLW8gLi9tZWdhaGl0XzEwODM5Ml9vdXQKbWVnYWhpdCAtLWstbWluIDIxIC0tay1tYXggMTQxIC0tay1zdGVwIDEyIC0xIFNhbXBsZV8xMDgzOTRfZndkLmdvb2QuZmFzdHEgLTIgU2FtcGxlXzEwODM5NF9yZXYuZ29vZC5mYXN0cSAtbyAuL21lZ2FoaXRfMTA4Mzk0X291dAptZWdhaGl0IC0tay1taW4gMjEgLS1rLW1heCAxNDEgLS1rLXN0ZXAgMTIgLTEgU2FtcGxlXzEwODM5Nl9md2QuZ29vZC5mYXN0cSAtMiBTYW1wbGVfMTA4Mzk2X3Jldi5nb29kLmZhc3RxIC1vIC4vbWVnYWhpdF8xMDgzOTZfb3V0CmBgYGAKCiMjIyMgNy41LjEuIEZlR2VuaWUgU3VtbWFyeQoKRmVHZW5pZSBpcyBhIHB5dGhvbiBzY3JpcHQgd2l0aCBkZXBlbmRlbmNpZXMgdGhhdCBjYW4gYmUgZG93bmxvYWRlZCBmcm9tICBbQXJrYWRpeS1HYXJiZXIgR2l0SHViXShodHRwczovL2dpdGh1Yi5jb20vQXJrYWRpeS1HYXJiZXIvRmVHZW5pZSkuCgpTdGFydCBieSBsb2FkaW5nIHByZXJlcXVpc2l0ZSBtb2R1bGVzCmBgYGBtYXJrZG93bgpgciAnJ2B7VGVybWluYWx9Cm1vZHVsZSBsb2FkIHB5dGhvbjMuNi1hbmFjb25kYSBCaW9pbmZvcm1hdGljcyBobW1lciBwcm9kaWdhbCBuY2JpLWJsYXN0IFIKYGBgYAoKUnVuIHRoZSBGZUdlbmllIHB5dGhvbiBzY3JpcHQKYGBgYG1hcmtkb3duCmByICcnYHtUZXJtaW5hbH0KRmVHZW5pZV9ybmEuc2gKCiMgVGhpcyBpcyB3aGF0J3MgaW5zaWRlIHRoZSAiRmVHZW5pZV9ybmEuc2giIHNjcmlwdApGZUdlbmllLnB5IC1iaW5fZGlyIC9QYXRoL1RvL2Fzc2VtYmx5X2Zhc3RhIC1iaW5fZXh0IGZhIC1vdXQgRmVHZW5pZV9ybmFfb3V0CmBgYGAKClJlc3VsdHMgZnJvbSBGZUdlbmllIGFuYWx5c2lzIHVzaW5nIEdhcmJlciBldCBhbC4gMjAyMCBSLXNjcmlwdHMuCgpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpGZUdlbmllX2hlYXRtYXBfZGF0YV9vcmdhbml6ZWQ8LXJlYWQuY3N2KCJQbG90LkRhdGEvRmVHZW5pZS5kb3RwbG90LmNzdiIsIGhlYWRlcj1GQUxTRSkKYGBgCgpgYGB7ciB3YXJuaW5nPUZBTFNFfQpsID0gbGVuZ3RoKEZlR2VuaWVfaGVhdG1hcF9kYXRhX29yZ2FuaXplZCkKZmVnZW5pZS50IDwtIHQoRmVHZW5pZV9oZWF0bWFwX2RhdGFfb3JnYW5pemVkWywzOmwtMV0pCmZlZ2VuaWUubWF0cml4ID0gYXMubWF0cml4KGZlZ2VuaWUudCkKCmNvbG5hbWVzKGZlZ2VuaWUudCkgPC0gYXMudmVjdG9yKEZlR2VuaWVfaGVhdG1hcF9kYXRhX29yZ2FuaXplZCRWMSkKRmVHZW5pZSA8LSBmZWdlbmllLnQKCiMtLS0tLS0tLS0tLS0tZGF0YSBwcmVwYXJhdGlvbgojIGNvbnZlcnQgdG8gZGF0YSBmcmFtZQpGZUdlbmllLmRhdGEgPC0gYXMuZGF0YS5mcmFtZShGZUdlbmllKQojRmVHZW5pZS5kYXRhPC1GZUdlbmllLmRhdGFbMSxdCiNjbGFzcyhGZUdlbmllLmRhdGEpCiMoRmVHZW5pZS5kYXRhKQoKIyAtLS0tLS0tLS0tLSBtZWx0IGRhdGEKRmVHZW5pZS5kYXRhLm1lbHQgPC0gbWVsdChGZUdlbmllLmRhdGEsIGlkLnZhcnMgPSAxOjEpCgojIHJlbmFtZSBjb2x1bW5zCmNvbG5hbWVzKEZlR2VuaWUuZGF0YS5tZWx0KVtjb2xuYW1lcyhGZUdlbmllLmRhdGEubWVsdCk9PSJ2YXJpYWJsZSJdIDwtICJJcm9uX2NhdGVnb3J5Igpjb2xuYW1lcyhGZUdlbmllLmRhdGEubWVsdClbY29sbmFtZXMoRmVHZW5pZS5kYXRhLm1lbHQpPT0idmFsdWUiXSA8LSAiTm9ybWFsaXplZF9nZW5lX2FidW5kYW5jZSIKCiMgLS0tLS0tLS0tLS0tLS0tLS0gb3V0cHV0IGZpbGVzCgpGZUdlbmllLmRhdGEubWVsdCROb3JtYWxpemVkX2dlbmVfYWJ1bmRhbmNlID0gYXMuY2hhcmFjdGVyKEZlR2VuaWUuZGF0YS5tZWx0JE5vcm1hbGl6ZWRfZ2VuZV9hYnVuZGFuY2UpCkZlR2VuaWUuZGF0YS5tZWx0JE5vcm1hbGl6ZWRfZ2VuZV9hYnVuZGFuY2UgPSBhcy5udW1lcmljKEZlR2VuaWUuZGF0YS5tZWx0JE5vcm1hbGl6ZWRfZ2VuZV9hYnVuZGFuY2UpCgpGZUdlbmllLm1ldGEucGxvdCA8LSBnZ3Bsb3QoRmVHZW5pZS5kYXRhLm1lbHQsIGFlcyh4ID0gWCwgeSA9IElyb25fY2F0ZWdvcnksIHNpemUgPSBOb3JtYWxpemVkX2dlbmVfYWJ1bmRhbmNlKSwgYWxwaGE9MC43KSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9SXJvbl9jYXRlZ29yeSkpICsKICBzY2FsZV9zaXplX2FyZWEobWF4X3NpemUgPSAxMCkgKwogIGxhYnMoeD0iIiwgeT0iSXJvbiBDYXRlZ29yeSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscz1jKCJpcm9uX2FxdWlzaXRpb24taXJvbl90cmFuc3BvcnQiID0gIklyb24gVHJhbnNwb3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpcm9uX2FxdWlzaXRpb24taGVtZV90cmFuc3BvcnQiID0gIkhlbWUgVHJhbnNwb3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpcm9uX2FxdWlzaXRpb24taGVtZV9veHlnZW5hc2UiID0gIkhlbWUgT3h5Z2VuYXNlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpcm9uX2FxdWlzaXRpb24tc2lkZXJvcGhvcmVfc3ludGhlc2lzIiA9ICJTaWRlcm9waG9yZSBTeW50aGVzaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImlyb25fYXF1aXNpdGlvbi1zaWRlcm9waG9yZV90cmFuc3BvcnQiID0gIlNpZGVyb3Bob3JlIFRyYW5zcG9ydCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaXJvbl9nZW5lX3JlZ3VsYXRpb24iID0gIklyb24gR2VuZSBSZWd1bGF0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpcm9uX294aWRhdGlvbiIgPSAiSXJvbiBPeGlkYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInBvc3NpYmxlX2lyb25fb3hpZGF0aW9uX2FuZF9wb3NzaWJsZV9pcm9uX3JlZHVjdGlvbiIgPSAiUHJvYmFibGUgSXJvbiBPeGlkYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInByb2JhYmxlX2lyb25fcmVkdWN0aW9uIiA9ICJQcm9iYWJsZSBJcm9uIFJlZHVjdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaXJvbl9yZWR1Y3Rpb24iID0gIklyb24gUmVkdWN0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpcm9uX3N0b3JhZ2UiID0gIklyb24gU3RvcmFnZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWFnbmV0b3NvbWVfZm9ybWF0aW9uIiA9ICJNYWduZXRvc29tZSBGb3JtYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImlyb25fYXF1aXNpdGlvbi1pcm9uX3VwdGFrZSIgPSAiSXJvbiBVcHRha2UiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpcm9uX2FxdWlzaXRpb24taGVtZV91cHRha2UiID0gIkhlbWUgVXB0YWtlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaXJvbl9hcXVpc2l0aW9uLWhlbWVfbHlhc2UiID0gIkhlbWUgTHlhc2UiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpcm9uX2FxdWlzaXRpb24tc2lkZXJvcGhvcmVfdXB0YWtlIiA9ICJTaWRlcm9waG9yZSBVcHRha2UiKSkgKwogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxLCBsaW5ldHlwZSA9ICJzb2xpZCIpLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXI9ImJsYWNrIiwgc2l6ZT0xLCBmaWxsPU5BKSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChmaWxsPSd3aGl0ZScsIGNvbG91cj0nd2hpdGUnKSwKICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQiLCBzaXplPTEwKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjEsIGNvbG91ciA9ICJncmF5IiksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShzaXplID0gMC4xLCBjb2xvdXIgPSAiZ3JheSIpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyLCBjb2xvdXI9ImJsYWNrIiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMSwgYW5nbGUgPSAyNzAsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEyLCBoanVzdD0xKSwgbGVnZW5kLnBvc2l0aW9uPSJyaWdodCIpICsgZ3VpZGVzKGNvbG9yID0gRkFMU0UpICsgbGFicyhzaXplPSJOb3JtYWxpemVkXG5HZW5lIEFidW5kYW5jZSIpCmBgYAoKYGBge3J9CkZlR2VuaWUubWV0YS5wbG90CmBgYAoKIyMjIyA3LjUuMi4gVHVzcyBGZUdlbmllCgpQbG90IHRoZSByZWxhdGl2ZSBpcm9uIGdlbmUgYWJ1bmRhbmNlIGRhdGEgZnJvbSB0aGUgTWV0YWdlbm9tZXMgKE1HKSBhbmQgTWV0YXRyYW5zY3JpcHRvbWVzIChNVCkgd2l0aGluIFR1c3MuCmBgYHtyLCBlY2hvPUZBTFNFfQp0dXNzX2RuYV9mZWdlbmllX2JhcmRhdGE8LXJlYWQuY3N2KCJQbG90LkRhdGEvdHVzcy5kbmEuZmVnZW5pZS5iYXJwbG90LmNzdiIpCmBgYAoKYGBge3Igd2FybmluZz1GQUxTRX0KIyBQbGFjZSBjYXRlZ29yaWVzIGluIHRoZSBwcmVmZXJyZWQgb3JkZXIgZm9yIHBsb3R0aW5nCnR1c3NfZG5hX2ZlZ2VuaWVfYmFyZGF0YSRJcm9uIDwtIGZhY3Rvcih0dXNzX2RuYV9mZWdlbmllX2JhcmRhdGEkSXJvbixsZXZlbHMgPSBjKCJJcm9uIE94aWRhdGlvbiIsICJJcm9uIFJlZHVjdGlvbiIsICJTaWRlcm9waG9yZSBUcmFuc3BvcnQiLCAiSXJvbiBTdG9yYWdlIikpCgp0dXNzX2RuYV9mZWdlbmllX2JhcmRhdGEkU2FtcGxlIDwtIGZhY3Rvcih0dXNzX2RuYV9mZWdlbmllX2JhcmRhdGEkU2FtcGxlLGxldmVscz1jKCJUdXNzLU1HIiwiVHVzcy1NVC1UMCIsIlR1c3MtTVQtVDQiLCJUdXNzLU1ULVQyNCIpKQoKdHVzc19kbmFfZmVnZW5pZV9iYXJwbG90PC1nZ3Bsb3QodHVzc19kbmFfZmVnZW5pZV9iYXJkYXRhLCBhZXMoeCA9IElyb24sIHkgPSBNZWFuLCBmaWxsID0gU2FtcGxlKSkgKyBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvcj0iYmxhY2siKSArIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBNZWFuIC0gU0QsIHltYXggPSBNZWFuICsgU0QpLCB3aWR0aCA9IDAuMiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpKSArIHlsYWIoZXhwcmVzc2lvbihhdG9wKCJNaWNyb2JpYWwgSXJvbiBHZW5lcyIsIHBhc3RlKCJSZWxhdGl2ZSBBYnVuZGFuY2UgKCUpIikpKSkgKyB0aGVtZV9jbGFzc2ljKCkgKyB0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApLCBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTEyKSwgYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9OCksIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSkgKyBzY2FsZV9zaXplKGd1aWRlPUZBTFNFKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJibGFjayIsICJwYWxlZ3JlZW4iLCAiZ3JlZW4zIiwgImRhcmtncmVlbiIpKSArIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oSXJvbikgc3RyX3dyYXAoSXJvbiwgd2lkdGggPSAxMCkpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgMTAwKSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0wLjksIHk9MTIsIGxhYmVsPSJhIikgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0xLjEyLCB5PTIyLCBsYWJlbD0iYiIpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9MS4zNSwgeT0xOCwgbGFiZWw9ImFiIikgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0yLjEyLCB5PTEyLCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0zLjEyLCB5PTcwLCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD00LjEyLCB5PTUwLCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkgKyBnZW9tX3NlZ21lbnQoYWVzKHggPSAxLjEyLCB5ID0gMzUsIHhlbmQgPSAxLjEyLCB5ZW5kID0gNTApKSArIGdlb21fc2VnbWVudChhZXMoeCA9IDEuMTIsIHkgPSA1MCwgeGVuZCA9IDIuMTIsIHllbmQgPSA1MCkpICsgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMi4xMiwgeSA9IDUwLCB4ZW5kID0gMi4xMiwgeWVuZCA9IDIwKSkgKyBhbm5vdGF0ZSgidGV4dCIsIHggPSAxLjYzNSwgeSA9IDU0LCBzaXplPTMsIGxhYmVsID0gIlBhaXJlZH50LXRlc3R+KGl0YWxpYyhwKSA9PSAwLjAwNCkiLCBwYXJzZSA9IFRSVUUpICsgYW5ub3RhdGUoInRleHQiLCB4ID0gMS42MzUsIHkgPSA2MSwgc2l6ZT00LCBsYWJlbCA9ICJNZWFuIE1UIERpZmZlcmVuY2UgKDglKSIpCmBgYAoKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KdHVzc19kbmFfZmVnZW5pZV9iYXJwbG90CmBgYAoKYGBge3IgZWNobz1GQUxTRX0KdHVzc19kbmFfZmVnZW5pZV9yZWRveF9iYXJkYXRhPC1yZWFkLmNzdigiUGxvdC5EYXRhL3R1c3MuZG5hLmZlZ2VuaWUucmVkb3guYmFycGxvdC5jc3YiKQpgYGAKCmBgYHtyfQojIFBsYWNlIGNhdGVnb3JpZXMgaW4gdGhlIHByZWZlcnJlZCBvcmRlciBmb3IgcGxvdHRpbmcKdHVzc19kbmFfZmVnZW5pZV9yZWRveF9iYXJkYXRhJElyb24gPC0gZmFjdG9yKHR1c3NfZG5hX2ZlZ2VuaWVfcmVkb3hfYmFyZGF0YSRJcm9uLGxldmVscyA9IGMoIklyb24gT3hpZGF0aW9uIiwgIklyb24gUmVkdWN0aW9uIikpCgp0dXNzX2RuYV9mZWdlbmllX3JlZG94X2JhcmRhdGEkU2FtcGxlIDwtIGZhY3Rvcih0dXNzX2RuYV9mZWdlbmllX3JlZG94X2JhcmRhdGEkU2FtcGxlLGxldmVscz1jKCJUdXNzLU1HIiwiVHVzcy1NVC1UMCIsIlR1c3MtTVQtVDQiLCJUdXNzLU1ULVQyNCIpKQoKdHVzc19kbmFfZmVnZW5pZV9yZWRveF9iYXJwbG90PC1nZ3Bsb3QodHVzc19kbmFfZmVnZW5pZV9yZWRveF9iYXJkYXRhLCBhZXMoeCA9IElyb24sIHkgPSBNZWFuLCBmaWxsID0gU2FtcGxlKSkgKyBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvcj0iYmxhY2siKSArIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBNZWFuIC0gU0QsIHltYXggPSBNZWFuICsgU0QpLCB3aWR0aCA9IDAuMiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpKSArIHlsYWIoZXhwcmVzc2lvbihhdG9wKCJJcm9uIFJlZG94IEN5Y2xpbmcgR2VuZXMiLCBwYXN0ZSgiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpKSkpICsgdGhlbWVfY2xhc3NpYygpICsgdGhlbWUoYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTEwKSwgYXhpcy50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xMiksIGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCkpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTgpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X2JsYW5rKCkpICsgc2NhbGVfc2l6ZShndWlkZT1GQUxTRSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiZ3JheTgzIiwgInBhbGVncmVlbiIsICJncmVlbjMiLCAiZGFya2dyZWVuIikpICsgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBmdW5jdGlvbihJcm9uKSBzdHJfd3JhcChJcm9uLCB3aWR0aCA9IDEwKSkgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSwgbGltaXRzID0gYygwLCA0MCkpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9MC44OSwgeT04LCBsYWJlbD0iYSIpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9MS4xMiwgeT0xOCwgbGFiZWw9ImIiKSArIGFubm90YXRlKGdlb209InRleHQiLCB4PTEuMzUsIHk9MTMsIGxhYmVsPSJhYiIpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9Mi4xMiwgeT00LCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkgKyBnZW9tX3NlZ21lbnQoYWVzKHggPSAxLjEyLCB5ID0gMjIsIHhlbmQgPSAxLjEyLCB5ZW5kID0gMzApKSArIGdlb21fc2VnbWVudChhZXMoeCA9IDEuMTIsIHkgPSAzMCwgeGVuZCA9IDIuMTIsIHllbmQgPSAzMCkpICsgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMi4xMiwgeSA9IDMwLCB4ZW5kID0gMi4xMiwgeWVuZCA9IDcpKSArIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDEuNjM1LCB5ID0gMzIsIHNpemU9MywgbGFiZWwgPSAiUGFpcmVkfnQtdGVzdH4oaXRhbGljKHApID09IDAuMDA0KSIsIHBhcnNlID0gVFJVRSkgKyBhbm5vdGF0ZSgidGV4dCIsIHggPSAxLjYzNSwgeSA9IDM0LCBzaXplPTQsIGxhYmVsID0gIk1lYW4gTVQgRGlmZmVyZW5jZSAoNDN4KSIpCmBgYAoKYGBge3J9CnR1c3NfZG5hX2ZlZ2VuaWVfcmVkb3hfYmFycGxvdApgYGAKClJ1biBzdGF0aXN0aWNhbCB0ZXN0cyBvbiB0aGUgTUVUQVRSQU5TQ1JJUFRPTUVTIHRvIGRldGVybWluZSBpZiBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBleGlzdCBiZXR3ZWVuIHNhbXBsaW5nIHRpbWVwb2ludHMgZm9yIGVhY2ggaXJvbiBnZW5lIGNhdGVnb3J5IC4KCmBgYHtyIGVjaG89RkFMU0V9CnR1c3NfZmVnZW5pZV9zdGF0czwtcmVhZC5jc3YoIlN0YXRzLkRhdGEvdHVzcy5mZWdlbmllLnN0YXRzLmNzdiIpCmBgYAoKYGBge3J9CiMgU3Vic2V0IHJlc3BvbnNlIHZhcmlhYmxlcyBmb3IgTUFOT1ZBCnR1c3NfZmVnZW5pZV9zdGF0cyRyZXNwb25zZSA8LSBhcy5tYXRyaXgodHVzc19mZWdlbmllX3N0YXRzWywgMjo1XSkKYGBgCgpgYGB7cn0KIyBNQU5PVkEgdGVzdAp0dXNzX2ZlZ2VuaWVfbWFub3ZhIDwtIG1hbm92YShyZXNwb25zZSB+IFRpbWVwb2ludCwgZGF0YT10dXNzX2ZlZ2VuaWVfc3RhdHMpCnN1bW1hcnkuYW92KHR1c3NfZmVnZW5pZV9tYW5vdmEpCgojIyBSdW4gQU5PVkEgZm9yIGVhY2ggY2F0ZWdvcnkgb2YgaW50ZXJlc3QgKHNpZ25pZmljYW50IGluIE1BTk9WQSkKCiMgSXJvbiBPeGlkYXRpb24KdHVzc19mZWdlbmllX3N0YXQxPC1hb3YoSXJvbi5PeGlkYXRpb25+VGltZXBvaW50LGRhdGE9dHVzc19mZWdlbmllX3N0YXRzKQpzdW1tYXJ5LmFvdih0dXNzX2ZlZ2VuaWVfc3RhdDEpClR1a2V5SFNEKHR1c3NfZmVnZW5pZV9zdGF0MSkKCiMgdC10ZXN0IGZvciBkaWZmZXJlbmNlcyBiZXR3ZWVuIHJlZHVjdGlvbiBhbmQgb3hpZGF0aW9uIGF2ZXJhZ2VkIGFjcm9zcyBleHBlcmltZW50CnQudGVzdCh0dXNzX2ZlZ2VuaWVfc3RhdHMkSXJvbi5PeGlkYXRpb24sdHVzc19mZWdlbmllX3N0YXRzJElyb24uUmVkdWN0aW9uLHBhaXJlZD1UUlVFKQpgYGAKCiMjIyMgNy41LjMuIFdTIEZlR2VuaWUKClBsb3QgdGhlIHJlbGF0aXZlIGlyb24gZ2VuZSBhYnVuZGFuY2UgZGF0YSBmcm9tIHRoZSBNZXRhZ2Vub21lcyAoTUcpIGFuZCBNZXRhdHJhbnNjcmlwdG9tZXMgKE1UKSB3aXRoaW4gV1MuIApgYGB7ciwgZWNobz1GQUxTRX0Kd3NfZG5hX2ZlZ2VuaWVfYmFyZGF0YTwtcmVhZC5jc3YoIlBsb3QuRGF0YS93cy5kbmEuZmVnZW5pZS5iYXJwbG90LmNzdiIpCmBgYAoKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBQbGFjZSBjYXRlZ29yaWVzIGluIHRoZSBwcmVmZXJyZWQgb3JkZXIgZm9yIHBsb3R0aW5nCndzX2RuYV9mZWdlbmllX2JhcmRhdGEkSXJvbiA8LSBmYWN0b3Iod3NfZG5hX2ZlZ2VuaWVfYmFyZGF0YSRJcm9uLGxldmVscyA9IGMoIklyb24gT3hpZGF0aW9uIiwgIklyb24gUmVkdWN0aW9uIiwgIlNpZGVyb3Bob3JlIFRyYW5zcG9ydCIsICJJcm9uIFN0b3JhZ2UiKSkKCndzX2RuYV9mZWdlbmllX2JhcmRhdGEkU2FtcGxlIDwtIGZhY3Rvcih3c19kbmFfZmVnZW5pZV9iYXJkYXRhJFNhbXBsZSxsZXZlbHM9YygiV1MtTUciLCJXUy1NVC1UMCIsIldTLU1ULVQ0IiwiV1MtTVQtVDI0IikpCgp3c19kbmFfZmVnZW5pZV9iYXJwbG90PC1nZ3Bsb3Qod3NfZG5hX2ZlZ2VuaWVfYmFyZGF0YSwgYWVzKHggPSBJcm9uLCB5ID0gTWVhbiwgZmlsbCA9IFNhbXBsZSkpICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKyBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbiAtIFNELCB5bWF4ID0gTWVhbiArIFNEKSwgd2lkdGggPSAwLjIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSkgKyB5bGFiKGV4cHJlc3Npb24oYXRvcCgiTWljcm9iaWFsIElyb24gR2VuZXMiLCBwYXN0ZSgiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpKSkpICsgdGhlbWVfY2xhc3NpYygpICsgdGhlbWUoYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTEwKSwgYXhpcy50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xMiksIGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCkpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTgpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X2JsYW5rKCkpICsgc2NhbGVfc2l6ZShndWlkZT1GQUxTRSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiYmxhY2siLCJsaWdodHNreWJsdWUxIiwgImRvZGdlcmJsdWUxIiwgIm1pZG5pZ2h0Ymx1ZSIpKSArIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gZnVuY3Rpb24oSXJvbikgc3RyX3dyYXAoSXJvbiwgd2lkdGggPSAxMCkpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgMTAwKSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0xLjEyLCB5PTIwLCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0yLjEyLCB5PTMwLCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0zLjEyLCB5PTYwLCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD00LjEyLCB5PTYwLCBsYWJlbD0iaXRhbGljKE4uUy4pIiwgcGFyc2U9VFJVRSkgKyBnZW9tX3NlZ21lbnQoYWVzKHggPSAxLjEyLCB5ID0gMzAsIHhlbmQgPSAxLjEyLCB5ZW5kID0gNTApKSArIGdlb21fc2VnbWVudChhZXMoeCA9IDEuMTIsIHkgPSA1MCwgeGVuZCA9IDIuMTIsIHllbmQgPSA1MCkpICsgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMi4xMiwgeSA9IDUwLCB4ZW5kID0gMi4xMiwgeWVuZCA9IDQ1KSkgKyBhbm5vdGF0ZSgidGV4dCIsIHggPSAxLjYzNSwgeSA9IDU0LCBzaXplPTMsIGxhYmVsID0gIlBhaXJlZH50LXRlc3R+KGl0YWxpYyhwKSA9PSAwLjAwNSkiLCBwYXJzZSA9IFRSVUUpICsgYW5ub3RhdGUoInRleHQiLCB4ID0gMS42MzUsIHkgPSA2MSwgc2l6ZT00LCBsYWJlbCA9ICJNZWFuIE1UIERpZmZlcmVuY2UgKDE0JSkiKQpgYGAKCmBgYHtyIGVjaG89RkFMU0V9CndzX2RuYV9mZWdlbmllX2JhcnBsb3QKYGBgCgpgYGB7ciBlY2hvPUZBTFNFfQp3c19kbmFfZmVnZW5pZV9yZWRveF9iYXJkYXRhPC1yZWFkLmNzdigiUGxvdC5EYXRhL3dzLmRuYS5mZWdlbmllLnJlZG94LmJhcnBsb3QuY3N2IikKYGBgCgpgYGB7cn0KIyBQbGFjZSBjYXRlZ29yaWVzIGluIHRoZSBwcmVmZXJyZWQgb3JkZXIgZm9yIHBsb3R0aW5nCndzX2RuYV9mZWdlbmllX3JlZG94X2JhcmRhdGEkSXJvbiA8LSBmYWN0b3Iod3NfZG5hX2ZlZ2VuaWVfcmVkb3hfYmFyZGF0YSRJcm9uLGxldmVscyA9IGMoIklyb24gT3hpZGF0aW9uIiwgIklyb24gUmVkdWN0aW9uIikpCgp3c19kbmFfZmVnZW5pZV9yZWRveF9iYXJkYXRhJFNhbXBsZSA8LSBmYWN0b3Iod3NfZG5hX2ZlZ2VuaWVfcmVkb3hfYmFyZGF0YSRTYW1wbGUsbGV2ZWxzPWMoIldTLU1HIiwiV1MtTVQtVDAiLCJXUy1NVC1UNCIsIldTLU1ULVQyNCIpKQoKd3NfZG5hX2ZlZ2VuaWVfcmVkb3hfYmFycGxvdDwtZ2dwbG90KHdzX2RuYV9mZWdlbmllX3JlZG94X2JhcmRhdGEsIGFlcyh4ID0gSXJvbiwgeSA9IE1lYW4sIGZpbGwgPSBTYW1wbGUpKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGNvbG9yID0gImJsYWNrIikgKyBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbiAtIFNELCB5bWF4ID0gTWVhbiArIFNEKSwgd2lkdGggPSAwLjIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSkgKyB5bGFiKGV4cHJlc3Npb24oYXRvcCgiSXJvbiBSZWRveCBDeWNsaW5nIEdlbmVzIiwgcGFzdGUoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSkpKSArIHRoZW1lX2NsYXNzaWMoKSArIHRoZW1lKGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xMCksIGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTIpLCBheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLCBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpLCBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT04KSwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpKSArIHNjYWxlX3NpemUoZ3VpZGU9RkFMU0UpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoImJsYWNrIiwibGlnaHRza3libHVlMSIsICJkb2RnZXJibHVlMSIsICJtaWRuaWdodGJsdWUiKSkgKyBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGZ1bmN0aW9uKElyb24pIHN0cl93cmFwKElyb24sIHdpZHRoID0gMTApKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIDQwKSkgKyBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD0xLjEyLCB5PTguNSwgbGFiZWw9Iml0YWxpYyhOLlMuKSIsIHBhcnNlPVRSVUUpICsgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIHg9Mi4xMiwgeT0yNSwgbGFiZWw9Iml0YWxpYyhOLlMuKSIsIHBhcnNlPVRSVUUpICsgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMS4xMiwgeSA9IDEwLCB4ZW5kID0gMS4xMiwgeWVuZCA9IDMwKSkgKyBnZW9tX3NlZ21lbnQoYWVzKHggPSAxLjEyLCB5ID0gMzAsIHhlbmQgPSAyLjEyLCB5ZW5kID0gMzApKSArIGdlb21fc2VnbWVudChhZXMoeCA9IDIuMTIsIHkgPSAzMCwgeGVuZCA9IDIuMTIsIHllbmQgPSAyNykpICsgYW5ub3RhdGUoInRleHQiLCB4ID0gMS42MzUsIHkgPSAzMiwgc2l6ZT0zLCBsYWJlbCA9ICJQYWlyZWR+dC10ZXN0fihpdGFsaWMocCkgPT0gMC4wMDUpIiwgcGFyc2UgPSBUUlVFKSArIGFubm90YXRlKCJ0ZXh0IiwgeCA9IDEuNjM1LCB5ID0gMzQsIHNpemU9NCwgbGFiZWwgPSAiTWVhbiBNVCBEaWZmZXJlbmNlICg0eCkiKQpgYGAKCmBgYHtyfQp3c19kbmFfZmVnZW5pZV9yZWRveF9iYXJwbG90CmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9CiMgU2F2ZSB0aGUgVFVTUyBhbmQgV1MgRmVHZW5pZSBiYXJwbG90cyB0b2dldGhlcgpzZXRFUFMoKQpwb3N0c2NyaXB0KCJGaWcuNC5NVC5GZUdlbmllLmVwcyIsIHdpZHRoPTEwLjAsIGhlaWdodCA9IDUuMCkKZ2dhcnJhbmdlKHR1c3NfZG5hX2ZlZ2VuaWVfcmVkb3hfYmFycGxvdCwgd3NfZG5hX2ZlZ2VuaWVfcmVkb3hfYmFycGxvdCwgaGVpZ2h0cz1jKDUsNSksCiAgICAgICAgICBsYWJlbHMgPSBjKCJBIiwiQiIpLAogICAgICAgICAgbmNvbCA9IDIsIG5yb3cgPSAxLCBhbGlnbj0idiIpCmRldi5vZmYoKQpgYGAKClJ1biBzdGF0aXN0aWNhbCB0ZXN0cyBvbiB0aGUgTUVUQVRSQU5TQ1JJUFRPTUVTIHRvIGRldGVybWluZSBpZiBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBleGlzdCBiZXR3ZWVuIHNhbXBsaW5nIHRpbWVwb2ludHMgZm9yIGVhY2ggaXJvbiBnZW5lIGNhdGVnb3J5LgoKYGBge3IgZWNobz1GQUxTRX0Kd3NfZmVnZW5pZV9zdGF0czwtcmVhZC5jc3YoIlN0YXRzLkRhdGEvd3MuZmVnZW5pZS5zdGF0cy5jc3YiKQpgYGAKCmBgYHtyfQojIFN1YnNldCByZXNwb25zZSB2YXJpYWJsZXMgZm9yIE1BTk9WQQp3c19mZWdlbmllX3N0YXRzJHJlc3BvbnNlIDwtIGFzLm1hdHJpeCh3c19mZWdlbmllX3N0YXRzWywgMjo1XSkKCiMgTUFOT1ZBIHRlc3QKd3NfZmVnZW5pZV9tYW5vdmEgPC0gbWFub3ZhKHJlc3BvbnNlIH4gVGltZXBvaW50LCBkYXRhPXdzX2ZlZ2VuaWVfc3RhdHMpCnN1bW1hcnkuYW92KHdzX2ZlZ2VuaWVfbWFub3ZhKQoKIyB0LXRlc3QgZm9yIGRpZmZlcmVuY2VzIGJldHdlZW4gcmVkdWN0aW9uIGFuZCBveGlkYXRpb24gYXZlcmFnZWQgYWNyb3NzIGV4cGVyaW1lbnQKdC50ZXN0KHdzX2ZlZ2VuaWVfc3RhdHMkSXJvbi5PeGlkYXRpb24sd3NfZmVnZW5pZV9zdGF0cyRJcm9uLlJlZHVjdGlvbixwYWlyZWQ9VFJVRSkKYGBgCgojIyMjIDcuNS40LiBGZXJyb3B0b3NpcwoKRmVycm9wdG9zaXMgaXMgYSBmb3JtIG9mIHJlZ3VsYXRlZCBjZWxsIGRlYXRoIHRoYXQgcmVzdWx0cyBmcm9tIHRoZSBpcm9uLWRlcGVuZGVudCBhY2N1bXVsYXRpb24gb2YgbGlwaWQgcGVyb3hpZGVzIGFzc29jaWF0ZWQgd2l0aCByZWFjdGl2ZSBveHlnZW4gc3BlY2llcyBzdWNoIGFzIGh5ZHJveHlsIHJhZGljYWwuICBIZXJlLCBpdCBpcyBsaWtlbHkgdGhhdCBnZW5lIGV4cHJlc3Npb24gZm9yIGZlcnJvcHRvc2lzIGlzIGRpcmVjdGx5IGxpbmtlZCB3aXRoIHRoZSBvdmVycHJvZHVjdGlvbiBvZiBoeWRyb3h5bCByYWRpY2FsIGdpdmVuIHRoYXQgaHlkcm94eWwgcmFkaWNhbCBwcm9kdWN0aW9uIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2VvY2hlbWljYWwgb3hpZGF0aW9uIG9mIEZlKElJKSBoYXMgYmVlbiBzaG93biB0byBpbmNyZWFzZSBpbiB0dXNzb2NrIHR1bmRyYSBmb2xsb3dpbmcgcmFpbmZhbGwuICBIb3dldmVyLCBsaXR0bGUgaXMga25vd24gYWJvdXQgdGhlIHJlZ3VsYXRpb24gb2YgZmVycm9wdG9zaXMgaW4gc29pbCBlbnZpcm9ubWVudHMgb3IgZXZlbiBob3cgaXQgaXMgcmVndWxhdGVkIHdpdGhpbiBtaWNyb2JpYWwgY2VsbHMgcmVnYXJkbGVzcyBvZiBlbnZpcm9ubWVudC4gIE1vcmUgc3R1ZGllcyBuZWVkIHRvIGJlIGRvbmUgdG8gZGV0ZXJtaW5lIGFueSBkaXJlY3QgbGluayBiZXR3ZWVuIGh5ZHJveHlsIHJhZGljYWwgcHJvZHVjdGlvbiBhbmQgZmVycm9wdG9zaXMgZ2VuZSBleHByZXNzaW9uIGZvbGxvd2luZyByYWluZmFsbC4KYGBge3J9CnR1c3NfZmVycm9wdG9zaXM8LXRwbV9hbGxfZXhwX2FubgoKdHVzc19mZXJyb3B0b3Npczwtc3Vic2V0KHR1c3NfZmVycm9wdG9zaXMsIFRpZXJfSVY9PSIwNDIxNiBGZXJyb3B0b3NpcyBbUEFUSDprbzA0MjE2XSIsCnNlbGVjdD1JRDpUYXhvbm9teSkKdHVzc19mZXJyb3B0b3NpcwpgYGAKCiMgUmVwcm9kdWNpYmlsaXR5CgpUaGUgc2Vzc2lvbiBpbmZvcm1hdGlvbiBpcyBwcm92aWRlZCBmb3IgZnVsbCByZXByb2R1Y2liaWxpdHkuCmBgYHtyfQpkZXZ0b29sczo6c2Vzc2lvbl9pbmZvKCkKYGBg