load libraries————————————

Read Seurat object with load as you save it with save() function


All_samples_Merged <- readRDS("../../0-Seurat_RDS_OBJECT_FINAL/All_samples_Merged_with_STCAT_and_renamed_FINAL.rds")

1. Subset Normal CD4⁺ T Cells for Reference


# Subset normal CD4+ T cells from merged object
reference_cd4 <- subset(
  All_samples_Merged,
  subset = cell_line %in% c("CD4Tcells_lab", "CD4Tcells_10x")
)


DefaultAssay(reference_cd4) <- "RNA"  

2. Normalize & Integrate Reference (Accommodate Multiple Donors)


ref_list <- SplitObject(reference_cd4, split.by = "cell_line")

# 🔴 Run SCTransform on each subset to ensure consistent variable features
ref_list <- lapply(ref_list, function(x) {
  x <- SCTransform(x, verbose = FALSE)
  # 🔴 Store top 3000 variable features explicitly
  VariableFeatures(x) <- head(VariableFeatures(x), 3000)
  return(x)
})

# Run PCA on each SCT-normalized subset (required for RPCA)
ref_list <- lapply(ref_list, function(x) {
  x <- RunPCA(x, assay = "SCT", verbose = FALSE)
  return(x)
})

# Select integration features
ref_features <- SelectIntegrationFeatures(object.list = ref_list, nfeatures = 3000)

# 🔴 REMOVE TCR/TRAV/TRBV GENES FROM INTEGRATION FEATURES
ref_features <- ref_features[!grepl("^TRBV|^TRAV", ref_features)]  # 🔴 CHANGE

# Prepare SCT integration
ref_list <- PrepSCTIntegration(object.list = ref_list, anchor.features = ref_features)

  |                                                  | 0 % ~calculating  
  |+++++++++++++++++++++++++                         | 50% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=02s  
# Find integration anchors using RPCA reduction
ref_anchors <- FindIntegrationAnchors(
  object.list = ref_list,
  anchor.features = ref_features,
  normalization.method = "SCT",
  reduction = "rpca"
)

  |                                                  | 0 % ~calculating  
  |+++++++++++++++++++++++++                         | 50% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=02s  

  |                                                  | 0 % ~calculating  
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=04s  
# Integrate data
reference_integrated <- IntegrateData(anchorset = ref_anchors, normalization.method = "SCT")
[1] 1
[1] 2
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
# 🔴 Store SCT variable features explicitly inside object
VariableFeatures(reference_integrated) <- ref_features   # 🔴 IMPORTANT CHANGE

# 🔴 Set default assay to SCT for mapping L1 later
DefaultAssay(reference_integrated) <- "SCT"  # 🔴 CHANGE

3. Clustering & Dimensionality Reduction

reference_integrated <- FindClusters(reference_integrated, resolution = 0.2)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 8610
Number of edges: 291335

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.9143
Number of communities: 6
Elapsed time: 0 seconds
ElbowPlot(reference_integrated, ndims = 50)


# Visualize UMAP colored by original donor (cell_line)
DimPlot(reference_integrated, group.by = "cell_line", reduction = "umap") +
  ggtitle("UMAP of Integrated CD4⁺ T Cells")


# Visualize UMAP colored by original donor (cell_line)
DimPlot(reference_integrated, group.by = "SCT_snn_res.0.2", reduction = "umap") +
  ggtitle("UMAP of Integrated CD4⁺ T Cells")


# Visualize UMAP colored by original donor (cell_line)
DimPlot(reference_integrated, group.by = "Prediction", reduction = "umap") +
  ggtitle("UMAP of Integrated CD4⁺ T Cells")


# Visualize UMAP colored by original donor (cell_line)
DimPlot(reference_integrated, group.by = "predicted.celltype.l2", reduction = "umap") +
  ggtitle("UMAP of Integrated CD4⁺ T Cells")

Save the mapped query object (Sézary cell lines projected onto reference trajectory):



saveRDS(reference_integrated, file = "sezary_cell_lines_mapped_to_cd4_reference_integrated_before_Monocle3_03-09-2025.rds")

FeaturePlots


library(Seurat)
library(ggplot2)
library(patchwork)

# ---- Define marker lists for differentiation states ----
marker_list <- list(
  Tnaive = c("CCR7","SELL","LEF1","TCF7","IL7R","CD27"),
  Tcm    = c("CCR7","SELL","CD27","IL7R","BCL2","TCF7"),
  Tem    = c("CCR6","CXCR3","GZMK","PRF1","IFNG","CD45RO"),
  Temra  = c("GZMB","PRF1","KLRG1","CX3CR1","CD45RA"),
  Tex    = c("PDCD1","CTLA4","LAG3","TIGIT","TOX","ENTPD1"),
  CD4CTL = c("GZMB","PRF1","NKG7","KLRG1","CX3CR1") # CD4 cytotoxic markers
)

# ---- Keep only markers present in the dataset ----
marker_list <- lapply(marker_list, function(x) x[x %in% rownames(reference_integrated)])

# ---- Compute module scores one by one ----
for (state in names(marker_list)) {
  reference_integrated <- AddModuleScore(
    reference_integrated,
    features = list(marker_list[[state]]),
    name = state
  )
}

# Module scores are named Tnaive1, Tcm1, Tem1, Temra1, Tex1, CD4CTL1

# ---- Plot module scores individually with lightblue → red gradient and labels ----
plots <- lapply(names(marker_list), function(state) {
  FeaturePlot(
    reference_integrated,
    features = paste0(state,"1"),
    reduction = "umap",
    cols = c("lightblue","red"),
    label = TRUE
  ) + ggtitle(paste(state, "Markers")) + theme(plot.title = element_text(hjust = 0.5))
})

# ---- Display all plots in a grid ----
wrap_plots(plots, ncol = 3)

FeaturePlots

# ---- Load libraries ----
library(Seurat)
library(ggplot2)
library(patchwork)

# ---- Define markers for differentiation states ----
tnaive_markers <- c("CCR7", "SELL", "LEF1", "TCF7", "IL7R", "CD27", "CD45RA")
tcm_markers    <- c("CCR7", "SELL", "CD45RO", "IL7R", "CD27")
tem_markers    <- c("CCR6", "CXCR3", "GZMK", "PRF1", "IFNG", "CD45RO")
temra_markers  <- c("GZMB", "PRF1", "KLRG1", "CX3CR1", "CD45RA")
tex_markers    <- c("PDCD1", "CTLA4", "LAG3", "TIGIT", "TOX", "ENTPD1")
cd4ctl_markers <- c("GZMB", "PRF1", "NKG7", "KLRG1", "CX3CR1")  # CD4 cytotoxic markers

# ---- Keep only markers present in the dataset ----
tnaive_markers <- tnaive_markers[tnaive_markers %in% rownames(reference_integrated)]
tcm_markers    <- tcm_markers[tcm_markers %in% rownames(reference_integrated)]
tem_markers    <- tem_markers[tem_markers %in% rownames(reference_integrated)]
temra_markers  <- temra_markers[temra_markers %in% rownames(reference_integrated)]
tex_markers    <- tex_markers[tex_markers %in% rownames(reference_integrated)]
cd4ctl_markers <- cd4ctl_markers[cd4ctl_markers %in% rownames(reference_integrated)]

# ---- Function to generate patchwork feature plots ----
plot_markers_grid <- function(marker_vector, state_name) {
  plots <- lapply(marker_vector, function(gene){
    FeaturePlot(reference_integrated, features = gene, reduction = "umap",
                cols = c("lightblue", "red"), label = TRUE) +
      theme(plot.title = element_text(hjust = 0.5))
  })
  wrap_plots(plots) + plot_annotation(title = paste(state_name, "Marker Expression"))
}

# ---- Generate grids for each state ----
tnaive_plot <- plot_markers_grid(tnaive_markers, "Tnaive")
tcm_plot    <- plot_markers_grid(tcm_markers, "Tcm")
tem_plot    <- plot_markers_grid(tem_markers, "Tem")
temra_plot  <- plot_markers_grid(temra_markers, "Temra")
tex_plot    <- plot_markers_grid(tex_markers, "Tex")
cd4ctl_plot <- plot_markers_grid(cd4ctl_markers, "CD4 CTL")

# ---- Display plots ----
tnaive_plot

tcm_plot

tem_plot

temra_plot

tex_plot

cd4ctl_plot


# ---- Compute module scores for each state ----
reference_integrated <- AddModuleScore(reference_integrated, features = list(tnaive_markers), name = "Tnaive_Score")
reference_integrated <- AddModuleScore(reference_integrated, features = list(tcm_markers), name = "Tcm_Score")
reference_integrated <- AddModuleScore(reference_integrated, features = list(tem_markers), name = "Tem_Score")
reference_integrated <- AddModuleScore(reference_integrated, features = list(temra_markers), name = "Temra_Score")
reference_integrated <- AddModuleScore(reference_integrated, features = list(tex_markers), name = "Tex_Score")
reference_integrated <- AddModuleScore(reference_integrated, features = list(cd4ctl_markers), name = "CD4CTL_Score")

# ---- FeaturePlot for module scores ----
score_plots <- list(
  FeaturePlot(reference_integrated, features = "Tnaive_Score1", reduction = "umap", cols = c("lightblue","red"), label = TRUE) + ggtitle("Tnaive Module Score") + theme(plot.title = element_text(hjust=0.5)),
  FeaturePlot(reference_integrated, features = "Tcm_Score1", reduction = "umap", cols = c("lightblue","red"), label = TRUE) + ggtitle("Tcm Module Score") + theme(plot.title = element_text(hjust=0.5)),
  FeaturePlot(reference_integrated, features = "Tem_Score1", reduction = "umap", cols = c("lightblue","red"), label = TRUE) + ggtitle("Tem Module Score") + theme(plot.title = element_text(hjust=0.5)),
  FeaturePlot(reference_integrated, features = "Temra_Score1", reduction = "umap", cols = c("lightblue","red"), label = TRUE) + ggtitle("Temra Module Score") + theme(plot.title = element_text(hjust=0.5)),
  FeaturePlot(reference_integrated, features = "Tex_Score1", reduction = "umap", cols = c("lightblue","red"), label = TRUE) + ggtitle("Tex Module Score") + theme(plot.title = element_text(hjust=0.5)),
  FeaturePlot(reference_integrated, features = "CD4CTL_Score1", reduction = "umap", cols = c("lightblue","red"), label = TRUE) + ggtitle("CD4 CTL Module Score") + theme(plot.title = element_text(hjust=0.5))
)

wrap_plots(score_plots, ncol = 2)

NA
NA

Save the mapped query object (Sézary cell lines projected onto reference trajectory):



saveRDS(reference_integrated, file = "sezary_cell_lines_mapped_to_cd4_reference_integrated_before_Monocle3_03-09-2025.rds")

4. Trajectory and Pseudotime with Monocle3

library(monocle3)
library(SeuratWrappers)
library(Matrix)

cds <- as.cell_data_set(reference_integrated)
cds <- cluster_cells(cds, reduction_method = "UMAP")
cds <- learn_graph(cds, use_partition = TRUE)

  |                                                                                                            
  |                                                                                                      |   0%
  |                                                                                                            
  |======================================================================================================| 100%
naive_markers <- c("CCR7", "SELL", "LEF1", "TCF7", "CD45RA", "PTPRC")
naive_markers <- naive_markers[naive_markers %in% rownames(cds)]

# Extract log-normalized expression or fallback to counts log-transformed
if("logcounts" %in% assayNames(cds)) {
  expr_mat <- assay(cds, "logcounts")
} else {
  expr_mat <- log1p(assay(cds, "counts"))
}

naive_score <- Matrix::colMeans(expr_mat[naive_markers, , drop = FALSE])
threshold <- quantile(naive_score, 0.95)
root_cells <- names(naive_score[naive_score > threshold])

cds <- order_cells(cds, root_cells = root_cells)
reference_integrated$pseudotime <- pseudotime(cds)

plot_cells(cds, color_cells_by = "pseudotime", show_trajectory_graph = TRUE)


# Visualize UMAP colored by original donor (cell_line)
DimPlot(reference_integrated, group.by = "Prediction", reduction = "umap") +
  ggtitle("UMAP of Integrated CD4⁺ T Cells")


# Visualize UMAP colored by original donor (cell_line)
DimPlot(reference_integrated, group.by = "predicted.celltype.l2", reduction = "umap") +
  ggtitle("UMAP of Integrated CD4⁺ T Cells")

Save the mapped query object (Sézary cell lines projected onto reference trajectory):



saveRDS(reference_integrated, file = "sezary_cell_lines_mapped_to_cd4_reference_integrated_before_Query_Projection_03-09-2025.rds")
Ci0tLQp0aXRsZTogIlN0ZXAxOkludGVncmF0aW9uIG9mIG5vcm1hbCBDRDRUY2VsbHMgdG8gcHJvamVjdCBMMSIKYXV0aG9yOiBOYXNpciBNYWhtb29kIEFiYmFzaQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICAjcm1kZm9ybWF0czo6cmVhZHRoZWRvd24KICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRvY19jb2xsYXBzZWQ6IHRydWUKLS0tCgoKCiMjIGxvYWQgbGlicmFyaWVzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQoKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkobW9ub2NsZTMpCmxpYnJhcnkoaGFybW9ueSkKCgojIEV4dHJhIGxpYnJhcmllcwpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHBoZWF0bWFwKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoU0NwdWJyKQoKYGBgCgoKIyMgUmVhZCBTZXVyYXQgb2JqZWN0IHdpdGggbG9hZCBhcyB5b3Ugc2F2ZSBpdCB3aXRoIHNhdmUoKSBmdW5jdGlvbgpgYGB7ciBsb2FkU2V1cmF0fQoKQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIHJlYWRSRFMoIi4uLy4uLzAtU2V1cmF0X1JEU19PQkpFQ1RfRklOQUwvQWxsX3NhbXBsZXNfTWVyZ2VkX3dpdGhfU1RDQVRfYW5kX3JlbmFtZWRfRklOQUwucmRzIikKCgoKCmBgYAoKIyAxLiBTdWJzZXQgTm9ybWFsIENENOKBuiBUIENlbGxzIGZvciBSZWZlcmVuY2UKYGBge3J9CgojIFN1YnNldCBub3JtYWwgQ0Q0KyBUIGNlbGxzIGZyb20gbWVyZ2VkIG9iamVjdApyZWZlcmVuY2VfY2Q0IDwtIHN1YnNldCgKICBBbGxfc2FtcGxlc19NZXJnZWQsCiAgc3Vic2V0ID0gY2VsbF9saW5lICVpbiUgYygiQ0Q0VGNlbGxzX2xhYiIsICJDRDRUY2VsbHNfMTB4IikKKQoKCkRlZmF1bHRBc3NheShyZWZlcmVuY2VfY2Q0KSA8LSAiUk5BIiAgCmBgYAoKIyAyLiBOb3JtYWxpemUgJiBJbnRlZ3JhdGUgUmVmZXJlbmNlIChBY2NvbW1vZGF0ZSBNdWx0aXBsZSBEb25vcnMpCmBgYHtyfQoKcmVmX2xpc3QgPC0gU3BsaXRPYmplY3QocmVmZXJlbmNlX2NkNCwgc3BsaXQuYnkgPSAiY2VsbF9saW5lIikKCiMg8J+UtCBSdW4gU0NUcmFuc2Zvcm0gb24gZWFjaCBzdWJzZXQgdG8gZW5zdXJlIGNvbnNpc3RlbnQgdmFyaWFibGUgZmVhdHVyZXMKcmVmX2xpc3QgPC0gbGFwcGx5KHJlZl9saXN0LCBmdW5jdGlvbih4KSB7CiAgeCA8LSBTQ1RyYW5zZm9ybSh4LCB2ZXJib3NlID0gRkFMU0UpCiAgIyDwn5S0IFN0b3JlIHRvcCAzMDAwIHZhcmlhYmxlIGZlYXR1cmVzIGV4cGxpY2l0bHkKICBWYXJpYWJsZUZlYXR1cmVzKHgpIDwtIGhlYWQoVmFyaWFibGVGZWF0dXJlcyh4KSwgMzAwMCkKICByZXR1cm4oeCkKfSkKCiMgUnVuIFBDQSBvbiBlYWNoIFNDVC1ub3JtYWxpemVkIHN1YnNldCAocmVxdWlyZWQgZm9yIFJQQ0EpCnJlZl9saXN0IDwtIGxhcHBseShyZWZfbGlzdCwgZnVuY3Rpb24oeCkgewogIHggPC0gUnVuUENBKHgsIGFzc2F5ID0gIlNDVCIsIHZlcmJvc2UgPSBGQUxTRSkKICByZXR1cm4oeCkKfSkKCiMgU2VsZWN0IGludGVncmF0aW9uIGZlYXR1cmVzCnJlZl9mZWF0dXJlcyA8LSBTZWxlY3RJbnRlZ3JhdGlvbkZlYXR1cmVzKG9iamVjdC5saXN0ID0gcmVmX2xpc3QsIG5mZWF0dXJlcyA9IDMwMDApCgojIPCflLQgUkVNT1ZFIFRDUi9UUkFWL1RSQlYgR0VORVMgRlJPTSBJTlRFR1JBVElPTiBGRUFUVVJFUwpyZWZfZmVhdHVyZXMgPC0gcmVmX2ZlYXR1cmVzWyFncmVwbCgiXlRSQlZ8XlRSQVYiLCByZWZfZmVhdHVyZXMpXSAgIyDwn5S0IENIQU5HRQoKIyBQcmVwYXJlIFNDVCBpbnRlZ3JhdGlvbgpyZWZfbGlzdCA8LSBQcmVwU0NUSW50ZWdyYXRpb24ob2JqZWN0Lmxpc3QgPSByZWZfbGlzdCwgYW5jaG9yLmZlYXR1cmVzID0gcmVmX2ZlYXR1cmVzKQoKIyBGaW5kIGludGVncmF0aW9uIGFuY2hvcnMgdXNpbmcgUlBDQSByZWR1Y3Rpb24KcmVmX2FuY2hvcnMgPC0gRmluZEludGVncmF0aW9uQW5jaG9ycygKICBvYmplY3QubGlzdCA9IHJlZl9saXN0LAogIGFuY2hvci5mZWF0dXJlcyA9IHJlZl9mZWF0dXJlcywKICBub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJTQ1QiLAogIHJlZHVjdGlvbiA9ICJycGNhIgopCgojIEludGVncmF0ZSBkYXRhCnJlZmVyZW5jZV9pbnRlZ3JhdGVkIDwtIEludGVncmF0ZURhdGEoYW5jaG9yc2V0ID0gcmVmX2FuY2hvcnMsIG5vcm1hbGl6YXRpb24ubWV0aG9kID0gIlNDVCIpCgojIPCflLQgU3RvcmUgU0NUIHZhcmlhYmxlIGZlYXR1cmVzIGV4cGxpY2l0bHkgaW5zaWRlIG9iamVjdApWYXJpYWJsZUZlYXR1cmVzKHJlZmVyZW5jZV9pbnRlZ3JhdGVkKSA8LSByZWZfZmVhdHVyZXMgICAjIPCflLQgSU1QT1JUQU5UIENIQU5HRQoKIyDwn5S0IFNldCBkZWZhdWx0IGFzc2F5IHRvIFNDVCBmb3IgbWFwcGluZyBMMSBsYXRlcgpEZWZhdWx0QXNzYXkocmVmZXJlbmNlX2ludGVncmF0ZWQpIDwtICJTQ1QiICAjIPCflLQgQ0hBTkdFCmBgYAoKCiMgMy4gQ2x1c3RlcmluZyAmIERpbWVuc2lvbmFsaXR5IFJlZHVjdGlvbgpgYGB7cn0KCiMg8J+UtCBFeHBsaWNpdGx5IHNldCB2YXJpYWJsZSBmZWF0dXJlcyBhZnRlciBpbnRlZ3JhdGlvbgpWYXJpYWJsZUZlYXR1cmVzKHJlZmVyZW5jZV9pbnRlZ3JhdGVkKSA8LSByZWZfZmVhdHVyZXMgICAjIPCflLQgSU1QT1JUQU5UIENIQU5HRQoKdmFyX2dlbmVzIDwtIFZhcmlhYmxlRmVhdHVyZXMocmVmZXJlbmNlX2ludGVncmF0ZWQpCgojIEV4Y2x1ZGUgSExBL1hJU1Qgb25seSBpZiBpdCBsZWF2ZXMgZW5vdWdoIGZlYXR1cmVzCmZpbHRlcmVkX3Zhcl9nZW5lcyA8LSB2YXJfZ2VuZXNbIWdyZXBsKCJeSExBLXxeWElTVCIsIHZhcl9nZW5lcyldCmlmKGxlbmd0aChmaWx0ZXJlZF92YXJfZ2VuZXMpIDwgMTAwMCl7CiAgd2FybmluZygiVG9vIGZldyBmZWF0dXJlcyBhZnRlciBmaWx0ZXJpbmcgSExBL1hJU1Q7IHVzaW5nIGFsbCB2YXJpYWJsZSBmZWF0dXJlcyBmb3IgUENBIikKICBmaWx0ZXJlZF92YXJfZ2VuZXMgPC0gdmFyX2dlbmVzCn0KCiMgUnVuIFBDQSB3aXRoIGZpbHRlcmVkIHZhcmlhYmxlIGZlYXR1cmVzCnJlZmVyZW5jZV9pbnRlZ3JhdGVkIDwtIFJ1blBDQShyZWZlcmVuY2VfaW50ZWdyYXRlZCwgZmVhdHVyZXMgPSBmaWx0ZXJlZF92YXJfZ2VuZXMsIHZlcmJvc2UgPSBGQUxTRSkKCgpyZWZlcmVuY2VfaW50ZWdyYXRlZCA8LSBSdW5VTUFQKHJlZmVyZW5jZV9pbnRlZ3JhdGVkLCBkaW1zID0gMToxOCkKcmVmZXJlbmNlX2ludGVncmF0ZWQgPC0gRmluZE5laWdoYm9ycyhyZWZlcmVuY2VfaW50ZWdyYXRlZCwgZGltcyA9IDE6MTgpCnJlZmVyZW5jZV9pbnRlZ3JhdGVkIDwtIEZpbmRDbHVzdGVycyhyZWZlcmVuY2VfaW50ZWdyYXRlZCwgcmVzb2x1dGlvbiA9IDAuMikKCkVsYm93UGxvdChyZWZlcmVuY2VfaW50ZWdyYXRlZCwgbmRpbXMgPSA1MCkKCiMgVmlzdWFsaXplIFVNQVAgY29sb3JlZCBieSBvcmlnaW5hbCBkb25vciAoY2VsbF9saW5lKQpEaW1QbG90KHJlZmVyZW5jZV9pbnRlZ3JhdGVkLCBncm91cC5ieSA9ICJjZWxsX2xpbmUiLCByZWR1Y3Rpb24gPSAidW1hcCIpICsKICBnZ3RpdGxlKCJVTUFQIG9mIEludGVncmF0ZWQgQ0Q04oG6IFQgQ2VsbHMiKQoKIyBWaXN1YWxpemUgVU1BUCBjb2xvcmVkIGJ5IG9yaWdpbmFsIGRvbm9yIChjZWxsX2xpbmUpCkRpbVBsb3QocmVmZXJlbmNlX2ludGVncmF0ZWQsIGdyb3VwLmJ5ID0gIlNDVF9zbm5fcmVzLjAuMiIsIHJlZHVjdGlvbiA9ICJ1bWFwIikgKwogIGdndGl0bGUoIlVNQVAgb2YgSW50ZWdyYXRlZCBDRDTigbogVCBDZWxscyIpCgojIFZpc3VhbGl6ZSBVTUFQIGNvbG9yZWQgYnkgb3JpZ2luYWwgZG9ub3IgKGNlbGxfbGluZSkKRGltUGxvdChyZWZlcmVuY2VfaW50ZWdyYXRlZCwgZ3JvdXAuYnkgPSAiUHJlZGljdGlvbiIsIHJlZHVjdGlvbiA9ICJ1bWFwIikgKwogIGdndGl0bGUoIlVNQVAgb2YgSW50ZWdyYXRlZCBDRDTigbogVCBDZWxscyIpCgojIFZpc3VhbGl6ZSBVTUFQIGNvbG9yZWQgYnkgb3JpZ2luYWwgZG9ub3IgKGNlbGxfbGluZSkKRGltUGxvdChyZWZlcmVuY2VfaW50ZWdyYXRlZCwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIiwgcmVkdWN0aW9uID0gInVtYXAiKSArCiAgZ2d0aXRsZSgiVU1BUCBvZiBJbnRlZ3JhdGVkIENENOKBuiBUIENlbGxzIikKCmBgYAojIyBTYXZlIHRoZSBtYXBwZWQgcXVlcnkgb2JqZWN0IChTw6l6YXJ5IGNlbGwgbGluZXMgcHJvamVjdGVkIG9udG8gcmVmZXJlbmNlIHRyYWplY3RvcnkpOgpgYGB7cn0KCgpzYXZlUkRTKHJlZmVyZW5jZV9pbnRlZ3JhdGVkLCBmaWxlID0gInNlemFyeV9jZWxsX2xpbmVzX21hcHBlZF90b19jZDRfcmVmZXJlbmNlX2ludGVncmF0ZWRfYmVmb3JlX01vbm9jbGUzXzAzLTA5LTIwMjUucmRzIikKCgpgYGAKCiMjIyBGZWF0dXJlUGxvdHMKYGBge3IsZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CgpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHBhdGNod29yaykKCiMgLS0tLSBEZWZpbmUgbWFya2VyIGxpc3RzIGZvciBkaWZmZXJlbnRpYXRpb24gc3RhdGVzIC0tLS0KbWFya2VyX2xpc3QgPC0gbGlzdCgKICBUbmFpdmUgPSBjKCJDQ1I3IiwiU0VMTCIsIkxFRjEiLCJUQ0Y3IiwiSUw3UiIsIkNEMjciKSwKICBUY20gICAgPSBjKCJDQ1I3IiwiU0VMTCIsIkNEMjciLCJJTDdSIiwiQkNMMiIsIlRDRjciKSwKICBUZW0gICAgPSBjKCJDQ1I2IiwiQ1hDUjMiLCJHWk1LIiwiUFJGMSIsIklGTkciLCJDRDQ1Uk8iKSwKICBUZW1yYSAgPSBjKCJHWk1CIiwiUFJGMSIsIktMUkcxIiwiQ1gzQ1IxIiwiQ0Q0NVJBIiksCiAgVGV4ICAgID0gYygiUERDRDEiLCJDVExBNCIsIkxBRzMiLCJUSUdJVCIsIlRPWCIsIkVOVFBEMSIpLAogIENENENUTCA9IGMoIkdaTUIiLCJQUkYxIiwiTktHNyIsIktMUkcxIiwiQ1gzQ1IxIikgIyBDRDQgY3l0b3RveGljIG1hcmtlcnMKKQoKIyAtLS0tIEtlZXAgb25seSBtYXJrZXJzIHByZXNlbnQgaW4gdGhlIGRhdGFzZXQgLS0tLQptYXJrZXJfbGlzdCA8LSBsYXBwbHkobWFya2VyX2xpc3QsIGZ1bmN0aW9uKHgpIHhbeCAlaW4lIHJvd25hbWVzKHJlZmVyZW5jZV9pbnRlZ3JhdGVkKV0pCgojIC0tLS0gQ29tcHV0ZSBtb2R1bGUgc2NvcmVzIG9uZSBieSBvbmUgLS0tLQpmb3IgKHN0YXRlIGluIG5hbWVzKG1hcmtlcl9saXN0KSkgewogIHJlZmVyZW5jZV9pbnRlZ3JhdGVkIDwtIEFkZE1vZHVsZVNjb3JlKAogICAgcmVmZXJlbmNlX2ludGVncmF0ZWQsCiAgICBmZWF0dXJlcyA9IGxpc3QobWFya2VyX2xpc3RbW3N0YXRlXV0pLAogICAgbmFtZSA9IHN0YXRlCiAgKQp9CgojIE1vZHVsZSBzY29yZXMgYXJlIG5hbWVkIFRuYWl2ZTEsIFRjbTEsIFRlbTEsIFRlbXJhMSwgVGV4MSwgQ0Q0Q1RMMQoKIyAtLS0tIFBsb3QgbW9kdWxlIHNjb3JlcyBpbmRpdmlkdWFsbHkgd2l0aCBsaWdodGJsdWUg4oaSIHJlZCBncmFkaWVudCBhbmQgbGFiZWxzIC0tLS0KcGxvdHMgPC0gbGFwcGx5KG5hbWVzKG1hcmtlcl9saXN0KSwgZnVuY3Rpb24oc3RhdGUpIHsKICBGZWF0dXJlUGxvdCgKICAgIHJlZmVyZW5jZV9pbnRlZ3JhdGVkLAogICAgZmVhdHVyZXMgPSBwYXN0ZTAoc3RhdGUsIjEiKSwKICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgIGNvbHMgPSBjKCJsaWdodGJsdWUiLCJyZWQiKSwKICAgIGxhYmVsID0gVFJVRQogICkgKyBnZ3RpdGxlKHBhc3RlKHN0YXRlLCAiTWFya2VycyIpKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQp9KQoKIyAtLS0tIERpc3BsYXkgYWxsIHBsb3RzIGluIGEgZ3JpZCAtLS0tCndyYXBfcGxvdHMocGxvdHMsIG5jb2wgPSAzKQoKYGBgCgoKIyMjIEZlYXR1cmVQbG90cwpgYGB7cixmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KIyAtLS0tIExvYWQgbGlicmFyaWVzIC0tLS0KbGlicmFyeShTZXVyYXQpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwYXRjaHdvcmspCgojIC0tLS0gRGVmaW5lIG1hcmtlcnMgZm9yIGRpZmZlcmVudGlhdGlvbiBzdGF0ZXMgLS0tLQp0bmFpdmVfbWFya2VycyA8LSBjKCJDQ1I3IiwgIlNFTEwiLCAiTEVGMSIsICJUQ0Y3IiwgIklMN1IiLCAiQ0QyNyIsICJDRDQ1UkEiKQp0Y21fbWFya2VycyAgICA8LSBjKCJDQ1I3IiwgIlNFTEwiLCAiQ0Q0NVJPIiwgIklMN1IiLCAiQ0QyNyIpCnRlbV9tYXJrZXJzICAgIDwtIGMoIkNDUjYiLCAiQ1hDUjMiLCAiR1pNSyIsICJQUkYxIiwgIklGTkciLCAiQ0Q0NVJPIikKdGVtcmFfbWFya2VycyAgPC0gYygiR1pNQiIsICJQUkYxIiwgIktMUkcxIiwgIkNYM0NSMSIsICJDRDQ1UkEiKQp0ZXhfbWFya2VycyAgICA8LSBjKCJQRENEMSIsICJDVExBNCIsICJMQUczIiwgIlRJR0lUIiwgIlRPWCIsICJFTlRQRDEiKQpjZDRjdGxfbWFya2VycyA8LSBjKCJHWk1CIiwgIlBSRjEiLCAiTktHNyIsICJLTFJHMSIsICJDWDNDUjEiKSAgIyBDRDQgY3l0b3RveGljIG1hcmtlcnMKCiMgLS0tLSBLZWVwIG9ubHkgbWFya2VycyBwcmVzZW50IGluIHRoZSBkYXRhc2V0IC0tLS0KdG5haXZlX21hcmtlcnMgPC0gdG5haXZlX21hcmtlcnNbdG5haXZlX21hcmtlcnMgJWluJSByb3duYW1lcyhyZWZlcmVuY2VfaW50ZWdyYXRlZCldCnRjbV9tYXJrZXJzICAgIDwtIHRjbV9tYXJrZXJzW3RjbV9tYXJrZXJzICVpbiUgcm93bmFtZXMocmVmZXJlbmNlX2ludGVncmF0ZWQpXQp0ZW1fbWFya2VycyAgICA8LSB0ZW1fbWFya2Vyc1t0ZW1fbWFya2VycyAlaW4lIHJvd25hbWVzKHJlZmVyZW5jZV9pbnRlZ3JhdGVkKV0KdGVtcmFfbWFya2VycyAgPC0gdGVtcmFfbWFya2Vyc1t0ZW1yYV9tYXJrZXJzICVpbiUgcm93bmFtZXMocmVmZXJlbmNlX2ludGVncmF0ZWQpXQp0ZXhfbWFya2VycyAgICA8LSB0ZXhfbWFya2Vyc1t0ZXhfbWFya2VycyAlaW4lIHJvd25hbWVzKHJlZmVyZW5jZV9pbnRlZ3JhdGVkKV0KY2Q0Y3RsX21hcmtlcnMgPC0gY2Q0Y3RsX21hcmtlcnNbY2Q0Y3RsX21hcmtlcnMgJWluJSByb3duYW1lcyhyZWZlcmVuY2VfaW50ZWdyYXRlZCldCgojIC0tLS0gRnVuY3Rpb24gdG8gZ2VuZXJhdGUgcGF0Y2h3b3JrIGZlYXR1cmUgcGxvdHMgLS0tLQpwbG90X21hcmtlcnNfZ3JpZCA8LSBmdW5jdGlvbihtYXJrZXJfdmVjdG9yLCBzdGF0ZV9uYW1lKSB7CiAgcGxvdHMgPC0gbGFwcGx5KG1hcmtlcl92ZWN0b3IsIGZ1bmN0aW9uKGdlbmUpewogICAgRmVhdHVyZVBsb3QocmVmZXJlbmNlX2ludGVncmF0ZWQsIGZlYXR1cmVzID0gZ2VuZSwgcmVkdWN0aW9uID0gInVtYXAiLAogICAgICAgICAgICAgICAgY29scyA9IGMoImxpZ2h0Ymx1ZSIsICJyZWQiKSwgbGFiZWwgPSBUUlVFKSArCiAgICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQogIH0pCiAgd3JhcF9wbG90cyhwbG90cykgKyBwbG90X2Fubm90YXRpb24odGl0bGUgPSBwYXN0ZShzdGF0ZV9uYW1lLCAiTWFya2VyIEV4cHJlc3Npb24iKSkKfQoKIyAtLS0tIEdlbmVyYXRlIGdyaWRzIGZvciBlYWNoIHN0YXRlIC0tLS0KdG5haXZlX3Bsb3QgPC0gcGxvdF9tYXJrZXJzX2dyaWQodG5haXZlX21hcmtlcnMsICJUbmFpdmUiKQp0Y21fcGxvdCAgICA8LSBwbG90X21hcmtlcnNfZ3JpZCh0Y21fbWFya2VycywgIlRjbSIpCnRlbV9wbG90ICAgIDwtIHBsb3RfbWFya2Vyc19ncmlkKHRlbV9tYXJrZXJzLCAiVGVtIikKdGVtcmFfcGxvdCAgPC0gcGxvdF9tYXJrZXJzX2dyaWQodGVtcmFfbWFya2VycywgIlRlbXJhIikKdGV4X3Bsb3QgICAgPC0gcGxvdF9tYXJrZXJzX2dyaWQodGV4X21hcmtlcnMsICJUZXgiKQpjZDRjdGxfcGxvdCA8LSBwbG90X21hcmtlcnNfZ3JpZChjZDRjdGxfbWFya2VycywgIkNENCBDVEwiKQoKIyAtLS0tIERpc3BsYXkgcGxvdHMgLS0tLQp0bmFpdmVfcGxvdAp0Y21fcGxvdAp0ZW1fcGxvdAp0ZW1yYV9wbG90CnRleF9wbG90CmNkNGN0bF9wbG90CgojIC0tLS0gQ29tcHV0ZSBtb2R1bGUgc2NvcmVzIGZvciBlYWNoIHN0YXRlIC0tLS0KcmVmZXJlbmNlX2ludGVncmF0ZWQgPC0gQWRkTW9kdWxlU2NvcmUocmVmZXJlbmNlX2ludGVncmF0ZWQsIGZlYXR1cmVzID0gbGlzdCh0bmFpdmVfbWFya2VycyksIG5hbWUgPSAiVG5haXZlX1Njb3JlIikKcmVmZXJlbmNlX2ludGVncmF0ZWQgPC0gQWRkTW9kdWxlU2NvcmUocmVmZXJlbmNlX2ludGVncmF0ZWQsIGZlYXR1cmVzID0gbGlzdCh0Y21fbWFya2VycyksIG5hbWUgPSAiVGNtX1Njb3JlIikKcmVmZXJlbmNlX2ludGVncmF0ZWQgPC0gQWRkTW9kdWxlU2NvcmUocmVmZXJlbmNlX2ludGVncmF0ZWQsIGZlYXR1cmVzID0gbGlzdCh0ZW1fbWFya2VycyksIG5hbWUgPSAiVGVtX1Njb3JlIikKcmVmZXJlbmNlX2ludGVncmF0ZWQgPC0gQWRkTW9kdWxlU2NvcmUocmVmZXJlbmNlX2ludGVncmF0ZWQsIGZlYXR1cmVzID0gbGlzdCh0ZW1yYV9tYXJrZXJzKSwgbmFtZSA9ICJUZW1yYV9TY29yZSIpCnJlZmVyZW5jZV9pbnRlZ3JhdGVkIDwtIEFkZE1vZHVsZVNjb3JlKHJlZmVyZW5jZV9pbnRlZ3JhdGVkLCBmZWF0dXJlcyA9IGxpc3QodGV4X21hcmtlcnMpLCBuYW1lID0gIlRleF9TY29yZSIpCnJlZmVyZW5jZV9pbnRlZ3JhdGVkIDwtIEFkZE1vZHVsZVNjb3JlKHJlZmVyZW5jZV9pbnRlZ3JhdGVkLCBmZWF0dXJlcyA9IGxpc3QoY2Q0Y3RsX21hcmtlcnMpLCBuYW1lID0gIkNENENUTF9TY29yZSIpCgojIC0tLS0gRmVhdHVyZVBsb3QgZm9yIG1vZHVsZSBzY29yZXMgLS0tLQpzY29yZV9wbG90cyA8LSBsaXN0KAogIEZlYXR1cmVQbG90KHJlZmVyZW5jZV9pbnRlZ3JhdGVkLCBmZWF0dXJlcyA9ICJUbmFpdmVfU2NvcmUxIiwgcmVkdWN0aW9uID0gInVtYXAiLCBjb2xzID0gYygibGlnaHRibHVlIiwicmVkIiksIGxhYmVsID0gVFJVRSkgKyBnZ3RpdGxlKCJUbmFpdmUgTW9kdWxlIFNjb3JlIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0PTAuNSkpLAogIEZlYXR1cmVQbG90KHJlZmVyZW5jZV9pbnRlZ3JhdGVkLCBmZWF0dXJlcyA9ICJUY21fU2NvcmUxIiwgcmVkdWN0aW9uID0gInVtYXAiLCBjb2xzID0gYygibGlnaHRibHVlIiwicmVkIiksIGxhYmVsID0gVFJVRSkgKyBnZ3RpdGxlKCJUY20gTW9kdWxlIFNjb3JlIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0PTAuNSkpLAogIEZlYXR1cmVQbG90KHJlZmVyZW5jZV9pbnRlZ3JhdGVkLCBmZWF0dXJlcyA9ICJUZW1fU2NvcmUxIiwgcmVkdWN0aW9uID0gInVtYXAiLCBjb2xzID0gYygibGlnaHRibHVlIiwicmVkIiksIGxhYmVsID0gVFJVRSkgKyBnZ3RpdGxlKCJUZW0gTW9kdWxlIFNjb3JlIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0PTAuNSkpLAogIEZlYXR1cmVQbG90KHJlZmVyZW5jZV9pbnRlZ3JhdGVkLCBmZWF0dXJlcyA9ICJUZW1yYV9TY29yZTEiLCByZWR1Y3Rpb24gPSAidW1hcCIsIGNvbHMgPSBjKCJsaWdodGJsdWUiLCJyZWQiKSwgbGFiZWwgPSBUUlVFKSArIGdndGl0bGUoIlRlbXJhIE1vZHVsZSBTY29yZSIpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdD0wLjUpKSwKICBGZWF0dXJlUGxvdChyZWZlcmVuY2VfaW50ZWdyYXRlZCwgZmVhdHVyZXMgPSAiVGV4X1Njb3JlMSIsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgY29scyA9IGMoImxpZ2h0Ymx1ZSIsInJlZCIpLCBsYWJlbCA9IFRSVUUpICsgZ2d0aXRsZSgiVGV4IE1vZHVsZSBTY29yZSIpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdD0wLjUpKSwKICBGZWF0dXJlUGxvdChyZWZlcmVuY2VfaW50ZWdyYXRlZCwgZmVhdHVyZXMgPSAiQ0Q0Q1RMX1Njb3JlMSIsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgY29scyA9IGMoImxpZ2h0Ymx1ZSIsInJlZCIpLCBsYWJlbCA9IFRSVUUpICsgZ2d0aXRsZSgiQ0Q0IENUTCBNb2R1bGUgU2NvcmUiKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3Q9MC41KSkKKQoKd3JhcF9wbG90cyhzY29yZV9wbG90cywgbmNvbCA9IDIpCgoKYGBgCiMjIFNhdmUgdGhlIG1hcHBlZCBxdWVyeSBvYmplY3QgKFPDqXphcnkgY2VsbCBsaW5lcyBwcm9qZWN0ZWQgb250byByZWZlcmVuY2UgdHJhamVjdG9yeSk6CmBgYHtyfQoKCnNhdmVSRFMocmVmZXJlbmNlX2ludGVncmF0ZWQsIGZpbGUgPSAic2V6YXJ5X2NlbGxfbGluZXNfbWFwcGVkX3RvX2NkNF9yZWZlcmVuY2VfaW50ZWdyYXRlZF9iZWZvcmVfTW9ub2NsZTNfMDMtMDktMjAyNS5yZHMiKQoKCmBgYAoKIyA0LiBUcmFqZWN0b3J5IGFuZCBQc2V1ZG90aW1lIHdpdGggTW9ub2NsZTMKYGBge3J9CmxpYnJhcnkobW9ub2NsZTMpCmxpYnJhcnkoU2V1cmF0V3JhcHBlcnMpCmxpYnJhcnkoTWF0cml4KQoKY2RzIDwtIGFzLmNlbGxfZGF0YV9zZXQocmVmZXJlbmNlX2ludGVncmF0ZWQpCmNkcyA8LSBjbHVzdGVyX2NlbGxzKGNkcywgcmVkdWN0aW9uX21ldGhvZCA9ICJVTUFQIikKY2RzIDwtIGxlYXJuX2dyYXBoKGNkcywgdXNlX3BhcnRpdGlvbiA9IFRSVUUpCgpuYWl2ZV9tYXJrZXJzIDwtIGMoIkNDUjciLCAiU0VMTCIsICJMRUYxIiwgIlRDRjciLCAiQ0Q0NVJBIiwgIlBUUFJDIikKbmFpdmVfbWFya2VycyA8LSBuYWl2ZV9tYXJrZXJzW25haXZlX21hcmtlcnMgJWluJSByb3duYW1lcyhjZHMpXQoKIyBFeHRyYWN0IGxvZy1ub3JtYWxpemVkIGV4cHJlc3Npb24gb3IgZmFsbGJhY2sgdG8gY291bnRzIGxvZy10cmFuc2Zvcm1lZAppZigibG9nY291bnRzIiAlaW4lIGFzc2F5TmFtZXMoY2RzKSkgewogIGV4cHJfbWF0IDwtIGFzc2F5KGNkcywgImxvZ2NvdW50cyIpCn0gZWxzZSB7CiAgZXhwcl9tYXQgPC0gbG9nMXAoYXNzYXkoY2RzLCAiY291bnRzIikpCn0KCm5haXZlX3Njb3JlIDwtIE1hdHJpeDo6Y29sTWVhbnMoZXhwcl9tYXRbbmFpdmVfbWFya2VycywgLCBkcm9wID0gRkFMU0VdKQp0aHJlc2hvbGQgPC0gcXVhbnRpbGUobmFpdmVfc2NvcmUsIDAuOTUpCnJvb3RfY2VsbHMgPC0gbmFtZXMobmFpdmVfc2NvcmVbbmFpdmVfc2NvcmUgPiB0aHJlc2hvbGRdKQoKY2RzIDwtIG9yZGVyX2NlbGxzKGNkcywgcm9vdF9jZWxscyA9IHJvb3RfY2VsbHMpCnJlZmVyZW5jZV9pbnRlZ3JhdGVkJHBzZXVkb3RpbWUgPC0gcHNldWRvdGltZShjZHMpCgpwbG90X2NlbGxzKGNkcywgY29sb3JfY2VsbHNfYnkgPSAicHNldWRvdGltZSIsIHNob3dfdHJhamVjdG9yeV9ncmFwaCA9IFRSVUUpCgojIFZpc3VhbGl6ZSBVTUFQIGNvbG9yZWQgYnkgb3JpZ2luYWwgZG9ub3IgKGNlbGxfbGluZSkKRGltUGxvdChyZWZlcmVuY2VfaW50ZWdyYXRlZCwgZ3JvdXAuYnkgPSAiUHJlZGljdGlvbiIsIHJlZHVjdGlvbiA9ICJ1bWFwIikgKwogIGdndGl0bGUoIlVNQVAgb2YgSW50ZWdyYXRlZCBDRDTigbogVCBDZWxscyIpCgojIFZpc3VhbGl6ZSBVTUFQIGNvbG9yZWQgYnkgb3JpZ2luYWwgZG9ub3IgKGNlbGxfbGluZSkKRGltUGxvdChyZWZlcmVuY2VfaW50ZWdyYXRlZCwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIiwgcmVkdWN0aW9uID0gInVtYXAiKSArCiAgZ2d0aXRsZSgiVU1BUCBvZiBJbnRlZ3JhdGVkIENENOKBuiBUIENlbGxzIikKCmBgYAoKIyMgU2F2ZSB0aGUgbWFwcGVkIHF1ZXJ5IG9iamVjdCAoU8OpemFyeSBjZWxsIGxpbmVzIHByb2plY3RlZCBvbnRvIHJlZmVyZW5jZSB0cmFqZWN0b3J5KToKYGBge3J9CgoKc2F2ZVJEUyhyZWZlcmVuY2VfaW50ZWdyYXRlZCwgZmlsZSA9ICJzZXphcnlfY2VsbF9saW5lc19tYXBwZWRfdG9fY2Q0X3JlZmVyZW5jZV9pbnRlZ3JhdGVkX2JlZm9yZV9RdWVyeV9Qcm9qZWN0aW9uXzAzLTA5LTIwMjUucmRzIikKCgpgYGAKCg==