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=