load libraries

1. Load monocle Object



cds <- readRDS("../cds_checkpoint_2/cds_object.rds")

2. Visualization of Trajectory


p1 <- plot_cells(cds,
                color_cells_by = "pseudotime",
                label_cell_groups = FALSE,
                label_leaves = FALSE,
                label_branch_points = FALSE,
                graph_label_size = 1.5)

p1


p2 <- plot_cells(cds,
                color_cells_by = "Patient_origin",
                label_cell_groups = FALSE,
                label_leaves = FALSE,
                label_branch_points = FALSE,
                graph_label_size = 1.5)

p2


p3 <- plot_cells(cds,
                color_cells_by = "orig.ident",
                label_cell_groups = FALSE,
                label_leaves = FALSE,
                label_branch_points = FALSE,
                graph_label_size = 1.5)

p3

3. Visualize Gene Expression Along Pseudotime


plot_genes_in_pseudotime(cds["CCR7", ])

plot_genes_in_pseudotime(cds["SELL", ])

plot_genes_in_pseudotime(cds["LEF1", ])

plot_genes_in_pseudotime(cds["TCF7", ])


#Output tells you: how canonical naïve markers decline/shift across pseudotime.

Visualize Gene Expression Along Pseudotime

plot_genes_in_pseudotime(cds["CLIC1", ])

plot_genes_in_pseudotime(cds["YWHAH", ])

plot_genes_in_pseudotime(cds["TOX", ])

plot_genes_in_pseudotime(cds["TOX2", ])

plot_genes_in_pseudotime(cds["LAG3", ])

plot_genes_in_pseudotime(cds["FOXP3", ])

plot_genes_in_pseudotime(cds["IL2RA", ])

plot_genes_in_pseudotime(cds["GATA3", ])

plot_genes_in_pseudotime(cds["GATA2", ])

plot_genes_in_pseudotime(cds["IKZF2", ])

#Output tells you: how canonical naïve markers decline/shift across pseudotime.

Visualize Gene Expression Along Pseudotime

plot_genes_in_pseudotime(cds["STAT1", ])

plot_genes_in_pseudotime(cds["CXCR1", ])

plot_genes_in_pseudotime(cds["PIM2", ])

plot_genes_in_pseudotime(cds["KLF2", ])

plot_genes_in_pseudotime(cds["LGALS3", ])

plot_genes_in_pseudotime(cds["CCND2", ])

plot_genes_in_pseudotime(cds["PIM2", ])

plot_genes_in_pseudotime(cds["CD74", ])

plot_genes_in_pseudotime(cds["CD40", ])

plot_genes_in_pseudotime(cds["CD44", ])

plot_genes_in_pseudotime(cds["CD52", ])

plot_genes_in_pseudotime(cds["CD69", ])

plot_genes_in_pseudotime(cds["PRF1", ])

plot_genes_in_pseudotime(cds["GZMB", ])

plot_genes_in_pseudotime(cds["CD7", ])

plot_genes_in_pseudotime(cds["DPP4", ])

plot_genes_in_pseudotime(cds["CD28", ])

plot_genes_in_pseudotime(cds["CD27", ])

plot_genes_in_pseudotime(cds["CD8A", ])


#Output tells you: how canonical naïve markers decline/shift across pseudotime.

Visualize Gene Expression Along Pseudotime

marker_groups <- list(
  "CD4 Tex (Exhausted)" = c("TOX", "LAG3", "CTLA4", "TIGIT"),
  "CD4 Treg" = c("FOXP3", "IL2RA", "CTLA4", "IKZF2", "TIGIT"),
  "CD4 Tcm (Central Memory)" = c("CCR7", "SELL", "IL7R", "TCF7"),
  "CD4 Tn (Naive)" = c("CCR7", "SELL", "IL7R", "TCF7", "LEF1"),
  "CD4 Tem (Effector Memory)" = c("GZMB", "PRF1", "IFNG", "KLRG1"),
  "CD4 Trm (Tissue Resident)" = c("CD69", "CXCR6"),
  "CD4 Tc (Cytotoxic)" = c("PRF1", "GZMB", "NKG7", "GNLY"),
  "CD4 Tisg (IFN Signature)" = c("ISG15", "IFI6", "IFIT3", "MX1"),
  "CD4 Proliferation" = c("MKI67", "TOP2A"),
  "CD4 Th17" = c("STAT3", "AHR", "CCR6", "BATF"),
  "CD4 Temra (Effector Memory RA+)" = c("PTPRC", "GZMB"),
  "CD4 Tfh (Follicular Helper)" = c("BCL6", "ICOS"),
  "CD4 Tstr (Stress)" = c("HSPA1A", "ATF3"),
  "CD4 Activated" = c("IL2RA", "CD69", "HLA-DRA")
)

library(monocle3)
library(ggplot2)

# Flatten your marker_groups list to a single vector of unique genes
all_genes <- unique(unlist(marker_groups))

# Optional: check which genes are actually present in your cds
all_genes_present <- all_genes[all_genes %in% rownames(cds)]

# Loop over genes and plot
for (gene in all_genes_present) {
  print(plot_genes_in_pseudotime(cds[gene, ]) + ggtitle(gene))
}

Summarize Lineages and Cell Fate Branches

Visualize Gene Modules Along Pseudotime

Multi-Gene Pseudotime Plot with Facets

Multi-Gene Pseudotime Plot with Facets

Optional: Overlay CITE-seq Protein Expression

Pathway Enrichment of Top DEGs or Gene Modules

Branch Probability / Fate Bias

Explore Branch-Specific Differential Expression

Explore Branch-Specific Differential Expression

Explore Branch-Specific Differential Expression

Visualize Gene Modules Along Pseudotime

LS0tCnRpdGxlOiAiVHJhamVjdG9yeSBhbmFseXNpcyAoTW9ub2NsZTMpLUNoZWNrcG9pbnQyX29ud2FyZHMiCmF1dGhvcjogIk5hc2lyIE1haG1vb2QgQWJiYXNpIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMKICB3b3JkX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIGRmX3ByaW50OiBwYWdlZAogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Kb3B0aW9ucyhzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCnNldC5zZWVkKDEyMykKYGBgCgoKIyMgbG9hZCBsaWJyYXJpZXMKYGBge3IsIGluY2x1ZGU9RkFMU0V9CgpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShTaW5nbGVDZWxsRXhwZXJpbWVudCkKbGlicmFyeShNYXRyaXgpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoU0NwdWJyKQpsaWJyYXJ5KGNsdXN0ZXJQcm9maWxlcikKbGlicmFyeShvcmcuSHMuZWcuZGIpCmxpYnJhcnkoaWdyYXBoKQoKIyBMb2FkIEdlbm9tZUluZm9EYiAobmVlZGVkIGZvciBTZXFpbmZvKQpsaWJyYXJ5KEdlbm9tZUluZm9EYikKbGlicmFyeShtb25vY2xlMykKCmBgYAoKCiMgMS4gTG9hZCBtb25vY2xlIE9iamVjdCAKYGBge3J9CgoKY2RzIDwtIHJlYWRSRFMoIi4uL2Nkc19jaGVja3BvaW50XzIvY2RzX29iamVjdC5yZHMiKQoKYGBgCgoKIyAyLiBWaXN1YWxpemF0aW9uIG9mIFRyYWplY3RvcnkKYGBge3J9CgpwMSA8LSBwbG90X2NlbGxzKGNkcywKICAgICAgICAgICAgICAgIGNvbG9yX2NlbGxzX2J5ID0gInBzZXVkb3RpbWUiLAogICAgICAgICAgICAgICAgbGFiZWxfY2VsbF9ncm91cHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgIGxhYmVsX2xlYXZlcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgbGFiZWxfYnJhbmNoX3BvaW50cyA9IEZBTFNFLAogICAgICAgICAgICAgICAgZ3JhcGhfbGFiZWxfc2l6ZSA9IDEuNSkKCnAxCgpwMiA8LSBwbG90X2NlbGxzKGNkcywKICAgICAgICAgICAgICAgIGNvbG9yX2NlbGxzX2J5ID0gIlBhdGllbnRfb3JpZ2luIiwKICAgICAgICAgICAgICAgIGxhYmVsX2NlbGxfZ3JvdXBzID0gRkFMU0UsCiAgICAgICAgICAgICAgICBsYWJlbF9sZWF2ZXMgPSBGQUxTRSwKICAgICAgICAgICAgICAgIGxhYmVsX2JyYW5jaF9wb2ludHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgIGdyYXBoX2xhYmVsX3NpemUgPSAxLjUpCgpwMgoKcDMgPC0gcGxvdF9jZWxscyhjZHMsCiAgICAgICAgICAgICAgICBjb2xvcl9jZWxsc19ieSA9ICJvcmlnLmlkZW50IiwKICAgICAgICAgICAgICAgIGxhYmVsX2NlbGxfZ3JvdXBzID0gRkFMU0UsCiAgICAgICAgICAgICAgICBsYWJlbF9sZWF2ZXMgPSBGQUxTRSwKICAgICAgICAgICAgICAgIGxhYmVsX2JyYW5jaF9wb2ludHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgIGdyYXBoX2xhYmVsX3NpemUgPSAxLjUpCgpwMwpgYGAKCiMgMy4gVmlzdWFsaXplIEdlbmUgRXhwcmVzc2lvbiBBbG9uZyBQc2V1ZG90aW1lCmBgYHtyfQoKcGxvdF9nZW5lc19pbl9wc2V1ZG90aW1lKGNkc1siQ0NSNyIsIF0pCnBsb3RfZ2VuZXNfaW5fcHNldWRvdGltZShjZHNbIlNFTEwiLCBdKQpwbG90X2dlbmVzX2luX3BzZXVkb3RpbWUoY2RzWyJMRUYxIiwgXSkKcGxvdF9nZW5lc19pbl9wc2V1ZG90aW1lKGNkc1siVENGNyIsIF0pCgojT3V0cHV0IHRlbGxzIHlvdTogaG93IGNhbm9uaWNhbCBuYcOvdmUgbWFya2VycyBkZWNsaW5lL3NoaWZ0IGFjcm9zcyBwc2V1ZG90aW1lLgpgYGAKCgojIyBWaXN1YWxpemUgR2VuZSBFeHByZXNzaW9uIEFsb25nIFBzZXVkb3RpbWUKYGBge3J9CnBsb3RfZ2VuZXNfaW5fcHNldWRvdGltZShjZHNbIkNMSUMxIiwgXSkKcGxvdF9nZW5lc19pbl9wc2V1ZG90aW1lKGNkc1siWVdIQUgiLCBdKQpwbG90X2dlbmVzX2luX3BzZXVkb3RpbWUoY2RzWyJUT1giLCBdKQpwbG90X2dlbmVzX2luX3BzZXVkb3RpbWUoY2RzWyJUT1gyIiwgXSkKcGxvdF9nZW5lc19pbl9wc2V1ZG90aW1lKGNkc1siTEFHMyIsIF0pCnBsb3RfZ2VuZXNfaW5fcHNldWRvdGltZShjZHNbIkZPWFAzIiwgXSkKcGxvdF9nZW5lc19pbl9wc2V1ZG90aW1lKGNkc1siSUwyUkEiLCBdKQpwbG90X2dlbmVzX2luX3BzZXVkb3RpbWUoY2RzWyJHQVRBMyIsIF0pCnBsb3RfZ2VuZXNfaW5fcHNldWRvdGltZShjZHNbIkdBVEEyIiwgXSkKcGxvdF9nZW5lc19pbl9wc2V1ZG90aW1lKGNkc1siSUtaRjIiLCBdKQojT3V0cHV0IHRlbGxzIHlvdTogaG93IGNhbm9uaWNhbCBuYcOvdmUgbWFya2VycyBkZWNsaW5lL3NoaWZ0IGFjcm9zcyBwc2V1ZG90aW1lLgoKYGBgCgojIyBWaXN1YWxpemUgR2VuZSBFeHByZXNzaW9uIEFsb25nIFBzZXVkb3RpbWUKYGBge3J9CnBsb3RfZ2VuZXNfaW5fcHNldWRvdGltZShjZHNbIlNUQVQxIiwgXSkKcGxvdF9nZW5lc19pbl9wc2V1ZG90aW1lKGNkc1siQ1hDUjEiLCBdKQpwbG90X2dlbmVzX2luX3BzZXVkb3RpbWUoY2RzWyJQSU0yIiwgXSkKcGxvdF9nZW5lc19pbl9wc2V1ZG90aW1lKGNkc1siS0xGMiIsIF0pCnBsb3RfZ2VuZXNfaW5fcHNldWRvdGltZShjZHNbIkxHQUxTMyIsIF0pCnBsb3RfZ2VuZXNfaW5fcHNldWRvdGltZShjZHNbIkNDTkQyIiwgXSkKcGxvdF9nZW5lc19pbl9wc2V1ZG90aW1lKGNkc1siUElNMiIsIF0pCnBsb3RfZ2VuZXNfaW5fcHNldWRvdGltZShjZHNbIkNENzQiLCBdKQpwbG90X2dlbmVzX2luX3BzZXVkb3RpbWUoY2RzWyJDRDQwIiwgXSkKcGxvdF9nZW5lc19pbl9wc2V1ZG90aW1lKGNkc1siQ0Q0NCIsIF0pCnBsb3RfZ2VuZXNfaW5fcHNldWRvdGltZShjZHNbIkNENTIiLCBdKQpwbG90X2dlbmVzX2luX3BzZXVkb3RpbWUoY2RzWyJDRDY5IiwgXSkKcGxvdF9nZW5lc19pbl9wc2V1ZG90aW1lKGNkc1siUFJGMSIsIF0pCnBsb3RfZ2VuZXNfaW5fcHNldWRvdGltZShjZHNbIkdaTUIiLCBdKQpwbG90X2dlbmVzX2luX3BzZXVkb3RpbWUoY2RzWyJDRDciLCBdKQpwbG90X2dlbmVzX2luX3BzZXVkb3RpbWUoY2RzWyJEUFA0IiwgXSkKcGxvdF9nZW5lc19pbl9wc2V1ZG90aW1lKGNkc1siQ0QyOCIsIF0pCnBsb3RfZ2VuZXNfaW5fcHNldWRvdGltZShjZHNbIkNEMjciLCBdKQpwbG90X2dlbmVzX2luX3BzZXVkb3RpbWUoY2RzWyJDRDhBIiwgXSkKCiNPdXRwdXQgdGVsbHMgeW91OiBob3cgY2Fub25pY2FsIG5hw692ZSBtYXJrZXJzIGRlY2xpbmUvc2hpZnQgYWNyb3NzIHBzZXVkb3RpbWUuCgpgYGAKIyMgVmlzdWFsaXplIEdlbmUgRXhwcmVzc2lvbiBBbG9uZyBQc2V1ZG90aW1lCmBgYHtyfQptYXJrZXJfZ3JvdXBzIDwtIGxpc3QoCiAgIkNENCBUZXggKEV4aGF1c3RlZCkiID0gYygiVE9YIiwgIkxBRzMiLCAiQ1RMQTQiLCAiVElHSVQiKSwKICAiQ0Q0IFRyZWciID0gYygiRk9YUDMiLCAiSUwyUkEiLCAiQ1RMQTQiLCAiSUtaRjIiLCAiVElHSVQiKSwKICAiQ0Q0IFRjbSAoQ2VudHJhbCBNZW1vcnkpIiA9IGMoIkNDUjciLCAiU0VMTCIsICJJTDdSIiwgIlRDRjciKSwKICAiQ0Q0IFRuIChOYWl2ZSkiID0gYygiQ0NSNyIsICJTRUxMIiwgIklMN1IiLCAiVENGNyIsICJMRUYxIiksCiAgIkNENCBUZW0gKEVmZmVjdG9yIE1lbW9yeSkiID0gYygiR1pNQiIsICJQUkYxIiwgIklGTkciLCAiS0xSRzEiKSwKICAiQ0Q0IFRybSAoVGlzc3VlIFJlc2lkZW50KSIgPSBjKCJDRDY5IiwgIkNYQ1I2IiksCiAgIkNENCBUYyAoQ3l0b3RveGljKSIgPSBjKCJQUkYxIiwgIkdaTUIiLCAiTktHNyIsICJHTkxZIiksCiAgIkNENCBUaXNnIChJRk4gU2lnbmF0dXJlKSIgPSBjKCJJU0cxNSIsICJJRkk2IiwgIklGSVQzIiwgIk1YMSIpLAogICJDRDQgUHJvbGlmZXJhdGlvbiIgPSBjKCJNS0k2NyIsICJUT1AyQSIpLAogICJDRDQgVGgxNyIgPSBjKCJTVEFUMyIsICJBSFIiLCAiQ0NSNiIsICJCQVRGIiksCiAgIkNENCBUZW1yYSAoRWZmZWN0b3IgTWVtb3J5IFJBKykiID0gYygiUFRQUkMiLCAiR1pNQiIpLAogICJDRDQgVGZoIChGb2xsaWN1bGFyIEhlbHBlcikiID0gYygiQkNMNiIsICJJQ09TIiksCiAgIkNENCBUc3RyIChTdHJlc3MpIiA9IGMoIkhTUEExQSIsICJBVEYzIiksCiAgIkNENCBBY3RpdmF0ZWQiID0gYygiSUwyUkEiLCAiQ0Q2OSIsICJITEEtRFJBIikKKQoKbGlicmFyeShtb25vY2xlMykKbGlicmFyeShnZ3Bsb3QyKQoKIyBGbGF0dGVuIHlvdXIgbWFya2VyX2dyb3VwcyBsaXN0IHRvIGEgc2luZ2xlIHZlY3RvciBvZiB1bmlxdWUgZ2VuZXMKYWxsX2dlbmVzIDwtIHVuaXF1ZSh1bmxpc3QobWFya2VyX2dyb3VwcykpCgojIE9wdGlvbmFsOiBjaGVjayB3aGljaCBnZW5lcyBhcmUgYWN0dWFsbHkgcHJlc2VudCBpbiB5b3VyIGNkcwphbGxfZ2VuZXNfcHJlc2VudCA8LSBhbGxfZ2VuZXNbYWxsX2dlbmVzICVpbiUgcm93bmFtZXMoY2RzKV0KCiMgTG9vcCBvdmVyIGdlbmVzIGFuZCBwbG90CmZvciAoZ2VuZSBpbiBhbGxfZ2VuZXNfcHJlc2VudCkgewogIHByaW50KHBsb3RfZ2VuZXNfaW5fcHNldWRvdGltZShjZHNbZ2VuZSwgXSkgKyBnZ3RpdGxlKGdlbmUpKQp9CgpgYGAKCgoKCiMjIFN1bW1hcml6ZSBMaW5lYWdlcyBhbmQgQ2VsbCBGYXRlIEJyYW5jaGVzCmBgYHtyLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KY2RzIDwtIGNsdXN0ZXJfY2VsbHMoY2RzKQpwX2JyYW5jaGVzIDwtIHBsb3RfY2VsbHMoY2RzLCBjb2xvcl9jZWxsc19ieSA9ICJjbHVzdGVyIikKcHJpbnQocF9icmFuY2hlcykKCnBsb3RfY2VsbHMoCmNkcywKY29sb3JfY2VsbHNfYnkgPSAicHNldWRvdGltZSIsCmxhYmVsX2JyYW5jaF9wb2ludHMgPSBUUlVFLApsYWJlbF9sZWF2ZXMgPSBUUlVFLApsYWJlbF9yb290cyA9IFRSVUUsCmdyYXBoX2xhYmVsX3NpemUgPSAyCikKCmBgYAoKCgojIyBWaXN1YWxpemUgR2VuZSBNb2R1bGVzIEFsb25nIFBzZXVkb3RpbWUKYGBge3IsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEwfQoKIyMgSWRlbnRpZnkgY28tZXhwcmVzc2VkIGdlbmUgbW9kdWxlcwpnZW5lX21vZHVsZXMgPC0gZmluZF9nZW5lX21vZHVsZXMoY2RzLCByZXNvbHV0aW9uID0gMWUtMikKCiMjIEV4cGxvcmUgZmlyc3QgbW9kdWxlIGFsb25nIHRyYWplY3RvcnkKcGxvdF9jZWxscyhjZHMsIAogICAgICAgICAgIGdlbmVzID0gZ2VuZV9tb2R1bGVzW1sxXV0sIAogICAgICAgICAgIHNob3dfdHJhamVjdG9yeV9ncmFwaCA9IEZBTFNFLCAKICAgICAgICAgICBsYWJlbF9jZWxsX2dyb3VwcyA9IEZBTFNFKSArCiAgZ2d0aXRsZSgiR2VuZSBNb2R1bGUgMSBFeHByZXNzaW9uIEFsb25nIFRyYWplY3RvcnkiKQoKIyMgT3B0aW9uYWw6IGxvb3Agb3ZlciBtb2R1bGVzIHRvIHZpc3VhbGl6ZSBtdWx0aXBsZQpsYXBwbHkoc2VxX2Fsb25nKGdlbmVfbW9kdWxlcylbMTo1XSwgZnVuY3Rpb24oaSkgewogIHBsb3RfY2VsbHMoY2RzLCBnZW5lcyA9IGdlbmVfbW9kdWxlc1tbaV1dLCBzaG93X3RyYWplY3RvcnlfZ3JhcGggPSBGQUxTRSkKfSkKCgoKYGBgCgoKIyMgTXVsdGktR2VuZSBQc2V1ZG90aW1lIFBsb3Qgd2l0aCBGYWNldHMKYGBge3IsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEwfQoKIyMgTXVsdGktR2VuZSBQc2V1ZG90aW1lIFBsb3RzIGJ5IEZ1bmN0aW9uYWwgTWFya2VyIEdyb3VwcwoKbGlicmFyeShnZ3Bsb3QyKQoKIyBEZWZpbmUgbWFya2VyIGdyb3VwcwptYXJrZXJfZ3JvdXBzIDwtIGxpc3QoCiAgIkNENCBUZXggKEV4aGF1c3RlZCkiID0gYygiVE9YIiwgIkxBRzMiLCAiQ1RMQTQiLCAiVElHSVQiKSwKICAiQ0Q0IFRyZWciID0gYygiRk9YUDMiLCAiSUwyUkEiLCAiQ1RMQTQiLCAiSUtaRjIiLCAiVElHSVQiKSwKICAiQ0Q0IFRjbSAoQ2VudHJhbCBNZW1vcnkpIiA9IGMoIkNDUjciLCAiU0VMTCIsICJJTDdSIiwgIlRDRjciKSwKICAiQ0Q0IFRuIChOYWl2ZSkiID0gYygiQ0NSNyIsICJTRUxMIiwgIklMN1IiLCAiVENGNyIsICJMRUYxIiksCiAgIkNENCBUZW0gKEVmZmVjdG9yIE1lbW9yeSkiID0gYygiR1pNQiIsICJQUkYxIiwgIklGTkciLCAiS0xSRzEiKSwKICAiQ0Q0IFRybSAoVGlzc3VlIFJlc2lkZW50KSIgPSBjKCJDRDY5IiwgIkNYQ1I2IiksCiAgIkNENCBUYyAoQ3l0b3RveGljKSIgPSBjKCJQUkYxIiwgIkdaTUIiLCAiTktHNyIsICJHTkxZIiksCiAgIkNENCBUaXNnIChJRk4gU2lnbmF0dXJlKSIgPSBjKCJJU0cxNSIsICJJRkk2IiwgIklGSVQzIiwgIk1YMSIpLAogICJDRDQgUHJvbGlmZXJhdGlvbiIgPSBjKCJNS0k2NyIsICJUT1AyQSIpLAogICJDRDQgVGgxNyIgPSBjKCJTVEFUMyIsICJBSFIiLCAiQ0NSNiIsICJCQVRGIiksCiAgIkNENCBUZW1yYSAoRWZmZWN0b3IgTWVtb3J5IFJBKykiID0gYygiUFRQUkMiLCAiR1pNQiIpLAogICJDRDQgVGZoIChGb2xsaWN1bGFyIEhlbHBlcikiID0gYygiQkNMNiIsICJJQ09TIiksCiAgIkNENCBUc3RyIChTdHJlc3MpIiA9IGMoIkhTUEExQSIsICJBVEYzIiksCiAgIkNENCBBY3RpdmF0ZWQiID0gYygiSUwyUkEiLCAiQ0Q2OSIsICJITEEtRFJBIikKKQoKIyBMb29wIHRocm91Z2ggZWFjaCBtYXJrZXIgZ3JvdXAgYW5kIHBsb3QKZm9yIChncm91cF9uYW1lIGluIG5hbWVzKG1hcmtlcl9ncm91cHMpKSB7CiAgCiAgZ2VuZXNfdG9fcGxvdCA8LSBtYXJrZXJfZ3JvdXBzW1tncm91cF9uYW1lXV0KICAjIEtlZXAgb25seSBnZW5lcyBwcmVzZW50IGluIENEUwogIGdlbmVzX3RvX3Bsb3QgPC0gZ2VuZXNfdG9fcGxvdFtnZW5lc190b19wbG90ICVpbiUgcm93bmFtZXMoY2RzKV0KICAKICBpZiAobGVuZ3RoKGdlbmVzX3RvX3Bsb3QpID4gMCkgewogICAgcCA8LSBwbG90X2NlbGxzKGNkc1tnZW5lc190b19wbG90LCBdLCAKICAgICAgICAgICAgICAgICAgICBnZW5lcyA9IGdlbmVzX3RvX3Bsb3QsIAogICAgICAgICAgICAgICAgICAgIHNob3dfdHJhamVjdG9yeV9ncmFwaCA9IEZBTFNFKSArCiAgICAgICAgIGZhY2V0X3dyYXAofiBnZW5lX3Nob3J0X25hbWUsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgICAgICAgIGdndGl0bGUocGFzdGUwKGdyb3VwX25hbWUsICIgTWFya2VyIER5bmFtaWNzIEFsb25nIFBzZXVkb3RpbWUiKSkKICAgIAogICAgcHJpbnQocCkKICB9Cn0KCiMg4pyFIE91dHB1dDoKIyAgIE9uZSBmYWNldGVkIHBzZXVkb3RpbWUgcGxvdCBwZXIgZnVuY3Rpb25hbCBULWNlbGwgcHJvZ3JhbS4KIyAgIEVhY2ggZmlndXJlIHNob3dzIGV4cHJlc3Npb24gZHluYW1pY3Mgb2YgdGhlIGdyb3Vw4oCZcyBtYXJrZXJzIGFjcm9zcyBwc2V1ZG90aW1lLgoKCmBgYAoKIyMgTXVsdGktR2VuZSBQc2V1ZG90aW1lIFBsb3Qgd2l0aCBGYWNldHMKYGBge3J9CgpsaWJyYXJ5KGdncGxvdDIpCgojIEV4YW1wbGUgZ2VuZSBsaXN0CmdlbmVzX3RvX3Bsb3QgCgojIEtlZXAgb25seSBnZW5lcyBwcmVzZW50IGluIENEUwpnZW5lc190b19wbG90IDwtIGdlbmVzX3RvX3Bsb3RbZ2VuZXNfdG9fcGxvdCAlaW4lIHJvd25hbWVzKGNkcyldCgpwbG90X2NlbGxzKGNkc1tnZW5lc190b19wbG90LCBdLCAKICAgICAgICAgICBnZW5lcyA9IGdlbmVzX3RvX3Bsb3QsIAogICAgICAgICAgIHNob3dfdHJhamVjdG9yeV9ncmFwaCA9IEZBTFNFKSArCiAgZmFjZXRfd3JhcCh+IGdlbmVfc2hvcnRfbmFtZSwgc2NhbGVzID0gImZyZWVfeSIpICsKICBnZ3RpdGxlKCJOYWl2ZSBUIENlbGwgTWFya2VyIER5bmFtaWNzIEFsb25nIFBzZXVkb3RpbWUiKQoKI091dHB1dDogQ2xlYXIgdmlzdWFsaXphdGlvbiBvZiBlYWNoIGdlbmXigJlzIGR5bmFtaWNzIGFsb25nIHBzZXVkb3RpbWUuCgpgYGAKCiMjIE9wdGlvbmFsOiBPdmVybGF5IENJVEUtc2VxIFByb3RlaW4gRXhwcmVzc2lvbgpgYGB7cn0KCiMgRXhhbXBsZTogaWYgeW91ciBTZXVyYXQgb2JqZWN0IGhhcyBDSVRFLXNlcSAoQURUKSBkYXRhCmFkdF9tYXJrZXJzIDwtIGMoImFkdF9DRDQ1UkEiLCAiYWR0X0NENjJMIikgICMgYWRqdXN0IHRvIHlvdXIgcGFuZWwKZm9yKG1hcmtlciBpbiBhZHRfbWFya2Vycyl7CiAgcGxvdF9jZWxscyhjZHMsIAogICAgICAgICAgICAgY29sb3JfY2VsbHNfYnkgPSBtYXJrZXIsIAogICAgICAgICAgICAgc2hvd190cmFqZWN0b3J5X2dyYXBoID0gVFJVRSkgKwogICAgZ2d0aXRsZShwYXN0ZSgiQURUIEV4cHJlc3Npb246IiwgbWFya2VyKSkKfQoKCmBgYAoKCiMjIFBhdGh3YXkgRW5yaWNobWVudCBvZiBUb3AgREVHcyBvciBHZW5lIE1vZHVsZXMKYGBge3J9CgpsaWJyYXJ5KGNsdXN0ZXJQcm9maWxlcikKbGlicmFyeShvcmcuSHMuZWcuZGIpCgojIENvbnZlcnQgZ2VuZSBzeW1ib2xzIHRvIEVudHJleiBJRHMKZW50cmV6X2lkcyA8LSBiaXRyKHRvcDUwX2dlbmVzLCBmcm9tVHlwZT0iU1lNQk9MIiwgdG9UeXBlPSJFTlRSRVpJRCIsIE9yZ0RiPSJvcmcuSHMuZWcuZGIiKQoKIyBLRUdHIGVucmljaG1lbnQKa2VnZ19yZXMgPC0gZW5yaWNoS0VHRyhlbnRyZXpfaWRzJEVOVFJFWklELCBvcmdhbmlzbT0iaHNhIikKCiMgVmlzdWFsaXplIHRvcCBwYXRod2F5cwpkb3RwbG90KGtlZ2dfcmVzLCBzaG93Q2F0ZWdvcnk9MTApICsgZ2d0aXRsZSgiS0VHRyBQYXRod2F5cyBmb3IgVG9wIERFR3MiKQoKIyBPdXRwdXQ6IEJpb2xvZ2ljYWwgaW50ZXJwcmV0YXRpb24gb2YgYnJhbmNoZXMgKGUuZy4sIHByb2xpZmVyYXRpb24sIFQtY2VsbCBhY3RpdmF0aW9uLCBpbW11bmUgZXZhc2lvbikuCmBgYAoKIyMgQnJhbmNoIFByb2JhYmlsaXR5IC8gRmF0ZSBCaWFzCmBgYHtyfQojIyBCcmFuY2ggUHJvYmFiaWxpdHkgLyBGYXRlIEJpYXMgKHNpbXBsaWZpZWQgdmlzdWFsaXphdGlvbikKIyBNb25vY2xlMyBsZXRzIHlvdSB2aXN1YWxpemUgYnJhbmNoIHBvaW50cyBkaXJlY3RseSBvbiB0aGUgdHJhamVjdG9yeS4KIyBUaGlzIGRvZXMgbm90IGNvbXB1dGUgcHJvYmFiaWxpdGllcywgYnV0IGhpZ2hsaWdodHMgYmlmdXJjYXRpb25zLgoKIyBQbG90IHRyYWplY3Rvcnkgd2l0aCBicmFuY2ggcG9pbnRzCnBsb3RfY2VsbHMoY2RzLAogICAgICAgICAgIGNvbG9yX2NlbGxzX2J5ID0gInBzZXVkb3RpbWUiLAogICAgICAgICAgIGxhYmVsX2JyYW5jaF9wb2ludHMgPSBUUlVFLAogICAgICAgICAgIGxhYmVsX2xlYXZlcyA9IFRSVUUsCiAgICAgICAgICAgbGFiZWxfcm9vdHMgPSBUUlVFLAogICAgICAgICAgIGdyYXBoX2xhYmVsX3NpemUgPSAyKQoKIyBPcHRpb25hbDogdmlzdWFsaXplIGJyYW5jaCBzdHJ1Y3R1cmUgb25seQpwbG90X2NlbGxzKGNkcywKICAgICAgICAgICBzaG93X3RyYWplY3RvcnlfZ3JhcGggPSBUUlVFLAogICAgICAgICAgIGxhYmVsX2JyYW5jaF9wb2ludHMgPSBUUlVFLAogICAgICAgICAgIGxhYmVsX2NlbGxfZ3JvdXBzID0gRkFMU0UsCiAgICAgICAgICAgbGFiZWxfbGVhdmVzID0gVFJVRSwKICAgICAgICAgICBsYWJlbF9yb290cyA9IFRSVUUpCgoKYGBgCgoKIyMgRXhwbG9yZSBCcmFuY2gtU3BlY2lmaWMgRGlmZmVyZW50aWFsIEV4cHJlc3Npb24KYGBge3IsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9CgojIyBTZWxlY3QgdG9wIERFR3MgcGVyIGJyYW5jaCAocV92YWx1ZSA8IDAuMDUpCnRvcF9kZWdzIDwtIGRlZ19ieV9icmFuY2ggJT4lCiAgZmlsdGVyKHFfdmFsdWUgPCAwLjA1KSAlPiUKICBhcnJhbmdlKHFfdmFsdWUpCgojIE9wdGlvbmFsOiB0YWtlIHRvcCA1MCBmb3IgcGxvdHRpbmcKdG9wNTBfZ2VuZXMgPC0gaGVhZCh0b3BfZGVncyRnZW5lX3Nob3J0X25hbWUsIDUwKQoKIyMgUGxvdCBwc2V1ZG90aW1lIGV4cHJlc3Npb24gb2YgdG9wIERFR3MKcGxvdF9jZWxscyhjZHNbdG9wNTBfZ2VuZXMsIF0sIAogICAgICAgICAgIGdlbmVzPXRvcDUwX2dlbmVzLCAKICAgICAgICAgICBzaG93X3RyYWplY3RvcnlfZ3JhcGggPSBUUlVFLCAKICAgICAgICAgICBsYWJlbF9jZWxsX2dyb3VwcyA9IEZBTFNFKQoKI091dHB1dDogSGlnaGxpZ2h0cyBicmFuY2gtc3BlY2lmaWMgdHJhbnNjcmlwdGlvbmFsIHByb2dyYW1zIGFuZCBjZWxsIGZhdGUgYmlhc2VzLgoKCgpgYGAKCiMjIEV4cGxvcmUgQnJhbmNoLVNwZWNpZmljIERpZmZlcmVudGlhbCBFeHByZXNzaW9uCmBgYHtyLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQoKbGlicmFyeShnZ3Bsb3QyKQoKZm9yIChnZW5lIGluIHRvcDUwX2dlbmVzKSB7CiAgcCA8LSBwbG90X2NlbGxzKGNkc1tnZW5lLCBdLCAKICAgICAgICAgICAgICAgICAgZ2VuZXMgPSBnZW5lLAogICAgICAgICAgICAgICAgICBzaG93X3RyYWplY3RvcnlfZ3JhcGggPSBUUlVFLAogICAgICAgICAgICAgICAgICBsYWJlbF9jZWxsX2dyb3VwcyA9IEZBTFNFKSArCiAgICAgICBnZ3RpdGxlKGdlbmUpCiAgcHJpbnQocCkKfQoKCmBgYAoKCiMjIyAgRXhwbG9yZSBCcmFuY2gtU3BlY2lmaWMgRGlmZmVyZW50aWFsIEV4cHJlc3Npb24KYGBge3IsIGZpZy5oZWlnaHQ9MTYsIGZpZy53aWR0aD0yMH0KIyMgSWRlbnRpZnkgZ2VuZXMgdGhhdCB2YXJ5IGFsb25nIGJyYW5jaGVzCmRlZ19ieV9icmFuY2ggPC0gZ3JhcGhfdGVzdChjZHMsIG5laWdoYm9yX2dyYXBoID0gInByaW5jaXBhbF9ncmFwaCIsIGNvcmVzID0gNCkKZGVnX2J5X2JyYW5jaCA8LSBkZWdfYnlfYnJhbmNoICU+JSBhcnJhbmdlKHFfdmFsdWUpCmBgYAoKCiMjIFZpc3VhbGl6ZSBHZW5lIE1vZHVsZXMgQWxvbmcgUHNldWRvdGltZQpgYGB7ciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CgojIyBJZGVudGlmeSBjby1leHByZXNzZWQgZ2VuZSBtb2R1bGVzCmdlbmVfbW9kdWxlcyA8LSBmaW5kX2dlbmVfbW9kdWxlcyhjZHMsIHJlc29sdXRpb24gPSAxZS0yKQoKIyMgRXhwbG9yZSBmaXJzdCBtb2R1bGUgYWxvbmcgdHJhamVjdG9yeQpwbG90X2NlbGxzKGNkcywgCiAgICAgICAgICAgZ2VuZXMgPSBnZW5lX21vZHVsZXNbWzFdXSwgCiAgICAgICAgICAgc2hvd190cmFqZWN0b3J5X2dyYXBoID0gRkFMU0UsIAogICAgICAgICAgIGxhYmVsX2NlbGxfZ3JvdXBzID0gRkFMU0UpICsKICBnZ3RpdGxlKCJHZW5lIE1vZHVsZSAxIEV4cHJlc3Npb24gQWxvbmcgVHJhamVjdG9yeSIpCgojIyBPcHRpb25hbDogbG9vcCBvdmVyIG1vZHVsZXMgdG8gdmlzdWFsaXplIG11bHRpcGxlCmxhcHBseShzZXFfYWxvbmcoZ2VuZV9tb2R1bGVzKVsxOjVdLCBmdW5jdGlvbihpKSB7CiAgcGxvdF9jZWxscyhjZHMsIGdlbmVzID0gZ2VuZV9tb2R1bGVzW1tpXV0sIHNob3dfdHJhamVjdG9yeV9ncmFwaCA9IEZBTFNFKQp9KQoKCgpgYGAKCgo=