knitr::opts_chunk$set(cache = TRUE, dev = c("png", "pdf"))
library(eucs)
library(here)
library(xtable)
grampians_taxa_tab <- subset(
  medians_grampians,
  select = c(taxon, sla_mm2_per_mg, seed_mass_mg, max_height_m)
)

sla_n_samples <- subset(
  traits_grampians,
  select = c(tree, taxon, sla_mm2_per_mg)
)

sla_n_samples <- sla_n_samples[complete.cases(sla_n_samples), ]

sm_n_samples <- subset(
  traits_grampians,
  select = c(taxon, seed_mass_mg)
)

sm_n_samples <- sm_n_samples[complete.cases(sm_n_samples), ]

nplots <- table(subset(modeldata_grampians, occupancy, taxon))

names(nplots)[
  names(nplots) %in%
    c(
      "Eucalyptus (goniocalyx|nortonii)",
      "Eucalyptus leucoxylon",
      "Eucalyptus radiata",
      "Eucalyptus viminalis subsp. (pryoriana|viminalis)"
    )
  ] <- c(
    "Eucalyptus goniocalyx subsp. (goniocalyx|viridissima)",
    "Eucalyptus leucoxylon subsp. (leucoxylon|pruinosa)",
    "Eucalyptus radiata subsp. radiata",
    "Eucalyptus viminalis subsp. viminalis"
  )

grampians_taxa_tab <- data.frame(
  "\\vtop{\\hbox{\\strut }\\hbox{\\strut Taxon}}" = paste0(
    "\\textit{",
    gsub("subsp.", "ssp.", gsub("Eucalyptus", "E.", grampians_taxa_tab$taxon)),
    "}"
  ),
  "\\vtop{\\hbox{\\strut No.}\\hbox{\\strut of}\\hbox{\\strut plots}}" =
    as.character(nplots[grampians_taxa_tab$taxon]),
  "\\vtop{\\hbox{\\strut SLA}\\hbox{\\strut (mm$^2$/mg)}}" = paste0(
    round(grampians_taxa_tab$sla_mm2_per_mg, 1),
    " (", table(sla_n_samples$taxon)[grampians_taxa_tab$taxon],
    "/", table(unique(sla_n_samples[1:2])$taxon)[grampians_taxa_tab$taxon], ")"
  ),
  "\\vtop{\\hbox{\\strut Seed}\\hbox{\\strut mass}\\hbox{\\strut (mg)}}" =
    paste0(
      round(grampians_taxa_tab$seed_mass_mg, 1),
      " (", table(sm_n_samples$taxon)[grampians_taxa_tab$taxon], ")"
    ),
  "\\vtop{\\hbox{\\strut Max}\\hbox{\\strut height}\\hbox{\\strut (m)}}" =
    as.character(round(grampians_taxa_tab$max_height_m, 0)),
  check.names = FALSE,
  stringsAsFactors = FALSE
)

grampians_taxa_tab[
    grampians_taxa_tab[, 1]%in%
      c(
        "\\textit{E. goniocalyx ssp. (goniocalyx|viridissima)}",
        "\\textit{E. leucoxylon ssp. (leucoxylon|pruinosa)}"
      ), 1
  ] <- c(
    "\\textit{E. goniocalyx}",
    "\\textit{E. leucoxylon}"
  )

dir.create(
  here("notebooks/eucalypt_taxa_summaries_files"),
  showWarnings = FALSE
)

print(
  xtable(
    grampians_taxa_tab, caption =
      "Grampians taxa. Number of plots at which each taxa occurred.
      Median SLA (number of leaves/number of trees). Median seed mass (number of
      samples). Maximum attainable height.",
    label = "tab:grampianstaxasummary"
  ),
  file = here(
    "notebooks/eucalypt_taxa_summaries_files/grampianssummarytab.tex"
  ),
  include.rownames = FALSE,
  table.placement = "htbp!",
  caption.placement = "top",
  sanitize.text.function = identity
)
southeast_taxa_tab <- subset(
  combine_taxa_traits(medians_southeast, euctils::taxa_groups),
  select = c(taxon, sla_mm2_per_mg, seed_mass_mg, max_height_m)
)

southeast_samples <- local({
    df <- traits_southeast
    for (i in seq_along(taxa_groups)) {
      df[
        grepl(taxa_groups[i], df$taxon) |
        grepl(taxa_groups[i], df$taxon, fixed = TRUE),
        "taxon"
      ] <- names(taxa_groups)[i]
    }
    df
  })

sla_n_samples <- subset(
  southeast_samples,
  select = c(tree, taxon, sla_mm2_per_mg)
)

sla_n_samples <- sla_n_samples[complete.cases(sla_n_samples), ]

sm_n_samples <- subset(
  southeast_samples,
  select = c(tree, taxon, seed_mass_mg)
)

sm_n_samples <- sm_n_samples[complete.cases(sm_n_samples), ]

nplots <- table(subset(modeldata_southeast, occupancy, taxon))

nregs <- table(
  unique(subset(modeldata_southeast, occupancy, c(taxon, ibra_subregion)))$taxon
)

southeast_taxa_tab <- southeast_taxa_tab[complete.cases(southeast_taxa_tab), ]

southeast_taxa_tab <- data.frame(
   taxon = southeast_taxa_tab$taxon,
  "\\vtop{\\hbox{\\strut No.}\\hbox{\\strut of}\\hbox{\\strut regions}}" =
    as.character(nregs[southeast_taxa_tab$taxon]),
  "\\vtop{\\hbox{\\strut No.}\\hbox{\\strut of}\\hbox{\\strut plots}}" =
    as.character(nplots[southeast_taxa_tab$taxon]),
  "\\vtop{\\hbox{\\strut SLA}\\hbox{\\strut (mm$^2$/mg)}}" = paste0(
    round(southeast_taxa_tab$sla_mm2_per_mg, 1),
    " (", table(sla_n_samples$taxon)[southeast_taxa_tab$taxon],
    "/", table(unique(sla_n_samples[1:2])$taxon)[southeast_taxa_tab$taxon], ")"
  ),
  "\\vtop{\\hbox{\\strut Seed}\\hbox{\\strut mass}\\hbox{\\strut (mg)}}" =
    paste0(
      round(southeast_taxa_tab$seed_mass_mg, 1),
      " (", table(sm_n_samples$taxon)[southeast_taxa_tab$taxon],
      "/", table(unique(sm_n_samples[1:2])$taxon)[southeast_taxa_tab$taxon], ")"
    ),
  "\\vtop{\\hbox{\\strut Max}\\hbox{\\strut height}\\hbox{\\strut (m)}}" =
    as.character(round(southeast_taxa_tab$max_height_m, 0)),
  check.names = FALSE,
  stringsAsFactors = FALSE
)

southeast_taxa_tab$taxon <- gsub("subsp.", "ssp.", southeast_taxa_tab$taxon)
southeast_taxa_tab$taxon <- gsub("(", "", southeast_taxa_tab$taxon, fixed = T)
southeast_taxa_tab$taxon <- gsub(")", "", southeast_taxa_tab$taxon, fixed = T)
southeast_taxa_tab$taxon <- gsub("|", "/", southeast_taxa_tab$taxon, fixed = T)
southeast_taxa_tab$taxon <- paste0("\\textit{", southeast_taxa_tab$taxon, "}")
southeast_taxa_tab <- southeast_taxa_tab[order(southeast_taxa_tab$taxon), ]

colnames(southeast_taxa_tab)[1] <-
  "\\vtop{\\hbox{\\strut }\\hbox{\\strut Taxon}}"

southeast_taxa_tab <- southeast_taxa_tab[complete.cases(southeast_taxa_tab), ]

print(
  xtable(
    southeast_taxa_tab,
    caption =
      "Southeast taxa. Number of IBRA subregions in which the taxon occurs.
      Number of plots at which each taxa occurred. Median SLA (number of
      leaves/number of trees). Median seed mass (number of samples/number of
      trees). Maximum attainable height.",
    label = "tab:southeasttaxasummary",
    align = c(
      "l", "P{.42\\textwidth}", "P{.07\\textwidth}", "P{.045\\textwidth}",
      "P{.11\\textwidth}", "P{.11\\textwidth}", "P{.06\\textwidth}"
    )
  ),
  file = here(
    "notebooks/eucalypt_taxa_summaries_files/southeastsummarytab.tex"
  ),
  tabular.environment = 'longtable',
  size = "\\fontsize{8pt}{8pt}\\selectfont",
  hline.after = -1,
  include.colnames = TRUE,
  floating = FALSE,
  add.to.row = list(pos = list(0), command = "\\hline \\endhead "),
  include.rownames = FALSE,
  table.placement = "htbp!",
  caption.placement = "top",
  sanitize.text.function = identity
)

Correlations among traits

par(mar = rep(.5, 4), oma = c(3, 4, 4, 3), mfrow = c(2, 2))
rgns <- c("South-east Australia" = FALSE, "Grampians" = TRUE)
vars <- list()
vars[[1]] <- c("sla_mm2_per_mg", "seed_mass_mg")
vars[[2]] <- c("max_height_m", "seed_mass_mg")
labels <- c(
  sla_mm2_per_mg = "SLA (mm\u00b2/mg)",
  seed_mass_mg   = "Seed mass (mg)",
  max_height_m   = "Maximum height (m)"
)

trait_data <- list()
trait_data$southeast <-
  unique(modeldata_southeast[, c("taxon", names(labels))])[-1]
trait_data$grampians <-
  unique(modeldata_grampians[, c("taxon", names(labels))])[-1]

for (i in seq(vars[[1]])) {
  for (j in seq(vars[[2]])) {
    if (sum(i, j) > 3) {
      plot.new()
      if (i == j) {
        legend(
          "center", c("Southeast","Grampians"),
          fill = c("black", "white"),
          bty = "n", cex = 1, xpd = NA
        )
      }
    } else {
      plot(
        subset(trait_data[[1]], select = c(vars[[1]][j], vars[[2]][i])),
        xaxt = "n", yaxt = "n", pch = 19, log = "xy",
        panel.first = grid(col = "grey"),
        xlim = range(do.call(rbind, trait_data)[vars[[1]][j]], na.rm = TRUE) * c(.9, 1.2),
        ylim = range(do.call(rbind, trait_data)[vars[[2]][i]], na.rm = TRUE) * c(.9, 1.2)
      )
      points(
        subset(trait_data[[2]], select = c(vars[[1]][j], vars[[2]][i])),
        bg = "white", pch = 21
      )
      if (sum(i, j) == 3) {
        axis(1, cex.axis = .8)
        axis(4, las = 1, cex.axis = .8)
      }
      if (i == 1) mtext(labels[vars[[1]][j]], 3, 1)
      if (j == 1) mtext(labels[vars[[2]][i]], 2, 1)
    }
  }
}

IycgLS0tCiMnIHRpdGxlOiAiU3VtbWFyaWVzIG9mIGV1Y2FseXB0IHRheGEgYW5kIHRoZWlyIHRyYWl0cyIKIycgYXV0aG9yOiAiV2lsbGlhbSBLLiBNb3JyaXMiCiMnIGRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKIycgb3V0cHV0OgojJyAgIHJtYXJrZG93bjo6aHRtbF9ub3RlYm9vazoKIycgICAgIGNvZGVfZm9sZGluZzogaGlkZQojJyAtLS0KCiMrIHNldHVwLCBtZXNzYWdlPUZBTFNFCmtuaXRyOjpvcHRzX2NodW5rJHNldChjYWNoZSA9IFRSVUUsIGRldiA9IGMoInBuZyIsICJwZGYiKSkKbGlicmFyeShldWNzKQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkoeHRhYmxlKQoKIysgZ3JhbXBpYW5zX3RheGFfdGFibGUsIG1lc3NhZ2U9RkFMU0UsIHdhcmluZz1GQUxTRQpncmFtcGlhbnNfdGF4YV90YWIgPC0gc3Vic2V0KAogIG1lZGlhbnNfZ3JhbXBpYW5zLAogIHNlbGVjdCA9IGModGF4b24sIHNsYV9tbTJfcGVyX21nLCBzZWVkX21hc3NfbWcsIG1heF9oZWlnaHRfbSkKKQoKc2xhX25fc2FtcGxlcyA8LSBzdWJzZXQoCiAgdHJhaXRzX2dyYW1waWFucywKICBzZWxlY3QgPSBjKHRyZWUsIHRheG9uLCBzbGFfbW0yX3Blcl9tZykKKQoKc2xhX25fc2FtcGxlcyA8LSBzbGFfbl9zYW1wbGVzW2NvbXBsZXRlLmNhc2VzKHNsYV9uX3NhbXBsZXMpLCBdCgpzbV9uX3NhbXBsZXMgPC0gc3Vic2V0KAogIHRyYWl0c19ncmFtcGlhbnMsCiAgc2VsZWN0ID0gYyh0YXhvbiwgc2VlZF9tYXNzX21nKQopCgpzbV9uX3NhbXBsZXMgPC0gc21fbl9zYW1wbGVzW2NvbXBsZXRlLmNhc2VzKHNtX25fc2FtcGxlcyksIF0KCm5wbG90cyA8LSB0YWJsZShzdWJzZXQobW9kZWxkYXRhX2dyYW1waWFucywgb2NjdXBhbmN5LCB0YXhvbikpCgpuYW1lcyhucGxvdHMpWwogIG5hbWVzKG5wbG90cykgJWluJQogICAgYygKICAgICAgIkV1Y2FseXB0dXMgKGdvbmlvY2FseXh8bm9ydG9uaWkpIiwKICAgICAgIkV1Y2FseXB0dXMgbGV1Y294eWxvbiIsCiAgICAgICJFdWNhbHlwdHVzIHJhZGlhdGEiLAogICAgICAiRXVjYWx5cHR1cyB2aW1pbmFsaXMgc3Vic3AuIChwcnlvcmlhbmF8dmltaW5hbGlzKSIKICAgICkKICBdIDwtIGMoCiAgICAiRXVjYWx5cHR1cyBnb25pb2NhbHl4IHN1YnNwLiAoZ29uaW9jYWx5eHx2aXJpZGlzc2ltYSkiLAogICAgIkV1Y2FseXB0dXMgbGV1Y294eWxvbiBzdWJzcC4gKGxldWNveHlsb258cHJ1aW5vc2EpIiwKICAgICJFdWNhbHlwdHVzIHJhZGlhdGEgc3Vic3AuIHJhZGlhdGEiLAogICAgIkV1Y2FseXB0dXMgdmltaW5hbGlzIHN1YnNwLiB2aW1pbmFsaXMiCiAgKQoKZ3JhbXBpYW5zX3RheGFfdGFiIDwtIGRhdGEuZnJhbWUoCiAgIlxcdnRvcHtcXGhib3h7XFxzdHJ1dCB9XFxoYm94e1xcc3RydXQgVGF4b259fSIgPSBwYXN0ZTAoCiAgICAiXFx0ZXh0aXR7IiwKICAgIGdzdWIoInN1YnNwLiIsICJzc3AuIiwgZ3N1YigiRXVjYWx5cHR1cyIsICJFLiIsIGdyYW1waWFuc190YXhhX3RhYiR0YXhvbikpLAogICAgIn0iCiAgKSwKICAiXFx2dG9we1xcaGJveHtcXHN0cnV0IE5vLn1cXGhib3h7XFxzdHJ1dCBvZn1cXGhib3h7XFxzdHJ1dCBwbG90c319IiA9CiAgICBhcy5jaGFyYWN0ZXIobnBsb3RzW2dyYW1waWFuc190YXhhX3RhYiR0YXhvbl0pLAogICJcXHZ0b3B7XFxoYm94e1xcc3RydXQgU0xBfVxcaGJveHtcXHN0cnV0IChtbSReMiQvbWcpfX0iID0gcGFzdGUwKAogICAgcm91bmQoZ3JhbXBpYW5zX3RheGFfdGFiJHNsYV9tbTJfcGVyX21nLCAxKSwKICAgICIgKCIsIHRhYmxlKHNsYV9uX3NhbXBsZXMkdGF4b24pW2dyYW1waWFuc190YXhhX3RhYiR0YXhvbl0sCiAgICAiLyIsIHRhYmxlKHVuaXF1ZShzbGFfbl9zYW1wbGVzWzE6Ml0pJHRheG9uKVtncmFtcGlhbnNfdGF4YV90YWIkdGF4b25dLCAiKSIKICApLAogICJcXHZ0b3B7XFxoYm94e1xcc3RydXQgU2VlZH1cXGhib3h7XFxzdHJ1dCBtYXNzfVxcaGJveHtcXHN0cnV0IChtZyl9fSIgPQogICAgcGFzdGUwKAogICAgICByb3VuZChncmFtcGlhbnNfdGF4YV90YWIkc2VlZF9tYXNzX21nLCAxKSwKICAgICAgIiAoIiwgdGFibGUoc21fbl9zYW1wbGVzJHRheG9uKVtncmFtcGlhbnNfdGF4YV90YWIkdGF4b25dLCAiKSIKICAgICksCiAgIlxcdnRvcHtcXGhib3h7XFxzdHJ1dCBNYXh9XFxoYm94e1xcc3RydXQgaGVpZ2h0fVxcaGJveHtcXHN0cnV0IChtKX19IiA9CiAgICBhcy5jaGFyYWN0ZXIocm91bmQoZ3JhbXBpYW5zX3RheGFfdGFiJG1heF9oZWlnaHRfbSwgMCkpLAogIGNoZWNrLm5hbWVzID0gRkFMU0UsCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKCmdyYW1waWFuc190YXhhX3RhYlsKICAgIGdyYW1waWFuc190YXhhX3RhYlssIDFdJWluJQogICAgICBjKAogICAgICAgICJcXHRleHRpdHtFLiBnb25pb2NhbHl4IHNzcC4gKGdvbmlvY2FseXh8dmlyaWRpc3NpbWEpfSIsCiAgICAgICAgIlxcdGV4dGl0e0UuIGxldWNveHlsb24gc3NwLiAobGV1Y294eWxvbnxwcnVpbm9zYSl9IgogICAgICApLCAxCiAgXSA8LSBjKAogICAgIlxcdGV4dGl0e0UuIGdvbmlvY2FseXh9IiwKICAgICJcXHRleHRpdHtFLiBsZXVjb3h5bG9ufSIKICApCgpkaXIuY3JlYXRlKAogIGhlcmUoIm5vdGVib29rcy9ldWNhbHlwdF90YXhhX3N1bW1hcmllc19maWxlcyIpLAogIHNob3dXYXJuaW5ncyA9IEZBTFNFCikKCnByaW50KAogIHh0YWJsZSgKICAgIGdyYW1waWFuc190YXhhX3RhYiwgY2FwdGlvbiA9CiAgICAgICJHcmFtcGlhbnMgdGF4YS4gTnVtYmVyIG9mIHBsb3RzIGF0IHdoaWNoIGVhY2ggdGF4YSBvY2N1cnJlZC4KICAgICAgTWVkaWFuIFNMQSAobnVtYmVyIG9mIGxlYXZlcy9udW1iZXIgb2YgdHJlZXMpLiBNZWRpYW4gc2VlZCBtYXNzIChudW1iZXIgb2YKICAgICAgc2FtcGxlcykuIE1heGltdW0gYXR0YWluYWJsZSBoZWlnaHQuIiwKICAgIGxhYmVsID0gInRhYjpncmFtcGlhbnN0YXhhc3VtbWFyeSIKICApLAogIGZpbGUgPSBoZXJlKAogICAgIm5vdGVib29rcy9ldWNhbHlwdF90YXhhX3N1bW1hcmllc19maWxlcy9ncmFtcGlhbnNzdW1tYXJ5dGFiLnRleCIKICApLAogIGluY2x1ZGUucm93bmFtZXMgPSBGQUxTRSwKICB0YWJsZS5wbGFjZW1lbnQgPSAiaHRicCEiLAogIGNhcHRpb24ucGxhY2VtZW50ID0gInRvcCIsCiAgc2FuaXRpemUudGV4dC5mdW5jdGlvbiA9IGlkZW50aXR5CikKCgojKyBzb3V0aGVhc3RfdGF4YV90YWJsZSwgbWVzc2FnZT1GQUxTRSwgd2FyaW5nPUZBTFNFCnNvdXRoZWFzdF90YXhhX3RhYiA8LSBzdWJzZXQoCiAgY29tYmluZV90YXhhX3RyYWl0cyhtZWRpYW5zX3NvdXRoZWFzdCwgZXVjdGlsczo6dGF4YV9ncm91cHMpLAogIHNlbGVjdCA9IGModGF4b24sIHNsYV9tbTJfcGVyX21nLCBzZWVkX21hc3NfbWcsIG1heF9oZWlnaHRfbSkKKQoKc291dGhlYXN0X3NhbXBsZXMgPC0gbG9jYWwoewogICAgZGYgPC0gdHJhaXRzX3NvdXRoZWFzdAogICAgZm9yIChpIGluIHNlcV9hbG9uZyh0YXhhX2dyb3VwcykpIHsKICAgICAgZGZbCiAgICAgICAgZ3JlcGwodGF4YV9ncm91cHNbaV0sIGRmJHRheG9uKSB8CiAgICAgICAgZ3JlcGwodGF4YV9ncm91cHNbaV0sIGRmJHRheG9uLCBmaXhlZCA9IFRSVUUpLAogICAgICAgICJ0YXhvbiIKICAgICAgXSA8LSBuYW1lcyh0YXhhX2dyb3VwcylbaV0KICAgIH0KICAgIGRmCiAgfSkKCnNsYV9uX3NhbXBsZXMgPC0gc3Vic2V0KAogIHNvdXRoZWFzdF9zYW1wbGVzLAogIHNlbGVjdCA9IGModHJlZSwgdGF4b24sIHNsYV9tbTJfcGVyX21nKQopCgpzbGFfbl9zYW1wbGVzIDwtIHNsYV9uX3NhbXBsZXNbY29tcGxldGUuY2FzZXMoc2xhX25fc2FtcGxlcyksIF0KCnNtX25fc2FtcGxlcyA8LSBzdWJzZXQoCiAgc291dGhlYXN0X3NhbXBsZXMsCiAgc2VsZWN0ID0gYyh0cmVlLCB0YXhvbiwgc2VlZF9tYXNzX21nKQopCgpzbV9uX3NhbXBsZXMgPC0gc21fbl9zYW1wbGVzW2NvbXBsZXRlLmNhc2VzKHNtX25fc2FtcGxlcyksIF0KCm5wbG90cyA8LSB0YWJsZShzdWJzZXQobW9kZWxkYXRhX3NvdXRoZWFzdCwgb2NjdXBhbmN5LCB0YXhvbikpCgpucmVncyA8LSB0YWJsZSgKICB1bmlxdWUoc3Vic2V0KG1vZGVsZGF0YV9zb3V0aGVhc3QsIG9jY3VwYW5jeSwgYyh0YXhvbiwgaWJyYV9zdWJyZWdpb24pKSkkdGF4b24KKQoKc291dGhlYXN0X3RheGFfdGFiIDwtIHNvdXRoZWFzdF90YXhhX3RhYltjb21wbGV0ZS5jYXNlcyhzb3V0aGVhc3RfdGF4YV90YWIpLCBdCgpzb3V0aGVhc3RfdGF4YV90YWIgPC0gZGF0YS5mcmFtZSgKICAgdGF4b24gPSBzb3V0aGVhc3RfdGF4YV90YWIkdGF4b24sCiAgIlxcdnRvcHtcXGhib3h7XFxzdHJ1dCBOby59XFxoYm94e1xcc3RydXQgb2Z9XFxoYm94e1xcc3RydXQgcmVnaW9uc319IiA9CiAgICBhcy5jaGFyYWN0ZXIobnJlZ3Nbc291dGhlYXN0X3RheGFfdGFiJHRheG9uXSksCiAgIlxcdnRvcHtcXGhib3h7XFxzdHJ1dCBOby59XFxoYm94e1xcc3RydXQgb2Z9XFxoYm94e1xcc3RydXQgcGxvdHN9fSIgPQogICAgYXMuY2hhcmFjdGVyKG5wbG90c1tzb3V0aGVhc3RfdGF4YV90YWIkdGF4b25dKSwKICAiXFx2dG9we1xcaGJveHtcXHN0cnV0IFNMQX1cXGhib3h7XFxzdHJ1dCAobW0kXjIkL21nKX19IiA9IHBhc3RlMCgKICAgIHJvdW5kKHNvdXRoZWFzdF90YXhhX3RhYiRzbGFfbW0yX3Blcl9tZywgMSksCiAgICAiICgiLCB0YWJsZShzbGFfbl9zYW1wbGVzJHRheG9uKVtzb3V0aGVhc3RfdGF4YV90YWIkdGF4b25dLAogICAgIi8iLCB0YWJsZSh1bmlxdWUoc2xhX25fc2FtcGxlc1sxOjJdKSR0YXhvbilbc291dGhlYXN0X3RheGFfdGFiJHRheG9uXSwgIikiCiAgKSwKICAiXFx2dG9we1xcaGJveHtcXHN0cnV0IFNlZWR9XFxoYm94e1xcc3RydXQgbWFzc31cXGhib3h7XFxzdHJ1dCAobWcpfX0iID0KICAgIHBhc3RlMCgKICAgICAgcm91bmQoc291dGhlYXN0X3RheGFfdGFiJHNlZWRfbWFzc19tZywgMSksCiAgICAgICIgKCIsIHRhYmxlKHNtX25fc2FtcGxlcyR0YXhvbilbc291dGhlYXN0X3RheGFfdGFiJHRheG9uXSwKICAgICAgIi8iLCB0YWJsZSh1bmlxdWUoc21fbl9zYW1wbGVzWzE6Ml0pJHRheG9uKVtzb3V0aGVhc3RfdGF4YV90YWIkdGF4b25dLCAiKSIKICAgICksCiAgIlxcdnRvcHtcXGhib3h7XFxzdHJ1dCBNYXh9XFxoYm94e1xcc3RydXQgaGVpZ2h0fVxcaGJveHtcXHN0cnV0IChtKX19IiA9CiAgICBhcy5jaGFyYWN0ZXIocm91bmQoc291dGhlYXN0X3RheGFfdGFiJG1heF9oZWlnaHRfbSwgMCkpLAogIGNoZWNrLm5hbWVzID0gRkFMU0UsCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKCnNvdXRoZWFzdF90YXhhX3RhYiR0YXhvbiA8LSBnc3ViKCJzdWJzcC4iLCAic3NwLiIsIHNvdXRoZWFzdF90YXhhX3RhYiR0YXhvbikKc291dGhlYXN0X3RheGFfdGFiJHRheG9uIDwtIGdzdWIoIigiLCAiIiwgc291dGhlYXN0X3RheGFfdGFiJHRheG9uLCBmaXhlZCA9IFQpCnNvdXRoZWFzdF90YXhhX3RhYiR0YXhvbiA8LSBnc3ViKCIpIiwgIiIsIHNvdXRoZWFzdF90YXhhX3RhYiR0YXhvbiwgZml4ZWQgPSBUKQpzb3V0aGVhc3RfdGF4YV90YWIkdGF4b24gPC0gZ3N1YigifCIsICIvIiwgc291dGhlYXN0X3RheGFfdGFiJHRheG9uLCBmaXhlZCA9IFQpCnNvdXRoZWFzdF90YXhhX3RhYiR0YXhvbiA8LSBwYXN0ZTAoIlxcdGV4dGl0eyIsIHNvdXRoZWFzdF90YXhhX3RhYiR0YXhvbiwgIn0iKQpzb3V0aGVhc3RfdGF4YV90YWIgPC0gc291dGhlYXN0X3RheGFfdGFiW29yZGVyKHNvdXRoZWFzdF90YXhhX3RhYiR0YXhvbiksIF0KCmNvbG5hbWVzKHNvdXRoZWFzdF90YXhhX3RhYilbMV0gPC0KICAiXFx2dG9we1xcaGJveHtcXHN0cnV0IH1cXGhib3h7XFxzdHJ1dCBUYXhvbn19IgoKc291dGhlYXN0X3RheGFfdGFiIDwtIHNvdXRoZWFzdF90YXhhX3RhYltjb21wbGV0ZS5jYXNlcyhzb3V0aGVhc3RfdGF4YV90YWIpLCBdCgpwcmludCgKICB4dGFibGUoCiAgICBzb3V0aGVhc3RfdGF4YV90YWIsCiAgICBjYXB0aW9uID0KICAgICAgIlNvdXRoZWFzdCB0YXhhLiBOdW1iZXIgb2YgSUJSQSBzdWJyZWdpb25zIGluIHdoaWNoIHRoZSB0YXhvbiBvY2N1cnMuCiAgICAgIE51bWJlciBvZiBwbG90cyBhdCB3aGljaCBlYWNoIHRheGEgb2NjdXJyZWQuIE1lZGlhbiBTTEEgKG51bWJlciBvZgogICAgICBsZWF2ZXMvbnVtYmVyIG9mIHRyZWVzKS4gTWVkaWFuIHNlZWQgbWFzcyAobnVtYmVyIG9mIHNhbXBsZXMvbnVtYmVyIG9mCiAgICAgIHRyZWVzKS4gTWF4aW11bSBhdHRhaW5hYmxlIGhlaWdodC4iLAogICAgbGFiZWwgPSAidGFiOnNvdXRoZWFzdHRheGFzdW1tYXJ5IiwKICAgIGFsaWduID0gYygKICAgICAgImwiLCAiUHsuNDJcXHRleHR3aWR0aH0iLCAiUHsuMDdcXHRleHR3aWR0aH0iLCAiUHsuMDQ1XFx0ZXh0d2lkdGh9IiwKICAgICAgIlB7LjExXFx0ZXh0d2lkdGh9IiwgIlB7LjExXFx0ZXh0d2lkdGh9IiwgIlB7LjA2XFx0ZXh0d2lkdGh9IgogICAgKQogICksCiAgZmlsZSA9IGhlcmUoCiAgICAibm90ZWJvb2tzL2V1Y2FseXB0X3RheGFfc3VtbWFyaWVzX2ZpbGVzL3NvdXRoZWFzdHN1bW1hcnl0YWIudGV4IgogICksCiAgdGFidWxhci5lbnZpcm9ubWVudCA9ICdsb25ndGFibGUnLAogIHNpemUgPSAiXFxmb250c2l6ZXs4cHR9ezhwdH1cXHNlbGVjdGZvbnQiLAogIGhsaW5lLmFmdGVyID0gLTEsCiAgaW5jbHVkZS5jb2xuYW1lcyA9IFRSVUUsCiAgZmxvYXRpbmcgPSBGQUxTRSwKICBhZGQudG8ucm93ID0gbGlzdChwb3MgPSBsaXN0KDApLCBjb21tYW5kID0gIlxcaGxpbmUgXFxlbmRoZWFkICIpLAogIGluY2x1ZGUucm93bmFtZXMgPSBGQUxTRSwKICB0YWJsZS5wbGFjZW1lbnQgPSAiaHRicCEiLAogIGNhcHRpb24ucGxhY2VtZW50ID0gInRvcCIsCiAgc2FuaXRpemUudGV4dC5mdW5jdGlvbiA9IGlkZW50aXR5CikKCiMnICMjIENvcnJlbGF0aW9ucyBhbW9uZyB0cmFpdHMKIysgcGFpcnMtdHJhaXRzLCBmaWcud2lkdGggPSAzLjUsIGZpZy5oZWlnaHQgPSAzLjUsIHdhcm5pbmcgPSBGQUxTRSwgZGV2LmFyZ3MgPSBsaXN0KHBvaW50c2l6ZSA9IDgpCnBhcihtYXIgPSByZXAoLjUsIDQpLCBvbWEgPSBjKDMsIDQsIDQsIDMpLCBtZnJvdyA9IGMoMiwgMikpCnJnbnMgPC0gYygiU291dGgtZWFzdCBBdXN0cmFsaWEiID0gRkFMU0UsICJHcmFtcGlhbnMiID0gVFJVRSkKdmFycyA8LSBsaXN0KCkKdmFyc1tbMV1dIDwtIGMoInNsYV9tbTJfcGVyX21nIiwgInNlZWRfbWFzc19tZyIpCnZhcnNbWzJdXSA8LSBjKCJtYXhfaGVpZ2h0X20iLCAic2VlZF9tYXNzX21nIikKbGFiZWxzIDwtIGMoCiAgc2xhX21tMl9wZXJfbWcgPSAiU0xBIChtbVx1MDBiMi9tZykiLAogIHNlZWRfbWFzc19tZyAgID0gIlNlZWQgbWFzcyAobWcpIiwKICBtYXhfaGVpZ2h0X20gICA9ICJNYXhpbXVtIGhlaWdodCAobSkiCikKCnRyYWl0X2RhdGEgPC0gbGlzdCgpCnRyYWl0X2RhdGEkc291dGhlYXN0IDwtCiAgdW5pcXVlKG1vZGVsZGF0YV9zb3V0aGVhc3RbLCBjKCJ0YXhvbiIsIG5hbWVzKGxhYmVscykpXSlbLTFdCnRyYWl0X2RhdGEkZ3JhbXBpYW5zIDwtCiAgdW5pcXVlKG1vZGVsZGF0YV9ncmFtcGlhbnNbLCBjKCJ0YXhvbiIsIG5hbWVzKGxhYmVscykpXSlbLTFdCgpmb3IgKGkgaW4gc2VxKHZhcnNbWzFdXSkpIHsKICBmb3IgKGogaW4gc2VxKHZhcnNbWzJdXSkpIHsKICAgIGlmIChzdW0oaSwgaikgPiAzKSB7CiAgICAgIHBsb3QubmV3KCkKICAgICAgaWYgKGkgPT0gaikgewogICAgICAgIGxlZ2VuZCgKICAgICAgICAgICJjZW50ZXIiLCBjKCJTb3V0aGVhc3QiLCJHcmFtcGlhbnMiKSwKICAgICAgICAgIGZpbGwgPSBjKCJibGFjayIsICJ3aGl0ZSIpLAogICAgICAgICAgYnR5ID0gIm4iLCBjZXggPSAxLCB4cGQgPSBOQQogICAgICAgICkKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgcGxvdCgKICAgICAgICBzdWJzZXQodHJhaXRfZGF0YVtbMV1dLCBzZWxlY3QgPSBjKHZhcnNbWzFdXVtqXSwgdmFyc1tbMl1dW2ldKSksCiAgICAgICAgeGF4dCA9ICJuIiwgeWF4dCA9ICJuIiwgcGNoID0gMTksIGxvZyA9ICJ4eSIsCiAgICAgICAgcGFuZWwuZmlyc3QgPSBncmlkKGNvbCA9ICJncmV5IiksCiAgICAgICAgeGxpbSA9IHJhbmdlKGRvLmNhbGwocmJpbmQsIHRyYWl0X2RhdGEpW3ZhcnNbWzFdXVtqXV0sIG5hLnJtID0gVFJVRSkgKiBjKC45LCAxLjIpLAogICAgICAgIHlsaW0gPSByYW5nZShkby5jYWxsKHJiaW5kLCB0cmFpdF9kYXRhKVt2YXJzW1syXV1baV1dLCBuYS5ybSA9IFRSVUUpICogYyguOSwgMS4yKQogICAgICApCiAgICAgIHBvaW50cygKICAgICAgICBzdWJzZXQodHJhaXRfZGF0YVtbMl1dLCBzZWxlY3QgPSBjKHZhcnNbWzFdXVtqXSwgdmFyc1tbMl1dW2ldKSksCiAgICAgICAgYmcgPSAid2hpdGUiLCBwY2ggPSAyMQogICAgICApCiAgICAgIGlmIChzdW0oaSwgaikgPT0gMykgewogICAgICAgIGF4aXMoMSwgY2V4LmF4aXMgPSAuOCkKICAgICAgICBheGlzKDQsIGxhcyA9IDEsIGNleC5heGlzID0gLjgpCiAgICAgIH0KICAgICAgaWYgKGkgPT0gMSkgbXRleHQobGFiZWxzW3ZhcnNbWzFdXVtqXV0sIDMsIDEpCiAgICAgIGlmIChqID09IDEpIG10ZXh0KGxhYmVsc1t2YXJzW1syXV1baV1dLCAyLCAxKQogICAgfQogIH0KfQo=