diff --git a/RNA-seq/02-gastric_cancer_tximeta.nb.html b/RNA-seq/02-gastric_cancer_tximeta.nb.html index 960eadc4..ac9605f5 100644 --- a/RNA-seq/02-gastric_cancer_tximeta.nb.html +++ b/RNA-seq/02-gastric_cancer_tximeta.nb.html @@ -3298,8 +3298,8 @@

Summarize to gene

# Summarize to the gene level
 gene_summarized <- summarizeToGene(txi_data) 
- -
loading existing EnsDb created: 2022-09-13 21:36:34
+ +
loading existing EnsDb created: 2022-10-05 12:54:35
obtaining transcript-to-gene mapping from database
diff --git a/RNA-seq/05-nb_cell_line_DESeq2.nb.html b/RNA-seq/05-nb_cell_line_DESeq2.nb.html index f5090b10..0f67f9d2 100644 --- a/RNA-seq/05-nb_cell_line_DESeq2.nb.html +++ b/RNA-seq/05-nb_cell_line_DESeq2.nb.html @@ -3576,7 +3576,7 @@

Shrinking log2 fold change estimates

@@ -3623,7 +3623,7 @@

Making a Volcano Plot

theme(legend.position = "bottom") -

+

diff --git a/RNA-seq/06-openpbta_heatmap.nb.html b/RNA-seq/06-openpbta_heatmap.nb.html index 12f70dbd..c166a53a 100644 --- a/RNA-seq/06-openpbta_heatmap.nb.html +++ b/RNA-seq/06-openpbta_heatmap.nb.html @@ -3514,7 +3514,7 @@

Heatmap itself!

Set `ht_opt$message = FALSE` to turn off this message. -

+

diff --git a/intro-to-R-tidyverse/01-intro_to_base_R-live.Rmd b/intro-to-R-tidyverse/01-intro_to_base_R-live.Rmd index 25303b96..4baa4fa1 100644 --- a/intro-to-R-tidyverse/01-intro_to_base_R-live.Rmd +++ b/intro-to-R-tidyverse/01-intro_to_base_R-live.Rmd @@ -361,7 +361,7 @@ mean(values_1_to_20) We have learned functions such as `c`, `length`, `sum`, and etc. Imagine defining a variable called `c`: This will work, but it will lead to a -lot of unintended bugs, so its best to avoid this. +lot of unintended bugs, so it's best to avoid this. ### The `%in%` logical operator diff --git a/intro-to-R-tidyverse/01-intro_to_base_R.nb.html b/intro-to-R-tidyverse/01-intro_to_base_R.nb.html index 66fe91fd..f07bdbb9 100644 --- a/intro-to-R-tidyverse/01-intro_to_base_R.nb.html +++ b/intro-to-R-tidyverse/01-intro_to_base_R.nb.html @@ -3586,7 +3586,7 @@

A note on variable naming

We have learned functions such as c, length, sum, and etc. Imagine defining a variable called c: This will work, but it will lead to a -lot of unintended bugs, so its best to avoid this.

+lot of unintended bugs, so it’s best to avoid this.

The %in% logical operator

@@ -3958,7 +3958,7 @@

Session Info

-
LS0tCnRpdGxlOiAiSW50cm9kdWN0aW9uIHRvIFIgYW5kIFJTdHVkaW8iCmF1dGhvcjogT3JpZ2luYWxseSBhdXRob3JlZCBieSBTdGVwaGFuaWUgSi4gU3BpZWxtYW4sPGJyPmFkYXB0ZWQgYnkgQ0NETCBmb3IgQUxTRgpkYXRlOiAyMDIxCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKLS0tCgojIyBPYmplY3RpdmVzCgpUaGlzIG5vdGVib29rIHdpbGwgZGVtb25zdHJhdGUgaG93IHRvOiAgCgotIE5hdmlnYXRlIHRoZSBSU3R1ZGlvIGVudmlyb25tZW50ICAKLSBVc2UgUiBmb3Igc2ltcGxlIGNhbGN1bGF0aW9ucywgYm90aCBtYXRoZW1hdGljYWwgYW5kIGxvZ2ljYWwgIAotIERlZmluZSBhbmQgdXNlIHZhcmlhYmxlcyBpbiBiYXNlIFIgIAotIFVuZGVyc3RhbmQgYW5kIGFwcGx5IGJhc2UgUiBmdW5jdGlvbnMgICAKLSBVbmRlcnN0YW5kLCBkZWZpbmUsIGFuZCB1c2UgUiBkYXRhIHR5cGVzLCBpbmNsdWRpbmcgdmVjdG9yIG1hbmlwdWxhdGlvbiBhbmQgaW5kZXhpbmcgIAotIFVuZGVyc3RhbmQgdGhlIGFuYXRvbXkgb2YgYSBkYXRhIGZyYW1lICAKCi0tLQoKIyMjIyAqTW9yZSByZXNvdXJjZXMgZm9yIGxlYXJuaW5nIFIqIAoKLSBbU3dpcmwsIGFuIGludGVyYWN0aXZlIHR1dG9yaWFsXShodHRwczovL3N3aXJsc3RhdHMuY29tLykgIAotIFtfUiBmb3IgRGF0YSBTY2llbmNlXyBib29rXShodHRwczovL3I0ZHMuaGFkLmNvLm56LykgIAotIFtUdXRvcmlhbCBvbiBSLCBSU3R1ZGlvIGFuZCBSIE1hcmtkb3duXShodHRwczovL2lzbWF5Yy5naXRodWIuaW8vcmJhc2ljcy1ib29rLykgIAotIFtIYW5keSBSIGNoZWF0c2hlZXRzXShodHRwczovL3d3dy5yc3R1ZGlvLmNvbS9yZXNvdXJjZXMvY2hlYXRzaGVldHMvKSAgCi0gW1IgTWFya2Rvd24gd2Vic2l0ZV0oaHR0cHM6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pICAKLSBbX1IgTWFya2Rvd246IFRoZSBEZWZpbml0aXZlIEd1aWRlX10oaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvcm1hcmtkb3duLykgIAoKIyMgV2hhdCBpcyBSPwoKKipSKiogaXMgYSBzdGF0aXN0aWNhbCBjb21wdXRpbmcgbGFuZ3VhZ2UgdGhhdCBpcyBfb3BlbiBzb3VyY2VfLCBtZWFuaW5nIHRoZSB1bmRlcmx5aW5nIGNvZGUgZm9yIHRoZSBsYW5ndWFnZSBpcyBmcmVlbHkgYXZhaWxhYmxlIHRvIGFueW9uZS4gCllvdSBkbyBub3QgbmVlZCBhIHNwZWNpYWwgbGljZW5zZSBvciBzZXQgb2YgcGVybWlzc2lvbnMgdG8gdXNlIGFuZCBkZXZlbG9wIGNvZGUgaW4gUi4gCgpSIGl0c2VsZiBpcyBhbiBfaW50ZXJwcmV0ZWQgY29tcHV0ZXIgbGFuZ3VhZ2VfIGFuZCBjb21lcyB3aXRoIGZ1bmN0aW9uYWxpdHkgdGhhdCBjb21lcyBidW5kbGVkIHdpdGggdGhlIGxhbmd1YWdlIGl0c2VsZiwga25vd24gYXMgKioiYmFzZSBSIioqLgpCdXQgdGhlcmUgaXMgYWxzbyByaWNoIGFkZGl0aW9uYWwgZnVuY3Rpb25hbGl0eSBwcm92aWRlZCBieSAqKmV4dGVybmFsIHBhY2thZ2VzKiosIG9yIGxpYnJhcmllcyBvZiBjb2RlIHRoYXQgYXNzaXN0IGluIGFjY29tcGxpc2hpbmcgY2VydGFpbiB0YXNrcyBhbmQgY2FuIGJlIGZyZWVseSBkb3dubG9hZGVkIGFuZCBsb2FkZWQgZm9yIHVzZS4gCgpJbiB0aGUgbmV4dCBub3RlYm9vayBhbmQgc3Vic2VxdWVudCBtb2R1bGVzLCB3ZSB3aWxsIGJlIHVzaW5nIGEgc3VpdGUgb2YgcGFja2FnZXMgY29sbGVjdGl2ZWx5IGtub3duIGFzIFsqKlRoZSBUaWR5dmVyc2UqKl0oaHR0cHM6Ly90aWR5dmVyc2Uub3JnKS4gClRoZSBgdGlkeXZlcnNlYCBpcyBnZWFyZWQgdG93YXJkcyBpbnR1aXRpdmUgZGF0YSBzY2llbmNlIGFwcGxpY2F0aW9ucyB0aGF0IGZvbGxvdyBhIHNoYXJlZCBkYXRhIHBoaWxvc29waHkuCkJ1dCB0aGVyZSBhcmUgc3RpbGwgbWFueSBjb3JlIGZlYXR1cmVzIG9mIGJhc2UgUiB3aGljaCBhcmUgaW1wb3J0YW50IHRvIGJlIGF3YXJlIG9mLCBhbmQgd2Ugd2lsbCBiZSB1c2luZyBjb25jZXB0cyBmcm9tIGJvdGggYmFzZSBSIGFuZCB0aGUgdGlkeXZlcnNlIGluIG91ciBhbmFseXNlcywgYXMgd2VsbCBhcyB0YXNrIHNwZWNpZmljIHBhY2thZ2VzIGZvciBhbmFseXNlcyBzdWNoIGFzIGdlbmUgZXhwcmVzc2lvbi4gCgojIyMgV2hhdCBpcyBSU3R1ZGlvPwoKUlN0dWRpbyBpcyBhIF9ncmFwaGljYWwgZW52aXJvbm1lbnRfICgiaW50ZWdyYXRlZCBkZXZlbG9wbWVudCBlbnZpcm9ubWVudCIgb3IgSURFKSBmb3Igd3JpdGluZyBhbmQgZGV2ZWxvcGluZyBSIGNvZGUuIFJTdHVkaW8gaXMgTk9UIGEgc2VwYXJhdGUgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgLSBpdCBpcyBhbiBpbnRlcmZhY2Ugd2UgdXNlIHRvIGZhY2lsaXRhdGUgUiBwcm9ncmFtbWluZy4gCkluIG90aGVyIHdvcmRzLCB5b3UgY2FuIHByb2dyYW0gaW4gUiB3aXRob3V0IFJTdHVkaW8sIGJ1dCB5b3UgY2FuJ3QgdXNlIHRoZSBSU3R1ZGlvIGVudmlyb25tZW50IHdpdGhvdXQgUi4KCkZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IFJTdHVkaW8gdGhhbiB5b3UgZXZlciB3YW50ZWQgdG8ga25vdywgc2VlIHRoaXMgW1JTdHVkaW8gSURFIENoZWF0c2hlZXQgKHBkZildKGh0dHBzOi8vZ2l0aHViLmNvbS9yc3R1ZGlvL2NoZWF0c2hlZXRzL3Jhdy9tYWluL3JzdHVkaW8taWRlLnBkZikuCgojIyBUaGUgUlN0dWRpbyBFbnZpcm9ubWVudAoKVGhlIFJTdHVkaW8gZW52aXJvbm1lbnQgaGFzIGZvdXIgbWFpbiAqKnBhbmVzKiosIGVhY2ggb2Ygd2hpY2ggbWF5IGhhdmUgYSBudW1iZXIgb2YgdGFicyB0aGF0IGRpc3BsYXkgZGlmZmVyZW50IGluZm9ybWF0aW9uIG9yIGZ1bmN0aW9uYWxpdHkuICh0aGVpciBzcGVjaWZpYyBsb2NhdGlvbiBjYW4gYmUgY2hhbmdlZCB1bmRlciBUb29scyAtPiBHbG9iYWwgT3B0aW9ucyAtPiBQYW5lIExheW91dCkuCiFbUlN0dWRpbyBBcHBlYXJhbmNlXShzY3JlZW5zaG90cy9yc3R1ZGlvLXBhbmVzLnBuZykgCgoxLiBUaGUgKipFZGl0b3IqKiBwYW5lIGlzIHdoZXJlIHlvdSBjYW4gd3JpdGUgUiBzY3JpcHRzIGFuZCBvdGhlciBkb2N1bWVudHMuIEVhY2ggdGFiIGhlcmUgaXMgaXRzIG93biBkb2N1bWVudC4KVGhpcyBpcyB5b3VyIF90ZXh0IGVkaXRvcl8sIHdoaWNoIHdpbGwgYWxsb3cgeW91IHRvIHNhdmUgeW91ciBSIGNvZGUgZm9yIGZ1dHVyZSB1c2UuIApOb3RlIHRoYXQgY2hhbmdlIGNvZGUgaGVyZSB3aWxsIG5vdCBydW4gYXV0b21hdGljYWxseSB1bnRpbCB5b3UgcnVuIGl0LiAKCjIuIFRoZSAqKkNvbnNvbGUqKiBwYW5lIGlzIHdoZXJlIHlvdSBjYW4gX2ludGVyYWN0aXZlbHlfIHJ1biBSIGNvZGUuIAogICsgVGhlcmUgaXMgYWxzbyBhICoqVGVybWluYWwqKiB0YWIgaGVyZSB3aGljaCBjYW4gYmUgdXNlZCBmb3IgcnVubmluZyBwcm9ncmFtcyBvdXRzaWRlIFIgb24geW91ciBjb21wdXRlcgogIAozLiBUaGUgKipFbnZpcm9ubWVudCoqIHBhbmUgcHJpbWFyaWx5IGRpc3BsYXlzIHRoZSB2YXJpYWJsZXMsIHNvbWV0aW1lcyBrbm93biBhcyBfb2JqZWN0c18gdGhhdCBhcmUgZGVmaW5lZCBkdXJpbmcgYSBnaXZlbiBSIHNlc3Npb24sIGFuZCB3aGF0IGRhdGEgb3IgdmFsdWVzIHRoZXkgbWlnaHQgaG9sZC4KCjQuIFRoZSAqKkhlbHAgdmlld2VyKiogcGFuZSBoYXMgc2V2ZXJhbCB0YWJzIGFsbCBvZiB3aGljaCBhcmUgcHJldHR5IGltcG9ydGFudDoKICAgICsgVGhlICoqRmlsZXMqKiB0YWIgc2hvd3MgdGhlIHN0cnVjdHVyZSBhbmQgY29udGVudHMgb2YgZmlsZXMgYW5kIGZvbGRlcnMgKGFsc28ga25vd24gYXMgZGlyZWN0b3JpZXMpIG9uIHlvdXIgY29tcHV0ZXIuCiAgICArIFRoZSAqKlBsb3RzKiogdGFiIHdpbGwgcmV2ZWFsIHBsb3RzIHdoZW4geW91IG1ha2UgdGhlbQogICAgKyBUaGUgKipQYWNrYWdlcyoqIHRhYiBzaG93cyB3aGljaCBpbnN0YWxsZWQgcGFja2FnZXMgaGF2ZSBiZWVuIGxvYWRlZCBpbnRvIHlvdXIgUiBzZXNzaW9uCiAgICArIFRoZSAqKkhlbHAqKiB0YWIgd2lsbCBzaG93IHRoZSBoZWxwIHBhZ2Ugd2hlbiB5b3UgbG9vayB1cCBhIGZ1bmN0aW9uCiAgICArIFRoZSAqKlZpZXdlcioqIHBhbmUgd2lsbCByZXZlYWwgY29tcGlsZWQgUiBNYXJrZG93biBkb2N1bWVudHMgCgojIyBCYXNpYyBDYWxjdWxhdGlvbnMKCiMjIyBNYXRoZW1hdGljYWwgb3BlcmF0b3JzCgpUaGUgbW9zdCBiYXNpYyB1c2Ugb2YgUiBpcyBhcyBhIHJlZ3VsYXIgY2FsY3VsYXRvcjoKCnwgT3BlcmF0aW9uIHwgU3ltYm9sIHwKfC0tLS0tLS0tLS0tfC0tLS0tLS0tfAp8IEFkZCAgfCBgK2AgfCAKfCBTdWJ0cmFjdCAgfCBgLWAgfCAKfCBNdWx0aXBseSAgfCBgKmAgfCAKfCBEaXZpZGUgIHwgYC9gIHwgCnwgRXhwb25lbnRpYXRlIHwgYF5gIG9yIGAqKmAgfCAKCkZvciBleGFtcGxlLCB3ZSBjYW4gZG8gc29tZSBzaW1wbGUgbXVsdGlwbGljYXRpb24gbGlrZSB0aGlzLiAKV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiAKVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSAKcGxhY2luZyB5b3VyIGN1cnNvciBpbnNpZGUgaXQgYW5kIHByZXNzaW5nICpDbWQrU2hpZnQrRW50ZXIqLiAKCmBgYHtyIGNhbGN1bGF0b3J9CjUgKiA2CmBgYAoKVXNlIHRoZSBjb25zb2xlIHRvIGNhbGN1bGF0ZSBvdGhlciBleHByZXNzaW9ucy4gU3RhbmRhcmQgb3JkZXIgb2Ygb3BlcmF0aW9ucyBhcHBsaWVzIChtb3N0bHkpLCBhbmQgIHlvdSBjYW4gdXNlIHBhcmVudGhlc2VzIGAoKWAgYXMgeW91IG1pZ2h0IGV4cGVjdCAoYnV0IG5vdCBicmFja2V0cyBgW11gIG9yIGJyYWNlc2B7fWAsIHdoaWNoIGhhdmUgc3BlY2lhbCBtZWFuaW5ncykuIE5vdGUgaG93ZXZlciwgdGhhdCB5b3UgbXVzdCAqKmFsd2F5cyoqIHNwZWNpZnkgbXVsdGlwbGljYXRpb24gd2l0aCBgKmA7IGltcGxpY2l0IG11bHRpcGxpY2F0aW9uIHN1Y2ggYXMgYDEwKDMgKyA0KWAgb3IgYDEweGAgd2lsbCBub3Qgd29yayBhbmQgd2lsbCBnZW5lcmF0ZSBhbiBlcnJvciwgb3Igd29yc2UuCgpgYGB7ciBleHByZXNzaW9ucywgbGl2ZSA9IFRSVUV9CjEwICogKDMgKyA0KV4yCmBgYAoKCiMjIyBEZWZpbmluZyBhbmQgdXNpbmcgdmFyaWFibGVzIAoKVG8gZGVmaW5lIGEgdmFyaWFibGUsIHdlIHVzZSB0aGUgX2Fzc2lnbm1lbnQgb3BlcmF0b3JfIHdoaWNoIGxvb2tzIGxpa2UgYW4gYXJyb3c6IGA8LWAsIGZvciBleGFtcGxlIGB4IDwtIDdgIHRha2VzIHRoZSB2YWx1ZSBvbiB0aGUgcmlnaHQtaGFuZCBzaWRlIG9mIHRoZSBvcGVyYXRvciBhbmQgYXNzaWducyBpdCB0byB0aGUgdmFyaWFibGUgbmFtZSBvbiB0aGUgbGVmdC1oYW5kIHNpZGUuIAoKYGBge3IgdmFyLWRlZmluZSwgbGl2ZSA9IFRSVUV9CiMgRGVmaW5lIGEgdmFyaWFibGUgeCB0byBlcXVhbCA3LCBhbmQgcHJpbnQgb3V0IHRoZSB2YWx1ZSBvZiB4CnggPC0gNwoKIyBXZSBjYW4gaGF2ZSBSIHJlcGVhdCBiYWNrIHRvIHVzIHdoYXQgYHhgIGlzIGJ5IGp1c3QgdXNpbmcgYHhgCngKYGBgCgpTb21lIGZlYXR1cmVzIG9mIHZhcmlhYmxlcywgY29uc2lkZXJpbmcgdGhlIGV4YW1wbGUgYHggPC0gN2A6CkV2ZXJ5IHZhcmlhYmxlIGhhcyBhICoqbmFtZSoqLCBhICoqdmFsdWUqKiwgYW5kIGEgKip0eXBlKiouIApUaGlzIHZhcmlhYmxlJ3MgbmFtZSBpcyBgeGAsIGl0cyB2YWx1ZSBpcyBgN2AsIGFuZCBpdHMgdHlwZSBpcyBgbnVtZXJpY2AgKDcgaXMgYSBudW1iZXIhKS4KUmUtZGVmaW5pbmcgYSB2YXJpYWJsZSB3aWxsIG92ZXJ3cml0ZSB0aGUgdmFsdWUuCgpgYGB7ciB2YXItcmVkZWZpbmV9CnggPC0gNS41Cgp4CmBgYAoKV2UgY2FuIG1vZGlmeSBhbiBleGlzdGluZyB2YXJpYWJsZSBieSByZWFzc2lnbmluZyBpdCB0byBpdHMgc2FtZSBuYW1lLiAKSGVyZSB3ZSdsbCBhZGQgYDJgIHRvIGB4YCBhbmQgcmVhc3NpZ24gdGhlIHJlc3VsdCBiYWNrIHRvIGB4YC4gCgpgYGB7ciB2YXItbW9kaWZ5LCBsaXZlID0gVFJVRX0KeCA8LSB4ICsgMgoKeApgYGAKCiMjIyBWYXJpYWJsZSBuYW1pbmcgbm90ZToKQXMgYmVzdCB5b3UgY2FuLCBpdCBpcyBhIGdvb2QgaWRlYSB0byBtYWtlIHlvdXIgdmFyaWFibGUgbmFtZXMgaW5mb3JtYXRpdmUgKGUuZy4gYHhgIGRvZXNuJ3QgbWVhbiBhbnl0aGluZywgYnV0IGBzYW5kd2ljaF9wcmljZWAgaXMgbWVhbmluZ2Z1bC4uLiBpZiB3ZSdyZSB0YWxraW5nIGFib3V0IHRoZSBjb3N0IG9mIHNhbmR3aWNoZXMsIHRoYXQgaXMuLikuIAoKIyMjIENvbW1lbnRzCgpBcmd1YWJseSB0aGUgX19tb3N0IGltcG9ydGFudF9fIGFzcGVjdCBvZiB5b3VyIGNvZGluZyBpcyBjb21tZW50czogU21hbGwgcGllY2VzIG9mIGV4cGxhbmF0b3J5IHRleHQgeW91IGxlYXZlIGluIHlvdXIgY29kZSB0byBleHBsYWluIHdoYXQgdGhlIGNvZGUgaXMgZG9pbmcgYW5kL29yIGxlYXZlIG5vdGVzIHRvIHlvdXJzZWxmIG9yIG90aGVycy4gCkNvbW1lbnRzIGFyZSBpbnZhbHVhYmxlIGZvciBjb21tdW5pY2F0aW5nIHlvdXIgY29kZSB0byBvdGhlcnMsIGJ1dCB0aGV5IGFyZSBtb3N0IGltcG9ydGFudCBmb3IgKipGdXR1cmUgWW91KiouIApGdXR1cmUgWW91IGNvbWVzIGludG8gZXhpc3RlbmNlIGFib3V0IG9uZSBzZWNvbmQgYWZ0ZXIgeW91IHdyaXRlIGNvZGUsIGFuZCBoYXMgbm8gaWRlYSB3aGF0IG9uIGVhcnRoIFBhc3QgWW91IHdhcyB0aGlua2luZy4gCgpDb21tZW50cyBpbiBSIGNvZGUgYXJlIGluZGljYXRlZCB3aXRoIHBvdW5kIHNpZ25zICgqYWthKiBoYXNodGFncywgb2N0b3Rob3JwcykuIFIgd2lsbCBfaWdub3JlXyBhbnkgdGV4dCBpbiBhIGxpbmUgYWZ0ZXIgdGhlIHBvdW5kIHNpZ24sIHNvIHlvdSBjYW4gcHV0IHdoYXRldmVyIHRleHQgeW91IGxpa2UgdGhlcmUuCgpgYGB7ciBjb21tZW50c30KMjIvNyAjIG5vdCBxdWl0ZSBwaQoKIyBJZiB3ZSBuZWVkIGEgYmV0dGVyIGFwcHJveGltYXRpb24gb2YgcGksIHdlIGNhbiB1c2UgRXVsZXIncyBmb3JtdWxhCiMgVGhpcyB1c2VzIGF0YW4oKSwgd2hpY2ggY2FsY3VsYXRlcyBhcmN0YW5nZW50LgoyMCAqIGF0YW4oMS83KSArIDggKiBhdGFuKDMvNzkpIApgYGAKCkhlbHAgb3V0IEZ1dHVyZSBZb3UgYnkgYWRkaW5nIGxvdHMgb2YgY29tbWVudHMhIApGdXR1cmUgWW91IG5leHQgd2VlayB0aGlua3MgVG9kYXkgWW91IGlzIGFuIGlkaW90LCBhbmQgdGhlIG9ubHkgd2F5IHlvdSBjYW4gY29udmluY2UgRnV0dXJlIFlvdSB0aGF0IFRvZGF5IFlvdSBpcyByZWFzb25hYmx5IGNvbXBldGVudCBpcyBieSBhZGRpbmcgY29tbWVudHMgaW4geW91ciBjb2RlIGV4cGxhaW5pbmcgd2h5IFRvZGF5IFlvdSBpcyBhY3R1YWxseSBub3Qgc28gYmFkLgoKIyMgRnVuY3Rpb25zCldlIGNhbiB1c2UgcHJlLWJ1aWx0IGNvbXB1dGF0aW9uIG1ldGhvZHMgY2FsbGVkICJmdW5jdGlvbnMiIGZvciBvdGhlciBvcGVyYXRpb25zLiAKRnVuY3Rpb25zIGhhdmUgdGhlIGZvbGxvd2luZyBmb3JtYXQsIHdoZXJlIHRoZSBfYXJndW1lbnRfIGlzIHRoZSBpbmZvcm1hdGlvbiB3ZSBhcmUgcHJvdmlkaW5nIHRvIHRoZSBmdW5jdGlvbiBmb3IgaXQgdG8gcnVuLiAKQW4gZXhhbXBsZSBvZiB0aGlzIHdhcyB0aGUgYGF0YW4oKWAgZnVuY3Rpb24gdXNlZCBhYm92ZS4KCmBgYHIKZnVuY3Rpb25fbmFtZShhcmd1bWVudCkKYGBgCgpUbyBsZWFybiBhYm91dCBmdW5jdGlvbnMsIHdlJ2xsIGV4YW1pbmUgb25lIGNhbGxlZCBgbG9nKClgIGZpcnN0LiAKClRvIGtub3cgd2hhdCBhIGZ1bmN0aW9uIGRvZXMgYW5kIGhvdyB0byB1c2UgaXQsIHVzZSB0aGUgcXVlc3Rpb24gbWFyayB3aGljaCB3aWxsIHJldmVhbCBkb2N1bWVudGF0aW9uIGluIHRoZSAqKmhlbHAgcGFuZSoqOiBgP2xvZ2AKIVtyaGVscF0oc2NyZWVuc2hvdHMvcmhlbHAtbG9nLnBuZykgCgpUaGUgZG9jdW1lbnRhdGlvbiB0ZWxscyB1cyB0aGF0IGBsb2coKWAgaXMgZGVyaXZlZCBmcm9tIGB7YmFzZX1gLCBtZWFuaW5nIGl0IGlzIGEgZnVuY3Rpb24gdGhhdCBpcyBwYXJ0IG9mIGJhc2UgUi4gCkl0IHByb3ZpZGVzIGEgYnJpZWYgZGVzY3JpcHRpb24gb2Ygd2hhdCB0aGUgZnVuY3Rpb24gZG9lcyBhbmQgc2hvd3Mgc2V2ZXJhbCBleGFtcGxlcyBvZiB0byBob3cgdXNlIGl0LgoKSW4gcGFydGljdWxhciwgdGhlIGRvY3VtZW50YXRpb24gdGVsbHMgdXMgYWJvdXQgd2hhdCBhcmd1bWVudChzKSB0byBwcm92aWRlOgoKKyBUaGUgZmlyc3QgX3JlcXVpcmVkXyBhcmd1bWVudCBpcyB0aGUgdmFsdWUgd2UnZCBsaWtlIHRvIHRha2UgdGhlIGxvZyBvZiwgYnkgZGVmYXVsdCBpdHMgX25hdHVyYWwgbG9nXworIFRoZSBzZWNvbmQgX29wdGlvbmFsXyBhcmd1bWVudCBjYW4gc3BlY2lmeSBhIGRpZmZlcmVudCBiYXNlIHJhdGhlciB0aGFuIHRoZSBkZWZhdWx0IGBlYC4KCkZ1bmN0aW9ucyBhbHNvIF9yZXR1cm5fIHZhbHVlcyBmb3IgdXMgdG8gdXNlLiAKSW4gdGhlIGNhc2Ugb2YgYGxvZygpYCwgdGhlIHJldHVybmVkIHZhbHVlIGlzIHRoZSBsb2cnZCB2YWx1ZSB0aGUgZnVuY3Rpb24gY29tcHV0ZWQuCgpgYGB7ciBsb2d9CmxvZyg3MykKYGBgCgpIZXJlIHdlIGNhbiBzcGVjaWZ5IGFuIF9hcmd1bWVudF8gb2YgYGJhc2VgIHRvIGNhbGN1bGF0ZSBsb2cgYmFzZSAzLiAKCmBgYHtyIGxvZzN9CmxvZyg4MSwgYmFzZSA9IDMpCmBgYAoKSWYgd2UgZG9uJ3Qgc3BlY2lmeSB0aGUgX2FyZ3VtZW50XyBuYW1lcywgaXQgYXNzdW1lcyB0aGV5IGFyZSBpbiB0aGUgb3JkZXIgdGhhdCBgbG9nYCBkZWZpbmVzIHRoZW0uIApTZWUgYD9sb2dgIHRvIHNlZSBtb3JlIGFib3V0IGl0cyBhcmd1bWVudHMuIAoKYGBge3IgbG9nMiwgbGl2ZSA9IFRSVUV9CmxvZyg4LCAyKQpgYGAKCldlIGNhbiBzd2l0Y2ggdGhlIG9yZGVyIGlmIHdlIHNwZWNpZnkgdGhlIGFyZ3VtZW50IG5hbWVzLiAKCmBgYHtyIGxvZy1vcmRlcn0KbG9nKGJhc2UgPSAxMCwgeCA9IDQzNDIpCmBgYAoKV2UgY2FuIGFsc28gcHJvdmlkZSB2YXJpYWJsZXMgYXMgYXJndW1lbnRzIGluIHRoZSBzYW1lIHdheSBhcyB0aGUgcmF3IHZhbHVlcy4gCgpgYGB7ciBsb2ctdmFyaWFibGV9Cm1lYW5pbmcgPC0gNDIKbG9nKG1lYW5pbmcpCmBgYAoKIyMgV29ya2luZyB3aXRoIHZhcmlhYmxlcwoKIyMjIFZhcmlhYmxlIFR5cGVzCgpWYXJpYWJsZSB0eXBlcyBpbiBSIGNhbiBzb21ldGltZXMgYmUgX2NvZXJjZWRfIChjb252ZXJ0ZWQpIGZyb20gb25lIHR5cGUgdG8gYW5vdGhlci4KCmBgYHtyfQojIERlZmluZSBhIHZhcmlhYmxlIHdpdGggYSBudW1iZXIKeCA8LSAxNQpgYGAKClRoZSBmdW5jdGlvbiBgY2xhc3MoKWAgd2lsbCB0ZWxsIHVzIHRoZSB2YXJpYWJsZSdzIHR5cGUuCgpgYGB7cn0KY2xhc3MoeCkKYGBgCgpMZXQncyBjb2VyY2UgaXQgdG8gYSBjaGFyYWN0ZXIuIAoKYGBge3J9CnggPC0gYXMuY2hhcmFjdGVyKHgpCmNsYXNzKHgpCmBgYAoKU2VlIGl0IG5vdyBoYXMgcXVvdGVzIGFyb3VuZCBpdD8gSXQncyBub3cgYSBjaGFyYWN0ZXIgYW5kIHdpbGwgYmVoYXZlIGFzIHN1Y2guCgpgYGB7cn0KeApgYGAKClVzZSB0aGlzIGNodW5rIHRvIHRyeSB0byBwZXJmb3JtIGNhbGN1bGF0aW9ucyB3aXRoIGB4YCwgbm93IHRoYXQgaXQgaXMgYSBjaGFyYWN0ZXIsIHdoYXQgaGFwcGVucz8gCgpgYGB7ciBsaXZlID0gVFJVRX0KIyBUcnkgdG8gcGVyZm9ybSBjYWxjdWxhdGlvbnMgb24gYHhgCmBgYAoKQnV0IHdlIGNhbid0IGNvZXJjZSBldmVyeXRoaW5nOgoKYGBge3J9CiMgTGV0J3MgY3JlYXRlIGEgY2hhcmFjdGVyIHZhcmlhYmxlCnggPC0gImxvb2sgYXQgbXkgY2hhcmFjdGVyIHZhcmlhYmxlIgpgYGAKCkxldCdzIHRyeSBtYWtpbmcgdGhpcyBhIG51bWVyaWMgdmFyaWFibGU6CgpgYGB7ciBjb2VyY2UtY2hhciwgZXJyb3I9VFJVRX0KeCA8LSBhcy5udW1lcmljKHgpCmBgYAoKUHJpbnQgb3V0IGB4YC4KCmBgYHtyfQp4CmBgYAoKUiBpcyB0ZWxsaW5nIHVzIGl0IGRvZXNuJ3Qga25vdyBob3cgdG8gY29udmVydCB0aGlzIHRvIGEgbnVtZXJpYyB2YXJpYWJsZSwgc28gaXQgaGFzIHJldHVybmVkIGBOQWAgaW5zdGVhZC4KCkZvciByZWZlcmVuY2UsIGhlcmUncyBhIHN1bW1hcnkgb2Ygc29tZSBvZiB0aGUgbW9zdCBpbXBvcnRhbnQgdmFyaWFibGUgdHlwZXMuIAoKfCBWYXJpYWJsZSBUeXBlIHwgRGVmaW5pdGlvbiB8IEV4YW1wbGVzIHwgQ29lcmNpb24gfAp8LS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tfCAtLS0tLS0tLXwKfCBgbnVtZXJpY2AgICAgICAgfCBBbnkgbnVtYmVyIHZhbHVlIHwgYDVgPGJyPmA3LjVgIDxicj5gLTFgfCBgYXMubnVtZXJpYygpYAp8IGBpbnRlZ2VyYCAgICAgICB8IEFueSBfd2hvbGVfIG51bWJlciB2YWx1ZSAobm8gZGVjaW1hbHMpIHwgYDVgIDxicj4gYC0xMDBgIHwgYGFzLmludGVnZXIoKWAKfGBjaGFyYWN0ZXJgICAgICAgfCBBbnkgY29sbGVjdGlvbiBvZiBjaGFyYWN0ZXJzIGRlZmluZWQgd2l0aGluIF9xdW90YXRpb24gbWFya3NfLiBBbHNvIGtub3duIGFzIGEgInN0cmluZyIuIHwgYCJhImAgKGEgc2luZ2xlIGxldHRlcikgPGJyPmAic3RyaW5nb2ZsZXR0ZXJzImAgKGEgd2hvbGUgYnVuY2ggb2YgY2hhcmFjdGVycyBwdXQgdG9nZXRoZXIgYXMgb25lKSA8YnI+IGAic3RyaW5nIG9mIGxldHRlcnMgYW5kIHNwYWNlcyJgIDxicj4gYCI1ImAgPGJyPiBgJ3NpbmdsZSBxdW90ZXMgYXJlIGFsc28gZ29vZCdgIHwgYGFzLmNoYXJhY3RlcigpYAp8YGxvZ2ljYWxgICAgICAgfCBBIHZhbHVlIG9mIGBUUlVFYCwgYEZBTFNFYCwgb3IgYE5BYCB8IGBUUlVFYCA8YnI+IGBGQUxTRWAgPGJyPiBgTkFgIChub3QgZGVmaW5lZCkgfCBgYXMubG9naWNhbCgpYCAKfGBmYWN0b3JgICAgICAgIHwgQSBzcGVjaWFsIHR5cGUgb2YgdmFyaWFibGUgdGhhdCBkZW5vdGVzIHNwZWNpZmljIGNhdGVnb3JpZXMgb2YgYSBjYXRlZ29yaWNhbCB2YXJpYWJsZSB8IChzdGF5IHR1bmVkLi4pIHwgYGFzLmZhY3RvcigpYAoKIyMjIFZlY3RvcnMKCllvdSB3aWxsIGhhdmUgbm90aWNlZCB0aGF0IGFsbCB5b3VyIGNvbXB1dGF0aW9ucyB0ZW5kIHRvIHBvcCB1cCB3aXRoIGEgYFsxXWAgcHJlY2VkaW5nIHRoZW0gaW4gUidzIG91dHB1dC4gClRoaXMgaXMgYmVjYXVzZSwgaW4gZmFjdCwgYWxsIChvayBtb3N0bHkgYWxsKSB2YXJpYWJsZXMgYXJlIF9ieSBkZWZhdWx0XyAgdmVjdG9ycywgYW5kIG91ciBhbnN3ZXJzIGFyZSB0aGUgZmlyc3QgKGluIHRoZXNlIGNhc2VzIG9ubHkpIHZhbHVlIGluIHRoZSB2ZWN0b3IuIApBcyB2ZWN0b3JzIGdldCBsb25nZXIsIG5ldyBpbmRleCBpbmRpY2F0b3JzIHdpbGwgYXBwZWFyIGF0IHRoZSBzdGFydCBvZiBuZXcgbGluZXMuIAoKYGBge3J9CiMgVGhpcyBpcyBhY3R1YWxseSBhbiB2ZWN0b3IgdGhhdCBoYXMgb25lIGl0ZW0gaW4gaXQuCnggPC0gNwpgYGAKCmBgYHtyIHZlY3Rvci1sZW5ndGh9CiMgVGhlIGxlbmd0aCgpIGZ1bmN0aW9ucyB0ZWxscyB1cyBob3cgbG9uZyBhbiB2ZWN0b3IgaXM6Cmxlbmd0aCh4KQpgYGAKCldlIGNhbiBkZWZpbmUgdmVjdG9ycyB3aXRoIHRoZSBmdW5jdGlvbiBgYygpYCwgd2hpY2ggc3RhbmRzIGZvciAiY29tYmluZSIuIApUaGlzIGZ1bmN0aW9uIHRha2VzIGEgY29tbWEtc2VwYXJhdGVkIHNldCBvZiB2YWx1ZXMgdG8gcGxhY2UgaW4gdGhlIHZlY3RvciwgYW5kIHJldHVybnMgdGhlIHZlY3RvciBpdHNlbGY6CgpgYGB7ciBtYWtlLXZlY3Rvcn0KbXlfbnVtZXJpY192ZWN0b3IgPC0gYygxLCAxLCAyLCAzLCA1LCA4LCAxMywgMjEpCm15X251bWVyaWNfdmVjdG9yCmBgYAoKV2UgY2FuIGJ1aWxkIG9uIHZlY3RvcnMgaW4gcGxhY2UgYnkgcmVkZWZpbmluZyB0aGVtOgoKYGBge3IgZmliYm9uYWNjaSwgbGl2ZSA9IFRSVUV9CiMgYWRkIHRoZSBuZXh0IHR3byBGaWJvbmFjY2kgbnVtYmVycyB0byB0aGUgc2VyaWVzLgpteV9udW1lcmljX3ZlY3RvciA8LSBjKG15X251bWVyaWNfdmVjdG9yLCAzNCwgNTUpCm15X251bWVyaWNfdmVjdG9yCmBgYAoKV2UgY2FuIHB1bGwgb3V0IHNwZWNpZmljIGl0ZW1zIGZyb20gYW4gdmVjdG9yIHVzaW5nIGEgcHJvY2VzcyBjYWxsZWQgX2luZGV4aW5nXywgd2hpY2ggdXNlcyBicmFja2V0cyBgW11gIHRvIHNwZWNpZnkgdGhlIHBvc2l0aW9uIG9mIGFuIGl0ZW0uIAoKYGBge3Igc3Vic2V0MX0KIyBHcmFiIHRoZSBmb3VydGggdmFsdWUgZnJvbSBteV9udW1lcmljX3ZlY3RvcgojIFRoaXMgZ2l2ZXMgdXMgYW4gdmVjdG9yIG9mIGxlbmd0aCAxIApteV9udW1lcmljX3ZlY3Rvcls0XQpgYGAKCkNvbG9ucyBhcmUgYWxzbyBhIG5pY2Ugd2F5IHRvIHF1aWNrbHkgbWFrZSBvcmRlcmVkIG51bWVyaWMgdmVjdG9ycwpVc2UgYSBjb2xvbiB0byBzcGVjaWZ5IGFuIGluY2x1c2l2ZSByYW5nZSBvZiBpbmRpY2VzClRoaXMgd2lsbCByZXR1cm4gYW4gdmVjdG9yIHdpdGggMiwgMywgNCwgYW5kIDUuCgpgYGB7ciBzdWJzZXQtbWFueX0KbXlfbnVtZXJpY192ZWN0b3JbMjo1XQpgYGAKCk9uZSBtYWpvciBiZW5lZml0IG9mIHZlY3RvcnMgaXMgdGhlIGNvbmNlcHQgb2YgKip2ZWN0b3JpemF0aW9uKiosIHdoZXJlIFIgYnkgZGVmYXVsdCBwZXJmb3JtcyBvcGVyYXRpb25zIG9uIHRoZSBfZW50aXJlIHZlY3RvciBhdCBvbmNlXy4gCkZvciBleGFtcGxlLCB3ZSBjYW4gZ2V0IHRoZSBsb2cgb2YgYWxsIG51bWJlcnMgMS0yMCB3aXRoIGEgc2luZ2xlLCBzaW1wbGUgY2FsbCwgYW5kIG1vcmUhCgpgYGB7ciB2ZWN0b3JpemV9CnZhbHVlc18xX3RvXzIwIDwtIDE6MjAKYGBgCgoKYGBge3IgdmVjdG9yaXplLWxvZywgbGl2ZSA9IFRSVUV9CiMgY2FsY3VsYXRlIHRoZSBsb2cgb2YgdmFsdWVzXzFfdG9fMjAKbG9nKHZhbHVlc18xX3RvXzIwKQpgYGAKCkZpbmFsbHksIHdlIGNhbiBhcHBseSBsb2dpY2FsIGV4cHJlc3Npb25zIHRvIHZlY3RvcnMsIGp1c3QgYXMgd2UgY2FuIGRvIGZvciBzaW5nbGUgdmFsdWVzLgpUaGUgb3V0cHV0IGhlcmUgaXMgYSBsb2dpY2FsIHZlY3RvciB0ZWxsaW5nIHVzIHdoZXRoZXIgZWFjaCB2YWx1ZSBpbiBleGFtcGxlX3ZlY3RvciBpcyBUUlVFIG9yIEZBTFNFCgpgYGB7ciB2ZWN0b3ItY29tcGFyZX0KIyBXaGljaCB2YWx1ZXMgYXJlIDw9IDM/CnZhbHVlc18xX3RvXzIwIDw9IDMKYGBgCgpUaGVyZSBhcmUgc2V2ZXJhbCBrZXkgZnVuY3Rpb25zIHdoaWNoIGNhbiBiZSB1c2VkIG9uIHZlY3RvcnMgY29udGFpbmluZyBudW1lcmljIHZhbHVlcywgc29tZSBvZiB3aGljaCBhcmUgYmVsb3cuCgorIGBtZWFuKClgOiBUaGUgYXZlcmFnZSB2YWx1ZSBpbiB0aGUgdmVjdG9yCisgYG1pbigpYDogVGhlIG1pbmltdW0gdmFsdWUgaW4gdGhlIHZlY3RvcgorIGBtYXgoKWA6IFRoZSBtYXhpbXVtIHZhbHVlIGluIHRoZSB2ZWN0b3IKKyBgc3VtKClgOiBUaGUgc3VtIG9mIGFsbCB2YWx1ZXMgaW4gdGhlIHZlY3RvcgoKV2UgY2FuIHRyeSBvdXQgdGhlc2UgZnVuY3Rpb25zIG9uIHRoZSB2ZWN0b3IgYHZhbHVlc18xX3RvXzIwYCB3ZSd2ZSBjcmVhdGVkLiAKCmBgYHtyIHZlY3Rvci1mdW5jc30KbWVhbih2YWx1ZXNfMV90b18yMCkKCiMgVHJ5IG91dCBzb21lIG9mIHRoZSBvdGhlciBmdW5jdGlvbnMgd2UndmUgbGlzdGVkIGFib3ZlIAoKYGBgCgojIyMgQSBub3RlIG9uIHZhcmlhYmxlIG5hbWluZwoKV2UgaGF2ZSBsZWFybmVkIGZ1bmN0aW9ucyBzdWNoIGFzIGBjYCwgYGxlbmd0aGAsIGBzdW1gLCBhbmQgZXRjLiAKSW1hZ2luZSBkZWZpbmluZyBhIHZhcmlhYmxlIGNhbGxlZCBgY2A6IFRoaXMgd2lsbCB3b3JrLCBidXQgaXQgd2lsbCBsZWFkIHRvIGEgCmxvdCBvZiB1bmludGVuZGVkIGJ1Z3MsIHNvIGl0cyBiZXN0IHRvIGF2b2lkIHRoaXMuIAoKIyMjIFRoZSBgJWluJWAgbG9naWNhbCBvcGVyYXRvciAKCmAlaW4lYCBpcyB1c2VmdWwgZm9yIGRldGVybWluaW5nIHdoZXRoZXIgYSBnaXZlbiBpdGVtKHMpIGFyZSBpbiBhbiB2ZWN0b3IuCgpgYGB7ciBpbi1vcGVyYXRvcn0KIyBpcyBgN2AgaW4gb3VyIHZlY3Rvcj8gCjcgJWluJSB2YWx1ZXNfMV90b18yMApgYGAKCmBgYHtyIGluMiwgbGl2ZSA9IFRSVUV9CiMgaXMgYDUwYCBpbiBvdXIgdmVjdG9yPyAKNTAgJWluJSB2YWx1ZXNfMV90b18yMApgYGAKCldlIGNhbiB0ZXN0IGEgdmVjdG9yIG9mIHZhbHVlcyBiZWluZyB3aXRoaW4gYW5vdGhlciB2ZWN0b3Igb2YgdmFsdWVzLiAKCmBgYHtyIHZlY3Rvci1pbiwgbGl2ZSA9IFRSVUV9CnF1ZXN0aW9uX3ZhbHVlcyA8LSBjKDE6MywgNywgNTApCiMgQXJlIHRoZXNlIHZhbHVlcyBpbiBvdXIgdmVjdG9yPwpxdWVzdGlvbl92YWx1ZXMgJWluJSB2YWx1ZXNfMV90b18yMApgYGAKCiMjIERhdGEgZnJhbWVzCgpfRGF0YSBmcmFtZXMgYXJlIG9uZSBvZiB0aGUgbW9zdCB1c2VmdWwgdG9vbHMgZm9yIGRhdGEgYW5hbHlzaXMgaW4gUi5fIApUaGV5IGFyZSB0YWJsZXMgd2hpY2ggY29uc2lzdCBvZiByb3dzIGFuZCBjb2x1bW5zLCBtdWNoIGxpa2UgYSBfc3ByZWFkc2hlZXRfLiAKRWFjaCBjb2x1bW4gaXMgYSB2YXJpYWJsZSB3aGljaCBiZWhhdmVzIGFzIGEgX3ZlY3Rvcl8sIGFuZCBlYWNoIHJvdyBpcyBhbiBvYnNlcnZhdGlvbi4gCldlIHdpbGwgYmVnaW4gb3VyIGV4cGxvcmF0aW9uIHdpdGggZGF0YXNldCBvZiBtZWFzdXJlbWVudHMgZnJvbSB0aHJlZSBwZW5ndWluIHNwZWNpZXMgbWVhc3VyZWQsIHdoaWNoIHdlIGNhbiBmaW5kIGluIHRoZSBbYHBhbG1lcnBlbmd1aW5zYCBwYWNrYWdlXShodHRwczovL2FsbGlzb25ob3JzdC5naXRodWIuaW8vcGFsbWVycGVuZ3VpbnMvKS4gCldlJ2xsIHRhbGsgbW9yZSBhYm91dCBwYWNrYWdlcyBzb29uIQpUbyB1c2UgdGhpcyBkYXRhc2V0LCB3ZSB3aWxsIGxvYWQgaXQgZnJvbSB0aGUgYHBhbG1lcnBlbmd1aW5zYCBwYWNrYWdlIHVzaW5nIGEgYDo6YCAobW9yZSBvbiB0aGlzIGxhdGVyKSBhbmQgYXNzaWduIGl0IHRvIGEgdmFyaWFibGUgbmFtZWQgYHBlbmd1aW5zYCBpbiBvdXIgY3VycmVudCBlbnZpcm9ubWVudC4KCmBgYHtyIHBlbmd1aW4tbGlicmFyeX0KcGVuZ3VpbnMgPC0gcGFsbWVycGVuZ3VpbnM6OnBlbmd1aW5zCmBgYAoKIVtkcmF3aW5ncyBvZiBwZW5ndWluIHNwZWNpZXNdKGRpYWdyYW1zL2x0ZXJfcGVuZ3VpbnMucG5nKSBBcnR3b3JrIGJ5IFtAYWxsaXNvbl9ob3JzdF0oaHR0cHM6Ly90d2l0dGVyLmNvbS9hbGxpc29uX2hvcnN0KQoKIyMjIEV4cGxvcmluZyBkYXRhIGZyYW1lcwoKVGhlIGZpcnN0IHN0ZXAgdG8gdXNpbmcgYW55IGRhdGEgaXMgdG8gbG9vayBhdCBpdCEhISAKUlN0dWRpbyBjb250YWlucyBhIHNwZWNpYWwgZnVuY3Rpb24gYFZpZXcoKWAgd2hpY2ggYWxsb3dzIHlvdSB0byBsaXRlcmFsbHkgdmlldyBhIHZhcmlhYmxlLgpZb3UgY2FuIGFsc28gY2xpY2sgb24gdGhlIG9iamVjdCBpbiB0aGUgZW52aXJvbm1lbnQgcGFuZSB0byBzZWUgaXRzIG92ZXJhbGwgcHJvcGVydGllcywgb3IgY2xpY2sgdGhlIHRhYmxlIGljb24gb24gdGhlIG9iamVjdCdzIHJvdyB0byBhdXRvbWF0aWNhbGx5IHZpZXcgdGhlIHZhcmlhYmxlLiAKClNvbWUgdXNlZnVsIGZ1bmN0aW9ucyBmb3IgZXhwbG9yaW5nIG91ciBkYXRhIGZyYW1lIGluY2x1ZGU6CgorIGBoZWFkKClgIHRvIHNlZSB0aGUgZmlyc3QgNiByb3dzIG9mIGEgZGF0YSBmcmFtZS4gQWRkaXRpb25hbCBhcmd1bWVudHMgc3VwcGxpZWQgY2FuIGNoYW5nZSB0aGUgbnVtYmVyIG9mIHJvd3MuCisgYHRhaWwoKWAgdG8gc2VlIHRoZSBsYXN0IDYgcm93cyBvZiBhIGRhdGEgZnJhbWUuIEFkZGl0aW9uYWwgYXJndW1lbnRzIHN1cHBsaWVkIGNhbiBjaGFuZ2UgdGhlIG51bWJlciBvZiByb3dzLgorIGBuYW1lcygpYCB0byBzZWUgdGhlIGNvbHVtbiBuYW1lcyBvZiB0aGUgZGF0YSBmcmFtZS4KKyBgbnJvdygpYCB0byBzZWUgaG93IG1hbnkgcm93cyBhcmUgaW4gdGhlIGRhdGEgZnJhbWUKKyBgbmNvbCgpYCB0byBzZWUgaG93IG1hbnkgY29sdW1ucyBhcmUgaW4gdGhlIGRhdGEgZnJhbWUuCgpXZSBjYW4gYWRkaXRpb25hbGx5IGV4cGxvcmUgX292ZXJhbGwgcHJvcGVydGllc18gb2YgdGhlIGRhdGEgZnJhbWUgd2l0aCB0d28gZGlmZmVyZW50IGZ1bmN0aW9uczogYHN1bW1hcnkoKWAgYW5kIGBzdHIoKWAuCgpUaGlzIHByb3ZpZGVzIHN1bW1hcnkgc3RhdGlzdGljcyBmb3IgZWFjaCBjb2x1bW46CgpgYGB7ciBwZW5ndWlucy1zdW1tYXJ5fQpzdW1tYXJ5KHBlbmd1aW5zKQpgYGAKClRoaXMgcHJvdmlkZXMgYSBzaG9ydCB2aWV3IG9mIHRoZSAqKnN0cioqdWN0dXJlIGFuZCBjb250ZW50cyBvZiB0aGUgZGF0YSBmcmFtZS4KCmBgYHtyIHBlbmd1aW5zLXN0cn0Kc3RyKHBlbmd1aW5zKQpgYGAKCllvdSdsbCBub3RpY2UgdGhhdCB0aGUgY29sdW1uIGBzcGVjaWVzYCBpcyBhIF9mYWN0b3JfOiBUaGlzIGlzIGEgc3BlY2lhbCB0eXBlIG9mIGNoYXJhY3RlciB2YXJpYWJsZSB0aGF0IHJlcHJlc2VudHMgZGlzdGluY3QgY2F0ZWdvcmllcyBrbm93biBhcyAibGV2ZWxzIi4gCldlIGhhdmUgbGVhcm5lZCBoZXJlIHRoYXQgdGhlcmUgYXJlIHRocmVlIGxldmVscyBpbiB0aGUgYHNwZWNpZXNgIGNvbHVtbjogQWRlbGllLCBDaGluc3RyYXAsIGFuZCBHZW50b28uCldlIG1pZ2h0IHdhbnQgdG8gZXhwbG9yZSBpbmRpdmlkdWFsIGNvbHVtbnMgb2YgdGhlIGRhdGEgZnJhbWUgbW9yZSBpbi1kZXB0aC4gCldlIGNhbiBleGFtaW5lIGluZGl2aWR1YWwgY29sdW1ucyB1c2luZyB0aGUgZG9sbGFyIHNpZ24gYCRgIHRvIHNlbGVjdCBvbmUgYnkgbmFtZToKCmBgYHtyIHBlbmd1aW5zLXN1YnNldH0KIyBFeHRyYWN0IGJpbGxfbGVuZ3RoX21tIGFzIGEgdmVjdG9yCnBlbmd1aW5zJGJpbGxfbGVuZ3RoX21tCgojIGluZGV4aW5nIG9wZXJhdG9ycyBjYW4gYmUgdXNlZCBvbiB0aGVzZSB2ZWN0b3JzIHRvbwpwZW5ndWlucyRiaWxsX2xlbmd0aF9tbVsxOjEwXQpgYGAKCldlIGNhbiBwZXJmb3JtIG91ciByZWd1bGFyIHZlY3RvciBvcGVyYXRpb25zIG9uIGNvbHVtbnMgZGlyZWN0bHkuCgpgYGB7ciBwZW5ndWlucy1jb2wtbWVhbiwgbGl2ZSA9IFRSVUV9CiMgY2FsY3VsYXRlIHRoZSBtZWFuIG9mIHRoZSBiaWxsX2xlbmd0aF9tbSBjb2x1bW4KbWVhbihwZW5ndWlucyRiaWxsX2xlbmd0aF9tbSwKICAgICBuYS5ybSA9IFRSVUUpICMgcmVtb3ZlIG1pc3NpbmcgdmFsdWVzIGJlZm9yZSBjYWxjdWxhdGluZyB0aGUgbWVhbgpgYGAKCldlIGNhbiBhbHNvIGNhbGN1bGF0ZSB0aGUgZnVsbCBzdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGEgc2luZ2xlIGNvbHVtbiBkaXJlY3RseS4gCgpgYGB7ciBwZW5ndWlucy1jb2wtc3VtbWFyeSwgbGl2ZSA9IFRSVUV9CiMgc2hvdyBhIHN1bW1hcnkgb2YgdGhlIGJpbGxfbGVuZ3RoX21tIGNvbHVtbgpzdW1tYXJ5KHBlbmd1aW5zJGJpbGxfbGVuZ3RoX21tKQpgYGAKCkV4dHJhY3QgYFNwZWNpZXNgIGFzIGEgdmVjdG9yIGFuZCBzdWJzZXQgaXQgdG8gc2VlIGEgcHJldmlldy4KCmBgYHtyIHBlbmd1aW5zLWNvbC1zdWJzZXQsIGxpdmUgPSBUUlVFfQojIGdldCB0aGUgZmlyc3QgMTAgdmFsdWVzIG9mIHRoZSBzcGVjaWVzIGNvbHVtbgpwZW5ndWlucyRzcGVjaWVzWzE6MTBdCmBgYAoKQW5kIHZpZXcgaXRzIF9sZXZlbHNfIHdpdGggdGhlIGBsZXZlbHMoKWAgZnVuY3Rpb24uCgpgYGB7ciBwZW5ndWluLWxldmVsc30KbGV2ZWxzKHBlbmd1aW5zJHNwZWNpZXMpCmBgYAoKIyMgRmlsZXMgYW5kIGRpcmVjdG9yaWVzCgpJbiBtYW55IHNpdHVhdGlvbnMsIHdlIHdpbGwgYmUgcmVhZGluZyBpbiB0YWJ1bGFyIGRhdGEgZnJvbSBhIGZpbGUgYW5kIHVzaW5nIGl0IGFzIGEgZGF0YSBmcmFtZS4gClRvIHByYWN0aWNlLCB3ZSB3aWxsIHJlYWQgaW4gYSBmaWxlIHdlIHdpbGwgYmUgdXNpbmcgaW4gdGhlIG5leHQgbm90ZWJvb2sgYXMgd2VsbCwgYGdlbmVfcmVzdWx0c19HU0U0NDk3MS50c3ZgLCBpbiB0aGUgYGRhdGFgIGZvbGRlci4gCkZpbGUgcGF0aHMgYXJlIHJlbGF0aXZlIHRvIHRoZSBsb2NhdGlvbiB3aGVyZSB0aGlzIG5vdGVib29rIGZpbGUgKC5SbWQpIGlzIHNhdmVkLgoKSGVyZSB3ZSB3aWxsIHVzZSBhIGZ1bmN0aW9uLCBgcmVhZF90c3YoKWAgZnJvbSB0aGUgYHJlYWRyYCBwYWNrYWdlLgpCZWZvcmUgd2UgYXJlIGFibGUgdG8gdXNlIHRoZSBmdW5jdGlvbiwgd2UgaGF2ZSB0byBsb2FkIHRoZSBwYWNrYWdlIHVzaW5nIGBsaWJyYXJ5KClgLiAKCmBgYHtyIHJlYWRyfQpsaWJyYXJ5KHJlYWRyKQpgYGAKCmBmaWxlLnBhdGgoKWAgY3JlYXRlcyBhIHByb3Blcmx5IGZvcm1hdHRlZCBmaWxlIHBhdGggYnkgYWRkaW5nIGEgcGF0aCBzZXBhcmF0b3IgKGAvYCBvbiBNYWMgYW5kIExpbnV4IG9wZXJhdGluZyBzeXN0ZW1zLCB0aGUgbGF0dGVyIG9mIHdoaWNoIGlzIHRoZSBvcGVyYXRpbmcgc3lzdGVtIHRoYXQgb3VyIFJTdHVkaW8gU2VydmVyIHJ1bnMgb24pIGJldHdlZW4gc2VwYXJhdGUgZm9sZGVycyBvciBkaXJlY3Rvcmllcy4KQmVjYXVzZSBmaWxlIHBhdGggc2VwYXJhdG9ycyBjYW4gZGlmZmVyIGJldHdlZW4geW91ciBjb21wdXRlciBhbmQgdGhlIGNvbXB1dGVyIG9mIHNvbWVvbmUgd2hvIHdhbnRzIHRvIHVzZSB5b3VyIGNvZGUsIHdlIHVzZSBgZmlsZS5wYXRoKClgIGluc3RlYWQgb2YgdHlwaW5nIG91dCBgImRhdGEvZ2VuZV9yZXN1bHRzX0dTRTQ0OTcxLnRzdiJgLgpFYWNoIF9hcmd1bWVudF8gdG8gYGZpbGUucGF0aCgpYCBpcyBhIGRpcmVjdG9yeSBvciBmaWxlIG5hbWUuCllvdSdsbCBub3RpY2UgZWFjaCBhcmd1bWVudCBpcyBpbiBxdW90ZXMsIHdlIHNwZWNpZnkgYGRhdGFgIGZpcnN0IGJlY2F1c2UgdGhlIGZpbGUsIGBnZW5lX3Jlc3VsdHNfR1NFNDQ5NzEudHN2YCBpcyBpbiB0aGUgYGRhdGFgIGZvbGRlci4gCgpgYGB7ciBmaWxlLnBhdGh9CmZpbGUucGF0aCgiZGF0YSIsICJnZW5lX3Jlc3VsdHNfR1NFNDQ5NzEudHN2IikKYGBgCgpXZSBjYW4gc3RvcmUgdGhpcyBmaWxlIHBhdGggYXMgYSB2YXJpYWJsZSBpbiBvdXIgZW52aXJvbm1lbnQuIAoKYGBge3IgZmlsZS5wYXRoLXZhcmlhYmxlfQpnZW5lX2ZpbGVfcGF0aCA8LSBmaWxlLnBhdGgoImRhdGEiLCAiZ2VuZV9yZXN1bHRzX0dTRTQ0OTcxLnRzdiIpCmBgYAoKTm93IHdlIGFyZSByZWFkeSB0byB1c2UgYHJlYWRfdHN2KClgIHRvIHJlYWQgdGhlIGZpbGUgaW50byBSLgpUaGUgcmVzdWx0aW5nIGRhdGEgZnJhbWUgd2lsbCBiZSBzdG9yZWQgaW4gYSB2YXJpYWJsZSBuYW1lZCBgc3RhdHNfZGZgLgpOb3RlIHRoZSBgPC1gIChhc3NpZ25tZW50IG9wZXJhdG9yISkgaXMgcmVzcG9uc2libGUgZm9yIHNhdmluZyB0aGlzIHRvIG91ciBnbG9iYWwgZW52aXJvbm1lbnQuIAoKYGBge3IgcmVhZC1zdGF0c30KIyByZWFkIGluIHRoZSBmaWxlIGBnZW5lX3Jlc3VsdHNfR1NFNDQ5NzEudHN2YCBmcm9tIHRoZSBkYXRhIGRpcmVjdG9yeQpzdGF0c19kZiA8LSByZWFkX3RzdihnZW5lX2ZpbGVfcGF0aCkKYGBgCgpUYWtlIGEgbG9vayBhdCB5b3VyIGVudmlyb25tZW50IHBhbmVsIHRvIHNlZSB3aGF0IGBzdGF0c19kZmAgbG9va3MgbGlrZS4gCldlIGNhbiBhbHNvIHByaW50IG91dCBhIHByZXZpZXcgb2YgdGhlIGBzdGF0c19kZmAgZGF0YSBmcmFtZSBoZXJlLiAKCmBgYHtyIHNob3ctc3RhdHMsIGxpdmUgPSBUUlVFfQojIGRpc3BsYXkgc3RhdHNfZGYKc3RhdHNfZGYKYGBgCgojIyMgU2Vzc2lvbiBJbmZvCgpBdCB0aGUgZW5kIG9mIGV2ZXJ5IG5vdGVib29rLCB5b3Ugd2lsbCBzZWUgdXMgcHJpbnQgb3V0IGBzZXNzaW9uSW5mb2AuIApUaGlzIGFpZHMgaW4gdGhlIHJlcHJvZHVjaWJpbGl0eSBvZiB5b3VyIGNvZGUgYnkgc2hvd2luZyBleGFjdGx5IHdoYXQgcGFja2FnZXMgCmFuZCB2ZXJzaW9ucyB3ZXJlIGJlaW5nIHVzZWQgdGhlIGxhc3QgdGltZSB0aGUgbm90ZWJvb2sgd2FzIHJ1bi4KCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAo=
+
LS0tCnRpdGxlOiAiSW50cm9kdWN0aW9uIHRvIFIgYW5kIFJTdHVkaW8iCmF1dGhvcjogT3JpZ2luYWxseSBhdXRob3JlZCBieSBTdGVwaGFuaWUgSi4gU3BpZWxtYW4sPGJyPmFkYXB0ZWQgYnkgQ0NETCBmb3IgQUxTRgpkYXRlOiAyMDIxCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKLS0tCgojIyBPYmplY3RpdmVzCgpUaGlzIG5vdGVib29rIHdpbGwgZGVtb25zdHJhdGUgaG93IHRvOiAgCgotIE5hdmlnYXRlIHRoZSBSU3R1ZGlvIGVudmlyb25tZW50ICAKLSBVc2UgUiBmb3Igc2ltcGxlIGNhbGN1bGF0aW9ucywgYm90aCBtYXRoZW1hdGljYWwgYW5kIGxvZ2ljYWwgIAotIERlZmluZSBhbmQgdXNlIHZhcmlhYmxlcyBpbiBiYXNlIFIgIAotIFVuZGVyc3RhbmQgYW5kIGFwcGx5IGJhc2UgUiBmdW5jdGlvbnMgICAKLSBVbmRlcnN0YW5kLCBkZWZpbmUsIGFuZCB1c2UgUiBkYXRhIHR5cGVzLCBpbmNsdWRpbmcgdmVjdG9yIG1hbmlwdWxhdGlvbiBhbmQgaW5kZXhpbmcgIAotIFVuZGVyc3RhbmQgdGhlIGFuYXRvbXkgb2YgYSBkYXRhIGZyYW1lICAKCi0tLQoKIyMjIyAqTW9yZSByZXNvdXJjZXMgZm9yIGxlYXJuaW5nIFIqIAoKLSBbU3dpcmwsIGFuIGludGVyYWN0aXZlIHR1dG9yaWFsXShodHRwczovL3N3aXJsc3RhdHMuY29tLykgIAotIFtfUiBmb3IgRGF0YSBTY2llbmNlXyBib29rXShodHRwczovL3I0ZHMuaGFkLmNvLm56LykgIAotIFtUdXRvcmlhbCBvbiBSLCBSU3R1ZGlvIGFuZCBSIE1hcmtkb3duXShodHRwczovL2lzbWF5Yy5naXRodWIuaW8vcmJhc2ljcy1ib29rLykgIAotIFtIYW5keSBSIGNoZWF0c2hlZXRzXShodHRwczovL3d3dy5yc3R1ZGlvLmNvbS9yZXNvdXJjZXMvY2hlYXRzaGVldHMvKSAgCi0gW1IgTWFya2Rvd24gd2Vic2l0ZV0oaHR0cHM6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pICAKLSBbX1IgTWFya2Rvd246IFRoZSBEZWZpbml0aXZlIEd1aWRlX10oaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvcm1hcmtkb3duLykgIAoKIyMgV2hhdCBpcyBSPwoKKipSKiogaXMgYSBzdGF0aXN0aWNhbCBjb21wdXRpbmcgbGFuZ3VhZ2UgdGhhdCBpcyBfb3BlbiBzb3VyY2VfLCBtZWFuaW5nIHRoZSB1bmRlcmx5aW5nIGNvZGUgZm9yIHRoZSBsYW5ndWFnZSBpcyBmcmVlbHkgYXZhaWxhYmxlIHRvIGFueW9uZS4gCllvdSBkbyBub3QgbmVlZCBhIHNwZWNpYWwgbGljZW5zZSBvciBzZXQgb2YgcGVybWlzc2lvbnMgdG8gdXNlIGFuZCBkZXZlbG9wIGNvZGUgaW4gUi4gCgpSIGl0c2VsZiBpcyBhbiBfaW50ZXJwcmV0ZWQgY29tcHV0ZXIgbGFuZ3VhZ2VfIGFuZCBjb21lcyB3aXRoIGZ1bmN0aW9uYWxpdHkgdGhhdCBjb21lcyBidW5kbGVkIHdpdGggdGhlIGxhbmd1YWdlIGl0c2VsZiwga25vd24gYXMgKioiYmFzZSBSIioqLgpCdXQgdGhlcmUgaXMgYWxzbyByaWNoIGFkZGl0aW9uYWwgZnVuY3Rpb25hbGl0eSBwcm92aWRlZCBieSAqKmV4dGVybmFsIHBhY2thZ2VzKiosIG9yIGxpYnJhcmllcyBvZiBjb2RlIHRoYXQgYXNzaXN0IGluIGFjY29tcGxpc2hpbmcgY2VydGFpbiB0YXNrcyBhbmQgY2FuIGJlIGZyZWVseSBkb3dubG9hZGVkIGFuZCBsb2FkZWQgZm9yIHVzZS4gCgpJbiB0aGUgbmV4dCBub3RlYm9vayBhbmQgc3Vic2VxdWVudCBtb2R1bGVzLCB3ZSB3aWxsIGJlIHVzaW5nIGEgc3VpdGUgb2YgcGFja2FnZXMgY29sbGVjdGl2ZWx5IGtub3duIGFzIFsqKlRoZSBUaWR5dmVyc2UqKl0oaHR0cHM6Ly90aWR5dmVyc2Uub3JnKS4gClRoZSBgdGlkeXZlcnNlYCBpcyBnZWFyZWQgdG93YXJkcyBpbnR1aXRpdmUgZGF0YSBzY2llbmNlIGFwcGxpY2F0aW9ucyB0aGF0IGZvbGxvdyBhIHNoYXJlZCBkYXRhIHBoaWxvc29waHkuCkJ1dCB0aGVyZSBhcmUgc3RpbGwgbWFueSBjb3JlIGZlYXR1cmVzIG9mIGJhc2UgUiB3aGljaCBhcmUgaW1wb3J0YW50IHRvIGJlIGF3YXJlIG9mLCBhbmQgd2Ugd2lsbCBiZSB1c2luZyBjb25jZXB0cyBmcm9tIGJvdGggYmFzZSBSIGFuZCB0aGUgdGlkeXZlcnNlIGluIG91ciBhbmFseXNlcywgYXMgd2VsbCBhcyB0YXNrIHNwZWNpZmljIHBhY2thZ2VzIGZvciBhbmFseXNlcyBzdWNoIGFzIGdlbmUgZXhwcmVzc2lvbi4gCgojIyMgV2hhdCBpcyBSU3R1ZGlvPwoKUlN0dWRpbyBpcyBhIF9ncmFwaGljYWwgZW52aXJvbm1lbnRfICgiaW50ZWdyYXRlZCBkZXZlbG9wbWVudCBlbnZpcm9ubWVudCIgb3IgSURFKSBmb3Igd3JpdGluZyBhbmQgZGV2ZWxvcGluZyBSIGNvZGUuIFJTdHVkaW8gaXMgTk9UIGEgc2VwYXJhdGUgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgLSBpdCBpcyBhbiBpbnRlcmZhY2Ugd2UgdXNlIHRvIGZhY2lsaXRhdGUgUiBwcm9ncmFtbWluZy4gCkluIG90aGVyIHdvcmRzLCB5b3UgY2FuIHByb2dyYW0gaW4gUiB3aXRob3V0IFJTdHVkaW8sIGJ1dCB5b3UgY2FuJ3QgdXNlIHRoZSBSU3R1ZGlvIGVudmlyb25tZW50IHdpdGhvdXQgUi4KCkZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IFJTdHVkaW8gdGhhbiB5b3UgZXZlciB3YW50ZWQgdG8ga25vdywgc2VlIHRoaXMgW1JTdHVkaW8gSURFIENoZWF0c2hlZXQgKHBkZildKGh0dHBzOi8vZ2l0aHViLmNvbS9yc3R1ZGlvL2NoZWF0c2hlZXRzL3Jhdy9tYWluL3JzdHVkaW8taWRlLnBkZikuCgojIyBUaGUgUlN0dWRpbyBFbnZpcm9ubWVudAoKVGhlIFJTdHVkaW8gZW52aXJvbm1lbnQgaGFzIGZvdXIgbWFpbiAqKnBhbmVzKiosIGVhY2ggb2Ygd2hpY2ggbWF5IGhhdmUgYSBudW1iZXIgb2YgdGFicyB0aGF0IGRpc3BsYXkgZGlmZmVyZW50IGluZm9ybWF0aW9uIG9yIGZ1bmN0aW9uYWxpdHkuICh0aGVpciBzcGVjaWZpYyBsb2NhdGlvbiBjYW4gYmUgY2hhbmdlZCB1bmRlciBUb29scyAtPiBHbG9iYWwgT3B0aW9ucyAtPiBQYW5lIExheW91dCkuCiFbUlN0dWRpbyBBcHBlYXJhbmNlXShzY3JlZW5zaG90cy9yc3R1ZGlvLXBhbmVzLnBuZykgCgoxLiBUaGUgKipFZGl0b3IqKiBwYW5lIGlzIHdoZXJlIHlvdSBjYW4gd3JpdGUgUiBzY3JpcHRzIGFuZCBvdGhlciBkb2N1bWVudHMuIEVhY2ggdGFiIGhlcmUgaXMgaXRzIG93biBkb2N1bWVudC4KVGhpcyBpcyB5b3VyIF90ZXh0IGVkaXRvcl8sIHdoaWNoIHdpbGwgYWxsb3cgeW91IHRvIHNhdmUgeW91ciBSIGNvZGUgZm9yIGZ1dHVyZSB1c2UuIApOb3RlIHRoYXQgY2hhbmdlIGNvZGUgaGVyZSB3aWxsIG5vdCBydW4gYXV0b21hdGljYWxseSB1bnRpbCB5b3UgcnVuIGl0LiAKCjIuIFRoZSAqKkNvbnNvbGUqKiBwYW5lIGlzIHdoZXJlIHlvdSBjYW4gX2ludGVyYWN0aXZlbHlfIHJ1biBSIGNvZGUuIAogICsgVGhlcmUgaXMgYWxzbyBhICoqVGVybWluYWwqKiB0YWIgaGVyZSB3aGljaCBjYW4gYmUgdXNlZCBmb3IgcnVubmluZyBwcm9ncmFtcyBvdXRzaWRlIFIgb24geW91ciBjb21wdXRlcgogIAozLiBUaGUgKipFbnZpcm9ubWVudCoqIHBhbmUgcHJpbWFyaWx5IGRpc3BsYXlzIHRoZSB2YXJpYWJsZXMsIHNvbWV0aW1lcyBrbm93biBhcyBfb2JqZWN0c18gdGhhdCBhcmUgZGVmaW5lZCBkdXJpbmcgYSBnaXZlbiBSIHNlc3Npb24sIGFuZCB3aGF0IGRhdGEgb3IgdmFsdWVzIHRoZXkgbWlnaHQgaG9sZC4KCjQuIFRoZSAqKkhlbHAgdmlld2VyKiogcGFuZSBoYXMgc2V2ZXJhbCB0YWJzIGFsbCBvZiB3aGljaCBhcmUgcHJldHR5IGltcG9ydGFudDoKICAgICsgVGhlICoqRmlsZXMqKiB0YWIgc2hvd3MgdGhlIHN0cnVjdHVyZSBhbmQgY29udGVudHMgb2YgZmlsZXMgYW5kIGZvbGRlcnMgKGFsc28ga25vd24gYXMgZGlyZWN0b3JpZXMpIG9uIHlvdXIgY29tcHV0ZXIuCiAgICArIFRoZSAqKlBsb3RzKiogdGFiIHdpbGwgcmV2ZWFsIHBsb3RzIHdoZW4geW91IG1ha2UgdGhlbQogICAgKyBUaGUgKipQYWNrYWdlcyoqIHRhYiBzaG93cyB3aGljaCBpbnN0YWxsZWQgcGFja2FnZXMgaGF2ZSBiZWVuIGxvYWRlZCBpbnRvIHlvdXIgUiBzZXNzaW9uCiAgICArIFRoZSAqKkhlbHAqKiB0YWIgd2lsbCBzaG93IHRoZSBoZWxwIHBhZ2Ugd2hlbiB5b3UgbG9vayB1cCBhIGZ1bmN0aW9uCiAgICArIFRoZSAqKlZpZXdlcioqIHBhbmUgd2lsbCByZXZlYWwgY29tcGlsZWQgUiBNYXJrZG93biBkb2N1bWVudHMgCgojIyBCYXNpYyBDYWxjdWxhdGlvbnMKCiMjIyBNYXRoZW1hdGljYWwgb3BlcmF0b3JzCgpUaGUgbW9zdCBiYXNpYyB1c2Ugb2YgUiBpcyBhcyBhIHJlZ3VsYXIgY2FsY3VsYXRvcjoKCnwgT3BlcmF0aW9uIHwgU3ltYm9sIHwKfC0tLS0tLS0tLS0tfC0tLS0tLS0tfAp8IEFkZCAgfCBgK2AgfCAKfCBTdWJ0cmFjdCAgfCBgLWAgfCAKfCBNdWx0aXBseSAgfCBgKmAgfCAKfCBEaXZpZGUgIHwgYC9gIHwgCnwgRXhwb25lbnRpYXRlIHwgYF5gIG9yIGAqKmAgfCAKCkZvciBleGFtcGxlLCB3ZSBjYW4gZG8gc29tZSBzaW1wbGUgbXVsdGlwbGljYXRpb24gbGlrZSB0aGlzLiAKV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiAKVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSAKcGxhY2luZyB5b3VyIGN1cnNvciBpbnNpZGUgaXQgYW5kIHByZXNzaW5nICpDbWQrU2hpZnQrRW50ZXIqLiAKCmBgYHtyIGNhbGN1bGF0b3J9CjUgKiA2CmBgYAoKVXNlIHRoZSBjb25zb2xlIHRvIGNhbGN1bGF0ZSBvdGhlciBleHByZXNzaW9ucy4gU3RhbmRhcmQgb3JkZXIgb2Ygb3BlcmF0aW9ucyBhcHBsaWVzIChtb3N0bHkpLCBhbmQgIHlvdSBjYW4gdXNlIHBhcmVudGhlc2VzIGAoKWAgYXMgeW91IG1pZ2h0IGV4cGVjdCAoYnV0IG5vdCBicmFja2V0cyBgW11gIG9yIGJyYWNlc2B7fWAsIHdoaWNoIGhhdmUgc3BlY2lhbCBtZWFuaW5ncykuIE5vdGUgaG93ZXZlciwgdGhhdCB5b3UgbXVzdCAqKmFsd2F5cyoqIHNwZWNpZnkgbXVsdGlwbGljYXRpb24gd2l0aCBgKmA7IGltcGxpY2l0IG11bHRpcGxpY2F0aW9uIHN1Y2ggYXMgYDEwKDMgKyA0KWAgb3IgYDEweGAgd2lsbCBub3Qgd29yayBhbmQgd2lsbCBnZW5lcmF0ZSBhbiBlcnJvciwgb3Igd29yc2UuCgpgYGB7ciBleHByZXNzaW9ucywgbGl2ZSA9IFRSVUV9CjEwICogKDMgKyA0KV4yCmBgYAoKCiMjIyBEZWZpbmluZyBhbmQgdXNpbmcgdmFyaWFibGVzIAoKVG8gZGVmaW5lIGEgdmFyaWFibGUsIHdlIHVzZSB0aGUgX2Fzc2lnbm1lbnQgb3BlcmF0b3JfIHdoaWNoIGxvb2tzIGxpa2UgYW4gYXJyb3c6IGA8LWAsIGZvciBleGFtcGxlIGB4IDwtIDdgIHRha2VzIHRoZSB2YWx1ZSBvbiB0aGUgcmlnaHQtaGFuZCBzaWRlIG9mIHRoZSBvcGVyYXRvciBhbmQgYXNzaWducyBpdCB0byB0aGUgdmFyaWFibGUgbmFtZSBvbiB0aGUgbGVmdC1oYW5kIHNpZGUuIAoKYGBge3IgdmFyLWRlZmluZSwgbGl2ZSA9IFRSVUV9CiMgRGVmaW5lIGEgdmFyaWFibGUgeCB0byBlcXVhbCA3LCBhbmQgcHJpbnQgb3V0IHRoZSB2YWx1ZSBvZiB4CnggPC0gNwoKIyBXZSBjYW4gaGF2ZSBSIHJlcGVhdCBiYWNrIHRvIHVzIHdoYXQgYHhgIGlzIGJ5IGp1c3QgdXNpbmcgYHhgCngKYGBgCgpTb21lIGZlYXR1cmVzIG9mIHZhcmlhYmxlcywgY29uc2lkZXJpbmcgdGhlIGV4YW1wbGUgYHggPC0gN2A6CkV2ZXJ5IHZhcmlhYmxlIGhhcyBhICoqbmFtZSoqLCBhICoqdmFsdWUqKiwgYW5kIGEgKip0eXBlKiouIApUaGlzIHZhcmlhYmxlJ3MgbmFtZSBpcyBgeGAsIGl0cyB2YWx1ZSBpcyBgN2AsIGFuZCBpdHMgdHlwZSBpcyBgbnVtZXJpY2AgKDcgaXMgYSBudW1iZXIhKS4KUmUtZGVmaW5pbmcgYSB2YXJpYWJsZSB3aWxsIG92ZXJ3cml0ZSB0aGUgdmFsdWUuCgpgYGB7ciB2YXItcmVkZWZpbmV9CnggPC0gNS41Cgp4CmBgYAoKV2UgY2FuIG1vZGlmeSBhbiBleGlzdGluZyB2YXJpYWJsZSBieSByZWFzc2lnbmluZyBpdCB0byBpdHMgc2FtZSBuYW1lLiAKSGVyZSB3ZSdsbCBhZGQgYDJgIHRvIGB4YCBhbmQgcmVhc3NpZ24gdGhlIHJlc3VsdCBiYWNrIHRvIGB4YC4gCgpgYGB7ciB2YXItbW9kaWZ5LCBsaXZlID0gVFJVRX0KeCA8LSB4ICsgMgoKeApgYGAKCiMjIyBWYXJpYWJsZSBuYW1pbmcgbm90ZToKQXMgYmVzdCB5b3UgY2FuLCBpdCBpcyBhIGdvb2QgaWRlYSB0byBtYWtlIHlvdXIgdmFyaWFibGUgbmFtZXMgaW5mb3JtYXRpdmUgKGUuZy4gYHhgIGRvZXNuJ3QgbWVhbiBhbnl0aGluZywgYnV0IGBzYW5kd2ljaF9wcmljZWAgaXMgbWVhbmluZ2Z1bC4uLiBpZiB3ZSdyZSB0YWxraW5nIGFib3V0IHRoZSBjb3N0IG9mIHNhbmR3aWNoZXMsIHRoYXQgaXMuLikuIAoKIyMjIENvbW1lbnRzCgpBcmd1YWJseSB0aGUgX19tb3N0IGltcG9ydGFudF9fIGFzcGVjdCBvZiB5b3VyIGNvZGluZyBpcyBjb21tZW50czogU21hbGwgcGllY2VzIG9mIGV4cGxhbmF0b3J5IHRleHQgeW91IGxlYXZlIGluIHlvdXIgY29kZSB0byBleHBsYWluIHdoYXQgdGhlIGNvZGUgaXMgZG9pbmcgYW5kL29yIGxlYXZlIG5vdGVzIHRvIHlvdXJzZWxmIG9yIG90aGVycy4gCkNvbW1lbnRzIGFyZSBpbnZhbHVhYmxlIGZvciBjb21tdW5pY2F0aW5nIHlvdXIgY29kZSB0byBvdGhlcnMsIGJ1dCB0aGV5IGFyZSBtb3N0IGltcG9ydGFudCBmb3IgKipGdXR1cmUgWW91KiouIApGdXR1cmUgWW91IGNvbWVzIGludG8gZXhpc3RlbmNlIGFib3V0IG9uZSBzZWNvbmQgYWZ0ZXIgeW91IHdyaXRlIGNvZGUsIGFuZCBoYXMgbm8gaWRlYSB3aGF0IG9uIGVhcnRoIFBhc3QgWW91IHdhcyB0aGlua2luZy4gCgpDb21tZW50cyBpbiBSIGNvZGUgYXJlIGluZGljYXRlZCB3aXRoIHBvdW5kIHNpZ25zICgqYWthKiBoYXNodGFncywgb2N0b3Rob3JwcykuIFIgd2lsbCBfaWdub3JlXyBhbnkgdGV4dCBpbiBhIGxpbmUgYWZ0ZXIgdGhlIHBvdW5kIHNpZ24sIHNvIHlvdSBjYW4gcHV0IHdoYXRldmVyIHRleHQgeW91IGxpa2UgdGhlcmUuCgpgYGB7ciBjb21tZW50c30KMjIvNyAjIG5vdCBxdWl0ZSBwaQoKIyBJZiB3ZSBuZWVkIGEgYmV0dGVyIGFwcHJveGltYXRpb24gb2YgcGksIHdlIGNhbiB1c2UgRXVsZXIncyBmb3JtdWxhCiMgVGhpcyB1c2VzIGF0YW4oKSwgd2hpY2ggY2FsY3VsYXRlcyBhcmN0YW5nZW50LgoyMCAqIGF0YW4oMS83KSArIDggKiBhdGFuKDMvNzkpIApgYGAKCkhlbHAgb3V0IEZ1dHVyZSBZb3UgYnkgYWRkaW5nIGxvdHMgb2YgY29tbWVudHMhIApGdXR1cmUgWW91IG5leHQgd2VlayB0aGlua3MgVG9kYXkgWW91IGlzIGFuIGlkaW90LCBhbmQgdGhlIG9ubHkgd2F5IHlvdSBjYW4gY29udmluY2UgRnV0dXJlIFlvdSB0aGF0IFRvZGF5IFlvdSBpcyByZWFzb25hYmx5IGNvbXBldGVudCBpcyBieSBhZGRpbmcgY29tbWVudHMgaW4geW91ciBjb2RlIGV4cGxhaW5pbmcgd2h5IFRvZGF5IFlvdSBpcyBhY3R1YWxseSBub3Qgc28gYmFkLgoKIyMgRnVuY3Rpb25zCldlIGNhbiB1c2UgcHJlLWJ1aWx0IGNvbXB1dGF0aW9uIG1ldGhvZHMgY2FsbGVkICJmdW5jdGlvbnMiIGZvciBvdGhlciBvcGVyYXRpb25zLiAKRnVuY3Rpb25zIGhhdmUgdGhlIGZvbGxvd2luZyBmb3JtYXQsIHdoZXJlIHRoZSBfYXJndW1lbnRfIGlzIHRoZSBpbmZvcm1hdGlvbiB3ZSBhcmUgcHJvdmlkaW5nIHRvIHRoZSBmdW5jdGlvbiBmb3IgaXQgdG8gcnVuLiAKQW4gZXhhbXBsZSBvZiB0aGlzIHdhcyB0aGUgYGF0YW4oKWAgZnVuY3Rpb24gdXNlZCBhYm92ZS4KCmBgYHIKZnVuY3Rpb25fbmFtZShhcmd1bWVudCkKYGBgCgpUbyBsZWFybiBhYm91dCBmdW5jdGlvbnMsIHdlJ2xsIGV4YW1pbmUgb25lIGNhbGxlZCBgbG9nKClgIGZpcnN0LiAKClRvIGtub3cgd2hhdCBhIGZ1bmN0aW9uIGRvZXMgYW5kIGhvdyB0byB1c2UgaXQsIHVzZSB0aGUgcXVlc3Rpb24gbWFyayB3aGljaCB3aWxsIHJldmVhbCBkb2N1bWVudGF0aW9uIGluIHRoZSAqKmhlbHAgcGFuZSoqOiBgP2xvZ2AKIVtyaGVscF0oc2NyZWVuc2hvdHMvcmhlbHAtbG9nLnBuZykgCgpUaGUgZG9jdW1lbnRhdGlvbiB0ZWxscyB1cyB0aGF0IGBsb2coKWAgaXMgZGVyaXZlZCBmcm9tIGB7YmFzZX1gLCBtZWFuaW5nIGl0IGlzIGEgZnVuY3Rpb24gdGhhdCBpcyBwYXJ0IG9mIGJhc2UgUi4gCkl0IHByb3ZpZGVzIGEgYnJpZWYgZGVzY3JpcHRpb24gb2Ygd2hhdCB0aGUgZnVuY3Rpb24gZG9lcyBhbmQgc2hvd3Mgc2V2ZXJhbCBleGFtcGxlcyBvZiB0byBob3cgdXNlIGl0LgoKSW4gcGFydGljdWxhciwgdGhlIGRvY3VtZW50YXRpb24gdGVsbHMgdXMgYWJvdXQgd2hhdCBhcmd1bWVudChzKSB0byBwcm92aWRlOgoKKyBUaGUgZmlyc3QgX3JlcXVpcmVkXyBhcmd1bWVudCBpcyB0aGUgdmFsdWUgd2UnZCBsaWtlIHRvIHRha2UgdGhlIGxvZyBvZiwgYnkgZGVmYXVsdCBpdHMgX25hdHVyYWwgbG9nXworIFRoZSBzZWNvbmQgX29wdGlvbmFsXyBhcmd1bWVudCBjYW4gc3BlY2lmeSBhIGRpZmZlcmVudCBiYXNlIHJhdGhlciB0aGFuIHRoZSBkZWZhdWx0IGBlYC4KCkZ1bmN0aW9ucyBhbHNvIF9yZXR1cm5fIHZhbHVlcyBmb3IgdXMgdG8gdXNlLiAKSW4gdGhlIGNhc2Ugb2YgYGxvZygpYCwgdGhlIHJldHVybmVkIHZhbHVlIGlzIHRoZSBsb2cnZCB2YWx1ZSB0aGUgZnVuY3Rpb24gY29tcHV0ZWQuCgpgYGB7ciBsb2d9CmxvZyg3MykKYGBgCgpIZXJlIHdlIGNhbiBzcGVjaWZ5IGFuIF9hcmd1bWVudF8gb2YgYGJhc2VgIHRvIGNhbGN1bGF0ZSBsb2cgYmFzZSAzLiAKCmBgYHtyIGxvZzN9CmxvZyg4MSwgYmFzZSA9IDMpCmBgYAoKSWYgd2UgZG9uJ3Qgc3BlY2lmeSB0aGUgX2FyZ3VtZW50XyBuYW1lcywgaXQgYXNzdW1lcyB0aGV5IGFyZSBpbiB0aGUgb3JkZXIgdGhhdCBgbG9nYCBkZWZpbmVzIHRoZW0uIApTZWUgYD9sb2dgIHRvIHNlZSBtb3JlIGFib3V0IGl0cyBhcmd1bWVudHMuIAoKYGBge3IgbG9nMiwgbGl2ZSA9IFRSVUV9CmxvZyg4LCAyKQpgYGAKCldlIGNhbiBzd2l0Y2ggdGhlIG9yZGVyIGlmIHdlIHNwZWNpZnkgdGhlIGFyZ3VtZW50IG5hbWVzLiAKCmBgYHtyIGxvZy1vcmRlcn0KbG9nKGJhc2UgPSAxMCwgeCA9IDQzNDIpCmBgYAoKV2UgY2FuIGFsc28gcHJvdmlkZSB2YXJpYWJsZXMgYXMgYXJndW1lbnRzIGluIHRoZSBzYW1lIHdheSBhcyB0aGUgcmF3IHZhbHVlcy4gCgpgYGB7ciBsb2ctdmFyaWFibGV9Cm1lYW5pbmcgPC0gNDIKbG9nKG1lYW5pbmcpCmBgYAoKIyMgV29ya2luZyB3aXRoIHZhcmlhYmxlcwoKIyMjIFZhcmlhYmxlIFR5cGVzCgpWYXJpYWJsZSB0eXBlcyBpbiBSIGNhbiBzb21ldGltZXMgYmUgX2NvZXJjZWRfIChjb252ZXJ0ZWQpIGZyb20gb25lIHR5cGUgdG8gYW5vdGhlci4KCmBgYHtyfQojIERlZmluZSBhIHZhcmlhYmxlIHdpdGggYSBudW1iZXIKeCA8LSAxNQpgYGAKClRoZSBmdW5jdGlvbiBgY2xhc3MoKWAgd2lsbCB0ZWxsIHVzIHRoZSB2YXJpYWJsZSdzIHR5cGUuCgpgYGB7cn0KY2xhc3MoeCkKYGBgCgpMZXQncyBjb2VyY2UgaXQgdG8gYSBjaGFyYWN0ZXIuIAoKYGBge3J9CnggPC0gYXMuY2hhcmFjdGVyKHgpCmNsYXNzKHgpCmBgYAoKU2VlIGl0IG5vdyBoYXMgcXVvdGVzIGFyb3VuZCBpdD8gSXQncyBub3cgYSBjaGFyYWN0ZXIgYW5kIHdpbGwgYmVoYXZlIGFzIHN1Y2guCgpgYGB7cn0KeApgYGAKClVzZSB0aGlzIGNodW5rIHRvIHRyeSB0byBwZXJmb3JtIGNhbGN1bGF0aW9ucyB3aXRoIGB4YCwgbm93IHRoYXQgaXQgaXMgYSBjaGFyYWN0ZXIsIHdoYXQgaGFwcGVucz8gCgpgYGB7ciBsaXZlID0gVFJVRX0KIyBUcnkgdG8gcGVyZm9ybSBjYWxjdWxhdGlvbnMgb24gYHhgCmBgYAoKQnV0IHdlIGNhbid0IGNvZXJjZSBldmVyeXRoaW5nOgoKYGBge3J9CiMgTGV0J3MgY3JlYXRlIGEgY2hhcmFjdGVyIHZhcmlhYmxlCnggPC0gImxvb2sgYXQgbXkgY2hhcmFjdGVyIHZhcmlhYmxlIgpgYGAKCkxldCdzIHRyeSBtYWtpbmcgdGhpcyBhIG51bWVyaWMgdmFyaWFibGU6CgpgYGB7ciBjb2VyY2UtY2hhciwgZXJyb3I9VFJVRX0KeCA8LSBhcy5udW1lcmljKHgpCmBgYAoKUHJpbnQgb3V0IGB4YC4KCmBgYHtyfQp4CmBgYAoKUiBpcyB0ZWxsaW5nIHVzIGl0IGRvZXNuJ3Qga25vdyBob3cgdG8gY29udmVydCB0aGlzIHRvIGEgbnVtZXJpYyB2YXJpYWJsZSwgc28gaXQgaGFzIHJldHVybmVkIGBOQWAgaW5zdGVhZC4KCkZvciByZWZlcmVuY2UsIGhlcmUncyBhIHN1bW1hcnkgb2Ygc29tZSBvZiB0aGUgbW9zdCBpbXBvcnRhbnQgdmFyaWFibGUgdHlwZXMuIAoKfCBWYXJpYWJsZSBUeXBlIHwgRGVmaW5pdGlvbiB8IEV4YW1wbGVzIHwgQ29lcmNpb24gfAp8LS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tfCAtLS0tLS0tLXwKfCBgbnVtZXJpY2AgICAgICAgfCBBbnkgbnVtYmVyIHZhbHVlIHwgYDVgPGJyPmA3LjVgIDxicj5gLTFgfCBgYXMubnVtZXJpYygpYAp8IGBpbnRlZ2VyYCAgICAgICB8IEFueSBfd2hvbGVfIG51bWJlciB2YWx1ZSAobm8gZGVjaW1hbHMpIHwgYDVgIDxicj4gYC0xMDBgIHwgYGFzLmludGVnZXIoKWAKfGBjaGFyYWN0ZXJgICAgICAgfCBBbnkgY29sbGVjdGlvbiBvZiBjaGFyYWN0ZXJzIGRlZmluZWQgd2l0aGluIF9xdW90YXRpb24gbWFya3NfLiBBbHNvIGtub3duIGFzIGEgInN0cmluZyIuIHwgYCJhImAgKGEgc2luZ2xlIGxldHRlcikgPGJyPmAic3RyaW5nb2ZsZXR0ZXJzImAgKGEgd2hvbGUgYnVuY2ggb2YgY2hhcmFjdGVycyBwdXQgdG9nZXRoZXIgYXMgb25lKSA8YnI+IGAic3RyaW5nIG9mIGxldHRlcnMgYW5kIHNwYWNlcyJgIDxicj4gYCI1ImAgPGJyPiBgJ3NpbmdsZSBxdW90ZXMgYXJlIGFsc28gZ29vZCdgIHwgYGFzLmNoYXJhY3RlcigpYAp8YGxvZ2ljYWxgICAgICAgfCBBIHZhbHVlIG9mIGBUUlVFYCwgYEZBTFNFYCwgb3IgYE5BYCB8IGBUUlVFYCA8YnI+IGBGQUxTRWAgPGJyPiBgTkFgIChub3QgZGVmaW5lZCkgfCBgYXMubG9naWNhbCgpYCAKfGBmYWN0b3JgICAgICAgIHwgQSBzcGVjaWFsIHR5cGUgb2YgdmFyaWFibGUgdGhhdCBkZW5vdGVzIHNwZWNpZmljIGNhdGVnb3JpZXMgb2YgYSBjYXRlZ29yaWNhbCB2YXJpYWJsZSB8IChzdGF5IHR1bmVkLi4pIHwgYGFzLmZhY3RvcigpYAoKIyMjIFZlY3RvcnMKCllvdSB3aWxsIGhhdmUgbm90aWNlZCB0aGF0IGFsbCB5b3VyIGNvbXB1dGF0aW9ucyB0ZW5kIHRvIHBvcCB1cCB3aXRoIGEgYFsxXWAgcHJlY2VkaW5nIHRoZW0gaW4gUidzIG91dHB1dC4gClRoaXMgaXMgYmVjYXVzZSwgaW4gZmFjdCwgYWxsIChvayBtb3N0bHkgYWxsKSB2YXJpYWJsZXMgYXJlIF9ieSBkZWZhdWx0XyAgdmVjdG9ycywgYW5kIG91ciBhbnN3ZXJzIGFyZSB0aGUgZmlyc3QgKGluIHRoZXNlIGNhc2VzIG9ubHkpIHZhbHVlIGluIHRoZSB2ZWN0b3IuIApBcyB2ZWN0b3JzIGdldCBsb25nZXIsIG5ldyBpbmRleCBpbmRpY2F0b3JzIHdpbGwgYXBwZWFyIGF0IHRoZSBzdGFydCBvZiBuZXcgbGluZXMuIAoKYGBge3J9CiMgVGhpcyBpcyBhY3R1YWxseSBhbiB2ZWN0b3IgdGhhdCBoYXMgb25lIGl0ZW0gaW4gaXQuCnggPC0gNwpgYGAKCmBgYHtyIHZlY3Rvci1sZW5ndGh9CiMgVGhlIGxlbmd0aCgpIGZ1bmN0aW9ucyB0ZWxscyB1cyBob3cgbG9uZyBhbiB2ZWN0b3IgaXM6Cmxlbmd0aCh4KQpgYGAKCldlIGNhbiBkZWZpbmUgdmVjdG9ycyB3aXRoIHRoZSBmdW5jdGlvbiBgYygpYCwgd2hpY2ggc3RhbmRzIGZvciAiY29tYmluZSIuIApUaGlzIGZ1bmN0aW9uIHRha2VzIGEgY29tbWEtc2VwYXJhdGVkIHNldCBvZiB2YWx1ZXMgdG8gcGxhY2UgaW4gdGhlIHZlY3RvciwgYW5kIHJldHVybnMgdGhlIHZlY3RvciBpdHNlbGY6CgpgYGB7ciBtYWtlLXZlY3Rvcn0KbXlfbnVtZXJpY192ZWN0b3IgPC0gYygxLCAxLCAyLCAzLCA1LCA4LCAxMywgMjEpCm15X251bWVyaWNfdmVjdG9yCmBgYAoKV2UgY2FuIGJ1aWxkIG9uIHZlY3RvcnMgaW4gcGxhY2UgYnkgcmVkZWZpbmluZyB0aGVtOgoKYGBge3IgZmliYm9uYWNjaSwgbGl2ZSA9IFRSVUV9CiMgYWRkIHRoZSBuZXh0IHR3byBGaWJvbmFjY2kgbnVtYmVycyB0byB0aGUgc2VyaWVzLgpteV9udW1lcmljX3ZlY3RvciA8LSBjKG15X251bWVyaWNfdmVjdG9yLCAzNCwgNTUpCm15X251bWVyaWNfdmVjdG9yCmBgYAoKV2UgY2FuIHB1bGwgb3V0IHNwZWNpZmljIGl0ZW1zIGZyb20gYW4gdmVjdG9yIHVzaW5nIGEgcHJvY2VzcyBjYWxsZWQgX2luZGV4aW5nXywgd2hpY2ggdXNlcyBicmFja2V0cyBgW11gIHRvIHNwZWNpZnkgdGhlIHBvc2l0aW9uIG9mIGFuIGl0ZW0uIAoKYGBge3Igc3Vic2V0MX0KIyBHcmFiIHRoZSBmb3VydGggdmFsdWUgZnJvbSBteV9udW1lcmljX3ZlY3RvcgojIFRoaXMgZ2l2ZXMgdXMgYW4gdmVjdG9yIG9mIGxlbmd0aCAxIApteV9udW1lcmljX3ZlY3Rvcls0XQpgYGAKCkNvbG9ucyBhcmUgYWxzbyBhIG5pY2Ugd2F5IHRvIHF1aWNrbHkgbWFrZSBvcmRlcmVkIG51bWVyaWMgdmVjdG9ycwpVc2UgYSBjb2xvbiB0byBzcGVjaWZ5IGFuIGluY2x1c2l2ZSByYW5nZSBvZiBpbmRpY2VzClRoaXMgd2lsbCByZXR1cm4gYW4gdmVjdG9yIHdpdGggMiwgMywgNCwgYW5kIDUuCgpgYGB7ciBzdWJzZXQtbWFueX0KbXlfbnVtZXJpY192ZWN0b3JbMjo1XQpgYGAKCk9uZSBtYWpvciBiZW5lZml0IG9mIHZlY3RvcnMgaXMgdGhlIGNvbmNlcHQgb2YgKip2ZWN0b3JpemF0aW9uKiosIHdoZXJlIFIgYnkgZGVmYXVsdCBwZXJmb3JtcyBvcGVyYXRpb25zIG9uIHRoZSBfZW50aXJlIHZlY3RvciBhdCBvbmNlXy4gCkZvciBleGFtcGxlLCB3ZSBjYW4gZ2V0IHRoZSBsb2cgb2YgYWxsIG51bWJlcnMgMS0yMCB3aXRoIGEgc2luZ2xlLCBzaW1wbGUgY2FsbCwgYW5kIG1vcmUhCgpgYGB7ciB2ZWN0b3JpemV9CnZhbHVlc18xX3RvXzIwIDwtIDE6MjAKYGBgCgoKYGBge3IgdmVjdG9yaXplLWxvZywgbGl2ZSA9IFRSVUV9CiMgY2FsY3VsYXRlIHRoZSBsb2cgb2YgdmFsdWVzXzFfdG9fMjAKbG9nKHZhbHVlc18xX3RvXzIwKQpgYGAKCkZpbmFsbHksIHdlIGNhbiBhcHBseSBsb2dpY2FsIGV4cHJlc3Npb25zIHRvIHZlY3RvcnMsIGp1c3QgYXMgd2UgY2FuIGRvIGZvciBzaW5nbGUgdmFsdWVzLgpUaGUgb3V0cHV0IGhlcmUgaXMgYSBsb2dpY2FsIHZlY3RvciB0ZWxsaW5nIHVzIHdoZXRoZXIgZWFjaCB2YWx1ZSBpbiBleGFtcGxlX3ZlY3RvciBpcyBUUlVFIG9yIEZBTFNFCgpgYGB7ciB2ZWN0b3ItY29tcGFyZX0KIyBXaGljaCB2YWx1ZXMgYXJlIDw9IDM/CnZhbHVlc18xX3RvXzIwIDw9IDMKYGBgCgpUaGVyZSBhcmUgc2V2ZXJhbCBrZXkgZnVuY3Rpb25zIHdoaWNoIGNhbiBiZSB1c2VkIG9uIHZlY3RvcnMgY29udGFpbmluZyBudW1lcmljIHZhbHVlcywgc29tZSBvZiB3aGljaCBhcmUgYmVsb3cuCgorIGBtZWFuKClgOiBUaGUgYXZlcmFnZSB2YWx1ZSBpbiB0aGUgdmVjdG9yCisgYG1pbigpYDogVGhlIG1pbmltdW0gdmFsdWUgaW4gdGhlIHZlY3RvcgorIGBtYXgoKWA6IFRoZSBtYXhpbXVtIHZhbHVlIGluIHRoZSB2ZWN0b3IKKyBgc3VtKClgOiBUaGUgc3VtIG9mIGFsbCB2YWx1ZXMgaW4gdGhlIHZlY3RvcgoKV2UgY2FuIHRyeSBvdXQgdGhlc2UgZnVuY3Rpb25zIG9uIHRoZSB2ZWN0b3IgYHZhbHVlc18xX3RvXzIwYCB3ZSd2ZSBjcmVhdGVkLiAKCmBgYHtyIHZlY3Rvci1mdW5jc30KbWVhbih2YWx1ZXNfMV90b18yMCkKCiMgVHJ5IG91dCBzb21lIG9mIHRoZSBvdGhlciBmdW5jdGlvbnMgd2UndmUgbGlzdGVkIGFib3ZlIAoKYGBgCgojIyMgQSBub3RlIG9uIHZhcmlhYmxlIG5hbWluZwoKV2UgaGF2ZSBsZWFybmVkIGZ1bmN0aW9ucyBzdWNoIGFzIGBjYCwgYGxlbmd0aGAsIGBzdW1gLCBhbmQgZXRjLiAKSW1hZ2luZSBkZWZpbmluZyBhIHZhcmlhYmxlIGNhbGxlZCBgY2A6IFRoaXMgd2lsbCB3b3JrLCBidXQgaXQgd2lsbCBsZWFkIHRvIGEgCmxvdCBvZiB1bmludGVuZGVkIGJ1Z3MsIHNvIGl0J3MgYmVzdCB0byBhdm9pZCB0aGlzLiAKCiMjIyBUaGUgYCVpbiVgIGxvZ2ljYWwgb3BlcmF0b3IgCgpgJWluJWAgaXMgdXNlZnVsIGZvciBkZXRlcm1pbmluZyB3aGV0aGVyIGEgZ2l2ZW4gaXRlbShzKSBhcmUgaW4gYW4gdmVjdG9yLgoKYGBge3IgaW4tb3BlcmF0b3J9CiMgaXMgYDdgIGluIG91ciB2ZWN0b3I/IAo3ICVpbiUgdmFsdWVzXzFfdG9fMjAKYGBgCgpgYGB7ciBpbjIsIGxpdmUgPSBUUlVFfQojIGlzIGA1MGAgaW4gb3VyIHZlY3Rvcj8gCjUwICVpbiUgdmFsdWVzXzFfdG9fMjAKYGBgCgpXZSBjYW4gdGVzdCBhIHZlY3RvciBvZiB2YWx1ZXMgYmVpbmcgd2l0aGluIGFub3RoZXIgdmVjdG9yIG9mIHZhbHVlcy4gCgpgYGB7ciB2ZWN0b3ItaW4sIGxpdmUgPSBUUlVFfQpxdWVzdGlvbl92YWx1ZXMgPC0gYygxOjMsIDcsIDUwKQojIEFyZSB0aGVzZSB2YWx1ZXMgaW4gb3VyIHZlY3Rvcj8KcXVlc3Rpb25fdmFsdWVzICVpbiUgdmFsdWVzXzFfdG9fMjAKYGBgCgojIyBEYXRhIGZyYW1lcwoKX0RhdGEgZnJhbWVzIGFyZSBvbmUgb2YgdGhlIG1vc3QgdXNlZnVsIHRvb2xzIGZvciBkYXRhIGFuYWx5c2lzIGluIFIuXyAKVGhleSBhcmUgdGFibGVzIHdoaWNoIGNvbnNpc3Qgb2Ygcm93cyBhbmQgY29sdW1ucywgbXVjaCBsaWtlIGEgX3NwcmVhZHNoZWV0Xy4gCkVhY2ggY29sdW1uIGlzIGEgdmFyaWFibGUgd2hpY2ggYmVoYXZlcyBhcyBhIF92ZWN0b3JfLCBhbmQgZWFjaCByb3cgaXMgYW4gb2JzZXJ2YXRpb24uIApXZSB3aWxsIGJlZ2luIG91ciBleHBsb3JhdGlvbiB3aXRoIGRhdGFzZXQgb2YgbWVhc3VyZW1lbnRzIGZyb20gdGhyZWUgcGVuZ3VpbiBzcGVjaWVzIG1lYXN1cmVkLCB3aGljaCB3ZSBjYW4gZmluZCBpbiB0aGUgW2BwYWxtZXJwZW5ndWluc2AgcGFja2FnZV0oaHR0cHM6Ly9hbGxpc29uaG9yc3QuZ2l0aHViLmlvL3BhbG1lcnBlbmd1aW5zLykuIApXZSdsbCB0YWxrIG1vcmUgYWJvdXQgcGFja2FnZXMgc29vbiEKVG8gdXNlIHRoaXMgZGF0YXNldCwgd2Ugd2lsbCBsb2FkIGl0IGZyb20gdGhlIGBwYWxtZXJwZW5ndWluc2AgcGFja2FnZSB1c2luZyBhIGA6OmAgKG1vcmUgb24gdGhpcyBsYXRlcikgYW5kIGFzc2lnbiBpdCB0byBhIHZhcmlhYmxlIG5hbWVkIGBwZW5ndWluc2AgaW4gb3VyIGN1cnJlbnQgZW52aXJvbm1lbnQuCgpgYGB7ciBwZW5ndWluLWxpYnJhcnl9CnBlbmd1aW5zIDwtIHBhbG1lcnBlbmd1aW5zOjpwZW5ndWlucwpgYGAKCiFbZHJhd2luZ3Mgb2YgcGVuZ3VpbiBzcGVjaWVzXShkaWFncmFtcy9sdGVyX3Blbmd1aW5zLnBuZykgQXJ0d29yayBieSBbQGFsbGlzb25faG9yc3RdKGh0dHBzOi8vdHdpdHRlci5jb20vYWxsaXNvbl9ob3JzdCkKCiMjIyBFeHBsb3JpbmcgZGF0YSBmcmFtZXMKClRoZSBmaXJzdCBzdGVwIHRvIHVzaW5nIGFueSBkYXRhIGlzIHRvIGxvb2sgYXQgaXQhISEgClJTdHVkaW8gY29udGFpbnMgYSBzcGVjaWFsIGZ1bmN0aW9uIGBWaWV3KClgIHdoaWNoIGFsbG93cyB5b3UgdG8gbGl0ZXJhbGx5IHZpZXcgYSB2YXJpYWJsZS4KWW91IGNhbiBhbHNvIGNsaWNrIG9uIHRoZSBvYmplY3QgaW4gdGhlIGVudmlyb25tZW50IHBhbmUgdG8gc2VlIGl0cyBvdmVyYWxsIHByb3BlcnRpZXMsIG9yIGNsaWNrIHRoZSB0YWJsZSBpY29uIG9uIHRoZSBvYmplY3QncyByb3cgdG8gYXV0b21hdGljYWxseSB2aWV3IHRoZSB2YXJpYWJsZS4gCgpTb21lIHVzZWZ1bCBmdW5jdGlvbnMgZm9yIGV4cGxvcmluZyBvdXIgZGF0YSBmcmFtZSBpbmNsdWRlOgoKKyBgaGVhZCgpYCB0byBzZWUgdGhlIGZpcnN0IDYgcm93cyBvZiBhIGRhdGEgZnJhbWUuIEFkZGl0aW9uYWwgYXJndW1lbnRzIHN1cHBsaWVkIGNhbiBjaGFuZ2UgdGhlIG51bWJlciBvZiByb3dzLgorIGB0YWlsKClgIHRvIHNlZSB0aGUgbGFzdCA2IHJvd3Mgb2YgYSBkYXRhIGZyYW1lLiBBZGRpdGlvbmFsIGFyZ3VtZW50cyBzdXBwbGllZCBjYW4gY2hhbmdlIHRoZSBudW1iZXIgb2Ygcm93cy4KKyBgbmFtZXMoKWAgdG8gc2VlIHRoZSBjb2x1bW4gbmFtZXMgb2YgdGhlIGRhdGEgZnJhbWUuCisgYG5yb3coKWAgdG8gc2VlIGhvdyBtYW55IHJvd3MgYXJlIGluIHRoZSBkYXRhIGZyYW1lCisgYG5jb2woKWAgdG8gc2VlIGhvdyBtYW55IGNvbHVtbnMgYXJlIGluIHRoZSBkYXRhIGZyYW1lLgoKV2UgY2FuIGFkZGl0aW9uYWxseSBleHBsb3JlIF9vdmVyYWxsIHByb3BlcnRpZXNfIG9mIHRoZSBkYXRhIGZyYW1lIHdpdGggdHdvIGRpZmZlcmVudCBmdW5jdGlvbnM6IGBzdW1tYXJ5KClgIGFuZCBgc3RyKClgLgoKVGhpcyBwcm92aWRlcyBzdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIGVhY2ggY29sdW1uOgoKYGBge3IgcGVuZ3VpbnMtc3VtbWFyeX0Kc3VtbWFyeShwZW5ndWlucykKYGBgCgpUaGlzIHByb3ZpZGVzIGEgc2hvcnQgdmlldyBvZiB0aGUgKipzdHIqKnVjdHVyZSBhbmQgY29udGVudHMgb2YgdGhlIGRhdGEgZnJhbWUuCgpgYGB7ciBwZW5ndWlucy1zdHJ9CnN0cihwZW5ndWlucykKYGBgCgpZb3UnbGwgbm90aWNlIHRoYXQgdGhlIGNvbHVtbiBgc3BlY2llc2AgaXMgYSBfZmFjdG9yXzogVGhpcyBpcyBhIHNwZWNpYWwgdHlwZSBvZiBjaGFyYWN0ZXIgdmFyaWFibGUgdGhhdCByZXByZXNlbnRzIGRpc3RpbmN0IGNhdGVnb3JpZXMga25vd24gYXMgImxldmVscyIuIApXZSBoYXZlIGxlYXJuZWQgaGVyZSB0aGF0IHRoZXJlIGFyZSB0aHJlZSBsZXZlbHMgaW4gdGhlIGBzcGVjaWVzYCBjb2x1bW46IEFkZWxpZSwgQ2hpbnN0cmFwLCBhbmQgR2VudG9vLgpXZSBtaWdodCB3YW50IHRvIGV4cGxvcmUgaW5kaXZpZHVhbCBjb2x1bW5zIG9mIHRoZSBkYXRhIGZyYW1lIG1vcmUgaW4tZGVwdGguIApXZSBjYW4gZXhhbWluZSBpbmRpdmlkdWFsIGNvbHVtbnMgdXNpbmcgdGhlIGRvbGxhciBzaWduIGAkYCB0byBzZWxlY3Qgb25lIGJ5IG5hbWU6CgpgYGB7ciBwZW5ndWlucy1zdWJzZXR9CiMgRXh0cmFjdCBiaWxsX2xlbmd0aF9tbSBhcyBhIHZlY3RvcgpwZW5ndWlucyRiaWxsX2xlbmd0aF9tbQoKIyBpbmRleGluZyBvcGVyYXRvcnMgY2FuIGJlIHVzZWQgb24gdGhlc2UgdmVjdG9ycyB0b28KcGVuZ3VpbnMkYmlsbF9sZW5ndGhfbW1bMToxMF0KYGBgCgpXZSBjYW4gcGVyZm9ybSBvdXIgcmVndWxhciB2ZWN0b3Igb3BlcmF0aW9ucyBvbiBjb2x1bW5zIGRpcmVjdGx5LgoKYGBge3IgcGVuZ3VpbnMtY29sLW1lYW4sIGxpdmUgPSBUUlVFfQojIGNhbGN1bGF0ZSB0aGUgbWVhbiBvZiB0aGUgYmlsbF9sZW5ndGhfbW0gY29sdW1uCm1lYW4ocGVuZ3VpbnMkYmlsbF9sZW5ndGhfbW0sCiAgICAgbmEucm0gPSBUUlVFKSAjIHJlbW92ZSBtaXNzaW5nIHZhbHVlcyBiZWZvcmUgY2FsY3VsYXRpbmcgdGhlIG1lYW4KYGBgCgpXZSBjYW4gYWxzbyBjYWxjdWxhdGUgdGhlIGZ1bGwgc3VtbWFyeSBzdGF0aXN0aWNzIGZvciBhIHNpbmdsZSBjb2x1bW4gZGlyZWN0bHkuIAoKYGBge3IgcGVuZ3VpbnMtY29sLXN1bW1hcnksIGxpdmUgPSBUUlVFfQojIHNob3cgYSBzdW1tYXJ5IG9mIHRoZSBiaWxsX2xlbmd0aF9tbSBjb2x1bW4Kc3VtbWFyeShwZW5ndWlucyRiaWxsX2xlbmd0aF9tbSkKYGBgCgpFeHRyYWN0IGBTcGVjaWVzYCBhcyBhIHZlY3RvciBhbmQgc3Vic2V0IGl0IHRvIHNlZSBhIHByZXZpZXcuCgpgYGB7ciBwZW5ndWlucy1jb2wtc3Vic2V0LCBsaXZlID0gVFJVRX0KIyBnZXQgdGhlIGZpcnN0IDEwIHZhbHVlcyBvZiB0aGUgc3BlY2llcyBjb2x1bW4KcGVuZ3VpbnMkc3BlY2llc1sxOjEwXQpgYGAKCkFuZCB2aWV3IGl0cyBfbGV2ZWxzXyB3aXRoIHRoZSBgbGV2ZWxzKClgIGZ1bmN0aW9uLgoKYGBge3IgcGVuZ3Vpbi1sZXZlbHN9CmxldmVscyhwZW5ndWlucyRzcGVjaWVzKQpgYGAKCiMjIEZpbGVzIGFuZCBkaXJlY3RvcmllcwoKSW4gbWFueSBzaXR1YXRpb25zLCB3ZSB3aWxsIGJlIHJlYWRpbmcgaW4gdGFidWxhciBkYXRhIGZyb20gYSBmaWxlIGFuZCB1c2luZyBpdCBhcyBhIGRhdGEgZnJhbWUuIApUbyBwcmFjdGljZSwgd2Ugd2lsbCByZWFkIGluIGEgZmlsZSB3ZSB3aWxsIGJlIHVzaW5nIGluIHRoZSBuZXh0IG5vdGVib29rIGFzIHdlbGwsIGBnZW5lX3Jlc3VsdHNfR1NFNDQ5NzEudHN2YCwgaW4gdGhlIGBkYXRhYCBmb2xkZXIuIApGaWxlIHBhdGhzIGFyZSByZWxhdGl2ZSB0byB0aGUgbG9jYXRpb24gd2hlcmUgdGhpcyBub3RlYm9vayBmaWxlICguUm1kKSBpcyBzYXZlZC4KCkhlcmUgd2Ugd2lsbCB1c2UgYSBmdW5jdGlvbiwgYHJlYWRfdHN2KClgIGZyb20gdGhlIGByZWFkcmAgcGFja2FnZS4KQmVmb3JlIHdlIGFyZSBhYmxlIHRvIHVzZSB0aGUgZnVuY3Rpb24sIHdlIGhhdmUgdG8gbG9hZCB0aGUgcGFja2FnZSB1c2luZyBgbGlicmFyeSgpYC4gCgpgYGB7ciByZWFkcn0KbGlicmFyeShyZWFkcikKYGBgCgpgZmlsZS5wYXRoKClgIGNyZWF0ZXMgYSBwcm9wZXJseSBmb3JtYXR0ZWQgZmlsZSBwYXRoIGJ5IGFkZGluZyBhIHBhdGggc2VwYXJhdG9yIChgL2Agb24gTWFjIGFuZCBMaW51eCBvcGVyYXRpbmcgc3lzdGVtcywgdGhlIGxhdHRlciBvZiB3aGljaCBpcyB0aGUgb3BlcmF0aW5nIHN5c3RlbSB0aGF0IG91ciBSU3R1ZGlvIFNlcnZlciBydW5zIG9uKSBiZXR3ZWVuIHNlcGFyYXRlIGZvbGRlcnMgb3IgZGlyZWN0b3JpZXMuCkJlY2F1c2UgZmlsZSBwYXRoIHNlcGFyYXRvcnMgY2FuIGRpZmZlciBiZXR3ZWVuIHlvdXIgY29tcHV0ZXIgYW5kIHRoZSBjb21wdXRlciBvZiBzb21lb25lIHdobyB3YW50cyB0byB1c2UgeW91ciBjb2RlLCB3ZSB1c2UgYGZpbGUucGF0aCgpYCBpbnN0ZWFkIG9mIHR5cGluZyBvdXQgYCJkYXRhL2dlbmVfcmVzdWx0c19HU0U0NDk3MS50c3YiYC4KRWFjaCBfYXJndW1lbnRfIHRvIGBmaWxlLnBhdGgoKWAgaXMgYSBkaXJlY3Rvcnkgb3IgZmlsZSBuYW1lLgpZb3UnbGwgbm90aWNlIGVhY2ggYXJndW1lbnQgaXMgaW4gcXVvdGVzLCB3ZSBzcGVjaWZ5IGBkYXRhYCBmaXJzdCBiZWNhdXNlIHRoZSBmaWxlLCBgZ2VuZV9yZXN1bHRzX0dTRTQ0OTcxLnRzdmAgaXMgaW4gdGhlIGBkYXRhYCBmb2xkZXIuIAoKYGBge3IgZmlsZS5wYXRofQpmaWxlLnBhdGgoImRhdGEiLCAiZ2VuZV9yZXN1bHRzX0dTRTQ0OTcxLnRzdiIpCmBgYAoKV2UgY2FuIHN0b3JlIHRoaXMgZmlsZSBwYXRoIGFzIGEgdmFyaWFibGUgaW4gb3VyIGVudmlyb25tZW50LiAKCmBgYHtyIGZpbGUucGF0aC12YXJpYWJsZX0KZ2VuZV9maWxlX3BhdGggPC0gZmlsZS5wYXRoKCJkYXRhIiwgImdlbmVfcmVzdWx0c19HU0U0NDk3MS50c3YiKQpgYGAKCk5vdyB3ZSBhcmUgcmVhZHkgdG8gdXNlIGByZWFkX3RzdigpYCB0byByZWFkIHRoZSBmaWxlIGludG8gUi4KVGhlIHJlc3VsdGluZyBkYXRhIGZyYW1lIHdpbGwgYmUgc3RvcmVkIGluIGEgdmFyaWFibGUgbmFtZWQgYHN0YXRzX2RmYC4KTm90ZSB0aGUgYDwtYCAoYXNzaWdubWVudCBvcGVyYXRvciEpIGlzIHJlc3BvbnNpYmxlIGZvciBzYXZpbmcgdGhpcyB0byBvdXIgZ2xvYmFsIGVudmlyb25tZW50LiAKCmBgYHtyIHJlYWQtc3RhdHN9CiMgcmVhZCBpbiB0aGUgZmlsZSBgZ2VuZV9yZXN1bHRzX0dTRTQ0OTcxLnRzdmAgZnJvbSB0aGUgZGF0YSBkaXJlY3RvcnkKc3RhdHNfZGYgPC0gcmVhZF90c3YoZ2VuZV9maWxlX3BhdGgpCmBgYAoKVGFrZSBhIGxvb2sgYXQgeW91ciBlbnZpcm9ubWVudCBwYW5lbCB0byBzZWUgd2hhdCBgc3RhdHNfZGZgIGxvb2tzIGxpa2UuIApXZSBjYW4gYWxzbyBwcmludCBvdXQgYSBwcmV2aWV3IG9mIHRoZSBgc3RhdHNfZGZgIGRhdGEgZnJhbWUgaGVyZS4gCgpgYGB7ciBzaG93LXN0YXRzLCBsaXZlID0gVFJVRX0KIyBkaXNwbGF5IHN0YXRzX2RmCnN0YXRzX2RmCmBgYAoKIyMjIFNlc3Npb24gSW5mbwoKQXQgdGhlIGVuZCBvZiBldmVyeSBub3RlYm9vaywgeW91IHdpbGwgc2VlIHVzIHByaW50IG91dCBgc2Vzc2lvbkluZm9gLiAKVGhpcyBhaWRzIGluIHRoZSByZXByb2R1Y2liaWxpdHkgb2YgeW91ciBjb2RlIGJ5IHNob3dpbmcgZXhhY3RseSB3aGF0IHBhY2thZ2VzIAphbmQgdmVyc2lvbnMgd2VyZSBiZWluZyB1c2VkIHRoZSBsYXN0IHRpbWUgdGhlIG5vdGVib29rIHdhcyBydW4uCgpgYGB7cn0Kc2Vzc2lvbkluZm8oKQpgYGAK
diff --git a/intro-to-R-tidyverse/02-intro_to_ggplot2-live.Rmd b/intro-to-R-tidyverse/02-intro_to_ggplot2-live.Rmd index 923ccf8f..389346f8 100644 --- a/intro-to-R-tidyverse/02-intro_to_ggplot2-live.Rmd +++ b/intro-to-R-tidyverse/02-intro_to_ggplot2-live.Rmd @@ -163,6 +163,8 @@ Remember, the name of this package is `ggplot2`, but the function we use is call 1. `data`, which is the data frame that contains the data we want to plot. 2. `mapping`, which is a special list made with the `aes()` function to describe which values will be used for each **aes**thetic component of the plot, such as the x and y coordinates of each point. (If you find calling things like the x and y coordinates "aesthetics" confusing, don't worry, you are not alone.) +Specifically, the `aes()` function is used to specify that a given column (variable) in your data frame be mapped to a given aesthetic component of the plot. + ```{r ggplot-base} ggplot( @@ -346,11 +348,17 @@ volcano_plot <- ggplot( ``` When we are happy with our plot, we can save the plot using `ggsave`. +It's a good idea to also specify `width` and `height` arguments (units in inches) +to ensure the saved plot is always the same size every time you run this code. +Here, we'll save a 6"x6" plot. + ```{r ggsave} ggsave( plot = volcano_plot, - filename = file.path(plots_dir, "volcano_plot.png") + filename = file.path(plots_dir, "volcano_plot.png"), + width = 6, + height = 6 ) ``` diff --git a/intro-to-R-tidyverse/02-intro_to_ggplot2.nb.html b/intro-to-R-tidyverse/02-intro_to_ggplot2.nb.html index 59d873ca..26f963ae 100644 --- a/intro-to-R-tidyverse/02-intro_to_ggplot2.nb.html +++ b/intro-to-R-tidyverse/02-intro_to_ggplot2.nb.html @@ -3209,7 +3209,10 @@

Plotting this data

each aesthetic component of the plot, such as the x and y coordinates of each point. (If you find calling things like the x and y coordinates “aesthetics” confusing, don’t worry, you are not -alone.) +alone.)
+Specifically, the aes() function is used to specify that a +given column (variable) in your data frame be mapped to a given +aesthetic component of the plot. @@ -3507,18 +3510,20 @@

Adjust our ggplot

When we are happy with our plot, we can save the plot using -ggsave.

+ggsave. It’s a good idea to also specify width +and height arguments (units in inches) to ensure the saved +plot is always the same size every time you run this code. Here, we’ll +save a 6”x6” plot.

- +
ggsave(
   plot = volcano_plot,
-  filename = file.path(plots_dir, "volcano_plot.png")
+  filename = file.path(plots_dir, "volcano_plot.png"),
+  width = 6, 
+  height = 6 
 )
- -
Saving 7 x 5 in image
- @@ -3578,7 +3583,7 @@

Session Info

-
LS0tCnRpdGxlOiAiSW50cm9kdWN0aW9uIHRvIGdncGxvdDIiCmF1dGhvcjogIkNDREwgZm9yIEFMU0YiIApkYXRlOiAyMDIxCm91dHB1dDogICAKICBodG1sX25vdGVib29rOiAKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKCiMjIE9iamVjdGl2ZXMKClRoaXMgbm90ZWJvb2sgd2lsbCBkZW1vbnN0cmF0ZSBob3cgdG86IAoKLSBMb2FkIGFuZCB1c2UgUiBwYWNrYWdlcyAgCi0gUmVhZCBpbiBhbmQgcGVyZm9ybSBzaW1wbGUgbWFuaXB1bGF0aW9ucyBvZiBkYXRhIGZyYW1lcyAKLSBVc2UgYGdncGxvdDJgIHRvIHBsb3QgYW5kIHZpc3VhbGl6ZSBkYXRhCi0gQ3VzdG9taXplIHBsb3RzIHVzaW5nIGZlYXR1cmVzIG9mIGBnZ3Bsb3QyYAoKLS0tCgpXZSdsbCB1c2UgYSByZWFsIGdlbmUgZXhwcmVzc2lvbiBkYXRhc2V0IHRvIGdldCBjb21mb3J0YWJsZSBtYWtpbmcgdmlzdWFsaXphdGlvbnMgdXNpbmcgZ2dwbG90Mi4gCldlJ3ZlIFtwZXJmb3JtZWQgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYW5hbHlzZXNdKC4vc2NyaXB0cy8wMC1zZXR1cC1pbnRyby10by1SLlIpIG9uIGEgcHJlLXByb2Nlc3NlZCBbYXN0cm9jeXRvbWEgbWljcm9hcnJheSBkYXRhc2V0XShodHRwczovL3d3dy5yZWZpbmUuYmlvL2V4cGVyaW1lbnRzL0dTRTQ0OTcxL2dlbmUtZXhwcmVzc2lvbi1kYXRhLWZyb20tcGlsb2N5dGljLWFzdHJvY3l0b21hLXR1bW91ci1zYW1wbGVzLWFuZC1ub3JtYWwtY2VyZWJlbGx1bS1jb250cm9scykuCldlJ2xsIHN0YXJ0IGJ5IG1ha2luZyBhIHZvbGNhbm8gcGxvdCBvZiBkaWZmZXJlbnRpYWwgZ2VuZSBleHByZXNzaW9uIHJlc3VsdHMgZnJvbSB0aGlzIGV4cGVyaW1lbnQuCldlIHBlcmZvcm1lZCB0aHJlZSBzZXRzIG9mIGNvbnRyYXN0czogIAoKMSkgYHNleGAgY2F0ZWdvcnkgY29udHJhc3Rpbmc6IGBNYWxlYCB2cyBgRmVtYWxlYCAgCjIpIGB0aXNzdWVgIGNhdGVnb3J5IGNvbnRyYXN0aW5nIDogYFBpbG9jeXRpYyBhc3Ryb2N5dG9tYSB0dW1vcmAgc2FtcGxlcyB2cyBgbm9ybWFsIGNlcmViZWxsdW1gIHNhbXBsZXMgIAozKSBBbiBpbnRlcmFjdGlvbiBvZiBib3RoIGBzZXhgIGFuZCBgdGlzc3VlYC4gCgoqKk1vcmUgZ2dwbG90MiByZXNvdXJjZXM6KiogIAoKLSBbZ2dwbG90MiB3ZWJzaXRlXShodHRwczovL2dncGxvdDIudGlkeXZlcnNlLm9yZy8pICAKLSBbSGFuZHkgY2hlYXRzaGVldCBmb3IgZ2dwbG90MiAocGRmKV0oaHR0cHM6Ly9naXRodWIuY29tL3JzdHVkaW8vY2hlYXRzaGVldHMvcmF3L21haW4vZGF0YS12aXN1YWxpemF0aW9uLnBkZikKLSBbX0RhdGEgVmlzdWFsaXphdGlvbiwgQSBwcmFjdGljYWwgaW50cm9kdWN0aW9uX10oaHR0cHM6Ly9zb2N2aXouY28vKQotIFtEYXRhIHZpc3VhbGl6YXRpb24gY2hhcHRlciBvZiBfUiBmb3IgRGF0YSBTY2llbmNlX10oaHR0cHM6Ly9yNGRzLmhhZC5jby5uei9kYXRhLXZpc3VhbGlzYXRpb24uaHRtbCkgIAotIFtnZ3Bsb3QyIG9ubGluZSB0dXRvcmlhbF0oaHR0cDovL3Itc3RhdGlzdGljcy5jby9Db21wbGV0ZS1HZ3Bsb3QyLVR1dG9yaWFsLVBhcnQxLVdpdGgtUi1Db2RlLmh0bWwpICAKCiMjIFNldCBVcAoKV2Ugc2F2ZWQgdGhlc2UgcmVzdWx0cyB0byBhIHRhYiBzZXBhcmF0ZWQgdmFsdWVzIChUU1YpIGZpbGUgY2FsbGVkIGBnZW5lX3Jlc3VsdHNfR1NFNDQ5NzEudHN2YC4KSXQncyBiZWVuIHNhdmVkIHRvIHRoZSBgZGF0YWAgZm9sZGVyLiAKRmlsZSBwYXRocyBhcmUgcmVsYXRpdmUgdG8gd2hlcmUgdGhpcyBub3RlYm9vayBmaWxlICguUm1kKSBpcyBzYXZlZC4KU28gd2UgY2FuIHJlZmVyZW5jZSBpdCBsYXRlciwgbGV0J3MgbWFrZSBhIHZhcmlhYmxlIHdpdGggb3VyIGRhdGEgZGlyZWN0b3J5IG5hbWUuIAoKYGBge3J9CmRhdGFfZGlyIDwtICJkYXRhIgpgYGAKCkxldCdzIGRlY2xhcmUgb3VyIG91dHB1dCBmb2xkZXIgbmFtZSBhcyBpdHMgb3duIHZhcmlhYmxlLiAKCmBgYHtyfQpwbG90c19kaXIgPC0gInBsb3RzIgpgYGAKCldlIGNhbiBhbHNvIGNyZWF0ZSBhIGRpcmVjdG9yeSBpZiBpdCBkb2Vzbid0IGFscmVhZHkgZXhpc3QuIAoKYGBge3IgY3JlYXRlaWZ9CiMgVGhlIGlmIHN0YXRlbWVudCBoZXJlIHRlc3RzIHdoZXRoZXIgdGhlIHBsb3QgZGlyZWN0b3J5IGV4aXN0cyBhbmQKIyBvbmx5IGV4ZWN1dGVzIHRoZSAgZXhwcmVzc2lvbnMgYmV0d2VlbiB0aGUgYnJhY2VzIGlmIGl0IGRvZXMgbm90LgppZiAoIWRpci5leGlzdHMocGxvdHNfZGlyKSkgewogIGRpci5jcmVhdGUocGxvdHNfZGlyKQp9CmBgYAoKSW4gdGhpcyBub3RlYm9vayB3ZSB3aWxsIGJlIHVzaW5nIGZ1bmN0aW9ucyBmcm9tIHRoZSBUaWR5dmVyc2Ugc2V0IG9mIHBhY2thZ2VzLCBzbyB3ZSBuZWVkIHRvIGxvYWQgaW4gdGhvc2UgZnVuY3Rpb25zIHVzaW5nIGBsaWJyYXJ5KClgLgpXZSBjb3VsZCBsb2FkIHRoZSBpbmRpdmlkdWFsIHBhY2thZ2VzIHdlIG5lZWQgb25lIGF0IGEgdGltZSwgYnV0IGl0IGlzIGNvbnZlbmllbnQgZm9yIG5vdyB0byBsb2FkIHRoZW0gYWxsIHdpdGggdGhlIGB0aWR5dmVyc2VgICJwYWNrYWdlLCIgd2hpY2ggZ3JvdXBzIG1hbnkgb2YgdGhlbSB0b2dldGhlciBhcyBhIHNob3J0Y3V0LgpLZWVwIGEgbG9vayBvdXQgZm9yIHdoZXJlIHdlIHRlbGwgeW91IHdoaWNoIGluZGl2aWR1YWwgcGFja2FnZSBkaWZmZXJlbnQgZnVuY3Rpb25zIGNvbWUgZnJvbS4KCmBgYHtyIHRpZHl2ZXJzZX0KbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKIyMgUmVhZCBpbiB0aGUgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYW5hbHlzaXMgcmVzdWx0cyBmaWxlCgpIZXJlIHdlIGFyZSB1c2luZyBhIGB0aWR5dmVyc2VgIGZ1bmN0aW9uIGByZWFkX3RzdigpYCBmcm9tIHRoZSBgcmVhZHJgIHBhY2thZ2UuCkxpa2Ugd2UgZGlkIGluIHRoZSBwcmV2aW91cyBub3RlYm9vaywgd2Ugd2lsbCBzdG9yZSB0aGUgcmVzdWx0aW5nIGRhdGEgZnJhbWUgYXMgYHN0YXRzX2RmYC4KCmBgYHtyIHJlYWQtc3RhdHN9CiMgcmVhZCBpbiB0aGUgZmlsZSBgZ2VuZV9yZXN1bHRzX0dTRTQ0OTcxLnRzdmAgZnJvbSB0aGUgZGF0YSBkaXJlY3RvcnkKc3RhdHNfZGYgPC0gcmVhZF90c3YoZmlsZS5wYXRoKAogIGRhdGFfZGlyLAogICJnZW5lX3Jlc3VsdHNfR1NFNDQ5NzEudHN2IgopKQpgYGAKCldlIGNhbiB0YWtlIGEgbG9vayBhdCBhIGNvbHVtbiBpbmRpdmlkdWFsbHkgYnkgdXNpbmcgYSBgJGAuIApOb3RlIHdlIGFyZSB1c2luZyBgaGVhZCgpYCBzbyB0aGUgd2hvbGUgdGhpbmcgZG9lc24ndCBwcmludCBvdXQuIAoKYGBge3IgY29sdW1ufQpoZWFkKHN0YXRzX2RmJGNvbnRyYXN0KQpgYGAKCklmIHdlIHdhbnQgdG8gc2VlIGEgc3BlY2lmaWMgc2V0IG9mIHZhbHVlcywgd2UgY2FuIHVzZSBicmFja2V0cyB3aXRoIHRoZSBpbmRpY2VzIG9mIHRoZSB2YWx1ZXMgd2UnZCBsaWtlIHJldHVybmVkLgoKYGBge3J9CnN0YXRzX2RmJGF2Z19leHByZXNzaW9uWzY6MTBdCmBgYAoKTGV0J3MgbG9vayBhdCBzb21lIGJhc2ljIHN0YXRpc3RpY3MgZnJvbSB0aGUgZGF0YSBzZXQgdXNpbmcgYHN1bW1hcnkoKWAKCmBgYHtyIHN0YXRzLXN1bW1hcnksIGxpdmUgPSBUUlVFfQojIHN1bW1hcnkgb2Ygc3RhdHNfZGYKc3VtbWFyeShzdGF0c19kZikKYGBgCgpUaGUgc3RhdGlzdGljcyBmb3IgYGNvbnRyYXN0YCBhcmUgbm90IHZlcnkgaW5mb3JtYXRpdmUsIHNvIGxldCdzIGRvIHRoYXQgYWdhaW4gd2l0aCBqdXN0IHRoZSBgY29udHJhc3RgIGNvbHVtbiBhZnRlciBjb252ZXJ0aW5nIGl0IHRvIGEgYGZhY3RvcmAKYGBge3IgZmFjdG9yLXN1bW1hcnksIGxpdmUgPSBUUlVFfQojIHN1bW1hcnkgb2YgYHN0YXRzX2RmJGNvbnRyYXN0YCBhcyBhIGZhY3RvcgpzdW1tYXJ5KGFzLmZhY3RvcihzdGF0c19kZiRjb250cmFzdCkpCmBgYAoKIyMgU2V0IHVwIHRoZSBkYXRhc2V0CgpCZWZvcmUgd2UgbWFrZSBvdXIgcGxvdCwgd2Ugd2FudCB0byBjYWxjdWxhdGUgYSBzZXQgb2YgbmV3IHZhbHVlcyBmb3IgZWFjaCByb3c7IHRyYW5zZm9ybWF0aW9ucyBvZiB0aGUgcmF3IHN0YXRpc3RpY3MgaW4gb3VyIHRhYmxlLgpUbyBkbyB0aGlzIHdlIHdpbGwgdXNlIGEgZnVuY3Rpb24gZnJvbSB0aGUgYGRwbHlyYCBwYWNrYWdlIGNhbGxlZCBgbXV0YXRlKClgIHRvIG1ha2UgYSBuZXcgY29sdW1uIG9mIC1sb2cxMCBwIHZhbHVlcy4KCmBgYHtyIG11dGF0ZX0KIyBhZGQgYSBgbmVnX2xvZzEwX3BgIGNvbHVtbiB0byB0aGUgZGF0YSBmcmFtZQpzdGF0c19kZiA8LSBtdXRhdGUoc3RhdHNfZGYsICMgZGF0YSBmcmFtZSB3ZSdkIGxpa2UgdG8gYWRkIGEgdmFyaWFibGUgdG8KICBuZWdfbG9nMTBfcCA9IC1sb2cxMChwX3ZhbHVlKSAjIGNvbHVtbiBuYW1lIGFuZCB2YWx1ZXMKKQpgYGAKCkxldCdzIGZpbHRlciB0byBvbmx5IGBtYWxlX2ZlbWFsZWAgY29udHJhc3QgZGF0YS4gCkZpcnN0IGxldCdzIHRyeSBvdXQgYSBsb2dpY2FsIGV4cHJlc3Npb246IAoKYGBge3IgZXZhbCA9IEZBTFNFfQpzdGF0c19kZiRjb250cmFzdCA9PSAibWFsZV9mZW1hbGUiCmBgYAoKTm93IHdlIGNhbiB0cnkgb3V0IHRoZSBgZmlsdGVyKClgIGZ1bmN0aW9uLgpOb3RpY2UgdGhhdCB3ZSBhcmUgbm90IGFzc2lnbmluZyB0aGUgcmVzdWx0cyB0byBhIHZhcmlhYmxlLCBzbyB0aGlzIGZpbHRlcmVkIGRhdGFzZXQgd2lsbCBub3QgYmUgc2F2ZWQgdG8gdGhlIGVudmlyb25tZW50LgoKYGBge3IgZmlsdGVyLCBsaXZlID0gVFJVRX0KIyBmaWx0ZXIgc3RhdHNfZGYgdG8gIm1hbGVfZmVtYWxlIiBvbmx5CmZpbHRlcihzdGF0c19kZiwgY29udHJhc3QgPT0gIm1hbGVfZmVtYWxlIikKYGBgCgpOb3cgd2UgY2FuIGFzc2lnbiB0aGUgcmVzdWx0cyB0byBhIG5ldyBkYXRhIGZyYW1lOiBgbWFsZV9mZW1hbGVfZGZgLiAKCmBgYHtyIGZpbHRlci1zYXZlLCBsaXZlID0gVFJVRX0KIyBmaWx0ZXIgYW5kIHNhdmUgdG8gbWFsZV9mZW1hbGVfZGYKbWFsZV9mZW1hbGVfZGYgPC0gZmlsdGVyKHN0YXRzX2RmLCBjb250cmFzdCA9PSAibWFsZV9mZW1hbGUiKQpgYGAKCiMjIFBsb3R0aW5nIHRoaXMgZGF0YQoKTGV0J3MgbWFrZSBhIHZvbGNhbm8gcGxvdCB3aXRoIHRoaXMgZGF0YS4gCkZpcnN0IGxldCdzIHRha2UgYSBsb29rIGF0IG9ubHkgdGhlIHR1bW9yIHZzLiBub3JtYWwgY29tcGFyaXNvbi4gCkxldCdzIHNhdmUgdGhpcyBhcyBhIHNlcGFyYXRlIGRhdGEgZnJhbWUgYnkgYXNzaWduaW5nIGl0IGEgbmV3IG5hbWUuIAoKYGBge3IgZmlsdGVyLXR1bW9yfQp0dW1vcl9ub3JtYWxfZGYgPC0gZmlsdGVyKHN0YXRzX2RmLCBjb250cmFzdCA9PSAiYXN0cm9jeXRvbWFfbm9ybWFsIikKYGBgCgpUbyBtYWtlIHRoaXMgcGxvdCB3ZSB3aWxsIGJlIHVzaW5nIGZ1bmN0aW9ucyBmcm9tIHRoZSBgZ2dwbG90MmAgcGFja2FnZSwgdGhlIG1haW4gcGxvdHRpbmcgcGFja2FnZSBvZiB0aGUgdGlkeXZlcnNlLgpXZSB1c2UgdGhlIGZpcnN0IGZ1bmN0aW9uLCBgZ2dwbG90KClgIHRvIGRlZmluZSB0aGUgZGF0YSB0aGF0IHdpbGwgYmUgcGxvdHRlZC4KUmVtZW1iZXIsIHRoZSBuYW1lIG9mIHRoaXMgcGFja2FnZSBpcyBgZ2dwbG90MmAsIGJ1dCB0aGUgZnVuY3Rpb24gd2UgdXNlIGlzIGNhbGxlZCBgZ2dwbG90KClgIHdpdGhvdXQgdGhlIGAyYC4KYGdncGxvdCgpYCB0YWtlcyB0d28gbWFpbiBhcmd1bWVudHM6ICAKCjEuIGBkYXRhYCwgd2hpY2ggaXMgdGhlIGRhdGEgZnJhbWUgdGhhdCBjb250YWlucyB0aGUgZGF0YSB3ZSB3YW50IHRvIHBsb3QuICAKMi4gYG1hcHBpbmdgLCB3aGljaCBpcyBhIHNwZWNpYWwgbGlzdCBtYWRlIHdpdGggdGhlIGBhZXMoKWAgZnVuY3Rpb24gdG8gZGVzY3JpYmUgd2hpY2ggdmFsdWVzIHdpbGwgYmUgdXNlZCBmb3IgZWFjaCAqKmFlcyoqdGhldGljIGNvbXBvbmVudCBvZiB0aGUgcGxvdCwgc3VjaCBhcyB0aGUgeCBhbmQgeSBjb29yZGluYXRlcyBvZiBlYWNoIHBvaW50LiAKKElmIHlvdSBmaW5kIGNhbGxpbmcgdGhpbmdzIGxpa2UgdGhlIHggYW5kIHkgY29vcmRpbmF0ZXMgImFlc3RoZXRpY3MiIGNvbmZ1c2luZywgZG9uJ3Qgd29ycnksIHlvdSBhcmUgbm90IGFsb25lLikgIAoKYGBge3IgZ2dwbG90LWJhc2V9CmdncGxvdCgKICB0dW1vcl9ub3JtYWxfZGYsICMgVGhpcyBmaXJzdCBhcmd1bWVudCBpcyB0aGUgZGF0YSBmcmFtZSB3aXRoIHRoZSBkYXRhIHdlIHdhbnQgdG8gcGxvdAogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsICMgVGhpcyBpcyB0aGUgY29sdW1uIG5hbWUgb2YgdGhlIHZhbHVlcyB3ZSB3YW50IHRvIHVzZQogICAgIyBmb3IgdGhlIHggY29vcmRpbmF0ZXMKICAgIHkgPSBuZWdfbG9nMTBfcAogICkgIyBUaGlzIGlzIHRoZSBjb2x1bW4gbmFtZSBvZiB0aGUgZGF0YSB3ZSB3YW50IGZvciB0aGUgeS1heGlzCikKYGBgCgpZb3UnbGwgbm90aWNlIHRoaXMgcGxvdCBkb2Vzbid0IGhhdmUgYW55dGhpbmcgb24gaXQgYmVjYXVzZSB3ZSBoYXZlbid0IApzcGVjaWZpZWQgYSBwbG90IHR5cGUgeWV0LgpUbyBkbyB0aGF0LCB3ZSB3aWxsIGFkZCBhbm90aGVyIGdncGxvdCBsYXllciB3aXRoIGArYCB3aGljaCB3aWxsIHNwZWNpZnkgZXhhY3RseSB3aGF0IHdlIHdhbnQgdG8gcGxvdC4KQSB2b2xjYW5vIHBsb3QgaXMgYSBzcGVjaWFsIGtpbmQgb2Ygc2NhdHRlciBwbG90LCBzbyB0byBtYWtlIHRoYXQgd2Ugd2lsbCB3YW50IHRvIHBsb3QgaW5kaXZpZHVhbCBwb2ludHMsIHdoaWNoIHdlIGNhbiBkbyB3aXRoIGBnZW9tX3BvaW50KClgLgoKYGBge3IgZ2dwbG90LXBvaW50cywgbGl2ZSA9IFRSVUV9CiMgVGhpcyBmaXJzdCBwYXJ0IGlzIHRoZSBzYW1lIGFzIGJlZm9yZQpnZ3Bsb3QoCiAgdHVtb3Jfbm9ybWFsX2RmLAogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsCiAgICB5ID0gbmVnX2xvZzEwX3AKICApCikgKwogICMgTm93IHdlIGFyZSBhZGRpbmcgb24gYSBsYXllciB0byBzcGVjaWZ5IHdoYXQga2luZCBvZiBwbG90IHdlIHdhbnQKICBnZW9tX3BvaW50KCkKYGBgCgpIZXJlJ3MgYSBicmllZiBzdW1tYXJ5IG9mIGdncGxvdDIgc3RydWN0dXJlLiAKIVtnZ3Bsb3QyIHN0cnVjdHVyZV0oZGlhZ3JhbXMvZ2dwbG90X3N0cnVjdHVyZS5wbmcpCgojIyMgQWRqdXN0IG91ciBnZ3Bsb3QKCk5vdyB0aGF0IHdlIGhhdmUgYSBiYXNlIHBsb3QgdGhhdCBzaG93cyBvdXIgZGF0YSwgd2UgY2FuIGFkZCBsYXllcnMgb24gdG8gaXQgYW5kIGFkanVzdCBpdC4KV2UgY2FuIGFkanVzdCB0aGUgY29sb3Igb2YgcG9pbnRzIHVzaW5nIHRoZSBgY29sb3JgIGFlc3RoZXRpYy4KCmBgYHtyIGdncGxvdC1jb2xvciwgbGl2ZSA9IFRSVUV9CmdncGxvdCgKICB0dW1vcl9ub3JtYWxfZGYsCiAgYWVzKAogICAgeCA9IGxvZ19mb2xkX2NoYW5nZSwKICAgIHkgPSBuZWdfbG9nMTBfcCwKICAgIGNvbG9yID0gYXZnX2V4cHJlc3Npb24KICApICMgV2UgYWRkZWQgdGhpcyBhcmd1bWVudCB0byBjb2xvciBjb2RlIHRoZSBwb2ludHMhCikgKwogIGdlb21fcG9pbnQoKQpgYGAKCkJlY2F1c2Ugd2UgaGF2ZSBzbyBtYW55IHBvaW50cyBvdmVybGFwcGluZyBvbmUgYW5vdGhlciwgd2Ugd2lsbCB3YW50IHRvIGFkanVzdCAKdGhlIHRyYW5zcGFyZW5jeSwgd2hpY2ggd2UgY2FuIGRvIHdpdGggYW4gYGFscGhhYCBhcmd1bWVudC4gCgpgYGB7ciBnZ3Bsb3QtYWxwaGEsIGxpdmUgPSBUUlVFfQpnZ3Bsb3QoCiAgdHVtb3Jfbm9ybWFsX2RmLAogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsCiAgICB5ID0gbmVnX2xvZzEwX3AsCiAgICBjb2xvciA9IGF2Z19leHByZXNzaW9uCiAgKQopICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4yKSAjIFdlIGFyZSB1c2luZyB0aGUgYGFscGhhYCBhcmd1bWVudCB0byBtYWtlIG91ciBwb2ludHMgdHJhbnNwYXJlbnQKYGBgCgpOb3RpY2UgdGhhdCB3ZSBhZGRlZCB0aGUgYWxwaGEgd2l0aGluIHRoZSBgZ2VvbV9wb2ludCgpYCBmdW5jdGlvbiwgbm90IHRvIHRoZSBgYWVzKClgLiAKV2UgZGlkIHRoaXMgYmVjYXVzZSB3ZSB3YW50IGFsbCBvZiB0aGUgcG9pbnRzIHRvIGhhdmUgdGhlIHNhbWUgbGV2ZWwgb2YgdHJhbnNwYXJlbmN5LCBhbmQgaXQgd2lsbCBub3QgdmFyeSBkZXBlbmRpbmcgb24gYW55IHZhcmlhYmxlIGluIHRoZSBkYXRhLgpXZSBjYW4gYWxzbyBjaGFuZ2UgdGhlIGJhY2tncm91bmQgYW5kIGFwcGVhcmFuY2Ugb2YgdGhlIHBsb3QgYXMgYSB3aG9sZSBieSBhZGRpbmcgYSBgdGhlbWVgLgoKYGBge3IgZ2dwbG90LXRoZW1lfQpnZ3Bsb3QoCiAgdHVtb3Jfbm9ybWFsX2RmLAogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsCiAgICB5ID0gbmVnX2xvZzEwX3AsCiAgICBjb2xvciA9IGF2Z19leHByZXNzaW9uCiAgKQopICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4yKSArCiAgdGhlbWVfYncoKSAjIEFkZCBvbiB0aGlzIHNldCBvZiBhcHBlYXJhbmNlIHByZXNldHMgdG8gbWFrZSBpdCBwcmV0dHkKYGBgCgpXZSBhcmUgbm90IGxpbWl0ZWQgdG8gYSBzaW5nbGUgcGxvdHRpbmcgbGF5ZXIuIApGb3IgZXhhbXBsZSwgaWYgd2Ugd2FudCB0byBhZGQgYSBob3Jpem9udGFsIGxpbmUgdG8gaW5kaWNhdGUgYSBzaWduaWZpY2FuY2UgY3V0b2ZmLCB3ZSBjYW4gZG8gdGhhdCB3aXRoIGBnZW9tX2hsaW5lKClgLgpGb3Igbm93LCB3ZSB3aWxsIGNob29zZSB0aGUgdmFsdWUgb2YgNS41ICh0aGF0IGlzIGNsb3NlIHRvIGEgQm9uZmVycm9uaSBjb3JyZWN0aW9uKSBhbmQgYWRkIHRoYXQgdG8gdGhlIHBsb3QuCgpgYGB7ciBnZ3Bsb3QtaGxpbmUsIGxpdmUgPSBUUlVFfQpnZ3Bsb3QoCiAgdHVtb3Jfbm9ybWFsX2RmLAogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsCiAgICB5ID0gbmVnX2xvZzEwX3AsCiAgICBjb2xvciA9IGF2Z19leHByZXNzaW9uCiAgKQopICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4yKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDUuNSwgY29sb3IgPSAiZGFya2dyZWVuIikgIyB3ZSBjYW4gc3BlY2lmeSBjb2xvcnMgYnkgbmFtZXMgaGVyZQpgYGAKCldlIGNhbiBjaGFuZ2UgdGhlIHggYW5kIHkgbGFiZWxzIHVzaW5nIGEgZmV3IGRpZmZlcmVudCBzdHJhdGVnaWVzLiAKT25lIGFwcHJvYWNoIGlzIHRvIHVzZSBmdW5jdGlvbnMgYHhsYWIoKWAgYW5kIGB5bGFiKClgIGluZGl2aWR1YWxseSB0byBzZXQsIHJlc3BlY3RpdmVseSwgdGhlIHgtYXhpcyBsYWJlbCBhbmQgdGhlIHRoZSB5LWF4aXMgbGFiZWwuCgoKYGBge3IgZ2dwbG90LWxhYmVsLTF9CmdncGxvdCgKICB0dW1vcl9ub3JtYWxfZGYsCiAgYWVzKAogICAgeCA9IGxvZ19mb2xkX2NoYW5nZSwKICAgIHkgPSBuZWdfbG9nMTBfcCwKICAgIGNvbG9yID0gYXZnX2V4cHJlc3Npb24KICApCikgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LjUsIGNvbG9yID0gImRhcmtncmVlbiIpICsKICB0aGVtZV9idygpICsKICAjIEFkZCBsYWJlbHMgd2l0aCBzZXBhcmF0ZSBmdW5jdGlvbnM6CiAgeGxhYigibG9nMiBGb2xkIENoYW5nZSBUdW1vci9Ob3JtYWwiKSArIAogIHlsYWIoIi1sb2cxMCBwIHZhbHVlIikgCmBgYAoKCkFsdGVybmF0aXZlbHksIHdlIGNhbiB1c2UgdGhlIGBnZ3Bsb3QyYCBmdW5jdGlvbiBgbGFicygpYCwgd2hpY2ggdGFrZXMgaW5kaXZpZHVhbCBhcmd1bWVudHMgZm9yIGVhY2ggbGFiZWwgd2Ugd2FudCB3YW50IHRvIHNldC4gCldlIGNhbiBhbHNvIGluY2x1ZGUgdGhlIGFyZ3VtZW50IGB0aXRsZWAgdG8gYWRkIGFuIG92ZXJhbGwgcGxvdCB0aXRsZS4KCmBgYHtyIGdncGxvdC1sYWJlbC0yLCBsaXZlID0gVFJVRX0KZ2dwbG90KAogIHR1bW9yX25vcm1hbF9kZiwKICBhZXMoCiAgICB4ID0gbG9nX2ZvbGRfY2hhbmdlLAogICAgeSA9IG5lZ19sb2cxMF9wLAogICAgY29sb3IgPSBhdmdfZXhwcmVzc2lvbgogICkKKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDUuNSwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIHRoZW1lX2J3KCkgKwogICMgQWRkIHggYW5kIHkgbGFiZWxzIGFuZCBvdmVyYWxsIHBsb3QgdGl0bGUgd2l0aCBhcmd1bWVudHMgdG8gbGFicygpOgogIGxhYnMoCiAgICB4ID0gImxvZzIgRm9sZCBDaGFuZ2UgVHVtb3IvTm9ybWFsIiwKICAgIHkgPSAiLWxvZzEwIHAgdmFsdWUiLAogICAgdGl0bGUgPSAiQXN0cm9jeXRvbWEgVHVtb3IgdnMgTm9ybWFsIENlcmViZWxsdW0iCiAgKQogIApgYGAKClNvbWV0aGluZyBncmVhdCBhYm91dCB0aGUgYGxhYnMoKWAgZnVuY3Rpb24gaXMgeW91IGNhbiBhbHNvIHVzZSBpdCB0byBzcGVjaWZ5IGxhYmVscyBmb3IgeW91ciAqbGVnZW5kcyogZGVyaXZlZCBmcm9tIGNlcnRhaW4gYWVzdGhldGljcy4gCkluIHRoaXMgcGxvdCwgb3VyIGxlZ2VuZCBpcyBkZXJpdmVkIGZyb20gYSAqY29sb3IgYWVzdGhldGljKiwgc28gd2UgY2FuIHNwZWNpZnkgdGhlIGtleXdvcmQgImNvbG9yIiB0byB1cGRhdGUgdGhlIGxlZ2VuZCB0aXRsZS4KCmBgYHtyIGdncGxvdC1sYWJlbC1hZXN9CmdncGxvdCgKICB0dW1vcl9ub3JtYWxfZGYsCiAgYWVzKAogICAgeCA9IGxvZ19mb2xkX2NoYW5nZSwKICAgIHkgPSBuZWdfbG9nMTBfcCwKICAgIGNvbG9yID0gYXZnX2V4cHJlc3Npb24KICApCikgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LjUsIGNvbG9yID0gImRhcmtncmVlbiIpICsKICB0aGVtZV9idygpICsKICAjIEFkZCB4IGFuZCB5IGxhYmVscyBhbmQgb3ZlcmFsbCBwbG90IHRpdGxlIHdpdGggYXJndW1lbnRzIHRvIGxhYnMoKToKICBsYWJzKAogICAgeCA9ICJsb2cyIEZvbGQgQ2hhbmdlIFR1bW9yL05vcm1hbCIsCiAgICB5ID0gIi1sb2cxMCBwIHZhbHVlIiwKICAgIHRpdGxlID0gIkFzdHJvY3l0b21hIFR1bW9yIHZzIE5vcm1hbCBDZXJlYmVsbHVtIiwKICAgICMgVXNlIHRoZSBjb2xvciBrZXl3b3JkIHRvIGxhYmVsIHRoZSBjb2xvciBsZWdlbmQKICAgIGNvbG9yID0gIkF2ZXJhZ2UgZXhwcmVzc2lvbiIKICApCiAgCmBgYAoKClVzZSB0aGlzIGNodW5rIHRvIG1ha2UgdGhlIHNhbWUga2luZCBvZiBwbG90IGFzIHRoZSBwcmV2aW91cyBjaHVuayBidXQgaW5zdGVhZCBwbG90IHRoZSBtYWxlIGZlbWFsZSBjb250cmFzdCBkYXRhLCB0aGF0IGlzIHN0b3JlZCBpbiBgbWFsZV9mZW1hbGVfZGZgLiAKCmBgYHtyIG1mLXZvbGNhbm8sIGxpdmUgPSBUUlVFfQojIFVzZSB0aGlzIGNodW5rIHRvIG1ha2UgdGhlIHNhbWUga2luZCBvZiB2b2xjYW5vIHBsb3QsIGJ1dCB3aXRoIHRoZSBtYWxlLWZlbWFsZSBjb250cmFzdCBkYXRhLgoKYGBgCgoKVHVybnMgb3V0LCB3ZSBkb24ndCBoYXZlIHRvIHBsb3QgZWFjaCBjb250cmFzdCBzZXBhcmF0ZWx5LCBpbnN0ZWFkLCB3ZSBjYW4gdXNlIHRoZSBvcmlnaW5hbCBkYXRhIGZyYW1lIHRoYXQgY29udGFpbnMgYWxsIHRocmVlIGNvbnRyYXN0cycgZGF0YSwgYHN0YXRzX2RmYCwgYW5kIGFkZCBhIGBmYWNldF93cmFwYCB0byBtYWtlIGVhY2ggY29udHJhc3QgaXRzIG93biBwbG90LiAKCmBgYHtyIGdncGxvdC1mYWNldHN9CmdncGxvdCgKICBzdGF0c19kZiwgIyBTd2l0Y2ggdG8gdGhlIGJpZ2dlciBkYXRhIGZyYW1lIHdpdGggYWxsIHRocmVlIGNvbnRyYXN0cycgZGF0YQogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsCiAgICB5ID0gbmVnX2xvZzEwX3AsCiAgICBjb2xvciA9IGF2Z19leHByZXNzaW9uCiAgKQopICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4yKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNS41LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgdGhlbWVfYncoKSArCiAgZmFjZXRfd3JhcCh+Y29udHJhc3QpICsKICBsYWJzKAogICAgeCAgPSAibG9nMiBGb2xkIENoYW5nZSIsICMgTm93IHRoYXQgdGhpcyBpbmNsdWRlcyB0aGUgb3RoZXIgY29udHJhc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgd2UnbGwgbWFrZSB0aGlzIGxhYmVsIG1vcmUgZ2VuZXJhbAogICAgeSA9ICItbG9nMTAgcCB2YWx1ZSIsCiAgICBjb2xvciA9ICJBdmVyYWdlIGV4cHJlc3Npb24iCiAgKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0yNSwgMjUpKSAjIHpvb20gaW4gb24gdGhlIHgtYXhpcwpgYGAKCldlIGNhbiBzdG9yZSB0aGUgcGxvdCBhcyBhbiBvYmplY3QgaW4gdGhlIGdsb2JhbCBlbnZpcm9ubWVudCBieSB1c2luZyBgPC1gIG9wZXJhdG9yLiAKSGVyZSB3ZSB3aWxsIGNhbGwgdGhpcyBgdm9sY2Fub19wbG90YC4gCgpgYGB7ciBnZ3Bsb3Qtc3RvcmUtb2JqZWN0fQp2b2xjYW5vX3Bsb3QgPC0gZ2dwbG90KAogIHN0YXRzX2RmLCAjIFdlIGFyZSBjYWxsaW5nIHRoaXMgcGxvdCBgdm9sY2Fub19wbG90YAogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsCiAgICB5ID0gbmVnX2xvZzEwX3AsCiAgICBjb2xvciA9IGF2Z19leHByZXNzaW9uCiAgKQopICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4yKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNS41LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgdGhlbWVfYncoKSArCiAgZmFjZXRfd3JhcCh+Y29udHJhc3QpICsKICBsYWJzKAogICAgeCAgPSAibG9nMiBGb2xkIENoYW5nZSIsCiAgICB5ID0gIi1sb2cxMCBwIHZhbHVlIiwKICAgIGNvbG9yID0gIkF2ZXJhZ2UgZXhwcmVzc2lvbiIKICApICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTI1LCAyNSkpCmBgYAoKV2hlbiB3ZSBhcmUgaGFwcHkgd2l0aCBvdXIgcGxvdCwgd2UgY2FuIHNhdmUgdGhlIHBsb3QgdXNpbmcgYGdnc2F2ZWAuIAoKYGBge3IgZ2dzYXZlfQpnZ3NhdmUoCiAgcGxvdCA9IHZvbGNhbm9fcGxvdCwKICBmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90c19kaXIsICJ2b2xjYW5vX3Bsb3QucG5nIikKKQpgYGAKCiMjIyBTZXNzaW9uIEluZm8KCmBgYHtyfQojIFByaW50IG91dCB0aGUgdmVyc2lvbnMgYW5kIHBhY2thZ2VzIHdlIGFyZSB1c2luZyBpbiB0aGlzIHNlc3Npb24Kc2Vzc2lvbkluZm8oKQpgYGAK
+
LS0tCnRpdGxlOiAiSW50cm9kdWN0aW9uIHRvIGdncGxvdDIiCmF1dGhvcjogIkNDREwgZm9yIEFMU0YiIApkYXRlOiAyMDIxCm91dHB1dDogICAKICBodG1sX25vdGVib29rOiAKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKCiMjIE9iamVjdGl2ZXMKClRoaXMgbm90ZWJvb2sgd2lsbCBkZW1vbnN0cmF0ZSBob3cgdG86IAoKLSBMb2FkIGFuZCB1c2UgUiBwYWNrYWdlcyAgCi0gUmVhZCBpbiBhbmQgcGVyZm9ybSBzaW1wbGUgbWFuaXB1bGF0aW9ucyBvZiBkYXRhIGZyYW1lcyAKLSBVc2UgYGdncGxvdDJgIHRvIHBsb3QgYW5kIHZpc3VhbGl6ZSBkYXRhCi0gQ3VzdG9taXplIHBsb3RzIHVzaW5nIGZlYXR1cmVzIG9mIGBnZ3Bsb3QyYAoKLS0tCgpXZSdsbCB1c2UgYSByZWFsIGdlbmUgZXhwcmVzc2lvbiBkYXRhc2V0IHRvIGdldCBjb21mb3J0YWJsZSBtYWtpbmcgdmlzdWFsaXphdGlvbnMgdXNpbmcgZ2dwbG90Mi4gCldlJ3ZlIFtwZXJmb3JtZWQgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYW5hbHlzZXNdKC4vc2NyaXB0cy8wMC1zZXR1cC1pbnRyby10by1SLlIpIG9uIGEgcHJlLXByb2Nlc3NlZCBbYXN0cm9jeXRvbWEgbWljcm9hcnJheSBkYXRhc2V0XShodHRwczovL3d3dy5yZWZpbmUuYmlvL2V4cGVyaW1lbnRzL0dTRTQ0OTcxL2dlbmUtZXhwcmVzc2lvbi1kYXRhLWZyb20tcGlsb2N5dGljLWFzdHJvY3l0b21hLXR1bW91ci1zYW1wbGVzLWFuZC1ub3JtYWwtY2VyZWJlbGx1bS1jb250cm9scykuCldlJ2xsIHN0YXJ0IGJ5IG1ha2luZyBhIHZvbGNhbm8gcGxvdCBvZiBkaWZmZXJlbnRpYWwgZ2VuZSBleHByZXNzaW9uIHJlc3VsdHMgZnJvbSB0aGlzIGV4cGVyaW1lbnQuCldlIHBlcmZvcm1lZCB0aHJlZSBzZXRzIG9mIGNvbnRyYXN0czogIAoKMSkgYHNleGAgY2F0ZWdvcnkgY29udHJhc3Rpbmc6IGBNYWxlYCB2cyBgRmVtYWxlYCAgCjIpIGB0aXNzdWVgIGNhdGVnb3J5IGNvbnRyYXN0aW5nIDogYFBpbG9jeXRpYyBhc3Ryb2N5dG9tYSB0dW1vcmAgc2FtcGxlcyB2cyBgbm9ybWFsIGNlcmViZWxsdW1gIHNhbXBsZXMgIAozKSBBbiBpbnRlcmFjdGlvbiBvZiBib3RoIGBzZXhgIGFuZCBgdGlzc3VlYC4gCgoqKk1vcmUgZ2dwbG90MiByZXNvdXJjZXM6KiogIAoKLSBbZ2dwbG90MiB3ZWJzaXRlXShodHRwczovL2dncGxvdDIudGlkeXZlcnNlLm9yZy8pICAKLSBbSGFuZHkgY2hlYXRzaGVldCBmb3IgZ2dwbG90MiAocGRmKV0oaHR0cHM6Ly9naXRodWIuY29tL3JzdHVkaW8vY2hlYXRzaGVldHMvcmF3L21haW4vZGF0YS12aXN1YWxpemF0aW9uLnBkZikKLSBbX0RhdGEgVmlzdWFsaXphdGlvbiwgQSBwcmFjdGljYWwgaW50cm9kdWN0aW9uX10oaHR0cHM6Ly9zb2N2aXouY28vKQotIFtEYXRhIHZpc3VhbGl6YXRpb24gY2hhcHRlciBvZiBfUiBmb3IgRGF0YSBTY2llbmNlX10oaHR0cHM6Ly9yNGRzLmhhZC5jby5uei9kYXRhLXZpc3VhbGlzYXRpb24uaHRtbCkgIAotIFtnZ3Bsb3QyIG9ubGluZSB0dXRvcmlhbF0oaHR0cDovL3Itc3RhdGlzdGljcy5jby9Db21wbGV0ZS1HZ3Bsb3QyLVR1dG9yaWFsLVBhcnQxLVdpdGgtUi1Db2RlLmh0bWwpICAKCiMjIFNldCBVcAoKV2Ugc2F2ZWQgdGhlc2UgcmVzdWx0cyB0byBhIHRhYiBzZXBhcmF0ZWQgdmFsdWVzIChUU1YpIGZpbGUgY2FsbGVkIGBnZW5lX3Jlc3VsdHNfR1NFNDQ5NzEudHN2YC4KSXQncyBiZWVuIHNhdmVkIHRvIHRoZSBgZGF0YWAgZm9sZGVyLiAKRmlsZSBwYXRocyBhcmUgcmVsYXRpdmUgdG8gd2hlcmUgdGhpcyBub3RlYm9vayBmaWxlICguUm1kKSBpcyBzYXZlZC4KU28gd2UgY2FuIHJlZmVyZW5jZSBpdCBsYXRlciwgbGV0J3MgbWFrZSBhIHZhcmlhYmxlIHdpdGggb3VyIGRhdGEgZGlyZWN0b3J5IG5hbWUuIAoKYGBge3J9CmRhdGFfZGlyIDwtICJkYXRhIgpgYGAKCkxldCdzIGRlY2xhcmUgb3VyIG91dHB1dCBmb2xkZXIgbmFtZSBhcyBpdHMgb3duIHZhcmlhYmxlLiAKCmBgYHtyfQpwbG90c19kaXIgPC0gInBsb3RzIgpgYGAKCldlIGNhbiBhbHNvIGNyZWF0ZSBhIGRpcmVjdG9yeSBpZiBpdCBkb2Vzbid0IGFscmVhZHkgZXhpc3QuIAoKYGBge3IgY3JlYXRlaWZ9CiMgVGhlIGlmIHN0YXRlbWVudCBoZXJlIHRlc3RzIHdoZXRoZXIgdGhlIHBsb3QgZGlyZWN0b3J5IGV4aXN0cyBhbmQKIyBvbmx5IGV4ZWN1dGVzIHRoZSAgZXhwcmVzc2lvbnMgYmV0d2VlbiB0aGUgYnJhY2VzIGlmIGl0IGRvZXMgbm90LgppZiAoIWRpci5leGlzdHMocGxvdHNfZGlyKSkgewogIGRpci5jcmVhdGUocGxvdHNfZGlyKQp9CmBgYAoKSW4gdGhpcyBub3RlYm9vayB3ZSB3aWxsIGJlIHVzaW5nIGZ1bmN0aW9ucyBmcm9tIHRoZSBUaWR5dmVyc2Ugc2V0IG9mIHBhY2thZ2VzLCBzbyB3ZSBuZWVkIHRvIGxvYWQgaW4gdGhvc2UgZnVuY3Rpb25zIHVzaW5nIGBsaWJyYXJ5KClgLgpXZSBjb3VsZCBsb2FkIHRoZSBpbmRpdmlkdWFsIHBhY2thZ2VzIHdlIG5lZWQgb25lIGF0IGEgdGltZSwgYnV0IGl0IGlzIGNvbnZlbmllbnQgZm9yIG5vdyB0byBsb2FkIHRoZW0gYWxsIHdpdGggdGhlIGB0aWR5dmVyc2VgICJwYWNrYWdlLCIgd2hpY2ggZ3JvdXBzIG1hbnkgb2YgdGhlbSB0b2dldGhlciBhcyBhIHNob3J0Y3V0LgpLZWVwIGEgbG9vayBvdXQgZm9yIHdoZXJlIHdlIHRlbGwgeW91IHdoaWNoIGluZGl2aWR1YWwgcGFja2FnZSBkaWZmZXJlbnQgZnVuY3Rpb25zIGNvbWUgZnJvbS4KCmBgYHtyIHRpZHl2ZXJzZX0KbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKIyMgUmVhZCBpbiB0aGUgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYW5hbHlzaXMgcmVzdWx0cyBmaWxlCgpIZXJlIHdlIGFyZSB1c2luZyBhIGB0aWR5dmVyc2VgIGZ1bmN0aW9uIGByZWFkX3RzdigpYCBmcm9tIHRoZSBgcmVhZHJgIHBhY2thZ2UuCkxpa2Ugd2UgZGlkIGluIHRoZSBwcmV2aW91cyBub3RlYm9vaywgd2Ugd2lsbCBzdG9yZSB0aGUgcmVzdWx0aW5nIGRhdGEgZnJhbWUgYXMgYHN0YXRzX2RmYC4KCmBgYHtyIHJlYWQtc3RhdHN9CiMgcmVhZCBpbiB0aGUgZmlsZSBgZ2VuZV9yZXN1bHRzX0dTRTQ0OTcxLnRzdmAgZnJvbSB0aGUgZGF0YSBkaXJlY3RvcnkKc3RhdHNfZGYgPC0gcmVhZF90c3YoZmlsZS5wYXRoKAogIGRhdGFfZGlyLAogICJnZW5lX3Jlc3VsdHNfR1NFNDQ5NzEudHN2IgopKQpgYGAKCldlIGNhbiB0YWtlIGEgbG9vayBhdCBhIGNvbHVtbiBpbmRpdmlkdWFsbHkgYnkgdXNpbmcgYSBgJGAuIApOb3RlIHdlIGFyZSB1c2luZyBgaGVhZCgpYCBzbyB0aGUgd2hvbGUgdGhpbmcgZG9lc24ndCBwcmludCBvdXQuIAoKYGBge3IgY29sdW1ufQpoZWFkKHN0YXRzX2RmJGNvbnRyYXN0KQpgYGAKCklmIHdlIHdhbnQgdG8gc2VlIGEgc3BlY2lmaWMgc2V0IG9mIHZhbHVlcywgd2UgY2FuIHVzZSBicmFja2V0cyB3aXRoIHRoZSBpbmRpY2VzIG9mIHRoZSB2YWx1ZXMgd2UnZCBsaWtlIHJldHVybmVkLgoKYGBge3J9CnN0YXRzX2RmJGF2Z19leHByZXNzaW9uWzY6MTBdCmBgYAoKTGV0J3MgbG9vayBhdCBzb21lIGJhc2ljIHN0YXRpc3RpY3MgZnJvbSB0aGUgZGF0YSBzZXQgdXNpbmcgYHN1bW1hcnkoKWAKCmBgYHtyIHN0YXRzLXN1bW1hcnksIGxpdmUgPSBUUlVFfQojIHN1bW1hcnkgb2Ygc3RhdHNfZGYKc3VtbWFyeShzdGF0c19kZikKYGBgCgpUaGUgc3RhdGlzdGljcyBmb3IgYGNvbnRyYXN0YCBhcmUgbm90IHZlcnkgaW5mb3JtYXRpdmUsIHNvIGxldCdzIGRvIHRoYXQgYWdhaW4gd2l0aCBqdXN0IHRoZSBgY29udHJhc3RgIGNvbHVtbiBhZnRlciBjb252ZXJ0aW5nIGl0IHRvIGEgYGZhY3RvcmAKYGBge3IgZmFjdG9yLXN1bW1hcnksIGxpdmUgPSBUUlVFfQojIHN1bW1hcnkgb2YgYHN0YXRzX2RmJGNvbnRyYXN0YCBhcyBhIGZhY3RvcgpzdW1tYXJ5KGFzLmZhY3RvcihzdGF0c19kZiRjb250cmFzdCkpCmBgYAoKIyMgU2V0IHVwIHRoZSBkYXRhc2V0CgpCZWZvcmUgd2UgbWFrZSBvdXIgcGxvdCwgd2Ugd2FudCB0byBjYWxjdWxhdGUgYSBzZXQgb2YgbmV3IHZhbHVlcyBmb3IgZWFjaCByb3c7IHRyYW5zZm9ybWF0aW9ucyBvZiB0aGUgcmF3IHN0YXRpc3RpY3MgaW4gb3VyIHRhYmxlLgpUbyBkbyB0aGlzIHdlIHdpbGwgdXNlIGEgZnVuY3Rpb24gZnJvbSB0aGUgYGRwbHlyYCBwYWNrYWdlIGNhbGxlZCBgbXV0YXRlKClgIHRvIG1ha2UgYSBuZXcgY29sdW1uIG9mIC1sb2cxMCBwIHZhbHVlcy4KCmBgYHtyIG11dGF0ZX0KIyBhZGQgYSBgbmVnX2xvZzEwX3BgIGNvbHVtbiB0byB0aGUgZGF0YSBmcmFtZQpzdGF0c19kZiA8LSBtdXRhdGUoc3RhdHNfZGYsICMgZGF0YSBmcmFtZSB3ZSdkIGxpa2UgdG8gYWRkIGEgdmFyaWFibGUgdG8KICBuZWdfbG9nMTBfcCA9IC1sb2cxMChwX3ZhbHVlKSAjIGNvbHVtbiBuYW1lIGFuZCB2YWx1ZXMKKQpgYGAKCkxldCdzIGZpbHRlciB0byBvbmx5IGBtYWxlX2ZlbWFsZWAgY29udHJhc3QgZGF0YS4gCkZpcnN0IGxldCdzIHRyeSBvdXQgYSBsb2dpY2FsIGV4cHJlc3Npb246IAoKYGBge3IgZXZhbCA9IEZBTFNFfQpzdGF0c19kZiRjb250cmFzdCA9PSAibWFsZV9mZW1hbGUiCmBgYAoKTm93IHdlIGNhbiB0cnkgb3V0IHRoZSBgZmlsdGVyKClgIGZ1bmN0aW9uLgpOb3RpY2UgdGhhdCB3ZSBhcmUgbm90IGFzc2lnbmluZyB0aGUgcmVzdWx0cyB0byBhIHZhcmlhYmxlLCBzbyB0aGlzIGZpbHRlcmVkIGRhdGFzZXQgd2lsbCBub3QgYmUgc2F2ZWQgdG8gdGhlIGVudmlyb25tZW50LgoKYGBge3IgZmlsdGVyLCBsaXZlID0gVFJVRX0KIyBmaWx0ZXIgc3RhdHNfZGYgdG8gIm1hbGVfZmVtYWxlIiBvbmx5CmZpbHRlcihzdGF0c19kZiwgY29udHJhc3QgPT0gIm1hbGVfZmVtYWxlIikKYGBgCgpOb3cgd2UgY2FuIGFzc2lnbiB0aGUgcmVzdWx0cyB0byBhIG5ldyBkYXRhIGZyYW1lOiBgbWFsZV9mZW1hbGVfZGZgLiAKCmBgYHtyIGZpbHRlci1zYXZlLCBsaXZlID0gVFJVRX0KIyBmaWx0ZXIgYW5kIHNhdmUgdG8gbWFsZV9mZW1hbGVfZGYKbWFsZV9mZW1hbGVfZGYgPC0gZmlsdGVyKHN0YXRzX2RmLCBjb250cmFzdCA9PSAibWFsZV9mZW1hbGUiKQpgYGAKCiMjIFBsb3R0aW5nIHRoaXMgZGF0YQoKTGV0J3MgbWFrZSBhIHZvbGNhbm8gcGxvdCB3aXRoIHRoaXMgZGF0YS4gCkZpcnN0IGxldCdzIHRha2UgYSBsb29rIGF0IG9ubHkgdGhlIHR1bW9yIHZzLiBub3JtYWwgY29tcGFyaXNvbi4gCkxldCdzIHNhdmUgdGhpcyBhcyBhIHNlcGFyYXRlIGRhdGEgZnJhbWUgYnkgYXNzaWduaW5nIGl0IGEgbmV3IG5hbWUuIAoKYGBge3IgZmlsdGVyLXR1bW9yfQp0dW1vcl9ub3JtYWxfZGYgPC0gZmlsdGVyKHN0YXRzX2RmLCBjb250cmFzdCA9PSAiYXN0cm9jeXRvbWFfbm9ybWFsIikKYGBgCgpUbyBtYWtlIHRoaXMgcGxvdCB3ZSB3aWxsIGJlIHVzaW5nIGZ1bmN0aW9ucyBmcm9tIHRoZSBgZ2dwbG90MmAgcGFja2FnZSwgdGhlIG1haW4gcGxvdHRpbmcgcGFja2FnZSBvZiB0aGUgdGlkeXZlcnNlLgpXZSB1c2UgdGhlIGZpcnN0IGZ1bmN0aW9uLCBgZ2dwbG90KClgIHRvIGRlZmluZSB0aGUgZGF0YSB0aGF0IHdpbGwgYmUgcGxvdHRlZC4KUmVtZW1iZXIsIHRoZSBuYW1lIG9mIHRoaXMgcGFja2FnZSBpcyBgZ2dwbG90MmAsIGJ1dCB0aGUgZnVuY3Rpb24gd2UgdXNlIGlzIGNhbGxlZCBgZ2dwbG90KClgIHdpdGhvdXQgdGhlIGAyYC4KYGdncGxvdCgpYCB0YWtlcyB0d28gbWFpbiBhcmd1bWVudHM6ICAKCjEuIGBkYXRhYCwgd2hpY2ggaXMgdGhlIGRhdGEgZnJhbWUgdGhhdCBjb250YWlucyB0aGUgZGF0YSB3ZSB3YW50IHRvIHBsb3QuICAKMi4gYG1hcHBpbmdgLCB3aGljaCBpcyBhIHNwZWNpYWwgbGlzdCBtYWRlIHdpdGggdGhlIGBhZXMoKWAgZnVuY3Rpb24gdG8gZGVzY3JpYmUgd2hpY2ggdmFsdWVzIHdpbGwgYmUgdXNlZCBmb3IgZWFjaCAqKmFlcyoqdGhldGljIGNvbXBvbmVudCBvZiB0aGUgcGxvdCwgc3VjaCBhcyB0aGUgeCBhbmQgeSBjb29yZGluYXRlcyBvZiBlYWNoIHBvaW50LiAKKElmIHlvdSBmaW5kIGNhbGxpbmcgdGhpbmdzIGxpa2UgdGhlIHggYW5kIHkgY29vcmRpbmF0ZXMgImFlc3RoZXRpY3MiIGNvbmZ1c2luZywgZG9uJ3Qgd29ycnksIHlvdSBhcmUgbm90IGFsb25lLikgIApTcGVjaWZpY2FsbHksIHRoZSBgYWVzKClgIGZ1bmN0aW9uIGlzIHVzZWQgdG8gc3BlY2lmeSB0aGF0IGEgZ2l2ZW4gY29sdW1uICh2YXJpYWJsZSkgaW4geW91ciBkYXRhIGZyYW1lIGJlIG1hcHBlZCB0byBhIGdpdmVuIGFlc3RoZXRpYyBjb21wb25lbnQgb2YgdGhlIHBsb3QuCgoKYGBge3IgZ2dwbG90LWJhc2V9CmdncGxvdCgKICB0dW1vcl9ub3JtYWxfZGYsICMgVGhpcyBmaXJzdCBhcmd1bWVudCBpcyB0aGUgZGF0YSBmcmFtZSB3aXRoIHRoZSBkYXRhIHdlIHdhbnQgdG8gcGxvdAogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsICMgVGhpcyBpcyB0aGUgY29sdW1uIG5hbWUgb2YgdGhlIHZhbHVlcyB3ZSB3YW50IHRvIHVzZQogICAgIyBmb3IgdGhlIHggY29vcmRpbmF0ZXMKICAgIHkgPSBuZWdfbG9nMTBfcAogICkgIyBUaGlzIGlzIHRoZSBjb2x1bW4gbmFtZSBvZiB0aGUgZGF0YSB3ZSB3YW50IGZvciB0aGUgeS1heGlzCikKYGBgCgpZb3UnbGwgbm90aWNlIHRoaXMgcGxvdCBkb2Vzbid0IGhhdmUgYW55dGhpbmcgb24gaXQgYmVjYXVzZSB3ZSBoYXZlbid0IApzcGVjaWZpZWQgYSBwbG90IHR5cGUgeWV0LgpUbyBkbyB0aGF0LCB3ZSB3aWxsIGFkZCBhbm90aGVyIGdncGxvdCBsYXllciB3aXRoIGArYCB3aGljaCB3aWxsIHNwZWNpZnkgZXhhY3RseSB3aGF0IHdlIHdhbnQgdG8gcGxvdC4KQSB2b2xjYW5vIHBsb3QgaXMgYSBzcGVjaWFsIGtpbmQgb2Ygc2NhdHRlciBwbG90LCBzbyB0byBtYWtlIHRoYXQgd2Ugd2lsbCB3YW50IHRvIHBsb3QgaW5kaXZpZHVhbCBwb2ludHMsIHdoaWNoIHdlIGNhbiBkbyB3aXRoIGBnZW9tX3BvaW50KClgLgoKYGBge3IgZ2dwbG90LXBvaW50cywgbGl2ZSA9IFRSVUV9CiMgVGhpcyBmaXJzdCBwYXJ0IGlzIHRoZSBzYW1lIGFzIGJlZm9yZQpnZ3Bsb3QoCiAgdHVtb3Jfbm9ybWFsX2RmLAogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsCiAgICB5ID0gbmVnX2xvZzEwX3AKICApCikgKwogICMgTm93IHdlIGFyZSBhZGRpbmcgb24gYSBsYXllciB0byBzcGVjaWZ5IHdoYXQga2luZCBvZiBwbG90IHdlIHdhbnQKICBnZW9tX3BvaW50KCkKYGBgCgpIZXJlJ3MgYSBicmllZiBzdW1tYXJ5IG9mIGdncGxvdDIgc3RydWN0dXJlLiAKIVtnZ3Bsb3QyIHN0cnVjdHVyZV0oZGlhZ3JhbXMvZ2dwbG90X3N0cnVjdHVyZS5wbmcpCgojIyMgQWRqdXN0IG91ciBnZ3Bsb3QKCk5vdyB0aGF0IHdlIGhhdmUgYSBiYXNlIHBsb3QgdGhhdCBzaG93cyBvdXIgZGF0YSwgd2UgY2FuIGFkZCBsYXllcnMgb24gdG8gaXQgYW5kIGFkanVzdCBpdC4KV2UgY2FuIGFkanVzdCB0aGUgY29sb3Igb2YgcG9pbnRzIHVzaW5nIHRoZSBgY29sb3JgIGFlc3RoZXRpYy4KCmBgYHtyIGdncGxvdC1jb2xvciwgbGl2ZSA9IFRSVUV9CmdncGxvdCgKICB0dW1vcl9ub3JtYWxfZGYsCiAgYWVzKAogICAgeCA9IGxvZ19mb2xkX2NoYW5nZSwKICAgIHkgPSBuZWdfbG9nMTBfcCwKICAgIGNvbG9yID0gYXZnX2V4cHJlc3Npb24KICApICMgV2UgYWRkZWQgdGhpcyBhcmd1bWVudCB0byBjb2xvciBjb2RlIHRoZSBwb2ludHMhCikgKwogIGdlb21fcG9pbnQoKQpgYGAKCkJlY2F1c2Ugd2UgaGF2ZSBzbyBtYW55IHBvaW50cyBvdmVybGFwcGluZyBvbmUgYW5vdGhlciwgd2Ugd2lsbCB3YW50IHRvIGFkanVzdCAKdGhlIHRyYW5zcGFyZW5jeSwgd2hpY2ggd2UgY2FuIGRvIHdpdGggYW4gYGFscGhhYCBhcmd1bWVudC4gCgpgYGB7ciBnZ3Bsb3QtYWxwaGEsIGxpdmUgPSBUUlVFfQpnZ3Bsb3QoCiAgdHVtb3Jfbm9ybWFsX2RmLAogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsCiAgICB5ID0gbmVnX2xvZzEwX3AsCiAgICBjb2xvciA9IGF2Z19leHByZXNzaW9uCiAgKQopICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4yKSAjIFdlIGFyZSB1c2luZyB0aGUgYGFscGhhYCBhcmd1bWVudCB0byBtYWtlIG91ciBwb2ludHMgdHJhbnNwYXJlbnQKYGBgCgpOb3RpY2UgdGhhdCB3ZSBhZGRlZCB0aGUgYWxwaGEgd2l0aGluIHRoZSBgZ2VvbV9wb2ludCgpYCBmdW5jdGlvbiwgbm90IHRvIHRoZSBgYWVzKClgLiAKV2UgZGlkIHRoaXMgYmVjYXVzZSB3ZSB3YW50IGFsbCBvZiB0aGUgcG9pbnRzIHRvIGhhdmUgdGhlIHNhbWUgbGV2ZWwgb2YgdHJhbnNwYXJlbmN5LCBhbmQgaXQgd2lsbCBub3QgdmFyeSBkZXBlbmRpbmcgb24gYW55IHZhcmlhYmxlIGluIHRoZSBkYXRhLgpXZSBjYW4gYWxzbyBjaGFuZ2UgdGhlIGJhY2tncm91bmQgYW5kIGFwcGVhcmFuY2Ugb2YgdGhlIHBsb3QgYXMgYSB3aG9sZSBieSBhZGRpbmcgYSBgdGhlbWVgLgoKYGBge3IgZ2dwbG90LXRoZW1lfQpnZ3Bsb3QoCiAgdHVtb3Jfbm9ybWFsX2RmLAogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsCiAgICB5ID0gbmVnX2xvZzEwX3AsCiAgICBjb2xvciA9IGF2Z19leHByZXNzaW9uCiAgKQopICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4yKSArCiAgdGhlbWVfYncoKSAjIEFkZCBvbiB0aGlzIHNldCBvZiBhcHBlYXJhbmNlIHByZXNldHMgdG8gbWFrZSBpdCBwcmV0dHkKYGBgCgpXZSBhcmUgbm90IGxpbWl0ZWQgdG8gYSBzaW5nbGUgcGxvdHRpbmcgbGF5ZXIuIApGb3IgZXhhbXBsZSwgaWYgd2Ugd2FudCB0byBhZGQgYSBob3Jpem9udGFsIGxpbmUgdG8gaW5kaWNhdGUgYSBzaWduaWZpY2FuY2UgY3V0b2ZmLCB3ZSBjYW4gZG8gdGhhdCB3aXRoIGBnZW9tX2hsaW5lKClgLgpGb3Igbm93LCB3ZSB3aWxsIGNob29zZSB0aGUgdmFsdWUgb2YgNS41ICh0aGF0IGlzIGNsb3NlIHRvIGEgQm9uZmVycm9uaSBjb3JyZWN0aW9uKSBhbmQgYWRkIHRoYXQgdG8gdGhlIHBsb3QuCgpgYGB7ciBnZ3Bsb3QtaGxpbmUsIGxpdmUgPSBUUlVFfQpnZ3Bsb3QoCiAgdHVtb3Jfbm9ybWFsX2RmLAogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsCiAgICB5ID0gbmVnX2xvZzEwX3AsCiAgICBjb2xvciA9IGF2Z19leHByZXNzaW9uCiAgKQopICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4yKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDUuNSwgY29sb3IgPSAiZGFya2dyZWVuIikgIyB3ZSBjYW4gc3BlY2lmeSBjb2xvcnMgYnkgbmFtZXMgaGVyZQpgYGAKCldlIGNhbiBjaGFuZ2UgdGhlIHggYW5kIHkgbGFiZWxzIHVzaW5nIGEgZmV3IGRpZmZlcmVudCBzdHJhdGVnaWVzLiAKT25lIGFwcHJvYWNoIGlzIHRvIHVzZSBmdW5jdGlvbnMgYHhsYWIoKWAgYW5kIGB5bGFiKClgIGluZGl2aWR1YWxseSB0byBzZXQsIHJlc3BlY3RpdmVseSwgdGhlIHgtYXhpcyBsYWJlbCBhbmQgdGhlIHRoZSB5LWF4aXMgbGFiZWwuCgoKYGBge3IgZ2dwbG90LWxhYmVsLTF9CmdncGxvdCgKICB0dW1vcl9ub3JtYWxfZGYsCiAgYWVzKAogICAgeCA9IGxvZ19mb2xkX2NoYW5nZSwKICAgIHkgPSBuZWdfbG9nMTBfcCwKICAgIGNvbG9yID0gYXZnX2V4cHJlc3Npb24KICApCikgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LjUsIGNvbG9yID0gImRhcmtncmVlbiIpICsKICB0aGVtZV9idygpICsKICAjIEFkZCBsYWJlbHMgd2l0aCBzZXBhcmF0ZSBmdW5jdGlvbnM6CiAgeGxhYigibG9nMiBGb2xkIENoYW5nZSBUdW1vci9Ob3JtYWwiKSArIAogIHlsYWIoIi1sb2cxMCBwIHZhbHVlIikgCmBgYAoKCkFsdGVybmF0aXZlbHksIHdlIGNhbiB1c2UgdGhlIGBnZ3Bsb3QyYCBmdW5jdGlvbiBgbGFicygpYCwgd2hpY2ggdGFrZXMgaW5kaXZpZHVhbCBhcmd1bWVudHMgZm9yIGVhY2ggbGFiZWwgd2Ugd2FudCB3YW50IHRvIHNldC4gCldlIGNhbiBhbHNvIGluY2x1ZGUgdGhlIGFyZ3VtZW50IGB0aXRsZWAgdG8gYWRkIGFuIG92ZXJhbGwgcGxvdCB0aXRsZS4KCmBgYHtyIGdncGxvdC1sYWJlbC0yLCBsaXZlID0gVFJVRX0KZ2dwbG90KAogIHR1bW9yX25vcm1hbF9kZiwKICBhZXMoCiAgICB4ID0gbG9nX2ZvbGRfY2hhbmdlLAogICAgeSA9IG5lZ19sb2cxMF9wLAogICAgY29sb3IgPSBhdmdfZXhwcmVzc2lvbgogICkKKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDUuNSwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIHRoZW1lX2J3KCkgKwogICMgQWRkIHggYW5kIHkgbGFiZWxzIGFuZCBvdmVyYWxsIHBsb3QgdGl0bGUgd2l0aCBhcmd1bWVudHMgdG8gbGFicygpOgogIGxhYnMoCiAgICB4ID0gImxvZzIgRm9sZCBDaGFuZ2UgVHVtb3IvTm9ybWFsIiwKICAgIHkgPSAiLWxvZzEwIHAgdmFsdWUiLAogICAgdGl0bGUgPSAiQXN0cm9jeXRvbWEgVHVtb3IgdnMgTm9ybWFsIENlcmViZWxsdW0iCiAgKQogIApgYGAKClNvbWV0aGluZyBncmVhdCBhYm91dCB0aGUgYGxhYnMoKWAgZnVuY3Rpb24gaXMgeW91IGNhbiBhbHNvIHVzZSBpdCB0byBzcGVjaWZ5IGxhYmVscyBmb3IgeW91ciAqbGVnZW5kcyogZGVyaXZlZCBmcm9tIGNlcnRhaW4gYWVzdGhldGljcy4gCkluIHRoaXMgcGxvdCwgb3VyIGxlZ2VuZCBpcyBkZXJpdmVkIGZyb20gYSAqY29sb3IgYWVzdGhldGljKiwgc28gd2UgY2FuIHNwZWNpZnkgdGhlIGtleXdvcmQgImNvbG9yIiB0byB1cGRhdGUgdGhlIGxlZ2VuZCB0aXRsZS4KCmBgYHtyIGdncGxvdC1sYWJlbC1hZXN9CmdncGxvdCgKICB0dW1vcl9ub3JtYWxfZGYsCiAgYWVzKAogICAgeCA9IGxvZ19mb2xkX2NoYW5nZSwKICAgIHkgPSBuZWdfbG9nMTBfcCwKICAgIGNvbG9yID0gYXZnX2V4cHJlc3Npb24KICApCikgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LjUsIGNvbG9yID0gImRhcmtncmVlbiIpICsKICB0aGVtZV9idygpICsKICAjIEFkZCB4IGFuZCB5IGxhYmVscyBhbmQgb3ZlcmFsbCBwbG90IHRpdGxlIHdpdGggYXJndW1lbnRzIHRvIGxhYnMoKToKICBsYWJzKAogICAgeCA9ICJsb2cyIEZvbGQgQ2hhbmdlIFR1bW9yL05vcm1hbCIsCiAgICB5ID0gIi1sb2cxMCBwIHZhbHVlIiwKICAgIHRpdGxlID0gIkFzdHJvY3l0b21hIFR1bW9yIHZzIE5vcm1hbCBDZXJlYmVsbHVtIiwKICAgICMgVXNlIHRoZSBjb2xvciBrZXl3b3JkIHRvIGxhYmVsIHRoZSBjb2xvciBsZWdlbmQKICAgIGNvbG9yID0gIkF2ZXJhZ2UgZXhwcmVzc2lvbiIKICApCiAgCmBgYAoKClVzZSB0aGlzIGNodW5rIHRvIG1ha2UgdGhlIHNhbWUga2luZCBvZiBwbG90IGFzIHRoZSBwcmV2aW91cyBjaHVuayBidXQgaW5zdGVhZCBwbG90IHRoZSBtYWxlIGZlbWFsZSBjb250cmFzdCBkYXRhLCB0aGF0IGlzIHN0b3JlZCBpbiBgbWFsZV9mZW1hbGVfZGZgLiAKCmBgYHtyIG1mLXZvbGNhbm8sIGxpdmUgPSBUUlVFfQojIFVzZSB0aGlzIGNodW5rIHRvIG1ha2UgdGhlIHNhbWUga2luZCBvZiB2b2xjYW5vIHBsb3QsIGJ1dCB3aXRoIHRoZSBtYWxlLWZlbWFsZSBjb250cmFzdCBkYXRhLgoKYGBgCgoKVHVybnMgb3V0LCB3ZSBkb24ndCBoYXZlIHRvIHBsb3QgZWFjaCBjb250cmFzdCBzZXBhcmF0ZWx5LCBpbnN0ZWFkLCB3ZSBjYW4gdXNlIHRoZSBvcmlnaW5hbCBkYXRhIGZyYW1lIHRoYXQgY29udGFpbnMgYWxsIHRocmVlIGNvbnRyYXN0cycgZGF0YSwgYHN0YXRzX2RmYCwgYW5kIGFkZCBhIGBmYWNldF93cmFwYCB0byBtYWtlIGVhY2ggY29udHJhc3QgaXRzIG93biBwbG90LiAKCmBgYHtyIGdncGxvdC1mYWNldHN9CmdncGxvdCgKICBzdGF0c19kZiwgIyBTd2l0Y2ggdG8gdGhlIGJpZ2dlciBkYXRhIGZyYW1lIHdpdGggYWxsIHRocmVlIGNvbnRyYXN0cycgZGF0YQogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsCiAgICB5ID0gbmVnX2xvZzEwX3AsCiAgICBjb2xvciA9IGF2Z19leHByZXNzaW9uCiAgKQopICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4yKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNS41LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgdGhlbWVfYncoKSArCiAgZmFjZXRfd3JhcCh+Y29udHJhc3QpICsKICBsYWJzKAogICAgeCAgPSAibG9nMiBGb2xkIENoYW5nZSIsICMgTm93IHRoYXQgdGhpcyBpbmNsdWRlcyB0aGUgb3RoZXIgY29udHJhc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgd2UnbGwgbWFrZSB0aGlzIGxhYmVsIG1vcmUgZ2VuZXJhbAogICAgeSA9ICItbG9nMTAgcCB2YWx1ZSIsCiAgICBjb2xvciA9ICJBdmVyYWdlIGV4cHJlc3Npb24iCiAgKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0yNSwgMjUpKSAjIHpvb20gaW4gb24gdGhlIHgtYXhpcwpgYGAKCldlIGNhbiBzdG9yZSB0aGUgcGxvdCBhcyBhbiBvYmplY3QgaW4gdGhlIGdsb2JhbCBlbnZpcm9ubWVudCBieSB1c2luZyBgPC1gIG9wZXJhdG9yLiAKSGVyZSB3ZSB3aWxsIGNhbGwgdGhpcyBgdm9sY2Fub19wbG90YC4gCgpgYGB7ciBnZ3Bsb3Qtc3RvcmUtb2JqZWN0fQp2b2xjYW5vX3Bsb3QgPC0gZ2dwbG90KAogIHN0YXRzX2RmLCAjIFdlIGFyZSBjYWxsaW5nIHRoaXMgcGxvdCBgdm9sY2Fub19wbG90YAogIGFlcygKICAgIHggPSBsb2dfZm9sZF9jaGFuZ2UsCiAgICB5ID0gbmVnX2xvZzEwX3AsCiAgICBjb2xvciA9IGF2Z19leHByZXNzaW9uCiAgKQopICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4yKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNS41LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgdGhlbWVfYncoKSArCiAgZmFjZXRfd3JhcCh+Y29udHJhc3QpICsKICBsYWJzKAogICAgeCAgPSAibG9nMiBGb2xkIENoYW5nZSIsCiAgICB5ID0gIi1sb2cxMCBwIHZhbHVlIiwKICAgIGNvbG9yID0gIkF2ZXJhZ2UgZXhwcmVzc2lvbiIKICApICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTI1LCAyNSkpCmBgYAoKV2hlbiB3ZSBhcmUgaGFwcHkgd2l0aCBvdXIgcGxvdCwgd2UgY2FuIHNhdmUgdGhlIHBsb3QgdXNpbmcgYGdnc2F2ZWAuIApJdCdzIGEgZ29vZCBpZGVhIHRvIGFsc28gc3BlY2lmeSBgd2lkdGhgIGFuZCBgaGVpZ2h0YCBhcmd1bWVudHMgKHVuaXRzIGluIGluY2hlcykKdG8gZW5zdXJlIHRoZSBzYXZlZCBwbG90IGlzIGFsd2F5cyB0aGUgc2FtZSBzaXplIGV2ZXJ5IHRpbWUgeW91IHJ1biB0aGlzIGNvZGUuCkhlcmUsIHdlJ2xsIHNhdmUgYSA2Ing2IiBwbG90LgoKCmBgYHtyIGdnc2F2ZX0KZ2dzYXZlKAogIHBsb3QgPSB2b2xjYW5vX3Bsb3QsCiAgZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdHNfZGlyLCAidm9sY2Fub19wbG90LnBuZyIpLAogIHdpZHRoID0gNiwgCiAgaGVpZ2h0ID0gNiAKKQpgYGAKCiMjIyBTZXNzaW9uIEluZm8KCmBgYHtyfQojIFByaW50IG91dCB0aGUgdmVyc2lvbnMgYW5kIHBhY2thZ2VzIHdlIGFyZSB1c2luZyBpbiB0aGlzIHNlc3Npb24Kc2Vzc2lvbkluZm8oKQpgYGAK
diff --git a/scRNA-seq/04-dimension_reduction_scRNA.nb.html b/scRNA-seq/04-dimension_reduction_scRNA.nb.html index dd3c70e7..8ca700e4 100644 --- a/scRNA-seq/04-dimension_reduction_scRNA.nb.html +++ b/scRNA-seq/04-dimension_reduction_scRNA.nb.html @@ -3715,7 +3715,7 @@

UMAP experiments

UMAP_plot_wrapper(nn_param = 3) -

+

@@ -3788,7 +3788,7 @@

t-SNE comparison

plotReducedDim(normalized_sce, "TSNE", colour_by = "detected") -

+