load libraries
Load Object & Set
RNA Assay
Add Standardized Cell
Labels
# ── Borcherding ───────────────────────────────────────────────────────────────
borcherding$cell_label <- ifelse(
borcherding$Disease_state == "Healthy",
"Healthy CD4\u207A T",
"SS Malignant"
)
borcherding$cell_label <- factor(borcherding$cell_label,
levels = c("SS Malignant",
"Healthy CD4\u207A T"))
borcherding$cohort <- "Borcherding et al., 2022"
# ── Herrera ───────────────────────────────────────────────────────────────────
herrera$cell_label <- ifelse(
herrera$condition == "Healthy",
"Healthy CD4\u207A T",
"SS Malignant"
)
herrera$cell_label <- factor(herrera$cell_label,
levels = c("SS Malignant",
"Healthy CD4\u207A T"))
herrera$cohort <- "Herrera et al., 2021"
cat("Borcherding labels:\n")
Borcherding labels:
print(table(borcherding$cell_label))
SS Malignant Healthy CD4⁺ T
33393 4437
cat("\nHerrera labels:\n")
Herrera labels:
print(table(herrera$cell_label))
SS Malignant Healthy CD4⁺ T
6366 4419
Session Info
sessionInfo()
R version 4.5.2 (2025-10-31)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 24.04.3 LTS
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.12.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0 LAPACK version 3.12.0
locale:
[1] LC_CTYPE=en_GB.UTF-8 LC_NUMERIC=C LC_TIME=fr_FR.UTF-8
[4] LC_COLLATE=en_GB.UTF-8 LC_MONETARY=fr_FR.UTF-8 LC_MESSAGES=en_GB.UTF-8
[7] LC_PAPER=fr_FR.UTF-8 LC_NAME=C LC_ADDRESS=C
[10] LC_TELEPHONE=C LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C
time zone: Europe/Paris
tzcode source: system (glibc)
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] shadowtext_0.1.6 patchwork_1.3.2 dplyr_1.2.0 ggpubr_0.6.2
[5] ggplot2_4.0.2 Seurat_5.4.0 SeuratObject_5.3.0 sp_2.2-1
loaded via a namespace (and not attached):
[1] RColorBrewer_1.1-3 rstudioapi_0.18.0 jsonlite_2.0.0
[4] magrittr_2.0.4 spatstat.utils_3.2-1 farver_2.1.2
[7] ragg_1.5.0 vctrs_0.7.1 ROCR_1.0-12
[10] spatstat.explore_3.7-0 rstatix_0.7.3 htmltools_0.5.9
[13] broom_1.0.12 Formula_1.2-5 sctransform_0.4.3
[16] parallelly_1.46.1 KernSmooth_2.23-26 htmlwidgets_1.6.4
[19] ica_1.0-3 plyr_1.8.9 plotly_4.12.0
[22] zoo_1.8-15 igraph_2.2.2 mime_0.13
[25] lifecycle_1.0.5 pkgconfig_2.0.3 Matrix_1.7-4
[28] R6_2.6.1 fastmap_1.2.0 fitdistrplus_1.2-6
[31] future_1.69.0 shiny_1.12.1 digest_0.6.39
[34] tensor_1.5.1 RSpectra_0.16-2 irlba_2.3.7
[37] textshaping_1.0.4 labeling_0.4.3 progressr_0.18.0
[40] spatstat.sparse_3.1-0 httr_1.4.7 polyclip_1.10-7
[43] abind_1.4-8 compiler_4.5.2 fontquiver_0.2.1
[46] withr_3.0.2 S7_0.2.1 backports_1.5.0
[49] carData_3.0-6 fastDummies_1.7.5 ggsignif_0.6.4
[52] MASS_7.3-65 tools_4.5.2 lmtest_0.9-40
[55] otel_0.2.0 httpuv_1.6.16 future.apply_1.20.1
[58] goftest_1.2-3 glue_1.8.0 nlme_3.1-168
[61] promises_1.5.0 grid_4.5.2 Rtsne_0.17
[64] cluster_2.1.8.2 reshape2_1.4.5 generics_0.1.4
[67] gtable_0.3.6 spatstat.data_3.1-9 tidyr_1.3.2
[70] data.table_1.18.2.1 car_3.1-5 utf8_1.2.6
[73] spatstat.geom_3.7-0 RcppAnnoy_0.0.23 ggrepel_0.9.6
[76] RANN_2.6.2 pillar_1.11.1 stringr_1.6.0
[79] spam_2.11-3 RcppHNSW_0.6.0 later_1.4.5
[82] splines_4.5.2 lattice_0.22-9 survival_3.8-3
[85] deldir_2.0-4 tidyselect_1.2.1 fontLiberation_0.1.0
[88] miniUI_0.1.2 pbapply_1.7-4 knitr_1.51
[91] fontBitstreamVera_0.1.1 gridExtra_2.3 scattermore_1.2
[94] xfun_0.56 matrixStats_1.5.0 stringi_1.8.7
[97] lazyeval_0.2.2 evaluate_1.0.5 codetools_0.2-20
[100] gdtools_0.5.0 tibble_3.3.1 cli_3.6.5
[103] uwot_0.2.4 systemfonts_1.3.1 xtable_1.8-4
[106] reticulate_1.44.1 dichromat_2.0-0.1 Rcpp_1.1.1
[109] globals_0.19.0 spatstat.random_3.4-4 png_0.1-8
[112] spatstat.univar_3.1-6 parallel_4.5.2 dotCall64_1.2
[115] listenv_0.10.0 viridisLite_0.4.3 ggiraph_0.9.4
[118] scales_1.4.0 ggridges_0.5.7 purrr_1.2.1
[121] rlang_1.1.7 cowplot_1.2.0
LS0tCnRpdGxlOiAiRmlndXJlIDdGIC0gQ0xJQzEgVmFsaWRhdGlvbiB8IEJvcmNoZXJkaW5nIDIwMjIgJiBIZXJyZXJhIDIwMjEiCmF1dGhvcjogTmFzaXIgTWFobW9vZCBBYmJhc2kKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGNzczogc3R5bGUuY3NzCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHRydWUKICAgIHRoZW1lOiBqb3VybmFsCi0tLQoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyAgICAgICA9IFRSVUUsCiAgd2FybmluZyAgICA9IEZBTFNFLAogIG1lc3NhZ2UgICAgPSBGQUxTRSwKICBmaWcud2lkdGggID0gMTAsCiAgZmlnLmhlaWdodCA9IDYsCiAgZHBpICAgICAgICA9IDMwMAopCmBgYAoKCgoKIyBsb2FkIGxpYnJhcmllcwpgYGB7ciAsIGluY2x1ZGU9RkFMU0V9CgpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdncHVicikKbGlicmFyeShkcGx5cikKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoc2hhZG93dGV4dCkgICAjIGZvciB3aGl0ZS1vdXRsaW5lZCBsYWJlbHMgb24gVU1BUAoKYGBgCgoKIyBMb2FkIE9iamVjdCAmIFNldCBSTkEgQXNzYXkKYGBge3IgLCBpbmNsdWRlPUZBTFNFfQoKYm9yY2hlcmRpbmcgPC0gcmVhZFJEUygiL2hvbWUvYmlvaW5mby8xLVRoZXNpc19GaW5hbF9ZZWFyXzIwMjUvMjAyNS1ZZWFyM19BbmFseXNpcy8xLXNjUk5BX1JFU1VMVFMtMTktMTEtMjAyNS8xLUJpb21hcmtlcnNfVmFsaWRhdGlvbl93aXRoX1B1YmxpY19EYXRhLUF1Z3VzdDIwMjUvQm9yY2hfQ29tYmluZWQvZGF0YS9TZXphcnlfU1NfdnNfSENfX0JvcmNoZXJkaW5nMjAyM19UQ1JfZmlsdGVyZWQucmRzIikKCmhlcnJlcmEgICAgIDwtIHJlYWRSRFMoIi9ob21lL2Jpb2luZm8vMS1UaGVzaXNfRmluYWxfWWVhcl8yMDI1LzIwMjUtWWVhcjNfQW5hbHlzaXMvMS1zY1JOQV9SRVNVTFRTLTE5LTExLTIwMjUvMS1CaW9tYXJrZXJzX1ZhbGlkYXRpb25fd2l0aF9QdWJsaWNfRGF0YS1BdWd1c3QyMDI1L0hlcnJlcmFfRGF0YS9IZXJyYXJhX1RDUl9BQi9BbmFseXNpcy9TZXphcnlfQmxvb2RfU2tpbl92c19IQ19UQ1JfZmlsdGVyZWQucmRzIikKCiMg4pSA4pSAIFJOQSBhc3NheSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKRGVmYXVsdEFzc2F5KGJvcmNoZXJkaW5nKSA8LSAiUk5BIgpEZWZhdWx0QXNzYXkoaGVycmVyYSkgICAgIDwtICJSTkEiCgojIOKUgOKUgCBKb2luIGxheWVycyAoU2V1cmF0IHY1KSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKYm9yY2hlcmRpbmcgPC0gSm9pbkxheWVycyhib3JjaGVyZGluZykKaGVycmVyYSAgICAgPC0gSm9pbkxheWVycyhoZXJyZXJhKQoKY2F0KCJCb3JjaGVyZGluZyDigJQgQ2VsbHM6IiwgbmNvbChib3JjaGVyZGluZyksICJcbiIpCnByaW50KHRhYmxlKGJvcmNoZXJkaW5nJERpc2Vhc2Vfc3RhdGUpKQoKY2F0KCJcbkhlcnJlcmEg4oCUIENlbGxzOiIsIG5jb2woaGVycmVyYSksICJcbiIpCnByaW50KHRhYmxlKGhlcnJlcmEkY29uZGl0aW9uKSkKCmNhdCgiXG5DTElDMSBpbiBCb3JjaGVyZGluZzoiLCAiQ0xJQzEiICVpbiUgcm93bmFtZXMoYm9yY2hlcmRpbmcpLCAiXG4iKQpjYXQoIkNMSUMxIGluIEhlcnJlcmE6ICAgICIsICJDTElDMSIgJWluJSByb3duYW1lcyhoZXJyZXJhKSwgICAgICJcbiIpCmBgYAoKCgoKCgojIyBBZGQgU3RhbmRhcmRpemVkIENlbGwgTGFiZWxzCmBgYHtyIHBhdGhzfQojIOKUgOKUgCBCb3JjaGVyZGluZyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKYm9yY2hlcmRpbmckY2VsbF9sYWJlbCA8LSBpZmVsc2UoCiAgYm9yY2hlcmRpbmckRGlzZWFzZV9zdGF0ZSA9PSAiSGVhbHRoeSIsCiAgIkhlYWx0aHkgQ0Q0XHUyMDdBIFQiLAogICJTUyBNYWxpZ25hbnQiCikKYm9yY2hlcmRpbmckY2VsbF9sYWJlbCA8LSBmYWN0b3IoYm9yY2hlcmRpbmckY2VsbF9sYWJlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlNTIE1hbGlnbmFudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIZWFsdGh5IENENFx1MjA3QSBUIikpCmJvcmNoZXJkaW5nJGNvaG9ydCA8LSAiQm9yY2hlcmRpbmcgZXQgYWwuLCAyMDIyIgoKIyDilIDilIAgSGVycmVyYSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKaGVycmVyYSRjZWxsX2xhYmVsIDwtIGlmZWxzZSgKICBoZXJyZXJhJGNvbmRpdGlvbiA9PSAiSGVhbHRoeSIsCiAgIkhlYWx0aHkgQ0Q0XHUyMDdBIFQiLAogICJTUyBNYWxpZ25hbnQiCikKaGVycmVyYSRjZWxsX2xhYmVsIDwtIGZhY3RvcihoZXJyZXJhJGNlbGxfbGFiZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlNTIE1hbGlnbmFudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkhlYWx0aHkgQ0Q0XHUyMDdBIFQiKSkKaGVycmVyYSRjb2hvcnQgPC0gIkhlcnJlcmEgZXQgYWwuLCAyMDIxIgoKY2F0KCJCb3JjaGVyZGluZyBsYWJlbHM6XG4iKQpwcmludCh0YWJsZShib3JjaGVyZGluZyRjZWxsX2xhYmVsKSkKY2F0KCJcbkhlcnJlcmEgbGFiZWxzOlxuIikKcHJpbnQodGFibGUoaGVycmVyYSRjZWxsX2xhYmVsKSkKYGBgCgojIEV4dHJhY3QgQ0xJQzEgRXhwcmVzc2lvbgpgYGB7ciAsIG1lc3NhZ2U9RkFMU0V9CmRmX2JvcmNoIDwtIEZldGNoRGF0YShib3JjaGVyZGluZywKICAgICAgICAgICAgICAgICAgICAgIHZhcnMgPSBjKCJDTElDMSIsICJjZWxsX2xhYmVsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb2hvcnQiLCAiRGlzZWFzZV9zdGF0ZSIpKSAlPiUKICAgICAgICAgICAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oImNlbGxfaWQiKSAlPiUKICAgICAgICAgICAgcmVuYW1lKGdyb3VwID0gRGlzZWFzZV9zdGF0ZSkKCmRmX2hlcnIgIDwtIEZldGNoRGF0YShoZXJyZXJhLAogICAgICAgICAgICAgICAgICAgICAgdmFycyA9IGMoIkNMSUMxIiwgImNlbGxfbGFiZWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvaG9ydCIsICJjb25kaXRpb24iKSkgJT4lCiAgICAgICAgICAgIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJjZWxsX2lkIikgJT4lCiAgICAgICAgICAgIHJlbmFtZShncm91cCA9IGNvbmRpdGlvbikKCiMgQ29tYmluZQpjbGljMV9kZiA8LSByYmluZChkZl9ib3JjaCwgZGZfaGVycikKCmNsaWMxX2RmJGNvaG9ydCA8LSBmYWN0b3IoY2xpYzFfZGYkY29ob3J0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJIZXJyZXJhIGV0IGFsLiwgMjAyMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJvcmNoZXJkaW5nIGV0IGFsLiwgMjAyMiIpKQoKIyBTdW1tYXJ5IHN0YXRpc3RpY3MKY2F0KCI9PT0gQ0xJQzEgRXhwcmVzc2lvbiBTdW1tYXJ5ID09PVxuIikKY2xpYzFfZGYgJT4lCiAgZ3JvdXBfYnkoY29ob3J0LCBjZWxsX2xhYmVsKSAlPiUKICBzdW1tYXJpc2UoCiAgICBuICAgICAgPSBuKCksCiAgICBtZWFuICAgPSByb3VuZChtZWFuKENMSUMxKSwgICAzKSwKICAgIG1lZGlhbiA9IHJvdW5kKG1lZGlhbihDTElDMSksIDMpLAogICAgLmdyb3VwcyA9ICJkcm9wIgogICkgJT4lCiAgcHJpbnQoKQoKYGBgCgojIyBIZWxwZXI6IFVNQVAgQ2VudHJvaWQgRnVuY3Rpb24KYGBge3IgLCBtZXNzYWdlPUZBTFNFfQojIENvbXB1dGVzIG1lZGlhbiBVTUFQIGNvb3JkaW5hdGVzIHBlciBjZWxsX2xhYmVsIGdyb3VwCmdldF9jZW50cm9pZHMgPC0gZnVuY3Rpb24oc2V1cmF0X29iaiwgcmVkdWN0aW9uID0gInVtYXAiKSB7CiAgY29vcmRzIDwtIGFzLmRhdGEuZnJhbWUoCiAgICBFbWJlZGRpbmdzKHNldXJhdF9vYmosIHJlZHVjdGlvbiA9IHJlZHVjdGlvbikKICApCiAgY29sbmFtZXMoY29vcmRzKSA8LSBjKCJVTUFQXzEiLCAiVU1BUF8yIikKICBjb29yZHMkbGFiZWwgPC0gc2V1cmF0X29iaiRjZWxsX2xhYmVsCgogIGNvb3JkcyAlPiUKICAgIGdyb3VwX2J5KGxhYmVsKSAlPiUKICAgIHN1bW1hcmlzZSgKICAgICAgVU1BUF8xICA9IG1lZGlhbihVTUFQXzEpLAogICAgICBVTUFQXzIgID0gbWVkaWFuKFVNQVBfMiksCiAgICAgIC5ncm91cHMgPSAiZHJvcCIKICAgICkKfQoKY2VudHJvaWRzX2ggPC0gZ2V0X2NlbnRyb2lkcyhoZXJyZXJhLCAgICAgInVtYXAiKQpjZW50cm9pZHNfYiA8LSBnZXRfY2VudHJvaWRzKGJvcmNoZXJkaW5nLCAidW1hcCIpCgpjYXQoIkhlcnJlcmEgY2VudHJvaWRzOlxuIik7ICAgIHByaW50KGNlbnRyb2lkc19oKQpjYXQoIlxuQm9yY2hlcmRpbmcgY2VudHJvaWRzOlxuIik7IHByaW50KGNlbnRyb2lkc19iKQoKYGBgCgojIyBGaWd1cmUgN0Yg4oCUIE1haW4gQ29tYmluZWQgVmlvbGluIFBsb3QxCmBgYHtyICwgbWVzc2FnZT1GQUxTRX0KbXlfY29sb3JzIDwtIGMoIlNTIE1hbGlnbmFudCIgICAgICAgID0gIiNFNjRCMzUiLAogICAgICAgICAgICAgICAiSGVhbHRoeSBDRDRcdTIwN0EgVCIgPSAiIzREQkJENSIpCgpmaWc3RiA8LSBnZ3Bsb3QoY2xpYzFfZGYsCiAgICAgICAgICAgICAgICBhZXMoeCA9IGNlbGxfbGFiZWwsIHkgPSBDTElDMSwgZmlsbCA9IGNlbGxfbGFiZWwpKSArCgogIGdlb21fdmlvbGluKHRyaW0gICAgICA9IFRSVUUsCiAgICAgICAgICAgICAgYWxwaGEgICAgID0gMC44NSwKICAgICAgICAgICAgICBzY2FsZSAgICAgPSAid2lkdGgiLAogICAgICAgICAgICAgIGNvbG9yICAgICA9ICJncmV5MzAiLAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDAuNCkgKwoKICBnZW9tX2JveHBsb3Qod2lkdGggICAgICAgICA9IDAuMTIsCiAgICAgICAgICAgICAgIGZpbGwgICAgICAgICAgPSAid2hpdGUiLAogICAgICAgICAgICAgICBjb2xvciAgICAgICAgID0gImdyZXkyMCIsCiAgICAgICAgICAgICAgIG91dGxpZXIuc2l6ZSAgPSAwLjMsCiAgICAgICAgICAgICAgIG91dGxpZXIuYWxwaGEgPSAwLjQsCiAgICAgICAgICAgICAgIGxpbmV3aWR0aCAgICAgPSAwLjUpICsKCiAgc3RhdF9jb21wYXJlX21lYW5zKAogICAgY29tcGFyaXNvbnMgPSBsaXN0KGMoIlNTIE1hbGlnbmFudCIsICJIZWFsdGh5IENENFx1MjA3QSBUIikpLAogICAgbWV0aG9kICAgICAgPSAid2lsY294LnRlc3QiLAogICAgbGFiZWwgICAgICAgPSAicC5mb3JtYXQiLAogICAgc2l6ZSAgICAgICAgPSA0LAogICAgbGFiZWwueS5ucGMgPSAwLjkzCiAgKSArCgogIGZhY2V0X3dyYXAofiBjb2hvcnQsIHNjYWxlcyA9ICJmcmVlX3kiLCBucm93ID0gMSkgKwoKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBteV9jb2xvcnMpICsKCiAgbGFicygKICAgIHRpdGxlICAgID0gIkNMSUMxIE92ZXJleHByZXNzaW9uIFZhbGlkYXRlZCBBY3Jvc3MgSW5kZXBlbmRlbnQgU1MgQ29ob3J0cyIsCiAgICBzdWJ0aXRsZSA9ICJXaWxjb3hvbiByYW5rLXN1bSB0ZXN0IHwgbG9nLW5vcm1hbGl6ZWQgZXhwcmVzc2lvbiIsCiAgICB4ICAgICAgICA9ICIiLAogICAgeSAgICAgICAgPSAiQ0xJQzEgRXhwcmVzc2lvbiAobG9nLW5vcm1hbGl6ZWQpIgogICkgKwoKICB0aGVtZV9jbGFzc2ljKGJhc2Vfc2l6ZSA9IDEzKSArCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlICAgICAgID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpLAogICAgcGxvdC5zdWJ0aXRsZSAgICA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgc2l6ZSA9IDEwLCBjb2xvciA9ICJncmV5NTAiKSwKICAgIHN0cmlwLnRleHQgICAgICAgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDEyKSwKICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJncmV5OTUiLCBjb2xvciA9ICJncmV5NzAiKSwKICAgIGF4aXMudGV4dC54ICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSwKICAgIGF4aXMudGV4dC55ICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSwKICAgIHBhbmVsLnNwYWNpbmcgICAgPSB1bml0KDEuNSwgImxpbmVzIiksCiAgICBsZWdlbmQucG9zaXRpb24gID0gIm5vbmUiCiAgKQoKZmlnN0YKCmBgYAoKIyMgRmlndXJlIDdGIOKAlCBNYWluIENvbWJpbmVkIFZpb2xpbiBQbG90MgpgYGB7ciAsIG1lc3NhZ2U9RkFMU0V9Cm15X2NvbG9ycyA8LSBjKCJTUyBNYWxpZ25hbnQiICAgICAgICA9ICIjRTY0QjM1IiwKICAgICAgICAgICAgICAgIkhlYWx0aHkgQ0Q0XHUyMDdBIFQiID0gIiM0REJCRDUiKQoKZmlnN0YgPC0gZ2dwbG90KGNsaWMxX2RmLAogICAgICAgICAgICAgICAgYWVzKHggPSBjZWxsX2xhYmVsLCB5ID0gQ0xJQzEsIGZpbGwgPSBjZWxsX2xhYmVsKSkgKwoKICBnZW9tX3Zpb2xpbih0cmltICAgICAgPSBUUlVFLAogICAgICAgICAgICAgIGFscGhhICAgICA9IDAuODUsCiAgICAgICAgICAgICAgc2NhbGUgICAgID0gIndpZHRoIiwKICAgICAgICAgICAgICBjb2xvciAgICAgPSAiZ3JleTMwIiwKICAgICAgICAgICAgICBsaW5ld2lkdGggPSAwLjQpICsKCiAgZ2VvbV9ib3hwbG90KHdpZHRoICAgICAgICAgPSAwLjEyLAogICAgICAgICAgICAgICBmaWxsICAgICAgICAgID0gIndoaXRlIiwKICAgICAgICAgICAgICAgY29sb3IgICAgICAgICA9ICJncmV5MjAiLAogICAgICAgICAgICAgICBvdXRsaWVyLnNpemUgID0gMC4zLAogICAgICAgICAgICAgICBvdXRsaWVyLmFscGhhID0gMC40LAogICAgICAgICAgICAgICBsaW5ld2lkdGggICAgID0gMC41KSArCgogIHN0YXRfY29tcGFyZV9tZWFucygKICAgIGNvbXBhcmlzb25zID0gbGlzdChjKCJTUyBNYWxpZ25hbnQiLCAiSGVhbHRoeSBDRDRcdTIwN0EgVCIpKSwKICAgIG1ldGhvZCAgICAgID0gIndpbGNveC50ZXN0IiwKICAgIGxhYmVsICAgICAgID0gInAuZm9ybWF0IiwKICAgIHNpemUgICAgICAgID0gNCwKICAgIGxhYmVsLnkubnBjID0gMC45MwogICkgKwoKICBmYWNldF93cmFwKH4gY29ob3J0LCBzY2FsZXMgPSAiZnJlZV95IiwgbnJvdyA9IDEpICsKCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbXlfY29sb3JzKSArCgogIGxhYnMoCiAgICB0aXRsZSAgICA9ICJDTElDMSBPdmVyZXhwcmVzc2lvbiBWYWxpZGF0ZWQgQWNyb3NzIEluZGVwZW5kZW50IFNTIENvaG9ydHMiLAogICAgc3VidGl0bGUgPSAiV2lsY294b24gcmFuay1zdW0gdGVzdCB8IGxvZy1ub3JtYWxpemVkIGV4cHJlc3Npb24iLAogICAgeCAgICAgICAgPSAiIiwKICAgIHkgICAgICAgID0gIkNMSUMxIEV4cHJlc3Npb24gKGxvZy1ub3JtYWxpemVkKSIKICApICsKCiAgdGhlbWVfY2xhc3NpYyhiYXNlX3NpemUgPSAxMykgKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSAgICAgICA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSwKICAgIHBsb3Quc3VidGl0bGUgICAgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHNpemUgPSAxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiZ3JleTUwIiksCiAgICBzdHJpcC50ZXh0ICAgICAgID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxMiksCiAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiZ3JleTk1IiwgY29sb3IgPSAiZ3JleTcwIiksCiAgICBheGlzLnRleHQueCAgICAgID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSksCiAgICBheGlzLnRleHQueSAgICAgID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSksCiAgICBwYW5lbC5zcGFjaW5nICAgID0gdW5pdCgxLjUsICJsaW5lcyIpLAogICAgbGVnZW5kLnBvc2l0aW9uICA9ICJub25lIgogICkKCmZpZzdGCgpgYGAKCgojIyAgVU1BUCBGZWF0dXJlUGxvdHMgd2l0aCBTUy9IZWFsdGh5IExhYmVscwpgYGB7ciAsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTE0fQojIOKUgOKUgCBIZXJyZXJhIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgApwX3VtYXBfaCA8LSBGZWF0dXJlUGxvdChoZXJyZXJhLAogICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgID0gIkNMSUMxIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyICAgICA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xzICAgICAgPSBjKCJncmV5OTAiLCAiI0U2NEIzNSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgcHQuc2l6ZSAgID0gMC4zKSArCgogIGdlb21fc2hhZG93dGV4dChkYXRhICAgICAgICA9IGNlbnRyb2lkc19oLAogICAgICAgICAgICAgICAgICBhZXMoeCAgICAgICA9IFVNQVBfMSwKICAgICAgICAgICAgICAgICAgICAgIHkgICAgICAgPSBVTUFQXzIsCiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCAgID0gbGFiZWwpLAogICAgICAgICAgICAgICAgICBjb2xvciAgICAgICA9ICJibGFjayIsCiAgICAgICAgICAgICAgICAgIGJnLmNvbG9yICAgID0gIndoaXRlIiwKICAgICAgICAgICAgICAgICAgYmcuciAgICAgICAgPSAwLjE1LAogICAgICAgICAgICAgICAgICBmb250ZmFjZSAgICA9ICJib2xkIiwKICAgICAgICAgICAgICAgICAgc2l6ZSAgICAgICAgPSA0LAogICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSArCgogIGxhYnModGl0bGUgPSAiQ0xJQzEgfCBIZXJyZXJhIGV0IGFsLiwgMjAyMSIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiLCBzaXplID0gMTIpKQoKIyDilIDilIAgQm9yY2hlcmRpbmcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACnBfdW1hcF9iIDwtIEZlYXR1cmVQbG90KGJvcmNoZXJkaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgID0gIkNMSUMxIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyICAgICA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xzICAgICAgPSBjKCJncmV5OTAiLCAiI0U2NEIzNSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgcHQuc2l6ZSAgID0gMC4zKSArCgogIGdlb21fc2hhZG93dGV4dChkYXRhICAgICAgICA9IGNlbnRyb2lkc19iLAogICAgICAgICAgICAgICAgICBhZXMoeCAgICAgICA9IFVNQVBfMSwKICAgICAgICAgICAgICAgICAgICAgIHkgICAgICAgPSBVTUFQXzIsCiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCAgID0gbGFiZWwpLAogICAgICAgICAgICAgICAgICBjb2xvciAgICAgICA9ICJibGFjayIsCiAgICAgICAgICAgICAgICAgIGJnLmNvbG9yICAgID0gIndoaXRlIiwKICAgICAgICAgICAgICAgICAgYmcuciAgICAgICAgPSAwLjE1LAogICAgICAgICAgICAgICAgICBmb250ZmFjZSAgICA9ICJib2xkIiwKICAgICAgICAgICAgICAgICAgc2l6ZSAgICAgICAgPSA0LAogICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSArCgogIGxhYnModGl0bGUgPSAiQ0xJQzEgfCBCb3JjaGVyZGluZyBldCBhbC4sIDIwMjIiKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDEyKSkKCnBfdW1hcF9oIHwgcF91bWFwX2IKCmBgYAoKCgoKIyMgIERpbVBsb3Qg4oCUIENlbGwgSWRlbnRpdHkgd2l0aCBMYWJlbHMKYGBge3IgLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xNH0KcF9kaW1faCA8LSBEaW1QbG90KGhlcnJlcmEsCiAgICAgICAgICAgICAgICAgICAgZ3JvdXAuYnkgID0gImNlbGxfbGFiZWwiLAogICAgICAgICAgICAgICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICAgICAgICAgICAgICBjb2xzICAgICAgPSBteV9jb2xvcnMsCiAgICAgICAgICAgICAgICAgICAgcHQuc2l6ZSAgID0gMC4zLAogICAgICAgICAgICAgICAgICAgIGxhYmVsICAgICA9IEZBTFNFKSArCgogIGdlb21fc2hhZG93dGV4dChkYXRhICAgICAgICA9IGNlbnRyb2lkc19oLAogICAgICAgICAgICAgICAgICBhZXMoeCAgICAgICA9IFVNQVBfMSwKICAgICAgICAgICAgICAgICAgICAgIHkgICAgICAgPSBVTUFQXzIsCiAgICAgICAgICAgICAgICAgICAgICBsYWJlbCAgID0gbGFiZWwpLAogICAgICAgICAgICAgICAgICBjb2xvciAgICAgICA9ICJibGFjayIsCiAgICAgICAgICAgICAgICAgIGJnLmNvbG9yICAgID0gIndoaXRlIiwKICAgICAgICAgICAgICAgICAgYmcuciAgICAgICAgPSAwLjE1LAogICAgICAgICAgICAgICAgICBmb250ZmFjZSAgICA9ICJib2xkIiwKICAgICAgICAgICAgICAgICAgc2l6ZSAgICAgICAgPSA0LAogICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSArCgogIGxhYnModGl0bGUgPSAiSGVycmVyYSBldCBhbC4sIDIwMjEiKSArCiAgdGhlbWUocGxvdC50aXRsZSAgICA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKcF9kaW1fYiA8LSBEaW1QbG90KGJvcmNoZXJkaW5nLAogICAgICAgICAgICAgICAgICAgIGdyb3VwLmJ5ICA9ICJjZWxsX2xhYmVsIiwKICAgICAgICAgICAgICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsCiAgICAgICAgICAgICAgICAgICAgY29scyAgICAgID0gbXlfY29sb3JzLAogICAgICAgICAgICAgICAgICAgIHB0LnNpemUgICA9IDAuMywKICAgICAgICAgICAgICAgICAgICBsYWJlbCAgICAgPSBGQUxTRSkgKwoKICBnZW9tX3NoYWRvd3RleHQoZGF0YSAgICAgICAgPSBjZW50cm9pZHNfYiwKICAgICAgICAgICAgICAgICAgYWVzKHggICAgICAgPSBVTUFQXzEsCiAgICAgICAgICAgICAgICAgICAgICB5ICAgICAgID0gVU1BUF8yLAogICAgICAgICAgICAgICAgICAgICAgbGFiZWwgICA9IGxhYmVsKSwKICAgICAgICAgICAgICAgICAgY29sb3IgICAgICAgPSAiYmxhY2siLAogICAgICAgICAgICAgICAgICBiZy5jb2xvciAgICA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgICAgIGJnLnIgICAgICAgID0gMC4xNSwKICAgICAgICAgICAgICAgICAgZm9udGZhY2UgICAgPSAiYm9sZCIsCiAgICAgICAgICAgICAgICAgIHNpemUgICAgICAgID0gNCwKICAgICAgICAgICAgICAgICAgaW5oZXJpdC5hZXMgPSBGQUxTRSkgKwoKICBsYWJzKHRpdGxlID0gIkJvcmNoZXJkaW5nIGV0IGFsLiwgMjAyMiIpICsKICB0aGVtZShwbG90LnRpdGxlICAgID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpwX2RpbV9oIHwgcF9kaW1fYgpgYGAKCgojIyAgRnVsbCBQdWJsaWNhdGlvbiBGaWd1cmUKYGBge3IgLCBmaWcuaGVpZ2h0PTE4LCBmaWcud2lkdGg9MTR9CmZ1bGxfZmlnIDwtIChwX2RpbV9oIHwgcF9kaW1fYikgLwogICAgICAgICAgICAocF91bWFwX2ggfCBwX3VtYXBfYikgLwogICAgICAgICAgICBmaWc3RiArCgogIHBsb3RfbGF5b3V0KGhlaWdodHMgPSBjKDEsIDEsIDEuMikpICsKCiAgcGxvdF9hbm5vdGF0aW9uKAogICAgdGl0bGUgICAgICA9ICJDTElDMSBPdmVyZXhwcmVzc2lvbiBWYWxpZGF0ZWQgaW4gVHdvIEluZGVwZW5kZW50IFNTIENvaG9ydHMiLAogICAgdGFnX2xldmVscyA9ICJBIiwKICAgIHRoZW1lICAgICAgPSB0aGVtZSgKICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE1KQogICAgKQogICkKCmZ1bGxfZmlnCmBgYAoKCgojICAgU2F2ZSBGaWd1cmVzCmBgYHtyfQpkaXIuY3JlYXRlKCJvdXRwdXQiLCBzaG93V2FybmluZ3MgPSBGQUxTRSkKCmdnc2F2ZSgib3V0cHV0L0ZpZ3VyZTdGX0NMSUMxX3Zpb2xpbl9jb21iaW5lZC5wZGYiLAogICAgICAgcGxvdCA9IGZpZzdGLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1LCBkcGkgPSAzMDApCmdnc2F2ZSgib3V0cHV0L0ZpZ3VyZTdGX0NMSUMxX3Zpb2xpbl9jb21iaW5lZC5wbmciLAogICAgICAgcGxvdCA9IGZpZzdGLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1LCBkcGkgPSAzMDApCgpnZ3NhdmUoIm91dHB1dC9GaWd1cmU3Rl9DTElDMV9VTUFQX2xhYmVsZWQucGRmIiwKICAgICAgIHBsb3QgPSBwX3VtYXBfaCB8IHBfdW1hcF9iLAogICAgICAgd2lkdGggPSAxNCwgaGVpZ2h0ID0gNSwgZHBpID0gMzAwKQpnZ3NhdmUoIm91dHB1dC9GaWd1cmU3Rl9DTElDMV9VTUFQX2xhYmVsZWQucG5nIiwKICAgICAgIHBsb3QgPSBwX3VtYXBfaCB8IHBfdW1hcF9iLAogICAgICAgd2lkdGggPSAxNCwgaGVpZ2h0ID0gNSwgZHBpID0gMzAwKQoKZ2dzYXZlKCJvdXRwdXQvRmlndXJlN0ZfRGltUGxvdF9sYWJlbGVkLnBkZiIsCiAgICAgICBwbG90ID0gcF9kaW1faCB8IHBfZGltX2IsCiAgICAgICB3aWR0aCA9IDE0LCBoZWlnaHQgPSA1LCBkcGkgPSAzMDApCmdnc2F2ZSgib3V0cHV0L0ZpZ3VyZTdGX0RpbVBsb3RfbGFiZWxlZC5wbmciLAogICAgICAgcGxvdCA9IHBfZGltX2ggfCBwX2RpbV9iLAogICAgICAgd2lkdGggPSAxNCwgaGVpZ2h0ID0gNSwgZHBpID0gMzAwKQoKZ2dzYXZlKCJvdXRwdXQvRmlndXJlN0ZfZnVsbF9maWd1cmUucGRmIiwKICAgICAgIHBsb3QgPSBmdWxsX2ZpZywgd2lkdGggPSAxNCwgaGVpZ2h0ID0gMTQsIGRwaSA9IDMwMCkKZ2dzYXZlKCJvdXRwdXQvRmlndXJlN0ZfZnVsbF9maWd1cmUucG5nIiwKICAgICAgIHBsb3QgPSBmdWxsX2ZpZywgd2lkdGggPSAxNCwgaGVpZ2h0ID0gMTQsIGRwaSA9IDMwMCkKCmNhdCgiQWxsIGZpZ3VyZXMgc2F2ZWQgdG8gb3V0cHV0L1xuIikKYGBgCgoKCiMgICAgU2Vzc2lvbiBJbmZvCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAoKCgoKCg==