Functions
Data
CC data
cc_data = Read10X(data.dir = "/sci/labs/yotamd/lab_share/avishai.wizel/R_projects/HMSC/Data/cervical_cancer_data/Tumor/")
cc_cancer = CreateSeuratObject(counts = cc_data, min.cells = 3, min.features = 200)
cc_cancer[["percent.mt"]] <- PercentageFeatureSet(cc_cancer, pattern = "^MT-")
cc_cancer <- subset(cc_cancer, subset = percent.mt < 10)
cc_cancer <- NormalizeData(cc_cancer)
cc_cancer <- FindVariableFeatures(cc_cancer,nfeatures = 2000)
cc_cancer <- ScaleData(cc_cancer,features = VariableFeatures(cc_cancer),vars.to.regress = c("percent.mt","nCount_RNA"))
cc_cancer %<>% RunPCA( features = VariableFeatures(object = cc_cancer))
ElbowPlot(cc_cancer,ndims = 50)


HPV
hpv_bam = read_tsv(file = "./Data/cervical_cancer_data/hpv_bam.tsv",col_select = 1,col_names = F)
Rows: 29481 Columns: 1
── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (1): X1
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
reads_per_cell = str_extract(pattern = "CR:Z:.*$",string = hpv_bam$X1) %>% str_sub( start = 6) %>% table() %>% as.data.frame() %>% column_to_rownames(".")
rownames(reads_per_cell) = paste0(rownames(reads_per_cell),"-1")
reads_per_cell
zero_cells = colnames(cc_cancer)[!colnames(cc_cancer) %in% rownames(reads_per_cell)]
zero_cells_freq = data.frame(row.names = zero_cells,Freq = rep(0,length(zero_cells)))
reads_per_cell_all_cells = rbind(reads_per_cell,zero_cells_freq)
cc_cancer %<>% AddMetaData(metadata = reads_per_cell_all_cells,col.name = "HPV_reads")
hpv_reads = FetchData(object = cc_cancer,vars = "HPV_reads")
data = hpv_reads %>% mutate("0 reads" = if_else(condition = HPV_reads == 0,true = 1,false = 0))
data = data %>% mutate("1 reads" = if_else(condition = HPV_reads == 1,true = 1,false = 0))
data = data %>% mutate("2 reads" = if_else(condition = HPV_reads == 2,true = 1,false = 0))
data = data %>% mutate("3-23 reads" = if_else(condition = HPV_reads >=3 &HPV_reads <24,true = 1,false = 0))
data = data %>% mutate("24+ reads" = if_else(condition = HPV_reads >=24,true = 1,false = 0))
data = colSums(data[,2:ncol(data)]) %>% as.data.frame()
names(data)[1] = "count"
data = rownames_to_column(data,var = "bin")
ggplot(data=data, aes(x=factor(bin,levels = c("0 reads","1 reads","2 reads","3-23 reads","24+ reads")), y=count)) +
geom_bar(stat="identity", fill="steelblue") + xlab("HPV Reads")+ theme_minimal()+
geom_text(aes(label=count), vjust=-0.5, color="black", size=3.5)

Cell
types
library(patchwork)
p1 = FeaturePlot(object = cc_cancer,features = c("CDH1","CDKN2A","EPCAM")) + plot_annotation(
title = 'cancer markers')
p2 = FeaturePlot(object = cc_cancer,features = c("CD27", "PRF1","CD28"))+ plot_annotation(
title = 'Lymphocytes markers')
p3 = FeaturePlot(object = cc_cancer,features = c("CD163", "FCGR2A"),ncol = 1)+ plot_annotation(
title = 'Macrophages markers')
print_tab(plt = p1,title = "cancer markers")
cancer markers

print_tab(plt = p2,title = "Lymphocytes markers")
Lymphocytes markers

print_tab(plt = p3,title = "Macrophages markers")
Macrophages markers

NA
clusters 4 and 7 have been removed
cc_cancer <- subset(cc_cancer, subset = seurat_clusters != 4)
cc_cancer <- subset(cc_cancer, subset = seurat_clusters != 7)
MYB
FeaturePlot(object = cc_cancer,features = c("MYB"))

df = cc_cancer@assays$RNA@data["MYB",] %>% as.data.frame()
names(df) = "MYB"
data = df %>% mutate("MYB=0" = if_else(condition = MYB == 0,true = 1,false = 0))
data = data %>% mutate("0>MYB<1" = if_else(condition = MYB >0 & MYB < 1,true = 1,false = 0))
data = data %>% mutate("MYB >= 1" = if_else(condition = MYB >=1,true = 1,false = 0))
data = colSums(data[,2:ncol(data)]) %>% as.data.frame()
names(data)[1] = "count"
data = rownames_to_column(data,var = "bin")
ggplot(data=data, aes(x=factor(bin,levels = c("MYB=0","0>MYB<1","MYB >= 1")), y=count)) +
geom_bar(stat="identity", fill="steelblue") + xlab("log(TPM) levels")+ theme_minimal()+
geom_text(aes(label=count), vjust=-0.5, color="black", size=3.5)

HPV positive
hpv_positive = hpv_reads %>% dplyr::mutate(hpv_positive = case_when(HPV_reads >= 1 ~ "positive",
HPV_reads < 1 ~ "negative")
)
cc_cancer = AddMetaData(object = cc_cancer,metadata = hpv_positive)
DimPlot(object = cc_cancer,group.by = c("hpv_positive"),pt.size = 0.5)

MYB positive
myb_data = FetchData(object = cc_cancer,vars = ("MYB"))%>% dplyr::mutate(myb_positive = case_when(MYB >= 0.2 ~ "positive",
MYB < 0.2 ~ "negative")) %>% dplyr::select("myb_positive")
cc_cancer = AddMetaData(object = cc_cancer,metadata = myb_data,col.name = "MYB_positive")
DimPlot(object = cc_cancer,group.by = c("MYB_positive"),pt.size = 0.5)

HPV percent / MYB
levels
library(ggrepel)
data = FetchData(object = cc_cancer,vars = c("MYB","hpv_positive","seurat_clusters"))
average_data1 = data %>% group_by(seurat_clusters) %>%
dplyr::summarize(average_myb = mean(MYB, na.rm=TRUE))
average_data2 = data %>% group_by(seurat_clusters,hpv_positive) %>%
summarise(count = n(),) %>% mutate(hpv_percent = count / sum(count))
`summarise()` has grouped output by 'seurat_clusters'. You can override using the `.groups` argument.
average_data2 = average_data2 %>% dplyr::filter(hpv_positive == "positive")
average_all = cbind(average_data1,average_data2)
average_all = average_all[,c(-1)]
ggplot(average_all,
aes(x = hpv_percent, y = average_myb, label=seurat_clusters)) + geom_smooth(method = lm) +
geom_point() + stat_cor(method = "pearson")+geom_text_repel()
`geom_smooth()` using formula 'y ~ x'

HPV percent / MYB
percent
library(ggrepel)
data = FetchData(object = cc_cancer,vars = c("MYB_positive","hpv_positive","seurat_clusters"))
data$MYB_positive = as.factor(data$MYB_positive)
average_data1 = data %>% group_by(seurat_clusters,MYB_positive, .drop = FALSE) %>%
summarise(count = n())%>% mutate(myb_percent = count / sum(count))
`summarise()` has grouped output by 'seurat_clusters'. You can override using the `.groups` argument.
average_data1 = average_data1 %>% dplyr::filter(MYB_positive == "positive" & seurat_clusters!=4 & seurat_clusters!=7 )
average_data2 = data %>% group_by(seurat_clusters,hpv_positive) %>%
summarise(count = n()) %>% mutate(hpv_percent = count / sum(count))
`summarise()` has grouped output by 'seurat_clusters'. You can override using the `.groups` argument.
average_data2 = average_data2 %>% dplyr::filter(hpv_positive == "positive") %>% dplyr::filter(seurat_clusters!=4 & seurat_clusters!=7 )
average_data2 = average_data2[,c(-1)]
average_all = cbind(average_data1,average_data2)
New names:
• `count` -> `count...3`
• `count` -> `count...6`
ggplot(average_all,
aes(x = hpv_percent, y = myb_percent, label=seurat_clusters)) + geom_smooth(method = lm) +
geom_point() + stat_cor(method = "pearson")+geom_text_repel()
`geom_smooth()` using formula 'y ~ x'

Boxplot HPV_positive
VS MYB
myb_vs_hpv = FetchData(object = cc_cancer, vars = c("hpv_positive", "MYB"))
myb_vs_hpv$hpv_positive = paste("HPV", myb_vs_hpv$hpv_positive)
p = ggboxplot(myb_vs_hpv, x = "hpv_positive", y = "MYB",
palette = "jco",
add = "jitter")+ stat_compare_means(method = "wilcox.test",comparisons = list(c("HPV positive","HPV negative")))+ stat_summary(fun.data = function(x) data.frame(y=max(x)*1.2, label = paste("Mean=",round(mean(x),digits = 2))), geom="text") +ylab("log2(gene)")+ggtitle(gene)
print_tab(p,title = gene)
## MYB {.unnumbered }

NA
Boxplot MYB_positive
VS HPV
myb_vs_hpv = FetchData(object = cc_cancer, vars = c("HPV_reads", "MYB_positive"))
myb_vs_hpv$MYB_positive = paste("MYB", myb_vs_hpv$MYB_positive)
p = ggboxplot(myb_vs_hpv, x = "MYB_positive", y = "HPV_reads",
palette = "jco",
add = "jitter")+ stat_compare_means(method = "wilcox.test",comparisons = list(c("MYB positive","MYB negative")))+ stat_summary(fun.data = function(x) data.frame(y=max(x)*1.2, label = paste("Mean=",round(mean(x),digits = 2))), geom="text")
print_tab(p,title = gene)
## MYB {.unnumbered }

NA
library(ggstatsplot)
df = FetchData(object = cc_cancer,vars = c("hpv_positive","MYB_positive")) %>% droplevels()
test = fisher.test(table(df))
plt = ggbarstats(
df,
hpv_positive,
MYB_positive,
results.subtitle = FALSE,
subtitle = paste0("Fisher's exact test", ", p-value = ",
round(test$p.value, 13))
)
print_tab(plt = plt,title = "fisher")
## fisher {.unnumbered }

NA
LS0tCnRpdGxlOiAnYHIgcnN0dWRpb2FwaTo6Z2V0U291cmNlRWRpdG9yQ29udGV4dCgpJHBhdGggJT4lIGJhc2VuYW1lKCkgJT4lIGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLHJlcGxhY2VtZW50ID0gIiIpYCcgCmF1dGhvcjogIkF2aXNoYWkgV2l6ZWwiCmRhdGU6ICdgciBTeXMudGltZSgpYCcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19jb2xsYXBzZTogeWVzCiAgICB0b2NfZmxvYXQ6IAogICAgICBjb2xsYXBzZWQ6IEZBTFNFCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRvY19kZXB0aDogMQotLS0KCiMgRnVuY3Rpb25zCgpgYGB7ciB3YXJuaW5nPUZBTFNFfQpgYGAKCiMgRGF0YQoKIyBDQyBkYXRhCgpgYGB7cn0KY2NfZGF0YSAgPSBSZWFkMTBYKGRhdGEuZGlyID0gIi9zY2kvbGFicy95b3RhbWQvbGFiX3NoYXJlL2F2aXNoYWkud2l6ZWwvUl9wcm9qZWN0cy9ITVNDL0RhdGEvY2VydmljYWxfY2FuY2VyX2RhdGEvVHVtb3IvIikKYGBgCgpgYGB7cn0KY2NfY2FuY2VyID0gQ3JlYXRlU2V1cmF0T2JqZWN0KGNvdW50cyA9IGNjX2RhdGEsIG1pbi5jZWxscyA9IDMsIG1pbi5mZWF0dXJlcyA9IDIwMCkKY2NfY2FuY2VyW1sicGVyY2VudC5tdCJdXSA8LSBQZXJjZW50YWdlRmVhdHVyZVNldChjY19jYW5jZXIsIHBhdHRlcm4gPSAiXk1ULSIpCmNjX2NhbmNlciA8LSBzdWJzZXQoY2NfY2FuY2VyLCBzdWJzZXQgPSBwZXJjZW50Lm10IDwgMTApCgpjY19jYW5jZXIgPC0gTm9ybWFsaXplRGF0YShjY19jYW5jZXIpCmNjX2NhbmNlciA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhjY19jYW5jZXIsbmZlYXR1cmVzID0gMjAwMCkKY2NfY2FuY2VyIDwtIFNjYWxlRGF0YShjY19jYW5jZXIsZmVhdHVyZXMgPSBWYXJpYWJsZUZlYXR1cmVzKGNjX2NhbmNlciksdmFycy50by5yZWdyZXNzID0gYygicGVyY2VudC5tdCIsIm5Db3VudF9STkEiKSkKY2NfY2FuY2VyICAlPD4lICBSdW5QQ0EoIGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBjY19jYW5jZXIpKQpgYGAKCmBgYHtyfQpFbGJvd1Bsb3QoY2NfY2FuY2VyLG5kaW1zID0gNTApCgpgYGAKCmBgYHtyfQpjY19jYW5jZXIgICU8PiUgIEZpbmROZWlnaGJvcnMoZGltcyA9IDE6MzApICU+JSAgRmluZENsdXN0ZXJzKHJlc29sdXRpb24gPSAwLjUpICU+JSAgUnVuVU1BUChkaW1zID0gMTozMCkKRGltUGxvdChjY19jYW5jZXIpCmBgYAoKIyBIUFYKCmBgYHtyfQpocHZfYmFtID0gcmVhZF90c3YoZmlsZSA9ICIuL0RhdGEvY2VydmljYWxfY2FuY2VyX2RhdGEvaHB2X2JhbS50c3YiLGNvbF9zZWxlY3QgPSAxLGNvbF9uYW1lcyA9IEYpCnJlYWRzX3Blcl9jZWxsID0gc3RyX2V4dHJhY3QocGF0dGVybiA9ICJDUjpaOi4qJCIsc3RyaW5nID0gaHB2X2JhbSRYMSkgJT4lIHN0cl9zdWIoIHN0YXJ0ID0gNikgJT4lIHRhYmxlKCkgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgY29sdW1uX3RvX3Jvd25hbWVzKCIuIikKcm93bmFtZXMocmVhZHNfcGVyX2NlbGwpID0gcGFzdGUwKHJvd25hbWVzKHJlYWRzX3Blcl9jZWxsKSwiLTEiKQpyZWFkc19wZXJfY2VsbApgYGAKCmBgYHtyfQp6ZXJvX2NlbGxzID0gY29sbmFtZXMoY2NfY2FuY2VyKVshY29sbmFtZXMoY2NfY2FuY2VyKSAlaW4lIHJvd25hbWVzKHJlYWRzX3Blcl9jZWxsKV0KemVyb19jZWxsc19mcmVxID0gZGF0YS5mcmFtZShyb3cubmFtZXMgPSB6ZXJvX2NlbGxzLEZyZXEgPSByZXAoMCxsZW5ndGgoemVyb19jZWxscykpKQpyZWFkc19wZXJfY2VsbF9hbGxfY2VsbHMgPSByYmluZChyZWFkc19wZXJfY2VsbCx6ZXJvX2NlbGxzX2ZyZXEpCmNjX2NhbmNlciAlPD4lIEFkZE1ldGFEYXRhKG1ldGFkYXRhID0gcmVhZHNfcGVyX2NlbGxfYWxsX2NlbGxzLGNvbC5uYW1lID0gIkhQVl9yZWFkcyIpCmhwdl9yZWFkcyA9IEZldGNoRGF0YShvYmplY3QgPSBjY19jYW5jZXIsdmFycyA9ICJIUFZfcmVhZHMiKQpgYGAKCmBgYHtyfQpkYXRhID0gaHB2X3JlYWRzICU+JSBtdXRhdGUoIjAgcmVhZHMiID0gaWZfZWxzZShjb25kaXRpb24gPSBIUFZfcmVhZHMgPT0gMCx0cnVlID0gMSxmYWxzZSA9IDApKQpkYXRhID0gZGF0YSAlPiUgbXV0YXRlKCIxIHJlYWRzIiA9IGlmX2Vsc2UoY29uZGl0aW9uID0gSFBWX3JlYWRzID09IDEsdHJ1ZSA9IDEsZmFsc2UgPSAwKSkKZGF0YSA9IGRhdGEgJT4lIG11dGF0ZSgiMiByZWFkcyIgPSBpZl9lbHNlKGNvbmRpdGlvbiA9IEhQVl9yZWFkcyA9PSAyLHRydWUgPSAxLGZhbHNlID0gMCkpCmRhdGEgPSBkYXRhICU+JSBtdXRhdGUoIjMtMjMgcmVhZHMiID0gaWZfZWxzZShjb25kaXRpb24gPSBIUFZfcmVhZHMgPj0zICZIUFZfcmVhZHMgIDwyNCx0cnVlID0gMSxmYWxzZSA9IDApKQpkYXRhID0gZGF0YSAlPiUgbXV0YXRlKCIyNCsgcmVhZHMiID0gaWZfZWxzZShjb25kaXRpb24gPSBIUFZfcmVhZHMgPj0yNCx0cnVlID0gMSxmYWxzZSA9IDApKQpkYXRhID0gY29sU3VtcyhkYXRhWywyOm5jb2woZGF0YSldKSAlPiUgYXMuZGF0YS5mcmFtZSgpCm5hbWVzKGRhdGEpWzFdID0gImNvdW50IgpkYXRhID0gcm93bmFtZXNfdG9fY29sdW1uKGRhdGEsdmFyID0gImJpbiIpCmdncGxvdChkYXRhPWRhdGEsIGFlcyh4PWZhY3RvcihiaW4sbGV2ZWxzID0gYygiMCByZWFkcyIsIjEgcmVhZHMiLCIyIHJlYWRzIiwiMy0yMyByZWFkcyIsIjI0KyByZWFkcyIpKSwgeT1jb3VudCkpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGZpbGw9InN0ZWVsYmx1ZSIpICsgeGxhYigiSFBWIFJlYWRzIikrIHRoZW1lX21pbmltYWwoKSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPWNvdW50KSwgdmp1c3Q9LTAuNSwgY29sb3I9ImJsYWNrIiwgc2l6ZT0zLjUpCmBgYAoKIyBDZWxsIHR5cGVzIHsudGFic2V0fQoKYGBge3IgZmlnLmhlaWdodD03LCBmaWcud2lkdGg9NyxyZXN1bHRzPSdhc2lzJ30KbGlicmFyeShwYXRjaHdvcmspCgpwMSA9IEZlYXR1cmVQbG90KG9iamVjdCA9IGNjX2NhbmNlcixmZWF0dXJlcyA9IGMoIkNESDEiLCJDREtOMkEiLCJFUENBTSIpKSArIHBsb3RfYW5ub3RhdGlvbigKICB0aXRsZSA9ICdjYW5jZXIgbWFya2VycycpCgpwMiA9IEZlYXR1cmVQbG90KG9iamVjdCA9IGNjX2NhbmNlcixmZWF0dXJlcyA9IGMoIkNEMjciLCAiUFJGMSIsIkNEMjgiKSkrIHBsb3RfYW5ub3RhdGlvbigKICB0aXRsZSA9ICdMeW1waG9jeXRlcyBtYXJrZXJzJykKCnAzID0gRmVhdHVyZVBsb3Qob2JqZWN0ID0gY2NfY2FuY2VyLGZlYXR1cmVzID0gYygiQ0QxNjMiLCAiRkNHUjJBIiksbmNvbCA9IDEpKyBwbG90X2Fubm90YXRpb24oCiAgdGl0bGUgPSAnTWFjcm9waGFnZXMgbWFya2VycycpCgpwcmludF90YWIocGx0ID0gcDEsdGl0bGUgPSAiY2FuY2VyIG1hcmtlcnMiKQpwcmludF90YWIocGx0ID0gcDIsdGl0bGUgPSAiTHltcGhvY3l0ZXMgbWFya2VycyIpCnByaW50X3RhYihwbHQgPSBwMyx0aXRsZSA9ICJNYWNyb3BoYWdlcyBtYXJrZXJzIikKYGBgCgpjbHVzdGVycyA0IGFuZCA3IGhhdmUgYmVlbiByZW1vdmVkCgpgYGB7cn0KY2NfY2FuY2VyIDwtIHN1YnNldChjY19jYW5jZXIsIHN1YnNldCA9IHNldXJhdF9jbHVzdGVycyAhPSA0KQpjY19jYW5jZXIgPC0gc3Vic2V0KGNjX2NhbmNlciwgc3Vic2V0ID0gc2V1cmF0X2NsdXN0ZXJzICE9IDcpCgpgYGAKCiMgTVlCCgpgYGB7cn0KRmVhdHVyZVBsb3Qob2JqZWN0ID0gY2NfY2FuY2VyLGZlYXR1cmVzID0gYygiTVlCIikpCgpkZiA9IGNjX2NhbmNlckBhc3NheXMkUk5BQGRhdGFbIk1ZQiIsXSAlPiUgYXMuZGF0YS5mcmFtZSgpCm5hbWVzKGRmKSA9ICJNWUIiCgpkYXRhID0gZGYgJT4lIG11dGF0ZSgiTVlCPTAiID0gaWZfZWxzZShjb25kaXRpb24gPSBNWUIgPT0gMCx0cnVlID0gMSxmYWxzZSA9IDApKQpkYXRhID0gZGF0YSAlPiUgbXV0YXRlKCIwPk1ZQjwxIiAgPSBpZl9lbHNlKGNvbmRpdGlvbiA9IE1ZQiA+MCAmIE1ZQiAgPCAxLHRydWUgPSAxLGZhbHNlID0gMCkpCmRhdGEgPSBkYXRhICU+JSBtdXRhdGUoIk1ZQiA+PSAxIiAgPSBpZl9lbHNlKGNvbmRpdGlvbiA9IE1ZQiA+PTEsdHJ1ZSA9IDEsZmFsc2UgPSAwKSkKZGF0YSA9IGNvbFN1bXMoZGF0YVssMjpuY29sKGRhdGEpXSkgJT4lIGFzLmRhdGEuZnJhbWUoKQpuYW1lcyhkYXRhKVsxXSA9ICJjb3VudCIKZGF0YSA9IHJvd25hbWVzX3RvX2NvbHVtbihkYXRhLHZhciA9ICJiaW4iKQpnZ3Bsb3QoZGF0YT1kYXRhLCBhZXMoeD1mYWN0b3IoYmluLGxldmVscyA9IGMoIk1ZQj0wIiwiMD5NWUI8MSIsIk1ZQiA+PSAxIikpLCB5PWNvdW50KSkgKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgZmlsbD0ic3RlZWxibHVlIikgKyB4bGFiKCJsb2coVFBNKSBsZXZlbHMiKSsgdGhlbWVfbWluaW1hbCgpKwogIGdlb21fdGV4dChhZXMobGFiZWw9Y291bnQpLCB2anVzdD0tMC41LCBjb2xvcj0iYmxhY2siLCBzaXplPTMuNSkKYGBgCgojIEhQViBwb3NpdGl2ZQoKYGBge3J9CgpocHZfcG9zaXRpdmUgPSBocHZfcmVhZHMgJT4lIGRwbHlyOjptdXRhdGUoaHB2X3Bvc2l0aXZlID0gY2FzZV93aGVuKEhQVl9yZWFkcyA+PSAxIH4gInBvc2l0aXZlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIUFZfcmVhZHMgPCAxIH4gIm5lZ2F0aXZlIikKKQoKCmNjX2NhbmNlciA9IEFkZE1ldGFEYXRhKG9iamVjdCA9IGNjX2NhbmNlcixtZXRhZGF0YSA9IGhwdl9wb3NpdGl2ZSkKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD03fQpEaW1QbG90KG9iamVjdCA9IGNjX2NhbmNlcixncm91cC5ieSAgPSBjKCJocHZfcG9zaXRpdmUiKSxwdC5zaXplID0gMC41KQpgYGAKCiMgTVlCIHBvc2l0aXZlCgpgYGB7cn0KbXliX2RhdGEgPSBGZXRjaERhdGEob2JqZWN0ID0gY2NfY2FuY2VyLHZhcnMgPSAoIk1ZQiIpKSU+JSBkcGx5cjo6bXV0YXRlKG15Yl9wb3NpdGl2ZSA9IGNhc2Vfd2hlbihNWUIgPj0gMC4yIH4gInBvc2l0aXZlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNWUIgPCAwLjIgfiAibmVnYXRpdmUiKSkgJT4lIGRwbHlyOjpzZWxlY3QoIm15Yl9wb3NpdGl2ZSIpCgoKCmNjX2NhbmNlciA9IEFkZE1ldGFEYXRhKG9iamVjdCA9IGNjX2NhbmNlcixtZXRhZGF0YSA9IG15Yl9kYXRhLGNvbC5uYW1lID0gIk1ZQl9wb3NpdGl2ZSIpCkRpbVBsb3Qob2JqZWN0ID0gY2NfY2FuY2VyLGdyb3VwLmJ5ICA9IGMoIk1ZQl9wb3NpdGl2ZSIpLHB0LnNpemUgPSAwLjUpCgpgYGAKCiMgSFBWIHBlcmNlbnQgLyBNWUIgbGV2ZWxzCgpgYGB7cn0KbGlicmFyeShnZ3JlcGVsKQpkYXRhID0gRmV0Y2hEYXRhKG9iamVjdCA9IGNjX2NhbmNlcix2YXJzID0gIGMoIk1ZQiIsImhwdl9wb3NpdGl2ZSIsInNldXJhdF9jbHVzdGVycyIpKQphdmVyYWdlX2RhdGExICA9IGRhdGEgJT4lIGdyb3VwX2J5KHNldXJhdF9jbHVzdGVycykgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKGF2ZXJhZ2VfbXliID0gbWVhbihNWUIsIG5hLnJtPVRSVUUpKQoKYXZlcmFnZV9kYXRhMiAgPSBkYXRhICU+JSAgZ3JvdXBfYnkoc2V1cmF0X2NsdXN0ZXJzLGhwdl9wb3NpdGl2ZSkgJT4lCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCkgJT4lICBtdXRhdGUoaHB2X3BlcmNlbnQgPSBjb3VudCAvIHN1bShjb3VudCkpCmF2ZXJhZ2VfZGF0YTIgPSBhdmVyYWdlX2RhdGEyICU+JSBkcGx5cjo6ZmlsdGVyKGhwdl9wb3NpdGl2ZSA9PSAicG9zaXRpdmUiKQoKCmF2ZXJhZ2VfYWxsID0gY2JpbmQoYXZlcmFnZV9kYXRhMSxhdmVyYWdlX2RhdGEyKSAKYXZlcmFnZV9hbGwgPSBhdmVyYWdlX2FsbFssYygtMSldCgpnZ3Bsb3QoYXZlcmFnZV9hbGwsCiAgICAgICAgICAgYWVzKHggPSBocHZfcGVyY2VudCwgeSA9IGF2ZXJhZ2VfbXliLCBsYWJlbD1zZXVyYXRfY2x1c3RlcnMpKSArICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSkgKwogIGdlb21fcG9pbnQoKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikrZ2VvbV90ZXh0X3JlcGVsKCkKYGBgCgojIEhQViBwZXJjZW50IC8gTVlCIHBlcmNlbnQKCmBgYHtyfQpsaWJyYXJ5KGdncmVwZWwpCmRhdGEgPSBGZXRjaERhdGEob2JqZWN0ID0gY2NfY2FuY2VyLHZhcnMgPSAgYygiTVlCX3Bvc2l0aXZlIiwiaHB2X3Bvc2l0aXZlIiwic2V1cmF0X2NsdXN0ZXJzIikpCmRhdGEkTVlCX3Bvc2l0aXZlID0gYXMuZmFjdG9yKGRhdGEkTVlCX3Bvc2l0aXZlKSAKYXZlcmFnZV9kYXRhMSAgPSBkYXRhICU+JSAgZ3JvdXBfYnkoc2V1cmF0X2NsdXN0ZXJzLE1ZQl9wb3NpdGl2ZSwgLmRyb3AgPSBGQUxTRSkgJT4lCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSU+JSAgbXV0YXRlKG15Yl9wZXJjZW50ID0gY291bnQgLyBzdW0oY291bnQpKQphdmVyYWdlX2RhdGExID0gYXZlcmFnZV9kYXRhMSAlPiUgZHBseXI6OmZpbHRlcihNWUJfcG9zaXRpdmUgPT0gInBvc2l0aXZlIiAmIHNldXJhdF9jbHVzdGVycyE9NCAmIHNldXJhdF9jbHVzdGVycyE9NyApCgoKYXZlcmFnZV9kYXRhMiAgPSBkYXRhICU+JSAgZ3JvdXBfYnkoc2V1cmF0X2NsdXN0ZXJzLGhwdl9wb3NpdGl2ZSkgJT4lCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUgIG11dGF0ZShocHZfcGVyY2VudCA9IGNvdW50IC8gc3VtKGNvdW50KSkKYXZlcmFnZV9kYXRhMiA9IGF2ZXJhZ2VfZGF0YTIgJT4lIGRwbHlyOjpmaWx0ZXIoaHB2X3Bvc2l0aXZlID09ICJwb3NpdGl2ZSIpICU+JSBkcGx5cjo6ZmlsdGVyKHNldXJhdF9jbHVzdGVycyE9NCAmIHNldXJhdF9jbHVzdGVycyE9NyApCmF2ZXJhZ2VfZGF0YTIgPSBhdmVyYWdlX2RhdGEyWyxjKC0xKV0KCgphdmVyYWdlX2FsbCA9IGNiaW5kKGF2ZXJhZ2VfZGF0YTEsYXZlcmFnZV9kYXRhMikgCgpnZ3Bsb3QoYXZlcmFnZV9hbGwsCiAgICAgICAgICAgYWVzKHggPSBocHZfcGVyY2VudCwgeSA9IG15Yl9wZXJjZW50LCBsYWJlbD1zZXVyYXRfY2x1c3RlcnMpKSArICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSkgKwogIGdlb21fcG9pbnQoKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikrZ2VvbV90ZXh0X3JlcGVsKCkKYGBgCgojIEJveHBsb3QgSFBWX3Bvc2l0aXZlIFZTIE1ZQgoKYGBge3J9Cm15Yl92c19ocHYgPSBGZXRjaERhdGEob2JqZWN0ID0gY2NfY2FuY2VyLCB2YXJzID0gYygiaHB2X3Bvc2l0aXZlIiwgIk1ZQiIpKQpteWJfdnNfaHB2JGhwdl9wb3NpdGl2ZSA9IHBhc3RlKCJIUFYiLCBteWJfdnNfaHB2JGhwdl9wb3NpdGl2ZSkKCnAgPSBnZ2JveHBsb3QobXliX3ZzX2hwdiwgeCA9ICJocHZfcG9zaXRpdmUiLCB5ID0gIk1ZQiIsCiAgICAgICAgICAgIHBhbGV0dGUgPSAiamNvIiwKICAgICAgICAgICAgYWRkID0gImppdHRlciIpKyBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gIndpbGNveC50ZXN0Iixjb21wYXJpc29ucyA9IGxpc3QoYygiSFBWIHBvc2l0aXZlIiwiSFBWIG5lZ2F0aXZlIikpKSsgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gZnVuY3Rpb24oeCkgZGF0YS5mcmFtZSh5PW1heCh4KSoxLjIsIGxhYmVsID0gcGFzdGUoIk1lYW49Iixyb3VuZChtZWFuKHgpLGRpZ2l0cyA9IDIpKSksIGdlb209InRleHQiKSAreWxhYigibG9nMihnZW5lKSIpK2dndGl0bGUoZ2VuZSkKICBwcmludF90YWIocCx0aXRsZSA9IGdlbmUpCgpgYGAKCiMgQm94cGxvdCBNWUJfcG9zaXRpdmUgVlMgSFBWCgpgYGB7cn0KbXliX3ZzX2hwdiA9IEZldGNoRGF0YShvYmplY3QgPSBjY19jYW5jZXIsIHZhcnMgPSBjKCJIUFZfcmVhZHMiLCAiTVlCX3Bvc2l0aXZlIikpCm15Yl92c19ocHYkTVlCX3Bvc2l0aXZlID0gcGFzdGUoIk1ZQiIsIG15Yl92c19ocHYkTVlCX3Bvc2l0aXZlKQoKcCA9IGdnYm94cGxvdChteWJfdnNfaHB2LCB4ID0gIk1ZQl9wb3NpdGl2ZSIsIHkgPSAiSFBWX3JlYWRzIiwKICAgICAgICAgICAgcGFsZXR0ZSA9ICJqY28iLAogICAgICAgICAgICBhZGQgPSAiaml0dGVyIikrIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAid2lsY294LnRlc3QiLGNvbXBhcmlzb25zID0gbGlzdChjKCJNWUIgcG9zaXRpdmUiLCJNWUIgbmVnYXRpdmUiKSkpKyBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBmdW5jdGlvbih4KSBkYXRhLmZyYW1lKHk9bWF4KHgpKjEuMiwgbGFiZWwgPSBwYXN0ZSgiTWVhbj0iLHJvdW5kKG1lYW4oeCksZGlnaXRzID0gMikpKSwgZ2VvbT0idGV4dCIpIAogIHByaW50X3RhYihwLHRpdGxlID0gZ2VuZSkKYGBgCgpgYGB7cn0KbGlicmFyeShnZ3N0YXRzcGxvdCkKZGYgID0gRmV0Y2hEYXRhKG9iamVjdCA9IGNjX2NhbmNlcix2YXJzID0gYygiaHB2X3Bvc2l0aXZlIiwiTVlCX3Bvc2l0aXZlIikpICU+JSBkcm9wbGV2ZWxzKCkgCnRlc3QgPSBmaXNoZXIudGVzdCh0YWJsZShkZikpCnBsdCA9IGdnYmFyc3RhdHMoCiAgZGYsCiAgaHB2X3Bvc2l0aXZlLAogIE1ZQl9wb3NpdGl2ZSwKICByZXN1bHRzLnN1YnRpdGxlID0gRkFMU0UsCiAgc3VidGl0bGUgPSBwYXN0ZTAoIkZpc2hlcidzIGV4YWN0IHRlc3QiLCAiLCBwLXZhbHVlID0gIiwKICAgICAgICAgICAgICAgICAgICByb3VuZCh0ZXN0JHAudmFsdWUsIDEzKSkKKQoKcHJpbnRfdGFiKHBsdCA9IHBsdCx0aXRsZSA9ICJmaXNoZXIiKQpgYGAKCmBgYHs9aHRtbH0KPHNjcmlwdCBzcmM9Imh0dHBzOi8vaHlwb3RoZXMuaXMvZW1iZWQuanMiIGFzeW5jPjwvc2NyaXB0PgpgYGAK