1. load libraries
2. Load Seurat Object
#Load Seurat Object merged from cell lines and a control(PBMC) after filtration
load("../../../0-IMP-OBJECTS/All_Samples_Merged_with_10x_Azitmuth_Annotated.robj")
All_samples_Merged
An object of class Seurat
36752 features across 59355 samples within 5 assays
Active assay: RNA (36601 features, 0 variable features)
2 layers present: data, counts
4 other assays present: ADT, prediction.score.celltype.l1, prediction.score.celltype.l2, prediction.score.celltype.l3
2 dimensional reductions calculated: integrated_dr, ref.umap
3. Data PREPARATION
# Data Preparation for Seurat v5
alldata <- All_samples_Merged
# Split the object by 'orig.ident' for individual dataset processing
alldata.list <- SplitObject(alldata, split.by = "orig.ident")
# Normalize and identify variable features for each dataset in the list
for (i in 1:length(alldata.list)) {
alldata.list[[i]] <- NormalizeData(alldata.list[[i]], verbose = FALSE)
alldata.list[[i]] <- FindVariableFeatures(alldata.list[[i]], selection.method = "vst", nfeatures = 2000, verbose = FALSE)
}
# Get the variable genes for each dataset
hvgs_per_dataset <- lapply(alldata.list, VariableFeatures)
# Include the variable genes selected on the whole dataset
hvgs_per_dataset$all <- VariableFeatures(alldata)
# Create a heatmap to show overlap across datasets
temp <- unique(unlist(hvgs_per_dataset))
overlap <- sapply(hvgs_per_dataset, function(x) temp %in% x)
pheatmap::pheatmap(t(overlap * 1), cluster_rows = FALSE,
color = c("grey90", "grey20"))

# Select integration features across datasets
hvgs_all <- SelectIntegrationFeatures(alldata.list)
hvgs_per_dataset$all_ranks <- hvgs_all
# Generate the overlap heatmap for all selected integration features
temp <- unique(unlist(hvgs_per_dataset))
overlap <- sapply(hvgs_per_dataset, function(x) temp %in% x)
pheatmap::pheatmap(t(overlap * 1), cluster_rows = FALSE,
color = c("grey90", "grey20"))

# Scale and PCA on each dataset using selected integration features
alldata.list <- lapply(alldata.list, function(x) {
x <- ScaleData(x, features = hvgs_all, verbose = FALSE)
x <- RunPCA(x, features = hvgs_all, verbose = FALSE)
})
4. rpca-integration


wrap_plots(
DimPlot(alldata.int, reduction = "pca_rpca", group.by = "orig.ident")+NoAxes()+ggtitle("PCA integrated"),
DimPlot(alldata.int, reduction = "tsne_rpca", group.by = "orig.ident")+NoAxes()+ggtitle("tSNE integrated"),
DimPlot(alldata.int, reduction = "umap_rpca", group.by = "orig.ident")+NoAxes()+ggtitle("UMAP integrated"),
DimPlot(alldata.int, reduction = "pca_rpca", group.by = "rpca_snn_res.1.2")+NoAxes()+ggtitle("PCA integrated"),
DimPlot(alldata.int, reduction = "tsne_rpca", group.by = "rpca_snn_res.1.2")+NoAxes()+ggtitle("tSNE integrated"),
DimPlot(alldata.int, reduction = "umap_rpca", group.by = "rpca_snn_res.1.2")+NoAxes()+ggtitle("UMAP integrated"),
ncol = 3) + plot_layout(guides = "collect")
DimPlot(alldata.int, reduction = "pca_rpca", group.by = "orig.ident")+NoAxes()+ggtitle("PCA integrated")
DimPlot(alldata.int, reduction = "tsne_rpca", group.by = "orig.ident")+NoAxes()+ggtitle("tSNE integrated")

DimPlot(alldata.int, reduction = "umap_rpca", group.by = "orig.ident")+NoAxes()+ggtitle("UMAP integrated")

DimPlot(alldata.int, reduction = "umap_rpca", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("UMAP integrated")

DimPlot(alldata.int, reduction = "pca_rpca", group.by = "rpca_snn_res.1.2")+NoAxes()+ggtitle("PCA integrated")

DimPlot(alldata.int, reduction = "tsne_rpca", group.by = "rpca_snn_res.1.2")+NoAxes()+ggtitle("tSNE integrated")

DimPlot(alldata.int, reduction = "umap_rpca", group.by = "rpca_snn_res.1.2")+NoAxes()+ggtitle("UMAP integrated")

DimPlot(alldata.int, reduction = "umap_rpca", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("UMAP integrated")

clean memory
5. CCA-integration
alldata.anchors <- FindIntegrationAnchors(object.list = alldata.list, dims = 1:20, reduction = "cca", anchor.features = hvgs_all)
Scaling features for provided objects
| | 0 % ~calculating
|++++++ | 11% ~06s
|++++++++++++ | 22% ~05s
|+++++++++++++++++ | 33% ~04s
|+++++++++++++++++++++++ | 44% ~04s
|++++++++++++++++++++++++++++ | 56% ~03s
|++++++++++++++++++++++++++++++++++ | 67% ~02s
|+++++++++++++++++++++++++++++++++++++++ | 78% ~01s
|+++++++++++++++++++++++++++++++++++++++++++++ | 89% ~01s
|++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=07s
Finding all pairwise anchors
| | 0 % ~calculating
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 17582 anchors
Filtering anchors
Retained 4390 anchors
|++ | 3 % ~54m 31s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 18513 anchors
Filtering anchors
Retained 3622 anchors
|+++ | 6 % ~49m 43s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 20076 anchors
Filtering anchors
Retained 3917 anchors
|+++++ | 8 % ~49m 30s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 16847 anchors
Filtering anchors
Retained 4035 anchors
|++++++ | 11% ~45m 26s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 18298 anchors
Filtering anchors
Retained 3937 anchors
|+++++++ | 14% ~43m 02s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 18874 anchors
Filtering anchors
Retained 4778 anchors
|+++++++++ | 17% ~41m 52s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 17248 anchors
Filtering anchors
Retained 3219 anchors
|++++++++++ | 19% ~39m 31s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 18747 anchors
Filtering anchors
Retained 4198 anchors
|++++++++++++ | 22% ~37m 57s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 18982 anchors
Filtering anchors
Retained 5431 anchors
|+++++++++++++ | 25% ~37m 10s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 17453 anchors
Filtering anchors
Retained 5515 anchors
|++++++++++++++ | 28% ~35m 49s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 16315 anchors
Filtering anchors
Retained 3622 anchors
|++++++++++++++++ | 31% ~33m 58s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 17457 anchors
Filtering anchors
Retained 3813 anchors
|+++++++++++++++++ | 33% ~32m 28s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 18135 anchors
Filtering anchors
Retained 4714 anchors
|+++++++++++++++++++ | 36% ~31m 28s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 16499 anchors
Filtering anchors
Retained 4824 anchors
|++++++++++++++++++++ | 39% ~30m 03s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 16944 anchors
Filtering anchors
Retained 5311 anchors
|+++++++++++++++++++++ | 42% ~28m 36s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 16195 anchors
Filtering anchors
Retained 3381 anchors
|+++++++++++++++++++++++ | 44% ~26m 57s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 17093 anchors
Filtering anchors
Retained 3639 anchors
|++++++++++++++++++++++++ | 47% ~25m 27s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 17425 anchors
Filtering anchors
Retained 4174 anchors
|+++++++++++++++++++++++++ | 50% ~24m 07s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 16371 anchors
Filtering anchors
Retained 6258 anchors
|+++++++++++++++++++++++++++ | 53% ~22m 41s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 16308 anchors
Filtering anchors
Retained 6736 anchors
|++++++++++++++++++++++++++++ | 56% ~21m 14s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 15342 anchors
Filtering anchors
Retained 5510 anchors
|++++++++++++++++++++++++++++++ | 58% ~19m 39s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 18467 anchors
Filtering anchors
Retained 1372 anchors
|+++++++++++++++++++++++++++++++ | 61% ~18m 23s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 19665 anchors
Filtering anchors
Retained 1083 anchors
|++++++++++++++++++++++++++++++++ | 64% ~17m 12s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 19261 anchors
Filtering anchors
Retained 567 anchors
|++++++++++++++++++++++++++++++++++ | 67% ~16m 04s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 18082 anchors
Filtering anchors
Retained 1019 anchors
|+++++++++++++++++++++++++++++++++++ | 69% ~14m 50s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 18827 anchors
Filtering anchors
Retained 647 anchors
|+++++++++++++++++++++++++++++++++++++ | 72% ~13m 37s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 17086 anchors
Filtering anchors
Retained 641 anchors
|++++++++++++++++++++++++++++++++++++++ | 75% ~12m 09s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 17461 anchors
Filtering anchors
Retained 730 anchors
|+++++++++++++++++++++++++++++++++++++++ | 78% ~10m 44s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 19554 anchors
Filtering anchors
Retained 1051 anchors
|+++++++++++++++++++++++++++++++++++++++++ | 81% ~09m 24s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 21001 anchors
Filtering anchors
Retained 985 anchors
|++++++++++++++++++++++++++++++++++++++++++ | 83% ~08m 05s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 20852 anchors
Filtering anchors
Retained 589 anchors
|++++++++++++++++++++++++++++++++++++++++++++ | 86% ~06m 49s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 19662 anchors
Filtering anchors
Retained 793 anchors
|+++++++++++++++++++++++++++++++++++++++++++++ | 89% ~05m 31s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 20342 anchors
Filtering anchors
Retained 506 anchors
|++++++++++++++++++++++++++++++++++++++++++++++ | 92% ~04m 10s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 18548 anchors
Filtering anchors
Retained 461 anchors
|++++++++++++++++++++++++++++++++++++++++++++++++ | 94% ~02m 46s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 18397 anchors
Filtering anchors
Retained 593 anchors
|+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~01m 23s
Running CCA
Merging objects
Finding neighborhoods
Finding anchors
Found 18764 anchors
Filtering anchors
Retained 6192 anchors
|++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=51m 03s
gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 14534635 776.3 22490452 1201.2 22490452 1201.2
Vcells 2560499425 19535.1 7316888909 55823.5 7316863687 55823.3
alldata.int <- IntegrateData(anchorset = alldata.anchors, dims = 1:20, new.assay.name = "CCA")
Merging dataset 7 into 5
Extracting anchors for merged samples
Finding integration vectors
Finding integration vector weights
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Integrating data
Avis : Layer counts isn't present in the assay object; returning NULLMerging dataset 6 into 5 7
Extracting anchors for merged samples
Finding integration vectors
Avis : Different cells in new layer data than already exists for scale.dataFinding integration vector weights
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Integrating data
Avis : Layer counts isn't present in the assay object; returning NULLMerging dataset 4 into 5 7 6
Extracting anchors for merged samples
Finding integration vectors
Avis : Different cells in new layer data than already exists for scale.dataFinding integration vector weights
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Integrating data
Avis : Layer counts isn't present in the assay object; returning NULLMerging dataset 3 into 5 7 6 4
Extracting anchors for merged samples
Finding integration vectors
Avis : Different cells in new layer data than already exists for scale.dataFinding integration vector weights
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Integrating data
Avis : Layer counts isn't present in the assay object; returning NULLMerging dataset 1 into 2
Extracting anchors for merged samples
Finding integration vectors
Finding integration vector weights
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Integrating data
Avis : Layer counts isn't present in the assay object; returning NULLMerging dataset 8 into 9
Extracting anchors for merged samples
Finding integration vectors
Finding integration vector weights
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Integrating data
Avis : Layer counts isn't present in the assay object; returning NULLMerging dataset 2 1 into 5 7 6 4 3
Extracting anchors for merged samples
Finding integration vectors
Finding integration vector weights
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Integrating data
Avis : Layer counts isn't present in the assay object; returning NULLMerging dataset 9 8 into 5 7 6 4 3 2 1
Extracting anchors for merged samples
Finding integration vectors
Finding integration vector weights
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Integrating data
Avis : Layer counts isn't present in the assay object; returning NULL
names(alldata.int@assays)
[1] "RNA" "ADT" "prediction.score.celltype.l1" "prediction.score.celltype.l2"
[5] "prediction.score.celltype.l3" "CCA"
alldata.int@active.assay
[1] "CCA"
DefaultAssay(alldata.int) <- "CCA"
#Run Dimensionality reduction on integrated space
alldata.int <- ScaleData(alldata.int, verbose = TRUE)
Centering and scaling data matrix
|
| | 0%
|
|============================================================ | 50%
|
|=========================================================================================================================| 100%
alldata.int <- RunPCA(alldata.int, features = hvgs_all, reduction.name = "pca_CCA", do.print = TRUE, pcs.print = 1:5, genes.print = 15, verbose = FALSE)
alldata.int <- RunUMAP(alldata.int, reduction = "pca_CCA", reduction.name = "umap_CCA", dims = 1:20, verbose = FALSE)
alldata.int <- RunTSNE(alldata.int, reduction = "pca_CCA",reduction.name = "tsne_CCA",dims = 1:20, verbose = FALSE)
alldata.int <- FindNeighbors(alldata.int, reduction = "pca_CCA", dims = 1:20, verbose = FALSE)
alldata.int <- FindClusters(alldata.int, resolution = 1.2, verbose = FALSE)
wrap_plots(
DimPlot(alldata.int, reduction = "pca_CCA", group.by = "orig.ident")+NoAxes()+ggtitle("PCA integrated"),
DimPlot(alldata.int, reduction = "tsne_CCA", group.by = "orig.ident")+NoAxes()+ggtitle("tSNE integrated"),
DimPlot(alldata.int, reduction = "umap_CCA", group.by = "orig.ident")+NoAxes()+ggtitle("UMAP integrated"),
DimPlot(alldata.int, reduction = "pca_CCA", group.by = "CCA_snn_res.1.2")+NoAxes()+ggtitle("PCA integrated"),
DimPlot(alldata.int, reduction = "tsne_CCA", group.by = "CCA_snn_res.1.2")+NoAxes()+ggtitle("tSNE integrated"),
DimPlot(alldata.int, reduction = "umap_CCA", group.by = "CCA_snn_res.1.2")+NoAxes()+ggtitle("UMAP integrated"),
ncol = 3) + plot_layout(guides = "collect")

DimPlot(alldata.int, reduction = "pca_CCA", group.by = "orig.ident")+NoAxes()+ggtitle("PCA integrated")

DimPlot(alldata.int, reduction = "tsne_CCA", group.by = "orig.ident")+NoAxes()+ggtitle("tSNE integrated")

DimPlot(alldata.int, reduction = "umap_CCA", group.by = "orig.ident")+NoAxes()+ggtitle("UMAP integrated")

DimPlot(alldata.int, reduction = "umap_CCA", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("UMAP integrated")

DimPlot(alldata.int, reduction = "pca_CCA", group.by = "CCA_snn_res.1.2")+NoAxes()+ggtitle("PCA integrated")

DimPlot(alldata.int, reduction = "tsne_CCA", group.by = "CCA_snn_res.1.2")+NoAxes()+ggtitle("tSNE integrated")

DimPlot(alldata.int, reduction = "umap_CCA", group.by = "CCA_snn_res.1.2")+NoAxes()+ggtitle("UMAP integrated")

DimPlot(alldata.int, reduction = "umap_CCA", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("UMAP integrated")

clean memory
# remove all objects that will not be used
rm(alldata.anchors)
gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 14534570 776.3 22490452 1201.2 22490452 1201.2
Vcells 2440142574 18616.9 7316888909 55823.5 7316863687 55823.3
6. Harmony-integration
alldata.int@active.assay = "RNA"
VariableFeatures(alldata.int) = hvgs_all
alldata.int = ScaleData(alldata.int, vars.to.regress = c("percent.mt", "nFeature_RNA"))
Regressing out percent.mt, nFeature_RNA
|
| | 0%
|
|= | 0%
|
|= | 1%
|
|== | 1%
|
|== | 2%
|
|=== | 2%
|
|=== | 3%
|
|==== | 3%
|
|==== | 4%
|
|===== | 4%
|
|===== | 5%
|
|====== | 5%
|
|====== | 6%
|
|======= | 6%
|
|======= | 7%
|
|======== | 7%
|
|======== | 8%
|
|========= | 8%
|
|========= | 9%
|
|========== | 9%
|
|========== | 10%
|
|=========== | 10%
|
|============ | 10%
|
|============ | 11%
|
|============= | 11%
|
|============= | 12%
|
|============== | 12%
|
|============== | 13%
|
|=============== | 13%
|
|=============== | 14%
|
|================ | 14%
|
|================ | 15%
|
|================= | 15%
|
|================= | 16%
|
|================== | 16%
|
|================== | 17%
|
|=================== | 17%
|
|=================== | 18%
|
|==================== | 18%
|
|==================== | 19%
|
|===================== | 19%
|
|===================== | 20%
|
|====================== | 20%
|
|======================= | 20%
|
|======================= | 21%
|
|======================== | 21%
|
|======================== | 22%
|
|========================= | 22%
|
|========================= | 23%
|
|========================== | 23%
|
|========================== | 24%
|
|=========================== | 24%
|
|=========================== | 25%
|
|============================ | 25%
|
|============================ | 26%
|
|============================= | 26%
|
|============================= | 27%
|
|============================== | 27%
|
|============================== | 28%
|
|=============================== | 28%
|
|=============================== | 29%
|
|================================ | 29%
|
|================================ | 30%
|
|================================= | 30%
|
|================================== | 30%
|
|================================== | 31%
|
|=================================== | 31%
|
|=================================== | 32%
|
|==================================== | 32%
|
|==================================== | 33%
|
|===================================== | 33%
|
|===================================== | 34%
|
|====================================== | 34%
|
|====================================== | 35%
|
|======================================= | 35%
|
|======================================= | 36%
|
|======================================== | 36%
|
|======================================== | 37%
|
|========================================= | 37%
|
|========================================= | 38%
|
|========================================== | 38%
|
|========================================== | 39%
|
|=========================================== | 39%
|
|=========================================== | 40%
|
|============================================ | 40%
|
|============================================= | 40%
|
|============================================= | 41%
|
|============================================== | 41%
|
|============================================== | 42%
|
|=============================================== | 42%
|
|=============================================== | 43%
|
|================================================ | 43%
|
|================================================ | 44%
|
|================================================= | 44%
|
|================================================= | 45%
|
|================================================== | 45%
|
|================================================== | 46%
|
|=================================================== | 46%
|
|=================================================== | 47%
|
|==================================================== | 47%
|
|==================================================== | 48%
|
|===================================================== | 48%
|
|===================================================== | 49%
|
|====================================================== | 49%
|
|====================================================== | 50%
|
|======================================================= | 50%
|
|======================================================== | 50%
|
|======================================================== | 51%
|
|========================================================= | 51%
|
|========================================================= | 52%
|
|========================================================== | 52%
|
|========================================================== | 53%
|
|=========================================================== | 53%
|
|=========================================================== | 54%
|
|============================================================ | 54%
|
|============================================================ | 55%
|
|============================================================= | 55%
|
|============================================================= | 56%
|
|============================================================== | 56%
|
|============================================================== | 57%
|
|=============================================================== | 57%
|
|=============================================================== | 58%
|
|================================================================ | 58%
|
|================================================================ | 59%
|
|================================================================= | 59%
|
|================================================================= | 60%
|
|================================================================== | 60%
|
|=================================================================== | 60%
|
|=================================================================== | 61%
|
|==================================================================== | 61%
|
|==================================================================== | 62%
|
|===================================================================== | 62%
|
|===================================================================== | 63%
|
|====================================================================== | 63%
|
|====================================================================== | 64%
|
|======================================================================= | 64%
|
|======================================================================= | 65%
|
|======================================================================== | 65%
|
|======================================================================== | 66%
|
|========================================================================= | 66%
|
|========================================================================= | 67%
|
|========================================================================== | 67%
|
|========================================================================== | 68%
|
|=========================================================================== | 68%
|
|=========================================================================== | 69%
|
|============================================================================ | 69%
|
|============================================================================ | 70%
|
|============================================================================= | 70%
|
|============================================================================== | 70%
|
|============================================================================== | 71%
|
|=============================================================================== | 71%
|
|=============================================================================== | 72%
|
|================================================================================ | 72%
|
|================================================================================ | 73%
|
|================================================================================= | 73%
|
|================================================================================= | 74%
|
|================================================================================== | 74%
|
|================================================================================== | 75%
|
|=================================================================================== | 75%
|
|=================================================================================== | 76%
|
|==================================================================================== | 76%
|
|==================================================================================== | 77%
|
|===================================================================================== | 77%
|
|===================================================================================== | 78%
|
|====================================================================================== | 78%
|
|====================================================================================== | 79%
|
|======================================================================================= | 79%
|
|======================================================================================= | 80%
|
|======================================================================================== | 80%
|
|========================================================================================= | 80%
|
|========================================================================================= | 81%
|
|========================================================================================== | 81%
|
|========================================================================================== | 82%
|
|=========================================================================================== | 82%
|
|=========================================================================================== | 83%
|
|============================================================================================ | 83%
|
|============================================================================================ | 84%
|
|============================================================================================= | 84%
|
|============================================================================================= | 85%
|
|============================================================================================== | 85%
|
|============================================================================================== | 86%
|
|=============================================================================================== | 86%
|
|=============================================================================================== | 87%
|
|================================================================================================ | 87%
|
|================================================================================================ | 88%
|
|================================================================================================= | 88%
|
|================================================================================================= | 89%
|
|================================================================================================== | 89%
|
|================================================================================================== | 90%
|
|=================================================================================================== | 90%
|
|==================================================================================================== | 90%
|
|==================================================================================================== | 91%
|
|===================================================================================================== | 91%
|
|===================================================================================================== | 92%
|
|====================================================================================================== | 92%
|
|====================================================================================================== | 93%
|
|======================================================================================================= | 93%
|
|======================================================================================================= | 94%
|
|======================================================================================================== | 94%
|
|======================================================================================================== | 95%
|
|========================================================================================================= | 95%
|
|========================================================================================================= | 96%
|
|========================================================================================================== | 96%
|
|========================================================================================================== | 97%
|
|=========================================================================================================== | 97%
|
|=========================================================================================================== | 98%
|
|============================================================================================================ | 98%
|
|============================================================================================================ | 99%
|
|============================================================================================================= | 99%
|
|============================================================================================================= | 100%
|
|==============================================================================================================| 100%
Centering and scaling data matrix
|
| | 0%
|
|======================================================= | 50%
|
|==============================================================================================================| 100%
alldata.int = RunPCA(alldata.int, reduction.name = "pca_harmony")
PC_ 1
Positive: NPM1, HSPD1, FABP5, HSP90AB1, TUBA1B, TYMS, CD70, CCND2, H2AFZ, TUBB
PTTG1, UBE2S, JPT1, PCLAF, NME1, PRDX1, IL2RA, C12orf75, TXN, LDHA
HMGB2, BATF3, PSAT1, RRM2, HNRNPAB, HSPE1, SRM, HLA-DRB5, HLA-DPA1, ATP5MC3
Negative: TYROBP, LYZ, S100A9, SPI1, S100A8, AIF1, FCER1G, VCAN, RNF130, CYBB
FCN1, HCK, FOS, CST3, LRMDA, CD14, TNFAIP2, SERPINA1, RAB31, PLXDC2
CD36, DPYD, CEBPD, SYK, CSTA, ARHGAP26, MPEG1, LRP1, CLEC7A, GAS7
PC_ 2
Positive: LTB, GZMM, CD7, CST7, LEF1, KIR3DL1, GAS5, TRGV2, TCF7, LSR
CD52, GYPC, TRBV23-1, CD27, SPOCK2, IFITM1, CXCR3, IL32, MATK, FCMR
KRT1, IL12RB2, EEF2, XCL1, SYNE2, SLFN5, KLRC1, FAM9C, CD69, NKG7
Negative: HLA-DRA, HLA-DRB5, HLA-DPA1, LGALS1, HLA-DRB1, CD74, HLA-DPB1, LGALS3, FTL, IFI30
RAB11FIP1, TYMP, ANXA5, YBX3, AHNAK, ZEB2, S100A6, CD70, HLA-DMA, HLA-DQB1
S100A11, ANXA1, PLXDC2, CTSH, LYZ, S100A9, BLVRB, CST3, IL2RA, TIMP1
PC_ 3
Positive: TNFRSF4, HLA-DQA2, SYT4, BACE2, PHLDA2, GRIA4, EEF1A2, CCL17, CA2, ADGRB3
PTP4A3, C12orf75, KRT7, IGHE, PRG4, TRAV4, LY6E, AC112770.1, PON2, FGGY
THY1, MSC, MCTP2, SMIM3, STMN2, IGKC, AL138720.1, NME4, CTSH, IGFBP4
Negative: RBPMS, TRAV17, TENM3, PPBP, TRAV9-2, PPP2R2B, NCR3, HLA-DQA1, LMNA, IQCG
PLD1, RPL22L1, STMN1, SRGN, CTAG2, ANXA2, SLC7A11-AS1, TK1, SPOCK1, MT2A
HLA-DRB1, VAMP5, STAT1, TNFSF10, AC010967.1, KIF2A, CCNA2, MACROD2, CREB3L3, RYR2
PC_ 4
Positive: CCR7, BTG1, MS4A1, CD79A, AFF3, SELL, BANK1, FCMR, IGHM, LINC00926
RALGPS2, BACH2, PNRC1, TCL1A, CD19, NIBAN3, PAX5, SPIB, FCRLA, S1PR1
IL7R, IGHD, VPREB3, ISG20, LINC02397, LBH, CD40, BLK, FAM107B, POU2AF1
Negative: KIR3DL1, XCL1, KIR2DL3, KLRC1, S100A4, KIR2DL4, TRGV2, PFN1, XCL2, MATK
KRT86, KRT81, CST7, MT1G, TOP2A, ACTB, CLIC1, ESYT2, MYO1E, NME1
PHF19, GAPDH, ENO1, ATP5MC3, CXCR3, TXN, PYCARD, CKS2, COTL1, CTSC
PC_ 5
Positive: DUSP4, S100A4, CD2, F2R, TMSB4X, TP73, AL136456.1, TMEM163, RAB37, TSC22D3
LAPTM5, TNFRSF18, LIME1, EEF1A2, LINC02694, LSP1, HIST1H1C, TRAV4, MALAT1, EMP3
MKI67, WNT5B, ENTPD1, TOP2A, UBE2C, GAS2L1, QPRT, CENPF, LINC01934, UBC
Negative: RPL23, C1QBP, FCER2, LTA, DNAJC12, MIR155HG, PPBP, SRM, RPL22L1, KRT1
SLC7A11-AS1, NME1, NFIB, EIF4A1, PPID, PPP1R14B, ODC1, AC069410.1, AC068672.2, IL4
RXFP1, HSPE1, DANCR, UNC13C, SLC35F3, CSMD1, TXNDC17, FAM9C, GINS2, COL19A1
Avis : Key 'PC_' taken, using 'pcaharmony_' instead
alldata.int <- RunHarmony(
alldata.int,
group.by.vars = "orig.ident",
reduction.use = "pca_harmony",
dims.use = 1:20,
assay.use = "RNA")
Transposing data matrix
Initializing state using k-means centroids initialization
Harmony 1/10
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 2/10
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 3/10
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony 4/10
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Harmony converged after 4 iterations
alldata.int <- RunUMAP(alldata.int, dims = 1:20, reduction = "harmony", reduction.name = "umap_harmony")
14:10:50 UMAP embedding parameters a = 0.9922 b = 1.112
14:10:50 Read 59355 rows and found 20 numeric columns
14:10:50 Using Annoy for neighbor search, n_neighbors = 30
14:10:50 Building Annoy index with metric = cosine, n_trees = 50
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
14:10:58 Writing NN index file to temp file /tmp/RtmpJEsrc8/file375c62dab042
14:10:58 Searching Annoy index using 1 thread, search_k = 3000
14:11:27 Annoy recall = 100%
14:11:29 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 30
14:11:33 Initializing from normalized Laplacian + noise (using RSpectra)
14:11:36 Commencing optimization for 200 epochs, with 2572314 positive edges
Using method 'umap'
0% 10 20 30 40 50 60 70 80 90 100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
14:12:15 Optimization finished
alldata.int <- RunTSNE(alldata.int, dims = 1:20, reduction = "harmony", reduction.name = "tsne_harmony")
Avis : Key 'tSNE_' taken, using 'tsneharmony_' instead
alldata.int <- FindNeighbors(alldata.int, reduction = "pca_harmony", dims = 1:20, verbose = FALSE)
alldata.int <- FindClusters(alldata.int, resolution = 1.2, verbose = FALSE)
wrap_plots(
DimPlot(alldata.int, reduction = "pca_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("PCA integrated"),
DimPlot(alldata.int, reduction = "tsne_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("tSNE integrated"),
DimPlot(alldata.int, reduction = "umap_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("UMAP integrated"),
DimPlot(alldata.int, reduction = "pca_harmony", group.by = "RNA_snn_res.1.2")+NoAxes()+ggtitle("PCA integrated"),
DimPlot(alldata.int, reduction = "tsne_harmony", group.by = "RNA_snn_res.1.2")+NoAxes()+ggtitle("tSNE integrated"),
DimPlot(alldata.int, reduction = "umap_harmony", group.by = "RNA_snn_res.1.2")+NoAxes()+ggtitle("UMAP integrated"),
ncol = 3) + plot_layout(guides = "collect")

DimPlot(alldata.int, reduction = "pca_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("PCA integrated")

DimPlot(alldata.int, reduction = "tsne_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("tSNE integrated")

DimPlot(alldata.int, reduction = "umap_harmony", group.by = "orig.ident")+NoAxes()+ggtitle("UMAP integrated")

DimPlot(alldata.int, reduction = "umap_harmony", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("UMAP integrated")

DimPlot(alldata.int, reduction = "pca_harmony", group.by = "RNA_snn_res.1.2")+NoAxes()+ggtitle("PCA integrated")

DimPlot(alldata.int, reduction = "tsne_harmony", group.by = "RNA_snn_res.1.2")+NoAxes()+ggtitle("tSNE integrated")

DimPlot(alldata.int, reduction = "umap_harmony", group.by = "RNA_snn_res.1.2")+NoAxes()+ggtitle("UMAP integrated")

DimPlot(alldata.int, reduction = "umap_harmony", group.by = "predicted.celltype.l2")+NoAxes()+ggtitle("UMAP integrated")

NA
7. Marker Gene Visualization
# Set marker genes specific to requested immune cell types
myfeatures <- c("CD19", "CD79A", "MS4A1", # B cells
"CD14", "LYZ", "FCGR3A", # Monocytes
"CSF1R", "CD68", # Macrophages
"NKG7", "GNLY", "KIR3DL1", # NK cells
"MKI67", # Proliferating NK cells
"CD34", "KIT", # HSPCs
"CD3E", "CCR7", # T cells
"SELL", "CD45RO", # Tnaive, Tcm
"CD44", "CD45RA") # Tem, Temra
# # Visualize marker genes for RPCA
# FeaturePlot(alldata.int, features = myfeatures, reduction = "pca_rpca", ncol = 4) +
# ggtitle("Marker Gene Expression - RPCA Integration") +
# NoLegend()
# Visualize marker genes for CCA
FeaturePlot(alldata.int, features = myfeatures, reduction = "pca_CCA", ncol = 4) +
ggtitle("Marker Gene Expression - CCA Integration") +
NoLegend()
Avis : Could not find CD45RO in the default search locations, found in 'ADT' assay insteadAvis : Could not find CD45RA in the default search locations, found in 'ADT' assay instead

# Visualize marker genes for Harmony
FeaturePlot(alldata.int, features = myfeatures, reduction = "umap_harmony", ncol = 4) +
ggtitle("Marker Gene Expression - Harmony Integration") +
NoLegend()
Avis : Could not find CD45RO in the default search locations, found in 'ADT' assay insteadAvis : Could not find CD45RA in the default search locations, found in 'ADT' assay instead

8. Save the Seurat object as an Robj file
# save(All_samples_Merged_Harmony_Integrated, file = "All_samples_Merged_Harmony_Integrated.Robj")
LS0tCnRpdGxlOiAiUlBDQS1DQ0EtSGFybW9ueSBJbnRlZ3JhdGlvbiBvZiBQQk1DMTB4IHdpdGggTm9ybWFsaXplRGF0YS1WU1Qgb24gc2FtcGxlcyBwYXJ0MyIKYXV0aG9yOiBOYXNpciBNYWhtb29kIEFiYmFzaQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICAjcm1kZm9ybWF0czo6cmVhZHRoZWRvd24KICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRvY19jb2xsYXBzZWQ6IHRydWUKLS0tCgojIDEuIGxvYWQgbGlicmFyaWVzCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShTZXVyYXRPYmplY3QpCmxpYnJhcnkoU2V1cmF0RGF0YSkKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoaGFybW9ueSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJldGljdWxhdGUpCmxpYnJhcnkoQXppbXV0aCkKbGlicmFyeShkcGx5cikKbGlicmFyeShSdHNuZSkKbGlicmFyeShoYXJtb255KQoKYGBgCgoKCgojIDIuIExvYWQgU2V1cmF0IE9iamVjdCAKYGBge3IgbG9hZF9zZXVyYXR9CgojTG9hZCBTZXVyYXQgT2JqZWN0IG1lcmdlZCBmcm9tIGNlbGwgbGluZXMgYW5kIGEgY29udHJvbChQQk1DKSBhZnRlciBmaWx0cmF0aW9uCmxvYWQoIi4uLy4uLy4uLzAtSU1QLU9CSkVDVFMvQWxsX1NhbXBsZXNfTWVyZ2VkX3dpdGhfMTB4X0F6aXRtdXRoX0Fubm90YXRlZC5yb2JqIikKCkFsbF9zYW1wbGVzX01lcmdlZAoKYGBgCiMgMy4gRGF0YSBQUkVQQVJBVElPTgpgYGB7ciBkYXRhLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KCiMgRGF0YSBQcmVwYXJhdGlvbiBmb3IgU2V1cmF0IHY1CmFsbGRhdGEgPC0gQWxsX3NhbXBsZXNfTWVyZ2VkCgojIFNwbGl0IHRoZSBvYmplY3QgYnkgJ29yaWcuaWRlbnQnIGZvciBpbmRpdmlkdWFsIGRhdGFzZXQgcHJvY2Vzc2luZwphbGxkYXRhLmxpc3QgPC0gU3BsaXRPYmplY3QoYWxsZGF0YSwgc3BsaXQuYnkgPSAib3JpZy5pZGVudCIpCgojIE5vcm1hbGl6ZSBhbmQgaWRlbnRpZnkgdmFyaWFibGUgZmVhdHVyZXMgZm9yIGVhY2ggZGF0YXNldCBpbiB0aGUgbGlzdApmb3IgKGkgaW4gMTpsZW5ndGgoYWxsZGF0YS5saXN0KSkgewogICAgYWxsZGF0YS5saXN0W1tpXV0gPC0gTm9ybWFsaXplRGF0YShhbGxkYXRhLmxpc3RbW2ldXSwgdmVyYm9zZSA9IEZBTFNFKQogICAgYWxsZGF0YS5saXN0W1tpXV0gPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoYWxsZGF0YS5saXN0W1tpXV0sIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjAwMCwgdmVyYm9zZSA9IEZBTFNFKQp9CgojIEdldCB0aGUgdmFyaWFibGUgZ2VuZXMgZm9yIGVhY2ggZGF0YXNldApodmdzX3Blcl9kYXRhc2V0IDwtIGxhcHBseShhbGxkYXRhLmxpc3QsIFZhcmlhYmxlRmVhdHVyZXMpCgojIEluY2x1ZGUgdGhlIHZhcmlhYmxlIGdlbmVzIHNlbGVjdGVkIG9uIHRoZSB3aG9sZSBkYXRhc2V0Cmh2Z3NfcGVyX2RhdGFzZXQkYWxsIDwtIFZhcmlhYmxlRmVhdHVyZXMoYWxsZGF0YSkKCiMgQ3JlYXRlIGEgaGVhdG1hcCB0byBzaG93IG92ZXJsYXAgYWNyb3NzIGRhdGFzZXRzCnRlbXAgPC0gdW5pcXVlKHVubGlzdChodmdzX3Blcl9kYXRhc2V0KSkKb3ZlcmxhcCA8LSBzYXBwbHkoaHZnc19wZXJfZGF0YXNldCwgZnVuY3Rpb24oeCkgdGVtcCAlaW4lIHgpCnBoZWF0bWFwOjpwaGVhdG1hcCh0KG92ZXJsYXAgKiAxKSwgY2x1c3Rlcl9yb3dzID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICBjb2xvciA9IGMoImdyZXk5MCIsICJncmV5MjAiKSkKCiMgU2VsZWN0IGludGVncmF0aW9uIGZlYXR1cmVzIGFjcm9zcyBkYXRhc2V0cwpodmdzX2FsbCA8LSBTZWxlY3RJbnRlZ3JhdGlvbkZlYXR1cmVzKGFsbGRhdGEubGlzdCkKaHZnc19wZXJfZGF0YXNldCRhbGxfcmFua3MgPC0gaHZnc19hbGwKCiMgR2VuZXJhdGUgdGhlIG92ZXJsYXAgaGVhdG1hcCBmb3IgYWxsIHNlbGVjdGVkIGludGVncmF0aW9uIGZlYXR1cmVzCnRlbXAgPC0gdW5pcXVlKHVubGlzdChodmdzX3Blcl9kYXRhc2V0KSkKb3ZlcmxhcCA8LSBzYXBwbHkoaHZnc19wZXJfZGF0YXNldCwgZnVuY3Rpb24oeCkgdGVtcCAlaW4lIHgpCnBoZWF0bWFwOjpwaGVhdG1hcCh0KG92ZXJsYXAgKiAxKSwgY2x1c3Rlcl9yb3dzID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICBjb2xvciA9IGMoImdyZXk5MCIsICJncmV5MjAiKSkKCiMgU2NhbGUgYW5kIFBDQSBvbiBlYWNoIGRhdGFzZXQgdXNpbmcgc2VsZWN0ZWQgaW50ZWdyYXRpb24gZmVhdHVyZXMKYWxsZGF0YS5saXN0IDwtIGxhcHBseShhbGxkYXRhLmxpc3QsIGZ1bmN0aW9uKHgpIHsKICAgIHggPC0gU2NhbGVEYXRhKHgsIGZlYXR1cmVzID0gaHZnc19hbGwsIHZlcmJvc2UgPSBGQUxTRSkKICAgIHggPC0gUnVuUENBKHgsIGZlYXR1cmVzID0gaHZnc19hbGwsIHZlcmJvc2UgPSBGQUxTRSkKfSkKCmBgYAoKCiMgNC4gcnBjYS1pbnRlZ3JhdGlvbgpgYGB7ciBpbnRlZ3JhdGlvbi1ycGNhLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KCmFsbGRhdGEuYW5jaG9ycyA8LSBGaW5kSW50ZWdyYXRpb25BbmNob3JzKG9iamVjdC5saXN0ID0gYWxsZGF0YS5saXN0LCBkaW1zID0gMToyMCwgcmVkdWN0aW9uID0gInJwY2EiLCBhbmNob3IuZmVhdHVyZXMgPSBodmdzX2FsbCkKCmFsbGRhdGEuaW50IDwtIEludGVncmF0ZURhdGEoYW5jaG9yc2V0ID0gYWxsZGF0YS5hbmNob3JzLCBkaW1zID0gMToyMCwgbmV3LmFzc2F5Lm5hbWUgPSAicnBjYSIpCgpuYW1lcyhhbGxkYXRhLmludEBhc3NheXMpCgphbGxkYXRhLmludEBhY3RpdmUuYXNzYXkKCkRlZmF1bHRBc3NheShhbGxkYXRhLmludCkgPC0gInJwY2EiCgojUnVuIERpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbiBvbiBpbnRlZ3JhdGVkIHNwYWNlCmFsbGRhdGEuaW50IDwtIFNjYWxlRGF0YShhbGxkYXRhLmludCwgdmVyYm9zZSA9IEZBTFNFKQphbGxkYXRhLmludCA8LSBSdW5QQ0EoYWxsZGF0YS5pbnQsIGZlYXR1cmVzID0gaHZnc19hbGwsIHJlZHVjdGlvbi5uYW1lID0gInBjYV9ycGNhIiwgZG8ucHJpbnQgPSBUUlVFLCBwY3MucHJpbnQgPSAxOjUsIGdlbmVzLnByaW50ID0gMTUsIHZlcmJvc2UgPSBGQUxTRSkKYWxsZGF0YS5pbnQgPC0gUnVuVU1BUChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInBjYV9ycGNhIiwgcmVkdWN0aW9uLm5hbWUgPSAidW1hcF9ycGNhIiwgZGltcyA9IDE6MjAsIHZlcmJvc2UgPSBGQUxTRSkKYWxsZGF0YS5pbnQgPC0gUnVuVFNORShhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInBjYV9ycGNhIiwgcmVkdWN0aW9uLm5hbWUgPSAidHNuZV9ycGNhIiwgZGltcyA9IDE6MjAsIHZlcmJvc2UgPSBGQUxTRSkKYWxsZGF0YS5pbnQgPC0gRmluZE5laWdoYm9ycyhhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInBjYV9ycGNhIiwgZGltcyA9IDE6MjAsIHZlcmJvc2UgPSBGQUxTRSkKYWxsZGF0YS5pbnQgPC0gRmluZENsdXN0ZXJzKGFsbGRhdGEuaW50LCByZXNvbHV0aW9uID0gMS4yLCB2ZXJib3NlID0gRkFMU0UpCgoKCndyYXBfcGxvdHMoCgogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInBjYV9ycGNhIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpK05vQXhlcygpK2dndGl0bGUoIlBDQSBpbnRlZ3JhdGVkIiksCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidHNuZV9ycGNhIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpLAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfcnBjYSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKSwKCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX3JwY2EiLCBncm91cC5ieSA9ICJycGNhX3Nubl9yZXMuMS4yIikrTm9BeGVzKCkrZ2d0aXRsZSgiUENBIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX3JwY2EiLCBncm91cC5ieSA9ICJycGNhX3Nubl9yZXMuMS4yIikrTm9BeGVzKCkrZ2d0aXRsZSgidFNORSBpbnRlZ3JhdGVkIiksCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9ycGNhIiwgZ3JvdXAuYnkgPSAicnBjYV9zbm5fcmVzLjEuMiIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpLAogICAgbmNvbCA9IDMpICsgcGxvdF9sYXlvdXQoZ3VpZGVzID0gImNvbGxlY3QiKQoKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJwY2FfcnBjYSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJQQ0EgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidHNuZV9ycGNhIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9ycGNhIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9ycGNhIiwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIikrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIikKCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX3JwY2EiLCBncm91cC5ieSA9ICJycGNhX3Nubl9yZXMuMS4yIikrTm9BeGVzKCkrZ2d0aXRsZSgiUENBIGludGVncmF0ZWQiKQogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInRzbmVfcnBjYSIsIGdyb3VwLmJ5ID0gInJwY2Ffc25uX3Jlcy4xLjIiKStOb0F4ZXMoKStnZ3RpdGxlKCJ0U05FIGludGVncmF0ZWQiKQogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfcnBjYSIsIGdyb3VwLmJ5ID0gInJwY2Ffc25uX3Jlcy4xLjIiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKQogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfcnBjYSIsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpCgpgYGAKCiMgY2xlYW4gbWVtb3J5CmBgYHtyIGNsZWFuTWVtb3J5MX0KIyByZW1vdmUgYWxsIG9iamVjdHMgdGhhdCB3aWxsIG5vdCBiZSB1c2VkCnJtKGFsbGRhdGEsIGFsbGRhdGEuaW50LCBhbGxkYXRhLmFuY2hvcnMpCgpnYygpCmBgYAoKIyA1LiBDQ0EtaW50ZWdyYXRpb24KYGBge3IgaW50ZWdyYXRpb24tQ0NBLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KCmFsbGRhdGEuYW5jaG9ycyA8LSBGaW5kSW50ZWdyYXRpb25BbmNob3JzKG9iamVjdC5saXN0ID0gYWxsZGF0YS5saXN0LCBkaW1zID0gMToyMCwgcmVkdWN0aW9uID0gImNjYSIsIGFuY2hvci5mZWF0dXJlcyA9IGh2Z3NfYWxsKQoKYWxsZGF0YS5pbnQgPC0gSW50ZWdyYXRlRGF0YShhbmNob3JzZXQgPSBhbGxkYXRhLmFuY2hvcnMsIGRpbXMgPSAxOjIwLCBuZXcuYXNzYXkubmFtZSA9ICJDQ0EiKQoKbmFtZXMoYWxsZGF0YS5pbnRAYXNzYXlzKQoKYWxsZGF0YS5pbnRAYWN0aXZlLmFzc2F5CgpEZWZhdWx0QXNzYXkoYWxsZGF0YS5pbnQpIDwtICJDQ0EiCgojUnVuIERpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbiBvbiBpbnRlZ3JhdGVkIHNwYWNlCmFsbGRhdGEuaW50IDwtIFNjYWxlRGF0YShhbGxkYXRhLmludCwgdmVyYm9zZSA9IFRSVUUpCmFsbGRhdGEuaW50IDwtIFJ1blBDQShhbGxkYXRhLmludCwgZmVhdHVyZXMgPSBodmdzX2FsbCwgcmVkdWN0aW9uLm5hbWUgPSAicGNhX0NDQSIsIGRvLnByaW50ID0gVFJVRSwgcGNzLnByaW50ID0gMTo1LCBnZW5lcy5wcmludCA9IDE1LCB2ZXJib3NlID0gRkFMU0UpCmFsbGRhdGEuaW50IDwtIFJ1blVNQVAoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJwY2FfQ0NBIiwgcmVkdWN0aW9uLm5hbWUgPSAidW1hcF9DQ0EiLCBkaW1zID0gMToyMCwgdmVyYm9zZSA9IEZBTFNFKQphbGxkYXRhLmludCA8LSBSdW5UU05FKGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX0NDQSIscmVkdWN0aW9uLm5hbWUgPSAidHNuZV9DQ0EiLGRpbXMgPSAxOjIwLCB2ZXJib3NlID0gRkFMU0UpCmFsbGRhdGEuaW50IDwtIEZpbmROZWlnaGJvcnMoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJwY2FfQ0NBIiwgZGltcyA9IDE6MjAsIHZlcmJvc2UgPSBGQUxTRSkKYWxsZGF0YS5pbnQgPC0gRmluZENsdXN0ZXJzKGFsbGRhdGEuaW50LCByZXNvbHV0aW9uID0gMS4yLCB2ZXJib3NlID0gRkFMU0UpCgoKCndyYXBfcGxvdHMoCgogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInBjYV9DQ0EiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikrTm9BeGVzKCkrZ2d0aXRsZSgiUENBIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX0NDQSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJ0U05FIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX0NDQSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKSwKCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX0NDQSIsIGdyb3VwLmJ5ID0gIkNDQV9zbm5fcmVzLjEuMiIpK05vQXhlcygpK2dndGl0bGUoIlBDQSBpbnRlZ3JhdGVkIiksCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidHNuZV9DQ0EiLCBncm91cC5ieSA9ICJDQ0Ffc25uX3Jlcy4xLjIiKStOb0F4ZXMoKStnZ3RpdGxlKCJ0U05FIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX0NDQSIsIGdyb3VwLmJ5ID0gIkNDQV9zbm5fcmVzLjEuMiIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpLAogICAgbmNvbCA9IDMpICsgcGxvdF9sYXlvdXQoZ3VpZGVzID0gImNvbGxlY3QiKQoKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJwY2FfQ0NBIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpK05vQXhlcygpK2dndGl0bGUoIlBDQSBpbnRlZ3JhdGVkIikKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX0NDQSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJ0U05FIGludGVncmF0ZWQiKQogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfQ0NBIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9DQ0EiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKQogICAgCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX0NDQSIsIGdyb3VwLmJ5ID0gIkNDQV9zbm5fcmVzLjEuMiIpK05vQXhlcygpK2dndGl0bGUoIlBDQSBpbnRlZ3JhdGVkIikKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX0NDQSIsIGdyb3VwLmJ5ID0gIkNDQV9zbm5fcmVzLjEuMiIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9DQ0EiLCBncm91cC5ieSA9ICJDQ0Ffc25uX3Jlcy4xLjIiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKQogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInVtYXBfQ0NBIiwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIikrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIikKYGBgCgoKIyBjbGVhbiBtZW1vcnkKYGBge3IgY2xlYW5NZW1vcnkyfQojIHJlbW92ZSBhbGwgb2JqZWN0cyB0aGF0IHdpbGwgbm90IGJlIHVzZWQKcm0oYWxsZGF0YS5hbmNob3JzKQoKZ2MoKQoKCgpgYGAKCgojIDYuIEhhcm1vbnktaW50ZWdyYXRpb24KYGBge3IgaW50ZWdyYXRpb24taGFybW9ueSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CgphbGxkYXRhLmludEBhY3RpdmUuYXNzYXkgPSAiUk5BIgpWYXJpYWJsZUZlYXR1cmVzKGFsbGRhdGEuaW50KSA9IGh2Z3NfYWxsCmFsbGRhdGEuaW50ID0gU2NhbGVEYXRhKGFsbGRhdGEuaW50LCB2YXJzLnRvLnJlZ3Jlc3MgPSBjKCJwZXJjZW50Lm10IiwgIm5GZWF0dXJlX1JOQSIpKQphbGxkYXRhLmludCA9IFJ1blBDQShhbGxkYXRhLmludCwgcmVkdWN0aW9uLm5hbWUgPSAicGNhX2hhcm1vbnkiKQoKCgphbGxkYXRhLmludCA8LSBSdW5IYXJtb255KAogIGFsbGRhdGEuaW50LAogIGdyb3VwLmJ5LnZhcnMgPSAib3JpZy5pZGVudCIsCiAgcmVkdWN0aW9uLnVzZSA9ICJwY2FfaGFybW9ueSIsCiAgZGltcy51c2UgPSAxOjIwLAogIGFzc2F5LnVzZSA9ICJSTkEiKQoKCmFsbGRhdGEuaW50IDwtIFJ1blVNQVAoYWxsZGF0YS5pbnQsIGRpbXMgPSAxOjIwLCByZWR1Y3Rpb24gPSAiaGFybW9ueSIsIHJlZHVjdGlvbi5uYW1lID0gInVtYXBfaGFybW9ueSIpCmFsbGRhdGEuaW50IDwtIFJ1blRTTkUoYWxsZGF0YS5pbnQsIGRpbXMgPSAxOjIwLCByZWR1Y3Rpb24gPSAiaGFybW9ueSIsIHJlZHVjdGlvbi5uYW1lID0gInRzbmVfaGFybW9ueSIpCmFsbGRhdGEuaW50IDwtIEZpbmROZWlnaGJvcnMoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJwY2FfaGFybW9ueSIsIGRpbXMgPSAxOjIwLCB2ZXJib3NlID0gRkFMU0UpCmFsbGRhdGEuaW50IDwtIEZpbmRDbHVzdGVycyhhbGxkYXRhLmludCwgcmVzb2x1dGlvbiA9IDEuMiwgdmVyYm9zZSA9IEZBTFNFKQoKCiAKIAogd3JhcF9wbG90cygKCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAicGNhX2hhcm1vbnkiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikrTm9BeGVzKCkrZ2d0aXRsZSgiUENBIGludGVncmF0ZWQiKSwKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ0c25lX2hhcm1vbnkiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikrTm9BeGVzKCkrZ2d0aXRsZSgidFNORSBpbnRlZ3JhdGVkIiksCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9oYXJtb255IiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpLAoKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJwY2FfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIlJOQV9zbm5fcmVzLjEuMiIpK05vQXhlcygpK2dndGl0bGUoIlBDQSBpbnRlZ3JhdGVkIiksCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidHNuZV9oYXJtb255IiwgZ3JvdXAuYnkgPSAiUk5BX3Nubl9yZXMuMS4yIikrTm9BeGVzKCkrZ2d0aXRsZSgidFNORSBpbnRlZ3JhdGVkIiksCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9oYXJtb255IiwgZ3JvdXAuYnkgPSAiUk5BX3Nubl9yZXMuMS4yIikrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIiksCiAgICBuY29sID0gMykgKyBwbG90X2xheW91dChndWlkZXMgPSAiY29sbGVjdCIpCiAKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJwY2FfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKStOb0F4ZXMoKStnZ3RpdGxlKCJQQ0EgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidHNuZV9oYXJtb255IiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9oYXJtb255IiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpK05vQXhlcygpK2dndGl0bGUoIlVNQVAgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9oYXJtb255IiwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIikrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIikKICAgIAogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInBjYV9oYXJtb255IiwgZ3JvdXAuYnkgPSAiUk5BX3Nubl9yZXMuMS4yIikrTm9BeGVzKCkrZ2d0aXRsZSgiUENBIGludGVncmF0ZWQiKQogICAgRGltUGxvdChhbGxkYXRhLmludCwgcmVkdWN0aW9uID0gInRzbmVfaGFybW9ueSIsIGdyb3VwLmJ5ID0gIlJOQV9zbm5fcmVzLjEuMiIpK05vQXhlcygpK2dndGl0bGUoInRTTkUgaW50ZWdyYXRlZCIpCiAgICBEaW1QbG90KGFsbGRhdGEuaW50LCByZWR1Y3Rpb24gPSAidW1hcF9oYXJtb255IiwgZ3JvdXAuYnkgPSAiUk5BX3Nubl9yZXMuMS4yIikrTm9BeGVzKCkrZ2d0aXRsZSgiVU1BUCBpbnRlZ3JhdGVkIikKICAgIERpbVBsb3QoYWxsZGF0YS5pbnQsIHJlZHVjdGlvbiA9ICJ1bWFwX2hhcm1vbnkiLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiKStOb0F4ZXMoKStnZ3RpdGxlKCJVTUFQIGludGVncmF0ZWQiKQogICAgCmBgYAoKCgoKCgoKCiMgNy4gTWFya2VyIEdlbmUgVmlzdWFsaXphdGlvbgpgYGB7ciBmZWF0dXJlcGxvdC1oYXJtb255LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0KCgojIFNldCBtYXJrZXIgZ2VuZXMgc3BlY2lmaWMgdG8gcmVxdWVzdGVkIGltbXVuZSBjZWxsIHR5cGVzCm15ZmVhdHVyZXMgPC0gYygiQ0QxOSIsICJDRDc5QSIsICJNUzRBMSIsICMgQiBjZWxscwogICAgICAgICAgICAgICAgIkNEMTQiLCAiTFlaIiwgIkZDR1IzQSIsICMgTW9ub2N5dGVzCiAgICAgICAgICAgICAgICAiQ1NGMVIiLCAiQ0Q2OCIsICMgTWFjcm9waGFnZXMKICAgICAgICAgICAgICAgICJOS0c3IiwgIkdOTFkiLCAiS0lSM0RMMSIsICMgTksgY2VsbHMKICAgICAgICAgICAgICAgICJNS0k2NyIsICMgUHJvbGlmZXJhdGluZyBOSyBjZWxscwogICAgICAgICAgICAgICAgIkNEMzQiLCAiS0lUIiwgIyBIU1BDcwogICAgICAgICAgICAgICAgIkNEM0UiLCAiQ0NSNyIsICMgVCBjZWxscwogICAgICAgICAgICAgICAgIlNFTEwiLCAiQ0Q0NVJPIiwgIyBUbmFpdmUsIFRjbQogICAgICAgICAgICAgICAgIkNENDQiLCAiQ0Q0NVJBIikgIyBUZW0sIFRlbXJhCgojICMgVmlzdWFsaXplIG1hcmtlciBnZW5lcyBmb3IgUlBDQQojIEZlYXR1cmVQbG90KGFsbGRhdGEuaW50LCBmZWF0dXJlcyA9IG15ZmVhdHVyZXMsIHJlZHVjdGlvbiA9ICJwY2FfcnBjYSIsIG5jb2wgPSA0KSArIAojICAgZ2d0aXRsZSgiTWFya2VyIEdlbmUgRXhwcmVzc2lvbiAtIFJQQ0EgSW50ZWdyYXRpb24iKSArCiMgICBOb0xlZ2VuZCgpCgojIFZpc3VhbGl6ZSBtYXJrZXIgZ2VuZXMgZm9yIENDQQpGZWF0dXJlUGxvdChhbGxkYXRhLmludCwgZmVhdHVyZXMgPSBteWZlYXR1cmVzLCByZWR1Y3Rpb24gPSAidW1hcF9DQ0EiLCBuY29sID0gNCkgKyAKICBnZ3RpdGxlKCJNYXJrZXIgR2VuZSBFeHByZXNzaW9uIC0gQ0NBIEludGVncmF0aW9uIikgKwogIE5vTGVnZW5kKCkKCiMgVmlzdWFsaXplIG1hcmtlciBnZW5lcyBmb3IgSGFybW9ueQpGZWF0dXJlUGxvdChhbGxkYXRhLmludCwgZmVhdHVyZXMgPSBteWZlYXR1cmVzLCByZWR1Y3Rpb24gPSAidW1hcF9oYXJtb255IiwgbmNvbCA9IDQpICsgCiAgZ2d0aXRsZSgiTWFya2VyIEdlbmUgRXhwcmVzc2lvbiAtIEhhcm1vbnkgSW50ZWdyYXRpb24iKSArCiAgTm9MZWdlbmQoKQoKYGBgCgoKIyA4LiBTYXZlIHRoZSBTZXVyYXQgb2JqZWN0IGFzIGFuIFJvYmogZmlsZQpgYGB7ciBzYXZlUk9CSn0KCiMgc2F2ZShBbGxfc2FtcGxlc19NZXJnZWRfSGFybW9ueV9JbnRlZ3JhdGVkLCBmaWxlID0gIkFsbF9zYW1wbGVzX01lcmdlZF9IYXJtb255X0ludGVncmF0ZWQuUm9iaiIpCgoKYGBgCgoKCgo=