Load data

data = read.csv('data.csv')
data$Resampling9ms.Axel = as.numeric(data$Resampling9ms.Axel)
Error in `$<-.data.frame`(`*tmp*`, Resampling9ms.Axel, value = numeric(0)) : 
  replacement has 0 rows, data has 24
data2 = read.csv('dataComparisonPixel3and4.csv')
data2$Resampling9ms.Axel = as.numeric(data2$Resampling9ms.Axel)
data2$Resampling10ms.Axel = as.numeric(data2$Resampling10ms.Axel)
data_aggr2 = data2 %>% group_by(freq) %>%
                     summarize(Baseline.AxelM = mean(Baseline.Axel), ciBaseline.Axel.lower = ci(Baseline.Axel)["CI lower"], ciBaseline.Axel.upper = ci(Baseline.Axel)["CI upper"],
                               Resampling0ms.AxelM = mean(Resampling0ms.Axel), ciResampling0ms.Axel.lower = ci(Resampling0ms.Axel)["CI lower"], ciResampling0ms.Axel.upper = ci(Resampling0ms.Axel)["CI upper"],
                               Resampling1ms.AxelM = mean(Resampling1ms.Axel), ciResampling1ms.Axel.lower = ci(Resampling1ms.Axel)["CI lower"], ciResampling1ms.Axel.upper = ci(Resampling1ms.Axel)["CI upper"],
                               Resampling2ms.AxelM = mean(Resampling2ms.Axel), ciResampling2ms.Axel.lower = ci(Resampling2ms.Axel)["CI lower"], ciResampling2ms.Axel.upper = ci(Resampling2ms.Axel)["CI upper"],
                               Resampling3ms.AxelM = mean(Resampling3ms.Axel), ciResampling3ms.Axel.lower = ci(Resampling3ms.Axel)["CI lower"], ciResampling3ms.Axel.upper = ci(Resampling3ms.Axel)["CI upper"],
                               Resampling4ms.AxelM = mean(Resampling4ms.Axel), ciResampling4ms.Axel.lower = ci(Resampling4ms.Axel)["CI lower"], ciResampling4ms.Axel.upper = ci(Resampling4ms.Axel)["CI upper"],
                               Resampling5ms.AxelM = mean(Resampling5ms.Axel), ciResampling5ms.Axel.lower = ci(Resampling5ms.Axel)["CI lower"], ciResampling5ms.Axel.upper = ci(Resampling5ms.Axel)["CI upper"],
                               Resampling6ms.AxelM = mean(Resampling6ms.Axel), ciResampling6ms.Axel.lower = ci(Resampling6ms.Axel)["CI lower"], ciResampling6ms.Axel.upper = ci(Resampling6ms.Axel)["CI upper"],
                               Resampling7ms.AxelM = mean(Resampling7ms.Axel), ciResampling7ms.Axel.lower = ci(Resampling7ms.Axel)["CI lower"], ciResampling7ms.Axel.upper = ci(Resampling7ms.Axel)["CI upper"],
                               Resampling8ms.AxelM = mean(Resampling8ms.Axel), ciResampling8ms.Axel.lower = ci(Resampling8ms.Axel)["CI lower"], ciResampling8ms.Axel.upper = ci(Resampling8ms.Axel)["CI upper"],
                               Resampling9ms.AxelM = mean(Resampling9ms.Axel), ciResampling9ms.Axel.lower = ci(Resampling9ms.Axel)["CI lower"], ciResampling9ms.Axel.upper = ci(Resampling9ms.Axel)["CI upper"],
                               Resampling10ms.AxelM = mean(Resampling10ms.Axel), ciResampling10ms.Axel.lower = ci(Resampling10ms.Axel)["CI lower"], ciResampling10ms.Axel.upper = ci(Resampling10ms.Axel)["CI upper"],
                               .groups = 'drop'
                               )

Impact of the display rate on the spatial jitter (Figure 7)

t <- list(
  family = "sans serif",
  size = 20,
  color = 'black')

t2 <- list(
  family = "sans serif",
  size = 30,
  color = 'black')

p <- plot_ly(data = data_aggr, type = "scatter", mode = 'lines+markers', x = ~freq, y = ~Baseline.AxelM, name = 'Simulated',
             error_y = list(symmetric=F, array=~ciBaseline.Axel.upper-Baseline.AxelM, arrayminus=~Baseline.AxelM-ciBaseline.Axel.lower, color = '#000000')) %>%

             add_trace(data = data_aggr2, y=~Baseline.AxelM, name = 'Real',
                       error_y = list(symmetric=F, array=~ciBaseline.Axel.upper-Baseline.AxelM, arrayminus=~Baseline.AxelM-ciBaseline.Axel.lower, color = '#000000')) %>%  
        
             layout(yaxis = list(title = "Spatial jitter (pixels)", range = c(0,35)),
                    xaxis = list(title = 'Output frequency (Hz)', type = "category"),
                    legend = list(x = 0.8, y = 0.95, bordercolor = "#000", borderwidth=2), 
                    font = t, title = list(font = t2)
                    )

p

orca(p, "ImpactOfTheDisplayRateOnJitter.pdf")

-

\

|

/

-

\

|

/

-

\

|

 
htmlwidgets::saveWidget(p, file = 'ImpactOfTheDisplayRateOnJitter.html')

Plot Linear resampling - jitter (Figure 8)


p <- plot_ly(data = data_aggr, type = "scatter", mode = 'lines+markers', x = ~freq, y = ~Baseline.AxelM, name = 'Baseline',
             error_y = list(symmetric=F, array=~ciBaseline.Axel.upper-Baseline.AxelM, arrayminus=~Baseline.AxelM-ciBaseline.Axel.lower, color = '#000000')) %>%
  
             add_trace(data = data_aggr, y=~Resampling0ms.AxelM, name = '0 ms',
                       error_y = list(symmetric=F, array=~ciResampling0ms.Axel.upper-Resampling0ms.AxelM, arrayminus=~Resampling0ms.AxelM-ciResampling0ms.Axel.lower, color = '#000000')) %>%
             add_trace(data = data_aggr, y=~Resampling1ms.AxelM, name = '1 ms',
                       error_y = list(symmetric=F, array=~ciResampling1ms.Axel.upper-Resampling1ms.AxelM, arrayminus=~Resampling1ms.AxelM-ciResampling1ms.Axel.lower, color = '#000000')) %>%  
             add_trace(data = data_aggr, y=~Resampling2ms.AxelM, name = '2 ms',
                       error_y = list(symmetric=F, array=~ciResampling2ms.Axel.upper-Resampling2ms.AxelM, arrayminus=~Resampling2ms.AxelM-ciResampling2ms.Axel.lower, color = '#000000')) %>%  
             add_trace(data = data_aggr, y=~Resampling3ms.AxelM, name = '3 ms',
                       error_y = list(symmetric=F, array=~ciResampling3ms.Axel.upper-Resampling3ms.AxelM, arrayminus=~Resampling3ms.AxelM-ciResampling3ms.Axel.lower, color = '#000000')) %>%  
             add_trace(data = data_aggr, y=~Resampling4ms.AxelM, name = '4 ms',
                       error_y = list(symmetric=F, array=~ciResampling4ms.Axel.upper-Resampling4ms.AxelM, arrayminus=~Resampling4ms.AxelM-ciResampling4ms.Axel.lower, color = '#000000')) %>%  
             add_trace(data = data_aggr, y=~Resampling5ms.AxelM, name = '5 ms',
                       error_y = list(symmetric=F, array=~ciResampling5ms.Axel.upper-Resampling5ms.AxelM, arrayminus=~Resampling5ms.AxelM-ciResampling5ms.Axel.lower, color = '#000000')) %>%  
             add_trace(data = data_aggr, y=~Resampling6ms.AxelM, name = '6 ms',
                       error_y = list(symmetric=F, array=~ciResampling6ms.Axel.upper-Resampling6ms.AxelM, arrayminus=~Resampling6ms.AxelM-ciResampling6ms.Axel.lower, color = '#000000')) %>%  
             add_trace(data = data_aggr, y=~Resampling7ms.AxelM, name = '7 ms',
                       error_y = list(symmetric=F, array=~ciResampling7ms.Axel.upper-Resampling7ms.AxelM, arrayminus=~Resampling7ms.AxelM-ciResampling7ms.Axel.lower, color = '#000000')) %>%  
             add_trace(data = data_aggr, y=~Resampling8ms.AxelM, name = '8 ms',
                       error_y = list(symmetric=F, array=~ciResampling8ms.Axel.upper-Resampling8ms.AxelM, arrayminus=~Resampling8ms.AxelM-ciResampling8ms.Axel.lower, color = '#000000')) %>%  
             add_trace(data = data_aggr, y=~Resampling9ms.AxelM, name = '9 ms',
                       error_y = list(symmetric=F, array=~ciResampling9ms.Axel.upper-Resampling9ms.AxelM, arrayminus=~Resampling9ms.AxelM-ciResampling9ms.Axel.lower, color = '#000000')) %>%  
             add_trace(data = data_aggr, y=~Resampling10ms.AxelM, name = '10 ms', line=list(color='#2C5A39'), marker=list(color='#2C5A39'),
                       error_y = list(symmetric=F, array=~ciResampling10ms.Axel.upper-Resampling10ms.AxelM, arrayminus=~Resampling10ms.AxelM-ciResampling10ms.Axel.lower, color = '#000000')) %>%    

             layout(yaxis = list(title = "Spatial jitter (pixels)", range = c(0,35)),
                    xaxis = list(title = 'Output frequency (Hz)', type = "category"),
                    legend = list(x = 1, y = 0.95, bordercolor = "#000", borderwidth=2), 
                    font = t, titlefont = t2
                    )


p
The titlefont attribute is deprecated. Use title = list(font = ...) instead.The titlefont attribute is deprecated. Use title = list(font = ...) instead.

orca(p, "LinearResamplingJitterVSfreq.pdf")
The titlefont attribute is deprecated. Use title = list(font = ...) instead.

-

\

|

/

-

\

|

/

-

\

|

 
#htmlwidgets::saveWidget(p, file = 'JitterByfrequencyAxel.html')

Plot jitter latency tradeoff - linear resampling (Figure 9)

`summarise()` regrouping output by 'freq' (override with `.groups` argument)
data_aggrBaseline = data_aggr5 %>% filter(technique == 'Baseline')
  
data_aggr7 = py$df
The working directory was changed to /Users/casiez inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
data_aggrLatency = data_aggr7 %>% select(-JitterScore) %>% spread(technique, timeToFrame)
data_aggrJitter = data_aggr7 %>% select(-timeToFrame) %>% spread(technique, JitterScore)
t <- list(
  family = "sans serif",
  size = 15,
  color = 'black')
t2 <- list(
  family = "sans serif",
  size = 30,
  color = 'black')
symbols = c('circle', 'triangle-up', 'square', 'cross', 'diamond', 'star-triangle-down', 'hourglass', 'star', 'bowtie', 'x')
# p <- plot_ly(data = data_aggr6, type = "scatter", mode = 'markers', x = ~timeToFrame, y = ~JitterScore, symbol = ~technique, sort = FALSE) %>%
p <- plot_ly(type = "scatter", symbols = symbols, mode = 'markers', symbol = data_aggrLatency$freq, marker = list(size = 9, line = list(color = 'rgb(50,50,50)',width = 1))) %>%
  
    # Comment this line to disable Frequencies legend
    add_trace(x = data_aggrLatency$Baseline, y = data_aggrJitter$Baseline, name = paste0(data_aggrLatency$freq," Hz"), marker = list(color = 'rgba(0,0,0,0.5)'), legendgroup = "freq") %>%
    
    add_trace(x = data_aggrLatency$Baseline, y = data_aggrJitter$Baseline, mode = 'markers', name = 'Baseline', marker = list(color = 'rgb(0,0,0)'),legendgroup = "lat") %>%
    #add_trace(x = data_aggrLatency$OE, y=data_aggrJitter$OE, name = '1€ filter', marker = list(color = 'rgb(255,255,255)'),legendgroup = "lat") %>%
    #add_trace(x = data_aggrLatency$OE, y=data_aggrJitter$OE, name = 'MA.Gery', marker = list(color = 'rgb(255,255,255)'),legendgroup = "lat") %>%
    add_trace(x = data_aggrLatency$MA, y=data_aggrJitter$MA, name = 'MA', marker = list(color = 'rgb(255,255,255)'),legendgroup = "lat") %>%
    add_trace(x = data_aggrLatency$Resampling0ms, y=data_aggrJitter$Resampling0ms, name = '0 ms', marker = list(color = 'rgb(69,117,180)'),legendgroup = "lat") %>%
    add_trace(x = data_aggrLatency$Resampling2ms, y=data_aggrJitter$Resampling2ms, name = '2 ms', marker = list(color = 'rgb(215,48,39)'),legendgroup = "lat") %>%
    add_trace(x = data_aggrLatency$Resampling4ms, y=data_aggrJitter$Resampling4ms, name = '4 ms', marker = list(color = 'rgb(252,141,89)'),legendgroup = "lat") %>%
    add_trace(x = data_aggrLatency$Resampling6ms, y=data_aggrJitter$Resampling6ms, name = '6 ms', marker = list(color = 'rgb(255,255,191)'),legendgroup = "lat") %>%
    add_trace(x = data_aggrLatency$Resampling8ms, y=data_aggrJitter$Resampling8ms, name = '8 ms', marker = list(color = 'rgb(145,207,96)'),legendgroup = "lat") %>%
    add_trace(x = data_aggrLatency$Resampling10ms, y=data_aggrJitter$Resampling10ms, name = '10 ms', marker = list(color = 'rgb(26,152,80)'),legendgroup = "lat") %>%
  
    layout(yaxis = list(title = "Spatial jitter (pixels)"),
          xaxis = list(title = 'Latency compared to baseline (ms)'),
          legend = list(x = 1, y = 0.5, bordercolor = "#000", borderwidth=2, orientation = 'v', font = t, titlefont = t2
          ))
p
The shape palette can deal with a maximum of 6 discrete values because more than 6 becomes difficult to discriminate; you have 10. Consider specifying shapes manually if you must have them.The shape palette can deal with a maximum of 6 discrete values because more than 6 becomes difficult to discriminate; you have 10. Consider specifying shapes manually if you must have them.

orca(p, "JitterLatencyTradeoffComparedToBaseline.pdf")
The shape palette can deal with a maximum of 6 discrete values because more than 6 becomes difficult to discriminate; you have 10. Consider specifying shapes manually if you must have them.

-

\

|

/

-

\

|

/

-

\

|

 
#htmlwidgets::saveWidget(p, file = 'ImpactOfTheDisplayRateOnJitter.html')

Test of other extrapolation techniques

Linear predictor

data = read.csv('dataLinear.csv')
data$Resampling9ms.Axel = as.numeric(data$Resampling9ms.Axel)
data$Resampling10ms.Axel = as.numeric(data$Resampling10ms.Axel)
data_aggrLinear = data %>% group_by(freq) %>%
                     summarize(Baseline.AxelM = mean(Baseline.Axel), ciBaseline.Axel.lower = ci(Baseline.Axel)["CI lower"], ciBaseline.Axel.upper = ci(Baseline.Axel)["CI upper"],
                               Resampling0ms.AxelM = mean(Resampling0ms.Axel), ciResampling0ms.Axel.lower = ci(Resampling0ms.Axel)["CI lower"], ciResampling0ms.Axel.upper = ci(Resampling0ms.Axel)["CI upper"],
                               OE.AxelM = mean(OE.Axel), ciOE.Axel.lower = ci(OE.Axel)["CI lower"], ciOE.Axel.upper = ci(OE.Axel)["CI upper"],
                               Resampling1ms.AxelM = mean(Resampling1ms.Axel), ciResampling1ms.Axel.lower = ci(Resampling1ms.Axel)["CI lower"], ciResampling1ms.Axel.upper = ci(Resampling1ms.Axel)["CI upper"],
                               Resampling2ms.AxelM = mean(Resampling2ms.Axel), ciResampling2ms.Axel.lower = ci(Resampling2ms.Axel)["CI lower"], ciResampling2ms.Axel.upper = ci(Resampling2ms.Axel)["CI upper"],
                               Resampling3ms.AxelM = mean(Resampling3ms.Axel), ciResampling3ms.Axel.lower = ci(Resampling3ms.Axel)["CI lower"], ciResampling3ms.Axel.upper = ci(Resampling3ms.Axel)["CI upper"],
                               Resampling4ms.AxelM = mean(Resampling4ms.Axel), ciResampling4ms.Axel.lower = ci(Resampling4ms.Axel)["CI lower"], ciResampling4ms.Axel.upper = ci(Resampling4ms.Axel)["CI upper"],
                               Resampling5ms.AxelM = mean(Resampling5ms.Axel), ciResampling5ms.Axel.lower = ci(Resampling5ms.Axel)["CI lower"], ciResampling5ms.Axel.upper = ci(Resampling5ms.Axel)["CI upper"],
                               Resampling6ms.AxelM = mean(Resampling6ms.Axel), ciResampling6ms.Axel.lower = ci(Resampling6ms.Axel)["CI lower"], ciResampling6ms.Axel.upper = ci(Resampling6ms.Axel)["CI upper"],
                               Resampling7ms.AxelM = mean(Resampling7ms.Axel), ciResampling7ms.Axel.lower = ci(Resampling7ms.Axel)["CI lower"], ciResampling7ms.Axel.upper = ci(Resampling7ms.Axel)["CI upper"],
                               Resampling8ms.AxelM = mean(Resampling8ms.Axel), ciResampling8ms.Axel.lower = ci(Resampling8ms.Axel)["CI lower"], ciResampling8ms.Axel.upper = ci(Resampling8ms.Axel)["CI upper"],
                               Resampling9ms.AxelM = mean(Resampling9ms.Axel), ciResampling9ms.Axel.lower = ci(Resampling9ms.Axel)["CI lower"], ciResampling9ms.Axel.upper = ci(Resampling9ms.Axel)["CI upper"],
                               Resampling10ms.AxelM = mean(Resampling10ms.Axel), ciResampling10ms.Axel.lower = ci(Resampling10ms.Axel)["CI lower"], ciResampling10ms.Axel.upper = ci(Resampling10ms.Axel)["CI upper"],
                               
                               TimeToFT.baseline.M = mean(timeToFT.baseline), TimeToTF.baseline.ci.lower = ci(timeToFT.baseline)["CI lower"], TimeToTF.baseline.ci.upper = ci(timeToFT.baseline)["CI upper"],
                               TimeToFT.OE.M = mean(timeToFT.OE), TimeToFT.OE.ci.lower = ci(timeToFT.OE)["CI lower"], TimeToFT.OE.ci.upper = ci(timeToFT.OE)["CI upper"],
                               TimeToFT.resamp0ms.M = mean(timeToFT.resamp.delay.0ms), TimeToFT.resamp0ms.ci.lower = ci(timeToFT.resamp.delay.0ms)["CI lower"], TimeToFT.resamp0ms.ci.upper = ci(timeToFT.resamp.delay.0ms)["CI upper"],
                               TimeToFT.resamp1ms.M = mean(timeToFT.resamp.delay.1ms), TimeToFT.resamp1ms.ci.lower = ci(timeToFT.resamp.delay.1ms)["CI lower"], TimeToFT.resamp1ms.ci.upper = ci(timeToFT.resamp.delay.1ms)["CI upper"],
                               TimeToFT.resamp2ms.M = mean(timeToFT.resamp.delay.2ms), TimeToFT.resamp2ms.ci.lower = ci(timeToFT.resamp.delay.2ms)["CI lower"], TimeToFT.resamp2ms.ci.upper = ci(timeToFT.resamp.delay.2ms)["CI upper"],
                               TimeToFT.resamp3ms.M = mean(timeToFT.resamp.delay.3ms), TimeToFT.resamp3ms.ci.lower = ci(timeToFT.resamp.delay.3ms)["CI lower"], TimeToFT.resamp3ms.ci.upper = ci(timeToFT.resamp.delay.3ms)["CI upper"],
                               TimeToFT.resamp4ms.M = mean(timeToFT.resamp.delay.4ms), TimeToFT.resamp4ms.ci.lower = ci(timeToFT.resamp.delay.4ms)["CI lower"], TimeToFT.resamp4ms.ci.upper = ci(timeToFT.resamp.delay.4ms)["CI upper"],
                               TimeToFT.resamp5ms.M = mean(timeToFT.resamp.delay.5ms), TimeToFT.resamp5ms.ci.lower = ci(timeToFT.resamp.delay.5ms)["CI lower"], TimeToFT.resamp5ms.ci.upper = ci(timeToFT.resamp.delay.5ms)["CI upper"],
                               TimeToFT.resamp6ms.M = mean(timeToFT.resamp.delay.6ms), TimeToFT.resamp6ms.ci.lower = ci(timeToFT.resamp.delay.6ms)["CI lower"], TimeToFT.resamp6ms.ci.upper = ci(timeToFT.resamp.delay.6ms)["CI upper"],
                               TimeToFT.resamp7ms.M = mean(timeToFT.resamp.delay.7ms), TimeToFT.resamp7ms.ci.lower = ci(timeToFT.resamp.delay.7ms)["CI lower"], TimeToFT.resamp7ms.ci.upper = ci(timeToFT.resamp.delay.7ms)["CI upper"],
                               TimeToFT.resamp8ms.M = mean(timeToFT.resamp.delay.8ms), TimeToFT.resamp8ms.ci.lower = ci(timeToFT.resamp.delay.8ms)["CI lower"], TimeToFT.resamp8ms.ci.upper = ci(timeToFT.resamp.delay.8ms)["CI upper"],
                               TimeToFT.resamp9ms.M = mean(timeToFT.resamp.delay.9ms), TimeToFT.resamp9ms.ci.lower = ci(timeToFT.resamp.delay.9ms)["CI lower"], TimeToFT.resamp9ms.ci.upper = ci(timeToFT.resamp.delay.9ms)["CI upper"],
                               TimeToFT.resamp10ms.M = mean(timeToFT.resamp.delay.10ms), TimeToFT.resamp10ms.ci.lower = ci(timeToFT.resamp.delay.10ms)["CI lower"], TimeToFT.resamp10ms.ci.upper = ci(timeToFT.resamp.delay.10ms)["CI upper"],
                               
                         

                               )
`summarise()` ungrouping output (override with `.groups` argument)

Quadratic predictor

data = read.csv('dataQuadratic.csv')
data$Resampling9ms.Axel = as.numeric(data$Resampling9ms.Axel)
data$Resampling10ms.Axel = as.numeric(data$Resampling10ms.Axel)
data_aggrQuadratic = data %>% group_by(freq) %>%
                     summarize(Baseline.AxelM = mean(Baseline.Axel), ciBaseline.Axel.lower = ci(Baseline.Axel)["CI lower"], ciBaseline.Axel.upper = ci(Baseline.Axel)["CI upper"],
                               Resampling0ms.AxelM = mean(Resampling0ms.Axel), ciResampling0ms.Axel.lower = ci(Resampling0ms.Axel)["CI lower"], ciResampling0ms.Axel.upper = ci(Resampling0ms.Axel)["CI upper"],
                               OE.AxelM = mean(OE.Axel), ciOE.Axel.lower = ci(OE.Axel)["CI lower"], ciOE.Axel.upper = ci(OE.Axel)["CI upper"],
                               Resampling1ms.AxelM = mean(Resampling1ms.Axel), ciResampling1ms.Axel.lower = ci(Resampling1ms.Axel)["CI lower"], ciResampling1ms.Axel.upper = ci(Resampling1ms.Axel)["CI upper"],
                               Resampling2ms.AxelM = mean(Resampling2ms.Axel), ciResampling2ms.Axel.lower = ci(Resampling2ms.Axel)["CI lower"], ciResampling2ms.Axel.upper = ci(Resampling2ms.Axel)["CI upper"],
                               Resampling3ms.AxelM = mean(Resampling3ms.Axel), ciResampling3ms.Axel.lower = ci(Resampling3ms.Axel)["CI lower"], ciResampling3ms.Axel.upper = ci(Resampling3ms.Axel)["CI upper"],
                               Resampling4ms.AxelM = mean(Resampling4ms.Axel), ciResampling4ms.Axel.lower = ci(Resampling4ms.Axel)["CI lower"], ciResampling4ms.Axel.upper = ci(Resampling4ms.Axel)["CI upper"],
                               Resampling5ms.AxelM = mean(Resampling5ms.Axel), ciResampling5ms.Axel.lower = ci(Resampling5ms.Axel)["CI lower"], ciResampling5ms.Axel.upper = ci(Resampling5ms.Axel)["CI upper"],
                               Resampling6ms.AxelM = mean(Resampling6ms.Axel), ciResampling6ms.Axel.lower = ci(Resampling6ms.Axel)["CI lower"], ciResampling6ms.Axel.upper = ci(Resampling6ms.Axel)["CI upper"],
                               Resampling7ms.AxelM = mean(Resampling7ms.Axel), ciResampling7ms.Axel.lower = ci(Resampling7ms.Axel)["CI lower"], ciResampling7ms.Axel.upper = ci(Resampling7ms.Axel)["CI upper"],
                               Resampling8ms.AxelM = mean(Resampling8ms.Axel), ciResampling8ms.Axel.lower = ci(Resampling8ms.Axel)["CI lower"], ciResampling8ms.Axel.upper = ci(Resampling8ms.Axel)["CI upper"],
                               Resampling9ms.AxelM = mean(Resampling9ms.Axel), ciResampling9ms.Axel.lower = ci(Resampling9ms.Axel)["CI lower"], ciResampling9ms.Axel.upper = ci(Resampling9ms.Axel)["CI upper"],
                               Resampling10ms.AxelM = mean(Resampling10ms.Axel), ciResampling10ms.Axel.lower = ci(Resampling10ms.Axel)["CI lower"], ciResampling10ms.Axel.upper = ci(Resampling10ms.Axel)["CI upper"],
                               
                               TimeToFT.baseline.M = mean(timeToFT.baseline), TimeToTF.baseline.ci.lower = ci(timeToFT.baseline)["CI lower"], TimeToTF.baseline.ci.upper = ci(timeToFT.baseline)["CI upper"],
                               TimeToFT.OE.M = mean(timeToFT.OE), TimeToFT.OE.ci.lower = ci(timeToFT.OE)["CI lower"], TimeToFT.OE.ci.upper = ci(timeToFT.OE)["CI upper"],
                               TimeToFT.resamp0ms.M = mean(timeToFT.resamp.delay.0ms), TimeToFT.resamp0ms.ci.lower = ci(timeToFT.resamp.delay.0ms)["CI lower"], TimeToFT.resamp0ms.ci.upper = ci(timeToFT.resamp.delay.0ms)["CI upper"],
                               TimeToFT.resamp1ms.M = mean(timeToFT.resamp.delay.1ms), TimeToFT.resamp1ms.ci.lower = ci(timeToFT.resamp.delay.1ms)["CI lower"], TimeToFT.resamp1ms.ci.upper = ci(timeToFT.resamp.delay.1ms)["CI upper"],
                               TimeToFT.resamp2ms.M = mean(timeToFT.resamp.delay.2ms), TimeToFT.resamp2ms.ci.lower = ci(timeToFT.resamp.delay.2ms)["CI lower"], TimeToFT.resamp2ms.ci.upper = ci(timeToFT.resamp.delay.2ms)["CI upper"],
                               TimeToFT.resamp3ms.M = mean(timeToFT.resamp.delay.3ms), TimeToFT.resamp3ms.ci.lower = ci(timeToFT.resamp.delay.3ms)["CI lower"], TimeToFT.resamp3ms.ci.upper = ci(timeToFT.resamp.delay.3ms)["CI upper"],
                               TimeToFT.resamp4ms.M = mean(timeToFT.resamp.delay.4ms), TimeToFT.resamp4ms.ci.lower = ci(timeToFT.resamp.delay.4ms)["CI lower"], TimeToFT.resamp4ms.ci.upper = ci(timeToFT.resamp.delay.4ms)["CI upper"],
                               TimeToFT.resamp5ms.M = mean(timeToFT.resamp.delay.5ms), TimeToFT.resamp5ms.ci.lower = ci(timeToFT.resamp.delay.5ms)["CI lower"], TimeToFT.resamp5ms.ci.upper = ci(timeToFT.resamp.delay.5ms)["CI upper"],
                               TimeToFT.resamp6ms.M = mean(timeToFT.resamp.delay.6ms), TimeToFT.resamp6ms.ci.lower = ci(timeToFT.resamp.delay.6ms)["CI lower"], TimeToFT.resamp6ms.ci.upper = ci(timeToFT.resamp.delay.6ms)["CI upper"],
                               TimeToFT.resamp7ms.M = mean(timeToFT.resamp.delay.7ms), TimeToFT.resamp7ms.ci.lower = ci(timeToFT.resamp.delay.7ms)["CI lower"], TimeToFT.resamp7ms.ci.upper = ci(timeToFT.resamp.delay.7ms)["CI upper"],
                               TimeToFT.resamp8ms.M = mean(timeToFT.resamp.delay.8ms), TimeToFT.resamp8ms.ci.lower = ci(timeToFT.resamp.delay.8ms)["CI lower"], TimeToFT.resamp8ms.ci.upper = ci(timeToFT.resamp.delay.8ms)["CI upper"],
                               TimeToFT.resamp9ms.M = mean(timeToFT.resamp.delay.9ms), TimeToFT.resamp9ms.ci.lower = ci(timeToFT.resamp.delay.9ms)["CI lower"], TimeToFT.resamp9ms.ci.upper = ci(timeToFT.resamp.delay.9ms)["CI upper"],
                               TimeToFT.resamp10ms.M = mean(timeToFT.resamp.delay.10ms), TimeToFT.resamp10ms.ci.lower = ci(timeToFT.resamp.delay.10ms)["CI lower"], TimeToFT.resamp10ms.ci.upper = ci(timeToFT.resamp.delay.10ms)["CI upper"],
                               

                               )
`summarise()` ungrouping output (override with `.groups` argument)

LaViola predictor

data = read.csv('dataLaViola.csv')
data$Resampling9ms.Axel = as.numeric(data$Resampling9ms.Axel)
data$Resampling10ms.Axel = as.numeric(data$Resampling10ms.Axel)
data_aggrLaViola = data %>% group_by(freq) %>%
                     summarize(Baseline.AxelM = mean(Baseline.Axel), ciBaseline.Axel.lower = ci(Baseline.Axel)["CI lower"], ciBaseline.Axel.upper = ci(Baseline.Axel)["CI upper"],
                               Resampling0ms.AxelM = mean(Resampling0ms.Axel), ciResampling0ms.Axel.lower = ci(Resampling0ms.Axel)["CI lower"], ciResampling0ms.Axel.upper = ci(Resampling0ms.Axel)["CI upper"],
                               OE.AxelM = mean(OE.Axel), ciOE.Axel.lower = ci(OE.Axel)["CI lower"], ciOE.Axel.upper = ci(OE.Axel)["CI upper"],
                               Resampling1ms.AxelM = mean(Resampling1ms.Axel), ciResampling1ms.Axel.lower = ci(Resampling1ms.Axel)["CI lower"], ciResampling1ms.Axel.upper = ci(Resampling1ms.Axel)["CI upper"],
                               Resampling2ms.AxelM = mean(Resampling2ms.Axel), ciResampling2ms.Axel.lower = ci(Resampling2ms.Axel)["CI lower"], ciResampling2ms.Axel.upper = ci(Resampling2ms.Axel)["CI upper"],
                               Resampling3ms.AxelM = mean(Resampling3ms.Axel), ciResampling3ms.Axel.lower = ci(Resampling3ms.Axel)["CI lower"], ciResampling3ms.Axel.upper = ci(Resampling3ms.Axel)["CI upper"],
                               Resampling4ms.AxelM = mean(Resampling4ms.Axel), ciResampling4ms.Axel.lower = ci(Resampling4ms.Axel)["CI lower"], ciResampling4ms.Axel.upper = ci(Resampling4ms.Axel)["CI upper"],
                               Resampling5ms.AxelM = mean(Resampling5ms.Axel), ciResampling5ms.Axel.lower = ci(Resampling5ms.Axel)["CI lower"], ciResampling5ms.Axel.upper = ci(Resampling5ms.Axel)["CI upper"],
                               Resampling6ms.AxelM = mean(Resampling6ms.Axel), ciResampling6ms.Axel.lower = ci(Resampling6ms.Axel)["CI lower"], ciResampling6ms.Axel.upper = ci(Resampling6ms.Axel)["CI upper"],
                               Resampling7ms.AxelM = mean(Resampling7ms.Axel), ciResampling7ms.Axel.lower = ci(Resampling7ms.Axel)["CI lower"], ciResampling7ms.Axel.upper = ci(Resampling7ms.Axel)["CI upper"],
                               Resampling8ms.AxelM = mean(Resampling8ms.Axel), ciResampling8ms.Axel.lower = ci(Resampling8ms.Axel)["CI lower"], ciResampling8ms.Axel.upper = ci(Resampling8ms.Axel)["CI upper"],
                               Resampling9ms.AxelM = mean(Resampling9ms.Axel), ciResampling9ms.Axel.lower = ci(Resampling9ms.Axel)["CI lower"], ciResampling9ms.Axel.upper = ci(Resampling9ms.Axel)["CI upper"],
                               Resampling10ms.AxelM = mean(Resampling10ms.Axel), ciResampling10ms.Axel.lower = ci(Resampling10ms.Axel)["CI lower"], ciResampling10ms.Axel.upper = ci(Resampling10ms.Axel)["CI upper"],
                               
                               TimeToFT.baseline.M = mean(timeToFT.baseline), TimeToTF.baseline.ci.lower = ci(timeToFT.baseline)["CI lower"], TimeToTF.baseline.ci.upper = ci(timeToFT.baseline)["CI upper"],
                               TimeToFT.OE.M = mean(timeToFT.OE), TimeToFT.OE.ci.lower = ci(timeToFT.OE)["CI lower"], TimeToFT.OE.ci.upper = ci(timeToFT.OE)["CI upper"],
                               TimeToFT.resamp0ms.M = mean(timeToFT.resamp.delay.0ms), TimeToFT.resamp0ms.ci.lower = ci(timeToFT.resamp.delay.0ms)["CI lower"], TimeToFT.resamp0ms.ci.upper = ci(timeToFT.resamp.delay.0ms)["CI upper"],
                               TimeToFT.resamp1ms.M = mean(timeToFT.resamp.delay.1ms), TimeToFT.resamp1ms.ci.lower = ci(timeToFT.resamp.delay.1ms)["CI lower"], TimeToFT.resamp1ms.ci.upper = ci(timeToFT.resamp.delay.1ms)["CI upper"],
                               TimeToFT.resamp2ms.M = mean(timeToFT.resamp.delay.2ms), TimeToFT.resamp2ms.ci.lower = ci(timeToFT.resamp.delay.2ms)["CI lower"], TimeToFT.resamp2ms.ci.upper = ci(timeToFT.resamp.delay.2ms)["CI upper"],
                               TimeToFT.resamp3ms.M = mean(timeToFT.resamp.delay.3ms), TimeToFT.resamp3ms.ci.lower = ci(timeToFT.resamp.delay.3ms)["CI lower"], TimeToFT.resamp3ms.ci.upper = ci(timeToFT.resamp.delay.3ms)["CI upper"],
                               TimeToFT.resamp4ms.M = mean(timeToFT.resamp.delay.4ms), TimeToFT.resamp4ms.ci.lower = ci(timeToFT.resamp.delay.4ms)["CI lower"], TimeToFT.resamp4ms.ci.upper = ci(timeToFT.resamp.delay.4ms)["CI upper"],
                               TimeToFT.resamp5ms.M = mean(timeToFT.resamp.delay.5ms), TimeToFT.resamp5ms.ci.lower = ci(timeToFT.resamp.delay.5ms)["CI lower"], TimeToFT.resamp5ms.ci.upper = ci(timeToFT.resamp.delay.5ms)["CI upper"],
                               TimeToFT.resamp6ms.M = mean(timeToFT.resamp.delay.6ms), TimeToFT.resamp6ms.ci.lower = ci(timeToFT.resamp.delay.6ms)["CI lower"], TimeToFT.resamp6ms.ci.upper = ci(timeToFT.resamp.delay.6ms)["CI upper"],
                               TimeToFT.resamp7ms.M = mean(timeToFT.resamp.delay.7ms), TimeToFT.resamp7ms.ci.lower = ci(timeToFT.resamp.delay.7ms)["CI lower"], TimeToFT.resamp7ms.ci.upper = ci(timeToFT.resamp.delay.7ms)["CI upper"],
                               TimeToFT.resamp8ms.M = mean(timeToFT.resamp.delay.8ms), TimeToFT.resamp8ms.ci.lower = ci(timeToFT.resamp.delay.8ms)["CI lower"], TimeToFT.resamp8ms.ci.upper = ci(timeToFT.resamp.delay.8ms)["CI upper"],
                               TimeToFT.resamp9ms.M = mean(timeToFT.resamp.delay.9ms), TimeToFT.resamp9ms.ci.lower = ci(timeToFT.resamp.delay.9ms)["CI lower"], TimeToFT.resamp9ms.ci.upper = ci(timeToFT.resamp.delay.9ms)["CI upper"],
                               TimeToFT.resamp10ms.M = mean(timeToFT.resamp.delay.10ms), TimeToFT.resamp10ms.ci.lower = ci(timeToFT.resamp.delay.10ms)["CI lower"], TimeToFT.resamp10ms.ci.upper = ci(timeToFT.resamp.delay.10ms)["CI upper"],
                               
                      

                               )
`summarise()` ungrouping output (override with `.groups` argument)

Plot Linear resampling - jitter (Figure 10)


p <- plot_ly(data = data_aggrLinear, type = "scatter", mode = 'lines+markers', x = ~freq, y = ~Baseline.AxelM, name = 'Baseline', line=list(color='#FF0000'), marker=list(color='#FF0000'), 
             error_y = list(symmetric=F, array=~ciBaseline.Axel.upper-Baseline.AxelM, arrayminus=~Baseline.AxelM-ciBaseline.Axel.lower, color = '#000000')) %>%
  
             add_trace(data = data_aggrLinear, y=~Resampling0ms.AxelM, name = 'Linear 0 ms', line=list(color='#A63603'), marker=list(color='#A63603'), 
                       error_y = list(symmetric=F, array=~ciResampling0ms.Axel.upper-Resampling0ms.AxelM, arrayminus=~Resampling0ms.AxelM-ciResampling0ms.Axel.lower, color = '#000000')) %>%
             add_trace(data = data_aggrLinear, y=~Resampling2ms.AxelM, name = 'Linear 2 ms', line=list(color='#E6550D'), marker=list(color='#E6550D'), 
                       error_y = list(symmetric=F, array=~ciResampling2ms.Axel.upper-Resampling2ms.AxelM, arrayminus=~Resampling2ms.AxelM-ciResampling2ms.Axel.lower, color = '#000000')) %>%
             add_trace(data = data_aggrLinear, y=~Resampling4ms.AxelM, name = 'Linear 4 ms', line=list(color='#FDBE85'), marker=list(color='#FC8D59'), 
                       error_y = list(symmetric=F, array=~ciResampling4ms.Axel.upper-Resampling4ms.AxelM, arrayminus=~Resampling4ms.AxelM-ciResampling4ms.Axel.lower, color = '#000000')) %>%

             add_trace(data = data_aggrQuadratic, y=~Resampling0ms.AxelM, name = 'Curve 0 ms', line=list(color='#006D2C'), marker=list(color='#006D2C'),
                       error_y = list(symmetric=F, array=~ciResampling0ms.Axel.upper-Resampling0ms.AxelM, arrayminus=~Resampling0ms.AxelM-ciResampling0ms.Axel.lower, color = '#000000')) %>%
             add_trace(data = data_aggrQuadratic, y=~Resampling2ms.AxelM, name = 'Curve 2 ms', line=list(color='#31A354'), marker=list(color='#31A354'),
                       error_y = list(symmetric=F, array=~ciResampling2ms.Axel.upper-Resampling2ms.AxelM, arrayminus=~Resampling2ms.AxelM-ciResampling2ms.Axel.lower, color = '#000000')) %>%
             add_trace(data = data_aggrQuadratic, y=~Resampling4ms.AxelM, name = 'Curve 4 ms', line=list(color='#BAE4B3'), marker=list(color='#BAE4B3'),
                       error_y = list(symmetric=F, array=~ciResampling4ms.Axel.upper-Resampling4ms.AxelM, arrayminus=~Resampling4ms.AxelM-ciResampling4ms.Axel.lower, color = '#000000')) %>%

             add_trace(data = data_aggrLaViola, y=~Resampling0ms.AxelM, name = 'DESP 0 ms', line=list(color='#08519C'), marker=list(color='#08519C'),
                       error_y = list(symmetric=F, array=~ciResampling0ms.Axel.upper-Resampling0ms.AxelM, arrayminus=~Resampling0ms.AxelM-ciResampling0ms.Axel.lower, color = '#000000')) %>%
             add_trace(data = data_aggrLaViola, y=~Resampling2ms.AxelM, name = 'DESP 2 ms', line=list(color='#3182BD'), marker=list(color='#3182BD'),
                       error_y = list(symmetric=F, array=~ciResampling2ms.Axel.upper-Resampling2ms.AxelM, arrayminus=~Resampling2ms.AxelM-ciResampling2ms.Axel.lower, color = '#000000')) %>%
             add_trace(data = data_aggrLaViola, y=~Resampling4ms.AxelM, name = 'DESP 4 ms', line=list(color='#BDD7E7'), marker=list(color='#BDD7E7'),
                       error_y = list(symmetric=F, array=~ciResampling4ms.Axel.upper-Resampling4ms.AxelM, arrayminus=~Resampling4ms.AxelM-ciResampling4ms.Axel.lower, color = '#000000')) %>%
  
             layout(yaxis = list(title = "Spatial jitter (pixels)", range = c(0,35)),
                    xaxis = list(title = 'Output frequency (Hz)', type = "category"),
                    legend = list(x = 1, y = 0.95, bordercolor = "#000", borderwidth=2), 
                    font = t, titlefont = t2
                    )


p
The titlefont attribute is deprecated. Use title = list(font = ...) instead.The titlefont attribute is deprecated. Use title = list(font = ...) instead.

orca(p, "ComparisonPredictors.pdf")
The titlefont attribute is deprecated. Use title = list(font = ...) instead.

-

\

|

/

-

\

|

/

-

\

 
#htmlwidgets::saveWidget(p, file = 'JitterByfrequencyAxel.html')
LS0tCnRpdGxlOiAiTW9kZWxpbmcgYW5kIFJlZHVjaW5nIFNwYXRpYWwgSml0dGVyIGNhdXNlZCBieSBBc3luY2hyb25vdXMgSW5wdXQgYW5kIE91dHB1dCBSYXRlcyIKYXV0aG9yOiAiR8OpcnkgQ2FzaWV6IGFuZCBBeGVsIEFudG9pbmUiCmRhdGU6ICIyMDIwIgo8IS0tb3V0cHV0OiBodG1sX2RvY3VtZW50LS0+Cm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRoZW1lOiBsdW1lbgogICAgaGlnaGxpZ2h0OiB0ZXh0bWF0ZQogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBudW1iZXJfc2VjdGlvbnM6IFRSVUUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShnbW9kZWxzKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkocmV0aWN1bGF0ZSkKYGBgCgoKCiMgTG9hZCBkYXRhCgpgYGB7ciBsb2FkRGF0YSwgd2FybmluZz1GQUxTRX0KZGF0YSA9IHJlYWQuY3N2KCdkYXRhLmNzdicpCmRhdGEkUmVzYW1wbGluZzltcy5BeGVsID0gYXMubnVtZXJpYyhkYXRhJFJlc2FtcGxpbmc5bXMuQXhlbCkKZGF0YSRSZXNhbXBsaW5nMTBtcy5BeGVsID0gYXMubnVtZXJpYyhkYXRhJFJlc2FtcGxpbmcxMG1zLkF4ZWwpCmRhdGFfYWdnciA9IGRhdGEgJT4lIGdyb3VwX2J5KGZyZXEpICU+JQogICAgICAgICAgICAgICAgICAgICBzdW1tYXJpemUoQmFzZWxpbmUuQXhlbE0gPSBtZWFuKEJhc2VsaW5lLkF4ZWwpLCBjaUJhc2VsaW5lLkF4ZWwubG93ZXIgPSBjaShCYXNlbGluZS5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lCYXNlbGluZS5BeGVsLnVwcGVyID0gY2koQmFzZWxpbmUuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nMG1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nMG1zLkF4ZWwpLCBjaVJlc2FtcGxpbmcwbXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmcwbXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzBtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzBtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BLkF4ZWxNID0gbWVhbihNQS5BeGVsKSwgY2lNQS5BeGVsLmxvd2VyID0gY2koTUEuQXhlbClbIkNJIGxvd2VyIl0sIGNpTUEuQXhlbC51cHBlciA9IGNpKE1BLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzFtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzFtcy5BeGVsKSwgY2lSZXNhbXBsaW5nMW1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nMW1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmcxbXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmcxbXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nMm1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nMm1zLkF4ZWwpLCBjaVJlc2FtcGxpbmcybXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmcybXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzJtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzJtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmczbXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmczbXMuQXhlbCksIGNpUmVzYW1wbGluZzNtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzNtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nM21zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nM21zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzRtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzRtcy5BeGVsKSwgY2lSZXNhbXBsaW5nNG1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nNG1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmc0bXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmc0bXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nNW1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nNW1zLkF4ZWwpLCBjaVJlc2FtcGxpbmc1bXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmc1bXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzVtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzVtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmc2bXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmc2bXMuQXhlbCksIGNpUmVzYW1wbGluZzZtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzZtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nNm1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nNm1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzdtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzdtcy5BeGVsKSwgY2lSZXNhbXBsaW5nN21zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nN21zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmc3bXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmc3bXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nOG1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nOG1zLkF4ZWwpLCBjaVJlc2FtcGxpbmc4bXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmc4bXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzhtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzhtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmc5bXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmc5bXMuQXhlbCksIGNpUmVzYW1wbGluZzltcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzltcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nOW1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nOW1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzEwbXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmcxMG1zLkF4ZWwpLCBjaVJlc2FtcGxpbmcxMG1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nMTBtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nMTBtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzEwbXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVUb0ZULmJhc2VsaW5lLk0gPSBtZWFuKHRpbWVUb0ZULmJhc2VsaW5lKSwgVGltZVRvVEYuYmFzZWxpbmUuY2kubG93ZXIgPSBjaSh0aW1lVG9GVC5iYXNlbGluZSlbIkNJIGxvd2VyIl0sIFRpbWVUb1RGLmJhc2VsaW5lLmNpLnVwcGVyID0gY2kodGltZVRvRlQuYmFzZWxpbmUpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVRvRlQuTUEuTSA9IG1lYW4odGltZVRvRlQuTUEpLCBUaW1lVG9GVC5NQS5jaS5sb3dlciA9IGNpKHRpbWVUb0ZULk1BKVsiQ0kgbG93ZXIiXSwgVGltZVRvRlQuTUEuY2kudXBwZXIgPSBjaSh0aW1lVG9GVC5NQSlbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lVG9GVC5yZXNhbXAwbXMuTSA9IG1lYW4odGltZVRvRlQucmVzYW1wLmRlbGF5LjBtcyksIFRpbWVUb0ZULnJlc2FtcDBtcy5jaS5sb3dlciA9IGNpKHRpbWVUb0ZULnJlc2FtcC5kZWxheS4wbXMpWyJDSSBsb3dlciJdLCBUaW1lVG9GVC5yZXNhbXAwbXMuY2kudXBwZXIgPSBjaSh0aW1lVG9GVC5yZXNhbXAuZGVsYXkuMG1zKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVUb0ZULnJlc2FtcDFtcy5NID0gbWVhbih0aW1lVG9GVC5yZXNhbXAuZGVsYXkuMW1zKSwgVGltZVRvRlQucmVzYW1wMW1zLmNpLmxvd2VyID0gY2kodGltZVRvRlQucmVzYW1wLmRlbGF5LjFtcylbIkNJIGxvd2VyIl0sIFRpbWVUb0ZULnJlc2FtcDFtcy5jaS51cHBlciA9IGNpKHRpbWVUb0ZULnJlc2FtcC5kZWxheS4xbXMpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVRvRlQucmVzYW1wMm1zLk0gPSBtZWFuKHRpbWVUb0ZULnJlc2FtcC5kZWxheS4ybXMpLCBUaW1lVG9GVC5yZXNhbXAybXMuY2kubG93ZXIgPSBjaSh0aW1lVG9GVC5yZXNhbXAuZGVsYXkuMm1zKVsiQ0kgbG93ZXIiXSwgVGltZVRvRlQucmVzYW1wMm1zLmNpLnVwcGVyID0gY2kodGltZVRvRlQucmVzYW1wLmRlbGF5LjJtcylbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lVG9GVC5yZXNhbXAzbXMuTSA9IG1lYW4odGltZVRvRlQucmVzYW1wLmRlbGF5LjNtcyksIFRpbWVUb0ZULnJlc2FtcDNtcy5jaS5sb3dlciA9IGNpKHRpbWVUb0ZULnJlc2FtcC5kZWxheS4zbXMpWyJDSSBsb3dlciJdLCBUaW1lVG9GVC5yZXNhbXAzbXMuY2kudXBwZXIgPSBjaSh0aW1lVG9GVC5yZXNhbXAuZGVsYXkuM21zKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVUb0ZULnJlc2FtcDRtcy5NID0gbWVhbih0aW1lVG9GVC5yZXNhbXAuZGVsYXkuNG1zKSwgVGltZVRvRlQucmVzYW1wNG1zLmNpLmxvd2VyID0gY2kodGltZVRvRlQucmVzYW1wLmRlbGF5LjRtcylbIkNJIGxvd2VyIl0sIFRpbWVUb0ZULnJlc2FtcDRtcy5jaS51cHBlciA9IGNpKHRpbWVUb0ZULnJlc2FtcC5kZWxheS40bXMpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVRvRlQucmVzYW1wNW1zLk0gPSBtZWFuKHRpbWVUb0ZULnJlc2FtcC5kZWxheS41bXMpLCBUaW1lVG9GVC5yZXNhbXA1bXMuY2kubG93ZXIgPSBjaSh0aW1lVG9GVC5yZXNhbXAuZGVsYXkuNW1zKVsiQ0kgbG93ZXIiXSwgVGltZVRvRlQucmVzYW1wNW1zLmNpLnVwcGVyID0gY2kodGltZVRvRlQucmVzYW1wLmRlbGF5LjVtcylbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lVG9GVC5yZXNhbXA2bXMuTSA9IG1lYW4odGltZVRvRlQucmVzYW1wLmRlbGF5LjZtcyksIFRpbWVUb0ZULnJlc2FtcDZtcy5jaS5sb3dlciA9IGNpKHRpbWVUb0ZULnJlc2FtcC5kZWxheS42bXMpWyJDSSBsb3dlciJdLCBUaW1lVG9GVC5yZXNhbXA2bXMuY2kudXBwZXIgPSBjaSh0aW1lVG9GVC5yZXNhbXAuZGVsYXkuNm1zKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVUb0ZULnJlc2FtcDdtcy5NID0gbWVhbih0aW1lVG9GVC5yZXNhbXAuZGVsYXkuN21zKSwgVGltZVRvRlQucmVzYW1wN21zLmNpLmxvd2VyID0gY2kodGltZVRvRlQucmVzYW1wLmRlbGF5LjdtcylbIkNJIGxvd2VyIl0sIFRpbWVUb0ZULnJlc2FtcDdtcy5jaS51cHBlciA9IGNpKHRpbWVUb0ZULnJlc2FtcC5kZWxheS43bXMpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVRvRlQucmVzYW1wOG1zLk0gPSBtZWFuKHRpbWVUb0ZULnJlc2FtcC5kZWxheS44bXMpLCBUaW1lVG9GVC5yZXNhbXA4bXMuY2kubG93ZXIgPSBjaSh0aW1lVG9GVC5yZXNhbXAuZGVsYXkuOG1zKVsiQ0kgbG93ZXIiXSwgVGltZVRvRlQucmVzYW1wOG1zLmNpLnVwcGVyID0gY2kodGltZVRvRlQucmVzYW1wLmRlbGF5LjhtcylbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lVG9GVC5yZXNhbXA5bXMuTSA9IG1lYW4odGltZVRvRlQucmVzYW1wLmRlbGF5LjltcyksIFRpbWVUb0ZULnJlc2FtcDltcy5jaS5sb3dlciA9IGNpKHRpbWVUb0ZULnJlc2FtcC5kZWxheS45bXMpWyJDSSBsb3dlciJdLCBUaW1lVG9GVC5yZXNhbXA5bXMuY2kudXBwZXIgPSBjaSh0aW1lVG9GVC5yZXNhbXAuZGVsYXkuOW1zKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVUb0ZULnJlc2FtcDEwbXMuTSA9IG1lYW4odGltZVRvRlQucmVzYW1wLmRlbGF5LjEwbXMpLCBUaW1lVG9GVC5yZXNhbXAxMG1zLmNpLmxvd2VyID0gY2kodGltZVRvRlQucmVzYW1wLmRlbGF5LjEwbXMpWyJDSSBsb3dlciJdLCBUaW1lVG9GVC5yZXNhbXAxMG1zLmNpLnVwcGVyID0gY2kodGltZVRvRlQucmVzYW1wLmRlbGF5LjEwbXMpWyJDSSB1cHBlciJdLCAuZ3JvdXBzID0gJ2Ryb3AnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCmBgYAoKCmBgYHtyIGxvYWREYXRhMiwgd2FybmluZz1GQUxTRX0KZGF0YTIgPSByZWFkLmNzdignZGF0YUNvbXBhcmlzb25QaXhlbDNhbmQ0LmNzdicpCmRhdGEyJFJlc2FtcGxpbmc5bXMuQXhlbCA9IGFzLm51bWVyaWMoZGF0YTIkUmVzYW1wbGluZzltcy5BeGVsKQpkYXRhMiRSZXNhbXBsaW5nMTBtcy5BeGVsID0gYXMubnVtZXJpYyhkYXRhMiRSZXNhbXBsaW5nMTBtcy5BeGVsKQpkYXRhX2FnZ3IyID0gZGF0YTIgJT4lIGdyb3VwX2J5KGZyZXEpICU+JQogICAgICAgICAgICAgICAgICAgICBzdW1tYXJpemUoQmFzZWxpbmUuQXhlbE0gPSBtZWFuKEJhc2VsaW5lLkF4ZWwpLCBjaUJhc2VsaW5lLkF4ZWwubG93ZXIgPSBjaShCYXNlbGluZS5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lCYXNlbGluZS5BeGVsLnVwcGVyID0gY2koQmFzZWxpbmUuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nMG1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nMG1zLkF4ZWwpLCBjaVJlc2FtcGxpbmcwbXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmcwbXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzBtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzBtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmcxbXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmcxbXMuQXhlbCksIGNpUmVzYW1wbGluZzFtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzFtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nMW1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nMW1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzJtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzJtcy5BeGVsKSwgY2lSZXNhbXBsaW5nMm1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nMm1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmcybXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmcybXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nM21zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nM21zLkF4ZWwpLCBjaVJlc2FtcGxpbmczbXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmczbXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzNtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzNtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmc0bXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmc0bXMuQXhlbCksIGNpUmVzYW1wbGluZzRtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzRtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nNG1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nNG1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzVtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzVtcy5BeGVsKSwgY2lSZXNhbXBsaW5nNW1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nNW1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmc1bXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmc1bXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nNm1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nNm1zLkF4ZWwpLCBjaVJlc2FtcGxpbmc2bXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmc2bXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzZtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzZtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmc3bXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmc3bXMuQXhlbCksIGNpUmVzYW1wbGluZzdtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzdtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nN21zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nN21zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzhtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzhtcy5BeGVsKSwgY2lSZXNhbXBsaW5nOG1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nOG1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmc4bXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmc4bXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nOW1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nOW1zLkF4ZWwpLCBjaVJlc2FtcGxpbmc5bXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmc5bXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzltcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzltcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmcxMG1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nMTBtcy5BeGVsKSwgY2lSZXNhbXBsaW5nMTBtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzEwbXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzEwbXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmcxMG1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdyb3VwcyA9ICdkcm9wJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQpgYGAKCgojIEltcGFjdCBvZiB0aGUgZGlzcGxheSByYXRlIG9uIHRoZSBzcGF0aWFsIGppdHRlciAoRmlndXJlIDcpCgoKYGBge3IgcGxvdEltcGFjdE9mVGhlRGlzcGxheVJhdGVPbkppdHRlcn0KdCA8LSBsaXN0KAogIGZhbWlseSA9ICJzYW5zIHNlcmlmIiwKICBzaXplID0gMjAsCiAgY29sb3IgPSAnYmxhY2snKQoKdDIgPC0gbGlzdCgKICBmYW1pbHkgPSAic2FucyBzZXJpZiIsCiAgc2l6ZSA9IDMwLAogIGNvbG9yID0gJ2JsYWNrJykKCnAgPC0gcGxvdF9seShkYXRhID0gZGF0YV9hZ2dyLCB0eXBlID0gInNjYXR0ZXIiLCBtb2RlID0gJ2xpbmVzK21hcmtlcnMnLCB4ID0gfmZyZXEsIHkgPSB+QmFzZWxpbmUuQXhlbE0sIG5hbWUgPSAnU2ltdWxhdGVkJywKICAgICAgICAgICAgIGVycm9yX3kgPSBsaXN0KHN5bW1ldHJpYz1GLCBhcnJheT1+Y2lCYXNlbGluZS5BeGVsLnVwcGVyLUJhc2VsaW5lLkF4ZWxNLCBhcnJheW1pbnVzPX5CYXNlbGluZS5BeGVsTS1jaUJhc2VsaW5lLkF4ZWwubG93ZXIsIGNvbG9yID0gJyMwMDAwMDAnKSkgJT4lCgogICAgICAgICAgICAgYWRkX3RyYWNlKGRhdGEgPSBkYXRhX2FnZ3IyLCB5PX5CYXNlbGluZS5BeGVsTSwgbmFtZSA9ICdSZWFsJywKICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl95ID0gbGlzdChzeW1tZXRyaWM9RiwgYXJyYXk9fmNpQmFzZWxpbmUuQXhlbC51cHBlci1CYXNlbGluZS5BeGVsTSwgYXJyYXltaW51cz1+QmFzZWxpbmUuQXhlbE0tY2lCYXNlbGluZS5BeGVsLmxvd2VyLCBjb2xvciA9ICcjMDAwMDAwJykpICU+JSAgCiAgICAgICAgCiAgICAgICAgICAgICBsYXlvdXQoeWF4aXMgPSBsaXN0KHRpdGxlID0gIlNwYXRpYWwgaml0dGVyIChwaXhlbHMpIiwgcmFuZ2UgPSBjKDAsMzUpKSwKICAgICAgICAgICAgICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAnT3V0cHV0IGZyZXF1ZW5jeSAoSHopJywgdHlwZSA9ICJjYXRlZ29yeSIpLAogICAgICAgICAgICAgICAgICAgIGxlZ2VuZCA9IGxpc3QoeCA9IDAuOCwgeSA9IDAuOTUsIGJvcmRlcmNvbG9yID0gIiMwMDAiLCBib3JkZXJ3aWR0aD0yKSwgCiAgICAgICAgICAgICAgICAgICAgZm9udCA9IHQsIHRpdGxlID0gbGlzdChmb250ID0gdDIpCiAgICAgICAgICAgICAgICAgICAgKQoKcApvcmNhKHAsICJJbXBhY3RPZlRoZURpc3BsYXlSYXRlT25KaXR0ZXIucGRmIikKaHRtbHdpZGdldHM6OnNhdmVXaWRnZXQocCwgZmlsZSA9ICdJbXBhY3RPZlRoZURpc3BsYXlSYXRlT25KaXR0ZXIuaHRtbCcpCmBgYAoKCiMgUGxvdCBMaW5lYXIgcmVzYW1wbGluZyAtIGppdHRlciAoRmlndXJlIDgpCgpgYGB7ciBMaW5lYXJSZXNhbXBsaW5nSml0dGVyVlNmcmVxfQoKcCA8LSBwbG90X2x5KGRhdGEgPSBkYXRhX2FnZ3IsIHR5cGUgPSAic2NhdHRlciIsIG1vZGUgPSAnbGluZXMrbWFya2VycycsIHggPSB+ZnJlcSwgeSA9IH5CYXNlbGluZS5BeGVsTSwgbmFtZSA9ICdCYXNlbGluZScsCiAgICAgICAgICAgICBlcnJvcl95ID0gbGlzdChzeW1tZXRyaWM9RiwgYXJyYXk9fmNpQmFzZWxpbmUuQXhlbC51cHBlci1CYXNlbGluZS5BeGVsTSwgYXJyYXltaW51cz1+QmFzZWxpbmUuQXhlbE0tY2lCYXNlbGluZS5BeGVsLmxvd2VyLCBjb2xvciA9ICcjMDAwMDAwJykpICU+JQogIAogICAgICAgICAgICAgYWRkX3RyYWNlKGRhdGEgPSBkYXRhX2FnZ3IsIHk9flJlc2FtcGxpbmcwbXMuQXhlbE0sIG5hbWUgPSAnMCBtcycsCiAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JfeSA9IGxpc3Qoc3ltbWV0cmljPUYsIGFycmF5PX5jaVJlc2FtcGxpbmcwbXMuQXhlbC51cHBlci1SZXNhbXBsaW5nMG1zLkF4ZWxNLCBhcnJheW1pbnVzPX5SZXNhbXBsaW5nMG1zLkF4ZWxNLWNpUmVzYW1wbGluZzBtcy5BeGVsLmxvd2VyLCBjb2xvciA9ICcjMDAwMDAwJykpICU+JQogICAgICAgICAgICAgYWRkX3RyYWNlKGRhdGEgPSBkYXRhX2FnZ3IsIHk9flJlc2FtcGxpbmcxbXMuQXhlbE0sIG5hbWUgPSAnMSBtcycsCiAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JfeSA9IGxpc3Qoc3ltbWV0cmljPUYsIGFycmF5PX5jaVJlc2FtcGxpbmcxbXMuQXhlbC51cHBlci1SZXNhbXBsaW5nMW1zLkF4ZWxNLCBhcnJheW1pbnVzPX5SZXNhbXBsaW5nMW1zLkF4ZWxNLWNpUmVzYW1wbGluZzFtcy5BeGVsLmxvd2VyLCBjb2xvciA9ICcjMDAwMDAwJykpICU+JSAgCiAgICAgICAgICAgICBhZGRfdHJhY2UoZGF0YSA9IGRhdGFfYWdnciwgeT1+UmVzYW1wbGluZzJtcy5BeGVsTSwgbmFtZSA9ICcyIG1zJywKICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl95ID0gbGlzdChzeW1tZXRyaWM9RiwgYXJyYXk9fmNpUmVzYW1wbGluZzJtcy5BeGVsLnVwcGVyLVJlc2FtcGxpbmcybXMuQXhlbE0sIGFycmF5bWludXM9flJlc2FtcGxpbmcybXMuQXhlbE0tY2lSZXNhbXBsaW5nMm1zLkF4ZWwubG93ZXIsIGNvbG9yID0gJyMwMDAwMDAnKSkgJT4lICAKICAgICAgICAgICAgIGFkZF90cmFjZShkYXRhID0gZGF0YV9hZ2dyLCB5PX5SZXNhbXBsaW5nM21zLkF4ZWxNLCBuYW1lID0gJzMgbXMnLAogICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3kgPSBsaXN0KHN5bW1ldHJpYz1GLCBhcnJheT1+Y2lSZXNhbXBsaW5nM21zLkF4ZWwudXBwZXItUmVzYW1wbGluZzNtcy5BeGVsTSwgYXJyYXltaW51cz1+UmVzYW1wbGluZzNtcy5BeGVsTS1jaVJlc2FtcGxpbmczbXMuQXhlbC5sb3dlciwgY29sb3IgPSAnIzAwMDAwMCcpKSAlPiUgIAogICAgICAgICAgICAgYWRkX3RyYWNlKGRhdGEgPSBkYXRhX2FnZ3IsIHk9flJlc2FtcGxpbmc0bXMuQXhlbE0sIG5hbWUgPSAnNCBtcycsCiAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JfeSA9IGxpc3Qoc3ltbWV0cmljPUYsIGFycmF5PX5jaVJlc2FtcGxpbmc0bXMuQXhlbC51cHBlci1SZXNhbXBsaW5nNG1zLkF4ZWxNLCBhcnJheW1pbnVzPX5SZXNhbXBsaW5nNG1zLkF4ZWxNLWNpUmVzYW1wbGluZzRtcy5BeGVsLmxvd2VyLCBjb2xvciA9ICcjMDAwMDAwJykpICU+JSAgCiAgICAgICAgICAgICBhZGRfdHJhY2UoZGF0YSA9IGRhdGFfYWdnciwgeT1+UmVzYW1wbGluZzVtcy5BeGVsTSwgbmFtZSA9ICc1IG1zJywKICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl95ID0gbGlzdChzeW1tZXRyaWM9RiwgYXJyYXk9fmNpUmVzYW1wbGluZzVtcy5BeGVsLnVwcGVyLVJlc2FtcGxpbmc1bXMuQXhlbE0sIGFycmF5bWludXM9flJlc2FtcGxpbmc1bXMuQXhlbE0tY2lSZXNhbXBsaW5nNW1zLkF4ZWwubG93ZXIsIGNvbG9yID0gJyMwMDAwMDAnKSkgJT4lICAKICAgICAgICAgICAgIGFkZF90cmFjZShkYXRhID0gZGF0YV9hZ2dyLCB5PX5SZXNhbXBsaW5nNm1zLkF4ZWxNLCBuYW1lID0gJzYgbXMnLAogICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3kgPSBsaXN0KHN5bW1ldHJpYz1GLCBhcnJheT1+Y2lSZXNhbXBsaW5nNm1zLkF4ZWwudXBwZXItUmVzYW1wbGluZzZtcy5BeGVsTSwgYXJyYXltaW51cz1+UmVzYW1wbGluZzZtcy5BeGVsTS1jaVJlc2FtcGxpbmc2bXMuQXhlbC5sb3dlciwgY29sb3IgPSAnIzAwMDAwMCcpKSAlPiUgIAogICAgICAgICAgICAgYWRkX3RyYWNlKGRhdGEgPSBkYXRhX2FnZ3IsIHk9flJlc2FtcGxpbmc3bXMuQXhlbE0sIG5hbWUgPSAnNyBtcycsCiAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JfeSA9IGxpc3Qoc3ltbWV0cmljPUYsIGFycmF5PX5jaVJlc2FtcGxpbmc3bXMuQXhlbC51cHBlci1SZXNhbXBsaW5nN21zLkF4ZWxNLCBhcnJheW1pbnVzPX5SZXNhbXBsaW5nN21zLkF4ZWxNLWNpUmVzYW1wbGluZzdtcy5BeGVsLmxvd2VyLCBjb2xvciA9ICcjMDAwMDAwJykpICU+JSAgCiAgICAgICAgICAgICBhZGRfdHJhY2UoZGF0YSA9IGRhdGFfYWdnciwgeT1+UmVzYW1wbGluZzhtcy5BeGVsTSwgbmFtZSA9ICc4IG1zJywKICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl95ID0gbGlzdChzeW1tZXRyaWM9RiwgYXJyYXk9fmNpUmVzYW1wbGluZzhtcy5BeGVsLnVwcGVyLVJlc2FtcGxpbmc4bXMuQXhlbE0sIGFycmF5bWludXM9flJlc2FtcGxpbmc4bXMuQXhlbE0tY2lSZXNhbXBsaW5nOG1zLkF4ZWwubG93ZXIsIGNvbG9yID0gJyMwMDAwMDAnKSkgJT4lICAKICAgICAgICAgICAgIGFkZF90cmFjZShkYXRhID0gZGF0YV9hZ2dyLCB5PX5SZXNhbXBsaW5nOW1zLkF4ZWxNLCBuYW1lID0gJzkgbXMnLAogICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3kgPSBsaXN0KHN5bW1ldHJpYz1GLCBhcnJheT1+Y2lSZXNhbXBsaW5nOW1zLkF4ZWwudXBwZXItUmVzYW1wbGluZzltcy5BeGVsTSwgYXJyYXltaW51cz1+UmVzYW1wbGluZzltcy5BeGVsTS1jaVJlc2FtcGxpbmc5bXMuQXhlbC5sb3dlciwgY29sb3IgPSAnIzAwMDAwMCcpKSAlPiUgIAogICAgICAgICAgICAgYWRkX3RyYWNlKGRhdGEgPSBkYXRhX2FnZ3IsIHk9flJlc2FtcGxpbmcxMG1zLkF4ZWxNLCBuYW1lID0gJzEwIG1zJywgbGluZT1saXN0KGNvbG9yPScjMkM1QTM5JyksIG1hcmtlcj1saXN0KGNvbG9yPScjMkM1QTM5JyksCiAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JfeSA9IGxpc3Qoc3ltbWV0cmljPUYsIGFycmF5PX5jaVJlc2FtcGxpbmcxMG1zLkF4ZWwudXBwZXItUmVzYW1wbGluZzEwbXMuQXhlbE0sIGFycmF5bWludXM9flJlc2FtcGxpbmcxMG1zLkF4ZWxNLWNpUmVzYW1wbGluZzEwbXMuQXhlbC5sb3dlciwgY29sb3IgPSAnIzAwMDAwMCcpKSAlPiUgICAgCgogICAgICAgICAgICAgbGF5b3V0KHlheGlzID0gbGlzdCh0aXRsZSA9ICJTcGF0aWFsIGppdHRlciAocGl4ZWxzKSIsIHJhbmdlID0gYygwLDM1KSksCiAgICAgICAgICAgICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gJ091dHB1dCBmcmVxdWVuY3kgKEh6KScsIHR5cGUgPSAiY2F0ZWdvcnkiKSwKICAgICAgICAgICAgICAgICAgICBsZWdlbmQgPSBsaXN0KHggPSAxLCB5ID0gMC45NSwgYm9yZGVyY29sb3IgPSAiIzAwMCIsIGJvcmRlcndpZHRoPTIpLCAKICAgICAgICAgICAgICAgICAgICBmb250ID0gdCwgdGl0bGUgPSBsaXN0KGZvbnQgPSB0MikKICAgICAgICAgICAgICAgICAgICApCgoKcApvcmNhKHAsICJMaW5lYXJSZXNhbXBsaW5nSml0dGVyVlNmcmVxLnBkZiIpCiNodG1sd2lkZ2V0czo6c2F2ZVdpZGdldChwLCBmaWxlID0gJ0ppdHRlckJ5ZnJlcXVlbmN5QXhlbC5odG1sJykKYGBgCgoKCiMgUGxvdCBqaXR0ZXIgbGF0ZW5jeSB0cmFkZW9mZiAtIGxpbmVhciByZXNhbXBsaW5nIChGaWd1cmUgOSkKCmBgYHtyIHJlZm9ybWF0RGF0YSwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0KZGF0YV9hZ2dyMiA9IGRhdGEgICU+JQogICAgICAgICBzZWxlY3QodGFzaywgcGFydCwgZGV2aWNlLCBmcmVxLCBCYXNlbGluZS5BeGVsLCBSZXNhbXBsaW5nMG1zLkF4ZWwsIFJlc2FtcGxpbmcxbXMuQXhlbCwgUmVzYW1wbGluZzJtcy5BeGVsLCBSZXNhbXBsaW5nM21zLkF4ZWwsIFJlc2FtcGxpbmc0bXMuQXhlbCwgUmVzYW1wbGluZzVtcy5BeGVsLCBSZXNhbXBsaW5nNm1zLkF4ZWwsIFJlc2FtcGxpbmc3bXMuQXhlbCwgUmVzYW1wbGluZzhtcy5BeGVsLCBSZXNhbXBsaW5nOW1zLkF4ZWwsIFJlc2FtcGxpbmcxMG1zLkF4ZWwsIE1BLkF4ZWwpICU+JQogICAgICAgICByZW5hbWUoQmFzZWxpbmUgPSBCYXNlbGluZS5BeGVsLCBSZXNhbXBsaW5nMG1zID0gUmVzYW1wbGluZzBtcy5BeGVsLCBSZXNhbXBsaW5nMW1zID0gUmVzYW1wbGluZzFtcy5BeGVsLCBSZXNhbXBsaW5nMm1zID0gUmVzYW1wbGluZzJtcy5BeGVsLCBSZXNhbXBsaW5nM21zID0gUmVzYW1wbGluZzNtcy5BeGVsLCBSZXNhbXBsaW5nNG1zID0gUmVzYW1wbGluZzRtcy5BeGVsLCBSZXNhbXBsaW5nNW1zID0gUmVzYW1wbGluZzVtcy5BeGVsLCBSZXNhbXBsaW5nNm1zID0gUmVzYW1wbGluZzZtcy5BeGVsLCBSZXNhbXBsaW5nN21zID0gUmVzYW1wbGluZzdtcy5BeGVsLCBSZXNhbXBsaW5nOG1zID0gUmVzYW1wbGluZzhtcy5BeGVsLCBSZXNhbXBsaW5nOW1zID0gUmVzYW1wbGluZzltcy5BeGVsLCBSZXNhbXBsaW5nMTBtcyA9IFJlc2FtcGxpbmcxMG1zLkF4ZWwsIE1BID0gTUEuQXhlbCkgJT4lCiAgICAgICAgIGdhdGhlcihrZXkgPSAidGVjaG5pcXVlIiwgdmFsdWUgPSAiQXhlbE1ldHJpY1Njb3JlIiwgQmFzZWxpbmUsIFJlc2FtcGxpbmcwbXMsIFJlc2FtcGxpbmcxbXMsIFJlc2FtcGxpbmcybXMsIFJlc2FtcGxpbmczbXMsIFJlc2FtcGxpbmc0bXMsIFJlc2FtcGxpbmc1bXMsIFJlc2FtcGxpbmc2bXMsIFJlc2FtcGxpbmc3bXMsIFJlc2FtcGxpbmc4bXMsIFJlc2FtcGxpbmc5bXMsIFJlc2FtcGxpbmcxMG1zLCBNQSkgCmRhdGFfYWdncjMgPSAgZGF0YSAlPiUgCiAgICAgICAgIHNlbGVjdCh0YXNrLCBwYXJ0LCBkZXZpY2UsIGZyZXEsIHRpbWVUb0ZULmJhc2VsaW5lLCB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuMG1zLCB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuMW1zLCB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuMm1zLCB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuM21zLCB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuNG1zLCB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuNW1zLCB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuNm1zLCB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuN21zLCB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuOG1zLCB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuOW1zLCB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuMTBtcywgdGltZVRvRlQuTUEpICU+JQogICAgICAgICByZW5hbWUoQmFzZWxpbmUgPSB0aW1lVG9GVC5iYXNlbGluZSwgUmVzYW1wbGluZzBtcyA9IHRpbWVUb0ZULnJlc2FtcC5kZWxheS4wbXMsIFJlc2FtcGxpbmcxbXMgPSB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuMW1zLCBSZXNhbXBsaW5nMm1zID0gdGltZVRvRlQucmVzYW1wLmRlbGF5LjJtcywgUmVzYW1wbGluZzNtcyA9IHRpbWVUb0ZULnJlc2FtcC5kZWxheS4zbXMsIFJlc2FtcGxpbmc0bXMgPSB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuNG1zLCBSZXNhbXBsaW5nNW1zID0gdGltZVRvRlQucmVzYW1wLmRlbGF5LjVtcywgUmVzYW1wbGluZzZtcyA9IHRpbWVUb0ZULnJlc2FtcC5kZWxheS42bXMsIFJlc2FtcGxpbmc3bXMgPSB0aW1lVG9GVC5yZXNhbXAuZGVsYXkuN21zLCBSZXNhbXBsaW5nOG1zID0gdGltZVRvRlQucmVzYW1wLmRlbGF5LjhtcywgUmVzYW1wbGluZzltcyA9IHRpbWVUb0ZULnJlc2FtcC5kZWxheS45bXMsIFJlc2FtcGxpbmcxMG1zID0gdGltZVRvRlQucmVzYW1wLmRlbGF5LjEwbXMsIE1BID0gdGltZVRvRlQuTUEpICU+JQogICAgICAgICBnYXRoZXIoa2V5ID0gInRlY2huaXF1ZSIsIHZhbHVlID0gInRpbWVUb0ZUIiwgQmFzZWxpbmUsIFJlc2FtcGxpbmcwbXMsIFJlc2FtcGxpbmcxbXMsIFJlc2FtcGxpbmcybXMsIFJlc2FtcGxpbmczbXMsIFJlc2FtcGxpbmc0bXMsIFJlc2FtcGxpbmc1bXMsIFJlc2FtcGxpbmc2bXMsIFJlc2FtcGxpbmc3bXMsIFJlc2FtcGxpbmc4bXMsIFJlc2FtcGxpbmc5bXMsIFJlc2FtcGxpbmcxMG1zLCBNQSkgCmRhdGFfYWdncjQgPSBsZWZ0X2pvaW4oZGF0YV9hZ2dyMiwgZGF0YV9hZ2dyMywgYnkgPSBjKCJ0YXNrIiwgInBhcnQiLCAiZGV2aWNlIiwgImZyZXEiLCAidGVjaG5pcXVlIikpCmRhdGFfYWdncjUgPSBkYXRhX2FnZ3I0ICU+JSBncm91cF9ieShmcmVxLCB0ZWNobmlxdWUpICU+JSBzdW1tYXJpemUoSml0dGVyU2NvcmUgPSBtZWFuKEF4ZWxNZXRyaWNTY29yZSksIHRpbWVUb0ZyYW1lID0gbWVhbih0aW1lVG9GVCkpCmBgYAoKYGBge3IgYmFzZWxpbmV9CmRhdGFfYWdnckJhc2VsaW5lID0gZGF0YV9hZ2dyNSAlPiUgZmlsdGVyKHRlY2huaXF1ZSA9PSAnQmFzZWxpbmUnKQogIApgYGAKCmBgYHtweXRob24gYWdncnB5dGhvbn0KZGYwID0gci5kYXRhX2FnZ3JCYXNlbGluZQpwcmludChkZjApCmJhc2VsaW5lID0ge30KZm9yIGksIHJvdyBpbiBkZjAuaXRlcnJvd3MoKToKICBiYXNlbGluZVtyb3dbJ2ZyZXEnXV0gPSB7fQogIGJhc2VsaW5lW3Jvd1snZnJlcSddXVsndGltZVRvRnJhbWUnXSA9IHJvd1sndGltZVRvRnJhbWUnXQojcHJpbnQoYmFzZWxpbmUpCmBgYAoKYGBge3B5dGhvbiBrZWVwZ29pbmd3aXRoUHl0aG9ufQppbXBvcnQgcGFuZGFzCmRmID0gci5kYXRhX2FnZ3I1CmZvciBpLCByb3cgaW4gZGYuaXRlcnJvd3MoKToKICBkZi5hdFtpLCJ0aW1lVG9GcmFtZSJdID0gcm93WyJ0aW1lVG9GcmFtZSJdIC0gYmFzZWxpbmVbcm93WydmcmVxJ11dWyd0aW1lVG9GcmFtZSddCgpgYGAKCmBgYHtyIHB5MnJ9CmRhdGFfYWdncjcgPSBweSRkZgpgYGAKCgpgYGB7ciBKaXR0ZXJMYXRlbmN5VHJhZGVvZmZDb21wYXJlZFRvQmFzZWxpbmV9CmRhdGFfYWdnckxhdGVuY3kgPSBkYXRhX2FnZ3I3ICU+JSBzZWxlY3QoLUppdHRlclNjb3JlKSAlPiUgc3ByZWFkKHRlY2huaXF1ZSwgdGltZVRvRnJhbWUpCmRhdGFfYWdnckppdHRlciA9IGRhdGFfYWdncjcgJT4lIHNlbGVjdCgtdGltZVRvRnJhbWUpICU+JSBzcHJlYWQodGVjaG5pcXVlLCBKaXR0ZXJTY29yZSkKdCA8LSBsaXN0KAogIGZhbWlseSA9ICJzYW5zIHNlcmlmIiwKICBzaXplID0gMTUsCiAgY29sb3IgPSAnYmxhY2snKQp0MiA8LSBsaXN0KAogIGZhbWlseSA9ICJzYW5zIHNlcmlmIiwKICBzaXplID0gMzAsCiAgY29sb3IgPSAnYmxhY2snKQpzeW1ib2xzID0gYygnY2lyY2xlJywgJ3RyaWFuZ2xlLXVwJywgJ3NxdWFyZScsICdjcm9zcycsICdkaWFtb25kJywgJ3N0YXItdHJpYW5nbGUtZG93bicsICdob3VyZ2xhc3MnLCAnc3RhcicsICdib3d0aWUnLCAneCcpCnAgPC0gcGxvdF9seSh0eXBlID0gInNjYXR0ZXIiLCBzeW1ib2xzID0gc3ltYm9scywgbW9kZSA9ICdtYXJrZXJzJywgc3ltYm9sID0gZGF0YV9hZ2dyTGF0ZW5jeSRmcmVxLCBtYXJrZXIgPSBsaXN0KHNpemUgPSA5LCBsaW5lID0gbGlzdChjb2xvciA9ICdyZ2IoNTAsNTAsNTApJyx3aWR0aCA9IDEpKSkgJT4lCiAgCiAgICAjIENvbW1lbnQgdGhpcyBsaW5lIHRvIGRpc2FibGUgRnJlcXVlbmNpZXMgbGVnZW5kCiAgICBhZGRfdHJhY2UoeCA9IGRhdGFfYWdnckxhdGVuY3kkQmFzZWxpbmUsIHkgPSBkYXRhX2FnZ3JKaXR0ZXIkQmFzZWxpbmUsIG5hbWUgPSBwYXN0ZTAoZGF0YV9hZ2dyTGF0ZW5jeSRmcmVxLCIgSHoiKSwgbWFya2VyID0gbGlzdChjb2xvciA9ICdyZ2JhKDAsMCwwLDAuNSknKSwgbGVnZW5kZ3JvdXAgPSAiZnJlcSIpICU+JQogICAgCiAgICBhZGRfdHJhY2UoeCA9IGRhdGFfYWdnckxhdGVuY3kkQmFzZWxpbmUsIHkgPSBkYXRhX2FnZ3JKaXR0ZXIkQmFzZWxpbmUsIG1vZGUgPSAnbWFya2VycycsIG5hbWUgPSAnQmFzZWxpbmUnLCBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJ3JnYigwLDAsMCknKSxsZWdlbmRncm91cCA9ICJsYXQiKSAlPiUKICAgIGFkZF90cmFjZSh4ID0gZGF0YV9hZ2dyTGF0ZW5jeSRNQSwgeT1kYXRhX2FnZ3JKaXR0ZXIkTUEsIG5hbWUgPSAnTUEnLCBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJ3JnYigyNTUsMjU1LDI1NSknKSxsZWdlbmRncm91cCA9ICJsYXQiKSAlPiUKICAgIGFkZF90cmFjZSh4ID0gZGF0YV9hZ2dyTGF0ZW5jeSRSZXNhbXBsaW5nMG1zLCB5PWRhdGFfYWdnckppdHRlciRSZXNhbXBsaW5nMG1zLCBuYW1lID0gJzAgbXMnLCBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJ3JnYig2OSwxMTcsMTgwKScpLGxlZ2VuZGdyb3VwID0gImxhdCIpICU+JQogICAgYWRkX3RyYWNlKHggPSBkYXRhX2FnZ3JMYXRlbmN5JFJlc2FtcGxpbmcybXMsIHk9ZGF0YV9hZ2dySml0dGVyJFJlc2FtcGxpbmcybXMsIG5hbWUgPSAnMiBtcycsIG1hcmtlciA9IGxpc3QoY29sb3IgPSAncmdiKDIxNSw0OCwzOSknKSxsZWdlbmRncm91cCA9ICJsYXQiKSAlPiUKICAgIGFkZF90cmFjZSh4ID0gZGF0YV9hZ2dyTGF0ZW5jeSRSZXNhbXBsaW5nNG1zLCB5PWRhdGFfYWdnckppdHRlciRSZXNhbXBsaW5nNG1zLCBuYW1lID0gJzQgbXMnLCBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJ3JnYigyNTIsMTQxLDg5KScpLGxlZ2VuZGdyb3VwID0gImxhdCIpICU+JQogICAgYWRkX3RyYWNlKHggPSBkYXRhX2FnZ3JMYXRlbmN5JFJlc2FtcGxpbmc2bXMsIHk9ZGF0YV9hZ2dySml0dGVyJFJlc2FtcGxpbmc2bXMsIG5hbWUgPSAnNiBtcycsIG1hcmtlciA9IGxpc3QoY29sb3IgPSAncmdiKDI1NSwyNTUsMTkxKScpLGxlZ2VuZGdyb3VwID0gImxhdCIpICU+JQogICAgYWRkX3RyYWNlKHggPSBkYXRhX2FnZ3JMYXRlbmN5JFJlc2FtcGxpbmc4bXMsIHk9ZGF0YV9hZ2dySml0dGVyJFJlc2FtcGxpbmc4bXMsIG5hbWUgPSAnOCBtcycsIG1hcmtlciA9IGxpc3QoY29sb3IgPSAncmdiKDE0NSwyMDcsOTYpJyksbGVnZW5kZ3JvdXAgPSAibGF0IikgJT4lCiAgICBhZGRfdHJhY2UoeCA9IGRhdGFfYWdnckxhdGVuY3kkUmVzYW1wbGluZzEwbXMsIHk9ZGF0YV9hZ2dySml0dGVyJFJlc2FtcGxpbmcxMG1zLCBuYW1lID0gJzEwIG1zJywgbWFya2VyID0gbGlzdChjb2xvciA9ICdyZ2IoMjYsMTUyLDgwKScpLGxlZ2VuZGdyb3VwID0gImxhdCIpICU+JQogIAogICAgbGF5b3V0KHlheGlzID0gbGlzdCh0aXRsZSA9ICJTcGF0aWFsIGppdHRlciAocGl4ZWxzKSIpLAogICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gJ0xhdGVuY3kgY29tcGFyZWQgdG8gYmFzZWxpbmUgKG1zKScpLAogICAgICAgICAgbGVnZW5kID0gbGlzdCh4ID0gMSwgeSA9IDAuNSwgYm9yZGVyY29sb3IgPSAiIzAwMCIsIGJvcmRlcndpZHRoPTIsIG9yaWVudGF0aW9uID0gJ3YnLCBmb250ID0gdCwgdGl0bGUgPSBsaXN0KGZvbnQgPSB0MikKICAgICAgICAgICkpCnAKb3JjYShwLCAiSml0dGVyTGF0ZW5jeVRyYWRlb2ZmQ29tcGFyZWRUb0Jhc2VsaW5lLnBkZiIpCiNodG1sd2lkZ2V0czo6c2F2ZVdpZGdldChwLCBmaWxlID0gJ0ltcGFjdE9mVGhlRGlzcGxheVJhdGVPbkppdHRlci5odG1sJykKYGBgCgoKIyBUZXN0IG9mIG90aGVyIGV4dHJhcG9sYXRpb24gdGVjaG5pcXVlcwoKIyMgTGluZWFyIHByZWRpY3RvcgoKYGBge3IgbG9hZERhdGFMaW5lYXIsIHdhcm5pbmc9RkFMU0V9CmRhdGEgPSByZWFkLmNzdignZGF0YUxpbmVhci5jc3YnKQpkYXRhJFJlc2FtcGxpbmc5bXMuQXhlbCA9IGFzLm51bWVyaWMoZGF0YSRSZXNhbXBsaW5nOW1zLkF4ZWwpCmRhdGEkUmVzYW1wbGluZzEwbXMuQXhlbCA9IGFzLm51bWVyaWMoZGF0YSRSZXNhbXBsaW5nMTBtcy5BeGVsKQpkYXRhX2FnZ3JMaW5lYXIgPSBkYXRhICU+JSBncm91cF9ieShmcmVxKSAlPiUKICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXplKEJhc2VsaW5lLkF4ZWxNID0gbWVhbihCYXNlbGluZS5BeGVsKSwgY2lCYXNlbGluZS5BeGVsLmxvd2VyID0gY2koQmFzZWxpbmUuQXhlbClbIkNJIGxvd2VyIl0sIGNpQmFzZWxpbmUuQXhlbC51cHBlciA9IGNpKEJhc2VsaW5lLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzBtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzBtcy5BeGVsKSwgY2lSZXNhbXBsaW5nMG1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nMG1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmcwbXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmcwbXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nMW1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nMW1zLkF4ZWwpLCBjaVJlc2FtcGxpbmcxbXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmcxbXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzFtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzFtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmcybXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmcybXMuQXhlbCksIGNpUmVzYW1wbGluZzJtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzJtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nMm1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nMm1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzNtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzNtcy5BeGVsKSwgY2lSZXNhbXBsaW5nM21zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nM21zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmczbXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmczbXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nNG1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nNG1zLkF4ZWwpLCBjaVJlc2FtcGxpbmc0bXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmc0bXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzRtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzRtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmc1bXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmc1bXMuQXhlbCksIGNpUmVzYW1wbGluZzVtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzVtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nNW1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nNW1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzZtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzZtcy5BeGVsKSwgY2lSZXNhbXBsaW5nNm1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nNm1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmc2bXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmc2bXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nN21zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nN21zLkF4ZWwpLCBjaVJlc2FtcGxpbmc3bXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmc3bXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzdtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzdtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmc4bXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmc4bXMuQXhlbCksIGNpUmVzYW1wbGluZzhtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzhtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nOG1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nOG1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzltcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzltcy5BeGVsKSwgY2lSZXNhbXBsaW5nOW1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nOW1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmc5bXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmc5bXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nMTBtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzEwbXMuQXhlbCksIGNpUmVzYW1wbGluZzEwbXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmcxMG1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmcxMG1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nMTBtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5ncm91cHMgPSAnZHJvcCcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKYGBgCgoKIyMgUXVhZHJhdGljIHByZWRpY3RvcgoKYGBge3IgbG9hZFF1YWRyYXRpYywgd2FybmluZz1GQUxTRX0KZGF0YSA9IHJlYWQuY3N2KCdkYXRhUXVhZHJhdGljLmNzdicpCmRhdGEkUmVzYW1wbGluZzltcy5BeGVsID0gYXMubnVtZXJpYyhkYXRhJFJlc2FtcGxpbmc5bXMuQXhlbCkKZGF0YSRSZXNhbXBsaW5nMTBtcy5BeGVsID0gYXMubnVtZXJpYyhkYXRhJFJlc2FtcGxpbmcxMG1zLkF4ZWwpCmRhdGFfYWdnclF1YWRyYXRpYyA9IGRhdGEgJT4lIGdyb3VwX2J5KGZyZXEpICU+JQogICAgICAgICAgICAgICAgICAgICBzdW1tYXJpemUoQmFzZWxpbmUuQXhlbE0gPSBtZWFuKEJhc2VsaW5lLkF4ZWwpLCBjaUJhc2VsaW5lLkF4ZWwubG93ZXIgPSBjaShCYXNlbGluZS5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lCYXNlbGluZS5BeGVsLnVwcGVyID0gY2koQmFzZWxpbmUuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nMG1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nMG1zLkF4ZWwpLCBjaVJlc2FtcGxpbmcwbXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmcwbXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzBtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzBtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmcxbXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmcxbXMuQXhlbCksIGNpUmVzYW1wbGluZzFtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzFtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nMW1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nMW1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzJtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzJtcy5BeGVsKSwgY2lSZXNhbXBsaW5nMm1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nMm1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmcybXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmcybXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nM21zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nM21zLkF4ZWwpLCBjaVJlc2FtcGxpbmczbXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmczbXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzNtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzNtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmc0bXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmc0bXMuQXhlbCksIGNpUmVzYW1wbGluZzRtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzRtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nNG1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nNG1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzVtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzVtcy5BeGVsKSwgY2lSZXNhbXBsaW5nNW1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nNW1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmc1bXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmc1bXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nNm1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nNm1zLkF4ZWwpLCBjaVJlc2FtcGxpbmc2bXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmc2bXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzZtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzZtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmc3bXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmc3bXMuQXhlbCksIGNpUmVzYW1wbGluZzdtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzdtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nN21zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nN21zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzhtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzhtcy5BeGVsKSwgY2lSZXNhbXBsaW5nOG1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nOG1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmc4bXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmc4bXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nOW1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nOW1zLkF4ZWwpLCBjaVJlc2FtcGxpbmc5bXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmc5bXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzltcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzltcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmcxMG1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nMTBtcy5BeGVsKSwgY2lSZXNhbXBsaW5nMTBtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzEwbXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzEwbXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmcxMG1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdyb3VwcyA9ICdkcm9wJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQpgYGAKCiMjIExhVmlvbGEgcHJlZGljdG9yCgpgYGB7ciBsb2FkTGF2aW9sYSwgd2FybmluZz1GQUxTRX0KZGF0YSA9IHJlYWQuY3N2KCdkYXRhTGFWaW9sYS5jc3YnKQpkYXRhJFJlc2FtcGxpbmc5bXMuQXhlbCA9IGFzLm51bWVyaWMoZGF0YSRSZXNhbXBsaW5nOW1zLkF4ZWwpCmRhdGEkUmVzYW1wbGluZzEwbXMuQXhlbCA9IGFzLm51bWVyaWMoZGF0YSRSZXNhbXBsaW5nMTBtcy5BeGVsKQpkYXRhX2FnZ3JMYVZpb2xhID0gZGF0YSAlPiUgZ3JvdXBfYnkoZnJlcSkgJT4lCiAgICAgICAgICAgICAgICAgICAgIHN1bW1hcml6ZShCYXNlbGluZS5BeGVsTSA9IG1lYW4oQmFzZWxpbmUuQXhlbCksIGNpQmFzZWxpbmUuQXhlbC5sb3dlciA9IGNpKEJhc2VsaW5lLkF4ZWwpWyJDSSBsb3dlciJdLCBjaUJhc2VsaW5lLkF4ZWwudXBwZXIgPSBjaShCYXNlbGluZS5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmcwbXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmcwbXMuQXhlbCksIGNpUmVzYW1wbGluZzBtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzBtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nMG1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nMG1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzFtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzFtcy5BeGVsKSwgY2lSZXNhbXBsaW5nMW1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nMW1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmcxbXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmcxbXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nMm1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nMm1zLkF4ZWwpLCBjaVJlc2FtcGxpbmcybXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmcybXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzJtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzJtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmczbXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmczbXMuQXhlbCksIGNpUmVzYW1wbGluZzNtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzNtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nM21zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nM21zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzRtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzRtcy5BeGVsKSwgY2lSZXNhbXBsaW5nNG1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nNG1zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmc0bXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmc0bXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nNW1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nNW1zLkF4ZWwpLCBjaVJlc2FtcGxpbmc1bXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmc1bXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzVtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzVtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmc2bXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmc2bXMuQXhlbCksIGNpUmVzYW1wbGluZzZtcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzZtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nNm1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nNm1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzdtcy5BeGVsTSA9IG1lYW4oUmVzYW1wbGluZzdtcy5BeGVsKSwgY2lSZXNhbXBsaW5nN21zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nN21zLkF4ZWwpWyJDSSBsb3dlciJdLCBjaVJlc2FtcGxpbmc3bXMuQXhlbC51cHBlciA9IGNpKFJlc2FtcGxpbmc3bXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNhbXBsaW5nOG1zLkF4ZWxNID0gbWVhbihSZXNhbXBsaW5nOG1zLkF4ZWwpLCBjaVJlc2FtcGxpbmc4bXMuQXhlbC5sb3dlciA9IGNpKFJlc2FtcGxpbmc4bXMuQXhlbClbIkNJIGxvd2VyIl0sIGNpUmVzYW1wbGluZzhtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzhtcy5BeGVsKVsiQ0kgdXBwZXIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc2FtcGxpbmc5bXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmc5bXMuQXhlbCksIGNpUmVzYW1wbGluZzltcy5BeGVsLmxvd2VyID0gY2koUmVzYW1wbGluZzltcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nOW1zLkF4ZWwudXBwZXIgPSBjaShSZXNhbXBsaW5nOW1zLkF4ZWwpWyJDSSB1cHBlciJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzYW1wbGluZzEwbXMuQXhlbE0gPSBtZWFuKFJlc2FtcGxpbmcxMG1zLkF4ZWwpLCBjaVJlc2FtcGxpbmcxMG1zLkF4ZWwubG93ZXIgPSBjaShSZXNhbXBsaW5nMTBtcy5BeGVsKVsiQ0kgbG93ZXIiXSwgY2lSZXNhbXBsaW5nMTBtcy5BeGVsLnVwcGVyID0gY2koUmVzYW1wbGluZzEwbXMuQXhlbClbIkNJIHVwcGVyIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZ3JvdXBzID0gJ2Ryb3AnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCmBgYAoKIyMgUGxvdCBMaW5lYXIgcmVzYW1wbGluZyAtIGppdHRlciAoRmlndXJlIDEwKQoKYGBge3IgQ29tcGFyaXNvblByZWRpY3RvcnN9CgpwIDwtIHBsb3RfbHkoZGF0YSA9IGRhdGFfYWdnckxpbmVhciwgdHlwZSA9ICJzY2F0dGVyIiwgbW9kZSA9ICdsaW5lcyttYXJrZXJzJywgeCA9IH5mcmVxLCB5ID0gfkJhc2VsaW5lLkF4ZWxNLCBuYW1lID0gJ0Jhc2VsaW5lJywgbGluZT1saXN0KGNvbG9yPScjRkYwMDAwJyksIG1hcmtlcj1saXN0KGNvbG9yPScjRkYwMDAwJyksIAogICAgICAgICAgICAgZXJyb3JfeSA9IGxpc3Qoc3ltbWV0cmljPUYsIGFycmF5PX5jaUJhc2VsaW5lLkF4ZWwudXBwZXItQmFzZWxpbmUuQXhlbE0sIGFycmF5bWludXM9fkJhc2VsaW5lLkF4ZWxNLWNpQmFzZWxpbmUuQXhlbC5sb3dlciwgY29sb3IgPSAnIzAwMDAwMCcpKSAlPiUKICAKICAgICAgICAgICAgIGFkZF90cmFjZShkYXRhID0gZGF0YV9hZ2dyTGluZWFyLCB5PX5SZXNhbXBsaW5nMG1zLkF4ZWxNLCBuYW1lID0gJ0xpbmVhciAwIG1zJywgbGluZT1saXN0KGNvbG9yPScjQTYzNjAzJyksIG1hcmtlcj1saXN0KGNvbG9yPScjQTYzNjAzJyksIAogICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3kgPSBsaXN0KHN5bW1ldHJpYz1GLCBhcnJheT1+Y2lSZXNhbXBsaW5nMG1zLkF4ZWwudXBwZXItUmVzYW1wbGluZzBtcy5BeGVsTSwgYXJyYXltaW51cz1+UmVzYW1wbGluZzBtcy5BeGVsTS1jaVJlc2FtcGxpbmcwbXMuQXhlbC5sb3dlciwgY29sb3IgPSAnIzAwMDAwMCcpKSAlPiUKICAgICAgICAgICAgIGFkZF90cmFjZShkYXRhID0gZGF0YV9hZ2dyTGluZWFyLCB5PX5SZXNhbXBsaW5nMm1zLkF4ZWxNLCBuYW1lID0gJ0xpbmVhciAyIG1zJywgbGluZT1saXN0KGNvbG9yPScjRTY1NTBEJyksIG1hcmtlcj1saXN0KGNvbG9yPScjRTY1NTBEJyksIAogICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3kgPSBsaXN0KHN5bW1ldHJpYz1GLCBhcnJheT1+Y2lSZXNhbXBsaW5nMm1zLkF4ZWwudXBwZXItUmVzYW1wbGluZzJtcy5BeGVsTSwgYXJyYXltaW51cz1+UmVzYW1wbGluZzJtcy5BeGVsTS1jaVJlc2FtcGxpbmcybXMuQXhlbC5sb3dlciwgY29sb3IgPSAnIzAwMDAwMCcpKSAlPiUKICAgICAgICAgICAgIGFkZF90cmFjZShkYXRhID0gZGF0YV9hZ2dyTGluZWFyLCB5PX5SZXNhbXBsaW5nNG1zLkF4ZWxNLCBuYW1lID0gJ0xpbmVhciA0IG1zJywgbGluZT1saXN0KGNvbG9yPScjRkRCRTg1JyksIG1hcmtlcj1saXN0KGNvbG9yPScjRkM4RDU5JyksIAogICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3kgPSBsaXN0KHN5bW1ldHJpYz1GLCBhcnJheT1+Y2lSZXNhbXBsaW5nNG1zLkF4ZWwudXBwZXItUmVzYW1wbGluZzRtcy5BeGVsTSwgYXJyYXltaW51cz1+UmVzYW1wbGluZzRtcy5BeGVsTS1jaVJlc2FtcGxpbmc0bXMuQXhlbC5sb3dlciwgY29sb3IgPSAnIzAwMDAwMCcpKSAlPiUKCiAgICAgICAgICAgICBhZGRfdHJhY2UoZGF0YSA9IGRhdGFfYWdnclF1YWRyYXRpYywgeT1+UmVzYW1wbGluZzBtcy5BeGVsTSwgbmFtZSA9ICdDdXJ2ZSAwIG1zJywgbGluZT1saXN0KGNvbG9yPScjMDA2RDJDJyksIG1hcmtlcj1saXN0KGNvbG9yPScjMDA2RDJDJyksCiAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JfeSA9IGxpc3Qoc3ltbWV0cmljPUYsIGFycmF5PX5jaVJlc2FtcGxpbmcwbXMuQXhlbC51cHBlci1SZXNhbXBsaW5nMG1zLkF4ZWxNLCBhcnJheW1pbnVzPX5SZXNhbXBsaW5nMG1zLkF4ZWxNLWNpUmVzYW1wbGluZzBtcy5BeGVsLmxvd2VyLCBjb2xvciA9ICcjMDAwMDAwJykpICU+JQogICAgICAgICAgICAgYWRkX3RyYWNlKGRhdGEgPSBkYXRhX2FnZ3JRdWFkcmF0aWMsIHk9flJlc2FtcGxpbmcybXMuQXhlbE0sIG5hbWUgPSAnQ3VydmUgMiBtcycsIGxpbmU9bGlzdChjb2xvcj0nIzMxQTM1NCcpLCBtYXJrZXI9bGlzdChjb2xvcj0nIzMxQTM1NCcpLAogICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3kgPSBsaXN0KHN5bW1ldHJpYz1GLCBhcnJheT1+Y2lSZXNhbXBsaW5nMm1zLkF4ZWwudXBwZXItUmVzYW1wbGluZzJtcy5BeGVsTSwgYXJyYXltaW51cz1+UmVzYW1wbGluZzJtcy5BeGVsTS1jaVJlc2FtcGxpbmcybXMuQXhlbC5sb3dlciwgY29sb3IgPSAnIzAwMDAwMCcpKSAlPiUKICAgICAgICAgICAgIGFkZF90cmFjZShkYXRhID0gZGF0YV9hZ2dyUXVhZHJhdGljLCB5PX5SZXNhbXBsaW5nNG1zLkF4ZWxNLCBuYW1lID0gJ0N1cnZlIDQgbXMnLCBsaW5lPWxpc3QoY29sb3I9JyNCQUU0QjMnKSwgbWFya2VyPWxpc3QoY29sb3I9JyNCQUU0QjMnKSwKICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl95ID0gbGlzdChzeW1tZXRyaWM9RiwgYXJyYXk9fmNpUmVzYW1wbGluZzRtcy5BeGVsLnVwcGVyLVJlc2FtcGxpbmc0bXMuQXhlbE0sIGFycmF5bWludXM9flJlc2FtcGxpbmc0bXMuQXhlbE0tY2lSZXNhbXBsaW5nNG1zLkF4ZWwubG93ZXIsIGNvbG9yID0gJyMwMDAwMDAnKSkgJT4lCgogICAgICAgICAgICAgYWRkX3RyYWNlKGRhdGEgPSBkYXRhX2FnZ3JMYVZpb2xhLCB5PX5SZXNhbXBsaW5nMG1zLkF4ZWxNLCBuYW1lID0gJ0RFU1AgMCBtcycsIGxpbmU9bGlzdChjb2xvcj0nIzA4NTE5QycpLCBtYXJrZXI9bGlzdChjb2xvcj0nIzA4NTE5QycpLAogICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3kgPSBsaXN0KHN5bW1ldHJpYz1GLCBhcnJheT1+Y2lSZXNhbXBsaW5nMG1zLkF4ZWwudXBwZXItUmVzYW1wbGluZzBtcy5BeGVsTSwgYXJyYXltaW51cz1+UmVzYW1wbGluZzBtcy5BeGVsTS1jaVJlc2FtcGxpbmcwbXMuQXhlbC5sb3dlciwgY29sb3IgPSAnIzAwMDAwMCcpKSAlPiUKICAgICAgICAgICAgIGFkZF90cmFjZShkYXRhID0gZGF0YV9hZ2dyTGFWaW9sYSwgeT1+UmVzYW1wbGluZzJtcy5BeGVsTSwgbmFtZSA9ICdERVNQIDIgbXMnLCBsaW5lPWxpc3QoY29sb3I9JyMzMTgyQkQnKSwgbWFya2VyPWxpc3QoY29sb3I9JyMzMTgyQkQnKSwKICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl95ID0gbGlzdChzeW1tZXRyaWM9RiwgYXJyYXk9fmNpUmVzYW1wbGluZzJtcy5BeGVsLnVwcGVyLVJlc2FtcGxpbmcybXMuQXhlbE0sIGFycmF5bWludXM9flJlc2FtcGxpbmcybXMuQXhlbE0tY2lSZXNhbXBsaW5nMm1zLkF4ZWwubG93ZXIsIGNvbG9yID0gJyMwMDAwMDAnKSkgJT4lCiAgICAgICAgICAgICBhZGRfdHJhY2UoZGF0YSA9IGRhdGFfYWdnckxhVmlvbGEsIHk9flJlc2FtcGxpbmc0bXMuQXhlbE0sIG5hbWUgPSAnREVTUCA0IG1zJywgbGluZT1saXN0KGNvbG9yPScjQkREN0U3JyksIG1hcmtlcj1saXN0KGNvbG9yPScjQkREN0U3JyksCiAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JfeSA9IGxpc3Qoc3ltbWV0cmljPUYsIGFycmF5PX5jaVJlc2FtcGxpbmc0bXMuQXhlbC51cHBlci1SZXNhbXBsaW5nNG1zLkF4ZWxNLCBhcnJheW1pbnVzPX5SZXNhbXBsaW5nNG1zLkF4ZWxNLWNpUmVzYW1wbGluZzRtcy5BeGVsLmxvd2VyLCBjb2xvciA9ICcjMDAwMDAwJykpICU+JQogIAogICAgICAgICAgICAgbGF5b3V0KHlheGlzID0gbGlzdCh0aXRsZSA9ICJTcGF0aWFsIGppdHRlciAocGl4ZWxzKSIsIHJhbmdlID0gYygwLDM1KSksCiAgICAgICAgICAgICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gJ091dHB1dCBmcmVxdWVuY3kgKEh6KScsIHR5cGUgPSAiY2F0ZWdvcnkiKSwKICAgICAgICAgICAgICAgICAgICBsZWdlbmQgPSBsaXN0KHggPSAxLCB5ID0gMC45NSwgYm9yZGVyY29sb3IgPSAiIzAwMCIsIGJvcmRlcndpZHRoPTIpLCAKICAgICAgICAgICAgICAgICAgICBmb250ID0gdCwgdGl0bGUgPSBsaXN0KGZvbnQgPSB0MikKICAgICAgICAgICAgICAgICAgICApCgoKcApvcmNhKHAsICJDb21wYXJpc29uUHJlZGljdG9ycy5wZGYiKQojaHRtbHdpZGdldHM6OnNhdmVXaWRnZXQocCwgZmlsZSA9ICdKaXR0ZXJCeWZyZXF1ZW5jeUF4ZWwuaHRtbCcpCmBgYAo=