1 Functions

library(stringi)
source_from_github(repositoy = "DEG_functions",version = "0.2.47")
source_from_github(repositoy = "cNMF_functions",version = "0.4.0",script_name = "cnmf_functions_V3.R")
source_from_github(repositoy = "sc_general_functions",version = "0.1.28",script_name = "functions.R")

2 Data

library("readxl")
acc_all = readRDS(file = "./Data/acc_tpm_nCount_mito_no146_15k_alldata.rds")
acc_cancer_pri = readRDS(file = "./Data/acc_cancer_no146_primaryonly15k_cancercells.rds")
acc_cancer = readRDS(file = "./Data/acc_tpm_nCount_mito_no146_15k_cancercells.rds")


neuronal_signatures <- read_excel("./Data/Neuronal Signatures.xlsx",col_names =F)
neuronal_signatures  %<>%  t() %>% as.data.frame() %>% janitor::row_to_names(1) %>%  filter(!row_number() == 1)
rownames(neuronal_signatures) <- NULL
colnames(neuronal_signatures)   %<>%  gsub(replacement = "", pattern = "_\\d.*") #remove any _numbers
colnames(neuronal_signatures)   %<>%  gsub(replacement = "", pattern = "\\(.*") #rename "(" to the end
colnames(neuronal_signatures)   %<>%  gsub(replacement = "_", pattern = " ") #rename all spaces

neuronal_pathways <- read_excel("./Data/Pathway analysis Gene sets.xlsx",col_names =F)
neuronal_pathways  %<>%  t() %>% as.data.frame() %>% janitor::row_to_names(1) %>%  filter(!row_number() == 1)  %>%  as.list() 
neuronal_pathways = lapply(neuronal_pathways, na.omit)
neuronal_pathways = lapply(neuronal_pathways, as.character)

3 Neuronal signatures

3.1 Violin plots

for (neural_name in colnames(neuronal_signatures)) {
  genes = neuronal_signatures[,neural_name,drop=T]
  # Assuming df is your data frame

  
  pathways_scores = FetchData(object = acc_all,vars = genes,slot = "data") %>% 
    mutate_all(~ 2^.)%>% mutate_all(~ .-1) %>%  #covert log(TPM+1) to TPM
    rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
  acc_all  %<>% AddMetaData(metadata = pathways_scores$score,col.name = neural_name)
}

Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = “data”) : The following requested variables were not found: SNHG29, NOP53 Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = “data”) : The following requested variables were not found: NOP53 Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = “data”) : The following requested variables were not found: NOP53

plt = VlnPlot(object = acc_all,features = colnames(neuronal_signatures))
plt[[1]] = plt[[1]]+ ylab("TPM")
plt[[4]] = plt[[4]]+ ylab("TPM")
plt[[7]] = plt[[7]]+ ylab("TPM")
print_tab(plt = plt,title = "expression with RP genes",subtitle_num = 3)

expression with RP genes

NA

rp_genes = lapply(neuronal_signatures %>% as.list(),  function(x) {x[startsWith(x = x,prefix = "RP")]}) %>% unlist() %>% unique() %>% as.data.frame()
print_tab(rp_genes,title = " RP genes names",subtitle_num = 3)

RP genes names

NA

neuronal_signatures_no_RP = lapply(neuronal_signatures %>% as.list(),  function(x) {x[!startsWith(x = x,prefix = "RP")]})
names(neuronal_signatures_no_RP) =  paste0(names(neuronal_signatures_no_RP),"_noRP")
for (neural_name in names(neuronal_signatures_no_RP)) {
  genes = neuronal_signatures_no_RP[[neural_name]]
  # Assuming df is your data frame

  pathways_scores = FetchData(object = acc_all,vars = genes,slot = "data") %>% 
    mutate_all(~ 2^.)%>% mutate_all(~ .-1) %>%  #covert log(TPM+1) to TPM
    rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
  acc_all  %<>% AddMetaData(metadata = pathways_scores$score,col.name = neural_name)
}

plt = VlnPlot(object = acc_all,features = names(neuronal_signatures_no_RP))
for (i in 1:(length(plt$patches$plots)+1)) {
  plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=12))
  if (i %in% c(1,4,7)) {
    plt[[i]] = plt[[i]]+ylab("TPM")
  }
}
print_tab(plt = plt,title = "expression without RP genes",subtitle_num = 3)

expression without RP genes

NA

3.2 UMAPS

plt1 = FeaturePlot(object = acc_all,features = colnames(neuronal_signatures))& theme(plot.title = element_text(size=13))
plt2 = FeaturePlot(object = acc_all,features = names(neuronal_signatures_no_RP)) & theme(plot.title = element_text(size=12))
print_tab(plt = plt1,title = "UMAP with RP",subtitle_num = 3)

UMAP with RP

print_tab(plt = plt2,title = "UMAP without RP",subtitle_num = 3)

UMAP without RP

NA

3.3 High Sympathetic_cholinergic_neuron

high_cholinergic_neuron = list( high_cholinergic_neuron = colnames(acc_all)[acc_all$Sympathetic_cholinergic_neuron_noRP>1000])
DimPlot(object = acc_all, cells.highlight = high_cholinergic_neuron, cols.highlight = "red", cols = "gray", order = TRUE)

4 Pathway comparison

4.1 pathway all cancer cells UMAP

for (pathway_name in names(neuronal_pathways)) {
  genes = neuronal_pathways[[pathway_name]]
  pathways_scores = FetchData(object = acc_all,vars = genes,slot = "data") %>% 
    mutate_all(~ 2^.)%>% mutate_all(~ .-1) %>%  #covert log(TPM+1) to TPM
    rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
  acc_all  %<>% AddMetaData(metadata = pathways_scores$score,col.name = pathway_name)
}
Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = "data") :
  The following requested variables were not found: ADORA3
Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = "data") :
  The following requested variables were not found: ADORA3
Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = "data") :
  The following requested variables were not found: ASCL1, PHOX2B
Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = "data") :
  The following requested variables were not found: ASCL1, PHOX2B
Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = "data") :
  The following requested variables were not found: ARX, HOXB1, ASCL1, PRLH, PHOX2B, ISX
Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = "data") :
  The following requested variables were not found: HOXB1, PHOX2B
Warning in FetchData.Seurat(object = acc_all, vars = genes, slot = "data") :
  The following requested variables were not found: DRD3, MIR1-1, MIR133A1


plt = FeaturePlot(object = acc_all,features = names(neuronal_pathways),pt.size = 0.5)
for (i in 1:(length(plt$patches$plots)+1)) {
  plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=10.5))+ labs(color='TPM') + scale_color_gradientn(colours = rainbow(5))
}

Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale.

print_tab(plt,title = "TPM",subtitle_num = 3)

TPM

NA

for (pathway_name in names(neuronal_pathways)) {
  genes = neuronal_pathways[[pathway_name]]
  pathways_scores = FetchData(object = acc_all,vars = genes,slot = "data") %>% 
    rowwise() %>% mutate(score = mean(c_across(everything()))) #mean
  acc_all  %<>% AddMetaData(metadata = pathways_scores$score,col.name = pathway_name)
}


plt1 = FeaturePlot(object = acc_all,features = names(neuronal_pathways),pt.size = 0.5)&
  theme(plot.title = element_text(size=10.5)) & labs(color='log (TPM+1)') & scale_color_gradientn(colours = rainbow(5))

Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale.

plt2 = FeaturePlot(object = acc_all,features = names(neuronal_pathways),pt.size = 0.5)&
  theme(plot.title = element_text(size=10.5)) & labs(color='log (TPM+1)')


print_tab(plt2,title = "log(TPM+1) ",subtitle_num = 3)

log(TPM+1)

print_tab(plt1,title = "log(TPM+1) rainbow",subtitle_num = 3)

log(TPM+1) rainbow

NA

5 Beta-2 receptor

5.1 UMAP

b2r_genes = c("RAF1", "PAMPK1", "PRKACA", "PIK3CA", "AKT1", "AKT2", "AKT3", "CREB1", "CREBBP", "BCL2", "BAD", "JUN", "FOS",  "MYC")
tpm_1 = FeaturePlot(object = acc_tpm,features = b2r_genes[1:9],pt.size = 0.5,slot = "counts") & scale_color_gradientn(colours = rainbow(5)) & labs(color='TPM')

Warning in FetchData.Seurat(object = object, vars = c(dims, “ident”, features), : The following requested variables were not found: PAMPK1 Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale.

tpm_2 = FeaturePlot(object = acc_tpm,features = b2r_genes[10:length(b2r_genes)],pt.size = 0.5,slot = "counts") & scale_color_gradientn(colours = rainbow(5)) & labs(color='TPM')

Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale. Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale.

logTPM1 = FeaturePlot(object = acc_all,features = b2r_genes[1:9],pt.size = 0.5) & labs(color='log(TPM+1)')

Warning in FetchData.Seurat(object = object, vars = c(dims, “ident”, features), : The following requested variables were not found: PAMPK1

logTPM2 = FeaturePlot(object = acc_all,features = b2r_genes[10:length(b2r_genes)]) & labs(color='log(TPM+1)')

print_tab(plt = tpm_1,title = "TPM part 1",subtitle_num = 3)

TPM part 1

print_tab(plt = tpm_2,title = "TPM part 2",subtitle_num = 3)

TPM part 2

print_tab(plt = logTPM1,title = "log TPM part 1",subtitle_num = 3)

log TPM part 1

print_tab(plt = logTPM2,title = "log TPM part 2",subtitle_num = 3)

log TPM part 2

NA

5.2 Signature

pathways_scores = FetchData(object = acc_all,vars = b2r_genes,slot = "data") %>% 
  mutate_all(~ 2^.)%>% mutate_all(~ .-1) %>%  #covert log(TPM+1) to TPM
  rowwise() %>% mutate(score = mean(c_across(everything()))) #mean

Warning in FetchData.Seurat(object = acc_all, vars = b2r_genes, slot = “data”) : The following requested variables were not found: PAMPK1

acc_all  %<>% AddMetaData(metadata = pathways_scores$score,col.name = "b2r_signature_TPM")

tpm = FeaturePlot(object = acc_all,features ="b2r_signature_TPM",pt.size = 0.5,slot = "counts") & scale_color_gradientn(colours = rainbow(5)) & labs(color='TPM')

Scale for ‘colour’ is already present. Adding another scale for ‘colour’, which will replace the existing scale.

pathways_scores = FetchData(object = acc_all,vars = b2r_genes,slot = "data") %>% 
  rowwise() %>% mutate(score = mean(c_across(everything()))) #mean

Warning in FetchData.Seurat(object = acc_all, vars = b2r_genes, slot = “data”) : The following requested variables were not found: PAMPK1

acc_all  %<>% AddMetaData(metadata = pathways_scores$score,col.name = "b2r_signature")

logTPM = FeaturePlot(object = acc_all,features ="b2r_signature",pt.size = 0.5,slot = "counts")  & labs(color='log TPM')

print_tab(plt = tpm,title = "TPM",subtitle_num = 3)

TPM

print_tab(plt = logTPM,title = "log TPM",subtitle_num = 3)

log TPM

NA

LS0tCnRpdGxlOiAiQW5hbHlzaXNfbWVldGluZ18xMV8xOSIKYXV0aG9yOiAiQXZpc2hhaSBXaXplbCIKZGF0ZTogJ2ByIFN5cy50aW1lKClgJwpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6IAogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICB0b2M6IHllcwogICAgdG9jX2NvbGxhcHNlOiB5ZXMKICAgIHRvY19mbG9hdDogCiAgICAgIGNvbGxhcHNlZDogRkFMU0UKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgdG9jX2RlcHRoOiAxCi0tLQoKIyBGdW5jdGlvbnMKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoc3RyaW5naSkKc291cmNlX2Zyb21fZ2l0aHViKHJlcG9zaXRveSA9ICJERUdfZnVuY3Rpb25zIix2ZXJzaW9uID0gIjAuMi40NyIpCnNvdXJjZV9mcm9tX2dpdGh1YihyZXBvc2l0b3kgPSAiY05NRl9mdW5jdGlvbnMiLHZlcnNpb24gPSAiMC40LjAiLHNjcmlwdF9uYW1lID0gImNubWZfZnVuY3Rpb25zX1YzLlIiKQpzb3VyY2VfZnJvbV9naXRodWIocmVwb3NpdG95ID0gInNjX2dlbmVyYWxfZnVuY3Rpb25zIix2ZXJzaW9uID0gIjAuMS4yOCIsc2NyaXB0X25hbWUgPSAiZnVuY3Rpb25zLlIiKQpgYGAKCiMgRGF0YQoKYGBge3J9CmxpYnJhcnkoInJlYWR4bCIpCmFjY19hbGwgPSByZWFkUkRTKGZpbGUgPSAiLi9EYXRhL2FjY190cG1fbkNvdW50X21pdG9fbm8xNDZfMTVrX2FsbGRhdGEucmRzIikKYWNjX2NhbmNlcl9wcmkgPSByZWFkUkRTKGZpbGUgPSAiLi9EYXRhL2FjY19jYW5jZXJfbm8xNDZfcHJpbWFyeW9ubHkxNWtfY2FuY2VyY2VsbHMucmRzIikKYWNjX2NhbmNlciA9IHJlYWRSRFMoZmlsZSA9ICIuL0RhdGEvYWNjX3RwbV9uQ291bnRfbWl0b19ubzE0Nl8xNWtfY2FuY2VyY2VsbHMucmRzIikKCgpuZXVyb25hbF9zaWduYXR1cmVzIDwtIHJlYWRfZXhjZWwoIi4vRGF0YS9OZXVyb25hbCBTaWduYXR1cmVzLnhsc3giLGNvbF9uYW1lcyA9RikKbmV1cm9uYWxfc2lnbmF0dXJlcyAgJTw+JSAgdCgpICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGphbml0b3I6OnJvd190b19uYW1lcygxKSAlPiUgIGZpbHRlcighcm93X251bWJlcigpID09IDEpCnJvd25hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpIDwtIE5VTEwKY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykgICAlPD4lICBnc3ViKHJlcGxhY2VtZW50ID0gIiIsIHBhdHRlcm4gPSAiX1xcZC4qIikgI3JlbW92ZSBhbnkgX251bWJlcnMKY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykgICAlPD4lICBnc3ViKHJlcGxhY2VtZW50ID0gIiIsIHBhdHRlcm4gPSAiXFwoLioiKSAjcmVuYW1lICIoIiB0byB0aGUgZW5kCmNvbG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpICAgJTw+JSAgZ3N1YihyZXBsYWNlbWVudCA9ICJfIiwgcGF0dGVybiA9ICIgIikgI3JlbmFtZSBhbGwgc3BhY2VzCgpuZXVyb25hbF9wYXRod2F5cyA8LSByZWFkX2V4Y2VsKCIuL0RhdGEvUGF0aHdheSBhbmFseXNpcyBHZW5lIHNldHMueGxzeCIsY29sX25hbWVzID1GKQpuZXVyb25hbF9wYXRod2F5cyAgJTw+JSAgdCgpICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGphbml0b3I6OnJvd190b19uYW1lcygxKSAlPiUgIGZpbHRlcighcm93X251bWJlcigpID09IDEpICAlPiUgIGFzLmxpc3QoKSAKbmV1cm9uYWxfcGF0aHdheXMgPSBsYXBwbHkobmV1cm9uYWxfcGF0aHdheXMsIG5hLm9taXQpCm5ldXJvbmFsX3BhdGh3YXlzID0gbGFwcGx5KG5ldXJvbmFsX3BhdGh3YXlzLCBhcy5jaGFyYWN0ZXIpCgpgYGAKCiMgTmV1cm9uYWwgc2lnbmF0dXJlcwoKIyMgVmlvbGluIHBsb3RzIHsudGFic2V0fQoKYGBge3IgcmVzdWx0cz0nYXNpcyd9CmZvciAobmV1cmFsX25hbWUgaW4gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykpIHsKICBnZW5lcyA9IG5ldXJvbmFsX3NpZ25hdHVyZXNbLG5ldXJhbF9uYW1lLGRyb3A9VF0KICAjIEFzc3VtaW5nIGRmIGlzIHlvdXIgZGF0YSBmcmFtZQoKICAKICBwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2FsbCx2YXJzID0gZ2VuZXMsc2xvdCA9ICJkYXRhIikgJT4lIAogICAgbXV0YXRlX2FsbCh+IDJeLiklPiUgbXV0YXRlX2FsbCh+IC4tMSkgJT4lICAjY292ZXJ0IGxvZyhUUE0rMSkgdG8gVFBNCiAgICByb3d3aXNlKCkgJT4lIG11dGF0ZShzY29yZSA9IG1lYW4oY19hY3Jvc3MoZXZlcnl0aGluZygpKSkpICNtZWFuCiAgYWNjX2FsbCAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9IG5ldXJhbF9uYW1lKQp9CmBgYAoKYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCByZXN1bHRzPSdhc2lzJ30KcGx0ID0gVmxuUGxvdChvYmplY3QgPSBhY2NfYWxsLGZlYXR1cmVzID0gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykpCnBsdFtbMV1dID0gcGx0W1sxXV0rIHlsYWIoIlRQTSIpCnBsdFtbNF1dID0gcGx0W1s0XV0rIHlsYWIoIlRQTSIpCnBsdFtbN11dID0gcGx0W1s3XV0rIHlsYWIoIlRQTSIpCnByaW50X3RhYihwbHQgPSBwbHQsdGl0bGUgPSAiZXhwcmVzc2lvbiB3aXRoIFJQIGdlbmVzIixzdWJ0aXRsZV9udW0gPSAzKQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMiwgcmVzdWx0cz0nYXNpcyd9CnJwX2dlbmVzID0gbGFwcGx5KG5ldXJvbmFsX3NpZ25hdHVyZXMgJT4lIGFzLmxpc3QoKSwgIGZ1bmN0aW9uKHgpIHt4W3N0YXJ0c1dpdGgoeCA9IHgscHJlZml4ID0gIlJQIildfSkgJT4lIHVubGlzdCgpICU+JSB1bmlxdWUoKSAlPiUgYXMuZGF0YS5mcmFtZSgpCnByaW50X3RhYihycF9nZW5lcyx0aXRsZSA9ICIgUlAgZ2VuZXMgbmFtZXMiLHN1YnRpdGxlX251bSA9IDMpCgoKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTIsIHJlc3VsdHM9J2FzaXMnfQpuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQID0gbGFwcGx5KG5ldXJvbmFsX3NpZ25hdHVyZXMgJT4lIGFzLmxpc3QoKSwgIGZ1bmN0aW9uKHgpIHt4WyFzdGFydHNXaXRoKHggPSB4LHByZWZpeCA9ICJSUCIpXX0pCm5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXNfbm9fUlApID0gIHBhc3RlMChuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQKSwiX25vUlAiKQpmb3IgKG5ldXJhbF9uYW1lIGluIG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXNfbm9fUlApKSB7CiAgZ2VuZXMgPSBuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQW1tuZXVyYWxfbmFtZV1dCiAgIyBBc3N1bWluZyBkZiBpcyB5b3VyIGRhdGEgZnJhbWUKCiAgcGF0aHdheXNfc2NvcmVzID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19hbGwsdmFycyA9IGdlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICAgIG11dGF0ZV9hbGwofiAyXi4pJT4lIG11dGF0ZV9hbGwofiAuLTEpICU+JSAgI2NvdmVydCBsb2coVFBNKzEpIHRvIFRQTQogICAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgogIGFjY19hbGwgICU8PiUgQWRkTWV0YURhdGEobWV0YWRhdGEgPSBwYXRod2F5c19zY29yZXMkc2NvcmUsY29sLm5hbWUgPSBuZXVyYWxfbmFtZSkKfQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMiwgcmVzdWx0cz0nYXNpcyd9CgpwbHQgPSBWbG5QbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSBuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQKSkKZm9yIChpIGluIDE6KGxlbmd0aChwbHQkcGF0Y2hlcyRwbG90cykrMSkpIHsKCiAgcGx0W1tpXV0gPSBwbHRbW2ldXSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpCiAgaWYgKGkgJWluJSBjKDEsNCw3KSkgewogICAgcGx0W1tpXV0gPSBwbHRbW2ldXSt5bGFiKCJUUE0iKQogIH0KfQpwcmludF90YWIocGx0ID0gcGx0LHRpdGxlID0gImV4cHJlc3Npb24gd2l0aG91dCBSUCBnZW5lcyIsc3VidGl0bGVfbnVtID0gMykKYGBgCgojIyBVTUFQUyB7LnRhYnNldH0KCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMiwgcmVzdWx0cz0nYXNpcyd9CnBsdDEgPSBGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfYWxsLGZlYXR1cmVzID0gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykpJiB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTMpKQpwbHQyID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2FsbCxmZWF0dXJlcyA9IG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXNfbm9fUlApKSAmIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpCnByaW50X3RhYihwbHQgPSBwbHQxLHRpdGxlID0gIlVNQVAgd2l0aCBSUCIsc3VidGl0bGVfbnVtID0gMykKcHJpbnRfdGFiKHBsdCA9IHBsdDIsdGl0bGUgPSAiVU1BUCB3aXRob3V0IFJQIixzdWJ0aXRsZV9udW0gPSAzKQoKYGBgCgojIyBIaWdoIFN5bXBhdGhldGljX2Nob2xpbmVyZ2ljX25ldXJvbgoKYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCByZXN1bHRzPSdhc2lzJ30KaGlnaF9jaG9saW5lcmdpY19uZXVyb24gPSBsaXN0KCBoaWdoX2Nob2xpbmVyZ2ljX25ldXJvbiA9IGNvbG5hbWVzKGFjY19hbGwpW2FjY19hbGwkU3ltcGF0aGV0aWNfY2hvbGluZXJnaWNfbmV1cm9uX25vUlA+MTAwMF0pCkRpbVBsb3Qob2JqZWN0ID0gYWNjX2FsbCwgY2VsbHMuaGlnaGxpZ2h0ID0gaGlnaF9jaG9saW5lcmdpY19uZXVyb24sIGNvbHMuaGlnaGxpZ2h0ID0gInJlZCIsIGNvbHMgPSAiZ3JheSIsIG9yZGVyID0gVFJVRSkKCmBgYAoKIyBQYXRod2F5IGNvbXBhcmlzb24KCmBgYHtyfQpsaWJyYXJ5KHJlc2hhcGUyKSAKbGlicmFyeShnZ3B1YnIpCmRhdGEgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcix2YXJzID0gYyhuYW1lcyhuZXVyb25hbF9wYXRod2F5cylbMToyXSkpCmRhdGEgPSAgcmVzaGFwZTI6Om1lbHQoZGF0YSkKbmFtZXMgKGRhdGEpID0gYygicGF0aHdheSIsIlRQTSIpCmdnYm94cGxvdChkYXRhLCB4ID0gInBhdGh3YXkiLCB5ID0iVFBNIiwKICAgICAgICAgICAgICBwYWxldHRlID0gImpjbyIsCiAgICAgICAgICAgICAgYWRkID0gImppdHRlciIpKyB0aGVtZSggYXhpcy50ZXh0LnggID0gZWxlbWVudF90ZXh0KHNpemU9MTApKSsKICAgIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IGZ1bmN0aW9uKHgpIGRhdGEuZnJhbWUoeT0yMTAwLCBsYWJlbCA9IHBhc3RlKCJNZWFuPSIscm91bmQobWVhbih4KSxkaWdpdHMgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMikpKSwgZ2VvbT0idGV4dCIpIApgYGAKCiMjIHBhdGh3YXkgYWxsIGNhbmNlciBjZWxscyBVTUFQIHsudGFic2V0fQoKYGBge3J9CmZvciAocGF0aHdheV9uYW1lIGluIG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSkgewogIGdlbmVzID0gbmV1cm9uYWxfcGF0aHdheXNbW3BhdGh3YXlfbmFtZV1dCiAgcGF0aHdheXNfc2NvcmVzID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19hbGwsdmFycyA9IGdlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICAgIG11dGF0ZV9hbGwofiAyXi4pJT4lIG11dGF0ZV9hbGwofiAuLTEpICU+JSAgI2NvdmVydCBsb2coVFBNKzEpIHRvIFRQTQogICAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgogIGFjY19hbGwgICU8PiUgQWRkTWV0YURhdGEobWV0YWRhdGEgPSBwYXRod2F5c19zY29yZXMkc2NvcmUsY29sLm5hbWUgPSBwYXRod2F5X25hbWUpCn0KYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTE1LCBmaWcud2lkdGg9MTUsIG1lc3NhZ2U9RkFMU0UscmVzdWx0cz0nYXNpcyd9CgoKcGx0ID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2FsbCxmZWF0dXJlcyA9IG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSxwdC5zaXplID0gMC41KQpmb3IgKGkgaW4gMToobGVuZ3RoKHBsdCRwYXRjaGVzJHBsb3RzKSsxKSkgewogIHBsdFtbaV1dID0gcGx0W1tpXV0gKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTAuNSkpKyBsYWJzKGNvbG9yPSdUUE0nKSArIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gcmFpbmJvdyg1KSkKfQpwcmludF90YWIocGx0LHRpdGxlID0gIlRQTSIsc3VidGl0bGVfbnVtID0gMykKYGBgCgpgYGB7cn0KZm9yIChwYXRod2F5X25hbWUgaW4gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpKSB7CiAgZ2VuZXMgPSBuZXVyb25hbF9wYXRod2F5c1tbcGF0aHdheV9uYW1lXV0KICBwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2FsbCx2YXJzID0gZ2VuZXMsc2xvdCA9ICJkYXRhIikgJT4lIAogICAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgogIGFjY19hbGwgICU8PiUgQWRkTWV0YURhdGEobWV0YWRhdGEgPSBwYXRod2F5c19zY29yZXMkc2NvcmUsY29sLm5hbWUgPSBwYXRod2F5X25hbWUpCn0KYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTE1LCBmaWcud2lkdGg9MTUsIG1lc3NhZ2U9RkFMU0UscmVzdWx0cz0nYXNpcyd9CgoKcGx0MSA9IEZlYXR1cmVQbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSBuYW1lcyhuZXVyb25hbF9wYXRod2F5cykscHQuc2l6ZSA9IDAuNSkmCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEwLjUpKSAmIGxhYnMoY29sb3I9J2xvZyAoVFBNKzEpJykgJiBzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3VycyA9IHJhaW5ib3coNSkpCgoKcGx0MiA9IEZlYXR1cmVQbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSBuYW1lcyhuZXVyb25hbF9wYXRod2F5cykscHQuc2l6ZSA9IDAuNSkmCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEwLjUpKSAmIGxhYnMoY29sb3I9J2xvZyAoVFBNKzEpJykKCgpwcmludF90YWIocGx0Mix0aXRsZSA9ICJsb2coVFBNKzEpICIsc3VidGl0bGVfbnVtID0gMykKcHJpbnRfdGFiKHBsdDEsdGl0bGUgPSAibG9nKFRQTSsxKSByYWluYm93IixzdWJ0aXRsZV9udW0gPSAzKQoKYGBgCgojIEJldGEtMiByZWNlcHRvcgoKIyMgVU1BUCB7LnRhYnNldH0KCmBgYHtyIGZpZy5oZWlnaHQ9MTUsIGZpZy53aWR0aD0xNSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9CmIycl9nZW5lcyA9IGMoIlJBRjEiLCAiUEFNUEsxIiwgIlBSS0FDQSIsICJQSUszQ0EiLCAiQUtUMSIsICJBS1QyIiwgIkFLVDMiLCAiQ1JFQjEiLCAiQ1JFQkJQIiwgIkJDTDIiLCAiQkFEIiwgIkpVTiIsICJGT1MiLCAgIk1ZQyIpCnRwbV8xID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX3RwbSxmZWF0dXJlcyA9IGIycl9nZW5lc1sxOjldLHB0LnNpemUgPSAwLjUsc2xvdCA9ICJjb3VudHMiKSAmIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gcmFpbmJvdyg1KSkgJiBsYWJzKGNvbG9yPSdUUE0nKQp0cG1fMiA9IEZlYXR1cmVQbG90KG9iamVjdCA9IGFjY190cG0sZmVhdHVyZXMgPSBiMnJfZ2VuZXNbMTA6bGVuZ3RoKGIycl9nZW5lcyldLHB0LnNpemUgPSAwLjUsc2xvdCA9ICJjb3VudHMiKSAmIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gcmFpbmJvdyg1KSkgJiBsYWJzKGNvbG9yPSdUUE0nKQoKbG9nVFBNMSA9IEZlYXR1cmVQbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSBiMnJfZ2VuZXNbMTo5XSxwdC5zaXplID0gMC41KSAmIGxhYnMoY29sb3I9J2xvZyhUUE0rMSknKQpsb2dUUE0yID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2FsbCxmZWF0dXJlcyA9IGIycl9nZW5lc1sxMDpsZW5ndGgoYjJyX2dlbmVzKV0pICYgbGFicyhjb2xvcj0nbG9nKFRQTSsxKScpCgpwcmludF90YWIocGx0ID0gdHBtXzEsdGl0bGUgPSAiVFBNIHBhcnQgMSIsc3VidGl0bGVfbnVtID0gMykKcHJpbnRfdGFiKHBsdCA9IHRwbV8yLHRpdGxlID0gIlRQTSBwYXJ0IDIiLHN1YnRpdGxlX251bSA9IDMpCnByaW50X3RhYihwbHQgPSBsb2dUUE0xLHRpdGxlID0gImxvZyBUUE0gcGFydCAxIixzdWJ0aXRsZV9udW0gPSAzKQpwcmludF90YWIocGx0ID0gbG9nVFBNMix0aXRsZSA9ICJsb2cgVFBNIHBhcnQgMiIsc3VidGl0bGVfbnVtID0gMykKYGBgCgojIyBTaWduYXR1cmUgey50YWJzZXR9CgpgYGB7ciByZXN1bHRzPSdhc2lzJ30KcGF0aHdheXNfc2NvcmVzID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19hbGwsdmFycyA9IGIycl9nZW5lcyxzbG90ID0gImRhdGEiKSAlPiUgCiAgbXV0YXRlX2FsbCh+IDJeLiklPiUgbXV0YXRlX2FsbCh+IC4tMSkgJT4lICAjY292ZXJ0IGxvZyhUUE0rMSkgdG8gVFBNCiAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgphY2NfYWxsICAlPD4lIEFkZE1ldGFEYXRhKG1ldGFkYXRhID0gcGF0aHdheXNfc2NvcmVzJHNjb3JlLGNvbC5uYW1lID0gImIycl9zaWduYXR1cmVfVFBNIikKCnRwbSA9IEZlYXR1cmVQbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSJiMnJfc2lnbmF0dXJlX1RQTSIscHQuc2l6ZSA9IDAuNSxzbG90ID0gImNvdW50cyIpICYgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSByYWluYm93KDUpKSAmIGxhYnMoY29sb3I9J1RQTScpCgpwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2FsbCx2YXJzID0gYjJyX2dlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICByb3d3aXNlKCkgJT4lIG11dGF0ZShzY29yZSA9IG1lYW4oY19hY3Jvc3MoZXZlcnl0aGluZygpKSkpICNtZWFuCmFjY19hbGwgICU8PiUgQWRkTWV0YURhdGEobWV0YWRhdGEgPSBwYXRod2F5c19zY29yZXMkc2NvcmUsY29sLm5hbWUgPSAiYjJyX3NpZ25hdHVyZSIpCgpsb2dUUE0gPSBGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfYWxsLGZlYXR1cmVzID0iYjJyX3NpZ25hdHVyZSIscHQuc2l6ZSA9IDAuNSxzbG90ID0gImNvdW50cyIpICAmIGxhYnMoY29sb3I9J2xvZyBUUE0nKQoKcHJpbnRfdGFiKHBsdCA9IHRwbSx0aXRsZSA9ICJUUE0iLHN1YnRpdGxlX251bSA9IDMpCnByaW50X3RhYihwbHQgPSBsb2dUUE0sdGl0bGUgPSAibG9nIFRQTSIsc3VidGl0bGVfbnVtID0gMykKYGBgCgpgYGB7PWh0bWx9CjxzY3JpcHQgc3JjPSJodHRwczovL2h5cG90aGVzLmlzL2VtYmVkLmpzIiBhc3luYz48L3NjcmlwdD4KYGBgCg==