1. Load Libraries

2. Load Data

2.1 Load CSV Files with Mean Expression


# Define cell lines
cell_lines <- c("L1", "L2", "L3", "L4", "L5", "L6", "L7")

# Define filtering criteria
mean_expr_threshold <- 0.2
p_val_threshold <- 0.05
logfc_threshold <- 1

# Summary Function
summarize_markers <- function(markers, cell_line) {
  num_pval0 <- sum(markers$p_val_adj == 0)
  num_pval1 <- sum(markers$p_val_adj == 1)
  num_significant <- sum(markers$p_val_adj < p_val_threshold)
  num_upregulated <- sum(markers$avg_log2FC > logfc_threshold)
  num_downregulated <- sum(markers$avg_log2FC < -logfc_threshold)
  
  cat("\nSummary for", cell_line, ":\n")
  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")
}

# Volcano Plot Function
create_volcano_plot <- function(markers, cell_line) {
  volcano <- EnhancedVolcano(markers,
                             lab = markers$gene,
                             x = "avg_log2FC",
                             y = "p_val_adj",
                             title = paste0(cell_line, " vs Normal CD4+ T Cells"),
                             pCutoff = p_val_threshold,
                             FCcutoff = logfc_threshold,
                             pointSize = 2.5,
                             labSize = 3.0)
  
  print(volcano)
}

# Main Function to Process Each Cell Line
process_cell_line <- function(cell_line) {
  # Construct file name and read data
  file_name <- paste0("Updated_DE_Results_", cell_line, "_with_MeanExpr.csv")
  markers <- read.csv(file_name, row.names = 1)
  
  # Filter genes based on mean expression
  markers <- markers %>%
    filter(!(mean_expr_group1 < mean_expr_threshold & mean_expr_group2 < mean_expr_threshold))
  
  # Apply additional filters
  filtered_markers <- markers %>%
    filter(p_val_adj < p_val_threshold & abs(avg_log2FC) > logfc_threshold)
  
  # Summarize the filtered results
  summarize_markers(filtered_markers, cell_line)
  
  # Generate volcano plot
  create_volcano_plot(filtered_markers, cell_line)
}

# Loop through each cell line and apply the function
for (cell_line in cell_lines) {
  process_cell_line(cell_line)
}

Summary for L1 :
Number of genes with p_val_adj = 0: 1803 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 4129 
Number of upregulated genes (avg_log2FC > 1): 4013 
Number of downregulated genes (avg_log2FC < -1): 116 
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

Summary for L2 :
Number of genes with p_val_adj = 0: 2945 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 5465 
Number of upregulated genes (avg_log2FC > 1): 5324 
Number of downregulated genes (avg_log2FC < -1): 141 

Summary for L3 :
Number of genes with p_val_adj = 0: 2051 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 3725 
Number of upregulated genes (avg_log2FC > 1): 3432 
Number of downregulated genes (avg_log2FC < -1): 293 

Summary for L4 :
Number of genes with p_val_adj = 0: 3185 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 5584 
Number of upregulated genes (avg_log2FC > 1): 5419 
Number of downregulated genes (avg_log2FC < -1): 165 

Summary for L5 :
Number of genes with p_val_adj = 0: 2607 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 4688 
Number of upregulated genes (avg_log2FC > 1): 4471 
Number of downregulated genes (avg_log2FC < -1): 217 

Summary for L6 :
Number of genes with p_val_adj = 0: 1927 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 4074 
Number of upregulated genes (avg_log2FC > 1): 3915 
Number of downregulated genes (avg_log2FC < -1): 159 

Summary for L7 :
Number of genes with p_val_adj = 0: 2258 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 4455 
Number of upregulated genes (avg_log2FC > 1): 4277 
Number of downregulated genes (avg_log2FC < -1): 178 

2.2 Volcano Plot for MAST with SCT Assay

# Load necessary libraries
library(dplyr)
library(ggplot2)
library(EnhancedVolcano)

# Define cell lines
cell_lines <- c("L1", "L2", "L3", "L4", "L5", "L6", "L7")

# Define filtering criteria
mean_expr_threshold <- 0.2
p_val_threshold <- 0.05
logfc_threshold <- 1

# Define genes to highlight
highlight_genes <- c('KIR3DL2', 'TOX', 'TWIST1', 'CD52', 'CCR4', 'IL2RA', 
                     'CD7', 'DPP4', 'CCR7', 'GATA3', 'FOXP3', 'DNM3', 
                     'NCR1', 'CD70', 'AIRE', 'PDCD1 (PD-1)', 'CD274 (PD-L1)')

# Summary Function
summarize_markers <- function(markers, cell_line) {
  num_pval0 <- sum(markers$p_val_adj == 0)
  num_pval1 <- sum(markers$p_val_adj == 1)
  num_significant <- sum(markers$p_val_adj < p_val_threshold)
  num_upregulated <- sum(markers$avg_log2FC > logfc_threshold)
  num_downregulated <- sum(markers$avg_log2FC < -logfc_threshold)
  
  cat("\nSummary for", cell_line, ":\n")
  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")
}

# Volcano Plot Function
create_volcano_plot <- function(markers, cell_line) {
  volcano <- EnhancedVolcano(markers,
                             lab = markers$gene,
                             x = "avg_log2FC",
                             y = "p_val_adj",
                             title = paste0(cell_line, " vs Normal CD4+ T Cells"),
                             pCutoff = p_val_threshold,
                             FCcutoff = logfc_threshold,
                             pointSize = 2.5,
                             labSize = 3.0)
  print(volcano)
}

# Volcano Plot with Selected Genes
create_volcano_plot_highlight <- function(markers, cell_line) {
  volcano <- EnhancedVolcano(markers,
                             lab = markers$gene,
                             x = "avg_log2FC", 
                             y = "p_val_adj",
                             selectLab = highlight_genes,
                             title = paste0(cell_line, " vs Normal CD4+ T cells (Highlighted Genes)"),
                             xlab = bquote(~Log[2]~ 'fold change'),
                             pCutoff = 0.0001,
                             FCcutoff = logfc_threshold, 
                             pointSize = 3.0,
                             labSize = 3.0,
                             boxedLabels = TRUE,
                             colAlpha = 0.5,
                             legendPosition = 'right',
                             legendLabSize = 10,
                             legendIconSize = 4.0,
                             drawConnectors = TRUE,
                             widthConnectors = 0.5,
                             colConnectors = 'black',
                             arrowheads = FALSE,
                             max.overlaps = 30)
  print(volcano)
}

# Main Function to Process Each Cell Line
process_cell_line <- function(cell_line) {
  # Construct file name and read data
  file_name <- paste0("Updated_DE_Results_", cell_line, "_with_MeanExpr.csv")
  markers <- read.csv(file_name, row.names = 1)
  
  # Filter genes based on mean expression
  markers <- markers %>%
    filter(!(mean_expr_group1 < mean_expr_threshold & mean_expr_group2 < mean_expr_threshold))
  
  # Apply additional filters
  filtered_markers <- markers %>%
    filter(p_val_adj < p_val_threshold & abs(avg_log2FC) > logfc_threshold)
  
  # Summarize the filtered results
  summarize_markers(filtered_markers, cell_line)
  
  # Generate volcano plots
  create_volcano_plot(filtered_markers, cell_line)
  create_volcano_plot_highlight(filtered_markers, cell_line)
  
  # Save filtered results to CSV
  output_file <- paste0("Filtered_DE_Results_", cell_line, "_with_MeanExpr.csv")
  write.csv(filtered_markers, output_file, row.names = TRUE)
}

# Loop through each cell line and apply the function
for (cell_line in cell_lines) {
  process_cell_line(cell_line)
}

Summary for L1 :
Number of genes with p_val_adj = 0: 1803 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 4129 
Number of upregulated genes (avg_log2FC > 1): 4013 
Number of downregulated genes (avg_log2FC < -1): 116 
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

Summary for L2 :
Number of genes with p_val_adj = 0: 2945 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 5465 
Number of upregulated genes (avg_log2FC > 1): 5324 
Number of downregulated genes (avg_log2FC < -1): 141 

Summary for L3 :
Number of genes with p_val_adj = 0: 2051 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 3725 
Number of upregulated genes (avg_log2FC > 1): 3432 
Number of downregulated genes (avg_log2FC < -1): 293 

Summary for L4 :
Number of genes with p_val_adj = 0: 3185 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 5584 
Number of upregulated genes (avg_log2FC > 1): 5419 
Number of downregulated genes (avg_log2FC < -1): 165 

Summary for L5 :
Number of genes with p_val_adj = 0: 2607 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 4688 
Number of upregulated genes (avg_log2FC > 1): 4471 
Number of downregulated genes (avg_log2FC < -1): 217 

Summary for L6 :
Number of genes with p_val_adj = 0: 1927 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 4074 
Number of upregulated genes (avg_log2FC > 1): 3915 
Number of downregulated genes (avg_log2FC < -1): 159 

Summary for L7 :
Number of genes with p_val_adj = 0: 2258 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 4455 
Number of upregulated genes (avg_log2FC > 1): 4277 
Number of downregulated genes (avg_log2FC < -1): 178 

LS0tCnRpdGxlOiAiRmlsdGVyaW5nIGFuZCBWaXN1YWxpemF0aW9uKGNlbGwgbGluZXMgdnMgQ29udHJvbCkiCmF1dGhvcjogTmFzaXIgTWFobW9vZCBBYmJhc2kKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfY29sbGFwc2VkOiB0cnVlCi0tLQoKIyAxLiBMb2FkIExpYnJhcmllcwpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KCiMgTG9hZCBuZWNlc3NhcnkgbGlicmFyaWVzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShFbmhhbmNlZFZvbGNhbm8pCmxpYnJhcnkocGhlYXRtYXApCmxpYnJhcnkodGliYmxlKQoKYGBgCgojIDIuIExvYWQgRGF0YQojIyAyLjEgTG9hZCBDU1YgRmlsZXMgd2l0aCBNZWFuIEV4cHJlc3Npb24KYGBge3IsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKIyBEZWZpbmUgY2VsbCBsaW5lcwpjZWxsX2xpbmVzIDwtIGMoIkwxIiwgIkwyIiwgIkwzIiwgIkw0IiwgIkw1IiwgIkw2IiwgIkw3IikKCiMgRGVmaW5lIGZpbHRlcmluZyBjcml0ZXJpYQptZWFuX2V4cHJfdGhyZXNob2xkIDwtIDAuMgpwX3ZhbF90aHJlc2hvbGQgPC0gMC4wNQpsb2dmY190aHJlc2hvbGQgPC0gMQoKIyBTdW1tYXJ5IEZ1bmN0aW9uCnN1bW1hcml6ZV9tYXJrZXJzIDwtIGZ1bmN0aW9uKG1hcmtlcnMsIGNlbGxfbGluZSkgewogIG51bV9wdmFsMCA8LSBzdW0obWFya2VycyRwX3ZhbF9hZGogPT0gMCkKICBudW1fcHZhbDEgPC0gc3VtKG1hcmtlcnMkcF92YWxfYWRqID09IDEpCiAgbnVtX3NpZ25pZmljYW50IDwtIHN1bShtYXJrZXJzJHBfdmFsX2FkaiA8IHBfdmFsX3RocmVzaG9sZCkKICBudW1fdXByZWd1bGF0ZWQgPC0gc3VtKG1hcmtlcnMkYXZnX2xvZzJGQyA+IGxvZ2ZjX3RocmVzaG9sZCkKICBudW1fZG93bnJlZ3VsYXRlZCA8LSBzdW0obWFya2VycyRhdmdfbG9nMkZDIDwgLWxvZ2ZjX3RocmVzaG9sZCkKICAKICBjYXQoIlxuU3VtbWFyeSBmb3IiLCBjZWxsX2xpbmUsICI6XG4iKQogIGNhdCgiTnVtYmVyIG9mIGdlbmVzIHdpdGggcF92YWxfYWRqID0gMDoiLCBudW1fcHZhbDAsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2YgZ2VuZXMgd2l0aCBwX3ZhbF9hZGogPSAxOiIsIG51bV9wdmFsMSwgIlxuIikKICBjYXQoIk51bWJlciBvZiBzaWduaWZpY2FudCBnZW5lcyAocF92YWxfYWRqIDwgMC4wNSk6IiwgbnVtX3NpZ25pZmljYW50LCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIHVwcmVndWxhdGVkIGdlbmVzIChhdmdfbG9nMkZDID4gMSk6IiwgbnVtX3VwcmVndWxhdGVkLCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIGRvd25yZWd1bGF0ZWQgZ2VuZXMgKGF2Z19sb2cyRkMgPCAtMSk6IiwgbnVtX2Rvd25yZWd1bGF0ZWQsICJcbiIpCn0KCiMgVm9sY2FubyBQbG90IEZ1bmN0aW9uCmNyZWF0ZV92b2xjYW5vX3Bsb3QgPC0gZnVuY3Rpb24obWFya2VycywgY2VsbF9saW5lKSB7CiAgdm9sY2FubyA8LSBFbmhhbmNlZFZvbGNhbm8obWFya2VycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWIgPSBtYXJrZXJzJGdlbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gInBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSBwYXN0ZTAoY2VsbF9saW5lLCAiIHZzIE5vcm1hbCBDRDQrIFQgQ2VsbHMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gcF92YWxfdGhyZXNob2xkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gbG9nZmNfdGhyZXNob2xkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDIuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJTaXplID0gMy4wKQogIAogIHByaW50KHZvbGNhbm8pCn0KCiMgTWFpbiBGdW5jdGlvbiB0byBQcm9jZXNzIEVhY2ggQ2VsbCBMaW5lCnByb2Nlc3NfY2VsbF9saW5lIDwtIGZ1bmN0aW9uKGNlbGxfbGluZSkgewogICMgQ29uc3RydWN0IGZpbGUgbmFtZSBhbmQgcmVhZCBkYXRhCiAgZmlsZV9uYW1lIDwtIHBhc3RlMCgiVXBkYXRlZF9ERV9SZXN1bHRzXyIsIGNlbGxfbGluZSwgIl93aXRoX01lYW5FeHByLmNzdiIpCiAgbWFya2VycyA8LSByZWFkLmNzdihmaWxlX25hbWUsIHJvdy5uYW1lcyA9IDEpCiAgCiAgIyBGaWx0ZXIgZ2VuZXMgYmFzZWQgb24gbWVhbiBleHByZXNzaW9uCiAgbWFya2VycyA8LSBtYXJrZXJzICU+JQogICAgZmlsdGVyKCEobWVhbl9leHByX2dyb3VwMSA8IG1lYW5fZXhwcl90aHJlc2hvbGQgJiBtZWFuX2V4cHJfZ3JvdXAyIDwgbWVhbl9leHByX3RocmVzaG9sZCkpCiAgCiAgIyBBcHBseSBhZGRpdGlvbmFsIGZpbHRlcnMKICBmaWx0ZXJlZF9tYXJrZXJzIDwtIG1hcmtlcnMgJT4lCiAgICBmaWx0ZXIocF92YWxfYWRqIDwgcF92YWxfdGhyZXNob2xkICYgYWJzKGF2Z19sb2cyRkMpID4gbG9nZmNfdGhyZXNob2xkKQogIAogICMgU3VtbWFyaXplIHRoZSBmaWx0ZXJlZCByZXN1bHRzCiAgc3VtbWFyaXplX21hcmtlcnMoZmlsdGVyZWRfbWFya2VycywgY2VsbF9saW5lKQogIAogICMgR2VuZXJhdGUgdm9sY2FubyBwbG90CiAgY3JlYXRlX3ZvbGNhbm9fcGxvdChmaWx0ZXJlZF9tYXJrZXJzLCBjZWxsX2xpbmUpCn0KCiMgTG9vcCB0aHJvdWdoIGVhY2ggY2VsbCBsaW5lIGFuZCBhcHBseSB0aGUgZnVuY3Rpb24KZm9yIChjZWxsX2xpbmUgaW4gY2VsbF9saW5lcykgewogIHByb2Nlc3NfY2VsbF9saW5lKGNlbGxfbGluZSkKfQoKCmBgYAoKCiMjIDIuMiBWb2xjYW5vIFBsb3QgZm9yIE1BU1Qgd2l0aCBTQ1QgQXNzYXkKYGBge3IsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQojIExvYWQgbmVjZXNzYXJ5IGxpYnJhcmllcwpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoRW5oYW5jZWRWb2xjYW5vKQoKIyBEZWZpbmUgY2VsbCBsaW5lcwpjZWxsX2xpbmVzIDwtIGMoIkwxIiwgIkwyIiwgIkwzIiwgIkw0IiwgIkw1IiwgIkw2IiwgIkw3IikKCiMgRGVmaW5lIGZpbHRlcmluZyBjcml0ZXJpYQptZWFuX2V4cHJfdGhyZXNob2xkIDwtIDAuMgpwX3ZhbF90aHJlc2hvbGQgPC0gMC4wNQpsb2dmY190aHJlc2hvbGQgPC0gMQoKIyBEZWZpbmUgZ2VuZXMgdG8gaGlnaGxpZ2h0CmhpZ2hsaWdodF9nZW5lcyA8LSBjKCdLSVIzREwyJywgJ1RPWCcsICdUV0lTVDEnLCAnQ0Q1MicsICdDQ1I0JywgJ0lMMlJBJywgCiAgICAgICAgICAgICAgICAgICAgICdDRDcnLCAnRFBQNCcsICdDQ1I3JywgJ0dBVEEzJywgJ0ZPWFAzJywgJ0ROTTMnLCAKICAgICAgICAgICAgICAgICAgICAgJ05DUjEnLCAnQ0Q3MCcsICdBSVJFJywgJ1BEQ0QxIChQRC0xKScsICdDRDI3NCAoUEQtTDEpJykKCiMgU3VtbWFyeSBGdW5jdGlvbgpzdW1tYXJpemVfbWFya2VycyA8LSBmdW5jdGlvbihtYXJrZXJzLCBjZWxsX2xpbmUpIHsKICBudW1fcHZhbDAgPC0gc3VtKG1hcmtlcnMkcF92YWxfYWRqID09IDApCiAgbnVtX3B2YWwxIDwtIHN1bShtYXJrZXJzJHBfdmFsX2FkaiA9PSAxKQogIG51bV9zaWduaWZpY2FudCA8LSBzdW0obWFya2VycyRwX3ZhbF9hZGogPCBwX3ZhbF90aHJlc2hvbGQpCiAgbnVtX3VwcmVndWxhdGVkIDwtIHN1bShtYXJrZXJzJGF2Z19sb2cyRkMgPiBsb2dmY190aHJlc2hvbGQpCiAgbnVtX2Rvd25yZWd1bGF0ZWQgPC0gc3VtKG1hcmtlcnMkYXZnX2xvZzJGQyA8IC1sb2dmY190aHJlc2hvbGQpCiAgCiAgY2F0KCJcblN1bW1hcnkgZm9yIiwgY2VsbF9saW5lLCAiOlxuIikKICBjYXQoIk51bWJlciBvZiBnZW5lcyB3aXRoIHBfdmFsX2FkaiA9IDA6IiwgbnVtX3B2YWwwLCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIGdlbmVzIHdpdGggcF92YWxfYWRqID0gMToiLCBudW1fcHZhbDEsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2Ygc2lnbmlmaWNhbnQgZ2VuZXMgKHBfdmFsX2FkaiA8IDAuMDUpOiIsIG51bV9zaWduaWZpY2FudCwgIlxuIikKICBjYXQoIk51bWJlciBvZiB1cHJlZ3VsYXRlZCBnZW5lcyAoYXZnX2xvZzJGQyA+IDEpOiIsIG51bV91cHJlZ3VsYXRlZCwgIlxuIikKICBjYXQoIk51bWJlciBvZiBkb3ducmVndWxhdGVkIGdlbmVzIChhdmdfbG9nMkZDIDwgLTEpOiIsIG51bV9kb3ducmVndWxhdGVkLCAiXG4iKQp9CgojIFZvbGNhbm8gUGxvdCBGdW5jdGlvbgpjcmVhdGVfdm9sY2Fub19wbG90IDwtIGZ1bmN0aW9uKG1hcmtlcnMsIGNlbGxfbGluZSkgewogIHZvbGNhbm8gPC0gRW5oYW5jZWRWb2xjYW5vKG1hcmtlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiID0gbWFya2VycyRnZW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gcGFzdGUwKGNlbGxfbGluZSwgIiB2cyBOb3JtYWwgQ0Q0KyBUIENlbGxzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEN1dG9mZiA9IHBfdmFsX3RocmVzaG9sZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IGxvZ2ZjX3RocmVzaG9sZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2ludFNpemUgPSAyLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiU2l6ZSA9IDMuMCkKICBwcmludCh2b2xjYW5vKQp9CgojIFZvbGNhbm8gUGxvdCB3aXRoIFNlbGVjdGVkIEdlbmVzCmNyZWF0ZV92b2xjYW5vX3Bsb3RfaGlnaGxpZ2h0IDwtIGZ1bmN0aW9uKG1hcmtlcnMsIGNlbGxfbGluZSkgewogIHZvbGNhbm8gPC0gRW5oYW5jZWRWb2xjYW5vKG1hcmtlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiID0gbWFya2VycyRnZW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RMYWIgPSBoaWdobGlnaHRfZ2VuZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSBwYXN0ZTAoY2VsbF9saW5lLCAiIHZzIE5vcm1hbCBDRDQrIFQgY2VsbHMgKEhpZ2hsaWdodGVkIEdlbmVzKSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIgPSBicXVvdGUofkxvZ1syXX4gJ2ZvbGQgY2hhbmdlJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDAwMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IGxvZ2ZjX3RocmVzaG9sZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMy4wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYlNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm94ZWRMYWJlbHMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbEFscGhhID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmRMYWJTaXplID0gMTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kSWNvblNpemUgPSA0LjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xDb25uZWN0b3JzID0gJ2JsYWNrJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJvd2hlYWRzID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4Lm92ZXJsYXBzID0gMzApCiAgcHJpbnQodm9sY2FubykKfQoKIyBNYWluIEZ1bmN0aW9uIHRvIFByb2Nlc3MgRWFjaCBDZWxsIExpbmUKcHJvY2Vzc19jZWxsX2xpbmUgPC0gZnVuY3Rpb24oY2VsbF9saW5lKSB7CiAgIyBDb25zdHJ1Y3QgZmlsZSBuYW1lIGFuZCByZWFkIGRhdGEKICBmaWxlX25hbWUgPC0gcGFzdGUwKCJVcGRhdGVkX0RFX1Jlc3VsdHNfIiwgY2VsbF9saW5lLCAiX3dpdGhfTWVhbkV4cHIuY3N2IikKICBtYXJrZXJzIDwtIHJlYWQuY3N2KGZpbGVfbmFtZSwgcm93Lm5hbWVzID0gMSkKICAKICAjIEZpbHRlciBnZW5lcyBiYXNlZCBvbiBtZWFuIGV4cHJlc3Npb24KICBtYXJrZXJzIDwtIG1hcmtlcnMgJT4lCiAgICBmaWx0ZXIoIShtZWFuX2V4cHJfZ3JvdXAxIDwgbWVhbl9leHByX3RocmVzaG9sZCAmIG1lYW5fZXhwcl9ncm91cDIgPCBtZWFuX2V4cHJfdGhyZXNob2xkKSkKICAKICAjIEFwcGx5IGFkZGl0aW9uYWwgZmlsdGVycwogIGZpbHRlcmVkX21hcmtlcnMgPC0gbWFya2VycyAlPiUKICAgIGZpbHRlcihwX3ZhbF9hZGogPCBwX3ZhbF90aHJlc2hvbGQgJiBhYnMoYXZnX2xvZzJGQykgPiBsb2dmY190aHJlc2hvbGQpCiAgCiAgIyBTdW1tYXJpemUgdGhlIGZpbHRlcmVkIHJlc3VsdHMKICBzdW1tYXJpemVfbWFya2VycyhmaWx0ZXJlZF9tYXJrZXJzLCBjZWxsX2xpbmUpCiAgCiAgIyBHZW5lcmF0ZSB2b2xjYW5vIHBsb3RzCiAgY3JlYXRlX3ZvbGNhbm9fcGxvdChmaWx0ZXJlZF9tYXJrZXJzLCBjZWxsX2xpbmUpCiAgY3JlYXRlX3ZvbGNhbm9fcGxvdF9oaWdobGlnaHQoZmlsdGVyZWRfbWFya2VycywgY2VsbF9saW5lKQogIAogICMgU2F2ZSBmaWx0ZXJlZCByZXN1bHRzIHRvIENTVgogIG91dHB1dF9maWxlIDwtIHBhc3RlMCgiRmlsdGVyZWRfREVfUmVzdWx0c18iLCBjZWxsX2xpbmUsICJfd2l0aF9NZWFuRXhwci5jc3YiKQogIHdyaXRlLmNzdihmaWx0ZXJlZF9tYXJrZXJzLCBvdXRwdXRfZmlsZSwgcm93Lm5hbWVzID0gVFJVRSkKfQoKIyBMb29wIHRocm91Z2ggZWFjaCBjZWxsIGxpbmUgYW5kIGFwcGx5IHRoZSBmdW5jdGlvbgpmb3IgKGNlbGxfbGluZSBpbiBjZWxsX2xpbmVzKSB7CiAgcHJvY2Vzc19jZWxsX2xpbmUoY2VsbF9saW5lKQp9CgpgYGAKCgoK