index.html macrophage_estimation.html

1 RNA sequencing of Leishmania panamensis during infection of human macrophages: Differential Expression

In ‘macrophage_estimation’, we did a series of analyses to try to pick out some of the surrogate variables in the data. Now we will perform a set of differential expression analyses using the results from that. Since the ‘batch’ element of the data is reasonably well explained, we will not abuse the data with sva/combat, but instead include batch in the experimental model.

2 Differential expression analyses

It appears that it is possible though somewhat difficult to apply batch estimations generated by sva to the model given to DESeq/EdgeR/limma. In the case of limma it is fairly simple, but in the other two it is a bit more difficult. There is a nice discussion of this at: https://www.biostars.org/p/156186/ I am attempting to apply that logic to this data with limited success.

my_contrasts <- list(
    "macro_chr-sh" = c("macro_ch","macro_sh"),
    "macro_chr-nil" = c("macro_ch","macro_nil"),
    "macro_sh-nil" = c("macro_sh", "macro_nil"))
macro_norm <- sm(normalize_expt(macrophage_parasite, filter=TRUE, convert="cpm", norm="quant"))
## Error in normalize_expt(macrophage_parasite, filter = TRUE, convert = "cpm", : object 'macrophage_parasite' not found
macro_combat_norm <- sm(normalize_expt(macrophage_parasite, filter=TRUE, norm="quant", batch="combat_scale"))
## Error in normalize_expt(macrophage_parasite, filter = TRUE, norm = "quant", : object 'macrophage_parasite' not found
macro_lowfilt <- sm(normalize_expt(macrophage_parasite, filter=TRUE))
## Error in normalize_expt(macrophage_parasite, filter = TRUE): object 'macrophage_parasite' not found
## Set up the data used in the 3 comparative contrast sets.

2.1 No batch in the model

macro_nobatch <- sm(all_pairwise(macro_lowfilt, model_batch=FALSE))
## Error in exists(sym, env, mode = "function", inherits = FALSE): object 'macro_lowfilt' not found
## wow, all tools including basic agree almost completely
medians_by_condition <- macro_nobatch$basic$medians
## Error in eval(expr, envir, enclos): object 'macro_nobatch' not found
macro_nobatch_tables <- sm(combine_de_tables(macro_nobatch,
                                             excel=paste0("excel/macrophage_nobatch-v", ver, ".xlsx"),
                                             keepers=my_contrasts,
                                             extra_annot=medians_by_condition))
## Error in combine_de_tables(macro_nobatch, excel = paste0("excel/macrophage_nobatch-v", : object 'macro_nobatch' not found
macro_nobatch_sig <- sm(extract_significant_genes(macro_nobatch_tables,
                                                  excel=paste0("excel/macrophage_nobatch_significant-v", ver, ".xlsx"),
                                                  p_type="unadjusted",
                                                  according_to="all"))
## Error in extract_significant_genes(macro_nobatch_tables, excel = paste0("excel/macrophage_nobatch_significant-v", : object 'macro_nobatch_tables' not found

2.2 Batch in the model

In this attempt, we add a batch factor in the experimental model and see how it does.

## Here just let all_pairwise run on filtered data and do its normal ~ 0 + condition + batch analyses
macro_batch <- sm(all_pairwise(macro_lowfilt))
## Error in exists(sym, env, mode = "function", inherits = FALSE): object 'macro_lowfilt' not found
medians_by_condition <- macro_batch$basic$medians
## Error in eval(expr, envir, enclos): object 'macro_batch' not found
macro_batch_tables <- sm(combine_de_tables(macro_batch, excel=paste0("excel/macrophage_batchmodel-v", ver, ".xlsx"),
                                           keepers=my_contrasts,
                                           extra_annot=medians_by_condition))
## Error in combine_de_tables(macro_batch, excel = paste0("excel/macrophage_batchmodel-v", : object 'macro_batch' not found
macro_batch_sig <- sm(extract_significant_genes(macro_batch_tables,
                                                excel=paste0("excel/macrophage_batchmodel_significant-v", ver, ".xlsx"),
                                                p_type="unadjusted",
                                                according_to="all"))
## Error in extract_significant_genes(macro_batch_tables, excel = paste0("excel/macrophage_batchmodel_significant-v", : object 'macro_batch_tables' not found

2.3 Batch estimated with SVA

## Here just let all_pairwise run on filtered data and do its normal ~ 0 + condition + batch analyses
macro_sva <- sm(all_pairwise(macro_lowfilt, model_batch="sva"))
## Error in get_model_adjust(input, estimate_type = model_batch, surrogates = surrogates): object 'macro_lowfilt' not found
medians_by_condition <- macro_sva$basic$medians
## Error in eval(expr, envir, enclos): object 'macro_sva' not found
macro_sva_tables <- sm(combine_de_tables(macro_sva, excel=paste0("excel/macrophage_sva-v", ver, ".xlsx"),
                                         keepers=my_contrasts,
                                         extra_annot=medians_by_condition))
## Error in combine_de_tables(macro_sva, excel = paste0("excel/macrophage_sva-v", : object 'macro_sva' not found
macro_sva_sig <- sm(extract_significant_genes(macro_sva_tables,
                                              excel=paste0("excel/macrophage_sva_significant-v", ver, ".xlsx"),
                                              p_type="unadjusted",
                                              according_to="all"))
## Error in extract_significant_genes(macro_sva_tables, excel = paste0("excel/macrophage_sva_significant-v", : object 'macro_sva_tables' not found

2.4 Batch correction via ruv residuals

## Here just let all_pairwise run on filtered data and do its normal ~ 0 + condition + batch analyses
## Bizarrely, sometimes if one runs this, it gives an error "Error in (function (classes, fdef, mtable) : unable to find an inherited method for function 'RUVr' for signature '"matrix", "logical", "numeric", "NULL"'"  -- however, if one then simply runs it again it works fine.
## I am going to assume that it is because I do not explicitly invoke the library.
library(ruv)
macro_ruvres <- try(sm(all_pairwise(macro_lowfilt, model_batch="ruv_residuals")))
if (class(macro_ruvres) == "try-error") {
    macro_ruvres <- sm(all_pairwise(macro_lowfilt, model_batch="ruv_residuals"))
}
## Error in get_model_adjust(input, estimate_type = model_batch, surrogates = surrogates): object 'macro_lowfilt' not found
medians_by_condition <- macro_ruvres$basic$medians
## Error in macro_ruvres$basic: $ operator is invalid for atomic vectors
macro_ruvres_tables <- sm(combine_de_tables(macro_ruvres, excel=paste0("excel/macrophage_ruvres-v", ver, ".xlsx"),
                                            keepers=my_contrasts,
                                            extra_annot=medians_by_condition))
## Error in all_pairwise_result[["limma"]]: subscript out of bounds
macro_ruvres_sig <- sm(extract_significant_genes(macro_ruvres_tables,
                                                 excel=paste0("excel/macrophage_ruvres_significant-v", ver, ".xlsx"),
                                                 p_type="unadjusted",
                                                 according_to="all"))
## Error in extract_significant_genes(macro_ruvres_tables, excel = paste0("excel/macrophage_ruvres_significant-v", : object 'macro_ruvres_tables' not found

2.5 Batch correction with pca

## Here just let all_pairwise run on filtered data and do its normal ~ 0 + condition + batch analyses
macro_pca <- sm(all_pairwise(macro_lowfilt, model_batch="pca"))
## Error in get_model_adjust(input, estimate_type = model_batch, surrogates = surrogates): object 'macro_lowfilt' not found
medians_by_condition <- macro_pca$basic$medians
## Error in eval(expr, envir, enclos): object 'macro_pca' not found
macro_pca_tables <- sm(combine_de_tables(macro_pca, excel=paste0("excel/macrophage_pca-v", ver, ".xlsx"),
                                         keepers=my_contrasts,
                                         extra_annot=medians_by_condition))
## Error in combine_de_tables(macro_pca, excel = paste0("excel/macrophage_pca-v", : object 'macro_pca' not found
macro_pca_sig <- sm(extract_significant_genes(macro_pca_tables,
                                              excel=paste0("excel/macrophage_pca_significant-v", ver, ".xlsx"),
                                              p_type="unadjusted",
                                              according_to="all"))
## Error in extract_significant_genes(macro_pca_tables, excel = paste0("excel/macrophage_pca_significant-v", : object 'macro_pca_tables' not found

2.6 Batch correction with ruv empirical

## Here just let all_pairwise run on filtered data and do its normal ~ 0 + condition + batch analyses
macro_ruvemp <- sm(all_pairwise(macro_lowfilt, model_batch="ruv_empirical"))
## Error in get_model_adjust(input, estimate_type = model_batch, surrogates = surrogates): object 'macro_lowfilt' not found
medians_by_condition <- macro_ruvemp$basic$medians
## Error in eval(expr, envir, enclos): object 'macro_ruvemp' not found
macro_ruvemp_tables <- sm(combine_de_tables(macro_ruvemp, excel=paste0("excel/macrophage_ruvemp-v", ver, ".xlsx"),
                                            keepers=my_contrasts,
                                            extra_annot=medians_by_condition))
## Error in combine_de_tables(macro_ruvemp, excel = paste0("excel/macrophage_ruvemp-v", : object 'macro_ruvemp' not found
macro_ruvemp_sig <- sm(extract_significant_genes(macro_ruvemp_tables,
                                                 excel=paste0("excel/macrophage_ruvemp_significant-v", ver, ".xlsx"),
                                                 p_type="unadjusted",
                                                 according_to="all"))
## Error in extract_significant_genes(macro_ruvemp_tables, excel = paste0("excel/macrophage_ruvemp_significant-v", : object 'macro_ruvemp_tables' not found

2.7 Batch correction with combat

Then repeat with the batch-corrected data and see the differences.

macro_combat <- sm(all_pairwise(macro_combat_norm, force=TRUE))
## Error in exists(sym, env, mode = "function", inherits = FALSE): object 'macro_combat_norm' not found
medians_by_condition <- macro_combat$basic$medians
## Error in eval(expr, envir, enclos): object 'macro_combat' not found
macro_combat_tables <- sm(combine_de_tables(macro_combat,
                                            excel=paste0("excel/macrophage_combat-v", ver, ".xlsx"),
                                            keepers=my_contrasts,
                                            extra_annot=medians_by_condition))
## Error in combine_de_tables(macro_combat, excel = paste0("excel/macrophage_combat-v", : object 'macro_combat' not found
macro_combat_sig <- sm(extract_significant_genes(macro_combat_tables,
                                                 excel=paste0("excel/macrophage_combat_significant-v", ver, ".xlsx"),
                                                 p_type="unadjusted",
                                                 according_to="all"))
## Error in extract_significant_genes(macro_combat_tables, excel = paste0("excel/macrophage_combat_significant-v", : object 'macro_combat_tables' not found

3 Figure out how to compare these results

I have 4 methods of performing this differential expression analysis. Each one comes with a set of metrics defining ‘significant’. Perhaps I can make a table of the # of genes defined as significant by contrast for each. In addition it may be worth while to do a scatter plots of the logFCs between these comparisons and see how well they agree?

4 Look first at the de counts

macro_nobatch_sig$limma$counts
## Error in eval(expr, envir, enclos): object 'macro_nobatch_sig' not found
macro_batch_sig$limma$counts
## Error in eval(expr, envir, enclos): object 'macro_batch_sig' not found
macro_sva_sig$limma$counts
## Error in eval(expr, envir, enclos): object 'macro_sva_sig' not found
macro_ruvres_sig$limma$counts
## Error in eval(expr, envir, enclos): object 'macro_ruvres_sig' not found
macro_pca_sig$limma$counts
## Error in eval(expr, envir, enclos): object 'macro_pca_sig' not found
macro_ruvemp_sig$limma$counts
## Error in eval(expr, envir, enclos): object 'macro_ruvemp_sig' not found
macro_combat_sig$limma$counts
## Error in eval(expr, envir, enclos): object 'macro_combat_sig' not found

4.1 Compare DeSeq / Basic without batch in model

nobatch_basic <- merge(macro_nobatch$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$basic$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_nobatch$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$basic$all_tables$macro_sh_vs_macro_ch, : object 'macro_nobatch' not found
rownames(nobatch_basic) <- nobatch_basic[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'nobatch_basic' not found
nobatch_logfc <- nobatch_basic[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'nobatch_basic' not found
colnames(nobatch_logfc) <- c("nobatch","basic")
## Error in colnames(nobatch_logfc) <- c("nobatch", "basic"): object 'nobatch_logfc' not found
lfc_nb_b <- sm(plot_linear_scatter(nobatch_logfc, pretty_colors=FALSE))
## Error in data.frame(df[, c(1, 2)]): object 'nobatch_logfc' not found
lfc_nb_b$scatter
## Error in eval(expr, envir, enclos): object 'lfc_nb_b' not found
lfc_nb_b$correlation
## Error in eval(expr, envir, enclos): object 'lfc_nb_b' not found
nobatch_p <- nobatch_basic[, c("P.Value","p")]
## Error in eval(expr, envir, enclos): object 'nobatch_basic' not found
nobatch_p[[2]] <- as.numeric(nobatch_p[[2]])
## Error in eval(expr, envir, enclos): object 'nobatch_p' not found
colnames(nobatch_p) <- c("nobatch","basic")
## Error in colnames(nobatch_p) <- c("nobatch", "basic"): object 'nobatch_p' not found
nobatch_p <- -1 * log(nobatch_p)
## Error in eval(expr, envir, enclos): object 'nobatch_p' not found
p_nb_b <- sm(plot_linear_scatter(nobatch_p, pretty_colors=FALSE))
## Error in data.frame(df[, c(1, 2)]): object 'nobatch_p' not found
p_nb_b$scatter
## Error in eval(expr, envir, enclos): object 'p_nb_b' not found
p_nb_b$correlation
## Error in eval(expr, envir, enclos): object 'p_nb_b' not found

4.2 Compare SVA to batch in model, DESeq

sva_batch <- merge(macro_sva$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$deseq$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_sva$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$deseq$all_tables$macro_sh_vs_macro_ch, : object 'macro_sva' not found
rownames(sva_batch) <- sva_batch[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'sva_batch' not found
sva_logfc <- sva_batch[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'sva_batch' not found
colnames(sva_logfc) <- c("sva","batch")
## Error in colnames(sva_logfc) <- c("sva", "batch"): object 'sva_logfc' not found
lfc_b_s <- sm(plot_linear_scatter(sva_logfc, pretty_colors=FALSE))
## Error in data.frame(df[, c(1, 2)]): object 'sva_logfc' not found
lfc_b_s$scatter
## Error in eval(expr, envir, enclos): object 'lfc_b_s' not found
lfc_b_s$correlation
## Error in eval(expr, envir, enclos): object 'lfc_b_s' not found
sva_p <- sva_batch[, c("P.Value.x","P.Value.y")]
## Error in eval(expr, envir, enclos): object 'sva_batch' not found
sva_p[[2]] <- as.numeric(sva_p[[2]])
## Error in eval(expr, envir, enclos): object 'sva_p' not found
colnames(sva_p) <- c("sva","batch")
## Error in colnames(sva_p) <- c("sva", "batch"): object 'sva_p' not found
sva_p <- -1 * log(sva_p)
## Error in eval(expr, envir, enclos): object 'sva_p' not found
p_b_s <- sm(plot_linear_scatter(sva_p, pretty_colors=FALSE))
## Error in data.frame(df[, c(1, 2)]): object 'sva_p' not found
p_b_s$scatter
## Error in eval(expr, envir, enclos): object 'p_b_s' not found
p_b_s$correlation
## Error in eval(expr, envir, enclos): object 'p_b_s' not found

4.2.1 Include p-value estimations

Try putting some information of the p-values with the comparative log2fc

lfcp_b_s <- sva_batch[, c("logFC.x", "logFC.y", "P.Value.x", "P.Value.y")]
## Error in eval(expr, envir, enclos): object 'sva_batch' not found
colnames(lfcp_b_s) <- c("l2fcsva", "l2fcbatch", "psva", "pbatch")
## Error in colnames(lfcp_b_s) <- c("l2fcsva", "l2fcbatch", "psva", "pbatch"): object 'lfcp_b_s' not found
lfc_b_s$scatter
## Error in eval(expr, envir, enclos): object 'lfc_b_s' not found
cutoff <- 0.1
lfcp_b_s$state <- ifelse(lfcp_b_s$psva > cutoff & lfcp_b_s$pbatch > cutoff, "bothinsig",
                  ifelse(lfcp_b_s$psva <= cutoff & lfcp_b_s$pbatch <= cutoff, "bothsig",
                  ifelse(lfcp_b_s$psva <= cutoff, "svasig", "batchsig")))
## Error in ifelse(lfcp_b_s$psva > cutoff & lfcp_b_s$pbatch > cutoff, "bothinsig", : object 'lfcp_b_s' not found
##lfcp_b_s$lfcstate <- ifelse(lfcp_b_s$l2fcsva >= 0.75 & lfcp_b_s$l2fcbatch, "", "")
num_bothinsig <- sum(lfcp_b_s$state == "bothinsig")
## Error in eval(expr, envir, enclos): object 'lfcp_b_s' not found
num_bothsig <- sum(lfcp_b_s$state == "bothsig")
## Error in eval(expr, envir, enclos): object 'lfcp_b_s' not found
num_svasig <- sum(lfcp_b_s$state == "svasig")
## Error in eval(expr, envir, enclos): object 'lfcp_b_s' not found
num_batchsig <- sum(lfcp_b_s$state == "batchsig")
## Error in eval(expr, envir, enclos): object 'lfcp_b_s' not found
library(ggplot2)
aes_color = "(l2fcsva >= 0.75 | l2fcsva <= -0.75 | l2fcbatch >= 0.75 | l2fcbatch <= -0.75)"

plt <- ggplot2::ggplot(lfcp_b_s, aes_string(x="l2fcsva", y="l2fcbatch")) +
    ## ggplot2::geom_point(stat="identity", size=2, alpha=0.2, aes_string(shape="as.factor(aes_color)", colour="as.factor(state)", fill="as.factor(state)")) +
    ggplot2::geom_abline(colour="blue", slope=1, intercept=0, size=0.5) +
    ggplot2::geom_hline(yintercept=c(-0.75, 0.75), color="red", size=0.5) +
    ggplot2::geom_vline(xintercept=c(-0.75, 0.75), color="red", size=0.5) +
    ggplot2::geom_point(stat="identity", size=2, alpha=0.2, aes_string(colour="as.factor(state)", fill="as.factor(state)")) +
    ggplot2::scale_color_manual(name="state", values=c("bothinsig"="grey", "bothsig"="forestgreen", "svasig"="darkred", "batchsig"="darkblue")) +
    ggplot2::scale_fill_manual(name="state", values=c("bothinsig"="grey", "bothsig"="forestgreen", "svasig"="darkred", "batchsig"="darkblue"),
                               labels=c(
                                   paste0("Both InSig.: ", num_bothinsig),
                                   paste0("Both Sig.: ", num_bothsig),
                                   paste0("Sva Sig.: ", num_svasig),
                                   paste0("Batch Sig.: ", num_batchsig)),
                               guide=ggplot2::guide_legend(override.aes=aes(size=3, fill="grey"))) +
    ggplot2::guides(fill=ggplot2::guide_legend(override.aes=list(size=3))) +
    ggplot2::theme_bw()
## Error in ggplot2::ggplot(lfcp_b_s, aes_string(x = "l2fcsva", y = "l2fcbatch")): object 'lfcp_b_s' not found
plt
## Error in eval(expr, envir, enclos): object 'plt' not found

4.3 Compare ruvresid to batch in model, DESeq

batch_ruvresid_deseq <- merge(macro_ruvres$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$basic$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in macro_ruvres$deseq: $ operator is invalid for atomic vectors
rownames(batch_ruvresid_deseq) <- batch_ruvresid_deseq[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'batch_ruvresid_deseq' not found
batch_ruvresid_logfc <- batch_ruvresid_deseq[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'batch_ruvresid_deseq' not found
colnames(batch_ruvresid_logfc) <- c("nobatch","basic")
## Error in colnames(batch_ruvresid_logfc) <- c("nobatch", "basic"): object 'batch_ruvresid_logfc' not found
lfc_ruv_bat <- plot_linear_scatter(batch_ruvresid_logfc, pretty_colors=FALSE)
## Error in data.frame(df[, c(1, 2)]): object 'batch_ruvresid_logfc' not found
lfc_ruv_bat$scatter
## Error in eval(expr, envir, enclos): object 'lfc_ruv_bat' not found
lfc_ruv_bat$correlation
## Error in eval(expr, envir, enclos): object 'lfc_ruv_bat' not found

4.4 Compare pca to batch in model, DESeq

batch_pca_deseq <- merge(macro_pca$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$basic$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_pca$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$basic$all_tables$macro_sh_vs_macro_ch, : object 'macro_pca' not found
rownames(batch_pca_deseq) <- batch_pca_deseq[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'batch_pca_deseq' not found
batch_pca_logfc <- batch_pca_deseq[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'batch_pca_deseq' not found
colnames(batch_pca_logfc) <- c("nobatch","basic")
## Error in colnames(batch_pca_logfc) <- c("nobatch", "basic"): object 'batch_pca_logfc' not found
lfc_pca_bat <- plot_linear_scatter(batch_pca_logfc, pretty_colors=FALSE)
## Error in data.frame(df[, c(1, 2)]): object 'batch_pca_logfc' not found
lfc_pca_bat$scatter
## Error in eval(expr, envir, enclos): object 'lfc_pca_bat' not found
lfc_pca_bat$correlation
## Error in eval(expr, envir, enclos): object 'lfc_pca_bat' not found

4.5 Compare ruv empirical to batch in model, DESeq

batch_ruvemp_deseq <- merge(macro_ruvemp$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$basic$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_ruvemp$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$basic$all_tables$macro_sh_vs_macro_ch, : object 'macro_ruvemp' not found
rownames(batch_ruvemp_deseq) <- batch_ruvemp_deseq[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'batch_ruvemp_deseq' not found
batch_ruvemp_logfc <- batch_ruvemp_deseq[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'batch_ruvemp_deseq' not found
colnames(batch_ruvemp_logfc) <- c("nobatch","basic")
## Error in colnames(batch_ruvemp_logfc) <- c("nobatch", "basic"): object 'batch_ruvemp_logfc' not found
lfc_ruvemp_bat <- sm(plot_linear_scatter(batch_ruvemp_logfc, pretty_colors=FALSE))
## Error in data.frame(df[, c(1, 2)]): object 'batch_ruvemp_logfc' not found
lfc_ruvemp_bat$scatter
## Error in eval(expr, envir, enclos): object 'lfc_ruvemp_bat' not found
lfc_ruvemp_bat$correlation
## Error in eval(expr, envir, enclos): object 'lfc_ruvemp_bat' not found

4.6 Compare combat to batch in model, DESeq

combat_batch <- merge(macro_combat$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$deseq$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_combat$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$deseq$all_tables$macro_sh_vs_macro_ch, : object 'macro_combat' not found
rownames(combat_batch) <- combat_batch[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'combat_batch' not found
combat_batch <- combat_batch[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'combat_batch' not found
colnames(combat_batch) <- c("batch","combat")
## Error in colnames(combat_batch) <- c("batch", "combat"): object 'combat_batch' not found
b_c <- plot_linear_scatter(combat_batch, pretty_colors=FALSE)
## Error in data.frame(df[, c(1, 2)]): object 'combat_batch' not found
b_c$scatter
## Error in eval(expr, envir, enclos): object 'b_c' not found
b_c$correlation
## Error in eval(expr, envir, enclos): object 'b_c' not found

4.7 Compare no batch to batch in model, limma

nobatch_batch <- merge(macro_nobatch$limma$all_tables$macro_sh_vs_macro_ch, macro_batch$limma$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_nobatch$limma$all_tables$macro_sh_vs_macro_ch, macro_batch$limma$all_tables$macro_sh_vs_macro_ch, : object 'macro_nobatch' not found
rownames(nobatch_batch) <- nobatch_batch[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'nobatch_batch' not found
nobatch_batch <- nobatch_batch[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'nobatch_batch' not found
colnames(nobatch_batch) <- c("nobatch","batch")
## Error in colnames(nobatch_batch) <- c("nobatch", "batch"): object 'nobatch_batch' not found
nb_b <- plot_linear_scatter(nobatch_batch, pretty_colors=FALSE)
## Error in data.frame(df[, c(1, 2)]): object 'nobatch_batch' not found
nb_b$scatter
## Error in eval(expr, envir, enclos): object 'nb_b' not found
nb_b$correlation
## Error in eval(expr, envir, enclos): object 'nb_b' not found

4.8 Batch in model vs. SVA, limma

batch_sva <- merge(macro_batch$limma$all_tables$macro_sh_vs_macro_ch, macro_sva$limma$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_batch$limma$all_tables$macro_sh_vs_macro_ch, macro_sva$limma$all_tables$macro_sh_vs_macro_ch, : object 'macro_batch' not found
rownames(batch_sva) <- batch_sva[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'batch_sva' not found
batch_sva <- batch_sva[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'batch_sva' not found
colnames(batch_sva) <- c("batch","sva")
## Error in colnames(batch_sva) <- c("batch", "sva"): object 'batch_sva' not found
b_s <- plot_linear_scatter(batch_sva, pretty_colors=FALSE)
## Error in data.frame(df[, c(1, 2)]): object 'batch_sva' not found
b_s$scatter
## Error in eval(expr, envir, enclos): object 'b_s' not found
b_s$correlation
## Error in eval(expr, envir, enclos): object 'b_s' not found

4.9 Batch in model vs. combat, limma

batch_combat <- merge(macro_batch$limma$all_tables$macro_sh_vs_macro_ch, macro_combat$limma$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_batch$limma$all_tables$macro_sh_vs_macro_ch, macro_combat$limma$all_tables$macro_sh_vs_macro_ch, : object 'macro_batch' not found
rownames(batch_combat) <- batch_combat[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'batch_combat' not found
batch_combat <- batch_combat[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'batch_combat' not found
colnames(batch_combat) <- c("batch","combat")
## Error in colnames(batch_combat) <- c("batch", "combat"): object 'batch_combat' not found
b_c <- plot_linear_scatter(batch_combat, pretty_colors=FALSE)
## Error in data.frame(df[, c(1, 2)]): object 'batch_combat' not found
b_c$scatter
## Error in eval(expr, envir, enclos): object 'b_c' not found
b_c$correlation
## Error in eval(expr, envir, enclos): object 'b_c' not found

4.10 Nobatch vs. batch in model, edger

nobatch_batch <- merge(macro_nobatch$edger$all_tables$macro_sh_vs_macro_ch, macro_batch$edger$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_nobatch$edger$all_tables$macro_sh_vs_macro_ch, macro_batch$edger$all_tables$macro_sh_vs_macro_ch, : object 'macro_nobatch' not found
rownames(nobatch_batch) <- nobatch_batch[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'nobatch_batch' not found
nobatch_batch <- nobatch_batch[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'nobatch_batch' not found
colnames(nobatch_batch) <- c("nobatch","batch")
## Error in colnames(nobatch_batch) <- c("nobatch", "batch"): object 'nobatch_batch' not found
nb_b <- sm(plot_linear_scatter(nobatch_batch, pretty_colors=FALSE))
## Error in data.frame(df[, c(1, 2)]): object 'nobatch_batch' not found
nb_b$scatter
## Error in eval(expr, envir, enclos): object 'nb_b' not found
nb_b$correlation
## Error in eval(expr, envir, enclos): object 'nb_b' not found

4.11 Batch in model vs. SVA, edger

batch_sva <- merge(macro_batch$edger$all_tables$macro_sh_vs_macro_ch, macro_sva$edger$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_batch$edger$all_tables$macro_sh_vs_macro_ch, macro_sva$edger$all_tables$macro_sh_vs_macro_ch, : object 'macro_batch' not found
rownames(batch_sva) <- batch_sva[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'batch_sva' not found
batch_sva <- batch_sva[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'batch_sva' not found
colnames(batch_sva) <- c("batch","sva")
## Error in colnames(batch_sva) <- c("batch", "sva"): object 'batch_sva' not found
b_s <- plot_linear_scatter(batch_sva, pretty_colors=FALSE)
## Error in data.frame(df[, c(1, 2)]): object 'batch_sva' not found
b_s$scatter
## Error in eval(expr, envir, enclos): object 'b_s' not found
b_s$correlation
## Error in eval(expr, envir, enclos): object 'b_s' not found

4.12 Batch in model vs. combat, edger

batch_combat <- merge(macro_batch$edger$all_tables$macro_sh_vs_macro_ch, macro_combat$edger$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_batch$edger$all_tables$macro_sh_vs_macro_ch, macro_combat$edger$all_tables$macro_sh_vs_macro_ch, : object 'macro_batch' not found
rownames(batch_combat) <- batch_combat[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'batch_combat' not found
batch_combat <- batch_combat[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'batch_combat' not found
colnames(batch_combat) <- c("batch","combat")
## Error in colnames(batch_combat) <- c("batch", "combat"): object 'batch_combat' not found
b_c <- plot_linear_scatter(batch_combat, pretty_colors=FALSE)
## Error in data.frame(df[, c(1, 2)]): object 'batch_combat' not found
b_c$scatter
## Error in eval(expr, envir, enclos): object 'b_c' not found
b_c$correlation
## Error in eval(expr, envir, enclos): object 'b_c' not found

4.13 Compare nobatch vs. batch, deseq

nobatch_batch <- merge(macro_nobatch$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$deseq$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_nobatch$deseq$all_tables$macro_sh_vs_macro_ch, macro_batch$deseq$all_tables$macro_sh_vs_macro_ch, : object 'macro_nobatch' not found
rownames(nobatch_batch) <- nobatch_batch[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'nobatch_batch' not found
nobatch_batch <- nobatch_batch[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'nobatch_batch' not found
colnames(nobatch_batch) <- c("nobatch","batch")
## Error in colnames(nobatch_batch) <- c("nobatch", "batch"): object 'nobatch_batch' not found
nb_b <- sm(plot_linear_scatter(nobatch_batch, pretty_colors=FALSE))
## Error in data.frame(df[, c(1, 2)]): object 'nobatch_batch' not found
nb_b$scatter
## Error in eval(expr, envir, enclos): object 'nb_b' not found
nb_b$correlation
## Error in eval(expr, envir, enclos): object 'nb_b' not found

4.14 Compare batch vs. SVA, deseq

batch_sva <- merge(macro_batch$deseq$all_tables$macro_sh_vs_macro_ch, macro_sva$deseq$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_batch$deseq$all_tables$macro_sh_vs_macro_ch, macro_sva$deseq$all_tables$macro_sh_vs_macro_ch, : object 'macro_batch' not found
rownames(batch_sva) <- batch_sva[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'batch_sva' not found
batch_sva <- batch_sva[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'batch_sva' not found
colnames(batch_sva) <- c("batch","sva")
## Error in colnames(batch_sva) <- c("batch", "sva"): object 'batch_sva' not found
b_s <- sm(plot_linear_scatter(batch_sva, pretty_colors=FALSE))
## Error in data.frame(df[, c(1, 2)]): object 'batch_sva' not found
b_s$scatter
## Error in eval(expr, envir, enclos): object 'b_s' not found
b_s$correlation
## Error in eval(expr, envir, enclos): object 'b_s' not found

4.15 Batch in model vs. combat, deseq

batch_combat <- merge(macro_batch$deseq$all_tables$macro_sh_vs_macro_ch, macro_combat$deseq$all_tables$macro_sh_vs_macro_ch, by="row.names")
## Error in merge(macro_batch$deseq$all_tables$macro_sh_vs_macro_ch, macro_combat$deseq$all_tables$macro_sh_vs_macro_ch, : object 'macro_batch' not found
rownames(batch_combat) <- batch_combat[["Row.names"]]
## Error in eval(expr, envir, enclos): object 'batch_combat' not found
batch_combat <- batch_combat[, c("logFC.x","logFC.y")]
## Error in eval(expr, envir, enclos): object 'batch_combat' not found
colnames(batch_combat) <- c("batch","combat")
## Error in colnames(batch_combat) <- c("batch", "combat"): object 'batch_combat' not found
b_c <- sm(plot_linear_scatter(batch_combat, pretty_colors=FALSE))
## Error in data.frame(df[, c(1, 2)]): object 'batch_combat' not found
b_c$scatter
## Error in eval(expr, envir, enclos): object 'b_c' not found
b_c$correlation
## Error in eval(expr, envir, enclos): object 'b_c' not found
tmp <- sm(saveme(filename="macrophage_expression_parasite.rda.xz"))

index.html macrophage_estimation.html

LS0tCnRpdGxlOiAiUk5Bc2VxIG9mIEwucGFuYW1lbnNpczogSHVtYW4gTWFjcm9waGFnZSBEaWZmZXJlbnRpYWwgRXhwcmVzc2lvbi4iCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKIGh0bWxfZG9jdW1lbnQ6CiAgY29kZV9kb3dubG9hZDogdHJ1ZQogIGNvZGVfZm9sZGluZzogc2hvdwogIGZpZ19jYXB0aW9uOiB0cnVlCiAgZmlnX2hlaWdodDogNwogIGZpZ193aWR0aDogNwogIGhpZ2hsaWdodDogdGFuZ28KICBrZWVwX21kOiBmYWxzZQogIG1vZGU6IHNlbGZjb250YWluZWQKICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogIHRoZW1lOiBjb3NtbwogIHRvYzogdHJ1ZQogIHRvY19mbG9hdDoKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCi0tLQoKPHN0eWxlPgogIDwhLS0gRG9jdW1lbnQgcHJlbHVkZSByZXZpc2lvbiAyMDE2LTEwIC0tPgogIGJvZHkgLm1haW4tY29udGFpbmVyIHsKICAgIG1heC13aWR0aDogMTYwMHB4Owp9Cjwvc3R5bGU+CgpgYGB7ciBvcHRpb25zLCBpbmNsdWRlPUZBTFNFfQojIyBUaGVzZSBhcmUgdGhlIG9wdGlvbnMgSSB0ZW5kIHRvIGZhdm9yCmxpYnJhcnkoImhwZ2x0b29scyIpCnR0IDwtIHNtKGRldnRvb2xzOjpsb2FkX2FsbCgifi9ocGdsdG9vbHMiKSkKa25pdHI6Om9wdHNfa25pdCRzZXQoCiAgICBwcm9ncmVzcyA9IFRSVUUsCiAgICB2ZXJib3NlID0gVFJVRSwKICAgIHdpZHRoID0gOTAsCiAgICBlY2hvID0gVFJVRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogICAgZXJyb3IgPSBUUlVFLAogICAgZmlnLndpZHRoID0gOCwKICAgIGZpZy5oZWlnaHQgPSA4LAogICAgZHBpID0gOTYpCm9wdGlvbnMoCiAgICBkaWdpdHMgPSA0LAogICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLAogICAga25pdHIuZHVwbGljYXRlLmxhYmVsID0gImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZT0xMCkpCnNldC5zZWVkKDEpCnJtZF9maWxlIDwtICJtYWNyb3BoYWdlX2V4cHJlc3Npb25fcGFyYXNpdGUuUm1kIgp2ZXIgPC0gIjIwMTcwMjAyIgpgYGAKCltpbmRleC5odG1sXShpbmRleC5odG1sKSBbbWFjcm9waGFnZV9lc3RpbWF0aW9uLmh0bWxdKG1hY3JvcGhhZ2VfZXN0aW1hdGlvbi5odG1sKQoKYGBge3IgcmVuZGVyaW5nLCBpbmNsdWRlPUZBTFNFLCBldmFsPUZBTFNFfQojIyBUaGlzIGJsb2NrIGlzIHVzZWQgdG8gcmVuZGVyIGEgZG9jdW1lbnQgZnJvbSB3aXRoaW4gaXQuCnJtYXJrZG93bjo6cmVuZGVyKHJtZF9maWxlKQoKIyMgQW4gZXh0cmEgcmVuZGVyZXIgZm9yIHBkZiBvdXRwdXQKcm1hcmtkb3duOjpyZW5kZXIocm1kX2ZpbGUsIG91dHB1dF9mb3JtYXQ9InBkZl9kb2N1bWVudCIsIG91dHB1dF9vcHRpb25zPWMoInNraXBfaHRtbCIpKQojIyBPciB0byBzYXZlL2xvYWQgbGFyZ2UgUmRhdGEgZmlsZXMuCmhwZ2x0b29sczo6OnNhdmVtZSgpCmhwZ2x0b29sczo6OmxvYWRtZSgpCnJtKGxpc3Q9bHMoKSkKYGBgCgpSTkEgc2VxdWVuY2luZyBvZiBMZWlzaG1hbmlhIHBhbmFtZW5zaXMgZHVyaW5nIGluZmVjdGlvbiBvZiBodW1hbiBtYWNyb3BoYWdlczogRGlmZmVyZW50aWFsIEV4cHJlc3Npb24KPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgpJbiAnbWFjcm9waGFnZV9lc3RpbWF0aW9uJywgd2UgZGlkIGEgc2VyaWVzIG9mIGFuYWx5c2VzIHRvIHRyeSB0byBwaWNrIG91dCBzb21lIG9mIHRoZSBzdXJyb2dhdGUKdmFyaWFibGVzIGluIHRoZSBkYXRhLiAgTm93IHdlIHdpbGwgcGVyZm9ybSBhIHNldCBvZiBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNlcyB1c2luZyB0aGUKcmVzdWx0cyBmcm9tIHRoYXQuICBTaW5jZSB0aGUgJ2JhdGNoJyBlbGVtZW50IG9mIHRoZSBkYXRhIGlzIHJlYXNvbmFibHkgd2VsbCBleHBsYWluZWQsIHdlIHdpbGwgbm90CmFidXNlIHRoZSBkYXRhIHdpdGggc3ZhL2NvbWJhdCwgYnV0IGluc3RlYWQgaW5jbHVkZSBiYXRjaCBpbiB0aGUgZXhwZXJpbWVudGFsIG1vZGVsLgoKYGBge3IgbG9hZG1lLCBpbmNsdWRlPUZBTFNFfQp0bXAgPC0gc20obG9hZG1lKGZpbGVuYW1lPSJtYWNyb3BoYWdlX2VzdGltYXRpb25fcGFyYXNpdGUucmRhLnh6IikpCmBgYAoKIyBEaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNlcwoKSXQgYXBwZWFycyB0aGF0IGl0IGlzIHBvc3NpYmxlIHRob3VnaCBzb21ld2hhdCBkaWZmaWN1bHQgdG8gYXBwbHkgYmF0Y2ggZXN0aW1hdGlvbnMgZ2VuZXJhdGVkIGJ5IHN2YQp0byB0aGUgbW9kZWwgZ2l2ZW4gdG8gREVTZXEvRWRnZVIvbGltbWEuICBJbiB0aGUgY2FzZSBvZiBsaW1tYSBpdCBpcyBmYWlybHkgc2ltcGxlLCBidXQgaW4gdGhlIG90aGVyCnR3byBpdCBpcyBhIGJpdCBtb3JlIGRpZmZpY3VsdC4gIFRoZXJlIGlzIGEgbmljZSBkaXNjdXNzaW9uIG9mIHRoaXMgYXQ6IGh0dHBzOi8vd3d3LmJpb3N0YXJzLm9yZy9wLzE1NjE4Ni8KSSBhbSBhdHRlbXB0aW5nIHRvIGFwcGx5IHRoYXQgbG9naWMgdG8gdGhpcyBkYXRhIHdpdGggbGltaXRlZCBzdWNjZXNzLgoKYGBge3Igc2V0dXBfZGUsIGZpZy5zaG93PSJoaWRlIn0KbXlfY29udHJhc3RzIDwtIGxpc3QoCiAgICAibWFjcm9fY2hyLXNoIiA9IGMoIm1hY3JvX2NoIiwibWFjcm9fc2giKSwKICAgICJtYWNyb19jaHItbmlsIiA9IGMoIm1hY3JvX2NoIiwibWFjcm9fbmlsIiksCiAgICAibWFjcm9fc2gtbmlsIiA9IGMoIm1hY3JvX3NoIiwgIm1hY3JvX25pbCIpKQptYWNyb19ub3JtIDwtIHNtKG5vcm1hbGl6ZV9leHB0KG1hY3JvcGhhZ2VfcGFyYXNpdGUsIGZpbHRlcj1UUlVFLCBjb252ZXJ0PSJjcG0iLCBub3JtPSJxdWFudCIpKQptYWNyb19jb21iYXRfbm9ybSA8LSBzbShub3JtYWxpemVfZXhwdChtYWNyb3BoYWdlX3BhcmFzaXRlLCBmaWx0ZXI9VFJVRSwgbm9ybT0icXVhbnQiLCBiYXRjaD0iY29tYmF0X3NjYWxlIikpCm1hY3JvX2xvd2ZpbHQgPC0gc20obm9ybWFsaXplX2V4cHQobWFjcm9waGFnZV9wYXJhc2l0ZSwgZmlsdGVyPVRSVUUpKQojIyBTZXQgdXAgdGhlIGRhdGEgdXNlZCBpbiB0aGUgMyBjb21wYXJhdGl2ZSBjb250cmFzdCBzZXRzLgpgYGAKCiMjIE5vIGJhdGNoIGluIHRoZSBtb2RlbAoKYGBge3IgbWFjcm9fbm9iYXRjaCwgZmlnLnNob3c9ImhpZGUifQptYWNyb19ub2JhdGNoIDwtIHNtKGFsbF9wYWlyd2lzZShtYWNyb19sb3dmaWx0LCBtb2RlbF9iYXRjaD1GQUxTRSkpCiMjIHdvdywgYWxsIHRvb2xzIGluY2x1ZGluZyBiYXNpYyBhZ3JlZSBhbG1vc3QgY29tcGxldGVseQptZWRpYW5zX2J5X2NvbmRpdGlvbiA8LSBtYWNyb19ub2JhdGNoJGJhc2ljJG1lZGlhbnMKbWFjcm9fbm9iYXRjaF90YWJsZXMgPC0gc20oY29tYmluZV9kZV90YWJsZXMobWFjcm9fbm9iYXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9tYWNyb3BoYWdlX25vYmF0Y2gtdiIsIHZlciwgIi54bHN4IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXBlcnM9bXlfY29udHJhc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYV9hbm5vdD1tZWRpYW5zX2J5X2NvbmRpdGlvbikpCm1hY3JvX25vYmF0Y2hfc2lnIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMobWFjcm9fbm9iYXRjaF90YWJsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9tYWNyb3BoYWdlX25vYmF0Y2hfc2lnbmlmaWNhbnQtdiIsIHZlciwgIi54bHN4IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcF90eXBlPSJ1bmFkanVzdGVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2NvcmRpbmdfdG89ImFsbCIpKQpgYGAKCiMjIEJhdGNoIGluIHRoZSBtb2RlbAoKSW4gdGhpcyAgYXR0ZW1wdCwgd2UgYWRkIGEgYmF0Y2ggZmFjdG9yIGluIHRoZSBleHBlcmltZW50YWwgbW9kZWwgYW5kIHNlZSBob3cgaXQgZG9lcy4KCmBgYHtyIG1hY3JvX2JhdGNoLCBmaWcuc2hvdz0iaGlkZSJ9CiMjIEhlcmUganVzdCBsZXQgYWxsX3BhaXJ3aXNlIHJ1biBvbiBmaWx0ZXJlZCBkYXRhIGFuZCBkbyBpdHMgbm9ybWFsIH4gMCArIGNvbmRpdGlvbiArIGJhdGNoIGFuYWx5c2VzCm1hY3JvX2JhdGNoIDwtIHNtKGFsbF9wYWlyd2lzZShtYWNyb19sb3dmaWx0KSkKbWVkaWFuc19ieV9jb25kaXRpb24gPC0gbWFjcm9fYmF0Y2gkYmFzaWMkbWVkaWFucwptYWNyb19iYXRjaF90YWJsZXMgPC0gc20oY29tYmluZV9kZV90YWJsZXMobWFjcm9fYmF0Y2gsIGV4Y2VsPXBhc3RlMCgiZXhjZWwvbWFjcm9waGFnZV9iYXRjaG1vZGVsLXYiLCB2ZXIsICIueGxzeCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcGVycz1teV9jb250cmFzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYV9hbm5vdD1tZWRpYW5zX2J5X2NvbmRpdGlvbikpCm1hY3JvX2JhdGNoX3NpZyA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKG1hY3JvX2JhdGNoX3RhYmxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9tYWNyb3BoYWdlX2JhdGNobW9kZWxfc2lnbmlmaWNhbnQtdiIsIHZlciwgIi54bHN4IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBfdHlwZT0idW5hZGp1c3RlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY29yZGluZ190bz0iYWxsIikpCmBgYAoKIyMgQmF0Y2ggZXN0aW1hdGVkIHdpdGggU1ZBCgpgYGB7ciBtYWNyb19zdmEsIGZpZy5zaG93PSJoaWRlIn0KIyMgSGVyZSBqdXN0IGxldCBhbGxfcGFpcndpc2UgcnVuIG9uIGZpbHRlcmVkIGRhdGEgYW5kIGRvIGl0cyBub3JtYWwgfiAwICsgY29uZGl0aW9uICsgYmF0Y2ggYW5hbHlzZXMKbWFjcm9fc3ZhIDwtIHNtKGFsbF9wYWlyd2lzZShtYWNyb19sb3dmaWx0LCBtb2RlbF9iYXRjaD0ic3ZhIikpCm1lZGlhbnNfYnlfY29uZGl0aW9uIDwtIG1hY3JvX3N2YSRiYXNpYyRtZWRpYW5zCm1hY3JvX3N2YV90YWJsZXMgPC0gc20oY29tYmluZV9kZV90YWJsZXMobWFjcm9fc3ZhLCBleGNlbD1wYXN0ZTAoImV4Y2VsL21hY3JvcGhhZ2Vfc3ZhLXYiLCB2ZXIsICIueGxzeCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXBlcnM9bXlfY29udHJhc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhX2Fubm90PW1lZGlhbnNfYnlfY29uZGl0aW9uKSkKbWFjcm9fc3ZhX3NpZyA8LSBzbShleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKG1hY3JvX3N2YV90YWJsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlbD1wYXN0ZTAoImV4Y2VsL21hY3JvcGhhZ2Vfc3ZhX3NpZ25pZmljYW50LXYiLCB2ZXIsICIueGxzeCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcF90eXBlPSJ1bmFkanVzdGVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY29yZGluZ190bz0iYWxsIikpCmBgYAoKIyMgQmF0Y2ggY29ycmVjdGlvbiB2aWEgcnV2IHJlc2lkdWFscwoKYGBge3IgbWFjcm9fcnV2cmVzaWQsIGZpZy5zaG93PSJoaWRlIn0KIyMgSGVyZSBqdXN0IGxldCBhbGxfcGFpcndpc2UgcnVuIG9uIGZpbHRlcmVkIGRhdGEgYW5kIGRvIGl0cyBub3JtYWwgfiAwICsgY29uZGl0aW9uICsgYmF0Y2ggYW5hbHlzZXMKIyMgQml6YXJyZWx5LCBzb21ldGltZXMgaWYgb25lIHJ1bnMgdGhpcywgaXQgZ2l2ZXMgYW4gZXJyb3IgIkVycm9yIGluIChmdW5jdGlvbiAoY2xhc3NlcywgZmRlZiwgbXRhYmxlKSA6IHVuYWJsZSB0byBmaW5kIGFuIGluaGVyaXRlZCBtZXRob2QgZm9yIGZ1bmN0aW9uICdSVVZyJyBmb3Igc2lnbmF0dXJlICcibWF0cml4IiwgImxvZ2ljYWwiLCAibnVtZXJpYyIsICJOVUxMIiciICAtLSBob3dldmVyLCBpZiBvbmUgdGhlbiBzaW1wbHkgcnVucyBpdCBhZ2FpbiBpdCB3b3JrcyBmaW5lLgojIyBJIGFtIGdvaW5nIHRvIGFzc3VtZSB0aGF0IGl0IGlzIGJlY2F1c2UgSSBkbyBub3QgZXhwbGljaXRseSBpbnZva2UgdGhlIGxpYnJhcnkuCmxpYnJhcnkocnV2KQptYWNyb19ydXZyZXMgPC0gdHJ5KHNtKGFsbF9wYWlyd2lzZShtYWNyb19sb3dmaWx0LCBtb2RlbF9iYXRjaD0icnV2X3Jlc2lkdWFscyIpKSkKaWYgKGNsYXNzKG1hY3JvX3J1dnJlcykgPT0gInRyeS1lcnJvciIpIHsKICAgIG1hY3JvX3J1dnJlcyA8LSBzbShhbGxfcGFpcndpc2UobWFjcm9fbG93ZmlsdCwgbW9kZWxfYmF0Y2g9InJ1dl9yZXNpZHVhbHMiKSkKfQptZWRpYW5zX2J5X2NvbmRpdGlvbiA8LSBtYWNyb19ydXZyZXMkYmFzaWMkbWVkaWFucwptYWNyb19ydXZyZXNfdGFibGVzIDwtIHNtKGNvbWJpbmVfZGVfdGFibGVzKG1hY3JvX3J1dnJlcywgZXhjZWw9cGFzdGUwKCJleGNlbC9tYWNyb3BoYWdlX3J1dnJlcy12IiwgdmVyLCAiLnhsc3giKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwZXJzPW15X2NvbnRyYXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYV9hbm5vdD1tZWRpYW5zX2J5X2NvbmRpdGlvbikpCm1hY3JvX3J1dnJlc19zaWcgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhtYWNyb19ydXZyZXNfdGFibGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9tYWNyb3BoYWdlX3J1dnJlc19zaWduaWZpY2FudC12IiwgdmVyLCAiLnhsc3giKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBfdHlwZT0idW5hZGp1c3RlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2NvcmRpbmdfdG89ImFsbCIpKQpgYGAKCiMjIEJhdGNoIGNvcnJlY3Rpb24gd2l0aCBwY2EKCmBgYHtyIG1hY3JvX3BjYSwgZmlnLnNob3c9ImhpZGUifQojIyBIZXJlIGp1c3QgbGV0IGFsbF9wYWlyd2lzZSBydW4gb24gZmlsdGVyZWQgZGF0YSBhbmQgZG8gaXRzIG5vcm1hbCB+IDAgKyBjb25kaXRpb24gKyBiYXRjaCBhbmFseXNlcwptYWNyb19wY2EgPC0gc20oYWxsX3BhaXJ3aXNlKG1hY3JvX2xvd2ZpbHQsIG1vZGVsX2JhdGNoPSJwY2EiKSkKbWVkaWFuc19ieV9jb25kaXRpb24gPC0gbWFjcm9fcGNhJGJhc2ljJG1lZGlhbnMKbWFjcm9fcGNhX3RhYmxlcyA8LSBzbShjb21iaW5lX2RlX3RhYmxlcyhtYWNyb19wY2EsIGV4Y2VsPXBhc3RlMCgiZXhjZWwvbWFjcm9waGFnZV9wY2EtdiIsIHZlciwgIi54bHN4IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcGVycz1teV9jb250cmFzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFfYW5ub3Q9bWVkaWFuc19ieV9jb25kaXRpb24pKQptYWNyb19wY2Ffc2lnIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMobWFjcm9fcGNhX3RhYmxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvbWFjcm9waGFnZV9wY2Ffc2lnbmlmaWNhbnQtdiIsIHZlciwgIi54bHN4IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwX3R5cGU9InVuYWRqdXN0ZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjb3JkaW5nX3RvPSJhbGwiKSkKYGBgCgojIyBCYXRjaCBjb3JyZWN0aW9uIHdpdGggcnV2IGVtcGlyaWNhbAoKYGBge3IgbWFjcm9fcnV2ZW1wLCBmaWcuc2hvdz0iaGlkZSJ9CiMjIEhlcmUganVzdCBsZXQgYWxsX3BhaXJ3aXNlIHJ1biBvbiBmaWx0ZXJlZCBkYXRhIGFuZCBkbyBpdHMgbm9ybWFsIH4gMCArIGNvbmRpdGlvbiArIGJhdGNoIGFuYWx5c2VzCm1hY3JvX3J1dmVtcCA8LSBzbShhbGxfcGFpcndpc2UobWFjcm9fbG93ZmlsdCwgbW9kZWxfYmF0Y2g9InJ1dl9lbXBpcmljYWwiKSkKbWVkaWFuc19ieV9jb25kaXRpb24gPC0gbWFjcm9fcnV2ZW1wJGJhc2ljJG1lZGlhbnMKbWFjcm9fcnV2ZW1wX3RhYmxlcyA8LSBzbShjb21iaW5lX2RlX3RhYmxlcyhtYWNyb19ydXZlbXAsIGV4Y2VsPXBhc3RlMCgiZXhjZWwvbWFjcm9waGFnZV9ydXZlbXAtdiIsIHZlciwgIi54bHN4IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcGVycz1teV9jb250cmFzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFfYW5ub3Q9bWVkaWFuc19ieV9jb25kaXRpb24pKQptYWNyb19ydXZlbXBfc2lnIDwtIHNtKGV4dHJhY3Rfc2lnbmlmaWNhbnRfZ2VuZXMobWFjcm9fcnV2ZW1wX3RhYmxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2VsPXBhc3RlMCgiZXhjZWwvbWFjcm9waGFnZV9ydXZlbXBfc2lnbmlmaWNhbnQtdiIsIHZlciwgIi54bHN4IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwX3R5cGU9InVuYWRqdXN0ZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjb3JkaW5nX3RvPSJhbGwiKSkKYGBgCgojIyBCYXRjaCBjb3JyZWN0aW9uIHdpdGggY29tYmF0CgpUaGVuIHJlcGVhdCB3aXRoIHRoZSBiYXRjaC1jb3JyZWN0ZWQgZGF0YSBhbmQgc2VlIHRoZSBkaWZmZXJlbmNlcy4KCmBgYHtyIHJlcGVhdF9wYWlyd2lzZV9iYXRjaCwgZmlnLnNob3c9ImhpZGUifQptYWNyb19jb21iYXQgPC0gc20oYWxsX3BhaXJ3aXNlKG1hY3JvX2NvbWJhdF9ub3JtLCBmb3JjZT1UUlVFKSkKbWVkaWFuc19ieV9jb25kaXRpb24gPC0gbWFjcm9fY29tYmF0JGJhc2ljJG1lZGlhbnMKbWFjcm9fY29tYmF0X3RhYmxlcyA8LSBzbShjb21iaW5lX2RlX3RhYmxlcyhtYWNyb19jb21iYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9tYWNyb3BoYWdlX2NvbWJhdC12IiwgdmVyLCAiLnhsc3giKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwZXJzPW15X2NvbnRyYXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYV9hbm5vdD1tZWRpYW5zX2J5X2NvbmRpdGlvbikpCm1hY3JvX2NvbWJhdF9zaWcgPC0gc20oZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhtYWNyb19jb21iYXRfdGFibGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZWw9cGFzdGUwKCJleGNlbC9tYWNyb3BoYWdlX2NvbWJhdF9zaWduaWZpY2FudC12IiwgdmVyLCAiLnhsc3giKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBfdHlwZT0idW5hZGp1c3RlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2NvcmRpbmdfdG89ImFsbCIpKQpgYGAKCiMgRmlndXJlIG91dCBob3cgdG8gY29tcGFyZSB0aGVzZSByZXN1bHRzCgpJIGhhdmUgNCBtZXRob2RzIG9mIHBlcmZvcm1pbmcgdGhpcyBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNpcy4gIEVhY2ggb25lIGNvbWVzIHdpdGggYSBzZXQgb2YKbWV0cmljcyBkZWZpbmluZyAnc2lnbmlmaWNhbnQnLiAgUGVyaGFwcyBJIGNhbiBtYWtlIGEgdGFibGUgb2YgdGhlICMgb2YgZ2VuZXMgZGVmaW5lZCBhcyBzaWduaWZpY2FudApieSBjb250cmFzdCBmb3IgZWFjaC4gIEluIGFkZGl0aW9uIGl0IG1heSBiZSB3b3J0aCB3aGlsZSB0byBkbyBhIHNjYXR0ZXIgcGxvdHMgb2YgdGhlIGxvZ0ZDcyBiZXR3ZWVuCnRoZXNlIGNvbXBhcmlzb25zIGFuZCBzZWUgaG93IHdlbGwgdGhleSBhZ3JlZT8KCiMgTG9vayBmaXJzdCBhdCB0aGUgZGUgY291bnRzCgpgYGB7ciBjb21wYXJlX2RlX3NldHVwfQptYWNyb19ub2JhdGNoX3NpZyRsaW1tYSRjb3VudHMKbWFjcm9fYmF0Y2hfc2lnJGxpbW1hJGNvdW50cwptYWNyb19zdmFfc2lnJGxpbW1hJGNvdW50cwptYWNyb19ydXZyZXNfc2lnJGxpbW1hJGNvdW50cwptYWNyb19wY2Ffc2lnJGxpbW1hJGNvdW50cwptYWNyb19ydXZlbXBfc2lnJGxpbW1hJGNvdW50cwptYWNyb19jb21iYXRfc2lnJGxpbW1hJGNvdW50cwpgYGAKCiMjIENvbXBhcmUgRGVTZXEgLyBCYXNpYyB3aXRob3V0IGJhdGNoIGluIG1vZGVsCgpgYGB7ciBiYXNpY19kZXNlcV9ub2JhdGNofQpub2JhdGNoX2Jhc2ljIDwtIG1lcmdlKG1hY3JvX25vYmF0Y2gkZGVzZXEkYWxsX3RhYmxlcyRtYWNyb19zaF92c19tYWNyb19jaCwgbWFjcm9fYmF0Y2gkYmFzaWMkYWxsX3RhYmxlcyRtYWNyb19zaF92c19tYWNyb19jaCwgYnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKG5vYmF0Y2hfYmFzaWMpIDwtIG5vYmF0Y2hfYmFzaWNbWyJSb3cubmFtZXMiXV0Kbm9iYXRjaF9sb2dmYyA8LSBub2JhdGNoX2Jhc2ljWywgYygibG9nRkMueCIsImxvZ0ZDLnkiKV0KY29sbmFtZXMobm9iYXRjaF9sb2dmYykgPC0gYygibm9iYXRjaCIsImJhc2ljIikKbGZjX25iX2IgPC0gc20ocGxvdF9saW5lYXJfc2NhdHRlcihub2JhdGNoX2xvZ2ZjLCBwcmV0dHlfY29sb3JzPUZBTFNFKSkKbGZjX25iX2Ikc2NhdHRlcgpsZmNfbmJfYiRjb3JyZWxhdGlvbgpub2JhdGNoX3AgPC0gbm9iYXRjaF9iYXNpY1ssIGMoIlAuVmFsdWUiLCJwIildCm5vYmF0Y2hfcFtbMl1dIDwtIGFzLm51bWVyaWMobm9iYXRjaF9wW1syXV0pCmNvbG5hbWVzKG5vYmF0Y2hfcCkgPC0gYygibm9iYXRjaCIsImJhc2ljIikKbm9iYXRjaF9wIDwtIC0xICogbG9nKG5vYmF0Y2hfcCkKcF9uYl9iIDwtIHNtKHBsb3RfbGluZWFyX3NjYXR0ZXIobm9iYXRjaF9wLCBwcmV0dHlfY29sb3JzPUZBTFNFKSkKcF9uYl9iJHNjYXR0ZXIKcF9uYl9iJGNvcnJlbGF0aW9uCmBgYAoKIyMgQ29tcGFyZSBTVkEgdG8gYmF0Y2ggaW4gbW9kZWwsIERFU2VxCgpgYGB7ciBkZXNlcV9zdmFfYmF0Y2h9CnN2YV9iYXRjaCA8LSBtZXJnZShtYWNyb19zdmEkZGVzZXEkYWxsX3RhYmxlcyRtYWNyb19zaF92c19tYWNyb19jaCwgbWFjcm9fYmF0Y2gkZGVzZXEkYWxsX3RhYmxlcyRtYWNyb19zaF92c19tYWNyb19jaCwgYnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKHN2YV9iYXRjaCkgPC0gc3ZhX2JhdGNoW1siUm93Lm5hbWVzIl1dCnN2YV9sb2dmYyA8LSBzdmFfYmF0Y2hbLCBjKCJsb2dGQy54IiwibG9nRkMueSIpXQpjb2xuYW1lcyhzdmFfbG9nZmMpIDwtIGMoInN2YSIsImJhdGNoIikKbGZjX2JfcyA8LSBzbShwbG90X2xpbmVhcl9zY2F0dGVyKHN2YV9sb2dmYywgcHJldHR5X2NvbG9ycz1GQUxTRSkpCmxmY19iX3Mkc2NhdHRlcgpsZmNfYl9zJGNvcnJlbGF0aW9uCnN2YV9wIDwtIHN2YV9iYXRjaFssIGMoIlAuVmFsdWUueCIsIlAuVmFsdWUueSIpXQpzdmFfcFtbMl1dIDwtIGFzLm51bWVyaWMoc3ZhX3BbWzJdXSkKY29sbmFtZXMoc3ZhX3ApIDwtIGMoInN2YSIsImJhdGNoIikKc3ZhX3AgPC0gLTEgKiBsb2coc3ZhX3ApCnBfYl9zIDwtIHNtKHBsb3RfbGluZWFyX3NjYXR0ZXIoc3ZhX3AsIHByZXR0eV9jb2xvcnM9RkFMU0UpKQpwX2JfcyRzY2F0dGVyCnBfYl9zJGNvcnJlbGF0aW9uCmBgYAoKIyMjIEluY2x1ZGUgcC12YWx1ZSBlc3RpbWF0aW9ucwoKVHJ5IHB1dHRpbmcgc29tZSBpbmZvcm1hdGlvbiBvZiB0aGUgcC12YWx1ZXMgd2l0aCB0aGUgY29tcGFyYXRpdmUgbG9nMmZjCgpgYGB7ciBsMmZzX3B2YWxzfQpsZmNwX2JfcyA8LSBzdmFfYmF0Y2hbLCBjKCJsb2dGQy54IiwgImxvZ0ZDLnkiLCAiUC5WYWx1ZS54IiwgIlAuVmFsdWUueSIpXQpjb2xuYW1lcyhsZmNwX2JfcykgPC0gYygibDJmY3N2YSIsICJsMmZjYmF0Y2giLCAicHN2YSIsICJwYmF0Y2giKQpsZmNfYl9zJHNjYXR0ZXIKY3V0b2ZmIDwtIDAuMQpsZmNwX2JfcyRzdGF0ZSA8LSBpZmVsc2UobGZjcF9iX3MkcHN2YSA+IGN1dG9mZiAmIGxmY3BfYl9zJHBiYXRjaCA+IGN1dG9mZiwgImJvdGhpbnNpZyIsCiAgICAgICAgICAgICAgICAgIGlmZWxzZShsZmNwX2JfcyRwc3ZhIDw9IGN1dG9mZiAmIGxmY3BfYl9zJHBiYXRjaCA8PSBjdXRvZmYsICJib3Roc2lnIiwKICAgICAgICAgICAgICAgICAgaWZlbHNlKGxmY3BfYl9zJHBzdmEgPD0gY3V0b2ZmLCAic3Zhc2lnIiwgImJhdGNoc2lnIikpKQojI2xmY3BfYl9zJGxmY3N0YXRlIDwtIGlmZWxzZShsZmNwX2JfcyRsMmZjc3ZhID49IDAuNzUgJiBsZmNwX2JfcyRsMmZjYmF0Y2gsICIiLCAiIikKbnVtX2JvdGhpbnNpZyA8LSBzdW0obGZjcF9iX3Mkc3RhdGUgPT0gImJvdGhpbnNpZyIpCm51bV9ib3Roc2lnIDwtIHN1bShsZmNwX2JfcyRzdGF0ZSA9PSAiYm90aHNpZyIpCm51bV9zdmFzaWcgPC0gc3VtKGxmY3BfYl9zJHN0YXRlID09ICJzdmFzaWciKQpudW1fYmF0Y2hzaWcgPC0gc3VtKGxmY3BfYl9zJHN0YXRlID09ICJiYXRjaHNpZyIpCgpsaWJyYXJ5KGdncGxvdDIpCmFlc19jb2xvciA9ICIobDJmY3N2YSA+PSAwLjc1IHwgbDJmY3N2YSA8PSAtMC43NSB8IGwyZmNiYXRjaCA+PSAwLjc1IHwgbDJmY2JhdGNoIDw9IC0wLjc1KSIKCnBsdCA8LSBnZ3Bsb3QyOjpnZ3Bsb3QobGZjcF9iX3MsIGFlc19zdHJpbmcoeD0ibDJmY3N2YSIsIHk9ImwyZmNiYXRjaCIpKSArCiAgICAjIyBnZ3Bsb3QyOjpnZW9tX3BvaW50KHN0YXQ9ImlkZW50aXR5Iiwgc2l6ZT0yLCBhbHBoYT0wLjIsIGFlc19zdHJpbmcoc2hhcGU9ImFzLmZhY3RvcihhZXNfY29sb3IpIiwgY29sb3VyPSJhcy5mYWN0b3Ioc3RhdGUpIiwgZmlsbD0iYXMuZmFjdG9yKHN0YXRlKSIpKSArCiAgICBnZ3Bsb3QyOjpnZW9tX2FibGluZShjb2xvdXI9ImJsdWUiLCBzbG9wZT0xLCBpbnRlcmNlcHQ9MCwgc2l6ZT0wLjUpICsKICAgIGdncGxvdDI6Omdlb21faGxpbmUoeWludGVyY2VwdD1jKC0wLjc1LCAwLjc1KSwgY29sb3I9InJlZCIsIHNpemU9MC41KSArCiAgICBnZ3Bsb3QyOjpnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9YygtMC43NSwgMC43NSksIGNvbG9yPSJyZWQiLCBzaXplPTAuNSkgKwogICAgZ2dwbG90Mjo6Z2VvbV9wb2ludChzdGF0PSJpZGVudGl0eSIsIHNpemU9MiwgYWxwaGE9MC4yLCBhZXNfc3RyaW5nKGNvbG91cj0iYXMuZmFjdG9yKHN0YXRlKSIsIGZpbGw9ImFzLmZhY3RvcihzdGF0ZSkiKSkgKwogICAgZ2dwbG90Mjo6c2NhbGVfY29sb3JfbWFudWFsKG5hbWU9InN0YXRlIiwgdmFsdWVzPWMoImJvdGhpbnNpZyI9ImdyZXkiLCAiYm90aHNpZyI9ImZvcmVzdGdyZWVuIiwgInN2YXNpZyI9ImRhcmtyZWQiLCAiYmF0Y2hzaWciPSJkYXJrYmx1ZSIpKSArCiAgICBnZ3Bsb3QyOjpzY2FsZV9maWxsX21hbnVhbChuYW1lPSJzdGF0ZSIsIHZhbHVlcz1jKCJib3RoaW5zaWciPSJncmV5IiwgImJvdGhzaWciPSJmb3Jlc3RncmVlbiIsICJzdmFzaWciPSJkYXJrcmVkIiwgImJhdGNoc2lnIj0iZGFya2JsdWUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlMCgiQm90aCBJblNpZy46ICIsIG51bV9ib3RoaW5zaWcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlMCgiQm90aCBTaWcuOiAiLCBudW1fYm90aHNpZyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKCJTdmEgU2lnLjogIiwgbnVtX3N2YXNpZyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKCJCYXRjaCBTaWcuOiAiLCBudW1fYmF0Y2hzaWcpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGd1aWRlPWdncGxvdDI6Omd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXM9YWVzKHNpemU9MywgZmlsbD0iZ3JleSIpKSkgKwogICAgZ2dwbG90Mjo6Z3VpZGVzKGZpbGw9Z2dwbG90Mjo6Z3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcz1saXN0KHNpemU9MykpKSArCiAgICBnZ3Bsb3QyOjp0aGVtZV9idygpCnBsdApgYGAKCiMjIENvbXBhcmUgcnV2cmVzaWQgdG8gYmF0Y2ggaW4gbW9kZWwsIERFU2VxCgpgYGB7ciBiYXRjaF9ydXZyZXNpZF9kZXNlcX0KYmF0Y2hfcnV2cmVzaWRfZGVzZXEgPC0gbWVyZ2UobWFjcm9fcnV2cmVzJGRlc2VxJGFsbF90YWJsZXMkbWFjcm9fc2hfdnNfbWFjcm9fY2gsIG1hY3JvX2JhdGNoJGJhc2ljJGFsbF90YWJsZXMkbWFjcm9fc2hfdnNfbWFjcm9fY2gsIGJ5PSJyb3cubmFtZXMiKQpyb3duYW1lcyhiYXRjaF9ydXZyZXNpZF9kZXNlcSkgPC0gYmF0Y2hfcnV2cmVzaWRfZGVzZXFbWyJSb3cubmFtZXMiXV0KYmF0Y2hfcnV2cmVzaWRfbG9nZmMgPC0gYmF0Y2hfcnV2cmVzaWRfZGVzZXFbLCBjKCJsb2dGQy54IiwibG9nRkMueSIpXQpjb2xuYW1lcyhiYXRjaF9ydXZyZXNpZF9sb2dmYykgPC0gYygibm9iYXRjaCIsImJhc2ljIikKbGZjX3J1dl9iYXQgPC0gcGxvdF9saW5lYXJfc2NhdHRlcihiYXRjaF9ydXZyZXNpZF9sb2dmYywgcHJldHR5X2NvbG9ycz1GQUxTRSkKbGZjX3J1dl9iYXQkc2NhdHRlcgpsZmNfcnV2X2JhdCRjb3JyZWxhdGlvbgpgYGAKCiMjIENvbXBhcmUgcGNhIHRvIGJhdGNoIGluIG1vZGVsLCBERVNlcQoKYGBge3IgYmF0Y2hfcGNhX2Rlc2VxfQpiYXRjaF9wY2FfZGVzZXEgPC0gbWVyZ2UobWFjcm9fcGNhJGRlc2VxJGFsbF90YWJsZXMkbWFjcm9fc2hfdnNfbWFjcm9fY2gsIG1hY3JvX2JhdGNoJGJhc2ljJGFsbF90YWJsZXMkbWFjcm9fc2hfdnNfbWFjcm9fY2gsIGJ5PSJyb3cubmFtZXMiKQpyb3duYW1lcyhiYXRjaF9wY2FfZGVzZXEpIDwtIGJhdGNoX3BjYV9kZXNlcVtbIlJvdy5uYW1lcyJdXQpiYXRjaF9wY2FfbG9nZmMgPC0gYmF0Y2hfcGNhX2Rlc2VxWywgYygibG9nRkMueCIsImxvZ0ZDLnkiKV0KY29sbmFtZXMoYmF0Y2hfcGNhX2xvZ2ZjKSA8LSBjKCJub2JhdGNoIiwiYmFzaWMiKQpsZmNfcGNhX2JhdCA8LSBwbG90X2xpbmVhcl9zY2F0dGVyKGJhdGNoX3BjYV9sb2dmYywgcHJldHR5X2NvbG9ycz1GQUxTRSkKbGZjX3BjYV9iYXQkc2NhdHRlcgpsZmNfcGNhX2JhdCRjb3JyZWxhdGlvbgpgYGAKCiMjIENvbXBhcmUgcnV2IGVtcGlyaWNhbCB0byBiYXRjaCBpbiBtb2RlbCwgREVTZXEKCmBgYHtyIGJhdGNoX3J1dmVtcF9kZXNlcX0KYmF0Y2hfcnV2ZW1wX2Rlc2VxIDwtIG1lcmdlKG1hY3JvX3J1dmVtcCRkZXNlcSRhbGxfdGFibGVzJG1hY3JvX3NoX3ZzX21hY3JvX2NoLCBtYWNyb19iYXRjaCRiYXNpYyRhbGxfdGFibGVzJG1hY3JvX3NoX3ZzX21hY3JvX2NoLCBieT0icm93Lm5hbWVzIikKcm93bmFtZXMoYmF0Y2hfcnV2ZW1wX2Rlc2VxKSA8LSBiYXRjaF9ydXZlbXBfZGVzZXFbWyJSb3cubmFtZXMiXV0KYmF0Y2hfcnV2ZW1wX2xvZ2ZjIDwtIGJhdGNoX3J1dmVtcF9kZXNlcVssIGMoImxvZ0ZDLngiLCJsb2dGQy55IildCmNvbG5hbWVzKGJhdGNoX3J1dmVtcF9sb2dmYykgPC0gYygibm9iYXRjaCIsImJhc2ljIikKbGZjX3J1dmVtcF9iYXQgPC0gc20ocGxvdF9saW5lYXJfc2NhdHRlcihiYXRjaF9ydXZlbXBfbG9nZmMsIHByZXR0eV9jb2xvcnM9RkFMU0UpKQpsZmNfcnV2ZW1wX2JhdCRzY2F0dGVyCmxmY19ydXZlbXBfYmF0JGNvcnJlbGF0aW9uCmBgYAoKIyMgQ29tcGFyZSBjb21iYXQgdG8gYmF0Y2ggaW4gbW9kZWwsIERFU2VxCgpgYGB7ciBjb21wYXJlX2JhdGNoX2NvbWJhdH0KY29tYmF0X2JhdGNoIDwtIG1lcmdlKG1hY3JvX2NvbWJhdCRkZXNlcSRhbGxfdGFibGVzJG1hY3JvX3NoX3ZzX21hY3JvX2NoLCBtYWNyb19iYXRjaCRkZXNlcSRhbGxfdGFibGVzJG1hY3JvX3NoX3ZzX21hY3JvX2NoLCBieT0icm93Lm5hbWVzIikKcm93bmFtZXMoY29tYmF0X2JhdGNoKSA8LSBjb21iYXRfYmF0Y2hbWyJSb3cubmFtZXMiXV0KY29tYmF0X2JhdGNoIDwtIGNvbWJhdF9iYXRjaFssIGMoImxvZ0ZDLngiLCJsb2dGQy55IildCmNvbG5hbWVzKGNvbWJhdF9iYXRjaCkgPC0gYygiYmF0Y2giLCJjb21iYXQiKQpiX2MgPC0gcGxvdF9saW5lYXJfc2NhdHRlcihjb21iYXRfYmF0Y2gsIHByZXR0eV9jb2xvcnM9RkFMU0UpCmJfYyRzY2F0dGVyCmJfYyRjb3JyZWxhdGlvbgpgYGAKCiMjIENvbXBhcmUgbm8gYmF0Y2ggdG8gYmF0Y2ggaW4gbW9kZWwsIGxpbW1hCgpgYGB7ciBjb21wYXJlX2JhdGNoX25vYmF0Y2hfbGltbWF9Cm5vYmF0Y2hfYmF0Y2ggPC0gbWVyZ2UobWFjcm9fbm9iYXRjaCRsaW1tYSRhbGxfdGFibGVzJG1hY3JvX3NoX3ZzX21hY3JvX2NoLCBtYWNyb19iYXRjaCRsaW1tYSRhbGxfdGFibGVzJG1hY3JvX3NoX3ZzX21hY3JvX2NoLCBieT0icm93Lm5hbWVzIikKcm93bmFtZXMobm9iYXRjaF9iYXRjaCkgPC0gbm9iYXRjaF9iYXRjaFtbIlJvdy5uYW1lcyJdXQpub2JhdGNoX2JhdGNoIDwtIG5vYmF0Y2hfYmF0Y2hbLCBjKCJsb2dGQy54IiwibG9nRkMueSIpXQpjb2xuYW1lcyhub2JhdGNoX2JhdGNoKSA8LSBjKCJub2JhdGNoIiwiYmF0Y2giKQpuYl9iIDwtIHBsb3RfbGluZWFyX3NjYXR0ZXIobm9iYXRjaF9iYXRjaCwgcHJldHR5X2NvbG9ycz1GQUxTRSkKbmJfYiRzY2F0dGVyCm5iX2IkY29ycmVsYXRpb24KYGBgCgojIyBCYXRjaCBpbiBtb2RlbCB2cy4gU1ZBLCBsaW1tYQoKYGBge3IgY29tcGFyZV9iYXRjaF9zdmFfbGltbWF9CmJhdGNoX3N2YSA8LSBtZXJnZShtYWNyb19iYXRjaCRsaW1tYSRhbGxfdGFibGVzJG1hY3JvX3NoX3ZzX21hY3JvX2NoLCBtYWNyb19zdmEkbGltbWEkYWxsX3RhYmxlcyRtYWNyb19zaF92c19tYWNyb19jaCwgYnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKGJhdGNoX3N2YSkgPC0gYmF0Y2hfc3ZhW1siUm93Lm5hbWVzIl1dCmJhdGNoX3N2YSA8LSBiYXRjaF9zdmFbLCBjKCJsb2dGQy54IiwibG9nRkMueSIpXQpjb2xuYW1lcyhiYXRjaF9zdmEpIDwtIGMoImJhdGNoIiwic3ZhIikKYl9zIDwtIHBsb3RfbGluZWFyX3NjYXR0ZXIoYmF0Y2hfc3ZhLCBwcmV0dHlfY29sb3JzPUZBTFNFKQpiX3Mkc2NhdHRlcgpiX3MkY29ycmVsYXRpb24KYGBgCgojIyBCYXRjaCBpbiBtb2RlbCB2cy4gY29tYmF0LCBsaW1tYQoKYGBge3IgY29tcGFyZV9iYXRjaF9jb21iYXRfbGltbWF9CmJhdGNoX2NvbWJhdCA8LSBtZXJnZShtYWNyb19iYXRjaCRsaW1tYSRhbGxfdGFibGVzJG1hY3JvX3NoX3ZzX21hY3JvX2NoLCBtYWNyb19jb21iYXQkbGltbWEkYWxsX3RhYmxlcyRtYWNyb19zaF92c19tYWNyb19jaCwgYnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKGJhdGNoX2NvbWJhdCkgPC0gYmF0Y2hfY29tYmF0W1siUm93Lm5hbWVzIl1dCmJhdGNoX2NvbWJhdCA8LSBiYXRjaF9jb21iYXRbLCBjKCJsb2dGQy54IiwibG9nRkMueSIpXQpjb2xuYW1lcyhiYXRjaF9jb21iYXQpIDwtIGMoImJhdGNoIiwiY29tYmF0IikKYl9jIDwtIHBsb3RfbGluZWFyX3NjYXR0ZXIoYmF0Y2hfY29tYmF0LCBwcmV0dHlfY29sb3JzPUZBTFNFKQpiX2Mkc2NhdHRlcgpiX2MkY29ycmVsYXRpb24KYGBgCgojIyBOb2JhdGNoIHZzLiBiYXRjaCBpbiBtb2RlbCwgZWRnZXIKCmBgYHtyIGNvbXBhcmVfbm9iYXRjaF9iYXRjaF9lZGdlcn0Kbm9iYXRjaF9iYXRjaCA8LSBtZXJnZShtYWNyb19ub2JhdGNoJGVkZ2VyJGFsbF90YWJsZXMkbWFjcm9fc2hfdnNfbWFjcm9fY2gsIG1hY3JvX2JhdGNoJGVkZ2VyJGFsbF90YWJsZXMkbWFjcm9fc2hfdnNfbWFjcm9fY2gsIGJ5PSJyb3cubmFtZXMiKQpyb3duYW1lcyhub2JhdGNoX2JhdGNoKSA8LSBub2JhdGNoX2JhdGNoW1siUm93Lm5hbWVzIl1dCm5vYmF0Y2hfYmF0Y2ggPC0gbm9iYXRjaF9iYXRjaFssIGMoImxvZ0ZDLngiLCJsb2dGQy55IildCmNvbG5hbWVzKG5vYmF0Y2hfYmF0Y2gpIDwtIGMoIm5vYmF0Y2giLCJiYXRjaCIpCm5iX2IgPC0gc20ocGxvdF9saW5lYXJfc2NhdHRlcihub2JhdGNoX2JhdGNoLCBwcmV0dHlfY29sb3JzPUZBTFNFKSkKbmJfYiRzY2F0dGVyCm5iX2IkY29ycmVsYXRpb24KYGBgCgojIyBCYXRjaCBpbiBtb2RlbCB2cy4gU1ZBLCBlZGdlcgoKYGBge3IgY29tcGFyZV9iYXRjaF9zdmFfZWRnZXJ9CmJhdGNoX3N2YSA8LSBtZXJnZShtYWNyb19iYXRjaCRlZGdlciRhbGxfdGFibGVzJG1hY3JvX3NoX3ZzX21hY3JvX2NoLCBtYWNyb19zdmEkZWRnZXIkYWxsX3RhYmxlcyRtYWNyb19zaF92c19tYWNyb19jaCwgYnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKGJhdGNoX3N2YSkgPC0gYmF0Y2hfc3ZhW1siUm93Lm5hbWVzIl1dCmJhdGNoX3N2YSA8LSBiYXRjaF9zdmFbLCBjKCJsb2dGQy54IiwibG9nRkMueSIpXQpjb2xuYW1lcyhiYXRjaF9zdmEpIDwtIGMoImJhdGNoIiwic3ZhIikKYl9zIDwtIHBsb3RfbGluZWFyX3NjYXR0ZXIoYmF0Y2hfc3ZhLCBwcmV0dHlfY29sb3JzPUZBTFNFKQpiX3Mkc2NhdHRlcgpiX3MkY29ycmVsYXRpb24KYGBgCgojIyBCYXRjaCBpbiBtb2RlbCB2cy4gY29tYmF0LCBlZGdlcgoKYGBge3IgY29tcGFyZV9iYXRjaF9jb21iYXRfZWRnZXJ9CmJhdGNoX2NvbWJhdCA8LSBtZXJnZShtYWNyb19iYXRjaCRlZGdlciRhbGxfdGFibGVzJG1hY3JvX3NoX3ZzX21hY3JvX2NoLCBtYWNyb19jb21iYXQkZWRnZXIkYWxsX3RhYmxlcyRtYWNyb19zaF92c19tYWNyb19jaCwgYnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKGJhdGNoX2NvbWJhdCkgPC0gYmF0Y2hfY29tYmF0W1siUm93Lm5hbWVzIl1dCmJhdGNoX2NvbWJhdCA8LSBiYXRjaF9jb21iYXRbLCBjKCJsb2dGQy54IiwibG9nRkMueSIpXQpjb2xuYW1lcyhiYXRjaF9jb21iYXQpIDwtIGMoImJhdGNoIiwiY29tYmF0IikKYl9jIDwtIHBsb3RfbGluZWFyX3NjYXR0ZXIoYmF0Y2hfY29tYmF0LCBwcmV0dHlfY29sb3JzPUZBTFNFKQpiX2Mkc2NhdHRlcgpiX2MkY29ycmVsYXRpb24KYGBgCgojIyBDb21wYXJlIG5vYmF0Y2ggdnMuIGJhdGNoLCBkZXNlcQoKYGBge3IgY29tcGFyZV9ub2JhdGNoX2JhdGNoX2Rlc2VxfQpub2JhdGNoX2JhdGNoIDwtIG1lcmdlKG1hY3JvX25vYmF0Y2gkZGVzZXEkYWxsX3RhYmxlcyRtYWNyb19zaF92c19tYWNyb19jaCwgbWFjcm9fYmF0Y2gkZGVzZXEkYWxsX3RhYmxlcyRtYWNyb19zaF92c19tYWNyb19jaCwgYnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKG5vYmF0Y2hfYmF0Y2gpIDwtIG5vYmF0Y2hfYmF0Y2hbWyJSb3cubmFtZXMiXV0Kbm9iYXRjaF9iYXRjaCA8LSBub2JhdGNoX2JhdGNoWywgYygibG9nRkMueCIsImxvZ0ZDLnkiKV0KY29sbmFtZXMobm9iYXRjaF9iYXRjaCkgPC0gYygibm9iYXRjaCIsImJhdGNoIikKbmJfYiA8LSBzbShwbG90X2xpbmVhcl9zY2F0dGVyKG5vYmF0Y2hfYmF0Y2gsIHByZXR0eV9jb2xvcnM9RkFMU0UpKQpuYl9iJHNjYXR0ZXIKbmJfYiRjb3JyZWxhdGlvbgpgYGAKCiMjIENvbXBhcmUgYmF0Y2ggdnMuIFNWQSwgZGVzZXEKCmBgYHtyIGNvbXBhcmVfYmF0Y2hfc3ZhX2Rlc2VxfQpiYXRjaF9zdmEgPC0gbWVyZ2UobWFjcm9fYmF0Y2gkZGVzZXEkYWxsX3RhYmxlcyRtYWNyb19zaF92c19tYWNyb19jaCwgbWFjcm9fc3ZhJGRlc2VxJGFsbF90YWJsZXMkbWFjcm9fc2hfdnNfbWFjcm9fY2gsIGJ5PSJyb3cubmFtZXMiKQpyb3duYW1lcyhiYXRjaF9zdmEpIDwtIGJhdGNoX3N2YVtbIlJvdy5uYW1lcyJdXQpiYXRjaF9zdmEgPC0gYmF0Y2hfc3ZhWywgYygibG9nRkMueCIsImxvZ0ZDLnkiKV0KY29sbmFtZXMoYmF0Y2hfc3ZhKSA8LSBjKCJiYXRjaCIsInN2YSIpCmJfcyA8LSBzbShwbG90X2xpbmVhcl9zY2F0dGVyKGJhdGNoX3N2YSwgcHJldHR5X2NvbG9ycz1GQUxTRSkpCmJfcyRzY2F0dGVyCmJfcyRjb3JyZWxhdGlvbgpgYGAKCiMjIEJhdGNoIGluIG1vZGVsIHZzLiBjb21iYXQsIGRlc2VxCgpgYGB7ciBiYXRjaF9jb21iYXRfZGVzZXF9CmJhdGNoX2NvbWJhdCA8LSBtZXJnZShtYWNyb19iYXRjaCRkZXNlcSRhbGxfdGFibGVzJG1hY3JvX3NoX3ZzX21hY3JvX2NoLCBtYWNyb19jb21iYXQkZGVzZXEkYWxsX3RhYmxlcyRtYWNyb19zaF92c19tYWNyb19jaCwgYnk9InJvdy5uYW1lcyIpCnJvd25hbWVzKGJhdGNoX2NvbWJhdCkgPC0gYmF0Y2hfY29tYmF0W1siUm93Lm5hbWVzIl1dCmJhdGNoX2NvbWJhdCA8LSBiYXRjaF9jb21iYXRbLCBjKCJsb2dGQy54IiwibG9nRkMueSIpXQpjb2xuYW1lcyhiYXRjaF9jb21iYXQpIDwtIGMoImJhdGNoIiwiY29tYmF0IikKYl9jIDwtIHNtKHBsb3RfbGluZWFyX3NjYXR0ZXIoYmF0Y2hfY29tYmF0LCBwcmV0dHlfY29sb3JzPUZBTFNFKSkKYl9jJHNjYXR0ZXIKYl9jJGNvcnJlbGF0aW9uCmBgYAoKYGBge3Igc2F2ZV9tYWNyb19leHByZXNzaW9ufQp0bXAgPC0gc20oc2F2ZW1lKGZpbGVuYW1lPSJtYWNyb3BoYWdlX2V4cHJlc3Npb25fcGFyYXNpdGUucmRhLnh6IikpCmBgYAoKW2luZGV4Lmh0bWxdKGluZGV4Lmh0bWwpIFttYWNyb3BoYWdlX2VzdGltYXRpb24uaHRtbF0obWFjcm9waGFnZV9lc3RpbWF0aW9uLmh0bWwpCg==