From ab14226cd49ca104dc650f6710e46df0a2c74bbe Mon Sep 17 00:00:00 2001 From: Jaclyn Taroni <19534205+jaclyn-taroni@users.noreply.github.com> Date: Wed, 7 Aug 2024 18:18:29 +0000 Subject: [PATCH 1/3] Add a magic files doc for RNA-seq --- RNA-seq/setup/magic-files.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 RNA-seq/setup/magic-files.md diff --git a/RNA-seq/setup/magic-files.md b/RNA-seq/setup/magic-files.md new file mode 100644 index 00000000..29755782 --- /dev/null +++ b/RNA-seq/setup/magic-files.md @@ -0,0 +1,15 @@ +# Cooking show magic + +To allow participants who might get bogged down to quickly recover and continue with later notebook sections or exercises, we like to keep a set of output files on hand that they can quickly access as needed. +This document is for tracking where these files are created and stored. + +In general, the files for this module will be stored in `/shared/data/training-data//RNA-seq/`, and should be created before each training using the latest versions of the referenced notebooks. +The sub-path for each file should be the same as that for `training-modules/RNA-seq`. + +Files are listed below by the notebook that produces them: + +- `setup/ref_notebooks/04-nb_cell_line_tximeta.Rmd` (participants create their own notebook for this step) + - `data/NB-cell/txi/NB-cell_tximeta.rds` +- `05-nb_cell_line_DESeq2.Rmd` + - `results/NB-cell/NB-cell_DESeq_amplified_v_nonamplified.rds` + - `results/NB-cell/NB-cell_DESeq_amplified_v_nonamplified_results.tsv` From fc6af47346e809f54d6528a10cd59817350208e9 Mon Sep 17 00:00:00 2001 From: Jaclyn Taroni <19534205+jaclyn-taroni@users.noreply.github.com> Date: Wed, 7 Aug 2024 18:26:35 +0000 Subject: [PATCH 2/3] Write a section on dependence on NB DGE notebook --- pathway-analysis/setup/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pathway-analysis/setup/README.md b/pathway-analysis/setup/README.md index 8dfbcaca..3d9eef7c 100644 --- a/pathway-analysis/setup/README.md +++ b/pathway-analysis/setup/README.md @@ -6,6 +6,9 @@ This document provides background for preparing data for use in the guided noteb ⚠️ **The setup of this module relies on data or results prepared as part of other modules.** +For the GSEA notebook, we use differential expression results from the neuroblastoma cell line data generated in `RNA-seq/05-nb_cell_line_DESeq2.Rmd`. +The DGE notebook relies on the output of `tximeta`, which can be generated by running `RNA-seq/setup/ref_notebooks/04-nb_cell_line_tximeta.Rmd` after RNA-seq files have been linked appropriately. + For the GSVA notebook, we use a subset of the OpenPBTA stranded dataset (medulloblastoma samples) that we download and process in `machine-learning/setup`. It also depends on a step, performed in `machine-learning/03-openpbta_PLIER.Rmd`, where duplicate gene symbols are collapsed to the row that has the highest mean value. ### Data Preparation From cf87c4e111f891d0ee9d34a4ebbe6c57423ae980 Mon Sep 17 00:00:00 2001 From: Jaclyn Taroni <19534205+jaclyn-taroni@users.noreply.github.com> Date: Wed, 7 Aug 2024 18:27:26 +0000 Subject: [PATCH 3/3] Name chunk with head --- .../02-gene_set_enrichment_analysis.Rmd | 3 +- .../02-gene_set_enrichment_analysis.nb.html | 3332 +++++++++++++++-- 2 files changed, 3002 insertions(+), 333 deletions(-) diff --git a/pathway-analysis/02-gene_set_enrichment_analysis.Rmd b/pathway-analysis/02-gene_set_enrichment_analysis.Rmd index 02c08413..3c79f68b 100644 --- a/pathway-analysis/02-gene_set_enrichment_analysis.Rmd +++ b/pathway-analysis/02-gene_set_enrichment_analysis.Rmd @@ -132,8 +132,9 @@ hs_hallmark_df <- msigdbr(species = "Homo sapiens", # Read in the DGE results dge_results_df <- readr::read_tsv(dge_results_file) ``` +Let's take a peek at the contents of this file. -```{r} +```{r head_dge, live = TRUE} head(dge_results_df) ``` diff --git a/pathway-analysis/02-gene_set_enrichment_analysis.nb.html b/pathway-analysis/02-gene_set_enrichment_analysis.nb.html index a46c6641..ea09ec8e 100644 --- a/pathway-analysis/02-gene_set_enrichment_analysis.nb.html +++ b/pathway-analysis/02-gene_set_enrichment_analysis.nb.html @@ -15,39 +15,2657 @@ Pathway analysis: Gene Set Enrichment Analysis (GSEA) - - + + - - - - - - - - - - - - - + + + + + + + + + + + + + + +code{white-space: pre-wrap;} +span.smallcaps{font-variant: small-caps;} +span.underline{text-decoration: underline;} +div.column{display: inline-block; vertical-align: top; width: 50%;} +div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} +ul.task-list{list-style: none;} + - + -

Since this data frame of DGE results includes gene symbols, we do not need to perform any kind of gene identifier conversion. We do, however, need to check for duplicate gene symbols. We can accomplish this with duplicated(), which returns a logical vector (e.g., TRUE or FALSE). The function sum() will count TRUE values as 1s and FALSE as 0s, so using it with duplicated() will count the number of duplicate values.

+

Since this data frame of DGE results includes gene symbols, we do not +need to perform any kind of gene identifier conversion. We do, however, +need to check for duplicate gene symbols. We can accomplish this with +duplicated(), which returns a logical vector (e.g., +TRUE or FALSE). The function +sum() will count TRUE values as 1s and +FALSE as 0s, so using it with duplicated() +will count the number of duplicate values.

- +
sum(duplicated(dge_results_df$gene_symbol))
@@ -501,14 +3129,21 @@

Differential gene expression results

This will cause a problem when we go to run GSEA.

Removing duplicates

-

The GSEA approach requires on discriminating between genes that are in a gene set and those that are not. Practically speaking, gene sets are just collections of gene identifiers! When the function we use for GSEA pre-ranked gets a list with duplicated gene identifiers, it can produce unexpected results.

-

Compared to the total number of genes that are in our results, there are not a lot of duplicates but we’ll still need to make a decision about how to handle them.

-

Let’s get a vector of the duplicated gene symbols so we can use it to explore our filtering steps.

+

The GSEA approach requires on discriminating between genes that are +in a gene set and those that are not. Practically speaking, gene sets +are just collections of gene identifiers! When the function we use for +GSEA pre-ranked gets a list with duplicated gene identifiers, it can +produce unexpected results.

+

Compared to the total number of genes that are in our results, there +are not a lot of duplicates but we’ll still need to make a decision +about how to handle them.

+

Let’s get a vector of the duplicated gene symbols so we can use it to +explore our filtering steps.

- -
duplicated_gene_symbols <- dge_results_df %>%
-  dplyr::filter(duplicated(gene_symbol)) %>%
+
+
duplicated_gene_symbols <- dge_results_df |>
+  dplyr::filter(duplicated(gene_symbol)) |>
   dplyr::pull(gene_symbol)
@@ -516,29 +3151,45 @@

Removing duplicates

Now we’ll look at the values for the the duplicated gene symbols.

- -
dge_results_df %>%
-  dplyr::filter(gene_symbol %in% duplicated_gene_symbols) %>%
+
+
dge_results_df |>
+  dplyr::filter(gene_symbol %in% duplicated_gene_symbols) |>
   dplyr::arrange(gene_symbol)
+
+

We can see that the associated values vary for each row.

-

Let’s keep the gene symbols associated with the higher absolute value of the log2 fold change.

-

Retaining the instance of the gene symbols with the higher absolute value of a gene-level statistic means that we will retain the value that is likely to be more highly- or lowly-ranked or, put another way, the values less likely to be towards the middle of the ranked gene list. We should keep this decision in mind when interpreting our results. For example, if all the duplicate identifiers happened to be in a particular gene set, we may get an overly optimistic view of how perturbed that gene set is because we preferentially selected instances of the identifier that have a higher absolute value of the statistic used for ranking.

-

In the next chunk, we are going to filter out the duplicated rows using the dplyr::distinct() function after sorting by absolute value of the log2 fold change. This will keep the first row with the duplicated value thus keeping the row with the largest absolute value.

+

Let’s keep the gene symbols associated with the higher absolute value +of the log2 fold change.

+

Retaining the instance of the gene symbols with the higher absolute +value of a gene-level statistic means that we will retain the value that +is likely to be more highly- or lowly-ranked or, put another way, the +values less likely to be towards the middle of the ranked gene list. We +should keep this decision in mind when interpreting our results. For +example, if all the duplicate identifiers happened to be in a particular +gene set, we may get an overly optimistic view of how perturbed that +gene set is because we preferentially selected instances of the +identifier that have a higher absolute value of the statistic used for +ranking.

+

In the next chunk, we are going to filter out the duplicated rows +using the dplyr::distinct() function after sorting by +absolute value of the log2 fold change. This will keep the first row +with the duplicated value thus keeping the row with the largest absolute +value.

- -
filtered_dge_df <- dge_results_df %>%
+
+
filtered_dge_df <- dge_results_df |>
   # Sort so that the highest absolute values of the log2 fold change are at the
   # top
-  dplyr::arrange(dplyr::desc(abs(log2FoldChange))) %>%
+  dplyr::arrange(dplyr::desc(abs(log2FoldChange))) |>
   # Filter out the duplicated rows using `dplyr::distinct()`
   dplyr::distinct(gene_symbol, .keep_all = TRUE)
@@ -547,29 +3198,33 @@

Removing duplicates

Let’s see what happened to our duplicate identifiers.

- -
# Subset to & arrange by gene symbols that were duplicated in the original 
+
+
# Subset to & arrange by gene symbols that were duplicated in the original
 # data frame of results
-filtered_dge_df %>%
-  dplyr::filter(gene_symbol %in% duplicated_gene_symbols) %>%
+filtered_dge_df |>
+  dplyr::filter(gene_symbol %in% duplicated_gene_symbols) |>
   dplyr::arrange(gene_symbol)
+
+

Now we’re ready to prep our pre-ranked list for GSEA.

Pre-ranked list

-

The GSEA() function takes a pre-ranked (sorted) named vector of statistics, where the names in the vector are gene identifiers. This is step 1 – gene-level statistics.

+

The GSEA() function takes a pre-ranked (sorted) named +vector of statistics, where the names in the vector are gene +identifiers. This is step 1 – gene-level statistics.

- -
lfc_vector <- filtered_dge_df %>%
+
+
lfc_vector <- filtered_dge_df |>
   # Extract a vector of `log2FoldChange` named by `gene_symbol`
   dplyr::pull(log2FoldChange, name = gene_symbol)
 lfc_vector <- sort(lfc_vector, decreasing = TRUE)
@@ -579,26 +3234,26 @@

Pre-ranked list

Let’s look at the top ranked values.

- +
# Look at first entries of the log2 fold change vector
 head(lfc_vector)
- +
  GAGE12D    GABBR1   FABP5P7  KIAA0355      MNX1    GAGE2A 
-23.620487 23.130046 22.682641 22.562941  6.813764  6.801245 
+23.620487 23.130027 22.682631 22.562940 6.813764 6.801245

And the bottom of the list.

- +
# Look at the last entries of the log2 fold change vector
 tail(lfc_vector)
- +
     MUC15      TFPI2      LENG1       MT1M       DAZ2   CSPG4P4Y 
- -8.017004  -8.768669 -22.754783 -25.318887 -25.444288 -26.095612 
+ -8.017004 -8.768669 -22.754783 -25.318887 -25.444428 -26.095612
@@ -607,10 +3262,12 @@

Pre-ranked list

Run GSEA

Now for the analysis!

-

We can use the GSEA() function to perform GSEA with any generic set of gene sets, but there are several functions for using specific, commonly used gene sets (e.g., gseKEGG()).

+

We can use the GSEA() function to perform GSEA with any +generic set of gene sets, but there are several functions for using +specific, commonly used gene sets (e.g., gseKEGG()).

- +
gsea_results <- GSEA(geneList = lfc_vector,  # ordered ranked gene list
                      minGSSize = 25,  # minimum gene set size
                      maxGSSize = 500,  # maximum gene set set
@@ -620,101 +3277,117 @@ 

Run GSEA

gs_name, gene_symbol))
- -
preparing geneSet collections...
- - -
GSEA analysis...
- - -
Warning in preparePathwaysAndStats(pathways, stats, minSize, maxSize, gseaParam, : There are ties in the preranked stats (0.06% of the list).
-The order of those tied genes will be arbitrary, which may produce unexpected results.
- - -
leading edge analysis...
- - -
done...
- + +
using 'fgsea' for GSEA analysis, please cite Korotkevich et al (2019).
+
+preparing geneSet collections...
+GSEA analysis...
+Warning: There are ties in the preranked stats (0.1% of the list).
+The order of those tied genes will be arbitrary, which may produce unexpected results.leading edge analysis...
+done...
+ -

The warning about ties means that there are multiple genes that have the same log2 fold change value. This percentage is small and unlikely to impact our results. A large number of ties might tell us there’s something wrong with our DGE results (Ballereau et al. 2018).

+

The warning about ties means that there are multiple genes that have +the same log2 fold change value. This percentage is small and unlikely +to impact our results. A large number of ties might tell us there’s +something wrong with our DGE results (Ballereau +et al. 2018).

Let’s take a look at the GSEA results.

- -
View(gsea_results@result %>%
+
+
View(gsea_results@result |>
        dplyr::arrange(dplyr::desc(NES))
 )
-

Normalized enrichment scores (NES) are enrichment scores that are scaled to make gene sets that contain different number of genes comparable.

+

Normalized enrichment scores (NES) are enrichment scores that are +scaled to make gene sets that contain different number of genes +comparable.

Let’s write these results to file.

- -
gsea_results@result %>% readr::write_tsv(gsea_results_file)
+ +
gsea_results@result |> readr::write_tsv(gsea_results_file)

Visualizing GSEA results

-

We can visualize GSEA results for individual pathways or gene sets using enrichplot::gseaplot(). Let’s take a look at 3 different pathways – one with a highly positive NES, one with a highly negative NES, and one that was not a significant result – to get more insight into how ES are calculated.

+

We can visualize GSEA results for individual pathways or gene sets +using enrichplot::gseaplot(). Let’s take a look at 3 +different pathways – one with a highly positive NES, one with a highly +negative NES, and one that was not a significant result – to get more +insight into how ES are calculated.

Highly Positive NES

-

The gene set HALLMARK_MYC_TARGETS_V1 had high positive log2 fold changes. Recall a positive log2 fold change means a it had a higher expression value in MYCN amplified cell lines.

+

The gene set HALLMARK_MYC_TARGETS_V1 had high positive +log2 fold changes. Recall a positive log2 fold change means a it had a +higher expression value in MYCN amplified cell lines.

- +
enrichplot::gseaplot(gsea_results,
                      geneSetID = "HALLMARK_MYC_TARGETS_V1",
                      title = "HALLMARK_MYC_TARGETS_V1",
                      color.line = "#0066FF")
- -

+ +

-

Notice how the genes that are in the gene set, indicated by the black bars, tend to be on the left side of the graph indicating that they have positive gene-level scores.

+

Notice how the genes that are in the gene set, indicated by the black +bars, tend to be on the left side of the graph indicating that they have +positive gene-level scores.

Highly Negative NES

-

The gene set HALLMARK_INTERFERON_ALPHA_RESPONSE had a highly negative NES.

+

The gene set HALLMARK_INTERFERON_ALPHA_RESPONSE had a +highly negative NES.

- +
enrichplot::gseaplot(gsea_results,
                      geneSetID = "HALLMARK_INTERFERON_ALPHA_RESPONSE",
                      title = "HALLMARK_INTERFERON_ALPHA_RESPONSE",
                      color.line = "#0066FF")
- -

+ +

-

This gene set shows the opposite pattern – genes in the pathway tend to be on the right side of the graph.

+

This gene set shows the opposite pattern – genes in the pathway tend +to be on the right side of the graph.

A non-significant result

-

The @results slot will only show gene sets that pass the pvalueCutoff threshold we supplied to GSEA(), but we can plot any gene set so long as we know its name. Let’s look at HALLMARK_P53_PATHWAY, which was not in the results we viewed earlier.

+

The @results slot will only show gene sets that pass the +pvalueCutoff threshold we supplied to GSEA(), +but we can plot any gene set so long as we know its name. Let’s look at +HALLMARK_P53_PATHWAY, which was not in the results we +viewed earlier.

- +
enrichplot::gseaplot(gsea_results,
                      geneSetID = "HALLMARK_P53_PATHWAY",
                      title = "HALLMARK_P53_PATHWAY",
                      color.line = "#0066FF")
- -

+ +

-

Genes in the pathway are distributed more evenly throughout the ranked list, resulting in a more “middling” score.

-

Note: The plots returned by enrichplot::gseaplot are ggplots, so we could use ggplot2::ggsave() to save them to file if we wanted to.

+

Genes in the pathway are distributed more evenly throughout the +ranked list, resulting in a more “middling” score.

+

Note: The plots returned by enrichplot::gseaplot are +ggplots, so we could use ggplot2::ggsave() to save them to +file if we wanted to.

@@ -722,69 +3395,61 @@

A non-significant result

Session Info

- +
sessionInfo()
- -
R version 4.0.3 (2020-10-10)
-Platform: x86_64-pc-linux-gnu (64-bit)
-Running under: Ubuntu 20.04 LTS
+
+
R version 4.4.0 (2024-04-24)
+Platform: x86_64-pc-linux-gnu
+Running under: Ubuntu 22.04.4 LTS
 
 Matrix products: default
-BLAS/LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.8.so
+BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
+LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so;  LAPACK version 3.10.0
 
 locale:
- [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
- [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
- [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=C             
- [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
- [9] LC_ADDRESS=C               LC_TELEPHONE=C            
-[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
+ [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8        LC_COLLATE=C.UTF-8     LC_MONETARY=C.UTF-8   
+ [6] LC_MESSAGES=C.UTF-8    LC_PAPER=C.UTF-8       LC_NAME=C              LC_ADDRESS=C           LC_TELEPHONE=C        
+[11] LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   
+
+time zone: Etc/UTC
+tzcode source: system (glibc)
 
 attached base packages:
 [1] stats     graphics  grDevices utils     datasets  methods   base     
 
 other attached packages:
-[1] msigdbr_7.2.1          clusterProfiler_3.18.1 optparse_1.6.6        
+[1] msigdbr_7.5.1          clusterProfiler_4.12.0
 
 loaded via a namespace (and not attached):
- [1] enrichplot_1.10.2    bit64_4.0.5          RColorBrewer_1.1-2  
- [4] tools_4.0.3          R6_2.5.0             DBI_1.1.1           
- [7] BiocGenerics_0.36.0  colorspace_2.0-0     tidyselect_1.1.0    
-[10] gridExtra_2.3        bit_4.0.4            compiler_4.0.3      
-[13] cli_2.2.0            Biobase_2.50.0       scatterpie_0.1.5    
-[16] labeling_0.4.2       shadowtext_0.0.7     scales_1.1.1        
-[19] readr_1.4.0          stringr_1.4.0        digest_0.6.27       
-[22] rmarkdown_2.6        DOSE_3.16.0          pkgconfig_2.0.3     
-[25] htmltools_0.5.1.1    fastmap_1.1.0        rlang_0.4.10        
-[28] rstudioapi_0.13      RSQLite_2.2.3        farver_2.0.3        
-[31] generics_0.1.0       jsonlite_1.7.2       BiocParallel_1.24.1 
-[34] GOSemSim_2.16.1      dplyr_1.0.3          magrittr_2.0.1      
-[37] GO.db_3.12.1         Matrix_1.3-2         fansi_0.4.2         
-[40] Rcpp_1.0.6           munsell_0.5.0        S4Vectors_0.28.1    
-[43] viridis_0.5.1        lifecycle_0.2.0      stringi_1.5.3       
-[46] yaml_2.2.1           ggraph_2.0.4         MASS_7.3-53         
-[49] plyr_1.8.6           qvalue_2.22.0        grid_4.0.3          
-[52] blob_1.2.1           parallel_4.0.3       ggrepel_0.9.1       
-[55] DO.db_2.9            crayon_1.3.4         lattice_0.20-41     
-[58] graphlayouts_0.7.1   cowplot_1.1.1        splines_4.0.3       
-[61] hms_1.0.0            ps_1.5.0             knitr_1.30          
-[64] pillar_1.4.7         fgsea_1.16.0         igraph_1.2.6        
-[67] reshape2_1.4.4       stats4_4.0.3         fastmatch_1.1-0     
-[70] glue_1.4.2           evaluate_0.14        downloader_0.4      
-[73] data.table_1.13.6    BiocManager_1.30.10  vctrs_0.3.6         
-[76] tweenr_1.0.1         gtable_0.3.0         getopt_1.20.3       
-[79] purrr_0.3.4          polyclip_1.10-0      tidyr_1.1.2         
-[82] assertthat_0.2.1     cachem_1.0.1         ggplot2_3.3.3       
-[85] xfun_0.20            ggforce_0.3.2        tidygraph_1.2.0     
-[88] viridisLite_0.3.0    tibble_3.0.5         rvcheck_0.1.8       
-[91] AnnotationDbi_1.52.0 memoise_1.1.0        IRanges_2.24.1      
-[94] ellipsis_0.3.1      
+ [1] DBI_1.2.2 shadowtext_0.1.3 gson_0.1.0 gridExtra_2.3 rlang_1.1.3 + [6] magrittr_2.0.3 DOSE_3.30.0 compiler_4.4.0 RSQLite_2.3.6 png_0.1-8 + [11] vctrs_0.6.5 reshape2_1.4.4 stringr_1.5.1 pkgconfig_2.0.3 crayon_1.5.2 + [16] fastmap_1.1.1 XVector_0.44.0 labeling_0.4.3 ggraph_2.2.1 utf8_1.2.4 + [21] HDO.db_0.99.1 tzdb_0.4.0 enrichplot_1.24.0 UCSC.utils_1.0.0 purrr_1.0.2 + [26] bit_4.0.5 xfun_0.43 zlibbioc_1.50.0 cachem_1.0.8 aplot_0.2.2 + [31] GenomeInfoDb_1.40.0 jsonlite_1.8.8 blob_1.2.4 BiocParallel_1.38.0 tweenr_2.0.3 + [36] parallel_4.4.0 R6_2.5.1 stringi_1.8.3 RColorBrewer_1.1-3 GOSemSim_2.30.0 + [41] knitr_1.46 Rcpp_1.0.12 readr_2.1.5 IRanges_2.38.0 Matrix_1.7-0 + [46] splines_4.4.0 igraph_2.0.3 tidyselect_1.2.1 qvalue_2.36.0 rstudioapi_0.16.0 + [51] viridis_0.6.5 codetools_0.2-20 lattice_0.22-6 tibble_3.2.1 plyr_1.8.9 + [56] Biobase_2.64.0 treeio_1.28.0 withr_3.0.0 KEGGREST_1.44.0 gridGraphics_0.5-1 + [61] scatterpie_0.2.2 polyclip_1.10-6 Biostrings_2.72.0 pillar_1.9.0 ggtree_3.12.0 + [66] stats4_4.4.0 ggfun_0.1.4 generics_0.1.3 vroom_1.6.5 hms_1.1.3 + [71] S4Vectors_0.42.0 ggplot2_3.5.1 munsell_0.5.1 scales_1.3.0 tidytree_0.4.6 + [76] glue_1.7.0 lazyeval_0.2.2 tools_4.4.0 data.table_1.15.4 fgsea_1.30.0 + [81] babelgene_22.9 fs_1.6.4 graphlayouts_1.1.1 fastmatch_1.1-4 tidygraph_1.3.1 + [86] cowplot_1.1.3 grid_4.4.0 tidyr_1.3.1 ape_5.8 AnnotationDbi_1.66.0 + [91] colorspace_2.1-0 nlme_3.1-164 GenomeInfoDbData_1.2.12 patchwork_1.2.0 ggforce_0.4.2 + [96] cli_3.6.2 fansi_1.0.6 viridisLite_0.4.2 dplyr_1.1.4 gtable_0.3.5 +[101] yulab.utils_0.1.4 digest_0.6.35 BiocGenerics_0.50.0 ggrepel_0.9.5 ggplotify_0.1.2 +[106] farver_2.1.1 memoise_2.0.1 lifecycle_1.0.4 httr_1.4.7 GO.db_3.19.1 +[111] bit64_4.0.5 MASS_7.3-60.2
-
LS0tCnRpdGxlOiAiUGF0aHdheSBhbmFseXNpczogR2VuZSBTZXQgRW5yaWNobWVudCBBbmFseXNpcyAoR1NFQSkiCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCmF1dGhvcjogQ0NETCBmb3IgQUxTRgpkYXRlOiAyMDIwCi0tLQoKIyMgT2JqZWN0aXZlcwoKVGhpcyBub3RlYm9vayB3aWxsIGRlbW9uc3RyYXRlIGhvdyB0bzoKCi0gUHJlcGFyZSB0YWJ1bGFyIGRhdGEgb2YgZ2VuZS1sZXZlbCBzdGF0aXN0aWNzIGZvciB1c2Ugd2l0aCBHZW5lIFNldCBFbnJpY2htZW50IEFuYWx5c2lzIChHU0VBKSwgaW5jbHVkaW5nIGhvdyB0byByZW1vdmUgZHVwbGljYXRlIGdlbmUgaWRlbnRpZmllcnMKLSBQZXJmb3JtIEdTRUEgd2l0aCB0aGUgYGNsdXN0ZXJQcm9maWxlcmAgcGFja2FnZQotIFZpc3VhbGl6ZSBHU0VBIHJlc3VsdHMgd2l0aCB0aGUgYGVucmljaHBsb3RgIHBhY2thZ2UKCi0tLQoKSW4gdGhpcyBub3RlYm9vaywgd2Ugd2lsbCBwZXJmb3JtIEdlbmUgU2V0IEVucmljaG1lbnQgQW5hbHlzaXMgKEdTRUEpIG9uIHRoZSBuZXVyb2JsYXN0b21hIGNlbGwgbGluZSBkaWZmZXJlbnRpYWwgZ2VuZSBleHByZXNzaW9uIChER0UpIHJlc3VsdHMgd2UgZ2VuZXJhdGVkIGR1cmluZyB0aGUgUk5BLXNlcSBtb2R1bGUuCgpUbyByZWZyZXNoIG91ciBtZW1vcnksIHdlIGFuYWx5emVkIGRhdGEgZnJvbSBbSGFyZW56YSAqZXQgYWwuKiAoMjAxNyldKGh0dHBzOi8vZG9pLm9yZy8xMC4xMDM4L3NkYXRhLjIwMTcuMzMpIGFuZCBzcGVjaWZpY2FsbHkgdGVzdGVkIGZvciBER0UgYmV0d2VlbiB3aXRoIF9NWUNOXyBhbXBsaWZpZWQgY2VsbCBsaW5lcyBhbmQgbm9uLWFtcGxpZmllZCBjZWxsIGxpbmVzIHVzaW5nIGBERVNlcTJgLgpXZSBoYXZlIGEgdGFibGUgb2YgcmVzdWx0cyB0aGF0IGNvbnRhaW5zIG91ciBsb2cyIGZvbGQgY2hhbmdlcyBhbmQgYWRqdXN0ZWQgcC12YWx1ZXMuCgpHU0VBIGlzIGEgZnVuY3Rpb25hbCBjbGFzcyBzY29yaW5nIChGQ1MpIGFwcHJvYWNoIHRvIHBhdGh3YXkgYW5hbHlzaXMgdGhhdCB3YXMgZmlyc3QgaW50cm9kdWNlZCBpbiBbU3VicmFtYW5pYW4gX2V0IGFsLl8gKDIwMDUpXShodHRwczovL2RvaS5vcmcvMTAuMTA3My9wbmFzLjA1MDY1ODAxMDIpLgpUaGUgcmF0aW9uYWxlIGJlaGluZCBGQ1MgYXBwcm9hY2hlcyBpcyB0aGF0IHNtYWxsIGNoYW5nZXMgaW4gaW5kaXZpZHVhbCBnZW5lcyB0aGF0IHBhcnRpY2lwYXRlIGluIHRoZSBzYW1lIGJpb2xvZ2ljYWwgcHJvY2VzcyBvciBwYXRod2F5IGNhbiBiZSBzaWduaWZpY2FudCBhbmQgb2YgYmlvbG9naWNhbCBpbnRlcmVzdC4KRkNTIG1ldGhvZHMgYXJlIGJldHRlciBzdWl0ZWQgZm9yIGlkZW50aWZ5aW5nIHRoZXNlIHBhdGh3YXlzIHRoYXQgc2hvdyBjb29yZGluYXRlZCBjaGFuZ2VzIHRoYW4gT1JBLgpJbiBPUkEsIHdlIHBpY2sgYSBjdXRvZmYgdGhhdCBfdHlwaWNhbGx5XyBvbmx5IGNhcHR1cmVzIGdlbmVzIHdpdGggbGFyZ2UgaW5kaXZpZHVhbCBjaGFuZ2VzLgoKVGhlcmUgYXJlIDMgZ2VuZXJhbCBzdGVwcyBpbiBGQ1MgbWV0aG9kcyAoW0toYXRyaSBfZXQgYWwuXyAyMDEyXSggaHR0cHM6Ly9kb2kub3JnLzEwLjEzNzEvam91cm5hbC5wY2JpLjEwMDIzNzUpKToKIAoxLiBDYWxjdWxhdGUgYSBnZW5lLWxldmVsIHN0YXRpc3RpYyAod2UnbGwgdXNlIGxvZzIgZm9sZCBjaGFuZ2UgZnJvbSBERVNlcTIgaGVyZSkKMi4gR2VuZS1sZXZlbCBzdGF0aXN0aWNzIGFyZSBhZ2dyZWdhdGVkIGludG8gYSBwYXRod2F5LWxldmVsIHN0YXRpc3RpYwozLiBBc3Nlc3MgdGhlIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSBvZiB0aGUgcGF0aHdheS1sZXZlbCBzdGF0aXN0aWMKCiMjIyMgT3RoZXIgcmVzb3VyY2VzCgoqIEZvciBhbm90aGVyIGV4YW1wbGUgdXNpbmcgYGNsdXN0ZXJQcm9maWxlcmAgZm9yIEdTRUEsIHNlZSBbX0ludHJvIHRvIERHRTogRnVuY3Rpb25hbCBBbmFseXNpcy5fIGZyb20gSGFydmFyZCBDaGFuIEJpb2luZm9ybWF0aWNzIENvcmUgVHJhaW5pbmcuXShodHRwczovL2hiY3RyYWluaW5nLmdpdGh1Yi5pby9ER0Vfd29ya3Nob3AvbGVzc29ucy8wOV9mdW5jdGlvbmFsX2FuYWx5c2lzLmh0bWwpCiogVGhlIHdheSB3ZSdsbCB1c2UgYGNsdXN0ZXJQcm9maWxlcmAgaGVyZSB1c2VzIGBmZ3NlYWAgKEZhc3QgR2VuZSBTZXQgRW5yaWNobWVudCBBbmFseXNpcykgdW5kZXIgdGhlIGhvb2QuCllvdSBjYW4gcmVhZCBtb3JlIGFib3V0IGZnc2VhIGluIFtLb3JvdGtldmljaCBfZXQgYWwuXyAoMjAyMSldKGh0dHBzOi8vZG9pLm9yZy8xMC4xMTAxLzA2MDAxMikuCiogW3JlZmluZS5iaW8gZXhhbXBsZXMgR2VuZSBzZXQgZW5yaWNobWVudCBhbmFseXNpcyAtIFJOQS1zZXFdKGh0dHBzOi8vYWxleHNsZW1vbmFkZS5naXRodWIuaW8vcmVmaW5lYmlvLWV4YW1wbGVzLzAzLXJuYXNlcS9wYXRod2F5LWFuYWx5c2lzX3JuYXNlcV8wMl9nc2VhLmh0bWwpIGZyb20gd2hpY2ggdGhpcyBtYXRlcmlhbCBoYXMgYmVlbiBhZGFwdGVkLgoKIyMgU2V0IHVwCgojIyMgTGlicmFyaWVzCgpgYGB7ciBsaWJyYXJpZXN9CiMgUGFja2FnZSB0byBydW4gR1NFQQpsaWJyYXJ5KGNsdXN0ZXJQcm9maWxlcikKIyBQYWNrYWdlIHRoYXQgY29udGFpbnMgdGhlIE1TaWdEQiBnZW5lIHNldHMgaW4gdGlkeSBmb3JtYXQKbGlicmFyeShtc2lnZGJyKQpgYGAKCiMjIyBEaXJlY3RvcmllcyBhbmQgRmlsZXMKCiMjIyMgRGlyZWN0b3JpZXMKCmBgYHtyfQojIFdoZXJlIHRoZSBER0UgcmVzdWx0cyBhcmUgc3RvcmVkCmlucHV0X2RpciA8LSBmaWxlLnBhdGgoIi4uIiwgIlJOQS1zZXEiLCAicmVzdWx0cyIsICJOQi1jZWxsIikKCiMgV2Ugd2lsbCBjcmVhdGUgYSBkaXJlY3RvcnkgdG8gc3BlY2lmaWNhbGx5IGhvbGQgb3VyIEdTRUEgcmVzdWx0cyBpZiBpdCBkb2VzIAojIG5vdCB5ZXQgZXhpc3QKb3V0cHV0X2RpciA8LSBmaWxlLnBhdGgoInJlc3VsdHMiLCAiTkItY2VsbCIpCmlmICghZGlyLmV4aXN0cyhvdXRwdXRfZGlyKSkgewogIGRpci5jcmVhdGUob3V0cHV0X2RpciwgcmVjdXJzaXZlID0gVFJVRSkKfQpgYGAKCiMjIyMgSW5wdXQgZmlsZXMKCmBgYHtyIGlucHV0X2ZpbGVzfQojIERHRSByZXN1bHRzCmRnZV9yZXN1bHRzX2ZpbGUgPC0gZmlsZS5wYXRoKGlucHV0X2RpciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkItY2VsbF9ERVNlcV9hbXBsaWZpZWRfdl9ub25hbXBsaWZpZWRfcmVzdWx0cy50c3YiKQpgYGAKCiMjIyMgT3V0cHV0IGZpbGVzCgpgYGB7ciBvdXRwdXRfZmlsZXN9CiMgR1NFQSBwYXRod2F5LWxldmVsIHNjb3JlcyBhbmQgc3RhdGlzdGljcwpnc2VhX3Jlc3VsdHNfZmlsZSA8LSBmaWxlLnBhdGgob3V0cHV0X2RpciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOQi1jZWxsX2dzZWFfcmVzdWx0cy50c3YiKQpgYGAKCiMjIEdlbmUgU2V0IEVucmljaG1lbnQgQW5hbHlzaXMKCl9BZGFwdGVkIGZyb20gW3JlZmluZS5iaW8gZXhhbXBsZXNdKGh0dHBzOi8vZ2l0aHViLmNvbS9BbGV4c0xlbW9uYWRlL3JlZmluZWJpby1leGFtcGxlcy9ibG9iLzMzY2RlZmY2NmQ1N2Y5ZmU4ZWU0ZmNiNTE1NmFlYTRhYzJkY2UwN2YvMDMtcm5hc2VxL3BhdGh3YXktYW5hbHlzaXNfcm5hc2VxXzAyX2dzZWEuUm1kKV8KCiFbXShkaWFncmFtcy9zdWJyYW1hbmlhbl9maWcxLmpwZykKCioqRmlndXJlIDEuIFtTdWJyYW1hbmlhbiBfZXQgYWwuXyAoMjAwNSldKGh0dHBzOi8vZG9pLm9yZy8xMC4xMDczL3BuYXMuMDUwNjU4MDEwMikuKioKCkdTRUEgY2FsY3VsYXRlcyBhIHBhdGh3YXktbGV2ZWwgbWV0cmljLCBjYWxsZWQgYW4gZW5yaWNobWVudCBzY29yZSAoc29tZXRpbWVzIGFiYnJldmlhdGVkIGFzIEVTKSwgYnkgcmFua2luZyBnZW5lcyBieSBhIGdlbmUtbGV2ZWwgc3RhdGlzdGljLgpUaGlzIHNjb3JlIHJlZmxlY3RzIHdoZXRoZXIgb3Igbm90IGEgZ2VuZSBzZXQgb3IgcGF0aHdheSBpcyBvdmVyLXJlcHJlc2VudGVkIGF0IHRoZSB0b3Agb3IgYm90dG9tIG9mIHRoZSBnZW5lIHJhbmtpbmdzIChbU3VicmFtYW5pYW4gX2V0IGFsLl8gMjAwNV0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwNzMvcG5hcy4wNTA2NTgwMTAyKTsgW1l1XShodHRwOi8veXVsYWItc211LnRvcC9jbHVzdGVyUHJvZmlsZXItYm9vay9jaGFwdGVyMi5odG1sI2dlbmUtc2V0LWVucmljaG1lbnQtYW5hbHlzaXMpKSAKClNwZWNpZmljYWxseSwgYWxsIGdlbmVzIGFyZSByYW5rZWQgZnJvbSBtb3N0IHBvc2l0aXZlIHRvIG1vc3QgbmVnYXRpdmUgYmFzZWQgb24gdGhlaXIgc3RhdGlzdGljIGFuZCBhIHJ1bm5pbmcgc3VtIGlzIGNhbGN1bGF0ZWQ6ClN0YXJ0aW5nIHdpdGggdGhlIG1vc3QgaGlnaGx5IHJhbmtlZCBnZW5lcywgdGhlIHJ1bm5pbmcgc3VtIGluY3JlYXNlcyBmb3IgZWFjaCBnZW5lIGluIHRoZSBwYXRod2F5IGFuZCBkZWNyZWFzZXMgZm9yIGVhY2ggZ2VuZSBub3QgaW4gdGhlIHBhdGh3YXkuClRoZSBlbnJpY2htZW50IHNjb3JlIGZvciBhIHBhdGh3YXkgaXMgdGhlIHJ1bm5pbmcgc3VtJ3MgbWF4aW11bSBkZXZpYXRpb24gZnJvbSB6ZXJvLgpHU0VBIGFsc28gYXNzZXNzZXMgc3RhdGlzdGljYWwgc2lnbmlmaWNhbmNlIG9mIHRoZSBzY29yZXMgZm9yIGVhY2ggcGF0aHdheSB0aHJvdWdoIHBlcm11dGF0aW9uIHRlc3RpbmcuIApBcyBhIHJlc3VsdCwgZWFjaCBpbnB1dCBwYXRod2F5IHdpbGwgaGF2ZSBhIHAtdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGl0IHRoYXQgaXMgdGhlbiBjb3JyZWN0ZWQgZm9yIG11bHRpcGxlIGh5cG90aGVzaXMgdGVzdGluZyAoW1N1YnJhbWFuaWFuIF9ldCBhbC5fIDIwMDVdKGh0dHBzOi8vZG9pLm9yZy8xMC4xMDczL3BuYXMuMDUwNjU4MDEwMik7IFtZdV0oaHR0cDovL3l1bGFiLXNtdS50b3AvY2x1c3RlclByb2ZpbGVyLWJvb2svY2hhcHRlcjIuaHRtbCNnZW5lLXNldC1lbnJpY2htZW50LWFuYWx5c2lzKSkuCgpUaGUgaW1wbGVtZW50YXRpb24gb2YgR1NFQSB3ZSB1c2UgaW4gaGVyZSBleGFtcGxlcyByZXF1aXJlcyBhIGdlbmUgbGlzdCBvcmRlcmVkIGJ5IHNvbWUgc3RhdGlzdGljIGFuZCBpbnB1dCBnZW5lIHNldHMuIApXaGVuIHlvdSB1c2UgcHJldmlvdXNseSBjb21wdXRlZCBnZW5lLWxldmVsIHN0YXRpc3RpY3Mgd2l0aCBHU0VBLCBpdCBpcyBjYWxsZWQgR1NFQSBwcmUtcmFua2VkLgoKIyMjIEdlbmUgc2V0cwoKSW4gdGhlIHByZXZpb3VzIG5vdGVib29rLCB3ZSB1c2VkIEtFR0cgcGF0aHdheXMgZm9yIG92ZXItcmVwcmVzZW50YXRpb24gYW5hbHlzaXMuCldlIGlkZW50aWZpZWQgcGF0aHdheXMgdGhhdCB3ZXJlIHNpZ25pZmljYW50bHkgb3Zlci1yZXByZXNlbnRlZCBhbmQgZm91bmQgdGhhdCB0aGUgc2lnbmlmaWNhbnQgcGF0aHdheXMgc2hhcmVkIGdlbmVzLgpGQ1MgbWV0aG9kcyBhbmFseXplIGVhY2ggcGF0aHdheSBpbmRlcGVuZGVudGx5IGFuZCBlc3NlbnRpYWxseSBpZ25vcmUgdGhpcyBvdmVybGFwIGJldHdlZW4gZ2VuZSBzZXRzLgoKTVNpZ0RCIGluY2x1ZGVzIGEgY29sbGVjdGlvbiBjYWxsZWQgSGFsbG1hcmsgZ2VuZSBzZXRzIChbTGliZXJ6b24gKmV0IGFsLiogMjAxNV0oaHR0cHM6Ly9keC5kb2kub3JnLzEwLjEwMTYlMkZqLmNlbHMuMjAxNS4xMi4wMDQpKQpIZXJlJ3MgYW4gZXhjZXJwdCBvZiB0aGUgW2NvbGxlY3Rpb24gZGVzY3JpcHRpb25dKGh0dHBzOi8vd3d3LmdzZWEtbXNpZ2RiLm9yZy9nc2VhL21zaWdkYi9jb2xsZWN0aW9uX2RldGFpbHMuanNwI0gpOgoKPiBIYWxsbWFyayBnZW5lIHNldHMgc3VtbWFyaXplIGFuZCByZXByZXNlbnQgc3BlY2lmaWMgd2VsbC1kZWZpbmVkIGJpb2xvZ2ljYWwgc3RhdGVzIG9yIHByb2Nlc3NlcyBhbmQgZGlzcGxheSBjb2hlcmVudCBleHByZXNzaW9uLiBUaGVzZSBnZW5lIHNldHMgd2VyZSBnZW5lcmF0ZWQgYnkgYSBjb21wdXRhdGlvbmFsIG1ldGhvZG9sb2d5IGJhc2VkIG9uIGlkZW50aWZ5aW5nIGdlbmUgc2V0IG92ZXJsYXBzIGFuZCByZXRhaW5pbmcgZ2VuZXMgdGhhdCBkaXNwbGF5IGNvb3JkaW5hdGUgZXhwcmVzc2lvbi4gVGhlIGhhbGxtYXJrcyByZWR1Y2Ugbm9pc2UgYW5kIHJlZHVuZGFuY3kgYW5kIHByb3ZpZGUgYSBiZXR0ZXIgZGVsaW5lYXRlZCBiaW9sb2dpY2FsIHNwYWNlIGZvciBHU0VBLgoKV2UnbGwgdXNlIHRoZSBIYWxsbWFyayBjb2xsZWN0aW9uIGZvciBHU0VBLgpOb3RhYmx5LCB0aGVyZSBhcmUgb25seSA1MCBnZW5lIHNldHMgaW5jbHVkZWQgaW4gdGhpcyBjb2xsZWN0aW9uLgpUaGUgZmV3ZXIgZ2VuZSBzZXRzIHdlIHRlc3QsIHRoZSBsb3dlciBvdXIgbXVsdGlwbGUgaHlwb3RoZXNpcyB0ZXN0aW5nIGJ1cmRlbi4KCldlIGNhbiByZXRyaWV2ZSBvbmx5IHRoZSBIYWxsbWFyayBnZW5lIHNldHMgYnkgc3BlY2lmeWluZyBgY2F0ZWdvcnkgPSAiSCJgIHRvIHRoZSBgbXNpZ2RicigpYCBmdW5jdGlvbi4KCmBgYHtyIGhhbGxtYXJrX3NldHMsIGxpdmUgPSBUUlVFfQpoc19oYWxsbWFya19kZiA8LSBtc2lnZGJyKHNwZWNpZXMgPSAiSG9tbyBzYXBpZW5zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeSA9ICJIIikKYGBgCgojIyBEaWZmZXJlbnRpYWwgZ2VuZSBleHByZXNzaW9uIHJlc3VsdHMKCmBgYHtyIHJlYWRfaW5fZGdlLCBsaXZlID0gVFJVRX0KIyBSZWFkIGluIHRoZSBER0UgcmVzdWx0cwpkZ2VfcmVzdWx0c19kZiA8LSByZWFkcjo6cmVhZF90c3YoZGdlX3Jlc3VsdHNfZmlsZSkKYGBgCgpgYGB7cn0KaGVhZChkZ2VfcmVzdWx0c19kZikKYGBgCgpTaW5jZSB0aGlzIGRhdGEgZnJhbWUgb2YgREdFIHJlc3VsdHMgaW5jbHVkZXMgZ2VuZSBzeW1ib2xzLCB3ZSBkbyBub3QgbmVlZCB0byBwZXJmb3JtIGFueSBraW5kIG9mIGdlbmUgaWRlbnRpZmllciBjb252ZXJzaW9uLgpXZSBkbywgaG93ZXZlciwgbmVlZCB0byBjaGVjayBmb3IgZHVwbGljYXRlIGdlbmUgc3ltYm9scy4gCldlIGNhbiBhY2NvbXBsaXNoIHRoaXMgd2l0aCBgZHVwbGljYXRlZCgpYCwgd2hpY2ggcmV0dXJucyBhIGxvZ2ljYWwgdmVjdG9yIChlLmcuLCBgVFJVRWAgb3IgYEZBTFNFYCkuClRoZSBmdW5jdGlvbiBgc3VtKClgIHdpbGwgY291bnQgYFRSVUVgIHZhbHVlcyBhcyAxcyBhbmQgYEZBTFNFYCBhcyAwcywgc28gdXNpbmcgaXQgd2l0aCBgZHVwbGljYXRlZCgpYCB3aWxsIGNvdW50IHRoZSBudW1iZXIgb2YgZHVwbGljYXRlIHZhbHVlcy4KCmBgYHtyIGFueV9kdXBsaWNhdGVkLCBsaXZlID0gVFJVRX0Kc3VtKGR1cGxpY2F0ZWQoZGdlX3Jlc3VsdHNfZGYkZ2VuZV9zeW1ib2wpKQpgYGAKClRoaXMgd2lsbCBjYXVzZSBhIHByb2JsZW0gd2hlbiB3ZSBnbyB0byBydW4gR1NFQS4KCiMjIyBSZW1vdmluZyBkdXBsaWNhdGVzCgpUaGUgR1NFQSBhcHByb2FjaCByZXF1aXJlcyBvbiBkaXNjcmltaW5hdGluZyBiZXR3ZWVuIGdlbmVzIHRoYXQgYXJlIGluIGEgZ2VuZSBzZXQgYW5kIHRob3NlIHRoYXQgYXJlIG5vdC4gClByYWN0aWNhbGx5IHNwZWFraW5nLCBnZW5lIHNldHMgYXJlIGp1c3QgY29sbGVjdGlvbnMgb2YgZ2VuZSBpZGVudGlmaWVycyEKV2hlbiB0aGUgZnVuY3Rpb24gd2UgdXNlIGZvciBHU0VBIHByZS1yYW5rZWQgZ2V0cyBhIGxpc3Qgd2l0aCBkdXBsaWNhdGVkIGdlbmUgaWRlbnRpZmllcnMsIGl0IGNhbiBwcm9kdWNlIHVuZXhwZWN0ZWQgcmVzdWx0cy4KCkNvbXBhcmVkIHRvIHRoZSB0b3RhbCBudW1iZXIgb2YgZ2VuZXMgdGhhdCBhcmUgaW4gb3VyIHJlc3VsdHMsIHRoZXJlIGFyZSBub3QgYSBsb3Qgb2YgZHVwbGljYXRlcyBidXQgd2UnbGwgc3RpbGwgbmVlZCB0byBtYWtlIGEgZGVjaXNpb24gYWJvdXQgaG93IHRvIGhhbmRsZSB0aGVtLgoKTGV0J3MgZ2V0IGEgdmVjdG9yIG9mIHRoZSBkdXBsaWNhdGVkIGdlbmUgc3ltYm9scyBzbyB3ZSBjYW4gdXNlIGl0IHRvIGV4cGxvcmUgb3VyIGZpbHRlcmluZyBzdGVwcy4KCmBgYHtyIGdlbmVfZHVwcywgbGl2ZSA9IFRSVUV9CmR1cGxpY2F0ZWRfZ2VuZV9zeW1ib2xzIDwtIGRnZV9yZXN1bHRzX2RmICU+JQogIGRwbHlyOjpmaWx0ZXIoZHVwbGljYXRlZChnZW5lX3N5bWJvbCkpICU+JQogIGRwbHlyOjpwdWxsKGdlbmVfc3ltYm9sKQpgYGAKCk5vdyB3ZSdsbCBsb29rIGF0IHRoZSB2YWx1ZXMgZm9yIHRoZSB0aGUgZHVwbGljYXRlZCBnZW5lIHN5bWJvbHMuCgpgYGB7ciBzaG93X2dlbmVfZHVwc30KZGdlX3Jlc3VsdHNfZGYgJT4lCiAgZHBseXI6OmZpbHRlcihnZW5lX3N5bWJvbCAlaW4lIGR1cGxpY2F0ZWRfZ2VuZV9zeW1ib2xzKSAlPiUKICBkcGx5cjo6YXJyYW5nZShnZW5lX3N5bWJvbCkKYGBgCgpXZSBjYW4gc2VlIHRoYXQgdGhlIGFzc29jaWF0ZWQgdmFsdWVzIHZhcnkgZm9yIGVhY2ggcm93LgoKTGV0J3Mga2VlcCB0aGUgZ2VuZSBzeW1ib2xzIGFzc29jaWF0ZWQgd2l0aCB0aGUgaGlnaGVyIGFic29sdXRlIHZhbHVlIG9mIHRoZSBsb2cyIGZvbGQgY2hhbmdlLgoKUmV0YWluaW5nIHRoZSBpbnN0YW5jZSBvZiB0aGUgZ2VuZSBzeW1ib2xzIHdpdGggdGhlIGhpZ2hlciBhYnNvbHV0ZSB2YWx1ZSBvZiBhIGdlbmUtbGV2ZWwgc3RhdGlzdGljIG1lYW5zIHRoYXQgd2Ugd2lsbCByZXRhaW4gdGhlIHZhbHVlIHRoYXQgaXMgbGlrZWx5IHRvIGJlIG1vcmUgaGlnaGx5LSBvciBsb3dseS1yYW5rZWQgb3IsIHB1dCBhbm90aGVyIHdheSwgdGhlIHZhbHVlcyBsZXNzIGxpa2VseSB0byBiZSB0b3dhcmRzIHRoZSBtaWRkbGUgb2YgdGhlIHJhbmtlZCBnZW5lIGxpc3QuCldlIHNob3VsZCBrZWVwIHRoaXMgZGVjaXNpb24gaW4gbWluZCB3aGVuIGludGVycHJldGluZyBvdXIgcmVzdWx0cy4KRm9yIGV4YW1wbGUsIGlmIGFsbCB0aGUgZHVwbGljYXRlIGlkZW50aWZpZXJzIGhhcHBlbmVkIHRvIGJlIGluIGEgcGFydGljdWxhciBnZW5lIHNldCwgd2UgbWF5IGdldCBhbiBvdmVybHkgb3B0aW1pc3RpYyB2aWV3IG9mIGhvdyBwZXJ0dXJiZWQgdGhhdCBnZW5lIHNldCBpcyBiZWNhdXNlIHdlIHByZWZlcmVudGlhbGx5IHNlbGVjdGVkIGluc3RhbmNlcyBvZiB0aGUgaWRlbnRpZmllciB0aGF0IGhhdmUgYSBoaWdoZXIgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIHN0YXRpc3RpYyB1c2VkIGZvciByYW5raW5nLgoKSW4gdGhlIG5leHQgY2h1bmssIHdlIGFyZSBnb2luZyB0byBmaWx0ZXIgb3V0IHRoZSBkdXBsaWNhdGVkIHJvd3MgdXNpbmcgdGhlIGBkcGx5cjo6ZGlzdGluY3QoKWAgZnVuY3Rpb24gYWZ0ZXIgc29ydGluZyBieSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGUgbG9nMiBmb2xkIGNoYW5nZS4KVGhpcyB3aWxsIGtlZXAgdGhlIGZpcnN0IHJvdyB3aXRoIHRoZSBkdXBsaWNhdGVkIHZhbHVlIHRodXMga2VlcGluZyB0aGUgcm93IHdpdGggdGhlIGxhcmdlc3QgYWJzb2x1dGUgdmFsdWUuCgpgYGB7ciBmaWx0ZXJfZGdlfQpmaWx0ZXJlZF9kZ2VfZGYgPC0gZGdlX3Jlc3VsdHNfZGYgJT4lCiAgIyBTb3J0IHNvIHRoYXQgdGhlIGhpZ2hlc3QgYWJzb2x1dGUgdmFsdWVzIG9mIHRoZSBsb2cyIGZvbGQgY2hhbmdlIGFyZSBhdCB0aGUKICAjIHRvcAogIGRwbHlyOjphcnJhbmdlKGRwbHlyOjpkZXNjKGFicyhsb2cyRm9sZENoYW5nZSkpKSAlPiUKICAjIEZpbHRlciBvdXQgdGhlIGR1cGxpY2F0ZWQgcm93cyB1c2luZyBgZHBseXI6OmRpc3RpbmN0KClgCiAgZHBseXI6OmRpc3RpbmN0KGdlbmVfc3ltYm9sLCAua2VlcF9hbGwgPSBUUlVFKQpgYGAKCkxldCdzIHNlZSB3aGF0IGhhcHBlbmVkIHRvIG91ciBkdXBsaWNhdGUgaWRlbnRpZmllcnMuCgpgYGB7ciBzaG93X2ZpbHRlcmVkX2RnZSwgbGl2ZSA9IFRSVUV9CiMgU3Vic2V0IHRvICYgYXJyYW5nZSBieSBnZW5lIHN5bWJvbHMgdGhhdCB3ZXJlIGR1cGxpY2F0ZWQgaW4gdGhlIG9yaWdpbmFsIAojIGRhdGEgZnJhbWUgb2YgcmVzdWx0cwpmaWx0ZXJlZF9kZ2VfZGYgJT4lCiAgZHBseXI6OmZpbHRlcihnZW5lX3N5bWJvbCAlaW4lIGR1cGxpY2F0ZWRfZ2VuZV9zeW1ib2xzKSAlPiUKICBkcGx5cjo6YXJyYW5nZShnZW5lX3N5bWJvbCkKYGBgCgpOb3cgd2UncmUgcmVhZHkgdG8gcHJlcCBvdXIgcHJlLXJhbmtlZCBsaXN0IGZvciBHU0VBLgoKIyMjIFByZS1yYW5rZWQgbGlzdAoKVGhlIGBHU0VBKClgIGZ1bmN0aW9uIHRha2VzIGEgcHJlLXJhbmtlZCAoc29ydGVkKSBuYW1lZCB2ZWN0b3Igb2Ygc3RhdGlzdGljcywgd2hlcmUgdGhlIG5hbWVzIGluIHRoZSB2ZWN0b3IgYXJlIGdlbmUgaWRlbnRpZmllcnMuClRoaXMgaXMgc3RlcCAxIC0tIGdlbmUtbGV2ZWwgc3RhdGlzdGljcy4KCmBgYHtyIGxmY192ZWN0b3J9CmxmY192ZWN0b3IgPC0gZmlsdGVyZWRfZGdlX2RmICU+JQogICMgRXh0cmFjdCBhIHZlY3RvciBvZiBgbG9nMkZvbGRDaGFuZ2VgIG5hbWVkIGJ5IGBnZW5lX3N5bWJvbGAKICBkcGx5cjo6cHVsbChsb2cyRm9sZENoYW5nZSwgbmFtZSA9IGdlbmVfc3ltYm9sKQpsZmNfdmVjdG9yIDwtIHNvcnQobGZjX3ZlY3RvciwgZGVjcmVhc2luZyA9IFRSVUUpCmBgYAoKTGV0J3MgbG9vayBhdCB0aGUgdG9wIHJhbmtlZCB2YWx1ZXMuCgpgYGB7ciBoZWFkX2xmYywgbGl2ZSA9IFRSVUV9CiMgTG9vayBhdCBmaXJzdCBlbnRyaWVzIG9mIHRoZSBsb2cyIGZvbGQgY2hhbmdlIHZlY3RvcgpoZWFkKGxmY192ZWN0b3IpCmBgYAoKQW5kIHRoZSBib3R0b20gb2YgdGhlIGxpc3QuCgpgYGB7ciB0YWlsX2xmYywgbGl2ZSA9IFRSVUV9CiMgTG9vayBhdCB0aGUgbGFzdCBlbnRyaWVzIG9mIHRoZSBsb2cyIGZvbGQgY2hhbmdlIHZlY3Rvcgp0YWlsKGxmY192ZWN0b3IpCmBgYAoKIyMgUnVuIEdTRUEKCk5vdyBmb3IgdGhlIGFuYWx5c2lzIQoKV2UgY2FuIHVzZSB0aGUgYEdTRUEoKWAgZnVuY3Rpb24gdG8gcGVyZm9ybSBHU0VBIHdpdGggYW55IGdlbmVyaWMgc2V0IG9mIGdlbmUgc2V0cywgYnV0IHRoZXJlIGFyZSBzZXZlcmFsIGZ1bmN0aW9ucyBmb3IgdXNpbmcgc3BlY2lmaWMsIGNvbW1vbmx5IHVzZWQgZ2VuZSBzZXRzIChlLmcuLCBgZ3NlS0VHRygpYCkuCgpgYGB7ciBydW5fZ3NlYX0KZ3NlYV9yZXN1bHRzIDwtIEdTRUEoZ2VuZUxpc3QgPSBsZmNfdmVjdG9yLCAgIyBvcmRlcmVkIHJhbmtlZCBnZW5lIGxpc3QKICAgICAgICAgICAgICAgICAgICAgbWluR1NTaXplID0gMjUsICAjIG1pbmltdW0gZ2VuZSBzZXQgc2l6ZQogICAgICAgICAgICAgICAgICAgICBtYXhHU1NpemUgPSA1MDAsICAjIG1heGltdW0gZ2VuZSBzZXQgc2V0CiAgICAgICAgICAgICAgICAgICAgIHB2YWx1ZUN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICAgICAgICAgIHBBZGp1c3RNZXRob2QgPSAiQkgiLCAgIyBjb3JyZWN0aW9uIGZvciBtdWx0aXBsZSBoeXBvdGhlc2lzIHRlc3RpbmcKICAgICAgICAgICAgICAgICAgICAgVEVSTTJHRU5FID0gZHBseXI6OnNlbGVjdChoc19oYWxsbWFya19kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnc19uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVfc3ltYm9sKSkKYGBgCgpUaGUgd2FybmluZyBhYm91dCB0aWVzIG1lYW5zIHRoYXQgdGhlcmUgYXJlIG11bHRpcGxlIGdlbmVzIHRoYXQgaGF2ZSB0aGUgc2FtZSBsb2cyIGZvbGQgY2hhbmdlIHZhbHVlLiAKVGhpcyBwZXJjZW50YWdlIGlzIHNtYWxsIGFuZCB1bmxpa2VseSB0byBpbXBhY3Qgb3VyIHJlc3VsdHMuCkEgbGFyZ2UgbnVtYmVyIG9mIHRpZXMgbWlnaHQgdGVsbCB1cyB0aGVyZSdzIHNvbWV0aGluZyB3cm9uZyB3aXRoIG91ciBER0UgcmVzdWx0cyAoW0JhbGxlcmVhdSBfZXQgYWwuXyAyMDE4XShodHRwczovL2Jpb2luZm9ybWF0aWNzLWNvcmUtc2hhcmVkLXRyYWluaW5nLmdpdGh1Yi5pby9jcnVrLXN1bW1lci1zY2hvb2wtMjAxOC9STkFTZXEyMDE4L2h0bWwvMDZfR2VuZV9zZXRfdGVzdGluZy5uYi5odG1sKSkuCgpMZXQncyB0YWtlIGEgbG9vayBhdCB0aGUgR1NFQSByZXN1bHRzLgoKYGBge3Igdmlld19nc2VhLCBsaXZlID0gVFJVRSwgZXZhbCA9IEZBTFNFfQpWaWV3KGdzZWFfcmVzdWx0c0ByZXN1bHQgJT4lCiAgICAgICBkcGx5cjo6YXJyYW5nZShkcGx5cjo6ZGVzYyhORVMpKQopCmBgYAoKTm9ybWFsaXplZCBlbnJpY2htZW50IHNjb3JlcyAoTkVTKSBhcmUgZW5yaWNobWVudCBzY29yZXMgdGhhdCBhcmUgc2NhbGVkIHRvIG1ha2UgZ2VuZSBzZXRzIHRoYXQgY29udGFpbiBkaWZmZXJlbnQgbnVtYmVyIG9mIGdlbmVzIGNvbXBhcmFibGUuCgpMZXQncyB3cml0ZSB0aGVzZSByZXN1bHRzIHRvIGZpbGUuCgpgYGB7ciB3cml0ZV9nc2VhfQpnc2VhX3Jlc3VsdHNAcmVzdWx0ICU+JSByZWFkcjo6d3JpdGVfdHN2KGdzZWFfcmVzdWx0c19maWxlKQpgYGAKCiMjIyBWaXN1YWxpemluZyBHU0VBIHJlc3VsdHMKCldlIGNhbiB2aXN1YWxpemUgR1NFQSByZXN1bHRzIGZvciBpbmRpdmlkdWFsIHBhdGh3YXlzIG9yIGdlbmUgc2V0cyB1c2luZyBgZW5yaWNocGxvdDo6Z3NlYXBsb3QoKWAuCkxldCdzIHRha2UgYSBsb29rIGF0IDMgZGlmZmVyZW50IHBhdGh3YXlzIC0tIG9uZSB3aXRoIGEgaGlnaGx5IHBvc2l0aXZlIE5FUywgb25lIHdpdGggYSBoaWdobHkgbmVnYXRpdmUgTkVTLCBhbmQgb25lIHRoYXQgd2FzIG5vdCBhIHNpZ25pZmljYW50IHJlc3VsdCAtLSB0byBnZXQgbW9yZSBpbnNpZ2h0IGludG8gaG93IEVTIGFyZSBjYWxjdWxhdGVkLgoKIyMjIyBIaWdobHkgUG9zaXRpdmUgTkVTCgpUaGUgZ2VuZSBzZXQgYEhBTExNQVJLX01ZQ19UQVJHRVRTX1YxYCBoYWQgaGlnaCBwb3NpdGl2ZSBsb2cyIGZvbGQgY2hhbmdlcy4KUmVjYWxsIGEgcG9zaXRpdmUgbG9nMiBmb2xkIGNoYW5nZSBtZWFucyBhIGl0IGhhZCBhIGhpZ2hlciBleHByZXNzaW9uIHZhbHVlIGluIF9NWUNOXyBhbXBsaWZpZWQgY2VsbCBsaW5lcy4KCmBgYHtyIG15Y192MX0KZW5yaWNocGxvdDo6Z3NlYXBsb3QoZ3NlYV9yZXN1bHRzLAogICAgICAgICAgICAgICAgICAgICBnZW5lU2V0SUQgPSAiSEFMTE1BUktfTVlDX1RBUkdFVFNfVjEiLAogICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJIQUxMTUFSS19NWUNfVEFSR0VUU19WMSIsCiAgICAgICAgICAgICAgICAgICAgIGNvbG9yLmxpbmUgPSAiIzAwNjZGRiIpCmBgYAoKTm90aWNlIGhvdyB0aGUgZ2VuZXMgdGhhdCBhcmUgaW4gdGhlIGdlbmUgc2V0LCBpbmRpY2F0ZWQgYnkgdGhlIGJsYWNrIGJhcnMsIHRlbmQgdG8gYmUgb24gdGhlIGxlZnQgc2lkZSBvZiB0aGUgZ3JhcGggaW5kaWNhdGluZyB0aGF0IHRoZXkgaGF2ZSBwb3NpdGl2ZSBnZW5lLWxldmVsIHNjb3Jlcy4KCiMjIyMgSGlnaGx5IE5lZ2F0aXZlIE5FUwoKVGhlIGdlbmUgc2V0IGBIQUxMTUFSS19JTlRFUkZFUk9OX0FMUEhBX1JFU1BPTlNFYCBoYWQgYSBoaWdobHkgbmVnYXRpdmUgTkVTLgoKYGBge3IgaW5mbGFtbWF0b3J5fQplbnJpY2hwbG90Ojpnc2VhcGxvdChnc2VhX3Jlc3VsdHMsCiAgICAgICAgICAgICAgICAgICAgIGdlbmVTZXRJRCA9ICJIQUxMTUFSS19JTlRFUkZFUk9OX0FMUEhBX1JFU1BPTlNFIiwKICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiSEFMTE1BUktfSU5URVJGRVJPTl9BTFBIQV9SRVNQT05TRSIsCiAgICAgICAgICAgICAgICAgICAgIGNvbG9yLmxpbmUgPSAiIzAwNjZGRiIpCmBgYAoKVGhpcyBnZW5lIHNldCBzaG93cyB0aGUgb3Bwb3NpdGUgcGF0dGVybiAtLSBnZW5lcyBpbiB0aGUgcGF0aHdheSB0ZW5kIHRvIGJlIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBncmFwaC4KCiMjIyMgQSBub24tc2lnbmlmaWNhbnQgcmVzdWx0CgpUaGUgYEByZXN1bHRzYCBzbG90IHdpbGwgb25seSBzaG93IGdlbmUgc2V0cyB0aGF0IHBhc3MgdGhlIGBwdmFsdWVDdXRvZmZgIHRocmVzaG9sZCB3ZSBzdXBwbGllZCB0byBgR1NFQSgpYCwgYnV0IHdlIGNhbiBwbG90IGFueSBnZW5lIHNldCBzbyBsb25nIGFzIHdlIGtub3cgaXRzIG5hbWUuCkxldCdzIGxvb2sgYXQgYEhBTExNQVJLX1A1M19QQVRIV0FZYCwgd2hpY2ggd2FzIG5vdCBpbiB0aGUgcmVzdWx0cyB3ZSB2aWV3ZWQgZWFybGllci4KCmBgYHtyIHA1MywgbGl2ZSA9IFRSVUV9CmVucmljaHBsb3Q6OmdzZWFwbG90KGdzZWFfcmVzdWx0cywKICAgICAgICAgICAgICAgICAgICAgZ2VuZVNldElEID0gIkhBTExNQVJLX1A1M19QQVRIV0FZIiwKICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiSEFMTE1BUktfUDUzX1BBVEhXQVkiLAogICAgICAgICAgICAgICAgICAgICBjb2xvci5saW5lID0gIiMwMDY2RkYiKQpgYGAKCkdlbmVzIGluIHRoZSBwYXRod2F5IGFyZSBkaXN0cmlidXRlZCBtb3JlIGV2ZW5seSB0aHJvdWdob3V0IHRoZSByYW5rZWQgbGlzdCwgcmVzdWx0aW5nIGluIGEgbW9yZSAibWlkZGxpbmciIHNjb3JlLgoKKk5vdGU6IFRoZSBwbG90cyByZXR1cm5lZCBieSBgZW5yaWNocGxvdDo6Z3NlYXBsb3RgIGFyZSBnZ3Bsb3RzLCBzbyB3ZSBjb3VsZCB1c2UgYGdncGxvdDI6Omdnc2F2ZSgpYCB0byBzYXZlIHRoZW0gdG8gZmlsZSBpZiB3ZSB3YW50ZWQgdG8uKgoKIyMgU2Vzc2lvbiBJbmZvCgpgYGB7ciBzZXNzaW9uX2luZm99CnNlc3Npb25JbmZvKCkKYGBgCg==
+
LS0tCnRpdGxlOiAiUGF0aHdheSBhbmFseXNpczogR2VuZSBTZXQgRW5yaWNobWVudCBBbmFseXNpcyAoR1NFQSkiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKYXV0aG9yOiBDQ0RMIGZvciBBTFNGCmRhdGU6IDIwMjAKLS0tCgojIyBPYmplY3RpdmVzCgpUaGlzIG5vdGVib29rIHdpbGwgZGVtb25zdHJhdGUgaG93IHRvOgoKLSBQcmVwYXJlIHRhYnVsYXIgZGF0YSBvZiBnZW5lLWxldmVsIHN0YXRpc3RpY3MgZm9yIHVzZSB3aXRoIEdlbmUgU2V0IEVucmljaG1lbnQgQW5hbHlzaXMgKEdTRUEpLCBpbmNsdWRpbmcgaG93IHRvIHJlbW92ZSBkdXBsaWNhdGUgZ2VuZSBpZGVudGlmaWVycwotIFBlcmZvcm0gR1NFQSB3aXRoIHRoZSBgY2x1c3RlclByb2ZpbGVyYCBwYWNrYWdlCi0gVmlzdWFsaXplIEdTRUEgcmVzdWx0cyB3aXRoIHRoZSBgZW5yaWNocGxvdGAgcGFja2FnZQoKLS0tCgpJbiB0aGlzIG5vdGVib29rLCB3ZSB3aWxsIHBlcmZvcm0gR2VuZSBTZXQgRW5yaWNobWVudCBBbmFseXNpcyAoR1NFQSkgb24gdGhlIG5ldXJvYmxhc3RvbWEgY2VsbCBsaW5lIGRpZmZlcmVudGlhbCBnZW5lIGV4cHJlc3Npb24gKERHRSkgcmVzdWx0cyB3ZSBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBSTkEtc2VxIG1vZHVsZS4KClRvIHJlZnJlc2ggb3VyIG1lbW9yeSwgd2UgYW5hbHl6ZWQgZGF0YSBmcm9tIFtIYXJlbnphICpldCBhbC4qICgyMDE3KV0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwMzgvc2RhdGEuMjAxNy4zMykgYW5kIHNwZWNpZmljYWxseSB0ZXN0ZWQgZm9yIERHRSBiZXR3ZWVuIHdpdGggX01ZQ05fIGFtcGxpZmllZCBjZWxsIGxpbmVzIGFuZCBub24tYW1wbGlmaWVkIGNlbGwgbGluZXMgdXNpbmcgYERFU2VxMmAuCldlIGhhdmUgYSB0YWJsZSBvZiByZXN1bHRzIHRoYXQgY29udGFpbnMgb3VyIGxvZzIgZm9sZCBjaGFuZ2VzIGFuZCBhZGp1c3RlZCBwLXZhbHVlcy4KCkdTRUEgaXMgYSBmdW5jdGlvbmFsIGNsYXNzIHNjb3JpbmcgKEZDUykgYXBwcm9hY2ggdG8gcGF0aHdheSBhbmFseXNpcyB0aGF0IHdhcyBmaXJzdCBpbnRyb2R1Y2VkIGluIFtTdWJyYW1hbmlhbiBfZXQgYWwuXyAoMjAwNSldKGh0dHBzOi8vZG9pLm9yZy8xMC4xMDczL3BuYXMuMDUwNjU4MDEwMikuClRoZSByYXRpb25hbGUgYmVoaW5kIEZDUyBhcHByb2FjaGVzIGlzIHRoYXQgc21hbGwgY2hhbmdlcyBpbiBpbmRpdmlkdWFsIGdlbmVzIHRoYXQgcGFydGljaXBhdGUgaW4gdGhlIHNhbWUgYmlvbG9naWNhbCBwcm9jZXNzIG9yIHBhdGh3YXkgY2FuIGJlIHNpZ25pZmljYW50IGFuZCBvZiBiaW9sb2dpY2FsIGludGVyZXN0LgpGQ1MgbWV0aG9kcyBhcmUgYmV0dGVyIHN1aXRlZCBmb3IgaWRlbnRpZnlpbmcgdGhlc2UgcGF0aHdheXMgdGhhdCBzaG93IGNvb3JkaW5hdGVkIGNoYW5nZXMgdGhhbiBPUkEuCkluIE9SQSwgd2UgcGljayBhIGN1dG9mZiB0aGF0IF90eXBpY2FsbHlfIG9ubHkgY2FwdHVyZXMgZ2VuZXMgd2l0aCBsYXJnZSBpbmRpdmlkdWFsIGNoYW5nZXMuCgpUaGVyZSBhcmUgMyBnZW5lcmFsIHN0ZXBzIGluIEZDUyBtZXRob2RzIChbS2hhdHJpIF9ldCBhbC5fIDIwMTJdKCBodHRwczovL2RvaS5vcmcvMTAuMTM3MS9qb3VybmFsLnBjYmkuMTAwMjM3NSkpOgoKMS4gQ2FsY3VsYXRlIGEgZ2VuZS1sZXZlbCBzdGF0aXN0aWMgKHdlJ2xsIHVzZSBsb2cyIGZvbGQgY2hhbmdlIGZyb20gREVTZXEyIGhlcmUpCjIuIEdlbmUtbGV2ZWwgc3RhdGlzdGljcyBhcmUgYWdncmVnYXRlZCBpbnRvIGEgcGF0aHdheS1sZXZlbCBzdGF0aXN0aWMKMy4gQXNzZXNzIHRoZSBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2Ugb2YgdGhlIHBhdGh3YXktbGV2ZWwgc3RhdGlzdGljCgojIyMjIE90aGVyIHJlc291cmNlcwoKKiBGb3IgYW5vdGhlciBleGFtcGxlIHVzaW5nIGBjbHVzdGVyUHJvZmlsZXJgIGZvciBHU0VBLCBzZWUgW19JbnRybyB0byBER0U6IEZ1bmN0aW9uYWwgQW5hbHlzaXMuXyBmcm9tIEhhcnZhcmQgQ2hhbiBCaW9pbmZvcm1hdGljcyBDb3JlIFRyYWluaW5nLl0oaHR0cHM6Ly9oYmN0cmFpbmluZy5naXRodWIuaW8vREdFX3dvcmtzaG9wL2xlc3NvbnMvMDlfZnVuY3Rpb25hbF9hbmFseXNpcy5odG1sKQoqIFRoZSB3YXkgd2UnbGwgdXNlIGBjbHVzdGVyUHJvZmlsZXJgIGhlcmUgdXNlcyBgZmdzZWFgIChGYXN0IEdlbmUgU2V0IEVucmljaG1lbnQgQW5hbHlzaXMpIHVuZGVyIHRoZSBob29kLgpZb3UgY2FuIHJlYWQgbW9yZSBhYm91dCBmZ3NlYSBpbiBbS29yb3RrZXZpY2ggX2V0IGFsLl8gKDIwMjEpXShodHRwczovL2RvaS5vcmcvMTAuMTEwMS8wNjAwMTIpLgoqIFtyZWZpbmUuYmlvIGV4YW1wbGVzIEdlbmUgc2V0IGVucmljaG1lbnQgYW5hbHlzaXMgLSBSTkEtc2VxXShodHRwczovL2FsZXhzbGVtb25hZGUuZ2l0aHViLmlvL3JlZmluZWJpby1leGFtcGxlcy8wMy1ybmFzZXEvcGF0aHdheS1hbmFseXNpc19ybmFzZXFfMDJfZ3NlYS5odG1sKSBmcm9tIHdoaWNoIHRoaXMgbWF0ZXJpYWwgaGFzIGJlZW4gYWRhcHRlZC4KCiMjIFNldCB1cAoKIyMjIExpYnJhcmllcwoKYGBge3IgbGlicmFyaWVzfQojIFBhY2thZ2UgdG8gcnVuIEdTRUEKbGlicmFyeShjbHVzdGVyUHJvZmlsZXIpCiMgUGFja2FnZSB0aGF0IGNvbnRhaW5zIHRoZSBNU2lnREIgZ2VuZSBzZXRzIGluIHRpZHkgZm9ybWF0CmxpYnJhcnkobXNpZ2RicikKYGBgCgojIyMgRGlyZWN0b3JpZXMgYW5kIEZpbGVzCgojIyMjIERpcmVjdG9yaWVzCgpgYGB7cn0KIyBXaGVyZSB0aGUgREdFIHJlc3VsdHMgYXJlIHN0b3JlZAppbnB1dF9kaXIgPC0gZmlsZS5wYXRoKCIuLiIsICJSTkEtc2VxIiwgInJlc3VsdHMiLCAiTkItY2VsbCIpCgojIFdlIHdpbGwgY3JlYXRlIGEgZGlyZWN0b3J5IHRvIHNwZWNpZmljYWxseSBob2xkIG91ciBHU0VBIHJlc3VsdHMgaWYgaXQgZG9lcwojIG5vdCB5ZXQgZXhpc3QKb3V0cHV0X2RpciA8LSBmaWxlLnBhdGgoInJlc3VsdHMiLCAiTkItY2VsbCIpCmlmICghZGlyLmV4aXN0cyhvdXRwdXRfZGlyKSkgewogIGRpci5jcmVhdGUob3V0cHV0X2RpciwgcmVjdXJzaXZlID0gVFJVRSkKfQpgYGAKCiMjIyMgSW5wdXQgZmlsZXMKCmBgYHtyIGlucHV0X2ZpbGVzfQojIERHRSByZXN1bHRzCmRnZV9yZXN1bHRzX2ZpbGUgPC0gZmlsZS5wYXRoKGlucHV0X2RpciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTkItY2VsbF9ERVNlcV9hbXBsaWZpZWRfdl9ub25hbXBsaWZpZWRfcmVzdWx0cy50c3YiKQpgYGAKCiMjIyMgT3V0cHV0IGZpbGVzCgpgYGB7ciBvdXRwdXRfZmlsZXN9CiMgR1NFQSBwYXRod2F5LWxldmVsIHNjb3JlcyBhbmQgc3RhdGlzdGljcwpnc2VhX3Jlc3VsdHNfZmlsZSA8LSBmaWxlLnBhdGgob3V0cHV0X2RpciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOQi1jZWxsX2dzZWFfcmVzdWx0cy50c3YiKQpgYGAKCiMjIEdlbmUgU2V0IEVucmljaG1lbnQgQW5hbHlzaXMKCl9BZGFwdGVkIGZyb20gW3JlZmluZS5iaW8gZXhhbXBsZXNdKGh0dHBzOi8vZ2l0aHViLmNvbS9BbGV4c0xlbW9uYWRlL3JlZmluZWJpby1leGFtcGxlcy9ibG9iLzMzY2RlZmY2NmQ1N2Y5ZmU4ZWU0ZmNiNTE1NmFlYTRhYzJkY2UwN2YvMDMtcm5hc2VxL3BhdGh3YXktYW5hbHlzaXNfcm5hc2VxXzAyX2dzZWEuUm1kKV8KCiFbXShkaWFncmFtcy9zdWJyYW1hbmlhbl9maWcxLmpwZykKCioqRmlndXJlIDEuIFtTdWJyYW1hbmlhbiBfZXQgYWwuXyAoMjAwNSldKGh0dHBzOi8vZG9pLm9yZy8xMC4xMDczL3BuYXMuMDUwNjU4MDEwMikuKioKCkdTRUEgY2FsY3VsYXRlcyBhIHBhdGh3YXktbGV2ZWwgbWV0cmljLCBjYWxsZWQgYW4gZW5yaWNobWVudCBzY29yZSAoc29tZXRpbWVzIGFiYnJldmlhdGVkIGFzIEVTKSwgYnkgcmFua2luZyBnZW5lcyBieSBhIGdlbmUtbGV2ZWwgc3RhdGlzdGljLgpUaGlzIHNjb3JlIHJlZmxlY3RzIHdoZXRoZXIgb3Igbm90IGEgZ2VuZSBzZXQgb3IgcGF0aHdheSBpcyBvdmVyLXJlcHJlc2VudGVkIGF0IHRoZSB0b3Agb3IgYm90dG9tIG9mIHRoZSBnZW5lIHJhbmtpbmdzIChbU3VicmFtYW5pYW4gX2V0IGFsLl8gMjAwNV0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwNzMvcG5hcy4wNTA2NTgwMTAyKTsgW1l1XShodHRwOi8veXVsYWItc211LnRvcC9jbHVzdGVyUHJvZmlsZXItYm9vay9jaGFwdGVyMi5odG1sI2dlbmUtc2V0LWVucmljaG1lbnQtYW5hbHlzaXMpKQoKU3BlY2lmaWNhbGx5LCBhbGwgZ2VuZXMgYXJlIHJhbmtlZCBmcm9tIG1vc3QgcG9zaXRpdmUgdG8gbW9zdCBuZWdhdGl2ZSBiYXNlZCBvbiB0aGVpciBzdGF0aXN0aWMgYW5kIGEgcnVubmluZyBzdW0gaXMgY2FsY3VsYXRlZDoKU3RhcnRpbmcgd2l0aCB0aGUgbW9zdCBoaWdobHkgcmFua2VkIGdlbmVzLCB0aGUgcnVubmluZyBzdW0gaW5jcmVhc2VzIGZvciBlYWNoIGdlbmUgaW4gdGhlIHBhdGh3YXkgYW5kIGRlY3JlYXNlcyBmb3IgZWFjaCBnZW5lIG5vdCBpbiB0aGUgcGF0aHdheS4KVGhlIGVucmljaG1lbnQgc2NvcmUgZm9yIGEgcGF0aHdheSBpcyB0aGUgcnVubmluZyBzdW0ncyBtYXhpbXVtIGRldmlhdGlvbiBmcm9tIHplcm8uCkdTRUEgYWxzbyBhc3Nlc3NlcyBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2Ugb2YgdGhlIHNjb3JlcyBmb3IgZWFjaCBwYXRod2F5IHRocm91Z2ggcGVybXV0YXRpb24gdGVzdGluZy4KQXMgYSByZXN1bHQsIGVhY2ggaW5wdXQgcGF0aHdheSB3aWxsIGhhdmUgYSBwLXZhbHVlIGFzc29jaWF0ZWQgd2l0aCBpdCB0aGF0IGlzIHRoZW4gY29ycmVjdGVkIGZvciBtdWx0aXBsZSBoeXBvdGhlc2lzIHRlc3RpbmcgKFtTdWJyYW1hbmlhbiBfZXQgYWwuXyAyMDA1XShodHRwczovL2RvaS5vcmcvMTAuMTA3My9wbmFzLjA1MDY1ODAxMDIpOyBbWXVdKGh0dHA6Ly95dWxhYi1zbXUudG9wL2NsdXN0ZXJQcm9maWxlci1ib29rL2NoYXB0ZXIyLmh0bWwjZ2VuZS1zZXQtZW5yaWNobWVudC1hbmFseXNpcykpLgoKVGhlIGltcGxlbWVudGF0aW9uIG9mIEdTRUEgd2UgdXNlIGluIGhlcmUgZXhhbXBsZXMgcmVxdWlyZXMgYSBnZW5lIGxpc3Qgb3JkZXJlZCBieSBzb21lIHN0YXRpc3RpYyBhbmQgaW5wdXQgZ2VuZSBzZXRzLgpXaGVuIHlvdSB1c2UgcHJldmlvdXNseSBjb21wdXRlZCBnZW5lLWxldmVsIHN0YXRpc3RpY3Mgd2l0aCBHU0VBLCBpdCBpcyBjYWxsZWQgR1NFQSBwcmUtcmFua2VkLgoKIyMjIEdlbmUgc2V0cwoKSW4gdGhlIHByZXZpb3VzIG5vdGVib29rLCB3ZSB1c2VkIEtFR0cgcGF0aHdheXMgZm9yIG92ZXItcmVwcmVzZW50YXRpb24gYW5hbHlzaXMuCldlIGlkZW50aWZpZWQgcGF0aHdheXMgdGhhdCB3ZXJlIHNpZ25pZmljYW50bHkgb3Zlci1yZXByZXNlbnRlZCBhbmQgZm91bmQgdGhhdCB0aGUgc2lnbmlmaWNhbnQgcGF0aHdheXMgc2hhcmVkIGdlbmVzLgpGQ1MgbWV0aG9kcyBhbmFseXplIGVhY2ggcGF0aHdheSBpbmRlcGVuZGVudGx5IGFuZCBlc3NlbnRpYWxseSBpZ25vcmUgdGhpcyBvdmVybGFwIGJldHdlZW4gZ2VuZSBzZXRzLgoKTVNpZ0RCIGluY2x1ZGVzIGEgY29sbGVjdGlvbiBjYWxsZWQgSGFsbG1hcmsgZ2VuZSBzZXRzIChbTGliZXJ6b24gKmV0IGFsLiogMjAxNV0oaHR0cHM6Ly9keC5kb2kub3JnLzEwLjEwMTYlMkZqLmNlbHMuMjAxNS4xMi4wMDQpKQpIZXJlJ3MgYW4gZXhjZXJwdCBvZiB0aGUgW2NvbGxlY3Rpb24gZGVzY3JpcHRpb25dKGh0dHBzOi8vd3d3LmdzZWEtbXNpZ2RiLm9yZy9nc2VhL21zaWdkYi9jb2xsZWN0aW9uX2RldGFpbHMuanNwI0gpOgoKPiBIYWxsbWFyayBnZW5lIHNldHMgc3VtbWFyaXplIGFuZCByZXByZXNlbnQgc3BlY2lmaWMgd2VsbC1kZWZpbmVkIGJpb2xvZ2ljYWwgc3RhdGVzIG9yIHByb2Nlc3NlcyBhbmQgZGlzcGxheSBjb2hlcmVudCBleHByZXNzaW9uLiBUaGVzZSBnZW5lIHNldHMgd2VyZSBnZW5lcmF0ZWQgYnkgYSBjb21wdXRhdGlvbmFsIG1ldGhvZG9sb2d5IGJhc2VkIG9uIGlkZW50aWZ5aW5nIGdlbmUgc2V0IG92ZXJsYXBzIGFuZCByZXRhaW5pbmcgZ2VuZXMgdGhhdCBkaXNwbGF5IGNvb3JkaW5hdGUgZXhwcmVzc2lvbi4gVGhlIGhhbGxtYXJrcyByZWR1Y2Ugbm9pc2UgYW5kIHJlZHVuZGFuY3kgYW5kIHByb3ZpZGUgYSBiZXR0ZXIgZGVsaW5lYXRlZCBiaW9sb2dpY2FsIHNwYWNlIGZvciBHU0VBLgoKV2UnbGwgdXNlIHRoZSBIYWxsbWFyayBjb2xsZWN0aW9uIGZvciBHU0VBLgpOb3RhYmx5LCB0aGVyZSBhcmUgb25seSA1MCBnZW5lIHNldHMgaW5jbHVkZWQgaW4gdGhpcyBjb2xsZWN0aW9uLgpUaGUgZmV3ZXIgZ2VuZSBzZXRzIHdlIHRlc3QsIHRoZSBsb3dlciBvdXIgbXVsdGlwbGUgaHlwb3RoZXNpcyB0ZXN0aW5nIGJ1cmRlbi4KCldlIGNhbiByZXRyaWV2ZSBvbmx5IHRoZSBIYWxsbWFyayBnZW5lIHNldHMgYnkgc3BlY2lmeWluZyBgY2F0ZWdvcnkgPSAiSCJgIHRvIHRoZSBgbXNpZ2RicigpYCBmdW5jdGlvbi4KCmBgYHtyIGhhbGxtYXJrX3NldHMsIGxpdmUgPSBUUlVFfQpoc19oYWxsbWFya19kZiA8LSBtc2lnZGJyKHNwZWNpZXMgPSAiSG9tbyBzYXBpZW5zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeSA9ICJIIikKYGBgCgojIyBEaWZmZXJlbnRpYWwgZ2VuZSBleHByZXNzaW9uIHJlc3VsdHMKCmBgYHtyIHJlYWRfaW5fZGdlLCBsaXZlID0gVFJVRX0KIyBSZWFkIGluIHRoZSBER0UgcmVzdWx0cwpkZ2VfcmVzdWx0c19kZiA8LSByZWFkcjo6cmVhZF90c3YoZGdlX3Jlc3VsdHNfZmlsZSkKYGBgCkxldCdzIHRha2UgYSBwZWVrIGF0IHRoZSBjb250ZW50cyBvZiB0aGlzIGZpbGUuCgpgYGB7ciBoZWFkX2RnZSwgbGl2ZSA9IFRSVUV9CmhlYWQoZGdlX3Jlc3VsdHNfZGYpCmBgYAoKU2luY2UgdGhpcyBkYXRhIGZyYW1lIG9mIERHRSByZXN1bHRzIGluY2x1ZGVzIGdlbmUgc3ltYm9scywgd2UgZG8gbm90IG5lZWQgdG8gcGVyZm9ybSBhbnkga2luZCBvZiBnZW5lIGlkZW50aWZpZXIgY29udmVyc2lvbi4KV2UgZG8sIGhvd2V2ZXIsIG5lZWQgdG8gY2hlY2sgZm9yIGR1cGxpY2F0ZSBnZW5lIHN5bWJvbHMuCldlIGNhbiBhY2NvbXBsaXNoIHRoaXMgd2l0aCBgZHVwbGljYXRlZCgpYCwgd2hpY2ggcmV0dXJucyBhIGxvZ2ljYWwgdmVjdG9yIChlLmcuLCBgVFJVRWAgb3IgYEZBTFNFYCkuClRoZSBmdW5jdGlvbiBgc3VtKClgIHdpbGwgY291bnQgYFRSVUVgIHZhbHVlcyBhcyAxcyBhbmQgYEZBTFNFYCBhcyAwcywgc28gdXNpbmcgaXQgd2l0aCBgZHVwbGljYXRlZCgpYCB3aWxsIGNvdW50IHRoZSBudW1iZXIgb2YgZHVwbGljYXRlIHZhbHVlcy4KCmBgYHtyIGFueV9kdXBsaWNhdGVkLCBsaXZlID0gVFJVRX0Kc3VtKGR1cGxpY2F0ZWQoZGdlX3Jlc3VsdHNfZGYkZ2VuZV9zeW1ib2wpKQpgYGAKClRoaXMgd2lsbCBjYXVzZSBhIHByb2JsZW0gd2hlbiB3ZSBnbyB0byBydW4gR1NFQS4KCiMjIyBSZW1vdmluZyBkdXBsaWNhdGVzCgpUaGUgR1NFQSBhcHByb2FjaCByZXF1aXJlcyBvbiBkaXNjcmltaW5hdGluZyBiZXR3ZWVuIGdlbmVzIHRoYXQgYXJlIGluIGEgZ2VuZSBzZXQgYW5kIHRob3NlIHRoYXQgYXJlIG5vdC4KUHJhY3RpY2FsbHkgc3BlYWtpbmcsIGdlbmUgc2V0cyBhcmUganVzdCBjb2xsZWN0aW9ucyBvZiBnZW5lIGlkZW50aWZpZXJzIQpXaGVuIHRoZSBmdW5jdGlvbiB3ZSB1c2UgZm9yIEdTRUEgcHJlLXJhbmtlZCBnZXRzIGEgbGlzdCB3aXRoIGR1cGxpY2F0ZWQgZ2VuZSBpZGVudGlmaWVycywgaXQgY2FuIHByb2R1Y2UgdW5leHBlY3RlZCByZXN1bHRzLgoKQ29tcGFyZWQgdG8gdGhlIHRvdGFsIG51bWJlciBvZiBnZW5lcyB0aGF0IGFyZSBpbiBvdXIgcmVzdWx0cywgdGhlcmUgYXJlIG5vdCBhIGxvdCBvZiBkdXBsaWNhdGVzIGJ1dCB3ZSdsbCBzdGlsbCBuZWVkIHRvIG1ha2UgYSBkZWNpc2lvbiBhYm91dCBob3cgdG8gaGFuZGxlIHRoZW0uCgpMZXQncyBnZXQgYSB2ZWN0b3Igb2YgdGhlIGR1cGxpY2F0ZWQgZ2VuZSBzeW1ib2xzIHNvIHdlIGNhbiB1c2UgaXQgdG8gZXhwbG9yZSBvdXIgZmlsdGVyaW5nIHN0ZXBzLgoKYGBge3IgZ2VuZV9kdXBzLCBsaXZlID0gVFJVRX0KZHVwbGljYXRlZF9nZW5lX3N5bWJvbHMgPC0gZGdlX3Jlc3VsdHNfZGYgfD4KICBkcGx5cjo6ZmlsdGVyKGR1cGxpY2F0ZWQoZ2VuZV9zeW1ib2wpKSB8PgogIGRwbHlyOjpwdWxsKGdlbmVfc3ltYm9sKQpgYGAKCk5vdyB3ZSdsbCBsb29rIGF0IHRoZSB2YWx1ZXMgZm9yIHRoZSB0aGUgZHVwbGljYXRlZCBnZW5lIHN5bWJvbHMuCgpgYGB7ciBzaG93X2dlbmVfZHVwc30KZGdlX3Jlc3VsdHNfZGYgfD4KICBkcGx5cjo6ZmlsdGVyKGdlbmVfc3ltYm9sICVpbiUgZHVwbGljYXRlZF9nZW5lX3N5bWJvbHMpIHw+CiAgZHBseXI6OmFycmFuZ2UoZ2VuZV9zeW1ib2wpCmBgYAoKV2UgY2FuIHNlZSB0aGF0IHRoZSBhc3NvY2lhdGVkIHZhbHVlcyB2YXJ5IGZvciBlYWNoIHJvdy4KCkxldCdzIGtlZXAgdGhlIGdlbmUgc3ltYm9scyBhc3NvY2lhdGVkIHdpdGggdGhlIGhpZ2hlciBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGUgbG9nMiBmb2xkIGNoYW5nZS4KClJldGFpbmluZyB0aGUgaW5zdGFuY2Ugb2YgdGhlIGdlbmUgc3ltYm9scyB3aXRoIHRoZSBoaWdoZXIgYWJzb2x1dGUgdmFsdWUgb2YgYSBnZW5lLWxldmVsIHN0YXRpc3RpYyBtZWFucyB0aGF0IHdlIHdpbGwgcmV0YWluIHRoZSB2YWx1ZSB0aGF0IGlzIGxpa2VseSB0byBiZSBtb3JlIGhpZ2hseS0gb3IgbG93bHktcmFua2VkIG9yLCBwdXQgYW5vdGhlciB3YXksIHRoZSB2YWx1ZXMgbGVzcyBsaWtlbHkgdG8gYmUgdG93YXJkcyB0aGUgbWlkZGxlIG9mIHRoZSByYW5rZWQgZ2VuZSBsaXN0LgpXZSBzaG91bGQga2VlcCB0aGlzIGRlY2lzaW9uIGluIG1pbmQgd2hlbiBpbnRlcnByZXRpbmcgb3VyIHJlc3VsdHMuCkZvciBleGFtcGxlLCBpZiBhbGwgdGhlIGR1cGxpY2F0ZSBpZGVudGlmaWVycyBoYXBwZW5lZCB0byBiZSBpbiBhIHBhcnRpY3VsYXIgZ2VuZSBzZXQsIHdlIG1heSBnZXQgYW4gb3Zlcmx5IG9wdGltaXN0aWMgdmlldyBvZiBob3cgcGVydHVyYmVkIHRoYXQgZ2VuZSBzZXQgaXMgYmVjYXVzZSB3ZSBwcmVmZXJlbnRpYWxseSBzZWxlY3RlZCBpbnN0YW5jZXMgb2YgdGhlIGlkZW50aWZpZXIgdGhhdCBoYXZlIGEgaGlnaGVyIGFic29sdXRlIHZhbHVlIG9mIHRoZSBzdGF0aXN0aWMgdXNlZCBmb3IgcmFua2luZy4KCkluIHRoZSBuZXh0IGNodW5rLCB3ZSBhcmUgZ29pbmcgdG8gZmlsdGVyIG91dCB0aGUgZHVwbGljYXRlZCByb3dzIHVzaW5nIHRoZSBgZHBseXI6OmRpc3RpbmN0KClgIGZ1bmN0aW9uIGFmdGVyIHNvcnRpbmcgYnkgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIGxvZzIgZm9sZCBjaGFuZ2UuClRoaXMgd2lsbCBrZWVwIHRoZSBmaXJzdCByb3cgd2l0aCB0aGUgZHVwbGljYXRlZCB2YWx1ZSB0aHVzIGtlZXBpbmcgdGhlIHJvdyB3aXRoIHRoZSBsYXJnZXN0IGFic29sdXRlIHZhbHVlLgoKYGBge3IgZmlsdGVyX2RnZX0KZmlsdGVyZWRfZGdlX2RmIDwtIGRnZV9yZXN1bHRzX2RmIHw+CiAgIyBTb3J0IHNvIHRoYXQgdGhlIGhpZ2hlc3QgYWJzb2x1dGUgdmFsdWVzIG9mIHRoZSBsb2cyIGZvbGQgY2hhbmdlIGFyZSBhdCB0aGUKICAjIHRvcAogIGRwbHlyOjphcnJhbmdlKGRwbHlyOjpkZXNjKGFicyhsb2cyRm9sZENoYW5nZSkpKSB8PgogICMgRmlsdGVyIG91dCB0aGUgZHVwbGljYXRlZCByb3dzIHVzaW5nIGBkcGx5cjo6ZGlzdGluY3QoKWAKICBkcGx5cjo6ZGlzdGluY3QoZ2VuZV9zeW1ib2wsIC5rZWVwX2FsbCA9IFRSVUUpCmBgYAoKTGV0J3Mgc2VlIHdoYXQgaGFwcGVuZWQgdG8gb3VyIGR1cGxpY2F0ZSBpZGVudGlmaWVycy4KCmBgYHtyIHNob3dfZmlsdGVyZWRfZGdlLCBsaXZlID0gVFJVRX0KIyBTdWJzZXQgdG8gJiBhcnJhbmdlIGJ5IGdlbmUgc3ltYm9scyB0aGF0IHdlcmUgZHVwbGljYXRlZCBpbiB0aGUgb3JpZ2luYWwKIyBkYXRhIGZyYW1lIG9mIHJlc3VsdHMKZmlsdGVyZWRfZGdlX2RmIHw+CiAgZHBseXI6OmZpbHRlcihnZW5lX3N5bWJvbCAlaW4lIGR1cGxpY2F0ZWRfZ2VuZV9zeW1ib2xzKSB8PgogIGRwbHlyOjphcnJhbmdlKGdlbmVfc3ltYm9sKQpgYGAKCk5vdyB3ZSdyZSByZWFkeSB0byBwcmVwIG91ciBwcmUtcmFua2VkIGxpc3QgZm9yIEdTRUEuCgojIyMgUHJlLXJhbmtlZCBsaXN0CgpUaGUgYEdTRUEoKWAgZnVuY3Rpb24gdGFrZXMgYSBwcmUtcmFua2VkIChzb3J0ZWQpIG5hbWVkIHZlY3RvciBvZiBzdGF0aXN0aWNzLCB3aGVyZSB0aGUgbmFtZXMgaW4gdGhlIHZlY3RvciBhcmUgZ2VuZSBpZGVudGlmaWVycy4KVGhpcyBpcyBzdGVwIDEgLS0gZ2VuZS1sZXZlbCBzdGF0aXN0aWNzLgoKYGBge3IgbGZjX3ZlY3Rvcn0KbGZjX3ZlY3RvciA8LSBmaWx0ZXJlZF9kZ2VfZGYgfD4KICAjIEV4dHJhY3QgYSB2ZWN0b3Igb2YgYGxvZzJGb2xkQ2hhbmdlYCBuYW1lZCBieSBgZ2VuZV9zeW1ib2xgCiAgZHBseXI6OnB1bGwobG9nMkZvbGRDaGFuZ2UsIG5hbWUgPSBnZW5lX3N5bWJvbCkKbGZjX3ZlY3RvciA8LSBzb3J0KGxmY192ZWN0b3IsIGRlY3JlYXNpbmcgPSBUUlVFKQpgYGAKCkxldCdzIGxvb2sgYXQgdGhlIHRvcCByYW5rZWQgdmFsdWVzLgoKYGBge3IgaGVhZF9sZmMsIGxpdmUgPSBUUlVFfQojIExvb2sgYXQgZmlyc3QgZW50cmllcyBvZiB0aGUgbG9nMiBmb2xkIGNoYW5nZSB2ZWN0b3IKaGVhZChsZmNfdmVjdG9yKQpgYGAKCkFuZCB0aGUgYm90dG9tIG9mIHRoZSBsaXN0LgoKYGBge3IgdGFpbF9sZmMsIGxpdmUgPSBUUlVFfQojIExvb2sgYXQgdGhlIGxhc3QgZW50cmllcyBvZiB0aGUgbG9nMiBmb2xkIGNoYW5nZSB2ZWN0b3IKdGFpbChsZmNfdmVjdG9yKQpgYGAKCiMjIFJ1biBHU0VBCgpOb3cgZm9yIHRoZSBhbmFseXNpcyEKCldlIGNhbiB1c2UgdGhlIGBHU0VBKClgIGZ1bmN0aW9uIHRvIHBlcmZvcm0gR1NFQSB3aXRoIGFueSBnZW5lcmljIHNldCBvZiBnZW5lIHNldHMsIGJ1dCB0aGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgZm9yIHVzaW5nIHNwZWNpZmljLCBjb21tb25seSB1c2VkIGdlbmUgc2V0cyAoZS5nLiwgYGdzZUtFR0coKWApLgoKYGBge3IgcnVuX2dzZWF9CmdzZWFfcmVzdWx0cyA8LSBHU0VBKGdlbmVMaXN0ID0gbGZjX3ZlY3RvciwgICMgb3JkZXJlZCByYW5rZWQgZ2VuZSBsaXN0CiAgICAgICAgICAgICAgICAgICAgIG1pbkdTU2l6ZSA9IDI1LCAgIyBtaW5pbXVtIGdlbmUgc2V0IHNpemUKICAgICAgICAgICAgICAgICAgICAgbWF4R1NTaXplID0gNTAwLCAgIyBtYXhpbXVtIGdlbmUgc2V0IHNldAogICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgICAgICBwQWRqdXN0TWV0aG9kID0gIkJIIiwgICMgY29ycmVjdGlvbiBmb3IgbXVsdGlwbGUgaHlwb3RoZXNpcyB0ZXN0aW5nCiAgICAgICAgICAgICAgICAgICAgIFRFUk0yR0VORSA9IGRwbHlyOjpzZWxlY3QoaHNfaGFsbG1hcmtfZGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3NfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lX3N5bWJvbCkpCmBgYAoKVGhlIHdhcm5pbmcgYWJvdXQgdGllcyBtZWFucyB0aGF0IHRoZXJlIGFyZSBtdWx0aXBsZSBnZW5lcyB0aGF0IGhhdmUgdGhlIHNhbWUgbG9nMiBmb2xkIGNoYW5nZSB2YWx1ZS4KVGhpcyBwZXJjZW50YWdlIGlzIHNtYWxsIGFuZCB1bmxpa2VseSB0byBpbXBhY3Qgb3VyIHJlc3VsdHMuCkEgbGFyZ2UgbnVtYmVyIG9mIHRpZXMgbWlnaHQgdGVsbCB1cyB0aGVyZSdzIHNvbWV0aGluZyB3cm9uZyB3aXRoIG91ciBER0UgcmVzdWx0cyAoW0JhbGxlcmVhdSBfZXQgYWwuXyAyMDE4XShodHRwczovL2Jpb2luZm9ybWF0aWNzLWNvcmUtc2hhcmVkLXRyYWluaW5nLmdpdGh1Yi5pby9jcnVrLXN1bW1lci1zY2hvb2wtMjAxOC9STkFTZXEyMDE4L2h0bWwvMDZfR2VuZV9zZXRfdGVzdGluZy5uYi5odG1sKSkuCgpMZXQncyB0YWtlIGEgbG9vayBhdCB0aGUgR1NFQSByZXN1bHRzLgoKYGBge3Igdmlld19nc2VhLCBsaXZlID0gVFJVRSwgZXZhbCA9IEZBTFNFfQpWaWV3KGdzZWFfcmVzdWx0c0ByZXN1bHQgfD4KICAgICAgIGRwbHlyOjphcnJhbmdlKGRwbHlyOjpkZXNjKE5FUykpCikKYGBgCgpOb3JtYWxpemVkIGVucmljaG1lbnQgc2NvcmVzIChORVMpIGFyZSBlbnJpY2htZW50IHNjb3JlcyB0aGF0IGFyZSBzY2FsZWQgdG8gbWFrZSBnZW5lIHNldHMgdGhhdCBjb250YWluIGRpZmZlcmVudCBudW1iZXIgb2YgZ2VuZXMgY29tcGFyYWJsZS4KCkxldCdzIHdyaXRlIHRoZXNlIHJlc3VsdHMgdG8gZmlsZS4KCmBgYHtyIHdyaXRlX2dzZWF9CmdzZWFfcmVzdWx0c0ByZXN1bHQgfD4gcmVhZHI6OndyaXRlX3Rzdihnc2VhX3Jlc3VsdHNfZmlsZSkKYGBgCgojIyMgVmlzdWFsaXppbmcgR1NFQSByZXN1bHRzCgpXZSBjYW4gdmlzdWFsaXplIEdTRUEgcmVzdWx0cyBmb3IgaW5kaXZpZHVhbCBwYXRod2F5cyBvciBnZW5lIHNldHMgdXNpbmcgYGVucmljaHBsb3Q6OmdzZWFwbG90KClgLgpMZXQncyB0YWtlIGEgbG9vayBhdCAzIGRpZmZlcmVudCBwYXRod2F5cyAtLSBvbmUgd2l0aCBhIGhpZ2hseSBwb3NpdGl2ZSBORVMsIG9uZSB3aXRoIGEgaGlnaGx5IG5lZ2F0aXZlIE5FUywgYW5kIG9uZSB0aGF0IHdhcyBub3QgYSBzaWduaWZpY2FudCByZXN1bHQgLS0gdG8gZ2V0IG1vcmUgaW5zaWdodCBpbnRvIGhvdyBFUyBhcmUgY2FsY3VsYXRlZC4KCiMjIyMgSGlnaGx5IFBvc2l0aXZlIE5FUwoKVGhlIGdlbmUgc2V0IGBIQUxMTUFSS19NWUNfVEFSR0VUU19WMWAgaGFkIGhpZ2ggcG9zaXRpdmUgbG9nMiBmb2xkIGNoYW5nZXMuClJlY2FsbCBhIHBvc2l0aXZlIGxvZzIgZm9sZCBjaGFuZ2UgbWVhbnMgYSBpdCBoYWQgYSBoaWdoZXIgZXhwcmVzc2lvbiB2YWx1ZSBpbiBfTVlDTl8gYW1wbGlmaWVkIGNlbGwgbGluZXMuCgpgYGB7ciBteWNfdjF9CmVucmljaHBsb3Q6OmdzZWFwbG90KGdzZWFfcmVzdWx0cywKICAgICAgICAgICAgICAgICAgICAgZ2VuZVNldElEID0gIkhBTExNQVJLX01ZQ19UQVJHRVRTX1YxIiwKICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiSEFMTE1BUktfTVlDX1RBUkdFVFNfVjEiLAogICAgICAgICAgICAgICAgICAgICBjb2xvci5saW5lID0gIiMwMDY2RkYiKQpgYGAKCk5vdGljZSBob3cgdGhlIGdlbmVzIHRoYXQgYXJlIGluIHRoZSBnZW5lIHNldCwgaW5kaWNhdGVkIGJ5IHRoZSBibGFjayBiYXJzLCB0ZW5kIHRvIGJlIG9uIHRoZSBsZWZ0IHNpZGUgb2YgdGhlIGdyYXBoIGluZGljYXRpbmcgdGhhdCB0aGV5IGhhdmUgcG9zaXRpdmUgZ2VuZS1sZXZlbCBzY29yZXMuCgojIyMjIEhpZ2hseSBOZWdhdGl2ZSBORVMKClRoZSBnZW5lIHNldCBgSEFMTE1BUktfSU5URVJGRVJPTl9BTFBIQV9SRVNQT05TRWAgaGFkIGEgaGlnaGx5IG5lZ2F0aXZlIE5FUy4KCmBgYHtyIGluZmxhbW1hdG9yeX0KZW5yaWNocGxvdDo6Z3NlYXBsb3QoZ3NlYV9yZXN1bHRzLAogICAgICAgICAgICAgICAgICAgICBnZW5lU2V0SUQgPSAiSEFMTE1BUktfSU5URVJGRVJPTl9BTFBIQV9SRVNQT05TRSIsCiAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkhBTExNQVJLX0lOVEVSRkVST05fQUxQSEFfUkVTUE9OU0UiLAogICAgICAgICAgICAgICAgICAgICBjb2xvci5saW5lID0gIiMwMDY2RkYiKQpgYGAKClRoaXMgZ2VuZSBzZXQgc2hvd3MgdGhlIG9wcG9zaXRlIHBhdHRlcm4gLS0gZ2VuZXMgaW4gdGhlIHBhdGh3YXkgdGVuZCB0byBiZSBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgZ3JhcGguCgojIyMjIEEgbm9uLXNpZ25pZmljYW50IHJlc3VsdAoKVGhlIGBAcmVzdWx0c2Agc2xvdCB3aWxsIG9ubHkgc2hvdyBnZW5lIHNldHMgdGhhdCBwYXNzIHRoZSBgcHZhbHVlQ3V0b2ZmYCB0aHJlc2hvbGQgd2Ugc3VwcGxpZWQgdG8gYEdTRUEoKWAsIGJ1dCB3ZSBjYW4gcGxvdCBhbnkgZ2VuZSBzZXQgc28gbG9uZyBhcyB3ZSBrbm93IGl0cyBuYW1lLgpMZXQncyBsb29rIGF0IGBIQUxMTUFSS19QNTNfUEFUSFdBWWAsIHdoaWNoIHdhcyBub3QgaW4gdGhlIHJlc3VsdHMgd2Ugdmlld2VkIGVhcmxpZXIuCgpgYGB7ciBwNTMsIGxpdmUgPSBUUlVFfQplbnJpY2hwbG90Ojpnc2VhcGxvdChnc2VhX3Jlc3VsdHMsCiAgICAgICAgICAgICAgICAgICAgIGdlbmVTZXRJRCA9ICJIQUxMTUFSS19QNTNfUEFUSFdBWSIsCiAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkhBTExNQVJLX1A1M19QQVRIV0FZIiwKICAgICAgICAgICAgICAgICAgICAgY29sb3IubGluZSA9ICIjMDA2NkZGIikKYGBgCgpHZW5lcyBpbiB0aGUgcGF0aHdheSBhcmUgZGlzdHJpYnV0ZWQgbW9yZSBldmVubHkgdGhyb3VnaG91dCB0aGUgcmFua2VkIGxpc3QsIHJlc3VsdGluZyBpbiBhIG1vcmUgIm1pZGRsaW5nIiBzY29yZS4KCipOb3RlOiBUaGUgcGxvdHMgcmV0dXJuZWQgYnkgYGVucmljaHBsb3Q6OmdzZWFwbG90YCBhcmUgZ2dwbG90cywgc28gd2UgY291bGQgdXNlIGBnZ3Bsb3QyOjpnZ3NhdmUoKWAgdG8gc2F2ZSB0aGVtIHRvIGZpbGUgaWYgd2Ugd2FudGVkIHRvLioKCiMjIFNlc3Npb24gSW5mbwoKYGBge3Igc2Vzc2lvbl9pbmZvfQpzZXNzaW9uSW5mbygpCmBgYAo=
@@ -825,7 +3490,7 @@

Session Info

$(document).ready(function () { $('.tabset-dropdown > .nav-tabs > li').click(function () { - $(this).parent().toggleClass('nav-tabs-open') + $(this).parent().toggleClass('nav-tabs-open'); }); }); @@ -841,6 +3506,9 @@

Session Info