diff --git a/RNA-seq/02-gastric_cancer_tximeta.nb.html b/RNA-seq/02-gastric_cancer_tximeta.nb.html index 778bfb98..36238c1a 100644 --- a/RNA-seq/02-gastric_cancer_tximeta.nb.html +++ b/RNA-seq/02-gastric_cancer_tximeta.nb.html @@ -3264,8 +3264,8 @@
# Summarize to the gene level
gene_summarized <- summarizeToGene(txi_data)
-
-loading existing EnsDb created: 2024-12-04 21:59:44
+
+loading existing EnsDb created: 2024-12-06 16:59:27
obtaining transcript-to-gene mapping from database
diff --git a/scRNA-seq-advanced/02-dataset_integration-live.Rmd b/scRNA-seq-advanced/02-dataset_integration-live.Rmd
index 107bc35c..ca0a06f2 100644
--- a/scRNA-seq-advanced/02-dataset_integration-live.Rmd
+++ b/scRNA-seq-advanced/02-dataset_integration-live.Rmd
@@ -702,9 +702,8 @@ Like `fastMNN`, `harmony` performs integration on a merged PCA matrix.
However, unlike `fastMNN`, `harmony` does not "back-calculate" corrected expression from the corrected PCA matrix and it only returns the corrected PCA matrix itself.
For input, `harmony` needs a couple pieces of information:
-- First, `harmony` can either take a matrix of normalized expression values, from which it will calculate a batch-weighted PCA matrix to integrate, or it can take a batch-weighted PCA matrix directly to perform integration.
-Since we already calculated a batch-weighted PCA matrix (our `merged_PCA` reduced dimension), we'll provide this information directly.
- - We will need to specify the additional argument `do_pca=FALSE` to tell `harmony` that the input matrix we provided already is a PCA matrix.
+- First, `harmony` takes a batch-weighted PCA matrix to perform integration.
+We already calculated a batch-weighted PCA matrix (our `merged_PCA` reduced dimension), we'll provide this as the the input.
- Second, we need to tell `harmony` about the covariates to use - `sample` and `patient`.
To do this, we provide two arguments:
- `meta_data`, a data frame that contains covariates across samples.
@@ -715,8 +714,7 @@ To do this, we provide two arguments:
Let's go!
```{r run harmony, live = TRUE}
-# integrate with harmony, setting the argument `do_pca = FALSE`
-# since we are providing a PCA matrix directly
+# Run harmony integration
```
diff --git a/scRNA-seq-advanced/02-dataset_integration.nb.html b/scRNA-seq-advanced/02-dataset_integration.nb.html
index ff74f293..5a02c685 100644
--- a/scRNA-seq-advanced/02-dataset_integration.nb.html
+++ b/scRNA-seq-advanced/02-dataset_integration.nb.html
@@ -4557,17 +4557,10 @@ harmony
harmony
needs a couple pieces of
information:
harmony
can either take a matrix of normalized
-expression values, from which it will calculate a batch-weighted PCA
-matrix to integrate, or it can take a batch-weighted PCA matrix directly
-to perform integration. Since we already calculated a batch-weighted PCA
-matrix (our merged_PCA
reduced dimension), we’ll provide
-this information directly.
-do_pca=FALSE
to tell harmony
that the input
-matrix we provided already is a PCA matrix.harmony
takes a batch-weighted PCA matrix to
+perform integration. We already calculated a batch-weighted PCA matrix
+(our merged_PCA
reduced dimension), we’ll provide this as
+the the input.harmony
about the covariates to
use - sample
and patient
. To do this, we
provide two arguments:
@@ -4584,25 +4577,14 @@ harmony
Let’s go!
- -# integrate with harmony, setting the argument `do_pca = FALSE`
-# since we are providing a PCA matrix directly
-harmony_pca <- harmony::HarmonyMatrix(
+
+# Run harmony integration
+harmony_pca <- harmony::RunHarmony(
data_mat = reducedDim(merged_sce, "merged_PCA"),
- do_pca = FALSE,
meta_data = colData(merged_sce),
vars_use = c("sample", "patient")
)
-
-Warning in harmony::HarmonyMatrix(data_mat = reducedDim(merged_sce,
-"merged_PCA"), : HarmonyMatrix is deprecated and will be removed in the future
-from the API in the future
-
-
-Warning: Warning: The parameters do_pca and npcs are deprecated. They will be ignored for this function call and please remove parameters do_pca and npcs and pass to harmony cell_embeddings directly.
-This warning is displayed once per session.
-
Transposing data matrix
@@ -4829,7 +4811,7 @@ Print session info
-LS0tCnRpdGxlOiAiSW50ZWdyYXRpbmcgc2NSTkEtc2VxIGRhdGFzZXRzIgphdXRob3I6IERhdGEgTGFiIGZvciBBTFNGCmRhdGU6IDIwMjMKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogMwogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKIyMgT2JqZWN0aXZlcwoKVGhpcyBub3RlYm9vayB3aWxsIGRlbW9uc3RyYXRlIGhvdyB0bzoKCi0gUHJlcGFyZSBTQ0Ugb2JqZWN0cyBmb3IgaW50ZWdyYXRpb24KLSBBcHBseSBpbnRlZ3JhdGlvbiBtZXRob2RzIGluY2x1ZGluZyBgZmFzdE1OTmAgYW5kIGBoYXJtb255YAotIFZpc3VhbGx5IGV4cGxvcmUgdGhlIHJlc3VsdHMgb2YgaW50ZWdyYXRpb24KLSBVc2UgYHB1cnJyOjptYXAoKWAgZnVuY3Rpb25zIGZvciBpdGVyYXRpbmcgb3ZlciBsaXN0cwoKLS0tCgpJbiB0aGlzIG5vdGVib29rLCB3ZSdsbCBwZXJmb3JtIGludGVncmF0aW9uIG9uIHNjUk5BLXNlcSBkYXRhc2V0cyBmcm9tIHRoZSBbU2luZ2xlLWNlbGwgUGVkaWF0cmljIENhbmNlciBBdGxhcyAoYFNjUENBYCldKGh0dHBzOi8vc2NwY2EuYWxleHNsZW1vbmFkZS5vcmcvKSwgYSBkYXRhYmFzZSBvZiB1bmlmb3JtbHktcHJvY2Vzc2VkIHBlZGlhdHJpYyBzY1JOQS1zZXEgZGF0YSBidWlsdCBhbmQgbWFpbnRhaW5lZCBieSB0aGUgRGF0YSBMYWIuClRoZSBgU2NQQ0FgIGRhdGFiYXNlIGN1cnJlbnRseSBob3N0cyBzaW5nbGUtY2VsbCBwZWRpYXRyaWMgY2FuY2VyIHRyYW5zY3JpcHRvbWljIGRhdGEgZ2VuZXJhdGVkIGJ5IEFMU0YtZnVuZGVkIGxhYnMsIHdpdGggdGhlIGdvYWwgb2YgbWFraW5nIHRoaXMgZGF0YSBlYXNpbHkgYWNjZXNzaWJsZSB0byBpbnZlc3RpZ2F0b3JzIChsaWtlIHlvdSEpLgpUaGUgZXhwcmVzc2lvbiBkYXRhIGluIGBTY1BDQWAgd2VyZSBtYXBwaW5nIGFuZCBxdWFudGlmaWVkIHdpdGggW2BhbGV2aW4tZnJ5YF0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwMzgvczQxNTkyLTAyMi0wMTQwOC0zKSwgZm9sbG93ZWQgYnkgcHJvY2Vzc2luZyB3aXRoIEJpb2NvbmR1Y3RvciB0b29scyB1c2luZyB0aGUgc2FtZSBnZW5lcmFsIHByb2NlZHVyZXMgdGhhdCB3ZSBoYXZlIGNvdmVyZWQgaW4gdGhpcyB3b3Jrc2hvcC4KVGhlIHByb2Nlc3NpbmcgcGlwZWxpbmUgdXNlZCBgZW1wdHlEcm9wc0NlbGxSYW5nZXIoKWAgYW5kIGBtaVFDYCB0byBmaWx0ZXIgdGhlIHJhdyBjb3VudHMgbWF0cml4LCBgc2N1dHRsZWAgdG8gbG9nLW5vcm1hbGl6ZSB0aGUgY291bnRzLCBhbmQgYHNjYXRlcmAgZm9yIGRpbWVuc2lvbiByZWR1Y3Rpb24uClRoZSBwcm9jZXNzZWQgZGF0YSBhcmUgc3RvcmVkIGFzIGAucmRzYCBmaWxlcyBjb250YWluaW5nIGBTaW5nbGVDZWxsRXhwZXJpbWVudGAgb2JqZWN0cy4KWW91IGNhbiByZWFkIG1vcmUgYWJvdXQgaG93IGRhdGEgaW4gdGhlIGBTY1BDQWAgaXMgcHJvY2Vzc2VkIGluIFt0aGUgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uXShodHRwczovL3NjcGNhLnJlYWR0aGVkb2NzLmlvL2VuL2xhdGVzdC8pLgoKCiFbU2luZ2xlLWNlbGwgcm9hZG1hcDogSW50ZWdyYXRpb24gT3ZlcnZpZXddKGRpYWdyYW1zL3JvYWRtYXBfbXVsdGlfbWVyZ2UtaW50ZWdyYXRlLnBuZykKClRvIGxlYXJuIGFib3V0IGludGVncmF0aW9uLCB3ZSdsbCBoYXZlIGEgbG9vayBhdCBmb3VyIHNhbXBsZXMgZnJvbSB0aGUgW2BTQ1BDUDAwMDAwNWAgcHJvamVjdF0oaHR0cHM6Ly9zY3BjYS5hbGV4c2xlbW9uYWRlLm9yZy9wcm9qZWN0cy9TQ1BDUDAwMDAwNSkgKFtQYXRlbCBfZXQgYWwuXyAyMDIyXShodHRwczovL2RvaS5vcmcvMTAuMTAxNi9qLmRldmNlbC4yMDIyLjA0LjAwMykpLCBhbiBpbnZlc3RpZ2F0aW9uIG9mIHBlZGlhdHJpYyBzb2xpZCB0dW1vcnMgbGVkIGJ5IHRoZSBbRHllcl0oaHR0cHM6Ly93d3cuc3RqdWRlLm9yZy9yZXNlYXJjaC9sYWJzL2R5ZXItbGFiLmh0bWwpIGFuZCBbQ2hlbl0oaHR0cHM6Ly93d3cuc3RqdWRlLm9yZy9yZXNlYXJjaC9sYWJzL2NoZW4tbGFiLXRhb3NoZW5nLmh0bWwpIGxhYnMgYXQgU3QuIEp1ZGUgQ2hpbGRyZW4ncyBSZXNlYXJjaCBIb3NwaXRhbC4KVGhlIHBhcnRpY3VsYXIgbGlicmFyaWVzIHdlJ2xsIGludGVncmF0ZSBjb21lIGZyb20gdHdvIHJoYWJkb215b3NhcmNvbWEgKFJNUykgcGF0aWVudHMsIHdpdGggdHdvIHNhbXBsZXMgZnJvbSBlYWNoIG9mIHR3byBwYXRpZW50cywgYWxsIHNlcXVlbmNlZCB3aXRoIDEweCBDaHJvbWl1bSB2MyB0ZWNobm9sb2d5LgpFYWNoIGxpYnJhcnkgaXMgZnJvbSBhIHNlcGFyYXRlIGJpb2xvZ2ljYWwgc2FtcGxlLgoKV2UnbGwgYmUgaW50ZWdyYXRpbmcgdGhlc2Ugc2FtcGxlcyB3aXRoIHR3byBkaWZmZXJlbnQgdG9vbHMsIFtgZmFzdE1OTmBdKGh0dHA6Ly93d3cuYmlvY29uZHVjdG9yLm9yZy9wYWNrYWdlcy8zLjE2L2Jpb2MvaHRtbC9iYXRjaGVsb3IuaHRtbCkgKFtIYWdodmVyZGkgX2V0IGFsLl8gMjAxOF0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwMzgvbmJ0LjQwOTEpKSBhbmQgW2BoYXJtb255YF0oaHR0cHM6Ly9wb3J0YWxzLmJyb2FkaW5zdGl0dXRlLm9yZy9oYXJtb255LykgKFtLb3JzdW5za3kgX2V0IGFsLl8gMjAxOV0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwMzgvczQxNTkyLTAxOS0wNjE5LTApKS4KSW50ZWdyYXRpb24gY29ycmVjdHMgZm9yIGJhdGNoIGVmZmVjdHMgdGhhdCBhcmlzZSBmcm9tIGRpZmZlcmVudCBsaWJyYXJ5IHByZXBhcmF0aW9ucywgZ2VuZXRpYyBiYWNrZ3JvdW5kcywgYW5kIG90aGVyIHNhbXBsZS1zcGVjaWZpYyBmYWN0b3JzLCBzbyB0aGF0IGRhdGFzZXRzIGNhbiBiZSBqb2ludGx5IGFuYWx5emVkIGF0IHRoZSBjZWxsIGxldmVsLgpgZmFzdE1OTmAgY29ycmVjdHMgZm9yIGJhdGNoIGVmZmVjdHMgdXNpbmcgYSBmYXN0ZXIgdmFyaWFudCBvZiB0aGUgbXV0dWFsLW5lYXJlc3QgbmVpZ2hib3JzIGFsZ29yaXRobSwgdGhlIHRlY2huaWNhbCBkZXRhaWxzIG9mIHdoaWNoIHlvdSBjYW4gbGVhcm4gbW9yZSBhYm91dCBmcm9tIHRoaXMgW3ZpZ25ldHRlIGJ5IEx1biAoMjAxOSldKGh0dHBzOi8vbWFyaW9uaWxhYi5naXRodWIuaW8vRnVydGhlck1OTjIwMTgvdGhlb3J5L2Rlc2NyaXB0aW9uLmh0bWwpLgpgaGFybW9ueWAsIG9uIHRoZSBvdGhlciBoYW5kLCBjb3JyZWN0cyBmb3IgYmF0Y2ggZWZmZWN0cyB1c2luZyBhbiBpdGVyYXRpdmUgY2x1c3RlcmluZyBhcHByb2FjaCwgYW5kIHVubGlrZSBgZmFzdE1OTmAsIGl0IGlzIGFsc28gYWJsZSB0byBjb25zaWRlciBhZGRpdGlvbmFsIGNvdmFyaWF0ZXMgYmV5b25kIGp1c3QgdGhlIGJhdGNoIGdyb3VwaW5ncy4KClJlZ2FyZGxlc3Mgb2Ygd2hpY2ggaW50ZWdyYXRpb24gdG9vbCBpcyB1c2VkLCB0aGUgYFNpbmdsZUNlbGxFeHBlcmltZW50YCAoU0NFKSBvYmplY3RzIGZpcnN0IG5lZWQgdG8gYmUgcmVmb3JtYXR0ZWQgYW5kIG1lcmdlZCBpbnRvIGEgc2luZ2xlICh1bmNvcnJlY3RlZCEpIFNDRSBvYmplY3QgdGhhdCBjb250YWlucyBhbGwgY2VsbHMgZnJvbSBhbGwgc2FtcGxlcy4KVGhpcyBtZXJnZWQgU0NFIGNhbiB0aGVuIGJlIHVzZWQgZm9yIGludGVncmF0aW9uIHRvIG9idGFpbiBhIGZvcm1hbGx5IGJhdGNoLWNvcnJlY3RlZCBTQ0Ugb2JqZWN0LgoKCiMjIFNldCB1cAoKYGBge3Igc2V0dXB9CiMgTG9hZCBsaWJyYXJpZXMKbGlicmFyeShnZ3Bsb3QyKSAgIyBwbG90dGluZyB0b29scwpsaWJyYXJ5KFNpbmdsZUNlbGxFeHBlcmltZW50KSAjIHdvcmsgd2l0aCBTQ0Ugb2JqZWN0cwoKIyBTZXQgdGhlIHNlZWQgZm9yIHJlcHJvZHVjaWJpbGl0eQpzZXQuc2VlZCgxMjM0NSkKYGBgCgoKIyMjIERpcmVjdG9yaWVzIGFuZCBmaWxlcwoKCldlIGhhdmUgYWxyZWFkeSBwcmVwYXJlZCBjb3VudCBkYXRhIGZvciB0aGUgZm91ciBzYW1wbGVzIHdlJ2xsIGJlIGludGVncmF0aW5nIChpLmUuLCBmaWx0ZXJlZCBjZWxscywgbm9ybWFsaXplZCBjb3VudHMsIGFuZCBjYWxjdWxhdGVkIFBDQSAmIFVNQVApLgpUaGVzZSBTQ0Ugb2JqZWN0cywgc3RvcmVkIGFzIFJEUyBmaWxlcywgYXJlIGF2YWlsYWJsZSBpbiB0aGUgYGRhdGEvcm1zL3Byb2Nlc3NlZC9gIGRpcmVjdG9yeSBhbmQgYXJlIG5hbWVkIGFjY29yZGluZyB0byB0aGVpciBgU2NQQ0FgIGxpYnJhcnkgaWRzIDoKCi0gYFNDUENMMDAwNDc5LnJkc2AgKFBhdGllbnQgQSkKLSBgU0NQQ0wwMDA0ODAucmRzYCAoUGF0aWVudCBBKQotIGBTQ1BDTDAwMDQ4MS5yZHNgIChQYXRpZW50IEIpCi0gYFNDUENMMDAwNDgyLnJkc2AgKFBhdGllbnQgQikKClRvIGJlZ2luLCBsZXQncyBzZXQgdXAgb3VyIGRpcmVjdG9yaWVzIGFuZCBmaWxlczoKCmBgYHtyIGRpcmVjdG9yaWVzLCBsaXZlID0gVFJVRX0KIyBEZWZpbmUgZGlyZWN0b3J5IHdoZXJlIHByb2Nlc3NlZCBTQ0Ugb2JqZWN0cyB0byBiZSBpbnRlZ3JhdGVkIGFyZSBzdG9yZWQKaW5wdXRfZGlyIDwtIGZpbGUucGF0aCgiZGF0YSIsICJybXMiLCAicHJvY2Vzc2VkIikKCiMgRGVmaW5lIGRpcmVjdG9yeSB0byBzYXZlIGludGVncmF0ZWQgU0NFIG9iamVjdCB0bwpvdXRwdXRfZGlyIDwtIGZpbGUucGF0aCgiZGF0YSIsICJybXMiLCAiaW50ZWdyYXRlZCIpCgojIENyZWF0ZSBvdXRwdXQgZGlyZWN0b3J5IGlmIGl0IGRvZXNuJ3QgZXhpc3QKZnM6OmRpcl9jcmVhdGUob3V0cHV0X2RpcikKCiMgRGVmaW5lIG91dHB1dCBmaWxlIG5hbWUgZm9yIHRoZSBpbnRlZ3JhdGVkIG9iamVjdAppbnRlZ3JhdGVkX3NjZV9maWxlIDwtIGZpbGUucGF0aChvdXRwdXRfZGlyLCAicm1zX2ludGVncmF0ZWRfc3Vic2V0LnJkcyIpCmBgYAoKCldlIGNhbiB1c2UgdGhlIGBkaXIoKWAgZnVuY3Rpb24gdG8gbGlzdCBhbGwgY29udGVudHMgb2YgYSBnaXZlbiBkaXJlY3RvcnksIGZvciBleGFtcGxlIHRvIHNlZSBhbGwgdGhlIGZpbGVzIGluIG91ciBgaW5wdXRfZGlyYDoKCmBgYHtyIGlucHV0IGRpciwgbGl2ZSA9IFRSVUV9CmRpcihpbnB1dF9kaXIpCmBgYAoKV2Ugd2FudCB0byByZWFkIGluIGp1c3QgZm91ciBvZiB0aGVzZSBmaWxlcywgYXMgbGlzdGVkIHByZXZpb3VzbHkuClRvIHJlYWQgaW4gdGhlc2UgZmlsZXMsIHdlIGNvdWxkIHVzZSB0aGUgYHJlYWRyOjpyZWFkX3JkcygpYCBmdW5jdGlvbiAob3IgdGhlIGJhc2UgUiBgcmVhZFJEUygpYCkgZm91ciB0aW1lcywgb25jZSBmb3IgZWFjaCBvZiB0aGUgZmlsZXMuCldlIGNvdWxkIGFsc28gdXNlIGEgYGZvcmAgbG9vcCwgd2hpY2ggaXMgdGhlIGFwcHJvYWNoIHRoYXQgbWFueSBwcm9ncmFtbWluZyBsYW5ndWFnZXMgd291bGQgbGVhbiB0b3dhcmQuCkEgZGlmZmVyZW50IGFuZCBtb3JlIG1vZHVsYXIgY29kaW5nIGFwcHJvYWNoIHRvIHJlYWRpbmcgaW4gdGhlc2UgZmlsZXMgKGFuZCBtb3JlISkgaXMgdG8gbGV2ZXJhZ2UgdGhlIFtgcHVycnJgXShodHRwczovL3B1cnJyLnRpZHl2ZXJzZS5vcmcvKSBgdGlkeXZlcnNlYCBwYWNrYWdlLCB3aGljaCBwcm92aWRlcyBhIGNvbnZlbmllbnQgc2V0IG9mIGZ1bmN0aW9ucyBmb3Igb3BlcmF0aW5nIG9uIGxpc3RzLgpZb3UgY2FuIHJlYWQgbW9yZSBhYm91dCB0aGUgYHB1cnJyYCBmdW5jdGlvbnMgYW5kIHRoZWlyIHBvd2VyIGFuZCB1dGlsaXR5IGluIFIgaW4gW3RoZSAiRnVuY3Rpb25hbHMiIGNoYXB0ZXIgb2YgdGhlIF9BZHZhbmNlZCBSXyBlLWJvb2tdKGh0dHBzOi8vYWR2LXIuaGFkbGV5Lm56L2Z1bmN0aW9uYWxzLmh0bWwpLgoKT2YgcGFydGljdWxhciBpbnRlcmVzdCBpcyB0aGUgW2BwdXJycjo6bWFwKClgXShodHRwczovL3B1cnJyLnRpZHl2ZXJzZS5vcmcvcmVmZXJlbmNlL21hcC5odG1sKSBmYW1pbHkgb2YgZnVuY3Rpb25zLCB3aGljaCBjYW4gYmUgdXNlZCB0byBydW4gYSBnaXZlbiBmdW5jdGlvbiBvbiBlYWNoIGVsZW1lbnQgb2YgYSBsaXN0IChvciB2ZWN0b3IpIGluIG9uZSBjYWxsLgpUaGUgZ2VuZXJhbCBzeW50YXggZm9yIGBwdXJycjo6bWFwKClgIGFuZCBmcmllbmRzIGlzOgoKYGBgCiMgU3ludGF4IGZvciB1c2luZyB0aGUgbWFwIGZ1bmN0aW9uOgpwdXJycjo6bWFwKDxpbnB1dCBsaXN0IG9yIHZlY3Rvcj4sCiAgICAgICAgICAgPGZ1bmN0aW9uIHRvIGFwcGx5IHRvIGVhY2ggaXRlbSBpbiB0aGUgaW5wdXQ+LAogICAgICAgICAgIDxhbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgdG8gdGhlIGZ1bmN0aW9uIGNhbiBnbyBoZXJlPiwKICAgICAgICAgICA8YW5kIGFsc28gaGVyZSBpZiB0aGVyZSBhcmUgZXZlbiBtb3JlIGFyZ3VtZW50cywgYW5kIHNvIG9uPikKYGBgCgoKVGhlIG91dHB1dCBmcm9tIHJ1bm5pbmcgYHB1cnJyOjptYXAoKWAgaXMgYWx3YXlzIGEgbGlzdCAoYnV0IG5vdGUgdGhhdCB0aGVyZSBhcmUgb3RoZXIgYHB1cnJyOjptYXAoKWAgcmVsYXRpdmVzIHdoaWNoIHJldHVybiBvdGhlciBvYmplY3QgdHlwZXMsIGFzIHlvdSBjYW4gcmVhZCBhYm91dCBpbiBbdGhlIGBwdXJycjo6bWFwKClgIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vcHVycnIudGlkeXZlcnNlLm9yZy9yZWZlcmVuY2UvaW5kZXguaHRtbCkpLgpJZiB0aGlzIGNvbmNlcHQgc291bmRzIGEgbGl0dGxlIGZhbWlsaWFyIHRvIHlvdSwgdGhhdCdzIGJlY2F1c2UgaXQgcHJvYmFibHkgaXMhCkJhc2UgUidzIGBsYXBwbHkoKWAgZnVuY3Rpb24gY2FuIHByb3ZpZGUgc2ltaWxhciB1dGlsaXR5LCBhbmQgdGhlIGBwdXJycjo6bWFwKClgIGZhbWlseSBvZiBmdW5jdGlvbnMgY2FuIChpbiBwYXJ0KSBiZSB0aG91Z2h0IG9mIGFzIGFuIGFsdGVybmF0aXZlIHRvIHNvbWUgb2YgdGhlIGJhc2UgUiBgYXBwbHlgIGZ1bmN0aW9ucywgd2l0aCBtb3JlIGNvbnNpc3RlbnQgYmVoYXZpb3IuCgpMZXQncyBzZWUgYSB2ZXJ5IHNpbXBsZSBleGFtcGxlIG9mIGBwdXJycjo6bWFwKClgIGluIGFjdGlvbiwgaW5zcGlyZWQgYnkgY2FuY2VyIGdyb3VwcyB0aGUgRGF0YSBMYWIgaGFzIGFuYWx5emVkIHRocm91Z2ggdGhlIFtPcGVuUEJUQV0oaHR0cHM6Ly9naXRodWIuY29tL0FsZXhzTGVtb25hZGUvT3BlblBCVEEtYW5hbHlzaXMvKSBwcm9qZWN0OgoKYGBge3IgbWFwIGV4YW1wbGV9CiMgRGVmaW5lIGEgbGlzdCBvZiBjYW5jZXIgaGlzdG9sb2dpZXMKaGlzdG9sb2dpZXMgPC0gbGlzdCgKICAibG93LWdyYWRlIGdsaW9tYXMiICA9IGMoIlNFR0EiLCAiUEEiLCAiR05HIiwgIlBYQSIpLAogICJoaWdoLWdyYWRlIGdsaW9tYXMiID0gYygiRE1HIiwgIkRJUEciKSwKICAiZW1icnlvbmFsIHR1bW9ycyIgICA9IGMoIk1CIiwgIkFUUlQiLCAiRVRNUiIpCiApCgojIFRoZSBvdmVyYWxsIGxlbmd0aCBvZiB0aGUgbGlzdCBpcyAzCmxlbmd0aChoaXN0b2xvZ2llcykKCiMgSG93IGNhbiB3ZSBydW4gYGxlbmd0aCgpYCBvbiBlYWNoIGl0ZW0gb2YgdGhlIGxpc3Q/CiMgV2UgY2FuIHVzZSBvdXIgbmV3IGZyaWVuZCBwdXJycjo6bWFwKCk6CnB1cnJyOjptYXAoaGlzdG9sb2dpZXMsIGxlbmd0aCkKYGBgCgpPbmUgb3RoZXIgbmV3IGNvZGluZyBzdHJhdGVneSB3ZSdsbCBsZWFybiBpbiB0aGlzIG5vdGVib29rIGlzIHVzaW5nIHRoZSBbYGdsdWVgXShodHRwczovL2dsdWUudGlkeXZlcnNlLm9yZy8pIHBhY2thZ2UgdG8gY29tYmluZSBzdHJpbmdzLgpUaGlzIHBhY2thZ2Ugb2ZmZXJzIGEgY29udmVuaWVudCBmdW5jdGlvbiBgZ2x1ZTo6Z2x1ZSgpYCB0aGF0IGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIGJhc2UgUiBgcGFzdGUoKWAgZnVuY3Rpb24uCgpgYGB7ciBwYXN0ZX0KIyBEZWZpbmUgYSB2YXJpYWJsZSBmb3IgZXhhbXBsZToKb3JnX25hbWUgPC0gIkRhdGEgTGFiIgoKIyBXZSBjYW4gdXNlIHBhc3RlIHRvIGNvbWJpbmUgc3RyaW5ncyBhbmQgdmFyaWFibGVzOgpwYXN0ZSgiV2VsY29tZSB0byB0aGUiLCBvcmdfbmFtZSwgIndvcmtzaG9wIG9uIEFkdmFuY2VkIHNjUk5BLXNlcSEiKQpgYGAKCldlIGNhbiB1c2UgYGdsdWU6OmdsdWUoKWAgdG8gYWNjb21wbGlzaCB0aGUgc2FtZSBnb2FsIHdpdGggc29tZSBkaWZmZXJlbnQgc3ludGF4OgoKYGBge3IgZ2x1ZX0KIyBnbHVlOjpnbHVlIHRha2VzIGEgc2luZ2xlIHN0cmluZyBhcmd1bWVudCAob25seSBvbmUgc2V0IG9mIHF1b3RlcyEpLCBhbmQKIyAgdmFyaWFibGVzIGNhbiBlYXNpbHkgYmUgaW5jbHVkZWQgaW5zaWRlIHtjdXJseSBicmFjZXN9CmdsdWU6OmdsdWUoIldlbGNvbWUgdG8gdGhlIHtvcmdfbmFtZX0gd29ya3Nob3Agb24gQWR2YW5jZWQgc2NSTkEtc2VxISIpCmBgYAoKKE5vdGUgdGhhdCBldmVuIHRob3VnaCB0aGUgYGdsdWU6OmdsdWUoKWAgb3V0cHV0IGlzbid0IGluIHF1b3RlcywgaXQgc3RpbGwgYmVoYXZlcyBsaWtlIGEgc3RyaW5nISkKCgpBbHJpZ2h0LCB0aW1lIGZvciB0aGUgZ29vZCBzdHVmZiEKTGV0J3MgdXNlIGBwdXJycjo6bWFwKClgIHRvIHJlYWQgaW4gb3VyIFNDRSBvYmplY3RzIHNvIHRoYXQgdGhleSBhcmUgaW1tZWRpYXRlbHkgc3RvcmVkIHRvZ2V0aGVyIGluIGEgbGlzdC4KCgpXZSdsbCBmaXJzdCBuZWVkIHRvIGRlZmluZSBhIHZlY3RvciBvZiB0aGUgZmlsZSBwYXRocyB0byByZWFkIGluLgpXZSdsbCBzdGFydCBieSBjcmVhdGluZyBhIHZlY3RvciBvZiBzYW1wbGUgbmFtZXMgdGhlbXNlbHZlcyBhbmQgdGhlbiBmb3JtYXR0aW5nIHRoZW0gaW50byB0aGUgY29ycmVjdCBwYXRocy4KVGhpcyB3YXkgKGZvcmVzaGFkb3dpbmchKSB3ZSBhbHNvIGhhdmUgYSBzdGFuZC1hbG9uZSB2ZWN0b3Igb2YganVzdCBzYW1wbGUgbmFtZXMsIHdoaWNoIHdpbGwgY29tZSBpbiBoYW5keSEKCmBgYHtyIHNhbXBsZSBuYW1lc30KIyBWZWN0b3Igb2YgYWxsIHRoZSBzYW1wbGVzIHRvIHJlYWQgaW46CnNhbXBsZV9uYW1lcyA8LSBjKCJTQ1BDTDAwMDQ3OSIsCiAgICAgICAgICAgICAgICAgICJTQ1BDTDAwMDQ4MCIsCiAgICAgICAgICAgICAgICAgICJTQ1BDTDAwMDQ4MSIsCiAgICAgICAgICAgICAgICAgICJTQ1BDTDAwMDQ4MiIpCmBgYAoKCmBgYHtyIGRlZmluZSBzY2VfcGF0aHMsIGxpdmUgPSBUUlVFfQojIE5vdywgY29udmVydCB0aGVzZSB0byBmaWxlIHBhdGhzOiA8aW5wdXRfZGlyPi88c2FtcGxlX25hbWU+LnJkcwpzY2VfcGF0aHMgPC0gZmlsZS5wYXRoKGlucHV0X2RpciwKICAgICAgICAgICAgICAgICAgICAgICBnbHVlOjpnbHVlKCJ7c2FtcGxlX25hbWVzfS5yZHMiKQopCiMgUHJpbnQgdGhlIHNjZV9wYXRocyB2ZWN0b3IKc2NlX3BhdGhzCmBgYAoKV2UgY2FuIG5vdyByZWFkIHRoZXNlIGZpbGVzIGluIGFuZCBjcmVhdGUgYSBsaXN0IG9mIGZvdXIgU0NFIG9iamVjdHMuClNpbmNlIGByZWFkcjo6cmVhZF9yZHMoKWAgY2FuIG9ubHkgb3BlcmF0ZSBvbiBvbmUgaW5wdXQgYXQgYSB0aW1lLCB3ZSdsbCBuZWVkIHRvIHVzZSBgcHVycnI6Om1hcCgpYCB0byBydW4gaXQgb24gYWxsIGlucHV0IGZpbGUgcGF0aHMgaW4gb25lIGNvbW1hbmQuCkFsdGhvdWdoIGBzY2VfcGF0aHNgIGlzIGEgdmVjdG9yIChub3QgYSBsaXN0KSwgaXQgd2lsbCBzdGlsbCB3b3JrIGFzIGlucHV0IHRvIGBwdXJycjptYXAoKWAuClRoZSBvdXRwdXQgZnJvbSB0aGlzIGNvZGUgd2lsbCBzdGlsbCBiZSBhIGxpc3QsIHNpbmNlIHRoYXQncyB3aGF0IGBwdXJycjo6bWFwKClgIGFsd2F5cyByZXR1cm5zLgoKYGBge3IgcmVhZCBzY2UgcGF0aHMsIGxpdmUgPSBUUlVFfQojIFVzZSBwdXJycjo6bWFwKCkgdG8gcmVhZCBhbGwgZmlsZXMgaW50byBhIGxpc3QgYXQgb25jZQpzY2VfbGlzdCA8LSBwdXJycjo6bWFwKAogIHNjZV9wYXRocywKICByZWFkcjo6cmVhZF9yZHMKKQpgYGAKCkxldCdzIGhhdmUgYSBsb29rIGF0IG91ciBsaXN0IG9mIFNDRSBvYmplY3RzOgoKYGBge3IgcHJpbnQgc2NlIGxpc3QsIGxpdmU9VFJVRX0KIyBQcmludCBzY2VfbGlzdApzY2VfbGlzdApgYGAKCldlIG5vdyBoYXZlIGEgbGlzdCBvZiBsZW5ndGggZm91ciwgd2hlcmUgZWFjaCBpdGVtIGlzIGEgcHJvY2Vzc2VkIFNDRSBvYmplY3QhCkhvd2V2ZXIsIHdlJ2xsIG5lZWQgdG8ga2VlcCB0cmFjayBvZiB3aGljaCBzYW1wbGUgZWFjaCBpdGVtIGlzLCBzbyBpdCdzIGhlbHBmdWwgdG8gYWRkIF9uYW1lc18gdG8gdGhpcyBsaXN0IHJlcHJlc2VudGluZyB0aGUgcmVsZXZhbnQgc2FtcGxlIG5hbWVzLgoKYGBge3IgYWRkIGxpc3QgbmFtZXMsIGxpdmUgPSBUUlVFfQojIEFzc2lnbiB0aGUgc2FtcGxlIG5hbWVzIGFzIHRoZSBuYW1lcyBmb3Igc2NlX2xpc3QKbmFtZXMoc2NlX2xpc3QpIDwtIHNhbXBsZV9uYW1lcwpgYGAKCmBgYHtyIHByaW50IG5hbWVkIGxpc3QsIGxpdmU9VFJVRX0KIyBQcmludCB0aGUgbGlzdCB0byBzZWUgaXQgd2l0aCBuYW1lcwpzY2VfbGlzdApgYGAKCklmIHlvdSBsb29rIGNsb3NlbHkgYXQgdGhlIHByaW50ZWQgU0NFIG9iamVjdHMsIHlvdSBtYXkgbm90aWNlIHRoYXQgdGhleSBhbGwgY29udGFpbiBgY29sRGF0YWAgdGFibGUgY29sdW1ucyBgY2VsbHR5cGVfZmluZWAgYW5kIGBjZWxsdHlwZV9icm9hZGAuClRoZXNlIGNvbHVtbnMgKHdoaWNoIHdlIGFkZGVkIHRvIFNDRSBvYmplY3RzIGR1cmluZyBbcHJlLXByb2Nlc3NpbmddKGh0dHBzOi8vZ2l0aHViLmNvbS9BbGV4c0xlbW9uYWRlL3RyYWluaW5nLW1vZHVsZXMvdHJlZS9tYXN0ZXIvc2NSTkEtc2VxLWFkdmFuY2VkL3NldHVwL3JtcykpIGNvbnRhaW4gcHV0YXRpdmUgX2NlbGwgdHlwZSBhbm5vdGF0aW9uc18gYXMgYXNzaWduZWQgaW4gW1BhdGVsIF9ldCBhbC5fICgyMDIyKV0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwMTYvai5kZXZjZWwuMjAyMi4wNC4wMDMpLgpXZSB3aWxsIGVuZCB1cCBsZXZlcmFnaW5nIHRoZXNlIGNlbGwgdHlwZSBhbm5vdGF0aW9ucyB0byBleHBsb3JlIGhvdyBzdWNjZXNzZnVsIG91ciBpbnRlZ3JhdGlvbiBpczsgYWZ0ZXIgaW50ZWdyYXRpb24sIHdlIGV4cGVjdCBjZWxsIHR5cGVzIGZyb20gZGlmZmVyZW50IHNhbXBsZXMgdG8gZ3JvdXAgdG9nZXRoZXIsIHJhdGhlciB0aGFuIGJlaW5nIHNlcGFyYXRlZCBieSBiYXRjaGVzLgoKVGhhdCBzYWlkLCB0aGUgaW50ZWdyYXRpb24gbWV0aG9kcyB3ZSB3aWxsIGJlIGFwcGx5aW5nIF9kbyBub3QgYWN0dWFsbHkgdXNlXyB0aGVzZSBjZWxsIHR5cGUgYW5ub3RhdGlvbnMuCklmIHdlIGhhdmUgYW5ub3RhdGlvbnMsIHRoZXkgYXJlIGEgaGVscGZ1bCAiYm9udXMiIGZvciBhc3Nlc3NpbmcgdGhlIGludGVncmF0aW9uJ3Mgc3VjY2VzcywgYnV0IHRoZXkgYXJlIG5vdCBwYXJ0IG9mIHRoZSBpbnRlZ3JhdGlvbiBpdHNlbGYuCgoKIyMgUHJlcGFyZSB0aGUgU0NFIGxpc3QgZm9yIGludGVncmF0aW9uCgohW1NpbmdsZS1jZWxsIHJvYWRtYXA6IE1lcmdlXShkaWFncmFtcy9yb2FkbWFwX211bHRpX21lcmdlLnBuZykKCgpOb3cgdGhhdCB3ZSBoYXZlIGEgbGlzdCBvZiBwcm9jZXNzZWQgU0NFIG9iamVjdHMsIHdlIG5lZWQgdG8gbWVyZ2UgdGhlIG9iamVjdHMgaW50byBvbmUgb3ZlcmFsbCBTQ0Ugb2JqZWN0IGZvciBpbnB1dCB0byBpbnRlZ3JhdGlvbi4KQSB3b3JkIG9mIGNhdXRpb24gYmVmb3JlIHdlIGJlZ2luOiAqKlRoaXMgbWVyZ2VkIFNDRSBvYmplY3QgaXMgTk9UIGFuIGludGVncmF0ZWQgU0NFISoqCk1lcmdpbmcgU0NFcyBkb2VzIG5vdCBwZXJmb3JtIGFueSBiYXRjaCBjb3JyZWN0aW9uLCBidXQganVzdCByZW9yZ2FuaXplcyB0aGUgZGF0YSB0byBhbGxvdyB1cyB0byBwcm9jZWVkIHRvIGludGVncmF0aW9uIG5leHQuCgpUbyBtZXJnZSBTQ0Ugb2JqZWN0cywgd2UgZG8gbmVlZCB0byBkbyBzb21lIHdyYW5nbGluZyBhbmQgYm9va2tlZXBpbmcgdG8gZW5zdXJlIGNvbXBhdGliaWxpdHkgYW5kIHRoYXQgd2UgZG9uJ3QgbG9zZSBpbXBvcnRhbnQgaW5mb3JtYXRpb24uCk92ZXJhbGwgd2UnbGwgd2FudCB0byB0YWtlIGNhcmUgb2YgdGhlc2UgaXRlbXM6CgoxLiBXZSBzaG91bGQgYmUgYWJsZSB0byB0cmFjZSBzYW1wbGUtc3BlY2lmaWMgaW5mb3JtYXRpb24gYmFjayB0byB0aGUgb3JpZ2luYXRpbmcgc2FtcGxlLCBpbmNsdWRpbmcuLi4KICAgIC0gQ2VsbC1sZXZlbCBpbmZvcm1hdGlvbjogV2hpY2ggc2FtcGxlIGlzIGVhY2ggY2VsbCBmcm9tPwogICAgLSBMaWJyYXJ5LXNwZWNpZmljIGZlYXR1cmUgc3RhdGlzdGljcywgZS5nLiwgZ2VuZS1sZXZlbCBzdGF0aXN0aWNzIGZvciBhIGdpdmVuIGxpYnJhcnkgZm91bmQgaW4gYHJvd0RhdGFgLgogICAgV2hpY2ggc2FtcGxlIGlzIGEgZ2l2ZW4gZmVhdHVyZSBzdGF0aXN0aWMgZnJvbT8KMi4gU0NFIG9iamVjdHMgc2hvdWxkIGNvbnRhaW4gdGhlIHNhbWUgZ2VuZXM6IEVhY2ggU0NFIG9iamVjdCBzaG91bGQgaGF2ZSB0aGUgc2FtZSByb3cgbmFtZXMuCjMuIFNDRSBjZWxsIG1ldGFkYXRhIGNvbHVtbnMgc2hvdWxkIG1hdGNoOiBUaGUgYGNvbERhdGFgIGZvciBlYWNoIFNDRSBvYmplY3Qgc2hvdWxkIGhhdmUgdGhlIHNhbWUgY29sdW1uIG5hbWVzLgoKCldlJ2xsIGJlZ2luIGJ5IHRha2luZyBzb21lIHRpbWUgdG8gdGhvcm91Z2hseSBleHBsb3JlIG91ciBTQ0Ugb2JqZWN0cyBhbmQgZmlndXJlIG91dCB3aGF0IHdyYW5nbGluZyBzdGVwcyB3ZSBuZWVkIHRvIHRha2UgZm9yIHRoZXNlIHNwZWNpZmljIGRhdGEuCkRvbid0IHNraXAgdGhpcyBleHBsb3JhdGlvbiEKQmVhciBpbiBtaW5kIHRoYXQgdGhlIGV4YWN0IHdyYW5nbGluZyBzaG93biBoZXJlIHdpbGwgbm90IGJlIHRoZSBzYW1lIGZvciBvdGhlciBTQ0Ugb2JqZWN0cyB5b3Ugd29yayB3aXRoLCBidXQgdGhlIHNhbWUgZ2VuZXJhbCBwcmluY2lwbGVzIGFwcGx5LgoKCiMjIyMgUHJlc2VydmluZyBzYW1wbGUgaW5mb3JtYXRpb24gYXQgdGhlIGNlbGwgbGV2ZWwKCkhvdyB3aWxsIHdlIGJlIGFibGUgdG8gdGVsbCB3aGljaCBzYW1wbGUgYSBnaXZlbiBjZWxsIGNhbWUgZnJvbT8KClRoZSBiZXN0IHdheSB0byBkbyB0aGlzIGlzIHNpbXBseSB0byBhZGQgYSBgY29sRGF0YWAgY29sdW1uIHdpdGggdGhlIHNhbXBsZSBpbmZvcm1hdGlvbiwgc28gdGhhdCB3ZSBjYW4ga25vdyB3aGljaCBzYW1wbGUgZWFjaCByb3cgY2FtZSBmcm9tLgoKSW4gYWRkaXRpb24sIHdlIHdhbnQgdG8gcGF5IHNvbWUgYXR0ZW50aW9uIHRvIHRoZSBTQ0Ugb2JqZWN0J3MgY29sdW1uIG5hbWVzICh0aGUgY2VsbCBpZHMpLCB3aGljaCBtdXN0IHJlbWFpbiB1bmlxdWUgYWZ0ZXIgbWVyZ2luZyBzaW5jZSBkdXBsaWNhdGUgaWRzIHdpbGwgY2F1c2UgYW4gUiBlcnJvci4KSW4gdGhpcyBjYXNlLCB0aGUgU0NFIGNvbHVtbiBuYW1lcyBhcmUgYmFyY29kZXMgKHdoaWNoIGlzIHVzdWFsbHkgYnV0IG5vdCBhbHdheXMgdGhlIGNhc2UgaW4gU0NFIG9iamVjdHMpLCB3aGljaCBhcmUgb25seSBndWFyYW50ZWVkIHRvIGJlIHVuaXF1ZSBfd2l0aGluXyBhIHNhbXBsZSBidXQgbWF5IGJlIHJlcGVhdGVkIGFjcm9zcyBzYW1wbGVzLgpTbywgYWZ0ZXIgbWVyZ2luZywgaXQncyB0ZWNobmljYWxseSBwb3NzaWJsZSB0aGF0IG11bHRpcGxlIGNlbGxzIHdpbGwgaGF2ZSB0aGUgc2FtZSBiYXJjb2RlLgpUaGlzIHdvdWxkIGJlIGEgcHJvYmxlbSBmb3IgdHdvIHJlYXNvbnM6CkZpcnN0LCB0aGUgY2VsbCBpZCB3b3VsZCBub3QgYmUgYWJsZSB0byBwb2ludCB1cyBiYWNrIHRvIGNlbGwncyBvcmlnaW5hdGluZyBzYW1wbGUuClNlY29uZCwgaXQgd291bGQgbGl0ZXJhbGx5IGNhdXNlIGFuIGVycm9yIGluIFIsIHdoaWNoIGRvZXMgbm90IGFsbG93IGR1cGxpY2F0ZSBjb2x1bW4gbmFtZXMuCgoKT25lIHdheSB0byBlbnN1cmUgdGhhdCBjZWxsIGlkcyByZW1haW4gdW5pcXVlIGV2ZW4gYWZ0ZXIgbWVyZ2luZyBpcyB0byBhY3R1YWxseSBtb2RpZnkgdGhlbSBieSBfcHJlcGVuZGluZ18gdGhlIHJlbGV2YW50IHNhbXBsZSBuYW1lLgpGb3IgZXhhbXBsZSwgY29uc2lkZXIgdGhlc2UgYmFyY29kZXMgZm9yIHRoZSBgU0NQQ0wwMDA0NzlgIHNhbXBsZToKCmBgYHtyIGJhcmNvZGVzfQojIExvb2sgYXQgdGhlIGNvbHVtbiBuYW1lcyBmb3IgdGhlIGBTQ1BDTDAwMDQ3OWAgc2FtcGxlLCBmb3IgZXhhbXBsZQpjb2xuYW1lcyhzY2VfbGlzdCRTQ1BDTDAwMDQ3OSkgfD4KICAjIE9ubHkgcHJpbnQgb3V0IHRoZSBmaXJzdCA2IGZvciBjb252ZW5pZW5jZQogIGhlYWQoKQpgYGAKClRoZXNlIGlkcyB3aWxsIGJlIHVwZGF0ZWQgdG8gYFNDUENMMDAwNDc5LUdHR0FDQ1RDQUFHQ0dHQVRgLCBgU0NQQ0wwMDA0NzktQ0FDQUdBVEFHVEdBR1RHQ2AsIGFuZCBzbyBvbiwgdGhlcmVieSBlbnN1cmluZyBmdWxseSB1bmlxdWUgaWRzIGZvciBhbGwgY2VsbHMgYWNyb3NzIGFsbCBzYW1wbGVzLgoKIyMjIyBQcmVzZXJ2aW5nIHNhbXBsZSBpbmZvcm1hdGlvbiBhdCB0aGUgZ2VuZSBsZXZlbAoKVGhlIGByb3dEYXRhYCB0YWJsZSBpbiBTQ0Ugb2JqZWN0cyB3aWxsIG9mdGVuIGNvbnRhaW4gYm90aCAiZ2VuZXJhbCIgYW5kICJsaWJyYXJ5LXNwZWNpZmljIiBpbmZvcm1hdGlvbiwgZm9yIGV4YW1wbGU6CgpgYGB7ciByb3dkYXRhfQpyb3dEYXRhKHNjZV9saXN0JFNDUENMMDAwNDc5KSB8PgogIGhlYWQoKQpgYGAKCkhlcmUsIHRoZSByb3duYW1lcyBhcmUgRW5zZW1ibCBnZW5lIGlkcywgYW5kIGNvbHVtbnMgYXJlIGBnZW5lX3N5bWJvbGAsIGBtZWFuYCwgYW5kIGBkZXRlY3RlZGAuClRoZSBgZ2VuZV9zeW1ib2xgIGNvbHVtbiBpcyBnZW5lcmFsIGluZm9ybWF0aW9uIGFib3V0IGFsbCBnZW5lcywgbm90IHNwZWNpZmljIHRvIGFueSBsaWJyYXJ5IG9yIGV4cGVyaW1lbnQsIGJ1dCBgbWVhbmAgYW5kIGBkZXRlY3RlZGAgYXJlIGxpYnJhcnktc3BlY2lmaWMgZ2VuZSBzdGF0aXN0aWNzLgpTbywgYGdlbmVfc3ltYm9sYCBkb2VzIG5vdCBuZWVkIHRvIGJlIHRyYWNlZCBiYWNrIHRvIGl0cyBvcmlnaW5hdGluZyBzYW1wbGUsIGJ1dCBgbWVhbmAgYW5kIGBkZXRlY3RlZGAgZG8uClRvIHRoaXMgZW5kLCB3ZSBjYW4gdGFrZSBhIHNpbWlsYXIgYXBwcm9hY2ggdG8gd2hhdCB3ZSdsbCBkbyBmb3IgY2VsbCBpZHM6CldlIGNhbiBjaGFuZ2UgdGhlIHNhbXBsZS1zcGVjaWZpYyBgcm93RGF0YWAgY29sdW1uIG5hbWVzIGJ5IHByZXBlbmRpbmcgdGhlIHNhbXBsZSBuYW1lLgpGb3IgZXhhbXBsZSwgcmF0aGVyIHRoYW4gYmVpbmcgY2FsbGVkIGBtZWFuYCwgdGhpcyBjb2x1bW4gd2lsbCBiZSBuYW1lZCBgU0NQQ0wwMDA0NzktbWVhbmAgZm9yIHRoZSBgU0NQQ0wwMDA0NzlgIHNhbXBsZS4KCkFsbCBvdXIgU0NFIG9iamVjdHMgaGF2ZSB0aGUgc2FtZSBgcm93RGF0YWAgY29sdW1ucyAoYXMgd2UgY2FuIHNlZSBpbiB0aGUgbmV4dCBjaHVuayksIHNvIHdlJ2xsIHBlcmZvcm0gdGhpcyByZW5hbWluZyBhY3Jvc3MgYWxsIFNDRXMuCgpgYGB7ciBjb21wYXJlIHJvd2RhdGEsIGxpdmUgPSBUUlVFfQojIFVzZSBgcHVycnI6Om1hcCgpYCB0byBxdWlja2x5IGV4dHJhY3Qgcm93RGF0YSBjb2x1bW4gbmFtZXMgZm9yIGFsbCBTQ0VzCnB1cnJyOjptYXAoc2NlX2xpc3QsCiAgICAgICAgICAgXCh4KSBjb2xuYW1lcyhyb3dEYXRhKHgpKSkKYGBgCgoKIyMjIyBFbnN1cmluZyB0aGF0IG9ubHkgc2hhcmVkIGdlbmVzIGFyZSB1c2VkCgpUaGUgbmV4dCBzdGVwIGluIGVuc3VyaW5nIFNDRSBjb21wYXRpYmlsaXR5IGlzIHRvIG1ha2Ugc3VyZSB0aGV5IGFsbCBjb250YWluIHRoZSBzYW1lIGdlbmVzLCB3aGljaCBhcmUgc3RvcmVkIGFzIHRoZSBTQ0Ugb2JqZWN0J3Mgcm93IG5hbWVzICh0aGVzZSBuYW1lcyBhcmUgYWxzbyBmb3VuZCB0aGUgYHJvd0RhdGFgIHNsb3QncyByb3cgbmFtZXMpLgpIZXJlLCB0aG9zZSBnZW5lIGlkcyBhcmUgdW5pcXVlIEVuc2VtYmwgZ2VuZSBpZHMuCgpXZSBjYW4gdXNlIHNvbWUgYHB1cnJyYCBtYWdpYyB0byBxdWlja2x5IGZpbmQgdGhlIHNldCBvZiBzaGFyZWQgZ2VuZXMgYW1vbmcgb3VyIHNhbXBsZXM6CgpgYGB7ciBzaGFyZWQgZ2VuZXN9CiMgRGVmaW5lIHZlY3RvciBvZiBzaGFyZWQgZ2VuZXMKc2hhcmVkX2dlbmVzIDwtIHNjZV9saXN0IHw+CiAgIyBnZXQgcm93bmFtZXMgKGdlbmVzKSBmb3IgZWFjaCBTQ0UgaW4gc2NlX2xpc3QKICBwdXJycjo6bWFwKHJvd25hbWVzKSB8PgogICMgcmVkdWNlIHRvIHRoZSBfaW50ZXJzZWN0aW9uXyBhbW9uZyBsaXN0cwogIHB1cnJyOjpyZWR1Y2UoaW50ZXJzZWN0KQpgYGAKCmBgYHtyIHByaW50IHNoYXJlZCBnZW5lcywgbGl2ZSA9IFRSVUV9CiMgVXNlIGhlYWQgdG8gbG9vayBhdCB0aGUgdmVjdG9yIG9mIHNoYXJlZCBnZW5lczoKaGVhZChzaGFyZWRfZ2VuZXMpCmBgYAoKSW4gdGhpcyBjYXNlLCB3ZSBoYXBwZW4gdG8ga25vdyB0aGF0IGFsbCBTQ0Ugb2JqZWN0cyB3ZSdyZSB3b3JraW5nIHdpdGggYWxyZWFkeSBjb250YWluZWQgdGhlIHNhbWUgZ2VuZXMuCldlIGRvIGEgcXVpY2stYW5kLWRpcnR5IGNoZWNrIGZvciB0aGlzIGJ5IGxvb2tpbmcgYXQgdGhlIG51bWJlciBvZiByb3dzIGFjcm9zcyBTQ0Ugb2JqZWN0cywgYW5kIHdlJ2xsIHNlZSB0aGF0IHRoZXkgYXJlIGFsbCB0aGUgc2FtZToKCmBgYHtyIGNoZWNrIHNoYXJlZCBnZW5lcywgbGl2ZSA9IFRSVUV9CiMgVGhlIG51bWJlciBvZiBnZW5lcyBpbiBhbiBTQ0UgY29ycmVzcG9uZHMgdG8gaXRzIG51bWJlciBvZiByb3dzOgpzY2VfbGlzdCB8PgogIHB1cnJyOjptYXAobnJvdykKYGBgCgpTbywgZm9yIG91ciBkYXRhLCB3ZSB3aWxsIG5vdCBoYXZlIHRvIHN1YnNldCB0byBzaGFyZWQgZ2VuZXMgc2luY2UgdGhleSBhcmUgYWxyZWFkeSBzaGFyZWQhCgojIyMjIEVuc3VyaW5nIG1hdGNoaW5nIGNvbHVtbnMgaW4gYGNvbERhdGFgCgpGaW5hbGx5LCB3ZSdsbCBuZWVkIHRvIGhhdmUgdGhlIHNhbWUgY29sdW1uIG5hbWVzIGFjcm9zcyBhbGwgU0NFIGBjb2xEYXRhYCB0YWJsZXMsIHNvIGxldCdzIGxvb2sgYXQgYWxsIHRob3NlIGNvbHVtbiBuYW1lcy4KV2UgY2FuIHVzZSBzaW1pbGFyIHN5bnRheCBoZXJlIHRvIHdoYXQgd2UgdXNlZCB0byBsb29rIGF0IGFsbCB0aGUgYHJvd0RhdGFgIGNvbHVtbiBuYW1lcy4KCmBgYHtyIGNvbXBhcmUgY29sZGF0YX0KcHVycnI6Om1hcChzY2VfbGlzdCwKICAgICAgICAgICBcKHgpIGNvbG5hbWVzKGNvbERhdGEoeCkpICkKYGBgCgpJdCBsb29rcyBsaWtlIHRoZSBjb2x1bW4gbmFtZXMgYXJlIGFsbCBhbHJlYWR5IG1hdGNoaW5nIGFtb25nIFNDRXMsIHNvIHRoZXJlJ3Mgbm8gc3BlY2lmaWMgcHJlcGFyYXRpb24gd2UnbGwgbmVlZCB0byBkbyB0aGVyZS4KCiMjIyBQZXJmb3JtIFNDRSBtZXJnaW5nCgpBcyB5b3UgY2FuIHNlZSwgdGhlcmUncyBhIGxvdCBvZiBtb3ZpbmcgcGFydHMgdG8gY29uc2lkZXIhCkFnYWluLCB0aGVzZSBtb3ZpbmcgcGFydHMgbWF5ICh3aWxsISkgZGlmZmVyIGZvciBTQ0VzIHRoYXQgeW91IGFyZSB3b3JraW5nIHdpdGgsIHNvIHlvdSBoYXZlIHRvIGV4cGxvcmUgeW91ciBvd24gU0NFcyBpbiBkZXB0aCB0byBwcmVwYXJlIGZvciBtZXJnaW5nLgoKQmFzZWQgb24gb3VyIGV4cGxvcmF0aW9uLCBoZXJlIGlzIGEgc2NoZW1hdGljIG9mIGhvdyBvbmUgb2YgdGhlIFNDRSBvYmplY3RzIHdpbGwgdWx0aW1hdGVseSBiZSBtb2RpZmllZCBpbnRvIHRoZSBmaW5hbCBtZXJnZWQgU0NFOgoKIVtdKGRpYWdyYW1zL3RlY2huaWNhbF9tZXJnZV9zY2UucG5nKQoKCldlJ2xsIHdyaXRlIGEgX2N1c3RvbSBmdW5jdGlvbl8gKHNlZW4gaW4gdGhlIGNodW5rIGJlbG93KSB0YWlsb3JlZCB0byBvdXIgd3JhbmdsaW5nIHN0ZXBzIHRoYXQgcHJlcGFyZXMgYSBzaW5nbGUgU0NFIG9iamVjdCBmb3IgbWVyZ2luZy4KV2UnbGwgdGhlbiB1c2Ugb3VyIG5ldyBgcHVycnI6Om1hcCgpYCBwcm9ncmFtbWluZyBza2lsbHMgdG8gcnVuIHRoaXMgZnVuY3Rpb24gb3ZlciB0aGUgYHNjZV9saXN0YC4KVGhpcyB3aWxsIGdpdmUgdXMgYSBuZXcgbGlzdCBvZiBmb3JtYXR0ZWQgU0NFcyB0aGF0IHdlIGNhbiBwcm9jZWVkIHRvIG1lcmdlLgpJdCdzIGltcG9ydGFudCB0byByZW1lbWJlciB0aGF0IHRoZSBgZm9ybWF0X3NjZSgpYCBmdW5jdGlvbiB3cml0dGVuIGJlbG93IGlzIG5vdCBhIGZ1bmN0aW9uIGZvciBnZW5lcmFsIHVzZSDigJMgaXQncyBiZWVuIHByZWNpc2VseSB3cml0dGVuIHRvIG1hdGNoIHRoZSBwcm9jZXNzaW5nIHdlIG5lZWQgdG8gZG8gZm9yIF90aGVzZV8gU0NFcywgYW5kIGRpZmZlcmVudCBTQ0VzIHlvdSB3b3JrIHdpdGggd2lsbCByZXF1aXJlIGRpZmZlcmVudCB0eXBlcyBvZiBwcm9jZXNzaW5nLgoKYGBge3IgZm9ybWF0X3NjZSBmdW5jdGlvbn0KZm9ybWF0X3NjZSA8LSBmdW5jdGlvbihzY2UsIHNhbXBsZV9uYW1lKSB7CiAgIyBJbnB1dCBhcmd1bWVudHM6CiAgIyMgc2NlOiBBbiBTQ0Ugb2JqZWN0IHRvIGZvcm1hdAogICMjIHNhbXBsZV9uYW1lOiBUaGUgU0NFIG9iamVjdCdzIG5hbWUKICAjIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBhIGZvcm1hdHRlZCBTQ0Ugb2JqZWN0LgoKICAjIyMjIyMgRW5zdXJlIHRoYXQgd2UgY2FuIGlkZW50aWZ5IHRoZSBvcmlnaW5hdGluZyBzYW1wbGUgaW5mb3JtYXRpb24gIyMjIyMjCiAgIyBBZGQgYSBjb2x1bW4gY2FsbGVkIGBzYW1wbGVgIHRoYXQgc3RvcmVzIHRoaXMgaW5mb3JtYXRpb24KICAjIFRoaXMgd2lsbCBiZSBzdG9yZWQgaW4gYGNvbERhdGFgCiAgc2NlJHNhbXBsZSA8LSBzYW1wbGVfbmFtZQoKCiAgIyMjIyMjIEVuc3VyZSBjZWxsIGlkcyB3aWxsIGJlIHVuaXF1ZSAjIyMjIyMKICAjIFVwZGF0ZSB0aGUgU0NFIG9iamVjdCBjb2x1bW4gbmFtZXMgKGNlbGwgaWRzKSBieSBwcmVwZW5kaW5nIGBzYW1wbGVfbmFtZWAKICBjb2xuYW1lcyhzY2UpIDwtIGdsdWU6OmdsdWUoIntzYW1wbGVfbmFtZX0te2NvbG5hbWVzKHNjZSl9IikKCgogICMjIyMjIyBFbnN1cmUgZ2VuZS1sZXZlbCBzdGF0aXN0aWNzIGNhbiBiZSBpZGVudGlmaWVkIGluIGByb3dEYXRhYCAjIyMjIyMKICAjIFdlIHdhbnQgdG8gcmVuYW1lIHRoZSBjb2x1bW5zIGBtZWFuYCBhbmQgYGRldGVjdGVkYCB0byBjb250YWluIHRoZSBgc2FtcGxlX25hbWVgCiAgIyBSZWNhbGwgdGhlIG5hbWVzIGFyZTogImdlbmVfc3ltYm9sIiwgIm1lYW4iLCAiZGV0ZWN0ZWQiCiAgY29sbmFtZXMocm93RGF0YShzY2UpKSA8LSBjKCJnZW5lX3N5bWJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsdWU6OmdsdWUoIntzYW1wbGVfbmFtZX0tbWVhbiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbHVlOjpnbHVlKCJ7c2FtcGxlX25hbWV9LWRldGVjdGVkIikpCgogICMgUmV0dXJuIHRoZSBmb3JtYXR0ZWQgU0NFIG9iamVjdAogIHJldHVybihzY2UpCn0KYGBgCgpUbyBydW4gdGhpcyBmdW5jdGlvbiwgd2UnbGwgdXNlIHRoZSBgcHVycnI6Om1hcDIoKWAgZnVuY3Rpb24sIGEgcmVsYXRpdmUgb2YgYHB1cnJyOjptYXAoKWAgdGhhdCBhbGxvd3MgeW91IHRvIGxvb3Agb3ZlciBfdHdvXyBpbnB1dCBsaXN0cy92ZWN0b3JzLgpJbiBvdXIgY2FzZSwgd2Ugd2FudCB0byBydW4gYGZvcm1hdF9zY2UoKWAgb3ZlciBwYWlyZWQgYHNjZV9saXN0YCBpdGVtcyBhbmQgYHNjZV9saXN0YCBuYW1lcy4KCmBgYHtyIGZvcm1hdCBzY2VzIGZvciBtZXJnZSwgbGl2ZSA9IFRSVUV9CiMgV2UgY2FuIHVzZSBgcHVycnI6Om1hcDIoKWAgdG8gbG9vcCBvdmVyIHR3byBsaXN0L3ZlY3RvciBhcmd1bWVudHMKc2NlX2xpc3RfZm9ybWF0dGVkIDwtIHB1cnJyOjptYXAyKAogICMgRWFjaCAiaXRlcmF0aW9uIiB3aWxsIG1hcmNoIGRvd24gdGhlIGZpcnN0IHR3bwogICMgIGFyZ3VtZW50cyBgc2NlX2xpc3RgIGFuZCBgbmFtZXMoc2NlX2xpc3QpYCBpbiBvcmRlcgogIHNjZV9saXN0LAogIG5hbWVzKHNjZV9saXN0KSwKICAjIE5hbWUgb2YgdGhlIGZ1bmN0aW9uIHRvIHJ1bgogIGZvcm1hdF9zY2UKKQoKIyBQcmludCByZXN1bHRpbmcgbGlzdApzY2VfbGlzdF9mb3JtYXR0ZWQKYGBgCgooUHNzdCwgbGlrZSBgcHVycnJgIGFuZCB3YW50IHRvIGRpdmUgZGVlcGVyPyBDaGVjayBvdXQgW3RoZSBgcHVycnI6OmltYXAoKWAgZnVuY3Rpb25dKGh0dHBzOi8vcHVycnIudGlkeXZlcnNlLm9yZy9yZWZlcmVuY2UvaW1hcC5odG1sKSEpCgoKQXQgbG9uZyBsYXN0LCB3ZSBhcmUgcmVhZHkgdG8gbWVyZ2UgdGhlIFNDRXMsIHdoaWNoIHdlJ2xsIGRvIHVzaW5nIHRoZSBSIGZ1bmN0aW9uIGBjYmluZCgpYC4KVGhlIGBjYmluZCgpYCBmdW5jdGlvbiBpcyBvZnRlbiB1c2VkIHRvIGNvbWJpbmUgZGF0YSBmcmFtZXMgb3IgbWF0cmljZXMgYnkgY29sdW1uLCBpLmUuICJzdGFjayIgdGhlbSBuZXh0IHRvIGVhY2ggb3RoZXIuClRoZSBzYW1lIHByaW5jaXBsZSBhcHBsaWVzIGhlcmUsIGJ1dCB3aGVuIHJ1biBvbiBTQ0Ugb2JqZWN0cywgYGNiaW5kKClgIHdpbGwgY3JlYXRlIGEgbmV3IFNDRSBvYmplY3QgYnkgY29tYmluaW5nIGBjb3VudHNgIGFuZCBgbG9nY291bnRzYCBtYXRyaWNlcyBieSBjb2x1bW4uCkZvbGxvd2luZyB0aGF0IHN0cnVjdHVyZSwgb3RoZXIgU0NFIHNsb3RzIChgY29sRGF0YWAsIGByb3dEYXRhYCwgcmVkdWNlZCBkaW1lbnNpb25zLCBhbmQgb3RoZXIgbWV0YWRhdGEpIGFyZSBjb21iaW5lZCBhcHByb3ByaWF0ZWx5LgoKU2luY2Ugd2UgbmVlZCB0byBhcHBseSBgY2JpbmQoKWAgdG8gYSBfbGlzdF8gb2Ygb2JqZWN0cywgd2UgbmVlZCB0byB1c2Ugc29tZSBzbGlnaHRseS1nbmFybHkgc3ludGF4OiBXZSdsbCB1c2UgdGhlIGZ1bmN0aW9uIGBkby5jYWxsKClgLCB3aGljaCBhbGxvd3MgdGhlIGBjYmluZCgpYCBpbnB1dCB0byBiZSBhIGxpc3Qgb2Ygb2JqZWN0cyB0byBjb21iaW5lLgoKYGBge3IgbWVyZ2VzIHNjZXMsIGxpdmUgPSBUUlVFfQojIE1lcmdlIFNDRSBvYmplY3RzCm1lcmdlZF9zY2UgPC0gZG8uY2FsbChjYmluZCwgc2NlX2xpc3RfZm9ybWF0dGVkKQoKIyBQcmludCB0aGUgbWVyZ2VkX3NjZSBvYmplY3QKbWVyZ2VkX3NjZQpgYGAKCldlIG5vdyBoYXZlIGEgc2luZ2xlIFNDRSBvYmplY3QgdGhhdCBjb250YWlucyBhbGwgY2VsbHMgZnJvbSBhbGwgc2FtcGxlcyB3ZSdkIGxpa2UgdG8gaW50ZWdyYXRlLgoKTGV0J3MgdGFrZSBhIHBlZWsgYXQgc29tZSBvZiB0aGUgaW5uYXJkcyBvZiB0aGlzIG5ldyBTQ0Ugb2JqZWN0OgoKYGBge3IgZXhwbG9yZSBtZXJnZWRfc2NlLCBsaXZlID0gVFJVRX0KIyBXaGF0IGFyZSB0aGUgdW5pcXVlIHZhbHVlcyBpbiB0aGUgYHNhbXBsZWAgY29sdW1uPwp1bmlxdWUoIGNvbERhdGEobWVyZ2VkX3NjZSkkc2FtcGxlICkKCiMgV2hhdCBhcmUgdGhlIG5ldyBjZWxsIGlkcyAoY29sdW1uIG5hbWVzKT8KaGVhZCggY29sbmFtZXMobWVyZ2VkX3NjZSkgKQoKIyBXaGF0IGRvZXMgcm93RGF0YSBsb29rIGxpa2U/CmhlYWQoIHJvd0RhdGEobWVyZ2VkX3NjZSkgKQpgYGAKCgojIyBJbnRlZ3JhdGlvbgoKIVtTaW5nbGUtY2VsbCByb2FkbWFwOiBJbnRlZ3JhdGVdKGRpYWdyYW1zL3JvYWRtYXBfbXVsdGlfaW50ZWdyYXRlLnBuZykKCgpTbyBmYXIsIHdlJ3ZlIGNyZWF0ZWQgYSBgbWVyZ2VkX3NjZWAgb2JqZWN0IHdoaWNoIGlzIChhbG1vc3QhKSByZWFkeSBmb3IgaW50ZWdyYXRpb24uCgpUaGUgaW50ZWdyYXRpb24gbWV0aG9kcyB3ZSdsbCBiZSB1c2luZyBoZXJlIGFjdHVhbGx5IHBlcmZvcm0gYmF0Y2ggY29ycmVjdGlvbiBvbiBhIHJlZHVjZWQgZGltZW5zaW9uIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBub3JtYWxpemVkIGdlbmUgZXhwcmVzc2lvbiB2YWx1ZXMsIHdoaWNoIGlzIG1vcmUgZWZmaWNpZW50LgpgZmFzdE1OTmAgYW5kIGBoYXJtb255YCBzcGVjaWZpY2FsbHkgdXNlIFBDQSBmb3IgdGhpcywgYnV0IGJlIGF3YXJlIHRoYXQgZGlmZmVyZW50IGludGVncmF0aW9uIG1ldGhvZHMgbWF5IHVzZSBvdGhlciBraW5kcyBvZiByZWR1Y2VkIGRpbWVuc2lvbnMuCgpZb3UnbGwgbm90aWNlIHRoYXQgdGhlIG1lcmdlZCBTQ0Ugb2JqZWN0IG9iamVjdCBhbHJlYWR5IGNvbnRhaW5zIFBDQSBhbmQgVU1BUCByZWR1Y2VkIGRpbWVuc2lvbnMsIHdoaWNoIHdlcmUgY2FsY3VsYXRlZCBkdXJpbmcgb3VyIHByZS1wcm9jZXNzaW5nOgoKYGBge3IgbWVyZ2VkX3NjZSByZWRkaW0sIGxpdmUgPSBUUlVFfQojIFByaW50IHRoZSByZWR1Y2VkRGltTmFtZXMgb2YgdGhlIG1lcmdlZF9zY2UKcmVkdWNlZERpbU5hbWVzKG1lcmdlZF9zY2UpCmBgYAoKVGhlc2UgcmVwcmVzZW50IHRoZSBvcmlnaW5hbCBkaW1lbnNpb24gcmVkdWN0aW9ucyB0aGF0IHdlcmUgcGVyZm9ybWVkIG9uIF9lYWNoIGluZGl2aWR1YWwgU0NFXyBiZWZvcmUgbWVyZ2luZywgYnV0IHdlIGFjdHVhbGx5IG5lZWQgdG8gY2FsY3VsYXRlIFBDQSAoYW5kIFVNQVAgZm9yIHZpc3VhbGl6YXRpb24pIGZyb20gdGhlIG1lcmdlZCBvYmplY3QgZGlyZWN0bHkuCgpXaHkgY2FuJ3Qgd2UgdXNlIHRoZSBzYW1wbGUtc3BlY2lmaWMgUENBIGFuZCBVTUFQIG1hdHJpY2VzPwpQYXJ0IG9mIHRoZXNlIGNhbGN1bGF0aW9ucyB0aGVtc2VsdmVzIGludm9sdmVzIHNjYWxpbmcgdGhlIHJhdyBkYXRhIHRvIGNlbnRlciB0aGUgbWVhbi4KV2hlbiBzYW1wbGVzIGFyZSBzZXBhcmF0ZWx5IGNlbnRlcmVkIGJ1dCBwbG90dGluZyB0b2dldGhlciwgeW91IHdpbGwgc2VlIHNhbXBsZXMgIm92ZXJsYXBwaW5nIiBpbiBzcGFjZSwgYnV0IHRoaXMgcGxhY2VtZW50IGlzIGFjdHVhbGx5IGp1c3QgYW4gYXJ0aWZhY3Qgb2YgdGhlIGluZGl2aWR1YWwgY2VudGVyaW5nLgpJbiBhZGRpdGlvbiwgdGhlIG1hdGhlbWF0aWNhbCByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgb3JpZ2luYWwgZXhwcmVzc2lvbiBkYXRhIGFuZCByZWR1Y2VkIGRpbWVuc2lvbiB2ZXJzaW9uIG9mIHRoYXQgZGF0YSB3aWxsIGRpZmZlciBhY3Jvc3Mgc2FtcGxlcywgbWVhbmluZyB3ZSBjYW4ndCBpbnRlcnByZXQgdGhlbSBhbGwgdG9nZXRoZXIuClRvIHNlZSBob3cgdGhpcyBsb29rcywgbGV0J3MgbG9vayBhdCB0aGUgVU1BUCB3aGVuIGNhbGN1bGF0ZWQgZnJvbSBpbmRpdmlkdWFsIHNhbXBsZXM6CgpgYGB7ciBwbG90IGluZGl2aWR1YWwgVU1BUHMsIGxpdmUgPSBUUlVFfQojIFBsb3QgVU1BUCBjYWxjdWxhdGVkIGZyb20gaW5kaXZpZHVhbCBzYW1wbGVzIHdpdGggc2VwYXJhdGUgc2NhbGluZwpzY2F0ZXI6OnBsb3RSZWR1Y2VkRGltKG1lcmdlZF9zY2UsCiAgICAgICAgICAgICAgICAgICAgICAgZGltcmVkID0gIlVNQVAiLAogICAgICAgICAgICAgICAgICAgICAgIGNvbG9yX2J5ID0gInNhbXBsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRfc2l6ZSA9IDAuNSwKICAgICAgICAgICAgICAgICAgICAgICBwb2ludF9hbHBoYSA9IDAuMikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIiwgbmFtZSA9ICJzYW1wbGUiKSArICMgVXNlIGEgQ1ZELWZyaWVuZGx5IGNvbG9yIHNjaGVtZSBhbmQgc3BlY2lmeSBsZWdlbmQgbmFtZQogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzLCBhbHBoYSA9IDEpKSkgKyAjIE1vZGlmeSB0aGUgbGVnZW5kIGtleSB3aXRoIGxhcmdlciwgZWFzaWVyIHRvIHNlZSBwb2ludHMKICBnZ3RpdGxlKCJVTUFQIGNhbGN1bGF0ZWQgb24gZWFjaCBzYW1wbGUgc2VwYXJhdGVseSIpCgpgYGAKCgpBcyB3ZSBzZWUgaW4gdGhpcyBVTUFQLCBhbGwgc2FtcGxlcyBhcmUgY2VudGVyZWQgYXQgemVybyBhbmQgYWxsIG92ZXJsYXBwaW5nLgpUaGlzIHZpc3VhbCBhcnRpZmFjdCBjYW4gZ2l2ZSB0aGUgX2luY29ycmVjdCBpbXByZXNzaW9uXyB0aGF0IGRhdGEgaXMgaW50ZWdyYXRlZCAtIHRvIGJlIGNsZWFyLCB0aGlzIGRhdGEgaXMgTk9UIGludGVncmF0ZWQhCgpGb3IgaW5wdXQgdG8gaW50ZWdyYXRpb24sIHdlJ2xsIHdhbnQgdGhlIHJlZHVjZWQgZGltZW5zaW9uIGNhbGN1bGF0aW9ucyB0byBjb25zaWRlciBub3JtYWxpemVkIGdlbmUgZXhwcmVzc2lvbiB2YWx1ZXMgZnJvbSBhbGwgc2FtcGxlcyBzaW11bHRhbmVvdXNseS4KU28gd2UnbGwgbmVlZCB0byByZWNhbGN1bGF0ZSBQQ0EgKGFuZCBVTUFQIGZvciB2aXN1YWxpemF0aW9uKSBvbiB0aGUgbWVyZ2VkIG9iamVjdC4KV2UnbGwgYWxzbyBzYXZlIHRoZXNlIG5ldyByZWR1Y2VkIGRpbWVuc2lvbnMgd2l0aCBkaWZmZXJlbnQgbmFtZXMsIGBtZXJnZWRfUENBYCBhbmQgYG1lcmdlZF9VTUFQYCwgdG8gZGlzdGluZ3Vpc2ggdGhlbSBmcm9tIGFscmVhZHktcHJlc2VudCBgUENBYCBhbmQgYFVNQVBgLgoKRmlyc3QsIGFzIHVzdWFsLCB3ZSdsbCBkZXRlcm1pbmUgdGhlIGhpZ2gtdmFyaWFuY2UgZ2VuZXMgdG8gdXNlIGZvciBQQ0EgZnJvbSB0aGUgYG1lcmdlZF9zY2VgIG9iamVjdC4KRm9yIHRoaXMsIHdlJ2xsIG5lZWQgdG8gcHJvdmlkZSB0aGUgYXJndW1lbnQgYGJsb2NrID0gbWVyZ2VkX3NjZSRzYW1wbGVgIHdoZW4gbW9kZWxpbmcgZ2VuZSB2YXJpYW5jZSwgd2hpY2ggdGVsbHMgYHNjcmFuOjptb2RlbEdlbmVWYXIoKWAgdG8gZmlyc3QgbW9kZWwgdmFyaWFuY2Ugc2VwYXJhdGVseSBmb3IgZWFjaCBiYXRjaCBhbmQgdGhlbiBjb21iaW5lIHRob3NlIG1vZGVsaW5nIHN0YXRpc3RpY3MuCgpgYGB7ciBjYWxjIG1lcmdlZCBodiBnZW5lc30KIyBTcGVjaWZ5IHRoZSBudW1iZXIgb2YgZ2VuZXMgdG8gaWRlbnRpZnkKbnVtX2dlbmVzIDwtIDIwMDAKCiMgQ2FsY3VsYXRlIHZhcmlhdGlvbiBmb3IgZWFjaCBnZW5lCmdlbmVfdmFyaWFuY2UgPC0gc2NyYW46Om1vZGVsR2VuZVZhcihtZXJnZWRfc2NlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzcGVjaWZ5IHRoZSBncm91cGluZyBjb2x1bW46CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBibG9jayA9IG1lcmdlZF9zY2Ukc2FtcGxlKQoKIyBHZXQgdGhlIHRvcCBgbnVtX2dlbmVzYCBoaWdoLXZhcmlhbmNlIGdlbmVzIHRvIHVzZSBmb3IgZGltZW5zaW9uIHJlZHVjdGlvbgpodl9nZW5lcyA8LSBzY3Jhbjo6Z2V0VG9wSFZHcyhnZW5lX3ZhcmlhbmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuID0gbnVtX2dlbmVzKQpgYGAKClRvIGNhbGN1bGF0ZSB0aGUgUENBIG1hdHJpeCBpdHNlbGYsIHdlJ2xsIHVzZSBhbiBhcHByb2FjaCBmcm9tIHRoZSBgYmF0Y2hlbG9yYCBwYWNrYWdlLCB3aGljaCBpcyB0aGUgUiBwYWNrYWdlIHRoYXQgY29udGFpbnMgdGhlIGBmYXN0TU5OYCBtZXRob2QuClRoZSBbYGJhdGNoZWxvcjo6bXVsdGlCYXRjaFBDQSgpYF0oaHR0cHM6Ly9yZHJyLmlvL2Jpb2MvYmF0Y2hlbG9yL21hbi9tdWx0aUJhdGNoUENBLmh0bWwpIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgYSBiYXRjaC13ZWlnaHRlZCBQQ0EgbWF0cml4LgpUaGlzIHdlaWdodGluZyBlbnN1cmVzIHRoYXQgYWxsIGJhdGNoZXMsIHdoaWNoIG1heSBoYXZlIHZlcnkgZGlmZmVyZW50IG51bWJlcnMgb2YgY2VsbHMsIGNvbnRyaWJ1dGUgZXF1YWxseSB0byB0aGUgb3ZlcmFsbCBzY2FsaW5nLgoKYGBge3IgbWFrZSBtZXJnZWRfcGNhLCBsaXZlID0gVFJVRX0KIyBVc2UgYmF0Y2hlbG9yIHRvIGNhbGN1bGF0ZSBQQ0EgZm9yIG1lcmdlZF9zY2UsIGNvbnNpZGVyaW5nIG9ubHkKIyAgdGhlIGhpZ2gtdmFyaWFuY2UgZ2VuZXMKIyBXZSdsbCBuZWVkIHRvIGluY2x1ZGUgdGhlIGFyZ3VtZW50IGBwcmVzZXJ2ZS5zaW5nbGUgPSBUUlVFYCB0byBnZXQKIyAgYSBzaW5nbGUgbWF0cml4IHdpdGggYWxsIHNhbXBsZXMgYW5kIG5vdCBzZXBhcmF0ZSBtYXRyaWNlcyBmb3IgZWFjaCBzYW1wbGUKbWVyZ2VkX3BjYSA8LSBiYXRjaGVsb3I6Om11bHRpQmF0Y2hQQ0EobWVyZ2VkX3NjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2V0LnJvdyA9IGh2X2dlbmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9IG1lcmdlZF9zY2Ukc2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVzZXJ2ZS5zaW5nbGUgPSBUUlVFKQpgYGAKCkxldCdzIGhhdmUgYSBsb29rIGF0IHRoZSBvdXRwdXQ6CmBgYHtyIHByaW50IG1lcmdlZF9wY2EsIGxpdmUgPSBUUlVFfQojIFRoaXMgb3V0cHV0IGlzIG5vdCB2ZXJ5IGludGVyZXN0aW5nIQptZXJnZWRfcGNhCmBgYAoKV2UgY2FuIHVzZSBpbmRleGluZyBgW1sxXV1gIHRvIHNlZSB0aGUgUENBIG1hdHJpeCBjYWxjdWxhdGVkLCBsb29raW5nIGF0IGEgc21hbGwgc3Vic2V0IGZvciBjb252ZW5pZW5jZToKCmBgYHtyIHByaW50IG1lcmdlZF9wY2EgaW5kZXhlZCwgbGl2ZSA9IFRSVUV9Cm1lcmdlZF9wY2FbWzFdXVsxOjUsMTo1XQpgYGAKCldlIGNhbiBub3cgaW5jbHVkZSB0aGlzIFBDQSBtYXRyaXggaW4gb3VyIGBtZXJnZWRfc2NlYCBvYmplY3Q6CgpgYGB7ciBhZGQgbWVyZ2VkX3BjYSwgbGl2ZSA9IFRSVUV9CiMgYWRkIFBDQSByZXN1bHRzIHRvIG1lcmdlZCBTQ0Ugb2JqZWN0CnJlZHVjZWREaW0obWVyZ2VkX3NjZSwgIm1lcmdlZF9QQ0EiKSA8LSBtZXJnZWRfcGNhW1sxXV0KYGBgCgpOb3cgdGhhdCB3ZSBoYXZlIHRoZSBQQ0EgbWF0cml4LCB3ZSBjYW4gcHJvY2VlZCB0byBjYWxjdWxhdGUgVU1BUCB0byB2aXN1YWxpemUgdGhlIHVuY29ycmVjdGVkIG1lcmdlZCBkYXRhLgoKV2UnbGwgY2FsY3VsYXRlIFVNQVAgYXMgInVzdWFsIiwgYnV0IGluIHRoaXMgY2FzZSB3ZSdsbCBzcGVjaWZ5IHR3byBhZGRpdGlvbmFsIGFyZ3VtZW50czoKCi0gYGRpbXJlZCA9ICJtZXJnZWRfUENBImAsIHdoaWNoIHNwZWNpZmllcyB3aGljaCBleGlzdGluZyByZWR1Y2VkIGRpbWVuc2lvbiBzaG91bGQgYmUgdXNlZCBmb3IgdGhlIGNhbGN1bGF0aW9uLgpXZSB3YW50IHRvIHVzZSB0aGUgYmF0Y2gtd2VpZ2h0ZWQgUENBLCB3aGljaCB3ZSBuYW1lZCBhYm92ZSBhcyBgIm1lcmdlZF9QQ0EiYC4KLSBgbmFtZSA9ICJtZXJnZWRfVU1BUCJgLCB3aGljaCBuYW1lcyB0aGUgZmluYWwgVU1BUCB0aGF0IHRoaXMgZnVuY3Rpb24gY2FsY3VsYXRlcy4KVGhpcyBhcmd1bWVudCB3aWxsIHByZXZlbnQgdXMgZnJvbSBvdmVyd3JpdGluZyB0aGUgZXhpc3RpbmcgVU1BUCB3aGljaCBpcyBhbHJlYWR5IG5hbWVkICJVTUFQIiBhbmQgaW5zdGVhZCBjcmVhdGUgYSBzZXBhcmF0ZSBgIm1lcmdlZF9VTUFQImAuCgpgYGB7ciBjYWxjdWxhdGUgbWVyZ2VkIHVtYXAsIGxpdmUgPSBUUlVFfQojIGFkZCBtZXJnZWRfVU1BUCBmcm9tIG1lcmdlZF9QQ0EKbWVyZ2VkX3NjZSA8LSBzY2F0ZXI6OnJ1blVNQVAobWVyZ2VkX3NjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltcmVkID0gIm1lcmdlZF9QQ0EiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gIm1lcmdlZF9VTUFQIikKYGBgCgpOb3csIGxldCdzIHNlZSBob3cgdGhpcyBuZXcgYG1lcmdlZF9VTUFQYCBsb29rcyBjb21wYXJlZCB0byB0aGUgYFVNQVBgIGNhbGN1bGF0ZWQgZnJvbSBpbmRpdmlkdWFsIHNhbXBsZXM6CgpgYGB7ciBwbG90IHVuY29ycmVjdGVkIG1lcmdlZCBVTUFQfQojIFVNQVBzIHNjYWxlZCB0b2dldGhlciB3aGVuIGNhbGN1bGF0ZWQgZnJvbSB0aGUgbWVyZ2VkIFNDRQpzY2F0ZXI6OnBsb3RSZWR1Y2VkRGltKG1lcmdlZF9zY2UsCiAgICAgICAgICAgICAgICAgICAgICAgZGltcmVkID0gIm1lcmdlZF9VTUFQIiwKICAgICAgICAgICAgICAgICAgICAgICBjb2xvcl9ieSA9ICJzYW1wbGUiLAogICAgICAgICAgICAgICAgICAgICAgICMgU29tZSBzdHlsaW5nIHRvIGhlbHAgdXMgc2VlIHRoZSBwb2ludHM6CiAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRfc2l6ZSA9IDAuNSwKICAgICAgICAgICAgICAgICAgICAgICBwb2ludF9hbHBoYSA9IDAuMikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIiwgbmFtZSA9ICJzYW1wbGUiKSArCiAgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMsIGFscGhhID0gMSkpKSArCiAgZ2d0aXRsZSgiVU1BUCBjYWxjdWxhdGVkIG9uIG1lcmdlZF9zY2UiKQpgYGAKClNhbXBsZXMgYXJlIG5vdyBzZXBhcmF0ZWQsIHdoaWNoIG1vcmUgcmVhc29uYWJseSByZWZsZWN0cyB0aGF0IHRoaXMgZGF0YSBpcyBfbm90IHlldCBiYXRjaC1jb3JyZWN0ZWRfLgpXZSBjYW4gdGhpbmsgb2YgdGhpcyBVTUFQIGFzIG91ciAiYmVmb3JlIiBVTUFQLCBhbmQgd2UgY2FuIGNvbXBhcmUgdGhpcyB0byB0aGUgImFmdGVyIiBVTUFQIHdlIHNlZSBwb3N0LWludGVncmF0aW9uLgoKTGV0J3MgZGlzY3VzcyBhIGxpdHRsZSBmaXJzdDogV2hhdCB2aXN1YWwgZGlmZmVyZW5jZXMgZG8geW91IHRoaW5rIHRoZSBVTUFQIG9uIHRoZSBpbnRlZ3JhdGVkIHZlcnNpb24gb2YgZGF0YSB3aWxsIGhhdmU/CldoYXQgc2ltaWxhcml0aWVzIGRvIHlvdSB0aGluayB0aGUgaW50ZWdyYXRlZCBVTUFQIHdpbGwgaGF2ZSB0byB0aGlzIHBsb3Q/CgoKIyMjIEludGVncmF0aW9uIHdpdGggYGZhc3RNTk5gCgpGaW5hbGx5LCB3ZSdyZSByZWFkeSB0byBpbnRlZ3JhdGUhClRvIHN0YXJ0LCB3ZSdsbCB1c2UgdGhlIGBmYXN0TU5OYCBhcHByb2FjaCBmcm9tIHRoZSBCaW9jb25kdWN0b3IgW2BiYXRjaGVsb3JgIHBhY2thZ2VdKGh0dHA6Ly93d3cuYmlvY29uZHVjdG9yLm9yZy9wYWNrYWdlcy8zLjE2L2Jpb2MvaHRtbC9iYXRjaGVsb3IuaHRtbCkuCgpgZmFzdE1OTmAgdGFrZXMgYXMgaW5wdXQgdGhlIGBtZXJnZWRfc2NlYCBvYmplY3QgdG8gaW50ZWdyYXRlLCBhbmQgdGhlIGZpcnN0IHN0ZXAgaXQgcGVyZm9ybXMgaXMgYWN0dWFsbHkgdG8gcnVuIGBiYXRjaGVsb3I6Om11bHRpQmF0Y2hQQ0EoKWAgb24gdGhhdCBTQ0UuCkl0IHRoZW4gdXNlcyB0aGF0IGJhdGNoLXdlaWdodGVkIFBDQSBtYXRyaXggdG8gcGVyZm9ybSB0aGUgYWN0dWFsIGJhdGNoIGNvcnJlY3Rpb24uClRoZSBgYmF0Y2hgIGFyZ3VtZW50IGlzIHVzZWQgdG8gc3BlY2lmeSB0aGUgZGlmZmVyZW50IGdyb3VwaW5ncyB3aXRoaW4gdGhlIGBtZXJnZWRfc2NlYCAoaS5lLiB0aGUgb3JpZ2luYWwgc2FtcGxlIHRoYXQgZWFjaCBjZWxsIGJlbG9uZ3MgdG8pLCBhbmQgdGhlIGBzdWJzZXQucm93YCBhcmd1bWVudCBjYW4gb3B0aW9uYWxseSBiZSB1c2VkIHRvIHByb3ZpZGUgYSB2ZWN0b3Igb2YgaGlnaC12YXJpYW5jZSBnZW5lcyB0aGF0IHNob3VsZCBiZSBjb25zaWRlcmVkIGZvciB0aGlzIFBDQSBjYWxjdWxhdGlvbi4KYGZhc3RNTk5gIHdpbGwgcmV0dXJuIGFuIFNDRSBvYmplY3QgdGhhdCBjb250YWlucyBhIGJhdGNoLWNvcnJlY3RlZCBQQ0EuCkxldCdzIHJ1biBpdCBhbmQgc2F2ZSB0aGUgcmVzdWx0IHRvIGEgdmFyaWFibGUgY2FsbGVkIGBpbnRlZ3JhdGVkX3NjZWAuCgoKYGBge3IgcnVuIGZhc3Rtbm4sIGxpdmUgPSBUUlVFfQojIGludGVncmF0ZSB3aXRoIGZhc3RNTk4sIGFnYWluIHNwZWNpZnlpbmcgb25seSBvdXIgaGlnaC12YXJpYW5jZSBnZW5lcwppbnRlZ3JhdGVkX3NjZSA8LSBiYXRjaGVsb3I6OmZhc3RNTk4oCiAgbWVyZ2VkX3NjZSwKICBiYXRjaCA9IG1lcmdlZF9zY2Ukc2FtcGxlLAogIHN1YnNldC5yb3cgPSBodl9nZW5lcwopCmBgYAoKTGV0J3MgaGF2ZSBhIGxvb2sgYXQgdGhlIHJlc3VsdDoKCmBgYHtyIGZhc3Rtbm4gcmVzdWx0LCBsaXZlID0gVFJVRX0KIyBQcmludCB0aGUgaW50ZWdyYXRlZF9zY2Ugb2JqZWN0CmludGVncmF0ZWRfc2NlCmBgYAoKVGhlcmUgYXJlIGNvdXBsZSBwaWVjZXMgb2YgaW5mb3JtYXRpb24gaGVyZSBvZiBpbnRlcmVzdDoKCi0gVGhlIGBjb3JyZWN0ZWRgIHJlZHVjZWQgZGltZW5zaW9uIHJlcHJlc2VudHMgdGhlIGJhdGNoLWNvcnJlY3RlZCBQQ0EgdGhhdCBgZmFzdE1OTmAgY2FsY3VsYXRlZC4KLSBUaGUgYHJlY29uc3RydWN0ZWRgIGFzc2F5IHJlcHJlc2VudHMgdGhlIGJhdGNoLWNvcnJlY3RlZCBub3JtYWxpemVkIGV4cHJlc3Npb24gdmFsdWVzLCB3aGljaCBgZmFzdE1OTmAgImJhY2stY2FsY3VsYXRlZCIgZnJvbSB0aGUgYmF0Y2gtY29ycmVjdGVkIFBDQSAoYGNvcnJlY3RlZGApLgpHZW5lcmFsbHkgc3BlYWtpbmcsIHRoZXNlIGV4cHJlc3Npb24gdmFsdWVzIGFyZSBub3Qgc3RhbmQtYWxvbmUgdmFsdWVzIHRoYXQgeW91IHNob3VsZCB1c2UgZm9yIG90aGVyIGFwcGxpY2F0aW9ucyBsaWtlIGRpZmZlcmVudGlhbCBnZW5lIGV4cHJlc3Npb24sIGFzIGRlc2NyaWJlZCBpbiBbX09yY2hlc3RyYXRpbmcgU2luZ2xlIENlbGwgQW5hbHlzZXNfXShodHRwOi8vYmlvY29uZHVjdG9yLm9yZy9ib29rcy8zLjE2L09TQ0EubXVsdGlzYW1wbGUvdXNpbmctY29ycmVjdGVkLXZhbHVlcy5odG1sKS4KSWYgdGhlIGBzdWJzZXQucm93YCBhcmd1bWVudCBpcyBwcm92aWRlZCAoYXMgaXQgd2FzIGhlcmUpLCBvbmx5IGdlbmVzIHByZXNlbnQgaW4gYHN1YnNldC5yb3dgIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlc2UgcmVjb25zdHJ1Y3RlZCBleHByZXNzaW9uIHZhbHVlcywgYnV0IHRoaXMgc2V0dGluZyBjYW4gYmUgb3ZlcnJpZGRlbiBzbyB0aGF0IGFsbCBnZW5lcyBoYXZlIHJlY29uc3RydWN0ZWQgZXhwcmVzc2lvbiB3aXRoIHRoZSBhcmd1bWVudCBgY29ycmVjdC5hbGwgPSBUUlVFYC4KCldlJ3JlIG1vc3RseSBpbnRlcmVzdGVkIGluIHRoZSBQQ0EgdGhhdCBgZmFzdE1OTmAgY2FsY3VsYXRlZCwgc28gbGV0J3Mgc2F2ZSB0aGF0IGluZm9ybWF0aW9uICh3aXRoIGFuIGluZm9ybWF0aXZlIGFuZCB1bmlxdWUgbmFtZSkgaW50byBvdXIgYG1lcmdlZF9zY2VgIG9iamVjdDoKCmBgYHtyIGZhc3Rtbm4gcGNzLCBsaXZlID0gVFJVRX0KIyBNYWtlIGEgbmV3IHJlZHVjZWREaW0gbmFtZWQgZmFzdG1ubl9QQ0EgZnJvbSB0aGUgY29ycmVjdGVkIHJlZHVjZWREaW0gaW4gaW50ZWdyYXRlZF9zY2UKcmVkdWNlZERpbShtZXJnZWRfc2NlLCAiZmFzdG1ubl9QQ0EiKSA8LSByZWR1Y2VkRGltKGludGVncmF0ZWRfc2NlLCAiY29ycmVjdGVkIikKYGBgCgpGaW5hbGx5LCB3ZSdsbCBjYWxjdWxhdGUgVU1BUCBmcm9tIHRoZXNlIGNvcnJlY3RlZCBQQ0EgbWF0cml4IGZvciB2aXN1YWxpemF0aW9uLgoKYGBge3IgY2FsY3VsYXRlIGZhc3Rtbm4gdW1hcCwgbGl2ZSA9IFRSVUV9CiMgQ2FsY3VsYXRlIFVNQVAKbWVyZ2VkX3NjZSA8LSBzY2F0ZXI6OnJ1blVNQVAoCiAgbWVyZ2VkX3NjZSwKICBkaW1yZWQgPSAiZmFzdG1ubl9QQ0EiLAogIG5hbWUgPSAiZmFzdG1ubl9VTUFQIgopCmBgYAoKRmlyc3QsIGxldCdzIHBsb3QgdGhlIGludGVncmF0ZWQgVU1BUCBoaWdobGlnaHRpbmcgdGhlIGRpZmZlcmVudCBiYXRjaGVzLgpBIHdlbGwtaW50ZWdyYXRlZCBkYXRhc2V0IHdpbGwgc2hvdyBiYXRjaCBtaXhpbmcsIGJ1dCBhIHBvb3JseS1pbnRlZ3JhdGVkIGRhdGFzZXQgd2lsbCBzaG93IG1vcmUgc2VwYXJhdGlvbiBhbW9uZyBiYXRjaGVzLCBzaW1pbGFyIHRvIHRoZSB1bmNvcnJlY3RlZCBVTUFQLgpOb3RlIHRoYXQgdGhpcyBpcyBhIG1vcmUgcXVhbGl0YXRpdmUgd2F5IHRvIGFzc2VzcyB0aGUgc3VjY2VzcyBvZiBpbnRlZ3JhdGlvbiwgYnV0IHRoZXJlIGFyZSBmb3JtYWwgbWV0cmljcyBvbmUgY2FuIHVzZSB0byBhc3Nlc3MgYmF0Y2ggbWl4aW5nLCB3aGljaCB5b3UgY2FuIHJlYWQgbW9yZSBhYm91dCBpbiBbdGhpcyBjaGFwdGVyIG9mIE9TQ0FdKGh0dHA6Ly9iaW9jb25kdWN0b3Iub3JnL2Jvb2tzLzMuMTYvT1NDQS5tdWx0aXNhbXBsZS9jb3JyZWN0aW9uLWRpYWdub3N0aWNzLmh0bWwpLgoKYGBge3IgcGxvdCBmYXN0bW5uIHVtYXAgYmF0Y2hlc30Kc2NhdGVyOjpwbG90UmVkdWNlZERpbShtZXJnZWRfc2NlLAogICAgICAgICAgICAgICAgICAgICAgICMgcGxvdCB0aGUgZmFzdE1OTiBjb29yZGluYXRlcwogICAgICAgICAgICAgICAgICAgICAgIGRpbXJlZCA9ICJmYXN0bW5uX1VNQVAiLAogICAgICAgICAgICAgICAgICAgICAgICMgY29sb3IgYnkgc2FtcGxlCiAgICAgICAgICAgICAgICAgICAgICAgY29sb3JfYnkgPSAic2FtcGxlIiwKICAgICAgICAgICAgICAgICAgICAgICAjIFNvbWUgc3R5bGluZyB0byBoZWxwIHVzIHNlZSB0aGUgcG9pbnRzOgogICAgICAgICAgICAgICAgICAgICAgIHBvaW50X3NpemUgPSAwLjUsCiAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRfYWxwaGEgPSAwLjIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIsIG5hbWUgPSAic2FtcGxlIikgKwogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzLCBhbHBoYSA9IDEpKSkgKwogIGdndGl0bGUoIlVNQVAgYWZ0ZXIgaW50ZWdyYXRpb24gd2l0aCBmYXN0TU5OIikKYGBgCgpUaGlzIGBmYXN0bW5uX1VNQVBgIGNlcnRhaW5seSBsb29rcyBkaWZmZXJlbnQgZnJvbSB0aGUgb25lIHdlIG1hZGUgZnJvbSBgbWVyZ2VkX1VNQVBgIQpXaGF0IGRpZmZlcmVudCB0cmVuZHMgZG8geW91IHNlZT8KRG8gYWxsIHNhbXBsZXMgbG9vayAiZXF1YWxseSB3ZWxsIiBpbnRlZ3JhdGVkLCBmcm9tIGEgZmlyc3QgbG9vaz8KCkltcG9ydGFudGx5LCBvbmUgcmVhc29uIHRoYXQgYmF0Y2hlcyBtYXkgc3RpbGwgYXBwZWFyIHNlcGFyYXRlZCBpbiB0aGUgY29ycmVjdGVkIFVNQVAgaXMgaWYgdGhleSBfc2hvdWxkXyBiZSBzZXBhcmF0ZWQgLSBmb3IgZXhhbXBsZSwgbWF5YmUgdHdvIGJhdGNoZXMgY29udGFpbiB2ZXJ5IGRpZmZlcmVudCBjZWxsIHR5cGVzLCBoYXZlIHZlcnkgZGlmZmVyZW50IGRpYWdub3Nlcywgb3IgbWF5IGJlIGZyb20gZGlmZmVyZW50IHBhdGllbnRzLgoKUmVjYWxsIGZyb20gZWFybGllciB0aGF0IHdlIGNvbnZlbmllbnRseSBoYXZlIGNlbGwgdHlwZSBhbm5vdGF0aW9ucyBpbiBvdXIgU0NFcywgc28gd2UgY2FuIGV4cGxvcmUgdGhvc2UgaGVyZSEKTGV0J3MgdGFrZSBhIHF1aWNrIGRldG91ciB0byBzZWUgd2hhdCBraW5kcyBvZiBjZWxsIHR5cGVzIGFyZSBpbiB0aGlzIGRhdGEgYnkgbWFraW5nIGEgYmFycGxvdCBvZiB0aGUgY2VsbCB0eXBlcyBhY3Jvc3Mgc2FtcGxlczoKCmBgYHtyIGV4cGxvcmUgY2VsbHR5cGVzfQojIENlbGwgdHlwZXMgYXJlIGluIHRoZSBgY2VsbHR5cGVfYnJvYWRgIGFuZCBgY2VsbHR5cGVfZmluZWAgY29sdW1ucwptZXJnZWRfc2NlX2RmIDwtIGFzLmRhdGEuZnJhbWUoY29sRGF0YShtZXJnZWRfc2NlKSkKCiMgVXNlIGdncGxvdDIgdG8gbWFrZSBhIGJhcnBsb3QgdGhlIGNlbGwgdHlwZXMgYWNyb3NzIHNhbXBsZXMKZ2dwbG90KG1lcmdlZF9zY2VfZGYsCiAgICAgICBhZXMoeCA9IHNhbXBsZSwKICAgICAgICAgICBmaWxsID0gY2VsbHR5cGVfYnJvYWQpKSArCiAgIyBCYXJwbG90IG9mIGNlbGx0eXBlIHByb3BvcnRpb25zCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsKICAjIFVzZSBhIENWRC1mcmllbmRseSBjb2xvciBzY2hlbWUKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIiwgbmEudmFsdWUgPSAiZ3JleTgwIikgKwogICMgbmljZXIgdGhlbWUKICB0aGVtZV9idygpCmBgYAoKV2Ugc2VlIHRoYXQgVHVtb3IgY2VsbCB0eXBlcyBhcmUgYnkgZmFyIHRoZSBtb3N0IHByZXZhbGVudCBhY3Jvc3MgYWxsIHNhbXBsZXMsIGFuZCBub3JtYWwgdGlzc3VlIGNlbGwgdHlwZXMgYXJlIG5vdCB2ZXJ5IGNvbW1vbi4KV2Ugc2VlIGFsc28gdGhhdCBgU0NQQ0wwMDA0ODFgIGhhcyBhIGxhcmdlciBgVHVtb3JfTXlvY3l0ZWAgcG9wdWxhdGlvbiwgd2hpbGUgYWxsIG90aGVyIHNhbXBsZXMgaGF2ZSBsYXJnZXIgYFR1bW9yX01lc29kZXJtYCBwb3B1bGF0aW9ucy4KVGhpcyBkaWZmZXJlbmNlIF9tYXlfIGV4cGxhaW4gd2h5IHdlIG9ic2VydmUgdGhhdCBgU0NQQ0wwMDA0ODFgIGlzIHNvbWV3aGF0IG1vcmUgc2VwYXJhdGVkIGZyb20gdGhlIG90aGVyIHNhbXBsZXMgaW4gdGhlIGBmYXN0TU5OYCBVTUFQLgoKTGV0J3MgcmUtcGxvdCB0aGlzIFVNQVAgdG8gaGlnaGxpZ2h0IGNlbGwgdHlwZXM6CgoKYGBge3IgcGxvdCBmYXN0bW5uIHVtYXAgY2VsbHR5cGVzfQpzY2F0ZXI6OnBsb3RSZWR1Y2VkRGltKG1lcmdlZF9zY2UsCiAgICAgICAgICAgICAgICAgICAgICAgZGltcmVkID0gImZhc3Rtbm5fVU1BUCIsCiAgICAgICAgICAgICAgICAgICAgICAgIyBjb2xvciBieSBicm9hZCBjZWxsdHlwZXMKICAgICAgICAgICAgICAgICAgICAgICBjb2xvcl9ieSA9ICJjZWxsdHlwZV9icm9hZCIsCiAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRfc2l6ZSA9IDAuNSwKICAgICAgICAgICAgICAgICAgICAgICBwb2ludF9hbHBoYSA9IDAuMikgKwogICMgaW5jbHVkZSBhcmd1bWVudCB0byBzcGVjaWZ5IGNvbG9yIG9mIE5BIHZhbHVlcwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIiwgbmFtZSA9ICJCcm9hZCBjZWxsdHlwZSIsIG5hLnZhbHVlID0gImdyZXk4MCIpICsKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gMywgYWxwaGEgPSAxKSkpICsKICBnZ3RpdGxlKCJVTUFQIGFmdGVyIGludGVncmF0aW9uIHdpdGggZmFzdE1OTiIpCmBgYAoKVGhpcyBVTUFQIHNob3dzIHRoYXQgdGhlIG5vcm1hbCB0aXNzdWUgY2VsbCB0eXBlcyAobW9zdGx5IHZhc2N1bGFyIGVuZG90aGVsaXVtLCBtdXNjbGUgY2VsbHMsIGFuZCBtb25vY3l0ZXMpIHRlbmQgdG8gY2x1c3RlciB0b2dldGhlciBhbmQgYXJlIGdlbmVyYWxseSBzZXBhcmF0ZWQgZnJvbSB0aGUgdHVtb3IgY2VsbCB0eXBlcywgd2hpY2ggaXMgYW4gZW5jb3VyYWdpbmcgcGF0dGVybiEKVHVtb3IgY2VsbCB0eXBlcyBmcm9tIGRpZmZlcmVudCBzYW1wbGVzIGFyZSBhbGwgYWxzbyBjbHVzdGVyaW5nIHRvZ2V0aGVyLCB3aGljaCBpcyBldmVuIG1vcmUgZW5jb3VyYWdpbmcgdGhhdCB3ZSBoYWQgc3VjY2Vzc2Z1bCBpbnRlZ3JhdGlvbi4KCkhvd2V2ZXIsIGl0J3MgYSBiaXQgY2hhbGxlbmdpbmcgdG8gc2VlIGFsbCB0aGUgcG9pbnRzIGdpdmVuIHRoZSBhbW91bnQgb2Ygb3ZlcmxhcCBpbiB0aGUgcGxvdC4KT25lIHdheSB3ZSBjYW4gc2VlIGFsbCB0aGUgcG9pbnRzIGEgYml0IGJldHRlciBpcyB0byBmYWNldCB0aGUgcGxvdCBieSBzYW1wbGUsIHVzaW5nIGBmYWNldF93cmFwKClgIGZyb20gdGhlIGBnZ3Bsb3QyYCBwYWNrYWdlICh3aGljaCB3ZSBjYW4gZG8gYmVjYXVzZSBgc2NhdGVyOjpwbG90UmVkdWNlZERpbSgpYCByZXR1cm5zIGEgYGdncGxvdDJgIG9iamVjdCk6CgpgYGB7ciBwbG90IGZhc3Rtbm4gdW1hcCBjZWxsdHlwZXMgZmFjZXRlZH0Kc2NhdGVyOjpwbG90UmVkdWNlZERpbShtZXJnZWRfc2NlLAogICAgICAgICAgICAgICAgICAgICAgIGRpbXJlZCA9ICJmYXN0bW5uX1VNQVAiLAogICAgICAgICAgICAgICAgICAgICAgIGNvbG9yX2J5ID0gImNlbGx0eXBlX2Jyb2FkIiwKICAgICAgICAgICAgICAgICAgICAgICBwb2ludF9zaXplID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgIHBvaW50X2FscGhhID0gMC4yLAogICAgICAgICAgICAgICAgICAgICAgICMgQWxsb3cgZm9yIGZhY2V0aW5nIGJ5IGEgdmFyaWFibGUgdXNpbmcgYG90aGVyX2ZpZWxkc2A6CiAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJfZmllbGRzID0gInNhbXBsZSIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIsIG5hbWUgPSAiQnJvYWQgY2VsbHR5cGUiLCBuYS52YWx1ZSA9ICJncmV5ODAiKSArCiAgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMsIGFscGhhID0gMSkpKSArCiAgZ2d0aXRsZSgiVU1BUCBhZnRlciBpbnRlZ3JhdGlvbiB3aXRoIGZhc3RNTk4iKSArCiAgIyBGYWNldCBieSBzYW1wbGUKICBmYWNldF93cmFwKHZhcnMoc2FtcGxlKSkgKwogICMgVXNlIGEgdGhlbWUgd2l0aCBiYWNrZ3JvdW5kIGdyaWQgdG8gbW9yZSBlYXNpbHkgY29tcGFyZSBwYW5lbCBjb29yZGluYXRlcwogIHRoZW1lX2J3KCkKYGBgCgpXaGF0IHRyZW5kcyBkbyB5b3Ugb2JzZXJ2ZSBiZXR3ZWVuIHR1bW9yIGFuZCBoZWFsdGh5IHRpc3N1ZXMgYW1vbmcgdGhlc2UgaW50ZWdyYXRlZCBzYW1wbGVzPwoKCiMjIyBJbnRlZ3JhdGlvbiB3aXRoIGBoYXJtb255YAoKYGZhc3RNTk5gIGlzIG9ubHkgb25lIG9mIG1hbnkgYXBwcm9hY2hlcyB0byBwZXJmb3JtIGludGVncmF0aW9uLCBhbmQgZGlmZmVyZW50IG1ldGhvZHMgaGF2ZSBkaWZmZXJlbnQgY2FwYWJpbGl0aWVzIGFuZCBtYXkgZ2l2ZSBkaWZmZXJlbnQgcmVzdWx0cy4KRm9yIGV4YW1wbGUsIHNvbWUgbWV0aG9kcyBjYW4gYWNjb21tb2RhdGUgYWRkaXRpb25hbCBjb3ZhcmlhdGVzIChlLmcuLCB0ZWNobm9sb2d5LCBwYXRpZW50LCBkaWFnbm9zaXMsIGV0Yy4pIHRoYXQgY2FuIGluZmx1ZW5jZSBpbnRlZ3JhdGlvbi4KSW4gZmFjdCB0aGUgZGF0YSB3ZSBhcmUgdXNpbmcgaGFzIGEga25vd24gX3BhdGllbnRfIGNvdmFyaWF0ZTsgYFNDUENMMDAwNDc5YCBhbmQgYFNDUENMMDAwNDgwYCBhcmUgZnJvbSB0aGUgZmlyc3QgcGF0aWVudCwgYW5kIGBTQ1BDTDAwMDQ4MWAgYW5kIGBTQ1BDTDAwMDQ4MmAgYXJlIGZyb20gdGhlIHNlY29uZCBwYXRpZW50LgoKU28sIGxldCdzIHBlcmZvcm0gaW50ZWdyYXRpb24gd2l0aCBhIG1ldGhvZCB0aGF0IGNhbiB1c2UgdGhpcyBpbmZvcm1hdGlvbiAtIFtgaGFybW9ueWBdKGh0dHBzOi8vcG9ydGFscy5icm9hZGluc3RpdHV0ZS5vcmcvaGFybW9ueS8pIQoKVG8gYmVnaW4gc2V0dGluZyB1cCBmb3IgYGhhcm1vbnlgIGludGVncmF0aW9uLCB3ZSBuZWVkIHRvIGFkZCBleHBsaWNpdCBwYXRpZW50IGluZm9ybWF0aW9uIGludG8gb3VyIG1lcmdlZCBTQ0UuCldlJ2xsIGNyZWF0ZSBhIG5ldyBjb2x1bW4gYHBhdGllbnRgIHdob3NlIHZhbHVlIGlzIGVpdGhlciAiQSIgb3IgIkIiIGRlcGVuZGluZyBvbiB0aGUgZ2l2ZW4gc2FtcGxlIG5hbWUsIHVzaW5nIHRoZSBbYGRwbHlyOjpjYXNlX3doZW4oKWBdKGh0dHBzOi8vZHBseXIudGlkeXZlcnNlLm9yZy9yZWZlcmVuY2UvY2FzZV93aGVuLmh0bWwpIGZ1bmN0aW9uLgpXZSBwcm92aWRlIHRoaXMgZnVuY3Rpb24gd2l0aCBhIHNldCBvZiBsb2dpY2FsIGV4cHJlc3Npb25zIGFuZCBlYWNoIGFzc2lnbmVkIHZhbHVlIGlzIGRlc2lnbmF0ZWQgYnkgYH5gLgpUaGUgZXhwcmVzc2lvbnMgYXJlIGV2YWx1YXRlZCBpbiBvcmRlciwgc3RvcHBpbmcgYXQgdGhlIF9maXJzdF8gb25lIHRoYXQgZXZhbHVhdGVzIGFzIGBUUlVFYCBhbmQgcmV0dXJuaW5nIHRoZSBhc3NvY2lhdGVkIHZhbHVlLgoKYGBge3IgYWRkIHBhdGllbnQgaW5mb30KIyBDcmVhdGUgcGF0aWVudCBjb2x1bW4gd2l0aCB2YWx1ZXMgIkEiIG9yICJCIiBmb3IgdGhlIHR3byBwYXRpZW50cwptZXJnZWRfc2NlJHBhdGllbnQgPC0gZHBseXI6OmNhc2Vfd2hlbigKICBtZXJnZWRfc2NlJHNhbXBsZSAlaW4lIGMoIlNDUENMMDAwNDc5IiwgIlNDUENMMDAwNDgwIikgfiAiQSIsCiAgbWVyZ2VkX3NjZSRzYW1wbGUgJWluJSBjKCJTQ1BDTDAwMDQ4MSIsICJTQ1BDTDAwMDQ4MiIpIH4gIkIiLAopCmBgYAoKClVubGlrZSBgZmFzdE1OTmAsIGBoYXJtb255YCBkb2VzIG5vdCBjYWxjdWxhdGUgY29ycmVjdGVkIGV4cHJlc3Npb24gdmFsdWVzIG5vciBkb2VzIGl0IHJldHVybiBhbiBTQ0Ugb2JqZWN0LgpMaWtlIGBmYXN0TU5OYCwgYGhhcm1vbnlgIHBlcmZvcm1zIGludGVncmF0aW9uIG9uIGEgbWVyZ2VkIFBDQSBtYXRyaXguCkhvd2V2ZXIsIHVubGlrZSBgZmFzdE1OTmAsIGBoYXJtb255YCBkb2VzIG5vdCAiYmFjay1jYWxjdWxhdGUiIGNvcnJlY3RlZCBleHByZXNzaW9uIGZyb20gdGhlIGNvcnJlY3RlZCBQQ0EgbWF0cml4IGFuZCBpdCBvbmx5IHJldHVybnMgdGhlIGNvcnJlY3RlZCBQQ0EgbWF0cml4IGl0c2VsZi4KRm9yIGlucHV0LCBgaGFybW9ueWAgbmVlZHMgYSBjb3VwbGUgcGllY2VzIG9mIGluZm9ybWF0aW9uOgoKLSBGaXJzdCwgYGhhcm1vbnlgIGNhbiBlaXRoZXIgdGFrZSBhIG1hdHJpeCBvZiBub3JtYWxpemVkIGV4cHJlc3Npb24gdmFsdWVzLCBmcm9tIHdoaWNoIGl0IHdpbGwgY2FsY3VsYXRlIGEgYmF0Y2gtd2VpZ2h0ZWQgUENBIG1hdHJpeCB0byBpbnRlZ3JhdGUsIG9yIGl0IGNhbiB0YWtlIGEgYmF0Y2gtd2VpZ2h0ZWQgUENBIG1hdHJpeCBkaXJlY3RseSB0byBwZXJmb3JtIGludGVncmF0aW9uLgpTaW5jZSB3ZSBhbHJlYWR5IGNhbGN1bGF0ZWQgYSBiYXRjaC13ZWlnaHRlZCBQQ0EgbWF0cml4IChvdXIgYG1lcmdlZF9QQ0FgIHJlZHVjZWQgZGltZW5zaW9uKSwgd2UnbGwgcHJvdmlkZSB0aGlzIGluZm9ybWF0aW9uIGRpcmVjdGx5LgogIC0gV2Ugd2lsbCBuZWVkIHRvIHNwZWNpZnkgdGhlIGFkZGl0aW9uYWwgYXJndW1lbnQgYGRvX3BjYT1GQUxTRWAgdG8gdGVsbCBgaGFybW9ueWAgdGhhdCB0aGUgaW5wdXQgbWF0cml4IHdlIHByb3ZpZGVkIGFscmVhZHkgaXMgYSBQQ0EgbWF0cml4LgotIFNlY29uZCwgd2UgbmVlZCB0byB0ZWxsIGBoYXJtb255YCBhYm91dCB0aGUgY292YXJpYXRlcyB0byB1c2UgLSBgc2FtcGxlYCBhbmQgYHBhdGllbnRgLgpUbyBkbyB0aGlzLCB3ZSBwcm92aWRlIHR3byBhcmd1bWVudHM6CiAgLSBgbWV0YV9kYXRhYCwgYSBkYXRhIGZyYW1lIHRoYXQgY29udGFpbnMgY292YXJpYXRlcyBhY3Jvc3Mgc2FtcGxlcy4KICBXZSBjYW4gc2ltcGx5IHNwZWNpZnkgdGhlIFNDRSBgY29sRGF0YWAgaGVyZSBzaW5jZSBpdCBjb250YWlucyBgc2FtcGxlYCBhbmQgYHBhdGllbnRgIGNvbHVtbnMuCiAgLSBgdmFyc191c2VgLCBhIHZlY3RvciBvZiB3aGljaCBjb2x1bW4gbmFtZXMgaW4gYG1ldGFfZGF0YWAgc2hvdWxkIGFjdHVhbGx5IGJlIHVzZWQgYXMgY292YXJpYXRlcy4KICBPdGhlciBjb2x1bW5zIGluIGBtZXRhX2RhdGFgIHdoaWNoIGFyZSBub3QgaW4gYHZhcnNfdXNlYCBhcmUgaWdub3JlZC4KCkxldCdzIGdvIQoKYGBge3IgcnVuIGhhcm1vbnksIGxpdmUgPSBUUlVFfQojIGludGVncmF0ZSB3aXRoIGhhcm1vbnksIHNldHRpbmcgdGhlIGFyZ3VtZW50IGBkb19wY2EgPSBGQUxTRWAKIyAgc2luY2Ugd2UgYXJlIHByb3ZpZGluZyBhIFBDQSBtYXRyaXggZGlyZWN0bHkKaGFybW9ueV9wY2EgPC0gaGFybW9ueTo6SGFybW9ueU1hdHJpeCgKICBkYXRhX21hdCA9IHJlZHVjZWREaW0obWVyZ2VkX3NjZSwgIm1lcmdlZF9QQ0EiKSwKICBkb19wY2EgPSBGQUxTRSwKICBtZXRhX2RhdGEgPSBjb2xEYXRhKG1lcmdlZF9zY2UpLAogIHZhcnNfdXNlID0gYygic2FtcGxlIiwgInBhdGllbnQiKQopCmBgYAoKVGhlIHJlc3VsdCBpcyBhIFBDQSBtYXRyaXguCkxldCdzIHByaW50IGEgc3Vic2V0IG9mIHRoaXMgbWF0cml4IHRvIHNlZSBpdDoKCmBgYHtyIHByaW50IGhhcm1vbnkgcmVzdWx0LCBsaXZlID0gVFJVRX0KIyBQcmludCB0aGUgaGFybW9ueSByZXN1bHQKaGFybW9ueV9wY2FbMTo1LCAxOjVdCmBgYAoKQXMgd2UgZGlkIHdpdGggYGZhc3RNTk5gIHJlc3VsdHMsIGxldCdzIHN0b3JlIHRoaXMgUENBIG1hdHJpeCBkaXJlY3RseSBpbiBvdXIgYG1lcmdlZF9zY2VgIG9iamVjdCB3aXRoIGFuIGluZm9ybWF0aXZlIG5hbWUgdGhhdCB3b24ndCBvdmVyd3JpdGUgYW55IG9mIHRoZSBleGlzdGluZyBQQ0EgbWF0cmljZXMuCldlJ2xsIGFsc28gY2FsY3VsYXRlIFVNQVAgZnJvbSBpdC4KCmBgYHtyIHNhdmUgaGFybW9ueSwgbGl2ZSA9IFRSVUV9CiMgU3RvcmUgUENBIGFzIGBoYXJtb255X1BDQWAKcmVkdWNlZERpbShtZXJnZWRfc2NlLCAiaGFybW9ueV9QQ0EiKSA8LSBoYXJtb255X3BjYQoKIyBBcyBiZWZvcmUsIGNhbGN1bGF0ZSBVTUFQIG9uIHRoaXMgUENBIG1hdHJpeCB3aXRoIGFwcHJvcHJpYXRlIG5hbWVzCm1lcmdlZF9zY2UgPC0gc2NhdGVyOjpydW5VTUFQKG1lcmdlZF9zY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbXJlZCA9ICJoYXJtb255X1BDQSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgICA9ICJoYXJtb255X1VNQVAiKQpgYGAKCgpMZXQncyBzZWUgaG93IHRoZSBgaGFybW9ueWAgVU1BUCwgY29sb3JlZCBieSBzYW1wbGUsIGxvb2tzIGNvbXBhcmVkIHRvIHRoZSBgZmFzdE1OTmAgVU1BUDoKCmBgYHtyIHBsb3QgaGFybW9ueSB1bWFwIGJhdGNoZXN9CnNjYXRlcjo6cGxvdFJlZHVjZWREaW0obWVyZ2VkX3NjZSwKICAgICAgICAgICAgICAgICAgICAgICBkaW1yZWQgPSAiaGFybW9ueV9VTUFQIiwKICAgICAgICAgICAgICAgICAgICAgICBjb2xvcl9ieSA9ICJzYW1wbGUiLAogICAgICAgICAgICAgICAgICAgICAgIHBvaW50X3NpemUgPSAwLjUsCiAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRfYWxwaGEgPSAwLjIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIsIG5hbWUgPSAic2FtcGxlIikgKwogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzLCBhbHBoYSA9IDEpKSkgKwogIGdndGl0bGUoIlVNQVAgYWZ0ZXIgaW50ZWdyYXRpb24gd2l0aCBoYXJtb255IikKYGBgCgpIb3cgZG8geW91IHRoaW5rIHRoaXMgYGhhcm1vbnlgIFVNQVAgY29tcGFyZXMgdG8gdGhhdCBmcm9tIGBmYXN0TU5OYCBpbnRlZ3JhdGlvbj8KCkxldCdzIHNlZSBob3cgdGhpcyBVTUFQIGxvb2tzIGNvbG9yZWQgYnkgY2VsbCB0eXBlLCBhbmQgZmFjZXRlZCBmb3IgdmlzaWJpbGl0eToKCmBgYHtyIHBsb3QgaGFybW9ueSB1bWFwIGNlbGx0eXBlc30Kc2NhdGVyOjpwbG90UmVkdWNlZERpbShtZXJnZWRfc2NlLAogICAgICAgICAgICAgICAgICAgICAgIGRpbXJlZCA9ICJoYXJtb255X1VNQVAiLAogICAgICAgICAgICAgICAgICAgICAgIGNvbG9yX2J5ID0gImNlbGx0eXBlX2Jyb2FkIiwKICAgICAgICAgICAgICAgICAgICAgICBwb2ludF9zaXplID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgIHBvaW50X2FscGhhID0gMC4yLAogICAgICAgICAgICAgICAgICAgICAgICMgU3BlY2lmeSB2YXJpYWJsZSBmb3IgZmFjZXRpbmcKICAgICAgICAgICAgICAgICAgICAgICBvdGhlcl9maWVsZHMgPSAic2FtcGxlIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIiwgbmFtZSA9ICJCcm9hZCBjZWxsdHlwZSIsIG5hLnZhbHVlID0gImdyZXk4MCIpICsKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gMykpKSArCiAgZ2d0aXRsZSgiVU1BUCBhZnRlciBpbnRlZ3JhdGlvbiB3aXRoIGhhcm1vbnkiKSArCiAgZmFjZXRfd3JhcCh2YXJzKHNhbXBsZSkpCmBgYAoKV2hhdCBkbyB5b3Ugbm93IG5vdGljZSBpbiB0aGlzIGZhY2V0ZWQgdmlldyB0aGF0IHdhc24ndCBjbGVhciBwcmV2aW91c2x5PwpBcmUgdGhlcmUgb3RoZXIgcGF0dGVybnMgeW91IHNlZSB0aGF0IGFyZSBzaW1pbGFyIG9yIGRpZmZlcmVudCBmcm9tIHRoZSBgZmFzdE1OTmAgVU1BUD8KSG93IGRvIHlvdSB0aGluayBgZmFzdE1OTmAgdnMuIGBoYXJtb255YCBwZXJmb3JtZWQgaW4gaW50ZWdyYXRpbmcgdGhlc2Ugc2FtcGxlcz8KCiMjIyBFeHBvcnQKCkZpbmFsbHksIHdlJ2xsIGV4cG9ydCB0aGUgZmluYWwgU0NFIG9iamVjdCB3aXRoIGJvdGggYGZhc3RNTk5gIGFuZCBgaGFybW9ueWAgaW50ZWdyYXRpb24gdG8gYSBmaWxlLgpTaW5jZSB0aGlzIG9iamVjdCBpcyB2ZXJ5IGxhcmdlIChvdmVyIDEgR0IhKSwgd2UnbGwgZXhwb3J0IGl0IHRvIGEgZmlsZSB3aXRoIHNvbWUgY29tcHJlc3Npb24sIHdoaWNoLCBpbiB0aGlzIGNhc2UsIHdpbGwgcmVkdWNlIHRoZSBmaW5hbCBzaXplIHRvIGEgc21hbGxlciB+MzYwIE1CLgpUaGlzIHdpbGwgdGFrZSBhIGNvdXBsZSBtaW51dGVzIHRvIHNhdmUgd2hpbGUgY29tcHJlc3Npb24gaXMgcGVyZm9ybWVkLgoKYGBge3Igc2F2ZSBpbnRlZ3JhdGlvbiwgbGl2ZSA9IFRSVUV9CiMgRXhwb3J0IHRvIFJEUyBmaWxlIHdpdGggImd6IiBjb21wcmVzc2lvbgpyZWFkcjo6d3JpdGVfcmRzKG1lcmdlZF9zY2UsCiAgICAgICAgICAgICAgICAgaW50ZWdyYXRlZF9zY2VfZmlsZSwKICAgICAgICAgICAgICAgICBjb21wcmVzcyA9ICJneiIpCmBgYAoKCiMjIFByaW50IHNlc3Npb24gaW5mbwoKQXMgYWx3YXlzLCB3ZSdsbCBwcmludCB0aGUgc2Vzc2lvbiBpbmZvIHRvIGJlIHRyYW5zcGFyZW50IGFib3V0IHdoYXQgcGFja2FnZXMsIGFuZCB3aGljaCB2ZXJzaW9ucywgd2VyZSB1c2VkIGR1cmluZyB0aGlzIFIgc2Vzc2lvbi4KCmBgYHtyIHNlc3Npb25pbmZvfQpzZXNzaW9uSW5mbygpCmBgYAo=
+LS0tCnRpdGxlOiAiSW50ZWdyYXRpbmcgc2NSTkEtc2VxIGRhdGFzZXRzIgphdXRob3I6IERhdGEgTGFiIGZvciBBTFNGCmRhdGU6IDIwMjMKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogMwogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKIyMgT2JqZWN0aXZlcwoKVGhpcyBub3RlYm9vayB3aWxsIGRlbW9uc3RyYXRlIGhvdyB0bzoKCi0gUHJlcGFyZSBTQ0Ugb2JqZWN0cyBmb3IgaW50ZWdyYXRpb24KLSBBcHBseSBpbnRlZ3JhdGlvbiBtZXRob2RzIGluY2x1ZGluZyBgZmFzdE1OTmAgYW5kIGBoYXJtb255YAotIFZpc3VhbGx5IGV4cGxvcmUgdGhlIHJlc3VsdHMgb2YgaW50ZWdyYXRpb24KLSBVc2UgYHB1cnJyOjptYXAoKWAgZnVuY3Rpb25zIGZvciBpdGVyYXRpbmcgb3ZlciBsaXN0cwoKLS0tCgpJbiB0aGlzIG5vdGVib29rLCB3ZSdsbCBwZXJmb3JtIGludGVncmF0aW9uIG9uIHNjUk5BLXNlcSBkYXRhc2V0cyBmcm9tIHRoZSBbU2luZ2xlLWNlbGwgUGVkaWF0cmljIENhbmNlciBBdGxhcyAoYFNjUENBYCldKGh0dHBzOi8vc2NwY2EuYWxleHNsZW1vbmFkZS5vcmcvKSwgYSBkYXRhYmFzZSBvZiB1bmlmb3JtbHktcHJvY2Vzc2VkIHBlZGlhdHJpYyBzY1JOQS1zZXEgZGF0YSBidWlsdCBhbmQgbWFpbnRhaW5lZCBieSB0aGUgRGF0YSBMYWIuClRoZSBgU2NQQ0FgIGRhdGFiYXNlIGN1cnJlbnRseSBob3N0cyBzaW5nbGUtY2VsbCBwZWRpYXRyaWMgY2FuY2VyIHRyYW5zY3JpcHRvbWljIGRhdGEgZ2VuZXJhdGVkIGJ5IEFMU0YtZnVuZGVkIGxhYnMsIHdpdGggdGhlIGdvYWwgb2YgbWFraW5nIHRoaXMgZGF0YSBlYXNpbHkgYWNjZXNzaWJsZSB0byBpbnZlc3RpZ2F0b3JzIChsaWtlIHlvdSEpLgpUaGUgZXhwcmVzc2lvbiBkYXRhIGluIGBTY1BDQWAgd2VyZSBtYXBwaW5nIGFuZCBxdWFudGlmaWVkIHdpdGggW2BhbGV2aW4tZnJ5YF0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwMzgvczQxNTkyLTAyMi0wMTQwOC0zKSwgZm9sbG93ZWQgYnkgcHJvY2Vzc2luZyB3aXRoIEJpb2NvbmR1Y3RvciB0b29scyB1c2luZyB0aGUgc2FtZSBnZW5lcmFsIHByb2NlZHVyZXMgdGhhdCB3ZSBoYXZlIGNvdmVyZWQgaW4gdGhpcyB3b3Jrc2hvcC4KVGhlIHByb2Nlc3NpbmcgcGlwZWxpbmUgdXNlZCBgZW1wdHlEcm9wc0NlbGxSYW5nZXIoKWAgYW5kIGBtaVFDYCB0byBmaWx0ZXIgdGhlIHJhdyBjb3VudHMgbWF0cml4LCBgc2N1dHRsZWAgdG8gbG9nLW5vcm1hbGl6ZSB0aGUgY291bnRzLCBhbmQgYHNjYXRlcmAgZm9yIGRpbWVuc2lvbiByZWR1Y3Rpb24uClRoZSBwcm9jZXNzZWQgZGF0YSBhcmUgc3RvcmVkIGFzIGAucmRzYCBmaWxlcyBjb250YWluaW5nIGBTaW5nbGVDZWxsRXhwZXJpbWVudGAgb2JqZWN0cy4KWW91IGNhbiByZWFkIG1vcmUgYWJvdXQgaG93IGRhdGEgaW4gdGhlIGBTY1BDQWAgaXMgcHJvY2Vzc2VkIGluIFt0aGUgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uXShodHRwczovL3NjcGNhLnJlYWR0aGVkb2NzLmlvL2VuL2xhdGVzdC8pLgoKCiFbU2luZ2xlLWNlbGwgcm9hZG1hcDogSW50ZWdyYXRpb24gT3ZlcnZpZXddKGRpYWdyYW1zL3JvYWRtYXBfbXVsdGlfbWVyZ2UtaW50ZWdyYXRlLnBuZykKClRvIGxlYXJuIGFib3V0IGludGVncmF0aW9uLCB3ZSdsbCBoYXZlIGEgbG9vayBhdCBmb3VyIHNhbXBsZXMgZnJvbSB0aGUgW2BTQ1BDUDAwMDAwNWAgcHJvamVjdF0oaHR0cHM6Ly9zY3BjYS5hbGV4c2xlbW9uYWRlLm9yZy9wcm9qZWN0cy9TQ1BDUDAwMDAwNSkgKFtQYXRlbCBfZXQgYWwuXyAyMDIyXShodHRwczovL2RvaS5vcmcvMTAuMTAxNi9qLmRldmNlbC4yMDIyLjA0LjAwMykpLCBhbiBpbnZlc3RpZ2F0aW9uIG9mIHBlZGlhdHJpYyBzb2xpZCB0dW1vcnMgbGVkIGJ5IHRoZSBbRHllcl0oaHR0cHM6Ly93d3cuc3RqdWRlLm9yZy9yZXNlYXJjaC9sYWJzL2R5ZXItbGFiLmh0bWwpIGFuZCBbQ2hlbl0oaHR0cHM6Ly93d3cuc3RqdWRlLm9yZy9yZXNlYXJjaC9sYWJzL2NoZW4tbGFiLXRhb3NoZW5nLmh0bWwpIGxhYnMgYXQgU3QuIEp1ZGUgQ2hpbGRyZW4ncyBSZXNlYXJjaCBIb3NwaXRhbC4KVGhlIHBhcnRpY3VsYXIgbGlicmFyaWVzIHdlJ2xsIGludGVncmF0ZSBjb21lIGZyb20gdHdvIHJoYWJkb215b3NhcmNvbWEgKFJNUykgcGF0aWVudHMsIHdpdGggdHdvIHNhbXBsZXMgZnJvbSBlYWNoIG9mIHR3byBwYXRpZW50cywgYWxsIHNlcXVlbmNlZCB3aXRoIDEweCBDaHJvbWl1bSB2MyB0ZWNobm9sb2d5LgpFYWNoIGxpYnJhcnkgaXMgZnJvbSBhIHNlcGFyYXRlIGJpb2xvZ2ljYWwgc2FtcGxlLgoKV2UnbGwgYmUgaW50ZWdyYXRpbmcgdGhlc2Ugc2FtcGxlcyB3aXRoIHR3byBkaWZmZXJlbnQgdG9vbHMsIFtgZmFzdE1OTmBdKGh0dHA6Ly93d3cuYmlvY29uZHVjdG9yLm9yZy9wYWNrYWdlcy8zLjE2L2Jpb2MvaHRtbC9iYXRjaGVsb3IuaHRtbCkgKFtIYWdodmVyZGkgX2V0IGFsLl8gMjAxOF0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwMzgvbmJ0LjQwOTEpKSBhbmQgW2BoYXJtb255YF0oaHR0cHM6Ly9wb3J0YWxzLmJyb2FkaW5zdGl0dXRlLm9yZy9oYXJtb255LykgKFtLb3JzdW5za3kgX2V0IGFsLl8gMjAxOV0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwMzgvczQxNTkyLTAxOS0wNjE5LTApKS4KSW50ZWdyYXRpb24gY29ycmVjdHMgZm9yIGJhdGNoIGVmZmVjdHMgdGhhdCBhcmlzZSBmcm9tIGRpZmZlcmVudCBsaWJyYXJ5IHByZXBhcmF0aW9ucywgZ2VuZXRpYyBiYWNrZ3JvdW5kcywgYW5kIG90aGVyIHNhbXBsZS1zcGVjaWZpYyBmYWN0b3JzLCBzbyB0aGF0IGRhdGFzZXRzIGNhbiBiZSBqb2ludGx5IGFuYWx5emVkIGF0IHRoZSBjZWxsIGxldmVsLgpgZmFzdE1OTmAgY29ycmVjdHMgZm9yIGJhdGNoIGVmZmVjdHMgdXNpbmcgYSBmYXN0ZXIgdmFyaWFudCBvZiB0aGUgbXV0dWFsLW5lYXJlc3QgbmVpZ2hib3JzIGFsZ29yaXRobSwgdGhlIHRlY2huaWNhbCBkZXRhaWxzIG9mIHdoaWNoIHlvdSBjYW4gbGVhcm4gbW9yZSBhYm91dCBmcm9tIHRoaXMgW3ZpZ25ldHRlIGJ5IEx1biAoMjAxOSldKGh0dHBzOi8vbWFyaW9uaWxhYi5naXRodWIuaW8vRnVydGhlck1OTjIwMTgvdGhlb3J5L2Rlc2NyaXB0aW9uLmh0bWwpLgpgaGFybW9ueWAsIG9uIHRoZSBvdGhlciBoYW5kLCBjb3JyZWN0cyBmb3IgYmF0Y2ggZWZmZWN0cyB1c2luZyBhbiBpdGVyYXRpdmUgY2x1c3RlcmluZyBhcHByb2FjaCwgYW5kIHVubGlrZSBgZmFzdE1OTmAsIGl0IGlzIGFsc28gYWJsZSB0byBjb25zaWRlciBhZGRpdGlvbmFsIGNvdmFyaWF0ZXMgYmV5b25kIGp1c3QgdGhlIGJhdGNoIGdyb3VwaW5ncy4KClJlZ2FyZGxlc3Mgb2Ygd2hpY2ggaW50ZWdyYXRpb24gdG9vbCBpcyB1c2VkLCB0aGUgYFNpbmdsZUNlbGxFeHBlcmltZW50YCAoU0NFKSBvYmplY3RzIGZpcnN0IG5lZWQgdG8gYmUgcmVmb3JtYXR0ZWQgYW5kIG1lcmdlZCBpbnRvIGEgc2luZ2xlICh1bmNvcnJlY3RlZCEpIFNDRSBvYmplY3QgdGhhdCBjb250YWlucyBhbGwgY2VsbHMgZnJvbSBhbGwgc2FtcGxlcy4KVGhpcyBtZXJnZWQgU0NFIGNhbiB0aGVuIGJlIHVzZWQgZm9yIGludGVncmF0aW9uIHRvIG9idGFpbiBhIGZvcm1hbGx5IGJhdGNoLWNvcnJlY3RlZCBTQ0Ugb2JqZWN0LgoKCiMjIFNldCB1cAoKYGBge3Igc2V0dXB9CiMgTG9hZCBsaWJyYXJpZXMKbGlicmFyeShnZ3Bsb3QyKSAgIyBwbG90dGluZyB0b29scwpsaWJyYXJ5KFNpbmdsZUNlbGxFeHBlcmltZW50KSAjIHdvcmsgd2l0aCBTQ0Ugb2JqZWN0cwoKIyBTZXQgdGhlIHNlZWQgZm9yIHJlcHJvZHVjaWJpbGl0eQpzZXQuc2VlZCgxMjM0NSkKYGBgCgoKIyMjIERpcmVjdG9yaWVzIGFuZCBmaWxlcwoKCldlIGhhdmUgYWxyZWFkeSBwcmVwYXJlZCBjb3VudCBkYXRhIGZvciB0aGUgZm91ciBzYW1wbGVzIHdlJ2xsIGJlIGludGVncmF0aW5nIChpLmUuLCBmaWx0ZXJlZCBjZWxscywgbm9ybWFsaXplZCBjb3VudHMsIGFuZCBjYWxjdWxhdGVkIFBDQSAmIFVNQVApLgpUaGVzZSBTQ0Ugb2JqZWN0cywgc3RvcmVkIGFzIFJEUyBmaWxlcywgYXJlIGF2YWlsYWJsZSBpbiB0aGUgYGRhdGEvcm1zL3Byb2Nlc3NlZC9gIGRpcmVjdG9yeSBhbmQgYXJlIG5hbWVkIGFjY29yZGluZyB0byB0aGVpciBgU2NQQ0FgIGxpYnJhcnkgaWRzIDoKCi0gYFNDUENMMDAwNDc5LnJkc2AgKFBhdGllbnQgQSkKLSBgU0NQQ0wwMDA0ODAucmRzYCAoUGF0aWVudCBBKQotIGBTQ1BDTDAwMDQ4MS5yZHNgIChQYXRpZW50IEIpCi0gYFNDUENMMDAwNDgyLnJkc2AgKFBhdGllbnQgQikKClRvIGJlZ2luLCBsZXQncyBzZXQgdXAgb3VyIGRpcmVjdG9yaWVzIGFuZCBmaWxlczoKCmBgYHtyIGRpcmVjdG9yaWVzLCBsaXZlID0gVFJVRX0KIyBEZWZpbmUgZGlyZWN0b3J5IHdoZXJlIHByb2Nlc3NlZCBTQ0Ugb2JqZWN0cyB0byBiZSBpbnRlZ3JhdGVkIGFyZSBzdG9yZWQKaW5wdXRfZGlyIDwtIGZpbGUucGF0aCgiZGF0YSIsICJybXMiLCAicHJvY2Vzc2VkIikKCiMgRGVmaW5lIGRpcmVjdG9yeSB0byBzYXZlIGludGVncmF0ZWQgU0NFIG9iamVjdCB0bwpvdXRwdXRfZGlyIDwtIGZpbGUucGF0aCgiZGF0YSIsICJybXMiLCAiaW50ZWdyYXRlZCIpCgojIENyZWF0ZSBvdXRwdXQgZGlyZWN0b3J5IGlmIGl0IGRvZXNuJ3QgZXhpc3QKZnM6OmRpcl9jcmVhdGUob3V0cHV0X2RpcikKCiMgRGVmaW5lIG91dHB1dCBmaWxlIG5hbWUgZm9yIHRoZSBpbnRlZ3JhdGVkIG9iamVjdAppbnRlZ3JhdGVkX3NjZV9maWxlIDwtIGZpbGUucGF0aChvdXRwdXRfZGlyLCAicm1zX2ludGVncmF0ZWRfc3Vic2V0LnJkcyIpCmBgYAoKCldlIGNhbiB1c2UgdGhlIGBkaXIoKWAgZnVuY3Rpb24gdG8gbGlzdCBhbGwgY29udGVudHMgb2YgYSBnaXZlbiBkaXJlY3RvcnksIGZvciBleGFtcGxlIHRvIHNlZSBhbGwgdGhlIGZpbGVzIGluIG91ciBgaW5wdXRfZGlyYDoKCmBgYHtyIGlucHV0IGRpciwgbGl2ZSA9IFRSVUV9CmRpcihpbnB1dF9kaXIpCmBgYAoKV2Ugd2FudCB0byByZWFkIGluIGp1c3QgZm91ciBvZiB0aGVzZSBmaWxlcywgYXMgbGlzdGVkIHByZXZpb3VzbHkuClRvIHJlYWQgaW4gdGhlc2UgZmlsZXMsIHdlIGNvdWxkIHVzZSB0aGUgYHJlYWRyOjpyZWFkX3JkcygpYCBmdW5jdGlvbiAob3IgdGhlIGJhc2UgUiBgcmVhZFJEUygpYCkgZm91ciB0aW1lcywgb25jZSBmb3IgZWFjaCBvZiB0aGUgZmlsZXMuCldlIGNvdWxkIGFsc28gdXNlIGEgYGZvcmAgbG9vcCwgd2hpY2ggaXMgdGhlIGFwcHJvYWNoIHRoYXQgbWFueSBwcm9ncmFtbWluZyBsYW5ndWFnZXMgd291bGQgbGVhbiB0b3dhcmQuCkEgZGlmZmVyZW50IGFuZCBtb3JlIG1vZHVsYXIgY29kaW5nIGFwcHJvYWNoIHRvIHJlYWRpbmcgaW4gdGhlc2UgZmlsZXMgKGFuZCBtb3JlISkgaXMgdG8gbGV2ZXJhZ2UgdGhlIFtgcHVycnJgXShodHRwczovL3B1cnJyLnRpZHl2ZXJzZS5vcmcvKSBgdGlkeXZlcnNlYCBwYWNrYWdlLCB3aGljaCBwcm92aWRlcyBhIGNvbnZlbmllbnQgc2V0IG9mIGZ1bmN0aW9ucyBmb3Igb3BlcmF0aW5nIG9uIGxpc3RzLgpZb3UgY2FuIHJlYWQgbW9yZSBhYm91dCB0aGUgYHB1cnJyYCBmdW5jdGlvbnMgYW5kIHRoZWlyIHBvd2VyIGFuZCB1dGlsaXR5IGluIFIgaW4gW3RoZSAiRnVuY3Rpb25hbHMiIGNoYXB0ZXIgb2YgdGhlIF9BZHZhbmNlZCBSXyBlLWJvb2tdKGh0dHBzOi8vYWR2LXIuaGFkbGV5Lm56L2Z1bmN0aW9uYWxzLmh0bWwpLgoKT2YgcGFydGljdWxhciBpbnRlcmVzdCBpcyB0aGUgW2BwdXJycjo6bWFwKClgXShodHRwczovL3B1cnJyLnRpZHl2ZXJzZS5vcmcvcmVmZXJlbmNlL21hcC5odG1sKSBmYW1pbHkgb2YgZnVuY3Rpb25zLCB3aGljaCBjYW4gYmUgdXNlZCB0byBydW4gYSBnaXZlbiBmdW5jdGlvbiBvbiBlYWNoIGVsZW1lbnQgb2YgYSBsaXN0IChvciB2ZWN0b3IpIGluIG9uZSBjYWxsLgpUaGUgZ2VuZXJhbCBzeW50YXggZm9yIGBwdXJycjo6bWFwKClgIGFuZCBmcmllbmRzIGlzOgoKYGBgCiMgU3ludGF4IGZvciB1c2luZyB0aGUgbWFwIGZ1bmN0aW9uOgpwdXJycjo6bWFwKDxpbnB1dCBsaXN0IG9yIHZlY3Rvcj4sCiAgICAgICAgICAgPGZ1bmN0aW9uIHRvIGFwcGx5IHRvIGVhY2ggaXRlbSBpbiB0aGUgaW5wdXQ+LAogICAgICAgICAgIDxhbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgdG8gdGhlIGZ1bmN0aW9uIGNhbiBnbyBoZXJlPiwKICAgICAgICAgICA8YW5kIGFsc28gaGVyZSBpZiB0aGVyZSBhcmUgZXZlbiBtb3JlIGFyZ3VtZW50cywgYW5kIHNvIG9uPikKYGBgCgoKVGhlIG91dHB1dCBmcm9tIHJ1bm5pbmcgYHB1cnJyOjptYXAoKWAgaXMgYWx3YXlzIGEgbGlzdCAoYnV0IG5vdGUgdGhhdCB0aGVyZSBhcmUgb3RoZXIgYHB1cnJyOjptYXAoKWAgcmVsYXRpdmVzIHdoaWNoIHJldHVybiBvdGhlciBvYmplY3QgdHlwZXMsIGFzIHlvdSBjYW4gcmVhZCBhYm91dCBpbiBbdGhlIGBwdXJycjo6bWFwKClgIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vcHVycnIudGlkeXZlcnNlLm9yZy9yZWZlcmVuY2UvaW5kZXguaHRtbCkpLgpJZiB0aGlzIGNvbmNlcHQgc291bmRzIGEgbGl0dGxlIGZhbWlsaWFyIHRvIHlvdSwgdGhhdCdzIGJlY2F1c2UgaXQgcHJvYmFibHkgaXMhCkJhc2UgUidzIGBsYXBwbHkoKWAgZnVuY3Rpb24gY2FuIHByb3ZpZGUgc2ltaWxhciB1dGlsaXR5LCBhbmQgdGhlIGBwdXJycjo6bWFwKClgIGZhbWlseSBvZiBmdW5jdGlvbnMgY2FuIChpbiBwYXJ0KSBiZSB0aG91Z2h0IG9mIGFzIGFuIGFsdGVybmF0aXZlIHRvIHNvbWUgb2YgdGhlIGJhc2UgUiBgYXBwbHlgIGZ1bmN0aW9ucywgd2l0aCBtb3JlIGNvbnNpc3RlbnQgYmVoYXZpb3IuCgpMZXQncyBzZWUgYSB2ZXJ5IHNpbXBsZSBleGFtcGxlIG9mIGBwdXJycjo6bWFwKClgIGluIGFjdGlvbiwgaW5zcGlyZWQgYnkgY2FuY2VyIGdyb3VwcyB0aGUgRGF0YSBMYWIgaGFzIGFuYWx5emVkIHRocm91Z2ggdGhlIFtPcGVuUEJUQV0oaHR0cHM6Ly9naXRodWIuY29tL0FsZXhzTGVtb25hZGUvT3BlblBCVEEtYW5hbHlzaXMvKSBwcm9qZWN0OgoKYGBge3IgbWFwIGV4YW1wbGV9CiMgRGVmaW5lIGEgbGlzdCBvZiBjYW5jZXIgaGlzdG9sb2dpZXMKaGlzdG9sb2dpZXMgPC0gbGlzdCgKICAibG93LWdyYWRlIGdsaW9tYXMiICA9IGMoIlNFR0EiLCAiUEEiLCAiR05HIiwgIlBYQSIpLAogICJoaWdoLWdyYWRlIGdsaW9tYXMiID0gYygiRE1HIiwgIkRJUEciKSwKICAiZW1icnlvbmFsIHR1bW9ycyIgICA9IGMoIk1CIiwgIkFUUlQiLCAiRVRNUiIpCiApCgojIFRoZSBvdmVyYWxsIGxlbmd0aCBvZiB0aGUgbGlzdCBpcyAzCmxlbmd0aChoaXN0b2xvZ2llcykKCiMgSG93IGNhbiB3ZSBydW4gYGxlbmd0aCgpYCBvbiBlYWNoIGl0ZW0gb2YgdGhlIGxpc3Q/CiMgV2UgY2FuIHVzZSBvdXIgbmV3IGZyaWVuZCBwdXJycjo6bWFwKCk6CnB1cnJyOjptYXAoaGlzdG9sb2dpZXMsIGxlbmd0aCkKYGBgCgpPbmUgb3RoZXIgbmV3IGNvZGluZyBzdHJhdGVneSB3ZSdsbCBsZWFybiBpbiB0aGlzIG5vdGVib29rIGlzIHVzaW5nIHRoZSBbYGdsdWVgXShodHRwczovL2dsdWUudGlkeXZlcnNlLm9yZy8pIHBhY2thZ2UgdG8gY29tYmluZSBzdHJpbmdzLgpUaGlzIHBhY2thZ2Ugb2ZmZXJzIGEgY29udmVuaWVudCBmdW5jdGlvbiBgZ2x1ZTo6Z2x1ZSgpYCB0aGF0IGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIGJhc2UgUiBgcGFzdGUoKWAgZnVuY3Rpb24uCgpgYGB7ciBwYXN0ZX0KIyBEZWZpbmUgYSB2YXJpYWJsZSBmb3IgZXhhbXBsZToKb3JnX25hbWUgPC0gIkRhdGEgTGFiIgoKIyBXZSBjYW4gdXNlIHBhc3RlIHRvIGNvbWJpbmUgc3RyaW5ncyBhbmQgdmFyaWFibGVzOgpwYXN0ZSgiV2VsY29tZSB0byB0aGUiLCBvcmdfbmFtZSwgIndvcmtzaG9wIG9uIEFkdmFuY2VkIHNjUk5BLXNlcSEiKQpgYGAKCldlIGNhbiB1c2UgYGdsdWU6OmdsdWUoKWAgdG8gYWNjb21wbGlzaCB0aGUgc2FtZSBnb2FsIHdpdGggc29tZSBkaWZmZXJlbnQgc3ludGF4OgoKYGBge3IgZ2x1ZX0KIyBnbHVlOjpnbHVlIHRha2VzIGEgc2luZ2xlIHN0cmluZyBhcmd1bWVudCAob25seSBvbmUgc2V0IG9mIHF1b3RlcyEpLCBhbmQKIyAgdmFyaWFibGVzIGNhbiBlYXNpbHkgYmUgaW5jbHVkZWQgaW5zaWRlIHtjdXJseSBicmFjZXN9CmdsdWU6OmdsdWUoIldlbGNvbWUgdG8gdGhlIHtvcmdfbmFtZX0gd29ya3Nob3Agb24gQWR2YW5jZWQgc2NSTkEtc2VxISIpCmBgYAoKKE5vdGUgdGhhdCBldmVuIHRob3VnaCB0aGUgYGdsdWU6OmdsdWUoKWAgb3V0cHV0IGlzbid0IGluIHF1b3RlcywgaXQgc3RpbGwgYmVoYXZlcyBsaWtlIGEgc3RyaW5nISkKCgpBbHJpZ2h0LCB0aW1lIGZvciB0aGUgZ29vZCBzdHVmZiEKTGV0J3MgdXNlIGBwdXJycjo6bWFwKClgIHRvIHJlYWQgaW4gb3VyIFNDRSBvYmplY3RzIHNvIHRoYXQgdGhleSBhcmUgaW1tZWRpYXRlbHkgc3RvcmVkIHRvZ2V0aGVyIGluIGEgbGlzdC4KCgpXZSdsbCBmaXJzdCBuZWVkIHRvIGRlZmluZSBhIHZlY3RvciBvZiB0aGUgZmlsZSBwYXRocyB0byByZWFkIGluLgpXZSdsbCBzdGFydCBieSBjcmVhdGluZyBhIHZlY3RvciBvZiBzYW1wbGUgbmFtZXMgdGhlbXNlbHZlcyBhbmQgdGhlbiBmb3JtYXR0aW5nIHRoZW0gaW50byB0aGUgY29ycmVjdCBwYXRocy4KVGhpcyB3YXkgKGZvcmVzaGFkb3dpbmchKSB3ZSBhbHNvIGhhdmUgYSBzdGFuZC1hbG9uZSB2ZWN0b3Igb2YganVzdCBzYW1wbGUgbmFtZXMsIHdoaWNoIHdpbGwgY29tZSBpbiBoYW5keSEKCmBgYHtyIHNhbXBsZSBuYW1lc30KIyBWZWN0b3Igb2YgYWxsIHRoZSBzYW1wbGVzIHRvIHJlYWQgaW46CnNhbXBsZV9uYW1lcyA8LSBjKCJTQ1BDTDAwMDQ3OSIsCiAgICAgICAgICAgICAgICAgICJTQ1BDTDAwMDQ4MCIsCiAgICAgICAgICAgICAgICAgICJTQ1BDTDAwMDQ4MSIsCiAgICAgICAgICAgICAgICAgICJTQ1BDTDAwMDQ4MiIpCmBgYAoKCmBgYHtyIGRlZmluZSBzY2VfcGF0aHMsIGxpdmUgPSBUUlVFfQojIE5vdywgY29udmVydCB0aGVzZSB0byBmaWxlIHBhdGhzOiA8aW5wdXRfZGlyPi88c2FtcGxlX25hbWU+LnJkcwpzY2VfcGF0aHMgPC0gZmlsZS5wYXRoKGlucHV0X2RpciwKICAgICAgICAgICAgICAgICAgICAgICBnbHVlOjpnbHVlKCJ7c2FtcGxlX25hbWVzfS5yZHMiKQopCiMgUHJpbnQgdGhlIHNjZV9wYXRocyB2ZWN0b3IKc2NlX3BhdGhzCmBgYAoKV2UgY2FuIG5vdyByZWFkIHRoZXNlIGZpbGVzIGluIGFuZCBjcmVhdGUgYSBsaXN0IG9mIGZvdXIgU0NFIG9iamVjdHMuClNpbmNlIGByZWFkcjo6cmVhZF9yZHMoKWAgY2FuIG9ubHkgb3BlcmF0ZSBvbiBvbmUgaW5wdXQgYXQgYSB0aW1lLCB3ZSdsbCBuZWVkIHRvIHVzZSBgcHVycnI6Om1hcCgpYCB0byBydW4gaXQgb24gYWxsIGlucHV0IGZpbGUgcGF0aHMgaW4gb25lIGNvbW1hbmQuCkFsdGhvdWdoIGBzY2VfcGF0aHNgIGlzIGEgdmVjdG9yIChub3QgYSBsaXN0KSwgaXQgd2lsbCBzdGlsbCB3b3JrIGFzIGlucHV0IHRvIGBwdXJycjptYXAoKWAuClRoZSBvdXRwdXQgZnJvbSB0aGlzIGNvZGUgd2lsbCBzdGlsbCBiZSBhIGxpc3QsIHNpbmNlIHRoYXQncyB3aGF0IGBwdXJycjo6bWFwKClgIGFsd2F5cyByZXR1cm5zLgoKYGBge3IgcmVhZCBzY2UgcGF0aHMsIGxpdmUgPSBUUlVFfQojIFVzZSBwdXJycjo6bWFwKCkgdG8gcmVhZCBhbGwgZmlsZXMgaW50byBhIGxpc3QgYXQgb25jZQpzY2VfbGlzdCA8LSBwdXJycjo6bWFwKAogIHNjZV9wYXRocywKICByZWFkcjo6cmVhZF9yZHMKKQpgYGAKCkxldCdzIGhhdmUgYSBsb29rIGF0IG91ciBsaXN0IG9mIFNDRSBvYmplY3RzOgoKYGBge3IgcHJpbnQgc2NlIGxpc3QsIGxpdmU9VFJVRX0KIyBQcmludCBzY2VfbGlzdApzY2VfbGlzdApgYGAKCldlIG5vdyBoYXZlIGEgbGlzdCBvZiBsZW5ndGggZm91ciwgd2hlcmUgZWFjaCBpdGVtIGlzIGEgcHJvY2Vzc2VkIFNDRSBvYmplY3QhCkhvd2V2ZXIsIHdlJ2xsIG5lZWQgdG8ga2VlcCB0cmFjayBvZiB3aGljaCBzYW1wbGUgZWFjaCBpdGVtIGlzLCBzbyBpdCdzIGhlbHBmdWwgdG8gYWRkIF9uYW1lc18gdG8gdGhpcyBsaXN0IHJlcHJlc2VudGluZyB0aGUgcmVsZXZhbnQgc2FtcGxlIG5hbWVzLgoKYGBge3IgYWRkIGxpc3QgbmFtZXMsIGxpdmUgPSBUUlVFfQojIEFzc2lnbiB0aGUgc2FtcGxlIG5hbWVzIGFzIHRoZSBuYW1lcyBmb3Igc2NlX2xpc3QKbmFtZXMoc2NlX2xpc3QpIDwtIHNhbXBsZV9uYW1lcwpgYGAKCmBgYHtyIHByaW50IG5hbWVkIGxpc3QsIGxpdmU9VFJVRX0KIyBQcmludCB0aGUgbGlzdCB0byBzZWUgaXQgd2l0aCBuYW1lcwpzY2VfbGlzdApgYGAKCklmIHlvdSBsb29rIGNsb3NlbHkgYXQgdGhlIHByaW50ZWQgU0NFIG9iamVjdHMsIHlvdSBtYXkgbm90aWNlIHRoYXQgdGhleSBhbGwgY29udGFpbiBgY29sRGF0YWAgdGFibGUgY29sdW1ucyBgY2VsbHR5cGVfZmluZWAgYW5kIGBjZWxsdHlwZV9icm9hZGAuClRoZXNlIGNvbHVtbnMgKHdoaWNoIHdlIGFkZGVkIHRvIFNDRSBvYmplY3RzIGR1cmluZyBbcHJlLXByb2Nlc3NpbmddKGh0dHBzOi8vZ2l0aHViLmNvbS9BbGV4c0xlbW9uYWRlL3RyYWluaW5nLW1vZHVsZXMvdHJlZS9tYXN0ZXIvc2NSTkEtc2VxLWFkdmFuY2VkL3NldHVwL3JtcykpIGNvbnRhaW4gcHV0YXRpdmUgX2NlbGwgdHlwZSBhbm5vdGF0aW9uc18gYXMgYXNzaWduZWQgaW4gW1BhdGVsIF9ldCBhbC5fICgyMDIyKV0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwMTYvai5kZXZjZWwuMjAyMi4wNC4wMDMpLgpXZSB3aWxsIGVuZCB1cCBsZXZlcmFnaW5nIHRoZXNlIGNlbGwgdHlwZSBhbm5vdGF0aW9ucyB0byBleHBsb3JlIGhvdyBzdWNjZXNzZnVsIG91ciBpbnRlZ3JhdGlvbiBpczsgYWZ0ZXIgaW50ZWdyYXRpb24sIHdlIGV4cGVjdCBjZWxsIHR5cGVzIGZyb20gZGlmZmVyZW50IHNhbXBsZXMgdG8gZ3JvdXAgdG9nZXRoZXIsIHJhdGhlciB0aGFuIGJlaW5nIHNlcGFyYXRlZCBieSBiYXRjaGVzLgoKVGhhdCBzYWlkLCB0aGUgaW50ZWdyYXRpb24gbWV0aG9kcyB3ZSB3aWxsIGJlIGFwcGx5aW5nIF9kbyBub3QgYWN0dWFsbHkgdXNlXyB0aGVzZSBjZWxsIHR5cGUgYW5ub3RhdGlvbnMuCklmIHdlIGhhdmUgYW5ub3RhdGlvbnMsIHRoZXkgYXJlIGEgaGVscGZ1bCAiYm9udXMiIGZvciBhc3Nlc3NpbmcgdGhlIGludGVncmF0aW9uJ3Mgc3VjY2VzcywgYnV0IHRoZXkgYXJlIG5vdCBwYXJ0IG9mIHRoZSBpbnRlZ3JhdGlvbiBpdHNlbGYuCgoKIyMgUHJlcGFyZSB0aGUgU0NFIGxpc3QgZm9yIGludGVncmF0aW9uCgohW1NpbmdsZS1jZWxsIHJvYWRtYXA6IE1lcmdlXShkaWFncmFtcy9yb2FkbWFwX211bHRpX21lcmdlLnBuZykKCgpOb3cgdGhhdCB3ZSBoYXZlIGEgbGlzdCBvZiBwcm9jZXNzZWQgU0NFIG9iamVjdHMsIHdlIG5lZWQgdG8gbWVyZ2UgdGhlIG9iamVjdHMgaW50byBvbmUgb3ZlcmFsbCBTQ0Ugb2JqZWN0IGZvciBpbnB1dCB0byBpbnRlZ3JhdGlvbi4KQSB3b3JkIG9mIGNhdXRpb24gYmVmb3JlIHdlIGJlZ2luOiAqKlRoaXMgbWVyZ2VkIFNDRSBvYmplY3QgaXMgTk9UIGFuIGludGVncmF0ZWQgU0NFISoqCk1lcmdpbmcgU0NFcyBkb2VzIG5vdCBwZXJmb3JtIGFueSBiYXRjaCBjb3JyZWN0aW9uLCBidXQganVzdCByZW9yZ2FuaXplcyB0aGUgZGF0YSB0byBhbGxvdyB1cyB0byBwcm9jZWVkIHRvIGludGVncmF0aW9uIG5leHQuCgpUbyBtZXJnZSBTQ0Ugb2JqZWN0cywgd2UgZG8gbmVlZCB0byBkbyBzb21lIHdyYW5nbGluZyBhbmQgYm9va2tlZXBpbmcgdG8gZW5zdXJlIGNvbXBhdGliaWxpdHkgYW5kIHRoYXQgd2UgZG9uJ3QgbG9zZSBpbXBvcnRhbnQgaW5mb3JtYXRpb24uCk92ZXJhbGwgd2UnbGwgd2FudCB0byB0YWtlIGNhcmUgb2YgdGhlc2UgaXRlbXM6CgoxLiBXZSBzaG91bGQgYmUgYWJsZSB0byB0cmFjZSBzYW1wbGUtc3BlY2lmaWMgaW5mb3JtYXRpb24gYmFjayB0byB0aGUgb3JpZ2luYXRpbmcgc2FtcGxlLCBpbmNsdWRpbmcuLi4KICAgIC0gQ2VsbC1sZXZlbCBpbmZvcm1hdGlvbjogV2hpY2ggc2FtcGxlIGlzIGVhY2ggY2VsbCBmcm9tPwogICAgLSBMaWJyYXJ5LXNwZWNpZmljIGZlYXR1cmUgc3RhdGlzdGljcywgZS5nLiwgZ2VuZS1sZXZlbCBzdGF0aXN0aWNzIGZvciBhIGdpdmVuIGxpYnJhcnkgZm91bmQgaW4gYHJvd0RhdGFgLgogICAgV2hpY2ggc2FtcGxlIGlzIGEgZ2l2ZW4gZmVhdHVyZSBzdGF0aXN0aWMgZnJvbT8KMi4gU0NFIG9iamVjdHMgc2hvdWxkIGNvbnRhaW4gdGhlIHNhbWUgZ2VuZXM6IEVhY2ggU0NFIG9iamVjdCBzaG91bGQgaGF2ZSB0aGUgc2FtZSByb3cgbmFtZXMuCjMuIFNDRSBjZWxsIG1ldGFkYXRhIGNvbHVtbnMgc2hvdWxkIG1hdGNoOiBUaGUgYGNvbERhdGFgIGZvciBlYWNoIFNDRSBvYmplY3Qgc2hvdWxkIGhhdmUgdGhlIHNhbWUgY29sdW1uIG5hbWVzLgoKCldlJ2xsIGJlZ2luIGJ5IHRha2luZyBzb21lIHRpbWUgdG8gdGhvcm91Z2hseSBleHBsb3JlIG91ciBTQ0Ugb2JqZWN0cyBhbmQgZmlndXJlIG91dCB3aGF0IHdyYW5nbGluZyBzdGVwcyB3ZSBuZWVkIHRvIHRha2UgZm9yIHRoZXNlIHNwZWNpZmljIGRhdGEuCkRvbid0IHNraXAgdGhpcyBleHBsb3JhdGlvbiEKQmVhciBpbiBtaW5kIHRoYXQgdGhlIGV4YWN0IHdyYW5nbGluZyBzaG93biBoZXJlIHdpbGwgbm90IGJlIHRoZSBzYW1lIGZvciBvdGhlciBTQ0Ugb2JqZWN0cyB5b3Ugd29yayB3aXRoLCBidXQgdGhlIHNhbWUgZ2VuZXJhbCBwcmluY2lwbGVzIGFwcGx5LgoKCiMjIyMgUHJlc2VydmluZyBzYW1wbGUgaW5mb3JtYXRpb24gYXQgdGhlIGNlbGwgbGV2ZWwKCkhvdyB3aWxsIHdlIGJlIGFibGUgdG8gdGVsbCB3aGljaCBzYW1wbGUgYSBnaXZlbiBjZWxsIGNhbWUgZnJvbT8KClRoZSBiZXN0IHdheSB0byBkbyB0aGlzIGlzIHNpbXBseSB0byBhZGQgYSBgY29sRGF0YWAgY29sdW1uIHdpdGggdGhlIHNhbXBsZSBpbmZvcm1hdGlvbiwgc28gdGhhdCB3ZSBjYW4ga25vdyB3aGljaCBzYW1wbGUgZWFjaCByb3cgY2FtZSBmcm9tLgoKSW4gYWRkaXRpb24sIHdlIHdhbnQgdG8gcGF5IHNvbWUgYXR0ZW50aW9uIHRvIHRoZSBTQ0Ugb2JqZWN0J3MgY29sdW1uIG5hbWVzICh0aGUgY2VsbCBpZHMpLCB3aGljaCBtdXN0IHJlbWFpbiB1bmlxdWUgYWZ0ZXIgbWVyZ2luZyBzaW5jZSBkdXBsaWNhdGUgaWRzIHdpbGwgY2F1c2UgYW4gUiBlcnJvci4KSW4gdGhpcyBjYXNlLCB0aGUgU0NFIGNvbHVtbiBuYW1lcyBhcmUgYmFyY29kZXMgKHdoaWNoIGlzIHVzdWFsbHkgYnV0IG5vdCBhbHdheXMgdGhlIGNhc2UgaW4gU0NFIG9iamVjdHMpLCB3aGljaCBhcmUgb25seSBndWFyYW50ZWVkIHRvIGJlIHVuaXF1ZSBfd2l0aGluXyBhIHNhbXBsZSBidXQgbWF5IGJlIHJlcGVhdGVkIGFjcm9zcyBzYW1wbGVzLgpTbywgYWZ0ZXIgbWVyZ2luZywgaXQncyB0ZWNobmljYWxseSBwb3NzaWJsZSB0aGF0IG11bHRpcGxlIGNlbGxzIHdpbGwgaGF2ZSB0aGUgc2FtZSBiYXJjb2RlLgpUaGlzIHdvdWxkIGJlIGEgcHJvYmxlbSBmb3IgdHdvIHJlYXNvbnM6CkZpcnN0LCB0aGUgY2VsbCBpZCB3b3VsZCBub3QgYmUgYWJsZSB0byBwb2ludCB1cyBiYWNrIHRvIGNlbGwncyBvcmlnaW5hdGluZyBzYW1wbGUuClNlY29uZCwgaXQgd291bGQgbGl0ZXJhbGx5IGNhdXNlIGFuIGVycm9yIGluIFIsIHdoaWNoIGRvZXMgbm90IGFsbG93IGR1cGxpY2F0ZSBjb2x1bW4gbmFtZXMuCgoKT25lIHdheSB0byBlbnN1cmUgdGhhdCBjZWxsIGlkcyByZW1haW4gdW5pcXVlIGV2ZW4gYWZ0ZXIgbWVyZ2luZyBpcyB0byBhY3R1YWxseSBtb2RpZnkgdGhlbSBieSBfcHJlcGVuZGluZ18gdGhlIHJlbGV2YW50IHNhbXBsZSBuYW1lLgpGb3IgZXhhbXBsZSwgY29uc2lkZXIgdGhlc2UgYmFyY29kZXMgZm9yIHRoZSBgU0NQQ0wwMDA0NzlgIHNhbXBsZToKCmBgYHtyIGJhcmNvZGVzfQojIExvb2sgYXQgdGhlIGNvbHVtbiBuYW1lcyBmb3IgdGhlIGBTQ1BDTDAwMDQ3OWAgc2FtcGxlLCBmb3IgZXhhbXBsZQpjb2xuYW1lcyhzY2VfbGlzdCRTQ1BDTDAwMDQ3OSkgfD4KICAjIE9ubHkgcHJpbnQgb3V0IHRoZSBmaXJzdCA2IGZvciBjb252ZW5pZW5jZQogIGhlYWQoKQpgYGAKClRoZXNlIGlkcyB3aWxsIGJlIHVwZGF0ZWQgdG8gYFNDUENMMDAwNDc5LUdHR0FDQ1RDQUFHQ0dHQVRgLCBgU0NQQ0wwMDA0NzktQ0FDQUdBVEFHVEdBR1RHQ2AsIGFuZCBzbyBvbiwgdGhlcmVieSBlbnN1cmluZyBmdWxseSB1bmlxdWUgaWRzIGZvciBhbGwgY2VsbHMgYWNyb3NzIGFsbCBzYW1wbGVzLgoKIyMjIyBQcmVzZXJ2aW5nIHNhbXBsZSBpbmZvcm1hdGlvbiBhdCB0aGUgZ2VuZSBsZXZlbAoKVGhlIGByb3dEYXRhYCB0YWJsZSBpbiBTQ0Ugb2JqZWN0cyB3aWxsIG9mdGVuIGNvbnRhaW4gYm90aCAiZ2VuZXJhbCIgYW5kICJsaWJyYXJ5LXNwZWNpZmljIiBpbmZvcm1hdGlvbiwgZm9yIGV4YW1wbGU6CgpgYGB7ciByb3dkYXRhfQpyb3dEYXRhKHNjZV9saXN0JFNDUENMMDAwNDc5KSB8PgogIGhlYWQoKQpgYGAKCkhlcmUsIHRoZSByb3duYW1lcyBhcmUgRW5zZW1ibCBnZW5lIGlkcywgYW5kIGNvbHVtbnMgYXJlIGBnZW5lX3N5bWJvbGAsIGBtZWFuYCwgYW5kIGBkZXRlY3RlZGAuClRoZSBgZ2VuZV9zeW1ib2xgIGNvbHVtbiBpcyBnZW5lcmFsIGluZm9ybWF0aW9uIGFib3V0IGFsbCBnZW5lcywgbm90IHNwZWNpZmljIHRvIGFueSBsaWJyYXJ5IG9yIGV4cGVyaW1lbnQsIGJ1dCBgbWVhbmAgYW5kIGBkZXRlY3RlZGAgYXJlIGxpYnJhcnktc3BlY2lmaWMgZ2VuZSBzdGF0aXN0aWNzLgpTbywgYGdlbmVfc3ltYm9sYCBkb2VzIG5vdCBuZWVkIHRvIGJlIHRyYWNlZCBiYWNrIHRvIGl0cyBvcmlnaW5hdGluZyBzYW1wbGUsIGJ1dCBgbWVhbmAgYW5kIGBkZXRlY3RlZGAgZG8uClRvIHRoaXMgZW5kLCB3ZSBjYW4gdGFrZSBhIHNpbWlsYXIgYXBwcm9hY2ggdG8gd2hhdCB3ZSdsbCBkbyBmb3IgY2VsbCBpZHM6CldlIGNhbiBjaGFuZ2UgdGhlIHNhbXBsZS1zcGVjaWZpYyBgcm93RGF0YWAgY29sdW1uIG5hbWVzIGJ5IHByZXBlbmRpbmcgdGhlIHNhbXBsZSBuYW1lLgpGb3IgZXhhbXBsZSwgcmF0aGVyIHRoYW4gYmVpbmcgY2FsbGVkIGBtZWFuYCwgdGhpcyBjb2x1bW4gd2lsbCBiZSBuYW1lZCBgU0NQQ0wwMDA0NzktbWVhbmAgZm9yIHRoZSBgU0NQQ0wwMDA0NzlgIHNhbXBsZS4KCkFsbCBvdXIgU0NFIG9iamVjdHMgaGF2ZSB0aGUgc2FtZSBgcm93RGF0YWAgY29sdW1ucyAoYXMgd2UgY2FuIHNlZSBpbiB0aGUgbmV4dCBjaHVuayksIHNvIHdlJ2xsIHBlcmZvcm0gdGhpcyByZW5hbWluZyBhY3Jvc3MgYWxsIFNDRXMuCgpgYGB7ciBjb21wYXJlIHJvd2RhdGEsIGxpdmUgPSBUUlVFfQojIFVzZSBgcHVycnI6Om1hcCgpYCB0byBxdWlja2x5IGV4dHJhY3Qgcm93RGF0YSBjb2x1bW4gbmFtZXMgZm9yIGFsbCBTQ0VzCnB1cnJyOjptYXAoc2NlX2xpc3QsCiAgICAgICAgICAgXCh4KSBjb2xuYW1lcyhyb3dEYXRhKHgpKSkKYGBgCgoKIyMjIyBFbnN1cmluZyB0aGF0IG9ubHkgc2hhcmVkIGdlbmVzIGFyZSB1c2VkCgpUaGUgbmV4dCBzdGVwIGluIGVuc3VyaW5nIFNDRSBjb21wYXRpYmlsaXR5IGlzIHRvIG1ha2Ugc3VyZSB0aGV5IGFsbCBjb250YWluIHRoZSBzYW1lIGdlbmVzLCB3aGljaCBhcmUgc3RvcmVkIGFzIHRoZSBTQ0Ugb2JqZWN0J3Mgcm93IG5hbWVzICh0aGVzZSBuYW1lcyBhcmUgYWxzbyBmb3VuZCB0aGUgYHJvd0RhdGFgIHNsb3QncyByb3cgbmFtZXMpLgpIZXJlLCB0aG9zZSBnZW5lIGlkcyBhcmUgdW5pcXVlIEVuc2VtYmwgZ2VuZSBpZHMuCgpXZSBjYW4gdXNlIHNvbWUgYHB1cnJyYCBtYWdpYyB0byBxdWlja2x5IGZpbmQgdGhlIHNldCBvZiBzaGFyZWQgZ2VuZXMgYW1vbmcgb3VyIHNhbXBsZXM6CgpgYGB7ciBzaGFyZWQgZ2VuZXN9CiMgRGVmaW5lIHZlY3RvciBvZiBzaGFyZWQgZ2VuZXMKc2hhcmVkX2dlbmVzIDwtIHNjZV9saXN0IHw+CiAgIyBnZXQgcm93bmFtZXMgKGdlbmVzKSBmb3IgZWFjaCBTQ0UgaW4gc2NlX2xpc3QKICBwdXJycjo6bWFwKHJvd25hbWVzKSB8PgogICMgcmVkdWNlIHRvIHRoZSBfaW50ZXJzZWN0aW9uXyBhbW9uZyBsaXN0cwogIHB1cnJyOjpyZWR1Y2UoaW50ZXJzZWN0KQpgYGAKCmBgYHtyIHByaW50IHNoYXJlZCBnZW5lcywgbGl2ZSA9IFRSVUV9CiMgVXNlIGhlYWQgdG8gbG9vayBhdCB0aGUgdmVjdG9yIG9mIHNoYXJlZCBnZW5lczoKaGVhZChzaGFyZWRfZ2VuZXMpCmBgYAoKSW4gdGhpcyBjYXNlLCB3ZSBoYXBwZW4gdG8ga25vdyB0aGF0IGFsbCBTQ0Ugb2JqZWN0cyB3ZSdyZSB3b3JraW5nIHdpdGggYWxyZWFkeSBjb250YWluZWQgdGhlIHNhbWUgZ2VuZXMuCldlIGRvIGEgcXVpY2stYW5kLWRpcnR5IGNoZWNrIGZvciB0aGlzIGJ5IGxvb2tpbmcgYXQgdGhlIG51bWJlciBvZiByb3dzIGFjcm9zcyBTQ0Ugb2JqZWN0cywgYW5kIHdlJ2xsIHNlZSB0aGF0IHRoZXkgYXJlIGFsbCB0aGUgc2FtZToKCmBgYHtyIGNoZWNrIHNoYXJlZCBnZW5lcywgbGl2ZSA9IFRSVUV9CiMgVGhlIG51bWJlciBvZiBnZW5lcyBpbiBhbiBTQ0UgY29ycmVzcG9uZHMgdG8gaXRzIG51bWJlciBvZiByb3dzOgpzY2VfbGlzdCB8PgogIHB1cnJyOjptYXAobnJvdykKYGBgCgpTbywgZm9yIG91ciBkYXRhLCB3ZSB3aWxsIG5vdCBoYXZlIHRvIHN1YnNldCB0byBzaGFyZWQgZ2VuZXMgc2luY2UgdGhleSBhcmUgYWxyZWFkeSBzaGFyZWQhCgojIyMjIEVuc3VyaW5nIG1hdGNoaW5nIGNvbHVtbnMgaW4gYGNvbERhdGFgCgpGaW5hbGx5LCB3ZSdsbCBuZWVkIHRvIGhhdmUgdGhlIHNhbWUgY29sdW1uIG5hbWVzIGFjcm9zcyBhbGwgU0NFIGBjb2xEYXRhYCB0YWJsZXMsIHNvIGxldCdzIGxvb2sgYXQgYWxsIHRob3NlIGNvbHVtbiBuYW1lcy4KV2UgY2FuIHVzZSBzaW1pbGFyIHN5bnRheCBoZXJlIHRvIHdoYXQgd2UgdXNlZCB0byBsb29rIGF0IGFsbCB0aGUgYHJvd0RhdGFgIGNvbHVtbiBuYW1lcy4KCmBgYHtyIGNvbXBhcmUgY29sZGF0YX0KcHVycnI6Om1hcChzY2VfbGlzdCwKICAgICAgICAgICBcKHgpIGNvbG5hbWVzKGNvbERhdGEoeCkpICkKYGBgCgpJdCBsb29rcyBsaWtlIHRoZSBjb2x1bW4gbmFtZXMgYXJlIGFsbCBhbHJlYWR5IG1hdGNoaW5nIGFtb25nIFNDRXMsIHNvIHRoZXJlJ3Mgbm8gc3BlY2lmaWMgcHJlcGFyYXRpb24gd2UnbGwgbmVlZCB0byBkbyB0aGVyZS4KCiMjIyBQZXJmb3JtIFNDRSBtZXJnaW5nCgpBcyB5b3UgY2FuIHNlZSwgdGhlcmUncyBhIGxvdCBvZiBtb3ZpbmcgcGFydHMgdG8gY29uc2lkZXIhCkFnYWluLCB0aGVzZSBtb3ZpbmcgcGFydHMgbWF5ICh3aWxsISkgZGlmZmVyIGZvciBTQ0VzIHRoYXQgeW91IGFyZSB3b3JraW5nIHdpdGgsIHNvIHlvdSBoYXZlIHRvIGV4cGxvcmUgeW91ciBvd24gU0NFcyBpbiBkZXB0aCB0byBwcmVwYXJlIGZvciBtZXJnaW5nLgoKQmFzZWQgb24gb3VyIGV4cGxvcmF0aW9uLCBoZXJlIGlzIGEgc2NoZW1hdGljIG9mIGhvdyBvbmUgb2YgdGhlIFNDRSBvYmplY3RzIHdpbGwgdWx0aW1hdGVseSBiZSBtb2RpZmllZCBpbnRvIHRoZSBmaW5hbCBtZXJnZWQgU0NFOgoKIVtdKGRpYWdyYW1zL3RlY2huaWNhbF9tZXJnZV9zY2UucG5nKQoKCldlJ2xsIHdyaXRlIGEgX2N1c3RvbSBmdW5jdGlvbl8gKHNlZW4gaW4gdGhlIGNodW5rIGJlbG93KSB0YWlsb3JlZCB0byBvdXIgd3JhbmdsaW5nIHN0ZXBzIHRoYXQgcHJlcGFyZXMgYSBzaW5nbGUgU0NFIG9iamVjdCBmb3IgbWVyZ2luZy4KV2UnbGwgdGhlbiB1c2Ugb3VyIG5ldyBgcHVycnI6Om1hcCgpYCBwcm9ncmFtbWluZyBza2lsbHMgdG8gcnVuIHRoaXMgZnVuY3Rpb24gb3ZlciB0aGUgYHNjZV9saXN0YC4KVGhpcyB3aWxsIGdpdmUgdXMgYSBuZXcgbGlzdCBvZiBmb3JtYXR0ZWQgU0NFcyB0aGF0IHdlIGNhbiBwcm9jZWVkIHRvIG1lcmdlLgpJdCdzIGltcG9ydGFudCB0byByZW1lbWJlciB0aGF0IHRoZSBgZm9ybWF0X3NjZSgpYCBmdW5jdGlvbiB3cml0dGVuIGJlbG93IGlzIG5vdCBhIGZ1bmN0aW9uIGZvciBnZW5lcmFsIHVzZSDigJMgaXQncyBiZWVuIHByZWNpc2VseSB3cml0dGVuIHRvIG1hdGNoIHRoZSBwcm9jZXNzaW5nIHdlIG5lZWQgdG8gZG8gZm9yIF90aGVzZV8gU0NFcywgYW5kIGRpZmZlcmVudCBTQ0VzIHlvdSB3b3JrIHdpdGggd2lsbCByZXF1aXJlIGRpZmZlcmVudCB0eXBlcyBvZiBwcm9jZXNzaW5nLgoKYGBge3IgZm9ybWF0X3NjZSBmdW5jdGlvbn0KZm9ybWF0X3NjZSA8LSBmdW5jdGlvbihzY2UsIHNhbXBsZV9uYW1lKSB7CiAgIyBJbnB1dCBhcmd1bWVudHM6CiAgIyMgc2NlOiBBbiBTQ0Ugb2JqZWN0IHRvIGZvcm1hdAogICMjIHNhbXBsZV9uYW1lOiBUaGUgU0NFIG9iamVjdCdzIG5hbWUKICAjIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBhIGZvcm1hdHRlZCBTQ0Ugb2JqZWN0LgoKICAjIyMjIyMgRW5zdXJlIHRoYXQgd2UgY2FuIGlkZW50aWZ5IHRoZSBvcmlnaW5hdGluZyBzYW1wbGUgaW5mb3JtYXRpb24gIyMjIyMjCiAgIyBBZGQgYSBjb2x1bW4gY2FsbGVkIGBzYW1wbGVgIHRoYXQgc3RvcmVzIHRoaXMgaW5mb3JtYXRpb24KICAjIFRoaXMgd2lsbCBiZSBzdG9yZWQgaW4gYGNvbERhdGFgCiAgc2NlJHNhbXBsZSA8LSBzYW1wbGVfbmFtZQoKCiAgIyMjIyMjIEVuc3VyZSBjZWxsIGlkcyB3aWxsIGJlIHVuaXF1ZSAjIyMjIyMKICAjIFVwZGF0ZSB0aGUgU0NFIG9iamVjdCBjb2x1bW4gbmFtZXMgKGNlbGwgaWRzKSBieSBwcmVwZW5kaW5nIGBzYW1wbGVfbmFtZWAKICBjb2xuYW1lcyhzY2UpIDwtIGdsdWU6OmdsdWUoIntzYW1wbGVfbmFtZX0te2NvbG5hbWVzKHNjZSl9IikKCgogICMjIyMjIyBFbnN1cmUgZ2VuZS1sZXZlbCBzdGF0aXN0aWNzIGNhbiBiZSBpZGVudGlmaWVkIGluIGByb3dEYXRhYCAjIyMjIyMKICAjIFdlIHdhbnQgdG8gcmVuYW1lIHRoZSBjb2x1bW5zIGBtZWFuYCBhbmQgYGRldGVjdGVkYCB0byBjb250YWluIHRoZSBgc2FtcGxlX25hbWVgCiAgIyBSZWNhbGwgdGhlIG5hbWVzIGFyZTogImdlbmVfc3ltYm9sIiwgIm1lYW4iLCAiZGV0ZWN0ZWQiCiAgY29sbmFtZXMocm93RGF0YShzY2UpKSA8LSBjKCJnZW5lX3N5bWJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsdWU6OmdsdWUoIntzYW1wbGVfbmFtZX0tbWVhbiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbHVlOjpnbHVlKCJ7c2FtcGxlX25hbWV9LWRldGVjdGVkIikpCgogICMgUmV0dXJuIHRoZSBmb3JtYXR0ZWQgU0NFIG9iamVjdAogIHJldHVybihzY2UpCn0KYGBgCgpUbyBydW4gdGhpcyBmdW5jdGlvbiwgd2UnbGwgdXNlIHRoZSBgcHVycnI6Om1hcDIoKWAgZnVuY3Rpb24sIGEgcmVsYXRpdmUgb2YgYHB1cnJyOjptYXAoKWAgdGhhdCBhbGxvd3MgeW91IHRvIGxvb3Agb3ZlciBfdHdvXyBpbnB1dCBsaXN0cy92ZWN0b3JzLgpJbiBvdXIgY2FzZSwgd2Ugd2FudCB0byBydW4gYGZvcm1hdF9zY2UoKWAgb3ZlciBwYWlyZWQgYHNjZV9saXN0YCBpdGVtcyBhbmQgYHNjZV9saXN0YCBuYW1lcy4KCmBgYHtyIGZvcm1hdCBzY2VzIGZvciBtZXJnZSwgbGl2ZSA9IFRSVUV9CiMgV2UgY2FuIHVzZSBgcHVycnI6Om1hcDIoKWAgdG8gbG9vcCBvdmVyIHR3byBsaXN0L3ZlY3RvciBhcmd1bWVudHMKc2NlX2xpc3RfZm9ybWF0dGVkIDwtIHB1cnJyOjptYXAyKAogICMgRWFjaCAiaXRlcmF0aW9uIiB3aWxsIG1hcmNoIGRvd24gdGhlIGZpcnN0IHR3bwogICMgIGFyZ3VtZW50cyBgc2NlX2xpc3RgIGFuZCBgbmFtZXMoc2NlX2xpc3QpYCBpbiBvcmRlcgogIHNjZV9saXN0LAogIG5hbWVzKHNjZV9saXN0KSwKICAjIE5hbWUgb2YgdGhlIGZ1bmN0aW9uIHRvIHJ1bgogIGZvcm1hdF9zY2UKKQoKIyBQcmludCByZXN1bHRpbmcgbGlzdApzY2VfbGlzdF9mb3JtYXR0ZWQKYGBgCgooUHNzdCwgbGlrZSBgcHVycnJgIGFuZCB3YW50IHRvIGRpdmUgZGVlcGVyPyBDaGVjayBvdXQgW3RoZSBgcHVycnI6OmltYXAoKWAgZnVuY3Rpb25dKGh0dHBzOi8vcHVycnIudGlkeXZlcnNlLm9yZy9yZWZlcmVuY2UvaW1hcC5odG1sKSEpCgoKQXQgbG9uZyBsYXN0LCB3ZSBhcmUgcmVhZHkgdG8gbWVyZ2UgdGhlIFNDRXMsIHdoaWNoIHdlJ2xsIGRvIHVzaW5nIHRoZSBSIGZ1bmN0aW9uIGBjYmluZCgpYC4KVGhlIGBjYmluZCgpYCBmdW5jdGlvbiBpcyBvZnRlbiB1c2VkIHRvIGNvbWJpbmUgZGF0YSBmcmFtZXMgb3IgbWF0cmljZXMgYnkgY29sdW1uLCBpLmUuICJzdGFjayIgdGhlbSBuZXh0IHRvIGVhY2ggb3RoZXIuClRoZSBzYW1lIHByaW5jaXBsZSBhcHBsaWVzIGhlcmUsIGJ1dCB3aGVuIHJ1biBvbiBTQ0Ugb2JqZWN0cywgYGNiaW5kKClgIHdpbGwgY3JlYXRlIGEgbmV3IFNDRSBvYmplY3QgYnkgY29tYmluaW5nIGBjb3VudHNgIGFuZCBgbG9nY291bnRzYCBtYXRyaWNlcyBieSBjb2x1bW4uCkZvbGxvd2luZyB0aGF0IHN0cnVjdHVyZSwgb3RoZXIgU0NFIHNsb3RzIChgY29sRGF0YWAsIGByb3dEYXRhYCwgcmVkdWNlZCBkaW1lbnNpb25zLCBhbmQgb3RoZXIgbWV0YWRhdGEpIGFyZSBjb21iaW5lZCBhcHByb3ByaWF0ZWx5LgoKU2luY2Ugd2UgbmVlZCB0byBhcHBseSBgY2JpbmQoKWAgdG8gYSBfbGlzdF8gb2Ygb2JqZWN0cywgd2UgbmVlZCB0byB1c2Ugc29tZSBzbGlnaHRseS1nbmFybHkgc3ludGF4OiBXZSdsbCB1c2UgdGhlIGZ1bmN0aW9uIGBkby5jYWxsKClgLCB3aGljaCBhbGxvd3MgdGhlIGBjYmluZCgpYCBpbnB1dCB0byBiZSBhIGxpc3Qgb2Ygb2JqZWN0cyB0byBjb21iaW5lLgoKYGBge3IgbWVyZ2VzIHNjZXMsIGxpdmUgPSBUUlVFfQojIE1lcmdlIFNDRSBvYmplY3RzCm1lcmdlZF9zY2UgPC0gZG8uY2FsbChjYmluZCwgc2NlX2xpc3RfZm9ybWF0dGVkKQoKIyBQcmludCB0aGUgbWVyZ2VkX3NjZSBvYmplY3QKbWVyZ2VkX3NjZQpgYGAKCldlIG5vdyBoYXZlIGEgc2luZ2xlIFNDRSBvYmplY3QgdGhhdCBjb250YWlucyBhbGwgY2VsbHMgZnJvbSBhbGwgc2FtcGxlcyB3ZSdkIGxpa2UgdG8gaW50ZWdyYXRlLgoKTGV0J3MgdGFrZSBhIHBlZWsgYXQgc29tZSBvZiB0aGUgaW5uYXJkcyBvZiB0aGlzIG5ldyBTQ0Ugb2JqZWN0OgoKYGBge3IgZXhwbG9yZSBtZXJnZWRfc2NlLCBsaXZlID0gVFJVRX0KIyBXaGF0IGFyZSB0aGUgdW5pcXVlIHZhbHVlcyBpbiB0aGUgYHNhbXBsZWAgY29sdW1uPwp1bmlxdWUoIGNvbERhdGEobWVyZ2VkX3NjZSkkc2FtcGxlICkKCiMgV2hhdCBhcmUgdGhlIG5ldyBjZWxsIGlkcyAoY29sdW1uIG5hbWVzKT8KaGVhZCggY29sbmFtZXMobWVyZ2VkX3NjZSkgKQoKIyBXaGF0IGRvZXMgcm93RGF0YSBsb29rIGxpa2U/CmhlYWQoIHJvd0RhdGEobWVyZ2VkX3NjZSkgKQpgYGAKCgojIyBJbnRlZ3JhdGlvbgoKIVtTaW5nbGUtY2VsbCByb2FkbWFwOiBJbnRlZ3JhdGVdKGRpYWdyYW1zL3JvYWRtYXBfbXVsdGlfaW50ZWdyYXRlLnBuZykKCgpTbyBmYXIsIHdlJ3ZlIGNyZWF0ZWQgYSBgbWVyZ2VkX3NjZWAgb2JqZWN0IHdoaWNoIGlzIChhbG1vc3QhKSByZWFkeSBmb3IgaW50ZWdyYXRpb24uCgpUaGUgaW50ZWdyYXRpb24gbWV0aG9kcyB3ZSdsbCBiZSB1c2luZyBoZXJlIGFjdHVhbGx5IHBlcmZvcm0gYmF0Y2ggY29ycmVjdGlvbiBvbiBhIHJlZHVjZWQgZGltZW5zaW9uIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBub3JtYWxpemVkIGdlbmUgZXhwcmVzc2lvbiB2YWx1ZXMsIHdoaWNoIGlzIG1vcmUgZWZmaWNpZW50LgpgZmFzdE1OTmAgYW5kIGBoYXJtb255YCBzcGVjaWZpY2FsbHkgdXNlIFBDQSBmb3IgdGhpcywgYnV0IGJlIGF3YXJlIHRoYXQgZGlmZmVyZW50IGludGVncmF0aW9uIG1ldGhvZHMgbWF5IHVzZSBvdGhlciBraW5kcyBvZiByZWR1Y2VkIGRpbWVuc2lvbnMuCgpZb3UnbGwgbm90aWNlIHRoYXQgdGhlIG1lcmdlZCBTQ0Ugb2JqZWN0IG9iamVjdCBhbHJlYWR5IGNvbnRhaW5zIFBDQSBhbmQgVU1BUCByZWR1Y2VkIGRpbWVuc2lvbnMsIHdoaWNoIHdlcmUgY2FsY3VsYXRlZCBkdXJpbmcgb3VyIHByZS1wcm9jZXNzaW5nOgoKYGBge3IgbWVyZ2VkX3NjZSByZWRkaW0sIGxpdmUgPSBUUlVFfQojIFByaW50IHRoZSByZWR1Y2VkRGltTmFtZXMgb2YgdGhlIG1lcmdlZF9zY2UKcmVkdWNlZERpbU5hbWVzKG1lcmdlZF9zY2UpCmBgYAoKVGhlc2UgcmVwcmVzZW50IHRoZSBvcmlnaW5hbCBkaW1lbnNpb24gcmVkdWN0aW9ucyB0aGF0IHdlcmUgcGVyZm9ybWVkIG9uIF9lYWNoIGluZGl2aWR1YWwgU0NFXyBiZWZvcmUgbWVyZ2luZywgYnV0IHdlIGFjdHVhbGx5IG5lZWQgdG8gY2FsY3VsYXRlIFBDQSAoYW5kIFVNQVAgZm9yIHZpc3VhbGl6YXRpb24pIGZyb20gdGhlIG1lcmdlZCBvYmplY3QgZGlyZWN0bHkuCgpXaHkgY2FuJ3Qgd2UgdXNlIHRoZSBzYW1wbGUtc3BlY2lmaWMgUENBIGFuZCBVTUFQIG1hdHJpY2VzPwpQYXJ0IG9mIHRoZXNlIGNhbGN1bGF0aW9ucyB0aGVtc2VsdmVzIGludm9sdmVzIHNjYWxpbmcgdGhlIHJhdyBkYXRhIHRvIGNlbnRlciB0aGUgbWVhbi4KV2hlbiBzYW1wbGVzIGFyZSBzZXBhcmF0ZWx5IGNlbnRlcmVkIGJ1dCBwbG90dGluZyB0b2dldGhlciwgeW91IHdpbGwgc2VlIHNhbXBsZXMgIm92ZXJsYXBwaW5nIiBpbiBzcGFjZSwgYnV0IHRoaXMgcGxhY2VtZW50IGlzIGFjdHVhbGx5IGp1c3QgYW4gYXJ0aWZhY3Qgb2YgdGhlIGluZGl2aWR1YWwgY2VudGVyaW5nLgpJbiBhZGRpdGlvbiwgdGhlIG1hdGhlbWF0aWNhbCByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgb3JpZ2luYWwgZXhwcmVzc2lvbiBkYXRhIGFuZCByZWR1Y2VkIGRpbWVuc2lvbiB2ZXJzaW9uIG9mIHRoYXQgZGF0YSB3aWxsIGRpZmZlciBhY3Jvc3Mgc2FtcGxlcywgbWVhbmluZyB3ZSBjYW4ndCBpbnRlcnByZXQgdGhlbSBhbGwgdG9nZXRoZXIuClRvIHNlZSBob3cgdGhpcyBsb29rcywgbGV0J3MgbG9vayBhdCB0aGUgVU1BUCB3aGVuIGNhbGN1bGF0ZWQgZnJvbSBpbmRpdmlkdWFsIHNhbXBsZXM6CgpgYGB7ciBwbG90IGluZGl2aWR1YWwgVU1BUHMsIGxpdmUgPSBUUlVFfQojIFBsb3QgVU1BUCBjYWxjdWxhdGVkIGZyb20gaW5kaXZpZHVhbCBzYW1wbGVzIHdpdGggc2VwYXJhdGUgc2NhbGluZwpzY2F0ZXI6OnBsb3RSZWR1Y2VkRGltKG1lcmdlZF9zY2UsCiAgICAgICAgICAgICAgICAgICAgICAgZGltcmVkID0gIlVNQVAiLAogICAgICAgICAgICAgICAgICAgICAgIGNvbG9yX2J5ID0gInNhbXBsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRfc2l6ZSA9IDAuNSwKICAgICAgICAgICAgICAgICAgICAgICBwb2ludF9hbHBoYSA9IDAuMikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIiwgbmFtZSA9ICJzYW1wbGUiKSArICMgVXNlIGEgQ1ZELWZyaWVuZGx5IGNvbG9yIHNjaGVtZSBhbmQgc3BlY2lmeSBsZWdlbmQgbmFtZQogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzLCBhbHBoYSA9IDEpKSkgKyAjIE1vZGlmeSB0aGUgbGVnZW5kIGtleSB3aXRoIGxhcmdlciwgZWFzaWVyIHRvIHNlZSBwb2ludHMKICBnZ3RpdGxlKCJVTUFQIGNhbGN1bGF0ZWQgb24gZWFjaCBzYW1wbGUgc2VwYXJhdGVseSIpCgpgYGAKCgpBcyB3ZSBzZWUgaW4gdGhpcyBVTUFQLCBhbGwgc2FtcGxlcyBhcmUgY2VudGVyZWQgYXQgemVybyBhbmQgYWxsIG92ZXJsYXBwaW5nLgpUaGlzIHZpc3VhbCBhcnRpZmFjdCBjYW4gZ2l2ZSB0aGUgX2luY29ycmVjdCBpbXByZXNzaW9uXyB0aGF0IGRhdGEgaXMgaW50ZWdyYXRlZCAtIHRvIGJlIGNsZWFyLCB0aGlzIGRhdGEgaXMgTk9UIGludGVncmF0ZWQhCgpGb3IgaW5wdXQgdG8gaW50ZWdyYXRpb24sIHdlJ2xsIHdhbnQgdGhlIHJlZHVjZWQgZGltZW5zaW9uIGNhbGN1bGF0aW9ucyB0byBjb25zaWRlciBub3JtYWxpemVkIGdlbmUgZXhwcmVzc2lvbiB2YWx1ZXMgZnJvbSBhbGwgc2FtcGxlcyBzaW11bHRhbmVvdXNseS4KU28gd2UnbGwgbmVlZCB0byByZWNhbGN1bGF0ZSBQQ0EgKGFuZCBVTUFQIGZvciB2aXN1YWxpemF0aW9uKSBvbiB0aGUgbWVyZ2VkIG9iamVjdC4KV2UnbGwgYWxzbyBzYXZlIHRoZXNlIG5ldyByZWR1Y2VkIGRpbWVuc2lvbnMgd2l0aCBkaWZmZXJlbnQgbmFtZXMsIGBtZXJnZWRfUENBYCBhbmQgYG1lcmdlZF9VTUFQYCwgdG8gZGlzdGluZ3Vpc2ggdGhlbSBmcm9tIGFscmVhZHktcHJlc2VudCBgUENBYCBhbmQgYFVNQVBgLgoKRmlyc3QsIGFzIHVzdWFsLCB3ZSdsbCBkZXRlcm1pbmUgdGhlIGhpZ2gtdmFyaWFuY2UgZ2VuZXMgdG8gdXNlIGZvciBQQ0EgZnJvbSB0aGUgYG1lcmdlZF9zY2VgIG9iamVjdC4KRm9yIHRoaXMsIHdlJ2xsIG5lZWQgdG8gcHJvdmlkZSB0aGUgYXJndW1lbnQgYGJsb2NrID0gbWVyZ2VkX3NjZSRzYW1wbGVgIHdoZW4gbW9kZWxpbmcgZ2VuZSB2YXJpYW5jZSwgd2hpY2ggdGVsbHMgYHNjcmFuOjptb2RlbEdlbmVWYXIoKWAgdG8gZmlyc3QgbW9kZWwgdmFyaWFuY2Ugc2VwYXJhdGVseSBmb3IgZWFjaCBiYXRjaCBhbmQgdGhlbiBjb21iaW5lIHRob3NlIG1vZGVsaW5nIHN0YXRpc3RpY3MuCgpgYGB7ciBjYWxjIG1lcmdlZCBodiBnZW5lc30KIyBTcGVjaWZ5IHRoZSBudW1iZXIgb2YgZ2VuZXMgdG8gaWRlbnRpZnkKbnVtX2dlbmVzIDwtIDIwMDAKCiMgQ2FsY3VsYXRlIHZhcmlhdGlvbiBmb3IgZWFjaCBnZW5lCmdlbmVfdmFyaWFuY2UgPC0gc2NyYW46Om1vZGVsR2VuZVZhcihtZXJnZWRfc2NlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzcGVjaWZ5IHRoZSBncm91cGluZyBjb2x1bW46CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBibG9jayA9IG1lcmdlZF9zY2Ukc2FtcGxlKQoKIyBHZXQgdGhlIHRvcCBgbnVtX2dlbmVzYCBoaWdoLXZhcmlhbmNlIGdlbmVzIHRvIHVzZSBmb3IgZGltZW5zaW9uIHJlZHVjdGlvbgpodl9nZW5lcyA8LSBzY3Jhbjo6Z2V0VG9wSFZHcyhnZW5lX3ZhcmlhbmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuID0gbnVtX2dlbmVzKQpgYGAKClRvIGNhbGN1bGF0ZSB0aGUgUENBIG1hdHJpeCBpdHNlbGYsIHdlJ2xsIHVzZSBhbiBhcHByb2FjaCBmcm9tIHRoZSBgYmF0Y2hlbG9yYCBwYWNrYWdlLCB3aGljaCBpcyB0aGUgUiBwYWNrYWdlIHRoYXQgY29udGFpbnMgdGhlIGBmYXN0TU5OYCBtZXRob2QuClRoZSBbYGJhdGNoZWxvcjo6bXVsdGlCYXRjaFBDQSgpYF0oaHR0cHM6Ly9yZHJyLmlvL2Jpb2MvYmF0Y2hlbG9yL21hbi9tdWx0aUJhdGNoUENBLmh0bWwpIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgYSBiYXRjaC13ZWlnaHRlZCBQQ0EgbWF0cml4LgpUaGlzIHdlaWdodGluZyBlbnN1cmVzIHRoYXQgYWxsIGJhdGNoZXMsIHdoaWNoIG1heSBoYXZlIHZlcnkgZGlmZmVyZW50IG51bWJlcnMgb2YgY2VsbHMsIGNvbnRyaWJ1dGUgZXF1YWxseSB0byB0aGUgb3ZlcmFsbCBzY2FsaW5nLgoKYGBge3IgbWFrZSBtZXJnZWRfcGNhLCBsaXZlID0gVFJVRX0KIyBVc2UgYmF0Y2hlbG9yIHRvIGNhbGN1bGF0ZSBQQ0EgZm9yIG1lcmdlZF9zY2UsIGNvbnNpZGVyaW5nIG9ubHkKIyAgdGhlIGhpZ2gtdmFyaWFuY2UgZ2VuZXMKIyBXZSdsbCBuZWVkIHRvIGluY2x1ZGUgdGhlIGFyZ3VtZW50IGBwcmVzZXJ2ZS5zaW5nbGUgPSBUUlVFYCB0byBnZXQKIyAgYSBzaW5nbGUgbWF0cml4IHdpdGggYWxsIHNhbXBsZXMgYW5kIG5vdCBzZXBhcmF0ZSBtYXRyaWNlcyBmb3IgZWFjaCBzYW1wbGUKbWVyZ2VkX3BjYSA8LSBiYXRjaGVsb3I6Om11bHRpQmF0Y2hQQ0EobWVyZ2VkX3NjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2V0LnJvdyA9IGh2X2dlbmVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXRjaCA9IG1lcmdlZF9zY2Ukc2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVzZXJ2ZS5zaW5nbGUgPSBUUlVFKQpgYGAKCkxldCdzIGhhdmUgYSBsb29rIGF0IHRoZSBvdXRwdXQ6CmBgYHtyIHByaW50IG1lcmdlZF9wY2EsIGxpdmUgPSBUUlVFfQojIFRoaXMgb3V0cHV0IGlzIG5vdCB2ZXJ5IGludGVyZXN0aW5nIQptZXJnZWRfcGNhCmBgYAoKV2UgY2FuIHVzZSBpbmRleGluZyBgW1sxXV1gIHRvIHNlZSB0aGUgUENBIG1hdHJpeCBjYWxjdWxhdGVkLCBsb29raW5nIGF0IGEgc21hbGwgc3Vic2V0IGZvciBjb252ZW5pZW5jZToKCmBgYHtyIHByaW50IG1lcmdlZF9wY2EgaW5kZXhlZCwgbGl2ZSA9IFRSVUV9Cm1lcmdlZF9wY2FbWzFdXVsxOjUsMTo1XQpgYGAKCldlIGNhbiBub3cgaW5jbHVkZSB0aGlzIFBDQSBtYXRyaXggaW4gb3VyIGBtZXJnZWRfc2NlYCBvYmplY3Q6CgpgYGB7ciBhZGQgbWVyZ2VkX3BjYSwgbGl2ZSA9IFRSVUV9CiMgYWRkIFBDQSByZXN1bHRzIHRvIG1lcmdlZCBTQ0Ugb2JqZWN0CnJlZHVjZWREaW0obWVyZ2VkX3NjZSwgIm1lcmdlZF9QQ0EiKSA8LSBtZXJnZWRfcGNhW1sxXV0KYGBgCgpOb3cgdGhhdCB3ZSBoYXZlIHRoZSBQQ0EgbWF0cml4LCB3ZSBjYW4gcHJvY2VlZCB0byBjYWxjdWxhdGUgVU1BUCB0byB2aXN1YWxpemUgdGhlIHVuY29ycmVjdGVkIG1lcmdlZCBkYXRhLgoKV2UnbGwgY2FsY3VsYXRlIFVNQVAgYXMgInVzdWFsIiwgYnV0IGluIHRoaXMgY2FzZSB3ZSdsbCBzcGVjaWZ5IHR3byBhZGRpdGlvbmFsIGFyZ3VtZW50czoKCi0gYGRpbXJlZCA9ICJtZXJnZWRfUENBImAsIHdoaWNoIHNwZWNpZmllcyB3aGljaCBleGlzdGluZyByZWR1Y2VkIGRpbWVuc2lvbiBzaG91bGQgYmUgdXNlZCBmb3IgdGhlIGNhbGN1bGF0aW9uLgpXZSB3YW50IHRvIHVzZSB0aGUgYmF0Y2gtd2VpZ2h0ZWQgUENBLCB3aGljaCB3ZSBuYW1lZCBhYm92ZSBhcyBgIm1lcmdlZF9QQ0EiYC4KLSBgbmFtZSA9ICJtZXJnZWRfVU1BUCJgLCB3aGljaCBuYW1lcyB0aGUgZmluYWwgVU1BUCB0aGF0IHRoaXMgZnVuY3Rpb24gY2FsY3VsYXRlcy4KVGhpcyBhcmd1bWVudCB3aWxsIHByZXZlbnQgdXMgZnJvbSBvdmVyd3JpdGluZyB0aGUgZXhpc3RpbmcgVU1BUCB3aGljaCBpcyBhbHJlYWR5IG5hbWVkICJVTUFQIiBhbmQgaW5zdGVhZCBjcmVhdGUgYSBzZXBhcmF0ZSBgIm1lcmdlZF9VTUFQImAuCgpgYGB7ciBjYWxjdWxhdGUgbWVyZ2VkIHVtYXAsIGxpdmUgPSBUUlVFfQojIGFkZCBtZXJnZWRfVU1BUCBmcm9tIG1lcmdlZF9QQ0EKbWVyZ2VkX3NjZSA8LSBzY2F0ZXI6OnJ1blVNQVAobWVyZ2VkX3NjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltcmVkID0gIm1lcmdlZF9QQ0EiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gIm1lcmdlZF9VTUFQIikKYGBgCgpOb3csIGxldCdzIHNlZSBob3cgdGhpcyBuZXcgYG1lcmdlZF9VTUFQYCBsb29rcyBjb21wYXJlZCB0byB0aGUgYFVNQVBgIGNhbGN1bGF0ZWQgZnJvbSBpbmRpdmlkdWFsIHNhbXBsZXM6CgpgYGB7ciBwbG90IHVuY29ycmVjdGVkIG1lcmdlZCBVTUFQfQojIFVNQVBzIHNjYWxlZCB0b2dldGhlciB3aGVuIGNhbGN1bGF0ZWQgZnJvbSB0aGUgbWVyZ2VkIFNDRQpzY2F0ZXI6OnBsb3RSZWR1Y2VkRGltKG1lcmdlZF9zY2UsCiAgICAgICAgICAgICAgICAgICAgICAgZGltcmVkID0gIm1lcmdlZF9VTUFQIiwKICAgICAgICAgICAgICAgICAgICAgICBjb2xvcl9ieSA9ICJzYW1wbGUiLAogICAgICAgICAgICAgICAgICAgICAgICMgU29tZSBzdHlsaW5nIHRvIGhlbHAgdXMgc2VlIHRoZSBwb2ludHM6CiAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRfc2l6ZSA9IDAuNSwKICAgICAgICAgICAgICAgICAgICAgICBwb2ludF9hbHBoYSA9IDAuMikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIiwgbmFtZSA9ICJzYW1wbGUiKSArCiAgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMsIGFscGhhID0gMSkpKSArCiAgZ2d0aXRsZSgiVU1BUCBjYWxjdWxhdGVkIG9uIG1lcmdlZF9zY2UiKQpgYGAKClNhbXBsZXMgYXJlIG5vdyBzZXBhcmF0ZWQsIHdoaWNoIG1vcmUgcmVhc29uYWJseSByZWZsZWN0cyB0aGF0IHRoaXMgZGF0YSBpcyBfbm90IHlldCBiYXRjaC1jb3JyZWN0ZWRfLgpXZSBjYW4gdGhpbmsgb2YgdGhpcyBVTUFQIGFzIG91ciAiYmVmb3JlIiBVTUFQLCBhbmQgd2UgY2FuIGNvbXBhcmUgdGhpcyB0byB0aGUgImFmdGVyIiBVTUFQIHdlIHNlZSBwb3N0LWludGVncmF0aW9uLgoKTGV0J3MgZGlzY3VzcyBhIGxpdHRsZSBmaXJzdDogV2hhdCB2aXN1YWwgZGlmZmVyZW5jZXMgZG8geW91IHRoaW5rIHRoZSBVTUFQIG9uIHRoZSBpbnRlZ3JhdGVkIHZlcnNpb24gb2YgZGF0YSB3aWxsIGhhdmU/CldoYXQgc2ltaWxhcml0aWVzIGRvIHlvdSB0aGluayB0aGUgaW50ZWdyYXRlZCBVTUFQIHdpbGwgaGF2ZSB0byB0aGlzIHBsb3Q/CgoKIyMjIEludGVncmF0aW9uIHdpdGggYGZhc3RNTk5gCgpGaW5hbGx5LCB3ZSdyZSByZWFkeSB0byBpbnRlZ3JhdGUhClRvIHN0YXJ0LCB3ZSdsbCB1c2UgdGhlIGBmYXN0TU5OYCBhcHByb2FjaCBmcm9tIHRoZSBCaW9jb25kdWN0b3IgW2BiYXRjaGVsb3JgIHBhY2thZ2VdKGh0dHA6Ly93d3cuYmlvY29uZHVjdG9yLm9yZy9wYWNrYWdlcy8zLjE2L2Jpb2MvaHRtbC9iYXRjaGVsb3IuaHRtbCkuCgpgZmFzdE1OTmAgdGFrZXMgYXMgaW5wdXQgdGhlIGBtZXJnZWRfc2NlYCBvYmplY3QgdG8gaW50ZWdyYXRlLCBhbmQgdGhlIGZpcnN0IHN0ZXAgaXQgcGVyZm9ybXMgaXMgYWN0dWFsbHkgdG8gcnVuIGBiYXRjaGVsb3I6Om11bHRpQmF0Y2hQQ0EoKWAgb24gdGhhdCBTQ0UuCkl0IHRoZW4gdXNlcyB0aGF0IGJhdGNoLXdlaWdodGVkIFBDQSBtYXRyaXggdG8gcGVyZm9ybSB0aGUgYWN0dWFsIGJhdGNoIGNvcnJlY3Rpb24uClRoZSBgYmF0Y2hgIGFyZ3VtZW50IGlzIHVzZWQgdG8gc3BlY2lmeSB0aGUgZGlmZmVyZW50IGdyb3VwaW5ncyB3aXRoaW4gdGhlIGBtZXJnZWRfc2NlYCAoaS5lLiB0aGUgb3JpZ2luYWwgc2FtcGxlIHRoYXQgZWFjaCBjZWxsIGJlbG9uZ3MgdG8pLCBhbmQgdGhlIGBzdWJzZXQucm93YCBhcmd1bWVudCBjYW4gb3B0aW9uYWxseSBiZSB1c2VkIHRvIHByb3ZpZGUgYSB2ZWN0b3Igb2YgaGlnaC12YXJpYW5jZSBnZW5lcyB0aGF0IHNob3VsZCBiZSBjb25zaWRlcmVkIGZvciB0aGlzIFBDQSBjYWxjdWxhdGlvbi4KYGZhc3RNTk5gIHdpbGwgcmV0dXJuIGFuIFNDRSBvYmplY3QgdGhhdCBjb250YWlucyBhIGJhdGNoLWNvcnJlY3RlZCBQQ0EuCkxldCdzIHJ1biBpdCBhbmQgc2F2ZSB0aGUgcmVzdWx0IHRvIGEgdmFyaWFibGUgY2FsbGVkIGBpbnRlZ3JhdGVkX3NjZWAuCgoKYGBge3IgcnVuIGZhc3Rtbm4sIGxpdmUgPSBUUlVFfQojIGludGVncmF0ZSB3aXRoIGZhc3RNTk4sIGFnYWluIHNwZWNpZnlpbmcgb25seSBvdXIgaGlnaC12YXJpYW5jZSBnZW5lcwppbnRlZ3JhdGVkX3NjZSA8LSBiYXRjaGVsb3I6OmZhc3RNTk4oCiAgbWVyZ2VkX3NjZSwKICBiYXRjaCA9IG1lcmdlZF9zY2Ukc2FtcGxlLAogIHN1YnNldC5yb3cgPSBodl9nZW5lcwopCmBgYAoKTGV0J3MgaGF2ZSBhIGxvb2sgYXQgdGhlIHJlc3VsdDoKCmBgYHtyIGZhc3Rtbm4gcmVzdWx0LCBsaXZlID0gVFJVRX0KIyBQcmludCB0aGUgaW50ZWdyYXRlZF9zY2Ugb2JqZWN0CmludGVncmF0ZWRfc2NlCmBgYAoKVGhlcmUgYXJlIGNvdXBsZSBwaWVjZXMgb2YgaW5mb3JtYXRpb24gaGVyZSBvZiBpbnRlcmVzdDoKCi0gVGhlIGBjb3JyZWN0ZWRgIHJlZHVjZWQgZGltZW5zaW9uIHJlcHJlc2VudHMgdGhlIGJhdGNoLWNvcnJlY3RlZCBQQ0EgdGhhdCBgZmFzdE1OTmAgY2FsY3VsYXRlZC4KLSBUaGUgYHJlY29uc3RydWN0ZWRgIGFzc2F5IHJlcHJlc2VudHMgdGhlIGJhdGNoLWNvcnJlY3RlZCBub3JtYWxpemVkIGV4cHJlc3Npb24gdmFsdWVzLCB3aGljaCBgZmFzdE1OTmAgImJhY2stY2FsY3VsYXRlZCIgZnJvbSB0aGUgYmF0Y2gtY29ycmVjdGVkIFBDQSAoYGNvcnJlY3RlZGApLgpHZW5lcmFsbHkgc3BlYWtpbmcsIHRoZXNlIGV4cHJlc3Npb24gdmFsdWVzIGFyZSBub3Qgc3RhbmQtYWxvbmUgdmFsdWVzIHRoYXQgeW91IHNob3VsZCB1c2UgZm9yIG90aGVyIGFwcGxpY2F0aW9ucyBsaWtlIGRpZmZlcmVudGlhbCBnZW5lIGV4cHJlc3Npb24sIGFzIGRlc2NyaWJlZCBpbiBbX09yY2hlc3RyYXRpbmcgU2luZ2xlIENlbGwgQW5hbHlzZXNfXShodHRwOi8vYmlvY29uZHVjdG9yLm9yZy9ib29rcy8zLjE2L09TQ0EubXVsdGlzYW1wbGUvdXNpbmctY29ycmVjdGVkLXZhbHVlcy5odG1sKS4KSWYgdGhlIGBzdWJzZXQucm93YCBhcmd1bWVudCBpcyBwcm92aWRlZCAoYXMgaXQgd2FzIGhlcmUpLCBvbmx5IGdlbmVzIHByZXNlbnQgaW4gYHN1YnNldC5yb3dgIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlc2UgcmVjb25zdHJ1Y3RlZCBleHByZXNzaW9uIHZhbHVlcywgYnV0IHRoaXMgc2V0dGluZyBjYW4gYmUgb3ZlcnJpZGRlbiBzbyB0aGF0IGFsbCBnZW5lcyBoYXZlIHJlY29uc3RydWN0ZWQgZXhwcmVzc2lvbiB3aXRoIHRoZSBhcmd1bWVudCBgY29ycmVjdC5hbGwgPSBUUlVFYC4KCldlJ3JlIG1vc3RseSBpbnRlcmVzdGVkIGluIHRoZSBQQ0EgdGhhdCBgZmFzdE1OTmAgY2FsY3VsYXRlZCwgc28gbGV0J3Mgc2F2ZSB0aGF0IGluZm9ybWF0aW9uICh3aXRoIGFuIGluZm9ybWF0aXZlIGFuZCB1bmlxdWUgbmFtZSkgaW50byBvdXIgYG1lcmdlZF9zY2VgIG9iamVjdDoKCmBgYHtyIGZhc3Rtbm4gcGNzLCBsaXZlID0gVFJVRX0KIyBNYWtlIGEgbmV3IHJlZHVjZWREaW0gbmFtZWQgZmFzdG1ubl9QQ0EgZnJvbSB0aGUgY29ycmVjdGVkIHJlZHVjZWREaW0gaW4gaW50ZWdyYXRlZF9zY2UKcmVkdWNlZERpbShtZXJnZWRfc2NlLCAiZmFzdG1ubl9QQ0EiKSA8LSByZWR1Y2VkRGltKGludGVncmF0ZWRfc2NlLCAiY29ycmVjdGVkIikKYGBgCgpGaW5hbGx5LCB3ZSdsbCBjYWxjdWxhdGUgVU1BUCBmcm9tIHRoZXNlIGNvcnJlY3RlZCBQQ0EgbWF0cml4IGZvciB2aXN1YWxpemF0aW9uLgoKYGBge3IgY2FsY3VsYXRlIGZhc3Rtbm4gdW1hcCwgbGl2ZSA9IFRSVUV9CiMgQ2FsY3VsYXRlIFVNQVAKbWVyZ2VkX3NjZSA8LSBzY2F0ZXI6OnJ1blVNQVAoCiAgbWVyZ2VkX3NjZSwKICBkaW1yZWQgPSAiZmFzdG1ubl9QQ0EiLAogIG5hbWUgPSAiZmFzdG1ubl9VTUFQIgopCmBgYAoKRmlyc3QsIGxldCdzIHBsb3QgdGhlIGludGVncmF0ZWQgVU1BUCBoaWdobGlnaHRpbmcgdGhlIGRpZmZlcmVudCBiYXRjaGVzLgpBIHdlbGwtaW50ZWdyYXRlZCBkYXRhc2V0IHdpbGwgc2hvdyBiYXRjaCBtaXhpbmcsIGJ1dCBhIHBvb3JseS1pbnRlZ3JhdGVkIGRhdGFzZXQgd2lsbCBzaG93IG1vcmUgc2VwYXJhdGlvbiBhbW9uZyBiYXRjaGVzLCBzaW1pbGFyIHRvIHRoZSB1bmNvcnJlY3RlZCBVTUFQLgpOb3RlIHRoYXQgdGhpcyBpcyBhIG1vcmUgcXVhbGl0YXRpdmUgd2F5IHRvIGFzc2VzcyB0aGUgc3VjY2VzcyBvZiBpbnRlZ3JhdGlvbiwgYnV0IHRoZXJlIGFyZSBmb3JtYWwgbWV0cmljcyBvbmUgY2FuIHVzZSB0byBhc3Nlc3MgYmF0Y2ggbWl4aW5nLCB3aGljaCB5b3UgY2FuIHJlYWQgbW9yZSBhYm91dCBpbiBbdGhpcyBjaGFwdGVyIG9mIE9TQ0FdKGh0dHA6Ly9iaW9jb25kdWN0b3Iub3JnL2Jvb2tzLzMuMTYvT1NDQS5tdWx0aXNhbXBsZS9jb3JyZWN0aW9uLWRpYWdub3N0aWNzLmh0bWwpLgoKYGBge3IgcGxvdCBmYXN0bW5uIHVtYXAgYmF0Y2hlc30Kc2NhdGVyOjpwbG90UmVkdWNlZERpbShtZXJnZWRfc2NlLAogICAgICAgICAgICAgICAgICAgICAgICMgcGxvdCB0aGUgZmFzdE1OTiBjb29yZGluYXRlcwogICAgICAgICAgICAgICAgICAgICAgIGRpbXJlZCA9ICJmYXN0bW5uX1VNQVAiLAogICAgICAgICAgICAgICAgICAgICAgICMgY29sb3IgYnkgc2FtcGxlCiAgICAgICAgICAgICAgICAgICAgICAgY29sb3JfYnkgPSAic2FtcGxlIiwKICAgICAgICAgICAgICAgICAgICAgICAjIFNvbWUgc3R5bGluZyB0byBoZWxwIHVzIHNlZSB0aGUgcG9pbnRzOgogICAgICAgICAgICAgICAgICAgICAgIHBvaW50X3NpemUgPSAwLjUsCiAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRfYWxwaGEgPSAwLjIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIsIG5hbWUgPSAic2FtcGxlIikgKwogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzLCBhbHBoYSA9IDEpKSkgKwogIGdndGl0bGUoIlVNQVAgYWZ0ZXIgaW50ZWdyYXRpb24gd2l0aCBmYXN0TU5OIikKYGBgCgpUaGlzIGBmYXN0bW5uX1VNQVBgIGNlcnRhaW5seSBsb29rcyBkaWZmZXJlbnQgZnJvbSB0aGUgb25lIHdlIG1hZGUgZnJvbSBgbWVyZ2VkX1VNQVBgIQpXaGF0IGRpZmZlcmVudCB0cmVuZHMgZG8geW91IHNlZT8KRG8gYWxsIHNhbXBsZXMgbG9vayAiZXF1YWxseSB3ZWxsIiBpbnRlZ3JhdGVkLCBmcm9tIGEgZmlyc3QgbG9vaz8KCkltcG9ydGFudGx5LCBvbmUgcmVhc29uIHRoYXQgYmF0Y2hlcyBtYXkgc3RpbGwgYXBwZWFyIHNlcGFyYXRlZCBpbiB0aGUgY29ycmVjdGVkIFVNQVAgaXMgaWYgdGhleSBfc2hvdWxkXyBiZSBzZXBhcmF0ZWQgLSBmb3IgZXhhbXBsZSwgbWF5YmUgdHdvIGJhdGNoZXMgY29udGFpbiB2ZXJ5IGRpZmZlcmVudCBjZWxsIHR5cGVzLCBoYXZlIHZlcnkgZGlmZmVyZW50IGRpYWdub3Nlcywgb3IgbWF5IGJlIGZyb20gZGlmZmVyZW50IHBhdGllbnRzLgoKUmVjYWxsIGZyb20gZWFybGllciB0aGF0IHdlIGNvbnZlbmllbnRseSBoYXZlIGNlbGwgdHlwZSBhbm5vdGF0aW9ucyBpbiBvdXIgU0NFcywgc28gd2UgY2FuIGV4cGxvcmUgdGhvc2UgaGVyZSEKTGV0J3MgdGFrZSBhIHF1aWNrIGRldG91ciB0byBzZWUgd2hhdCBraW5kcyBvZiBjZWxsIHR5cGVzIGFyZSBpbiB0aGlzIGRhdGEgYnkgbWFraW5nIGEgYmFycGxvdCBvZiB0aGUgY2VsbCB0eXBlcyBhY3Jvc3Mgc2FtcGxlczoKCmBgYHtyIGV4cGxvcmUgY2VsbHR5cGVzfQojIENlbGwgdHlwZXMgYXJlIGluIHRoZSBgY2VsbHR5cGVfYnJvYWRgIGFuZCBgY2VsbHR5cGVfZmluZWAgY29sdW1ucwptZXJnZWRfc2NlX2RmIDwtIGFzLmRhdGEuZnJhbWUoY29sRGF0YShtZXJnZWRfc2NlKSkKCiMgVXNlIGdncGxvdDIgdG8gbWFrZSBhIGJhcnBsb3QgdGhlIGNlbGwgdHlwZXMgYWNyb3NzIHNhbXBsZXMKZ2dwbG90KG1lcmdlZF9zY2VfZGYsCiAgICAgICBhZXMoeCA9IHNhbXBsZSwKICAgICAgICAgICBmaWxsID0gY2VsbHR5cGVfYnJvYWQpKSArCiAgIyBCYXJwbG90IG9mIGNlbGx0eXBlIHByb3BvcnRpb25zCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsKICAjIFVzZSBhIENWRC1mcmllbmRseSBjb2xvciBzY2hlbWUKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIiwgbmEudmFsdWUgPSAiZ3JleTgwIikgKwogICMgbmljZXIgdGhlbWUKICB0aGVtZV9idygpCmBgYAoKV2Ugc2VlIHRoYXQgVHVtb3IgY2VsbCB0eXBlcyBhcmUgYnkgZmFyIHRoZSBtb3N0IHByZXZhbGVudCBhY3Jvc3MgYWxsIHNhbXBsZXMsIGFuZCBub3JtYWwgdGlzc3VlIGNlbGwgdHlwZXMgYXJlIG5vdCB2ZXJ5IGNvbW1vbi4KV2Ugc2VlIGFsc28gdGhhdCBgU0NQQ0wwMDA0ODFgIGhhcyBhIGxhcmdlciBgVHVtb3JfTXlvY3l0ZWAgcG9wdWxhdGlvbiwgd2hpbGUgYWxsIG90aGVyIHNhbXBsZXMgaGF2ZSBsYXJnZXIgYFR1bW9yX01lc29kZXJtYCBwb3B1bGF0aW9ucy4KVGhpcyBkaWZmZXJlbmNlIF9tYXlfIGV4cGxhaW4gd2h5IHdlIG9ic2VydmUgdGhhdCBgU0NQQ0wwMDA0ODFgIGlzIHNvbWV3aGF0IG1vcmUgc2VwYXJhdGVkIGZyb20gdGhlIG90aGVyIHNhbXBsZXMgaW4gdGhlIGBmYXN0TU5OYCBVTUFQLgoKTGV0J3MgcmUtcGxvdCB0aGlzIFVNQVAgdG8gaGlnaGxpZ2h0IGNlbGwgdHlwZXM6CgoKYGBge3IgcGxvdCBmYXN0bW5uIHVtYXAgY2VsbHR5cGVzfQpzY2F0ZXI6OnBsb3RSZWR1Y2VkRGltKG1lcmdlZF9zY2UsCiAgICAgICAgICAgICAgICAgICAgICAgZGltcmVkID0gImZhc3Rtbm5fVU1BUCIsCiAgICAgICAgICAgICAgICAgICAgICAgIyBjb2xvciBieSBicm9hZCBjZWxsdHlwZXMKICAgICAgICAgICAgICAgICAgICAgICBjb2xvcl9ieSA9ICJjZWxsdHlwZV9icm9hZCIsCiAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRfc2l6ZSA9IDAuNSwKICAgICAgICAgICAgICAgICAgICAgICBwb2ludF9hbHBoYSA9IDAuMikgKwogICMgaW5jbHVkZSBhcmd1bWVudCB0byBzcGVjaWZ5IGNvbG9yIG9mIE5BIHZhbHVlcwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIiwgbmFtZSA9ICJCcm9hZCBjZWxsdHlwZSIsIG5hLnZhbHVlID0gImdyZXk4MCIpICsKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gMywgYWxwaGEgPSAxKSkpICsKICBnZ3RpdGxlKCJVTUFQIGFmdGVyIGludGVncmF0aW9uIHdpdGggZmFzdE1OTiIpCmBgYAoKVGhpcyBVTUFQIHNob3dzIHRoYXQgdGhlIG5vcm1hbCB0aXNzdWUgY2VsbCB0eXBlcyAobW9zdGx5IHZhc2N1bGFyIGVuZG90aGVsaXVtLCBtdXNjbGUgY2VsbHMsIGFuZCBtb25vY3l0ZXMpIHRlbmQgdG8gY2x1c3RlciB0b2dldGhlciBhbmQgYXJlIGdlbmVyYWxseSBzZXBhcmF0ZWQgZnJvbSB0aGUgdHVtb3IgY2VsbCB0eXBlcywgd2hpY2ggaXMgYW4gZW5jb3VyYWdpbmcgcGF0dGVybiEKVHVtb3IgY2VsbCB0eXBlcyBmcm9tIGRpZmZlcmVudCBzYW1wbGVzIGFyZSBhbGwgYWxzbyBjbHVzdGVyaW5nIHRvZ2V0aGVyLCB3aGljaCBpcyBldmVuIG1vcmUgZW5jb3VyYWdpbmcgdGhhdCB3ZSBoYWQgc3VjY2Vzc2Z1bCBpbnRlZ3JhdGlvbi4KCkhvd2V2ZXIsIGl0J3MgYSBiaXQgY2hhbGxlbmdpbmcgdG8gc2VlIGFsbCB0aGUgcG9pbnRzIGdpdmVuIHRoZSBhbW91bnQgb2Ygb3ZlcmxhcCBpbiB0aGUgcGxvdC4KT25lIHdheSB3ZSBjYW4gc2VlIGFsbCB0aGUgcG9pbnRzIGEgYml0IGJldHRlciBpcyB0byBmYWNldCB0aGUgcGxvdCBieSBzYW1wbGUsIHVzaW5nIGBmYWNldF93cmFwKClgIGZyb20gdGhlIGBnZ3Bsb3QyYCBwYWNrYWdlICh3aGljaCB3ZSBjYW4gZG8gYmVjYXVzZSBgc2NhdGVyOjpwbG90UmVkdWNlZERpbSgpYCByZXR1cm5zIGEgYGdncGxvdDJgIG9iamVjdCk6CgpgYGB7ciBwbG90IGZhc3Rtbm4gdW1hcCBjZWxsdHlwZXMgZmFjZXRlZH0Kc2NhdGVyOjpwbG90UmVkdWNlZERpbShtZXJnZWRfc2NlLAogICAgICAgICAgICAgICAgICAgICAgIGRpbXJlZCA9ICJmYXN0bW5uX1VNQVAiLAogICAgICAgICAgICAgICAgICAgICAgIGNvbG9yX2J5ID0gImNlbGx0eXBlX2Jyb2FkIiwKICAgICAgICAgICAgICAgICAgICAgICBwb2ludF9zaXplID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgIHBvaW50X2FscGhhID0gMC4yLAogICAgICAgICAgICAgICAgICAgICAgICMgQWxsb3cgZm9yIGZhY2V0aW5nIGJ5IGEgdmFyaWFibGUgdXNpbmcgYG90aGVyX2ZpZWxkc2A6CiAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJfZmllbGRzID0gInNhbXBsZSIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIsIG5hbWUgPSAiQnJvYWQgY2VsbHR5cGUiLCBuYS52YWx1ZSA9ICJncmV5ODAiKSArCiAgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMsIGFscGhhID0gMSkpKSArCiAgZ2d0aXRsZSgiVU1BUCBhZnRlciBpbnRlZ3JhdGlvbiB3aXRoIGZhc3RNTk4iKSArCiAgIyBGYWNldCBieSBzYW1wbGUKICBmYWNldF93cmFwKHZhcnMoc2FtcGxlKSkgKwogICMgVXNlIGEgdGhlbWUgd2l0aCBiYWNrZ3JvdW5kIGdyaWQgdG8gbW9yZSBlYXNpbHkgY29tcGFyZSBwYW5lbCBjb29yZGluYXRlcwogIHRoZW1lX2J3KCkKYGBgCgpXaGF0IHRyZW5kcyBkbyB5b3Ugb2JzZXJ2ZSBiZXR3ZWVuIHR1bW9yIGFuZCBoZWFsdGh5IHRpc3N1ZXMgYW1vbmcgdGhlc2UgaW50ZWdyYXRlZCBzYW1wbGVzPwoKCiMjIyBJbnRlZ3JhdGlvbiB3aXRoIGBoYXJtb255YAoKYGZhc3RNTk5gIGlzIG9ubHkgb25lIG9mIG1hbnkgYXBwcm9hY2hlcyB0byBwZXJmb3JtIGludGVncmF0aW9uLCBhbmQgZGlmZmVyZW50IG1ldGhvZHMgaGF2ZSBkaWZmZXJlbnQgY2FwYWJpbGl0aWVzIGFuZCBtYXkgZ2l2ZSBkaWZmZXJlbnQgcmVzdWx0cy4KRm9yIGV4YW1wbGUsIHNvbWUgbWV0aG9kcyBjYW4gYWNjb21tb2RhdGUgYWRkaXRpb25hbCBjb3ZhcmlhdGVzIChlLmcuLCB0ZWNobm9sb2d5LCBwYXRpZW50LCBkaWFnbm9zaXMsIGV0Yy4pIHRoYXQgY2FuIGluZmx1ZW5jZSBpbnRlZ3JhdGlvbi4KSW4gZmFjdCB0aGUgZGF0YSB3ZSBhcmUgdXNpbmcgaGFzIGEga25vd24gX3BhdGllbnRfIGNvdmFyaWF0ZTsgYFNDUENMMDAwNDc5YCBhbmQgYFNDUENMMDAwNDgwYCBhcmUgZnJvbSB0aGUgZmlyc3QgcGF0aWVudCwgYW5kIGBTQ1BDTDAwMDQ4MWAgYW5kIGBTQ1BDTDAwMDQ4MmAgYXJlIGZyb20gdGhlIHNlY29uZCBwYXRpZW50LgoKU28sIGxldCdzIHBlcmZvcm0gaW50ZWdyYXRpb24gd2l0aCBhIG1ldGhvZCB0aGF0IGNhbiB1c2UgdGhpcyBpbmZvcm1hdGlvbiAtIFtgaGFybW9ueWBdKGh0dHBzOi8vcG9ydGFscy5icm9hZGluc3RpdHV0ZS5vcmcvaGFybW9ueS8pIQoKVG8gYmVnaW4gc2V0dGluZyB1cCBmb3IgYGhhcm1vbnlgIGludGVncmF0aW9uLCB3ZSBuZWVkIHRvIGFkZCBleHBsaWNpdCBwYXRpZW50IGluZm9ybWF0aW9uIGludG8gb3VyIG1lcmdlZCBTQ0UuCldlJ2xsIGNyZWF0ZSBhIG5ldyBjb2x1bW4gYHBhdGllbnRgIHdob3NlIHZhbHVlIGlzIGVpdGhlciAiQSIgb3IgIkIiIGRlcGVuZGluZyBvbiB0aGUgZ2l2ZW4gc2FtcGxlIG5hbWUsIHVzaW5nIHRoZSBbYGRwbHlyOjpjYXNlX3doZW4oKWBdKGh0dHBzOi8vZHBseXIudGlkeXZlcnNlLm9yZy9yZWZlcmVuY2UvY2FzZV93aGVuLmh0bWwpIGZ1bmN0aW9uLgpXZSBwcm92aWRlIHRoaXMgZnVuY3Rpb24gd2l0aCBhIHNldCBvZiBsb2dpY2FsIGV4cHJlc3Npb25zIGFuZCBlYWNoIGFzc2lnbmVkIHZhbHVlIGlzIGRlc2lnbmF0ZWQgYnkgYH5gLgpUaGUgZXhwcmVzc2lvbnMgYXJlIGV2YWx1YXRlZCBpbiBvcmRlciwgc3RvcHBpbmcgYXQgdGhlIF9maXJzdF8gb25lIHRoYXQgZXZhbHVhdGVzIGFzIGBUUlVFYCBhbmQgcmV0dXJuaW5nIHRoZSBhc3NvY2lhdGVkIHZhbHVlLgoKYGBge3IgYWRkIHBhdGllbnQgaW5mb30KIyBDcmVhdGUgcGF0aWVudCBjb2x1bW4gd2l0aCB2YWx1ZXMgIkEiIG9yICJCIiBmb3IgdGhlIHR3byBwYXRpZW50cwptZXJnZWRfc2NlJHBhdGllbnQgPC0gZHBseXI6OmNhc2Vfd2hlbigKICBtZXJnZWRfc2NlJHNhbXBsZSAlaW4lIGMoIlNDUENMMDAwNDc5IiwgIlNDUENMMDAwNDgwIikgfiAiQSIsCiAgbWVyZ2VkX3NjZSRzYW1wbGUgJWluJSBjKCJTQ1BDTDAwMDQ4MSIsICJTQ1BDTDAwMDQ4MiIpIH4gIkIiLAopCmBgYAoKClVubGlrZSBgZmFzdE1OTmAsIGBoYXJtb255YCBkb2VzIG5vdCBjYWxjdWxhdGUgY29ycmVjdGVkIGV4cHJlc3Npb24gdmFsdWVzIG5vciBkb2VzIGl0IHJldHVybiBhbiBTQ0Ugb2JqZWN0LgpMaWtlIGBmYXN0TU5OYCwgYGhhcm1vbnlgIHBlcmZvcm1zIGludGVncmF0aW9uIG9uIGEgbWVyZ2VkIFBDQSBtYXRyaXguCkhvd2V2ZXIsIHVubGlrZSBgZmFzdE1OTmAsIGBoYXJtb255YCBkb2VzIG5vdCAiYmFjay1jYWxjdWxhdGUiIGNvcnJlY3RlZCBleHByZXNzaW9uIGZyb20gdGhlIGNvcnJlY3RlZCBQQ0EgbWF0cml4IGFuZCBpdCBvbmx5IHJldHVybnMgdGhlIGNvcnJlY3RlZCBQQ0EgbWF0cml4IGl0c2VsZi4KRm9yIGlucHV0LCBgaGFybW9ueWAgbmVlZHMgYSBjb3VwbGUgcGllY2VzIG9mIGluZm9ybWF0aW9uOgoKLSBGaXJzdCwgYGhhcm1vbnlgIHRha2VzIGEgYmF0Y2gtd2VpZ2h0ZWQgUENBIG1hdHJpeCB0byBwZXJmb3JtIGludGVncmF0aW9uLgpXZSBhbHJlYWR5IGNhbGN1bGF0ZWQgYSBiYXRjaC13ZWlnaHRlZCBQQ0EgbWF0cml4IChvdXIgYG1lcmdlZF9QQ0FgIHJlZHVjZWQgZGltZW5zaW9uKSwgd2UnbGwgcHJvdmlkZSB0aGlzIGFzIHRoZSB0aGUgaW5wdXQuCi0gU2Vjb25kLCB3ZSBuZWVkIHRvIHRlbGwgYGhhcm1vbnlgIGFib3V0IHRoZSBjb3ZhcmlhdGVzIHRvIHVzZSAtIGBzYW1wbGVgIGFuZCBgcGF0aWVudGAuClRvIGRvIHRoaXMsIHdlIHByb3ZpZGUgdHdvIGFyZ3VtZW50czoKICAtIGBtZXRhX2RhdGFgLCBhIGRhdGEgZnJhbWUgdGhhdCBjb250YWlucyBjb3ZhcmlhdGVzIGFjcm9zcyBzYW1wbGVzLgogIFdlIGNhbiBzaW1wbHkgc3BlY2lmeSB0aGUgU0NFIGBjb2xEYXRhYCBoZXJlIHNpbmNlIGl0IGNvbnRhaW5zIGBzYW1wbGVgIGFuZCBgcGF0aWVudGAgY29sdW1ucy4KICAtIGB2YXJzX3VzZWAsIGEgdmVjdG9yIG9mIHdoaWNoIGNvbHVtbiBuYW1lcyBpbiBgbWV0YV9kYXRhYCBzaG91bGQgYWN0dWFsbHkgYmUgdXNlZCBhcyBjb3ZhcmlhdGVzLgogIE90aGVyIGNvbHVtbnMgaW4gYG1ldGFfZGF0YWAgd2hpY2ggYXJlIG5vdCBpbiBgdmFyc191c2VgIGFyZSBpZ25vcmVkLgoKTGV0J3MgZ28hCgpgYGB7ciBydW4gaGFybW9ueSwgbGl2ZSA9IFRSVUV9CiMgUnVuIGhhcm1vbnkgaW50ZWdyYXRpb24KaGFybW9ueV9wY2EgPC0gaGFybW9ueTo6UnVuSGFybW9ueSgKICBkYXRhX21hdCA9IHJlZHVjZWREaW0obWVyZ2VkX3NjZSwgIm1lcmdlZF9QQ0EiKSwKICBtZXRhX2RhdGEgPSBjb2xEYXRhKG1lcmdlZF9zY2UpLAogIHZhcnNfdXNlID0gYygic2FtcGxlIiwgInBhdGllbnQiKQopCmBgYAoKVGhlIHJlc3VsdCBpcyBhIFBDQSBtYXRyaXguCkxldCdzIHByaW50IGEgc3Vic2V0IG9mIHRoaXMgbWF0cml4IHRvIHNlZSBpdDoKCmBgYHtyIHByaW50IGhhcm1vbnkgcmVzdWx0LCBsaXZlID0gVFJVRX0KIyBQcmludCB0aGUgaGFybW9ueSByZXN1bHQKaGFybW9ueV9wY2FbMTo1LCAxOjVdCmBgYAoKQXMgd2UgZGlkIHdpdGggYGZhc3RNTk5gIHJlc3VsdHMsIGxldCdzIHN0b3JlIHRoaXMgUENBIG1hdHJpeCBkaXJlY3RseSBpbiBvdXIgYG1lcmdlZF9zY2VgIG9iamVjdCB3aXRoIGFuIGluZm9ybWF0aXZlIG5hbWUgdGhhdCB3b24ndCBvdmVyd3JpdGUgYW55IG9mIHRoZSBleGlzdGluZyBQQ0EgbWF0cmljZXMuCldlJ2xsIGFsc28gY2FsY3VsYXRlIFVNQVAgZnJvbSBpdC4KCmBgYHtyIHNhdmUgaGFybW9ueSwgbGl2ZSA9IFRSVUV9CiMgU3RvcmUgUENBIGFzIGBoYXJtb255X1BDQWAKcmVkdWNlZERpbShtZXJnZWRfc2NlLCAiaGFybW9ueV9QQ0EiKSA8LSBoYXJtb255X3BjYQoKIyBBcyBiZWZvcmUsIGNhbGN1bGF0ZSBVTUFQIG9uIHRoaXMgUENBIG1hdHJpeCB3aXRoIGFwcHJvcHJpYXRlIG5hbWVzCm1lcmdlZF9zY2UgPC0gc2NhdGVyOjpydW5VTUFQKG1lcmdlZF9zY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbXJlZCA9ICJoYXJtb255X1BDQSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgICA9ICJoYXJtb255X1VNQVAiKQpgYGAKCgpMZXQncyBzZWUgaG93IHRoZSBgaGFybW9ueWAgVU1BUCwgY29sb3JlZCBieSBzYW1wbGUsIGxvb2tzIGNvbXBhcmVkIHRvIHRoZSBgZmFzdE1OTmAgVU1BUDoKCmBgYHtyIHBsb3QgaGFybW9ueSB1bWFwIGJhdGNoZXN9CnNjYXRlcjo6cGxvdFJlZHVjZWREaW0obWVyZ2VkX3NjZSwKICAgICAgICAgICAgICAgICAgICAgICBkaW1yZWQgPSAiaGFybW9ueV9VTUFQIiwKICAgICAgICAgICAgICAgICAgICAgICBjb2xvcl9ieSA9ICJzYW1wbGUiLAogICAgICAgICAgICAgICAgICAgICAgIHBvaW50X3NpemUgPSAwLjUsCiAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRfYWxwaGEgPSAwLjIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIsIG5hbWUgPSAic2FtcGxlIikgKwogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzLCBhbHBoYSA9IDEpKSkgKwogIGdndGl0bGUoIlVNQVAgYWZ0ZXIgaW50ZWdyYXRpb24gd2l0aCBoYXJtb255IikKYGBgCgpIb3cgZG8geW91IHRoaW5rIHRoaXMgYGhhcm1vbnlgIFVNQVAgY29tcGFyZXMgdG8gdGhhdCBmcm9tIGBmYXN0TU5OYCBpbnRlZ3JhdGlvbj8KCkxldCdzIHNlZSBob3cgdGhpcyBVTUFQIGxvb2tzIGNvbG9yZWQgYnkgY2VsbCB0eXBlLCBhbmQgZmFjZXRlZCBmb3IgdmlzaWJpbGl0eToKCmBgYHtyIHBsb3QgaGFybW9ueSB1bWFwIGNlbGx0eXBlc30Kc2NhdGVyOjpwbG90UmVkdWNlZERpbShtZXJnZWRfc2NlLAogICAgICAgICAgICAgICAgICAgICAgIGRpbXJlZCA9ICJoYXJtb255X1VNQVAiLAogICAgICAgICAgICAgICAgICAgICAgIGNvbG9yX2J5ID0gImNlbGx0eXBlX2Jyb2FkIiwKICAgICAgICAgICAgICAgICAgICAgICBwb2ludF9zaXplID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgIHBvaW50X2FscGhhID0gMC4yLAogICAgICAgICAgICAgICAgICAgICAgICMgU3BlY2lmeSB2YXJpYWJsZSBmb3IgZmFjZXRpbmcKICAgICAgICAgICAgICAgICAgICAgICBvdGhlcl9maWVsZHMgPSAic2FtcGxlIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIiwgbmFtZSA9ICJCcm9hZCBjZWxsdHlwZSIsIG5hLnZhbHVlID0gImdyZXk4MCIpICsKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gMykpKSArCiAgZ2d0aXRsZSgiVU1BUCBhZnRlciBpbnRlZ3JhdGlvbiB3aXRoIGhhcm1vbnkiKSArCiAgZmFjZXRfd3JhcCh2YXJzKHNhbXBsZSkpCmBgYAoKV2hhdCBkbyB5b3Ugbm93IG5vdGljZSBpbiB0aGlzIGZhY2V0ZWQgdmlldyB0aGF0IHdhc24ndCBjbGVhciBwcmV2aW91c2x5PwpBcmUgdGhlcmUgb3RoZXIgcGF0dGVybnMgeW91IHNlZSB0aGF0IGFyZSBzaW1pbGFyIG9yIGRpZmZlcmVudCBmcm9tIHRoZSBgZmFzdE1OTmAgVU1BUD8KSG93IGRvIHlvdSB0aGluayBgZmFzdE1OTmAgdnMuIGBoYXJtb255YCBwZXJmb3JtZWQgaW4gaW50ZWdyYXRpbmcgdGhlc2Ugc2FtcGxlcz8KCiMjIyBFeHBvcnQKCkZpbmFsbHksIHdlJ2xsIGV4cG9ydCB0aGUgZmluYWwgU0NFIG9iamVjdCB3aXRoIGJvdGggYGZhc3RNTk5gIGFuZCBgaGFybW9ueWAgaW50ZWdyYXRpb24gdG8gYSBmaWxlLgpTaW5jZSB0aGlzIG9iamVjdCBpcyB2ZXJ5IGxhcmdlIChvdmVyIDEgR0IhKSwgd2UnbGwgZXhwb3J0IGl0IHRvIGEgZmlsZSB3aXRoIHNvbWUgY29tcHJlc3Npb24sIHdoaWNoLCBpbiB0aGlzIGNhc2UsIHdpbGwgcmVkdWNlIHRoZSBmaW5hbCBzaXplIHRvIGEgc21hbGxlciB+MzYwIE1CLgpUaGlzIHdpbGwgdGFrZSBhIGNvdXBsZSBtaW51dGVzIHRvIHNhdmUgd2hpbGUgY29tcHJlc3Npb24gaXMgcGVyZm9ybWVkLgoKYGBge3Igc2F2ZSBpbnRlZ3JhdGlvbiwgbGl2ZSA9IFRSVUV9CiMgRXhwb3J0IHRvIFJEUyBmaWxlIHdpdGggImd6IiBjb21wcmVzc2lvbgpyZWFkcjo6d3JpdGVfcmRzKG1lcmdlZF9zY2UsCiAgICAgICAgICAgICAgICAgaW50ZWdyYXRlZF9zY2VfZmlsZSwKICAgICAgICAgICAgICAgICBjb21wcmVzcyA9ICJneiIpCmBgYAoKCiMjIFByaW50IHNlc3Npb24gaW5mbwoKQXMgYWx3YXlzLCB3ZSdsbCBwcmludCB0aGUgc2Vzc2lvbiBpbmZvIHRvIGJlIHRyYW5zcGFyZW50IGFib3V0IHdoYXQgcGFja2FnZXMsIGFuZCB3aGljaCB2ZXJzaW9ucywgd2VyZSB1c2VkIGR1cmluZyB0aGlzIFIgc2Vzc2lvbi4KCmBgYHtyIHNlc3Npb25pbmZvfQpzZXNzaW9uSW5mbygpCmBgYAo=
diff --git a/scRNA-seq-advanced/03-differential_expression.nb.html b/scRNA-seq-advanced/03-differential_expression.nb.html
index f484865b..61e1322c 100644
--- a/scRNA-seq-advanced/03-differential_expression.nb.html
+++ b/scRNA-seq-advanced/03-differential_expression.nb.html
@@ -4049,7 +4049,7 @@ Exploring the identified differentially expressed genes
increasing max.overlaps
-
+