Please use the same folder as work directory as the data files. 1.
Remove anything left in the datafiles
If necesearry please install the following packages:2
if (!requireNamespace("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install("clusterProfiler")
BiocManager::install("ReactomePA")
BiocManager::install("rrvgo")
BiocManager::install("enrichplot")
BiocManager::install("msigdbr")
BiocManager::install("org.Hs.eg.db")
BiocManager::install("AnnotationDbi")
install.packages("ggplot2")
install.packages("glue")
BiocManager::install("fgsea")
install.packages("mulea")
- Reading in necesearry packages
- Data input and prepearation for enrtichment analysis THe working
directory to be ecpected to be the folder of the Rmd file
PPI network propagation output
outcome_uc <- read.csv("uc_only_ppi_10k.txt", sep="\t", row.names = 1)
head(outcome_uc)
Reactome gene annotation file
reactome_ontology <- read_gmt("ReactomePathways.gmt")
reactome_ontology <- reactome_ontology %>%
rename(ontology_id = "ontology_id",
ontology_name = "ontology_name",
list_of_values = "list_of_values")
head(reactome_ontology)
Filtering onytology for minimum 5 and maximmum 400 elments -
excluding really large and really small patheways. We can change theese
settings later.
reactome_ontology_filtered <- filter_ontology(gmt = reactome_ontology,
min_nr_of_elements = 5,
max_nr_of_elements = 500)
OmniPath newtwork file
op <- read.csv("OmniPath_27_10_2021_directed.ncol", sep=" ", header = FALSE, row.names = NULL)
head(op)
head(outcome_uc)
filtered_outcome_uc <- outcome_uc[outcome_uc$Z_Count>0,]
head(filtered_outcome_uc)
bg <- unique(c(op$V1,op$V2))
# Translating genes in the background and outcome data to gene symbols
# Translate background genes
bg_symbols <- mapIds(org.Hs.eg.db, keys = bg, column = "SYMBOL", keytype = "UNIPROT", multiVals = "first")
- Creating Figure 4/b
histogramplot_uc <- ggplot(filtered_outcome_uc, aes(x=Z_Count)) +
geom_histogram(colour="white", fill="orange", binwidth = 50)+
ylab("Number of individual proteins") + xlab("Number of patients") +
geom_vline(aes(xintercept=100),
color="black", linetype="dashed", size=1) +
scale_x_continuous(breaks=seq(0,1400,200)) + theme_light()
theme(panel.background = element_rect(fill = "black")) +
theme(plot.background = element_rect(fill = "white", colour = "white")) +
theme(axis.title.x = element_text(colour = "black", size = 10)) +
theme(axis.title.y = element_text(colour = "black", size = 10)) +
theme(axis.text = element_text(color= "black", size = 10)) +
theme(axis.line = element_line(color = "black")) +
theme(panel.grid.minor = element_blank())
histogramplot_uc
- Enrichmnet and creating Figure 2c
commonly_afffected_genes_uc <- filtered_outcome_uc[filtered_outcome_uc$Z_Count>100,]
dim(commonly_afffected_genes_uc)
commonly_afffected_uc_genes_symbols <- mapIds(org.Hs.eg.db, keys = row.names(commonly_afffected_genes_uc),
column = "SYMBOL", keytype = "UNIPROT", multiVals = "first")
ora_model <- ora(gmt = reactome_ontology_filtered,
# Test set variable
element_names = commonly_afffected_uc_genes_symbols,
# Background set variable
background_element_names = bg_symbols,
# p-value adjustment method
p_value_adjustment_method = "eFDR",
# Number of permutations
number_of_permutations = 10000,
# Number of processor threads to use
nthreads = 2,
# Setting a random seed for reproducibility
random_seed = 42)
reactome_results_uc_ppi <- run_test(ora_model)
reactome_results_uc_ppi$GeneRatio <- reactome_results_uc_ppi$nr_common_with_tested_elements / length(commonly_afffected_uc_genes_symbols)
sig_results_uc_ppi <- reactome_results_uc_ppi %>%
# Rows where the eFDR < 0.05
filter(eFDR < 0.1) %>%
# Arrange the rows by the gene ratio for plotting
arrange(desc(GeneRatio))
sig_results_uc_ppi$ontology_id <- factor(sig_results_uc_ppi$ontology_id,
levels = sig_results_uc_ppi[order(sig_results_uc_ppi$GeneRatio, decreasing = FALSE), "ontology_id"])
sig_results_uc_ppi
write.csv(reactome_results_uc_ppi, glue("Reactome_UC_PPI_100_cutoff_ora_results.csv"), row.names = FALSE)
Label formatting
sig_results_uc_ppi$formed_id <- gsub("_", " ", sig_results_uc_ppi$ontology_id)
sig_results_uc_ppi$formed_id <- factor(sig_results_uc_ppi$formed_id,
levels = sig_results_uc_ppi[order(sig_results_uc_ppi$GeneRatio,
decreasing = FALSE), "formed_id"])
Adding a small amount for the fDR calcuation based on the MULEA
calcautions.
sig_results_uc_ppi$eFDR = sig_results_uc_ppi$eFDR +10^-12
dotplot_reactome_uc_ppi <- ggplot(sig_results_uc_ppi[1:20,], aes(x=GeneRatio, y=formed_id)) +
geom_point(aes(size=nr_common_with_tested_elements, colour=eFDR)) +
scale_y_discrete(labels = label_wrap(50)) +
scale_color_continuous(low="red", high="blue",
limits=c(10^-5, 0.1),
trans = "log10", name="Emprical FDR")
dotplot_reactome_uc_ppi <- dotplot_reactome_uc_ppi +
scale_size(limits = c(2,20), range = c(2,15), name = "Number of genes") +
xlim(0, 0.23) +
xlab("Gene Ratio") +
ylab("Reactome pathways") +
theme_light() +
theme(rect=element_rect(fill="white")) +
theme(panel.background = element_rect(fill = "white")) +
theme(plot.background = element_rect(fill = "white")) +
theme(plot.background = element_rect(colour = "white"))+
theme(axis.title.x = element_text(colour = "black", size = 10)) +
theme(axis.title.y = element_text(colour = "black", size = 10)) +
theme(axis.text = element_text(color= "black", size = 10)) +
theme(axis.line = element_line(color = "black")) +
theme(legend.background = element_rect(fill ="white")) +
theme(legend.text = element_text(color="black", size = 10)) +
theme(legend.title = element_text(color= "black", size = 10))
dotplot_reactome_uc_ppi
png(file=glue("Histogram_UC_PPI_v4.png"),width=8, height=4, units="in", res=600)
histogramplot_uc
dev.off()
png(file=glue("Hallmarks_UC_PPItop100_v3_top20.png"),width=8, height=8, units="in", res=600)
dotplot_reactome_uc_ppi
dev.off()
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2sgRmlndXJlIDViIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NClBsZWFzZSB1c2UgdGhlIHNhbWUgZm9sZGVyIGFzIHdvcmsgZGlyZWN0b3J5IGFzIHRoZSBkYXRhIGZpbGVzLg0KMS4gUmVtb3ZlIGFueXRoaW5nIGxlZnQgaW4gdGhlIGRhdGFmaWxlcw0KYGBge3J9DQpybShsaXN0PWxzKCkpDQpgYGANCmBgYHtyfQ0KSWYgbmVjZXNlYXJyeSBwbGVhc2UgaW5zdGFsbCB0aGUgZm9sbG93aW5nIHBhY2thZ2VzOjINCmlmICghcmVxdWlyZU5hbWVzcGFjZSgiQmlvY01hbmFnZXIiLCBxdWlldGx5ID0gVFJVRSkpDQogICAgaW5zdGFsbC5wYWNrYWdlcygiQmlvY01hbmFnZXIiKQ0KQmlvY01hbmFnZXI6Omluc3RhbGwoImNsdXN0ZXJQcm9maWxlciIpDQpCaW9jTWFuYWdlcjo6aW5zdGFsbCgiUmVhY3RvbWVQQSIpIA0KQmlvY01hbmFnZXI6Omluc3RhbGwoInJydmdvIikNCkJpb2NNYW5hZ2VyOjppbnN0YWxsKCJlbnJpY2hwbG90IikNCkJpb2NNYW5hZ2VyOjppbnN0YWxsKCJtc2lnZGJyIikNCkJpb2NNYW5hZ2VyOjppbnN0YWxsKCJvcmcuSHMuZWcuZGIiKQ0KQmlvY01hbmFnZXI6Omluc3RhbGwoIkFubm90YXRpb25EYmkiKQ0KaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQppbnN0YWxsLnBhY2thZ2VzKCJnbHVlIikNCkJpb2NNYW5hZ2VyOjppbnN0YWxsKCJmZ3NlYSIpDQppbnN0YWxsLnBhY2thZ2VzKCJtdWxlYSIpDQpgYGANCg0KMi4gUmVhZGluZyBpbiBuZWNlc2VhcnJ5IHBhY2thZ2VzDQpgYGB7cn0NCmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQ0KbGlicmFyeShSZWFjdG9tZVBBKQ0KbGlicmFyeShycnZnbykNCmxpYnJhcnkoZW5yaWNocGxvdCkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkobXNpZ2RicikNCm9yZ2FuaXNtID0ib3JnLkhzLmVnLmRiIg0KbGlicmFyeShvcmdhbmlzbSwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKQ0KbGlicmFyeShnbHVlKQ0KbGlicmFyeShtdWxlYSkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShBbm5vdGF0aW9uRGJpKQ0KbGlicmFyeShzY2FsZXMpDQpgYGANCjMuIERhdGEgaW5wdXQgYW5kIHByZXBlYXJhdGlvbiBmb3IgZW5ydGljaG1lbnQgYW5hbHlzaXMNClRIZSB3b3JraW5nIGRpcmVjdG9yeSB0byBiZSBlY3BlY3RlZCB0byBiZSB0aGUgZm9sZGVyIG9mIHRoZSBSbWQgZmlsZQ0KDQpQUEkgbmV0d29yayBwcm9wYWdhdGlvbiBvdXRwdXQNCmBgYHtyfQ0Kb3V0Y29tZV91YyA8LSByZWFkLmNzdigidWNfb25seV9wcGlfMTBrLnR4dCIsIHNlcD0iXHQiLCByb3cubmFtZXMgPSAxKQ0KaGVhZChvdXRjb21lX3VjKQ0KYGBgDQpSZWFjdG9tZSBnZW5lIGFubm90YXRpb24gZmlsZQ0KYGBge3J9DQpyZWFjdG9tZV9vbnRvbG9neSA8LSByZWFkX2dtdCgiUmVhY3RvbWVQYXRod2F5cy5nbXQiKQ0KYGBgDQpgYGB7cn0NCnJlYWN0b21lX29udG9sb2d5IDwtIHJlYWN0b21lX29udG9sb2d5ICU+JSANCnJlbmFtZShvbnRvbG9neV9pZCA9ICJvbnRvbG9neV9pZCIsDQogICAgb250b2xvZ3lfbmFtZSA9ICJvbnRvbG9neV9uYW1lIiwNCiAgICBsaXN0X29mX3ZhbHVlcyA9ICJsaXN0X29mX3ZhbHVlcyIpDQpoZWFkKHJlYWN0b21lX29udG9sb2d5KSAgICAgIA0KYGBgDQpGaWx0ZXJpbmcgb255dG9sb2d5IGZvciBtaW5pbXVtIDUgYW5kIG1heGltbXVtIDQwMCBlbG1lbnRzIC0gZXhjbHVkaW5nIHJlYWxseSBsYXJnZSBhbmQgcmVhbGx5IHNtYWxsIHBhdGhld2F5cy4gV2UgY2FuIGNoYW5nZSB0aGVlc2Ugc2V0dGluZ3MgbGF0ZXIuDQpgYGB7cn0NCnJlYWN0b21lX29udG9sb2d5X2ZpbHRlcmVkIDwtIGZpbHRlcl9vbnRvbG9neShnbXQgPSByZWFjdG9tZV9vbnRvbG9neSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5fbnJfb2ZfZWxlbWVudHMgPSA1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heF9ucl9vZl9lbGVtZW50cyA9IDUwMCkNCmBgYA0KT21uaVBhdGggbmV3dHdvcmsgZmlsZQ0KYGBge3J9DQpvcCA8LSByZWFkLmNzdigiT21uaVBhdGhfMjdfMTBfMjAyMV9kaXJlY3RlZC5uY29sIiwgc2VwPSIgIiwgaGVhZGVyID0gRkFMU0UsIHJvdy5uYW1lcyA9IE5VTEwpDQpoZWFkKG9wKQ0KYGBgDQpgYGB7cn0NCmhlYWQob3V0Y29tZV91YykNCmBgYA0KYGBge3J9DQpmaWx0ZXJlZF9vdXRjb21lX3VjIDwtIG91dGNvbWVfdWNbb3V0Y29tZV91YyRaX0NvdW50PjAsXQ0KaGVhZChmaWx0ZXJlZF9vdXRjb21lX3VjKQ0KYGBgDQoNCg0KYGBge3J9DQpiZyA8LSB1bmlxdWUoYyhvcCRWMSxvcCRWMikpDQpgYGANCmBgYHtyfQ0KIyBUcmFuc2xhdGluZyBnZW5lcyBpbiB0aGUgYmFja2dyb3VuZCBhbmQgb3V0Y29tZSBkYXRhIHRvIGdlbmUgc3ltYm9scw0KDQojIFRyYW5zbGF0ZSBiYWNrZ3JvdW5kIGdlbmVzDQpiZ19zeW1ib2xzIDwtIG1hcElkcyhvcmcuSHMuZWcuZGIsIGtleXMgPSBiZywgY29sdW1uID0gIlNZTUJPTCIsIGtleXR5cGUgPSAiVU5JUFJPVCIsIG11bHRpVmFscyA9ICJmaXJzdCIpDQpgYGANCjQuIENyZWF0aW5nIEZpZ3VyZSA0L2INCmBgYHtyfQ0KaGlzdG9ncmFtcGxvdF91YyA8LSBnZ3Bsb3QoZmlsdGVyZWRfb3V0Y29tZV91YywgYWVzKHg9Wl9Db3VudCkpICsgDQogICAgZ2VvbV9oaXN0b2dyYW0oY29sb3VyPSJ3aGl0ZSIsIGZpbGw9Im9yYW5nZSIsIGJpbndpZHRoID0gNTApKw0KICAgIHlsYWIoIk51bWJlciBvZiBpbmRpdmlkdWFsIHByb3RlaW5zIikgKyB4bGFiKCJOdW1iZXIgb2YgcGF0aWVudHMiKSArDQogICAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD0xMDApLA0KICAgICAgICAgICAgY29sb3I9ImJsYWNrIiwgbGluZXR5cGU9ImRhc2hlZCIsIHNpemU9MSkgKyANCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLDE0MDAsMjAwKSkgKyB0aGVtZV9saWdodCgpDQogICAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImJsYWNrIikpICsNCiAgICB0aGVtZShwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIsIGNvbG91ciA9ICJ3aGl0ZSIpKSArDQogICAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxMCkpICsNCiAgICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoY29sb3VyID0gImJsYWNrIiwgc2l6ZSA9IDEwKSkgKw0KICAgIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvcj0gImJsYWNrIiwgc2l6ZSA9IDEwKSkgKw0KICAgIHRoZW1lKGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJibGFjayIpKSArDQogICAgdGhlbWUocGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkNCmhpc3RvZ3JhbXBsb3RfdWMNCmBgYA0KDQo1LiBFbnJpY2htbmV0IGFuZCBjcmVhdGluZyBGaWd1cmUgMmMNCmBgYHtyfQ0KY29tbW9ubHlfYWZmZmVjdGVkX2dlbmVzX3VjIDwtIGZpbHRlcmVkX291dGNvbWVfdWNbZmlsdGVyZWRfb3V0Y29tZV91YyRaX0NvdW50PjEwMCxdIA0KYGBgDQpgYGB7cn0NCmRpbShjb21tb25seV9hZmZmZWN0ZWRfZ2VuZXNfdWMpDQpgYGANCmBgYHtyfQ0KY29tbW9ubHlfYWZmZmVjdGVkX3VjX2dlbmVzX3N5bWJvbHMgPC0gbWFwSWRzKG9yZy5Icy5lZy5kYiwga2V5cyA9IHJvdy5uYW1lcyhjb21tb25seV9hZmZmZWN0ZWRfZ2VuZXNfdWMpLCANCmNvbHVtbiA9ICJTWU1CT0wiLCBrZXl0eXBlID0gIlVOSVBST1QiLCBtdWx0aVZhbHMgPSAiZmlyc3QiKQ0KYGBgDQoNCmBgYHtyfQ0Kb3JhX21vZGVsIDwtIG9yYShnbXQgPSByZWFjdG9tZV9vbnRvbG9neV9maWx0ZXJlZCwgDQogICAgICAgICAgICAgICAgICMgVGVzdCBzZXQgdmFyaWFibGUNCiAgICAgICAgICAgICAgICAgZWxlbWVudF9uYW1lcyA9IGNvbW1vbmx5X2FmZmZlY3RlZF91Y19nZW5lc19zeW1ib2xzLCANCiAgICAgICAgICAgICAgICAgIyBCYWNrZ3JvdW5kIHNldCB2YXJpYWJsZQ0KICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kX2VsZW1lbnRfbmFtZXMgPSBiZ19zeW1ib2xzLCANCiAgICAgICAgICAgICAgICAgIyBwLXZhbHVlIGFkanVzdG1lbnQgbWV0aG9kDQogICAgICAgICAgICAgICAgIHBfdmFsdWVfYWRqdXN0bWVudF9tZXRob2QgPSAiZUZEUiIsIA0KICAgICAgICAgICAgICAgICAjIE51bWJlciBvZiBwZXJtdXRhdGlvbnMNCiAgICAgICAgICAgICAgICAgbnVtYmVyX29mX3Blcm11dGF0aW9ucyA9IDEwMDAwLA0KICAgICAgICAgICAgICAgICAjIE51bWJlciBvZiBwcm9jZXNzb3IgdGhyZWFkcyB0byB1c2UNCiAgICAgICAgICAgICAgICAgbnRocmVhZHMgPSAyLCANCiAgICAgICAgICAgICAgICAgIyBTZXR0aW5nIGEgcmFuZG9tIHNlZWQgZm9yIHJlcHJvZHVjaWJpbGl0eQ0KICAgICAgICAgICAgICAgICByYW5kb21fc2VlZCA9IDQyKSANCg0KcmVhY3RvbWVfcmVzdWx0c191Y19wcGkgPC0gcnVuX3Rlc3Qob3JhX21vZGVsKQ0KYGBgDQpgYGB7cn0NCnJlYWN0b21lX3Jlc3VsdHNfdWNfcHBpJEdlbmVSYXRpbyA8LSByZWFjdG9tZV9yZXN1bHRzX3VjX3BwaSRucl9jb21tb25fd2l0aF90ZXN0ZWRfZWxlbWVudHMgLyBsZW5ndGgoY29tbW9ubHlfYWZmZmVjdGVkX3VjX2dlbmVzX3N5bWJvbHMpDQpzaWdfcmVzdWx0c191Y19wcGkgPC0gcmVhY3RvbWVfcmVzdWx0c191Y19wcGkgJT4lDQogICAgIyBSb3dzIHdoZXJlIHRoZSBlRkRSIDwgMC4wNQ0KICAgIGZpbHRlcihlRkRSIDwgMC4xKSAlPiUNCiAgICAjIEFycmFuZ2UgdGhlIHJvd3MgYnkgdGhlIGdlbmUgcmF0aW8gZm9yIHBsb3R0aW5nDQogICAgYXJyYW5nZShkZXNjKEdlbmVSYXRpbykpDQpzaWdfcmVzdWx0c191Y19wcGkkb250b2xvZ3lfaWQgPC0gZmFjdG9yKHNpZ19yZXN1bHRzX3VjX3BwaSRvbnRvbG9neV9pZCwNCmxldmVscyA9IHNpZ19yZXN1bHRzX3VjX3BwaVtvcmRlcihzaWdfcmVzdWx0c191Y19wcGkkR2VuZVJhdGlvLCBkZWNyZWFzaW5nID0gRkFMU0UpLCAib250b2xvZ3lfaWQiXSkNCnNpZ19yZXN1bHRzX3VjX3BwaQ0KYGBgDQpgYGB7cn0NCndyaXRlLmNzdihyZWFjdG9tZV9yZXN1bHRzX3VjX3BwaSwgZ2x1ZSgiUmVhY3RvbWVfVUNfUFBJXzEwMF9jdXRvZmZfb3JhX3Jlc3VsdHMuY3N2IiksIHJvdy5uYW1lcyA9IEZBTFNFKQ0KYGBgDQpMYWJlbCBmb3JtYXR0aW5nDQpgYGB7cn0NCnNpZ19yZXN1bHRzX3VjX3BwaSRmb3JtZWRfaWQgPC0gZ3N1YigiXyIsICIgIiwgc2lnX3Jlc3VsdHNfdWNfcHBpJG9udG9sb2d5X2lkKQ0Kc2lnX3Jlc3VsdHNfdWNfcHBpJGZvcm1lZF9pZCA8LSBmYWN0b3Ioc2lnX3Jlc3VsdHNfdWNfcHBpJGZvcm1lZF9pZCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHNpZ19yZXN1bHRzX3VjX3BwaVtvcmRlcihzaWdfcmVzdWx0c191Y19wcGkkR2VuZVJhdGlvLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjcmVhc2luZyA9IEZBTFNFKSwgImZvcm1lZF9pZCJdKQ0KDQpgYGANCkFkZGluZyBhIHNtYWxsIGFtb3VudCBmb3IgdGhlIGZEUiBjYWxjdWF0aW9uIGJhc2VkIG9uIHRoZSBNVUxFQSBjYWxjYXV0aW9ucy4NCmBgYHtyfQ0Kc2lnX3Jlc3VsdHNfdWNfcHBpJGVGRFIgPSBzaWdfcmVzdWx0c191Y19wcGkkZUZEUiArMTBeLTEyDQpgYGANCmBgYHtyfQ0KZG90cGxvdF9yZWFjdG9tZV91Y19wcGkgPC0gZ2dwbG90KHNpZ19yZXN1bHRzX3VjX3BwaVsxOjIwLF0sIGFlcyh4PUdlbmVSYXRpbywgeT1mb3JtZWRfaWQpKSArDQogICAgZ2VvbV9wb2ludChhZXMoc2l6ZT1ucl9jb21tb25fd2l0aF90ZXN0ZWRfZWxlbWVudHMsIGNvbG91cj1lRkRSKSkgKw0KICAgIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gbGFiZWxfd3JhcCg1MCkpICsgDQogICAgc2NhbGVfY29sb3JfY29udGludW91cyhsb3c9InJlZCIsIGhpZ2g9ImJsdWUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0cz1jKDEwXi01LCAwLjEpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnMgPSAibG9nMTAiLCBuYW1lPSJFbXByaWNhbCBGRFIiKQ0KICAgICAgICAgICAgICAgIA0KDQpkb3RwbG90X3JlYWN0b21lX3VjX3BwaSA8LSBkb3RwbG90X3JlYWN0b21lX3VjX3BwaSArDQogICAgc2NhbGVfc2l6ZShsaW1pdHMgPSBjKDIsMjApLCByYW5nZSA9IGMoMiwxNSksIG5hbWUgPSAiTnVtYmVyIG9mIGdlbmVzIikgKyANCiAgICB4bGltKDAsIDAuMjMpICsNCiAgICB4bGFiKCJHZW5lIFJhdGlvIikgKw0KICAgIHlsYWIoIlJlYWN0b21lIHBhdGh3YXlzIikgKw0KICAgIHRoZW1lX2xpZ2h0KCkgKw0KICAgIHRoZW1lKHJlY3Q9ZWxlbWVudF9yZWN0KGZpbGw9IndoaXRlIikpICsNCiAgICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiKSkgKw0KICAgIHRoZW1lKHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIikpICsNCiAgICB0aGVtZShwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gIndoaXRlIikpKw0KICAgIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAiYmxhY2siLCBzaXplID0gMTApKSArDQogICAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxMCkpICsNCiAgICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3I9ICJibGFjayIsIHNpemUgPSAxMCkpICsNCiAgICB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiYmxhY2siKSkgKw0KICAgIHRoZW1lKGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSJ3aGl0ZSIpKSArDQogICAgdGhlbWUobGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgc2l6ZSA9IDEwKSkgKw0KICAgIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0gImJsYWNrIiwgc2l6ZSA9IDEwKSkgDQpgYGANCmBgYHtyfQ0KZG90cGxvdF9yZWFjdG9tZV91Y19wcGkNCmBgYA0KDQpgYGB7cn0NCnBuZyhmaWxlPWdsdWUoIkhpc3RvZ3JhbV9VQ19QUElfdjQucG5nIiksd2lkdGg9OCwgaGVpZ2h0PTQsIHVuaXRzPSJpbiIsIHJlcz02MDApDQpoaXN0b2dyYW1wbG90X3VjDQpkZXYub2ZmKCkNCnBuZyhmaWxlPWdsdWUoIkhhbGxtYXJrc19VQ19QUEl0b3AxMDBfdjNfdG9wMjAucG5nIiksd2lkdGg9OCwgaGVpZ2h0PTgsIHVuaXRzPSJpbiIsIHJlcz02MDApDQpkb3RwbG90X3JlYWN0b21lX3VjX3BwaQ0KZGV2Lm9mZigpDQpgYGANCg==