# Import metadata
metadata <-read.csv("~/Documents/gbru_fy18_rice_methane/march2020/metadata_biomassCH4_noRIL9.csv", header=TRUE)
Explore uni-variate distributions of data
library(tidyverse)
metadata %>%
keep(is.numeric) %>%
gather() %>%
ggplot(aes(value)) +
facet_wrap(~ key, scales = "free") +
geom_histogram(bins=12)

Genotype vs Sum Methane
d <- ggplot(metadata, aes(genotype, sum_ch4))
d + geom_point(aes(color=dev))

Total methane is highly consistent across treatment time point for each genotype.
Genotype vs Daily Methane
d <- ggplot(metadata, aes(genotype, daily_ch4))
d + geom_point(aes(color=dev))

D2 is the high methane producing time-point
Total methane and root biomass
d <- ggplot(metadata[metadata$dev=="D3",], aes(sum_ch4, root_biomass_2017))
d + geom_point(aes(colour = factor(genotype)))

Total methane and shoot biomass
d <- ggplot(metadata[metadata$dev=="D3",], aes((sum_ch4), log10(shoot_root_ratio2017)))
d + geom_point(aes(colour = factor(genotype)))

Load taxonomic count data
# Import OTU counts
otudata<-read.table("~/Documents/gbru_fy18_rice_methane/march2020/otu_table.tsv", header=TRUE)
# Move feature ID to rownames
row.names(otudata)<-otudata$feature.id
otudata<-otudata[,-1]
# Sort columns by name
otudata<- otudata[, order(names(otudata))]
# load Taxonomy annotation
taxa <- read.table("~/Documents/gbru_fy18_rice_methane/march2020/observation_meta_data.tsv", sep="\t", header=TRUE, quote = "")
Define function to filter taxa with low abundance and many zeros
#Define the geometric mean for all values greater than 0
geomean <- function(x) { exp(mean(log(x[x>0]))) }
# Create a function to filter rows by the proportion of nonzero samples and the geometric mean of the nonzero samples
prefilter <- function(x, zcutoff, mcutoff){
nzvect <- apply(x, 1, function(y){
((sum(y>0)/length(y))> zcutoff) & (geomean(y)> mcutoff)
})
lowcounts <- t(as.data.frame(apply(x[!nzvect,],2,sum)))
rownames(lowcounts)<-c("lowconts")
df1 <-rbind(lowcounts, x[nzvect,])
return(df1)
}
Group by Family and Genus
Initial tests of un-grouped and unfiltered data returned no significant taxa. Independent filtering by depth is something which has been done in DESeq2 and EdgeR and is considered a valid preselection technique.
#Filter data to specific taxonomic levels
cdata <-cbind(taxa,otudata)
library(dplyr)
library(tidyr)
fd_long<- gather(cdata, sample, count, colnames(cdata)[10:105], factor_key=TRUE)
#group by family
fd_fam_tally <- fd_long[,c(7,10,11)] %>% group_by(taxonomy_5, sample) %>% summarise(n = sum(count))
fd_fam_wide <- pivot_wider(fd_fam_tally, names_from= sample, values_from=n)
df_fam_wide<- as.data.frame(fd_fam_wide)
rownames(df_fam_wide)<- df_fam_wide[,1]
df_fam_wide<- df_fam_wide[,-1]
otutaxa_fam<-prefilter(df_fam_wide, 0.5, 100)
#group by genus
fd_genus_tally <- fd_long[,c(8,10,11)] %>% group_by(taxonomy_6, sample) %>% summarise(n = sum(count))
fd_genus_wide <- fd_genus_tally %>% pivot_wider(names_from= sample, values_from=n)
df_genus_wide<- as.data.frame(fd_genus_wide)
rownames(df_genus_wide)<- df_genus_wide[,1]
df_genus_wide<- df_genus_wide[,-1]
otutaxa_genus<-prefilter(df_genus_wide, 0.5, 100)
ALDEx2 statistical analysis for compositional count data at the family level
library("ALDEx2")
# Construct covariates matrix
covariates1 <- data.frame(genotype=metadata$genotype, sumch4=log10(metadata$sum_ch4), dev=metadata$dev)
# Process
#select D3 developmental stage
d3cov<- covariates1[covariates1$dev=="D3",]
d3cov<-d3cov[1:30,]
d3rows <- as.numeric(rownames(d3cov))
d3otus <- otutaxa_fam[,d3rows]
# create model matrix for log10 of total methane
mm1 <- model.matrix(~ sumch4, d3cov)
Fit a GLM on total methane
# run CLR transformations and sampling
d3ch4fam.clr.glm<- aldex.glm(d3ch4fam.clr, verbose=TRUE)
running tests for each MC instance:
|------------(25%)----------(50%)----------(75%)----------|
d3ch4fam.clr.glm[d3ch4fam.clr.glm$`model.sumch4 Pr(>|t|).BH`<0.5,]
Results
Because there are no significant taxa after BH correction. The challenge of regressing this data is that each sample does not have its own menthane measurment whic reduces the degrees of freedom
Do a correlation test
corr.test.fam <- aldex.corr(d3ch4fam.clr, d3cov$sumch4)
Results
Eight families have a signifigant statistical association with methane in the correlation test
corr.test.fam[corr.test.fam$BH<0.05,]
hist(corr.test.fam$BH)

ALDEx22 statistical analysis for compositional count data at the Genus Level
Fit a GLM on total methane
# run CLR transformations and sampling
d3ch4genus.clr.glm<- aldex.glm(d3ch4genus.clr, verbose=TRUE)
running tests for each MC instance:
|------------(25%)----------(50%)----------(75%)----------|
Results
Because there are no significant taxa after BH correction. The challenge of regressing this data is that each sample does not have its own menthane measurment whic reduces the degrees of freedom
d3ch4genus.clr.glm[d3ch4genus.clr.glm$`model.sumch4 Pr(>|t|).BH`<0.5,]
Do a correlation test
corr.test.fam <- aldex.corr(d3ch4genus.clr, d3cov$sumch4)
Results
Eight families have a signifigant statistical association with methane in the correlation test
corr.test.fam[corr.test.fam$BH<0.10,]
# New apprach: Split methane into a categoical variable and do a Welche’s test on high vs low methane
# Construct covariates matrix
covariates2 <- data.frame(genotype=metadata$genotype, sumch4=log10(metadata$sum_ch4), dev=metadata$dev)
# Process
#select D3 developmental stage
d3cov<- covariates2[covariates2$dev=="D3",]
d3cov<-d3cov[1:30,]
d3cov$methfactor<-cut(d3cov$sumch4,breaks=2)
d3rows <- as.numeric(rownames(d3cov))
d3otus <- otutaxa_fam[,d3rows]
# create model matrix for log10 of total methane
mm1 <- model.matrix(~ methfactor, d3cov)
hlmeth.clr <- aldex.clr(d3otus, as.character(d3cov$methfactor), mc.samples=128, denom="iqlr")
operating in serial mode
computing iqlr centering
hlmeth.test <- aldex.ttest(hlmeth.clr, hist.plot=TRUE )

hlmeth.test[hlmeth.test$we.eBH<0.1,]
## Results Spliting into high and low methane at D2 did not highlihght new groups.
# Run the methane GLM anaysis for timepoint D2
## Construct new covariates matrix
covariates1 <- data.frame(genotype=metadata$genotype, sumch4=log10(metadata$sum_ch4), dev=metadata$dev)
# Process
#select D3 developmental stage
d2cov<- covariates1[covariates1$dev=="D2",]
d2cov<-d2cov[1:30,] # Remove soil samples
d2rows <- as.numeric(rownames(d2cov))
d2otus <- otutaxa_fam[,d2rows]
# create model matrix for log10 of total methane
mm2 <- model.matrix(~ sumch4, d2cov)
Fit a GLM on total methane
# run CLR transformations and sampling
d2ch4fam.clr.glm<- aldex.glm(d2ch4fam.clr, verbose=TRUE)
running tests for each MC instance:
|------------(25%)----------(50%)----------(75%)----------|
d2ch4fam.clr.glm[d2ch4fam.clr.glm$`model.sumch4 Pr(>|t|).BH`<0.5,]
Results
There were no signifigant effects at stage D2
#Test RIL6 (lowest emitter) and RIL1 (highest emmitter) at D3
c16<-covariates1[covariates1$genotype %in% c("RIL1", "RIL6") & covariates1$dev=="D3",]
c16rows <- as.numeric(rownames(c16))
c16otus <- otutaxa_fam[,c16rows]
hlgeno.clr <- aldex.clr(c16otus, c16$genotype, mc.samples=128, denom="iqlr")
operating in serial mode
computing iqlr centering
hlgeno.test <- aldex.ttest(hlmeth.clr, hist.plot=TRUE )

# run CLR transformations and sampling
hlgeno.test[hlgeno.test$we.eBH<0.1,]
LS0tCnRpdGxlOiAiRXhwbG9yYXRvcnkgYW5hbHlzaXMgb2YgcmljZSBtZXRoYW5lIGRhdGEgc2V0IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgoKYGBge3J9CiMgSW1wb3J0IG1ldGFkYXRhCm1ldGFkYXRhIDwtcmVhZC5jc3YoIn4vRG9jdW1lbnRzL2dicnVfZnkxOF9yaWNlX21ldGhhbmUvbWFyY2gyMDIwL21ldGFkYXRhX2Jpb21hc3NDSDRfbm9SSUw5LmNzdiIsIGhlYWRlcj1UUlVFKQpgYGAKCiMgRXhwbG9yZSB1bmktdmFyaWF0ZSBkaXN0cmlidXRpb25zIG9mIGRhdGEKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQptZXRhZGF0YSAlPiUKICBrZWVwKGlzLm51bWVyaWMpICU+JSAKICBnYXRoZXIoKSAlPiUgCiAgZ2dwbG90KGFlcyh2YWx1ZSkpICsKICAgIGZhY2V0X3dyYXAofiBrZXksIHNjYWxlcyA9ICJmcmVlIikgKwogICAgZ2VvbV9oaXN0b2dyYW0oYmlucz0xMikKYGBgCgojIEdlbm90eXBlIHZzIFN1bSBNZXRoYW5lCmBgYHtyfQpkIDwtIGdncGxvdChtZXRhZGF0YSwgYWVzKGdlbm90eXBlLCBzdW1fY2g0KSkKZCArIGdlb21fcG9pbnQoYWVzKGNvbG9yPWRldikpCgpgYGAKVG90YWwgbWV0aGFuZSBpcyBoaWdobHkgY29uc2lzdGVudCBhY3Jvc3MgdHJlYXRtZW50IHRpbWUgcG9pbnQgZm9yIGVhY2ggZ2Vub3R5cGUuCgojIEdlbm90eXBlIHZzIERhaWx5IE1ldGhhbmUKYGBge3J9CmQgPC0gZ2dwbG90KG1ldGFkYXRhLCBhZXMoZ2Vub3R5cGUsIGRhaWx5X2NoNCkpCmQgKyBnZW9tX3BvaW50KGFlcyhjb2xvcj1kZXYpKQoKYGBgCkQyIGlzIHRoZSBoaWdoIG1ldGhhbmUgcHJvZHVjaW5nIHRpbWUtcG9pbnQgCgojIFRvdGFsIG1ldGhhbmUgYW5kIHJvb3QgYmlvbWFzcwpgYGB7cn0KZCA8LSBnZ3Bsb3QobWV0YWRhdGFbbWV0YWRhdGEkZGV2PT0iRDMiLF0sIGFlcyhzdW1fY2g0LCByb290X2Jpb21hc3NfMjAxNykpCmQgKyBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBmYWN0b3IoZ2Vub3R5cGUpKSkKYGBgCgojIFRvdGFsIG1ldGhhbmUgYW5kIHNob290IGJpb21hc3MKYGBge3J9CmQgPC0gZ2dwbG90KG1ldGFkYXRhW21ldGFkYXRhJGRldj09IkQzIixdLCBhZXMoKHN1bV9jaDQpLCBsb2cxMChzaG9vdF9yb290X3JhdGlvMjAxNykpKQpkICsgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gZmFjdG9yKGdlbm90eXBlKSkpCmBgYAoKIyBMb2FkIHRheG9ub21pYyBjb3VudCBkYXRhCmBgYHtyfQojIEltcG9ydCBPVFUgY291bnRzCm90dWRhdGE8LXJlYWQudGFibGUoIn4vRG9jdW1lbnRzL2dicnVfZnkxOF9yaWNlX21ldGhhbmUvbWFyY2gyMDIwL290dV90YWJsZS50c3YiLCBoZWFkZXI9VFJVRSkKIyBNb3ZlIGZlYXR1cmUgSUQgdG8gcm93bmFtZXMKcm93Lm5hbWVzKG90dWRhdGEpPC1vdHVkYXRhJGZlYXR1cmUuaWQKb3R1ZGF0YTwtb3R1ZGF0YVssLTFdCiMgU29ydCBjb2x1bW5zIGJ5IG5hbWUKb3R1ZGF0YTwtIG90dWRhdGFbLCBvcmRlcihuYW1lcyhvdHVkYXRhKSldCiMgbG9hZCBUYXhvbm9teSBhbm5vdGF0aW9uIAp0YXhhIDwtIHJlYWQudGFibGUoIn4vRG9jdW1lbnRzL2dicnVfZnkxOF9yaWNlX21ldGhhbmUvbWFyY2gyMDIwL29ic2VydmF0aW9uX21ldGFfZGF0YS50c3YiLCBzZXA9Ilx0IiwgaGVhZGVyPVRSVUUsIHF1b3RlID0gIiIpCgpgYGAKCiMgRGVmaW5lIGZ1bmN0aW9uIHRvIGZpbHRlciB0YXhhIHdpdGggbG93IGFidW5kYW5jZSBhbmQgbWFueSB6ZXJvcyAKCmBgYHtyfQoKI0RlZmluZSB0aGUgZ2VvbWV0cmljIG1lYW4gZm9yIGFsbCB2YWx1ZXMgZ3JlYXRlciB0aGFuIDAKZ2VvbWVhbiA8LSBmdW5jdGlvbih4KSB7IGV4cChtZWFuKGxvZyh4W3g+MF0pKSkgfQoKIyBDcmVhdGUgYSBmdW5jdGlvbiB0byBmaWx0ZXIgcm93cyBieSB0aGUgcHJvcG9ydGlvbiBvZiBub256ZXJvIHNhbXBsZXMgYW5kIHRoZSBnZW9tZXRyaWMgbWVhbiBvZiB0aGUgbm9uemVybyBzYW1wbGVzCnByZWZpbHRlciA8LSBmdW5jdGlvbih4LCB6Y3V0b2ZmLCBtY3V0b2ZmKXsKICAgIG56dmVjdCA8LSBhcHBseSh4LCAxLCBmdW5jdGlvbih5KXsKICAgICAgKChzdW0oeT4wKS9sZW5ndGgoeSkpPiB6Y3V0b2ZmKSAmIChnZW9tZWFuKHkpPiBtY3V0b2ZmKQogICAgICB9KQogICAgbG93Y291bnRzIDwtIHQoYXMuZGF0YS5mcmFtZShhcHBseSh4WyFuenZlY3QsXSwyLHN1bSkpKQogICAgcm93bmFtZXMobG93Y291bnRzKTwtYygibG93Y29udHMiKQogICAgZGYxIDwtcmJpbmQobG93Y291bnRzLCB4W256dmVjdCxdKQogICAgcmV0dXJuKGRmMSkKfQpgYGAKCgojIEdyb3VwIGJ5IEZhbWlseSBhbmQgR2VudXMKSW5pdGlhbCB0ZXN0cyBvZiB1bi1ncm91cGVkIGFuZCB1bmZpbHRlcmVkIGRhdGEgcmV0dXJuZWQgbm8gc2lnbmlmaWNhbnQgdGF4YS4gSW5kZXBlbmRlbnQgZmlsdGVyaW5nIGJ5IGRlcHRoIGlzIHNvbWV0aGluZyB3aGljaCBoYXMgYmVlbiBkb25lIGluIERFU2VxMiBhbmQgRWRnZVIgYW5kIGlzIGNvbnNpZGVyZWQgYSB2YWxpZCBwcmVzZWxlY3Rpb24gdGVjaG5pcXVlLiAgCmBgYHtyfQojRmlsdGVyIGRhdGEgdG8gc3BlY2lmaWMgdGF4b25vbWljIGxldmVscwpjZGF0YSA8LWNiaW5kKHRheGEsb3R1ZGF0YSkKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKCmZkX2xvbmc8LSBnYXRoZXIoY2RhdGEsIHNhbXBsZSwgY291bnQsIGNvbG5hbWVzKGNkYXRhKVsxMDoxMDVdLCBmYWN0b3Jfa2V5PVRSVUUpCgojZ3JvdXAgYnkgZmFtaWx5CmZkX2ZhbV90YWxseSA8LSBmZF9sb25nWyxjKDcsMTAsMTEpXSAlPiUgZ3JvdXBfYnkodGF4b25vbXlfNSwgc2FtcGxlKSAlPiUgIHN1bW1hcmlzZShuID0gc3VtKGNvdW50KSkKZmRfZmFtX3dpZGUgPC0gcGl2b3Rfd2lkZXIoZmRfZmFtX3RhbGx5LCBuYW1lc19mcm9tPSBzYW1wbGUsIHZhbHVlc19mcm9tPW4pCmRmX2ZhbV93aWRlPC0gYXMuZGF0YS5mcmFtZShmZF9mYW1fd2lkZSkKcm93bmFtZXMoZGZfZmFtX3dpZGUpPC0gZGZfZmFtX3dpZGVbLDFdCmRmX2ZhbV93aWRlPC0gZGZfZmFtX3dpZGVbLC0xXQpvdHV0YXhhX2ZhbTwtcHJlZmlsdGVyKGRmX2ZhbV93aWRlLCAwLjUsIDEwMCkKCiNncm91cCBieSBnZW51cwpmZF9nZW51c190YWxseSA8LSBmZF9sb25nWyxjKDgsMTAsMTEpXSAlPiUgZ3JvdXBfYnkodGF4b25vbXlfNiwgc2FtcGxlKSAlPiUgIHN1bW1hcmlzZShuID0gc3VtKGNvdW50KSkKZmRfZ2VudXNfd2lkZSA8LSBmZF9nZW51c190YWxseSAlPiUgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbT0gc2FtcGxlLCB2YWx1ZXNfZnJvbT1uKQpkZl9nZW51c193aWRlPC0gYXMuZGF0YS5mcmFtZShmZF9nZW51c193aWRlKQpyb3duYW1lcyhkZl9nZW51c193aWRlKTwtIGRmX2dlbnVzX3dpZGVbLDFdCmRmX2dlbnVzX3dpZGU8LSBkZl9nZW51c193aWRlWywtMV0Kb3R1dGF4YV9nZW51czwtcHJlZmlsdGVyKGRmX2dlbnVzX3dpZGUsIDAuNSwgMTAwKQpgYGAKCgojIEFMREV4MiBzdGF0aXN0aWNhbCBhbmFseXNpcyBmb3IgY29tcG9zaXRpb25hbCBjb3VudCBkYXRhIGF0IHRoZSBmYW1pbHkgbGV2ZWwKYGBge3J9CmxpYnJhcnkoIkFMREV4MiIpCgojIENvbnN0cnVjdCBjb3ZhcmlhdGVzIG1hdHJpeApjb3ZhcmlhdGVzMSA8LSBkYXRhLmZyYW1lKGdlbm90eXBlPW1ldGFkYXRhJGdlbm90eXBlLCBzdW1jaDQ9bG9nMTAobWV0YWRhdGEkc3VtX2NoNCksIGRldj1tZXRhZGF0YSRkZXYpCiMgUHJvY2VzcyAKCiNzZWxlY3QgRDMgZGV2ZWxvcG1lbnRhbCBzdGFnZSAKZDNjb3Y8LSAgY292YXJpYXRlczFbY292YXJpYXRlczEkZGV2PT0iRDMiLF0KZDNjb3Y8LWQzY292WzE6MzAsXQpkM3Jvd3MgPC0gYXMubnVtZXJpYyhyb3duYW1lcyhkM2NvdikpCmQzb3R1cyA8LSBvdHV0YXhhX2ZhbVssZDNyb3dzXQoKIyBjcmVhdGUgbW9kZWwgbWF0cml4IGZvciBsb2cxMCBvZiB0b3RhbCBtZXRoYW5lCm1tMSA8LSBtb2RlbC5tYXRyaXgofiBzdW1jaDQsIGQzY292KQoKCmBgYAoKIyMgUnVuIENlbnRlcmVkIGxvZyByYXRpbyB0cmFuc2Zvcm1hdGlvbnMgYW5kIERpcmljaGxldCBzYW1wbGluZwpgYGB7cn0KIyBydW4gQ0xSIHRyYW5zZm9ybWF0aW9ucyBhbmQgc2FtcGxpbmcKZDNjaDRmYW0uY2xyPC0gIGFsZGV4LmNscihvdHV0YXhhX2ZhbVssZDNyb3dzXSwgbW0xLCBtYy5zYW1wbGVzID0gMTI4LCBkZW5vbT0iYWxsIiwgdmVyYm9zZT1UUlVFLCB1c2VNQz1UUlVFKQpgYGAKCiMjIEZpdCBhIEdMTSBvbiB0b3RhbCBtZXRoYW5lCmBgYHtyfQojIHJ1biBDTFIgdHJhbnNmb3JtYXRpb25zIGFuZCBzYW1wbGluZwpkM2NoNGZhbS5jbHIuZ2xtPC0gYWxkZXguZ2xtKGQzY2g0ZmFtLmNsciwgdmVyYm9zZT1UUlVFKQpgYGAKYGBge3J9CmQzY2g0ZmFtLmNsci5nbG1bZDNjaDRmYW0uY2xyLmdsbSRgbW9kZWwuc3VtY2g0IFByKD58dHwpLkJIYDwwLjUsXQpgYGAKCiMjIyBSZXN1bHRzCkJlY2F1c2UgdGhlcmUgYXJlIG5vIHNpZ25pZmljYW50IHRheGEgYWZ0ZXIgQkggY29ycmVjdGlvbi4gVGhlIGNoYWxsZW5nZSBvZiByZWdyZXNzaW5nIHRoaXMgZGF0YSBpcyB0aGF0IGVhY2ggc2FtcGxlIGRvZXMgbm90IGhhdmUgaXRzIG93biBtZW50aGFuZSBtZWFzdXJtZW50IHdoaWMgcmVkdWNlcyB0aGUgZGVncmVlcyBvZiBmcmVlZG9tCgojIyBEbyBhIGNvcnJlbGF0aW9uIHRlc3QKYGBge3J9CmNvcnIudGVzdC5mYW0gPC0gYWxkZXguY29ycihkM2NoNGZhbS5jbHIsIGQzY292JHN1bWNoNCkKYGBgCgoKIyMjIFJlc3VsdHMKRWlnaHQgZmFtaWxpZXMgaGF2ZSBhIHNpZ25pZmlnYW50IHN0YXRpc3RpY2FsIGFzc29jaWF0aW9uIHdpdGggbWV0aGFuZSBpbiB0aGUgY29ycmVsYXRpb24gdGVzdApgYGB7cn0KY29yci50ZXN0LmZhbVtjb3JyLnRlc3QuZmFtJEJIPDAuMDUsXQpgYGAKCmBgYHtyfQpoaXN0KGNvcnIudGVzdC5mYW0kQkgpCmBgYAoKIyBBTERFeDIyIHN0YXRpc3RpY2FsIGFuYWx5c2lzIGZvciBjb21wb3NpdGlvbmFsIGNvdW50IGRhdGEgYXQgdGhlIEdlbnVzIExldmVsCgojIyBSdW4gQ2VudGVyZWQgbG9nIHJhdGlvIHRyYW5zZm9ybWF0aW9ucyBhbmQgRGlyaWNobGV0IHNhbXBsaW5nCmBgYHtyfQojIHJ1biBDTFIgdHJhbnNmb3JtYXRpb25zIGFuZCBzYW1wbGluZwpkM2NoNGdlbnVzLmNscjwtICBhbGRleC5jbHIob3R1dGF4YV9nZW51c1ssZDNyb3dzXSwgbW0xLCBtYy5zYW1wbGVzID0gMTI4LCBkZW5vbT0iYWxsIiwgdmVyYm9zZT1UUlVFLCB1c2VNQz1UUlVFKQpgYGAKCiMjIEZpdCBhIEdMTSBvbiB0b3RhbCBtZXRoYW5lCmBgYHtyfQojIHJ1biBDTFIgdHJhbnNmb3JtYXRpb25zIGFuZCBzYW1wbGluZwpkM2NoNGdlbnVzLmNsci5nbG08LSBhbGRleC5nbG0oZDNjaDRnZW51cy5jbHIsIHZlcmJvc2U9VFJVRSkKYGBgCgojIyMgUmVzdWx0cwpCZWNhdXNlIHRoZXJlIGFyZSBubyBzaWduaWZpY2FudCB0YXhhIGFmdGVyIEJIIGNvcnJlY3Rpb24uIFRoZSBjaGFsbGVuZ2Ugb2YgcmVncmVzc2luZyB0aGlzIGRhdGEgaXMgdGhhdCBlYWNoIHNhbXBsZSBkb2VzIG5vdCBoYXZlIGl0cyBvd24gbWVudGhhbmUgbWVhc3VybWVudCB3aGljIHJlZHVjZXMgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbQpgYGB7cn0KZDNjaDRnZW51cy5jbHIuZ2xtW2QzY2g0Z2VudXMuY2xyLmdsbSRgbW9kZWwuc3VtY2g0IFByKD58dHwpLkJIYDwwLjUsXQpgYGAKCiMjIERvIGEgY29ycmVsYXRpb24gdGVzdApgYGB7cn0KY29yci50ZXN0LmZhbSA8LSBhbGRleC5jb3JyKGQzY2g0Z2VudXMuY2xyLCBkM2NvdiRzdW1jaDQpCmBgYAoKCiMjIyBSZXN1bHRzCkVpZ2h0IGZhbWlsaWVzIGhhdmUgYSBzaWduaWZpZ2FudCBzdGF0aXN0aWNhbCBhc3NvY2lhdGlvbiB3aXRoIG1ldGhhbmUgaW4gdGhlIGNvcnJlbGF0aW9uIHRlc3QKYGBge3J9CmNvcnIudGVzdC5mYW1bY29yci50ZXN0LmZhbSRCSDwwLjEwLF0KYGBgCgoKIAogIyBOZXcgYXBwcmFjaDogU3BsaXQgbWV0aGFuZSBpbnRvIGEgY2F0ZWdvaWNhbCB2YXJpYWJsZSBhbmQgZG8gYSBXZWxjaGUncyB0ZXN0IG9uIGhpZ2ggdnMgbG93IG1ldGhhbmUKICAKYGBge3J9CiMgQ29uc3RydWN0IGNvdmFyaWF0ZXMgbWF0cml4CmNvdmFyaWF0ZXMyIDwtIGRhdGEuZnJhbWUoZ2Vub3R5cGU9bWV0YWRhdGEkZ2Vub3R5cGUsIHN1bWNoND1sb2cxMChtZXRhZGF0YSRzdW1fY2g0KSwgZGV2PW1ldGFkYXRhJGRldikKIyBQcm9jZXNzIAoKI3NlbGVjdCBEMyBkZXZlbG9wbWVudGFsIHN0YWdlIApkM2NvdjwtICBjb3ZhcmlhdGVzMltjb3ZhcmlhdGVzMiRkZXY9PSJEMyIsXQpkM2NvdjwtZDNjb3ZbMTozMCxdCmQzY292JG1ldGhmYWN0b3I8LWN1dChkM2NvdiRzdW1jaDQsYnJlYWtzPTIpCmQzcm93cyA8LSBhcy5udW1lcmljKHJvd25hbWVzKGQzY292KSkKZDNvdHVzIDwtIG90dXRheGFfZmFtWyxkM3Jvd3NdCgojIGNyZWF0ZSBtb2RlbCBtYXRyaXggZm9yIGxvZzEwIG9mIHRvdGFsIG1ldGhhbmUKbW0xIDwtIG1vZGVsLm1hdHJpeCh+IG1ldGhmYWN0b3IsIGQzY292KQoKaGxtZXRoLmNsciA8LSBhbGRleC5jbHIoZDNvdHVzLCBhcy5jaGFyYWN0ZXIoZDNjb3YkbWV0aGZhY3RvciksIG1jLnNhbXBsZXM9MTI4LCBkZW5vbT0iaXFsciIpCmhsbWV0aC50ZXN0IDwtIGFsZGV4LnR0ZXN0KGhsbWV0aC5jbHIsIGhpc3QucGxvdD1UUlVFICkKCmBgYAogCmBgYHtyfQpobG1ldGgudGVzdFtobG1ldGgudGVzdCR3ZS5lQkg8MC4xLF0KYGBgCiAjIyBSZXN1bHRzCiBTcGxpdGluZyBpbnRvIGhpZ2ggYW5kIGxvdyBtZXRoYW5lIGF0IEQyIGRpZCBub3QgaGlnaGxpaGdodCBuZXcgZ3JvdXBzLgogCiAjIFJ1biB0aGUgbWV0aGFuZSBHTE0gYW5heXNpcyBmb3IgdGltZXBvaW50IEQyCiAKIAogIyMgQ29uc3RydWN0IG5ldyBjb3ZhcmlhdGVzIG1hdHJpeAogCmBgYHtyfQpjb3ZhcmlhdGVzMSA8LSBkYXRhLmZyYW1lKGdlbm90eXBlPW1ldGFkYXRhJGdlbm90eXBlLCBzdW1jaDQ9bG9nMTAobWV0YWRhdGEkc3VtX2NoNCksIGRldj1tZXRhZGF0YSRkZXYpCiMgUHJvY2VzcyAKCiNzZWxlY3QgRDMgZGV2ZWxvcG1lbnRhbCBzdGFnZSAKZDJjb3Y8LSAgY292YXJpYXRlczFbY292YXJpYXRlczEkZGV2PT0iRDIiLF0KZDJjb3Y8LWQyY292WzE6MzAsXSAjIFJlbW92ZSBzb2lsIHNhbXBsZXMKZDJyb3dzIDwtIGFzLm51bWVyaWMocm93bmFtZXMoZDJjb3YpKQpkMm90dXMgPC0gb3R1dGF4YV9mYW1bLGQycm93c10KCiMgY3JlYXRlIG1vZGVsIG1hdHJpeCBmb3IgbG9nMTAgb2YgdG90YWwgbWV0aGFuZQptbTIgPC0gbW9kZWwubWF0cml4KH4gc3VtY2g0LCBkMmNvdikKYGBgCiAKIyMgUnVuIENlbnRlcmVkIGxvZyByYXRpbyB0cmFuc2Zvcm1hdGlvbnMgYW5kIERpcmljaGxldCBzYW1wbGluZwpgYGB7cn0KZDJjaDRmYW0uY2xyPC0gIGFsZGV4LmNscihvdHV0YXhhX2ZhbVssZDJyb3dzXSwgbW0yLCBtYy5zYW1wbGVzID0gMTI4LCBkZW5vbT0iYWxsIiwgdmVyYm9zZT1UUlVFLCB1c2VNQz1UUlVFKQpgYGAKCiMjIEZpdCBhIEdMTSBvbiB0b3RhbCBtZXRoYW5lCmBgYHtyfQojIHJ1biBDTFIgdHJhbnNmb3JtYXRpb25zIGFuZCBzYW1wbGluZwpkMmNoNGZhbS5jbHIuZ2xtPC0gYWxkZXguZ2xtKGQyY2g0ZmFtLmNsciwgdmVyYm9zZT1UUlVFKQpgYGAKCmBgYHtyfQpkMmNoNGZhbS5jbHIuZ2xtW2QyY2g0ZmFtLmNsci5nbG0kYG1vZGVsLnN1bWNoNCBQcig+fHR8KS5CSGA8MC41LF0KYGBgCgojIyBSZXN1bHRzClRoZXJlIHdlcmUgbm8gc2lnbmlmaWdhbnQgZWZmZWN0cyBhdCBzdGFnZSBEMgoKCiNUZXN0IFJJTDYgKGxvd2VzdCBlbWl0dGVyKSBhbmQgUklMMSAoaGlnaGVzdCBlbW1pdHRlcikgYXQgRDMKYGBge3J9CgpjMTY8LWNvdmFyaWF0ZXMxW2NvdmFyaWF0ZXMxJGdlbm90eXBlICVpbiUgYygiUklMMSIsICJSSUw2IikgJiBjb3ZhcmlhdGVzMSRkZXY9PSJEMyIsXQpjMTZyb3dzIDwtIGFzLm51bWVyaWMocm93bmFtZXMoYzE2KSkKYzE2b3R1cyA8LSBvdHV0YXhhX2ZhbVssYzE2cm93c10KCmhsZ2Vuby5jbHIgPC0gYWxkZXguY2xyKGMxNm90dXMsIGMxNiRnZW5vdHlwZSwgbWMuc2FtcGxlcz0xMjgsIGRlbm9tPSJpcWxyIikKaGxnZW5vLnRlc3QgPC0gYWxkZXgudHRlc3QoaGxtZXRoLmNsciwgaGlzdC5wbG90PVRSVUUgKQpgYGAKCmBgYHtyfQojIHJ1biBDTFIgdHJhbnNmb3JtYXRpb25zIGFuZCBzYW1wbGluZwpobGdlbm8udGVzdFtobGdlbm8udGVzdCR3ZS5lQkg8MC4xLF0KYGBg