3. Summarize Results
3.1 Summary Function
summarize_markers <- function(markers) {
num_pval0 <- sum(markers$p_val_adj == 0)
num_pval1 <- sum(markers$p_val_adj == 1)
num_significant <- sum(markers$p_val_adj < 0.05)
num_upregulated <- sum(markers$avg_log2FC > 1)
num_downregulated <- sum(markers$avg_log2FC < -1)
cat("Number of genes with p_val_adj = 0:", num_pval0, "\n")
cat("Number of genes with p_val_adj = 1:", num_pval1, "\n")
cat("Number of significant genes (p_val_adj < 0.05):", num_significant, "\n")
cat("Number of upregulated genes (avg_log2FC > 1):", num_upregulated, "\n")
cat("Number of downregulated genes (avg_log2FC < -1):", num_downregulated, "\n")
}
3.2 Summarize Markers1 (MAST with Batch Correction)
cat("Markers1 Summary (MAST with Batch Correction):\n")
Markers1 Summary (MAST with Batch Correction):
summarize_markers(markers_mast_batch)
Number of genes with p_val_adj = 0: 1
Number of genes with p_val_adj = 1: 16799
Number of significant genes (p_val_adj < 0.05): 8601
Number of upregulated genes (avg_log2FC > 1): 14796
Number of downregulated genes (avg_log2FC < -1): 2494
3.3 Summary for Markers2 (Wilcoxon Test)
cat("Markers2 Summary (Wilcoxon Test):\n")
Markers2 Summary (Wilcoxon Test):
summarize_markers(markers_wilcox)
Number of genes with p_val_adj = 0: 4502
Number of genes with p_val_adj = 1: 10049
Number of significant genes (p_val_adj < 0.05): 15357
Number of upregulated genes (avg_log2FC > 1): 14796
Number of downregulated genes (avg_log2FC < -1): 2494
3.4 Summary for Markers3 (MAST without Batch Correction)
cat("Markers3 Summary (MAST without Batch Correction):\n")
Markers3 Summary (MAST without Batch Correction):
summarize_markers(markers_mast_no_batch)
Number of genes with p_val_adj = 0: 4957
Number of genes with p_val_adj = 1: 9570
Number of significant genes (p_val_adj < 0.05): 15882
Number of upregulated genes (avg_log2FC > 1): 14796
Number of downregulated genes (avg_log2FC < -1): 2494
4. Volcano Plots for All Genes
4.1 Volcano Plot for MAST with Batch Correction
EnhancedVolcano(markers_mast_batch,
lab = markers_mast_batch$gene,
x = "avg_log2FC",
y = "p_val_adj",
title = "MAST with Batch Correction (All Genes)",
pCutoff = 0.05,
FCcutoff = 1.0)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

4.2 Volcano Plot for Wilcoxon Test
EnhancedVolcano(markers_wilcox,
lab = markers_wilcox$gene,
x = "avg_log2FC",
y = "p_val_adj",
title = "Wilcoxon Test (All Genes)",
pCutoff = 0.05,
FCcutoff = 1.0)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

4.3 Volcano Plot for MAST without Batch Correction
EnhancedVolcano(markers_mast_no_batch,
lab = markers_mast_no_batch$gene,
x = "avg_log2FC",
y = "p_val_adj",
title = "MAST without Batch Correction (All Genes)",
pCutoff = 0.05,
FCcutoff = 1.0)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

5. Filter and Summarize Results
5.1 Apply Expression Filter First
# Apply the expression filter first
markers_mast_batch <- markers_mast_batch %>%
filter(!(mean_expr_group1 < 0.2 & mean_expr_group2 < 0.2))
markers_wilcox <- markers_wilcox %>%
filter(!(mean_expr_group1 < 0.2 & mean_expr_group2 < 0.2))
markers_mast_no_batch <- markers_mast_no_batch %>%
filter(!(mean_expr_group1 < 0.2 & mean_expr_group2 < 0.2))
5.2 Apply Additional Filters for Statistical Significance and Fold
Change
# Define filtering criteria
p_val_threshold <- 0.05
logfc_threshold <- 1
# Apply additional filters for markers_mast_batch
filtered_markers_mast_batch <- markers_mast_batch %>%
filter(p_val_adj < p_val_threshold & abs(avg_log2FC) > logfc_threshold)
# Apply additional filters for markers_wilcox
filtered_markers_wilcox <- markers_wilcox %>%
filter(p_val_adj < p_val_threshold & abs(avg_log2FC) > logfc_threshold)
# Apply additional filters for markers_mast_no_batch
filtered_markers_mast_no_batch <- markers_mast_no_batch %>%
filter(p_val_adj < p_val_threshold & abs(avg_log2FC) > logfc_threshold)
# Save filtered results
# write.csv(filtered_markers_mast_batch, file = "0-imp_Robj/1-MAST_with_batch_as_Covariate_filtered.csv", row.names = TRUE)
# write.csv(filtered_markers_wilcox, file = "0-imp_Robj/2-Wilcox_min.pct_logfcT-Default_filtered.csv", row.names = TRUE)
# write.csv(filtered_markers_mast_no_batch, file = "0-imp_Robj/3-MAST_without_batch_as_Covariate_filtered.csv", row.names = TRUE)
5.3 Summary Function
summarize_markers <- function(markers) {
num_pval0 <- sum(markers$p_val_adj == 0)
num_pval1 <- sum(markers$p_val_adj == 1)
num_significant <- sum(markers$p_val_adj < 0.05)
num_upregulated <- sum(markers$avg_log2FC > 1)
num_downregulated <- sum(markers$avg_log2FC < -1)
cat("Number of genes with p_val_adj = 0:", num_pval0, "\n")
cat("Number of genes with p_val_adj = 1:", num_pval1, "\n")
cat("Number of significant genes (p_val_adj < 0.05):", num_significant, "\n")
cat("Number of upregulated genes (avg_log2FC > 1):", num_upregulated, "\n")
cat("Number of downregulated genes (avg_log2FC < -1):", num_downregulated, "\n")
}
5.4 Summarize Markers1 (MAST with Batch Correction)
cat("Markers1 Summary (MAST with Batch Correction):\n")
Markers1 Summary (MAST with Batch Correction):
summarize_markers(filtered_markers_mast_batch)
Number of genes with p_val_adj = 0: 0
Number of genes with p_val_adj = 1: 0
Number of significant genes (p_val_adj < 0.05): 3133
Number of upregulated genes (avg_log2FC > 1): 3042
Number of downregulated genes (avg_log2FC < -1): 91
5.5 Summarize Markers2 (Wilcoxon Test)
cat("Markers2 Summary (Wilcoxon Test):\n")
Markers2 Summary (Wilcoxon Test):
summarize_markers(filtered_markers_wilcox)
Number of genes with p_val_adj = 0: 3933
Number of genes with p_val_adj = 1: 0
Number of significant genes (p_val_adj < 0.05): 4630
Number of upregulated genes (avg_log2FC > 1): 4503
Number of downregulated genes (avg_log2FC < -1): 127
5.6 Summarize Markers3 (MAST without Batch Correction)
cat("Markers3 Summary (MAST without Batch Correction):\n")
Markers3 Summary (MAST without Batch Correction):
summarize_markers(filtered_markers_mast_no_batch)
Number of genes with p_val_adj = 0: 4090
Number of genes with p_val_adj = 1: 0
Number of significant genes (p_val_adj < 0.05): 4630
Number of upregulated genes (avg_log2FC > 1): 4503
Number of downregulated genes (avg_log2FC < -1): 127
6. Visualization of Filtered Results
6.1 Volcano Plot for Filtered MAST with Batch Correction
EnhancedVolcano(filtered_markers_mast_batch,
lab = filtered_markers_mast_batch$gene,
x = "avg_log2FC",
y = "p_val_adj",
title = "Filtered MAST with Batch Correction",
pCutoff = 0.05,
FCcutoff = 1.0)

6.2 Volcano Plot for Wilcoxon Test
EnhancedVolcano(filtered_markers_wilcox,
lab = filtered_markers_wilcox$gene,
x = "avg_log2FC",
y = "p_val_adj",
title = "Filtered Wilcoxon Test",
pCutoff = 0.05,
FCcutoff = 1.0)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

6.3 Volcano Plot for MAST without Batch Correction
EnhancedVolcano(filtered_markers_mast_no_batch,
lab = filtered_markers_mast_no_batch$gene,
x = "avg_log2FC",
y = "p_val_adj",
title = "Filtered MAST withrout Batch Correction",
pCutoff = 0.05,
FCcutoff = 1.0)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

LS0tCnRpdGxlOiAiRGlmZmVyZW50aWFsIEV4cHJlc3Npb24gQW5hbHlzaXMgLSBGaWx0ZXJpbmcgYW5kIFZpc3VhbGl6YXRpb24iCmF1dGhvcjogTmFzaXIgTWFobW9vZCBBYmJhc2kKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfY29sbGFwc2VkOiB0cnVlCi0tLQoKIyAxLiBMb2FkIExpYnJhcmllcwpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KEVuaGFuY2VkVm9sY2FubykKbGlicmFyeShwaGVhdG1hcCkKbGlicmFyeSh0aWJibGUpCmBgYAoKIyAyLiBMb2FkIERhdGEKIyMgMi4xIExvYWQgQ1NWIEZpbGVzIHdpdGggTWVhbiBFeHByZXNzaW9uCmBgYHtyfQoKIyBMb2FkIHRoZSBDU1YgZmlsZXMgd2l0aCBtZWFuIGV4cHJlc3Npb24gZGF0YQptYXJrZXJzX21hc3RfYmF0Y2ggPC0gcmVhZC5jc3YoIjAtaW1wX1JvYmovMS1NQVNUX3dpdGhfYmF0Y2hfYXNfQ292YXJpYXRlX3dpdGhfbWVhbkV4cHJlc3Npb24uY3N2Iiwgcm93Lm5hbWVzID0gMSkKbWFya2Vyc193aWxjb3ggPC0gcmVhZC5jc3YoIjAtaW1wX1JvYmovMi1XaWxjb3hfbWluLnBjdF9sb2dmY1QtMF93aXRoX21lYW5FeHByZXNzaW9uLmNzdiIsIHJvdy5uYW1lcyA9IDEpCm1hcmtlcnNfbWFzdF9ub19iYXRjaCA8LSByZWFkLmNzdigiMC1pbXBfUm9iai8zLU1BU1Rfd2l0aG91dF9iYXRjaF9hc19Db3ZhcmlhdGVfd2l0aF9tZWFuRXhwcmVzc2lvbi5jc3YiLCByb3cubmFtZXMgPSAxKQoKYGBgCgojIDMuIFN1bW1hcml6ZSBSZXN1bHRzCiMjIDMuMSBTdW1tYXJ5IEZ1bmN0aW9uCmBgYHtyfQpzdW1tYXJpemVfbWFya2VycyA8LSBmdW5jdGlvbihtYXJrZXJzKSB7CiAgbnVtX3B2YWwwIDwtIHN1bShtYXJrZXJzJHBfdmFsX2FkaiA9PSAwKQogIG51bV9wdmFsMSA8LSBzdW0obWFya2VycyRwX3ZhbF9hZGogPT0gMSkKICBudW1fc2lnbmlmaWNhbnQgPC0gc3VtKG1hcmtlcnMkcF92YWxfYWRqIDwgMC4wNSkKICBudW1fdXByZWd1bGF0ZWQgPC0gc3VtKG1hcmtlcnMkYXZnX2xvZzJGQyA+IDEpCiAgbnVtX2Rvd25yZWd1bGF0ZWQgPC0gc3VtKG1hcmtlcnMkYXZnX2xvZzJGQyA8IC0xKQogIAogIGNhdCgiTnVtYmVyIG9mIGdlbmVzIHdpdGggcF92YWxfYWRqID0gMDoiLCBudW1fcHZhbDAsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2YgZ2VuZXMgd2l0aCBwX3ZhbF9hZGogPSAxOiIsIG51bV9wdmFsMSwgIlxuIikKICBjYXQoIk51bWJlciBvZiBzaWduaWZpY2FudCBnZW5lcyAocF92YWxfYWRqIDwgMC4wNSk6IiwgbnVtX3NpZ25pZmljYW50LCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIHVwcmVndWxhdGVkIGdlbmVzIChhdmdfbG9nMkZDID4gMSk6IiwgbnVtX3VwcmVndWxhdGVkLCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIGRvd25yZWd1bGF0ZWQgZ2VuZXMgKGF2Z19sb2cyRkMgPCAtMSk6IiwgbnVtX2Rvd25yZWd1bGF0ZWQsICJcbiIpCn0KCmBgYAoKIyMgMy4yIFN1bW1hcml6ZSBNYXJrZXJzMSAoTUFTVCB3aXRoIEJhdGNoIENvcnJlY3Rpb24pCmBgYHtyfQpjYXQoIk1hcmtlcnMxIFN1bW1hcnkgKE1BU1Qgd2l0aCBCYXRjaCBDb3JyZWN0aW9uKTpcbiIpCnN1bW1hcml6ZV9tYXJrZXJzKG1hcmtlcnNfbWFzdF9iYXRjaCkKCmBgYAoKIyMgMy4zIFN1bW1hcnkgZm9yIE1hcmtlcnMyIChXaWxjb3hvbiBUZXN0KQpgYGB7cn0KY2F0KCJNYXJrZXJzMiBTdW1tYXJ5IChXaWxjb3hvbiBUZXN0KTpcbiIpCnN1bW1hcml6ZV9tYXJrZXJzKG1hcmtlcnNfd2lsY294KQpgYGAKCiMjIDMuNCBTdW1tYXJ5IGZvciBNYXJrZXJzMyAoTUFTVCB3aXRob3V0IEJhdGNoIENvcnJlY3Rpb24pCmBgYHtyfQpjYXQoIk1hcmtlcnMzIFN1bW1hcnkgKE1BU1Qgd2l0aG91dCBCYXRjaCBDb3JyZWN0aW9uKTpcbiIpCnN1bW1hcml6ZV9tYXJrZXJzKG1hcmtlcnNfbWFzdF9ub19iYXRjaCkKYGBgCgoKCiMgNC4gVm9sY2FubyBQbG90cyBmb3IgQWxsIEdlbmVzCiMjIDQuMSBWb2xjYW5vIFBsb3QgZm9yIE1BU1Qgd2l0aCBCYXRjaCBDb3JyZWN0aW9uCmBgYHtyLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTJ9CkVuaGFuY2VkVm9sY2FubyhtYXJrZXJzX21hc3RfYmF0Y2gsCiAgICAgICAgICAgICAgICBsYWIgPSBtYXJrZXJzX21hc3RfYmF0Y2gkZ2VuZSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsCiAgICAgICAgICAgICAgICB5ID0gInBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJNQVNUIHdpdGggQmF0Y2ggQ29ycmVjdGlvbiAoQWxsIEdlbmVzKSIsCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMS4wKQpgYGAKCiMjIDQuMiBWb2xjYW5vIFBsb3QgZm9yIFdpbGNveG9uIFRlc3QKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKG1hcmtlcnNfd2lsY294LAogICAgICAgICAgICAgICAgbGFiID0gbWFya2Vyc193aWxjb3gkZ2VuZSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsCiAgICAgICAgICAgICAgICB5ID0gInBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJXaWxjb3hvbiBUZXN0IChBbGwgR2VuZXMpIiwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjApCmBgYAoKIyMgNC4zIFZvbGNhbm8gUGxvdCBmb3IgTUFTVCB3aXRob3V0IEJhdGNoIENvcnJlY3Rpb24KYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKG1hcmtlcnNfbWFzdF9ub19iYXRjaCwKICAgICAgICAgICAgICAgIGxhYiA9IG1hcmtlcnNfbWFzdF9ub19iYXRjaCRnZW5lLAogICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHRpdGxlID0gIk1BU1Qgd2l0aG91dCBCYXRjaCBDb3JyZWN0aW9uIChBbGwgR2VuZXMpIiwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjApCmBgYAoKIyA1LiBGaWx0ZXIgYW5kIFN1bW1hcml6ZSBSZXN1bHRzCiMjIDUuMSBBcHBseSBFeHByZXNzaW9uIEZpbHRlciBGaXJzdApgYGB7cn0KIyBBcHBseSB0aGUgZXhwcmVzc2lvbiBmaWx0ZXIgZmlyc3QKbWFya2Vyc19tYXN0X2JhdGNoIDwtIG1hcmtlcnNfbWFzdF9iYXRjaCAlPiUKICBmaWx0ZXIoIShtZWFuX2V4cHJfZ3JvdXAxIDwgMC4yICYgbWVhbl9leHByX2dyb3VwMiA8IDAuMikpCgptYXJrZXJzX3dpbGNveCA8LSBtYXJrZXJzX3dpbGNveCAlPiUKICBmaWx0ZXIoIShtZWFuX2V4cHJfZ3JvdXAxIDwgMC4yICYgbWVhbl9leHByX2dyb3VwMiA8IDAuMikpCgptYXJrZXJzX21hc3Rfbm9fYmF0Y2ggPC0gbWFya2Vyc19tYXN0X25vX2JhdGNoICU+JQogIGZpbHRlcighKG1lYW5fZXhwcl9ncm91cDEgPCAwLjIgJiBtZWFuX2V4cHJfZ3JvdXAyIDwgMC4yKSkKYGBgCgojIyA1LjIgQXBwbHkgQWRkaXRpb25hbCBGaWx0ZXJzIGZvciBTdGF0aXN0aWNhbCBTaWduaWZpY2FuY2UgYW5kIEZvbGQgQ2hhbmdlCmBgYHtyfQojIERlZmluZSBmaWx0ZXJpbmcgY3JpdGVyaWEKcF92YWxfdGhyZXNob2xkIDwtIDAuMDUKbG9nZmNfdGhyZXNob2xkIDwtIDEKCiMgQXBwbHkgYWRkaXRpb25hbCBmaWx0ZXJzIGZvciBtYXJrZXJzX21hc3RfYmF0Y2gKZmlsdGVyZWRfbWFya2Vyc19tYXN0X2JhdGNoIDwtIG1hcmtlcnNfbWFzdF9iYXRjaCAlPiUKICBmaWx0ZXIocF92YWxfYWRqIDwgcF92YWxfdGhyZXNob2xkICYgYWJzKGF2Z19sb2cyRkMpID4gbG9nZmNfdGhyZXNob2xkKQoKIyBBcHBseSBhZGRpdGlvbmFsIGZpbHRlcnMgZm9yIG1hcmtlcnNfd2lsY294CmZpbHRlcmVkX21hcmtlcnNfd2lsY294IDwtIG1hcmtlcnNfd2lsY294ICU+JQogIGZpbHRlcihwX3ZhbF9hZGogPCBwX3ZhbF90aHJlc2hvbGQgJiBhYnMoYXZnX2xvZzJGQykgPiBsb2dmY190aHJlc2hvbGQpCgojIEFwcGx5IGFkZGl0aW9uYWwgZmlsdGVycyBmb3IgbWFya2Vyc19tYXN0X25vX2JhdGNoCmZpbHRlcmVkX21hcmtlcnNfbWFzdF9ub19iYXRjaCA8LSBtYXJrZXJzX21hc3Rfbm9fYmF0Y2ggJT4lCiAgZmlsdGVyKHBfdmFsX2FkaiA8IHBfdmFsX3RocmVzaG9sZCAmIGFicyhhdmdfbG9nMkZDKSA+IGxvZ2ZjX3RocmVzaG9sZCkKCiMgU2F2ZSBmaWx0ZXJlZCByZXN1bHRzCiMgd3JpdGUuY3N2KGZpbHRlcmVkX21hcmtlcnNfbWFzdF9iYXRjaCwgZmlsZSA9ICIwLWltcF9Sb2JqLzEtTUFTVF93aXRoX2JhdGNoX2FzX0NvdmFyaWF0ZV9maWx0ZXJlZC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQojIHdyaXRlLmNzdihmaWx0ZXJlZF9tYXJrZXJzX3dpbGNveCwgZmlsZSA9ICIwLWltcF9Sb2JqLzItV2lsY294X21pbi5wY3RfbG9nZmNULURlZmF1bHRfZmlsdGVyZWQuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkKIyB3cml0ZS5jc3YoZmlsdGVyZWRfbWFya2Vyc19tYXN0X25vX2JhdGNoLCBmaWxlID0gIjAtaW1wX1JvYmovMy1NQVNUX3dpdGhvdXRfYmF0Y2hfYXNfQ292YXJpYXRlX2ZpbHRlcmVkLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpCmBgYAoKIyMgNS4zIFN1bW1hcnkgRnVuY3Rpb24KYGBge3J9CnN1bW1hcml6ZV9tYXJrZXJzIDwtIGZ1bmN0aW9uKG1hcmtlcnMpIHsKICBudW1fcHZhbDAgPC0gc3VtKG1hcmtlcnMkcF92YWxfYWRqID09IDApCiAgbnVtX3B2YWwxIDwtIHN1bShtYXJrZXJzJHBfdmFsX2FkaiA9PSAxKQogIG51bV9zaWduaWZpY2FudCA8LSBzdW0obWFya2VycyRwX3ZhbF9hZGogPCAwLjA1KQogIG51bV91cHJlZ3VsYXRlZCA8LSBzdW0obWFya2VycyRhdmdfbG9nMkZDID4gMSkKICBudW1fZG93bnJlZ3VsYXRlZCA8LSBzdW0obWFya2VycyRhdmdfbG9nMkZDIDwgLTEpCiAgCiAgY2F0KCJOdW1iZXIgb2YgZ2VuZXMgd2l0aCBwX3ZhbF9hZGogPSAwOiIsIG51bV9wdmFsMCwgIlxuIikKICBjYXQoIk51bWJlciBvZiBnZW5lcyB3aXRoIHBfdmFsX2FkaiA9IDE6IiwgbnVtX3B2YWwxLCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIHNpZ25pZmljYW50IGdlbmVzIChwX3ZhbF9hZGogPCAwLjA1KToiLCBudW1fc2lnbmlmaWNhbnQsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2YgdXByZWd1bGF0ZWQgZ2VuZXMgKGF2Z19sb2cyRkMgPiAxKToiLCBudW1fdXByZWd1bGF0ZWQsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2YgZG93bnJlZ3VsYXRlZCBnZW5lcyAoYXZnX2xvZzJGQyA8IC0xKToiLCBudW1fZG93bnJlZ3VsYXRlZCwgIlxuIikKfQpgYGAKCiMjIDUuNCBTdW1tYXJpemUgTWFya2VyczEgKE1BU1Qgd2l0aCBCYXRjaCBDb3JyZWN0aW9uKQpgYGB7cn0KY2F0KCJNYXJrZXJzMSBTdW1tYXJ5IChNQVNUIHdpdGggQmF0Y2ggQ29ycmVjdGlvbik6XG4iKQpzdW1tYXJpemVfbWFya2VycyhmaWx0ZXJlZF9tYXJrZXJzX21hc3RfYmF0Y2gpCmBgYAoKIyMgNS41IFN1bW1hcml6ZSBNYXJrZXJzMiAoV2lsY294b24gVGVzdCkKYGBge3J9CmNhdCgiTWFya2VyczIgU3VtbWFyeSAoV2lsY294b24gVGVzdCk6XG4iKQpzdW1tYXJpemVfbWFya2VycyhmaWx0ZXJlZF9tYXJrZXJzX3dpbGNveCkKYGBgCgojIyA1LjYgU3VtbWFyaXplIE1hcmtlcnMzIChNQVNUIHdpdGhvdXQgQmF0Y2ggQ29ycmVjdGlvbikKYGBge3J9CmNhdCgiTWFya2VyczMgU3VtbWFyeSAoTUFTVCB3aXRob3V0IEJhdGNoIENvcnJlY3Rpb24pOlxuIikKc3VtbWFyaXplX21hcmtlcnMoZmlsdGVyZWRfbWFya2Vyc19tYXN0X25vX2JhdGNoKQpgYGAKCiMgNi4gVmlzdWFsaXphdGlvbiBvZiBGaWx0ZXJlZCBSZXN1bHRzCiMjIDYuMSBWb2xjYW5vIFBsb3QgZm9yIEZpbHRlcmVkIE1BU1Qgd2l0aCBCYXRjaCBDb3JyZWN0aW9uCmBgYHtyLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTJ9CkVuaGFuY2VkVm9sY2FubyhmaWx0ZXJlZF9tYXJrZXJzX21hc3RfYmF0Y2gsCiAgICAgICAgICAgICAgICBsYWIgPSBmaWx0ZXJlZF9tYXJrZXJzX21hc3RfYmF0Y2gkZ2VuZSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsCiAgICAgICAgICAgICAgICB5ID0gInBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJGaWx0ZXJlZCBNQVNUIHdpdGggQmF0Y2ggQ29ycmVjdGlvbiIsCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMS4wKQpgYGAKCiMjIDYuMiBWb2xjYW5vIFBsb3QgZm9yIFdpbGNveG9uIFRlc3QKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKGZpbHRlcmVkX21hcmtlcnNfd2lsY294LAogICAgICAgICAgICAgICAgbGFiID0gZmlsdGVyZWRfbWFya2Vyc193aWxjb3gkZ2VuZSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsCiAgICAgICAgICAgICAgICB5ID0gInBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJGaWx0ZXJlZCBXaWxjb3hvbiBUZXN0IiwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjApCmBgYAoKIyMgNi4zIFZvbGNhbm8gUGxvdCBmb3IgTUFTVCB3aXRob3V0IEJhdGNoIENvcnJlY3Rpb24KYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKGZpbHRlcmVkX21hcmtlcnNfbWFzdF9ub19iYXRjaCwKICAgICAgICAgICAgICAgIGxhYiA9IGZpbHRlcmVkX21hcmtlcnNfbWFzdF9ub19iYXRjaCRnZW5lLAogICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHRpdGxlID0gIkZpbHRlcmVkIE1BU1Qgd2l0aHJvdXQgQmF0Y2ggQ29ycmVjdGlvbiIsCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMS4wKQpgYGAKCg==