## Set-Up
knitr::opts_chunk$set(echo = TRUE)
library(tidyverse)
library(sparkline)
TODAY<-Sys.Date()
## ADD SPARKLINE FUNCTION (Only needed once)
formattableWithSL <- function(TableDF,rawDF,key,SLfield){
## Add sparkline field to TableDF
TableDF$sparkline <- TableDF[[key]]
## Now basically call formattable, passing in the vars
formattable(TableDF,list(
"sparkline"=function(z){
sapply(z,function(zz){knitr::knit(text = sprintf(
'`r sparkline(c(%s))`',
paste0(
rawDF[which(rawDF[,key] == zz),SLfield],
collapse=","
)),
quiet = TRUE
)})} ))
}
eBACH_QC_Database1 <- readxl::read_excel( "/Volumes/eBACH/MRI/QC_Output/eBACH_QC_Database.xlsx",
sheet = "PRE", col_types = c("numeric",
"text", "text", "date", "text", "text",
"text", "text", "text", "text", "text",
"text", "numeric", "text", "text",
"text", "text", "text", "text", "text",
"numeric", "text", "numeric", "numeric",
"numeric", "text", "text", "text",
"text", "numeric", "text", "text",
"text", "text", "text", "text", "text"))
eBACH_QC_Database1<-eBACH_QC_Database1[complete.cases(eBACH_QC_Database1$Subject),]
eBACH_QC_Database1$WeeklyReport<-eBACH_QC_Database1$`Weekly report?`
eBACH_QC_Database1$Date<-eBACH_QC_Database1$`Date of MRI Scan`
eBACH_QC_Database1$Session<-"MR1"
eBACH_QC_Database1$ScanNotes<-eBACH_QC_Database1$`Overall Scan Notes`
eBACH_QC_Database1$QC03<-eBACH_QC_Database1$Notes...20
eBACH_QC_Database1$QC04<-eBACH_QC_Database1$Notes...27
eBACH_QC_Database1<-eBACH_QC_Database1%>% select(Subject,Session,Date, WeeklyReport,ScanNotes,QC03, QC04)
eBACH_QC_Database1<-eBACH_QC_Database1[complete.cases(eBACH_QC_Database1$Subject),]
eBACH_QC_Database1<-as.tibble(eBACH_QC_Database1)
#eBACH_QC_Database1.tb<-kable(eBACH_QC_Database1) %>%
# kable_styling(bootstrap_options = c("responsive", "bordered"),full_width = T,font_size = 10)%>%
# row_spec(0, align='c')%>%
# column_spec(1, bold = T) %>%
# column_spec(2, width = "1cm",border_right = T) %>%
# column_spec(3, bold = F,width = "3cm" ) %>%
# column_spec(4, bold = T, width = "1cm", border_left = T) %>%
# column_spec(5, width = "10cm", border_right = F) %>%
# column_spec(6, width = "10cm")
# kableExtra::scroll_box(eBACH_QC_Database1.tb, height = "300pt", width = "700pt" )
-
/
eBACH_QC_Database3 <- readxl::read_excel("/Volumes/eBACH/MRI/QC_Output/eBACH_QC_Database.xlsx",
sheet = "POST")
eBACH_QC_Database3<-eBACH_QC_Database3[complete.cases(eBACH_QC_Database3$Subject),]
eBACH_QC_Database3$WeeklyReport<-eBACH_QC_Database3$`Weekly report?`
eBACH_QC_Database3$Session<-"MR3"
eBACH_QC_Database3$Date<-eBACH_QC_Database3$`Date of MRI Scan`
eBACH_QC_Database3$ScanNotes<-eBACH_QC_Database3$`Overall Scan Notes`
eBACH_QC_Database3$QC03<-eBACH_QC_Database3$Notes...27
eBACH_QC_Database3$QC04<-eBACH_QC_Database3$Notes...38
eBACH_QC_Database3<-eBACH_QC_Database3%>% select(Subject,WeeklyReport,Date,Session, ScanNotes,QC03, QC04)
eBACH_QC_Database3<-eBACH_QC_Database3[complete.cases(eBACH_QC_Database3$Subject),]
tmp<-rbind(eBACH_QC_Database1, eBACH_QC_Database2)
tmp2<-rbind(tmp, Exclude1)
eBACH.Admin<-rbind(tmp2, eBACH_QC_Database3)
MRIQC Admin Database
Baseline: 30
Withdrew After Baseline MRI: 4
--- Randomized: E1058, E1067
--- Dropped before randomized: E1027, E1031
Mid-Point: 7
Post-Intervention: 3
Import Master Spreadsheets for Report...
Check: MASTER Spreadsheets
September 10 2020
library(formattable)
# Average by Site
################
# Make Summary table w/ SPARK_LINE
eBACH<-arrange(eBACH, "Date")
eBACH<-eBACH[complete.cases(eBACH$cnr),]
res <- eBACH %>%
dplyr::group_by(Session) %>%
dplyr::summarise(N=n(),
'CNR'=round(mean(cnr),4),
'sd'=round(sd(cnr),4),
'cnr'=as.character(htmltools::as.tags(sparkline(c(cnr)))),
'FWHM'=round(mean(fwhm_avg),4),
'sd '=round(mean(fwhm_avg),4),
'fwhm'=as.character(htmltools::as.tags(sparkline(c(fwhm_avg)))),
SNR.mean=round(mean(snr_total),4),
'sd'=round(sd(snr_total),4),
"snr"=as.character(htmltools::as.tags(sparkline(c(snr_total)))),
SNRd.mean=round(mean(snrd_total),4),
'sd'=round(sd(snrd_total),4),
snrd=as.character(htmltools::as.tags(sparkline(c(snrd_total))))) %>%
formattable() %>%
formattable::as.htmlwidget()
res$dependencies <- c(res$dependencies,htmlwidgets:::widget_dependencies("sparkline", "sparkline"))
res
eBACH<-arrange(eBACH, "Date")
eBACH$months<-format(as.Date(eBACH$Date), "%b/%y")
# select part of the dataset and use it for plotting
eBACH$months<-factor(eBACH$months, levels=c("Jun/19", "Jul/19" ,"Sep/19" , "Oct/19" ,"Nov/19", "Dec/19" ,"Jan/20" ,"Feb/20", "Aug/20"))
TMP2<-eBACH %>% select(SubID, Session, months, cnr, fwhm_avg,snr_total,snrd_total)
TMP2<-reshape2::melt(TMP2, id.vars=c("SubID", "Session", "months"))
TMP2$Session<-as.factor(TMP2$Session)
ggstatsplot::grouped_ggbetweenstats(
data = TMP2,
x=months,
y = value,
grouping.var = variable,
plot.type = "violin",
type = "np",
conf.level = 0.99,
xlab = "report",
ylab = "value",
ggtheme = ggplot2::theme_gray(), # a different theme
package = "yarrr", # package from which color palette is to be taken
palette = "info2", # choosing a different color palette
outlier.tagging = TRUE,
outlier.label.args = list(color = "red"), # outlier point label color
ggstatsplot.layer = FALSE,
outlier.label = "SubID",
pairwise.comparisons = TRUE, # display results from pairwise comparisons
pairwise.display = "significant", # display only significant pairwise comparisons
# arguments relevant for ggstatsplot::combine_plots
title.text = "Annual Strutural IQM Report",
title.size = 12 )

snr_mean.compar<-compare_means(snr_total ~ months, eBACH)
datatable(snr_mean.compar, rownames = FALSE,
options = list(pageLength = 5))
MASTER Weekly Report == 0
eBACH$date<-format(as.Date(eBACH$Date),"%b/%d/%y")
NEW.table<-eBACH %>% filter(WeeklyReport=="0") %>% group_by(Session) %>% select(Subject, Session, date, ScanNotes, QC03,QC04)
DT::datatable(NEW.table, rownames = FALSE)
Structural Report
eBACH$cnrZ<-as.numeric(scale(eBACH$cnr, scale = T))
eBACH$fwhmZ<-as.numeric(scale(eBACH$fwhm_avg, scale = T))
eBACH$snrZ<-as.numeric(scale(eBACH$snr_total, scale = T))
eBACH$snrdZ<-as.numeric(scale(eBACH$snrd_total, scale = T))
eBACH$Report<-if_else(eBACH$WeeklyReport=="0", "New", "Current")
eBACH$Report<-as.factor(eBACH$Report)
eBACH<-arrange(eBACH, "Date")
res <- eBACH %>%
dplyr::group_by(Report) %>%
dplyr::summarise(N=n(),
'CNR'=round(mean(cnr),3),
' sd'=round(sd(cnr),3),
' z'= as.character(htmltools::as.tags(sparkline(c(cnrZ), type = "bar"))),
'FWHM'=round(mean(fwhm_avg),3),
'sd '=round(mean(fwhm_avg),3),
'Z'= as.character(htmltools::as.tags(sparkline(c(fwhmZ), type = "line"))),
"SNR"=round(mean(snr_total),3),
'.sd '=round(sd(snr_total),3),
'z '= as.character(htmltools::as.tags(sparkline(c(snrZ), type = "box"))),
'SNRd'=round(mean(snrd_total),3),
'sd.'=round(sd(snrd_total),3),
'Z '= as.character(htmltools::as.tags(sparkline(c(snrdZ), type = "box")))) %>%
formattable( align =c("l","l","r","l","l","r","l","l","r","l","l","r","l","l") ) %>%
formattable::as.htmlwidget()
res$dependencies <- c(res$dependencies,htmlwidgets:::widget_dependencies("sparkline", "sparkline"))
res
TMP<-eBACH %>% select(SubID, Session, Date, Report, cnr, fwhm_avg,snr_total,snrd_total)
TMP<-reshape2::melt(TMP, id.vars=c("SubID", "Session", "Date", "Report"))
TMP$Session<-as.factor(TMP$Session)
TMP$Report<-as.factor(TMP$Report)
# select part of the dataset and use it for plotting
ggstatsplot::grouped_ggbetweenstats(
data = TMP,
x=Report,
y = value,
grouping.var = variable,
plot.type = "violin",
type = "np",
conf.level = 0.99,
xlab = "report",
ylab = "value",
ggtheme = ggplot2::theme_gray(), # a different theme
package = "yarrr", # package from which color palette is to be taken
palette = "info2", # choosing a different color palette
outlier.tagging = TRUE,
outlier.label.args = list(color = "red"), # outlier point label color
title.size = 12,
ggstatsplot.layer = FALSE,
outlier.label = "SubID",
# arguments relevant for ggstatsplot::combine_plots
title.text = "Weekly MPRAGE Report",
sub.size = 3,
greedy=TRUE,
pairwise.comparisons = TRUE, # display results from pairwise comparisons
pairwise.display = "significant", # display only significant pairwise comparisons
stats.label.args = list(size = 2, direction = "y"))

SNR_Dens.plot<-ggdensity(eBACH, x = "snr_total",
add = "mean", rug = TRUE, na.rm=TRUE,
color = "Session", fill = "Session")
g <- ggplot(eBACH, aes(months, snr_total))
gbox_SNR_month<-g + geom_boxplot(aes(fill=factor(Session))) +
theme(axis.text.x = element_text(angle=65, vjust=0.6)) +
labs(title="Box plot",
subtitle="MPRAGE SNR Grouped by Month & Session",
x="Month",
y="MPRAGE SNR")
gridExtra::grid.arrange(SNR_Dens.plot, gbox_SNR_month, ncol=2)
# Violin plots with box plots inside
# :::::::::::::::::::::::::::::::::::::::::::::::::::
# Change fill color by groups: dose
# add boxplot with white fill colorRest.DF
my_comparisons.df<-compare_means(snr_total ~ Session , eBACH)
my_comparisons <- list( c("MR1", "MR2"),
c("MR1", "MR3"),
c("MR2", "MR3")
)
plot.anova1<-ggviolin(eBACH,
x = "Session", y = "snr_total",
fill = "Session", na.rm=TRUE,
add = "boxplot", add.params = list(fill = "white"))+
stat_compare_means(comparisons = my_comparisons, label = "p.signif") + # Add significance levels
stat_compare_means(label.y = 2) +
ggtitle("SNR by Session")+
theme(legend.position='right')
# Violin plots with box plots inside
# :::::::::::::::::::::::::::::::::::::::::::::::::::
# Change fill color by groups: dose
# add boxplot with white fill colorRest.DF
my_comparisons.df<-compare_means(cnr ~ Session , eBACH)
my_comparisons <- list( c("MR1", "MR2"),
c("MR1", "MR3"),
c("MR2", "MR3")
)
plot.anova2<-ggviolin(eBACH,
x = "Session", y = "cnr",
fill = "Session", na.rm=TRUE,
add = "boxplot", add.params = list(fill = "white"))+
stat_compare_means(comparisons = my_comparisons, label = "p.signif") + # Add significance levels
stat_compare_means(label.y = 2) +
ggtitle("CNR by Session")+
theme(legend.position='right')
gridExtra::grid.arrange(plot.anova1, plot.anova2, ncol=2)

MPRAGE_snr.compar<-compare_means(snr_total~Session, eBACH)
MPRAGE_snr.compar<-as.data.frame(MPRAGE_snr.compar)
DT::datatable(MPRAGE_snr.compar, rownames = FALSE)
Functional Report
Emotional Reappraisal Task
BOLD.emoreap.IQMs.df<-eBACH_BOLD
BOLD.emoreap.IQMs.df<-BOLD.emoreap.IQMs.df[BOLD.emoreap.IQMs.df$Task=="emoreap",]
BOLD.emoreap.IQMs.df<-BOLD.emoreap.IQMs.df[complete.cases(BOLD.emoreap.IQMs.df$dvars_nstd),]
BOLD.emoreap.IQMs.df$dvars_nstd<-digits(BOLD.emoreap.IQMs.df$dvars_nstd, digits = 4)
BOLD.emoreap.IQMs.df$fd_mean<-digits(BOLD.emoreap.IQMs.df$fd_mean, digits = 4)
BOLD.emoreap.IQMs.df$fwhm_avg<-digits(BOLD.emoreap.IQMs.df$fwhm_avg, digits = 4)
BOLD.emoreap.IQMs.df$snr<-digits(BOLD.emoreap.IQMs.df$snr, digits = 4)
BOLD.emoreap.IQMs.df$tsnr<-digits(BOLD.emoreap.IQMs.df$tsnr, digits = 4)
BOLD.emoreap.IQMs.df$gcor<-digits(BOLD.emoreap.IQMs.df$gcor, digits = 4)
BOLD.emoreap.IQMs.df<-BOLD.emoreap.IQMs.df[complete.cases(BOLD.emoreap.IQMs.df$Subject),]
BOLD.emoreap.IQMs.df<-as.data.frame(BOLD.emoreap.IQMs.df, rownames=FALSE)
BOLD.emoreap.IQMs.df<-arrange(BOLD.emoreap.IQMs.df,"Date" )
BOLD.emoreap.IQMs.df$Scan<-paste(BOLD.emoreap.IQMs.df$SubID,BOLD.emoreap.IQMs.df$Session, sep = "_" )
TMP3<-BOLD.emoreap.IQMs.df %>% select(SubID, Session,Date, Report,dvars_nstd ,fd_mean, snr,tsnr)
TMP3<-reshape2::melt(TMP3, id.vars=c("SubID","Session" ,"Date", "Report"))
# select part of the dataset and use it for plotting
ggstatsplot::grouped_ggbetweenstats(
data = TMP3,
x=Report,
y = value,
grouping.var = variable,
plot.type = "violin",
type = "np",
conf.level = 0.99,
xlab = "report",
ylab = "value",
ggtheme = ggplot2::theme_gray(), # a different theme
package = "yarrr", # package from which color palette is to be taken
palette = "info2", # choosing a different color palette
outlier.tagging = TRUE,
outlier.label.args = list(color = "red"), # outlier point label color
title.size = 12,
ggstatsplot.layer = FALSE,
outlier.label = "SubID",
# arguments relevant for ggstatsplot::combine_plots
title.text = "Weekly EmoReap. IQMs.df IQM Report",
sub.size = 3,
greedy=TRUE,
pairwise.comparisons = TRUE, # display results from pairwise comparisons
pairwise.display = "significant", # display only significant pairwise comparisons
stats.label.args = list(size = 2, direction = "y"))

BOLD.emoreap.IQMs.df<-eBACH_BOLD
BOLD.emoreap.IQMs.df<-BOLD.emoreap.IQMs.df[BOLD.emoreap.IQMs.df$Task=="emoreap",]
BOLD.emoreap.IQMs.df<-BOLD.emoreap.IQMs.df[complete.cases(BOLD.emoreap.IQMs.df$dvars_nstd),]
BOLD.emoreap.IQMs.df$dvars_nstd<-digits(BOLD.emoreap.IQMs.df$dvars_nstd, digits = 4)
BOLD.emoreap.IQMs.df$fd_mean<-digits(BOLD.emoreap.IQMs.df$fd_mean, digits = 4)
BOLD.emoreap.IQMs.df$fwhm_avg<-digits(BOLD.emoreap.IQMs.df$fwhm_avg, digits = 4)
BOLD.emoreap.IQMs.df$snr<-digits(BOLD.emoreap.IQMs.df$snr, digits = 4)
BOLD.emoreap.IQMs.df$tsnr<-digits(BOLD.emoreap.IQMs.df$tsnr, digits = 4)
BOLD.emoreap.IQMs.df$gcor<-digits(BOLD.emoreap.IQMs.df$gcor, digits = 4)
BOLD.emoreap.IQMs.df<-BOLD.emoreap.IQMs.df[complete.cases(BOLD.emoreap.IQMs.df$Subject),]
BOLD.emoreap.IQMs.df<-as.data.frame(BOLD.emoreap.IQMs.df, rownames=FALSE)
BOLD.emoreap.IQMs.df<-arrange(BOLD.emoreap.IQMs.df,"Date" )
# Violin plots with box plots inside
# :::::::::::::::::::::::::::::::::::::::::::::::::::
# Change fill color by groups: dose
# add boxplot with white fill colorRest.DF
my_comparisons.df<-compare_means(snr ~ Session , BOLD.emoreap.IQMs.df)
my_comparisons <- list( c("MR1", "MR2"),
c("MR1", "MR3"),
c("MR2", "MR3")
)
plot.anova1<-ggviolin(BOLD.emoreap.IQMs.df,
x = "Session", y = "snr",
fill = "Session", na.rm=TRUE,
add = "boxplot", add.params = list(fill = "white"))+
stat_compare_means(comparisons = my_comparisons, label = "p.signif") + # Add significance levels
stat_compare_means(label.y = 2) +
ggtitle("SNR by Session")+
theme(legend.position='right')
# Violin plots with box plots inside
# :::::::::::::::::::::::::::::::::::::::::::::::::::
# Change fill color by groups: dose
# add boxplot with white fill colorRest.DF
my_comparisons.df<-compare_means(fd_mean ~ Session , BOLD.emoreap.IQMs.df)
my_comparisons <- list( c("MR1", "MR2"),
c("MR1", "MR3"),
c("MR2", "MR3")
)
plot.anova2<-ggviolin(BOLD.emoreap.IQMs.df,
x = "Session", y = "fd_mean",
fill = "Session", na.rm=TRUE,
add = "boxplot", add.params = list(fill = "white"))+
stat_compare_means(comparisons = my_comparisons, label = "p.signif") + # Add significance levels
stat_compare_means(label.y = 2) +
ggtitle("fd_mean by Session")+
theme(legend.position='right')
plot.anova3<-ggviolin(BOLD.emoreap.IQMs.df,
x = "Session", y = "tsnr",
fill = "Session", na.rm=TRUE,
add = "boxplot", add.params = list(fill = "white"))+
stat_compare_means(comparisons = my_comparisons, label = "p.signif") + # Add significance levels
stat_compare_means(label.y = 2) +
ggtitle("tsnr by Session")+
theme(legend.position='right')
gridExtra::grid.arrange(plot.anova1, plot.anova2,plot.anova3, ncol=3)

Resting State
BOLD.rest.IQMs.df<-eBACH_BOLD
BOLD.rest.IQMs.df<-BOLD.rest.IQMs.df[BOLD.rest.IQMs.df$Task=="rest",]
BOLD.rest.IQMs.df<-arrange(BOLD.rest.IQMs.df,"Date" )
BOLD.rest.IQMs.df<-BOLD.rest.IQMs.df[complete.cases(BOLD.rest.IQMs.df$dvars_nstd),]
BOLD.rest.IQMs.df$dvars_nstd<-digits(BOLD.rest.IQMs.df$dvars_nstd, digits = 4)
BOLD.rest.IQMs.df$fd_mean<-digits(BOLD.rest.IQMs.df$fd_mean, digits = 4)
BOLD.rest.IQMs.df$fwhm_avg<-digits(BOLD.rest.IQMs.df$fwhm_avg, digits = 4)
BOLD.rest.IQMs.df$snr<-digits(BOLD.rest.IQMs.df$snr, digits = 4)
BOLD.rest.IQMs.df$tsnr<-digits(BOLD.rest.IQMs.df$tsnr, digits = 4)
BOLD.rest.IQMs.df$gcor<-digits(BOLD.rest.IQMs.df$gcor, digits = 4)
BOLD.rest.IQMs.df<-as.data.frame(BOLD.rest.IQMs.df, rownames=FALSE)
TMP3<-BOLD.rest.IQMs.df %>% select(SubID, Session,Date, Report,dvars_nstd ,fd_mean, snr,tsnr)
TMP3<-reshape2::melt(TMP3, id.vars=c("SubID","Session" ,"Date", "Report"))
# select part of the dataset and use it for plotting
ggstatsplot::grouped_ggbetweenstats(
data = TMP3,
x=Report,
y = value,
grouping.var = variable,
plot.type = "violin",
type = "np",
conf.level = 0.99,
xlab = "report",
ylab = "value",
ggtheme = ggplot2::theme_gray(), # a different theme
package = "yarrr", # package from which color palette is to be taken
palette = "info2", # choosing a different color palette
outlier.tagging = TRUE,
outlier.label.args = list(color = "red"), # outlier point label color
title.size = 12,
ggstatsplot.layer = FALSE,
outlier.label = "SubID",
# arguments relevant for ggstatsplot::combine_plots
title.text = "Weekly Resting State IQMs.df IQM Report",
sub.size = 3,
greedy=TRUE,
pairwise.comparisons = TRUE, # display results from pairwise comparisons
pairwise.display = "significant", # display only significant pairwise comparisons
stats.label.args = list(size = 2, direction = "y"))

BOLD.rest.IQMs.df<-eBACH_BOLD
BOLD.rest.IQMs.df<-BOLD.rest.IQMs.df[BOLD.rest.IQMs.df$Task=="rest",]
BOLD.rest.IQMs.df<-arrange(BOLD.rest.IQMs.df,"Date" )
BOLD.rest.IQMs.df<-BOLD.rest.IQMs.df[complete.cases(BOLD.rest.IQMs.df$dvars_nstd),]
BOLD.rest.IQMs.df$dvars_nstd<-digits(BOLD.rest.IQMs.df$dvars_nstd, digits = 4)
BOLD.rest.IQMs.df$fd_mean<-digits(BOLD.rest.IQMs.df$fd_mean, digits = 4)
BOLD.rest.IQMs.df$fwhm_avg<-digits(BOLD.rest.IQMs.df$fwhm_avg, digits = 4)
BOLD.rest.IQMs.df$snr<-digits(BOLD.rest.IQMs.df$snr, digits = 4)
BOLD.rest.IQMs.df$tsnr<-digits(BOLD.rest.IQMs.df$tsnr, digits = 4)
BOLD.rest.IQMs.df$gcor<-digits(BOLD.rest.IQMs.df$gcor, digits = 4)
BOLD.rest.IQMs.df<-as.data.frame(BOLD.rest.IQMs.df, rownames=FALSE)
# Violin plots with box plots inside
# :::::::::::::::::::::::::::::::::::::::::::::::::::
# Change fill color by groups: dose
# add boxplot with white fill colorRest.DF
my_comparisons.df<-compare_means(snr ~ Session , BOLD.rest.IQMs.df)
my_comparisons <- list( c("MR1", "MR2"),
c("MR1", "MR3"),
c("MR2", "MR3")
)
plot.anova1<-ggviolin(BOLD.rest.IQMs.df,
x = "Session", y = "snr",
fill = "Session", na.rm=TRUE,
add = "boxplot", add.params = list(fill = "white"))+
stat_compare_means(comparisons = my_comparisons, label = "p.signif") + # Add significance levels
stat_compare_means(label.y = 2) +
ggtitle("SNR by Session")+
theme(legend.position='right')
# Violin plots with box plots inside
# :::::::::::::::::::::::::::::::::::::::::::::::::::
# Change fill color by groups: dose
# add boxplot with white fill colorRest.DF
my_comparisons.df<-compare_means(fd_mean ~ Session , BOLD.rest.IQMs.df)
my_comparisons <- list( c("MR1", "MR2"),
c("MR1", "MR3"),
c("MR2", "MR3")
)
plot.anova2<-ggviolin(BOLD.rest.IQMs.df,
x = "Session", y = "fd_mean",
fill = "Session", na.rm=TRUE,
add = "boxplot", add.params = list(fill = "white"))+
stat_compare_means(comparisons = my_comparisons, label = "p.signif") + # Add significance levels
stat_compare_means(label.y = 2) +
ggtitle("fd_mean by Session")+
theme(legend.position='right')
plot.anova3<-ggviolin(BOLD.rest.IQMs.df,
x = "Session", y = "tsnr",
fill = "Session", na.rm=TRUE,
add = "boxplot", add.params = list(fill = "white"))+
stat_compare_means(comparisons = my_comparisons, label = "p.signif") + # Add significance levels
stat_compare_means(label.y = 2) +
ggtitle("tsnr by Session")+
theme(legend.position='right')
gridExtra::grid.arrange(plot.anova1, plot.anova2,plot.anova3, ncol=3)

MSIT Stress Task
BOLD.msit.IQMs.df<-eBACH_BOLD
BOLD.msit.IQMs.df<-BOLD.msit.IQMs.df[BOLD.msit.IQMs.df$Task=="msit",]
BOLD.msit.IQMs.df<-BOLD.emoreap.IQMs.df[complete.cases(BOLD.msit.IQMs.df$dvars_nstd),]
BOLD.msit.IQMs.df$dvars_nstd<-digits(BOLD.msit.IQMs.df$dvars_nstd, digits = 4)
BOLD.msit.IQMs.df$fd_mean<-digits(BOLD.msit.IQMs.df$fd_mean, digits = 4)
BOLD.msit.IQMs.df$fwhm_avg<-digits(BOLD.msit.IQMs.df$fwhm_avg, digits = 4)
BOLD.msit.IQMs.df$snr<-digits(BOLD.msit.IQMs.df$snr, digits = 4)
BOLD.msit.IQMs.df$tsnr<-digits(BOLD.msit.IQMs.df$tsnr, digits = 4)
BOLD.msit.IQMs.df$gcor<-digits(BOLD.msit.IQMs.df$gcor, digits = 4)
BOLD.msit.IQMs.df$SubID<-as.character(BOLD.msit.IQMs.df$SubID)
BOLD.msit.IQMs.df<-as.data.frame(BOLD.msit.IQMs.df, rownames=FALSE)
BOLD.msit.IQMs.df<-BOLD.msit.IQMs.df[complete.cases(BOLD.msit.IQMs.df$SubID),]
BOLD.msit.IQMs.df<-arrange(BOLD.msit.IQMs.df,"Date" )
TMP3<-BOLD.msit.IQMs.df %>% select(SubID, Session,Date, Report,dvars_nstd ,fd_mean, snr,tsnr)
TMP3<-reshape2::melt(TMP3, id.vars=c("SubID","Session" ,"Date", "Report"))
# select part of the dataset and use it for plotting
ggstatsplot::grouped_ggbetweenstats(
data = TMP3,
x=Report,
y = value,
grouping.var = variable,
plot.type = "violin",
type = "np",
conf.level = 0.99,
xlab = "report",
ylab = "value",
ggtheme = ggplot2::theme_gray(), # a different theme
package = "yarrr", # package from which color palette is to be taken
palette = "info2", # choosing a different color palette
outlier.tagging = TRUE,
outlier.label.args = list(color = "red"), # outlier point label color
title.size = 12,
ggstatsplot.layer = FALSE,
outlier.label = "SubID",
# arguments relevant for ggstatsplot::combine_plots
title.text = "Weekly Resting State IQMs.df IQM Report",
sub.size = 3,
greedy=TRUE,
pairwise.comparisons = TRUE, # display results from pairwise comparisons
pairwise.display = "significant", # display only significant pairwise comparisons
stats.label.args = list(size = 2, direction = "y"))


Stroop Stress Task
BOLD.stroop.IQMs.df<-eBACH_BOLD
BOLD.stroop.IQMs.df<-BOLD.stroop.IQMs.df[BOLD.stroop.IQMs.df$Task=="stroop",]
BOLD.stroop.IQMs.df<-BOLD.stroop.IQMs.df[complete.cases(BOLD.stroop.IQMs.df$SubID),]
BOLD.stroop.IQMs.df<-BOLD.emoreap.IQMs.df[complete.cases(BOLD.stroop.IQMs.df$dvars_nstd),]
BOLD.stroop.IQMs.df$dvars_nstd<-digits(BOLD.stroop.IQMs.df$dvars_nstd, digits = 4)
BOLD.stroop.IQMs.df$fd_mean<-digits(BOLD.stroop.IQMs.df$fd_mean, digits = 4)
BOLD.stroop.IQMs.df$fwhm_avg<-digits(BOLD.stroop.IQMs.df$fwhm_avg, digits = 4)
BOLD.stroop.IQMs.df$snr<-digits(BOLD.stroop.IQMs.df$snr, digits = 4)
BOLD.stroop.IQMs.df$tsnr<-digits(BOLD.stroop.IQMs.df$tsnr, digits = 4)
BOLD.stroop.IQMs.df$gcor<-digits(BOLD.stroop.IQMs.df$gcor, digits = 4)
BOLD.stroop.IQMs.df<-as.data.frame(BOLD.stroop.IQMs.df, rownames=FALSE)
BOLD.stroop.IQMs.df<-arrange(BOLD.stroop.IQMs.df,"Date" )
TMP3<-BOLD.stroop.IQMs.df %>% select(SubID, Session,Date, Report,dvars_nstd ,fd_mean, snr,tsnr)
TMP3<-reshape2::melt(TMP3, id.vars=c("SubID","Session" ,"Date", "Report"))
# select part of the dataset and use it for plotting
ggstatsplot::grouped_ggbetweenstats(
data = TMP3,
x=Report,
y = value,
grouping.var = variable,
plot.type = "violin",
type = "np",
conf.level = 0.99,
xlab = "report",
ylab = "value",
ggtheme = ggplot2::theme_gray(), # a different theme
package = "yarrr", # package from which color palette is to be taken
palette = "info2", # choosing a different color palette
outlier.tagging = TRUE,
outlier.label.args = list(color = "red"), # outlier point label color
title.size = 12,
ggstatsplot.layer = FALSE,
outlier.label = "SubID",
# arguments relevant for ggstatsplot::combine_plots
title.text = "Weekly Resting State IQMs.df IQM Report",
sub.size = 3,
greedy=TRUE,
pairwise.comparisons = TRUE, # display results from pairwise comparisons
pairwise.display = "significant", # display only significant pairwise comparisons
stats.label.args = list(size = 2, direction = "y"))


LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoubWFpbi1jb250YWluZXIgewogIG1heC13aWR0aDogMTYwMHB4OwogIG1hcmdpbi1sZWZ0OiBhdXRvOwogIG1hcmdpbi1yaWdodDogYXV0bzsKfQo8L3N0eWxlPgoKCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1UUlVFfQojIyBTZXQtVXAKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShzcGFya2xpbmUpClRPREFZPC1TeXMuRGF0ZSgpCgojIyBBREQgU1BBUktMSU5FIEZVTkNUSU9OIChPbmx5IG5lZWRlZCBvbmNlKQpmb3JtYXR0YWJsZVdpdGhTTCA8LSBmdW5jdGlvbihUYWJsZURGLHJhd0RGLGtleSxTTGZpZWxkKXsKICAjIyBBZGQgc3BhcmtsaW5lIGZpZWxkIHRvIFRhYmxlREYKICBUYWJsZURGJHNwYXJrbGluZSA8LSBUYWJsZURGW1trZXldXQogICMjIE5vdyBiYXNpY2FsbHkgY2FsbCBmb3JtYXR0YWJsZSwgcGFzc2luZyBpbiB0aGUgdmFycwogIGZvcm1hdHRhYmxlKFRhYmxlREYsbGlzdCgKICAgICJzcGFya2xpbmUiPWZ1bmN0aW9uKHopewogICAgICBzYXBwbHkoeixmdW5jdGlvbih6eil7a25pdHI6OmtuaXQodGV4dCA9IHNwcmludGYoCiAgICAgICAgICAgICAgJ2ByIHNwYXJrbGluZShjKCVzKSlgJywKICAgICAgICAgICAgICBwYXN0ZTAoCiAgICAgICAgICAgICAgICByYXdERlt3aGljaChyYXdERlssa2V5XSA9PSB6eiksU0xmaWVsZF0sCiAgICAgICAgICAgICAgICBjb2xsYXBzZT0iLCIKICAgICAgICAgICAgICApKSwKICAgICAgICAgICAgcXVpZXQgPSBUUlVFCiAgICAgICAgICApfSl9ICApKQp9CgpgYGAKYGBge3IsIGVCQUNIIEJhc2VsaW5lIEFETUlOLCBpbmNsdWRlPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmVCQUNIX1FDX0RhdGFiYXNlMSA8LSByZWFkeGw6OnJlYWRfZXhjZWwoICIvVm9sdW1lcy9lQkFDSC9NUkkvUUNfT3V0cHV0L2VCQUNIX1FDX0RhdGFiYXNlLnhsc3giLCAKICAgIHNoZWV0ID0gIlBSRSIsIGNvbF90eXBlcyA9IGMoIm51bWVyaWMiLCAKICAgICAgICAidGV4dCIsICJ0ZXh0IiwgImRhdGUiLCAidGV4dCIsICJ0ZXh0IiwgCiAgICAgICAgInRleHQiLCAidGV4dCIsICJ0ZXh0IiwgInRleHQiLCAidGV4dCIsIAogICAgICAgICJ0ZXh0IiwgIm51bWVyaWMiLCAidGV4dCIsICJ0ZXh0IiwgCiAgICAgICAgInRleHQiLCAidGV4dCIsICJ0ZXh0IiwgInRleHQiLCAidGV4dCIsIAogICAgICAgICJudW1lcmljIiwgInRleHQiLCAibnVtZXJpYyIsICJudW1lcmljIiwgCiAgICAgICAgIm51bWVyaWMiLCAidGV4dCIsICJ0ZXh0IiwgInRleHQiLCAKICAgICAgICAidGV4dCIsICJudW1lcmljIiwgInRleHQiLCAidGV4dCIsIAogICAgICAgICJ0ZXh0IiwgInRleHQiLCAidGV4dCIsICJ0ZXh0IiwgInRleHQiKSkKZUJBQ0hfUUNfRGF0YWJhc2UxPC1lQkFDSF9RQ19EYXRhYmFzZTFbY29tcGxldGUuY2FzZXMoZUJBQ0hfUUNfRGF0YWJhc2UxJFN1YmplY3QpLF0KZUJBQ0hfUUNfRGF0YWJhc2UxJFdlZWtseVJlcG9ydDwtZUJBQ0hfUUNfRGF0YWJhc2UxJGBXZWVrbHkgcmVwb3J0P2AKZUJBQ0hfUUNfRGF0YWJhc2UxJERhdGU8LWVCQUNIX1FDX0RhdGFiYXNlMSRgRGF0ZSBvZiBNUkkgU2NhbmAKZUJBQ0hfUUNfRGF0YWJhc2UxJFNlc3Npb248LSJNUjEiCmVCQUNIX1FDX0RhdGFiYXNlMSRTY2FuTm90ZXM8LWVCQUNIX1FDX0RhdGFiYXNlMSRgT3ZlcmFsbCBTY2FuIE5vdGVzYAplQkFDSF9RQ19EYXRhYmFzZTEkUUMwMzwtZUJBQ0hfUUNfRGF0YWJhc2UxJE5vdGVzLi4uMjAKZUJBQ0hfUUNfRGF0YWJhc2UxJFFDMDQ8LWVCQUNIX1FDX0RhdGFiYXNlMSROb3Rlcy4uLjI3CmVCQUNIX1FDX0RhdGFiYXNlMTwtZUJBQ0hfUUNfRGF0YWJhc2UxJT4lIHNlbGVjdChTdWJqZWN0LFNlc3Npb24sRGF0ZSwgV2Vla2x5UmVwb3J0LFNjYW5Ob3RlcyxRQzAzLCBRQzA0KQplQkFDSF9RQ19EYXRhYmFzZTE8LWVCQUNIX1FDX0RhdGFiYXNlMVtjb21wbGV0ZS5jYXNlcyhlQkFDSF9RQ19EYXRhYmFzZTEkU3ViamVjdCksXQplQkFDSF9RQ19EYXRhYmFzZTE8LWFzLnRpYmJsZShlQkFDSF9RQ19EYXRhYmFzZTEpCiNlQkFDSF9RQ19EYXRhYmFzZTEudGI8LWthYmxlKGVCQUNIX1FDX0RhdGFiYXNlMSkgJT4lCiMga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInJlc3BvbnNpdmUiLCAiYm9yZGVyZWQiKSxmdWxsX3dpZHRoID0gVCxmb250X3NpemUgPSAxMCklPiUKIyAgcm93X3NwZWMoMCwgYWxpZ249J2MnKSU+JQojICBjb2x1bW5fc3BlYygxLCBib2xkID0gVCkgJT4lCiMgICAgY29sdW1uX3NwZWMoMiwgIHdpZHRoID0gIjFjbSIsYm9yZGVyX3JpZ2h0ID0gVCkgJT4lCiMgICAgY29sdW1uX3NwZWMoMywgYm9sZCA9IEYsd2lkdGggPSAiM2NtIiApICU+JQojICAgICAgY29sdW1uX3NwZWMoNCwgYm9sZCA9IFQsIHdpZHRoID0gIjFjbSIsIGJvcmRlcl9sZWZ0ID0gVCkgJT4lCiMgICAgY29sdW1uX3NwZWMoNSwgd2lkdGggPSAiMTBjbSIsIGJvcmRlcl9yaWdodCA9IEYpICU+JQojICAgICAgY29sdW1uX3NwZWMoNiwgd2lkdGggPSAiMTBjbSIpIAojIGthYmxlRXh0cmE6OnNjcm9sbF9ib3goZUJBQ0hfUUNfRGF0YWJhc2UxLnRiLCBoZWlnaHQgPSAiMzAwcHQiLCB3aWR0aCA9ICI3MDBwdCIgKQpgYGAKYGBge3IgV2l0aGRyZXcgYWZ0ZXIgQmFzbGluZSBTY2FuLCAgaW5jbHVkZT1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQpFeGNsdWRlMSA8LSByZWFkeGw6OnJlYWRfZXhjZWwoIi9Wb2x1bWVzL2VCQUNIL01SSS9RQ19PdXRwdXQvZUJBQ0hfUUNfRGF0YWJhc2UueGxzeCIsIAogICAgc2hlZXQgPSAiRXhjbHVkZWQgb3IgV2l0aGRyZXcgZnJvbSBTdHVkeSIsIAogICAgY29sX3R5cGVzID0gYygibnVtZXJpYyIsICJ0ZXh0IiwgInRleHQiLCAKICAgICAgICAidGV4dCIsICJkYXRlIiwgInRleHQiLCAidGV4dCIsICJ0ZXh0IiwgCiAgICAgICAgInRleHQiLCAibnVtZXJpYyIsICJudW1lcmljIiwgIm51bWVyaWMiLCAKICAgICAgICAibnVtZXJpYyIsICJudW1lcmljIiwgInRleHQiLCAidGV4dCIsIAogICAgICAgICJ0ZXh0IiwgInRleHQiLCAidGV4dCIsICJ0ZXh0IiwgInRleHQiLCAKICAgICAgICAibnVtZXJpYyIsICJudW1lcmljIiwgIm51bWVyaWMiLCAKICAgICAgICAibnVtZXJpYyIsICJudW1lcmljIiwgIm51bWVyaWMiLCAKICAgICAgICAidGV4dCIsICJudW1lcmljIiwgIm51bWVyaWMiLCAibnVtZXJpYyIsIAogICAgICAgICJ0ZXh0IiwgIm51bWVyaWMiLCAidGV4dCIsICJ0ZXh0IiwgCiAgICAgICAgInRleHQiLCAidGV4dCIpKQpFeGNsdWRlMTwtRXhjbHVkZTFbY29tcGxldGUuY2FzZXMoRXhjbHVkZTEkU3ViamVjdCksXQpQUkUuUmFuZG9taXphdGlvbjwtRXhjbHVkZTEgJT4lIGZpbHRlcihFeGNsdWRlMSRgSW5jbHVkZWQgaW4gTUFTVEVSIFNwcmVhZHNoZWV0cz9gPT0ibi9hIikgJT4lIHNlbGVjdChTdWJqZWN0KQoKRXhjbHVkZTEkRGF0ZTwtRXhjbHVkZTEkYERhdGUgb2YgTVJJIFNjYW5gCkV4Y2x1ZGUxJFNjYW5Ob3RlczwtRXhjbHVkZTEkYE92ZXJhbGwgU2NhbiBOb3Rlc2AKRXhjbHVkZTEkUUMwMzwtRXhjbHVkZTEkTm90ZXMuLi4yMQpFeGNsdWRlMSRRQzA0PC1FeGNsdWRlMSROb3Rlcy4uLjI4CkV4Y2x1ZGUxJFdlZWtseVJlcG9ydDwtRXhjbHVkZTEkYEluY2x1ZGVkIGluIE1BU1RFUiBTcHJlYWRzaGVldHM/YApFeGNsdWRlMTwtRXhjbHVkZTElPiUgc2VsZWN0KFN1YmplY3QsV2Vla2x5UmVwb3J0LERhdGUsU2Vzc2lvbiwgU2Nhbk5vdGVzLFFDMDMsIFFDMDQpCgpSYW5kb21pemVkPC1FeGNsdWRlMSAlPiUgZmlsdGVyKEV4Y2x1ZGUxJFdlZWtseVJlcG9ydD09IjEiKSAlPiUgc2VsZWN0KFN1YmplY3QpCgpFeGNsdWRlMTwtYXMuZGF0YS5mcmFtZShFeGNsdWRlMSkKYGBgCmBgYHtyLCBSZXNjYW5uZWQgQWRtaW4sIGluY2x1ZGU9VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0KRXhjbHVkZTIgPC0gcmVhZHhsOjpyZWFkX2V4Y2VsKCIvVm9sdW1lcy9lQkFDSC9NUkkvUUNfT3V0cHV0L2VCQUNIX1FDX0RhdGFiYXNlLnhsc3giLCAKICAgIHNoZWV0ID0gIlJlLVNjYW5uZWQiLCBjb2xfdHlwZXMgPSBjKCJudW1lcmljIiwgCiAgICAgICAgInRleHQiLCAidGV4dCIsICJudW1lcmljIiwgImRhdGUiLCAKICAgICAgICAidGV4dCIsICJ0ZXh0IiwgIm51bWVyaWMiLCAibnVtZXJpYyIsIAogICAgICAgICJudW1lcmljIiwgIm51bWVyaWMiLCAibnVtZXJpYyIsIAogICAgICAgICJudW1lcmljIiwgIm51bWVyaWMiLCAidGV4dCIsICJ0ZXh0IiwgCiAgICAgICAgInRleHQiLCAidGV4dCIsICJ0ZXh0IiwgInRleHQiLCAidGV4dCIsIAogICAgICAgICJudW1lcmljIiwgIm51bWVyaWMiLCAibnVtZXJpYyIsIAogICAgICAgICJudW1lcmljIiwgIm51bWVyaWMiLCAibnVtZXJpYyIsIAogICAgICAgICJ0ZXh0IiwgIm51bWVyaWMiLCAibnVtZXJpYyIsICJudW1lcmljIiwgCiAgICAgICAgInRleHQiLCAibnVtZXJpYyIsICJ0ZXh0IiwgInRleHQiLCAKICAgICAgICAidGV4dCIsICJ0ZXh0IikpCkV4Y2x1ZGUyPC1FeGNsdWRlMltjb21wbGV0ZS5jYXNlcyhFeGNsdWRlMiRTdWJqZWN0KSxdCkV4Y2x1ZGUyJFdlZWtseVJlcG9ydDwtRXhjbHVkZTIkYFdlZWtseSBSZXBvcnQ/YApFeGNsdWRlMiREYXRlPC1FeGNsdWRlMiRgRGF0ZSBvZiBNUkkgU2NhbmAKRXhjbHVkZTIkU2Vzc2lvbjwtRXhjbHVkZTIkU2Vzc2lvbgpFeGNsdWRlMiRTY2FuTm90ZXM8LUV4Y2x1ZGUyJGBPdmVyYWxsIFNjYW4gTm90ZXNgCkV4Y2x1ZGUyJFFDMDM8LUV4Y2x1ZGUyJE5vdGVzLi4uMjEKRXhjbHVkZTIkUUMwNDwtRXhjbHVkZTIkTm90ZXMuLi4yOApFeGNsdWRlMjwtRXhjbHVkZTIlPiUgc2VsZWN0KFN1YmplY3QsV2Vla2x5UmVwb3J0LERhdGUsU2Vzc2lvbiwgU2Nhbk5vdGVzLFFDMDMsIFFDMDQpCmBgYApgYGB7ciAsZUJBQ0ggTWlkLVBvaW50IEFETUlOLCBpbmNsdWRlPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9CmVCQUNIX1FDX0RhdGFiYXNlMiA8LSByZWFkeGw6OnJlYWRfZXhjZWwoIi9Wb2x1bWVzL2VCQUNIL01SSS9RQ19PdXRwdXQvZUJBQ0hfUUNfRGF0YWJhc2UueGxzeCIsIAogICAgc2hlZXQgPSAiTUlEIiwgY29sX3R5cGVzID0gYygidGV4dCIsIAogICAgICAgICJ0ZXh0IiwgInRleHQiLCAidGV4dCIsICJkYXRlIiwgInRleHQiLCAKICAgICAgICAidGV4dCIsICJ0ZXh0IiwgIm51bWVyaWMiLCAibnVtZXJpYyIsIAogICAgICAgICJ0ZXh0IiwgInRleHQiLCAidGV4dCIsICJudW1lcmljIiwgCiAgICAgICAgIm51bWVyaWMiLCAibnVtZXJpYyIsICJ0ZXh0IiwgInRleHQiLCAKICAgICAgICAidGV4dCIsICJ0ZXh0IiwgInRleHQiLCAidGV4dCIsICJ0ZXh0IiwgCiAgICAgICAgInRleHQiLCAibnVtZXJpYyIsICJ0ZXh0IiwgIm51bWVyaWMiLCAKICAgICAgICAidGV4dCIsICJ0ZXh0IiwgInRleHQiLCAibnVtZXJpYyIsIAogICAgICAgICJudW1lcmljIiwgIm51bWVyaWMiLCAidGV4dCIsICJ0ZXh0IiwgCiAgICAgICAgInRleHQiLCAidGV4dCIpKQplQkFDSF9RQ19EYXRhYmFzZTI8LWVCQUNIX1FDX0RhdGFiYXNlMltjb21wbGV0ZS5jYXNlcyhlQkFDSF9RQ19EYXRhYmFzZTIkU3ViamVjdCksXQplQkFDSF9RQ19EYXRhYmFzZTIkV2Vla2x5UmVwb3J0PC1lQkFDSF9RQ19EYXRhYmFzZTIkYFdlZWtseSByZXBvcnQ/YAplQkFDSF9RQ19EYXRhYmFzZTIkRGF0ZTwtZUJBQ0hfUUNfRGF0YWJhc2UyJGBEYXRlIG9mIE1SSSBTY2FuYAplQkFDSF9RQ19EYXRhYmFzZTIkU2Vzc2lvbjwtIk1SMiIKZUJBQ0hfUUNfRGF0YWJhc2UyJFNjYW5Ob3RlczwtZUJBQ0hfUUNfRGF0YWJhc2UyJGBSdW4gU2hlZXQgTm90ZXNgCmVCQUNIX1FDX0RhdGFiYXNlMiRRQzAzPC1lQkFDSF9RQ19EYXRhYmFzZTIkTm90ZXMuLi4yMwplQkFDSF9RQ19EYXRhYmFzZTIkUUMwNDwtZUJBQ0hfUUNfRGF0YWJhc2UyJE5vdGVzLi4uMzAKZUJBQ0hfUUNfRGF0YWJhc2UyPC1lQkFDSF9RQ19EYXRhYmFzZTIlPiUgc2VsZWN0KFN1YmplY3QsV2Vla2x5UmVwb3J0LERhdGUsU2Vzc2lvbiwgU2Nhbk5vdGVzLFFDMDMsIFFDMDQpCmVCQUNIX1FDX0RhdGFiYXNlMjwtZUJBQ0hfUUNfRGF0YWJhc2UyW2NvbXBsZXRlLmNhc2VzKGVCQUNIX1FDX0RhdGFiYXNlMiRTdWJqZWN0KSxdCmVCQUNIX1FDX0RhdGFiYXNlMjwtYXJyYW5nZShlQkFDSF9RQ19EYXRhYmFzZTIsIERhdGUpCgpgYGAKYGBge3IgLGVCQUNIIDEybW8uRm9sbG93LVVwIEFETUlOLCBpbmNsdWRlPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmVCQUNIX1FDX0RhdGFiYXNlMyA8LSByZWFkeGw6OnJlYWRfZXhjZWwoIi9Wb2x1bWVzL2VCQUNIL01SSS9RQ19PdXRwdXQvZUJBQ0hfUUNfRGF0YWJhc2UueGxzeCIsIAogICAgc2hlZXQgPSAiUE9TVCIpCmVCQUNIX1FDX0RhdGFiYXNlMzwtZUJBQ0hfUUNfRGF0YWJhc2UzW2NvbXBsZXRlLmNhc2VzKGVCQUNIX1FDX0RhdGFiYXNlMyRTdWJqZWN0KSxdCmVCQUNIX1FDX0RhdGFiYXNlMyRXZWVrbHlSZXBvcnQ8LWVCQUNIX1FDX0RhdGFiYXNlMyRgV2Vla2x5IHJlcG9ydD9gCmVCQUNIX1FDX0RhdGFiYXNlMyRTZXNzaW9uPC0iTVIzIgplQkFDSF9RQ19EYXRhYmFzZTMkRGF0ZTwtZUJBQ0hfUUNfRGF0YWJhc2UzJGBEYXRlIG9mIE1SSSBTY2FuYAplQkFDSF9RQ19EYXRhYmFzZTMkU2Nhbk5vdGVzPC1lQkFDSF9RQ19EYXRhYmFzZTMkYE92ZXJhbGwgU2NhbiBOb3Rlc2AKZUJBQ0hfUUNfRGF0YWJhc2UzJFFDMDM8LWVCQUNIX1FDX0RhdGFiYXNlMyROb3Rlcy4uLjI3CmVCQUNIX1FDX0RhdGFiYXNlMyRRQzA0PC1lQkFDSF9RQ19EYXRhYmFzZTMkTm90ZXMuLi4zOAplQkFDSF9RQ19EYXRhYmFzZTM8LWVCQUNIX1FDX0RhdGFiYXNlMyU+JSBzZWxlY3QoU3ViamVjdCxXZWVrbHlSZXBvcnQsRGF0ZSxTZXNzaW9uLCBTY2FuTm90ZXMsUUMwMywgUUMwNCkKZUJBQ0hfUUNfRGF0YWJhc2UzPC1lQkFDSF9RQ19EYXRhYmFzZTNbY29tcGxldGUuY2FzZXMoZUJBQ0hfUUNfRGF0YWJhc2UzJFN1YmplY3QpLF0KCnRtcDwtcmJpbmQoZUJBQ0hfUUNfRGF0YWJhc2UxLCBlQkFDSF9RQ19EYXRhYmFzZTIpCnRtcDI8LXJiaW5kKHRtcCwgRXhjbHVkZTEpCmVCQUNILkFkbWluPC1yYmluZCh0bXAyLCBlQkFDSF9RQ19EYXRhYmFzZTMpCmBgYAojIyBNUklRQyBBZG1pbiBEYXRhYmFzZQojIyBCYXNlbGluZTogIGByICBucm93KGVCQUNIX1FDX0RhdGFiYXNlMSlgICAKIyMjIyBXaXRoZHJldyBBZnRlciBCYXNlbGluZSBNUkk6ICAgIGByICBucm93KEV4Y2x1ZGUxKWAgIAojIyMjIyAtLS0gUmFuZG9taXplZDogYHIgUmFuZG9taXplZCRTdWJqZWN0YCAgIAojIyMjIyAtLS0gRHJvcHBlZCBiZWZvcmUgcmFuZG9taXplZDogYHIgUFJFLlJhbmRvbWl6YXRpb24kU3ViamVjdGAgIAojIyBNaWQtUG9pbnQ6IGByIG5yb3coZUJBQ0hfUUNfRGF0YWJhc2UyKWAgIAojIyBQb3N0LUludGVydmVudGlvbjogYHIgbnJvdyhlQkFDSF9RQ19EYXRhYmFzZTMpYCAgCjxici8+CgojIyMgSW1wb3J0IE1hc3RlciBTcHJlYWRzaGVldHMgZm9yIFJlcG9ydC4uLgpgYGB7ciwgQmFzZWxpbmUgTUFTVEVSIFNwcmVhZHNoZWV0LCBpbmNsdWRlPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9ClQxLk1SMS5NQVNURVI8LXJlYWR4bDo6cmVhZF9leGNlbCgiL1ZvbHVtZXMvZUJBQ0gvTVJJL1FDX091dHB1dC9lQkFDSF9CU19NUklfUUNfTUFTVEVSLnhsc3giLCBzaGVldD0iZUJBQ0hfTVJJX1FDMDRfVDEiKQpUMS5NUjEuTUFTVEVSPC1UMS5NUjEuTUFTVEVSW2Jhc2U6OnN0YXJ0c1dpdGgoVDEuTVIxLk1BU1RFUiRiaWRzX25hbWUsICJzdWIiKSxdClQxLk1SMS5NQVNURVI8LVQxLk1SMS5NQVNURVJbY29tcGxldGUuY2FzZXMoVDEuTVIxLk1BU1RFUiRiaWRzX25hbWUpLF0KeDwtVDEuTVIxLk1BU1RFUiRiaWRzX25hbWUKdGVtcDwtc3Ryc3BsaXQoeCwiLSIpCm1hdCAgPC0gbWF0cml4KHVubGlzdCh0ZW1wKSwgbmNvbD0yLCBieXJvdz1UUlVFKQpkZiAgIDwtIGFzLmRhdGEuZnJhbWUobWF0KQpkZiRTdWJJRDwtYXMuY2hhcmFjdGVyKGRmJFYyKQp4PC1kZiRTdWJJRAp0ZW1wPC1zdHJzcGxpdCh4LCJNUjEiKQptYXQgIDwtIG1hdHJpeCh1bmxpc3QodGVtcCksIG5jb2w9MiwgYnlyb3c9VFJVRSkKZGYgICA8LSBhcy5kYXRhLmZyYW1lKG1hdCkKVDEuTVIxLk1BU1RFUiRTdWJJRDwtYXMuY2hhcmFjdGVyKGRmJFYxKQpUMS5NUjEuTUFTVEVSJFNlc3Npb248LSJNUjEiCnJtKG1hdCxkZix4LHRlbXApCgpCT0xELk1SMS5NQVNURVI8LXJlYWR4bDo6cmVhZF9leGNlbCgiL1ZvbHVtZXMvZUJBQ0gvTVJJL1FDX091dHB1dC9lQkFDSF9CU19NUklfUUNfTUFTVEVSLnhsc3giLCBzaGVldCA9ICJlQkFDSF9NUklfUUMwNF9CT0xEIikKQk9MRC5NUjEuTUFTVEVSPC1CT0xELk1SMS5NQVNURVJbYmFzZTo6c3RhcnRzV2l0aChCT0xELk1SMS5NQVNURVIkYmlkc19uYW1lLCAic3ViIiksXQpCT0xELk1SMS5NQVNURVI8LUJPTEQuTVIxLk1BU1RFUltjb21wbGV0ZS5jYXNlcyhCT0xELk1SMS5NQVNURVIkYmlkc19uYW1lKSxdCkJPTEQuTVIxLk1BU1RFUiRTdWJJRDwtQk9MRC5NUjEuTUFTVEVSJGJpZHNfbmFtZQp4PC1CT0xELk1SMS5NQVNURVIkYmlkc19uYW1lCnRlbXA8LXN0cnNwbGl0KHgsInN1Yi0iKQptYXQgIDwtIG1hdHJpeCh1bmxpc3QodGVtcCksIG5jb2w9MiwgYnlyb3c9VFJVRSkKZGYgICA8LSBhcy5kYXRhLmZyYW1lKG1hdCkKCmRmJFN1YklEPC1hcy5jaGFyYWN0ZXIoZGYkVjIpCng8LWRmJFN1YklECnRlbXA8LXN0cnNwbGl0KHgsIi0iKQptYXQgIDwtIG1hdHJpeCh1bmxpc3QodGVtcCksIG5jb2w9MiwgYnlyb3c9VFJVRSkKZGYgICA8LSBhcy5kYXRhLmZyYW1lKG1hdCkKZGYkVGFzazwtYXMuY2hhcmFjdGVyKGRmJFYyKQp4PC1kZiRUYXNrCnRlbXA8LXN0cnNwbGl0KHgsIl8iKQptYXQgIDwtIG1hdHJpeCh1bmxpc3QodGVtcCksIG5jb2w9MiwgYnlyb3c9VFJVRSkKZGYkVGFzazwtbWF0WywxXQpkZiRTdWJJRDwtYXMuY2hhcmFjdGVyKGRmJFYxKQp4PC1kZiRTdWJJRAp0ZW1wPC1zdHJzcGxpdCh4LCJNUjEiKQptYXQgIDwtIG1hdHJpeCh1bmxpc3QodGVtcCksIG5jb2w9MiwgYnlyb3c9VFJVRSkKZGYkU3ViSUQ8LW1hdFssMV0KZGYkU2Vzc2lvbjwtIk1SMSIKeDwtYygiU3ViSUQiLCJUYXNrIiwiU2Vzc2lvbiIpClRBU0suZGY8LWRmW3hdCmRmICAgPC0gY2JpbmQoVEFTSy5kZixCT0xELk1SMS5NQVNURVIpCkJPTEQuTVIxLk1BU1RFUiAgPC0gYXMuZGF0YS5mcmFtZShkZikKQk9MRC5NUjEuTUFTVEVSPC1CT0xELk1SMS5NQVNURVJbLC1jKDQpXQoKCmBgYApgYGB7ciwgTWlkLVBvaW50IE1BU1RFUiBTcHJlYWRzaGVldCwgaW5jbHVkZT1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQojIyBNaWQtUG9pbnQKVDEuTVIyLk1BU1RFUjwtcmVhZHhsOjpyZWFkX2V4Y2VsKCIvVm9sdW1lcy9lQkFDSC9NUkkvUUNfT3V0cHV0L2VCQUNIXzZNT19NUklfUUNfTUFTVEVSLnhsc3giLCBzaGVldD0iZUJBQ0hfTVJJX1FDMDRfVDEiKQpUMS5NUjIuTUFTVEVSPC1UMS5NUjIuTUFTVEVSW2Jhc2U6OnN0YXJ0c1dpdGgoVDEuTVIyLk1BU1RFUiRiaWRzX25hbWUsICJzdWIiKSxdClQxLk1SMi5NQVNURVI8LVQxLk1SMi5NQVNURVJbY29tcGxldGUuY2FzZXMoVDEuTVIyLk1BU1RFUiRiaWRzX25hbWUpLF0KeDwtVDEuTVIyLk1BU1RFUiRiaWRzX25hbWUKdGVtcDwtc3Ryc3BsaXQoeCwiLSIpCm1hdCAgPC0gbWF0cml4KHVubGlzdCh0ZW1wKSwgbmNvbD0yLCBieXJvdz1UUlVFKQpkZiAgIDwtIGFzLmRhdGEuZnJhbWUobWF0KQpkZiRTdWJJRDwtYXMuY2hhcmFjdGVyKGRmJFYyKQp4PC1kZiRTdWJJRAp0ZW1wPC1zdHJzcGxpdCh4LCJNUjIiKQptYXQgIDwtIG1hdHJpeCh1bmxpc3QodGVtcCksIG5jb2w9MiwgYnlyb3c9VFJVRSkKZGYgICA8LSBhcy5kYXRhLmZyYW1lKG1hdCkKVDEuTVIyLk1BU1RFUiRTdWJJRDwtYXMuY2hhcmFjdGVyKGRmJFYxKQpUMS5NUjIuTUFTVEVSJFNlc3Npb248LSJNUjIiCgpCT0xELk1SMi5NQVNURVI8LXJlYWR4bDo6cmVhZF9leGNlbCgiL1ZvbHVtZXMvZUJBQ0gvTVJJL1FDX091dHB1dC9lQkFDSF82TU9fTVJJX1FDX01BU1RFUi54bHN4Iiwgc2hlZXQgPSAiZUJBQ0hfTVJJX1FDMDRfQk9MRCIpCkJPTEQuTVIyLk1BU1RFUjwtQk9MRC5NUjIuTUFTVEVSW2Jhc2U6OnN0YXJ0c1dpdGgoQk9MRC5NUjIuTUFTVEVSJGJpZHNfbmFtZSwgInN1YiIpLF0KQk9MRC5NUjIuTUFTVEVSPC1CT0xELk1SMi5NQVNURVJbY29tcGxldGUuY2FzZXMoQk9MRC5NUjIuTUFTVEVSJGJpZHNfbmFtZSksXQpCT0xELk1SMi5NQVNURVIkYmlkc19uYW1lPC1hcy5jaGFyYWN0ZXIoQk9MRC5NUjIuTUFTVEVSJGJpZHNfbmFtZSkKeDwtQk9MRC5NUjIuTUFTVEVSJGJpZHNfbmFtZQp0ZW1wPC1zdHJzcGxpdCh4LCJzdWItIikKbWF0ICA8LSBtYXRyaXgodW5saXN0KHRlbXApLCBuY29sPTIsIGJ5cm93PVRSVUUpCmRmICAgPC0gYXMuZGF0YS5mcmFtZShtYXQpCmRmJFN1YklEPC1hcy5jaGFyYWN0ZXIoZGYkVjIpCng8LWRmJFN1YklECnRlbXA8LXN0cnNwbGl0KHgsIi0iKQptYXQgIDwtIG1hdHJpeCh1bmxpc3QodGVtcCksIG5jb2w9MiwgYnlyb3c9VFJVRSkKZGYgICA8LSBhcy5kYXRhLmZyYW1lKG1hdCkKZGYkVGFzazwtYXMuY2hhcmFjdGVyKGRmJFYyKQp4PC1kZiRUYXNrCnRlbXA8LXN0cnNwbGl0KHgsIl8iKQptYXQgIDwtIG1hdHJpeCh1bmxpc3QodGVtcCksIG5jb2w9MiwgYnlyb3c9VFJVRSkKZGYkVGFzazwtbWF0WywxXQpkZiRTdWJJRDwtYXMuY2hhcmFjdGVyKGRmJFYxKQp4PC1kZiRTdWJJRAp0ZW1wPC1zdHJzcGxpdCh4LCJNUjIiKQptYXQgIDwtIG1hdHJpeCh1bmxpc3QodGVtcCksIG5jb2w9MiwgYnlyb3c9VFJVRSkKZGYkU3ViSUQ8LW1hdFssMV0KZGYkU2Vzc2lvbjwtIk1SMiIKeDwtYygiU3ViSUQiLCJUYXNrIiwiU2Vzc2lvbiIpClRBU0suZGY8LWRmW3hdCmRmICAgPC0gY2JpbmQoVEFTSy5kZixCT0xELk1SMi5NQVNURVIpCkJPTEQuTVIyLk1BU1RFUiA8LSBhcy5kYXRhLmZyYW1lKGRmKQpybShkZiwgbWF0LCB0ZW1wLCAgeCkKYGBgCmBgYHtyLCBQb3N0LUludGVydmVudGlvbiBNQVNURVIgU3ByZWFkc2hlZXQsIGluY2x1ZGU9VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0KIyMgUG9zdC1JbnRlcnZlbnRpb24KVDEuTVIzLk1BU1RFUjwtcmVhZHhsOjpyZWFkX2V4Y2VsKCIvVm9sdW1lcy9lQkFDSC9NUkkvUUNfT3V0cHV0L2VCQUNIXzEybW9fTVJJX1FDX01BU1RFUi54bHN4Iiwgc2hlZXQ9ImVCQUNIX01SSV9RQzA0X1QxIikKVDEuTVIzLk1BU1RFUjwtVDEuTVIzLk1BU1RFUltiYXNlOjpzdGFydHNXaXRoKFQxLk1SMy5NQVNURVIkYmlkc19uYW1lLCAic3ViIiksXQpUMS5NUjMuTUFTVEVSPC1UMS5NUjMuTUFTVEVSW2NvbXBsZXRlLmNhc2VzKFQxLk1SMy5NQVNURVIkYmlkc19uYW1lKSxdCng8LVQxLk1SMy5NQVNURVIkYmlkc19uYW1lCnRlbXA8LXN0cnNwbGl0KHgsIi0iKQptYXQgIDwtIG1hdHJpeCh1bmxpc3QodGVtcCksIG5jb2w9MiwgYnlyb3c9VFJVRSkKZGYgICA8LSBhcy5kYXRhLmZyYW1lKG1hdCkKZGYkU3ViSUQ8LWFzLmNoYXJhY3RlcihkZiRWMikKeDwtZGYkU3ViSUQKdGVtcDwtc3Ryc3BsaXQoeCwiTVIzIikKbWF0ICA8LSBtYXRyaXgodW5saXN0KHRlbXApLCBuY29sPTIsIGJ5cm93PVRSVUUpCmRmICAgPC0gYXMuZGF0YS5mcmFtZShtYXQpClQxLk1SMy5NQVNURVIkU3ViSUQ8LWFzLmNoYXJhY3RlcihkZiRWMSkKVDEuTVIzLk1BU1RFUiRTZXNzaW9uPC0iTVIzIgoKQk9MRC5NUjMuTUFTVEVSPC1yZWFkeGw6OnJlYWRfZXhjZWwoIi9Wb2x1bWVzL2VCQUNIL01SSS9RQ19PdXRwdXQvZUJBQ0hfMTJtb19NUklfUUNfTUFTVEVSLnhsc3giLCBzaGVldCA9ICJlQkFDSF9NUklfUUMwNF9CT0xEIikKQk9MRC5NUjMuTUFTVEVSPC1CT0xELk1SMy5NQVNURVJbYmFzZTo6c3RhcnRzV2l0aChCT0xELk1SMy5NQVNURVIkYmlkc19uYW1lLCAic3ViIiksXQpCT0xELk1SMy5NQVNURVI8LUJPTEQuTVIzLk1BU1RFUltjb21wbGV0ZS5jYXNlcyhCT0xELk1SMy5NQVNURVIkYmlkc19uYW1lKSxdCkJPTEQuTVIzLk1BU1RFUiRiaWRzX25hbWU8LWFzLmNoYXJhY3RlcihCT0xELk1SMy5NQVNURVIkYmlkc19uYW1lKQp4PC1CT0xELk1SMy5NQVNURVIkYmlkc19uYW1lCnRlbXA8LXN0cnNwbGl0KHgsInN1Yi0iKQptYXQgIDwtIG1hdHJpeCh1bmxpc3QodGVtcCksIG5jb2w9MiwgYnlyb3c9VFJVRSkKZGYgICA8LSBhcy5kYXRhLmZyYW1lKG1hdCkKZGYkU3ViSUQ8LWFzLmNoYXJhY3RlcihkZiRWMikKeDwtZGYkU3ViSUQKdGVtcDwtc3Ryc3BsaXQoeCwiLSIpCm1hdCAgPC0gbWF0cml4KHVubGlzdCh0ZW1wKSwgbmNvbD0yLCBieXJvdz1UUlVFKQpkZiAgIDwtIGFzLmRhdGEuZnJhbWUobWF0KQpkZiRUYXNrPC1hcy5jaGFyYWN0ZXIoZGYkVjIpCng8LWRmJFRhc2sKdGVtcDwtc3Ryc3BsaXQoeCwiXyIpCm1hdCAgPC0gbWF0cml4KHVubGlzdCh0ZW1wKSwgbmNvbD0yLCBieXJvdz1UUlVFKQpkZiRUYXNrPC1tYXRbLDFdCmRmJFN1YklEPC1hcy5jaGFyYWN0ZXIoZGYkVjEpCng8LWRmJFN1YklECnRlbXA8LXN0cnNwbGl0KHgsIk1SMyIpCm1hdCAgPC0gbWF0cml4KHVubGlzdCh0ZW1wKSwgbmNvbD0yLCBieXJvdz1UUlVFKQpkZiRTdWJJRDwtbWF0WywxXQpkZiRTZXNzaW9uPC0iTVIzIgp4PC1jKCJTdWJJRCIsIlRhc2siLCJTZXNzaW9uIikKVEFTSy5kZjwtZGZbeF0KZGYgICA8LSBjYmluZChUQVNLLmRmLEJPTEQuTVIzLk1BU1RFUikKQk9MRC5JUU1zLmRmICA8LSBhcy5kYXRhLmZyYW1lKGRmKQpybShkZiwgbWF0LCB0ZW1wLCAgeCkKQk9MRC5NUjMuTUFTVEVSPC1CT0xELklRTXMuZGZbLC1jKDQpXQoKYGBgCiMjIENoZWNrOiBNQVNURVIgU3ByZWFkc2hlZXRzCmBgYHtyLCBDSEVDSyBNSVNTSU5HIERBVCAsIGluY2x1ZGU9VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0KZUJBQ0hfUUNfRGF0YWJhc2UxPC1hcy50aWJibGUoZUJBQ0hfUUNfRGF0YWJhc2UxKQplQkFDSF9RQ19EYXRhYmFzZTI8LWFzLnRpYmJsZShlQkFDSF9RQ19EYXRhYmFzZTIpCmVCQUNIX1FDX0RhdGFiYXNlMSRTdWJqZWN0WyEoZUJBQ0hfUUNfRGF0YWJhc2UxJFN1YmplY3QgJWluJSAgVDEuTVIxLk1BU1RFUiRTdWJJRCldCmVCQUNIX1FDX0RhdGFiYXNlMiRTdWJqZWN0WyEoZUJBQ0hfUUNfRGF0YWJhc2UyJFN1YmplY3QgJWluJSAgVDEuTVIyLk1BU1RFUiRTdWJJRCldCmVCQUNIX1FDX0RhdGFiYXNlMyRTdWJqZWN0WyEoZUJBQ0hfUUNfRGF0YWJhc2UzJFN1YmplY3QgJWluJSAgVDEuTVIzLk1BU1RFUiRTdWJJRCldClQxLk1SMS5NQVNURVIgPC0gVDEuTVIxLk1BU1RFUiAlPiUgc2VsZWN0KFN1YklELCBTZXNzaW9uLGNucixmd2htX2F2ZyxzbnJfdG90YWwsc25yZF90b3RhbCkKVDEuTVIyLk1BU1RFUiA8LSBUMS5NUjIuTUFTVEVSICU+JSBzZWxlY3QoU3ViSUQsU2Vzc2lvbiwgY25yLGZ3aG1fYXZnLHNucl90b3RhbCxzbnJkX3RvdGFsKQpUMS5NUjMuTUFTVEVSIDwtIFQxLk1SMy5NQVNURVIgJT4lIHNlbGVjdChTdWJJRCwgU2Vzc2lvbixjbnIsZndobV9hdmcsc25yX3RvdGFsLHNucmRfdG90YWwpCnRtcDwtcmJpbmQoVDEuTVIxLk1BU1RFUixUMS5NUjIuTUFTVEVSICkKU3RydWN0LlFDPC1yYmluZCh0bXAsVDEuTVIzLk1BU1RFUiApCmVCQUNILkFkbWluJFNlc3Npb248LWFzLmZhY3RvcihlQkFDSC5BZG1pbiRTZXNzaW9uKQplQkFDSC5BZG1pbiRTdWJJRDwtYXMuY2hhcmFjdGVyKGVCQUNILkFkbWluJFN1YmplY3QpCmVCQUNIPC1sZWZ0X2pvaW4oZUJBQ0guQWRtaW4sIFN0cnVjdC5RQykKCkJPTEQuTVIxLk1BU1RFUjwtQk9MRC5NUjEuTUFTVEVSICU+JSBzZWxlY3QoU3ViSUQsIFNlc3Npb24sVGFzayxkdmFyc19uc3RkLCBmZF9tZWFuLGZ3aG1fYXZnLGdjb3Isc25yLHRzbnIpCkJPTEQuTVIyLk1BU1RFUjwtQk9MRC5NUjIuTUFTVEVSICU+JSBzZWxlY3QoU3ViSUQsIFNlc3Npb24sVGFzayxkdmFyc19uc3RkLCBmZF9tZWFuLGZ3aG1fYXZnLGdjb3Isc25yLHRzbnIpCkJPTEQuTVIzLk1BU1RFUjwtQk9MRC5NUjMuTUFTVEVSICU+JSBzZWxlY3QoU3ViSUQsIFNlc3Npb24sVGFzayxkdmFyc19uc3RkLCBmZF9tZWFuLGZ3aG1fYXZnLGdjb3Isc25yLHRzbnIpCnRtcDwtcmJpbmQoQk9MRC5NUjEuTUFTVEVSLEJPTEQuTVIyLk1BU1RFUiApCkJPTEQuUUM8LXJiaW5kKHRtcCxCT0xELk1SMy5NQVNURVIgKQplQkFDSF9CT0xEPC1sZWZ0X2pvaW4oZUJBQ0guQWRtaW4sIEJPTEQuUUMpCmVCQUNIX0JPTEQkUmVwb3J0PC1pZl9lbHNlKGVCQUNIX0JPTEQkV2Vla2x5UmVwb3J0PT0iMCIsICJOZXciLCAiQ3VycmVudCIpCmVCQUNIX0JPTEQkUmVwb3J0PC1hcy5mYWN0b3IoZUJBQ0hfQk9MRCRSZXBvcnQpCmVCQUNIX0JPTEQ8LWFycmFuZ2UoZUJBQ0hfQk9MRCwgIkRhdGUiKQpgYGAKCgoKCmBgYHtyIHNldHVwX3RtcCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShEVCkKbGlicmFyeShnZ2FsdCkKbGlicmFyeShwbHlyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShnZ0V4dHJhKQpsaWJyYXJ5KGdncGxvdGx5RXh0cmEpCmxpYnJhcnkoZ2d0aGVtZXMpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkoc2NhbGVzKSAjIHRvIGFjY2VzcyBicmVha3MvZm9ybWF0dGluZyBmdW5jdGlvbnMKbGlicmFyeSh2aXNyZWcpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGdncHVicikKbGlicmFyeShyc3RhdGl4KQpsaWJyYXJ5KEdHYWxseSkKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkoZ2dzdGF0c3Bsb3QpCgplQkFDSDwtYXJyYW5nZShlQkFDSCwgIkRhdGUiKQplQkFDSCRtb250aHM8LWZvcm1hdChhcy5EYXRlKGVCQUNIJERhdGUpLCAiJWIvJXkiKQojIHNlbGVjdCBwYXJ0IG9mIHRoZSBkYXRhc2V0IGFuZCB1c2UgaXQgZm9yIHBsb3R0aW5nCmVCQUNIJG1vbnRoczwtZmFjdG9yKGVCQUNIJG1vbnRocywgbGV2ZWxzPWMoIkp1bi8xOSIsICJKdWwvMTkiICAsIlNlcC8xOSIgLCAiT2N0LzE5IiAsIk5vdi8xOSIsICJEZWMvMTkiICwiSmFuLzIwIiAsIkZlYi8yMCIsICAiQXVnLzIwIikpCgojU2NhbiBmcmVxdWVuY3kgYnkgc2l0ZSBmb3IgZWFjaCBRdWFydGVyIApTZXNzaW9uWG1vbnRoczwtIGFzLmRhdGEuZnJhbWUodGFibGUobW9udGhzPWVCQUNIJG1vbnRocywgYnk9ZUJBQ0gkU2Vzc2lvbikpCm5hbWVzKFNlc3Npb25YbW9udGhzKVtuYW1lcyhTZXNzaW9uWG1vbnRocykgPT0gImJ5Il0gPC0gIlNlc3Npb24iIAoKIyBSZW9yZGVyIHRoZSBkYXRhYmFzZSBhY2NvcmRpbmcgdG8gUXVhcnRlci50aW1lLCBzbyB0aGF0IHdoZW4gaXQgY29tZXMgdG8gZGF0YSB2aXN1YWxpemF0aW9uIHRoZSB3ZWVrZGF5cyB3aWxsIGJlIGluIHRoZSByaWdodCBvcmRlciMjCgpTZXNzaW9uWG1vbnRocyRtb250aHM8LSBmYWN0b3IoU2Vzc2lvblhtb250aHMkbW9udGhzLCBsZXZlbHM9YygiSnVuLzE5IiwgIkp1bC8xOSIgICwiU2VwLzE5IiAsICJPY3QvMTkiICwiTm92LzE5IiwgIkRlYy8xOSIgLCJKYW4vMjAiICwiRmViLzIwIiwgICJBdWcvMjAiKSkKClNjYW5fZnJlcTwtU2Vzc2lvblhtb250aHNbb3JkZXIoU2Vzc2lvblhtb250aHMkbW9udGhzKSxdCgpDb3VudHNfYnlfbW9udGg8LWdncGxvdChkYXRhPVNjYW5fZnJlcSwKICAgICAgIGFlcyh4ID1tb250aHMsIHk9RnJlcSwgIGZpbGw9U2Vzc2lvbikpKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSsKICBnZ3RpdGxlKGxhYmVsID0gIlNjYW4gRnJlcXVlbmN5IGJ5IE1vbnRoIikrCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIAogICAgICAgIGxpbmVoZWlnaHQgPSAwLjgsIGZhY2UgPSAiYm9sZCIpKSsKICAgICAgICB4bGFiKCJNb250aCIpK3lsYWIoIlNjYW5GcmVxIikKZ2dwbG90bHkoQ291bnRzX2J5X21vbnRoKQpgYGAKCgpgYGB7ciwgTkVXLCAgd2FybmluZz1GQUxTRSwgIGVjaG89RkFMU0V9CmRmPC1jKCJTdWJJRCIsICJTZXNzaW9uIiwgIkRhdGUiLCAgImNuciIgLCAiZndobV9hdmciLCAic25yX3RvdGFsIiAsInNucmRfdG90YWwiICkKdG1wPC1lQkFDSFtkZl0Kcm0oZGYpCgojIyBHR0FMTFk6OiBHR1BMT1QgYWRkLW9uIGJ5IFRpZHl2ZXJzZQojIFJ1biB0aGlzIHRvIHNodXQgb2ZmIGJpbndpZHRoIHdhcm5pbmcKREFUQV9aX3R5cGVzIDwtIGxpc3QoCiAgY29tYm9Ib3Jpem9udGFsID0gd3JhcChnZ2FsbHlfZmFjZXRoaXN0LCBiaW53aWR0aCA9IDIpCikKIyMjR0dUcwojQmFzaWMgUGxvdDogZ2d0cyhEQVRBX1NpdGVaLmRmLCAiRGF0ZTEiLCA1OjkpICNub3J1bgp0bXAkRGF0ZTwtYXMuRGF0ZSh0bXAkRGF0ZSkKREFUQV9aX21hcHBpbmcgPC0gYWVzKGNvbG9yID0gU2Vzc2lvbikKCk1QUkFHRV9RQVBzX2J5X0RhdGU8LWdndHMoCiAgdG1wLCBEQVRBX1pfbWFwcGluZywKICAiRGF0ZSIsIDM6NywKICB0eXBlcyA9IERBVEFfWl90eXBlcywKICBsZWdlbmQgPSBjKDQpLAogIGNvbHVtbkxhYmVsc1kgPSBjKAogICAgICJTZXNzaW9uIiwKICAgICAiQ05SIiwKICAgICAiZndobSIsIAogICAgICJTTlIiLCAKICAgICAiU05SZCIKICApLAogIHNob3dTdHJpcHMgPSBGQUxTRQopICsKICBsYWJzKAogICAgdGl0bGU9ICJNUFJBR0UgSVFNUyBieSBTZXNzaW9uIE92ZXIgVGltZSIsCiAgICBmaWxsID0gIlNlc3Npb24iKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoCiAgICAgIGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvciA9ICJncmV5IgogICAgKQogICkKTVBSQUdFX1FBUHNfYnlfRGF0ZQpgYGAKCgojIyMjIGByIGZvcm1hdChUT0RBWSwgZm9ybWF0PSIlQiAlZCAlWSIpYCAgCgoKYGBge3IgU3RydWN0dXJhbCBJUU0gYnkgU2Vzc2lvbiBTcGFya2xpbmUsIGluY2x1ZGU9VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSxyZXN1bHRzPSdhcy5pcyd9CmxpYnJhcnkoZm9ybWF0dGFibGUpCiMgQXZlcmFnZSBieSBTaXRlCiMjIyMjIyMjIyMjIyMjIyMKIyBNYWtlIFN1bW1hcnkgdGFibGUgdy8gU1BBUktfTElORQplQkFDSDwtYXJyYW5nZShlQkFDSCwgIkRhdGUiKQplQkFDSDwtZUJBQ0hbY29tcGxldGUuY2FzZXMoZUJBQ0gkY25yKSxdCnJlcyA8LSBlQkFDSCAlPiUgCiAgZHBseXI6Omdyb3VwX2J5KFNlc3Npb24pICU+JSAKICBkcGx5cjo6c3VtbWFyaXNlKE49bigpLAogICAgICAgICAgICAnQ05SJz1yb3VuZChtZWFuKGNuciksNCksCiAgICAgICAgICAgICdzZCc9cm91bmQoc2QoY25yKSw0KSwKICAgICAgICAgICAgJ2Nucic9YXMuY2hhcmFjdGVyKGh0bWx0b29sczo6YXMudGFncyhzcGFya2xpbmUoYyhjbnIpKSkpLAoKICAgICAgICAgICAgJ0ZXSE0nPXJvdW5kKG1lYW4oZndobV9hdmcpLDQpLAogICAgICAgICAgICAnc2QgJz1yb3VuZChtZWFuKGZ3aG1fYXZnKSw0KSwKICAgICAgICAgICAgJ2Z3aG0nPWFzLmNoYXJhY3RlcihodG1sdG9vbHM6OmFzLnRhZ3Moc3BhcmtsaW5lKGMoZndobV9hdmcpKSkpLAoKICAgICAgICAgICAgU05SLm1lYW49cm91bmQobWVhbihzbnJfdG90YWwpLDQpLAogICAgICAgICAgICAnc2QnPXJvdW5kKHNkKHNucl90b3RhbCksNCksCiAgICAgICAgICAgICJzbnIiPWFzLmNoYXJhY3RlcihodG1sdG9vbHM6OmFzLnRhZ3Moc3BhcmtsaW5lKGMoc25yX3RvdGFsKSkpKSwKCiAgICAgICAgICAgIAogICAgICAgICAgICBTTlJkLm1lYW49cm91bmQobWVhbihzbnJkX3RvdGFsKSw0KSwKICAgICAgICAgICAgJ3NkJz1yb3VuZChzZChzbnJkX3RvdGFsKSw0KSwKICAgICAgICAgICAgc25yZD1hcy5jaGFyYWN0ZXIoaHRtbHRvb2xzOjphcy50YWdzKHNwYXJrbGluZShjKHNucmRfdG90YWwpKSkpKSAlPiUKCiAgZm9ybWF0dGFibGUoKSAlPiUKICBmb3JtYXR0YWJsZTo6YXMuaHRtbHdpZGdldCgpCgpyZXMkZGVwZW5kZW5jaWVzIDwtIGMocmVzJGRlcGVuZGVuY2llcyxodG1sd2lkZ2V0czo6OndpZGdldF9kZXBlbmRlbmNpZXMoInNwYXJrbGluZSIsICJzcGFya2xpbmUiKSkKcmVzCmBgYAoKYGBge3IgQW5udWFsIFN0cnVjdCBSZXBvcnQsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoID0gMTMsb3V0LndpZHRoID0gIjEzaW4iLCBmaWcuYWxpZ249ImMifQplQkFDSDwtYXJyYW5nZShlQkFDSCwgIkRhdGUiKQplQkFDSCRtb250aHM8LWZvcm1hdChhcy5EYXRlKGVCQUNIJERhdGUpLCAiJWIvJXkiKQojIHNlbGVjdCBwYXJ0IG9mIHRoZSBkYXRhc2V0IGFuZCB1c2UgaXQgZm9yIHBsb3R0aW5nCmVCQUNIJG1vbnRoczwtZmFjdG9yKGVCQUNIJG1vbnRocywgbGV2ZWxzPWMoIkp1bi8xOSIsICJKdWwvMTkiICAsIlNlcC8xOSIgLCAiT2N0LzE5IiAsIk5vdi8xOSIsICJEZWMvMTkiICwiSmFuLzIwIiAsIkZlYi8yMCIsICAiQXVnLzIwIikpCgpUTVAyPC1lQkFDSCAlPiUgc2VsZWN0KFN1YklELCBTZXNzaW9uLCBtb250aHMsIGNuciwgZndobV9hdmcsc25yX3RvdGFsLHNucmRfdG90YWwpClRNUDI8LXJlc2hhcGUyOjptZWx0KFRNUDIsIGlkLnZhcnM9YygiU3ViSUQiLCAiU2Vzc2lvbiIsICJtb250aHMiKSkKVE1QMiRTZXNzaW9uPC1hcy5mYWN0b3IoVE1QMiRTZXNzaW9uKQoKZ2dzdGF0c3Bsb3Q6Omdyb3VwZWRfZ2diZXR3ZWVuc3RhdHMoCiAgICBkYXRhID0gVE1QMiwKICAgIHg9bW9udGhzLAogICAgeSA9IHZhbHVlLAogICAgZ3JvdXBpbmcudmFyID0gdmFyaWFibGUsCiBwbG90LnR5cGUgPSAidmlvbGluIiwKICAgIHR5cGUgPSAibnAiLAogICAgY29uZi5sZXZlbCA9IDAuOTksCiAgICB4bGFiID0gInJlcG9ydCIsCiAgICB5bGFiID0gInZhbHVlIiwKICAgZ2d0aGVtZSA9IGdncGxvdDI6OnRoZW1lX2dyYXkoKSwgIyBhIGRpZmZlcmVudCB0aGVtZQogICAgcGFja2FnZSA9ICJ5YXJyciIsICMgcGFja2FnZSBmcm9tIHdoaWNoIGNvbG9yIHBhbGV0dGUgaXMgdG8gYmUgdGFrZW4KICAgIHBhbGV0dGUgPSAiaW5mbzIiLCAjIGNob29zaW5nIGEgZGlmZmVyZW50IGNvbG9yIHBhbGV0dGUKICAgIG91dGxpZXIudGFnZ2luZyA9IFRSVUUsCiAgICBvdXRsaWVyLmxhYmVsLmFyZ3MgPSBsaXN0KGNvbG9yID0gInJlZCIpLCAjIG91dGxpZXIgcG9pbnQgbGFiZWwgY29sb3IKICAgIGdnc3RhdHNwbG90LmxheWVyID0gRkFMU0UsCiAgICBvdXRsaWVyLmxhYmVsID0gIlN1YklEIiwKIHBhaXJ3aXNlLmNvbXBhcmlzb25zID0gVFJVRSwgIyBkaXNwbGF5IHJlc3VsdHMgZnJvbSBwYWlyd2lzZSBjb21wYXJpc29ucwogICAgcGFpcndpc2UuZGlzcGxheSA9ICJzaWduaWZpY2FudCIsICMgZGlzcGxheSBvbmx5IHNpZ25pZmljYW50IHBhaXJ3aXNlIGNvbXBhcmlzb25zCiAgICAjIGFyZ3VtZW50cyByZWxldmFudCBmb3IgZ2dzdGF0c3Bsb3Q6OmNvbWJpbmVfcGxvdHMKICAgIHRpdGxlLnRleHQgPSAiQW5udWFsIFN0cnV0dXJhbCBJUU0gUmVwb3J0IiwKIHRpdGxlLnNpemUgPSAxMiApCgpzbnJfbWVhbi5jb21wYXI8LWNvbXBhcmVfbWVhbnMoc25yX3RvdGFsIH4gbW9udGhzLCBlQkFDSCkKZGF0YXRhYmxlKHNucl9tZWFuLmNvbXBhciwgcm93bmFtZXMgPSBGQUxTRSwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSA1KSkgCgoKYGBgCgogIAogIAojIyBNQVNURVIgV2Vla2x5IFJlcG9ydCA9PSAwCmBgYHtyIFJlcG9ydCBTdWJqZWN0cyBUYWJsZSwgaW5jbHVkZT1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBvdXQud2lkdGggPSAiMTJpbiJ9CmVCQUNIJGRhdGU8LWZvcm1hdChhcy5EYXRlKGVCQUNIJERhdGUpLCIlYi8lZC8leSIpCk5FVy50YWJsZTwtZUJBQ0ggJT4lIGZpbHRlcihXZWVrbHlSZXBvcnQ9PSIwIikgJT4lIGdyb3VwX2J5KFNlc3Npb24pICU+JSBzZWxlY3QoU3ViamVjdCwgU2Vzc2lvbiwgZGF0ZSwgU2Nhbk5vdGVzLCBRQzAzLFFDMDQpCkRUOjpkYXRhdGFibGUoTkVXLnRhYmxlLCByb3duYW1lcyA9IEZBTFNFKQpgYGAKCgojIFN0cnVjdHVyYWwgUmVwb3J0CmBgYHtyIFdlZWtseSBTdHJ1Y3R1cmFsIFJlcG9ydCBTcGFya2xpbmUsIGluY2x1ZGU9VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0nYXMuaXMnfQplQkFDSCRjbnJaPC1hcy5udW1lcmljKHNjYWxlKGVCQUNIJGNuciwgc2NhbGUgPSBUKSkKZUJBQ0gkZndobVo8LWFzLm51bWVyaWMoc2NhbGUoZUJBQ0gkZndobV9hdmcsIHNjYWxlID0gVCkpCmVCQUNIJHNuclo8LWFzLm51bWVyaWMoc2NhbGUoZUJBQ0gkc25yX3RvdGFsLCBzY2FsZSA9IFQpKQplQkFDSCRzbnJkWjwtYXMubnVtZXJpYyhzY2FsZShlQkFDSCRzbnJkX3RvdGFsLCBzY2FsZSA9IFQpKQplQkFDSCRSZXBvcnQ8LWlmX2Vsc2UoZUJBQ0gkV2Vla2x5UmVwb3J0PT0iMCIsICJOZXciLCAiQ3VycmVudCIpCmVCQUNIJFJlcG9ydDwtYXMuZmFjdG9yKGVCQUNIJFJlcG9ydCkKZUJBQ0g8LWFycmFuZ2UoZUJBQ0gsICJEYXRlIikKCnJlcyA8LSBlQkFDSCAlPiUgCiAgZHBseXI6Omdyb3VwX2J5KFJlcG9ydCkgJT4lIAogIGRwbHlyOjpzdW1tYXJpc2UoTj1uKCksCiAgICAgICdDTlInPXJvdW5kKG1lYW4oY25yKSwzKSwKICAgICAgJyBzZCc9cm91bmQoc2QoY25yKSwzKSwKICAgICAgJyB6Jz0gYXMuY2hhcmFjdGVyKGh0bWx0b29sczo6YXMudGFncyhzcGFya2xpbmUoYyhjbnJaKSwgdHlwZSA9ICJiYXIiKSkpLCAKCiAgICAgICAnRldITSc9cm91bmQobWVhbihmd2htX2F2ZyksMyksCiAgICAgICAnc2QgJz1yb3VuZChtZWFuKGZ3aG1fYXZnKSwzKSwKICAgICAgICdaJz0gYXMuY2hhcmFjdGVyKGh0bWx0b29sczo6YXMudGFncyhzcGFya2xpbmUoYyhmd2htWiksIHR5cGUgPSAibGluZSIpKSksIAoKCiAgICAgICAiU05SIj1yb3VuZChtZWFuKHNucl90b3RhbCksMyksCiAgICAgICAnLnNkICc9cm91bmQoc2Qoc25yX3RvdGFsKSwzKSwKICAgICAgICAneiAnPSBhcy5jaGFyYWN0ZXIoaHRtbHRvb2xzOjphcy50YWdzKHNwYXJrbGluZShjKHNuclopLCB0eXBlID0gImJveCIpKSksCgogICAgICAgICdTTlJkJz1yb3VuZChtZWFuKHNucmRfdG90YWwpLDMpLAogICAgICAgICdzZC4nPXJvdW5kKHNkKHNucmRfdG90YWwpLDMpLAogICAgICAgICdaICc9IGFzLmNoYXJhY3RlcihodG1sdG9vbHM6OmFzLnRhZ3Moc3BhcmtsaW5lKGMoc25yZFopLCB0eXBlID0gImJveCIpKSkpICU+JQoKICBmb3JtYXR0YWJsZSggYWxpZ24gPWMoImwiLCJsIiwiciIsImwiLCJsIiwiciIsImwiLCJsIiwiciIsImwiLCJsIiwiciIsImwiLCJsIikgKSAlPiUKICBmb3JtYXR0YWJsZTo6YXMuaHRtbHdpZGdldCgpCgpyZXMkZGVwZW5kZW5jaWVzIDwtIGMocmVzJGRlcGVuZGVuY2llcyxodG1sd2lkZ2V0czo6OndpZGdldF9kZXBlbmRlbmNpZXMoInNwYXJrbGluZSIsICJzcGFya2xpbmUiKSkKcmVzCmBgYAoKYGBge3IgV2Vla2x5IFN0cnVjdHVyYWwgUmVwb3J0IEJveHBsb3RzLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBmaWcud2lkdGggPSAxMSwgICAgb3V0LndpZHRoID0gIjEyaW4iLCBmaWcuYWxpZ249ImMifQpUTVA8LWVCQUNIICU+JSBzZWxlY3QoU3ViSUQsIFNlc3Npb24sIERhdGUsIFJlcG9ydCwgY25yLCBmd2htX2F2ZyxzbnJfdG90YWwsc25yZF90b3RhbCkKVE1QPC1yZXNoYXBlMjo6bWVsdChUTVAsIGlkLnZhcnM9YygiU3ViSUQiLCAiU2Vzc2lvbiIsICJEYXRlIiwgIlJlcG9ydCIpKQoKVE1QJFNlc3Npb248LWFzLmZhY3RvcihUTVAkU2Vzc2lvbikKVE1QJFJlcG9ydDwtYXMuZmFjdG9yKFRNUCRSZXBvcnQpCiMgc2VsZWN0IHBhcnQgb2YgdGhlIGRhdGFzZXQgYW5kIHVzZSBpdCBmb3IgcGxvdHRpbmcKZ2dzdGF0c3Bsb3Q6Omdyb3VwZWRfZ2diZXR3ZWVuc3RhdHMoCiAgICBkYXRhID0gVE1QLAogICAgeD1SZXBvcnQsCiAgICB5ID0gdmFsdWUsCiAgICBncm91cGluZy52YXIgPSB2YXJpYWJsZSwKIHBsb3QudHlwZSA9ICJ2aW9saW4iLAogICAgdHlwZSA9ICJucCIsCiAgICBjb25mLmxldmVsID0gMC45OSwKICAgIHhsYWIgPSAicmVwb3J0IiwKICAgIHlsYWIgPSAidmFsdWUiLAogICBnZ3RoZW1lID0gZ2dwbG90Mjo6dGhlbWVfZ3JheSgpLCAjIGEgZGlmZmVyZW50IHRoZW1lCiAgcGFja2FnZSA9ICJ5YXJyciIsICMgcGFja2FnZSBmcm9tIHdoaWNoIGNvbG9yIHBhbGV0dGUgaXMgdG8gYmUgdGFrZW4KICBwYWxldHRlID0gImluZm8yIiwgIyBjaG9vc2luZyBhIGRpZmZlcmVudCBjb2xvciBwYWxldHRlCiAgICBvdXRsaWVyLnRhZ2dpbmcgPSBUUlVFLAogICAgb3V0bGllci5sYWJlbC5hcmdzID0gbGlzdChjb2xvciA9ICJyZWQiKSwgIyBvdXRsaWVyIHBvaW50IGxhYmVsIGNvbG9yCiAgICB0aXRsZS5zaXplID0gMTIsCiAgICBnZ3N0YXRzcGxvdC5sYXllciA9IEZBTFNFLAogICAgb3V0bGllci5sYWJlbCA9ICJTdWJJRCIsCiAgICAjIGFyZ3VtZW50cyByZWxldmFudCBmb3IgZ2dzdGF0c3Bsb3Q6OmNvbWJpbmVfcGxvdHMKICAgIHRpdGxlLnRleHQgPSAiV2Vla2x5IE1QUkFHRSBSZXBvcnQiLAogc3ViLnNpemUgPSAzLAogZ3JlZWR5PVRSVUUsCiBwYWlyd2lzZS5jb21wYXJpc29ucyA9IFRSVUUsICMgZGlzcGxheSByZXN1bHRzIGZyb20gcGFpcndpc2UgY29tcGFyaXNvbnMKICAgIHBhaXJ3aXNlLmRpc3BsYXkgPSAic2lnbmlmaWNhbnQiLCAjIGRpc3BsYXkgb25seSBzaWduaWZpY2FudCBwYWlyd2lzZSBjb21wYXJpc29ucwogc3RhdHMubGFiZWwuYXJncyA9IGxpc3Qoc2l6ZSA9IDIsIGRpcmVjdGlvbiA9ICJ5IikpCgpgYGAKCmBgYHtyLCBNUFJBR0UgU05SIEFjcm9zcyBUaW1lLCB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGggPSAxMSwgICAgb3V0LndpZHRoID0gIjEyaW4iLCBmaWcuYWxpZ249ImMifQpTTlJfRGVucy5wbG90PC1nZ2RlbnNpdHkoZUJBQ0gsIHggPSAic25yX3RvdGFsIiwKICAgYWRkID0gIm1lYW4iLCBydWcgPSBUUlVFLCBuYS5ybT1UUlVFLAogICBjb2xvciA9ICJTZXNzaW9uIiwgZmlsbCA9ICJTZXNzaW9uIikKCmcgPC0gZ2dwbG90KGVCQUNILCBhZXMobW9udGhzLCBzbnJfdG90YWwpKQpnYm94X1NOUl9tb250aDwtZyArIGdlb21fYm94cGxvdChhZXMoZmlsbD1mYWN0b3IoU2Vzc2lvbikpKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTY1LCB2anVzdD0wLjYpKSArIAogIGxhYnModGl0bGU9IkJveCBwbG90IiwgCiAgICAgICBzdWJ0aXRsZT0iTVBSQUdFIFNOUiBHcm91cGVkIGJ5IE1vbnRoICYgU2Vzc2lvbiIsCiAgICAgICB4PSJNb250aCIsCiAgICAgICB5PSJNUFJBR0UgU05SIikKCgpncmlkRXh0cmE6OmdyaWQuYXJyYW5nZShTTlJfRGVucy5wbG90LCBnYm94X1NOUl9tb250aCwgbmNvbD0yKQoKYGBgCgpgYGB7ciwgTVBSQUdFIENOUiBBY3Jvc3MgVGltZSAsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzLmlzJywgIGZpZy53aWR0aCA9IDExLCAgICBvdXQud2lkdGggPSAiMTJpbiIsIGZpZy5hbGlnbj0iYyJ9CkNOUi5EZW5zLnBsb3Q8LWdnZGVuc2l0eShlQkFDSCwgeCA9ICJjbnIiLAogICBhZGQgPSAibWVhbiIsIHJ1ZyA9IFRSVUUsIG5hLnJtPVRSVUUsCiAgIGNvbG9yID0gIlNlc3Npb24iLCBmaWxsID0gIlNlc3Npb24iKQoKZyA8LSBnZ3Bsb3QoZUJBQ0gsIGFlcyhtb250aHMsIGNucikpCmdib3hfY25yX21vbnRoPC1nICsgZ2VvbV9ib3hwbG90KGFlcyhmaWxsPWZhY3RvcihTZXNzaW9uKSkpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NjUsIHZqdXN0PTAuNikpICsgCiAgbGFicyh0aXRsZT0iQm94IHBsb3QiLCAKICAgICAgIHN1YnRpdGxlPSJNUFJBR0UgQ05SIEdyb3VwZWQgYnkgTW9udGggJiBTZXNzaW9uIiwKICAgICAgIHg9Im1vbnRocyIsCiAgICAgICB5PSJjbnIiLAogICAgICAgY2FwdGlvbj0iTmVlZCB0byB0YWtlIGEgY2xvc2VyIGxvb2sgYXQgSmFudWFyeSwgbGlrZWx5IEUxMDk4LCBzdGlsbCBoYXZlIHRvIG1ha2Ugc3VyZSBjb3JyZWN0IE1SSVFDX0lOIGZpbGVzIHdlcmUgdXNlZC4iICkKIAojCiNNUFJBR0VfY25yLmNvbXBhcjwtY29tcGFyZV9tZWFucyhjbnJ+U2Vzc2lvbiwgdG1wKQojTVBSQUdFX2Nuci5jb21wYXI8LWFzLmRhdGEuZnJhbWUoTVBSQUdFX2Nuci5jb21wYXIpCgoKZ3JpZEV4dHJhOjpncmlkLmFycmFuZ2UoQ05SLkRlbnMucGxvdCwgZ2JveF9jbnJfbW9udGgsIG5jb2w9MikKCmBgYAoKYGBge3IgU2Vzc2lvbiBDb21wYXJlIFRhYmxlLCB3YXJuaW5nPUZBTFNFLGZpZy53aWR0aCA9IDEyLCAgICBvdXQud2lkdGggPSAiMTJpbiJ9CiMgVmlvbGluIHBsb3RzIHdpdGggYm94IHBsb3RzIGluc2lkZQojIDo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6OgojIENoYW5nZSBmaWxsIGNvbG9yIGJ5IGdyb3VwczogZG9zZQojIGFkZCBib3hwbG90IHdpdGggd2hpdGUgZmlsbCBjb2xvclJlc3QuREYKbXlfY29tcGFyaXNvbnMuZGY8LWNvbXBhcmVfbWVhbnMoc25yX3RvdGFsIH4gU2Vzc2lvbiAsIGVCQUNIKQpteV9jb21wYXJpc29ucyA8LSBsaXN0KCBjKCJNUjEiLCAiTVIyIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGMoIk1SMSIsICJNUjMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgYygiTVIyIiwgIk1SMyIpCiAgICAgICAgICAgICAgICAgICAgICAgKQoKCnBsb3QuYW5vdmExPC1nZ3Zpb2xpbihlQkFDSCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICJTZXNzaW9uIiwgeSA9ICJzbnJfdG90YWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gIlNlc3Npb24iLCAgbmEucm09VFJVRSwKICAgICAgICAgIGFkZCA9ICJib3hwbG90IiwgYWRkLnBhcmFtcyA9IGxpc3QoZmlsbCA9ICJ3aGl0ZSIpKSsKICAgICAgICAgIHN0YXRfY29tcGFyZV9tZWFucyhjb21wYXJpc29ucyA9IG15X2NvbXBhcmlzb25zLCBsYWJlbCA9ICJwLnNpZ25pZiIpICsgIyBBZGQgc2lnbmlmaWNhbmNlIGxldmVscwogICAgICAgICAgc3RhdF9jb21wYXJlX21lYW5zKGxhYmVsLnkgPSAyKSAgKwogIGdndGl0bGUoIlNOUiBieSBTZXNzaW9uIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSdyaWdodCcpCgoKIyBWaW9saW4gcGxvdHMgd2l0aCBib3ggcGxvdHMgaW5zaWRlCiMgOjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6CiMgQ2hhbmdlIGZpbGwgY29sb3IgYnkgZ3JvdXBzOiBkb3NlCiMgYWRkIGJveHBsb3Qgd2l0aCB3aGl0ZSBmaWxsIGNvbG9yUmVzdC5ERgpteV9jb21wYXJpc29ucy5kZjwtY29tcGFyZV9tZWFucyhjbnIgfiBTZXNzaW9uICwgZUJBQ0gpCm15X2NvbXBhcmlzb25zIDwtIGxpc3QoIGMoIk1SMSIsICJNUjIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgYygiTVIxIiwgIk1SMyIpLAogICAgICAgICAgICAgICAgICAgICAgICBjKCJNUjIiLCAiTVIzIikKICAgICAgICAgICAgICAgICAgICAgICApCgoKcGxvdC5hbm92YTI8LWdndmlvbGluKGVCQUNILCAKICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gIlNlc3Npb24iLCB5ID0gImNuciIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiU2Vzc2lvbiIsICBuYS5ybT1UUlVFLAogICAgICAgICAgYWRkID0gImJveHBsb3QiLCBhZGQucGFyYW1zID0gbGlzdChmaWxsID0gIndoaXRlIikpKwogICAgICAgICAgc3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zID0gbXlfY29tcGFyaXNvbnMsIGxhYmVsID0gInAuc2lnbmlmIikgKyAjIEFkZCBzaWduaWZpY2FuY2UgbGV2ZWxzCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMobGFiZWwueSA9IDIpICArCiAgZ2d0aXRsZSgiQ05SIGJ5IFNlc3Npb24iKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249J3JpZ2h0JykKCgpncmlkRXh0cmE6OmdyaWQuYXJyYW5nZShwbG90LmFub3ZhMSwgcGxvdC5hbm92YTIsIG5jb2w9MikKTVBSQUdFX3Nuci5jb21wYXI8LWNvbXBhcmVfbWVhbnMoc25yX3RvdGFsflNlc3Npb24sIGVCQUNIKQpNUFJBR0Vfc25yLmNvbXBhcjwtYXMuZGF0YS5mcmFtZShNUFJBR0Vfc25yLmNvbXBhcikKRFQ6OmRhdGF0YWJsZShNUFJBR0Vfc25yLmNvbXBhciwgcm93bmFtZXMgPSBGQUxTRSkKCgpgYGAKPGJyLz4KPGJyLz4KCiMgRnVuY3Rpb25hbCBSZXBvcnQKCiMjIEVtb3Rpb25hbCBSZWFwcHJhaXNhbCBUYXNrCmBgYHtyIEVNT1JFQVAgQ1VSUkVOVCBSRVBPUlQsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGZpZy53aWR0aCA9IDEyLCAgICBvdXQud2lkdGggPSAiMTJpbiJ9CkJPTEQuZW1vcmVhcC5JUU1zLmRmPC1lQkFDSF9CT0xECkJPTEQuZW1vcmVhcC5JUU1zLmRmPC1CT0xELmVtb3JlYXAuSVFNcy5kZltCT0xELmVtb3JlYXAuSVFNcy5kZiRUYXNrPT0iZW1vcmVhcCIsXQpCT0xELmVtb3JlYXAuSVFNcy5kZjwtQk9MRC5lbW9yZWFwLklRTXMuZGZbY29tcGxldGUuY2FzZXMoQk9MRC5lbW9yZWFwLklRTXMuZGYkZHZhcnNfbnN0ZCksXQpCT0xELmVtb3JlYXAuSVFNcy5kZiRkdmFyc19uc3RkPC1kaWdpdHMoQk9MRC5lbW9yZWFwLklRTXMuZGYkZHZhcnNfbnN0ZCwgZGlnaXRzID0gNCkKQk9MRC5lbW9yZWFwLklRTXMuZGYkZmRfbWVhbjwtZGlnaXRzKEJPTEQuZW1vcmVhcC5JUU1zLmRmJGZkX21lYW4sIGRpZ2l0cyA9IDQpCkJPTEQuZW1vcmVhcC5JUU1zLmRmJGZ3aG1fYXZnPC1kaWdpdHMoQk9MRC5lbW9yZWFwLklRTXMuZGYkZndobV9hdmcsIGRpZ2l0cyA9IDQpCkJPTEQuZW1vcmVhcC5JUU1zLmRmJHNucjwtZGlnaXRzKEJPTEQuZW1vcmVhcC5JUU1zLmRmJHNuciwgZGlnaXRzID0gNCkKQk9MRC5lbW9yZWFwLklRTXMuZGYkdHNucjwtZGlnaXRzKEJPTEQuZW1vcmVhcC5JUU1zLmRmJHRzbnIsIGRpZ2l0cyA9IDQpCkJPTEQuZW1vcmVhcC5JUU1zLmRmJGdjb3I8LWRpZ2l0cyhCT0xELmVtb3JlYXAuSVFNcy5kZiRnY29yLCBkaWdpdHMgPSA0KQpCT0xELmVtb3JlYXAuSVFNcy5kZjwtQk9MRC5lbW9yZWFwLklRTXMuZGZbY29tcGxldGUuY2FzZXMoQk9MRC5lbW9yZWFwLklRTXMuZGYkU3ViamVjdCksXQpCT0xELmVtb3JlYXAuSVFNcy5kZjwtYXMuZGF0YS5mcmFtZShCT0xELmVtb3JlYXAuSVFNcy5kZiwgcm93bmFtZXM9RkFMU0UpCkJPTEQuZW1vcmVhcC5JUU1zLmRmPC1hcnJhbmdlKEJPTEQuZW1vcmVhcC5JUU1zLmRmLCJEYXRlIiApCkJPTEQuZW1vcmVhcC5JUU1zLmRmJFNjYW48LXBhc3RlKEJPTEQuZW1vcmVhcC5JUU1zLmRmJFN1YklELEJPTEQuZW1vcmVhcC5JUU1zLmRmJFNlc3Npb24sIHNlcCA9ICJfIiApCgpUTVAzPC1CT0xELmVtb3JlYXAuSVFNcy5kZiAlPiUgc2VsZWN0KFN1YklELCBTZXNzaW9uLERhdGUsIFJlcG9ydCxkdmFyc19uc3RkICxmZF9tZWFuLCBzbnIsdHNucikKVE1QMzwtcmVzaGFwZTI6Om1lbHQoVE1QMywgaWQudmFycz1jKCJTdWJJRCIsIlNlc3Npb24iICwiRGF0ZSIsICJSZXBvcnQiKSkKIyBzZWxlY3QgcGFydCBvZiB0aGUgZGF0YXNldCBhbmQgdXNlIGl0IGZvciBwbG90dGluZwpnZ3N0YXRzcGxvdDo6Z3JvdXBlZF9nZ2JldHdlZW5zdGF0cygKICAgIGRhdGEgPSBUTVAzLAogICAgeD1SZXBvcnQsCiAgICB5ID0gdmFsdWUsCiAgICBncm91cGluZy52YXIgPSB2YXJpYWJsZSwKIHBsb3QudHlwZSA9ICJ2aW9saW4iLAogICAgdHlwZSA9ICJucCIsCiAgICBjb25mLmxldmVsID0gMC45OSwKICAgIHhsYWIgPSAicmVwb3J0IiwKICAgIHlsYWIgPSAidmFsdWUiLAogICBnZ3RoZW1lID0gZ2dwbG90Mjo6dGhlbWVfZ3JheSgpLCAjIGEgZGlmZmVyZW50IHRoZW1lCiAgcGFja2FnZSA9ICJ5YXJyciIsICMgcGFja2FnZSBmcm9tIHdoaWNoIGNvbG9yIHBhbGV0dGUgaXMgdG8gYmUgdGFrZW4KICBwYWxldHRlID0gImluZm8yIiwgIyBjaG9vc2luZyBhIGRpZmZlcmVudCBjb2xvciBwYWxldHRlCiAgICBvdXRsaWVyLnRhZ2dpbmcgPSBUUlVFLAogICAgb3V0bGllci5sYWJlbC5hcmdzID0gbGlzdChjb2xvciA9ICJyZWQiKSwgIyBvdXRsaWVyIHBvaW50IGxhYmVsIGNvbG9yCiAgICB0aXRsZS5zaXplID0gMTIsCiAgICBnZ3N0YXRzcGxvdC5sYXllciA9IEZBTFNFLAogICAgb3V0bGllci5sYWJlbCA9ICJTdWJJRCIsCiAgICAjIGFyZ3VtZW50cyByZWxldmFudCBmb3IgZ2dzdGF0c3Bsb3Q6OmNvbWJpbmVfcGxvdHMKICAgIHRpdGxlLnRleHQgPSAiV2Vla2x5IEVtb1JlYXAuIElRTXMuZGYgSVFNIFJlcG9ydCIsCiBzdWIuc2l6ZSA9IDMsCiBncmVlZHk9VFJVRSwKIHBhaXJ3aXNlLmNvbXBhcmlzb25zID0gVFJVRSwgIyBkaXNwbGF5IHJlc3VsdHMgZnJvbSBwYWlyd2lzZSBjb21wYXJpc29ucwogICAgcGFpcndpc2UuZGlzcGxheSA9ICJzaWduaWZpY2FudCIsICMgZGlzcGxheSBvbmx5IHNpZ25pZmljYW50IHBhaXJ3aXNlIGNvbXBhcmlzb25zCiBzdGF0cy5sYWJlbC5hcmdzID0gbGlzdChzaXplID0gMiwgZGlyZWN0aW9uID0gInkiKSkKCmBgYAoKYGBge3IgRU1PUkVBUCwgd2FybmluZz1GQUxTRSwgICBmaWcuaGVpZ2h0PTgsICBmaWcud2lkdGggPSAxMiwgICAgb3V0LndpZHRoID0gIjEyaW4ifQpCT0xELmVtb3JlYXAuSVFNcy5kZjwtZUJBQ0hfQk9MRApCT0xELmVtb3JlYXAuSVFNcy5kZjwtQk9MRC5lbW9yZWFwLklRTXMuZGZbQk9MRC5lbW9yZWFwLklRTXMuZGYkVGFzaz09ImVtb3JlYXAiLF0KQk9MRC5lbW9yZWFwLklRTXMuZGY8LUJPTEQuZW1vcmVhcC5JUU1zLmRmW2NvbXBsZXRlLmNhc2VzKEJPTEQuZW1vcmVhcC5JUU1zLmRmJGR2YXJzX25zdGQpLF0KQk9MRC5lbW9yZWFwLklRTXMuZGYkZHZhcnNfbnN0ZDwtZGlnaXRzKEJPTEQuZW1vcmVhcC5JUU1zLmRmJGR2YXJzX25zdGQsIGRpZ2l0cyA9IDQpCkJPTEQuZW1vcmVhcC5JUU1zLmRmJGZkX21lYW48LWRpZ2l0cyhCT0xELmVtb3JlYXAuSVFNcy5kZiRmZF9tZWFuLCBkaWdpdHMgPSA0KQpCT0xELmVtb3JlYXAuSVFNcy5kZiRmd2htX2F2ZzwtZGlnaXRzKEJPTEQuZW1vcmVhcC5JUU1zLmRmJGZ3aG1fYXZnLCBkaWdpdHMgPSA0KQpCT0xELmVtb3JlYXAuSVFNcy5kZiRzbnI8LWRpZ2l0cyhCT0xELmVtb3JlYXAuSVFNcy5kZiRzbnIsIGRpZ2l0cyA9IDQpCkJPTEQuZW1vcmVhcC5JUU1zLmRmJHRzbnI8LWRpZ2l0cyhCT0xELmVtb3JlYXAuSVFNcy5kZiR0c25yLCBkaWdpdHMgPSA0KQpCT0xELmVtb3JlYXAuSVFNcy5kZiRnY29yPC1kaWdpdHMoQk9MRC5lbW9yZWFwLklRTXMuZGYkZ2NvciwgZGlnaXRzID0gNCkKQk9MRC5lbW9yZWFwLklRTXMuZGY8LUJPTEQuZW1vcmVhcC5JUU1zLmRmW2NvbXBsZXRlLmNhc2VzKEJPTEQuZW1vcmVhcC5JUU1zLmRmJFN1YmplY3QpLF0KQk9MRC5lbW9yZWFwLklRTXMuZGY8LWFzLmRhdGEuZnJhbWUoQk9MRC5lbW9yZWFwLklRTXMuZGYsIHJvd25hbWVzPUZBTFNFKQpCT0xELmVtb3JlYXAuSVFNcy5kZjwtYXJyYW5nZShCT0xELmVtb3JlYXAuSVFNcy5kZiwiRGF0ZSIgKQojIFZpb2xpbiBwbG90cyB3aXRoIGJveCBwbG90cyBpbnNpZGUKIyA6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6OjoKIyBDaGFuZ2UgZmlsbCBjb2xvciBieSBncm91cHM6IGRvc2UKIyBhZGQgYm94cGxvdCB3aXRoIHdoaXRlIGZpbGwgY29sb3JSZXN0LkRGCm15X2NvbXBhcmlzb25zLmRmPC1jb21wYXJlX21lYW5zKHNuciB+IFNlc3Npb24gLCBCT0xELmVtb3JlYXAuSVFNcy5kZikKbXlfY29tcGFyaXNvbnMgPC0gbGlzdCggYygiTVIxIiwgIk1SMiIpLAogICAgICAgICAgICAgICAgICAgICAgICBjKCJNUjEiLCAiTVIzIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGMoIk1SMiIsICJNUjMiKQogICAgICAgICAgICAgICAgICAgICAgICkKCgpwbG90LmFub3ZhMTwtZ2d2aW9saW4oQk9MRC5lbW9yZWFwLklRTXMuZGYsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiU2Vzc2lvbiIsIHkgPSAic25yIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJTZXNzaW9uIiwgIG5hLnJtPVRSVUUsCiAgICAgICAgICBhZGQgPSAiYm94cGxvdCIsIGFkZC5wYXJhbXMgPSBsaXN0KGZpbGwgPSAid2hpdGUiKSkrCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnMgPSBteV9jb21wYXJpc29ucywgbGFiZWwgPSAicC5zaWduaWYiKSArICMgQWRkIHNpZ25pZmljYW5jZSBsZXZlbHMKICAgICAgICAgIHN0YXRfY29tcGFyZV9tZWFucyhsYWJlbC55ID0gMikgICsKICBnZ3RpdGxlKCJTTlIgYnkgU2Vzc2lvbiIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ncmlnaHQnKQoKIyBWaW9saW4gcGxvdHMgd2l0aCBib3ggcGxvdHMgaW5zaWRlCiMgOjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6CiMgQ2hhbmdlIGZpbGwgY29sb3IgYnkgZ3JvdXBzOiBkb3NlCiMgYWRkIGJveHBsb3Qgd2l0aCB3aGl0ZSBmaWxsIGNvbG9yUmVzdC5ERgpteV9jb21wYXJpc29ucy5kZjwtY29tcGFyZV9tZWFucyhmZF9tZWFuIH4gU2Vzc2lvbiAsIEJPTEQuZW1vcmVhcC5JUU1zLmRmKQpteV9jb21wYXJpc29ucyA8LSBsaXN0KCBjKCJNUjEiLCAiTVIyIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGMoIk1SMSIsICJNUjMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgYygiTVIyIiwgIk1SMyIpCiAgICAgICAgICAgICAgICAgICAgICAgKQoKCnBsb3QuYW5vdmEyPC1nZ3Zpb2xpbihCT0xELmVtb3JlYXAuSVFNcy5kZiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICJTZXNzaW9uIiwgeSA9ICJmZF9tZWFuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJTZXNzaW9uIiwgIG5hLnJtPVRSVUUsCiAgICAgICAgICBhZGQgPSAiYm94cGxvdCIsIGFkZC5wYXJhbXMgPSBsaXN0KGZpbGwgPSAid2hpdGUiKSkrCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnMgPSBteV9jb21wYXJpc29ucywgbGFiZWwgPSAicC5zaWduaWYiKSArICMgQWRkIHNpZ25pZmljYW5jZSBsZXZlbHMKICAgICAgICAgIHN0YXRfY29tcGFyZV9tZWFucyhsYWJlbC55ID0gMikgICsKICBnZ3RpdGxlKCJmZF9tZWFuIGJ5IFNlc3Npb24iKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249J3JpZ2h0JykKCnBsb3QuYW5vdmEzPC1nZ3Zpb2xpbihCT0xELmVtb3JlYXAuSVFNcy5kZiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICJTZXNzaW9uIiwgeSA9ICJ0c25yIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJTZXNzaW9uIiwgIG5hLnJtPVRSVUUsCiAgICAgICAgICBhZGQgPSAiYm94cGxvdCIsIGFkZC5wYXJhbXMgPSBsaXN0KGZpbGwgPSAid2hpdGUiKSkrCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnMgPSBteV9jb21wYXJpc29ucywgbGFiZWwgPSAicC5zaWduaWYiKSArICMgQWRkIHNpZ25pZmljYW5jZSBsZXZlbHMKICAgICAgICAgIHN0YXRfY29tcGFyZV9tZWFucyhsYWJlbC55ID0gMikgICsKICBnZ3RpdGxlKCJ0c25yIGJ5IFNlc3Npb24iKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249J3JpZ2h0JykKCgpncmlkRXh0cmE6OmdyaWQuYXJyYW5nZShwbG90LmFub3ZhMSwgcGxvdC5hbm92YTIscGxvdC5hbm92YTMsIG5jb2w9MykKCmBgYAo8YnIvPgo8YnIvPgoKIyMgUmVzdGluZyBTdGF0ZQpgYGB7ciBSRVNUIENVUlJFTlQgUkVQT1JULCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBmaWcud2lkdGggPSAxMiwgICAgb3V0LndpZHRoID0gIjEyaW4ifQpCT0xELnJlc3QuSVFNcy5kZjwtZUJBQ0hfQk9MRApCT0xELnJlc3QuSVFNcy5kZjwtQk9MRC5yZXN0LklRTXMuZGZbQk9MRC5yZXN0LklRTXMuZGYkVGFzaz09InJlc3QiLF0KQk9MRC5yZXN0LklRTXMuZGY8LWFycmFuZ2UoQk9MRC5yZXN0LklRTXMuZGYsIkRhdGUiICkKQk9MRC5yZXN0LklRTXMuZGY8LUJPTEQucmVzdC5JUU1zLmRmW2NvbXBsZXRlLmNhc2VzKEJPTEQucmVzdC5JUU1zLmRmJGR2YXJzX25zdGQpLF0KQk9MRC5yZXN0LklRTXMuZGYkZHZhcnNfbnN0ZDwtZGlnaXRzKEJPTEQucmVzdC5JUU1zLmRmJGR2YXJzX25zdGQsIGRpZ2l0cyA9IDQpCkJPTEQucmVzdC5JUU1zLmRmJGZkX21lYW48LWRpZ2l0cyhCT0xELnJlc3QuSVFNcy5kZiRmZF9tZWFuLCBkaWdpdHMgPSA0KQpCT0xELnJlc3QuSVFNcy5kZiRmd2htX2F2ZzwtZGlnaXRzKEJPTEQucmVzdC5JUU1zLmRmJGZ3aG1fYXZnLCBkaWdpdHMgPSA0KQpCT0xELnJlc3QuSVFNcy5kZiRzbnI8LWRpZ2l0cyhCT0xELnJlc3QuSVFNcy5kZiRzbnIsIGRpZ2l0cyA9IDQpCkJPTEQucmVzdC5JUU1zLmRmJHRzbnI8LWRpZ2l0cyhCT0xELnJlc3QuSVFNcy5kZiR0c25yLCBkaWdpdHMgPSA0KQpCT0xELnJlc3QuSVFNcy5kZiRnY29yPC1kaWdpdHMoQk9MRC5yZXN0LklRTXMuZGYkZ2NvciwgZGlnaXRzID0gNCkKQk9MRC5yZXN0LklRTXMuZGY8LWFzLmRhdGEuZnJhbWUoQk9MRC5yZXN0LklRTXMuZGYsIHJvd25hbWVzPUZBTFNFKQoKVE1QMzwtQk9MRC5yZXN0LklRTXMuZGYgJT4lIHNlbGVjdChTdWJJRCwgU2Vzc2lvbixEYXRlLCBSZXBvcnQsZHZhcnNfbnN0ZCAsZmRfbWVhbiwgc25yLHRzbnIpClRNUDM8LXJlc2hhcGUyOjptZWx0KFRNUDMsIGlkLnZhcnM9YygiU3ViSUQiLCJTZXNzaW9uIiAsIkRhdGUiLCAiUmVwb3J0IikpCiMgc2VsZWN0IHBhcnQgb2YgdGhlIGRhdGFzZXQgYW5kIHVzZSBpdCBmb3IgcGxvdHRpbmcKZ2dzdGF0c3Bsb3Q6Omdyb3VwZWRfZ2diZXR3ZWVuc3RhdHMoCiAgICBkYXRhID0gVE1QMywKICAgIHg9UmVwb3J0LAogICAgeSA9IHZhbHVlLAogICAgZ3JvdXBpbmcudmFyID0gdmFyaWFibGUsCiBwbG90LnR5cGUgPSAidmlvbGluIiwKICAgIHR5cGUgPSAibnAiLAogICAgY29uZi5sZXZlbCA9IDAuOTksCiAgICB4bGFiID0gInJlcG9ydCIsCiAgICB5bGFiID0gInZhbHVlIiwKICAgZ2d0aGVtZSA9IGdncGxvdDI6OnRoZW1lX2dyYXkoKSwgIyBhIGRpZmZlcmVudCB0aGVtZQogIHBhY2thZ2UgPSAieWFycnIiLCAjIHBhY2thZ2UgZnJvbSB3aGljaCBjb2xvciBwYWxldHRlIGlzIHRvIGJlIHRha2VuCiAgcGFsZXR0ZSA9ICJpbmZvMiIsICMgY2hvb3NpbmcgYSBkaWZmZXJlbnQgY29sb3IgcGFsZXR0ZQogICAgb3V0bGllci50YWdnaW5nID0gVFJVRSwKICAgIG91dGxpZXIubGFiZWwuYXJncyA9IGxpc3QoY29sb3IgPSAicmVkIiksICMgb3V0bGllciBwb2ludCBsYWJlbCBjb2xvcgogICAgdGl0bGUuc2l6ZSA9IDEyLAogICAgZ2dzdGF0c3Bsb3QubGF5ZXIgPSBGQUxTRSwKICAgIG91dGxpZXIubGFiZWwgPSAiU3ViSUQiLAogICAgIyBhcmd1bWVudHMgcmVsZXZhbnQgZm9yIGdnc3RhdHNwbG90Ojpjb21iaW5lX3Bsb3RzCiAgICB0aXRsZS50ZXh0ID0gIldlZWtseSBSZXN0aW5nIFN0YXRlIElRTXMuZGYgSVFNIFJlcG9ydCIsCiBzdWIuc2l6ZSA9IDMsCiBncmVlZHk9VFJVRSwKIHBhaXJ3aXNlLmNvbXBhcmlzb25zID0gVFJVRSwgIyBkaXNwbGF5IHJlc3VsdHMgZnJvbSBwYWlyd2lzZSBjb21wYXJpc29ucwogICAgcGFpcndpc2UuZGlzcGxheSA9ICJzaWduaWZpY2FudCIsICMgZGlzcGxheSBvbmx5IHNpZ25pZmljYW50IHBhaXJ3aXNlIGNvbXBhcmlzb25zCiBzdGF0cy5sYWJlbC5hcmdzID0gbGlzdChzaXplID0gMiwgZGlyZWN0aW9uID0gInkiKSkKCmBgYAoKYGBge3IgUkVTVCwgd2FybmluZz1GQUxTRSwgICAgZmlnLndpZHRoID0gMTIsICAgIG91dC53aWR0aCA9ICIxMmluIn0KQk9MRC5yZXN0LklRTXMuZGY8LWVCQUNIX0JPTEQKQk9MRC5yZXN0LklRTXMuZGY8LUJPTEQucmVzdC5JUU1zLmRmW0JPTEQucmVzdC5JUU1zLmRmJFRhc2s9PSJyZXN0IixdCkJPTEQucmVzdC5JUU1zLmRmPC1hcnJhbmdlKEJPTEQucmVzdC5JUU1zLmRmLCJEYXRlIiApCkJPTEQucmVzdC5JUU1zLmRmPC1CT0xELnJlc3QuSVFNcy5kZltjb21wbGV0ZS5jYXNlcyhCT0xELnJlc3QuSVFNcy5kZiRkdmFyc19uc3RkKSxdCkJPTEQucmVzdC5JUU1zLmRmJGR2YXJzX25zdGQ8LWRpZ2l0cyhCT0xELnJlc3QuSVFNcy5kZiRkdmFyc19uc3RkLCBkaWdpdHMgPSA0KQpCT0xELnJlc3QuSVFNcy5kZiRmZF9tZWFuPC1kaWdpdHMoQk9MRC5yZXN0LklRTXMuZGYkZmRfbWVhbiwgZGlnaXRzID0gNCkKQk9MRC5yZXN0LklRTXMuZGYkZndobV9hdmc8LWRpZ2l0cyhCT0xELnJlc3QuSVFNcy5kZiRmd2htX2F2ZywgZGlnaXRzID0gNCkKQk9MRC5yZXN0LklRTXMuZGYkc25yPC1kaWdpdHMoQk9MRC5yZXN0LklRTXMuZGYkc25yLCBkaWdpdHMgPSA0KQpCT0xELnJlc3QuSVFNcy5kZiR0c25yPC1kaWdpdHMoQk9MRC5yZXN0LklRTXMuZGYkdHNuciwgZGlnaXRzID0gNCkKQk9MRC5yZXN0LklRTXMuZGYkZ2NvcjwtZGlnaXRzKEJPTEQucmVzdC5JUU1zLmRmJGdjb3IsIGRpZ2l0cyA9IDQpCkJPTEQucmVzdC5JUU1zLmRmPC1hcy5kYXRhLmZyYW1lKEJPTEQucmVzdC5JUU1zLmRmLCByb3duYW1lcz1GQUxTRSkKIyBWaW9saW4gcGxvdHMgd2l0aCBib3ggcGxvdHMgaW5zaWRlCiMgOjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6CiMgQ2hhbmdlIGZpbGwgY29sb3IgYnkgZ3JvdXBzOiBkb3NlCiMgYWRkIGJveHBsb3Qgd2l0aCB3aGl0ZSBmaWxsIGNvbG9yUmVzdC5ERgpteV9jb21wYXJpc29ucy5kZjwtY29tcGFyZV9tZWFucyhzbnIgfiBTZXNzaW9uICwgQk9MRC5yZXN0LklRTXMuZGYpCm15X2NvbXBhcmlzb25zIDwtIGxpc3QoIGMoIk1SMSIsICJNUjIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgYygiTVIxIiwgIk1SMyIpLAogICAgICAgICAgICAgICAgICAgICAgICBjKCJNUjIiLCAiTVIzIikKICAgICAgICAgICAgICAgICAgICAgICApCgoKcGxvdC5hbm92YTE8LWdndmlvbGluKEJPTEQucmVzdC5JUU1zLmRmLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gIlNlc3Npb24iLCB5ID0gInNuciIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiU2Vzc2lvbiIsICBuYS5ybT1UUlVFLAogICAgICAgICAgYWRkID0gImJveHBsb3QiLCBhZGQucGFyYW1zID0gbGlzdChmaWxsID0gIndoaXRlIikpKwogICAgICAgICAgc3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zID0gbXlfY29tcGFyaXNvbnMsIGxhYmVsID0gInAuc2lnbmlmIikgKyAjIEFkZCBzaWduaWZpY2FuY2UgbGV2ZWxzCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMobGFiZWwueSA9IDIpICArCiAgZ2d0aXRsZSgiU05SIGJ5IFNlc3Npb24iKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249J3JpZ2h0JykKCiMgVmlvbGluIHBsb3RzIHdpdGggYm94IHBsb3RzIGluc2lkZQojIDo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6OgojIENoYW5nZSBmaWxsIGNvbG9yIGJ5IGdyb3VwczogZG9zZQojIGFkZCBib3hwbG90IHdpdGggd2hpdGUgZmlsbCBjb2xvclJlc3QuREYKbXlfY29tcGFyaXNvbnMuZGY8LWNvbXBhcmVfbWVhbnMoZmRfbWVhbiB+IFNlc3Npb24gLCBCT0xELnJlc3QuSVFNcy5kZikKbXlfY29tcGFyaXNvbnMgPC0gbGlzdCggYygiTVIxIiwgIk1SMiIpLAogICAgICAgICAgICAgICAgICAgICAgICBjKCJNUjEiLCAiTVIzIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGMoIk1SMiIsICJNUjMiKQogICAgICAgICAgICAgICAgICAgICAgICkKCgpwbG90LmFub3ZhMjwtZ2d2aW9saW4oQk9MRC5yZXN0LklRTXMuZGYsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiU2Vzc2lvbiIsIHkgPSAiZmRfbWVhbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiU2Vzc2lvbiIsICBuYS5ybT1UUlVFLAogICAgICAgICAgYWRkID0gImJveHBsb3QiLCBhZGQucGFyYW1zID0gbGlzdChmaWxsID0gIndoaXRlIikpKwogICAgICAgICAgc3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zID0gbXlfY29tcGFyaXNvbnMsIGxhYmVsID0gInAuc2lnbmlmIikgKyAjIEFkZCBzaWduaWZpY2FuY2UgbGV2ZWxzCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMobGFiZWwueSA9IDIpICArCiAgZ2d0aXRsZSgiZmRfbWVhbiBieSBTZXNzaW9uIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSdyaWdodCcpCgpwbG90LmFub3ZhMzwtZ2d2aW9saW4oQk9MRC5yZXN0LklRTXMuZGYsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiU2Vzc2lvbiIsIHkgPSAidHNuciIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiU2Vzc2lvbiIsICBuYS5ybT1UUlVFLAogICAgICAgICAgYWRkID0gImJveHBsb3QiLCBhZGQucGFyYW1zID0gbGlzdChmaWxsID0gIndoaXRlIikpKwogICAgICAgICAgc3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zID0gbXlfY29tcGFyaXNvbnMsIGxhYmVsID0gInAuc2lnbmlmIikgKyAjIEFkZCBzaWduaWZpY2FuY2UgbGV2ZWxzCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMobGFiZWwueSA9IDIpICArCiAgZ2d0aXRsZSgidHNuciBieSBTZXNzaW9uIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSdyaWdodCcpCgoKZ3JpZEV4dHJhOjpncmlkLmFycmFuZ2UocGxvdC5hbm92YTEsIHBsb3QuYW5vdmEyLHBsb3QuYW5vdmEzLCBuY29sPTMpCgpgYGAKPGJyLz4KPGJyLz4KCiMjIE1TSVQgU3RyZXNzIFRhc2sKYGBge3IgTVNJVCBDVVJSRU5UIFJFUE9SVCwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZmlnLndpZHRoID0gMTIsICAgIG91dC53aWR0aCA9ICIxMmluIn0KQk9MRC5tc2l0LklRTXMuZGY8LWVCQUNIX0JPTEQKQk9MRC5tc2l0LklRTXMuZGY8LUJPTEQubXNpdC5JUU1zLmRmW0JPTEQubXNpdC5JUU1zLmRmJFRhc2s9PSJtc2l0IixdCkJPTEQubXNpdC5JUU1zLmRmPC1CT0xELmVtb3JlYXAuSVFNcy5kZltjb21wbGV0ZS5jYXNlcyhCT0xELm1zaXQuSVFNcy5kZiRkdmFyc19uc3RkKSxdCkJPTEQubXNpdC5JUU1zLmRmJGR2YXJzX25zdGQ8LWRpZ2l0cyhCT0xELm1zaXQuSVFNcy5kZiRkdmFyc19uc3RkLCBkaWdpdHMgPSA0KQpCT0xELm1zaXQuSVFNcy5kZiRmZF9tZWFuPC1kaWdpdHMoQk9MRC5tc2l0LklRTXMuZGYkZmRfbWVhbiwgZGlnaXRzID0gNCkKQk9MRC5tc2l0LklRTXMuZGYkZndobV9hdmc8LWRpZ2l0cyhCT0xELm1zaXQuSVFNcy5kZiRmd2htX2F2ZywgZGlnaXRzID0gNCkKQk9MRC5tc2l0LklRTXMuZGYkc25yPC1kaWdpdHMoQk9MRC5tc2l0LklRTXMuZGYkc25yLCBkaWdpdHMgPSA0KQpCT0xELm1zaXQuSVFNcy5kZiR0c25yPC1kaWdpdHMoQk9MRC5tc2l0LklRTXMuZGYkdHNuciwgZGlnaXRzID0gNCkKQk9MRC5tc2l0LklRTXMuZGYkZ2NvcjwtZGlnaXRzKEJPTEQubXNpdC5JUU1zLmRmJGdjb3IsIGRpZ2l0cyA9IDQpCkJPTEQubXNpdC5JUU1zLmRmJFN1YklEPC1hcy5jaGFyYWN0ZXIoQk9MRC5tc2l0LklRTXMuZGYkU3ViSUQpCkJPTEQubXNpdC5JUU1zLmRmPC1hcy5kYXRhLmZyYW1lKEJPTEQubXNpdC5JUU1zLmRmLCByb3duYW1lcz1GQUxTRSkKQk9MRC5tc2l0LklRTXMuZGY8LUJPTEQubXNpdC5JUU1zLmRmW2NvbXBsZXRlLmNhc2VzKEJPTEQubXNpdC5JUU1zLmRmJFN1YklEKSxdCkJPTEQubXNpdC5JUU1zLmRmPC1hcnJhbmdlKEJPTEQubXNpdC5JUU1zLmRmLCJEYXRlIiApClRNUDM8LUJPTEQubXNpdC5JUU1zLmRmICU+JSBzZWxlY3QoU3ViSUQsIFNlc3Npb24sRGF0ZSwgUmVwb3J0LGR2YXJzX25zdGQgLGZkX21lYW4sIHNucix0c25yKQpUTVAzPC1yZXNoYXBlMjo6bWVsdChUTVAzLCBpZC52YXJzPWMoIlN1YklEIiwiU2Vzc2lvbiIgLCJEYXRlIiwgIlJlcG9ydCIpKQojIHNlbGVjdCBwYXJ0IG9mIHRoZSBkYXRhc2V0IGFuZCB1c2UgaXQgZm9yIHBsb3R0aW5nCmdnc3RhdHNwbG90Ojpncm91cGVkX2dnYmV0d2VlbnN0YXRzKAogICAgZGF0YSA9IFRNUDMsCiAgICB4PVJlcG9ydCwKICAgIHkgPSB2YWx1ZSwKICAgIGdyb3VwaW5nLnZhciA9IHZhcmlhYmxlLAogcGxvdC50eXBlID0gInZpb2xpbiIsCiAgICB0eXBlID0gIm5wIiwKICAgIGNvbmYubGV2ZWwgPSAwLjk5LAogICAgeGxhYiA9ICJyZXBvcnQiLAogICAgeWxhYiA9ICJ2YWx1ZSIsCiAgIGdndGhlbWUgPSBnZ3Bsb3QyOjp0aGVtZV9ncmF5KCksICMgYSBkaWZmZXJlbnQgdGhlbWUKICBwYWNrYWdlID0gInlhcnJyIiwgIyBwYWNrYWdlIGZyb20gd2hpY2ggY29sb3IgcGFsZXR0ZSBpcyB0byBiZSB0YWtlbgogIHBhbGV0dGUgPSAiaW5mbzIiLCAjIGNob29zaW5nIGEgZGlmZmVyZW50IGNvbG9yIHBhbGV0dGUKICAgIG91dGxpZXIudGFnZ2luZyA9IFRSVUUsCiAgICBvdXRsaWVyLmxhYmVsLmFyZ3MgPSBsaXN0KGNvbG9yID0gInJlZCIpLCAjIG91dGxpZXIgcG9pbnQgbGFiZWwgY29sb3IKICAgIHRpdGxlLnNpemUgPSAxMiwKICAgIGdnc3RhdHNwbG90LmxheWVyID0gRkFMU0UsCiAgICBvdXRsaWVyLmxhYmVsID0gIlN1YklEIiwKICAgICMgYXJndW1lbnRzIHJlbGV2YW50IGZvciBnZ3N0YXRzcGxvdDo6Y29tYmluZV9wbG90cwogICAgdGl0bGUudGV4dCA9ICJXZWVrbHkgUmVzdGluZyBTdGF0ZSBJUU1zLmRmIElRTSBSZXBvcnQiLAogc3ViLnNpemUgPSAzLAogZ3JlZWR5PVRSVUUsCiBwYWlyd2lzZS5jb21wYXJpc29ucyA9IFRSVUUsICMgZGlzcGxheSByZXN1bHRzIGZyb20gcGFpcndpc2UgY29tcGFyaXNvbnMKICAgIHBhaXJ3aXNlLmRpc3BsYXkgPSAic2lnbmlmaWNhbnQiLCAjIGRpc3BsYXkgb25seSBzaWduaWZpY2FudCBwYWlyd2lzZSBjb21wYXJpc29ucwogc3RhdHMubGFiZWwuYXJncyA9IGxpc3Qoc2l6ZSA9IDIsIGRpcmVjdGlvbiA9ICJ5IikpCgpgYGAKCmBgYHtyIE1TSVQsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0UsICAgIGZpZy53aWR0aCA9IDEyLCAgICBvdXQud2lkdGggPSAiMTJpbiJ9CkJPTEQubXNpdC5JUU1zLmRmPC1lQkFDSF9CT0xECkJPTEQubXNpdC5JUU1zLmRmPC1CT0xELm1zaXQuSVFNcy5kZltCT0xELm1zaXQuSVFNcy5kZiRUYXNrPT0ibXNpdCIsXQpCT0xELm1zaXQuSVFNcy5kZjwtQk9MRC5lbW9yZWFwLklRTXMuZGZbY29tcGxldGUuY2FzZXMoQk9MRC5tc2l0LklRTXMuZGYkZHZhcnNfbnN0ZCksXQpCT0xELm1zaXQuSVFNcy5kZiRkdmFyc19uc3RkPC1kaWdpdHMoQk9MRC5tc2l0LklRTXMuZGYkZHZhcnNfbnN0ZCwgZGlnaXRzID0gNCkKQk9MRC5tc2l0LklRTXMuZGYkZmRfbWVhbjwtZGlnaXRzKEJPTEQubXNpdC5JUU1zLmRmJGZkX21lYW4sIGRpZ2l0cyA9IDQpCkJPTEQubXNpdC5JUU1zLmRmJGZ3aG1fYXZnPC1kaWdpdHMoQk9MRC5tc2l0LklRTXMuZGYkZndobV9hdmcsIGRpZ2l0cyA9IDQpCkJPTEQubXNpdC5JUU1zLmRmJHNucjwtZGlnaXRzKEJPTEQubXNpdC5JUU1zLmRmJHNuciwgZGlnaXRzID0gNCkKQk9MRC5tc2l0LklRTXMuZGYkdHNucjwtZGlnaXRzKEJPTEQubXNpdC5JUU1zLmRmJHRzbnIsIGRpZ2l0cyA9IDQpCkJPTEQubXNpdC5JUU1zLmRmJGdjb3I8LWRpZ2l0cyhCT0xELm1zaXQuSVFNcy5kZiRnY29yLCBkaWdpdHMgPSA0KQpCT0xELm1zaXQuSVFNcy5kZiRTdWJJRDwtYXMuY2hhcmFjdGVyKEJPTEQubXNpdC5JUU1zLmRmJFN1YklEKQpCT0xELm1zaXQuSVFNcy5kZjwtYXMuZGF0YS5mcmFtZShCT0xELm1zaXQuSVFNcy5kZiwgcm93bmFtZXM9RkFMU0UpCkJPTEQubXNpdC5JUU1zLmRmPC1CT0xELm1zaXQuSVFNcy5kZltjb21wbGV0ZS5jYXNlcyhCT0xELm1zaXQuSVFNcy5kZiRTdWJJRCksXQpCT0xELm1zaXQuSVFNcy5kZjwtYXJyYW5nZShCT0xELm1zaXQuSVFNcy5kZiwiRGF0ZSIgKQojIFZpb2xpbiBwbG90cyB3aXRoIGJveCBwbG90cyBpbnNpZGUKIyA6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6OjoKIyBDaGFuZ2UgZmlsbCBjb2xvciBieSBncm91cHM6IGRvc2UKIyBhZGQgYm94cGxvdCB3aXRoIHdoaXRlIGZpbGwgY29sb3JSZXN0LkRGCm15X2NvbXBhcmlzb25zLmRmPC1jb21wYXJlX21lYW5zKHNuciB+IFNlc3Npb24gLCBCT0xELm1zaXQuSVFNcy5kZikKbXlfY29tcGFyaXNvbnMgPC0gbGlzdCggYygiTVIxIiwgIk1SMiIpLAogICAgICAgICAgICAgICAgICAgICAgICBjKCJNUjEiLCAiTVIzIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGMoIk1SMiIsICJNUjMiKQogICAgICAgICAgICAgICAgICAgICAgICkKCgpwbG90LmFub3ZhMTwtZ2d2aW9saW4oQk9MRC5tc2l0LklRTXMuZGYsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiU2Vzc2lvbiIsIHkgPSAic25yIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJTZXNzaW9uIiwgIG5hLnJtPVRSVUUsCiAgICAgICAgICBhZGQgPSAiYm94cGxvdCIsIGFkZC5wYXJhbXMgPSBsaXN0KGZpbGwgPSAid2hpdGUiKSkrCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnMgPSBteV9jb21wYXJpc29ucywgbGFiZWwgPSAicC5zaWduaWYiKSArICMgQWRkIHNpZ25pZmljYW5jZSBsZXZlbHMKICAgICAgICAgIHN0YXRfY29tcGFyZV9tZWFucyhsYWJlbC55ID0gMikgICsKICBnZ3RpdGxlKCJTTlIgYnkgU2Vzc2lvbiIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ncmlnaHQnKQoKIyBWaW9saW4gcGxvdHMgd2l0aCBib3ggcGxvdHMgaW5zaWRlCiMgOjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6CiMgQ2hhbmdlIGZpbGwgY29sb3IgYnkgZ3JvdXBzOiBkb3NlCiMgYWRkIGJveHBsb3Qgd2l0aCB3aGl0ZSBmaWxsIGNvbG9yUmVzdC5ERgpteV9jb21wYXJpc29ucy5kZjwtY29tcGFyZV9tZWFucyhmZF9tZWFuIH4gU2Vzc2lvbiAsIEJPTEQubXNpdC5JUU1zLmRmKQpteV9jb21wYXJpc29ucyA8LSBsaXN0KCBjKCJNUjEiLCAiTVIyIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGMoIk1SMSIsICJNUjMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgYygiTVIyIiwgIk1SMyIpCiAgICAgICAgICAgICAgICAgICAgICAgKQoKCnBsb3QuYW5vdmEyPC1nZ3Zpb2xpbihCT0xELm1zaXQuSVFNcy5kZiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICJTZXNzaW9uIiwgeSA9ICJmZF9tZWFuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJTZXNzaW9uIiwgIG5hLnJtPVRSVUUsCiAgICAgICAgICBhZGQgPSAiYm94cGxvdCIsIGFkZC5wYXJhbXMgPSBsaXN0KGZpbGwgPSAid2hpdGUiKSkrCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnMgPSBteV9jb21wYXJpc29ucywgbGFiZWwgPSAicC5zaWduaWYiKSArICMgQWRkIHNpZ25pZmljYW5jZSBsZXZlbHMKICAgICAgICAgIHN0YXRfY29tcGFyZV9tZWFucyhsYWJlbC55ID0gMikgICsKICBnZ3RpdGxlKCJmZF9tZWFuIGJ5IFNlc3Npb24iKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249J3JpZ2h0JykKCnBsb3QuYW5vdmEzPC1nZ3Zpb2xpbihCT0xELm1zaXQuSVFNcy5kZiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICJTZXNzaW9uIiwgeSA9ICJ0c25yIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJTZXNzaW9uIiwgIG5hLnJtPVRSVUUsCiAgICAgICAgICBhZGQgPSAiYm94cGxvdCIsIGFkZC5wYXJhbXMgPSBsaXN0KGZpbGwgPSAid2hpdGUiKSkrCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnMgPSBteV9jb21wYXJpc29ucywgbGFiZWwgPSAicC5zaWduaWYiKSArICMgQWRkIHNpZ25pZmljYW5jZSBsZXZlbHMKICAgICAgICAgIHN0YXRfY29tcGFyZV9tZWFucyhsYWJlbC55ID0gMikgICsKICBnZ3RpdGxlKCJ0c25yIGJ5IFNlc3Npb24iKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249J3JpZ2h0JykKCgpncmlkRXh0cmE6OmdyaWQuYXJyYW5nZShwbG90LmFub3ZhMSwgcGxvdC5hbm92YTIscGxvdC5hbm92YTMsIG5jb2w9MykKCmBgYAo8YnIvPgo8YnIvPgoKIyMgU3Ryb29wIFN0cmVzcyBUYXNrCmBgYHtyIFN0cm9vcCBDVVJSRU5UIFJFUE9SVCwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZmlnLndpZHRoID0gMTIsICAgIG91dC53aWR0aCA9ICIxMmluIn0KQk9MRC5zdHJvb3AuSVFNcy5kZjwtZUJBQ0hfQk9MRApCT0xELnN0cm9vcC5JUU1zLmRmPC1CT0xELnN0cm9vcC5JUU1zLmRmW0JPTEQuc3Ryb29wLklRTXMuZGYkVGFzaz09InN0cm9vcCIsXQpCT0xELnN0cm9vcC5JUU1zLmRmPC1CT0xELnN0cm9vcC5JUU1zLmRmW2NvbXBsZXRlLmNhc2VzKEJPTEQuc3Ryb29wLklRTXMuZGYkU3ViSUQpLF0KQk9MRC5zdHJvb3AuSVFNcy5kZjwtQk9MRC5lbW9yZWFwLklRTXMuZGZbY29tcGxldGUuY2FzZXMoQk9MRC5zdHJvb3AuSVFNcy5kZiRkdmFyc19uc3RkKSxdCkJPTEQuc3Ryb29wLklRTXMuZGYkZHZhcnNfbnN0ZDwtZGlnaXRzKEJPTEQuc3Ryb29wLklRTXMuZGYkZHZhcnNfbnN0ZCwgZGlnaXRzID0gNCkKQk9MRC5zdHJvb3AuSVFNcy5kZiRmZF9tZWFuPC1kaWdpdHMoQk9MRC5zdHJvb3AuSVFNcy5kZiRmZF9tZWFuLCBkaWdpdHMgPSA0KQpCT0xELnN0cm9vcC5JUU1zLmRmJGZ3aG1fYXZnPC1kaWdpdHMoQk9MRC5zdHJvb3AuSVFNcy5kZiRmd2htX2F2ZywgZGlnaXRzID0gNCkKQk9MRC5zdHJvb3AuSVFNcy5kZiRzbnI8LWRpZ2l0cyhCT0xELnN0cm9vcC5JUU1zLmRmJHNuciwgZGlnaXRzID0gNCkKQk9MRC5zdHJvb3AuSVFNcy5kZiR0c25yPC1kaWdpdHMoQk9MRC5zdHJvb3AuSVFNcy5kZiR0c25yLCBkaWdpdHMgPSA0KQpCT0xELnN0cm9vcC5JUU1zLmRmJGdjb3I8LWRpZ2l0cyhCT0xELnN0cm9vcC5JUU1zLmRmJGdjb3IsIGRpZ2l0cyA9IDQpCkJPTEQuc3Ryb29wLklRTXMuZGY8LWFzLmRhdGEuZnJhbWUoQk9MRC5zdHJvb3AuSVFNcy5kZiwgcm93bmFtZXM9RkFMU0UpCkJPTEQuc3Ryb29wLklRTXMuZGY8LWFycmFuZ2UoQk9MRC5zdHJvb3AuSVFNcy5kZiwiRGF0ZSIgKQoKVE1QMzwtQk9MRC5zdHJvb3AuSVFNcy5kZiAlPiUgc2VsZWN0KFN1YklELCBTZXNzaW9uLERhdGUsIFJlcG9ydCxkdmFyc19uc3RkICxmZF9tZWFuLCBzbnIsdHNucikKVE1QMzwtcmVzaGFwZTI6Om1lbHQoVE1QMywgaWQudmFycz1jKCJTdWJJRCIsIlNlc3Npb24iICwiRGF0ZSIsICJSZXBvcnQiKSkKIyBzZWxlY3QgcGFydCBvZiB0aGUgZGF0YXNldCBhbmQgdXNlIGl0IGZvciBwbG90dGluZwpnZ3N0YXRzcGxvdDo6Z3JvdXBlZF9nZ2JldHdlZW5zdGF0cygKICAgIGRhdGEgPSBUTVAzLAogICAgeD1SZXBvcnQsCiAgICB5ID0gdmFsdWUsCiAgICBncm91cGluZy52YXIgPSB2YXJpYWJsZSwKIHBsb3QudHlwZSA9ICJ2aW9saW4iLAogICAgdHlwZSA9ICJucCIsCiAgICBjb25mLmxldmVsID0gMC45OSwKICAgIHhsYWIgPSAicmVwb3J0IiwKICAgIHlsYWIgPSAidmFsdWUiLAogICBnZ3RoZW1lID0gZ2dwbG90Mjo6dGhlbWVfZ3JheSgpLCAjIGEgZGlmZmVyZW50IHRoZW1lCiAgcGFja2FnZSA9ICJ5YXJyciIsICMgcGFja2FnZSBmcm9tIHdoaWNoIGNvbG9yIHBhbGV0dGUgaXMgdG8gYmUgdGFrZW4KICBwYWxldHRlID0gImluZm8yIiwgIyBjaG9vc2luZyBhIGRpZmZlcmVudCBjb2xvciBwYWxldHRlCiAgICBvdXRsaWVyLnRhZ2dpbmcgPSBUUlVFLAogICAgb3V0bGllci5sYWJlbC5hcmdzID0gbGlzdChjb2xvciA9ICJyZWQiKSwgIyBvdXRsaWVyIHBvaW50IGxhYmVsIGNvbG9yCiAgICB0aXRsZS5zaXplID0gMTIsCiAgICBnZ3N0YXRzcGxvdC5sYXllciA9IEZBTFNFLAogICAgb3V0bGllci5sYWJlbCA9ICJTdWJJRCIsCiAgICAjIGFyZ3VtZW50cyByZWxldmFudCBmb3IgZ2dzdGF0c3Bsb3Q6OmNvbWJpbmVfcGxvdHMKICAgIHRpdGxlLnRleHQgPSAiV2Vla2x5IFJlc3RpbmcgU3RhdGUgSVFNcy5kZiBJUU0gUmVwb3J0IiwKIHN1Yi5zaXplID0gMywKIGdyZWVkeT1UUlVFLAogcGFpcndpc2UuY29tcGFyaXNvbnMgPSBUUlVFLCAjIGRpc3BsYXkgcmVzdWx0cyBmcm9tIHBhaXJ3aXNlIGNvbXBhcmlzb25zCiAgICBwYWlyd2lzZS5kaXNwbGF5ID0gInNpZ25pZmljYW50IiwgIyBkaXNwbGF5IG9ubHkgc2lnbmlmaWNhbnQgcGFpcndpc2UgY29tcGFyaXNvbnMKIHN0YXRzLmxhYmVsLmFyZ3MgPSBsaXN0KHNpemUgPSAyLCBkaXJlY3Rpb24gPSAieSIpKQoKYGBgCgpgYGB7ciBTdHJvb3AsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0UsICAgIGZpZy53aWR0aCA9IDEyLCAgICBvdXQud2lkdGggPSAiMTJpbiJ9CkJPTEQuc3Ryb29wLklRTXMuZGY8LWVCQUNIX0JPTEQKQk9MRC5zdHJvb3AuSVFNcy5kZjwtQk9MRC5zdHJvb3AuSVFNcy5kZltCT0xELnN0cm9vcC5JUU1zLmRmJFRhc2s9PSJzdHJvb3AiLF0KQk9MRC5zdHJvb3AuSVFNcy5kZjwtQk9MRC5zdHJvb3AuSVFNcy5kZltjb21wbGV0ZS5jYXNlcyhCT0xELnN0cm9vcC5JUU1zLmRmJFN1YklEKSxdCkJPTEQuc3Ryb29wLklRTXMuZGY8LUJPTEQuZW1vcmVhcC5JUU1zLmRmW2NvbXBsZXRlLmNhc2VzKEJPTEQuc3Ryb29wLklRTXMuZGYkZHZhcnNfbnN0ZCksXQpCT0xELnN0cm9vcC5JUU1zLmRmJGR2YXJzX25zdGQ8LWRpZ2l0cyhCT0xELnN0cm9vcC5JUU1zLmRmJGR2YXJzX25zdGQsIGRpZ2l0cyA9IDQpCkJPTEQuc3Ryb29wLklRTXMuZGYkZmRfbWVhbjwtZGlnaXRzKEJPTEQuc3Ryb29wLklRTXMuZGYkZmRfbWVhbiwgZGlnaXRzID0gNCkKQk9MRC5zdHJvb3AuSVFNcy5kZiRmd2htX2F2ZzwtZGlnaXRzKEJPTEQuc3Ryb29wLklRTXMuZGYkZndobV9hdmcsIGRpZ2l0cyA9IDQpCkJPTEQuc3Ryb29wLklRTXMuZGYkc25yPC1kaWdpdHMoQk9MRC5zdHJvb3AuSVFNcy5kZiRzbnIsIGRpZ2l0cyA9IDQpCkJPTEQuc3Ryb29wLklRTXMuZGYkdHNucjwtZGlnaXRzKEJPTEQuc3Ryb29wLklRTXMuZGYkdHNuciwgZGlnaXRzID0gNCkKQk9MRC5zdHJvb3AuSVFNcy5kZiRnY29yPC1kaWdpdHMoQk9MRC5zdHJvb3AuSVFNcy5kZiRnY29yLCBkaWdpdHMgPSA0KQpCT0xELnN0cm9vcC5JUU1zLmRmPC1hcy5kYXRhLmZyYW1lKEJPTEQuc3Ryb29wLklRTXMuZGYsIHJvd25hbWVzPUZBTFNFKQpCT0xELnN0cm9vcC5JUU1zLmRmPC1hcnJhbmdlKEJPTEQuc3Ryb29wLklRTXMuZGYsIkRhdGUiICkKCiMgVmlvbGluIHBsb3RzIHdpdGggYm94IHBsb3RzIGluc2lkZQojIDo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6OgojIENoYW5nZSBmaWxsIGNvbG9yIGJ5IGdyb3VwczogZG9zZQojIGFkZCBib3hwbG90IHdpdGggd2hpdGUgZmlsbCBjb2xvclJlc3QuREYKbXlfY29tcGFyaXNvbnMuZGY8LWNvbXBhcmVfbWVhbnMoc25yIH4gU2Vzc2lvbiAsIEJPTEQuc3Ryb29wLklRTXMuZGYpCm15X2NvbXBhcmlzb25zIDwtIGxpc3QoIGMoIk1SMSIsICJNUjIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgYygiTVIxIiwgIk1SMyIpLAogICAgICAgICAgICAgICAgICAgICAgICBjKCJNUjIiLCAiTVIzIikKICAgICAgICAgICAgICAgICAgICAgICApCgoKcGxvdC5hbm92YTE8LWdndmlvbGluKEJPTEQuc3Ryb29wLklRTXMuZGYsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiU2Vzc2lvbiIsIHkgPSAic25yIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJTZXNzaW9uIiwgIG5hLnJtPVRSVUUsCiAgICAgICAgICBhZGQgPSAiYm94cGxvdCIsIGFkZC5wYXJhbXMgPSBsaXN0KGZpbGwgPSAid2hpdGUiKSkrCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnMgPSBteV9jb21wYXJpc29ucywgbGFiZWwgPSAicC5zaWduaWYiKSArICMgQWRkIHNpZ25pZmljYW5jZSBsZXZlbHMKICAgICAgICAgIHN0YXRfY29tcGFyZV9tZWFucyhsYWJlbC55ID0gMikgICsKICBnZ3RpdGxlKCJTTlIgYnkgU2Vzc2lvbiIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ncmlnaHQnKQoKIyBWaW9saW4gcGxvdHMgd2l0aCBib3ggcGxvdHMgaW5zaWRlCiMgOjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6CiMgQ2hhbmdlIGZpbGwgY29sb3IgYnkgZ3JvdXBzOiBkb3NlCiMgYWRkIGJveHBsb3Qgd2l0aCB3aGl0ZSBmaWxsIGNvbG9yUmVzdC5ERgpteV9jb21wYXJpc29ucy5kZjwtY29tcGFyZV9tZWFucyhmZF9tZWFuIH4gU2Vzc2lvbiAsIEJPTEQuc3Ryb29wLklRTXMuZGYpCm15X2NvbXBhcmlzb25zIDwtIGxpc3QoIGMoIk1SMSIsICJNUjIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgYygiTVIxIiwgIk1SMyIpLAogICAgICAgICAgICAgICAgICAgICAgICBjKCJNUjIiLCAiTVIzIikKICAgICAgICAgICAgICAgICAgICAgICApCgoKcGxvdC5hbm92YTI8LWdndmlvbGluKEJPTEQuc3Ryb29wLklRTXMuZGYsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiU2Vzc2lvbiIsIHkgPSAiZmRfbWVhbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSAiU2Vzc2lvbiIsICBuYS5ybT1UUlVFLAogICAgICAgICAgYWRkID0gImJveHBsb3QiLCBhZGQucGFyYW1zID0gbGlzdChmaWxsID0gIndoaXRlIikpKwogICAgICAgICAgc3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zID0gbXlfY29tcGFyaXNvbnMsIGxhYmVsID0gInAuc2lnbmlmIikgKyAjIEFkZCBzaWduaWZpY2FuY2UgbGV2ZWxzCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMobGFiZWwueSA9IDIpICArCiAgZ2d0aXRsZSgiZmRfbWVhbiBieSBTZXNzaW9uIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSdyaWdodCcpCgpwbG90LmFub3ZhMzwtZ2d2aW9saW4oQk9MRC5zdHJvb3AuSVFNcy5kZiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICJTZXNzaW9uIiwgeSA9ICJ0c25yIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJTZXNzaW9uIiwgIG5hLnJtPVRSVUUsCiAgICAgICAgICBhZGQgPSAiYm94cGxvdCIsIGFkZC5wYXJhbXMgPSBsaXN0KGZpbGwgPSAid2hpdGUiKSkrCiAgICAgICAgICBzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnMgPSBteV9jb21wYXJpc29ucywgbGFiZWwgPSAicC5zaWduaWYiKSArICMgQWRkIHNpZ25pZmljYW5jZSBsZXZlbHMKICAgICAgICAgIHN0YXRfY29tcGFyZV9tZWFucyhsYWJlbC55ID0gMikgICsKICBnZ3RpdGxlKCJ0c25yIGJ5IFNlc3Npb24iKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249J3JpZ2h0JykKCgpncmlkRXh0cmE6OmdyaWQuYXJyYW5nZShwbG90LmFub3ZhMSwgcGxvdC5hbm92YTIscGxvdC5hbm92YTMsIG5jb2w9MykKCmBgYApgYGB7ciBibGFuaywgfQpgYGA=