diff --git a/.github/components/dictionary.txt b/.github/components/dictionary.txt index cc834fc48..c32f83983 100644 --- a/.github/components/dictionary.txt +++ b/.github/components/dictionary.txt @@ -45,6 +45,7 @@ conda config containerd CopyKAT +CPM CRediT Crompton Ctrl @@ -82,9 +83,12 @@ erythroid et ETP ewings +EWS EWS-FLI1 +exocrine fibroblast fibroblasts +FLI formatters Generis GFM @@ -106,6 +110,7 @@ histological histologies homotypic HPC +HSC IAM ICJME ie @@ -123,6 +128,7 @@ Jupyter karyotyping LCA leiden +leptomeningeal LGBTQ licensor licensor's @@ -134,7 +140,7 @@ linter's linters lockfile Looney -Louvain +louvain LSfR macOS macrophage @@ -151,30 +157,40 @@ microRNA Miniconda Miniforge misidentification +modularity monocyte monocytes +mononuclear MSC multifactor +multinucleated myeloid natively Nextflow nephroblastoma nephron +neutrophil NK nonconsensual octicons onboarded oncotarget +ontologies openscpca OpenScPCA OpenScPCA's +osteoblasts +osteoclast +osteoclasts overclustered Panglao PanglaoDB PDX peritubular +perivascular ploidy pluripotent +programmatically PMID PNG podman @@ -215,6 +231,7 @@ ScType SEACells SemVar seq +SingleCellExperiment SingleR snRNA socio @@ -247,6 +264,7 @@ UCell UMAP uncomment unhide +ureteric uteric vCPU vCPUs diff --git a/analyses/cell-type-consensus/exploratory-notebooks/01-reference-exploration.Rmd b/analyses/cell-type-consensus/exploratory-notebooks/01-reference-exploration.Rmd index 9a06b85cb..68a70703f 100644 --- a/analyses/cell-type-consensus/exploratory-notebooks/01-reference-exploration.Rmd +++ b/analyses/cell-type-consensus/exploratory-notebooks/01-reference-exploration.Rmd @@ -40,31 +40,31 @@ repository_base <- rprojroot::find_root(rprojroot::is_git_root) # The path to this module ref_dir <- file.path(repository_base, "analyses", "cell-type-consensus", "references") -# path to ref file for panglao +# path to ref file for panglao panglao_file <- file.path(ref_dir, "panglao-cell-type-ontologies.tsv") ``` ```{r} -# grab obo file +# grab obo file cl_ont <- ontologyIndex::get_ontology("http://purl.obolibrary.org/obo/cl-basic.obo") -# read in panglao file +# read in panglao file panglao_df <- readr::read_tsv(panglao_file) |> - # rename columns to have panglao in them for easy joining later + # rename columns to have panglao in them for easy joining later dplyr::select( panglao_ontology = "ontology_id", panglao_annotation = "human_readable_value" ) # grab singler ref from celldex -blueprint_ref <- celldex::BlueprintEncodeData() +blueprint_ref <- celldex::BlueprintEncodeData() # get ontologies and human readable name into data frame blueprint_df <- data.frame( blueprint_ontology = blueprint_ref$label.ont, blueprint_annotation_main = blueprint_ref$label.main, blueprint_annotation_fine = blueprint_ref$label.fine -) |> +) |> unique() ``` @@ -74,12 +74,12 @@ Below I will calculate the total number of ancestors and the total number of des This will give us an idea of the range of values we expect to see when looking at the PanglaoDB and Blueprint Encode references. ```{r} -# turn cl_ont into data frame with one row per term +# turn cl_ont into data frame with one row per term cl_df <- data.frame( cl_ontology = cl_ont$id, cl_annotation = cl_ont$name -) |> - dplyr::rowwise() |> +) |> + dplyr::rowwise() |> dplyr::mutate( # list all ancestors and descendants calculate total ancestors = list(ontologyIndex::get_ancestors(cl_ont, cl_ontology)), @@ -93,29 +93,31 @@ The vertical lines in the below plot indicate the value for cell types of varyin ```{r} celltypes_of_interest <- c("eukaryotic cell", "lymphocyte", "leukocyte", "hematopoietic cell", "T cell", "endothelial cell", "smooth muscle cell", "memory T cell") -line_df <- cl_df |> - dplyr::filter(cl_annotation %in% celltypes_of_interest) |> - dplyr::select(cl_annotation, total_descendants, total_ancestors) |> +line_df <- cl_df |> + dplyr::filter(cl_annotation %in% celltypes_of_interest) |> + dplyr::select(cl_annotation, total_descendants, total_ancestors) |> unique() -# group any labels that have the same number of ancestors -ancestor_labels_df <- line_df |> - dplyr::group_by(total_ancestors) |> +# group any labels that have the same number of ancestors +ancestor_labels_df <- line_df |> + dplyr::group_by(total_ancestors) |> dplyr::summarise(cl_annotation = paste(cl_annotation, collapse = ",")) ``` ```{r} -# make density plots showing distribution of ancestors and descendants +# make density plots showing distribution of ancestors and descendants ggplot(cl_df, aes(x = total_ancestors)) + geom_density(fill = "#00274C", alpha = 0.5) + - geom_vline(data = ancestor_labels_df, - mapping = aes(xintercept = total_ancestors), - lty = 2) + + geom_vline( + data = ancestor_labels_df, + mapping = aes(xintercept = total_ancestors), + lty = 2 + ) + geom_text( data = ancestor_labels_df, mapping = aes(x = total_ancestors, y = 0.04, label = cl_annotation), - angle = 90, + angle = 90, vjust = -0.5 ) + labs( @@ -132,13 +134,15 @@ Below we will look at total number of descendants. ```{r} ggplot(cl_df, aes(x = total_descendants)) + geom_density(fill = "#FFCB05", alpha = 0.5) + - geom_vline(data = line_df, - mapping = aes(xintercept = total_descendants), - lty = 2) + + geom_vline( + data = line_df, + mapping = aes(xintercept = total_descendants), + lty = 2 + ) + geom_text( data = line_df, mapping = aes(x = total_descendants, y = 0.6, label = cl_annotation), - angle = 90, + angle = 90, vjust = -0.5 ) + labs( @@ -152,20 +156,22 @@ It looks like most cell types have very few descendants, so let's zoom into the ```{r} ggplot(cl_df, aes(x = total_descendants)) + geom_density(fill = "#FFCB05", alpha = 0.5) + - geom_vline(data = line_df, - mapping = aes(xintercept = total_descendants), - lty = 2) + + geom_vline( + data = line_df, + mapping = aes(xintercept = total_descendants), + lty = 2 + ) + geom_text( data = line_df, mapping = aes(x = total_descendants, y = 0.6, label = cl_annotation), - angle = 90, + angle = 90, vjust = -0.5 ) + labs( x = "Number of descendants", y = "Density" ) + - xlim(c(0,500)) + xlim(c(0, 500)) ``` Here we see a much larger range of values and that cell types become more general as the number of descendants goes up. @@ -194,42 +200,44 @@ cl_graph <- igraph::make_graph(rbind(unlist(parent_terms), rep(names(parent_term ```{r} # get a data frame with all combinations of panglao and blueprint terms -# one row for each combination -all_ref_df <- expand.grid(panglao_df$panglao_ontology, - blueprint_df$blueprint_ontology) |> +# one row for each combination +all_ref_df <- expand.grid( + panglao_df$panglao_ontology, + blueprint_df$blueprint_ontology +) |> dplyr::rename( panglao_ontology = "Var1", blueprint_ontology = "Var2" - ) |> + ) |> # add in the human readable values for each ontology term - dplyr::left_join(blueprint_df, by = "blueprint_ontology") |> - dplyr::left_join(panglao_df, by = "panglao_ontology") |> - tidyr::drop_na() |> - dplyr::rowwise() |> + dplyr::left_join(blueprint_df, by = "blueprint_ontology") |> + dplyr::left_join(panglao_df, by = "panglao_ontology") |> + tidyr::drop_na() |> + dplyr::rowwise() |> dplyr::mutate( # least common shared ancestor lca = list(rownames(ontoProc::findCommonAncestors(blueprint_ontology, panglao_ontology, g = cl_graph))) ) -lca_df <- all_ref_df |> +lca_df <- all_ref_df |> dplyr::mutate( - total_lca = length(lca), # max is three terms - lca = paste0(lca, collapse = ",") # make it easier to split the df + total_lca = length(lca), # max is three terms + lca = paste0(lca, collapse = ",") # make it easier to split the df ) |> - # split each lca term into its own column - tidyr::separate(lca, into = c("lca_1", "lca_2", "lca_3"), sep = ",") |> + # split each lca term into its own column + tidyr::separate(lca, into = c("lca_1", "lca_2", "lca_3"), sep = ",") |> tidyr::pivot_longer( cols = dplyr::starts_with("lca"), names_to = "lca_number", values_to = "lca" - ) |> - tidyr::drop_na() |> - dplyr::select(-lca_number) |> - # account for any cases where the ontology IDs are exact matches + ) |> + tidyr::drop_na() |> + dplyr::select(-lca_number) |> + # account for any cases where the ontology IDs are exact matches # r complains about doing this earlier since the lca column holds lists until now - dplyr::mutate(lca = dplyr::if_else(blueprint_ontology == panglao_ontology, blueprint_ontology, lca)) |> - # join in information for each of the lca terms including name, number of ancestors and descendants - dplyr::left_join(cl_df, by = c("lca" = "cl_ontology")) + dplyr::mutate(lca = dplyr::if_else(blueprint_ontology == panglao_ontology, blueprint_ontology, lca)) |> + # join in information for each of the lca terms including name, number of ancestors and descendants + dplyr::left_join(cl_df, by = c("lca" = "cl_ontology")) ``` @@ -238,13 +246,15 @@ lca_df <- all_ref_df |> ```{r} ggplot(lca_df, aes(x = total_ancestors)) + geom_density() + - geom_vline(data = ancestor_labels_df, - mapping = aes(xintercept = total_ancestors), - lty = 2) + + geom_vline( + data = ancestor_labels_df, + mapping = aes(xintercept = total_ancestors), + lty = 2 + ) + geom_text( data = ancestor_labels_df, mapping = aes(x = total_ancestors, y = 0.6, label = cl_annotation), - angle = 90, + angle = 90, vjust = -0.5 ) + labs( @@ -256,13 +266,15 @@ ggplot(lca_df, aes(x = total_ancestors)) + ```{r} ggplot(lca_df, aes(x = total_descendants)) + geom_density() + - geom_vline(data = line_df, - mapping = aes(xintercept = total_descendants), - lty = 2) + + geom_vline( + data = line_df, + mapping = aes(xintercept = total_descendants), + lty = 2 + ) + geom_text( data = line_df, mapping = aes(x = total_descendants, y = 0.002, label = cl_annotation), - angle = 90, + angle = 90, vjust = -0.5 ) + labs( @@ -271,18 +283,20 @@ ggplot(lca_df, aes(x = total_descendants)) + ) ``` -Let's zoom into the area below 1000, since we already know we would want to exlude anything above that based on this plot. +Let's zoom into the area below 1000, since we already know we would want to exclude anything above that based on this plot. ```{r} ggplot(lca_df, aes(x = total_descendants)) + geom_density() + - geom_vline(data = line_df, - mapping = aes(xintercept = total_descendants), - lty = 2) + + geom_vline( + data = line_df, + mapping = aes(xintercept = total_descendants), + lty = 2 + ) + geom_text( data = line_df, mapping = aes(x = total_descendants, y = 0.002, label = cl_annotation), - angle = 90, + angle = 90, vjust = -0.5 ) + xlim(c(0, 1000)) + @@ -304,30 +318,30 @@ This is likely to be a good cutoff for deciding which LCA labels to keep. ```{r} peak_idx <- splus2R::peaks(lca_df$total_descendants) -cutoff <- lca_df$total_descendants[peak_idx] |> - min() # find the smallest peak and use that as the cutoff for number of descendants +cutoff <- lca_df$total_descendants[peak_idx] |> + min() # find the smallest peak and use that as the cutoff for number of descendants ``` Below is the list of all consensus cell type labels that we will be keeping if we were to just use this cutoff. ```{r} -celltypes_to_keep <- lca_df |> - dplyr::filter(total_descendants <= cutoff) |> - dplyr::pull(cl_annotation) |> +celltypes_to_keep <- lca_df |> + dplyr::filter(total_descendants <= cutoff) |> + dplyr::pull(cl_annotation) |> unique() celltypes_to_keep ``` -We can also look at all the cell types we are keeping and the total number of descendants to see if there are any that may be we don't want to include because the term is too braod. +We can also look at all the cell types we are keeping and the total number of descendants to see if there are any that may be we don't want to include because the term is too broad. ```{r} # pull out the cell types and total descendants for cell types to keep plot_celltype_df <- lca_df |> dplyr::filter(cl_annotation %in% celltypes_to_keep) |> - dplyr::select(cl_annotation, total_descendants) |> + dplyr::select(cl_annotation, total_descendants) |> unique() # bar chart showing total number of descendants for each cell type @@ -354,12 +368,12 @@ Below are tables that look specifically at the combinations of cell type annotat #### Blood cell ```{r} -print_df <- lca_df |> +print_df <- lca_df |> dplyr::select(blueprint_ontology, blueprint_annotation_main, blueprint_annotation_fine, panglao_ontology, panglao_annotation, total_lca, lca, cl_annotation) # blood cell -print_df |> - dplyr::filter(cl_annotation == "blood cell") +print_df |> + dplyr::filter(cl_annotation == "blood cell") ``` I think I'm in favor of not having a "blood cell" label, since I'm not sure that it's helpful. @@ -369,7 +383,7 @@ Also, if two different methods label something a platelet and a neutrophil, then ```{r} # bone cell -print_df |> +print_df |> dplyr::filter(cl_annotation == "bone cell") ``` @@ -379,7 +393,7 @@ I think I would also remove bone cell, since hematopoietic stem cells and osteoc ```{r} # myeloid leukocyte cell -print_df |> +print_df |> dplyr::filter(cl_annotation == "myeloid leukocyte") ``` @@ -390,9 +404,9 @@ Noting that after discussion we have decided to keep this one since T and B cell ```{r} # progenitor cell -print_df |> - dplyr::filter(cl_annotation == "progenitor cell") |> - head(n=15) # there's a lot of these so let's only print out some +print_df |> + dplyr::filter(cl_annotation == "progenitor cell") |> + head(n = 15) # there's a lot of these so let's only print out some ``` Same with `progenitor cell`, I do think it could be helpful to know that something may be a progenitor cell, but when you have a cell with the label for HSC and the label for cells like monocytes or osteoblasts, then maybe we are talking about a tumor cell instead. @@ -403,16 +417,16 @@ Along those same lines, I think the below terms, `lining cell` and `supporting c #### Lining cell ```{r} -# lining cell -print_df |> +# lining cell +print_df |> dplyr::filter(cl_annotation == "lining cell") ``` #### Supporting cell ```{r} -# supporting cell -print_df |> +# supporting cell +print_df |> dplyr::filter(cl_annotation == "supporting cell") ``` @@ -422,9 +436,9 @@ print_df |> We can also look at what cell type labels we are excluding when using this cut off to see if there are any terms we might actually want to keep instead. ```{r} -lca_df |> - dplyr::filter(total_descendants > cutoff) |> - dplyr::pull(cl_annotation) |> +lca_df |> + dplyr::filter(total_descendants > cutoff) |> + dplyr::pull(cl_annotation) |> unique() ``` @@ -435,7 +449,7 @@ Let's look at those combinations. ```{r} # neuron -print_df |> +print_df |> dplyr::filter(cl_annotation == "neuron") ``` @@ -446,7 +460,7 @@ Even though neuron has ~ 500 descendants, I think we should keep these labels. ```{r} # epithelial cell -print_df |> +print_df |> dplyr::filter(cl_annotation == "epithelial cell") ``` @@ -460,9 +474,9 @@ Maybe in the case where we have multiple LCAs we are already too broad and we sh Here I'm looking at the total number of descendants for all terms that show up because a term has multiple LCAs. ```{r} -lca_df |> - dplyr::filter(total_lca > 1) |> - dplyr::select(cl_annotation, total_descendants) |> +lca_df |> + dplyr::filter(total_lca > 1) |> + dplyr::select(cl_annotation, total_descendants) |> unique() |> dplyr::arrange(total_descendants) ``` @@ -475,13 +489,13 @@ I'll also look to see what cell types we lose when we add this extra filtering s ```{r} # remove any combinations with more than one lca -filtered_lca_df <- lca_df |> +filtered_lca_df <- lca_df |> dplyr::filter(total_lca < 2) -# get a list of cell types to keep based on cutoff -updated_celltypes <- filtered_lca_df |> - dplyr::filter(total_descendants <= cutoff) |> - dplyr::pull(cl_annotation) |> +# get a list of cell types to keep based on cutoff +updated_celltypes <- filtered_lca_df |> + dplyr::filter(total_descendants <= cutoff) |> + dplyr::pull(cl_annotation) |> unique() # which cell types are now missing from the list to keep @@ -493,7 +507,7 @@ It looks like I am losing a few terms I already said were not specific and then #### Hematopoietic precursor cell ```{r} -print_df |> +print_df |> dplyr::filter(cl_annotation == "hematopoietic precursor cell") ``` @@ -503,8 +517,8 @@ I think in the context of pediatric cancer having this label would be helpful, s Let's look at what the other LCA is for an example set. ```{r} -lca_df |> - dplyr::filter(panglao_ontology == "CL:0000037" & blueprint_ontology == "CL:0000050") |> +lca_df |> + dplyr::filter(panglao_ontology == "CL:0000037" & blueprint_ontology == "CL:0000050") |> dplyr::select(blueprint_annotation_main, blueprint_annotation_fine, panglao_annotation, cl_annotation) ``` @@ -514,7 +528,7 @@ Personally, I would keep the term for `hematopoietic precursor cell` because I t #### Perivascular cell ```{r} -print_df |> +print_df |> dplyr::filter(cl_annotation == "perivascular cell") ``` @@ -537,18 +551,20 @@ Then we will look at the values for pairs that have an LCA that pass the total d ```{r} information_content <- ontologySimilarity::descendants_IC(cl_ont) -# get similarity index for each set of terms -si_df <- lca_df |> - dplyr::rowwise() |> +# get similarity index for each set of terms +si_df <- lca_df |> + dplyr::rowwise() |> dplyr::mutate( - similarity_index = ontologySimilarity::get_sim_grid(ontology = cl_ont, - term_sets = list(panglao_ontology, blueprint_ontology)) |> + similarity_index = ontologySimilarity::get_sim_grid( + ontology = cl_ont, + term_sets = list(panglao_ontology, blueprint_ontology) + ) |> ontologySimilarity::get_sim() ) ``` ```{r} -si_df <- si_df |> +si_df <- si_df |> dplyr::mutate( lca_threshold = dplyr::if_else(total_descendants < cutoff, "PASS", "FAIL") ) @@ -570,24 +586,25 @@ Here each LCA term is its own plot and the vertical lines are the similarity ind ```{r} celltypes_to_plot <- c("myeloid leukocyte", "T cell", "cell", "supporting cell", "B cell") -celltypes_to_plot |> +celltypes_to_plot |> purrr::map(\(celltype){ - line_df <- si_df |> - dplyr::filter(cl_annotation == celltype) |> - dplyr::select(cl_annotation, similarity_index) |> + line_df <- si_df |> + dplyr::filter(cl_annotation == celltype) |> + dplyr::select(cl_annotation, similarity_index) |> unique() - + ggplot(si_df, aes(x = similarity_index)) + geom_density() + - geom_vline(data = line_df, - mapping = aes(xintercept = similarity_index), - lty = 2) + + geom_vline( + data = line_df, + mapping = aes(xintercept = similarity_index), + lty = 2 + ) + labs( x = "Similarity index", y = "Density", title = celltype ) - }) ``` diff --git a/analyses/cell-type-consensus/exploratory-notebooks/01-reference-exploration.html b/analyses/cell-type-consensus/exploratory-notebooks/01-reference-exploration.html index e2cae57ad..caee7a793 100644 --- a/analyses/cell-type-consensus/exploratory-notebooks/01-reference-exploration.html +++ b/analyses/cell-type-consensus/exploratory-notebooks/01-reference-exploration.html @@ -9,12 +9,366 @@ - - -Summary of cell type ontologies in reference files +01-reference-exploration + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +

<!DOCTYPE html>

+ + + + + + + + +Summary of cell type ontologies in reference files + - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - -

This notebook aims to identify a set of consensus labels between cell -types in the PanglaoDB and Blueprint Encode references.

+

+This notebook aims to identify a set of consensus labels between cell +types in the PanglaoDB and Blueprint Encode references. +

-

Setup

+

+Setup +

suppressPackageStartupMessages({
   # load required packages
   library(ggplot2)
@@ -529,12 +895,16 @@ 

Setup

unique()
-

Full cell ontology

-

Below I will calculate the total number of ancestors and the total +

+Full cell ontology +

+

+Below I will calculate the total number of ancestors and the total number of descendants for each term in the full cell type ontology and then show the distributions for those statistics. This will give us an idea of the range of values we expect to see when looking at the -PanglaoDB and Blueprint Encode references.

+PanglaoDB and Blueprint Encode references. +

# turn cl_ont into data frame with one row per term 
 cl_df <- data.frame(
   cl_ontology = cl_ont$id,
@@ -548,8 +918,10 @@ 

Full cell ontology

descendants = list(ontologyIndex::get_descendants(cl_ont, cl_ontology, exclude_roots = TRUE)), total_descendants = length(descendants) )
-

The vertical lines in the below plot indicate the value for cell -types of varying granularity.

+

+The vertical lines in the below plot indicate the value for cell types +of varying granularity. +

celltypes_of_interest <- c("eukaryotic cell", "lymphocyte", "leukocyte", "hematopoietic cell", "T cell", "endothelial cell", "smooth muscle cell", "memory T cell")
 line_df <- cl_df |> 
   dplyr::filter(cl_annotation %in% celltypes_of_interest) |> 
@@ -576,12 +948,18 @@ 

Full cell ontology

x = "Number of ancestors", y = "Density" )
-

-

Generally it looks like as the cell types get more specific we see a +

+ +

+

+Generally it looks like as the cell types get more specific we see a greater number of ancestors. However, the range of values is small and we see some cell types have the same value and probably not the same -level of granularity.

-

Below we will look at total number of descendants.

+level of granularity. +

+

+Below we will look at total number of descendants. +

ggplot(cl_df, aes(x = total_descendants)) +
   geom_density(fill = "#FFCB05", alpha = 0.5) +
   geom_vline(data = line_df,
@@ -597,9 +975,13 @@ 

Full cell ontology

x = "Number of descendants", y = "Density" )
-

-

It looks like most cell types have very few descendants, so let’s -zoom into the area below 500 to get a better look.

+

+ +

+

+It looks like most cell types have very few descendants, so let’s zoom +into the area below 500 to get a better look. +

ggplot(cl_df, aes(x = total_descendants)) +
   geom_density(fill = "#FFCB05", alpha = 0.5) +
   geom_vline(data = line_df,
@@ -619,30 +1001,42 @@ 

Full cell ontology

## Warning: Removed 14 rows containing non-finite outside the scale range (`stat_density()`).
## Warning: Removed 3 rows containing missing values or values outside the scale range (`geom_vline()`).
## Warning: Removed 3 rows containing missing values or values outside the scale range (`geom_text()`).
-

-

Here we see a much larger range of values and that cell types become +

+ +

+

+Here we see a much larger range of values and that cell types become more general as the number of descendants goes up. However, this distribution alone is probably not helpful in determining a cutoff. The next section we will look at this distribution specifically for cell -types present in our references, PanglaoDB and Blueprint encode.

+types present in our references, PanglaoDB and Blueprint encode. +

-

Latest common ancestor (LCA) between PanglaoDB and Blueprint -encode

-

This section will look at identifying the latest common ancestor -(LCA) between all possible combinations of terms from PanglaoDB (used -for assigning cell types with CellAssign) and the +

+Latest common ancestor (LCA) between PanglaoDB and Blueprint encode +

+

+This section will look at identifying the latest common ancestor (LCA) +between all possible combinations of terms from PanglaoDB (used for +assigning cell types with CellAssign) and the BlueprintEncodeData reference from celldex (used for assigning cell types with SingleR). The LCA refers to the latest term in the cell ontology hierarchy that is common -between two terms. I will use the ontoProc::findCommonAncestors() -function to get the LCA for each combination.

-

Note that it is possible to have more than one LCA for a set of -terms. To start, I will keep all LCA terms found.

-

For each LCA, I will again look at the total number of ancestors and +between two terms. I will use the +ontoProc::findCommonAncestors() +function to get the LCA for each combination. +

+

+Note that it is possible to have more than one LCA for a set of terms. +To start, I will keep all LCA terms found. +

+

+For each LCA, I will again look at the total number of ancestors and descendants and see if I can identify an appropriate cutoff. Ultimately, I would like to see if we can use that cutoff to decide if we should -keep the LCA term as the consensus label or use “Unknown”.

+keep the LCA term as the consensus label or use “Unknown”. +

# first set up the graph from cl ont
 parent_terms <- cl_ont$parents
 cl_graph <- igraph::make_graph(rbind(unlist(parent_terms), rep(names(parent_terms), lengths(parent_terms))))
@@ -696,7 +1090,9 @@

Latest common ancestor (LCA) between PanglaoDB and Blueprint
## Warning: Expected 3 pieces. Missing pieces filled with `NA` in 7967 rows [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
 ## 18, 19, 20, ...].
-

Distribution of ancestors and descendants

+

+Distribution of ancestors and descendants +

ggplot(lca_df, aes(x = total_ancestors)) +
   geom_density() +
   geom_vline(data = ancestor_labels_df,
@@ -712,7 +1108,9 @@ 

Distribution of ancestors and descendants

x = "Total number of ancestors", y = "Density" )
-

+

+ +

ggplot(lca_df, aes(x = total_descendants)) +
   geom_density() +
   geom_vline(data = line_df,
@@ -728,9 +1126,13 @@ 

Distribution of ancestors and descendants

x = "Total number of descendants", y = "Density" )
-

-

Let’s zoom into the area below 1000, since we already know we would -want to exlude anything above that based on this plot.

+

+ +

+

+Let’s zoom into the area below 1000, since we already know we would want +to exlude anything above that based on this plot. +

ggplot(lca_df, aes(x = total_descendants)) +
   geom_density() +
   geom_vline(data = line_df,
@@ -750,27 +1152,37 @@ 

Distribution of ancestors and descendants

## Warning: Removed 6856 rows containing non-finite outside the scale range (`stat_density()`).
## Warning: Removed 1 row containing missing values or values outside the scale range (`geom_vline()`).
## Warning: Removed 1 row containing missing values or values outside the scale range (`geom_text()`).
-

-

We can use the vertical lines for cells of interest to help us define -a potential cutoff based on the granularity we would like to see in our +

+ +

+

+We can use the vertical lines for cells of interest to help us define a +potential cutoff based on the granularity we would like to see in our consensus label. We want to be able to label things like T cell, but we don’t want to label anything as lymphocyte as that’s probably not helpful. I don’t see any obvious cutoffs that may be present in the total number of ancestors, but the number of descendants is likely to be informative. I think it might be a good idea to start by drawing a line at the local maxima between the T cell and lymphocyte lines on the -number of descendants graph.

+number of descendants graph. +

-

Defining a cutoff for number of descendants

-

First we will find the value for the first peak shown in the +

+Defining a cutoff for number of descendants +

+

+First we will find the value for the first peak shown in the distribution. This is likely to be a good cutoff for deciding which LCA -labels to keep.

+labels to keep. +

peak_idx <- splus2R::peaks(lca_df$total_descendants)
 cutoff <- lca_df$total_descendants[peak_idx] |> 
   min() # find the smallest peak and use that as the cutoff for number of descendants 
-

Below is the list of all consensus cell type labels that we will be -keeping if we were to just use this cutoff.

+

+Below is the list of all consensus cell type labels that we will be +keeping if we were to just use this cutoff. +

celltypes_to_keep <- lca_df |> 
   dplyr::filter(total_descendants <= cutoff) |> 
   dplyr::pull(cl_annotation) |> 
@@ -796,9 +1208,11 @@ 

Defining a cutoff for number of descendants

## [49] "pericyte" "perivascular cell" "supporting cell" ## [52] "astrocyte" "glial cell" "macroglial cell" ## [55] "neuron associated cell" "mesangial cell"
-

We can also look at all the cell types we are keeping and the total +

+We can also look at all the cell types we are keeping and the total number of descendants to see if there are any that may be we don’t want -to include because the term is too braod.

+to include because the term is too braod. +

# pull out the cell types and total descendants for cell types to keep
 plot_celltype_df <- lca_df |>
   dplyr::filter(cl_annotation %in% celltypes_to_keep) |>
@@ -815,21 +1229,31 @@ 

Defining a cutoff for number of descendants

x = "cell type", y = "Total descendants" )
-

-

There are a few terms that I think might be more broad than we want -like blood cell, bone cell, -supporting cell, and lining cell. I’m on the -fence about keeping myeloid leukocyte and -progenitor cell. I think if we wanted to remove those terms -we could move our cutoff to be the same number of descendants as -T cell, since we do want to keep that.

-

One could also argue to remove stromal cell or -extracellular matrix secreting cell.

-

Below are tables that look specifically at the combinations of cell -type annotations that resulted in some of the terms that I might -consider removing.

+

+ +

+

+There are a few terms that I think might be more broad than we want like +blood cell, bone cell, supporting +cell, and lining cell. I’m on the fence about +keeping myeloid leukocyte and progenitor cell. +I think if we wanted to remove those terms we could move our cutoff to +be the same number of descendants as T cell, since we do +want to keep that. +

+

+One could also argue to remove stromal cell or +extracellular matrix secreting cell. +

+

+Below are tables that look specifically at the combinations of cell type +annotations that resulted in some of the terms that I might consider +removing. +

-

Blood cell

+

+Blood cell +

print_df <- lca_df |> 
   dplyr::select(blueprint_ontology, blueprint_annotation_main, blueprint_annotation_fine, panglao_ontology, panglao_annotation, total_lca, lca, cl_annotation)
 
@@ -850,87 +1274,203 @@ 

Blood cell

-blueprint_ontology -blueprint_annotation_main -blueprint_annotation_fine -panglao_ontology -panglao_annotation -total_lca -lca -cl_annotation + +blueprint_ontology + + +blueprint_annotation_main + + +blueprint_annotation_fine + + +panglao_ontology + + +panglao_annotation + + +total_lca + + +lca + + +cl_annotation + -CL:0000775 -Neutrophils -Neutrophils -CL:0000233 -platelet -2 -CL:0000081 -blood cell - - -CL:0000232 -Erythrocytes -Erythrocytes -CL:0000767 -basophil -2 -CL:0000081 -blood cell - - -CL:0000232 -Erythrocytes -Erythrocytes -CL:0000771 -eosinophil -2 -CL:0000081 -blood cell - - -CL:0000232 -Erythrocytes -Erythrocytes -CL:0000775 -neutrophil -2 -CL:0000081 -blood cell - - -CL:0000232 -Erythrocytes -Erythrocytes -CL:0000233 -platelet -2 -CL:0000081 -blood cell - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000233 -platelet -2 -CL:0000081 -blood cell + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000233 + + +platelet + + +2 + + +CL:0000081 + + +blood cell + + + + +CL:0000232 + + +Erythrocytes + + +Erythrocytes + + +CL:0000767 + + +basophil + + +2 + + +CL:0000081 + + +blood cell + + + + +CL:0000232 + + +Erythrocytes + + +Erythrocytes + + +CL:0000771 + + +eosinophil + + +2 + + +CL:0000081 + + +blood cell + + + + +CL:0000232 + + +Erythrocytes + + +Erythrocytes + + +CL:0000775 + + +neutrophil + + +2 + + +CL:0000081 + + +blood cell + + + + +CL:0000232 + + +Erythrocytes + + +Erythrocytes + + +CL:0000233 + + +platelet + + +2 + + +CL:0000081 + + +blood cell + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000233 + + +platelet + + +2 + + +CL:0000081 + + +blood cell +
-

I think I’m in favor of not having a “blood cell” label, since I’m -not sure that it’s helpful. Also, if two different methods label -something a platelet and a neutrophil, then perhaps that label is -inaccurate and it’s really a tumor cell.

+

+I think I’m in favor of not having a “blood cell” label, since I’m not +sure that it’s helpful. Also, if two different methods label something a +platelet and a neutrophil, then perhaps that label is inaccurate and +it’s really a tumor cell. +

-

Bone cell

+

+Bone cell +

# bone cell
 print_df |> 
   dplyr::filter(cl_annotation == "bone cell")
@@ -948,45 +1488,97 @@

Bone cell

-blueprint_ontology -blueprint_annotation_main -blueprint_annotation_fine -panglao_ontology -panglao_annotation -total_lca -lca -cl_annotation + +blueprint_ontology + + +blueprint_annotation_main + + +blueprint_annotation_fine + + +panglao_ontology + + +panglao_annotation + + +total_lca + + +lca + + +cl_annotation + -CL:0000557 -HSC -GMP -CL:0000092 -osteoclast -2 -CL:0001035 -bone cell - - -CL:0000557 -HSC -GMP -CL:0000137 -osteocyte -1 -CL:0001035 -bone cell + +CL:0000557 + + +HSC + + +GMP + + +CL:0000092 + + +osteoclast + + +2 + + +CL:0001035 + + +bone cell + + + + +CL:0000557 + + +HSC + + +GMP + + +CL:0000137 + + +osteocyte + + +1 + + +CL:0001035 + + +bone cell +
-

I think I would also remove bone cell, since hematopoietic stem cells -and osteoclasts seem pretty different to me.

+

+I think I would also remove bone cell, since hematopoietic stem cells +and osteoclasts seem pretty different to me. +

-

Myeloid leukocyte

+

+Myeloid leukocyte +

# myeloid leukocyte cell
 print_df |> 
   dplyr::filter(cl_annotation == "myeloid leukocyte")
@@ -1004,739 +1596,1895 @@

Myeloid leukocyte

-blueprint_ontology -blueprint_annotation_main -blueprint_annotation_fine -panglao_ontology -panglao_annotation -total_lca -lca -cl_annotation + +blueprint_ontology + + +blueprint_annotation_main + + +blueprint_annotation_fine + + +panglao_ontology + + +panglao_annotation + + +total_lca + + +lca + + +cl_annotation + -CL:0000775 -Neutrophils -Neutrophils -CL:0000583 -alveolar macrophage -1 -CL:0000766 -myeloid leukocyte - - -CL:0000775 -Neutrophils -Neutrophils -CL:0000235 -macrophage -1 -CL:0000766 -myeloid leukocyte - - -CL:0000775 -Neutrophils -Neutrophils -CL:0000097 -mast cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000775 -Neutrophils -Neutrophils -CL:0000576 -monocyte -1 -CL:0000766 -myeloid leukocyte - - -CL:0000775 -Neutrophils -Neutrophils -CL:0000576 -monocyte -1 -CL:0000766 -myeloid leukocyte - - -CL:0000775 -Neutrophils -Neutrophils -CL:0000092 -osteoclast -1 -CL:0000766 -myeloid leukocyte - - -CL:0000775 -Neutrophils -Neutrophils -CL:0000091 -Kupffer cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000775 -Neutrophils -Neutrophils -CL:0000453 -Langerhans cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000775 -Neutrophils -Neutrophils -CL:0000129 -microglial cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000775 -Neutrophils -Neutrophils -CL:0000889 -myeloid suppressor cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000775 -Neutrophils -Neutrophils -CL:0000576 -monocyte -1 -CL:0000766 -myeloid leukocyte - - -CL:0000775 -Neutrophils -Neutrophils -CL:0000576 -monocyte -1 -CL:0000766 -myeloid leukocyte - - -CL:0000775 -Neutrophils -Neutrophils -CL:0000874 -splenic red pulp macrophage -1 -CL:0000766 -myeloid leukocyte - - -CL:0000576 -Monocytes -Monocytes -CL:0000583 -alveolar macrophage -2 -CL:0000766 -myeloid leukocyte - - -CL:0000576 -Monocytes -Monocytes -CL:0000767 -basophil -1 -CL:0000766 -myeloid leukocyte - - -CL:0000576 -Monocytes -Monocytes -CL:0000771 -eosinophil -1 -CL:0000766 -myeloid leukocyte - - -CL:0000576 -Monocytes -Monocytes -CL:0000235 -macrophage -2 -CL:0000766 -myeloid leukocyte - - -CL:0000576 -Monocytes -Monocytes -CL:0000097 -mast cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000576 -Monocytes -Monocytes -CL:0000775 -neutrophil -1 -CL:0000766 -myeloid leukocyte - - -CL:0000576 -Monocytes -Monocytes -CL:0000092 -osteoclast -2 -CL:0000766 -myeloid leukocyte - - -CL:0000576 -Monocytes -Monocytes -CL:0000091 -Kupffer cell -2 -CL:0000766 -myeloid leukocyte - - -CL:0000576 -Monocytes -Monocytes -CL:0000453 -Langerhans cell -2 -CL:0000766 -myeloid leukocyte - - -CL:0000576 -Monocytes -Monocytes -CL:0000129 -microglial cell -2 -CL:0000766 -myeloid leukocyte - - -CL:0000576 -Monocytes -Monocytes -CL:0000889 -myeloid suppressor cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000576 -Monocytes -Monocytes -CL:0000874 -splenic red pulp macrophage -2 -CL:0000766 -myeloid leukocyte - - -CL:0000235 -Macrophages -Macrophages -CL:0000767 -basophil -1 -CL:0000766 -myeloid leukocyte - - -CL:0000235 -Macrophages -Macrophages -CL:0000771 -eosinophil -1 -CL:0000766 -myeloid leukocyte - - -CL:0000235 -Macrophages -Macrophages -CL:0000097 -mast cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000235 -Macrophages -Macrophages -CL:0000576 -monocyte -2 -CL:0000766 -myeloid leukocyte - - -CL:0000235 -Macrophages -Macrophages -CL:0000576 -monocyte -2 -CL:0000766 -myeloid leukocyte - - -CL:0000235 -Macrophages -Macrophages -CL:0000775 -neutrophil -1 -CL:0000766 -myeloid leukocyte - - -CL:0000235 -Macrophages -Macrophages -CL:0000092 -osteoclast -2 -CL:0000766 -myeloid leukocyte - - -CL:0000235 -Macrophages -Macrophages -CL:0000453 -Langerhans cell -3 -CL:0000766 -myeloid leukocyte - - -CL:0000235 -Macrophages -Macrophages -CL:0000889 -myeloid suppressor cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000235 -Macrophages -Macrophages -CL:0000576 -monocyte -2 -CL:0000766 -myeloid leukocyte - - -CL:0000235 -Macrophages -Macrophages -CL:0000576 -monocyte -2 -CL:0000766 -myeloid leukocyte - - -CL:0000863 -Macrophages -Macrophages M1 -CL:0000767 -basophil -1 -CL:0000766 -myeloid leukocyte - - -CL:0000863 -Macrophages -Macrophages M1 -CL:0000771 -eosinophil -1 -CL:0000766 -myeloid leukocyte - - -CL:0000863 -Macrophages -Macrophages M1 -CL:0000097 -mast cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000863 -Macrophages -Macrophages M1 -CL:0000576 -monocyte -2 -CL:0000766 -myeloid leukocyte - - -CL:0000863 -Macrophages -Macrophages M1 -CL:0000576 -monocyte -2 -CL:0000766 -myeloid leukocyte - - -CL:0000863 -Macrophages -Macrophages M1 -CL:0000775 -neutrophil -1 -CL:0000766 -myeloid leukocyte - - -CL:0000863 -Macrophages -Macrophages M1 -CL:0000092 -osteoclast -2 -CL:0000766 -myeloid leukocyte - - -CL:0000863 -Macrophages -Macrophages M1 -CL:0000453 -Langerhans cell -3 -CL:0000766 -myeloid leukocyte - - -CL:0000863 -Macrophages -Macrophages M1 -CL:0000889 -myeloid suppressor cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000863 -Macrophages -Macrophages M1 -CL:0000576 -monocyte -2 -CL:0000766 -myeloid leukocyte - - -CL:0000863 -Macrophages -Macrophages M1 -CL:0000576 -monocyte -2 -CL:0000766 -myeloid leukocyte - - -CL:0000890 -Macrophages -Macrophages M2 -CL:0000767 -basophil -1 -CL:0000766 -myeloid leukocyte - - -CL:0000890 -Macrophages -Macrophages M2 -CL:0000771 -eosinophil -1 -CL:0000766 -myeloid leukocyte - - -CL:0000890 -Macrophages -Macrophages M2 -CL:0000097 -mast cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000890 -Macrophages -Macrophages M2 -CL:0000576 -monocyte -2 -CL:0000766 -myeloid leukocyte - - -CL:0000890 -Macrophages -Macrophages M2 -CL:0000576 -monocyte -2 -CL:0000766 -myeloid leukocyte - - -CL:0000890 -Macrophages -Macrophages M2 -CL:0000775 -neutrophil -1 -CL:0000766 -myeloid leukocyte - - -CL:0000890 -Macrophages -Macrophages M2 -CL:0000092 -osteoclast -2 -CL:0000766 -myeloid leukocyte - - -CL:0000890 -Macrophages -Macrophages M2 -CL:0000453 -Langerhans cell -3 -CL:0000766 -myeloid leukocyte - - -CL:0000890 -Macrophages -Macrophages M2 -CL:0000889 -myeloid suppressor cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000890 -Macrophages -Macrophages M2 -CL:0000576 -monocyte -2 -CL:0000766 -myeloid leukocyte - - -CL:0000890 -Macrophages -Macrophages M2 -CL:0000576 -monocyte -2 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000583 -alveolar macrophage -1 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000235 -macrophage -1 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000097 -mast cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000576 -monocyte -1 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000576 -monocyte -1 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000092 -osteoclast -1 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000091 -Kupffer cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000453 -Langerhans cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000129 -microglial cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000889 -myeloid suppressor cell -1 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000576 -monocyte -1 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000576 -monocyte -1 -CL:0000766 -myeloid leukocyte - - -CL:0000771 -Eosinophils -Eosinophils -CL:0000874 -splenic red pulp macrophage -1 -CL:0000766 -myeloid leukocyte + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000583 + + +alveolar macrophage + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000235 + + +macrophage + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000097 + + +mast cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000576 + + +monocyte + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000576 + + +monocyte + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000092 + + +osteoclast + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000091 + + +Kupffer cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000453 + + +Langerhans cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000129 + + +microglial cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000889 + + +myeloid suppressor cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000576 + + +monocyte + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000576 + + +monocyte + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000775 + + +Neutrophils + + +Neutrophils + + +CL:0000874 + + +splenic red pulp macrophage + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000583 + + +alveolar macrophage + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000767 + + +basophil + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000771 + + +eosinophil + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000235 + + +macrophage + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000097 + + +mast cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000775 + + +neutrophil + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000092 + + +osteoclast + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000091 + + +Kupffer cell + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000453 + + +Langerhans cell + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000129 + + +microglial cell + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000889 + + +myeloid suppressor cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000874 + + +splenic red pulp macrophage + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000235 + + +Macrophages + + +Macrophages + + +CL:0000767 + + +basophil + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000235 + + +Macrophages + + +Macrophages + + +CL:0000771 + + +eosinophil + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000235 + + +Macrophages + + +Macrophages + + +CL:0000097 + + +mast cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000235 + + +Macrophages + + +Macrophages + + +CL:0000576 + + +monocyte + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000235 + + +Macrophages + + +Macrophages + + +CL:0000576 + + +monocyte + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000235 + + +Macrophages + + +Macrophages + + +CL:0000775 + + +neutrophil + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000235 + + +Macrophages + + +Macrophages + + +CL:0000092 + + +osteoclast + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000235 + + +Macrophages + + +Macrophages + + +CL:0000453 + + +Langerhans cell + + +3 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000235 + + +Macrophages + + +Macrophages + + +CL:0000889 + + +myeloid suppressor cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000235 + + +Macrophages + + +Macrophages + + +CL:0000576 + + +monocyte + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000235 + + +Macrophages + + +Macrophages + + +CL:0000576 + + +monocyte + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000863 + + +Macrophages + + +Macrophages M1 + + +CL:0000767 + + +basophil + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000863 + + +Macrophages + + +Macrophages M1 + + +CL:0000771 + + +eosinophil + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000863 + + +Macrophages + + +Macrophages M1 + + +CL:0000097 + + +mast cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000863 + + +Macrophages + + +Macrophages M1 + + +CL:0000576 + + +monocyte + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000863 + + +Macrophages + + +Macrophages M1 + + +CL:0000576 + + +monocyte + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000863 + + +Macrophages + + +Macrophages M1 + + +CL:0000775 + + +neutrophil + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000863 + + +Macrophages + + +Macrophages M1 + + +CL:0000092 + + +osteoclast + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000863 + + +Macrophages + + +Macrophages M1 + + +CL:0000453 + + +Langerhans cell + + +3 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000863 + + +Macrophages + + +Macrophages M1 + + +CL:0000889 + + +myeloid suppressor cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000863 + + +Macrophages + + +Macrophages M1 + + +CL:0000576 + + +monocyte + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000863 + + +Macrophages + + +Macrophages M1 + + +CL:0000576 + + +monocyte + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000890 + + +Macrophages + + +Macrophages M2 + + +CL:0000767 + + +basophil + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000890 + + +Macrophages + + +Macrophages M2 + + +CL:0000771 + + +eosinophil + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000890 + + +Macrophages + + +Macrophages M2 + + +CL:0000097 + + +mast cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000890 + + +Macrophages + + +Macrophages M2 + + +CL:0000576 + + +monocyte + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000890 + + +Macrophages + + +Macrophages M2 + + +CL:0000576 + + +monocyte + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000890 + + +Macrophages + + +Macrophages M2 + + +CL:0000775 + + +neutrophil + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000890 + + +Macrophages + + +Macrophages M2 + + +CL:0000092 + + +osteoclast + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000890 + + +Macrophages + + +Macrophages M2 + + +CL:0000453 + + +Langerhans cell + + +3 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000890 + + +Macrophages + + +Macrophages M2 + + +CL:0000889 + + +myeloid suppressor cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000890 + + +Macrophages + + +Macrophages M2 + + +CL:0000576 + + +monocyte + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000890 + + +Macrophages + + +Macrophages M2 + + +CL:0000576 + + +monocyte + + +2 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000583 + + +alveolar macrophage + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000235 + + +macrophage + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000097 + + +mast cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000576 + + +monocyte + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000576 + + +monocyte + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000092 + + +osteoclast + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000091 + + +Kupffer cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000453 + + +Langerhans cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000129 + + +microglial cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000889 + + +myeloid suppressor cell + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000576 + + +monocyte + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000576 + + +monocyte + + +1 + + +CL:0000766 + + +myeloid leukocyte + + + + +CL:0000771 + + +Eosinophils + + +Eosinophils + + +CL:0000874 + + +splenic red pulp macrophage + + +1 + + +CL:0000766 + + +myeloid leukocyte +
-

I’m torn on this one, because I do think it’s helpful to know if +

+I’m torn on this one, because I do think it’s helpful to know if something is of the myeloid lineage, but if we aren’t keeping lymphocyte then I would argue we shouldn’t keep myeloid leukocyte. Noting that after discussion we have decided to keep this one since T and B cells are much easier to differentiate based on gene expression alone than -cells that are part of the myeloid lineage.

+cells that are part of the myeloid lineage. +

-

Progenitor cell

+

+Progenitor cell +

# progenitor cell
 print_df |> 
   dplyr::filter(cl_annotation == "progenitor cell") |> 
@@ -1755,181 +3503,443 @@ 

Progenitor cell

-blueprint_ontology -blueprint_annotation_main -blueprint_annotation_fine -panglao_ontology -panglao_annotation -total_lca -lca -cl_annotation + +blueprint_ontology + + +blueprint_annotation_main + + +blueprint_annotation_fine + + +panglao_ontology + + +panglao_annotation + + +total_lca + + +lca + + +cl_annotation + -CL:0000576 -Monocytes -Monocytes -CL:0000765 -erythroblast -2 -CL:0011026 -progenitor cell - - -CL:0000576 -Monocytes -Monocytes -CL:0000037 -hematopoietic stem cell -2 -CL:0011026 -progenitor cell - - -CL:0000576 -Monocytes -Monocytes -CL:0000062 -osteoblast -1 -CL:0011026 -progenitor cell - - -CL:0000576 -Monocytes -Monocytes -CL:0000158 -club cell -1 -CL:0011026 -progenitor cell - - -CL:0000576 -Monocytes -Monocytes -CL:0000038 -erythroid progenitor cell -2 -CL:0011026 -progenitor cell - - -CL:0000576 -Monocytes -Monocytes -CL:4042021 -neuronal-restricted precursor -1 -CL:0011026 -progenitor cell - - -CL:0000576 -Monocytes -Monocytes -CL:0002453 -oligodendrocyte precursor cell -1 -CL:0011026 -progenitor cell - - -CL:0000576 -Monocytes -Monocytes -CL:0002351 -progenitor cell of endocrine pancreas -1 -CL:0011026 -progenitor cell - - -CL:0000050 -HSC -MEP -CL:0000765 -erythroblast -2 -CL:0011026 -progenitor cell - - -CL:0000050 -HSC -MEP -CL:0000037 -hematopoietic stem cell -2 -CL:0011026 -progenitor cell - - -CL:0000050 -HSC -MEP -CL:0000576 -monocyte -2 -CL:0011026 -progenitor cell - - -CL:0000050 -HSC -MEP -CL:0000576 -monocyte -2 -CL:0011026 -progenitor cell - - -CL:0000050 -HSC -MEP -CL:0000062 -osteoblast -1 -CL:0011026 -progenitor cell - - -CL:0000050 -HSC -MEP -CL:0000158 -club cell -1 -CL:0011026 -progenitor cell - - -CL:0000050 -HSC -MEP -CL:0000038 -erythroid progenitor cell -3 -CL:0011026 -progenitor cell + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000765 + + +erythroblast + + +2 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000037 + + +hematopoietic stem cell + + +2 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000062 + + +osteoblast + + +1 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000158 + + +club cell + + +1 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0000038 + + +erythroid progenitor cell + + +2 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:4042021 + + +neuronal-restricted precursor + + +1 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0002453 + + +oligodendrocyte precursor cell + + +1 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000576 + + +Monocytes + + +Monocytes + + +CL:0002351 + + +progenitor cell of endocrine pancreas + + +1 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000050 + + +HSC + + +MEP + + +CL:0000765 + + +erythroblast + + +2 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000050 + + +HSC + + +MEP + + +CL:0000037 + + +hematopoietic stem cell + + +2 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000050 + + +HSC + + +MEP + + +CL:0000576 + + +monocyte + + +2 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000050 + + +HSC + + +MEP + + +CL:0000576 + + +monocyte + + +2 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000050 + + +HSC + + +MEP + + +CL:0000062 + + +osteoblast + + +1 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000050 + + +HSC + + +MEP + + +CL:0000158 + + +club cell + + +1 + + +CL:0011026 + + +progenitor cell + + + + +CL:0000050 + + +HSC + + +MEP + + +CL:0000038 + + +erythroid progenitor cell + + +3 + + +CL:0011026 + + +progenitor cell +
-

Same with progenitor cell, I do think it could be -helpful to know that something may be a progenitor cell, but when you -have a cell with the label for HSC and the label for cells like -monocytes or osteoblasts, then maybe we are talking about a tumor cell -instead. After discussion, we are going to remove progenitor cells.

-

Along those same lines, I think the below terms, -lining cell and supporting cell, are too broad -even though they have few descendants.

+

+Same with progenitor cell, I do think it could be helpful +to know that something may be a progenitor cell, but when you have a +cell with the label for HSC and the label for cells like monocytes or +osteoblasts, then maybe we are talking about a tumor cell instead. After +discussion, we are going to remove progenitor cells. +

+

+Along those same lines, I think the below terms, lining +cell and supporting cell, are too broad even though +they have few descendants. +

-

Lining cell

+

+Lining cell +

# lining cell 
 print_df |> 
   dplyr::filter(cl_annotation == "lining cell")
@@ -1947,83 +3957,197 @@

Lining cell

-blueprint_ontology -blueprint_annotation_main -blueprint_annotation_fine -panglao_ontology -panglao_annotation -total_lca -lca -cl_annotation + +blueprint_ontology + + +blueprint_annotation_main + + +blueprint_annotation_fine + + +panglao_ontology + + +panglao_annotation + + +total_lca + + +lca + + +cl_annotation + -CL:0000115 -Endothelial cells -Endothelial cells -CL:0000077 -mesothelial cell -2 -CL:0000213 -lining cell - - -CL:0000115 -Endothelial cells -Endothelial cells -CL:0002481 -peritubular myoid cell -2 -CL:0000213 -lining cell - - -CL:0000115 -Endothelial cells -Endothelial cells -CL:0000216 -Sertoli cell -2 -CL:0000213 -lining cell - - -CL:2000008 -Endothelial cells -mv Endothelial cells -CL:0000077 -mesothelial cell -2 -CL:0000213 -lining cell - - -CL:2000008 -Endothelial cells -mv Endothelial cells -CL:0002481 -peritubular myoid cell -2 -CL:0000213 -lining cell - - -CL:2000008 -Endothelial cells -mv Endothelial cells -CL:0000216 -Sertoli cell -2 -CL:0000213 -lining cell + +CL:0000115 + + +Endothelial cells + + +Endothelial cells + + +CL:0000077 + + +mesothelial cell + + +2 + + +CL:0000213 + + +lining cell + + + + +CL:0000115 + + +Endothelial cells + + +Endothelial cells + + +CL:0002481 + + +peritubular myoid cell + + +2 + + +CL:0000213 + + +lining cell + + + + +CL:0000115 + + +Endothelial cells + + +Endothelial cells + + +CL:0000216 + + +Sertoli cell + + +2 + + +CL:0000213 + + +lining cell + + + + +CL:2000008 + + +Endothelial cells + + +mv Endothelial cells + + +CL:0000077 + + +mesothelial cell + + +2 + + +CL:0000213 + + +lining cell + + + + +CL:2000008 + + +Endothelial cells + + +mv Endothelial cells + + +CL:0002481 + + +peritubular myoid cell + + +2 + + +CL:0000213 + + +lining cell + + + + +CL:2000008 + + +Endothelial cells + + +mv Endothelial cells + + +CL:0000216 + + +Sertoli cell + + +2 + + +CL:0000213 + + +lining cell +
-

Supporting cell

+

+Supporting cell +

# supporting cell 
 print_df |> 
   dplyr::filter(cl_annotation == "supporting cell")
@@ -2041,36 +4165,84 @@

Supporting cell

-blueprint_ontology -blueprint_annotation_main -blueprint_annotation_fine -panglao_ontology -panglao_annotation -total_lca -lca -cl_annotation + +blueprint_ontology + + +blueprint_annotation_main + + +blueprint_annotation_fine + + +panglao_ontology + + +panglao_annotation + + +total_lca + + +lca + + +cl_annotation + -CL:0000669 -Pericytes -Pericytes -CL:0000216 -Sertoli cell -2 -CL:0000630 -supporting cell - - -CL:0000650 -Mesangial cells -Mesangial cells -CL:0000216 -Sertoli cell -2 -CL:0000630 -supporting cell + +CL:0000669 + + +Pericytes + + +Pericytes + + +CL:0000216 + + +Sertoli cell + + +2 + + +CL:0000630 + + +supporting cell + + + + +CL:0000650 + + +Mesangial cells + + +Mesangial cells + + +CL:0000216 + + +Sertoli cell + + +2 + + +CL:0000630 + + +supporting cell + @@ -2078,10 +4250,14 @@

Supporting cell

-

Discarded cell types

-

We can also look at what cell type labels we are excluding when using +

+Discarded cell types +

+

+We can also look at what cell type labels we are excluding when using this cut off to see if there are any terms we might actually want to -keep instead.

+keep instead. +

lca_df |> 
   dplyr::filter(total_descendants > cutoff) |> 
   dplyr::pull(cl_annotation) |> 
@@ -2093,10 +4269,14 @@ 

Discarded cell types

## [13] "secretory cell" "connective tissue cell" "electrically responsive cell" ## [16] "contractile cell" "epithelial cell" "neuron" ## [19] "neural cell"
-

The only terms in this list that I would be concerned about losing -are “neuron” and epithelial cells. Let’s look at those combinations.

+

+The only terms in this list that I would be concerned about losing are +“neuron” and epithelial cells. Let’s look at those combinations. +

-

Neuron

+

+Neuron +

# neuron
 print_df |> 
   dplyr::filter(cl_annotation == "neuron")
@@ -2114,226 +4294,566 @@

Neuron

-blueprint_ontology -blueprint_annotation_main -blueprint_annotation_fine -panglao_ontology -panglao_annotation -total_lca -lca -cl_annotation + +blueprint_ontology + + +blueprint_annotation_main + + +blueprint_annotation_fine + + +panglao_ontology + + +panglao_annotation + + +total_lca + + +lca + + +cl_annotation + -CL:0000540 -Neurons -Neurons -CL:0000109 -adrenergic neuron -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000108 -cholinergic neuron -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000166 -chromaffin cell -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000700 -dopaminergic neuron -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0007011 -enteric neuron -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:1001509 -glycinergic neuron -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000099 -interneuron -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000100 -motor neuron -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000165 -neuroendocrine cell -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000540 -neuron -0 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0008025 -noradrenergic neuron -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000210 -photoreceptor cell -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000740 -retinal ganglion cell -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000850 -serotonergic neuron -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:4023169 -trigeminal neuron -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000695 -Cajal-Retzius cell -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000617 -GABAergic neuron -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000679 -glutamatergic neuron -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000121 -Purkinje cell -1 -CL:0000540 -neuron - - -CL:0000540 -Neurons -Neurons -CL:0000598 -pyramidal neuron -1 -CL:0000540 -neuron + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000109 + + +adrenergic neuron + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000108 + + +cholinergic neuron + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000166 + + +chromaffin cell + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000700 + + +dopaminergic neuron + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0007011 + + +enteric neuron + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:1001509 + + +glycinergic neuron + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000099 + + +interneuron + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000100 + + +motor neuron + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000165 + + +neuroendocrine cell + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000540 + + +neuron + + +0 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0008025 + + +noradrenergic neuron + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000210 + + +photoreceptor cell + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000740 + + +retinal ganglion cell + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000850 + + +serotonergic neuron + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:4023169 + + +trigeminal neuron + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000695 + + +Cajal-Retzius cell + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000617 + + +GABAergic neuron + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000679 + + +glutamatergic neuron + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000121 + + +Purkinje cell + + +1 + + +CL:0000540 + + +neuron + + + + +CL:0000540 + + +Neurons + + +Neurons + + +CL:0000598 + + +pyramidal neuron + + +1 + + +CL:0000540 + + +neuron +
-

It looks like there are a lot of types of neurons in the PanglaoDB +

+It looks like there are a lot of types of neurons in the PanglaoDB reference and only “neuron” as a term in Blueprint. Even though neuron -has ~ 500 descendants, I think we should keep these labels.

+has ~ 500 descendants, I think we should keep these labels. +

-

Epithelial cell

+

+Epithelial cell +

# epithelial cell
 print_df |> 
   dplyr::filter(cl_annotation == "epithelial cell")
@@ -2351,1015 +4871,2605 @@

Epithelial cell

-blueprint_ontology -blueprint_annotation_main -blueprint_annotation_fine -panglao_ontology -panglao_annotation -total_lca -lca -cl_annotation + +blueprint_ontology + + +blueprint_annotation_main + + +blueprint_annotation_fine + + +panglao_ontology + + +panglao_annotation + + +total_lca + + +lca + + +cl_annotation + -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000622 -acinar cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:1000488 -cholangiocyte -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000166 -chromaffin cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000584 -enterocyte -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000164 -enteroendocrine cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000065 -ependymal cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000066 -epithelial cell -0 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000160 -goblet cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000501 -granulosa cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000182 -hepatocyte -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0005006 -ionocyte -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000312 -keratinocyte -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000077 -mesothelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000185 -myoepithelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000165 -neuroendocrine cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002167 -olfactory epithelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000510 -paneth cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000162 -parietal cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002481 -peritubular myoid cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000652 -pinealocyte -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000653 -podocyte -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000209 -taste receptor cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000731 -urothelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002368 -respiratory epithelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002370 -respiratory goblet cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000171 -pancreatic A cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000169 -type B pancreatic cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000706 -choroid plexus epithelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000158 -club cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002250 -intestinal crypt stem cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000173 -pancreatic D cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002305 -epithelial cell of distal tubule -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002079 -pancreatic ductal cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000504 -enterochromaffin-like cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0005019 -pancreatic epsilon cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002258 -thyroid follicular cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002179 -foveolar cell of stomach -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000696 -PP cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000155 -peptic cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002292 -type I cell of carotid body -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0005010 -renal intercalated cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:1000909 -kidney loop of Henle epithelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002326 -luminal epithelial cell of mammary gland -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002327 -mammary gland epithelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000242 -Merkel cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000682 -M cell of gut -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002199 -oxyphil cell of parathyroid gland -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000446 -chief cell of parathyroid gland -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0005009 -renal principal cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002306 -epithelial cell of proximal tubule -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002062 -pulmonary alveolar type 1 cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002063 -pulmonary alveolar type 2 cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:1001596 -salivary gland glandular cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002140 -acinar cell of sebaceous gland -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0000216 -Sertoli cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002562 -hair germinal matrix cell -1 -CL:0000066 -epithelial cell - - -CL:0000066 -Epithelial cells -Epithelial cells -CL:0002204 -brush cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000622 -acinar cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:1000488 -cholangiocyte -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000584 -enterocyte -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000164 -enteroendocrine cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000066 -epithelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000160 -goblet cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000501 -granulosa cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000182 -hepatocyte -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0005006 -ionocyte -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000185 -myoepithelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000510 -paneth cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000162 -parietal cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000653 -podocyte -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000209 -taste receptor cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000731 -urothelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0002368 -respiratory epithelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0002370 -respiratory goblet cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000171 -pancreatic A cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000169 -type B pancreatic cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000158 -club cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0002250 -intestinal crypt stem cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000173 -pancreatic D cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0002305 -epithelial cell of distal tubule -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0002079 -pancreatic ductal cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000504 -enterochromaffin-like cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0005019 -pancreatic epsilon cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0002258 -thyroid follicular cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0002179 -foveolar cell of stomach -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000696 -PP cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000155 -peptic cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0005010 -renal intercalated cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:1000909 -kidney loop of Henle epithelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0002326 -luminal epithelial cell of mammary gland -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0002327 -mammary gland epithelial cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000682 -M cell of gut -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0002199 -oxyphil cell of parathyroid gland -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0000446 -chief cell of parathyroid gland -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0005009 -renal principal cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0002306 -epithelial cell of proximal tubule -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:1001596 -salivary gland glandular cell -1 -CL:0000066 -epithelial cell - - -CL:0000312 -Keratinocytes -Keratinocytes -CL:0002204 -brush cell -1 -CL:0000066 -epithelial cell + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000622 + + +acinar cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:1000488 + + +cholangiocyte + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000166 + + +chromaffin cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000584 + + +enterocyte + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000164 + + +enteroendocrine cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000065 + + +ependymal cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000066 + + +epithelial cell + + +0 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000160 + + +goblet cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000501 + + +granulosa cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000182 + + +hepatocyte + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0005006 + + +ionocyte + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000312 + + +keratinocyte + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000077 + + +mesothelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000185 + + +myoepithelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000165 + + +neuroendocrine cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002167 + + +olfactory epithelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000510 + + +paneth cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000162 + + +parietal cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002481 + + +peritubular myoid cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000652 + + +pinealocyte + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000653 + + +podocyte + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000209 + + +taste receptor cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000731 + + +urothelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002368 + + +respiratory epithelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002370 + + +respiratory goblet cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000171 + + +pancreatic A cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000169 + + +type B pancreatic cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000706 + + +choroid plexus epithelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000158 + + +club cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002250 + + +intestinal crypt stem cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000173 + + +pancreatic D cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002305 + + +epithelial cell of distal tubule + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002079 + + +pancreatic ductal cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000504 + + +enterochromaffin-like cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0005019 + + +pancreatic epsilon cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002258 + + +thyroid follicular cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002179 + + +foveolar cell of stomach + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000696 + + +PP cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000155 + + +peptic cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002292 + + +type I cell of carotid body + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0005010 + + +renal intercalated cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:1000909 + + +kidney loop of Henle epithelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002326 + + +luminal epithelial cell of mammary gland + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002327 + + +mammary gland epithelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000242 + + +Merkel cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000682 + + +M cell of gut + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002199 + + +oxyphil cell of parathyroid gland + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000446 + + +chief cell of parathyroid gland + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0005009 + + +renal principal cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002306 + + +epithelial cell of proximal tubule + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002062 + + +pulmonary alveolar type 1 cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002063 + + +pulmonary alveolar type 2 cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:1001596 + + +salivary gland glandular cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002140 + + +acinar cell of sebaceous gland + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0000216 + + +Sertoli cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002562 + + +hair germinal matrix cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000066 + + +Epithelial cells + + +Epithelial cells + + +CL:0002204 + + +brush cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000622 + + +acinar cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:1000488 + + +cholangiocyte + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000584 + + +enterocyte + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000164 + + +enteroendocrine cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000066 + + +epithelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000160 + + +goblet cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000501 + + +granulosa cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000182 + + +hepatocyte + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0005006 + + +ionocyte + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000185 + + +myoepithelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000510 + + +paneth cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000162 + + +parietal cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000653 + + +podocyte + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000209 + + +taste receptor cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000731 + + +urothelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0002368 + + +respiratory epithelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0002370 + + +respiratory goblet cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000171 + + +pancreatic A cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000169 + + +type B pancreatic cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000158 + + +club cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0002250 + + +intestinal crypt stem cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000173 + + +pancreatic D cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0002305 + + +epithelial cell of distal tubule + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0002079 + + +pancreatic ductal cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000504 + + +enterochromaffin-like cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0005019 + + +pancreatic epsilon cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0002258 + + +thyroid follicular cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0002179 + + +foveolar cell of stomach + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000696 + + +PP cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000155 + + +peptic cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0005010 + + +renal intercalated cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:1000909 + + +kidney loop of Henle epithelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0002326 + + +luminal epithelial cell of mammary gland + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0002327 + + +mammary gland epithelial cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000682 + + +M cell of gut + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0002199 + + +oxyphil cell of parathyroid gland + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0000446 + + +chief cell of parathyroid gland + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0005009 + + +renal principal cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0002306 + + +epithelial cell of proximal tubule + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:1001596 + + +salivary gland glandular cell + + +1 + + +CL:0000066 + + +epithelial cell + + + + +CL:0000312 + + +Keratinocytes + + +Keratinocytes + + +CL:0002204 + + +brush cell + + +1 + + +CL:0000066 + + +epithelial cell +
-

The PanglaoDB cell types seem to be more specific than the ones -present in Blueprint Encode, similar to the observation with neurons. We -should keep epithelial cell in the cases where the Blueprint Encode -annotation is Epithelial cells but not when it is -Keratinocytes.

+

+The PanglaoDB cell types seem to be more specific than the ones present +in Blueprint Encode, similar to the observation with neurons. We should +keep epithelial cell in the cases where the Blueprint Encode annotation +is Epithelial cells but not when it is +Keratinocytes. +

-

Removing anything with more than 1 LCA

-

One thing I noticed when looking at the labels that have less than -the cutoff is that most of them are from scenarios where we have -multiple LCAs. Maybe in the case where we have multiple LCAs we are -already too broad and we should just eliminate those matches from the -beginning. Here I’m looking at the total number of descendants for all -terms that show up because a term has multiple LCAs.

+

+Removing anything with more than 1 LCA +

+

+One thing I noticed when looking at the labels that have less than the +cutoff is that most of them are from scenarios where we have multiple +LCAs. Maybe in the case where we have multiple LCAs we are already too +broad and we should just eliminate those matches from the beginning. +Here I’m looking at the total number of descendants for all terms that +show up because a term has multiple LCAs. +

lca_df |> 
   dplyr::filter(total_lca > 1) |> 
   dplyr::select(cl_annotation, total_descendants) |> 
@@ -3369,119 +7479,222 @@ 

Removing anything with more than 1 LCA

- - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
cl_annotationtotal_descendants +cl_annotation + +total_descendants +
bone cell38 +bone cell + +38 +
blood cell41 +blood cell + +41 +
perivascular cell41 +perivascular cell + +41 +
stromal cell53 +stromal cell + +53 +
supporting cell61 +supporting cell + +61 +
hematopoietic precursor cell105 +hematopoietic precursor cell + +105 +
lining cell120 +lining cell + +120 +
myeloid leukocyte165 +myeloid leukocyte + +165 +
progenitor cell165 +progenitor cell + +165 +
mononuclear phagocyte169 +mononuclear phagocyte + +169 +
phagocyte (sensu Vertebrata)175 +phagocyte (sensu Vertebrata) + +175 +
contractile cell177 +contractile cell + +177 +
defensive cell199 +defensive cell + +199 +
professional antigen presenting cell212 +professional antigen presenting cell + +212 +
connective tissue cell223 +connective tissue cell + +223 +
myeloid cell247 +myeloid cell + +247 +
stuff accumulating cell266 +stuff accumulating cell + +266 +
precursor cell271 +precursor cell + +271 +
secretory cell457 +secretory cell + +457 +
mononuclear cell503 +mononuclear cell + +503 +
leukocyte540 +leukocyte + +540 +
electrically responsive cell673 +electrically responsive cell + +673 +
hematopoietic cell684 +hematopoietic cell + +684 +
eukaryotic cell2645 +eukaryotic cell + +2645 +
-

It looks like most of these terms are pretty broad and are either -much higher than the cutoff or right around the cutoff with a few -exceptions. Things like “bone cell” and “supporting cell” have few -descendants, but I would still argue these are very broad terms and not -useful.

-

I’m going to filter out any matches that show two LCA terms first and +

+It looks like most of these terms are pretty broad and are either much +higher than the cutoff or right around the cutoff with a few exceptions. +Things like “bone cell” and “supporting cell” have few descendants, but +I would still argue these are very broad terms and not useful. +

+

+I’m going to filter out any matches that show two LCA terms first and then use the cutoff to define labels we would keep. I’ll also look to see what cell types we lose when we add this extra filtering step to be -sure they are ones that we want to lose.

+sure they are ones that we want to lose. +

# remove any combinations with more than one lca
 filtered_lca_df <- lca_df |> 
   dplyr::filter(total_lca < 2)
@@ -3496,12 +7709,16 @@ 

Removing anything with more than 1 LCA

setdiff(celltypes_to_keep, updated_celltypes)
## [1] "blood cell"                   "hematopoietic precursor cell" "lining cell"                 
 ## [4] "perivascular cell"            "supporting cell"
-

It looks like I am losing a few terms I already said were not -specific and then a few other terms, like “hematopoietic precursor cell” -and “perivascular cell”. I’ll look at both of those to confirm we would -not want them.

+

+It looks like I am losing a few terms I already said were not specific +and then a few other terms, like “hematopoietic precursor cell” and +“perivascular cell”. I’ll look at both of those to confirm we would not +want them. +

-

Hematopoietic precursor cell

+

+Hematopoietic precursor cell +

print_df |> 
   dplyr::filter(cl_annotation == "hematopoietic precursor cell")
@@ -3518,135 +7735,331 @@

Hematopoietic precursor cell

-blueprint_ontology -blueprint_annotation_main -blueprint_annotation_fine -panglao_ontology -panglao_annotation -total_lca -lca -cl_annotation + +blueprint_ontology + + +blueprint_annotation_main + + +blueprint_annotation_fine + + +panglao_ontology + + +panglao_annotation + + +total_lca + + +lca + + +cl_annotation + -CL:0000050 -HSC -MEP -CL:0000037 -hematopoietic stem cell -2 -CL:0008001 -hematopoietic precursor cell - - -CL:0000050 -HSC -MEP -CL:0000038 -erythroid progenitor cell -3 -CL:0008001 -hematopoietic precursor cell - - -CL:0000037 -HSC -HSC -CL:0000038 -erythroid progenitor cell -2 -CL:0008001 -hematopoietic precursor cell - - -CL:0000837 -HSC -MPP -CL:0000037 -hematopoietic stem cell -2 -CL:0008001 -hematopoietic precursor cell - - -CL:0000837 -HSC -MPP -CL:0000038 -erythroid progenitor cell -2 -CL:0008001 -hematopoietic precursor cell - - -CL:0000051 -HSC -CLP -CL:0000037 -hematopoietic stem cell -2 -CL:0008001 -hematopoietic precursor cell - - -CL:0000051 -HSC -CLP -CL:0000038 -erythroid progenitor cell -2 -CL:0008001 -hematopoietic precursor cell - - -CL:0000557 -HSC -GMP -CL:0000037 -hematopoietic stem cell -2 -CL:0008001 -hematopoietic precursor cell - - -CL:0000557 -HSC -GMP -CL:0000038 -erythroid progenitor cell -3 -CL:0008001 -hematopoietic precursor cell - - -CL:0000049 -HSC -CMP -CL:0000037 -hematopoietic stem cell -2 -CL:0008001 -hematopoietic precursor cell - - -CL:0000049 -HSC -CMP -CL:0000038 -erythroid progenitor cell -2 -CL:0008001 -hematopoietic precursor cell + +CL:0000050 + + +HSC + + +MEP + + +CL:0000037 + + +hematopoietic stem cell + + +2 + + +CL:0008001 + + +hematopoietic precursor cell + + + + +CL:0000050 + + +HSC + + +MEP + + +CL:0000038 + + +erythroid progenitor cell + + +3 + + +CL:0008001 + + +hematopoietic precursor cell + + + + +CL:0000037 + + +HSC + + +HSC + + +CL:0000038 + + +erythroid progenitor cell + + +2 + + +CL:0008001 + + +hematopoietic precursor cell + + + + +CL:0000837 + + +HSC + + +MPP + + +CL:0000037 + + +hematopoietic stem cell + + +2 + + +CL:0008001 + + +hematopoietic precursor cell + + + + +CL:0000837 + + +HSC + + +MPP + + +CL:0000038 + + +erythroid progenitor cell + + +2 + + +CL:0008001 + + +hematopoietic precursor cell + + + + +CL:0000051 + + +HSC + + +CLP + + +CL:0000037 + + +hematopoietic stem cell + + +2 + + +CL:0008001 + + +hematopoietic precursor cell + + + + +CL:0000051 + + +HSC + + +CLP + + +CL:0000038 + + +erythroid progenitor cell + + +2 + + +CL:0008001 + + +hematopoietic precursor cell + + + + +CL:0000557 + + +HSC + + +GMP + + +CL:0000037 + + +hematopoietic stem cell + + +2 + + +CL:0008001 + + +hematopoietic precursor cell + + + + +CL:0000557 + + +HSC + + +GMP + + +CL:0000038 + + +erythroid progenitor cell + + +3 + + +CL:0008001 + + +hematopoietic precursor cell + + + + +CL:0000049 + + +HSC + + +CMP + + +CL:0000037 + + +hematopoietic stem cell + + +2 + + +CL:0008001 + + +hematopoietic precursor cell + + + + +CL:0000049 + + +HSC + + +CMP + + +CL:0000038 + + +erythroid progenitor cell + + +2 + + +CL:0008001 + + +hematopoietic precursor cell +
-

It looks like here we should be keeping these matches because both +

+It looks like here we should be keeping these matches because both references have these labels as hematopoietic stem and progenitor cells. I think in the context of pediatric cancer having this label would be -helpful, so maybe we shouldn’t remove all terms that have 2 LCAs.

-

Let’s look at what the other LCA is for an example set.

+helpful, so maybe we shouldn’t remove all terms that have 2 LCAs. +

+

+Let’s look at what the other LCA is for an example set. +

lca_df |> 
   dplyr::filter(panglao_ontology == "CL:0000037" & blueprint_ontology == "CL:0000050") |> 
   dplyr::select(blueprint_annotation_main, blueprint_annotation_fine, panglao_annotation, cl_annotation)
@@ -3660,36 +8073,64 @@

Hematopoietic precursor cell

-blueprint_annotation_main -blueprint_annotation_fine -panglao_annotation -cl_annotation + +blueprint_annotation_main + + +blueprint_annotation_fine + + +panglao_annotation + + +cl_annotation + -HSC -MEP -hematopoietic stem cell -hematopoietic precursor cell - - -HSC -MEP -hematopoietic stem cell -progenitor cell + +HSC + + +MEP + + +hematopoietic stem cell + + +hematopoietic precursor cell + + + + +HSC + + +MEP + + +hematopoietic stem cell + + +progenitor cell +
-

It looks like these terms have both -hematopoietic precursor cell and -progenitor cell as LCAs. Personally, I would keep the term -for hematopoietic precursor cell because I think it’s more -informative and specific to the type of progenitor cell.

+

+It looks like these terms have both hematopoietic precursor +cell and progenitor cell as LCAs. Personally, I +would keep the term for hematopoietic precursor cell +because I think it’s more informative and specific to the type of +progenitor cell. +

-

Perivascular cell

+

+Perivascular cell +

print_df |> 
   dplyr::filter(cl_annotation == "perivascular cell")
@@ -3706,125 +8147,282 @@

Perivascular cell

-blueprint_ontology -blueprint_annotation_main -blueprint_annotation_fine -panglao_ontology -panglao_annotation -total_lca -lca -cl_annotation + +blueprint_ontology + + +blueprint_annotation_main + + +blueprint_annotation_fine + + +panglao_ontology + + +panglao_annotation + + +total_lca + + +lca + + +cl_annotation + -CL:0000669 -Pericytes -Pericytes -CL:0000359 -vascular associated smooth muscle cell -3 -CL:4033054 -perivascular cell - - -CL:0000669 -Pericytes -Pericytes -CL:0000359 -vascular associated smooth muscle cell -3 -CL:4033054 -perivascular cell - - -CL:0000669 -Pericytes -Pericytes -CL:0000359 -vascular associated smooth muscle cell -3 -CL:4033054 -perivascular cell - - -CL:0000669 -Pericytes -Pericytes -CL:0000359 -vascular associated smooth muscle cell -3 -CL:4033054 -perivascular cell - - -CL:0000650 -Mesangial cells -Mesangial cells -CL:0000359 -vascular associated smooth muscle cell -3 -CL:4033054 -perivascular cell - - -CL:0000650 -Mesangial cells -Mesangial cells -CL:0000359 -vascular associated smooth muscle cell -3 -CL:4033054 -perivascular cell - - -CL:0000650 -Mesangial cells -Mesangial cells -CL:0000359 -vascular associated smooth muscle cell -3 -CL:4033054 -perivascular cell - - -CL:0000650 -Mesangial cells -Mesangial cells -CL:0000359 -vascular associated smooth muscle cell -3 -CL:4033054 -perivascular cell + +CL:0000669 + + +Pericytes + + +Pericytes + + +CL:0000359 + + +vascular associated smooth muscle cell + + +3 + + +CL:4033054 + + +perivascular cell + + + + +CL:0000669 + + +Pericytes + + +Pericytes + + +CL:0000359 + + +vascular associated smooth muscle cell + + +3 + + +CL:4033054 + + +perivascular cell + + + + +CL:0000669 + + +Pericytes + + +Pericytes + + +CL:0000359 + + +vascular associated smooth muscle cell + + +3 + + +CL:4033054 + + +perivascular cell + + + + +CL:0000669 + + +Pericytes + + +Pericytes + + +CL:0000359 + + +vascular associated smooth muscle cell + + +3 + + +CL:4033054 + + +perivascular cell + + + + +CL:0000650 + + +Mesangial cells + + +Mesangial cells + + +CL:0000359 + + +vascular associated smooth muscle cell + + +3 + + +CL:4033054 + + +perivascular cell + + + + +CL:0000650 + + +Mesangial cells + + +Mesangial cells + + +CL:0000359 + + +vascular associated smooth muscle cell + + +3 + + +CL:4033054 + + +perivascular cell + + + + +CL:0000650 + + +Mesangial cells + + +Mesangial cells + + +CL:0000359 + + +vascular associated smooth muscle cell + + +3 + + +CL:4033054 + + +perivascular cell + + + + +CL:0000650 + + +Mesangial cells + + +Mesangial cells + + +CL:0000359 + + +vascular associated smooth muscle cell + + +3 + + +CL:4033054 + + +perivascular cell +
-

I would remove perivascular cell, since the cell type +

+I would remove perivascular cell, since the cell type labels from PanglaoDB and Blueprint are pretty different from each -other.

+other. +

-

Similarity index

-

An alternative approach would be to calculate the similarity +

+Similarity index +

+

+An alternative approach would be to calculate the +similarity index between each set of terms and define a cutoff for which set of terms are similar. This is a value on a 0-1 scale where 0 indicates no -similarity and 1 indicates the terms are equal.

-

Although this could provide a metric that we could use to define -similar cell types, we would still have to identify the label to use -which would most likely be the LCA. Even if the similarity index is -close to 1, if the LCA term is not informative then I don’t know that we -would want to use that.

-

However, we could use this to finalize the actual pairs of terms that -we trust. For example, if the LCA for a pair is T cell we -can look at the similarity index to confirm that specific pair of terms -has high similarity.

-

Below I’ll calculate the similarity index for each set of terms and -plot the distribution. Then we will look at the values for pairs that -have an LCA that pass the total descendants threshold we set to see if -those pairs have a higher similarity index.

+similarity and 1 indicates the terms are equal. +

+

+Although this could provide a metric that we could use to define similar +cell types, we would still have to identify the label to use which would +most likely be the LCA. Even if the similarity index is close to 1, if +the LCA term is not informative then I don’t know that we would want to +use that. +

+

+However, we could use this to finalize the actual pairs of terms that we +trust. For example, if the LCA for a pair is T cell we can +look at the similarity index to confirm that specific pair of terms has +high similarity. +

+

+Below I’ll calculate the similarity index for each set of terms and plot +the distribution. Then we will look at the values for pairs that have an +LCA that pass the total descendants threshold we set to see if those +pairs have a higher similarity index. +

information_content <- ontologySimilarity::descendants_IC(cl_ont)
 
 # get similarity index for each set of terms 
@@ -3846,15 +8444,21 @@ 

Similarity index

x = "Similarity index", y = "Density" )
-

-

This looks as I expected with most of the pairs that pass the total +

+ +

+

+This looks as I expected with most of the pairs that pass the total descendants cutoff having a higher similarity index than those that do not pass. There is still some overlap though so perhaps even if a set of terms shares an LCA that passes the threshold, the actual terms being -compared may be further apart than we would like.

-

Now let’s look at the similarity index for various LCA terms. Here -each LCA term is its own plot and the vertical lines are the similarity -index for each pair of terms that results in that LCA.

+compared may be further apart than we would like. +

+

+Now let’s look at the similarity index for various LCA terms. Here each +LCA term is its own plot and the vertical lines are the similarity index +for each pair of terms that results in that LCA. +

celltypes_to_plot <- c("myeloid leukocyte", "T cell", "cell", "supporting cell", "B cell")
 
 celltypes_to_plot |> 
@@ -3877,59 +8481,84 @@ 

Similarity index

})
## [[1]]
-

+

+ +

## 
 ## [[2]]
-

+

+ +

## 
 ## [[3]]
-

+

+ +

## 
 ## [[4]]
-

+

+ +

## 
 ## [[5]]
-

-

It looks like terms that are more granular like T and B cell have -higher similarity index values than terms that are less granular which -is what we would expect. However, within terms like myeloid leukocyte -and even T cell we do see a range of values. We could dig deeper into -which pairs are resulting in which similarity index values if we wanted -to, but I think that might be a future direction if we feel like the -similarity index is something that could be useful.

+

+ +

+

+It looks like terms that are more granular like T and B cell have higher +similarity index values than terms that are less granular which is what +we would expect. However, within terms like myeloid leukocyte and even T +cell we do see a range of values. We could dig deeper into which pairs +are resulting in which similarity index values if we wanted to, but I +think that might be a future direction if we feel like the similarity +index is something that could be useful. +

-

Conclusions

-

Based on these findings, I think it might be best to create a -reference that has all possible pairs of labels between PanglaoDB and -Blueprint Encode and the resulting consensus label for those pairs. To -do this we could come up with a whitelist of LCA terms that we would be -comfortable including and all other cell types would be unknowns. I -would use the following criteria to come up with my whitelist:

+

+Conclusions +

+

+Based on these findings, I think it might be best to create a reference +that has all possible pairs of labels between PanglaoDB and Blueprint +Encode and the resulting consensus label for those pairs. To do this we +could come up with a whitelist of LCA terms that we would be comfortable +including and all other cell types would be unknowns. I would use the +following criteria to come up with my whitelist: +

    -
  • Pairs should not have more than 1 LCA, with the exception of the -matches that have the label hematopoietic precursor cell.
  • -
  • The LCA should have equal to or less than 170 total -descendants.
  • -
  • We should include the term for neuron and -epithelial cell even though they do not pass the threshold -for number of descendants. However, epithelial cell should -only be included if the Blueprint Encode name is -Epithelial cells and not -Keratinocytes.
  • -
  • Terms that are too broad should be removed. This includes: -lining cell, blood cell, -progenitor cell, bone cell, and -supporting cell
  • +
  • +Pairs should not have more than 1 LCA, with the exception of the matches +that have the label hematopoietic precursor cell. +
  • +
  • +The LCA should have equal to or less than 170 total descendants. +
  • +
  • +We should include the term for neuron and epithelial +cell even though they do not pass the threshold for number of +descendants. However, epithelial cell should only be +included if the Blueprint Encode name is Epithelial cells +and not Keratinocytes. +
  • +
  • +Terms that are too broad should be removed. This includes: lining +cell, blood cell, progenitor cell, +bone cell, and supporting cell +
-

Alternatively, rather than eliminate terms that are too broad we -could look at the similarity index for individual matches and decide on -a case by case basis if those should be allowed. Although I still think -having a term that is too broad, even if it’s a good match, is not super -informative.

+

+Alternatively, rather than eliminate terms that are too broad we could +look at the similarity index for individual matches and decide on a case +by case basis if those should be allowed. Although I still think having +a term that is too broad, even if it’s a good match, is not super +informative. +

-

Session info

+

+Session info +

sessionInfo()
## R version 4.4.2 (2024-10-31)
 ## Platform: aarch64-apple-darwin20
@@ -3984,6 +8613,48 @@ 

Session info

## [117] htmltools_0.5.8.1 lifecycle_1.0.4 httr_1.4.7 mime_0.12 ## [121] bit64_4.5.2
+ + + + + + + + + + @@ -4018,11 +8689,6 @@

Session info

- diff --git a/analyses/cell-type-consensus/references/README.md b/analyses/cell-type-consensus/references/README.md index 4d642c58e..ec7e2495f 100644 --- a/analyses/cell-type-consensus/references/README.md +++ b/analyses/cell-type-consensus/references/README.md @@ -1,32 +1,32 @@ # References -This folder contains all reference files used for generating consensus cell types. +This folder contains all reference files used for generating consensus cell types. -1. `panglao-cell-type-ontologies.tsv`: This file contains a table with all possible cell types in the reference used when running `CellAssign`. -The table includes the following columns: +1. `panglao-cell-type-ontologies.tsv`: This file contains a table with all possible cell types in the reference used when running `CellAssign`. +The table includes the following columns: | | | -| --- | --- | -| `ontology_id` | [cell type (CL) ontology identifier term](https://www.ebi.ac.uk/ols4/ontologies/cl) | +| --- | --- | +| `ontology_id` | [cell type (CL) ontology identifier term](https://www.ebi.ac.uk/ols4/ontologies/cl) | | `human_readable_value` | Label associated with the cell type ontology term | -| `panglao_cell_type` | Original name for the cell type as set by `PanglaoDB` | +| `panglao_cell_type` | Original name for the cell type as set by `PanglaoDB` | -To generate this file follow these steps: +To generate this file follow these steps: -- Download the original reference file with `00-download-panglao-ref.sh`. -- Programmatically assign ontology lables with `01-prepare-cell-type-ontologies.sh`. -- Assign any ontology values manually by finding the most representive [cell type ontology (CL) identifier term](https://www.ebi.ac.uk/ols4/ontologies/cl). +- Download the original reference file with `00-download-panglao-ref.sh`. +- Programmatically assign ontology labels with `01-prepare-cell-type-ontologies.sh`. +- Assign any ontology values manually by finding the most representative [cell type ontology (CL) identifier term](https://www.ebi.ac.uk/ols4/ontologies/cl). -There were a few terms that were assigned manually that did not have an obvious or exact match in the cell type ontology that should be noted: +There were a few terms that were assigned manually that did not have an obvious or exact match in the cell type ontology that should be noted: -- `Kidney progenitor cells` were assigned the [`CL:0000324` for metanephric mesenchyme stem cell](https://www.ebi.ac.uk/ols4/ontologies/cl/classes/http%253A%252F%252Fpurl.obolibrary.org%252Fobo%252FCL_0000324). -This term refers specifically to the stem cells that ultimately comprise the nephron, but does not account for the part of the kidney that is derived from ureteric bud cells. -- `Meningeal cells` were assigned to [`CL:0000708` for leptomeningeal cell](https://www.ebi.ac.uk/ols4/ontologies/cl/classes/http%253A%252F%252Fpurl.obolibrary.org%252Fobo%252FCL_0000708). -This was the closest term that covered general cell types found in the meninges. -- `Pancreatic progenitor cells` were assigned to [`CL:0002351` for progenitor cell of endocrine pancreas](https://www.ebi.ac.uk/ols4/ontologies/cl/classes/http%253A%252F%252Fpurl.obolibrary.org%252Fobo%252FCL_0002351). -This term only covers progenitor cells for the endocrine pancreas and does not cover the exocrine pancreas. -There were no terms that encompassed both other than `progenitor cell`. +- `Kidney progenitor cells` were assigned the [`CL:0000324` for metanephric mesenchyme stem cell](https://www.ebi.ac.uk/ols4/ontologies/cl/classes/http%253A%252F%252Fpurl.obolibrary.org%252Fobo%252FCL_0000324). +This term refers specifically to the stem cells that ultimately comprise the nephron, but does not account for the part of the kidney that is derived from ureteric bud cells. +- `Meningeal cells` were assigned to [`CL:0000708` for leptomeningeal cell](https://www.ebi.ac.uk/ols4/ontologies/cl/classes/http%253A%252F%252Fpurl.obolibrary.org%252Fobo%252FCL_0000708). +This was the closest term that covered general cell types found in the meninges. +- `Pancreatic progenitor cells` were assigned to [`CL:0002351` for progenitor cell of endocrine pancreas](https://www.ebi.ac.uk/ols4/ontologies/cl/classes/http%253A%252F%252Fpurl.obolibrary.org%252Fobo%252FCL_0002351). +This term only covers progenitor cells for the endocrine pancreas and does not cover the exocrine pancreas. +There were no terms that encompassed both other than `progenitor cell`. - `Osteoclast precursor cells` were assigned to [`CL:0000576` for monocyte](https://www.ebi.ac.uk/ols4/ontologies/cl/classes/http%253A%252F%252Fpurl.obolibrary.org%252Fobo%252FCL_0000576). -Monocytes differentiate into mononuclear osteoclasts which are then activated and become multinucleated osteoclasts. -Because monocytes are the "precursor" to the differentiated osteoclast, we chose to use this term. -- `NA` was used for `Undefined placental cells` and `Transient cells` as no clear cell type from the cell ontology was identified. +Monocytes differentiate into mononuclear osteoclasts which are then activated and become multinucleated osteoclasts. +Because monocytes are the "precursor" to the differentiated osteoclast, we chose to use this term. +- `NA` was used for `Undefined placental cells` and `Transient cells` as no clear cell type from the cell ontology was identified. diff --git a/analyses/hello-clusters/01_perform-evaluate-clustering.Rmd b/analyses/hello-clusters/01_perform-evaluate-clustering.Rmd index d7f2fbb55..80268a302 100644 --- a/analyses/hello-clusters/01_perform-evaluate-clustering.Rmd +++ b/analyses/hello-clusters/01_perform-evaluate-clustering.Rmd @@ -2,8 +2,8 @@ title: "Performing graph-based clustering with rOpenScPCA" date: "`r Sys.Date()`" author: "Data Lab" -output: - html_notebook: +output: + html_notebook: toc: yes toc_float: yes df_print: paged @@ -76,7 +76,6 @@ set.seed(2024) ## Read in and prepare data To begin, we'll read in the `SingleCellExperiment` (SCE) object. -We'll also establish a corresponding processed Seurat object from its raw counts that we'll use for some examples. ```{r read data} # Read the SCE file @@ -94,7 +93,7 @@ pca_matrix <- reducedDim(sce, "PCA") ## Perform clustering -This section will show how to perform clustering with the function `rOpenScPCA::calculate_clusters()`. +This section will show how to perform clustering with the function `rOpenScPCA::calculate_clusters()`. This function takes a PCA matrix with rownames representing unique cell ids (e.g., barcodes) as its primary argument. By default it will calculate clusters using the following parameters: @@ -152,7 +151,7 @@ cluster_results_df <- rOpenScPCA::calculate_clusters( ## Calculate QC metrics on clusters -This section demonstrates how to use several functions for evaluating cluster quality and reliability. +This section demonstrates how to use several functions for evaluating cluster quality and reliability. It's important to note that a full evaluation of clustering results would compare these metrics across a set of clustering results, with the aim of identifying an optimal parameterization. All functions presented in this section take the following required arguments: @@ -236,7 +235,7 @@ ggplot(purity_results) + ### Cluster stability -Another approach to exploring cluster quality is how stable the clusters themselves are using bootstrapping. +Another approach to exploring cluster quality is how stable the clusters themselves are using bootstrapping. Given a set of original clusters, we can compare the bootstrapped cluster identities to original ones using the Adjusted Rand Index (ARI), which measures the similarity of two data clusterings. ARI ranges from -1 to 1, where: @@ -276,7 +275,7 @@ ggplot(stability_results) + #### Using non-default clustering parameters -When calculating bootstrap clusters, `rOpenScPCA::calculate_stability()` uses `rOpenScPCA::calculate_clusters()` with default parameters. +When calculating bootstrap clusters, `rOpenScPCA::calculate_stability()` uses `rOpenScPCA::calculate_clusters()` with default parameters. If your original clusters were not calculated with these defaults, you should pass those customized values into this function as well to ensure a fair comparison between your original clusters and the bootstrap clusters. @@ -331,7 +330,6 @@ If you are analyzing your data with a Seurat pipeline that includes calculating To demonstrate this, we'll convert our SCE object to a Seurat using the function `rOpenScPCA::sce_to_seurat()`. Then, we'll use a simple Seurat pipeline to obtain clusters. - ```{r sce to seurat, message = FALSE} # Convert the SCE to a Seurat object using rOpenScPCA @@ -380,8 +378,8 @@ We do not recommend using `rOpenScPCA::calculate_stability()` on Seurat clusters ### Evaluating ScPCA clusters -ScPCA cell metadata already contains a column called `cluster` with results from an automated clustering. -These clusters were calculated using `bluster`, the same tool that `rOpenScPCA` uses. +ScPCA cell metadata already contains a column called `cluster` with results from an automated clustering. +These clusters were calculated using `bluster`, the same tool that `rOpenScPCA` uses. The specifications used for this clustering are stored in the SCE object's metadata, as follows; note that all other clustering parameters were left at their default values. * `metadata(sce)$cluster_algorithm`: The clustering algorithm used @@ -446,7 +444,7 @@ scpca_stability_df <- rOpenScPCA::calculate_stability( ``` -## Saving clustering results +## Saving clustering results Results can either be directly exported as a TSV file (e.g., with `readr::write_tsv()`), or you can add the results into your SCE or Seurat object. The subsequent examples will demonstrate saving the cluster assignments stored in `cluster_results_df$cluster` to an SCE and a Seurat object. @@ -456,7 +454,7 @@ Objects from the ScPCA Portal already contain a column called `cluster` with res These automatic clusters were not evaluated, and their parameters were not optimized for any given library. To avoid ambiguity between the existing and new clustering results, we'll name the new column `ropenscpca_cluster`. -### Saving results to an SCE object +### Saving results to an SCE object We can add columns to an SCE object's `colData` table by directly creating a column in the object with `$`. Before we do so, we'll confirm that the clusters are in the same order as the SCE object by comparing cell ids: @@ -473,7 +471,7 @@ all.equal( sce$ropenscpca_cluster <- cluster_results_df$cluster ``` -### Saving results to a Seurat object +### Saving results to a Seurat object We can add columns to an Seurat object's cell metadata table by directly creating a column in the object with `$` (note that you can also use the Seurat function `AddMetaData()`). diff --git a/analyses/hello-clusters/01_perform-evaluate-clustering.nb.html b/analyses/hello-clusters/01_perform-evaluate-clustering.nb.html index 702a46da2..bc5d1fd95 100644 --- a/analyses/hello-clusters/01_perform-evaluate-clustering.nb.html +++ b/analyses/hello-clusters/01_perform-evaluate-clustering.nb.html @@ -11,7 +11,7 @@ - + Performing graph-based clustering with rOpenScPCA @@ -2901,7 +2901,7 @@

Performing graph-based clustering with rOpenScPCA

Data Lab

-

2024-12-17

+

2024-12-20

@@ -3005,8 +3005,7 @@

Set the random seed

Read in and prepare data

To begin, we’ll read in the SingleCellExperiment (SCE) -object. We’ll also establish a corresponding processed Seurat object -from its raw counts that we’ll use for some examples.

+object.

@@ -3062,7 +3061,7 @@

Clustering with default parameters

@@ -3175,7 +3174,7 @@

Silhouette width

@@ -3191,7 +3190,7 @@

Silhouette width

labs(x = "Cluster", y = "Silhouette width")
-

+

@@ -3228,7 +3227,7 @@

Neighborhood purity

@@ -3244,7 +3243,7 @@

Neighborhood purity

labs(x = "Cluster", y = "Neighborhood purity")
-

+

@@ -3286,7 +3285,7 @@

Cluster stability

@@ -3302,7 +3301,7 @@

Cluster stability

labs(x = "Adjusted rand index across bootstrap replicates") -

+

@@ -3360,7 +3359,7 @@

Working with objects directly

@@ -3385,8 +3384,7 @@

Evaluating Seurat clusters

them.

To demonstrate this, we’ll convert our SCE object to a Seurat using the function rOpenScPCA::sce_to_seurat(). Then, we’ll use a -simple Seurat pipeline to obtain clusters. -

+simple Seurat pipeline to obtain clusters.

@@ -3406,24 +3404,31 @@

Evaluating Seurat clusters

FindNeighbors() |> FindClusters() - + +
Warning in irlba(A = t(x = object), nv = npcs, ...): You're computing too large
+a percentage of total singular values, use a standard svd instead.
+ + +
Warning: Number of dimensions changing from 10 to 50
+ +
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
 
-Number of nodes: 2623
-Number of edges: 78853
+Number of nodes: 100
+Number of edges: 4142
 
 Running Louvain algorithm...
-Maximum modularity in 10 random starts: 0.8478
-Number of communities: 13
+Maximum modularity in 10 random starts: 0.2147
+Number of communities: 2
 Elapsed time: 0 seconds
seurat_obj
- +
An object of class Seurat 
-145743 features across 2623 samples within 3 assays 
-Active assay: SCT (25105 features, 3000 variable features)
+126242 features across 100 samples within 3 assays 
+Active assay: SCT (5604 features, 3000 variable features)
  3 layers present: counts, data, scale.data
  2 other assays present: RNA, spliced
  2 dimensional reductions calculated: pca, umap
@@ -3446,7 +3451,7 @@

Evaluating Seurat clusters

@@ -3538,7 +3543,7 @@

Evaluating ScPCA clusters

@@ -3771,7 +3776,7 @@

Session Info

-
LS0tCnRpdGxlOiAiUGVyZm9ybWluZyBncmFwaC1iYXNlZCBjbHVzdGVyaW5nIHdpdGggck9wZW5TY1BDQSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgphdXRob3I6ICJEYXRhIExhYiIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgZGZfcHJpbnQ6IHBhZ2VkCi0tLQoKIyMgSW50cm9kdWN0aW9uCgpUaGlzIG5vdGVib29rIHByb3ZpZGVzIGV4YW1wbGVzIG9mIGhvdyB0byB1c2UgZnVuY3Rpb25zIGluIGByT3BlblNjUENBYCB0aGF0OgoKKiBQZXJmb3JtIGNsdXN0ZXJpbmcKKiBDYWxjdWxhdGUgUUMgbWV0cmljcyBvbiBjbHVzdGVycywgaW5jbHVkaW5nOgogICogU2lsaG91ZXR0ZSB3aWR0aAogICogTmVpZ2hib3Job29kIHB1cml0eQogICogQ2x1c3RlciBzdGFiaWxpdHksIGFzIG1lYXN1cmVkIHdpdGggdGhlIEFkanVzdGVkIFJhbmQgSW5kZXgKKiBDYWxjdWxhdGUgUUMgbWV0cmljcyBvbiBjbHVzdGVycyBvYnRhaW5lZCB3aXRoIG90aGVyIHRvb2xzLCBzdWNoIGFzIGBTZXVyYXRgCiogU2F2ZSBjbHVzdGVyaW5nIHJlc3VsdHMgdG8gYW4gU0NFIG9yIGBTZXVyYXRgCgpXaGlsZSB0aGlzIG5vdGVib29rIGRlbW9uc3RyYXRlcyBob3cgdG8gdXNlIGluZGl2aWR1YWwgZnVuY3Rpb25zIHRoYXQgY2FsY3VsYXRlIGhlbHBmdWwgbWV0cmljcyBmb3IgZXZhbHVhdGluZyBjbHVzdGVyaW5nIHJlc3VsdHMsIGEgZnVsbCBldmFsdWF0aW9uIHdvdWxkIGNvbXBhcmUgdGhlc2UgbWV0cmljcyBhY3Jvc3MgZGlmZmVyZW50IGNsdXN0ZXJpbmdzIGZyb20gZGlmZmVyZW50IHBhcmFtZXRlcml6YXRpb25zLgoKVGhpcyBub3RlYm9vayB3aWxsIHVzZSB0aGUgc2FtcGxlIGBTQ1BDUzAwMDAwMWAgZnJvbSBwcm9qZWN0IGBTQ1BDUDAwMDAwMWAsIHdoaWNoIGlzIGFzc3VtZWQgcHJlc2VudCBpbiB0aGUgYE9wZW5TY1BDQS1hbmFseXNpcy9kYXRhL2N1cnJlbnQvU0NQQ1AwMDAwMDFgIGRpcmVjdG9yeSwgZm9yIGFsbCBleGFtcGxlcy4KUGxlYXNlIFtzZWUgdGhpcyBkb2N1bWVudGF0aW9uXShodHRwczovL29wZW5zY3BjYS5yZWFkdGhlZG9jcy5pby9lbi9sYXRlc3QvZ2V0dGluZy1zdGFydGVkL2FjY2Vzc2luZy1yZXNvdXJjZXMvZ2V0dGluZy1hY2Nlc3MtdG8tZGF0YS8pIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IG9idGFpbmluZyBTY1BDQSBkYXRhLgoKIyMgU2V0dXAKCiMjIyBQYWNrYWdlcwoKCmBgYHtyIHBhY2thZ2VzfQpsaWJyYXJ5KHJPcGVuU2NQQ0EpCgpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMoewogIGxpYnJhcnkoU2luZ2xlQ2VsbEV4cGVyaW1lbnQpCiAgbGlicmFyeShTZXVyYXQpCiAgbGlicmFyeShkcGx5cikKICBsaWJyYXJ5KGdncGxvdDIpCn0pCgojIFNldCBnZ3Bsb3QgdGhlbWUgZm9yIHBsb3RzCnRoZW1lX3NldCh0aGVtZV9idygpKQpgYGAKCgojIyMgUGF0aHMKCmBgYHtyIGJhc2UgcGF0aHN9CiMgVGhlIGJhc2UgcGF0aCBmb3IgdGhlIE9wZW5TY1BDQSByZXBvc2l0b3J5CnJlcG9zaXRvcnlfYmFzZSA8LSBycHJvanJvb3Q6OmZpbmRfcm9vdChycHJvanJvb3Q6OmlzX2dpdF9yb290KQoKIyBUaGUgY3VycmVudCBkYXRhIGRpcmVjdG9yeSwgZm91bmQgd2l0aGluIHRoZSByZXBvc2l0b3J5IGJhc2UgZGlyZWN0b3J5CmRhdGFfZGlyIDwtIGZpbGUucGF0aChyZXBvc2l0b3J5X2Jhc2UsICJkYXRhIiwgImN1cnJlbnQiKQoKIyBUaGUgcGF0aCB0byB0aGlzIG1vZHVsZQptb2R1bGVfYmFzZSA8LSBmaWxlLnBhdGgocmVwb3NpdG9yeV9iYXNlLCAiYW5hbHlzZXMiLCAiaGVsbG8tY2x1c3RlcnMiKQpgYGAKCmBgYHtyIGlucHV0IGZpbGUgcGF0aH0KIyBQYXRoIHRvIHByb2Nlc3NlZCBTQ0UgZmlsZSBmb3Igc2FtcGxlIFNDUENTMDAwMDAxCmlucHV0X3NjZV9maWxlIDwtIGZpbGUucGF0aChkYXRhX2RpciwgIlNDUENQMDAwMDAxIiwgIlNDUENTMDAwMDAxIiwgIlNDUENMMDAwMDAxX3Byb2Nlc3NlZC5yZHMiKQpgYGAKCgojIyMgU2V0IHRoZSByYW5kb20gc2VlZAoKQmVjYXVzZSBjbHVzdGVyaW5nIGludm9sdmVzIHJhbmRvbSBzYW1wbGluZywgaXQgaXMgaW1wb3J0YW50IHRvIHNldCB0aGUgcmFuZG9tIHNlZWQgYXQgdGhlIHRvcCBvZiB5b3VyIGFuYWx5c2lzIHNjcmlwdCBvciBub3RlYm9vayB0byBlbnN1cmUgcmVwcm9kdWNpYmlsaXR5LgoKYGBge3Igc2V0IHNlZWR9CnNldC5zZWVkKDIwMjQpCmBgYAoKIyMgUmVhZCBpbiBhbmQgcHJlcGFyZSBkYXRhCgpUbyBiZWdpbiwgd2UnbGwgcmVhZCBpbiB0aGUgYFNpbmdsZUNlbGxFeHBlcmltZW50YCAoU0NFKSBvYmplY3QuCldlJ2xsIGFsc28gZXN0YWJsaXNoIGEgY29ycmVzcG9uZGluZyBwcm9jZXNzZWQgU2V1cmF0IG9iamVjdCBmcm9tIGl0cyByYXcgY291bnRzIHRoYXQgd2UnbGwgdXNlIGZvciBzb21lIGV4YW1wbGVzLgoKYGBge3IgcmVhZCBkYXRhfQojIFJlYWQgdGhlIFNDRSBmaWxlCnNjZSA8LSByZWFkUkRTKGlucHV0X3NjZV9maWxlKQpgYGAKCkZvciB0aGUgaW5pdGlhbCBjbHVzdGVyIGNhbGN1bGF0aW9ucyBhbmQgZXZhbHVhdGlvbnMsIHdlIHdpbGwgdXNlIHRoZSBQQ0EgbWF0cml4IGV4dHJhY3RlZCBmcm9tIHRoZSBTQ0Ugb2JqZWN0LgpJdCdzIGFsc28gcG9zc2libGUgdG8gdXNlIGFuIFNDRSBvYmplY3Qgb3IgYSBTZXVyYXQgb2JqZWN0IGRpcmVjdGx5LCB3aGljaCB3ZSB3aWxsIGRlbW9uc3RyYXRlIGxhdGVyLgoKCmBgYHtyIGV4dHJhY3QgcGNhIGRhdGF9CiMgRXh0cmFjdCB0aGUgUENBIG1hdHJpeCBmcm9tIGFuIFNDRSBvYmplY3QKcGNhX21hdHJpeCA8LSByZWR1Y2VkRGltKHNjZSwgIlBDQSIpCmBgYAoKIyMgUGVyZm9ybSBjbHVzdGVyaW5nCgpUaGlzIHNlY3Rpb24gd2lsbCBzaG93IGhvdyB0byBwZXJmb3JtIGNsdXN0ZXJpbmcgd2l0aCB0aGUgZnVuY3Rpb24gYHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9jbHVzdGVycygpYC4gCgpUaGlzIGZ1bmN0aW9uIHRha2VzIGEgUENBIG1hdHJpeCB3aXRoIHJvd25hbWVzIHJlcHJlc2VudGluZyB1bmlxdWUgY2VsbCBpZHMgKGUuZy4sIGJhcmNvZGVzKSBhcyBpdHMgcHJpbWFyeSBhcmd1bWVudC4KQnkgZGVmYXVsdCBpdCB3aWxsIGNhbGN1bGF0ZSBjbHVzdGVycyB1c2luZyB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6CgoqIExvdXZhaW4gYWxnb3JpdGhtCiogSmFjY2FyZCB3ZWlnaHRpbmcKKiAxMCBuZWFyZXN0IG5laWdoYm9ycwoqIEEgcmVzb2x1dGlvbiBwYXJhbWV0ZXIgb2YgMQoKVGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiBhIHRhYmxlIHdpdGggdGhlIGZvbGxvd2luZyBjb2x1bW5zOgoKKiBgY2VsbF9pZGA6IFVuaXF1ZSBjZWxsIGlkZW50aWZpZXJzLCBvYnRhaW5lZCBmcm9tIHRoZSBQQ0EgbWF0cml4J3Mgcm93IG5hbWVzCiogYGNsdXN0ZXJgOiBBIGZhY3RvciBjb2x1bW4gd2l0aCB0aGUgY2x1c3RlciBpZGVudGl0aWVzCiogVGhlcmUgd2lsbCBiZSBvbmUgY29sdW1uIGZvciBlYWNoIGNsdXN0ZXJpbmcgcGFyYW1ldGVyIHVzZWQKCgojIyMgQ2x1c3RlcmluZyB3aXRoIGRlZmF1bHQgcGFyYW1ldGVycwoKYGBge3IgY2x1c3RlciBzY2V9CiMgQ2FsY3VsYXRlIGNsdXN0ZXJzIHdpdGggZGVmYXVsdCBwYXJhbWV0ZXJzCmNsdXN0ZXJfcmVzdWx0c19kZiA8LSByT3BlblNjUENBOjpjYWxjdWxhdGVfY2x1c3RlcnMocGNhX21hdHJpeCkKCiMgUHJpbnQgdGhlIGZpcnN0IHJvd3Mgb2YgdGhlIHJlc3VsdGluZyB0YWJsZQpoZWFkKGNsdXN0ZXJfcmVzdWx0c19kZikKYGBgCgojIyMgQ2x1c3RlcmluZyB3aXRoIG5vbi1kZWZhdWx0IHBhcmFtZXRlcnMKClBhcmFtZXRlcnMgdXNlZCBmb3IgY2x1c3RlcmluZyBjYW4gYmUgY3VzdG9taXplZCB3aXRoIHRoZXNlIGFyZ3VtZW50czoKCiogVGhlIGBhbGdvcml0aG1gIGNhbiBiZSBvbmUgb2Y6CiAgKiBgbG91dmFpbmAsIGB3YWxrdHJhcGAsIG9yIGBsZWlkZW5gCiogVGhlIGB3ZWlnaHRpbmdgIGNhbiBiZSBvbmUgb2Y6CiAgKiBgamFjY2FyZGAsIGByYW5rYCwgb3IgYG51bWJlcmAKKiBUaGUgbmVhcmVzdCBuZWlnaGJvcnMgcGFyYW1ldGVyIGNhbiBiZSBjdXN0b21pemVkIHdpdGggdGhlIGBubmAgYXJndW1lbnQKKiBUaGUgcmVzb2x1dGlvbiBwYXJhbWV0ZXIgY2FuIGJlIGN1c3RvbWl6ZWQgd2l0aCB0aGUgYHJlc29sdXRpb25gIGFyZ3VtZW50CiAgKiBUaGlzIHBhcmFtZXRlciBpcyBvbmx5IHVzZWQgYnkgTG91dmFpbiBhbmQgTGVpZGVuIGFsZ29yaXRobXMKKiBJZiB0aGUgTGVpZGVuIGFsZ29yaXRobSBpcyB1c2VkLCBpdHMgZGVmYXVsdCBvYmplY3RpdmUgZnVuY3Rpb24gcGFyYW1ldGVyIHdpbGwgYmUgYENQTWAsIGJ1dCB5b3UgY2FuIGFsc28gc2V0ICBgb2JqZWN0aXZlX2Z1bmN0aW9uID0gIm1vZHVsYXJpdHkiYCBpbnN0ZWFkLgoqIFlvdSBjYW4gcHJvdmlkZSBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgYXMgYSBsaXN0IHRvIHRoZSBgY2x1c3Rlcl9hcmdzYCBhcmd1bWVudC4KICAqIFBsZWFzZSByZWZlciB0byB0aGUgW2BpZ3JhcGhgIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vaWdyYXBoLm9yZy9yL2h0bWwvbGF0ZXN0KSB0byBsZWFybiBtb3JlIGFib3V0IHdoYXQgYWRkaXRpb25hbCBwYXJhbWV0ZXJzIGNhbiBiZSBwcm92aWRlZCB0byBlYWNoIGNsdXN0ZXJpbmcgYWxnb3JpdGhtLgogICogTm90ZSB0aGF0IGBjbHVzdGVyX2FyZ3NgIG9ubHkgYWNjZXB0cyBzaW5nbGUtbGVuZ3RoIGFyZ3VtZW50cyAobm8gdmVjdG9ycyBvciBsaXN0cykuCgpGb3IgZXhhbXBsZToKCmBgYHtyIGNsdXN0ZXIgc2NlIG5vbmRlZmF1bHR9CiMgQ2FsY3VsYXRlIGNsdXN0ZXJzIHdpdGggbm9uLWRlZmF1bHQgcGFyYW1ldGVycwpjbHVzdGVyX3Jlc3VsdHNfZGYgPC0gck9wZW5TY1BDQTo6Y2FsY3VsYXRlX2NsdXN0ZXJzKAogIHBjYV9tYXRyaXgsCiAgYWxnb3JpdGhtID0gImxlaWRlbiIsCiAgbm4gPSAxNSwKICBvYmplY3RpdmVfZnVuY3Rpb24gPSAibW9kdWxhcml0eSIKKQpgYGAKCgojIyBDYWxjdWxhdGUgUUMgbWV0cmljcyBvbiBjbHVzdGVycwoKVGhpcyBzZWN0aW9uIGRlbW9uc3RyYXRlcyBob3cgdG8gdXNlIHNldmVyYWwgZnVuY3Rpb25zIGZvciBldmFsdWF0aW5nIGNsdXN0ZXIgcXVhbGl0eSBhbmQgcmVsaWFiaWxpdHkuIApJdCdzIGltcG9ydGFudCB0byBub3RlIHRoYXQgYSBmdWxsIGV2YWx1YXRpb24gb2YgY2x1c3RlcmluZyByZXN1bHRzIHdvdWxkIGNvbXBhcmUgdGhlc2UgbWV0cmljcyBhY3Jvc3MgYSBzZXQgb2YgY2x1c3RlcmluZyByZXN1bHRzLCB3aXRoIHRoZSBhaW0gb2YgaWRlbnRpZnlpbmcgYW4gb3B0aW1hbCBwYXJhbWV0ZXJpemF0aW9uLgoKQWxsIGZ1bmN0aW9ucyBwcmVzZW50ZWQgaW4gdGhpcyBzZWN0aW9uIHRha2UgdGhlIGZvbGxvd2luZyByZXF1aXJlZCBhcmd1bWVudHM6CgoqIEEgUENBIG1hdHJpeCB3aXRoIHJvdyBuYW1lcyByZXByZXNlbnRpbmcgdW5pcXVlIGNlbGwgaWRzIChlLmcuLCBiYXJjb2RlcykKKiBBIGRhdGEgZnJhbWUgd2l0aCwgYXQgbGVhc3QsIGNvbHVtbnMgcmVwcmVzZW50aW5nIHVuaXF1ZSBjZWxsIGlkcyBhbmQgY2x1c3RlciBhc3NpZ25tZW50cwogICogQnkgZGVmYXVsdCwgdGhlc2UgY29sdW1ucyBzaG91bGQgYmUgbmFtZWQgYGNlbGxfaWRgIGFuZCBgY2x1c3RlcmAsIHJlc3BlY3RpdmVseSwgbWF0Y2hpbmcgdGhlIG91dHB1dCBvZiBgck9wZW5TY1BDQTo6Y2FsY3VsYXRlX2NsdXN0ZXJzKClgCiAgKiBZb3UgY2FuIG92ZXJyaWRlIHRoZXNlIGRlZmF1bHRzIHVzaW5nIHRoZSBhcmd1bWVudHMgYGNlbGxfaWRfY29sYCBhbmQgYGNsdXN0ZXJfY29sYAoKIyMjIFNpbGhvdWV0dGUgd2lkdGgKClNpbGhvdWV0dGUgd2lkdGggaXMgYSBjb21tb24gbWV0cmljIHRoYXQgbWVhc3VyZXMgaG93IHdlbGwgc2VwYXJhdGVkIGNsdXN0ZXJzIGFyZSBieSwgZm9yIGVhY2ggY2VsbCwgY29tcGFyaW5nIHRoZSBhdmVyYWdlIGRpc3RhbmNlIHRvIGFsbCBjZWxscyBpbiB0aGUgc2FtZSBjbHVzdGVyLCBhbmQgYWxsIGNlbGxzIGluIG90aGVyIGNsdXN0ZXJzLgpUaGlzIHZhbHVlIHJhbmdlcyBmcm9tIC0xIHRvIDEuCkNlbGxzIGluIHdlbGwtc2VwYXJhdGVkIGNsdXN0ZXJzIHNob3VsZCBoYXZlIGhpZ2ggc2lsaG91ZXR0ZSB2YWx1ZXMgY2xvc2VyIHRvIDEuCllvdSBjYW4gcmVhZCBtb3JlIGFib3V0IHNpbGhvdWV0dGUgd2lkdGggcHVyaXR5IGZyb20gdGhlIFtfT3JjaGVzdHJhdGluZyBTaW5nbGUgQ2VsbCBBbmFseXNpcyB3aXRoIEJpb2NvbmR1Y3Rvcl8gYm9va10oaHR0cHM6Ly9iaW9jb25kdWN0b3Iub3JnL2Jvb2tzLzMuMTkvT1NDQS5hZHZhbmNlZC9jbHVzdGVyaW5nLXJlZHV4Lmh0bWwjc2lsaG91ZXR0ZS13aWR0aCkuCgpXZSdsbCB1c2UgdGhlIGZ1bmN0aW9uIGByT3BlblNjUENBOjpjYWxjdWxhdGVfc2lsaG91ZXR0ZSgpYCB0byBjYWxjdWxhdGUgdGhlIHNpbGhvdWV0dGUgd2lkdGguCgpUaGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIHRoZSBpbnB1dHRlZCBkYXRhIGZyYW1lIHdpdGggdHdvIGFkZGl0aW9uYWwgY29sdW1uczoKCiogYHNpbGhvdWV0dGVfd2lkdGhgOiBUaGUgY2FsY3VsYXRlZCBzaWxob3VldHRlIHdpZHRoIGZvciB0aGUgY2VsbAoqIGBzaWxob3VldHRlX290aGVyYDogVGhlIGNsb3NldCBjbHVzdGVyIHRvIHRoZSBjZWxsIGJlc2lkZXMgdGhlIGNsdXN0ZXIgdG8gd2hpY2ggaXQgYmVsb25ncywgYXMgdXNlZCBpbiB0aGUgc2lsaG91ZXR0ZSB3aWR0aCBjYWxjdWxhdGlvbgoKCmBgYHtyIHNpbGhvdWV0dGV9CiMgY2FsY3VsYXRlIHRoZSBzaWxob3VldHRlIHdpZHRoIGZvciBlYWNoIGNlbGwKc2lsaG91ZXR0ZV9yZXN1bHRzIDwtIHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9zaWxob3VldHRlKAogIHBjYV9tYXRyaXgsCiAgY2x1c3Rlcl9yZXN1bHRzX2RmCikKCiMgUHJpbnQgdGhlIGZpcnN0IHJvd3Mgb2YgdGhlIHJlc3VsdGluZyB0YWJsZQpoZWFkKHNpbGhvdWV0dGVfcmVzdWx0cykKYGBgCgoKV2UgY2FuIHZpc3VhbGl6ZSB0aGVzZSByZXN1bHRzIGJ5IHBsb3R0aW5nIHNpbGhvdWV0dGUgd2lkdGggYWNyb3NzIGNsdXN0ZXJzIGFzIHZpb2xpbiBwbG90cywgZm9yIGV4YW1wbGU6CgpgYGB7ciB2aW9saW4gc2lsaG91ZXR0ZX0KZ2dwbG90KHNpbGhvdWV0dGVfcmVzdWx0cykgKwogIGFlcyh4ID0gY2x1c3RlciwgeSA9IHNpbGhvdWV0dGVfd2lkdGgpICsKICBnZW9tX3Zpb2xpbihmaWxsID0gImRhcmttYWdlbnRhIikgKwogIGxhYnMoeCA9ICJDbHVzdGVyIiwgeSA9ICJTaWxob3VldHRlIHdpZHRoIikKYGBgCgojIyMgTmVpZ2hib3Job29kIHB1cml0eQoKTmVpZ2hib3Job29kIHB1cml0eSBpcyBkZWZpbmVkLCBmb3IgZWFjaCBjZWxsLCBhcyB0aGUgcHJvcG9ydGlvbiBvZiBuZWlnaGJvcmluZyBjZWxscyB0aGF0IGFyZSBhc3NpZ25lZCB0byB0aGUgc2FtZSBjbHVzdGVyLgpUaGlzIHZhbHVlIHJhbmdlcyBmcm9tIDAgdG8gMS4KQ2VsbHMgaW4gd2VsbC1zZXBhcmF0ZWQgY2x1c3RlcnMgc2hvdWxkIGhhdmUgaGlnaCBwdXJpdHkgdmFsdWVzIGNsb3NlciB0byAxLCBzaW5jZSB0aGVyZSBzaG91bGQgYmUgbWluaW1hbCBvdmVybGFwIGJldHdlZW4gbWVtYmVyIGFuZCBuZWlnaGJvcmluZyBjZWxscy4KWW91IGNhbiByZWFkIG1vcmUgYWJvdXQgbmVpZ2hib3Job29kIHB1cml0eSBmcm9tIHRoZSBbX09yY2hlc3RyYXRpbmcgU2luZ2xlIENlbGwgQW5hbHlzaXMgd2l0aCBCaW9jb25kdWN0b3JfIGJvb2tdKGh0dHBzOi8vYmlvY29uZHVjdG9yLm9yZy9ib29rcy8zLjE5L09TQ0EuYWR2YW5jZWQvY2x1c3RlcmluZy1yZWR1eC5odG1sI2NsdXN0ZXItcHVyaXR5KS4KCldlJ2xsIHVzZSB0aGUgZnVuY3Rpb24gYHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9wdXJpdHkoKWAgdG8gY2FsY3VsYXRlIHRoZSBuZWlnaGJvcmhvb2QgcHVyaXR5LgoKVGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiB0aGUgaW5wdXR0ZWQgZGF0YSBmcmFtZSB3aXRoIHR3byBhZGRpdGlvbmFsIGNvbHVtbnM6CgoqIGBwdXJpdHlgOiBUaGUgbmVpZ2hib3Job29kIHB1cml0eSBmb3IgdGhlIGNlbGwKKiBgbWF4aW11bV9uZWlnaGJvcmA6IFRoZSBjbHVzdGVyIHdpdGggdGhlIGhpZ2hlc3QgcHJvcG9ydGlvbiBvZiBvYnNlcnZhdGlvbnMgbmVpZ2hib3JpbmcgdGhlIGNlbGwKCgpgYGB7ciBwdXJpdHl9CiMgY2FsY3VsYXRlIHRoZSBuZWlnaGJvcmhvb2QgcHVyaXR5IGZvciBlYWNoIGNlbGwKcHVyaXR5X3Jlc3VsdHMgPC0gck9wZW5TY1BDQTo6Y2FsY3VsYXRlX3B1cml0eSgKICBwY2FfbWF0cml4LAogIGNsdXN0ZXJfcmVzdWx0c19kZgopCgojIFByaW50IHRoZSBmaXJzdCByb3dzIG9mIHRoZSByZXN1bHRpbmcgdGFibGUKaGVhZChwdXJpdHlfcmVzdWx0cykKYGBgCgoKV2UgY2FuIHZpc3VhbGl6ZSB0aGVzZSByZXN1bHRzIGJ5IHBsb3R0aW5nIHB1cml0eSBjbHVzdGVycyBhcyB2aW9saW4gcGxvdHMsIGZvciBleGFtcGxlOgoKYGBge3IgdmlvbGluIHB1cml0eX0KZ2dwbG90KHB1cml0eV9yZXN1bHRzKSArCiAgYWVzKHggPSBjbHVzdGVyLCB5ID0gcHVyaXR5KSArCiAgZ2VvbV92aW9saW4oZmlsbCA9ICJkYXJrb2xpdmVncmVlbjMiKSArCiAgbGFicyh4ID0gIkNsdXN0ZXIiLCB5ID0gIk5laWdoYm9yaG9vZCBwdXJpdHkiKQpgYGAKCiMjIyBDbHVzdGVyIHN0YWJpbGl0eQoKQW5vdGhlciBhcHByb2FjaCB0byBleHBsb3JpbmcgY2x1c3RlciBxdWFsaXR5IGlzIGhvdyBzdGFibGUgdGhlIGNsdXN0ZXJzIHRoZW1zZWx2ZXMgYXJlIHVzaW5nIGJvb3RzdHJhcHBpbmcuIApHaXZlbiBhIHNldCBvZiBvcmlnaW5hbCBjbHVzdGVycywgd2UgY2FuIGNvbXBhcmUgdGhlIGJvb3RzdHJhcHBlZCBjbHVzdGVyIGlkZW50aXRpZXMgdG8gb3JpZ2luYWwgb25lcyB1c2luZyB0aGUgQWRqdXN0ZWQgUmFuZCBJbmRleCAoQVJJKSwgd2hpY2ggbWVhc3VyZXMgdGhlIHNpbWlsYXJpdHkgb2YgdHdvIGRhdGEgY2x1c3RlcmluZ3MuCkFSSSByYW5nZXMgZnJvbSAtMSB0byAxLCB3aGVyZToKCiogQSB2YWx1ZSBvZiAxIGluZGljYXRlcyB0aGV5IGFyZSBjb21wbGV0ZWx5IG92ZXJsYXBwaW5nCiogQSB2YWx1ZSBvZiAtMSBpbmRpY2F0ZXMgdGhleSBhcmUgY29tcGxldGVseSBkaXN0aW5jdAoqIEEgdmFsdWUgb2YgMCBpbmRpY2F0ZXMgYSByYW5kb20gcmVsYXRpb25zaGlwCgpXZSBleHBlY3QgdGhhdCBoaWdobHkgc3RhYmxlIGNsdXN0ZXJpbmdzIGhhdmUgQVJJIHZhbHVlcyBjbG9zZXIgdG8gMSBhY3Jvc3MgYSBzZXQgb2YgYm9vdHN0cmFwIHJlcGxpY2F0ZXMuCgpZb3UgY2FuIHJlYWQgbW9yZSBhYm91dCB0aGUgQWRqdXN0ZWQgUmFuZCBJbmRleCBmcm9tIHRoZSBbX09yY2hlc3RyYXRpbmcgU2luZ2xlIENlbGwgQW5hbHlzaXMgd2l0aCBCaW9jb25kdWN0b3JfIGJvb2tdKGh0dHBzOi8vYmlvY29uZHVjdG9yLm9yZy9ib29rcy9yZWxlYXNlL09TQ0EuYWR2YW5jZWQvY2x1c3RlcmluZy1yZWR1eC5odG1sI2FkanVzdGVkLXJhbmQtaW5kZXgpLgoKV2UnbGwgdXNlIHRoZSBmdW5jdGlvbiBgck9wZW5TY1BDQTo6Y2FsY3VsYXRlX3N0YWJpbGl0eSgpYCB0byBjYWxjdWxhdGUgdGhlIGNsdXN0ZXIgc3RhYmlsaXR5LgpCeSBkZWZhdWx0LCB0aGlzIGZ1bmN0aW9uIHBlcmZvcm1zIDIwIGJvb3RzdHJhcCByZXBsaWNhdGVzLCBidXQgdGhpcyBjYW4gYmUgY3VzdG9taXplZCB1c2luZyB0aGUgYXJndW1lbnQgYHJlcGxpY2F0ZXNgLgoKVGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiBhIGRhdGEgZnJhbWUgd2l0aCBjb2x1bW5zIGByZXBsaWNhdGVgLCBgYXJpYCwgYW5kIGFkZGl0aW9uYWwgY29sdW1ucyBmb3IgdGhlIGNsdXN0ZXJpbmcgcGFyYW1ldGVycyB1c2VkIHdoZW4gY2FsY3VsYXRpbmcgYm9vdHN0cmFwIGNsdXN0ZXJzLgoKYGBge3Igc3RhYmlsaXR5LCB3YXJuaW5nPUZBTFNFfQojIGNhbGN1bGF0ZSB0aGUgc3RhYmlsaXR5IG9mIGNsdXN0ZXJzCnN0YWJpbGl0eV9yZXN1bHRzIDwtIHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9zdGFiaWxpdHkoCiAgcGNhX21hdHJpeCwKICBjbHVzdGVyX3Jlc3VsdHNfZGYKKQoKIyBwcmludCB0aGUgcmVzdWx0CnN0YWJpbGl0eV9yZXN1bHRzCmBgYAoKV2UgY2FuIHZpc3VhbGl6ZSB0aGVzZSByZXN1bHRzIGJ5IHBsb3R0aW5nIHN0YWJpbGl0eSBhcyBhIGRlbnNpdHkgcGxvdCwgZm9yIGV4YW1wbGU6CgpgYGB7ciBhcmkgZGVuc2l0eX0KZ2dwbG90KHN0YWJpbGl0eV9yZXN1bHRzKSArCiAgYWVzKHggPSBhcmkpICsKICBnZW9tX2RlbnNpdHkoY29sb3IgPSAiZ3JleTMwIiwgZmlsbCA9ICJsaWdodHNsYXRlYmx1ZSIpICsKICBsYWJzKHggPSAiQWRqdXN0ZWQgcmFuZCBpbmRleCBhY3Jvc3MgYm9vdHN0cmFwIHJlcGxpY2F0ZXMiKQpgYGAKCgojIyMjIFVzaW5nIG5vbi1kZWZhdWx0IGNsdXN0ZXJpbmcgcGFyYW1ldGVycwoKV2hlbiBjYWxjdWxhdGluZyBib290c3RyYXAgY2x1c3RlcnMsIGByT3BlblNjUENBOjpjYWxjdWxhdGVfc3RhYmlsaXR5KClgIHVzZXMgYHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9jbHVzdGVycygpYCB3aXRoIGRlZmF1bHQgcGFyYW1ldGVycy4gCklmIHlvdXIgb3JpZ2luYWwgY2x1c3RlcnMgd2VyZSBub3QgY2FsY3VsYXRlZCB3aXRoIHRoZXNlIGRlZmF1bHRzLCB5b3Ugc2hvdWxkIHBhc3MgdGhvc2UgY3VzdG9taXplZCB2YWx1ZXMgaW50byB0aGlzIGZ1bmN0aW9uIGFzIHdlbGwgdG8gZW5zdXJlIGEgZmFpciBjb21wYXJpc29uIGJldHdlZW4geW91ciBvcmlnaW5hbCBjbHVzdGVycyBhbmQgdGhlIGJvb3RzdHJhcCBjbHVzdGVycy4KCgpgYGB7ciBzdGFiaWxpdHkgY3VzdG9tIHBhcmFtZXRlcnN9CiMgQ2FsY3VsYXRlIGNsdXN0ZXJzIHdpdGggbm9uLWRlZmF1bHQgcGFyYW1ldGVycwpjbHVzdGVyX2RmX2xlaWRlbiA8LSByT3BlblNjUENBOjpjYWxjdWxhdGVfY2x1c3RlcnMoCiAgcGNhX21hdHJpeCwKICBhbGdvcml0aG0gPSAibGVpZGVuIiwKICByZXNvbHV0aW9uID0gMC41LAogIG5uID0gMTUKKQoKIyBOb3csIHBhc3MgaW4gdGhlIHNhbWUgYXJndW1lbnRzIGN1c3RvbWl6aW5nIHBhcmFtZXRlcnMgaGVyZQpzdGFiaWxpdHlfcmVzdWx0c19sZWlkZW4gPC0gck9wZW5TY1BDQTo6Y2FsY3VsYXRlX3N0YWJpbGl0eSgKICBwY2FfbWF0cml4LAogIGNsdXN0ZXJfZGZfbGVpZGVuLAogIGFsZ29yaXRobSA9ICJsZWlkZW4iLAogIHJlc29sdXRpb24gPSAwLjUsCiAgbm4gPSAxNQopCmBgYAoKCiMjIFdvcmtpbmcgd2l0aCBvYmplY3RzIGRpcmVjdGx5CgpBcyBwcmVzZW50ZWQgYWJvdmUsIGByT3BlblNjUENBYCBjbHVzdGVyaW5nIGZ1bmN0aW9ucyB0YWtlIGEgUENBIG1hdHJpeCB3aXRoIHJvdyBuYW1lcyByZXByZXNlbnRpbmcgdW5pcXVlIGNlbGwgaWRzIGFzIHRoZWlyIGZpcnN0IGFyZ3VtZW50LgoKSW5zdGVhZCBvZiBhIG1hdHJpeCwgeW91IGNhbiBhbHRlcm5hdGl2ZWx5IHBhc3MgaW4gYW4gU0NFIG9yIFNldXJhdCBvYmplY3QgdGhhdCBjb250YWlucyBhIG1hdHJpeC4KCldlIHNob3cgYW4gZXhhbXBsZSBvZiB0aGlzIGJlbG93IHdpdGggYW5kIFNDRSBvYmplY3QgYW5kIGByT3BlblNjUENBOjpjYWxjdWxhdGVfY2x1c3RlcnMoKWAsIGJ1dCB0aGlzIHdpbGwgYWxzbyB3b3JrIGZvciBhbnkgb2YgdGhlIGV2YWx1YXRpb24gZnVuY3Rpb25zIGFzIHdlbGwgYW5kIGhhcyB0aGUgc2FtZSBzeW50YXggZm9yIFNldXJhdCBvYmplY3RzLgoKYGBge3IgcnVuIG9uIHNjZX0KIyBDYWxjdWxhdGUgY2x1c3RlcnMgZnJvbSBhbiBTQ0Ugb2JqZWN0IHVzaW5nIGRlZmF1bHQgcGFyYW1ldGVycwpjbHVzdGVyX3Jlc3VsdHNfZGYgPC0gck9wZW5TY1BDQTo6Y2FsY3VsYXRlX2NsdXN0ZXJzKHNjZSkKY2x1c3Rlcl9yZXN1bHRzX2RmCmBgYAoKCmByT3BlblNjUENBYCBhc3N1bWVzIHRoYXQgdGhlIFBDQSBtYXRyaXggaXMgbmFtZWQgYFBDQWAgaW4gU0NFIG9iamVjdHMsIGFuZCBgcGNhYCBpbiBTZXVyYXQgb2JqZWN0cy4KSWYgdGhlIFBDQSBtYXRyaXggeW91IHdhbnQgdG8gdXNlIGluIHRoZSBvYmplY3QgaGFzIGEgZGlmZmVyZW50IG5hbWUsIHlvdSBjYW4gcHJvdmlkZSB0aGUgYXJndW1lbnQgYHBjX25hbWVgLgoKCiMjIENhbGN1bGF0aW5nIFFDIG1ldHJpY3Mgb24gZXhpc3RpbmcgY2x1c3RlcnMKCklmIHlvdSBhbHJlYWR5IGhhdmUgY2x1c3RlcmluZyByZXN1bHRzIGNhbGN1bGF0ZWQgd2l0aCBvdGhlciB0b29scywgeW91IGNhbiBzdGlsbCB1c2UgdGhlIGByT3BlblNjUENBYCBmdW5jdGlvbnMgdG8gZXZhbHVhdGUgeW91ciBjbHVzdGVycy4KCkluIHRoaXMgc2VjdGlvbiwgd2UnbGwgcHJlc2VudCBleGFtcGxlcyBvZiBob3cgeW91IGNhbiBjYWxjdWxhdGUgdGhlIHNpbGhvdWV0dGUgd2lkdGgsIG5laWdoYm9yaG9vZCBwdXJpdHksIGFuZCBjbHVzdGVyIHN0YWJpbGl0eSBmcm9tIGV4aXN0aW5nIGNsdXN0ZXIgYXNzaWdubWVudHMgd2l0aGluIG9iamVjdHMuCgojIyMgRXZhbHVhdGluZyBTZXVyYXQgY2x1c3RlcnMKCklmIHlvdSBhcmUgYW5hbHl6aW5nIHlvdXIgZGF0YSB3aXRoIGEgU2V1cmF0IHBpcGVsaW5lIHRoYXQgaW5jbHVkZXMgY2FsY3VsYXRpbmcgY2x1c3RlcnMsIHlvdSBjYW4gdXNlIGByT3BlblNjUENBYCB0byBldmFsdWF0ZSB0aGVtLgoKVG8gZGVtb25zdHJhdGUgdGhpcywgd2UnbGwgY29udmVydCBvdXIgU0NFIG9iamVjdCB0byBhIFNldXJhdCB1c2luZyB0aGUgZnVuY3Rpb24gYHJPcGVuU2NQQ0E6OnNjZV90b19zZXVyYXQoKWAuClRoZW4sIHdlJ2xsIHVzZSBhIHNpbXBsZSBTZXVyYXQgcGlwZWxpbmUgdG8gb2J0YWluIGNsdXN0ZXJzLgo8IS0tIFRPRE86IFdlIHdpbGwgd2FudCB0byByZWZlcmVuY2UgdGhpcyBtb2R1bGUgZm9yIGZ1cnRoZXIgZG9jdW1lbnRhdGlvbiBvbiB0aGlzIGZ1bmN0aW9uOiBodHRwczovL2dpdGh1Yi5jb20vQWxleHNMZW1vbmFkZS9PcGVuU2NQQ0EtYW5hbHlzaXMvaXNzdWVzLzk0NSAtLT4KCmBgYHtyIHNjZSB0byBzZXVyYXQsIG1lc3NhZ2UgPSBGQUxTRX0KIyBDb252ZXJ0IHRoZSBTQ0UgdG8gYSBTZXVyYXQgb2JqZWN0IHVzaW5nIHJPcGVuU2NQQ0EKc2V1cmF0X29iaiA8LSByT3BlblNjUENBOjpzY2VfdG9fc2V1cmF0KHNjZSkKCiMgQ2FsY3VsYXRlIGNsdXN0ZXJzIHdpdGggU2V1cmF0IHVzaW5nIGEgc3RhbmRhcmQgU2V1cmF0IHBpcGVsaW5lLCBmb3IgZXhhbXBsZQpzZXVyYXRfb2JqIDwtIHNldXJhdF9vYmogfD4KICBTQ1RyYW5zZm9ybSgpIHw+CiAgUnVuUENBKCkgfD4KICBGaW5kTmVpZ2hib3JzKCkgfD4KICBGaW5kQ2x1c3RlcnMoKQoKc2V1cmF0X29iagpgYGAKCgpUbyBjYWxjdWxhdGUgUUMgbWV0cmljcyBvbiB0aGVzZSBjbHVzdGVycywgd2UnbGwgbmVlZCB0byBjcmVhdGUgYSBkYXRhIGZyYW1lIHdpdGggY29sdW1ucyBgY2VsbF9pZGAgYW5kIGBjbHVzdGVyYDoKCmBgYHtyIHByZXBhcmUgc2V1cmF0IGlucHV0fQojIENyZWF0ZSBhIGRhdGEgZnJhbWUgZm9yIGlucHV0CnNldXJhdF9jbHVzdGVyX2RmIDwtIGRhdGEuZnJhbWUoCiAgY2VsbF9pZCA9IGNvbG5hbWVzKHNldXJhdF9vYmopLAogIGNsdXN0ZXIgPSBzZXVyYXRfb2JqJHNldXJhdF9jbHVzdGVycwopCgpoZWFkKHNldXJhdF9jbHVzdGVyX2RmKQpgYGAKCk5vdywgd2UgY2FuIHJ1biBgck9wZW5TY1BDQTo6Y2FsY3VsYXRlX3NpbGhvdWV0dGUoKWAgYW5kIGByT3BlblNjUENBOjpjYWxjdWxhdGVfcHVyaXR5KClgIHVzaW5nIHRoaXMgZGF0YSBmcmFtZSBhbmQgdGhlIFNldXJhdCBvYmplY3Q6CgpgYGB7ciBzZXVyYXQgc2lsaG91ZXR0ZX0Kc2V1cmF0X3NpbGhvdWV0dGVfZGYgPC0gck9wZW5TY1BDQTo6Y2FsY3VsYXRlX3NpbGhvdWV0dGUoCiAgc2V1cmF0X29iaiwKICBzZXVyYXRfY2x1c3Rlcl9kZgopCmBgYAoKYGBge3Igc2V1cmF0IHB1cml0eX0Kc2V1cmF0X3B1cml0eV9kZiA8LSByT3BlblNjUENBOjpjYWxjdWxhdGVfcHVyaXR5KAogIHNldXJhdF9vYmosCiAgc2V1cmF0X2NsdXN0ZXJfZGYKKQpgYGAKCldlIGRvIG5vdCByZWNvbW1lbmQgdXNpbmcgYHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9zdGFiaWxpdHkoKWAgb24gU2V1cmF0IGNsdXN0ZXJzIGR1ZSB0byBkaWZmZXJlbmNlcyBpbiB0aGUgdW5kZXJseWluZyBjbHVzdGVyaW5nIGFwcHJvYWNoIGJldHdlZW4gU2V1cmF0IGFuZCB0aGUgYGJsdXN0ZXJgIHBhY2thZ2Ugd2hpY2ggYHJPcGVuU2NQQ0FgIHVzZXMuCgojIyMgRXZhbHVhdGluZyBTY1BDQSBjbHVzdGVycwoKU2NQQ0EgY2VsbCBtZXRhZGF0YSBhbHJlYWR5IGNvbnRhaW5zIGEgY29sdW1uIGNhbGxlZCBgY2x1c3RlcmAgd2l0aCByZXN1bHRzIGZyb20gYW4gYXV0b21hdGVkIGNsdXN0ZXJpbmcuIApUaGVzZSBjbHVzdGVycyB3ZXJlIGNhbGN1bGF0ZWQgdXNpbmcgYGJsdXN0ZXJgLCB0aGUgc2FtZSB0b29sIHRoYXQgYHJPcGVuU2NQQ0FgIHVzZXMuIApUaGUgc3BlY2lmaWNhdGlvbnMgdXNlZCBmb3IgdGhpcyBjbHVzdGVyaW5nIGFyZSBzdG9yZWQgaW4gdGhlIFNDRSBvYmplY3QncyBtZXRhZGF0YSwgYXMgZm9sbG93czsgbm90ZSB0aGF0IGFsbCBvdGhlciBjbHVzdGVyaW5nIHBhcmFtZXRlcnMgd2VyZSBsZWZ0IGF0IHRoZWlyIGRlZmF1bHQgdmFsdWVzLgoKKiBgbWV0YWRhdGEoc2NlKSRjbHVzdGVyX2FsZ29yaXRobWA6IFRoZSBjbHVzdGVyaW5nIGFsZ29yaXRobSB1c2VkCiogYG1ldGFkYXRhKHNjZSkkY2x1c3Rlcl93ZWlnaHRpbmdgOiBUaGUgd2VpZ2h0aW5nIHNjaGVtZSB1c2VkCiogYG1ldGFkYXRhKHNjZSkkY2x1c3Rlcl9ubmA6IFRoZSBudW1iZXIgb2YgbmVhcmVzdCBuZWlnaGJvcnMgdXNlZAoKWW91IGNhbiBzZWUgYWxsIHRoZWlyIHZhbHVlcyBoZXJlOgoKCmBgYHtyIGV4dHJhY3QgY2x1c3RlciBwYXJhbXN9CiMgUHJpbnQgY2x1c3RlcmluZyBzcGVjaWZpY2F0aW9ucwptZXRhZGF0YShzY2UpW2MoImNsdXN0ZXJfYWxnb3JpdGhtIiwgImNsdXN0ZXJfd2VpZ2h0aW5nIiwgImNsdXN0ZXJfbm4iKV0KYGBgCgoKSW4gdGhpcyBleGFtcGxlLCB3ZSdsbCBzaG93IGhvdyB0byB1c2UgdGhlIGNsdXN0ZXIgZXZhbHVhdGlvbiBmdW5jdGlvbnMgb24gdGhlc2UgY2x1c3RlcnMuCgpUbyBiZWdpbiwgd2UnbGwgcHJlcGFyZSBhIGRhdGEgZnJhbWUgd2l0aCB0d28gY29sdW1uczogYGNlbGxfaWRgIGNvbnRhaW5pbmcgY2VsbCBiYXJjb2RlcywgYW5kIGBjbHVzdGVyYCBjb250YWluaW5nIHRoZSBjbHVzdGVyIGlkZW50aXRpZXMuCgpgYGB7ciBwcmVwYXJlIHNjcGNhIGRhdGEgZnJhbWV9CnNjcGNhX2NsdXN0ZXJfZGYgPC0gZGF0YS5mcmFtZSgKICBjZWxsX2lkID0gY29sbmFtZXMoc2NlKSwKICBjbHVzdGVyID0gc2NlJGNsdXN0ZXIKKQoKaGVhZChzY3BjYV9jbHVzdGVyX2RmKQpgYGAKCldlIGNhbiBydW4gZXZhbHVhdGlvbiBmdW5jdGlvbnMgdXNpbmcgdGhpcyBkYXRhIGZyYW1lIGFuZCB0aGUgU0NFIG9iamVjdC4KCmBgYHtyIHNjcGNhIHNpbGhvdWV0dGV9CiMgQ2FsY3VsYXRlIHNpbGhvdWV0dGUgd2lkdGgKc2NwY2Ffc2lsaG91ZXR0ZV9kZiA8LSByT3BlblNjUENBOjpjYWxjdWxhdGVfc2lsaG91ZXR0ZSgKICBzY2UsCiAgc2NwY2FfY2x1c3Rlcl9kZgopCmBgYAoKYGBge3Igc2NwY2EgcHVyaXR5fQojIENhbGN1bGF0ZSBuZWlnaGJvcmhvb2QgcHVyaXR5CnNjcGNhX3B1cml0eV9kZiA8LSByT3BlblNjUENBOjpjYWxjdWxhdGVfcHVyaXR5KAogIHNjZSwKICBzY3BjYV9jbHVzdGVyX2RmCikKYGBgCgpXaGVuIHJ1bm5pbmcgYHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9zdGFiaWxpdHkoKWAsIHdlJ2xsIHNwZWNpZnkgdGhlIHNhbWUgcGFyYW1ldGVycyBvcmlnaW5hbGx5IHVzZWQgdG8gYnVpbGQgdGhlIGNsdXN0ZXJzIGJ5IGV4dHJhY3RpbmcgdGhlbSBmcm9tIHRoZSBtZXRhZGF0YS4KV2UnbGwgbmVlZCB0byBlbnN1cmUgdGhlIHByb3ZpZGVkIGFyZ3VtZW50cyBhcmUgbG93ZXJjYXNlLCBhcyB3ZWxsLgoKR2VuZXJhbGx5IHNwZWFraW5nLCB3ZSBvbmx5IHJlY29tbWVuZCBldmFsdWF0aW5nIGNsdXN0ZXJzIHdpdGggYHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9zdGFiaWxpdHkoKWAgaWYgeW91IGtub3cgdGhlIG9yaWdpbmFsIHBhcmFtZXRlcnMgdXNlZC4KCgpgYGB7ciBzY3BjYSBzdGFiaWxpdHl9CnNjcGNhX3N0YWJpbGl0eV9kZiA8LSByT3BlblNjUENBOjpjYWxjdWxhdGVfc3RhYmlsaXR5KAogIHNjZSwKICBzY3BjYV9jbHVzdGVyX2RmLAogICMgcHJvdmlkZSBTY1BDQSBjbHVzdGVyaW5nIHBhcmFtZXRlcnMgYnkgZXh0cmFjdGluZyBmcm9tIHRoZSBTQ0UgbWV0YWRhdGEKICBhbGdvcml0aG0gPSB0b2xvd2VyKG1ldGFkYXRhKHNjZSkkY2x1c3Rlcl9hbGdvcml0aG0pLAogIHdlaWdodGluZyA9IHRvbG93ZXIobWV0YWRhdGEoc2NlKSRjbHVzdGVyX3dlaWdodGluZyksCiAgbm4gPSBtZXRhZGF0YShzY2UpJGNsdXN0ZXJfbm4KKQpgYGAKCgojIyBTYXZpbmcgY2x1c3RlcmluZyByZXN1bHRzIAoKUmVzdWx0cyBjYW4gZWl0aGVyIGJlIGRpcmVjdGx5IGV4cG9ydGVkIGFzIGEgVFNWIGZpbGUgKGUuZy4sIHdpdGggYHJlYWRyOjp3cml0ZV90c3YoKWApLCBvciB5b3UgY2FuIGFkZCB0aGUgcmVzdWx0cyBpbnRvIHlvdXIgU0NFIG9yIFNldXJhdCBvYmplY3QuClRoZSBzdWJzZXF1ZW50IGV4YW1wbGVzIHdpbGwgZGVtb25zdHJhdGUgc2F2aW5nIHRoZSBjbHVzdGVyIGFzc2lnbm1lbnRzIHN0b3JlZCBpbiBgY2x1c3Rlcl9yZXN1bHRzX2RmJGNsdXN0ZXJgIHRvIGFuIFNDRSBhbmQgYSBTZXVyYXQgb2JqZWN0LgoKX0Egd29yZCBvZiBjYXV0aW9uIV8KT2JqZWN0cyBmcm9tIHRoZSBTY1BDQSBQb3J0YWwgYWxyZWFkeSBjb250YWluIGEgY29sdW1uIGNhbGxlZCBgY2x1c3RlcmAgd2l0aCByZXN1bHRzIGZyb20gYW4gYXV0b21hdGVkIGNsdXN0ZXJpbmcuClRoZXNlIGF1dG9tYXRpYyBjbHVzdGVycyB3ZXJlIG5vdCBldmFsdWF0ZWQsIGFuZCB0aGVpciBwYXJhbWV0ZXJzIHdlcmUgbm90IG9wdGltaXplZCBmb3IgYW55IGdpdmVuIGxpYnJhcnkuClRvIGF2b2lkIGFtYmlndWl0eSBiZXR3ZWVuIHRoZSBleGlzdGluZyBhbmQgbmV3IGNsdXN0ZXJpbmcgcmVzdWx0cywgd2UnbGwgbmFtZSB0aGUgbmV3IGNvbHVtbiBgcm9wZW5zY3BjYV9jbHVzdGVyYC4KCiMjIyBTYXZpbmcgcmVzdWx0cyB0byBhbiBTQ0Ugb2JqZWN0IAoKV2UgY2FuIGFkZCBjb2x1bW5zIHRvIGFuIFNDRSBvYmplY3QncyBgY29sRGF0YWAgdGFibGUgYnkgZGlyZWN0bHkgY3JlYXRpbmcgYSBjb2x1bW4gaW4gdGhlIG9iamVjdCB3aXRoIGAkYC4KQmVmb3JlIHdlIGRvIHNvLCB3ZSdsbCBjb25maXJtIHRoYXQgdGhlIGNsdXN0ZXJzIGFyZSBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGUgU0NFIG9iamVjdCBieSBjb21wYXJpbmcgY2VsbCBpZHM6CgpgYGB7ciBjaGVjayBzY2Ugb3JkZXJ9CmFsbC5lcXVhbCgKICBjb2xuYW1lcyhzY2UpLAogIGNsdXN0ZXJfcmVzdWx0c19kZiRjZWxsX2lkCikKYGBgCgpgYGB7ciBhZGQgdG8gc2NlfQojIEFkZCBjbHVzdGVyIHJlc3VsdHMgdG8gdGhlIGNvbERhdGEKc2NlJHJvcGVuc2NwY2FfY2x1c3RlciA8LSBjbHVzdGVyX3Jlc3VsdHNfZGYkY2x1c3RlcgpgYGAKCiMjIyBTYXZpbmcgcmVzdWx0cyB0byBhIFNldXJhdCBvYmplY3QgCgoKV2UgY2FuIGFkZCBjb2x1bW5zIHRvIGFuIFNldXJhdCBvYmplY3QncyBjZWxsIG1ldGFkYXRhIHRhYmxlIGJ5IGRpcmVjdGx5IGNyZWF0aW5nIGEgY29sdW1uIGluIHRoZSBvYmplY3Qgd2l0aCBgJGAgKG5vdGUgdGhhdCB5b3UgY2FuIGFsc28gdXNlIHRoZSBTZXVyYXQgZnVuY3Rpb24gYEFkZE1ldGFEYXRhKClgKS4KQmVmb3JlIHdlIGRvIHNvLCB3ZSdsbCBjb25maXJtIHRoYXQgdGhlIGNsdXN0ZXJzIGFyZSBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGUgU2V1cmF0IG9iamVjdCBieSBjb21wYXJpbmcgY2VsbCBpZHM6CgoKYGBge3IgY2hlY2sgc2V1cmF0IG9yZGVyfQphbGwuZXF1YWwoCiAgY29sbmFtZXMoc2V1cmF0X29iaiksCiAgY2x1c3Rlcl9yZXN1bHRzX2RmJGNlbGxfaWQKKQpgYGAKCmBgYHtyIGFkZCB0byBzZXVyYXR9CiMgQWRkIGNsdXN0ZXIgcmVzdWx0cyB0byB0aGUgY2VsbCBtZXRhZGF0YQpzZXVyYXRfb2JqJHJvcGVuc2NwY2FfY2x1c3RlciA8LSBjbHVzdGVyX3Jlc3VsdHNfZGYkY2x1c3RlcgpgYGAKCgojIyBTZXNzaW9uIEluZm8KCmBgYHtyIHNlc3Npb24gaW5mb30KIyByZWNvcmQgdGhlIHZlcnNpb25zIG9mIHRoZSBwYWNrYWdlcyB1c2VkIGluIHRoaXMgYW5hbHlzaXMgYW5kIG90aGVyIGVudmlyb25tZW50IGluZm9ybWF0aW9uCnNlc3Npb25JbmZvKCkKYGBgCg==
+
LS0tCnRpdGxlOiAiUGVyZm9ybWluZyBncmFwaC1iYXNlZCBjbHVzdGVyaW5nIHdpdGggck9wZW5TY1BDQSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgphdXRob3I6ICJEYXRhIExhYiIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGRmX3ByaW50OiBwYWdlZAotLS0KCiMjIEludHJvZHVjdGlvbgoKVGhpcyBub3RlYm9vayBwcm92aWRlcyBleGFtcGxlcyBvZiBob3cgdG8gdXNlIGZ1bmN0aW9ucyBpbiBgck9wZW5TY1BDQWAgdGhhdDoKCiogUGVyZm9ybSBjbHVzdGVyaW5nCiogQ2FsY3VsYXRlIFFDIG1ldHJpY3Mgb24gY2x1c3RlcnMsIGluY2x1ZGluZzoKICAqIFNpbGhvdWV0dGUgd2lkdGgKICAqIE5laWdoYm9yaG9vZCBwdXJpdHkKICAqIENsdXN0ZXIgc3RhYmlsaXR5LCBhcyBtZWFzdXJlZCB3aXRoIHRoZSBBZGp1c3RlZCBSYW5kIEluZGV4CiogQ2FsY3VsYXRlIFFDIG1ldHJpY3Mgb24gY2x1c3RlcnMgb2J0YWluZWQgd2l0aCBvdGhlciB0b29scywgc3VjaCBhcyBgU2V1cmF0YAoqIFNhdmUgY2x1c3RlcmluZyByZXN1bHRzIHRvIGFuIFNDRSBvciBgU2V1cmF0YAoKV2hpbGUgdGhpcyBub3RlYm9vayBkZW1vbnN0cmF0ZXMgaG93IHRvIHVzZSBpbmRpdmlkdWFsIGZ1bmN0aW9ucyB0aGF0IGNhbGN1bGF0ZSBoZWxwZnVsIG1ldHJpY3MgZm9yIGV2YWx1YXRpbmcgY2x1c3RlcmluZyByZXN1bHRzLCBhIGZ1bGwgZXZhbHVhdGlvbiB3b3VsZCBjb21wYXJlIHRoZXNlIG1ldHJpY3MgYWNyb3NzIGRpZmZlcmVudCBjbHVzdGVyaW5ncyBmcm9tIGRpZmZlcmVudCBwYXJhbWV0ZXJpemF0aW9ucy4KClRoaXMgbm90ZWJvb2sgd2lsbCB1c2UgdGhlIHNhbXBsZSBgU0NQQ1MwMDAwMDFgIGZyb20gcHJvamVjdCBgU0NQQ1AwMDAwMDFgLCB3aGljaCBpcyBhc3N1bWVkIHByZXNlbnQgaW4gdGhlIGBPcGVuU2NQQ0EtYW5hbHlzaXMvZGF0YS9jdXJyZW50L1NDUENQMDAwMDAxYCBkaXJlY3RvcnksIGZvciBhbGwgZXhhbXBsZXMuClBsZWFzZSBbc2VlIHRoaXMgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9vcGVuc2NwY2EucmVhZHRoZWRvY3MuaW8vZW4vbGF0ZXN0L2dldHRpbmctc3RhcnRlZC9hY2Nlc3NpbmctcmVzb3VyY2VzL2dldHRpbmctYWNjZXNzLXRvLWRhdGEvKSBmb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBvYnRhaW5pbmcgU2NQQ0EgZGF0YS4KCiMjIFNldHVwCgojIyMgUGFja2FnZXMKCgpgYGB7ciBwYWNrYWdlc30KbGlicmFyeShyT3BlblNjUENBKQoKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKHsKICBsaWJyYXJ5KFNpbmdsZUNlbGxFeHBlcmltZW50KQogIGxpYnJhcnkoU2V1cmF0KQogIGxpYnJhcnkoZHBseXIpCiAgbGlicmFyeShnZ3Bsb3QyKQp9KQoKIyBTZXQgZ2dwbG90IHRoZW1lIGZvciBwbG90cwp0aGVtZV9zZXQodGhlbWVfYncoKSkKYGBgCgoKIyMjIFBhdGhzCgpgYGB7ciBiYXNlIHBhdGhzfQojIFRoZSBiYXNlIHBhdGggZm9yIHRoZSBPcGVuU2NQQ0EgcmVwb3NpdG9yeQpyZXBvc2l0b3J5X2Jhc2UgPC0gcnByb2pyb290OjpmaW5kX3Jvb3QocnByb2pyb290Ojppc19naXRfcm9vdCkKCiMgVGhlIGN1cnJlbnQgZGF0YSBkaXJlY3RvcnksIGZvdW5kIHdpdGhpbiB0aGUgcmVwb3NpdG9yeSBiYXNlIGRpcmVjdG9yeQpkYXRhX2RpciA8LSBmaWxlLnBhdGgocmVwb3NpdG9yeV9iYXNlLCAiZGF0YSIsICJjdXJyZW50IikKCiMgVGhlIHBhdGggdG8gdGhpcyBtb2R1bGUKbW9kdWxlX2Jhc2UgPC0gZmlsZS5wYXRoKHJlcG9zaXRvcnlfYmFzZSwgImFuYWx5c2VzIiwgImhlbGxvLWNsdXN0ZXJzIikKYGBgCgpgYGB7ciBpbnB1dCBmaWxlIHBhdGh9CiMgUGF0aCB0byBwcm9jZXNzZWQgU0NFIGZpbGUgZm9yIHNhbXBsZSBTQ1BDUzAwMDAwMQppbnB1dF9zY2VfZmlsZSA8LSBmaWxlLnBhdGgoZGF0YV9kaXIsICJTQ1BDUDAwMDAwMSIsICJTQ1BDUzAwMDAwMSIsICJTQ1BDTDAwMDAwMV9wcm9jZXNzZWQucmRzIikKYGBgCgoKIyMjIFNldCB0aGUgcmFuZG9tIHNlZWQKCkJlY2F1c2UgY2x1c3RlcmluZyBpbnZvbHZlcyByYW5kb20gc2FtcGxpbmcsIGl0IGlzIGltcG9ydGFudCB0byBzZXQgdGhlIHJhbmRvbSBzZWVkIGF0IHRoZSB0b3Agb2YgeW91ciBhbmFseXNpcyBzY3JpcHQgb3Igbm90ZWJvb2sgdG8gZW5zdXJlIHJlcHJvZHVjaWJpbGl0eS4KCmBgYHtyIHNldCBzZWVkfQpzZXQuc2VlZCgyMDI0KQpgYGAKCiMjIFJlYWQgaW4gYW5kIHByZXBhcmUgZGF0YQoKVG8gYmVnaW4sIHdlJ2xsIHJlYWQgaW4gdGhlIGBTaW5nbGVDZWxsRXhwZXJpbWVudGAgKFNDRSkgb2JqZWN0LgoKYGBge3IgcmVhZCBkYXRhfQojIFJlYWQgdGhlIFNDRSBmaWxlCnNjZSA8LSByZWFkUkRTKGlucHV0X3NjZV9maWxlKQpgYGAKCkZvciB0aGUgaW5pdGlhbCBjbHVzdGVyIGNhbGN1bGF0aW9ucyBhbmQgZXZhbHVhdGlvbnMsIHdlIHdpbGwgdXNlIHRoZSBQQ0EgbWF0cml4IGV4dHJhY3RlZCBmcm9tIHRoZSBTQ0Ugb2JqZWN0LgpJdCdzIGFsc28gcG9zc2libGUgdG8gdXNlIGFuIFNDRSBvYmplY3Qgb3IgYSBTZXVyYXQgb2JqZWN0IGRpcmVjdGx5LCB3aGljaCB3ZSB3aWxsIGRlbW9uc3RyYXRlIGxhdGVyLgoKCmBgYHtyIGV4dHJhY3QgcGNhIGRhdGF9CiMgRXh0cmFjdCB0aGUgUENBIG1hdHJpeCBmcm9tIGFuIFNDRSBvYmplY3QKcGNhX21hdHJpeCA8LSByZWR1Y2VkRGltKHNjZSwgIlBDQSIpCmBgYAoKIyMgUGVyZm9ybSBjbHVzdGVyaW5nCgpUaGlzIHNlY3Rpb24gd2lsbCBzaG93IGhvdyB0byBwZXJmb3JtIGNsdXN0ZXJpbmcgd2l0aCB0aGUgZnVuY3Rpb24gYHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9jbHVzdGVycygpYC4KClRoaXMgZnVuY3Rpb24gdGFrZXMgYSBQQ0EgbWF0cml4IHdpdGggcm93bmFtZXMgcmVwcmVzZW50aW5nIHVuaXF1ZSBjZWxsIGlkcyAoZS5nLiwgYmFyY29kZXMpIGFzIGl0cyBwcmltYXJ5IGFyZ3VtZW50LgpCeSBkZWZhdWx0IGl0IHdpbGwgY2FsY3VsYXRlIGNsdXN0ZXJzIHVzaW5nIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVyczoKCiogTG91dmFpbiBhbGdvcml0aG0KKiBKYWNjYXJkIHdlaWdodGluZwoqIDEwIG5lYXJlc3QgbmVpZ2hib3JzCiogQSByZXNvbHV0aW9uIHBhcmFtZXRlciBvZiAxCgpUaGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIGEgdGFibGUgd2l0aCB0aGUgZm9sbG93aW5nIGNvbHVtbnM6CgoqIGBjZWxsX2lkYDogVW5pcXVlIGNlbGwgaWRlbnRpZmllcnMsIG9idGFpbmVkIGZyb20gdGhlIFBDQSBtYXRyaXgncyByb3cgbmFtZXMKKiBgY2x1c3RlcmA6IEEgZmFjdG9yIGNvbHVtbiB3aXRoIHRoZSBjbHVzdGVyIGlkZW50aXRpZXMKKiBUaGVyZSB3aWxsIGJlIG9uZSBjb2x1bW4gZm9yIGVhY2ggY2x1c3RlcmluZyBwYXJhbWV0ZXIgdXNlZAoKCiMjIyBDbHVzdGVyaW5nIHdpdGggZGVmYXVsdCBwYXJhbWV0ZXJzCgpgYGB7ciBjbHVzdGVyIHNjZX0KIyBDYWxjdWxhdGUgY2x1c3RlcnMgd2l0aCBkZWZhdWx0IHBhcmFtZXRlcnMKY2x1c3Rlcl9yZXN1bHRzX2RmIDwtIHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9jbHVzdGVycyhwY2FfbWF0cml4KQoKIyBQcmludCB0aGUgZmlyc3Qgcm93cyBvZiB0aGUgcmVzdWx0aW5nIHRhYmxlCmhlYWQoY2x1c3Rlcl9yZXN1bHRzX2RmKQpgYGAKCiMjIyBDbHVzdGVyaW5nIHdpdGggbm9uLWRlZmF1bHQgcGFyYW1ldGVycwoKUGFyYW1ldGVycyB1c2VkIGZvciBjbHVzdGVyaW5nIGNhbiBiZSBjdXN0b21pemVkIHdpdGggdGhlc2UgYXJndW1lbnRzOgoKKiBUaGUgYGFsZ29yaXRobWAgY2FuIGJlIG9uZSBvZjoKICAqIGBsb3V2YWluYCwgYHdhbGt0cmFwYCwgb3IgYGxlaWRlbmAKKiBUaGUgYHdlaWdodGluZ2AgY2FuIGJlIG9uZSBvZjoKICAqIGBqYWNjYXJkYCwgYHJhbmtgLCBvciBgbnVtYmVyYAoqIFRoZSBuZWFyZXN0IG5laWdoYm9ycyBwYXJhbWV0ZXIgY2FuIGJlIGN1c3RvbWl6ZWQgd2l0aCB0aGUgYG5uYCBhcmd1bWVudAoqIFRoZSByZXNvbHV0aW9uIHBhcmFtZXRlciBjYW4gYmUgY3VzdG9taXplZCB3aXRoIHRoZSBgcmVzb2x1dGlvbmAgYXJndW1lbnQKICAqIFRoaXMgcGFyYW1ldGVyIGlzIG9ubHkgdXNlZCBieSBMb3V2YWluIGFuZCBMZWlkZW4gYWxnb3JpdGhtcwoqIElmIHRoZSBMZWlkZW4gYWxnb3JpdGhtIGlzIHVzZWQsIGl0cyBkZWZhdWx0IG9iamVjdGl2ZSBmdW5jdGlvbiBwYXJhbWV0ZXIgd2lsbCBiZSBgQ1BNYCwgYnV0IHlvdSBjYW4gYWxzbyBzZXQgIGBvYmplY3RpdmVfZnVuY3Rpb24gPSAibW9kdWxhcml0eSJgIGluc3RlYWQuCiogWW91IGNhbiBwcm92aWRlIGFkZGl0aW9uYWwgcGFyYW1ldGVycyBhcyBhIGxpc3QgdG8gdGhlIGBjbHVzdGVyX2FyZ3NgIGFyZ3VtZW50LgogICogUGxlYXNlIHJlZmVyIHRvIHRoZSBbYGlncmFwaGAgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9pZ3JhcGgub3JnL3IvaHRtbC9sYXRlc3QpIHRvIGxlYXJuIG1vcmUgYWJvdXQgd2hhdCBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgY2FuIGJlIHByb3ZpZGVkIHRvIGVhY2ggY2x1c3RlcmluZyBhbGdvcml0aG0uCiAgKiBOb3RlIHRoYXQgYGNsdXN0ZXJfYXJnc2Agb25seSBhY2NlcHRzIHNpbmdsZS1sZW5ndGggYXJndW1lbnRzIChubyB2ZWN0b3JzIG9yIGxpc3RzKS4KCkZvciBleGFtcGxlOgoKYGBge3IgY2x1c3RlciBzY2Ugbm9uZGVmYXVsdH0KIyBDYWxjdWxhdGUgY2x1c3RlcnMgd2l0aCBub24tZGVmYXVsdCBwYXJhbWV0ZXJzCmNsdXN0ZXJfcmVzdWx0c19kZiA8LSByT3BlblNjUENBOjpjYWxjdWxhdGVfY2x1c3RlcnMoCiAgcGNhX21hdHJpeCwKICBhbGdvcml0aG0gPSAibGVpZGVuIiwKICBubiA9IDE1LAogIG9iamVjdGl2ZV9mdW5jdGlvbiA9ICJtb2R1bGFyaXR5IgopCmBgYAoKCiMjIENhbGN1bGF0ZSBRQyBtZXRyaWNzIG9uIGNsdXN0ZXJzCgpUaGlzIHNlY3Rpb24gZGVtb25zdHJhdGVzIGhvdyB0byB1c2Ugc2V2ZXJhbCBmdW5jdGlvbnMgZm9yIGV2YWx1YXRpbmcgY2x1c3RlciBxdWFsaXR5IGFuZCByZWxpYWJpbGl0eS4KSXQncyBpbXBvcnRhbnQgdG8gbm90ZSB0aGF0IGEgZnVsbCBldmFsdWF0aW9uIG9mIGNsdXN0ZXJpbmcgcmVzdWx0cyB3b3VsZCBjb21wYXJlIHRoZXNlIG1ldHJpY3MgYWNyb3NzIGEgc2V0IG9mIGNsdXN0ZXJpbmcgcmVzdWx0cywgd2l0aCB0aGUgYWltIG9mIGlkZW50aWZ5aW5nIGFuIG9wdGltYWwgcGFyYW1ldGVyaXphdGlvbi4KCkFsbCBmdW5jdGlvbnMgcHJlc2VudGVkIGluIHRoaXMgc2VjdGlvbiB0YWtlIHRoZSBmb2xsb3dpbmcgcmVxdWlyZWQgYXJndW1lbnRzOgoKKiBBIFBDQSBtYXRyaXggd2l0aCByb3cgbmFtZXMgcmVwcmVzZW50aW5nIHVuaXF1ZSBjZWxsIGlkcyAoZS5nLiwgYmFyY29kZXMpCiogQSBkYXRhIGZyYW1lIHdpdGgsIGF0IGxlYXN0LCBjb2x1bW5zIHJlcHJlc2VudGluZyB1bmlxdWUgY2VsbCBpZHMgYW5kIGNsdXN0ZXIgYXNzaWdubWVudHMKICAqIEJ5IGRlZmF1bHQsIHRoZXNlIGNvbHVtbnMgc2hvdWxkIGJlIG5hbWVkIGBjZWxsX2lkYCBhbmQgYGNsdXN0ZXJgLCByZXNwZWN0aXZlbHksIG1hdGNoaW5nIHRoZSBvdXRwdXQgb2YgYHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9jbHVzdGVycygpYAogICogWW91IGNhbiBvdmVycmlkZSB0aGVzZSBkZWZhdWx0cyB1c2luZyB0aGUgYXJndW1lbnRzIGBjZWxsX2lkX2NvbGAgYW5kIGBjbHVzdGVyX2NvbGAKCiMjIyBTaWxob3VldHRlIHdpZHRoCgpTaWxob3VldHRlIHdpZHRoIGlzIGEgY29tbW9uIG1ldHJpYyB0aGF0IG1lYXN1cmVzIGhvdyB3ZWxsIHNlcGFyYXRlZCBjbHVzdGVycyBhcmUgYnksIGZvciBlYWNoIGNlbGwsIGNvbXBhcmluZyB0aGUgYXZlcmFnZSBkaXN0YW5jZSB0byBhbGwgY2VsbHMgaW4gdGhlIHNhbWUgY2x1c3RlciwgYW5kIGFsbCBjZWxscyBpbiBvdGhlciBjbHVzdGVycy4KVGhpcyB2YWx1ZSByYW5nZXMgZnJvbSAtMSB0byAxLgpDZWxscyBpbiB3ZWxsLXNlcGFyYXRlZCBjbHVzdGVycyBzaG91bGQgaGF2ZSBoaWdoIHNpbGhvdWV0dGUgdmFsdWVzIGNsb3NlciB0byAxLgpZb3UgY2FuIHJlYWQgbW9yZSBhYm91dCBzaWxob3VldHRlIHdpZHRoIHB1cml0eSBmcm9tIHRoZSBbX09yY2hlc3RyYXRpbmcgU2luZ2xlIENlbGwgQW5hbHlzaXMgd2l0aCBCaW9jb25kdWN0b3JfIGJvb2tdKGh0dHBzOi8vYmlvY29uZHVjdG9yLm9yZy9ib29rcy8zLjE5L09TQ0EuYWR2YW5jZWQvY2x1c3RlcmluZy1yZWR1eC5odG1sI3NpbGhvdWV0dGUtd2lkdGgpLgoKV2UnbGwgdXNlIHRoZSBmdW5jdGlvbiBgck9wZW5TY1BDQTo6Y2FsY3VsYXRlX3NpbGhvdWV0dGUoKWAgdG8gY2FsY3VsYXRlIHRoZSBzaWxob3VldHRlIHdpZHRoLgoKVGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiB0aGUgaW5wdXR0ZWQgZGF0YSBmcmFtZSB3aXRoIHR3byBhZGRpdGlvbmFsIGNvbHVtbnM6CgoqIGBzaWxob3VldHRlX3dpZHRoYDogVGhlIGNhbGN1bGF0ZWQgc2lsaG91ZXR0ZSB3aWR0aCBmb3IgdGhlIGNlbGwKKiBgc2lsaG91ZXR0ZV9vdGhlcmA6IFRoZSBjbG9zZXQgY2x1c3RlciB0byB0aGUgY2VsbCBiZXNpZGVzIHRoZSBjbHVzdGVyIHRvIHdoaWNoIGl0IGJlbG9uZ3MsIGFzIHVzZWQgaW4gdGhlIHNpbGhvdWV0dGUgd2lkdGggY2FsY3VsYXRpb24KCgpgYGB7ciBzaWxob3VldHRlfQojIGNhbGN1bGF0ZSB0aGUgc2lsaG91ZXR0ZSB3aWR0aCBmb3IgZWFjaCBjZWxsCnNpbGhvdWV0dGVfcmVzdWx0cyA8LSByT3BlblNjUENBOjpjYWxjdWxhdGVfc2lsaG91ZXR0ZSgKICBwY2FfbWF0cml4LAogIGNsdXN0ZXJfcmVzdWx0c19kZgopCgojIFByaW50IHRoZSBmaXJzdCByb3dzIG9mIHRoZSByZXN1bHRpbmcgdGFibGUKaGVhZChzaWxob3VldHRlX3Jlc3VsdHMpCmBgYAoKCldlIGNhbiB2aXN1YWxpemUgdGhlc2UgcmVzdWx0cyBieSBwbG90dGluZyBzaWxob3VldHRlIHdpZHRoIGFjcm9zcyBjbHVzdGVycyBhcyB2aW9saW4gcGxvdHMsIGZvciBleGFtcGxlOgoKYGBge3IgdmlvbGluIHNpbGhvdWV0dGV9CmdncGxvdChzaWxob3VldHRlX3Jlc3VsdHMpICsKICBhZXMoeCA9IGNsdXN0ZXIsIHkgPSBzaWxob3VldHRlX3dpZHRoKSArCiAgZ2VvbV92aW9saW4oZmlsbCA9ICJkYXJrbWFnZW50YSIpICsKICBsYWJzKHggPSAiQ2x1c3RlciIsIHkgPSAiU2lsaG91ZXR0ZSB3aWR0aCIpCmBgYAoKIyMjIE5laWdoYm9yaG9vZCBwdXJpdHkKCk5laWdoYm9yaG9vZCBwdXJpdHkgaXMgZGVmaW5lZCwgZm9yIGVhY2ggY2VsbCwgYXMgdGhlIHByb3BvcnRpb24gb2YgbmVpZ2hib3JpbmcgY2VsbHMgdGhhdCBhcmUgYXNzaWduZWQgdG8gdGhlIHNhbWUgY2x1c3Rlci4KVGhpcyB2YWx1ZSByYW5nZXMgZnJvbSAwIHRvIDEuCkNlbGxzIGluIHdlbGwtc2VwYXJhdGVkIGNsdXN0ZXJzIHNob3VsZCBoYXZlIGhpZ2ggcHVyaXR5IHZhbHVlcyBjbG9zZXIgdG8gMSwgc2luY2UgdGhlcmUgc2hvdWxkIGJlIG1pbmltYWwgb3ZlcmxhcCBiZXR3ZWVuIG1lbWJlciBhbmQgbmVpZ2hib3JpbmcgY2VsbHMuCllvdSBjYW4gcmVhZCBtb3JlIGFib3V0IG5laWdoYm9yaG9vZCBwdXJpdHkgZnJvbSB0aGUgW19PcmNoZXN0cmF0aW5nIFNpbmdsZSBDZWxsIEFuYWx5c2lzIHdpdGggQmlvY29uZHVjdG9yXyBib29rXShodHRwczovL2Jpb2NvbmR1Y3Rvci5vcmcvYm9va3MvMy4xOS9PU0NBLmFkdmFuY2VkL2NsdXN0ZXJpbmctcmVkdXguaHRtbCNjbHVzdGVyLXB1cml0eSkuCgpXZSdsbCB1c2UgdGhlIGZ1bmN0aW9uIGByT3BlblNjUENBOjpjYWxjdWxhdGVfcHVyaXR5KClgIHRvIGNhbGN1bGF0ZSB0aGUgbmVpZ2hib3Job29kIHB1cml0eS4KClRoaXMgZnVuY3Rpb24gd2lsbCByZXR1cm4gdGhlIGlucHV0dGVkIGRhdGEgZnJhbWUgd2l0aCB0d28gYWRkaXRpb25hbCBjb2x1bW5zOgoKKiBgcHVyaXR5YDogVGhlIG5laWdoYm9yaG9vZCBwdXJpdHkgZm9yIHRoZSBjZWxsCiogYG1heGltdW1fbmVpZ2hib3JgOiBUaGUgY2x1c3RlciB3aXRoIHRoZSBoaWdoZXN0IHByb3BvcnRpb24gb2Ygb2JzZXJ2YXRpb25zIG5laWdoYm9yaW5nIHRoZSBjZWxsCgoKYGBge3IgcHVyaXR5fQojIGNhbGN1bGF0ZSB0aGUgbmVpZ2hib3Job29kIHB1cml0eSBmb3IgZWFjaCBjZWxsCnB1cml0eV9yZXN1bHRzIDwtIHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9wdXJpdHkoCiAgcGNhX21hdHJpeCwKICBjbHVzdGVyX3Jlc3VsdHNfZGYKKQoKIyBQcmludCB0aGUgZmlyc3Qgcm93cyBvZiB0aGUgcmVzdWx0aW5nIHRhYmxlCmhlYWQocHVyaXR5X3Jlc3VsdHMpCmBgYAoKCldlIGNhbiB2aXN1YWxpemUgdGhlc2UgcmVzdWx0cyBieSBwbG90dGluZyBwdXJpdHkgY2x1c3RlcnMgYXMgdmlvbGluIHBsb3RzLCBmb3IgZXhhbXBsZToKCmBgYHtyIHZpb2xpbiBwdXJpdHl9CmdncGxvdChwdXJpdHlfcmVzdWx0cykgKwogIGFlcyh4ID0gY2x1c3RlciwgeSA9IHB1cml0eSkgKwogIGdlb21fdmlvbGluKGZpbGwgPSAiZGFya29saXZlZ3JlZW4zIikgKwogIGxhYnMoeCA9ICJDbHVzdGVyIiwgeSA9ICJOZWlnaGJvcmhvb2QgcHVyaXR5IikKYGBgCgojIyMgQ2x1c3RlciBzdGFiaWxpdHkKCkFub3RoZXIgYXBwcm9hY2ggdG8gZXhwbG9yaW5nIGNsdXN0ZXIgcXVhbGl0eSBpcyBob3cgc3RhYmxlIHRoZSBjbHVzdGVycyB0aGVtc2VsdmVzIGFyZSB1c2luZyBib290c3RyYXBwaW5nLgpHaXZlbiBhIHNldCBvZiBvcmlnaW5hbCBjbHVzdGVycywgd2UgY2FuIGNvbXBhcmUgdGhlIGJvb3RzdHJhcHBlZCBjbHVzdGVyIGlkZW50aXRpZXMgdG8gb3JpZ2luYWwgb25lcyB1c2luZyB0aGUgQWRqdXN0ZWQgUmFuZCBJbmRleCAoQVJJKSwgd2hpY2ggbWVhc3VyZXMgdGhlIHNpbWlsYXJpdHkgb2YgdHdvIGRhdGEgY2x1c3RlcmluZ3MuCkFSSSByYW5nZXMgZnJvbSAtMSB0byAxLCB3aGVyZToKCiogQSB2YWx1ZSBvZiAxIGluZGljYXRlcyB0aGV5IGFyZSBjb21wbGV0ZWx5IG92ZXJsYXBwaW5nCiogQSB2YWx1ZSBvZiAtMSBpbmRpY2F0ZXMgdGhleSBhcmUgY29tcGxldGVseSBkaXN0aW5jdAoqIEEgdmFsdWUgb2YgMCBpbmRpY2F0ZXMgYSByYW5kb20gcmVsYXRpb25zaGlwCgpXZSBleHBlY3QgdGhhdCBoaWdobHkgc3RhYmxlIGNsdXN0ZXJpbmdzIGhhdmUgQVJJIHZhbHVlcyBjbG9zZXIgdG8gMSBhY3Jvc3MgYSBzZXQgb2YgYm9vdHN0cmFwIHJlcGxpY2F0ZXMuCgpZb3UgY2FuIHJlYWQgbW9yZSBhYm91dCB0aGUgQWRqdXN0ZWQgUmFuZCBJbmRleCBmcm9tIHRoZSBbX09yY2hlc3RyYXRpbmcgU2luZ2xlIENlbGwgQW5hbHlzaXMgd2l0aCBCaW9jb25kdWN0b3JfIGJvb2tdKGh0dHBzOi8vYmlvY29uZHVjdG9yLm9yZy9ib29rcy9yZWxlYXNlL09TQ0EuYWR2YW5jZWQvY2x1c3RlcmluZy1yZWR1eC5odG1sI2FkanVzdGVkLXJhbmQtaW5kZXgpLgoKV2UnbGwgdXNlIHRoZSBmdW5jdGlvbiBgck9wZW5TY1BDQTo6Y2FsY3VsYXRlX3N0YWJpbGl0eSgpYCB0byBjYWxjdWxhdGUgdGhlIGNsdXN0ZXIgc3RhYmlsaXR5LgpCeSBkZWZhdWx0LCB0aGlzIGZ1bmN0aW9uIHBlcmZvcm1zIDIwIGJvb3RzdHJhcCByZXBsaWNhdGVzLCBidXQgdGhpcyBjYW4gYmUgY3VzdG9taXplZCB1c2luZyB0aGUgYXJndW1lbnQgYHJlcGxpY2F0ZXNgLgoKVGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiBhIGRhdGEgZnJhbWUgd2l0aCBjb2x1bW5zIGByZXBsaWNhdGVgLCBgYXJpYCwgYW5kIGFkZGl0aW9uYWwgY29sdW1ucyBmb3IgdGhlIGNsdXN0ZXJpbmcgcGFyYW1ldGVycyB1c2VkIHdoZW4gY2FsY3VsYXRpbmcgYm9vdHN0cmFwIGNsdXN0ZXJzLgoKYGBge3Igc3RhYmlsaXR5LCB3YXJuaW5nPUZBTFNFfQojIGNhbGN1bGF0ZSB0aGUgc3RhYmlsaXR5IG9mIGNsdXN0ZXJzCnN0YWJpbGl0eV9yZXN1bHRzIDwtIHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9zdGFiaWxpdHkoCiAgcGNhX21hdHJpeCwKICBjbHVzdGVyX3Jlc3VsdHNfZGYKKQoKIyBwcmludCB0aGUgcmVzdWx0CnN0YWJpbGl0eV9yZXN1bHRzCmBgYAoKV2UgY2FuIHZpc3VhbGl6ZSB0aGVzZSByZXN1bHRzIGJ5IHBsb3R0aW5nIHN0YWJpbGl0eSBhcyBhIGRlbnNpdHkgcGxvdCwgZm9yIGV4YW1wbGU6CgpgYGB7ciBhcmkgZGVuc2l0eX0KZ2dwbG90KHN0YWJpbGl0eV9yZXN1bHRzKSArCiAgYWVzKHggPSBhcmkpICsKICBnZW9tX2RlbnNpdHkoY29sb3IgPSAiZ3JleTMwIiwgZmlsbCA9ICJsaWdodHNsYXRlYmx1ZSIpICsKICBsYWJzKHggPSAiQWRqdXN0ZWQgcmFuZCBpbmRleCBhY3Jvc3MgYm9vdHN0cmFwIHJlcGxpY2F0ZXMiKQpgYGAKCgojIyMjIFVzaW5nIG5vbi1kZWZhdWx0IGNsdXN0ZXJpbmcgcGFyYW1ldGVycwoKV2hlbiBjYWxjdWxhdGluZyBib290c3RyYXAgY2x1c3RlcnMsIGByT3BlblNjUENBOjpjYWxjdWxhdGVfc3RhYmlsaXR5KClgIHVzZXMgYHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9jbHVzdGVycygpYCB3aXRoIGRlZmF1bHQgcGFyYW1ldGVycy4KSWYgeW91ciBvcmlnaW5hbCBjbHVzdGVycyB3ZXJlIG5vdCBjYWxjdWxhdGVkIHdpdGggdGhlc2UgZGVmYXVsdHMsIHlvdSBzaG91bGQgcGFzcyB0aG9zZSBjdXN0b21pemVkIHZhbHVlcyBpbnRvIHRoaXMgZnVuY3Rpb24gYXMgd2VsbCB0byBlbnN1cmUgYSBmYWlyIGNvbXBhcmlzb24gYmV0d2VlbiB5b3VyIG9yaWdpbmFsIGNsdXN0ZXJzIGFuZCB0aGUgYm9vdHN0cmFwIGNsdXN0ZXJzLgoKCmBgYHtyIHN0YWJpbGl0eSBjdXN0b20gcGFyYW1ldGVyc30KIyBDYWxjdWxhdGUgY2x1c3RlcnMgd2l0aCBub24tZGVmYXVsdCBwYXJhbWV0ZXJzCmNsdXN0ZXJfZGZfbGVpZGVuIDwtIHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9jbHVzdGVycygKICBwY2FfbWF0cml4LAogIGFsZ29yaXRobSA9ICJsZWlkZW4iLAogIHJlc29sdXRpb24gPSAwLjUsCiAgbm4gPSAxNQopCgojIE5vdywgcGFzcyBpbiB0aGUgc2FtZSBhcmd1bWVudHMgY3VzdG9taXppbmcgcGFyYW1ldGVycyBoZXJlCnN0YWJpbGl0eV9yZXN1bHRzX2xlaWRlbiA8LSByT3BlblNjUENBOjpjYWxjdWxhdGVfc3RhYmlsaXR5KAogIHBjYV9tYXRyaXgsCiAgY2x1c3Rlcl9kZl9sZWlkZW4sCiAgYWxnb3JpdGhtID0gImxlaWRlbiIsCiAgcmVzb2x1dGlvbiA9IDAuNSwKICBubiA9IDE1CikKYGBgCgoKIyMgV29ya2luZyB3aXRoIG9iamVjdHMgZGlyZWN0bHkKCkFzIHByZXNlbnRlZCBhYm92ZSwgYHJPcGVuU2NQQ0FgIGNsdXN0ZXJpbmcgZnVuY3Rpb25zIHRha2UgYSBQQ0EgbWF0cml4IHdpdGggcm93IG5hbWVzIHJlcHJlc2VudGluZyB1bmlxdWUgY2VsbCBpZHMgYXMgdGhlaXIgZmlyc3QgYXJndW1lbnQuCgpJbnN0ZWFkIG9mIGEgbWF0cml4LCB5b3UgY2FuIGFsdGVybmF0aXZlbHkgcGFzcyBpbiBhbiBTQ0Ugb3IgU2V1cmF0IG9iamVjdCB0aGF0IGNvbnRhaW5zIGEgbWF0cml4LgoKV2Ugc2hvdyBhbiBleGFtcGxlIG9mIHRoaXMgYmVsb3cgd2l0aCBhbmQgU0NFIG9iamVjdCBhbmQgYHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9jbHVzdGVycygpYCwgYnV0IHRoaXMgd2lsbCBhbHNvIHdvcmsgZm9yIGFueSBvZiB0aGUgZXZhbHVhdGlvbiBmdW5jdGlvbnMgYXMgd2VsbCBhbmQgaGFzIHRoZSBzYW1lIHN5bnRheCBmb3IgU2V1cmF0IG9iamVjdHMuCgpgYGB7ciBydW4gb24gc2NlfQojIENhbGN1bGF0ZSBjbHVzdGVycyBmcm9tIGFuIFNDRSBvYmplY3QgdXNpbmcgZGVmYXVsdCBwYXJhbWV0ZXJzCmNsdXN0ZXJfcmVzdWx0c19kZiA8LSByT3BlblNjUENBOjpjYWxjdWxhdGVfY2x1c3RlcnMoc2NlKQpjbHVzdGVyX3Jlc3VsdHNfZGYKYGBgCgoKYHJPcGVuU2NQQ0FgIGFzc3VtZXMgdGhhdCB0aGUgUENBIG1hdHJpeCBpcyBuYW1lZCBgUENBYCBpbiBTQ0Ugb2JqZWN0cywgYW5kIGBwY2FgIGluIFNldXJhdCBvYmplY3RzLgpJZiB0aGUgUENBIG1hdHJpeCB5b3Ugd2FudCB0byB1c2UgaW4gdGhlIG9iamVjdCBoYXMgYSBkaWZmZXJlbnQgbmFtZSwgeW91IGNhbiBwcm92aWRlIHRoZSBhcmd1bWVudCBgcGNfbmFtZWAuCgoKIyMgQ2FsY3VsYXRpbmcgUUMgbWV0cmljcyBvbiBleGlzdGluZyBjbHVzdGVycwoKSWYgeW91IGFscmVhZHkgaGF2ZSBjbHVzdGVyaW5nIHJlc3VsdHMgY2FsY3VsYXRlZCB3aXRoIG90aGVyIHRvb2xzLCB5b3UgY2FuIHN0aWxsIHVzZSB0aGUgYHJPcGVuU2NQQ0FgIGZ1bmN0aW9ucyB0byBldmFsdWF0ZSB5b3VyIGNsdXN0ZXJzLgoKSW4gdGhpcyBzZWN0aW9uLCB3ZSdsbCBwcmVzZW50IGV4YW1wbGVzIG9mIGhvdyB5b3UgY2FuIGNhbGN1bGF0ZSB0aGUgc2lsaG91ZXR0ZSB3aWR0aCwgbmVpZ2hib3Job29kIHB1cml0eSwgYW5kIGNsdXN0ZXIgc3RhYmlsaXR5IGZyb20gZXhpc3RpbmcgY2x1c3RlciBhc3NpZ25tZW50cyB3aXRoaW4gb2JqZWN0cy4KCiMjIyBFdmFsdWF0aW5nIFNldXJhdCBjbHVzdGVycwoKSWYgeW91IGFyZSBhbmFseXppbmcgeW91ciBkYXRhIHdpdGggYSBTZXVyYXQgcGlwZWxpbmUgdGhhdCBpbmNsdWRlcyBjYWxjdWxhdGluZyBjbHVzdGVycywgeW91IGNhbiB1c2UgYHJPcGVuU2NQQ0FgIHRvIGV2YWx1YXRlIHRoZW0uCgpUbyBkZW1vbnN0cmF0ZSB0aGlzLCB3ZSdsbCBjb252ZXJ0IG91ciBTQ0Ugb2JqZWN0IHRvIGEgU2V1cmF0IHVzaW5nIHRoZSBmdW5jdGlvbiBgck9wZW5TY1BDQTo6c2NlX3RvX3NldXJhdCgpYC4KVGhlbiwgd2UnbGwgdXNlIGEgc2ltcGxlIFNldXJhdCBwaXBlbGluZSB0byBvYnRhaW4gY2x1c3RlcnMuCgpgYGB7ciBzY2UgdG8gc2V1cmF0LCBtZXNzYWdlID0gRkFMU0V9CiMgQ29udmVydCB0aGUgU0NFIHRvIGEgU2V1cmF0IG9iamVjdCB1c2luZyByT3BlblNjUENBCnNldXJhdF9vYmogPC0gck9wZW5TY1BDQTo6c2NlX3RvX3NldXJhdChzY2UpCgojIENhbGN1bGF0ZSBjbHVzdGVycyB3aXRoIFNldXJhdCB1c2luZyBhIHN0YW5kYXJkIFNldXJhdCBwaXBlbGluZSwgZm9yIGV4YW1wbGUKc2V1cmF0X29iaiA8LSBzZXVyYXRfb2JqIHw+CiAgU0NUcmFuc2Zvcm0oKSB8PgogIFJ1blBDQSgpIHw+CiAgRmluZE5laWdoYm9ycygpIHw+CiAgRmluZENsdXN0ZXJzKCkKCnNldXJhdF9vYmoKYGBgCgoKVG8gY2FsY3VsYXRlIFFDIG1ldHJpY3Mgb24gdGhlc2UgY2x1c3RlcnMsIHdlJ2xsIG5lZWQgdG8gY3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIGNvbHVtbnMgYGNlbGxfaWRgIGFuZCBgY2x1c3RlcmA6CgpgYGB7ciBwcmVwYXJlIHNldXJhdCBpbnB1dH0KIyBDcmVhdGUgYSBkYXRhIGZyYW1lIGZvciBpbnB1dApzZXVyYXRfY2x1c3Rlcl9kZiA8LSBkYXRhLmZyYW1lKAogIGNlbGxfaWQgPSBjb2xuYW1lcyhzZXVyYXRfb2JqKSwKICBjbHVzdGVyID0gc2V1cmF0X29iaiRzZXVyYXRfY2x1c3RlcnMKKQoKaGVhZChzZXVyYXRfY2x1c3Rlcl9kZikKYGBgCgpOb3csIHdlIGNhbiBydW4gYHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9zaWxob3VldHRlKClgIGFuZCBgck9wZW5TY1BDQTo6Y2FsY3VsYXRlX3B1cml0eSgpYCB1c2luZyB0aGlzIGRhdGEgZnJhbWUgYW5kIHRoZSBTZXVyYXQgb2JqZWN0OgoKYGBge3Igc2V1cmF0IHNpbGhvdWV0dGV9CnNldXJhdF9zaWxob3VldHRlX2RmIDwtIHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9zaWxob3VldHRlKAogIHNldXJhdF9vYmosCiAgc2V1cmF0X2NsdXN0ZXJfZGYKKQpgYGAKCmBgYHtyIHNldXJhdCBwdXJpdHl9CnNldXJhdF9wdXJpdHlfZGYgPC0gck9wZW5TY1BDQTo6Y2FsY3VsYXRlX3B1cml0eSgKICBzZXVyYXRfb2JqLAogIHNldXJhdF9jbHVzdGVyX2RmCikKYGBgCgpXZSBkbyBub3QgcmVjb21tZW5kIHVzaW5nIGByT3BlblNjUENBOjpjYWxjdWxhdGVfc3RhYmlsaXR5KClgIG9uIFNldXJhdCBjbHVzdGVycyBkdWUgdG8gZGlmZmVyZW5jZXMgaW4gdGhlIHVuZGVybHlpbmcgY2x1c3RlcmluZyBhcHByb2FjaCBiZXR3ZWVuIFNldXJhdCBhbmQgdGhlIGBibHVzdGVyYCBwYWNrYWdlIHdoaWNoIGByT3BlblNjUENBYCB1c2VzLgoKIyMjIEV2YWx1YXRpbmcgU2NQQ0EgY2x1c3RlcnMKClNjUENBIGNlbGwgbWV0YWRhdGEgYWxyZWFkeSBjb250YWlucyBhIGNvbHVtbiBjYWxsZWQgYGNsdXN0ZXJgIHdpdGggcmVzdWx0cyBmcm9tIGFuIGF1dG9tYXRlZCBjbHVzdGVyaW5nLgpUaGVzZSBjbHVzdGVycyB3ZXJlIGNhbGN1bGF0ZWQgdXNpbmcgYGJsdXN0ZXJgLCB0aGUgc2FtZSB0b29sIHRoYXQgYHJPcGVuU2NQQ0FgIHVzZXMuClRoZSBzcGVjaWZpY2F0aW9ucyB1c2VkIGZvciB0aGlzIGNsdXN0ZXJpbmcgYXJlIHN0b3JlZCBpbiB0aGUgU0NFIG9iamVjdCdzIG1ldGFkYXRhLCBhcyBmb2xsb3dzOyBub3RlIHRoYXQgYWxsIG90aGVyIGNsdXN0ZXJpbmcgcGFyYW1ldGVycyB3ZXJlIGxlZnQgYXQgdGhlaXIgZGVmYXVsdCB2YWx1ZXMuCgoqIGBtZXRhZGF0YShzY2UpJGNsdXN0ZXJfYWxnb3JpdGhtYDogVGhlIGNsdXN0ZXJpbmcgYWxnb3JpdGhtIHVzZWQKKiBgbWV0YWRhdGEoc2NlKSRjbHVzdGVyX3dlaWdodGluZ2A6IFRoZSB3ZWlnaHRpbmcgc2NoZW1lIHVzZWQKKiBgbWV0YWRhdGEoc2NlKSRjbHVzdGVyX25uYDogVGhlIG51bWJlciBvZiBuZWFyZXN0IG5laWdoYm9ycyB1c2VkCgpZb3UgY2FuIHNlZSBhbGwgdGhlaXIgdmFsdWVzIGhlcmU6CgoKYGBge3IgZXh0cmFjdCBjbHVzdGVyIHBhcmFtc30KIyBQcmludCBjbHVzdGVyaW5nIHNwZWNpZmljYXRpb25zCm1ldGFkYXRhKHNjZSlbYygiY2x1c3Rlcl9hbGdvcml0aG0iLCAiY2x1c3Rlcl93ZWlnaHRpbmciLCAiY2x1c3Rlcl9ubiIpXQpgYGAKCgpJbiB0aGlzIGV4YW1wbGUsIHdlJ2xsIHNob3cgaG93IHRvIHVzZSB0aGUgY2x1c3RlciBldmFsdWF0aW9uIGZ1bmN0aW9ucyBvbiB0aGVzZSBjbHVzdGVycy4KClRvIGJlZ2luLCB3ZSdsbCBwcmVwYXJlIGEgZGF0YSBmcmFtZSB3aXRoIHR3byBjb2x1bW5zOiBgY2VsbF9pZGAgY29udGFpbmluZyBjZWxsIGJhcmNvZGVzLCBhbmQgYGNsdXN0ZXJgIGNvbnRhaW5pbmcgdGhlIGNsdXN0ZXIgaWRlbnRpdGllcy4KCmBgYHtyIHByZXBhcmUgc2NwY2EgZGF0YSBmcmFtZX0Kc2NwY2FfY2x1c3Rlcl9kZiA8LSBkYXRhLmZyYW1lKAogIGNlbGxfaWQgPSBjb2xuYW1lcyhzY2UpLAogIGNsdXN0ZXIgPSBzY2UkY2x1c3RlcgopCgpoZWFkKHNjcGNhX2NsdXN0ZXJfZGYpCmBgYAoKV2UgY2FuIHJ1biBldmFsdWF0aW9uIGZ1bmN0aW9ucyB1c2luZyB0aGlzIGRhdGEgZnJhbWUgYW5kIHRoZSBTQ0Ugb2JqZWN0LgoKYGBge3Igc2NwY2Egc2lsaG91ZXR0ZX0KIyBDYWxjdWxhdGUgc2lsaG91ZXR0ZSB3aWR0aApzY3BjYV9zaWxob3VldHRlX2RmIDwtIHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9zaWxob3VldHRlKAogIHNjZSwKICBzY3BjYV9jbHVzdGVyX2RmCikKYGBgCgpgYGB7ciBzY3BjYSBwdXJpdHl9CiMgQ2FsY3VsYXRlIG5laWdoYm9yaG9vZCBwdXJpdHkKc2NwY2FfcHVyaXR5X2RmIDwtIHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9wdXJpdHkoCiAgc2NlLAogIHNjcGNhX2NsdXN0ZXJfZGYKKQpgYGAKCldoZW4gcnVubmluZyBgck9wZW5TY1BDQTo6Y2FsY3VsYXRlX3N0YWJpbGl0eSgpYCwgd2UnbGwgc3BlY2lmeSB0aGUgc2FtZSBwYXJhbWV0ZXJzIG9yaWdpbmFsbHkgdXNlZCB0byBidWlsZCB0aGUgY2x1c3RlcnMgYnkgZXh0cmFjdGluZyB0aGVtIGZyb20gdGhlIG1ldGFkYXRhLgpXZSdsbCBuZWVkIHRvIGVuc3VyZSB0aGUgcHJvdmlkZWQgYXJndW1lbnRzIGFyZSBsb3dlcmNhc2UsIGFzIHdlbGwuCgpHZW5lcmFsbHkgc3BlYWtpbmcsIHdlIG9ubHkgcmVjb21tZW5kIGV2YWx1YXRpbmcgY2x1c3RlcnMgd2l0aCBgck9wZW5TY1BDQTo6Y2FsY3VsYXRlX3N0YWJpbGl0eSgpYCBpZiB5b3Uga25vdyB0aGUgb3JpZ2luYWwgcGFyYW1ldGVycyB1c2VkLgoKCmBgYHtyIHNjcGNhIHN0YWJpbGl0eX0Kc2NwY2Ffc3RhYmlsaXR5X2RmIDwtIHJPcGVuU2NQQ0E6OmNhbGN1bGF0ZV9zdGFiaWxpdHkoCiAgc2NlLAogIHNjcGNhX2NsdXN0ZXJfZGYsCiAgIyBwcm92aWRlIFNjUENBIGNsdXN0ZXJpbmcgcGFyYW1ldGVycyBieSBleHRyYWN0aW5nIGZyb20gdGhlIFNDRSBtZXRhZGF0YQogIGFsZ29yaXRobSA9IHRvbG93ZXIobWV0YWRhdGEoc2NlKSRjbHVzdGVyX2FsZ29yaXRobSksCiAgd2VpZ2h0aW5nID0gdG9sb3dlcihtZXRhZGF0YShzY2UpJGNsdXN0ZXJfd2VpZ2h0aW5nKSwKICBubiA9IG1ldGFkYXRhKHNjZSkkY2x1c3Rlcl9ubgopCmBgYAoKCiMjIFNhdmluZyBjbHVzdGVyaW5nIHJlc3VsdHMKClJlc3VsdHMgY2FuIGVpdGhlciBiZSBkaXJlY3RseSBleHBvcnRlZCBhcyBhIFRTViBmaWxlIChlLmcuLCB3aXRoIGByZWFkcjo6d3JpdGVfdHN2KClgKSwgb3IgeW91IGNhbiBhZGQgdGhlIHJlc3VsdHMgaW50byB5b3VyIFNDRSBvciBTZXVyYXQgb2JqZWN0LgpUaGUgc3Vic2VxdWVudCBleGFtcGxlcyB3aWxsIGRlbW9uc3RyYXRlIHNhdmluZyB0aGUgY2x1c3RlciBhc3NpZ25tZW50cyBzdG9yZWQgaW4gYGNsdXN0ZXJfcmVzdWx0c19kZiRjbHVzdGVyYCB0byBhbiBTQ0UgYW5kIGEgU2V1cmF0IG9iamVjdC4KCl9BIHdvcmQgb2YgY2F1dGlvbiFfCk9iamVjdHMgZnJvbSB0aGUgU2NQQ0EgUG9ydGFsIGFscmVhZHkgY29udGFpbiBhIGNvbHVtbiBjYWxsZWQgYGNsdXN0ZXJgIHdpdGggcmVzdWx0cyBmcm9tIGFuIGF1dG9tYXRlZCBjbHVzdGVyaW5nLgpUaGVzZSBhdXRvbWF0aWMgY2x1c3RlcnMgd2VyZSBub3QgZXZhbHVhdGVkLCBhbmQgdGhlaXIgcGFyYW1ldGVycyB3ZXJlIG5vdCBvcHRpbWl6ZWQgZm9yIGFueSBnaXZlbiBsaWJyYXJ5LgpUbyBhdm9pZCBhbWJpZ3VpdHkgYmV0d2VlbiB0aGUgZXhpc3RpbmcgYW5kIG5ldyBjbHVzdGVyaW5nIHJlc3VsdHMsIHdlJ2xsIG5hbWUgdGhlIG5ldyBjb2x1bW4gYHJvcGVuc2NwY2FfY2x1c3RlcmAuCgojIyMgU2F2aW5nIHJlc3VsdHMgdG8gYW4gU0NFIG9iamVjdAoKV2UgY2FuIGFkZCBjb2x1bW5zIHRvIGFuIFNDRSBvYmplY3QncyBgY29sRGF0YWAgdGFibGUgYnkgZGlyZWN0bHkgY3JlYXRpbmcgYSBjb2x1bW4gaW4gdGhlIG9iamVjdCB3aXRoIGAkYC4KQmVmb3JlIHdlIGRvIHNvLCB3ZSdsbCBjb25maXJtIHRoYXQgdGhlIGNsdXN0ZXJzIGFyZSBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGUgU0NFIG9iamVjdCBieSBjb21wYXJpbmcgY2VsbCBpZHM6CgpgYGB7ciBjaGVjayBzY2Ugb3JkZXJ9CmFsbC5lcXVhbCgKICBjb2xuYW1lcyhzY2UpLAogIGNsdXN0ZXJfcmVzdWx0c19kZiRjZWxsX2lkCikKYGBgCgpgYGB7ciBhZGQgdG8gc2NlfQojIEFkZCBjbHVzdGVyIHJlc3VsdHMgdG8gdGhlIGNvbERhdGEKc2NlJHJvcGVuc2NwY2FfY2x1c3RlciA8LSBjbHVzdGVyX3Jlc3VsdHNfZGYkY2x1c3RlcgpgYGAKCiMjIyBTYXZpbmcgcmVzdWx0cyB0byBhIFNldXJhdCBvYmplY3QKCgpXZSBjYW4gYWRkIGNvbHVtbnMgdG8gYW4gU2V1cmF0IG9iamVjdCdzIGNlbGwgbWV0YWRhdGEgdGFibGUgYnkgZGlyZWN0bHkgY3JlYXRpbmcgYSBjb2x1bW4gaW4gdGhlIG9iamVjdCB3aXRoIGAkYCAobm90ZSB0aGF0IHlvdSBjYW4gYWxzbyB1c2UgdGhlIFNldXJhdCBmdW5jdGlvbiBgQWRkTWV0YURhdGEoKWApLgpCZWZvcmUgd2UgZG8gc28sIHdlJ2xsIGNvbmZpcm0gdGhhdCB0aGUgY2x1c3RlcnMgYXJlIGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZSBTZXVyYXQgb2JqZWN0IGJ5IGNvbXBhcmluZyBjZWxsIGlkczoKCgpgYGB7ciBjaGVjayBzZXVyYXQgb3JkZXJ9CmFsbC5lcXVhbCgKICBjb2xuYW1lcyhzZXVyYXRfb2JqKSwKICBjbHVzdGVyX3Jlc3VsdHNfZGYkY2VsbF9pZAopCmBgYAoKYGBge3IgYWRkIHRvIHNldXJhdH0KIyBBZGQgY2x1c3RlciByZXN1bHRzIHRvIHRoZSBjZWxsIG1ldGFkYXRhCnNldXJhdF9vYmokcm9wZW5zY3BjYV9jbHVzdGVyIDwtIGNsdXN0ZXJfcmVzdWx0c19kZiRjbHVzdGVyCmBgYAoKCiMjIFNlc3Npb24gSW5mbwoKYGBge3Igc2Vzc2lvbiBpbmZvfQojIHJlY29yZCB0aGUgdmVyc2lvbnMgb2YgdGhlIHBhY2thZ2VzIHVzZWQgaW4gdGhpcyBhbmFseXNpcyBhbmQgb3RoZXIgZW52aXJvbm1lbnQgaW5mb3JtYXRpb24Kc2Vzc2lvbkluZm8oKQpgYGAK