Load libraries

library(Seurat)
library(scrattch.hicat)
library(monocle)
library(Matrix)
library(dplyr)
library(RColorBrewer)
library(ggplot2)
library(ggExtra)
library(cowplot)
library(wesanderson)
library(MoMAColors)
library(princurve)

#Set ggplot theme as classic
theme_set(theme_classic())

Load dataset

Pidd1.data <- readRDS("Pidd1KO.cells.RDS")

DimPlot(object = Pidd1.data,
        group.by = "Cell.ident",
        reduction = "spring",
        cols = c("grey40","#4cabdc","#046c9a", "#7293c8", "#31b6bd", "#ebcb2e", "#9ec22f", "#a9961b", "#cc3a1b", wes_palette("FantasticFox1")),
        pt.size = 0.5)  & NoAxes()

Neurons.data <-  subset(Pidd1.data,
                        subset = Cell.ident %in% c("Progenitors_Hem", "Differentiating_CRs", "Neurons_Cajal-Retzius"))

DimPlot(object = Neurons.data,
        group.by = "Cell.ident",
        reduction = "spring",
        cols = c("#4cabdc", "#7293c8","#cc3a1b"),
        pt.size = 0.5)  & NoAxes()

Neurons.data <- SCTransform(Neurons.data,
                        method = "glmGamPoi",
                        vars.to.regress = c("percent.mito", "CC.Difference", "nCount_RNA"),
                        verbose = T)
## 
  |                                                                            
  |                                                                      |   0%
  |                                                                            
  |==================                                                    |  25%
  |                                                                            
  |===================================                                   |  50%
  |                                                                            
  |====================================================                  |  75%
  |                                                                            
  |======================================================================| 100%
## 
  |                                                                            
  |                                                                      |   0%
  |                                                                            
  |==                                                                    |   3%
  |                                                                            
  |====                                                                  |   6%
  |                                                                            
  |=======                                                               |   9%
  |                                                                            
  |=========                                                             |  12%
  |                                                                            
  |===========                                                           |  16%
  |                                                                            
  |=============                                                         |  19%
  |                                                                            
  |===============                                                       |  22%
  |                                                                            
  |==================                                                    |  25%
  |                                                                            
  |====================                                                  |  28%
  |                                                                            
  |======================                                                |  31%
  |                                                                            
  |========================                                              |  34%
  |                                                                            
  |==========================                                            |  38%
  |                                                                            
  |============================                                          |  41%
  |                                                                            
  |===============================                                       |  44%
  |                                                                            
  |=================================                                     |  47%
  |                                                                            
  |===================================                                   |  50%
  |                                                                            
  |=====================================                                 |  53%
  |                                                                            
  |=======================================                               |  56%
  |                                                                            
  |==========================================                            |  59%
  |                                                                            
  |============================================                          |  62%
  |                                                                            
  |==============================================                        |  66%
  |                                                                            
  |================================================                      |  69%
  |                                                                            
  |==================================================                    |  72%
  |                                                                            
  |====================================================                  |  75%
  |                                                                            
  |=======================================================               |  78%
  |                                                                            
  |=========================================================             |  81%
  |                                                                            
  |===========================================================           |  84%
  |                                                                            
  |=============================================================         |  88%
  |                                                                            
  |===============================================================       |  91%
  |                                                                            
  |==================================================================    |  94%
  |                                                                            
  |====================================================================  |  97%
  |                                                                            
  |======================================================================| 100%
## 
  |                                                                            
  |                                                                      |   0%
  |                                                                            
  |==                                                                    |   3%
  |                                                                            
  |====                                                                  |   6%
  |                                                                            
  |=======                                                               |   9%
  |                                                                            
  |=========                                                             |  12%
  |                                                                            
  |===========                                                           |  16%
  |                                                                            
  |=============                                                         |  19%
  |                                                                            
  |===============                                                       |  22%
  |                                                                            
  |==================                                                    |  25%
  |                                                                            
  |====================                                                  |  28%
  |                                                                            
  |======================                                                |  31%
  |                                                                            
  |========================                                              |  34%
  |                                                                            
  |==========================                                            |  38%
  |                                                                            
  |============================                                          |  41%
  |                                                                            
  |===============================                                       |  44%
  |                                                                            
  |=================================                                     |  47%
  |                                                                            
  |===================================                                   |  50%
  |                                                                            
  |=====================================                                 |  53%
  |                                                                            
  |=======================================                               |  56%
  |                                                                            
  |==========================================                            |  59%
  |                                                                            
  |============================================                          |  62%
  |                                                                            
  |==============================================                        |  66%
  |                                                                            
  |================================================                      |  69%
  |                                                                            
  |==================================================                    |  72%
  |                                                                            
  |====================================================                  |  75%
  |                                                                            
  |=======================================================               |  78%
  |                                                                            
  |=========================================================             |  81%
  |                                                                            
  |===========================================================           |  84%
  |                                                                            
  |=============================================================         |  88%
  |                                                                            
  |===============================================================       |  91%
  |                                                                            
  |==================================================================    |  94%
  |                                                                            
  |====================================================================  |  97%
  |                                                                            
  |======================================================================| 100%
Neurons.data  <- FindVariableFeatures(Neurons.data, selection.method = "vst", nfeatures = 1000)
Neurons.data <- RunPCA(Neurons.data, features = VariableFeatures(Neurons.data)[!VariableFeatures(Neurons.data) %in% c("eYFP", "Pidd1")] , verbose = FALSE)

Neurons.data <- RunUMAP(Neurons.data, dims = 1:5)
DimPlot(object = Neurons.data,
        group.by = "Cell.ident",
        reduction = "umap",
        cols = c("#4cabdc", "#7293c8","#cc3a1b"),
        pt.size = 0.5)  & NoAxes()

DimPlot(object = Neurons.data,
        group.by = "Genotype",
        reduction = "umap",
        cols = c("#7293c8", "#cc3a1b"),
        pt.size = 1)  & NoAxes()

FeaturePlot(object = Neurons.data,
            features = c("Gmnc", "AI593442", "Trp73", "Top2a", "Pcna", "Dll1"),
            pt.size = 0.5,
            cols = c("grey90", brewer.pal(9,"YlGnBu")),
            reduction = "umap",
            order = T) & NoAxes() & NoLegend()

fit <- principal_curve(as.matrix(Neurons.data@meta.data[,c("AP_signature1", "BP_signature1", "EN_signature1", "LN_signature1")]),
                       smoother='lowess',
                       trace=TRUE,
                       f = 1,
                       stretch=0)
## Starting curve---distance^2: 247832.2
## Iteration 1---distance^2: 191.8651
## Iteration 2---distance^2: 172.381
## Iteration 3---distance^2: 164.9822
## Iteration 4---distance^2: 161.6177
## Iteration 5---distance^2: 159.781
## Iteration 6---distance^2: 158.8637
## Iteration 7---distance^2: 158.7367
PseudotimeScore <- fit$lambda/max(fit$lambda)

if (cor(PseudotimeScore, Neurons.data@assays$RNA@data['Hmga2', ]) > 0) {
  Neurons.data$PseudotimeScore <- -(PseudotimeScore - max(PseudotimeScore))
}
FeaturePlot(object = Neurons.data,
            features = "PseudotimeScore",
            pt.size = 1.5,
            split.by = "Genotype",
            cols =  rev(brewer.pal(n =11, name = "Spectral")),
            reduction = "umap",
            order = T) & NoAxes()

Neurons.data <- NormalizeData(Neurons.data, assay = "RNA", normalization.method = "LogNormalize", scale.factor = 10000)
saveRDS(Neurons.data, "CR.Traj.Pidd1KO.RDS")

Plot gene expression along pseudotime

# Define functions

Plot.gene.trend <- function (Dataset, gene, show.pt = T, x.intercept = NULL) 
{
  data <- data.frame(Genotype = as.character(Dataset@meta.data$Genotype), Pseudotime = Dataset@meta.data$PseudotimeScore)
  data$Gene <- Dataset@assays[["RNA"]]@data[gene, ]
  p <- ggplot(data = data, aes(x = Pseudotime, y = Gene, color = Genotype)) + 
    geom_point(size=1, alpha = ifelse(show.pt == T, 0.5, 0)) +
    scale_color_manual(values = moma.colors("Althoff", 6)[c(5,2)]) +
    geom_smooth(method = "loess", n = 30, size = 2) +
    ggtitle(gene) +
    ylim(0, NA) + 
    theme(legend.position = "none",
          panel.grid.major = element_blank(),
          panel.grid.minor = element_blank(),
          panel.background = element_blank(),
          axis.ticks.x = element_blank(),
          axis.text.x = element_blank(), 
          axis.title.y = element_blank(), 
          axis.line = element_line(size = 1))
  
  if (!is.null(x.intercept)) {
    p <- p + geom_vline(xintercept = x.intercept, colour = "red", 
      linetype = 2)
  }
  return(p)
}


Plot.genes.trend <- function (Dataset, genes, show.pt=T, x.intercept = NULL) 
{
  pList <- mapply(FUN = Plot.gene.trend, gene = genes, MoreArgs = list(Dataset = Dataset, 
    show.pt = show.pt, x.intercept = x.intercept), SIMPLIFY = FALSE)
  print(x = cowplot::plot_grid(plotlist = pList, ncol = 3))
}
Plot.gene.trend(Neurons.data, "Trp73")

Plot.genes.trend(Neurons.data, c("Pidd1", "eYFP", "Hrk"))

Plot.genes.trend(Neurons.data, rownames(read.table("WT.Gene.dynamique.csv", header = T))[1:9])

Plot.genes.trend(Neurons.data, rownames(read.table("WT.Gene.dynamique.csv", header = T))[10:18])

Plot.genes.trend(Neurons.data, rownames(read.table("WT.Gene.dynamique.csv", header = T))[19:27])

Plot.genes.trend(Neurons.data, rownames(read.table("WT.Gene.dynamique.csv", header = T))[28:36])

Plot.genes.trend(Neurons.data, rownames(read.table("WT.Gene.dynamique.csv", header = T))[37:39])

Plot.genes.trend(Neurons.data, rownames(read.table("KO.Gene.dynamique.csv", header = T))[1:9])

Plot.genes.trend(Neurons.data, rownames(read.table("KO.Gene.dynamique.csv", header = T))[10:18])

Plot.genes.trend(Neurons.data, rownames(read.table("KO.Gene.dynamique.csv", header = T))[19:27])

Plot.genes.trend(Neurons.data, rownames(read.table("KO.Gene.dynamique.csv", header = T))[28:34])

Neurons.data <- SetIdent(Neurons.data, value = Neurons.data@meta.data$Cell.ident)
KO.DEG <- FindMarkers(Neurons.data, subset.ident = "Neurons_Cajal-Retzius", group.by = "Genotype", ident.1 = "Pidd1.KO")

Plot.genes.trend(Neurons.data, rownames(KO.DEG)[1:9])

Plot.genes.trend(Neurons.data, rownames(KO.DEG)[10:18])

Plot.genes.trend(Neurons.data, rownames(KO.DEG)[19:27])

Plot.genes.trend(Neurons.data, rownames(KO.DEG)[28:36])

Plot.genes.trend(Neurons.data, rownames(KO.DEG)[37:45])

Plot.genes.trend(Neurons.data, rownames(KO.DEG)[46:54])

Plot.genes.trend(Neurons.data, rownames(KO.DEG)[55:63])

Plot.genes.trend(Neurons.data, rownames(KO.DEG)[64:72])

Plot.genes.trend(Neurons.data, rownames(KO.DEG)[73:81])

Session Info

#date
format(Sys.time(), "%d %B, %Y, %H,%M")
## [1] "05 November, 2023, 01,20"
#Packages used
sessionInfo()
## R version 4.1.1 (2021-08-10)
## Platform: x86_64-conda-linux-gnu (64-bit)
## Running under: CentOS Linux 7 (Core)
## 
## Matrix products: default
## BLAS/LAPACK: /shared/ifbstor1/software/miniconda/envs/r-4.1.1/lib/libopenblasp-r0.3.18.so
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] splines   stats4    stats     graphics  grDevices utils     datasets 
## [8] methods   base     
## 
## other attached packages:
##  [1] princurve_2.1.6       MoMAColors_0.0.0.9000 wesanderson_0.3.6    
##  [4] cowplot_1.1.1         ggExtra_0.9           RColorBrewer_1.1-3   
##  [7] dplyr_1.0.10          monocle_2.22.0        DDRTree_0.1.5        
## [10] irlba_2.3.5.1         VGAM_1.1-5            ggplot2_3.3.6        
## [13] Biobase_2.54.0        BiocGenerics_0.40.0   Matrix_1.3-4         
## [16] scrattch.hicat_1.0.0  sp_1.4-7              SeuratObject_4.1.0   
## [19] Seurat_4.1.1         
## 
## loaded via a namespace (and not attached):
##   [1] plyr_1.8.7            igraph_1.3.1          lazyeval_0.2.2       
##   [4] densityClust_0.3      listenv_0.8.0         scattermore_0.8      
##   [7] fastICA_1.2-3         digest_0.6.30         htmltools_0.5.2      
##  [10] viridis_0.6.2         fansi_1.0.3           magrittr_2.0.3       
##  [13] tensor_1.5            cluster_2.1.2         ROCR_1.0-11          
##  [16] limma_3.50.0          globals_0.14.0        matrixStats_0.62.0   
##  [19] docopt_0.7.1          spatstat.sparse_2.1-1 colorspace_2.0-3     
##  [22] ggrepel_0.9.1         xfun_0.34             rgdal_1.5-23         
##  [25] crayon_1.5.2          sparsesvd_0.2         jsonlite_1.8.2       
##  [28] progressr_0.10.0      spatstat.data_2.2-0   survival_3.2-13      
##  [31] zoo_1.8-10            glue_1.6.2            polyclip_1.10-0      
##  [34] gtable_0.3.1          leiden_0.3.10         future.apply_1.9.0   
##  [37] abind_1.4-5           scales_1.2.1          pheatmap_1.0.12      
##  [40] DBI_1.1.2             spatstat.random_2.2-0 miniUI_0.1.1.1       
##  [43] Rcpp_1.0.9            viridisLite_0.4.1     xtable_1.8-4         
##  [46] reticulate_1.24       spatstat.core_2.4-2   htmlwidgets_1.5.4    
##  [49] httr_1.4.4            FNN_1.1.3.1           ellipsis_0.3.2       
##  [52] ica_1.0-2             farver_2.1.1          pkgconfig_2.0.3      
##  [55] sass_0.4.1            uwot_0.1.11           deldir_1.0-6         
##  [58] utf8_1.2.2            labeling_0.4.2        tidyselect_1.2.0     
##  [61] rlang_1.0.6           reshape2_1.4.4        later_1.3.0          
##  [64] munsell_0.5.0         tools_4.1.1           cli_3.4.1            
##  [67] generics_0.1.3        ggridges_0.5.3        evaluate_0.17        
##  [70] stringr_1.4.1         fastmap_1.1.0         yaml_2.3.6           
##  [73] goftest_1.2-3         knitr_1.40            fitdistrplus_1.1-8   
##  [76] purrr_0.3.5           RANN_2.6.1            pbapply_1.5-0        
##  [79] future_1.25.0         nlme_3.1-153          mime_0.12            
##  [82] slam_0.1-49           compiler_4.1.1        rstudioapi_0.13      
##  [85] plotly_4.10.0         png_0.1-7             spatstat.utils_2.3-0 
##  [88] tibble_3.1.8          bslib_0.3.1           stringi_1.7.8        
##  [91] highr_0.9             rgeos_0.5-9           lattice_0.20-45      
##  [94] HSMMSingleCell_1.14.0 vctrs_0.4.2           pillar_1.8.1         
##  [97] lifecycle_1.0.3       spatstat.geom_2.4-0   combinat_0.0-8       
## [100] lmtest_0.9-40         jquerylib_0.1.4       RcppAnnoy_0.0.19     
## [103] data.table_1.14.2     httpuv_1.6.5          patchwork_1.1.1      
## [106] R6_2.5.1              promises_1.2.0.1      KernSmooth_2.23-20   
## [109] gridExtra_2.3         parallelly_1.31.1     codetools_0.2-18     
## [112] MASS_7.3-54           assertthat_0.2.1      ggstream_0.1.0       
## [115] withr_2.5.0           qlcMatrix_0.9.7       sctransform_0.3.3    
## [118] mgcv_1.8-38           parallel_4.1.1        grid_4.1.1           
## [121] rpart_4.1-15          tidyr_1.2.1           rmarkdown_2.11       
## [124] Rtsne_0.16            shiny_1.7.1

  1. IPNP & Imagine Institute, Paris, France, ↩︎

LS0tCnRpdGxlOiAiUGxvdCBnZW5lIGR5bmFtaWNzIGFsb25nIFdUL1BpZGQxS08gQ1IgZGlmZmVyZW50aWF0aW9uIHRyYWplY3RvcnkiCmF1dGhvcjoKICAgLSBGcsOpZMOpcmljIENhdXNlcmV0XltJUE5QICYgSW1hZ2luZSBJbnN0aXR1dGUsIFBhcmlzLCBGcmFuY2UsIGZyZWRlcmljLmNhdXNlcmV0QGluc2VybS5mcl0gWyFbXShodHRwczovL29yY2lkLm9yZy9zaXRlcy9kZWZhdWx0L2ZpbGVzL2ltYWdlcy9vcmNpZF8xNngxNi5wbmcpXShodHRwczovL29yY2lkLm9yZy8wMDAwLTAwMDItMDU0My00OTM4KQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDogCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKICAgIGRmX3ByaW50OiB0aWJibGUKICAgIGhpZ2hsaWdodDogaGFkZG9jawogICAgdGhlbWU6IGNvc21vCiAgICBjc3M6ICIuLi9zdHlsZS5jc3MiCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA1CiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogeWVzCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZmlnLmFsaWduID0gJ2NlbnRlcicsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNhY2hlLmxhenkgPSBGQUxTRSkKYGBgCgojIExvYWQgbGlicmFyaWVzCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShzY3JhdHRjaC5oaWNhdCkKbGlicmFyeShtb25vY2xlKQpsaWJyYXJ5KE1hdHJpeCkKbGlicmFyeShkcGx5cikKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShnZ0V4dHJhKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkod2VzYW5kZXJzb24pCmxpYnJhcnkoTW9NQUNvbG9ycykKbGlicmFyeShwcmluY3VydmUpCgojU2V0IGdncGxvdCB0aGVtZSBhcyBjbGFzc2ljCnRoZW1lX3NldCh0aGVtZV9jbGFzc2ljKCkpCmBgYAoKIyBMb2FkIGRhdGFzZXQKCmBgYHtyfQpQaWRkMS5kYXRhIDwtIHJlYWRSRFMoIlBpZGQxS08uY2VsbHMuUkRTIikKCkRpbVBsb3Qob2JqZWN0ID0gUGlkZDEuZGF0YSwKICAgICAgICBncm91cC5ieSA9ICJDZWxsLmlkZW50IiwKICAgICAgICByZWR1Y3Rpb24gPSAic3ByaW5nIiwKICAgICAgICBjb2xzID0gYygiZ3JleTQwIiwiIzRjYWJkYyIsIiMwNDZjOWEiLCAiIzcyOTNjOCIsICIjMzFiNmJkIiwgIiNlYmNiMmUiLCAiIzllYzIyZiIsICIjYTk5NjFiIiwgIiNjYzNhMWIiLCB3ZXNfcGFsZXR0ZSgiRmFudGFzdGljRm94MSIpKSwKICAgICAgICBwdC5zaXplID0gMC41KSAgJiBOb0F4ZXMoKQpgYGAKCmBgYHtyfQpOZXVyb25zLmRhdGEgPC0gIHN1YnNldChQaWRkMS5kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzZXQgPSBDZWxsLmlkZW50ICVpbiUgYygiUHJvZ2VuaXRvcnNfSGVtIiwgIkRpZmZlcmVudGlhdGluZ19DUnMiLCAiTmV1cm9uc19DYWphbC1SZXR6aXVzIikpCgpEaW1QbG90KG9iamVjdCA9IE5ldXJvbnMuZGF0YSwKICAgICAgICBncm91cC5ieSA9ICJDZWxsLmlkZW50IiwKICAgICAgICByZWR1Y3Rpb24gPSAic3ByaW5nIiwKICAgICAgICBjb2xzID0gYygiIzRjYWJkYyIsICIjNzI5M2M4IiwiI2NjM2ExYiIpLAogICAgICAgIHB0LnNpemUgPSAwLjUpICAmIE5vQXhlcygpCmBgYAoKYGBge3IgY2xhc3Mub3V0cHV0PSJzY3JvbGwtMTAwIiwgY2FjaGU9VFJVRX0KCk5ldXJvbnMuZGF0YSA8LSBTQ1RyYW5zZm9ybShOZXVyb25zLmRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJnbG1HYW1Qb2kiLAogICAgICAgICAgICAgICAgICAgICAgICB2YXJzLnRvLnJlZ3Jlc3MgPSBjKCJwZXJjZW50Lm1pdG8iLCAiQ0MuRGlmZmVyZW5jZSIsICJuQ291bnRfUk5BIiksCiAgICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBUKQoKTmV1cm9ucy5kYXRhICA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhOZXVyb25zLmRhdGEsIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMTAwMCkKYGBgCgpgYGB7ciBjbGFzcy5vdXRwdXQ9InNjcm9sbC0xMDAiLCBjYWNoZT1UUlVFfQpOZXVyb25zLmRhdGEgPC0gUnVuUENBKE5ldXJvbnMuZGF0YSwgZmVhdHVyZXMgPSBWYXJpYWJsZUZlYXR1cmVzKE5ldXJvbnMuZGF0YSlbIVZhcmlhYmxlRmVhdHVyZXMoTmV1cm9ucy5kYXRhKSAlaW4lIGMoImVZRlAiLCAiUGlkZDEiKV0gLCB2ZXJib3NlID0gRkFMU0UpCgpOZXVyb25zLmRhdGEgPC0gUnVuVU1BUChOZXVyb25zLmRhdGEsIGRpbXMgPSAxOjUpCmBgYAoKYGBge3J9CkRpbVBsb3Qob2JqZWN0ID0gTmV1cm9ucy5kYXRhLAogICAgICAgIGdyb3VwLmJ5ID0gIkNlbGwuaWRlbnQiLAogICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICBjb2xzID0gYygiIzRjYWJkYyIsICIjNzI5M2M4IiwiI2NjM2ExYiIpLAogICAgICAgIHB0LnNpemUgPSAwLjUpICAmIE5vQXhlcygpCmBgYAoKYGBge3J9CkRpbVBsb3Qob2JqZWN0ID0gTmV1cm9ucy5kYXRhLAogICAgICAgIGdyb3VwLmJ5ID0gIkdlbm90eXBlIiwKICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsCiAgICAgICAgY29scyA9IGMoIiM3MjkzYzgiLCAiI2NjM2ExYiIpLAogICAgICAgIHB0LnNpemUgPSAxKSAgJiBOb0F4ZXMoKQpgYGAKCmBgYHtyfQpGZWF0dXJlUGxvdChvYmplY3QgPSBOZXVyb25zLmRhdGEsCiAgICAgICAgICAgIGZlYXR1cmVzID0gYygiR21uYyIsICJBSTU5MzQ0MiIsICJUcnA3MyIsICJUb3AyYSIsICJQY25hIiwgIkRsbDEiKSwKICAgICAgICAgICAgcHQuc2l6ZSA9IDAuNSwKICAgICAgICAgICAgY29scyA9IGMoImdyZXk5MCIsIGJyZXdlci5wYWwoOSwiWWxHbkJ1IikpLAogICAgICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsCiAgICAgICAgICAgIG9yZGVyID0gVCkgJiBOb0F4ZXMoKSAmIE5vTGVnZW5kKCkKYGBgCgpgYGB7cn0KZml0IDwtIHByaW5jaXBhbF9jdXJ2ZShhcy5tYXRyaXgoTmV1cm9ucy5kYXRhQG1ldGEuZGF0YVssYygiQVBfc2lnbmF0dXJlMSIsICJCUF9zaWduYXR1cmUxIiwgIkVOX3NpZ25hdHVyZTEiLCAiTE5fc2lnbmF0dXJlMSIpXSksCiAgICAgICAgICAgICAgICAgICAgICAgc21vb3RoZXI9J2xvd2VzcycsCiAgICAgICAgICAgICAgICAgICAgICAgdHJhY2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICBmID0gMSwKICAgICAgICAgICAgICAgICAgICAgICBzdHJldGNoPTApCgpQc2V1ZG90aW1lU2NvcmUgPC0gZml0JGxhbWJkYS9tYXgoZml0JGxhbWJkYSkKCmlmIChjb3IoUHNldWRvdGltZVNjb3JlLCBOZXVyb25zLmRhdGFAYXNzYXlzJFJOQUBkYXRhWydIbWdhMicsIF0pID4gMCkgewogIE5ldXJvbnMuZGF0YSRQc2V1ZG90aW1lU2NvcmUgPC0gLShQc2V1ZG90aW1lU2NvcmUgLSBtYXgoUHNldWRvdGltZVNjb3JlKSkKfQoKYGBgCgpgYGB7cn0KRmVhdHVyZVBsb3Qob2JqZWN0ID0gTmV1cm9ucy5kYXRhLAogICAgICAgICAgICBmZWF0dXJlcyA9ICJQc2V1ZG90aW1lU2NvcmUiLAogICAgICAgICAgICBwdC5zaXplID0gMS41LAogICAgICAgICAgICBzcGxpdC5ieSA9ICJHZW5vdHlwZSIsCiAgICAgICAgICAgIGNvbHMgPSAgcmV2KGJyZXdlci5wYWwobiA9MTEsIG5hbWUgPSAiU3BlY3RyYWwiKSksCiAgICAgICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICAgICAgb3JkZXIgPSBUKSAmIE5vQXhlcygpCgoKTmV1cm9ucy5kYXRhIDwtIE5vcm1hbGl6ZURhdGEoTmV1cm9ucy5kYXRhLCBhc3NheSA9ICJSTkEiLCBub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJMb2dOb3JtYWxpemUiLCBzY2FsZS5mYWN0b3IgPSAxMDAwMCkKc2F2ZVJEUyhOZXVyb25zLmRhdGEsICJDUi5UcmFqLlBpZGQxS08uUkRTIikKYGBgCgojIFBsb3QgZ2VuZSBleHByZXNzaW9uIGFsb25nIHBzZXVkb3RpbWUKCmBgYHtyfQojIERlZmluZSBmdW5jdGlvbnMKClBsb3QuZ2VuZS50cmVuZCA8LSBmdW5jdGlvbiAoRGF0YXNldCwgZ2VuZSwgc2hvdy5wdCA9IFQsIHguaW50ZXJjZXB0ID0gTlVMTCkgCnsKICBkYXRhIDwtIGRhdGEuZnJhbWUoR2Vub3R5cGUgPSBhcy5jaGFyYWN0ZXIoRGF0YXNldEBtZXRhLmRhdGEkR2Vub3R5cGUpLCBQc2V1ZG90aW1lID0gRGF0YXNldEBtZXRhLmRhdGEkUHNldWRvdGltZVNjb3JlKQogIGRhdGEkR2VuZSA8LSBEYXRhc2V0QGFzc2F5c1tbIlJOQSJdXUBkYXRhW2dlbmUsIF0KICBwIDwtIGdncGxvdChkYXRhID0gZGF0YSwgYWVzKHggPSBQc2V1ZG90aW1lLCB5ID0gR2VuZSwgY29sb3IgPSBHZW5vdHlwZSkpICsgCiAgICBnZW9tX3BvaW50KHNpemU9MSwgYWxwaGEgPSBpZmVsc2Uoc2hvdy5wdCA9PSBULCAwLjUsIDApKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gbW9tYS5jb2xvcnMoIkFsdGhvZmYiLCA2KVtjKDUsMildKSArCiAgICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBuID0gMzAsIHNpemUgPSAyKSArCiAgICBnZ3RpdGxlKGdlbmUpICsKICAgIHlsaW0oMCwgTkEpICsgCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKHNpemUgPSAxKSkKICAKICBpZiAoIWlzLm51bGwoeC5pbnRlcmNlcHQpKSB7CiAgICBwIDwtIHAgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSB4LmludGVyY2VwdCwgY29sb3VyID0gInJlZCIsIAogICAgICBsaW5ldHlwZSA9IDIpCiAgfQogIHJldHVybihwKQp9CgoKUGxvdC5nZW5lcy50cmVuZCA8LSBmdW5jdGlvbiAoRGF0YXNldCwgZ2VuZXMsIHNob3cucHQ9VCwgeC5pbnRlcmNlcHQgPSBOVUxMKSAKewogIHBMaXN0IDwtIG1hcHBseShGVU4gPSBQbG90LmdlbmUudHJlbmQsIGdlbmUgPSBnZW5lcywgTW9yZUFyZ3MgPSBsaXN0KERhdGFzZXQgPSBEYXRhc2V0LCAKICAgIHNob3cucHQgPSBzaG93LnB0LCB4LmludGVyY2VwdCA9IHguaW50ZXJjZXB0KSwgU0lNUExJRlkgPSBGQUxTRSkKICBwcmludCh4ID0gY293cGxvdDo6cGxvdF9ncmlkKHBsb3RsaXN0ID0gcExpc3QsIG5jb2wgPSAzKSkKfQoKYGBgCgpgYGB7cn0KClBsb3QuZ2VuZS50cmVuZChOZXVyb25zLmRhdGEsICJUcnA3MyIpCgpQbG90LmdlbmVzLnRyZW5kKE5ldXJvbnMuZGF0YSwgYygiUGlkZDEiLCAiZVlGUCIsICJIcmsiKSkKUGxvdC5nZW5lcy50cmVuZChOZXVyb25zLmRhdGEsIHJvd25hbWVzKHJlYWQudGFibGUoIldULkdlbmUuZHluYW1pcXVlLmNzdiIsIGhlYWRlciA9IFQpKVsxOjldKQpQbG90LmdlbmVzLnRyZW5kKE5ldXJvbnMuZGF0YSwgcm93bmFtZXMocmVhZC50YWJsZSgiV1QuR2VuZS5keW5hbWlxdWUuY3N2IiwgaGVhZGVyID0gVCkpWzEwOjE4XSkKUGxvdC5nZW5lcy50cmVuZChOZXVyb25zLmRhdGEsIHJvd25hbWVzKHJlYWQudGFibGUoIldULkdlbmUuZHluYW1pcXVlLmNzdiIsIGhlYWRlciA9IFQpKVsxOToyN10pClBsb3QuZ2VuZXMudHJlbmQoTmV1cm9ucy5kYXRhLCByb3duYW1lcyhyZWFkLnRhYmxlKCJXVC5HZW5lLmR5bmFtaXF1ZS5jc3YiLCBoZWFkZXIgPSBUKSlbMjg6MzZdKQpQbG90LmdlbmVzLnRyZW5kKE5ldXJvbnMuZGF0YSwgcm93bmFtZXMocmVhZC50YWJsZSgiV1QuR2VuZS5keW5hbWlxdWUuY3N2IiwgaGVhZGVyID0gVCkpWzM3OjM5XSkKClBsb3QuZ2VuZXMudHJlbmQoTmV1cm9ucy5kYXRhLCByb3duYW1lcyhyZWFkLnRhYmxlKCJLTy5HZW5lLmR5bmFtaXF1ZS5jc3YiLCBoZWFkZXIgPSBUKSlbMTo5XSkKUGxvdC5nZW5lcy50cmVuZChOZXVyb25zLmRhdGEsIHJvd25hbWVzKHJlYWQudGFibGUoIktPLkdlbmUuZHluYW1pcXVlLmNzdiIsIGhlYWRlciA9IFQpKVsxMDoxOF0pClBsb3QuZ2VuZXMudHJlbmQoTmV1cm9ucy5kYXRhLCByb3duYW1lcyhyZWFkLnRhYmxlKCJLTy5HZW5lLmR5bmFtaXF1ZS5jc3YiLCBoZWFkZXIgPSBUKSlbMTk6MjddKQpQbG90LmdlbmVzLnRyZW5kKE5ldXJvbnMuZGF0YSwgcm93bmFtZXMocmVhZC50YWJsZSgiS08uR2VuZS5keW5hbWlxdWUuY3N2IiwgaGVhZGVyID0gVCkpWzI4OjM0XSkKCk5ldXJvbnMuZGF0YSA8LSBTZXRJZGVudChOZXVyb25zLmRhdGEsIHZhbHVlID0gTmV1cm9ucy5kYXRhQG1ldGEuZGF0YSRDZWxsLmlkZW50KQpLTy5ERUcgPC0gRmluZE1hcmtlcnMoTmV1cm9ucy5kYXRhLCBzdWJzZXQuaWRlbnQgPSAiTmV1cm9uc19DYWphbC1SZXR6aXVzIiwgZ3JvdXAuYnkgPSAiR2Vub3R5cGUiLCBpZGVudC4xID0gIlBpZGQxLktPIikKClBsb3QuZ2VuZXMudHJlbmQoTmV1cm9ucy5kYXRhLCByb3duYW1lcyhLTy5ERUcpWzE6OV0pClBsb3QuZ2VuZXMudHJlbmQoTmV1cm9ucy5kYXRhLCByb3duYW1lcyhLTy5ERUcpWzEwOjE4XSkKUGxvdC5nZW5lcy50cmVuZChOZXVyb25zLmRhdGEsIHJvd25hbWVzKEtPLkRFRylbMTk6MjddKQpQbG90LmdlbmVzLnRyZW5kKE5ldXJvbnMuZGF0YSwgcm93bmFtZXMoS08uREVHKVsyODozNl0pClBsb3QuZ2VuZXMudHJlbmQoTmV1cm9ucy5kYXRhLCByb3duYW1lcyhLTy5ERUcpWzM3OjQ1XSkKUGxvdC5nZW5lcy50cmVuZChOZXVyb25zLmRhdGEsIHJvd25hbWVzKEtPLkRFRylbNDY6NTRdKQpQbG90LmdlbmVzLnRyZW5kKE5ldXJvbnMuZGF0YSwgcm93bmFtZXMoS08uREVHKVs1NTo2M10pClBsb3QuZ2VuZXMudHJlbmQoTmV1cm9ucy5kYXRhLCByb3duYW1lcyhLTy5ERUcpWzY0OjcyXSkKUGxvdC5nZW5lcy50cmVuZChOZXVyb25zLmRhdGEsIHJvd25hbWVzKEtPLkRFRylbNzM6ODFdKQoKCmBgYAoKCgojIFNlc3Npb24gSW5mbwoKYGBge3J9CiNkYXRlCmZvcm1hdChTeXMudGltZSgpLCAiJWQgJUIsICVZLCAlSCwlTSIpCgojUGFja2FnZXMgdXNlZApzZXNzaW9uSW5mbygpCmBgYAo=