1 Functions

library(stringi)
source_from_github(repositoy = "DEG_functions",version = "0.2.47")
ℹ SHA-1 hash of file is f5bb1cd741d13bded83fe3b6fd43169e29731216
Welcome to enrichR
Checking connection ... 
Enrichr ... Connection is Live!
FlyEnrichr ... Connection is available!
WormEnrichr ... Connection is available!
YeastEnrichr ... Connection is available!
FishEnrichr ... Connection is available!
source_from_github(repositoy = "cNMF_functions",version = "0.4.0",script_name = "cnmf_functions_V3.R")
ℹ SHA-1 hash of file is 7b39dfd215cf7e1d29ee976ecc6bfa0e3f1532f6
Loading required package: reticulate
source_from_github(repositoy = "sc_general_functions",version = "0.1.28",script_name = "functions.R")
ℹ SHA-1 hash of file is 737683e4e0a82ffa22769bbd4a0842a271fe63fc
Loading required package: RColorBrewer

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 ACC all cells UMAP

DimPlot(acc_all)

4 Neuronal signatures

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")
plt

5 Neuronal signatures NO RP genes

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)
}
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 = names(neuronal_signatures_no_RP))
plt[[1]] = plt[[1]]+ ylab("TPM")
plt[[4]] = plt[[4]]+ ylab("TPM")
plt[[7]] = plt[[7]]+ ylab("TPM")
plt

5.1 Neuronal signatures expression

count.data <- GetAssayData(object = acc_all[["RNA"]], slot = "data")
count.data <- as.matrix(x = (2**count.data) - 1)
acc_tpm <- SetAssayData(
    object = acc_all,
    slot = "counts",
    new.data = count.data,
    assay = "RNA"
)

for (neural_name in colnames(neuronal_signatures)) {
  genes = neuronal_signatures[,neural_name,drop=T]
  # Assuming df is your data frame
  print_tab(
    DoHeatmap(object = acc_tpm,features = genes,slot = "counts",combine = T,disp.max = 5000)+ labs(fill = "TPM") 
  ,title = neural_name,subtitle_num = 3)
}

Sympathetic_cholinergic_neuron

Sympathetic_noradrenergic_neuron

Peripheral_nervous_system_neuron_

Warning in DoHeatmap(object = acc_tpm, features = genes, slot = “counts”, : The following features were omitted as they were not found in the counts slot for the RNA assay: NOP53, SNHG29

Autonomic_neuron

Peripheral_neuron

Sensory_neuron

Warning in DoHeatmap(object = acc_tpm, features = genes, slot = “counts”, : The following features were omitted as they were not found in the counts slot for the RNA assay: NOP53

Adrenergic_neuron_tabula_sapiens

Warning in DoHeatmap(object = acc_tpm, features = genes, slot = “counts”, : The following features were omitted as they were not found in the counts slot for the RNA assay: NOP53

Peripheral_sensory_neuron

Parasympathetic_neuron

NA

5.2 WBC

wbc_cells = subset(acc_all, subset = cell.type == "WBC")
wbc_cells <- FindNeighbors(wbc_cells, dims = 1:10,verbose = F) %>%  FindClusters(resolution = 0.5) %>%  RunUMAP(dims = 1:10,verbose = F)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 33
Number of edges: 528

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.5572
Number of communities: 2
Elapsed time: 0 seconds
DimPlot(wbc_cells)

WBC devided into 2 clusters:

VlnPlot(object = wbc_cells,features = c("CD79A","PTPRC"))

5.3 WBC Neuronal signatures

acc_all$cluster_idents = acc_all@active.ident
data = FetchData(object = acc_all,vars = c("cluster_idents")) %>% mutate(cluster_idents = as.character(cluster_idents))
cluster_0_cells = subset(wbc_cells, subset = seurat_clusters == 0) %>% colnames()
cluster_1_cells = subset(wbc_cells, subset = seurat_clusters == 1) %>% colnames()

data[rownames(data) %in% cluster_0_cells,] ="WBC_cluster_0"
data[rownames(data) %in% cluster_1_cells,] ="WBC_cluster_1"
acc_all$cluster_idents = data

plt = VlnPlot(object = acc_all,features = colnames(neuronal_signatures),group.by = "cluster_idents")
plt[[1]] = plt[[1]]+ ylab("TPM")
plt[[4]] = plt[[4]]+ ylab("TPM")
plt[[7]] = plt[[7]]+ ylab("TPM")
plt

5.4 CD79A neuronal_signatures correlation

library(ggpubr)
for (neural_name in colnames(neuronal_signatures)) {
  wbc_cells = subset(acc_all, subset = cell.type == "WBC")
  data = FetchData(object = wbc_cells,vars = c(neural_name,"CD79A"))
  p = ggplot(data, aes_string(x=neural_name, y="CD79A")) + 
           geom_point()+
           geom_smooth(method=lm) +
           stat_cor()
  print_tab(p,title  = neural_name,subtitle_num = 3)
}

Sympathetic_cholinergic_neuron

geom_smooth() using formula ‘y ~ x’

Sympathetic_noradrenergic_neuron

geom_smooth() using formula ‘y ~ x’

Peripheral_nervous_system_neuron_

geom_smooth() using formula ‘y ~ x’

Autonomic_neuron

geom_smooth() using formula ‘y ~ x’

Peripheral_neuron

geom_smooth() using formula ‘y ~ x’

Sensory_neuron

geom_smooth() using formula ‘y ~ x’

Adrenergic_neuron_tabula_sapiens

geom_smooth() using formula ‘y ~ x’

Peripheral_sensory_neuron

geom_smooth() using formula ‘y ~ x’

Parasympathetic_neuron

geom_smooth() using formula ‘y ~ x’

NA

5.5 PTPRC neuronal_signatures correlation

library(ggpubr)
for (neural_name in colnames(neuronal_signatures)) {
  wbc_cells = subset(acc_all, subset = cell.type == "WBC")
  data = FetchData(object = wbc_cells,vars = c(neural_name,"PTPRC"))
  p = ggplot(data, aes_string(x=neural_name, y="PTPRC")) + 
    geom_point()+
    geom_smooth(method=lm) +
    stat_cor()
  print_tab(p,title  = neural_name,subtitle_num = 3)
}

Sympathetic_cholinergic_neuron

geom_smooth() using formula ‘y ~ x’

Sympathetic_noradrenergic_neuron

geom_smooth() using formula ‘y ~ x’

Peripheral_nervous_system_neuron_

geom_smooth() using formula ‘y ~ x’

Autonomic_neuron

geom_smooth() using formula ‘y ~ x’

Peripheral_neuron

geom_smooth() using formula ‘y ~ x’

Sensory_neuron

geom_smooth() using formula ‘y ~ x’

Adrenergic_neuron_tabula_sapiens

geom_smooth() using formula ‘y ~ x’

Peripheral_sensory_neuron

geom_smooth() using formula ‘y ~ x’

Parasympathetic_neuron

geom_smooth() using formula ‘y ~ x’

NA

5.6 PTPRC neuronal_signatures correlation no RP

library(ggpubr)
for (neural_name in names(neuronal_signatures_no_RP)) {
  wbc_cells = subset(acc_all, subset = cell.type == "WBC")
  data = FetchData(object = wbc_cells,vars = c(neural_name,"PTPRC"))
  p = ggplot(data, aes_string(x=neural_name, y="PTPRC")) + 
           geom_point()+
           geom_smooth(method=lm) +
           stat_cor()
  print_tab(p,title  = neural_name,subtitle_num = 3)
}

Sympathetic_cholinergic_neuron_noRP

geom_smooth() using formula ‘y ~ x’

Sympathetic_noradrenergic_neuron_noRP

geom_smooth() using formula ‘y ~ x’

5.6.1 Peripheral_nervous_system_neuron__noRP {.unnumbered }

geom_smooth() using formula ‘y ~ x’

Autonomic_neuron_noRP

geom_smooth() using formula ‘y ~ x’

Peripheral_neuron_noRP

geom_smooth() using formula ‘y ~ x’

Sensory_neuron_noRP

geom_smooth() using formula ‘y ~ x’

Adrenergic_neuron_tabula_sapiens_noRP

geom_smooth() using formula ‘y ~ x’

Peripheral_sensory_neuron_noRP

geom_smooth() using formula ‘y ~ x’

Parasympathetic_neuron_noRP

geom_smooth() using formula ‘y ~ x’

NA

FeaturePlot(object = wbc_cells,features = c("PTPRC", colnames(neuronal_signatures)[1:5]))

FeaturePlot(object = wbc_cells,features = c("PTPRC", colnames(neuronal_signatures)[6:9]))

7 Neuronal pathways in ACC cancer cells

7.1 dim reduction

acc_cancer <- RunPCA(acc_cancer, features = VariableFeatures(object = acc_cancer),verbose = F)
ElbowPlot(acc_cancer)

acc_cancer <- FindNeighbors(acc_cancer, dims = 1:10,verbose = F) %>%  FindClusters(resolution = 0.5) %>%  RunUMAP(dims = 1:10,verbose = F)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 951
Number of edges: 28888

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8456
Number of communities: 7
Elapsed time: 0 seconds
DimPlot(acc_cancer,group.by = "patient.ident")

for (pathway_name in names(neuronal_pathways)) {
  genes = neuronal_pathways[[pathway_name]]
  pathways_scores = FetchData(object = acc_cancer,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_cancer  %<>% AddMetaData(metadata = pathways_scores$score,col.name = pathway_name)
}
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: ADORA3
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: ADORA3
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: ASCL1, PHOX2B
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: ASCL1, PHOX2B
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: ARX, HOXB1, ASCL1, PRLH, PHOX2B, ISX
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: HOXB1, PHOX2B
Warning in FetchData.Seurat(object = acc_cancer, vars = genes, slot = "data") :
  The following requested variables were not found: DRD3, MIR1-1, MIR133A1

7.2 Scores UMAP


plt = FeaturePlot(object = acc_cancer,features = names(neuronal_pathways))
for (i in 1:(length(plt$patches$plots)+1)) {
  plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=10.5))+ labs(color='TPM')
}
print_tab(plt,title = "UMAP" ,subtitle_num = 3)

UMAP

plt = FeaturePlot(object = acc_cancer,features = names(neuronal_pathways),max.cutoff = 50)
for (i in 1:(length(plt$patches$plots)+1)) {
  plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=10.5))+ labs(color='TPM')
}
print_tab(plt,title = "UMAP max=50" ,subtitle_num = 3)

UMAP max=50

plt = FeaturePlot(object = acc_cancer,features = names(neuronal_pathways),max.cutoff = 250)
for (i in 1:(length(plt$patches$plots)+1)) {
  plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=10.5))+ labs(color='TPM')
}
print_tab(plt,title = "UMAP max=250" ,subtitle_num = 3)

UMAP max=250

plt = FeaturePlot(object = acc_cancer,features = names(neuronal_pathways))
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 = "UMAP rainbow" ,subtitle_num = 3)

UMAP rainbow

NA

7.3 Scores violin

 plt = VlnPlot(object = acc_cancer,features = names(neuronal_pathways),group.by = "patient.ident")+theme(plot.title = element_text(size = 3))
 
for (i in 1:(length(plt$patches$plots)+1)) {
  plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=9.5))
  if (i %in% c(1,4,7)) {
    plt[[i]] = plt[[i]]+ylab("TPM")
  }
}
print(plt)

8 ACC2 DEG

acc_cancer_pri = SetIdent(object = acc_cancer_pri,value = "patient.ident")
markers = FindMarkers(object = acc_cancer_pri,ident.1 = "ACC2",features = VariableFeatures(acc_cancer_pri),densify = T)
volcano_plot(de_genes = markers,max_names = 10,title = "",ident1 = "ACC2",ident2 = "PNI patients",show_graph = F,log2fc_cutoff = 1)

8.1 GSEA- canonical pathways

up = up in ACC2

library(hypeR)
genesets <- msigdb_download("Homo sapiens",category="H") %>% append( msigdb_download("Homo sapiens",category="C2",subcategory = "CP"))
all_genes = markers  %>%  arrange(desc(avg_log2FC)) %>% select("avg_log2FC") 
ranked_list   <- setNames(all_genes$avg_log2FC, rownames(all_genes))
hyp_obj <- hypeR_fgsea(signature = ranked_list,genesets =  genesets,up_only = F)
hyp_dots(hyp_obj)
$up

$dn

8.2 GSEA- GO BP

genesets <- msigdb_download("Homo sapiens",category="H") %>% append( msigdb_download("Homo sapiens",category="C5",subcategory = "GO:BP"))
all_genes = markers  %>%  arrange(desc(avg_log2FC)) %>% select("avg_log2FC") 
ranked_list   <- setNames(all_genes$avg_log2FC, rownames(all_genes))
hyp_obj <- hypeR_fgsea(signature = ranked_list,genesets =  genesets,up_only = F)
Warning in fgsea::fgseaMultilevel(stats = signature, pathways = gsets.obj$genesets,  :
  For some of the pathways the P-values were likely overestimated. For such pathways log2err is set to NA.
hyp_dots(hyp_obj)
$up

$dn

9 Neuronal pathways in ACC primary cancer cells

lum_score = FetchData(acc_cancer_pri,"luminal_over_myo")
lum_score  %<>% mutate (lum_or_myo = case_when(
         luminal_over_myo > 1 ~ "luminal",
         luminal_over_myo < (-1) ~ "myo",
         TRUE ~ "unknown"))
acc_cancer_pri  %<>% AddMetaData(metadata = lum_score$lum_or_myo,col.name = "lum_or_myo")
for (pathway_name in names(neuronal_pathways)) {
  genes = neuronal_pathways[[pathway_name]]
 pathways_scores = FetchData(object = acc_cancer_pri,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_cancer_pri  %<>% AddMetaData(metadata = pathways_scores$score,col.name = pathway_name)
}
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: ADORA3
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: ADORA3
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: ASCL1, PHOX2B
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: ASCL1, PHOX2B
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: ARX, HOXB1, ASCL1, PRLH, PHOX2B, ISX
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: HOXB1, PHOX2B
Warning in FetchData.Seurat(object = acc_cancer_pri, vars = genes, slot = "data") :
  The following requested variables were not found: DRD3, MIR1-1, MIR133A1
plt = FeaturePlot(object = acc_cancer_pri,features =  names(neuronal_pathways))

for (i in 1:(length(plt$patches$plots)+1)) {
  plt[[i]] = plt[[i]] + theme(plot.title = element_text(size=10.5))+ labs(color='TPM') 
}
print(plt)

10 Lum vs Myo

library(ggpubr)
for (pathway in names(neuronal_pathways)) {
  data = FetchData(object = acc_cancer_pri,vars = c("lum_or_myo",pathway)) %>% filter(lum_or_myo != "unknown")
  p = ggboxplot(data, x = "lum_or_myo", y =pathway,
                palette = "jco",
                add = "jitter")+ 
    stat_compare_means(method = "wilcox.test",comparisons = list(c("luminal","myo")))+ stat_summary(fun.data = function(x) data.frame(y=max(x)*1.2, label = paste("Mean=",round(mean(x),digits = 2))), geom="text") +ylab("TPM")+ggtitle(pathway)
  print_tab(p,title = pathway)
}

GOBP_NOREPINEPHRINE_SECRETION

GOBP_NOREPINEPHRINE_TRANSPORT

GOBP_NORADRENERGIC_NEURON_DEVELOPMENT

GOBP_NORADRENERGIC_NEURON_DIFFERENTIATION

GOBP_AUTONOMIC_NERVOUS_SYSTEM_DEVELOPMENT

GOBP_PARASYMPATHETIC_NERVOUS_SYSTEM_DEVELOPMENT

GOBP_ADRENERGIC_RECEPTOR_SIGNALING_PATHWAY

GOMF_BETA_2_ADRENERGIC_RECEPTOR_BINDING

NA

LS0tCnRpdGxlOiAnYHIgcnN0dWRpb2FwaTo6Z2V0U291cmNlRWRpdG9yQ29udGV4dCgpJHBhdGggJT4lIGJhc2VuYW1lKCkgJT4lIGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLHJlcGxhY2VtZW50ID0gIiIpYCcgCmF1dGhvcjogIkF2aXNoYWkgV2l6ZWwiCmRhdGU6ICdgciBTeXMudGltZSgpYCcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19jb2xsYXBzZTogeWVzCiAgICB0b2NfZmxvYXQ6IAogICAgICBjb2xsYXBzZWQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgdG9jX2RlcHRoOiA0Ci0tLQoKIyBGdW5jdGlvbnMKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoc3RyaW5naSkKc291cmNlX2Zyb21fZ2l0aHViKHJlcG9zaXRveSA9ICJERUdfZnVuY3Rpb25zIix2ZXJzaW9uID0gIjAuMi40NyIpCnNvdXJjZV9mcm9tX2dpdGh1YihyZXBvc2l0b3kgPSAiY05NRl9mdW5jdGlvbnMiLHZlcnNpb24gPSAiMC40LjAiLHNjcmlwdF9uYW1lID0gImNubWZfZnVuY3Rpb25zX1YzLlIiKQpzb3VyY2VfZnJvbV9naXRodWIocmVwb3NpdG95ID0gInNjX2dlbmVyYWxfZnVuY3Rpb25zIix2ZXJzaW9uID0gIjAuMS4yOCIsc2NyaXB0X25hbWUgPSAiZnVuY3Rpb25zLlIiKQpgYGAKCiMgRGF0YQoKYGBge3J9CmxpYnJhcnkoInJlYWR4bCIpCmFjY19hbGwgPSByZWFkUkRTKGZpbGUgPSAiLi9EYXRhL2FjY190cG1fbkNvdW50X21pdG9fbm8xNDZfMTVrX2FsbGRhdGEucmRzIikKYWNjX2NhbmNlcl9wcmkgPSByZWFkUkRTKGZpbGUgPSAiLi9EYXRhL2FjY19jYW5jZXJfbm8xNDZfcHJpbWFyeW9ubHkxNWtfY2FuY2VyY2VsbHMucmRzIikKYWNjX2NhbmNlciA9IHJlYWRSRFMoZmlsZSA9ICIuL0RhdGEvYWNjX3RwbV9uQ291bnRfbWl0b19ubzE0Nl8xNWtfY2FuY2VyY2VsbHMucmRzIikKCgpuZXVyb25hbF9zaWduYXR1cmVzIDwtIHJlYWRfZXhjZWwoIi4vRGF0YS9OZXVyb25hbCBTaWduYXR1cmVzLnhsc3giLGNvbF9uYW1lcyA9RikKbmV1cm9uYWxfc2lnbmF0dXJlcyAgJTw+JSAgdCgpICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGphbml0b3I6OnJvd190b19uYW1lcygxKSAlPiUgIGZpbHRlcighcm93X251bWJlcigpID09IDEpCnJvd25hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpIDwtIE5VTEwKY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykgICAlPD4lICBnc3ViKHJlcGxhY2VtZW50ID0gIiIsIHBhdHRlcm4gPSAiX1xcZC4qIikgI3JlbW92ZSBhbnkgX251bWJlcnMKY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykgICAlPD4lICBnc3ViKHJlcGxhY2VtZW50ID0gIiIsIHBhdHRlcm4gPSAiXFwoLioiKSAjcmVuYW1lICIoIiB0byB0aGUgZW5kCmNvbG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpICAgJTw+JSAgZ3N1YihyZXBsYWNlbWVudCA9ICJfIiwgcGF0dGVybiA9ICIgIikgI3JlbmFtZSBhbGwgc3BhY2VzCgpuZXVyb25hbF9wYXRod2F5cyA8LSByZWFkX2V4Y2VsKCIuL0RhdGEvUGF0aHdheSBhbmFseXNpcyBHZW5lIHNldHMueGxzeCIsY29sX25hbWVzID1GKQpuZXVyb25hbF9wYXRod2F5cyAgJTw+JSAgdCgpICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIGphbml0b3I6OnJvd190b19uYW1lcygxKSAlPiUgIGZpbHRlcighcm93X251bWJlcigpID09IDEpICAlPiUgIGFzLmxpc3QoKSAKbmV1cm9uYWxfcGF0aHdheXMgPSBsYXBwbHkobmV1cm9uYWxfcGF0aHdheXMsIG5hLm9taXQpCm5ldXJvbmFsX3BhdGh3YXlzID0gbGFwcGx5KG5ldXJvbmFsX3BhdGh3YXlzLCBhcy5jaGFyYWN0ZXIpCgpgYGAKCiMgQUNDIGFsbCBjZWxscyBVTUFQCgpgYGB7cn0KRGltUGxvdChhY2NfYWxsKQpgYGAKCiMgTmV1cm9uYWwgc2lnbmF0dXJlcwoKYGBge3IgcmVzdWx0cz0nYXNpcyd9CmZvciAobmV1cmFsX25hbWUgaW4gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykpIHsKICBnZW5lcyA9IG5ldXJvbmFsX3NpZ25hdHVyZXNbLG5ldXJhbF9uYW1lLGRyb3A9VF0KICAjIEFzc3VtaW5nIGRmIGlzIHlvdXIgZGF0YSBmcmFtZQoKICAKICBwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2FsbCx2YXJzID0gZ2VuZXMsc2xvdCA9ICJkYXRhIikgJT4lIAogICAgbXV0YXRlX2FsbCh+IDJeLiklPiUgbXV0YXRlX2FsbCh+IC4tMSkgJT4lICAjY292ZXJ0IGxvZyhUUE0rMSkgdG8gVFBNCiAgICByb3d3aXNlKCkgJT4lIG11dGF0ZShzY29yZSA9IG1lYW4oY19hY3Jvc3MoZXZlcnl0aGluZygpKSkpICNtZWFuCiAgYWNjX2FsbCAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9IG5ldXJhbF9uYW1lKQp9CmBgYAoKYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpwbHQgPSBWbG5QbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSBjb2xuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzKSkKcGx0W1sxXV0gPSBwbHRbWzFdXSsgeWxhYigiVFBNIikKcGx0W1s0XV0gPSBwbHRbWzRdXSsgeWxhYigiVFBNIikKcGx0W1s3XV0gPSBwbHRbWzddXSsgeWxhYigiVFBNIikKcGx0CmBgYAoKIyBOZXVyb25hbCBzaWduYXR1cmVzIE5PIFJQIGdlbmVzCgpgYGB7ciBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTJ9Cm5ldXJvbmFsX3NpZ25hdHVyZXNfbm9fUlAgPSBsYXBwbHkobmV1cm9uYWxfc2lnbmF0dXJlcyAlPiUgYXMubGlzdCgpLCAgZnVuY3Rpb24oeCkge3hbIXN0YXJ0c1dpdGgoeCA9IHgscHJlZml4ID0gIlJQIildfSkKbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlc19ub19SUCkgPSAgcGFzdGUwKG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXNfbm9fUlApLCJfbm9SUCIpCmZvciAobmV1cmFsX25hbWUgaW4gbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlc19ub19SUCkpIHsKICBnZW5lcyA9IG5ldXJvbmFsX3NpZ25hdHVyZXNfbm9fUlBbW25ldXJhbF9uYW1lXV0KICAjIEFzc3VtaW5nIGRmIGlzIHlvdXIgZGF0YSBmcmFtZQoKICBwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2FsbCx2YXJzID0gZ2VuZXMsc2xvdCA9ICJkYXRhIikgJT4lIAogICAgbXV0YXRlX2FsbCh+IDJeLiklPiUgbXV0YXRlX2FsbCh+IC4tMSkgJT4lICAjY292ZXJ0IGxvZyhUUE0rMSkgdG8gVFBNCiAgICByb3d3aXNlKCkgJT4lIG11dGF0ZShzY29yZSA9IG1lYW4oY19hY3Jvc3MoZXZlcnl0aGluZygpKSkpICNtZWFuCiAgYWNjX2FsbCAgJTw+JSBBZGRNZXRhRGF0YShtZXRhZGF0YSA9IHBhdGh3YXlzX3Njb3JlcyRzY29yZSxjb2wubmFtZSA9IG5ldXJhbF9uYW1lKQp9CgpwbHQgPSBWbG5QbG90KG9iamVjdCA9IGFjY19hbGwsZmVhdHVyZXMgPSBuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzX25vX1JQKSkKcGx0W1sxXV0gPSBwbHRbWzFdXSsgeWxhYigiVFBNIikKcGx0W1s0XV0gPSBwbHRbWzRdXSsgeWxhYigiVFBNIikKcGx0W1s3XV0gPSBwbHRbWzddXSsgeWxhYigiVFBNIikKcGx0CmBgYAoKIyMgTmV1cm9uYWwgc2lnbmF0dXJlcyBleHByZXNzaW9uIHsudGFic2V0fQoKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgcmVzdWx0cz0nYXNpcyd9CmNvdW50LmRhdGEgPC0gR2V0QXNzYXlEYXRhKG9iamVjdCA9IGFjY19hbGxbWyJSTkEiXV0sIHNsb3QgPSAiZGF0YSIpCmNvdW50LmRhdGEgPC0gYXMubWF0cml4KHggPSAoMioqY291bnQuZGF0YSkgLSAxKQphY2NfdHBtIDwtIFNldEFzc2F5RGF0YSgKICAgIG9iamVjdCA9IGFjY19hbGwsCiAgICBzbG90ID0gImNvdW50cyIsCiAgICBuZXcuZGF0YSA9IGNvdW50LmRhdGEsCiAgICBhc3NheSA9ICJSTkEiCikKCmZvciAobmV1cmFsX25hbWUgaW4gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcykpIHsKICBnZW5lcyA9IG5ldXJvbmFsX3NpZ25hdHVyZXNbLG5ldXJhbF9uYW1lLGRyb3A9VF0KICAjIEFzc3VtaW5nIGRmIGlzIHlvdXIgZGF0YSBmcmFtZQogIHByaW50X3RhYigKICAgIERvSGVhdG1hcChvYmplY3QgPSBhY2NfdHBtLGZlYXR1cmVzID0gZ2VuZXMsc2xvdCA9ICJjb3VudHMiLGNvbWJpbmUgPSBULGRpc3AubWF4ID0gNTAwMCkrIGxhYnMoZmlsbCA9ICJUUE0iKSAKICAsdGl0bGUgPSBuZXVyYWxfbmFtZSxzdWJ0aXRsZV9udW0gPSAzKQp9CmBgYAoKIyMgV0JDCgpgYGB7cn0Kd2JjX2NlbGxzID0gc3Vic2V0KGFjY19hbGwsIHN1YnNldCA9IGNlbGwudHlwZSA9PSAiV0JDIikKd2JjX2NlbGxzIDwtIEZpbmROZWlnaGJvcnMod2JjX2NlbGxzLCBkaW1zID0gMToxMCx2ZXJib3NlID0gRikgJT4lICBGaW5kQ2x1c3RlcnMocmVzb2x1dGlvbiA9IDAuNSkgJT4lICBSdW5VTUFQKGRpbXMgPSAxOjEwLHZlcmJvc2UgPSBGKQoKRGltUGxvdCh3YmNfY2VsbHMpCmBgYAoKV0JDIGRldmlkZWQgaW50byAyIGNsdXN0ZXJzOgoKYGBge3J9ClZsblBsb3Qob2JqZWN0ID0gd2JjX2NlbGxzLGZlYXR1cmVzID0gYygiQ0Q3OUEiLCJQVFBSQyIpKQpgYGAKCiMjIFdCQyBOZXVyb25hbCBzaWduYXR1cmVzCgpgYGB7ciBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTN9CmFjY19hbGwkY2x1c3Rlcl9pZGVudHMgPSBhY2NfYWxsQGFjdGl2ZS5pZGVudApkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19hbGwsdmFycyA9IGMoImNsdXN0ZXJfaWRlbnRzIikpICU+JSBtdXRhdGUoY2x1c3Rlcl9pZGVudHMgPSBhcy5jaGFyYWN0ZXIoY2x1c3Rlcl9pZGVudHMpKQpjbHVzdGVyXzBfY2VsbHMgPSBzdWJzZXQod2JjX2NlbGxzLCBzdWJzZXQgPSBzZXVyYXRfY2x1c3RlcnMgPT0gMCkgJT4lIGNvbG5hbWVzKCkKY2x1c3Rlcl8xX2NlbGxzID0gc3Vic2V0KHdiY19jZWxscywgc3Vic2V0ID0gc2V1cmF0X2NsdXN0ZXJzID09IDEpICU+JSBjb2xuYW1lcygpCgpkYXRhW3Jvd25hbWVzKGRhdGEpICVpbiUgY2x1c3Rlcl8wX2NlbGxzLF0gPSJXQkNfY2x1c3Rlcl8wIgpkYXRhW3Jvd25hbWVzKGRhdGEpICVpbiUgY2x1c3Rlcl8xX2NlbGxzLF0gPSJXQkNfY2x1c3Rlcl8xIgphY2NfYWxsJGNsdXN0ZXJfaWRlbnRzID0gZGF0YQoKcGx0ID0gVmxuUGxvdChvYmplY3QgPSBhY2NfYWxsLGZlYXR1cmVzID0gY29sbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlcyksZ3JvdXAuYnkgPSAiY2x1c3Rlcl9pZGVudHMiKQpwbHRbWzFdXSA9IHBsdFtbMV1dKyB5bGFiKCJUUE0iKQpwbHRbWzRdXSA9IHBsdFtbNF1dKyB5bGFiKCJUUE0iKQpwbHRbWzddXSA9IHBsdFtbN11dKyB5bGFiKCJUUE0iKQpwbHQKYGBgCgojIyBDRDc5QSBuZXVyb25hbF9zaWduYXR1cmVzIGNvcnJlbGF0aW9uIHsudGFic2V0fQoKYGBge3IgcmVzdWx0cz0nYXNpcyd9CmxpYnJhcnkoZ2dwdWJyKQpmb3IgKG5ldXJhbF9uYW1lIGluIGNvbG5hbWVzKG5ldXJvbmFsX3NpZ25hdHVyZXMpKSB7CiAgd2JjX2NlbGxzID0gc3Vic2V0KGFjY19hbGwsIHN1YnNldCA9IGNlbGwudHlwZSA9PSAiV0JDIikKICBkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IHdiY19jZWxscyx2YXJzID0gYyhuZXVyYWxfbmFtZSwiQ0Q3OUEiKSkKICBwID0gZ2dwbG90KGRhdGEsIGFlc19zdHJpbmcoeD1uZXVyYWxfbmFtZSwgeT0iQ0Q3OUEiKSkgKyAKICAgICAgICAgICBnZW9tX3BvaW50KCkrCiAgICAgICAgICAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtKSArCiAgICAgICAgICAgc3RhdF9jb3IoKQogIHByaW50X3RhYihwLHRpdGxlICA9IG5ldXJhbF9uYW1lLHN1YnRpdGxlX251bSA9IDMpCn0KCmBgYAoKIyMgUFRQUkMgbmV1cm9uYWxfc2lnbmF0dXJlcyBjb3JyZWxhdGlvbiB7LnRhYnNldH0KCmBgYHtyIHJlc3VsdHM9J2FzaXMnfQpsaWJyYXJ5KGdncHVicikKZm9yIChuZXVyYWxfbmFtZSBpbiBjb2xuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzKSkgewogIHdiY19jZWxscyA9IHN1YnNldChhY2NfYWxsLCBzdWJzZXQgPSBjZWxsLnR5cGUgPT0gIldCQyIpCiAgZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSB3YmNfY2VsbHMsdmFycyA9IGMobmV1cmFsX25hbWUsIlBUUFJDIikpCiAgcCA9IGdncGxvdChkYXRhLCBhZXNfc3RyaW5nKHg9bmV1cmFsX25hbWUsIHk9IlBUUFJDIikpICsgCiAgICBnZW9tX3BvaW50KCkrCiAgICBnZW9tX3Ntb290aChtZXRob2Q9bG0pICsKICAgIHN0YXRfY29yKCkKICBwcmludF90YWIocCx0aXRsZSAgPSBuZXVyYWxfbmFtZSxzdWJ0aXRsZV9udW0gPSAzKQp9CgpgYGAKCiMjIFBUUFJDIG5ldXJvbmFsX3NpZ25hdHVyZXMgY29ycmVsYXRpb24gbm8gUlAgey50YWJzZXR9CgpgYGB7ciByZXN1bHRzPSdhc2lzJ30KbGlicmFyeShnZ3B1YnIpCmZvciAobmV1cmFsX25hbWUgaW4gbmFtZXMobmV1cm9uYWxfc2lnbmF0dXJlc19ub19SUCkpIHsKICB3YmNfY2VsbHMgPSBzdWJzZXQoYWNjX2FsbCwgc3Vic2V0ID0gY2VsbC50eXBlID09ICJXQkMiKQogIGRhdGEgPSBGZXRjaERhdGEob2JqZWN0ID0gd2JjX2NlbGxzLHZhcnMgPSBjKG5ldXJhbF9uYW1lLCJQVFBSQyIpKQogIHAgPSBnZ3Bsb3QoZGF0YSwgYWVzX3N0cmluZyh4PW5ldXJhbF9uYW1lLCB5PSJQVFBSQyIpKSArIAogICAgICAgICAgIGdlb21fcG9pbnQoKSsKICAgICAgICAgICBnZW9tX3Ntb290aChtZXRob2Q9bG0pICsKICAgICAgICAgICBzdGF0X2NvcigpCiAgcHJpbnRfdGFiKHAsdGl0bGUgID0gbmV1cmFsX25hbWUsc3VidGl0bGVfbnVtID0gMykKfQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRmVhdHVyZVBsb3Qob2JqZWN0ID0gd2JjX2NlbGxzLGZlYXR1cmVzID0gYygiUFRQUkMiLCBjb2xuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzKVsxOjVdKSkKRmVhdHVyZVBsb3Qob2JqZWN0ID0gd2JjX2NlbGxzLGZlYXR1cmVzID0gYygiUFRQUkMiLCBjb2xuYW1lcyhuZXVyb25hbF9zaWduYXR1cmVzKVs2OjldKSkKYGBgCgojIENTRjMKCltTaW5nbGUtY2VsbCBSTkEgc2VxdWVuY2luZyByZXZlYWxzIGludHJhdHVtb3JhbCBoZXRlcm9nZW5laXR5IGFuZCBwb3RlbnRpYWwgbWVjaGFuaXNtcyBvZiBtYWxpZ25hbnQgcHJvZ3Jlc3Npb24gaW4gcHJvc3RhdGUgY2FuY2VyIHdpdGggcGVyaW5ldXJhbCBpbnZhc2lvbl0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wbWMvYXJ0aWNsZXMvUE1DOTg3NTc5OS8pCgpgYGB7cn0KVmxuUGxvdChvYmplY3QgPSBhY2NfYWxsLGZlYXR1cmVzID0gIkNTRjMiLGdyb3VwLmJ5ID0gInBhdGllbnQuaWRlbnQiKSsgeWxhYigibG9nMiAoVFBNKzEpIikKYGBgCgojIE5ldXJvbmFsIHBhdGh3YXlzIGluIEFDQyBjYW5jZXIgY2VsbHMKCiMjIGRpbSByZWR1Y3Rpb24KCmBgYHtyfQphY2NfY2FuY2VyIDwtIFJ1blBDQShhY2NfY2FuY2VyLCBmZWF0dXJlcyA9IFZhcmlhYmxlRmVhdHVyZXMob2JqZWN0ID0gYWNjX2NhbmNlciksdmVyYm9zZSA9IEYpCkVsYm93UGxvdChhY2NfY2FuY2VyKQphY2NfY2FuY2VyIDwtIEZpbmROZWlnaGJvcnMoYWNjX2NhbmNlciwgZGltcyA9IDE6MTAsdmVyYm9zZSA9IEYpICU+JSAgRmluZENsdXN0ZXJzKHJlc29sdXRpb24gPSAwLjUpICU+JSAgUnVuVU1BUChkaW1zID0gMToxMCx2ZXJib3NlID0gRikKYGBgCgpgYGB7cn0KRGltUGxvdChhY2NfY2FuY2VyLGdyb3VwLmJ5ID0gInBhdGllbnQuaWRlbnQiKQpgYGAKCmBgYHtyfQpmb3IgKHBhdGh3YXlfbmFtZSBpbiBuYW1lcyhuZXVyb25hbF9wYXRod2F5cykpIHsKICBnZW5lcyA9IG5ldXJvbmFsX3BhdGh3YXlzW1twYXRod2F5X25hbWVdXQogIHBhdGh3YXlzX3Njb3JlcyA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FuY2VyLHZhcnMgPSBnZW5lcyxzbG90ID0gImRhdGEiKSAlPiUgCiAgICBtdXRhdGVfYWxsKH4gMl4uKSU+JSBtdXRhdGVfYWxsKH4gLi0xKSAlPiUgICNjb3ZlcnQgbG9nKFRQTSsxKSB0byBUUE0KICAgIHJvd3dpc2UoKSAlPiUgbXV0YXRlKHNjb3JlID0gbWVhbihjX2Fjcm9zcyhldmVyeXRoaW5nKCkpKSkgI21lYW4KICBhY2NfY2FuY2VyICAlPD4lIEFkZE1ldGFEYXRhKG1ldGFkYXRhID0gcGF0aHdheXNfc2NvcmVzJHNjb3JlLGNvbC5uYW1lID0gcGF0aHdheV9uYW1lKQp9CmBgYAoKIyMgU2NvcmVzIFVNQVAgey50YWJzZXR9CgpgYGB7ciBmaWcuaGVpZ2h0PTEzLCBmaWcud2lkdGg9MTMsIHJlc3VsdHM9J2FzaXMnfQoKcGx0ID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2NhbmNlcixmZWF0dXJlcyA9IG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSkKZm9yIChpIGluIDE6KGxlbmd0aChwbHQkcGF0Y2hlcyRwbG90cykrMSkpIHsKICBwbHRbW2ldXSA9IHBsdFtbaV1dICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEwLjUpKSsgbGFicyhjb2xvcj0nVFBNJykKfQpwcmludF90YWIocGx0LHRpdGxlID0gIlVNQVAiICxzdWJ0aXRsZV9udW0gPSAzKQoKcGx0ID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2NhbmNlcixmZWF0dXJlcyA9IG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSxtYXguY3V0b2ZmID0gNTApCmZvciAoaSBpbiAxOihsZW5ndGgocGx0JHBhdGNoZXMkcGxvdHMpKzEpKSB7CiAgcGx0W1tpXV0gPSBwbHRbW2ldXSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMC41KSkrIGxhYnMoY29sb3I9J1RQTScpCn0KcHJpbnRfdGFiKHBsdCx0aXRsZSA9ICJVTUFQIG1heD01MCIgLHN1YnRpdGxlX251bSA9IDMpCgpwbHQgPSBGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfY2FuY2VyLGZlYXR1cmVzID0gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpLG1heC5jdXRvZmYgPSAyNTApCmZvciAoaSBpbiAxOihsZW5ndGgocGx0JHBhdGNoZXMkcGxvdHMpKzEpKSB7CiAgcGx0W1tpXV0gPSBwbHRbW2ldXSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMC41KSkrIGxhYnMoY29sb3I9J1RQTScpCn0KcHJpbnRfdGFiKHBsdCx0aXRsZSA9ICJVTUFQIG1heD0yNTAiICxzdWJ0aXRsZV9udW0gPSAzKQoKcGx0ID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2NhbmNlcixmZWF0dXJlcyA9IG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSkKZm9yIChpIGluIDE6KGxlbmd0aChwbHQkcGF0Y2hlcyRwbG90cykrMSkpIHsKICBwbHRbW2ldXSA9IHBsdFtbaV1dICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEwLjUpKSsgbGFicyhjb2xvcj0nVFBNJykgKyBzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3VycyA9IHJhaW5ib3coNSkpCn0KcHJpbnRfdGFiKHBsdCx0aXRsZSA9ICJVTUFQIHJhaW5ib3ciICxzdWJ0aXRsZV9udW0gPSAzKQoKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTEzLCBmaWcud2lkdGg9MTMsIHJlc3VsdHM9J2FzaXMnfQoKYGBgCgojIyBTY29yZXMgdmlvbGluCgpgYGB7ciBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTJ9CiBwbHQgPSBWbG5QbG90KG9iamVjdCA9IGFjY19jYW5jZXIsZmVhdHVyZXMgPSBuYW1lcyhuZXVyb25hbF9wYXRod2F5cyksZ3JvdXAuYnkgPSAicGF0aWVudC5pZGVudCIpK3RoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDMpKQogCmZvciAoaSBpbiAxOihsZW5ndGgocGx0JHBhdGNoZXMkcGxvdHMpKzEpKSB7CiAgcGx0W1tpXV0gPSBwbHRbW2ldXSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT05LjUpKQogIGlmIChpICVpbiUgYygxLDQsNykpIHsKICAgIHBsdFtbaV1dID0gcGx0W1tpXV0reWxhYigiVFBNIikKICB9Cn0KcHJpbnQocGx0KQpgYGAKCiMgQUNDMiBERUcKCmBgYHtyfQphY2NfY2FuY2VyX3ByaSA9IFNldElkZW50KG9iamVjdCA9IGFjY19jYW5jZXJfcHJpLHZhbHVlID0gInBhdGllbnQuaWRlbnQiKQptYXJrZXJzID0gRmluZE1hcmtlcnMob2JqZWN0ID0gYWNjX2NhbmNlcl9wcmksaWRlbnQuMSA9ICJBQ0MyIixmZWF0dXJlcyA9IFZhcmlhYmxlRmVhdHVyZXMoYWNjX2NhbmNlcl9wcmkpLGRlbnNpZnkgPSBUKQoKYGBgCgpgYGB7cn0Kdm9sY2Fub19wbG90KGRlX2dlbmVzID0gbWFya2VycyxtYXhfbmFtZXMgPSAxMCx0aXRsZSA9ICIiLGlkZW50MSA9ICJBQ0MyIixpZGVudDIgPSAiUE5JIHBhdGllbnRzIixzaG93X2dyYXBoID0gRixsb2cyZmNfY3V0b2ZmID0gMSkKYGBgCgojIyBHU0VBLSBjYW5vbmljYWwgcGF0aHdheXMKCnVwID0gdXAgaW4gQUNDMgoKYGBge3J9CmxpYnJhcnkoaHlwZVIpCmdlbmVzZXRzIDwtIG1zaWdkYl9kb3dubG9hZCgiSG9tbyBzYXBpZW5zIixjYXRlZ29yeT0iSCIpICU+JSBhcHBlbmQoIG1zaWdkYl9kb3dubG9hZCgiSG9tbyBzYXBpZW5zIixjYXRlZ29yeT0iQzIiLHN1YmNhdGVnb3J5ID0gIkNQIikpCmFsbF9nZW5lcyA9IG1hcmtlcnMgICU+JSAgYXJyYW5nZShkZXNjKGF2Z19sb2cyRkMpKSAlPiUgc2VsZWN0KCJhdmdfbG9nMkZDIikgCnJhbmtlZF9saXN0ICAgPC0gc2V0TmFtZXMoYWxsX2dlbmVzJGF2Z19sb2cyRkMsIHJvd25hbWVzKGFsbF9nZW5lcykpCmh5cF9vYmogPC0gaHlwZVJfZmdzZWEoc2lnbmF0dXJlID0gcmFua2VkX2xpc3QsZ2VuZXNldHMgPSAgZ2VuZXNldHMsdXBfb25seSA9IEYpCmh5cF9kb3RzKGh5cF9vYmopCmBgYAoKIyMgR1NFQS0gR08gQlAKCmBgYHtyfQpnZW5lc2V0cyA8LSBtc2lnZGJfZG93bmxvYWQoIkhvbW8gc2FwaWVucyIsY2F0ZWdvcnk9IkgiKSAlPiUgYXBwZW5kKCBtc2lnZGJfZG93bmxvYWQoIkhvbW8gc2FwaWVucyIsY2F0ZWdvcnk9IkM1IixzdWJjYXRlZ29yeSA9ICJHTzpCUCIpKQphbGxfZ2VuZXMgPSBtYXJrZXJzICAlPiUgIGFycmFuZ2UoZGVzYyhhdmdfbG9nMkZDKSkgJT4lIHNlbGVjdCgiYXZnX2xvZzJGQyIpIApyYW5rZWRfbGlzdCAgIDwtIHNldE5hbWVzKGFsbF9nZW5lcyRhdmdfbG9nMkZDLCByb3duYW1lcyhhbGxfZ2VuZXMpKQpoeXBfb2JqIDwtIGh5cGVSX2Znc2VhKHNpZ25hdHVyZSA9IHJhbmtlZF9saXN0LGdlbmVzZXRzID0gIGdlbmVzZXRzLHVwX29ubHkgPSBGKQpoeXBfZG90cyhoeXBfb2JqKQpgYGAKCmBgYHs9aHRtbH0KPHNjcmlwdCBzcmM9Imh0dHBzOi8vaHlwb3RoZXMuaXMvZW1iZWQuanMiIGFzeW5jPjwvc2NyaXB0PgpgYGAKIyBOZXVyb25hbCBwYXRod2F5cyBpbiBBQ0MgcHJpbWFyeSBjYW5jZXIgY2VsbHMKCmBgYHtyfQpsdW1fc2NvcmUgPSBGZXRjaERhdGEoYWNjX2NhbmNlcl9wcmksImx1bWluYWxfb3Zlcl9teW8iKQpsdW1fc2NvcmUgICU8PiUgbXV0YXRlIChsdW1fb3JfbXlvID0gY2FzZV93aGVuKAogICAgICAgICBsdW1pbmFsX292ZXJfbXlvID4gMSB+ICJsdW1pbmFsIiwKICAgICAgICAgbHVtaW5hbF9vdmVyX215byA8ICgtMSkgfiAibXlvIiwKICAgICAgICAgVFJVRSB+ICJ1bmtub3duIikpCmFjY19jYW5jZXJfcHJpICAlPD4lIEFkZE1ldGFEYXRhKG1ldGFkYXRhID0gbHVtX3Njb3JlJGx1bV9vcl9teW8sY29sLm5hbWUgPSAibHVtX29yX215byIpCmBgYAoKYGBge3J9CmZvciAocGF0aHdheV9uYW1lIGluIG5hbWVzKG5ldXJvbmFsX3BhdGh3YXlzKSkgewogIGdlbmVzID0gbmV1cm9uYWxfcGF0aHdheXNbW3BhdGh3YXlfbmFtZV1dCiBwYXRod2F5c19zY29yZXMgPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcl9wcmksdmFycyA9IGdlbmVzLHNsb3QgPSAiZGF0YSIpICU+JSAKICAgIG11dGF0ZV9hbGwofiAyXi4pJT4lIG11dGF0ZV9hbGwofiAuLTEpICU+JSAgI2NvdmVydCBsb2coVFBNKzEpIHRvIFRQTQogICAgcm93d2lzZSgpICU+JSBtdXRhdGUoc2NvcmUgPSBtZWFuKGNfYWNyb3NzKGV2ZXJ5dGhpbmcoKSkpKSAjbWVhbgogIGFjY19jYW5jZXJfcHJpICAlPD4lIEFkZE1ldGFEYXRhKG1ldGFkYXRhID0gcGF0aHdheXNfc2NvcmVzJHNjb3JlLGNvbC5uYW1lID0gcGF0aHdheV9uYW1lKQp9CmBgYAoKYGBge3IgZmlnLmhlaWdodD0xMywgZmlnLndpZHRoPTEzfQpwbHQgPSBGZWF0dXJlUGxvdChvYmplY3QgPSBhY2NfY2FuY2VyX3ByaSxmZWF0dXJlcyA9ICBuYW1lcyhuZXVyb25hbF9wYXRod2F5cykpCgpmb3IgKGkgaW4gMToobGVuZ3RoKHBsdCRwYXRjaGVzJHBsb3RzKSsxKSkgewogIHBsdFtbaV1dID0gcGx0W1tpXV0gKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTAuNSkpKyBsYWJzKGNvbG9yPSdUUE0nKSAKfQpwcmludChwbHQpCmBgYAoKIyBMdW0gdnMgTXlvIHsudGFic2V0fQoKYGBge3IgcmVzdWx0cz0nYXNpcyd9CmxpYnJhcnkoZ2dwdWJyKQpmb3IgKHBhdGh3YXkgaW4gbmFtZXMobmV1cm9uYWxfcGF0aHdheXMpKSB7CiAgZGF0YSA9IEZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FuY2VyX3ByaSx2YXJzID0gYygibHVtX29yX215byIscGF0aHdheSkpICU+JSBmaWx0ZXIobHVtX29yX215byAhPSAidW5rbm93biIpCiAgcCA9IGdnYm94cGxvdChkYXRhLCB4ID0gImx1bV9vcl9teW8iLCB5ID1wYXRod2F5LAogICAgICAgICAgICAgICAgcGFsZXR0ZSA9ICJqY28iLAogICAgICAgICAgICAgICAgYWRkID0gImppdHRlciIpKyAKICAgIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLGNvbXBhcmlzb25zID0gbGlzdChjKCJsdW1pbmFsIiwibXlvIikpKSsgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gZnVuY3Rpb24oeCkgZGF0YS5mcmFtZSh5PW1heCh4KSoxLjIsIGxhYmVsID0gcGFzdGUoIk1lYW49Iixyb3VuZChtZWFuKHgpLGRpZ2l0cyA9IDIpKSksIGdlb209InRleHQiKSAreWxhYigiVFBNIikrZ2d0aXRsZShwYXRod2F5KQogIHByaW50X3RhYihwLHRpdGxlID0gcGF0aHdheSkKfQoKYGBgCg==