Script to generate plots for the IEC2018 presentation about ATCHU

Libraries

library(librarian)
shelf(openair,
      reshape2,
      ggplot2,
      readr,
      latex2exp)
Warning in shelf(openair, reshape2, ggplot2, readr, latex2exp): cran_repo = '@CRAN@' is not a valid URL. 
                    Defaulting to cran_repo = 'https://cran.r-project.org'.

Load data

data.wide <- read_delim("~/data/ATCHU/ATCHU_dataset.csv",delim = ',',
                        col_types = cols(col_datetime(format = ""),
                                      col_double(),
                                      col_double(),
                                      col_double(),
                                      col_double(),
                                      col_double(),
                                      col_double(),
                                      col_double(),
                                      col_double(),
                                      col_double(),
                                      col_double(),
                                      col_double(),
                                      col_double(),
                                      col_double(),
                                      col_double(),
                                      col_double()))
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 16635 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                             expected   <int> <chr> <chr>      <chr>      <chr>                            actual 1     1 <NA>  16 columns 17 columns '~/data/ATCHU/ATCHU_dataset.csv' file 2     2 <NA>  16 columns 17 columns '~/data/ATCHU/ATCHU_dataset.csv' row 3     3 <NA>  16 columns 17 columns '~/data/ATCHU/ATCHU_dataset.csv' col 4     4 <NA>  16 columns 17 columns '~/data/ATCHU/ATCHU_dataset.csv' expected 5     5 <NA>  16 columns 17 columns '~/data/ATCHU/ATCHU_dataset.csv'
... ................. ... .................................................................... ........ .................................................................... ...... .................................................................... .... .................................................................... ... .................................................................... ... .................................................................... ........ ....................................................................
See problems(...) for more details.
attr(data.wide$date,"tzone") <- "NZST"

Calculate extra vars

data.wide$NOxHS <- data.wide$NOHS + data.wide$NO2HS
data.wide$NOxMP <- data.wide$NOMP + data.wide$NO2MP
data.wide$BC.NOxHS <- data.wide$BCHS / data.wide$NOxHS

Load Grimm data for HS

load("~/data/ATCHU/grimm_HS.RData")
Dp.HS <- Dp
names(grimm_dndlogdp.HS) <- c(names(grimm_dndlogdp.HS)[1:2],paste0("HS",names(grimm_dndlogdp.HS)[3:18]))
data.wide <- merge(data.wide,grimm_dndlogdp.HS,by = 'date',all = TRUE)

Load Grimm data for MP

load("~/data/ATCHU/grimm_MP.RData")
names(grimm_dndlogdp.MP) <- c(names(grimm_dndlogdp.MP)[1:2],paste0("MP",names(grimm_dndlogdp.MP)[3:33]))
data.wide <- merge(data.wide,grimm_dndlogdp.MP,by = 'date',all = TRUE)

Load SMPS data from UoA

load("~/data/ATCHU/smps_UA.RData")
Dp.smps.UA <- Dp.UA
data.wide <- merge(data.wide,smps_10min_wide,by = 'date',all = TRUE)

Load 2B NOx data from UoA

parsed2B <- read_csv("~/data/ATCHU/RAW/UoA/2BNOX/parsed2B.txt",
                     col_types = cols(date = col_datetime(format = "%Y/%m/%d %H:%M:%S GMT")))
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 1435 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1 11460 O3    an integer 4294966000 '~/data/ATCHU/RAW/UoA/2BNOX/parsed2B.… file 2 11461 O3    an integer 4294966000 '~/data/ATCHU/RAW/UoA/2BNOX/parsed2B.… row 3 11462 O3    an integer 4294966000 '~/data/ATCHU/RAW/UoA/2BNOX/parsed2B.… col 4 11463 O3    an integer 4294966000 '~/data/ATCHU/RAW/UoA/2BNOX/parsed2B.… expected 5 11464 O3    an integer 4294966000 '~/data/ATCHU/RAW/UoA/2BNOX/parsed2B.…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
nox.UA <- subset(parsed2B,(date < as.POSIXct("2015-04-29 20:00:00")))[,1:2]
names(nox.UA) <- c('date','NOx.UA')
data.wide <- merge(data.wide,nox.UA,by='date',all = TRUE)

Load Grimm data for UoA

load("~/data/ATCHU/grimm_UA.RData")
data.wide <- merge(data.wide,grimm_dndlogdp.UA, by = 'date', all = TRUE)

Average up to 1 hour

data.wide.1hr <- timeAverage(data.wide,avg.time = '1 hour')

Correcting the scales for the Grimm data

data.wide.1hr[,21:35] <- data.wide.1hr[,21:35] / 10 # Halsley Drive
data.wide.1hr[,38:68] <- data.wide.1hr[,38:68] / 100 # Musick Point
data.wide.1hr[,172:202] <- data.wide.1hr[,172:202] / 100 #Auckland University

Plots

All pollution roses are normalised so that the fraction of measurements of certain level is shown.

Describe Halsley Drive

HSn300 = dN/dlogDp at 300nm from the Grimm

timePlot(data.wide.1hr,pollutant = c('BCHS','NOHS','NO2HS','O3HS','wsHS','HSn300') , y.relation = 'free')

timeVariation(data.wide.1hr,
              pollutant = c('BCHS','NOxHS'),
              normalise = TRUE)

pollutionRose(data.wide.1hr,
              pollutant = 'BCHS',
              ws='wsHS',
              wd='wdHS',
              normalise = TRUE,
              cols = 'heat',
              breaks = c(0,500,1500,3000),
              statistic = 'prop.count')

pollutionRose(data.wide.1hr,
              pollutant = 'NOHS',
              ws='wsHS',
              wd='wdHS',
              normalise = TRUE,
              cols = 'heat',
              breaks = c(0,2,4,6),
              statistic = 'prop.count')

pollutionRose(data.wide.1hr,
              pollutant = 'HSn300',
              ws='wsHS',
              wd='wdHS',
              normalise = TRUE,
              cols = 'heat',
              breaks = c(0,2,4,6),
              statistic = 'prop.count')

Describe UoA

50 = dN/dLogDp at 50nm from the SMPS n265 = dN/dLogDp at 265nm from the Grimm

timePlot(data.wide.1hr,pollutant = c('NOx.UA','BCUoA','50','n265'),y.relation = 'free')

pollutionRose(data.wide.1hr,
              pollutant = 'BCUoA',
              ws='wsMP',
              wd='wdMP',
              normalise = TRUE,
              cols = 'heat',
              breaks = c(0,500,1500,3000),
              statistic = 'prop.count')

pollutionRose(data.wide.1hr,
              pollutant = 'NOx.UA',
              ws='wsMP',
              wd='wdMP',
              normalise = TRUE,
              cols = 'heat',
              breaks = c(0,2,5,10,20),
              statistic = 'prop.count')
Warning in windRose(mydata, pollutant = pollutant, paddle = paddle, seg =
seg, : Some values are below minimum break.

pollutionRose(data.wide.1hr,
              pollutant = '50',
              ws='wsMP',
              wd='wdMP',
              normalise = TRUE,
              cols = 'heat',
              statistic = 'prop.count')

pollutionRose(data.wide.1hr,
              pollutant = 'n265',
              ws='wsMP',
              wd='wdMP',
              normalise = TRUE,
              cols = 'heat',
              statistic = 'prop.count')

Describe Musick Point

n265 = dN/dLogDp at 265nm from the Grimm

timePlot(data.wide.1hr,pollutant = c('NOMP','NO2MP','N6MP','O3MP','wsMP','MPn265'),y.relation = 'free')

pollutionRose(data.wide.1hr,
              pollutant = 'NOMP',
              ws='wsMP',
              wd='wdMP',
              normalise = TRUE,
              cols = 'heat',
              breaks = c(0,2,4,6),
              statistic = 'prop.count')

pollutionRose(data.wide.1hr,
              pollutant = 'N6MP',
              ws='wsMP',
              wd='wdMP',
              normalise = TRUE,
              cols = 'heat',
              breaks = c(0,2000,5000,10000,20000),
              statistic = 'prop.count')

pollutionRose(data.wide.1hr,
              pollutant = 'MPn265',
              ws='wsMP',
              wd='wdMP',
              normalise = TRUE,
              cols = 'heat',
              statistic = 'prop.count')

Compare Size Distributions by wind sector

sw_sector.HS <- (data.wide.1hr$wdHS < 255) & (data.wide.1hr$wdHS > 195)
ne_sector.HS <- (data.wide.1hr$wdHS < 75) & (data.wide.1hr$wdHS > 15)
sizedist_sw.HS <- colMeans(data.wide.1hr[sw_sector.HS,21:35],na.rm = TRUE)
sizedist_ne.HS <- colMeans(data.wide.1hr[ne_sector.HS,21:35],na.rm = TRUE)

sw_sector.MP <- (data.wide.1hr$wdMP < 255) & (data.wide.1hr$wdMP > 195)
ne_sector.MP <- (data.wide.1hr$wdMP < 75) & (data.wide.1hr$wdMP > 15)
sizedist_sw.MP <- colMeans(data.wide.1hr[sw_sector.MP,38:68],na.rm = TRUE)
sizedist_ne.MP <- colMeans(data.wide.1hr[ne_sector.MP,38:68],na.rm = TRUE)

sizedist_sw.UA <- colMeans(data.wide.1hr[sw_sector.MP,70:169], na.rm = TRUE)
sizedist_ne.UA <- colMeans(data.wide.1hr[ne_sector.MP,70:169], na.rm = TRUE)

sizedist_sw.grimm.UA <- colMeans(data.wide.1hr[sw_sector.MP,172:202], na.rm = TRUE)
sizedist_ne.grimm.UA <- colMeans(data.wide.1hr[ne_sector.MP,172:202], na.rm = TRUE)

NOxsizedist_sw.UA <- colMeans(data.wide.1hr[sw_sector.MP,70:169]/data.wide.1hr$NOx.UA[sw_sector.MP], na.rm = TRUE)
NOxsizedist_ne.UA <- colMeans(data.wide.1hr[ne_sector.MP,70:169]/data.wide.1hr$NOx.UA[ne_sector.MP], na.rm = TRUE)

cbbPalette <- c("#000000", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7")

Comparing size distribution between Grimm and SMPS at the university (Sanity check)

sanity1 <- timeAverage(smps_10min_wide,avg.time = '1 hour')
sanity2 <- timeAverage(grimm_dndlogdp.UA,avg.time = '1 hour')
sanity.check <- merge(sanity1,sanity2,by = 'date')

sanity.sizedist_sw.UA <- colMeans(sanity.check[,3:102], na.rm = TRUE)
sanity.sizedist_sw.grimm.UA <- colMeans(sanity.check[,104:134], na.rm = TRUE) / 100
ggplot() +
  geom_line(aes(x=Dp.smps.UA,y=sanity.sizedist_sw.UA,colour = 'UoA SMPS')) +
  geom_line(aes(x=Dp.UA,y=sanity.sizedist_sw.grimm.UA,colour = 'UoA Grimm')) +
  scale_y_continuous(trans = 'log10') +
  scale_x_continuous(trans = 'log10') +
  scale_colour_manual(values = cbbPalette) +
  ylab(TeX("$(\\frac{dN}{dlogD_p})\\[pt/cc\\]$")) + 
  xlab(TeX("$D_p\\[nm\\]"))

University roof

ggplot() +
  geom_line(aes(x=Dp.smps.UA,y=sizedist_ne.UA,colour = 'UoA North-East (smps)')) +
  geom_line(aes(x=Dp.smps.UA,y=sizedist_sw.UA,colour = 'UoA South-West (smps)')) +
  geom_line(aes(x=Dp.UA,y=sizedist_ne.grimm.UA,colour = 'UoA North-East (grimm)')) +
  geom_line(aes(x=Dp.UA,y=sizedist_sw.grimm.UA,colour = 'UoA South-West (grimm)')) +
  #geom_line(aes(x=Dp.HS,y=sizedist_sw.HS,colour = 'HS South-West')) +
  #geom_line(aes(x=Dp.HS,y=sizedist_ne.HS,colour = 'HS North-East')) +
#  geom_line(aes(x=Dp.MP,y=sizedist_sw.MP,colour = 'MP South-West (grimm)')) +
#  geom_line(aes(x=Dp.MP,y=sizedist_ne.MP,colour = 'MP North-East (grimm)')) +
  scale_y_continuous(trans = 'log10') +
  scale_x_continuous(trans = 'log10') +
  scale_colour_manual(values = cbbPalette) +
  ylab(TeX("$(\\frac{dN}{dlogD_p})\\[pt/cc\\]$")) + 
  xlab(TeX("$D_p\\[nm\\]"))
Warning: Transformation introduced infinite values in continuous y-axis
Warning: Removed 1 rows containing missing values (geom_path).

Musick Point

ggplot() +
  #geom_line(aes(x=Dp.smps.UA,y=sizedist_ne.UA,colour = 'UoA North-East (smps)')) +
  #geom_line(aes(x=Dp.smps.UA,y=sizedist_sw.UA,colour = 'UoA South-West (smps)')) +
  #geom_line(aes(x=Dp.HS,y=sizedist_sw.HS,colour = 'HS South-West')) +
  #geom_line(aes(x=Dp.HS,y=sizedist_ne.HS,colour = 'HS North-East')) +
  geom_line(aes(x=Dp.MP,y=sizedist_sw.MP,colour = 'MP South-West (grimm)')) +
  geom_line(aes(x=Dp.MP,y=sizedist_ne.MP,colour = 'MP North-East (grimm)')) +
  scale_y_continuous(trans = 'log10') +
  scale_x_continuous(trans = 'log10') +
  scale_colour_manual(values = cbbPalette) +
  ylab(TeX("$(\\frac{dN}{dlogD_p})\\[pt/cc\\]$")) + 
  xlab(TeX("$D_p\\[nm\\]"))

Halsley School

ggplot() +
  #geom_line(aes(x=Dp.smps.UA,y=sizedist_ne.UA,colour = 'UoA North-East (smps)')) +
  #geom_line(aes(x=Dp.smps.UA,y=sizedist_sw.UA,colour = 'UoA South-West (smps)')) +
  geom_line(aes(x=Dp.HS,y=sizedist_sw.HS,colour = 'HS South-West')) +
  geom_line(aes(x=Dp.HS,y=sizedist_ne.HS,colour = 'HS North-East')) +
  #geom_line(aes(x=Dp.MP,y=sizedist_sw.MP,colour = 'MP South-West')) +
  #geom_line(aes(x=Dp.MP,y=sizedist_ne.MP,colour = 'MP North-East')) +
  scale_y_continuous(trans = 'log10') +
  scale_x_continuous(trans = 'log10') +
  scale_colour_manual(values = cbbPalette)
Warning: Removed 3 rows containing missing values (geom_path).
Warning: Removed 2 rows containing missing values (geom_path).

Halsley School and Musick Point

ggplot() +
#  geom_line(aes(x=Dp.smps.UA,y=sizedist_ne.UA,colour = 'UoA North-East')) +
#  geom_line(aes(x=Dp.smps.UA,y=sizedist_sw.UA,colour = 'UoA South-West')) +
  geom_line(aes(x=Dp.HS,y=sizedist_sw.HS,colour = 'HS South-West')) +
  geom_line(aes(x=Dp.HS,y=sizedist_ne.HS,colour = 'HS North-East')) +
  geom_line(aes(x=Dp.MP,y=sizedist_sw.MP,colour = 'MP South-West')) +
  geom_line(aes(x=Dp.MP,y=sizedist_ne.MP,colour = 'MP North-East')) +
  scale_y_continuous(trans = 'log10') +
  scale_x_continuous(trans = 'log10') +
  scale_colour_manual(values = cbbPalette)
Warning: Removed 3 rows containing missing values (geom_path).
Warning: Removed 2 rows containing missing values (geom_path).

Musick Point and Auckland University

ggplot() +
  geom_line(aes(x=Dp.smps.UA,y=sizedist_ne.UA,colour = 'UoA North-East')) +
  geom_line(aes(x=Dp.smps.UA,y=sizedist_sw.UA,colour = 'UoA South-West')) +
  geom_line(aes(x=Dp.UA,y=sizedist_ne.grimm.UA,colour = 'UoA North-East')) +
  geom_line(aes(x=Dp.UA,y=sizedist_sw.grimm.UA,colour = 'UoA South-West')) +
  #geom_line(aes(x=Dp.HS,y=sizedist_sw.HS,colour = 'HS South-West')) +
  #geom_line(aes(x=Dp.HS,y=sizedist_ne.HS,colour = 'HS North-East')) +
  geom_line(aes(x=Dp.MP,y=sizedist_sw.MP,colour = 'MP South-West')) +
  geom_line(aes(x=Dp.MP,y=sizedist_ne.MP,colour = 'MP North-East')) +
  scale_y_continuous(trans = 'log10') +
  scale_x_continuous(trans = 'log10') +
  scale_colour_manual(values = cbbPalette) +
  ylab(TeX("$(\\frac{dN}{dlogD_p})\\[pt/cc\\]$")) + 
  xlab(TeX("$D_p\\[nm\\]"))
Warning: Transformation introduced infinite values in continuous y-axis
Warning: Removed 1 rows containing missing values (geom_path).

(dN/dlogDp)/NOx at University

ggplot() +
  geom_line(aes(x=Dp.smps.UA,y=NOxsizedist_ne.UA,colour = 'UoA North-East')) +
  geom_line(aes(x=Dp.smps.UA,y=NOxsizedist_sw.UA,colour = 'UoA South-West')) +
  scale_y_continuous(trans = 'log10') +
  scale_x_continuous(trans = 'log10') +
  scale_colour_manual(values = cbbPalette) +
  ylab(TeX("$\\frac{(\\frac{dN}{dlogD_p})}{NO_X}\\[pt/cc\\]$")) + 
  xlab(TeX("$D_p\\[nm\\]"))

IycgLS0tCiMndGl0bGU6ICJJRUMgMjAxOCBwbG90cyIKIydvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKIydhdXRob3I6IEd1c3Rhdm8gT2xpdmFyZXMKIyctLS0KIycKIycKIycgU2NyaXB0IHRvIGdlbmVyYXRlIHBsb3RzIGZvciB0aGUgSUVDMjAxOCBwcmVzZW50YXRpb24gYWJvdXQgQVRDSFUKIycgCgojJyAjIExpYnJhcmllcyAjIyMjCmxpYnJhcnkobGlicmFyaWFuKQpzaGVsZihvcGVuYWlyLAogICAgICByZXNoYXBlMiwKICAgICAgZ2dwbG90MiwKICAgICAgcmVhZHIsCiAgICAgIGxhdGV4MmV4cCkKIycgIyBMb2FkIGRhdGEgIyMjIwpkYXRhLndpZGUgPC0gcmVhZF9kZWxpbSgifi9kYXRhL0FUQ0hVL0FUQ0hVX2RhdGFzZXQuY3N2IixkZWxpbSA9ICcsJywKICAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gY29scyhjb2xfZGF0ZXRpbWUoZm9ybWF0ID0gIiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF9kb3VibGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfZG91YmxlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX2RvdWJsZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF9kb3VibGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfZG91YmxlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX2RvdWJsZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF9kb3VibGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfZG91YmxlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX2RvdWJsZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF9kb3VibGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfZG91YmxlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX2RvdWJsZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF9kb3VibGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfZG91YmxlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX2RvdWJsZSgpKSkKYXR0cihkYXRhLndpZGUkZGF0ZSwidHpvbmUiKSA8LSAiTlpTVCIKCiMnICMjIENhbGN1bGF0ZSBleHRyYSB2YXJzCmRhdGEud2lkZSROT3hIUyA8LSBkYXRhLndpZGUkTk9IUyArIGRhdGEud2lkZSROTzJIUwpkYXRhLndpZGUkTk94TVAgPC0gZGF0YS53aWRlJE5PTVAgKyBkYXRhLndpZGUkTk8yTVAKZGF0YS53aWRlJEJDLk5PeEhTIDwtIGRhdGEud2lkZSRCQ0hTIC8gZGF0YS53aWRlJE5PeEhTCiMnICMjIExvYWQgR3JpbW0gZGF0YSBmb3IgSFMKbG9hZCgifi9kYXRhL0FUQ0hVL2dyaW1tX0hTLlJEYXRhIikKRHAuSFMgPC0gRHAKbmFtZXMoZ3JpbW1fZG5kbG9nZHAuSFMpIDwtIGMobmFtZXMoZ3JpbW1fZG5kbG9nZHAuSFMpWzE6Ml0scGFzdGUwKCJIUyIsbmFtZXMoZ3JpbW1fZG5kbG9nZHAuSFMpWzM6MThdKSkKZGF0YS53aWRlIDwtIG1lcmdlKGRhdGEud2lkZSxncmltbV9kbmRsb2dkcC5IUyxieSA9ICdkYXRlJyxhbGwgPSBUUlVFKQoKIycgIyMgTG9hZCBHcmltbSBkYXRhIGZvciBNUApsb2FkKCJ+L2RhdGEvQVRDSFUvZ3JpbW1fTVAuUkRhdGEiKQpuYW1lcyhncmltbV9kbmRsb2dkcC5NUCkgPC0gYyhuYW1lcyhncmltbV9kbmRsb2dkcC5NUClbMToyXSxwYXN0ZTAoIk1QIixuYW1lcyhncmltbV9kbmRsb2dkcC5NUClbMzozM10pKQpkYXRhLndpZGUgPC0gbWVyZ2UoZGF0YS53aWRlLGdyaW1tX2RuZGxvZ2RwLk1QLGJ5ID0gJ2RhdGUnLGFsbCA9IFRSVUUpCgojJyAjIyBMb2FkIFNNUFMgZGF0YSBmcm9tIFVvQQpsb2FkKCJ+L2RhdGEvQVRDSFUvc21wc19VQS5SRGF0YSIpCkRwLnNtcHMuVUEgPC0gRHAuVUEKZGF0YS53aWRlIDwtIG1lcmdlKGRhdGEud2lkZSxzbXBzXzEwbWluX3dpZGUsYnkgPSAnZGF0ZScsYWxsID0gVFJVRSkKCiMnICMjIExvYWQgMkIgTk94IGRhdGEgZnJvbSBVb0EKcGFyc2VkMkIgPC0gcmVhZF9jc3YoIn4vZGF0YS9BVENIVS9SQVcvVW9BLzJCTk9YL3BhcnNlZDJCLnR4dCIsCiAgICAgICAgICAgICAgICAgICAgIGNvbF90eXBlcyA9IGNvbHMoZGF0ZSA9IGNvbF9kYXRldGltZShmb3JtYXQgPSAiJVkvJW0vJWQgJUg6JU06JVMgR01UIikpKQpub3guVUEgPC0gc3Vic2V0KHBhcnNlZDJCLChkYXRlIDwgYXMuUE9TSVhjdCgiMjAxNS0wNC0yOSAyMDowMDowMCIpKSlbLDE6Ml0KbmFtZXMobm94LlVBKSA8LSBjKCdkYXRlJywnTk94LlVBJykKZGF0YS53aWRlIDwtIG1lcmdlKGRhdGEud2lkZSxub3guVUEsYnk9J2RhdGUnLGFsbCA9IFRSVUUpCgojJyAjIyBMb2FkIEdyaW1tIGRhdGEgZm9yIFVvQQpsb2FkKCJ+L2RhdGEvQVRDSFUvZ3JpbW1fVUEuUkRhdGEiKQpkYXRhLndpZGUgPC0gbWVyZ2UoZGF0YS53aWRlLGdyaW1tX2RuZGxvZ2RwLlVBLCBieSA9ICdkYXRlJywgYWxsID0gVFJVRSkKCiMnICMjIEF2ZXJhZ2UgdXAgdG8gMSBob3VyCmRhdGEud2lkZS4xaHIgPC0gdGltZUF2ZXJhZ2UoZGF0YS53aWRlLGF2Zy50aW1lID0gJzEgaG91cicpCiMnICMjIyBDb3JyZWN0aW5nIHRoZSBzY2FsZXMgZm9yIHRoZSBHcmltbSBkYXRhCmRhdGEud2lkZS4xaHJbLDIxOjM1XSA8LSBkYXRhLndpZGUuMWhyWywyMTozNV0gLyAxMCAjIEhhbHNsZXkgRHJpdmUKZGF0YS53aWRlLjFoclssMzg6NjhdIDwtIGRhdGEud2lkZS4xaHJbLDM4OjY4XSAvIDEwMCAjIE11c2ljayBQb2ludApkYXRhLndpZGUuMWhyWywxNzI6MjAyXSA8LSBkYXRhLndpZGUuMWhyWywxNzI6MjAyXSAvIDEwMCAjQXVja2xhbmQgVW5pdmVyc2l0eQoKIycgIyBQbG90cyAjIyMjCiMnIEFsbCBwb2xsdXRpb24gcm9zZXMgYXJlIG5vcm1hbGlzZWQgc28gdGhhdCB0aGUgZnJhY3Rpb24gb2YgbWVhc3VyZW1lbnRzIG9mIGNlcnRhaW4gbGV2ZWwgaXMgc2hvd24uCiMnIAoKIycgIyMgRGVzY3JpYmUgSGFsc2xleSBEcml2ZSAjIyMjCiMnIEhTbjMwMCA9IGROL2Rsb2dEcCBhdCAzMDBubSBmcm9tIHRoZSBHcmltbQoKdGltZVBsb3QoZGF0YS53aWRlLjFocixwb2xsdXRhbnQgPSBjKCdCQ0hTJywnTk9IUycsJ05PMkhTJywnTzNIUycsJ3dzSFMnLCdIU24zMDAnKSAsIHkucmVsYXRpb24gPSAnZnJlZScpCgp0aW1lVmFyaWF0aW9uKGRhdGEud2lkZS4xaHIsCiAgICAgICAgICAgICAgcG9sbHV0YW50ID0gYygnQkNIUycsJ05PeEhTJyksCiAgICAgICAgICAgICAgbm9ybWFsaXNlID0gVFJVRSkKCnBvbGx1dGlvblJvc2UoZGF0YS53aWRlLjFociwKICAgICAgICAgICAgICBwb2xsdXRhbnQgPSAnQkNIUycsCiAgICAgICAgICAgICAgd3M9J3dzSFMnLAogICAgICAgICAgICAgIHdkPSd3ZEhTJywKICAgICAgICAgICAgICBub3JtYWxpc2UgPSBUUlVFLAogICAgICAgICAgICAgIGNvbHMgPSAnaGVhdCcsCiAgICAgICAgICAgICAgYnJlYWtzID0gYygwLDUwMCwxNTAwLDMwMDApLAogICAgICAgICAgICAgIHN0YXRpc3RpYyA9ICdwcm9wLmNvdW50JykKCnBvbGx1dGlvblJvc2UoZGF0YS53aWRlLjFociwKICAgICAgICAgICAgICBwb2xsdXRhbnQgPSAnTk9IUycsCiAgICAgICAgICAgICAgd3M9J3dzSFMnLAogICAgICAgICAgICAgIHdkPSd3ZEhTJywKICAgICAgICAgICAgICBub3JtYWxpc2UgPSBUUlVFLAogICAgICAgICAgICAgIGNvbHMgPSAnaGVhdCcsCiAgICAgICAgICAgICAgYnJlYWtzID0gYygwLDIsNCw2KSwKICAgICAgICAgICAgICBzdGF0aXN0aWMgPSAncHJvcC5jb3VudCcpCgpwb2xsdXRpb25Sb3NlKGRhdGEud2lkZS4xaHIsCiAgICAgICAgICAgICAgcG9sbHV0YW50ID0gJ0hTbjMwMCcsCiAgICAgICAgICAgICAgd3M9J3dzSFMnLAogICAgICAgICAgICAgIHdkPSd3ZEhTJywKICAgICAgICAgICAgICBub3JtYWxpc2UgPSBUUlVFLAogICAgICAgICAgICAgIGNvbHMgPSAnaGVhdCcsCiAgICAgICAgICAgICAgYnJlYWtzID0gYygwLDIsNCw2KSwKICAgICAgICAgICAgICBzdGF0aXN0aWMgPSAncHJvcC5jb3VudCcpCgoKIycgIyMgRGVzY3JpYmUgVW9BICMjIyMKIycgNTAgPSBkTi9kTG9nRHAgYXQgNTBubSBmcm9tIHRoZSBTTVBTCiMnIG4yNjUgPSBkTi9kTG9nRHAgYXQgMjY1bm0gZnJvbSB0aGUgR3JpbW0KdGltZVBsb3QoZGF0YS53aWRlLjFocixwb2xsdXRhbnQgPSBjKCdOT3guVUEnLCdCQ1VvQScsJzUwJywnbjI2NScpLHkucmVsYXRpb24gPSAnZnJlZScpCgpwb2xsdXRpb25Sb3NlKGRhdGEud2lkZS4xaHIsCiAgICAgICAgICAgICAgcG9sbHV0YW50ID0gJ0JDVW9BJywKICAgICAgICAgICAgICB3cz0nd3NNUCcsCiAgICAgICAgICAgICAgd2Q9J3dkTVAnLAogICAgICAgICAgICAgIG5vcm1hbGlzZSA9IFRSVUUsCiAgICAgICAgICAgICAgY29scyA9ICdoZWF0JywKICAgICAgICAgICAgICBicmVha3MgPSBjKDAsNTAwLDE1MDAsMzAwMCksCiAgICAgICAgICAgICAgc3RhdGlzdGljID0gJ3Byb3AuY291bnQnKQoKcG9sbHV0aW9uUm9zZShkYXRhLndpZGUuMWhyLAogICAgICAgICAgICAgIHBvbGx1dGFudCA9ICdOT3guVUEnLAogICAgICAgICAgICAgIHdzPSd3c01QJywKICAgICAgICAgICAgICB3ZD0nd2RNUCcsCiAgICAgICAgICAgICAgbm9ybWFsaXNlID0gVFJVRSwKICAgICAgICAgICAgICBjb2xzID0gJ2hlYXQnLAogICAgICAgICAgICAgIGJyZWFrcyA9IGMoMCwyLDUsMTAsMjApLAogICAgICAgICAgICAgIHN0YXRpc3RpYyA9ICdwcm9wLmNvdW50JykKcG9sbHV0aW9uUm9zZShkYXRhLndpZGUuMWhyLAogICAgICAgICAgICAgIHBvbGx1dGFudCA9ICc1MCcsCiAgICAgICAgICAgICAgd3M9J3dzTVAnLAogICAgICAgICAgICAgIHdkPSd3ZE1QJywKICAgICAgICAgICAgICBub3JtYWxpc2UgPSBUUlVFLAogICAgICAgICAgICAgIGNvbHMgPSAnaGVhdCcsCiAgICAgICAgICAgICAgc3RhdGlzdGljID0gJ3Byb3AuY291bnQnKQpwb2xsdXRpb25Sb3NlKGRhdGEud2lkZS4xaHIsCiAgICAgICAgICAgICAgcG9sbHV0YW50ID0gJ24yNjUnLAogICAgICAgICAgICAgIHdzPSd3c01QJywKICAgICAgICAgICAgICB3ZD0nd2RNUCcsCiAgICAgICAgICAgICAgbm9ybWFsaXNlID0gVFJVRSwKICAgICAgICAgICAgICBjb2xzID0gJ2hlYXQnLAogICAgICAgICAgICAgIHN0YXRpc3RpYyA9ICdwcm9wLmNvdW50JykKCiMnICMjIERlc2NyaWJlIE11c2ljayBQb2ludCAjIyMjCiMnIG4yNjUgPSBkTi9kTG9nRHAgYXQgMjY1bm0gZnJvbSB0aGUgR3JpbW0KdGltZVBsb3QoZGF0YS53aWRlLjFocixwb2xsdXRhbnQgPSBjKCdOT01QJywnTk8yTVAnLCdONk1QJywnTzNNUCcsJ3dzTVAnLCdNUG4yNjUnKSx5LnJlbGF0aW9uID0gJ2ZyZWUnKQoKcG9sbHV0aW9uUm9zZShkYXRhLndpZGUuMWhyLAogICAgICAgICAgICAgIHBvbGx1dGFudCA9ICdOT01QJywKICAgICAgICAgICAgICB3cz0nd3NNUCcsCiAgICAgICAgICAgICAgd2Q9J3dkTVAnLAogICAgICAgICAgICAgIG5vcm1hbGlzZSA9IFRSVUUsCiAgICAgICAgICAgICAgY29scyA9ICdoZWF0JywKICAgICAgICAgICAgICBicmVha3MgPSBjKDAsMiw0LDYpLAogICAgICAgICAgICAgIHN0YXRpc3RpYyA9ICdwcm9wLmNvdW50JykKCnBvbGx1dGlvblJvc2UoZGF0YS53aWRlLjFociwKICAgICAgICAgICAgICBwb2xsdXRhbnQgPSAnTjZNUCcsCiAgICAgICAgICAgICAgd3M9J3dzTVAnLAogICAgICAgICAgICAgIHdkPSd3ZE1QJywKICAgICAgICAgICAgICBub3JtYWxpc2UgPSBUUlVFLAogICAgICAgICAgICAgIGNvbHMgPSAnaGVhdCcsCiAgICAgICAgICAgICAgYnJlYWtzID0gYygwLDIwMDAsNTAwMCwxMDAwMCwyMDAwMCksCiAgICAgICAgICAgICAgc3RhdGlzdGljID0gJ3Byb3AuY291bnQnKQpwb2xsdXRpb25Sb3NlKGRhdGEud2lkZS4xaHIsCiAgICAgICAgICAgICAgcG9sbHV0YW50ID0gJ01QbjI2NScsCiAgICAgICAgICAgICAgd3M9J3dzTVAnLAogICAgICAgICAgICAgIHdkPSd3ZE1QJywKICAgICAgICAgICAgICBub3JtYWxpc2UgPSBUUlVFLAogICAgICAgICAgICAgIGNvbHMgPSAnaGVhdCcsCiAgICAgICAgICAgICAgc3RhdGlzdGljID0gJ3Byb3AuY291bnQnKQoKIycgIyMgQ29tcGFyZSBTaXplIERpc3RyaWJ1dGlvbnMgYnkgd2luZCBzZWN0b3IKc3dfc2VjdG9yLkhTIDwtIChkYXRhLndpZGUuMWhyJHdkSFMgPCAyNTUpICYgKGRhdGEud2lkZS4xaHIkd2RIUyA+IDE5NSkKbmVfc2VjdG9yLkhTIDwtIChkYXRhLndpZGUuMWhyJHdkSFMgPCA3NSkgJiAoZGF0YS53aWRlLjFociR3ZEhTID4gMTUpCnNpemVkaXN0X3N3LkhTIDwtIGNvbE1lYW5zKGRhdGEud2lkZS4xaHJbc3dfc2VjdG9yLkhTLDIxOjM1XSxuYS5ybSA9IFRSVUUpCnNpemVkaXN0X25lLkhTIDwtIGNvbE1lYW5zKGRhdGEud2lkZS4xaHJbbmVfc2VjdG9yLkhTLDIxOjM1XSxuYS5ybSA9IFRSVUUpCgpzd19zZWN0b3IuTVAgPC0gKGRhdGEud2lkZS4xaHIkd2RNUCA8IDI1NSkgJiAoZGF0YS53aWRlLjFociR3ZE1QID4gMTk1KQpuZV9zZWN0b3IuTVAgPC0gKGRhdGEud2lkZS4xaHIkd2RNUCA8IDc1KSAmIChkYXRhLndpZGUuMWhyJHdkTVAgPiAxNSkKc2l6ZWRpc3Rfc3cuTVAgPC0gY29sTWVhbnMoZGF0YS53aWRlLjFocltzd19zZWN0b3IuTVAsMzg6NjhdLG5hLnJtID0gVFJVRSkKc2l6ZWRpc3RfbmUuTVAgPC0gY29sTWVhbnMoZGF0YS53aWRlLjFocltuZV9zZWN0b3IuTVAsMzg6NjhdLG5hLnJtID0gVFJVRSkKCnNpemVkaXN0X3N3LlVBIDwtIGNvbE1lYW5zKGRhdGEud2lkZS4xaHJbc3dfc2VjdG9yLk1QLDcwOjE2OV0sIG5hLnJtID0gVFJVRSkKc2l6ZWRpc3RfbmUuVUEgPC0gY29sTWVhbnMoZGF0YS53aWRlLjFocltuZV9zZWN0b3IuTVAsNzA6MTY5XSwgbmEucm0gPSBUUlVFKQoKc2l6ZWRpc3Rfc3cuZ3JpbW0uVUEgPC0gY29sTWVhbnMoZGF0YS53aWRlLjFocltzd19zZWN0b3IuTVAsMTcyOjIwMl0sIG5hLnJtID0gVFJVRSkKc2l6ZWRpc3RfbmUuZ3JpbW0uVUEgPC0gY29sTWVhbnMoZGF0YS53aWRlLjFocltuZV9zZWN0b3IuTVAsMTcyOjIwMl0sIG5hLnJtID0gVFJVRSkKCk5PeHNpemVkaXN0X3N3LlVBIDwtIGNvbE1lYW5zKGRhdGEud2lkZS4xaHJbc3dfc2VjdG9yLk1QLDcwOjE2OV0vZGF0YS53aWRlLjFociROT3guVUFbc3dfc2VjdG9yLk1QXSwgbmEucm0gPSBUUlVFKQpOT3hzaXplZGlzdF9uZS5VQSA8LSBjb2xNZWFucyhkYXRhLndpZGUuMWhyW25lX3NlY3Rvci5NUCw3MDoxNjldL2RhdGEud2lkZS4xaHIkTk94LlVBW25lX3NlY3Rvci5NUF0sIG5hLnJtID0gVFJVRSkKCmNiYlBhbGV0dGUgPC0gYygiIzAwMDAwMCIsICIjRTY5RjAwIiwgIiM1NkI0RTkiLCAiIzAwOUU3MyIsICIjRjBFNDQyIiwgIiMwMDcyQjIiLCAiI0Q1NUUwMCIsICIjQ0M3OUE3IikKCiMnICMjIyBDb21wYXJpbmcgc2l6ZSBkaXN0cmlidXRpb24gYmV0d2VlbiBHcmltbSBhbmQgU01QUyBhdCB0aGUgdW5pdmVyc2l0eSAoU2FuaXR5IGNoZWNrKQpzYW5pdHkxIDwtIHRpbWVBdmVyYWdlKHNtcHNfMTBtaW5fd2lkZSxhdmcudGltZSA9ICcxIGhvdXInKQpzYW5pdHkyIDwtIHRpbWVBdmVyYWdlKGdyaW1tX2RuZGxvZ2RwLlVBLGF2Zy50aW1lID0gJzEgaG91cicpCnNhbml0eS5jaGVjayA8LSBtZXJnZShzYW5pdHkxLHNhbml0eTIsYnkgPSAnZGF0ZScpCgpzYW5pdHkuc2l6ZWRpc3Rfc3cuVUEgPC0gY29sTWVhbnMoc2FuaXR5LmNoZWNrWywzOjEwMl0sIG5hLnJtID0gVFJVRSkKc2FuaXR5LnNpemVkaXN0X3N3LmdyaW1tLlVBIDwtIGNvbE1lYW5zKHNhbml0eS5jaGVja1ssMTA0OjEzNF0sIG5hLnJtID0gVFJVRSkgLyAxMDAKZ2dwbG90KCkgKwogIGdlb21fbGluZShhZXMoeD1EcC5zbXBzLlVBLHk9c2FuaXR5LnNpemVkaXN0X3N3LlVBLGNvbG91ciA9ICdVb0EgU01QUycpKSArCiAgZ2VvbV9saW5lKGFlcyh4PURwLlVBLHk9c2FuaXR5LnNpemVkaXN0X3N3LmdyaW1tLlVBLGNvbG91ciA9ICdVb0EgR3JpbW0nKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICdsb2cxMCcpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAnbG9nMTAnKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjYmJQYWxldHRlKSArCiAgeWxhYihUZVgoIiQoXFxmcmFje2ROfXtkbG9nRF9wfSlcXFtwdC9jY1xcXSQiKSkgKyAKICB4bGFiKFRlWCgiJERfcFxcW25tXFxdIikpCgoKCiMnICMjIyBVbml2ZXJzaXR5IHJvb2YgCmdncGxvdCgpICsKICBnZW9tX2xpbmUoYWVzKHg9RHAuc21wcy5VQSx5PXNpemVkaXN0X25lLlVBLGNvbG91ciA9ICdVb0EgTm9ydGgtRWFzdCAoc21wcyknKSkgKwogIGdlb21fbGluZShhZXMoeD1EcC5zbXBzLlVBLHk9c2l6ZWRpc3Rfc3cuVUEsY29sb3VyID0gJ1VvQSBTb3V0aC1XZXN0IChzbXBzKScpKSArCiAgZ2VvbV9saW5lKGFlcyh4PURwLlVBLHk9c2l6ZWRpc3RfbmUuZ3JpbW0uVUEsY29sb3VyID0gJ1VvQSBOb3J0aC1FYXN0IChncmltbSknKSkgKwogIGdlb21fbGluZShhZXMoeD1EcC5VQSx5PXNpemVkaXN0X3N3LmdyaW1tLlVBLGNvbG91ciA9ICdVb0EgU291dGgtV2VzdCAoZ3JpbW0pJykpICsKICAjZ2VvbV9saW5lKGFlcyh4PURwLkhTLHk9c2l6ZWRpc3Rfc3cuSFMsY29sb3VyID0gJ0hTIFNvdXRoLVdlc3QnKSkgKwogICNnZW9tX2xpbmUoYWVzKHg9RHAuSFMseT1zaXplZGlzdF9uZS5IUyxjb2xvdXIgPSAnSFMgTm9ydGgtRWFzdCcpKSArCiMgIGdlb21fbGluZShhZXMoeD1EcC5NUCx5PXNpemVkaXN0X3N3Lk1QLGNvbG91ciA9ICdNUCBTb3V0aC1XZXN0IChncmltbSknKSkgKwojICBnZW9tX2xpbmUoYWVzKHg9RHAuTVAseT1zaXplZGlzdF9uZS5NUCxjb2xvdXIgPSAnTVAgTm9ydGgtRWFzdCAoZ3JpbW0pJykpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAnbG9nMTAnKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gJ2xvZzEwJykgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gY2JiUGFsZXR0ZSkgKwogIHlsYWIoVGVYKCIkKFxcZnJhY3tkTn17ZGxvZ0RfcH0pXFxbcHQvY2NcXF0kIikpICsgCiAgeGxhYihUZVgoIiREX3BcXFtubVxcXSIpKQoKIycgIyMjIE11c2ljayBQb2ludAoKZ2dwbG90KCkgKwogICNnZW9tX2xpbmUoYWVzKHg9RHAuc21wcy5VQSx5PXNpemVkaXN0X25lLlVBLGNvbG91ciA9ICdVb0EgTm9ydGgtRWFzdCAoc21wcyknKSkgKwogICNnZW9tX2xpbmUoYWVzKHg9RHAuc21wcy5VQSx5PXNpemVkaXN0X3N3LlVBLGNvbG91ciA9ICdVb0EgU291dGgtV2VzdCAoc21wcyknKSkgKwogICNnZW9tX2xpbmUoYWVzKHg9RHAuSFMseT1zaXplZGlzdF9zdy5IUyxjb2xvdXIgPSAnSFMgU291dGgtV2VzdCcpKSArCiAgI2dlb21fbGluZShhZXMoeD1EcC5IUyx5PXNpemVkaXN0X25lLkhTLGNvbG91ciA9ICdIUyBOb3J0aC1FYXN0JykpICsKICBnZW9tX2xpbmUoYWVzKHg9RHAuTVAseT1zaXplZGlzdF9zdy5NUCxjb2xvdXIgPSAnTVAgU291dGgtV2VzdCAoZ3JpbW0pJykpICsKICBnZW9tX2xpbmUoYWVzKHg9RHAuTVAseT1zaXplZGlzdF9uZS5NUCxjb2xvdXIgPSAnTVAgTm9ydGgtRWFzdCAoZ3JpbW0pJykpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAnbG9nMTAnKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gJ2xvZzEwJykgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gY2JiUGFsZXR0ZSkgKwogIHlsYWIoVGVYKCIkKFxcZnJhY3tkTn17ZGxvZ0RfcH0pXFxbcHQvY2NcXF0kIikpICsgCiAgeGxhYihUZVgoIiREX3BcXFtubVxcXSIpKQoKIycgIyMjIEhhbHNsZXkgU2Nob29sCmdncGxvdCgpICsKICAjZ2VvbV9saW5lKGFlcyh4PURwLnNtcHMuVUEseT1zaXplZGlzdF9uZS5VQSxjb2xvdXIgPSAnVW9BIE5vcnRoLUVhc3QgKHNtcHMpJykpICsKICAjZ2VvbV9saW5lKGFlcyh4PURwLnNtcHMuVUEseT1zaXplZGlzdF9zdy5VQSxjb2xvdXIgPSAnVW9BIFNvdXRoLVdlc3QgKHNtcHMpJykpICsKICBnZW9tX2xpbmUoYWVzKHg9RHAuSFMseT1zaXplZGlzdF9zdy5IUyxjb2xvdXIgPSAnSFMgU291dGgtV2VzdCcpKSArCiAgZ2VvbV9saW5lKGFlcyh4PURwLkhTLHk9c2l6ZWRpc3RfbmUuSFMsY29sb3VyID0gJ0hTIE5vcnRoLUVhc3QnKSkgKwogICNnZW9tX2xpbmUoYWVzKHg9RHAuTVAseT1zaXplZGlzdF9zdy5NUCxjb2xvdXIgPSAnTVAgU291dGgtV2VzdCcpKSArCiAgI2dlb21fbGluZShhZXMoeD1EcC5NUCx5PXNpemVkaXN0X25lLk1QLGNvbG91ciA9ICdNUCBOb3J0aC1FYXN0JykpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAnbG9nMTAnKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gJ2xvZzEwJykgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gY2JiUGFsZXR0ZSkKCiMnIEhhbHNsZXkgU2Nob29sIGFuZCBNdXNpY2sgUG9pbnQKZ2dwbG90KCkgKwojICBnZW9tX2xpbmUoYWVzKHg9RHAuc21wcy5VQSx5PXNpemVkaXN0X25lLlVBLGNvbG91ciA9ICdVb0EgTm9ydGgtRWFzdCcpKSArCiMgIGdlb21fbGluZShhZXMoeD1EcC5zbXBzLlVBLHk9c2l6ZWRpc3Rfc3cuVUEsY29sb3VyID0gJ1VvQSBTb3V0aC1XZXN0JykpICsKICBnZW9tX2xpbmUoYWVzKHg9RHAuSFMseT1zaXplZGlzdF9zdy5IUyxjb2xvdXIgPSAnSFMgU291dGgtV2VzdCcpKSArCiAgZ2VvbV9saW5lKGFlcyh4PURwLkhTLHk9c2l6ZWRpc3RfbmUuSFMsY29sb3VyID0gJ0hTIE5vcnRoLUVhc3QnKSkgKwogIGdlb21fbGluZShhZXMoeD1EcC5NUCx5PXNpemVkaXN0X3N3Lk1QLGNvbG91ciA9ICdNUCBTb3V0aC1XZXN0JykpICsKICBnZW9tX2xpbmUoYWVzKHg9RHAuTVAseT1zaXplZGlzdF9uZS5NUCxjb2xvdXIgPSAnTVAgTm9ydGgtRWFzdCcpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gJ2xvZzEwJykgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICdsb2cxMCcpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGNiYlBhbGV0dGUpCgojJyBNdXNpY2sgUG9pbnQgYW5kIEF1Y2tsYW5kIFVuaXZlcnNpdHkKZ2dwbG90KCkgKwogIGdlb21fbGluZShhZXMoeD1EcC5zbXBzLlVBLHk9c2l6ZWRpc3RfbmUuVUEsY29sb3VyID0gJ1VvQSBOb3J0aC1FYXN0JykpICsKICBnZW9tX2xpbmUoYWVzKHg9RHAuc21wcy5VQSx5PXNpemVkaXN0X3N3LlVBLGNvbG91ciA9ICdVb0EgU291dGgtV2VzdCcpKSArCiAgZ2VvbV9saW5lKGFlcyh4PURwLlVBLHk9c2l6ZWRpc3RfbmUuZ3JpbW0uVUEsY29sb3VyID0gJ1VvQSBOb3J0aC1FYXN0JykpICsKICBnZW9tX2xpbmUoYWVzKHg9RHAuVUEseT1zaXplZGlzdF9zdy5ncmltbS5VQSxjb2xvdXIgPSAnVW9BIFNvdXRoLVdlc3QnKSkgKwogICNnZW9tX2xpbmUoYWVzKHg9RHAuSFMseT1zaXplZGlzdF9zdy5IUyxjb2xvdXIgPSAnSFMgU291dGgtV2VzdCcpKSArCiAgI2dlb21fbGluZShhZXMoeD1EcC5IUyx5PXNpemVkaXN0X25lLkhTLGNvbG91ciA9ICdIUyBOb3J0aC1FYXN0JykpICsKICBnZW9tX2xpbmUoYWVzKHg9RHAuTVAseT1zaXplZGlzdF9zdy5NUCxjb2xvdXIgPSAnTVAgU291dGgtV2VzdCcpKSArCiAgZ2VvbV9saW5lKGFlcyh4PURwLk1QLHk9c2l6ZWRpc3RfbmUuTVAsY29sb3VyID0gJ01QIE5vcnRoLUVhc3QnKSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICdsb2cxMCcpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAnbG9nMTAnKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjYmJQYWxldHRlKSArCiAgeWxhYihUZVgoIiQoXFxmcmFje2ROfXtkbG9nRF9wfSlcXFtwdC9jY1xcXSQiKSkgKyAKICB4bGFiKFRlWCgiJERfcFxcW25tXFxdIikpCgojJyAjIyAoZE4vZGxvZ0RwKS9OT3ggYXQgVW5pdmVyc2l0eQpnZ3Bsb3QoKSArCiAgZ2VvbV9saW5lKGFlcyh4PURwLnNtcHMuVUEseT1OT3hzaXplZGlzdF9uZS5VQSxjb2xvdXIgPSAnVW9BIE5vcnRoLUVhc3QnKSkgKwogIGdlb21fbGluZShhZXMoeD1EcC5zbXBzLlVBLHk9Tk94c2l6ZWRpc3Rfc3cuVUEsY29sb3VyID0gJ1VvQSBTb3V0aC1XZXN0JykpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAnbG9nMTAnKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gJ2xvZzEwJykgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gY2JiUGFsZXR0ZSkgKwogIHlsYWIoVGVYKCIkXFxmcmFjeyhcXGZyYWN7ZE59e2Rsb2dEX3B9KX17Tk9fWH1cXFtwdC9jY1xcXSQiKSkgKyAKICB4bGFiKFRlWCgiJERfcFxcW25tXFxdIikpCgo=