Pacotes e códigos auxiliares

if(!require(plotly)){
  install.packages("plotly")
  require(plotly)
}
if(!require(ggplot2)){
  install.packages("ggplot2")
  require(ggplot2)
} 
if(!require(ggrepel)){
  install.packages("ggrepel")
  require(ggrepel)
} 
if(!require(ggthemes)){
  install.packages("ggthemes")
  require(ggthemes)
} 
if(!require(rgl)){
  install.packages("rgl")
  require(rgl)
} 
source('plot_PCA.R')
source('White_Noise_Mixture.R')
source('theory_information.R')

theme_set(theme_clean(base_size = 20, base_family = "sans"))

rainbow_colors = palette(c("#fca311",#amarelo
                           "#000000", #preto
                           "#ff006e", #rosa
                           "#40916c", #verde
                           "#6a040f", #vermelho
                           "#eb5e28", #laranja
                           "#6a4c93", #roxo
                           "#50514f", #cinza
                           "#5e3023", #marrom
                           "#3f88c5", #azul
                           "#60d394"))

Estrutura espacial dos pontos

O objetivo deste experimento consiste em obter uma visão global da variação das bandas de intensidade no momento da caracterização de texturas no plano HC. Uma vez que sabemos que o uso de \(\tau = 1\) nos fornece uma maior separabilidade entre as classes, abaixo fornecemos tais análises apenas variando a dimensão \(D\) dos embeddings.

Para representar as bandas de intensidade (que são variáveis categóricas) no plot tridimensional realizamos o encoding de tal forma que:

# Bandt-Pompe parameters -------------------------------------------------------
D = 3
Tau = 1

# WATG results -----------------------------------------------------------------
hc_hh = read.csv(file = paste0("../Data/WATG_HHHH_D", D, "T", Tau, ".csv"), header = TRUE, sep = ",")
hc_hv = read.csv(file = paste0("../Data/WATG_HVHV_D", D, "T", Tau, ".csv"), header = TRUE, sep = ",")
hc_vv = read.csv(file = paste0("../Data/WATG_VVVV_D", D, "T", Tau, ".csv"), header = TRUE, sep = ",")

hc_df = data.frame(H = c(rbind(hc_hh$V1, hc_hv$V1, hc_vv$V1)),
                   C = c(rbind(hc_hh$V2, hc_hv$V2, hc_vv$V2)),
                   Classes = c(rep('Forest', 120), rep('Ocean', 240), rep('Urban', 120), rep('Pasture', 120)),
                   Band = rep(c(1, 2, 3), 200))

# Cotas and Trozos -------------------------------------------------------------
c1x = readingMPR(factorial(D)^2, 1)
c1y = readingMPR(factorial(D)^2, 2)
c2x = readingMPR(factorial(D)^2, 3)
c2y = readingMPR(factorial(D)^2, 4)

cx = c(c1x, c2x)
cy = c(c1y, c2y)

cotas = data.frame("cx" = c(cx[1:124364], cx[1:124364], cx[1:124364]), 
                   "cy" = c(cy[1:124364], cy[1:124364], cy[1:124364]),
                   Band = c(rep(1, length(cx)*3 - 1), rep(2, length(cx)*3 - 1), rep(3, length(cx)*3 - 1)))

# Plot without add limits in axes ----------------------------------------------
fig <- plot_ly() %>%  
  add_trace(data = cotas, x = ~cx, y = ~cy, z = ~Band, type = 'scatter3d', mode = 'lines', line = list(color= 'rgba(169, 169, 169, 0.8)', width = 4)) %>% 
  add_trace(data = hc_df, x = ~H, y = ~C, z = ~Band, type = 'scatter3d', mode = 'lines+markers', 
            line = list(width = 1),
            marker = list(size = 3),
            color = ~Classes, colors = c('#3F84E5', '#B20D30', '#3F784C', '#EFCD4A')) %>% 
  layout(scene = list(xaxis = list(title = 'H'), 
                      yaxis = list(title = 'C'), 
                      zaxis = list(title = '',
                      ticktext = list("HH", "HV", "VV"), 
                      tickvals = list(1, 2, 3),
                      tickmode = "array")))
fig
# Plot with limits in axes -----------------------------------------------------
fig <- plot_ly() %>%  
  add_trace(data = cotas, x = ~cx, y = ~cy, z = ~Band, type = 'scatter3d', mode = 'lines', line = list(color= 'rgba(169, 169, 169, 0.85)', width = 4)) %>% 
  add_trace(data = hc_df, x = ~H, y = ~C, z = ~Band, type = 'scatter3d', mode = 'lines+markers', 
            line = list(width = 1),
            marker = list(size = 3),
            color = ~Classes, colors = c('#3F84E5', '#B20D30', '#3F784C', '#EFCD4A')) %>% 
  layout(scene = list(xaxis = list(title = 'H', range = c(min(hc_df$H), max(hc_df$H))),
                      yaxis = list(title = 'C', range = c(min(hc_df$C), max(hc_df$C))),
                      zaxis = list(title = '',
                      ticktext = list("HH", "HV", "VV"), 
                      tickvals = list(1, 2, 3),
                      tickmode = "array")))
fig

Misturas de patches homogêneos com ruídos

Neste experimento estudamos o comportamento do ponto emblemático característico da classe de regiões urbanas quando temos \(D = 6\) e \(\tau = 1\).

hh_horizontal_vertical = read.csv('../Data/hh_horizontal_vertical.csv')

ggplot(data = hh_horizontal_vertical, aes(x = H, y = C)) +
      geom_point(size = 1.5, alpha = .4) + 
      geom_point(data = hh_horizontal_vertical[1,], aes(x = H, y = C), size = 1.5, alpha = .4, color = "red") + 
      geom_label_repel(aes(label = paste("Delta ==", Steps)), parse = TRUE, segment.size = 0.5, min.segment.length = 0, force = 18) +
      scale_color_manual(values = rainbow_colors) +
      ggtitle('HHHH, Horizontal and vertical') + 
      xlab(expression(italic(H))) + ylab(expression(italic(C))) +
      theme(plot.title = element_text(hjust = 0.5), legend.position = "none")

hv_horizontal_vertical = read.csv('../Data/hv_horizontal_vertical.csv')

ggplot(data = hv_horizontal_vertical, aes(x = H, y = C)) +
      geom_point(size = 1.5, alpha = .4) + 
      geom_point(data = hv_horizontal_vertical[1,], aes(x = H, y = C), size = 1.5, alpha = .4, color = "red") + 
      geom_label_repel(aes(label = paste("Delta ==", Steps)), parse = TRUE, segment.size = 0.5, min.segment.length = 0, force = 18) +
      scale_color_manual(values = rainbow_colors) +
      xlab(expression(italic(H))) + ylab(expression(italic(C))) +
      ggtitle('HVHV, Horizontal and vertical') + 
      theme(plot.title = element_text(hjust = 0.5), legend.position = "none")

vv_horizontal_vertical = read.csv('../Data/vv_horizontal_vertical.csv')

ggplot(data = vv_horizontal_vertical, aes(x = H, y = C)) +
      geom_point(size = 1.5, alpha = .4) + 
      geom_point(data = vv_horizontal_vertical[1,], aes(x = H, y = C), size = 1.5, alpha = .4, color = "red") + 
      geom_label_repel(aes(label = paste("Delta ==", Steps)), parse = TRUE, segment.size = 0.5, min.segment.length = 0, force = 18) +
      scale_color_manual(values = rainbow_colors) +
      xlab(expression(italic(H))) + ylab(expression(italic(C))) +
      ggtitle('VVVV, Horizontal and vertical') + 
      theme(plot.title = element_text(hjust = 0.5), legend.position = "none")

Analisando as sequências produzidas pelas misturas

p = plot.ts.mixtures('HHHH')
HHHH - i: 1 of 9
HHHH - i: 2 of 9
HHHH - i: 3 of 9
HHHH - i: 4 of 9
HHHH - i: 5 of 9
HHHH - i: 6 of 9
HHHH - i: 7 of 9
HHHH - i: 8 of 9
HHHH - i: 9 of 9
print(p)

p = plot.ts.mixtures('HVHV')
print(p)

p = plot.ts.mixtures('VVVV')
print(p)

Analisando os histogramas produzidos pelas misturas

p = plot.hist.mixtures('HHHH')
print(p)

p = plot.hist.mixtures('HVHV')
print(p)

p = plot.hist.mixtures('VVVV')
print(p)

LS0tCnRpdGxlOiAiVHJhbnNpdGlvbiBHcmFwaHMgZm9yIFNBUiBJbWFnZSBUZXh0dXJlIENoYXJhY3Rlcml6YXRpb24gLSBWaXN1YWxpemF0aW9uIGFuZCBSZXN1bHRzIG9mIEV4cGVyaW1lbnRzIgphdXRob3I6ICJFZHVhcmRhIENoYWdhcyIKZGF0ZTogIk1heSwgMjAyMSIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgojIyMgUGFjb3RlcyBlIGPDs2RpZ29zIGF1eGlsaWFyZXMKCmBgYHtyfQppZighcmVxdWlyZShwbG90bHkpKXsKICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQogIHJlcXVpcmUocGxvdGx5KQp9CmlmKCFyZXF1aXJlKGdncGxvdDIpKXsKICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikKICByZXF1aXJlKGdncGxvdDIpCn0gCmlmKCFyZXF1aXJlKGdncmVwZWwpKXsKICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3JlcGVsIikKICByZXF1aXJlKGdncmVwZWwpCn0gCmlmKCFyZXF1aXJlKGdndGhlbWVzKSl7CiAgaW5zdGFsbC5wYWNrYWdlcygiZ2d0aGVtZXMiKQogIHJlcXVpcmUoZ2d0aGVtZXMpCn0gCnNvdXJjZSgncGxvdF9QQ0EuUicpCnNvdXJjZSgncGxvdF9NaXh0dXJlcy5SJykKc291cmNlKCdXaGl0ZV9Ob2lzZV9NaXh0dXJlLlInKQpzb3VyY2UoJ3RoZW9yeV9pbmZvcm1hdGlvbi5SJykKCnRoZW1lX3NldCh0aGVtZV9jbGVhbihiYXNlX3NpemUgPSAyMCwgYmFzZV9mYW1pbHkgPSAic2FucyIpKQoKcmFpbmJvd19jb2xvcnMgPSBwYWxldHRlKGMoIiNmY2EzMTEiLCNhbWFyZWxvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIjMDAwMDAwIiwgI3ByZXRvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIjZmYwMDZlIiwgI3Jvc2EKICAgICAgICAgICAgICAgICAgICAgICAgICAgIiM0MDkxNmMiLCAjdmVyZGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIiM2YTA0MGYiLCAjdmVybWVsaG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIiNlYjVlMjgiLCAjbGFyYW5qYQogICAgICAgICAgICAgICAgICAgICAgICAgICAiIzZhNGM5MyIsICNyb3hvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIjNTA1MTRmIiwgI2NpbnphCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIjNWUzMDIzIiwgI21hcnJvbQogICAgICAgICAgICAgICAgICAgICAgICAgICAiIzNmODhjNSIsICNhenVsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIjNjBkMzk0IikpCmBgYAoKIyMjIEVzdHJ1dHVyYSBlc3BhY2lhbCBkb3MgcG9udG9zIAoKTyBvYmpldGl2byBkZXN0ZSBleHBlcmltZW50byBjb25zaXN0ZSBlbSBvYnRlciB1bWEgdmlzw6NvIGdsb2JhbCBkYSB2YXJpYcOnw6NvIGRhcyBiYW5kYXMgZGUgaW50ZW5zaWRhZGUgbm8gbW9tZW50byBkYSBjYXJhY3Rlcml6YcOnw6NvIGRlIHRleHR1cmFzIG5vIHBsYW5vIEhDLiBVbWEgdmV6IHF1ZSBzYWJlbW9zIHF1ZSBvIHVzbyBkZSAkXHRhdSA9IDEkIG5vcyBmb3JuZWNlIHVtYSBtYWlvciBzZXBhcmFiaWxpZGFkZSBlbnRyZSBhcyBjbGFzc2VzLCBhYmFpeG8gZm9ybmVjZW1vcyB0YWlzIGFuw6FsaXNlcyBhcGVuYXMgdmFyaWFuZG8gYSBkaW1lbnPDo28gJEQkIGRvcyBlbWJlZGRpbmdzLgoKUGFyYSByZXByZXNlbnRhciBhcyBiYW5kYXMgZGUgaW50ZW5zaWRhZGUgKHF1ZSBzw6NvIHZhcmnDoXZlaXMgY2F0ZWfDs3JpY2FzKSBubyBwbG90IHRyaWRpbWVuc2lvbmFsIHJlYWxpemFtb3MgbyBlbmNvZGluZyBkZSB0YWwgZm9ybWEgcXVlOgoKKiBCYW5kID0gMSwgZXF1aXZhbGUgYW9zIGRhZG9zIG9idGlkb3MgcGVsYSBiYW5kYSBISCBkZSBpbnRlbnNpZGFkZSwKCiogQmFuZCA9IDIsIGVxdWl2YWxlIGFvcyBkYWRvcyBvYnRpZG9zIHBlbGEgYmFuZGEgSFYgZGUgaW50ZW5zaWRhZGUsCgoqIEJhbmQgPSAzLCBlcXVpdmFsZSBhb3MgZGFkb3Mgb2J0aWRvcyBwZWxhIGJhbmRhIFZWIGRlIGludGVuc2lkYWRlLgoKYGBge3J9CiMgQmFuZHQtUG9tcGUgcGFyYW1ldGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkQgPSAzClRhdSA9IDEKCiMgV0FURyByZXN1bHRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmhjX2hoID0gcmVhZC5jc3YoZmlsZSA9IHBhc3RlMCgiLi4vRGF0YS9XQVRHX0hISEhfRCIsIEQsICJUIiwgVGF1LCAiLmNzdiIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiLCIpCmhjX2h2ID0gcmVhZC5jc3YoZmlsZSA9IHBhc3RlMCgiLi4vRGF0YS9XQVRHX0hWSFZfRCIsIEQsICJUIiwgVGF1LCAiLmNzdiIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiLCIpCmhjX3Z2ID0gcmVhZC5jc3YoZmlsZSA9IHBhc3RlMCgiLi4vRGF0YS9XQVRHX1ZWVlZfRCIsIEQsICJUIiwgVGF1LCAiLmNzdiIpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiLCIpCgpoY19kZiA9IGRhdGEuZnJhbWUoSCA9IGMocmJpbmQoaGNfaGgkVjEsIGhjX2h2JFYxLCBoY192diRWMSkpLAogICAgICAgICAgICAgICAgICAgQyA9IGMocmJpbmQoaGNfaGgkVjIsIGhjX2h2JFYyLCBoY192diRWMikpLAogICAgICAgICAgICAgICAgICAgQ2xhc3NlcyA9IGMocmVwKCdGb3Jlc3QnLCAxMjApLCByZXAoJ09jZWFuJywgMjQwKSwgcmVwKCdVcmJhbicsIDEyMCksIHJlcCgnUGFzdHVyZScsIDEyMCkpLAogICAgICAgICAgICAgICAgICAgQmFuZCA9IHJlcChjKDEsIDIsIDMpLCAyMDApKQoKIyBDb3RhcyBhbmQgVHJvem9zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYzF4ID0gcmVhZGluZ01QUihmYWN0b3JpYWwoRCleMiwgMSkKYzF5ID0gcmVhZGluZ01QUihmYWN0b3JpYWwoRCleMiwgMikKYzJ4ID0gcmVhZGluZ01QUihmYWN0b3JpYWwoRCleMiwgMykKYzJ5ID0gcmVhZGluZ01QUihmYWN0b3JpYWwoRCleMiwgNCkKCmN4ID0gYyhjMXgsIGMyeCkKY3kgPSBjKGMxeSwgYzJ5KQoKY290YXMgPSBkYXRhLmZyYW1lKCJjeCIgPSBjKGN4WzE6MTI0MzY0XSwgY3hbMToxMjQzNjRdLCBjeFsxOjEyNDM2NF0pLCAKICAgICAgICAgICAgICAgICAgICJjeSIgPSBjKGN5WzE6MTI0MzY0XSwgY3lbMToxMjQzNjRdLCBjeVsxOjEyNDM2NF0pLAogICAgICAgICAgICAgICAgICAgQmFuZCA9IGMocmVwKDEsIGxlbmd0aChjeCkqMyAtIDEpLCByZXAoMiwgbGVuZ3RoKGN4KSozIC0gMSksIHJlcCgzLCBsZW5ndGgoY3gpKjMgLSAxKSkpCgojIFBsb3Qgd2l0aG91dCBhZGQgbGltaXRzIGluIGF4ZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpmaWcgPC0gcGxvdF9seSgpICU+JSAgCiAgYWRkX3RyYWNlKGRhdGEgPSBjb3RhcywgeCA9IH5jeCwgeSA9IH5jeSwgeiA9IH5CYW5kLCB0eXBlID0gJ3NjYXR0ZXIzZCcsIG1vZGUgPSAnbGluZXMnLCBsaW5lID0gbGlzdChjb2xvcj0gJ3JnYmEoMTY5LCAxNjksIDE2OSwgMC44KScsIHdpZHRoID0gNCkpICU+JSAKICBhZGRfdHJhY2UoZGF0YSA9IGhjX2RmLCB4ID0gfkgsIHkgPSB+QywgeiA9IH5CYW5kLCB0eXBlID0gJ3NjYXR0ZXIzZCcsIG1vZGUgPSAnbGluZXMrbWFya2VycycsIAogICAgICAgICAgICBsaW5lID0gbGlzdCh3aWR0aCA9IDEpLAogICAgICAgICAgICBtYXJrZXIgPSBsaXN0KHNpemUgPSAzKSwKICAgICAgICAgICAgY29sb3IgPSB+Q2xhc3NlcywgY29sb3JzID0gYygnIzNGODRFNScsICcjQjIwRDMwJywgJyMzRjc4NEMnLCAnI0VGQ0Q0QScpKSAlPiUgCiAgbGF5b3V0KHNjZW5lID0gbGlzdCh4YXhpcyA9IGxpc3QodGl0bGUgPSAnSCcpLCAKICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICdDJyksIAogICAgICAgICAgICAgICAgICAgICAgemF4aXMgPSBsaXN0KHRpdGxlID0gJycsCiAgICAgICAgICAgICAgICAgICAgICB0aWNrdGV4dCA9IGxpc3QoIkhIIiwgIkhWIiwgIlZWIiksIAogICAgICAgICAgICAgICAgICAgICAgdGlja3ZhbHMgPSBsaXN0KDEsIDIsIDMpLAogICAgICAgICAgICAgICAgICAgICAgdGlja21vZGUgPSAiYXJyYXkiKSkpCmZpZwpgYGAKCmBgYHtyfQojIFBsb3Qgd2l0aCBsaW1pdHMgaW4gYXhlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpmaWcgPC0gcGxvdF9seSgpICU+JSAgCiAgYWRkX3RyYWNlKGRhdGEgPSBjb3RhcywgeCA9IH5jeCwgeSA9IH5jeSwgeiA9IH5CYW5kLCB0eXBlID0gJ3NjYXR0ZXIzZCcsIG1vZGUgPSAnbGluZXMnLCBsaW5lID0gbGlzdChjb2xvcj0gJ3JnYmEoMTY5LCAxNjksIDE2OSwgMC44NSknLCB3aWR0aCA9IDQpKSAlPiUgCiAgYWRkX3RyYWNlKGRhdGEgPSBoY19kZiwgeCA9IH5ILCB5ID0gfkMsIHogPSB+QmFuZCwgdHlwZSA9ICdzY2F0dGVyM2QnLCBtb2RlID0gJ2xpbmVzK21hcmtlcnMnLCAKICAgICAgICAgICAgbGluZSA9IGxpc3Qod2lkdGggPSAxKSwKICAgICAgICAgICAgbWFya2VyID0gbGlzdChzaXplID0gMyksCiAgICAgICAgICAgIGNvbG9yID0gfkNsYXNzZXMsIGNvbG9ycyA9IGMoJyMzRjg0RTUnLCAnI0IyMEQzMCcsICcjM0Y3ODRDJywgJyNFRkNENEEnKSkgJT4lIAogIGxheW91dChzY2VuZSA9IGxpc3QoeGF4aXMgPSBsaXN0KHRpdGxlID0gJ0gnLCByYW5nZSA9IGMobWluKGhjX2RmJEgpLCBtYXgoaGNfZGYkSCkpKSwKICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICdDJywgcmFuZ2UgPSBjKG1pbihoY19kZiRDKSwgbWF4KGhjX2RmJEMpKSksCiAgICAgICAgICAgICAgICAgICAgICB6YXhpcyA9IGxpc3QodGl0bGUgPSAnJywKICAgICAgICAgICAgICAgICAgICAgIHRpY2t0ZXh0ID0gbGlzdCgiSEgiLCAiSFYiLCAiVlYiKSwgCiAgICAgICAgICAgICAgICAgICAgICB0aWNrdmFscyA9IGxpc3QoMSwgMiwgMyksCiAgICAgICAgICAgICAgICAgICAgICB0aWNrbW9kZSA9ICJhcnJheSIpKSkKZmlnCmBgYAoKIyMjIE1pc3R1cmFzIGRlIHBhdGNoZXMgaG9tb2fDqm5lb3MgY29tIHJ1w61kb3MKCk5lc3RlIGV4cGVyaW1lbnRvIGVzdHVkYW1vcyBvIGNvbXBvcnRhbWVudG8gZG8gcG9udG8gZW1ibGVtw6F0aWNvIGNhcmFjdGVyw61zdGljbyBkYSBjbGFzc2UgZGUgcmVnacO1ZXMgdXJiYW5hcyBxdWFuZG8gdGVtb3MgJEQgPSA2JCBlICRcdGF1ID0gMSQuIAoKYGBge3J9CmhoX2hvcml6b250YWxfdmVydGljYWwgPSByZWFkLmNzdignLi4vRGF0YS9oaF9ob3Jpem9udGFsX3ZlcnRpY2FsLmNzdicpCgpnZ3Bsb3QoZGF0YSA9IGhoX2hvcml6b250YWxfdmVydGljYWwsIGFlcyh4ID0gSCwgeSA9IEMpKSArCiAgICAgIGdlb21fcG9pbnQoc2l6ZSA9IDEuNSwgYWxwaGEgPSAuNCkgKyAKICAgICAgZ2VvbV9wb2ludChkYXRhID0gaGhfaG9yaXpvbnRhbF92ZXJ0aWNhbFsxLF0sIGFlcyh4ID0gSCwgeSA9IEMpLCBzaXplID0gMS41LCBhbHBoYSA9IC40LCBjb2xvciA9ICJyZWQiKSArIAogICAgICBnZW9tX2xhYmVsX3JlcGVsKGFlcyhsYWJlbCA9IHBhc3RlKCJEZWx0YSA9PSIsIFN0ZXBzKSksIHBhcnNlID0gVFJVRSwgc2VnbWVudC5zaXplID0gMC41LCBtaW4uc2VnbWVudC5sZW5ndGggPSAwLCBmb3JjZSA9IDE4KSArCiAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSByYWluYm93X2NvbG9ycykgKwogICAgICBnZ3RpdGxlKCdISEhILCBIb3Jpem9udGFsIGFuZCB2ZXJ0aWNhbCcpICsgCiAgICAgIHhsYWIoZXhwcmVzc2lvbihpdGFsaWMoSCkpKSArIHlsYWIoZXhwcmVzc2lvbihpdGFsaWMoQykpKSArCiAgICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLCBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYApgYGB7cn0KaHZfaG9yaXpvbnRhbF92ZXJ0aWNhbCA9IHJlYWQuY3N2KCcuLi9EYXRhL2h2X2hvcml6b250YWxfdmVydGljYWwuY3N2JykKCmdncGxvdChkYXRhID0gaHZfaG9yaXpvbnRhbF92ZXJ0aWNhbCwgYWVzKHggPSBILCB5ID0gQykpICsKICAgICAgZ2VvbV9wb2ludChzaXplID0gMS41LCBhbHBoYSA9IC40KSArIAogICAgICBnZW9tX3BvaW50KGRhdGEgPSBodl9ob3Jpem9udGFsX3ZlcnRpY2FsWzEsXSwgYWVzKHggPSBILCB5ID0gQyksIHNpemUgPSAxLjUsIGFscGhhID0gLjQsIGNvbG9yID0gInJlZCIpICsgCiAgICAgIGdlb21fbGFiZWxfcmVwZWwoYWVzKGxhYmVsID0gcGFzdGUoIkRlbHRhID09IiwgU3RlcHMpKSwgcGFyc2UgPSBUUlVFLCBzZWdtZW50LnNpemUgPSAwLjUsIG1pbi5zZWdtZW50Lmxlbmd0aCA9IDAsIGZvcmNlID0gMTgpICsKICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHJhaW5ib3dfY29sb3JzKSArCiAgICAgIHhsYWIoZXhwcmVzc2lvbihpdGFsaWMoSCkpKSArIHlsYWIoZXhwcmVzc2lvbihpdGFsaWMoQykpKSArCiAgICAgIGdndGl0bGUoJ0hWSFYsIEhvcml6b250YWwgYW5kIHZlcnRpY2FsJykgKyAKICAgICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgpgYGB7cn0KdnZfaG9yaXpvbnRhbF92ZXJ0aWNhbCA9IHJlYWQuY3N2KCcuLi9EYXRhL3Z2X2hvcml6b250YWxfdmVydGljYWwuY3N2JykKCmdncGxvdChkYXRhID0gdnZfaG9yaXpvbnRhbF92ZXJ0aWNhbCwgYWVzKHggPSBILCB5ID0gQykpICsKICAgICAgZ2VvbV9wb2ludChzaXplID0gMS41LCBhbHBoYSA9IC40KSArIAogICAgICBnZW9tX3BvaW50KGRhdGEgPSB2dl9ob3Jpem9udGFsX3ZlcnRpY2FsWzEsXSwgYWVzKHggPSBILCB5ID0gQyksIHNpemUgPSAxLjUsIGFscGhhID0gLjQsIGNvbG9yID0gInJlZCIpICsgCiAgICAgIGdlb21fbGFiZWxfcmVwZWwoYWVzKGxhYmVsID0gcGFzdGUoIkRlbHRhID09IiwgU3RlcHMpKSwgcGFyc2UgPSBUUlVFLCBzZWdtZW50LnNpemUgPSAwLjUsIG1pbi5zZWdtZW50Lmxlbmd0aCA9IDAsIGZvcmNlID0gMTgpICsKICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHJhaW5ib3dfY29sb3JzKSArCiAgICAgIHhsYWIoZXhwcmVzc2lvbihpdGFsaWMoSCkpKSArIHlsYWIoZXhwcmVzc2lvbihpdGFsaWMoQykpKSArCiAgICAgIGdndGl0bGUoJ1ZWVlYsIEhvcml6b250YWwgYW5kIHZlcnRpY2FsJykgKyAKICAgICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCiMjIyBBbmFsaXNhbmRvIGFzIHNlcXXDqm5jaWFzIHByb2R1emlkYXMgcGVsYXMgbWlzdHVyYXMKCmBgYHtyfQpwID0gcGxvdC50cy5taXh0dXJlcygnSEhISCcpCnByaW50KHApCmBgYAoKYGBge3J9CnAgPSBwbG90LnRzLm1peHR1cmVzKCdIVkhWJykKcHJpbnQocCkKYGBgCgpgYGB7cn0KcCA9IHBsb3QudHMubWl4dHVyZXMoJ1ZWVlYnKQpwcmludChwKQpgYGAKCiMjIyBBbmFsaXNhbmRvIG9zIGhpc3RvZ3JhbWFzIHByb2R1emlkb3MgcGVsYXMgbWlzdHVyYXMKCmBgYHtyfQpwID0gcGxvdC5oaXN0Lm1peHR1cmVzKCdISEhIJykKcHJpbnQocCkKYGBgCgpgYGB7cn0KcCA9IHBsb3QuaGlzdC5taXh0dXJlcygnSFZIVicpCnByaW50KHApCmBgYAoKYGBge3J9CnAgPSBwbG90Lmhpc3QubWl4dHVyZXMoJ1ZWVlYnKQpwcmludChwKQpgYGAK