diff --git a/31-plotting_sample_size_biological_context_coverage.Rmd b/31-plotting_sample_size_biological_context_coverage.Rmd index 124aae3..b70275a 100644 --- a/31-plotting_sample_size_biological_context_coverage.Rmd +++ b/31-plotting_sample_size_biological_context_coverage.Rmd @@ -169,14 +169,16 @@ will be plotting are from `30-evaluate_sample_size_and_biological_context`. # pathway coverage and proportion of LVs associated with pathways context.coverage.file <- file.path("results", "30", "biological_context_pathway_coverage.tsv") + +# we'll want to reorder the biological contexts by sample size +context.levels <- c("blood", "cancer", "tissue", "cell line", "other tissues") + context.coverage.df <- readr::read_tsv(context.coverage.file) %>% # clean up the context information for plotting dplyr::mutate(biological_context = gsub("_", " ", biological_context)) %>% # reorder by the sample size (low -> high) dplyr::mutate(biological_context = factor(biological_context, - levels = c("blood", "cancer", - "tissue", "cell line", - "other tissues"))) + levels = context.levels)) # number of latent variables context.num.file <- file.path("results", "30", "biological_context_number_of_lvs.tsv") @@ -185,9 +187,7 @@ context.num.df <- readr::read_tsv(context.num.file) %>% dplyr::mutate(biological_context = gsub("_", " ", biological_context)) %>% # reorder by the sample size (low -> high) dplyr::mutate(biological_context = factor(biological_context, - levels = c("blood", "cancer", - "tissue", "cell line", - "other tissues"))) + levels = context.levels)) ``` ### Sample size @@ -196,21 +196,21 @@ context.num.df <- readr::read_tsv(context.num.file) %>% # pathway coverage and proportion of LVs associated with pathways size.coverage.file <- file.path("results", "30", "subsampled_pathway_coverage.tsv") + +# order by sample size +size.levels <- c("500", "1000", "2000", "4000", "8000", "16000", "32000") + # for plotting, we want the sample size as a factor (otherwise it's hard to # see what is happening on the lower end of things) but to order by the integer # value size.coverage.df <- readr::read_tsv(size.coverage.file) %>% - dplyr::mutate(sample_size = factor(sample_size, - levels = c("500", "1000", "2000", "4000", - "8000", "16000", "32000"))) + dplyr::mutate(sample_size = factor(sample_size, levels = size.levels)) # Number of latent variables size.num.file <- file.path("results", "30", "subsampled_number_of_lvs.tsv") size.num.df <- readr::read_tsv(size.num.file) %>% - dplyr::mutate(sample_size = factor(sample_size, - levels = c("500", "1000", "2000", "4000", - "8000", "16000", "32000"))) + dplyr::mutate(sample_size = factor(sample_size, levels = size.levels)) ``` ### MultiPLIER diff --git a/31-plotting_sample_size_biological_context_coverage.nb.html b/31-plotting_sample_size_biological_context_coverage.nb.html index a10ec50..0b8bd98 100644 --- a/31-plotting_sample_size_biological_context_coverage.nb.html +++ b/31-plotting_sample_size_biological_context_coverage.nb.html @@ -443,18 +443,18 @@

Read in data

Biological context

- +
# pathway coverage and proportion of LVs associated with pathways
 context.coverage.file <- file.path("results", "30", 
                                    "biological_context_pathway_coverage.tsv")
+# we'll want to reorder the biological contexts by sample size
+context.levels <- c("blood", "cancer", "tissue", "cell line", "other tissues")
 context.coverage.df <- readr::read_tsv(context.coverage.file) %>%
   # clean up the context information for plotting
   dplyr::mutate(biological_context = gsub("_", " ", biological_context)) %>%
   # reorder by the sample size (low -> high)
   dplyr::mutate(biological_context = factor(biological_context,
-                                            levels = c("blood", "cancer",
-                                                       "tissue", "cell line",
-                                                       "other tissues")))
+ levels = context.levels))
Parsed with column specification:
@@ -465,7 +465,7 @@ 

Biological context

biological_context = col_character() )
- +
# number of latent variables
 context.num.file <- file.path("results", "30", 
                               "biological_context_number_of_lvs.tsv")
@@ -474,9 +474,7 @@ 

Biological context

dplyr::mutate(biological_context = gsub("_", " ", biological_context)) %>% # reorder by the sample size (low -> high) dplyr::mutate(biological_context = factor(biological_context, - levels = c("blood", "cancer", - "tissue", "cell line", - "other tissues")))
+ levels = context.levels))
Parsed with column specification:
@@ -493,17 +491,17 @@ 

Biological context

Sample size

- +
# pathway coverage and proportion of LVs associated with pathways
 size.coverage.file <- file.path("results", "30", 
                                 "subsampled_pathway_coverage.tsv")
+# order by sample size
+size.levels <- c("500", "1000", "2000", "4000", "8000", "16000", "32000")
 # for plotting, we want the sample size as a factor (otherwise it's hard to
 # see what is happening on the lower end of things) but to order by the integer
 # value
 size.coverage.df <- readr::read_tsv(size.coverage.file) %>%
-    dplyr::mutate(sample_size = factor(sample_size,
-                                     levels = c("500", "1000", "2000", "4000",
-                                                "8000", "16000", "32000")))
+ dplyr::mutate(sample_size = factor(sample_size, levels = size.levels))
Parsed with column specification:
@@ -514,14 +512,12 @@ 

Sample size

sample_size = col_integer() )
- +
# Number of latent variables
 size.num.file <- file.path("results", "30",
                            "subsampled_number_of_lvs.tsv")
 size.num.df <- readr::read_tsv(size.num.file) %>%
-      dplyr::mutate(sample_size = factor(sample_size,
-                                     levels = c("500", "1000", "2000", "4000",
-                                                "8000", "16000", "32000")))
+ dplyr::mutate(sample_size = factor(sample_size, levels = size.levels))
Parsed with column specification:
@@ -666,13 +662,13 @@ 

Following up on the proportion of LVs associated with pathways results

prop.plots$size
-

+

prop.plots$context
-

+

prop.plots$recount2
@@ -825,7 +821,7 @@

Check sparsity

-
LS0tCnRpdGxlOiAiUGxvdHRpbmc6IHNhbXBsZSBzaXplIGFuZCBiaW9sb2dpY2FsIGNvbnRleHQgcGF0aHdheSBjb3ZlcmFnZSwgbnVtYmVyCm9mIGxhdGVudCB2YXJpYWJsZXMiCm91dHB1dDogICAKICBodG1sX25vdGVib29rOiAKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKKipKLiBUYXJvbmkgMjAxOCoqCgpJbiB0aGlzIG5vdGVib29rLCB3ZSB3aWxsIGJlIHBsb3R0aW5nOgoKKiBUaGUgbnVtYmVyIG9mIGxhdGVudCB2YXJpYWJsZXMgZm9yIG1vZGVscyB0cmFpbmVkIG9uIDEpIGRpZmZlcmVudCBiaW9sb2dpY2FsIApjb250ZXh0cyAyKSByYW5kb20gc3Vic2FtcGxpbmcgKHZhcmlvdXMgc2FtcGxlIHNpemVzKSBhbmQgdGhlIDMpIGZ1bGwgcmVjb3VudDIgCm1vZGVsIChNdWx0aVBMSUVSKQoKKiBUaGUgcGF0aHdheSBjb3ZlcmFnZSBhbmQgcHJvcG9ydGlvbiBvZiB0aGUgbGF0ZW50IHZhcmlhYmxlcyBhc3NvY2lhdGVkIHdpdGgKcGF0aHdheXMgZnJvbSB0aGUgc2FtZSB0aHJlZSBjb25kaXRpb25zCgojIyBTZXQgdXAKCmBgYHtyfQojIG1hZ3JpdHRyIHBpcGUKYCU+JWAgPC0gZHBseXI6OmAlPiVgCmBgYAoKV2UnbGwgdXNlIGBnZ3Bsb3QyYCBmb3IgcGxvdHRpbmcuCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpgYGAKCiMjIyMgQ3VzdG9tIGZ1bmN0aW9ucwoKYGBge3J9CiMgY3VzdG9tIGdncGxvdDIgdGhlbWUKY3VzdG9tX3RoZW1lIDwtIGZ1bmN0aW9uKCkgewogIGdncGxvdDI6OnRoZW1lX2J3KCkgKwogICAgZ2dwbG90Mjo6dGhlbWUoYXhpcy50ZXh0LnggPSBnZ3Bsb3QyOjplbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpLAogICAgICAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgICAgICAgICAgICAgcGxvdC50aXRsZSA9IGdncGxvdDI6OmVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlLnggPSBnZ3Bsb3QyOjplbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgICB0ZXh0ID0gZ2dwbG90Mjo6ZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpIAp9CmBgYAoKYGBge3J9CiMgdGhpcyBleHBlY3RzIHRoYXQgZGF0YS5mcmFtZXMgd2lsbCBhbHJlYWR5IGJlIGNsZWFuZWQgYW5kIHJlLW9yZGVyZWQhCiMgYWxsIGRhdGEuZnJhbWVzIG11c3QgaGF2ZSB0aGUgc2FtZSBjb2x1bW4gZm9yIHVzZSBhcyB0aGUgeS52YXJpYWJsZSAKIyAoZS5nLiwgbWF0Y2hpbmcgeS52YXJpYWJsZS5uYW1lKQpUaHJlZVBsb3RzV3JhcHBlciA8LSBmdW5jdGlvbihzaXplLmRmLCBjb250ZXh0LmRmLCByZWNvdW50Mi5kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeS52YXJpYWJsZS5uYW1lLCB5LmxhYmVsLCB5LmxpbWl0cyA9ICJjKDAsIDEpIikgewogICMgR2l2ZW4gcmVzdWx0cyBmb3Igc2FtcGxlIHNpemUsIGJpb2xvZ2ljYWwgY29udGV4dCwgYW5kIE11bHRpUExJRVIgbWFrZQogICMgcGxvdHMgZm9yIHRoZSB0aHJlZSBjb25kaXRpb25zICh1c2luZyBjdXN0b21fdGhlbWUgZnJvbSBhYm92ZSkKICAjIAogICMgQXJnczoKICAjICAgc2l6ZS5kZjogZGF0YS5mcmFtZSB3aXRoIHRoZSBzYW1wbGUgc2l6ZSByZXN1bHRzLCByZXF1aXJlcyBhIGNvbHVtbiBuYW1lZAogICMgICAgICAgICAgInNhbXBsZV9zaXplIgogICMgICBjb250ZXh0LmRmOiBkYXRhLmZyYW1lIHdpdGggdGhlIGJpb2xvZ2ljYWwgY29udGV4dCByZXN1bHRzLCByZXF1aXJlcyBhIAogICMgICAgICAgICAgICAgY29sdW1uIG5hbWVkICJiaW9sb2dpY2FsX2NvbnRleHQiCiAgIyAgIHJlY291bnQyLmRmOiBkYXRhLmZyYW1lIHdpdGggbXVsdGlwbGllciByZXN1bHRzLCByZXF1aXJlcyBhIGNvbHVtbiBuYW1lZAogICMgICAgICAgICAgICAgICJjb25kaXRpb24iCiAgIyAgIHkudmFyaWFibGUubmFtZTogdGhlIGNvbHVtbiBuYW1lLCBzaGFyZWQgYnkgYWxsIHRocmVlIGRhdGEuZnJhbWVzLCB0aGF0CiAgIyAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSB1c2VkIGFzIHRoZSB5IHZhcmlhYmxlIGluIHRoZSBwbG90cwogICMgICB5LmxhYmVsOiB3aGF0IHNob3VsZCB0aGUgeS1heGlzIGxhYmVsIGJlPwogICMgICB5LmxpbWl0czogcGFzc2VkIHRvIGdncGxvdDI6OnlsaW0sIHNob3VsZCBmb2xsb3cgdGhlIGZvcm1hdCAKICAjICAgICAgICAgICAgICJjKDxMT1dFUiBMSU1JVD4sIDxVUFBFUiBMSU1JVD4pIgogICMKICAjIFJldHVybnM6IAogICMgICBhIGxpc3Qgb2YgdGhlIGZvbGxvdyBwbG90czogc2l6ZSwgY29udGV4dCwgcmVjb3VudDIKICAKICAjIHN0YW5kYXJkaXplZCBnZW9tX2JveHBsb3QgKyBnZW9tX2ppdHRlciBwbG90IGZvciBzYW1wbGUgc2l6ZSBhbmQgYmlvbG9naWNhbAogICMgY29udGV4dCBwbG90cwogIEJveHBsb3RKaXR0ZXIgPC0gZnVuY3Rpb24oZGYsIHgudmFyLCB5LnZhciwgeS5saW0pewogICAgZ2dwbG90KGRhdGEgPSBkZiwgYWVzX3N0cmluZyh4ID0geC52YXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0geS52YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0geC52YXIpKSArCiAgICAgICMgd2lsbCBiZSB1c2luZyBqaXR0ZXIgc28gaW5jbHVkaW5nIGFuIG91dGxpZXIgc2hhcGUgaW4gdGhlIGJveHBsb3QgY291bGQKICAgICAgIyBjb25mdXNlIHRoaW5ncyBhIGJpdAogICAgICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZSA9IE5BKSArCiAgICAgIGdlb21faml0dGVyKGFscGhhID0gMC41LCB3aWR0aCA9IDAuMykgKwogICAgICBjdXN0b21fdGhlbWUoKSArCiAgICAgIHlsaW0oZXZhbChwYXJzZSh0ZXh0ID0geS5saW0pKSkKICB9CiAgCiAgc2l6ZS5wbG90IDwtIHNpemUuZGYgJT4lCiAgICBCb3hwbG90Sml0dGVyKHgudmFyID0gInNhbXBsZV9zaXplIiwKICAgICAgICAgICAgICAgICAgeS52YXIgPSB5LnZhcmlhYmxlLm5hbWUsCiAgICAgICAgICAgICAgICAgIHkubGltID0geS5saW1pdHMpICsKICAgICMgb25seSB0aGUgc2FtcGxlIHNpemUgcGxvdCB3aGljaCB3aWxsIGJlIG9uIHRoZSBsZWZ0IGluIG11bHRpcGFuZWwgZmlndXJlcwogICAgIyB3aWxsIGhhdmUgYSB5LWF4aXMgbGFiZWwKICAgIGxhYnMoeSA9IHkubGFiZWwsIHRpdGxlID0gIlNhbXBsZSBTaXplIikKICAKICBjb250ZXh0LnBsb3QgPC0gY29udGV4dC5kZiAlPiUKICAgIEJveHBsb3RKaXR0ZXIoeC52YXIgPSAiYmlvbG9naWNhbF9jb250ZXh0IiwKICAgICAgICAgICAgICAgICAgeS52YXIgPSB5LnZhcmlhYmxlLm5hbWUsCiAgICAgICAgICAgICAgICAgIHkubGltID0geS5saW1pdHMpICsKICAgICAgbGFicyh5ID0gTlVMTCwgdGl0bGUgPSAiQmlvbG9naWNhbCBDb250ZXh0IikKICAKICAjIHRoZSBtdWx0aXBsaWVyIHBsb3QgaXMgYSBzaW5nbGUgcG9pbnQuIHRoZSBjdXN0b20gdGhlbWUgaXMgc2hhcmVkLgogIHJlY291bnQyLnBsb3QgPC0gcmVjb3VudDIuZGYgJT4lCiAgICBnZ3Bsb3QoYWVzX3N0cmluZyh4ID0gImNvbmRpdGlvbiIsIHkgPSB5LnZhcmlhYmxlLm5hbWUpKSArCiAgICBnZW9tX3BvaW50KGZpbGwgPSAiIzAwMDBGRiIsIHNoYXBlID0gMjMsIHNpemUgPSA0KSArCiAgICBjdXN0b21fdGhlbWUoKSArCiAgICB5bGltKGV2YWwocGFyc2UodGV4dCA9IHkubGltaXRzKSkpICsKICAgIGxhYnMoeSA9IE5VTEwsIHRpdGxlID0gIk11bHRpUExJRVIiKQogIAogICMgcmV0dXJuIGEgbGlzdCBvZiB0aGUgdGhyZWUgcGxvdHMKICByZXR1cm4obGlzdCgic2l6ZSIgPSBzaXplLnBsb3QsCiAgICAgICAgICAgICAgImNvbnRleHQiID0gY29udGV4dC5wbG90LAogICAgICAgICAgICAgICJyZWNvdW50MiIgPSByZWNvdW50Mi5wbG90KSkKfQoKYGBgCgpgYGB7cn0KTXVsdGlQYW5lbFdyYXBwZXIgPC0gZnVuY3Rpb24oc2l6ZS5wbG90LCBjb250ZXh0LnBsb3QsIHJlY291bnQyLnBsb3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90LnRpdGxlLCBvdXRwdXQuZmlsZSkgewogICMgZ2l2ZW4gdGhlIHBsb3RzIGZvciB0aGUgc2FtcGxlIHNpemUgZXhwZXJpbWVudCwgdGhlIGJpb2xvZ2ljYWwgY29udGV4dAogICMgZXhwZXJpbWVudCBhbmQgdGhlIGZ1bGwgTXVsdGlQTElFUiBtb2RlbCwgcmVzcGVjdGl2ZWx5LCBtYWtlIGEgbXVsdGlwYW5lbAogICMgcGxvdCB0aXRsZWQgd2l0aCB0aGUgcGxvdC50aXRsZSBhcmd1bWVudCBhbmQgc2F2ZWQgYXMgYW4gMTEiVyB4IDUiSCBwbG90CiAgIyBpbiB0aGUgbG9jYXRpb24gc3BlY2lmaWVkIGJ5IG91dHB1dC5maWxlCiAgCiAgIyBmb3IgdGhlIHRocmVlIGNvbmRpdGlvbnMsIG1ha2UgYSAzIGNvbHVtbiBtdWx0aXBhbmVsIHBsb3QKICBwYW5lbHMgPC0gY293cGxvdDo6cGxvdF9ncmlkKHNpemUucGxvdCwgY29udGV4dC5wbG90LCByZWNvdW50Mi5wbG90LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduID0gImgiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGhlIHNpemUgcGxvdCB3aWxsIGhhdmUgdGhlIHktYXhpcyBsYWJlbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhbmQgdGhlIE11bHRpUExJRVIgcGFuZWwgc2hvdWxkIGJlIHF1aXRlIHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc21hbGwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbF93aWR0aHMgPSBjKDEuMTI1LCAxLCAwLjM3NSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmNvbCA9IDMpCiAgCiAgIyB0aGUgdGl0bGUgInBhbmVsIgogIHAudGl0bGUgPC0gY293cGxvdDo6Z2dkcmF3KCkgKyAKICAgIGNvd3Bsb3Q6OmRyYXdfbGFiZWwocGxvdC50aXRsZSwgZm9udGZhY2UgPSAiYm9sZCIsIAogICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMjApCiAgCiAgIyBjb21iaW5lIHRvIGdldCB0aGUgZmluYWwgcGxvdAogIGZpbmFsLnBsb3QgPC0gY293cGxvdDo6cGxvdF9ncmlkKHAudGl0bGUsIHBhbmVscywgbmNvbCA9IDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbF9oZWlnaHRzID0gYygwLjEsIDEpKQogIAogICMgc2F2ZSAxMSJXIHggNSJIIGZpbGUgKHRoZSB0eXBlIG9mIGZpbGUgaXMgZGV0ZXJtaW5lZCBieSB0aGUgZmlsZSBleHRlbnNpb24KICAjIHByb3ZpZGVkIGluIG91dHB1dC5maWxlKQogIGdnc2F2ZShvdXRwdXQuZmlsZSwgcGxvdCA9IGZpbmFsLnBsb3QsIHdpZHRoID0gMTEsIGhlaWdodCA9IDUpCiAgCn0KYGBgCgojIyMjIERpcmVjdG9yeSBzZXR1cAoKYGBge3J9CiMgcGxvdCBhbmQgcmVzdWx0IGRpcmVjdG9yeSBzZXR1cCBmb3IgdGhpcyBub3RlYm9vawpwbG90LmRpciA8LSBmaWxlLnBhdGgoInBsb3RzIiwgIjMxIikKZGlyLmNyZWF0ZShwbG90LmRpciwgcmVjdXJzaXZlID0gVFJVRSwgc2hvd1dhcm5pbmdzID0gRkFMU0UpCnJlc3VsdHMuZGlyIDwtIGZpbGUucGF0aCgicmVzdWx0cyIsICIzMSIpCmRpci5jcmVhdGUocmVzdWx0cy5kaXIsIHJlY3Vyc2l2ZSA9IFRSVUUsIHNob3dXYXJuaW5ncyA9IEZBTFNFKQpgYGAKCiMjIFJlYWQgaW4gZGF0YQoKRm9yIGJvdGggdGhlIGJpb2xvZ2ljYWwgY29udGV4dCBhbmQgc2FtcGxlIHNpemUgZXZhbHVhdGlvbnMsIHRoZSByZXN1bHRzIHdlCndpbGwgYmUgcGxvdHRpbmcgYXJlIGZyb20gYDMwLWV2YWx1YXRlX3NhbXBsZV9zaXplX2FuZF9iaW9sb2dpY2FsX2NvbnRleHRgLgoKIyMjIEJpb2xvZ2ljYWwgY29udGV4dAoKYGBge3J9CiMgcGF0aHdheSBjb3ZlcmFnZSBhbmQgcHJvcG9ydGlvbiBvZiBMVnMgYXNzb2NpYXRlZCB3aXRoIHBhdGh3YXlzCmNvbnRleHQuY292ZXJhZ2UuZmlsZSA8LSBmaWxlLnBhdGgoInJlc3VsdHMiLCAiMzAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmlvbG9naWNhbF9jb250ZXh0X3BhdGh3YXlfY292ZXJhZ2UudHN2IikKY29udGV4dC5jb3ZlcmFnZS5kZiA8LSByZWFkcjo6cmVhZF90c3YoY29udGV4dC5jb3ZlcmFnZS5maWxlKSAlPiUKICAjIGNsZWFuIHVwIHRoZSBjb250ZXh0IGluZm9ybWF0aW9uIGZvciBwbG90dGluZwogIGRwbHlyOjptdXRhdGUoYmlvbG9naWNhbF9jb250ZXh0ID0gZ3N1YigiXyIsICIgIiwgYmlvbG9naWNhbF9jb250ZXh0KSkgJT4lCiAgIyByZW9yZGVyIGJ5IHRoZSBzYW1wbGUgc2l6ZSAobG93IC0+IGhpZ2gpCiAgZHBseXI6Om11dGF0ZShiaW9sb2dpY2FsX2NvbnRleHQgPSBmYWN0b3IoYmlvbG9naWNhbF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoImJsb29kIiwgImNhbmNlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGlzc3VlIiwgImNlbGwgbGluZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3RoZXIgdGlzc3VlcyIpKSkKIyBudW1iZXIgb2YgbGF0ZW50IHZhcmlhYmxlcwpjb250ZXh0Lm51bS5maWxlIDwtIGZpbGUucGF0aCgicmVzdWx0cyIsICIzMCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmlvbG9naWNhbF9jb250ZXh0X251bWJlcl9vZl9sdnMudHN2IikKY29udGV4dC5udW0uZGYgPC0gcmVhZHI6OnJlYWRfdHN2KGNvbnRleHQubnVtLmZpbGUpICU+JQogICMgY2xlYW4gdXAgdGhlIGNvbnRleHQgaW5mb3JtYXRpb24gZm9yIHBsb3R0aW5nCiAgZHBseXI6Om11dGF0ZShiaW9sb2dpY2FsX2NvbnRleHQgPSBnc3ViKCJfIiwgIiAiLCBiaW9sb2dpY2FsX2NvbnRleHQpKSAlPiUKICAjIHJlb3JkZXIgYnkgdGhlIHNhbXBsZSBzaXplIChsb3cgLT4gaGlnaCkKICBkcGx5cjo6bXV0YXRlKGJpb2xvZ2ljYWxfY29udGV4dCA9IGZhY3RvcihiaW9sb2dpY2FsX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiYmxvb2QiLCAiY2FuY2VyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0aXNzdWUiLCAiY2VsbCBsaW5lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvdGhlciB0aXNzdWVzIikpKQpgYGAKCiMjIyBTYW1wbGUgc2l6ZSAKCmBgYHtyfQojIHBhdGh3YXkgY292ZXJhZ2UgYW5kIHByb3BvcnRpb24gb2YgTFZzIGFzc29jaWF0ZWQgd2l0aCBwYXRod2F5cwpzaXplLmNvdmVyYWdlLmZpbGUgPC0gZmlsZS5wYXRoKCJyZXN1bHRzIiwgIjMwIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN1YnNhbXBsZWRfcGF0aHdheV9jb3ZlcmFnZS50c3YiKQojIGZvciBwbG90dGluZywgd2Ugd2FudCB0aGUgc2FtcGxlIHNpemUgYXMgYSBmYWN0b3IgKG90aGVyd2lzZSBpdCdzIGhhcmQgdG8KIyBzZWUgd2hhdCBpcyBoYXBwZW5pbmcgb24gdGhlIGxvd2VyIGVuZCBvZiB0aGluZ3MpIGJ1dCB0byBvcmRlciBieSB0aGUgaW50ZWdlcgojIHZhbHVlCnNpemUuY292ZXJhZ2UuZGYgPC0gcmVhZHI6OnJlYWRfdHN2KHNpemUuY292ZXJhZ2UuZmlsZSkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKHNhbXBsZV9zaXplID0gZmFjdG9yKHNhbXBsZV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiNTAwIiwgIjEwMDAiLCAiMjAwMCIsICI0MDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjgwMDAiLCAiMTYwMDAiLCAiMzIwMDAiKSkpCgojIE51bWJlciBvZiBsYXRlbnQgdmFyaWFibGVzCnNpemUubnVtLmZpbGUgPC0gZmlsZS5wYXRoKCJyZXN1bHRzIiwgIjMwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgInN1YnNhbXBsZWRfbnVtYmVyX29mX2x2cy50c3YiKQpzaXplLm51bS5kZiA8LSByZWFkcjo6cmVhZF90c3Yoc2l6ZS5udW0uZmlsZSkgJT4lCiAgICAgIGRwbHlyOjptdXRhdGUoc2FtcGxlX3NpemUgPSBmYWN0b3Ioc2FtcGxlX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCI1MDAiLCAiMTAwMCIsICIyMDAwIiwgIjQwMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiODAwMCIsICIxNjAwMCIsICIzMjAwMCIpKSkKYGBgCgojIyMgTXVsdGlQTElFUgoKRm9yIHRoZSBmdWxsIHJlY291bnQyIGJpdHMsIHdlJ2xsIHVzZSB0aGUgc2FtZSB2YWx1ZXMgdGhhdCBhcmUgaW4gCmBmaWd1cmVfbm90ZWJvb2tzL3N1YnNhbXBsaW5nX2ZpZ3VyZXNgLgooVGhlIGZ1bGwgbW9kZWwgd2FzIHRyYWluZWQgb24gfjM3SyBzYW1wbGVzLCBiZWNhdXNlIHdlIHN1YnNldCByZWNvdW50MiB0bwppbmNsdWRlIG9ubHkgdGhvc2Ugc2FtcGxlcyB3aXRoIG1ldGFkYXRhLikKCmBgYHtyfQojIG51bWJlciBvZiBsYXRlbnQgdmFyaWFibGVzIGluIHRoZSBNdWx0aVBMSUVSIG1vZGVsCnJlY291bnQyLm51bS5sdnMgPC0gOTg3CiMgcGF0aHdheSBjb3ZlcmFnZQpyZWNvdW50Mi5jb3ZlcmFnZSA8LSAwLjQxODc4OTgKIyBwcm9wb3J0aW9uIG9mIHRoZSBsYXRlbnQgdmFyaWFibGVzIGFzc29jaWF0ZWQgd2l0aCBhIHBhdGh3YXkKcmVjb3VudDIubHYucHJvcCA8LSAwLjIwMTYyMTEKYGBgCgpNYWtlIGludG8gYGRhdGEuZnJhbWVzYCBmb3IgcGxvdHRpbmcgcHVycG9zZXMuIApXZSdsbCBhbHdheXMgdXNlICJjb25kaXRpb24iIGFzIG9uZSBvZiB0aGUgY29sdW1uIG5hbWVzIChzZWUgCmBUaHJlZVBsb3RzV3JhcHBlcmAgYWJvdmUpLgoKYGBge3J9CiMgcHJvcG9ydGlvbiBvZiBMVnMgYXNzb2NpYXRlZCB3aXRoIHBhdGh3YXlzCnJlY291bnQyLnByb3AuZGYgPC0gZGF0YS5mcmFtZSh2YWx1ZSA9IHJlY291bnQyLmx2LnByb3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25kaXRpb24gPSAiZnVsbCByZWNvdW50MiIpCiMgcGF0aHdheSBjb3ZlcmFnZQpyZWNvdW50Mi5jb3ZlcmFnZS5kZiA8LSBkYXRhLmZyYW1lKHZhbHVlID0gcmVjb3VudDIuY292ZXJhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uID0gImZ1bGwgcmVjb3VudDIiKQojIG51bWJlciBvZiBsYXRlbnQgdmFyaWFibGVzCnJlY291bnQyLm51bS5kZiA8LSAKICBkYXRhLmZyYW1lKG51bWJlcl9vZl9sYXRlbnRfdmFyaWFibGVzID0gYXMuaW50ZWdlcihyZWNvdW50Mi5udW0ubHZzKSwKICAgICAgICAgICAgIGNvbmRpdGlvbiA9ICJmdWxsIHJlY291bnQyIikKYGBgCgojIyBQbG90dGluZwoKIyMjIE51bWJlciBvZiBsYXRlbnQgdmFyaWFibGVzCgpgYGB7cn0KbnVtLnBsb3RzIDwtIFRocmVlUGxvdHNXcmFwcGVyKHNpemUuZGYgPSBzaXplLm51bS5kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZGYgPSBjb250ZXh0Lm51bS5kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY291bnQyLmRmID0gcmVjb3VudDIubnVtLmRmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeS52YXJpYWJsZS5uYW1lID0gIm51bWJlcl9vZl9sYXRlbnRfdmFyaWFibGVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkubGFiZWwgPSAibnVtYmVyIG9mIGxhdGVudCB2YXJpYWJsZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeS5saW1pdHMgPSAiYygwLCAxMDAwKSIpCmBgYAoKU2F2ZSB0byBmaWxlCgpgYGB7cn0KTXVsdGlQYW5lbFdyYXBwZXIoc2l6ZS5wbG90ID0gbnVtLnBsb3RzJHNpemUsCiAgICAgICAgICAgICAgICAgIGNvbnRleHQucGxvdCA9IG51bS5wbG90cyRjb250ZXh0LAogICAgICAgICAgICAgICAgICByZWNvdW50Mi5wbG90ID0gbnVtLnBsb3RzJHJlY291bnQyLAogICAgICAgICAgICAgICAgICBwbG90LnRpdGxlID0gIk51bWJlciBvZiBMYXRlbnQgVmFyaWFibGVzIiwKICAgICAgICAgICAgICAgICAgb3V0cHV0LmZpbGUgPSBmaWxlLnBhdGgocGxvdC5kaXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibnVtYmVyX29mX2xhdGVudF92YXJpYWJsZXMucGRmIikpCmBgYAoKIyMjIFBhdGh3YXkgY292ZXJhZ2UKClRoZSBzYW1wbGUgc2l6ZSBhbmQgYmlvbG9naWNhbCBjb250ZXh0IGBkYXRhLmZyYW1lc2AgY29udGFpbiB0aGUgaW5mb3JtYXRpb24KYWJvdXQgcGF0aHdheSBjb3ZlcmFnZSBfYW5kXyB0aGUgcHJvcG9ydGlvbiBvZiBMVnMgYXNzb2NpYXRlZCB3aXRoIGEgcGF0aHdheSwKc28gd2UnbGwgbmVlZCB0byBmaWx0ZXIgdGhlbSB0byB0aGUgY29ycmVjdCBtZXRyaWMuCgpgYGB7cn0KY292ZXJhZ2UucGxvdHMgPC0gCiAgVGhyZWVQbG90c1dyYXBwZXIoc2l6ZS5kZiA9IGRwbHlyOjpmaWx0ZXIoc2l6ZS5jb3ZlcmFnZS5kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWMgPT0gInBhdGh3YXkgY292ZXJhZ2UiKSwKICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmRmID0gZHBseXI6OmZpbHRlcihjb250ZXh0LmNvdmVyYWdlLmRmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpYyA9PSAicGF0aHdheSBjb3ZlcmFnZSIpLAogICAgICAgICAgICAgICAgICAgIHJlY291bnQyLmRmID0gcmVjb3VudDIuY292ZXJhZ2UuZGYsCiAgICAgICAgICAgICAgICAgICAgeS52YXJpYWJsZS5uYW1lID0gInZhbHVlIiwKICAgICAgICAgICAgICAgICAgICB5LmxhYmVsID0gInByb3BvcnRpb24gb2YgaW5wdXQgcGF0aHdheXMiKQpgYGAKCmBgYHtyfQpNdWx0aVBhbmVsV3JhcHBlcihzaXplLnBsb3QgPSBjb3ZlcmFnZS5wbG90cyRzaXplLAogICAgICAgICAgICAgICAgICBjb250ZXh0LnBsb3QgPSBjb3ZlcmFnZS5wbG90cyRjb250ZXh0LAogICAgICAgICAgICAgICAgICByZWNvdW50Mi5wbG90ID0gY292ZXJhZ2UucGxvdHMkcmVjb3VudDIsCiAgICAgICAgICAgICAgICAgIHBsb3QudGl0bGUgPSAiUGF0aHdheSBDb3ZlcmFnZSIsCiAgICAgICAgICAgICAgICAgIG91dHB1dC5maWxlID0gZmlsZS5wYXRoKHBsb3QuZGlyLCAicGF0aHdheV9jb3ZlcmFnZS5wZGYiKSkKYGBgCgojIyMgTGF0ZW50IHZhcmlhYmxlcyBzaWduaWZpY2FudGx5IGFzc29jaWF0ZWQgd2l0aCBwYXRod2F5cwoKYGBge3J9CiMgZm9yIGxpbmUgbGVuZ3RoL3N0eWxlIHB1cnBvc2VzCm1ldHJpYy50by51c2UgPC0gIkxWIGFzc29jaWF0ZWQgd2l0aCBwYXRod2F5cyIKcHJvcC5wbG90cyA8LSAKICBUaHJlZVBsb3RzV3JhcHBlcihzaXplLmRmID0gZHBseXI6OmZpbHRlcihzaXplLmNvdmVyYWdlLmRmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpYyA9PSBtZXRyaWMudG8udXNlKSwKICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmRmID0gZHBseXI6OmZpbHRlcihjb250ZXh0LmNvdmVyYWdlLmRmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpYyA9PSBtZXRyaWMudG8udXNlKSwKICAgICAgICAgICAgICAgICAgICByZWNvdW50Mi5kZiA9IHJlY291bnQyLmNvdmVyYWdlLmRmLAogICAgICAgICAgICAgICAgICAgIHkudmFyaWFibGUubmFtZSA9ICJ2YWx1ZSIsCiAgICAgICAgICAgICAgICAgICAgeS5sYWJlbCA9ICJwcm9wb3J0aW9uIG9mIGxhdGVudCB2YXJpYWJsZXMiKQpgYGAKCmBgYHtyfQpNdWx0aVBhbmVsV3JhcHBlcihzaXplLnBsb3QgPSBwcm9wLnBsb3RzJHNpemUsCiAgICAgICAgICAgICAgICAgIGNvbnRleHQucGxvdCA9IHByb3AucGxvdHMkY29udGV4dCwKICAgICAgICAgICAgICAgICAgcmVjb3VudDIucGxvdCA9IHByb3AucGxvdHMkcmVjb3VudDIsCiAgICAgICAgICAgICAgICAgIHBsb3QudGl0bGUgPSAiTFZzIHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIHBhdGh3YXlzIiwKICAgICAgICAgICAgICAgICAgb3V0cHV0LmZpbGUgPSBmaWxlLnBhdGgocGxvdC5kaXIsICJsdl9wcm9wb3J0aW9uLnBkZiIpKQoKYGBgCgojIyMgRm9sbG93aW5nIHVwIG9uIHRoZSBwcm9wb3J0aW9uIG9mIExWcyBhc3NvY2lhdGVkIHdpdGggcGF0aHdheXMgcmVzdWx0cwoKSWYgd2UgbG9vayBhdCB0aGUgYHByb3AucGxvdHNgCgpgYGB7cn0KcHJvcC5wbG90cyRzaXplCnByb3AucGxvdHMkY29udGV4dApwcm9wLnBsb3RzJHJlY291bnQyCmBgYAoKV2UgY2FuIHNlZSBpbiB0aGUgc2FtcGxlIHNpemUgcGxvdCB0aGF0LCBnZW5lcmFsbHkgc3BlYWtpbmcsIHRoZSBsYXJnZXIgdGhlIApzYW1wbGUgc2l6ZSwgdGhlIGxvd2VyIHRoZSBwcm9wb3J0aW9uIG9mIGxhdGVudCB2YXJpYWJsZXMgdGhhdCBhcmUgYXNzb2NpYXRlZCAKd2l0aCBhdCBsZWFzdCBvbmUgcGF0aHdheS4KCmBQTElFUjo6UExJRVJgIGhhcyBhIHBhcmFtZXRlciwgYGZyYWNgLCB0aGF0IGRldGVybWluZXMgdGhlIGZyYWN0aW9uIG9mIGxhdGVudAp2YXJpYWJsZXMgdGhhdCBtZWV0cyB0aGF0IGNyaXRlcmlvbi4gCihgZnJhYyA9IDAuN2AgYnkgZGVmYXVsdCBpbiB0aGUgdmVyc2lvbiBvZiBQTElFUiB3ZSBoYXZlIG9uIHRoaXMgRG9ja2VyIApjb250YWluZXI7IHdlIGRpZCBub3Qgc3BlY2lmeSBgZnJhY2AuKQoKVGhpcyBwYXJhbWV0ZXIgaXMgdXNlZCB0byBzZXQgYEwzYCwgd2hpY2ggaXMgdGhlIHBlbmFsdHkgb24gYFVgIHRoYXQgY29udHJvbHMKc3BhcnNpdHkgKFtNYW8sIGV0IGFsLiBfYmlvUnhpdl8uIDIwMTcuXShodHRwOi8vZHguZG9pLm9yZy8xMC4xMTAxLzExNjA2MSkpLgpCYXNlZCBvbiBteSB1bmRlcnN0YW5kaW5nLCB0aGlzIGNvbnRyb2xzIHRoZSBwcm9wb3J0aW9uIG9mIHBvc2l0aXZlIGVudHJpZXMgaW4gCmBVYCAoaS5lLiwgdGhlIG51bWJlciBvZiBnZW5lIHNldHMgdGhhdCBhbiBMViBoYXMgc29tZSBhc3NvY2lhdGlvbiB3aXRoKSwgYnV0IAppdCBfZG9lcyBub3RfIGd1YXJhbnRlZSB0aGF0IGFsbCBvZiB0aGVzZSBhc3NvY2lhdGlvbnMgd2lsbCBiZSBzaWduaWZpY2FudAooW01hbywgZXQgYWwuIF9iaW9SeGl2Xy4gMjAxNy5dKGh0dHA6Ly9keC5kb2kub3JnLzEwLjExMDEvMTE2MDYxKSkgYW5kIAp0aGUgY3V0b2ZmIHdlIGhhcHBlbiB0byBiZSB1c2luZyAoYEZEUiA8IDAuMDVgKSBpcyBub3QgdGFrZW4gaW50byBhY2NvdW50LiAKCkZvciByZWZlcmVuY2UsIHRoaXMgaXMgdGhlIHNhbXBsZSBzaXplIGluZm9ybWF0aW9uIGZvciB0aGVzZSBkaWZmZXJlbnQgdHJhaW5pbmcKc2V0czoKCnwgQmlvbG9naWNhbCBjb25kaXRpb24gfCBTYW1wbGUgc2l6ZSB8Cnw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tLS18CnwgYmxvb2QgfCAzODYyIHwKfCBjYW5jZXIgfCA4ODA3IHwKfCB0aXNzdWUgfCAxMjM5NiB8CnwgY2VsbCBsaW5lIHwgMTQ1MzIgfAp8IG90aGVyIHRpc3N1ZXMgKG5vdCBibG9vZCkgfCAzMjk4NCB8IAoKT25jZSB3ZSB0YWtlIHRoZSBiaW9sb2dpY2FsIGNvbnRleHQgZXhwZXJpbWVudHMgaW50byBhY2NvdW50LCBpdCBnZXRzIGEgYml0Cm1vcmUgaW50ZXJlc3Rpbmc6CgoqIFRoZSBgYmxvb2RgIHRyYWluaW5nIHNldCBoYXMgfjQwMDAgc2FtcGxlcywgYnV0IG1vZGVscyB0cmFpbmVkIG9uIGJsb29kIGhhdmUgYSAKbXVjaCBoaWdoZXIgcHJvcG9ydGlvbiBvZiBsYXRlbnQgdmFyaWFibGVzIHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIApwYXRod2F5cyB0aGFuIHRoZSBtb2RlbHMgdHJhaW5lZCBvbiA0MDAwIHJhbmRvbWx5IHNlbGVjdGVkIHNhbXBsZXMuCldlJ2QgZXhwZWN0IHRoYXQgdGhlcmUnZCBiZSBsZXNzICJ0ZWNobmljYWwgbm9pc2UiIGFuZCBtb3JlICJiaW9sb2dpY2FsIHNpZ25hbCIKaW4gdGhlIGBibG9vZGAgdHJhaW5pbmcgc2V0LgpJdCdzIGFsc28gbGlrZWx5IHRvIGJlIGEgZnVuY3Rpb24gb2YgdGhlIHBhdGh3YXlzIHVuZGVyIGNvbnNpZGVyYXRpb24uIApTcGVjaWZpY2FsbHksIHdlIHN1cHBseSBpbW11bmUgY2VsbC1yZWxhdGVkIGdlbmUgc2V0cyB0byB0aGUgbW9kZWxzLCBhbmQKd2UgZXhwZWN0IGBibG9vZGAgc2FtcGxlcyB0byBiZSBfcGFydGljdWxhcmx5XyByZWxldmFudCBmb3IgdGhvc2UgZ2VuZSBzZXRzLgoqIEl0IGxvb2tzIGxpa2UgdGhlIF9tb3JlIGxhdGVudCB2YXJpYWJsZXNfLCB0aGUgX2xvd2VyIHByb3BvcnRpb24gb2YgTFZzCnNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIGEgcGF0aHdheV8gYmFzZWQgb24gdGhlIHNhbXBsZSBzaXplIHJlc3VsdHMgYWxvbmUuCkFuZCBpdCdzIGNlcnRhaW5seSB0aGUgY2FzZSB0aGF0IHRoZSBtb3JlIExWcyAtPiB0aGUgbW9yZSBwYXRod2F5cyB0aGF0IGFyZQpjYXB0dXJlZCBieSB0aGUgbW9kZWwgKGhpZ2hlciBwYXRod2F5IGNvdmVyYWdlKS4gCkhvd2V2ZXIsIGB0aXNzdWVgIG1vZGVscyBoYXZlIGhpZ2hlciBudW1iZXIgb2YgTFZzIGFuZCBtb3JlIHBhdGh3YXkgY292ZXJhZ2UKdGhhbiBgY2VsbCBsaW5lYCBtb2RlbHMgYnV0IHRoZXkgaGF2ZSBhcHByb3hpbWF0ZWx5IHRoZSBzYW1lIHByb3BvcnRpb24gb2YgTFZzCnNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIGEgcGF0aHdheS4KVGhlc2UgdmFsdWVzIGFyZSBhbHNvIHBlcmhhcHMgYSBiaXQgbG93ZXIgdGhhbiB3ZSB3b3VsZCBleHBlY3QgYmFzZWQgb24gc2FtcGxlIApzaXplIGFsb25lIChsb29raW5nIGF0IGAxNjAwMGAgZnJvbSBzYW1wbGUgc2l6ZSBwbG90KS4KCiMjIENoZWNrIGBVYCBzcGFyc2l0eQoKVG8gZm9sbG93IHVwIG9uIHRoZSBvYnNlcnZhdGlvbnMgYWJvdmUsIGxldCdzIGNoZWNrIHRoYXQsIF9pbiBwcmFjdGljZV8sIHRoZSAKZnJhY3Rpb24gb2YgdGhlIExWcyB0aGF0IGhhdmUgYXQgbGVhc3Qgb25lIGFzc29jaWF0aW9uIHdpdGggYSBwYXRod2F5IHNob3VsZCBiZQoqKn4wLjcqKi4KRmlyc3QsIHJlbW92aW5nIGV2ZXJ5dGhpbmcgZnJvbSB0aGUgd29ya3NwYWNlLgoKYGBge3J9CnJtKGxpc3QgPSBscygpKQpgYGAKCiMjIyMgQ3VzdG9tIGZ1bmN0aW9ucyBqdXN0IGZvciB0aGlzCgpgYGB7cn0KIyB0aGlzIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgd2l0aCBsaXN0cyBvZiBtb2RlbHMgb3V0cHV0IGZyb20KIyBzY3JpcHRzL3N1YnNhbXBsaW5nX1BMSUVSLlIKR2V0U3BhcnNpdHlMaXN0IDwtIGZ1bmN0aW9uKGxpc3Qub2YubW9kZWxzKSB7CiAgIyB3ZSBhc3N1bWUgdGhhdCB0aGUgbGlzdCBvZiBtb2RlbHMgaGFzIG5hbWVzCiAgCiAgIyB0aGVzZSBzcGFyc2l0eSBjYWxjdWxhdGlvbnMgYXJlIGRpZmZlcmVudCBmcm9tIHdoYXQgd2UndmUgZG9uZSBiZWZvcmUKICBDaGVja1VTcGFyc2l0eSA8LSBmdW5jdGlvbihwbGllci5tb2RlbCkgewogICAgdS5tYXRyaXggPC0gcGxpZXIubW9kZWwkVQogICAgIyB3aGF0IHByb3BvcnRpb24gb2YgdmFsdWVzIGFyZSBwb3NpdGl2ZT8KICAgIHRvdGFsLnBvc2l0aXZlIDwtIHN1bSh1Lm1hdHJpeCA+IDApIC8gKGRpbSh1Lm1hdHJpeClbMV0gKiBkaW0odS5tYXRyaXgpWzJdKQogICAgIyB3aGF0IHByb3BvcnRpb24gb2YgY29sdW1ucyBoYXZlIGF0IGxlYXN0IDEgcG9zaXRpdmUgdmFsdWUgKGFzc29jaWF0aW9uKT8KICAgIGNvbC53aXNlIDwtIHN1bShhcHBseSh1Lm1hdHJpeCwgMiwgZnVuY3Rpb24oeCkgYW55KHggPiAwKSkpIC8gbmNvbCh1Lm1hdHJpeCkKICAgIHJldHVybihsaXN0KCJvdmVyYWxsIiA9IHRvdGFsLnBvc2l0aXZlLAogICAgICAgICAgICAgICAgImNvbHVtbl93aXNlIiA9IGNvbC53aXNlKSkKICB9CiAgCiAgc3BhcnNpdHkubGlzdCA8LSBsYXBwbHkobGlzdC5vZi5tb2RlbHMsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIENoZWNrVVNwYXJzaXR5KHgkUExJRVIpKQogIAp9CgojIHdlJ2xsIHVzZSB0aGlzIHR3aWNlIC0tIG9uY2UgZm9yIGJpb2xvZ2ljYWwgY29udGV4dCBhbmQgb25jZSBmb3Igc2FtcGxlIHNpemUKIyB3ZSBhc3N1bWUgdGhhdCB0aGUgZmlsZXMudmVjdG9yIGlzIG5hbWVkCkdldFJlc3VsdHMgPC0gZnVuY3Rpb24oZmlsZXMudmVjdG9yKSB7CiAgbGFwcGx5KGZpbGVzLnZlY3RvciwgCiAgICAgICAgIGZ1bmN0aW9uKHgpIHsKICAgICAgICAgICAjIGZvciBlYWNoIGZpbGUsIHJlYWQgaW4gdGhlIGxpc3Qgb2YgbW9kZWxzCiAgICAgICAgICAgbW9kZWwubGlzdCA8LSByZWFkUkRTKHgpCiAgICAgICAgICAgIyBnZXQgdGhlIHNwYXJzaXR5IGxpc3QgZm9yIHRoZSBjdXJyZW50IGxpc3Qgb2YgbW9kZWxzCiAgICAgICAgICAgR2V0U3BhcnNpdHlMaXN0KG1vZGVsLmxpc3QpCiAgICAgICAgIH0pCn0KCmBgYAoKIyMjIyBGaWxlcwoKYGBge3J9Cm1vZGVscy5kaXIgPC0gIm1vZGVscyIKIyBzYW1wbGUgc2l6ZQpzaXplLm1vZGVsLmZpbGVzIDwtIGxpc3QuZmlsZXMobW9kZWxzLmRpciwgcGF0dGVybiA9ICJzdWJzYW1wbGVkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdWxsLm5hbWVzID0gVFJVRSkKbmFtZXMoc2l6ZS5tb2RlbC5maWxlcykgPC0gc3ViKCIuUkRTIiwgIiIsIHN1YigiLipbX10iLCAiIiwgc2l6ZS5tb2RlbC5maWxlcykpCgojIGJpb2xvZ2ljYWwgY29udGV4dApjb250ZXh0Lm1vZGVsLmZpbGVzIDwtIGxpc3QuZmlsZXMobW9kZWxzLmRpciwgcGF0dGVybiA9ICJhY2Nlc3Npb25zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bGwubmFtZXMgPSBUUlVFKQpuYW1lcyhjb250ZXh0Lm1vZGVsLmZpbGVzKSA8LSAKICBzdHJpbmdyOjpzdHJfbWF0Y2goY29udGV4dC5tb2RlbC5maWxlcywgInJlY291bnQyXyguKj8pX2FjY2Vzc2lvbnMiKVssIDJdCgpgYGAKCiMjIyMgQ2hlY2sgc3BhcnNpdHkKCmBgYHtyfQpzaXplLnJlc3VsdHMgPC0gR2V0UmVzdWx0cyhzaXplLm1vZGVsLmZpbGVzKQpzaXplLmRmIDwtIHJlc2hhcGUyOjptZWx0KHNpemUucmVzdWx0cykKc3VtbWFyeShkcGx5cjo6ZmlsdGVyKHNpemUuZGYsIEwzID09ICJjb2x1bW5fd2lzZSIpJHZhbHVlKQpgYGAKCmBgYHtyfQpjb250ZXh0LnJlc3VsdHMgPC0gR2V0UmVzdWx0cyhjb250ZXh0Lm1vZGVsLmZpbGVzKQpjb250ZXh0LmRmIDwtIHJlc2hhcGUyOjptZWx0KGNvbnRleHQucmVzdWx0cykKc3VtbWFyeShkcGx5cjo6ZmlsdGVyKGNvbnRleHQuZGYsIEwzID09ICJjb2x1bW5fd2lzZSIpJHZhbHVlKQpgYGAKClRoZXNlIHJlc3VsdHMgYXJlIGNvbnNpc3RlbnQgd2l0aCBvdXIgZXhwZWN0YXRpb25zLgo=
+
LS0tCnRpdGxlOiAiUGxvdHRpbmc6IHNhbXBsZSBzaXplIGFuZCBiaW9sb2dpY2FsIGNvbnRleHQgcGF0aHdheSBjb3ZlcmFnZSwgbnVtYmVyCm9mIGxhdGVudCB2YXJpYWJsZXMiCm91dHB1dDogICAKICBodG1sX25vdGVib29rOiAKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKKipKLiBUYXJvbmkgMjAxOCoqCgpJbiB0aGlzIG5vdGVib29rLCB3ZSB3aWxsIGJlIHBsb3R0aW5nOgoKKiBUaGUgbnVtYmVyIG9mIGxhdGVudCB2YXJpYWJsZXMgZm9yIG1vZGVscyB0cmFpbmVkIG9uIDEpIGRpZmZlcmVudCBiaW9sb2dpY2FsIApjb250ZXh0cyAyKSByYW5kb20gc3Vic2FtcGxpbmcgKHZhcmlvdXMgc2FtcGxlIHNpemVzKSBhbmQgdGhlIDMpIGZ1bGwgcmVjb3VudDIgCm1vZGVsIChNdWx0aVBMSUVSKQoKKiBUaGUgcGF0aHdheSBjb3ZlcmFnZSBhbmQgcHJvcG9ydGlvbiBvZiB0aGUgbGF0ZW50IHZhcmlhYmxlcyBhc3NvY2lhdGVkIHdpdGgKcGF0aHdheXMgZnJvbSB0aGUgc2FtZSB0aHJlZSBjb25kaXRpb25zCgojIyBTZXQgdXAKCmBgYHtyfQojIG1hZ3JpdHRyIHBpcGUKYCU+JWAgPC0gZHBseXI6OmAlPiVgCmBgYAoKV2UnbGwgdXNlIGBnZ3Bsb3QyYCBmb3IgcGxvdHRpbmcuCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpgYGAKCiMjIyMgQ3VzdG9tIGZ1bmN0aW9ucwoKYGBge3J9CiMgY3VzdG9tIGdncGxvdDIgdGhlbWUKY3VzdG9tX3RoZW1lIDwtIGZ1bmN0aW9uKCkgewogIGdncGxvdDI6OnRoZW1lX2J3KCkgKwogICAgZ2dwbG90Mjo6dGhlbWUoYXhpcy50ZXh0LnggPSBnZ3Bsb3QyOjplbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpLAogICAgICAgICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgICAgICAgICAgICAgcGxvdC50aXRsZSA9IGdncGxvdDI6OmVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlLnggPSBnZ3Bsb3QyOjplbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgICB0ZXh0ID0gZ2dwbG90Mjo6ZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpIAp9CmBgYAoKYGBge3J9CiMgdGhpcyBleHBlY3RzIHRoYXQgZGF0YS5mcmFtZXMgd2lsbCBhbHJlYWR5IGJlIGNsZWFuZWQgYW5kIHJlLW9yZGVyZWQhCiMgYWxsIGRhdGEuZnJhbWVzIG11c3QgaGF2ZSB0aGUgc2FtZSBjb2x1bW4gZm9yIHVzZSBhcyB0aGUgeS52YXJpYWJsZSAKIyAoZS5nLiwgbWF0Y2hpbmcgeS52YXJpYWJsZS5uYW1lKQpUaHJlZVBsb3RzV3JhcHBlciA8LSBmdW5jdGlvbihzaXplLmRmLCBjb250ZXh0LmRmLCByZWNvdW50Mi5kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeS52YXJpYWJsZS5uYW1lLCB5LmxhYmVsLCB5LmxpbWl0cyA9ICJjKDAsIDEpIikgewogICMgR2l2ZW4gcmVzdWx0cyBmb3Igc2FtcGxlIHNpemUsIGJpb2xvZ2ljYWwgY29udGV4dCwgYW5kIE11bHRpUExJRVIgbWFrZQogICMgcGxvdHMgZm9yIHRoZSB0aHJlZSBjb25kaXRpb25zICh1c2luZyBjdXN0b21fdGhlbWUgZnJvbSBhYm92ZSkKICAjIAogICMgQXJnczoKICAjICAgc2l6ZS5kZjogZGF0YS5mcmFtZSB3aXRoIHRoZSBzYW1wbGUgc2l6ZSByZXN1bHRzLCByZXF1aXJlcyBhIGNvbHVtbiBuYW1lZAogICMgICAgICAgICAgInNhbXBsZV9zaXplIgogICMgICBjb250ZXh0LmRmOiBkYXRhLmZyYW1lIHdpdGggdGhlIGJpb2xvZ2ljYWwgY29udGV4dCByZXN1bHRzLCByZXF1aXJlcyBhIAogICMgICAgICAgICAgICAgY29sdW1uIG5hbWVkICJiaW9sb2dpY2FsX2NvbnRleHQiCiAgIyAgIHJlY291bnQyLmRmOiBkYXRhLmZyYW1lIHdpdGggbXVsdGlwbGllciByZXN1bHRzLCByZXF1aXJlcyBhIGNvbHVtbiBuYW1lZAogICMgICAgICAgICAgICAgICJjb25kaXRpb24iCiAgIyAgIHkudmFyaWFibGUubmFtZTogdGhlIGNvbHVtbiBuYW1lLCBzaGFyZWQgYnkgYWxsIHRocmVlIGRhdGEuZnJhbWVzLCB0aGF0CiAgIyAgICAgICAgICAgICAgICAgICAgd2lsbCBiZSB1c2VkIGFzIHRoZSB5IHZhcmlhYmxlIGluIHRoZSBwbG90cwogICMgICB5LmxhYmVsOiB3aGF0IHNob3VsZCB0aGUgeS1heGlzIGxhYmVsIGJlPwogICMgICB5LmxpbWl0czogcGFzc2VkIHRvIGdncGxvdDI6OnlsaW0sIHNob3VsZCBmb2xsb3cgdGhlIGZvcm1hdCAKICAjICAgICAgICAgICAgICJjKDxMT1dFUiBMSU1JVD4sIDxVUFBFUiBMSU1JVD4pIgogICMKICAjIFJldHVybnM6IAogICMgICBhIGxpc3Qgb2YgdGhlIGZvbGxvdyBwbG90czogc2l6ZSwgY29udGV4dCwgcmVjb3VudDIKICAKICAjIHN0YW5kYXJkaXplZCBnZW9tX2JveHBsb3QgKyBnZW9tX2ppdHRlciBwbG90IGZvciBzYW1wbGUgc2l6ZSBhbmQgYmlvbG9naWNhbAogICMgY29udGV4dCBwbG90cwogIEJveHBsb3RKaXR0ZXIgPC0gZnVuY3Rpb24oZGYsIHgudmFyLCB5LnZhciwgeS5saW0pewogICAgZ2dwbG90KGRhdGEgPSBkZiwgYWVzX3N0cmluZyh4ID0geC52YXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0geS52YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0geC52YXIpKSArCiAgICAgICMgd2lsbCBiZSB1c2luZyBqaXR0ZXIgc28gaW5jbHVkaW5nIGFuIG91dGxpZXIgc2hhcGUgaW4gdGhlIGJveHBsb3QgY291bGQKICAgICAgIyBjb25mdXNlIHRoaW5ncyBhIGJpdAogICAgICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZSA9IE5BKSArCiAgICAgIGdlb21faml0dGVyKGFscGhhID0gMC41LCB3aWR0aCA9IDAuMykgKwogICAgICBjdXN0b21fdGhlbWUoKSArCiAgICAgIHlsaW0oZXZhbChwYXJzZSh0ZXh0ID0geS5saW0pKSkKICB9CiAgCiAgc2l6ZS5wbG90IDwtIHNpemUuZGYgJT4lCiAgICBCb3hwbG90Sml0dGVyKHgudmFyID0gInNhbXBsZV9zaXplIiwKICAgICAgICAgICAgICAgICAgeS52YXIgPSB5LnZhcmlhYmxlLm5hbWUsCiAgICAgICAgICAgICAgICAgIHkubGltID0geS5saW1pdHMpICsKICAgICMgb25seSB0aGUgc2FtcGxlIHNpemUgcGxvdCB3aGljaCB3aWxsIGJlIG9uIHRoZSBsZWZ0IGluIG11bHRpcGFuZWwgZmlndXJlcwogICAgIyB3aWxsIGhhdmUgYSB5LWF4aXMgbGFiZWwKICAgIGxhYnMoeSA9IHkubGFiZWwsIHRpdGxlID0gIlNhbXBsZSBTaXplIikKICAKICBjb250ZXh0LnBsb3QgPC0gY29udGV4dC5kZiAlPiUKICAgIEJveHBsb3RKaXR0ZXIoeC52YXIgPSAiYmlvbG9naWNhbF9jb250ZXh0IiwKICAgICAgICAgICAgICAgICAgeS52YXIgPSB5LnZhcmlhYmxlLm5hbWUsCiAgICAgICAgICAgICAgICAgIHkubGltID0geS5saW1pdHMpICsKICAgICAgbGFicyh5ID0gTlVMTCwgdGl0bGUgPSAiQmlvbG9naWNhbCBDb250ZXh0IikKICAKICAjIHRoZSBtdWx0aXBsaWVyIHBsb3QgaXMgYSBzaW5nbGUgcG9pbnQuIHRoZSBjdXN0b20gdGhlbWUgaXMgc2hhcmVkLgogIHJlY291bnQyLnBsb3QgPC0gcmVjb3VudDIuZGYgJT4lCiAgICBnZ3Bsb3QoYWVzX3N0cmluZyh4ID0gImNvbmRpdGlvbiIsIHkgPSB5LnZhcmlhYmxlLm5hbWUpKSArCiAgICBnZW9tX3BvaW50KGZpbGwgPSAiIzAwMDBGRiIsIHNoYXBlID0gMjMsIHNpemUgPSA0KSArCiAgICBjdXN0b21fdGhlbWUoKSArCiAgICB5bGltKGV2YWwocGFyc2UodGV4dCA9IHkubGltaXRzKSkpICsKICAgIGxhYnMoeSA9IE5VTEwsIHRpdGxlID0gIk11bHRpUExJRVIiKQogIAogICMgcmV0dXJuIGEgbGlzdCBvZiB0aGUgdGhyZWUgcGxvdHMKICByZXR1cm4obGlzdCgic2l6ZSIgPSBzaXplLnBsb3QsCiAgICAgICAgICAgICAgImNvbnRleHQiID0gY29udGV4dC5wbG90LAogICAgICAgICAgICAgICJyZWNvdW50MiIgPSByZWNvdW50Mi5wbG90KSkKfQoKYGBgCgpgYGB7cn0KTXVsdGlQYW5lbFdyYXBwZXIgPC0gZnVuY3Rpb24oc2l6ZS5wbG90LCBjb250ZXh0LnBsb3QsIHJlY291bnQyLnBsb3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90LnRpdGxlLCBvdXRwdXQuZmlsZSkgewogICMgZ2l2ZW4gdGhlIHBsb3RzIGZvciB0aGUgc2FtcGxlIHNpemUgZXhwZXJpbWVudCwgdGhlIGJpb2xvZ2ljYWwgY29udGV4dAogICMgZXhwZXJpbWVudCBhbmQgdGhlIGZ1bGwgTXVsdGlQTElFUiBtb2RlbCwgcmVzcGVjdGl2ZWx5LCBtYWtlIGEgbXVsdGlwYW5lbAogICMgcGxvdCB0aXRsZWQgd2l0aCB0aGUgcGxvdC50aXRsZSBhcmd1bWVudCBhbmQgc2F2ZWQgYXMgYW4gMTEiVyB4IDUiSCBwbG90CiAgIyBpbiB0aGUgbG9jYXRpb24gc3BlY2lmaWVkIGJ5IG91dHB1dC5maWxlCiAgCiAgIyBmb3IgdGhlIHRocmVlIGNvbmRpdGlvbnMsIG1ha2UgYSAzIGNvbHVtbiBtdWx0aXBhbmVsIHBsb3QKICBwYW5lbHMgPC0gY293cGxvdDo6cGxvdF9ncmlkKHNpemUucGxvdCwgY29udGV4dC5wbG90LCByZWNvdW50Mi5wbG90LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduID0gImgiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGhlIHNpemUgcGxvdCB3aWxsIGhhdmUgdGhlIHktYXhpcyBsYWJlbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBhbmQgdGhlIE11bHRpUExJRVIgcGFuZWwgc2hvdWxkIGJlIHF1aXRlIHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc21hbGwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbF93aWR0aHMgPSBjKDEuMTI1LCAxLCAwLjM3NSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmNvbCA9IDMpCiAgCiAgIyB0aGUgdGl0bGUgInBhbmVsIgogIHAudGl0bGUgPC0gY293cGxvdDo6Z2dkcmF3KCkgKyAKICAgIGNvd3Bsb3Q6OmRyYXdfbGFiZWwocGxvdC50aXRsZSwgZm9udGZhY2UgPSAiYm9sZCIsIAogICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMjApCiAgCiAgIyBjb21iaW5lIHRvIGdldCB0aGUgZmluYWwgcGxvdAogIGZpbmFsLnBsb3QgPC0gY293cGxvdDo6cGxvdF9ncmlkKHAudGl0bGUsIHBhbmVscywgbmNvbCA9IDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbF9oZWlnaHRzID0gYygwLjEsIDEpKQogIAogICMgc2F2ZSAxMSJXIHggNSJIIGZpbGUgKHRoZSB0eXBlIG9mIGZpbGUgaXMgZGV0ZXJtaW5lZCBieSB0aGUgZmlsZSBleHRlbnNpb24KICAjIHByb3ZpZGVkIGluIG91dHB1dC5maWxlKQogIGdnc2F2ZShvdXRwdXQuZmlsZSwgcGxvdCA9IGZpbmFsLnBsb3QsIHdpZHRoID0gMTEsIGhlaWdodCA9IDUpCiAgCn0KYGBgCgojIyMjIERpcmVjdG9yeSBzZXR1cAoKYGBge3J9CiMgcGxvdCBhbmQgcmVzdWx0IGRpcmVjdG9yeSBzZXR1cCBmb3IgdGhpcyBub3RlYm9vawpwbG90LmRpciA8LSBmaWxlLnBhdGgoInBsb3RzIiwgIjMxIikKZGlyLmNyZWF0ZShwbG90LmRpciwgcmVjdXJzaXZlID0gVFJVRSwgc2hvd1dhcm5pbmdzID0gRkFMU0UpCnJlc3VsdHMuZGlyIDwtIGZpbGUucGF0aCgicmVzdWx0cyIsICIzMSIpCmRpci5jcmVhdGUocmVzdWx0cy5kaXIsIHJlY3Vyc2l2ZSA9IFRSVUUsIHNob3dXYXJuaW5ncyA9IEZBTFNFKQpgYGAKCiMjIFJlYWQgaW4gZGF0YQoKRm9yIGJvdGggdGhlIGJpb2xvZ2ljYWwgY29udGV4dCBhbmQgc2FtcGxlIHNpemUgZXZhbHVhdGlvbnMsIHRoZSByZXN1bHRzIHdlCndpbGwgYmUgcGxvdHRpbmcgYXJlIGZyb20gYDMwLWV2YWx1YXRlX3NhbXBsZV9zaXplX2FuZF9iaW9sb2dpY2FsX2NvbnRleHRgLgoKIyMjIEJpb2xvZ2ljYWwgY29udGV4dAoKYGBge3J9CiMgcGF0aHdheSBjb3ZlcmFnZSBhbmQgcHJvcG9ydGlvbiBvZiBMVnMgYXNzb2NpYXRlZCB3aXRoIHBhdGh3YXlzCmNvbnRleHQuY292ZXJhZ2UuZmlsZSA8LSBmaWxlLnBhdGgoInJlc3VsdHMiLCAiMzAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmlvbG9naWNhbF9jb250ZXh0X3BhdGh3YXlfY292ZXJhZ2UudHN2IikKCiMgd2UnbGwgd2FudCB0byByZW9yZGVyIHRoZSBiaW9sb2dpY2FsIGNvbnRleHRzIGJ5IHNhbXBsZSBzaXplCmNvbnRleHQubGV2ZWxzIDwtIGMoImJsb29kIiwgImNhbmNlciIsICJ0aXNzdWUiLCAiY2VsbCBsaW5lIiwgIm90aGVyIHRpc3N1ZXMiKQoKY29udGV4dC5jb3ZlcmFnZS5kZiA8LSByZWFkcjo6cmVhZF90c3YoY29udGV4dC5jb3ZlcmFnZS5maWxlKSAlPiUKICAjIGNsZWFuIHVwIHRoZSBjb250ZXh0IGluZm9ybWF0aW9uIGZvciBwbG90dGluZwogIGRwbHlyOjptdXRhdGUoYmlvbG9naWNhbF9jb250ZXh0ID0gZ3N1YigiXyIsICIgIiwgYmlvbG9naWNhbF9jb250ZXh0KSkgJT4lCiAgIyByZW9yZGVyIGJ5IHRoZSBzYW1wbGUgc2l6ZSAobG93IC0+IGhpZ2gpCiAgZHBseXI6Om11dGF0ZShiaW9sb2dpY2FsX2NvbnRleHQgPSBmYWN0b3IoYmlvbG9naWNhbF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGNvbnRleHQubGV2ZWxzKSkKIyBudW1iZXIgb2YgbGF0ZW50IHZhcmlhYmxlcwpjb250ZXh0Lm51bS5maWxlIDwtIGZpbGUucGF0aCgicmVzdWx0cyIsICIzMCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmlvbG9naWNhbF9jb250ZXh0X251bWJlcl9vZl9sdnMudHN2IikKY29udGV4dC5udW0uZGYgPC0gcmVhZHI6OnJlYWRfdHN2KGNvbnRleHQubnVtLmZpbGUpICU+JQogICMgY2xlYW4gdXAgdGhlIGNvbnRleHQgaW5mb3JtYXRpb24gZm9yIHBsb3R0aW5nCiAgZHBseXI6Om11dGF0ZShiaW9sb2dpY2FsX2NvbnRleHQgPSBnc3ViKCJfIiwgIiAiLCBiaW9sb2dpY2FsX2NvbnRleHQpKSAlPiUKICAjIHJlb3JkZXIgYnkgdGhlIHNhbXBsZSBzaXplIChsb3cgLT4gaGlnaCkKICBkcGx5cjo6bXV0YXRlKGJpb2xvZ2ljYWxfY29udGV4dCA9IGZhY3RvcihiaW9sb2dpY2FsX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gY29udGV4dC5sZXZlbHMpKQpgYGAKCiMjIyBTYW1wbGUgc2l6ZSAKCmBgYHtyfQojIHBhdGh3YXkgY292ZXJhZ2UgYW5kIHByb3BvcnRpb24gb2YgTFZzIGFzc29jaWF0ZWQgd2l0aCBwYXRod2F5cwpzaXplLmNvdmVyYWdlLmZpbGUgPC0gZmlsZS5wYXRoKCJyZXN1bHRzIiwgIjMwIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN1YnNhbXBsZWRfcGF0aHdheV9jb3ZlcmFnZS50c3YiKQoKIyBvcmRlciBieSBzYW1wbGUgc2l6ZQpzaXplLmxldmVscyA8LSBjKCI1MDAiLCAiMTAwMCIsICIyMDAwIiwgIjQwMDAiLCAiODAwMCIsICIxNjAwMCIsICIzMjAwMCIpCgojIGZvciBwbG90dGluZywgd2Ugd2FudCB0aGUgc2FtcGxlIHNpemUgYXMgYSBmYWN0b3IgKG90aGVyd2lzZSBpdCdzIGhhcmQgdG8KIyBzZWUgd2hhdCBpcyBoYXBwZW5pbmcgb24gdGhlIGxvd2VyIGVuZCBvZiB0aGluZ3MpIGJ1dCB0byBvcmRlciBieSB0aGUgaW50ZWdlcgojIHZhbHVlCnNpemUuY292ZXJhZ2UuZGYgPC0gcmVhZHI6OnJlYWRfdHN2KHNpemUuY292ZXJhZ2UuZmlsZSkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKHNhbXBsZV9zaXplID0gZmFjdG9yKHNhbXBsZV9zaXplLCBsZXZlbHMgPSBzaXplLmxldmVscykpCgojIE51bWJlciBvZiBsYXRlbnQgdmFyaWFibGVzCnNpemUubnVtLmZpbGUgPC0gZmlsZS5wYXRoKCJyZXN1bHRzIiwgIjMwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgInN1YnNhbXBsZWRfbnVtYmVyX29mX2x2cy50c3YiKQpzaXplLm51bS5kZiA8LSByZWFkcjo6cmVhZF90c3Yoc2l6ZS5udW0uZmlsZSkgJT4lCiAgICAgIGRwbHlyOjptdXRhdGUoc2FtcGxlX3NpemUgPSBmYWN0b3Ioc2FtcGxlX3NpemUsIGxldmVscyA9IHNpemUubGV2ZWxzKSkKYGBgCgojIyMgTXVsdGlQTElFUgoKRm9yIHRoZSBmdWxsIHJlY291bnQyIGJpdHMsIHdlJ2xsIHVzZSB0aGUgc2FtZSB2YWx1ZXMgdGhhdCBhcmUgaW4gCmBmaWd1cmVfbm90ZWJvb2tzL3N1YnNhbXBsaW5nX2ZpZ3VyZXNgLgooVGhlIGZ1bGwgbW9kZWwgd2FzIHRyYWluZWQgb24gfjM3SyBzYW1wbGVzLCBiZWNhdXNlIHdlIHN1YnNldCByZWNvdW50MiB0bwppbmNsdWRlIG9ubHkgdGhvc2Ugc2FtcGxlcyB3aXRoIG1ldGFkYXRhLikKCmBgYHtyfQojIG51bWJlciBvZiBsYXRlbnQgdmFyaWFibGVzIGluIHRoZSBNdWx0aVBMSUVSIG1vZGVsCnJlY291bnQyLm51bS5sdnMgPC0gOTg3CiMgcGF0aHdheSBjb3ZlcmFnZQpyZWNvdW50Mi5jb3ZlcmFnZSA8LSAwLjQxODc4OTgKIyBwcm9wb3J0aW9uIG9mIHRoZSBsYXRlbnQgdmFyaWFibGVzIGFzc29jaWF0ZWQgd2l0aCBhIHBhdGh3YXkKcmVjb3VudDIubHYucHJvcCA8LSAwLjIwMTYyMTEKYGBgCgpNYWtlIGludG8gYGRhdGEuZnJhbWVzYCBmb3IgcGxvdHRpbmcgcHVycG9zZXMuIApXZSdsbCBhbHdheXMgdXNlICJjb25kaXRpb24iIGFzIG9uZSBvZiB0aGUgY29sdW1uIG5hbWVzIChzZWUgCmBUaHJlZVBsb3RzV3JhcHBlcmAgYWJvdmUpLgoKYGBge3J9CiMgcHJvcG9ydGlvbiBvZiBMVnMgYXNzb2NpYXRlZCB3aXRoIHBhdGh3YXlzCnJlY291bnQyLnByb3AuZGYgPC0gZGF0YS5mcmFtZSh2YWx1ZSA9IHJlY291bnQyLmx2LnByb3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25kaXRpb24gPSAiZnVsbCByZWNvdW50MiIpCiMgcGF0aHdheSBjb3ZlcmFnZQpyZWNvdW50Mi5jb3ZlcmFnZS5kZiA8LSBkYXRhLmZyYW1lKHZhbHVlID0gcmVjb3VudDIuY292ZXJhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uID0gImZ1bGwgcmVjb3VudDIiKQojIG51bWJlciBvZiBsYXRlbnQgdmFyaWFibGVzCnJlY291bnQyLm51bS5kZiA8LSAKICBkYXRhLmZyYW1lKG51bWJlcl9vZl9sYXRlbnRfdmFyaWFibGVzID0gYXMuaW50ZWdlcihyZWNvdW50Mi5udW0ubHZzKSwKICAgICAgICAgICAgIGNvbmRpdGlvbiA9ICJmdWxsIHJlY291bnQyIikKYGBgCgojIyBQbG90dGluZwoKIyMjIE51bWJlciBvZiBsYXRlbnQgdmFyaWFibGVzCgpgYGB7cn0KbnVtLnBsb3RzIDwtIFRocmVlUGxvdHNXcmFwcGVyKHNpemUuZGYgPSBzaXplLm51bS5kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZGYgPSBjb250ZXh0Lm51bS5kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY291bnQyLmRmID0gcmVjb3VudDIubnVtLmRmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeS52YXJpYWJsZS5uYW1lID0gIm51bWJlcl9vZl9sYXRlbnRfdmFyaWFibGVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkubGFiZWwgPSAibnVtYmVyIG9mIGxhdGVudCB2YXJpYWJsZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeS5saW1pdHMgPSAiYygwLCAxMDAwKSIpCmBgYAoKU2F2ZSB0byBmaWxlCgpgYGB7cn0KTXVsdGlQYW5lbFdyYXBwZXIoc2l6ZS5wbG90ID0gbnVtLnBsb3RzJHNpemUsCiAgICAgICAgICAgICAgICAgIGNvbnRleHQucGxvdCA9IG51bS5wbG90cyRjb250ZXh0LAogICAgICAgICAgICAgICAgICByZWNvdW50Mi5wbG90ID0gbnVtLnBsb3RzJHJlY291bnQyLAogICAgICAgICAgICAgICAgICBwbG90LnRpdGxlID0gIk51bWJlciBvZiBMYXRlbnQgVmFyaWFibGVzIiwKICAgICAgICAgICAgICAgICAgb3V0cHV0LmZpbGUgPSBmaWxlLnBhdGgocGxvdC5kaXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibnVtYmVyX29mX2xhdGVudF92YXJpYWJsZXMucGRmIikpCmBgYAoKIyMjIFBhdGh3YXkgY292ZXJhZ2UKClRoZSBzYW1wbGUgc2l6ZSBhbmQgYmlvbG9naWNhbCBjb250ZXh0IGBkYXRhLmZyYW1lc2AgY29udGFpbiB0aGUgaW5mb3JtYXRpb24KYWJvdXQgcGF0aHdheSBjb3ZlcmFnZSBfYW5kXyB0aGUgcHJvcG9ydGlvbiBvZiBMVnMgYXNzb2NpYXRlZCB3aXRoIGEgcGF0aHdheSwKc28gd2UnbGwgbmVlZCB0byBmaWx0ZXIgdGhlbSB0byB0aGUgY29ycmVjdCBtZXRyaWMuCgpgYGB7cn0KY292ZXJhZ2UucGxvdHMgPC0gCiAgVGhyZWVQbG90c1dyYXBwZXIoc2l6ZS5kZiA9IGRwbHlyOjpmaWx0ZXIoc2l6ZS5jb3ZlcmFnZS5kZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRyaWMgPT0gInBhdGh3YXkgY292ZXJhZ2UiKSwKICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmRmID0gZHBseXI6OmZpbHRlcihjb250ZXh0LmNvdmVyYWdlLmRmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpYyA9PSAicGF0aHdheSBjb3ZlcmFnZSIpLAogICAgICAgICAgICAgICAgICAgIHJlY291bnQyLmRmID0gcmVjb3VudDIuY292ZXJhZ2UuZGYsCiAgICAgICAgICAgICAgICAgICAgeS52YXJpYWJsZS5uYW1lID0gInZhbHVlIiwKICAgICAgICAgICAgICAgICAgICB5LmxhYmVsID0gInByb3BvcnRpb24gb2YgaW5wdXQgcGF0aHdheXMiKQpgYGAKCmBgYHtyfQpNdWx0aVBhbmVsV3JhcHBlcihzaXplLnBsb3QgPSBjb3ZlcmFnZS5wbG90cyRzaXplLAogICAgICAgICAgICAgICAgICBjb250ZXh0LnBsb3QgPSBjb3ZlcmFnZS5wbG90cyRjb250ZXh0LAogICAgICAgICAgICAgICAgICByZWNvdW50Mi5wbG90ID0gY292ZXJhZ2UucGxvdHMkcmVjb3VudDIsCiAgICAgICAgICAgICAgICAgIHBsb3QudGl0bGUgPSAiUGF0aHdheSBDb3ZlcmFnZSIsCiAgICAgICAgICAgICAgICAgIG91dHB1dC5maWxlID0gZmlsZS5wYXRoKHBsb3QuZGlyLCAicGF0aHdheV9jb3ZlcmFnZS5wZGYiKSkKYGBgCgojIyMgTGF0ZW50IHZhcmlhYmxlcyBzaWduaWZpY2FudGx5IGFzc29jaWF0ZWQgd2l0aCBwYXRod2F5cwoKYGBge3J9CiMgZm9yIGxpbmUgbGVuZ3RoL3N0eWxlIHB1cnBvc2VzCm1ldHJpYy50by51c2UgPC0gIkxWIGFzc29jaWF0ZWQgd2l0aCBwYXRod2F5cyIKcHJvcC5wbG90cyA8LSAKICBUaHJlZVBsb3RzV3JhcHBlcihzaXplLmRmID0gZHBseXI6OmZpbHRlcihzaXplLmNvdmVyYWdlLmRmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpYyA9PSBtZXRyaWMudG8udXNlKSwKICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmRmID0gZHBseXI6OmZpbHRlcihjb250ZXh0LmNvdmVyYWdlLmRmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldHJpYyA9PSBtZXRyaWMudG8udXNlKSwKICAgICAgICAgICAgICAgICAgICByZWNvdW50Mi5kZiA9IHJlY291bnQyLmNvdmVyYWdlLmRmLAogICAgICAgICAgICAgICAgICAgIHkudmFyaWFibGUubmFtZSA9ICJ2YWx1ZSIsCiAgICAgICAgICAgICAgICAgICAgeS5sYWJlbCA9ICJwcm9wb3J0aW9uIG9mIGxhdGVudCB2YXJpYWJsZXMiKQpgYGAKCmBgYHtyfQpNdWx0aVBhbmVsV3JhcHBlcihzaXplLnBsb3QgPSBwcm9wLnBsb3RzJHNpemUsCiAgICAgICAgICAgICAgICAgIGNvbnRleHQucGxvdCA9IHByb3AucGxvdHMkY29udGV4dCwKICAgICAgICAgICAgICAgICAgcmVjb3VudDIucGxvdCA9IHByb3AucGxvdHMkcmVjb3VudDIsCiAgICAgICAgICAgICAgICAgIHBsb3QudGl0bGUgPSAiTFZzIHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIHBhdGh3YXlzIiwKICAgICAgICAgICAgICAgICAgb3V0cHV0LmZpbGUgPSBmaWxlLnBhdGgocGxvdC5kaXIsICJsdl9wcm9wb3J0aW9uLnBkZiIpKQoKYGBgCgojIyMgRm9sbG93aW5nIHVwIG9uIHRoZSBwcm9wb3J0aW9uIG9mIExWcyBhc3NvY2lhdGVkIHdpdGggcGF0aHdheXMgcmVzdWx0cwoKSWYgd2UgbG9vayBhdCB0aGUgYHByb3AucGxvdHNgCgpgYGB7cn0KcHJvcC5wbG90cyRzaXplCnByb3AucGxvdHMkY29udGV4dApwcm9wLnBsb3RzJHJlY291bnQyCmBgYAoKV2UgY2FuIHNlZSBpbiB0aGUgc2FtcGxlIHNpemUgcGxvdCB0aGF0LCBnZW5lcmFsbHkgc3BlYWtpbmcsIHRoZSBsYXJnZXIgdGhlIApzYW1wbGUgc2l6ZSwgdGhlIGxvd2VyIHRoZSBwcm9wb3J0aW9uIG9mIGxhdGVudCB2YXJpYWJsZXMgdGhhdCBhcmUgYXNzb2NpYXRlZCAKd2l0aCBhdCBsZWFzdCBvbmUgcGF0aHdheS4KCmBQTElFUjo6UExJRVJgIGhhcyBhIHBhcmFtZXRlciwgYGZyYWNgLCB0aGF0IGRldGVybWluZXMgdGhlIGZyYWN0aW9uIG9mIGxhdGVudAp2YXJpYWJsZXMgdGhhdCBtZWV0cyB0aGF0IGNyaXRlcmlvbi4gCihgZnJhYyA9IDAuN2AgYnkgZGVmYXVsdCBpbiB0aGUgdmVyc2lvbiBvZiBQTElFUiB3ZSBoYXZlIG9uIHRoaXMgRG9ja2VyIApjb250YWluZXI7IHdlIGRpZCBub3Qgc3BlY2lmeSBgZnJhY2AuKQoKVGhpcyBwYXJhbWV0ZXIgaXMgdXNlZCB0byBzZXQgYEwzYCwgd2hpY2ggaXMgdGhlIHBlbmFsdHkgb24gYFVgIHRoYXQgY29udHJvbHMKc3BhcnNpdHkgKFtNYW8sIGV0IGFsLiBfYmlvUnhpdl8uIDIwMTcuXShodHRwOi8vZHguZG9pLm9yZy8xMC4xMTAxLzExNjA2MSkpLgpCYXNlZCBvbiBteSB1bmRlcnN0YW5kaW5nLCB0aGlzIGNvbnRyb2xzIHRoZSBwcm9wb3J0aW9uIG9mIHBvc2l0aXZlIGVudHJpZXMgaW4gCmBVYCAoaS5lLiwgdGhlIG51bWJlciBvZiBnZW5lIHNldHMgdGhhdCBhbiBMViBoYXMgc29tZSBhc3NvY2lhdGlvbiB3aXRoKSwgYnV0IAppdCBfZG9lcyBub3RfIGd1YXJhbnRlZSB0aGF0IGFsbCBvZiB0aGVzZSBhc3NvY2lhdGlvbnMgd2lsbCBiZSBzaWduaWZpY2FudAooW01hbywgZXQgYWwuIF9iaW9SeGl2Xy4gMjAxNy5dKGh0dHA6Ly9keC5kb2kub3JnLzEwLjExMDEvMTE2MDYxKSkgYW5kIAp0aGUgY3V0b2ZmIHdlIGhhcHBlbiB0byBiZSB1c2luZyAoYEZEUiA8IDAuMDVgKSBpcyBub3QgdGFrZW4gaW50byBhY2NvdW50LiAKCkZvciByZWZlcmVuY2UsIHRoaXMgaXMgdGhlIHNhbXBsZSBzaXplIGluZm9ybWF0aW9uIGZvciB0aGVzZSBkaWZmZXJlbnQgdHJhaW5pbmcKc2V0czoKCnwgQmlvbG9naWNhbCBjb25kaXRpb24gfCBTYW1wbGUgc2l6ZSB8Cnw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tLS18CnwgYmxvb2QgfCAzODYyIHwKfCBjYW5jZXIgfCA4ODA3IHwKfCB0aXNzdWUgfCAxMjM5NiB8CnwgY2VsbCBsaW5lIHwgMTQ1MzIgfAp8IG90aGVyIHRpc3N1ZXMgKG5vdCBibG9vZCkgfCAzMjk4NCB8IAoKT25jZSB3ZSB0YWtlIHRoZSBiaW9sb2dpY2FsIGNvbnRleHQgZXhwZXJpbWVudHMgaW50byBhY2NvdW50LCBpdCBnZXRzIGEgYml0Cm1vcmUgaW50ZXJlc3Rpbmc6CgoqIFRoZSBgYmxvb2RgIHRyYWluaW5nIHNldCBoYXMgfjQwMDAgc2FtcGxlcywgYnV0IG1vZGVscyB0cmFpbmVkIG9uIGJsb29kIGhhdmUgYSAKbXVjaCBoaWdoZXIgcHJvcG9ydGlvbiBvZiBsYXRlbnQgdmFyaWFibGVzIHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIApwYXRod2F5cyB0aGFuIHRoZSBtb2RlbHMgdHJhaW5lZCBvbiA0MDAwIHJhbmRvbWx5IHNlbGVjdGVkIHNhbXBsZXMuCldlJ2QgZXhwZWN0IHRoYXQgdGhlcmUnZCBiZSBsZXNzICJ0ZWNobmljYWwgbm9pc2UiIGFuZCBtb3JlICJiaW9sb2dpY2FsIHNpZ25hbCIKaW4gdGhlIGBibG9vZGAgdHJhaW5pbmcgc2V0LgpJdCdzIGFsc28gbGlrZWx5IHRvIGJlIGEgZnVuY3Rpb24gb2YgdGhlIHBhdGh3YXlzIHVuZGVyIGNvbnNpZGVyYXRpb24uIApTcGVjaWZpY2FsbHksIHdlIHN1cHBseSBpbW11bmUgY2VsbC1yZWxhdGVkIGdlbmUgc2V0cyB0byB0aGUgbW9kZWxzLCBhbmQKd2UgZXhwZWN0IGBibG9vZGAgc2FtcGxlcyB0byBiZSBfcGFydGljdWxhcmx5XyByZWxldmFudCBmb3IgdGhvc2UgZ2VuZSBzZXRzLgoqIEl0IGxvb2tzIGxpa2UgdGhlIF9tb3JlIGxhdGVudCB2YXJpYWJsZXNfLCB0aGUgX2xvd2VyIHByb3BvcnRpb24gb2YgTFZzCnNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIGEgcGF0aHdheV8gYmFzZWQgb24gdGhlIHNhbXBsZSBzaXplIHJlc3VsdHMgYWxvbmUuCkFuZCBpdCdzIGNlcnRhaW5seSB0aGUgY2FzZSB0aGF0IHRoZSBtb3JlIExWcyAtPiB0aGUgbW9yZSBwYXRod2F5cyB0aGF0IGFyZQpjYXB0dXJlZCBieSB0aGUgbW9kZWwgKGhpZ2hlciBwYXRod2F5IGNvdmVyYWdlKS4gCkhvd2V2ZXIsIGB0aXNzdWVgIG1vZGVscyBoYXZlIGhpZ2hlciBudW1iZXIgb2YgTFZzIGFuZCBtb3JlIHBhdGh3YXkgY292ZXJhZ2UKdGhhbiBgY2VsbCBsaW5lYCBtb2RlbHMgYnV0IHRoZXkgaGF2ZSBhcHByb3hpbWF0ZWx5IHRoZSBzYW1lIHByb3BvcnRpb24gb2YgTFZzCnNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIGEgcGF0aHdheS4KVGhlc2UgdmFsdWVzIGFyZSBhbHNvIHBlcmhhcHMgYSBiaXQgbG93ZXIgdGhhbiB3ZSB3b3VsZCBleHBlY3QgYmFzZWQgb24gc2FtcGxlIApzaXplIGFsb25lIChsb29raW5nIGF0IGAxNjAwMGAgZnJvbSBzYW1wbGUgc2l6ZSBwbG90KS4KCiMjIENoZWNrIGBVYCBzcGFyc2l0eQoKVG8gZm9sbG93IHVwIG9uIHRoZSBvYnNlcnZhdGlvbnMgYWJvdmUsIGxldCdzIGNoZWNrIHRoYXQsIF9pbiBwcmFjdGljZV8sIHRoZSAKZnJhY3Rpb24gb2YgdGhlIExWcyB0aGF0IGhhdmUgYXQgbGVhc3Qgb25lIGFzc29jaWF0aW9uIHdpdGggYSBwYXRod2F5IHNob3VsZCBiZQoqKn4wLjcqKi4KRmlyc3QsIHJlbW92aW5nIGV2ZXJ5dGhpbmcgZnJvbSB0aGUgd29ya3NwYWNlLgoKYGBge3J9CnJtKGxpc3QgPSBscygpKQpgYGAKCiMjIyMgQ3VzdG9tIGZ1bmN0aW9ucyBqdXN0IGZvciB0aGlzCgpgYGB7cn0KIyB0aGlzIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgd2l0aCBsaXN0cyBvZiBtb2RlbHMgb3V0cHV0IGZyb20KIyBzY3JpcHRzL3N1YnNhbXBsaW5nX1BMSUVSLlIKR2V0U3BhcnNpdHlMaXN0IDwtIGZ1bmN0aW9uKGxpc3Qub2YubW9kZWxzKSB7CiAgIyB3ZSBhc3N1bWUgdGhhdCB0aGUgbGlzdCBvZiBtb2RlbHMgaGFzIG5hbWVzCiAgCiAgIyB0aGVzZSBzcGFyc2l0eSBjYWxjdWxhdGlvbnMgYXJlIGRpZmZlcmVudCBmcm9tIHdoYXQgd2UndmUgZG9uZSBiZWZvcmUKICBDaGVja1VTcGFyc2l0eSA8LSBmdW5jdGlvbihwbGllci5tb2RlbCkgewogICAgdS5tYXRyaXggPC0gcGxpZXIubW9kZWwkVQogICAgIyB3aGF0IHByb3BvcnRpb24gb2YgdmFsdWVzIGFyZSBwb3NpdGl2ZT8KICAgIHRvdGFsLnBvc2l0aXZlIDwtIHN1bSh1Lm1hdHJpeCA+IDApIC8gKGRpbSh1Lm1hdHJpeClbMV0gKiBkaW0odS5tYXRyaXgpWzJdKQogICAgIyB3aGF0IHByb3BvcnRpb24gb2YgY29sdW1ucyBoYXZlIGF0IGxlYXN0IDEgcG9zaXRpdmUgdmFsdWUgKGFzc29jaWF0aW9uKT8KICAgIGNvbC53aXNlIDwtIHN1bShhcHBseSh1Lm1hdHJpeCwgMiwgZnVuY3Rpb24oeCkgYW55KHggPiAwKSkpIC8gbmNvbCh1Lm1hdHJpeCkKICAgIHJldHVybihsaXN0KCJvdmVyYWxsIiA9IHRvdGFsLnBvc2l0aXZlLAogICAgICAgICAgICAgICAgImNvbHVtbl93aXNlIiA9IGNvbC53aXNlKSkKICB9CiAgCiAgc3BhcnNpdHkubGlzdCA8LSBsYXBwbHkobGlzdC5vZi5tb2RlbHMsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIENoZWNrVVNwYXJzaXR5KHgkUExJRVIpKQogIAp9CgojIHdlJ2xsIHVzZSB0aGlzIHR3aWNlIC0tIG9uY2UgZm9yIGJpb2xvZ2ljYWwgY29udGV4dCBhbmQgb25jZSBmb3Igc2FtcGxlIHNpemUKIyB3ZSBhc3N1bWUgdGhhdCB0aGUgZmlsZXMudmVjdG9yIGlzIG5hbWVkCkdldFJlc3VsdHMgPC0gZnVuY3Rpb24oZmlsZXMudmVjdG9yKSB7CiAgbGFwcGx5KGZpbGVzLnZlY3RvciwgCiAgICAgICAgIGZ1bmN0aW9uKHgpIHsKICAgICAgICAgICAjIGZvciBlYWNoIGZpbGUsIHJlYWQgaW4gdGhlIGxpc3Qgb2YgbW9kZWxzCiAgICAgICAgICAgbW9kZWwubGlzdCA8LSByZWFkUkRTKHgpCiAgICAgICAgICAgIyBnZXQgdGhlIHNwYXJzaXR5IGxpc3QgZm9yIHRoZSBjdXJyZW50IGxpc3Qgb2YgbW9kZWxzCiAgICAgICAgICAgR2V0U3BhcnNpdHlMaXN0KG1vZGVsLmxpc3QpCiAgICAgICAgIH0pCn0KCmBgYAoKIyMjIyBGaWxlcwoKYGBge3J9Cm1vZGVscy5kaXIgPC0gIm1vZGVscyIKIyBzYW1wbGUgc2l6ZQpzaXplLm1vZGVsLmZpbGVzIDwtIGxpc3QuZmlsZXMobW9kZWxzLmRpciwgcGF0dGVybiA9ICJzdWJzYW1wbGVkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdWxsLm5hbWVzID0gVFJVRSkKbmFtZXMoc2l6ZS5tb2RlbC5maWxlcykgPC0gc3ViKCIuUkRTIiwgIiIsIHN1YigiLipbX10iLCAiIiwgc2l6ZS5tb2RlbC5maWxlcykpCgojIGJpb2xvZ2ljYWwgY29udGV4dApjb250ZXh0Lm1vZGVsLmZpbGVzIDwtIGxpc3QuZmlsZXMobW9kZWxzLmRpciwgcGF0dGVybiA9ICJhY2Nlc3Npb25zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bGwubmFtZXMgPSBUUlVFKQpuYW1lcyhjb250ZXh0Lm1vZGVsLmZpbGVzKSA8LSAKICBzdHJpbmdyOjpzdHJfbWF0Y2goY29udGV4dC5tb2RlbC5maWxlcywgInJlY291bnQyXyguKj8pX2FjY2Vzc2lvbnMiKVssIDJdCgpgYGAKCiMjIyMgQ2hlY2sgc3BhcnNpdHkKCmBgYHtyfQpzaXplLnJlc3VsdHMgPC0gR2V0UmVzdWx0cyhzaXplLm1vZGVsLmZpbGVzKQpzaXplLmRmIDwtIHJlc2hhcGUyOjptZWx0KHNpemUucmVzdWx0cykKc3VtbWFyeShkcGx5cjo6ZmlsdGVyKHNpemUuZGYsIEwzID09ICJjb2x1bW5fd2lzZSIpJHZhbHVlKQpgYGAKCmBgYHtyfQpjb250ZXh0LnJlc3VsdHMgPC0gR2V0UmVzdWx0cyhjb250ZXh0Lm1vZGVsLmZpbGVzKQpjb250ZXh0LmRmIDwtIHJlc2hhcGUyOjptZWx0KGNvbnRleHQucmVzdWx0cykKc3VtbWFyeShkcGx5cjo6ZmlsdGVyKGNvbnRleHQuZGYsIEwzID09ICJjb2x1bW5fd2lzZSIpJHZhbHVlKQpgYGAKClRoZXNlIHJlc3VsdHMgYXJlIGNvbnNpc3RlbnQgd2l0aCBvdXIgZXhwZWN0YXRpb25zLgo=
diff --git a/plots/31/lv_proportion.pdf b/plots/31/lv_proportion.pdf index 21d540e..91cce90 100644 Binary files a/plots/31/lv_proportion.pdf and b/plots/31/lv_proportion.pdf differ diff --git a/plots/31/number_of_latent_variables.pdf b/plots/31/number_of_latent_variables.pdf index dc341bf..c4c20c4 100644 Binary files a/plots/31/number_of_latent_variables.pdf and b/plots/31/number_of_latent_variables.pdf differ diff --git a/plots/31/pathway_coverage.pdf b/plots/31/pathway_coverage.pdf index 7c3725e..10d6e49 100644 Binary files a/plots/31/pathway_coverage.pdf and b/plots/31/pathway_coverage.pdf differ