1 Metabolic Pathway Analysis in Sézary Syndrome scRNA-seq Data

1.1 load libraries

1.2 Load Seurat Object


All_samples_Merged <- readRDS("1-Thesis_Final_Year_2025/2025-Final_Year_Results/2025-Year3_Analysis/0-Seurat_RDS_OBJECT_FINAL/All_samples_Merged_with_Renamed_Clusters_final-26-10-2025.rds")

2 filtering cells based on percent.mt if needed (optional)

2.1 Voilin Plot Function for Percent.mt


VlnPlot(All_samples_Merged, features = "percent.mt", group.by = "orig.ident")


VlnPlot(All_samples_Merged, features = "percent.mt", group.by = "seurat_clusters")

All cell lines and healthy controls exhibit low and comparable mitochondrial RNA proportions (~2–3%), indicating good-quality cells without excessive apoptosis. This metric was later regressed out during SCTransform and is used strictly as QC.

3 Pathway Scoring Analysis

3.1 UCell Scoring for Metabolic Pathways

3.2 Calculate Seurat Enrichment Scores and Visualizations


All_samples_Merged$cell_line_ordered <- factor(
  All_samples_Merged$orig.ident,
  levels = c("L1","L2","L3","L4","L5","L6","L7","CD4T_lab","CD4T_10x")
)

p1 <- SCpubr::do_EnrichmentHeatmap(
  sample = All_samples_Merged,
  input_gene_list = gene_sets,
  group.by = "cell_line_ordered",  enforce_symmetry = TRUE, use_viridis = FALSE
)
p1

3.3 Calculate Seurat Enrichment Scores and Visualizations


p2 <- SCpubr::do_EnrichmentHeatmap(sample = All_samples_Merged,
                                  input_gene_list = gene_sets, group.by = "orig.ident", flip = TRUE, enforce_symmetry = TRUE, use_viridis = FALSE)
p2

p3 <- SCpubr::do_EnrichmentHeatmap(sample = All_samples_Merged,
                                  input_gene_list = gene_sets,
                                  group.by = c("Patient_origin", "orig.ident"), flip = TRUE,  enforce_symmetry = TRUE, use_viridis = FALSE)
p3

3.4 Calculate UCell Scores and Visualizations


p4 <- SCpubr::do_EnrichmentHeatmap(sample = All_samples_Merged,
                                  input_gene_list = gene_sets,
                                  flip = TRUE,
                                  flavor = "UCell",
                                   enforce_symmetry = TRUE,
                                  use_viridis = FALSE)
p4

3.5 Quality Check

# Check which genes are present or missing in the Seurat object
gene_presence <- lapply(gene_sets, function(gset) {
  present <- gset[gset %in% rownames(All_samples_Merged)]
  missing <- gset[!gset %in% rownames(All_samples_Merged)]
  list(present = present, missing = missing)
})

# Example: view results for OXPHOS_CUSTOM
gene_presence$OXPHOS_CUSTOM$present   # genes present
  [1] "COX17"    "TCIRG1"   "ATP5PD"   "ATP5MG"   "UQCR11"   "COX6B2"   "NDUFA11"  "ATP6V1G3" "COX4I1"  
 [10] "COX5B"    "COX6A1"   "COX6B1"   "COX6C"    "COX7A2"   "COX7B"    "COX7C"    "COX8A"    "COX10"   
 [19] "COX11"    "COX15"    "CYC1"     "ATP6V0E2" "COX7B2"   "ATP6V0A2" "ATP6V0D2" "ATP6V1C2" "PPA2"    
 [28] "UQCRQ"    "UQCR10"   "NDUFS7"   "UQCRHL"   "MT-ATP6"  "MT-ATP8"  "MT-CO1"   "MT-CO2"   "MT-CO3"  
 [37] "MT-CYB"   "MT-ND1"   "MT-ND2"   "MT-ND3"   "MT-ND4"   "MT-ND4L"  "MT-ND5"   "MT-ND6"   "NDUFA1"  
 [46] "NDUFA2"   "NDUFA3"   "NDUFA4"   "NDUFA5"   "NDUFA6"   "NDUFA7"   "NDUFA8"   "NDUFA9"   "NDUFA10" 
 [55] "NDUFAB1"  "NDUFB1"   "NDUFB2"   "NDUFB3"   "NDUFB4"   "NDUFB5"   "NDUFB6"   "NDUFB7"   "NDUFB8"  
 [64] "NDUFB9"   "NDUFB10"  "NDUFC1"   "NDUFC2"   "NDUFS1"   "NDUFS2"   "NDUFS3"   "NDUFV1"   "NDUFS4"  
 [73] "NDUFS5"   "NDUFS6"   "NDUFS8"   "NDUFV2"   "NDUFV3"   "ATP12A"   "ATP4A"    "ATP4B"    "ATP5F1A" 
 [82] "ATP5F1B"  "ATP6V0A4" "ATP5F1C"  "ATP5F1D"  "ATP6V1D"  "ATP5F1E"  "ATP5PB"   "ATP5MC1"  "ATP6V1H" 
 [91] "ATP5MC2"  "ATP5MC3"  "ATP5ME"   "ATP5PF"   "ATP6V1A"  "ATP6V1B2" "ATP6V0C"  "ATP6V1C1" "ATP6V1E1"
[100] "ATP6V0B"  "ATP6V1G2" "ATP6V0A1" "ATP6AP1"  "ATP5PO"   "PPA1"     "NDUFA4L2" "SDHA"     "SDHB"    
[109] "SDHC"     "SDHD"     "LHPP"     "UQCRB"    "UQCRC1"   "UQCRC2"   "UQCRFS1"  "UQCRH"    "ATP6V0E1"
[118] "ATP6V1E2" "ATP6V0D1" "COX7A2L"  "ATP6V1F"  "COX5A"    "ATP6V1G1" "ATP5MF"  
gene_presence$OXPHOS_CUSTOM$missing   # genes not found
[1] "COX6CP3"   "COX6A2"    "COX7A1"    "COX8C"     "ATP5MC1P5" "ATP6V1B1"  "SDHCP5"    "UQCR10P1" 
[9] "COX4I2"   
# Optional: summarize counts
sapply(gene_presence, function(x) c(present = length(x$present), missing = length(x$missing)))
        OXPHOS_MSIG OXPHOS_CUSTOM GLYCO_MSIG GLYCO_CUSTOM MITO_ETC_CUSTOM
present         201           124        196           16              13
missing           0             9          4            0               0
gene_presence
$OXPHOS_MSIG
$OXPHOS_MSIG$present
  [1] "ABCB7"    "ACAA1"    "ACAA2"    "ACADM"    "ACADSB"   "ACADVL"   "ACAT1"    "ACO2"     "AFG3L2"  
 [10] "AIFM1"    "ALAS1"    "ALDH6A1"  "ATP1B1"   "ATP5F1A"  "ATP5F1B"  "ATP5F1C"  "ATP5F1D"  "ATP5F1E" 
 [19] "ATP5MC1"  "ATP5MC2"  "ATP5MC3"  "ATP5ME"   "ATP5MF"   "ATP5MG"   "ATP5PB"   "ATP5PD"   "ATP5PF"  
 [28] "ATP5PO"   "ATP6AP1"  "ATP6V0B"  "ATP6V0C"  "ATP6V0E1" "ATP6V1C1" "ATP6V1D"  "ATP6V1E1" "ATP6V1F" 
 [37] "ATP6V1G1" "ATP6V1H"  "BAX"      "BCKDHA"   "BDH2"     "CASP7"    "COX10"    "COX11"    "COX15"   
 [46] "COX17"    "COX4I1"   "COX5A"    "COX5B"    "COX6A1"   "COX6B1"   "COX6C"    "COX7A2"   "COX7A2L" 
 [55] "COX7B"    "COX7C"    "COX8A"    "CPT1A"    "CS"       "CYB5A"    "CYB5R3"   "CYC1"     "CYCS"    
 [64] "DECR1"    "DLAT"     "DLD"      "DLST"     "ECH1"     "ECHS1"    "ECI1"     "ETFA"     "ETFB"    
 [73] "ETFDH"    "FDX1"     "FH"       "FXN"      "GLUD1"    "GOT2"     "GPI"      "GPX4"     "GRPEL1"  
 [82] "HADHA"    "HADHB"    "HCCS"     "HSD17B10" "HSPA9"    "HTRA2"    "IDH1"     "IDH2"     "IDH3A"   
 [91] "IDH3B"    "IDH3G"    "IMMT"     "ISCA1"    "ISCU"     "LDHA"     "LDHB"     "LRPPRC"   "MAOB"    
[100] "MDH1"     "MDH2"     "MFN2"     "MGST3"    "MPC1"     "MRPL11"   "MRPL15"   "MRPL34"   "MRPL35"  
[109] "MRPS11"   "MRPS12"   "MRPS15"   "MRPS22"   "MRPS30"   "MTRF1"    "MTRR"     "MTX2"     "NDUFA1"  
[118] "NDUFA2"   "NDUFA3"   "NDUFA4"   "NDUFA5"   "NDUFA6"   "NDUFA7"   "NDUFA8"   "NDUFA9"   "NDUFAB1" 
[127] "NDUFB1"   "NDUFB2"   "NDUFB3"   "NDUFB4"   "NDUFB5"   "NDUFB6"   "NDUFB7"   "NDUFB8"   "NDUFC1"  
[136] "NDUFC2"   "NDUFS1"   "NDUFS2"   "NDUFS3"   "NDUFS4"   "NDUFS6"   "NDUFS7"   "NDUFS8"   "NDUFV1"  
[145] "NDUFV2"   "NNT"      "NQO2"     "OAT"      "OGDH"     "OPA1"     "OXA1L"    "PDHA1"    "PDHB"    
[154] "PDHX"     "PDK4"     "PDP1"     "PHB2"     "PHYH"     "PMPCA"    "POLR2F"   "POR"      "PRDX3"   
[163] "RETSAT"   "RHOT1"    "RHOT2"    "SDHA"     "SDHB"     "SDHC"     "SDHD"     "SLC25A11" "SLC25A12"
[172] "SLC25A20" "SLC25A3"  "SLC25A4"  "SLC25A5"  "SLC25A6"  "SLC25A6"  "SUCLA2"   "SUCLG1"   "SUPV3L1" 
[181] "SURF1"    "TCIRG1"   "TIMM10"   "TIMM13"   "TIMM17A"  "TIMM50"   "TIMM8B"   "TIMM9"    "TOMM22"  
[190] "TOMM70"   "UQCR10"   "UQCR11"   "UQCRB"    "UQCRC1"   "UQCRC2"   "UQCRFS1"  "UQCRH"    "UQCRQ"   
[199] "VDAC1"    "VDAC2"    "VDAC3"   

$OXPHOS_MSIG$missing
character(0)


$OXPHOS_CUSTOM
$OXPHOS_CUSTOM$present
  [1] "COX17"    "TCIRG1"   "ATP5PD"   "ATP5MG"   "UQCR11"   "COX6B2"   "NDUFA11"  "ATP6V1G3" "COX4I1"  
 [10] "COX5B"    "COX6A1"   "COX6B1"   "COX6C"    "COX7A2"   "COX7B"    "COX7C"    "COX8A"    "COX10"   
 [19] "COX11"    "COX15"    "CYC1"     "ATP6V0E2" "COX7B2"   "ATP6V0A2" "ATP6V0D2" "ATP6V1C2" "PPA2"    
 [28] "UQCRQ"    "UQCR10"   "NDUFS7"   "UQCRHL"   "MT-ATP6"  "MT-ATP8"  "MT-CO1"   "MT-CO2"   "MT-CO3"  
 [37] "MT-CYB"   "MT-ND1"   "MT-ND2"   "MT-ND3"   "MT-ND4"   "MT-ND4L"  "MT-ND5"   "MT-ND6"   "NDUFA1"  
 [46] "NDUFA2"   "NDUFA3"   "NDUFA4"   "NDUFA5"   "NDUFA6"   "NDUFA7"   "NDUFA8"   "NDUFA9"   "NDUFA10" 
 [55] "NDUFAB1"  "NDUFB1"   "NDUFB2"   "NDUFB3"   "NDUFB4"   "NDUFB5"   "NDUFB6"   "NDUFB7"   "NDUFB8"  
 [64] "NDUFB9"   "NDUFB10"  "NDUFC1"   "NDUFC2"   "NDUFS1"   "NDUFS2"   "NDUFS3"   "NDUFV1"   "NDUFS4"  
 [73] "NDUFS5"   "NDUFS6"   "NDUFS8"   "NDUFV2"   "NDUFV3"   "ATP12A"   "ATP4A"    "ATP4B"    "ATP5F1A" 
 [82] "ATP5F1B"  "ATP6V0A4" "ATP5F1C"  "ATP5F1D"  "ATP6V1D"  "ATP5F1E"  "ATP5PB"   "ATP5MC1"  "ATP6V1H" 
 [91] "ATP5MC2"  "ATP5MC3"  "ATP5ME"   "ATP5PF"   "ATP6V1A"  "ATP6V1B2" "ATP6V0C"  "ATP6V1C1" "ATP6V1E1"
[100] "ATP6V0B"  "ATP6V1G2" "ATP6V0A1" "ATP6AP1"  "ATP5PO"   "PPA1"     "NDUFA4L2" "SDHA"     "SDHB"    
[109] "SDHC"     "SDHD"     "LHPP"     "UQCRB"    "UQCRC1"   "UQCRC2"   "UQCRFS1"  "UQCRH"    "ATP6V0E1"
[118] "ATP6V1E2" "ATP6V0D1" "COX7A2L"  "ATP6V1F"  "COX5A"    "ATP6V1G1" "ATP5MF"  

$OXPHOS_CUSTOM$missing
[1] "COX6CP3"   "COX6A2"    "COX7A1"    "COX8C"     "ATP5MC1P5" "ATP6V1B1"  "SDHCP5"    "UQCR10P1" 
[9] "COX4I2"   


$GLYCO_MSIG
$GLYCO_MSIG$present
  [1] "ABCB6"    "ADORA2B"  "AGL"      "AGRN"     "AK3"      "AK4"      "AKR1A1"   "ALDH7A1"  "ALDH9A1" 
 [10] "ALDOA"    "ALDOB"    "ALG1"     "ANG"      "ANGPTL4"  "ANKZF1"   "ARPP19"   "ARTN"     "AURKA"   
 [19] "B3GALT6"  "B3GAT1"   "B3GAT3"   "B3GNT3"   "B4GALT1"  "B4GALT2"  "B4GALT4"  "B4GALT7"  "BIK"     
 [28] "BPNT1"    "CACNA1H"  "CAPN5"    "CASP6"    "CD44"     "CDK1"     "CENPA"    "CHPF"     "CHPF2"   
 [37] "CHST1"    "CHST12"   "CHST2"    "CHST6"    "CITED2"   "CLDN3"    "CLN6"     "COG2"     "COL5A1"  
 [46] "COPB2"    "CTH"      "CXCR4"    "CYB5A"    "DCN"      "DDIT4"    "DEPDC1"   "DLD"      "DPYSL4"  
 [55] "DSC2"     "ECD"      "EFNA3"    "EGFR"     "EGLN3"    "ELF3"     "ENO1"     "ENO2"     "ERO1A"   
 [64] "EXT1"     "EXT2"     "FAM162A"  "FBP2"     "FKBP4"    "FUT8"     "G6PD"     "GAL3ST1"  "GALE"    
 [73] "GALK1"    "GALK2"    "GAPDHS"   "GCLC"     "GFPT1"    "GLCE"     "GLRX"     "GMPPA"    "GMPPB"   
 [82] "GNE"      "GNPDA1"   "GOT1"     "GOT2"     "GPC1"     "GPC3"     "GPC4"     "GPR87"    "GUSB"    
 [91] "GYS1"     "GYS2"     "HAX1"     "HDLBP"    "HK2"      "HMMR"     "HOMER1"   "HS2ST1"   "HS6ST2"  
[100] "HSPA5"    "IDH1"     "IDUA"     "IER3"     "IGFBP3"   "IL13RA1"  "IRS2"     "ISG20"    "KDELR3"  
[109] "KIF20A"   "KIF2A"    "LCT"      "LDHA"     "LDHC"     "LHPP"     "LHX9"     "MDH1"     "MDH2"    
[118] "ME1"      "ME2"      "MED24"    "MERTK"    "MET"      "MIF"      "MIOX"     "MPI"      "MXI1"    
[127] "NANP"     "NASP"     "NDST3"    "NDUFV3"   "NOL3"     "NSDHL"    "NT5E"     "P4HA1"    "P4HA2"   
[136] "PAM"      "PAXIP1"   "PC"       "PDK3"     "PFKFB1"   "PFKP"     "PGAM1"    "PGAM2"    "PGK1"    
[145] "PGLS"     "PGM2"     "PHKA2"    "PKM"      "PKP2"     "PLOD1"    "PLOD2"    "PMM2"     "POLR3K"  
[154] "PPFIA4"   "PPIA"     "PPP2CB"   "PRPS1"    "PSMC4"    "PYGB"     "PYGL"     "QSOX1"    "RBCK1"   
[163] "RPE"      "RRAGD"    "SAP30"    "SDC1"     "SDC2"     "SDC3"     "SDHC"     "SLC16A3"  "SLC25A10"
[172] "SLC25A13" "SLC35A3"  "SLC37A4"  "SOD1"     "SOX9"     "SPAG4"    "SRD5A3"   "STC1"     "STC2"    
[181] "STMN1"    "TALDO1"   "TFF3"     "TGFA"     "TGFBI"    "TKTL1"    "TPBG"     "TPI1"     "TPST1"   
[190] "TXN"      "UGP2"     "VCAN"     "VEGFA"    "VLDLR"    "XYLT2"    "ZNF292"  

$GLYCO_MSIG$missing
[1] "CHST4" "CLDN9" "GFUS"  "RARS1"


$GLYCO_CUSTOM
$GLYCO_CUSTOM$present
 [1] "HK1"    "PGK1"   "TPI1"   "ALDOA"  "ENO1"   "PKM"    "ENO2"   "ALDOC"  "ENO3"   "ALDOB"  "PGAM2" 
[12] "GAPDHS" "GPI"    "PFKM"   "PFKFB1" "PFKFB2"

$GLYCO_CUSTOM$missing
character(0)


$MITO_ETC_CUSTOM
$MITO_ETC_CUSTOM$present
 [1] "MT-ND1"  "MT-ND2"  "MT-ND3"  "MT-ND4"  "MT-ND4L" "MT-ND5"  "MT-ND6"  "MT-CYB"  "MT-CO1"  "MT-CO2" 
[11] "MT-CO3"  "MT-ATP6" "MT-ATP8"

$MITO_ETC_CUSTOM$missing
character(0)

4 Visualizations

4.1 Calculate UCell Enrichment Scores and Visualizations-Custom list

LS0tCnRpdGxlOiAiVmFsaWRhdGlvbiBvZiBDYXJlbCBnZW5lIGxpc3QiCmF1dGhvcjogIk5hc2lyIE1haG1vb2QgQWJiYXNpIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclQiAlZCwgJVknKWAiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiB0cnVlCiAgICB0aGVtZTogam91cm5hbAotLS0KCgoKCiMgTWV0YWJvbGljIFBhdGh3YXkgQW5hbHlzaXMgaW4gU8OpemFyeSBTeW5kcm9tZSBzY1JOQS1zZXEgRGF0YQoKIyMgbG9hZCBsaWJyYXJpZXMKYGBge3IgLCBpbmNsdWRlPUZBTFNFfQoKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkobXNpZ2RicikKbGlicmFyeShTQ3B1YnIpCmxpYnJhcnkoVUNlbGwpCmxpYnJhcnkoZHBseXIpCgpgYGAKCgojIyBMb2FkIFNldXJhdCBPYmplY3QKYGBge3IgLCBtZXNzYWdlPUZBTFNFfQoKQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIHJlYWRSRFMoIjEtVGhlc2lzX0ZpbmFsX1llYXJfMjAyNS8yMDI1LUZpbmFsX1llYXJfUmVzdWx0cy8yMDI1LVllYXIzX0FuYWx5c2lzLzAtU2V1cmF0X1JEU19PQkpFQ1RfRklOQUwvQWxsX3NhbXBsZXNfTWVyZ2VkX3dpdGhfUmVuYW1lZF9DbHVzdGVyc19maW5hbC0yNi0xMC0yMDI1LnJkcyIpCgpgYGAKCiMgZmlsdGVyaW5nIGNlbGxzIGJhc2VkIG9uIHBlcmNlbnQubXQgaWYgbmVlZGVkIChvcHRpb25hbCkKCiMjIFZvaWxpbiBQbG90IEZ1bmN0aW9uIGZvciBQZXJjZW50Lm10CmBgYHtyICwgbWVzc2FnZT1GQUxTRX0KClZsblBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCBmZWF0dXJlcyA9ICJwZXJjZW50Lm10IiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpCgpWbG5QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgZmVhdHVyZXMgPSAicGVyY2VudC5tdCIsIGdyb3VwLmJ5ID0gInNldXJhdF9jbHVzdGVycyIpCgpgYGAKCioqQWxsIGNlbGwgbGluZXMgYW5kIGhlYWx0aHkgY29udHJvbHMgZXhoaWJpdCBsb3cgYW5kIGNvbXBhcmFibGUgbWl0b2Nob25kcmlhbCBSTkEgcHJvcG9ydGlvbnMgKH4y4oCTMyUpLCBpbmRpY2F0aW5nIGdvb2QtcXVhbGl0eSBjZWxscyB3aXRob3V0IGV4Y2Vzc2l2ZSBhcG9wdG9zaXMuIFRoaXMgbWV0cmljIHdhcyBsYXRlciByZWdyZXNzZWQgb3V0IGR1cmluZyBTQ1RyYW5zZm9ybSBhbmQgaXMgdXNlZCBzdHJpY3RseSBhcyBRQy4qKgoKIyBQYXRod2F5IFNjb3JpbmcgQW5hbHlzaXMKCiMjIFVDZWxsIFNjb3JpbmcgZm9yIE1ldGFib2xpYyBQYXRod2F5cwpgYGB7ciAsIGluY2x1ZGU9RkFMU0V9CgojIEdldCBNU2lnREIgSGFsbG1hcmsgcGF0aHdheXMKaF9kZiA8LSBtc2lnZGJyKHNwZWNpZXMgPSAiSG9tbyBzYXBpZW5zIiwgY2F0ZWdvcnkgPSAiSCIpCgojIE94aWRhdGl2ZSBwaG9zcGhvcnlsYXRpb24gKEhBTExNQVJLKQpveHBob3NfbXNpZyA8LSBoX2RmICU+JQogIGZpbHRlcihnc19uYW1lID09ICJIQUxMTUFSS19PWElEQVRJVkVfUEhPU1BIT1JZTEFUSU9OIikgJT4lCiAgcHVsbChnZW5lX3N5bWJvbCkKCiMgR2x5Y29seXNpcyAoSEFMTE1BUkspCmdseWNvX21zaWcgPC0gaF9kZiAlPiUKICBmaWx0ZXIoZ3NfbmFtZSA9PSAiSEFMTE1BUktfR0xZQ09MWVNJUyIpICU+JQogIHB1bGwoZ2VuZV9zeW1ib2wpCgoKCiMgQ3VzdG9tIE9YUEhPUyBnZW5lcwpQaG9zcGhvcnlsYXRpb25fb3h5ZGF0aXZlIDwtIGMoCiAgIkNPWDZDUDMiLCJDT1gxNyIsIlRDSVJHMSIsIkFUUDVQRCIsIkFUUDVNRyIsIlVRQ1IxMSIsIkNPWDZCMiIsIk5EVUZBMTEiLCJBVFA2VjFHMyIsIkNPWDRJMSIsCiAgIkNPWDVCIiwiQ09YNkExIiwiQ09YNkEyIiwiQ09YNkIxIiwiQ09YNkMiLCJDT1g3QTEiLCJDT1g3QTIiLCJDT1g3QiIsIkNPWDdDIiwiQ09YOEEiLCJDT1gxMCIsCiAgIkNPWDExIiwiQ09YMTUiLCJDWUMxIiwiQVRQNlYwRTIiLCJDT1g3QjIiLCJBVFA2VjBBMiIsIkFUUDZWMEQyIiwiQVRQNlYxQzIiLCJQUEEyIiwiVVFDUlEiLAogICJVUUNSMTAiLCJDT1g4QyIsIk5EVUZTNyIsIkFUUDVNQzFQNSIsIlVRQ1JITCIsIk1ULUFUUDYiLCJNVC1BVFA4IiwiTVQtQ08xIiwiTVQtQ08yIiwiTVQtQ08zIiwKICAiTVQtQ1lCIiwiTVQtTkQxIiwiTVQtTkQyIiwiTVQtTkQzIiwiTVQtTkQ0IiwiTVQtTkQ0TCIsIk1ULU5ENSIsIk1ULU5ENiIsIk5EVUZBMSIsIk5EVUZBMiIsCiAgIk5EVUZBMyIsIk5EVUZBNCIsIk5EVUZBNSIsIk5EVUZBNiIsIk5EVUZBNyIsIk5EVUZBOCIsIk5EVUZBOSIsIk5EVUZBMTAiLCJORFVGQUIxIiwiTkRVRkIxIiwKICAiTkRVRkIyIiwiTkRVRkIzIiwiTkRVRkI0IiwiTkRVRkI1IiwiTkRVRkI2IiwiTkRVRkI3IiwiTkRVRkI4IiwiTkRVRkI5IiwiTkRVRkIxMCIsIk5EVUZDMSIsCiAgIk5EVUZDMiIsIk5EVUZTMSIsIk5EVUZTMiIsIk5EVUZTMyIsIk5EVUZWMSIsIk5EVUZTNCIsIk5EVUZTNSIsIk5EVUZTNiIsIk5EVUZTOCIsIk5EVUZWMiIsCiAgIk5EVUZWMyIsIkFUUDEyQSIsIkFUUDRBIiwiQVRQNEIiLCJBVFA1RjFBIiwiQVRQNUYxQiIsIkFUUDZWMEE0IiwiQVRQNUYxQyIsIkFUUDVGMUQiLCJBVFA2VjFEIiwKICAiQVRQNUYxRSIsIkFUUDVQQiIsIkFUUDVNQzEiLCJBVFA2VjFIIiwiQVRQNU1DMiIsIkFUUDVNQzMiLCJBVFA1TUUiLCJBVFA1UEYiLCJBVFA2VjFBIiwiQVRQNlYxQjEiLAogICJBVFA2VjFCMiIsIkFUUDZWMEMiLCJBVFA2VjFDMSIsIkFUUDZWMUUxIiwiQVRQNlYwQiIsIkFUUDZWMUcyIiwiQVRQNlYwQTEiLCJBVFA2QVAxIiwiQVRQNVBPIiwKICAiUFBBMSIsIk5EVUZBNEwyIiwiU0RIQSIsIlNESEIiLCJTREhDIiwiU0RIRCIsIkxIUFAiLCJTREhDUDUiLCJVUUNSMTBQMSIsIlVRQ1JCIiwiVVFDUkMxIiwKICAiVVFDUkMyIiwiVVFDUkZTMSIsIlVRQ1JIIiwiQ09YNEkyIiwiQVRQNlYwRTEiLCJBVFA2VjFFMiIsIkFUUDZWMEQxIiwiQ09YN0EyTCIsIkFUUDZWMUYiLAogICJDT1g1QSIsIkFUUDZWMUcxIiwiQVRQNU1GIgopCgojIEN1c3RvbSBHbHljb2x5c2lzIGdlbmVzCkdseWNvbHlzaXMgPC0gYygKICAiSEsxIiwgIlBHSzEiLCAiVFBJMSIsICJBTERPQSIsICJFTk8xIiwgIlBLTSIsICJFTk8yIiwgIkFMRE9DIiwgIkVOTzMiLCAiQUxET0IiLAogICJQR0FNMiIsICJHQVBESFMiLCAiR1BJIiwgIlBGS00iLCAiUEZLRkIxIiwgIlBGS0ZCMiIKKQoKTWl0b2Nob25kcmlhbF9nZW5lcyA8LSBjKAoiTVQtTkQxIiwiTVQtTkQyIiwiTVQtTkQzIiwiTVQtTkQ0IiwiTVQtTkQ0TCIsIk1ULU5ENSIsIk1ULU5ENiIsCiJNVC1DWUIiLAoiTVQtQ08xIiwiTVQtQ08yIiwiTVQtQ08zIiwKIk1ULUFUUDYiLCJNVC1BVFA4IgopCgojIFByZXBhcmUgeW91ciBjdXN0b20gbGlzdHMgKGFscmVhZHkgZGVmaW5lZCkKIyBQaG9zcGhvcnlsYXRpb25fb3h5ZGF0aXZlIGFuZCBHbHljb2x5c2lzCiMgTWFrZSBzdXJlIGdlbmVzIGFyZSB1bmlxdWUKY3VzdG9tX294cGhvcyA8LSB1bmlxdWUoUGhvc3Bob3J5bGF0aW9uX294eWRhdGl2ZSkKY3VzdG9tX2dseWNvICA8LSB1bmlxdWUoR2x5Y29seXNpcykKCiMgQ29tYmluZSBpbnRvIGEgbmFtZWQgbGlzdCBmb3IgVUNlbGwgc2NvcmluZwpnZW5lX3NldHMgPC0gbGlzdCgKT1hQSE9TX01TSUcgPSBveHBob3NfbXNpZywKT1hQSE9TX0NVU1RPTSA9IGN1c3RvbV9veHBob3MsCkdMWUNPX01TSUcgPSBnbHljb19tc2lnLApHTFlDT19DVVNUT00gPSBjdXN0b21fZ2x5Y28sCk1JVE9fRVRDX0NVU1RPTSA9IE1pdG9jaG9uZHJpYWxfZ2VuZXMKKQpgYGAKCgojIyBDYWxjdWxhdGUgU2V1cmF0IEVucmljaG1lbnQgU2NvcmVzIGFuZCBWaXN1YWxpemF0aW9ucwpgYGB7ciAsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTE0fQoKQWxsX3NhbXBsZXNfTWVyZ2VkJGNlbGxfbGluZV9vcmRlcmVkIDwtIGZhY3RvcigKICBBbGxfc2FtcGxlc19NZXJnZWQkb3JpZy5pZGVudCwKICBsZXZlbHMgPSBjKCJMMSIsIkwyIiwiTDMiLCJMNCIsIkw1IiwiTDYiLCJMNyIsIkNENFRfbGFiIiwiQ0Q0VF8xMHgiKQopCgpwMSA8LSBTQ3B1YnI6OmRvX0VucmljaG1lbnRIZWF0bWFwKAogIHNhbXBsZSA9IEFsbF9zYW1wbGVzX01lcmdlZCwKICBpbnB1dF9nZW5lX2xpc3QgPSBnZW5lX3NldHMsCiAgZ3JvdXAuYnkgPSAiY2VsbF9saW5lX29yZGVyZWQiLCAgZW5mb3JjZV9zeW1tZXRyeSA9IFRSVUUsIHVzZV92aXJpZGlzID0gRkFMU0UKKQpwMQpgYGAKIyMgQ2FsY3VsYXRlIFNldXJhdCBFbnJpY2htZW50IFNjb3JlcyBhbmQgVmlzdWFsaXphdGlvbnMKYGBge3IgLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQoKcDIgPC0gU0NwdWJyOjpkb19FbnJpY2htZW50SGVhdG1hcChzYW1wbGUgPSBBbGxfc2FtcGxlc19NZXJnZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dF9nZW5lX2xpc3QgPSBnZW5lX3NldHMsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiLCBmbGlwID0gVFJVRSwgZW5mb3JjZV9zeW1tZXRyeSA9IFRSVUUsIHVzZV92aXJpZGlzID0gRkFMU0UpCnAyCmBgYAoKCgpgYGB7ciAsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTh9CnAzIDwtIFNDcHVicjo6ZG9fRW5yaWNobWVudEhlYXRtYXAoc2FtcGxlID0gQWxsX3NhbXBsZXNfTWVyZ2VkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRfZ2VuZV9saXN0ID0gZ2VuZV9zZXRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAuYnkgPSBjKCJQYXRpZW50X29yaWdpbiIsICJvcmlnLmlkZW50IiksIGZsaXAgPSBUUlVFLCAgZW5mb3JjZV9zeW1tZXRyeSA9IFRSVUUsIHVzZV92aXJpZGlzID0gRkFMU0UpCnAzCmBgYAoKIyMgQ2FsY3VsYXRlIFVDZWxsIFNjb3JlcyBhbmQgVmlzdWFsaXphdGlvbnMKYGBge3IgLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQoKcDQgPC0gU0NwdWJyOjpkb19FbnJpY2htZW50SGVhdG1hcChzYW1wbGUgPSBBbGxfc2FtcGxlc19NZXJnZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dF9nZW5lX2xpc3QgPSBnZW5lX3NldHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGlwID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsYXZvciA9ICJVQ2VsbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5mb3JjZV9zeW1tZXRyeSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VfdmlyaWRpcyA9IEZBTFNFKQpwNApgYGAKCiMjIFF1YWxpdHkgQ2hlY2sKYGBge3IgLCBpbmNsdWRlPVRSVUV9CiMgQ2hlY2sgd2hpY2ggZ2VuZXMgYXJlIHByZXNlbnQgb3IgbWlzc2luZyBpbiB0aGUgU2V1cmF0IG9iamVjdApnZW5lX3ByZXNlbmNlIDwtIGxhcHBseShnZW5lX3NldHMsIGZ1bmN0aW9uKGdzZXQpIHsKICBwcmVzZW50IDwtIGdzZXRbZ3NldCAlaW4lIHJvd25hbWVzKEFsbF9zYW1wbGVzX01lcmdlZCldCiAgbWlzc2luZyA8LSBnc2V0WyFnc2V0ICVpbiUgcm93bmFtZXMoQWxsX3NhbXBsZXNfTWVyZ2VkKV0KICBsaXN0KHByZXNlbnQgPSBwcmVzZW50LCBtaXNzaW5nID0gbWlzc2luZykKfSkKCiMgRXhhbXBsZTogdmlldyByZXN1bHRzIGZvciBPWFBIT1NfQ1VTVE9NCmdlbmVfcHJlc2VuY2UkT1hQSE9TX0NVU1RPTSRwcmVzZW50ICAgIyBnZW5lcyBwcmVzZW50CmdlbmVfcHJlc2VuY2UkT1hQSE9TX0NVU1RPTSRtaXNzaW5nICAgIyBnZW5lcyBub3QgZm91bmQKCiMgT3B0aW9uYWw6IHN1bW1hcml6ZSBjb3VudHMKc2FwcGx5KGdlbmVfcHJlc2VuY2UsIGZ1bmN0aW9uKHgpIGMocHJlc2VudCA9IGxlbmd0aCh4JHByZXNlbnQpLCBtaXNzaW5nID0gbGVuZ3RoKHgkbWlzc2luZykpKQoKZ2VuZV9wcmVzZW5jZQpgYGAKCiMgVmlzdWFsaXphdGlvbnMKCiMjIENhbGN1bGF0ZSBVQ2VsbCBFbnJpY2htZW50IFNjb3JlcyBhbmQgVmlzdWFsaXphdGlvbnMtQ3VzdG9tIGxpc3QKYGBge3IgLCBpbmNsdWRlPUZBTFNFfQojIENyZWF0ZSBhIGxpc3Qgd2l0aCBvbmx5IHlvdXIgY3VzdG9tIGdlbmUgc2V0cwpjdXN0b21fZ2VuZV9zZXRzIDwtIGxpc3QoCiAgT1hQSE9TX0NVU1RPTSA9IFBob3NwaG9yeWxhdGlvbl9veHlkYXRpdmUsCiAgR0xZQ09fQ1VTVE9NICA9IEdseWNvbHlzaXMsCiAgTUlUT19FVENfQ1VTVE9NID0gTWl0b2Nob25kcmlhbF9nZW5lcwopCgojIEVuc3VyZSBnZW5lcyBleGlzdCBpbiB0aGUgU2V1cmF0IG9iamVjdApjdXN0b21fZ2VuZV9zZXRzIDwtIGxhcHBseShjdXN0b21fZ2VuZV9zZXRzLCBmdW5jdGlvbih4KSB4W3ggJWluJSByb3duYW1lcyhBbGxfc2FtcGxlc19NZXJnZWQpXSkKCiMgUnVuIGhlYXRtYXAgZm9yIGN1c3RvbSBnZW5lIHNldHMgb25seQpwNSA8LSBTQ3B1YnI6OmRvX0VucmljaG1lbnRIZWF0bWFwKAogIHNhbXBsZSA9IEFsbF9zYW1wbGVzX01lcmdlZCwKICBpbnB1dF9nZW5lX2xpc3QgPSBjdXN0b21fZ2VuZV9zZXRzLAogIGZsaXAgPSBUUlVFLAogIGZsYXZvciA9ICJVQ2VsbCIsCiAgZW5mb3JjZV9zeW1tZXRyeSA9IFRSVUUsCiAgdXNlX3ZpcmlkaXMgPSBGQUxTRSwKKQpwNQpgYGAKCg==