Title: Exome sequencing of bulked segregants identified a novel TaMKK3-A allele linked to the wheat ERA8 ABA-hypersensitive germination phenotype

Authors: Shantel A. Martinez, Oluwayesi Shorinola, Samantha Conselman, Deven See, Daniel Z. Skinner, Cristobal Uauy, and Camille M. Steber

This repository contains all datasets for the paper, Martinez et al. 2020, and can be used to enable reproducibility of the QTL Mapping and figures created.

The datasets generated during and/or analysed during the current study are available in the GitHub repository, github.com/shantel-martinez/ERA8-Mapping.

Load All Data

To download all of the datasets used in this analysis:


Once downloaded, the environment can be loaded:

load("ERA8-Mapping-Data.RData")

Load Libraries

library(qtl)
library(tidyverse)
font<-element_text(face = "bold",  size = 16) #ggplot aesthetic
# library(kableExtra)
# library(knitr)
library(DT) 
sketch = htmltools::withTags(table(    #table aesthetic
  class = 'display',
  thead(
    tr(
      th(rowspan = 2, 'Species'),
      th(colspan = 2, 'Sepal'),
      th(colspan = 2, 'Petal')
    ),
    tr(
      lapply(rep(c('Length', 'Width'), 2), th)
    )
  )
)) 

Zak/ZakERA8 BC3F2:3

After-ripening timecourse

ZParABA <- read.csv("./ZZ8ARTC_E1.csv", header = TRUE, na.string="NA") 
ZParABA$ABA_uM <- as.character(ZParABA$ABA_uM)
ZParABA$Geno <- as.character(ZParABA$Geno)
ParABAf <-
  ZParABA %>%
    filter(Geno != "Zak..2.2.6", Geno != "95.3.91.4" , Geno != "Zak..2.2.8")

ParABA2 <- subset(ParABAf, ParABAf$ABA_uM == "0" )
ggplot(data = ParABA2 , aes(x=AR_wk, y=PG_d5, color = Geno)) +
  geom_line(size=1.5) +
  geom_point(aes(size = 3))+
  geom_errorbar(aes(ymin=PG_d5-PG_Std, ymax=PG_d5+PG_Std), width=1,
                 position=position_dodge(0.05))+
  ylim(0,100)+ theme_bw()+ theme(axis.text = font, axis.title = font)+
  # labs(title = "Figure S2a", subtitle = "0uM ABA (No Hormone)", y = "Percent Germination", x = "Weeks After-ripened")+
  labs(title = "0uM ABA (No Hormone)", y = "Percent Germination", x = "Weeks After-ripened")+ theme(legend.position="none") +
  scale_color_manual(values=c("#440154","#A2CD5A"))

ggsave("20190923_ZZ8_Parents_MES.png", width = 5, height = 5, units = "in")

ParABA2 <- subset(ParABAf, ParABAf$ABA_uM == "2")
ggplot(data = ParABA2 , aes(x=AR_wk, y=PG_d5, color = Geno)) +
  geom_line(size=1.5) +
  geom_point(aes(size = 3))+
  geom_errorbar(aes(ymin=PG_d5-PG_Std, ymax=PG_d5+PG_Std), width=1,
                 position=position_dodge(0.05))+
  ylim(0,100)+ theme_bw()+ theme(axis.text = font, axis.title = font)+
  # labs(title = "Figure S2b", subtitle = "2uM ABA", y = "Percent Germination", x = "Weeks After-ripened")+
  labs(title = "2uM ABA", y = "Percent Germination", x = "Weeks After-ripened")+ theme(legend.position="none") +
  scale_color_manual(values=c("#440154","#A2CD5A"))

ggsave("20190923_ZZ8_Parents_ABA.png", width = 5, height = 5, units = "in")

The ZZ8 dataset contains Zak/ZakERA8 BC3 F2:3 genotypic data, phenotypic data, and marker positions on chromosome 4A.

ZZ8 <- read.cross("csv",".","./ZZ8_SNP1-SNP_30_all.csv",na.strings=c("-","NA","."),BC.gen=3, F.gen=2)
##   This is an object of class "cross".
##   It is too complex to print, so we provide just this summary.
##     BC(3)F(2) cross
## 
##     No. individuals:    424 
## 
##     No. phenotypes:     3 
##     Percent phenotyped: 100 97.9 97.9 
## 
##     No. chromosomes:    1 
##         Autosomes:      4A 
## 
##     Total markers:      11 
##     No. markers:        11 
##     Percent genotyped:  92.6 
##     Genotypes (%):      AA:27.9  AB:51.9  BB:20.2  not BB:0.0  not AA:0.0

Phenotypes include: Percent Germination (PG) and Germination Index (GI)

Composite Interval Mapping

data_2 <- calc.genoprob(ZZ8, step=0)
out.cimPGavg <- cim(data_2, pheno.col="PG",map.function=c("kosambi"),method=c("hk"))
out.cimPGavg$Trait <- ("PG") 
out.cimGIavg <- cim(data_2, pheno.col="GI",map.function=c("kosambi"),method=c("hk"))
out.cimGIavg$Trait <- ("GI")

Determine Significance Threshhold

a <- scanone(ZZ8, method="hk", pheno.col = "PG", n.perm=1000)
b <- scanone(ZZ8, method="hk", pheno.col = "GI", n.perm=1000)
summary(a) 
summary(b)

Wrangle Results

ZZ8_all <- rbind(out.cimPGavg, out.cimGIavg)
ZZ8_all$Population <- ("all")

Repeat CIM for the X5.1 subset only

data5.1<-read.cross("csv",".","./ZZ8_SNP1-SNP_30_5.1.csv",na.strings=c("-","NA","."),BC.gen=3, F.gen=2)
##   This is an object of class "cross".
##   It is too complex to print, so we provide just this summary.
##     BC(3)F(2) cross
## 
##     No. individuals:    122 
## 
##     No. phenotypes:     3 
##     Percent phenotyped: 100 94.3 94.3 
## 
##     No. chromosomes:    1 
##         Autosomes:      4A 
## 
##     Total markers:      11 
##     No. markers:        11 
##     Percent genotyped:  91.7 
##     Genotypes (%):      AA:28.1  AB:53.7  BB:18.2  not BB:0.0  not AA:0.0
data_2 <- calc.genoprob(data5.1, step=0)
out.cimPGavg <- cim(data_2, pheno.col="PG",map.function=c("kosambi"),method=c("hk"))
out.cimPGavg$Trait <- ("PG") 
out.cimGIavg <- cim(data_2, pheno.col="GI",map.function=c("kosambi"),method=c("hk"))
a <- scanone(data5.1, method="hk", pheno.col = "PG", n.perm=1000)
b <- scanone(data5.1, method="hk", pheno.col = "GI", n.perm=1000)
summary(a) 
summary(b) 
ZZ8_5.1 <- rbind(out.cimPGavg, out.cimGIavg)
ZZ8_5.1$Population <- ("5.1")

Repeat CIM for the X5.2a subset only

data5.2a<-read.cross("csv",".","./ZZ8_SNP1-SNP_30_5.2a.csv",na.strings=c("-","NA","."),BC.gen=3, F.gen=2)
##   This is an object of class "cross".
##   It is too complex to print, so we provide just this summary.
##     BC(3)F(2) cross
## 
##     No. individuals:    242 
## 
##     No. phenotypes:     3 
##     Percent phenotyped: 100 99.2 99.2 
## 
##     No. chromosomes:    1 
##         Autosomes:      4A 
## 
##     Total markers:      11 
##     No. markers:        11 
##     Percent genotyped:  93.2 
##     Genotypes (%):      AA:27.6  AB:50.8  BB:21.5  not BB:0.0  not AA:0.0
data_2 <- calc.genoprob(data5.2a, step=0)
out.cimPGavg <- cim(data_2, pheno.col="PG",map.function=c("kosambi"),method=c("hk"))
out.cimPGavg$Trait <- ("PG") 
out.cimGIavg <- cim(data_2, pheno.col="GI",map.function=c("kosambi"),method=c("hk"))
out.cimGIavg$Trait <- ("GI")
a <- scanone(data5.2a, method="hk", pheno.col = "PG", n.perm=1000)
b <- scanone(data5.2a, method="hk", pheno.col = "GI", n.perm=1000)
summary(a) 
summary(b) 
ZZ8_5.2a <- rbind(out.cimPGavg, out.cimGIavg)
ZZ8_5.2a$Population <- ("5.2a")

Repeat CIM for the X5.2b subset only

data5.2b <- read.cross("csv",".","./ZZ8_SNP1-SNP_30_5.2b.csv",na.strings=c("-","NA","."),BC.gen=3, F.gen=2)
##   This is an object of class "cross".
##   It is too complex to print, so we provide just this summary.
##     BC(3)F(2) cross
## 
##     No. individuals:    60 
## 
##     No. phenotypes:     3 
##     Percent phenotyped: 100 100 100 
## 
##     No. chromosomes:    1 
##         Autosomes:      4A 
## 
##     Total markers:      11 
##     No. markers:        11 
##     Percent genotyped:  92 
##     Genotypes (%):      AA:28.8  AB:52.6  BB:18.6  not BB:0.0  not AA:0.0
data_2 <- calc.genoprob(data5.2b, step=0)
out.cimPGavg <- cim(data_2, pheno.col="PG",map.function=c("kosambi"),method=c("hk"))
out.cimPGavg$Trait <- ("PG") 
out.cimGIavg <- cim(data_2, pheno.col="GI",map.function=c("kosambi"),method=c("hk"))
out.cimGIavg$Trait <- ("GI")
a <- scanone(data5.2b, method="hk", pheno.col = "PG", n.perm=1000)
b <- scanone(data5.2b, method="hk", pheno.col = "GI", n.perm=1000)
summary(a) 
summary(b) 
ZZ8_5.2b <- rbind(out.cimPGavg, out.cimGIavg)
ZZ8_5.2b$Population <- ("5.2b")

Graph Results

QTL Graph for Germination Index (GI)

ZZ8_QTL <- rbind(ZZ8_all, ZZ8_5.1, ZZ8_5.2b, ZZ8_5.2a)
GI <- ZZ8_QTL[(ZZ8_QTL$Trait %in% "GI"),]

ggplot(data = GI , aes(x=GI$pos, y=GI$lod)) + 
  geom_line(aes(colour=GI$Population), size=1)+geom_hline(aes(yintercept = 1.85))+
  theme_bw()+ theme(axis.text = font,  axis.title = font)+ 
  labs(x = "Chromosome 4A ERA8 Region (cM)", y = "LOD")+
  scale_color_manual(values=c("#78c679", "#006837", "#31a354","#A2CD5A")) + theme(legend.position="none") +
  ggsave("ZZ8_4A_QTL.png", width = 3, height = 3, units = "in")

Louise/ZakERA8 RIL F6:7

After-ripening timecourse

ParABA <- read.csv("LZ8ARTC_2014.csv", header = TRUE, na.string="NA") 
ParABA$ABA_uM <- as.character(ParABA$ABA_uM)
ParABA$Geno <- as.character(ParABA$Geno)
ParABAf <-
  ParABA %>%
    filter(Geno != "ERA8.1", Geno != "ERA8.3" , Geno != "ERA8.4")

ParABA2 <- subset(ParABAf, ParABAf$ABA_uM == "2" & ParABAf$AR_wk != 7)
ggplot(data = ParABA2 , aes(x=AR_wk, y=PG_d5, color = Geno)) +
  geom_line(size=1.5) +
  geom_point(aes(size = 3))+
  geom_errorbar(aes(ymin=PG_d5-PG_Std, ymax=PG_d5+PG_Std), width=1,
                 position=position_dodge(0.05))+
  ylim(0,100)+ theme_bw()+ theme(axis.text = font, axis.title = font)+
  # labs(title = "Figure 5a")+
  scale_color_manual(values=c("#440154","#008B8B", "#A2CD5A"))

ggsave("20190313_1-6ARWhole_Parents.png", width = 7, height = 7, units = "in")


ParABAc <- subset(ParABA, ParABA$AR_wk == 7)
target <- c("0", "2", "5", "10")
require(gdata)
ParABAc$ABA_uM <- reorder.factor(ParABAc$ABA_uM, new.order=target)
ggplot(data = ParABAc , aes(x=ABA_uM, y=PG_d5, color = Geno, shape = ABA_uM)) +
  geom_point(aes(size = 4))+
  geom_errorbar(aes(ymin=PG_d5-PG_Std, ymax=PG_d5+PG_Std), width=.2,
                 position=position_dodge(0.05))+
  ylim(0,100)+ theme_bw()+ theme(axis.text = font, axis.title = font)+
  # labs(title = "Figure 5b")+
  scale_color_manual(values=c("#440154", "#008B8B", "#A2CD5A"))+
  scale_shape_manual(values=c(1,16,17,15))  

ggsave("20190313_7ARCut_Parents.png", width = 3, height = 5, units = "in")

EMS-derived SNPs

# LZ8 <- read.cross("csv",".","./LZ8_SNP1-SNP30_MKK3.csv",na.strings=c("-","NA","."),BC.gen=0, F.gen=5)
LZ8
##   This is an object of class "cross".
##   It is too complex to print, so we provide just this summary.
##     BC(0)F(5) cross
## 
##     No. individuals:    207 
## 
##     No. phenotypes:     21 
##     Percent phenotyped: 100 100 100 100 100 100 100 88.9 88.9 88.4 88.4 
##                         82.1 82.1 84.5 84.1 84.5 84.5 84.5 83.6 99.5 99.5 
## 
##     No. chromosomes:    1 
##         Autosomes:      4A 
## 
##     Total markers:      13 
##     No. markers:        13 
##     Percent genotyped:  92.7 
##     Genotypes (%):      AA:50.1  AB:5.5  BB:44.4  not BB:0.0  not AA:0.0
data_2 <- calc.genoprob(data5.2b, step=0)
data_2 <- calc.genoprob(LZ8, step=0)

out.cimE1PGD1 <- cim(data_2, pheno.col="E1D1",map.function=c("kosambi"),method=c("hk"))
out.cimE1PGD1$Trait <- ("E1PGD1") 
out.cimE1PGD2 <- cim(data_2, pheno.col="E1D2",map.function=c("kosambi"),method=c("hk"))
out.cimE1PGD2$Trait <- ("E1PGD2")
out.cimE1PGD3 <- cim(data_2, pheno.col="E1D3",map.function=c("kosambi"),method=c("hk"))
out.cimE1PGD3$Trait <- ("E1PGD3")
out.cimE1PGD4 <- cim(data_2, pheno.col="E1D4",map.function=c("kosambi"),method=c("hk"))
out.cimE1PGD4$Trait <- ("E1PGD4")
out.cimE1PGD5 <- cim(data_2, pheno.col="E1D5",map.function=c("kosambi"),method=c("hk"))
out.cimE1PGD5$Trait <- ("E1PGD5")
out.cimE1GIavg <- cim(data_2, pheno.col="E1GI",map.function=c("kosambi"),method=c("hk"))
out.cimE1GIavg$Trait <- ("E1GIavg")

out.cimE2PGD1 <- cim(data_2, pheno.col="E2D1",map.function=c("kosambi"),method=c("hk"))
out.cimE2PGD1$Trait <- ("E2PGD1")
out.cimE2PGD2 <- cim(data_2, pheno.col="E2D2",map.function=c("kosambi"),method=c("hk"))
out.cimE2PGD2$Trait <- ("E2PGD2")
out.cimE2PGD3 <- cim(data_2, pheno.col="E2D3",map.function=c("kosambi"),method=c("hk"))
out.cimE2PGD3$Trait <- ("E2PGD3")
out.cimE2PGD4 <- cim(data_2, pheno.col="E2D4",map.function=c("kosambi"),method=c("hk"))
out.cimE2PGD4$Trait <- ("E2PGD4")
out.cimE2PGD5 <- cim(data_2, pheno.col="E2D5",map.function=c("kosambi"),method=c("hk"))
out.cimE2PGD5$Trait <- ("E2PGD5")
out.cimE2GIavg <- cim(data_2, pheno.col="E2GI",map.function=c("kosambi"),method=c("hk"))
out.cimE2GIavg$Trait <- ("E2GIavg")

out.cimE3PGD1 <- cim(data_2, pheno.col="E3D1",map.function=c("kosambi"),method=c("hk"))
out.cimE3PGD1$Trait <- ("E3PGD1")
out.cimE3PGD2 <- cim(data_2, pheno.col="E3D2",map.function=c("kosambi"),method=c("hk"))
out.cimE3PGD2$Trait <- ("E3PGD2")
out.cimE3PGD3 <- cim(data_2, pheno.col="E3D3",map.function=c("kosambi"),method=c("hk"))
out.cimE3PGD3$Trait <- ("E3PGD3")
out.cimE3PGD4 <- cim(data_2, pheno.col="E3D4",map.function=c("kosambi"),method=c("hk"))
out.cimE3PGD4$Trait <- ("E3PGD4")
out.cimE3PGD5 <- cim(data_2, pheno.col="E3D5",map.function=c("kosambi"),method=c("hk"))
out.cimE3PGD5$Trait <- ("E3PGD5")
out.cimE3GIavg <- cim(data_2, pheno.col="E3GI",map.function=c("kosambi"),method=c("hk"))
out.cimE3GIavg$Trait <- ("E3GIavg")

QTL.LZ8.ERA8 <- rbind(out.cimE1PGD1, out.cimE1PGD2, out.cimE1PGD3, out.cimE1PGD4, out.cimE1PGD5, 
                      out.cimE1GIavg, out.cimE2PGD1, out.cimE2PGD2, out.cimE2PGD3, out.cimE2PGD4, 
                      out.cimE2PGD5, out.cimE2GIavg,out.cimE3PGD1, out.cimE3PGD2, out.cimE3PGD3, 
                      out.cimE3PGD4, out.cimE3PGD5, out.cimE3GIavg)
QTL.LZ8.Day1 <- rbind(out.cimE1PGD1, out.cimE2PGD1,out.cimE3PGD1)
QTL.LZ8.GI <- rbind(out.cimE1GIavg, out.cimE2GIavg,out.cimE3GIavg)

Calculating the significant LOD score threshold for each trait

a<-scanone(LZ8, method="hk", pheno.col = "E1D1", n.perm=1000)
c<-scanone(LZ8, method="hk", pheno.col = "E1D2", n.perm=1000)
d<-scanone(LZ8, method="hk", pheno.col = "E1D3", n.perm=1000)
e<-scanone(LZ8, method="hk", pheno.col = "E1D4", n.perm=1000)
f<-scanone(LZ8, method="hk", pheno.col = "E1D5", n.perm=1000)
g<-scanone(LZ8, method="hk", pheno.col = "E1GI", n.perm=1000)
b1<-scanone(LZ8, method="hk", pheno.col = "E2D1", n.perm=1000)
c1<-scanone(LZ8, method="hk", pheno.col = "E2D2", n.perm=1000)
d1<-scanone(LZ8, method="hk", pheno.col = "E2D3", n.perm=1000)
e1<-scanone(LZ8, method="hk", pheno.col = "E2D4", n.perm=1000)
f1<-scanone(LZ8, method="hk", pheno.col = "E2D5", n.perm=1000)
g1<-scanone(LZ8, method="hk", pheno.col = "E2GI", n.perm=1000)
h<-scanone(LZ8, method="hk", pheno.col = "E3D1", n.perm=1000)
i<-scanone(LZ8, method="hk", pheno.col = "E3D2", n.perm=1000)
j<-scanone(LZ8, method="hk", pheno.col = "E3D3", n.perm=1000)
k<-scanone(LZ8, method="hk", pheno.col = "E3D4", n.perm=1000)
l<-scanone(LZ8, method="hk", pheno.col = "E3D5", n.perm=1000)
m<-scanone(LZ8, method="hk", pheno.col = "E3GI", n.perm=1000)
summary(a) #2.12 E1D1 
summary(c) #2.10
summary(d) #2.20
summary(e) #2.15
summary(f) #2.02
summary(g) #1.98
summary(b1) #2.06 E2D1
summary(c1) #2.17
summary(d1) #2.03
summary(e1) #1.96
summary(f1) #2.17
summary(g1) #2.10
summary(h) #2.01 E3D1
summary(i) #2.01
summary(j) #2.21
summary(k) #2.12
summary(l) #2.11
summary(m) #2.19

QTL Graph for GI

ggplot(QTL.LZ8.GI, aes(x=QTL.LZ8.GI$pos, y=QTL.LZ8.GI$lod))+
  geom_line(aes(colour = factor(Trait)),size = 1)+
  theme_bw()+ theme(axis.text = font,  axis.title = font)+
  geom_hline(aes(yintercept = 2.10))+ 
  labs(x = "Chromosome 4A (cM)", y = NULL) +
  ylim (0,10) +
  scale_color_manual(values=c("#96CDCD", "#20B2AA", "#00868B")) + theme(legend.position="none") + 
  ggsave("LZ8_4A_QTL.png", width = 3, height = 3, units = "in")

Genotyping-by-sequencing SNPs

# LZ8GBS <- read.cross("csv",".","./LZ8_GBS_all.csv",na.strings=c("-","NA","."),BC.gen=0, F.gen=5)
LZ8GBS
##   This is an object of class "cross".
##   It is too complex to print, so we provide just this summary.
##     BC(0)F(5) cross
## 
##     No. individuals:    209 
## 
##     No. phenotypes:     21 
##     Percent phenotyped: 99 99 99 99 99 99 99 88 88 87.6 87.6 81.3 81.3 83.7 
##                         83.3 83.7 83.7 83.7 82.8 98.6 98.6 
## 
##     No. chromosomes:    45 
##         Autosomes:      1A.1 1B.1 1B.2 1B.3 1D.1 1D.2 2A.1 2A.2 2B.1 2D.1 
##                         3A.1 3A.2 3A.3 3A.4 3B.1 3D.1 3D.2 4A.1 4A.2 4A.3 
##                         4B.1 4B.2 4D.1 5A.1 5A.2 5B.1 5B.2 5B.3 5D.1 5D.2 
##                         6A.1 6A.2 6B.1 6B.2 6D.1 6D.2 6D.3 7A.1 7A.2 7B.1 
##                         7B.2 7D.1 7D.2 7D.3 UNK.1 
## 
##     Total markers:      2234 
##     No. markers:        231 132 6 9 8 49 14 84 49 57 80 41 5 54 64 19 27 
##                         127 92 5 124 6 11 54 8 66 13 5 18 9 129 40 19 20 16 
##                         13 5 106 132 201 5 20 8 33 20 
##     Percent genotyped:  99 
##     Genotypes (%):      AA:45.2  AB:3.5  BB:51.4  not BB:0.0  not AA:0.0

View genotypic data

plot.map(LZ8GBS)

geno.image(LZ8GBS)

Omit Skewed Markers with potential segregation distortion

gt<-geno.table(LZ8GBS)
g <- gt[gt$P.value<0.05/totmar(LZ8GBS),]
datatable(g,rownames = FALSE, container = sketch, caption = htmltools::tags$caption(style = 'text-align: left;', 'Table A - Skewed GBS markers '))
drop <- c( "A15328_3A_7A_70" ,"A23596_unk_70" ,"A1484_unk_70" ,"A13016_1B_70" ,"A15940_1B_100" ,"A9591_1B_100" ,"A576_1B_70" ,"A18104_1D_100" ,"A27014_1B_2B_100","A17967_2D_100" ,"A13978_2D_70" ,"A25742_3A_100" ,"A18332_3A_70" ,"A12777_3D_100" ,"A273_4A_100" ,"A21245_4A_70" ,"A10491_4A_70" ,"A18377_4A_4B_70" ,"A25000_4B_70" ,"A25441_4B_100" ,"A4035_4D_100" ,"A18379_4D_100" ,"A18009_4D_70" ,"A19099_4D_7D_100","A16328_4D_70" ,"A11848_4D_70" ,"A12209_4D_100" ,"A27652_4D_100" ,"A21275_5A_100" ,"A25877_5A_100" ,"A25439_5A_70" ,"A25438_unk_70" ,"A20969_5A_70" ,"A8097_5A_100" ,"A19723_5A_100" ,"A11602_5A_100" ,"A7781_5A_100" ,"A11185_5D_100" ,"A27769_5D_100" ,"A16263_3D_5D_100","A18607_5D_100" ,"A25725_5D_100" ,"A1900_6A_70" ,"A11910_3A_6A_70" ,"A25264_6A_70" ,"A20866_6A_100" ,"A11585_6B_70" ,"A11967_6B_100" ,"A20255_6B_100" ,"A19959_6B_70" ,"A27878_6B_70" ,"A28179_6B_100" ,"A28536_6B_70" ,"A1460_6B_100" ,"A9811_6B_100" ,"A16328_6B_100" ,"A13442_6B_70" ,"A26650_3A_4B_70" ,"A8101_6B_100" ,"A7718_6B_6D_70" ,"A10138_6B_70" ,"A27566_unk_70" ,"A15195_unk_70" ,"A15639_unk_100" ,"A10596_6B_100" ,"A27867_unk_100" ,"A10599_unk_100" ,"A20619_6B_100" ,"A7070_6B_100" ,"A6713_1B_6B_70" ,"A22215_6B_100" ,"A499_5D_100" ,"A21788_6D_70" ,"A21995_6D_100" ,"A18389_6D_100" ,"A11691_6D_100" ,"A11316_6D_70" ,"A28649_6D_70" ,"A28881_6D_100" ,"A18071_6D_100" ,"A8016_7A_7D_100" ,"A6637_unk_70" ,"A7471_7A_100" ,"A12324_4B_7B_70" ,"A13388_7B_100" ,"A28147_7B_100" ,"A27851_7B_70" ,"A11842_7D_70" ,"A28228_7D_100" ,"A21486_7D_100" ,"A27928_7D_70" ,"A18989_unk_100","A7100_7A_70","A23150_unk_70")
LZ8GBS <- drop.markers(LZ8GBS, drop)
gt<-geno.table(LZ8GBS)
gt[gt$P.value<0.05/totmar(LZ8GBS),]
## [1] chr     missing AA      AB      BB      not.BB  not.AA  P.value
## <0 rows> (or 0-length row.names)

Composite Interval Mapping

Across all traits

data_2 <- calc.genoprob(LZ8GBS, step=0)
out.cimE1PGD1 <- cim(data_2, pheno.col="E1D1",map.function=c("kosambi"),method=c("hk"))
out.cimE1PGD1$Trait <- ("E1PGD1") 
out.cimE1PGD2 <- cim(data_2, pheno.col="E1D2",map.function=c("kosambi"),method=c("hk"))
out.cimE1PGD2$Trait <- ("E1PGD2")
out.cimE1PGD3 <- cim(data_2, pheno.col="E1D3",map.function=c("kosambi"),method=c("hk"))
out.cimE1PGD3$Trait <- ("E1PGD3")
out.cimE1PGD4 <- cim(data_2, pheno.col="E1D4",map.function=c("kosambi"),method=c("hk"))
out.cimE1PGD4$Trait <- ("E1PGD4")
out.cimE1PGD5 <- cim(data_2, pheno.col="E1D5",map.function=c("kosambi"),method=c("hk"))
out.cimE1PGD5$Trait <- ("E1PGD5")
out.cimE1GIavg <- cim(data_2, pheno.col="E1GI",map.function=c("kosambi"),method=c("hk"))
out.cimE1GIavg$Trait <- ("E1GIavg")
out.cimE2PGD1 <- cim(data_2, pheno.col="E2D1",map.function=c("kosambi"),method=c("hk"))
out.cimE2PGD1$Trait <- ("E2PGD1")
out.cimE2PGD2 <- cim(data_2, pheno.col="E2D2",map.function=c("kosambi"),method=c("hk"))
out.cimE2PGD2$Trait <- ("E2PGD2")
out.cimE2PGD3 <- cim(data_2, pheno.col="E2D3",map.function=c("kosambi"),method=c("hk"))
out.cimE2PGD3$Trait <- ("E2PGD3")
out.cimE2PGD4 <- cim(data_2, pheno.col="E2D4",map.function=c("kosambi"),method=c("hk"))
out.cimE2PGD4$Trait <- ("E2PGD4")
out.cimE2PGD5 <- cim(data_2, pheno.col="E2D5",map.function=c("kosambi"),method=c("hk"))
out.cimE2PGD5$Trait <- ("E2PGD5")
out.cimE2GIavg <- cim(data_2, pheno.col="E2GI",map.function=c("kosambi"),method=c("hk"))
out.cimE2GIavg$Trait <- ("E2GIavg")
out.cimE3PGD1 <- cim(data_2, pheno.col="E3D1",map.function=c("kosambi"),method=c("hk"))
out.cimE3PGD1$Trait <- ("E3PGD1")
out.cimE3PGD2 <- cim(data_2, pheno.col="E3D2",map.function=c("kosambi"),method=c("hk"))
out.cimE3PGD2$Trait <- ("E3PGD2")
out.cimE3PGD3 <- cim(data_2, pheno.col="E3D3",map.function=c("kosambi"),method=c("hk"))
out.cimE3PGD3$Trait <- ("E3PGD3")
out.cimE3PGD4 <- cim(data_2, pheno.col="E3D4",map.function=c("kosambi"),method=c("hk"))
out.cimE3PGD4$Trait <- ("E3PGD4")
out.cimE3PGD5 <- cim(data_2, pheno.col="E3D5",map.function=c("kosambi"),method=c("hk"))
out.cimE3PGD5$Trait <- ("E3PGD5")
out.cimE3GIavg <- cim(data_2, pheno.col="E3GI",map.function=c("kosambi"),method=c("hk"))
out.cimE3GIavg$Trait <- ("E3GIavg")

QTL.LZ8.ERA8 <- rbind(out.cimE1PGD1, out.cimE1PGD2, out.cimE1PGD3, out.cimE1PGD4, out.cimE1PGD5, out.cimE1GIavg, out.cimE2PGD1, out.cimE2PGD2, out.cimE2PGD3, out.cimE2PGD4, out.cimE2PGD5, out.cimE2GIavg,out.cimE3PGD1, out.cimE3PGD2, out.cimE3PGD3, out.cimE3PGD4, out.cimE3PGD5, out.cimE3GIavg)
# write.table(QTL.LZ8.ERA8, "./QTLLZ8All.txt", sep="\t")
a<-scanone(LZ8GBS, method="hk", pheno.col = "E1D1", n.perm=1000)
c<-scanone(LZ8GBS, method="hk", pheno.col = "E1D2", n.perm=1000)
d<-scanone(LZ8GBS, method="hk", pheno.col = "E1D3", n.perm=1000)
e<-scanone(LZ8GBS, method="hk", pheno.col = "E1D4", n.perm=1000)
f<-scanone(LZ8GBS, method="hk", pheno.col = "E1D5", n.perm=1000)
g<-scanone(LZ8GBS, method="hk", pheno.col = "E1GI", n.perm=1000)
b1<-scanone(LZ8GBS, method="hk", pheno.col = "E2D1", n.perm=1000)
c1<-scanone(LZ8GBS, method="hk", pheno.col = "E2D2", n.perm=1000)
d1<-scanone(LZ8GBS, method="hk", pheno.col = "E2D3", n.perm=1000)
e1<-scanone(LZ8GBS, method="hk", pheno.col = "E2D4", n.perm=1000)
f1<-scanone(LZ8GBS, method="hk", pheno.col = "E2D5", n.perm=1000)
g1<-scanone(LZ8GBS, method="hk", pheno.col = "E2GI", n.perm=1000)
h<-scanone(LZ8GBS, method="hk", pheno.col = "E3D1", n.perm=1000)
i<-scanone(LZ8GBS, method="hk", pheno.col = "E3D2", n.perm=1000)
j<-scanone(LZ8GBS, method="hk", pheno.col = "E3D3", n.perm=1000)
k<-scanone(LZ8GBS, method="hk", pheno.col = "E3D4", n.perm=1000)
l<-scanone(LZ8GBS, method="hk", pheno.col = "E3D5", n.perm=1000)
m<-scanone(LZ8GBS, method="hk", pheno.col = "E3GI", n.perm=1000)
summary(a) #
summary(c) #
summary(d) #
summary(e) #
summary(f) #
summary(g) #
summary(b1) #
summary(c1) #
summary(d1) #
summary(e1) #
summary(f1) #
summary(g1) #
summary(h) #
summary(i) #
summary(j) #
summary(k) #
summary(l) #
summary(m) #

Heading and Height

QTL Analysis

data_2 <- calc.genoprob(LZ8GBS, step=0)
out.cimHeight <- cim(data_2, pheno.col="Height",map.function=c("kosambi"),method=c("hk"))
out.cimHeight$Trait <- ("Height") 
out.cimHeading <- cim(data_2, pheno.col="Heading",map.function=c("kosambi"),method=c("hk"))
out.cimHeading$Trait <- ("Heading")

Calculate Significance Threshold

a<-scanone(LZ8GBS, method="hk", pheno.col = "Heading", n.perm=1000)
summary(a) #4.43 5%
b<-scanone(LZ8GBS, method="hk", pheno.col = "Height", n.perm=1000)
summary(b) #4.38 5%

Graph the Manhatten Plot

For graphing purposes only, add a column to give unique positions for each marker per chromosome.

# uniqpos <- read.table("./GBS_UniquePos.txt",header=TRUE,na.string=c("", " ", "NA", "na"))
uniqpos$chr <- NULL
uniqpos$pos <- NULL
QTL.LZ8.ERA8 <- as.data.frame(QTL.LZ8.ERA8)
LZ8  <- cbind(QTL.LZ8.ERA8, uniqpos)

ggplot(LZ8, aes(x=LZ8$order, y=LZ8$lod))+
  geom_point(aes(colour = factor(Genome)),size = 2)+ylim(0,6)+theme_bw()+ theme(axis.text = font,  axis.title = font, axis.text.x=element_blank())+ scale_color_manual(values=c("#0A0A0A", "#8A8A8A", "#D1D1D1","#A2CD5A"))+ 
  labs(x = "Chromosome 1A - 7D and Unknown" , y = "LOD",subtitle="ABA Sensitivity QTL")

# uniqposAHH <- read.table("./GBS_UniquePos_ABAHeadHei.txt",header=TRUE,na.string=c("", " ", "NA", "na"))
uniqposAHH$chr <- NULL
uniqposAHH$pos <- NULL
QTL.LZ8.ERA8 <- rbind(out.cimE1PGD1, out.cimE1PGD2, out.cimE1PGD3, out.cimE1PGD4, 
                      out.cimE1PGD5, out.cimE1GIavg, out.cimE2PGD1, out.cimE2PGD2, 
                      out.cimE2PGD3, out.cimE2PGD4, out.cimE2PGD5, out.cimE2GIavg,
                      out.cimE3PGD1, out.cimE3PGD2, out.cimE3PGD3, out.cimE3PGD4, 
                      out.cimE3PGD5, out.cimE3GIavg, out.cimHeight, out.cimHeading )
QTL.LZ8.ERA8 <- as.data.frame(QTL.LZ8.ERA8)
QTL.LZ8  <- cbind(QTL.LZ8.ERA8, uniqposAHH)
ggplot(QTL.LZ8, aes(x=QTL.LZ8$order, y=QTL.LZ8$lod))+
  geom_point(aes(colour = factor(Genome)),size = 2)+ylim(0,6)+theme_bw()+ 
  theme(axis.text = font,  axis.title = font, axis.text.x=element_blank())+ 
  scale_color_manual(values=c("#0A0A0A", "#8A8A8A", "#D1D1D1","#A2CD5A")) + geom_hline(aes(yintercept = 4.4))+ 
  labs(x = "Chromosome 1A - 7D and Unknown" , y = "LOD",  title = "Figure S5b", subtitle="ABA, Heading Date, and Height QTL")

QTL.LZ8.4A <-  subset(QTL.LZ8 ,  QTL.LZ8$chr=="4A.1" | QTL.LZ8$chr=="4A.2" | QTL.LZ8$chr=="4A.3" )
ggplot(QTL.LZ8.4A, aes(x=QTL.LZ8.4A$order, y=QTL.LZ8.4A$lod))+
  geom_point(aes(colour = factor(chr)),size = 2)+ylim(0,6)+theme_bw()+ 
  theme(axis.text = font,  axis.title = font, axis.text.x=element_blank())+ 
  scale_color_manual(values=c("#0A0A0A", "#8A8A8A", "#D1D1D1")) + geom_hline(aes(yintercept = 4.4))+ 
  labs(x = "Chromosome 4A" , y = "LOD",  title = "Figure S5c", subtitle="ABA, Heading Date, and Height QTL")

List of Significant QTL on Chromosome 4A

QTL.LZ8.4A %>% 
  mutate(lod = round(lod,2)) %>%
  filter(lod > 4.4) %>%
  arrange(str_extract(chr, '^.'), pos) %>%
  dplyr::select(Marker, chr, pos,  Trait, lod)  %>%
  datatable()#rownames = FALSE, container = sketch, caption = htmltools::tags$caption(style = 'text-align: left;', 'Table S11 - Significant QTL on chromosome 4A'))

Significant Alleles in LZ8 population

ATol<-read.table("AllTolQTLAlleles.txt", head = T,na.string=c("."," ","NA","na","NaN"))
ggplot(ATol, aes(x = OverallTolAlleles, y = E1D2)) +
  geom_point(aes(colour = ATol$Color), size = 2)+ theme_bw() + 
  theme(panel.grid.minor = element_blank(),
        panel.border = element_rect(colour = "#7D7D7D"), panel.background = element_blank(),
        axis.line = element_line(size=0.5))   +
  geom_smooth(method=lm,colour = "#7A7A7A")+ ylim(0, 100) +
  scale_colour_manual(values = c("#008B8B", "#0A0A0A" ,"#7A7A7A","#551A8B")) + 
  # theme(legend.position="none")+
  labs(y = "Percent Germination", title = "E1D2", subtitle = "Figure S4a", x = "")

ggsave("LZ8_4A_HaplotypeE1.png", width = 3, height = 3, units = "in")

ggplot(ATol, aes(x = OverallTolAlleles, y = E2D3)) +
  geom_point(aes(colour = ATol$Color), size = 2)+ theme_bw() + 
  theme(panel.grid.minor = element_blank(),
        panel.border = element_rect(colour = "#7D7D7D"), panel.background = element_blank(),
        axis.line = element_line(size=0.5))   +
  geom_smooth(method=lm,colour = "#7A7A7A")+ ylim(0, 100) +
  scale_colour_manual(values = c("#008B8B", "#0A0A0A" ,"#7A7A7A","#551A8B")) + 
  # theme(legend.position="none")+
  labs(y = "Percent Germination", title = "E2D3", subtitle = "Figure S4b", x = "Number of Favorable Alleles")

ggsave("LZ8_4A_HaplotypeE2.png", width = 3, height = 3, units = "in")

ggplot(ATol, aes(x = OverallTolAlleles, y = E3D1)) +
  geom_point(aes(colour = ATol$Color), size = 2)+ theme_bw() + 
  theme(panel.grid.minor = element_blank(),
        panel.border = element_rect(colour = "#7D7D7D"), panel.background = element_blank(),
        axis.line = element_line(size=0.5))   +
  geom_smooth(method=lm,colour = "#7A7A7A")+ ylim(0, 100) +
  scale_colour_manual(values = c("#008B8B", "#0A0A0A" ,"#7A7A7A","#551A8B"))+ 
  # theme(legend.position="none")+
  labs(y = "Percent Germination", title = "E3D1", subtitle = "Figure S4c", x = "")

ggsave("LZ8_4A_HaplotypeE3.png", width = 3, height = 3, units = "in")

Otis/ZakERA8 F2:3

The OZ8 dataset contains the Otis/ZakERA8 F2: F3 genotypic data, phenotypic data, and marker positions on chromosome 4A.

OZ8<-read.cross("csv",".","./OZ8_SNP6-SNP29.csv",na.strings=c("-","NA","."),BC.gen=0, F.gen=2)
OZ8
##   This is an object of class "cross".
##   It is too complex to print, so we provide just this summary.
##     BC(0)F(2) cross
## 
##     No. individuals:    108 
## 
##     No. phenotypes:     7 
##     Percent phenotyped: 100 98.1 98.1 98.1 98.1 98.1 98.1 
## 
##     No. chromosomes:    1 
##         Autosomes:      4A 
## 
##     Total markers:      4 
##     No. markers:        4 
##     Percent genotyped:  99.5 
##     Genotypes (%):      AA:24.0  AB:49.1  BB:27.0  not BB:0.0  not AA:0.0
# geno.image(OZ8)
# summary(OZ8$pheno)

Check for skewed markers

gt<-geno.table(OZ8)
gt[gt$P.value<0.05/totmar(OZ8),]  
## [1] chr     missing AA      AB      BB      not.BB  not.AA  P.value
## <0 rows> (or 0-length row.names)

No markers are skewed.

The phenotypes include percent germination (PG) is separated by day (d1…d5) and Germination Index (GI) is calculated over all 5 days:
> PG_d1, PG_d2, PG_d3, PG_d4, PG_d5, GI

Compite Interval Mapping

data_2 <- calc.genoprob(OZ8, step=0)
out.cimGI <- cim(data_2, pheno.col="GI",map.function=c("kosambi"),method=c("hk"))
a<-scanone(OZ8, method="hk", pheno.col = "GI", n.perm=1000)
summary(a) 

out.cimd5 <- cim(data_2, pheno.col="PG_d5",map.function=c("kosambi"),method=c("hk"))
out.cimd4 <- cim(data_2, pheno.col="PG_d4",map.function=c("kosambi"),method=c("hk"))
out.cimd3 <- cim(data_2, pheno.col="PG_d3",map.function=c("kosambi"),method=c("hk"))
out.cimd2 <- cim(data_2, pheno.col="PG_d2",map.function=c("kosambi"),method=c("hk"))
out.cimd1 <- cim(data_2, pheno.col="PG_d1",map.function=c("kosambi"),method=c("hk"))

Wrangle Results

out.cimd5$Pheno <- "d5"
out.cimd4$Pheno <- "d4"
out.cimd3$Pheno <- "d3"
out.cimd2$Pheno <- "d2"
out.cimd1$Pheno <- "d1"
out.cimGI$Pheno <- "GI"
Otera8 <- rbind(out.cimGI ,out.cimd5,out.cimd4,out.cimd3,out.cimd2,out.cimd1 )

Graph Results

ggplot(Otera8, aes(x=Otera8$pos, y=Otera8$lod, colour = factor(Otera8$Pheno)))+
  geom_line(size = 1.5)+
  theme_bw()+ theme(axis.text = font,  axis.title = font)+
  geom_hline(aes(yintercept = 1.73, colour = ""))+ 
  labs(x = "Chromosome 4A (cM)", y = "LOD") 

out.cimGI2 <- rbind(out.cimGI, out.cimd5)
ggplot(out.cimGI2, aes(x=out.cimGI2$pos, y=out.cimGI2$lod))+
  geom_line(aes(colour = factor(Pheno)),size = 1)+
  theme_bw()+ theme(axis.text = font,  axis.title = font)+
  geom_hline(aes(yintercept = 1.78))+ 
  labs(x = "Chromosome 4A (cM)", y = "LOD")  +
  ylim (0,10) +xlim (0,11)+
  scale_color_manual(values=c("#CD6600","#FFB90F")) + theme(legend.position="none")+
  ggsave("OZ8_4A_QTL.png", width = 3, height = 3, units = "in")

Interval Map of 4A Region

imap <- read.csv("D:/Shantel/Research Projects/3. Zak ERA8/1_Mapping Zak ERA8 Data/ERA8 Interval Mapping/ZZ8 5.1 5.2 Group Data for R.csv", na.string="-")
imap$Group <-  as.character(imap$Group)
imapf <-  filter(imap, Group == "ERA8-g" | Group == "I") 
t.test(PG_avg ~ Group, data=imapf)
## 
##  Welch Two Sample t-test
## 
## data:  PG_avg by Group
## t = -4.5576, df = 41.888, p-value = 4.435e-05
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -41.06224 -15.85678
## sample estimates:
## mean in group ERA8-g      mean in group I 
##             24.73684             53.19635

Repeat for other groups

imapf <-  filter(imap, Group == "Zak" | Group == "I") 
t.test(PG_avg ~ Group, data=imapf)
imapf <-  filter(imap, Group == "Zak-g" | Group == "I") 
t.test(PG_avg ~ Group, data=imapf)

imapf <-  filter(imap, Group == "Zak-g" | Group == "Zak") 
t.test(PG_avg ~ Group, data=imapf)

imapf <-  filter(imap, Group == "ERA8-g" | Group == "II") 
t.test(PG_avg ~ Group, data=imapf)
imapf <-  filter(imap, Group == "Zak" | Group == "II") 
t.test(PG_avg ~ Group, data=imapf)



imapf <-  filter(imap, Group == "Zak-g" | Group == "III") 
t.test(PG_avg ~ Group, data=imapf)
imapf <-  filter(imap, Group == "ERA8-g" | Group == "III") 
t.test(PG_avg ~ Group, data=imapf)

imapf <-  filter(imap, Group == "Zak-g" | Group == "IV") 
t.test(PG_avg ~ Group, data=imapf)
imapf <-  filter(imap, Group == "ERA8-g" | Group == "IV") 
t.test(PG_avg ~ Group, data=imapf)

imapf <-  filter(imap, Group == "ERA8-g" | Group == "VI") 
t.test(PG_avg ~ Group, data=imapf)
imapf <-  filter(imap, Group == "Zak-g" | Group == "VI") 
t.test(PG_avg ~ Group, data=imapf)
imapf <-  filter(imap, Group == "ERA8" | Group == "VI") 
t.test(PG_avg ~ Group, data=imapf)

Plot Interval Map

imap$PG_avg <- as.integer(imap$PG_avg)
target <- c( "VII","VI","V","IV", "III", "II", "I", "Zak-g", "ERA8-g", "Zak", "ERA8")
require(gdata)
imap$Group<- reorder.factor( imap$Group, new.order=target)
library(ggplot2)
ggplot(imap, aes(imap$Group, imap$PG_avg)) +
  geom_boxplot(aes(fill = factor(color)))+ theme_bw() +
  scale_fill_manual(values=c( "#7A7A7A","#A2CD5A","#440154" ))+
  geom_jitter(width = 0.05)+
  scale_y_continuous(breaks = seq(0, 100,10))+
  coord_flip() + labs(title = "Figure 4e")

ggsave("20190430_ZZ8_IntervalMap.PNG", width = 10, height = 8, units = "in")

Session Information

sessionInfo()
## R version 3.5.3 (2019-03-11)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 17763)
## 
## Matrix products: default
## 
## locale:
## [1] LC_COLLATE=English_United States.1252 
## [2] LC_CTYPE=English_United States.1252   
## [3] LC_MONETARY=English_United States.1252
## [4] LC_NUMERIC=C                          
## [5] LC_TIME=English_United States.1252    
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] gdata_2.18.0         DT_0.5               forcats_0.4.0       
##  [4] stringr_1.4.0        dplyr_0.8.0.1        purrr_0.3.2         
##  [7] readr_1.3.1          tidyr_0.8.3          tibble_2.1.1        
## [10] ggplot2_3.1.1        tidyverse_1.2.1      qtl_1.44-9          
## [13] base64enc_0.1-3      RevoUtils_11.0.3     RevoUtilsMath_11.0.0
## 
## loaded via a namespace (and not attached):
##  [1] gtools_3.8.1     tidyselect_0.2.5 xfun_0.6         haven_2.1.0     
##  [5] lattice_0.20-38  colorspace_1.4-1 generics_0.0.2   htmltools_0.3.6 
##  [9] yaml_2.2.0       rlang_0.3.4      later_0.8.0      pillar_1.3.1    
## [13] glue_1.3.1       withr_2.1.2      modelr_0.1.4     readxl_1.3.1    
## [17] plyr_1.8.4       munsell_0.5.0    gtable_0.3.0     cellranger_1.1.0
## [21] rvest_0.3.3      htmlwidgets_1.3  evaluate_0.13    labeling_0.3    
## [25] knitr_1.22       httpuv_1.5.1     crosstalk_1.0.0  parallel_3.5.3  
## [29] broom_0.5.2      Rcpp_1.0.1       xtable_1.8-3     promises_1.0.1  
## [33] scales_1.0.0     backports_1.1.4  jsonlite_1.5     mime_0.6        
## [37] hms_0.4.2        digest_0.6.18    stringi_1.4.3    shiny_1.3.1     
## [41] grid_3.5.3       cli_1.1.0        tools_3.5.3      magrittr_1.5    
## [45] lazyeval_0.2.2   crayon_1.3.4     pkgconfig_2.0.2  xml2_1.2.0      
## [49] lubridate_1.7.4  assertthat_0.2.1 rmarkdown_1.12   httr_1.4.0      
## [53] rstudioapi_0.10  R6_2.3.0         nlme_3.1-137     compiler_3.5.3
LS0tDQp0aXRsZTogIlFUTCBNYXBwaW5nIG9mIEVSQTgiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiAic2hvdyIgDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiA1DQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgdGhlbWU6IGZsYXRseQ0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVZLiVtLiVkJylgIg0KLS0tDQoNCioqVGl0bGUqKjogRXhvbWUgc2VxdWVuY2luZyBvZiBidWxrZWQgc2VncmVnYW50cyBpZGVudGlmaWVkIGEgbm92ZWwgKlRhTUtLMy1BKiBhbGxlbGUgbGlua2VkIHRvIHRoZSB3aGVhdCAqRVJBOCogQUJBLWh5cGVyc2Vuc2l0aXZlIGdlcm1pbmF0aW9uIHBoZW5vdHlwZQ0KDQoqKkF1dGhvcnMqKjogU2hhbnRlbCBBLiBNYXJ0aW5leiwgT2x1d2F5ZXNpIFNob3Jpbm9sYSwgU2FtYW50aGEgQ29uc2VsbWFuLCBEZXZlbiBTZWUsIERhbmllbCBaLiBTa2lubmVyLCBDcmlzdG9iYWwgVWF1eSwgYW5kIENhbWlsbGUgTS4gU3RlYmVyDQoNClRoaXMgcmVwb3NpdG9yeSBjb250YWlucyBhbGwgZGF0YXNldHMgZm9yIHRoZSBwYXBlciwgTWFydGluZXogZXQgYWwuIDIwMjAsIGFuZCBjYW4gYmUgdXNlZCB0byBlbmFibGUgcmVwcm9kdWNpYmlsaXR5IG9mIHRoZSBRVEwgTWFwcGluZyBhbmQgZmlndXJlcyBjcmVhdGVkLiAgDQoNClRoZSBkYXRhc2V0cyBnZW5lcmF0ZWQgZHVyaW5nIGFuZC9vciBhbmFseXNlZCBkdXJpbmcgdGhlIGN1cnJlbnQgc3R1ZHkgYXJlIGF2YWlsYWJsZSBpbiB0aGUgR2l0SHViIHJlcG9zaXRvcnksIFtnaXRodWIuY29tL3NoYW50ZWwtbWFydGluZXovRVJBOC1NYXBwaW5nXShnaXRodWIuY29tL3NoYW50ZWwtbWFydGluZXovRVJBOC1NYXBwaW5nKS4gIA0KDQojIyMjIExvYWQgQWxsIERhdGENClRvIGRvd25sb2FkIGFsbCBvZiB0aGUgZGF0YXNldHMgdXNlZCBpbiB0aGlzIGFuYWx5c2lzOiANCmBgYHtyIGVjaG89RkFMU0V9DQpzZXREb3dubG9hZFVSSSA9IGZ1bmN0aW9uKGxpc3QsIGZpbGVuYW1lID0gc3RvcCgiJ2ZpbGVuYW1lJyBtdXN0IGJlIHNwZWNpZmllZCIpLCB0ZXh0SFRNTCA9ICIiLCBmaWxlZXh0ID0gIlJEYXRhIiwgZW52aXIgPSBwYXJlbnQuZnJhbWUoKSl7DQogIHJlcXVpcmUoYmFzZTY0ZW5jLHF1aWV0bHkgPSBUUlVFKQ0KICBkaXZuYW1lID0gcGFzdGUoc2FtcGxlKExFVFRFUlMpLGNvbGxhcHNlPSIiKQ0KICB0ZiA9IHRlbXBmaWxlKHBhdHRlcm49ZmlsZW5hbWUsIGZpbGVleHQgPSBmaWxlZXh0KQ0KICBzYXZlKGxpc3QgPSBsaXN0LCBmaWxlID0gdGYsIGVudmlyID0gZW52aXIpDQogIGZpbGVuYW1lV2l0aEV4dCA9IHBhc3RlKGZpbGVuYW1lLGZpbGVleHQsc2VwPSIuIikNCiAgDQogIHVyaSA9IGRhdGFVUkkoZmlsZSA9IHRmLCBtaW1lID0gImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIsIGVuY29kaW5nID0gImJhc2U2NCIpDQogIGNhdCgiPGEgc3R5bGU9J3RleHQtZGVjb3JhdGlvbjogbm9uZScgaWQ9JyIsZGl2bmFtZSwiJz48L2E+DQogICAgPHNjcmlwdD4NCiAgICB2YXIgYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTsNCiAgICB2YXIgZGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJyIsZGl2bmFtZSwiJyk7DQogICAgZGl2LmFwcGVuZENoaWxkKGEpOw0KICAgIGEuc2V0QXR0cmlidXRlKCdocmVmJywgJyIsdXJpLCInKTsNCiAgICBhLmlubmVySFRNTCA9ICciLHRleHRIVE1MLCInICsgJyAoIixmaWxlbmFtZVdpdGhFeHQsIiknOw0KICAgIGlmICh0eXBlb2YgYS5kb3dubG9hZCAhPSAndW5kZWZpbmVkJykgew0KICAgICAgYS5zZXRBdHRyaWJ1dGUoJ2Rvd25sb2FkJywgJyIsZmlsZW5hbWVXaXRoRXh0LCInKTsNCiAgICB9ZWxzZXsNCiAgICAgIGEuc2V0QXR0cmlidXRlKCdvbmNsaWNrJywgJ2NvbmZpcm0oXCJZb3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUgZG93bmxvYWQgSFRNTDUgYXR0cmlidXRlLiBZb3UgbXVzdCByZW5hbWUgdGhlIGZpbGUgdG8gIixmaWxlbmFtZVdpdGhFeHQsIiBhZnRlciBkb3dubG9hZGluZyBpdCAob3IgdXNlIENocm9tZS9GaXJlZm94L09wZXJhKS4gXCIpJyk7DQogICAgfQ0KICAgIDwvc2NyaXB0PiIsDQogICAgc2VwPSIiKQ0KfQ0KZSA8LSBsb2FkKCIuL0VSQTgtTWFwcGluZy1EYXRhLlJEYXRhIikNCmBgYA0KDQpgYGB7ciByZXN1bHRzPSdhc2lzJyxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9DQpzZXREb3dubG9hZFVSSSgiZSIsIGZpbGVuYW1lID0gIkVSQTgtTWFwcGluZy1EYXRhIikNCmBgYA0KPC9icj4gDQpPbmNlIGRvd25sb2FkZWQsIHRoZSBlbnZpcm9ubWVudCBjYW4gYmUgbG9hZGVkOiAgDQpgYGB7ciBldmFsID0gRkFMU0V9DQpsb2FkKCJFUkE4LU1hcHBpbmctRGF0YS5SRGF0YSIpDQpgYGANCg0KIyMjIyBMb2FkIExpYnJhcmllcw0KYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCmxpYnJhcnkocXRsKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpmb250PC1lbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgIHNpemUgPSAxNikgI2dncGxvdCBhZXN0aGV0aWMNCiMgbGlicmFyeShrYWJsZUV4dHJhKQ0KIyBsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShEVCkgDQpza2V0Y2ggPSBodG1sdG9vbHM6OndpdGhUYWdzKHRhYmxlKCAgICAjdGFibGUgYWVzdGhldGljDQogIGNsYXNzID0gJ2Rpc3BsYXknLA0KICB0aGVhZCgNCiAgICB0cigNCiAgICAgIHRoKHJvd3NwYW4gPSAyLCAnU3BlY2llcycpLA0KICAgICAgdGgoY29sc3BhbiA9IDIsICdTZXBhbCcpLA0KICAgICAgdGgoY29sc3BhbiA9IDIsICdQZXRhbCcpDQogICAgKSwNCiAgICB0cigNCiAgICAgIGxhcHBseShyZXAoYygnTGVuZ3RoJywgJ1dpZHRoJyksIDIpLCB0aCkNCiAgICApDQogICkNCikpIA0KYGBgDQoNCiMjIFphay9aYWtFUkE4IEJDM0YyOjMNCiMjIyMgQWZ0ZXItcmlwZW5pbmcgdGltZWNvdXJzZSAgDQoNCg0KYGBge3IgZXZhbCA9IEZBTFNFfQ0KWlBhckFCQSA8LSByZWFkLmNzdigiLi9aWjhBUlRDX0UxLmNzdiIsIGhlYWRlciA9IFRSVUUsIG5hLnN0cmluZz0iTkEiKSANCmBgYA0KDQoNCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpaUGFyQUJBJEFCQV91TSA8LSBhcy5jaGFyYWN0ZXIoWlBhckFCQSRBQkFfdU0pDQpaUGFyQUJBJEdlbm8gPC0gYXMuY2hhcmFjdGVyKFpQYXJBQkEkR2VubykNClBhckFCQWYgPC0NCiAgWlBhckFCQSAlPiUNCiAgICBmaWx0ZXIoR2VubyAhPSAiWmFrLi4yLjIuNiIsIEdlbm8gIT0gIjk1LjMuOTEuNCIgLCBHZW5vICE9ICJaYWsuLjIuMi44IikNCg0KUGFyQUJBMiA8LSBzdWJzZXQoUGFyQUJBZiwgUGFyQUJBZiRBQkFfdU0gPT0gIjAiICkNCmdncGxvdChkYXRhID0gUGFyQUJBMiAsIGFlcyh4PUFSX3drLCB5PVBHX2Q1LCBjb2xvciA9IEdlbm8pKSArDQogIGdlb21fbGluZShzaXplPTEuNSkgKw0KICBnZW9tX3BvaW50KGFlcyhzaXplID0gMykpKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVBHX2Q1LVBHX1N0ZCwgeW1heD1QR19kNStQR19TdGQpLCB3aWR0aD0xLA0KICAgICAgICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgwLjA1KSkrDQogIHlsaW0oMCwxMDApKyB0aGVtZV9idygpKyB0aGVtZShheGlzLnRleHQgPSBmb250LCBheGlzLnRpdGxlID0gZm9udCkrDQogICMgbGFicyh0aXRsZSA9ICJGaWd1cmUgUzJhIiwgc3VidGl0bGUgPSAiMHVNIEFCQSAoTm8gSG9ybW9uZSkiLCB5ID0gIlBlcmNlbnQgR2VybWluYXRpb24iLCB4ID0gIldlZWtzIEFmdGVyLXJpcGVuZWQiKSsNCiAgbGFicyh0aXRsZSA9ICIwdU0gQUJBIChObyBIb3Jtb25lKSIsIHkgPSAiUGVyY2VudCBHZXJtaW5hdGlvbiIsIHggPSAiV2Vla3MgQWZ0ZXItcmlwZW5lZCIpKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiIzQ0MDE1NCIsIiNBMkNENUEiKSkNCmdnc2F2ZSgiMjAxOTA5MjNfWlo4X1BhcmVudHNfTUVTLnBuZyIsIHdpZHRoID0gNSwgaGVpZ2h0ID0gNSwgdW5pdHMgPSAiaW4iKQ0KDQpQYXJBQkEyIDwtIHN1YnNldChQYXJBQkFmLCBQYXJBQkFmJEFCQV91TSA9PSAiMiIpDQpnZ3Bsb3QoZGF0YSA9IFBhckFCQTIgLCBhZXMoeD1BUl93aywgeT1QR19kNSwgY29sb3IgPSBHZW5vKSkgKw0KICBnZW9tX2xpbmUoc2l6ZT0xLjUpICsNCiAgZ2VvbV9wb2ludChhZXMoc2l6ZSA9IDMpKSsNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1QR19kNS1QR19TdGQsIHltYXg9UEdfZDUrUEdfU3RkKSwgd2lkdGg9MSwNCiAgICAgICAgICAgICAgICAgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoMC4wNSkpKw0KICB5bGltKDAsMTAwKSsgdGhlbWVfYncoKSsgdGhlbWUoYXhpcy50ZXh0ID0gZm9udCwgYXhpcy50aXRsZSA9IGZvbnQpKw0KICAjIGxhYnModGl0bGUgPSAiRmlndXJlIFMyYiIsIHN1YnRpdGxlID0gIjJ1TSBBQkEiLCB5ID0gIlBlcmNlbnQgR2VybWluYXRpb24iLCB4ID0gIldlZWtzIEFmdGVyLXJpcGVuZWQiKSsNCiAgbGFicyh0aXRsZSA9ICIydU0gQUJBIiwgeSA9ICJQZXJjZW50IEdlcm1pbmF0aW9uIiwgeCA9ICJXZWVrcyBBZnRlci1yaXBlbmVkIikrIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCIjNDQwMTU0IiwiI0EyQ0Q1QSIpKQ0KZ2dzYXZlKCIyMDE5MDkyM19aWjhfUGFyZW50c19BQkEucG5nIiwgd2lkdGggPSA1LCBoZWlnaHQgPSA1LCB1bml0cyA9ICJpbiIpDQoNCg0KDQpgYGANCg0KDQoNCg0KVGhlIGBaWjhgIGRhdGFzZXQgY29udGFpbnMgWmFrL1pha0VSQTggQkMzIEYyOjMgZ2Vub3R5cGljIGRhdGEsIHBoZW5vdHlwaWMgZGF0YSwgYW5kIG1hcmtlciBwb3NpdGlvbnMgb24gY2hyb21vc29tZSA0QS4gICAgDQpgYGB7ciBldmFsPUZBTFNFfQ0KWlo4IDwtIHJlYWQuY3Jvc3MoImNzdiIsIi4iLCIuL1paOF9TTlAxLVNOUF8zMF9hbGwuY3N2IixuYS5zdHJpbmdzPWMoIi0iLCJOQSIsIi4iKSxCQy5nZW49MywgRi5nZW49MikNCmBgYA0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCiMgWlo4IDwtIHJlYWQuY3Jvc3MoImNzdiIsIi4iLCIuL1paOF9TTlAxLVNOUF8zMF9hbGwuY3N2IixuYS5zdHJpbmdzPWMoIi0iLCJOQSIsIi4iKSxCQy5nZW49MywgRi5nZW49MikNClpaOA0KYGBgDQpQaGVub3R5cGVzIGluY2x1ZGU6IFBlcmNlbnQgR2VybWluYXRpb24gKGBQR2ApIGFuZCBHZXJtaW5hdGlvbiBJbmRleCAoYEdJYCkgIA0KDQojIyMjIENvbXBvc2l0ZSBJbnRlcnZhbCBNYXBwaW5nIA0KYGBge3J9DQpkYXRhXzIgPC0gY2FsYy5nZW5vcHJvYihaWjgsIHN0ZXA9MCkNCm91dC5jaW1QR2F2ZyA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IlBHIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbVBHYXZnJFRyYWl0IDwtICgiUEciKSANCm91dC5jaW1HSWF2ZyA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkdJIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUdJYXZnJFRyYWl0IDwtICgiR0kiKQ0KYGBgDQoNCiMjIyMgRGV0ZXJtaW5lIFNpZ25pZmljYW5jZSBUaHJlc2hob2xkICANCmBgYHtyIGV2YWwgPSBGQUxTRX0NCmEgPC0gc2Nhbm9uZShaWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiUEciLCBuLnBlcm09MTAwMCkNCmIgPC0gc2Nhbm9uZShaWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiR0kiLCBuLnBlcm09MTAwMCkNCnN1bW1hcnkoYSkgDQpzdW1tYXJ5KGIpDQpgYGANCg0KIyMjIyBXcmFuZ2xlIFJlc3VsdHMgIA0KYGBge3J9DQpaWjhfYWxsIDwtIHJiaW5kKG91dC5jaW1QR2F2Zywgb3V0LmNpbUdJYXZnKQ0KWlo4X2FsbCRQb3B1bGF0aW9uIDwtICgiYWxsIikNCmBgYA0KDQoqKiogICANCioqUmVwZWF0IENJTSBmb3IgdGhlIFg1LjEgc3Vic2V0IG9ubHkqKiAgIA0KYGBge3IgZXZhbCA9IEZBTFNFfQ0KZGF0YTUuMTwtcmVhZC5jcm9zcygiY3N2IiwiLiIsIi4vWlo4X1NOUDEtU05QXzMwXzUuMS5jc3YiLG5hLnN0cmluZ3M9YygiLSIsIk5BIiwiLiIpLEJDLmdlbj0zLCBGLmdlbj0yKQ0KYGBgDQpgYGB7ciAgZWNobyA9IEZBTFNFfQ0KZGF0YTUuMQ0KYGBgDQoNCmBgYHtyIGV2YWwgPSBGQUxTRX0NCmRhdGFfMiA8LSBjYWxjLmdlbm9wcm9iKGRhdGE1LjEsIHN0ZXA9MCkNCm91dC5jaW1QR2F2ZyA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IlBHIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbVBHYXZnJFRyYWl0IDwtICgiUEciKSANCm91dC5jaW1HSWF2ZyA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkdJIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0KYSA8LSBzY2Fub25lKGRhdGE1LjEsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiUEciLCBuLnBlcm09MTAwMCkNCmIgPC0gc2Nhbm9uZShkYXRhNS4xLCBtZXRob2Q9ImhrIiwgcGhlbm8uY29sID0gIkdJIiwgbi5wZXJtPTEwMDApDQpzdW1tYXJ5KGEpIA0Kc3VtbWFyeShiKSANClpaOF81LjEgPC0gcmJpbmQob3V0LmNpbVBHYXZnLCBvdXQuY2ltR0lhdmcpDQpaWjhfNS4xJFBvcHVsYXRpb24gPC0gKCI1LjEiKQ0KYGBgDQpgYGB7ciBlY2hvID0gRkFMU0V9DQpkYXRhXzIgPC0gY2FsYy5nZW5vcHJvYihkYXRhNS4xLCBzdGVwPTApDQpvdXQuY2ltUEdhdmcgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJQRyIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1QR2F2ZyRUcmFpdCA8LSAoIlBHIikgDQpvdXQuY2ltR0lhdmcgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJHSSIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1HSWF2ZyRUcmFpdCA8LSAoIkdJIikNClpaOF81LjEgPC0gcmJpbmQob3V0LmNpbVBHYXZnLCBvdXQuY2ltR0lhdmcpDQpaWjhfNS4xJFBvcHVsYXRpb24gPC0gKCI1LjEiKQ0KYGBgDQoNCg0KKioqICANCioqUmVwZWF0IENJTSBmb3IgdGhlIFg1LjJhIHN1YnNldCBvbmx5KiogICANCmBgYHtyIGV2YWwgPSBGQUxTRX0NCmRhdGE1LjJhPC1yZWFkLmNyb3NzKCJjc3YiLCIuIiwiLi9aWjhfU05QMS1TTlBfMzBfNS4yYS5jc3YiLG5hLnN0cmluZ3M9YygiLSIsIk5BIiwiLiIpLEJDLmdlbj0zLCBGLmdlbj0yKQ0KYGBgDQpgYGB7ciAgZWNobyA9IEZBTFNFfQ0KZGF0YTUuMmENCmBgYA0KDQoNCmBgYHtyICBldmFsID0gRkFMU0V9DQpkYXRhXzIgPC0gY2FsYy5nZW5vcHJvYihkYXRhNS4yYSwgc3RlcD0wKQ0Kb3V0LmNpbVBHYXZnIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iUEciLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltUEdhdmckVHJhaXQgPC0gKCJQRyIpIA0Kb3V0LmNpbUdJYXZnIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iR0kiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltR0lhdmckVHJhaXQgPC0gKCJHSSIpDQphIDwtIHNjYW5vbmUoZGF0YTUuMmEsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiUEciLCBuLnBlcm09MTAwMCkNCmIgPC0gc2Nhbm9uZShkYXRhNS4yYSwgbWV0aG9kPSJoayIsIHBoZW5vLmNvbCA9ICJHSSIsIG4ucGVybT0xMDAwKQ0Kc3VtbWFyeShhKSANCnN1bW1hcnkoYikgDQpaWjhfNS4yYSA8LSByYmluZChvdXQuY2ltUEdhdmcsIG91dC5jaW1HSWF2ZykNClpaOF81LjJhJFBvcHVsYXRpb24gPC0gKCI1LjJhIikNCmBgYA0KDQpgYGB7ciBlY2hvID0gRkFMU0V9DQpkYXRhXzIgPC0gY2FsYy5nZW5vcHJvYihkYXRhNS4yYSwgc3RlcD0wKQ0Kb3V0LmNpbVBHYXZnIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iUEciLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltUEdhdmckVHJhaXQgPC0gKCJQRyIpIA0Kb3V0LmNpbUdJYXZnIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iR0kiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltR0lhdmckVHJhaXQgPC0gKCJHSSIpDQpaWjhfNS4yYSA8LSByYmluZChvdXQuY2ltUEdhdmcsIG91dC5jaW1HSWF2ZykNClpaOF81LjJhJFBvcHVsYXRpb24gPC0gKCI1LjJhIikNCmBgYA0KDQoqKlJlcGVhdCBDSU0gZm9yIHRoZSBYNS4yYiBzdWJzZXQgb25seSoqICAgDQoNCmBgYHtyIGV2YWwgPSBGQUxTRX0NCmRhdGE1LjJiIDwtIHJlYWQuY3Jvc3MoImNzdiIsIi4iLCIuL1paOF9TTlAxLVNOUF8zMF81LjJiLmNzdiIsbmEuc3RyaW5ncz1jKCItIiwiTkEiLCIuIiksQkMuZ2VuPTMsIEYuZ2VuPTIpDQpgYGANCmBgYHtyICBlY2hvID0gRkFMU0V9DQpkYXRhNS4yYg0KYGBgDQoNCmBgYHtyIGV2YWwgPSBGQUxTRX0NCmRhdGFfMiA8LSBjYWxjLmdlbm9wcm9iKGRhdGE1LjJiLCBzdGVwPTApDQpvdXQuY2ltUEdhdmcgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJQRyIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1QR2F2ZyRUcmFpdCA8LSAoIlBHIikgDQpvdXQuY2ltR0lhdmcgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJHSSIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1HSWF2ZyRUcmFpdCA8LSAoIkdJIikNCmEgPC0gc2Nhbm9uZShkYXRhNS4yYiwgbWV0aG9kPSJoayIsIHBoZW5vLmNvbCA9ICJQRyIsIG4ucGVybT0xMDAwKQ0KYiA8LSBzY2Fub25lKGRhdGE1LjJiLCBtZXRob2Q9ImhrIiwgcGhlbm8uY29sID0gIkdJIiwgbi5wZXJtPTEwMDApDQpzdW1tYXJ5KGEpIA0Kc3VtbWFyeShiKSANClpaOF81LjJiIDwtIHJiaW5kKG91dC5jaW1QR2F2Zywgb3V0LmNpbUdJYXZnKQ0KWlo4XzUuMmIkUG9wdWxhdGlvbiA8LSAoIjUuMmIiKQ0KYGBgDQpgYGB7ciBlY2hvID0gRkFMU0V9DQpkYXRhXzIgPC0gY2FsYy5nZW5vcHJvYihkYXRhNS4yYiwgc3RlcD0wKQ0Kb3V0LmNpbVBHYXZnIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iUEciLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltUEdhdmckVHJhaXQgPC0gKCJQRyIpIA0Kb3V0LmNpbUdJYXZnIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iR0kiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltR0lhdmckVHJhaXQgPC0gKCJHSSIpDQpaWjhfNS4yYiA8LSByYmluZChvdXQuY2ltUEdhdmcsIG91dC5jaW1HSWF2ZykNClpaOF81LjJiJFBvcHVsYXRpb24gPC0gKCI1LjJiIikNCmBgYA0KDQojIyMjIEdyYXBoIFJlc3VsdHMNClFUTCBHcmFwaCBmb3IgR2VybWluYXRpb24gSW5kZXggKGBHSWApICANCmBgYHtyIGV2YWw9RkFMU0V9DQpaWjhfUVRMIDwtIHJiaW5kKFpaOF9hbGwsIFpaOF81LjEsIFpaOF81LjJiLCBaWjhfNS4yYSkNCkdJIDwtIFpaOF9RVExbKFpaOF9RVEwkVHJhaXQgJWluJSAiR0kiKSxdDQoNCmdncGxvdChkYXRhID0gR0kgLCBhZXMoeD1HSSRwb3MsIHk9R0kkbG9kKSkgKyANCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXI9R0kkUG9wdWxhdGlvbiksIHNpemU9MSkrZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDEuODUpKSsNCiAgdGhlbWVfYncoKSsgdGhlbWUoYXhpcy50ZXh0ID0gZm9udCwgIGF4aXMudGl0bGUgPSBmb250KSsgDQogIGxhYnMoeCA9ICJDaHJvbW9zb21lIDRBIEVSQTggUmVnaW9uIChjTSkiLCB5ID0gIkxPRCIpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIiM3OGM2NzkiLCAiIzAwNjgzNyIsICIjMzFhMzU0IiwiI0EyQ0Q1QSIpKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsNCiAgZ2dzYXZlKCJaWjhfNEFfUVRMLnBuZyIsIHdpZHRoID0gMywgaGVpZ2h0ID0gMywgdW5pdHMgPSAiaW4iKQ0KYGBgDQoNCmBgYHtyICBlY2hvPUZBTFNFfQ0KWlo4X1FUTCA8LSByYmluZChaWjhfYWxsLCBaWjhfNS4xLCBaWjhfNS4yYiwgWlo4XzUuMmEpDQpHSSA8LSBaWjhfUVRMWyhaWjhfUVRMJFRyYWl0ICVpbiUgIkdJIiksXQ0KDQpnZ3Bsb3QoZGF0YSA9IEdJICwgYWVzKHg9R0kkcG9zLCB5PUdJJGxvZCkpICsgDQogIGdlb21fbGluZShhZXMoY29sb3VyPUdJJFBvcHVsYXRpb24pLCBzaXplPTEpK2dlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSAxLjg1KSkrDQogIHRoZW1lX2J3KCkrIHRoZW1lKGF4aXMudGV4dCA9IGZvbnQsICBheGlzLnRpdGxlID0gZm9udCkrIA0KICBsYWJzKHggPSAiQ2hyb21vc29tZSA0QSBFUkE4IFJlZ2lvbiAoY00pIiwgeSA9ICJMT0QiLCB0aXRsZSA9ICAiRmlndXJlIDNhIikrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiIzc4YzY3OSIsICIjMDA2ODM3IiwgIiMzMWEzNTQiLCIjQTJDRDVBIikpICMrIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsNCiAgIyBnZ3NhdmUoIlpaOF80QV9RVEwucG5nIiwgd2lkdGggPSAzLCBoZWlnaHQgPSAzLCB1bml0cyA9ICJpbiIpDQpgYGANCg0KIyMgTG91aXNlL1pha0VSQTggUklMIEY2OjcgDQojIyMjIEFmdGVyLXJpcGVuaW5nIHRpbWVjb3Vyc2UgIA0KDQpgYGB7ciBldmFsID0gRkFMU0V9DQpQYXJBQkEgPC0gcmVhZC5jc3YoIkxaOEFSVENfMjAxNC5jc3YiLCBoZWFkZXIgPSBUUlVFLCBuYS5zdHJpbmc9Ik5BIikgDQpgYGANCg0KDQpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KUGFyQUJBJEFCQV91TSA8LSBhcy5jaGFyYWN0ZXIoUGFyQUJBJEFCQV91TSkNClBhckFCQSRHZW5vIDwtIGFzLmNoYXJhY3RlcihQYXJBQkEkR2VubykNClBhckFCQWYgPC0NCiAgUGFyQUJBICU+JQ0KICAgIGZpbHRlcihHZW5vICE9ICJFUkE4LjEiLCBHZW5vICE9ICJFUkE4LjMiICwgR2VubyAhPSAiRVJBOC40IikNCg0KUGFyQUJBMiA8LSBzdWJzZXQoUGFyQUJBZiwgUGFyQUJBZiRBQkFfdU0gPT0gIjIiICYgUGFyQUJBZiRBUl93ayAhPSA3KQ0KZ2dwbG90KGRhdGEgPSBQYXJBQkEyICwgYWVzKHg9QVJfd2ssIHk9UEdfZDUsIGNvbG9yID0gR2VubykpICsNCiAgZ2VvbV9saW5lKHNpemU9MS41KSArDQogIGdlb21fcG9pbnQoYWVzKHNpemUgPSAzKSkrDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49UEdfZDUtUEdfU3RkLCB5bWF4PVBHX2Q1K1BHX1N0ZCksIHdpZHRoPTEsDQogICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKDAuMDUpKSsNCiAgeWxpbSgwLDEwMCkrIHRoZW1lX2J3KCkrIHRoZW1lKGF4aXMudGV4dCA9IGZvbnQsIGF4aXMudGl0bGUgPSBmb250KSsNCiAgIyBsYWJzKHRpdGxlID0gIkZpZ3VyZSA1YSIpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIiM0NDAxNTQiLCIjMDA4QjhCIiwgIiNBMkNENUEiKSkNCmdnc2F2ZSgiMjAxOTAzMTNfMS02QVJXaG9sZV9QYXJlbnRzLnBuZyIsIHdpZHRoID0gNywgaGVpZ2h0ID0gNywgdW5pdHMgPSAiaW4iKQ0KDQoNClBhckFCQWMgPC0gc3Vic2V0KFBhckFCQSwgUGFyQUJBJEFSX3drID09IDcpDQp0YXJnZXQgPC0gYygiMCIsICIyIiwgIjUiLCAiMTAiKQ0KcmVxdWlyZShnZGF0YSkNClBhckFCQWMkQUJBX3VNIDwtIHJlb3JkZXIuZmFjdG9yKFBhckFCQWMkQUJBX3VNLCBuZXcub3JkZXI9dGFyZ2V0KQ0KZ2dwbG90KGRhdGEgPSBQYXJBQkFjICwgYWVzKHg9QUJBX3VNLCB5PVBHX2Q1LCBjb2xvciA9IEdlbm8sIHNoYXBlID0gQUJBX3VNKSkgKw0KICBnZW9tX3BvaW50KGFlcyhzaXplID0gNCkpKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVBHX2Q1LVBHX1N0ZCwgeW1heD1QR19kNStQR19TdGQpLCB3aWR0aD0uMiwNCiAgICAgICAgICAgICAgICAgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoMC4wNSkpKw0KICB5bGltKDAsMTAwKSsgdGhlbWVfYncoKSsgdGhlbWUoYXhpcy50ZXh0ID0gZm9udCwgYXhpcy50aXRsZSA9IGZvbnQpKw0KICAjIGxhYnModGl0bGUgPSAiRmlndXJlIDViIikrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiIzQ0MDE1NCIsICIjMDA4QjhCIiwgIiNBMkNENUEiKSkrDQogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXM9YygxLDE2LDE3LDE1KSkgIA0KZ2dzYXZlKCIyMDE5MDMxM183QVJDdXRfUGFyZW50cy5wbmciLCB3aWR0aCA9IDMsIGhlaWdodCA9IDUsIHVuaXRzID0gImluIikNCg0KYGBgDQoNCg0KIyMjIEVNUy1kZXJpdmVkIFNOUHMgDQpgYGB7ciAgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCiMgTFo4IDwtIHJlYWQuY3Jvc3MoImNzdiIsIi4iLCIuL0xaOF9TTlAxLVNOUDMwX01LSzMuY3N2IixuYS5zdHJpbmdzPWMoIi0iLCJOQSIsIi4iKSxCQy5nZW49MCwgRi5nZW49NSkNCkxaOA0KYGBgDQoNCg0KYGBge3J9DQpkYXRhXzIgPC0gY2FsYy5nZW5vcHJvYihkYXRhNS4yYiwgc3RlcD0wKQ0KZGF0YV8yIDwtIGNhbGMuZ2Vub3Byb2IoTFo4LCBzdGVwPTApDQoNCm91dC5jaW1FMVBHRDEgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFMUQxIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUxUEdEMSRUcmFpdCA8LSAoIkUxUEdEMSIpIA0Kb3V0LmNpbUUxUEdEMiA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUxRDIiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTFQR0QyJFRyYWl0IDwtICgiRTFQR0QyIikNCm91dC5jaW1FMVBHRDMgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFMUQzIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUxUEdEMyRUcmFpdCA8LSAoIkUxUEdEMyIpDQpvdXQuY2ltRTFQR0Q0IDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iRTFENCIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1FMVBHRDQkVHJhaXQgPC0gKCJFMVBHRDQiKQ0Kb3V0LmNpbUUxUEdENSA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUxRDUiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTFQR0Q1JFRyYWl0IDwtICgiRTFQR0Q1IikNCm91dC5jaW1FMUdJYXZnIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iRTFHSSIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1FMUdJYXZnJFRyYWl0IDwtICgiRTFHSWF2ZyIpDQoNCm91dC5jaW1FMlBHRDEgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFMkQxIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUyUEdEMSRUcmFpdCA8LSAoIkUyUEdEMSIpDQpvdXQuY2ltRTJQR0QyIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iRTJEMiIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1FMlBHRDIkVHJhaXQgPC0gKCJFMlBHRDIiKQ0Kb3V0LmNpbUUyUEdEMyA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUyRDMiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTJQR0QzJFRyYWl0IDwtICgiRTJQR0QzIikNCm91dC5jaW1FMlBHRDQgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFMkQ0IixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUyUEdENCRUcmFpdCA8LSAoIkUyUEdENCIpDQpvdXQuY2ltRTJQR0Q1IDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iRTJENSIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1FMlBHRDUkVHJhaXQgPC0gKCJFMlBHRDUiKQ0Kb3V0LmNpbUUyR0lhdmcgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFMkdJIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUyR0lhdmckVHJhaXQgPC0gKCJFMkdJYXZnIikNCg0Kb3V0LmNpbUUzUEdEMSA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUzRDEiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTNQR0QxJFRyYWl0IDwtICgiRTNQR0QxIikNCm91dC5jaW1FM1BHRDIgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFM0QyIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUzUEdEMiRUcmFpdCA8LSAoIkUzUEdEMiIpDQpvdXQuY2ltRTNQR0QzIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iRTNEMyIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1FM1BHRDMkVHJhaXQgPC0gKCJFM1BHRDMiKQ0Kb3V0LmNpbUUzUEdENCA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUzRDQiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTNQR0Q0JFRyYWl0IDwtICgiRTNQR0Q0IikNCm91dC5jaW1FM1BHRDUgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFM0Q1IixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUzUEdENSRUcmFpdCA8LSAoIkUzUEdENSIpDQpvdXQuY2ltRTNHSWF2ZyA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUzR0kiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTNHSWF2ZyRUcmFpdCA8LSAoIkUzR0lhdmciKQ0KDQpRVEwuTFo4LkVSQTggPC0gcmJpbmQob3V0LmNpbUUxUEdEMSwgb3V0LmNpbUUxUEdEMiwgb3V0LmNpbUUxUEdEMywgb3V0LmNpbUUxUEdENCwgb3V0LmNpbUUxUEdENSwgDQogICAgICAgICAgICAgICAgICAgICAgb3V0LmNpbUUxR0lhdmcsIG91dC5jaW1FMlBHRDEsIG91dC5jaW1FMlBHRDIsIG91dC5jaW1FMlBHRDMsIG91dC5jaW1FMlBHRDQsIA0KICAgICAgICAgICAgICAgICAgICAgIG91dC5jaW1FMlBHRDUsIG91dC5jaW1FMkdJYXZnLG91dC5jaW1FM1BHRDEsIG91dC5jaW1FM1BHRDIsIG91dC5jaW1FM1BHRDMsIA0KICAgICAgICAgICAgICAgICAgICAgIG91dC5jaW1FM1BHRDQsIG91dC5jaW1FM1BHRDUsIG91dC5jaW1FM0dJYXZnKQ0KUVRMLkxaOC5EYXkxIDwtIHJiaW5kKG91dC5jaW1FMVBHRDEsIG91dC5jaW1FMlBHRDEsb3V0LmNpbUUzUEdEMSkNClFUTC5MWjguR0kgPC0gcmJpbmQob3V0LmNpbUUxR0lhdmcsIG91dC5jaW1FMkdJYXZnLG91dC5jaW1FM0dJYXZnKQ0KYGBgDQoNCkNhbGN1bGF0aW5nIHRoZSBzaWduaWZpY2FudCBMT0Qgc2NvcmUgdGhyZXNob2xkIGZvciBlYWNoIHRyYWl0DQpgYGB7ciBldmFsPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KYTwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTFEMSIsIG4ucGVybT0xMDAwKQ0KYzwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTFEMiIsIG4ucGVybT0xMDAwKQ0KZDwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTFEMyIsIG4ucGVybT0xMDAwKQ0KZTwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTFENCIsIG4ucGVybT0xMDAwKQ0KZjwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTFENSIsIG4ucGVybT0xMDAwKQ0KZzwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTFHSSIsIG4ucGVybT0xMDAwKQ0KYjE8LXNjYW5vbmUoTFo4LCBtZXRob2Q9ImhrIiwgcGhlbm8uY29sID0gIkUyRDEiLCBuLnBlcm09MTAwMCkNCmMxPC1zY2Fub25lKExaOCwgbWV0aG9kPSJoayIsIHBoZW5vLmNvbCA9ICJFMkQyIiwgbi5wZXJtPTEwMDApDQpkMTwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTJEMyIsIG4ucGVybT0xMDAwKQ0KZTE8LXNjYW5vbmUoTFo4LCBtZXRob2Q9ImhrIiwgcGhlbm8uY29sID0gIkUyRDQiLCBuLnBlcm09MTAwMCkNCmYxPC1zY2Fub25lKExaOCwgbWV0aG9kPSJoayIsIHBoZW5vLmNvbCA9ICJFMkQ1Iiwgbi5wZXJtPTEwMDApDQpnMTwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTJHSSIsIG4ucGVybT0xMDAwKQ0KaDwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTNEMSIsIG4ucGVybT0xMDAwKQ0KaTwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTNEMiIsIG4ucGVybT0xMDAwKQ0Kajwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTNEMyIsIG4ucGVybT0xMDAwKQ0Kazwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTNENCIsIG4ucGVybT0xMDAwKQ0KbDwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTNENSIsIG4ucGVybT0xMDAwKQ0KbTwtc2Nhbm9uZShMWjgsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTNHSSIsIG4ucGVybT0xMDAwKQ0Kc3VtbWFyeShhKSAjMi4xMiBFMUQxIA0Kc3VtbWFyeShjKSAjMi4xMA0Kc3VtbWFyeShkKSAjMi4yMA0Kc3VtbWFyeShlKSAjMi4xNQ0Kc3VtbWFyeShmKSAjMi4wMg0Kc3VtbWFyeShnKSAjMS45OA0Kc3VtbWFyeShiMSkgIzIuMDYgRTJEMQ0Kc3VtbWFyeShjMSkgIzIuMTcNCnN1bW1hcnkoZDEpICMyLjAzDQpzdW1tYXJ5KGUxKSAjMS45Ng0Kc3VtbWFyeShmMSkgIzIuMTcNCnN1bW1hcnkoZzEpICMyLjEwDQpzdW1tYXJ5KGgpICMyLjAxIEUzRDENCnN1bW1hcnkoaSkgIzIuMDENCnN1bW1hcnkoaikgIzIuMjENCnN1bW1hcnkoaykgIzIuMTINCnN1bW1hcnkobCkgIzIuMTENCnN1bW1hcnkobSkgIzIuMTkNCmBgYA0KDQoNClFUTCBHcmFwaCBmb3IgR0kNCmBgYHtyIGV2YWwgPSBGQUxTRX0NCmdncGxvdChRVEwuTFo4LkdJLCBhZXMoeD1RVEwuTFo4LkdJJHBvcywgeT1RVEwuTFo4LkdJJGxvZCkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGZhY3RvcihUcmFpdCkpLHNpemUgPSAxKSsNCiAgdGhlbWVfYncoKSsgdGhlbWUoYXhpcy50ZXh0ID0gZm9udCwgIGF4aXMudGl0bGUgPSBmb250KSsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDIuMTApKSsgDQogIGxhYnMoeCA9ICJDaHJvbW9zb21lIDRBIChjTSkiLCB5ID0gTlVMTCkgKw0KICB5bGltICgwLDEwKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiIzk2Q0RDRCIsICIjMjBCMkFBIiwgIiMwMDg2OEIiKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArIA0KICBnZ3NhdmUoIkxaOF80QV9RVEwucG5nIiwgd2lkdGggPSAzLCBoZWlnaHQgPSAzLCB1bml0cyA9ICJpbiIpDQpgYGANCg0KYGBge3IgZWNobz1GQUxTRX0NCmdncGxvdChRVEwuTFo4LkdJLCBhZXMoeD1RVEwuTFo4LkdJJHBvcywgeT1RVEwuTFo4LkdJJGxvZCkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGZhY3RvcihUcmFpdCkpLHNpemUgPSAxKSsNCiAgdGhlbWVfYncoKSsgdGhlbWUoYXhpcy50ZXh0ID0gZm9udCwgIGF4aXMudGl0bGUgPSBmb250KSsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDIuMTApKSsgDQogIGxhYnMoeCA9ICJDaHJvbW9zb21lIDRBIChjTSkiLCB5ID0gTlVMTCwgdGl0bGUgPSAgIkZpZ3VyZSAzYiIpICsNCiAgeWxpbSAoMCwxMCkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIiM5NkNEQ0QiLCAiIzIwQjJBQSIsICIjMDA4NjhCIikpIA0KYGBgDQoNCiMjIyBHZW5vdHlwaW5nLWJ5LXNlcXVlbmNpbmcgU05Qcw0KDQpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KIyBMWjhHQlMgPC0gcmVhZC5jcm9zcygiY3N2IiwiLiIsIi4vTFo4X0dCU19hbGwuY3N2IixuYS5zdHJpbmdzPWMoIi0iLCJOQSIsIi4iKSxCQy5nZW49MCwgRi5nZW49NSkNCkxaOEdCUw0KYGBgDQoNClZpZXcgZ2Vub3R5cGljIGRhdGENCmBgYHtyfQ0KcGxvdC5tYXAoTFo4R0JTKQ0KZ2Vuby5pbWFnZShMWjhHQlMpDQpgYGANCg0KT21pdCBTa2V3ZWQgTWFya2VycyB3aXRoIHBvdGVudGlhbCBzZWdyZWdhdGlvbiBkaXN0b3J0aW9uDQpgYGB7cn0NCmd0PC1nZW5vLnRhYmxlKExaOEdCUykNCmcgPC0gZ3RbZ3QkUC52YWx1ZTwwLjA1L3RvdG1hcihMWjhHQlMpLF0NCmRhdGF0YWJsZShnLHJvd25hbWVzID0gRkFMU0UsIGNvbnRhaW5lciA9IHNrZXRjaCwgY2FwdGlvbiA9IGh0bWx0b29sczo6dGFncyRjYXB0aW9uKHN0eWxlID0gJ3RleHQtYWxpZ246IGxlZnQ7JywgJ1RhYmxlIEEgLSBTa2V3ZWQgR0JTIG1hcmtlcnMgJykpDQpgYGANCg0KYGBge3J9DQpkcm9wIDwtIGMoICJBMTUzMjhfM0FfN0FfNzAiICwiQTIzNTk2X3Vua183MCIgLCJBMTQ4NF91bmtfNzAiICwiQTEzMDE2XzFCXzcwIiAsIkExNTk0MF8xQl8xMDAiICwiQTk1OTFfMUJfMTAwIiAsIkE1NzZfMUJfNzAiICwiQTE4MTA0XzFEXzEwMCIgLCJBMjcwMTRfMUJfMkJfMTAwIiwiQTE3OTY3XzJEXzEwMCIgLCJBMTM5NzhfMkRfNzAiICwiQTI1NzQyXzNBXzEwMCIgLCJBMTgzMzJfM0FfNzAiICwiQTEyNzc3XzNEXzEwMCIgLCJBMjczXzRBXzEwMCIgLCJBMjEyNDVfNEFfNzAiICwiQTEwNDkxXzRBXzcwIiAsIkExODM3N180QV80Ql83MCIgLCJBMjUwMDBfNEJfNzAiICwiQTI1NDQxXzRCXzEwMCIgLCJBNDAzNV80RF8xMDAiICwiQTE4Mzc5XzREXzEwMCIgLCJBMTgwMDlfNERfNzAiICwiQTE5MDk5XzREXzdEXzEwMCIsIkExNjMyOF80RF83MCIgLCJBMTE4NDhfNERfNzAiICwiQTEyMjA5XzREXzEwMCIgLCJBMjc2NTJfNERfMTAwIiAsIkEyMTI3NV81QV8xMDAiICwiQTI1ODc3XzVBXzEwMCIgLCJBMjU0MzlfNUFfNzAiICwiQTI1NDM4X3Vua183MCIgLCJBMjA5NjlfNUFfNzAiICwiQTgwOTdfNUFfMTAwIiAsIkExOTcyM181QV8xMDAiICwiQTExNjAyXzVBXzEwMCIgLCJBNzc4MV81QV8xMDAiICwiQTExMTg1XzVEXzEwMCIgLCJBMjc3NjlfNURfMTAwIiAsIkExNjI2M18zRF81RF8xMDAiLCJBMTg2MDdfNURfMTAwIiAsIkEyNTcyNV81RF8xMDAiICwiQTE5MDBfNkFfNzAiICwiQTExOTEwXzNBXzZBXzcwIiAsIkEyNTI2NF82QV83MCIgLCJBMjA4NjZfNkFfMTAwIiAsIkExMTU4NV82Ql83MCIgLCJBMTE5NjdfNkJfMTAwIiAsIkEyMDI1NV82Ql8xMDAiICwiQTE5OTU5XzZCXzcwIiAsIkEyNzg3OF82Ql83MCIgLCJBMjgxNzlfNkJfMTAwIiAsIkEyODUzNl82Ql83MCIgLCJBMTQ2MF82Ql8xMDAiICwiQTk4MTFfNkJfMTAwIiAsIkExNjMyOF82Ql8xMDAiICwiQTEzNDQyXzZCXzcwIiAsIkEyNjY1MF8zQV80Ql83MCIgLCJBODEwMV82Ql8xMDAiICwiQTc3MThfNkJfNkRfNzAiICwiQTEwMTM4XzZCXzcwIiAsIkEyNzU2Nl91bmtfNzAiICwiQTE1MTk1X3Vua183MCIgLCJBMTU2MzlfdW5rXzEwMCIgLCJBMTA1OTZfNkJfMTAwIiAsIkEyNzg2N191bmtfMTAwIiAsIkExMDU5OV91bmtfMTAwIiAsIkEyMDYxOV82Ql8xMDAiICwiQTcwNzBfNkJfMTAwIiAsIkE2NzEzXzFCXzZCXzcwIiAsIkEyMjIxNV82Ql8xMDAiICwiQTQ5OV81RF8xMDAiICwiQTIxNzg4XzZEXzcwIiAsIkEyMTk5NV82RF8xMDAiICwiQTE4Mzg5XzZEXzEwMCIgLCJBMTE2OTFfNkRfMTAwIiAsIkExMTMxNl82RF83MCIgLCJBMjg2NDlfNkRfNzAiICwiQTI4ODgxXzZEXzEwMCIgLCJBMTgwNzFfNkRfMTAwIiAsIkE4MDE2XzdBXzdEXzEwMCIgLCJBNjYzN191bmtfNzAiICwiQTc0NzFfN0FfMTAwIiAsIkExMjMyNF80Ql83Ql83MCIgLCJBMTMzODhfN0JfMTAwIiAsIkEyODE0N183Ql8xMDAiICwiQTI3ODUxXzdCXzcwIiAsIkExMTg0Ml83RF83MCIgLCJBMjgyMjhfN0RfMTAwIiAsIkEyMTQ4Nl83RF8xMDAiICwiQTI3OTI4XzdEXzcwIiAsIkExODk4OV91bmtfMTAwIiwiQTcxMDBfN0FfNzAiLCJBMjMxNTBfdW5rXzcwIikNCkxaOEdCUyA8LSBkcm9wLm1hcmtlcnMoTFo4R0JTLCBkcm9wKQ0KZ3Q8LWdlbm8udGFibGUoTFo4R0JTKQ0KZ3RbZ3QkUC52YWx1ZTwwLjA1L3RvdG1hcihMWjhHQlMpLF0NCmBgYA0KDQojIyMjIENvbXBvc2l0ZSBJbnRlcnZhbCBNYXBwaW5nDQpBY3Jvc3MgYWxsIHRyYWl0cyAgDQpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KZGF0YV8yIDwtIGNhbGMuZ2Vub3Byb2IoTFo4R0JTLCBzdGVwPTApDQpvdXQuY2ltRTFQR0QxIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iRTFEMSIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1FMVBHRDEkVHJhaXQgPC0gKCJFMVBHRDEiKSANCm91dC5jaW1FMVBHRDIgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFMUQyIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUxUEdEMiRUcmFpdCA8LSAoIkUxUEdEMiIpDQpvdXQuY2ltRTFQR0QzIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iRTFEMyIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1FMVBHRDMkVHJhaXQgPC0gKCJFMVBHRDMiKQ0Kb3V0LmNpbUUxUEdENCA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUxRDQiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTFQR0Q0JFRyYWl0IDwtICgiRTFQR0Q0IikNCm91dC5jaW1FMVBHRDUgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFMUQ1IixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUxUEdENSRUcmFpdCA8LSAoIkUxUEdENSIpDQpvdXQuY2ltRTFHSWF2ZyA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUxR0kiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTFHSWF2ZyRUcmFpdCA8LSAoIkUxR0lhdmciKQ0Kb3V0LmNpbUUyUEdEMSA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUyRDEiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTJQR0QxJFRyYWl0IDwtICgiRTJQR0QxIikNCm91dC5jaW1FMlBHRDIgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFMkQyIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUyUEdEMiRUcmFpdCA8LSAoIkUyUEdEMiIpDQpvdXQuY2ltRTJQR0QzIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iRTJEMyIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1FMlBHRDMkVHJhaXQgPC0gKCJFMlBHRDMiKQ0Kb3V0LmNpbUUyUEdENCA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUyRDQiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTJQR0Q0JFRyYWl0IDwtICgiRTJQR0Q0IikNCm91dC5jaW1FMlBHRDUgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFMkQ1IixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUyUEdENSRUcmFpdCA8LSAoIkUyUEdENSIpDQpvdXQuY2ltRTJHSWF2ZyA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUyR0kiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTJHSWF2ZyRUcmFpdCA8LSAoIkUyR0lhdmciKQ0Kb3V0LmNpbUUzUEdEMSA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUzRDEiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTNQR0QxJFRyYWl0IDwtICgiRTNQR0QxIikNCm91dC5jaW1FM1BHRDIgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFM0QyIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUzUEdEMiRUcmFpdCA8LSAoIkUzUEdEMiIpDQpvdXQuY2ltRTNQR0QzIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iRTNEMyIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1FM1BHRDMkVHJhaXQgPC0gKCJFM1BHRDMiKQ0Kb3V0LmNpbUUzUEdENCA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUzRDQiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTNQR0Q0JFRyYWl0IDwtICgiRTNQR0Q0IikNCm91dC5jaW1FM1BHRDUgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJFM0Q1IixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbUUzUEdENSRUcmFpdCA8LSAoIkUzUEdENSIpDQpvdXQuY2ltRTNHSWF2ZyA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkUzR0kiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltRTNHSWF2ZyRUcmFpdCA8LSAoIkUzR0lhdmciKQ0KDQpRVEwuTFo4LkVSQTggPC0gcmJpbmQob3V0LmNpbUUxUEdEMSwgb3V0LmNpbUUxUEdEMiwgb3V0LmNpbUUxUEdEMywgb3V0LmNpbUUxUEdENCwgb3V0LmNpbUUxUEdENSwgb3V0LmNpbUUxR0lhdmcsIG91dC5jaW1FMlBHRDEsIG91dC5jaW1FMlBHRDIsIG91dC5jaW1FMlBHRDMsIG91dC5jaW1FMlBHRDQsIG91dC5jaW1FMlBHRDUsIG91dC5jaW1FMkdJYXZnLG91dC5jaW1FM1BHRDEsIG91dC5jaW1FM1BHRDIsIG91dC5jaW1FM1BHRDMsIG91dC5jaW1FM1BHRDQsIG91dC5jaW1FM1BHRDUsIG91dC5jaW1FM0dJYXZnKQ0KIyB3cml0ZS50YWJsZShRVEwuTFo4LkVSQTgsICIuL1FUTExaOEFsbC50eHQiLCBzZXA9Ilx0IikNCmBgYA0KDQpgYGB7ciBldmFsPUZBTFNFfQ0KYTwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTFEMSIsIG4ucGVybT0xMDAwKQ0KYzwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTFEMiIsIG4ucGVybT0xMDAwKQ0KZDwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTFEMyIsIG4ucGVybT0xMDAwKQ0KZTwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTFENCIsIG4ucGVybT0xMDAwKQ0KZjwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTFENSIsIG4ucGVybT0xMDAwKQ0KZzwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTFHSSIsIG4ucGVybT0xMDAwKQ0KYjE8LXNjYW5vbmUoTFo4R0JTLCBtZXRob2Q9ImhrIiwgcGhlbm8uY29sID0gIkUyRDEiLCBuLnBlcm09MTAwMCkNCmMxPC1zY2Fub25lKExaOEdCUywgbWV0aG9kPSJoayIsIHBoZW5vLmNvbCA9ICJFMkQyIiwgbi5wZXJtPTEwMDApDQpkMTwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTJEMyIsIG4ucGVybT0xMDAwKQ0KZTE8LXNjYW5vbmUoTFo4R0JTLCBtZXRob2Q9ImhrIiwgcGhlbm8uY29sID0gIkUyRDQiLCBuLnBlcm09MTAwMCkNCmYxPC1zY2Fub25lKExaOEdCUywgbWV0aG9kPSJoayIsIHBoZW5vLmNvbCA9ICJFMkQ1Iiwgbi5wZXJtPTEwMDApDQpnMTwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTJHSSIsIG4ucGVybT0xMDAwKQ0KaDwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTNEMSIsIG4ucGVybT0xMDAwKQ0KaTwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTNEMiIsIG4ucGVybT0xMDAwKQ0Kajwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTNEMyIsIG4ucGVybT0xMDAwKQ0Kazwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTNENCIsIG4ucGVybT0xMDAwKQ0KbDwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTNENSIsIG4ucGVybT0xMDAwKQ0KbTwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiRTNHSSIsIG4ucGVybT0xMDAwKQ0Kc3VtbWFyeShhKSAjDQpzdW1tYXJ5KGMpICMNCnN1bW1hcnkoZCkgIw0Kc3VtbWFyeShlKSAjDQpzdW1tYXJ5KGYpICMNCnN1bW1hcnkoZykgIw0Kc3VtbWFyeShiMSkgIw0Kc3VtbWFyeShjMSkgIw0Kc3VtbWFyeShkMSkgIw0Kc3VtbWFyeShlMSkgIw0Kc3VtbWFyeShmMSkgIw0Kc3VtbWFyeShnMSkgIw0Kc3VtbWFyeShoKSAjDQpzdW1tYXJ5KGkpICMNCnN1bW1hcnkoaikgIw0Kc3VtbWFyeShrKSAjDQpzdW1tYXJ5KGwpICMNCnN1bW1hcnkobSkgIw0KYGBgDQoNCg0KDQojIyMgSGVhZGluZyBhbmQgSGVpZ2h0ICANCg0KUVRMIEFuYWx5c2lzDQpgYGB7ciAgd2FybmluZz0gRkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpkYXRhXzIgPC0gY2FsYy5nZW5vcHJvYihMWjhHQlMsIHN0ZXA9MCkNCm91dC5jaW1IZWlnaHQgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJIZWlnaHQiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltSGVpZ2h0JFRyYWl0IDwtICgiSGVpZ2h0IikgDQpvdXQuY2ltSGVhZGluZyA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IkhlYWRpbmciLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltSGVhZGluZyRUcmFpdCA8LSAoIkhlYWRpbmciKQ0KYGBgDQoNCkNhbGN1bGF0ZSBTaWduaWZpY2FuY2UgVGhyZXNob2xkDQpgYGB7ciBldmFsPUZBTFNFfQ0KYTwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiSGVhZGluZyIsIG4ucGVybT0xMDAwKQ0Kc3VtbWFyeShhKSAjNC40MyA1JQ0KYjwtc2Nhbm9uZShMWjhHQlMsIG1ldGhvZD0iaGsiLCBwaGVuby5jb2wgPSAiSGVpZ2h0Iiwgbi5wZXJtPTEwMDApDQpzdW1tYXJ5KGIpICM0LjM4IDUlDQpgYGANCg0KIyMjIEdyYXBoIHRoZSBNYW5oYXR0ZW4gUGxvdA0KDQoNCkZvciBncmFwaGluZyBwdXJwb3NlcyBvbmx5LCBhZGQgYSBjb2x1bW4gdG8gZ2l2ZSB1bmlxdWUgcG9zaXRpb25zIGZvciBlYWNoIG1hcmtlciBwZXIgY2hyb21vc29tZS4gDQpgYGB7ciB3YXJuaW5nPSBGQUxTRSwgbWVzc2FnZT1GQUxTRX0NCiMgdW5pcXBvcyA8LSByZWFkLnRhYmxlKCIuL0dCU19VbmlxdWVQb3MudHh0IixoZWFkZXI9VFJVRSxuYS5zdHJpbmc9YygiIiwgIiAiLCAiTkEiLCAibmEiKSkNCnVuaXFwb3MkY2hyIDwtIE5VTEwNCnVuaXFwb3MkcG9zIDwtIE5VTEwNClFUTC5MWjguRVJBOCA8LSBhcy5kYXRhLmZyYW1lKFFUTC5MWjguRVJBOCkNCkxaOCAgPC0gY2JpbmQoUVRMLkxaOC5FUkE4LCB1bmlxcG9zKQ0KDQpnZ3Bsb3QoTFo4LCBhZXMoeD1MWjgkb3JkZXIsIHk9TFo4JGxvZCkpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBmYWN0b3IoR2Vub21lKSksc2l6ZSA9IDIpK3lsaW0oMCw2KSt0aGVtZV9idygpKyB0aGVtZShheGlzLnRleHQgPSBmb250LCAgYXhpcy50aXRsZSA9IGZvbnQsIGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSkrIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiIzBBMEEwQSIsICIjOEE4QThBIiwgIiNEMUQxRDEiLCIjQTJDRDVBIikpKyANCiAgbGFicyh4ID0gIkNocm9tb3NvbWUgMUEgLSA3RCBhbmQgVW5rbm93biIgLCB5ID0gIkxPRCIsc3VidGl0bGU9IkFCQSBTZW5zaXRpdml0eSBRVEwiKQ0KYGBgDQoNCmBgYHtyICB3YXJuaW5nPSBGQUxTRSwgbWVzc2FnZT1GQUxTRX0NCiMgdW5pcXBvc0FISCA8LSByZWFkLnRhYmxlKCIuL0dCU19VbmlxdWVQb3NfQUJBSGVhZEhlaS50eHQiLGhlYWRlcj1UUlVFLG5hLnN0cmluZz1jKCIiLCAiICIsICJOQSIsICJuYSIpKQ0KdW5pcXBvc0FISCRjaHIgPC0gTlVMTA0KdW5pcXBvc0FISCRwb3MgPC0gTlVMTA0KUVRMLkxaOC5FUkE4IDwtIHJiaW5kKG91dC5jaW1FMVBHRDEsIG91dC5jaW1FMVBHRDIsIG91dC5jaW1FMVBHRDMsIG91dC5jaW1FMVBHRDQsIA0KICAgICAgICAgICAgICAgICAgICAgIG91dC5jaW1FMVBHRDUsIG91dC5jaW1FMUdJYXZnLCBvdXQuY2ltRTJQR0QxLCBvdXQuY2ltRTJQR0QyLCANCiAgICAgICAgICAgICAgICAgICAgICBvdXQuY2ltRTJQR0QzLCBvdXQuY2ltRTJQR0Q0LCBvdXQuY2ltRTJQR0Q1LCBvdXQuY2ltRTJHSWF2ZywNCiAgICAgICAgICAgICAgICAgICAgICBvdXQuY2ltRTNQR0QxLCBvdXQuY2ltRTNQR0QyLCBvdXQuY2ltRTNQR0QzLCBvdXQuY2ltRTNQR0Q0LCANCiAgICAgICAgICAgICAgICAgICAgICBvdXQuY2ltRTNQR0Q1LCBvdXQuY2ltRTNHSWF2Zywgb3V0LmNpbUhlaWdodCwgb3V0LmNpbUhlYWRpbmcgKQ0KUVRMLkxaOC5FUkE4IDwtIGFzLmRhdGEuZnJhbWUoUVRMLkxaOC5FUkE4KQ0KUVRMLkxaOCAgPC0gY2JpbmQoUVRMLkxaOC5FUkE4LCB1bmlxcG9zQUhIKQ0KZ2dwbG90KFFUTC5MWjgsIGFlcyh4PVFUTC5MWjgkb3JkZXIsIHk9UVRMLkxaOCRsb2QpKSsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gZmFjdG9yKEdlbm9tZSkpLHNpemUgPSAyKSt5bGltKDAsNikrdGhlbWVfYncoKSsgDQogIHRoZW1lKGF4aXMudGV4dCA9IGZvbnQsICBheGlzLnRpdGxlID0gZm9udCwgYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpKSsgDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiIzBBMEEwQSIsICIjOEE4QThBIiwgIiNEMUQxRDEiLCIjQTJDRDVBIikpICsgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDQuNCkpKyANCiAgbGFicyh4ID0gIkNocm9tb3NvbWUgMUEgLSA3RCBhbmQgVW5rbm93biIgLCB5ID0gIkxPRCIsICB0aXRsZSA9ICJGaWd1cmUgUzViIiwgc3VidGl0bGU9IkFCQSwgSGVhZGluZyBEYXRlLCBhbmQgSGVpZ2h0IFFUTCIpDQoNClFUTC5MWjguNEEgPC0gIHN1YnNldChRVEwuTFo4ICwgIFFUTC5MWjgkY2hyPT0iNEEuMSIgfCBRVEwuTFo4JGNocj09IjRBLjIiIHwgUVRMLkxaOCRjaHI9PSI0QS4zIiApDQpnZ3Bsb3QoUVRMLkxaOC40QSwgYWVzKHg9UVRMLkxaOC40QSRvcmRlciwgeT1RVEwuTFo4LjRBJGxvZCkpKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBmYWN0b3IoY2hyKSksc2l6ZSA9IDIpK3lsaW0oMCw2KSt0aGVtZV9idygpKyANCiAgdGhlbWUoYXhpcy50ZXh0ID0gZm9udCwgIGF4aXMudGl0bGUgPSBmb250LCBheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCkpKyANCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCIjMEEwQTBBIiwgIiM4QThBOEEiLCAiI0QxRDFEMSIpKSArIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSA0LjQpKSsgDQogIGxhYnMoeCA9ICJDaHJvbW9zb21lIDRBIiAsIHkgPSAiTE9EIiwgIHRpdGxlID0gIkZpZ3VyZSBTNWMiLCBzdWJ0aXRsZT0iQUJBLCBIZWFkaW5nIERhdGUsIGFuZCBIZWlnaHQgUVRMIikNCg0KYGBgDQoNCkxpc3Qgb2YgU2lnbmlmaWNhbnQgUVRMIG9uIENocm9tb3NvbWUgNEEgDQpgYGB7ciAgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KUVRMLkxaOC40QSAlPiUgDQogIG11dGF0ZShsb2QgPSByb3VuZChsb2QsMikpICU+JQ0KICBmaWx0ZXIobG9kID4gNC40KSAlPiUNCiAgYXJyYW5nZShzdHJfZXh0cmFjdChjaHIsICdeLicpLCBwb3MpICU+JQ0KICBkcGx5cjo6c2VsZWN0KE1hcmtlciwgY2hyLCBwb3MsICBUcmFpdCwgbG9kKSAgJT4lDQogIGRhdGF0YWJsZSgpI3Jvd25hbWVzID0gRkFMU0UsIGNvbnRhaW5lciA9IHNrZXRjaCwgY2FwdGlvbiA9IGh0bWx0b29sczo6dGFncyRjYXB0aW9uKHN0eWxlID0gJ3RleHQtYWxpZ246IGxlZnQ7JywgJ1RhYmxlIFMxMSAtIFNpZ25pZmljYW50IFFUTCBvbiBjaHJvbW9zb21lIDRBJykpDQpgYGANCg0KDQojIyBTaWduaWZpY2FudCBBbGxlbGVzIGluIExaOCBwb3B1bGF0aW9uICANCg0KYGBge3IgZXZhbCA9IEZBTFNFfQ0KQVRvbDwtcmVhZC50YWJsZSgiQWxsVG9sUVRMQWxsZWxlcy50eHQiLCBoZWFkID0gVCxuYS5zdHJpbmc9YygiLiIsIiAiLCJOQSIsIm5hIiwiTmFOIikpDQpgYGANCg0KYGBge3Igd2FybmluZyA9IEZBTFNFfQ0KZ2dwbG90KEFUb2wsIGFlcyh4ID0gT3ZlcmFsbFRvbEFsbGVsZXMsIHkgPSBFMUQyKSkgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBBVG9sJENvbG9yKSwgc2l6ZSA9IDIpKyB0aGVtZV9idygpICsgDQogIHRoZW1lKHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiIzdEN0Q3RCIpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoc2l6ZT0wLjUpKSAgICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLGNvbG91ciA9ICIjN0E3QTdBIikrIHlsaW0oMCwgMTAwKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiIzAwOEI4QiIsICIjMEEwQTBBIiAsIiM3QTdBN0EiLCIjNTUxQThCIikpICsgDQogICMgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrDQogIGxhYnMoeSA9ICJQZXJjZW50IEdlcm1pbmF0aW9uIiwgdGl0bGUgPSAiRTFEMiIsIHN1YnRpdGxlID0gIkZpZ3VyZSBTNGEiLCB4ID0gIiIpDQpnZ3NhdmUoIkxaOF80QV9IYXBsb3R5cGVFMS5wbmciLCB3aWR0aCA9IDMsIGhlaWdodCA9IDMsIHVuaXRzID0gImluIikNCg0KZ2dwbG90KEFUb2wsIGFlcyh4ID0gT3ZlcmFsbFRvbEFsbGVsZXMsIHkgPSBFMkQzKSkgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBBVG9sJENvbG9yKSwgc2l6ZSA9IDIpKyB0aGVtZV9idygpICsgDQogIHRoZW1lKHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiIzdEN0Q3RCIpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoc2l6ZT0wLjUpKSAgICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLGNvbG91ciA9ICIjN0E3QTdBIikrIHlsaW0oMCwgMTAwKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiIzAwOEI4QiIsICIjMEEwQTBBIiAsIiM3QTdBN0EiLCIjNTUxQThCIikpICsgDQogICMgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrDQogIGxhYnMoeSA9ICJQZXJjZW50IEdlcm1pbmF0aW9uIiwgdGl0bGUgPSAiRTJEMyIsIHN1YnRpdGxlID0gIkZpZ3VyZSBTNGIiLCB4ID0gIk51bWJlciBvZiBGYXZvcmFibGUgQWxsZWxlcyIpDQpnZ3NhdmUoIkxaOF80QV9IYXBsb3R5cGVFMi5wbmciLCB3aWR0aCA9IDMsIGhlaWdodCA9IDMsIHVuaXRzID0gImluIikNCg0KZ2dwbG90KEFUb2wsIGFlcyh4ID0gT3ZlcmFsbFRvbEFsbGVsZXMsIHkgPSBFM0QxKSkgKw0KICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBBVG9sJENvbG9yKSwgc2l6ZSA9IDIpKyB0aGVtZV9idygpICsgDQogIHRoZW1lKHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiIzdEN0Q3RCIpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoc2l6ZT0wLjUpKSAgICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLGNvbG91ciA9ICIjN0E3QTdBIikrIHlsaW0oMCwgMTAwKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiIzAwOEI4QiIsICIjMEEwQTBBIiAsIiM3QTdBN0EiLCIjNTUxQThCIikpKyANCiAgIyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsNCiAgbGFicyh5ID0gIlBlcmNlbnQgR2VybWluYXRpb24iLCB0aXRsZSA9ICJFM0QxIiwgc3VidGl0bGUgPSAiRmlndXJlIFM0YyIsIHggPSAiIikNCmdnc2F2ZSgiTFo4XzRBX0hhcGxvdHlwZUUzLnBuZyIsIHdpZHRoID0gMywgaGVpZ2h0ID0gMywgdW5pdHMgPSAiaW4iKQ0KYGBgDQoNCg0KIyMgT3Rpcy9aYWtFUkE4IEYyOjMgDQoNClRoZSBgT1o4YCBkYXRhc2V0IGNvbnRhaW5zIHRoZSBPdGlzL1pha0VSQTggRjI6IEYzIGdlbm90eXBpYyBkYXRhLCBwaGVub3R5cGljIGRhdGEsIGFuZCBtYXJrZXIgcG9zaXRpb25zIG9uIGNocm9tb3NvbWUgNEEuICANCmBgYHtyIGV2YWwgPSBGQUxTRX0NCk9aODwtcmVhZC5jcm9zcygiY3N2IiwiLiIsIi4vT1o4X1NOUDYtU05QMjkuY3N2IixuYS5zdHJpbmdzPWMoIi0iLCJOQSIsIi4iKSxCQy5nZW49MCwgRi5nZW49MikNCmBgYA0KYGBge3Igd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KT1o4DQojIGdlbm8uaW1hZ2UoT1o4KQ0KIyBzdW1tYXJ5KE9aOCRwaGVubykNCmBgYA0KDQoqKkNoZWNrIGZvciBza2V3ZWQgbWFya2VycyoqICANCmBgYHtyfQ0KZ3Q8LWdlbm8udGFibGUoT1o4KQ0KZ3RbZ3QkUC52YWx1ZTwwLjA1L3RvdG1hcihPWjgpLF0gIA0KYGBgDQpObyBtYXJrZXJzIGFyZSBza2V3ZWQuICANCjwvYnI+DQpUaGUgcGhlbm90eXBlcyBpbmNsdWRlIHBlcmNlbnQgZ2VybWluYXRpb24gKGBQR2ApIGlzIHNlcGFyYXRlZCBieSBkYXkgKGQxLi4uZDUpIGFuZCBHZXJtaW5hdGlvbiBJbmRleCAoYEdJYCkgaXMgY2FsY3VsYXRlZCBvdmVyIGFsbCA1IGRheXM6ICANCj4gUEdfZDEsIAlQR19kMiwJUEdfZDMsCVBHX2Q0LAlQR19kNSwJR0kgIA0KDQojIyMjIENvbXBpdGUgSW50ZXJ2YWwgTWFwcGluZw0KYGBge3IgZXZhbCA9IEZBTFNFfQ0KZGF0YV8yIDwtIGNhbGMuZ2Vub3Byb2IoT1o4LCBzdGVwPTApDQpvdXQuY2ltR0kgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJHSSIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCmE8LXNjYW5vbmUoT1o4LCBtZXRob2Q9ImhrIiwgcGhlbm8uY29sID0gIkdJIiwgbi5wZXJtPTEwMDApDQpzdW1tYXJ5KGEpIA0KDQpvdXQuY2ltZDUgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJQR19kNSIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1kNCA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IlBHX2Q0IixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbWQzIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iUEdfZDMiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltZDIgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJQR19kMiIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1kMSA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IlBHX2QxIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0KYGBgDQoNCmBgYHtyIGVjaG8gPSBGQUxTRX0NCmRhdGFfMiA8LSBjYWxjLmdlbm9wcm9iKE9aOCwgc3RlcD0wKQ0Kb3V0LmNpbUdJIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iR0kiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltZDUgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJQR19kNSIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1kNCA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IlBHX2Q0IixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbWQzIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iUEdfZDMiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltZDIgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJQR19kMiIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1kMSA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IlBHX2QxIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0KYGBgDQoNCiMjIyMgV3JhbmdsZSBSZXN1bHRzDQpgYGB7cn0NCm91dC5jaW1kNSRQaGVubyA8LSAiZDUiDQpvdXQuY2ltZDQkUGhlbm8gPC0gImQ0Ig0Kb3V0LmNpbWQzJFBoZW5vIDwtICJkMyINCm91dC5jaW1kMiRQaGVubyA8LSAiZDIiDQpvdXQuY2ltZDEkUGhlbm8gPC0gImQxIg0Kb3V0LmNpbUdJJFBoZW5vIDwtICJHSSINCk90ZXJhOCA8LSByYmluZChvdXQuY2ltR0kgLG91dC5jaW1kNSxvdXQuY2ltZDQsb3V0LmNpbWQzLG91dC5jaW1kMixvdXQuY2ltZDEgKQ0KYGBgDQoNCmBgYHtyIGVjaG8gPSBGQUxTRX0NCmRhdGFfMiA8LSBjYWxjLmdlbm9wcm9iKE9aOCwgc3RlcD0wKQ0Kb3V0LmNpbUdJIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iR0kiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQoNCm91dC5jaW1kNSA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IlBHX2Q1IixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0KDQpvdXQuY2ltZDQgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJQR19kNCIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCm91dC5jaW1kMyA8LSBjaW0oZGF0YV8yLCBwaGVuby5jb2w9IlBHX2QzIixtYXAuZnVuY3Rpb249Yygia29zYW1iaSIpLG1ldGhvZD1jKCJoayIpKQ0Kb3V0LmNpbWQyIDwtIGNpbShkYXRhXzIsIHBoZW5vLmNvbD0iUEdfZDIiLG1hcC5mdW5jdGlvbj1jKCJrb3NhbWJpIiksbWV0aG9kPWMoImhrIikpDQpvdXQuY2ltZDEgPC0gY2ltKGRhdGFfMiwgcGhlbm8uY29sPSJQR19kMSIsbWFwLmZ1bmN0aW9uPWMoImtvc2FtYmkiKSxtZXRob2Q9YygiaGsiKSkNCg0Kb3V0LmNpbWQ1JFBoZW5vIDwtICJkNSINCm91dC5jaW1kNCRQaGVubyA8LSAiZDQiDQpvdXQuY2ltZDMkUGhlbm8gPC0gImQzIg0Kb3V0LmNpbWQyJFBoZW5vIDwtICJkMiINCm91dC5jaW1kMSRQaGVubyA8LSJkMSINCm91dC5jaW1HSSRQaGVubyA8LSJHSSINCk90ZXJhOCA8LSByYmluZChvdXQuY2ltR0kgLG91dC5jaW1kNSxvdXQuY2ltZDQsb3V0LmNpbWQzLG91dC5jaW1kMixvdXQuY2ltZDEgKQ0KYGBgDQoNCiMjIyMgR3JhcGggUmVzdWx0cyANCmBgYHtyIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZT1GQUxTRX0NCmdncGxvdChPdGVyYTgsIGFlcyh4PU90ZXJhOCRwb3MsIHk9T3RlcmE4JGxvZCwgY29sb3VyID0gZmFjdG9yKE90ZXJhOCRQaGVubykpKSsNCiAgZ2VvbV9saW5lKHNpemUgPSAxLjUpKw0KICB0aGVtZV9idygpKyB0aGVtZShheGlzLnRleHQgPSBmb250LCAgYXhpcy50aXRsZSA9IGZvbnQpKw0KICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gMS43MywgY29sb3VyID0gIiIpKSsgDQogIGxhYnMoeCA9ICJDaHJvbW9zb21lIDRBIChjTSkiLCB5ID0gIkxPRCIpIA0KYGBgDQoNCmBgYHtyIGV2YWwgPSBGQUxTRX0NCm91dC5jaW1HSTIgPC0gcmJpbmQob3V0LmNpbUdJLCBvdXQuY2ltZDUpDQpnZ3Bsb3Qob3V0LmNpbUdJMiwgYWVzKHg9b3V0LmNpbUdJMiRwb3MsIHk9b3V0LmNpbUdJMiRsb2QpKSsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBmYWN0b3IoUGhlbm8pKSxzaXplID0gMSkrDQogIHRoZW1lX2J3KCkrIHRoZW1lKGF4aXMudGV4dCA9IGZvbnQsICBheGlzLnRpdGxlID0gZm9udCkrDQogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSAxLjc4KSkrIA0KICBsYWJzKHggPSAiQ2hyb21vc29tZSA0QSAoY00pIiwgeSA9ICJMT0QiKSAgKw0KICB5bGltICgwLDEwKSAreGxpbSAoMCwxMSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiI0NENjYwMCIsIiNGRkI5MEYiKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsNCiAgZ2dzYXZlKCJPWjhfNEFfUVRMLnBuZyIsIHdpZHRoID0gMywgaGVpZ2h0ID0gMywgdW5pdHMgPSAiaW4iKQ0KYGBgDQoNCg0KYGBge3IgZWNobyA9IEZBTFNFfQ0Kb3V0LmNpbUdJMiA8LSByYmluZChvdXQuY2ltR0ksIG91dC5jaW1kNSkNCmdncGxvdChvdXQuY2ltR0kyLCBhZXMoeD1vdXQuY2ltR0kyJHBvcywgeT1vdXQuY2ltR0kyJGxvZCkpKw0KICBnZW9tX2xpbmUoYWVzKGNvbG91ciA9IGZhY3RvcihQaGVubykpLHNpemUgPSAxKSsNCiAgdGhlbWVfYncoKSsgdGhlbWUoYXhpcy50ZXh0ID0gZm9udCwgIGF4aXMudGl0bGUgPSBmb250KSsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDEuNzgpKSsgDQogIGxhYnMoeCA9ICJDaHJvbW9zb21lIDRBIChjTSkiLCB5ID0gIkxPRCIsIHRpdGxlID0gICJGaWd1cmUgM2MiKSAgKw0KICB5bGltICgwLDEwKSAreGxpbSAoMCwxMSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiI0NENjYwMCIsIiNGRkI5MEYiKSkgIysgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrDQojIGdnc2F2ZSgiT1o4XzRBX1FUTC5wbmciLCB3aWR0aCA9IDMsIGhlaWdodCA9IDMsIHVuaXRzID0gImluIikNCmBgYA0KDQoNCiMjIEludGVydmFsIE1hcCBvZiA0QSBSZWdpb24gIA0KDQoNCmBgYHtyIGV2YWwgPSBGQUxTRX0NCmltYXAgPC0gcmVhZC5jc3YoIkQ6L1NoYW50ZWwvUmVzZWFyY2ggUHJvamVjdHMvMy4gWmFrIEVSQTgvMV9NYXBwaW5nIFphayBFUkE4IERhdGEvRVJBOCBJbnRlcnZhbCBNYXBwaW5nL1paOCA1LjEgNS4yIEdyb3VwIERhdGEgZm9yIFIuY3N2IiwgbmEuc3RyaW5nPSItIikNCmBgYA0KDQoNCmBgYHtyfQ0KaW1hcCRHcm91cCA8LSAgYXMuY2hhcmFjdGVyKGltYXAkR3JvdXApDQppbWFwZiA8LSAgZmlsdGVyKGltYXAsIEdyb3VwID09ICJFUkE4LWciIHwgR3JvdXAgPT0gIkkiKSANCnQudGVzdChQR19hdmcgfiBHcm91cCwgZGF0YT1pbWFwZikNCmBgYA0KUmVwZWF0IGZvciBvdGhlciBncm91cHMgDQpgYGB7ciBldmFsID0gRkFMU0V9DQppbWFwZiA8LSAgZmlsdGVyKGltYXAsIEdyb3VwID09ICJaYWsiIHwgR3JvdXAgPT0gIkkiKSANCnQudGVzdChQR19hdmcgfiBHcm91cCwgZGF0YT1pbWFwZikNCmltYXBmIDwtICBmaWx0ZXIoaW1hcCwgR3JvdXAgPT0gIlphay1nIiB8IEdyb3VwID09ICJJIikgDQp0LnRlc3QoUEdfYXZnIH4gR3JvdXAsIGRhdGE9aW1hcGYpDQoNCmltYXBmIDwtICBmaWx0ZXIoaW1hcCwgR3JvdXAgPT0gIlphay1nIiB8IEdyb3VwID09ICJaYWsiKSANCnQudGVzdChQR19hdmcgfiBHcm91cCwgZGF0YT1pbWFwZikNCg0KaW1hcGYgPC0gIGZpbHRlcihpbWFwLCBHcm91cCA9PSAiRVJBOC1nIiB8IEdyb3VwID09ICJJSSIpIA0KdC50ZXN0KFBHX2F2ZyB+IEdyb3VwLCBkYXRhPWltYXBmKQ0KaW1hcGYgPC0gIGZpbHRlcihpbWFwLCBHcm91cCA9PSAiWmFrIiB8IEdyb3VwID09ICJJSSIpIA0KdC50ZXN0KFBHX2F2ZyB+IEdyb3VwLCBkYXRhPWltYXBmKQ0KDQoNCg0KaW1hcGYgPC0gIGZpbHRlcihpbWFwLCBHcm91cCA9PSAiWmFrLWciIHwgR3JvdXAgPT0gIklJSSIpIA0KdC50ZXN0KFBHX2F2ZyB+IEdyb3VwLCBkYXRhPWltYXBmKQ0KaW1hcGYgPC0gIGZpbHRlcihpbWFwLCBHcm91cCA9PSAiRVJBOC1nIiB8IEdyb3VwID09ICJJSUkiKSANCnQudGVzdChQR19hdmcgfiBHcm91cCwgZGF0YT1pbWFwZikNCg0KaW1hcGYgPC0gIGZpbHRlcihpbWFwLCBHcm91cCA9PSAiWmFrLWciIHwgR3JvdXAgPT0gIklWIikgDQp0LnRlc3QoUEdfYXZnIH4gR3JvdXAsIGRhdGE9aW1hcGYpDQppbWFwZiA8LSAgZmlsdGVyKGltYXAsIEdyb3VwID09ICJFUkE4LWciIHwgR3JvdXAgPT0gIklWIikgDQp0LnRlc3QoUEdfYXZnIH4gR3JvdXAsIGRhdGE9aW1hcGYpDQoNCmltYXBmIDwtICBmaWx0ZXIoaW1hcCwgR3JvdXAgPT0gIkVSQTgtZyIgfCBHcm91cCA9PSAiVkkiKSANCnQudGVzdChQR19hdmcgfiBHcm91cCwgZGF0YT1pbWFwZikNCmltYXBmIDwtICBmaWx0ZXIoaW1hcCwgR3JvdXAgPT0gIlphay1nIiB8IEdyb3VwID09ICJWSSIpIA0KdC50ZXN0KFBHX2F2ZyB+IEdyb3VwLCBkYXRhPWltYXBmKQ0KaW1hcGYgPC0gIGZpbHRlcihpbWFwLCBHcm91cCA9PSAiRVJBOCIgfCBHcm91cCA9PSAiVkkiKSANCnQudGVzdChQR19hdmcgfiBHcm91cCwgZGF0YT1pbWFwZikNCg0KYGBgDQoNClBsb3QgSW50ZXJ2YWwgTWFwDQpgYGB7ciB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQoNCmltYXAkUEdfYXZnIDwtIGFzLmludGVnZXIoaW1hcCRQR19hdmcpDQp0YXJnZXQgPC0gYyggIlZJSSIsIlZJIiwiViIsIklWIiwgIklJSSIsICJJSSIsICJJIiwgIlphay1nIiwgIkVSQTgtZyIsICJaYWsiLCAiRVJBOCIpDQpyZXF1aXJlKGdkYXRhKQ0KaW1hcCRHcm91cDwtIHJlb3JkZXIuZmFjdG9yKCBpbWFwJEdyb3VwLCBuZXcub3JkZXI9dGFyZ2V0KQ0KbGlicmFyeShnZ3Bsb3QyKQ0KZ2dwbG90KGltYXAsIGFlcyhpbWFwJEdyb3VwLCBpbWFwJFBHX2F2ZykpICsNCiAgZ2VvbV9ib3hwbG90KGFlcyhmaWxsID0gZmFjdG9yKGNvbG9yKSkpKyB0aGVtZV9idygpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoICIjN0E3QTdBIiwiI0EyQ0Q1QSIsIiM0NDAxNTQiICkpKw0KICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMDUpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwxMCkpKw0KICBjb29yZF9mbGlwKCkgKyBsYWJzKHRpdGxlID0gIkZpZ3VyZSA0ZSIpDQpnZ3NhdmUoIjIwMTkwNDMwX1paOF9JbnRlcnZhbE1hcC5QTkciLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4LCB1bml0cyA9ICJpbiIpDQpgYGANCg0KDQojIyBTZXNzaW9uIEluZm9ybWF0aW9uDQpgYGB7cn0NCnNlc3Npb25JbmZvKCkNCmBgYA0K